summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGunnar Sletta <gunnar.sletta@nokia.com>2011-09-13 08:54:45 +0200
committerGunnar Sletta <gunnar.sletta@nokia.com>2011-09-13 08:54:45 +0200
commitb62bd0584a7872b6917917009b707785b3abd077 (patch)
tree9981f274712c098cabbff0c4667672a3934e5393 /src
parent5e10745dca1d10025404a9f268f03ae697fb10cc (diff)
parent97baad65f65783d2b5ff938f6217aec9434f2e5f (diff)
Merge branch 'refactor'
Conflicts: mkspecs/qws/linux-lsb-g++/qmake.conf src/gui/image/qpixmap_mac.cpp src/gui/painting/qpaintengine_x11.cpp src/gui/painting/qtessellator.cpp src/gui/text/qfontengine_qws.cpp src/gui/text/qfontengine_x11.cpp src/gui/widgets/qlinecontrol.cpp src/opengl/qgl.h src/opengl/qgl_x11egl.cpp src/plugins/plugins.pro Change-Id: If52dcd55cd55f2983a756c2f843967702b60a310
Diffstat (limited to 'src')
m---------src/3rdparty/v80
-rw-r--r--src/corelib/global/qglobal.h65
-rw-r--r--src/corelib/global/qnamespace.h58
-rw-r--r--src/corelib/global/qt_pch.h2
-rw-r--r--src/corelib/io/qdir.cpp2
-rw-r--r--src/corelib/io/qfsfileengine_p.h4
-rw-r--r--src/corelib/io/qprocess.cpp6
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp48
-rw-r--r--src/corelib/kernel/qcoreapplication.h21
-rw-r--r--src/corelib/kernel/qcoreapplication_p.h2
-rw-r--r--src/corelib/kernel/qcoreapplication_win.cpp2
-rw-r--r--src/corelib/kernel/qcoreevent.cpp1
-rw-r--r--src/corelib/kernel/qcoreevent.h8
-rw-r--r--src/corelib/kernel/qeventdispatcher_win.cpp74
-rw-r--r--src/corelib/kernel/qeventdispatcher_win_p.h71
-rw-r--r--src/corelib/kernel/qmetatype.cpp41
-rw-r--r--src/corelib/kernel/qmetatype.h16
-rw-r--r--src/corelib/kernel/qobject.cpp1
-rw-r--r--src/corelib/kernel/qobject.h4
-rw-r--r--src/corelib/kernel/qvariant.h37
-rw-r--r--src/corelib/plugin/qlibrary_p.h4
-rw-r--r--src/corelib/thread/qthread.cpp4
-rw-r--r--src/corelib/tools/qdatetime.cpp4
-rw-r--r--src/corelib/tools/qlocale.cpp11
-rw-r--r--src/gui/accessible/accessible.pri25
-rw-r--r--src/gui/accessible/qaccessible.h472
-rw-r--r--src/gui/accessible/qaccessible2.cpp317
-rw-r--r--src/gui/accessible/qaccessible2.h358
-rw-r--r--src/gui/accessible/qaccessible_win.cpp1439
-rw-r--r--src/gui/accessible/qaccessiblebridge.h92
-rw-r--r--src/gui/accessible/qaccessibleobject.h140
-rw-r--r--src/gui/accessible/qaccessibleplugin.h87
-rw-r--r--src/gui/accessible/qaccessiblewidget.cpp1034
-rw-r--r--src/gui/accessible/qaccessiblewidget.h141
-rw-r--r--src/gui/dialogs/dialogs.pri122
-rw-r--r--src/gui/dialogs/qabstractpagesetupdialog.cpp139
-rw-r--r--src/gui/dialogs/qabstractpagesetupdialog.h82
-rw-r--r--src/gui/dialogs/qabstractprintdialog.cpp497
-rw-r--r--src/gui/dialogs/qabstractprintdialog.h129
-rw-r--r--src/gui/dialogs/qabstractprintdialog_p.h95
-rw-r--r--src/gui/dialogs/qcolordialog.cpp2114
-rw-r--r--src/gui/dialogs/qcolordialog.h150
-rw-r--r--src/gui/dialogs/qdialog.h140
-rw-r--r--src/gui/dialogs/qdialog_p.h113
-rw-r--r--src/gui/dialogs/qdialogsbinarycompat_win.cpp137
-rw-r--r--src/gui/dialogs/qerrormessage.h88
-rw-r--r--src/gui/dialogs/qfiledialog.cpp3555
-rw-r--r--src/gui/dialogs/qfiledialog.h331
-rw-r--r--src/gui/dialogs/qfiledialog_win.cpp825
-rw-r--r--src/gui/dialogs/qfilesystemmodel.h180
-rw-r--r--src/gui/dialogs/qfontdialog.cpp1077
-rw-r--r--src/gui/dialogs/qfontdialog.h147
-rw-r--r--src/gui/dialogs/qfscompleter_p.h82
-rw-r--r--src/gui/dialogs/qinputdialog.h256
-rw-r--r--src/gui/dialogs/qmessagebox.cpp2751
-rw-r--r--src/gui/dialogs/qmessagebox.h365
-rw-r--r--src/gui/dialogs/qpagesetupdialog.h112
-rw-r--r--src/gui/dialogs/qpagesetupdialog_unix.cpp620
-rw-r--r--src/gui/dialogs/qprintdialog.h174
-rw-r--r--src/gui/dialogs/qprintdialog_qws.cpp567
-rw-r--r--src/gui/dialogs/qprintdialog_unix.cpp1309
-rw-r--r--src/gui/dialogs/qprintpreviewdialog.cpp802
-rw-r--r--src/gui/dialogs/qprintpreviewdialog.h107
-rw-r--r--src/gui/dialogs/qprogressdialog.cpp907
-rw-r--r--src/gui/dialogs/qprogressdialog.h145
-rw-r--r--src/gui/dialogs/qwizard.h268
-rw-r--r--src/gui/dialogs/qwizard_win.cpp759
-rw-r--r--src/gui/dialogs/qwizard_win_p.h158
-rw-r--r--src/gui/effects/effects.pri4
-rw-r--r--src/gui/effects/qgraphicseffect.cpp1235
-rw-r--r--src/gui/effects/qgraphicseffect.h289
-rw-r--r--src/gui/effects/qgraphicseffect_p.h231
-rw-r--r--src/gui/egl/egl.pri22
-rw-r--r--src/gui/egl/qegl_p.h2
-rw-r--r--src/gui/egl/qegl_qpa.cpp5
-rw-r--r--src/gui/egl/qegl_qws.cpp114
-rw-r--r--src/gui/egl/qegl_x11.cpp30
-rw-r--r--src/gui/egl/qeglcontext_p.h4
-rw-r--r--src/gui/egl/qeglproperties_p.h2
-rw-r--r--src/gui/embedded/directfb.pri40
-rw-r--r--src/gui/embedded/embedded.pri226
-rw-r--r--src/gui/embedded/qcopchannel_qws.cpp608
-rw-r--r--src/gui/embedded/qcopchannel_qws.h108
-rw-r--r--src/gui/embedded/qdecoration_qws.cpp404
-rw-r--r--src/gui/embedded/qdecoration_qws.h124
-rw-r--r--src/gui/embedded/qdecorationdefault_qws.cpp803
-rw-r--r--src/gui/embedded/qdecorationdefault_qws.h101
-rw-r--r--src/gui/embedded/qdecorationfactory_qws.cpp156
-rw-r--r--src/gui/embedded/qdecorationfactory_qws.h66
-rw-r--r--src/gui/embedded/qdecorationplugin_qws.cpp116
-rw-r--r--src/gui/embedded/qdecorationplugin_qws.h80
-rw-r--r--src/gui/embedded/qdecorationstyled_qws.cpp313
-rw-r--r--src/gui/embedded/qdecorationstyled_qws.h73
-rw-r--r--src/gui/embedded/qdecorationwindows_qws.cpp407
-rw-r--r--src/gui/embedded/qdecorationwindows_qws.h77
-rw-r--r--src/gui/embedded/qdirectpainter_qws.cpp682
-rw-r--r--src/gui/embedded/qdirectpainter_qws.h112
-rw-r--r--src/gui/embedded/qkbd_defaultmap_qws_p.h806
-rw-r--r--src/gui/embedded/qkbd_qws.cpp693
-rw-r--r--src/gui/embedded/qkbd_qws.h103
-rw-r--r--src/gui/embedded/qkbd_qws_p.h134
-rw-r--r--src/gui/embedded/qkbddriverfactory_qws.cpp187
-rw-r--r--src/gui/embedded/qkbddriverfactory_qws.h70
-rw-r--r--src/gui/embedded/qkbddriverplugin_qws.cpp124
-rw-r--r--src/gui/embedded/qkbddriverplugin_qws.h84
-rw-r--r--src/gui/embedded/qkbdintegrity_qws.cpp197
-rw-r--r--src/gui/embedded/qkbdintegrity_qws.h81
-rw-r--r--src/gui/embedded/qkbdlinuxinput_qws.cpp245
-rw-r--r--src/gui/embedded/qkbdlinuxinput_qws.h79
-rw-r--r--src/gui/embedded/qkbdqnx_qws.cpp236
-rw-r--r--src/gui/embedded/qkbdqnx_qws.h76
-rw-r--r--src/gui/embedded/qkbdtty_qws.cpp353
-rw-r--r--src/gui/embedded/qkbdtty_qws.h79
-rw-r--r--src/gui/embedded/qkbdum_qws.cpp144
-rw-r--r--src/gui/embedded/qkbdum_qws.h77
-rw-r--r--src/gui/embedded/qkbdvfb_qws.cpp124
-rw-r--r--src/gui/embedded/qkbdvfb_qws.h86
-rw-r--r--src/gui/embedded/qlock.cpp325
-rw-r--r--src/gui/embedded/qlock_p.h100
-rw-r--r--src/gui/embedded/qmouse_qws.cpp653
-rw-r--r--src/gui/embedded/qmouse_qws.h123
-rw-r--r--src/gui/embedded/qmousedriverfactory_qws.cpp197
-rw-r--r--src/gui/embedded/qmousedriverfactory_qws.h67
-rw-r--r--src/gui/embedded/qmousedriverplugin_qws.cpp124
-rw-r--r--src/gui/embedded/qmousedriverplugin_qws.h84
-rw-r--r--src/gui/embedded/qmouseintegrity_qws.cpp271
-rw-r--r--src/gui/embedded/qmouseintegrity_qws.h82
-rw-r--r--src/gui/embedded/qmouselinuxinput_qws.cpp205
-rw-r--r--src/gui/embedded/qmouselinuxinput_qws.h78
-rw-r--r--src/gui/embedded/qmouselinuxtp_qws.cpp335
-rw-r--r--src/gui/embedded/qmouselinuxtp_qws.h77
-rw-r--r--src/gui/embedded/qmousepc_qws.cpp794
-rw-r--r--src/gui/embedded/qmousepc_qws.h76
-rw-r--r--src/gui/embedded/qmouseqnx_qws.cpp190
-rw-r--r--src/gui/embedded/qmouseqnx_qws.h79
-rw-r--r--src/gui/embedded/qmousetslib_qws.cpp371
-rw-r--r--src/gui/embedded/qmousetslib_qws.h80
-rw-r--r--src/gui/embedded/qmousevfb_qws.cpp133
-rw-r--r--src/gui/embedded/qmousevfb_qws.h83
-rw-r--r--src/gui/embedded/qscreen_qws.cpp3347
-rw-r--r--src/gui/embedded/qscreen_qws.h391
-rw-r--r--src/gui/embedded/qscreendriverfactory_qws.cpp204
-rw-r--r--src/gui/embedded/qscreendriverfactory_qws.h67
-rw-r--r--src/gui/embedded/qscreendriverplugin_qws.cpp123
-rw-r--r--src/gui/embedded/qscreendriverplugin_qws.h84
-rw-r--r--src/gui/embedded/qscreenintegrityfb_qws.cpp405
-rw-r--r--src/gui/embedded/qscreenintegrityfb_qws.h83
-rw-r--r--src/gui/embedded/qscreenlinuxfb_qws.cpp1386
-rw-r--r--src/gui/embedded/qscreenlinuxfb_qws.h135
-rw-r--r--src/gui/embedded/qscreenmulti_qws.cpp486
-rw-r--r--src/gui/embedded/qscreenmulti_qws_p.h114
-rw-r--r--src/gui/embedded/qscreenproxy_qws.cpp635
-rw-r--r--src/gui/embedded/qscreenproxy_qws.h153
-rw-r--r--src/gui/embedded/qscreenqnx_qws.cpp450
-rw-r--r--src/gui/embedded/qscreenqnx_qws.h82
-rw-r--r--src/gui/embedded/qscreentransformed_qws.cpp748
-rw-r--r--src/gui/embedded/qscreentransformed_qws.h103
-rw-r--r--src/gui/embedded/qscreenvfb_qws.cpp445
-rw-r--r--src/gui/embedded/qscreenvfb_qws.h86
-rw-r--r--src/gui/embedded/qsoundqss_qws.cpp1530
-rw-r--r--src/gui/embedded/qsoundqss_qws.h177
-rw-r--r--src/gui/embedded/qtransportauth_qws.cpp1563
-rw-r--r--src/gui/embedded/qtransportauth_qws.h281
-rw-r--r--src/gui/embedded/qtransportauth_qws_p.h189
-rw-r--r--src/gui/embedded/qtransportauthdefs_qws.h174
-rw-r--r--src/gui/embedded/qunixsocket.cpp1800
-rw-r--r--src/gui/embedded/qunixsocket_p.h202
-rw-r--r--src/gui/embedded/qunixsocketserver.cpp376
-rw-r--r--src/gui/embedded/qunixsocketserver_p.h98
-rw-r--r--src/gui/embedded/qvfbhdr.h119
-rw-r--r--src/gui/embedded/qwindowsystem_p.h315
-rw-r--r--src/gui/embedded/qwindowsystem_qws.cpp4960
-rw-r--r--src/gui/embedded/qwindowsystem_qws.h508
-rw-r--r--src/gui/embedded/qwscommand_qws.cpp609
-rw-r--r--src/gui/embedded/qwscommand_qws_p.h851
-rw-r--r--src/gui/embedded/qwscursor_qws.cpp654
-rw-r--r--src/gui/embedded/qwscursor_qws.h83
-rw-r--r--src/gui/embedded/qwsdisplay_qws.h185
-rw-r--r--src/gui/embedded/qwsdisplay_qws_p.h161
-rw-r--r--src/gui/embedded/qwsembedwidget.cpp227
-rw-r--r--src/gui/embedded/qwsembedwidget.h82
-rw-r--r--src/gui/embedded/qwsevent_qws.cpp216
-rw-r--r--src/gui/embedded/qwsevent_qws.h459
-rw-r--r--src/gui/embedded/qwslock.cpp236
-rw-r--r--src/gui/embedded/qwslock_p.h85
-rw-r--r--src/gui/embedded/qwsmanager_p.h122
-rw-r--r--src/gui/embedded/qwsmanager_qws.cpp537
-rw-r--r--src/gui/embedded/qwsmanager_qws.h122
-rw-r--r--src/gui/embedded/qwsproperty_qws.cpp145
-rw-r--r--src/gui/embedded/qwsproperty_qws.h96
-rw-r--r--src/gui/embedded/qwsprotocolitem_qws.h100
-rw-r--r--src/gui/embedded/qwssharedmemory.cpp185
-rw-r--r--src/gui/embedded/qwssharedmemory_p.h105
-rw-r--r--src/gui/embedded/qwssignalhandler.cpp128
-rw-r--r--src/gui/embedded/qwssignalhandler_p.h99
-rw-r--r--src/gui/embedded/qwssocket_qws.cpp280
-rw-r--r--src/gui/embedded/qwssocket_qws.h120
-rw-r--r--src/gui/embedded/qwsutils_qws.h98
-rw-r--r--src/gui/graphicsview/qgraphicsanchorlayout.h128
-rw-r--r--src/gui/graphicsview/qgraphicsanchorlayout_p.cpp3015
-rw-r--r--src/gui/graphicsview/qgraphicsgridlayout.h144
-rw-r--r--src/gui/graphicsview/qgraphicsitem.cpp11603
-rw-r--r--src/gui/graphicsview/qgraphicsitem.h1172
-rw-r--r--src/gui/graphicsview/qgraphicsitem_p.h891
-rw-r--r--src/gui/graphicsview/qgraphicsitemanimation.h120
-rw-r--r--src/gui/graphicsview/qgraphicslayout.h100
-rw-r--r--src/gui/graphicsview/qgraphicslayout_p.h154
-rw-r--r--src/gui/graphicsview/qgraphicslayoutitem.h155
-rw-r--r--src/gui/graphicsview/qgraphicslayoutitem_p.h103
-rw-r--r--src/gui/graphicsview/qgraphicslinearlayout.h119
-rw-r--r--src/gui/graphicsview/qgraphicsproxywidget.cpp1569
-rw-r--r--src/gui/graphicsview/qgraphicsproxywidget.h147
-rw-r--r--src/gui/graphicsview/qgraphicsscene.cpp6504
-rw-r--r--src/gui/graphicsview/qgraphicsscene.h329
-rw-r--r--src/gui/graphicsview/qgraphicsscene_p.h359
-rw-r--r--src/gui/graphicsview/qgraphicssceneevent.cpp1674
-rw-r--r--src/gui/graphicsview/qgraphicssceneevent.h326
-rw-r--r--src/gui/graphicsview/qgraphicsscenelinearindex_p.h109
-rw-r--r--src/gui/graphicsview/qgraphicstransform.h159
-rw-r--r--src/gui/graphicsview/qgraphicsview.cpp3880
-rw-r--r--src/gui/graphicsview/qgraphicsview.h316
-rw-r--r--src/gui/graphicsview/qgraphicsview_p.h233
-rw-r--r--src/gui/graphicsview/qgraphicswidget.cpp2425
-rw-r--r--src/gui/graphicsview/qgraphicswidget.h257
-rw-r--r--src/gui/graphicsview/qgraphicswidget_p.cpp906
-rw-r--r--src/gui/graphicsview/qgraphicswidget_p.h226
-rw-r--r--src/gui/gui.pro43
-rw-r--r--src/gui/image/image.pri31
-rw-r--r--src/gui/image/qbitmap.cpp105
-rw-r--r--src/gui/image/qbitmap.h25
-rw-r--r--src/gui/image/qbmphandler.cpp23
-rw-r--r--src/gui/image/qbmphandler_p.h17
-rw-r--r--src/gui/image/qicon.cpp1256
-rw-r--r--src/gui/image/qicon.h162
-rw-r--r--src/gui/image/qicon_p.h138
-rw-r--r--src/gui/image/qiconengine.h104
-rw-r--r--src/gui/image/qiconengineplugin.h104
-rw-r--r--src/gui/image/qiconloader.cpp570
-rw-r--r--src/gui/image/qiconloader_p.h192
-rw-r--r--src/gui/image/qimage.cpp632
-rw-r--r--src/gui/image/qimage.h172
-rw-r--r--src/gui/image/qimage_p.h3
-rw-r--r--src/gui/image/qimagepixmapcleanuphooks.cpp18
-rw-r--r--src/gui/image/qimagepixmapcleanuphooks_p.h16
-rw-r--r--src/gui/image/qimagereader.cpp2
-rw-r--r--src/gui/image/qimagewriter.cpp2
-rw-r--r--src/gui/image/qmovie.h20
-rw-r--r--src/gui/image/qnativeimage.cpp116
-rw-r--r--src/gui/image/qnativeimage_p.h12
-rw-r--r--src/gui/image/qnativeimagehandleprovider_p.h69
-rw-r--r--src/gui/image/qpicture.cpp2
-rw-r--r--src/gui/image/qpicture.h3
-rw-r--r--src/gui/image/qpixmap.cpp629
-rw-r--r--src/gui/image/qpixmap.h160
-rw-r--r--src/gui/image/qpixmap_blitter.cpp50
-rw-r--r--src/gui/image/qpixmap_blitter_p.h22
-rw-r--r--src/gui/image/qpixmap_mac.cpp1233
-rw-r--r--src/gui/image/qpixmap_mac_p.h134
-rw-r--r--src/gui/image/qpixmap_qpa.cpp6
-rw-r--r--src/gui/image/qpixmap_qws.cpp160
-rw-r--r--src/gui/image/qpixmap_raster.cpp98
-rw-r--r--src/gui/image/qpixmap_raster_p.h15
-rw-r--r--src/gui/image/qpixmap_s60.cpp1040
-rw-r--r--src/gui/image/qpixmap_s60_p.h141
-rw-r--r--src/gui/image/qpixmap_win.cpp477
-rw-r--r--src/gui/image/qpixmap_x11.cpp2419
-rw-r--r--src/gui/image/qpixmap_x11_p.h156
-rw-r--r--src/gui/image/qpixmapcache_p.h6
-rw-r--r--src/gui/image/qpixmapdata.cpp290
-rw-r--r--src/gui/image/qpixmapdata_p.h180
-rw-r--r--src/gui/image/qpixmapdatafactory.cpp115
-rw-r--r--src/gui/image/qpixmapdatafactory_p.h81
-rw-r--r--src/gui/image/qpixmapfilter.cpp1382
-rw-r--r--src/gui/image/qpixmapfilter_p.h196
-rw-r--r--src/gui/image/qplatformpixmap.cpp189
-rw-r--r--src/gui/image/qplatformpixmap_qpa.h160
-rw-r--r--src/gui/image/qvolatileimage.cpp17
-rw-r--r--src/gui/image/qvolatileimage_p.h1
-rw-r--r--src/gui/inputmethod/inputmethod.pri31
-rw-r--r--src/gui/inputmethod/qcoefepinputcontext_p.h176
-rw-r--r--src/gui/inputmethod/qcoefepinputcontext_s60.cpp1200
-rw-r--r--src/gui/inputmethod/qinputcontext.cpp500
-rw-r--r--src/gui/inputmethod/qinputcontext.h139
-rw-r--r--src/gui/inputmethod/qinputcontext_p.h94
-rw-r--r--src/gui/inputmethod/qinputcontextfactory.cpp354
-rw-r--r--src/gui/inputmethod/qinputcontextfactory.h88
-rw-r--r--src/gui/inputmethod/qinputcontextplugin.cpp178
-rw-r--r--src/gui/inputmethod/qinputcontextplugin.h106
-rw-r--r--src/gui/inputmethod/qmacinputcontext_p.h97
-rw-r--r--src/gui/inputmethod/qwininputcontext_p.h111
-rw-r--r--src/gui/inputmethod/qwsinputcontext_p.h97
-rw-r--r--src/gui/inputmethod/qwsinputcontext_qws.cpp246
-rw-r--r--src/gui/inputmethod/qximinputcontext_p.h142
-rw-r--r--src/gui/itemviews/itemviews.pri72
-rw-r--r--src/gui/itemviews/qabstractitemdelegate.h134
-rw-r--r--src/gui/itemviews/qabstractitemview.cpp4320
-rw-r--r--src/gui/itemviews/qabstractitemview.h381
-rw-r--r--src/gui/itemviews/qabstractitemview_p.h458
-rw-r--r--src/gui/itemviews/qabstractproxymodel.h113
-rw-r--r--src/gui/itemviews/qcolumnview.h123
-rw-r--r--src/gui/itemviews/qcolumnview_p.h189
-rw-r--r--src/gui/itemviews/qdatawidgetmapper.h128
-rw-r--r--src/gui/itemviews/qdirmodel.h160
-rw-r--r--src/gui/itemviews/qfileiconprovider.h82
-rw-r--r--src/gui/itemviews/qheaderview.h250
-rw-r--r--src/gui/itemviews/qheaderview_p.h366
-rw-r--r--src/gui/itemviews/qidentityproxymodel.h120
-rw-r--r--src/gui/itemviews/qitemdelegate.cpp1341
-rw-r--r--src/gui/itemviews/qitemdelegate.h141
-rw-r--r--src/gui/itemviews/qitemeditorfactory.h124
-rw-r--r--src/gui/itemviews/qitemselectionmodel.h255
-rw-r--r--src/gui/itemviews/qlistview.cpp3224
-rw-r--r--src/gui/itemviews/qlistview.h203
-rw-r--r--src/gui/itemviews/qlistwidget.h335
-rw-r--r--src/gui/itemviews/qlistwidget_p.h175
-rw-r--r--src/gui/itemviews/qproxymodel.h143
-rw-r--r--src/gui/itemviews/qsortfilterproxymodel.h201
-rw-r--r--src/gui/itemviews/qstandarditemmodel.h456
-rw-r--r--src/gui/itemviews/qstringlistmodel.h91
-rw-r--r--src/gui/itemviews/qstyleditemdelegate.h116
-rw-r--r--src/gui/itemviews/qtableview.h198
-rw-r--r--src/gui/itemviews/qtablewidget.h377
-rw-r--r--src/gui/itemviews/qtreeview.h242
-rw-r--r--src/gui/itemviews/qtreeview_p.h255
-rw-r--r--src/gui/itemviews/qtreewidget.h432
-rw-r--r--src/gui/itemviews/qtreewidget_p.h248
-rw-r--r--src/gui/itemviews/qtreewidgetitemiterator.h159
-rw-r--r--src/gui/kernel/kernel.pri353
-rw-r--r--src/gui/kernel/mac.pri4
-rw-r--r--src/gui/kernel/qaction.h264
-rw-r--r--src/gui/kernel/qaction_p.h144
-rw-r--r--src/gui/kernel/qactiongroup.h112
-rw-r--r--src/gui/kernel/qapplication.cpp6141
-rw-r--r--src/gui/kernel/qapplication.h431
-rw-r--r--src/gui/kernel/qapplication_mac.mm3137
-rw-r--r--src/gui/kernel/qapplication_p.h683
-rw-r--r--src/gui/kernel/qapplication_qpa.cpp968
-rw-r--r--src/gui/kernel/qapplication_qws.cpp3802
-rw-r--r--src/gui/kernel/qapplication_s60.cpp2723
-rw-r--r--src/gui/kernel/qapplication_win.cpp4253
-rw-r--r--src/gui/kernel/qapplication_x11.cpp6254
-rw-r--r--src/gui/kernel/qboxlayout.h173
-rw-r--r--src/gui/kernel/qclipboard.cpp2
-rw-r--r--src/gui/kernel/qclipboard.h1
-rw-r--r--src/gui/kernel/qclipboard_qpa.cpp15
-rw-r--r--src/gui/kernel/qclipboard_qws.cpp304
-rw-r--r--src/gui/kernel/qcocoaapplication_mac.mm222
-rw-r--r--src/gui/kernel/qcocoaapplication_mac_p.h117
-rw-r--r--src/gui/kernel/qcocoaapplicationdelegate_mac.mm354
-rw-r--r--src/gui/kernel/qcocoaapplicationdelegate_mac_p.h128
-rw-r--r--src/gui/kernel/qcocoamenuloader_mac.mm264
-rw-r--r--src/gui/kernel/qcocoamenuloader_mac_p.h95
-rw-r--r--src/gui/kernel/qcocoaview_mac_p.h87
-rw-r--r--src/gui/kernel/qcursor.cpp12
-rw-r--r--src/gui/kernel/qcursor.h12
-rw-r--r--src/gui/kernel/qcursor_qpa.cpp18
-rw-r--r--src/gui/kernel/qcursor_qws.cpp138
-rw-r--r--src/gui/kernel/qcursor_x11.cpp640
-rw-r--r--src/gui/kernel/qdesktopwidget.h110
-rw-r--r--src/gui/kernel/qdesktopwidget_qpa.cpp176
-rw-r--r--src/gui/kernel/qdesktopwidget_qws.cpp159
-rw-r--r--src/gui/kernel/qdnd.cpp314
-rw-r--r--src/gui/kernel/qdnd_p.h262
-rw-r--r--src/gui/kernel/qdnd_qws.cpp426
-rw-r--r--src/gui/kernel/qdnd_x11.cpp2061
-rw-r--r--src/gui/kernel/qdrag.cpp11
-rw-r--r--src/gui/kernel/qdrag.h12
-rw-r--r--src/gui/kernel/qevent.cpp748
-rw-r--r--src/gui/kernel/qevent.h224
-rw-r--r--src/gui/kernel/qevent_p.h47
-rw-r--r--src/gui/kernel/qeventdispatcher_glib_qpa.cpp147
-rw-r--r--src/gui/kernel/qeventdispatcher_glib_qpa_p.h88
-rw-r--r--src/gui/kernel/qeventdispatcher_glib_qws.cpp195
-rw-r--r--src/gui/kernel/qeventdispatcher_glib_qws_p.h78
-rw-r--r--src/gui/kernel/qeventdispatcher_qpa.cpp334
-rw-r--r--src/gui/kernel/qeventdispatcher_qpa_p.h86
-rw-r--r--src/gui/kernel/qeventdispatcher_qws.cpp168
-rw-r--r--src/gui/kernel/qeventdispatcher_qws_p.h86
-rw-r--r--src/gui/kernel/qeventdispatcher_s60_p.h127
-rw-r--r--src/gui/kernel/qformlayout.h163
-rw-r--r--src/gui/kernel/qgenericpluginfactory_qpa.cpp2
-rw-r--r--src/gui/kernel/qgesture.cpp807
-rw-r--r--src/gui/kernel/qgesture.h275
-rw-r--r--src/gui/kernel/qgesture_p.h197
-rw-r--r--src/gui/kernel/qgesturemanager.cpp720
-rw-r--r--src/gui/kernel/qgesturerecognizer.h102
-rw-r--r--src/gui/kernel/qgridlayout.h176
-rw-r--r--src/gui/kernel/qguiapplication.cpp1495
-rw-r--r--src/gui/kernel/qguiapplication.h158
-rw-r--r--src/gui/kernel/qguiapplication_p.h194
-rw-r--r--src/gui/kernel/qguiplatformplugin_p.h126
-rw-r--r--src/gui/kernel/qguivariant.cpp87
-rw-r--r--src/gui/kernel/qinputpanel.cpp190
-rw-r--r--src/gui/kernel/qinputpanel.h123
-rw-r--r--src/gui/kernel/qinputpanel_p.h69
-rw-r--r--src/gui/kernel/qkde_p.h81
-rw-r--r--src/gui/kernel/qkeymapper.cpp6
-rw-r--r--src/gui/kernel/qkeymapper_mac.cpp1023
-rw-r--r--src/gui/kernel/qkeymapper_p.h4
-rw-r--r--src/gui/kernel/qkeymapper_qpa.cpp (renamed from src/gui/kernel/qkeymapper_qws.cpp)0
-rw-r--r--src/gui/kernel/qkeymapper_win.cpp1207
-rw-r--r--src/gui/kernel/qkeysequence.cpp349
-rw-r--r--src/gui/kernel/qkeysequence.h3
-rw-r--r--src/gui/kernel/qlayout.h245
-rw-r--r--src/gui/kernel/qlayout_p.h101
-rw-r--r--src/gui/kernel/qlayoutengine.cpp436
-rw-r--r--src/gui/kernel/qlayoutengine_p.h140
-rw-r--r--src/gui/kernel/qlayoutitem.h182
-rw-r--r--src/gui/kernel/qmacdefines_mac.h180
-rw-r--r--src/gui/kernel/qmime_mac.cpp1310
-rw-r--r--src/gui/kernel/qopenglcontext.cpp605
-rw-r--r--src/gui/kernel/qopenglcontext.h146
-rw-r--r--src/gui/kernel/qopenglcontext_p.h234
-rw-r--r--src/gui/kernel/qpalette.cpp194
-rw-r--r--src/gui/kernel/qpalette.h73
-rw-r--r--src/gui/kernel/qplatformclipboard_qpa.cpp10
-rw-r--r--src/gui/kernel/qplatformclipboard_qpa.h1
-rw-r--r--src/gui/kernel/qplatformcursor_qpa.cpp18
-rw-r--r--src/gui/kernel/qplatformcursor_qpa.h6
-rw-r--r--src/gui/kernel/qplatformdrag_qpa.h67
-rw-r--r--src/gui/kernel/qplatformeventloopintegration_qpa.cpp86
-rw-r--r--src/gui/kernel/qplatformeventloopintegration_qpa.h82
-rw-r--r--src/gui/kernel/qplatformglcontext_qpa.cpp210
-rw-r--r--src/gui/kernel/qplatformglcontext_qpa.h91
-rw-r--r--src/gui/kernel/qplatforminputcontext_qpa.cpp102
-rw-r--r--src/gui/kernel/qplatforminputcontext_qpa.h81
-rw-r--r--src/gui/kernel/qplatformintegration_qpa.cpp185
-rw-r--r--src/gui/kernel/qplatformintegration_qpa.h59
-rw-r--r--src/gui/kernel/qplatformintegrationfactory_qpa.cpp2
-rw-r--r--src/gui/kernel/qplatformnativeinterface_qpa.cpp18
-rw-r--r--src/gui/kernel/qplatformnativeinterface_qpa.h9
-rw-r--r--src/gui/kernel/qplatformopenglcontext_qpa.cpp111
-rw-r--r--src/gui/kernel/qplatformopenglcontext_qpa.h90
-rw-r--r--src/gui/kernel/qplatformscreen_qpa.cpp91
-rw-r--r--src/gui/kernel/qplatformscreen_qpa.h41
-rw-r--r--src/gui/kernel/qplatformsurface_qpa.cpp56
-rw-r--r--src/gui/kernel/qplatformsurface_qpa.h74
-rw-r--r--src/gui/kernel/qplatformwindow_qpa.cpp118
-rw-r--r--src/gui/kernel/qplatformwindow_qpa.h33
-rw-r--r--src/gui/kernel/qplatformwindowformat_qpa.cpp994
-rw-r--r--src/gui/kernel/qplatformwindowformat_qpa.h234
-rw-r--r--src/gui/kernel/qscreen.cpp212
-rw-r--r--src/gui/kernel/qscreen.h98
-rw-r--r--src/gui/kernel/qsessionmanager.h4
-rw-r--r--src/gui/kernel/qsessionmanager_qpa.cpp4
-rw-r--r--src/gui/kernel/qsessionmanager_qws.cpp171
-rw-r--r--src/gui/kernel/qshortcut.h107
-rw-r--r--src/gui/kernel/qshortcutmap.cpp897
-rw-r--r--src/gui/kernel/qsizepolicy.h244
-rw-r--r--src/gui/kernel/qsoftkeymanager_p.h115
-rw-r--r--src/gui/kernel/qsound.cpp390
-rw-r--r--src/gui/kernel/qsound.h95
-rw-r--r--src/gui/kernel/qsound_qws.cpp350
-rw-r--r--src/gui/kernel/qstackedlayout.h115
-rw-r--r--src/gui/kernel/qstylehints.cpp80
-rw-r--r--src/gui/kernel/qstylehints.h73
-rw-r--r--src/gui/kernel/qsurface.cpp57
-rw-r--r--src/gui/kernel/qsurface.h82
-rw-r--r--src/gui/kernel/qsurfaceformat.cpp466
-rw-r--r--src/gui/kernel/qsurfaceformat.h152
-rw-r--r--src/gui/kernel/qt_cocoa_helpers_mac.mm1824
-rw-r--r--src/gui/kernel/qt_cocoa_helpers_mac_p.h340
-rw-r--r--src/gui/kernel/qt_gui_pch.h8
-rw-r--r--src/gui/kernel/qt_mac_p.h286
-rw-r--r--src/gui/kernel/qt_x11_p.h757
-rw-r--r--src/gui/kernel/qtooltip.h84
-rw-r--r--src/gui/kernel/qwhatsthis.cpp777
-rw-r--r--src/gui/kernel/qwhatsthis.h88
-rw-r--r--src/gui/kernel/qwidget.cpp12686
-rw-r--r--src/gui/kernel/qwidget.h1090
-rw-r--r--src/gui/kernel/qwidget_p.h1036
-rw-r--r--src/gui/kernel/qwidget_qpa.cpp890
-rw-r--r--src/gui/kernel/qwidget_qws.cpp1221
-rw-r--r--src/gui/kernel/qwidget_x11.cpp3149
-rw-r--r--src/gui/kernel/qwidgetaction.h91
-rw-r--r--src/gui/kernel/qwindow.cpp701
-rw-r--r--src/gui/kernel/qwindow.h227
-rw-r--r--src/gui/kernel/qwindow_p.h118
-rw-r--r--src/gui/kernel/qwindowdefs.h12
-rw-r--r--src/gui/kernel/qwindowdefs_win.h4
-rw-r--r--src/gui/kernel/qwindowsysteminterface_qpa.cpp152
-rw-r--r--src/gui/kernel/qwindowsysteminterface_qpa.h51
-rw-r--r--src/gui/kernel/qwindowsysteminterface_qpa_p.h81
-rw-r--r--src/gui/kernel/qx11embed_x11.h132
-rw-r--r--src/gui/kernel/qx11info_x11.h123
-rw-r--r--src/gui/mac/macresources.qrc12
-rw-r--r--src/gui/opengl/opengl.pri48
-rw-r--r--src/gui/opengl/qopengl.cpp109
-rw-r--r--src/gui/opengl/qopengl.h76
-rw-r--r--src/gui/opengl/qopengl2pexvertexarray.cpp175
-rw-r--r--src/gui/opengl/qopengl2pexvertexarray_p.h169
-rw-r--r--src/gui/opengl/qopengl_p.h87
-rw-r--r--src/gui/opengl/qopenglbuffer.cpp567
-rw-r--r--src/gui/opengl/qopenglbuffer.h132
-rw-r--r--src/gui/opengl/qopenglcolormap.cpp297
-rw-r--r--src/gui/opengl/qopenglcolormap.h105
-rw-r--r--src/gui/opengl/qopenglcustomshaderstage.cpp138
-rw-r--r--src/gui/opengl/qopenglcustomshaderstage_p.h94
-rw-r--r--src/gui/opengl/qopenglengineshadermanager.cpp881
-rw-r--r--src/gui/opengl/qopenglengineshadermanager_p.h514
-rw-r--r--src/gui/opengl/qopenglengineshadersource_p.h529
-rw-r--r--src/gui/opengl/qopenglextensions_p.h677
-rw-r--r--src/gui/opengl/qopenglframebufferobject.cpp1229
-rw-r--r--src/gui/opengl/qopenglframebufferobject.h163
-rw-r--r--src/gui/opengl/qopenglframebufferobject_p.h142
-rw-r--r--src/gui/opengl/qopenglfunctions.cpp2452
-rw-r--r--src/gui/opengl/qopenglfunctions.h2427
-rw-r--r--src/gui/opengl/qopenglgradientcache.cpp227
-rw-r--r--src/gui/opengl/qopenglgradientcache_p.h101
-rw-r--r--src/gui/opengl/qopenglpaintdevice.cpp231
-rw-r--r--src/gui/opengl/qopenglpaintdevice.h103
-rw-r--r--src/gui/opengl/qopenglpaintengine.cpp2432
-rw-r--r--src/gui/opengl/qopenglpaintengine_p.h339
-rw-r--r--src/gui/opengl/qopenglshadercache_meego_p.h457
-rw-r--r--src/gui/opengl/qopenglshadercache_p.h98
-rw-r--r--src/gui/opengl/qopenglshaderprogram.cpp3105
-rw-r--r--src/gui/opengl/qopenglshaderprogram.h317
-rw-r--r--src/gui/opengl/qopengltexturecache.cpp215
-rw-r--r--src/gui/opengl/qopengltexturecache_p.h102
-rw-r--r--src/gui/opengl/qopengltextureglyphcache.cpp396
-rw-r--r--src/gui/opengl/qopengltextureglyphcache_p.h170
-rw-r--r--src/gui/opengl/qopengltriangulatingstroker.cpp588
-rw-r--r--src/gui/opengl/qopengltriangulatingstroker_p.h157
-rw-r--r--src/gui/opengl/qrbtree_p.h573
-rw-r--r--src/gui/opengl/qtriangulator.cpp2621
-rw-r--r--src/gui/opengl/qtriangulator_p.h148
-rwxr-xr-xsrc/gui/painting/makepsheader.pl195
-rw-r--r--src/gui/painting/painting.pri170
-rw-r--r--src/gui/painting/qbackingstore.cpp1656
-rw-r--r--src/gui/painting/qbackingstore.h93
-rw-r--r--src/gui/painting/qbackingstore_p.h278
-rw-r--r--src/gui/painting/qbrush.cpp32
-rw-r--r--src/gui/painting/qbrush.h10
-rw-r--r--src/gui/painting/qcolor.cpp86
-rw-r--r--src/gui/painting/qcolor.h26
-rw-r--r--src/gui/painting/qcolormap.h97
-rw-r--r--src/gui/painting/qcolormap_qpa.cpp231
-rw-r--r--src/gui/painting/qcolormap_qws.cpp185
-rw-r--r--src/gui/painting/qcssutil_p.h4
-rw-r--r--src/gui/painting/qcups.cpp401
-rw-r--r--src/gui/painting/qcups_p.h121
-rw-r--r--src/gui/painting/qdrawhelper.cpp744
-rw-r--r--src/gui/painting/qdrawhelper_p.h145
-rw-r--r--src/gui/painting/qdrawutil.cpp1360
-rw-r--r--src/gui/painting/qdrawutil.h195
-rw-r--r--src/gui/painting/qgraphicssystem.cpp97
-rw-r--r--src/gui/painting/qgraphicssystem_mac.cpp59
-rw-r--r--src/gui/painting/qgraphicssystem_mac_p.h69
-rw-r--r--src/gui/painting/qgraphicssystem_p.h85
-rw-r--r--src/gui/painting/qgraphicssystem_qws.cpp62
-rw-r--r--src/gui/painting/qgraphicssystem_qws_p.h79
-rw-r--r--src/gui/painting/qgraphicssystem_raster.cpp72
-rw-r--r--src/gui/painting/qgraphicssystem_raster_p.h69
-rw-r--r--src/gui/painting/qgraphicssystem_runtime.cpp426
-rw-r--r--src/gui/painting/qgraphicssystem_runtime_p.h187
-rw-r--r--src/gui/painting/qgraphicssystemfactory.cpp123
-rw-r--r--src/gui/painting/qgraphicssystemfactory_p.h78
-rw-r--r--src/gui/painting/qgraphicssystemplugin.cpp56
-rw-r--r--src/gui/painting/qgraphicssystemplugin_p.h92
-rw-r--r--src/gui/painting/qmatrix.cpp36
-rw-r--r--src/gui/painting/qmatrix.h12
-rw-r--r--src/gui/painting/qmemrotate.cpp12
-rw-r--r--src/gui/painting/qmemrotate_p.h2
-rw-r--r--src/gui/painting/qpagedpaintdevice.cpp227
-rw-r--r--src/gui/painting/qpagedpaintdevice.h53
-rw-r--r--src/gui/painting/qpagedpaintdevice_p.h89
-rw-r--r--src/gui/painting/qpaintdevice.cpp17
-rw-r--r--src/gui/painting/qpaintdevice.h59
-rw-r--r--src/gui/painting/qpaintdevice_mac.cpp152
-rw-r--r--src/gui/painting/qpaintdevice_qpa.cpp5
-rw-r--r--src/gui/painting/qpaintdevice_qws.cpp56
-rw-r--r--src/gui/painting/qpaintdevice_x11.cpp198
-rw-r--r--src/gui/painting/qpaintengine.cpp6
-rw-r--r--src/gui/painting/qpaintengine.h2
-rw-r--r--src/gui/painting/qpaintengine_blitter.cpp9
-rw-r--r--src/gui/painting/qpaintengine_blitter_p.h4
-rw-r--r--src/gui/painting/qpaintengine_mac.cpp1747
-rw-r--r--src/gui/painting/qpaintengine_p.h4
-rw-r--r--src/gui/painting/qpaintengine_preview.cpp223
-rw-r--r--src/gui/painting/qpaintengine_preview_p.h106
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp370
-rw-r--r--src/gui/painting/qpaintengine_raster_p.h69
-rw-r--r--src/gui/painting/qpaintengine_s60.cpp145
-rw-r--r--src/gui/painting/qpaintengine_s60_p.h84
-rw-r--r--src/gui/painting/qpaintengine_x11.cpp2499
-rw-r--r--src/gui/painting/qpaintengine_x11_p.h246
-rw-r--r--src/gui/painting/qpaintengineex_p.h2
-rw-r--r--src/gui/painting/qpainter.cpp653
-rw-r--r--src/gui/painting/qpainter.h77
-rw-r--r--src/gui/painting/qpathclipper_p.h2
-rw-r--r--src/gui/painting/qpdf.cpp1820
-rw-r--r--src/gui/painting/qpdf_p.h151
-rw-r--r--src/gui/painting/qpdfwriter.cpp212
-rw-r--r--src/gui/painting/qpdfwriter.h91
-rw-r--r--src/gui/painting/qplatformbackingstore_qpa.cpp155
-rw-r--r--src/gui/painting/qplatformbackingstore_qpa.h86
-rw-r--r--src/gui/painting/qprintengine.h119
-rw-r--r--src/gui/painting/qprintengine_pdf.cpp1244
-rw-r--r--src/gui/painting/qprintengine_pdf_p.h195
-rw-r--r--src/gui/painting/qprintengine_ps.cpp972
-rw-r--r--src/gui/painting/qprintengine_ps_p.h137
-rw-r--r--src/gui/painting/qprintengine_qws.cpp886
-rw-r--r--src/gui/painting/qprintengine_qws_p.h213
-rw-r--r--src/gui/painting/qprinter.cpp2453
-rw-r--r--src/gui/painting/qprinter.h337
-rw-r--r--src/gui/painting/qprinter_p.h140
-rw-r--r--src/gui/painting/qprinterinfo.cpp173
-rw-r--r--src/gui/painting/qprinterinfo.h90
-rw-r--r--src/gui/painting/qprinterinfo_p.h107
-rw-r--r--src/gui/painting/qprinterinfo_unix.cpp927
-rw-r--r--src/gui/painting/qprinterinfo_unix_p.h125
-rw-r--r--src/gui/painting/qpsprinter.agl452
-rw-r--r--src/gui/painting/qpsprinter.ps449
-rw-r--r--src/gui/painting/qregion.cpp21
-rw-r--r--src/gui/painting/qregion.h9
-rw-r--r--src/gui/painting/qregion_mac.cpp286
-rw-r--r--src/gui/painting/qregion_qws.cpp3183
-rw-r--r--src/gui/painting/qstylepainter.h112
-rw-r--r--src/gui/painting/qtessellator.cpp1498
-rw-r--r--src/gui/painting/qtessellator_p.h102
-rw-r--r--src/gui/painting/qunifiedtoolbarsurface_mac.cpp265
-rw-r--r--src/gui/painting/qunifiedtoolbarsurface_mac_p.h140
-rw-r--r--src/gui/painting/qwindowsurface.cpp383
-rw-r--r--src/gui/painting/qwindowsurface_mac.cpp139
-rw-r--r--src/gui/painting/qwindowsurface_mac_p.h84
-rw-r--r--src/gui/painting/qwindowsurface_p.h138
-rw-r--r--src/gui/painting/qwindowsurface_qws.cpp1433
-rw-r--r--src/gui/painting/qwindowsurface_qws_p.h355
-rw-r--r--src/gui/painting/qwindowsurface_raster.cpp487
-rw-r--r--src/gui/painting/qwindowsurface_raster_p.h132
-rw-r--r--src/gui/painting/qwindowsurface_s60.cpp254
-rw-r--r--src/gui/painting/qwindowsurface_s60_p.h93
-rw-r--r--src/gui/painting/qwindowsurface_x11.cpp265
-rw-r--r--src/gui/painting/qwindowsurface_x11_p.h92
-rw-r--r--src/gui/painting/qwmatrix.h61
-rw-r--r--src/gui/s60framework/qs60mainapplication.h93
-rw-r--r--src/gui/s60framework/qs60mainappui.cpp430
-rw-r--r--src/gui/s60framework/qs60mainappui.h152
-rw-r--r--src/gui/s60framework/qs60maindocument.h92
-rw-r--r--src/gui/statemachine/qguistatemachine.cpp523
-rw-r--r--src/gui/statemachine/qkeyeventtransition.h88
-rw-r--r--src/gui/statemachine/qmouseeventtransition.h92
-rw-r--r--src/gui/styles/qcdestyle.h82
-rw-r--r--src/gui/styles/qcleanlooksstyle.h114
-rw-r--r--src/gui/styles/qcommonstyle.h109
-rw-r--r--src/gui/styles/qgtkpainter.cpp716
-rw-r--r--src/gui/styles/qgtkpainter_p.h129
-rw-r--r--src/gui/styles/qgtkstyle.cpp3560
-rw-r--r--src/gui/styles/qgtkstyle.h128
-rw-r--r--src/gui/styles/qgtkstyle_p.cpp1146
-rw-r--r--src/gui/styles/qgtkstyle_p.h531
-rw-r--r--src/gui/styles/qmacstyle_mac.h148
-rw-r--r--src/gui/styles/qmacstyle_mac.mm6042
-rw-r--r--src/gui/styles/qmacstyle_mac_p.h241
-rw-r--r--src/gui/styles/qmotifstyle.cpp2721
-rw-r--r--src/gui/styles/qmotifstyle.h128
-rw-r--r--src/gui/styles/qplastiquestyle.h119
-rw-r--r--src/gui/styles/qproxystyle.h114
-rw-r--r--src/gui/styles/qs60style.h118
-rw-r--r--src/gui/styles/qs60style_s60.cpp1591
-rw-r--r--src/gui/styles/qstyle.cpp2493
-rw-r--r--src/gui/styles/qstyle.h889
-rw-r--r--src/gui/styles/qstyle_p.h108
-rw-r--r--src/gui/styles/qstylefactory.h66
-rw-r--r--src/gui/styles/qstylehelper_p.h118
-rw-r--r--src/gui/styles/qstyleoption.h970
-rw-r--r--src/gui/styles/qstyleplugin.h81
-rw-r--r--src/gui/styles/qstylesheetstyle.cpp5898
-rw-r--r--src/gui/styles/qstylesheetstyle_p.h204
-rw-r--r--src/gui/styles/qwindowscestyle.h103
-rw-r--r--src/gui/styles/qwindowsmobilestyle.h116
-rw-r--r--src/gui/styles/qwindowsstyle.cpp3390
-rw-r--r--src/gui/styles/qwindowsstyle.h111
-rw-r--r--src/gui/styles/qwindowsvistastyle.cpp2669
-rw-r--r--src/gui/styles/qwindowsvistastyle.h108
-rw-r--r--src/gui/styles/qwindowsxpstyle.cpp4277
-rw-r--r--src/gui/styles/qwindowsxpstyle.h107
-rw-r--r--src/gui/styles/qwindowsxpstyle_p.h356
-rw-r--r--src/gui/styles/styles.pri190
-rw-r--r--src/gui/symbian/qsymbianevent.h108
-rw-r--r--src/gui/text/qabstractfontengine_qws.cpp776
-rw-r--r--src/gui/text/qabstractfontengine_qws.h221
-rw-r--r--src/gui/text/qabstracttextdocumentlayout.h1
-rw-r--r--src/gui/text/qcssparser.cpp6
-rw-r--r--src/gui/text/qcssparser_p.h14
-rw-r--r--src/gui/text/qfont.cpp101
-rw-r--r--src/gui/text/qfont.h10
-rw-r--r--src/gui/text/qfont_qpa.cpp5
-rw-r--r--src/gui/text/qfont_qws.cpp135
-rw-r--r--src/gui/text/qfont_x11.cpp368
-rw-r--r--src/gui/text/qfontdatabase.cpp48
-rw-r--r--src/gui/text/qfontdatabase.h4
-rw-r--r--src/gui/text/qfontdatabase_qpa.cpp31
-rw-r--r--src/gui/text/qfontdatabase_qws.cpp972
-rw-r--r--src/gui/text/qfontengine.cpp39
-rw-r--r--src/gui/text/qfontengine_ft_p.h2
-rw-r--r--src/gui/text/qfontengine_p.h6
-rw-r--r--src/gui/text/qfontengine_qpa.cpp3
-rw-r--r--src/gui/text/qfontengine_qws.cpp662
-rw-r--r--src/gui/text/qfontengine_x11.cpp1203
-rw-r--r--src/gui/text/qfontengine_x11_p.h180
-rw-r--r--src/gui/text/qfontmetrics.h9
-rw-r--r--src/gui/text/qfontsubset.cpp249
-rw-r--r--src/gui/text/qfontsubset_p.h6
-rw-r--r--src/gui/text/qglyphrun.cpp33
-rw-r--r--src/gui/text/qglyphrun.h10
-rw-r--r--src/gui/text/qglyphrun_p.h6
-rw-r--r--src/gui/text/qlinecontrol.cpp1705
-rw-r--r--src/gui/text/qlinecontrol_p.h455
-rw-r--r--src/gui/text/qplatformfontdatabase_qpa.cpp24
-rw-r--r--src/gui/text/qplatformfontdatabase_qpa.h4
-rw-r--r--src/gui/text/qrawfont.cpp129
-rw-r--r--src/gui/text/qrawfont.h5
-rw-r--r--src/gui/text/qrawfont_p.h8
-rw-r--r--src/gui/text/qrawfont_qpa.cpp4
-rw-r--r--src/gui/text/qstatictext.cpp4
-rw-r--r--src/gui/text/qsyntaxhighlighter.cpp21
-rw-r--r--src/gui/text/qsyntaxhighlighter.h2
-rw-r--r--src/gui/text/qtextcontrol.cpp458
-rw-r--r--src/gui/text/qtextcontrol_p.h51
-rw-r--r--src/gui/text/qtextcontrol_p_p.h12
-rw-r--r--src/gui/text/qtextcursor.h3
-rw-r--r--src/gui/text/qtextcursor_p.h4
-rw-r--r--src/gui/text/qtextdocument.cpp119
-rw-r--r--src/gui/text/qtextdocument.h6
-rw-r--r--src/gui/text/qtextdocumentlayout.cpp4
-rw-r--r--src/gui/text/qtextdocumentlayout_p.h2
-rw-r--r--src/gui/text/qtextengine.cpp8
-rw-r--r--src/gui/text/qtextengine_p.h6
-rw-r--r--src/gui/text/qtexthtmlparser.cpp6
-rw-r--r--src/gui/text/qtextimagehandler.cpp14
-rw-r--r--src/gui/text/qtextlayout.cpp2
-rw-r--r--src/gui/text/qtextoption.cpp4
-rw-r--r--src/gui/text/text.pri36
-rw-r--r--src/gui/util/qcompleter.cpp1833
-rw-r--r--src/gui/util/qcompleter.h171
-rw-r--r--src/gui/util/qcompleter_p.h264
-rw-r--r--src/gui/util/qdesktopservices.cpp2
-rw-r--r--src/gui/util/qdesktopservices_qpa.cpp94
-rw-r--r--src/gui/util/qdesktopservices_qws.cpp93
-rw-r--r--src/gui/util/qflickgesture.cpp715
-rw-r--r--src/gui/util/qflickgesture_p.h113
-rw-r--r--src/gui/util/qhexstring_p.h98
-rw-r--r--src/gui/util/qscroller.h155
-rw-r--r--src/gui/util/qscrollerproperties.h140
-rw-r--r--src/gui/util/qsystemtrayicon.cpp674
-rw-r--r--src/gui/util/qsystemtrayicon.h132
-rw-r--r--src/gui/util/qsystemtrayicon_p.h186
-rw-r--r--src/gui/util/qundogroup.h110
-rw-r--r--src/gui/util/qundostack.h159
-rw-r--r--src/gui/util/qundostack_p.h114
-rw-r--r--src/gui/util/qundoview.cpp476
-rw-r--r--src/gui/util/qundoview.h102
-rw-r--r--src/gui/util/qvalidator.cpp (renamed from src/gui/widgets/qvalidator.cpp)0
-rw-r--r--src/gui/util/qvalidator.h (renamed from src/gui/widgets/qvalidator.h)0
-rw-r--r--src/gui/util/util.pri67
-rw-r--r--src/gui/widgets/qabstractbutton.cpp1470
-rw-r--r--src/gui/widgets/qabstractbutton.h180
-rw-r--r--src/gui/widgets/qabstractplatformmenubar_p.h108
-rw-r--r--src/gui/widgets/qabstractscrollarea.h144
-rw-r--r--src/gui/widgets/qabstractscrollarea_p.h146
-rw-r--r--src/gui/widgets/qabstractslider.h184
-rw-r--r--src/gui/widgets/qabstractspinbox.h181
-rw-r--r--src/gui/widgets/qabstractspinbox_p.h170
-rw-r--r--src/gui/widgets/qbuttongroup.h112
-rw-r--r--src/gui/widgets/qcalendarwidget.h204
-rw-r--r--src/gui/widgets/qcheckbox.h114
-rw-r--r--src/gui/widgets/qcocoamenu_mac.mm244
-rw-r--r--src/gui/widgets/qcocoamenu_mac_p.h82
-rw-r--r--src/gui/widgets/qcombobox.h339
-rw-r--r--src/gui/widgets/qcombobox_p.h421
-rw-r--r--src/gui/widgets/qcommandlinkbutton.h85
-rw-r--r--src/gui/widgets/qdatetimeedit.h230
-rw-r--r--src/gui/widgets/qdatetimeedit_p.h185
-rw-r--r--src/gui/widgets/qdial.h122
-rw-r--r--src/gui/widgets/qdialogbuttonbox.cpp1285
-rw-r--r--src/gui/widgets/qdialogbuttonbox.h168
-rw-r--r--src/gui/widgets/qdockarealayout.cpp3329
-rw-r--r--src/gui/widgets/qdockarealayout_p.h308
-rw-r--r--src/gui/widgets/qdockwidget.cpp1605
-rw-r--r--src/gui/widgets/qdockwidget.h146
-rw-r--r--src/gui/widgets/qdockwidget_p.h207
-rw-r--r--src/gui/widgets/qeffects_p.h84
-rw-r--r--src/gui/widgets/qfocusframe.h82
-rw-r--r--src/gui/widgets/qfontcombobox.h112
-rw-r--r--src/gui/widgets/qframe.h148
-rw-r--r--src/gui/widgets/qgroupbox.h122
-rw-r--r--src/gui/widgets/qlabel.cpp1734
-rw-r--r--src/gui/widgets/qlabel.h182
-rw-r--r--src/gui/widgets/qlabel_p.h153
-rw-r--r--src/gui/widgets/qlcdnumber.h144
-rw-r--r--src/gui/widgets/qlinecontrol.cpp1920
-rw-r--r--src/gui/widgets/qlinecontrol_p.h514
-rw-r--r--src/gui/widgets/qlineedit.cpp2360
-rw-r--r--src/gui/widgets/qlineedit.h300
-rw-r--r--src/gui/widgets/qlineedit_p.cpp292
-rw-r--r--src/gui/widgets/qlineedit_p.h155
-rw-r--r--src/gui/widgets/qmaccocoaviewcontainer_mac.h73
-rw-r--r--src/gui/widgets/qmacnativewidget_mac.h74
-rw-r--r--src/gui/widgets/qmainwindow.cpp1686
-rw-r--r--src/gui/widgets/qmainwindow.h219
-rw-r--r--src/gui/widgets/qmainwindowlayout_p.h357
-rw-r--r--src/gui/widgets/qmdiarea.h179
-rw-r--r--src/gui/widgets/qmdiarea_p.h285
-rw-r--r--src/gui/widgets/qmdisubwindow.h159
-rw-r--r--src/gui/widgets/qmenu.cpp3560
-rw-r--r--src/gui/widgets/qmenu.h434
-rw-r--r--src/gui/widgets/qmenu_mac.mm2217
-rw-r--r--src/gui/widgets/qmenu_p.h395
-rw-r--r--src/gui/widgets/qmenubar.cpp2623
-rw-r--r--src/gui/widgets/qmenubar.h367
-rw-r--r--src/gui/widgets/qmenubar_p.h306
-rw-r--r--src/gui/widgets/qmenubar_x11.cpp139
-rw-r--r--src/gui/widgets/qmenubar_x11_p.h87
-rw-r--r--src/gui/widgets/qmenudata.cpp96
-rw-r--r--src/gui/widgets/qmenudata.h80
-rw-r--r--src/gui/widgets/qplaintextedit.cpp2998
-rw-r--r--src/gui/widgets/qplaintextedit.h329
-rw-r--r--src/gui/widgets/qplaintextedit_p.h187
-rw-r--r--src/gui/widgets/qprintpreviewwidget.cpp844
-rw-r--r--src/gui/widgets/qprintpreviewwidget.h127
-rw-r--r--src/gui/widgets/qprogressbar.h132
-rw-r--r--src/gui/widgets/qpushbutton.h127
-rw-r--r--src/gui/widgets/qradiobutton.h89
-rw-r--r--src/gui/widgets/qrubberband.h104
-rw-r--r--src/gui/widgets/qscrollarea.cpp522
-rw-r--r--src/gui/widgets/qscrollarea.h101
-rw-r--r--src/gui/widgets/qscrollarea_p.h81
-rw-r--r--src/gui/widgets/qscrollbar.cpp764
-rw-r--r--src/gui/widgets/qscrollbar.h104
-rw-r--r--src/gui/widgets/qsizegrip.cpp570
-rw-r--r--src/gui/widgets/qsizegrip.h95
-rw-r--r--src/gui/widgets/qslider.cpp652
-rw-r--r--src/gui/widgets/qslider.h134
-rw-r--r--src/gui/widgets/qspinbox.h188
-rw-r--r--src/gui/widgets/qsplashscreen.h99
-rw-r--r--src/gui/widgets/qsplitter.h192
-rw-r--r--src/gui/widgets/qstackedwidget.h100
-rw-r--r--src/gui/widgets/qstatusbar.h116
-rw-r--r--src/gui/widgets/qtabbar.h226
-rw-r--r--src/gui/widgets/qtabwidget.h254
-rw-r--r--src/gui/widgets/qtextbrowser.h140
-rw-r--r--src/gui/widgets/qtextedit.cpp2810
-rw-r--r--src/gui/widgets/qtextedit.h430
-rw-r--r--src/gui/widgets/qtextedit_p.h141
-rw-r--r--src/gui/widgets/qtoolbar.cpp1349
-rw-r--r--src/gui/widgets/qtoolbar.h188
-rw-r--r--src/gui/widgets/qtoolbar_p.h135
-rw-r--r--src/gui/widgets/qtoolbarextension_p.h80
-rw-r--r--src/gui/widgets/qtoolbarlayout_p.h134
-rw-r--r--src/gui/widgets/qtoolbarseparator_p.h88
-rw-r--r--src/gui/widgets/qtoolbox.h148
-rw-r--r--src/gui/widgets/qtoolbutton.h199
-rw-r--r--src/gui/widgets/qwidgetanimator.cpp117
-rw-r--r--src/gui/widgets/qwidgetresizehandler_p.h141
-rw-r--r--src/gui/widgets/qworkspace.h137
-rw-r--r--src/gui/widgets/widgets.pri177
-rw-r--r--src/modules/qt_gui.pri3
-rw-r--r--src/modules/qt_opengl.pri2
-rw-r--r--src/modules/qt_openvg.pri16
-rw-r--r--src/modules/qt_platformsupport.pri15
-rw-r--r--src/modules/qt_printsupport.pri16
-rw-r--r--src/modules/qt_widgets.pri14
-rw-r--r--src/opengl/gl2paintengineex/qglengineshadermanager.cpp55
-rw-r--r--src/opengl/gl2paintengineex/qglengineshadermanager_p.h1
-rw-r--r--src/opengl/gl2paintengineex/qglgradientcache.cpp25
-rw-r--r--src/opengl/gl2paintengineex/qglgradientcache_p.h9
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp36
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h8
-rw-r--r--src/opengl/gl2paintengineex/qrbtree_p.h573
-rw-r--r--src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp74
-rw-r--r--src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h48
-rw-r--r--src/opengl/gl2paintengineex/qtriangulator.cpp2612
-rw-r--r--src/opengl/gl2paintengineex/qtriangulator_p.h148
-rw-r--r--src/opengl/opengl.pro170
-rw-r--r--src/opengl/qgl.cpp825
-rw-r--r--src/opengl/qgl.h119
-rw-r--r--src/opengl/qgl_egl.cpp351
-rw-r--r--src/opengl/qgl_egl_p.h69
-rw-r--r--src/opengl/qgl_mac.mm996
-rw-r--r--src/opengl/qgl_p.h363
-rw-r--r--src/opengl/qgl_qpa.cpp224
-rw-r--r--src/opengl/qgl_qws.cpp318
-rw-r--r--src/opengl/qgl_symbian.cpp472
-rw-r--r--src/opengl/qgl_win.cpp1601
-rw-r--r--src/opengl/qgl_wince.cpp636
-rw-r--r--src/opengl/qgl_x11.cpp1904
-rw-r--r--src/opengl/qgl_x11egl.cpp562
-rw-r--r--src/opengl/qglbuffer.cpp71
-rw-r--r--src/opengl/qglextensions.cpp11
-rw-r--r--src/opengl/qglextensions_p.h40
-rw-r--r--src/opengl/qglframebufferobject.cpp208
-rw-r--r--src/opengl/qglframebufferobject.h19
-rw-r--r--src/opengl/qglframebufferobject_p.h17
-rw-r--r--src/opengl/qglfunctions.cpp36
-rw-r--r--src/opengl/qglfunctions.h20
-rw-r--r--src/opengl/qglpaintdevice.cpp22
-rw-r--r--src/opengl/qglpaintdevice_p.h2
-rw-r--r--src/opengl/qglpixelbuffer.cpp117
-rw-r--r--src/opengl/qglpixelbuffer.h13
-rw-r--r--src/opengl/qglpixelbuffer_egl.cpp224
-rw-r--r--src/opengl/qglpixelbuffer_mac.mm331
-rw-r--r--src/opengl/qglpixelbuffer_p.h103
-rw-r--r--src/opengl/qglpixelbuffer_win.cpp403
-rw-r--r--src/opengl/qglpixelbuffer_x11.cpp290
-rw-r--r--src/opengl/qglpixmapfilter.cpp621
-rw-r--r--src/opengl/qglpixmapfilter_p.h94
-rw-r--r--src/opengl/qglscreen_qws.cpp242
-rw-r--r--src/opengl/qglscreen_qws.h127
-rw-r--r--src/opengl/qglshaderprogram.cpp229
-rw-r--r--src/opengl/qglshaderprogram.h26
-rw-r--r--src/opengl/qgltexturepool.cpp244
-rw-r--r--src/opengl/qgltexturepool_p.h147
-rw-r--r--src/opengl/qglwindowsurface_qws.cpp133
-rw-r--r--src/opengl/qglwindowsurface_qws_p.h90
-rw-r--r--src/opengl/qgraphicsshadereffect.cpp6
-rw-r--r--src/opengl/qgraphicsshadereffect_p.h2
-rw-r--r--src/opengl/qgraphicssystem_gl.cpp114
-rw-r--r--src/opengl/qgraphicssystem_gl_p.h80
-rw-r--r--src/opengl/qpaintengine_opengl.cpp5635
-rw-r--r--src/opengl/qpaintengine_opengl_p.h158
-rw-r--r--src/opengl/qpixmapdata_gl.cpp829
-rw-r--r--src/opengl/qpixmapdata_gl_p.h247
-rw-r--r--src/opengl/qpixmapdata_poolgl.cpp934
-rw-r--r--src/opengl/qpixmapdata_x11gl_egl.cpp403
-rw-r--r--src/opengl/qpixmapdata_x11gl_p.h98
-rw-r--r--src/opengl/qwindowsurface_gl.cpp1174
-rw-r--r--src/opengl/qwindowsurface_gl_p.h129
-rw-r--r--src/opengl/qwindowsurface_x11gl.cpp213
-rw-r--r--src/opengl/qwindowsurface_x11gl_p.h83
-rw-r--r--src/opengl/util/README-GLSL18
-rw-r--r--src/opengl/util/brush_painter.glsl7
-rw-r--r--src/opengl/util/brushes.conf6
-rw-r--r--src/opengl/util/composition_mode_colorburn.glsl13
-rw-r--r--src/opengl/util/composition_mode_colordodge.glsl15
-rw-r--r--src/opengl/util/composition_mode_darken.glsl9
-rw-r--r--src/opengl/util/composition_mode_difference.glsl9
-rw-r--r--src/opengl/util/composition_mode_exclusion.glsl9
-rw-r--r--src/opengl/util/composition_mode_hardlight.glsl14
-rw-r--r--src/opengl/util/composition_mode_lighten.glsl9
-rw-r--r--src/opengl/util/composition_mode_multiply.glsl9
-rw-r--r--src/opengl/util/composition_mode_overlay.glsl13
-rw-r--r--src/opengl/util/composition_mode_screen.glsl6
-rw-r--r--src/opengl/util/composition_mode_softlight.glsl22
-rw-r--r--src/opengl/util/composition_modes.conf12
-rw-r--r--src/opengl/util/conical_brush.glsl27
-rw-r--r--src/opengl/util/ellipse_aa.glsl58
-rw-r--r--src/opengl/util/fast_painter.glsl19
-rw-r--r--src/opengl/util/fragmentprograms_p.h7287
-rw-r--r--src/opengl/util/generator.cpp500
-rw-r--r--src/opengl/util/generator.pro13
-rwxr-xr-xsrc/opengl/util/glsl_to_include.sh73
-rw-r--r--src/opengl/util/linear_brush.glsl22
-rw-r--r--src/opengl/util/masks.conf2
-rw-r--r--src/opengl/util/meego/main.cpp89
-rw-r--r--src/opengl/util/meego/shader-cache-introspector.pro7
-rw-r--r--src/opengl/util/painter.glsl21
-rw-r--r--src/opengl/util/painter_nomask.glsl9
-rw-r--r--src/opengl/util/pattern_brush.glsl23
-rw-r--r--src/opengl/util/radial_brush.glsl28
-rw-r--r--src/opengl/util/simple_porter_duff.glsl16
-rw-r--r--src/opengl/util/solid_brush.glsl4
-rw-r--r--src/opengl/util/texture_brush.glsl21
-rw-r--r--src/opengl/util/trap_exact_aa.glsl58
-rw-r--r--src/openvg/openvg.pro76
-rw-r--r--src/openvg/qpaintengine_vg.cpp4225
-rw-r--r--src/openvg/qpaintengine_vg_p.h179
-rw-r--r--src/openvg/qpixmapdata_vg.cpp575
-rw-r--r--src/openvg/qpixmapdata_vg_p.h202
-rw-r--r--src/openvg/qpixmapfilter_vg.cpp356
-rw-r--r--src/openvg/qpixmapfilter_vg_p.h108
-rw-r--r--src/openvg/qvg.h65
-rw-r--r--src/openvg/qvg_p.h112
-rw-r--r--src/openvg/qvg_symbian.cpp366
-rw-r--r--src/openvg/qvgcompositionhelper_p.h90
-rw-r--r--src/openvg/qvgfontglyphcache_p.h101
-rw-r--r--src/openvg/qvgimagepool.cpp233
-rw-r--r--src/openvg/qvgimagepool_p.h157
-rw-r--r--src/openvg/qwindowsurface_vg.cpp148
-rw-r--r--src/openvg/qwindowsurface_vg_p.h94
-rw-r--r--src/openvg/qwindowsurface_vgegl.cpp783
-rw-r--r--src/openvg/qwindowsurface_vgegl_p.h148
-rw-r--r--src/platformsupport/cglconvenience/cglconvenience.mm108
-rw-r--r--src/platformsupport/cglconvenience/cglconvenience.pri11
-rw-r--r--src/platformsupport/cglconvenience/cglconvenience_p.h54
-rw-r--r--src/platformsupport/dnd/dnd.pri4
-rw-r--r--src/platformsupport/dnd/qsimpledrag.cpp202
-rw-r--r--src/platformsupport/dnd/qsimpledrag_p.h75
-rw-r--r--src/platformsupport/eglconvenience/eglconvenience.pri16
-rw-r--r--src/platformsupport/eglconvenience/qeglconvenience.cpp313
-rw-r--r--src/platformsupport/eglconvenience/qeglconvenience_p.h60
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformcontext.cpp160
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformcontext_p.h76
-rw-r--r--src/platformsupport/eglconvenience/qxlibeglintegration.cpp184
-rw-r--r--src/platformsupport/eglconvenience/qxlibeglintegration_p.h53
-rw-r--r--src/platformsupport/eventdispatchers/eventdispatchers.pri16
-rw-r--r--src/platformsupport/eventdispatchers/qeventdispatcher_glib.cpp117
-rw-r--r--src/platformsupport/eventdispatchers/qeventdispatcher_glib_p.h86
-rw-r--r--src/platformsupport/eventdispatchers/qeventdispatcher_qpa.cpp92
-rw-r--r--src/platformsupport/eventdispatchers/qeventdispatcher_qpa_p.h80
-rw-r--r--src/platformsupport/eventdispatchers/qgenericunixeventdispatcher.cpp55
-rw-r--r--src/platformsupport/eventdispatchers/qgenericunixeventdispatcher_p.h43
-rw-r--r--src/platformsupport/fb_base/fb_base.cpp507
-rw-r--r--src/platformsupport/fb_base/fb_base.pri4
-rw-r--r--src/platformsupport/fb_base/fb_base_p.h (renamed from src/plugins/platforms/fb_base/fb_base.h)0
-rw-r--r--src/platformsupport/fontdatabases/basicunix/basicunix.pri84
-rw-r--r--src/platformsupport/fontdatabases/basicunix/qbasicunixfontdatabase.cpp422
-rw-r--r--src/platformsupport/fontdatabases/basicunix/qbasicunixfontdatabase_p.h68
-rw-r--r--src/platformsupport/fontdatabases/fontconfig/fontconfig.pri2
-rw-r--r--src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp604
-rw-r--r--src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h56
-rw-r--r--src/platformsupport/fontdatabases/fontdatabases.pri10
-rw-r--r--src/platformsupport/fontdatabases/genericunix/genericunix.pri1
-rw-r--r--src/platformsupport/fontdatabases/genericunix/qgenericunixfontdatabase_p.h53
-rw-r--r--src/platformsupport/glxconvenience/glxconvenience.pri6
-rw-r--r--src/platformsupport/glxconvenience/qglxconvenience.cpp225
-rw-r--r--src/platformsupport/glxconvenience/qglxconvenience_p.h57
-rw-r--r--src/platformsupport/inputcontext/inputcontext.pri6
-rw-r--r--src/platformsupport/inputcontext/qplatforminputcontextfactory_qpa.cpp110
-rw-r--r--src/platformsupport/inputcontext/qplatforminputcontextfactory_qpa_p.h79
-rw-r--r--src/platformsupport/inputcontext/qplatforminputcontextplugin_qpa.cpp55
-rw-r--r--src/platformsupport/inputcontext/qplatforminputcontextplugin_qpa_p.h92
-rw-r--r--src/platformsupport/platformsupport.pro33
-rw-r--r--src/platformsupport/printersupport/genericunix/genericunix.pri4
-rw-r--r--src/platformsupport/printersupport/genericunix/qgenericunixprintersupport.cpp71
-rw-r--r--src/platformsupport/printersupport/genericunix/qgenericunixprintersupport_p.h59
-rw-r--r--src/platformsupport/printersupport/printersupport.pri3
-rw-r--r--src/plugins/accessible/widgets/complexwidgets.h6
-rw-r--r--src/plugins/accessible/widgets/itemviews.h10
-rw-r--r--src/plugins/accessible/widgets/qaccessiblemenu.cpp2
-rw-r--r--src/plugins/accessible/widgets/qaccessiblemenu.h2
-rw-r--r--src/plugins/accessible/widgets/qaccessiblewidgets.cpp2
-rw-r--r--src/plugins/accessible/widgets/qaccessiblewidgets.h4
-rw-r--r--src/plugins/accessible/widgets/rangecontrols.h4
-rw-r--r--src/plugins/accessible/widgets/simplewidgets.h4
-rw-r--r--src/plugins/accessible/widgets/widgets.pro2
-rw-r--r--src/plugins/decorations/decorations.pro4
-rw-r--r--src/plugins/decorations/default/default.pro10
-rw-r--r--src/plugins/decorations/default/main.cpp76
-rw-r--r--src/plugins/decorations/styled/main.cpp77
-rw-r--r--src/plugins/decorations/styled/styled.pro13
-rw-r--r--src/plugins/decorations/windows/main.cpp76
-rw-r--r--src/plugins/decorations/windows/windows.pro10
-rw-r--r--src/plugins/generic/linuxinput/linuxinput.pro6
-rw-r--r--src/plugins/generic/linuxinput/main.cpp5
-rw-r--r--src/plugins/generic/linuxinput/qlinuxinput.cpp192
-rw-r--r--src/plugins/generic/linuxinput/qlinuxinput.h25
-rw-r--r--src/plugins/gfxdrivers/ahi/ahi.pro14
-rw-r--r--src/plugins/gfxdrivers/ahi/qscreenahi_qws.cpp598
-rw-r--r--src/plugins/gfxdrivers/ahi/qscreenahi_qws.h84
-rw-r--r--src/plugins/gfxdrivers/ahi/qscreenahiplugin.cpp74
-rw-r--r--src/plugins/gfxdrivers/directfb/directfb.pro15
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbkeyboard.cpp436
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbkeyboard.h74
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbmouse.cpp294
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbmouse.h75
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp221
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h108
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp1430
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.h123
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp588
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h105
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp1819
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbscreen.h303
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbscreenplugin.cpp78
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp506
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h129
-rw-r--r--src/plugins/gfxdrivers/eglnullws/README48
-rw-r--r--src/plugins/gfxdrivers/eglnullws/eglnullws.pro18
-rw-r--r--src/plugins/gfxdrivers/eglnullws/eglnullwsscreen.cpp181
-rw-r--r--src/plugins/gfxdrivers/eglnullws/eglnullwsscreen.h69
-rw-r--r--src/plugins/gfxdrivers/eglnullws/eglnullwsscreenplugin.cpp66
-rw-r--r--src/plugins/gfxdrivers/eglnullws/eglnullwsscreenplugin.h47
-rw-r--r--src/plugins/gfxdrivers/eglnullws/eglnullwswindowsurface.cpp84
-rw-r--r--src/plugins/gfxdrivers/eglnullws/eglnullwswindowsurface.h63
-rw-r--r--src/plugins/gfxdrivers/gfxdrivers.pro10
-rw-r--r--src/plugins/gfxdrivers/linuxfb/linuxfb.pro14
-rw-r--r--src/plugins/gfxdrivers/linuxfb/main.cpp79
-rw-r--r--src/plugins/gfxdrivers/powervr/QWSWSEGL/QWSWSEGL.pro26
-rw-r--r--src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable.c830
-rw-r--r--src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable.h169
-rw-r--r--src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable_p.h132
-rw-r--r--src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwswsegl.c402
-rw-r--r--src/plugins/gfxdrivers/powervr/README66
-rw-r--r--src/plugins/gfxdrivers/powervr/powervr.pri2
-rw-r--r--src/plugins/gfxdrivers/powervr/powervr.pro3
-rw-r--r--src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.cpp351
-rw-r--r--src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.h99
-rw-r--r--src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.pro27
-rw-r--r--src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreenplugin.cpp74
-rw-r--r--src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglwindowsurface.cpp273
-rw-r--r--src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglwindowsurface.h85
-rw-r--r--src/plugins/gfxdrivers/qvfb/main.cpp82
-rw-r--r--src/plugins/gfxdrivers/qvfb/qvfb.pro19
-rw-r--r--src/plugins/gfxdrivers/transformed/main.cpp84
-rw-r--r--src/plugins/gfxdrivers/transformed/transformed.pro13
-rw-r--r--src/plugins/gfxdrivers/vnc/main.cpp86
-rw-r--r--src/plugins/gfxdrivers/vnc/qscreenvnc_p.h524
-rw-r--r--src/plugins/gfxdrivers/vnc/qscreenvnc_qws.cpp2338
-rw-r--r--src/plugins/gfxdrivers/vnc/qscreenvnc_qws.h88
-rw-r--r--src/plugins/gfxdrivers/vnc/vnc.pro16
-rw-r--r--src/plugins/graphicssystems/graphicssystems.pro15
-rw-r--r--src/plugins/graphicssystems/meego/dithering.cpp266
-rw-r--r--src/plugins/graphicssystems/meego/meego.pro13
-rw-r--r--src/plugins/graphicssystems/meego/qmeegoextensions.cpp213
-rw-r--r--src/plugins/graphicssystems/meego/qmeegoextensions.h125
-rw-r--r--src/plugins/graphicssystems/meego/qmeegographicssystem.cpp534
-rw-r--r--src/plugins/graphicssystems/meego/qmeegographicssystem.h127
-rw-r--r--src/plugins/graphicssystems/meego/qmeegographicssystemplugin.cpp58
-rw-r--r--src/plugins/graphicssystems/meego/qmeegographicssystemplugin.h54
-rw-r--r--src/plugins/graphicssystems/meego/qmeegolivepixmapdata.cpp323
-rw-r--r--src/plugins/graphicssystems/meego/qmeegolivepixmapdata.h78
-rw-r--r--src/plugins/graphicssystems/meego/qmeegopixmapdata.cpp224
-rw-r--r--src/plugins/graphicssystems/meego/qmeegopixmapdata.h74
-rw-r--r--src/plugins/graphicssystems/meego/qmeegorasterpixmapdata.cpp60
-rw-r--r--src/plugins/graphicssystems/meego/qmeegorasterpixmapdata.h55
-rw-r--r--src/plugins/graphicssystems/opengl/main.cpp95
-rw-r--r--src/plugins/graphicssystems/opengl/opengl.pro13
-rw-r--r--src/plugins/graphicssystems/openvg/main.cpp71
-rw-r--r--src/plugins/graphicssystems/openvg/openvg.pro14
-rw-r--r--src/plugins/graphicssystems/openvg/qgraphicssystem_vg.cpp88
-rw-r--r--src/plugins/graphicssystems/openvg/qgraphicssystem_vg_p.h73
-rw-r--r--src/plugins/graphicssystems/shivavg/README8
-rw-r--r--src/plugins/graphicssystems/shivavg/main.cpp71
-rw-r--r--src/plugins/graphicssystems/shivavg/shivavg.pro12
-rw-r--r--src/plugins/graphicssystems/shivavg/shivavggraphicssystem.cpp62
-rw-r--r--src/plugins/graphicssystems/shivavg/shivavggraphicssystem.h60
-rw-r--r--src/plugins/graphicssystems/shivavg/shivavgwindowsurface.cpp358
-rw-r--r--src/plugins/graphicssystems/shivavg/shivavgwindowsurface.h76
-rw-r--r--src/plugins/graphicssystems/trace/main.cpp69
-rw-r--r--src/plugins/graphicssystems/trace/qgraphicssystem_trace.cpp153
-rw-r--r--src/plugins/graphicssystems/trace/qgraphicssystem_trace_p.h71
-rw-r--r--src/plugins/graphicssystems/trace/trace.pro13
-rw-r--r--src/plugins/imageformats/ico/qicohandler.cpp1
-rw-r--r--src/plugins/inputmethods/imsw-multi/imsw-multi.pro13
-rw-r--r--src/plugins/inputmethods/imsw-multi/qmultiinputcontext.cpp212
-rw-r--r--src/plugins/inputmethods/imsw-multi/qmultiinputcontext.h117
-rw-r--r--src/plugins/inputmethods/imsw-multi/qmultiinputcontextplugin.cpp111
-rw-r--r--src/plugins/inputmethods/imsw-multi/qmultiinputcontextplugin.h85
-rw-r--r--src/plugins/inputmethods/inputmethods.pro3
-rw-r--r--src/plugins/kbddrivers/kbddrivers.pro2
-rw-r--r--src/plugins/kbddrivers/linuxinput/linuxinput.pro14
-rw-r--r--src/plugins/kbddrivers/linuxinput/main.cpp77
-rw-r--r--src/plugins/mousedrivers/linuxtp/linuxtp.pro14
-rw-r--r--src/plugins/mousedrivers/linuxtp/main.cpp76
-rw-r--r--src/plugins/mousedrivers/mousedrivers.pro5
-rw-r--r--src/plugins/mousedrivers/pc/main.cpp81
-rw-r--r--src/plugins/mousedrivers/pc/pc.pro14
-rw-r--r--src/plugins/mousedrivers/tslib/main.cpp77
-rw-r--r--src/plugins/mousedrivers/tslib/tslib.pro16
-rw-r--r--src/plugins/platforminputcontexts/ibus/ibus.pro19
-rw-r--r--src/plugins/platforminputcontexts/ibus/interfaces/org.freedesktop.IBus.InputContext.xml80
-rw-r--r--src/plugins/platforminputcontexts/ibus/interfaces/org.freedesktop.IBus.xml30
-rw-r--r--src/plugins/platforminputcontexts/ibus/main.cpp71
-rw-r--r--src/plugins/platforminputcontexts/ibus/qibusinputcontextproxy.cpp26
-rw-r--r--src/plugins/platforminputcontexts/ibus/qibusinputcontextproxy.h144
-rw-r--r--src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp329
-rw-r--r--src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h74
-rw-r--r--src/plugins/platforminputcontexts/ibus/qibusproxy.cpp26
-rw-r--r--src/plugins/platforminputcontexts/ibus/qibusproxy.h88
-rw-r--r--src/plugins/platforminputcontexts/ibus/qibustypes.cpp209
-rw-r--r--src/plugins/platforminputcontexts/ibus/qibustypes.h116
-rw-r--r--src/plugins/platforminputcontexts/platforminputcontexts.pro4
-rw-r--r--src/plugins/platforms/cocoa/cocoa.pro42
-rw-r--r--src/plugins/platforms/cocoa/images/copyarrowcursor.png (renamed from src/gui/mac/images/copyarrowcursor.png)bin1976 -> 1976 bytes
-rw-r--r--src/plugins/platforms/cocoa/images/forbiddencursor.png (renamed from src/gui/mac/images/forbiddencursor.png)bin1745 -> 1745 bytes
-rw-r--r--src/plugins/platforms/cocoa/images/leopard-unified-toolbar-on.png (renamed from src/gui/mac/images/leopard-unified-toolbar-on.png)bin356 -> 356 bytes
-rw-r--r--src/plugins/platforms/cocoa/images/pluscursor.png (renamed from src/gui/mac/images/pluscursor.png)bin688 -> 688 bytes
-rw-r--r--src/plugins/platforms/cocoa/images/spincursor.png (renamed from src/gui/mac/images/spincursor.png)bin748 -> 748 bytes
-rw-r--r--src/plugins/platforms/cocoa/images/waitcursor.png (renamed from src/gui/mac/images/waitcursor.png)bin724 -> 724 bytes
-rw-r--r--src/plugins/platforms/cocoa/qcocoaapplication.h116
-rw-r--r--src/plugins/platforms/cocoa/qcocoaapplication.mm227
-rw-r--r--src/plugins/platforms/cocoa/qcocoaapplicationdelegate.h127
-rw-r--r--src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm354
-rw-r--r--src/plugins/platforms/cocoa/qcocoaautoreleasepool.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoabackingstore.h71
-rw-r--r--src/plugins/platforms/cocoa/qcocoabackingstore.mm98
-rw-r--r--src/plugins/platforms/cocoa/qcocoaeventdispatcher.h220
-rw-r--r--src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm1123
-rw-r--r--src/plugins/platforms/cocoa/qcocoaeventloopintegration.h65
-rw-r--r--src/plugins/platforms/cocoa/qcocoaeventloopintegration.mm112
-rw-r--r--src/plugins/platforms/cocoa/qcocoaglcontext.h43
-rw-r--r--src/plugins/platforms/cocoa/qcocoaglcontext.mm99
-rw-r--r--src/plugins/platforms/cocoa/qcocoahelpers.h90
-rw-r--r--src/plugins/platforms/cocoa/qcocoahelpers.mm448
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.h16
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.mm92
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenu.h80
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenu.mm267
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuloader.h95
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuloader.mm314
-rw-r--r--src/plugins/platforms/cocoa/qcocoanativeinterface.h55
-rw-r--r--src/plugins/platforms/cocoa/qcocoanativeinterface.mm59
-rw-r--r--src/plugins/platforms/cocoa/qcocoaresources.qrc17
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.h37
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm318
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindowsurface.h73
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindowsurface.mm103
-rw-r--r--src/plugins/platforms/cocoa/qmenu_mac.h85
-rw-r--r--src/plugins/platforms/cocoa/qmenu_mac.mm1274
-rw-r--r--src/plugins/platforms/cocoa/qnsview.h11
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm193
-rw-r--r--src/plugins/platforms/cocoa/qnswindowdelegate.h21
-rw-r--r--src/plugins/platforms/cocoa/qnswindowdelegate.mm12
-rw-r--r--src/plugins/platforms/cocoa/qt_menu.nib/classes.nib (renamed from src/gui/mac/qt_menu.nib/classes.nib)0
-rw-r--r--src/plugins/platforms/cocoa/qt_menu.nib/info.nib (renamed from src/gui/mac/qt_menu.nib/info.nib)0
-rw-r--r--src/plugins/platforms/cocoa/qt_menu.nib/keyedobjects.nib (renamed from src/gui/mac/qt_menu.nib/keyedobjects.nib)bin5560 -> 5560 bytes
-rw-r--r--src/plugins/platforms/directfb/directfb.pro10
-rw-r--r--src/plugins/platforms/directfb/qdirectfbblitter.cpp6
-rw-r--r--src/plugins/platforms/directfb/qdirectfbblitter.h2
-rw-r--r--src/plugins/platforms/directfb/qdirectfbconvenience.cpp4
-rw-r--r--src/plugins/platforms/directfb/qdirectfbconvenience.h2
-rw-r--r--src/plugins/platforms/directfb/qdirectfbcursor.cpp21
-rw-r--r--src/plugins/platforms/directfb/qdirectfbcursor.h8
-rw-r--r--src/plugins/platforms/directfb/qdirectfbglcontext.cpp4
-rw-r--r--src/plugins/platforms/directfb/qdirectfbglcontext.h4
-rw-r--r--src/plugins/platforms/directfb/qdirectfbinput.cpp13
-rw-r--r--src/plugins/platforms/directfb/qdirectfbinput.h4
-rw-r--r--src/plugins/platforms/directfb/qdirectfbintegration.cpp66
-rw-r--r--src/plugins/platforms/directfb/qdirectfbintegration.h22
-rw-r--r--src/plugins/platforms/directfb/qdirectfbwindow.cpp48
-rw-r--r--src/plugins/platforms/directfb/qdirectfbwindow.h6
-rw-r--r--src/plugins/platforms/directfb/qdirectfbwindowsurface.cpp17
-rw-r--r--src/plugins/platforms/directfb/qdirectfbwindowsurface.h12
-rw-r--r--src/plugins/platforms/eglconvenience/eglconvenience.pri7
-rw-r--r--src/plugins/platforms/eglconvenience/qeglconvenience.cpp324
-rw-r--r--src/plugins/platforms/eglconvenience/qeglconvenience.h60
-rw-r--r--src/plugins/platforms/eglconvenience/qeglplatformcontext.cpp157
-rw-r--r--src/plugins/platforms/eglconvenience/qeglplatformcontext.h71
-rw-r--r--src/plugins/platforms/eglconvenience/qxlibeglintegration.cpp184
-rw-r--r--src/plugins/platforms/eglconvenience/qxlibeglintegration.h53
-rw-r--r--src/plugins/platforms/eglconvenience/xlibeglintegration.pri7
-rw-r--r--src/plugins/platforms/eglfs/eglfs.pro12
-rw-r--r--src/plugins/platforms/eglfs/qeglfsbackingstore.cpp104
-rw-r--r--src/plugins/platforms/eglfs/qeglfsbackingstore.h68
-rw-r--r--src/plugins/platforms/eglfs/qeglfsintegration.cpp44
-rw-r--r--src/plugins/platforms/eglfs/qeglfsintegration.h11
-rw-r--r--src/plugins/platforms/eglfs/qeglfsscreen.cpp50
-rw-r--r--src/plugins/platforms/eglfs/qeglfsscreen.h8
-rw-r--r--src/plugins/platforms/eglfs/qeglfswindow.cpp30
-rw-r--r--src/plugins/platforms/eglfs/qeglfswindow.h7
-rw-r--r--src/plugins/platforms/eglfs/qeglfswindowsurface.cpp101
-rw-r--r--src/plugins/platforms/eglfs/qeglfswindowsurface.h67
-rw-r--r--src/plugins/platforms/externalplugin.pri29
-rw-r--r--src/plugins/platforms/fb_base/fb_base.cpp507
-rw-r--r--src/plugins/platforms/fb_base/fb_base.pri2
-rw-r--r--src/plugins/platforms/fb_base/fb_base.pro23
-rw-r--r--src/plugins/platforms/fontdatabases/basicunix/basicunix.pri88
-rw-r--r--src/plugins/platforms/fontdatabases/basicunix/qbasicunixfontdatabase.cpp355
-rw-r--r--src/plugins/platforms/fontdatabases/basicunix/qbasicunixfontdatabase.h67
-rw-r--r--src/plugins/platforms/fontdatabases/fontconfig/fontconfig.pri12
-rw-r--r--src/plugins/platforms/fontdatabases/fontconfig/qfontconfigdatabase.cpp604
-rw-r--r--src/plugins/platforms/fontdatabases/fontconfig/qfontconfigdatabase.h56
-rw-r--r--src/plugins/platforms/fontdatabases/genericunix/genericunix.pri10
-rw-r--r--src/plugins/platforms/fontdatabases/genericunix/qgenericunixfontdatabase.h53
-rw-r--r--src/plugins/platforms/glxconvenience/glxconvenience.pri15
-rw-r--r--src/plugins/platforms/glxconvenience/qglxconvenience.cpp257
-rw-r--r--src/plugins/platforms/glxconvenience/qglxconvenience.h56
-rw-r--r--src/plugins/platforms/kms/kms.pro42
-rw-r--r--src/plugins/platforms/kms/main.cpp72
-rw-r--r--src/plugins/platforms/kms/qkmsbackingstore.cpp72
-rw-r--r--src/plugins/platforms/kms/qkmsbackingstore.h65
-rw-r--r--src/plugins/platforms/kms/qkmsbuffermanager.cpp198
-rw-r--r--src/plugins/platforms/kms/qkmsbuffermanager.h105
-rw-r--r--src/plugins/platforms/kms/qkmscontext.cpp113
-rw-r--r--src/plugins/platforms/kms/qkmscontext.h75
-rw-r--r--src/plugins/platforms/kms/qkmscursor.cpp131
-rw-r--r--src/plugins/platforms/kms/qkmscursor.h74
-rw-r--r--src/plugins/platforms/kms/qkmsdevice.cpp163
-rw-r--r--src/plugins/platforms/kms/qkmsdevice.h87
-rw-r--r--src/plugins/platforms/kms/qkmsintegration.cpp139
-rw-r--r--src/plugins/platforms/kms/qkmsintegration.h82
-rw-r--r--src/plugins/platforms/kms/qkmsscreen.cpp224
-rw-r--r--src/plugins/platforms/kms/qkmsscreen.h97
-rw-r--r--src/plugins/platforms/kms/qkmswindow.cpp64
-rw-r--r--src/plugins/platforms/kms/qkmswindow.h62
-rw-r--r--src/plugins/platforms/linuxfb/linuxfb.pro2
-rw-r--r--src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp10
-rw-r--r--src/plugins/platforms/linuxfb/qlinuxfbintegration.h4
-rw-r--r--src/plugins/platforms/minimal/minimal.pro6
-rw-r--r--src/plugins/platforms/minimal/qminimalbackingstore.cpp86
-rw-r--r--src/plugins/platforms/minimal/qminimalbackingstore.h67
-rw-r--r--src/plugins/platforms/minimal/qminimalintegration.cpp37
-rw-r--r--src/plugins/platforms/minimal/qminimalintegration.h10
-rw-r--r--src/plugins/platforms/minimal/qminimalwindowsurface.cpp86
-rw-r--r--src/plugins/platforms/minimal/qminimalwindowsurface.h67
-rw-r--r--src/plugins/platforms/openkode/qopenkodeintegration.cpp6
-rw-r--r--src/plugins/platforms/openkode/qopenkodeintegration.h4
-rw-r--r--src/plugins/platforms/openkode/qopenkodewindow.cpp4
-rw-r--r--src/plugins/platforms/openkode/qopenkodewindow.h2
-rw-r--r--src/plugins/platforms/openvglite/qgraphicssystem_vglite.cpp14
-rw-r--r--src/plugins/platforms/openvglite/qgraphicssystem_vglite.h2
-rw-r--r--src/plugins/platforms/openwfd/main.cpp72
-rw-r--r--src/plugins/platforms/openwfd/openwf.pro41
-rw-r--r--src/plugins/platforms/openwfd/qopenwfdbackingstore.cpp25
-rw-r--r--src/plugins/platforms/openwfd/qopenwfdbackingstore.h65
-rw-r--r--src/plugins/platforms/openwfd/qopenwfddevice.cpp317
-rw-r--r--src/plugins/platforms/openwfd/qopenwfddevice.h113
-rw-r--r--src/plugins/platforms/openwfd/qopenwfdevent.cpp46
-rw-r--r--src/plugins/platforms/openwfd/qopenwfdevent.h51
-rw-r--r--src/plugins/platforms/openwfd/qopenwfdglcontext.cpp97
-rw-r--r--src/plugins/platforms/openwfd/qopenwfdglcontext.h68
-rw-r--r--src/plugins/platforms/openwfd/qopenwfdintegration.cpp145
-rw-r--r--src/plugins/platforms/openwfd/qopenwfdintegration.h86
-rw-r--r--src/plugins/platforms/openwfd/qopenwfdnativeinterface.cpp141
-rw-r--r--src/plugins/platforms/openwfd/qopenwfdnativeinterface.h76
-rw-r--r--src/plugins/platforms/openwfd/qopenwfdoutputbuffer.cpp90
-rw-r--r--src/plugins/platforms/openwfd/qopenwfdoutputbuffer.h69
-rw-r--r--src/plugins/platforms/openwfd/qopenwfdport.cpp212
-rw-r--r--src/plugins/platforms/openwfd/qopenwfdport.h89
-rw-r--r--src/plugins/platforms/openwfd/qopenwfdportmode.cpp63
-rw-r--r--src/plugins/platforms/openwfd/qopenwfdportmode.h74
-rw-r--r--src/plugins/platforms/openwfd/qopenwfdscreen.cpp192
-rw-r--r--src/plugins/platforms/openwfd/qopenwfdscreen.h91
-rw-r--r--src/plugins/platforms/openwfd/qopenwfdwindow.cpp61
-rw-r--r--src/plugins/platforms/openwfd/qopenwfdwindow.h61
-rw-r--r--src/plugins/platforms/platforms.pro6
-rw-r--r--src/plugins/platforms/qvfb/qvfb.pro1
-rw-r--r--src/plugins/platforms/qvfb/qvfbintegration.cpp10
-rw-r--r--src/plugins/platforms/qvfb/qvfbintegration.h4
-rw-r--r--src/plugins/platforms/uikit/quikitintegration.h2
-rw-r--r--src/plugins/platforms/uikit/quikitintegration.mm4
-rw-r--r--src/plugins/platforms/uikit/quikitwindow.h2
-rw-r--r--src/plugins/platforms/uikit/quikitwindow.mm10
-rw-r--r--src/plugins/platforms/uikit/uikit.pro4
-rw-r--r--src/plugins/platforms/vnc/qvncintegration.cpp8
-rw-r--r--src/plugins/platforms/vnc/qvncintegration.h5
-rw-r--r--src/plugins/platforms/vnc/qvncserver.cpp2
-rw-r--r--src/plugins/platforms/vnc/vnc.pro2
-rw-r--r--src/plugins/platforms/wayland/gl_integration/gl_integration.pri13
-rw-r--r--src/plugins/platforms/wayland/gl_integration/qwaylandglintegration.h8
-rw-r--r--src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.cpp184
-rw-r--r--src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.h69
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglcontext.cpp106
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglcontext.h72
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglintegration.cpp82
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglintegration.h71
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglwindow.cpp106
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglwindow.h70
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_cgl/readback_cgl.pri10
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.cpp18
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.h7
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.cpp9
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.h6
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.cpp4
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.h4
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_egl/readback_egl.pri4
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.cpp101
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.h31
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.cpp9
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.h5
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.cpp65
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.h18
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_glx/readback_glx.pri1
-rw-r--r--src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.cpp25
-rw-r--r--src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.h11
-rw-r--r--src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.cpp81
-rw-r--r--src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.h22
-rw-r--r--src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.cpp74
-rw-r--r--src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.h32
-rw-r--r--src/plugins/platforms/wayland/gl_integration/wayland_egl/wayland_egl.pri2
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.cpp123
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.h32
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.cpp9
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.h7
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.cpp100
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.h22
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_egl/xcomposite_egl.pri2
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.cpp110
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.h37
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.cpp23
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.h5
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.cpp95
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.h24
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_glx/xcomposite_glx.pri1
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.cpp1
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.h4
-rw-r--r--src/plugins/platforms/wayland/main.cpp7
-rw-r--r--src/plugins/platforms/wayland/qwaylandclipboard.cpp2
-rw-r--r--src/plugins/platforms/wayland/qwaylandcursor.cpp73
-rw-r--r--src/plugins/platforms/wayland/qwaylandcursor.h14
-rw-r--r--src/plugins/platforms/wayland/qwaylanddisplay.cpp20
-rw-r--r--src/plugins/platforms/wayland/qwaylanddisplay.h2
-rw-r--r--src/plugins/platforms/wayland/qwaylanddnd.cpp423
-rw-r--r--src/plugins/platforms/wayland/qwaylanddnd.h86
-rw-r--r--src/plugins/platforms/wayland/qwaylandinputdevice.cpp12
-rw-r--r--src/plugins/platforms/wayland/qwaylandinputdevice.h1
-rw-r--r--src/plugins/platforms/wayland/qwaylandintegration.cpp87
-rw-r--r--src/plugins/platforms/wayland/qwaylandintegration.h17
-rw-r--r--src/plugins/platforms/wayland/qwaylandnativeinterface.cpp19
-rw-r--r--src/plugins/platforms/wayland/qwaylandnativeinterface.h6
-rw-r--r--src/plugins/platforms/wayland/qwaylandscreen.cpp5
-rw-r--r--src/plugins/platforms/wayland/qwaylandscreen.h2
-rw-r--r--src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp148
-rw-r--r--src/plugins/platforms/wayland/qwaylandshmbackingstore.h83
-rw-r--r--src/plugins/platforms/wayland/qwaylandshmsurface.cpp150
-rw-r--r--src/plugins/platforms/wayland/qwaylandshmsurface.h83
-rw-r--r--src/plugins/platforms/wayland/qwaylandshmwindow.cpp10
-rw-r--r--src/plugins/platforms/wayland/qwaylandshmwindow.h4
-rw-r--r--src/plugins/platforms/wayland/qwaylandwindow.cpp12
-rw-r--r--src/plugins/platforms/wayland/qwaylandwindow.h2
-rw-r--r--src/plugins/platforms/wayland/wayland.pro27
-rw-r--r--src/plugins/platforms/wayland/windowmanager_integration/qwaylandwindowmanagerintegration.cpp17
-rw-r--r--src/plugins/platforms/windows/array.h103
-rw-r--r--src/plugins/platforms/windows/main.cpp112
-rw-r--r--src/plugins/platforms/windows/pixmaputils.cpp316
-rw-r--r--src/plugins/platforms/windows/pixmaputils.h71
-rw-r--r--src/plugins/platforms/windows/qtwindows_additional.h121
-rw-r--r--src/plugins/platforms/windows/qtwindowsglobal.h182
-rw-r--r--src/plugins/platforms/windows/qwindows.qdocconf27
-rw-r--r--src/plugins/platforms/windows/qwindowsbackingstore.cpp143
-rw-r--r--src/plugins/platforms/windows/qwindowsbackingstore.h77
-rw-r--r--src/plugins/platforms/windows/qwindowsclipboard.cpp366
-rw-r--r--src/plugins/platforms/windows/qwindowsclipboard.h94
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp750
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.h172
-rw-r--r--src/plugins/platforms/windows/qwindowscursor.cpp451
-rw-r--r--src/plugins/platforms/windows/qwindowscursor.h93
-rw-r--r--src/plugins/platforms/windows/qwindowsdrag.cpp721
-rw-r--r--src/plugins/platforms/windows/qwindowsdrag.h116
-rw-r--r--src/plugins/platforms/windows/qwindowsfontdatabase.cpp950
-rw-r--r--src/plugins/platforms/windows/qwindowsfontdatabase.h107
-rw-r--r--src/plugins/platforms/windows/qwindowsfontengine.cpp1223
-rw-r--r--src/plugins/platforms/windows/qwindowsfontengine.h186
-rw-r--r--src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp737
-rw-r--r--src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h133
-rw-r--r--src/plugins/platforms/windows/qwindowsglcontext.cpp971
-rw-r--r--src/plugins/platforms/windows/qwindowsglcontext.h165
-rw-r--r--src/plugins/platforms/windows/qwindowsguieventdispatcher.cpp215
-rw-r--r--src/plugins/platforms/windows/qwindowsguieventdispatcher.h71
-rw-r--r--src/plugins/platforms/windows/qwindowsinputcontext.cpp598
-rw-r--r--src/plugins/platforms/windows/qwindowsinputcontext.h98
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.cpp271
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.h80
-rw-r--r--src/plugins/platforms/windows/qwindowsinternalmimedata.h70
-rw-r--r--src/plugins/platforms/windows/qwindowskeymapper.cpp1075
-rw-r--r--src/plugins/platforms/windows/qwindowskeymapper.h114
-rw-r--r--src/plugins/platforms/windows/qwindowsmime.cpp1557
-rw-r--r--src/plugins/platforms/windows/qwindowsmime.h102
-rw-r--r--src/plugins/platforms/windows/qwindowsmousehandler.cpp288
-rw-r--r--src/plugins/platforms/windows/qwindowsmousehandler.h115
-rw-r--r--src/plugins/platforms/windows/qwindowsnativeimage.cpp151
-rw-r--r--src/plugins/platforms/windows/qwindowsnativeimage.h82
-rw-r--r--src/plugins/platforms/windows/qwindowsole.cpp476
-rw-r--r--src/plugins/platforms/windows/qwindowsole.h127
-rw-r--r--src/plugins/platforms/windows/qwindowsscreen.cpp230
-rw-r--r--src/plugins/platforms/windows/qwindowsscreen.h100
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp1317
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.h284
-rw-r--r--src/plugins/platforms/windows/windows.pro70
-rw-r--r--src/plugins/platforms/xcb/README2
-rw-r--r--src/plugins/platforms/xcb/main.cpp5
-rw-r--r--src/plugins/platforms/xcb/qdri2context.cpp8
-rw-r--r--src/plugins/platforms/xcb/qdri2context.h4
-rw-r--r--src/plugins/platforms/xcb/qglxintegration.cpp61
-rw-r--r--src/plugins/platforms/xcb/qglxintegration.h26
-rw-r--r--src/plugins/platforms/xcb/qxcbbackingstore.cpp309
-rw-r--r--src/plugins/platforms/xcb/qxcbbackingstore.h72
-rw-r--r--src/plugins/platforms/xcb/qxcbclipboard.cpp848
-rw-r--r--src/plugins/platforms/xcb/qxcbclipboard.h108
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp474
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.h109
-rw-r--r--src/plugins/platforms/xcb/qxcbcursor.cpp546
-rw-r--r--src/plugins/platforms/xcb/qxcbcursor.h71
-rw-r--r--src/plugins/platforms/xcb/qxcbdrag.cpp1332
-rw-r--r--src/plugins/platforms/xcb/qxcbdrag.h158
-rw-r--r--src/plugins/platforms/xcb/qxcbeglsurface.h68
-rw-r--r--src/plugins/platforms/xcb/qxcbimage.cpp266
-rw-r--r--src/plugins/platforms/xcb/qxcbimage.h64
-rw-r--r--src/plugins/platforms/xcb/qxcbintegration.cpp177
-rw-r--r--src/plugins/platforms/xcb/qxcbintegration.h28
-rw-r--r--src/plugins/platforms/xcb/qxcbkeyboard.cpp219
-rw-r--r--src/plugins/platforms/xcb/qxcbkeyboard.h13
-rw-r--r--src/plugins/platforms/xcb/qxcbmime.cpp288
-rw-r--r--src/plugins/platforms/xcb/qxcbmime.h68
-rw-r--r--src/plugins/platforms/xcb/qxcbnativeinterface.cpp95
-rw-r--r--src/plugins/platforms/xcb/qxcbnativeinterface.h18
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.cpp220
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.h14
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp950
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.h62
-rw-r--r--src/plugins/platforms/xcb/qxcbwindowsurface.cpp270
-rw-r--r--src/plugins/platforms/xcb/qxcbwindowsurface.h72
-rw-r--r--src/plugins/platforms/xcb/qxcbwmsupport.cpp136
-rw-r--r--src/plugins/platforms/xcb/qxcbwmsupport.h67
-rw-r--r--src/plugins/platforms/xcb/xcb.pro103
-rw-r--r--src/plugins/platforms/xlib/main.cpp9
-rw-r--r--src/plugins/platforms/xlib/qglxintegration.cpp51
-rw-r--r--src/plugins/platforms/xlib/qglxintegration.h24
-rw-r--r--src/plugins/platforms/xlib/qxlibbackingstore.cpp223
-rw-r--r--src/plugins/platforms/xlib/qxlibbackingstore.h87
-rw-r--r--src/plugins/platforms/xlib/qxlibclipboard.cpp4
-rw-r--r--src/plugins/platforms/xlib/qxlibcursor.cpp7
-rw-r--r--src/plugins/platforms/xlib/qxlibcursor.h2
-rw-r--r--src/plugins/platforms/xlib/qxlibintegration.cpp103
-rw-r--r--src/plugins/platforms/xlib/qxlibintegration.h15
-rw-r--r--src/plugins/platforms/xlib/qxlibkeyboard.cpp2
-rw-r--r--src/plugins/platforms/xlib/qxlibkeyboard.h2
-rw-r--r--src/plugins/platforms/xlib/qxlibnativeinterface.cpp48
-rw-r--r--src/plugins/platforms/xlib/qxlibnativeinterface.h16
-rw-r--r--src/plugins/platforms/xlib/qxlibscreen.cpp54
-rw-r--r--src/plugins/platforms/xlib/qxlibscreen.h4
-rw-r--r--src/plugins/platforms/xlib/qxlibstatic.cpp5
-rw-r--r--src/plugins/platforms/xlib/qxlibwindow.cpp141
-rw-r--r--src/plugins/platforms/xlib/qxlibwindow.h20
-rw-r--r--src/plugins/platforms/xlib/qxlibwindowsurface.cpp235
-rw-r--r--src/plugins/platforms/xlib/qxlibwindowsurface.h86
-rw-r--r--src/plugins/platforms/xlib/xlib.pro24
-rw-r--r--src/plugins/plugins.pro15
-rw-r--r--src/printsupport/dialogs/dialogs.pri43
-rw-r--r--src/printsupport/dialogs/images/fit-page-24.png (renamed from src/gui/dialogs/images/fit-page-24.png)bin985 -> 985 bytes
-rw-r--r--src/printsupport/dialogs/images/fit-page-32.png (renamed from src/gui/dialogs/images/fit-page-32.png)bin1330 -> 1330 bytes
-rw-r--r--src/printsupport/dialogs/images/fit-width-24.png (renamed from src/gui/dialogs/images/fit-width-24.png)bin706 -> 706 bytes
-rw-r--r--src/printsupport/dialogs/images/fit-width-32.png (renamed from src/gui/dialogs/images/fit-width-32.png)bin1004 -> 1004 bytes
-rw-r--r--src/printsupport/dialogs/images/go-first-24.png (renamed from src/gui/dialogs/images/go-first-24.png)bin796 -> 796 bytes
-rw-r--r--src/printsupport/dialogs/images/go-first-32.png (renamed from src/gui/dialogs/images/go-first-32.png)bin985 -> 985 bytes
-rw-r--r--src/printsupport/dialogs/images/go-last-24.png (renamed from src/gui/dialogs/images/go-last-24.png)bin792 -> 792 bytes
-rw-r--r--src/printsupport/dialogs/images/go-last-32.png (renamed from src/gui/dialogs/images/go-last-32.png)bin984 -> 984 bytes
-rw-r--r--src/printsupport/dialogs/images/go-next-24.png (renamed from src/gui/dialogs/images/go-next-24.png)bin782 -> 782 bytes
-rw-r--r--src/printsupport/dialogs/images/go-next-32.png (renamed from src/gui/dialogs/images/go-next-32.png)bin948 -> 948 bytes
-rw-r--r--src/printsupport/dialogs/images/go-previous-24.png (renamed from src/gui/dialogs/images/go-previous-24.png)bin797 -> 797 bytes
-rw-r--r--src/printsupport/dialogs/images/go-previous-32.png (renamed from src/gui/dialogs/images/go-previous-32.png)bin945 -> 945 bytes
-rw-r--r--src/printsupport/dialogs/images/layout-landscape-24.png (renamed from src/gui/dialogs/images/layout-landscape-24.png)bin820 -> 820 bytes
-rw-r--r--src/printsupport/dialogs/images/layout-landscape-32.png (renamed from src/gui/dialogs/images/layout-landscape-32.png)bin1353 -> 1353 bytes
-rw-r--r--src/printsupport/dialogs/images/layout-portrait-24.png (renamed from src/gui/dialogs/images/layout-portrait-24.png)bin817 -> 817 bytes
-rw-r--r--src/printsupport/dialogs/images/layout-portrait-32.png (renamed from src/gui/dialogs/images/layout-portrait-32.png)bin1330 -> 1330 bytes
-rw-r--r--src/printsupport/dialogs/images/page-setup-24.png (renamed from src/gui/dialogs/images/page-setup-24.png)bin620 -> 620 bytes
-rw-r--r--src/printsupport/dialogs/images/page-setup-32.png (renamed from src/gui/dialogs/images/page-setup-32.png)bin1154 -> 1154 bytes
-rw-r--r--src/printsupport/dialogs/images/print-24.png (renamed from src/gui/dialogs/images/print-24.png)bin914 -> 914 bytes
-rw-r--r--src/printsupport/dialogs/images/print-32.png (renamed from src/gui/dialogs/images/print-32.png)bin1202 -> 1202 bytes
-rw-r--r--src/printsupport/dialogs/images/status-color.png (renamed from src/gui/dialogs/images/status-color.png)bin1475 -> 1475 bytes
-rw-r--r--src/printsupport/dialogs/images/status-gray-scale.png (renamed from src/gui/dialogs/images/status-gray-scale.png)bin1254 -> 1254 bytes
-rw-r--r--src/printsupport/dialogs/images/view-page-multi-24.png (renamed from src/gui/dialogs/images/view-page-multi-24.png)bin390 -> 390 bytes
-rw-r--r--src/printsupport/dialogs/images/view-page-multi-32.png (renamed from src/gui/dialogs/images/view-page-multi-32.png)bin556 -> 556 bytes
-rw-r--r--src/printsupport/dialogs/images/view-page-one-24.png (renamed from src/gui/dialogs/images/view-page-one-24.png)bin662 -> 662 bytes
-rw-r--r--src/printsupport/dialogs/images/view-page-one-32.png (renamed from src/gui/dialogs/images/view-page-one-32.png)bin810 -> 810 bytes
-rw-r--r--src/printsupport/dialogs/images/view-page-sided-24.png (renamed from src/gui/dialogs/images/view-page-sided-24.png)bin700 -> 700 bytes
-rw-r--r--src/printsupport/dialogs/images/view-page-sided-32.png (renamed from src/gui/dialogs/images/view-page-sided-32.png)bin908 -> 908 bytes
-rw-r--r--src/printsupport/dialogs/images/zoom-in-24.png (renamed from src/gui/dialogs/images/zoom-in-24.png)bin1302 -> 1302 bytes
-rw-r--r--src/printsupport/dialogs/images/zoom-in-32.png (renamed from src/gui/dialogs/images/zoom-in-32.png)bin1873 -> 1873 bytes
-rw-r--r--src/printsupport/dialogs/images/zoom-out-24.png (renamed from src/gui/dialogs/images/zoom-out-24.png)bin1247 -> 1247 bytes
-rw-r--r--src/printsupport/dialogs/images/zoom-out-32.png (renamed from src/gui/dialogs/images/zoom-out-32.png)bin1749 -> 1749 bytes
-rw-r--r--src/printsupport/dialogs/qabstractpagesetupdialog.cpp139
-rw-r--r--src/printsupport/dialogs/qabstractpagesetupdialog.h82
-rw-r--r--src/printsupport/dialogs/qabstractpagesetupdialog_p.h (renamed from src/gui/dialogs/qabstractpagesetupdialog_p.h)0
-rw-r--r--src/printsupport/dialogs/qabstractprintdialog.cpp501
-rw-r--r--src/printsupport/dialogs/qabstractprintdialog.h130
-rw-r--r--src/printsupport/dialogs/qabstractprintdialog_p.h102
-rw-r--r--src/printsupport/dialogs/qpagesetupdialog.cpp (renamed from src/gui/dialogs/qpagesetupdialog.cpp)0
-rw-r--r--src/printsupport/dialogs/qpagesetupdialog.h112
-rw-r--r--src/printsupport/dialogs/qpagesetupdialog_mac.mm (renamed from src/gui/dialogs/qpagesetupdialog_mac.mm)0
-rw-r--r--src/printsupport/dialogs/qpagesetupdialog_unix.cpp620
-rw-r--r--src/printsupport/dialogs/qpagesetupdialog_unix_p.h (renamed from src/gui/dialogs/qpagesetupdialog_unix_p.h)0
-rw-r--r--src/printsupport/dialogs/qpagesetupdialog_win.cpp (renamed from src/gui/dialogs/qpagesetupdialog_win.cpp)0
-rw-r--r--src/printsupport/dialogs/qpagesetupwidget.ui (renamed from src/gui/dialogs/qpagesetupwidget.ui)0
-rw-r--r--src/printsupport/dialogs/qprintdialog.h174
-rw-r--r--src/printsupport/dialogs/qprintdialog.qdoc (renamed from src/gui/dialogs/qprintdialog.qdoc)0
-rw-r--r--src/printsupport/dialogs/qprintdialog.qrc (renamed from src/gui/dialogs/qprintdialog.qrc)0
-rw-r--r--src/printsupport/dialogs/qprintdialog_mac.mm (renamed from src/gui/dialogs/qprintdialog_mac.mm)0
-rw-r--r--src/printsupport/dialogs/qprintdialog_unix.cpp1288
-rw-r--r--src/printsupport/dialogs/qprintdialog_win.cpp (renamed from src/gui/dialogs/qprintdialog_win.cpp)0
-rw-r--r--src/printsupport/dialogs/qprintpreviewdialog.cpp803
-rw-r--r--src/printsupport/dialogs/qprintpreviewdialog.h108
-rw-r--r--src/printsupport/dialogs/qprintpropertieswidget.ui (renamed from src/gui/dialogs/qprintpropertieswidget.ui)0
-rw-r--r--src/printsupport/dialogs/qprintsettingsoutput.ui (renamed from src/gui/dialogs/qprintsettingsoutput.ui)0
-rw-r--r--src/printsupport/dialogs/qprintwidget.ui (renamed from src/gui/dialogs/qprintwidget.ui)0
-rw-r--r--src/printsupport/kernel/kernel.pri34
-rw-r--r--src/printsupport/kernel/qcups.cpp446
-rw-r--r--src/printsupport/kernel/qcups_p.h133
-rw-r--r--src/printsupport/kernel/qpaintengine_alpha.cpp (renamed from src/gui/painting/qpaintengine_alpha.cpp)0
-rw-r--r--src/printsupport/kernel/qpaintengine_alpha_p.h (renamed from src/gui/painting/qpaintengine_alpha_p.h)0
-rw-r--r--src/printsupport/kernel/qpaintengine_preview.cpp223
-rw-r--r--src/printsupport/kernel/qpaintengine_preview_p.h106
-rw-r--r--src/printsupport/kernel/qplatformprintersupport_qpa.cpp133
-rw-r--r--src/printsupport/kernel/qplatformprintersupport_qpa.h84
-rw-r--r--src/printsupport/kernel/qplatformprintplugin.cpp72
-rw-r--r--src/printsupport/kernel/qplatformprintplugin_qpa.h94
-rw-r--r--src/printsupport/kernel/qprintengine.h119
-rw-r--r--src/printsupport/kernel/qprintengine_pdf.cpp666
-rw-r--r--src/printsupport/kernel/qprintengine_pdf_p.h165
-rw-r--r--src/printsupport/kernel/qprinter.cpp2264
-rw-r--r--src/printsupport/kernel/qprinter.h279
-rw-r--r--src/printsupport/kernel/qprinter_p.h131
-rw-r--r--src/printsupport/kernel/qprinterinfo.cpp205
-rw-r--r--src/printsupport/kernel/qprinterinfo.h91
-rw-r--r--src/printsupport/kernel/qprinterinfo_p.h108
-rw-r--r--src/printsupport/kernel/qprinterinfo_unix.cpp857
-rw-r--r--src/printsupport/kernel/qprinterinfo_unix_p.h130
-rw-r--r--src/printsupport/printsupport.pro22
-rw-r--r--src/printsupport/widgets/qprintpreviewwidget.cpp844
-rw-r--r--src/printsupport/widgets/qprintpreviewwidget.h127
-rw-r--r--src/printsupport/widgets/widgets.pri2
-rw-r--r--src/sql/models/qsqlrelationaldelegate.h6
-rw-r--r--src/src.pro36
-rw-r--r--src/testlib/qasciikey.cpp2
-rw-r--r--src/testlib/qbenchmark.cpp2
-rw-r--r--src/testlib/qtest.h14
-rw-r--r--src/testlib/qtest_gui.h2
-rw-r--r--src/testlib/qtestaccessible.h4
-rw-r--r--src/testlib/qtestkeyboard.h87
-rw-r--r--src/testlib/qtestmouse.h81
-rw-r--r--src/testlib/qtestsystem.h7
-rw-r--r--src/testlib/qtesttouch.h77
-rw-r--r--src/testlib/testlib.pro2
-rw-r--r--src/tools/bootstrap/bootstrap.pro1
-rw-r--r--src/tools/idc/idc.pro2
-rw-r--r--src/tools/tools.pro4
-rw-r--r--src/tools/uic/qclass_lib_map.h689
-rw-r--r--src/uitools/quiloader.cpp24
-rw-r--r--src/v8/v8.pri1
-rw-r--r--src/widgets/QtGui.dynlist (renamed from src/gui/QtGui.dynlist)0
-rw-r--r--src/widgets/accessible/accessible.pri25
-rw-r--r--src/widgets/accessible/qaccessible.cpp (renamed from src/gui/accessible/qaccessible.cpp)0
-rw-r--r--src/widgets/accessible/qaccessible.h472
-rw-r--r--src/widgets/accessible/qaccessible2.cpp317
-rw-r--r--src/widgets/accessible/qaccessible2.h358
-rw-r--r--src/widgets/accessible/qaccessible_mac.mm (renamed from src/gui/accessible/qaccessible_mac.mm)0
-rw-r--r--src/widgets/accessible/qaccessible_mac_carbon.cpp (renamed from src/gui/accessible/qaccessible_mac_carbon.cpp)0
-rw-r--r--src/widgets/accessible/qaccessible_mac_cocoa.mm (renamed from src/gui/accessible/qaccessible_mac_cocoa.mm)0
-rw-r--r--src/widgets/accessible/qaccessible_mac_p.h (renamed from src/gui/accessible/qaccessible_mac_p.h)0
-rw-r--r--src/widgets/accessible/qaccessible_unix.cpp (renamed from src/gui/accessible/qaccessible_unix.cpp)0
-rw-r--r--src/widgets/accessible/qaccessible_win.cpp1439
-rw-r--r--src/widgets/accessible/qaccessiblebridge.cpp (renamed from src/gui/accessible/qaccessiblebridge.cpp)0
-rw-r--r--src/widgets/accessible/qaccessiblebridge.h92
-rw-r--r--src/widgets/accessible/qaccessibleobject.cpp (renamed from src/gui/accessible/qaccessibleobject.cpp)0
-rw-r--r--src/widgets/accessible/qaccessibleobject.h140
-rw-r--r--src/widgets/accessible/qaccessibleplugin.cpp (renamed from src/gui/accessible/qaccessibleplugin.cpp)0
-rw-r--r--src/widgets/accessible/qaccessibleplugin.h87
-rw-r--r--src/widgets/accessible/qaccessiblewidget.cpp1034
-rw-r--r--src/widgets/accessible/qaccessiblewidget.h141
-rw-r--r--src/widgets/animation/animation.pri (renamed from src/gui/animation/animation.pri)0
-rw-r--r--src/widgets/animation/qguivariantanimation.cpp (renamed from src/gui/animation/qguivariantanimation.cpp)0
-rw-r--r--src/widgets/dialogs/dialogs.pri82
-rw-r--r--src/widgets/dialogs/images/qtlogo-64.png (renamed from src/gui/dialogs/images/qtlogo-64.png)bin2991 -> 2991 bytes
-rw-r--r--src/widgets/dialogs/qcolordialog.cpp2115
-rw-r--r--src/widgets/dialogs/qcolordialog.h150
-rw-r--r--src/widgets/dialogs/qcolordialog_mac.mm (renamed from src/gui/dialogs/qcolordialog_mac.mm)0
-rw-r--r--src/widgets/dialogs/qcolordialog_p.h (renamed from src/gui/dialogs/qcolordialog_p.h)0
-rw-r--r--src/widgets/dialogs/qcolordialog_symbian.cpp (renamed from src/gui/dialogs/qcolordialog_symbian.cpp)0
-rw-r--r--src/widgets/dialogs/qdialog.cpp (renamed from src/gui/dialogs/qdialog.cpp)0
-rw-r--r--src/widgets/dialogs/qdialog.h140
-rw-r--r--src/widgets/dialogs/qdialog_p.h113
-rw-r--r--src/widgets/dialogs/qdialogsbinarycompat_win.cpp137
-rw-r--r--src/widgets/dialogs/qerrormessage.cpp (renamed from src/gui/dialogs/qerrormessage.cpp)0
-rw-r--r--src/widgets/dialogs/qerrormessage.h88
-rw-r--r--src/widgets/dialogs/qfiledialog.cpp3555
-rw-r--r--src/widgets/dialogs/qfiledialog.h331
-rw-r--r--src/widgets/dialogs/qfiledialog.ui (renamed from src/gui/dialogs/qfiledialog.ui)0
-rw-r--r--src/widgets/dialogs/qfiledialog_embedded.ui (renamed from src/gui/dialogs/qfiledialog_embedded.ui)0
-rw-r--r--src/widgets/dialogs/qfiledialog_mac.mm (renamed from src/gui/dialogs/qfiledialog_mac.mm)0
-rw-r--r--src/widgets/dialogs/qfiledialog_p.h (renamed from src/gui/dialogs/qfiledialog_p.h)0
-rw-r--r--src/widgets/dialogs/qfiledialog_symbian.cpp (renamed from src/gui/dialogs/qfiledialog_symbian.cpp)0
-rw-r--r--src/widgets/dialogs/qfiledialog_win.cpp839
-rw-r--r--src/widgets/dialogs/qfiledialog_win_p.h (renamed from src/gui/dialogs/qfiledialog_win_p.h)0
-rw-r--r--src/widgets/dialogs/qfileinfogatherer.cpp (renamed from src/gui/dialogs/qfileinfogatherer.cpp)0
-rw-r--r--src/widgets/dialogs/qfileinfogatherer_p.h (renamed from src/gui/dialogs/qfileinfogatherer_p.h)0
-rw-r--r--src/widgets/dialogs/qfilesystemmodel.cpp (renamed from src/gui/dialogs/qfilesystemmodel.cpp)0
-rw-r--r--src/widgets/dialogs/qfilesystemmodel.h180
-rw-r--r--src/widgets/dialogs/qfilesystemmodel_p.h (renamed from src/gui/dialogs/qfilesystemmodel_p.h)0
-rw-r--r--src/widgets/dialogs/qfontdialog.cpp1077
-rw-r--r--src/widgets/dialogs/qfontdialog.h147
-rw-r--r--src/widgets/dialogs/qfontdialog_mac.mm (renamed from src/gui/dialogs/qfontdialog_mac.mm)0
-rw-r--r--src/widgets/dialogs/qfontdialog_p.h (renamed from src/gui/dialogs/qfontdialog_p.h)0
-rw-r--r--src/widgets/dialogs/qfscompleter_p.h82
-rw-r--r--src/widgets/dialogs/qinputdialog.cpp (renamed from src/gui/dialogs/qinputdialog.cpp)0
-rw-r--r--src/widgets/dialogs/qinputdialog.h256
-rw-r--r--src/widgets/dialogs/qmessagebox.cpp2753
-rw-r--r--src/widgets/dialogs/qmessagebox.h365
-rw-r--r--src/widgets/dialogs/qmessagebox.qrc (renamed from src/gui/dialogs/qmessagebox.qrc)0
-rw-r--r--src/widgets/dialogs/qnspanelproxy_mac.mm (renamed from src/gui/dialogs/qnspanelproxy_mac.mm)0
-rw-r--r--src/widgets/dialogs/qprogressdialog.cpp907
-rw-r--r--src/widgets/dialogs/qprogressdialog.h145
-rw-r--r--src/widgets/dialogs/qsidebar.cpp (renamed from src/gui/dialogs/qsidebar.cpp)0
-rw-r--r--src/widgets/dialogs/qsidebar_p.h (renamed from src/gui/dialogs/qsidebar_p.h)0
-rw-r--r--src/widgets/dialogs/qwizard.cpp (renamed from src/gui/dialogs/qwizard.cpp)0
-rw-r--r--src/widgets/dialogs/qwizard.h268
-rw-r--r--src/widgets/dialogs/qwizard_win.cpp773
-rw-r--r--src/widgets/dialogs/qwizard_win_p.h158
-rw-r--r--src/widgets/effects/effects.pri6
-rw-r--r--src/widgets/effects/qgraphicseffect.cpp1235
-rw-r--r--src/widgets/effects/qgraphicseffect.h289
-rw-r--r--src/widgets/effects/qgraphicseffect_p.h231
-rw-r--r--src/widgets/effects/qpixmapfilter.cpp1381
-rw-r--r--src/widgets/effects/qpixmapfilter_p.h196
-rw-r--r--src/widgets/graphicsview/graphicsview.pri (renamed from src/gui/graphicsview/graphicsview.pri)0
-rw-r--r--src/widgets/graphicsview/qgraph_p.h (renamed from src/gui/graphicsview/qgraph_p.h)0
-rw-r--r--src/widgets/graphicsview/qgraphicsanchorlayout.cpp (renamed from src/gui/graphicsview/qgraphicsanchorlayout.cpp)0
-rw-r--r--src/widgets/graphicsview/qgraphicsanchorlayout.h128
-rw-r--r--src/widgets/graphicsview/qgraphicsanchorlayout_p.cpp3016
-rw-r--r--src/widgets/graphicsview/qgraphicsanchorlayout_p.h (renamed from src/gui/graphicsview/qgraphicsanchorlayout_p.h)0
-rw-r--r--src/widgets/graphicsview/qgraphicsgridlayout.cpp (renamed from src/gui/graphicsview/qgraphicsgridlayout.cpp)0
-rw-r--r--src/widgets/graphicsview/qgraphicsgridlayout.h144
-rw-r--r--src/widgets/graphicsview/qgraphicsitem.cpp11603
-rw-r--r--src/widgets/graphicsview/qgraphicsitem.h1172
-rw-r--r--src/widgets/graphicsview/qgraphicsitem_p.h891
-rw-r--r--src/widgets/graphicsview/qgraphicsitemanimation.cpp (renamed from src/gui/graphicsview/qgraphicsitemanimation.cpp)0
-rw-r--r--src/widgets/graphicsview/qgraphicsitemanimation.h120
-rw-r--r--src/widgets/graphicsview/qgraphicslayout.cpp (renamed from src/gui/graphicsview/qgraphicslayout.cpp)0
-rw-r--r--src/widgets/graphicsview/qgraphicslayout.h100
-rw-r--r--src/widgets/graphicsview/qgraphicslayout_p.cpp (renamed from src/gui/graphicsview/qgraphicslayout_p.cpp)0
-rw-r--r--src/widgets/graphicsview/qgraphicslayout_p.h154
-rw-r--r--src/widgets/graphicsview/qgraphicslayoutitem.cpp (renamed from src/gui/graphicsview/qgraphicslayoutitem.cpp)0
-rw-r--r--src/widgets/graphicsview/qgraphicslayoutitem.h155
-rw-r--r--src/widgets/graphicsview/qgraphicslayoutitem_p.h103
-rw-r--r--src/widgets/graphicsview/qgraphicslinearlayout.cpp (renamed from src/gui/graphicsview/qgraphicslinearlayout.cpp)0
-rw-r--r--src/widgets/graphicsview/qgraphicslinearlayout.h119
-rw-r--r--src/widgets/graphicsview/qgraphicsproxywidget.cpp1569
-rw-r--r--src/widgets/graphicsview/qgraphicsproxywidget.h147
-rw-r--r--src/widgets/graphicsview/qgraphicsproxywidget_p.h (renamed from src/gui/graphicsview/qgraphicsproxywidget_p.h)0
-rw-r--r--src/widgets/graphicsview/qgraphicsscene.cpp6503
-rw-r--r--src/widgets/graphicsview/qgraphicsscene.h329
-rw-r--r--src/widgets/graphicsview/qgraphicsscene_bsp.cpp (renamed from src/gui/graphicsview/qgraphicsscene_bsp.cpp)0
-rw-r--r--src/widgets/graphicsview/qgraphicsscene_bsp_p.h (renamed from src/gui/graphicsview/qgraphicsscene_bsp_p.h)0
-rw-r--r--src/widgets/graphicsview/qgraphicsscene_p.h359
-rw-r--r--src/widgets/graphicsview/qgraphicsscenebsptreeindex.cpp (renamed from src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp)0
-rw-r--r--src/widgets/graphicsview/qgraphicsscenebsptreeindex_p.h (renamed from src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h)0
-rw-r--r--src/widgets/graphicsview/qgraphicssceneevent.cpp1674
-rw-r--r--src/widgets/graphicsview/qgraphicssceneevent.h326
-rw-r--r--src/widgets/graphicsview/qgraphicssceneindex.cpp (renamed from src/gui/graphicsview/qgraphicssceneindex.cpp)0
-rw-r--r--src/widgets/graphicsview/qgraphicssceneindex_p.h (renamed from src/gui/graphicsview/qgraphicssceneindex_p.h)0
-rw-r--r--src/widgets/graphicsview/qgraphicsscenelinearindex.cpp (renamed from src/gui/graphicsview/qgraphicsscenelinearindex.cpp)0
-rw-r--r--src/widgets/graphicsview/qgraphicsscenelinearindex_p.h109
-rw-r--r--src/widgets/graphicsview/qgraphicstransform.cpp (renamed from src/gui/graphicsview/qgraphicstransform.cpp)0
-rw-r--r--src/widgets/graphicsview/qgraphicstransform.h159
-rw-r--r--src/widgets/graphicsview/qgraphicstransform_p.h (renamed from src/gui/graphicsview/qgraphicstransform_p.h)0
-rw-r--r--src/widgets/graphicsview/qgraphicsview.cpp3880
-rw-r--r--src/widgets/graphicsview/qgraphicsview.h316
-rw-r--r--src/widgets/graphicsview/qgraphicsview_p.h233
-rw-r--r--src/widgets/graphicsview/qgraphicswidget.cpp2425
-rw-r--r--src/widgets/graphicsview/qgraphicswidget.h257
-rw-r--r--src/widgets/graphicsview/qgraphicswidget_p.cpp906
-rw-r--r--src/widgets/graphicsview/qgraphicswidget_p.h226
-rw-r--r--src/widgets/graphicsview/qgridlayoutengine.cpp (renamed from src/gui/graphicsview/qgridlayoutengine.cpp)0
-rw-r--r--src/widgets/graphicsview/qgridlayoutengine_p.h (renamed from src/gui/graphicsview/qgridlayoutengine_p.h)0
-rw-r--r--src/widgets/graphicsview/qsimplex_p.cpp (renamed from src/gui/graphicsview/qsimplex_p.cpp)0
-rw-r--r--src/widgets/graphicsview/qsimplex_p.h (renamed from src/gui/graphicsview/qsimplex_p.h)0
-rw-r--r--src/widgets/itemviews/itemviews.pri72
-rw-r--r--src/widgets/itemviews/qabstractitemdelegate.cpp (renamed from src/gui/itemviews/qabstractitemdelegate.cpp)0
-rw-r--r--src/widgets/itemviews/qabstractitemdelegate.h134
-rw-r--r--src/widgets/itemviews/qabstractitemview.cpp4320
-rw-r--r--src/widgets/itemviews/qabstractitemview.h381
-rw-r--r--src/widgets/itemviews/qabstractitemview_p.h458
-rw-r--r--src/widgets/itemviews/qabstractproxymodel.cpp (renamed from src/gui/itemviews/qabstractproxymodel.cpp)0
-rw-r--r--src/widgets/itemviews/qabstractproxymodel.h113
-rw-r--r--src/widgets/itemviews/qabstractproxymodel_p.h (renamed from src/gui/itemviews/qabstractproxymodel_p.h)0
-rw-r--r--src/widgets/itemviews/qbsptree.cpp (renamed from src/gui/itemviews/qbsptree.cpp)0
-rw-r--r--src/widgets/itemviews/qbsptree_p.h (renamed from src/gui/itemviews/qbsptree_p.h)0
-rw-r--r--src/widgets/itemviews/qcolumnview.cpp (renamed from src/gui/itemviews/qcolumnview.cpp)0
-rw-r--r--src/widgets/itemviews/qcolumnview.h123
-rw-r--r--src/widgets/itemviews/qcolumnview_p.h189
-rw-r--r--src/widgets/itemviews/qcolumnviewgrip.cpp (renamed from src/gui/itemviews/qcolumnviewgrip.cpp)0
-rw-r--r--src/widgets/itemviews/qcolumnviewgrip_p.h (renamed from src/gui/itemviews/qcolumnviewgrip_p.h)0
-rw-r--r--src/widgets/itemviews/qdatawidgetmapper.cpp (renamed from src/gui/itemviews/qdatawidgetmapper.cpp)0
-rw-r--r--src/widgets/itemviews/qdatawidgetmapper.h128
-rw-r--r--src/widgets/itemviews/qdirmodel.cpp (renamed from src/gui/itemviews/qdirmodel.cpp)0
-rw-r--r--src/widgets/itemviews/qdirmodel.h160
-rw-r--r--src/widgets/itemviews/qfileiconprovider.cpp (renamed from src/gui/itemviews/qfileiconprovider.cpp)0
-rw-r--r--src/widgets/itemviews/qfileiconprovider.h82
-rw-r--r--src/widgets/itemviews/qheaderview.cpp (renamed from src/gui/itemviews/qheaderview.cpp)0
-rw-r--r--src/widgets/itemviews/qheaderview.h250
-rw-r--r--src/widgets/itemviews/qheaderview_p.h366
-rw-r--r--src/widgets/itemviews/qidentityproxymodel.cpp (renamed from src/gui/itemviews/qidentityproxymodel.cpp)0
-rw-r--r--src/widgets/itemviews/qidentityproxymodel.h120
-rw-r--r--src/widgets/itemviews/qitemdelegate.cpp1341
-rw-r--r--src/widgets/itemviews/qitemdelegate.h141
-rw-r--r--src/widgets/itemviews/qitemeditorfactory.cpp (renamed from src/gui/itemviews/qitemeditorfactory.cpp)0
-rw-r--r--src/widgets/itemviews/qitemeditorfactory.h124
-rw-r--r--src/widgets/itemviews/qitemeditorfactory_p.h (renamed from src/gui/itemviews/qitemeditorfactory_p.h)0
-rw-r--r--src/widgets/itemviews/qitemselectionmodel.cpp (renamed from src/gui/itemviews/qitemselectionmodel.cpp)0
-rw-r--r--src/widgets/itemviews/qitemselectionmodel.h255
-rw-r--r--src/widgets/itemviews/qitemselectionmodel_p.h (renamed from src/gui/itemviews/qitemselectionmodel_p.h)0
-rw-r--r--src/widgets/itemviews/qlistview.cpp3225
-rw-r--r--src/widgets/itemviews/qlistview.h203
-rw-r--r--src/widgets/itemviews/qlistview_p.h (renamed from src/gui/itemviews/qlistview_p.h)0
-rw-r--r--src/widgets/itemviews/qlistwidget.cpp (renamed from src/gui/itemviews/qlistwidget.cpp)0
-rw-r--r--src/widgets/itemviews/qlistwidget.h335
-rw-r--r--src/widgets/itemviews/qlistwidget_p.h175
-rw-r--r--src/widgets/itemviews/qproxymodel.cpp (renamed from src/gui/itemviews/qproxymodel.cpp)0
-rw-r--r--src/widgets/itemviews/qproxymodel.h143
-rw-r--r--src/widgets/itemviews/qproxymodel_p.h (renamed from src/gui/itemviews/qproxymodel_p.h)0
-rw-r--r--src/widgets/itemviews/qsortfilterproxymodel.cpp (renamed from src/gui/itemviews/qsortfilterproxymodel.cpp)0
-rw-r--r--src/widgets/itemviews/qsortfilterproxymodel.h201
-rw-r--r--src/widgets/itemviews/qstandarditemmodel.cpp (renamed from src/gui/itemviews/qstandarditemmodel.cpp)0
-rw-r--r--src/widgets/itemviews/qstandarditemmodel.h456
-rw-r--r--src/widgets/itemviews/qstandarditemmodel_p.h (renamed from src/gui/itemviews/qstandarditemmodel_p.h)0
-rw-r--r--src/widgets/itemviews/qstringlistmodel.cpp (renamed from src/gui/itemviews/qstringlistmodel.cpp)0
-rw-r--r--src/widgets/itemviews/qstringlistmodel.h91
-rw-r--r--src/widgets/itemviews/qstyleditemdelegate.cpp (renamed from src/gui/itemviews/qstyleditemdelegate.cpp)0
-rw-r--r--src/widgets/itemviews/qstyleditemdelegate.h116
-rw-r--r--src/widgets/itemviews/qtableview.cpp (renamed from src/gui/itemviews/qtableview.cpp)0
-rw-r--r--src/widgets/itemviews/qtableview.h198
-rw-r--r--src/widgets/itemviews/qtableview_p.h (renamed from src/gui/itemviews/qtableview_p.h)0
-rw-r--r--src/widgets/itemviews/qtablewidget.cpp (renamed from src/gui/itemviews/qtablewidget.cpp)0
-rw-r--r--src/widgets/itemviews/qtablewidget.h377
-rw-r--r--src/widgets/itemviews/qtablewidget_p.h (renamed from src/gui/itemviews/qtablewidget_p.h)0
-rw-r--r--src/widgets/itemviews/qtreeview.cpp (renamed from src/gui/itemviews/qtreeview.cpp)0
-rw-r--r--src/widgets/itemviews/qtreeview.h242
-rw-r--r--src/widgets/itemviews/qtreeview_p.h255
-rw-r--r--src/widgets/itemviews/qtreewidget.cpp (renamed from src/gui/itemviews/qtreewidget.cpp)0
-rw-r--r--src/widgets/itemviews/qtreewidget.h432
-rw-r--r--src/widgets/itemviews/qtreewidget_p.h248
-rw-r--r--src/widgets/itemviews/qtreewidgetitemiterator.cpp (renamed from src/gui/itemviews/qtreewidgetitemiterator.cpp)0
-rw-r--r--src/widgets/itemviews/qtreewidgetitemiterator.h159
-rw-r--r--src/widgets/itemviews/qtreewidgetitemiterator_p.h (renamed from src/gui/itemviews/qtreewidgetitemiterator_p.h)0
-rw-r--r--src/widgets/itemviews/qwidgetitemdata_p.h (renamed from src/gui/itemviews/qwidgetitemdata_p.h)0
-rw-r--r--src/widgets/kernel/kernel.pri249
-rw-r--r--src/widgets/kernel/mac.pri4
-rw-r--r--src/widgets/kernel/qaction.cpp (renamed from src/gui/kernel/qaction.cpp)0
-rw-r--r--src/widgets/kernel/qaction.h264
-rw-r--r--src/widgets/kernel/qaction_p.h144
-rw-r--r--src/widgets/kernel/qactiongroup.cpp (renamed from src/gui/kernel/qactiongroup.cpp)0
-rw-r--r--src/widgets/kernel/qactiongroup.h112
-rw-r--r--src/widgets/kernel/qapplication.cpp5613
-rw-r--r--src/widgets/kernel/qapplication.h423
-rw-r--r--src/widgets/kernel/qapplication_p.h632
-rw-r--r--src/widgets/kernel/qapplication_qpa.cpp438
-rw-r--r--src/widgets/kernel/qboxlayout.cpp (renamed from src/gui/kernel/qboxlayout.cpp)0
-rw-r--r--src/widgets/kernel/qboxlayout.h173
-rw-r--r--src/widgets/kernel/qdesktopwidget.cpp (renamed from src/gui/kernel/qdesktopwidget.cpp)0
-rw-r--r--src/widgets/kernel/qdesktopwidget.h110
-rw-r--r--src/widgets/kernel/qdesktopwidget.qdoc (renamed from src/gui/kernel/qdesktopwidget.qdoc)0
-rw-r--r--src/widgets/kernel/qdesktopwidget_qpa.cpp171
-rw-r--r--src/widgets/kernel/qdesktopwidget_qpa_p.h (renamed from src/gui/kernel/qdesktopwidget_qpa_p.h)0
-rw-r--r--src/widgets/kernel/qformlayout.cpp (renamed from src/gui/kernel/qformlayout.cpp)0
-rw-r--r--src/widgets/kernel/qformlayout.h163
-rw-r--r--src/widgets/kernel/qgesture.cpp1118
-rw-r--r--src/widgets/kernel/qgesture.h328
-rw-r--r--src/widgets/kernel/qgesture_p.h245
-rw-r--r--src/widgets/kernel/qgesturemanager.cpp720
-rw-r--r--src/widgets/kernel/qgesturemanager_p.h (renamed from src/gui/kernel/qgesturemanager_p.h)0
-rw-r--r--src/widgets/kernel/qgesturerecognizer.cpp (renamed from src/gui/kernel/qgesturerecognizer.cpp)0
-rw-r--r--src/widgets/kernel/qgesturerecognizer.h102
-rw-r--r--src/widgets/kernel/qgridlayout.cpp (renamed from src/gui/kernel/qgridlayout.cpp)0
-rw-r--r--src/widgets/kernel/qgridlayout.h176
-rw-r--r--src/widgets/kernel/qguieventdispatcher_glib.cpp (renamed from src/gui/kernel/qguieventdispatcher_glib.cpp)0
-rw-r--r--src/widgets/kernel/qguieventdispatcher_glib_p.h (renamed from src/gui/kernel/qguieventdispatcher_glib_p.h)0
-rw-r--r--src/widgets/kernel/qguiplatformplugin.cpp (renamed from src/gui/kernel/qguiplatformplugin.cpp)0
-rw-r--r--src/widgets/kernel/qguiplatformplugin_p.h126
-rw-r--r--src/widgets/kernel/qicon.cpp1165
-rw-r--r--src/widgets/kernel/qicon.h143
-rw-r--r--src/widgets/kernel/qicon_p.h139
-rw-r--r--src/widgets/kernel/qiconengine.cpp (renamed from src/gui/image/qiconengine.cpp)0
-rw-r--r--src/widgets/kernel/qiconengine.h104
-rw-r--r--src/widgets/kernel/qiconengineplugin.cpp (renamed from src/gui/image/qiconengineplugin.cpp)0
-rw-r--r--src/widgets/kernel/qiconengineplugin.h104
-rw-r--r--src/widgets/kernel/qiconloader.cpp573
-rw-r--r--src/widgets/kernel/qiconloader_p.h192
-rw-r--r--src/widgets/kernel/qinputcontext.cpp406
-rw-r--r--src/widgets/kernel/qinputcontext.h131
-rw-r--r--src/widgets/kernel/qlayout.cpp (renamed from src/gui/kernel/qlayout.cpp)0
-rw-r--r--src/widgets/kernel/qlayout.h245
-rw-r--r--src/widgets/kernel/qlayout_p.h101
-rw-r--r--src/widgets/kernel/qlayoutengine.cpp436
-rw-r--r--src/widgets/kernel/qlayoutengine_p.h140
-rw-r--r--src/widgets/kernel/qlayoutitem.cpp (renamed from src/gui/kernel/qlayoutitem.cpp)0
-rw-r--r--src/widgets/kernel/qlayoutitem.h182
-rw-r--r--src/widgets/kernel/qplatformmenu_qpa.cpp51
-rw-r--r--src/widgets/kernel/qplatformmenu_qpa.h88
-rw-r--r--src/widgets/kernel/qsizepolicy.h244
-rw-r--r--src/widgets/kernel/qsizepolicy.qdoc (renamed from src/gui/kernel/qsizepolicy.qdoc)0
-rw-r--r--src/widgets/kernel/qsoftkeymanager.cpp (renamed from src/gui/kernel/qsoftkeymanager.cpp)0
-rw-r--r--src/widgets/kernel/qsoftkeymanager_common_p.h (renamed from src/gui/kernel/qsoftkeymanager_common_p.h)0
-rw-r--r--src/widgets/kernel/qsoftkeymanager_p.h115
-rw-r--r--src/widgets/kernel/qsound.cpp367
-rw-r--r--src/widgets/kernel/qsound.h90
-rw-r--r--src/widgets/kernel/qsound_p.h (renamed from src/gui/kernel/qsound_p.h)0
-rw-r--r--src/widgets/kernel/qstackedlayout.cpp (renamed from src/gui/kernel/qstackedlayout.cpp)0
-rw-r--r--src/widgets/kernel/qstackedlayout.h115
-rw-r--r--src/widgets/kernel/qstandardgestures.cpp (renamed from src/gui/kernel/qstandardgestures.cpp)0
-rw-r--r--src/widgets/kernel/qstandardgestures_p.h (renamed from src/gui/kernel/qstandardgestures_p.h)0
-rw-r--r--src/widgets/kernel/qt_gui_pch.h85
-rw-r--r--src/widgets/kernel/qtooltip.cpp (renamed from src/gui/kernel/qtooltip.cpp)0
-rw-r--r--src/widgets/kernel/qtooltip.h84
-rw-r--r--src/widgets/kernel/qwhatsthis.cpp777
-rw-r--r--src/widgets/kernel/qwhatsthis.h88
-rw-r--r--src/widgets/kernel/qwidget.cpp12610
-rw-r--r--src/widgets/kernel/qwidget.h1093
-rw-r--r--src/widgets/kernel/qwidget_p.h1018
-rw-r--r--src/widgets/kernel/qwidget_qpa.cpp925
-rw-r--r--src/widgets/kernel/qwidgetaction.cpp (renamed from src/gui/kernel/qwidgetaction.cpp)0
-rw-r--r--src/widgets/kernel/qwidgetaction.h91
-rw-r--r--src/widgets/kernel/qwidgetaction_p.h (renamed from src/gui/kernel/qwidgetaction_p.h)0
-rw-r--r--src/widgets/kernel/qwidgetbackingstore.cpp1393
-rw-r--r--src/widgets/kernel/qwidgetbackingstore_p.h268
-rw-r--r--src/widgets/kernel/qwidgetsvariant.cpp213
-rw-r--r--src/widgets/kernel/qwidgetwindow_qpa.cpp415
-rw-r--r--src/widgets/kernel/qwidgetwindow_qpa_p.h94
-rw-r--r--src/widgets/kernel/symbian.pri (renamed from src/gui/kernel/symbian.pri)0
-rw-r--r--src/widgets/kernel/win.pri (renamed from src/gui/kernel/win.pri)0
-rw-r--r--src/widgets/kernel/x11.pri (renamed from src/gui/kernel/x11.pri)0
-rw-r--r--src/widgets/platforms/mac/qapplication_mac.mm3131
-rw-r--r--src/widgets/platforms/mac/qclipboard_mac.cpp (renamed from src/gui/kernel/qclipboard_mac.cpp)0
-rw-r--r--src/widgets/platforms/mac/qcocoaintrospection_mac.mm (renamed from src/gui/kernel/qcocoaintrospection_mac.mm)0
-rw-r--r--src/widgets/platforms/mac/qcocoaintrospection_p.h (renamed from src/gui/kernel/qcocoaintrospection_p.h)0
-rw-r--r--src/widgets/platforms/mac/qcocoapanel_mac.mm (renamed from src/gui/kernel/qcocoapanel_mac.mm)0
-rw-r--r--src/widgets/platforms/mac/qcocoapanel_mac_p.h (renamed from src/gui/kernel/qcocoapanel_mac_p.h)0
-rw-r--r--src/widgets/platforms/mac/qcocoasharedwindowmethods_mac_p.h (renamed from src/gui/kernel/qcocoasharedwindowmethods_mac_p.h)0
-rw-r--r--src/widgets/platforms/mac/qcocoaview_mac.mm (renamed from src/gui/kernel/qcocoaview_mac.mm)0
-rw-r--r--src/widgets/platforms/mac/qcocoaview_mac_p.h87
-rw-r--r--src/widgets/platforms/mac/qcocoawindow_mac.mm (renamed from src/gui/kernel/qcocoawindow_mac.mm)0
-rw-r--r--src/widgets/platforms/mac/qcocoawindow_mac_p.h (renamed from src/gui/kernel/qcocoawindow_mac_p.h)0
-rw-r--r--src/widgets/platforms/mac/qcocoawindowcustomthemeframe_mac.mm (renamed from src/gui/kernel/qcocoawindowcustomthemeframe_mac.mm)0
-rw-r--r--src/widgets/platforms/mac/qcocoawindowcustomthemeframe_mac_p.h (renamed from src/gui/kernel/qcocoawindowcustomthemeframe_mac_p.h)0
-rw-r--r--src/widgets/platforms/mac/qcocoawindowdelegate_mac.mm (renamed from src/gui/kernel/qcocoawindowdelegate_mac.mm)0
-rw-r--r--src/widgets/platforms/mac/qcocoawindowdelegate_mac_p.h (renamed from src/gui/kernel/qcocoawindowdelegate_mac_p.h)0
-rw-r--r--src/widgets/platforms/mac/qcolormap_mac.cpp (renamed from src/gui/painting/qcolormap_mac.cpp)0
-rw-r--r--src/widgets/platforms/mac/qcursor_mac.mm (renamed from src/gui/kernel/qcursor_mac.mm)0
-rw-r--r--src/widgets/platforms/mac/qdesktopwidget_mac.mm (renamed from src/gui/kernel/qdesktopwidget_mac.mm)0
-rw-r--r--src/widgets/platforms/mac/qdesktopwidget_mac_p.h (renamed from src/gui/kernel/qdesktopwidget_mac_p.h)0
-rw-r--r--src/widgets/platforms/mac/qdnd_mac.mm (renamed from src/gui/kernel/qdnd_mac.mm)0
-rw-r--r--src/widgets/platforms/mac/qeventdispatcher_mac.mm (renamed from src/gui/kernel/qeventdispatcher_mac.mm)0
-rw-r--r--src/widgets/platforms/mac/qeventdispatcher_mac_p.h (renamed from src/gui/kernel/qeventdispatcher_mac_p.h)0
-rw-r--r--src/widgets/platforms/mac/qfont_mac.cpp (renamed from src/gui/text/qfont_mac.cpp)0
-rw-r--r--src/widgets/platforms/mac/qfontdatabase_mac.cpp (renamed from src/gui/text/qfontdatabase_mac.cpp)0
-rw-r--r--src/widgets/platforms/mac/qfontengine_coretext.mm (renamed from src/gui/text/qfontengine_coretext.mm)0
-rw-r--r--src/widgets/platforms/mac/qfontengine_coretext_p.h (renamed from src/gui/text/qfontengine_coretext_p.h)0
-rw-r--r--src/widgets/platforms/mac/qfontengine_mac.mm (renamed from src/gui/text/qfontengine_mac.mm)0
-rw-r--r--src/widgets/platforms/mac/qfontengine_mac_p.h (renamed from src/gui/text/qfontengine_mac_p.h)0
-rw-r--r--src/widgets/platforms/mac/qkeymapper_mac.cpp1023
-rw-r--r--src/widgets/platforms/mac/qmacdefines_mac.h158
-rw-r--r--src/widgets/platforms/mac/qmacgesturerecognizer_mac.mm (renamed from src/gui/kernel/qmacgesturerecognizer_mac.mm)0
-rw-r--r--src/widgets/platforms/mac/qmacgesturerecognizer_mac_p.h (renamed from src/gui/kernel/qmacgesturerecognizer_mac_p.h)0
-rw-r--r--src/widgets/platforms/mac/qmacinputcontext_mac.cpp (renamed from src/gui/inputmethod/qmacinputcontext_mac.cpp)0
-rw-r--r--src/widgets/platforms/mac/qmacinputcontext_p.h97
-rw-r--r--src/widgets/platforms/mac/qmime_mac.cpp1310
-rw-r--r--src/widgets/platforms/mac/qmultitouch_mac.mm (renamed from src/gui/kernel/qmultitouch_mac.mm)0
-rw-r--r--src/widgets/platforms/mac/qmultitouch_mac_p.h (renamed from src/gui/kernel/qmultitouch_mac_p.h)0
-rw-r--r--src/widgets/platforms/mac/qnsframeview_mac_p.h (renamed from src/gui/kernel/qnsframeview_mac_p.h)0
-rw-r--r--src/widgets/platforms/mac/qnsthemeframe_mac_p.h (renamed from src/gui/kernel/qnsthemeframe_mac_p.h)0
-rw-r--r--src/widgets/platforms/mac/qnstitledframe_mac_p.h (renamed from src/gui/kernel/qnstitledframe_mac_p.h)0
-rw-r--r--src/widgets/platforms/mac/qpaintdevice_mac.cpp152
-rw-r--r--src/widgets/platforms/mac/qpaintengine_mac.cpp1647
-rw-r--r--src/widgets/platforms/mac/qpaintengine_mac_p.h (renamed from src/gui/painting/qpaintengine_mac_p.h)0
-rw-r--r--src/widgets/platforms/mac/qpixmap_mac.cpp1174
-rw-r--r--src/widgets/platforms/mac/qpixmap_mac_p.h134
-rw-r--r--src/widgets/platforms/mac/qprintengine_mac.mm (renamed from src/gui/painting/qprintengine_mac.mm)0
-rw-r--r--src/widgets/platforms/mac/qprintengine_mac_p.h (renamed from src/gui/painting/qprintengine_mac_p.h)0
-rw-r--r--src/widgets/platforms/mac/qprinterinfo_mac.cpp (renamed from src/gui/painting/qprinterinfo_mac.cpp)0
-rw-r--r--src/widgets/platforms/mac/qrawfont_mac.cpp (renamed from src/gui/text/qrawfont_mac.cpp)0
-rw-r--r--src/widgets/platforms/mac/qregion_mac.cpp286
-rw-r--r--src/widgets/platforms/mac/qsound_mac.mm (renamed from src/gui/kernel/qsound_mac.mm)0
-rw-r--r--src/widgets/platforms/mac/qt_cocoa_helpers_mac.mm1563
-rw-r--r--src/widgets/platforms/mac/qt_cocoa_helpers_mac_p.h310
-rw-r--r--src/widgets/platforms/mac/qt_mac.cpp (renamed from src/gui/kernel/qt_mac.cpp)0
-rw-r--r--src/widgets/platforms/mac/qt_mac_p.h286
-rw-r--r--src/widgets/platforms/mac/qtextengine_mac.cpp (renamed from src/gui/text/qtextengine_mac.cpp)0
-rw-r--r--src/widgets/platforms/mac/qwidget_mac.mm (renamed from src/gui/kernel/qwidget_mac.mm)0
-rw-r--r--src/widgets/platforms/s60/qapplication_s60.cpp2715
-rw-r--r--src/widgets/platforms/s60/qclipboard_s60.cpp (renamed from src/gui/kernel/qclipboard_s60.cpp)0
-rw-r--r--src/widgets/platforms/s60/qcoefepinputcontext_p.h176
-rw-r--r--src/widgets/platforms/s60/qcoefepinputcontext_s60.cpp1200
-rw-r--r--src/widgets/platforms/s60/qcolormap_s60.cpp (renamed from src/gui/painting/qcolormap_s60.cpp)0
-rw-r--r--src/widgets/platforms/s60/qcursor_s60.cpp (renamed from src/gui/kernel/qcursor_s60.cpp)0
-rw-r--r--src/widgets/platforms/s60/qdesktopwidget_s60.cpp (renamed from src/gui/kernel/qdesktopwidget_s60.cpp)0
-rw-r--r--src/widgets/platforms/s60/qdnd_s60.cpp (renamed from src/gui/kernel/qdnd_s60.cpp)0
-rw-r--r--src/widgets/platforms/s60/qeventdispatcher_s60.cpp (renamed from src/gui/kernel/qeventdispatcher_s60.cpp)0
-rw-r--r--src/widgets/platforms/s60/qeventdispatcher_s60_p.h127
-rw-r--r--src/widgets/platforms/s60/qfont_s60.cpp (renamed from src/gui/text/qfont_s60.cpp)0
-rw-r--r--src/widgets/platforms/s60/qfontdatabase_s60.cpp (renamed from src/gui/text/qfontdatabase_s60.cpp)0
-rw-r--r--src/widgets/platforms/s60/qfontengine_s60.cpp (renamed from src/gui/text/qfontengine_s60.cpp)0
-rw-r--r--src/widgets/platforms/s60/qfontengine_s60_p.h (renamed from src/gui/text/qfontengine_s60_p.h)0
-rw-r--r--src/widgets/platforms/s60/qkeymapper_s60.cpp (renamed from src/gui/kernel/qkeymapper_s60.cpp)0
-rw-r--r--src/widgets/platforms/s60/qpaintengine_s60.cpp145
-rw-r--r--src/widgets/platforms/s60/qpaintengine_s60_p.h84
-rw-r--r--src/widgets/platforms/s60/qpixmap_s60.cpp1040
-rw-r--r--src/widgets/platforms/s60/qpixmap_s60_p.h141
-rw-r--r--src/widgets/platforms/s60/qregion_s60.cpp (renamed from src/gui/painting/qregion_s60.cpp)0
-rw-r--r--src/widgets/platforms/s60/qsoftkeymanager_s60.cpp (renamed from src/gui/kernel/qsoftkeymanager_s60.cpp)0
-rw-r--r--src/widgets/platforms/s60/qsoftkeymanager_s60_p.h (renamed from src/gui/kernel/qsoftkeymanager_s60_p.h)0
-rw-r--r--src/widgets/platforms/s60/qsound_s60.cpp (renamed from src/gui/kernel/qsound_s60.cpp)0
-rw-r--r--src/widgets/platforms/s60/qt_s60_p.h (renamed from src/gui/kernel/qt_s60_p.h)0
-rw-r--r--src/widgets/platforms/s60/qwidget_s60.cpp (renamed from src/gui/kernel/qwidget_s60.cpp)0
-rw-r--r--src/widgets/platforms/win/qapplication_win.cpp4248
-rw-r--r--src/widgets/platforms/win/qclipboard_win.cpp (renamed from src/gui/kernel/qclipboard_win.cpp)0
-rw-r--r--src/widgets/platforms/win/qcolormap_win.cpp (renamed from src/gui/painting/qcolormap_win.cpp)0
-rw-r--r--src/widgets/platforms/win/qcursor_win.cpp (renamed from src/gui/kernel/qcursor_win.cpp)0
-rw-r--r--src/widgets/platforms/win/qdesktopwidget_win.cpp (renamed from src/gui/kernel/qdesktopwidget_win.cpp)0
-rw-r--r--src/widgets/platforms/win/qdnd_win.cpp (renamed from src/gui/kernel/qdnd_win.cpp)0
-rw-r--r--src/widgets/platforms/win/qfont_win.cpp (renamed from src/gui/text/qfont_win.cpp)0
-rw-r--r--src/widgets/platforms/win/qfontdatabase_win.cpp (renamed from src/gui/text/qfontdatabase_win.cpp)0
-rw-r--r--src/widgets/platforms/win/qfontengine_win.cpp (renamed from src/gui/text/qfontengine_win.cpp)0
-rw-r--r--src/widgets/platforms/win/qfontengine_win_p.h (renamed from src/gui/text/qfontengine_win_p.h)0
-rw-r--r--src/widgets/platforms/win/qguifunctions_wince.cpp (renamed from src/gui/kernel/qguifunctions_wince.cpp)0
-rw-r--r--src/widgets/platforms/win/qguifunctions_wince.h (renamed from src/gui/kernel/qguifunctions_wince.h)0
-rw-r--r--src/widgets/platforms/win/qkeymapper_win.cpp1207
-rw-r--r--src/widgets/platforms/win/qmime_win.cpp (renamed from src/gui/kernel/qmime_win.cpp)0
-rw-r--r--src/widgets/platforms/win/qole_win.cpp (renamed from src/gui/kernel/qole_win.cpp)0
-rw-r--r--src/widgets/platforms/win/qpaintdevice_win.cpp (renamed from src/gui/painting/qpaintdevice_win.cpp)0
-rw-r--r--src/widgets/platforms/win/qpixmap_win.cpp477
-rw-r--r--src/widgets/platforms/win/qprintengine_win.cpp (renamed from src/gui/painting/qprintengine_win.cpp)0
-rw-r--r--src/widgets/platforms/win/qprintengine_win_p.h (renamed from src/gui/painting/qprintengine_win_p.h)0
-rw-r--r--src/widgets/platforms/win/qprinterinfo_win.cpp (renamed from src/gui/painting/qprinterinfo_win.cpp)0
-rw-r--r--src/widgets/platforms/win/qrawfont_win.cpp (renamed from src/gui/text/qrawfont_win.cpp)0
-rw-r--r--src/widgets/platforms/win/qregion_win.cpp (renamed from src/gui/painting/qregion_win.cpp)0
-rw-r--r--src/widgets/platforms/win/qsound_win.cpp (renamed from src/gui/kernel/qsound_win.cpp)0
-rw-r--r--src/widgets/platforms/win/qwidget_win.cpp (renamed from src/gui/kernel/qwidget_win.cpp)0
-rw-r--r--src/widgets/platforms/win/qwidget_wince.cpp (renamed from src/gui/kernel/qwidget_wince.cpp)0
-rw-r--r--src/widgets/platforms/win/qwininputcontext_p.h111
-rw-r--r--src/widgets/platforms/win/qwininputcontext_win.cpp (renamed from src/gui/inputmethod/qwininputcontext_win.cpp)0
-rw-r--r--src/widgets/platforms/win/qwinnativepangesturerecognizer_win.cpp (renamed from src/gui/kernel/qwinnativepangesturerecognizer_win.cpp)0
-rw-r--r--src/widgets/platforms/win/qwinnativepangesturerecognizer_win_p.h (renamed from src/gui/kernel/qwinnativepangesturerecognizer_win_p.h)0
-rw-r--r--src/widgets/platforms/x11/qapplication_x11.cpp6239
-rw-r--r--src/widgets/platforms/x11/qclipboard_x11.cpp (renamed from src/gui/kernel/qclipboard_x11.cpp)0
-rw-r--r--src/widgets/platforms/x11/qcolormap_x11.cpp (renamed from src/gui/painting/qcolormap_x11.cpp)0
-rw-r--r--src/widgets/platforms/x11/qcursor_x11.cpp640
-rw-r--r--src/widgets/platforms/x11/qdesktopwidget_x11.cpp (renamed from src/gui/kernel/qdesktopwidget_x11.cpp)0
-rw-r--r--src/widgets/platforms/x11/qdnd_x11.cpp2072
-rw-r--r--src/widgets/platforms/x11/qeventdispatcher_x11.cpp (renamed from src/gui/kernel/qeventdispatcher_x11.cpp)0
-rw-r--r--src/widgets/platforms/x11/qeventdispatcher_x11_p.h (renamed from src/gui/kernel/qeventdispatcher_x11_p.h)0
-rw-r--r--src/widgets/platforms/x11/qfont_x11.cpp368
-rw-r--r--src/widgets/platforms/x11/qfontdatabase_x11.cpp (renamed from src/gui/text/qfontdatabase_x11.cpp)0
-rw-r--r--src/widgets/platforms/x11/qfontengine_x11.cpp1205
-rw-r--r--src/widgets/platforms/x11/qfontengine_x11_p.h180
-rw-r--r--src/widgets/platforms/x11/qkde.cpp (renamed from src/gui/kernel/qkde.cpp)0
-rw-r--r--src/widgets/platforms/x11/qkde_p.h81
-rw-r--r--src/widgets/platforms/x11/qkeymapper_x11.cpp (renamed from src/gui/kernel/qkeymapper_x11.cpp)0
-rw-r--r--src/widgets/platforms/x11/qkeymapper_x11_p.cpp (renamed from src/gui/kernel/qkeymapper_x11_p.cpp)0
-rw-r--r--src/widgets/platforms/x11/qmotifdnd_x11.cpp (renamed from src/gui/kernel/qmotifdnd_x11.cpp)0
-rw-r--r--src/widgets/platforms/x11/qpaintdevice_x11.cpp84
-rw-r--r--src/widgets/platforms/x11/qpaintengine_x11.cpp2499
-rw-r--r--src/widgets/platforms/x11/qpaintengine_x11_p.h246
-rw-r--r--src/widgets/platforms/x11/qpixmap_x11.cpp2419
-rw-r--r--src/widgets/platforms/x11/qpixmap_x11_p.h156
-rw-r--r--src/widgets/platforms/x11/qregion_x11.cpp (renamed from src/gui/painting/qregion_x11.cpp)0
-rw-r--r--src/widgets/platforms/x11/qsound_x11.cpp (renamed from src/gui/kernel/qsound_x11.cpp)0
-rw-r--r--src/widgets/platforms/x11/qt_x11_p.h757
-rw-r--r--src/widgets/platforms/x11/qwidget_x11.cpp3149
-rw-r--r--src/widgets/platforms/x11/qwidgetcreate_x11.cpp (renamed from src/gui/kernel/qwidgetcreate_x11.cpp)0
-rw-r--r--src/widgets/platforms/x11/qx11embed_x11.cpp (renamed from src/gui/kernel/qx11embed_x11.cpp)0
-rw-r--r--src/widgets/platforms/x11/qx11embed_x11.h132
-rw-r--r--src/widgets/platforms/x11/qx11info_x11.cpp (renamed from src/gui/kernel/qx11info_x11.cpp)0
-rw-r--r--src/widgets/platforms/x11/qx11info_x11.h123
-rw-r--r--src/widgets/platforms/x11/qximinputcontext_p.h142
-rw-r--r--src/widgets/platforms/x11/qximinputcontext_x11.cpp (renamed from src/gui/inputmethod/qximinputcontext_x11.cpp)0
-rw-r--r--src/widgets/s60framework/qs60mainapplication.cpp (renamed from src/gui/s60framework/qs60mainapplication.cpp)0
-rw-r--r--src/widgets/s60framework/qs60mainapplication.h93
-rw-r--r--src/widgets/s60framework/qs60mainapplication_p.h (renamed from src/gui/s60framework/qs60mainapplication_p.h)0
-rw-r--r--src/widgets/s60framework/qs60mainappui.cpp430
-rw-r--r--src/widgets/s60framework/qs60mainappui.h152
-rw-r--r--src/widgets/s60framework/qs60maindocument.cpp (renamed from src/gui/s60framework/qs60maindocument.cpp)0
-rw-r--r--src/widgets/s60framework/qs60maindocument.h92
-rw-r--r--src/widgets/s60framework/s60framework.pri (renamed from src/gui/s60framework/s60framework.pri)0
-rw-r--r--src/widgets/s60framework/s60main.rss (renamed from src/gui/s60framework/s60main.rss)0
-rw-r--r--src/widgets/statemachine/qbasickeyeventtransition.cpp (renamed from src/gui/statemachine/qbasickeyeventtransition.cpp)0
-rw-r--r--src/widgets/statemachine/qbasickeyeventtransition_p.h (renamed from src/gui/statemachine/qbasickeyeventtransition_p.h)0
-rw-r--r--src/widgets/statemachine/qbasicmouseeventtransition.cpp (renamed from src/gui/statemachine/qbasicmouseeventtransition.cpp)0
-rw-r--r--src/widgets/statemachine/qbasicmouseeventtransition_p.h (renamed from src/gui/statemachine/qbasicmouseeventtransition_p.h)0
-rw-r--r--src/widgets/statemachine/qguistatemachine.cpp494
-rw-r--r--src/widgets/statemachine/qkeyeventtransition.cpp (renamed from src/gui/statemachine/qkeyeventtransition.cpp)0
-rw-r--r--src/widgets/statemachine/qkeyeventtransition.h88
-rw-r--r--src/widgets/statemachine/qmouseeventtransition.cpp (renamed from src/gui/statemachine/qmouseeventtransition.cpp)0
-rw-r--r--src/widgets/statemachine/qmouseeventtransition.h92
-rw-r--r--src/widgets/statemachine/statemachine.pri (renamed from src/gui/statemachine/statemachine.pri)0
-rw-r--r--src/widgets/styles/images/cdr-128.png (renamed from src/gui/styles/images/cdr-128.png)bin16418 -> 16418 bytes
-rw-r--r--src/widgets/styles/images/cdr-16.png (renamed from src/gui/styles/images/cdr-16.png)bin845 -> 845 bytes
-rw-r--r--src/widgets/styles/images/cdr-32.png (renamed from src/gui/styles/images/cdr-32.png)bin2016 -> 2016 bytes
-rw-r--r--src/widgets/styles/images/closedock-16.png (renamed from src/gui/styles/images/closedock-16.png)bin516 -> 516 bytes
-rw-r--r--src/widgets/styles/images/closedock-down-16.png (renamed from src/gui/styles/images/closedock-down-16.png)bin578 -> 578 bytes
-rw-r--r--src/widgets/styles/images/computer-16.png (renamed from src/gui/styles/images/computer-16.png)bin782 -> 782 bytes
-rw-r--r--src/widgets/styles/images/computer-32.png (renamed from src/gui/styles/images/computer-32.png)bin1807 -> 1807 bytes
-rw-r--r--src/widgets/styles/images/defaults60theme.blob (renamed from src/gui/styles/images/defaults60theme.blob)bin74127 -> 74127 bytes
-rw-r--r--src/widgets/styles/images/desktop-16.png (renamed from src/gui/styles/images/desktop-16.png)bin773 -> 773 bytes
-rw-r--r--src/widgets/styles/images/desktop-32.png (renamed from src/gui/styles/images/desktop-32.png)bin1103 -> 1103 bytes
-rw-r--r--src/widgets/styles/images/dirclosed-128.png (renamed from src/gui/styles/images/dirclosed-128.png)bin1386 -> 1386 bytes
-rw-r--r--src/widgets/styles/images/dirclosed-16.png (renamed from src/gui/styles/images/dirclosed-16.png)bin231 -> 231 bytes
-rw-r--r--src/widgets/styles/images/dirclosed-32.png (renamed from src/gui/styles/images/dirclosed-32.png)bin474 -> 474 bytes
-rw-r--r--src/widgets/styles/images/dirlink-128.png (renamed from src/gui/styles/images/dirlink-128.png)bin5155 -> 5155 bytes
-rw-r--r--src/widgets/styles/images/dirlink-16.png (renamed from src/gui/styles/images/dirlink-16.png)bin416 -> 416 bytes
-rw-r--r--src/widgets/styles/images/dirlink-32.png (renamed from src/gui/styles/images/dirlink-32.png)bin1046 -> 1046 bytes
-rw-r--r--src/widgets/styles/images/diropen-128.png (renamed from src/gui/styles/images/diropen-128.png)bin2075 -> 2075 bytes
-rw-r--r--src/widgets/styles/images/diropen-16.png (renamed from src/gui/styles/images/diropen-16.png)bin248 -> 248 bytes
-rw-r--r--src/widgets/styles/images/diropen-32.png (renamed from src/gui/styles/images/diropen-32.png)bin633 -> 633 bytes
-rw-r--r--src/widgets/styles/images/dockdock-16.png (renamed from src/gui/styles/images/dockdock-16.png)bin438 -> 438 bytes
-rw-r--r--src/widgets/styles/images/dockdock-down-16.png (renamed from src/gui/styles/images/dockdock-down-16.png)bin406 -> 406 bytes
-rw-r--r--src/widgets/styles/images/down-128.png (renamed from src/gui/styles/images/down-128.png)bin9550 -> 9550 bytes
-rw-r--r--src/widgets/styles/images/down-16.png (renamed from src/gui/styles/images/down-16.png)bin817 -> 817 bytes
-rw-r--r--src/widgets/styles/images/down-32.png (renamed from src/gui/styles/images/down-32.png)bin1820 -> 1820 bytes
-rw-r--r--src/widgets/styles/images/dvd-128.png (renamed from src/gui/styles/images/dvd-128.png)bin14941 -> 14941 bytes
-rw-r--r--src/widgets/styles/images/dvd-16.png (renamed from src/gui/styles/images/dvd-16.png)bin892 -> 892 bytes
-rw-r--r--src/widgets/styles/images/dvd-32.png (renamed from src/gui/styles/images/dvd-32.png)bin2205 -> 2205 bytes
-rw-r--r--src/widgets/styles/images/file-128.png (renamed from src/gui/styles/images/file-128.png)bin3997 -> 3997 bytes
-rw-r--r--src/widgets/styles/images/file-16.png (renamed from src/gui/styles/images/file-16.png)bin423 -> 423 bytes
-rw-r--r--src/widgets/styles/images/file-32.png (renamed from src/gui/styles/images/file-32.png)bin713 -> 713 bytes
-rw-r--r--src/widgets/styles/images/filecontents-128.png (renamed from src/gui/styles/images/filecontents-128.png)bin8109 -> 8109 bytes
-rw-r--r--src/widgets/styles/images/filecontents-16.png (renamed from src/gui/styles/images/filecontents-16.png)bin766 -> 766 bytes
-rw-r--r--src/widgets/styles/images/filecontents-32.png (renamed from src/gui/styles/images/filecontents-32.png)bin1712 -> 1712 bytes
-rw-r--r--src/widgets/styles/images/fileinfo-128.png (renamed from src/gui/styles/images/fileinfo-128.png)bin12002 -> 12002 bytes
-rw-r--r--src/widgets/styles/images/fileinfo-16.png (renamed from src/gui/styles/images/fileinfo-16.png)bin849 -> 849 bytes
-rw-r--r--src/widgets/styles/images/fileinfo-32.png (renamed from src/gui/styles/images/fileinfo-32.png)bin2010 -> 2010 bytes
-rw-r--r--src/widgets/styles/images/filelink-128.png (renamed from src/gui/styles/images/filelink-128.png)bin5601 -> 5601 bytes
-rw-r--r--src/widgets/styles/images/filelink-16.png (renamed from src/gui/styles/images/filelink-16.png)bin566 -> 566 bytes
-rw-r--r--src/widgets/styles/images/filelink-32.png (renamed from src/gui/styles/images/filelink-32.png)bin1192 -> 1192 bytes
-rw-r--r--src/widgets/styles/images/floppy-128.png (renamed from src/gui/styles/images/floppy-128.png)bin5074 -> 5074 bytes
-rw-r--r--src/widgets/styles/images/floppy-16.png (renamed from src/gui/styles/images/floppy-16.png)bin602 -> 602 bytes
-rw-r--r--src/widgets/styles/images/floppy-32.png (renamed from src/gui/styles/images/floppy-32.png)bin1019 -> 1019 bytes
-rw-r--r--src/widgets/styles/images/fontbitmap-16.png (renamed from src/gui/styles/images/fontbitmap-16.png)bin537 -> 537 bytes
-rw-r--r--src/widgets/styles/images/fonttruetype-16.png (renamed from src/gui/styles/images/fonttruetype-16.png)bin442 -> 442 bytes
-rw-r--r--src/widgets/styles/images/harddrive-128.png (renamed from src/gui/styles/images/harddrive-128.png)bin11250 -> 11250 bytes
-rw-r--r--src/widgets/styles/images/harddrive-16.png (renamed from src/gui/styles/images/harddrive-16.png)bin802 -> 802 bytes
-rw-r--r--src/widgets/styles/images/harddrive-32.png (renamed from src/gui/styles/images/harddrive-32.png)bin1751 -> 1751 bytes
-rw-r--r--src/widgets/styles/images/left-128.png (renamed from src/gui/styles/images/left-128.png)bin9432 -> 9432 bytes
-rw-r--r--src/widgets/styles/images/left-16.png (renamed from src/gui/styles/images/left-16.png)bin826 -> 826 bytes
-rw-r--r--src/widgets/styles/images/left-32.png (renamed from src/gui/styles/images/left-32.png)bin1799 -> 1799 bytes
-rw-r--r--src/widgets/styles/images/media-pause-16.png (renamed from src/gui/styles/images/media-pause-16.png)bin229 -> 229 bytes
-rw-r--r--src/widgets/styles/images/media-pause-32.png (renamed from src/gui/styles/images/media-pause-32.png)bin185 -> 185 bytes
-rw-r--r--src/widgets/styles/images/media-play-16.png (renamed from src/gui/styles/images/media-play-16.png)bin262 -> 262 bytes
-rw-r--r--src/widgets/styles/images/media-play-32.png (renamed from src/gui/styles/images/media-play-32.png)bin413 -> 413 bytes
-rw-r--r--src/widgets/styles/images/media-seek-backward-16.png (renamed from src/gui/styles/images/media-seek-backward-16.png)bin384 -> 384 bytes
-rw-r--r--src/widgets/styles/images/media-seek-backward-32.png (renamed from src/gui/styles/images/media-seek-backward-32.png)bin548 -> 548 bytes
-rw-r--r--src/widgets/styles/images/media-seek-forward-16.png (renamed from src/gui/styles/images/media-seek-forward-16.png)bin370 -> 370 bytes
-rw-r--r--src/widgets/styles/images/media-seek-forward-32.png (renamed from src/gui/styles/images/media-seek-forward-32.png)bin524 -> 524 bytes
-rw-r--r--src/widgets/styles/images/media-skip-backward-16.png (renamed from src/gui/styles/images/media-skip-backward-16.png)bin396 -> 396 bytes
-rw-r--r--src/widgets/styles/images/media-skip-backward-32.png (renamed from src/gui/styles/images/media-skip-backward-32.png)bin570 -> 570 bytes
-rw-r--r--src/widgets/styles/images/media-skip-forward-16.png (renamed from src/gui/styles/images/media-skip-forward-16.png)bin384 -> 384 bytes
-rw-r--r--src/widgets/styles/images/media-skip-forward-32.png (renamed from src/gui/styles/images/media-skip-forward-32.png)bin549 -> 549 bytes
-rw-r--r--src/widgets/styles/images/media-stop-16.png (renamed from src/gui/styles/images/media-stop-16.png)bin166 -> 166 bytes
-rw-r--r--src/widgets/styles/images/media-stop-32.png (renamed from src/gui/styles/images/media-stop-32.png)bin176 -> 176 bytes
-rw-r--r--src/widgets/styles/images/media-volume-16.png (renamed from src/gui/styles/images/media-volume-16.png)bin799 -> 799 bytes
-rw-r--r--src/widgets/styles/images/media-volume-muted-16.png (renamed from src/gui/styles/images/media-volume-muted-16.png)bin668 -> 668 bytes
-rw-r--r--src/widgets/styles/images/networkdrive-128.png (renamed from src/gui/styles/images/networkdrive-128.png)bin18075 -> 18075 bytes
-rw-r--r--src/widgets/styles/images/networkdrive-16.png (renamed from src/gui/styles/images/networkdrive-16.png)bin885 -> 885 bytes
-rw-r--r--src/widgets/styles/images/networkdrive-32.png (renamed from src/gui/styles/images/networkdrive-32.png)bin2245 -> 2245 bytes
-rw-r--r--src/widgets/styles/images/newdirectory-128.png (renamed from src/gui/styles/images/newdirectory-128.png)bin7503 -> 7503 bytes
-rw-r--r--src/widgets/styles/images/newdirectory-16.png (renamed from src/gui/styles/images/newdirectory-16.png)bin870 -> 870 bytes
-rw-r--r--src/widgets/styles/images/newdirectory-32.png (renamed from src/gui/styles/images/newdirectory-32.png)bin1590 -> 1590 bytes
-rw-r--r--src/widgets/styles/images/parentdir-128.png (renamed from src/gui/styles/images/parentdir-128.png)bin8093 -> 8093 bytes
-rw-r--r--src/widgets/styles/images/parentdir-16.png (renamed from src/gui/styles/images/parentdir-16.png)bin938 -> 938 bytes
-rw-r--r--src/widgets/styles/images/parentdir-32.png (renamed from src/gui/styles/images/parentdir-32.png)bin1603 -> 1603 bytes
-rw-r--r--src/widgets/styles/images/refresh-24.png (renamed from src/gui/styles/images/refresh-24.png)bin1654 -> 1654 bytes
-rw-r--r--src/widgets/styles/images/refresh-32.png (renamed from src/gui/styles/images/refresh-32.png)bin2431 -> 2431 bytes
-rw-r--r--src/widgets/styles/images/right-128.png (renamed from src/gui/styles/images/right-128.png)bin9367 -> 9367 bytes
-rw-r--r--src/widgets/styles/images/right-16.png (renamed from src/gui/styles/images/right-16.png)bin811 -> 811 bytes
-rw-r--r--src/widgets/styles/images/right-32.png (renamed from src/gui/styles/images/right-32.png)bin1804 -> 1804 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-apply-128.png (renamed from src/gui/styles/images/standardbutton-apply-128.png)bin5395 -> 5395 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-apply-16.png (renamed from src/gui/styles/images/standardbutton-apply-16.png)bin611 -> 611 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-apply-32.png (renamed from src/gui/styles/images/standardbutton-apply-32.png)bin1279 -> 1279 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-cancel-128.png (renamed from src/gui/styles/images/standardbutton-cancel-128.png)bin7039 -> 7039 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-cancel-16.png (renamed from src/gui/styles/images/standardbutton-cancel-16.png)bin689 -> 689 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-cancel-32.png (renamed from src/gui/styles/images/standardbutton-cancel-32.png)bin1573 -> 1573 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-clear-128.png (renamed from src/gui/styles/images/standardbutton-clear-128.png)bin3094 -> 3094 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-clear-16.png (renamed from src/gui/styles/images/standardbutton-clear-16.png)bin456 -> 456 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-clear-32.png (renamed from src/gui/styles/images/standardbutton-clear-32.png)bin866 -> 866 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-close-128.png (renamed from src/gui/styles/images/standardbutton-close-128.png)bin4512 -> 4512 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-close-16.png (renamed from src/gui/styles/images/standardbutton-close-16.png)bin366 -> 366 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-close-32.png (renamed from src/gui/styles/images/standardbutton-close-32.png)bin780 -> 780 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-closetab-16.png (renamed from src/gui/styles/images/standardbutton-closetab-16.png)bin406 -> 406 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-closetab-down-16.png (renamed from src/gui/styles/images/standardbutton-closetab-down-16.png)bin481 -> 481 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-closetab-hover-16.png (renamed from src/gui/styles/images/standardbutton-closetab-hover-16.png)bin570 -> 570 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-delete-128.png (renamed from src/gui/styles/images/standardbutton-delete-128.png)bin5414 -> 5414 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-delete-16.png (renamed from src/gui/styles/images/standardbutton-delete-16.png)bin722 -> 722 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-delete-32.png (renamed from src/gui/styles/images/standardbutton-delete-32.png)bin1541 -> 1541 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-help-128.png (renamed from src/gui/styles/images/standardbutton-help-128.png)bin10765 -> 10765 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-help-16.png (renamed from src/gui/styles/images/standardbutton-help-16.png)bin840 -> 840 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-help-32.png (renamed from src/gui/styles/images/standardbutton-help-32.png)bin2066 -> 2066 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-no-128.png (renamed from src/gui/styles/images/standardbutton-no-128.png)bin6520 -> 6520 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-no-16.png (renamed from src/gui/styles/images/standardbutton-no-16.png)bin701 -> 701 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-no-32.png (renamed from src/gui/styles/images/standardbutton-no-32.png)bin1445 -> 1445 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-ok-128.png (renamed from src/gui/styles/images/standardbutton-ok-128.png)bin4232 -> 4232 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-ok-16.png (renamed from src/gui/styles/images/standardbutton-ok-16.png)bin584 -> 584 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-ok-32.png (renamed from src/gui/styles/images/standardbutton-ok-32.png)bin1246 -> 1246 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-open-128.png (renamed from src/gui/styles/images/standardbutton-open-128.png)bin5415 -> 5415 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-open-16.png (renamed from src/gui/styles/images/standardbutton-open-16.png)bin629 -> 629 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-open-32.png (renamed from src/gui/styles/images/standardbutton-open-32.png)bin1154 -> 1154 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-save-128.png (renamed from src/gui/styles/images/standardbutton-save-128.png)bin4398 -> 4398 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-save-16.png (renamed from src/gui/styles/images/standardbutton-save-16.png)bin583 -> 583 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-save-32.png (renamed from src/gui/styles/images/standardbutton-save-32.png)bin1092 -> 1092 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-yes-128.png (renamed from src/gui/styles/images/standardbutton-yes-128.png)bin6554 -> 6554 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-yes-16.png (renamed from src/gui/styles/images/standardbutton-yes-16.png)bin687 -> 687 bytes
-rw-r--r--src/widgets/styles/images/standardbutton-yes-32.png (renamed from src/gui/styles/images/standardbutton-yes-32.png)bin1504 -> 1504 bytes
-rw-r--r--src/widgets/styles/images/stop-24.png (renamed from src/gui/styles/images/stop-24.png)bin1267 -> 1267 bytes
-rw-r--r--src/widgets/styles/images/stop-32.png (renamed from src/gui/styles/images/stop-32.png)bin1878 -> 1878 bytes
-rw-r--r--src/widgets/styles/images/trash-128.png (renamed from src/gui/styles/images/trash-128.png)bin3296 -> 3296 bytes
-rw-r--r--src/widgets/styles/images/trash-16.png (renamed from src/gui/styles/images/trash-16.png)bin419 -> 419 bytes
-rw-r--r--src/widgets/styles/images/trash-32.png (renamed from src/gui/styles/images/trash-32.png)bin883 -> 883 bytes
-rw-r--r--src/widgets/styles/images/up-128.png (renamed from src/gui/styles/images/up-128.png)bin9363 -> 9363 bytes
-rw-r--r--src/widgets/styles/images/up-16.png (renamed from src/gui/styles/images/up-16.png)bin814 -> 814 bytes
-rw-r--r--src/widgets/styles/images/up-32.png (renamed from src/gui/styles/images/up-32.png)bin1798 -> 1798 bytes
-rw-r--r--src/widgets/styles/images/viewdetailed-128.png (renamed from src/gui/styles/images/viewdetailed-128.png)bin4743 -> 4743 bytes
-rw-r--r--src/widgets/styles/images/viewdetailed-16.png (renamed from src/gui/styles/images/viewdetailed-16.png)bin499 -> 499 bytes
-rw-r--r--src/widgets/styles/images/viewdetailed-32.png (renamed from src/gui/styles/images/viewdetailed-32.png)bin1092 -> 1092 bytes
-rw-r--r--src/widgets/styles/images/viewlist-128.png (renamed from src/gui/styles/images/viewlist-128.png)bin4069 -> 4069 bytes
-rw-r--r--src/widgets/styles/images/viewlist-16.png (renamed from src/gui/styles/images/viewlist-16.png)bin490 -> 490 bytes
-rw-r--r--src/widgets/styles/images/viewlist-32.png (renamed from src/gui/styles/images/viewlist-32.png)bin1006 -> 1006 bytes
-rw-r--r--src/widgets/styles/qcdestyle.cpp (renamed from src/gui/styles/qcdestyle.cpp)0
-rw-r--r--src/widgets/styles/qcdestyle.h82
-rw-r--r--src/widgets/styles/qcleanlooksstyle.cpp (renamed from src/gui/styles/qcleanlooksstyle.cpp)0
-rw-r--r--src/widgets/styles/qcleanlooksstyle.h114
-rw-r--r--src/widgets/styles/qcleanlooksstyle_p.h (renamed from src/gui/styles/qcleanlooksstyle_p.h)0
-rw-r--r--src/widgets/styles/qcommonstyle.cpp (renamed from src/gui/styles/qcommonstyle.cpp)0
-rw-r--r--src/widgets/styles/qcommonstyle.h109
-rw-r--r--src/widgets/styles/qcommonstyle_p.h (renamed from src/gui/styles/qcommonstyle_p.h)0
-rw-r--r--src/widgets/styles/qcommonstylepixmaps_p.h (renamed from src/gui/styles/qcommonstylepixmaps_p.h)0
-rw-r--r--src/widgets/styles/qdrawutil.cpp1053
-rw-r--r--src/widgets/styles/qdrawutil.h175
-rw-r--r--src/widgets/styles/qgtkpainter.cpp716
-rw-r--r--src/widgets/styles/qgtkpainter_p.h129
-rw-r--r--src/widgets/styles/qgtkstyle.cpp3560
-rw-r--r--src/widgets/styles/qgtkstyle.h128
-rw-r--r--src/widgets/styles/qgtkstyle_p.cpp1146
-rw-r--r--src/widgets/styles/qgtkstyle_p.h531
-rw-r--r--src/widgets/styles/qmacstyle.qdoc (renamed from src/gui/styles/qmacstyle.qdoc)0
-rw-r--r--src/widgets/styles/qmacstyle_mac.h148
-rw-r--r--src/widgets/styles/qmacstyle_mac.mm6019
-rw-r--r--src/widgets/styles/qmacstyle_mac_p.h241
-rw-r--r--src/widgets/styles/qmacstylepixmaps_mac_p.h (renamed from src/gui/styles/qmacstylepixmaps_mac_p.h)0
-rw-r--r--src/widgets/styles/qmotifstyle.cpp2721
-rw-r--r--src/widgets/styles/qmotifstyle.h128
-rw-r--r--src/widgets/styles/qmotifstyle_p.h (renamed from src/gui/styles/qmotifstyle_p.h)0
-rw-r--r--src/widgets/styles/qplastiquestyle.cpp (renamed from src/gui/styles/qplastiquestyle.cpp)0
-rw-r--r--src/widgets/styles/qplastiquestyle.h119
-rw-r--r--src/widgets/styles/qproxystyle.cpp (renamed from src/gui/styles/qproxystyle.cpp)0
-rw-r--r--src/widgets/styles/qproxystyle.h114
-rw-r--r--src/widgets/styles/qproxystyle_p.h (renamed from src/gui/styles/qproxystyle_p.h)0
-rw-r--r--src/widgets/styles/qs60style.cpp (renamed from src/gui/styles/qs60style.cpp)0
-rw-r--r--src/widgets/styles/qs60style.h118
-rw-r--r--src/widgets/styles/qs60style_p.h (renamed from src/gui/styles/qs60style_p.h)0
-rw-r--r--src/widgets/styles/qs60style_s60.cpp1591
-rw-r--r--src/widgets/styles/qs60style_simulated.cpp (renamed from src/gui/styles/qs60style_simulated.cpp)0
-rw-r--r--src/widgets/styles/qs60style_stub.cpp (renamed from src/gui/styles/qs60style_stub.cpp)0
-rw-r--r--src/widgets/styles/qstyle.cpp2459
-rw-r--r--src/widgets/styles/qstyle.h889
-rw-r--r--src/widgets/styles/qstyle.qrc (renamed from src/gui/styles/qstyle.qrc)0
-rw-r--r--src/widgets/styles/qstyle_p.h108
-rw-r--r--src/widgets/styles/qstyle_s60.qrc (renamed from src/gui/styles/qstyle_s60.qrc)0
-rw-r--r--src/widgets/styles/qstyle_s60_simulated.qrc (renamed from src/gui/styles/qstyle_s60_simulated.qrc)0
-rw-r--r--src/widgets/styles/qstyle_wince.qrc (renamed from src/gui/styles/qstyle_wince.qrc)0
-rw-r--r--src/widgets/styles/qstylefactory.cpp (renamed from src/gui/styles/qstylefactory.cpp)0
-rw-r--r--src/widgets/styles/qstylefactory.h66
-rw-r--r--src/widgets/styles/qstylehelper.cpp (renamed from src/gui/styles/qstylehelper.cpp)0
-rw-r--r--src/widgets/styles/qstylehelper_p.h89
-rw-r--r--src/widgets/styles/qstyleoption.cpp (renamed from src/gui/styles/qstyleoption.cpp)0
-rw-r--r--src/widgets/styles/qstyleoption.h970
-rw-r--r--src/widgets/styles/qstylepainter.cpp (renamed from src/gui/painting/qstylepainter.cpp)0
-rw-r--r--src/widgets/styles/qstylepainter.h112
-rw-r--r--src/widgets/styles/qstyleplugin.cpp (renamed from src/gui/styles/qstyleplugin.cpp)0
-rw-r--r--src/widgets/styles/qstyleplugin.h81
-rw-r--r--src/widgets/styles/qstylesheetstyle.cpp5900
-rw-r--r--src/widgets/styles/qstylesheetstyle_default.cpp (renamed from src/gui/styles/qstylesheetstyle_default.cpp)0
-rw-r--r--src/widgets/styles/qstylesheetstyle_p.h204
-rw-r--r--src/widgets/styles/qwindowscestyle.cpp (renamed from src/gui/styles/qwindowscestyle.cpp)0
-rw-r--r--src/widgets/styles/qwindowscestyle.h103
-rw-r--r--src/widgets/styles/qwindowscestyle_p.h (renamed from src/gui/styles/qwindowscestyle_p.h)0
-rw-r--r--src/widgets/styles/qwindowsmobilestyle.cpp (renamed from src/gui/styles/qwindowsmobilestyle.cpp)0
-rw-r--r--src/widgets/styles/qwindowsmobilestyle.h116
-rw-r--r--src/widgets/styles/qwindowsmobilestyle_p.h (renamed from src/gui/styles/qwindowsmobilestyle_p.h)0
-rw-r--r--src/widgets/styles/qwindowsstyle.cpp3390
-rw-r--r--src/widgets/styles/qwindowsstyle.h111
-rw-r--r--src/widgets/styles/qwindowsstyle_p.h (renamed from src/gui/styles/qwindowsstyle_p.h)0
-rw-r--r--src/widgets/styles/qwindowsvistastyle.cpp2672
-rw-r--r--src/widgets/styles/qwindowsvistastyle.h108
-rw-r--r--src/widgets/styles/qwindowsvistastyle_p.h (renamed from src/gui/styles/qwindowsvistastyle_p.h)0
-rw-r--r--src/widgets/styles/qwindowsxpstyle.cpp4350
-rw-r--r--src/widgets/styles/qwindowsxpstyle.h107
-rw-r--r--src/widgets/styles/qwindowsxpstyle_p.h356
-rw-r--r--src/widgets/styles/styles.pri194
-rw-r--r--src/widgets/symbian/images/blank.png (renamed from src/gui/symbian/images/blank.png)bin91 -> 91 bytes
-rw-r--r--src/widgets/symbian/images/busy12.png (renamed from src/gui/symbian/images/busy12.png)bin253 -> 253 bytes
-rw-r--r--src/widgets/symbian/images/busy3.png (renamed from src/gui/symbian/images/busy3.png)bin251 -> 251 bytes
-rw-r--r--src/widgets/symbian/images/busy6.png (renamed from src/gui/symbian/images/busy6.png)bin253 -> 253 bytes
-rw-r--r--src/widgets/symbian/images/busy9.png (renamed from src/gui/symbian/images/busy9.png)bin255 -> 255 bytes
-rw-r--r--src/widgets/symbian/images/closehand.png (renamed from src/gui/symbian/images/closehand.png)bin190 -> 190 bytes
-rw-r--r--src/widgets/symbian/images/cross.png (renamed from src/gui/symbian/images/cross.png)bin145 -> 145 bytes
-rw-r--r--src/widgets/symbian/images/forbidden.png (renamed from src/gui/symbian/images/forbidden.png)bin256 -> 256 bytes
-rw-r--r--src/widgets/symbian/images/handpoint.png (renamed from src/gui/symbian/images/handpoint.png)bin230 -> 230 bytes
-rw-r--r--src/widgets/symbian/images/ibeam.png (renamed from src/gui/symbian/images/ibeam.png)bin176 -> 176 bytes
-rw-r--r--src/widgets/symbian/images/openhand.png (renamed from src/gui/symbian/images/openhand.png)bin201 -> 201 bytes
-rw-r--r--src/widgets/symbian/images/pointer.png (renamed from src/gui/symbian/images/pointer.png)bin222 -> 222 bytes
-rw-r--r--src/widgets/symbian/images/sizeall.png (renamed from src/gui/symbian/images/sizeall.png)bin188 -> 188 bytes
-rw-r--r--src/widgets/symbian/images/sizebdiag.png (renamed from src/gui/symbian/images/sizebdiag.png)bin192 -> 192 bytes
-rw-r--r--src/widgets/symbian/images/sizefdiag.png (renamed from src/gui/symbian/images/sizefdiag.png)bin197 -> 197 bytes
-rw-r--r--src/widgets/symbian/images/sizehor.png (renamed from src/gui/symbian/images/sizehor.png)bin175 -> 175 bytes
-rw-r--r--src/widgets/symbian/images/sizever.png (renamed from src/gui/symbian/images/sizever.png)bin171 -> 171 bytes
-rw-r--r--src/widgets/symbian/images/splith.png (renamed from src/gui/symbian/images/splith.png)bin206 -> 206 bytes
-rw-r--r--src/widgets/symbian/images/splitv.png (renamed from src/gui/symbian/images/splitv.png)bin205 -> 205 bytes
-rw-r--r--src/widgets/symbian/images/uparrow.png (renamed from src/gui/symbian/images/uparrow.png)bin157 -> 157 bytes
-rw-r--r--src/widgets/symbian/images/wait1.png (renamed from src/gui/symbian/images/wait1.png)bin219 -> 219 bytes
-rw-r--r--src/widgets/symbian/images/wait10.png (renamed from src/gui/symbian/images/wait10.png)bin220 -> 220 bytes
-rw-r--r--src/widgets/symbian/images/wait11.png (renamed from src/gui/symbian/images/wait11.png)bin220 -> 220 bytes
-rw-r--r--src/widgets/symbian/images/wait12.png (renamed from src/gui/symbian/images/wait12.png)bin213 -> 213 bytes
-rw-r--r--src/widgets/symbian/images/wait2.png (renamed from src/gui/symbian/images/wait2.png)bin219 -> 219 bytes
-rw-r--r--src/widgets/symbian/images/wait3.png (renamed from src/gui/symbian/images/wait3.png)bin210 -> 210 bytes
-rw-r--r--src/widgets/symbian/images/wait4.png (renamed from src/gui/symbian/images/wait4.png)bin215 -> 215 bytes
-rw-r--r--src/widgets/symbian/images/wait5.png (renamed from src/gui/symbian/images/wait5.png)bin217 -> 217 bytes
-rw-r--r--src/widgets/symbian/images/wait6.png (renamed from src/gui/symbian/images/wait6.png)bin213 -> 213 bytes
-rw-r--r--src/widgets/symbian/images/wait7.png (renamed from src/gui/symbian/images/wait7.png)bin215 -> 215 bytes
-rw-r--r--src/widgets/symbian/images/wait8.png (renamed from src/gui/symbian/images/wait8.png)bin217 -> 217 bytes
-rw-r--r--src/widgets/symbian/images/wait9.png (renamed from src/gui/symbian/images/wait9.png)bin209 -> 209 bytes
-rw-r--r--src/widgets/symbian/images/whatsthis.png (renamed from src/gui/symbian/images/whatsthis.png)bin254 -> 254 bytes
-rw-r--r--src/widgets/symbian/qsymbianevent.cpp (renamed from src/gui/symbian/qsymbianevent.cpp)0
-rw-r--r--src/widgets/symbian/qsymbianevent.h108
-rw-r--r--src/widgets/symbian/symbianresources.qrc (renamed from src/gui/symbian/symbianresources.qrc)0
-rw-r--r--src/widgets/to_be_moved/qshortcut.cpp (renamed from src/gui/kernel/qshortcut.cpp)0
-rw-r--r--src/widgets/to_be_moved/qshortcut.h107
-rw-r--r--src/widgets/to_be_moved/qshortcutmap.cpp897
-rw-r--r--src/widgets/to_be_moved/qshortcutmap_p.h (renamed from src/gui/kernel/qshortcutmap_p.h)0
-rw-r--r--src/widgets/to_be_moved/to_be_moved.pri7
-rw-r--r--src/widgets/util/qcolormap.h97
-rw-r--r--src/widgets/util/qcolormap.qdoc (renamed from src/gui/painting/qcolormap.qdoc)0
-rw-r--r--src/widgets/util/qcolormap_qpa.cpp228
-rw-r--r--src/widgets/util/qcompleter.cpp1833
-rw-r--r--src/widgets/util/qcompleter.h171
-rw-r--r--src/widgets/util/qcompleter_p.h264
-rw-r--r--src/widgets/util/qflickgesture.cpp717
-rw-r--r--src/widgets/util/qflickgesture_p.h113
-rw-r--r--src/widgets/util/qscroller.cpp (renamed from src/gui/util/qscroller.cpp)0
-rw-r--r--src/widgets/util/qscroller.h155
-rw-r--r--src/widgets/util/qscroller_mac.mm (renamed from src/gui/util/qscroller_mac.mm)0
-rw-r--r--src/widgets/util/qscroller_p.h (renamed from src/gui/util/qscroller_p.h)0
-rw-r--r--src/widgets/util/qscrollerproperties.cpp (renamed from src/gui/util/qscrollerproperties.cpp)0
-rw-r--r--src/widgets/util/qscrollerproperties.h140
-rw-r--r--src/widgets/util/qscrollerproperties_p.h (renamed from src/gui/util/qscrollerproperties_p.h)0
-rw-r--r--src/widgets/util/qsystemtrayicon.cpp674
-rw-r--r--src/widgets/util/qsystemtrayicon.h132
-rw-r--r--src/widgets/util/qsystemtrayicon_mac.mm (renamed from src/gui/util/qsystemtrayicon_mac.mm)0
-rw-r--r--src/widgets/util/qsystemtrayicon_p.h186
-rw-r--r--src/widgets/util/qsystemtrayicon_qpa.cpp (renamed from src/gui/util/qsystemtrayicon_qws.cpp)0
-rw-r--r--src/widgets/util/qsystemtrayicon_win.cpp (renamed from src/gui/util/qsystemtrayicon_win.cpp)0
-rw-r--r--src/widgets/util/qsystemtrayicon_wince.cpp (renamed from src/gui/util/qsystemtrayicon_wince.cpp)0
-rw-r--r--src/widgets/util/qsystemtrayicon_x11.cpp (renamed from src/gui/util/qsystemtrayicon_x11.cpp)0
-rw-r--r--src/widgets/util/qundogroup.cpp (renamed from src/gui/util/qundogroup.cpp)0
-rw-r--r--src/widgets/util/qundogroup.h110
-rw-r--r--src/widgets/util/qundostack.cpp (renamed from src/gui/util/qundostack.cpp)0
-rw-r--r--src/widgets/util/qundostack.h159
-rw-r--r--src/widgets/util/qundostack_p.h114
-rw-r--r--src/widgets/util/qundoview.cpp476
-rw-r--r--src/widgets/util/qundoview.h102
-rw-r--r--src/widgets/util/util.pri71
-rw-r--r--src/widgets/widgets.pro227
-rw-r--r--src/widgets/widgets/qabstractbutton.cpp1470
-rw-r--r--src/widgets/widgets/qabstractbutton.h180
-rw-r--r--src/widgets/widgets/qabstractbutton_p.h (renamed from src/gui/widgets/qabstractbutton_p.h)0
-rw-r--r--src/widgets/widgets/qabstractscrollarea.cpp (renamed from src/gui/widgets/qabstractscrollarea.cpp)0
-rw-r--r--src/widgets/widgets/qabstractscrollarea.h144
-rw-r--r--src/widgets/widgets/qabstractscrollarea_p.h146
-rw-r--r--src/widgets/widgets/qabstractslider.cpp (renamed from src/gui/widgets/qabstractslider.cpp)0
-rw-r--r--src/widgets/widgets/qabstractslider.h184
-rw-r--r--src/widgets/widgets/qabstractslider_p.h (renamed from src/gui/widgets/qabstractslider_p.h)0
-rw-r--r--src/widgets/widgets/qabstractspinbox.cpp (renamed from src/gui/widgets/qabstractspinbox.cpp)0
-rw-r--r--src/widgets/widgets/qabstractspinbox.h181
-rw-r--r--src/widgets/widgets/qabstractspinbox_p.h170
-rw-r--r--src/widgets/widgets/qbuttongroup.cpp (renamed from src/gui/widgets/qbuttongroup.cpp)0
-rw-r--r--src/widgets/widgets/qbuttongroup.h112
-rw-r--r--src/widgets/widgets/qcalendartextnavigator_p.h (renamed from src/gui/widgets/qcalendartextnavigator_p.h)0
-rw-r--r--src/widgets/widgets/qcalendarwidget.cpp (renamed from src/gui/widgets/qcalendarwidget.cpp)0
-rw-r--r--src/widgets/widgets/qcalendarwidget.h204
-rw-r--r--src/widgets/widgets/qcheckbox.cpp (renamed from src/gui/widgets/qcheckbox.cpp)0
-rw-r--r--src/widgets/widgets/qcheckbox.h114
-rw-r--r--src/widgets/widgets/qcocoatoolbardelegate_mac.mm (renamed from src/gui/widgets/qcocoatoolbardelegate_mac.mm)0
-rw-r--r--src/widgets/widgets/qcocoatoolbardelegate_mac_p.h (renamed from src/gui/widgets/qcocoatoolbardelegate_mac_p.h)0
-rw-r--r--src/widgets/widgets/qcombobox.cpp (renamed from src/gui/widgets/qcombobox.cpp)0
-rw-r--r--src/widgets/widgets/qcombobox.h339
-rw-r--r--src/widgets/widgets/qcombobox_p.h421
-rw-r--r--src/widgets/widgets/qcommandlinkbutton.cpp (renamed from src/gui/widgets/qcommandlinkbutton.cpp)0
-rw-r--r--src/widgets/widgets/qcommandlinkbutton.h85
-rw-r--r--src/widgets/widgets/qdatetimeedit.cpp (renamed from src/gui/widgets/qdatetimeedit.cpp)0
-rw-r--r--src/widgets/widgets/qdatetimeedit.h230
-rw-r--r--src/widgets/widgets/qdatetimeedit_p.h185
-rw-r--r--src/widgets/widgets/qdial.cpp (renamed from src/gui/widgets/qdial.cpp)0
-rw-r--r--src/widgets/widgets/qdial.h122
-rw-r--r--src/widgets/widgets/qdialogbuttonbox.cpp1285
-rw-r--r--src/widgets/widgets/qdialogbuttonbox.h168
-rw-r--r--src/widgets/widgets/qdockarealayout.cpp3329
-rw-r--r--src/widgets/widgets/qdockarealayout_p.h308
-rw-r--r--src/widgets/widgets/qdockwidget.cpp1605
-rw-r--r--src/widgets/widgets/qdockwidget.h146
-rw-r--r--src/widgets/widgets/qdockwidget_p.h207
-rw-r--r--src/widgets/widgets/qeffects.cpp (renamed from src/gui/widgets/qeffects.cpp)0
-rw-r--r--src/widgets/widgets/qeffects_p.h84
-rw-r--r--src/widgets/widgets/qfocusframe.cpp (renamed from src/gui/widgets/qfocusframe.cpp)0
-rw-r--r--src/widgets/widgets/qfocusframe.h82
-rw-r--r--src/widgets/widgets/qfontcombobox.cpp (renamed from src/gui/widgets/qfontcombobox.cpp)0
-rw-r--r--src/widgets/widgets/qfontcombobox.h112
-rw-r--r--src/widgets/widgets/qframe.cpp (renamed from src/gui/widgets/qframe.cpp)0
-rw-r--r--src/widgets/widgets/qframe.h148
-rw-r--r--src/widgets/widgets/qframe_p.h (renamed from src/gui/widgets/qframe_p.h)0
-rw-r--r--src/widgets/widgets/qgroupbox.cpp (renamed from src/gui/widgets/qgroupbox.cpp)0
-rw-r--r--src/widgets/widgets/qgroupbox.h122
-rw-r--r--src/widgets/widgets/qlabel.cpp1734
-rw-r--r--src/widgets/widgets/qlabel.h182
-rw-r--r--src/widgets/widgets/qlabel_p.h153
-rw-r--r--src/widgets/widgets/qlcdnumber.cpp (renamed from src/gui/widgets/qlcdnumber.cpp)0
-rw-r--r--src/widgets/widgets/qlcdnumber.h144
-rw-r--r--src/widgets/widgets/qlineedit.cpp2363
-rw-r--r--src/widgets/widgets/qlineedit.h300
-rw-r--r--src/widgets/widgets/qlineedit_p.cpp293
-rw-r--r--src/widgets/widgets/qlineedit_p.h155
-rw-r--r--src/widgets/widgets/qmaccocoaviewcontainer_mac.h73
-rw-r--r--src/widgets/widgets/qmaccocoaviewcontainer_mac.mm (renamed from src/gui/widgets/qmaccocoaviewcontainer_mac.mm)0
-rw-r--r--src/widgets/widgets/qmacnativewidget_mac.h74
-rw-r--r--src/widgets/widgets/qmacnativewidget_mac.mm (renamed from src/gui/widgets/qmacnativewidget_mac.mm)0
-rw-r--r--src/widgets/widgets/qmainwindow.cpp1686
-rw-r--r--src/widgets/widgets/qmainwindow.h219
-rw-r--r--src/widgets/widgets/qmainwindowlayout.cpp (renamed from src/gui/widgets/qmainwindowlayout.cpp)0
-rw-r--r--src/widgets/widgets/qmainwindowlayout_mac.mm (renamed from src/gui/widgets/qmainwindowlayout_mac.mm)0
-rw-r--r--src/widgets/widgets/qmainwindowlayout_p.h357
-rw-r--r--src/widgets/widgets/qmdiarea.cpp (renamed from src/gui/widgets/qmdiarea.cpp)0
-rw-r--r--src/widgets/widgets/qmdiarea.h179
-rw-r--r--src/widgets/widgets/qmdiarea_p.h285
-rw-r--r--src/widgets/widgets/qmdisubwindow.cpp (renamed from src/gui/widgets/qmdisubwindow.cpp)0
-rw-r--r--src/widgets/widgets/qmdisubwindow.h159
-rw-r--r--src/widgets/widgets/qmdisubwindow_p.h (renamed from src/gui/widgets/qmdisubwindow_p.h)0
-rw-r--r--src/widgets/widgets/qmenu.cpp3100
-rw-r--r--src/widgets/widgets/qmenu.h210
-rw-r--r--src/widgets/widgets/qmenu_p.h316
-rw-r--r--src/widgets/widgets/qmenu_symbian.cpp (renamed from src/gui/widgets/qmenu_symbian.cpp)0
-rw-r--r--src/widgets/widgets/qmenu_wince.cpp (renamed from src/gui/widgets/qmenu_wince.cpp)0
-rw-r--r--src/widgets/widgets/qmenu_wince.rc (renamed from src/gui/widgets/qmenu_wince.rc)0
-rw-r--r--src/widgets/widgets/qmenu_wince_resource_p.h (renamed from src/gui/widgets/qmenu_wince_resource_p.h)0
-rw-r--r--src/widgets/widgets/qmenubar.cpp2063
-rw-r--r--src/widgets/widgets/qmenubar.h177
-rw-r--r--src/widgets/widgets/qmenubar_p.h251
-rw-r--r--src/widgets/widgets/qplaintextedit.cpp2996
-rw-r--r--src/widgets/widgets/qplaintextedit.h327
-rw-r--r--src/widgets/widgets/qplaintextedit_p.h187
-rw-r--r--src/widgets/widgets/qprogressbar.cpp (renamed from src/gui/widgets/qprogressbar.cpp)0
-rw-r--r--src/widgets/widgets/qprogressbar.h132
-rw-r--r--src/widgets/widgets/qpushbutton.cpp (renamed from src/gui/widgets/qpushbutton.cpp)0
-rw-r--r--src/widgets/widgets/qpushbutton.h127
-rw-r--r--src/widgets/widgets/qpushbutton_p.h (renamed from src/gui/widgets/qpushbutton_p.h)0
-rw-r--r--src/widgets/widgets/qradiobutton.cpp (renamed from src/gui/widgets/qradiobutton.cpp)0
-rw-r--r--src/widgets/widgets/qradiobutton.h89
-rw-r--r--src/widgets/widgets/qrubberband.cpp (renamed from src/gui/widgets/qrubberband.cpp)0
-rw-r--r--src/widgets/widgets/qrubberband.h104
-rw-r--r--src/widgets/widgets/qscrollarea.cpp522
-rw-r--r--src/widgets/widgets/qscrollarea.h101
-rw-r--r--src/widgets/widgets/qscrollarea_p.h81
-rw-r--r--src/widgets/widgets/qscrollbar.cpp764
-rw-r--r--src/widgets/widgets/qscrollbar.h104
-rw-r--r--src/widgets/widgets/qsizegrip.cpp570
-rw-r--r--src/widgets/widgets/qsizegrip.h95
-rw-r--r--src/widgets/widgets/qslider.cpp666
-rw-r--r--src/widgets/widgets/qslider.h134
-rw-r--r--src/widgets/widgets/qspinbox.cpp (renamed from src/gui/widgets/qspinbox.cpp)0
-rw-r--r--src/widgets/widgets/qspinbox.h188
-rw-r--r--src/widgets/widgets/qsplashscreen.cpp (renamed from src/gui/widgets/qsplashscreen.cpp)0
-rw-r--r--src/widgets/widgets/qsplashscreen.h99
-rw-r--r--src/widgets/widgets/qsplitter.cpp (renamed from src/gui/widgets/qsplitter.cpp)0
-rw-r--r--src/widgets/widgets/qsplitter.h192
-rw-r--r--src/widgets/widgets/qsplitter_p.h (renamed from src/gui/widgets/qsplitter_p.h)0
-rw-r--r--src/widgets/widgets/qstackedwidget.cpp (renamed from src/gui/widgets/qstackedwidget.cpp)0
-rw-r--r--src/widgets/widgets/qstackedwidget.h100
-rw-r--r--src/widgets/widgets/qstatusbar.cpp (renamed from src/gui/widgets/qstatusbar.cpp)0
-rw-r--r--src/widgets/widgets/qstatusbar.h116
-rw-r--r--src/widgets/widgets/qtabbar.cpp (renamed from src/gui/widgets/qtabbar.cpp)0
-rw-r--r--src/widgets/widgets/qtabbar.h226
-rw-r--r--src/widgets/widgets/qtabbar_p.h (renamed from src/gui/widgets/qtabbar_p.h)0
-rw-r--r--src/widgets/widgets/qtabwidget.cpp (renamed from src/gui/widgets/qtabwidget.cpp)0
-rw-r--r--src/widgets/widgets/qtabwidget.h254
-rw-r--r--src/widgets/widgets/qtextbrowser.cpp (renamed from src/gui/widgets/qtextbrowser.cpp)0
-rw-r--r--src/widgets/widgets/qtextbrowser.h140
-rw-r--r--src/widgets/widgets/qtextedit.cpp2809
-rw-r--r--src/widgets/widgets/qtextedit.h430
-rw-r--r--src/widgets/widgets/qtextedit_p.h141
-rw-r--r--src/widgets/widgets/qtoolbar.cpp1349
-rw-r--r--src/widgets/widgets/qtoolbar.h188
-rw-r--r--src/widgets/widgets/qtoolbar_p.h135
-rw-r--r--src/widgets/widgets/qtoolbararealayout.cpp (renamed from src/gui/widgets/qtoolbararealayout.cpp)0
-rw-r--r--src/widgets/widgets/qtoolbararealayout_p.h (renamed from src/gui/widgets/qtoolbararealayout_p.h)0
-rw-r--r--src/widgets/widgets/qtoolbarextension.cpp (renamed from src/gui/widgets/qtoolbarextension.cpp)0
-rw-r--r--src/widgets/widgets/qtoolbarextension_p.h80
-rw-r--r--src/widgets/widgets/qtoolbarlayout.cpp (renamed from src/gui/widgets/qtoolbarlayout.cpp)0
-rw-r--r--src/widgets/widgets/qtoolbarlayout_p.h134
-rw-r--r--src/widgets/widgets/qtoolbarseparator.cpp (renamed from src/gui/widgets/qtoolbarseparator.cpp)0
-rw-r--r--src/widgets/widgets/qtoolbarseparator_p.h88
-rw-r--r--src/widgets/widgets/qtoolbox.cpp (renamed from src/gui/widgets/qtoolbox.cpp)0
-rw-r--r--src/widgets/widgets/qtoolbox.h148
-rw-r--r--src/widgets/widgets/qtoolbutton.cpp (renamed from src/gui/widgets/qtoolbutton.cpp)0
-rw-r--r--src/widgets/widgets/qtoolbutton.h199
-rw-r--r--src/widgets/widgets/qwidgetanimator.cpp117
-rw-r--r--src/widgets/widgets/qwidgetanimator_p.h (renamed from src/gui/widgets/qwidgetanimator_p.h)0
-rw-r--r--src/widgets/widgets/qwidgetlinecontrol.cpp1862
-rw-r--r--src/widgets/widgets/qwidgetlinecontrol_p.h499
-rw-r--r--src/widgets/widgets/qwidgetresizehandler.cpp (renamed from src/gui/widgets/qwidgetresizehandler.cpp)0
-rw-r--r--src/widgets/widgets/qwidgetresizehandler_p.h141
-rw-r--r--src/widgets/widgets/qwidgettextcontrol.cpp3148
-rw-r--r--src/widgets/widgets/qwidgettextcontrol_p.h305
-rw-r--r--src/widgets/widgets/qwidgettextcontrol_p_p.h238
-rw-r--r--src/widgets/widgets/qworkspace.cpp (renamed from src/gui/widgets/qworkspace.cpp)0
-rw-r--r--src/widgets/widgets/qworkspace.h137
-rw-r--r--src/widgets/widgets/widgets.pri165
2480 files changed, 342208 insertions, 411711 deletions
diff --git a/src/3rdparty/v8 b/src/3rdparty/v8
-Subproject 523f03f03b1ac16d272a13389f8a5654d9ff12e
+Subproject dc2cad4f8fc88c52fcea09b8d0262d35cd32dc4
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index 1552f67695..1cfd70112f 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -289,7 +289,7 @@ namespace QT_NAMESPACE {}
#endif
#if defined(Q_OS_DARWIN)
-# define Q_OS_MAC /* Q_OS_MAC is mostly for compatibility, but also more clear */
+# define Q_OS_MAC
# define Q_OS_MACX /* Q_OS_MACX is only for compatibility.*/
# if defined(Q_OS_DARWIN64)
# define Q_OS_MAC64
@@ -298,12 +298,6 @@ namespace QT_NAMESPACE {}
# endif
#endif
-#ifdef QT_AUTODETECT_COCOA
-# ifdef Q_OS_MAC64
-# define QT_MAC_USE_COCOA 1
-# endif
-#endif
-
#if defined(Q_WS_MAC64) && !defined(QT_MAC_USE_COCOA) && !defined(QT_BUILD_QMAKE) && !defined(QT_BOOTSTRAPPED)
#error "You are building a 64-bit application, but using a 32-bit version of Qt. Check your build configuration."
#endif
@@ -877,7 +871,9 @@ namespace QT_NAMESPACE {}
WIN16 - unsupported
*/
-#if defined(Q_OS_MSDOS)
+#if defined (Q_WS_QPA)
+
+#elif defined(Q_OS_MSDOS)
# define Q_WS_WIN16
# error "Qt requires Win32 and does not work with Windows 3.x"
#elif defined(_WIN32_X11_)
@@ -897,15 +893,7 @@ namespace QT_NAMESPACE {}
# define Q_WS_PM
# error "Qt does not work with OS/2 Presentation Manager or Workplace Shell"
#elif defined(Q_OS_UNIX)
-# if defined(Q_OS_MAC) && !defined(__USE_WS_X11__) && !defined(Q_WS_QWS) && !defined(Q_WS_QPA)
-# define Q_WS_MAC
-# define Q_WS_MACX
-# if defined(Q_OS_MAC64)
-# define Q_WS_MAC64
-# elif defined(Q_OS_MAC32)
-# define Q_WS_MAC32
-# endif
-# elif defined(Q_OS_SYMBIAN)
+# if defined(Q_OS_SYMBIAN)
# if !defined(QT_NO_S60)
# define Q_WS_S60
# endif
@@ -1143,7 +1131,7 @@ redefine to built-in booleans to make autotests work properly */
//defines the type for the WNDPROC on windows
//the alignment needs to be forced for sse2 to not crash with mingw
-#if defined(Q_WS_WIN)
+#if defined(Q_OS_WIN)
# if defined(Q_CC_MINGW)
# define QT_ENSURE_STACK_ALIGNED_FOR_SSE __attribute__ ((force_align_arg_pointer))
# else
@@ -1268,6 +1256,16 @@ class QDataStream;
# else
# define Q_GUI_EXPORT Q_DECL_IMPORT
# endif
+# if defined(QT_BUILD_WIDGETS_LIB)
+# define Q_WIDGETS_EXPORT Q_DECL_EXPORT
+# else
+# define Q_WIDGETS_EXPORT Q_DECL_IMPORT
+# endif
+# if defined(QT_BUILD_PRINTSUPPORT_LIB)
+# define Q_PRINTSUPPORT_EXPORT Q_DECL_EXPORT
+# else
+# define Q_PRINTSUPPORT_EXPORT Q_DECL_IMPORT
+# endif
# if defined(QT_BUILD_SQL_LIB)
# define Q_SQL_EXPORT Q_DECL_EXPORT
# else
@@ -1283,6 +1281,11 @@ class QDataStream;
# else
# define Q_SVG_EXPORT Q_DECL_IMPORT
# endif
+# if defined(QT_BUILD_QTQUICK1_LIB)
+# define Q_QTQUICK1_EXPORT Q_DECL_EXPORT
+# else
+# define Q_QTQUICK1_EXPORT Q_DECL_IMPORT
+# endif
# if defined(QT_BUILD_DECLARATIVE_LIB)
# define Q_DECLARATIVE_EXPORT Q_DECL_EXPORT
# else
@@ -1352,10 +1355,13 @@ class QDataStream;
# elif defined(QT_DLL) /* use a Qt DLL library */
# define Q_CORE_EXPORT Q_DECL_IMPORT
# define Q_GUI_EXPORT Q_DECL_IMPORT
+# define Q_WIDGETS_EXPORT Q_DECL_IMPORT
+# define Q_PRINTSUPPORT_EXPORT Q_DECL_IMPORT
# define Q_SQL_EXPORT Q_DECL_IMPORT
# define Q_NETWORK_EXPORT Q_DECL_IMPORT
# define Q_SVG_EXPORT Q_DECL_IMPORT
# define Q_DECLARATIVE_EXPORT Q_DECL_IMPORT
+# define Q_QTQUICK1_EXPORT Q_DECL_IMPORT
# define Q_CANVAS_EXPORT Q_DECL_IMPORT
# define Q_OPENGL_EXPORT Q_DECL_IMPORT
# define Q_MULTIMEDIA_EXPORT Q_DECL_IMPORT
@@ -1384,10 +1390,13 @@ class QDataStream;
# if defined(QT_SHARED)
# define Q_CORE_EXPORT Q_DECL_EXPORT
# define Q_GUI_EXPORT Q_DECL_EXPORT
+# define Q_WIDGETS_EXPORT Q_DECL_EXPORT
+# define Q_PRINTSUPPORT_EXPORT Q_DECL_EXPORT
# define Q_SQL_EXPORT Q_DECL_EXPORT
# define Q_NETWORK_EXPORT Q_DECL_EXPORT
# define Q_SVG_EXPORT Q_DECL_EXPORT
# define Q_DECLARATIVE_EXPORT Q_DECL_EXPORT
+# define Q_QTQUICK1_EXPORT Q_DECL_EXPORT
# define Q_OPENGL_EXPORT Q_DECL_EXPORT
# define Q_MULTIMEDIA_EXPORT Q_DECL_EXPORT
# define Q_OPENVG_EXPORT Q_DECL_EXPORT
@@ -1402,10 +1411,13 @@ class QDataStream;
# else
# define Q_CORE_EXPORT
# define Q_GUI_EXPORT
+# define Q_WIDGETS_EXPORT
+# define Q_PRINTSUPPORT_EXPORT
# define Q_SQL_EXPORT
# define Q_NETWORK_EXPORT
# define Q_SVG_EXPORT
# define Q_DECLARATIVE_EXPORT
+# define Q_QTQUICK1_EXPORT
# define Q_OPENGL_EXPORT
# define Q_MULTIMEDIA_EXPORT
# define Q_OPENVG_EXPORT
@@ -1433,6 +1445,16 @@ class QDataStream;
# else
# define Q_GUI_EXPORT_INLINE inline
# endif
+# if defined(QT_BUILD_WIDGETS_LIB)
+# define Q_WIDGETS_EXPORT_INLINE Q_WIDGETS_EXPORT inline
+# else
+# define Q_WIDGETS_EXPORT_INLINE inline
+# endif
+# if defined(QT_BUILD_PRINTSUPPORT_LIB)
+# define Q_PRINTSUPPORT_EXPORT_INLINE Q_PRINTSUPPORT_EXPORT inline
+# else
+# define Q_PRINTSUPPORT_EXPORT_INLINE inline
+# endif
# if defined(QT_BUILD_COMPAT_LIB)
# define Q_COMPAT_EXPORT_INLINE Q_COMPAT_EXPORT inline
# else
@@ -1444,10 +1466,14 @@ class QDataStream;
// note: this affects the contents of the DEF files (ie. these functions do not appear)
# define Q_CORE_EXPORT_INLINE inline
# define Q_GUI_EXPORT_INLINE inline
+# define Q_WIDGETS_EXPORT_INLINE inline
+# define Q_PRINTSUPPORT_EXPORT_INLINE inline
# define Q_COMPAT_EXPORT_INLINE inline
#else
# define Q_CORE_EXPORT_INLINE Q_CORE_EXPORT inline
# define Q_GUI_EXPORT_INLINE Q_GUI_EXPORT inline
+# define Q_WIDGETS_EXPORT_INLINE Q_WIDGETS_EXPORT inline
+# define Q_PRINTSUPPORT_EXPORT_INLINE Q_PRINTSUPPORT_EXPORT inline
# define Q_COMPAT_EXPORT_INLINE Q_COMPAT_EXPORT inline
#endif
@@ -1531,7 +1557,7 @@ public:
#else
# error "Qt not configured correctly, please run configure"
#endif
-#if defined(Q_WS_WIN) || defined(Q_OS_CYGWIN)
+#if defined(Q_OS_WIN) || defined(Q_OS_CYGWIN)
enum WinVersion {
WV_32s = 0x0001,
WV_95 = 0x0002,
@@ -2017,6 +2043,7 @@ static inline bool qIsNull(float f)
return false; \
}
#else
+
# define Q_DUMMY_COMPARISON_OPERATOR(C)
#endif
diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h
index 9253b19e60..a4b9cf1777 100644
--- a/src/corelib/global/qnamespace.h
+++ b/src/corelib/global/qnamespace.h
@@ -237,13 +237,13 @@ public:
Window = 0x00000001,
Dialog = 0x00000002 | Window,
Sheet = 0x00000004 | Window,
- Drawer = 0x00000006 | Window,
+ Drawer = Sheet | Dialog,
Popup = 0x00000008 | Window,
- Tool = 0x0000000a | Window,
- ToolTip = 0x0000000c | Window,
- SplashScreen = 0x0000000e | Window,
+ Tool = Popup | Dialog,
+ ToolTip = Popup | Sheet,
+ SplashScreen = ToolTip | Dialog,
Desktop = 0x00000010 | Window,
- SubWindow = 0x00000012,
+ SubWindow = 0x00000012,
WindowType_Mask = 0x000000ff,
MSWindowsFixedSizeDialogHint = 0x00000100,
@@ -258,13 +258,7 @@ public:
WindowContextHelpButtonHint = 0x00010000,
WindowShadeButtonHint = 0x00020000,
WindowStaysOnTopHint = 0x00040000,
- // reserved for Qt3Support:
- // WMouseNoMask = 0x00080000,
- // WDestructiveClose = 0x00100000,
- // WStaticContents = 0x00200000,
- // WGroupLeader = 0x00400000,
- // WShowModal = 0x00800000,
- // WNoMousePropagation = 0x01000000,
+
CustomizeWindowHint = 0x02000000,
WindowStaysOnBottomHint = 0x04000000,
WindowCloseButtonHint = 0x08000000,
@@ -1240,23 +1234,37 @@ public:
};
enum InputMethodQuery {
- ImMicroFocus,
- ImFont,
- ImCursorPosition,
- ImSurroundingText,
- ImCurrentSelection,
- ImMaximumTextLength,
- ImAnchorPosition
- };
+ ImEnabled = 0x1,
+ ImCursorRectangle = 0x2,
+ ImMicroFocus = 0x2, // deprecated
+ ImFont = 0x4,
+ ImCursorPosition = 0x8,
+ ImSurroundingText = 0x10,
+ ImCurrentSelection = 0x20,
+ ImMaximumTextLength = 0x40,
+ ImAnchorPosition = 0x80,
+ ImHints = 0x100,
+ ImPreferredLanguage = 0x200,
+
+ ImPlatformData = 0x80000000,
+ ImQueryAll = 0xffffffff
+ };
+ Q_DECLARE_FLAGS(InputMethodQueries, InputMethodQuery)
enum InputMethodHint {
ImhNone = 0x0,
+
ImhHiddenText = 0x1,
- ImhNoAutoUppercase = 0x2,
- ImhPreferNumbers = 0x4,
- ImhPreferUppercase = 0x8,
- ImhPreferLowercase = 0x10,
- ImhNoPredictiveText = 0x20,
+ ImhSensitiveData = 0x2,
+ ImhNoAutoUppercase = 0x4,
+ ImhPreferNumbers = 0x8,
+ ImhPreferUppercase = 0x10,
+ ImhPreferLowercase = 0x20,
+ ImhNoPredictiveText = 0x40,
+
+ ImhDate = 0x80,
+ ImhTime = 0x100,
+ ImhMultiLine = 0x200,
ImhDigitsOnly = 0x10000,
ImhFormattedNumbersOnly = 0x20000,
diff --git a/src/corelib/global/qt_pch.h b/src/corelib/global/qt_pch.h
index 738026a9ed..0926e02af1 100644
--- a/src/corelib/global/qt_pch.h
+++ b/src/corelib/global/qt_pch.h
@@ -50,7 +50,7 @@
#if defined __cplusplus
#include <qglobal.h>
-#ifdef Q_WS_WIN
+#ifdef Q_OS_WIN
# define _POSIX_
# include <limits.h>
# undef _POSIX_
diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp
index 41278f1b91..9faa9f17b3 100644
--- a/src/corelib/io/qdir.cpp
+++ b/src/corelib/io/qdir.cpp
@@ -1730,7 +1730,7 @@ QFileInfoList QDir::drives()
*/
QChar QDir::separator()
{
-#if defined (Q_FS_FAT) || defined(Q_WS_WIN) || defined(Q_OS_SYMBIAN)
+#if defined (Q_FS_FAT) || defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
return QLatin1Char('\\');
#elif defined(Q_OS_UNIX)
return QLatin1Char('/');
diff --git a/src/corelib/io/qfsfileengine_p.h b/src/corelib/io/qfsfileengine_p.h
index 79dda1b70a..89c08aeca7 100644
--- a/src/corelib/io/qfsfileengine_p.h
+++ b/src/corelib/io/qfsfileengine_p.h
@@ -77,7 +77,7 @@ class Q_AUTOTEST_EXPORT QFSFileEnginePrivate : public QAbstractFileEnginePrivate
Q_DECLARE_PUBLIC(QFSFileEngine)
public:
-#ifdef Q_WS_WIN
+#ifdef Q_OS_WIN
static QString longFileName(const QString &path);
#endif
@@ -143,7 +143,7 @@ public:
int getMapHandle();
#endif
-#ifdef Q_WS_WIN
+#ifdef Q_OS_WIN
HANDLE fileHandle;
HANDLE mapHandle;
QHash<uchar *, DWORD /* offset % AllocationGranularity */> maps;
diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp
index af43ab7320..ddbbbd5286 100644
--- a/src/corelib/io/qprocess.cpp
+++ b/src/corelib/io/qprocess.cpp
@@ -93,7 +93,7 @@ QT_END_NAMESPACE
#include <qsocketnotifier.h>
#include <qtimer.h>
-#ifdef Q_WS_WIN
+#ifdef Q_OS_WIN
#include <private/qwineventnotifier_p.h>
#endif
@@ -764,10 +764,10 @@ QProcessPrivate::QProcessPrivate()
dying = false;
emittedReadyRead = false;
emittedBytesWritten = false;
-#ifdef Q_WS_WIN
+#ifdef Q_OS_WIN
pipeWriter = 0;
processFinishedNotifier = 0;
-#endif // Q_WS_WIN
+#endif // Q_OS_WIN
#ifdef Q_OS_UNIX
serial = 0;
#endif
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index 6d8bf20b7c..d716c7b0f6 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -171,7 +171,7 @@ CApaCommandLine* QCoreApplicationPrivate::symbianCommandLine()
#endif
-#if defined(Q_WS_WIN) || defined(Q_WS_MAC)
+#if defined(Q_OS_WIN) || defined(Q_WS_MAC)
extern QString qAppFileName();
#endif
@@ -319,7 +319,7 @@ Q_GLOBAL_STATIC(QCoreApplicationData, coreappdata)
QCoreApplicationPrivate::QCoreApplicationPrivate(int &aargc, char **aargv, uint flags)
: QObjectPrivate(), argc(aargc), argv(aargv), application_type(0), eventFilter(0),
- in_exec(false), aboutToQuitEmitted(false)
+ in_exec(false), aboutToQuitEmitted(false), threadData_clean(false)
{
app_compile_version = flags & 0xffffff;
static const char *const empty = "";
@@ -344,7 +344,12 @@ QCoreApplicationPrivate::QCoreApplicationPrivate(int &aargc, char **aargv, uint
QCoreApplicationPrivate::~QCoreApplicationPrivate()
{
- if (threadData) {
+ cleanupThreadData();
+}
+
+void QCoreApplicationPrivate::cleanupThreadData()
+{
+ if (threadData && !threadData_clean) {
#ifndef QT_NO_THREAD
void *data = &threadData->tls;
QThreadStorageData::finish((void **)data);
@@ -363,6 +368,7 @@ QCoreApplicationPrivate::~QCoreApplicationPrivate()
threadData->postEventList.clear();
threadData->postEventList.recursion = 0;
threadData->quitNow = false;
+ threadData_clean = true;
}
}
@@ -578,23 +584,6 @@ void QCoreApplication::flush()
\a argc must be greater than zero and \a argv must contain at least
one valid character string.
*/
-QCoreApplication::QCoreApplication(int &argc, char **argv)
- : QObject(*new QCoreApplicationPrivate(argc, argv, 0x040000))
-{
- init();
- QCoreApplicationPrivate::eventDispatcher->startingUp();
-#if defined(Q_OS_SYMBIAN) && !defined(QT_NO_LIBRARY)
- // Refresh factoryloader, as text codecs are requested during lib path
- // resolving process and won't be therefore properly loaded.
- // Unknown if this is symbian specific issue.
- QFactoryLoader::refreshAll();
-#endif
-
-#if defined(Q_OS_SYMBIAN) && !defined(QT_NO_SYSTEMLOCALE)
- d_func()->symbianInit();
-#endif
-}
-
QCoreApplication::QCoreApplication(int &argc, char **argv, int _internal)
: QObject(*new QCoreApplicationPrivate(argc, argv, _internal))
{
@@ -754,20 +743,6 @@ void QCoreApplication::setAttribute(Qt::ApplicationAttribute attribute, bool on)
QCoreApplicationPrivate::attribs |= 1 << attribute;
else
QCoreApplicationPrivate::attribs &= ~(1 << attribute);
-#ifdef Q_OS_MAC
- // Turn on the no native menubar here, since we used to
- // do this implicitly. We DO NOT flip it off if someone sets
- // it to false.
- // Ideally, we'd have magic that would be something along the lines of
- // "follow MacPluginApplication" unless explicitly set.
- // Considering this attribute isn't only at the beginning
- // it's unlikely it will ever be a problem, but I want
- // to have the behavior documented here.
- if (attribute == Qt::AA_MacPluginApplication && on
- && !testAttribute(Qt::AA_DontUseNativeMenuBar)) {
- setAttribute(Qt::AA_DontUseNativeMenuBar, true);
- }
-#endif
}
/*!
@@ -1274,7 +1249,7 @@ void QCoreApplication::postEvent(QObject *receiver, QEvent *event, int priority)
*/
bool QCoreApplication::compressEvent(QEvent *event, QObject *receiver, QPostEventList *postedEvents)
{
-#ifdef Q_WS_WIN
+#ifdef Q_OS_WIN
Q_ASSERT(event);
Q_ASSERT(receiver);
Q_ASSERT(postedEvents);
@@ -1965,7 +1940,7 @@ QString QCoreApplication::applicationFilePath()
if (!d->cachedApplicationFilePath.isNull())
return d->cachedApplicationFilePath;
-#if defined(Q_WS_WIN)
+#if defined(Q_OS_WIN)
d->cachedApplicationFilePath = QFileInfo(qAppFileName()).filePath();
return d->cachedApplicationFilePath;
#elif defined(Q_WS_MAC)
@@ -2160,7 +2135,6 @@ QStringList QCoreApplication::arguments()
;
else if (l1arg == "-style" ||
l1arg == "-session" ||
- l1arg == "-graphicssystem" ||
l1arg == "-testability")
++a;
else
diff --git a/src/corelib/kernel/qcoreapplication.h b/src/corelib/kernel/qcoreapplication.h
index adc70387cc..04d538d1b3 100644
--- a/src/corelib/kernel/qcoreapplication.h
+++ b/src/corelib/kernel/qcoreapplication.h
@@ -46,7 +46,7 @@
#include <QtCore/qcoreevent.h>
#include <QtCore/qeventloop.h>
-#if defined(Q_WS_WIN) && !defined(tagMSG)
+#if defined(Q_OS_WIN) && !defined(tagMSG)
typedef struct tagMSG MSG;
#endif
@@ -77,16 +77,7 @@ public:
enum { ApplicationFlags = QT_VERSION
};
-#if defined(QT_BUILD_CORE_LIB) || defined(qdoc)
- QCoreApplication(int &argc, char **argv); // ### Qt5 remove
-#endif
-#if !defined(qdoc)
- QCoreApplication(int &argc, char **argv, int
-#if !defined(QT_BUILD_CORE_LIB)
- = ApplicationFlags
-#endif
- );
-#endif
+ QCoreApplication(int &argc, char **argv, int = ApplicationFlags);
~QCoreApplication();
@@ -157,7 +148,7 @@ public:
static void flush();
-#if defined(Q_WS_WIN)
+#if defined(Q_OS_WIN)
virtual bool winEventFilter(MSG *message, long *result);
#endif
@@ -198,11 +189,15 @@ private:
friend class QEventDispatcherUNIXPrivate;
friend class QApplication;
friend class QApplicationPrivate;
+ friend class QGuiApplication;
+ friend class QGuiApplicationPrivate;
friend class QETWidget;
friend class Q3AccelManager;
friend class QShortcutMap;
friend class QWidget;
+ friend class QWidgetWindow;
friend class QWidgetPrivate;
+ friend class QCocoaEventDispatcherPrivate;
friend bool qt_sendSpontaneousEvent(QObject*, QEvent*);
friend Q_CORE_EXPORT QString qAppName();
friend class QClassFactory;
@@ -266,7 +261,7 @@ Q_CORE_EXPORT void qAddPostRoutine(QtCleanUpFunction);
Q_CORE_EXPORT void qRemovePostRoutine(QtCleanUpFunction);
Q_CORE_EXPORT QString qAppName(); // get application name
-#if defined(Q_WS_WIN) && !defined(QT_NO_DEBUG_STREAM)
+#if defined(Q_OS_WIN) && !defined(QT_NO_DEBUG_STREAM)
Q_CORE_EXPORT QString decodeMSG(const MSG &);
Q_CORE_EXPORT QDebug operator<<(QDebug, const MSG &);
#endif
diff --git a/src/corelib/kernel/qcoreapplication_p.h b/src/corelib/kernel/qcoreapplication_p.h
index 8dff4ed80c..0914b24a16 100644
--- a/src/corelib/kernel/qcoreapplication_p.h
+++ b/src/corelib/kernel/qcoreapplication_p.h
@@ -110,6 +110,7 @@ public:
int &argc;
char **argv;
void appendApplicationPathToLibraryPaths(void);
+ void cleanupThreadData();
#ifndef QT_NO_TRANSLATION
QTranslatorList translators;
@@ -120,6 +121,7 @@ public:
bool in_exec;
bool aboutToQuitEmitted;
+ bool threadData_clean;
QString cachedApplicationDirPath;
QString cachedApplicationFilePath;
#if defined(Q_OS_SYMBIAN)
diff --git a/src/corelib/kernel/qcoreapplication_win.cpp b/src/corelib/kernel/qcoreapplication_win.cpp
index 6a77a74861..cb6d39a481 100644
--- a/src/corelib/kernel/qcoreapplication_win.cpp
+++ b/src/corelib/kernel/qcoreapplication_win.cpp
@@ -240,7 +240,7 @@ void QCoreApplicationPrivate::removePostedTimerEvent(QObject *object, int timerI
}
}
-#if defined(Q_WS_WIN) && !defined(QT_NO_DEBUG_STREAM)
+#if defined(Q_OS_WIN) && !defined(QT_NO_DEBUG_STREAM)
/*****************************************************************************
Convenience functions for convert WM_* messages into human readable strings,
including a nifty QDebug operator<< for simpel QDebug() << msg output.
diff --git a/src/corelib/kernel/qcoreevent.cpp b/src/corelib/kernel/qcoreevent.cpp
index 20376b9fa4..213f0e4a58 100644
--- a/src/corelib/kernel/qcoreevent.cpp
+++ b/src/corelib/kernel/qcoreevent.cpp
@@ -126,6 +126,7 @@ QT_BEGIN_NAMESPACE
\value Enter Mouse enters widget's boundaries.
\value EnterEditFocus An editor widget gains focus for editing.
\value EnterWhatsThisMode Send to toplevel widgets when the application enters "What's This?" mode.
+ \value Expose Sent to a window when its on-screen contents are invalidated and need to be flushed from the backing store.
\value FileOpen File open request (QFileOpenEvent).
\value FocusIn Widget gains keyboard focus (QFocusEvent).
\value FocusOut Widget loses keyboard focus (QFocusEvent).
diff --git a/src/corelib/kernel/qcoreevent.h b/src/corelib/kernel/qcoreevent.h
index 01a5356f73..831a403975 100644
--- a/src/corelib/kernel/qcoreevent.h
+++ b/src/corelib/kernel/qcoreevent.h
@@ -273,7 +273,13 @@ public:
ScrollPrepare = 204,
Scroll = 205,
- OrientationChange = 206, // Screen orientation has changed
+ Map = 206,
+ Unmap = 207,
+
+ Expose = 208,
+
+ InputMethodQuery = 209,
+ OrientationChange = 210, // Screen orientation has changed
// 512 reserved for Qt Jambi's MetaCall event
// 513 reserved for Qt Jambi's DeleteOnMainThread event
diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp
index 84663fa5ea..fc66e9bfd6 100644
--- a/src/corelib/kernel/qeventdispatcher_win.cpp
+++ b/src/corelib/kernel/qeventdispatcher_win.cpp
@@ -50,7 +50,6 @@
#include "qvarlengtharray.h"
#include "qwineventnotifier_p.h"
-#include "qabstracteventdispatcher_p.h"
#include "qcoreapplication_p.h"
#include <private/qthread_p.h>
#include <private/qmutexpool_p.h>
@@ -280,33 +279,7 @@ int WSAAsyncSelect(SOCKET, HWND, unsigned int, long)
class QEventDispatcherWin32Private;
-struct QSockNot {
- QSocketNotifier *obj;
- int fd;
-};
-typedef QHash<int, QSockNot *> QSNDict;
-
-struct WinTimerInfo { // internal timer info
- QObject *dispatcher;
- int timerId;
- int interval;
- QObject *obj; // - object to receive events
- bool inTimerEvent;
- int fastTimerId;
-};
-
-class QZeroTimerEvent : public QTimerEvent
-{
-public:
- inline QZeroTimerEvent(int timerId)
- : QTimerEvent(timerId)
- { t = QEvent::ZeroTimerEvent; }
-};
-
-typedef QList<WinTimerInfo*> WinTimerVec; // vector of TimerInfo structs
-typedef QHash<int, WinTimerInfo*> WinTimerDict; // fast dict of timers
-
-#if !defined(DWORD_PTR) && !defined(Q_WS_WIN64)
+#if !defined(DWORD_PTR) && !defined(Q_OS_WIN64)
#define DWORD_PTR DWORD
#endif
@@ -338,47 +311,6 @@ static void resolveTimerAPI()
}
}
-
-class QEventDispatcherWin32Private : public QAbstractEventDispatcherPrivate
-{
- Q_DECLARE_PUBLIC(QEventDispatcherWin32)
-public:
- QEventDispatcherWin32Private();
- ~QEventDispatcherWin32Private();
-
- DWORD threadId;
-
- bool interrupt;
-
- // internal window handle used for socketnotifiers/timers/etc
- HWND internalHwnd;
- HHOOK getMessageHook;
-
- // for controlling when to send posted events
- QAtomicInt serialNumber;
- int lastSerialNumber, sendPostedEventsWindowsTimerId;
- QAtomicInt wakeUps;
-
- // timers
- WinTimerVec timerVec;
- WinTimerDict timerDict;
- void registerTimer(WinTimerInfo *t);
- void unregisterTimer(WinTimerInfo *t, bool closingDown = false);
- void sendTimerEvent(int timerId);
-
- // socket notifiers
- QSNDict sn_read;
- QSNDict sn_write;
- QSNDict sn_except;
- void doWsaAsyncSelect(int socket);
-
- QList<QWinEventNotifier *> winEventNotifierList;
- void activateEventNotifier(QWinEventNotifier * wen);
-
- QList<MSG> queuedUserInputEvents;
- QList<MSG> queuedSocketEvents;
-};
-
QEventDispatcherWin32Private::QEventDispatcherWin32Private()
: threadId(GetCurrentThreadId()), interrupt(false), internalHwnd(0), getMessageHook(0),
serialNumber(0), lastSerialNumber(0), sendPostedEventsWindowsTimerId(0), wakeUps(0)
@@ -703,6 +635,10 @@ QEventDispatcherWin32::QEventDispatcherWin32(QObject *parent)
{
}
+QEventDispatcherWin32::QEventDispatcherWin32(QEventDispatcherWin32Private &dd, QObject *parent)
+ : QAbstractEventDispatcher(dd, parent)
+{ }
+
QEventDispatcherWin32::~QEventDispatcherWin32()
{
}
diff --git a/src/corelib/kernel/qeventdispatcher_win_p.h b/src/corelib/kernel/qeventdispatcher_win_p.h
index 8fa77fdc4e..4a7aac0c04 100644
--- a/src/corelib/kernel/qeventdispatcher_win_p.h
+++ b/src/corelib/kernel/qeventdispatcher_win_p.h
@@ -56,6 +56,8 @@
#include "QtCore/qabstracteventdispatcher.h"
#include "QtCore/qt_windows.h"
+#include "qabstracteventdispatcher_p.h"
+
QT_BEGIN_NAMESPACE
class QWinEventNotifier;
@@ -100,11 +102,80 @@ public:
bool event(QEvent *e);
+protected:
+ QEventDispatcherWin32(QEventDispatcherWin32Private &dd, QObject *parent = 0);
+
private:
friend LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp);
friend LRESULT QT_WIN_CALLBACK qt_GetMessageHook(int, WPARAM, LPARAM);
};
+struct QSockNot {
+ QSocketNotifier *obj;
+ int fd;
+};
+typedef QHash<int, QSockNot *> QSNDict;
+
+struct WinTimerInfo { // internal timer info
+ QObject *dispatcher;
+ int timerId;
+ int interval;
+ QObject *obj; // - object to receive events
+ bool inTimerEvent;
+ int fastTimerId;
+};
+
+class QZeroTimerEvent : public QTimerEvent
+{
+public:
+ inline QZeroTimerEvent(int timerId)
+ : QTimerEvent(timerId)
+ { t = QEvent::ZeroTimerEvent; }
+};
+
+typedef QList<WinTimerInfo*> WinTimerVec; // vector of TimerInfo structs
+typedef QHash<int, WinTimerInfo*> WinTimerDict; // fast dict of timers
+
+class Q_CORE_EXPORT QEventDispatcherWin32Private : public QAbstractEventDispatcherPrivate
+{
+ Q_DECLARE_PUBLIC(QEventDispatcherWin32)
+public:
+ QEventDispatcherWin32Private();
+ ~QEventDispatcherWin32Private();
+
+ DWORD threadId;
+
+ bool interrupt;
+
+ // internal window handle used for socketnotifiers/timers/etc
+ HWND internalHwnd;
+ HHOOK getMessageHook;
+
+ // for controlling when to send posted events
+ QAtomicInt serialNumber;
+ int lastSerialNumber, sendPostedEventsWindowsTimerId;
+ QAtomicInt wakeUps;
+
+ // timers
+ WinTimerVec timerVec;
+ WinTimerDict timerDict;
+ void registerTimer(WinTimerInfo *t);
+ void unregisterTimer(WinTimerInfo *t, bool closingDown = false);
+ void sendTimerEvent(int timerId);
+
+ // socket notifiers
+ QSNDict sn_read;
+ QSNDict sn_write;
+ QSNDict sn_except;
+ void doWsaAsyncSelect(int socket);
+
+ QList<QWinEventNotifier *> winEventNotifierList;
+ void activateEventNotifier(QWinEventNotifier * wen);
+
+ QList<MSG> queuedUserInputEvents;
+ QList<MSG> queuedSocketEvents;
+};
+
QT_END_NAMESPACE
#endif // QEVENTDISPATCHER_WIN_P_H
diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp
index f241903cb9..c97f9d260e 100644
--- a/src/corelib/kernel/qmetatype.cpp
+++ b/src/corelib/kernel/qmetatype.cpp
@@ -265,19 +265,16 @@ static const struct { const char * typeName; int typeNameLength; int type; } typ
QT_ADD_STATIC_METATYPE("QEasingCurve", QMetaType::QEasingCurve),
/* All GUI types */
- QT_ADD_STATIC_METATYPE("QColorGroup", 63),
QT_ADD_STATIC_METATYPE("QFont", QMetaType::QFont),
QT_ADD_STATIC_METATYPE("QPixmap", QMetaType::QPixmap),
QT_ADD_STATIC_METATYPE("QBrush", QMetaType::QBrush),
QT_ADD_STATIC_METATYPE("QColor", QMetaType::QColor),
QT_ADD_STATIC_METATYPE("QPalette", QMetaType::QPalette),
- QT_ADD_STATIC_METATYPE("QIcon", QMetaType::QIcon),
QT_ADD_STATIC_METATYPE("QImage", QMetaType::QImage),
QT_ADD_STATIC_METATYPE("QPolygon", QMetaType::QPolygon),
QT_ADD_STATIC_METATYPE("QRegion", QMetaType::QRegion),
QT_ADD_STATIC_METATYPE("QBitmap", QMetaType::QBitmap),
QT_ADD_STATIC_METATYPE("QCursor", QMetaType::QCursor),
- QT_ADD_STATIC_METATYPE("QSizePolicy", QMetaType::QSizePolicy),
QT_ADD_STATIC_METATYPE("QKeySequence", QMetaType::QKeySequence),
QT_ADD_STATIC_METATYPE("QPen", QMetaType::QPen),
QT_ADD_STATIC_METATYPE("QTextLength", QMetaType::QTextLength),
@@ -290,6 +287,10 @@ static const struct { const char * typeName; int typeNameLength; int type; } typ
QT_ADD_STATIC_METATYPE("QVector4D", QMetaType::QVector4D),
QT_ADD_STATIC_METATYPE("QQuaternion", QMetaType::QQuaternion),
+ /* All Widgets types */
+ QT_ADD_STATIC_METATYPE("QIcon", QMetaType::QIcon),
+ QT_ADD_STATIC_METATYPE("QSizePolicy", QMetaType::QSizePolicy),
+
/* All Metatype builtins */
QT_ADD_STATIC_METATYPE("void*", QMetaType::VoidStar),
QT_ADD_STATIC_METATYPE("long", QMetaType::Long),
@@ -338,6 +339,7 @@ struct QMetaTypeGuiHelper
#endif
};
Q_CORE_EXPORT const QMetaTypeGuiHelper *qMetaTypeGuiHelper = 0;
+Q_CORE_EXPORT const QMetaTypeGuiHelper *qMetaTypeWidgetsHelper = 0;
class QCustomTypeInfo
{
@@ -399,14 +401,17 @@ void QMetaType::registerStreamOperators(int idx, SaveOperator saveOp,
*/
const char *QMetaType::typeName(int type)
{
- enum { GuiTypeCount = LastGuiType - FirstGuiType };
+ enum { GuiTypeCount = LastGuiType - FirstGuiType,
+ WidgetsTypeCount = LastWidgetsType - FirstWidgetsType };
if (type >= 0 && type <= LastCoreType) {
return types[type].typeName;
} else if (type >= FirstGuiType && type <= LastGuiType) {
return types[type - FirstGuiType + LastCoreType + 1].typeName;
+ } else if (type >= FirstWidgetsType && type <= LastWidgetsType) {
+ return types[type - FirstWidgetsType + GuiTypeCount + LastCoreType + 2].typeName;
} else if (type >= FirstCoreExtType && type <= LastCoreExtType) {
- return types[type - FirstCoreExtType + GuiTypeCount + LastCoreType + 2].typeName;
+ return types[type - FirstCoreExtType + GuiTypeCount + WidgetsTypeCount + LastCoreType + 3].typeName;
} else if (type >= User) {
const QVector<QCustomTypeInfo> * const ct = customTypes();
QReadLocker locker(customTypesLock());
@@ -765,13 +770,11 @@ bool QMetaType::save(QDataStream &stream, int type, const void *data)
case QMetaType::QBrush:
case QMetaType::QColor:
case QMetaType::QPalette:
- case QMetaType::QIcon:
case QMetaType::QImage:
case QMetaType::QPolygon:
case QMetaType::QRegion:
case QMetaType::QBitmap:
case QMetaType::QCursor:
- case QMetaType::QSizePolicy:
case QMetaType::QKeySequence:
case QMetaType::QPen:
case QMetaType::QTextLength:
@@ -787,6 +790,12 @@ bool QMetaType::save(QDataStream &stream, int type, const void *data)
return false;
qMetaTypeGuiHelper[type - FirstGuiType].saveOp(stream, data);
break;
+ case QMetaType::QIcon:
+ case QMetaType::QSizePolicy:
+ if (!qMetaTypeWidgetsHelper)
+ return false;
+ qMetaTypeWidgetsHelper[type - FirstWidgetsType].saveOp(stream, data);
+ break;
default: {
const QVector<QCustomTypeInfo> * const ct = customTypes();
if (!ct)
@@ -967,13 +976,11 @@ bool QMetaType::load(QDataStream &stream, int type, void *data)
case QMetaType::QBrush:
case QMetaType::QColor:
case QMetaType::QPalette:
- case QMetaType::QIcon:
case QMetaType::QImage:
case QMetaType::QPolygon:
case QMetaType::QRegion:
case QMetaType::QBitmap:
case QMetaType::QCursor:
- case QMetaType::QSizePolicy:
case QMetaType::QKeySequence:
case QMetaType::QPen:
case QMetaType::QTextLength:
@@ -989,6 +996,12 @@ bool QMetaType::load(QDataStream &stream, int type, void *data)
return false;
qMetaTypeGuiHelper[type - FirstGuiType].loadOp(stream, data);
break;
+ case QMetaType::QIcon:
+ case QMetaType::QSizePolicy:
+ if (!qMetaTypeWidgetsHelper)
+ return false;
+ qMetaTypeWidgetsHelper[type - FirstWidgetsType].loadOp(stream, data);
+ break;
default: {
const QVector<QCustomTypeInfo> * const ct = customTypes();
if (!ct)
@@ -1218,6 +1231,10 @@ void *QMetaType::construct(int type, const void *copy)
if (!qMetaTypeGuiHelper)
return 0;
constr = qMetaTypeGuiHelper[type - FirstGuiType].constr;
+ } else if (type >= FirstWidgetsType && type <= LastWidgetsType) {
+ if (!qMetaTypeWidgetsHelper)
+ return 0;
+ constr = qMetaTypeWidgetsHelper[type - FirstWidgetsType].constr;
} else {
const QVector<QCustomTypeInfo> * const ct = customTypes();
QReadLocker locker(customTypesLock());
@@ -1380,6 +1397,12 @@ void QMetaType::destroy(int type, void *data)
if (!qMetaTypeGuiHelper)
return;
destr = qMetaTypeGuiHelper[type - FirstGuiType].destr;
+ } else if (type >= FirstWidgetsType && type <= LastWidgetsType) {
+ Q_ASSERT(qMetaTypeWidgetsHelper);
+
+ if (!qMetaTypeWidgetsHelper)
+ return;
+ destr = qMetaTypeWidgetsHelper[type - FirstWidgetsType].destr;
} else {
QReadLocker locker(customTypesLock());
if (type < User || !ct || ct->count() <= type - User)
diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h
index 767d79a14e..5df7658a13 100644
--- a/src/corelib/kernel/qmetatype.h
+++ b/src/corelib/kernel/qmetatype.h
@@ -71,16 +71,20 @@ public:
QLine = 23, QLineF = 24, QPoint = 25, QPointF = 26, QRegExp = 27,
QVariantHash = 28, QEasingCurve = 29, LastCoreType = QEasingCurve,
- FirstGuiType = 63 /* QColorGroup */,
+ FirstGuiType = 64 /* QFont */,
QFont = 64, QPixmap = 65, QBrush = 66, QColor = 67, QPalette = 68,
- QIcon = 69, QImage = 70, QPolygon = 71, QRegion = 72, QBitmap = 73,
- QCursor = 74, QSizePolicy = 75, QKeySequence = 76, QPen = 77,
- QTextLength = 78, QTextFormat = 79, QMatrix = 80, QTransform = 81,
- QMatrix4x4 = 82, QVector2D = 83, QVector3D = 84, QVector4D = 85,
- QQuaternion = 86,
+ QImage = 69, QPolygon = 70, QRegion = 71, QBitmap = 72,
+ QCursor = 73, QKeySequence = 74, QPen = 75,
+ QTextLength = 76, QTextFormat = 77, QMatrix = 78, QTransform = 79,
+ QMatrix4x4 = 80, QVector2D = 81, QVector3D = 82, QVector4D = 83,
+ QQuaternion = 84,
LastGuiType = QQuaternion,
+ FirstWidgetsType = 120, /* QIcon */
+ QIcon = 120, QSizePolicy = 121,
+ LastWidgetsType = QSizePolicy,
+
FirstCoreExtType = 128 /* VoidStar */,
VoidStar = 128, Long = 129, Short = 130, Char = 131, ULong = 132,
UShort = 133, UChar = 134, Float = 135, QObjectStar = 136, QWidgetStar = 137,
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index b769beac03..0f314d45f1 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -177,6 +177,7 @@ QObjectPrivate::QObjectPrivate(int version)
#endif
metaObject = 0;
hasGuards = false;
+ isWindow = false;
}
QObjectPrivate::~QObjectPrivate()
diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h
index 59ff988ba9..591c5c88bf 100644
--- a/src/corelib/kernel/qobject.h
+++ b/src/corelib/kernel/qobject.h
@@ -102,7 +102,8 @@ public:
uint inEventHandler : 1; //only used if QT_JAMBI_BUILD
uint inThreadChangeEvent : 1;
uint hasGuards : 1; //true iff there is one or more QPointer attached to this object
- uint unused : 22;
+ uint isWindow : 1; //for QWindow
+ uint unused : 21;
int postedEvents;
QMetaObject *metaObject; // assert dynamic
};
@@ -144,6 +145,7 @@ public:
void setObjectName(const QString &name);
inline bool isWidgetType() const { return d_ptr->isWidget; }
+ inline bool isWindowType() const { return d_ptr->isWindow; }
inline bool signalsBlocked() const { return d_ptr->blockSig; }
bool blockSignals(bool b);
diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h
index de8f9111f9..e77fc90b92 100644
--- a/src/corelib/kernel/qvariant.h
+++ b/src/corelib/kernel/qvariant.h
@@ -132,26 +132,27 @@ class Q_CORE_EXPORT QVariant
Brush = 66,
Color = 67,
Palette = 68,
- Icon = 69,
- Image = 70,
- Polygon = 71,
- Region = 72,
- Bitmap = 73,
- Cursor = 74,
- SizePolicy = 75,
- KeySequence = 76,
- Pen = 77,
- TextLength = 78,
- TextFormat = 79,
- Matrix = 80,
- Transform = 81,
- Matrix4x4 = 82,
- Vector2D = 83,
- Vector3D = 84,
- Vector4D = 85,
- Quaternion = 86,
+ Image = 69,
+ Polygon = 70,
+ Region = 71,
+ Bitmap = 72,
+ Cursor = 73,
+ KeySequence = 74,
+ Pen = 75,
+ TextLength = 76,
+ TextFormat = 77,
+ Matrix = 78,
+ Transform = 79,
+ Matrix4x4 = 80,
+ Vector2D = 81,
+ Vector3D = 82,
+ Vector4D = 83,
+ Quaternion = 84,
LastGuiType = Quaternion,
+ Icon = 120,
+ SizePolicy = 121,
+
UserType = 127,
LastType = 0xffffffff // need this so that gcc >= 3.4 allocates 32 bits for Type
};
diff --git a/src/corelib/plugin/qlibrary_p.h b/src/corelib/plugin/qlibrary_p.h
index 5559489767..15825c699f 100644
--- a/src/corelib/plugin/qlibrary_p.h
+++ b/src/corelib/plugin/qlibrary_p.h
@@ -53,7 +53,7 @@
// We mean it.
//
-#ifdef Q_WS_WIN
+#ifdef Q_OS_WIN
# include "QtCore/qt_windows.h"
#endif
#include "QtCore/qlibrary.h"
@@ -72,7 +72,7 @@ class QLibraryPrivate
{
public:
-#ifdef Q_WS_WIN
+#ifdef Q_OS_WIN
HINSTANCE
#else
void *
diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp
index 02a63bb92d..aeb118ffe5 100644
--- a/src/corelib/thread/qthread.cpp
+++ b/src/corelib/thread/qthread.cpp
@@ -176,12 +176,12 @@ QThreadPrivate::QThreadPrivate(QThreadData *d)
{
#if defined (Q_OS_UNIX)
thread_id = 0;
-#elif defined (Q_WS_WIN)
+#elif defined (Q_OS_WIN)
handle = 0;
id = 0;
waiters = 0;
#endif
-#if defined (Q_WS_WIN) || defined (Q_OS_SYMBIAN)
+#if defined (Q_OS_WIN) || defined (Q_OS_SYMBIAN)
terminationEnabled = true;
terminatePending = false;
#endif
diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp
index ac5d6c4a8e..3d3bc55d71 100644
--- a/src/corelib/tools/qdatetime.cpp
+++ b/src/corelib/tools/qdatetime.cpp
@@ -51,7 +51,7 @@
#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
#include <qt_windows.h>
#endif
-#ifndef Q_WS_WIN
+#ifndef Q_OS_WIN
#include <locale.h>
#endif
@@ -2519,7 +2519,7 @@ QString QDateTime::toString(Qt::DateFormat f) const
}
#ifndef QT_NO_TEXTDATE
else if (f == Qt::TextDate) {
-#ifndef Q_WS_WIN
+#ifndef Q_OS_WIN
buf = d->date.shortDayName(d->date.dayOfWeek());
buf += QLatin1Char(' ');
buf += d->date.shortMonthName(d->date.month());
diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp
index 36c4ae75a5..d2bb752c6d 100644
--- a/src/corelib/tools/qlocale.cpp
+++ b/src/corelib/tools/qlocale.cpp
@@ -39,6 +39,11 @@
**
****************************************************************************/
+#if !defined(QWS) && defined(Q_OS_MAC)
+# include "private/qcore_mac_p.h"
+# include <CoreFoundation/CoreFoundation.h>
+#endif
+
#include "qglobal.h"
#ifndef QT_NO_SYSTEMLOCALE
@@ -61,14 +66,10 @@ QT_END_NAMESPACE
#include "qstringlist.h"
#include "qvariant.h"
#include "qstringbuilder.h"
-#if defined(Q_WS_WIN)
+#if defined(Q_OS_WIN)
# include "qt_windows.h"
# include <time.h>
#endif
-#if !defined(QWS) && defined(Q_OS_MAC)
-# include "private/qcore_mac_p.h"
-# include <CoreFoundation/CoreFoundation.h>
-#endif
#include "private/qnumeric_p.h"
#include "private/qsystemlibrary_p.h"
diff --git a/src/gui/accessible/accessible.pri b/src/gui/accessible/accessible.pri
deleted file mode 100644
index 31362ffded..0000000000
--- a/src/gui/accessible/accessible.pri
+++ /dev/null
@@ -1,25 +0,0 @@
-# Qt accessibility module
-
-contains(QT_CONFIG, accessibility) {
- HEADERS += accessible/qaccessible.h \
- accessible/qaccessible2.h \
- accessible/qaccessibleobject.h \
- accessible/qaccessiblewidget.h \
- accessible/qaccessibleplugin.h
- SOURCES += accessible/qaccessible.cpp \
- accessible/qaccessible2.cpp \
- accessible/qaccessibleobject.cpp \
- accessible/qaccessiblewidget.cpp \
- accessible/qaccessibleplugin.cpp
-
- mac:!embedded:!qpa {
- HEADERS += accessible/qaccessible_mac_p.h
- OBJECTIVE_SOURCES += accessible/qaccessible_mac.mm \
- accessible/qaccessible_mac_cocoa.mm
- } else:win32 {
- SOURCES += accessible/qaccessible_win.cpp
- } else {
- HEADERS += accessible/qaccessiblebridge.h
- SOURCES += accessible/qaccessible_unix.cpp accessible/qaccessiblebridge.cpp
- }
-}
diff --git a/src/gui/accessible/qaccessible.h b/src/gui/accessible/qaccessible.h
deleted file mode 100644
index 24a6744643..0000000000
--- a/src/gui/accessible/qaccessible.h
+++ /dev/null
@@ -1,472 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QACCESSIBLE_H
-#define QACCESSIBLE_H
-
-#include <QtCore/qglobal.h>
-#include <QtCore/qobject.h>
-#include <QtCore/qrect.h>
-#include <QtCore/qset.h>
-#include <QtCore/qvector.h>
-#include <QtCore/qvariant.h>
-#include <QtGui/qcolor.h>
-#include <QtGui/qevent.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_ACCESSIBILITY
-
-class QAccessibleInterface;
-
-class Q_GUI_EXPORT QAccessible
-{
-public:
- enum Event {
- SoundPlayed = 0x0001,
- Alert = 0x0002,
- ForegroundChanged = 0x0003,
- MenuStart = 0x0004,
- MenuEnd = 0x0005,
- PopupMenuStart = 0x0006,
- PopupMenuEnd = 0x0007,
- ContextHelpStart = 0x000C,
- ContextHelpEnd = 0x000D,
- DragDropStart = 0x000E,
- DragDropEnd = 0x000F,
- DialogStart = 0x0010,
- DialogEnd = 0x0011,
- ScrollingStart = 0x0012,
- ScrollingEnd = 0x0013,
-
- MenuCommand = 0x0018,
-
- // Values from IAccessible2
- ActionChanged = 0x0101,
- ActiveDescendantChanged = 0x0102,
- AttributeChanged = 0x0103,
- DocumentContentChanged = 0x0104,
- DocumentLoadComplete = 0x0105,
- DocumentLoadStopped = 0x0106,
- DocumentReload = 0x0107,
- HyperlinkEndIndexChanged = 0x0108,
- HyperlinkNumberOfAnchorsChanged = 0x0109,
- HyperlinkSelectedLinkChanged = 0x010A,
- HypertextLinkActivated = 0x010B,
- HypertextLinkSelected = 0x010C,
- HyperlinkStartIndexChanged = 0x010D,
- HypertextChanged = 0x010E,
- HypertextNLinksChanged = 0x010F,
- ObjectAttributeChanged = 0x0110,
- PageChanged = 0x0111,
- SectionChanged = 0x0112,
- TableCaptionChanged = 0x0113,
- TableColumnDescriptionChanged = 0x0114,
- TableColumnHeaderChanged = 0x0115,
- TableModelChanged = 0x0116,
- TableRowDescriptionChanged = 0x0117,
- TableRowHeaderChanged = 0x0118,
- TableSummaryChanged = 0x0119,
- TextAttributeChanged = 0x011A,
- TextCaretMoved = 0x011B,
- // TextChanged = 0x011C, is deprecated in IA2, use TextUpdated
- TextColumnChanged = 0x011D,
- TextInserted = 0x011E,
- TextRemoved = 0x011F,
- TextUpdated = 0x0120,
- TextSelectionChanged = 0x0121,
- VisibleDataChanged = 0x0122,
-
- ObjectCreated = 0x8000,
- ObjectDestroyed = 0x8001,
- ObjectShow = 0x8002,
- ObjectHide = 0x8003,
- ObjectReorder = 0x8004,
- Focus = 0x8005,
- Selection = 0x8006,
- SelectionAdd = 0x8007,
- SelectionRemove = 0x8008,
- SelectionWithin = 0x8009,
- StateChanged = 0x800A,
- LocationChanged = 0x800B,
- NameChanged = 0x800C,
- DescriptionChanged = 0x800D,
- ValueChanged = 0x800E,
- ParentChanged = 0x800F,
- HelpChanged = 0x80A0,
- DefaultActionChanged = 0x80B0,
- AcceleratorChanged = 0x80C0
- };
-
- enum StateFlag {
- Normal = 0x00000000,
- Unavailable = 0x00000001,
- Selected = 0x00000002,
- Focused = 0x00000004,
- Pressed = 0x00000008,
- Checked = 0x00000010,
- Mixed = 0x00000020,
- ReadOnly = 0x00000040,
- HotTracked = 0x00000080,
- DefaultButton = 0x00000100,
- // #### Qt5 Expandable
- Expanded = 0x00000200,
- Collapsed = 0x00000400,
- Busy = 0x00000800,
- // Floating = 0x00001000,
- Marqueed = 0x00002000,
- Animated = 0x00004000,
- Invisible = 0x00008000,
- Offscreen = 0x00010000,
- Sizeable = 0x00020000,
- Movable = 0x00040000,
-#ifdef QT3_SUPPORT
- Moveable = Movable,
-#endif
- SelfVoicing = 0x00080000,
- Focusable = 0x00100000,
- Selectable = 0x00200000,
- Linked = 0x00400000,
- Traversed = 0x00800000,
- MultiSelectable = 0x01000000,
- ExtSelectable = 0x02000000,
- //AlertLow = 0x04000000,
- //AlertMedium = 0x08000000,
- //AlertHigh = 0x10000000, /* reused for HasInvokeExtension */
- Protected = 0x20000000,
- HasPopup = 0x40000000,
- Modal = 0x80000000,
-
- // #### Qt5 ManagesDescendants
- // #### Qt5 remove HasInvokeExtension
- HasInvokeExtension = 0x10000000 // internal
- };
- Q_DECLARE_FLAGS(State, StateFlag)
-
- enum Role {
- NoRole = 0x00000000,
- TitleBar = 0x00000001,
- MenuBar = 0x00000002,
- ScrollBar = 0x00000003,
- Grip = 0x00000004,
- Sound = 0x00000005,
- Cursor = 0x00000006,
- Caret = 0x00000007,
- AlertMessage = 0x00000008,
- Window = 0x00000009,
- Client = 0x0000000A,
- PopupMenu = 0x0000000B,
- MenuItem = 0x0000000C,
- ToolTip = 0x0000000D,
- Application = 0x0000000E,
- Document = 0x0000000F,
- Pane = 0x00000010,
- Chart = 0x00000011,
- Dialog = 0x00000012,
- Border = 0x00000013,
- Grouping = 0x00000014,
- Separator = 0x00000015,
- ToolBar = 0x00000016,
- StatusBar = 0x00000017,
- Table = 0x00000018,
- ColumnHeader = 0x00000019,
- RowHeader = 0x0000001A,
- Column = 0x0000001B,
- Row = 0x0000001C,
- Cell = 0x0000001D,
- Link = 0x0000001E,
- HelpBalloon = 0x0000001F,
- Assistant = 0x00000020,
- List = 0x00000021,
- ListItem = 0x00000022,
- Tree = 0x00000023,
- TreeItem = 0x00000024,
- PageTab = 0x00000025,
- PropertyPage = 0x00000026,
- Indicator = 0x00000027,
- Graphic = 0x00000028,
- StaticText = 0x00000029,
- EditableText = 0x0000002A, // Editable, selectable, etc.
- PushButton = 0x0000002B,
- CheckBox = 0x0000002C,
- RadioButton = 0x0000002D,
- ComboBox = 0x0000002E,
- // DropList = 0x0000002F,
- ProgressBar = 0x00000030,
- Dial = 0x00000031,
- HotkeyField = 0x00000032,
- Slider = 0x00000033,
- SpinBox = 0x00000034,
- Canvas = 0x00000035,
- Animation = 0x00000036,
- Equation = 0x00000037,
- ButtonDropDown = 0x00000038,
- ButtonMenu = 0x00000039,
- ButtonDropGrid = 0x0000003A,
- Whitespace = 0x0000003B,
- PageTabList = 0x0000003C,
- Clock = 0x0000003D,
- Splitter = 0x0000003E,
- // Additional Qt roles where enum value does not map directly to MSAA:
- LayeredPane = 0x0000003F,
- UserRole = 0x0000ffff
- };
-
- enum Text {
- Name = 0,
- Description,
- Value,
- Help,
- Accelerator,
- UserText = 0x0000ffff
- };
-
- enum RelationFlag {
- Unrelated = 0x00000000,
- Self = 0x00000001,
- Ancestor = 0x00000002,
- Child = 0x00000004,
- Descendent = 0x00000008,
- Sibling = 0x00000010,
- HierarchyMask = 0x000000ff,
-
- Up = 0x00000100,
- Down = 0x00000200,
- Left = 0x00000400,
- Right = 0x00000800,
- Covers = 0x00001000,
- Covered = 0x00002000,
- GeometryMask = 0x0000ff00,
-
- FocusChild = 0x00010000,
- Label = 0x00020000,
- Labelled = 0x00040000,
- Controller = 0x00080000,
- Controlled = 0x00100000,
- LogicalMask = 0x00ff0000
- };
- Q_DECLARE_FLAGS(Relation, RelationFlag)
-
- enum Action {
- DefaultAction = 0,
- Press = -1,
- FirstStandardAction = Press,
- SetFocus = -2,
- Increase = -3,
- Decrease = -4,
- Accept = -5,
- Cancel = -6,
- Select = -7,
- ClearSelection = -8,
- RemoveSelection = -9,
- ExtendSelection = -10,
- AddToSelection = -11,
- LastStandardAction = AddToSelection
- };
-
- enum Method {
- ListSupportedMethods = 0,
- SetCursorPosition = 1,
- GetCursorPosition = 2,
- ForegroundColor = 3,
- BackgroundColor = 4
- };
-
- typedef QAccessibleInterface*(*InterfaceFactory)(const QString &key, QObject*);
- typedef void(*UpdateHandler)(QObject*, int who, Event reason);
- typedef void(*RootObjectHandler)(QObject*);
-
- static void installFactory(InterfaceFactory);
- static void removeFactory(InterfaceFactory);
- static UpdateHandler installUpdateHandler(UpdateHandler);
- static RootObjectHandler installRootObjectHandler(RootObjectHandler);
-
- static QAccessibleInterface *queryAccessibleInterface(QObject *);
- static void updateAccessibility(QObject *, int who, Event reason);
- static bool isActive();
- static void setRootObject(QObject*);
-
- static void initialize();
- static void cleanup();
-
-private:
- static UpdateHandler updateHandler;
- static RootObjectHandler rootObjectHandler;
-};
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QAccessible::State)
-Q_DECLARE_OPERATORS_FOR_FLAGS(QAccessible::Relation)
-QT_END_NAMESPACE
-Q_DECLARE_METATYPE(QSet<QAccessible::Method>)
-QT_BEGIN_NAMESPACE
-
-namespace QAccessible2
-{
- enum InterfaceType
- {
- TextInterface,
- EditableTextInterface,
- ValueInterface,
- TableInterface,
- ActionInterface,
- ImageInterface,
- Table2Interface
- };
-}
-
-class QAccessible2Interface;
-class QAccessibleTextInterface;
-class QAccessibleEditableTextInterface;
-class QAccessibleValueInterface;
-class QAccessibleTableInterface;
-class QAccessibleActionInterface;
-class QAccessibleImageInterface;
-class QAccessibleTable2Interface;
-
-class Q_GUI_EXPORT QAccessibleInterface : public QAccessible
-{
-public:
- virtual ~QAccessibleInterface() {}
- // check for valid pointers
- virtual bool isValid() const = 0;
- virtual QObject *object() const = 0;
-
- // hierarchy
- virtual int childCount() const = 0;
- virtual int indexOfChild(const QAccessibleInterface *) const = 0;
-
- // relations
- virtual Relation relationTo(int child, const QAccessibleInterface *other,
- int otherChild) const = 0;
- virtual int childAt(int x, int y) const = 0;
-
- // navigation
- virtual int navigate(RelationFlag relation, int index, QAccessibleInterface **iface) const = 0;
-
- // properties and state
- virtual QString text(Text t, int child) const = 0;
- virtual void setText(Text t, int child, const QString &text) = 0;
- virtual QRect rect(int child) const = 0;
- virtual Role role(int child) const = 0;
- virtual State state(int child) const = 0;
-
- // action
- virtual int userActionCount(int child) const = 0;
- virtual QString actionText(int action, Text t, int child) const = 0;
- virtual bool doAction(int action, int child, const QVariantList &params = QVariantList()) = 0;
-
- QVariant invokeMethod(Method method, int child = 0,
- const QVariantList &params = QVariantList());
-
- inline QSet<Method> supportedMethods()
- { return qvariant_cast<QSet<Method> >(invokeMethod(ListSupportedMethods)); }
-
- inline QColor foregroundColor()
- { return qvariant_cast<QColor>(invokeMethod(ForegroundColor)); }
-
- inline QColor backgroundColor()
- { return qvariant_cast<QColor>(invokeMethod(BackgroundColor)); }
-
- inline QAccessibleTextInterface *textInterface()
- { return reinterpret_cast<QAccessibleTextInterface *>(cast_helper(QAccessible2::TextInterface)); }
-
- inline QAccessibleEditableTextInterface *editableTextInterface()
- { return reinterpret_cast<QAccessibleEditableTextInterface *>(cast_helper(QAccessible2::EditableTextInterface)); }
-
- inline QAccessibleValueInterface *valueInterface()
- { return reinterpret_cast<QAccessibleValueInterface *>(cast_helper(QAccessible2::ValueInterface)); }
-
- inline QAccessibleTableInterface *tableInterface()
- { return reinterpret_cast<QAccessibleTableInterface *>(cast_helper(QAccessible2::TableInterface)); }
-
- inline QAccessibleActionInterface *actionInterface()
- { return reinterpret_cast<QAccessibleActionInterface *>(cast_helper(QAccessible2::ActionInterface)); }
-
- inline QAccessibleImageInterface *imageInterface()
- { return reinterpret_cast<QAccessibleImageInterface *>(cast_helper(QAccessible2::ImageInterface)); }
-
- inline QAccessibleTable2Interface *table2Interface()
- { return reinterpret_cast<QAccessibleTable2Interface *>(cast_helper(QAccessible2::Table2Interface)); }
-
-private:
- QAccessible2Interface *cast_helper(QAccessible2::InterfaceType);
-};
-
-class Q_GUI_EXPORT QAccessibleInterfaceEx: public QAccessibleInterface
-{
-public:
- virtual QVariant invokeMethodEx(Method method, int child, const QVariantList &params) = 0;
- virtual QVariant virtual_hook(const QVariant &data);
- virtual QAccessible2Interface *interface_cast(QAccessible2::InterfaceType)
- { return 0; }
-};
-
-
-class Q_GUI_EXPORT QAccessibleEvent : public QEvent
-{
-public:
- inline QAccessibleEvent(Type type, int child);
- inline int child() const { return c; }
- inline QString value() const { return val; }
- inline void setValue(const QString &aText) { val = aText; }
-
-private:
- int c;
- QString val;
-};
-
-inline QAccessibleEvent::QAccessibleEvent(Type atype, int achild)
- : QEvent(atype), c(achild) {}
-
-#define QAccessibleInterface_iid "com.trolltech.Qt.QAccessibleInterface"
-Q_DECLARE_INTERFACE(QAccessibleInterface, QAccessibleInterface_iid)
-
-#endif // QT_NO_ACCESSIBILITY
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QACCESSIBLE_H
diff --git a/src/gui/accessible/qaccessible2.cpp b/src/gui/accessible/qaccessible2.cpp
deleted file mode 100644
index 078ff13e2c..0000000000
--- a/src/gui/accessible/qaccessible2.cpp
+++ /dev/null
@@ -1,317 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qaccessible2.h"
-#include "qapplication.h"
-#include "qclipboard.h"
-#include "qtextboundaryfinder.h"
-
-#ifndef QT_NO_ACCESSIBILITY
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \namespace QAccessible2
- \ingroup accessibility
- \internal
- \preliminary
-
- \brief The QAccessible2 namespace defines constants relating to
- IAccessible2-based interfaces
-
- \link http://www.linux-foundation.org/en/Accessibility/IAccessible2 IAccessible2 Specification \endlink
-*/
-
-/*!
- \class QAccessibleTextInterface
-
- \ingroup accessibility
- \internal
- \preliminary
-
- \brief The QAccessibleTextInterface class implements support for
- the IAccessibleText interface.
-
- \link http://www.linux-foundation.org/en/Accessibility/IAccessible2 IAccessible2 Specification \endlink
-*/
-
-/*!
- \class QAccessibleEditableTextInterface
- \ingroup accessibility
- \internal
- \preliminary
-
- \brief The QAccessibleEditableTextInterface class implements support for
- the IAccessibleEditableText interface.
-
- \link http://www.linux-foundation.org/en/Accessibility/IAccessible2 IAccessible2 Specification \endlink
-*/
-
-/*!
- \class QAccessibleSimpleEditableTextInterface
- \ingroup accessibility
- \internal
- \preliminary
-
- \brief The QAccessibleSimpleEditableTextInterface class is a convenience class for
- text-based widgets.
-
- \link http://www.linux-foundation.org/en/Accessibility/IAccessible2 IAccessible2 Specification \endlink
-*/
-
-/*!
- \class QAccessibleValueInterface
- \ingroup accessibility
- \internal
- \preliminary
-
- \brief The QAccessibleValueInterface class implements support for
- the IAccessibleValue interface.
-
- \link http://www.linux-foundation.org/en/Accessibility/IAccessible2 IAccessible2 Specification \endlink
-*/
-
-/*!
- \class QAccessibleActionInterface
- \ingroup accessibility
- \internal
- \preliminary
-
- \brief The QAccessibleActionInterface class implements support for
- the IAccessibleAction interface.
-
- \link http://www.linux-foundation.org/en/Accessibility/IAccessible2 IAccessible2 Specification \endlink
-*/
-
-/*!
- \class QAccessibleImageInterface
- \ingroup accessibility
- \internal
- \preliminary
-
- \brief The QAccessibleImageInterface class implements support for
- the IAccessibleImage interface.
-
- \link http://www.linux-foundation.org/en/Accessibility/IAccessible2 IAccessible2 Specification \endlink
-*/
-
-
-/*!
- \internal
-*/
-QString Q_GUI_EXPORT qTextBeforeOffsetFromString(int offset, QAccessible2::BoundaryType boundaryType,
- int *startOffset, int *endOffset, const QString& text)
-{
- QTextBoundaryFinder::BoundaryType type;
- switch (boundaryType) {
- case QAccessible2::CharBoundary:
- type = QTextBoundaryFinder::Grapheme;
- break;
- case QAccessible2::WordBoundary:
- type = QTextBoundaryFinder::Word;
- break;
- case QAccessible2::SentenceBoundary:
- type = QTextBoundaryFinder::Sentence;
- break;
- default:
- // in any other case return the whole line
- *startOffset = 0;
- *endOffset = text.length();
- return text;
- }
-
- QTextBoundaryFinder boundary(type, text);
- boundary.setPosition(offset);
-
- if (!boundary.isAtBoundary()) {
- boundary.toPreviousBoundary();
- }
- boundary.toPreviousBoundary();
- *startOffset = boundary.position();
- boundary.toNextBoundary();
- *endOffset = boundary.position();
-
- return text.mid(*startOffset, *endOffset - *startOffset);
-}
-
-/*!
- \internal
-*/
-QString Q_GUI_EXPORT qTextAfterOffsetFromString(int offset, QAccessible2::BoundaryType boundaryType,
- int *startOffset, int *endOffset, const QString& text)
-{
- QTextBoundaryFinder::BoundaryType type;
- switch (boundaryType) {
- case QAccessible2::CharBoundary:
- type = QTextBoundaryFinder::Grapheme;
- break;
- case QAccessible2::WordBoundary:
- type = QTextBoundaryFinder::Word;
- break;
- case QAccessible2::SentenceBoundary:
- type = QTextBoundaryFinder::Sentence;
- break;
- default:
- // in any other case return the whole line
- *startOffset = 0;
- *endOffset = text.length();
- return text;
- }
-
- QTextBoundaryFinder boundary(type, text);
- boundary.setPosition(offset);
-
- boundary.toNextBoundary();
- *startOffset = boundary.position();
- boundary.toNextBoundary();
- *endOffset = boundary.position();
-
- return text.mid(*startOffset, *endOffset - *startOffset);
-}
-
-/*!
- \internal
-*/
-QString Q_GUI_EXPORT qTextAtOffsetFromString(int offset, QAccessible2::BoundaryType boundaryType,
- int *startOffset, int *endOffset, const QString& text)
-{
- QTextBoundaryFinder::BoundaryType type;
- switch (boundaryType) {
- case QAccessible2::CharBoundary:
- type = QTextBoundaryFinder::Grapheme;
- break;
- case QAccessible2::WordBoundary:
- type = QTextBoundaryFinder::Word;
- break;
- case QAccessible2::SentenceBoundary:
- type = QTextBoundaryFinder::Sentence;
- break;
- default:
- // in any other case return the whole line
- *startOffset = 0;
- *endOffset = text.length();
- return text;
- }
-
- QTextBoundaryFinder boundary(type, text);
- boundary.setPosition(offset);
-
- if (!boundary.isAtBoundary()) {
- boundary.toPreviousBoundary();
- }
- *startOffset = boundary.position();
- boundary.toNextBoundary();
- *endOffset = boundary.position();
-
- return text.mid(*startOffset, *endOffset - *startOffset);
-}
-
-QAccessibleSimpleEditableTextInterface::QAccessibleSimpleEditableTextInterface(
- QAccessibleInterface *accessibleInterface)
- : iface(accessibleInterface)
-{
- Q_ASSERT(iface);
-}
-
-#ifndef QT_NO_CLIPBOARD
-static QString textForRange(QAccessibleInterface *iface, int startOffset, int endOffset)
-{
- return iface->text(QAccessible::Value, 0).mid(startOffset, endOffset - startOffset);
-}
-#endif
-
-void QAccessibleSimpleEditableTextInterface::copyText(int startOffset, int endOffset)
-{
-#ifdef QT_NO_CLIPBOARD
- Q_UNUSED(startOffset);
- Q_UNUSED(endOffset);
-#else
- QApplication::clipboard()->setText(textForRange(iface, startOffset, endOffset));
-#endif
-}
-
-void QAccessibleSimpleEditableTextInterface::deleteText(int startOffset, int endOffset)
-{
- QString txt = iface->text(QAccessible::Value, 0);
- txt.remove(startOffset, endOffset - startOffset);
- iface->setText(QAccessible::Value, 0, txt);
-}
-
-void QAccessibleSimpleEditableTextInterface::insertText(int offset, const QString &text)
-{
- QString txt = iface->text(QAccessible::Value, 0);
- txt.insert(offset, text);
- iface->setText(QAccessible::Value, 0, txt);
-}
-
-void QAccessibleSimpleEditableTextInterface::cutText(int startOffset, int endOffset)
-{
-#ifdef QT_NO_CLIPBOARD
- Q_UNUSED(startOffset);
- Q_UNUSED(endOffset);
-#else
- QString sub = textForRange(iface, startOffset, endOffset);
- deleteText(startOffset, endOffset);
- QApplication::clipboard()->setText(sub);
-#endif
-}
-
-void QAccessibleSimpleEditableTextInterface::pasteText(int offset)
-{
-#ifdef QT_NO_CLIPBOARD
- Q_UNUSED(offset);
-#else
- QString txt = iface->text(QAccessible::Value, 0);
- txt.insert(offset, QApplication::clipboard()->text());
- iface->setText(QAccessible::Value, 0, txt);
-#endif
-}
-
-void QAccessibleSimpleEditableTextInterface::replaceText(int startOffset, int endOffset, const QString &text)
-{
- QString txt = iface->text(QAccessible::Value, 0);
- txt.replace(startOffset, endOffset - startOffset, text);
- iface->setText(QAccessible::Value, 0, txt);
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_ACCESSIBILITY
diff --git a/src/gui/accessible/qaccessible2.h b/src/gui/accessible/qaccessible2.h
deleted file mode 100644
index 106b69efcf..0000000000
--- a/src/gui/accessible/qaccessible2.h
+++ /dev/null
@@ -1,358 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QACCESSIBLE2_H
-#define QACCESSIBLE2_H
-
-#include <QtGui/qaccessible.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_ACCESSIBILITY
-
-class QModelIndex;
-
-namespace QAccessible2
-{
- enum CoordinateType
- {
- RelativeToScreen = 0,
- RelativeToParent = 1
- };
-
- enum BoundaryType {
- CharBoundary,
- WordBoundary,
- SentenceBoundary,
- ParagraphBoundary,
- LineBoundary,
- NoBoundary
- };
-
- enum TableModelChangeType {
- TableModelChangeInsert,
- TableModelChangeDelete,
- TableModelChangeUpdate
- };
-
- struct TableModelChange {
- int firstColumn;
- int firstRow;
- int lastColumn;
- int lastRow;
- TableModelChangeType type;
-
- TableModelChange()
- : firstColumn(0), firstRow(0), lastColumn(0), lastRow(0), type(TableModelChangeUpdate)
- {}
- };
-}
-
-class Q_GUI_EXPORT QAccessible2Interface
-{
-public:
- virtual ~QAccessible2Interface() {}
-};
-
-// catch-all functions. If an accessible class doesn't implement interface T, return 0
-inline QAccessible2Interface *qAccessibleValueCastHelper() { return 0; }
-inline QAccessible2Interface *qAccessibleTextCastHelper() { return 0; }
-inline QAccessible2Interface *qAccessibleEditableTextCastHelper() { return 0; }
-inline QAccessible2Interface *qAccessibleTableCastHelper() { return 0; }
-inline QAccessible2Interface *qAccessibleActionCastHelper() { return 0; }
-inline QAccessible2Interface *qAccessibleImageCastHelper() { return 0; }
-inline QAccessible2Interface *qAccessibleTable2CastHelper() { return 0; }
-
-#define Q_ACCESSIBLE_OBJECT \
- public: \
- QAccessible2Interface *interface_cast(QAccessible2::InterfaceType t) \
- { \
- switch (t) { \
- case QAccessible2::TextInterface: \
- return qAccessibleTextCastHelper(); \
- case QAccessible2::EditableTextInterface: \
- return qAccessibleEditableTextCastHelper(); \
- case QAccessible2::ValueInterface: \
- return qAccessibleValueCastHelper(); \
- case QAccessible2::TableInterface: \
- return qAccessibleTableCastHelper(); \
- case QAccessible2::ActionInterface: \
- return qAccessibleActionCastHelper(); \
- case QAccessible2::ImageInterface: \
- return qAccessibleImageCastHelper(); \
- case QAccessible2::Table2Interface: \
- return qAccessibleTable2CastHelper(); \
- } \
- return 0; \
- } \
- private:
-
-class Q_GUI_EXPORT QAccessibleTextInterface: public QAccessible2Interface
-{
-public:
- inline QAccessible2Interface *qAccessibleTextCastHelper() { return this; }
-
- virtual ~QAccessibleTextInterface() {}
-
- virtual void addSelection(int startOffset, int endOffset) = 0;
- virtual QString attributes(int offset, int *startOffset, int *endOffset) = 0;
- virtual int cursorPosition() = 0;
- virtual QRect characterRect(int offset, QAccessible2::CoordinateType coordType) = 0;
- virtual int selectionCount() = 0;
- virtual int offsetAtPoint(const QPoint &point, QAccessible2::CoordinateType coordType) = 0;
- virtual void selection(int selectionIndex, int *startOffset, int *endOffset) = 0;
- virtual QString text(int startOffset, int endOffset) = 0;
- virtual QString textBeforeOffset (int offset, QAccessible2::BoundaryType boundaryType,
- int *startOffset, int *endOffset) = 0;
- virtual QString textAfterOffset(int offset, QAccessible2::BoundaryType boundaryType,
- int *startOffset, int *endOffset) = 0;
- virtual QString textAtOffset(int offset, QAccessible2::BoundaryType boundaryType,
- int *startOffset, int *endOffset) = 0;
- virtual void removeSelection(int selectionIndex) = 0;
- virtual void setCursorPosition(int position) = 0;
- virtual void setSelection(int selectionIndex, int startOffset, int endOffset) = 0;
- virtual int characterCount() = 0;
- virtual void scrollToSubstring(int startIndex, int endIndex) = 0;
-};
-
-class Q_GUI_EXPORT QAccessibleEditableTextInterface: public QAccessible2Interface
-{
-public:
- inline QAccessible2Interface *qAccessibleEditableTextCastHelper() { return this; }
-
- virtual ~QAccessibleEditableTextInterface() {}
-
- virtual void copyText(int startOffset, int endOffset) = 0;
- virtual void deleteText(int startOffset, int endOffset) = 0;
- virtual void insertText(int offset, const QString &text) = 0;
- virtual void cutText(int startOffset, int endOffset) = 0;
- virtual void pasteText(int offset) = 0;
- virtual void replaceText(int startOffset, int endOffset, const QString &text) = 0;
- virtual void setAttributes(int startOffset, int endOffset, const QString &attributes) = 0;
-};
-
-class Q_GUI_EXPORT QAccessibleSimpleEditableTextInterface: public QAccessibleEditableTextInterface
-{
-public:
- QAccessibleSimpleEditableTextInterface(QAccessibleInterface *accessibleInterface);
-
- void copyText(int startOffset, int endOffset);
- void deleteText(int startOffset, int endOffset);
- void insertText(int offset, const QString &text);
- void cutText(int startOffset, int endOffset);
- void pasteText(int offset);
- void replaceText(int startOffset, int endOffset, const QString &text);
- inline void setAttributes(int, int, const QString &) {}
-
-private:
- QAccessibleInterface *iface;
-};
-
-class Q_GUI_EXPORT QAccessibleValueInterface: public QAccessible2Interface
-{
-public:
- inline QAccessible2Interface *qAccessibleValueCastHelper() { return this; }
-
- virtual ~QAccessibleValueInterface() {}
-
- virtual QVariant currentValue() = 0;
- virtual void setCurrentValue(const QVariant &value) = 0;
- virtual QVariant maximumValue() = 0;
- virtual QVariant minimumValue() = 0;
-};
-
-class Q_GUI_EXPORT QAccessibleTableInterface: public QAccessible2Interface
-{
-public:
- inline QAccessible2Interface *qAccessibleTableCastHelper() { return this; }
-
- virtual QAccessibleInterface *accessibleAt(int row, int column) = 0;
- virtual QAccessibleInterface *caption() = 0;
- virtual int childIndex(int rowIndex, int columnIndex) = 0;
- virtual QString columnDescription(int column) = 0;
- virtual int columnSpan(int row, int column) = 0;
- virtual QAccessibleInterface *columnHeader() = 0;
- virtual int columnIndex(int childIndex) = 0;
- virtual int columnCount() = 0;
- virtual int rowCount() = 0;
- virtual int selectedColumnCount() = 0;
- virtual int selectedRowCount() = 0;
- virtual QString rowDescription(int row) = 0;
- virtual int rowSpan(int row, int column) = 0;
- virtual QAccessibleInterface *rowHeader() = 0;
- virtual int rowIndex(int childIndex) = 0;
- virtual int selectedRows(int maxRows, QList<int> *rows) = 0;
- virtual int selectedColumns(int maxColumns, QList<int> *columns) = 0;
- virtual QAccessibleInterface *summary() = 0;
- virtual bool isColumnSelected(int column) = 0;
- virtual bool isRowSelected(int row) = 0;
- virtual bool isSelected(int row, int column) = 0;
- virtual void selectRow(int row) = 0;
- virtual void selectColumn(int column) = 0;
- virtual void unselectRow(int row) = 0;
- virtual void unselectColumn(int column) = 0;
- virtual void cellAtIndex(int index, int *row, int *column, int *rowSpan,
- int *columnSpan, bool *isSelected) = 0;
-};
-
-class Q_GUI_EXPORT QAccessibleTable2CellInterface: public QAccessibleInterface
-{
-public:
- // Returns the number of columns occupied by this cell accessible.
- virtual int columnExtent() const = 0;
-
- // Returns the column headers as an array of cell accessibles.
- virtual QList<QAccessibleInterface*> columnHeaderCells() const = 0;
-
- // Translates this cell accessible into the corresponding column index.
- virtual int columnIndex() const = 0;
- // Returns the number of rows occupied by this cell accessible.
- virtual int rowExtent() const = 0;
- // Returns the row headers as an array of cell accessibles.
- virtual QList<QAccessibleInterface*> rowHeaderCells() const = 0;
- // Translates this cell accessible into the corresponding row index.
- virtual int rowIndex() const = 0;
- // Returns a boolean value indicating whether this cell is selected.
- virtual bool isSelected() const = 0;
-
- // Gets the row and column indexes and extents of this cell accessible and whether or not it is selected.
- virtual void rowColumnExtents(int *row, int *column, int *rowExtents, int *columnExtents, bool *selected) const = 0;
- // Returns a reference to the accessbile of the containing table.
- virtual QAccessibleTable2Interface* table() const = 0;
-
- // #### Qt5 this should not be here but part of the state
- virtual bool isExpandable() const = 0;
-};
-
-class Q_GUI_EXPORT QAccessibleTable2Interface: public QAccessible2Interface
-{
-public:
- inline QAccessible2Interface *qAccessibleTable2CastHelper() { return this; }
-
- // Returns the cell at the specified row and column in the table.
- virtual QAccessibleTable2CellInterface *cellAt (int row, int column) const = 0;
- // Returns the caption for the table.
- virtual QAccessibleInterface *caption() const = 0;
- // Returns the description text of the specified column in the table.
- virtual QString columnDescription(int column) const = 0;
- // Returns the total number of columns in table.
- virtual int columnCount() const = 0;
- // Returns the total number of rows in table.
- virtual int rowCount() const = 0;
- // Returns the total number of selected cells.
- virtual int selectedCellCount() const = 0;
- // Returns the total number of selected columns.
- virtual int selectedColumnCount() const = 0;
- // Returns the total number of selected rows.
- virtual int selectedRowCount() const = 0;
- // Returns the description text of the specified row in the table.
- virtual QString rowDescription(int row) const = 0;
- // Returns a list of accessibles currently selected.
- virtual QList<QAccessibleTable2CellInterface*> selectedCells() const = 0;
- // Returns a list of column indexes currently selected (0 based).
- virtual QList<int> selectedColumns() const = 0;
- // Returns a list of row indexes currently selected (0 based).
- virtual QList<int> selectedRows() const = 0;
- // Returns the summary description of the table.
- virtual QAccessibleInterface *summary() const = 0;
- // Returns a boolean value indicating whether the specified column is completely selected.
- virtual bool isColumnSelected(int column) const = 0;
- // Returns a boolean value indicating whether the specified row is completely selected.
- virtual bool isRowSelected(int row) const = 0;
- // Selects a row and unselects all previously selected rows.
- virtual bool selectRow(int row) = 0;
- // Selects a column and unselects all previously selected columns.
- virtual bool selectColumn(int column) = 0;
- // Unselects one row, leaving other selected rows selected (if any).
- virtual bool unselectRow(int row) = 0;
- // Unselects one column, leaving other selected columns selected (if any).
- virtual bool unselectColumn(int column) = 0;
- // Returns the type and extents describing how a table changed.
- virtual QAccessible2::TableModelChange modelChange() const = 0;
-
-protected:
- // These functions are called when the model changes.
- virtual void modelReset() = 0;
- virtual void rowsInserted(const QModelIndex &parent, int first, int last) = 0;
- virtual void rowsRemoved(const QModelIndex &parent, int first, int last) = 0;
- virtual void columnsInserted(const QModelIndex &parent, int first, int last) = 0;
- virtual void columnsRemoved(const QModelIndex &parent, int first, int last) = 0;
- virtual void rowsMoved( const QModelIndex &parent, int start, int end, const QModelIndex &destination, int row) = 0;
- virtual void columnsMoved( const QModelIndex &parent, int start, int end, const QModelIndex &destination, int column) = 0;
-
-friend class QAbstractItemView;
-friend class QAbstractItemViewPrivate;
-};
-
-class Q_GUI_EXPORT QAccessibleActionInterface : public QAccessible2Interface
-{
-public:
- inline QAccessible2Interface *qAccessibleActionCastHelper() { return this; }
-
- virtual int actionCount() = 0;
- virtual void doAction(int actionIndex) = 0;
- virtual QString description(int actionIndex) = 0;
- virtual QString name(int actionIndex) = 0;
- virtual QString localizedName(int actionIndex) = 0;
- virtual QStringList keyBindings(int actionIndex) = 0;
-};
-
-class Q_GUI_EXPORT QAccessibleImageInterface : public QAccessible2Interface
-{
-public:
- inline QAccessible2Interface *qAccessibleImageCastHelper() { return this; }
-
- virtual QString imageDescription() = 0;
- virtual QSize imageSize() = 0;
- virtual QRect imagePosition(QAccessible2::CoordinateType coordType) = 0;
-};
-
-#endif // QT_NO_ACCESSIBILITY
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif
diff --git a/src/gui/accessible/qaccessible_win.cpp b/src/gui/accessible/qaccessible_win.cpp
deleted file mode 100644
index 79ac4422ff..0000000000
--- a/src/gui/accessible/qaccessible_win.cpp
+++ /dev/null
@@ -1,1439 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#include "qaccessible.h"
-#ifndef QT_NO_ACCESSIBILITY
-
-#include "qapplication.h"
-#include <private/qsystemlibrary_p.h>
-#include "qmessagebox.h" // ### dependency
-#include "qt_windows.h"
-#include "qwidget.h"
-#include "qsettings.h"
-#include <QtCore/qmap.h>
-#include <QtCore/qpair.h>
-#include <QtGui/qgraphicsitem.h>
-#include <QtGui/qgraphicsscene.h>
-#include <QtGui/qgraphicsview.h>
-
-#include <winuser.h>
-#if !defined(WINABLEAPI)
-# if defined(Q_WS_WINCE)
-# include <bldver.h>
-# endif
-# include <winable.h>
-#endif
-
-#include <oleacc.h>
-#if !defined(Q_CC_BOR) && !defined (Q_CC_GNU)
-#include <comdef.h>
-#endif
-
-#ifdef Q_WS_WINCE
-#include "qguifunctions_wince.h"
-#endif
-
-QT_BEGIN_NAMESPACE
-
-//#define DEBUG_SHOW_ATCLIENT_COMMANDS
-#ifdef DEBUG_SHOW_ATCLIENT_COMMANDS
-QT_BEGIN_INCLUDE_NAMESPACE
-#include <qdebug.h>
-QT_END_INCLUDE_NAMESPACE
-
-static const char *roleString(QAccessible::Role role)
-{
- static const char *roles[] = {
- "NoRole" /* = 0x00000000 */,
- "TitleBar" /* = 0x00000001 */,
- "MenuBar" /* = 0x00000002 */,
- "ScrollBar" /* = 0x00000003 */,
- "Grip" /* = 0x00000004 */,
- "Sound" /* = 0x00000005 */,
- "Cursor" /* = 0x00000006 */,
- "Caret" /* = 0x00000007 */,
- "AlertMessage" /* = 0x00000008 */,
- "Window" /* = 0x00000009 */,
- "Client" /* = 0x0000000A */,
- "PopupMenu" /* = 0x0000000B */,
- "MenuItem" /* = 0x0000000C */,
- "ToolTip" /* = 0x0000000D */,
- "Application" /* = 0x0000000E */,
- "Document" /* = 0x0000000F */,
- "Pane" /* = 0x00000010 */,
- "Chart" /* = 0x00000011 */,
- "Dialog" /* = 0x00000012 */,
- "Border" /* = 0x00000013 */,
- "Grouping" /* = 0x00000014 */,
- "Separator" /* = 0x00000015 */,
- "ToolBar" /* = 0x00000016 */,
- "StatusBar" /* = 0x00000017 */,
- "Table" /* = 0x00000018 */,
- "ColumnHeader" /* = 0x00000019 */,
- "RowHeader" /* = 0x0000001A */,
- "Column" /* = 0x0000001B */,
- "Row" /* = 0x0000001C */,
- "Cell" /* = 0x0000001D */,
- "Link" /* = 0x0000001E */,
- "HelpBalloon" /* = 0x0000001F */,
- "Assistant" /* = 0x00000020 */,
- "List" /* = 0x00000021 */,
- "ListItem" /* = 0x00000022 */,
- "Tree" /* = 0x00000023 */,
- "TreeItem" /* = 0x00000024 */,
- "PageTab" /* = 0x00000025 */,
- "PropertyPage" /* = 0x00000026 */,
- "Indicator" /* = 0x00000027 */,
- "Graphic" /* = 0x00000028 */,
- "StaticText" /* = 0x00000029 */,
- "EditableText" /* = 0x0000002A */, // Editable, selectable, etc.
- "PushButton" /* = 0x0000002B */,
- "CheckBox" /* = 0x0000002C */,
- "RadioButton" /* = 0x0000002D */,
- "ComboBox" /* = 0x0000002E */,
- "DropList" /* = 0x0000002F */, // commented out
- "ProgressBar" /* = 0x00000030 */,
- "Dial" /* = 0x00000031 */,
- "HotkeyField" /* = 0x00000032 */,
- "Slider" /* = 0x00000033 */,
- "SpinBox" /* = 0x00000034 */,
- "Canvas" /* = 0x00000035 */,
- "Animation" /* = 0x00000036 */,
- "Equation" /* = 0x00000037 */,
- "ButtonDropDown" /* = 0x00000038 */,
- "ButtonMenu" /* = 0x00000039 */,
- "ButtonDropGrid" /* = 0x0000003A */,
- "Whitespace" /* = 0x0000003B */,
- "PageTabList" /* = 0x0000003C */,
- "Clock" /* = 0x0000003D */,
- "Splitter" /* = 0x0000003E */,
- "LayeredPane" /* = 0x0000003F */,
- "UserRole" /* = 0x0000ffff*/
- };
-
- if (role >=0x40)
- role = QAccessible::UserRole;
- return roles[int(role)];
-}
-
-static const char *eventString(QAccessible::Event ev)
-{
- static const char *events[] = {
- "null", // 0
- "SoundPlayed" /*= 0x0001*/,
- "Alert" /*= 0x0002*/,
- "ForegroundChanged" /*= 0x0003*/,
- "MenuStart" /*= 0x0004*/,
- "MenuEnd" /*= 0x0005*/,
- "PopupMenuStart" /*= 0x0006*/,
- "PopupMenuEnd" /*= 0x0007*/,
- "ContextHelpStart" /*= 0x000C*/, // 8
- "ContextHelpEnd" /*= 0x000D*/,
- "DragDropStart" /*= 0x000E*/,
- "DragDropEnd" /*= 0x000F*/,
- "DialogStart" /*= 0x0010*/,
- "DialogEnd" /*= 0x0011*/,
- "ScrollingStart" /*= 0x0012*/,
- "ScrollingEnd" /*= 0x0013*/,
- "MenuCommand" /*= 0x0018*/, // 16
-
- // Values from IAccessible2
- "ActionChanged" /*= 0x0101*/, // 17
- "ActiveDescendantChanged",
- "AttributeChanged",
- "DocumentContentChanged",
- "DocumentLoadComplete",
- "DocumentLoadStopped",
- "DocumentReload",
- "HyperlinkEndIndexChanged",
- "HyperlinkNumberOfAnchorsChanged",
- "HyperlinkSelectedLinkChanged",
- "HypertextLinkActivated",
- "HypertextLinkSelected",
- "HyperlinkStartIndexChanged",
- "HypertextChanged",
- "HypertextNLinksChanged",
- "ObjectAttributeChanged",
- "PageChanged",
- "SectionChanged",
- "TableCaptionChanged",
- "TableColumnDescriptionChanged",
- "TableColumnHeaderChanged",
- "TableModelChanged",
- "TableRowDescriptionChanged",
- "TableRowHeaderChanged",
- "TableSummaryChanged",
- "TextAttributeChanged",
- "TextCaretMoved",
- // TextChanged, deprecated, use TextUpdated
- //TextColumnChanged = TextCaretMoved + 2,
- "TextInserted",
- "TextRemoved",
- "TextUpdated",
- "TextSelectionChanged",
- "VisibleDataChanged", /*= 0x0101+32*/
- "ObjectCreated" /*= 0x8000*/, // 49
- "ObjectDestroyed" /*= 0x8001*/,
- "ObjectShow" /*= 0x8002*/,
- "ObjectHide" /*= 0x8003*/,
- "ObjectReorder" /*= 0x8004*/,
- "Focus" /*= 0x8005*/,
- "Selection" /*= 0x8006*/,
- "SelectionAdd" /*= 0x8007*/,
- "SelectionRemove" /*= 0x8008*/,
- "SelectionWithin" /*= 0x8009*/,
- "StateChanged" /*= 0x800A*/,
- "LocationChanged" /*= 0x800B*/,
- "NameChanged" /*= 0x800C*/,
- "DescriptionChanged" /*= 0x800D*/,
- "ValueChanged" /*= 0x800E*/,
- "ParentChanged" /*= 0x800F*/,
- "HelpChanged" /*= 0x80A0*/,
- "DefaultActionChanged" /*= 0x80B0*/,
- "AcceleratorChanged" /*= 0x80C0*/
- };
- int e = int(ev);
- if (e <= 0x80c0) {
- const int last = sizeof(events)/sizeof(char*) - 1;
-
- if (e <= 0x07)
- return events[e];
- else if (e <= 0x13)
- return events[e - 0x0c + 8];
- else if (e == 0x18)
- return events[16];
- else if (e <= 0x0101 + 32)
- return events[e - 0x101 + 17];
- else if (e <= 0x800f)
- return events[e - 0x8000 + 49];
- else if (e == 0x80a0)
- return events[last - 2];
- else if (e == 0x80b0)
- return events[last - 1];
- else if (e == 0x80c0)
- return events[last];
- }
- return "unknown";
-};
-
-void showDebug(const char* funcName, const QAccessibleInterface *iface)
-{
- qDebug() << "Role:" << roleString(iface->role(0))
- << "Name:" << iface->text(QAccessible::Name, 0)
- << "State:" << QString::number(int(iface->state(0)), 16)
- << QLatin1String(funcName);
-}
-#else
-# define showDebug(f, iface)
-#endif
-
-// This stuff is used for widgets/items with no window handle:
-typedef QMap<int, QPair<QObject*,int> > NotifyMap;
-Q_GLOBAL_STATIC(NotifyMap, qAccessibleRecentSentEvents)
-static int eventNum = 0;
-
-
-void QAccessible::initialize()
-{
-
-}
-void QAccessible::cleanup()
-{
-
-}
-
-void QAccessible::updateAccessibility(QObject *o, int who, Event reason)
-{
- Q_ASSERT(o);
-
- if (updateHandler) {
- updateHandler(o, who, reason);
- return;
- }
-
- QString soundName;
- switch (reason) {
- case PopupMenuStart:
- soundName = QLatin1String("MenuPopup");
- break;
-
- case MenuCommand:
- soundName = QLatin1String("MenuCommand");
- break;
-
- case Alert:
- {
-#ifndef QT_NO_MESSAGEBOX
- QMessageBox *mb = qobject_cast<QMessageBox*>(o);
- if (mb) {
- switch (mb->icon()) {
- case QMessageBox::Warning:
- soundName = QLatin1String("SystemExclamation");
- break;
- case QMessageBox::Critical:
- soundName = QLatin1String("SystemHand");
- break;
- case QMessageBox::Information:
- soundName = QLatin1String("SystemAsterisk");
- break;
- default:
- break;
- }
- } else
-#endif // QT_NO_MESSAGEBOX
- {
- soundName = QLatin1String("SystemAsterisk");
- }
-
- }
- break;
- default:
- break;
- }
-
- if (soundName.size()) {
-#ifndef QT_NO_SETTINGS
- QSettings settings(QLatin1String("HKEY_CURRENT_USER\\AppEvents\\Schemes\\Apps\\.Default\\") + soundName,
- QSettings::NativeFormat);
- QString file = settings.value(QLatin1String(".Current/.")).toString();
-#else
- QString file;
-#endif
- if (!file.isEmpty()) {
- PlaySound(reinterpret_cast<const wchar_t *>(soundName.utf16()), 0, SND_ALIAS | SND_ASYNC | SND_NODEFAULT | SND_NOWAIT);
- }
- }
-
- if (!isActive())
- return;
-
- typedef void (WINAPI *PtrNotifyWinEvent)(DWORD, HWND, LONG, LONG);
-
-#if defined(Q_WS_WINCE) // ### TODO: check for NotifyWinEvent in CE 6.0
- // There is no user32.lib nor NotifyWinEvent for CE
- return;
-#else
- static PtrNotifyWinEvent ptrNotifyWinEvent = 0;
- static bool resolvedNWE = false;
- if (!resolvedNWE) {
- resolvedNWE = true;
- ptrNotifyWinEvent = (PtrNotifyWinEvent)QSystemLibrary::resolve(QLatin1String("user32"), "NotifyWinEvent");
- }
- if (!ptrNotifyWinEvent)
- return;
-
- // An event has to be associated with a window,
- // so find the first parent that is a widget.
- QWidget *w = 0;
- QObject *p = o;
- do {
- if (p->isWidgetType()) {
- w = static_cast<QWidget*>(p);
- if (w->internalWinId())
- break;
- }
- if (QGraphicsObject *gfxObj = qobject_cast<QGraphicsObject*>(p)) {
- QGraphicsItem *parentItem = gfxObj->parentItem();
- if (parentItem) {
- p = parentItem->toGraphicsObject();
- } else {
- QGraphicsView *view = 0;
- if (QGraphicsScene *scene = gfxObj->scene()) {
- QWidget *fw = QApplication::focusWidget();
- const QList<QGraphicsView*> views = scene->views();
- for (int i = 0 ; i < views.count() && view != fw; ++i) {
- view = views.at(i);
- }
- }
- p = view;
- }
- } else {
- p = p->parent();
- }
-
- } while (p);
-
- //qDebug() << "updateAccessibility(), hwnd:" << w << ", object:" << o << "," << eventString(reason);
- if (!w) {
- if (reason != QAccessible::ContextHelpStart &&
- reason != QAccessible::ContextHelpEnd)
- w = QApplication::focusWidget();
- if (!w) {
- w = QApplication::activeWindow();
-
- if (!w)
- return;
-
-// ### Fixme
-// if (!w) {
-// w = qApp->mainWidget();
-// if (!w)
-// return;
-// }
- }
- }
-
- WId wid = w->internalWinId();
- if (reason != MenuCommand) { // MenuCommand is faked
- if (w != o) {
- // See comment "SENDING EVENTS TO OBJECTS WITH NO WINDOW HANDLE"
- eventNum %= 50; //[0..49]
- int eventId = - eventNum - 1;
-
- qAccessibleRecentSentEvents()->insert(eventId, qMakePair(o,who));
- ptrNotifyWinEvent(reason, wid, OBJID_CLIENT, eventId );
-
- ++eventNum;
- } else {
- ptrNotifyWinEvent(reason, wid, OBJID_CLIENT, who);
- }
- }
-#endif // Q_WS_WINCE
-}
-
-/* == SENDING EVENTS TO OBJECTS WITH NO WINDOW HANDLE ==
-
- If the user requested to send the event to a widget with no window,
- we need to send an event to an object with no hwnd.
- The way we do that is to send it to the *first* ancestor widget
- with a window.
- Then we'll need a way of identifying the child:
- We'll just keep a list of the most recent events that we have sent,
- where each entry in the list is identified by a negative value
- between [-50,-1]. This negative value we will pass on to
- NotifyWinEvent() as the child id. When the negative value have
- reached -50, it will wrap around to -1. This seems to be enough
-
- Now, when the client receives that event, he will first call
- AccessibleObjectFromEvent() where dwChildID is the special
- negative value. AccessibleObjectFromEvent does two steps:
- 1. It will first sent a WM_GETOBJECT to the server, asking
- for the IAccessible interface for the HWND.
- 2. With the IAccessible interface it got hold of it will call
- acc_getChild where the child id argument is the special
- negative identifier. In our reimplementation of get_accChild
- we check for this if the child id is negative. If it is, then
- we'll look up in our table for the entry that is associated
- with that value.
- The entry will then contain a pointer to the QObject /QWidget
- that we can use to call queryAccessibleInterface() on.
-
-
- The following figure shows how the interaction between server and
- client is in the case when the server is sending an event.
-
-SERVER (Qt) | CLIENT |
---------------------------------------------+---------------------------------------+
- |
-acc->updateAccessibility(obj, childIndex) |
- |
-recentEvents()->insert(- 1 - eventNum, |
- qMakePair(obj, childIndex) |
-NotifyWinEvent(hwnd, childId) => |
- | AccessibleObjectFromEvent(event, hwnd, OBJID_CLIENT, childId )
- | will do:
- <=== 1. send WM_GETOBJECT(hwnd, OBJID_CLIENT)
-widget ~= hwnd
-iface = queryAccessibleInteface(widget)
-(create IAccessible interface wrapper for
- iface)
- return iface ===> IAccessible* iface; (for hwnd)
- |
- <=== call iface->get_accChild(childId)
-get_accChild() { |
- if (varChildID.lVal < 0) {
- QPair ref = recentEvents().value(varChildID.lVal);
- [...]
- }
-*/
-
-
-void QAccessible::setRootObject(QObject *o)
-{
- if (rootObjectHandler) {
- rootObjectHandler(o);
- }
-}
-
-class QWindowsEnumerate : public IEnumVARIANT
-{
-public:
- QWindowsEnumerate(const QVector<int> &a)
- : ref(0), current(0),array(a)
- {
- }
-
- virtual ~QWindowsEnumerate() {}
-
- HRESULT STDMETHODCALLTYPE QueryInterface(REFIID, LPVOID *);
- ULONG STDMETHODCALLTYPE AddRef();
- ULONG STDMETHODCALLTYPE Release();
-
- HRESULT STDMETHODCALLTYPE Clone(IEnumVARIANT **ppEnum);
- HRESULT STDMETHODCALLTYPE Next(unsigned long celt, VARIANT FAR* rgVar, unsigned long FAR* pCeltFetched);
- HRESULT STDMETHODCALLTYPE Reset();
- HRESULT STDMETHODCALLTYPE Skip(unsigned long celt);
-
-private:
- ULONG ref;
- ULONG current;
- QVector<int> array;
-};
-
-HRESULT STDMETHODCALLTYPE QWindowsEnumerate::QueryInterface(REFIID id, LPVOID *iface)
-{
- *iface = 0;
- if (id == IID_IUnknown)
- *iface = (IUnknown*)this;
- else if (id == IID_IEnumVARIANT)
- *iface = (IEnumVARIANT*)this;
-
- if (*iface) {
- AddRef();
- return S_OK;
- }
-
- return E_NOINTERFACE;
-}
-
-ULONG STDMETHODCALLTYPE QWindowsEnumerate::AddRef()
-{
- return ++ref;
-}
-
-ULONG STDMETHODCALLTYPE QWindowsEnumerate::Release()
-{
- if (!--ref) {
- delete this;
- return 0;
- }
- return ref;
-}
-
-HRESULT STDMETHODCALLTYPE QWindowsEnumerate::Clone(IEnumVARIANT **ppEnum)
-{
- QWindowsEnumerate *penum = 0;
- *ppEnum = 0;
-
- penum = new QWindowsEnumerate(array);
- if (!penum)
- return E_OUTOFMEMORY;
- penum->current = current;
- penum->array = array;
- penum->AddRef();
- *ppEnum = penum;
-
- return S_OK;
-}
-
-HRESULT STDMETHODCALLTYPE QWindowsEnumerate::Next(unsigned long celt, VARIANT FAR* rgVar, unsigned long FAR* pCeltFetched)
-{
- if (pCeltFetched)
- *pCeltFetched = 0;
-
- ULONG l;
- for (l = 0; l < celt; l++) {
- VariantInit(&rgVar[l]);
- if ((current+1) > (ULONG)array.size()) {
- *pCeltFetched = l;
- return S_FALSE;
- }
-
- rgVar[l].vt = VT_I4;
- rgVar[l].lVal = array[(int)current];
- ++current;
- }
- *pCeltFetched = l;
- return S_OK;
-}
-
-HRESULT STDMETHODCALLTYPE QWindowsEnumerate::Reset()
-{
- current = 0;
- return S_OK;
-}
-
-HRESULT STDMETHODCALLTYPE QWindowsEnumerate::Skip(unsigned long celt)
-{
- current += celt;
- if (current > (ULONG)array.size()) {
- current = array.size();
- return S_FALSE;
- }
- return S_OK;
-}
-
-/*
-*/
-class QWindowsAccessible : public IAccessible, IOleWindow, QAccessible
-{
-public:
- QWindowsAccessible(QAccessibleInterface *a)
- : ref(0), accessible(a)
- {
- }
-
- virtual ~QWindowsAccessible()
- {
- delete accessible;
- }
-
- /* IUnknown */
- HRESULT STDMETHODCALLTYPE QueryInterface(REFIID, LPVOID *);
- ULONG STDMETHODCALLTYPE AddRef();
- ULONG STDMETHODCALLTYPE Release();
-
- /* IDispatch */
- HRESULT STDMETHODCALLTYPE GetTypeInfoCount(unsigned int *);
- HRESULT STDMETHODCALLTYPE GetTypeInfo(unsigned int, unsigned long, ITypeInfo **);
- HRESULT STDMETHODCALLTYPE GetIDsOfNames(const _GUID &, wchar_t **, unsigned int, unsigned long, long *);
- HRESULT STDMETHODCALLTYPE Invoke(long, const _GUID &, unsigned long, unsigned short, tagDISPPARAMS *, tagVARIANT *, tagEXCEPINFO *, unsigned int *);
-
- /* IAccessible */
- HRESULT STDMETHODCALLTYPE accHitTest(long xLeft, long yTop, VARIANT *pvarID);
- HRESULT STDMETHODCALLTYPE accLocation(long *pxLeft, long *pyTop, long *pcxWidth, long *pcyHeight, VARIANT varID);
- HRESULT STDMETHODCALLTYPE accNavigate(long navDir, VARIANT varStart, VARIANT *pvarEnd);
- HRESULT STDMETHODCALLTYPE get_accChild(VARIANT varChildID, IDispatch** ppdispChild);
- HRESULT STDMETHODCALLTYPE get_accChildCount(long* pcountChildren);
- HRESULT STDMETHODCALLTYPE get_accParent(IDispatch** ppdispParent);
-
- HRESULT STDMETHODCALLTYPE accDoDefaultAction(VARIANT varID);
- HRESULT STDMETHODCALLTYPE get_accDefaultAction(VARIANT varID, BSTR* pszDefaultAction);
- HRESULT STDMETHODCALLTYPE get_accDescription(VARIANT varID, BSTR* pszDescription);
- HRESULT STDMETHODCALLTYPE get_accHelp(VARIANT varID, BSTR *pszHelp);
- HRESULT STDMETHODCALLTYPE get_accHelpTopic(BSTR *pszHelpFile, VARIANT varChild, long *pidTopic);
- HRESULT STDMETHODCALLTYPE get_accKeyboardShortcut(VARIANT varID, BSTR *pszKeyboardShortcut);
- HRESULT STDMETHODCALLTYPE get_accName(VARIANT varID, BSTR* pszName);
- HRESULT STDMETHODCALLTYPE put_accName(VARIANT varChild, BSTR szName);
- HRESULT STDMETHODCALLTYPE get_accRole(VARIANT varID, VARIANT *pvarRole);
- HRESULT STDMETHODCALLTYPE get_accState(VARIANT varID, VARIANT *pvarState);
- HRESULT STDMETHODCALLTYPE get_accValue(VARIANT varID, BSTR* pszValue);
- HRESULT STDMETHODCALLTYPE put_accValue(VARIANT varChild, BSTR szValue);
-
- HRESULT STDMETHODCALLTYPE accSelect(long flagsSelect, VARIANT varID);
- HRESULT STDMETHODCALLTYPE get_accFocus(VARIANT *pvarID);
- HRESULT STDMETHODCALLTYPE get_accSelection(VARIANT *pvarChildren);
-
- /* IOleWindow */
- HRESULT STDMETHODCALLTYPE GetWindow(HWND *phwnd);
- HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL fEnterMode);
-
-private:
- ULONG ref;
- QAccessibleInterface *accessible;
-};
-
-static inline BSTR QStringToBSTR(const QString &str)
-{
- BSTR bstrVal;
-
- int wlen = str.length()+1;
- bstrVal = SysAllocStringByteLen(0, wlen*2);
- memcpy(bstrVal, str.unicode(), sizeof(QChar)*(wlen));
- bstrVal[wlen] = 0;
-
- return bstrVal;
-}
-
-/*
-*/
-IAccessible *qt_createWindowsAccessible(QAccessibleInterface *access)
-{
- QWindowsAccessible *acc = new QWindowsAccessible(access);
- IAccessible *iface;
- acc->QueryInterface(IID_IAccessible, (void**)&iface);
-
- return iface;
-}
-
-/*
- IUnknown
-*/
-HRESULT STDMETHODCALLTYPE QWindowsAccessible::QueryInterface(REFIID id, LPVOID *iface)
-{
- *iface = 0;
- if (id == IID_IUnknown)
- *iface = (IUnknown*)(IDispatch*)this;
- else if (id == IID_IDispatch)
- *iface = (IDispatch*)this;
- else if (id == IID_IAccessible)
- *iface = (IAccessible*)this;
- else if (id == IID_IOleWindow)
- *iface = (IOleWindow*)this;
- else
- return E_NOINTERFACE;
-
- AddRef();
- return S_OK;
-}
-
-ULONG STDMETHODCALLTYPE QWindowsAccessible::AddRef()
-{
- return ++ref;
-}
-
-ULONG STDMETHODCALLTYPE QWindowsAccessible::Release()
-{
- if (!--ref) {
- delete this;
- return 0;
- }
- return ref;
-}
-
-/*
- IDispatch
-*/
-
-HRESULT STDMETHODCALLTYPE QWindowsAccessible::GetTypeInfoCount(unsigned int * pctinfo)
-{
- // We don't use a type library
- *pctinfo = 0;
- return S_OK;
-}
-
-HRESULT STDMETHODCALLTYPE QWindowsAccessible::GetTypeInfo(unsigned int, unsigned long, ITypeInfo **pptinfo)
-{
- // We don't use a type library
- *pptinfo = 0;
- return S_OK;
-}
-
-HRESULT STDMETHODCALLTYPE QWindowsAccessible::GetIDsOfNames(const _GUID &, wchar_t **rgszNames, unsigned int, unsigned long, long *rgdispid)
-{
-#if !defined(Q_CC_BOR) && !defined(Q_CC_GNU)
- // PROPERTIES: Hierarchical
- if (_bstr_t(rgszNames[0]) == _bstr_t(L"accParent"))
- rgdispid[0] = DISPID_ACC_PARENT;
- else if(_bstr_t(rgszNames[0]) == _bstr_t(L"accChildCount"))
- rgdispid[0] = DISPID_ACC_CHILDCOUNT;
- else if(_bstr_t(rgszNames[0]) == _bstr_t(L"accChild"))
- rgdispid[0] = DISPID_ACC_CHILD;
-
- // PROPERTIES: Descriptional
- else if(_bstr_t(rgszNames[0]) == _bstr_t(L"accName("))
- rgdispid[0] = DISPID_ACC_NAME;
- else if(_bstr_t(rgszNames[0]) == _bstr_t(L"accValue"))
- rgdispid[0] = DISPID_ACC_VALUE;
- else if(_bstr_t(rgszNames[0]) == _bstr_t(L"accDescription"))
- rgdispid[0] = DISPID_ACC_DESCRIPTION;
- else if(_bstr_t(rgszNames[0]) == _bstr_t(L"accRole"))
- rgdispid[0] = DISPID_ACC_ROLE;
- else if(_bstr_t(rgszNames[0]) == _bstr_t(L"accState"))
- rgdispid[0] = DISPID_ACC_STATE;
- else if(_bstr_t(rgszNames[0]) == _bstr_t(L"accHelp"))
- rgdispid[0] = DISPID_ACC_HELP;
- else if(_bstr_t(rgszNames[0]) == _bstr_t(L"accHelpTopic"))
- rgdispid[0] = DISPID_ACC_HELPTOPIC;
- else if(_bstr_t(rgszNames[0]) == _bstr_t(L"accKeyboardShortcut"))
- rgdispid[0] = DISPID_ACC_KEYBOARDSHORTCUT;
- else if(_bstr_t(rgszNames[0]) == _bstr_t(L"accFocus"))
- rgdispid[0] = DISPID_ACC_FOCUS;
- else if(_bstr_t(rgszNames[0]) == _bstr_t(L"accSelection"))
- rgdispid[0] = DISPID_ACC_SELECTION;
- else if(_bstr_t(rgszNames[0]) == _bstr_t(L"accDefaultAction"))
- rgdispid[0] = DISPID_ACC_DEFAULTACTION;
-
- // METHODS
- else if(_bstr_t(rgszNames[0]) == _bstr_t(L"accSelect"))
- rgdispid[0] = DISPID_ACC_SELECT;
- else if(_bstr_t(rgszNames[0]) == _bstr_t(L"accLocation"))
- rgdispid[0] = DISPID_ACC_LOCATION;
- else if(_bstr_t(rgszNames[0]) == _bstr_t(L"accNavigate"))
- rgdispid[0] = DISPID_ACC_NAVIGATE;
- else if(_bstr_t(rgszNames[0]) == _bstr_t(L"accHitTest"))
- rgdispid[0] = DISPID_ACC_HITTEST;
- else if(_bstr_t(rgszNames[0]) == _bstr_t(L"accDoDefaultAction"))
- rgdispid[0] = DISPID_ACC_DODEFAULTACTION;
- else
- return DISP_E_UNKNOWNINTERFACE;
-
- return S_OK;
-#else
- Q_UNUSED(rgszNames);
- Q_UNUSED(rgdispid);
-
- return DISP_E_MEMBERNOTFOUND;
-#endif
-}
-
-HRESULT STDMETHODCALLTYPE QWindowsAccessible::Invoke(long dispIdMember, const _GUID &, unsigned long, unsigned short wFlags, tagDISPPARAMS *pDispParams, tagVARIANT *pVarResult, tagEXCEPINFO *, unsigned int *)
-{
- HRESULT hr = DISP_E_MEMBERNOTFOUND;
-
- switch(dispIdMember)
- {
- case DISPID_ACC_PARENT:
- if (wFlags == DISPATCH_PROPERTYGET) {
- if (!pVarResult)
- return E_INVALIDARG;
- hr = get_accParent(&pVarResult->pdispVal);
- } else {
- hr = DISP_E_MEMBERNOTFOUND;
- }
- break;
-
- case DISPID_ACC_CHILDCOUNT:
- if (wFlags == DISPATCH_PROPERTYGET) {
- if (!pVarResult)
- return E_INVALIDARG;
- hr = get_accChildCount(&pVarResult->lVal);
- } else {
- hr = DISP_E_MEMBERNOTFOUND;
- }
- break;
-
- case DISPID_ACC_CHILD:
- if (wFlags == DISPATCH_PROPERTYGET)
- hr = get_accChild(pDispParams->rgvarg[0], &pVarResult->pdispVal);
- else
- hr = DISP_E_MEMBERNOTFOUND;
- break;
-
- case DISPID_ACC_NAME:
- if (wFlags == DISPATCH_PROPERTYGET)
- hr = get_accName(pDispParams->rgvarg[0], &pVarResult->bstrVal);
- else if (wFlags == DISPATCH_PROPERTYPUT)
- hr = put_accName(pDispParams->rgvarg[0], pVarResult->bstrVal);
- else
- hr = DISP_E_MEMBERNOTFOUND;
- break;
-
- case DISPID_ACC_VALUE:
- if (wFlags == DISPATCH_PROPERTYGET)
- hr = get_accValue(pDispParams->rgvarg[0], &pVarResult->bstrVal);
- else if (wFlags == DISPATCH_PROPERTYPUT)
- hr = put_accValue(pDispParams->rgvarg[0], pVarResult->bstrVal);
- else
- hr = DISP_E_MEMBERNOTFOUND;
- break;
-
- case DISPID_ACC_DESCRIPTION:
- if (wFlags == DISPATCH_PROPERTYGET)
- hr = get_accDescription(pDispParams->rgvarg[0], &pVarResult->bstrVal);
- else
- hr = DISP_E_MEMBERNOTFOUND;
- break;
-
- case DISPID_ACC_ROLE:
- if (wFlags == DISPATCH_PROPERTYGET)
- hr = get_accRole(pDispParams->rgvarg[0], pVarResult);
- else
- hr = DISP_E_MEMBERNOTFOUND;
- break;
-
- case DISPID_ACC_STATE:
- if (wFlags == DISPATCH_PROPERTYGET)
- hr = get_accState(pDispParams->rgvarg[0], pVarResult);
- else
- hr = DISP_E_MEMBERNOTFOUND;
- break;
-
- case DISPID_ACC_HELP:
- if (wFlags == DISPATCH_PROPERTYGET)
- hr = get_accHelp(pDispParams->rgvarg[0], &pVarResult->bstrVal);
- else
- hr = DISP_E_MEMBERNOTFOUND;
- break;
-
- case DISPID_ACC_HELPTOPIC:
- if (wFlags == DISPATCH_PROPERTYGET)
- hr = get_accHelpTopic(&pDispParams->rgvarg[2].bstrVal, pDispParams->rgvarg[1], &pDispParams->rgvarg[0].lVal);
- else
- hr = DISP_E_MEMBERNOTFOUND;
- break;
-
- case DISPID_ACC_KEYBOARDSHORTCUT:
- if (wFlags == DISPATCH_PROPERTYGET)
- hr = get_accKeyboardShortcut(pDispParams->rgvarg[0], &pVarResult->bstrVal);
- else
- hr = DISP_E_MEMBERNOTFOUND;
- break;
-
- case DISPID_ACC_FOCUS:
- if (wFlags == DISPATCH_PROPERTYGET)
- hr = get_accFocus(pVarResult);
- else
- hr = DISP_E_MEMBERNOTFOUND;
- break;
-
- case DISPID_ACC_SELECTION:
- if (wFlags == DISPATCH_PROPERTYGET)
- hr = get_accSelection(pVarResult);
- else
- hr = DISP_E_MEMBERNOTFOUND;
- break;
-
- case DISPID_ACC_DEFAULTACTION:
- if (wFlags == DISPATCH_PROPERTYGET)
- hr = get_accDefaultAction(pDispParams->rgvarg[0], &pVarResult->bstrVal);
- else
- hr = DISP_E_MEMBERNOTFOUND;
- break;
-
- case DISPID_ACC_SELECT:
- if (wFlags == DISPATCH_METHOD)
- hr = accSelect(pDispParams->rgvarg[1].lVal, pDispParams->rgvarg[0]);
- else
- hr = DISP_E_MEMBERNOTFOUND;
- break;
-
- case DISPID_ACC_LOCATION:
- if (wFlags == DISPATCH_METHOD)
- hr = accLocation(&pDispParams->rgvarg[4].lVal, &pDispParams->rgvarg[3].lVal, &pDispParams->rgvarg[2].lVal, &pDispParams->rgvarg[1].lVal, pDispParams->rgvarg[0]);
- else
- hr = DISP_E_MEMBERNOTFOUND;
- break;
-
- case DISPID_ACC_NAVIGATE:
- if (wFlags == DISPATCH_METHOD)
- hr = accNavigate(pDispParams->rgvarg[1].lVal, pDispParams->rgvarg[0], pVarResult);
- else
- hr = DISP_E_MEMBERNOTFOUND;
- break;
-
- case DISPID_ACC_HITTEST:
- if (wFlags == DISPATCH_METHOD)
- hr = accHitTest(pDispParams->rgvarg[1].lVal, pDispParams->rgvarg[0].lVal, pVarResult);
- else
- hr = DISP_E_MEMBERNOTFOUND;
- break;
-
- case DISPID_ACC_DODEFAULTACTION:
- if (wFlags == DISPATCH_METHOD)
- hr = accDoDefaultAction(pDispParams->rgvarg[0]);
- else
- hr = DISP_E_MEMBERNOTFOUND;
- break;
-
- default:
- hr = DISP_E_MEMBERNOTFOUND;
- break;
- }
-
- if (!SUCCEEDED(hr)) {
- return hr;
- }
- return hr;
-}
-
-/*
- IAccessible
-*/
-HRESULT STDMETHODCALLTYPE QWindowsAccessible::accHitTest(long xLeft, long yTop, VARIANT *pvarID)
-{
- showDebug(__FUNCTION__, accessible);
- if (!accessible->isValid())
- return E_FAIL;
-
- int control = accessible->childAt(xLeft, yTop);
- if (control == -1) {
- (*pvarID).vt = VT_EMPTY;
- return S_FALSE;
- }
- QAccessibleInterface *acc = 0;
- if (control)
- accessible->navigate(Child, control, &acc);
- if (!acc) {
- (*pvarID).vt = VT_I4;
- (*pvarID).lVal = control;
- return S_OK;
- }
-
- QWindowsAccessible* wacc = new QWindowsAccessible(acc);
- IDispatch *iface = 0;
- wacc->QueryInterface(IID_IDispatch, (void**)&iface);
- if (iface) {
- (*pvarID).vt = VT_DISPATCH;
- (*pvarID).pdispVal = iface;
- return S_OK;
- } else {
- delete wacc;
- }
-
- (*pvarID).vt = VT_EMPTY;
- return S_FALSE;
-}
-
-HRESULT STDMETHODCALLTYPE QWindowsAccessible::accLocation(long *pxLeft, long *pyTop, long *pcxWidth, long *pcyHeight, VARIANT varID)
-{
- showDebug(__FUNCTION__, accessible);
- if (!accessible->isValid())
- return E_FAIL;
-
- QRect rect = accessible->rect(varID.lVal);
- if (rect.isValid()) {
- *pxLeft = rect.x();
- *pyTop = rect.y();
- *pcxWidth = rect.width();
- *pcyHeight = rect.height();
- } else {
- *pxLeft = 0;
- *pyTop = 0;
- *pcxWidth = 0;
- *pcyHeight = 0;
- }
- return S_OK;
-}
-
-HRESULT STDMETHODCALLTYPE QWindowsAccessible::accNavigate(long navDir, VARIANT varStart, VARIANT *pvarEnd)
-{
- showDebug(__FUNCTION__, accessible);
- if (!accessible->isValid())
- return E_FAIL;
-
- QAccessibleInterface *acc = 0;
- int control = -1;
- switch(navDir) {
- case NAVDIR_FIRSTCHILD:
- control = accessible->navigate(Child, 1, &acc);
- break;
- case NAVDIR_LASTCHILD:
- control = accessible->navigate(Child, accessible->childCount(), &acc);
- break;
- case NAVDIR_NEXT:
- case NAVDIR_PREVIOUS:
- if (!varStart.lVal){
- QAccessibleInterface *parent = 0;
- accessible->navigate(Ancestor, 1, &parent);
- if (parent) {
- int index = parent->indexOfChild(accessible);
- index += (navDir == NAVDIR_NEXT) ? 1 : -1;
- if (index > 0 && index <= parent->childCount())
- control = parent->navigate(Child, index, &acc);
- delete parent;
- }
- } else {
- int index = varStart.lVal;
- index += (navDir == NAVDIR_NEXT) ? 1 : -1;
- if (index > 0 && index <= accessible->childCount())
- control = accessible->navigate(Child, index, &acc);
- }
- break;
- case NAVDIR_UP:
- control = accessible->navigate(Up, varStart.lVal, &acc);
- break;
- case NAVDIR_DOWN:
- control = accessible->navigate(Down, varStart.lVal, &acc);
- break;
- case NAVDIR_LEFT:
- control = accessible->navigate(Left, varStart.lVal, &acc);
- break;
- case NAVDIR_RIGHT:
- control = accessible->navigate(Right, varStart.lVal, &acc);
- break;
- default:
- break;
- }
- if (control == -1) {
- (*pvarEnd).vt = VT_EMPTY;
- return S_FALSE;
- }
- if (!acc) {
- (*pvarEnd).vt = VT_I4;
- (*pvarEnd).lVal = control;
- return S_OK;
- }
-
- QWindowsAccessible* wacc = new QWindowsAccessible(acc);
-
- IDispatch *iface = 0;
- wacc->QueryInterface(IID_IDispatch, (void**)&iface);
- if (iface) {
- (*pvarEnd).vt = VT_DISPATCH;
- (*pvarEnd).pdispVal = iface;
- return S_OK;
- } else {
- delete wacc;
- }
-
- (*pvarEnd).vt = VT_EMPTY;
- return S_FALSE;
-}
-
-HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accChild(VARIANT varChildID, IDispatch** ppdispChild)
-{
- showDebug(__FUNCTION__, accessible);
- if (!accessible->isValid())
- return E_FAIL;
-
- if (varChildID.vt == VT_EMPTY)
- return E_INVALIDARG;
-
-
- int childIndex = varChildID.lVal;
- QAccessibleInterface *acc = 0;
-
- if (childIndex < 0) {
- const int entry = childIndex;
- QPair<QObject*, int> ref = qAccessibleRecentSentEvents()->value(entry);
- if (ref.first) {
- acc = queryAccessibleInterface(ref.first);
- if (acc && ref.second) {
- if (ref.second) {
- QAccessibleInterface *res;
- int index = acc->navigate(Child, ref.second, &res);
- delete acc;
- if (index == -1)
- return E_INVALIDARG;
- acc = res;
- }
- }
- }
- } else {
- RelationFlag rel = childIndex ? Child : Self;
- accessible->navigate(rel, childIndex, &acc);
- }
-
- if (acc) {
- QWindowsAccessible* wacc = new QWindowsAccessible(acc);
- wacc->QueryInterface(IID_IDispatch, (void**)ppdispChild);
- return S_OK;
- }
-
- *ppdispChild = 0;
- return S_FALSE;
-}
-
-HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accChildCount(long* pcountChildren)
-{
- showDebug(__FUNCTION__, accessible);
- if (!accessible->isValid())
- return E_FAIL;
-
- *pcountChildren = accessible->childCount();
- return S_OK;
-}
-
-HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accParent(IDispatch** ppdispParent)
-{
- showDebug(__FUNCTION__, accessible);
- if (!accessible->isValid())
- return E_FAIL;
-
- QAccessibleInterface *acc = 0;
- accessible->navigate(Ancestor, 1, &acc);
- if (acc) {
- QWindowsAccessible* wacc = new QWindowsAccessible(acc);
- wacc->QueryInterface(IID_IDispatch, (void**)ppdispParent);
-
- if (*ppdispParent)
- return S_OK;
- }
-
- *ppdispParent = 0;
- return S_FALSE;
-}
-
-/*
- Properties and methods
-*/
-HRESULT STDMETHODCALLTYPE QWindowsAccessible::accDoDefaultAction(VARIANT varID)
-{
- showDebug(__FUNCTION__, accessible);
- if (!accessible->isValid())
- return E_FAIL;
-
- return accessible->doAction(DefaultAction, varID.lVal, QVariantList()) ? S_OK : S_FALSE;
-}
-
-HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accDefaultAction(VARIANT varID, BSTR* pszDefaultAction)
-{
- showDebug(__FUNCTION__, accessible);
- if (!accessible->isValid())
- return E_FAIL;
-
- QString def = accessible->actionText(DefaultAction, Name, varID.lVal);
- if (def.isEmpty()) {
- *pszDefaultAction = 0;
- return S_FALSE;
- }
-
- *pszDefaultAction = QStringToBSTR(def);
- return S_OK;
-}
-
-HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accDescription(VARIANT varID, BSTR* pszDescription)
-{
- showDebug(__FUNCTION__, accessible);
- if (!accessible->isValid())
- return E_FAIL;
-
- QString descr = accessible->text(Description, varID.lVal);
- if (descr.size()) {
- *pszDescription = QStringToBSTR(descr);
- return S_OK;
- }
-
- *pszDescription = 0;
- return S_FALSE;
-}
-
-HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accHelp(VARIANT varID, BSTR *pszHelp)
-{
- showDebug(__FUNCTION__, accessible);
- if (!accessible->isValid())
- return E_FAIL;
-
- QString help = accessible->text(Help, varID.lVal);
- if (help.size()) {
- *pszHelp = QStringToBSTR(help);
- return S_OK;
- }
-
- *pszHelp = 0;
- return S_FALSE;
-}
-
-HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accHelpTopic(BSTR *, VARIANT, long *)
-{
- return DISP_E_MEMBERNOTFOUND;
-}
-
-HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accKeyboardShortcut(VARIANT varID, BSTR *pszKeyboardShortcut)
-{
- showDebug(__FUNCTION__, accessible);
- if (!accessible->isValid())
- return E_FAIL;
-
- QString sc = accessible->text(Accelerator, varID.lVal);
- if (sc.size()) {
- *pszKeyboardShortcut = QStringToBSTR(sc);
- return S_OK;
- }
-
- *pszKeyboardShortcut = 0;
- return S_FALSE;
-}
-
-HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accName(VARIANT varID, BSTR* pszName)
-{
- showDebug(__FUNCTION__, accessible);
- if (!accessible->isValid())
- return E_FAIL;
-
- QString n = accessible->text(Name, varID.lVal);
- if (n.size()) {
- *pszName = QStringToBSTR(n);
- return S_OK;
- }
-
- *pszName = 0;
- return S_FALSE;
-}
-
-HRESULT STDMETHODCALLTYPE QWindowsAccessible::put_accName(VARIANT, BSTR)
-{
- showDebug(__FUNCTION__, accessible);
- return DISP_E_MEMBERNOTFOUND;
-}
-
-HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accRole(VARIANT varID, VARIANT *pvarRole)
-{
- showDebug(__FUNCTION__, accessible);
- if (!accessible->isValid())
- return E_FAIL;
-
- Role role = accessible->role(varID.lVal);
- if (role != NoRole) {
- if (role == LayeredPane)
- role = QAccessible::Pane;
- (*pvarRole).vt = VT_I4;
- (*pvarRole).lVal = role;
- } else {
- (*pvarRole).vt = VT_EMPTY;
- }
- return S_OK;
-}
-
-HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accState(VARIANT varID, VARIANT *pvarState)
-{
- showDebug(__FUNCTION__, accessible);
- if (!accessible->isValid())
- return E_FAIL;
-
- (*pvarState).vt = VT_I4;
- (*pvarState).lVal = accessible->state(varID.lVal);
- return S_OK;
-}
-
-HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accValue(VARIANT varID, BSTR* pszValue)
-{
- showDebug(__FUNCTION__, accessible);
- if (!accessible->isValid())
- return E_FAIL;
-
- QString value = accessible->text(Value, varID.lVal);
- if (!value.isNull()) {
- *pszValue = QStringToBSTR(value);
- return S_OK;
- }
-
- *pszValue = 0;
- return S_FALSE;
-}
-
-HRESULT STDMETHODCALLTYPE QWindowsAccessible::put_accValue(VARIANT, BSTR)
-{
- showDebug(__FUNCTION__, accessible);
- return DISP_E_MEMBERNOTFOUND;
-}
-
-HRESULT STDMETHODCALLTYPE QWindowsAccessible::accSelect(long flagsSelect, VARIANT varID)
-{
- showDebug(__FUNCTION__, accessible);
- if (!accessible->isValid())
- return E_FAIL;
-
- bool res = false;
-
- if (flagsSelect & SELFLAG_TAKEFOCUS)
- res = accessible->doAction(SetFocus, varID.lVal, QVariantList());
- if (flagsSelect & SELFLAG_TAKESELECTION) {
- accessible->doAction(ClearSelection, 0, QVariantList());
- res = accessible->doAction(AddToSelection, varID.lVal, QVariantList());
- }
- if (flagsSelect & SELFLAG_EXTENDSELECTION)
- res = accessible->doAction(ExtendSelection, varID.lVal, QVariantList());
- if (flagsSelect & SELFLAG_ADDSELECTION)
- res = accessible->doAction(AddToSelection, varID.lVal, QVariantList());
- if (flagsSelect & SELFLAG_REMOVESELECTION)
- res = accessible->doAction(RemoveSelection, varID.lVal, QVariantList());
-
- return res ? S_OK : S_FALSE;
-}
-
-HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accFocus(VARIANT *pvarID)
-{
- showDebug(__FUNCTION__, accessible);
- if (!accessible->isValid())
- return E_FAIL;
-
- QAccessibleInterface *acc = 0;
- int control = accessible->navigate(FocusChild, 1, &acc);
- if (control == -1) {
- (*pvarID).vt = VT_EMPTY;
- return S_FALSE;
- }
- if (!acc || control == 0) {
- (*pvarID).vt = VT_I4;
- (*pvarID).lVal = control ? control : CHILDID_SELF;
- return S_OK;
- }
-
- QWindowsAccessible* wacc = new QWindowsAccessible(acc);
- IDispatch *iface = 0;
- wacc->QueryInterface(IID_IDispatch, (void**)&iface);
- if (iface) {
- (*pvarID).vt = VT_DISPATCH;
- (*pvarID).pdispVal = iface;
- return S_OK;
- } else {
- delete wacc;
- }
-
- (*pvarID).vt = VT_EMPTY;
- return S_FALSE;
-}
-
-HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accSelection(VARIANT *pvarChildren)
-{
- showDebug(__FUNCTION__, accessible);
- if (!accessible->isValid())
- return E_FAIL;
-
- int cc = accessible->childCount();
- QVector<int> sel(cc);
- int selIndex = 0;
- for (int i = 1; i <= cc; ++i) {
- QAccessibleInterface *child = 0;
- int i2 = accessible->navigate(Child, i, &child);
- bool isSelected = false;
- if (child) {
- isSelected = child->state(0) & Selected;
- delete child;
- child = 0;
- } else {
- isSelected = accessible->state(i2) & Selected;
- }
- if (isSelected)
- sel[selIndex++] = i;
- }
- sel.resize(selIndex);
- if (sel.isEmpty()) {
- (*pvarChildren).vt = VT_EMPTY;
- return S_FALSE;
- }
- if (sel.size() == 1) {
- (*pvarChildren).vt = VT_I4;
- (*pvarChildren).lVal = sel[0];
- return S_OK;
- }
- IEnumVARIANT *iface = new QWindowsEnumerate(sel);
- IUnknown *uiface;
- iface->QueryInterface(IID_IUnknown, (void**)&uiface);
- (*pvarChildren).vt = VT_UNKNOWN;
- (*pvarChildren).punkVal = uiface;
-
- return S_OK;
-}
-
-HRESULT STDMETHODCALLTYPE QWindowsAccessible::GetWindow(HWND *phwnd)
-{
- *phwnd = 0;
- if (!accessible->isValid())
- return E_UNEXPECTED;
-
- QObject *o = accessible->object();
- if (!o || !o->isWidgetType())
- return E_FAIL;
-
- *phwnd = static_cast<QWidget*>(o)->effectiveWinId();
- return S_OK;
-}
-
-HRESULT STDMETHODCALLTYPE QWindowsAccessible::ContextSensitiveHelp(BOOL)
-{
- return S_OK;
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_ACCESSIBILITY
diff --git a/src/gui/accessible/qaccessiblebridge.h b/src/gui/accessible/qaccessiblebridge.h
deleted file mode 100644
index 73edf51183..0000000000
--- a/src/gui/accessible/qaccessiblebridge.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QACCESSIBLEBRIDGE_H
-#define QACCESSIBLEBRIDGE_H
-
-#include <QtCore/qplugin.h>
-#include <QtCore/qfactoryinterface.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_ACCESSIBILITY
-
-class QAccessibleInterface;
-
-class QAccessibleBridge
-{
-public:
- virtual ~QAccessibleBridge() {}
- virtual void setRootObject(QAccessibleInterface *) = 0;
- virtual void notifyAccessibilityUpdate(int, QAccessibleInterface*, int) = 0;
-};
-
-struct Q_GUI_EXPORT QAccessibleBridgeFactoryInterface : public QFactoryInterface
-{
- virtual QAccessibleBridge *create(const QString& name) = 0;
-};
-
-#define QAccessibleBridgeFactoryInterface_iid "com.trolltech.Qt.QAccessibleBridgeFactoryInterface"
-Q_DECLARE_INTERFACE(QAccessibleBridgeFactoryInterface, QAccessibleBridgeFactoryInterface_iid)
-
-class Q_GUI_EXPORT QAccessibleBridgePlugin : public QObject, public QAccessibleBridgeFactoryInterface
-{
- Q_OBJECT
- Q_INTERFACES(QAccessibleBridgeFactoryInterface:QFactoryInterface)
-public:
- explicit QAccessibleBridgePlugin(QObject *parent = 0);
- ~QAccessibleBridgePlugin();
-
- virtual QStringList keys() const = 0;
- virtual QAccessibleBridge *create(const QString &key) = 0;
-};
-
-#endif // QT_NO_ACCESSIBILITY
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QACCESSIBLEBRIDGE_H
diff --git a/src/gui/accessible/qaccessibleobject.h b/src/gui/accessible/qaccessibleobject.h
deleted file mode 100644
index 8ebd285a6f..0000000000
--- a/src/gui/accessible/qaccessibleobject.h
+++ /dev/null
@@ -1,140 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QACCESSIBLEOBJECT_H
-#define QACCESSIBLEOBJECT_H
-
-#include <QtGui/qaccessible.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_ACCESSIBILITY
-
-class QAccessibleObjectPrivate;
-class QObject;
-
-class Q_GUI_EXPORT QAccessibleObject : public QAccessibleInterface
-{
-public:
- explicit QAccessibleObject(QObject *object);
-
- bool isValid() const;
- QObject *object() const;
-
- // properties
- QRect rect(int child) const;
- void setText(Text t, int child, const QString &text);
-
- // actions
- int userActionCount(int child) const;
- bool doAction(int action, int child, const QVariantList &params);
- QString actionText(int action, Text t, int child) const;
-
-protected:
- virtual ~QAccessibleObject();
-
-private:
- friend class QAccessibleObjectEx;
- QAccessibleObjectPrivate *d;
- Q_DISABLE_COPY(QAccessibleObject)
-};
-
-class Q_GUI_EXPORT QAccessibleObjectEx : public QAccessibleInterfaceEx
-{
-public:
- explicit QAccessibleObjectEx(QObject *object);
-
- bool isValid() const;
- QObject *object() const;
-
- // properties
- QRect rect(int child) const;
- void setText(Text t, int child, const QString &text);
-
- // actions
- int userActionCount(int child) const;
- bool doAction(int action, int child, const QVariantList &params);
- QString actionText(int action, Text t, int child) const;
-
-protected:
- virtual ~QAccessibleObjectEx();
-
-private:
- QAccessibleObjectPrivate *d;
- Q_DISABLE_COPY(QAccessibleObjectEx)
-};
-
-class Q_GUI_EXPORT QAccessibleApplication : public QAccessibleObject
-{
-public:
- QAccessibleApplication();
-
- // relations
- int childCount() const;
- int indexOfChild(const QAccessibleInterface*) const;
- Relation relationTo(int, const QAccessibleInterface *, int) const;
-
- // navigation
- int childAt(int x, int y) const;
- int navigate(RelationFlag, int, QAccessibleInterface **) const;
-
- // properties and state
- QString text(Text t, int child) const;
- Role role(int child) const;
- State state(int child) const;
-
- // actions
- int userActionCount(int child) const;
- bool doAction(int action, int child, const QVariantList &params);
- QString actionText(int action, Text t, int child) const;
-};
-
-#endif // QT_NO_ACCESSIBILITY
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QACCESSIBLEOBJECT_H
diff --git a/src/gui/accessible/qaccessibleplugin.h b/src/gui/accessible/qaccessibleplugin.h
deleted file mode 100644
index 3db84469ca..0000000000
--- a/src/gui/accessible/qaccessibleplugin.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QACCESSIBLEPLUGIN_H
-#define QACCESSIBLEPLUGIN_H
-
-#include <QtGui/qaccessible.h>
-#include <QtCore/qfactoryinterface.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_ACCESSIBILITY
-
-class QStringList;
-class QAccessibleInterface;
-
-struct Q_GUI_EXPORT QAccessibleFactoryInterface : public QAccessible, public QFactoryInterface
-{
- virtual QAccessibleInterface* create(const QString &key, QObject *object) = 0;
-};
-
-#define QAccessibleFactoryInterface_iid "com.trolltech.Qt.QAccessibleFactoryInterface"
-Q_DECLARE_INTERFACE(QAccessibleFactoryInterface, QAccessibleFactoryInterface_iid)
-
-class QAccessiblePluginPrivate;
-
-class Q_GUI_EXPORT QAccessiblePlugin : public QObject, public QAccessibleFactoryInterface
-{
- Q_OBJECT
- Q_INTERFACES(QAccessibleFactoryInterface:QFactoryInterface)
-public:
- explicit QAccessiblePlugin(QObject *parent = 0);
- ~QAccessiblePlugin();
-
- virtual QStringList keys() const = 0;
- virtual QAccessibleInterface *create(const QString &key, QObject *object) = 0;
-};
-
-#endif // QT_NO_ACCESSIBILITY
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QACCESSIBLEPLUGIN_H
diff --git a/src/gui/accessible/qaccessiblewidget.cpp b/src/gui/accessible/qaccessiblewidget.cpp
deleted file mode 100644
index 6a7d7e97cc..0000000000
--- a/src/gui/accessible/qaccessiblewidget.cpp
+++ /dev/null
@@ -1,1034 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qaccessiblewidget.h"
-
-#ifndef QT_NO_ACCESSIBILITY
-
-#include "qaction.h"
-#include "qapplication.h"
-#include "qgroupbox.h"
-#include "qlabel.h"
-#include "qtooltip.h"
-#include "qwhatsthis.h"
-#include "qwidget.h"
-#include "qdebug.h"
-#include <qmath.h>
-#include <QRubberBand>
-#include <QtGui/QFocusFrame>
-#include <QtGui/QMenu>
-
-QT_BEGIN_NAMESPACE
-
-static QList<QWidget*> childWidgets(const QWidget *widget)
-{
- QList<QObject*> list = widget->children();
- QList<QWidget*> widgets;
- for (int i = 0; i < list.size(); ++i) {
- QWidget *w = qobject_cast<QWidget *>(list.at(i));
- if (w && !w->isWindow()
- && !qobject_cast<QFocusFrame*>(w)
-#if !defined(QT_NO_MENU)
- && !qobject_cast<QMenu*>(w)
-#endif
- && w->objectName() != QLatin1String("qt_rubberband"))
- widgets.append(w);
- }
- return widgets;
-}
-
-static QString buddyString(const QWidget *widget)
-{
- if (!widget)
- return QString();
- QWidget *parent = widget->parentWidget();
- if (!parent)
- return QString();
-#ifndef QT_NO_SHORTCUT
- QObjectList ol = parent->children();
- for (int i = 0; i < ol.size(); ++i) {
- QLabel *label = qobject_cast<QLabel*>(ol.at(i));
- if (label && label->buddy() == widget)
- return label->text();
- }
-#endif
-
-#ifndef QT_NO_GROUPBOX
- QGroupBox *groupbox = qobject_cast<QGroupBox*>(parent);
- if (groupbox)
- return groupbox->title();
-#endif
-
- return QString();
-}
-
-QString Q_GUI_EXPORT qt_accStripAmp(const QString &text)
-{
- return QString(text).remove(QLatin1Char('&'));
-}
-
-QString Q_GUI_EXPORT qt_accHotKey(const QString &text)
-{
-#ifndef QT_NO_SHORTCUT
- if (text.isEmpty())
- return text;
-
- int fa = 0;
- QChar ac;
- while ((fa = text.indexOf(QLatin1Char('&'), fa)) != -1) {
- ++fa;
- if (fa < text.length()) {
- // ignore "&&"
- if (text.at(fa) == QLatin1Char('&')) {
- ++fa;
- continue;
- } else {
- ac = text.at(fa);
- break;
- }
- }
- }
- if (ac.isNull())
- return QString();
- return (QString)QKeySequence(Qt::ALT) + ac.toUpper();
-#else
- Q_UNUSED(text);
- return QString();
-#endif
-}
-
-class QAccessibleWidgetPrivate : public QAccessible
-{
-public:
- QAccessibleWidgetPrivate()
- :role(Client)
- {}
-
- Role role;
- QString name;
- QString description;
- QString value;
- QString help;
- QString accelerator;
- QStringList primarySignals;
- const QAccessibleInterface *asking;
-};
-
-/*!
- \class QAccessibleWidget
- \brief The QAccessibleWidget class implements the QAccessibleInterface for QWidgets.
-
- \ingroup accessibility
-
- This class is convenient to use as a base class for custom
- implementations of QAccessibleInterfaces that provide information
- about widget objects.
-
- The class provides functions to retrieve the parentObject() (the
- widget's parent widget), and the associated widget(). Controlling
- signals can be added with addControllingSignal(), and setters are
- provided for various aspects of the interface implementation, for
- example setValue(), setDescription(), setAccelerator(), and
- setHelp().
-
- \sa QAccessible, QAccessibleObject
-*/
-
-/*!
- Creates a QAccessibleWidget object for widget \a w.
- \a role and \a name are optional parameters that set the object's
- role and name properties.
-*/
-QAccessibleWidget::QAccessibleWidget(QWidget *w, Role role, const QString &name)
-: QAccessibleObject(w)
-{
- Q_ASSERT(widget());
- d = new QAccessibleWidgetPrivate();
- d->role = role;
- d->name = name;
- d->asking = 0;
-}
-
-/*!
- Destroys this object.
-*/
-QAccessibleWidget::~QAccessibleWidget()
-{
- delete d;
-}
-
-/*!
- Returns the associated widget.
-*/
-QWidget *QAccessibleWidget::widget() const
-{
- return qobject_cast<QWidget*>(object());
-}
-
-/*!
- Returns the associated widget's parent object, which is either the
- parent widget, or qApp for top-level widgets.
-*/
-QObject *QAccessibleWidget::parentObject() const
-{
- QObject *parent = object()->parent();
- if (!parent)
- parent = qApp;
- return parent;
-}
-
-/*! \reimp */
-int QAccessibleWidget::childAt(int x, int y) const
-{
- QWidget *w = widget();
- if (!w->isVisible())
- return -1;
- QPoint gp = w->mapToGlobal(QPoint(0, 0));
- if (!QRect(gp.x(), gp.y(), w->width(), w->height()).contains(x, y))
- return -1;
-
- QWidgetList list = childWidgets(w);
- int ccount = childCount();
-
- // a complex child
- if (list.size() < ccount) {
- for (int i = 1; i <= ccount; ++i) {
- if (rect(i).contains(x, y))
- return i;
- }
- return 0;
- }
-
- QPoint rp = w->mapFromGlobal(QPoint(x, y));
- for (int i = 0; i<list.size(); ++i) {
- QWidget *child = list.at(i);
- if (!child->isWindow() && !child->isHidden() && child->geometry().contains(rp)) {
- return i + 1;
- }
- }
- return 0;
-}
-
-/*! \reimp */
-QRect QAccessibleWidget::rect(int child) const
-{
- if (child) {
- qWarning("QAccessibleWidget::rect: This implementation does not support subelements! "
- "(ID %d unknown for %s)", child, widget()->metaObject()->className());
- }
-
- QWidget *w = widget();
- if (!w->isVisible())
- return QRect();
- QPoint wpos = w->mapToGlobal(QPoint(0, 0));
-
- return QRect(wpos.x(), wpos.y(), w->width(), w->height());
-}
-
-QT_BEGIN_INCLUDE_NAMESPACE
-#include <private/qobject_p.h>
-QT_END_INCLUDE_NAMESPACE
-
-class QACConnectionObject : public QObject
-{
- Q_DECLARE_PRIVATE(QObject)
-public:
- inline bool isSender(const QObject *receiver, const char *signal) const
- { return d_func()->isSender(receiver, signal); }
- inline QObjectList receiverList(const char *signal) const
- { return d_func()->receiverList(signal); }
- inline QObjectList senderList() const
- { return d_func()->senderList(); }
-};
-
-/*!
- Registers \a signal as a controlling signal.
-
- An object is a Controller to any other object connected to a
- controlling signal.
-*/
-void QAccessibleWidget::addControllingSignal(const QString &signal)
-{
- QByteArray s = QMetaObject::normalizedSignature(signal.toAscii());
- if (object()->metaObject()->indexOfSignal(s) < 0)
- qWarning("Signal %s unknown in %s", s.constData(), object()->metaObject()->className());
- d->primarySignals << QLatin1String(s);
-}
-
-/*!
- Sets the value of this interface implementation to \a value.
-
- The default implementation of text() returns the set value for
- the Value text.
-
- Note that the object wrapped by this interface is not modified.
-*/
-void QAccessibleWidget::setValue(const QString &value)
-{
- d->value = value;
-}
-
-/*!
- Sets the description of this interface implementation to \a desc.
-
- The default implementation of text() returns the set value for
- the Description text.
-
- Note that the object wrapped by this interface is not modified.
-*/
-void QAccessibleWidget::setDescription(const QString &desc)
-{
- d->description = desc;
-}
-
-/*!
- Sets the help of this interface implementation to \a help.
-
- The default implementation of text() returns the set value for
- the Help text.
-
- Note that the object wrapped by this interface is not modified.
-*/
-void QAccessibleWidget::setHelp(const QString &help)
-{
- d->help = help;
-}
-
-/*!
- Sets the accelerator of this interface implementation to \a accel.
-
- The default implementation of text() returns the set value for
- the Accelerator text.
-
- Note that the object wrapped by this interface is not modified.
-*/
-void QAccessibleWidget::setAccelerator(const QString &accel)
-{
- d->accelerator = accel;
-}
-
-static inline bool isAncestor(const QObject *obj, const QObject *child)
-{
- while (child) {
- if (child == obj)
- return true;
- child = child->parent();
- }
- return false;
-}
-
-
-/*! \reimp */
-QAccessible::Relation QAccessibleWidget::relationTo(int child,
- const QAccessibleInterface *other, int otherChild) const
-{
- Relation relation = Unrelated;
- if (d->asking == this) // recursive call
- return relation;
-
- QObject *o = other ? other->object() : 0;
- if (!o)
- return relation;
-
- QWidget *focus = widget()->focusWidget();
- if (object() == focus && isAncestor(o, focus))
- relation |= FocusChild;
-
- QACConnectionObject *connectionObject = (QACConnectionObject*)object();
- for (int sig = 0; sig < d->primarySignals.count(); ++sig) {
- if (connectionObject->isSender(o, d->primarySignals.at(sig).toAscii())) {
- relation |= Controller;
- break;
- }
- }
- // test for passive relationships.
- // d->asking protects from endless recursion.
- d->asking = this;
- int inverse = other->relationTo(otherChild, this, child);
- d->asking = 0;
-
- if (inverse & Controller)
- relation |= Controlled;
- if (inverse & Label)
- relation |= Labelled;
-
- if(o == object()) {
- if (child && !otherChild)
- return relation | Child;
- if (!child && otherChild)
- return relation | Ancestor;
- if (!child && !otherChild)
- return relation | Self;
- }
-
- QObject *parent = object()->parent();
- if (o == parent)
- return relation | Child;
-
- if (o->parent() == parent) {
- relation |= Sibling;
- QAccessibleInterface *sibIface = QAccessible::queryAccessibleInterface(o);
- Q_ASSERT(sibIface);
- QRect wg = rect(0);
- QRect sg = sibIface->rect(0);
- if (wg.intersects(sg)) {
- QAccessibleInterface *pIface = 0;
- sibIface->navigate(Ancestor, 1, &pIface);
- if (pIface && !((sibIface->state(0) | state(0)) & Invisible)) {
- int wi = pIface->indexOfChild(this);
- int si = pIface->indexOfChild(sibIface);
-
- if (wi > si)
- relation |= QAccessible::Covers;
- else
- relation |= QAccessible::Covered;
- }
- delete pIface;
- } else {
- QPoint wc = wg.center();
- QPoint sc = sg.center();
- if (wc.x() < sc.x())
- relation |= QAccessible::Left;
- else if(wc.x() > sc.x())
- relation |= QAccessible::Right;
- if (wc.y() < sc.y())
- relation |= QAccessible::Up;
- else if (wc.y() > sc.y())
- relation |= QAccessible::Down;
- }
- delete sibIface;
-
- return relation;
- }
-
- if (isAncestor(o, object()))
- return relation | Descendent;
- if (isAncestor(object(), o))
- return relation | Ancestor;
-
- return relation;
-}
-
-/*! \reimp */
-int QAccessibleWidget::navigate(RelationFlag relation, int entry,
- QAccessibleInterface **target) const
-{
- if (!target)
- return -1;
-
- *target = 0;
- QObject *targetObject = 0;
-
- QWidgetList childList = childWidgets(widget());
- bool complexWidget = childList.size() < childCount();
-
- switch (relation) {
- // Hierarchical
- case Self:
- targetObject = object();
- break;
- case Child:
- if (complexWidget) {
- if (entry > 0 && entry <= childCount())
- return entry;
- return -1;
- }else {
- if (entry > 0 && childList.size() >= entry)
- targetObject = childList.at(entry - 1);
- }
- break;
- case Ancestor:
- {
- if (entry <= 0)
- return -1;
- targetObject = widget()->parentWidget();
- int i;
- for (i = entry; i > 1 && targetObject; --i)
- targetObject = targetObject->parent();
- if (!targetObject && i == 1)
- targetObject = qApp;
- }
- break;
- case Sibling:
- {
- QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(parentObject());
- if (!iface)
- return -1;
-
- iface->navigate(Child, entry, target);
- delete iface;
- if (*target)
- return 0;
- }
- break;
-
- // Geometrical
- case QAccessible::Left:
- if (complexWidget && entry) {
- if (entry < 2 || widget()->height() > widget()->width() + 20) // looks vertical
- return -1;
- return entry - 1;
- }
- // fall through
- case QAccessible::Right:
- if (complexWidget && entry) {
- if (entry >= childCount() || widget()->height() > widget()->width() + 20) // looks vertical
- return -1;
- return entry + 1;
- }
- // fall through
- case QAccessible::Up:
- if (complexWidget && entry) {
- if (entry < 2 || widget()->width() > widget()->height() + 20) // looks horizontal
- return - 1;
- return entry - 1;
- }
- // fall through
- case QAccessible::Down:
- if (complexWidget && entry) {
- if (entry >= childCount() || widget()->width() > widget()->height() + 20) // looks horizontal
- return - 1;
- return entry + 1;
- } else {
- QAccessibleInterface *pIface = QAccessible::queryAccessibleInterface(parentObject());
- if (!pIface)
- return -1;
-
- QRect startg = rect(0);
- QPoint startc = startg.center();
- QAccessibleInterface *candidate = 0;
- int mindist = 100000;
- int sibCount = pIface->childCount();
- for (int i = 0; i < sibCount; ++i) {
- QAccessibleInterface *sibling = 0;
- pIface->navigate(Child, i+1, &sibling);
- Q_ASSERT(sibling);
- if ((relationTo(0, sibling, 0) & Self) || (sibling->state(0) & QAccessible::Invisible)) {
- //ignore ourself and invisible siblings
- delete sibling;
- continue;
- }
-
- QRect sibg = sibling->rect(0);
- QPoint sibc = sibg.center();
- QPoint sibp;
- QPoint startp;
- QPoint distp;
- switch (relation) {
- case QAccessible::Left:
- startp = QPoint(startg.left(), startg.top() + startg.height() / 2);
- sibp = QPoint(sibg.right(), sibg.top() + sibg.height() / 2);
- if (QPoint(sibc - startc).x() >= 0) {
- delete sibling;
- continue;
- }
- distp = sibp - startp;
- break;
- case QAccessible::Right:
- startp = QPoint(startg.right(), startg.top() + startg.height() / 2);
- sibp = QPoint(sibg.left(), sibg.top() + sibg.height() / 2);
- if (QPoint(sibc - startc).x() <= 0) {
- delete sibling;
- continue;
- }
- distp = sibp - startp;
- break;
- case QAccessible::Up:
- startp = QPoint(startg.left() + startg.width() / 2, startg.top());
- sibp = QPoint(sibg.left() + sibg.width() / 2, sibg.bottom());
- if (QPoint(sibc - startc).y() >= 0) {
- delete sibling;
- continue;
- }
- distp = sibp - startp;
- break;
- case QAccessible::Down:
- startp = QPoint(startg.left() + startg.width() / 2, startg.bottom());
- sibp = QPoint(sibg.left() + sibg.width() / 2, sibg.top());
- if (QPoint(sibc - startc).y() <= 0) {
- delete sibling;
- continue;
- }
- distp = sibp - startp;
- break;
- default:
- break;
- }
-
- int dist = (int)qSqrt((qreal)distp.x() * distp.x() + distp.y() * distp.y());
- if (dist < mindist) {
- delete candidate;
- candidate = sibling;
- mindist = dist;
- } else {
- delete sibling;
- }
- }
- delete pIface;
- *target = candidate;
- if (*target)
- return 0;
- }
- break;
- case Covers:
- if (entry > 0) {
- QAccessibleInterface *pIface = QAccessible::queryAccessibleInterface(parentObject());
- if (!pIface)
- return -1;
-
- QRect r = rect(0);
- int sibCount = pIface->childCount();
- QAccessibleInterface *sibling = 0;
- for (int i = pIface->indexOfChild(this) + 1; i <= sibCount && entry; ++i) {
- pIface->navigate(Child, i, &sibling);
- if (!sibling || (sibling->state(0) & Invisible)) {
- delete sibling;
- sibling = 0;
- continue;
- }
- if (sibling->rect(0).intersects(r))
- --entry;
- if (!entry)
- break;
- delete sibling;
- sibling = 0;
- }
- delete pIface;
- *target = sibling;
- if (*target)
- return 0;
- }
- break;
- case Covered:
- if (entry > 0) {
- QAccessibleInterface *pIface = QAccessible::queryAccessibleInterface(parentObject());
- if (!pIface)
- return -1;
-
- QRect r = rect(0);
- int index = pIface->indexOfChild(this);
- QAccessibleInterface *sibling = 0;
- for (int i = 1; i < index && entry; ++i) {
- pIface->navigate(Child, i, &sibling);
- Q_ASSERT(sibling);
- if (!sibling || (sibling->state(0) & Invisible)) {
- delete sibling;
- sibling = 0;
- continue;
- }
- if (sibling->rect(0).intersects(r))
- --entry;
- if (!entry)
- break;
- delete sibling;
- sibling = 0;
- }
- delete pIface;
- *target = sibling;
- if (*target)
- return 0;
- }
- break;
-
- // Logical
- case FocusChild:
- {
- if (widget()->hasFocus()) {
- targetObject = object();
- break;
- }
-
- QWidget *fw = widget()->focusWidget();
- if (!fw)
- return -1;
-
- if (isAncestor(widget(), fw) || fw == widget())
- targetObject = fw;
- /* ###
- QWidget *parent = fw;
- while (parent && !targetObject) {
- parent = parent->parentWidget();
- if (parent == widget())
- targetObject = fw;
- }
- */
- }
- break;
- case Label:
- if (entry > 0) {
- QAccessibleInterface *pIface = QAccessible::queryAccessibleInterface(parentObject());
- if (!pIface)
- return -1;
-
- // first check for all siblings that are labels to us
- // ideally we would go through all objects and check, but that
- // will be too expensive
- int sibCount = pIface->childCount();
- QAccessibleInterface *candidate = 0;
- for (int i = 0; i < sibCount && entry; ++i) {
- const int childId = pIface->navigate(Child, i+1, &candidate);
- Q_ASSERT(childId >= 0);
- if (childId > 0)
- candidate = pIface;
- if (candidate->relationTo(childId, this, 0) & Label)
- --entry;
- if (!entry)
- break;
- if (candidate != pIface)
- delete candidate;
- candidate = 0;
- }
- if (!candidate) {
- if (pIface->relationTo(0, this, 0) & Label)
- --entry;
- if (!entry)
- candidate = pIface;
- }
- if (pIface != candidate)
- delete pIface;
-
- *target = candidate;
- if (*target)
- return 0;
- }
- break;
- case Labelled: // only implemented in subclasses
- break;
- case Controller:
- if (entry > 0) {
- // check all senders we are connected to,
- // and figure out which one are controllers to us
- QACConnectionObject *connectionObject = (QACConnectionObject*)object();
- QObjectList allSenders = connectionObject->senderList();
- QObjectList senders;
- for (int s = 0; s < allSenders.size(); ++s) {
- QObject *sender = allSenders.at(s);
- QAccessibleInterface *candidate = QAccessible::queryAccessibleInterface(sender);
- if (!candidate)
- continue;
- if (candidate->relationTo(0, this, 0)&Controller)
- senders << sender;
- delete candidate;
- }
- if (entry <= senders.size())
- targetObject = senders.at(entry-1);
- }
- break;
- case Controlled:
- if (entry > 0) {
- QObjectList allReceivers;
- QACConnectionObject *connectionObject = (QACConnectionObject*)object();
- for (int sig = 0; sig < d->primarySignals.count(); ++sig) {
- QObjectList receivers = connectionObject->receiverList(d->primarySignals.at(sig).toAscii());
- allReceivers += receivers;
- }
- if (entry <= allReceivers.size())
- targetObject = allReceivers.at(entry-1);
- }
- break;
- default:
- break;
- }
-
- *target = QAccessible::queryAccessibleInterface(targetObject);
- return *target ? 0 : -1;
-}
-
-/*! \reimp */
-int QAccessibleWidget::childCount() const
-{
- QWidgetList cl = childWidgets(widget());
- return cl.size();
-}
-
-/*! \reimp */
-int QAccessibleWidget::indexOfChild(const QAccessibleInterface *child) const
-{
- QWidgetList cl = childWidgets(widget());
- int index = cl.indexOf(qobject_cast<QWidget *>(child->object()));
- if (index != -1)
- ++index;
- return index;
-}
-
-// from qwidget.cpp
-extern QString qt_setWindowTitle_helperHelper(const QString &, const QWidget*);
-
-/*! \reimp */
-QString QAccessibleWidget::text(Text t, int child) const
-{
- QString str;
-
- switch (t) {
- case Name:
- if (!d->name.isEmpty()) {
- str = d->name;
- } else if (!widget()->accessibleName().isEmpty()) {
- str = widget()->accessibleName();
- } else if (!child && widget()->isWindow()) {
- if (widget()->isMinimized())
- str = qt_setWindowTitle_helperHelper(widget()->windowIconText(), widget());
- else
- str = qt_setWindowTitle_helperHelper(widget()->windowTitle(), widget());
- } else {
- str = qt_accStripAmp(buddyString(widget()));
- }
- break;
- case Description:
- if (!d->description.isEmpty())
- str = d->description;
- else if (!widget()->accessibleDescription().isEmpty())
- str = widget()->accessibleDescription();
-#ifndef QT_NO_TOOLTIP
- else
- str = widget()->toolTip();
-#endif
- break;
- case Help:
- if (!d->help.isEmpty())
- str = d->help;
-#ifndef QT_NO_WHATSTHIS
- else
- str = widget()->whatsThis();
-#endif
- break;
- case Accelerator:
- if (!d->accelerator.isEmpty())
- str = d->accelerator;
- else
- str = qt_accHotKey(buddyString(widget()));
- break;
- case Value:
- str = d->value;
- break;
- default:
- break;
- }
- return str;
-}
-
-#ifndef QT_NO_ACTION
-
-/*! \reimp */
-int QAccessibleWidget::userActionCount(int child) const
-{
- if (child)
- return 0;
- return widget()->actions().count();
-}
-
-/*! \reimp */
-QString QAccessibleWidget::actionText(int action, Text t, int child) const
-{
- if (action == DefaultAction)
- action = SetFocus;
-
- if (action > 0 && !child) {
- QAction *act = widget()->actions().value(action - 1);
- if (act) {
- switch (t) {
- case Name:
- return act->text();
- case Description:
- return act->toolTip();
-#ifndef QT_NO_SHORTCUT
- case Accelerator:
- return act->shortcut().toString();
-#endif
- default:
- break;
- }
- }
- }
-
- return QAccessibleObject::actionText(action, t, child);
-}
-
-/*! \reimp */
-bool QAccessibleWidget::doAction(int action, int child, const QVariantList &params)
-{
- if (action == SetFocus || action == DefaultAction) {
- if (child || !widget()->isEnabled())
- return false;
- if (widget()->focusPolicy() != Qt::NoFocus)
- widget()->setFocus();
- else if (widget()->isWindow())
- widget()->activateWindow();
- else
- return false;
- return true;
- } else if (action > 0) {
- if (QAction *act = widget()->actions().value(action - 1)) {
- act->trigger();
- return true;
- }
- }
- return QAccessibleObject::doAction(action, child, params);
-}
-
-#endif // QT_NO_ACTION
-
-/*! \reimp */
-QAccessible::Role QAccessibleWidget::role(int child) const
-{
- if (!child)
- return d->role;
-
- QWidgetList childList = childWidgets(widget());
- if (childList.count() > 0 && child <= childList.count()) {
- QWidget *targetWidget = childList.at(child - 1);
- QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(targetWidget);
- if (iface) {
- QAccessible::Role role = iface->role(0);
- delete iface;
- return role;
- }
- }
-
- return NoRole;
-}
-
-/*! \reimp */
-QAccessible::State QAccessibleWidget::state(int child) const
-{
- if (child)
- return Normal;
-
- QAccessible::State state = Normal;
-
- QWidget *w = widget();
- if (w->testAttribute(Qt::WA_WState_Visible) == false)
- state |= Invisible;
- if (w->focusPolicy() != Qt::NoFocus && w->isActiveWindow())
- state |= Focusable;
- if (w->hasFocus())
- state |= Focused;
- if (!w->isEnabled())
- state |= Unavailable;
- if (w->isWindow()) {
- if (w->windowFlags() & Qt::WindowSystemMenuHint)
- state |= Movable;
- if (w->minimumSize() != w->maximumSize())
- state |= Sizeable;
- }
-
- return state;
-}
-
-// ### Qt 5: remove me - binary compatibility hack
-QAccessibleWidgetEx::QAccessibleWidgetEx(QWidget *o, Role role, const QString& name)
- : QAccessibleObjectEx(o)
-{
- Q_ASSERT(widget());
- d = new QAccessibleWidgetPrivate();
- d->role = role;
- d->name = name;
- d->asking = 0;
-}
-
-int QAccessibleWidgetEx::childCount() const
-{ return reinterpret_cast<const QAccessibleWidget *>(this)->QAccessibleWidget::childCount(); }
-int QAccessibleWidgetEx::indexOfChild(const QAccessibleInterface *child) const
-{ return reinterpret_cast<const QAccessibleWidget *>(this)->QAccessibleWidget::indexOfChild(child); }
-QAccessible::Relation QAccessibleWidgetEx::relationTo(int child, const QAccessibleInterface *other, int otherChild) const
-{ return reinterpret_cast<const QAccessibleWidget *>(this)->QAccessibleWidget::relationTo(child, other, otherChild); }
-
-int QAccessibleWidgetEx::childAt(int x, int y) const
-{ return reinterpret_cast<const QAccessibleWidget *>(this)->QAccessibleWidget::childAt(x, y); }
-QRect QAccessibleWidgetEx::rect(int child) const
-{ return reinterpret_cast<const QAccessibleWidget *>(this)->QAccessibleWidget::rect(child); }
-int QAccessibleWidgetEx::navigate(RelationFlag rel, int entry, QAccessibleInterface **target) const
-{ return reinterpret_cast<const QAccessibleWidget *>(this)->QAccessibleWidget::navigate(rel, entry, target); }
-
-QString QAccessibleWidgetEx::text(Text t, int child) const
-{ return reinterpret_cast<const QAccessibleWidget *>(this)->QAccessibleWidget::text(t, child); }
-QAccessible::Role QAccessibleWidgetEx::role(int child) const
-{ return reinterpret_cast<const QAccessibleWidget *>(this)->QAccessibleWidget::role(child); }
-QAccessible::State QAccessibleWidgetEx::state(int child) const
-{ return (reinterpret_cast<const QAccessibleWidget *>(this)->QAccessibleWidget::state(child))
- | HasInvokeExtension; }
-
-QString QAccessibleWidgetEx::actionText(int action, Text t, int child) const
-{ return reinterpret_cast<const QAccessibleWidget *>(this)->QAccessibleWidget::actionText(action, t, child); }
-bool QAccessibleWidgetEx::doAction(int action, int child, const QVariantList &params)
-{ return reinterpret_cast<QAccessibleWidget *>(this)->QAccessibleWidget::doAction(action, child, params); }
-
-QAccessibleWidgetEx::~QAccessibleWidgetEx()
-{ delete d; }
-QWidget *QAccessibleWidgetEx::widget() const
-{ return reinterpret_cast<const QAccessibleWidget *>(this)->QAccessibleWidget::widget(); }
-QObject *QAccessibleWidgetEx::parentObject() const
-{ return reinterpret_cast<const QAccessibleWidget *>(this)->QAccessibleWidget::parentObject(); }
-
-void QAccessibleWidgetEx::addControllingSignal(const QString &signal)
-{ reinterpret_cast<QAccessibleWidget *>(this)->QAccessibleWidget::addControllingSignal(signal); }
-void QAccessibleWidgetEx::setValue(const QString &value)
-{ reinterpret_cast<QAccessibleWidget *>(this)->QAccessibleWidget::setValue(value); }
-void QAccessibleWidgetEx::setDescription(const QString &desc)
-{ reinterpret_cast<QAccessibleWidget *>(this)->QAccessibleWidget::setDescription(desc); }
-void QAccessibleWidgetEx::setHelp(const QString &help)
-{ reinterpret_cast<QAccessibleWidget *>(this)->QAccessibleWidget::setHelp(help); }
-void QAccessibleWidgetEx::setAccelerator(const QString &accel)
-{ reinterpret_cast<QAccessibleWidget *>(this)->QAccessibleWidget::setAccelerator(accel); }
-
-QVariant QAccessibleWidgetEx::invokeMethodEx(Method method, int child, const QVariantList & /*params*/)
-{
- if (child)
- return QVariant();
-
- switch (method) {
- case ListSupportedMethods: {
- QSet<QAccessible::Method> set;
- set << ListSupportedMethods << ForegroundColor << BackgroundColor;
- return QVariant::fromValue(set);
- }
- case ForegroundColor:
- return widget()->palette().color(widget()->foregroundRole());
- case BackgroundColor:
- return widget()->palette().color(widget()->backgroundRole());
- default:
- return QVariant();
- }
-}
-
-QT_END_NAMESPACE
-
-#endif //QT_NO_ACCESSIBILITY
diff --git a/src/gui/accessible/qaccessiblewidget.h b/src/gui/accessible/qaccessiblewidget.h
deleted file mode 100644
index 1b7f82d4d9..0000000000
--- a/src/gui/accessible/qaccessiblewidget.h
+++ /dev/null
@@ -1,141 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QACCESSIBLEWIDGET_H
-#define QACCESSIBLEWIDGET_H
-
-#include <QtGui/qaccessibleobject.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_ACCESSIBILITY
-
-class QAccessibleWidgetPrivate;
-
-class Q_GUI_EXPORT QAccessibleWidget : public QAccessibleObject
-{
-public:
- explicit QAccessibleWidget(QWidget *o, Role r = Client, const QString& name = QString());
-
- int childCount() const;
- int indexOfChild(const QAccessibleInterface *child) const;
- Relation relationTo(int child, const QAccessibleInterface *other, int otherChild) const;
-
- int childAt(int x, int y) const;
- QRect rect(int child) const;
- int navigate(RelationFlag rel, int entry, QAccessibleInterface **target) const;
-
- QString text(Text t, int child) const;
- Role role(int child) const;
- State state(int child) const;
-
-#ifndef QT_NO_ACTION
- int userActionCount(int child) const;
- QString actionText(int action, Text t, int child) const;
- bool doAction(int action, int child, const QVariantList &params);
-#endif
-
-protected:
- ~QAccessibleWidget();
- QWidget *widget() const;
- QObject *parentObject() const;
-
- void addControllingSignal(const QString &signal);
- void setValue(const QString &value);
- void setDescription(const QString &desc);
- void setHelp(const QString &help);
- void setAccelerator(const QString &accel);
-
-private:
- friend class QAccessibleWidgetEx;
- QAccessibleWidgetPrivate *d;
- Q_DISABLE_COPY(QAccessibleWidget)
-};
-
-class Q_GUI_EXPORT QAccessibleWidgetEx : public QAccessibleObjectEx
-{
-public:
- explicit QAccessibleWidgetEx(QWidget *o, Role r = Client, const QString& name = QString());
-
- int childCount() const;
- int indexOfChild(const QAccessibleInterface *child) const;
- Relation relationTo(int child, const QAccessibleInterface *other, int otherChild) const;
-
- int childAt(int x, int y) const;
- QRect rect(int child) const;
- int navigate(RelationFlag rel, int entry, QAccessibleInterface **target) const;
-
- QString text(Text t, int child) const;
- Role role(int child) const;
- State state(int child) const;
-
- QString actionText(int action, Text t, int child) const;
- bool doAction(int action, int child, const QVariantList &params);
-
- QVariant invokeMethodEx(Method method, int child, const QVariantList &params);
-
-protected:
- ~QAccessibleWidgetEx();
- QWidget *widget() const;
- QObject *parentObject() const;
-
- void addControllingSignal(const QString &signal);
- void setValue(const QString &value);
- void setDescription(const QString &desc);
- void setHelp(const QString &help);
- void setAccelerator(const QString &accel);
-
-private:
- QAccessibleWidgetPrivate *d;
- Q_DISABLE_COPY(QAccessibleWidgetEx)
-};
-
-#endif // QT_NO_ACCESSIBILITY
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QACCESSIBLEWIDGET_H
diff --git a/src/gui/dialogs/dialogs.pri b/src/gui/dialogs/dialogs.pri
deleted file mode 100644
index 6ba707c9d3..0000000000
--- a/src/gui/dialogs/dialogs.pri
+++ /dev/null
@@ -1,122 +0,0 @@
-# Qt dialogs module
-
-HEADERS += \
- dialogs/qabstractprintdialog.h \
- dialogs/qabstractprintdialog_p.h \
- dialogs/qabstractpagesetupdialog.h \
- dialogs/qabstractpagesetupdialog_p.h \
- dialogs/qcolordialog.h \
- dialogs/qcolordialog_p.h \
- dialogs/qfscompleter_p.h \
- dialogs/qdialog.h \
- dialogs/qdialog_p.h \
- dialogs/qerrormessage.h \
- dialogs/qfiledialog.h \
- dialogs/qfiledialog_p.h \
- dialogs/qfontdialog.h \
- dialogs/qfontdialog_p.h \
- dialogs/qinputdialog.h \
- dialogs/qmessagebox.h \
- dialogs/qpagesetupdialog.h \
- dialogs/qprintdialog.h \
- dialogs/qprogressdialog.h \
- dialogs/qsidebar_p.h \
- dialogs/qfilesystemmodel.h \
- dialogs/qfilesystemmodel_p.h \
- dialogs/qfileinfogatherer_p.h \
- dialogs/qwizard.h \
- dialogs/qprintpreviewdialog.h
-
-!embedded:!qpa:mac {
- OBJECTIVE_SOURCES += dialogs/qfiledialog_mac.mm \
- dialogs/qfontdialog_mac.mm \
- dialogs/qnspanelproxy_mac.mm \
- dialogs/qpagesetupdialog_mac.mm \
- dialogs/qprintdialog_mac.mm
-
-# Compile qcolordialog_mac.mm with exception support, disregarding the -no-exceptions
-# configure option. (qcolordialog_mac needs to catch exceptions thrown by cocoa)
- EXCEPTION_SOURCES = dialogs/qcolordialog_mac.mm
- exceptions_compiler.commands = $$QMAKE_CXX -c
- exceptions_compiler.commands += $(CXXFLAGS) $(INCPATH) ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT}
- exceptions_compiler.commands += -fexceptions
- exceptions_compiler.dependency_type = TYPE_C
- exceptions_compiler.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_OBJ)}
- exceptions_compiler.input = EXCEPTION_SOURCES
- exceptions_compiler.variable_out = OBJECTS
- exceptions_compiler.name = compiling[exceptopns] ${QMAKE_FILE_IN}
- silent:exceptions_compiler.commands = @echo compiling[exceptopns] ${QMAKE_FILE_IN} && $$exceptions_compiler.commands
- QMAKE_EXTRA_COMPILERS += exceptions_compiler
-}
-
-win32 {
- HEADERS += dialogs/qwizard_win_p.h \
- dialogs/qfiledialog_win_p.h
- SOURCES += dialogs/qdialogsbinarycompat_win.cpp \
- dialogs/qfiledialog_win.cpp \
- dialogs/qpagesetupdialog_win.cpp \
- dialogs/qprintdialog_win.cpp \
- dialogs/qwizard_win.cpp
-
- !win32-borland:!wince*: LIBS += -lshell32 # the filedialog needs this library
-}
-
-!mac:!embedded:!symbian:unix|qpa {
- HEADERS += dialogs/qpagesetupdialog_unix_p.h
- SOURCES += dialogs/qprintdialog_unix.cpp \
- dialogs/qpagesetupdialog_unix.cpp
- FORMS += dialogs/qprintsettingsoutput.ui \
- dialogs/qprintwidget.ui \
- dialogs/qprintpropertieswidget.ui
-}
-
-embedded {
- contains(QT_CONFIG,qtopia) {
- HEADERS += dialogs/qpagesetupdialog_unix_p.h
- DEFINES += QTOPIA_PRINTDIALOG
- SOURCES += dialogs/qprintdialog_qws.cpp \
- dialogs/qpagesetupdialog_unix.cpp
- } else {
- HEADERS += dialogs/qpagesetupdialog_unix_p.h
- SOURCES += dialogs/qprintdialog_unix.cpp \
- dialogs/qpagesetupdialog_unix.cpp
- FORMS += dialogs/qprintsettingsoutput.ui \
- dialogs/qprintwidget.ui \
- dialogs/qprintpropertieswidget.ui
- }
-}
-
-wince*|symbian: FORMS += dialogs/qfiledialog_embedded.ui
-else: FORMS += dialogs/qfiledialog.ui
-
-INCLUDEPATH += $$PWD
-SOURCES += \
- dialogs/qabstractprintdialog.cpp \
- dialogs/qabstractpagesetupdialog.cpp \
- dialogs/qcolordialog.cpp \
- dialogs/qdialog.cpp \
- dialogs/qerrormessage.cpp \
- dialogs/qfiledialog.cpp \
- dialogs/qfontdialog.cpp \
- dialogs/qinputdialog.cpp \
- dialogs/qmessagebox.cpp \
- dialogs/qprogressdialog.cpp \
- dialogs/qsidebar.cpp \
- dialogs/qfilesystemmodel.cpp \
- dialogs/qfileinfogatherer.cpp \
- dialogs/qpagesetupdialog.cpp \
- dialogs/qwizard.cpp \
- dialogs/qprintpreviewdialog.cpp
-
-symbian:contains(QT_CONFIG, s60) {
- LIBS += -lCommonDialogs
- SOURCES += dialogs/qfiledialog_symbian.cpp \
- dialogs/qcolordialog_symbian.cpp
-}
-
-FORMS += dialogs/qpagesetupwidget.ui
-RESOURCES += dialogs/qprintdialog.qrc
-RESOURCES += dialogs/qmessagebox.qrc
-
-# Compensate for lack of platform defines in Symbian3
-symbian: DEFINES += SYMBIAN_VERSION_$$upper($$replace(SYMBIAN_VERSION,\\.,_))
diff --git a/src/gui/dialogs/qabstractpagesetupdialog.cpp b/src/gui/dialogs/qabstractpagesetupdialog.cpp
deleted file mode 100644
index 7a0e0080b2..0000000000
--- a/src/gui/dialogs/qabstractpagesetupdialog.cpp
+++ /dev/null
@@ -1,139 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qabstractpagesetupdialog.h"
-#include "qabstractpagesetupdialog_p.h"
-
-#ifndef QT_NO_PRINTDIALOG
-
-#include <QtCore/qcoreapplication.h>
-#include <QtGui/qprinter.h>
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \internal
- \class QAbstractPageSetupDialog
-
- \brief The QAbstractPageSetupDialog class provides a base for
- implementations of page setup dialogs.
-*/
-
-/*!
- Constructs the page setup dialog for the printer \a printer with
- \a parent as parent widget.
-*/
-QAbstractPageSetupDialog::QAbstractPageSetupDialog(QPrinter *printer, QWidget *parent)
- : QDialog(*(new QAbstractPageSetupDialogPrivate), parent)
-{
- Q_D(QAbstractPageSetupDialog);
- setWindowTitle(QCoreApplication::translate("QPrintPreviewDialog", "Page Setup"));
- d->setPrinter(printer);
-}
-
-/*!
- \internal
-*/
-QAbstractPageSetupDialog::QAbstractPageSetupDialog(QAbstractPageSetupDialogPrivate &ptr,
- QPrinter *printer, QWidget *parent)
- : QDialog(ptr, parent)
-{
- Q_D(QAbstractPageSetupDialog);
- setWindowTitle(QCoreApplication::translate("QPrintPreviewDialog", "Page Setup"));
- d->setPrinter(printer);
-}
-
-QAbstractPageSetupDialog::~QAbstractPageSetupDialog()
-{
- Q_D(QAbstractPageSetupDialog);
- if (d->opts & QPageSetupDialog::OwnsPrinter)
- delete d->printer;
-}
-
-/*!
- Returns the printer that this page setup dialog is operating on.
-*/
-QPrinter *QAbstractPageSetupDialog::printer()
-{
- Q_D(QAbstractPageSetupDialog);
- return d->printer;
-}
-
-void QAbstractPageSetupDialogPrivate::setPrinter(QPrinter *newPrinter)
-{
- if (newPrinter) {
- printer = newPrinter;
- } else {
- printer = new QPrinter;
- opts |= QPageSetupDialog::OwnsPrinter;
- }
-#ifndef Q_WS_X11
- if (printer->outputFormat() != QPrinter::NativeFormat)
- qWarning("QPageSetupDialog: Cannot be used on non-native printers");
-#endif
-}
-
-/*!
- \fn int QAbstractPageSetupDialog::exec()
-
- This virtual function is called to pop up the dialog. It must be
- reimplemented in subclasses.
-*/
-
-/*!
- \reimp
-*/
-void QAbstractPageSetupDialog::done(int result)
-{
- Q_D(QAbstractPageSetupDialog);
- QDialog::done(result);
- if (d->receiverToDisconnectOnClose) {
- disconnect(this, SIGNAL(accepted()),
- d->receiverToDisconnectOnClose, d->memberToDisconnectOnClose);
- d->receiverToDisconnectOnClose = 0;
- }
- d->memberToDisconnectOnClose.clear();
-
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_PRINTDIALOG
diff --git a/src/gui/dialogs/qabstractpagesetupdialog.h b/src/gui/dialogs/qabstractpagesetupdialog.h
deleted file mode 100644
index 188b455c37..0000000000
--- a/src/gui/dialogs/qabstractpagesetupdialog.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QABSTRACTPAGESETUPDIALOG_H
-#define QABSTRACTPAGESETUPDIALOG_H
-
-#include <QtGui/qdialog.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_PRINTDIALOG
-
-class QAbstractPageSetupDialogPrivate;
-class QPrinter;
-
-// ### Qt 5: Remove this class
-class Q_GUI_EXPORT QAbstractPageSetupDialog : public QDialog
-{
- Q_DECLARE_PRIVATE(QAbstractPageSetupDialog)
- Q_OBJECT
-
-public:
- explicit QAbstractPageSetupDialog(QPrinter *printer, QWidget *parent = 0);
- QAbstractPageSetupDialog(QAbstractPageSetupDialogPrivate &ptr,
- QPrinter *printer, QWidget *parent = 0);
- ~QAbstractPageSetupDialog();
-
- virtual int exec() = 0;
- void done(int result);
-
- QPrinter *printer();
-};
-
-#endif // QT_NO_PRINTDIALOG
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QABSTRACTPAGESETUPDIALOG_H
diff --git a/src/gui/dialogs/qabstractprintdialog.cpp b/src/gui/dialogs/qabstractprintdialog.cpp
deleted file mode 100644
index 4b495d1132..0000000000
--- a/src/gui/dialogs/qabstractprintdialog.cpp
+++ /dev/null
@@ -1,497 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qabstractprintdialog_p.h"
-#include "qcoreapplication.h"
-#include "qprintdialog.h"
-#include "qprinter.h"
-#include "private/qprinter_p.h"
-
-#ifndef QT_NO_PRINTDIALOG
-
-QT_BEGIN_NAMESPACE
-
-// hack
-class QPrintDialogPrivate : public QAbstractPrintDialogPrivate
-{
-};
-
-/*!
- \class QAbstractPrintDialog
- \brief The QAbstractPrintDialog class provides a base implementation for
- print dialogs used to configure printers.
-
- \ingroup printing
-
- This class implements getter and setter functions that are used to
- customize settings shown in print dialogs, but it is not used directly.
- Use QPrintDialog to display a print dialog in your application.
-
- In Symbian, there is no support for printing. Hence, this dialog should not
- be used in Symbian.
-
- \sa QPrintDialog, QPrinter, {Printing with Qt}
-*/
-
-/*!
- \enum QAbstractPrintDialog::PrintRange
-
- Used to specify the print range selection option.
-
- \value AllPages All pages should be printed.
- \value Selection Only the selection should be printed.
- \value PageRange The specified page range should be printed.
- \value CurrentPage Only the currently visible page should be printed.
-
- \sa QPrinter::PrintRange
-*/
-
-/*!
- \enum QAbstractPrintDialog::PrintDialogOption
-
- Used to specify which parts of the print dialog should be visible.
-
- \value None None of the options are enabled.
- \value PrintToFile The print to file option is enabled.
- \value PrintSelection The print selection option is enabled.
- \value PrintPageRange The page range selection option is enabled.
- \value PrintShowPageSize Show the page size + margins page only if this is enabled.
- \value PrintCollateCopies The collate copies option is enabled
- \value PrintCurrentPage The print current page option is enabled
-
- This value is obsolete and does nothing since Qt 4.5:
-
- \value DontUseSheet In previous versions of Qt, exec() the print dialog
- would create a sheet by default the dialog was given a parent.
- This is no longer supported in Qt 4.5. If you want to use sheets, use
- QPrintDialog::open() instead.
-*/
-
-/*!
- Constructs an abstract print dialog for \a printer with \a parent
- as parent widget.
-*/
-QAbstractPrintDialog::QAbstractPrintDialog(QPrinter *printer, QWidget *parent)
- : QDialog(*(new QAbstractPrintDialogPrivate), parent)
-{
- Q_D(QAbstractPrintDialog);
- setWindowTitle(QCoreApplication::translate("QPrintDialog", "Print"));
- d->setPrinter(printer);
-}
-
-/*!
- \internal
-*/
-QAbstractPrintDialog::QAbstractPrintDialog(QAbstractPrintDialogPrivate &ptr,
- QPrinter *printer,
- QWidget *parent)
- : QDialog(ptr, parent)
-{
- Q_D(QAbstractPrintDialog);
- setWindowTitle(QCoreApplication::translate("QPrintDialog", "Print"));
- d->setPrinter(printer);
-}
-
-/*!
- \internal
-*/
-QAbstractPrintDialog::~QAbstractPrintDialog()
-{
- Q_D(QAbstractPrintDialog);
- if (d->ownsPrinter)
- delete d->printer;
-}
-
-/*!
- Sets the given \a option to be enabled if \a on is true;
- otherwise, clears the given \a option.
-
- \sa options, testOption()
-*/
-void QPrintDialog::setOption(PrintDialogOption option, bool on)
-{
- Q_D(QPrintDialog);
- if (!(d->pd->options & option) != !on)
- setOptions(d->pd->options ^ option);
-}
-
-/*!
- Returns true if the given \a option is enabled; otherwise, returns
- false.
-
- \sa options, setOption()
-*/
-bool QPrintDialog::testOption(PrintDialogOption option) const
-{
- Q_D(const QPrintDialog);
- return (d->pd->options & option) != 0;
-}
-
-/*!
- \property QPrintDialog::options
- \brief the various options that affect the look and feel of the dialog
- \since 4.5
-
- By default, all options are disabled.
-
- Options should be set before showing the dialog. Setting them while the
- dialog is visible is not guaranteed to have an immediate effect on the
- dialog (depending on the option and on the platform).
-
- \sa setOption(), testOption()
-*/
-void QPrintDialog::setOptions(PrintDialogOptions options)
-{
- Q_D(QPrintDialog);
-
- PrintDialogOptions changed = (options ^ d->pd->options);
- if (!changed)
- return;
-
- d->pd->options = options;
-}
-
-QPrintDialog::PrintDialogOptions QPrintDialog::options() const
-{
- Q_D(const QPrintDialog);
- return d->pd->options;
-}
-
-/*!
- \obsolete
-
- Use QPrintDialog::setOptions() instead.
-*/
-void QAbstractPrintDialog::setEnabledOptions(PrintDialogOptions options)
-{
- Q_D(QAbstractPrintDialog);
- d->pd->options = options;
-}
-
-/*!
- \obsolete
-
- Use QPrintDialog::setOption(\a option, true) instead.
-*/
-void QAbstractPrintDialog::addEnabledOption(PrintDialogOption option)
-{
- Q_D(QAbstractPrintDialog);
- d->pd->options |= option;
-}
-
-/*!
- \obsolete
-
- Use QPrintDialog::options() instead.
-*/
-QAbstractPrintDialog::PrintDialogOptions QAbstractPrintDialog::enabledOptions() const
-{
- Q_D(const QAbstractPrintDialog);
- return d->pd->options;
-}
-
-/*!
- \obsolete
-
- Use QPrintDialog::testOption(\a option) instead.
-*/
-bool QAbstractPrintDialog::isOptionEnabled(PrintDialogOption option) const
-{
- Q_D(const QAbstractPrintDialog);
- return d->pd->options & option;
-}
-
-/*!
- Sets the print range option in to be \a range.
- */
-void QAbstractPrintDialog::setPrintRange(PrintRange range)
-{
- Q_D(QAbstractPrintDialog);
- d->pd->printRange = range;
-}
-
-/*!
- Returns the print range.
-*/
-QAbstractPrintDialog::PrintRange QAbstractPrintDialog::printRange() const
-{
- Q_D(const QAbstractPrintDialog);
- return d->pd->printRange;
-}
-
-/*!
- Sets the page range in this dialog to be from \a min to \a max. This also
- enables the PrintPageRange option.
-*/
-void QAbstractPrintDialog::setMinMax(int min, int max)
-{
- Q_D(QAbstractPrintDialog);
- Q_ASSERT_X(min <= max, "QAbstractPrintDialog::setMinMax",
- "'min' must be less than or equal to 'max'");
- d->pd->minPage = min;
- d->pd->maxPage = max;
- d->pd->options |= PrintPageRange;
-}
-
-/*!
- Returns the minimum page in the page range.
- By default, this value is set to 1.
-*/
-int QAbstractPrintDialog::minPage() const
-{
- Q_D(const QAbstractPrintDialog);
- return d->pd->minPage;
-}
-
-/*!
- Returns the maximum page in the page range. As of Qt 4.4, this
- function returns INT_MAX by default. Previous versions returned 1
- by default.
-*/
-int QAbstractPrintDialog::maxPage() const
-{
- Q_D(const QAbstractPrintDialog);
- return d->pd->maxPage;
-}
-
-/*!
- Sets the range in the print dialog to be from \a from to \a to.
-*/
-void QAbstractPrintDialog::setFromTo(int from, int to)
-{
- Q_D(QAbstractPrintDialog);
- Q_ASSERT_X(from <= to, "QAbstractPrintDialog::setFromTo",
- "'from' must be less than or equal to 'to'");
- d->pd->fromPage = from;
- d->pd->toPage = to;
-
- if (d->pd->minPage == 0 && d->pd->maxPage == 0)
- setMinMax(1, to);
-}
-
-/*!
- Returns the first page to be printed
- By default, this value is set to 0.
-*/
-int QAbstractPrintDialog::fromPage() const
-{
- Q_D(const QAbstractPrintDialog);
- return d->pd->fromPage;
-}
-
-/*!
- Returns the last page to be printed.
- By default, this value is set to 0.
-*/
-int QAbstractPrintDialog::toPage() const
-{
- Q_D(const QAbstractPrintDialog);
- return d->pd->toPage;
-}
-
-
-/*!
- Returns the printer that this printer dialog operates
- on.
-*/
-QPrinter *QAbstractPrintDialog::printer() const
-{
- Q_D(const QAbstractPrintDialog);
- return d->printer;
-}
-
-void QAbstractPrintDialogPrivate::setPrinter(QPrinter *newPrinter)
-{
- if (newPrinter) {
- printer = newPrinter;
- ownsPrinter = false;
- } else {
- printer = new QPrinter;
- ownsPrinter = true;
- }
- pd = printer->d_func();
-}
-
-/*!
- \fn int QAbstractPrintDialog::exec()
-
- This virtual function is called to pop up the dialog. It must be
- reimplemented in subclasses.
-*/
-
-/*!
- \class QPrintDialog
-
- \brief The QPrintDialog class provides a dialog for specifying
- the printer's configuration.
-
- \ingroup standard-dialogs
- \ingroup printing
-
- The dialog allows users to change document-related settings, such
- as the paper size and orientation, type of print (color or
- grayscale), range of pages, and number of copies to print.
-
- Controls are also provided to enable users to choose from the
- printers available, including any configured network printers.
-
- Typically, QPrintDialog objects are constructed with a QPrinter
- object, and executed using the exec() function.
-
- \snippet doc/src/snippets/code/src_gui_dialogs_qabstractprintdialog.cpp 0
-
- If the dialog is accepted by the user, the QPrinter object is
- correctly configured for printing.
-
- \table
- \row
- \o \inlineimage plastique-printdialog.png
- \o \inlineimage plastique-printdialog-properties.png
- \endtable
-
- The printer dialog (shown above in Plastique style) enables access to common
- printing properties. On X11 platforms that use the CUPS printing system, the
- settings for each available printer can be modified via the dialog's
- \gui{Properties} push button.
-
- On Windows and Mac OS X, the native print dialog is used, which means that
- some QWidget and QDialog properties set on the dialog won't be respected.
- The native print dialog on Mac OS X does not support setting printer options,
- i.e. setOptions() and setOption() have no effect.
-
- In Qt 4.4, it was possible to use the static functions to show a sheet on
- Mac OS X. This is no longer supported in Qt 4.5. If you want this
- functionality, use QPrintDialog::open().
-
- \sa QPageSetupDialog, QPrinter, {Pixelator Example}, {Order Form Example},
- {Image Viewer Example}, {Scribble Example}
-*/
-
-/*!
- \fn QPrintDialog::QPrintDialog(QPrinter *printer, QWidget *parent)
-
- Constructs a new modal printer dialog for the given \a printer
- with the given \a parent.
-*/
-
-/*!
- \fn QPrintDialog::~QPrintDialog()
-
- Destroys the print dialog.
-*/
-
-/*!
- \fn int QPrintDialog::exec()
- \reimp
-*/
-
-/*!
- \since 4.4
-
- Set a list of widgets as \a tabs to be shown on the print dialog, if supported.
-
- Currently this option is only supported on X11.
-
- Setting the option tabs will transfer their ownership to the print dialog.
-*/
-void QAbstractPrintDialog::setOptionTabs(const QList<QWidget*> &tabs)
-{
- Q_D(QAbstractPrintDialog);
- d->setTabs(tabs);
-}
-
-/*!
-
- \fn void QPrintDialog::accepted(QPrinter *printer)
-
- This signal is emitted when the user accepts the values set in the print dialog.
- The \a printer parameter includes the printer that the settings were applied to.
-*/
-
-/*!
- \fn QPrinter *QPrintDialog::printer()
-
- Returns the printer that this printer dialog operates
- on. This can be useful when using the QPrintDialog::open() method.
-*/
-
-/*!
- Closes the dialog and sets its result code to \a result. If this dialog
- is shown with exec(), done() causes the local event loop to finish,
- and exec() to return \a result.
-
- \sa QDialog::done()
-*/
-void QPrintDialog::done(int result)
-{
- Q_D(QPrintDialog);
- QDialog::done(result);
- if (result == Accepted)
- emit accepted(printer());
- if (d->receiverToDisconnectOnClose) {
- disconnect(this, SIGNAL(accepted(QPrinter*)),
- d->receiverToDisconnectOnClose, d->memberToDisconnectOnClose);
- d->receiverToDisconnectOnClose = 0;
- }
- d->memberToDisconnectOnClose.clear();
-}
-
-/*!
- \since 4.5
- \overload
-
- Opens the dialog and connects its accepted() signal to the slot specified
- by \a receiver and \a member.
-
- The signal will be disconnected from the slot when the dialog is closed.
-*/
-void QPrintDialog::open(QObject *receiver, const char *member)
-{
- Q_D(QPrintDialog);
- connect(this, SIGNAL(accepted(QPrinter*)), receiver, member);
- d->receiverToDisconnectOnClose = receiver;
- d->memberToDisconnectOnClose = member;
- QDialog::open();
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_PRINTDIALOG
diff --git a/src/gui/dialogs/qabstractprintdialog.h b/src/gui/dialogs/qabstractprintdialog.h
deleted file mode 100644
index d2117a80fc..0000000000
--- a/src/gui/dialogs/qabstractprintdialog.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QABSTRACTPRINTDIALOG_H
-#define QABSTRACTPRINTDIALOG_H
-
-#include <QtGui/qdialog.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_PRINTER
-
-class QAbstractPrintDialogPrivate;
-class QPrinter;
-
-// ### Qt 5: remove this class
-class Q_GUI_EXPORT QAbstractPrintDialog : public QDialog
-{
- Q_DECLARE_PRIVATE(QAbstractPrintDialog)
- Q_OBJECT
-
-public:
- enum PrintRange {
- AllPages,
- Selection,
- PageRange,
- CurrentPage
- };
-
- enum PrintDialogOption {
- None = 0x0000, // obsolete
- PrintToFile = 0x0001,
- PrintSelection = 0x0002,
- PrintPageRange = 0x0004,
- PrintShowPageSize = 0x0008,
- PrintCollateCopies = 0x0010,
- DontUseSheet = 0x0020,
- PrintCurrentPage = 0x0040
- };
-
- Q_DECLARE_FLAGS(PrintDialogOptions, PrintDialogOption)
-
-#ifndef QT_NO_PRINTDIALOG
- explicit QAbstractPrintDialog(QPrinter *printer, QWidget *parent = 0);
- ~QAbstractPrintDialog();
-
- virtual int exec() = 0;
-
- // obsolete
- void addEnabledOption(PrintDialogOption option);
- void setEnabledOptions(PrintDialogOptions options);
- PrintDialogOptions enabledOptions() const;
- bool isOptionEnabled(PrintDialogOption option) const;
-
- void setOptionTabs(const QList<QWidget*> &tabs);
-
- void setPrintRange(PrintRange range);
- PrintRange printRange() const;
-
- void setMinMax(int min, int max);
- int minPage() const;
- int maxPage() const;
-
- void setFromTo(int fromPage, int toPage);
- int fromPage() const;
- int toPage() const;
-
- QPrinter *printer() const;
-
-protected:
- QAbstractPrintDialog(QAbstractPrintDialogPrivate &ptr, QPrinter *printer, QWidget *parent = 0);
-
-private:
- Q_DISABLE_COPY(QAbstractPrintDialog)
-
-#endif // QT_NO_PRINTDIALOG
-};
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QAbstractPrintDialog::PrintDialogOptions)
-
-#endif // QT_NO_PRINTER
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QABSTRACTPRINTDIALOG_H
diff --git a/src/gui/dialogs/qabstractprintdialog_p.h b/src/gui/dialogs/qabstractprintdialog_p.h
deleted file mode 100644
index cda7607415..0000000000
--- a/src/gui/dialogs/qabstractprintdialog_p.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QABSTRACTPRINTDIALOG_P_H
-#define QABSTRACTPRINTDIALOG_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "private/qdialog_p.h"
-
-#ifndef QT_NO_PRINTDIALOG
-
-#include "QtGui/qabstractprintdialog.h"
-
-QT_BEGIN_NAMESPACE
-
-#ifndef QT_NO_PRINTER
-
-class QPrinter;
-class QPrinterPrivate;
-
-class QAbstractPrintDialogPrivate : public QDialogPrivate
-{
- Q_DECLARE_PUBLIC(QAbstractPrintDialog)
-
-public:
- QAbstractPrintDialogPrivate()
- : printer(0), pd(0), ownsPrinter(false)
- {
- }
-
- QPrinter *printer;
- QPrinterPrivate *pd;
- bool ownsPrinter;
- QPointer<QObject> receiverToDisconnectOnClose;
- QByteArray memberToDisconnectOnClose;
-
- virtual void setTabs(const QList<QWidget *> &) {}
- void setPrinter(QPrinter *newPrinter);
-};
-
-#endif //QT_NO_PRINTER
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_PRINTDIALOG
-
-#endif // QABSTRACTPRINTDIALOG_P_H
diff --git a/src/gui/dialogs/qcolordialog.cpp b/src/gui/dialogs/qcolordialog.cpp
deleted file mode 100644
index 015787433c..0000000000
--- a/src/gui/dialogs/qcolordialog.cpp
+++ /dev/null
@@ -1,2114 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qcolordialog_p.h"
-
-#ifndef QT_NO_COLORDIALOG
-
-#include "qapplication.h"
-#include "qdesktopwidget.h"
-#include "qdrawutil.h"
-#include "qevent.h"
-#include "qimage.h"
-#include "qlabel.h"
-#include "qlayout.h"
-#include "qlineedit.h"
-#include "qmenu.h"
-#include "qpainter.h"
-#include "qpixmap.h"
-#include "qpushbutton.h"
-#include "qsettings.h"
-#include "qstyle.h"
-#include "qstyleoption.h"
-#include "qvalidator.h"
-#include "qmime.h"
-#include "qspinbox.h"
-#include "qdialogbuttonbox.h"
-#include "private/qguiplatformplugin_p.h"
-
-#ifdef Q_WS_S60
-#include "private/qt_s60_p.h"
-#endif
-
-#if defined(Q_WS_S60) || defined(Q_WS_MAEMO_5)
-# define QT_SMALL_COLORDIALOG
-#endif
-
-QT_BEGIN_NAMESPACE
-
-//////////// QWellArray BEGIN
-
-struct QWellArrayData;
-
-class QWellArray : public QWidget
-{
- Q_OBJECT
- Q_PROPERTY(int selectedColumn READ selectedColumn)
- Q_PROPERTY(int selectedRow READ selectedRow)
-
-public:
- QWellArray(int rows, int cols, QWidget* parent=0);
- ~QWellArray() {}
- QString cellContent(int row, int col) const;
-
- int selectedColumn() const { return selCol; }
- int selectedRow() const { return selRow; }
-
- virtual void setCurrent(int row, int col);
- virtual void setSelected(int row, int col);
-
- QSize sizeHint() const;
-
- virtual void setCellBrush(int row, int col, const QBrush &);
- QBrush cellBrush(int row, int col);
-
- inline int cellWidth() const
- { return cellw; }
-
- inline int cellHeight() const
- { return cellh; }
-
- inline int rowAt(int y) const
- { return y / cellh; }
-
- inline int columnAt(int x) const
- { if (isRightToLeft()) return ncols - (x / cellw) - 1; return x / cellw; }
-
- inline int rowY(int row) const
- { return cellh * row; }
-
- inline int columnX(int column) const
- { if (isRightToLeft()) return cellw * (ncols - column - 1); return cellw * column; }
-
- inline int numRows() const
- { return nrows; }
-
- inline int numCols() const
- {return ncols; }
-
- inline QRect cellRect() const
- { return QRect(0, 0, cellw, cellh); }
-
- inline QSize gridSize() const
- { return QSize(ncols * cellw, nrows * cellh); }
-
- QRect cellGeometry(int row, int column)
- {
- QRect r;
- if (row >= 0 && row < nrows && column >= 0 && column < ncols)
- r.setRect(columnX(column), rowY(row), cellw, cellh);
- return r;
- }
-
- inline void updateCell(int row, int column) { update(cellGeometry(row, column)); }
-
-signals:
- void selected(int row, int col);
-
-protected:
- virtual void paintCell(QPainter *, int row, int col, const QRect&);
- virtual void paintCellContents(QPainter *, int row, int col, const QRect&);
-
- void mousePressEvent(QMouseEvent*);
- void mouseReleaseEvent(QMouseEvent*);
- void keyPressEvent(QKeyEvent*);
- void focusInEvent(QFocusEvent*);
- void focusOutEvent(QFocusEvent*);
- void paintEvent(QPaintEvent *);
-
-private:
- Q_DISABLE_COPY(QWellArray)
-
- int nrows;
- int ncols;
- int cellw;
- int cellh;
- int curRow;
- int curCol;
- int selRow;
- int selCol;
- QWellArrayData *d;
-};
-
-void QWellArray::paintEvent(QPaintEvent *e)
-{
- QRect r = e->rect();
- int cx = r.x();
- int cy = r.y();
- int ch = r.height();
- int cw = r.width();
- int colfirst = columnAt(cx);
- int collast = columnAt(cx + cw);
- int rowfirst = rowAt(cy);
- int rowlast = rowAt(cy + ch);
-
- if (isRightToLeft()) {
- int t = colfirst;
- colfirst = collast;
- collast = t;
- }
-
- QPainter painter(this);
- QPainter *p = &painter;
- QRect rect(0, 0, cellWidth(), cellHeight());
-
-
- if (collast < 0 || collast >= ncols)
- collast = ncols-1;
- if (rowlast < 0 || rowlast >= nrows)
- rowlast = nrows-1;
-
- // Go through the rows
- for (int r = rowfirst; r <= rowlast; ++r) {
- // get row position and height
- int rowp = rowY(r);
-
- // Go through the columns in the row r
- // if we know from where to where, go through [colfirst, collast],
- // else go through all of them
- for (int c = colfirst; c <= collast; ++c) {
- // get position and width of column c
- int colp = columnX(c);
- // Translate painter and draw the cell
- rect.translate(colp, rowp);
- paintCell(p, r, c, rect);
- rect.translate(-colp, -rowp);
- }
- }
-}
-
-struct QWellArrayData {
- QBrush *brush;
-};
-
-QWellArray::QWellArray(int rows, int cols, QWidget *parent)
- : QWidget(parent)
- ,nrows(rows), ncols(cols)
-{
- d = 0;
- setFocusPolicy(Qt::StrongFocus);
- cellw = 28;
- cellh = 24;
- curCol = 0;
- curRow = 0;
- selCol = -1;
- selRow = -1;
-}
-
-QSize QWellArray::sizeHint() const
-{
- ensurePolished();
- return gridSize().boundedTo(QSize(640, 480));
-}
-
-
-void QWellArray::paintCell(QPainter* p, int row, int col, const QRect &rect)
-{
- int b = 3; //margin
-
- const QPalette & g = palette();
- QStyleOptionFrame opt;
- int dfw = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
- opt.lineWidth = dfw;
- opt.midLineWidth = 1;
- opt.rect = rect.adjusted(b, b, -b, -b);
- opt.palette = g;
- opt.state = QStyle::State_Enabled | QStyle::State_Sunken;
- style()->drawPrimitive(QStyle::PE_Frame, &opt, p, this);
- b += dfw;
-
- if ((row == curRow) && (col == curCol)) {
- if (hasFocus()) {
- QStyleOptionFocusRect opt;
- opt.palette = g;
- opt.rect = rect;
- opt.state = QStyle::State_None | QStyle::State_KeyboardFocusChange;
- style()->drawPrimitive(QStyle::PE_FrameFocusRect, &opt, p, this);
- }
- }
- paintCellContents(p, row, col, opt.rect.adjusted(dfw, dfw, -dfw, -dfw));
-}
-
-/*!
- Reimplement this function to change the contents of the well array.
- */
-void QWellArray::paintCellContents(QPainter *p, int row, int col, const QRect &r)
-{
- if (d) {
- p->fillRect(r, d->brush[row*numCols()+col]);
- } else {
- p->fillRect(r, Qt::white);
- p->setPen(Qt::black);
- p->drawLine(r.topLeft(), r.bottomRight());
- p->drawLine(r.topRight(), r.bottomLeft());
- }
-}
-
-void QWellArray::mousePressEvent(QMouseEvent *e)
-{
- // The current cell marker is set to the cell the mouse is pressed in
- QPoint pos = e->pos();
- setCurrent(rowAt(pos.y()), columnAt(pos.x()));
-}
-
-void QWellArray::mouseReleaseEvent(QMouseEvent * /* event */)
-{
- // The current cell marker is set to the cell the mouse is clicked in
- setSelected(curRow, curCol);
-}
-
-
-/*
- Sets the cell currently having the focus. This is not necessarily
- the same as the currently selected cell.
-*/
-
-void QWellArray::setCurrent(int row, int col)
-{
- if ((curRow == row) && (curCol == col))
- return;
-
- if (row < 0 || col < 0)
- row = col = -1;
-
- int oldRow = curRow;
- int oldCol = curCol;
-
- curRow = row;
- curCol = col;
-
- updateCell(oldRow, oldCol);
- updateCell(curRow, curCol);
-}
-
-/*
- Sets the currently selected cell to \a row, \a column. If \a row or
- \a column are less than zero, the current cell is unselected.
-
- Does not set the position of the focus indicator.
-*/
-void QWellArray::setSelected(int row, int col)
-{
- int oldRow = selRow;
- int oldCol = selCol;
-
- if (row < 0 || col < 0)
- row = col = -1;
-
- selCol = col;
- selRow = row;
-
- updateCell(oldRow, oldCol);
- updateCell(selRow, selCol);
- if (row >= 0)
- emit selected(row, col);
-
-#ifndef QT_NO_MENU
- if (isVisible() && qobject_cast<QMenu*>(parentWidget()))
- parentWidget()->close();
-#endif
-}
-
-void QWellArray::focusInEvent(QFocusEvent*)
-{
- updateCell(curRow, curCol);
-}
-
-void QWellArray::setCellBrush(int row, int col, const QBrush &b)
-{
- if (!d) {
- d = new QWellArrayData;
- int i = numRows()*numCols();
- d->brush = new QBrush[i];
- }
- if (row >= 0 && row < numRows() && col >= 0 && col < numCols())
- d->brush[row*numCols()+col] = b;
-}
-
-/*
- Returns the brush set for the cell at \a row, \a column. If no brush is
- set, Qt::NoBrush is returned.
-*/
-
-QBrush QWellArray::cellBrush(int row, int col)
-{
- if (d && row >= 0 && row < numRows() && col >= 0 && col < numCols())
- return d->brush[row*numCols()+col];
- return Qt::NoBrush;
-}
-
-
-
-/*!\reimp
-*/
-
-void QWellArray::focusOutEvent(QFocusEvent*)
-{
- updateCell(curRow, curCol);
-}
-
-/*\reimp
-*/
-void QWellArray::keyPressEvent(QKeyEvent* e)
-{
- switch(e->key()) { // Look at the key code
- case Qt::Key_Left: // If 'left arrow'-key,
- if(curCol > 0) // and cr't not in leftmost col
- setCurrent(curRow, curCol - 1); // set cr't to next left column
- break;
- case Qt::Key_Right: // Correspondingly...
- if(curCol < numCols()-1)
- setCurrent(curRow, curCol + 1);
- break;
- case Qt::Key_Up:
- if(curRow > 0)
- setCurrent(curRow - 1, curCol);
- break;
- case Qt::Key_Down:
- if(curRow < numRows()-1)
- setCurrent(curRow + 1, curCol);
- break;
-#if 0
- // bad idea that shouldn't have been implemented; very counterintuitive
- case Qt::Key_Return:
- case Qt::Key_Enter:
- /*
- ignore the key, so that the dialog get it, but still select
- the current row/col
- */
- e->ignore();
- // fallthrough intended
-#endif
- case Qt::Key_Space:
- setSelected(curRow, curCol);
- break;
- default: // If not an interesting key,
- e->ignore(); // we don't accept the event
- return;
- }
-
-}
-
-//////////// QWellArray END
-
-static bool initrgb = false;
-static QRgb stdrgb[6*8];
-static QRgb cusrgb[2*8];
-static bool customSet = false;
-
-
-static void initRGB()
-{
- if (initrgb)
- return;
- initrgb = true;
- int i = 0;
- for (int g = 0; g < 4; g++)
- for (int r = 0; r < 4; r++)
- for (int b = 0; b < 3; b++)
- stdrgb[i++] = qRgb(r * 255 / 3, g * 255 / 3, b * 255 / 2);
-
- for (i = 0; i < 2*8; i++)
- cusrgb[i] = 0xffffffff;
-}
-
-/*!
- Returns the number of custom colors supported by QColorDialog. All
- color dialogs share the same custom colors.
-*/
-int QColorDialog::customCount()
-{
- return 2 * 8;
-}
-
-/*!
- \since 4.5
-
- Returns the custom color at the given \a index as a QRgb value.
-*/
-QRgb QColorDialog::customColor(int index)
-{
- if (uint(index) >= uint(customCount()))
- return qRgb(255, 255, 255);
- initRGB();
- return cusrgb[index];
-}
-
-/*!
- Sets the custom color at \a index to the QRgb \a color value.
-
- \note This function does not apply to the Native Color Dialog on the Mac
- OS X platform. If you still require this function, use the
- QColorDialog::DontUseNativeDialog option.
-*/
-void QColorDialog::setCustomColor(int index, QRgb color)
-{
- if (uint(index) >= uint(customCount()))
- return;
- initRGB();
- customSet = true;
- cusrgb[index] = color;
-}
-
-/*!
- Sets the standard color at \a index to the QRgb \a color value.
-
- \note This function does not apply to the Native Color Dialog on the Mac
- OS X platform. If you still require this function, use the
- QColorDialog::DontUseNativeDialog option.
-*/
-
-void QColorDialog::setStandardColor(int index, QRgb color)
-{
- if (uint(index) >= uint(6 * 8))
- return;
- initRGB();
- stdrgb[index] = color;
-}
-
-static inline void rgb2hsv(QRgb rgb, int &h, int &s, int &v)
-{
- QColor c;
- c.setRgb(rgb);
- c.getHsv(&h, &s, &v);
-}
-
-class QColorWell : public QWellArray
-{
-public:
- QColorWell(QWidget *parent, int r, int c, QRgb *vals)
- :QWellArray(r, c, parent), values(vals), mousePressed(false), oldCurrent(-1, -1)
- { setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum)); }
-
-protected:
- void paintCellContents(QPainter *, int row, int col, const QRect&);
- void mousePressEvent(QMouseEvent *e);
- void mouseMoveEvent(QMouseEvent *e);
- void mouseReleaseEvent(QMouseEvent *e);
-#ifndef QT_NO_DRAGANDDROP
- void dragEnterEvent(QDragEnterEvent *e);
- void dragLeaveEvent(QDragLeaveEvent *e);
- void dragMoveEvent(QDragMoveEvent *e);
- void dropEvent(QDropEvent *e);
-#endif
-
-private:
- QRgb *values;
- bool mousePressed;
- QPoint pressPos;
- QPoint oldCurrent;
-
-};
-
-void QColorWell::paintCellContents(QPainter *p, int row, int col, const QRect &r)
-{
- int i = row + col*numRows();
- p->fillRect(r, QColor(values[i]));
-}
-
-void QColorWell::mousePressEvent(QMouseEvent *e)
-{
- oldCurrent = QPoint(selectedRow(), selectedColumn());
- QWellArray::mousePressEvent(e);
- mousePressed = true;
- pressPos = e->pos();
-}
-
-void QColorWell::mouseMoveEvent(QMouseEvent *e)
-{
- QWellArray::mouseMoveEvent(e);
-#ifndef QT_NO_DRAGANDDROP
- if (!mousePressed)
- return;
- if ((pressPos - e->pos()).manhattanLength() > QApplication::startDragDistance()) {
- setCurrent(oldCurrent.x(), oldCurrent.y());
- int i = rowAt(pressPos.y()) + columnAt(pressPos.x()) * numRows();
- QColor col(values[i]);
- QMimeData *mime = new QMimeData;
- mime->setColorData(col);
- QPixmap pix(cellWidth(), cellHeight());
- pix.fill(col);
- QPainter p(&pix);
- p.drawRect(0, 0, pix.width() - 1, pix.height() - 1);
- p.end();
- QDrag *drg = new QDrag(this);
- drg->setMimeData(mime);
- drg->setPixmap(pix);
- mousePressed = false;
- drg->start();
- }
-#endif
-}
-
-#ifndef QT_NO_DRAGANDDROP
-void QColorWell::dragEnterEvent(QDragEnterEvent *e)
-{
- if (qvariant_cast<QColor>(e->mimeData()->colorData()).isValid())
- e->accept();
- else
- e->ignore();
-}
-
-void QColorWell::dragLeaveEvent(QDragLeaveEvent *)
-{
- if (hasFocus())
- parentWidget()->setFocus();
-}
-
-void QColorWell::dragMoveEvent(QDragMoveEvent *e)
-{
- if (qvariant_cast<QColor>(e->mimeData()->colorData()).isValid()) {
- setCurrent(rowAt(e->pos().y()), columnAt(e->pos().x()));
- e->accept();
- } else {
- e->ignore();
- }
-}
-
-void QColorWell::dropEvent(QDropEvent *e)
-{
- QColor col = qvariant_cast<QColor>(e->mimeData()->colorData());
- if (col.isValid()) {
- int i = rowAt(e->pos().y()) + columnAt(e->pos().x()) * numRows();
- values[i] = col.rgb();
- update();
- e->accept();
- } else {
- e->ignore();
- }
-}
-
-#endif // QT_NO_DRAGANDDROP
-
-void QColorWell::mouseReleaseEvent(QMouseEvent *e)
-{
- if (!mousePressed)
- return;
- QWellArray::mouseReleaseEvent(e);
- mousePressed = false;
-}
-
-class QColorPicker : public QFrame
-{
- Q_OBJECT
-public:
- QColorPicker(QWidget* parent);
- ~QColorPicker();
-
-public slots:
- void setCol(int h, int s);
-
-signals:
- void newCol(int h, int s);
-
-protected:
- QSize sizeHint() const;
- void paintEvent(QPaintEvent*);
- void mouseMoveEvent(QMouseEvent *);
- void mousePressEvent(QMouseEvent *);
- void resizeEvent(QResizeEvent *);
-
-private:
- int hue;
- int sat;
-
- QPoint colPt();
- int huePt(const QPoint &pt);
- int satPt(const QPoint &pt);
- void setCol(const QPoint &pt);
-
- QPixmap pix;
-};
-
-static int pWidth = 220;
-static int pHeight = 200;
-
-class QColorLuminancePicker : public QWidget
-{
- Q_OBJECT
-public:
- QColorLuminancePicker(QWidget* parent=0);
- ~QColorLuminancePicker();
-
-public slots:
- void setCol(int h, int s, int v);
- void setCol(int h, int s);
-
-signals:
- void newHsv(int h, int s, int v);
-
-protected:
- void paintEvent(QPaintEvent*);
- void mouseMoveEvent(QMouseEvent *);
- void mousePressEvent(QMouseEvent *);
-
-private:
- enum { foff = 3, coff = 4 }; //frame and contents offset
- int val;
- int hue;
- int sat;
-
- int y2val(int y);
- int val2y(int val);
- void setVal(int v);
-
- QPixmap *pix;
-};
-
-
-int QColorLuminancePicker::y2val(int y)
-{
- int d = height() - 2*coff - 1;
- return 255 - (y - coff)*255/d;
-}
-
-int QColorLuminancePicker::val2y(int v)
-{
- int d = height() - 2*coff - 1;
- return coff + (255-v)*d/255;
-}
-
-QColorLuminancePicker::QColorLuminancePicker(QWidget* parent)
- :QWidget(parent)
-{
- hue = 100; val = 100; sat = 100;
- pix = 0;
- // setAttribute(WA_NoErase, true);
-}
-
-QColorLuminancePicker::~QColorLuminancePicker()
-{
- delete pix;
-}
-
-void QColorLuminancePicker::mouseMoveEvent(QMouseEvent *m)
-{
- setVal(y2val(m->y()));
-}
-void QColorLuminancePicker::mousePressEvent(QMouseEvent *m)
-{
- setVal(y2val(m->y()));
-}
-
-void QColorLuminancePicker::setVal(int v)
-{
- if (val == v)
- return;
- val = qMax(0, qMin(v,255));
- delete pix; pix=0;
- repaint();
- emit newHsv(hue, sat, val);
-}
-
-//receives from a hue,sat chooser and relays.
-void QColorLuminancePicker::setCol(int h, int s)
-{
- setCol(h, s, val);
- emit newHsv(h, s, val);
-}
-
-void QColorLuminancePicker::paintEvent(QPaintEvent *)
-{
- int w = width() - 5;
-
- QRect r(0, foff, w, height() - 2*foff);
- int wi = r.width() - 2;
- int hi = r.height() - 2;
- if (!pix || pix->height() != hi || pix->width() != wi) {
- delete pix;
- QImage img(wi, hi, QImage::Format_RGB32);
- int y;
- uint *pixel = (uint *) img.scanLine(0);
- for (y = 0; y < hi; y++) {
- const uint *end = pixel + wi;
- while (pixel < end) {
- QColor c;
- c.setHsv(hue, sat, y2val(y+coff));
- *pixel = c.rgb();
- ++pixel;
- }
- }
- pix = new QPixmap(QPixmap::fromImage(img));
- }
- QPainter p(this);
- p.drawPixmap(1, coff, *pix);
- const QPalette &g = palette();
- qDrawShadePanel(&p, r, g, true);
- p.setPen(g.foreground().color());
- p.setBrush(g.foreground());
- QPolygon a;
- int y = val2y(val);
- a.setPoints(3, w, y, w+5, y+5, w+5, y-5);
- p.eraseRect(w, 0, 5, height());
- p.drawPolygon(a);
-}
-
-void QColorLuminancePicker::setCol(int h, int s , int v)
-{
- val = v;
- hue = h;
- sat = s;
- delete pix; pix=0;
- repaint();
-}
-
-QPoint QColorPicker::colPt()
-{
- QRect r = contentsRect();
- return QPoint((360 - hue) * (r.width() - 1) / 360, (255 - sat) * (r.height() - 1) / 255);
-}
-
-int QColorPicker::huePt(const QPoint &pt)
-{
- QRect r = contentsRect();
- return 360 - pt.x() * 360 / (r.width() - 1);
-}
-
-int QColorPicker::satPt(const QPoint &pt)
-{
- QRect r = contentsRect();
- return 255 - pt.y() * 255 / (r.height() - 1);
-}
-
-void QColorPicker::setCol(const QPoint &pt)
-{
- setCol(huePt(pt), satPt(pt));
-}
-
-QColorPicker::QColorPicker(QWidget* parent)
- : QFrame(parent)
-{
- hue = 0; sat = 0;
- setCol(150, 255);
-
- setAttribute(Qt::WA_NoSystemBackground);
- setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed) );
-}
-
-QColorPicker::~QColorPicker()
-{
-}
-
-QSize QColorPicker::sizeHint() const
-{
- return QSize(pWidth + 2*frameWidth(), pHeight + 2*frameWidth());
-}
-
-void QColorPicker::setCol(int h, int s)
-{
- int nhue = qMin(qMax(0,h), 359);
- int nsat = qMin(qMax(0,s), 255);
- if (nhue == hue && nsat == sat)
- return;
-
- QRect r(colPt(), QSize(20,20));
- hue = nhue; sat = nsat;
- r = r.united(QRect(colPt(), QSize(20,20)));
- r.translate(contentsRect().x()-9, contentsRect().y()-9);
- // update(r);
- repaint(r);
-}
-
-void QColorPicker::mouseMoveEvent(QMouseEvent *m)
-{
- QPoint p = m->pos() - contentsRect().topLeft();
- setCol(p);
- emit newCol(hue, sat);
-}
-
-void QColorPicker::mousePressEvent(QMouseEvent *m)
-{
- QPoint p = m->pos() - contentsRect().topLeft();
- setCol(p);
- emit newCol(hue, sat);
-}
-
-void QColorPicker::paintEvent(QPaintEvent* )
-{
- QPainter p(this);
- drawFrame(&p);
- QRect r = contentsRect();
-
- p.drawPixmap(r.topLeft(), pix);
- QPoint pt = colPt() + r.topLeft();
- p.setPen(Qt::black);
-
- p.fillRect(pt.x()-9, pt.y(), 20, 2, Qt::black);
- p.fillRect(pt.x(), pt.y()-9, 2, 20, Qt::black);
-
-}
-
-void QColorPicker::resizeEvent(QResizeEvent *ev)
-{
- QFrame::resizeEvent(ev);
-
- int w = width() - frameWidth() * 2;
- int h = height() - frameWidth() * 2;
- QImage img(w, h, QImage::Format_RGB32);
- int x, y;
- uint *pixel = (uint *) img.scanLine(0);
- for (y = 0; y < h; y++) {
- const uint *end = pixel + w;
- x = 0;
- while (pixel < end) {
- QPoint p(x, y);
- QColor c;
- c.setHsv(huePt(p), satPt(p), 200);
- *pixel = c.rgb();
- ++pixel;
- ++x;
- }
- }
- pix = QPixmap::fromImage(img);
-}
-
-
-class QColSpinBox : public QSpinBox
-{
-public:
- QColSpinBox(QWidget *parent)
- : QSpinBox(parent) { setRange(0, 255); }
- void setValue(int i) {
- bool block = signalsBlocked();
- blockSignals(true);
- QSpinBox::setValue(i);
- blockSignals(block);
- }
-};
-
-class QColorShowLabel;
-
-class QColorShower : public QWidget
-{
- Q_OBJECT
-public:
- QColorShower(QColorDialog *parent);
-
- //things that don't emit signals
- void setHsv(int h, int s, int v);
-
- int currentAlpha() const
- { return (colorDialog->options() & QColorDialog::ShowAlphaChannel) ? alphaEd->value() : 255; }
- void setCurrentAlpha(int a) { alphaEd->setValue(a); rgbEd(); }
- void showAlpha(bool b);
- bool isAlphaVisible() const;
-
- QRgb currentColor() const { return curCol; }
- QColor currentQColor() const { return curQColor; }
- void retranslateStrings();
- void updateQColor();
-
-public slots:
- void setRgb(QRgb rgb);
-
-signals:
- void newCol(QRgb rgb);
- void currentColorChanged(const QColor &color);
-
-private slots:
- void rgbEd();
- void hsvEd();
-private:
- void showCurrentColor();
- int hue, sat, val;
- QRgb curCol;
- QColor curQColor;
- QLabel *lblHue;
- QLabel *lblSat;
- QLabel *lblVal;
- QLabel *lblRed;
- QLabel *lblGreen;
- QLabel *lblBlue;
- QColSpinBox *hEd;
- QColSpinBox *sEd;
- QColSpinBox *vEd;
- QColSpinBox *rEd;
- QColSpinBox *gEd;
- QColSpinBox *bEd;
- QColSpinBox *alphaEd;
- QLabel *alphaLab;
- QColorShowLabel *lab;
- bool rgbOriginal;
- QColorDialog *colorDialog;
-
- friend class QColorDialog;
- friend class QColorDialogPrivate;
-};
-
-class QColorShowLabel : public QFrame
-{
- Q_OBJECT
-
-public:
- QColorShowLabel(QWidget *parent) : QFrame(parent) {
- setFrameStyle(QFrame::Panel|QFrame::Sunken);
- setAcceptDrops(true);
- mousePressed = false;
- }
- void setColor(QColor c) { col = c; }
-
-signals:
- void colorDropped(QRgb);
-
-protected:
- void paintEvent(QPaintEvent *);
- void mousePressEvent(QMouseEvent *e);
- void mouseMoveEvent(QMouseEvent *e);
- void mouseReleaseEvent(QMouseEvent *e);
-#ifndef QT_NO_DRAGANDDROP
- void dragEnterEvent(QDragEnterEvent *e);
- void dragLeaveEvent(QDragLeaveEvent *e);
- void dropEvent(QDropEvent *e);
-#endif
-
-private:
- QColor col;
- bool mousePressed;
- QPoint pressPos;
-};
-
-void QColorShowLabel::paintEvent(QPaintEvent *e)
-{
- QPainter p(this);
- drawFrame(&p);
- p.fillRect(contentsRect()&e->rect(), col);
-}
-
-void QColorShower::showAlpha(bool b)
-{
- alphaLab->setVisible(b);
- alphaEd->setVisible(b);
-}
-
-inline bool QColorShower::isAlphaVisible() const
-{
- return alphaLab->isVisible();
-}
-
-void QColorShowLabel::mousePressEvent(QMouseEvent *e)
-{
- mousePressed = true;
- pressPos = e->pos();
-}
-
-void QColorShowLabel::mouseMoveEvent(QMouseEvent *e)
-{
-#ifdef QT_NO_DRAGANDDROP
- Q_UNUSED(e);
-#else
- if (!mousePressed)
- return;
- if ((pressPos - e->pos()).manhattanLength() > QApplication::startDragDistance()) {
- QMimeData *mime = new QMimeData;
- mime->setColorData(col);
- QPixmap pix(30, 20);
- pix.fill(col);
- QPainter p(&pix);
- p.drawRect(0, 0, pix.width() - 1, pix.height() - 1);
- p.end();
- QDrag *drg = new QDrag(this);
- drg->setMimeData(mime);
- drg->setPixmap(pix);
- mousePressed = false;
- drg->start();
- }
-#endif
-}
-
-#ifndef QT_NO_DRAGANDDROP
-void QColorShowLabel::dragEnterEvent(QDragEnterEvent *e)
-{
- if (qvariant_cast<QColor>(e->mimeData()->colorData()).isValid())
- e->accept();
- else
- e->ignore();
-}
-
-void QColorShowLabel::dragLeaveEvent(QDragLeaveEvent *)
-{
-}
-
-void QColorShowLabel::dropEvent(QDropEvent *e)
-{
- QColor color = qvariant_cast<QColor>(e->mimeData()->colorData());
- if (color.isValid()) {
- col = color;
- repaint();
- emit colorDropped(col.rgb());
- e->accept();
- } else {
- e->ignore();
- }
-}
-#endif // QT_NO_DRAGANDDROP
-
-void QColorShowLabel::mouseReleaseEvent(QMouseEvent *)
-{
- if (!mousePressed)
- return;
- mousePressed = false;
-}
-
-QColorShower::QColorShower(QColorDialog *parent)
- : QWidget(parent)
-{
- colorDialog = parent;
-
- curCol = qRgb(255, 255, 255);
- curQColor = Qt::white;
-
- QGridLayout *gl = new QGridLayout(this);
- gl->setMargin(gl->spacing());
- lab = new QColorShowLabel(this);
-
-#ifdef QT_SMALL_COLORDIALOG
-# ifdef Q_WS_S60
- const bool nonTouchUI = !S60->hasTouchscreen;
-# elif defined Q_WS_MAEMO_5
- const bool nonTouchUI = false;
-# endif
-#endif
-
-#ifndef Q_WS_WINCE
-#ifdef QT_SMALL_COLORDIALOG
- lab->setMinimumHeight(60);
-#endif
- lab->setMinimumWidth(60);
-#else
- lab->setMinimumWidth(20);
-#endif
-
-// In S60, due to small screen and different screen layouts need to re-arrange the widgets.
-// For QVGA screens only the comboboxes and color label are visible.
-// For nHD screens only color and luminence pickers and color label are visible.
-#if !defined(QT_SMALL_COLORDIALOG)
- gl->addWidget(lab, 0, 0, -1, 1);
-#else
- if (nonTouchUI)
- gl->addWidget(lab, 0, 0, 1, -1);
- else
- gl->addWidget(lab, 0, 0, -1, 1);
-#endif
- connect(lab, SIGNAL(colorDropped(QRgb)), this, SIGNAL(newCol(QRgb)));
- connect(lab, SIGNAL(colorDropped(QRgb)), this, SLOT(setRgb(QRgb)));
-
- hEd = new QColSpinBox(this);
- hEd->setRange(0, 359);
- lblHue = new QLabel(this);
-#ifndef QT_NO_SHORTCUT
- lblHue->setBuddy(hEd);
-#endif
- lblHue->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
-#if !defined(QT_SMALL_COLORDIALOG)
- gl->addWidget(lblHue, 0, 1);
- gl->addWidget(hEd, 0, 2);
-#else
- if (nonTouchUI) {
- gl->addWidget(lblHue, 1, 0);
- gl->addWidget(hEd, 2, 0);
- } else {
- lblHue->hide();
- hEd->hide();
- }
-#endif
-
- sEd = new QColSpinBox(this);
- lblSat = new QLabel(this);
-#ifndef QT_NO_SHORTCUT
- lblSat->setBuddy(sEd);
-#endif
- lblSat->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
-#if !defined(QT_SMALL_COLORDIALOG)
- gl->addWidget(lblSat, 1, 1);
- gl->addWidget(sEd, 1, 2);
-#else
- if (nonTouchUI) {
- gl->addWidget(lblSat, 1, 1);
- gl->addWidget(sEd, 2, 1);
- } else {
- lblSat->hide();
- sEd->hide();
- }
-#endif
-
- vEd = new QColSpinBox(this);
- lblVal = new QLabel(this);
-#ifndef QT_NO_SHORTCUT
- lblVal->setBuddy(vEd);
-#endif
- lblVal->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
-#if !defined(QT_SMALL_COLORDIALOG)
- gl->addWidget(lblVal, 2, 1);
- gl->addWidget(vEd, 2, 2);
-#else
- if (nonTouchUI) {
- gl->addWidget(lblVal, 1, 2);
- gl->addWidget(vEd, 2, 2);
- } else {
- lblVal->hide();
- vEd->hide();
- }
-#endif
-
- rEd = new QColSpinBox(this);
- lblRed = new QLabel(this);
-#ifndef QT_NO_SHORTCUT
- lblRed->setBuddy(rEd);
-#endif
- lblRed->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
-#if !defined(QT_SMALL_COLORDIALOG)
- gl->addWidget(lblRed, 0, 3);
- gl->addWidget(rEd, 0, 4);
-#else
- if (nonTouchUI) {
- gl->addWidget(lblRed, 3, 0);
- gl->addWidget(rEd, 4, 0);
- } else {
- lblRed->hide();
- rEd->hide();
- }
-#endif
-
- gEd = new QColSpinBox(this);
- lblGreen = new QLabel(this);
-#ifndef QT_NO_SHORTCUT
- lblGreen->setBuddy(gEd);
-#endif
- lblGreen->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
-#if !defined(QT_SMALL_COLORDIALOG)
- gl->addWidget(lblGreen, 1, 3);
- gl->addWidget(gEd, 1, 4);
-#else
- if (nonTouchUI) {
- gl->addWidget(lblGreen, 3, 1);
- gl->addWidget(gEd, 4, 1);
- } else {
- lblGreen->hide();
- gEd->hide();
- }
-#endif
-
- bEd = new QColSpinBox(this);
- lblBlue = new QLabel(this);
-#ifndef QT_NO_SHORTCUT
- lblBlue->setBuddy(bEd);
-#endif
- lblBlue->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
-#if !defined(QT_SMALL_COLORDIALOG)
- gl->addWidget(lblBlue, 2, 3);
- gl->addWidget(bEd, 2, 4);
-#else
- if (nonTouchUI) {
- gl->addWidget(lblBlue, 3, 2);
- gl->addWidget(bEd, 4, 2);
- } else {
- lblBlue->hide();
- bEd->hide();
- }
-#endif
-
- alphaEd = new QColSpinBox(this);
- alphaLab = new QLabel(this);
-#ifndef QT_NO_SHORTCUT
- alphaLab->setBuddy(alphaEd);
-#endif
- alphaLab->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
-#if !defined(QT_SMALL_COLORDIALOG)
- gl->addWidget(alphaLab, 3, 1, 1, 3);
- gl->addWidget(alphaEd, 3, 4);
-#else
- if (nonTouchUI) {
- gl->addWidget(alphaLab, 1, 3, 3, 1);
- gl->addWidget(alphaEd, 4, 3);
- } else {
- alphaLab->hide();
- alphaEd->hide();
- }
-#endif
- alphaEd->hide();
- alphaLab->hide();
-
- connect(hEd, SIGNAL(valueChanged(int)), this, SLOT(hsvEd()));
- connect(sEd, SIGNAL(valueChanged(int)), this, SLOT(hsvEd()));
- connect(vEd, SIGNAL(valueChanged(int)), this, SLOT(hsvEd()));
-
- connect(rEd, SIGNAL(valueChanged(int)), this, SLOT(rgbEd()));
- connect(gEd, SIGNAL(valueChanged(int)), this, SLOT(rgbEd()));
- connect(bEd, SIGNAL(valueChanged(int)), this, SLOT(rgbEd()));
- connect(alphaEd, SIGNAL(valueChanged(int)), this, SLOT(rgbEd()));
-
- retranslateStrings();
-}
-
-inline QRgb QColorDialogPrivate::currentColor() const { return cs->currentColor(); }
-inline int QColorDialogPrivate::currentAlpha() const { return cs->currentAlpha(); }
-inline void QColorDialogPrivate::setCurrentAlpha(int a) { cs->setCurrentAlpha(a); }
-inline void QColorDialogPrivate::showAlpha(bool b) { cs->showAlpha(b); }
-inline bool QColorDialogPrivate::isAlphaVisible() const { return cs->isAlphaVisible(); }
-
-QColor QColorDialogPrivate::currentQColor() const
-{
- return cs->currentQColor();
-}
-
-void QColorShower::showCurrentColor()
-{
- lab->setColor(currentColor());
- lab->repaint();
-}
-
-void QColorShower::rgbEd()
-{
- rgbOriginal = true;
- curCol = qRgba(rEd->value(), gEd->value(), bEd->value(), currentAlpha());
-
- rgb2hsv(currentColor(), hue, sat, val);
-
- hEd->setValue(hue);
- sEd->setValue(sat);
- vEd->setValue(val);
-
- showCurrentColor();
- emit newCol(currentColor());
- updateQColor();
-}
-
-void QColorShower::hsvEd()
-{
- rgbOriginal = false;
- hue = hEd->value();
- sat = sEd->value();
- val = vEd->value();
-
- QColor c;
- c.setHsv(hue, sat, val);
- curCol = c.rgb();
-
- rEd->setValue(qRed(currentColor()));
- gEd->setValue(qGreen(currentColor()));
- bEd->setValue(qBlue(currentColor()));
-
- showCurrentColor();
- emit newCol(currentColor());
- updateQColor();
-}
-
-void QColorShower::setRgb(QRgb rgb)
-{
- rgbOriginal = true;
- curCol = rgb;
-
- rgb2hsv(currentColor(), hue, sat, val);
-
- hEd->setValue(hue);
- sEd->setValue(sat);
- vEd->setValue(val);
-
- rEd->setValue(qRed(currentColor()));
- gEd->setValue(qGreen(currentColor()));
- bEd->setValue(qBlue(currentColor()));
-
- showCurrentColor();
- updateQColor();
-}
-
-void QColorShower::setHsv(int h, int s, int v)
-{
- if (h < -1 || (uint)s > 255 || (uint)v > 255)
- return;
-
- rgbOriginal = false;
- hue = h; val = v; sat = s;
- QColor c;
- c.setHsv(hue, sat, val);
- curCol = c.rgb();
-
- hEd->setValue(hue);
- sEd->setValue(sat);
- vEd->setValue(val);
-
- rEd->setValue(qRed(currentColor()));
- gEd->setValue(qGreen(currentColor()));
- bEd->setValue(qBlue(currentColor()));
-
- showCurrentColor();
- updateQColor();
-}
-
-void QColorShower::retranslateStrings()
-{
- lblHue->setText(QColorDialog::tr("Hu&e:"));
- lblSat->setText(QColorDialog::tr("&Sat:"));
- lblVal->setText(QColorDialog::tr("&Val:"));
- lblRed->setText(QColorDialog::tr("&Red:"));
- lblGreen->setText(QColorDialog::tr("&Green:"));
- lblBlue->setText(QColorDialog::tr("Bl&ue:"));
- alphaLab->setText(QColorDialog::tr("A&lpha channel:"));
-}
-
-void QColorShower::updateQColor()
-{
- QColor oldQColor(curQColor);
- curQColor.setRgba(qRgba(qRed(curCol), qGreen(curCol), qBlue(curCol), currentAlpha()));
- if (curQColor != oldQColor)
- emit currentColorChanged(curQColor);
-}
-
-//sets all widgets to display h,s,v
-void QColorDialogPrivate::_q_newHsv(int h, int s, int v)
-{
- cs->setHsv(h, s, v);
- cp->setCol(h, s);
- lp->setCol(h, s, v);
-}
-
-//sets all widgets to display rgb
-void QColorDialogPrivate::setCurrentColor(QRgb rgb)
-{
- cs->setRgb(rgb);
- _q_newColorTypedIn(rgb);
-}
-
-// hack; doesn't keep curCol in sync, so use with care
-void QColorDialogPrivate::setCurrentQColor(const QColor &color)
-{
- Q_Q(QColorDialog);
- if (cs->curQColor != color) {
- cs->curQColor = color;
- emit q->currentColorChanged(color);
- }
-}
-
-bool QColorDialogPrivate::selectColor(const QColor &col)
-{
- QRgb color = col.rgb();
- int i = 0, j = 0;
- // Check standard colors
- if (standard) {
- for (i = 0; i < 6; i++) {
- for (j = 0; j < 8; j++) {
- if (color == stdrgb[i + j*6]) {
- _q_newStandard(i, j);
- standard->setCurrent(i, j);
- standard->setSelected(i, j);
- standard->setFocus();
- return true;
- }
- }
- }
- }
- // Check custom colors
- if (custom) {
- for (i = 0; i < 2; i++) {
- for (j = 0; j < 8; j++) {
- if (color == cusrgb[i + j*2]) {
- _q_newCustom(i, j);
- custom->setCurrent(i, j);
- custom->setSelected(i, j);
- custom->setFocus();
- return true;
- }
- }
- }
- }
- return false;
-}
-
-//sets all widgets except cs to display rgb
-void QColorDialogPrivate::_q_newColorTypedIn(QRgb rgb)
-{
- int h, s, v;
- rgb2hsv(rgb, h, s, v);
- cp->setCol(h, s);
- lp->setCol(h, s, v);
-}
-
-void QColorDialogPrivate::_q_newCustom(int r, int c)
-{
- int i = r+2*c;
- setCurrentColor(cusrgb[i]);
- nextCust = i;
- if (standard)
- standard->setSelected(-1,-1);
-}
-
-void QColorDialogPrivate::_q_newStandard(int r, int c)
-{
- setCurrentColor(stdrgb[r+c*6]);
- if (custom)
- custom->setSelected(-1,-1);
-}
-
-void QColorDialogPrivate::init(const QColor &initial)
-{
- Q_Q(QColorDialog);
-
- q->setSizeGripEnabled(false);
- q->setWindowTitle(QColorDialog::tr("Select Color"));
-
- nativeDialogInUse = false;
-
- nextCust = 0;
- QVBoxLayout *mainLay = new QVBoxLayout(q);
- // there's nothing in this dialog that benefits from sizing up
- mainLay->setSizeConstraint(QLayout::SetFixedSize);
-
- QHBoxLayout *topLay = new QHBoxLayout();
- mainLay->addLayout(topLay);
-
- leftLay = 0;
-
-#if defined(Q_WS_WINCE) || defined(QT_SMALL_COLORDIALOG)
- smallDisplay = true;
- const int lumSpace = 20;
-#else
- // small displays (e.g. PDAs) cannot fit the full color dialog,
- // so just use the color picker.
- smallDisplay = (QApplication::desktop()->width() < 480 || QApplication::desktop()->height() < 350);
- const int lumSpace = topLay->spacing() / 2;
-#endif
-
- if (!smallDisplay) {
- leftLay = new QVBoxLayout;
- topLay->addLayout(leftLay);
- }
-
- initRGB();
-
-#ifndef QT_NO_SETTINGS
- if (!customSet) {
- QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
- for (int i = 0; i < 2*8; ++i) {
- QVariant v = settings.value(QLatin1String("Qt/customColors/") + QString::number(i));
- if (v.isValid()) {
- QRgb rgb = v.toUInt();
- cusrgb[i] = rgb;
- }
- }
- }
-#endif
-
-#if defined(QT_SMALL_COLORDIALOG)
-# if defined(Q_WS_S60)
- const bool nonTouchUI = !S60->hasTouchscreen;
-# elif defined(Q_WS_MAEMO_5)
- const bool nonTouchUI = false;
-# endif
-#endif
-
- if (!smallDisplay) {
- standard = new QColorWell(q, 6, 8, stdrgb);
- lblBasicColors = new QLabel(q);
-#ifndef QT_NO_SHORTCUT
- lblBasicColors->setBuddy(standard);
-#endif
- q->connect(standard, SIGNAL(selected(int,int)), SLOT(_q_newStandard(int,int)));
- leftLay->addWidget(lblBasicColors);
- leftLay->addWidget(standard);
-
-#if !defined(Q_WS_WINCE)
- leftLay->addStretch();
-#endif
-
- custom = new QColorWell(q, 2, 8, cusrgb);
- custom->setAcceptDrops(true);
-
- q->connect(custom, SIGNAL(selected(int,int)), SLOT(_q_newCustom(int,int)));
- lblCustomColors = new QLabel(q);
-#ifndef QT_NO_SHORTCUT
- lblCustomColors->setBuddy(custom);
-#endif
- leftLay->addWidget(lblCustomColors);
- leftLay->addWidget(custom);
-
- addCusBt = new QPushButton(q);
- QObject::connect(addCusBt, SIGNAL(clicked()), q, SLOT(_q_addCustom()));
- leftLay->addWidget(addCusBt);
- } else {
- // better color picker size for small displays
-#if defined(QT_SMALL_COLORDIALOG)
- QSize screenSize = QApplication::desktop()->availableGeometry(QCursor::pos()).size();
- pWidth = pHeight = qMin(screenSize.width(), screenSize.height());
- pHeight -= 20;
- if(screenSize.height() > screenSize.width())
- pWidth -= 20;
-#else
- pWidth = 150;
- pHeight = 100;
-#endif
- custom = 0;
- standard = 0;
- }
-
- QVBoxLayout *rightLay = new QVBoxLayout;
- topLay->addLayout(rightLay);
-
- QHBoxLayout *pickLay = new QHBoxLayout;
- rightLay->addLayout(pickLay);
-
- QVBoxLayout *cLay = new QVBoxLayout;
- pickLay->addLayout(cLay);
- cp = new QColorPicker(q);
-
- cp->setFrameStyle(QFrame::Panel + QFrame::Sunken);
-
-#if defined(QT_SMALL_COLORDIALOG)
- if (!nonTouchUI) {
- pickLay->addWidget(cp);
- cLay->addSpacing(lumSpace);
- } else {
- cp->hide();
- }
-#else
- cLay->addSpacing(lumSpace);
- cLay->addWidget(cp);
-#endif
- cLay->addSpacing(lumSpace);
-
- lp = new QColorLuminancePicker(q);
-#if defined(QT_SMALL_COLORDIALOG)
- QSize screenSize = QApplication::desktop()->availableGeometry(QCursor::pos()).size();
- const int minDimension = qMin(screenSize.height(), screenSize.width());
- //set picker to be finger-usable
- int pickerWidth = !nonTouchUI ? minDimension/9 : minDimension/12;
- lp->setFixedWidth(pickerWidth);
- if (!nonTouchUI)
- pickLay->addWidget(lp);
- else
- lp->hide();
-#else
- lp->setFixedWidth(20);
- pickLay->addWidget(lp);
-#endif
-
- QObject::connect(cp, SIGNAL(newCol(int,int)), lp, SLOT(setCol(int,int)));
- QObject::connect(lp, SIGNAL(newHsv(int,int,int)), q, SLOT(_q_newHsv(int,int,int)));
-
- rightLay->addStretch();
-
- cs = new QColorShower(q);
- QObject::connect(cs, SIGNAL(newCol(QRgb)), q, SLOT(_q_newColorTypedIn(QRgb)));
- QObject::connect(cs, SIGNAL(currentColorChanged(QColor)),
- q, SIGNAL(currentColorChanged(QColor)));
-#if defined(QT_SMALL_COLORDIALOG)
- if (!nonTouchUI)
- pWidth -= cp->size().width();
- topLay->addWidget(cs);
-#else
- rightLay->addWidget(cs);
-#endif
-
- buttons = new QDialogButtonBox(q);
- mainLay->addWidget(buttons);
-
- ok = buttons->addButton(QDialogButtonBox::Ok);
- QObject::connect(ok, SIGNAL(clicked()), q, SLOT(accept()));
- ok->setDefault(true);
- cancel = buttons->addButton(QDialogButtonBox::Cancel);
- QObject::connect(cancel, SIGNAL(clicked()), q, SLOT(reject()));
-
- retranslateStrings();
-
-#ifdef Q_WS_MAC
- delegate = 0;
-#endif
-
- q->setCurrentColor(initial);
-}
-
-void QColorDialogPrivate::_q_addCustom()
-{
- cusrgb[nextCust] = cs->currentColor();
- if (custom)
- custom->update();
- nextCust = (nextCust+1) % 16;
-}
-
-void QColorDialogPrivate::retranslateStrings()
-{
- if (!smallDisplay) {
- lblBasicColors->setText(QColorDialog::tr("&Basic colors"));
- lblCustomColors->setText(QColorDialog::tr("&Custom colors"));
- addCusBt->setText(QColorDialog::tr("&Add to Custom Colors"));
- }
-
- cs->retranslateStrings();
-}
-
-static const Qt::WindowFlags DefaultWindowFlags =
- Qt::Dialog | Qt::WindowTitleHint | Qt::MSWindowsFixedSizeDialogHint
- | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint;
-
-/*!
- \class QColorDialog
- \brief The QColorDialog class provides a dialog widget for specifying colors.
-
- \ingroup standard-dialogs
-
- The color dialog's function is to allow users to choose colors.
- For example, you might use this in a drawing program to allow the
- user to set the brush color.
-
- The static functions provide modal color dialogs.
- \omit
- 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. 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
- during the execution of the program. Use setCustomColor() to set
- the custom colors, and use customColor() to get them.
-
- Additional widgets that allow users to pick colors are available
- as \l{Qt Solutions}.
-
- The \l{dialogs/standarddialogs}{Standard Dialogs} example shows
- how to use QColorDialog as well as other built-in Qt dialogs.
-
- \image plastique-colordialog.png A color dialog in the Plastique widget style.
-
- \sa QColor, QFileDialog, QPrintDialog, QFontDialog, {Standard Dialogs Example}
-*/
-
-/*!
- \since 4.5
-
- Constructs a color dialog with the given \a parent.
-*/
-QColorDialog::QColorDialog(QWidget *parent)
- : QDialog(*new QColorDialogPrivate, parent, DefaultWindowFlags)
-{
- Q_D(QColorDialog);
- d->init(Qt::white);
-}
-
-/*!
- \since 4.5
-
- Constructs a color dialog with the given \a parent and specified
- \a initial color.
-*/
-QColorDialog::QColorDialog(const QColor &initial, QWidget *parent)
- : QDialog(*new QColorDialogPrivate, parent, DefaultWindowFlags)
-{
- Q_D(QColorDialog);
- d->init(initial);
-}
-
-/*!
- \property QColorDialog::currentColor
- \brief the currently selected color in the dialog
-*/
-
-void QColorDialog::setCurrentColor(const QColor &color)
-{
- Q_D(QColorDialog);
- d->setCurrentColor(color.rgb());
- d->selectColor(color);
- d->setCurrentAlpha(color.alpha());
-
-#ifdef Q_WS_MAC
- d->setCurrentQColor(color);
- d->setCocoaPanelColor(color);
-#endif
- if (d->nativeDialogInUse)
- qt_guiPlatformPlugin()->colorDialogSetCurrentColor(this, color);
-}
-
-QColor QColorDialog::currentColor() const
-{
- Q_D(const QColorDialog);
- return d->currentQColor();
-}
-
-
-/*!
- Returns the color that the user selected by clicking the \gui{OK}
- or equivalent button.
-
- \note This color is not always the same as the color held by the
- \l currentColor property since the user can choose different colors
- before finally selecting the one to use.
-*/
-QColor QColorDialog::selectedColor() const
-{
- Q_D(const QColorDialog);
- return d->selectedQColor;
-}
-
-/*!
- Sets the given \a option to be enabled if \a on is true;
- otherwise, clears the given \a option.
-
- \sa options, testOption()
-*/
-void QColorDialog::setOption(ColorDialogOption option, bool on)
-{
- Q_D(QColorDialog);
- if (!(d->opts & option) != !on)
- setOptions(d->opts ^ option);
-}
-
-/*!
- \since 4.5
-
- Returns true if the given \a option is enabled; otherwise, returns
- false.
-
- \sa options, setOption()
-*/
-bool QColorDialog::testOption(ColorDialogOption option) const
-{
- Q_D(const QColorDialog);
- return (d->opts & option) != 0;
-}
-
-/*!
- \property QColorDialog::options
- \brief the various options that affect the look and feel of the dialog
-
- By default, all options are disabled.
-
- Options should be set before showing the dialog. Setting them while the
- dialog is visible is not guaranteed to have an immediate effect on the
- dialog (depending on the option and on the platform).
-
- \sa setOption(), testOption()
-*/
-void QColorDialog::setOptions(ColorDialogOptions options)
-{
- Q_D(QColorDialog);
-
- ColorDialogOptions changed = (options ^ d->opts);
- if (!changed)
- return;
-
- d->opts = options;
- d->buttons->setVisible(!(options & NoButtons));
- d->showAlpha(options & ShowAlphaChannel);
-}
-
-QColorDialog::ColorDialogOptions QColorDialog::options() const
-{
- Q_D(const QColorDialog);
- return d->opts;
-}
-
-/*!
- \enum QColorDialog::ColorDialogOption
-
- \since 4.5
-
- This enum specifies various options that affect the look and feel
- of a color dialog.
-
- \value ShowAlphaChannel Allow the user to select the alpha component of a color.
- \value NoButtons Don't display \gui{OK} and \gui{Cancel} buttons. (Useful for "live dialogs".)
- \value DontUseNativeDialog Use Qt's standard color dialog on the Mac instead of Apple's
- native color panel.
-
- \sa options, setOption(), testOption(), windowModality()
-*/
-
-/*!
- \fn void QColorDialog::currentColorChanged(const QColor &color)
-
- This signal is emitted whenever the current color changes in the dialog.
- The current color is specified by \a color.
-
- \sa color, colorSelected()
-*/
-
-#ifdef Q_WS_MAC
-// can only have one Cocoa color panel active
-bool QColorDialogPrivate::sharedColorPanelAvailable = true;
-#endif
-
-/*!
- \fn void QColorDialog::colorSelected(const QColor &color);
-
- This signal is emitted just after the user has clicked \gui{OK} to
- select a color to use. The chosen color is specified by \a color.
-
- \sa color, currentColorChanged()
-*/
-
-/*!
- Changes the visibility of the dialog. If \a visible is true, the dialog
- is shown; otherwise, it is hidden.
-*/
-void QColorDialog::setVisible(bool visible)
-{
- Q_D(QColorDialog);
-
- if (visible){
- if (testAttribute(Qt::WA_WState_ExplicitShowHide) && !testAttribute(Qt::WA_WState_Hidden))
- return;
- } else if (testAttribute(Qt::WA_WState_ExplicitShowHide) && testAttribute(Qt::WA_WState_Hidden))
- return;
-
- if (visible)
- d->selectedQColor = QColor();
-
-#if defined(Q_WS_MAC)
- if (visible) {
- if (d->delegate || (QColorDialogPrivate::sharedColorPanelAvailable &&
- !(testAttribute(Qt::WA_DontShowOnScreen) || (d->opts & DontUseNativeDialog)))){
- d->openCocoaColorPanel(currentColor(), parentWidget(), windowTitle(), options());
- QColorDialogPrivate::sharedColorPanelAvailable = false;
- setAttribute(Qt::WA_DontShowOnScreen);
- }
- setWindowFlags(windowModality() == Qt::WindowModal ? Qt::Sheet : DefaultWindowFlags);
- } else {
- if (d->delegate) {
- d->closeCocoaColorPanel();
- setAttribute(Qt::WA_DontShowOnScreen, false);
- }
- }
-#else
-
- if (!(d->opts & DontUseNativeDialog) && qt_guiPlatformPlugin()->colorDialogSetVisible(this, visible)) {
- d->nativeDialogInUse = true;
- // Set WA_DontShowOnScreen so that QDialog::setVisible(visible) below
- // updates the state correctly, but skips showing the non-native version:
- setAttribute(Qt::WA_DontShowOnScreen);
- } else {
- d->nativeDialogInUse = false;
- setAttribute(Qt::WA_DontShowOnScreen, false);
- }
-#endif
-
- QDialog::setVisible(visible);
-}
-
-/*!
- \overload
- \since 4.5
-
- Opens the dialog and connects its colorSelected() signal to the slot specified
- by \a receiver and \a member.
-
- The signal will be disconnected from the slot when the dialog is closed.
-*/
-void QColorDialog::open(QObject *receiver, const char *member)
-{
- Q_D(QColorDialog);
- connect(this, SIGNAL(colorSelected(QColor)), receiver, member);
- d->receiverToDisconnectOnClose = receiver;
- d->memberToDisconnectOnClose = member;
- QDialog::open();
-}
-
-/*!
- \fn QColorDialog::open()
-
- \since 4.5
- Shows the dialog as a \l{QDialog#Modal Dialogs}{window modal dialog},
- returning immediately.
-
- \sa QDialog::open()
-*/
-
-/*
- For Symbian color dialogs
-*/
-#ifdef Q_WS_S60
-extern QColor qtSymbianGetColor(const QColor &initial);
-#endif
-/*!
- \since 4.5
-
- Pops up a modal color dialog with the given window \a title (or "Select Color" if none is
- specified), lets the user choose a color, and returns that color. The color is initially set
- to \a initial. The dialog is a child of \a parent. It returns an invalid (see
- QColor::isValid()) color if the user cancels the dialog.
-
- The \a options argument allows you to customize the dialog.
-
- On Symbian, this static function will use the native color dialog and not a QColorDialog.
- On Symbian the parameters \a title and \a parent has no relevance and the
- \a options parameter is only used to define if the native color dialog is
- used or not.
-*/
-QColor QColorDialog::getColor(const QColor &initial, QWidget *parent, const QString &title,
- ColorDialogOptions options)
-{
-#ifdef Q_WS_S60
- if (!(options & DontUseNativeDialog))
- return qtSymbianGetColor(initial);
-#endif
- QColorDialog dlg(parent);
- if (!title.isEmpty())
- dlg.setWindowTitle(title);
- dlg.setOptions(options);
- dlg.setCurrentColor(initial);
- dlg.exec();
- return dlg.selectedColor();
-}
-
-/*!
- Pops up a modal color dialog, lets the user choose a color, and
- returns that color. The color is initially set to \a initial. The
- dialog is a child of \a parent. It returns an invalid (see
- QColor::isValid()) color if the user cancels the dialog.
-
- On Symbian, this static function will use the native
- color dialog and not a QColorDialog.
-*/
-
-QColor QColorDialog::getColor(const QColor &initial, QWidget *parent)
-{
-#ifdef Q_WS_S60
- return qtSymbianGetColor(initial);
-#endif
- return getColor(initial, parent, QString(), ColorDialogOptions(0));
-}
-
-
-/*!
- \obsolete
-
- Pops up a modal color dialog to allow the user to choose a color
- and an alpha channel (transparency) value. The color+alpha is
- initially set to \a initial. The dialog is a child of \a parent.
-
- If \a ok is non-null, \e *\a ok is set to true if the user clicked
- \gui{OK}, and to false if the user clicked Cancel.
-
- If the user clicks Cancel, the \a initial value is returned.
-
- Use QColorDialog::getColor() instead, passing the
- QColorDialog::ShowAlphaChannel option.
-*/
-
-QRgb QColorDialog::getRgba(QRgb initial, bool *ok, QWidget *parent)
-{
- QColor color(getColor(QColor(initial), parent, QString(), ShowAlphaChannel));
- QRgb result = color.isValid() ? color.rgba() : initial;
- if (ok)
- *ok = color.isValid();
- return result;
-}
-
-/*!
- Destroys the color dialog.
-*/
-
-QColorDialog::~QColorDialog()
-{
- Q_D(QColorDialog);
-#if defined(Q_WS_MAC)
- if (d->delegate) {
- d->releaseCocoaColorPanelDelegate();
- QColorDialogPrivate::sharedColorPanelAvailable = true;
- }
-#endif
-
-#ifndef QT_NO_SETTINGS
- if (!customSet) {
- QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
- for (int i = 0; i < 2*8; ++i)
- settings.setValue(QLatin1String("Qt/customColors/") + QString::number(i), cusrgb[i]);
- }
-#endif
- if (d->nativeDialogInUse)
- qt_guiPlatformPlugin()->colorDialogDelete(this);
-
-}
-
-
-/*!
- \reimp
-*/
-void QColorDialog::changeEvent(QEvent *e)
-{
- Q_D(QColorDialog);
- if (e->type() == QEvent::LanguageChange)
- d->retranslateStrings();
- QDialog::changeEvent(e);
-}
-
-/*!
- Closes the dialog and sets its result code to \a result. If this dialog
- is shown with exec(), done() causes the local event loop to finish,
- and exec() to return \a result.
-
- \sa QDialog::done()
-*/
-void QColorDialog::done(int result)
-{
- Q_D(QColorDialog);
- QDialog::done(result);
- if (result == Accepted) {
- d->selectedQColor = d->currentQColor();
- emit colorSelected(d->selectedQColor);
- } else {
- d->selectedQColor = QColor();
- }
- if (d->receiverToDisconnectOnClose) {
- disconnect(this, SIGNAL(colorSelected(QColor)),
- d->receiverToDisconnectOnClose, d->memberToDisconnectOnClose);
- d->receiverToDisconnectOnClose = 0;
- }
- d->memberToDisconnectOnClose.clear();
-}
-
-QT_END_NAMESPACE
-
-#include "qcolordialog.moc"
-#include "moc_qcolordialog.cpp"
-
-#endif // QT_NO_COLORDIALOG
-
-/*!
- \fn QColor QColorDialog::getColor(const QColor &init, QWidget *parent, const char *name)
- \compat
-*/
-
-/*!
- \fn QRgb QColorDialog::getRgba(QRgb rgba, bool *ok, QWidget *parent, const char *name)
- \compat
-*/
diff --git a/src/gui/dialogs/qcolordialog.h b/src/gui/dialogs/qcolordialog.h
deleted file mode 100644
index 7110069add..0000000000
--- a/src/gui/dialogs/qcolordialog.h
+++ /dev/null
@@ -1,150 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QCOLORDIALOG_H
-#define QCOLORDIALOG_H
-
-#include <QtGui/qdialog.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_COLORDIALOG
-
-class QColorDialogPrivate;
-
-class Q_GUI_EXPORT QColorDialog : public QDialog
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QColorDialog)
- Q_ENUMS(ColorDialogOption)
- Q_PROPERTY(QColor currentColor READ currentColor WRITE setCurrentColor
- NOTIFY currentColorChanged)
- Q_PROPERTY(ColorDialogOptions options READ options WRITE setOptions)
-
-public:
- enum ColorDialogOption {
- ShowAlphaChannel = 0x00000001,
- NoButtons = 0x00000002,
- DontUseNativeDialog = 0x00000004
- };
-
- Q_DECLARE_FLAGS(ColorDialogOptions, ColorDialogOption)
-
- explicit QColorDialog(QWidget *parent = 0);
- explicit QColorDialog(const QColor &initial, QWidget *parent = 0);
- ~QColorDialog();
-
- void setCurrentColor(const QColor &color);
- QColor currentColor() const;
-
- QColor selectedColor() const;
-
- void setOption(ColorDialogOption option, bool on = true);
- bool testOption(ColorDialogOption option) const;
- void setOptions(ColorDialogOptions options);
- ColorDialogOptions options() const;
-
-#ifdef Q_NO_USING_KEYWORD
- void open() { QDialog::open(); }
-#else
- using QDialog::open;
-#endif
- void open(QObject *receiver, const char *member);
-
- void setVisible(bool visible);
-
- // ### Qt 5: merge overloads with title = QString()
- static QColor getColor(const QColor &initial, QWidget *parent, const QString &title,
- ColorDialogOptions options = 0);
- static QColor getColor(const QColor &initial = Qt::white, QWidget *parent = 0);
-
- // obsolete
- static QRgb getRgba(QRgb rgba = 0xffffffff, bool *ok = 0, QWidget *parent = 0);
-
- // ### Qt 5: use QColor in signatures
- static int customCount();
- static QRgb customColor(int index);
- static void setCustomColor(int index, QRgb color);
- static void setStandardColor(int index, QRgb color);
-
-#ifdef QT3_SUPPORT
- static QColor getColor(const QColor &init, QWidget *parent, const char *name)
- { Q_UNUSED(name); return getColor(init, parent); }
- static QRgb getRgba(QRgb rgba, bool *ok, QWidget *parent, const char *name)
- { Q_UNUSED(name); return getRgba(rgba, ok, parent); }
-#endif
-
-Q_SIGNALS:
- void currentColorChanged(const QColor &color);
- void colorSelected(const QColor &color);
-
-protected:
- void changeEvent(QEvent *event);
- void done(int result);
-
-private:
- Q_DISABLE_COPY(QColorDialog)
-
- Q_PRIVATE_SLOT(d_func(), void _q_addCustom())
- Q_PRIVATE_SLOT(d_func(), void _q_newHsv(int h, int s, int v))
- Q_PRIVATE_SLOT(d_func(), void _q_newColorTypedIn(QRgb rgb))
- Q_PRIVATE_SLOT(d_func(), void _q_newCustom(int, int))
- Q_PRIVATE_SLOT(d_func(), void _q_newStandard(int, int))
-#if defined(Q_WS_MAC)
- Q_PRIVATE_SLOT(d_func(), void _q_macRunNativeAppModalPanel())
-#endif
-
- friend class QColorShower;
-};
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QColorDialog::ColorDialogOptions)
-
-#endif // QT_NO_COLORDIALOG
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QCOLORDIALOG_H
diff --git a/src/gui/dialogs/qdialog.h b/src/gui/dialogs/qdialog.h
deleted file mode 100644
index adec044ada..0000000000
--- a/src/gui/dialogs/qdialog.h
+++ /dev/null
@@ -1,140 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDIALOG_H
-#define QDIALOG_H
-
-#include <QtGui/qwidget.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QPushButton;
-class QDialogPrivate;
-
-class Q_GUI_EXPORT QDialog : public QWidget
-{
- Q_OBJECT
- friend class QPushButton;
-
- Q_PROPERTY(bool sizeGripEnabled READ isSizeGripEnabled WRITE setSizeGripEnabled)
- Q_PROPERTY(bool modal READ isModal WRITE setModal)
-
-public:
- explicit QDialog(QWidget *parent = 0, Qt::WindowFlags f = 0);
-#ifdef QT3_SUPPORT
- QT3_SUPPORT_CONSTRUCTOR QDialog(QWidget *parent, const char *name, bool modal = false,
- Qt::WindowFlags f = 0);
-#endif
- ~QDialog();
-
- enum DialogCode { Rejected, Accepted };
-
- int result() const;
-
- void setVisible(bool visible);
-
- void setOrientation(Qt::Orientation orientation);
- Qt::Orientation orientation() const;
-
- void setExtension(QWidget* extension);
- QWidget* extension() const;
-
- QSize sizeHint() const;
- QSize minimumSizeHint() const;
-
- void setSizeGripEnabled(bool);
- bool isSizeGripEnabled() const;
-
- void setModal(bool modal);
- void setResult(int r);
-
-Q_SIGNALS:
- void finished(int result);
- void accepted();
- void rejected();
-
-public Q_SLOTS:
- void open();
- int exec();
- virtual void done(int);
- virtual void accept();
- virtual void reject();
-
- void showExtension(bool);
-
-protected:
- QDialog(QDialogPrivate &, QWidget *parent, Qt::WindowFlags f = 0);
-
-#if defined(Q_WS_WINCE) || defined(Q_OS_SYMBIAN)
- bool event(QEvent *e);
-#endif
- void keyPressEvent(QKeyEvent *);
- void closeEvent(QCloseEvent *);
- void showEvent(QShowEvent *);
- void resizeEvent(QResizeEvent *);
-#ifndef QT_NO_CONTEXTMENU
- void contextMenuEvent(QContextMenuEvent *);
-#endif
- bool eventFilter(QObject *, QEvent *);
- void adjustPosition(QWidget*);
-private:
- Q_DECLARE_PRIVATE(QDialog)
- Q_DISABLE_COPY(QDialog)
-
-#if defined(Q_OS_SYMBIAN)
- bool symbianAdjustedPosition();
-#endif
-
-
-#ifdef Q_WS_WINCE_WM
- Q_PRIVATE_SLOT(d_func(), void _q_doneAction())
-#endif
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QDIALOG_H
diff --git a/src/gui/dialogs/qdialog_p.h b/src/gui/dialogs/qdialog_p.h
deleted file mode 100644
index 49ae18a10b..0000000000
--- a/src/gui/dialogs/qdialog_p.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDIALOG_P_H
-#define QDIALOG_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "private/qwidget_p.h"
-#include "QtCore/qeventloop.h"
-#include "QtCore/qpointer.h"
-#include "QtGui/qdialog.h"
-#include "QtGui/qpushbutton.h"
-
-QT_BEGIN_NAMESPACE
-
-class QSizeGrip;
-
-class QDialogPrivate : public QWidgetPrivate
-{
- Q_DECLARE_PUBLIC(QDialog)
-public:
-
- QDialogPrivate()
- : mainDef(0), orientation(Qt::Horizontal),extension(0), doShowExtension(false),
-#ifndef QT_NO_SIZEGRIP
- resizer(0),
- sizeGripEnabled(false),
-#endif
- rescode(0), resetModalityTo(-1), wasModalitySet(true), eventLoop(0)
- {}
-
- QPointer<QPushButton> mainDef;
- Qt::Orientation orientation;
- QWidget *extension;
- bool doShowExtension;
- QSize size, min, max;
-#ifndef QT_NO_SIZEGRIP
- QSizeGrip *resizer;
- bool sizeGripEnabled;
-#endif
- QPoint lastRMBPress;
-
- void setDefault(QPushButton *);
- void setMainDefault(QPushButton *);
- void hideDefault();
- void resetModalitySetByOpen();
-
-#ifdef Q_WS_WINCE_WM
- void _q_doneAction();
-#endif
-
-#ifdef Q_WS_MAC
- virtual void mac_nativeDialogModalHelp() {}
-#endif
-
- int rescode;
- int resetModalityTo;
- bool wasModalitySet;
-
- QPointer<QEventLoop> eventLoop;
-};
-
-QT_END_NAMESPACE
-
-#endif // QDIALOG_P_H
diff --git a/src/gui/dialogs/qdialogsbinarycompat_win.cpp b/src/gui/dialogs/qdialogsbinarycompat_win.cpp
deleted file mode 100644
index 0a29422c2e..0000000000
--- a/src/gui/dialogs/qdialogsbinarycompat_win.cpp
+++ /dev/null
@@ -1,137 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qglobal.h>
-
-// ### Qt 5: eliminate this file
-
-/*
- This is evil. MSVC doesn't let us remove private symbols, nor change their
- visibility; yet there are some symbols we really needed to make public, e.g.,
- ~QColorDialog(), and then there were some totally needless symbols in our
- header files, e.g., setSelectedAlpha(). So we define a new version of
- QColorDialog & Co. with only the private symbols that we removed from the
- public header files. The friends are there only to prevent potential compiler
- warnings.
-
- It would have been nicer to export the missing symbols as mangled "C" symbols
- instead but unfortunately MSVC uses out-of-reach characters like @ and . in
- their mangled C++ symbols.
-*/
-
-#if QT_VERSION < 0x050000 && defined(Q_CC_MSVC)
-
-QT_BEGIN_NAMESPACE
-
-#include <QtGui/QColor>
-#include <QtGui/QFont>
-
-class QColorDialogPrivate;
-class QFontDialogPrivate;
-class QInputDialogPrivate;
-class QWidget;
-
-class Q_GUI_EXPORT QColorDialog
-{
-private:
- explicit QColorDialog(QWidget *, bool);
- ~QColorDialog();
-
- void setColor(const QColor &);
- QColor color() const;
- bool selectColor(const QColor &);
- void setSelectedAlpha(int);
- int selectedAlpha() const;
-
- friend class QColorDialogPrivate;
-};
-
-QColorDialog::QColorDialog(QWidget *, bool) {}
-QColorDialog::~QColorDialog() {}
-void QColorDialog::setColor(const QColor &) {}
-QColor QColorDialog::color() const { return QColor(); }
-bool QColorDialog::selectColor(const QColor &) { return false; }
-void QColorDialog::setSelectedAlpha(int) {}
-int QColorDialog::selectedAlpha() const { return 0; }
-
-class Q_GUI_EXPORT QFontDialog
-{
-private:
- explicit QFontDialog(QWidget *, bool, Qt::WindowFlags);
- ~QFontDialog();
-
- QFont font() const;
- void setFont(const QFont &);
- void updateFamilies();
- void updateStyles();
- void updateSizes();
-
- static QFont getFont(bool *, const QFont *, QWidget *);
-
- friend class QFontDialogPrivate;
-};
-
-QFontDialog::QFontDialog(QWidget *, bool, Qt::WindowFlags) {}
-QFontDialog::~QFontDialog() {}
-QFont QFontDialog::font() const { return QFont(); }
-void QFontDialog::setFont(const QFont &) { }
-void QFontDialog::updateFamilies() {}
-void QFontDialog::updateStyles() {}
-void QFontDialog::updateSizes() {}
-QFont QFontDialog::getFont(bool *, const QFont *, QWidget *) { return QFont(); }
-
-class Q_GUI_EXPORT QInputDialog
-{
-private:
- enum Type { LineEdit, SpinBox, DoubleSpinBox, ComboBox, EditableComboBox };
-
- QInputDialog(const QString &, QWidget *, Type, Qt::WindowFlags);
- QInputDialog(const QString &, const QString &, QWidget *, QWidget *, Qt::WindowFlags);
- ~QInputDialog();
-};
-
-QInputDialog::QInputDialog(const QString &, QWidget *, Type, Qt::WindowFlags) {}
-QInputDialog::QInputDialog(const QString &, const QString &, QWidget *, QWidget *, Qt::WindowFlags) {}
-QInputDialog::~QInputDialog() {}
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/gui/dialogs/qerrormessage.h b/src/gui/dialogs/qerrormessage.h
deleted file mode 100644
index 45492dba89..0000000000
--- a/src/gui/dialogs/qerrormessage.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QERRORMESSAGE_H
-#define QERRORMESSAGE_H
-
-#include <QtGui/qdialog.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_ERRORMESSAGE
-
-class QErrorMessagePrivate;
-
-class Q_GUI_EXPORT QErrorMessage: public QDialog
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QErrorMessage)
-public:
- explicit QErrorMessage(QWidget* parent = 0);
- ~QErrorMessage();
-
- static QErrorMessage * qtHandler();
-
-public Q_SLOTS:
- void showMessage(const QString &message);
- void showMessage(const QString &message, const QString &type);
-#ifdef QT3_SUPPORT
- inline QT_MOC_COMPAT void message(const QString &text) { showMessage(text); }
-#endif
-
-protected:
- void done(int);
- void changeEvent(QEvent *e);
-
-private:
- Q_DISABLE_COPY(QErrorMessage)
-};
-
-#endif // QT_NO_ERRORMESSAGE
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QERRORMESSAGE_H
diff --git a/src/gui/dialogs/qfiledialog.cpp b/src/gui/dialogs/qfiledialog.cpp
deleted file mode 100644
index 5e8533e3bc..0000000000
--- a/src/gui/dialogs/qfiledialog.cpp
+++ /dev/null
@@ -1,3555 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qvariant.h>
-#include <private/qwidgetitemdata_p.h>
-#include "qfiledialog.h"
-
-#ifndef QT_NO_FILEDIALOG
-#include "qfiledialog_p.h"
-#include <qfontmetrics.h>
-#include <qaction.h>
-#include <qheaderview.h>
-#include <qshortcut.h>
-#include <qgridlayout.h>
-#include <qmenu.h>
-#include <qmessagebox.h>
-#include <qinputdialog.h>
-#include <stdlib.h>
-#include <qsettings.h>
-#include <qdebug.h>
-#include <qapplication.h>
-#include <qstylepainter.h>
-#if !defined(Q_WS_WINCE) && !defined(Q_OS_SYMBIAN)
-#include "ui_qfiledialog.h"
-#else
-#define Q_EMBEDDED_SMALLSCREEN
-#include "ui_qfiledialog_embedded.h"
-#if defined(Q_OS_WINCE)
-extern bool qt_priv_ptr_valid;
-#endif
-#if defined(Q_OS_UNIX)
-#include <pwd.h>
-#endif
-#endif
-
-QT_BEGIN_NAMESPACE
-
-Q_GLOBAL_STATIC(QString, lastVisitedDir)
-
-/*
- \internal
-
- Exported hooks that can be used to customize the static functions.
- */
-typedef QString (*_qt_filedialog_existing_directory_hook)(QWidget *parent, const QString &caption, const QString &dir, QFileDialog::Options options);
-Q_GUI_EXPORT _qt_filedialog_existing_directory_hook qt_filedialog_existing_directory_hook = 0;
-
-typedef QString (*_qt_filedialog_open_filename_hook)(QWidget * parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options);
-Q_GUI_EXPORT _qt_filedialog_open_filename_hook qt_filedialog_open_filename_hook = 0;
-
-typedef QStringList (*_qt_filedialog_open_filenames_hook)(QWidget * parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options);
-Q_GUI_EXPORT _qt_filedialog_open_filenames_hook qt_filedialog_open_filenames_hook = 0;
-
-typedef QString (*_qt_filedialog_save_filename_hook)(QWidget * parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options);
-Q_GUI_EXPORT _qt_filedialog_save_filename_hook qt_filedialog_save_filename_hook = 0;
-
-/*!
- \class QFileDialog
- \brief The QFileDialog class provides a dialog that allow users to select files or directories.
- \ingroup standard-dialogs
-
-
- The QFileDialog class enables a user to traverse the file system in
- order to select one or many files or a directory.
-
- The easiest way to create a QFileDialog is to use the static
- functions. On Windows, Mac OS X, KDE and GNOME, these static functions will
- call the native file dialog when possible.
-
- \snippet doc/src/snippets/code/src_gui_dialogs_qfiledialog.cpp 0
-
- In the above example, a modal QFileDialog is created using a static
- function. The dialog initially displays the contents of the "/home/jana"
- directory, and displays files matching the patterns given in the
- string "Image Files (*.png *.jpg *.bmp)". The parent of the file dialog
- is set to \e this, and the window title is set to "Open Image".
-
- If you want to use multiple filters, separate each one with
- \e two semicolons. For example:
-
- \snippet doc/src/snippets/code/src_gui_dialogs_qfiledialog.cpp 1
-
- You can create your own QFileDialog without using the static
- functions. By calling setFileMode(), you can specify what the user must
- select in the dialog:
-
- \snippet doc/src/snippets/code/src_gui_dialogs_qfiledialog.cpp 2
-
- In the above example, the mode of the file dialog is set to
- AnyFile, meaning that the user can select any file, or even specify a
- file that doesn't exist. This mode is useful for creating a
- "Save As" file dialog. Use ExistingFile if the user must select an
- existing file, or \l Directory if only a directory may be selected.
- See the \l QFileDialog::FileMode enum for the complete list of modes.
-
- The fileMode property contains the mode of operation for the dialog;
- this indicates what types of objects the user is expected to select.
- Use setNameFilter() to set the dialog's file filter. For example:
-
- \snippet doc/src/snippets/code/src_gui_dialogs_qfiledialog.cpp 3
-
- In the above example, the filter is set to \c{"Images (*.png *.xpm *.jpg)"},
- this means that only files with the extension \c png, \c xpm,
- or \c jpg will be shown in the QFileDialog. You can apply
- several filters by using setNameFilters(). Use selectNameFilter() to select
- one of the filters you've given as the file dialog's default filter.
-
- The file dialog has two view modes: \l{QFileDialog::}{List} and
- \l{QFileDialog::}{Detail}.
- \l{QFileDialog::}{List} presents the contents of the current directory
- as a list of file and directory names. \l{QFileDialog::}{Detail} also
- displays a list of file and directory names, but provides additional
- information alongside each name, such as the file size and modification
- date. Set the mode with setViewMode():
-
- \snippet doc/src/snippets/code/src_gui_dialogs_qfiledialog.cpp 4
-
- The last important function you will need to use when creating your
- own file dialog is selectedFiles().
-
- \snippet doc/src/snippets/code/src_gui_dialogs_qfiledialog.cpp 5
-
- In the above example, a modal file dialog is created and shown. If
- the user clicked OK, the file they selected is put in \c fileName.
-
- The dialog's working directory can be set with setDirectory().
- Each file in the current directory can be selected using
- the selectFile() function.
-
- The \l{dialogs/standarddialogs}{Standard Dialogs} example shows
- how to use QFileDialog as well as other built-in Qt dialogs.
-
- \sa QDir, QFileInfo, QFile, QPrintDialog, QColorDialog, QFontDialog, {Standard Dialogs Example},
- {Application Example}
-*/
-
-/*!
- \enum QFileDialog::AcceptMode
-
- \value AcceptOpen
- \value AcceptSave
-*/
-
-/*!
- \enum QFileDialog::ViewMode
-
- This enum describes the view mode of the file dialog; i.e. what
- information about each file will be displayed.
-
- \value Detail Displays an icon, a name, and details for each item in
- the directory.
- \value List Displays only an icon and a name for each item in the
- directory.
-
- \sa setViewMode()
-*/
-
-/*!
- \enum QFileDialog::FileMode
-
- This enum is used to indicate what the user may select in the file
- dialog; i.e. what the dialog will return if the user clicks OK.
-
- \value AnyFile The name of a file, whether it exists or not.
- \value ExistingFile The name of a single existing file.
- \value Directory The name of a directory. Both files and
- directories are displayed.
- \value ExistingFiles The names of zero or more existing files.
-
- This value is obsolete since Qt 4.5:
-
- \value DirectoryOnly Use \c Directory and setOption(ShowDirsOnly, true) instead.
-
- \sa setFileMode()
-*/
-
-/*!
- \enum QFileDialog::Option
-
- \value ShowDirsOnly Only show directories in the file dialog. By
- default both files and directories are shown. (Valid only in the
- \l Directory file mode.)
-
- \value DontResolveSymlinks Don't resolve symlinks in the file
- dialog. By default symlinks are resolved.
-
- \value DontConfirmOverwrite Don't ask for confirmation if an
- existing file is selected. By default confirmation is requested.
-
- \value DontUseNativeDialog Don't use the native file dialog. By
- default, the native file dialog is used unless you use a subclass
- of QFileDialog that contains the Q_OBJECT macro.
-
- \value ReadOnly Indicates that the model is readonly.
-
- \value HideNameFilterDetails Indicates if the file name filter details are
- hidden or not.
-
- \value DontUseSheet In previous versions of Qt, the static
- functions would create a sheet by default if the static function
- was given a parent. This is no longer supported and does nothing in Qt 4.5, The
- static functions will always be an application modal dialog. If
- you want to use sheets, use QFileDialog::open() instead.
-
-*/
-
-/*!
- \enum QFileDialog::DialogLabel
-
- \value LookIn
- \value FileName
- \value FileType
- \value Accept
- \value Reject
-*/
-
-/*!
- \fn void QFileDialog::filesSelected(const QStringList &selected)
-
- When the selection changes and the dialog is accepted, this signal is
- emitted with the (possibly empty) list of \a selected files.
-
- \sa currentChanged(), QDialog::Accepted
-*/
-
-
-/*!
- \fn void QFileDialog::fileSelected(const QString &file)
-
- When the selection changes and the dialog is accepted, this signal is
- emitted with the (possibly empty) selected \a file.
-
- \sa currentChanged(), QDialog::Accepted
-*/
-
-
-/*!
- \fn void QFileDialog::currentChanged(const QString &path)
-
- When the current file changes, this signal is emitted with the
- new file name as the \a path parameter.
-
- \sa filesSelected()
-*/
-
-/*!
- \fn void QFileDialog::directoryEntered(const QString &directory)
- \since 4.3
-
- This signal is emitted when the user enters a \a directory.
-*/
-
-/*!
- \fn void QFileDialog::filterSelected(const QString &filter)
- \since 4.3
-
- This signal is emitted when the user selects a \a filter.
-*/
-
-#if defined(Q_WS_WIN) || defined(Q_WS_MAC)
-bool Q_GUI_EXPORT qt_use_native_dialogs = true; // for the benefit of testing tools, until we have a proper API
-#endif
-
-QT_BEGIN_INCLUDE_NAMESPACE
-#ifdef Q_WS_WIN
-#include <qwindowsstyle.h>
-#endif
-#include <qshortcut.h>
-#ifdef Q_WS_MAC
-#include <qmacstyle_mac.h>
-#endif
-QT_END_INCLUDE_NAMESPACE
-
-/*!
- \fn QFileDialog::QFileDialog(QWidget *parent, Qt::WindowFlags flags)
-
- Constructs a file dialog with the given \a parent and widget \a flags.
-*/
-QFileDialog::QFileDialog(QWidget *parent, Qt::WindowFlags f)
- : QDialog(*new QFileDialogPrivate, parent, f)
-{
- Q_D(QFileDialog);
- d->init();
- d->lineEdit()->selectAll();
-}
-
-/*!
- Constructs a file dialog with the given \a parent and \a caption that
- initially displays the contents of the specified \a directory.
- The contents of the directory are filtered before being shown in the
- dialog, using a semicolon-separated list of filters specified by
- \a filter.
-*/
-QFileDialog::QFileDialog(QWidget *parent,
- const QString &caption,
- const QString &directory,
- const QString &filter)
- : QDialog(*new QFileDialogPrivate, parent, 0)
-{
- Q_D(QFileDialog);
- d->init(directory, filter, caption);
- d->lineEdit()->selectAll();
-}
-
-/*!
- \internal
-*/
-QFileDialog::QFileDialog(const QFileDialogArgs &args)
- : QDialog(*new QFileDialogPrivate, args.parent, 0)
-{
- Q_D(QFileDialog);
- d->init(args.directory, args.filter, args.caption);
- setFileMode(args.mode);
- setOptions(args.options);
- selectFile(args.selection);
- d->lineEdit()->selectAll();
-}
-
-/*!
- Destroys the file dialog.
-*/
-QFileDialog::~QFileDialog()
-{
- Q_D(QFileDialog);
-#ifndef QT_NO_SETTINGS
- QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
- settings.beginGroup(QLatin1String("Qt"));
- settings.setValue(QLatin1String("filedialog"), saveState());
-#endif
- d->deleteNativeDialog_sys();
-}
-
-/*!
- \since 4.3
- Sets the \a urls that are located in the sidebar.
-
- For instance:
-
- \snippet doc/src/snippets/filedialogurls.cpp 0
-
- The file dialog will then look like this:
-
- \image filedialogurls.png
-
- \sa sidebarUrls()
-*/
-void QFileDialog::setSidebarUrls(const QList<QUrl> &urls)
-{
- Q_D(QFileDialog);
- d->qFileDialogUi->sidebar->setUrls(urls);
-}
-
-/*!
- \since 4.3
- Returns a list of urls that are currently in the sidebar
-*/
-QList<QUrl> QFileDialog::sidebarUrls() const
-{
- Q_D(const QFileDialog);
- return d->qFileDialogUi->sidebar->urls();
-}
-
-static const qint32 QFileDialogMagic = 0xbe;
-
-const char *qt_file_dialog_filter_reg_exp =
-"^(.*)\\(([a-zA-Z0-9_.*? +;#\\-\\[\\]@\\{\\}/!<>\\$%&=^~:\\|]*)\\)$";
-
-/*!
- \since 4.3
- Saves the state of the dialog's layout, history and current directory.
-
- Typically this is used in conjunction with QSettings to remember the size
- for a future session. A version number is stored as part of the data.
-*/
-QByteArray QFileDialog::saveState() const
-{
- Q_D(const QFileDialog);
- int version = 3;
- QByteArray data;
- QDataStream stream(&data, QIODevice::WriteOnly);
-
- stream << qint32(QFileDialogMagic);
- stream << qint32(version);
- stream << d->qFileDialogUi->splitter->saveState();
- stream << d->qFileDialogUi->sidebar->urls();
- stream << history();
- stream << *lastVisitedDir();
- stream << d->qFileDialogUi->treeView->header()->saveState();
- stream << qint32(viewMode());
- return data;
-}
-
-/*!
- \since 4.3
- Restores the dialogs's layout, history and current directory to the \a state specified.
-
- Typically this is used in conjunction with QSettings to restore the size
- from a past session.
-
- Returns false if there are errors
-*/
-bool QFileDialog::restoreState(const QByteArray &state)
-{
- Q_D(QFileDialog);
- int version = 3;
- QByteArray sd = state;
- QDataStream stream(&sd, QIODevice::ReadOnly);
- if (stream.atEnd())
- return false;
- QByteArray splitterState;
- QByteArray headerData;
- QList<QUrl> bookmarks;
- QStringList history;
- QString currentDirectory;
- qint32 marker;
- qint32 v;
- qint32 viewMode;
- stream >> marker;
- stream >> v;
- if (marker != QFileDialogMagic || v != version)
- return false;
-
- stream >> splitterState
- >> bookmarks
- >> history
- >> currentDirectory
- >> headerData
- >> viewMode;
-
- if (!d->qFileDialogUi->splitter->restoreState(splitterState))
- return false;
- QList<int> list = d->qFileDialogUi->splitter->sizes();
- if (list.count() >= 2 && list.at(0) == 0 && list.at(1) == 0) {
- for (int i = 0; i < list.count(); ++i)
- list[i] = d->qFileDialogUi->splitter->widget(i)->sizeHint().width();
- d->qFileDialogUi->splitter->setSizes(list);
- }
-
- d->qFileDialogUi->sidebar->setUrls(bookmarks);
- while (history.count() > 5)
- history.pop_front();
- setHistory(history);
- setDirectory(lastVisitedDir()->isEmpty() ? currentDirectory : *lastVisitedDir());
- if (!d->qFileDialogUi->treeView->header()->restoreState(headerData))
- return false;
-
- setViewMode(ViewMode(viewMode));
- return true;
-}
-
-/*!
- \reimp
-*/
-void QFileDialog::changeEvent(QEvent *e)
-{
- Q_D(QFileDialog);
- if (e->type() == QEvent::LanguageChange) {
- d->retranslateWindowTitle();
- d->retranslateStrings();
- }
- QDialog::changeEvent(e);
-}
-
-QFileDialogPrivate::QFileDialogPrivate()
- :
-#ifndef QT_NO_PROXYMODEL
- proxyModel(0),
-#endif
- model(0),
- fileMode(QFileDialog::AnyFile),
- acceptMode(QFileDialog::AcceptOpen),
- currentHistoryLocation(-1),
- renameAction(0),
- deleteAction(0),
- showHiddenAction(0),
- useDefaultCaption(true),
- defaultFileTypes(true),
- fileNameLabelExplicitlySat(false),
- nativeDialogInUse(false),
-#ifdef Q_WS_MAC
- mDelegate(0),
-#ifndef QT_MAC_USE_COCOA
- mDialog(0),
- mDialogStarted(false),
- mDialogClosed(true),
-#endif
-#endif
- qFileDialogUi(0)
-{
-}
-
-QFileDialogPrivate::~QFileDialogPrivate()
-{
-}
-
-void QFileDialogPrivate::retranslateWindowTitle()
-{
- Q_Q(QFileDialog);
- if (!useDefaultCaption || setWindowTitle != q->windowTitle())
- return;
- if (acceptMode == QFileDialog::AcceptOpen) {
- if (fileMode == QFileDialog::DirectoryOnly || fileMode == QFileDialog::Directory)
- q->setWindowTitle(QFileDialog::tr("Find Directory"));
- else
- q->setWindowTitle(QFileDialog::tr("Open"));
- } else
- q->setWindowTitle(QFileDialog::tr("Save As"));
-
- setWindowTitle = q->windowTitle();
-}
-
-void QFileDialogPrivate::setLastVisitedDirectory(const QString &dir)
-{
- *lastVisitedDir() = dir;
-}
-
-void QFileDialogPrivate::retranslateStrings()
-{
- Q_Q(QFileDialog);
- /* WIDGETS */
- if (defaultFileTypes)
- q->setNameFilter(QFileDialog::tr("All Files (*)"));
-
- QList<QAction*> actions = qFileDialogUi->treeView->header()->actions();
- QAbstractItemModel *abstractModel = model;
-#ifndef QT_NO_PROXYMODEL
- if (proxyModel)
- abstractModel = proxyModel;
-#endif
- int total = qMin(abstractModel->columnCount(QModelIndex()), actions.count() + 1);
- for (int i = 1; i < total; ++i) {
- actions.at(i - 1)->setText(QFileDialog::tr("Show ") + abstractModel->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString());
- }
-
- /* MENU ACTIONS */
- renameAction->setText(QFileDialog::tr("&Rename"));
- deleteAction->setText(QFileDialog::tr("&Delete"));
- showHiddenAction->setText(QFileDialog::tr("Show &hidden files"));
- newFolderAction->setText(QFileDialog::tr("&New Folder"));
- qFileDialogUi->retranslateUi(q);
-
- if (!fileNameLabelExplicitlySat){
- if (fileMode == QFileDialog::DirectoryOnly || fileMode == QFileDialog::Directory) {
- q->setLabelText(QFileDialog::FileName, QFileDialog::tr("Directory:"));
- } else {
- q->setLabelText(QFileDialog::FileName, QFileDialog::tr("File &name:"));
- }
- fileNameLabelExplicitlySat = false;
- }
-}
-
-void QFileDialogPrivate::emitFilesSelected(const QStringList &files)
-{
- Q_Q(QFileDialog);
- emit q->filesSelected(files);
- if (files.count() == 1)
- emit q->fileSelected(files.first());
-}
-
-bool QFileDialogPrivate::canBeNativeDialog()
-{
- Q_Q(QFileDialog);
- if (nativeDialogInUse)
- return true;
- if (q->testAttribute(Qt::WA_DontShowOnScreen))
- return false;
- if (opts & QFileDialog::DontUseNativeDialog)
- return false;
-
- QLatin1String staticName(QFileDialog::staticMetaObject.className());
- QLatin1String dynamicName(q->metaObject()->className());
- return (staticName == dynamicName);
-}
-
-/*!
- \since 4.5
- Sets the given \a option to be enabled if \a on is true; otherwise,
- clears the given \a option.
-
- \sa options, testOption()
-*/
-void QFileDialog::setOption(Option option, bool on)
-{
- Q_D(QFileDialog);
- if (!(d->opts & option) != !on)
- setOptions(d->opts ^ option);
-}
-
-/*!
- \since 4.5
-
- Returns true if the given \a option is enabled; otherwise, returns
- false.
-
- \sa options, setOption()
-*/
-bool QFileDialog::testOption(Option option) const
-{
- Q_D(const QFileDialog);
- return (d->opts & option) != 0;
-}
-
-/*!
- \property QFileDialog::options
- \brief the various options that affect the look and feel of the dialog
- \since 4.5
-
- By default, all options are disabled.
-
- Options should be set before showing the dialog. Setting them while the
- dialog is visible is not guaranteed to have an immediate effect on the
- dialog (depending on the option and on the platform).
-
- \sa setOption(), testOption()
-*/
-void QFileDialog::setOptions(Options options)
-{
- Q_D(QFileDialog);
-
- Options changed = (options ^ d->opts);
- if (!changed)
- return;
-
- d->opts = options;
- if (changed & DontResolveSymlinks)
- d->model->setResolveSymlinks(!(options & DontResolveSymlinks));
- if (changed & ReadOnly) {
- bool ro = (options & ReadOnly);
- d->model->setReadOnly(ro);
- d->qFileDialogUi->newFolderButton->setEnabled(!ro);
- d->renameAction->setEnabled(!ro);
- d->deleteAction->setEnabled(!ro);
- }
- if (changed & HideNameFilterDetails)
- setNameFilters(d->nameFilters);
-
- if (changed & ShowDirsOnly)
- setFilter((options & ShowDirsOnly) ? filter() & ~QDir::Files : filter() | QDir::Files);
-}
-
-QFileDialog::Options QFileDialog::options() const
-{
- Q_D(const QFileDialog);
- return d->opts;
-}
-
-/*!
- \overload
-
- \since 4.5
-
- This function connects one of its signals to the slot specified by \a receiver
- and \a member. The specific signal depends is filesSelected() if fileMode is
- ExistingFiles and fileSelected() if fileMode is anything else.
-
- The signal will be disconnected from the slot when the dialog is closed.
-*/
-void QFileDialog::open(QObject *receiver, const char *member)
-{
- Q_D(QFileDialog);
- const char *signal = (fileMode() == ExistingFiles) ? SIGNAL(filesSelected(QStringList))
- : SIGNAL(fileSelected(QString));
- connect(this, signal, receiver, member);
- d->signalToDisconnectOnClose = signal;
- d->receiverToDisconnectOnClose = receiver;
- d->memberToDisconnectOnClose = member;
-
- QDialog::open();
-}
-
-
-/*!
- \reimp
-*/
-void QFileDialog::setVisible(bool visible)
-{
- Q_D(QFileDialog);
- if (visible){
- if (testAttribute(Qt::WA_WState_ExplicitShowHide) && !testAttribute(Qt::WA_WState_Hidden))
- return;
- } else if (testAttribute(Qt::WA_WState_ExplicitShowHide) && testAttribute(Qt::WA_WState_Hidden))
- return;
-
- if (d->canBeNativeDialog()){
- if (d->setVisible_sys(visible)){
- d->nativeDialogInUse = true;
- // Set WA_DontShowOnScreen so that QDialog::setVisible(visible) below
- // updates the state correctly, but skips showing the non-native version:
- setAttribute(Qt::WA_DontShowOnScreen);
-#ifndef QT_NO_FSCOMPLETER
- //So the completer don't try to complete and therefore to show a popup
- d->completer->setModel(0);
-#endif
- } else {
- d->nativeDialogInUse = false;
- setAttribute(Qt::WA_DontShowOnScreen, false);
-#ifndef QT_NO_FSCOMPLETER
- if (d->proxyModel != 0)
- d->completer->setModel(d->proxyModel);
- else
- d->completer->setModel(d->model);
-#endif
- }
- }
-
- if (!d->nativeDialogInUse)
- d->qFileDialogUi->fileNameEdit->setFocus();
-
- QDialog::setVisible(visible);
-}
-
-/*!
- \internal
- set the directory to url
-*/
-void QFileDialogPrivate::_q_goToUrl(const QUrl &url)
-{
- //The shortcut in the side bar may have a parent that is not fetched yet (e.g. an hidden file)
- //so we force the fetching
- QFileSystemModelPrivate::QFileSystemNode *node = model->d_func()->node(url.toLocalFile(), true);
- QModelIndex idx = model->d_func()->index(node);
- _q_enterDirectory(idx);
-}
-
-/*!
- \fn void QFileDialog::setDirectory(const QDir &directory)
-
- \overload
-*/
-
-/*!
- Sets the file dialog's current \a directory.
-*/
-void QFileDialog::setDirectory(const QString &directory)
-{
- Q_D(QFileDialog);
- QString newDirectory = directory;
- QFileInfo info(directory);
- //we remove .. and . from the given path if exist
- if (!directory.isEmpty())
- newDirectory = QDir::cleanPath(directory);
-
- if (!directory.isEmpty() && newDirectory.isEmpty())
- return;
-
- d->setLastVisitedDirectory(newDirectory);
-
- if (d->nativeDialogInUse){
- d->setDirectory_sys(newDirectory);
- return;
- }
- if (d->rootPath() == newDirectory)
- return;
- QModelIndex root = d->model->setRootPath(newDirectory);
- d->qFileDialogUi->newFolderButton->setEnabled(d->model->flags(root) & Qt::ItemIsDropEnabled);
- if (root != d->rootIndex()) {
-#ifndef QT_NO_FSCOMPLETER
- if (directory.endsWith(QLatin1Char('/')))
- d->completer->setCompletionPrefix(newDirectory);
- else
- d->completer->setCompletionPrefix(newDirectory + QLatin1Char('/'));
-#endif
- d->setRootIndex(root);
- }
- d->qFileDialogUi->listView->selectionModel()->clear();
-}
-
-/*!
- Returns the directory currently being displayed in the dialog.
-*/
-QDir QFileDialog::directory() const
-{
- Q_D(const QFileDialog);
- return QDir(d->nativeDialogInUse ? d->directory_sys() : d->rootPath());
-}
-
-/*!
- Selects the given \a filename in the file dialog.
-
- \sa selectedFiles()
-*/
-void QFileDialog::selectFile(const QString &filename)
-{
- Q_D(QFileDialog);
- if (filename.isEmpty())
- return;
-
- if (d->nativeDialogInUse){
- d->selectFile_sys(filename);
- return;
- }
-
- if (!QDir::isRelativePath(filename)) {
- QFileInfo info(filename);
- QString filenamePath = info.absoluteDir().path();
-
- if (d->model->rootPath() != filenamePath)
- setDirectory(filenamePath);
- }
-
- QModelIndex index = d->model->index(filename);
- QString file;
- if (!index.isValid()) {
- // save as dialog where we want to input a default value
- QString text = 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);
- }
- file = text;
- } else {
- file = index.data().toString();
- }
- d->qFileDialogUi->listView->selectionModel()->clear();
- if (!isVisible() || !d->lineEdit()->hasFocus())
- d->lineEdit()->setText(file);
-}
-
-#ifdef Q_OS_UNIX
-Q_AUTOTEST_EXPORT QString qt_tildeExpansion(const QString &path, bool *expanded = 0)
-{
- if (expanded != 0)
- *expanded = false;
- if (!path.startsWith(QLatin1Char('~')))
- return path;
- QString ret = path;
- QStringList tokens = ret.split(QDir::separator());
- if (tokens.first() == QLatin1String("~")) {
- ret.replace(0, 1, QDir::homePath());
- } else {
- QString userName = tokens.first();
- userName.remove(0, 1);
-#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_OPENBSD)
- passwd pw;
- passwd *tmpPw;
- char buf[200];
- const int bufSize = sizeof(buf);
- int err = getpwnam_r(userName.toLocal8Bit().constData(), &pw, buf, bufSize, &tmpPw);
- if (err || !tmpPw)
- return ret;
- const QString homePath = QString::fromLocal8Bit(pw.pw_dir);
-#else
- passwd *pw = getpwnam(userName.toLocal8Bit().constData());
- if (!pw)
- return ret;
- const QString homePath = QString::fromLocal8Bit(pw->pw_dir);
-#endif
- ret.replace(0, tokens.first().length(), homePath);
- }
- if (expanded != 0)
- *expanded = true;
- return ret;
-}
-#endif
-
-/**
- Returns the text in the line edit which can be one or more file names
- */
-QStringList QFileDialogPrivate::typedFiles() const
-{
- Q_Q(const QFileDialog);
- QStringList files;
- QString editText = lineEdit()->text();
- if (!editText.contains(QLatin1Char('"'))) {
-#ifdef Q_OS_UNIX
- const QString prefix = q->directory().absolutePath() + QDir::separator();
- if (QFile::exists(prefix + editText))
- files << editText;
- else
- files << qt_tildeExpansion(editText);
-#else
- files << editText;
-#endif
- } else {
- // " is used to separate files like so: "file1" "file2" "file3" ...
- // ### need escape character for filenames with quotes (")
- QStringList tokens = editText.split(QLatin1Char('\"'));
- for (int i=0; i<tokens.size(); ++i) {
- if ((i % 2) == 0)
- continue; // Every even token is a separator
-#ifdef Q_OS_UNIX
- const QString token = tokens.at(i);
- const QString prefix = q->directory().absolutePath() + QDir::separator();
- if (QFile::exists(prefix + token))
- files << token;
- else
- files << qt_tildeExpansion(token);
-#else
- files << toInternal(tokens.at(i));
-#endif
- }
- }
- return addDefaultSuffixToFiles(files);
-}
-
-QStringList QFileDialogPrivate::addDefaultSuffixToFiles(const QStringList filesToFix) const
-{
- QStringList files;
- for (int i=0; i<filesToFix.size(); ++i) {
- QString name = toInternal(filesToFix.at(i));
- QFileInfo info(name);
- // if the filename has no suffix, add the default suffix
- if (!defaultSuffix.isEmpty() && !info.isDir() && name.lastIndexOf(QLatin1Char('.')) == -1)
- name += QLatin1Char('.') + defaultSuffix;
- if (info.isAbsolute()) {
- files.append(name);
- } else {
- // at this point the path should only have Qt path separators.
- // This check is needed since we might be at the root directory
- // and on Windows it already ends with slash.
- QString path = rootPath();
- if (!path.endsWith(QLatin1Char('/')))
- path += QLatin1Char('/');
- path += name;
- files.append(path);
- }
- }
- return files;
-}
-
-
-/*!
- Returns a list of strings containing the absolute paths of the
- selected files in the dialog. If no files are selected, or
- the mode is not ExistingFiles or ExistingFile, selectedFiles() contains the current path in the viewport.
-
- \sa selectedNameFilter(), selectFile()
-*/
-QStringList QFileDialog::selectedFiles() const
-{
- Q_D(const QFileDialog);
- if (d->nativeDialogInUse)
- return d->addDefaultSuffixToFiles(d->selectedFiles_sys());
-
- QModelIndexList indexes = d->qFileDialogUi->listView->selectionModel()->selectedRows();
- QStringList files;
- for (int i = 0; i < indexes.count(); ++i)
- files.append(indexes.at(i).data(QFileSystemModel::FilePathRole).toString());
-
- if (files.isEmpty() && !d->lineEdit()->text().isEmpty())
- files = d->typedFiles();
-
- if (files.isEmpty() && !(d->fileMode == ExistingFile || d->fileMode == ExistingFiles))
- files.append(d->rootIndex().data(QFileSystemModel::FilePathRole).toString());
- return files;
-}
-
-/*
- Makes a list of filters from ;;-separated text.
- Used by the mac and windows implementations
-*/
-QStringList qt_make_filter_list(const QString &filter)
-{
- QString f(filter);
-
- if (f.isEmpty())
- return QStringList();
-
- QString sep(QLatin1String(";;"));
- int i = f.indexOf(sep, 0);
- if (i == -1) {
- if (f.indexOf(QLatin1Char('\n'), 0) != -1) {
- sep = QLatin1Char('\n');
- i = f.indexOf(sep, 0);
- }
- }
-
- return f.split(sep);
-}
-
-/*!
- \since 4.4
-
- Sets the filter used in the file dialog to the given \a filter.
-
- If \a filter contains a pair of parentheses containing one or more
- of \bold{anything*something}, separated by spaces, then only the
- text contained in the parentheses is used as the filter. This means
- that these calls are all equivalent:
-
- \snippet doc/src/snippets/code/src_gui_dialogs_qfiledialog.cpp 6
-
- \sa setNameFilters()
-*/
-void QFileDialog::setNameFilter(const QString &filter)
-{
- setNameFilters(qt_make_filter_list(filter));
-}
-
-/*!
- \obsolete
-
- Use setNameFilter() instead.
-*/
-void QFileDialog::setFilter(const QString &filter)
-{
- setNameFilter(filter);
-}
-
-/*!
- \property QFileDialog::nameFilterDetailsVisible
- \obsolete
- \brief This property holds whether the filter details is shown or not.
- \since 4.4
-
- When this property is true (the default), the filter details are shown
- in the combo box. When the property is set to false, these are hidden.
-
- Use setOption(HideNameFilterDetails, !\e enabled) or
- !testOption(HideNameFilterDetails).
-*/
-void QFileDialog::setNameFilterDetailsVisible(bool enabled)
-{
- setOption(HideNameFilterDetails, !enabled);
-}
-
-bool QFileDialog::isNameFilterDetailsVisible() const
-{
- return !testOption(HideNameFilterDetails);
-}
-
-
-/*
- Strip the filters by removing the details, e.g. (*.*).
-*/
-QStringList qt_strip_filters(const QStringList &filters)
-{
- QStringList strippedFilters;
- QRegExp r(QString::fromLatin1(qt_file_dialog_filter_reg_exp));
- for (int i = 0; i < filters.count(); ++i) {
- QString filterName;
- int index = r.indexIn(filters[i]);
- if (index >= 0)
- filterName = r.cap(1);
- strippedFilters.append(filterName.simplified());
- }
- return strippedFilters;
-}
-
-
-/*!
- \since 4.4
-
- Sets the \a filters used in the file dialog.
-
- \snippet doc/src/snippets/code/src_gui_dialogs_qfiledialog.cpp 7
-*/
-void QFileDialog::setNameFilters(const QStringList &filters)
-{
- Q_D(QFileDialog);
- d->defaultFileTypes = (filters == QStringList(QFileDialog::tr("All Files (*)")));
- QStringList cleanedFilters;
- for (int i = 0; i < filters.count(); ++i) {
- cleanedFilters << filters[i].simplified();
- }
- d->nameFilters = cleanedFilters;
-
- if (d->nativeDialogInUse){
- d->setNameFilters_sys(cleanedFilters);
- return;
- }
-
- d->qFileDialogUi->fileTypeCombo->clear();
- if (cleanedFilters.isEmpty())
- return;
-
- if (testOption(HideNameFilterDetails))
- d->qFileDialogUi->fileTypeCombo->addItems(qt_strip_filters(cleanedFilters));
- else
- d->qFileDialogUi->fileTypeCombo->addItems(cleanedFilters);
-
- d->_q_useNameFilter(0);
-}
-
-/*!
- \obsolete
-
- Use setNameFilters() instead.
-*/
-void QFileDialog::setFilters(const QStringList &filters)
-{
- setNameFilters(filters);
-}
-
-/*!
- \since 4.4
-
- Returns the file type filters that are in operation on this file
- dialog.
-*/
-QStringList QFileDialog::nameFilters() const
-{
- return d_func()->nameFilters;
-}
-
-/*!
- \obsolete
-
- Use nameFilters() instead.
-*/
-
-QStringList QFileDialog::filters() const
-{
- return nameFilters();
-}
-
-/*!
- \since 4.4
-
- Sets the current file type \a filter. Multiple filters can be
- passed in \a filter by separating them with semicolons or spaces.
-
- \sa setNameFilter(), setNameFilters(), selectedNameFilter()
-*/
-void QFileDialog::selectNameFilter(const QString &filter)
-{
- Q_D(QFileDialog);
- if (d->nativeDialogInUse) {
- d->selectNameFilter_sys(filter);
- return;
- }
- int i;
- if (testOption(HideNameFilterDetails)) {
- i = d->qFileDialogUi->fileTypeCombo->findText(qt_strip_filters(qt_make_filter_list(filter)).first());
- } else {
- i = d->qFileDialogUi->fileTypeCombo->findText(filter);
- }
- if (i >= 0) {
- d->qFileDialogUi->fileTypeCombo->setCurrentIndex(i);
- d->_q_useNameFilter(d->qFileDialogUi->fileTypeCombo->currentIndex());
- }
-}
-
-/*!
- \obsolete
-
- Use selectNameFilter() instead.
-*/
-
-void QFileDialog::selectFilter(const QString &filter)
-{
- selectNameFilter(filter);
-}
-
-/*!
- \since 4.4
-
- Returns the filter that the user selected in the file dialog.
-
- \sa selectedFiles()
-*/
-QString QFileDialog::selectedNameFilter() const
-{
- Q_D(const QFileDialog);
- if (d->nativeDialogInUse)
- return d->selectedNameFilter_sys();
-
- return d->qFileDialogUi->fileTypeCombo->currentText();
-}
-
-/*!
- \obsolete
-
- Use selectedNameFilter() instead.
-*/
-QString QFileDialog::selectedFilter() const
-{
- return selectedNameFilter();
-}
-
-/*!
- \since 4.4
-
- Returns the filter that is used when displaying files.
-
- \sa setFilter()
-*/
-QDir::Filters QFileDialog::filter() const
-{
- Q_D(const QFileDialog);
- return d->model->filter();
-}
-
-/*!
- \since 4.4
-
- Sets the filter used by the model to \a filters. The filter is used
- to specify the kind of files that should be shown.
-
- \sa filter()
-*/
-
-void QFileDialog::setFilter(QDir::Filters filters)
-{
- Q_D(QFileDialog);
- d->model->setFilter(filters);
- if (d->nativeDialogInUse){
- d->setFilter_sys();
- return;
- }
-
- d->showHiddenAction->setChecked((filters & QDir::Hidden));
-}
-
-/*!
- \property QFileDialog::viewMode
- \brief the way files and directories are displayed in the dialog
-
- By default, the \c Detail mode is used to display information about
- files and directories.
-
- \sa ViewMode
-*/
-void QFileDialog::setViewMode(QFileDialog::ViewMode mode)
-{
- Q_D(QFileDialog);
- if (mode == Detail)
- d->_q_showDetailsView();
- else
- d->_q_showListView();
-}
-
-QFileDialog::ViewMode QFileDialog::viewMode() const
-{
- Q_D(const QFileDialog);
- return (d->qFileDialogUi->stackedWidget->currentWidget() == d->qFileDialogUi->listView->parent() ? QFileDialog::List : QFileDialog::Detail);
-}
-
-/*!
- \property QFileDialog::fileMode
- \brief the file mode of the dialog
-
- The file mode defines the number and type of items that the user is
- expected to select in the dialog.
-
- By default, this property is set to AnyFile.
-
- This function will set the labels for the FileName and
- \l{QFileDialog::}{Accept} \l{DialogLabel}s. It is possible to set
- custom text after the call to setFileMode().
-
- \sa FileMode
-*/
-void QFileDialog::setFileMode(QFileDialog::FileMode mode)
-{
- Q_D(QFileDialog);
- d->fileMode = mode;
- d->retranslateWindowTitle();
-
- // keep ShowDirsOnly option in sync with fileMode (BTW, DirectoryOnly is obsolete)
- setOption(ShowDirsOnly, mode == DirectoryOnly);
-
- // set selection mode and behavior
- QAbstractItemView::SelectionMode selectionMode;
- if (mode == QFileDialog::ExistingFiles)
- selectionMode = QAbstractItemView::ExtendedSelection;
- else
- selectionMode = QAbstractItemView::SingleSelection;
- d->qFileDialogUi->listView->setSelectionMode(selectionMode);
- d->qFileDialogUi->treeView->setSelectionMode(selectionMode);
- // set filter
- d->model->setFilter(d->filterForMode(filter()));
- // setup file type for directory
- QString buttonText = (d->acceptMode == AcceptOpen ? tr("&Open") : tr("&Save"));
- if (mode == DirectoryOnly || mode == Directory) {
- d->qFileDialogUi->fileTypeCombo->clear();
- d->qFileDialogUi->fileTypeCombo->addItem(tr("Directories"));
- d->qFileDialogUi->fileTypeCombo->setEnabled(false);
-
- if (!d->fileNameLabelExplicitlySat){
- setLabelText(FileName, tr("Directory:"));
- d->fileNameLabelExplicitlySat = false;
- }
- buttonText = tr("&Choose");
- } else {
- if (!d->fileNameLabelExplicitlySat){
- setLabelText(FileName, tr("File &name:"));
- d->fileNameLabelExplicitlySat = false;
- }
- }
- setLabelText(Accept, buttonText);
- if (d->nativeDialogInUse){
- d->setFilter_sys();
- return;
- }
-
- d->qFileDialogUi->fileTypeCombo->setEnabled(!testOption(ShowDirsOnly));
- d->_q_updateOkButton();
-}
-
-QFileDialog::FileMode QFileDialog::fileMode() const
-{
- Q_D(const QFileDialog);
- return d->fileMode;
-}
-
-/*!
- \property QFileDialog::acceptMode
- \brief the accept mode of the dialog
-
- The action mode defines whether the dialog is for opening or saving files.
-
- By default, this property is set to \l{AcceptOpen}.
-
- \sa AcceptMode
-*/
-void QFileDialog::setAcceptMode(QFileDialog::AcceptMode mode)
-{
- Q_D(QFileDialog);
- d->acceptMode = mode;
- bool directoryMode = (d->fileMode == Directory || d->fileMode == DirectoryOnly);
- QDialogButtonBox::StandardButton button = (mode == AcceptOpen ? QDialogButtonBox::Open : QDialogButtonBox::Save);
- d->qFileDialogUi->buttonBox->setStandardButtons(button | QDialogButtonBox::Cancel);
- d->qFileDialogUi->buttonBox->button(button)->setEnabled(false);
- d->_q_updateOkButton();
- if (mode == AcceptOpen && directoryMode)
- setLabelText(Accept, tr("&Choose"));
- else
- setLabelText(Accept, (mode == AcceptOpen ? tr("&Open") : tr("&Save")));
- if (mode == AcceptSave) {
- d->qFileDialogUi->lookInCombo->setEditable(false);
- }
- d->retranslateWindowTitle();
-#if defined(Q_WS_MAC)
- d->deleteNativeDialog_sys();
- setAttribute(Qt::WA_DontShowOnScreen, false);
-#endif
-}
-
-/*
- Returns the file system model index that is the root index in the
- views
-*/
-QModelIndex QFileDialogPrivate::rootIndex() const {
- return mapToSource(qFileDialogUi->listView->rootIndex());
-}
-
-QAbstractItemView *QFileDialogPrivate::currentView() const {
- if (!qFileDialogUi->stackedWidget)
- return 0;
- if (qFileDialogUi->stackedWidget->currentWidget() == qFileDialogUi->listView->parent())
- return qFileDialogUi->listView;
- return qFileDialogUi->treeView;
-}
-
-QLineEdit *QFileDialogPrivate::lineEdit() const {
- return (QLineEdit*)qFileDialogUi->fileNameEdit;
-}
-
-/*
- Sets the view root index to be the file system model index
-*/
-void QFileDialogPrivate::setRootIndex(const QModelIndex &index) const {
- Q_ASSERT(index.isValid() ? index.model() == model : true);
- QModelIndex idx = mapFromSource(index);
- qFileDialogUi->treeView->setRootIndex(idx);
- qFileDialogUi->listView->setRootIndex(idx);
-}
-/*
- Select a file system model index
- returns the index that was selected (or not depending upon sortfilterproxymodel)
-*/
-QModelIndex QFileDialogPrivate::select(const QModelIndex &index) const {
- Q_ASSERT(index.isValid() ? index.model() == model : true);
-
- QModelIndex idx = mapFromSource(index);
- if (idx.isValid() && !qFileDialogUi->listView->selectionModel()->isSelected(idx))
- qFileDialogUi->listView->selectionModel()->select(idx,
- QItemSelectionModel::Select | QItemSelectionModel::Rows);
- return idx;
-}
-
-QFileDialog::AcceptMode QFileDialog::acceptMode() const
-{
- Q_D(const QFileDialog);
- return d->acceptMode;
-}
-
-/*!
- \property QFileDialog::readOnly
- \obsolete
- \brief Whether the filedialog is read-only
-
- If this property is set to false, the file dialog will allow renaming,
- and deleting of files and directories and creating directories.
-
- Use setOption(ReadOnly, \e enabled) or testOption(ReadOnly) instead.
-*/
-void QFileDialog::setReadOnly(bool enabled)
-{
- setOption(ReadOnly, enabled);
-}
-
-bool QFileDialog::isReadOnly() const
-{
- return testOption(ReadOnly);
-}
-
-/*!
- \property QFileDialog::resolveSymlinks
- \obsolete
- \brief whether the filedialog should resolve shortcuts
-
- If this property is set to true, the file dialog will resolve
- shortcuts or symbolic links.
-
- Use setOption(DontResolveSymlinks, !\a enabled) or
- !testOption(DontResolveSymlinks).
-*/
-void QFileDialog::setResolveSymlinks(bool enabled)
-{
- setOption(DontResolveSymlinks, !enabled);
-}
-
-bool QFileDialog::resolveSymlinks() const
-{
- return !testOption(DontResolveSymlinks);
-}
-
-/*!
- \property QFileDialog::confirmOverwrite
- \obsolete
- \brief whether the filedialog should ask before accepting a selected file,
- when the accept mode is AcceptSave
-
- Use setOption(DontConfirmOverwrite, !\e enabled) or
- !testOption(DontConfirmOverwrite) instead.
-*/
-void QFileDialog::setConfirmOverwrite(bool enabled)
-{
- setOption(DontConfirmOverwrite, !enabled);
-}
-
-bool QFileDialog::confirmOverwrite() const
-{
- return !testOption(DontConfirmOverwrite);
-}
-
-/*!
- \property QFileDialog::defaultSuffix
- \brief suffix added to the filename if no other suffix was specified
-
- This property specifies a string that will be added to the
- filename if it has no suffix already. The suffix is typically
- used to indicate the file type (e.g. "txt" indicates a text
- file).
-*/
-void QFileDialog::setDefaultSuffix(const QString &suffix)
-{
- Q_D(QFileDialog);
- d->defaultSuffix = suffix;
-}
-
-QString QFileDialog::defaultSuffix() const
-{
- Q_D(const QFileDialog);
- return d->defaultSuffix;
-}
-
-/*!
- Sets the browsing history of the filedialog to contain the given
- \a paths.
-*/
-void QFileDialog::setHistory(const QStringList &paths)
-{
- Q_D(QFileDialog);
- d->qFileDialogUi->lookInCombo->setHistory(paths);
-}
-
-void QFileDialogComboBox::setHistory(const QStringList &paths)
-{
- m_history = paths;
- // Only populate the first item, showPopup will populate the rest if needed
- QList<QUrl> list;
- QModelIndex idx = d_ptr->model->index(d_ptr->rootPath());
- //On windows the popup display the "C:\", convert to nativeSeparators
- QUrl url = QUrl::fromLocalFile(QDir::toNativeSeparators(idx.data(QFileSystemModel::FilePathRole).toString()));
- if (url.isValid())
- list.append(url);
- urlModel->setUrls(list);
-}
-
-/*!
- Returns the browsing history of the filedialog as a list of paths.
-*/
-QStringList QFileDialog::history() const
-{
- Q_D(const QFileDialog);
- QStringList currentHistory = d->qFileDialogUi->lookInCombo->history();
- //On windows the popup display the "C:\", convert to nativeSeparators
- QString newHistory = QDir::toNativeSeparators(d->rootIndex().data(QFileSystemModel::FilePathRole).toString());
- if (!currentHistory.contains(newHistory))
- currentHistory << newHistory;
- return currentHistory;
-}
-
-/*!
- Sets the item delegate used to render items in the views in the
- file dialog to the given \a delegate.
-
- \warning You should not share the same instance of a delegate between views.
- Doing so can cause incorrect or unintuitive editing behavior since each
- view connected to a given delegate may receive the \l{QAbstractItemDelegate::}{closeEditor()}
- signal, and attempt to access, modify or close an editor that has already been closed.
-
- Note that the model used is QFileSystemModel. It has custom item data roles, which is
- described by the \l{QFileSystemModel::}{Roles} enum. You can use a QFileIconProvider if
- you only want custom icons.
-
- \sa itemDelegate(), setIconProvider(), QFileSystemModel
-*/
-void QFileDialog::setItemDelegate(QAbstractItemDelegate *delegate)
-{
- Q_D(QFileDialog);
- d->qFileDialogUi->listView->setItemDelegate(delegate);
- d->qFileDialogUi->treeView->setItemDelegate(delegate);
-}
-
-/*!
- Returns the item delegate used to render the items in the views in the filedialog.
-*/
-QAbstractItemDelegate *QFileDialog::itemDelegate() const
-{
- Q_D(const QFileDialog);
- return d->qFileDialogUi->listView->itemDelegate();
-}
-
-/*!
- Sets the icon provider used by the filedialog to the specified \a provider.
-*/
-void QFileDialog::setIconProvider(QFileIconProvider *provider)
-{
- Q_D(QFileDialog);
- d->model->setIconProvider(provider);
- //It forces the refresh of all entries in the side bar, then we can get new icons
- d->qFileDialogUi->sidebar->setUrls(d->qFileDialogUi->sidebar->urls());
-}
-
-/*!
- Returns the icon provider used by the filedialog.
-*/
-QFileIconProvider *QFileDialog::iconProvider() const
-{
- Q_D(const QFileDialog);
- return d->model->iconProvider();
-}
-
-/*!
- Sets the \a text shown in the filedialog in the specified \a label.
-*/
-void QFileDialog::setLabelText(DialogLabel label, const QString &text)
-{
- Q_D(QFileDialog);
- QPushButton *button;
- switch (label) {
- case LookIn:
- d->qFileDialogUi->lookInLabel->setText(text);
- break;
- case FileName:
- d->qFileDialogUi->fileNameLabel->setText(text);
- d->fileNameLabelExplicitlySat = true;
- break;
- case FileType:
- d->qFileDialogUi->fileTypeLabel->setText(text);
- break;
- case Accept:
- d->acceptLabel = text;
- if (acceptMode() == AcceptOpen)
- button = d->qFileDialogUi->buttonBox->button(QDialogButtonBox::Open);
- else
- button = d->qFileDialogUi->buttonBox->button(QDialogButtonBox::Save);
- if (button)
- button->setText(text);
- break;
- case Reject:
- button = d->qFileDialogUi->buttonBox->button(QDialogButtonBox::Cancel);
- if (button)
- button->setText(text);
- break;
- }
-}
-
-/*!
- Returns the text shown in the filedialog in the specified \a label.
-*/
-QString QFileDialog::labelText(DialogLabel label) const
-{
- QPushButton *button;
- Q_D(const QFileDialog);
- switch (label) {
- case LookIn:
- return d->qFileDialogUi->lookInLabel->text();
- case FileName:
- return d->qFileDialogUi->fileNameLabel->text();
- case FileType:
- return d->qFileDialogUi->fileTypeLabel->text();
- case Accept:
- if (acceptMode() == AcceptOpen)
- button = d->qFileDialogUi->buttonBox->button(QDialogButtonBox::Open);
- else
- button = d->qFileDialogUi->buttonBox->button(QDialogButtonBox::Save);
- if (button)
- return button->text();
- case Reject:
- button = d->qFileDialogUi->buttonBox->button(QDialogButtonBox::Cancel);
- if (button)
- return button->text();
- }
- return QString();
-}
-
-/*
- For the native file dialogs
-*/
-
-#if defined(Q_WS_WIN)
-extern QString qt_win_get_open_file_name(const QFileDialogArgs &args,
- QString *initialDirectory,
- QString *selectedFilter);
-
-extern QString qt_win_get_save_file_name(const QFileDialogArgs &args,
- QString *initialDirectory,
- QString *selectedFilter);
-
-extern QStringList qt_win_get_open_file_names(const QFileDialogArgs &args,
- QString *initialDirectory,
- QString *selectedFilter);
-
-extern QString qt_win_get_existing_directory(const QFileDialogArgs &args);
-#endif
-
-/*
- For Symbian file dialogs
-*/
-#if defined(Q_WS_S60)
-extern QString qtSymbianGetOpenFileName(const QString &caption,
- const QString &dir,
- const QString &filter);
-
-extern QStringList qtSymbianGetOpenFileNames(const QString &caption,
- const QString &dir,
- const QString &filter);
-
-extern QString qtSymbianGetSaveFileName(const QString &caption,
- const QString &dir);
-
-extern QString qtSymbianGetExistingDirectory(const QString &caption,
- const QString &dir);
-#endif
-
-/*!
- This is a convenience static function that returns an existing file
- selected by the user. If the user presses Cancel, it returns a null string.
-
- \snippet doc/src/snippets/code/src_gui_dialogs_qfiledialog.cpp 8
-
- The function creates a modal file dialog with the given \a parent widget.
- If \a parent is not 0, the dialog will be shown centered over the parent
- widget.
-
- The file dialog's working directory will be set to \a dir. If \a dir
- includes a file name, the file will be selected. Only files that match the
- given \a filter are shown. The filter selected is set to \a selectedFilter.
- The parameters \a dir, \a selectedFilter, and \a filter may be empty
- strings. If you want multiple filters, separate them with ';;', for
- example:
-
- \code
- "Images (*.png *.xpm *.jpg);;Text files (*.txt);;XML files (*.xml)"
- \endcode
-
- The \a options argument holds various options about how to run the dialog,
- see the QFileDialog::Option enum for more information on the flags you can
- pass.
-
- The dialog's caption is set to \a caption. If \a caption is not specified
- then a default caption will be used.
-
- On Windows, Mac OS X and Symbian^3, this static function will use the
- native file dialog and not a QFileDialog.
-
- On Windows the dialog will spin a blocking modal event loop that will not
- dispatch any QTimers, and if \a parent is not 0 then it will position the
- dialog just below the parent's title bar.
-
- On Unix/X11, the normal behavior of the file dialog is to resolve and
- follow symlinks. For example, if \c{/usr/tmp} is a symlink to \c{/var/tmp},
- the file dialog will change to \c{/var/tmp} after entering \c{/usr/tmp}. If
- \a options includes DontResolveSymlinks, the file dialog will treat
- symlinks as regular directories.
-
- On Symbian^3 the parameter \a selectedFilter has no meaning and the
- \a options parameter is only used to define if the native file dialog is
- used.
-
- \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
- QFileDialog constructors.
-
- \sa getOpenFileNames(), getSaveFileName(), getExistingDirectory()
-*/
-QString QFileDialog::getOpenFileName(QWidget *parent,
- const QString &caption,
- const QString &dir,
- const QString &filter,
- QString *selectedFilter,
- Options options)
-{
- if (qt_filedialog_open_filename_hook && !(options & DontUseNativeDialog))
- return qt_filedialog_open_filename_hook(parent, caption, dir, filter, selectedFilter, options);
-#if defined(Q_WS_S60)
- if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0 && !(options & DontUseNativeDialog))
- return qtSymbianGetOpenFileName(caption, dir, filter);
-#endif
- QFileDialogArgs args;
- args.parent = parent;
- args.caption = caption;
- args.directory = QFileDialogPrivate::workingDirectory(dir);
- args.selection = QFileDialogPrivate::initialSelection(dir);
- args.filter = filter;
- args.mode = ExistingFile;
- args.options = options;
-#if defined(Q_WS_WIN)
- if (qt_use_native_dialogs && !(args.options & DontUseNativeDialog)) {
- return qt_win_get_open_file_name(args, &(args.directory), selectedFilter);
- }
-#endif
-
- // create a qt dialog
- QFileDialog dialog(args);
- if (selectedFilter)
- dialog.selectNameFilter(*selectedFilter);
- if (dialog.exec() == QDialog::Accepted) {
- if (selectedFilter)
- *selectedFilter = dialog.selectedFilter();
- return dialog.selectedFiles().value(0);
- }
- return QString();
-}
-
-/*!
- This is a convenience static function that will return one or more existing
- files selected by the user.
-
- \snippet doc/src/snippets/code/src_gui_dialogs_qfiledialog.cpp 9
-
- This function creates a modal file dialog with the given \a parent widget.
- If \a parent is not 0, the dialog will be shown centered over the parent
- widget.
-
- The file dialog's working directory will be set to \a dir. If \a dir
- includes a file name, the file will be selected. The filter is set to
- \a filter so that only those files which match the filter are shown. The
- filter selected is set to \a selectedFilter. The parameters \a dir,
- \a selectedFilter and \a filter may be empty strings. If you need multiple
- filters, separate them with ';;', for instance:
-
- \code
- "Images (*.png *.xpm *.jpg);;Text files (*.txt);;XML files (*.xml)"
- \endcode
-
- The dialog's caption is set to \a caption. If \a caption is not specified
- then a default caption will be used.
-
- On Windows, Mac OS X and Symbian^3, this static function will use the
- native file dialog and not a QFileDialog.
-
- On Windows the dialog will spin a blocking modal event loop that will not
- dispatch any QTimers, and if \a parent is not 0 then it will position the
- dialog just below the parent's title bar.
-
- On Unix/X11, the normal behavior of the file dialog is to resolve and
- follow symlinks. For example, if \c{/usr/tmp} is a symlink to \c{/var/tmp},
- the file dialog will change to \c{/var/tmp} after entering \c{/usr/tmp}.
- The \a options argument holds various options about how to run the dialog,
- see the QFileDialog::Option enum for more information on the flags you can
- pass.
-
- \note If you want to iterate over the list of files, you should iterate
- over a copy. For example:
-
- \snippet doc/src/snippets/code/src_gui_dialogs_qfiledialog.cpp 10
-
- On Symbian^3 the parameter \a selectedFilter has no meaning and the
- \a options parameter is only used to define if the native file dialog is
- used. On Symbian^3, this function can only return a single filename.
-
- \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
- QFileDialog constructors.
-
- \sa getOpenFileName(), getSaveFileName(), getExistingDirectory()
-*/
-QStringList QFileDialog::getOpenFileNames(QWidget *parent,
- const QString &caption,
- const QString &dir,
- const QString &filter,
- QString *selectedFilter,
- Options options)
-{
- if (qt_filedialog_open_filenames_hook && !(options & DontUseNativeDialog))
- return qt_filedialog_open_filenames_hook(parent, caption, dir, filter, selectedFilter, options);
-#if defined(Q_WS_S60)
- if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0 && !(options & DontUseNativeDialog))
- return qtSymbianGetOpenFileNames(caption, dir, filter);
-#endif
- QFileDialogArgs args;
- args.parent = parent;
- args.caption = caption;
- args.directory = QFileDialogPrivate::workingDirectory(dir);
- args.selection = QFileDialogPrivate::initialSelection(dir);
- args.filter = filter;
- args.mode = ExistingFiles;
- args.options = options;
-
-#if defined(Q_WS_WIN)
- if (qt_use_native_dialogs && !(args.options & DontUseNativeDialog)) {
- return qt_win_get_open_file_names(args, &(args.directory), selectedFilter);
- }
-#endif
-
- // create a qt dialog
- QFileDialog dialog(args);
- if (selectedFilter)
- dialog.selectNameFilter(*selectedFilter);
- if (dialog.exec() == QDialog::Accepted) {
- if (selectedFilter)
- *selectedFilter = dialog.selectedFilter();
- return dialog.selectedFiles();
- }
- return QStringList();
-}
-
-/*!
- This is a convenience static function that will return a file name selected
- by the user. The file does not have to exist.
-
- It creates a modal file dialog with the given \a parent widget. If
- \a parent is not 0, the dialog will be shown centered over the parent
- widget.
-
- \snippet doc/src/snippets/code/src_gui_dialogs_qfiledialog.cpp 11
-
- The file dialog's working directory will be set to \a dir. If \a dir
- includes a file name, the file will be selected. Only files that match the
- \a filter are shown. The filter selected is set to \a selectedFilter. The
- parameters \a dir, \a selectedFilter, and \a filter may be empty strings.
- Multiple filters are separated with ';;'. For instance:
-
- \code
- "Images (*.png *.xpm *.jpg);;Text files (*.txt);;XML files (*.xml)"
- \endcode
-
- The \a options argument holds various options about how to run the dialog,
- see the QFileDialog::Option enum for more information on the flags you can
- pass.
-
- The default filter can be chosen by setting \a selectedFilter to the
- desired value.
-
- The dialog's caption is set to \a caption. If \a caption is not specified,
- a default caption will be used.
-
- On Windows, Mac OS X and Symbian^3, this static function will use the
- native file dialog and not a QFileDialog.
-
- On Windows the dialog will spin a blocking modal event loop that will not
- dispatch any QTimers, and if \a parent is not 0 then it will position the
- dialog just below the parent's title bar. On Mac OS X, with its native file
- dialog, the filter argument is ignored.
-
- On Unix/X11, the normal behavior of the file dialog is to resolve and
- follow symlinks. For example, if \c{/usr/tmp} is a symlink to \c{/var/tmp},
- the file dialog will change to \c{/var/tmp} after entering \c{/usr/tmp}. If
- \a options includes DontResolveSymlinks the file dialog will treat symlinks
- as regular directories.
-
- On Symbian^3 the parameters \a filter and \a selectedFilter have no
- meaning. The \a options parameter is only used to define if the native file
- dialog is used.
-
- \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
- QFileDialog constructors.
-
- \sa getOpenFileName(), getOpenFileNames(), getExistingDirectory()
-*/
-QString QFileDialog::getSaveFileName(QWidget *parent,
- const QString &caption,
- const QString &dir,
- const QString &filter,
- QString *selectedFilter,
- Options options)
-{
- if (qt_filedialog_save_filename_hook && !(options & DontUseNativeDialog))
- return qt_filedialog_save_filename_hook(parent, caption, dir, filter, selectedFilter, options);
-#if defined(Q_WS_S60)
- if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0 && !(options & DontUseNativeDialog))
- return qtSymbianGetSaveFileName(caption, dir);
-#endif
- QFileDialogArgs args;
- args.parent = parent;
- args.caption = caption;
- args.directory = QFileDialogPrivate::workingDirectory(dir);
- args.selection = QFileDialogPrivate::initialSelection(dir);
- args.filter = filter;
- args.mode = AnyFile;
- args.options = options;
-
-#if defined(Q_WS_WIN)
- if (qt_use_native_dialogs && !(args.options & DontUseNativeDialog)) {
- return qt_win_get_save_file_name(args, &(args.directory), selectedFilter);
- }
-#endif
-
- // create a qt dialog
- QFileDialog dialog(args);
- dialog.setAcceptMode(AcceptSave);
- if (selectedFilter)
- dialog.selectNameFilter(*selectedFilter);
- if (dialog.exec() == QDialog::Accepted) {
- if (selectedFilter)
- *selectedFilter = dialog.selectedFilter();
- return dialog.selectedFiles().value(0);
- }
-
- return QString();
-}
-
-/*!
- This is a convenience static function that will return an existing
- directory selected by the user.
-
- \snippet doc/src/snippets/code/src_gui_dialogs_qfiledialog.cpp 12
-
- This function creates a modal file dialog with the given \a parent widget.
- If \a parent is not 0, the dialog will be shown centered over the parent
- widget.
-
- The dialog's working directory is set to \a dir, and the caption is set to
- \a caption. Either of these may be an empty string in which case the
- current directory and a default caption will be used respectively.
-
- The \a options argument holds various options about how to run the dialog,
- see the QFileDialog::Option enum for more information on the flags you can
- pass. To ensure a native file dialog, \l{QFileDialog::}{ShowDirsOnly} must
- be set.
-
- On Windows, Mac OS X and Symbian^3, this static function will use the
- native file dialog and not a QFileDialog. On Windows CE, if the device has
- no native file dialog, a QFileDialog will be used.
-
- On Unix/X11, the normal behavior of the file dialog is to resolve and
- follow symlinks. For example, if \c{/usr/tmp} is a symlink to \c{/var/tmp},
- the file dialog will change to \c{/var/tmp} after entering \c{/usr/tmp}. If
- \a options includes DontResolveSymlinks, the file dialog will treat
- symlinks as regular directories.
-
- On Windows the dialog will spin a blocking modal event loop that will not
- dispatch any QTimers, and if \a parent is not 0 then it will position the
- dialog just below the parent's title bar.
-
- On Symbian^3 the \a options parameter is only used to define if the native
- file dialog is used.
-
- \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
- QFileDialog constructors.
-
- \sa getOpenFileName(), getOpenFileNames(), getSaveFileName()
-*/
-QString QFileDialog::getExistingDirectory(QWidget *parent,
- const QString &caption,
- const QString &dir,
- Options options)
-{
- if (qt_filedialog_existing_directory_hook && !(options & DontUseNativeDialog))
- return qt_filedialog_existing_directory_hook(parent, caption, dir, options);
-#if defined(Q_WS_S60)
- if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0 && !(options & DontUseNativeDialog))
- return qtSymbianGetExistingDirectory(caption, dir);
-#endif
- QFileDialogArgs args;
- args.parent = parent;
- args.caption = caption;
- args.directory = QFileDialogPrivate::workingDirectory(dir);
- args.mode = (options & ShowDirsOnly ? DirectoryOnly : Directory);
- args.options = options;
-
-#if defined(Q_WS_WIN)
- if (qt_use_native_dialogs && !(args.options & DontUseNativeDialog) && (options & ShowDirsOnly)
-#if defined(Q_WS_WINCE)
- && qt_priv_ptr_valid
-#endif
- ) {
- return qt_win_get_existing_directory(args);
- }
-#endif
-
- // create a qt dialog
- QFileDialog dialog(args);
- if (dialog.exec() == QDialog::Accepted) {
- return dialog.selectedFiles().value(0);
- }
- return QString();
-}
-
-inline static QString _qt_get_directory(const QString &path)
-{
- QFileInfo info = QFileInfo(QDir::current(), path);
- if (info.exists() && info.isDir())
- return QDir::cleanPath(info.absoluteFilePath());
- info.setFile(info.absolutePath());
- if (info.exists() && info.isDir())
- return info.absoluteFilePath();
- return QString();
-}
-/*
- Get the initial directory path
-
- \sa initialSelection()
- */
-QString QFileDialogPrivate::workingDirectory(const QString &path)
-{
- if (!path.isEmpty()) {
- QString directory = _qt_get_directory(path);
- if (!directory.isEmpty())
- return directory;
- }
- QString directory = _qt_get_directory(*lastVisitedDir());
- if (!directory.isEmpty())
- return directory;
- return QDir::currentPath();
-}
-
-/*
- Get the initial selection given a path. The initial directory
- can contain both the initial directory and initial selection
- /home/user/foo.txt
-
- \sa workingDirectory()
- */
-QString QFileDialogPrivate::initialSelection(const QString &path)
-{
- if (!path.isEmpty()) {
- QFileInfo info(path);
- if (!info.isDir())
- return info.fileName();
- }
- return QString();
-}
-
-/*!
- \reimp
-*/
-void QFileDialog::done(int result)
-{
- Q_D(QFileDialog);
-
- QDialog::done(result);
-
- if (d->receiverToDisconnectOnClose) {
- disconnect(this, d->signalToDisconnectOnClose,
- d->receiverToDisconnectOnClose, d->memberToDisconnectOnClose);
- d->receiverToDisconnectOnClose = 0;
- }
- d->memberToDisconnectOnClose.clear();
- d->signalToDisconnectOnClose.clear();
-}
-
-/*!
- \reimp
-*/
-void QFileDialog::accept()
-{
- Q_D(QFileDialog);
- QStringList files = selectedFiles();
- if (files.isEmpty())
- return;
- if (d->nativeDialogInUse){
- d->emitFilesSelected(files);
- QDialog::accept();
- return;
- }
-
- QString lineEditText = d->lineEdit()->text();
- // "hidden feature" type .. and then enter, and it will move up a dir
- // special case for ".."
- if (lineEditText == QLatin1String("..")) {
- d->_q_navigateToParent();
- bool block = d->qFileDialogUi->fileNameEdit->blockSignals(true);
- d->lineEdit()->selectAll();
- d->qFileDialogUi->fileNameEdit->blockSignals(block);
- return;
- }
-
- switch (d->fileMode) {
- case DirectoryOnly:
- case Directory: {
- QString fn = files.first();
- QFileInfo info(fn);
- if (!info.exists())
- info = QFileInfo(d->getEnvironmentVariable(fn));
- if (!info.exists()) {
-#ifndef QT_NO_MESSAGEBOX
- QString message = tr("%1\nDirectory not found.\nPlease verify the "
- "correct directory name was given.");
- QMessageBox::warning(this, windowTitle(), message.arg(info.fileName()));
-#endif // QT_NO_MESSAGEBOX
- return;
- }
- if (info.isDir()) {
- d->emitFilesSelected(files);
- QDialog::accept();
- }
- return;
- }
-
- case AnyFile: {
- QString fn = files.first();
- QFileInfo info(fn);
- if (info.isDir()) {
- setDirectory(info.absoluteFilePath());
- return;
- }
-
- if (!info.exists()) {
- int maxNameLength = d->maxNameLength(info.path());
- if (maxNameLength >= 0 && info.fileName().length() > maxNameLength)
- return;
- }
-
- // check if we have to ask for permission to overwrite the file
- if (!info.exists() || !confirmOverwrite() || acceptMode() == AcceptOpen) {
- d->emitFilesSelected(QStringList(fn));
- QDialog::accept();
-#ifndef QT_NO_MESSAGEBOX
- } else {
- if (QMessageBox::warning(this, windowTitle(),
- tr("%1 already exists.\nDo you want to replace it?")
- .arg(info.fileName()),
- QMessageBox::Yes | QMessageBox::No, QMessageBox::No)
- == QMessageBox::Yes) {
- d->emitFilesSelected(QStringList(fn));
- QDialog::accept();
- }
-#endif
- }
- return;
- }
-
- case ExistingFile:
- case ExistingFiles:
- for (int i = 0; i < files.count(); ++i) {
- QFileInfo info(files.at(i));
- if (!info.exists())
- info = QFileInfo(d->getEnvironmentVariable(files.at(i)));
- if (!info.exists()) {
-#ifndef QT_NO_MESSAGEBOX
- QString message = tr("%1\nFile not found.\nPlease verify the "
- "correct file name was given.");
- QMessageBox::warning(this, windowTitle(), message.arg(info.fileName()));
-#endif // QT_NO_MESSAGEBOX
- return;
- }
- if (info.isDir()) {
- setDirectory(info.absoluteFilePath());
- d->lineEdit()->clear();
- return;
- }
- }
- d->emitFilesSelected(files);
- QDialog::accept();
- return;
- }
-}
-
-/*!
- \internal
-
- Create widgets, layout and set default values
-*/
-void QFileDialogPrivate::init(const QString &directory, const QString &nameFilter,
- const QString &caption)
-{
- Q_Q(QFileDialog);
- if (!caption.isEmpty()) {
- useDefaultCaption = false;
- setWindowTitle = caption;
- q->setWindowTitle(caption);
- }
-
- createWidgets();
- createMenuActions();
- retranslateStrings();
- q->setFileMode(fileMode);
-
-#ifndef QT_NO_SETTINGS
- QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
- settings.beginGroup(QLatin1String("Qt"));
- if (!directory.isEmpty())
- setLastVisitedDirectory(workingDirectory(directory));
- q->restoreState(settings.value(QLatin1String("filedialog")).toByteArray());
-#endif
-
-#if defined(Q_EMBEDDED_SMALLSCREEN)
- qFileDialogUi->lookInLabel->setVisible(false);
- qFileDialogUi->fileNameLabel->setVisible(false);
- qFileDialogUi->fileTypeLabel->setVisible(false);
- qFileDialogUi->sidebar->hide();
-#endif
- // Default case
- if (!nameFilter.isEmpty())
- q->setNameFilter(nameFilter);
- q->setAcceptMode(QFileDialog::AcceptOpen);
- q->setDirectory(workingDirectory(directory));
- q->selectFile(initialSelection(directory));
-
- _q_updateOkButton();
- q->resize(q->sizeHint());
-}
-
-/*!
- \internal
-
- Create the widgets, set properties and connections
-*/
-void QFileDialogPrivate::createWidgets()
-{
- Q_Q(QFileDialog);
- model = new QFileSystemModel(q);
- model->setObjectName(QLatin1String("qt_filesystem_model"));
-#ifdef Q_WS_MAC
- model->setNameFilterDisables(true);
-#else
- model->setNameFilterDisables(false);
-#endif
- model->d_func()->disableRecursiveSort = true;
- QFileDialog::connect(model, SIGNAL(fileRenamed(QString,QString,QString)), q, SLOT(_q_fileRenamed(QString,QString,QString)));
- QFileDialog::connect(model, SIGNAL(rootPathChanged(QString)),
- q, SLOT(_q_pathChanged(QString)));
- QFileDialog::connect(model, SIGNAL(rowsInserted(QModelIndex,int,int)),
- q, SLOT(_q_rowsInserted(QModelIndex)));
- model->setReadOnly(false);
-
- qFileDialogUi.reset(new Ui_QFileDialog());
- qFileDialogUi->setupUi(q);
-
- QList<QUrl> initialBookmarks;
- initialBookmarks << QUrl::fromLocalFile(QLatin1String(""))
- << QUrl::fromLocalFile(QDir::homePath());
- qFileDialogUi->sidebar->init(model, initialBookmarks);
- QFileDialog::connect(qFileDialogUi->sidebar, SIGNAL(goToUrl(QUrl)),
- q, SLOT(_q_goToUrl(QUrl)));
-
- QObject::connect(qFileDialogUi->buttonBox, SIGNAL(accepted()), q, SLOT(accept()));
- QObject::connect(qFileDialogUi->buttonBox, SIGNAL(rejected()), q, SLOT(reject()));
-
-
- qFileDialogUi->lookInCombo->init(this);
- QObject::connect(qFileDialogUi->lookInCombo, SIGNAL(activated(QString)), q, SLOT(_q_goToDirectory(QString)));
-
- qFileDialogUi->lookInCombo->setInsertPolicy(QComboBox::NoInsert);
- qFileDialogUi->lookInCombo->setDuplicatesEnabled(false);
-
- // filename
- qFileDialogUi->fileNameEdit->init(this);
-#ifndef QT_NO_SHORTCUT
- qFileDialogUi->fileNameLabel->setBuddy(qFileDialogUi->fileNameEdit);
-#endif
-#ifndef QT_NO_FSCOMPLETER
- completer = new QFSCompleter(model, q);
- qFileDialogUi->fileNameEdit->setCompleter(completer);
-#endif // QT_NO_FSCOMPLETER
- QObject::connect(qFileDialogUi->fileNameEdit, SIGNAL(textChanged(QString)),
- q, SLOT(_q_autoCompleteFileName(QString)));
- QObject::connect(qFileDialogUi->fileNameEdit, SIGNAL(textChanged(QString)),
- q, SLOT(_q_updateOkButton()));
-
- QObject::connect(qFileDialogUi->fileNameEdit, SIGNAL(returnPressed()), q, SLOT(accept()));
-
- // filetype
- qFileDialogUi->fileTypeCombo->setDuplicatesEnabled(false);
- qFileDialogUi->fileTypeCombo->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLength);
- qFileDialogUi->fileTypeCombo->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
- QObject::connect(qFileDialogUi->fileTypeCombo, SIGNAL(activated(int)),
- q, SLOT(_q_useNameFilter(int)));
- QObject::connect(qFileDialogUi->fileTypeCombo, SIGNAL(activated(QString)),
- q, SIGNAL(filterSelected(QString)));
-
- qFileDialogUi->listView->init(this);
- qFileDialogUi->listView->setModel(model);
- QObject::connect(qFileDialogUi->listView, SIGNAL(activated(QModelIndex)),
- q, SLOT(_q_enterDirectory(QModelIndex)));
- QObject::connect(qFileDialogUi->listView, SIGNAL(customContextMenuRequested(QPoint)),
- q, SLOT(_q_showContextMenu(QPoint)));
-#ifndef QT_NO_SHORTCUT
- QShortcut *shortcut = new QShortcut(qFileDialogUi->listView);
- shortcut->setKey(QKeySequence(QLatin1String("Delete")));
- QObject::connect(shortcut, SIGNAL(activated()), q, SLOT(_q_deleteCurrent()));
-#endif
-
- qFileDialogUi->treeView->init(this);
- qFileDialogUi->treeView->setModel(model);
- QHeaderView *treeHeader = qFileDialogUi->treeView->header();
- QFontMetrics fm(q->font());
- treeHeader->resizeSection(0, fm.width(QLatin1String("wwwwwwwwwwwwwwwwwwwwwwwwww")));
- treeHeader->resizeSection(1, fm.width(QLatin1String("128.88 GB")));
- treeHeader->resizeSection(2, fm.width(QLatin1String("mp3Folder")));
- treeHeader->resizeSection(3, fm.width(QLatin1String("10/29/81 02:02PM")));
- treeHeader->setContextMenuPolicy(Qt::ActionsContextMenu);
-
- QActionGroup *showActionGroup = new QActionGroup(q);
- showActionGroup->setExclusive(false);
- QObject::connect(showActionGroup, SIGNAL(triggered(QAction*)),
- q, SLOT(_q_showHeader(QAction*)));;
-
- QAbstractItemModel *abstractModel = model;
-#ifndef QT_NO_PROXYMODEL
- if (proxyModel)
- abstractModel = proxyModel;
-#endif
- for (int i = 1; i < abstractModel->columnCount(QModelIndex()); ++i) {
- QAction *showHeader = new QAction(showActionGroup);
- showHeader->setCheckable(true);
- showHeader->setChecked(true);
- treeHeader->addAction(showHeader);
- }
-
- QScopedPointer<QItemSelectionModel> selModel(qFileDialogUi->treeView->selectionModel());
- qFileDialogUi->treeView->setSelectionModel(qFileDialogUi->listView->selectionModel());
-
- QObject::connect(qFileDialogUi->treeView, SIGNAL(activated(QModelIndex)),
- q, SLOT(_q_enterDirectory(QModelIndex)));
- QObject::connect(qFileDialogUi->treeView, SIGNAL(customContextMenuRequested(QPoint)),
- q, SLOT(_q_showContextMenu(QPoint)));
-#ifndef QT_NO_SHORTCUT
- shortcut = new QShortcut(qFileDialogUi->treeView);
- shortcut->setKey(QKeySequence(QLatin1String("Delete")));
- QObject::connect(shortcut, SIGNAL(activated()), q, SLOT(_q_deleteCurrent()));
-#endif
-
- // Selections
- QItemSelectionModel *selections = qFileDialogUi->listView->selectionModel();
- QObject::connect(selections, SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
- q, SLOT(_q_selectionChanged()));
- QObject::connect(selections, SIGNAL(currentChanged(QModelIndex,QModelIndex)),
- q, SLOT(_q_currentChanged(QModelIndex)));
- qFileDialogUi->splitter->setStretchFactor(qFileDialogUi->splitter->indexOf(qFileDialogUi->splitter->widget(1)), QSizePolicy::Expanding);
-
- createToolButtons();
-}
-
-void QFileDialogPrivate::_q_showHeader(QAction *action)
-{
- Q_Q(QFileDialog);
- QActionGroup *actionGroup = qobject_cast<QActionGroup*>(q->sender());
- qFileDialogUi->treeView->header()->setSectionHidden(actionGroup->actions().indexOf(action) + 1, !action->isChecked());
-}
-
-#ifndef QT_NO_PROXYMODEL
-/*!
- \since 4.3
-
- Sets the model for the views to the given \a proxyModel. This is useful if you
- want to modify the underlying model; for example, to add columns, filter
- data or add drives.
-
- Any existing proxy model will be removed, but not deleted. The file dialog
- will take ownership of the \a proxyModel.
-
- \sa proxyModel()
-*/
-void QFileDialog::setProxyModel(QAbstractProxyModel *proxyModel)
-{
- Q_D(QFileDialog);
- if ((!proxyModel && !d->proxyModel)
- || (proxyModel == d->proxyModel))
- return;
-
- QModelIndex idx = d->rootIndex();
- if (d->proxyModel) {
- disconnect(d->proxyModel, SIGNAL(rowsInserted(QModelIndex,int,int)),
- this, SLOT(_q_rowsInserted(QModelIndex)));
- } else {
- disconnect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)),
- this, SLOT(_q_rowsInserted(QModelIndex)));
- }
-
- if (proxyModel != 0) {
- proxyModel->setParent(this);
- d->proxyModel = proxyModel;
- proxyModel->setSourceModel(d->model);
- d->qFileDialogUi->listView->setModel(d->proxyModel);
- d->qFileDialogUi->treeView->setModel(d->proxyModel);
-#ifndef QT_NO_FSCOMPLETER
- d->completer->setModel(d->proxyModel);
- d->completer->proxyModel = d->proxyModel;
-#endif
- connect(d->proxyModel, SIGNAL(rowsInserted(QModelIndex,int,int)),
- this, SLOT(_q_rowsInserted(QModelIndex)));
- } else {
- d->proxyModel = 0;
- d->qFileDialogUi->listView->setModel(d->model);
- d->qFileDialogUi->treeView->setModel(d->model);
-#ifndef QT_NO_FSCOMPLETER
- d->completer->setModel(d->model);
- d->completer->sourceModel = d->model;
- d->completer->proxyModel = 0;
-#endif
- connect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)),
- this, SLOT(_q_rowsInserted(QModelIndex)));
- }
- QScopedPointer<QItemSelectionModel> selModel(d->qFileDialogUi->treeView->selectionModel());
- d->qFileDialogUi->treeView->setSelectionModel(d->qFileDialogUi->listView->selectionModel());
-
- d->setRootIndex(idx);
-
- // reconnect selection
- QItemSelectionModel *selections = d->qFileDialogUi->listView->selectionModel();
- QObject::connect(selections, SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
- this, SLOT(_q_selectionChanged()));
- QObject::connect(selections, SIGNAL(currentChanged(QModelIndex,QModelIndex)),
- this, SLOT(_q_currentChanged(QModelIndex)));
-}
-
-/*!
- Returns the proxy model used by the file dialog. By default no proxy is set.
-
- \sa setProxyModel()
-*/
-QAbstractProxyModel *QFileDialog::proxyModel() const
-{
- Q_D(const QFileDialog);
- return d->proxyModel;
-}
-#endif // QT_NO_PROXYMODEL
-
-/*!
- \internal
-
- Create tool buttons, set properties and connections
-*/
-void QFileDialogPrivate::createToolButtons()
-{
- Q_Q(QFileDialog);
- qFileDialogUi->backButton->setIcon(q->style()->standardIcon(QStyle::SP_ArrowBack, 0, q));
- qFileDialogUi->backButton->setAutoRaise(true);
- qFileDialogUi->backButton->setEnabled(false);
- QObject::connect(qFileDialogUi->backButton, SIGNAL(clicked()), q, SLOT(_q_navigateBackward()));
-
- qFileDialogUi->forwardButton->setIcon(q->style()->standardIcon(QStyle::SP_ArrowForward, 0, q));
- qFileDialogUi->forwardButton->setAutoRaise(true);
- qFileDialogUi->forwardButton->setEnabled(false);
- QObject::connect(qFileDialogUi->forwardButton, SIGNAL(clicked()), q, SLOT(_q_navigateForward()));
-
- qFileDialogUi->toParentButton->setIcon(q->style()->standardIcon(QStyle::SP_FileDialogToParent, 0, q));
- qFileDialogUi->toParentButton->setAutoRaise(true);
- qFileDialogUi->toParentButton->setEnabled(false);
- QObject::connect(qFileDialogUi->toParentButton, SIGNAL(clicked()), q, SLOT(_q_navigateToParent()));
-
- qFileDialogUi->listModeButton->setIcon(q->style()->standardIcon(QStyle::SP_FileDialogListView, 0, q));
- qFileDialogUi->listModeButton->setAutoRaise(true);
- qFileDialogUi->listModeButton->setDown(true);
- QObject::connect(qFileDialogUi->listModeButton, SIGNAL(clicked()), q, SLOT(_q_showListView()));
-
- qFileDialogUi->detailModeButton->setIcon(q->style()->standardIcon(QStyle::SP_FileDialogDetailedView, 0, q));
- qFileDialogUi->detailModeButton->setAutoRaise(true);
- QObject::connect(qFileDialogUi->detailModeButton, SIGNAL(clicked()), q, SLOT(_q_showDetailsView()));
-
- QSize toolSize(qFileDialogUi->fileNameEdit->sizeHint().height(), qFileDialogUi->fileNameEdit->sizeHint().height());
- qFileDialogUi->backButton->setFixedSize(toolSize);
- qFileDialogUi->listModeButton->setFixedSize(toolSize);
- qFileDialogUi->detailModeButton->setFixedSize(toolSize);
- qFileDialogUi->forwardButton->setFixedSize(toolSize);
- qFileDialogUi->toParentButton->setFixedSize(toolSize);
-
- qFileDialogUi->newFolderButton->setIcon(q->style()->standardIcon(QStyle::SP_FileDialogNewFolder, 0, q));
- qFileDialogUi->newFolderButton->setFixedSize(toolSize);
- qFileDialogUi->newFolderButton->setAutoRaise(true);
- qFileDialogUi->newFolderButton->setEnabled(false);
- QObject::connect(qFileDialogUi->newFolderButton, SIGNAL(clicked()), q, SLOT(_q_createDirectory()));
-}
-
-/*!
- \internal
-
- Create actions which will be used in the right click.
-*/
-void QFileDialogPrivate::createMenuActions()
-{
- Q_Q(QFileDialog);
-
- QAction *goHomeAction = new QAction(q);
-#ifndef QT_NO_SHORTCUT
- goHomeAction->setShortcut(Qt::CTRL + Qt::Key_H + Qt::SHIFT);
-#endif
- QObject::connect(goHomeAction, SIGNAL(triggered()), q, SLOT(_q_goHome()));
- q->addAction(goHomeAction);
-
- // ### TODO add Desktop & Computer actions
-
- QAction *goToParent = new QAction(q);
- goToParent->setObjectName(QLatin1String("qt_goto_parent_action"));
-#ifndef QT_NO_SHORTCUT
- goToParent->setShortcut(Qt::CTRL + Qt::UpArrow);
-#endif
- QObject::connect(goToParent, SIGNAL(triggered()), q, SLOT(_q_navigateToParent()));
- q->addAction(goToParent);
-
- renameAction = new QAction(q);
- renameAction->setEnabled(false);
- renameAction->setObjectName(QLatin1String("qt_rename_action"));
- QObject::connect(renameAction, SIGNAL(triggered()), q, SLOT(_q_renameCurrent()));
-
- deleteAction = new QAction(q);
- deleteAction->setEnabled(false);
- deleteAction->setObjectName(QLatin1String("qt_delete_action"));
- QObject::connect(deleteAction, SIGNAL(triggered()), q, SLOT(_q_deleteCurrent()));
-
- showHiddenAction = new QAction(q);
- showHiddenAction->setObjectName(QLatin1String("qt_show_hidden_action"));
- showHiddenAction->setCheckable(true);
- QObject::connect(showHiddenAction, SIGNAL(triggered()), q, SLOT(_q_showHidden()));
-
- newFolderAction = new QAction(q);
- newFolderAction->setObjectName(QLatin1String("qt_new_folder_action"));
- QObject::connect(newFolderAction, SIGNAL(triggered()), q, SLOT(_q_createDirectory()));
-}
-
-void QFileDialogPrivate::_q_goHome()
-{
- Q_Q(QFileDialog);
- q->setDirectory(QDir::homePath());
-}
-
-/*!
- \internal
-
- Update history with new path, buttons, and combo
-*/
-void QFileDialogPrivate::_q_pathChanged(const QString &newPath)
-{
- Q_Q(QFileDialog);
- QDir dir(model->rootDirectory());
- qFileDialogUi->toParentButton->setEnabled(dir.exists());
- qFileDialogUi->sidebar->selectUrl(QUrl::fromLocalFile(newPath));
- q->setHistory(qFileDialogUi->lookInCombo->history());
-
- if (currentHistoryLocation < 0 || currentHistory.value(currentHistoryLocation) != QDir::toNativeSeparators(newPath)) {
- while (currentHistoryLocation >= 0 && currentHistoryLocation + 1 < currentHistory.count()) {
- currentHistory.removeLast();
- }
- currentHistory.append(QDir::toNativeSeparators(newPath));
- ++currentHistoryLocation;
- }
- qFileDialogUi->forwardButton->setEnabled(currentHistory.size() - currentHistoryLocation > 1);
- qFileDialogUi->backButton->setEnabled(currentHistoryLocation > 0);
-}
-
-/*!
- \internal
-
- Navigates to the last directory viewed in the dialog.
-*/
-void QFileDialogPrivate::_q_navigateBackward()
-{
- Q_Q(QFileDialog);
- if (!currentHistory.isEmpty() && currentHistoryLocation > 0) {
- --currentHistoryLocation;
- QString previousHistory = currentHistory.at(currentHistoryLocation);
- q->setDirectory(previousHistory);
- }
-}
-
-/*!
- \internal
-
- Navigates to the last directory viewed in the dialog.
-*/
-void QFileDialogPrivate::_q_navigateForward()
-{
- Q_Q(QFileDialog);
- if (!currentHistory.isEmpty() && currentHistoryLocation < currentHistory.size() - 1) {
- ++currentHistoryLocation;
- QString nextHistory = currentHistory.at(currentHistoryLocation);
- q->setDirectory(nextHistory);
- }
-}
-
-/*!
- \internal
-
- Navigates to the parent directory of the currently displayed directory
- in the dialog.
-*/
-void QFileDialogPrivate::_q_navigateToParent()
-{
- Q_Q(QFileDialog);
- QDir dir(model->rootDirectory());
- QString newDirectory;
- if (dir.isRoot()) {
- newDirectory = model->myComputer().toString();
- } else {
- dir.cdUp();
- newDirectory = dir.absolutePath();
- }
- q->setDirectory(newDirectory);
- emit q->directoryEntered(newDirectory);
-}
-
-/*!
- \internal
-
- Creates a new directory, first asking the user for a suitable name.
-*/
-void QFileDialogPrivate::_q_createDirectory()
-{
- Q_Q(QFileDialog);
- qFileDialogUi->listView->clearSelection();
-
- QString newFolderString = QFileDialog::tr("New Folder");
- QString folderName = newFolderString;
- QString prefix = q->directory().absolutePath() + QDir::separator();
- if (QFile::exists(prefix + folderName)) {
- qlonglong suffix = 2;
- while (QFile::exists(prefix + folderName)) {
- folderName = newFolderString + QString::number(suffix++);
- }
- }
-
- QModelIndex parent = rootIndex();
- QModelIndex index = model->mkdir(parent, folderName);
- if (!index.isValid())
- return;
-
- index = select(index);
- if (index.isValid()) {
- qFileDialogUi->treeView->setCurrentIndex(index);
- currentView()->edit(index);
- }
-}
-
-void QFileDialogPrivate::_q_showListView()
-{
- qFileDialogUi->listModeButton->setDown(true);
- qFileDialogUi->detailModeButton->setDown(false);
- qFileDialogUi->treeView->hide();
- qFileDialogUi->listView->show();
- qFileDialogUi->stackedWidget->setCurrentWidget(qFileDialogUi->listView->parentWidget());
- qFileDialogUi->listView->doItemsLayout();
-}
-
-void QFileDialogPrivate::_q_showDetailsView()
-{
- qFileDialogUi->listModeButton->setDown(false);
- qFileDialogUi->detailModeButton->setDown(true);
- qFileDialogUi->listView->hide();
- qFileDialogUi->treeView->show();
- qFileDialogUi->stackedWidget->setCurrentWidget(qFileDialogUi->treeView->parentWidget());
- qFileDialogUi->treeView->doItemsLayout();
-}
-
-/*!
- \internal
-
- Show the context menu for the file/dir under position
-*/
-void QFileDialogPrivate::_q_showContextMenu(const QPoint &position)
-{
-#ifdef QT_NO_MENU
- Q_UNUSED(position);
-#else
- Q_Q(QFileDialog);
- QAbstractItemView *view = 0;
- if (q->viewMode() == QFileDialog::Detail)
- view = qFileDialogUi->treeView;
- else
- view = qFileDialogUi->listView;
- QModelIndex index = view->indexAt(position);
- index = mapToSource(index.sibling(index.row(), 0));
-
- QMenu menu(view);
- if (index.isValid()) {
- // file context menu
- QFile::Permissions p(index.parent().data(QFileSystemModel::FilePermissions).toInt());
- renameAction->setEnabled(p & QFile::WriteUser);
- menu.addAction(renameAction);
- deleteAction->setEnabled(p & QFile::WriteUser);
- menu.addAction(deleteAction);
- menu.addSeparator();
- }
- menu.addAction(showHiddenAction);
- if (qFileDialogUi->newFolderButton->isVisible()) {
- newFolderAction->setEnabled(qFileDialogUi->newFolderButton->isEnabled());
- menu.addAction(newFolderAction);
- }
- menu.exec(view->viewport()->mapToGlobal(position));
-#endif // QT_NO_MENU
-}
-
-/*!
- \internal
-*/
-void QFileDialogPrivate::_q_renameCurrent()
-{
- Q_Q(QFileDialog);
- QModelIndex index = qFileDialogUi->listView->currentIndex();
- index = index.sibling(index.row(), 0);
- if (q->viewMode() == QFileDialog::List)
- qFileDialogUi->listView->edit(index);
- else
- qFileDialogUi->treeView->edit(index);
-}
-
-bool QFileDialogPrivate::removeDirectory(const QString &path)
-{
- QModelIndex modelIndex = model->index(path);
- return model->remove(modelIndex);
-}
-
-/*!
- \internal
-
- Deletes the currently selected item in the dialog.
-*/
-void QFileDialogPrivate::_q_deleteCurrent()
-{
- if (model->isReadOnly())
- return;
-
- QModelIndexList list = qFileDialogUi->listView->selectionModel()->selectedRows();
- for (int i = list.count() - 1; i >= 0; --i) {
- QModelIndex index = list.at(i);
- if (index == qFileDialogUi->listView->rootIndex())
- continue;
-
- index = mapToSource(index.sibling(index.row(), 0));
- if (!index.isValid())
- continue;
-
- QString fileName = index.data(QFileSystemModel::FileNameRole).toString();
- QString filePath = index.data(QFileSystemModel::FilePathRole).toString();
- bool isDir = model->isDir(index);
-
- QFile::Permissions p(index.parent().data(QFileSystemModel::FilePermissions).toInt());
-#ifndef QT_NO_MESSAGEBOX
- Q_Q(QFileDialog);
- if (!(p & QFile::WriteUser) && (QMessageBox::warning(q_func(), q_func()->windowTitle(),
- QFileDialog::tr("'%1' is write protected.\nDo you want to delete it anyway?")
- .arg(fileName),
- QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::No))
- return;
- else if (QMessageBox::warning(q_func(), q_func()->windowTitle(),
- QFileDialog::tr("Are sure you want to delete '%1'?")
- .arg(fileName),
- QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::No)
- return;
-
-#else
- if (!(p & QFile::WriteUser))
- return;
-#endif // QT_NO_MESSAGEBOX
-
- // the event loop has run, we can NOT reuse index because the model might have removed it.
- if (isDir) {
- if (!removeDirectory(filePath)) {
-#ifndef QT_NO_MESSAGEBOX
- QMessageBox::warning(q, q->windowTitle(),
- QFileDialog::tr("Could not delete directory."));
-#endif
- }
- } else {
- model->remove(index);
- }
- }
-}
-
-void QFileDialogPrivate::_q_autoCompleteFileName(const QString &text)
-{
- if (text.startsWith(QLatin1String("//")) || text.startsWith(QLatin1Char('\\'))) {
- qFileDialogUi->listView->selectionModel()->clearSelection();
- return;
- }
-
- QStringList multipleFiles = typedFiles();
- if (multipleFiles.count() > 0) {
- QModelIndexList oldFiles = qFileDialogUi->listView->selectionModel()->selectedRows();
- QModelIndexList newFiles;
- for (int i = 0; i < multipleFiles.count(); ++i) {
- QModelIndex idx = model->index(multipleFiles.at(i));
- if (oldFiles.contains(idx))
- oldFiles.removeAll(idx);
- else
- newFiles.append(idx);
- }
- for (int i = 0; i < newFiles.count(); ++i)
- select(newFiles.at(i));
- if (lineEdit()->hasFocus())
- for (int i = 0; i < oldFiles.count(); ++i)
- qFileDialogUi->listView->selectionModel()->select(oldFiles.at(i),
- QItemSelectionModel::Toggle | QItemSelectionModel::Rows);
- }
-}
-
-/*!
- \internal
-*/
-void QFileDialogPrivate::_q_updateOkButton()
-{
- Q_Q(QFileDialog);
- QPushButton *button = qFileDialogUi->buttonBox->button((acceptMode == QFileDialog::AcceptOpen)
- ? QDialogButtonBox::Open : QDialogButtonBox::Save);
- if (!button)
- return;
-
- bool enableButton = true;
- bool isOpenDirectory = false;
-
- QStringList files = q->selectedFiles();
- QString lineEditText = lineEdit()->text();
-
- if (lineEditText.startsWith(QLatin1String("//")) || lineEditText.startsWith(QLatin1Char('\\'))) {
- button->setEnabled(true);
- if (acceptMode == QFileDialog::AcceptSave)
- button->setText(acceptLabel);
- return;
- }
-
- if (files.isEmpty()) {
- enableButton = false;
- } else if (lineEditText == QLatin1String("..")) {
- isOpenDirectory = true;
- } else {
- switch (fileMode) {
- case QFileDialog::DirectoryOnly:
- case QFileDialog::Directory: {
- QString fn = files.first();
- QModelIndex idx = model->index(fn);
- if (!idx.isValid())
- idx = model->index(getEnvironmentVariable(fn));
- if (!idx.isValid() || !model->isDir(idx))
- enableButton = false;
- break;
- }
- case QFileDialog::AnyFile: {
- QString fn = files.first();
- QFileInfo info(fn);
- QModelIndex idx = model->index(fn);
- QString fileDir;
- QString fileName;
- if (info.isDir()) {
- fileDir = info.canonicalFilePath();
- } else {
- fileDir = fn.mid(0, fn.lastIndexOf(QLatin1Char('/')));
- fileName = fn.mid(fileDir.length() + 1);
- }
- if (lineEditText.contains(QLatin1String(".."))) {
- fileDir = info.canonicalFilePath();
- fileName = info.fileName();
- }
-
- if (fileDir == q->directory().canonicalPath() && fileName.isEmpty()) {
- enableButton = false;
- break;
- }
- if (idx.isValid() && model->isDir(idx)) {
- isOpenDirectory = true;
- enableButton = true;
- break;
- }
- if (!idx.isValid()) {
- int maxLength = maxNameLength(fileDir);
- enableButton = maxLength < 0 || fileName.length() <= maxLength;
- }
- break;
- }
- case QFileDialog::ExistingFile:
- case QFileDialog::ExistingFiles:
- for (int i = 0; i < files.count(); ++i) {
- QModelIndex idx = model->index(files.at(i));
- if (!idx.isValid())
- idx = model->index(getEnvironmentVariable(files.at(i)));
- if (!idx.isValid()) {
- enableButton = false;
- break;
- }
- if (idx.isValid() && model->isDir(idx)) {
- isOpenDirectory = true;
- break;
- }
- }
- break;
- default:
- break;
- }
- }
-
- button->setEnabled(enableButton);
- if (acceptMode == QFileDialog::AcceptSave)
- button->setText(isOpenDirectory ? QFileDialog::tr("&Open") : acceptLabel);
-}
-
-/*!
- \internal
-*/
-void QFileDialogPrivate::_q_currentChanged(const QModelIndex &index)
-{
- _q_updateOkButton();
- emit q_func()->currentChanged(index.data(QFileSystemModel::FilePathRole).toString());
-}
-
-/*!
- \internal
-
- This is called when the user double clicks on a file with the corresponding
- model item \a index.
-*/
-void QFileDialogPrivate::_q_enterDirectory(const QModelIndex &index)
-{
- Q_Q(QFileDialog);
- // My Computer or a directory
- QModelIndex sourceIndex = index.model() == proxyModel ? mapToSource(index) : 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
- || fileMode == QFileDialog::DirectoryOnly) {
- // ### find out why you have to do both of these.
- lineEdit()->setText(QString());
- lineEdit()->clear();
- }
- } else {
- q->accept();
- }
-}
-
-/*!
- \internal
-
- Changes the file dialog's current directory to the one specified
- by \a path.
-*/
-void QFileDialogPrivate::_q_goToDirectory(const QString &path)
-{
- #ifndef QT_NO_MESSAGEBOX
- Q_Q(QFileDialog);
-#endif
- QModelIndex index = qFileDialogUi->lookInCombo->model()->index(qFileDialogUi->lookInCombo->currentIndex(),
- qFileDialogUi->lookInCombo->modelColumn(),
- qFileDialogUi->lookInCombo->rootModelIndex());
- QString path2 = path;
- if (!index.isValid())
- index = mapFromSource(model->index(getEnvironmentVariable(path)));
- else {
- path2 = index.data(UrlRole).toUrl().toLocalFile();
- index = mapFromSource(model->index(path2));
- }
- QDir dir(path2);
- if (!dir.exists())
- dir = getEnvironmentVariable(path2);
-
- if (dir.exists() || path2.isEmpty() || path2 == model->myComputer().toString()) {
- _q_enterDirectory(index);
-#ifndef QT_NO_MESSAGEBOX
- } else {
- QString message = QFileDialog::tr("%1\nDirectory not found.\nPlease verify the "
- "correct directory name was given.");
- QMessageBox::warning(q, q->windowTitle(), message.arg(path2));
-#endif // QT_NO_MESSAGEBOX
- }
-}
-
-// Makes a list of filters from a normal filter string "Image Files (*.png *.jpg)"
-QStringList qt_clean_filter_list(const QString &filter)
-{
- QRegExp regexp(QString::fromLatin1(qt_file_dialog_filter_reg_exp));
- QString f = filter;
- int i = regexp.indexIn(f);
- if (i >= 0)
- f = regexp.cap(2);
- return f.split(QLatin1Char(' '), QString::SkipEmptyParts);
-}
-
-/*!
- \internal
-
- Sets the current name filter to be nameFilter and
- update the qFileDialogUi->fileNameEdit when in AcceptSave mode with the new extension.
-*/
-void QFileDialogPrivate::_q_useNameFilter(int index)
-{
- if (index == nameFilters.size()) {
- QAbstractItemModel *comboModel = qFileDialogUi->fileTypeCombo->model();
- nameFilters.append(comboModel->index(comboModel->rowCount() - 1, 0).data().toString());
- }
-
- QString nameFilter = nameFilters.at(index);
- QStringList newNameFilters = qt_clean_filter_list(nameFilter);
- if (acceptMode == QFileDialog::AcceptSave) {
- QString newNameFilterExtension;
- if (newNameFilters.count() > 0)
- newNameFilterExtension = QFileInfo(newNameFilters.at(0)).suffix();
-
- QString fileName = lineEdit()->text();
- const QString fileNameExtension = QFileInfo(fileName).suffix();
- if (!fileNameExtension.isEmpty() && !newNameFilterExtension.isEmpty()) {
- const int fileNameExtensionLength = fileNameExtension.count();
- fileName.replace(fileName.count() - fileNameExtensionLength,
- fileNameExtensionLength, newNameFilterExtension);
- qFileDialogUi->listView->clearSelection();
- lineEdit()->setText(fileName);
- }
- }
-
- model->setNameFilters(newNameFilters);
-}
-
-/*!
- \internal
-
- This is called when the model index corresponding to the current file is changed
- from \a index to \a current.
-*/
-void QFileDialogPrivate::_q_selectionChanged()
-{
- QModelIndexList indexes = qFileDialogUi->listView->selectionModel()->selectedRows();
- bool stripDirs = (fileMode != QFileDialog::DirectoryOnly && fileMode != QFileDialog::Directory);
-
- QStringList allFiles;
- for (int i = 0; i < indexes.count(); ++i) {
- if (stripDirs && model->isDir(mapToSource(indexes.at(i))))
- continue;
- allFiles.append(indexes.at(i).data().toString());
- }
- if (allFiles.count() > 1)
- for (int i = 0; i < allFiles.count(); ++i) {
- allFiles.replace(i, QString(QLatin1Char('"') + allFiles.at(i) + QLatin1Char('"')));
- }
-
- QString finalFiles = allFiles.join(QLatin1String(" "));
- if (!finalFiles.isEmpty() && !lineEdit()->hasFocus() && lineEdit()->isVisible())
- lineEdit()->setText(finalFiles);
- else
- _q_updateOkButton();
-}
-
-/*!
- \internal
-
- Includes hidden files and directories in the items displayed in the dialog.
-*/
-void QFileDialogPrivate::_q_showHidden()
-{
- Q_Q(QFileDialog);
- QDir::Filters dirFilters = q->filter();
- if (showHiddenAction->isChecked())
- dirFilters |= QDir::Hidden;
- else
- dirFilters &= ~QDir::Hidden;
- q->setFilter(dirFilters);
-}
-
-/*!
- \internal
-
- When parent is root and rows have been inserted when none was there before
- then select the first one.
-*/
-void QFileDialogPrivate::_q_rowsInserted(const QModelIndex &parent)
-{
- if (!qFileDialogUi->treeView
- || parent != qFileDialogUi->treeView->rootIndex()
- || !qFileDialogUi->treeView->selectionModel()
- || qFileDialogUi->treeView->selectionModel()->hasSelection()
- || qFileDialogUi->treeView->model()->rowCount(parent) == 0)
- return;
-}
-
-void QFileDialogPrivate::_q_fileRenamed(const QString &path, const QString oldName, const QString newName)
-{
- if (fileMode == QFileDialog::Directory || fileMode == QFileDialog::DirectoryOnly) {
- if (path == rootPath() && lineEdit()->text() == oldName)
- lineEdit()->setText(newName);
- }
-}
-
-/*!
- \internal
-
- For the list and tree view watch keys to goto parent and back in the history
-
- returns true if handled
-*/
-bool QFileDialogPrivate::itemViewKeyboardEvent(QKeyEvent *event) {
-
- Q_Q(QFileDialog);
- switch (event->key()) {
- case Qt::Key_Backspace:
- _q_navigateToParent();
- return true;
- case Qt::Key_Back:
-#ifdef QT_KEYPAD_NAVIGATION
- if (QApplication::keypadNavigationEnabled())
- return false;
-#endif
- case Qt::Key_Left:
- if (event->key() == Qt::Key_Back || event->modifiers() == Qt::AltModifier) {
- _q_navigateBackward();
- return true;
- }
- break;
- case Qt::Key_Escape:
- q->hide();
- return true;
- default:
- break;
- }
- return false;
-}
-
-QString QFileDialogPrivate::getEnvironmentVariable(const QString &string)
-{
-#ifdef Q_OS_UNIX
- if (string.size() > 1 && string.startsWith(QLatin1Char('$'))) {
- return QString::fromLocal8Bit(getenv(string.mid(1).toLatin1().constData()));
- }
-#else
- if (string.size() > 2 && string.startsWith(QLatin1Char('%')) && string.endsWith(QLatin1Char('%'))) {
- return QString::fromLocal8Bit(qgetenv(string.mid(1, string.size() - 2).toLatin1().constData()));
- }
-#endif
- return string;
-}
-
-void QFileDialogComboBox::init(QFileDialogPrivate *d_pointer) {
- d_ptr = d_pointer;
- urlModel = new QUrlModel(this);
- urlModel->showFullPath = true;
- urlModel->setFileSystemModel(d_ptr->model);
- setModel(urlModel);
-}
-
-void QFileDialogComboBox::showPopup()
-{
- if (model()->rowCount() > 1)
- QComboBox::showPopup();
-
- urlModel->setUrls(QList<QUrl>());
- QList<QUrl> list;
- QModelIndex idx = d_ptr->model->index(d_ptr->rootPath());
- while (idx.isValid()) {
- QUrl url = QUrl::fromLocalFile(idx.data(QFileSystemModel::FilePathRole).toString());
- if (url.isValid())
- list.append(url);
- idx = idx.parent();
- }
- // add "my computer"
- list.append(QUrl::fromLocalFile(QLatin1String("")));
- urlModel->addUrls(list, 0);
- idx = model()->index(model()->rowCount() - 1, 0);
-
- // append history
- QList<QUrl> urls;
- for (int i = 0; i < m_history.count(); ++i) {
- QUrl path = QUrl::fromLocalFile(m_history.at(i));
- if (!urls.contains(path))
- urls.prepend(path);
- }
- if (urls.count() > 0) {
- model()->insertRow(model()->rowCount());
- idx = model()->index(model()->rowCount()-1, 0);
- // ### TODO maybe add a horizontal line before this
- model()->setData(idx, QFileDialog::tr("Recent Places"));
- QStandardItemModel *m = qobject_cast<QStandardItemModel*>(model());
- if (m) {
- Qt::ItemFlags flags = m->flags(idx);
- flags &= ~Qt::ItemIsEnabled;
- m->item(idx.row(), idx.column())->setFlags(flags);
- }
- urlModel->addUrls(urls, -1, false);
- }
- setCurrentIndex(0);
-
- QComboBox::showPopup();
-}
-
-// Exact same as QComboBox::paintEvent(), except we elide the text.
-void QFileDialogComboBox::paintEvent(QPaintEvent *)
-{
- QStylePainter painter(this);
- painter.setPen(palette().color(QPalette::Text));
-
- // draw the combobox frame, focusrect and selected etc.
- QStyleOptionComboBox opt;
- initStyleOption(&opt);
-
- QRect editRect = style()->subControlRect(QStyle::CC_ComboBox, &opt,
- QStyle::SC_ComboBoxEditField, this);
- int size = editRect.width() - opt.iconSize.width() - 4;
- opt.currentText = opt.fontMetrics.elidedText(opt.currentText, Qt::ElideMiddle, size);
- painter.drawComplexControl(QStyle::CC_ComboBox, opt);
-
- // draw the icon and text
- painter.drawControl(QStyle::CE_ComboBoxLabel, opt);
-}
-
-QFileDialogListView::QFileDialogListView(QWidget *parent) : QListView(parent)
-{
-}
-
-void QFileDialogListView::init(QFileDialogPrivate *d_pointer)
-{
- d_ptr = d_pointer;
- setSelectionBehavior(QAbstractItemView::SelectRows);
- setWrapping(true);
- setResizeMode(QListView::Adjust);
- setEditTriggers(QAbstractItemView::EditKeyPressed);
- setContextMenuPolicy(Qt::CustomContextMenu);
-#ifndef QT_NO_DRAGANDDROP
- setDragDropMode(QAbstractItemView::InternalMove);
-#endif
-}
-
-QSize QFileDialogListView::sizeHint() const
-{
- int height = qMax(10, sizeHintForRow(0));
- return QSize(QListView::sizeHint().width() * 2, height * 30);
-}
-
-void QFileDialogListView::keyPressEvent(QKeyEvent *e)
-{
-#ifdef QT_KEYPAD_NAVIGATION
- if (QApplication::navigationMode() == Qt::NavigationModeKeypadDirectional) {
- QListView::keyPressEvent(e);
- return;
- }
-#endif // QT_KEYPAD_NAVIGATION
-
- if (!d_ptr->itemViewKeyboardEvent(e))
- QListView::keyPressEvent(e);
- e->accept();
-}
-
-QFileDialogTreeView::QFileDialogTreeView(QWidget *parent) : QTreeView(parent)
-{
-}
-
-void QFileDialogTreeView::init(QFileDialogPrivate *d_pointer)
-{
- d_ptr = d_pointer;
- setSelectionBehavior(QAbstractItemView::SelectRows);
- setRootIsDecorated(false);
- setItemsExpandable(false);
- setSortingEnabled(true);
- header()->setSortIndicator(0, Qt::AscendingOrder);
- header()->setStretchLastSection(false);
- setTextElideMode(Qt::ElideMiddle);
- setEditTriggers(QAbstractItemView::EditKeyPressed);
- setContextMenuPolicy(Qt::CustomContextMenu);
-#ifndef QT_NO_DRAGANDDROP
- setDragDropMode(QAbstractItemView::InternalMove);
-#endif
-}
-
-void QFileDialogTreeView::keyPressEvent(QKeyEvent *e)
-{
-#ifdef QT_KEYPAD_NAVIGATION
- if (QApplication::navigationMode() == Qt::NavigationModeKeypadDirectional) {
- QTreeView::keyPressEvent(e);
- return;
- }
-#endif // QT_KEYPAD_NAVIGATION
-
- if (!d_ptr->itemViewKeyboardEvent(e))
- QTreeView::keyPressEvent(e);
- e->accept();
-}
-
-QSize QFileDialogTreeView::sizeHint() const
-{
- int height = qMax(10, sizeHintForRow(0));
- QSize sizeHint = header()->sizeHint();
- return QSize(sizeHint.width() * 4, height * 30);
-}
-
-/*!
- // FIXME: this is a hack to avoid propagating key press events
- // to the dialog and from there to the "Ok" button
-*/
-void QFileDialogLineEdit::keyPressEvent(QKeyEvent *e)
-{
-#ifdef QT_KEYPAD_NAVIGATION
- if (QApplication::navigationMode() == Qt::NavigationModeKeypadDirectional) {
- QLineEdit::keyPressEvent(e);
- return;
- }
-#endif // QT_KEYPAD_NAVIGATION
-
- int key = e->key();
- QLineEdit::keyPressEvent(e);
- if (key != Qt::Key_Escape)
- e->accept();
- if (hideOnEsc && (key == Qt::Key_Escape || key == Qt::Key_Return || key == Qt::Key_Enter)) {
- e->accept();
- hide();
- d_ptr->currentView()->setFocus(Qt::ShortcutFocusReason);
- }
-}
-
-#ifndef QT_NO_FSCOMPLETER
-
-QString QFSCompleter::pathFromIndex(const QModelIndex &index) const
-{
- 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)) {
-#if defined(Q_OS_UNIX) || defined(Q_OS_WINCE)
- if (currentLocation == QDir::separator())
- return path.mid(currentLocation.length());
-#endif
- if (currentLocation.endsWith(QLatin1Char('/')))
- return path.mid(currentLocation.length());
- else
- return path.mid(currentLocation.length()+1);
- }
- return index.data(QFileSystemModel::FilePathRole).toString();
-}
-
-QStringList QFSCompleter::splitPath(const QString &path) const
-{
- if (path.isEmpty())
- return QStringList(completionPrefix());
-
- QString pathCopy = QDir::toNativeSeparators(path);
- QString sep = QDir::separator();
-#if defined(Q_OS_SYMBIAN)
- if (pathCopy == QLatin1String("\\"))
- return QStringList(pathCopy);
-#elif defined(Q_OS_WIN)
- if (pathCopy == QLatin1String("\\") || pathCopy == QLatin1String("\\\\"))
- return QStringList(pathCopy);
- QString doubleSlash(QLatin1String("\\\\"));
- if (pathCopy.startsWith(doubleSlash))
- pathCopy = pathCopy.mid(2);
- else
- doubleSlash.clear();
-#elif defined(Q_OS_UNIX)
- bool expanded;
- pathCopy = qt_tildeExpansion(pathCopy, &expanded);
- if (expanded) {
- QFileSystemModel *dirModel;
- if (proxyModel)
- dirModel = qobject_cast<QFileSystemModel *>(proxyModel->sourceModel());
- else
- dirModel = sourceModel;
- dirModel->fetchMore(dirModel->index(pathCopy));
- }
-#endif
-
- QRegExp re(QLatin1Char('[') + QRegExp::escape(sep) + QLatin1Char(']'));
-
-#if defined(Q_OS_SYMBIAN)
- QStringList parts = pathCopy.split(re, QString::SkipEmptyParts);
- if (pathCopy.endsWith(sep))
- parts.append(QString());
-#elif defined(Q_OS_WIN)
- QStringList parts = pathCopy.split(re, QString::SkipEmptyParts);
- if (!doubleSlash.isEmpty() && !parts.isEmpty())
- parts[0].prepend(doubleSlash);
- if (pathCopy.endsWith(sep))
- parts.append(QString());
-#else
- QStringList parts = pathCopy.split(re);
- if (pathCopy[0] == sep[0]) // read the "/" at the beginning as the split removed it
- parts[0] = sep[0];
-#endif
-
-#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
- bool startsFromRoot = !parts.isEmpty() && parts[0].endsWith(QLatin1Char(':'));
-#else
- bool startsFromRoot = pathCopy[0] == sep[0];
-#endif
- if (parts.count() == 1 || (parts.count() > 1 && !startsFromRoot)) {
- const QFileSystemModel *dirModel;
- if (proxyModel)
- dirModel = qobject_cast<const QFileSystemModel *>(proxyModel->sourceModel());
- else
- dirModel = sourceModel;
- QString currentLocation = QDir::toNativeSeparators(dirModel->rootPath());
-#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
- if (currentLocation.endsWith(QLatin1Char(':')))
- currentLocation.append(sep);
-#endif
- if (currentLocation.contains(sep) && path != currentLocation) {
- QStringList currentLocationList = splitPath(currentLocation);
- while (!currentLocationList.isEmpty()
- && parts.count() > 0
- && parts.at(0) == QLatin1String("..")) {
- parts.removeFirst();
- currentLocationList.removeLast();
- }
- if (!currentLocationList.isEmpty() && currentLocationList.last().isEmpty())
- currentLocationList.removeLast();
- return currentLocationList + parts;
- }
- }
- return parts;
-}
-
-#endif // QT_NO_COMPLETER
-
-#ifdef QT3_SUPPORT
-/*!
- Use selectedFiles() instead.
-
- \oldcode
- QString selected = dialog->selectedFile();
- \newcode
- QStringList files = dialog->selectedFiles();
- QString selected;
- if (!files.isEmpty())
- selected = files[0];
- \endcode
-*/
-QString QFileDialog::selectedFile() const
-{
- QStringList files = selectedFiles();
- return files.size() ? files.at(0) : QString();
-}
-
-/*!
- \typedef QFileDialog::Mode
-
- Use QFileDialog::FileMode instead.
-*/
-
-/*!
- \fn void QFileDialog::setMode(FileMode m)
-
- Use setFileMode() instead.
-*/
-
-/*!
- \fn FileMode QFileDialog::mode() const
-
- Use fileMode() instead.
-*/
-
-/*!
- \fn void QFileDialog::setDir(const QString &directory)
-
- Use setDirectory() instead.
-*/
-
-/*!
- \fn void QFileDialog::setDir( const QDir &directory )
-
- Use setDirectory() instead.
-*/
-
-/*!
- \fn QStringList QFileDialog::getOpenFileNames(const QString &filter,
- const QString &dir, QWidget *parent, const char* name,
- const QString &caption, QString *selectedFilter, bool resolveSymlinks)
-
- Use the getOpenFileNames() overload that takes \a parent as the first
- argument instead.
-*/
-
-/*!
- \fn QString QFileDialog::getOpenFileName(const QString &dir,
- const QString &filter, QWidget *parent = 0, const char *name,
- const QString &caption, QString *selectedFilter, bool resolveSymlinks)
-
- Use the getOpenFileName() overload that takes \a parent as the first
- argument instead.
-*/
-
-/*!
- \fn QString QFileDialog::getSaveFileName(const QString &dir,
- const QString &filter, QWidget *parent, const char *name,
- const QString &caption, QString *selectedFilter, bool resolveSymlinks)
-
- Use the getSaveFileName() overload that takes \a parent as the first
- argument instead.
-*/
-
-/*!
- \fn QString QFileDialog::getExistingDirectory(const QString &dir,
- QWidget *parent, const char *name, const QString &caption,
- bool dirOnly, bool resolveSymlinks)
-
- Use the getExistingDirectory() overload that takes \a parent as
- the first argument instead.
-*/
-
-#endif // QT3_SUPPORT
-
-QT_END_NAMESPACE
-
-#include "moc_qfiledialog.cpp"
-
-#endif // QT_NO_FILEDIALOG
diff --git a/src/gui/dialogs/qfiledialog.h b/src/gui/dialogs/qfiledialog.h
deleted file mode 100644
index a0001907ae..0000000000
--- a/src/gui/dialogs/qfiledialog.h
+++ /dev/null
@@ -1,331 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QFILEDIALOG_H
-#define QFILEDIALOG_H
-
-#include <QtCore/qdir.h>
-#include <QtCore/qstring.h>
-#include <QtGui/qdialog.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_FILEDIALOG
-
-class QModelIndex;
-class QItemSelection;
-struct QFileDialogArgs;
-class QFileIconProvider;
-class QFileDialogPrivate;
-class QAbstractItemDelegate;
-class QAbstractProxyModel;
-class QUrl;
-
-class Q_GUI_EXPORT QFileDialog : public QDialog
-{
- Q_OBJECT
- Q_ENUMS(ViewMode FileMode AcceptMode Option)
- Q_FLAGS(Options)
- Q_PROPERTY(ViewMode viewMode READ viewMode WRITE setViewMode)
- Q_PROPERTY(FileMode fileMode READ fileMode WRITE setFileMode)
- Q_PROPERTY(AcceptMode acceptMode READ acceptMode WRITE setAcceptMode)
- Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly DESIGNABLE false)
- Q_PROPERTY(bool resolveSymlinks READ resolveSymlinks WRITE setResolveSymlinks DESIGNABLE false)
- Q_PROPERTY(bool confirmOverwrite READ confirmOverwrite WRITE setConfirmOverwrite DESIGNABLE false)
- Q_PROPERTY(QString defaultSuffix READ defaultSuffix WRITE setDefaultSuffix)
- Q_PROPERTY(bool nameFilterDetailsVisible READ isNameFilterDetailsVisible
- WRITE setNameFilterDetailsVisible DESIGNABLE false)
- Q_PROPERTY(Options options READ options WRITE setOptions)
-
-public:
- enum ViewMode { Detail, List };
- enum FileMode { AnyFile, ExistingFile, Directory, ExistingFiles, DirectoryOnly };
- enum AcceptMode { AcceptOpen, AcceptSave };
- enum DialogLabel { LookIn, FileName, FileType, Accept, Reject };
-
- // ### Rename to FileDialogOption and FileDialogOptions for Qt 5.0
- enum Option
- {
- ShowDirsOnly = 0x00000001,
- DontResolveSymlinks = 0x00000002,
- DontConfirmOverwrite = 0x00000004,
- DontUseSheet = 0x00000008,
- DontUseNativeDialog = 0x00000010,
- ReadOnly = 0x00000020,
- HideNameFilterDetails = 0x00000040
- };
- Q_DECLARE_FLAGS(Options, Option)
-
- QFileDialog(QWidget *parent, Qt::WindowFlags f);
- explicit QFileDialog(QWidget *parent = 0,
- const QString &caption = QString(),
- const QString &directory = QString(),
- const QString &filter = QString());
- ~QFileDialog();
-
- void setDirectory(const QString &directory);
- inline void setDirectory(const QDir &directory);
- QDir directory() const;
-
- void selectFile(const QString &filename);
- QStringList selectedFiles() const;
-
-#ifdef QT_DEPRECATED
- QT_DEPRECATED void setFilter(const QString &filter);
- QT_DEPRECATED void setFilters(const QStringList &filters);
- QT_DEPRECATED QStringList filters() const;
- QT_DEPRECATED void selectFilter(const QString &filter);
- QT_DEPRECATED QString selectedFilter() const;
-#endif
- void setNameFilterDetailsVisible(bool enabled);
- bool isNameFilterDetailsVisible() const;
-
- void setNameFilter(const QString &filter);
- void setNameFilters(const QStringList &filters);
- QStringList nameFilters() const;
- void selectNameFilter(const QString &filter);
- QString selectedNameFilter() const;
-
- QDir::Filters filter() const;
- void setFilter(QDir::Filters filters);
-
- void setViewMode(ViewMode mode);
- ViewMode viewMode() const;
-
- void setFileMode(FileMode mode);
- FileMode fileMode() const;
-
- void setAcceptMode(AcceptMode mode);
- AcceptMode acceptMode() const;
-
- void setReadOnly(bool enabled);
- bool isReadOnly() const;
-
- void setResolveSymlinks(bool enabled);
- bool resolveSymlinks() const;
-
- void setSidebarUrls(const QList<QUrl> &urls);
- QList<QUrl> sidebarUrls() const;
-
- QByteArray saveState() const;
- bool restoreState(const QByteArray &state);
-
- void setConfirmOverwrite(bool enabled);
- bool confirmOverwrite() const;
-
- void setDefaultSuffix(const QString &suffix);
- QString defaultSuffix() const;
-
- void setHistory(const QStringList &paths);
- QStringList history() const;
-
- void setItemDelegate(QAbstractItemDelegate *delegate);
- QAbstractItemDelegate *itemDelegate() const;
-
- void setIconProvider(QFileIconProvider *provider);
- QFileIconProvider *iconProvider() const;
-
- void setLabelText(DialogLabel label, const QString &text);
- QString labelText(DialogLabel label) const;
-
-#ifndef QT_NO_PROXYMODEL
- void setProxyModel(QAbstractProxyModel *model);
- QAbstractProxyModel *proxyModel() const;
-#endif
-
- void setOption(Option option, bool on = true);
- bool testOption(Option option) const;
- void setOptions(Options options);
- Options options() const;
-
-#ifdef Q_NO_USING_KEYWORD
-#ifndef Q_QDOC
- void open() { QDialog::open(); }
-#endif
-#else
- using QDialog::open;
-#endif
- void open(QObject *receiver, const char *member);
- void setVisible(bool visible);
-
-Q_SIGNALS:
- void fileSelected(const QString &file);
- void filesSelected(const QStringList &files);
- void currentChanged(const QString &path);
- void directoryEntered(const QString &directory);
- void filterSelected(const QString &filter);
-
-public:
-#ifdef QT3_SUPPORT
- typedef FileMode Mode;
- inline QT3_SUPPORT void setMode(FileMode m) { setFileMode(m); }
- inline QT3_SUPPORT FileMode mode() const { return fileMode(); }
- inline QT3_SUPPORT void setDir(const QString &directory) { setDirectory(directory); }
- inline QT3_SUPPORT void setDir( const QDir &directory ) { setDirectory(directory); }
- QT3_SUPPORT QString selectedFile() const;
-#endif
-
- static QString getOpenFileName(QWidget *parent = 0,
- const QString &caption = QString(),
- const QString &dir = QString(),
- const QString &filter = QString(),
- QString *selectedFilter = 0,
- Options options = 0);
-
- static QString getSaveFileName(QWidget *parent = 0,
- const QString &caption = QString(),
- const QString &dir = QString(),
- const QString &filter = QString(),
- QString *selectedFilter = 0,
- Options options = 0);
-
- static QString getExistingDirectory(QWidget *parent = 0,
- const QString &caption = QString(),
- const QString &dir = QString(),
- Options options = ShowDirsOnly);
-
- static QStringList getOpenFileNames(QWidget *parent = 0,
- const QString &caption = QString(),
- const QString &dir = QString(),
- const QString &filter = QString(),
- QString *selectedFilter = 0,
- Options options = 0);
-
-#ifdef QT3_SUPPORT
- inline static QString QT3_SUPPORT getOpenFileName(const QString &dir,
- const QString &filter = QString(),
- QWidget *parent = 0, const char* name = 0,
- const QString &caption = QString(),
- QString *selectedFilter = 0,
- bool resolveSymlinks = true)
- { Q_UNUSED(name);
- return getOpenFileName(parent, caption, dir, filter, selectedFilter,
- resolveSymlinks ? Option(0) : DontResolveSymlinks); }
-
- inline static QString QT3_SUPPORT getSaveFileName(const QString &dir,
- const QString &filter = QString(),
- QWidget *parent = 0, const char* name = 0,
- const QString &caption = QString(),
- QString *selectedFilter = 0,
- bool resolveSymlinks = true)
- { Q_UNUSED(name);
- return getSaveFileName(parent, caption, dir, filter, selectedFilter,
- resolveSymlinks ? Option(0) : DontResolveSymlinks); }
-
- inline static QString QT3_SUPPORT getExistingDirectory(const QString &dir,
- QWidget *parent = 0,
- const char* name = 0,
- const QString &caption = QString(),
- bool dirOnly = true,
- bool resolveSymlinks = true)
- { Q_UNUSED(name);
- return getExistingDirectory(parent, caption, dir,
- Options((resolveSymlinks ? Option(0) : DontResolveSymlinks)
- | (dirOnly ? ShowDirsOnly : Option(0)))); }
-
- inline static QStringList QT3_SUPPORT getOpenFileNames(const QString &filter,
- const QString &dir = QString(),
- QWidget *parent = 0,
- const char* name = 0,
- const QString &caption = QString(),
- QString *selectedFilter = 0,
- bool resolveSymlinks = true)
- { Q_UNUSED(name);
- return getOpenFileNames(parent, caption, dir, filter, selectedFilter,
- resolveSymlinks ? Option(0) : DontResolveSymlinks); }
-#endif // QT3_SUPPORT
-
-protected:
- QFileDialog(const QFileDialogArgs &args);
- void done(int result);
- void accept();
- void changeEvent(QEvent *e);
-
-private:
- Q_DECLARE_PRIVATE(QFileDialog)
- Q_DISABLE_COPY(QFileDialog)
-
- Q_PRIVATE_SLOT(d_func(), void _q_pathChanged(const QString &))
-
- Q_PRIVATE_SLOT(d_func(), void _q_navigateBackward())
- Q_PRIVATE_SLOT(d_func(), void _q_navigateForward())
- Q_PRIVATE_SLOT(d_func(), void _q_navigateToParent())
- Q_PRIVATE_SLOT(d_func(), void _q_createDirectory())
- Q_PRIVATE_SLOT(d_func(), void _q_showListView())
- Q_PRIVATE_SLOT(d_func(), void _q_showDetailsView())
- Q_PRIVATE_SLOT(d_func(), void _q_showContextMenu(const QPoint &))
- Q_PRIVATE_SLOT(d_func(), void _q_renameCurrent())
- Q_PRIVATE_SLOT(d_func(), void _q_deleteCurrent())
- Q_PRIVATE_SLOT(d_func(), void _q_showHidden())
- Q_PRIVATE_SLOT(d_func(), void _q_updateOkButton())
- Q_PRIVATE_SLOT(d_func(), void _q_currentChanged(const QModelIndex &index))
- Q_PRIVATE_SLOT(d_func(), void _q_enterDirectory(const QModelIndex &index))
- Q_PRIVATE_SLOT(d_func(), void _q_goToDirectory(const QString &path))
- Q_PRIVATE_SLOT(d_func(), void _q_useNameFilter(int index))
- Q_PRIVATE_SLOT(d_func(), void _q_selectionChanged())
- Q_PRIVATE_SLOT(d_func(), void _q_goToUrl(const QUrl &url))
- Q_PRIVATE_SLOT(d_func(), void _q_goHome())
- Q_PRIVATE_SLOT(d_func(), void _q_showHeader(QAction *))
- Q_PRIVATE_SLOT(d_func(), void _q_autoCompleteFileName(const QString &text))
- Q_PRIVATE_SLOT(d_func(), void _q_rowsInserted(const QModelIndex & parent))
- Q_PRIVATE_SLOT(d_func(), void _q_fileRenamed(const QString &path,
- const QString oldName, const QString newName))
-#if defined(Q_WS_MAC)
- Q_PRIVATE_SLOT(d_func(), void _q_macRunNativeAppModalPanel())
-#endif
-};
-
-inline void QFileDialog::setDirectory(const QDir &adirectory)
-{ setDirectory(adirectory.absolutePath()); }
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QFileDialog::Options)
-
-#endif // QT_NO_FILEDIALOG
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QFILEDIALOG_H
diff --git a/src/gui/dialogs/qfiledialog_win.cpp b/src/gui/dialogs/qfiledialog_win.cpp
deleted file mode 100644
index de8e33d897..0000000000
--- a/src/gui/dialogs/qfiledialog_win.cpp
+++ /dev/null
@@ -1,825 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qfiledialog.h"
-
-#ifndef QT_NO_FILEDIALOG
-
-#include <private/qfiledialog_p.h>
-#include <qapplication.h>
-#include <private/qapplication_p.h>
-#include <qt_windows.h>
-#include <qglobal.h>
-#include <qregexp.h>
-#include <qbuffer.h>
-#include <qdir.h>
-#include <qstringlist.h>
-#include <private/qsystemlibrary_p.h>
-#include "qfiledialog_win_p.h"
-
-#ifndef QT_NO_THREAD
-# include <private/qmutexpool_p.h>
-#endif
-
-#ifdef Q_WS_WINCE
-#include <commdlg.h>
-bool qt_priv_ptr_valid = false;
-#else
-//we have to declare them here because they're not present for all SDK/compilers
-static const IID QT_IID_IFileOpenDialog = {0xd57c7288, 0xd4ad, 0x4768, {0xbe, 0x02, 0x9d, 0x96, 0x95, 0x32, 0xd9, 0x60} };
-static const IID QT_IID_IShellItem = {0x43826d1e, 0xe718, 0x42ee, {0xbc, 0x55, 0xa1, 0xe2, 0x61, 0xc3, 0x7b, 0xfe} };
-static const CLSID QT_CLSID_FileOpenDialog = {0xdc1c5a9c, 0xe88a, 0x4dde, {0xa5, 0xa1, 0x60, 0xf8, 0x2a, 0x20, 0xae, 0xf7} };
-#endif
-
-
-typedef qt_LPITEMIDLIST (WINAPI *PtrSHBrowseForFolder)(qt_BROWSEINFO*);
-static PtrSHBrowseForFolder ptrSHBrowseForFolder = 0;
-typedef BOOL (WINAPI *PtrSHGetPathFromIDList)(qt_LPITEMIDLIST, LPWSTR);
-static PtrSHGetPathFromIDList ptrSHGetPathFromIDList = 0;
-typedef HRESULT (WINAPI *PtrSHGetMalloc)(LPMALLOC *);
-static PtrSHGetMalloc ptrSHGetMalloc = 0;
-
-
-QT_BEGIN_NAMESPACE
-
-static void qt_win_resolve_libs()
-{
- static bool triedResolve = false;
-
- if (!triedResolve) {
-#ifndef QT_NO_THREAD
- // protect initialization
- QMutexLocker locker(QMutexPool::globalInstanceGet(&triedResolve));
- // check triedResolve again, since another thread may have already
- // done the initialization
- if (triedResolve) {
- // another thread did initialize the security function pointers,
- // so we shouldn't do it again.
- return;
- }
-#endif
-
- triedResolve = true;
-#if !defined(Q_WS_WINCE)
- QSystemLibrary lib(L"shell32");
- ptrSHBrowseForFolder = (PtrSHBrowseForFolder)lib.resolve("SHBrowseForFolderW");
- ptrSHGetPathFromIDList = (PtrSHGetPathFromIDList)lib.resolve("SHGetPathFromIDListW");
- ptrSHGetMalloc = (PtrSHGetMalloc)lib.resolve("SHGetMalloc");
-#else
- // CE stores them in a different lib and does not use unicode version
- HINSTANCE handle = LoadLibrary(L"Ceshell");
- ptrSHBrowseForFolder = (PtrSHBrowseForFolder)GetProcAddress(handle, L"SHBrowseForFolder");
- ptrSHGetPathFromIDList = (PtrSHGetPathFromIDList)GetProcAddress(handle, L"SHGetPathFromIDList");
- ptrSHGetMalloc = (PtrSHGetMalloc)GetProcAddress(handle, L"SHGetMalloc");
- if (ptrSHBrowseForFolder && ptrSHGetPathFromIDList && ptrSHGetMalloc)
- qt_priv_ptr_valid = true;
-#endif
- }
-}
-
-extern const char* qt_file_dialog_filter_reg_exp; // defined in qfiledialog.cpp
-extern QStringList qt_make_filter_list(const QString &filter);
-
-const int maxNameLen = 1023;
-const int maxMultiLen = 65535;
-
-// Returns the wildcard part of a filter.
-static QString qt_win_extract_filter(const QString &rawFilter)
-{
- QString result = rawFilter;
- QRegExp r(QString::fromLatin1(qt_file_dialog_filter_reg_exp));
- int index = r.indexIn(result);
- if (index >= 0)
- result = r.cap(2);
- QStringList list = result.split(QLatin1Char(' '));
- for(QStringList::iterator it = list.begin(); it < list.end(); ++it) {
- if (*it == QLatin1String("*")) {
- *it = QLatin1String("*.*");
- break;
- }
- }
- return list.join(QLatin1String(";"));
-}
-
-static QStringList qt_win_make_filters_list(const QString &filter)
-{
- QString f(filter);
-
- if (f.isEmpty())
- f = QFileDialog::tr("All Files (*.*)");
-
- return qt_make_filter_list(f);
-}
-
-// Makes a NUL-oriented Windows filter from a Qt filter.
-static QString qt_win_filter(const QString &filter, bool hideFiltersDetails)
-{
- QStringList filterLst = qt_win_make_filters_list(filter);
- QStringList::Iterator it = filterLst.begin();
- QString winfilters;
- QRegExp r(QString::fromLatin1(qt_file_dialog_filter_reg_exp));
- for (; it != filterLst.end(); ++it) {
- QString subfilter = *it;
- if (!subfilter.isEmpty()) {
- if (hideFiltersDetails) {
- int index = r.indexIn(subfilter);
- if (index >= 0)
- winfilters += r.cap(1);
- } else {
- winfilters += subfilter;
- }
- winfilters += QChar();
- winfilters += qt_win_extract_filter(subfilter);
- winfilters += QChar();
- }
- }
- winfilters += QChar();
- return winfilters;
-}
-
-static QString qt_win_selected_filter(const QString &filter, DWORD idx)
-{
- return qt_win_make_filters_list(filter).at((int)idx - 1);
-}
-
-static QString tFilters, tTitle, tInitDir;
-
-static OPENFILENAME* qt_win_make_OFN(QWidget *parent,
- const QString& initialSelection,
- const QString& initialDirectory,
- const QString& title,
- const QString& filters,
- QFileDialog::FileMode mode,
- QFileDialog::Options options)
-{
- if (parent)
- parent = parent->window();
- else
- parent = QApplication::activeWindow();
-
- tInitDir = QDir::toNativeSeparators(initialDirectory);
- tFilters = filters;
- tTitle = title;
- QString initSel = QDir::toNativeSeparators(initialSelection);
- if (!initSel.isEmpty()) {
- initSel.remove(QLatin1Char('<'));
- initSel.remove(QLatin1Char('>'));
- initSel.remove(QLatin1Char('\"'));
- initSel.remove(QLatin1Char('|'));
- }
-
- int maxLen = mode == QFileDialog::ExistingFiles ? maxMultiLen : maxNameLen;
- wchar_t *tInitSel = new wchar_t[maxLen + 1];
- if (initSel.length() > 0 && initSel.length() <= maxLen)
- memcpy(tInitSel, initSel.utf16(), (initSel.length()+1)*sizeof(QChar));
- else
- tInitSel[0] = 0;
-
- OPENFILENAME* ofn = new OPENFILENAME;
- memset(ofn, 0, sizeof(OPENFILENAME));
-
- ofn->lStructSize = sizeof(OPENFILENAME);
- ofn->hwndOwner = parent ? parent->winId() : 0;
- ofn->lpstrFilter = (wchar_t*)tFilters.utf16();
- ofn->lpstrFile = tInitSel;
- ofn->nMaxFile = maxLen;
- ofn->lpstrInitialDir = (wchar_t*)tInitDir.utf16();
- ofn->lpstrTitle = (wchar_t*)tTitle.utf16();
- ofn->Flags = (OFN_NOCHANGEDIR | OFN_HIDEREADONLY | OFN_EXPLORER | OFN_PATHMUSTEXIST);
- if (mode == QFileDialog::ExistingFile ||
- mode == QFileDialog::ExistingFiles)
- ofn->Flags |= (OFN_FILEMUSTEXIST);
- if (mode == QFileDialog::ExistingFiles)
- ofn->Flags |= (OFN_ALLOWMULTISELECT);
- if (!(options & QFileDialog::DontConfirmOverwrite))
- ofn->Flags |= OFN_OVERWRITEPROMPT;
-
- return ofn;
-}
-
-static void qt_win_clean_up_OFN(OPENFILENAME **ofn)
-{
- delete [] (*ofn)->lpstrFile;
- delete *ofn;
- *ofn = 0;
-}
-
-extern void qt_win_eatMouseMove();
-
-QString qt_win_get_open_file_name(const QFileDialogArgs &args,
- QString *initialDirectory,
- QString *selectedFilter)
-{
- QString result;
-
- QString isel = args.selection;
-
- if (initialDirectory && initialDirectory->left(5) == QLatin1String("file:"))
- initialDirectory->remove(0, 5);
- QFileInfo fi(*initialDirectory);
-
- if (initialDirectory && !fi.isDir()) {
- *initialDirectory = fi.absolutePath();
- if (isel.isEmpty())
- isel = fi.fileName();
- }
-
- if (!fi.exists())
- *initialDirectory = QDir::homePath();
-
- DWORD selFilIdx = 0;
-
- int idx = 0;
- if (selectedFilter) {
- QStringList filterLst = qt_win_make_filters_list(args.filter);
- idx = filterLst.indexOf(*selectedFilter);
- }
-
- QDialog modal_widget;
- modal_widget.setAttribute(Qt::WA_NoChildEventsForParent, true);
- modal_widget.setParent(args.parent, Qt::Window);
- QApplicationPrivate::enterModal(&modal_widget);
-
- bool hideFiltersDetails = args.options & QFileDialog::HideNameFilterDetails;
- OPENFILENAME* ofn = qt_win_make_OFN(args.parent, args.selection,
- args.directory, args.caption,
- qt_win_filter(args.filter, hideFiltersDetails),
- QFileDialog::ExistingFile,
- args.options);
- if (idx)
- ofn->nFilterIndex = idx + 1;
- if (GetOpenFileName(ofn)) {
- result = QString::fromWCharArray(ofn->lpstrFile);
- selFilIdx = ofn->nFilterIndex;
- }
- qt_win_clean_up_OFN(&ofn);
-
- QApplicationPrivate::leaveModal(&modal_widget);
-
- qt_win_eatMouseMove();
-
- if (result.isEmpty())
- return result;
-
- fi = result;
- *initialDirectory = fi.path();
- if (selectedFilter)
- *selectedFilter = qt_win_selected_filter(args.filter, selFilIdx);
- return fi.absoluteFilePath();
-}
-
-QString qt_win_get_save_file_name(const QFileDialogArgs &args,
- QString *initialDirectory,
- QString *selectedFilter)
-{
- QString result;
-
- QString isel = args.selection;
- if (initialDirectory && initialDirectory->left(5) == QLatin1String("file:"))
- initialDirectory->remove(0, 5);
- QFileInfo fi(*initialDirectory);
-
- if (initialDirectory && !fi.isDir()) {
- *initialDirectory = fi.absolutePath();
- if (isel.isEmpty())
- isel = fi.fileName();
- }
-
- if (!fi.exists())
- *initialDirectory = QDir::homePath();
-
- DWORD selFilIdx = 0;
-
- int idx = 0;
- if (selectedFilter) {
- QStringList filterLst = qt_win_make_filters_list(args.filter);
- idx = filterLst.indexOf(*selectedFilter);
- }
-
- QDialog modal_widget;
- modal_widget.setAttribute(Qt::WA_NoChildEventsForParent, true);
- modal_widget.setParent(args.parent, Qt::Window);
- QApplicationPrivate::enterModal(&modal_widget);
- bool hideFiltersDetails = args.options & QFileDialog::HideNameFilterDetails;
- // This block is used below for the lpstrDefExt member.
- // Note that the current MSDN docs document this member wrong.
- // It should rather be documented as "the default extension if no extension was given and if the
- // current filter does not have a extension (e.g (*)). If the current filter have an extension, use
- // the extension of the current filter"
- QString defaultSaveExt;
- if (selectedFilter && !selectedFilter->isEmpty()) {
- defaultSaveExt = qt_win_extract_filter(*selectedFilter);
- // make sure we only have the extension
- int firstDot = defaultSaveExt.indexOf(QLatin1Char('.'));
- if (firstDot != -1) {
- defaultSaveExt.remove(0, firstDot + 1);
- } else {
- defaultSaveExt.clear();
- }
- }
-
- OPENFILENAME *ofn = qt_win_make_OFN(args.parent, args.selection,
- args.directory, args.caption,
- qt_win_filter(args.filter, hideFiltersDetails),
- QFileDialog::AnyFile,
- args.options);
-
- ofn->lpstrDefExt = (wchar_t*)defaultSaveExt.utf16();
-
- if (idx)
- ofn->nFilterIndex = idx + 1;
- if (GetSaveFileName(ofn)) {
- result = QString::fromWCharArray(ofn->lpstrFile);
- selFilIdx = ofn->nFilterIndex;
- }
- qt_win_clean_up_OFN(&ofn);
-
-#if defined(Q_WS_WINCE)
- int semIndex = result.indexOf(QLatin1Char(';'));
- if (semIndex >= 0)
- result = result.left(semIndex);
-#endif
-
- QApplicationPrivate::leaveModal(&modal_widget);
-
- qt_win_eatMouseMove();
-
- if (result.isEmpty())
- return result;
-
- fi = result;
- *initialDirectory = fi.path();
- if (selectedFilter)
- *selectedFilter = qt_win_selected_filter(args.filter, selFilIdx);
- return fi.absoluteFilePath();
-}
-
-
-#ifndef Q_WS_WINCE
-
-typedef HRESULT (WINAPI *PtrSHCreateItemFromParsingName)(PCWSTR pszPath, IBindCtx *pbc, REFIID riid, void **ppv);
-static PtrSHCreateItemFromParsingName pSHCreateItemFromParsingName = 0;
-
-static bool qt_win_set_IFileDialogOptions(IFileDialog *pfd,
- const QString& initialSelection,
- const QString& initialDirectory,
- const QString& title,
- const QStringList& filterLst,
- QFileDialog::FileMode mode,
- QFileDialog::Options options)
-{
- if (!pSHCreateItemFromParsingName) {
- // This function is available only in Vista & above.
- QSystemLibrary shellLib(QLatin1String("Shell32"));
- pSHCreateItemFromParsingName = (PtrSHCreateItemFromParsingName)
- shellLib.resolve("SHCreateItemFromParsingName");
- if (!pSHCreateItemFromParsingName)
- return false;
- }
- HRESULT hr;
- QString winfilters;
- int numFilters = 0;
- quint32 currentOffset = 0;
- QList<quint32> offsets;
- QStringList::ConstIterator it = filterLst.begin();
- // Create the native filter string and save offset to each entry.
- for (; it != filterLst.end(); ++it) {
- QString subfilter = *it;
- if (!subfilter.isEmpty()) {
- offsets<<currentOffset;
- //Here the COMMON_ITEM_DIALOG API always add the details for the filter (e.g. *.txt)
- //so we don't need to handle the flag HideNameFilterDetails.
- winfilters += subfilter; // The name of the filter.
- winfilters += QChar();
- currentOffset += subfilter.size()+1;
- offsets<<currentOffset;
- QString spec = qt_win_extract_filter(subfilter);
- winfilters += spec; // The actual filter spec.
- winfilters += QChar();
- currentOffset += spec.size()+1;
- numFilters++;
- }
- }
- // Add the filters to the file dialog.
- if (numFilters) {
- wchar_t *szData = (wchar_t*)winfilters.utf16();
- qt_COMDLG_FILTERSPEC *filterSpec = new qt_COMDLG_FILTERSPEC[numFilters];
- for(int i = 0; i<numFilters; i++) {
- filterSpec[i].pszName = szData+offsets[i*2];
- filterSpec[i].pszSpec = szData+offsets[(i*2)+1];
- }
- hr = pfd->SetFileTypes(numFilters, filterSpec);
- delete []filterSpec;
- }
- // Set the starting folder.
- tInitDir = QDir::toNativeSeparators(initialDirectory);
- if (!tInitDir.isEmpty()) {
- IShellItem *psiDefaultFolder;
- hr = pSHCreateItemFromParsingName((wchar_t*)tInitDir.utf16(), NULL, QT_IID_IShellItem,
- reinterpret_cast<void**>(&psiDefaultFolder));
-
- if (SUCCEEDED(hr)) {
- hr = pfd->SetFolder(psiDefaultFolder);
- psiDefaultFolder->Release();
- }
- }
- // Set the currently selected file.
- QString initSel = QDir::toNativeSeparators(initialSelection);
- if (!initSel.isEmpty()) {
- initSel.remove(QLatin1Char('<'));
- initSel.remove(QLatin1Char('>'));
- initSel.remove(QLatin1Char('\"'));
- initSel.remove(QLatin1Char('|'));
- }
- if (!initSel.isEmpty()) {
- hr = pfd->SetFileName((wchar_t*)initSel.utf16());
- }
- // Set the title for the file dialog.
- if (!title.isEmpty()) {
- hr = pfd->SetTitle((wchar_t*)title.utf16());
- }
- // Set other flags for the dialog.
- DWORD newOptions;
- hr = pfd->GetOptions(&newOptions);
- if (SUCCEEDED(hr)) {
- newOptions |= FOS_NOCHANGEDIR;
- if (mode == QFileDialog::ExistingFile ||
- mode == QFileDialog::ExistingFiles)
- newOptions |= (FOS_FILEMUSTEXIST | FOS_PATHMUSTEXIST);
- if (mode == QFileDialog::ExistingFiles)
- newOptions |= FOS_ALLOWMULTISELECT;
- if (!(options & QFileDialog::DontConfirmOverwrite))
- newOptions |= FOS_OVERWRITEPROMPT;
- hr = pfd->SetOptions(newOptions);
- }
- return SUCCEEDED(hr);
-}
-
-static QStringList qt_win_CID_get_open_file_names(const QFileDialogArgs &args,
- QString *initialDirectory,
- const QStringList &filterList,
- QString *selectedFilter,
- int selectedFilterIndex)
-{
- QStringList result;
- QDialog modal_widget;
- modal_widget.setAttribute(Qt::WA_NoChildEventsForParent, true);
- modal_widget.setParent(args.parent, Qt::Window);
- QApplicationPrivate::enterModal(&modal_widget);
- // Multiple selection is allowed only in IFileOpenDialog.
- IFileOpenDialog *pfd = 0;
- HRESULT hr = CoCreateInstance(QT_CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER, QT_IID_IFileOpenDialog,
- reinterpret_cast<void**>(&pfd));
-
- if (SUCCEEDED(hr)) {
- qt_win_set_IFileDialogOptions(pfd, args.selection,
- args.directory, args.caption,
- filterList, QFileDialog::ExistingFiles,
- args.options);
- // Set the currently selected filter (one-based index).
- hr = pfd->SetFileTypeIndex(selectedFilterIndex+1);
- QWidget *parentWindow = args.parent;
- if (parentWindow)
- parentWindow = parentWindow->window();
- else
- parentWindow = QApplication::activeWindow();
- // Show the file dialog.
- hr = pfd->Show(parentWindow ? parentWindow->winId() : 0);
- if (SUCCEEDED(hr)) {
- // Retrieve the results.
- IShellItemArray *psiaResults;
- hr = pfd->GetResults(&psiaResults);
- if (SUCCEEDED(hr)) {
- DWORD numItems = 0;
- psiaResults->GetCount(&numItems);
- for (DWORD i = 0; i<numItems; i++) {
- IShellItem *psi = 0;
- hr = psiaResults->GetItemAt(i, &psi);
- if (SUCCEEDED(hr)) {
- // Retrieve the file name from shell item.
- wchar_t *pszPath;
- hr = psi->GetDisplayName(SIGDN_FILESYSPATH, &pszPath);
- if (SUCCEEDED(hr)) {
- QString fileName = QString::fromWCharArray(pszPath);
- result.append(fileName);
- CoTaskMemFree(pszPath);
- }
- psi->Release(); // Free the current item.
- }
- }
- psiaResults->Release(); // Free the array of items.
- }
- }
- }
- QApplicationPrivate::leaveModal(&modal_widget);
-
- qt_win_eatMouseMove();
-
- if (!result.isEmpty()) {
- // Retrieve the current folder name.
- IShellItem *psi = 0;
- hr = pfd->GetFolder(&psi);
- if (SUCCEEDED(hr)) {
- wchar_t *pszPath;
- hr = psi->GetDisplayName(SIGDN_FILESYSPATH, &pszPath);
- if (SUCCEEDED(hr)) {
- *initialDirectory = QString::fromWCharArray(pszPath);
- CoTaskMemFree(pszPath);
- }
- psi->Release();
- }
- // Retrieve the currently selected filter.
- if (selectedFilter) {
- quint32 filetype = 0;
- hr = pfd->GetFileTypeIndex(&filetype);
- if (SUCCEEDED(hr) && filetype && filetype <= (quint32)filterList.length()) {
- // This is a one-based index, not zero-based.
- *selectedFilter = filterList[filetype-1];
- }
- }
- }
- if (pfd)
- pfd->Release();
- return result;
-}
-
-QString qt_win_CID_get_existing_directory(const QFileDialogArgs &args)
-{
- QString result;
- QDialog modal_widget;
- modal_widget.setAttribute(Qt::WA_NoChildEventsForParent, true);
- modal_widget.setParent(args.parent, Qt::Window);
- QApplicationPrivate::enterModal(&modal_widget);
-
- IFileOpenDialog *pfd = 0;
- HRESULT hr = CoCreateInstance(QT_CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER,
- QT_IID_IFileOpenDialog, reinterpret_cast<void**>(&pfd));
-
- if (SUCCEEDED(hr)) {
- qt_win_set_IFileDialogOptions(pfd, args.selection,
- args.directory, args.caption,
- QStringList(), QFileDialog::ExistingFiles,
- args.options);
-
- // Set the FOS_PICKFOLDERS flag
- DWORD newOptions;
- hr = pfd->GetOptions(&newOptions);
- newOptions |= (FOS_PICKFOLDERS | FOS_FORCEFILESYSTEM);
- if (SUCCEEDED(hr) && SUCCEEDED((hr = pfd->SetOptions(newOptions)))) {
- QWidget *parentWindow = args.parent;
- if (parentWindow)
- parentWindow = parentWindow->window();
- else
- parentWindow = QApplication::activeWindow();
-
- // Show the file dialog.
- hr = pfd->Show(parentWindow ? parentWindow->winId() : 0);
- if (SUCCEEDED(hr)) {
- // Retrieve the result
- IShellItem *psi = 0;
- hr = pfd->GetResult(&psi);
- if (SUCCEEDED(hr)) {
- // Retrieve the file name from shell item.
- wchar_t *pszPath;
- hr = psi->GetDisplayName(SIGDN_FILESYSPATH, &pszPath);
- if (SUCCEEDED(hr)) {
- result = QString::fromWCharArray(pszPath);
- CoTaskMemFree(pszPath);
- }
- psi->Release(); // Free the current item.
- }
- }
- }
- }
- QApplicationPrivate::leaveModal(&modal_widget);
-
- qt_win_eatMouseMove();
-
- if (pfd)
- pfd->Release();
- return result;
-}
-
-#endif
-
-QStringList qt_win_get_open_file_names(const QFileDialogArgs &args,
- QString *initialDirectory,
- QString *selectedFilter)
-{
- QFileInfo fi;
- QDir dir;
-
- if (initialDirectory && initialDirectory->left(5) == QLatin1String("file:"))
- initialDirectory->remove(0, 5);
- fi = QFileInfo(*initialDirectory);
-
- if (initialDirectory && !fi.isDir()) {
- *initialDirectory = fi.absolutePath();
- }
-
- if (!fi.exists())
- *initialDirectory = QDir::homePath();
-
- DWORD selFilIdx = 0;
-
- QStringList filterLst = qt_win_make_filters_list(args.filter);
- int idx = 0;
- if (selectedFilter) {
- idx = filterLst.indexOf(*selectedFilter);
- }
- // Windows Vista (& above) allows users to search from file dialogs. If user selects
- // multiple files belonging to different folders from these search results, the
- // GetOpenFileName() will return only one folder name for all the files. To retrieve
- // the correct path for all selected files, we have to use Common Item Dialog interfaces.
-#ifndef Q_WS_WINCE
- if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)
- return qt_win_CID_get_open_file_names(args, initialDirectory, filterLst, selectedFilter, idx);
-#endif
-
- QStringList result;
- QDialog modal_widget;
- modal_widget.setAttribute(Qt::WA_NoChildEventsForParent, true);
- modal_widget.setParent(args.parent, Qt::Window);
- QApplicationPrivate::enterModal(&modal_widget);
-
- bool hideFiltersDetails = args.options & QFileDialog::HideNameFilterDetails;
- OPENFILENAME* ofn = qt_win_make_OFN(args.parent, args.selection,
- args.directory, args.caption,
- qt_win_filter(args.filter, hideFiltersDetails),
- QFileDialog::ExistingFiles,
- args.options);
- if (idx)
- ofn->nFilterIndex = idx + 1;
- if (GetOpenFileName(ofn)) {
- QString fileOrDir = QString::fromWCharArray(ofn->lpstrFile);
- selFilIdx = ofn->nFilterIndex;
- int offset = fileOrDir.length() + 1;
- if (ofn->lpstrFile[offset] == 0) {
- // Only one file selected; has full path
- fi.setFile(fileOrDir);
- QString res = fi.absoluteFilePath();
- if (!res.isEmpty())
- result.append(res);
- }
- else {
- // Several files selected; first string is path
- dir.setPath(fileOrDir);
- QString f;
- while(!(f = QString::fromWCharArray(ofn->lpstrFile + offset)).isEmpty()) {
- fi.setFile(dir, f);
- QString res = fi.absoluteFilePath();
- if (!res.isEmpty())
- result.append(res);
- offset += f.length() + 1;
- }
- }
- }
- qt_win_clean_up_OFN(&ofn);
-
- QApplicationPrivate::leaveModal(&modal_widget);
-
- qt_win_eatMouseMove();
-
- if (!result.isEmpty()) {
- *initialDirectory = fi.path(); // only save the path if there is a result
- if (selectedFilter)
- *selectedFilter = qt_win_selected_filter(args.filter, selFilIdx);
- }
- return result;
-}
-
-// MFC Directory Dialog. Contrib: Steve Williams (minor parts from Scott Powers)
-
-static int __stdcall winGetExistDirCallbackProc(HWND hwnd,
- UINT uMsg,
- LPARAM lParam,
- LPARAM lpData)
-{
- if (uMsg == BFFM_INITIALIZED && lpData != 0) {
- QString *initDir = (QString *)(lpData);
- if (!initDir->isEmpty()) {
- SendMessage(hwnd, BFFM_SETSELECTION, TRUE, LPARAM(initDir->utf16()));
- }
- } else if (uMsg == BFFM_SELCHANGED) {
- qt_win_resolve_libs();
- if (ptrSHGetPathFromIDList) {
- wchar_t path[MAX_PATH];
- ptrSHGetPathFromIDList(qt_LPITEMIDLIST(lParam), path);
- QString tmpStr = QString::fromWCharArray(path);
- if (!tmpStr.isEmpty())
- SendMessage(hwnd, BFFM_ENABLEOK, 1, 1);
- else
- SendMessage(hwnd, BFFM_ENABLEOK, 0, 0);
- SendMessage(hwnd, BFFM_SETSTATUSTEXT, 1, LPARAM(path));
- }
- }
- return 0;
-}
-
-QString qt_win_get_existing_directory(const QFileDialogArgs &args)
-{
-#ifndef Q_WS_WINCE
- if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)
- return qt_win_CID_get_existing_directory(args);
-#endif
-
- QString currentDir = QDir::currentPath();
- QString result;
- QWidget *parent = args.parent;
- if (parent)
- parent = parent->window();
- else
- parent = QApplication::activeWindow();
- if (parent)
- parent->createWinId();
-
- QDialog modal_widget;
- modal_widget.setAttribute(Qt::WA_NoChildEventsForParent, true);
- modal_widget.setParent(parent, Qt::Window);
- QApplicationPrivate::enterModal(&modal_widget);
-
- QString initDir = QDir::toNativeSeparators(args.directory);
- wchar_t path[MAX_PATH];
- wchar_t initPath[MAX_PATH];
- initPath[0] = 0;
- path[0] = 0;
- tTitle = args.caption;
-
- qt_BROWSEINFO bi;
-
- Q_ASSERT(!parent ||parent->testAttribute(Qt::WA_WState_Created));
- bi.hwndOwner = (parent ? parent->winId() : 0);
- bi.pidlRoot = NULL;
- //### This does not seem to be respected? - the dialog always displays "Browse for folder"
- bi.lpszTitle = (wchar_t*)tTitle.utf16();
- bi.pszDisplayName = initPath;
- bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT | BIF_NEWDIALOGSTYLE;
- bi.lpfn = winGetExistDirCallbackProc;
- bi.lParam = LPARAM(&initDir);
-
- qt_win_resolve_libs();
- if (ptrSHBrowseForFolder) {
- qt_LPITEMIDLIST pItemIDList = ptrSHBrowseForFolder(&bi);
- if (pItemIDList) {
- ptrSHGetPathFromIDList(pItemIDList, path);
- IMalloc *pMalloc;
- if (ptrSHGetMalloc(&pMalloc) == NOERROR) {
- pMalloc->Free(pItemIDList);
- pMalloc->Release();
- result = QString::fromWCharArray(path);
- }
- }
- }
- tTitle = QString();
-
- QApplicationPrivate::leaveModal(&modal_widget);
-
- qt_win_eatMouseMove();
-
- if (!result.isEmpty())
- result.replace(QLatin1Char('\\'), QLatin1Char('/'));
- return result;
-}
-
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/gui/dialogs/qfilesystemmodel.h b/src/gui/dialogs/qfilesystemmodel.h
deleted file mode 100644
index 0b1fa47b18..0000000000
--- a/src/gui/dialogs/qfilesystemmodel.h
+++ /dev/null
@@ -1,180 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QFILESYSTEMMODEL_H
-#define QFILESYSTEMMODEL_H
-
-#include <QtCore/qabstractitemmodel.h>
-#include <QtCore/qpair.h>
-#include <QtCore/qdir.h>
-#include <QtGui/qicon.h>
-#include <QtCore/qdiriterator.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_FILESYSTEMMODEL
-
-class ExtendedInformation;
-class QFileSystemModelPrivate;
-class QFileIconProvider;
-
-class Q_GUI_EXPORT QFileSystemModel : public QAbstractItemModel
-{
- Q_OBJECT
- Q_PROPERTY(bool resolveSymlinks READ resolveSymlinks WRITE setResolveSymlinks)
- Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly)
- Q_PROPERTY(bool nameFilterDisables READ nameFilterDisables WRITE setNameFilterDisables)
-
-Q_SIGNALS:
- void rootPathChanged(const QString &newPath);
- void fileRenamed(const QString &path, const QString &oldName, const QString &newName);
- void directoryLoaded(const QString &path);
-
-public:
- enum Roles {
- FileIconRole = Qt::DecorationRole,
- FilePathRole = Qt::UserRole + 1,
- FileNameRole = Qt::UserRole + 2,
- FilePermissions = Qt::UserRole + 3
- };
-
- explicit QFileSystemModel(QObject *parent = 0);
- ~QFileSystemModel();
-
- QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
- QModelIndex index(const QString &path, int column = 0) const;
- QModelIndex parent(const QModelIndex &child) const;
- bool hasChildren(const QModelIndex &parent = QModelIndex()) const;
- bool canFetchMore(const QModelIndex &parent) const;
- void fetchMore(const QModelIndex &parent);
-
- int rowCount(const QModelIndex &parent = QModelIndex()) const;
- int columnCount(const QModelIndex &parent = QModelIndex()) const;
-
- QVariant myComputer(int role = Qt::DisplayRole) const;
- QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
- bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
-
- QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
-
- Qt::ItemFlags flags(const QModelIndex &index) const;
-
- void sort(int column, Qt::SortOrder order = Qt::AscendingOrder);
-
- QStringList mimeTypes() const;
- QMimeData *mimeData(const QModelIndexList &indexes) const;
- bool dropMimeData(const QMimeData *data, Qt::DropAction action,
- int row, int column, const QModelIndex &parent);
- Qt::DropActions supportedDropActions() const;
-
- // QFileSystemModel specific API
- QModelIndex setRootPath(const QString &path);
- QString rootPath() const;
- QDir rootDirectory() const;
-
- void setIconProvider(QFileIconProvider *provider);
- QFileIconProvider *iconProvider() const;
-
- void setFilter(QDir::Filters filters);
- QDir::Filters filter() const;
-
- void setResolveSymlinks(bool enable);
- bool resolveSymlinks() const;
-
- void setReadOnly(bool enable);
- bool isReadOnly() const;
-
- void setNameFilterDisables(bool enable);
- bool nameFilterDisables() const;
-
- void setNameFilters(const QStringList &filters);
- QStringList nameFilters() const;
-
- QString filePath(const QModelIndex &index) const;
- bool isDir(const QModelIndex &index) const;
- qint64 size(const QModelIndex &index) const;
- QString type(const QModelIndex &index) const;
- QDateTime lastModified(const QModelIndex &index) const;
-
- QModelIndex mkdir(const QModelIndex &parent, const QString &name);
- bool rmdir(const QModelIndex &index) const; // ### Qt5: should not be const
- inline QString fileName(const QModelIndex &index) const;
- inline QIcon fileIcon(const QModelIndex &index) const;
- QFile::Permissions permissions(const QModelIndex &index) const;
- inline QFileInfo fileInfo(const QModelIndex &index) const;
- bool remove(const QModelIndex &index) const;
-
-protected:
- QFileSystemModel(QFileSystemModelPrivate &, QObject *parent = 0);
- void timerEvent(QTimerEvent *event);
- bool event(QEvent *event);
-
-private:
- Q_DECLARE_PRIVATE(QFileSystemModel)
- Q_DISABLE_COPY(QFileSystemModel)
-
- Q_PRIVATE_SLOT(d_func(), void _q_directoryChanged(const QString &directory, const QStringList &list))
- Q_PRIVATE_SLOT(d_func(), void _q_performDelayedSort())
- Q_PRIVATE_SLOT(d_func(), void _q_fileSystemChanged(const QString &path, const QList<QPair<QString, QFileInfo> > &))
- Q_PRIVATE_SLOT(d_func(), void _q_resolvedName(const QString &fileName, const QString &resolvedName))
-
- friend class QFileDialogPrivate;
-};
-
-inline QString QFileSystemModel::fileName(const QModelIndex &aindex) const
-{ return aindex.data(Qt::DisplayRole).toString(); }
-inline QIcon QFileSystemModel::fileIcon(const QModelIndex &aindex) const
-{ return qvariant_cast<QIcon>(aindex.data(Qt::DecorationRole)); }
-inline QFileInfo QFileSystemModel::fileInfo(const QModelIndex &aindex) const
-{ return QFileInfo(filePath(aindex)); }
-
-#endif // QT_NO_FILESYSTEMMODEL
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QFILESYSTEMMODEL_H
-
diff --git a/src/gui/dialogs/qfontdialog.cpp b/src/gui/dialogs/qfontdialog.cpp
deleted file mode 100644
index 6a646ff555..0000000000
--- a/src/gui/dialogs/qfontdialog.cpp
+++ /dev/null
@@ -1,1077 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qwindowdefs.h"
-
-#ifndef QT_NO_FONTDIALOG
-
-#include "qfontdialog.h"
-#include "qfontdialog_p.h"
-
-#include <qapplication.h>
-#include <qcheckbox.h>
-#include <qcombobox.h>
-#include <qevent.h>
-#include <qfontdatabase.h>
-#include <qgroupbox.h>
-#include <qlabel.h>
-#include <qlayout.h>
-#include <qlineedit.h>
-#include <qpushbutton.h>
-#include <qstyle.h>
-#include <qdialogbuttonbox.h>
-#include <qheaderview.h>
-#include <qlistview.h>
-#include <qstringlistmodel.h>
-#include <qvalidator.h>
-#include <private/qdialog_p.h>
-#include <private/qfont_p.h>
-
-#if defined(Q_WS_S60)
-#include <QtGui/qdesktopwidget.h>
-#endif
-
-QT_BEGIN_NAMESPACE
-
-class QFontListView : public QListView
-{
- Q_OBJECT
-public:
- QFontListView(QWidget *parent);
- inline QStringListModel *model() const {
- return static_cast<QStringListModel *>(QListView::model());
- }
- inline void setCurrentItem(int item) {
- QListView::setCurrentIndex(static_cast<QAbstractListModel*>(model())->index(item));
- }
- inline int currentItem() const {
- return QListView::currentIndex().row();
- }
- inline int count() const {
- return model()->rowCount();
- }
- inline QString currentText() const {
- int row = QListView::currentIndex().row();
- return row < 0 ? QString() : model()->stringList().at(row);
- }
- void currentChanged(const QModelIndex &current, const QModelIndex &previous) {
- QListView::currentChanged(current, previous);
- if (current.isValid())
- emit highlighted(current.row());
- }
- QString text(int i) const {
- return model()->stringList().at(i);
- }
-signals:
- void highlighted(int);
-};
-
-QFontListView::QFontListView(QWidget *parent)
- : QListView(parent)
-{
- setModel(new QStringListModel(parent));
- setEditTriggers(NoEditTriggers);
-}
-
-static const Qt::WindowFlags DefaultWindowFlags =
- Qt::Dialog | Qt::WindowSystemMenuHint;
-
-/*!
- \class QFontDialog
- \ingroup standard-dialogs
-
- \brief The QFontDialog class provides a dialog widget for selecting a font.
-
- A font dialog is created through one of the static getFont()
- functions.
-
- Examples:
-
- \snippet doc/src/snippets/code/src_gui_dialogs_qfontdialog.cpp 0
-
- The dialog can also be used to set a widget's font directly:
- \snippet doc/src/snippets/code/src_gui_dialogs_qfontdialog.cpp 1
- If the user clicks OK the font they chose will be used for myWidget,
- and if they click Cancel the original font is used.
-
- \image plastique-fontdialog.png A font dialog in the Plastique widget style.
-
- \sa QFont, QFontInfo, QFontMetrics, QColorDialog, QFileDialog, QPrintDialog,
- {Standard Dialogs Example}
-*/
-
-/*!
- \since 4.5
-
- Constructs a standard font dialog.
-
- Use setCurrentFont() to set the initial font attributes.
-
- The \a parent parameter is passed to the QDialog constructor.
-
- \sa getFont()
-*/
-QFontDialog::QFontDialog(QWidget *parent)
- : QDialog(*new QFontDialogPrivate, parent, DefaultWindowFlags)
-{
- Q_D(QFontDialog);
- d->init();
-}
-
-/*!
- \since 4.5
-
- Constructs a standard font dialog with the given \a parent and specified
- \a initial color.
-*/
-QFontDialog::QFontDialog(const QFont &initial, QWidget *parent)
- : QDialog(*new QFontDialogPrivate, parent, DefaultWindowFlags)
-{
- Q_D(QFontDialog);
- d->init();
- setCurrentFont(initial);
-}
-
-void QFontDialogPrivate::init()
-{
- Q_Q(QFontDialog);
-
-#ifdef Q_WS_MAC
- nativeDialogInUse = false;
- delegate = 0;
-#endif
-
- q->setSizeGripEnabled(true);
- q->setWindowTitle(QFontDialog::tr("Select Font"));
-
- // grid
- familyEdit = new QLineEdit(q);
- familyEdit->setReadOnly(true);
- familyList = new QFontListView(q);
- familyEdit->setFocusProxy(familyList);
-
- familyAccel = new QLabel(q);
-#ifndef QT_NO_SHORTCUT
- familyAccel->setBuddy(familyList);
-#endif
- familyAccel->setIndent(2);
-
- styleEdit = new QLineEdit(q);
- styleEdit->setReadOnly(true);
- styleList = new QFontListView(q);
- styleEdit->setFocusProxy(styleList);
-
- styleAccel = new QLabel(q);
-#ifndef QT_NO_SHORTCUT
- styleAccel->setBuddy(styleList);
-#endif
- styleAccel->setIndent(2);
-
- sizeEdit = new QLineEdit(q);
- sizeEdit->setFocusPolicy(Qt::ClickFocus);
- QIntValidator *validator = new QIntValidator(1, 512, q);
- sizeEdit->setValidator(validator);
- sizeList = new QFontListView(q);
-
- sizeAccel = new QLabel(q);
-#ifndef QT_NO_SHORTCUT
- sizeAccel->setBuddy(sizeEdit);
-#endif
- sizeAccel->setIndent(2);
-
- // effects box
- effects = new QGroupBox(q);
- QVBoxLayout *vbox = new QVBoxLayout(effects);
- strikeout = new QCheckBox(effects);
- vbox->addWidget(strikeout);
- underline = new QCheckBox(effects);
- vbox->addWidget(underline);
-
- sample = new QGroupBox(q);
- QHBoxLayout *hbox = new QHBoxLayout(sample);
- sampleEdit = new QLineEdit(sample);
- sampleEdit->setSizePolicy(QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored));
- sampleEdit->setAlignment(Qt::AlignCenter);
- // Note that the sample text is *not* translated with tr(), as the
- // characters used depend on the charset encoding.
- sampleEdit->setText(QLatin1String("AaBbYyZz"));
- hbox->addWidget(sampleEdit);
-
- writingSystemCombo = new QComboBox(q);
-
- writingSystemAccel = new QLabel(q);
-#ifndef QT_NO_SHORTCUT
- writingSystemAccel->setBuddy(writingSystemCombo);
-#endif
- writingSystemAccel->setIndent(2);
-
- size = 0;
- smoothScalable = false;
-
- QObject::connect(writingSystemCombo, SIGNAL(activated(int)), q, SLOT(_q_writingSystemHighlighted(int)));
- QObject::connect(familyList, SIGNAL(highlighted(int)), q, SLOT(_q_familyHighlighted(int)));
- QObject::connect(styleList, SIGNAL(highlighted(int)), q, SLOT(_q_styleHighlighted(int)));
- QObject::connect(sizeList, SIGNAL(highlighted(int)), q, SLOT(_q_sizeHighlighted(int)));
- QObject::connect(sizeEdit, SIGNAL(textChanged(QString)), q, SLOT(_q_sizeChanged(QString)));
-
- QObject::connect(strikeout, SIGNAL(clicked()), q, SLOT(_q_updateSample()));
- QObject::connect(underline, SIGNAL(clicked()), q, SLOT(_q_updateSample()));
-
- for (int i = 0; i < QFontDatabase::WritingSystemsCount; ++i) {
- QFontDatabase::WritingSystem ws = QFontDatabase::WritingSystem(i);
- QString writingSystemName = QFontDatabase::writingSystemName(ws);
- if (writingSystemName.isEmpty())
- break;
- writingSystemCombo->addItem(writingSystemName);
- }
-
- updateFamilies();
- if (familyList->count() != 0)
- familyList->setCurrentItem(0);
-
- // grid layout
- QGridLayout *mainGrid = new QGridLayout(q);
-
- int spacing = mainGrid->spacing();
- if (spacing >= 0) { // uniform spacing
- mainGrid->setSpacing(0);
-
- mainGrid->setColumnMinimumWidth(1, spacing);
- mainGrid->setColumnMinimumWidth(3, spacing);
-
- int margin = 0;
- mainGrid->getContentsMargins(0, 0, 0, &margin);
-
- mainGrid->setRowMinimumHeight(3, margin);
- mainGrid->setRowMinimumHeight(6, 2);
- mainGrid->setRowMinimumHeight(8, margin);
- }
-
- mainGrid->addWidget(familyAccel, 0, 0);
- mainGrid->addWidget(familyEdit, 1, 0);
- mainGrid->addWidget(familyList, 2, 0);
-
- mainGrid->addWidget(styleAccel, 0, 2);
- mainGrid->addWidget(styleEdit, 1, 2);
- mainGrid->addWidget(styleList, 2, 2);
-
- mainGrid->addWidget(sizeAccel, 0, 4);
- mainGrid->addWidget(sizeEdit, 1, 4);
- mainGrid->addWidget(sizeList, 2, 4);
-
- mainGrid->setColumnStretch(0, 38);
- mainGrid->setColumnStretch(2, 24);
- mainGrid->setColumnStretch(4, 10);
-
- mainGrid->addWidget(effects, 4, 0);
-
- mainGrid->addWidget(sample, 4, 2, 4, 3);
-
- mainGrid->addWidget(writingSystemAccel, 5, 0);
- mainGrid->addWidget(writingSystemCombo, 7, 0);
-
- buttonBox = new QDialogButtonBox(q);
- mainGrid->addWidget(buttonBox, 9, 0, 1, 5);
-
- QPushButton *button
- = static_cast<QPushButton *>(buttonBox->addButton(QDialogButtonBox::Ok));
- QObject::connect(buttonBox, SIGNAL(accepted()), q, SLOT(accept()));
- button->setDefault(true);
-
- buttonBox->addButton(QDialogButtonBox::Cancel);
- QObject::connect(buttonBox, SIGNAL(rejected()), q, SLOT(reject()));
-
-#if defined(Q_WS_WINCE)
- q->resize(180, 120);
-#elif defined(Q_WS_S60)
- q->resize(QApplication::desktop()->availableGeometry(QCursor::pos()).size());
-#else
- q->resize(500, 360);
-#endif // Q_WS_WINCE
-
- sizeEdit->installEventFilter(q);
- familyList->installEventFilter(q);
- styleList->installEventFilter(q);
- sizeList->installEventFilter(q);
-
- familyList->setFocus();
- retranslateStrings();
-}
-
-/*!
- \internal
- Destroys the font dialog and frees up its storage.
-*/
-
-QFontDialog::~QFontDialog()
-{
-#ifdef Q_WS_MAC
- Q_D(QFontDialog);
- if (d->delegate) {
- d->closeCocoaFontPanel();
- return;
- }
-#endif
-}
-
-/*!
- Executes a modal font dialog and returns a font.
-
- If the user clicks \gui OK, the selected font is returned. If the user
- clicks \gui Cancel, the \a initial font is returned.
-
- The dialog is constructed with the given \a parent and the options specified
- in \a options. \a title is shown as the window title of the dialog and \a
- initial is the initially selected font. If the \a ok parameter is not-null,
- the value it refers to is set to true if the user clicks \gui OK, and set to
- false if the user clicks \gui Cancel.
-
- Examples:
- \snippet doc/src/snippets/code/src_gui_dialogs_qfontdialog.cpp 2
-
- The dialog can also be used to set a widget's font directly:
- \snippet doc/src/snippets/code/src_gui_dialogs_qfontdialog.cpp 3
- In this example, if the user clicks OK the font they chose will be
- used, and if they click Cancel the original font is used.
-
- \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 QFontDialog constructors.
-*/
-QFont QFontDialog::getFont(bool *ok, const QFont &initial, QWidget *parent, const QString &title,
- FontDialogOptions options)
-{
- return QFontDialogPrivate::getFont(ok, initial, parent, title, options);
-}
-
-/*!
- \overload
- \since 4.5
-*/
-QFont QFontDialog::getFont(bool *ok, const QFont &initial, QWidget *parent, const QString &title)
-{
- return QFontDialogPrivate::getFont(ok, initial, parent, title, 0);
-}
-
-/*!
- \overload
-*/
-QFont QFontDialog::getFont(bool *ok, const QFont &initial, QWidget *parent)
-{
- return QFontDialogPrivate::getFont(ok, initial, parent, QString(), 0);
-}
-
-/*!
- \overload
-
- Executes a modal font dialog and returns a font.
-
- If the user clicks \gui OK, the selected font is returned. If the user
- clicks \gui Cancel, the Qt default font is returned.
-
- The dialog is constructed with the given \a parent.
- If the \a ok parameter is not-null, the value it refers to is set
- to true if the user clicks \gui OK, and false if the user clicks
- \gui Cancel.
-
- Example:
- \snippet doc/src/snippets/code/src_gui_dialogs_qfontdialog.cpp 4
-
- \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 QFontDialog constructors.
-*/
-QFont QFontDialog::getFont(bool *ok, QWidget *parent)
-{
- QFont initial;
- return QFontDialogPrivate::getFont(ok, initial, parent, QString(), 0);
-}
-
-QFont QFontDialogPrivate::getFont(bool *ok, const QFont &initial, QWidget *parent,
- const QString &title, QFontDialog::FontDialogOptions options)
-{
- QFontDialog dlg(parent);
- dlg.setOptions(options);
- dlg.setCurrentFont(initial);
- if (!title.isEmpty())
- dlg.setWindowTitle(title);
-
- int ret = (dlg.exec() || (options & QFontDialog::NoButtons));
- if (ok)
- *ok = !!ret;
- if (ret) {
- return dlg.selectedFont();
- } else {
- return initial;
- }
-}
-
-/*!
- \internal
- An event filter to make the Up, Down, PageUp and PageDown keys work
- correctly in the line edits. The source of the event is the object
- \a o and the event is \a e.
-*/
-
-bool QFontDialog::eventFilter(QObject *o , QEvent *e)
-{
- Q_D(QFontDialog);
- if (e->type() == QEvent::KeyPress) {
- QKeyEvent *k = (QKeyEvent *)e;
- if (o == d->sizeEdit &&
- (k->key() == Qt::Key_Up ||
- k->key() == Qt::Key_Down ||
- k->key() == Qt::Key_PageUp ||
- k->key() == Qt::Key_PageDown)) {
-
- int ci = d->sizeList->currentItem();
- (void)QApplication::sendEvent(d->sizeList, k);
-
- if (ci != d->sizeList->currentItem()
- && style()->styleHint(QStyle::SH_FontDialog_SelectAssociatedText, 0, this))
- d->sizeEdit->selectAll();
- return true;
- } else if ((o == d->familyList || o == d->styleList) &&
- (k->key() == Qt::Key_Return || k->key() == Qt::Key_Enter)) {
- k->accept();
- accept();
- return true;
- }
- } else if (e->type() == QEvent::FocusIn
- && style()->styleHint(QStyle::SH_FontDialog_SelectAssociatedText, 0, this)) {
- if (o == d->familyList)
- d->familyEdit->selectAll();
- else if (o == d->styleList)
- d->styleEdit->selectAll();
- else if (o == d->sizeList)
- d->sizeEdit->selectAll();
- } else if (e->type() == QEvent::MouseButtonPress && o == d->sizeList) {
- d->sizeEdit->setFocus();
- }
- return QDialog::eventFilter(o, e);
-}
-
-/*
- Updates the contents of the "font family" list box. This
- function can be reimplemented if you have special requirements.
-*/
-
-void QFontDialogPrivate::updateFamilies()
-{
- Q_Q(QFontDialog);
-
- enum match_t { MATCH_NONE = 0, MATCH_LAST_RESORT = 1, MATCH_APP = 2, MATCH_FAMILY = 3 };
-
- QStringList familyNames = fdb.families(writingSystem);
-
- familyList->model()->setStringList(familyNames);
-
- QString foundryName1, familyName1, foundryName2, familyName2;
- int bestFamilyMatch = -1;
- match_t bestFamilyType = MATCH_NONE;
-
- QFont f;
-
- // ##### do the right thing for a list of family names in the font.
- QFontDatabase::parseFontName(family, foundryName1, familyName1);
-
- QStringList::const_iterator it = familyNames.constBegin();
- int i = 0;
- for(; it != familyNames.constEnd(); ++it, ++i) {
- QFontDatabase::parseFontName(*it, foundryName2, familyName2);
-
- //try to match...
- if (familyName1 == familyName2) {
- bestFamilyType = MATCH_FAMILY;
- if (foundryName1 == foundryName2) {
- bestFamilyMatch = i;
- break;
- }
- if (bestFamilyMatch < MATCH_FAMILY)
- bestFamilyMatch = i;
- }
-
- //and try some fall backs
- match_t type = MATCH_NONE;
- if (bestFamilyType <= MATCH_NONE && familyName2 == f.lastResortFamily())
- type = MATCH_LAST_RESORT;
- if (bestFamilyType <= MATCH_LAST_RESORT && familyName2 == f.family())
- type = MATCH_APP;
- // ### add fallback for writingSystem
- if (type != MATCH_NONE) {
- bestFamilyType = type;
- bestFamilyMatch = i;
- }
- }
-
- if (i != -1 && bestFamilyType != MATCH_NONE)
- familyList->setCurrentItem(bestFamilyMatch);
- else
- familyList->setCurrentItem(0);
- familyEdit->setText(familyList->currentText());
- if (q->style()->styleHint(QStyle::SH_FontDialog_SelectAssociatedText, 0, q)
- && familyList->hasFocus())
- familyEdit->selectAll();
-
- updateStyles();
-}
-
-/*
- Updates the contents of the "font style" list box. This
- function can be reimplemented if you have special requirements.
-*/
-void QFontDialogPrivate::updateStyles()
-{
- Q_Q(QFontDialog);
- QStringList styles = fdb.styles(familyList->currentText());
- styleList->model()->setStringList(styles);
-
- if (styles.isEmpty()) {
- styleEdit->clear();
- smoothScalable = false;
- } else {
- if (!style.isEmpty()) {
- bool found = false;
- bool first = true;
- QString cstyle = style;
-
- redo:
- for (int i = 0; i < (int)styleList->count(); i++) {
- if (cstyle == styleList->text(i)) {
- styleList->setCurrentItem(i);
- found = true;
- break;
- }
- }
- if (!found && first) {
- if (cstyle.contains(QLatin1String("Italic"))) {
- cstyle.replace(QLatin1String("Italic"), QLatin1String("Oblique"));
- first = false;
- goto redo;
- } else if (cstyle.contains(QLatin1String("Oblique"))) {
- cstyle.replace(QLatin1String("Oblique"), QLatin1String("Italic"));
- first = false;
- goto redo;
- }
- }
- if (!found)
- styleList->setCurrentItem(0);
- } else {
- styleList->setCurrentItem(0);
- }
-
- styleEdit->setText(styleList->currentText());
- if (q->style()->styleHint(QStyle::SH_FontDialog_SelectAssociatedText, 0, q)
- && styleList->hasFocus())
- styleEdit->selectAll();
-
- smoothScalable = fdb.isSmoothlyScalable(familyList->currentText(), styleList->currentText());
- }
-
- updateSizes();
-}
-
-/*!
- \internal
- Updates the contents of the "font size" list box. This
- function can be reimplemented if you have special requirements.
-*/
-
-void QFontDialogPrivate::updateSizes()
-{
- Q_Q(QFontDialog);
-
- if (!familyList->currentText().isEmpty()) {
- QList<int> sizes = fdb.pointSizes(familyList->currentText(), styleList->currentText());
-
- int i = 0;
- int current = -1;
- QStringList str_sizes;
- for(QList<int>::const_iterator it = sizes.constBegin(); it != sizes.constEnd(); ++it) {
- str_sizes.append(QString::number(*it));
- if (current == -1 && *it >= size)
- current = i;
- ++i;
- }
- sizeList->model()->setStringList(str_sizes);
- if (current == -1) {
- // we request a size bigger than the ones in the list, select the biggest one
- current = sizeList->count() - 1;
- }
- sizeList->setCurrentItem(current);
-
- sizeEdit->blockSignals(true);
- sizeEdit->setText((smoothScalable ? QString::number(size) : sizeList->currentText()));
- if (q->style()->styleHint(QStyle::SH_FontDialog_SelectAssociatedText, 0, q)
- && sizeList->hasFocus())
- sizeEdit->selectAll();
- sizeEdit->blockSignals(false);
- } else {
- sizeEdit->clear();
- }
-
- _q_updateSample();
-}
-
-void QFontDialogPrivate::_q_updateSample()
-{
- // compute new font
- int pSize = sizeEdit->text().toInt();
- QFont newFont(fdb.font(familyList->currentText(), style, pSize));
- newFont.setStrikeOut(strikeout->isChecked());
- newFont.setUnderline(underline->isChecked());
-
- if (familyList->currentText().isEmpty())
- sampleEdit->clear();
-
- updateSampleFont(newFont);
-}
-
-void QFontDialogPrivate::updateSampleFont(const QFont &newFont)
-{
- Q_Q(QFontDialog);
- if (newFont != sampleEdit->font()) {
- sampleEdit->setFont(newFont);
- emit q->currentFontChanged(newFont);
- }
-}
-
-/*!
- \internal
-*/
-void QFontDialogPrivate::_q_writingSystemHighlighted(int index)
-{
- writingSystem = QFontDatabase::WritingSystem(index);
- sampleEdit->setText(fdb.writingSystemSample(writingSystem));
- updateFamilies();
-}
-
-/*!
- \internal
-*/
-void QFontDialogPrivate::_q_familyHighlighted(int i)
-{
- Q_Q(QFontDialog);
- family = familyList->text(i);
- familyEdit->setText(family);
- if (q->style()->styleHint(QStyle::SH_FontDialog_SelectAssociatedText, 0, q)
- && familyList->hasFocus())
- familyEdit->selectAll();
-
- updateStyles();
-}
-
-
-/*!
- \internal
-*/
-
-void QFontDialogPrivate::_q_styleHighlighted(int index)
-{
- Q_Q(QFontDialog);
- QString s = styleList->text(index);
- styleEdit->setText(s);
- if (q->style()->styleHint(QStyle::SH_FontDialog_SelectAssociatedText, 0, q)
- && styleList->hasFocus())
- styleEdit->selectAll();
-
- style = s;
-
- updateSizes();
-}
-
-
-/*!
- \internal
-*/
-
-void QFontDialogPrivate::_q_sizeHighlighted(int index)
-{
- Q_Q(QFontDialog);
- QString s = sizeList->text(index);
- sizeEdit->setText(s);
- if (q->style()->styleHint(QStyle::SH_FontDialog_SelectAssociatedText, 0, q)
- && sizeEdit->hasFocus())
- sizeEdit->selectAll();
-
- size = s.toInt();
- _q_updateSample();
-}
-
-/*!
- \internal
- This slot is called if the user changes the font size.
- The size is passed in the \a s argument as a \e string.
-*/
-
-void QFontDialogPrivate::_q_sizeChanged(const QString &s)
-{
- // no need to check if the conversion is valid, since we have an QIntValidator in the size edit
- int size = s.toInt();
- if (this->size == size)
- return;
-
- this->size = size;
- if (sizeList->count() != 0) {
- int i;
- for (i = 0; i < sizeList->count() - 1; i++) {
- if (sizeList->text(i).toInt() >= this->size)
- break;
- }
- sizeList->blockSignals(true);
- sizeList->setCurrentItem(i);
- sizeList->blockSignals(false);
- }
- _q_updateSample();
-}
-
-void QFontDialogPrivate::retranslateStrings()
-{
- familyAccel->setText(QFontDialog::tr("&Font"));
- styleAccel->setText(QFontDialog::tr("Font st&yle"));
- sizeAccel->setText(QFontDialog::tr("&Size"));
-#ifndef Q_WS_S60
- // Removed the title due to lack of screen estate in small S60 screen.
- // The effects are descriptive without a title (strikeout, underline).
- effects->setTitle(QFontDialog::tr("Effects"));
-#endif
- strikeout->setText(QFontDialog::tr("Stri&keout"));
- underline->setText(QFontDialog::tr("&Underline"));
- sample->setTitle(QFontDialog::tr("Sample"));
- writingSystemAccel->setText(QFontDialog::tr("Wr&iting System"));
-}
-
-/*!
- \reimp
-*/
-void QFontDialog::changeEvent(QEvent *e)
-{
- Q_D(QFontDialog);
- if (e->type() == QEvent::LanguageChange) {
- d->retranslateStrings();
- }
- QDialog::changeEvent(e);
-}
-
-/*!
- \since 4.5
-
- \property QFontDialog::currentFont
- \brief the current font of the dialog.
-*/
-
-/*!
- \since 4.5
-
- Sets the font highlighted in the QFontDialog to the given \a font.
-
- \sa selectedFont()
-*/
-void QFontDialog::setCurrentFont(const QFont &font)
-{
- Q_D(QFontDialog);
- d->family = font.family();
- d->style = d->fdb.styleString(font);
- d->size = font.pointSize();
- if (d->size == -1) {
- QFontInfo fi(font);
- d->size = fi.pointSize();
- }
- d->strikeout->setChecked(font.strikeOut());
- d->underline->setChecked(font.underline());
- d->updateFamilies();
-
-#ifdef Q_WS_MAC
- if (d->delegate)
- QFontDialogPrivate::setFont(d->delegate, font);
-#endif
-}
-
-/*!
- \since 4.5
-
- Returns the current font.
-
- \sa selectedFont()
-*/
-QFont QFontDialog::currentFont() const
-{
- Q_D(const QFontDialog);
- return d->sampleEdit->font();
-}
-
-/*!
- Returns the font that the user selected by clicking the \gui{OK}
- or equivalent button.
-
- \note This font is not always the same as the font held by the
- \l currentFont property since the user can choose different fonts
- before finally selecting the one to use.
-*/
-QFont QFontDialog::selectedFont() const
-{
- Q_D(const QFontDialog);
- return d->selectedFont;
-}
-
-/*!
- \enum QFontDialog::FontDialogOption
- \since 4.5
-
- This enum specifies various options that affect the look and feel
- of a font dialog.
-
- \value NoButtons Don't display \gui{OK} and \gui{Cancel} buttons. (Useful for "live dialogs".)
- \value DontUseNativeDialog Use Qt's standard font dialog on the Mac instead of Apple's
- native font panel. (Currently, the native dialog is never used,
- but this is likely to change in future Qt releases.)
-
- \sa options, setOption(), testOption()
-*/
-
-/*!
- Sets the given \a option to be enabled if \a on is true;
- otherwise, clears the given \a option.
-
- \sa options, testOption()
-*/
-void QFontDialog::setOption(FontDialogOption option, bool on)
-{
- Q_D(QFontDialog);
- if (!(d->opts & option) != !on)
- setOptions(d->opts ^ option);
-}
-
-/*!
- Returns true if the given \a option is enabled; otherwise, returns
- false.
-
- \sa options, setOption()
-*/
-bool QFontDialog::testOption(FontDialogOption option) const
-{
- Q_D(const QFontDialog);
- return (d->opts & option) != 0;
-}
-
-/*!
- \property QFontDialog::options
- \brief the various options that affect the look and feel of the dialog
- \since 4.5
-
- By default, all options are disabled.
-
- Options should be set before showing the dialog. Setting them while the
- dialog is visible is not guaranteed to have an immediate effect on the
- dialog (depending on the option and on the platform).
-
- \sa setOption(), testOption()
-*/
-void QFontDialog::setOptions(FontDialogOptions options)
-{
- Q_D(QFontDialog);
-
- FontDialogOptions changed = (options ^ d->opts);
- if (!changed)
- return;
-
- d->opts = options;
- d->buttonBox->setVisible(!(options & NoButtons));
-}
-
-QFontDialog::FontDialogOptions QFontDialog::options() const
-{
- Q_D(const QFontDialog);
- return d->opts;
-}
-
-#ifdef Q_WS_MAC
-// can only have one Cocoa font panel active
-bool QFontDialogPrivate::sharedFontPanelAvailable = true;
-#endif
-
-/*!
- \since 4.5
- \overload
-
- Opens the dialog and connects its fontSelected() signal to the slot specified
- by \a receiver and \a member.
-
- The signal will be disconnected from the slot when the dialog is closed.
-*/
-void QFontDialog::open(QObject *receiver, const char *member)
-{
- Q_D(QFontDialog);
- connect(this, SIGNAL(fontSelected(QFont)), receiver, member);
- d->receiverToDisconnectOnClose = receiver;
- d->memberToDisconnectOnClose = member;
- QDialog::open();
-}
-
-/*!
- \since 4.5
-
- \fn void QFontDialog::currentFontChanged(const QFont &font)
-
- This signal is emitted when the current font is changed. The new font is
- specified in \a font.
-
- The signal is emitted while a user is selecting a font. Ultimately, the
- chosen font may differ from the font currently selected.
-
- \sa currentFont, fontSelected(), selectedFont()
-*/
-
-/*!
- \since 4.5
-
- \fn void QFontDialog::fontSelected(const QFont &font)
-
- This signal is emitted when a font has been selected. The selected font is
- specified in \a font.
-
- The signal is only emitted when a user has chosen the final font to be
- used. It is not emitted while the user is changing the current font in the
- font dialog.
-
- \sa selectedFont(), currentFontChanged(), currentFont
-*/
-
-/*!
- \reimp
-*/
-void QFontDialog::setVisible(bool visible)
-{
- if (testAttribute(Qt::WA_WState_ExplicitShowHide) && testAttribute(Qt::WA_WState_Hidden) != visible)
- return;
-#ifdef Q_WS_MAC
- Q_D(QFontDialog);
- if (d->canBeNativeDialog()){
- if (d->setVisible_sys(visible)){
- d->nativeDialogInUse = true;
- // Set WA_DontShowOnScreen so that QDialog::setVisible(visible) below
- // updates the state correctly, but skips showing the non-native version:
- setAttribute(Qt::WA_DontShowOnScreen, true);
- } else {
- d->nativeDialogInUse = false;
- setAttribute(Qt::WA_DontShowOnScreen, false);
- }
- }
-#endif // Q_WS_MAC
- QDialog::setVisible(visible);
-}
-
-/*!
- Closes the dialog and sets its result code to \a result. If this dialog
- is shown with exec(), done() causes the local event loop to finish,
- and exec() to return \a result.
-
- \sa QDialog::done()
-*/
-void QFontDialog::done(int result)
-{
- Q_D(QFontDialog);
- QDialog::done(result);
- if (result == Accepted) {
- // We check if this is the same font we had before, if so we emit currentFontChanged
- QFont selectedFont = currentFont();
- if(selectedFont != d->selectedFont)
- emit(currentFontChanged(selectedFont));
- d->selectedFont = selectedFont;
- emit fontSelected(d->selectedFont);
- } else
- d->selectedFont = QFont();
- if (d->receiverToDisconnectOnClose) {
- disconnect(this, SIGNAL(fontSelected(QFont)),
- d->receiverToDisconnectOnClose, d->memberToDisconnectOnClose);
- d->receiverToDisconnectOnClose = 0;
- }
- d->memberToDisconnectOnClose.clear();
-}
-
-#ifdef Q_WS_MAC
-bool QFontDialogPrivate::canBeNativeDialog()
-{
- Q_Q(QFontDialog);
- if (nativeDialogInUse)
- return true;
- if (q->testAttribute(Qt::WA_DontShowOnScreen))
- return false;
- if (opts & QFontDialog::DontUseNativeDialog)
- return false;
-
- QLatin1String staticName(QFontDialog::staticMetaObject.className());
- QLatin1String dynamicName(q->metaObject()->className());
- return (staticName == dynamicName);
-}
-#endif // Q_WS_MAC
-
-/*!
- \fn QFont QFontDialog::getFont(bool *ok, const QFont &initial, QWidget* parent, const char* name)
- \since 4.5
-
- Call getFont(\a ok, \a initial, \a parent) instead.
-
- \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 QFontDialog constructors.
-
- The \a name parameter is ignored.
-*/
-
-/*!
- \fn QFont QFontDialog::getFont(bool *ok, QWidget* parent, const char* name)
-
- Call getFont(\a ok, \a parent) instead.
-
- \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 QFontDialog constructors.
-
- The \a name parameter is ignored.
-*/
-
-QT_END_NAMESPACE
-
-#include "qfontdialog.moc"
-#include "moc_qfontdialog.cpp"
-
-#endif // QT_NO_FONTDIALOG
diff --git a/src/gui/dialogs/qfontdialog.h b/src/gui/dialogs/qfontdialog.h
deleted file mode 100644
index 8e4957d11e..0000000000
--- a/src/gui/dialogs/qfontdialog.h
+++ /dev/null
@@ -1,147 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QFONTDIALOG_H
-#define QFONTDIALOG_H
-
-#include <QtGui/qwindowdefs.h>
-#include <QtGui/qdialog.h>
-#include <QtGui/qfont.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_FONTDIALOG
-
-class QFontDialogPrivate;
-
-class Q_GUI_EXPORT QFontDialog : public QDialog
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QFontDialog)
- Q_ENUMS(FontDialogOption)
- Q_PROPERTY(QFont currentFont READ currentFont WRITE setCurrentFont NOTIFY currentFontChanged)
- Q_PROPERTY(FontDialogOptions options READ options WRITE setOptions)
-
-public:
- enum FontDialogOption {
- NoButtons = 0x00000001,
- DontUseNativeDialog = 0x00000002
- };
-
- Q_DECLARE_FLAGS(FontDialogOptions, FontDialogOption)
-
- explicit QFontDialog(QWidget *parent = 0);
- explicit QFontDialog(const QFont &initial, QWidget *parent = 0);
- ~QFontDialog();
-
- void setCurrentFont(const QFont &font);
- QFont currentFont() const;
-
- QFont selectedFont() const;
-
- void setOption(FontDialogOption option, bool on = true);
- bool testOption(FontDialogOption option) const;
- void setOptions(FontDialogOptions options);
- FontDialogOptions options() const;
-
-#ifdef Q_NO_USING_KEYWORD
-#ifndef Q_QDOC
- void open() { QDialog::open(); }
-#endif
-#else
- using QDialog::open;
-#endif
- void open(QObject *receiver, const char *member);
-
- void setVisible(bool visible);
-
- // ### Qt 5: merge overloads
- static QFont getFont(bool *ok, const QFont &initial, QWidget *parent, const QString &title,
- FontDialogOptions options);
- static QFont getFont(bool *ok, const QFont &initial, QWidget *parent, const QString &title);
- static QFont getFont(bool *ok, const QFont &initial, QWidget *parent = 0);
- static QFont getFont(bool *ok, QWidget *parent = 0);
-
-#ifdef QT3_SUPPORT
- static QFont getFont(bool *ok, const QFont &initial, QWidget *parent, const char *name)
- { Q_UNUSED(name); return getFont(ok, initial, parent); }
- static QFont getFont(bool *ok, QWidget *parent, const char *name)
- { Q_UNUSED(name); return getFont(ok, parent); }
-#endif
-
-Q_SIGNALS:
- void currentFontChanged(const QFont &font);
- void fontSelected(const QFont &font);
-
-protected:
- void changeEvent(QEvent *event);
- void done(int result);
-
-private:
- // ### Qt 5: make protected
- bool eventFilter(QObject *object, QEvent *event);
-
- Q_DISABLE_COPY(QFontDialog)
-
- Q_PRIVATE_SLOT(d_func(), void _q_sizeChanged(const QString &))
- Q_PRIVATE_SLOT(d_func(), void _q_familyHighlighted(int))
- Q_PRIVATE_SLOT(d_func(), void _q_writingSystemHighlighted(int))
- Q_PRIVATE_SLOT(d_func(), void _q_styleHighlighted(int))
- Q_PRIVATE_SLOT(d_func(), void _q_sizeHighlighted(int))
- Q_PRIVATE_SLOT(d_func(), void _q_updateSample())
-#if defined(Q_WS_MAC)
- Q_PRIVATE_SLOT(d_func(), void _q_macRunNativeAppModalPanel())
-#endif
-};
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QFontDialog::FontDialogOptions)
-
-#endif // QT_NO_FONTDIALOG
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QFONTDIALOG_H
diff --git a/src/gui/dialogs/qfscompleter_p.h b/src/gui/dialogs/qfscompleter_p.h
deleted file mode 100644
index a3d21ab039..0000000000
--- a/src/gui/dialogs/qfscompleter_p.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QFSCOMPLETOR_P_H
-#define QFSCOMPLETOR_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qcompleter.h"
-#include <QtGui/qfilesystemmodel.h>
-QT_BEGIN_NAMESPACE
-#ifndef QT_NO_FSCOMPLETER
-
-/*!
- QCompleter that can deal with QFileSystemModel
- */
-class QFSCompleter : public QCompleter {
-public:
- QFSCompleter(QFileSystemModel *model, QObject *parent = 0)
- : QCompleter(model, parent), proxyModel(0), sourceModel(model)
- {
-#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
- setCaseSensitivity(Qt::CaseInsensitive);
-#endif
- }
- QString pathFromIndex(const QModelIndex &index) const;
- QStringList splitPath(const QString& path) const;
-
- QAbstractProxyModel *proxyModel;
- QFileSystemModel *sourceModel;
-};
-#endif // QT_NO_FSCOMPLETER
-QT_END_NAMESPACE
-#endif // QFSCOMPLETOR_P_H
-
diff --git a/src/gui/dialogs/qinputdialog.h b/src/gui/dialogs/qinputdialog.h
deleted file mode 100644
index 7853945130..0000000000
--- a/src/gui/dialogs/qinputdialog.h
+++ /dev/null
@@ -1,256 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QINPUTDIALOG_H
-#define QINPUTDIALOG_H
-
-#include <QtGui/qdialog.h>
-#include <QtCore/qstring.h>
-#include <QtGui/qlineedit.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_INPUTDIALOG
-
-class QInputDialogPrivate;
-
-class Q_GUI_EXPORT QInputDialog : public QDialog
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QInputDialog)
-// Q_ENUMS(InputMode InputDialogOption)
- QDOC_PROPERTY(InputMode inputMode READ inputMode WRITE setInputMode)
- QDOC_PROPERTY(QString labelText READ labelText WRITE setLabelText)
- QDOC_PROPERTY(InputDialogOptions options READ options WRITE setOptions)
- QDOC_PROPERTY(QString textValue READ textValue WRITE setTextValue NOTIFY textValueChanged)
- QDOC_PROPERTY(int intValue READ intValue WRITE setIntValue NOTIFY intValueChanged)
- QDOC_PROPERTY(int doubleValue READ doubleValue WRITE setDoubleValue NOTIFY doubleValueChanged)
- QDOC_PROPERTY(QLineEdit::EchoMode textEchoMode READ textEchoMode WRITE setTextEchoMode)
- QDOC_PROPERTY(bool comboBoxEditable READ isComboBoxEditable WRITE setComboBoxEditable)
- QDOC_PROPERTY(QStringList comboBoxItems READ comboBoxItems WRITE setComboBoxItems)
- QDOC_PROPERTY(int intMinimum READ intMinimum WRITE setIntMinimum)
- QDOC_PROPERTY(int intMaximum READ intMaximum WRITE setIntMaximum)
- QDOC_PROPERTY(int intStep READ intStep WRITE setIntStep)
- QDOC_PROPERTY(double doubleMinimum READ doubleMinimum WRITE setDoubleMinimum)
- QDOC_PROPERTY(double doubleMaximum READ doubleMaximum WRITE setDoubleMaximum)
- QDOC_PROPERTY(int doubleDecimals READ doubleDecimals WRITE setDoubleDecimals)
- QDOC_PROPERTY(QString okButtonText READ okButtonText WRITE setOkButtonText)
- QDOC_PROPERTY(QString cancelButtonText READ cancelButtonText WRITE setCancelButtonText)
-
-public:
- enum InputDialogOption {
- NoButtons = 0x00000001,
- UseListViewForComboBoxItems = 0x00000002
- };
-
- Q_DECLARE_FLAGS(InputDialogOptions, InputDialogOption)
-
- enum InputMode {
- TextInput,
- IntInput,
- DoubleInput
- };
-
- QInputDialog(QWidget *parent = 0, Qt::WindowFlags flags = 0);
- ~QInputDialog();
-
- void setInputMode(InputMode mode);
- InputMode inputMode() const;
-
- void setLabelText(const QString &text);
- QString labelText() const;
-
- void setOption(InputDialogOption option, bool on = true);
- bool testOption(InputDialogOption option) const;
- void setOptions(InputDialogOptions options);
- InputDialogOptions options() const;
-
- void setTextValue(const QString &text);
- QString textValue() const;
-
- void setTextEchoMode(QLineEdit::EchoMode mode);
- QLineEdit::EchoMode textEchoMode() const;
-
- void setComboBoxEditable(bool editable);
- bool isComboBoxEditable() const;
-
- void setComboBoxItems(const QStringList &items);
- QStringList comboBoxItems() const;
-
- void setIntValue(int value);
- int intValue() const;
-
- void setIntMinimum(int min);
- int intMinimum() const;
-
- void setIntMaximum(int max);
- int intMaximum() const;
-
- void setIntRange(int min, int max);
-
- void setIntStep(int step);
- int intStep() const;
-
- void setDoubleValue(double value);
- double doubleValue() const;
-
- void setDoubleMinimum(double min);
- double doubleMinimum() const;
-
- void setDoubleMaximum(double max);
- double doubleMaximum() const;
-
- void setDoubleRange(double min, double max);
-
- void setDoubleDecimals(int decimals);
- int doubleDecimals() const;
-
- void setOkButtonText(const QString &text);
- QString okButtonText() const;
-
- void setCancelButtonText(const QString &text);
- QString cancelButtonText() const;
-
-#ifdef Q_NO_USING_KEYWORD
-#ifndef Q_QDOC
- void open() { QDialog::open(); }
-#endif
-#else
- using QDialog::open;
-#endif
- void open(QObject *receiver, const char *member);
-
- QSize minimumSizeHint() const;
- QSize sizeHint() const;
-
- void setVisible(bool visible);
-
-#ifdef Q_QDOC
- static QString getText(QWidget *parent, const QString &title, const QString &label,
- QLineEdit::EchoMode echo = QLineEdit::Normal,
- const QString &text = QString(), bool *ok = 0, Qt::WindowFlags flags = 0,
- Qt::InputMethodHints inputMethodHints = Qt::ImhNone);
- static QString getItem(QWidget *parent, const QString &title, const QString &label,
- const QStringList &items, int current = 0, bool editable = true,
- bool *ok = 0, Qt::WindowFlags flags = 0,
- Qt::InputMethodHints inputMethodHints = Qt::ImhNone);
-#else
- static QString getText(QWidget *parent, const QString &title, const QString &label,
- QLineEdit::EchoMode echo = QLineEdit::Normal,
- const QString &text = QString(), bool *ok = 0, Qt::WindowFlags flags = 0);
- static QString getItem(QWidget *parent, const QString &title, const QString &label,
- const QStringList &items, int current = 0, bool editable = true,
- bool *ok = 0, Qt::WindowFlags flags = 0);
- static QString getText(QWidget *parent, const QString &title, const QString &label,
- QLineEdit::EchoMode echo,
- const QString &text, bool *ok, Qt::WindowFlags flags,
- Qt::InputMethodHints inputMethodHints);
- static QString getItem(QWidget *parent, const QString &title, const QString &label,
- const QStringList &items, int current, bool editable,
- bool *ok, Qt::WindowFlags flags,
- Qt::InputMethodHints inputMethodHints);
-#endif
- static int getInt(QWidget *parent, const QString &title, const QString &label, int value = 0,
- int minValue = -2147483647, int maxValue = 2147483647,
- int step = 1, bool *ok = 0, Qt::WindowFlags flags = 0);
- static double getDouble(QWidget *parent, const QString &title, const QString &label, double value = 0,
- double minValue = -2147483647, double maxValue = 2147483647,
- int decimals = 1, bool *ok = 0, Qt::WindowFlags flags = 0);
-
- // obsolete
- static int getInteger(QWidget *parent, const QString &title, const QString &label, int value = 0,
- int minValue = -2147483647, int maxValue = 2147483647,
- int step = 1, bool *ok = 0, Qt::WindowFlags flags = 0);
-
-#ifdef QT3_SUPPORT
- inline static QT3_SUPPORT QString getText(const QString &title, const QString &label,
- QLineEdit::EchoMode echo = QLineEdit::Normal,
- const QString &text = QString(), bool *ok = 0,
- QWidget *parent = 0, const char * = 0, Qt::WindowFlags flags = 0)
- { return getText(parent, title, label, echo, text, ok, flags); }
- inline static QT3_SUPPORT int getInteger(const QString &title, const QString &label, int value = 0,
- int minValue = -2147483647, int maxValue = 2147483647,
- int step = 1, bool *ok = 0,
- QWidget *parent = 0, const char * = 0, Qt::WindowFlags flags = 0)
- { return getInteger(parent, title, label, value, minValue, maxValue, step, ok, flags); }
- inline static QT3_SUPPORT double getDouble(const QString &title, const QString &label, double value = 0,
- double minValue = -2147483647, double maxValue = 2147483647,
- int decimals = 1, bool *ok = 0,
- QWidget *parent = 0, const char * = 0, Qt::WindowFlags flags = 0)
- { return getDouble(parent, title, label, value, minValue, maxValue, decimals, ok, flags); }
- inline static QT3_SUPPORT QString getItem(const QString &title, const QString &label, const QStringList &list,
- int current = 0, bool editable = true, bool *ok = 0,
- QWidget *parent = 0, const char * = 0, Qt::WindowFlags flags = 0)
- { return getItem(parent, title, label, list, current, editable, ok, flags); }
-#endif
-
-Q_SIGNALS:
- // ### emit signals!
- void textValueChanged(const QString &text);
- void textValueSelected(const QString &text);
- void intValueChanged(int value);
- void intValueSelected(int value);
- void doubleValueChanged(double value);
- void doubleValueSelected(double value);
-
-
-public:
- void done(int result); // ### Qt 5: Make protected.
-
-private:
- Q_DISABLE_COPY(QInputDialog)
- Q_PRIVATE_SLOT(d_func(), void _q_textChanged(const QString&))
- Q_PRIVATE_SLOT(d_func(), void _q_currentRowChanged(const QModelIndex&, const QModelIndex&))
-};
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QInputDialog::InputDialogOptions)
-
-#endif // QT_NO_INPUTDIALOG
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QINPUTDIALOG_H
diff --git a/src/gui/dialogs/qmessagebox.cpp b/src/gui/dialogs/qmessagebox.cpp
deleted file mode 100644
index 90ca080715..0000000000
--- a/src/gui/dialogs/qmessagebox.cpp
+++ /dev/null
@@ -1,2751 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtGui/qmessagebox.h>
-
-#ifndef QT_NO_MESSAGEBOX
-
-#include <QtGui/qdialogbuttonbox.h>
-#include "private/qlabel_p.h"
-#include "private/qapplication_p.h"
-#include <QtCore/qlist.h>
-#include <QtCore/qdebug.h>
-#include <QtGui/qstyle.h>
-#include <QtGui/qstyleoption.h>
-#include <QtGui/qgridlayout.h>
-#include <QtGui/qdesktopwidget.h>
-#include <QtGui/qpushbutton.h>
-#include <QtGui/qaccessible.h>
-#include <QtGui/qicon.h>
-#include <QtGui/qtextdocument.h>
-#include <QtGui/qapplication.h>
-#include <QtGui/qtextedit.h>
-#include <QtGui/qtextbrowser.h>
-#include <QtGui/qmenu.h>
-#include "qdialog_p.h"
-#include <QtGui/qfont.h>
-#include <QtGui/qfontmetrics.h>
-#include <QtGui/qclipboard.h>
-
-#ifndef QT_NO_STYLE_S60
-#include <qs60style.h>
-#endif
-
-#ifdef Q_WS_WINCE
-extern bool qt_wince_is_mobile(); //defined in qguifunctions_wince.cpp
-extern bool qt_wince_is_smartphone();//defined in qguifunctions_wince.cpp
-extern bool qt_wince_is_pocket_pc(); //defined in qguifunctions_wince.cpp
-
-#include "qguifunctions_wince.h"
-#endif
-
-QT_BEGIN_NAMESPACE
-
-enum Button { Old_Ok = 1, Old_Cancel = 2, Old_Yes = 3, Old_No = 4, Old_Abort = 5, Old_Retry = 6,
- Old_Ignore = 7, Old_YesAll = 8, Old_NoAll = 9, Old_ButtonMask = 0xFF,
- NewButtonMask = 0xFFFFFC00 };
-
-enum DetailButtonLabel { ShowLabel = 0, HideLabel = 1 };
-#ifndef QT_NO_TEXTEDIT
-class QMessageBoxDetailsText : public QWidget
-{
-public:
- class TextEdit : public QTextEdit
- {
- public:
- TextEdit(QWidget *parent=0) : QTextEdit(parent) { }
- void contextMenuEvent(QContextMenuEvent * e)
- {
-#ifndef QT_NO_CONTEXTMENU
- QMenu *menu = createStandardContextMenu();
- menu->setAttribute(Qt::WA_DeleteOnClose);
- menu->popup(e->globalPos());
-#else
- Q_UNUSED(e);
-#endif
- }
- };
-
- QMessageBoxDetailsText(QWidget *parent=0)
- : QWidget(parent)
- {
- QVBoxLayout *layout = new QVBoxLayout;
- layout->setMargin(0);
- QFrame *line = new QFrame(this);
- line->setFrameShape(QFrame::HLine);
- line->setFrameShadow(QFrame::Sunken);
- layout->addWidget(line);
- textEdit = new TextEdit();
- textEdit->setFixedHeight(100);
- textEdit->setFocusPolicy(Qt::NoFocus);
- textEdit->setReadOnly(true);
- layout->addWidget(textEdit);
- setLayout(layout);
- }
- void setText(const QString &text) { textEdit->setPlainText(text); }
- QString text() const { return textEdit->toPlainText(); }
-private:
- TextEdit *textEdit;
-};
-#endif // QT_NO_TEXTEDIT
-
-class DetailButton : public QPushButton
-{
-public:
- DetailButton(QWidget *parent) : QPushButton(label(ShowLabel), parent)
- {
- setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
- }
-
- QString label(DetailButtonLabel label) const
- { return label == ShowLabel ? QMessageBox::tr("Show Details...") : QMessageBox::tr("Hide Details..."); }
-
- void setLabel(DetailButtonLabel lbl)
- { setText(label(lbl)); }
-
- QSize sizeHint() const
- {
- ensurePolished();
- QStyleOptionButton opt;
- initStyleOption(&opt);
- const QFontMetrics fm = fontMetrics();
- opt.text = label(ShowLabel);
- QSize sz = fm.size(Qt::TextShowMnemonic, opt.text);
- QSize ret = style()->sizeFromContents(QStyle::CT_PushButton, &opt, sz, this).
- expandedTo(QApplication::globalStrut());
- opt.text = label(HideLabel);
- sz = fm.size(Qt::TextShowMnemonic, opt.text);
- ret.expandedTo(style()->sizeFromContents(QStyle::CT_PushButton, &opt, sz, this).
- expandedTo(QApplication::globalStrut()));
- return ret;
- }
-};
-
-
-class QMessageBoxPrivate : public QDialogPrivate
-{
- Q_DECLARE_PUBLIC(QMessageBox)
-
-public:
- QMessageBoxPrivate() : escapeButton(0), defaultButton(0), clickedButton(0), detailsButton(0),
-#ifndef QT_NO_TEXTEDIT
- detailsText(0),
-#endif
- compatMode(false), autoAddOkButton(true),
- detectedEscapeButton(0), informativeLabel(0) { }
-
- void init(const QString &title = QString(), const QString &text = QString());
- void _q_buttonClicked(QAbstractButton *);
-
- QAbstractButton *findButton(int button0, int button1, int button2, int flags);
- void addOldButtons(int button0, int button1, int button2);
-
- QAbstractButton *abstractButtonForId(int id) const;
- int execReturnCode(QAbstractButton *button);
-
- void detectEscapeButton();
- void updateSize();
- int layoutMinimumWidth();
- void retranslateStrings();
-
-#ifdef Q_WS_WINCE
- void hideSpecial();
-#endif
-
- static int showOldMessageBox(QWidget *parent, QMessageBox::Icon icon,
- const QString &title, const QString &text,
- int button0, int button1, int button2);
- static int showOldMessageBox(QWidget *parent, QMessageBox::Icon icon,
- const QString &title, const QString &text,
- const QString &button0Text,
- const QString &button1Text,
- const QString &button2Text,
- int defaultButtonNumber,
- int escapeButtonNumber);
-
- static QMessageBox::StandardButton showNewMessageBox(QWidget *parent,
- QMessageBox::Icon icon, const QString& title, const QString& text,
- QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton);
-
- static QPixmap standardIcon(QMessageBox::Icon icon, QMessageBox *mb);
-
- QLabel *label;
- QMessageBox::Icon icon;
- QLabel *iconLabel;
- QDialogButtonBox *buttonBox;
- QList<QAbstractButton *> customButtonList;
- QAbstractButton *escapeButton;
- QPushButton *defaultButton;
- QAbstractButton *clickedButton;
- DetailButton *detailsButton;
-#ifndef QT_NO_TEXTEDIT
- QMessageBoxDetailsText *detailsText;
-#endif
- bool compatMode;
- bool autoAddOkButton;
- QAbstractButton *detectedEscapeButton;
- QLabel *informativeLabel;
-#if defined(Q_OS_SYMBIAN) || defined(Q_WS_MAEMO_5)
- QTextBrowser *textBrowser;
-#endif
- QPointer<QObject> receiverToDisconnectOnClose;
- QByteArray memberToDisconnectOnClose;
- QByteArray signalToDisconnectOnClose;
-};
-
-void QMessageBoxPrivate::init(const QString &title, const QString &text)
-{
- Q_Q(QMessageBox);
-
- label = new QLabel;
- label->setObjectName(QLatin1String("qt_msgbox_label"));
- label->setTextInteractionFlags(Qt::TextInteractionFlags(q->style()->styleHint(QStyle::SH_MessageBox_TextInteractionFlags, 0, q)));
- label->setAlignment(Qt::AlignVCenter | Qt::AlignLeft);
- label->setOpenExternalLinks(true);
-#if defined(Q_WS_MAC)
- label->setContentsMargins(16, 0, 0, 0);
-#elif !defined(Q_WS_QWS)
- label->setContentsMargins(2, 0, 0, 0);
- label->setIndent(9);
-#endif
- icon = QMessageBox::NoIcon;
- iconLabel = new QLabel;
- iconLabel->setObjectName(QLatin1String("qt_msgboxex_icon_label"));
- iconLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
-
- buttonBox = new QDialogButtonBox;
- buttonBox->setObjectName(QLatin1String("qt_msgbox_buttonbox"));
- buttonBox->setCenterButtons(q->style()->styleHint(QStyle::SH_MessageBox_CenterButtons, 0, q));
- QObject::connect(buttonBox, SIGNAL(clicked(QAbstractButton*)),
- q, SLOT(_q_buttonClicked(QAbstractButton*)));
-
- QGridLayout *grid = new QGridLayout;
-#ifndef Q_WS_MAC
- grid->addWidget(iconLabel, 0, 0, 2, 1, Qt::AlignTop);
- grid->addWidget(label, 0, 1, 1, 1);
- // -- leave space for information label --
- grid->addWidget(buttonBox, 2, 0, 1, 2);
-#else
- grid->setMargin(0);
- grid->setVerticalSpacing(8);
- grid->setHorizontalSpacing(0);
- q->setContentsMargins(24, 15, 24, 20);
- grid->addWidget(iconLabel, 0, 0, 2, 1, Qt::AlignTop | Qt::AlignLeft);
- grid->addWidget(label, 0, 1, 1, 1);
- // -- leave space for information label --
- grid->setRowStretch(1, 100);
- grid->setRowMinimumHeight(2, 6);
- grid->addWidget(buttonBox, 3, 1, 1, 1);
-#endif
-
- grid->setSizeConstraint(QLayout::SetNoConstraint);
- q->setLayout(grid);
-
- if (!title.isEmpty() || !text.isEmpty()) {
- q->setWindowTitle(title);
- q->setText(text);
- }
- q->setModal(true);
-
-#ifdef Q_WS_MAC
- QFont f = q->font();
- f.setBold(true);
- label->setFont(f);
-#endif
- retranslateStrings();
-}
-
-int QMessageBoxPrivate::layoutMinimumWidth()
-{
- layout->activate();
- return layout->totalMinimumSize().width();
-}
-
-void QMessageBoxPrivate::updateSize()
-{
- Q_Q(QMessageBox);
-
- if (!q->isVisible())
- return;
-
- QSize screenSize = QApplication::desktop()->availableGeometry(QCursor::pos()).size();
-#if defined(Q_WS_QWS) || defined(Q_WS_WINCE) || defined(Q_OS_SYMBIAN)
- // the width of the screen, less the window border.
- int hardLimit = screenSize.width() - (q->frameGeometry().width() - q->geometry().width());
-#else
- int hardLimit = qMin(screenSize.width() - 480, 1000); // can never get bigger than this
- // on small screens allows the messagebox be the same size as the screen
- if (screenSize.width() <= 1024)
- hardLimit = screenSize.width();
-#endif
-#ifdef Q_WS_MAC
- int softLimit = qMin(screenSize.width()/2, 420);
-#elif defined(Q_WS_QWS)
- int softLimit = qMin(hardLimit, 500);
-#else
- // note: ideally on windows, hard and soft limits but it breaks compat
-#ifndef Q_WS_WINCE
- int softLimit = qMin(screenSize.width()/2, 500);
-#else
- int softLimit = qMin(screenSize.width() * 3 / 4, 500);
-#endif //Q_WS_WINCE
-#endif
-
- if (informativeLabel)
- informativeLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
-
- label->setWordWrap(false); // makes the label return min size
- int width = layoutMinimumWidth();
-
- if (width > softLimit) {
- label->setWordWrap(true);
- width = qMax(softLimit, layoutMinimumWidth());
-
- if (width > hardLimit) {
- label->d_func()->ensureTextControl();
- if (QTextControl *control = label->d_func()->control) {
- QTextOption opt = control->document()->defaultTextOption();
- opt.setWrapMode(QTextOption::WrapAnywhere);
- control->document()->setDefaultTextOption(opt);
- }
- width = hardLimit;
- }
- }
-#ifdef Q_WS_S60
- // in S60 portait messageBoxes should always occupy maximum width
- if (QApplication::desktop()->size().height() > QApplication::desktop()->size().width()){
- width = hardLimit;
- } else {
- // in landscape the messageBoxes should be of same width as in portrait
- width = qMin(QApplication::desktop()->size().height(), hardLimit);
- }
-#endif
-
- if (informativeLabel) {
- label->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
- QSizePolicy policy(QSizePolicy::Minimum, QSizePolicy::Preferred);
- policy.setHeightForWidth(true);
- informativeLabel->setSizePolicy(policy);
- width = qMax(width, layoutMinimumWidth());
- if (width > hardLimit) { // longest word is really big, so wrap anywhere
- informativeLabel->d_func()->ensureTextControl();
- if (QTextControl *control = informativeLabel->d_func()->control) {
- QTextOption opt = control->document()->defaultTextOption();
- opt.setWrapMode(QTextOption::WrapAnywhere);
- control->document()->setDefaultTextOption(opt);
- }
- width = hardLimit;
- }
- policy.setHeightForWidth(label->wordWrap());
- label->setSizePolicy(policy);
- }
-
- QFontMetrics fm(QApplication::font("QWorkspaceTitleBar"));
- int windowTitleWidth = qMin(fm.width(q->windowTitle()) + 50, hardLimit);
- if (windowTitleWidth > width)
- width = windowTitleWidth;
-
- layout->activate();
- int height = (layout->hasHeightForWidth())
- ? layout->totalHeightForWidth(width)
- : layout->totalMinimumSize().height();
-
-#ifndef QT_NO_STYLE_S60
- QS60Style *s60Style = 0;
- s60Style = qobject_cast<QS60Style *>(QApplication::style());
-
- //use custom pixel metric to deduce the minimum height of the messagebox
- if (s60Style)
- height = qMax(height, s60Style->pixelMetric((QStyle::PixelMetric)PM_MessageBoxHeight));
-#endif
-
- q->setFixedSize(width, height);
- QCoreApplication::removePostedEvents(q, QEvent::LayoutRequest);
-}
-
-
-#ifdef Q_WS_WINCE
-/*!
- \internal
- Hides special buttons which are rather shown in the title bar
- on WinCE, to conserve screen space.
-*/
-
-void QMessageBoxPrivate::hideSpecial()
-{
- Q_Q(QMessageBox);
- QList<QPushButton*> list = q->findChildren<QPushButton*>();
- for (int i=0; i<list.size(); ++i) {
- QPushButton *pb = list.at(i);
- QString text = pb->text();
- text.remove(QChar::fromLatin1('&'));
- if (text == QApplication::translate("QMessageBox", "OK" ))
- pb->setFixedSize(0,0);
- }
-}
-#endif
-
-static int oldButton(int button)
-{
- switch (button & QMessageBox::ButtonMask) {
- case QMessageBox::Ok:
- return Old_Ok;
- case QMessageBox::Cancel:
- return Old_Cancel;
- case QMessageBox::Yes:
- return Old_Yes;
- case QMessageBox::No:
- return Old_No;
- case QMessageBox::Abort:
- return Old_Abort;
- case QMessageBox::Retry:
- return Old_Retry;
- case QMessageBox::Ignore:
- return Old_Ignore;
- case QMessageBox::YesToAll:
- return Old_YesAll;
- case QMessageBox::NoToAll:
- return Old_NoAll;
- default:
- return 0;
- }
-}
-
-int QMessageBoxPrivate::execReturnCode(QAbstractButton *button)
-{
- int ret = buttonBox->standardButton(button);
- if (ret == QMessageBox::NoButton) {
- ret = customButtonList.indexOf(button); // if button == 0, correctly sets ret = -1
- } else if (compatMode) {
- ret = oldButton(ret);
- }
- return ret;
-}
-
-void QMessageBoxPrivate::_q_buttonClicked(QAbstractButton *button)
-{
- Q_Q(QMessageBox);
-#ifndef QT_NO_TEXTEDIT
- if (detailsButton && detailsText && button == detailsButton) {
- detailsButton->setLabel(detailsText->isHidden() ? HideLabel : ShowLabel);
- detailsText->setHidden(!detailsText->isHidden());
- updateSize();
- } else
-#endif
- {
- clickedButton = button;
- q->done(execReturnCode(button)); // does not trigger closeEvent
- emit q->buttonClicked(button);
-
- if (receiverToDisconnectOnClose) {
- QObject::disconnect(q, signalToDisconnectOnClose, receiverToDisconnectOnClose,
- memberToDisconnectOnClose);
- receiverToDisconnectOnClose = 0;
- }
- signalToDisconnectOnClose.clear();
- memberToDisconnectOnClose.clear();
- }
-}
-
-/*!
- \class QMessageBox
-
- \brief The QMessageBox class provides a modal dialog for informing
- the user or for asking the user a question and receiving an answer.
-
- \ingroup standard-dialogs
-
-
- A message box displays a primary \l{QMessageBox::text}{text} to
- alert the user to a situation, an \l{QMessageBox::informativeText}
- {informative text} to further explain the alert or to ask the user
- a question, and an optional \l{QMessageBox::detailedText}
- {detailed text} to provide even more data if the user requests
- it. A message box can also display an \l{QMessageBox::icon} {icon}
- and \l{QMessageBox::standardButtons} {standard buttons} for
- accepting a user response.
-
- Two APIs for using QMessageBox are provided, the property-based
- API, and the static functions. Calling one of the static functions
- is the simpler approach, but it is less flexible than using the
- property-based API, and the result is less informative. Using the
- property-based API is recommended.
-
- \section1 The Property-based API
-
- To use the property-based API, construct an instance of
- QMessageBox, set the desired properties, and call exec() to show
- the message. The simplest configuration is to set only the
- \l{QMessageBox::text} {message text} property.
-
- \snippet doc/src/snippets/code/src_gui_dialogs_qmessagebox.cpp 5
-
- The user must click the \gui{OK} button to dismiss the message
- box. The rest of the GUI is blocked until the message box is
- dismissed.
-
- \image msgbox1.png
-
- A better approach than just alerting the user to an event is to
- also ask the user what to do about it. Store the question in the
- \l{QMessageBox::informativeText} {informative text} property, and
- set the \l{QMessageBox::standardButtons} {standard buttons}
- property to the set of buttons you want as the set of user
- responses. The buttons are specified by combining values from
- StandardButtons using the bitwise OR operator. The display order
- for the buttons is platform-dependent. For example, on Windows,
- \gui{Save} is displayed to the left of \gui{Cancel}, whereas on
- Mac OS, the order is reversed.
-
- Mark one of your standard buttons to be your
- \l{QMessageBox::defaultButton()} {default button}.
-
- \snippet doc/src/snippets/code/src_gui_dialogs_qmessagebox.cpp 6
-
- This is the approach recommended in the
- \l{http://developer.apple.com/documentation/UserExperience/Conceptual/AppleHIGuidelines/XHIGWindows/chapter_18_section_7.html}
- {Mac OS X Guidlines}. Similar guidlines apply for the other
- platforms, but note the different ways the
- \l{QMessageBox::informativeText} {informative text} is handled for
- different platforms.
-
- \image msgbox2.png
-
- The exec() slot returns the StandardButtons value of the button
- that was clicked.
-
- \snippet doc/src/snippets/code/src_gui_dialogs_qmessagebox.cpp 7
-
- To give the user more information to help him answer the question,
- set the \l{QMessageBox::detailedText} {detailed text} property. If
- the \l{QMessageBox::detailedText} {detailed text} property is set,
- the \gui{Show Details...} button will be shown.
-
- \image msgbox3.png
-
- Clicking the \gui{Show Details...} button displays the detailed text.
-
- \image msgbox4.png
-
- \section2 Rich Text and the Text Format Property
-
- The \l{QMessageBox::detailedText} {detailed text} property is
- always interpreted as plain text. The \l{QMessageBox::text} {main
- text} and \l{QMessageBox::informativeText} {informative text}
- properties can be either plain text or rich text. These strings
- are interpreted according to the setting of the
- \l{QMessageBox::textFormat} {text format} property. The default
- setting is \l{Qt::AutoText} {auto-text}.
-
- Note that for some plain text strings containing XML
- meta-characters, the auto-text \l{Qt::mightBeRichText()} {rich
- text detection test} may fail causing your plain text string to be
- interpreted incorrectly as rich text. In these rare cases, use
- Qt::convertFromPlainText() to convert your plain text string to a
- visually equivalent rich text string, or set the
- \l{QMessageBox::textFormat} {text format} property explicitly with
- setTextFormat().
-
- \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
- guidelines:
-
- \table
- \row
- \o \img qmessagebox-quest.png
- \o \l Question
- \o For asking a question during normal operations.
- \row
- \o \img qmessagebox-info.png
- \o \l Information
- \o For reporting information about normal operations.
- \row
- \o \img qmessagebox-warn.png
- \o \l Warning
- \o For reporting non-critical errors.
- \row
- \o \img qmessagebox-crit.png
- \o \l Critical
- \o For reporting critical errors.
- \endtable
-
- \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
-
- Building message boxes with the static functions API, although
- convenient, is less flexible than using the property-based API,
- because the static function signatures lack parameters for setting
- the \l{QMessageBox::informativeText} {informative text} and
- \l{QMessageBox::detailedText} {detailed text} properties. One
- work-around for this has been to use the \c{title} parameter as
- the message box main text and the \c{text} parameter as the
- message box informative text. Because this has the obvious
- drawback of making a less readable message box, platform
- guidelines do not recommend it. The \e{Microsoft Windows User
- Interface Guidelines} recommend using the
- \l{QCoreApplication::applicationName} {application name} as the
- \l{QMessageBox::setWindowTitle()} {window's title}, which means
- that if you have an informative text in addition to your main
- text, you must concatenate it to the \c{text} parameter.
-
- Note that the static function signatures have changed with respect
- to their button parameters, which are now used to set the
- \l{QMessageBox::standardButtons} {standard buttons} and the
- \l{QMessageBox::defaultButton()} {default button}.
-
- Static functions are available for creating information(),
- question(), warning(), and critical() message boxes.
-
- \snippet doc/src/snippets/code/src_gui_dialogs_qmessagebox.cpp 0
-
- The \l{dialogs/standarddialogs}{Standard Dialogs} example shows
- how to use QMessageBox and the other built-in Qt dialogs.
-
- \section1 Advanced Usage
-
- If the \l{QMessageBox::StandardButtons} {standard buttons} are not
- flexible enough for your message box, you can use the addButton()
- overload that takes a text and a ButtonRoleto to add custom
- buttons. The ButtonRole is used by QMessageBox to determine the
- ordering of the buttons on screen (which varies according to the
- platform). You can test the value of clickedButton() after calling
- exec(). For example,
-
- \snippet doc/src/snippets/code/src_gui_dialogs_qmessagebox.cpp 2
-
- \section1 Default and Escape Keys
-
- The default button (i.e., the button activated when \key Enter is
- pressed) can be specified using setDefaultButton(). If a default
- button is not specified, QMessageBox tries to find one based on
- the \l{ButtonRole} {button roles} of the buttons used in the
- message box.
-
- The escape button (the button activated when \key Esc is pressed)
- can be specified using setEscapeButton(). If an escape button is
- not specified, QMessageBox tries to find one using these rules:
-
- \list 1
-
- \o If there is only one button, it is the button activated when
- \key Esc is pressed.
-
- \o If there is a \l Cancel button, it is the button activated when
- \key Esc is pressed.
-
- \o If there is exactly one button having either
- \l{QMessageBox::RejectRole} {the Reject role} or the
- \l{QMessageBox::NoRole} {the No role}, it is the button
- activated when \key Esc is pressed.
-
- \endlist
-
- When an escape button can't be determined using these rules,
- pressing \key Esc has no effect.
-
- \sa QDialogButtonBox, {fowler}{GUI Design Handbook: Message Box}, {Standard Dialogs Example}, {Application Example}
-*/
-
-/*!
- \enum QMessageBox::StandardButton
- \since 4.2
-
- These enums describe flags for standard buttons. Each button has a
- defined \l ButtonRole.
-
- \value Ok An "OK" button defined with the \l AcceptRole.
- \value Open A "Open" button defined with the \l AcceptRole.
- \value Save A "Save" button defined with the \l AcceptRole.
- \value Cancel A "Cancel" button defined with the \l RejectRole.
- \value Close A "Close" button defined with the \l RejectRole.
- \value Discard A "Discard" or "Don't Save" button, depending on the platform,
- defined with the \l DestructiveRole.
- \value Apply An "Apply" button defined with the \l ApplyRole.
- \value Reset A "Reset" button defined with the \l ResetRole.
- \value RestoreDefaults A "Restore Defaults" button defined with the \l ResetRole.
- \value Help A "Help" button defined with the \l HelpRole.
- \value SaveAll A "Save All" button defined with the \l AcceptRole.
- \value Yes A "Yes" button defined with the \l YesRole.
- \value YesToAll A "Yes to All" button defined with the \l YesRole.
- \value No A "No" button defined with the \l NoRole.
- \value NoToAll A "No to All" button defined with the \l NoRole.
- \value Abort An "Abort" button defined with the \l RejectRole.
- \value Retry A "Retry" button defined with the \l AcceptRole.
- \value Ignore An "Ignore" button defined with the \l AcceptRole.
-
- \value NoButton An invalid button.
-
- \omitvalue FirstButton
- \omitvalue LastButton
-
- The following values are obsolete:
-
- \value YesAll Use YesToAll instead.
- \value NoAll Use NoToAll instead.
- \value Default Use the \c defaultButton argument of
- information(), warning(), etc. instead, or call
- setDefaultButton().
- \value Escape Call setEscapeButton() instead.
- \value FlagMask
- \value ButtonMask
-
- \sa ButtonRole, standardButtons
-*/
-
-/*!
- \fn void QMessageBox::buttonClicked(QAbstractButton *button)
-
- This signal is emitted whenever a button is clicked inside the QMessageBox.
- The button that was clicked in returned in \a button.
-*/
-
-/*!
- Constructs a message box with no text and no buttons. \a parent is
- passed to the QDialog constructor.
-
- On Mac OS X, if you want your message box to appear
- as a Qt::Sheet of its \a parent, set the message box's
- \l{setWindowModality()} {window modality} to Qt::WindowModal or use open().
- Otherwise, the message box will be a standard dialog.
-
-*/
-QMessageBox::QMessageBox(QWidget *parent)
- : QDialog(*new QMessageBoxPrivate, parent, Qt::MSWindowsFixedSizeDialogHint | Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint)
-{
- Q_D(QMessageBox);
- d->init();
-}
-
-/*!
- Constructs a message box with the given \a icon, \a title, \a
- text, and standard \a buttons. Standard or custom buttons can be
- added at any time using addButton(). The \a parent and \a f
- arguments are passed to the QDialog constructor.
-
- The message box is an \l{Qt::ApplicationModal} {application modal}
- dialog box.
-
- On Mac OS X, if \a parent is not 0 and you want your message box
- to appear as a Qt::Sheet of that parent, set the message box's
- \l{setWindowModality()} {window modality} to Qt::WindowModal
- (default). Otherwise, the message box will be a standard dialog.
-
- \sa setWindowTitle(), setText(), setIcon(), setStandardButtons()
-*/
-QMessageBox::QMessageBox(Icon icon, const QString &title, const QString &text,
- StandardButtons buttons, QWidget *parent,
- Qt::WindowFlags f)
-: QDialog(*new QMessageBoxPrivate, parent, f | Qt::MSWindowsFixedSizeDialogHint | Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint)
-{
- Q_D(QMessageBox);
- d->init(title, text);
- setIcon(icon);
- if (buttons != NoButton)
- setStandardButtons(buttons);
-}
-
-/*!
- Destroys the message box.
-*/
-QMessageBox::~QMessageBox()
-{
-}
-
-/*!
- \since 4.2
-
- Adds the given \a button to the message box with the specified \a
- role.
-
- \sa removeButton(), button(), setStandardButtons()
-*/
-void QMessageBox::addButton(QAbstractButton *button, ButtonRole role)
-{
- Q_D(QMessageBox);
- if (!button)
- return;
- removeButton(button);
- d->buttonBox->addButton(button, (QDialogButtonBox::ButtonRole)role);
- d->customButtonList.append(button);
- d->autoAddOkButton = false;
-}
-
-/*!
- \since 4.2
- \overload
-
- Creates a button with the given \a text, adds it to the message box for the
- specified \a role, and returns it.
-*/
-QPushButton *QMessageBox::addButton(const QString& text, ButtonRole role)
-{
- Q_D(QMessageBox);
- QPushButton *pushButton = new QPushButton(text);
- addButton(pushButton, role);
- d->updateSize();
- return pushButton;
-}
-
-/*!
- \since 4.2
- \overload
-
- Adds a standard \a button to the message box if it is valid to do so, and
- returns the push button.
-
- \sa setStandardButtons()
-*/
-QPushButton *QMessageBox::addButton(StandardButton button)
-{
- Q_D(QMessageBox);
- QPushButton *pushButton = d->buttonBox->addButton((QDialogButtonBox::StandardButton)button);
- if (pushButton)
- d->autoAddOkButton = false;
- return pushButton;
-}
-
-/*!
- \since 4.2
-
- Removes \a button from the button box without deleting it.
-
- \sa addButton(), setStandardButtons()
-*/
-void QMessageBox::removeButton(QAbstractButton *button)
-{
- Q_D(QMessageBox);
- d->customButtonList.removeAll(button);
- if (d->escapeButton == button)
- d->escapeButton = 0;
- if (d->defaultButton == button)
- d->defaultButton = 0;
- d->buttonBox->removeButton(button);
- d->updateSize();
-}
-
-/*!
- \property QMessageBox::standardButtons
- \brief collection of standard buttons in the message box
- \since 4.2
-
- This property controls which standard buttons are used by the message box.
-
- By default, this property contains no standard buttons.
-
- \sa addButton()
-*/
-void QMessageBox::setStandardButtons(StandardButtons buttons)
-{
- Q_D(QMessageBox);
- d->buttonBox->setStandardButtons(QDialogButtonBox::StandardButtons(int(buttons)));
-
- QList<QAbstractButton *> buttonList = d->buttonBox->buttons();
- if (!buttonList.contains(d->escapeButton))
- d->escapeButton = 0;
- if (!buttonList.contains(d->defaultButton))
- d->defaultButton = 0;
- d->autoAddOkButton = false;
- d->updateSize();
-}
-
-QMessageBox::StandardButtons QMessageBox::standardButtons() const
-{
- Q_D(const QMessageBox);
- return QMessageBox::StandardButtons(int(d->buttonBox->standardButtons()));
-}
-
-/*!
- \since 4.2
-
- Returns the standard button enum value corresponding to the given \a button,
- or NoButton if the given \a button isn't a standard button.
-
- \sa button(), standardButtons()
-*/
-QMessageBox::StandardButton QMessageBox::standardButton(QAbstractButton *button) const
-{
- Q_D(const QMessageBox);
- return (QMessageBox::StandardButton)d->buttonBox->standardButton(button);
-}
-
-/*!
- \since 4.2
-
- Returns a pointer corresponding to the standard button \a which,
- or 0 if the standard button doesn't exist in this message box.
-
- \sa standardButtons, standardButton()
-*/
-QAbstractButton *QMessageBox::button(StandardButton which) const
-{
- Q_D(const QMessageBox);
- return d->buttonBox->button(QDialogButtonBox::StandardButton(which));
-}
-
-/*!
- \since 4.2
-
- Returns the button that is activated when escape is pressed.
-
- By default, QMessageBox attempts to automatically detect an
- escape button as follows:
-
- \list 1
- \o If there is only one button, it is made the escape button.
- \o If there is a \l Cancel button, it is made the escape button.
- \o On Mac OS X only, if there is exactly one button with the role
- QMessageBox::RejectRole, it is made the escape button.
- \endlist
-
- When an escape button could not be automatically detected, pressing
- \key Esc has no effect.
-
- \sa addButton()
-*/
-QAbstractButton *QMessageBox::escapeButton() const
-{
- Q_D(const QMessageBox);
- return d->escapeButton;
-}
-
-/*!
- \since 4.2
-
- Sets the button that gets activated when the \key Escape key is
- pressed to \a button.
-
- \sa addButton(), clickedButton()
-*/
-void QMessageBox::setEscapeButton(QAbstractButton *button)
-{
- Q_D(QMessageBox);
- if (d->buttonBox->buttons().contains(button))
- d->escapeButton = button;
-}
-
-/*!
- \since 4.3
-
- Sets the buttons that gets activated when the \key Escape key is
- pressed to \a button.
-
- \sa addButton(), clickedButton()
-*/
-void QMessageBox::setEscapeButton(QMessageBox::StandardButton button)
-{
- Q_D(QMessageBox);
- setEscapeButton(d->buttonBox->button(QDialogButtonBox::StandardButton(button)));
-}
-
-void QMessageBoxPrivate::detectEscapeButton()
-{
- if (escapeButton) { // escape button explicitly set
- detectedEscapeButton = escapeButton;
- return;
- }
-
- // Cancel button automatically becomes escape button
- detectedEscapeButton = buttonBox->button(QDialogButtonBox::Cancel);
- if (detectedEscapeButton)
- return;
-
- // If there is only one button, make it the escape button
- const QList<QAbstractButton *> buttons = buttonBox->buttons();
- if (buttons.count() == 1) {
- detectedEscapeButton = buttons.first();
- return;
- }
-
- // if the message box has one RejectRole button, make it the escape button
- for (int i = 0; i < buttons.count(); i++) {
- if (buttonBox->buttonRole(buttons.at(i)) == QDialogButtonBox::RejectRole) {
- if (detectedEscapeButton) { // already detected!
- detectedEscapeButton = 0;
- break;
- }
- detectedEscapeButton = buttons.at(i);
- }
- }
- if (detectedEscapeButton)
- return;
-
- // if the message box has one NoRole button, make it the escape button
- for (int i = 0; i < buttons.count(); i++) {
- if (buttonBox->buttonRole(buttons.at(i)) == QDialogButtonBox::NoRole) {
- if (detectedEscapeButton) { // already detected!
- detectedEscapeButton = 0;
- break;
- }
- detectedEscapeButton = buttons.at(i);
- }
- }
-}
-
-/*!
- \since 4.2
-
- Returns the button that was clicked by the user,
- or 0 if the user hit the \key Esc key and
- no \l{setEscapeButton()}{escape button} was set.
-
- If exec() hasn't been called yet, returns 0.
-
- Example:
-
- \snippet doc/src/snippets/code/src_gui_dialogs_qmessagebox.cpp 3
-
- \sa standardButton(), button()
-*/
-QAbstractButton *QMessageBox::clickedButton() const
-{
- Q_D(const QMessageBox);
- return d->clickedButton;
-}
-
-/*!
- \since 4.2
-
- Returns the button that should be the message box's
- \l{QPushButton::setDefault()}{default button}. Returns 0
- if no default button was set.
-
- \sa addButton(), QPushButton::setDefault()
-*/
-QPushButton *QMessageBox::defaultButton() const
-{
- Q_D(const QMessageBox);
- return d->defaultButton;
-}
-
-/*!
- \since 4.2
-
- Sets the message box's \l{QPushButton::setDefault()}{default button}
- to \a button.
-
- \sa addButton(), QPushButton::setDefault()
-*/
-void QMessageBox::setDefaultButton(QPushButton *button)
-{
- Q_D(QMessageBox);
- if (!d->buttonBox->buttons().contains(button))
- return;
- d->defaultButton = button;
- button->setDefault(true);
- button->setFocus();
-}
-
-/*!
- \since 4.3
-
- Sets the message box's \l{QPushButton::setDefault()}{default button}
- to \a button.
-
- \sa addButton(), QPushButton::setDefault()
-*/
-void QMessageBox::setDefaultButton(QMessageBox::StandardButton button)
-{
- Q_D(QMessageBox);
- setDefaultButton(d->buttonBox->button(QDialogButtonBox::StandardButton(button)));
-}
-
-/*!
- \property QMessageBox::text
- \brief the message box text to be displayed.
-
- The text will be interpreted either as a plain text or as rich text,
- depending on the text format setting (\l QMessageBox::textFormat).
- The default setting is Qt::AutoText, i.e., the message box will try
- to auto-detect the format of the text.
-
- The default value of this property is an empty string.
-
- \sa textFormat, QMessageBox::informativeText, QMessageBox::detailedText
-*/
-QString QMessageBox::text() const
-{
- Q_D(const QMessageBox);
- return d->label->text();
-}
-
-void QMessageBox::setText(const QString &text)
-{
- Q_D(QMessageBox);
- d->label->setText(text);
- d->label->setWordWrap(d->label->textFormat() == Qt::RichText
- || (d->label->textFormat() == Qt::AutoText && Qt::mightBeRichText(text)));
- d->updateSize();
-}
-
-/*!
- \enum QMessageBox::Icon
-
- This enum has the following values:
-
- \value NoIcon the message box does not have any icon.
-
- \value Question an icon indicating that
- the message is asking a question.
-
- \value Information an icon indicating that
- the message is nothing out of the ordinary.
-
- \value Warning an icon indicating that the
- message is a warning, but can be dealt with.
-
- \value Critical an icon indicating that
- the message represents a critical problem.
-
-*/
-
-/*!
- \property QMessageBox::icon
- \brief the message box's icon
-
- The icon of the message box can be specified with one of the
- values:
-
- \list
- \o QMessageBox::NoIcon
- \o QMessageBox::Question
- \o QMessageBox::Information
- \o QMessageBox::Warning
- \o QMessageBox::Critical
- \endlist
-
- The default is QMessageBox::NoIcon.
-
- The pixmap used to display the actual icon depends on the current
- \l{QWidget::style()} {GUI style}. You can also set a custom pixmap
- for the icon by setting the \l{QMessageBox::iconPixmap} {icon
- pixmap} property.
-
- \sa iconPixmap
-*/
-QMessageBox::Icon QMessageBox::icon() const
-{
- Q_D(const QMessageBox);
- return d->icon;
-}
-
-void QMessageBox::setIcon(Icon icon)
-{
- Q_D(QMessageBox);
- setIconPixmap(QMessageBoxPrivate::standardIcon((QMessageBox::Icon)icon,
- this));
- d->icon = icon;
-}
-
-/*!
- \property QMessageBox::iconPixmap
- \brief the current icon
-
- The icon currently used by the message box. Note that it's often
- hard to draw one pixmap that looks appropriate in all GUI styles;
- you may want to supply a different pixmap for each platform.
-
- By default, this property is undefined.
-
- \sa icon
-*/
-QPixmap QMessageBox::iconPixmap() const
-{
- Q_D(const QMessageBox);
- if (d->iconLabel && d->iconLabel->pixmap())
- return *d->iconLabel->pixmap();
- return QPixmap();
-}
-
-void QMessageBox::setIconPixmap(const QPixmap &pixmap)
-{
- Q_D(QMessageBox);
- d->iconLabel->setPixmap(pixmap);
- d->updateSize();
- d->icon = NoIcon;
-}
-
-/*!
- \property QMessageBox::textFormat
- \brief the format of the text displayed by the message box
-
- The current text format used by the message box. See the \l
- Qt::TextFormat enum for an explanation of the possible options.
-
- The default format is Qt::AutoText.
-
- \sa setText()
-*/
-Qt::TextFormat QMessageBox::textFormat() const
-{
- Q_D(const QMessageBox);
- return d->label->textFormat();
-}
-
-void QMessageBox::setTextFormat(Qt::TextFormat format)
-{
- Q_D(QMessageBox);
- d->label->setTextFormat(format);
- d->label->setWordWrap(format == Qt::RichText
- || (format == Qt::AutoText && Qt::mightBeRichText(d->label->text())));
- d->updateSize();
-}
-
-/*!
- \reimp
-*/
-bool QMessageBox::event(QEvent *e)
-{
- bool result =QDialog::event(e);
- switch (e->type()) {
- case QEvent::LayoutRequest:
- d_func()->updateSize();
- break;
- case QEvent::LanguageChange:
- d_func()->retranslateStrings();
- break;
-#ifdef Q_WS_WINCE
- case QEvent::OkRequest:
- case QEvent::HelpRequest: {
- QString bName =
- (e->type() == QEvent::OkRequest)
- ? QApplication::translate("QMessageBox", "OK")
- : QApplication::translate("QMessageBox", "Help");
- QList<QPushButton*> list = findChildren<QPushButton*>();
- for (int i=0; i<list.size(); ++i) {
- QPushButton *pb = list.at(i);
- if (pb->text() == bName) {
- if (pb->isEnabled())
- pb->click();
- return pb->isEnabled();
- }
- }
- }
-#endif
- default:
- break;
- }
- return result;
-}
-
-/*!
- \reimp
-*/
-void QMessageBox::resizeEvent(QResizeEvent *event)
-{
- QDialog::resizeEvent(event);
-}
-
-/*!
- \reimp
-*/
-void QMessageBox::closeEvent(QCloseEvent *e)
-{
- Q_D(QMessageBox);
- if (!d->detectedEscapeButton) {
- e->ignore();
- return;
- }
- QDialog::closeEvent(e);
- d->clickedButton = d->detectedEscapeButton;
- setResult(d->execReturnCode(d->detectedEscapeButton));
-}
-
-/*!
- \reimp
-*/
-void QMessageBox::changeEvent(QEvent *ev)
-{
- Q_D(QMessageBox);
- switch (ev->type()) {
- case QEvent::StyleChange:
- {
- if (d->icon != NoIcon)
- setIcon(d->icon);
- Qt::TextInteractionFlags flags(style()->styleHint(QStyle::SH_MessageBox_TextInteractionFlags, 0, this));
- d->label->setTextInteractionFlags(flags);
- d->buttonBox->setCenterButtons(style()->styleHint(QStyle::SH_MessageBox_CenterButtons, 0, this));
- if (d->informativeLabel)
- d->informativeLabel->setTextInteractionFlags(flags);
- // intentional fall through
- }
- case QEvent::FontChange:
- case QEvent::ApplicationFontChange:
-#ifdef Q_WS_MAC
- {
- QFont f = font();
- f.setBold(true);
- d->label->setFont(f);
- }
-#endif
- default:
- break;
- }
- QDialog::changeEvent(ev);
-}
-
-/*!
- \reimp
-*/
-void QMessageBox::keyPressEvent(QKeyEvent *e)
-{
- Q_D(QMessageBox);
- if (e->key() == Qt::Key_Escape
-#ifdef Q_WS_MAC
- || (e->modifiers() == Qt::ControlModifier && e->key() == Qt::Key_Period)
-#endif
- ) {
- if (d->detectedEscapeButton) {
-#ifdef Q_WS_MAC
- d->detectedEscapeButton->animateClick();
-#else
- d->detectedEscapeButton->click();
-#endif
- }
- return;
- }
-
-#if defined (Q_OS_WIN) && !defined(QT_NO_CLIPBOARD) && !defined(QT_NO_SHORTCUT)
- if (e == QKeySequence::Copy) {
- QString separator = QString::fromLatin1("---------------------------\n");
- QString textToCopy = separator;
- separator.prepend(QLatin1Char('\n'));
- textToCopy += windowTitle() + separator; // title
- textToCopy += d->label->text() + separator; // text
-
- if (d->informativeLabel)
- textToCopy += d->informativeLabel->text() + separator;
-
- QString buttonTexts;
- QList<QAbstractButton *> buttons = d->buttonBox->buttons();
- for (int i = 0; i < buttons.count(); i++) {
- buttonTexts += buttons[i]->text() + QLatin1String(" ");
- }
- textToCopy += buttonTexts + separator;
-
- QApplication::clipboard()->setText(textToCopy);
- return;
- }
-#endif //QT_NO_SHORTCUT QT_NO_CLIPBOARD Q_OS_WIN
-
-#ifndef QT_NO_SHORTCUT
- if (!(e->modifiers() & Qt::AltModifier)) {
- int key = e->key() & ~((int)Qt::MODIFIER_MASK|(int)Qt::UNICODE_ACCEL);
- if (key) {
- const QList<QAbstractButton *> buttons = d->buttonBox->buttons();
- for (int i = 0; i < buttons.count(); ++i) {
- QAbstractButton *pb = buttons.at(i);
- int acc = pb->shortcut() & ~((int)Qt::MODIFIER_MASK|(int)Qt::UNICODE_ACCEL);
- if (acc == key) {
- pb->animateClick();
- return;
- }
- }
- }
- }
-#endif
- QDialog::keyPressEvent(e);
-}
-
-#ifdef Q_WS_WINCE
-/*!
- \reimp
-*/
-void QMessageBox::setVisible(bool visible)
-{
- Q_D(QMessageBox);
- if (visible)
- d->hideSpecial();
- QDialog::setVisible(visible);
-}
-#endif
-
-
-/*!
- \overload
-
- Opens the dialog and connects its finished() or buttonClicked() signal to
- the slot specified by \a receiver and \a member. If the slot in \a member
- has a pointer for its first parameter the connection is to buttonClicked(),
- otherwise the connection is to finished().
-
- The signal will be disconnected from the slot when the dialog is closed.
-*/
-void QMessageBox::open(QObject *receiver, const char *member)
-{
- Q_D(QMessageBox);
- const char *signal = member && strchr(member, '*') ? SIGNAL(buttonClicked(QAbstractButton*))
- : SIGNAL(finished(int));
- connect(this, signal, receiver, member);
- d->signalToDisconnectOnClose = signal;
- d->receiverToDisconnectOnClose = receiver;
- d->memberToDisconnectOnClose = member;
- QDialog::open();
-}
-
-/*!
- \since 4.5
-
- Returns a list of all the buttons that have been added to the message box.
-
- \sa buttonRole(), addButton(), removeButton()
-*/
-QList<QAbstractButton *> QMessageBox::buttons() const
-{
- Q_D(const QMessageBox);
- return d->buttonBox->buttons();
-}
-
-/*!
- \since 4.5
-
- Returns the button role for the specified \a button. This function returns
- \l InvalidRole if \a button is 0 or has not been added to the message box.
-
- \sa buttons(), addButton()
-*/
-QMessageBox::ButtonRole QMessageBox::buttonRole(QAbstractButton *button) const
-{
- Q_D(const QMessageBox);
- return QMessageBox::ButtonRole(d->buttonBox->buttonRole(button));
-}
-
-/*!
- \reimp
-*/
-void QMessageBox::showEvent(QShowEvent *e)
-{
- Q_D(QMessageBox);
- if (d->autoAddOkButton) {
- addButton(Ok);
-#if defined(Q_WS_WINCE)
- d->hideSpecial();
-#endif
- }
- if (d->detailsButton)
- addButton(d->detailsButton, QMessageBox::ActionRole);
- d->detectEscapeButton();
- d->updateSize();
-
-#ifndef QT_NO_ACCESSIBILITY
- QAccessible::updateAccessibility(this, 0, QAccessible::Alert);
-#endif
-#ifdef Q_WS_WIN
- HMENU systemMenu = GetSystemMenu((HWND)winId(), FALSE);
- if (!d->detectedEscapeButton) {
- EnableMenuItem(systemMenu, SC_CLOSE, MF_BYCOMMAND|MF_GRAYED);
- }
- else {
- EnableMenuItem(systemMenu, SC_CLOSE, MF_BYCOMMAND|MF_ENABLED);
- }
-#endif
- QDialog::showEvent(e);
-}
-
-
-static QMessageBox::StandardButton showNewMessageBox(QWidget *parent,
- QMessageBox::Icon icon,
- const QString& title, const QString& text,
- QMessageBox::StandardButtons buttons,
- QMessageBox::StandardButton defaultButton)
-{
- // necessary for source compatibility with Qt 4.0 and 4.1
- // handles (Yes, No) and (Yes|Default, No)
- if (defaultButton && !(buttons & defaultButton))
- return (QMessageBox::StandardButton)
- QMessageBoxPrivate::showOldMessageBox(parent, icon, title,
- text, int(buttons),
- int(defaultButton), 0);
-
- QMessageBox msgBox(icon, title, text, QMessageBox::NoButton, parent);
- QDialogButtonBox *buttonBox = msgBox.findChild<QDialogButtonBox*>();
- Q_ASSERT(buttonBox != 0);
-
- uint mask = QMessageBox::FirstButton;
- while (mask <= QMessageBox::LastButton) {
- uint sb = buttons & mask;
- mask <<= 1;
- if (!sb)
- continue;
- QPushButton *button = msgBox.addButton((QMessageBox::StandardButton)sb);
- // Choose the first accept role as the default
- if (msgBox.defaultButton())
- continue;
- if ((defaultButton == QMessageBox::NoButton && buttonBox->buttonRole(button) == QDialogButtonBox::AcceptRole)
- || (defaultButton != QMessageBox::NoButton && sb == uint(defaultButton)))
- msgBox.setDefaultButton(button);
- }
- if (msgBox.exec() == -1)
- return QMessageBox::Cancel;
- return msgBox.standardButton(msgBox.clickedButton());
-}
-
-/*!
- \since 4.2
-
- Opens an information message box with the given \a title and
- \a text in front of the specified \a parent widget.
-
- The standard \a buttons are added to the message box.
- \a defaultButton specifies the button used when \key Enter is pressed.
- \a defaultButton must refer to a button that was given in \a buttons.
- If \a defaultButton is QMessageBox::NoButton, QMessageBox
- chooses a suitable default automatically.
-
- Returns the identity of the standard button that was clicked. If
- \key Esc was pressed instead, the \l{Default and Escape Keys}
- {escape button} is returned.
-
- The message box is an \l{Qt::ApplicationModal}{application modal}
- dialog box.
-
- \warning Do not delete \a parent during the execution of the dialog.
- If you want to do this, you should create the dialog
- yourself using one of the QMessageBox constructors.
-
- \sa question(), warning(), critical()
-*/
-QMessageBox::StandardButton QMessageBox::information(QWidget *parent, const QString &title,
- const QString& text, StandardButtons buttons,
- StandardButton defaultButton)
-{
- return showNewMessageBox(parent, Information, title, text, buttons,
- defaultButton);
-}
-
-
-/*!
- \since 4.2
-
- Opens a question message box with the given \a title and \a
- text in front of the specified \a parent widget.
-
- The standard \a buttons are added to the message box. \a
- defaultButton specifies the button used when \key Enter is
- pressed. \a defaultButton must refer to a button that was given in \a buttons.
- If \a defaultButton is QMessageBox::NoButton, QMessageBox
- chooses a suitable default automatically.
-
- Returns the identity of the standard button that was clicked. If
- \key Esc was pressed instead, the \l{Default and Escape Keys}
- {escape button} is returned.
-
- The message box is an \l{Qt::ApplicationModal} {application modal}
- dialog box.
-
- \warning Do not delete \a parent during the execution of the dialog.
- If you want to do this, you should create the dialog
- yourself using one of the QMessageBox constructors.
-
- \sa information(), warning(), critical()
-*/
-QMessageBox::StandardButton QMessageBox::question(QWidget *parent, const QString &title,
- const QString& text, StandardButtons buttons,
- StandardButton defaultButton)
-{
- return showNewMessageBox(parent, Question, title, text, buttons, defaultButton);
-}
-
-/*!
- \since 4.2
-
- Opens a warning message box with the given \a title and \a
- text in front of the specified \a parent widget.
-
- The standard \a buttons are added to the message box. \a
- defaultButton specifies the button used when \key Enter is
- pressed. \a defaultButton must refer to a button that was given in \a buttons.
- If \a defaultButton is QMessageBox::NoButton, QMessageBox
- chooses a suitable default automatically.
-
- Returns the identity of the standard button that was clicked. If
- \key Esc was pressed instead, the \l{Default and Escape Keys}
- {escape button} is returned.
-
- The message box is an \l{Qt::ApplicationModal} {application modal}
- dialog box.
-
- \warning Do not delete \a parent during the execution of the dialog.
- If you want to do this, you should create the dialog
- yourself using one of the QMessageBox constructors.
-
- \sa question(), information(), critical()
-*/
-QMessageBox::StandardButton QMessageBox::warning(QWidget *parent, const QString &title,
- const QString& text, StandardButtons buttons,
- StandardButton defaultButton)
-{
- return showNewMessageBox(parent, Warning, title, text, buttons, defaultButton);
-}
-
-/*!
- \since 4.2
-
- Opens a critical message box with the given \a title and \a
- text in front of the specified \a parent widget.
-
- The standard \a buttons are added to the message box. \a
- defaultButton specifies the button used when \key Enter is
- pressed. \a defaultButton must refer to a button that was given in \a buttons.
- If \a defaultButton is QMessageBox::NoButton, QMessageBox
- chooses a suitable default automatically.
-
- Returns the identity of the standard button that was clicked. If
- \key Esc was pressed instead, the \l{Default and Escape Keys}
- {escape button} is returned.
-
- The message box is an \l{Qt::ApplicationModal} {application modal}
- dialog box.
-
- \warning Do not delete \a parent during the execution of the dialog.
- If you want to do this, you should create the dialog
- yourself using one of the QMessageBox constructors.
-
- \sa question(), warning(), information()
-*/
-QMessageBox::StandardButton QMessageBox::critical(QWidget *parent, const QString &title,
- const QString& text, StandardButtons buttons,
- StandardButton defaultButton)
-{
- return showNewMessageBox(parent, Critical, title, text, buttons, defaultButton);
-}
-
-/*!
- Displays a simple about box with title \a title and text \a
- text. The about box's parent is \a parent.
-
- about() looks for a suitable icon in four locations:
-
- \list 1
- \o It prefers \link QWidget::windowIcon() parent->icon() \endlink
- if that exists.
- \o If not, it tries the top-level widget containing \a parent.
- \o If that fails, it tries the \link
- QApplication::activeWindow() active window. \endlink
- \o As a last resort it uses the Information icon.
- \endlist
-
- The about box has a single button labelled "OK". On Mac OS X, the
- about box is popped up as a modeless window; on other platforms,
- it is currently application modal.
-
- \sa QWidget::windowIcon(), QApplication::activeWindow()
-*/
-void QMessageBox::about(QWidget *parent, const QString &title, const QString &text)
-{
-#ifdef Q_WS_MAC
- static QPointer<QMessageBox> oldMsgBox;
-
- if (oldMsgBox && oldMsgBox->text() == text) {
- oldMsgBox->show();
- oldMsgBox->raise();
- oldMsgBox->activateWindow();
- return;
- }
-#endif
-
- QMessageBox *msgBox = new QMessageBox(title, text, Information, 0, 0, 0, parent
-#ifdef Q_WS_MAC
- , Qt::WindowTitleHint | Qt::WindowSystemMenuHint
-#endif
- );
- msgBox->setAttribute(Qt::WA_DeleteOnClose);
- QIcon icon = msgBox->windowIcon();
- QSize size = icon.actualSize(QSize(64, 64));
- msgBox->setIconPixmap(icon.pixmap(size));
-
- // should perhaps be a style hint
-#ifdef Q_WS_MAC
- oldMsgBox = msgBox;
-#if 0
- // ### doesn't work until close button is enabled in title bar
- msgBox->d_func()->autoAddOkButton = false;
-#else
- msgBox->d_func()->buttonBox->setCenterButtons(true);
-#endif
- msgBox->show();
-#else
- msgBox->exec();
-#endif
-}
-
-/*!
- Displays a simple message box about Qt, with the given \a title
- and centered over \a parent (if \a parent is not 0). 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.
-
- QApplication provides this functionality as a slot.
-
- On Mac OS X, the about box is popped up as a modeless window; on
- other platforms, it is currently application modal.
-
- \sa QApplication::aboutQt()
-*/
-void QMessageBox::aboutQt(QWidget *parent, const QString &title)
-{
-#ifdef Q_WS_MAC
- static QPointer<QMessageBox> oldMsgBox;
-
- if (oldMsgBox) {
- oldMsgBox->show();
- oldMsgBox->raise();
- oldMsgBox->activateWindow();
- return;
- }
-#endif
-
- QString translatedTextAboutQtCaption;
- translatedTextAboutQtCaption = QMessageBox::tr(
- "<h3>About Qt</h3>"
- "<p>This program uses Qt version %1.</p>"
- ).arg(QLatin1String(QT_VERSION_STR));
- QString translatedTextAboutQtText;
- translatedTextAboutQtText = QMessageBox::tr(
- "<p>Qt is a C++ toolkit for cross-platform application "
- "development.</p>"
- "<p>Qt provides single-source portability across MS&nbsp;Windows, "
- "Mac&nbsp;OS&nbsp;X, Linux, and all major commercial Unix variants. "
- "Qt is also available for embedded devices as Qt for Embedded Linux "
- "and Qt for Windows CE.</p>"
- "<p>Qt is available under three different licensing options designed "
- "to accommodate the needs of our various users.</p>"
- "<p>Qt licensed under our commercial license agreement is appropriate "
- "for development of proprietary/commercial software where you do not "
- "want to share any source code with third parties or otherwise cannot "
- "comply with the terms of the GNU LGPL version 2.1 or GNU GPL version "
- "3.0.</p>"
- "<p>Qt licensed under the GNU LGPL version 2.1 is appropriate for the "
- "development of Qt applications (proprietary or open source) provided "
- "you can comply with the terms and conditions of the GNU LGPL version "
- "2.1.</p>"
- "<p>Qt licensed under the GNU General Public License version 3.0 is "
- "appropriate for the development of Qt applications where you wish to "
- "use such applications in combination with software subject to the "
- "terms of the GNU GPL version 3.0 or where you are otherwise willing "
- "to comply with the terms of the GNU GPL version 3.0.</p>"
- "<p>Please see <a href=\"http://qt.nokia.com/products/licensing\">qt.nokia.com/products/licensing</a> "
- "for an overview of Qt licensing.</p>"
- "<p>Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).</p>"
- "<p>Qt is a Nokia product. See <a href=\"http://qt.nokia.com/\">qt.nokia.com</a> "
- "for more information.</p>"
- );
- QMessageBox *msgBox = new QMessageBox(parent);
- msgBox->setAttribute(Qt::WA_DeleteOnClose);
- msgBox->setWindowTitle(title.isEmpty() ? tr("About Qt") : title);
- msgBox->setText(translatedTextAboutQtCaption);
- msgBox->setInformativeText(translatedTextAboutQtText);
-
- QPixmap pm(QLatin1String(":/trolltech/qmessagebox/images/qtlogo-64.png"));
- if (!pm.isNull())
- msgBox->setIconPixmap(pm);
-#if defined(Q_WS_WINCE)
- msgBox->setDefaultButton(msgBox->addButton(QMessageBox::Ok));
-#endif
-
- // should perhaps be a style hint
-#ifdef Q_WS_MAC
- oldMsgBox = msgBox;
-#if 0
- // ### doesn't work until close button is enabled in title bar
- msgBox->d_func()->autoAddOkButton = false;
-#else
- msgBox->d_func()->buttonBox->setCenterButtons(true);
-#endif
- msgBox->show();
-#else
- msgBox->exec();
-#endif
-}
-
-/*!
- \internal
-*/
-QSize QMessageBox::sizeHint() const
-{
- // ### Qt 5: remove
- return QDialog::sizeHint();
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// Source and binary compatibility routines for 4.0 and 4.1
-
-static QMessageBox::StandardButton newButton(int button)
-{
- // this is needed for source compatibility with Qt 4.0 and 4.1
- if (button == QMessageBox::NoButton || (button & NewButtonMask))
- return QMessageBox::StandardButton(button & QMessageBox::ButtonMask);
-
-#if QT_VERSION < 0x050000
- // this is needed for binary compatibility with Qt 4.0 and 4.1
- switch (button & Old_ButtonMask) {
- case Old_Ok:
- return QMessageBox::Ok;
- case Old_Cancel:
- return QMessageBox::Cancel;
- case Old_Yes:
- return QMessageBox::Yes;
- case Old_No:
- return QMessageBox::No;
- case Old_Abort:
- return QMessageBox::Abort;
- case Old_Retry:
- return QMessageBox::Retry;
- case Old_Ignore:
- return QMessageBox::Ignore;
- case Old_YesAll:
- return QMessageBox::YesToAll;
- case Old_NoAll:
- return QMessageBox::NoToAll;
- default:
- return QMessageBox::NoButton;
- }
-#endif
-}
-
-static bool detectedCompat(int button0, int button1, int button2)
-{
- if (button0 != 0 && !(button0 & NewButtonMask))
- return true;
- if (button1 != 0 && !(button1 & NewButtonMask))
- return true;
- if (button2 != 0 && !(button2 & NewButtonMask))
- return true;
- return false;
-}
-
-QAbstractButton *QMessageBoxPrivate::findButton(int button0, int button1, int button2, int flags)
-{
- Q_Q(QMessageBox);
- int button = 0;
-
- if (button0 & flags) {
- button = button0;
- } else if (button1 & flags) {
- button = button1;
- } else if (button2 & flags) {
- button = button2;
- }
- return q->button(newButton(button));
-}
-
-void QMessageBoxPrivate::addOldButtons(int button0, int button1, int button2)
-{
- Q_Q(QMessageBox);
- q->addButton(newButton(button0));
- q->addButton(newButton(button1));
- q->addButton(newButton(button2));
- q->setDefaultButton(
- static_cast<QPushButton *>(findButton(button0, button1, button2, QMessageBox::Default)));
- q->setEscapeButton(findButton(button0, button1, button2, QMessageBox::Escape));
- compatMode = detectedCompat(button0, button1, button2);
-}
-
-QAbstractButton *QMessageBoxPrivate::abstractButtonForId(int id) const
-{
- Q_Q(const QMessageBox);
- QAbstractButton *result = customButtonList.value(id);
- if (result)
- return result;
- if (id & QMessageBox::FlagMask) // for compatibility with Qt 4.0/4.1 (even if it is silly)
- return 0;
- return q->button(newButton(id));
-}
-
-int QMessageBoxPrivate::showOldMessageBox(QWidget *parent, QMessageBox::Icon icon,
- const QString &title, const QString &text,
- int button0, int button1, int button2)
-{
- QMessageBox messageBox(icon, title, text, QMessageBox::NoButton, parent);
- messageBox.d_func()->addOldButtons(button0, button1, button2);
- return messageBox.exec();
-}
-
-int QMessageBoxPrivate::showOldMessageBox(QWidget *parent, QMessageBox::Icon icon,
- const QString &title, const QString &text,
- const QString &button0Text,
- const QString &button1Text,
- const QString &button2Text,
- int defaultButtonNumber,
- int escapeButtonNumber)
-{
- QMessageBox messageBox(icon, title, text, QMessageBox::NoButton, parent);
- QString myButton0Text = button0Text;
- if (myButton0Text.isEmpty())
- myButton0Text = QDialogButtonBox::tr("OK");
- messageBox.addButton(myButton0Text, QMessageBox::ActionRole);
- if (!button1Text.isEmpty())
- messageBox.addButton(button1Text, QMessageBox::ActionRole);
- if (!button2Text.isEmpty())
- messageBox.addButton(button2Text, QMessageBox::ActionRole);
-
- const QList<QAbstractButton *> &buttonList = messageBox.d_func()->customButtonList;
- messageBox.setDefaultButton(static_cast<QPushButton *>(buttonList.value(defaultButtonNumber)));
- messageBox.setEscapeButton(buttonList.value(escapeButtonNumber));
-
- return messageBox.exec();
-}
-
-void QMessageBoxPrivate::retranslateStrings()
-{
-#ifndef QT_NO_TEXTEDIT
- if (detailsButton)
- detailsButton->setLabel(detailsText->isHidden() ? ShowLabel : HideLabel);
-#endif
-}
-
-/*!
- \obsolete
-
- Constructs a message box with a \a title, a \a text, an \a icon,
- and up to three buttons.
-
- The \a icon must be one of the following:
- \list
- \o QMessageBox::NoIcon
- \o QMessageBox::Question
- \o QMessageBox::Information
- \o QMessageBox::Warning
- \o QMessageBox::Critical
- \endlist
-
- Each button, \a button0, \a button1 and \a button2, can have one
- of the following values:
- \list
- \o QMessageBox::NoButton
- \o QMessageBox::Ok
- \o QMessageBox::Cancel
- \o QMessageBox::Yes
- \o QMessageBox::No
- \o QMessageBox::Abort
- \o QMessageBox::Retry
- \o QMessageBox::Ignore
- \o QMessageBox::YesAll
- \o QMessageBox::NoAll
- \endlist
-
- Use QMessageBox::NoButton for the later parameters to have fewer
- than three buttons in your message box. If you don't specify any
- buttons at all, QMessageBox will provide an Ok button.
-
- One of the buttons can be OR-ed with the QMessageBox::Default
- flag to make it the default button (clicked when Enter is
- pressed).
-
- One of the buttons can be OR-ed with the QMessageBox::Escape flag
- to make it the cancel or close button (clicked when \key Esc is
- pressed).
-
- \snippet doc/src/snippets/dialogs/dialogs.cpp 2
-
- The message box is an \l{Qt::ApplicationModal} {application modal}
- dialog box.
-
- The \a parent and \a f arguments are passed to
- the QDialog constructor.
-
- \sa setWindowTitle(), setText(), setIcon()
-*/
-QMessageBox::QMessageBox(const QString &title, const QString &text, Icon icon,
- int button0, int button1, int button2, QWidget *parent,
- Qt::WindowFlags f)
- : QDialog(*new QMessageBoxPrivate, parent,
- f /*| Qt::MSWindowsFixedSizeDialogHint #### */| Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint)
-{
- Q_D(QMessageBox);
- d->init(title, text);
- setIcon(icon);
- d->addOldButtons(button0, button1, button2);
-}
-
-/*!
- \obsolete
-
- Opens an information message box with the given \a title and the
- \a text. The dialog may have up to three buttons. Each of the
- buttons, \a button0, \a button1 and \a button2 may be set to one
- of the following values:
-
- \list
- \o QMessageBox::NoButton
- \o QMessageBox::Ok
- \o QMessageBox::Cancel
- \o QMessageBox::Yes
- \o QMessageBox::No
- \o QMessageBox::Abort
- \o QMessageBox::Retry
- \o QMessageBox::Ignore
- \o QMessageBox::YesAll
- \o QMessageBox::NoAll
- \endlist
-
- If you don't want all three buttons, set the last button, or last
- two buttons to QMessageBox::NoButton.
-
- One button can be OR-ed with QMessageBox::Default, and one
- button can be OR-ed with QMessageBox::Escape.
-
- Returns the identity (QMessageBox::Ok, or QMessageBox::No, etc.)
- of the button that was clicked.
-
- The message box is an \l{Qt::ApplicationModal} {application modal}
- dialog box.
-
- \warning Do not delete \a parent during the execution of the dialog.
- If you want to do this, you should create the dialog
- yourself using one of the QMessageBox constructors.
-
- \sa question(), warning(), critical()
-*/
-int QMessageBox::information(QWidget *parent, const QString &title, const QString& text,
- int button0, int button1, int button2)
-{
- return QMessageBoxPrivate::showOldMessageBox(parent, Information, title, text,
- button0, button1, button2);
-}
-
-/*!
- \obsolete
- \overload
-
- Displays an information message box with the given \a title and
- \a text, as well as one, two or three buttons. Returns the index
- of the button that was clicked (0, 1 or 2).
-
- \a button0Text is the text of the first button, and is optional.
- If \a button0Text is not supplied, "OK" (translated) will be
- used. \a button1Text is the text of the second button, and is
- optional. \a button2Text is the text of the third button, and is
- optional. \a defaultButtonNumber (0, 1 or 2) is the index of the
- default button; pressing Return or Enter is the same as clicking
- the default button. It defaults to 0 (the first button). \a
- escapeButtonNumber is the index of the escape button; pressing
- \key Esc is the same as clicking this button. It defaults to -1;
- supply 0, 1 or 2 to make pressing \key Esc equivalent to clicking
- the relevant button.
-
- The message box is an \l{Qt::ApplicationModal} {application modal}
- dialog box.
-
- \warning Do not delete \a parent during the execution of the dialog.
- If you want to do this, you should create the dialog
- yourself using one of the QMessageBox constructors.
-
- \sa question(), warning(), critical()
-*/
-
-int QMessageBox::information(QWidget *parent, const QString &title, const QString& text,
- const QString& button0Text, const QString& button1Text,
- const QString& button2Text, int defaultButtonNumber,
- int escapeButtonNumber)
-{
- return QMessageBoxPrivate::showOldMessageBox(parent, Information, title, text,
- button0Text, button1Text, button2Text,
- defaultButtonNumber, escapeButtonNumber);
-}
-
-/*!
- \obsolete
-
- Opens a question message box with the given \a title and \a text.
- The dialog may have up to three buttons. Each of the buttons, \a
- button0, \a button1 and \a button2 may be set to one of the
- following values:
-
- \list
- \o QMessageBox::NoButton
- \o QMessageBox::Ok
- \o QMessageBox::Cancel
- \o QMessageBox::Yes
- \o QMessageBox::No
- \o QMessageBox::Abort
- \o QMessageBox::Retry
- \o QMessageBox::Ignore
- \o QMessageBox::YesAll
- \o QMessageBox::NoAll
- \endlist
-
- If you don't want all three buttons, set the last button, or last
- two buttons to QMessageBox::NoButton.
-
- One button can be OR-ed with QMessageBox::Default, and one
- button can be OR-ed with QMessageBox::Escape.
-
- Returns the identity (QMessageBox::Yes, or QMessageBox::No, etc.)
- of the button that was clicked.
-
- The message box is an \l{Qt::ApplicationModal} {application modal}
- dialog box.
-
- \warning Do not delete \a parent during the execution of the dialog.
- If you want to do this, you should create the dialog
- yourself using one of the QMessageBox constructors.
-
- \sa information(), warning(), critical()
-*/
-int QMessageBox::question(QWidget *parent, const QString &title, const QString& text,
- int button0, int button1, int button2)
-{
- return QMessageBoxPrivate::showOldMessageBox(parent, Question, title, text,
- button0, button1, button2);
-}
-
-/*!
- \obsolete
- \overload
-
- Displays a question message box with the given \a title and \a
- text, as well as one, two or three buttons. Returns the index of
- the button that was clicked (0, 1 or 2).
-
- \a button0Text is the text of the first button, and is optional.
- If \a button0Text is not supplied, "OK" (translated) will be used.
- \a button1Text is the text of the second button, and is optional.
- \a button2Text is the text of the third button, and is optional.
- \a defaultButtonNumber (0, 1 or 2) is the index of the default
- button; pressing Return or Enter is the same as clicking the
- default button. It defaults to 0 (the first button). \a
- escapeButtonNumber is the index of the Escape button; pressing
- Escape is the same as clicking this button. It defaults to -1;
- supply 0, 1 or 2 to make pressing Escape equivalent to clicking
- the relevant button.
-
- The message box is an \l{Qt::ApplicationModal} {application modal}
- dialog box.
-
- \warning Do not delete \a parent during the execution of the dialog.
- If you want to do this, you should create the dialog
- yourself using one of the QMessageBox constructors.
-
- \sa information(), warning(), critical()
-*/
-int QMessageBox::question(QWidget *parent, const QString &title, const QString& text,
- const QString& button0Text, const QString& button1Text,
- const QString& button2Text, int defaultButtonNumber,
- int escapeButtonNumber)
-{
- return QMessageBoxPrivate::showOldMessageBox(parent, Question, title, text,
- button0Text, button1Text, button2Text,
- defaultButtonNumber, escapeButtonNumber);
-}
-
-
-/*!
- \obsolete
-
- Opens a warning message box with the given \a title and \a text.
- The dialog may have up to three buttons. Each of the button
- parameters, \a button0, \a button1 and \a button2 may be set to
- one of the following values:
-
- \list
- \o QMessageBox::NoButton
- \o QMessageBox::Ok
- \o QMessageBox::Cancel
- \o QMessageBox::Yes
- \o QMessageBox::No
- \o QMessageBox::Abort
- \o QMessageBox::Retry
- \o QMessageBox::Ignore
- \o QMessageBox::YesAll
- \o QMessageBox::NoAll
- \endlist
-
- If you don't want all three buttons, set the last button, or last
- two buttons to QMessageBox::NoButton.
-
- One button can be OR-ed with QMessageBox::Default, and one
- button can be OR-ed with QMessageBox::Escape.
-
- Returns the identity (QMessageBox::Ok or QMessageBox::No or ...)
- of the button that was clicked.
-
- The message box is an \l{Qt::ApplicationModal} {application modal}
- dialog box.
-
- \warning Do not delete \a parent during the execution of the dialog.
- If you want to do this, you should create the dialog
- yourself using one of the QMessageBox constructors.
-
- \sa information(), question(), critical()
-*/
-int QMessageBox::warning(QWidget *parent, const QString &title, const QString& text,
- int button0, int button1, int button2)
-{
- return QMessageBoxPrivate::showOldMessageBox(parent, Warning, title, text,
- button0, button1, button2);
-}
-
-/*!
- \obsolete
- \overload
-
- Displays a warning message box with the given \a title and \a
- text, as well as one, two, or three buttons. Returns the number
- of the button that was clicked (0, 1, or 2).
-
- \a button0Text is the text of the first button, and is optional.
- If \a button0Text is not supplied, "OK" (translated) will be used.
- \a button1Text is the text of the second button, and is optional,
- and \a button2Text is the text of the third button, and is
- optional. \a defaultButtonNumber (0, 1 or 2) is the index of the
- default button; pressing Return or Enter is the same as clicking
- the default button. It defaults to 0 (the first button). \a
- escapeButtonNumber is the index of the Escape button; pressing
- Escape is the same as clicking this button. It defaults to -1;
- supply 0, 1, or 2 to make pressing Escape equivalent to clicking
- the relevant button.
-
- The message box is an \l{Qt::ApplicationModal} {application modal}
- dialog box.
-
- \warning Do not delete \a parent during the execution of the dialog.
- If you want to do this, you should create the dialog
- yourself using one of the QMessageBox constructors.
-
- \sa information(), question(), critical()
-*/
-int QMessageBox::warning(QWidget *parent, const QString &title, const QString& text,
- const QString& button0Text, const QString& button1Text,
- const QString& button2Text, int defaultButtonNumber,
- int escapeButtonNumber)
-{
- return QMessageBoxPrivate::showOldMessageBox(parent, Warning, title, text,
- button0Text, button1Text, button2Text,
- defaultButtonNumber, escapeButtonNumber);
-}
-
-/*!
- \obsolete
-
- Opens a critical message box with the given \a title and \a text.
- The dialog may have up to three buttons. Each of the button
- parameters, \a button0, \a button1 and \a button2 may be set to
- one of the following values:
-
- \list
- \o QMessageBox::NoButton
- \o QMessageBox::Ok
- \o QMessageBox::Cancel
- \o QMessageBox::Yes
- \o QMessageBox::No
- \o QMessageBox::Abort
- \o QMessageBox::Retry
- \o QMessageBox::Ignore
- \o QMessageBox::YesAll
- \o QMessageBox::NoAll
- \endlist
-
- If you don't want all three buttons, set the last button, or last
- two buttons to QMessageBox::NoButton.
-
- One button can be OR-ed with QMessageBox::Default, and one
- button can be OR-ed with QMessageBox::Escape.
-
- Returns the identity (QMessageBox::Ok, or QMessageBox::No, etc.)
- of the button that was clicked.
-
- The message box is an \l{Qt::ApplicationModal} {application modal}
- dialog box.
-
- \warning Do not delete \a parent during the execution of the dialog.
- If you want to do this, you should create the dialog
- yourself using one of the QMessageBox constructors.
-
- \sa information(), question(), warning()
-*/
-
-int QMessageBox::critical(QWidget *parent, const QString &title, const QString& text,
- int button0, int button1, int button2)
-{
- return QMessageBoxPrivate::showOldMessageBox(parent, Critical, title, text,
- button0, button1, button2);
-}
-
-/*!
- \obsolete
- \overload
-
- Displays a critical error message box with the given \a title and
- \a text, as well as one, two, or three buttons. Returns the
- number of the button that was clicked (0, 1 or 2).
-
- \a button0Text is the text of the first button, and is optional.
- If \a button0Text is not supplied, "OK" (translated) will be used.
- \a button1Text is the text of the second button, and is optional,
- and \a button2Text is the text of the third button, and is
- optional. \a defaultButtonNumber (0, 1 or 2) is the index of the
- default button; pressing Return or Enter is the same as clicking
- the default button. It defaults to 0 (the first button). \a
- escapeButtonNumber is the index of the Escape button; pressing
- Escape is the same as clicking this button. It defaults to -1;
- supply 0, 1, or 2 to make pressing Escape equivalent to clicking
- the relevant button.
-
- The message box is an \l{Qt::ApplicationModal} {application modal}
- dialog box.
-
- \warning Do not delete \a parent during the execution of the dialog.
- If you want to do this, you should create the dialog
- yourself using one of the QMessageBox constructors.
-
- \sa information(), question(), warning()
-*/
-int QMessageBox::critical(QWidget *parent, const QString &title, const QString& text,
- const QString& button0Text, const QString& button1Text,
- const QString& button2Text, int defaultButtonNumber,
- int escapeButtonNumber)
-{
- return QMessageBoxPrivate::showOldMessageBox(parent, Critical, title, text,
- button0Text, button1Text, button2Text,
- defaultButtonNumber, escapeButtonNumber);
-}
-
-
-/*!
- \obsolete
-
- Returns the text of the message box button \a button, or
- an empty string if the message box does not contain the button.
-
- Use button() and QPushButton::text() instead.
-*/
-QString QMessageBox::buttonText(int button) const
-{
- Q_D(const QMessageBox);
-
- if (QAbstractButton *abstractButton = d->abstractButtonForId(button)) {
- return abstractButton->text();
- } else if (d->buttonBox->buttons().isEmpty() && (button == Ok || button == Old_Ok)) {
- // for compatibility with Qt 4.0/4.1
- return QDialogButtonBox::tr("OK");
- }
- return QString();
-}
-
-/*!
- \obsolete
-
- Sets the text of the message box button \a button to \a text.
- Setting the text of a button that is not in the message box is
- silently ignored.
-
- Use addButton() instead.
-*/
-void QMessageBox::setButtonText(int button, const QString &text)
-{
- Q_D(QMessageBox);
- if (QAbstractButton *abstractButton = d->abstractButtonForId(button)) {
- abstractButton->setText(text);
- } else if (d->buttonBox->buttons().isEmpty() && (button == Ok || button == Old_Ok)) {
- // for compatibility with Qt 4.0/4.1
- addButton(QMessageBox::Ok)->setText(text);
- }
-}
-
-#ifndef QT_NO_TEXTEDIT
-/*!
- \property QMessageBox::detailedText
- \brief the text to be displayed in the details area.
- \since 4.2
-
- The text will be interpreted as a plain text.
-
- By default, this property contains an empty string.
-
- \sa QMessageBox::text, QMessageBox::informativeText
-*/
-QString QMessageBox::detailedText() const
-{
- Q_D(const QMessageBox);
- return d->detailsText ? d->detailsText->text() : QString();
-}
-
-void QMessageBox::setDetailedText(const QString &text)
-{
- Q_D(QMessageBox);
- if (text.isEmpty()) {
- delete d->detailsText;
- d->detailsText = 0;
- removeButton(d->detailsButton);
- delete d->detailsButton;
- d->detailsButton = 0;
- return;
- }
-
- if (!d->detailsText) {
- d->detailsText = new QMessageBoxDetailsText(this);
- QGridLayout* grid = qobject_cast<QGridLayout*>(layout());
- if (grid)
- grid->addWidget(d->detailsText, grid->rowCount(), 0, 1, grid->columnCount());
- d->detailsText->hide();
- }
- if (!d->detailsButton)
- d->detailsButton = new DetailButton(this);
- d->detailsText->setText(text);
-}
-#endif // QT_NO_TEXTEDIT
-
-/*!
- \property QMessageBox::informativeText
-
- \brief the informative text that provides a fuller description for
- the message
-
- \since 4.2
-
- Infromative text can be used to expand upon the text() to give more
- information to the user. On the Mac, this text appears in small
- system font below the text(). On other platforms, it is simply
- appended to the existing text.
-
- By default, this property contains an empty string.
-
- \sa QMessageBox::text, QMessageBox::detailedText
-*/
-QString QMessageBox::informativeText() const
-{
- Q_D(const QMessageBox);
- return d->informativeLabel ? d->informativeLabel->text() : QString();
-}
-
-void QMessageBox::setInformativeText(const QString &text)
-{
- Q_D(QMessageBox);
- if (text.isEmpty()) {
- layout()->removeWidget(d->informativeLabel);
- delete d->informativeLabel;
- d->informativeLabel = 0;
-#ifndef Q_WS_MAC
- d->label->setContentsMargins(2, 0, 0, 0);
-#endif
- d->updateSize();
- return;
- }
-
- if (!d->informativeLabel) {
- QLabel *label = new QLabel;
- label->setObjectName(QLatin1String("qt_msgbox_informativelabel"));
- label->setTextInteractionFlags(Qt::TextInteractionFlags(style()->styleHint(QStyle::SH_MessageBox_TextInteractionFlags, 0, this)));
- label->setAlignment(Qt::AlignTop | Qt::AlignLeft);
- label->setOpenExternalLinks(true);
- label->setWordWrap(true);
-#ifndef Q_WS_MAC
- d->label->setContentsMargins(2, 0, 0, 0);
- label->setContentsMargins(2, 0, 0, 6);
- label->setIndent(9);
-#else
- label->setContentsMargins(16, 0, 0, 0);
- // apply a smaller font the information label on the mac
- label->setFont(qt_app_fonts_hash()->value("QTipLabel"));
-#endif
- label->setWordWrap(true);
- QGridLayout *grid = static_cast<QGridLayout *>(layout());
-#if defined(Q_OS_SYMBIAN) || defined(Q_WS_MAEMO_5)
- label->hide();
- QTextBrowser *textBrowser = new QTextBrowser(this);
- textBrowser->setOpenExternalLinks(true);
- grid->addWidget(textBrowser, 1, 1, 1, 1);
- d->textBrowser = textBrowser;
-#else
- grid->addWidget(label, 1, 1, 1, 1);
-#endif
- d->informativeLabel = label;
- }
- d->informativeLabel->setText(text);
-
-#if defined(Q_OS_SYMBIAN) || defined(Q_WS_MAEMO_5)
- //We need to put the informative label inside textBrowser to enable scrolling of long texts.
- d->textBrowser->setText(d->informativeLabel->text());
-#endif
-
- d->updateSize();
-}
-
-/*!
- \since 4.2
-
- This function shadows QWidget::setWindowTitle().
-
- Sets the title of the message box to \a title. On Mac OS X,
- the window title is ignored (as required by the Mac OS X
- Guidelines).
-*/
-void QMessageBox::setWindowTitle(const QString &title)
-{
- // Message boxes on the mac do not have a title
-#ifndef Q_WS_MAC
- QDialog::setWindowTitle(title);
-#else
- Q_UNUSED(title);
-#endif
-}
-
-
-/*!
- \since 4.2
-
- This function shadows QWidget::setWindowModality().
-
- Sets the modality of the message box to \a windowModality.
-
- On Mac OS X, if the modality is set to Qt::WindowModal and the message box
- has a parent, then the message box will be a Qt::Sheet, otherwise the
- message box will be a standard dialog.
-*/
-void QMessageBox::setWindowModality(Qt::WindowModality windowModality)
-{
- QDialog::setWindowModality(windowModality);
-
- if (parentWidget() && windowModality == Qt::WindowModal)
- setParent(parentWidget(), Qt::Sheet);
- else
- setParent(parentWidget(), Qt::Dialog);
- setDefaultButton(d_func()->defaultButton);
-}
-
-#ifdef QT3_SUPPORT
-/*!
- \compat
-
- Constructs a message box with the given \a parent, \a name, and
- window flags, \a f.
- The window title is specified by \a title, and the message box
- displays message text and an icon specified by \a text and \a icon.
-
- The buttons that the user can access to respond to the message are
- defined by \a button0, \a button1, and \a button2.
-*/
-QMessageBox::QMessageBox(const QString& title,
- const QString &text, Icon icon,
- int button0, int button1, int button2,
- QWidget *parent, const char *name,
- bool modal, Qt::WindowFlags f)
- : QDialog(*new QMessageBoxPrivate, parent,
- f | Qt::WStyle_Customize | Qt::WStyle_DialogBorder | Qt::WStyle_Title | Qt::WStyle_SysMenu | Qt::WindowCloseButtonHint)
-{
- Q_D(QMessageBox);
- setObjectName(QString::fromAscii(name));
- d->init(title, text);
- d->addOldButtons(button0, button1, button2);
- setModal(modal);
- setIcon(icon);
-}
-
-/*!
- \compat
- Constructs a message box with the given \a parent and \a name.
-*/
-QMessageBox::QMessageBox(QWidget *parent, const char *name)
- : QDialog(*new QMessageBoxPrivate, parent,
- Qt::WStyle_Customize | Qt::WStyle_DialogBorder | Qt::WStyle_Title | Qt::WStyle_SysMenu | Qt::WindowCloseButtonHint)
-{
- Q_D(QMessageBox);
- setObjectName(QString::fromAscii(name));
- d->init();
-}
-
-/*!
- Returns the pixmap used for a standard icon. This
- allows the pixmaps to be used in more complex message boxes.
- \a icon specifies the required icon, e.g. QMessageBox::Information,
- QMessageBox::Warning or QMessageBox::Critical.
-
- \a style is unused.
-*/
-
-QPixmap QMessageBox::standardIcon(Icon icon, Qt::GUIStyle style)
-{
- Q_UNUSED(style);
- return QMessageBox::standardIcon(icon);
-}
-
-/*!
- \fn int QMessageBox::message(const QString &title, const QString &text,
- const QString &buttonText, QWidget *parent = 0,
- const char *name = 0)
-
- Opens a modal message box with the given \a title and showing the
- given \a text. The message box has a single button which has the
- given \a buttonText (or tr("OK")). The message box is centred over
- its \a parent and is called \a name.
-
- Use information(), warning(), question(), or critical() instead.
-
- \oldcode
- QMessageBox::message(tr("My App"), tr("All occurrences replaced."),
- tr("Close"), this);
- \newcode
- QMessageBox::information(this, tr("My App"),
- tr("All occurrences replaced."),
- QMessageBox::Close);
- \endcode
-*/
-
-/*!
- \fn bool QMessageBox::query(const QString &caption,
- const QString& text,
- const QString& yesButtonText,
- const QString& noButtonText,
- QWidget *parent, const char *name)
-
- \obsolete
-
- Queries the user using a modal message box with up to two buttons.
- The message box has the given \a caption (although some window
- managers don't show it), and shows the given \a text. The left
- button has the \a yesButtonText (or tr("OK")), and the right button
- has the \a noButtonText (or isn't shown). The message box is centred
- over its \a parent and is called \a name.
-
- Use information(), question(), warning(), or critical() instead.
-*/
-
-#endif
-
-QPixmap QMessageBoxPrivate::standardIcon(QMessageBox::Icon icon, QMessageBox *mb)
-{
- QStyle *style = mb ? mb->style() : QApplication::style();
- int iconSize = style->pixelMetric(QStyle::PM_MessageBoxIconSize, 0, mb);
- QIcon tmpIcon;
- switch (icon) {
- case QMessageBox::Information:
- tmpIcon = style->standardIcon(QStyle::SP_MessageBoxInformation, 0, mb);
- break;
- case QMessageBox::Warning:
- tmpIcon = style->standardIcon(QStyle::SP_MessageBoxWarning, 0, mb);
- break;
- case QMessageBox::Critical:
- tmpIcon = style->standardIcon(QStyle::SP_MessageBoxCritical, 0, mb);
- break;
- case QMessageBox::Question:
- tmpIcon = style->standardIcon(QStyle::SP_MessageBoxQuestion, 0, mb);
- default:
- break;
- }
- if (!tmpIcon.isNull())
- return tmpIcon.pixmap(iconSize, iconSize);
- return QPixmap();
-}
-
-/*!
- \obsolete
-
- Returns the pixmap used for a standard icon. This allows the
- pixmaps to be used in more complex message boxes. \a icon
- specifies the required icon, e.g. QMessageBox::Question,
- QMessageBox::Information, QMessageBox::Warning or
- QMessageBox::Critical.
-
- Call QStyle::standardIcon() with QStyle::SP_MessageBoxInformation etc.
- instead.
-*/
-
-QPixmap QMessageBox::standardIcon(Icon icon)
-{
- return QMessageBoxPrivate::standardIcon(icon, 0);
-}
-
-/*!
- \typedef QMessageBox::Button
- \obsolete
-
- Use QMessageBox::StandardButton instead.
-*/
-
-/*!
- \fn int QMessageBox::information(QWidget *parent, const QString &title,
- const QString& text, StandardButton button0,
- StandardButton button1)
- \fn int QMessageBox::warning(QWidget *parent, const QString &title,
- const QString& text, StandardButton button0,
- StandardButton button1)
- \fn int QMessageBox::critical(QWidget *parent, const QString &title,
- const QString& text, StandardButton button0,
- StandardButton button1)
- \fn int QMessageBox::question(QWidget *parent, const QString &title,
- const QString& text, StandardButton button0,
- StandardButton button1)
- \internal
-
- ### Needed for Qt 4 source compatibility
-*/
-
-/*!
- \fn int QMessageBox::exec()
-
- Shows the message box as a \l{QDialog#Modal Dialogs}{modal dialog},
- blocking until the user closes it.
-
- When using a QMessageBox with standard buttons, this functions returns a
- \l StandardButton value indicating the standard button that was clicked.
- When using QMessageBox with custom buttons, this function returns an
- opaque value; use clickedButton() to determine which button was clicked.
-
- Users cannot interact with any other window in the same
- application until they close the dialog, either by clicking a
- button or by using a mechanism provided by the window system.
-
- \sa show(), result()
-*/
-
-QT_END_NAMESPACE
-
-#include "moc_qmessagebox.cpp"
-
-#endif // QT_NO_MESSAGEBOX
diff --git a/src/gui/dialogs/qmessagebox.h b/src/gui/dialogs/qmessagebox.h
deleted file mode 100644
index f21562d899..0000000000
--- a/src/gui/dialogs/qmessagebox.h
+++ /dev/null
@@ -1,365 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QMESSAGEBOX_H
-#define QMESSAGEBOX_H
-
-#include <QtGui/qdialog.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_MESSAGEBOX
-
-class QLabel;
-class QMessageBoxPrivate;
-class QAbstractButton;
-
-class Q_GUI_EXPORT QMessageBox : public QDialog
-{
- Q_OBJECT
- Q_ENUMS(Icon)
- Q_FLAGS(StandardButtons)
- Q_PROPERTY(QString text READ text WRITE setText)
- // ### Qt 5: Rename 'icon' 'standardIcon' and 'iconPixmap' 'icon' (and use QIcon?)
- Q_PROPERTY(Icon icon READ icon WRITE setIcon)
- Q_PROPERTY(QPixmap iconPixmap READ iconPixmap WRITE setIconPixmap)
- Q_PROPERTY(Qt::TextFormat textFormat READ textFormat WRITE setTextFormat)
- Q_PROPERTY(StandardButtons standardButtons READ standardButtons WRITE setStandardButtons)
-#ifndef QT_NO_TEXTEDIT
- Q_PROPERTY(QString detailedText READ detailedText WRITE setDetailedText)
-#endif
- Q_PROPERTY(QString informativeText READ informativeText WRITE setInformativeText)
-
-public:
- enum Icon {
- NoIcon = 0,
- Information = 1,
- Warning = 2,
- Critical = 3,
- Question = 4
- };
-
- enum ButtonRole {
- // keep this in sync with QDialogButtonBox::ButtonRole
- InvalidRole = -1,
- AcceptRole,
- RejectRole,
- DestructiveRole,
- ActionRole,
- HelpRole,
- YesRole,
- NoRole,
- ResetRole,
- ApplyRole,
-
- NRoles
- };
-
- enum StandardButton {
- // keep this in sync with QDialogButtonBox::StandardButton
- NoButton = 0x00000000,
- Ok = 0x00000400,
- Save = 0x00000800,
- SaveAll = 0x00001000,
- Open = 0x00002000,
- Yes = 0x00004000,
- YesToAll = 0x00008000,
- No = 0x00010000,
- NoToAll = 0x00020000,
- Abort = 0x00040000,
- Retry = 0x00080000,
- Ignore = 0x00100000,
- Close = 0x00200000,
- Cancel = 0x00400000,
- Discard = 0x00800000,
- Help = 0x01000000,
- Apply = 0x02000000,
- Reset = 0x04000000,
- RestoreDefaults = 0x08000000,
-
- FirstButton = Ok, // internal
- LastButton = RestoreDefaults, // internal
-
- YesAll = YesToAll, // obsolete
- NoAll = NoToAll, // obsolete
-
- Default = 0x00000100, // obsolete
- Escape = 0x00000200, // obsolete
- FlagMask = 0x00000300, // obsolete
- ButtonMask = ~FlagMask // obsolete
- };
- typedef StandardButton Button; // obsolete
-
- Q_DECLARE_FLAGS(StandardButtons, StandardButton)
-
- explicit QMessageBox(QWidget *parent = 0);
- QMessageBox(Icon icon, const QString &title, const QString &text,
- StandardButtons buttons = NoButton, QWidget *parent = 0,
- Qt::WindowFlags flags = Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint);
- ~QMessageBox();
-
- void addButton(QAbstractButton *button, ButtonRole role);
- QPushButton *addButton(const QString &text, ButtonRole role);
- QPushButton *addButton(StandardButton button);
- void removeButton(QAbstractButton *button);
-
-#ifdef Q_WS_WINCE
- void setVisible(bool visible);
-#endif
-
-#ifdef Q_NO_USING_KEYWORD
-#ifndef Q_QDOC
- void open() { QDialog::open(); }
-#endif
-#else
- using QDialog::open;
-#endif
- void open(QObject *receiver, const char *member);
-
- QList<QAbstractButton *> buttons() const;
- ButtonRole buttonRole(QAbstractButton *button) const;
-
- void setStandardButtons(StandardButtons buttons);
- StandardButtons standardButtons() const;
- StandardButton standardButton(QAbstractButton *button) const;
- QAbstractButton *button(StandardButton which) const;
-
- QPushButton *defaultButton() const;
- void setDefaultButton(QPushButton *button);
- void setDefaultButton(StandardButton button);
-
- QAbstractButton *escapeButton() const;
- void setEscapeButton(QAbstractButton *button);
- void setEscapeButton(StandardButton button);
-
- QAbstractButton *clickedButton() const;
-
- QString text() const;
- void setText(const QString &text);
-
- Icon icon() const;
- void setIcon(Icon);
-
- QPixmap iconPixmap() const;
- void setIconPixmap(const QPixmap &pixmap);
-
- Qt::TextFormat textFormat() const;
- void setTextFormat(Qt::TextFormat format);
-
- static StandardButton information(QWidget *parent, const QString &title,
- const QString &text, StandardButtons buttons = Ok,
- StandardButton defaultButton = NoButton);
- // ### Qt 5: Replace Ok with Yes|No in question() function.
- // Also consider if Ok == Yes and Cancel == No.
- static StandardButton question(QWidget *parent, const QString &title,
- const QString &text, StandardButtons buttons = Ok,
- StandardButton defaultButton = NoButton);
- static StandardButton warning(QWidget *parent, const QString &title,
- const QString &text, StandardButtons buttons = Ok,
- StandardButton defaultButton = NoButton);
- static StandardButton critical(QWidget *parent, const QString &title,
- const QString &text, StandardButtons buttons = Ok,
- StandardButton defaultButton = NoButton);
- static void about(QWidget *parent, const QString &title, const QString &text);
- static void aboutQt(QWidget *parent, const QString &title = QString());
-
- QSize sizeHint() const;
-
- // the following functions are obsolete:
-
- QMessageBox(const QString &title, const QString &text, Icon icon,
- int button0, int button1, int button2,
- QWidget *parent = 0,
- Qt::WindowFlags f = Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint);
-
- static int information(QWidget *parent, const QString &title,
- const QString& text,
- int button0, int button1 = 0, int button2 = 0);
- static int information(QWidget *parent, const QString &title,
- const QString& text,
- const QString& button0Text,
- const QString& button1Text = QString(),
- const QString& button2Text = QString(),
- int defaultButtonNumber = 0,
- int escapeButtonNumber = -1);
- inline static StandardButton information(QWidget *parent, const QString &title,
- const QString& text,
- StandardButton button0, StandardButton button1 = NoButton)
- { return information(parent, title, text, StandardButtons(button0), button1); }
-
- static int question(QWidget *parent, const QString &title,
- const QString& text,
- int button0, int button1 = 0, int button2 = 0);
- static int question(QWidget *parent, const QString &title,
- const QString& text,
- const QString& button0Text,
- const QString& button1Text = QString(),
- const QString& button2Text = QString(),
- int defaultButtonNumber = 0,
- int escapeButtonNumber = -1);
- inline static int question(QWidget *parent, const QString &title,
- const QString& text,
- StandardButton button0, StandardButton button1)
- { return question(parent, title, text, StandardButtons(button0), button1); }
-
- static int warning(QWidget *parent, const QString &title,
- const QString& text,
- int button0, int button1, int button2 = 0);
- static int warning(QWidget *parent, const QString &title,
- const QString& text,
- const QString& button0Text,
- const QString& button1Text = QString(),
- const QString& button2Text = QString(),
- int defaultButtonNumber = 0,
- int escapeButtonNumber = -1);
- inline static int warning(QWidget *parent, const QString &title,
- const QString& text,
- StandardButton button0, StandardButton button1)
- { return warning(parent, title, text, StandardButtons(button0), button1); }
-
- static int critical(QWidget *parent, const QString &title,
- const QString& text,
- int button0, int button1, int button2 = 0);
- static int critical(QWidget *parent, const QString &title,
- const QString& text,
- const QString& button0Text,
- const QString& button1Text = QString(),
- const QString& button2Text = QString(),
- int defaultButtonNumber = 0,
- int escapeButtonNumber = -1);
- inline static int critical(QWidget *parent, const QString &title,
- const QString& text,
- StandardButton button0, StandardButton button1)
- { return critical(parent, title, text, StandardButtons(button0), button1); }
-
- QString buttonText(int button) const;
- void setButtonText(int button, const QString &text);
-
- QString informativeText() const;
- void setInformativeText(const QString &text);
-
-#ifndef QT_NO_TEXTEDIT
- QString detailedText() const;
- void setDetailedText(const QString &text);
-#endif
-
- void setWindowTitle(const QString &title);
- void setWindowModality(Qt::WindowModality windowModality);
-
-#ifdef QT3_SUPPORT
- QT3_SUPPORT_CONSTRUCTOR QMessageBox(const QString &title, const QString &text, Icon icon,
- int button0, int button1, int button2,
- QWidget *parent, const char *name, bool modal,
- Qt::WindowFlags f = Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint);
- QT3_SUPPORT_CONSTRUCTOR QMessageBox(QWidget *parent, const char *name);
-
- static QT3_SUPPORT QPixmap standardIcon(Icon icon, Qt::GUIStyle);
- static QT3_SUPPORT int message(const QString &title,
- const QString& text,
- const QString& buttonText=QString(),
- QWidget *parent = 0, const char * = 0) {
- return QMessageBox::information(parent, title, text,
- buttonText.isEmpty() ? tr("OK") : buttonText) == 0;
- }
- static QT3_SUPPORT bool query(const QString &title,
- const QString& text,
- const QString& yesButtonText = QString(),
- const QString& noButtonText = QString(),
- QWidget *parent = 0, const char * = 0) {
- return QMessageBox::information(parent, title, text,
- yesButtonText.isEmpty() ? tr("OK") : yesButtonText,
- noButtonText) == 0;
- }
-#endif
-
- static QPixmap standardIcon(Icon icon);
-
-Q_SIGNALS:
- void buttonClicked(QAbstractButton *button);
-
-#ifdef qdoc
-public Q_SLOTS:
- int exec();
-#endif
-
-protected:
- bool event(QEvent *e);
- void resizeEvent(QResizeEvent *event);
- void showEvent(QShowEvent *event);
- void closeEvent(QCloseEvent *event);
- void keyPressEvent(QKeyEvent *event);
- void changeEvent(QEvent *event);
-
-private:
- Q_PRIVATE_SLOT(d_func(), void _q_buttonClicked(QAbstractButton *))
-
- Q_DISABLE_COPY(QMessageBox)
- Q_DECLARE_PRIVATE(QMessageBox)
-};
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QMessageBox::StandardButtons)
-
-#define QT_REQUIRE_VERSION(argc, argv, str) { QString s = QString::fromLatin1(str);\
-QString sq = QString::fromLatin1(qVersion()); \
-if ((sq.section(QChar::fromLatin1('.'),0,0).toInt()<<16)+\
-(sq.section(QChar::fromLatin1('.'),1,1).toInt()<<8)+\
-sq.section(QChar::fromLatin1('.'),2,2).toInt()<(s.section(QChar::fromLatin1('.'),0,0).toInt()<<16)+\
-(s.section(QChar::fromLatin1('.'),1,1).toInt()<<8)+\
-s.section(QChar::fromLatin1('.'),2,2).toInt()) { \
-if (!qApp){ \
- new QApplication(argc,argv); \
-} \
-QString s = QApplication::tr("Executable '%1' requires Qt "\
- "%2, found Qt %3.").arg(qAppName()).arg(QString::fromLatin1(\
-str)).arg(QString::fromLatin1(qVersion())); QMessageBox::critical(0, QApplication::tr(\
-"Incompatible Qt Library Error"), s, QMessageBox::Abort, 0); qFatal("%s", s.toLatin1().data()); }}
-
-#endif // QT_NO_MESSAGEBOX
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QMESSAGEBOX_H
diff --git a/src/gui/dialogs/qpagesetupdialog.h b/src/gui/dialogs/qpagesetupdialog.h
deleted file mode 100644
index b1498d22d3..0000000000
--- a/src/gui/dialogs/qpagesetupdialog.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPAGESETUPDIALOG_H
-#define QPAGESETUPDIALOG_H
-
-#include <QtGui/qabstractpagesetupdialog.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_PRINTDIALOG
-
-class QPageSetupDialogPrivate;
-
-class Q_GUI_EXPORT QPageSetupDialog : public QAbstractPageSetupDialog
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QPageSetupDialog)
- Q_ENUMS(PageSetupDialogOption)
- Q_PROPERTY(PageSetupDialogOptions options READ options WRITE setOptions)
-
-public:
- enum PageSetupDialogOption {
- None = 0x00000000, // internal
- DontUseSheet = 0x00000001,
- OwnsPrinter = 0x80000000 // internal
- };
-
- Q_DECLARE_FLAGS(PageSetupDialogOptions, PageSetupDialogOption)
-
- explicit QPageSetupDialog(QPrinter *printer, QWidget *parent = 0);
- explicit QPageSetupDialog(QWidget *parent = 0);
-
- // obsolete
- void addEnabledOption(PageSetupDialogOption option);
- void setEnabledOptions(PageSetupDialogOptions options);
- PageSetupDialogOptions enabledOptions() const;
- bool isOptionEnabled(PageSetupDialogOption option) const;
-
- void setOption(PageSetupDialogOption option, bool on = true);
- bool testOption(PageSetupDialogOption option) const;
- void setOptions(PageSetupDialogOptions options);
- PageSetupDialogOptions options() const;
-
-#if defined(Q_WS_MAC) || defined(Q_OS_WIN)
- virtual void setVisible(bool visible);
-#endif
- virtual int exec();
-
-#ifdef Q_NO_USING_KEYWORD
-#ifndef Q_QDOC
- void open() { QDialog::open(); }
-#endif
-#else
- using QDialog::open;
-#endif
- void open(QObject *receiver, const char *member);
-
-#ifdef qdoc
- QPrinter *printer();
-#endif
-};
-
-#endif // QT_NO_PRINTDIALOG
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QPAGESETUPDIALOG_H
diff --git a/src/gui/dialogs/qpagesetupdialog_unix.cpp b/src/gui/dialogs/qpagesetupdialog_unix.cpp
deleted file mode 100644
index 61a2298115..0000000000
--- a/src/gui/dialogs/qpagesetupdialog_unix.cpp
+++ /dev/null
@@ -1,620 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qpagesetupdialog.h"
-
-#ifndef QT_NO_PRINTDIALOG
-#include "qpagesetupdialog_unix_p.h"
-
-#include "qpainter.h"
-#include "qprintdialog.h"
-#include "qdialogbuttonbox.h"
-#include <ui_qpagesetupwidget.h>
-
-#include <QtGui/qprinter.h>
-#include <private/qabstractpagesetupdialog_p.h>
-#include <private/qprinter_p.h>
-
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
-# include <private/qcups_p.h>
-# include <cups/cups.h>
-# include <private/qpdf_p.h>
-#endif
-
-
-QT_BEGIN_NAMESPACE
-
-QSizeF qt_printerPaperSize(QPrinter::Orientation, QPrinter::PaperSize, QPrinter::Unit, int);
-
-// Disabled until we have support for papersources on unix
-// #define PSD_ENABLE_PAPERSOURCE
-
-static void populatePaperSizes(QComboBox* cb)
-{
- cb->addItem(QPrintDialog::tr("A0"), QPrinter::A0);
- cb->addItem(QPrintDialog::tr("A1"), QPrinter::A1);
- cb->addItem(QPrintDialog::tr("A2"), QPrinter::A2);
- cb->addItem(QPrintDialog::tr("A3"), QPrinter::A3);
- cb->addItem(QPrintDialog::tr("A4"), QPrinter::A4);
- cb->addItem(QPrintDialog::tr("A5"), QPrinter::A5);
- cb->addItem(QPrintDialog::tr("A6"), QPrinter::A6);
- cb->addItem(QPrintDialog::tr("A7"), QPrinter::A7);
- cb->addItem(QPrintDialog::tr("A8"), QPrinter::A8);
- cb->addItem(QPrintDialog::tr("A9"), QPrinter::A9);
- cb->addItem(QPrintDialog::tr("B0"), QPrinter::B0);
- cb->addItem(QPrintDialog::tr("B1"), QPrinter::B1);
- cb->addItem(QPrintDialog::tr("B2"), QPrinter::B2);
- cb->addItem(QPrintDialog::tr("B3"), QPrinter::B3);
- cb->addItem(QPrintDialog::tr("B4"), QPrinter::B4);
- cb->addItem(QPrintDialog::tr("B5"), QPrinter::B5);
- cb->addItem(QPrintDialog::tr("B6"), QPrinter::B6);
- cb->addItem(QPrintDialog::tr("B7"), QPrinter::B7);
- cb->addItem(QPrintDialog::tr("B8"), QPrinter::B8);
- cb->addItem(QPrintDialog::tr("B9"), QPrinter::B9);
- cb->addItem(QPrintDialog::tr("B10"), QPrinter::B10);
- cb->addItem(QPrintDialog::tr("C5E"), QPrinter::C5E);
- cb->addItem(QPrintDialog::tr("DLE"), QPrinter::DLE);
- cb->addItem(QPrintDialog::tr("Executive"), QPrinter::Executive);
- cb->addItem(QPrintDialog::tr("Folio"), QPrinter::Folio);
- cb->addItem(QPrintDialog::tr("Ledger"), QPrinter::Ledger);
- cb->addItem(QPrintDialog::tr("Legal"), QPrinter::Legal);
- cb->addItem(QPrintDialog::tr("Letter"), QPrinter::Letter);
- cb->addItem(QPrintDialog::tr("Tabloid"), QPrinter::Tabloid);
- cb->addItem(QPrintDialog::tr("US Common #10 Envelope"), QPrinter::Comm10E);
- cb->addItem(QPrintDialog::tr("Custom"), QPrinter::Custom);
-}
-
-
-static QSizeF sizeForOrientation(QPrinter::Orientation orientation, const QSizeF &size)
-{
- return (orientation == QPrinter::Portrait) ? size : QSizeF(size.height(), size.width());
-}
-
-#ifdef PSD_ENABLE_PAPERSOURCE
-static const char *paperSourceNames[] = {
- "Only One",
- "Lower",
- "Middle",
- "Manual",
- "Envelope",
- "Envelope manual",
- "Auto",
- "Tractor",
- "Small format",
- "Large format",
- "Large capacity",
- "Cassette",
- "Form source",
- 0
-};
-
-struct PaperSourceNames
-{
- PaperSourceNames(const char *nam, QPrinter::PaperSource ps)
- : paperSource(ps), name(nam) {}
- QPrinter::PaperSource paperSource;
- const char *name;
-};
-#endif
-
-
-class QPagePreview : public QWidget
-{
-public:
- QPagePreview(QWidget *parent) : QWidget(parent)
- {
- setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
- setMinimumSize(50, 50);
- }
-
- void setPaperSize(const QSizeF& size)
- {
- m_size = size;
- update();
- }
-
- void setMargins(qreal left, qreal top, qreal right, qreal bottom)
- {
- m_left = left;
- m_top = top;
- m_right = right;
- m_bottom = bottom;
- update();
- }
-
-protected:
- void paintEvent(QPaintEvent *)
- {
- QRect pageRect;
- QSizeF adjustedSize(m_size);
- adjustedSize.scale(width()-10, height()-10, Qt::KeepAspectRatio);
- pageRect = QRect(QPoint(0,0), adjustedSize.toSize());
- pageRect.moveCenter(rect().center());
-
- qreal width_factor = pageRect.width() / m_size.width();
- qreal height_factor = pageRect.height() / m_size.height();
- int leftSize = qRound(m_left*width_factor);
- int topSize = qRound(m_top*height_factor);
- int rightSize = qRound(m_right*width_factor);
- int bottomSize = qRound(m_bottom * height_factor);
- QRect marginRect(pageRect.x()+leftSize,
- pageRect.y()+topSize,
- pageRect.width() - (leftSize+rightSize+1),
- pageRect.height() - (topSize+bottomSize+1));
-
- QPainter p(this);
- QColor shadow(palette().mid().color());
- for (int i=1; i<6; ++i) {
- shadow.setAlpha(180-i*30);
- QRect offset(pageRect.adjusted(i, i, i, i));
- p.setPen(shadow);
- p.drawLine(offset.left(), offset.bottom(), offset.right(), offset.bottom());
- p.drawLine(offset.right(), offset.top(), offset.right(), offset.bottom()-1);
- }
- p.fillRect(pageRect, palette().light());
-
- if (marginRect.isValid()) {
- p.setPen(QPen(palette().color(QPalette::Dark), 0, Qt::DotLine));
- p.drawRect(marginRect);
-
- marginRect.adjust(2, 2, -1, -1);
- p.setClipRect(marginRect);
- QFont font;
- font.setPointSizeF(font.pointSizeF()*0.25);
- p.setFont(font);
- p.setPen(palette().color(QPalette::Dark));
- QString text(QLatin1String("Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi."));
- for (int i=0; i<3; ++i)
- text += text;
- p.drawText(marginRect, Qt::TextWordWrap|Qt::AlignVCenter, text);
- }
- }
-
-private:
- // all these are in points
- qreal m_left, m_top, m_right, m_bottom;
- QSizeF m_size;
-};
-
-
-class QPageSetupDialogPrivate : public QAbstractPageSetupDialogPrivate
-{
- Q_DECLARE_PUBLIC(QPageSetupDialog)
-
-public:
- ~QPageSetupDialogPrivate();
- void init();
-
- QPageSetupWidget *widget;
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
- QCUPSSupport *cups;
-#endif
-};
-
-QPageSetupDialogPrivate::~QPageSetupDialogPrivate()
-{
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
- delete cups;
-#endif
-}
-
-void QPageSetupDialogPrivate::init()
-{
- Q_Q(QPageSetupDialog);
-
- widget = new QPageSetupWidget(q);
- widget->setPrinter(printer);
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
- if (printer->outputFormat() == QPrinter::NativeFormat && QCUPSSupport::isAvailable()) {
- cups = new QCUPSSupport;
- widget->selectPrinter(cups);
- } else {
- cups = 0;
- }
-#endif
-
- QDialogButtonBox *buttons = new QDialogButtonBox(QDialogButtonBox::Ok
- | QDialogButtonBox::Cancel,
- Qt::Horizontal, q);
- QObject::connect(buttons, SIGNAL(accepted()), q, SLOT(accept()));
- QObject::connect(buttons, SIGNAL(rejected()), q, SLOT(reject()));
-
- QVBoxLayout *lay = new QVBoxLayout(q);
- lay->addWidget(widget);
- lay->addWidget(buttons);
-}
-
-QPageSetupWidget::QPageSetupWidget(QWidget *parent)
- : QWidget(parent),
- m_printer(0),
- m_blockSignals(false),
- m_cups(0)
-{
- widget.setupUi(this);
-
- QString suffix = (QLocale::system().measurementSystem() == QLocale::ImperialSystem)
- ? QString::fromLatin1(" in")
- : QString::fromLatin1(" mm");
- widget.topMargin->setSuffix(suffix);
- widget.bottomMargin->setSuffix(suffix);
- widget.leftMargin->setSuffix(suffix);
- widget.rightMargin->setSuffix(suffix);
- widget.paperWidth->setSuffix(suffix);
- widget.paperHeight->setSuffix(suffix);
-
- QVBoxLayout *lay = new QVBoxLayout(widget.preview);
- widget.preview->setLayout(lay);
- m_pagePreview = new QPagePreview(widget.preview);
- lay->addWidget(m_pagePreview);
-
- setAttribute(Qt::WA_WState_Polished, false);
-
-#ifdef PSD_ENABLE_PAPERSOURCE
- for (int i=0; paperSourceNames[i]; ++i)
- widget.paperSource->insertItem(paperSourceNames[i]);
-#else
- widget.paperSourceLabel->setVisible(false);
- widget.paperSource->setVisible(false);
-#endif
-
- widget.reverseLandscape->setVisible(false);
- widget.reversePortrait->setVisible(false);
-
- populatePaperSizes(widget.paperSize);
-
- QStringList units;
- units << tr("Centimeters (cm)") << tr("Millimeters (mm)") << tr("Inches (in)") << tr("Points (pt)");
- widget.unit->addItems(units);
- connect(widget.unit, SIGNAL(activated(int)), this, SLOT(unitChanged(int)));
- widget.unit->setCurrentIndex((QLocale::system().measurementSystem() == QLocale::ImperialSystem) ? 2 : 1);
-
- connect(widget.paperSize, SIGNAL(currentIndexChanged(int)), this, SLOT(_q_paperSizeChanged()));
- connect(widget.paperWidth, SIGNAL(valueChanged(double)), this, SLOT(_q_paperSizeChanged()));
- connect(widget.paperHeight, SIGNAL(valueChanged(double)), this, SLOT(_q_paperSizeChanged()));
-
- connect(widget.leftMargin, SIGNAL(valueChanged(double)), this, SLOT(setLeftMargin(double)));
- connect(widget.topMargin, SIGNAL(valueChanged(double)), this, SLOT(setTopMargin(double)));
- connect(widget.rightMargin, SIGNAL(valueChanged(double)), this, SLOT(setRightMargin(double)));
- connect(widget.bottomMargin, SIGNAL(valueChanged(double)), this, SLOT(setBottomMargin(double)));
-
- connect(widget.portrait, SIGNAL(clicked()), this, SLOT(_q_pageOrientationChanged()));
- connect(widget.landscape, SIGNAL(clicked()), this, SLOT(_q_pageOrientationChanged()));
-}
-
-void QPageSetupWidget::setPrinter(QPrinter *printer)
-{
- m_printer = printer;
- m_blockSignals = true;
- selectPdfPsPrinter(printer);
- printer->getPageMargins(&m_leftMargin, &m_topMargin, &m_rightMargin, &m_bottomMargin, QPrinter::Point);
- unitChanged(widget.unit->currentIndex());
- m_pagePreview->setMargins(m_leftMargin, m_topMargin, m_rightMargin, m_bottomMargin);
- m_paperSize = printer->paperSize(QPrinter::Point);
- widget.paperWidth->setValue(m_paperSize.width() / m_currentMultiplier);
- widget.paperHeight->setValue(m_paperSize.height() / m_currentMultiplier);
-
- widget.landscape->setChecked(printer->orientation() == QPrinter::Landscape);
-
-#ifdef PSD_ENABLE_PAPERSOURCE
- widget.paperSource->setCurrentItem(printer->paperSource());
-#endif
- Q_ASSERT(m_blockSignals);
- m_blockSignals = false;
- _q_paperSizeChanged();
-}
-
-// set gui data on printer
-void QPageSetupWidget::setupPrinter() const
-{
- QPrinter::Orientation orientation = widget.portrait->isChecked()
- ? QPrinter::Portrait
- : QPrinter::Landscape;
- m_printer->setOrientation(orientation);
- // paper format
- QVariant val = widget.paperSize->itemData(widget.paperSize->currentIndex());
- int ps = m_printer->pageSize();
- if (val.type() == QVariant::Int) {
- ps = val.toInt();
- }
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
- else if (m_cups && QCUPSSupport::isAvailable() && m_cups->currentPPD()) {
- QByteArray cupsPageSize = val.toByteArray();
- QPrintEngine *engine = m_printer->printEngine();
- engine->setProperty(PPK_CupsStringPageSize, QString::fromLatin1(cupsPageSize));
- engine->setProperty(PPK_CupsOptions, m_cups->options());
-
- QRect pageRect = m_cups->pageRect(cupsPageSize);
- engine->setProperty(PPK_CupsPageRect, pageRect);
-
- QRect paperRect = m_cups->paperRect(cupsPageSize);
- engine->setProperty(PPK_CupsPaperRect, paperRect);
-
- for(ps = 0; ps < QPrinter::NPaperSize; ++ps) {
- QPdf::PaperSize size = QPdf::paperSize(QPrinter::PaperSize(ps));
- if (size.width == paperRect.width() && size.height == paperRect.height())
- break;
- }
- }
-#endif
- if (ps == QPrinter::Custom)
- m_printer->setPaperSize(sizeForOrientation(orientation, m_paperSize), QPrinter::Point);
- else
- m_printer->setPaperSize(static_cast<QPrinter::PaperSize>(ps));
-
-#ifdef PSD_ENABLE_PAPERSOURCE
- m_printer->setPaperSource((QPrinter::PaperSource)widget.paperSource->currentIndex());
-#endif
- m_printer->setPageMargins(m_leftMargin, m_topMargin, m_rightMargin, m_bottomMargin, QPrinter::Point);
-
-}
-
-void QPageSetupWidget::selectPrinter(QCUPSSupport *cups)
-{
- m_cups = cups;
- widget.paperSize->clear();
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
- if (m_cups && QCUPSSupport::isAvailable()) {
- const ppd_option_t* pageSizes = m_cups->pageSizes();
- const int numChoices = pageSizes ? pageSizes->num_choices : 0;
-
- int cupsDefaultSize = 0;
- QSize qtPreferredSize = m_printer->paperSize(QPrinter::Point).toSize();
- bool preferredSizeMatched = false;
- for (int i = 0; i < numChoices; ++i) {
- widget.paperSize->addItem(QString::fromLocal8Bit(pageSizes->choices[i].text), QByteArray(pageSizes->choices[i].choice));
- if (static_cast<int>(pageSizes->choices[i].marked) == 1)
- cupsDefaultSize = i;
- if (m_printer->d_func()->hasUserSetPageSize) {
- QRect cupsPaperSize = m_cups->paperRect(pageSizes->choices[i].choice);
- QSize diff = cupsPaperSize.size() - qtPreferredSize;
- if (qAbs(diff.width()) < 5 && qAbs(diff.height()) < 5) {
- widget.paperSize->setCurrentIndex(i);
- preferredSizeMatched = true;
- }
- }
- }
- if (!preferredSizeMatched)
- widget.paperSize->setCurrentIndex(cupsDefaultSize);
- if (m_printer->d_func()->hasCustomPageMargins) {
- m_printer->getPageMargins(&m_leftMargin, &m_topMargin, &m_rightMargin, &m_bottomMargin, QPrinter::Point);
- } else {
- QByteArray cupsPaperSizeChoice = widget.paperSize->itemData(widget.paperSize->currentIndex()).toByteArray();
- QRect paper = m_cups->paperRect(cupsPaperSizeChoice);
- QRect content = m_cups->pageRect(cupsPaperSizeChoice);
-
- m_leftMargin = content.x() - paper.x();
- m_topMargin = content.y() - paper.y();
- m_rightMargin = paper.right() - content.right();
- m_bottomMargin = paper.bottom() - content.bottom();
- }
- }
-#endif
- if (widget.paperSize->count() == 0) {
- populatePaperSizes(widget.paperSize);
- widget.paperSize->setCurrentIndex(widget.paperSize->findData(
- QLocale::system().measurementSystem() == QLocale::ImperialSystem ? QPrinter::Letter : QPrinter::A4));
- }
-
- unitChanged(widget.unit->currentIndex());
- m_pagePreview->setMargins(m_leftMargin, m_topMargin, m_rightMargin, m_bottomMargin);
-}
-
-void QPageSetupWidget::selectPdfPsPrinter(const QPrinter *p)
-{
- m_cups = 0;
- widget.paperSize->clear();
- populatePaperSizes(widget.paperSize);
- widget.paperSize->setCurrentIndex(widget.paperSize->findData(p->paperSize()));
-
- m_leftMargin = 90;
- m_topMargin = 72;
- m_bottomMargin = 72;
- m_rightMargin = 90;
- unitChanged(widget.unit->currentIndex());
- m_pagePreview->setMargins(m_leftMargin, m_topMargin, m_rightMargin, m_bottomMargin);
-}
-
-// Updates size/preview after the combobox has been changed.
-void QPageSetupWidget::_q_paperSizeChanged()
-{
- QVariant val = widget.paperSize->itemData(widget.paperSize->currentIndex());
- int index = m_printer->pageSize();
- if (val.type() == QVariant::Int) {
- index = val.toInt();
- }
-
- if (m_blockSignals) return;
- m_blockSignals = true;
-
- QPrinter::PaperSize size = QPrinter::PaperSize(index);
- QPrinter::Orientation orientation = widget.portrait->isChecked()
- ? QPrinter::Portrait
- : QPrinter::Landscape;
-
- bool custom = size == QPrinter::Custom;
-
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
- custom = custom ? !m_cups : custom;
-#endif
-
- widget.paperWidth->setEnabled(custom);
- widget.paperHeight->setEnabled(custom);
- widget.widthLabel->setEnabled(custom);
- widget.heightLabel->setEnabled(custom);
- if (custom) {
- m_paperSize.setWidth( widget.paperWidth->value() * m_currentMultiplier);
- m_paperSize.setHeight( widget.paperHeight->value() * m_currentMultiplier);
- m_pagePreview->setPaperSize(m_paperSize);
- } else {
- Q_ASSERT(m_printer);
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
- if (m_cups) { // combobox is filled with cups based data
- QByteArray cupsPageSize = widget.paperSize->itemData(widget.paperSize->currentIndex()).toByteArray();
- m_paperSize = m_cups->paperRect(cupsPageSize).size();
- if (orientation == QPrinter::Landscape)
- m_paperSize = QSizeF(m_paperSize.height(), m_paperSize.width()); // swap
- }
- else
-#endif
- m_paperSize = qt_printerPaperSize(orientation, size, QPrinter::Point, 1);
-
- m_pagePreview->setPaperSize(m_paperSize);
- widget.paperWidth->setValue(m_paperSize.width() / m_currentMultiplier);
- widget.paperHeight->setValue(m_paperSize.height() / m_currentMultiplier);
- }
- m_blockSignals = false;
-}
-
-void QPageSetupWidget::_q_pageOrientationChanged()
-{
- if (QPrinter::PaperSize(widget.paperSize->currentIndex()) == QPrinter::Custom) {
- double tmp = widget.paperWidth->value();
- widget.paperWidth->setValue(widget.paperHeight->value());
- widget.paperHeight->setValue(tmp);
- }
- _q_paperSizeChanged();
-}
-
-extern double qt_multiplierForUnit(QPrinter::Unit unit, int resolution);
-
-void QPageSetupWidget::unitChanged(int item)
-{
- QString suffix;
- switch(item) {
- case 0:
- m_currentMultiplier = 10 * qt_multiplierForUnit(QPrinter::Millimeter, 1);
- suffix = QString::fromLatin1(" cm");
- break;
- case 2:
- m_currentMultiplier = qt_multiplierForUnit(QPrinter::Inch, 1);
- suffix = QString::fromLatin1(" in");
- break;
- case 3:
- m_currentMultiplier = qt_multiplierForUnit(QPrinter::Point, 1);
- suffix = QString::fromLatin1(" pt");
- break;
- case 1:
- default:
- m_currentMultiplier = qt_multiplierForUnit(QPrinter::Millimeter, 1);
- suffix = QString::fromLatin1(" mm");
- break;
- }
- const bool old = m_blockSignals;
- m_blockSignals = true;
- widget.topMargin->setSuffix(suffix);
- widget.leftMargin->setSuffix(suffix);
- widget.rightMargin->setSuffix(suffix);
- widget.bottomMargin->setSuffix(suffix);
- widget.paperWidth->setSuffix(suffix);
- widget.paperHeight->setSuffix(suffix);
- widget.topMargin->setValue(m_topMargin / m_currentMultiplier);
- widget.leftMargin->setValue(m_leftMargin / m_currentMultiplier);
- widget.rightMargin->setValue(m_rightMargin / m_currentMultiplier);
- widget.bottomMargin->setValue(m_bottomMargin / m_currentMultiplier);
- widget.paperWidth->setValue(m_paperSize.width() / m_currentMultiplier);
- widget.paperHeight->setValue(m_paperSize.height() / m_currentMultiplier);
- m_blockSignals = old;
-}
-
-void QPageSetupWidget::setTopMargin(double newValue)
-{
- if (m_blockSignals) return;
- m_topMargin = newValue * m_currentMultiplier;
- m_pagePreview->setMargins(m_leftMargin, m_topMargin, m_rightMargin, m_bottomMargin);
-}
-
-void QPageSetupWidget::setBottomMargin(double newValue)
-{
- if (m_blockSignals) return;
- m_bottomMargin = newValue * m_currentMultiplier;
- m_pagePreview->setMargins(m_leftMargin, m_topMargin, m_rightMargin, m_bottomMargin);
-}
-
-void QPageSetupWidget::setLeftMargin(double newValue)
-{
- if (m_blockSignals) return;
- m_leftMargin = newValue * m_currentMultiplier;
- m_pagePreview->setMargins(m_leftMargin, m_topMargin, m_rightMargin, m_bottomMargin);
-}
-
-void QPageSetupWidget::setRightMargin(double newValue)
-{
- if (m_blockSignals) return;
- m_rightMargin = newValue * m_currentMultiplier;
- m_pagePreview->setMargins(m_leftMargin, m_topMargin, m_rightMargin, m_bottomMargin);
-}
-
-
-
-QPageSetupDialog::QPageSetupDialog(QPrinter *printer, QWidget *parent)
- : QAbstractPageSetupDialog(*(new QPageSetupDialogPrivate), printer, parent)
-{
- Q_D(QPageSetupDialog);
- d->init();
-}
-
-
-QPageSetupDialog::QPageSetupDialog(QWidget *parent)
- : QAbstractPageSetupDialog(*(new QPageSetupDialogPrivate), 0, parent)
-{
- Q_D(QPageSetupDialog);
- d->init();
-}
-
-/*!
- \internal
-*/
-int QPageSetupDialog::exec()
-{
- Q_D(QPageSetupDialog);
-
- int ret = QDialog::exec();
- if (ret == Accepted)
- d->widget->setupPrinter();
- return ret;
-}
-
-
-QT_END_NAMESPACE
-
-#include "moc_qpagesetupdialog.cpp"
-
-#endif // QT_NO_PRINTDIALOG
diff --git a/src/gui/dialogs/qprintdialog.h b/src/gui/dialogs/qprintdialog.h
deleted file mode 100644
index b1e30f0445..0000000000
--- a/src/gui/dialogs/qprintdialog.h
+++ /dev/null
@@ -1,174 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPRINTDIALOG_H
-#define QPRINTDIALOG_H
-
-#include <QtGui/qabstractprintdialog.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_PRINTDIALOG
-
-class QPrintDialogPrivate;
-class QPushButton;
-class QPrinter;
-
-#if defined (Q_OS_UNIX) && !defined(QTOPIA_PRINTDIALOG) && !defined(Q_WS_MAC) && !defined(Q_OS_SYMBIAN)
-class QUnixPrintWidgetPrivate;
-
-class Q_GUI_EXPORT QUnixPrintWidget : public QWidget
-{
- Q_OBJECT
-
-public:
- QUnixPrintWidget(QPrinter *printer, QWidget *parent = 0);
- ~QUnixPrintWidget();
- void updatePrinter();
-
-private:
- friend class QPrintDialogPrivate;
- friend class QUnixPrintWidgetPrivate;
- QUnixPrintWidgetPrivate *d;
- Q_PRIVATE_SLOT(d, void _q_printerChanged(int))
- Q_PRIVATE_SLOT(d, void _q_btnBrowseClicked())
- Q_PRIVATE_SLOT(d, void _q_btnPropertiesClicked())
-};
-#endif
-
-class Q_GUI_EXPORT QPrintDialog : public QAbstractPrintDialog
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QPrintDialog)
- Q_ENUMS(PrintDialogOption)
- Q_PROPERTY(PrintDialogOptions options READ options WRITE setOptions)
-
-public:
- explicit QPrintDialog(QPrinter *printer, QWidget *parent = 0);
- explicit QPrintDialog(QWidget *parent = 0);
- ~QPrintDialog();
-
- int exec();
-#if defined (Q_OS_UNIX) && !defined(QTOPIA_PRINTDIALOG) && !defined(Q_WS_MAC)
- virtual void accept();
-#endif
- void done(int result);
-
-#if defined (Q_OS_UNIX) && defined (QT3_SUPPORT)
- QT3_SUPPORT void setPrinter(QPrinter *, bool = false);
- QT3_SUPPORT QPrinter *printer() const;
- QT3_SUPPORT void addButton(QPushButton *button);
-#endif
-
- void setOption(PrintDialogOption option, bool on = true);
- bool testOption(PrintDialogOption option) const;
- void setOptions(PrintDialogOptions options);
- PrintDialogOptions options() const;
-
-#if defined(Q_OS_UNIX) || defined(Q_WS_MAC) || defined(Q_OS_WIN)
- void setVisible(bool visible);
-#endif
-
-#ifdef Q_NO_USING_KEYWORD
-#ifndef Q_QDOC
- void open() { QDialog::open(); }
-#endif
-#else
- using QDialog::open;
-#endif
- void open(QObject *receiver, const char *member);
-
-#ifdef qdoc
- QPrinter *printer();
-#endif
-
-#ifdef QTOPIA_PRINTDIALOG
-public:
- bool eventFilter(QObject *, QEvent *);
-#endif
-
-#ifdef Q_NO_USING_KEYWORD
-#ifndef Q_QDOC
- void accepted() { QDialog::accepted(); }
-#endif
-#else
- using QDialog::accepted;
-#endif
-
-Q_SIGNALS:
- void accepted(QPrinter *printer);
-
-private:
-#ifndef QTOPIA_PRINTDIALOG
- Q_PRIVATE_SLOT(d_func(), void _q_chbPrintLastFirstToggled(bool))
-#if defined (Q_OS_UNIX) && !defined (Q_OS_MAC)
- Q_PRIVATE_SLOT(d_func(), void _q_collapseOrExpandDialog())
-#endif
-# if defined(Q_OS_UNIX) && !defined (Q_OS_MAC) && !defined(QT_NO_MESSAGEBOX)
- Q_PRIVATE_SLOT(d_func(), void _q_checkFields())
-# endif
-#else // QTOPIA_PRINTDIALOG
- Q_PRIVATE_SLOT(d_func(), void _q_okClicked())
- Q_PRIVATE_SLOT(d_func(),void _q_printerOrFileSelected(QAbstractButton *b))
- Q_PRIVATE_SLOT(d_func(),void _q_paperSizeSelected(int))
- Q_PRIVATE_SLOT(d_func(), void _q_orientSelected(int))
- Q_PRIVATE_SLOT(d_func(), void _q_pageOrderSelected(int))
- Q_PRIVATE_SLOT(d_func(), void _q_colorModeSelected(QAbstractButton *))
- Q_PRIVATE_SLOT(d_func(), void _q_setNumCopies(int))
- Q_PRIVATE_SLOT(d_func(), void _q_printRangeSelected(int))
- Q_PRIVATE_SLOT(d_func(), void _q_setFirstPage(int))
- Q_PRIVATE_SLOT(d_func(), void _q_setLastPage(int))
- Q_PRIVATE_SLOT(d_func(), void _q_fileNameEditChanged(const QString &text))
-#endif // QTOPIA_PRINTDIALOG
- friend class QUnixPrintWidget;
-};
-
-#endif // QT_NO_PRINTDIALOG
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QPRINTDIALOG_H
diff --git a/src/gui/dialogs/qprintdialog_qws.cpp b/src/gui/dialogs/qprintdialog_qws.cpp
deleted file mode 100644
index 49e1eaa11d..0000000000
--- a/src/gui/dialogs/qprintdialog_qws.cpp
+++ /dev/null
@@ -1,567 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qplatformdefs.h"
-
-#include <private/qabstractprintdialog_p.h>
-#include "qprintdialog.h"
-
-#ifndef QT_NO_PRINTDIALOG
-
-#include "qapplication.h"
-#include "qbuttongroup.h"
-#include "qradiobutton.h"
-#include "qcombobox.h"
-#include "qspinbox.h"
-#include "qprinter.h"
-#include "qlineedit.h"
-#include "qdir.h"
-#include "qmessagebox.h"
-#include "qinputdialog.h"
-#include "qlayout.h"
-#include "qlabel.h"
-
-#include "qlibrary.h"
-
-#ifndef QT_NO_NIS
-
-#ifndef BOOL_DEFINED
-#define BOOL_DEFINED
-#endif
-
-#include <rpcsvc/ypclnt.h>
-#include <rpcsvc/yp_prot.h>
-
-#endif //QT_NO_NIS
-
-#include <ctype.h>
-#include <stdlib.h>
-
-#include <qdebug.h>
-
-QT_BEGIN_NAMESPACE
-
-typedef void (*QPrintDialogCreator)(QPrintDialog *parent);
-Q_GUI_EXPORT QPrintDialogCreator _qt_print_dialog_creator;
-
-class QPrintDialogPrivate : public QAbstractPrintDialogPrivate
-{
- Q_DECLARE_PUBLIC(QPrintDialog)
-public:
- QButtonGroup *printerOrFile;
- bool outputToFile;
- QRadioButton *printToPrinterButton;
- QRadioButton *printToFileButton;
- QLineEdit *fileName;
-
- QButtonGroup *colorMode;
- QRadioButton *printColor;
- QRadioButton *printGray;
- QPrinter::ColorMode colorMode2;
-
- QComboBox *orientationCombo, *sizeCombo;
- QPrinter::PaperSize pageSize;
- QPrinter::Orientation orientation;
-
- QSpinBox *copies;
- int numCopies;
- QPrinter::PaperSize indexToPaperSize[QPrinter::NPaperSize];
-
- QComboBox *rangeCombo;
- QSpinBox *firstPage;
- QSpinBox *lastPage;
-
- QComboBox *pageOrderCombo;
- QPrinter::PageOrder pageOrder2;
-
- QString faxNum;
-
- void init();
-
- void _q_okClicked();
- void _q_printerOrFileSelected(QAbstractButton *b);
- void _q_paperSizeSelected(int);
- void _q_orientSelected(int);
- void _q_pageOrderSelected(int);
- void _q_colorModeSelected(QAbstractButton *);
- void _q_setNumCopies(int);
- void _q_printRangeSelected(int);
- void _q_setFirstPage(int);
- void _q_setLastPage(int);
- void _q_fileNameEditChanged(const QString &text);
-
- void setupDestination();
- void setupPrinterSettings();
- void setupPaper();
- void setupOptions();
-
- void setPrinter(QPrinter *p, bool pickUpSettings);
-};
-
-static void isc(QPrintDialogPrivate *d, const QString & text,
- QPrinter::PaperSize ps);
-
-void QPrintDialogPrivate::_q_okClicked()
-{
- Q_Q(QPrintDialog);
-#ifndef QT_NO_MESSAGEBOX
- if (outputToFile && fileName->isModified() && QFileInfo(fileName->text()).exists()) {
- int confirm = QMessageBox::warning(
- q, QPrintDialog::tr("File exists"),
- QPrintDialog::tr("<qt>Do you want to overwrite it?</qt>"),
- QMessageBox::Yes, QMessageBox::No);
- if (confirm == QMessageBox::No)
- return;
- }
-#endif // QT_NO_MESSAGEBOX
-
- lastPage->interpretText();
- firstPage->interpretText();
- copies->interpretText();
- if (outputToFile) {
- printer->setOutputFileName(fileName->text());
- }
- printer->setOrientation(orientation);
- printer->setPaperSize(pageSize);
- printer->setPageOrder(pageOrder2);
- printer->setColorMode(colorMode2);
- printer->setCopyCount(numCopies);
-
- switch ((rangeCombo->itemData(rangeCombo->currentIndex())).toInt()){
- case (int)QPrintDialog::AllPages:
- q->setPrintRange(QPrintDialog::AllPages);
- q->setFromTo(0, 0);
- break;
- case (int)QPrintDialog::Selection:
- q->setPrintRange(QPrintDialog::Selection);
- q->setFromTo(0, 0);
- break;
- case (int)QPrintDialog::PageRange:
- q->setPrintRange(QPrintDialog::PageRange);
- q->setFromTo(firstPage->value(), lastPage->value());
- break;
- case (int)QPrintDialog::CurrentPage:
- q->setPrintRange(QPrintDialog::CurrentPage);
- q->setFromTo(0, 0);
- break;
- }
- q->accept();
-}
-
-void QPrintDialogPrivate::_q_printerOrFileSelected(QAbstractButton *b)
-{
- outputToFile = (b == printToFileButton);
- if (outputToFile) {
- _q_fileNameEditChanged(fileName->text());
- if (!fileName->isModified() && fileName->text().isEmpty()) {
- QString file = "print.tiff";
- fileName->setText(file);
- fileName->setCursorPosition(file.length());
- fileName->selectAll();
- fileName->setModified(true); // confirm overwrite when OK clicked
-
- }
- fileName->setEnabled(true);
- fileName->setFocus();
- } else {
- fileName->setText(QString());
- if (fileName->isEnabled())
- fileName->setEnabled(false);
- }
-}
-
-void QPrintDialogPrivate::_q_paperSizeSelected(int id)
-{
- if (id < QPrinter::NPaperSize)
- pageSize = QPrinter::PaperSize(indexToPaperSize[id]);
-}
-
-void QPrintDialogPrivate::_q_orientSelected(int id)
-{
- orientation = (QPrinter::Orientation)id;
-}
-
-void QPrintDialogPrivate::_q_pageOrderSelected(int id)
-{
- pageOrder2 = (QPrinter::PageOrder)id;
-}
-
-void QPrintDialogPrivate::_q_colorModeSelected(QAbstractButton *b)
-{
- colorMode2 = (b == printColor) ? QPrinter::Color : QPrinter::GrayScale;
-}
-
-void QPrintDialogPrivate::_q_setNumCopies(int copies)
-{
- numCopies = copies;
-}
-
-void QPrintDialogPrivate::_q_printRangeSelected(int id)
-{
- bool enable = (rangeCombo->itemData(id).toInt() == (int)QPrintDialog::PageRange);
- firstPage->setEnabled(enable);
- lastPage->setEnabled(enable);
-}
-
-void QPrintDialogPrivate::_q_setFirstPage(int fp)
-{
- Q_Q(QPrintDialog);
- if (printer) {
- lastPage->setMinimum(fp);
- lastPage->setMaximum(qMax(fp, q->maxPage()));
- }
-}
-
-void QPrintDialogPrivate::_q_setLastPage(int lp)
-{
- Q_Q(QPrintDialog);
- if (printer) {
- firstPage->setMinimum(qMin(lp, q->minPage()));
- firstPage->setMaximum(lp);
- }
-}
-
-void QPrintDialogPrivate::_q_fileNameEditChanged(const QString &text)
-{
- Q_UNUSED(text);
-}
-
-void QPrintDialogPrivate::setupDestination()
-{
- Q_Q(QPrintDialog);
-
- // print destinations
- printerOrFile = new QButtonGroup(q);
- QObject::connect(printerOrFile, SIGNAL(buttonClicked(QAbstractButton*)),
- q, SLOT(_q_printerOrFileSelected(QAbstractButton*)));
-
- printToPrinterButton = q->findChild<QRadioButton *>("printToPrinterButton");
- printerOrFile->addButton(printToPrinterButton);
- printToFileButton = q->findChild<QRadioButton *>("printToFileButton");
- printerOrFile->addButton(printToFileButton);
-
- // file name
- fileName = q->findChild<QLineEdit *>("fileName");
- QObject::connect(fileName, SIGNAL(textChanged(QString)),
- q, SLOT(_q_fileNameEditChanged(QString)));
-
- outputToFile = false;
-}
-
-void QPrintDialogPrivate::setupPrinterSettings()
-{
- Q_Q(QPrintDialog);
-
- // color mode
- colorMode = new QButtonGroup(q);
- QObject::connect(colorMode, SIGNAL(buttonClicked(QAbstractButton*)),
- q, SLOT(_q_colorModeSelected(QAbstractButton*)));
-
- printColor = q->findChild<QRadioButton *>("printColor");
- colorMode->addButton(printColor);
- printGray = q->findChild<QRadioButton *>("printGray");
- colorMode->addButton(printGray);
-}
-
-void isc(QPrintDialogPrivate *ptr, const QString & text, QPrinter::PaperSize ps)
-{
- if (ptr && !text.isEmpty() && ps < QPrinter::NPaperSize) {
- ptr->sizeCombo->addItem(text);
- int index = ptr->sizeCombo->count()-1;
- if (index >= 0 && index < QPrinter::NPaperSize)
- ptr->indexToPaperSize[index] = ps;
- }
-}
-
-void QPrintDialogPrivate::setupPaper()
-{
- Q_Q(QPrintDialog);
-
- pageSize = QPrinter::A4;
-
- // paper orientation
- orientationCombo = q->findChild<QComboBox *>("orientationCombo");
- orientation = QPrinter::Portrait;
- QObject::connect(orientationCombo, SIGNAL(activated(int)),
- q, SLOT(_q_orientSelected(int)));
-
- // paper size
- sizeCombo = q->findChild<QComboBox *>("sizeCombo");
-
- int n;
- for(n=0; n<QPrinter::NPaperSize; n++)
- indexToPaperSize[n] = QPrinter::A4;
-
- isc(this, QPrintDialog::tr("A0 (841 x 1189 mm)"), QPrinter::A0);
- isc(this, QPrintDialog::tr("A1 (594 x 841 mm)"), QPrinter::A1);
- isc(this, QPrintDialog::tr("A2 (420 x 594 mm)"), QPrinter::A2);
- isc(this, QPrintDialog::tr("A3 (297 x 420 mm)"), QPrinter::A3);
- isc(this, QPrintDialog::tr("A4 (210 x 297 mm, 8.26 x 11.7 inches)"), QPrinter::A4);
- isc(this, QPrintDialog::tr("A5 (148 x 210 mm)"), QPrinter::A5);
- isc(this, QPrintDialog::tr("A6 (105 x 148 mm)"), QPrinter::A6);
- isc(this, QPrintDialog::tr("A7 (74 x 105 mm)"), QPrinter::A7);
- isc(this, QPrintDialog::tr("A8 (52 x 74 mm)"), QPrinter::A8);
- isc(this, QPrintDialog::tr("A9 (37 x 52 mm)"), QPrinter::A9);
- isc(this, QPrintDialog::tr("B0 (1000 x 1414 mm)"), QPrinter::B0);
- isc(this, QPrintDialog::tr("B1 (707 x 1000 mm)"), QPrinter::B1);
- isc(this, QPrintDialog::tr("B2 (500 x 707 mm)"), QPrinter::B2);
- isc(this, QPrintDialog::tr("B3 (353 x 500 mm)"), QPrinter::B3);
- isc(this, QPrintDialog::tr("B4 (250 x 353 mm)"), QPrinter::B4);
- isc(this, QPrintDialog::tr("B5 (176 x 250 mm, 6.93 x 9.84 inches)"), QPrinter::B5);
- isc(this, QPrintDialog::tr("B6 (125 x 176 mm)"), QPrinter::B6);
- isc(this, QPrintDialog::tr("B7 (88 x 125 mm)"), QPrinter::B7);
- isc(this, QPrintDialog::tr("B8 (62 x 88 mm)"), QPrinter::B8);
- isc(this, QPrintDialog::tr("B9 (44 x 62 mm)"), QPrinter::B9);
- isc(this, QPrintDialog::tr("B10 (31 x 44 mm)"), QPrinter::B10);
- isc(this, QPrintDialog::tr("C5E (163 x 229 mm)"), QPrinter::C5E);
- isc(this, QPrintDialog::tr("DLE (110 x 220 mm)"), QPrinter::DLE);
- isc(this, QPrintDialog::tr("Executive (7.5 x 10 inches, 191 x 254 mm)"), QPrinter::Executive);
- isc(this, QPrintDialog::tr("Folio (210 x 330 mm)"), QPrinter::Folio);
- isc(this, QPrintDialog::tr("Ledger (432 x 279 mm)"), QPrinter::Ledger);
- isc(this, QPrintDialog::tr("Legal (8.5 x 14 inches, 216 x 356 mm)"), QPrinter::Legal);
- isc(this, QPrintDialog::tr("Letter (8.5 x 11 inches, 216 x 279 mm)"), QPrinter::Letter);
- isc(this, QPrintDialog::tr("Tabloid (279 x 432 mm)"), QPrinter::Tabloid);
- isc(this, QPrintDialog::tr("US Common #10 Envelope (105 x 241 mm)"), QPrinter::Comm10E);
-
- QObject::connect(sizeCombo, SIGNAL(activated(int)),
- q, SLOT(_q_paperSizeSelected(int)));
-}
-
-void QPrintDialogPrivate::setupOptions()
-{
- Q_Q(QPrintDialog);
-
- // no. of copies
- copies = q->findChild<QSpinBox *>("copies");
- QObject::connect(copies, SIGNAL(valueChanged(int)),
- q, SLOT(_q_setNumCopies(int)));
-
- // print range
- rangeCombo = q->findChild<QComboBox *>("rangeCombo");
- rangeCombo->addItem(QPrintDialog::tr("Print all"), QPrintDialog::AllPages);
- rangeCombo->addItem(QPrintDialog::tr("Print selection"), QPrintDialog::Selection);
- rangeCombo->addItem(QPrintDialog::tr("Print range"), QPrintDialog::PageRange);
- rangeCombo->addItem(QPrintDialog::tr("Print current page"), QPrintDialog::CurrentPage);
- QObject::connect(rangeCombo, SIGNAL(activated(int)),
- q, SLOT(_q_printRangeSelected(int)));
-
- // page range
- firstPage = q->findChild<QSpinBox *>("firstPage");
- firstPage->setRange(1, 9999);
- firstPage->setValue(1);
- QObject::connect(firstPage, SIGNAL(valueChanged(int)),
- q, SLOT(_q_setFirstPage(int)));
-
- lastPage = q->findChild<QSpinBox *>("lastPage");
- lastPage->setRange(1, 9999);
- lastPage->setValue(1);
- QObject::connect(lastPage, SIGNAL(valueChanged(int)),
- q, SLOT(_q_setLastPage(int)));
-
- // print order
- pageOrderCombo = q->findChild<QComboBox *>("pageOrderCombo");
- QObject::connect(pageOrderCombo, SIGNAL(activated(int)),
- q, SLOT(_q_pageOrderSelected(int)));
-}
-
-bool QPrintDialog::eventFilter(QObject *o, QEvent *e)
-{
- Q_UNUSED(o);
-
- Q_D(QPrintDialog);
- switch (e->type()){
- case QEvent::KeyPress:
- switch (static_cast<QKeyEvent*>(e)->key()) {
- case Qt::Key_Back:
- d->_q_okClicked();
- return true;
- }
- break;
- default:
- break;
- }
- return false;
-}
-
-QPrintDialog::QPrintDialog(QPrinter *printer, QWidget *parent)
- : QAbstractPrintDialog(*(new QPrintDialogPrivate), printer, parent)
-{
- d_func()->init();
-}
-
-QPrintDialog::QPrintDialog(QWidget *parent)
- : QAbstractPrintDialog(*(new QPrintDialogPrivate), 0, parent)
-{
- d_func()->init();
-}
-
-QPrintDialog::~QPrintDialog()
-{
-}
-
-void QPrintDialogPrivate::setPrinter(QPrinter *p, bool pickUpSettings)
-{
- Q_Q(QPrintDialog);
- printer = p;
-
- if (p && pickUpSettings) {
- // top to bottom in the old dialog.
- // printer or file
- outputToFile = !p->outputFileName().isEmpty() && q->isOptionEnabled(QPrintDialog::PrintToFile);
- if (outputToFile)
- printToFileButton->setChecked(true);
- else
- printToPrinterButton->setChecked(true);
- fileName->setEnabled(outputToFile);
-
- // file name
- if (q->isOptionEnabled(QPrintDialog::PrintToFile)) {
- fileName->setText(p->outputFileName());
- fileName->setModified(!fileName->text().isEmpty());
- } else {
- printToFileButton->setEnabled(false);
- }
-
- // orientation
- orientationCombo->setCurrentIndex((int)p->orientation());
- _q_orientSelected(p->orientation());
-
- // page size
- int n = 0;
- while (n < QPrinter::NPaperSize &&
- indexToPaperSize[n] != p->pageSize())
- n++;
- sizeCombo->setCurrentIndex(n);
- _q_paperSizeSelected(n);
-
- // page order
- pageOrder2 = p->pageOrder();
- pageOrderCombo->setCurrentIndex((int)pageOrder2);
-
- // color mode
- colorMode2 = p->colorMode();
- if (colorMode2 == QPrinter::Color)
- printColor->setChecked(true);
- else
- printGray->setChecked(true);
-
- // number of copies
- copies->setValue(p->copyCount());
- _q_setNumCopies(p->copyCount());
- }
-
- if (p) {
- if (!q->isOptionEnabled(QPrintDialog::PrintSelection)
- && rangeCombo->findData(QPrintDialog::Selection) > 0)
- rangeCombo->removeItem(rangeCombo->findData(QPrintDialog::Selection));
- if (!q->isOptionEnabled(QPrintDialog::PrintPageRange)
- && rangeCombo->findData(QPrintDialog::PageRange) > 0)
- rangeCombo->removeItem(rangeCombo->findData(QPrintDialog::PageRange));
- if (!q->isOptionEnabled(QPrintDialog::PrintCurrentPage)
- && rangeCombo->findData(QPrintDialog::CurrentPage) > 0)
- rangeCombo->removeItem(rangeCombo->findData(QPrintDialog::CurrentPage));
-
- switch (q->printRange()) {
- case QPrintDialog::AllPages:
- rangeCombo->setCurrentIndex((int)(QPrintDialog::AllPages));
- break;
- case QPrintDialog::Selection:
- rangeCombo->setCurrentIndex((int)(QPrintDialog::Selection));
- break;
- case QPrintDialog::PageRange:
- rangeCombo->setCurrentIndex((int)(QPrintDialog::PageRange));
- break;
- case QPrintDialog::CurrentPage:
- rangeCombo->setCurrentIndex((int)(QPrintDialog::CurrentPage));
- break;
- }
- }
-
- if (p && q->maxPage()) {
- int from = q->minPage();
- int to = q->maxPage();
- if (q->printRange() == QPrintDialog::PageRange) {
- from = q->fromPage();
- to = q->toPage();
- }
- firstPage->setRange(q->minPage(), to);
- lastPage->setRange(from, q->maxPage());
- firstPage->setValue(from);
- lastPage->setValue(to);
- }
-}
-
-int QPrintDialog::exec()
-{
- Q_D(QPrintDialog);
- d->setPrinter(d->printer, true);
- return QDialog::exec();
-}
-
-void QPrintDialogPrivate::init()
-{
- Q_Q(QPrintDialog);
- numCopies = 1;
-
- if (_qt_print_dialog_creator)
- (*_qt_print_dialog_creator)(q);
-
- setupDestination();
- setupPrinterSettings();
- setupPaper();
- setupOptions();
-
- setPrinter(printer, true);
-
- q->installEventFilter(q);
-}
-
-void QPrintDialog::setVisible(bool visible)
-{
- QAbstractPrintDialog::setVisible(visible);
-}
-
-QT_END_NAMESPACE
-
-#include "moc_qprintdialog.cpp"
-#include "qrc_qprintdialog.cpp"
-
-#endif // QT_NO_PRINTDIALOG
diff --git a/src/gui/dialogs/qprintdialog_unix.cpp b/src/gui/dialogs/qprintdialog_unix.cpp
deleted file mode 100644
index bb9b9306fd..0000000000
--- a/src/gui/dialogs/qprintdialog_unix.cpp
+++ /dev/null
@@ -1,1309 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qplatformdefs.h"
-
-#ifndef QT_NO_PRINTDIALOG
-
-#include "private/qabstractprintdialog_p.h"
-#include <QtGui/qmessagebox.h>
-#include "qprintdialog.h"
-#include "qfiledialog.h"
-#include <QtCore/qdir.h>
-#include <QtGui/qevent.h>
-#include <QtGui/qfilesystemmodel.h>
-#include <QtGui/qstyleditemdelegate.h>
-#include <QtGui/qprinter.h>
-
-#include <QtGui/qdialogbuttonbox.h>
-
-#include "qfscompleter_p.h"
-#include "ui_qprintpropertieswidget.h"
-#include "ui_qprintsettingsoutput.h"
-#include "ui_qprintwidget.h"
-
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
-# include <private/qcups_p.h>
-# include <cups/cups.h>
-# include <private/qpdf_p.h>
-#else
-# include <QtCore/qlibrary.h>
-#endif
-
-#include <private/qprinterinfo_unix_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QOptionTreeItem;
-class QPPDOptionsModel;
-
-class QPrintPropertiesDialog : public QDialog
-{
- Q_OBJECT
-public:
- QPrintPropertiesDialog(QAbstractPrintDialog *parent = 0);
- ~QPrintPropertiesDialog();
-
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
- void setCups(QCUPSSupport *cups) { m_cups = cups; }
- void addItemToOptions(QOptionTreeItem *parent, QList<const ppd_option_t*>& options, QList<const char*>& markedOptions) const;
-#endif
-
- void selectPrinter();
- void selectPdfPsPrinter(const QPrinter *p);
-
- /// copy printer properties to the widget
- void applyPrinterProperties(QPrinter *p);
- void setupPrinter() const;
-
-protected:
- void showEvent(QShowEvent* event);
-
-private:
- Ui::QPrintPropertiesWidget widget;
- QDialogButtonBox *m_buttons;
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
- QCUPSSupport *m_cups;
- QPPDOptionsModel *m_cupsOptionsModel;
-#endif
-};
-
-class QPrintDialogPrivate : public QAbstractPrintDialogPrivate
-{
- Q_DECLARE_PUBLIC(QPrintDialog)
- Q_DECLARE_TR_FUNCTIONS(QPrintDialog)
-public:
- QPrintDialogPrivate();
- ~QPrintDialogPrivate();
-
- void init();
- /// copy printer properties to the widget
- void applyPrinterProperties(QPrinter *p);
-
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
- void selectPrinter(QCUPSSupport *cups);
-#endif
-
- void _q_chbPrintLastFirstToggled(bool);
-#ifndef QT_NO_MESSAGEBOX
- void _q_checkFields();
-#endif
- void _q_collapseOrExpandDialog();
-
- void setupPrinter();
- void updateWidgets();
-
- virtual void setTabs(const QList<QWidget*> &tabs);
-
- Ui::QPrintSettingsOutput options;
- QUnixPrintWidget *top;
- QWidget *bottom;
- QDialogButtonBox *buttons;
- QPushButton *collapseButton;
-};
-
-#if defined (Q_OS_UNIX)
-class QUnixPrintWidgetPrivate
-{
-public:
- QUnixPrintWidgetPrivate(QUnixPrintWidget *q);
- ~QUnixPrintWidgetPrivate();
-
- /// copy printer properties to the widget
- void applyPrinterProperties(QPrinter *p);
- bool checkFields();
- void setupPrinter();
- void setOptionsPane(QPrintDialogPrivate *pane);
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
- void setCupsProperties();
-#endif
-
-// slots
- void _q_printerChanged(int index);
- void _q_btnPropertiesClicked();
- void _q_btnBrowseClicked();
-
- QUnixPrintWidget * const parent;
- QPrintPropertiesDialog *propertiesDialog;
- Ui::QPrintWidget widget;
- QAbstractPrintDialog * q;
- QPrinter *printer;
- QList<QPrinterDescription> lprPrinters;
- void updateWidget();
-
-private:
- QPrintDialogPrivate *optionsPane;
- bool filePrintersAdded;
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
- QCUPSSupport* cups;
- int cupsPrinterCount;
- const cups_dest_t* cupsPrinters;
- const ppd_file_t* cupsPPD;
-#endif
-};
-#endif
-
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
-class QOptionTreeItem
-{
-public:
- enum ItemType { Root, Group, Option, Choice };
-
- QOptionTreeItem(ItemType t, int i, const void* p, const char* desc, QOptionTreeItem* pi)
- : type(t),
- index(i),
- ptr(p),
- description(desc),
- selected(-1),
- selDescription(0),
- parentItem(pi) {}
-
- ~QOptionTreeItem() {
- while (!childItems.isEmpty())
- delete childItems.takeFirst();
- }
-
- ItemType type;
- int index;
- const void* ptr;
- const char* description;
- int selected;
- const char* selDescription;
- QOptionTreeItem* parentItem;
- QList<QOptionTreeItem*> childItems;
-};
-
-class QPPDOptionsModel : public QAbstractItemModel
-{
- friend class QPPDOptionsEditor;
-public:
- QPPDOptionsModel(QCUPSSupport *cups, QObject *parent = 0);
- ~QPPDOptionsModel();
-
- int columnCount(const QModelIndex& parent = QModelIndex()) const;
- int rowCount(const QModelIndex& parent = QModelIndex()) const;
- QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
- QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const;
- QModelIndex parent(const QModelIndex& index) const;
- Qt::ItemFlags flags(const QModelIndex& index) const;
- QVariant headerData ( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const;
-
- QOptionTreeItem* rootItem;
- QCUPSSupport *cups;
- const ppd_file_t* ppd;
- void parseItems();
- void parseGroups(QOptionTreeItem* parent);
- void parseOptions(QOptionTreeItem* parent);
- void parseChoices(QOptionTreeItem* parent);
-};
-
-class QPPDOptionsEditor : public QStyledItemDelegate
-{
- Q_OBJECT
-public:
- QPPDOptionsEditor(QObject* parent = 0) : QStyledItemDelegate(parent) {}
- ~QPPDOptionsEditor() {}
-
- QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const;
- void setEditorData(QWidget* editor, const QModelIndex& index) const;
- void setModelData( QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const;
-
-private slots:
- void cbChanged(int index);
-
-};
-
-#endif
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-QPrintPropertiesDialog::QPrintPropertiesDialog(QAbstractPrintDialog *parent)
- : QDialog(parent)
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
- , m_cups(0), m_cupsOptionsModel(0)
-#endif
-{
- QVBoxLayout *lay = new QVBoxLayout(this);
- this->setLayout(lay);
- QWidget *content = new QWidget(this);
- widget.setupUi(content);
- m_buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, this);
- lay->addWidget(content);
- lay->addWidget(m_buttons);
-
- connect(m_buttons->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(accept()));
- connect(m_buttons->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), this, SLOT(reject()));
-}
-
-QPrintPropertiesDialog::~QPrintPropertiesDialog()
-{
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
- delete m_cupsOptionsModel;
-#else
- delete widget.cupsPropertiesPage;
-#endif
-}
-
-void QPrintPropertiesDialog::applyPrinterProperties(QPrinter *p)
-{
- widget.pageSetup->setPrinter(p);
-}
-
-void QPrintPropertiesDialog::setupPrinter() const
-{
- widget.pageSetup->setupPrinter();
-
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
- QPPDOptionsModel* model = static_cast<QPPDOptionsModel*>(widget.treeView->model());
- if (model) {
- QOptionTreeItem* rootItem = model->rootItem;
- QList<const ppd_option_t*> options;
- QList<const char*> markedOptions;
-
- addItemToOptions(rootItem, options, markedOptions);
- model->cups->saveOptions(options, markedOptions);
- }
-#endif
-}
-
-void QPrintPropertiesDialog::selectPrinter()
-{
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
- widget.pageSetup->selectPrinter(m_cups);
- widget.treeView->setModel(0);
- if (m_cups && QCUPSSupport::isAvailable()) {
-
- if (m_cupsOptionsModel == 0) {
- m_cupsOptionsModel = new QPPDOptionsModel(m_cups);
-
- widget.treeView->setItemDelegate(new QPPDOptionsEditor(this));
- } else {
- // update the model
- m_cupsOptionsModel->parseItems();
- }
-
- if (m_cupsOptionsModel->rowCount() > 0) {
- widget.treeView->setModel(m_cupsOptionsModel);
-
- for (int i = 0; i < m_cupsOptionsModel->rowCount(); ++i)
- widget.treeView->expand(m_cupsOptionsModel->index(i,0));
-
- widget.tabs->setTabEnabled(1, true); // enable the advanced tab
- } else {
- widget.tabs->setTabEnabled(1, false);
- }
-
- } else
-#endif
- {
- widget.cupsPropertiesPage->setEnabled(false);
- widget.pageSetup->selectPrinter(0);
- }
-}
-
-void QPrintPropertiesDialog::selectPdfPsPrinter(const QPrinter *p)
-{
- widget.treeView->setModel(0);
- widget.pageSetup->selectPdfPsPrinter(p);
- widget.tabs->setTabEnabled(1, false); // disable the advanced tab
-}
-
-void QPrintPropertiesDialog::showEvent(QShowEvent* event)
-{
- widget.treeView->resizeColumnToContents(0);
- event->accept();
-}
-
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
-void QPrintPropertiesDialog::addItemToOptions(QOptionTreeItem *parent, QList<const ppd_option_t*>& options, QList<const char*>& markedOptions) const
-{
- for (int i = 0; i < parent->childItems.count(); ++i) {
- QOptionTreeItem *itm = parent->childItems.at(i);
- if (itm->type == QOptionTreeItem::Option) {
- const ppd_option_t* opt = reinterpret_cast<const ppd_option_t*>(itm->ptr);
- options << opt;
- if (qstrcmp(opt->defchoice, opt->choices[itm->selected].choice) != 0) {
- markedOptions << opt->keyword << opt->choices[itm->selected].choice;
- }
- } else {
- addItemToOptions(itm, options, markedOptions);
- }
- }
-}
-#endif
-
-QPrintDialogPrivate::QPrintDialogPrivate()
- : top(0), bottom(0), buttons(0), collapseButton(0)
-{
-}
-
-QPrintDialogPrivate::~QPrintDialogPrivate()
-{
-}
-
-void QPrintDialogPrivate::init()
-{
- Q_Q(QPrintDialog);
-
- top = new QUnixPrintWidget(0, q);
- bottom = new QWidget(q);
- options.setupUi(bottom);
- options.color->setIconSize(QSize(32, 32));
- options.color->setIcon(QIcon(QLatin1String(":/trolltech/dialogs/qprintdialog/images/status-color.png")));
- options.grayscale->setIconSize(QSize(32, 32));
- options.grayscale->setIcon(QIcon(QLatin1String(":/trolltech/dialogs/qprintdialog/images/status-gray-scale.png")));
- top->d->setOptionsPane(this);
-
- buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, q);
- collapseButton = new QPushButton(QPrintDialog::tr("&Options >>"), buttons);
- buttons->addButton(collapseButton, QDialogButtonBox::ResetRole);
- bottom->setVisible(false);
-
- QPushButton *printButton = buttons->button(QDialogButtonBox::Ok);
- printButton->setText(QPrintDialog::tr("&Print"));
- printButton->setDefault(true);
-
- QVBoxLayout *lay = new QVBoxLayout(q);
- q->setLayout(lay);
- lay->addWidget(top);
- lay->addWidget(bottom);
- lay->addWidget(buttons);
-
- QPrinter* p = q->printer();
-
- applyPrinterProperties(p);
-
-#ifdef QT_NO_MESSAGEBOX
- QObject::connect(buttons, SIGNAL(accepted()), q, SLOT(accept()));
-#else
- QObject::connect(buttons, SIGNAL(accepted()), q, SLOT(_q_checkFields()));
-#endif
- QObject::connect(buttons, SIGNAL(rejected()), q, SLOT(reject()));
-
- QObject::connect(options.reverse, SIGNAL(toggled(bool)),
- q, SLOT(_q_chbPrintLastFirstToggled(bool)));
-
- QObject::connect(collapseButton, SIGNAL(released()), q, SLOT(_q_collapseOrExpandDialog()));
-}
-
-void QPrintDialogPrivate::applyPrinterProperties(QPrinter *p)
-{
- if (p->colorMode() == QPrinter::Color)
- options.color->setChecked(true);
- else
- options.grayscale->setChecked(true);
-
- switch(p->duplex()) {
- case QPrinter::DuplexNone:
- options.noDuplex->setChecked(true); break;
- case QPrinter::DuplexLongSide:
- case QPrinter::DuplexAuto:
- options.duplexLong->setChecked(true); break;
- case QPrinter::DuplexShortSide:
- options.duplexShort->setChecked(true); break;
- }
- options.copies->setValue(p->copyCount());
- options.collate->setChecked(p->collateCopies());
- options.reverse->setChecked(p->pageOrder() == QPrinter::LastPageFirst);
- top->d->applyPrinterProperties(p);
-}
-
-void QPrintDialogPrivate::_q_chbPrintLastFirstToggled(bool checked)
-{
- Q_Q(QPrintDialog);
- if (checked)
- q->printer()->setPageOrder(QPrinter::LastPageFirst);
- else
- q->printer()->setPageOrder(QPrinter::FirstPageFirst);
-}
-
-void QPrintDialogPrivate::_q_collapseOrExpandDialog()
-{
- int collapseHeight = 0;
- Q_Q(QPrintDialog);
- QWidget *widgetToHide = bottom;
- if (widgetToHide->isVisible()) {
- collapseButton->setText(QPrintDialog::tr("&Options >>"));
- collapseHeight = widgetToHide->y() + widgetToHide->height() - (top->y() + top->height());
- }
- else
- collapseButton->setText(QPrintDialog::tr("&Options <<"));
- widgetToHide->setVisible(! widgetToHide->isVisible());
- if (! widgetToHide->isVisible()) { // make it shrink
- q->layout()->activate();
- q->resize( QSize(q->width(), q->height() - collapseHeight) );
- }
-}
-
-#ifndef QT_NO_MESSAGEBOX
-void QPrintDialogPrivate::_q_checkFields()
-{
- Q_Q(QPrintDialog);
- if (top->d->checkFields())
- q->accept();
-}
-#endif // QT_NO_MESSAGEBOX
-
-void QPrintDialogPrivate::setupPrinter()
-{
- Q_Q(QPrintDialog);
- QPrinter* p = q->printer();
-
- if (options.duplex->isEnabled()) {
- if (options.noDuplex->isChecked())
- p->setDuplex(QPrinter::DuplexNone);
- else if (options.duplexLong->isChecked())
- p->setDuplex(QPrinter::DuplexLongSide);
- else
- p->setDuplex(QPrinter::DuplexShortSide);
- }
-
- p->setColorMode( options.color->isChecked() ? QPrinter::Color : QPrinter::GrayScale );
-
- // print range
- if (options.printAll->isChecked()) {
- p->setPrintRange(QPrinter::AllPages);
- p->setFromTo(0,0);
- } else if (options.printSelection->isChecked()) {
- p->setPrintRange(QPrinter::Selection);
- p->setFromTo(0,0);
- } else if (options.printCurrentPage->isChecked()) {
- p->setPrintRange(QPrinter::CurrentPage);
- p->setFromTo(0,0);
- } else if (options.printRange->isChecked()) {
- p->setPrintRange(QPrinter::PageRange);
- p->setFromTo(options.from->value(), qMax(options.from->value(), options.to->value()));
- }
-
- // copies
- p->setCopyCount(options.copies->value());
- p->setCollateCopies(options.collate->isChecked());
-
- top->d->setupPrinter();
-}
-
-void QPrintDialogPrivate::updateWidgets()
-{
- Q_Q(QPrintDialog);
- options.gbPrintRange->setVisible(q->isOptionEnabled(QPrintDialog::PrintPageRange) ||
- q->isOptionEnabled(QPrintDialog::PrintSelection) ||
- q->isOptionEnabled(QPrintDialog::PrintCurrentPage));
-
- options.printRange->setEnabled(q->isOptionEnabled(QPrintDialog::PrintPageRange));
- options.printSelection->setVisible(q->isOptionEnabled(QPrintDialog::PrintSelection));
- options.printCurrentPage->setVisible(q->isOptionEnabled(QPrintDialog::PrintCurrentPage));
- options.collate->setVisible(q->isOptionEnabled(QPrintDialog::PrintCollateCopies));
-
- switch (q->printRange()) {
- case QPrintDialog::AllPages:
- options.printAll->setChecked(true);
- break;
- case QPrintDialog::Selection:
- options.printSelection->setChecked(true);
- break;
- case QPrintDialog::PageRange:
- options.printRange->setChecked(true);
- break;
- case QPrintDialog::CurrentPage:
- if (q->isOptionEnabled(QPrintDialog::PrintCurrentPage))
- options.printCurrentPage->setChecked(true);
- break;
- default:
- break;
- }
- const int minPage = qMax(1, qMin(q->minPage() , q->maxPage()));
- const int maxPage = qMax(1, q->maxPage() == INT_MAX ? 9999 : q->maxPage());
-
- options.from->setMinimum(minPage);
- options.to->setMinimum(minPage);
- options.from->setMaximum(maxPage);
- options.to->setMaximum(maxPage);
-
- options.from->setValue(q->fromPage());
- options.to->setValue(q->toPage());
- top->d->updateWidget();
-}
-
-void QPrintDialogPrivate::setTabs(const QList<QWidget*> &tabWidgets)
-{
- while(options.tabs->count() > 2)
- delete options.tabs->widget(2);
-
- QList<QWidget*>::ConstIterator iter = tabWidgets.begin();
- while(iter != tabWidgets.constEnd()) {
- QWidget *tab = *iter;
- options.tabs->addTab(tab, tab->windowTitle());
- ++iter;
- }
-}
-
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
-void QPrintDialogPrivate::selectPrinter(QCUPSSupport *cups)
-{
- options.duplex->setEnabled(cups && cups->ppdOption("Duplex"));
-}
-#endif
-
-////////////////////////////////////////////////////////////////////////////////
-
-QPrintDialog::QPrintDialog(QPrinter *printer, QWidget *parent)
- : QAbstractPrintDialog(*(new QPrintDialogPrivate), printer, parent)
-{
- Q_D(QPrintDialog);
- d->init();
-}
-
-/*!
- Constructs a print dialog with the given \a parent.
-*/
-QPrintDialog::QPrintDialog(QWidget *parent)
- : QAbstractPrintDialog(*(new QPrintDialogPrivate), 0, parent)
-{
- Q_D(QPrintDialog);
- d->init();
-}
-
-QPrintDialog::~QPrintDialog()
-{
-}
-
-void QPrintDialog::setVisible(bool visible)
-{
- Q_D(QPrintDialog);
-
- if (visible)
- d->updateWidgets();
-
- QAbstractPrintDialog::setVisible(visible);
-}
-
-int QPrintDialog::exec()
-{
- return QDialog::exec();
-}
-
-void QPrintDialog::accept()
-{
- Q_D(QPrintDialog);
- d->setupPrinter();
- QDialog::accept();
-}
-
-#ifdef QT3_SUPPORT
-QPrinter *QPrintDialog::printer() const
-{
- Q_D(const QPrintDialog);
- return d->printer;
-}
-
-void QPrintDialog::setPrinter(QPrinter *printer, bool pickupSettings)
-{
- if (!printer)
- return;
-
- Q_D(QPrintDialog);
- d->printer = printer;
-
- if (pickupSettings)
- d->applyPrinterProperties(printer);
-}
-
-void QPrintDialog::addButton(QPushButton *button)
-{
- Q_D(QPrintDialog);
- d->buttons->addButton(button, QDialogButtonBox::HelpRole);
-}
-#endif // QT3_SUPPORT
-
-#if defined (Q_OS_UNIX)
-
-/*! \internal
-*/
-QUnixPrintWidgetPrivate::QUnixPrintWidgetPrivate(QUnixPrintWidget *p)
- : parent(p), propertiesDialog(0), printer(0), optionsPane(0), filePrintersAdded(false)
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
- , cups(0), cupsPrinterCount(0), cupsPrinters(0), cupsPPD(0)
-#endif
-{
- q = 0;
- if (parent)
- q = qobject_cast<QAbstractPrintDialog*> (parent->parent());
-
- widget.setupUi(parent);
-
- int currentPrinterIndex = 0;
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
- cups = new QCUPSSupport;
- if (QCUPSSupport::isAvailable()) {
- cupsPPD = cups->currentPPD();
- cupsPrinterCount = cups->availablePrintersCount();
- cupsPrinters = cups->availablePrinters();
-
- for (int i = 0; i < cupsPrinterCount; ++i) {
- QString printerName(QString::fromLocal8Bit(cupsPrinters[i].name));
- if (cupsPrinters[i].instance)
- printerName += QLatin1Char('/') + QString::fromLocal8Bit(cupsPrinters[i].instance);
-
- widget.printers->addItem(printerName);
- if (cupsPrinters[i].is_default)
- widget.printers->setCurrentIndex(i);
- }
- // the model depends on valid ppd. so before enabling the
- // properties button we make sure the ppd is in fact valid.
- if (cupsPrinterCount && cups->currentPPD()) {
- widget.properties->setEnabled(true);
- }
- currentPrinterIndex = cups->currentPrinterIndex();
- } else {
-#endif
- currentPrinterIndex = qt_getLprPrinters(lprPrinters);
- // populating printer combo
- QList<QPrinterDescription>::const_iterator i = lprPrinters.constBegin();
- for(; i != lprPrinters.constEnd(); ++i)
- widget.printers->addItem((*i).name);
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
- }
-#endif
-
-#if !defined(QT_NO_FILESYSTEMMODEL) && !defined(QT_NO_COMPLETER)
- QFileSystemModel *fsm = new QFileSystemModel(widget.filename);
- fsm->setRootPath(QDir::homePath());
- widget.filename->setCompleter(new QCompleter(fsm, widget.filename));
-#endif
- _q_printerChanged(currentPrinterIndex);
-
- QObject::connect(widget.printers, SIGNAL(currentIndexChanged(int)),
- parent, SLOT(_q_printerChanged(int)));
- QObject::connect(widget.fileBrowser, SIGNAL(clicked()), parent, SLOT(_q_btnBrowseClicked()));
- QObject::connect(widget.properties, SIGNAL(clicked()), parent, SLOT(_q_btnPropertiesClicked()));
-
- // disable features that QPrinter does not yet support.
- widget.preview->setVisible(false);
-}
-
-void QUnixPrintWidgetPrivate::updateWidget()
-{
- const bool printToFile = q == 0 || q->isOptionEnabled(QPrintDialog::PrintToFile);
- if (printToFile && !filePrintersAdded) {
- if (widget.printers->count())
- widget.printers->insertSeparator(widget.printers->count());
- widget.printers->addItem(QPrintDialog::tr("Print to File (PDF)"));
- widget.printers->addItem(QPrintDialog::tr("Print to File (Postscript)"));
- filePrintersAdded = true;
- }
- if (!printToFile && filePrintersAdded) {
- widget.printers->removeItem(widget.printers->count()-1);
- widget.printers->removeItem(widget.printers->count()-1);
- if (widget.printers->count())
- widget.printers->removeItem(widget.printers->count()-1); // remove separator
- filePrintersAdded = false;
- }
- if (printer && filePrintersAdded && (printer->outputFormat() != QPrinter::NativeFormat
- || printer->printerName().isEmpty()))
- {
- if (printer->outputFormat() == QPrinter::PdfFormat)
- widget.printers->setCurrentIndex(widget.printers->count() - 2);
- else if (printer->outputFormat() == QPrinter::PostScriptFormat)
- widget.printers->setCurrentIndex(widget.printers->count() - 1);
- widget.filename->setEnabled(true);
- widget.lOutput->setEnabled(true);
- }
-
- widget.filename->setVisible(printToFile);
- widget.lOutput->setVisible(printToFile);
- widget.fileBrowser->setVisible(printToFile);
-
- widget.properties->setVisible(q->isOptionEnabled(QAbstractPrintDialog::PrintShowPageSize));
-}
-
-QUnixPrintWidgetPrivate::~QUnixPrintWidgetPrivate()
-{
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
- delete cups;
-#endif
-}
-
-void QUnixPrintWidgetPrivate::_q_printerChanged(int index)
-{
- if (index < 0)
- return;
- const int printerCount = widget.printers->count();
- widget.filename->setEnabled(false);
- widget.lOutput->setEnabled(false);
-
- if (filePrintersAdded) {
- Q_ASSERT(index != printerCount - 3); // separator
- if (index > printerCount - 3) { // PDF or postscript
- bool pdfPrinter = (index == printerCount - 2);
- widget.location->setText(QPrintDialog::tr("Local file"));
- widget.type->setText(QPrintDialog::tr("Write %1 file").arg(pdfPrinter ? QString::fromLatin1("PDF")
- : QString::fromLatin1("PostScript")));
- widget.properties->setEnabled(true);
- widget.filename->setEnabled(true);
- QString filename = widget.filename->text();
- QString suffix = QFileInfo(filename).suffix();
- if (pdfPrinter && suffix == QLatin1String("ps"))
- filename = filename.replace(QLatin1String(".ps"), QLatin1String(".pdf"));
- if (!pdfPrinter && suffix == QLatin1String("pdf"))
- filename = filename.replace(QLatin1String(".pdf"), QLatin1String(".ps"));
- widget.filename->setText(filename);
- widget.lOutput->setEnabled(true);
- if (propertiesDialog)
- propertiesDialog->selectPdfPsPrinter(printer);
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
- if (optionsPane)
- optionsPane->selectPrinter(0);
-#endif
- return;
- }
- }
-
- widget.location->setText(QString());
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
- if (QCUPSSupport::isAvailable()) {
- cups->setCurrentPrinter(index);
-
- const cups_option_t *opt = cups->printerOption(QString::fromLatin1("printer-location"));
- QString location;
- if (opt)
- location = QString::fromLocal8Bit(opt->value);
- widget.location->setText(location);
-
- cupsPPD = cups->currentPPD();
- // set printer type line
- QString type;
- if (cupsPPD)
- type = QString::fromLocal8Bit(cupsPPD->manufacturer) + QLatin1String(" - ") + QString::fromLocal8Bit(cupsPPD->modelname);
- widget.type->setText(type);
- if (propertiesDialog)
- propertiesDialog->selectPrinter();
- if (optionsPane)
- optionsPane->selectPrinter(cups);
- } else {
- if (optionsPane)
- optionsPane->selectPrinter(0);
-#endif
- if (lprPrinters.count() > 0) {
- QString type = lprPrinters.at(index).name + QLatin1Char('@') + lprPrinters.at(index).host;
- if (!lprPrinters.at(index).comment.isEmpty())
- type += QLatin1String(", ") + lprPrinters.at(index).comment;
- widget.type->setText(type);
- if (propertiesDialog)
- propertiesDialog->selectPrinter();
- }
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
- }
-#endif
-}
-
-void QUnixPrintWidgetPrivate::setOptionsPane(QPrintDialogPrivate *pane)
-{
- optionsPane = pane;
- if (optionsPane)
- _q_printerChanged(widget.printers->currentIndex());
-}
-
-void QUnixPrintWidgetPrivate::_q_btnBrowseClicked()
-{
- QString filename = widget.filename->text();
-#ifndef QT_NO_FILEDIALOG
- filename = QFileDialog::getSaveFileName(parent, QPrintDialog::tr("Print To File ..."), filename,
- QString(), 0, QFileDialog::DontConfirmOverwrite);
-#else
- filename.clear();
-#endif
- if (!filename.isEmpty()) {
- widget.filename->setText(filename);
- if (filename.endsWith(QString::fromLatin1(".ps"), Qt::CaseInsensitive))
- widget.printers->setCurrentIndex(widget.printers->count() - 1); // the postscript one
- else if (filename.endsWith(QString::fromLatin1(".pdf"), Qt::CaseInsensitive))
- widget.printers->setCurrentIndex(widget.printers->count() - 2); // the pdf one
- else if (widget.printers->currentIndex() != widget.printers->count() - 1) // if ps is not selected, pdf is default
- widget.printers->setCurrentIndex(widget.printers->count() - 2); // the pdf one
- }
-}
-
-void QUnixPrintWidgetPrivate::applyPrinterProperties(QPrinter *p)
-{
- if (p == 0)
- return;
- printer = p;
- if (p->outputFileName().isEmpty()) {
- QString home = QString::fromLocal8Bit(qgetenv("HOME").constData());
- QString cur = QDir::currentPath();
- if (home.at(home.length()-1) != QLatin1Char('/'))
- home += QLatin1Char('/');
- if (cur.at(cur.length()-1) != QLatin1Char('/'))
- cur += QLatin1Char('/');
- if (cur.left(home.length()) != home)
- cur = home;
-#ifdef Q_WS_X11
- if (p->docName().isEmpty()) {
- if (p->outputFormat() == QPrinter::PostScriptFormat)
- cur += QLatin1String("print.ps");
- else
- cur += QLatin1String("print.pdf");
- } else {
- QRegExp re(QString::fromLatin1("(.*)\\.\\S+"));
- if (re.exactMatch(p->docName()))
- cur += re.cap(1);
- else
- cur += p->docName();
- if (p->outputFormat() == QPrinter::PostScriptFormat)
- cur += QLatin1String(".ps");
- else
- cur += QLatin1String(".pdf");
- }
-#endif
- widget.filename->setText(cur);
- }
- else
- widget.filename->setText( p->outputFileName() );
- QString printer = p->printerName();
- if (!printer.isEmpty()) {
- for (int i = 0; i < widget.printers->count(); ++i) {
- if (widget.printers->itemText(i) == printer) {
- widget.printers->setCurrentIndex(i);
- break;
- }
- }
- }
- // PDF and PS printers are not added to the dialog yet, we'll handle those cases in QUnixPrintWidgetPrivate::updateWidget
-
- if (propertiesDialog)
- propertiesDialog->applyPrinterProperties(p);
-}
-
-#ifndef QT_NO_MESSAGEBOX
-bool QUnixPrintWidgetPrivate::checkFields()
-{
- if (widget.filename->isEnabled()) {
- QString file = widget.filename->text();
- QFile f(file);
- QFileInfo fi(f);
- bool exists = fi.exists();
- bool opened = false;
- if (exists && fi.isDir()) {
- QMessageBox::warning(q, q->windowTitle(),
- QPrintDialog::tr("%1 is a directory.\nPlease choose a different file name.").arg(file));
- return false;
- } else if ((exists && !fi.isWritable()) || !(opened = f.open(QFile::Append))) {
- QMessageBox::warning(q, q->windowTitle(),
- QPrintDialog::tr("File %1 is not writable.\nPlease choose a different file name.").arg(file));
- return false;
- } else if (exists) {
- int ret = QMessageBox::question(q, q->windowTitle(),
- QPrintDialog::tr("%1 already exists.\nDo you want to overwrite it?").arg(file),
- QMessageBox::Yes|QMessageBox::No, QMessageBox::No);
- if (ret == QMessageBox::No)
- return false;
- }
- if (opened) {
- f.close();
- if (!exists)
- f.remove();
- }
- }
-
- // Every test passed. Accept the dialog.
- return true;
-}
-#endif // QT_NO_MESSAGEBOX
-
-void QUnixPrintWidgetPrivate::_q_btnPropertiesClicked()
-{
- if (!propertiesDialog) {
- propertiesDialog = new QPrintPropertiesDialog(q);
- propertiesDialog->setResult(QDialog::Rejected);
- }
-
- if (propertiesDialog->result() == QDialog::Rejected) {
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
- propertiesDialog->setCups(cups);
-#endif
- propertiesDialog->applyPrinterProperties(q->printer());
-
- if (q->isOptionEnabled(QPrintDialog::PrintToFile)
- && (widget.printers->currentIndex() > widget.printers->count() - 3)) // PDF or postscript
- propertiesDialog->selectPdfPsPrinter(q->printer());
- else
- propertiesDialog->selectPrinter();
- }
- propertiesDialog->exec();
-}
-
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
-void QUnixPrintWidgetPrivate::setCupsProperties()
-{
- if (cups && QCUPSSupport::isAvailable() && cups->pageSizes()) {
- QPrintEngine *engine = printer->printEngine();
- const ppd_option_t* pageSizes = cups->pageSizes();
- QByteArray cupsPageSize;
- for (int i = 0; i < pageSizes->num_choices; ++i) {
- if (static_cast<int>(pageSizes->choices[i].marked) == 1)
- cupsPageSize = pageSizes->choices[i].choice;
- }
- engine->setProperty(PPK_CupsStringPageSize, QString::fromLatin1(cupsPageSize));
- engine->setProperty(PPK_CupsOptions, cups->options());
-
- QRect pageRect = cups->pageRect(cupsPageSize);
- engine->setProperty(PPK_CupsPageRect, pageRect);
-
- QRect paperRect = cups->paperRect(cupsPageSize);
- engine->setProperty(PPK_CupsPaperRect, paperRect);
-
- for (int ps = 0; ps < QPrinter::NPaperSize; ++ps) {
- QPdf::PaperSize size = QPdf::paperSize(QPrinter::PaperSize(ps));
- if (size.width == paperRect.width() && size.height == paperRect.height())
- printer->setPaperSize(static_cast<QPrinter::PaperSize>(ps));
- }
- }
-}
-#endif
-
-void QUnixPrintWidgetPrivate::setupPrinter()
-{
- const int printerCount = widget.printers->count();
- const int index = widget.printers->currentIndex();
-
- if (filePrintersAdded && index > printerCount - 3) { // PDF or postscript
- printer->setPrinterName(QString());
- Q_ASSERT(index != printerCount - 3); // separator
- if (index == printerCount - 2)
- printer->setOutputFormat(QPrinter::PdfFormat);
- else
- printer->setOutputFormat(QPrinter::PostScriptFormat);
- QString path = widget.filename->text();
- if (QDir::isRelativePath(path))
- path = QDir::homePath() + QDir::separator() + path;
- printer->setOutputFileName(path);
- }
- else {
- printer->setPrinterName(widget.printers->currentText());
- printer->setOutputFileName(QString());
- }
-
- if (propertiesDialog && propertiesDialog->result() == QDialog::Accepted)
- propertiesDialog->setupPrinter();
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
- if (!propertiesDialog)
- setCupsProperties();
-#endif
-}
-
-
-/*! \internal
-*/
-QUnixPrintWidget::QUnixPrintWidget(QPrinter *printer, QWidget *parent)
- : QWidget(parent), d(new QUnixPrintWidgetPrivate(this))
-{
- d->applyPrinterProperties(printer);
-}
-
-/*! \internal
-*/
-QUnixPrintWidget::~QUnixPrintWidget()
-{
- delete d;
-}
-
-/*! \internal
-
- Updates the printer with the states held in the QUnixPrintWidget.
-*/
-void QUnixPrintWidget::updatePrinter()
-{
- d->setupPrinter();
-}
-
-#endif
-
-////////////////////////////////////////////////////////////////////////////////
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
-
-QPPDOptionsModel::QPPDOptionsModel(QCUPSSupport *c, QObject *parent)
- : QAbstractItemModel(parent), rootItem(0), cups(c), ppd(c->currentPPD())
-{
- parseItems();
-}
-
-QPPDOptionsModel::~QPPDOptionsModel()
-{
-}
-
-int QPPDOptionsModel::columnCount(const QModelIndex&) const
-{
- return 2;
-}
-
-int QPPDOptionsModel::rowCount(const QModelIndex& parent) const
-{
- QOptionTreeItem* itm;
- if (!parent.isValid())
- itm = rootItem;
- else
- itm = reinterpret_cast<QOptionTreeItem*>(parent.internalPointer());
-
- if (itm->type == QOptionTreeItem::Option)
- return 0;
-
- return itm->childItems.count();
-}
-
-QVariant QPPDOptionsModel::data(const QModelIndex& index, int role) const
-{
- switch(role) {
- case Qt::FontRole: {
- QOptionTreeItem* itm = reinterpret_cast<QOptionTreeItem*>(index.internalPointer());
- if (itm && itm->type == QOptionTreeItem::Group){
- QFont font = QApplication::font();
- font.setBold(true);
- return QVariant(font);
- }
- return QVariant();
- }
- break;
-
- case Qt::DisplayRole: {
- QOptionTreeItem* itm;
- if (!index.isValid())
- itm = rootItem;
- else
- itm = reinterpret_cast<QOptionTreeItem*>(index.internalPointer());
-
- if (index.column() == 0)
- return cups->unicodeString(itm->description);
- else if (itm->type == QOptionTreeItem::Option && itm->selected > -1)
- return cups->unicodeString(itm->selDescription);
- else
- return QVariant();
- }
- break;
-
- default:
- return QVariant();
- }
- if (role != Qt::DisplayRole)
- return QVariant();
-}
-
-QModelIndex QPPDOptionsModel::index(int row, int column, const QModelIndex& parent) const
-{
- QOptionTreeItem* itm;
- if (!parent.isValid())
- itm = rootItem;
- else
- itm = reinterpret_cast<QOptionTreeItem*>(parent.internalPointer());
-
- return createIndex(row, column, itm->childItems.at(row));
-}
-
-
-QModelIndex QPPDOptionsModel::parent(const QModelIndex& index) const
-{
- if (!index.isValid())
- return QModelIndex();
-
- QOptionTreeItem* itm = reinterpret_cast<QOptionTreeItem*>(index.internalPointer());
-
- if (itm->parentItem && itm->parentItem != rootItem)
- return createIndex(itm->parentItem->index, 0, itm->parentItem);
- else
- return QModelIndex();
-}
-
-Qt::ItemFlags QPPDOptionsModel::flags(const QModelIndex& index) const
-{
- if (!index.isValid() || reinterpret_cast<QOptionTreeItem*>(index.internalPointer())->type == QOptionTreeItem::Group)
- return Qt::ItemIsEnabled;
-
- if (index.column() == 1)
- return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
-
- return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
-}
-
-void QPPDOptionsModel::parseItems()
-{
- emit layoutAboutToBeChanged();
- ppd = cups->currentPPD();
- delete rootItem;
- rootItem = new QOptionTreeItem(QOptionTreeItem::Root, 0, ppd, "Root Item", 0);
- parseGroups(rootItem);
- emit layoutChanged();
-}
-
-void QPPDOptionsModel::parseGroups(QOptionTreeItem* parent)
-{
- if (parent->type == QOptionTreeItem::Root) {
-
- const ppd_file_t* ppdFile = reinterpret_cast<const ppd_file_t*>(parent->ptr);
-
- if (ppdFile) {
- for (int i = 0; i < ppdFile->num_groups; ++i) {
- QOptionTreeItem* group = new QOptionTreeItem(QOptionTreeItem::Group, i, &ppdFile->groups[i], ppdFile->groups[i].text, parent);
- parent->childItems.append(group);
- parseGroups(group); // parse possible subgroups
- parseOptions(group); // parse options
- }
- }
- } else if (parent->type == QOptionTreeItem::Group) {
-
- const ppd_group_t* group = reinterpret_cast<const ppd_group_t*>(parent->ptr);
-
- if (group) {
- for (int i = 0; i < group->num_subgroups; ++i) {
- QOptionTreeItem* subgroup = new QOptionTreeItem(QOptionTreeItem::Group, i, &group->subgroups[i], group->subgroups[i].text, parent);
- parent->childItems.append(subgroup);
- parseGroups(subgroup); // parse possible subgroups
- parseOptions(subgroup); // parse options
- }
- }
- }
-}
-
-void QPPDOptionsModel::parseOptions(QOptionTreeItem* parent)
-{
- const ppd_group_t* group = reinterpret_cast<const ppd_group_t*>(parent->ptr);
- for (int i = 0; i < group->num_options; ++i) {
- QOptionTreeItem* opt = new QOptionTreeItem(QOptionTreeItem::Option, i, &group->options[i], group->options[i].text, parent);
- parent->childItems.append(opt);
- parseChoices(opt);
- }
-}
-
-void QPPDOptionsModel::parseChoices(QOptionTreeItem* parent)
-{
- const ppd_option_t* option = reinterpret_cast<const ppd_option_t*>(parent->ptr);
- bool marked = false;
- for (int i = 0; i < option->num_choices; ++i) {
- QOptionTreeItem* choice = new QOptionTreeItem(QOptionTreeItem::Choice, i, &option->choices[i], option->choices[i].text, parent);
- if (static_cast<int>(option->choices[i].marked) == 1) {
- parent->selected = i;
- parent->selDescription = option->choices[i].text;
- marked = true;
- } else if (!marked && qstrcmp(option->choices[i].choice, option->defchoice) == 0) {
- parent->selected = i;
- parent->selDescription = option->choices[i].text;
- }
- parent->childItems.append(choice);
- }
-}
-
-QVariant QPPDOptionsModel::headerData(int section, Qt::Orientation, int role) const
-{
- if (role != Qt::DisplayRole)
- return QVariant();
-
- switch(section){
- case 0:
- return QVariant(QApplication::translate("QPPDOptionsModel", "Name"));
- case 1:
- return QVariant(QApplication::translate("QPPDOptionsModel", "Value"));
- default:
- return QVariant();
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-QWidget* QPPDOptionsEditor::createEditor(QWidget* parent, const QStyleOptionViewItem&, const QModelIndex& index) const
-{
- if (index.column() == 1 && reinterpret_cast<QOptionTreeItem*>(index.internalPointer())->type == QOptionTreeItem::Option)
- return new QComboBox(parent);
- else
- return 0;
-}
-
-void QPPDOptionsEditor::setEditorData(QWidget* editor, const QModelIndex& index) const
-{
- if (index.column() != 1)
- return;
-
- QComboBox* cb = static_cast<QComboBox*>(editor);
- QOptionTreeItem* itm = reinterpret_cast<QOptionTreeItem*>(index.internalPointer());
-
- if (itm->selected == -1)
- cb->addItem(QString());
-
- for (int i = 0; i < itm->childItems.count(); ++i)
- cb->addItem(QString::fromLocal8Bit(itm->childItems.at(i)->description));
-
- if (itm->selected > -1)
- cb->setCurrentIndex(itm->selected);
-
- connect(cb, SIGNAL(currentIndexChanged(int)), this, SLOT(cbChanged(int)));
-}
-
-void QPPDOptionsEditor::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const
-{
- QComboBox* cb = static_cast<QComboBox*>(editor);
- QOptionTreeItem* itm = reinterpret_cast<QOptionTreeItem*>(index.internalPointer());
-
- if (itm->selected == cb->currentIndex())
- return;
-
- const ppd_option_t* opt = reinterpret_cast<const ppd_option_t*>(itm->ptr);
- QPPDOptionsModel* m = static_cast<QPPDOptionsModel*>(model);
-
- if (m->cups->markOption(opt->keyword, opt->choices[cb->currentIndex()].choice) == 0) {
- itm->selected = cb->currentIndex();
- itm->selDescription = reinterpret_cast<const ppd_option_t*>(itm->ptr)->choices[itm->selected].text;
- }
-}
-
-void QPPDOptionsEditor::cbChanged(int)
-{
-/*
- emit commitData(static_cast<QWidget*>(sender()));
-*/
-}
-
-#endif
-
-QT_END_NAMESPACE
-
-#include "moc_qprintdialog.cpp"
-#include "qprintdialog_unix.moc"
-#include "qrc_qprintdialog.cpp"
-
-#endif // QT_NO_PRINTDIALOG
-
diff --git a/src/gui/dialogs/qprintpreviewdialog.cpp b/src/gui/dialogs/qprintpreviewdialog.cpp
deleted file mode 100644
index e65bfb5efc..0000000000
--- a/src/gui/dialogs/qprintpreviewdialog.cpp
+++ /dev/null
@@ -1,802 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qprintpreviewdialog.h"
-#include "qprintpreviewwidget.h"
-#include <private/qprinter_p.h>
-#include "private/qdialog_p.h"
-
-#include <QtGui/qaction.h>
-#include <QtGui/qboxlayout.h>
-#include <QtGui/qcombobox.h>
-#include <QtGui/qlabel.h>
-#include <QtGui/qlineedit.h>
-#include <QtGui/qpagesetupdialog.h>
-#include <QtGui/qprinter.h>
-#include <QtGui/qstyle.h>
-#include <QtGui/qtoolbutton.h>
-#include <QtGui/qvalidator.h>
-#include <QtGui/qfiledialog.h>
-#include <QtGui/qmainwindow.h>
-#include <QtGui/qtoolbar.h>
-#include <QtGui/qformlayout.h>
-#include <QtCore/QCoreApplication>
-
-#include <math.h>
-
-#ifndef QT_NO_PRINTPREVIEWDIALOG
-
-QT_BEGIN_NAMESPACE
-
-namespace {
-class QPrintPreviewMainWindow : public QMainWindow
-{
-public:
- QPrintPreviewMainWindow(QWidget *parent) : QMainWindow(parent) {}
- QMenu *createPopupMenu() { return 0; }
-};
-
-class ZoomFactorValidator : public QDoubleValidator
-{
-public:
- ZoomFactorValidator(QObject* parent)
- : QDoubleValidator(parent) {}
- ZoomFactorValidator(qreal bottom, qreal top, int decimals, QObject *parent)
- : QDoubleValidator(bottom, top, decimals, parent) {}
-
- State validate(QString &input, int &pos) const
- {
- bool replacePercent = false;
- if (input.endsWith(QLatin1Char('%'))) {
- input = input.left(input.length() - 1);
- replacePercent = true;
- }
- State state = QDoubleValidator::validate(input, pos);
- if (replacePercent)
- input += QLatin1Char('%');
- const int num_size = 4;
- if (state == Intermediate) {
- int i = input.indexOf(QLocale::system().decimalPoint());
- if ((i == -1 && input.size() > num_size)
- || (i != -1 && i > num_size))
- return Invalid;
- }
- return state;
- }
-};
-
-class LineEdit : public QLineEdit
-{
- Q_OBJECT
-public:
- LineEdit(QWidget* parent = 0)
- : QLineEdit(parent)
- {
- setContextMenuPolicy(Qt::NoContextMenu);
- connect(this, SIGNAL(returnPressed()), SLOT(handleReturnPressed()));
- }
-
-protected:
- void focusInEvent(QFocusEvent *e)
- {
- origText = text();
- QLineEdit::focusInEvent(e);
- }
-
- void focusOutEvent(QFocusEvent *e)
- {
- if (isModified() && !hasAcceptableInput())
- setText(origText);
- QLineEdit::focusOutEvent(e);
- }
-
-private slots:
- void handleReturnPressed()
- {
- origText = text();
- }
-
-private:
- QString origText;
-};
-} // anonymous namespace
-
-class QPrintPreviewDialogPrivate : public QDialogPrivate
-{
- Q_DECLARE_PUBLIC(QPrintPreviewDialog)
-public:
- QPrintPreviewDialogPrivate()
- : printDialog(0), ownPrinter(false),
- initialized(false) {}
-
- // private slots
- void _q_fit(QAction *action);
- void _q_zoomIn();
- void _q_zoomOut();
- void _q_navigate(QAction *action);
- void _q_setMode(QAction *action);
- void _q_pageNumEdited();
- void _q_print();
- void _q_pageSetup();
- void _q_previewChanged();
- void _q_zoomFactorChanged();
-
- void init(QPrinter *printer = 0);
- void populateScene();
- void layoutPages();
- void setupActions();
- void updateNavActions();
- void setFitting(bool on);
- bool isFitting();
- void updatePageNumLabel();
- void updateZoomFactor();
-
- QPrintDialog *printDialog;
- QPrintPreviewWidget *preview;
- QPrinter *printer;
- bool ownPrinter;
- bool initialized;
-
- // widgets:
- QLineEdit *pageNumEdit;
- QLabel *pageNumLabel;
- QComboBox *zoomFactor;
-
- // actions:
- QActionGroup* navGroup;
- QAction *nextPageAction;
- QAction *prevPageAction;
- QAction *firstPageAction;
- QAction *lastPageAction;
-
- QActionGroup* fitGroup;
- QAction *fitWidthAction;
- QAction *fitPageAction;
-
- QActionGroup* zoomGroup;
- QAction *zoomInAction;
- QAction *zoomOutAction;
-
- QActionGroup* orientationGroup;
- QAction *portraitAction;
- QAction *landscapeAction;
-
- QActionGroup* modeGroup;
- QAction *singleModeAction;
- QAction *facingModeAction;
- QAction *overviewModeAction;
-
- QActionGroup *printerGroup;
- QAction *printAction;
- QAction *pageSetupAction;
-#if defined(Q_WS_MAC) && !defined(QT_MAC_USE_COCOA)
- QAction *closeAction;
-#endif
-
- QPointer<QObject> receiverToDisconnectOnClose;
- QByteArray memberToDisconnectOnClose;
-};
-
-void QPrintPreviewDialogPrivate::init(QPrinter *_printer)
-{
- Q_Q(QPrintPreviewDialog);
-
- if (_printer) {
- preview = new QPrintPreviewWidget(_printer, q);
- printer = _printer;
- } else {
- ownPrinter = true;
- printer = new QPrinter;
- preview = new QPrintPreviewWidget(printer, q);
- }
- QObject::connect(preview, SIGNAL(paintRequested(QPrinter*)), q, SIGNAL(paintRequested(QPrinter*)));
- QObject::connect(preview, SIGNAL(previewChanged()), q, SLOT(_q_previewChanged()));
- setupActions();
-
- pageNumEdit = new LineEdit;
- pageNumEdit->setAlignment(Qt::AlignRight);
- pageNumEdit->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
- pageNumLabel = new QLabel;
- QObject::connect(pageNumEdit, SIGNAL(editingFinished()), q, SLOT(_q_pageNumEdited()));
-
- zoomFactor = new QComboBox;
- zoomFactor->setEditable(true);
- zoomFactor->setMinimumContentsLength(7);
- zoomFactor->setInsertPolicy(QComboBox::NoInsert);
- LineEdit *zoomEditor = new LineEdit;
- zoomEditor->setValidator(new ZoomFactorValidator(1, 1000, 1, zoomEditor));
- zoomFactor->setLineEdit(zoomEditor);
- static const short factorsX2[] = { 25, 50, 100, 200, 250, 300, 400, 800, 1600 };
- for (int i = 0; i < int(sizeof(factorsX2) / sizeof(factorsX2[0])); ++i)
- zoomFactor->addItem(QPrintPreviewDialog::tr("%1%").arg(factorsX2[i] / 2.0));
- QObject::connect(zoomFactor->lineEdit(), SIGNAL(editingFinished()),
- q, SLOT(_q_zoomFactorChanged()));
- QObject::connect(zoomFactor, SIGNAL(currentIndexChanged(int)),
- q, SLOT(_q_zoomFactorChanged()));
-
- QPrintPreviewMainWindow *mw = new QPrintPreviewMainWindow(q);
- QToolBar *toolbar = new QToolBar(mw);
- toolbar->addAction(fitWidthAction);
- toolbar->addAction(fitPageAction);
- toolbar->addSeparator();
- toolbar->addWidget(zoomFactor);
- toolbar->addAction(zoomOutAction);
- toolbar->addAction(zoomInAction);
- toolbar->addSeparator();
- toolbar->addAction(portraitAction);
- toolbar->addAction(landscapeAction);
- toolbar->addSeparator();
- toolbar->addAction(firstPageAction);
- toolbar->addAction(prevPageAction);
-
- // this is to ensure the label text and the editor text are
- // aligned in all styles - the extra QVBoxLayout is a workaround
- // for bug in QFormLayout
- QWidget *pageEdit = new QWidget(toolbar);
- QVBoxLayout *vboxLayout = new QVBoxLayout;
- vboxLayout->setContentsMargins(0, 0, 0, 0);
-#ifdef Q_WS_MAC
- // We query the widgets about their size and then we fix the size.
- // This should do the trick for the laying out part...
- QSize pageNumEditSize, pageNumLabelSize;
- pageNumEditSize = pageNumEdit->minimumSizeHint();
- pageNumLabelSize = pageNumLabel->minimumSizeHint();
- pageNumEdit->resize(pageNumEditSize);
- pageNumLabel->resize(pageNumLabelSize);
-#endif
- QFormLayout *formLayout = new QFormLayout;
-#ifdef Q_WS_MAC
- // We have to change the growth policy in Mac.
- formLayout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow);
-#endif
- formLayout->setWidget(0, QFormLayout::LabelRole, pageNumEdit);
- formLayout->setWidget(0, QFormLayout::FieldRole, pageNumLabel);
- vboxLayout->addLayout(formLayout);
- vboxLayout->setAlignment(Qt::AlignVCenter);
- pageEdit->setLayout(vboxLayout);
- toolbar->addWidget(pageEdit);
-
- toolbar->addAction(nextPageAction);
- toolbar->addAction(lastPageAction);
- toolbar->addSeparator();
- toolbar->addAction(singleModeAction);
- toolbar->addAction(facingModeAction);
- toolbar->addAction(overviewModeAction);
- toolbar->addSeparator();
- toolbar->addAction(pageSetupAction);
- toolbar->addAction(printAction);
-#if defined(Q_WS_MAC) && !defined(QT_MAC_USE_COCOA)
- toolbar->addAction(closeAction);
-#endif
-
- // Cannot use the actions' triggered signal here, since it doesn't autorepeat
- QToolButton *zoomInButton = static_cast<QToolButton *>(toolbar->widgetForAction(zoomInAction));
- QToolButton *zoomOutButton = static_cast<QToolButton *>(toolbar->widgetForAction(zoomOutAction));
- zoomInButton->setAutoRepeat(true);
- zoomInButton->setAutoRepeatInterval(200);
- zoomInButton->setAutoRepeatDelay(200);
- zoomOutButton->setAutoRepeat(true);
- zoomOutButton->setAutoRepeatInterval(200);
- zoomOutButton->setAutoRepeatDelay(200);
- QObject::connect(zoomInButton, SIGNAL(clicked()), q, SLOT(_q_zoomIn()));
- QObject::connect(zoomOutButton, SIGNAL(clicked()), q, SLOT(_q_zoomOut()));
-
- mw->addToolBar(toolbar);
- mw->setCentralWidget(preview);
- // QMainWindows are always created as top levels, force it to be a
- // plain widget
- mw->setParent(q, Qt::Widget);
-
- QVBoxLayout *topLayout = new QVBoxLayout;
- topLayout->addWidget(mw);
- topLayout->setMargin(0);
- q->setLayout(topLayout);
-
- QString caption = QCoreApplication::translate("QPrintPreviewDialog", "Print Preview");
- if (!printer->docName().isEmpty())
- caption += QString::fromLatin1(": ") + printer->docName();
- q->setWindowTitle(caption);
-
- if (!printer->isValid()
-#if defined(Q_WS_WIN) || defined(Q_WS_MAC)
- || printer->outputFormat() != QPrinter::NativeFormat
-#endif
- )
- pageSetupAction->setEnabled(false);
- preview->setFocus();
-}
-
-static inline void qt_setupActionIcon(QAction *action, const QLatin1String &name)
-{
- QLatin1String imagePrefix(":/trolltech/dialogs/qprintpreviewdialog/images/");
- QIcon icon;
- icon.addFile(imagePrefix + name + QLatin1String("-24.png"), QSize(24, 24));
- icon.addFile(imagePrefix + name + QLatin1String("-32.png"), QSize(32, 32));
- action->setIcon(icon);
-}
-
-void QPrintPreviewDialogPrivate::setupActions()
-{
- Q_Q(QPrintPreviewDialog);
-
- // Navigation
- navGroup = new QActionGroup(q);
- navGroup->setExclusive(false);
- nextPageAction = navGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Next page"));
- prevPageAction = navGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Previous page"));
- firstPageAction = navGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "First page"));
- lastPageAction = navGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Last page"));
- qt_setupActionIcon(nextPageAction, QLatin1String("go-next"));
- qt_setupActionIcon(prevPageAction, QLatin1String("go-previous"));
- qt_setupActionIcon(firstPageAction, QLatin1String("go-first"));
- qt_setupActionIcon(lastPageAction, QLatin1String("go-last"));
- QObject::connect(navGroup, SIGNAL(triggered(QAction*)), q, SLOT(_q_navigate(QAction*)));
-
-
- fitGroup = new QActionGroup(q);
- fitWidthAction = fitGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Fit width"));
- fitPageAction = fitGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Fit page"));
- fitWidthAction->setObjectName(QLatin1String("fitWidthAction"));
- fitPageAction->setObjectName(QLatin1String("fitPageAction"));
- fitWidthAction->setCheckable(true);
- fitPageAction->setCheckable(true);
- qt_setupActionIcon(fitWidthAction, QLatin1String("fit-width"));
- qt_setupActionIcon(fitPageAction, QLatin1String("fit-page"));
- QObject::connect(fitGroup, SIGNAL(triggered(QAction*)), q, SLOT(_q_fit(QAction*)));
-
- // Zoom
- zoomGroup = new QActionGroup(q);
- zoomInAction = zoomGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Zoom in"));
- zoomOutAction = zoomGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Zoom out"));
- qt_setupActionIcon(zoomInAction, QLatin1String("zoom-in"));
- qt_setupActionIcon(zoomOutAction, QLatin1String("zoom-out"));
-
- // Portrait/Landscape
- orientationGroup = new QActionGroup(q);
- portraitAction = orientationGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Portrait"));
- landscapeAction = orientationGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Landscape"));
- portraitAction->setCheckable(true);
- landscapeAction->setCheckable(true);
- qt_setupActionIcon(portraitAction, QLatin1String("layout-portrait"));
- qt_setupActionIcon(landscapeAction, QLatin1String("layout-landscape"));
- QObject::connect(portraitAction, SIGNAL(triggered(bool)), preview, SLOT(setPortraitOrientation()));
- QObject::connect(landscapeAction, SIGNAL(triggered(bool)), preview, SLOT(setLandscapeOrientation()));
-
- // Display mode
- modeGroup = new QActionGroup(q);
- singleModeAction = modeGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Show single page"));
- facingModeAction = modeGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Show facing pages"));
- overviewModeAction = modeGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Show overview of all pages"));
- qt_setupActionIcon(singleModeAction, QLatin1String("view-page-one"));
- qt_setupActionIcon(facingModeAction, QLatin1String("view-page-sided"));
- qt_setupActionIcon(overviewModeAction, QLatin1String("view-page-multi"));
- singleModeAction->setObjectName(QLatin1String("singleModeAction"));
- facingModeAction->setObjectName(QLatin1String("facingModeAction"));
- overviewModeAction->setObjectName(QLatin1String("overviewModeAction"));
-
- singleModeAction->setCheckable(true);
- facingModeAction->setCheckable(true);
- overviewModeAction->setCheckable(true);
- QObject::connect(modeGroup, SIGNAL(triggered(QAction*)), q, SLOT(_q_setMode(QAction*)));
-
- // Print
- printerGroup = new QActionGroup(q);
- printAction = printerGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Print"));
- pageSetupAction = printerGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Page setup"));
- qt_setupActionIcon(printAction, QLatin1String("print"));
- qt_setupActionIcon(pageSetupAction, QLatin1String("page-setup"));
- QObject::connect(printAction, SIGNAL(triggered(bool)), q, SLOT(_q_print()));
- QObject::connect(pageSetupAction, SIGNAL(triggered(bool)), q, SLOT(_q_pageSetup()));
-#if defined(Q_WS_MAC) && !defined(QT_MAC_USE_COCOA)
- closeAction = printerGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Close"));
- QObject::connect(closeAction, SIGNAL(triggered(bool)), q, SLOT(reject()));
-#endif
-
- // Initial state:
- fitPageAction->setChecked(true);
- singleModeAction->setChecked(true);
- if (preview->orientation() == QPrinter::Portrait)
- portraitAction->setChecked(true);
- else
- landscapeAction->setChecked(true);
-}
-
-
-bool QPrintPreviewDialogPrivate::isFitting()
-{
- return (fitGroup->isExclusive()
- && (fitWidthAction->isChecked() || fitPageAction->isChecked()));
-}
-
-
-void QPrintPreviewDialogPrivate::setFitting(bool on)
-{
- if (isFitting() == on)
- return;
- fitGroup->setExclusive(on);
- if (on) {
- QAction* action = fitWidthAction->isChecked() ? fitWidthAction : fitPageAction;
- action->setChecked(true);
- if (fitGroup->checkedAction() != action) {
- // work around exclusitivity problem
- fitGroup->removeAction(action);
- fitGroup->addAction(action);
- }
- } else {
- fitWidthAction->setChecked(false);
- fitPageAction->setChecked(false);
- }
-}
-
-void QPrintPreviewDialogPrivate::updateNavActions()
-{
- int curPage = preview->currentPage();
- int numPages = preview->pageCount();
- nextPageAction->setEnabled(curPage < numPages);
- prevPageAction->setEnabled(curPage > 1);
- firstPageAction->setEnabled(curPage > 1);
- lastPageAction->setEnabled(curPage < numPages);
- pageNumEdit->setText(QString::number(curPage));
-}
-
-void QPrintPreviewDialogPrivate::updatePageNumLabel()
-{
- Q_Q(QPrintPreviewDialog);
-
- int numPages = preview->pageCount();
- int maxChars = QString::number(numPages).length();
- pageNumLabel->setText(QString::fromLatin1("/ %1").arg(numPages));
- int cyphersWidth = q->fontMetrics().width(QString().fill(QLatin1Char('8'), maxChars));
- int maxWidth = pageNumEdit->minimumSizeHint().width() + cyphersWidth;
- pageNumEdit->setMinimumWidth(maxWidth);
- pageNumEdit->setMaximumWidth(maxWidth);
- pageNumEdit->setValidator(new QIntValidator(1, numPages, pageNumEdit));
- // any old one will be deleted later along with its parent pageNumEdit
-}
-
-void QPrintPreviewDialogPrivate::updateZoomFactor()
-{
- zoomFactor->lineEdit()->setText(QString().sprintf("%.1f%%", preview->zoomFactor()*100));
-}
-
-void QPrintPreviewDialogPrivate::_q_fit(QAction* action)
-{
- setFitting(true);
- if (action == fitPageAction)
- preview->fitInView();
- else
- preview->fitToWidth();
-}
-
-void QPrintPreviewDialogPrivate::_q_zoomIn()
-{
- setFitting(false);
- preview->zoomIn();
- updateZoomFactor();
-}
-
-void QPrintPreviewDialogPrivate::_q_zoomOut()
-{
- setFitting(false);
- preview->zoomOut();
- updateZoomFactor();
-}
-
-void QPrintPreviewDialogPrivate::_q_pageNumEdited()
-{
- bool ok = false;
- int res = pageNumEdit->text().toInt(&ok);
- if (ok)
- preview->setCurrentPage(res);
-}
-
-void QPrintPreviewDialogPrivate::_q_navigate(QAction* action)
-{
- int curPage = preview->currentPage();
- if (action == prevPageAction)
- preview->setCurrentPage(curPage - 1);
- else if (action == nextPageAction)
- preview->setCurrentPage(curPage + 1);
- else if (action == firstPageAction)
- preview->setCurrentPage(1);
- else if (action == lastPageAction)
- preview->setCurrentPage(preview->pageCount());
- updateNavActions();
-}
-
-void QPrintPreviewDialogPrivate::_q_setMode(QAction* action)
-{
- if (action == overviewModeAction) {
- preview->setViewMode(QPrintPreviewWidget::AllPagesView);
- setFitting(false);
- fitGroup->setEnabled(false);
- navGroup->setEnabled(false);
- pageNumEdit->setEnabled(false);
- pageNumLabel->setEnabled(false);
- } else if (action == facingModeAction) {
- preview->setViewMode(QPrintPreviewWidget::FacingPagesView);
- } else {
- preview->setViewMode(QPrintPreviewWidget::SinglePageView);
- }
- if (action == facingModeAction || action == singleModeAction) {
- fitGroup->setEnabled(true);
- navGroup->setEnabled(true);
- pageNumEdit->setEnabled(true);
- pageNumLabel->setEnabled(true);
- setFitting(true);
- }
-}
-
-void QPrintPreviewDialogPrivate::_q_print()
-{
- Q_Q(QPrintPreviewDialog);
-
-#if defined(Q_WS_WIN) || defined(Q_WS_MAC)
- if (printer->outputFormat() != QPrinter::NativeFormat) {
- QString title;
- QString suffix;
- if (printer->outputFormat() == QPrinter::PdfFormat) {
- title = QCoreApplication::translate("QPrintPreviewDialog", "Export to PDF");
- suffix = QLatin1String(".pdf");
- } else {
- title = QCoreApplication::translate("QPrintPreviewDialog", "Export to PostScript");
- suffix = QLatin1String(".ps");
- }
- QString fileName = QFileDialog::getSaveFileName(q, title, printer->outputFileName(),
- QLatin1Char('*') + suffix);
- if (!fileName.isEmpty()) {
- if (QFileInfo(fileName).suffix().isEmpty())
- fileName.append(suffix);
- printer->setOutputFileName(fileName);
- }
- if (!printer->outputFileName().isEmpty())
- preview->print();
- q->accept();
- return;
- }
-#endif
-
- if (!printDialog)
- printDialog = new QPrintDialog(printer, q);
- if (printDialog->exec() == QDialog::Accepted) {
- preview->print();
- q->accept();
- }
-}
-
-void QPrintPreviewDialogPrivate::_q_pageSetup()
-{
- Q_Q(QPrintPreviewDialog);
-
- QPageSetupDialog pageSetup(printer, q);
- if (pageSetup.exec() == QDialog::Accepted) {
- // update possible orientation changes
- if (preview->orientation() == QPrinter::Portrait) {
- portraitAction->setChecked(true);
- preview->setPortraitOrientation();
- }else {
- landscapeAction->setChecked(true);
- preview->setLandscapeOrientation();
- }
- }
-}
-
-void QPrintPreviewDialogPrivate::_q_previewChanged()
-{
- updateNavActions();
- updatePageNumLabel();
- updateZoomFactor();
-}
-
-void QPrintPreviewDialogPrivate::_q_zoomFactorChanged()
-{
- QString text = zoomFactor->lineEdit()->text();
- bool ok;
- qreal factor = text.remove(QLatin1Char('%')).toFloat(&ok);
- factor = qMax(qreal(1.0), qMin(qreal(1000.0), factor));
- if (ok) {
- preview->setZoomFactor(factor/100.0);
- zoomFactor->setEditText(QString::fromLatin1("%1%").arg(factor));
- setFitting(false);
- }
-}
-
-///////////////////////////////////////////////////////////////////////////
-
-/*!
- \class QPrintPreviewDialog
- \since 4.4
-
- \brief The QPrintPreviewDialog class provides a dialog for
- previewing and configuring page layouts for printer output.
-
- \ingroup standard-dialogs
- \ingroup printing
-
- Using QPrintPreviewDialog in your existing application is
- straightforward:
-
- \list 1
- \o Create the QPrintPreviewDialog.
-
- You can construct a QPrintPreviewDialog with an existing QPrinter
- object, or you can have QPrintPreviewDialog create one for you,
- which will be the system default printer.
-
- \o Connect the paintRequested() signal to a slot.
-
- When the dialog needs to generate a set of preview pages, the
- paintRequested() signal will be emitted. You can use the exact
- same code for the actual printing as for having the preview
- generated, including calling QPrinter::newPage() to start a new
- page in the preview. Connect a slot to the paintRequested()
- signal, where you draw onto the QPrinter object that is passed
- into the slot.
-
- \o Call exec().
-
- Call QPrintPreviewDialog::exec() to show the preview dialog.
- \endlist
-
- In Symbian, there is no support for printing. Hence, this dialog should not
- be used in Symbian.
-
- \sa QPrinter, QPrintDialog, QPageSetupDialog, QPrintPreviewWidget
-*/
-
-/*!
- Constructs a QPrintPreviewDialog based on \a printer and with \a
- parent as the parent widget. The widget flags \a flags are passed on
- to the QWidget constructor.
-
- \sa QWidget::setWindowFlags()
-*/
-QPrintPreviewDialog::QPrintPreviewDialog(QPrinter* printer, QWidget *parent, Qt::WindowFlags flags)
- : QDialog(*new QPrintPreviewDialogPrivate, parent, flags)
-{
- Q_D(QPrintPreviewDialog);
- d->init(printer);
-}
-
-/*!
- \overload
- \fn QPrintPreviewDialog::QPrintPreviewDialog(QWidget *parent, Qt::WindowFlags flags)
-
- This will create an internal QPrinter object, which will use the
- system default printer.
-*/
-QPrintPreviewDialog::QPrintPreviewDialog(QWidget *parent, Qt::WindowFlags f)
- : QDialog(*new QPrintPreviewDialogPrivate, parent, f)
-{
- Q_D(QPrintPreviewDialog);
- d->init();
-}
-
-/*!
- Destroys the QPrintPreviewDialog.
-*/
-QPrintPreviewDialog::~QPrintPreviewDialog()
-{
- Q_D(QPrintPreviewDialog);
- if (d->ownPrinter)
- delete d->printer;
- delete d->printDialog;
-}
-
-/*!
- \reimp
-*/
-void QPrintPreviewDialog::setVisible(bool visible)
-{
- Q_D(QPrintPreviewDialog);
- // this will make the dialog get a decent default size
- if (visible && !d->initialized) {
- d->preview->updatePreview();
- d->initialized = true;
- }
- QDialog::setVisible(visible);
-}
-
-/*!
- \reimp
-*/
-void QPrintPreviewDialog::done(int result)
-{
- Q_D(QPrintPreviewDialog);
- QDialog::done(result);
- if (d->receiverToDisconnectOnClose) {
- disconnect(this, SIGNAL(finished(int)),
- d->receiverToDisconnectOnClose, d->memberToDisconnectOnClose);
- d->receiverToDisconnectOnClose = 0;
- }
- d->memberToDisconnectOnClose.clear();
-}
-
-/*!
- \overload
- \since 4.5
-
- Opens the dialog and connects its finished(int) signal to the slot specified
- by \a receiver and \a member.
-
- The signal will be disconnected from the slot when the dialog is closed.
-*/
-void QPrintPreviewDialog::open(QObject *receiver, const char *member)
-{
- Q_D(QPrintPreviewDialog);
- // the int parameter isn't very useful here; we could just as well connect
- // to reject(), but this feels less robust somehow
- connect(this, SIGNAL(finished(int)), receiver, member);
- d->receiverToDisconnectOnClose = receiver;
- d->memberToDisconnectOnClose = member;
- QDialog::open();
-}
-
-/*!
- Returns a pointer to the QPrinter object this dialog is currently
- operating on.
-*/
-QPrinter *QPrintPreviewDialog::printer()
-{
- Q_D(QPrintPreviewDialog);
- return d->printer;
-}
-
-/*!
- \fn void QPrintPreviewDialog::paintRequested(QPrinter *printer)
-
- This signal is emitted when the QPrintPreviewDialog needs to generate
- a set of preview pages.
-
- The \a printer instance supplied is the paint device onto which you should
- paint the contents of each page, using the QPrinter instance in the same way
- as you would when printing directly.
-*/
-
-
-QT_END_NAMESPACE
-
-#include "moc_qprintpreviewdialog.cpp"
-#include "qprintpreviewdialog.moc"
-
-#endif // QT_NO_PRINTPREVIEWDIALOG
-
-
diff --git a/src/gui/dialogs/qprintpreviewdialog.h b/src/gui/dialogs/qprintpreviewdialog.h
deleted file mode 100644
index 144bee2089..0000000000
--- a/src/gui/dialogs/qprintpreviewdialog.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPRINTPREVIEWDIALOG_H
-#define QPRINTPREVIEWDIALOG_H
-
-#include <QtGui/qdialog.h>
-
-#ifndef QT_NO_PRINTPREVIEWDIALOG
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QGraphicsView;
-class QPrintPreviewDialogPrivate;
-
-class Q_GUI_EXPORT QPrintPreviewDialog : public QDialog
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QPrintPreviewDialog)
-
-public:
- explicit QPrintPreviewDialog(QWidget *parent = 0, Qt::WindowFlags flags = 0);
- explicit QPrintPreviewDialog(QPrinter *printer, QWidget *parent = 0, Qt::WindowFlags flags = 0);
- ~QPrintPreviewDialog();
-
-#ifdef Q_NO_USING_KEYWORD
-#ifndef Q_QDOC
- void open() { QDialog::open(); }
-#endif
-#else
- using QDialog::open;
-#endif
- void open(QObject *receiver, const char *member);
-
- QPrinter *printer();
-
- void setVisible(bool visible);
- void done(int result);
-
-Q_SIGNALS:
- void paintRequested(QPrinter *printer);
-
-private:
- Q_PRIVATE_SLOT(d_func(), void _q_fit(QAction *action))
- Q_PRIVATE_SLOT(d_func(), void _q_zoomIn())
- Q_PRIVATE_SLOT(d_func(), void _q_zoomOut())
- Q_PRIVATE_SLOT(d_func(), void _q_navigate(QAction *action))
- Q_PRIVATE_SLOT(d_func(), void _q_setMode(QAction *action))
- Q_PRIVATE_SLOT(d_func(), void _q_pageNumEdited())
- Q_PRIVATE_SLOT(d_func(), void _q_print())
- Q_PRIVATE_SLOT(d_func(), void _q_pageSetup())
- Q_PRIVATE_SLOT(d_func(), void _q_previewChanged())
- Q_PRIVATE_SLOT(d_func(), void _q_zoomFactorChanged())
-
- void *dummy; // ### Qt 5 - remove me
-};
-
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QT_NO_PRINTPREVIEWDIALOG
-
-#endif // QPRINTPREVIEWDIALOG_H
diff --git a/src/gui/dialogs/qprogressdialog.cpp b/src/gui/dialogs/qprogressdialog.cpp
deleted file mode 100644
index 87df49cc51..0000000000
--- a/src/gui/dialogs/qprogressdialog.cpp
+++ /dev/null
@@ -1,907 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qprogressdialog.h"
-
-#ifndef QT_NO_PROGRESSDIALOG
-
-#include "qshortcut.h"
-#include "qpainter.h"
-#include "qdrawutil.h"
-#include "qlabel.h"
-#include "qprogressbar.h"
-#include "qapplication.h"
-#include "qstyle.h"
-#include "qpushbutton.h"
-#include "qcursor.h"
-#include "qtimer.h"
-#include "qelapsedtimer.h"
-#include <private/qdialog_p.h>
-#include <limits.h>
-
-#if defined(QT_SOFTKEYS_ENABLED)
-#include <qaction.h>
-#endif
-#ifdef Q_WS_S60
-#include <QtGui/qdesktopwidget.h>
-#endif
-
-
-QT_BEGIN_NAMESPACE
-
-// If the operation is expected to take this long (as predicted by
-// progress time), show the progress dialog.
-static const int defaultShowTime = 4000;
-// Wait at least this long before attempting to make a prediction.
-static const int minWaitTime = 50;
-
-class QProgressDialogPrivate : public QDialogPrivate
-{
- Q_DECLARE_PUBLIC(QProgressDialog)
-
-public:
- QProgressDialogPrivate() : label(0), cancel(0), bar(0),
- shown_once(false),
- cancellation_flag(false),
- showTime(defaultShowTime),
-#ifndef QT_NO_SHORTCUT
- escapeShortcut(0),
-#endif
-#ifdef QT_SOFTKEYS_ENABLED
- cancelAction(0),
-#endif
- useDefaultCancelText(false)
- {
- }
-
- void init(const QString &labelText, const QString &cancelText, int min, int max);
- void layout();
- void retranslateStrings();
- void _q_disconnectOnClose();
-
- QLabel *label;
- QPushButton *cancel;
- QProgressBar *bar;
- QTimer *forceTimer;
- bool shown_once;
- bool cancellation_flag;
- QElapsedTimer starttime;
-#ifndef QT_NO_CURSOR
- QCursor parentCursor;
-#endif
- int showTime;
- bool autoClose;
- bool autoReset;
- bool forceHide;
-#ifndef QT_NO_SHORTCUT
- QShortcut *escapeShortcut;
-#endif
-#ifdef QT_SOFTKEYS_ENABLED
- QAction *cancelAction;
-#endif
- bool useDefaultCancelText;
- QPointer<QObject> receiverToDisconnectOnClose;
- QByteArray memberToDisconnectOnClose;
-};
-
-void QProgressDialogPrivate::init(const QString &labelText, const QString &cancelText,
- int min, int max)
-{
- Q_Q(QProgressDialog);
- label = new QLabel(labelText, q);
- int align = q->style()->styleHint(QStyle::SH_ProgressDialog_TextLabelAlignment, 0, q);
- label->setAlignment(Qt::Alignment(align));
- bar = new QProgressBar(q);
- bar->setRange(min, max);
- autoClose = true;
- autoReset = true;
- forceHide = false;
- QObject::connect(q, SIGNAL(canceled()), q, SLOT(cancel()));
- forceTimer = new QTimer(q);
- QObject::connect(forceTimer, SIGNAL(timeout()), q, SLOT(forceShow()));
- if (useDefaultCancelText) {
- retranslateStrings();
- } else {
- q->setCancelButtonText(cancelText);
- }
-}
-
-void QProgressDialogPrivate::layout()
-{
- Q_Q(QProgressDialog);
- int sp = q->style()->pixelMetric(QStyle::PM_DefaultLayoutSpacing);
- int mtb = q->style()->pixelMetric(QStyle::PM_DefaultTopLevelMargin);
- int mlr = qMin(q->width() / 10, mtb);
- const bool centered =
- bool(q->style()->styleHint(QStyle::SH_ProgressDialog_CenterCancelButton, 0, q));
-
- int additionalSpacing = 0;
-#ifdef Q_OS_SYMBIAN
- //In Symbian, we need to have wider margins for dialog borders, as the actual border is some pixels
- //inside the dialog area (to enable transparent borders)
- additionalSpacing = mlr;
-#endif
-
- QSize cs = cancel ? cancel->sizeHint() : QSize(0,0);
- QSize bh = bar->sizeHint();
- int cspc;
- int lh = 0;
-
- // Find spacing and sizes that fit. It is important that a progress
- // dialog can be made very small if the user demands it so.
- for (int attempt=5; attempt--;) {
- cspc = cancel ? cs.height() + sp : 0;
- lh = qMax(0, q->height() - mtb - bh.height() - sp - cspc);
-
- if (lh < q->height()/4) {
- // Getting cramped
- sp /= 2;
- mtb /= 2;
- if (cancel) {
- cs.setHeight(qMax(4,cs.height()-sp-2));
- }
- bh.setHeight(qMax(4,bh.height()-sp-1));
- } else {
- break;
- }
- }
-
- if (cancel) {
- cancel->setGeometry(
- centered ? q->width()/2 - cs.width()/2 : q->width() - mlr - cs.width(),
- q->height() - mtb - cs.height(),
- cs.width(), cs.height());
- }
-
- if (label)
- label->setGeometry(mlr, additionalSpacing, q->width() - mlr * 2, lh);
- bar->setGeometry(mlr, lh + sp + additionalSpacing, q->width() - mlr * 2, bh.height());
-}
-
-void QProgressDialogPrivate::retranslateStrings()
-{
- Q_Q(QProgressDialog);
- if (useDefaultCancelText)
- q->setCancelButtonText(QProgressDialog::tr("Cancel"));
-}
-
-void QProgressDialogPrivate::_q_disconnectOnClose()
-{
- Q_Q(QProgressDialog);
- if (receiverToDisconnectOnClose) {
- QObject::disconnect(q, SIGNAL(canceled()), receiverToDisconnectOnClose,
- memberToDisconnectOnClose);
- receiverToDisconnectOnClose = 0;
- }
- memberToDisconnectOnClose.clear();
-}
-
-/*!
- \class QProgressDialog
- \brief The QProgressDialog class provides feedback on the progress of a slow operation.
- \ingroup standard-dialogs
-
-
- A progress dialog is used to give the user an indication of how long
- an operation is going to take, and to demonstrate that the
- application has not frozen. It can also give the user an opportunity
- to abort the operation.
-
- A common problem with progress dialogs is that it is difficult to know
- when to use them; operations take different amounts of time on different
- hardware. QProgressDialog offers a solution to this problem:
- it estimates the time the operation will take (based on time for
- steps), and only shows itself if that estimate is beyond minimumDuration()
- (4 seconds by default).
-
- Use setMinimum() and setMaximum() or the constructor to set the number of
- "steps" in the operation and call setValue() as the operation
- progresses. The number of steps can be chosen arbitrarily. It can be the
- number of files copied, the number of bytes received, the number of
- iterations through the main loop of your algorithm, or some other
- suitable unit. Progress starts at the value set by setMinimum(),
- and the progress dialog shows that the operation has finished when
- you call setValue() with the value set by setMaximum() as its argument.
-
- The dialog automatically resets and hides itself at the end of the
- operation. Use setAutoReset() and setAutoClose() to change this
- behavior. Note that if you set a new maximum (using setMaximum() or
- setRange()) that equals your current value(), the dialog will not
- close regardless.
-
- There are two ways of using QProgressDialog: modal and modeless.
-
- Compared to a modeless QProgressDialog, a modal QProgressDialog is simpler
- to use for the programmer. Do the operation in a loop, call \l setValue() at
- intervals, and check for cancellation with wasCanceled(). For example:
-
- \snippet doc/src/snippets/dialogs/dialogs.cpp 3
-
- A modeless progress dialog is suitable for operations that take
- place in the background, where the user is able to interact with the
- application. Such operations are typically based on QTimer (or
- QObject::timerEvent()), QSocketNotifier, or QUrlOperator; or performed
- in a separate thread. A QProgressBar in the status bar of your main window
- is often an alternative to a modeless progress dialog.
-
- You need to have an event loop to be running, connect the
- canceled() signal to a slot that stops the operation, and call \l
- setValue() at intervals. For example:
-
- \snippet doc/src/snippets/dialogs/dialogs.cpp 4
- \codeline
- \snippet doc/src/snippets/dialogs/dialogs.cpp 5
- \codeline
- \snippet doc/src/snippets/dialogs/dialogs.cpp 6
-
- In both modes the progress dialog may be customized by
- replacing the child widgets with custom widgets by using setLabel(),
- setBar(), and setCancelButton().
- The functions setLabelText() and setCancelButtonText()
- set the texts shown.
-
- \image plastique-progressdialog.png A progress dialog shown in the Plastique widget style.
-
- \sa QDialog, QProgressBar, {fowler}{GUI Design Handbook: Progress Indicator},
- {Find Files Example}, {Pixelator Example}
-*/
-
-
-/*!
- Constructs a progress dialog.
-
- Default settings:
- \list
- \i The label text is empty.
- \i The cancel button text is (translated) "Cancel".
- \i minimum is 0;
- \i maximum is 100
- \endlist
-
- The \a parent argument is dialog's parent widget. The widget flags, \a f, are
- passed to the QDialog::QDialog() constructor.
-
- \sa setLabelText(), setCancelButtonText(), setCancelButton(),
- setMinimum(), setMaximum()
-*/
-
-QProgressDialog::QProgressDialog(QWidget *parent, Qt::WindowFlags f)
- : QDialog(*(new QProgressDialogPrivate), parent, f)
-{
- Q_D(QProgressDialog);
- d->useDefaultCancelText = true;
- d->init(QString::fromLatin1(""), QString(), 0, 100);
-}
-
-/*!
- Constructs a progress dialog.
-
- The \a labelText is the text used to remind the user what is progressing.
-
- The \a cancelButtonText is the text to display on the cancel button. If
- QString() is passed then no cancel button is shown.
-
- The \a minimum and \a maximum is the number of steps in the operation for
- which this progress dialog shows progress. For example, if the
- operation is to examine 50 files, this value minimum value would be 0,
- and the maximum would be 50. Before examining the first file, call
- setValue(0). As each file is processed call setValue(1), setValue(2),
- etc., finally calling setValue(50) after examining the last file.
-
- The \a parent argument is the dialog's parent widget. The parent, \a parent, and
- widget flags, \a f, are passed to the QDialog::QDialog() constructor.
-
- \sa setLabelText(), setLabel(), setCancelButtonText(), setCancelButton(),
- setMinimum(), setMaximum()
-*/
-
-QProgressDialog::QProgressDialog(const QString &labelText,
- const QString &cancelButtonText,
- int minimum, int maximum,
- QWidget *parent, Qt::WindowFlags f)
- : QDialog(*(new QProgressDialogPrivate), parent, f)
-{
- Q_D(QProgressDialog);
- d->init(labelText, cancelButtonText, minimum, maximum);
-}
-
-
-/*!
- Destroys the progress dialog.
-*/
-
-QProgressDialog::~QProgressDialog()
-{
-}
-
-/*!
- \fn void QProgressDialog::canceled()
-
- This signal is emitted when the cancel button is clicked.
- It is connected to the cancel() slot by default.
-
- \sa wasCanceled()
-*/
-
-
-/*!
- Sets the label to \a label. The progress dialog resizes to fit. The
- label becomes owned by the progress dialog and will be deleted when
- necessary, so do not pass the address of an object on the stack.
-
- \sa setLabelText()
-*/
-
-void QProgressDialog::setLabel(QLabel *label)
-{
- Q_D(QProgressDialog);
- delete d->label;
- d->label = label;
- if (label) {
- if (label->parentWidget() == this) {
- label->hide(); // until we resize
- } else {
- label->setParent(this, 0);
- }
- }
- int w = qMax(isVisible() ? width() : 0, sizeHint().width());
- int h = qMax(isVisible() ? height() : 0, sizeHint().height());
- resize(w, h);
- if (label)
- label->show();
-}
-
-
-/*!
- \property QProgressDialog::labelText
- \brief the label's text
-
- The default text is an empty string.
-*/
-
-QString QProgressDialog::labelText() const
-{
- Q_D(const QProgressDialog);
- if (d->label)
- return d->label->text();
- return QString();
-}
-
-void QProgressDialog::setLabelText(const QString &text)
-{
- Q_D(QProgressDialog);
- if (d->label) {
- d->label->setText(text);
- int w = qMax(isVisible() ? width() : 0, sizeHint().width());
- int h = qMax(isVisible() ? height() : 0, sizeHint().height());
- resize(w, h);
- }
-}
-
-
-/*!
- Sets the cancel button to the push button, \a cancelButton. The
- progress dialog takes ownership of this button which will be deleted
- when necessary, so do not pass the address of an object that is on
- the stack, i.e. use new() to create the button. If 0 is passed then
- no cancel button will be shown.
-
- \sa setCancelButtonText()
-*/
-
-void QProgressDialog::setCancelButton(QPushButton *cancelButton)
-{
- Q_D(QProgressDialog);
- delete d->cancel;
- d->cancel = cancelButton;
- if (cancelButton) {
- if (cancelButton->parentWidget() == this) {
- cancelButton->hide(); // until we resize
- } else {
- cancelButton->setParent(this, 0);
- }
- connect(d->cancel, SIGNAL(clicked()), this, SIGNAL(canceled()));
-#ifndef QT_NO_SHORTCUT
- d->escapeShortcut = new QShortcut(Qt::Key_Escape, this, SIGNAL(canceled()));
-#endif
- } else {
-#ifndef QT_NO_SHORTCUT
- delete d->escapeShortcut;
- d->escapeShortcut = 0;
-#endif
- }
- int w = qMax(isVisible() ? width() : 0, sizeHint().width());
- int h = qMax(isVisible() ? height() : 0, sizeHint().height());
- resize(w, h);
- if (cancelButton)
-#if !defined(QT_SOFTKEYS_ENABLED)
- cancelButton->show();
-#else
- {
- d->cancelAction = new QAction(cancelButton->text(), cancelButton);
- d->cancelAction->setSoftKeyRole(QAction::NegativeSoftKey);
- connect(d->cancelAction, SIGNAL(triggered()), this, SIGNAL(canceled()));
- addAction(d->cancelAction);
- }
-#endif
-}
-
-/*!
- Sets the cancel button's text to \a cancelButtonText. If the text
- is set to QString() then it will cause the cancel button to be
- hidden and deleted.
-
- \sa setCancelButton()
-*/
-
-void QProgressDialog::setCancelButtonText(const QString &cancelButtonText)
-{
- Q_D(QProgressDialog);
- d->useDefaultCancelText = false;
-
- if (!cancelButtonText.isNull()) {
- if (d->cancel) {
- d->cancel->setText(cancelButtonText);
-#ifdef QT_SOFTKEYS_ENABLED
- d->cancelAction->setText(cancelButtonText);
-#endif
- } else {
- setCancelButton(new QPushButton(cancelButtonText, this));
- }
- } else {
- setCancelButton(0);
- }
- int w = qMax(isVisible() ? width() : 0, sizeHint().width());
- int h = qMax(isVisible() ? height() : 0, sizeHint().height());
- resize(w, h);
-}
-
-
-/*!
- Sets the progress bar widget to \a bar. The progress dialog resizes to
- fit. The progress dialog takes ownership of the progress \a bar which
- will be deleted when necessary, so do not use a progress bar
- allocated on the stack.
-*/
-
-void QProgressDialog::setBar(QProgressBar *bar)
-{
- Q_D(QProgressDialog);
- if (!bar) {
- qWarning("QProgressDialog::setBar: Cannot set a null progress bar");
- return;
- }
-#ifndef QT_NO_DEBUG
- if (value() > 0)
- qWarning("QProgressDialog::setBar: Cannot set a new progress bar "
- "while the old one is active");
-#endif
- delete d->bar;
- d->bar = bar;
- int w = qMax(isVisible() ? width() : 0, sizeHint().width());
- int h = qMax(isVisible() ? height() : 0, sizeHint().height());
- resize(w, h);
-}
-
-
-/*!
- \property QProgressDialog::wasCanceled
- \brief whether the dialog was canceled
-*/
-
-bool QProgressDialog::wasCanceled() const
-{
- Q_D(const QProgressDialog);
- return d->cancellation_flag;
-}
-
-
-/*!
- \property QProgressDialog::maximum
- \brief the highest value represented by the progress bar
-
- The default is 0.
-
- \sa minimum, setRange()
-*/
-
-int QProgressDialog::maximum() const
-{
- Q_D(const QProgressDialog);
- return d->bar->maximum();
-}
-
-void QProgressDialog::setMaximum(int maximum)
-{
- Q_D(QProgressDialog);
- d->bar->setMaximum(maximum);
-}
-
-/*!
- \property QProgressDialog::minimum
- \brief the lowest value represented by the progress bar
-
- The default is 0.
-
- \sa maximum, setRange()
-*/
-
-int QProgressDialog::minimum() const
-{
- Q_D(const QProgressDialog);
- return d->bar->minimum();
-}
-
-void QProgressDialog::setMinimum(int minimum)
-{
- Q_D(QProgressDialog);
- d->bar->setMinimum(minimum);
-}
-
-/*!
- Sets the progress dialog's minimum and maximum values
- to \a minimum and \a maximum, respectively.
-
- If \a maximum is smaller than \a minimum, \a minimum becomes the only
- legal value.
-
- If the current value falls outside the new range, the progress
- dialog is reset with reset().
-
- \sa minimum, maximum
-*/
-void QProgressDialog::setRange(int minimum, int maximum)
-{
- Q_D(QProgressDialog);
- d->bar->setRange(minimum, maximum);
-}
-
-
-/*!
- Resets the progress dialog.
- The progress dialog becomes hidden if autoClose() is true.
-
- \sa setAutoClose(), setAutoReset()
-*/
-
-void QProgressDialog::reset()
-{
- Q_D(QProgressDialog);
-#ifndef QT_NO_CURSOR
- if (value() >= 0) {
- if (parentWidget())
- parentWidget()->setCursor(d->parentCursor);
- }
-#endif
- if (d->autoClose || d->forceHide)
- hide();
- d->bar->reset();
- d->cancellation_flag = false;
- d->shown_once = false;
- d->forceTimer->stop();
-
- /*
- I wish we could disconnect the user slot provided to open() here but
- unfortunately reset() is usually called before the slot has been invoked.
- (reset() is itself invoked when canceled() is emitted.)
- */
- if (d->receiverToDisconnectOnClose)
- QMetaObject::invokeMethod(this, "_q_disconnectOnClose", Qt::QueuedConnection);
-}
-
-/*!
- Resets the progress dialog. wasCanceled() becomes true until
- the progress dialog is reset.
- The progress dialog becomes hidden.
-*/
-
-void QProgressDialog::cancel()
-{
- Q_D(QProgressDialog);
- d->forceHide = true;
- reset();
- d->forceHide = false;
- d->cancellation_flag = true;
-}
-
-
-int QProgressDialog::value() const
-{
- Q_D(const QProgressDialog);
- return d->bar->value();
-}
-
-/*!
- \property QProgressDialog::value
- \brief the current amount of progress made.
-
- For the progress dialog to work as expected, you should initially set
- this property to 0 and finally set it to
- QProgressDialog::maximum(); you can call setValue() any number of times
- in-between.
-
- \warning If the progress dialog is modal
- (see QProgressDialog::QProgressDialog()),
- setValue() calls QApplication::processEvents(), so take care that
- this does not cause undesirable re-entrancy in your code. For example,
- don't use a QProgressDialog inside a paintEvent()!
-
- \sa minimum, maximum
-*/
-void QProgressDialog::setValue(int progress)
-{
- Q_D(QProgressDialog);
- if (progress == d->bar->value()
- || (d->bar->value() == -1 && progress == d->bar->maximum()))
- return;
-
- d->bar->setValue(progress);
-
- if (d->shown_once) {
- if (isModal())
- QApplication::processEvents();
- } else {
- if (progress == 0) {
- d->starttime.start();
- d->forceTimer->start(d->showTime);
- return;
- } else {
- bool need_show;
- int elapsed = d->starttime.elapsed();
- if (elapsed >= d->showTime) {
- need_show = true;
- } else {
- if (elapsed > minWaitTime) {
- int estimate;
- int totalSteps = maximum() - minimum();
- int myprogress = progress - minimum();
- if ((totalSteps - myprogress) >= INT_MAX / elapsed)
- estimate = (totalSteps - myprogress) / myprogress * elapsed;
- else
- estimate = elapsed * (totalSteps - myprogress) / myprogress;
- need_show = estimate >= d->showTime;
- } else {
- need_show = false;
- }
- }
- if (need_show) {
- int w = qMax(isVisible() ? width() : 0, sizeHint().width());
- int h = qMax(isVisible() ? height() : 0, sizeHint().height());
- resize(w, h);
- show();
- d->shown_once = true;
- }
- }
-#ifdef Q_WS_MAC
- QApplication::flush();
-#endif
- }
-
- if (progress == d->bar->maximum() && d->autoReset)
- reset();
-}
-
-/*!
- Returns a size that fits the contents of the progress dialog.
- The progress dialog resizes itself as required, so you should not
- need to call this yourself.
-*/
-
-QSize QProgressDialog::sizeHint() const
-{
- Q_D(const QProgressDialog);
- QSize sh = d->label ? d->label->sizeHint() : QSize(0, 0);
- QSize bh = d->bar->sizeHint();
- int margin = style()->pixelMetric(QStyle::PM_DefaultTopLevelMargin);
- int spacing = style()->pixelMetric(QStyle::PM_DefaultLayoutSpacing);
- int h = margin * 2 + bh.height() + sh.height() + spacing;
- if (d->cancel)
- h += d->cancel->sizeHint().height() + spacing;
-#ifdef Q_WS_S60
- if (QApplication::desktop()->size().height() > QApplication::desktop()->size().width())
- return QSize(qMax(QApplication::desktop()->size().width(), sh.width() + 2 * margin), h);
- else
- return QSize(qMax(QApplication::desktop()->size().height(), sh.width() + 2 * margin), h);
-#else
- return QSize(qMax(200, sh.width() + 2 * margin), h);
-#endif
-}
-
-/*!\reimp
-*/
-void QProgressDialog::resizeEvent(QResizeEvent *)
-{
- Q_D(QProgressDialog);
- d->layout();
-}
-
-/*!
- \reimp
-*/
-void QProgressDialog::changeEvent(QEvent *ev)
-{
- Q_D(QProgressDialog);
- if (ev->type() == QEvent::StyleChange) {
- d->layout();
- } else if (ev->type() == QEvent::LanguageChange) {
- d->retranslateStrings();
- }
- QDialog::changeEvent(ev);
-}
-
-/*!
- \property QProgressDialog::minimumDuration
- \brief the time that must pass before the dialog appears
-
- If the expected duration of the task is less than the
- minimumDuration, the dialog will not appear at all. This prevents
- the dialog popping up for tasks that are quickly over. For tasks
- that are expected to exceed the minimumDuration, the dialog will
- pop up after the minimumDuration time or as soon as any progress
- is set.
-
- If set to 0, the dialog is always shown as soon as any progress is
- set. The default is 4000 milliseconds.
-*/
-void QProgressDialog::setMinimumDuration(int ms)
-{
- Q_D(QProgressDialog);
- d->showTime = ms;
- if (d->bar->value() == 0) {
- d->forceTimer->stop();
- d->forceTimer->start(ms);
- }
-}
-
-int QProgressDialog::minimumDuration() const
-{
- Q_D(const QProgressDialog);
- return d->showTime;
-}
-
-
-/*!
- \reimp
-*/
-
-void QProgressDialog::closeEvent(QCloseEvent *e)
-{
- emit canceled();
- QDialog::closeEvent(e);
-}
-
-/*!
- \property QProgressDialog::autoReset
- \brief whether the progress dialog calls reset() as soon as value() equals maximum()
-
- The default is true.
-
- \sa setAutoClose()
-*/
-
-void QProgressDialog::setAutoReset(bool b)
-{
- Q_D(QProgressDialog);
- d->autoReset = b;
-}
-
-bool QProgressDialog::autoReset() const
-{
- Q_D(const QProgressDialog);
- return d->autoReset;
-}
-
-/*!
- \property QProgressDialog::autoClose
- \brief whether the dialog gets hidden by reset()
-
- The default is true.
-
- \sa setAutoReset()
-*/
-
-void QProgressDialog::setAutoClose(bool close)
-{
- Q_D(QProgressDialog);
- d->autoClose = close;
-}
-
-bool QProgressDialog::autoClose() const
-{
- Q_D(const QProgressDialog);
- return d->autoClose;
-}
-
-/*!
- \reimp
-*/
-
-void QProgressDialog::showEvent(QShowEvent *e)
-{
- Q_D(QProgressDialog);
- QDialog::showEvent(e);
- int w = qMax(isVisible() ? width() : 0, sizeHint().width());
- int h = qMax(isVisible() ? height() : 0, sizeHint().height());
- resize(w, h);
- d->forceTimer->stop();
-}
-
-/*!
- Shows the dialog if it is still hidden after the algorithm has been started
- and minimumDuration milliseconds have passed.
-
- \sa setMinimumDuration()
-*/
-
-void QProgressDialog::forceShow()
-{
- Q_D(QProgressDialog);
- d->forceTimer->stop();
- if (d->shown_once || d->cancellation_flag)
- return;
-
- show();
- d->shown_once = true;
-}
-
-/*!
- \since 4.5
- \overload
-
- Opens the dialog and connects its accepted() signal to the slot specified
- by \a receiver and \a member.
-
- The signal will be disconnected from the slot when the dialog is closed.
-*/
-void QProgressDialog::open(QObject *receiver, const char *member)
-{
- Q_D(QProgressDialog);
- connect(this, SIGNAL(canceled()), receiver, member);
- d->receiverToDisconnectOnClose = receiver;
- d->memberToDisconnectOnClose = member;
- QDialog::open();
-}
-
-QT_END_NAMESPACE
-
-#include "moc_qprogressdialog.cpp"
-
-#endif // QT_NO_PROGRESSDIALOG
diff --git a/src/gui/dialogs/qprogressdialog.h b/src/gui/dialogs/qprogressdialog.h
deleted file mode 100644
index ca3ea5a0d9..0000000000
--- a/src/gui/dialogs/qprogressdialog.h
+++ /dev/null
@@ -1,145 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPROGRESSDIALOG_H
-#define QPROGRESSDIALOG_H
-
-#include <QtGui/qdialog.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_PROGRESSDIALOG
-
-class QPushButton;
-class QLabel;
-class QProgressBar;
-class QTimer;
-class QProgressDialogPrivate;
-
-class Q_GUI_EXPORT QProgressDialog : public QDialog
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QProgressDialog)
- Q_PROPERTY(bool wasCanceled READ wasCanceled)
- Q_PROPERTY(int minimum READ minimum WRITE setMinimum)
- Q_PROPERTY(int maximum READ maximum WRITE setMaximum)
- Q_PROPERTY(int value READ value WRITE setValue)
- Q_PROPERTY(bool autoReset READ autoReset WRITE setAutoReset)
- Q_PROPERTY(bool autoClose READ autoClose WRITE setAutoClose)
- Q_PROPERTY(int minimumDuration READ minimumDuration WRITE setMinimumDuration)
- Q_PROPERTY(QString labelText READ labelText WRITE setLabelText)
-
-public:
- explicit QProgressDialog(QWidget *parent = 0, Qt::WindowFlags flags = 0);
- QProgressDialog(const QString &labelText, const QString &cancelButtonText,
- int minimum, int maximum, QWidget *parent = 0, Qt::WindowFlags flags = 0);
- ~QProgressDialog();
-
- void setLabel(QLabel *label);
- void setCancelButton(QPushButton *button);
- void setBar(QProgressBar *bar);
-
- bool wasCanceled() const;
-
- int minimum() const;
- int maximum() const;
-
- int value() const;
-
- QSize sizeHint() const;
-
- QString labelText() const;
- int minimumDuration() const;
-
- void setAutoReset(bool reset);
- bool autoReset() const;
- void setAutoClose(bool close);
- bool autoClose() const;
-
-#ifdef Q_NO_USING_KEYWORD
-#ifndef Q_QDOC
- void open() { QDialog::open(); }
-#endif
-#else
- using QDialog::open;
-#endif
- void open(QObject *receiver, const char *member);
-
-public Q_SLOTS:
- void cancel();
- void reset();
- void setMaximum(int maximum);
- void setMinimum(int minimum);
- void setRange(int minimum, int maximum);
- void setValue(int progress);
- void setLabelText(const QString &text);
- void setCancelButtonText(const QString &text);
- void setMinimumDuration(int ms);
-
-Q_SIGNALS:
- void canceled();
-
-protected:
- void resizeEvent(QResizeEvent *event);
- void closeEvent(QCloseEvent *event);
- void changeEvent(QEvent *event);
- void showEvent(QShowEvent *event);
-
-protected Q_SLOTS:
- void forceShow();
-
-private:
- Q_DISABLE_COPY(QProgressDialog)
-
- Q_PRIVATE_SLOT(d_func(), void _q_disconnectOnClose())
-};
-
-#endif // QT_NO_PROGRESSDIALOG
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QPROGRESSDIALOG_H
diff --git a/src/gui/dialogs/qwizard.h b/src/gui/dialogs/qwizard.h
deleted file mode 100644
index 6978366480..0000000000
--- a/src/gui/dialogs/qwizard.h
+++ /dev/null
@@ -1,268 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWIZARD_H
-#define QWIZARD_H
-
-#include <QtGui/qdialog.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_WIZARD
-
-class QAbstractButton;
-class QWizardPage;
-class QWizardPrivate;
-
-class Q_GUI_EXPORT QWizard : public QDialog
-{
- Q_OBJECT
- Q_ENUMS(WizardStyle WizardOption)
- Q_FLAGS(WizardOptions)
- Q_PROPERTY(WizardStyle wizardStyle READ wizardStyle WRITE setWizardStyle)
- Q_PROPERTY(WizardOptions options READ options WRITE setOptions)
- Q_PROPERTY(Qt::TextFormat titleFormat READ titleFormat WRITE setTitleFormat)
- Q_PROPERTY(Qt::TextFormat subTitleFormat READ subTitleFormat WRITE setSubTitleFormat)
- Q_PROPERTY(int startId READ startId WRITE setStartId)
- Q_PROPERTY(int currentId READ currentId NOTIFY currentIdChanged)
-
-public:
- enum WizardButton {
- BackButton,
- NextButton,
- CommitButton,
- FinishButton,
- CancelButton,
- HelpButton,
- CustomButton1,
- CustomButton2,
- CustomButton3,
- Stretch,
-
- NoButton = -1,
- NStandardButtons = 6,
- NButtons = 9
- };
-
- enum WizardPixmap {
- WatermarkPixmap,
- LogoPixmap,
- BannerPixmap,
- BackgroundPixmap,
- NPixmaps
- };
-
- enum WizardStyle {
- ClassicStyle,
- ModernStyle,
- MacStyle,
- AeroStyle,
- NStyles
- };
-
- enum WizardOption {
- IndependentPages = 0x00000001,
- IgnoreSubTitles = 0x00000002,
- ExtendedWatermarkPixmap = 0x00000004,
- NoDefaultButton = 0x00000008,
- NoBackButtonOnStartPage = 0x00000010,
- NoBackButtonOnLastPage = 0x00000020,
- DisabledBackButtonOnLastPage = 0x00000040,
- HaveNextButtonOnLastPage = 0x00000080,
- HaveFinishButtonOnEarlyPages = 0x00000100,
- NoCancelButton = 0x00000200,
- CancelButtonOnLeft = 0x00000400,
- HaveHelpButton = 0x00000800,
- HelpButtonOnRight = 0x00001000,
- HaveCustomButton1 = 0x00002000,
- HaveCustomButton2 = 0x00004000,
- HaveCustomButton3 = 0x00008000
- };
-
- Q_DECLARE_FLAGS(WizardOptions, WizardOption)
-
- explicit QWizard(QWidget *parent = 0, Qt::WindowFlags flags = 0);
- ~QWizard();
-
- int addPage(QWizardPage *page);
- void setPage(int id, QWizardPage *page);
- void removePage(int id);
- QWizardPage *page(int id) const;
- bool hasVisitedPage(int id) const;
- QList<int> visitedPages() const; // ### visitedIds()?
- QList<int> pageIds() const;
- void setStartId(int id);
- int startId() const;
- QWizardPage *currentPage() const;
- int currentId() const;
-
- virtual bool validateCurrentPage();
- virtual int nextId() const;
-
- void setField(const QString &name, const QVariant &value);
- QVariant field(const QString &name) const;
-
- void setWizardStyle(WizardStyle style);
- WizardStyle wizardStyle() const;
-
- void setOption(WizardOption option, bool on = true);
- bool testOption(WizardOption option) const;
- void setOptions(WizardOptions options);
- WizardOptions options() const;
-
- void setButtonText(WizardButton which, const QString &text);
- QString buttonText(WizardButton which) const;
- void setButtonLayout(const QList<WizardButton> &layout);
- void setButton(WizardButton which, QAbstractButton *button);
- QAbstractButton *button(WizardButton which) const;
-
- void setTitleFormat(Qt::TextFormat format);
- Qt::TextFormat titleFormat() const;
- void setSubTitleFormat(Qt::TextFormat format);
- Qt::TextFormat subTitleFormat() const;
- void setPixmap(WizardPixmap which, const QPixmap &pixmap);
- QPixmap pixmap(WizardPixmap which) const;
-
- void setSideWidget(QWidget *widget);
- QWidget *sideWidget() const;
-
- void setDefaultProperty(const char *className, const char *property,
- const char *changedSignal);
-
- void setVisible(bool visible);
- QSize sizeHint() const;
-
-Q_SIGNALS:
- void currentIdChanged(int id);
- void helpRequested();
- void customButtonClicked(int which);
- void pageAdded(int id);
- void pageRemoved(int id);
-
-public Q_SLOTS:
- void back();
- void next();
- void restart();
-
-protected:
- bool event(QEvent *event);
- void resizeEvent(QResizeEvent *event);
- void paintEvent(QPaintEvent *event);
-#if defined(Q_WS_WIN)
- bool winEvent(MSG * message, long * result);
-#endif
- void done(int result);
- virtual void initializePage(int id);
- virtual void cleanupPage(int id);
-
-private:
- Q_DISABLE_COPY(QWizard)
- Q_DECLARE_PRIVATE(QWizard)
- Q_PRIVATE_SLOT(d_func(), void _q_emitCustomButtonClicked())
- Q_PRIVATE_SLOT(d_func(), void _q_updateButtonStates())
- Q_PRIVATE_SLOT(d_func(), void _q_handleFieldObjectDestroyed(QObject *))
-
- friend class QWizardPage;
-};
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QWizard::WizardOptions)
-
-class QWizardPagePrivate;
-
-class Q_GUI_EXPORT QWizardPage : public QWidget
-{
- Q_OBJECT
- Q_PROPERTY(QString title READ title WRITE setTitle)
- Q_PROPERTY(QString subTitle READ subTitle WRITE setSubTitle)
-
-public:
- QWizardPage(QWidget *parent = 0);
-
- void setTitle(const QString &title);
- QString title() const;
- void setSubTitle(const QString &subTitle);
- QString subTitle() const;
- void setPixmap(QWizard::WizardPixmap which, const QPixmap &pixmap);
- QPixmap pixmap(QWizard::WizardPixmap which) const;
- void setFinalPage(bool finalPage);
- bool isFinalPage() const;
- void setCommitPage(bool commitPage);
- bool isCommitPage() const;
- void setButtonText(QWizard::WizardButton which, const QString &text);
- QString buttonText(QWizard::WizardButton which) const;
-
- virtual void initializePage();
- virtual void cleanupPage();
- virtual bool validatePage();
- virtual bool isComplete() const;
- virtual int nextId() const;
-
-Q_SIGNALS:
- void completeChanged();
-
-protected:
- void setField(const QString &name, const QVariant &value);
- QVariant field(const QString &name) const;
- void registerField(const QString &name, QWidget *widget, const char *property = 0,
- const char *changedSignal = 0);
- QWizard *wizard() const;
-
-private:
- Q_DISABLE_COPY(QWizardPage)
- Q_DECLARE_PRIVATE(QWizardPage)
- Q_PRIVATE_SLOT(d_func(), void _q_maybeEmitCompleteChanged())
- Q_PRIVATE_SLOT(d_func(), void _q_updateCachedCompleteState())
-
- friend class QWizard;
- friend class QWizardPrivate;
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QT_NO_WIZARD
-
-#endif // QWIZARD_H
diff --git a/src/gui/dialogs/qwizard_win.cpp b/src/gui/dialogs/qwizard_win.cpp
deleted file mode 100644
index 9ea114c63f..0000000000
--- a/src/gui/dialogs/qwizard_win.cpp
+++ /dev/null
@@ -1,759 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QT_NO_WIZARD
-#ifndef QT_NO_STYLE_WINDOWSVISTA
-
-#include "qwizard_win_p.h"
-#include <private/qsystemlibrary_p.h>
-#include "qwizard.h"
-#include "qpaintengine.h"
-#include "qapplication.h"
-#include <QtGui/QMouseEvent>
-#include <QtGui/QDesktopWidget>
-
-// Note, these tests are duplicates in qwindowsxpstyle_p.h.
-#ifdef Q_CC_GNU
-# include <w32api.h>
-# if (__W32API_MAJOR_VERSION >= 3 || (__W32API_MAJOR_VERSION == 2 && __W32API_MINOR_VERSION >= 5))
-# ifdef _WIN32_WINNT
-# undef _WIN32_WINNT
-# endif
-# define _WIN32_WINNT 0x0501
-# include <commctrl.h>
-# endif
-#endif
-
-#include <uxtheme.h>
-
-QT_BEGIN_NAMESPACE
-
-//DWM related
-typedef struct { //MARGINS
- int cxLeftWidth; // width of left border that retains its size
- int cxRightWidth; // width of right border that retains its size
- int cyTopHeight; // height of top border that retains its size
- int cyBottomHeight; // height of bottom border that retains its size
-} WIZ_MARGINS;
-typedef struct { //DTTOPTS
- DWORD dwSize;
- DWORD dwFlags;
- COLORREF crText;
- COLORREF crBorder;
- COLORREF crShadow;
- int eTextShadowType;
- POINT ptShadowOffset;
- int iBorderSize;
- int iFontPropId;
- int iColorPropId;
- int iStateId;
- BOOL fApplyOverlay;
- int iGlowSize;
-} WIZ_DTTOPTS;
-
-typedef struct {
- DWORD dwFlags;
- DWORD dwMask;
-} WIZ_WTA_OPTIONS;
-
-#define WIZ_WM_THEMECHANGED 0x031A
-#define WIZ_WM_DWMCOMPOSITIONCHANGED 0x031E
-
-enum WIZ_WINDOWTHEMEATTRIBUTETYPE {
- WIZ_WTA_NONCLIENT = 1
-};
-
-#define WIZ_WTNCA_NODRAWCAPTION 0x00000001
-#define WIZ_WTNCA_NODRAWICON 0x00000002
-
-#define WIZ_DT_CENTER 0x00000001 //DT_CENTER
-#define WIZ_DT_VCENTER 0x00000004
-#define WIZ_DT_SINGLELINE 0x00000020
-#define WIZ_DT_NOPREFIX 0x00000800
-
-enum WIZ_NAVIGATIONPARTS { //NAVIGATIONPARTS
- WIZ_NAV_BACKBUTTON = 1,
- WIZ_NAV_FORWARDBUTTON = 2,
- WIZ_NAV_MENUBUTTON = 3,
-};
-
-enum WIZ_NAV_BACKBUTTONSTATES { //NAV_BACKBUTTONSTATES
- WIZ_NAV_BB_NORMAL = 1,
- WIZ_NAV_BB_HOT = 2,
- WIZ_NAV_BB_PRESSED = 3,
- WIZ_NAV_BB_DISABLED = 4,
-};
-
-#define WIZ_TMT_CAPTIONFONT (801) //TMT_CAPTIONFONT
-#define WIZ_DTT_COMPOSITED (1UL << 13) //DTT_COMPOSITED
-#define WIZ_DTT_GLOWSIZE (1UL << 11) //DTT_GLOWSIZE
-
-#define WIZ_WM_NCMOUSELEAVE 674 //WM_NCMOUSELEAVE
-
-#define WIZ_WP_CAPTION 1 //WP_CAPTION
-#define WIZ_CS_ACTIVE 1 //CS_ACTIVE
-#define WIZ_TMT_FILLCOLORHINT 3821 //TMT_FILLCOLORHINT
-#define WIZ_TMT_BORDERCOLORHINT 3822 //TMT_BORDERCOLORHINT
-
-typedef BOOL (WINAPI *PtrDwmDefWindowProc)(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, LRESULT *plResult);
-typedef HRESULT (WINAPI *PtrDwmIsCompositionEnabled)(BOOL* pfEnabled);
-typedef HRESULT (WINAPI *PtrDwmExtendFrameIntoClientArea)(HWND hWnd, const WIZ_MARGINS* pMarInset);
-typedef HRESULT (WINAPI *PtrSetWindowThemeAttribute)(HWND hwnd, enum WIZ_WINDOWTHEMEATTRIBUTETYPE eAttribute, PVOID pvAttribute, DWORD cbAttribute);
-
-static PtrDwmDefWindowProc pDwmDefWindowProc = 0;
-static PtrDwmIsCompositionEnabled pDwmIsCompositionEnabled = 0;
-static PtrDwmExtendFrameIntoClientArea pDwmExtendFrameIntoClientArea = 0;
-static PtrSetWindowThemeAttribute pSetWindowThemeAttribute = 0;
-
-//Theme related
-typedef bool (WINAPI *PtrIsAppThemed)();
-typedef bool (WINAPI *PtrIsThemeActive)();
-typedef HANDLE (WINAPI *PtrOpenThemeData)(HWND hwnd, LPCWSTR pszClassList);
-typedef HRESULT (WINAPI *PtrCloseThemeData)(HANDLE hTheme);
-typedef HRESULT (WINAPI *PtrGetThemeSysFont)(HANDLE hTheme, int iFontId, LOGFONTW *plf);
-typedef HRESULT (WINAPI *PtrDrawThemeTextEx)(HANDLE hTheme, HDC hdc, int iPartId, int iStateId, LPCWSTR pszText, int cchText, DWORD dwTextFlags, LPRECT pRect, const WIZ_DTTOPTS *pOptions);
-typedef HRESULT (WINAPI *PtrDrawThemeBackground)(HANDLE hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, OPTIONAL const RECT *pClipRect);
-typedef HRESULT (WINAPI *PtrGetThemePartSize)(HANDLE hTheme, HDC hdc, int iPartId, int iStateId, OPTIONAL RECT *prc, enum THEMESIZE eSize, OUT SIZE *psz);
-typedef HRESULT (WINAPI *PtrGetThemeColor)(HANDLE hTheme, int iPartId, int iStateId, int iPropId, OUT COLORREF *pColor);
-
-static PtrIsAppThemed pIsAppThemed = 0;
-static PtrIsThemeActive pIsThemeActive = 0;
-static PtrOpenThemeData pOpenThemeData = 0;
-static PtrCloseThemeData pCloseThemeData = 0;
-static PtrGetThemeSysFont pGetThemeSysFont = 0;
-static PtrDrawThemeTextEx pDrawThemeTextEx = 0;
-static PtrDrawThemeBackground pDrawThemeBackground = 0;
-static PtrGetThemePartSize pGetThemePartSize = 0;
-static PtrGetThemeColor pGetThemeColor = 0;
-
-bool QVistaHelper::is_vista = false;
-QVistaHelper::VistaState QVistaHelper::cachedVistaState = QVistaHelper::Dirty;
-
-/******************************************************************************
-** QVistaBackButton
-*/
-
-QVistaBackButton::QVistaBackButton(QWidget *widget)
- : QAbstractButton(widget)
-{
- setFocusPolicy(Qt::NoFocus);
-}
-
-QSize QVistaBackButton::sizeHint() const
-{
- ensurePolished();
- int size = int(QStyleHelper::dpiScaled(32));
- int width = size, height = size;
-/*
- HANDLE theme = pOpenThemeData(0, L"Navigation");
- SIZE size;
- if (pGetThemePartSize(theme, 0, WIZ_NAV_BACKBUTTON, WIZ_NAV_BB_NORMAL, 0, TS_TRUE, &size) == S_OK) {
- width = size.cx;
- height = size.cy;
- }
-*/
- return QSize(width, height);
-}
-
-void QVistaBackButton::enterEvent(QEvent *event)
-{
- if (isEnabled())
- update();
- QAbstractButton::enterEvent(event);
-}
-
-void QVistaBackButton::leaveEvent(QEvent *event)
-{
- if (isEnabled())
- update();
- QAbstractButton::leaveEvent(event);
-}
-
-void QVistaBackButton::paintEvent(QPaintEvent *)
-{
- QPainter p(this);
- QRect r = rect();
- HANDLE theme = pOpenThemeData(0, L"Navigation");
- //RECT rect;
- RECT clipRect;
- int xoffset = QWidget::mapToParent(r.topLeft()).x() - 1;
- int yoffset = QWidget::mapToParent(r.topLeft()).y() - 1;
-
- clipRect.top = r.top() + yoffset;
- clipRect.bottom = r.bottom() + yoffset;
- clipRect.left = r.left() + xoffset;
- clipRect.right = r.right() + xoffset;
-
- int state = WIZ_NAV_BB_NORMAL;
- if (!isEnabled())
- state = WIZ_NAV_BB_DISABLED;
- else if (isDown())
- state = WIZ_NAV_BB_PRESSED;
- else if (underMouse())
- state = WIZ_NAV_BB_HOT;
-
- pDrawThemeBackground(theme, p.paintEngine()->getDC(), WIZ_NAV_BACKBUTTON, state, &clipRect, &clipRect);
-}
-
-/******************************************************************************
-** QVistaHelper
-*/
-
-QVistaHelper::QVistaHelper(QWizard *wizard)
- : QObject(wizard)
- , pressed(false)
- , wizard(wizard)
- , backButton_(0)
-{
- is_vista = resolveSymbols();
- if (is_vista)
- backButton_ = new QVistaBackButton(wizard);
-
- // Handle diff between Windows 7 and Vista
- iconSpacing = QStyleHelper::dpiScaled(7);
- textSpacing = QSysInfo::WindowsVersion >= QSysInfo::WV_WINDOWS7 ?
- iconSpacing : QStyleHelper::dpiScaled(20);
-}
-
-QVistaHelper::~QVistaHelper()
-{
-}
-
-bool QVistaHelper::isCompositionEnabled()
-{
- bool value = is_vista;
- if (is_vista) {
- HRESULT hr;
- BOOL bEnabled;
-
- hr = pDwmIsCompositionEnabled(&bEnabled);
- value = (SUCCEEDED(hr) && bEnabled);
- }
- return value;
-}
-
-bool QVistaHelper::isThemeActive()
-{
- return is_vista && pIsThemeActive();
-}
-
-QVistaHelper::VistaState QVistaHelper::vistaState()
-{
- if (cachedVistaState == Dirty)
- cachedVistaState =
- isCompositionEnabled() ? VistaAero : isThemeActive() ? VistaBasic : Classic;
- return cachedVistaState;
-}
-
-QColor QVistaHelper::basicWindowFrameColor()
-{
- DWORD rgb;
- HANDLE hTheme = pOpenThemeData(QApplication::desktop()->winId(), L"WINDOW");
- pGetThemeColor(
- hTheme, WIZ_WP_CAPTION, WIZ_CS_ACTIVE,
- wizard->isActiveWindow() ? WIZ_TMT_FILLCOLORHINT : WIZ_TMT_BORDERCOLORHINT,
- &rgb);
- BYTE r = GetRValue(rgb);
- BYTE g = GetGValue(rgb);
- BYTE b = GetBValue(rgb);
- return QColor(r, g, b);
-}
-
-bool QVistaHelper::setDWMTitleBar(TitleBarChangeType type)
-{
- bool value = false;
- if (vistaState() == VistaAero) {
- WIZ_MARGINS mar = {0};
- if (type == NormalTitleBar)
- mar.cyTopHeight = 0;
- else
- mar.cyTopHeight = titleBarSize() + topOffset();
- HRESULT hr = pDwmExtendFrameIntoClientArea(wizard->winId(), &mar);
- value = SUCCEEDED(hr);
- }
- return value;
-}
-
-void QVistaHelper::drawTitleBar(QPainter *painter)
-{
- HDC hdc = painter->paintEngine()->getDC();
-
- if (vistaState() == VistaAero)
- drawBlackRect(QRect(0, 0, wizard->width(),
- titleBarSize() + topOffset()), hdc);
- Q_ASSERT(backButton_);
- const int btnTop = backButton_->mapToParent(QPoint()).y();
- const int btnHeight = backButton_->size().height();
- const int verticalCenter = (btnTop + btnHeight / 2) - 1;
-
- const QString text = wizard->window()->windowTitle();
- const QFont font = QApplication::font("QWorkspaceTitleBar");
- const QFontMetrics fontMetrics(font);
- const QRect brect = fontMetrics.boundingRect(text);
- int textHeight = brect.height();
- int textWidth = brect.width();
- int glowOffset = 0;
-
- if (vistaState() == VistaAero) {
- textHeight += 2 * glowSize();
- textWidth += 2 * glowSize();
- glowOffset = glowSize();
- }
-
- drawTitleText(
- painter, text,
- QRect(titleOffset() - glowOffset, verticalCenter - textHeight / 2, textWidth, textHeight),
- hdc);
-
- if (!wizard->windowIcon().isNull()) {
- QRect rect(leftMargin(), verticalCenter - iconSize() / 2, iconSize(), iconSize());
- HICON hIcon = wizard->windowIcon().pixmap(iconSize()).toWinHICON();
- DrawIconEx(hdc, rect.left(), rect.top(), hIcon, 0, 0, 0, NULL, DI_NORMAL | DI_COMPAT);
- DestroyIcon(hIcon);
- }
-}
-
-void QVistaHelper::setTitleBarIconAndCaptionVisible(bool visible)
-{
- if (is_vista) {
- WIZ_WTA_OPTIONS opt;
- opt.dwFlags = WIZ_WTNCA_NODRAWICON | WIZ_WTNCA_NODRAWCAPTION;
- if (visible)
- opt.dwMask = 0;
- else
- opt.dwMask = WIZ_WTNCA_NODRAWICON | WIZ_WTNCA_NODRAWCAPTION;
- pSetWindowThemeAttribute(wizard->winId(), WIZ_WTA_NONCLIENT, &opt, sizeof(WIZ_WTA_OPTIONS));
- }
-}
-
-bool QVistaHelper::winEvent(MSG* msg, long* result)
-{
- bool retval = true;
-
- switch (msg->message) {
- case WM_NCHITTEST: {
- LRESULT lResult;
- pDwmDefWindowProc(msg->hwnd, msg->message, msg->wParam, msg->lParam, &lResult);
- if (lResult == HTCLOSE || lResult == HTMAXBUTTON || lResult == HTMINBUTTON || lResult == HTHELP)
- *result = lResult;
- else
- *result = DefWindowProc(msg->hwnd, msg->message, msg->wParam, msg->lParam);
- break;
- }
- case WM_NCMOUSEMOVE:
- case WM_NCLBUTTONDOWN:
- case WM_NCLBUTTONUP:
- case WIZ_WM_NCMOUSELEAVE: {
- LRESULT lResult;
- pDwmDefWindowProc(msg->hwnd, msg->message, msg->wParam, msg->lParam, &lResult);
- *result = DefWindowProc(msg->hwnd, msg->message, msg->wParam, msg->lParam);
- break;
- }
- case WM_NCCALCSIZE: {
- NCCALCSIZE_PARAMS* lpncsp = (NCCALCSIZE_PARAMS*)msg->lParam;
- *result = DefWindowProc(msg->hwnd, msg->message, msg->wParam, msg->lParam);
- lpncsp->rgrc[0].top -= (vistaState() == VistaAero ? titleBarSize() : 0);
- break;
- }
- default:
- retval = false;
- }
-
- return retval;
-}
-
-void QVistaHelper::setMouseCursor(QPoint pos)
-{
-#ifndef QT_NO_CURSOR
- if (rtTop.contains(pos))
- wizard->setCursor(Qt::SizeVerCursor);
- else
- wizard->setCursor(Qt::ArrowCursor);
-#endif
-}
-
-void QVistaHelper::mouseEvent(QEvent *event)
-{
- switch (event->type()) {
- case QEvent::MouseMove:
- mouseMoveEvent(static_cast<QMouseEvent *>(event));
- break;
- case QEvent::MouseButtonPress:
- mousePressEvent(static_cast<QMouseEvent *>(event));
- break;
- case QEvent::MouseButtonRelease:
- mouseReleaseEvent(static_cast<QMouseEvent *>(event));
- break;
- default:
- break;
- }
-}
-
-// The following hack ensures that the titlebar is updated correctly
-// when the wizard style changes to and from AeroStyle. Specifically,
-// this function causes a Windows message of type WM_NCCALCSIZE to
-// be triggered.
-void QVistaHelper::setWindowPosHack()
-{
- const int x = wizard->geometry().x(); // ignored by SWP_NOMOVE
- const int y = wizard->geometry().y(); // ignored by SWP_NOMOVE
- const int w = wizard->width();
- const int h = wizard->height();
- SetWindowPos(wizard->winId(), 0, x, y, w, h, SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED);
-}
-
-// The following hack allows any QWidget subclass to access
-// QWidgetPrivate::topData() without being declared as a
-// friend by QWidget.
-class QHackWidget : public QWidget
-{
-public:
- Q_DECLARE_PRIVATE(QWidget)
- QTLWExtra* topData() { return d_func()->topData(); }
-};
-
-void QVistaHelper::collapseTopFrameStrut()
-{
- QTLWExtra *top = ((QHackWidget *)wizard)->d_func()->topData();
- int x1, y1, x2, y2;
- top->frameStrut.getCoords(&x1, &y1, &x2, &y2);
- top->frameStrut.setCoords(x1, 0, x2, y2);
-}
-
-bool QVistaHelper::handleWinEvent(MSG *message, long *result)
-{
- if (message->message == WIZ_WM_THEMECHANGED || message->message == WIZ_WM_DWMCOMPOSITIONCHANGED)
- cachedVistaState = Dirty;
-
- bool status = false;
- if (wizard->wizardStyle() == QWizard::AeroStyle && vistaState() == VistaAero) {
- status = winEvent(message, result);
- if (message->message == WM_NCCALCSIZE) {
- if (status)
- collapseTopFrameStrut();
- } else if (message->message == WM_NCPAINT) {
- wizard->update();
- }
- }
- return status;
-}
-
-void QVistaHelper::resizeEvent(QResizeEvent * event)
-{
- Q_UNUSED(event);
- rtTop = QRect (0, 0, wizard->width(), frameSize());
- int height = captionSize() + topOffset();
- if (vistaState() == VistaBasic)
- height -= titleBarSize();
- rtTitle = QRect (0, frameSize(), wizard->width(), height);
-}
-
-void QVistaHelper::paintEvent(QPaintEvent *event)
-{
- Q_UNUSED(event);
- QPainter painter(wizard);
- drawTitleBar(&painter);
-}
-
-void QVistaHelper::mouseMoveEvent(QMouseEvent *event)
-{
- if (wizard->windowState() & Qt::WindowMaximized) {
- event->ignore();
- return;
- }
-
- QRect rect = wizard->geometry();
- if (pressed) {
- switch (change) {
- case resizeTop:
- {
- const int dy = event->pos().y() - pressedPos.y();
- if ((dy > 0 && rect.height() > wizard->minimumHeight())
- || (dy < 0 && rect.height() < wizard->maximumHeight()))
- rect.setTop(rect.top() + dy);
- }
- break;
- case movePosition: {
- QPoint newPos = event->pos() - pressedPos;
- rect.moveLeft(rect.left() + newPos.x());
- rect.moveTop(rect.top() + newPos.y());
- break; }
- default:
- break;
- }
- wizard->setGeometry(rect);
-
- } else if (vistaState() == VistaAero) {
- setMouseCursor(event->pos());
- }
- event->ignore();
-}
-
-void QVistaHelper::mousePressEvent(QMouseEvent *event)
-{
- change = noChange;
-
- if (wizard->windowState() & Qt::WindowMaximized) {
- event->ignore();
- return;
- }
-
- if (rtTitle.contains(event->pos())) {
- change = movePosition;
- } else if (rtTop.contains(event->pos()))
- change = (vistaState() == VistaAero) ? resizeTop : movePosition;
-
- if (change != noChange) {
- if (vistaState() == VistaAero)
- setMouseCursor(event->pos());
- pressed = true;
- pressedPos = event->pos();
- } else {
- event->ignore();
- }
-}
-
-void QVistaHelper::mouseReleaseEvent(QMouseEvent *event)
-{
- change = noChange;
- if (pressed) {
- pressed = false;
- wizard->releaseMouse();
- if (vistaState() == VistaAero)
- setMouseCursor(event->pos());
- }
- event->ignore();
-}
-
-bool QVistaHelper::eventFilter(QObject *obj, QEvent *event)
-{
- if (obj != wizard)
- return QObject::eventFilter(obj, event);
-
- if (event->type() == QEvent::MouseMove) {
- QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
- long result;
- MSG msg;
- msg.message = WM_NCHITTEST;
- msg.wParam = 0;
- msg.lParam = MAKELPARAM(mouseEvent->globalX(), mouseEvent->globalY());
- msg.hwnd = wizard->winId();
- winEvent(&msg, &result);
- msg.wParam = result;
- msg.message = WM_NCMOUSEMOVE;
- winEvent(&msg, &result);
- } else if (event->type() == QEvent::MouseButtonPress) {
- QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
- long result;
- MSG msg;
- msg.message = WM_NCHITTEST;
- msg.wParam = 0;
- msg.lParam = MAKELPARAM(mouseEvent->globalX(), mouseEvent->globalY());
- msg.hwnd = wizard->winId();
- winEvent(&msg, &result);
- msg.wParam = result;
- msg.message = WM_NCLBUTTONDOWN;
- winEvent(&msg, &result);
- } else if (event->type() == QEvent::MouseButtonRelease) {
- QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
- long result;
- MSG msg;
- msg.message = WM_NCHITTEST;
- msg.wParam = 0;
- msg.lParam = MAKELPARAM(mouseEvent->globalX(), mouseEvent->globalY());
- msg.hwnd = wizard->winId();
- winEvent(&msg, &result);
- msg.wParam = result;
- msg.message = WM_NCLBUTTONUP;
- winEvent(&msg, &result);
- }
-
- return false;
-}
-
-HFONT QVistaHelper::getCaptionFont(HANDLE hTheme)
-{
- LOGFONT lf = {0};
-
- if (!hTheme)
- pGetThemeSysFont(hTheme, WIZ_TMT_CAPTIONFONT, &lf);
- else
- {
- NONCLIENTMETRICS ncm = {sizeof(NONCLIENTMETRICS)};
- SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, false);
- lf = ncm.lfMessageFont;
- }
- return CreateFontIndirect(&lf);
-}
-
-bool QVistaHelper::drawTitleText(QPainter *painter, const QString &text, const QRect &rect, HDC hdc)
-{
- bool value = false;
- if (vistaState() == VistaAero) {
- HANDLE hTheme = pOpenThemeData(QApplication::desktop()->winId(), L"WINDOW");
- if (!hTheme) return false;
- // Set up a memory DC and bitmap that we'll draw into
- HDC dcMem;
- HBITMAP bmp;
- BITMAPINFO dib = {{0}};
- dcMem = CreateCompatibleDC(hdc);
-
- dib.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- dib.bmiHeader.biWidth = rect.width();
- dib.bmiHeader.biHeight = -rect.height();
- dib.bmiHeader.biPlanes = 1;
- dib.bmiHeader.biBitCount = 32;
- dib.bmiHeader.biCompression = BI_RGB;
-
- bmp = CreateDIBSection(hdc, &dib, DIB_RGB_COLORS, NULL, NULL, 0);
-
- // Set up the DC
- HFONT hCaptionFont = getCaptionFont(hTheme);
- HBITMAP hOldBmp = (HBITMAP)SelectObject(dcMem, (HGDIOBJ) bmp);
- HFONT hOldFont = (HFONT)SelectObject(dcMem, (HGDIOBJ) hCaptionFont);
-
- // Draw the text!
- WIZ_DTTOPTS dto = { sizeof(WIZ_DTTOPTS) };
- const UINT uFormat = WIZ_DT_SINGLELINE|WIZ_DT_CENTER|WIZ_DT_VCENTER|WIZ_DT_NOPREFIX;
- RECT rctext ={0,0, rect.width(), rect.height()};
-
- dto.dwFlags = WIZ_DTT_COMPOSITED|WIZ_DTT_GLOWSIZE;
- dto.iGlowSize = glowSize();
-
- pDrawThemeTextEx(hTheme, dcMem, 0, 0, (LPCWSTR)text.utf16(), -1, uFormat, &rctext, &dto );
- BitBlt(hdc, rect.left(), rect.top(), rect.width(), rect.height(), dcMem, 0, 0, SRCCOPY);
- SelectObject(dcMem, (HGDIOBJ) hOldBmp);
- SelectObject(dcMem, (HGDIOBJ) hOldFont);
- DeleteObject(bmp);
- DeleteObject(hCaptionFont);
- DeleteDC(dcMem);
- //ReleaseDC(hwnd, hdc);
- } else if (vistaState() == VistaBasic) {
- painter->drawText(rect, text);
- }
- return value;
-}
-
-bool QVistaHelper::drawBlackRect(const QRect &rect, HDC hdc)
-{
- bool value = false;
- if (vistaState() == VistaAero) {
- // Set up a memory DC and bitmap that we'll draw into
- HDC dcMem;
- HBITMAP bmp;
- BITMAPINFO dib = {{0}};
- dcMem = CreateCompatibleDC(hdc);
-
- dib.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- dib.bmiHeader.biWidth = rect.width();
- dib.bmiHeader.biHeight = -rect.height();
- dib.bmiHeader.biPlanes = 1;
- dib.bmiHeader.biBitCount = 32;
- dib.bmiHeader.biCompression = BI_RGB;
-
- bmp = CreateDIBSection(hdc, &dib, DIB_RGB_COLORS, NULL, NULL, 0);
- HBITMAP hOldBmp = (HBITMAP)SelectObject(dcMem, (HGDIOBJ) bmp);
-
- BitBlt(hdc, rect.left(), rect.top(), rect.width(), rect.height(), dcMem, 0, 0, SRCCOPY);
- SelectObject(dcMem, (HGDIOBJ) hOldBmp);
-
- DeleteObject(bmp);
- DeleteDC(dcMem);
- }
- return value;
-}
-
-bool QVistaHelper::resolveSymbols()
-{
- static bool tried = false;
- if (!tried) {
- tried = true;
- QSystemLibrary dwmLib(L"dwmapi");
- pDwmIsCompositionEnabled =
- (PtrDwmIsCompositionEnabled)dwmLib.resolve("DwmIsCompositionEnabled");
- if (pDwmIsCompositionEnabled) {
- pDwmDefWindowProc = (PtrDwmDefWindowProc)dwmLib.resolve("DwmDefWindowProc");
- pDwmExtendFrameIntoClientArea =
- (PtrDwmExtendFrameIntoClientArea)dwmLib.resolve("DwmExtendFrameIntoClientArea");
- }
- QSystemLibrary themeLib(L"uxtheme");
- pIsAppThemed = (PtrIsAppThemed)themeLib.resolve("IsAppThemed");
- if (pIsAppThemed) {
- pDrawThemeBackground = (PtrDrawThemeBackground)themeLib.resolve("DrawThemeBackground");
- pGetThemePartSize = (PtrGetThemePartSize)themeLib.resolve("GetThemePartSize");
- pGetThemeColor = (PtrGetThemeColor)themeLib.resolve("GetThemeColor");
- pIsThemeActive = (PtrIsThemeActive)themeLib.resolve("IsThemeActive");
- pOpenThemeData = (PtrOpenThemeData)themeLib.resolve("OpenThemeData");
- pCloseThemeData = (PtrCloseThemeData)themeLib.resolve("CloseThemeData");
- pGetThemeSysFont = (PtrGetThemeSysFont)themeLib.resolve("GetThemeSysFont");
- pDrawThemeTextEx = (PtrDrawThemeTextEx)themeLib.resolve("DrawThemeTextEx");
- pSetWindowThemeAttribute = (PtrSetWindowThemeAttribute)themeLib.resolve("SetWindowThemeAttribute");
- }
- }
-
- return (
- pDwmIsCompositionEnabled != 0
- && pDwmDefWindowProc != 0
- && pDwmExtendFrameIntoClientArea != 0
- && pIsAppThemed != 0
- && pDrawThemeBackground != 0
- && pGetThemePartSize != 0
- && pGetThemeColor != 0
- && pIsThemeActive != 0
- && pOpenThemeData != 0
- && pCloseThemeData != 0
- && pGetThemeSysFont != 0
- && pDrawThemeTextEx != 0
- && pSetWindowThemeAttribute != 0
- );
-}
-
-int QVistaHelper::titleOffset()
-{
- int iconOffset = wizard ->windowIcon().isNull() ? 0 : iconSize() + textSpacing;
- return leftMargin() + iconOffset;
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_STYLE_WINDOWSVISTA
-
-#endif // QT_NO_WIZARD
diff --git a/src/gui/dialogs/qwizard_win_p.h b/src/gui/dialogs/qwizard_win_p.h
deleted file mode 100644
index 7009fa738d..0000000000
--- a/src/gui/dialogs/qwizard_win_p.h
+++ /dev/null
@@ -1,158 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWIZARD_WIN_P_H
-#define QWIZARD_WIN_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#ifndef QT_NO_WIZARD
-#ifndef QT_NO_STYLE_WINDOWSVISTA
-
-#include <qt_windows.h>
-#include <qobject.h>
-#include <qwidget.h>
-#include <qabstractbutton.h>
-#include <QtGui/private/qwidget_p.h>
-#include <QtGui/private/qstylehelper_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QVistaBackButton : public QAbstractButton
-{
-public:
- QVistaBackButton(QWidget *widget);
-
- QSize sizeHint() const;
- inline QSize minimumSizeHint() const
- { return sizeHint(); }
-
- void enterEvent(QEvent *event);
- void leaveEvent(QEvent *event);
- void paintEvent(QPaintEvent *event);
-};
-
-class QWizard;
-
-class QVistaHelper : public QObject
-{
-public:
- QVistaHelper(QWizard *wizard);
- ~QVistaHelper();
- enum TitleBarChangeType { NormalTitleBar, ExtendedTitleBar };
- bool setDWMTitleBar(TitleBarChangeType type);
- void setTitleBarIconAndCaptionVisible(bool visible);
- void mouseEvent(QEvent *event);
- bool handleWinEvent(MSG *message, long *result);
- void resizeEvent(QResizeEvent *event);
- void paintEvent(QPaintEvent *event);
- QVistaBackButton *backButton() const { return backButton_; }
- void disconnectBackButton() { if (backButton_) backButton_->disconnect(); }
- void hideBackButton() { if (backButton_) backButton_->hide(); }
- void setWindowPosHack();
- QColor basicWindowFrameColor();
- enum VistaState { VistaAero, VistaBasic, Classic, Dirty };
- static VistaState vistaState();
- static int titleBarSize() { return frameSize() + captionSize(); }
- static int topPadding() { // padding under text
- return int(QStyleHelper::dpiScaled(
- QSysInfo::WindowsVersion >= QSysInfo::WV_WINDOWS7 ? 4 : 6));
- }
- static int topOffset() {
- static int aeroOffset = QSysInfo::WindowsVersion >= QSysInfo::WV_WINDOWS7 ?
- QStyleHelper::dpiScaled(4) : QStyleHelper::dpiScaled(13);
- return (titleBarSize() + (vistaState() == VistaAero ? aeroOffset : 3)); }
-private:
- static HFONT getCaptionFont(HANDLE hTheme);
- bool drawTitleText(QPainter *painter, const QString &text, const QRect &rect, HDC hdc);
- static bool drawBlackRect(const QRect &rect, HDC hdc);
-
- static int frameSize() { return GetSystemMetrics(SM_CYSIZEFRAME); }
- static int captionSize() { return GetSystemMetrics(SM_CYCAPTION); }
-
- static int backButtonSize() { return int(QStyleHelper::dpiScaled(30)); }
- static int iconSize() { return 16; } // Standard Aero
- static int glowSize() { return 10; }
- int leftMargin() { return backButton_->isVisible() ? backButtonSize() + iconSpacing : 0; }
-
- int titleOffset();
- bool resolveSymbols();
- void drawTitleBar(QPainter *painter);
- void setMouseCursor(QPoint pos);
- void collapseTopFrameStrut();
- bool winEvent(MSG *message, long *result);
- void mouseMoveEvent(QMouseEvent *event);
- void mousePressEvent(QMouseEvent *event);
- void mouseReleaseEvent(QMouseEvent *event);
- bool eventFilter(QObject *obj, QEvent *event);
-
- static bool is_vista;
- static VistaState cachedVistaState;
- static bool isCompositionEnabled();
- static bool isThemeActive();
- enum Changes { resizeTop, movePosition, noChange } change;
- QPoint pressedPos;
- bool pressed;
- QRect rtTop;
- QRect rtTitle;
- QWizard *wizard;
- QVistaBackButton *backButton_;
-
- int titleBarOffset; // Extra spacing above the text
- int iconSpacing; // Space between button and icon
- int textSpacing; // Space between icon and text
-};
-
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_STYLE_WINDOWSVISTA
-#endif // QT_NO_WIZARD
-#endif // QWIZARD_WIN_P_H
diff --git a/src/gui/effects/effects.pri b/src/gui/effects/effects.pri
deleted file mode 100644
index 0ebf96fccb..0000000000
--- a/src/gui/effects/effects.pri
+++ /dev/null
@@ -1,4 +0,0 @@
-HEADERS += effects/qgraphicseffect.h \
- effects/qgraphicseffect_p.h
-
-SOURCES += effects/qgraphicseffect.cpp
diff --git a/src/gui/effects/qgraphicseffect.cpp b/src/gui/effects/qgraphicseffect.cpp
deleted file mode 100644
index a92d156e89..0000000000
--- a/src/gui/effects/qgraphicseffect.cpp
+++ /dev/null
@@ -1,1235 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*!
- \class QGraphicsEffect
- \brief The QGraphicsEffect class is the base class for all graphics
- effects.
- \since 4.6
- \ingroup multimedia
- \ingroup graphicsview-api
-
- Effects alter the appearance of elements by hooking into the rendering
- pipeline and operating between the source (e.g., a QGraphicsPixmapItem)
- and the destination device (e.g., QGraphicsView's viewport). Effects can be
- disabled by calling setEnabled(false). If effects are disabled, the source
- is rendered directly.
-
- To add a visual effect to a QGraphicsItem, for example, you can use one of
- the standard effects, or alternately, create your own effect by creating a
- subclass of QGraphicsEffect. The effect can then be installed on the item
- using QGraphicsItem::setGraphicsEffect().
-
- Qt provides the following standard effects:
-
- \list
- \o QGraphicsBlurEffect - blurs the item by a given radius
- \o QGraphicsDropShadowEffect - renders a dropshadow behind the item
- \o QGraphicsColorizeEffect - renders the item in shades of any given color
- \o QGraphicsOpacityEffect - renders the item with an opacity
- \endlist
-
- \table
- \row
- \o{2,1} \img graphicseffect-plain.png
- \row
- \o \img graphicseffect-blur.png
- \o \img graphicseffect-colorize.png
- \row
- \o \img graphicseffect-opacity.png
- \o \img graphicseffect-drop-shadow.png
- \endtable
-
- \img graphicseffect-widget.png
-
- For more information on how to use each effect, refer to the specific
- effect's documentation.
-
- To create your own custom effect, create a subclass of QGraphicsEffect (or
- any other existing effects) and reimplement the virtual function draw().
- This function is called whenever the effect needs to redraw. The draw()
- function takes the painter with which to draw as an argument. For more
- information, refer to the documenation for draw(). In the draw() function
- you can call sourcePixmap() to get a pixmap of the graphics effect source
- which you can then process.
-
- If your effect changes, use update() to request for a redraw. If your
- custom effect changes the bounding rectangle of the source, e.g., a radial
- glow effect may need to apply an extra margin, you can reimplement the
- virtual boundingRectFor() function, and call updateBoundingRect()
- to notify the framework whenever this rectangle changes. The virtual
- sourceChanged() function is called to notify the effects that
- the source has changed in some way - e.g., if the source is a
- QGraphicsRectItem and its rectangle parameters have changed.
-
- \sa QGraphicsItem::setGraphicsEffect(), QWidget::setGraphicsEffect()
-*/
-
-#include "qgraphicseffect_p.h"
-#include "private/qgraphicsitem_p.h"
-
-#include <QtGui/qgraphicsitem.h>
-
-#include <QtGui/qimage.h>
-#include <QtGui/qpainter.h>
-#include <QtGui/qpaintengine.h>
-#include <QtCore/qrect.h>
-#include <QtCore/qdebug.h>
-#include <private/qdrawhelper_p.h>
-
-#ifndef QT_NO_GRAPHICSEFFECT
-QT_BEGIN_NAMESPACE
-
-/*!
- \internal
- \class QGraphicsEffectSource
- \brief The QGraphicsEffectSource class represents the source on which a
- QGraphicsEffect is installed on.
-
- When a QGraphicsEffect is installed on a QGraphicsItem, for example, this
- class will act as a wrapper around QGraphicsItem. Then, calling update() is
- effectively the same as calling QGraphicsItem::update().
-
- QGraphicsEffectSource also provides a pixmap() function which creates a
- pixmap with the source painted into it.
-
- \sa QGraphicsItem::setGraphicsEffect(), QWidget::setGraphicsEffect().
-*/
-
-/*!
- \internal
-*/
-QGraphicsEffectSource::QGraphicsEffectSource(QGraphicsEffectSourcePrivate &dd, QObject *parent)
- : QObject(dd, parent)
-{}
-
-/*!
- Destroys the effect source.
-*/
-QGraphicsEffectSource::~QGraphicsEffectSource()
-{}
-
-/*!
- Returns the bounding rectangle of the source mapped to the given \a system.
-
- \sa draw()
-*/
-QRectF QGraphicsEffectSource::boundingRect(Qt::CoordinateSystem system) const
-{
- return d_func()->boundingRect(system);
-}
-
-/*!
- Returns the bounding rectangle of the source mapped to the given \a system.
-
- Calling this function with Qt::DeviceCoordinates outside of
- QGraphicsEffect::draw() will give undefined results, as there is no device
- context available.
-
- \sa draw()
-*/
-QRectF QGraphicsEffect::sourceBoundingRect(Qt::CoordinateSystem system) const
-{
- Q_D(const QGraphicsEffect);
- if (d->source)
- return d->source->boundingRect(system);
- return QRectF();
-}
-
-/*!
- Returns a pointer to the item if this source is a QGraphicsItem; otherwise
- returns 0.
-
- \sa widget()
-*/
-const QGraphicsItem *QGraphicsEffectSource::graphicsItem() const
-{
- return d_func()->graphicsItem();
-}
-
-/*!
- Returns a pointer to the widget if this source is a QWidget; otherwise
- returns 0.
-
- \sa graphicsItem()
-*/
-const QWidget *QGraphicsEffectSource::widget() const
-{
- return d_func()->widget();
-}
-
-/*!
- Returns a pointer to the style options (used when drawing the source) if
- available; otherwise returns 0.
-
- \sa graphicsItem(), widget()
-*/
-const QStyleOption *QGraphicsEffectSource::styleOption() const
-{
- return d_func()->styleOption();
-}
-
-/*!
- Draws the source using the given \a painter.
-
- This function should only be called from QGraphicsEffect::draw().
-
- \sa QGraphicsEffect::draw()
-*/
-void QGraphicsEffectSource::draw(QPainter *painter)
-{
- Q_D(const QGraphicsEffectSource);
-
- QPixmap pm;
- if (QPixmapCache::find(d->m_cacheKey, &pm)) {
- QTransform restoreTransform;
- if (d->m_cachedSystem == Qt::DeviceCoordinates) {
- restoreTransform = painter->worldTransform();
- painter->setWorldTransform(QTransform());
- }
-
- painter->drawPixmap(d->m_cachedOffset, pm);
-
- if (d->m_cachedSystem == Qt::DeviceCoordinates)
- painter->setWorldTransform(restoreTransform);
- } else {
- d_func()->draw(painter);
- }
-}
-
-/*!
- Draws the source directly using the given \a painter.
-
- This function should only be called from QGraphicsEffect::draw().
-
- For example:
-
- \snippet doc/src/snippets/code/src_gui_effects_qgraphicseffect.cpp 0
-
- \sa QGraphicsEffect::draw()
-*/
-void QGraphicsEffect::drawSource(QPainter *painter)
-{
- Q_D(const QGraphicsEffect);
- if (d->source)
- d->source->draw(painter);
-}
-
-/*!
- Schedules a redraw of the source. Call this function whenever the source
- needs to be redrawn.
-
- \sa QGraphicsEffect::updateBoundingRect(), QWidget::update(),
- QGraphicsItem::update(),
-*/
-void QGraphicsEffectSource::update()
-{
- d_func()->update();
-}
-
-/*!
- Returns true if the source effectively is a pixmap, e.g., a
- QGraphicsPixmapItem.
-
- This function is useful for optimization purposes. For instance, there's no
- point in drawing the source in device coordinates to avoid pixmap scaling
- if this function returns true - the source pixmap will be scaled anyways.
-*/
-bool QGraphicsEffectSource::isPixmap() const
-{
- return d_func()->isPixmap();
-}
-
-/*!
- Returns true if the source effectively is a pixmap, e.g., a
- QGraphicsPixmapItem.
-
- This function is useful for optimization purposes. For instance, there's no
- point in drawing the source in device coordinates to avoid pixmap scaling
- if this function returns true - the source pixmap will be scaled anyways.
-*/
-bool QGraphicsEffect::sourceIsPixmap() const
-{
- return source() ? source()->isPixmap() : false;
-}
-
-/*!
- Returns a pixmap with the source painted into it.
-
- The \a system specifies which coordinate system to be used for the source.
- The optional \a offset parameter returns the offset where the pixmap should
- be painted at using the current painter.
-
- The \a mode determines how much of the effect the pixmap will contain.
- By default, the pixmap will contain the whole effect.
-
- The returned pixmap is bound to the current painter's device rectangle when
- \a system is Qt::DeviceCoordinates.
-
- \sa QGraphicsEffect::draw(), boundingRect()
-*/
-QPixmap QGraphicsEffectSource::pixmap(Qt::CoordinateSystem system, QPoint *offset, QGraphicsEffect::PixmapPadMode mode) const
-{
- Q_D(const QGraphicsEffectSource);
-
- // Shortcut, no cache for childless pixmap items...
- const QGraphicsItem *item = graphicsItem();
- if (system == Qt::LogicalCoordinates && mode == QGraphicsEffect::NoPad && item && isPixmap()) {
- const QGraphicsPixmapItem *pixmapItem = static_cast<const QGraphicsPixmapItem *>(item);
- if (offset)
- *offset = pixmapItem->offset().toPoint();
- return pixmapItem->pixmap();
- }
-
- if (system == Qt::DeviceCoordinates && item
- && !static_cast<const QGraphicsItemEffectSourcePrivate *>(d_func())->info) {
- qWarning("QGraphicsEffectSource::pixmap: Not yet implemented, lacking device context");
- return QPixmap();
- }
-
- QPixmap pm;
- if (item && d->m_cachedSystem == system && d->m_cachedMode == mode)
- QPixmapCache::find(d->m_cacheKey, &pm);
-
- if (pm.isNull()) {
- pm = d->pixmap(system, &d->m_cachedOffset, mode);
- d->m_cachedSystem = system;
- d->m_cachedMode = mode;
-
- d->invalidateCache();
- d->m_cacheKey = QPixmapCache::insert(pm);
- }
-
- if (offset)
- *offset = d->m_cachedOffset;
-
- return pm;
-}
-
-/*!
- Returns a pixmap with the source painted into it.
-
- The \a system specifies which coordinate system to be used for the source.
- The optional \a offset parameter returns the offset where the pixmap should
- be painted at using the current painter. For control on how the pixmap is
- padded use the \a mode parameter.
-
- The returned pixmap is clipped to the current painter's device rectangle when
- \a system is Qt::DeviceCoordinates.
-
- Calling this function with Qt::DeviceCoordinates outside of
- QGraphicsEffect::draw() will give undefined results, as there is no device
- context available.
-
- \sa draw(), boundingRect()
-*/
-QPixmap QGraphicsEffect::sourcePixmap(Qt::CoordinateSystem system, QPoint *offset, QGraphicsEffect::PixmapPadMode mode) const
-{
- Q_D(const QGraphicsEffect);
- if (d->source)
- return d->source->pixmap(system, offset, mode);
- return QPixmap();
-}
-
-QGraphicsEffectSourcePrivate::~QGraphicsEffectSourcePrivate()
-{
- invalidateCache();
-}
-
-void QGraphicsEffectSourcePrivate::setCachedOffset(const QPoint &offset)
-{
- m_cachedOffset = offset;
-}
-
-void QGraphicsEffectSourcePrivate::invalidateCache(InvalidateReason reason) const
-{
- if (m_cachedMode != QGraphicsEffect::PadToEffectiveBoundingRect
- && (reason == EffectRectChanged
- || (reason == TransformChanged && m_cachedSystem == Qt::LogicalCoordinates))) {
- return;
- }
-
- QPixmapCache::remove(m_cacheKey);
-}
-
-/*!
- Constructs a new QGraphicsEffect instance having the
- specified \a parent.
-*/
-QGraphicsEffect::QGraphicsEffect(QObject *parent)
- : QObject(*new QGraphicsEffectPrivate, parent)
-{
-}
-
-/*!
- \internal
-*/
-QGraphicsEffect::QGraphicsEffect(QGraphicsEffectPrivate &dd, QObject *parent)
- : QObject(dd, parent)
-{
-}
-
-/*!
- Removes the effect from the source, and destroys the graphics effect.
-*/
-QGraphicsEffect::~QGraphicsEffect()
-{
- Q_D(QGraphicsEffect);
- d->setGraphicsEffectSource(0);
-}
-
-/*!
- Returns the effective bounding rectangle for this effect, i.e., the
- bounding rectangle of the source in device coordinates, adjusted by
- any margins applied by the effect itself.
-
- \sa boundingRectFor(), updateBoundingRect()
-*/
-QRectF QGraphicsEffect::boundingRect() const
-{
- Q_D(const QGraphicsEffect);
- if (d->source)
- return boundingRectFor(d->source->boundingRect());
- return QRectF();
-}
-
-/*!
- Returns the effective bounding rectangle for this effect, given the
- provided \a rect in the device coordinates. When writing
- you own custom effect, you must call updateBoundingRect() whenever any
- parameters are changed that may cause this this function to return a
- different value.
-
- \sa sourceBoundingRect()
-*/
-QRectF QGraphicsEffect::boundingRectFor(const QRectF &rect) const
-{
- return rect;
-}
-
-/*!
- \property QGraphicsEffect::enabled
- \brief whether the effect is enabled or not.
-
- If an effect is disabled, the source will be rendered with as normal, with
- no interference from the effect. If the effect is enabled, the source will
- be rendered with the effect applied.
-
- This property is enabled by default.
-
- Using this property, you can disable certain effects on slow platforms, in
- order to ensure that the user interface is responsive.
-*/
-bool QGraphicsEffect::isEnabled() const
-{
- Q_D(const QGraphicsEffect);
- return d->isEnabled;
-}
-
-void QGraphicsEffect::setEnabled(bool enable)
-{
- Q_D(QGraphicsEffect);
- if (d->isEnabled == enable)
- return;
-
- d->isEnabled = enable;
- if (d->source) {
- d->source->d_func()->effectBoundingRectChanged();
- d->source->d_func()->invalidateCache();
- }
- emit enabledChanged(enable);
-}
-
-/*!
- \fn void QGraphicsEffect::enabledChanged(bool enabled)
-
- This signal is emitted whenever the effect is enabled or disabled.
- The \a enabled parameter holds the effects's new enabled state.
-
- \sa isEnabled()
-*/
-
-/*!
- Schedules a redraw of the effect. Call this function whenever the effect
- needs to be redrawn. This function does not trigger a redraw of the source.
-
- \sa updateBoundingRect()
-*/
-void QGraphicsEffect::update()
-{
- Q_D(QGraphicsEffect);
- if (d->source)
- d->source->update();
-}
-
-/*!
- \internal
-
- Returns a pointer to the source, which provides extra context information
- that can be useful for the effect.
-
- \sa draw()
-*/
-QGraphicsEffectSource *QGraphicsEffect::source() const
-{
- Q_D(const QGraphicsEffect);
- return d->source;
-}
-
-/*!
- This function notifies the effect framework when the effect's bounding
- rectangle has changed. As a custom effect author, you must call this
- function whenever you change any parameters that will cause the virtual
- boundingRectFor() function to return a different value.
-
- This function will call update() if this is necessary.
-
- \sa boundingRectFor(), boundingRect(), sourceBoundingRect()
-*/
-void QGraphicsEffect::updateBoundingRect()
-{
- Q_D(QGraphicsEffect);
- if (d->source) {
- d->source->d_func()->effectBoundingRectChanged();
- d->source->d_func()->invalidateCache(QGraphicsEffectSourcePrivate::EffectRectChanged);
- }
-}
-
-/*!
- \fn virtual void QGraphicsEffect::draw(QPainter *painter) = 0
-
- This pure virtual function draws the effect and is called whenever the
- source needs to be drawn.
-
- Reimplement this function in a QGraphicsEffect subclass to provide the
- effect's drawing implementation, using \a painter.
-
- For example:
-
- \snippet doc/src/snippets/code/src_gui_effects_qgraphicseffect.cpp 1
-
- This function should not be called explicitly by the user, since it is
- meant for reimplementation purposes only.
-*/
-
-/*!
- \enum QGraphicsEffect::ChangeFlag
-
- This enum describes what has changed in QGraphicsEffectSource.
-
- \value SourceAttached The effect is installed on a source.
- \value SourceDetached The effect is uninstalled on a source.
- \value SourceBoundingRectChanged The bounding rect of the source has
- changed.
- \value SourceInvalidated The visual appearance of the source has changed.
-*/
-
-/*!
- \enum QGraphicsEffect::PixmapPadMode
-
- This enum describes how the pixmap returned from sourcePixmap should be
- padded.
-
- \value NoPad The pixmap should not receive any additional
- padding.
- \value PadToTransparentBorder The pixmap should be padded
- to ensure it has a completely transparent border.
- \value PadToEffectiveBoundingRect The pixmap should be padded to
- match the effective bounding rectangle of the effect.
-*/
-
-/*!
- This virtual function is called by QGraphicsEffect to notify the effect
- that the source has changed. If the effect applies any cache, then this
- cache must be purged in order to reflect the new appearance of the source.
-
- The \a flags describes what has changed.
-*/
-void QGraphicsEffect::sourceChanged(ChangeFlags flags)
-{
- Q_UNUSED(flags);
-}
-
-/*!
- \class QGraphicsColorizeEffect
- \brief The QGraphicsColorizeEffect class provides a colorize effect.
- \since 4.6
-
- A colorize effect renders the source with a tint of its color(). The color
- can be modified using the setColor() function.
-
- By default, the color is light blue (QColor(0, 0, 192)).
-
- \img graphicseffect-colorize.png
-
- \sa QGraphicsDropShadowEffect, QGraphicsBlurEffect, QGraphicsOpacityEffect
-*/
-
-/*!
- Constructs a new QGraphicsColorizeEffect instance.
- The \a parent parameter is passed to QGraphicsEffect's constructor.
-*/
-QGraphicsColorizeEffect::QGraphicsColorizeEffect(QObject *parent)
- : QGraphicsEffect(*new QGraphicsColorizeEffectPrivate, parent)
-{
-}
-
-/*!
- Destroys the effect.
-*/
-QGraphicsColorizeEffect::~QGraphicsColorizeEffect()
-{
-}
-
-/*!
- \property QGraphicsColorizeEffect::color
- \brief the color of the effect.
-
- By default, the color is light blue (QColor(0, 0, 192)).
-*/
-QColor QGraphicsColorizeEffect::color() const
-{
- Q_D(const QGraphicsColorizeEffect);
- return d->filter->color();
-}
-
-void QGraphicsColorizeEffect::setColor(const QColor &color)
-{
- Q_D(QGraphicsColorizeEffect);
- if (d->filter->color() == color)
- return;
-
- d->filter->setColor(color);
- update();
- emit colorChanged(color);
-}
-
-/*!
- \property QGraphicsColorizeEffect::strength
- \brief the strength of the effect.
-
- By default, the strength is 1.0.
- A strength 0.0 equals to no effect, while 1.0 means full colorization.
-*/
-qreal QGraphicsColorizeEffect::strength() const
-{
- Q_D(const QGraphicsColorizeEffect);
- return d->filter->strength();
-}
-
-void QGraphicsColorizeEffect::setStrength(qreal strength)
-{
- Q_D(QGraphicsColorizeEffect);
- if (qFuzzyCompare(d->filter->strength(), strength))
- return;
-
- d->filter->setStrength(strength);
- d->opaque = !qFuzzyIsNull(strength);
- update();
- emit strengthChanged(strength);
-}
-
-/*! \fn void QGraphicsColorizeEffect::strengthChanged(qreal strength)
- This signal is emitted whenever setStrength() changes the colorize
- strength property. \a strength contains the new strength value of
- the colorize effect.
- */
-
-/*!
- \fn void QGraphicsColorizeEffect::colorChanged(const QColor &color)
-
- This signal is emitted whenever the effect's color changes.
- The \a color parameter holds the effect's new color.
-*/
-
-/*!
- \reimp
-*/
-void QGraphicsColorizeEffect::draw(QPainter *painter)
-{
- Q_D(QGraphicsColorizeEffect);
-
- if (!d->opaque) {
- drawSource(painter);
- return;
- }
-
- QPoint offset;
- if (sourceIsPixmap()) {
- // No point in drawing in device coordinates (pixmap will be scaled anyways).
- const QPixmap pixmap = sourcePixmap(Qt::LogicalCoordinates, &offset, NoPad);
- if (!pixmap.isNull())
- d->filter->draw(painter, offset, pixmap);
-
- return;
- }
-
- // Draw pixmap in deviceCoordinates to avoid pixmap scaling.
- const QPixmap pixmap = sourcePixmap(Qt::DeviceCoordinates, &offset);
- if (pixmap.isNull())
- return;
-
- QTransform restoreTransform = painter->worldTransform();
- painter->setWorldTransform(QTransform());
- d->filter->draw(painter, offset, pixmap);
- painter->setWorldTransform(restoreTransform);
-}
-
-/*!
- \class QGraphicsBlurEffect
- \brief The QGraphicsBlurEffect class provides a blur effect.
- \since 4.6
-
- A blur effect blurs the source. This effect is useful for reducing details,
- such as when the source loses focus and you want to draw attention to other
- elements. The level of detail can be modified using the setBlurRadius()
- function. Use setBlurHints() to choose the blur hints.
-
- By default, the blur radius is 5 pixels. The blur radius is specified in
- device coordinates.
-
- \img graphicseffect-blur.png
-
- \sa QGraphicsDropShadowEffect, QGraphicsColorizeEffect, QGraphicsOpacityEffect
-*/
-
-/*!
- \enum QGraphicsBlurEffect::BlurHint
- \since 4.6
-
- This enum describes the possible hints that can be used to control how
- blur effects are applied. The hints might not have an effect in all the
- paint engines.
-
- \value PerformanceHint Indicates that rendering performance is the most important factor,
- at the potential cost of lower quality.
-
- \value QualityHint Indicates that rendering quality is the most important factor,
- at the potential cost of lower performance.
-
- \value AnimationHint Indicates that the blur radius is going to be animated, hinting
- that the implementation can keep a cache of blurred verisons of the source.
- Do not use this hint if the source is going to be dynamically changing.
-
- \sa blurHints(), setBlurHints()
-*/
-
-
-/*!
- Constructs a new QGraphicsBlurEffect instance.
- The \a parent parameter is passed to QGraphicsEffect's constructor.
-*/
-QGraphicsBlurEffect::QGraphicsBlurEffect(QObject *parent)
- : QGraphicsEffect(*new QGraphicsBlurEffectPrivate, parent)
-{
- Q_D(QGraphicsBlurEffect);
- d->filter->setBlurHints(QGraphicsBlurEffect::PerformanceHint);
-}
-
-/*!
- Destroys the effect.
-*/
-QGraphicsBlurEffect::~QGraphicsBlurEffect()
-{
-}
-
-/*!
- \property QGraphicsBlurEffect::blurRadius
- \brief the blur radius of the effect.
-
- Using a smaller radius results in a sharper appearance, whereas a bigger
- radius results in a more blurred appearance.
-
- By default, the blur radius is 5 pixels.
-
- The radius is given in device coordinates, meaning it is
- unaffected by scale.
-*/
-qreal QGraphicsBlurEffect::blurRadius() const
-{
- Q_D(const QGraphicsBlurEffect);
- return d->filter->radius();
-}
-
-void QGraphicsBlurEffect::setBlurRadius(qreal radius)
-{
- Q_D(QGraphicsBlurEffect);
- if (qFuzzyCompare(d->filter->radius(), radius))
- return;
-
- d->filter->setRadius(radius);
- updateBoundingRect();
- emit blurRadiusChanged(radius);
-}
-
-/*!
- \fn void QGraphicsBlurEffect::blurRadiusChanged(qreal radius)
-
- This signal is emitted whenever the effect's blur radius changes.
- The \a radius parameter holds the effect's new blur radius.
-*/
-
-/*!
- \property QGraphicsBlurEffect::blurHints
- \brief the blur hint of the effect.
-
- Use the PerformanceHint hint to say that you want a faster blur,
- the QualityHint hint to say that you prefer a higher quality blur,
- or the AnimationHint when you want to animate the blur radius.
-
- By default, the blur hint is PerformanceHint.
-*/
-QGraphicsBlurEffect::BlurHints QGraphicsBlurEffect::blurHints() const
-{
- Q_D(const QGraphicsBlurEffect);
- return d->filter->blurHints();
-}
-
-void QGraphicsBlurEffect::setBlurHints(QGraphicsBlurEffect::BlurHints hints)
-{
- Q_D(QGraphicsBlurEffect);
- if (d->filter->blurHints() == hints)
- return;
-
- d->filter->setBlurHints(hints);
- emit blurHintsChanged(hints);
-}
-
-/*!
- \fn void QGraphicsBlurEffect::blurHintsChanged(QGraphicsBlurEffect::BlurHints hints)
-
- This signal is emitted whenever the effect's blur hints changes.
- The \a hints parameter holds the effect's new blur hints.
-*/
-
-/*!
- \reimp
-*/
-QRectF QGraphicsBlurEffect::boundingRectFor(const QRectF &rect) const
-{
- Q_D(const QGraphicsBlurEffect);
- return d->filter->boundingRectFor(rect);
-}
-
-/*!
- \reimp
-*/
-void QGraphicsBlurEffect::draw(QPainter *painter)
-{
- Q_D(QGraphicsBlurEffect);
- if (d->filter->radius() < 1) {
- drawSource(painter);
- return;
- }
-
- PixmapPadMode mode = PadToEffectiveBoundingRect;
- if (painter->paintEngine()->type() == QPaintEngine::OpenGL2)
- mode = NoPad;
-
- QPoint offset;
- QPixmap pixmap = sourcePixmap(Qt::LogicalCoordinates, &offset, mode);
- if (pixmap.isNull())
- return;
-
- d->filter->draw(painter, offset, pixmap);
-}
-
-/*!
- \class QGraphicsDropShadowEffect
- \brief The QGraphicsDropShadowEffect class provides a drop shadow effect.
- \since 4.6
-
- A drop shadow effect renders the source with a drop shadow. The color of
- the drop shadow can be modified using the setColor() function. The drop
- shadow offset can be modified using the setOffset() function and the blur
- radius of the drop shadow can be changed with the setBlurRadius()
- function.
-
- By default, the drop shadow is a semi-transparent dark gray
- (QColor(63, 63, 63, 180)) shadow, blurred with a radius of 1 at an offset
- of 8 pixels towards the lower right. The drop shadow offset is specified
- in device coordinates.
-
- \img graphicseffect-drop-shadow.png
-
- \sa QGraphicsBlurEffect, QGraphicsColorizeEffect, QGraphicsOpacityEffect
-*/
-
-/*!
- Constructs a new QGraphicsDropShadowEffect instance.
- The \a parent parameter is passed to QGraphicsEffect's constructor.
-*/
-QGraphicsDropShadowEffect::QGraphicsDropShadowEffect(QObject *parent)
- : QGraphicsEffect(*new QGraphicsDropShadowEffectPrivate, parent)
-{
-}
-
-/*!
- Destroys the effect.
-*/
-QGraphicsDropShadowEffect::~QGraphicsDropShadowEffect()
-{
-}
-
-/*!
- \property QGraphicsDropShadowEffect::offset
- \brief the shadow offset in pixels.
-
- By default, the offset is 8 pixels towards the lower right.
-
- The offset is given in device coordinates, which means it is
- unaffected by scale.
-
- \sa xOffset(), yOffset(), blurRadius(), color()
-*/
-QPointF QGraphicsDropShadowEffect::offset() const
-{
- Q_D(const QGraphicsDropShadowEffect);
- return d->filter->offset();
-}
-
-void QGraphicsDropShadowEffect::setOffset(const QPointF &offset)
-{
- Q_D(QGraphicsDropShadowEffect);
- if (d->filter->offset() == offset)
- return;
-
- d->filter->setOffset(offset);
- updateBoundingRect();
- emit offsetChanged(offset);
-}
-
-/*!
- \property QGraphicsDropShadowEffect::xOffset
- \brief the horizontal shadow offset in pixels.
-
- By default, the horizontal shadow offset is 8 pixels.
-
-
-
- \sa yOffset(), offset()
-*/
-
-/*!
- \property QGraphicsDropShadowEffect::yOffset
- \brief the vertical shadow offset in pixels.
-
- By default, the vertical shadow offset is 8 pixels.
-
- \sa xOffset(), offset()
-*/
-
-/*!
- \fn void QGraphicsDropShadowEffect::offsetChanged(const QPointF &offset)
-
- This signal is emitted whenever the effect's shadow offset changes.
- The \a offset parameter holds the effect's new shadow offset.
-*/
-
-/*!
- \property QGraphicsDropShadowEffect::blurRadius
- \brief the blur radius in pixels of the drop shadow.
-
- Using a smaller radius results in a sharper shadow, whereas using a bigger
- radius results in a more blurred shadow.
-
- By default, the blur radius is 1 pixel.
-
- \sa color(), offset().
-*/
-qreal QGraphicsDropShadowEffect::blurRadius() const
-{
- Q_D(const QGraphicsDropShadowEffect);
- return d->filter->blurRadius();
-}
-
-void QGraphicsDropShadowEffect::setBlurRadius(qreal blurRadius)
-{
- Q_D(QGraphicsDropShadowEffect);
- if (qFuzzyCompare(d->filter->blurRadius(), blurRadius))
- return;
-
- d->filter->setBlurRadius(blurRadius);
- updateBoundingRect();
- emit blurRadiusChanged(blurRadius);
-}
-
-/*!
- \fn void QGraphicsDropShadowEffect::blurRadiusChanged(qreal blurRadius)
-
- This signal is emitted whenever the effect's blur radius changes.
- The \a blurRadius parameter holds the effect's new blur radius.
-*/
-
-/*!
- \property QGraphicsDropShadowEffect::color
- \brief the color of the drop shadow.
-
- By default, the drop color is a semi-transparent dark gray
- (QColor(63, 63, 63, 180)).
-
- \sa offset(), blurRadius()
-*/
-QColor QGraphicsDropShadowEffect::color() const
-{
- Q_D(const QGraphicsDropShadowEffect);
- return d->filter->color();
-}
-
-void QGraphicsDropShadowEffect::setColor(const QColor &color)
-{
- Q_D(QGraphicsDropShadowEffect);
- if (d->filter->color() == color)
- return;
-
- d->filter->setColor(color);
- update();
- emit colorChanged(color);
-}
-
-/*!
- \fn void QGraphicsDropShadowEffect::colorChanged(const QColor &color)
-
- This signal is emitted whenever the effect's color changes.
- The \a color parameter holds the effect's new color.
-*/
-
-/*!
- \reimp
-*/
-QRectF QGraphicsDropShadowEffect::boundingRectFor(const QRectF &rect) const
-{
- Q_D(const QGraphicsDropShadowEffect);
- return d->filter->boundingRectFor(rect);
-}
-
-/*!
- \reimp
-*/
-void QGraphicsDropShadowEffect::draw(QPainter *painter)
-{
- Q_D(QGraphicsDropShadowEffect);
- if (d->filter->blurRadius() <= 0 && d->filter->offset().isNull()) {
- drawSource(painter);
- return;
- }
-
- PixmapPadMode mode = PadToEffectiveBoundingRect;
- if (painter->paintEngine()->type() == QPaintEngine::OpenGL2)
- mode = NoPad;
-
- // Draw pixmap in device coordinates to avoid pixmap scaling.
- QPoint offset;
- const QPixmap pixmap = sourcePixmap(Qt::DeviceCoordinates, &offset, mode);
- if (pixmap.isNull())
- return;
-
- QTransform restoreTransform = painter->worldTransform();
- painter->setWorldTransform(QTransform());
- d->filter->draw(painter, offset, pixmap);
- painter->setWorldTransform(restoreTransform);
-}
-
-/*!
- \class QGraphicsOpacityEffect
- \brief The QGraphicsOpacityEffect class provides an opacity effect.
- \since 4.6
-
- An opacity effect renders the source with an opacity. This effect is useful
- for making the source semi-transparent, similar to a fade-in/fade-out
- sequence. The opacity can be modified using the setOpacity() function.
-
- By default, the opacity is 0.7.
-
- \img graphicseffect-opacity.png
-
- \sa QGraphicsDropShadowEffect, QGraphicsBlurEffect, QGraphicsColorizeEffect
-*/
-
-/*!
- Constructs a new QGraphicsOpacityEffect instance.
- The \a parent parameter is passed to QGraphicsEffect's constructor.
-*/
-QGraphicsOpacityEffect::QGraphicsOpacityEffect(QObject *parent)
- : QGraphicsEffect(*new QGraphicsOpacityEffectPrivate, parent)
-{
-}
-
-/*!
- Destroys the effect.
-*/
-QGraphicsOpacityEffect::~QGraphicsOpacityEffect()
-{
-}
-
-/*!
- \property QGraphicsOpacityEffect::opacity
- \brief the opacity of the effect.
-
- The value should be in the range of 0.0 to 1.0, where 0.0 is
- fully transparent and 1.0 is fully opaque.
-
- By default, the opacity is 0.7.
-
- \sa setOpacityMask()
-*/
-qreal QGraphicsOpacityEffect::opacity() const
-{
- Q_D(const QGraphicsOpacityEffect);
- return d->opacity;
-}
-
-void QGraphicsOpacityEffect::setOpacity(qreal opacity)
-{
- Q_D(QGraphicsOpacityEffect);
- opacity = qBound(qreal(0.0), opacity, qreal(1.0));
-
- if (qFuzzyCompare(d->opacity, opacity))
- return;
-
- d->opacity = opacity;
- if ((d->isFullyTransparent = qFuzzyIsNull(d->opacity)))
- d->isFullyOpaque = 0;
- else
- d->isFullyOpaque = qFuzzyIsNull(d->opacity - 1);
- update();
- emit opacityChanged(opacity);
-}
-
-/*!
- \fn void QGraphicsOpacityEffect::opacityChanged(qreal opacity)
-
- This signal is emitted whenever the effect's opacity changes.
- The \a opacity parameter holds the effect's new opacity.
-*/
-
-/*!
- \property QGraphicsOpacityEffect::opacityMask
- \brief the opacity mask of the effect.
-
- An opacity mask allows you apply opacity to portions of an element.
-
- For example:
-
- \snippet doc/src/snippets/code/src_gui_effects_qgraphicseffect.cpp 2
-
- There is no opacity mask by default.
-
- \sa setOpacity()
-*/
-QBrush QGraphicsOpacityEffect::opacityMask() const
-{
- Q_D(const QGraphicsOpacityEffect);
- return d->opacityMask;
-}
-
-void QGraphicsOpacityEffect::setOpacityMask(const QBrush &mask)
-{
- Q_D(QGraphicsOpacityEffect);
- if (d->opacityMask == mask)
- return;
-
- d->opacityMask = mask;
- d->hasOpacityMask = (mask.style() != Qt::NoBrush);
- update();
-
- emit opacityMaskChanged(mask);
-}
-
-/*!
- \fn void QGraphicsOpacityEffect::opacityMaskChanged(const QBrush &mask)
-
- This signal is emitted whenever the effect's opacity mask changes.
- The \a mask parameter holds the effect's new opacity mask.
-*/
-
-/*!
- \reimp
-*/
-void QGraphicsOpacityEffect::draw(QPainter *painter)
-{
- Q_D(QGraphicsOpacityEffect);
-
- // Transparent; nothing to draw.
- if (d->isFullyTransparent)
- return;
-
- // Opaque; draw directly without going through a pixmap.
- if (d->isFullyOpaque && !d->hasOpacityMask) {
- drawSource(painter);
- return;
- }
-
- QPoint offset;
- Qt::CoordinateSystem system = sourceIsPixmap() ? Qt::LogicalCoordinates : Qt::DeviceCoordinates;
- QPixmap pixmap = sourcePixmap(system, &offset, QGraphicsEffect::NoPad);
- if (pixmap.isNull())
- return;
-
- painter->save();
- painter->setOpacity(d->opacity);
-
- if (d->hasOpacityMask) {
- QPainter pixmapPainter(&pixmap);
- pixmapPainter.setRenderHints(painter->renderHints());
- pixmapPainter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
- if (system == Qt::DeviceCoordinates) {
- QTransform worldTransform = painter->worldTransform();
- worldTransform *= QTransform::fromTranslate(-offset.x(), -offset.y());
- pixmapPainter.setWorldTransform(worldTransform);
- pixmapPainter.fillRect(sourceBoundingRect(), d->opacityMask);
- } else {
- pixmapPainter.translate(-offset);
- pixmapPainter.fillRect(pixmap.rect(), d->opacityMask);
- }
- }
-
- if (system == Qt::DeviceCoordinates)
- painter->setWorldTransform(QTransform());
-
- painter->drawPixmap(offset, pixmap);
- painter->restore();
-}
-
-
-QT_END_NAMESPACE
-
-#endif //QT_NO_GRAPHICSEFFECT
diff --git a/src/gui/effects/qgraphicseffect.h b/src/gui/effects/qgraphicseffect.h
deleted file mode 100644
index 6ddb6ae92c..0000000000
--- a/src/gui/effects/qgraphicseffect.h
+++ /dev/null
@@ -1,289 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGRAPHICSEFFECT_H
-#define QGRAPHICSEFFECT_H
-
-#include <QtCore/qobject.h>
-#include <QtCore/qpoint.h>
-#include <QtCore/qrect.h>
-#include <QtGui/qcolor.h>
-#include <QtGui/qbrush.h>
-
-#ifndef QT_NO_GRAPHICSEFFECT
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QGraphicsItem;
-class QStyleOption;
-class QPainter;
-class QPixmap;
-
-class QGraphicsEffectSource;
-
-class QGraphicsEffectPrivate;
-class Q_GUI_EXPORT QGraphicsEffect : public QObject
-{
- Q_OBJECT
- Q_FLAGS(ChangeFlags)
- Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged)
-public:
- enum ChangeFlag {
- SourceAttached = 0x1,
- SourceDetached = 0x2,
- SourceBoundingRectChanged = 0x4,
- SourceInvalidated = 0x8
- };
- Q_DECLARE_FLAGS(ChangeFlags, ChangeFlag)
-
- enum PixmapPadMode {
- NoPad,
- PadToTransparentBorder,
- PadToEffectiveBoundingRect
- };
-
- QGraphicsEffect(QObject *parent = 0);
- virtual ~QGraphicsEffect();
-
- virtual QRectF boundingRectFor(const QRectF &sourceRect) const;
- QRectF boundingRect() const;
-
- bool isEnabled() const;
-
-public Q_SLOTS:
- void setEnabled(bool enable);
- void update();
-
-Q_SIGNALS:
- void enabledChanged(bool enabled);
-
-protected:
- QGraphicsEffect(QGraphicsEffectPrivate &d, QObject *parent = 0);
- virtual void draw(QPainter *painter) = 0;
- virtual void sourceChanged(ChangeFlags flags);
- void updateBoundingRect();
-
- bool sourceIsPixmap() const;
- QRectF sourceBoundingRect(Qt::CoordinateSystem system = Qt::LogicalCoordinates) const;
- void drawSource(QPainter *painter);
- QPixmap sourcePixmap(Qt::CoordinateSystem system = Qt::LogicalCoordinates,
- QPoint *offset = 0,
- PixmapPadMode mode = PadToEffectiveBoundingRect) const;
-
-private:
- Q_DECLARE_PRIVATE(QGraphicsEffect)
- Q_DISABLE_COPY(QGraphicsEffect)
- friend class QGraphicsItem;
- friend class QGraphicsItemPrivate;
- friend class QGraphicsScenePrivate;
- friend class QWidget;
- friend class QWidgetPrivate;
-
-public:
- QGraphicsEffectSource *source() const; // internal
-
-};
-Q_DECLARE_OPERATORS_FOR_FLAGS(QGraphicsEffect::ChangeFlags)
-
-class QGraphicsColorizeEffectPrivate;
-class Q_GUI_EXPORT QGraphicsColorizeEffect: public QGraphicsEffect
-{
- Q_OBJECT
- Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
- Q_PROPERTY(qreal strength READ strength WRITE setStrength NOTIFY strengthChanged)
-public:
- QGraphicsColorizeEffect(QObject *parent = 0);
- ~QGraphicsColorizeEffect();
-
- QColor color() const;
- qreal strength() const;
-
-public Q_SLOTS:
- void setColor(const QColor &c);
- void setStrength(qreal strength);
-
-Q_SIGNALS:
- void colorChanged(const QColor &color);
- void strengthChanged(qreal strength);
-
-protected:
- void draw(QPainter *painter);
-
-private:
- Q_DECLARE_PRIVATE(QGraphicsColorizeEffect)
- Q_DISABLE_COPY(QGraphicsColorizeEffect)
-};
-
-class QGraphicsBlurEffectPrivate;
-class Q_GUI_EXPORT QGraphicsBlurEffect: public QGraphicsEffect
-{
- Q_OBJECT
- Q_FLAGS(BlurHint BlurHints)
- Q_PROPERTY(qreal blurRadius READ blurRadius WRITE setBlurRadius NOTIFY blurRadiusChanged)
- Q_PROPERTY(BlurHints blurHints READ blurHints WRITE setBlurHints NOTIFY blurHintsChanged)
-public:
- enum BlurHint {
- PerformanceHint = 0x00,
- QualityHint = 0x01,
- AnimationHint = 0x02
- };
- Q_DECLARE_FLAGS(BlurHints, BlurHint)
-
- QGraphicsBlurEffect(QObject *parent = 0);
- ~QGraphicsBlurEffect();
-
- QRectF boundingRectFor(const QRectF &rect) const;
- qreal blurRadius() const;
- BlurHints blurHints() const;
-
-public Q_SLOTS:
- void setBlurRadius(qreal blurRadius);
- void setBlurHints(BlurHints hints);
-
-Q_SIGNALS:
- void blurRadiusChanged(qreal blurRadius);
- void blurHintsChanged(BlurHints hints);
-
-protected:
- void draw(QPainter *painter);
-
-private:
- Q_DECLARE_PRIVATE(QGraphicsBlurEffect)
- Q_DISABLE_COPY(QGraphicsBlurEffect)
-};
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QGraphicsBlurEffect::BlurHints)
-
-class QGraphicsDropShadowEffectPrivate;
-class Q_GUI_EXPORT QGraphicsDropShadowEffect: public QGraphicsEffect
-{
- Q_OBJECT
- Q_PROPERTY(QPointF offset READ offset WRITE setOffset NOTIFY offsetChanged)
- Q_PROPERTY(qreal xOffset READ xOffset WRITE setXOffset NOTIFY offsetChanged)
- Q_PROPERTY(qreal yOffset READ yOffset WRITE setYOffset NOTIFY offsetChanged)
- Q_PROPERTY(qreal blurRadius READ blurRadius WRITE setBlurRadius NOTIFY blurRadiusChanged)
- Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
-public:
- QGraphicsDropShadowEffect(QObject *parent = 0);
- ~QGraphicsDropShadowEffect();
-
- QRectF boundingRectFor(const QRectF &rect) const;
- QPointF offset() const;
-
- inline qreal xOffset() const
- { return offset().x(); }
-
- inline qreal yOffset() const
- { return offset().y(); }
-
- qreal blurRadius() const;
- QColor color() const;
-
-public Q_SLOTS:
- void setOffset(const QPointF &ofs);
-
- inline void setOffset(qreal dx, qreal dy)
- { setOffset(QPointF(dx, dy)); }
-
- inline void setOffset(qreal d)
- { setOffset(QPointF(d, d)); }
-
- inline void setXOffset(qreal dx)
- { setOffset(QPointF(dx, yOffset())); }
-
- inline void setYOffset(qreal dy)
- { setOffset(QPointF(xOffset(), dy)); }
-
- void setBlurRadius(qreal blurRadius);
- void setColor(const QColor &color);
-
-Q_SIGNALS:
- void offsetChanged(const QPointF &offset);
- void blurRadiusChanged(qreal blurRadius);
- void colorChanged(const QColor &color);
-
-protected:
- void draw(QPainter *painter);
-
-private:
- Q_DECLARE_PRIVATE(QGraphicsDropShadowEffect)
- Q_DISABLE_COPY(QGraphicsDropShadowEffect)
-};
-
-class QGraphicsOpacityEffectPrivate;
-class Q_GUI_EXPORT QGraphicsOpacityEffect: public QGraphicsEffect
-{
- Q_OBJECT
- Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity NOTIFY opacityChanged)
- Q_PROPERTY(QBrush opacityMask READ opacityMask WRITE setOpacityMask NOTIFY opacityMaskChanged)
-public:
- QGraphicsOpacityEffect(QObject *parent = 0);
- ~QGraphicsOpacityEffect();
-
- qreal opacity() const;
- QBrush opacityMask() const;
-
-public Q_SLOTS:
- void setOpacity(qreal opacity);
- void setOpacityMask(const QBrush &mask);
-
-Q_SIGNALS:
- void opacityChanged(qreal opacity);
- void opacityMaskChanged(const QBrush &mask);
-
-protected:
- void draw(QPainter *painter);
-
-private:
- Q_DECLARE_PRIVATE(QGraphicsOpacityEffect)
- Q_DISABLE_COPY(QGraphicsOpacityEffect)
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-#endif //QT_NO_GRAPHICSEFFECT
-
-#endif // QGRAPHICSEFFECT_H
-
diff --git a/src/gui/effects/qgraphicseffect_p.h b/src/gui/effects/qgraphicseffect_p.h
deleted file mode 100644
index 6a94db005e..0000000000
--- a/src/gui/effects/qgraphicseffect_p.h
+++ /dev/null
@@ -1,231 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGRAPHICSEFFECT_P_H
-#define QGRAPHICSEFFECT_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header
-// file may change from version to version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qgraphicseffect.h"
-
-#include <QPixmapCache>
-
-#include <private/qobject_p.h>
-#include <private/qpixmapfilter_p.h>
-
-#ifndef QT_NO_GRAPHICSEFFECT
-QT_BEGIN_NAMESPACE
-
-class QGraphicsEffectSourcePrivate;
-class Q_GUI_EXPORT QGraphicsEffectSource : public QObject
-{
- Q_OBJECT
-public:
- ~QGraphicsEffectSource();
- const QGraphicsItem *graphicsItem() const;
- const QWidget *widget() const;
- const QStyleOption *styleOption() const;
-
- bool isPixmap() const;
- void draw(QPainter *painter);
- void update();
-
- QRectF boundingRect(Qt::CoordinateSystem coordinateSystem = Qt::LogicalCoordinates) const;
- QRect deviceRect() const;
- QPixmap pixmap(Qt::CoordinateSystem system = Qt::LogicalCoordinates,
- QPoint *offset = 0,
- QGraphicsEffect::PixmapPadMode mode = QGraphicsEffect::PadToEffectiveBoundingRect) const;
-
-protected:
- QGraphicsEffectSource(QGraphicsEffectSourcePrivate &dd, QObject *parent = 0);
-
-private:
- Q_DECLARE_PRIVATE(QGraphicsEffectSource)
- Q_DISABLE_COPY(QGraphicsEffectSource)
- friend class QGraphicsEffect;
- friend class QGraphicsEffectPrivate;
- friend class QGraphicsScenePrivate;
- friend class QGraphicsItem;
- friend class QGraphicsItemPrivate;
- friend class QWidget;
- friend class QWidgetPrivate;
-};
-
-class QGraphicsEffectSourcePrivate : public QObjectPrivate
-{
- Q_DECLARE_PUBLIC(QGraphicsEffectSource)
-public:
- QGraphicsEffectSourcePrivate()
- : QObjectPrivate()
- , m_cachedSystem(Qt::DeviceCoordinates)
- , m_cachedMode(QGraphicsEffect::PadToTransparentBorder)
- {}
-
- enum InvalidateReason
- {
- TransformChanged,
- EffectRectChanged,
- SourceChanged
- };
-
- virtual ~QGraphicsEffectSourcePrivate();
- virtual void detach() = 0;
- virtual QRectF boundingRect(Qt::CoordinateSystem system) const = 0;
- virtual QRect deviceRect() const = 0;
- virtual const QGraphicsItem *graphicsItem() const = 0;
- virtual const QWidget *widget() const = 0;
- virtual const QStyleOption *styleOption() const = 0;
- virtual void draw(QPainter *p) = 0;
- virtual void update() = 0;
- virtual bool isPixmap() const = 0;
- virtual QPixmap pixmap(Qt::CoordinateSystem system, QPoint *offset = 0,
- QGraphicsEffect::PixmapPadMode mode = QGraphicsEffect::PadToTransparentBorder) const = 0;
- virtual void effectBoundingRectChanged() = 0;
-
- void setCachedOffset(const QPoint &offset);
- void invalidateCache(InvalidateReason reason = SourceChanged) const;
- Qt::CoordinateSystem currentCachedSystem() const { return m_cachedSystem; }
- QGraphicsEffect::PixmapPadMode currentCachedMode() const { return m_cachedMode; }
-
- friend class QGraphicsScenePrivate;
- friend class QGraphicsItem;
- friend class QGraphicsItemPrivate;
-
-private:
- mutable Qt::CoordinateSystem m_cachedSystem;
- mutable QGraphicsEffect::PixmapPadMode m_cachedMode;
- mutable QPoint m_cachedOffset;
- mutable QPixmapCache::Key m_cacheKey;
-};
-
-class Q_GUI_EXPORT QGraphicsEffectPrivate : public QObjectPrivate
-{
- Q_DECLARE_PUBLIC(QGraphicsEffect)
-public:
- QGraphicsEffectPrivate() : source(0), isEnabled(1) {}
-
- inline void setGraphicsEffectSource(QGraphicsEffectSource *newSource)
- {
- QGraphicsEffect::ChangeFlags flags;
- if (source) {
- flags |= QGraphicsEffect::SourceDetached;
- source->d_func()->invalidateCache();
- source->d_func()->detach();
- delete source;
- }
- source = newSource;
- if (newSource)
- flags |= QGraphicsEffect::SourceAttached;
- q_func()->sourceChanged(flags);
- }
-
- QGraphicsEffectSource *source;
- QRectF boundingRect;
- quint32 isEnabled : 1;
- quint32 padding : 31; // feel free to use
-};
-
-
-class QGraphicsColorizeEffectPrivate : public QGraphicsEffectPrivate
-{
- Q_DECLARE_PUBLIC(QGraphicsColorizeEffect)
-public:
- QGraphicsColorizeEffectPrivate()
- : opaque(true)
- {
- filter = new QPixmapColorizeFilter;
- }
- ~QGraphicsColorizeEffectPrivate() { delete filter; }
-
- QPixmapColorizeFilter *filter;
- quint32 opaque : 1;
- quint32 padding : 31;
-};
-
-class QGraphicsBlurEffectPrivate : public QGraphicsEffectPrivate
-{
- Q_DECLARE_PUBLIC(QGraphicsBlurEffect)
-public:
- QGraphicsBlurEffectPrivate() : filter(new QPixmapBlurFilter) {}
- ~QGraphicsBlurEffectPrivate() { delete filter; }
-
- QPixmapBlurFilter *filter;
-};
-
-class QGraphicsDropShadowEffectPrivate : public QGraphicsEffectPrivate
-{
- Q_DECLARE_PUBLIC(QGraphicsDropShadowEffect)
-public:
- QGraphicsDropShadowEffectPrivate() : filter(new QPixmapDropShadowFilter) {}
- ~QGraphicsDropShadowEffectPrivate() { delete filter; }
-
- QPixmapDropShadowFilter *filter;
-};
-
-class QGraphicsOpacityEffectPrivate : public QGraphicsEffectPrivate
-{
- Q_DECLARE_PUBLIC(QGraphicsOpacityEffect)
-public:
- QGraphicsOpacityEffectPrivate()
- : opacity(qreal(0.7)), isFullyTransparent(0), isFullyOpaque(0), hasOpacityMask(0) {}
- ~QGraphicsOpacityEffectPrivate() {}
-
- qreal opacity;
- QBrush opacityMask;
- uint isFullyTransparent : 1;
- uint isFullyOpaque : 1;
- uint hasOpacityMask : 1;
-};
-
-QT_END_NAMESPACE
-
-#endif //QT_NO_GRAPHICSEFFECT
-#endif // QGRAPHICSEFFECT_P_H
-
diff --git a/src/gui/egl/egl.pri b/src/gui/egl/egl.pri
index 8e8664c679..ec23da3312 100644
--- a/src/gui/egl/egl.pri
+++ b/src/gui/egl/egl.pri
@@ -25,19 +25,15 @@ contains(QT_CONFIG, egl): {
wince*: SOURCES += egl/qegl_wince.cpp
unix {
- embedded {
- SOURCES += egl/qegl_qws.cpp
- } else {
- qpa {
- SOURCES += egl/qegl_qpa.cpp
- } else {
- symbian {
- SOURCES += egl/qegl_symbian.cpp
- } else {
- SOURCES += egl/qegl_x11.cpp
- }
- }
- }
+ qpa {
+ SOURCES += egl/qegl_qpa.cpp
+ } else {
+ symbian {
+ SOURCES += egl/qegl_symbian.cpp
+ } else {
+ SOURCES += egl/qegl_x11.cpp
+ }
+ }
}
} else:symbian {
DEFINES += QT_NO_EGL
diff --git a/src/gui/egl/qegl_p.h b/src/gui/egl/qegl_p.h
index 9b0d82e69f..e0c02aa150 100644
--- a/src/gui/egl/qegl_p.h
+++ b/src/gui/egl/qegl_p.h
@@ -47,7 +47,7 @@
// -------------
//
// This file is not part of the Qt API. It exists for the convenience of
-// the QtOpenGL and QtOpenVG modules. This header file may change from
+// the QtGui and QtOpenVG modules. This header file may change from
// version to version without notice, or even be removed.
//
// We mean it.
diff --git a/src/gui/egl/qegl_qpa.cpp b/src/gui/egl/qegl_qpa.cpp
index 9b99e8b94a..c3eb044b22 100644
--- a/src/gui/egl/qegl_qpa.cpp
+++ b/src/gui/egl/qegl_qpa.cpp
@@ -46,7 +46,6 @@
#if !defined(QT_NO_EGL)
-#include <QtGui/private/qgraphicssystem_p.h>
#include <QtGui/private/qapplication_p.h>
#include <QtGui/qdesktopwidget.h>
@@ -75,7 +74,7 @@ EGLNativePixmapType QEgl::nativePixmap(QPixmap* pixmap)
static QPlatformScreen *screenForDevice(QPaintDevice *device)
{
- QPlatformIntegration *pi = QApplicationPrivate::platformIntegration();
+ QPlatformIntegration *pi = QGuiApplicationPrivate::platformIntegration();
QList<QPlatformScreen *> screens = pi->screens();
@@ -95,7 +94,7 @@ void QEglProperties::setPaintDeviceFormat(QPaintDevice *dev)
if (!dev)
return;
- // Find the QGLScreen for this paint device.
+ // Find the QOpenGLScreen for this paint device.
QPlatformScreen *screen = screenForDevice(dev);
if (!screen)
return;
diff --git a/src/gui/egl/qegl_qws.cpp b/src/gui/egl/qegl_qws.cpp
deleted file mode 100644
index b39f4dc521..0000000000
--- a/src/gui/egl/qegl_qws.cpp
+++ /dev/null
@@ -1,114 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtGui/qpaintdevice.h>
-#include <QtGui/qpixmap.h>
-#include <QtGui/qwidget.h>
-
-#include "qegl_p.h"
-#include "qeglcontext_p.h"
-
-#if !defined(QT_NO_EGL)
-
-#include <qscreen_qws.h>
-#include <qscreenproxy_qws.h>
-#include <qapplication.h>
-#include <qdesktopwidget.h>
-
-QT_BEGIN_NAMESPACE
-
-static QScreen *screenForDevice(QPaintDevice *device)
-{
- QScreen *screen = qt_screen;
- if (!screen)
- return 0;
- if (screen->classId() == QScreen::MultiClass) {
- int screenNumber;
- if (device && device->devType() == QInternal::Widget)
- screenNumber = qApp->desktop()->screenNumber(static_cast<QWidget *>(device));
- else
- screenNumber = 0;
- screen = screen->subScreens()[screenNumber];
- }
- while (screen->classId() == QScreen::ProxyClass ||
- screen->classId() == QScreen::TransformedClass) {
- screen = static_cast<QProxyScreen *>(screen)->screen();
- }
- return screen;
-}
-
-// Set pixel format and other properties based on a paint device.
-void QEglProperties::setPaintDeviceFormat(QPaintDevice *dev)
-{
- if (!dev)
- return;
-
- // Find the QGLScreen for this paint device.
- QScreen *screen = screenForDevice(dev);
- if (!screen)
- return;
- int devType = dev->devType();
- if (devType == QInternal::Image)
- setPixelFormat(static_cast<QImage *>(dev)->format());
- else
- setPixelFormat(screen->pixelFormat());
-}
-
-EGLNativeDisplayType QEgl::nativeDisplay()
-{
- return EGLNativeDisplayType(EGL_DEFAULT_DISPLAY);
-}
-
-EGLNativeWindowType QEgl::nativeWindow(QWidget* widget)
-{
- return (EGLNativeWindowType)(widget->winId()); // Might work
-}
-
-EGLNativePixmapType QEgl::nativePixmap(QPixmap*)
-{
- qWarning("QEgl: EGL pixmap surfaces not supported on QWS");
- return (EGLNativePixmapType)0;
-}
-
-
-QT_END_NAMESPACE
-
-#endif // !QT_NO_EGL
diff --git a/src/gui/egl/qegl_x11.cpp b/src/gui/egl/qegl_x11.cpp
index c0f8a240fb..4fd8a15157 100644
--- a/src/gui/egl/qegl_x11.cpp
+++ b/src/gui/egl/qegl_x11.cpp
@@ -43,7 +43,7 @@
#include <QtGui/private/qt_x11_p.h>
#include <QtGui/qx11info_x11.h>
-#include <QtGui/private/qpixmapdata_p.h>
+#include <QtGui/qplatformpixmap_qpa.h>
#include <QtGui/private/qpixmap_x11_p.h>
#include <QtGui/private/qimagepixmapcleanuphooks_p.h>
@@ -339,14 +339,14 @@ EGLSurface QEgl::createSurface(QPaintDevice *device, EGLConfig config, const QEg
return EGL_NO_SURFACE;
}
- QX11PixmapData *x11PixmapData = 0;
+ QX11PlatformPixmap *x11PlatformPixmap = 0;
if (devType == QInternal::Pixmap) {
- QPixmapData *pmd = static_cast<QPixmap*>(device)->data_ptr().data();
- if (pmd->classId() == QPixmapData::X11Class)
- x11PixmapData = static_cast<QX11PixmapData*>(pmd);
+ QPlatformPixmap *pmd = static_cast<QPixmap*>(device)->data_ptr().data();
+ if (pmd->classId() == QPlatformPixmap::X11Class)
+ x11PlatformPixmap = static_cast<QX11PlatformPixmap*>(pmd);
else {
- // TODO: Replace the pixmap's data with a new QX11PixmapData
- qWarning("WARNING: Creating an EGL surface on a QPixmap is only supported for QX11PixmapData");
+ // TODO: Replace the pixmap's data with a new QX11PlatformPixmap
+ qWarning("WARNING: Creating an EGL surface on a QPixmap is only supported for QX11PlatformPixmap");
return EGL_NO_SURFACE;
}
} else if ((devType != QInternal::Widget) && (devType != QInternal::Pbuffer)) {
@@ -426,11 +426,11 @@ EGLSurface QEgl::createSurface(QPaintDevice *device, EGLConfig config, const QEg
return surf;
}
- if (x11PixmapData) {
+ if (x11PlatformPixmap) {
// X11 Pixmaps are only created with a depth, so that's all we need to check
EGLint configDepth;
eglGetConfigAttrib(QEgl::display(), config, EGL_BUFFER_SIZE , &configDepth);
- if (x11PixmapData->depth() != configDepth) {
+ if (x11PlatformPixmap->depth() != configDepth) {
// The bit depths are wrong which means the EGLConfig isn't compatable with
// this pixmap. So we need to replace the pixmap's existing data with a new
// one which is created with the correct depth:
@@ -438,13 +438,13 @@ EGLSurface QEgl::createSurface(QPaintDevice *device, EGLConfig config, const QEg
#ifndef QT_NO_XRENDER
if (configDepth == 32) {
qWarning("Warning: EGLConfig's depth (32) != pixmap's depth (%d), converting to ARGB32",
- x11PixmapData->depth());
- x11PixmapData->convertToARGB32(true);
+ x11PlatformPixmap->depth());
+ x11PlatformPixmap->convertToARGB32(true);
} else
#endif
{
qWarning("Warning: EGLConfig's depth (%d) != pixmap's depth (%d)",
- configDepth, x11PixmapData->depth());
+ configDepth, x11PlatformPixmap->depth());
}
}
@@ -458,10 +458,10 @@ EGLSurface QEgl::createSurface(QPaintDevice *device, EGLConfig config, const QEg
surfaceAttribs.setValue(EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGB);
EGLSurface surf = eglCreatePixmapSurface(QEgl::display(), config,
- (EGLNativePixmapType) x11PixmapData->handle(),
+ (EGLNativePixmapType) x11PlatformPixmap->handle(),
surfaceAttribs.properties());
- x11PixmapData->gl_surface = (void*)surf;
- QImagePixmapCleanupHooks::enableCleanupHooks(x11PixmapData);
+ x11PlatformPixmap->gl_surface = (void*)surf;
+ QImagePixmapCleanupHooks::enableCleanupHooks(x11PlatformPixmap);
return surf;
}
diff --git a/src/gui/egl/qeglcontext_p.h b/src/gui/egl/qeglcontext_p.h
index 6cd76b386c..7ea18627d1 100644
--- a/src/gui/egl/qeglcontext_p.h
+++ b/src/gui/egl/qeglcontext_p.h
@@ -47,7 +47,7 @@
// -------------
//
// This file is not part of the Qt API. It exists for the convenience of
-// the QtOpenGL and QtOpenVG modules. This header file may change from
+// the QtGui and QtOpenVG modules. This header file may change from
// version to version without notice, or even be removed.
//
// We mean it.
@@ -109,7 +109,7 @@ private:
static void setCurrentContext(QEgl::API api, QEglContext *context);
friend class QMeeGoGraphicsSystem;
- friend class QMeeGoPixmapData;
+ friend class QMeeGoPlatformPixmap;
};
QT_END_NAMESPACE
diff --git a/src/gui/egl/qeglproperties_p.h b/src/gui/egl/qeglproperties_p.h
index 2d03cd0494..d8d64e01a1 100644
--- a/src/gui/egl/qeglproperties_p.h
+++ b/src/gui/egl/qeglproperties_p.h
@@ -47,7 +47,7 @@
// -------------
//
// This file is not part of the Qt API. It exists for the convenience
-// of the QtOpenGL and QtOpenVG modules. This header file may change from
+// of the QtGui and QtOpenVG modules. This header file may change from
// version to version without notice, or even be removed.
//
// We mean it.
diff --git a/src/gui/embedded/directfb.pri b/src/gui/embedded/directfb.pri
deleted file mode 100644
index 75d693e0b4..0000000000
--- a/src/gui/embedded/directfb.pri
+++ /dev/null
@@ -1,40 +0,0 @@
-# These defines might be necessary if your DirectFB driver doesn't
-# support all of the DirectFB API.
-#
-#DEFINES += QT_DIRECTFB_SUBSURFACE
-#DEFINES += QT_DIRECTFB_WINDOW_AS_CURSOR
-#DEFINES += QT_NO_DIRECTFB_IMAGEPROVIDER
-#DEFINES += QT_DIRECTFB_IMAGEPROVIDER_KEEPALIVE
-#DEFINES += QT_DIRECTFB_IMAGECACHE
-#DEFINES += QT_NO_DIRECTFB_WM
-#DEFINES += QT_NO_DIRECTFB_LAYER
-#DEFINES += QT_DIRECTFB_PALETTE
-#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
-#DEFINES += QT_NO_DIRECTFB_STRETCHBLIT
-DIRECTFB_DRAWINGOPERATIONS=DRAW_RECTS|DRAW_LINES|DRAW_IMAGE|DRAW_PIXMAP|DRAW_TILED_PIXMAP|STROKE_PATH|DRAW_PATH|DRAW_POINTS|DRAW_ELLIPSE|DRAW_POLYGON|DRAW_TEXT|FILL_PATH|FILL_RECT|DRAW_COLORSPANS|DRAW_ROUNDED_RECT|DRAW_STATICTEXT
-#DEFINES += \"QT_DIRECTFB_WARN_ON_RASTERFALLBACKS=$$DIRECTFB_DRAWINGOPERATIONS\"
-#DEFINES += \"QT_DIRECTFB_DISABLE_RASTERFALLBACKS=$$DIRECTFB_DRAWINGOPERATIONS\"
-
-HEADERS += $$QT_SOURCE_TREE/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h \
- $$QT_SOURCE_TREE/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h \
- $$QT_SOURCE_TREE/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.h \
- $$QT_SOURCE_TREE/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h \
- $$QT_SOURCE_TREE/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h \
- $$QT_SOURCE_TREE/src/plugins/gfxdrivers/directfb/qdirectfbkeyboard.h \
- $$QT_SOURCE_TREE/src/plugins/gfxdrivers/directfb/qdirectfbmouse.h
-
-SOURCES += $$QT_SOURCE_TREE/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp \
- $$QT_SOURCE_TREE/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp \
- $$QT_SOURCE_TREE/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp \
- $$QT_SOURCE_TREE/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp \
- $$QT_SOURCE_TREE/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp \
- $$QT_SOURCE_TREE/src/plugins/gfxdrivers/directfb/qdirectfbkeyboard.cpp \
- $$QT_SOURCE_TREE/src/plugins/gfxdrivers/directfb/qdirectfbmouse.cpp
-
-
-QMAKE_CXXFLAGS += $$QT_CFLAGS_DIRECTFB
-LIBS += $$QT_LIBS_DIRECTFB
diff --git a/src/gui/embedded/embedded.pri b/src/gui/embedded/embedded.pri
deleted file mode 100644
index 31f0bc6d50..0000000000
--- a/src/gui/embedded/embedded.pri
+++ /dev/null
@@ -1,226 +0,0 @@
-# Qt for Embedded Linux
-
-embedded {
- CONFIG -= opengl x11
- LIBS -= -dl
- KERNEL_P = kernel
-
- !mac:HEADERS += embedded/qsoundqss_qws.h
- HEADERS += \
- embedded/qcopchannel_qws.h \
- embedded/qdecoration_qws.h \
- embedded/qdecorationfactory_qws.h \
- embedded/qdecorationplugin_qws.h \
- embedded/qdirectpainter_qws.h \
- embedded/qlock_p.h \
- embedded/qscreen_qws.h \
- embedded/qscreenmulti_qws_p.h \
- embedded/qscreenproxy_qws.h \
- embedded/qwindowsystem_qws.h \
- embedded/qwindowsystem_p.h \
- embedded/qwscommand_qws_p.h \
- embedded/qwscursor_qws.h \
- embedded/qwsdisplay_qws.h \
- embedded/qwsdisplay_qws_p.h \
- embedded/qwsevent_qws.h \
- embedded/qwsmanager_qws.h \
- embedded/qwsmanager_p.h \
- embedded/qwsproperty_qws.h \
- embedded/qwsprotocolitem_qws.h \
- embedded/qtransportauth_qws.h \
- embedded/qtransportauth_qws_p.h \
- embedded/qtransportauthdefs_qws.h \
- embedded/qwssocket_qws.h \
- embedded/qwslock_p.h \
- embedded/qwsutils_qws.h \
- embedded/qwssharedmemory_p.h \
- embedded/qwssignalhandler_p.h \
- embedded/qwsembedwidget.h
-
- !mac:SOURCES += embedded/qsoundqss_qws.cpp
- SOURCES += \
- embedded/qcopchannel_qws.cpp \
- embedded/qdecoration_qws.cpp \
- embedded/qdecorationfactory_qws.cpp \
- embedded/qdecorationplugin_qws.cpp \
- embedded/qdirectpainter_qws.cpp \
- embedded/qlock.cpp \
- embedded/qscreen_qws.cpp \
- embedded/qscreenmulti_qws.cpp \
- embedded/qscreenproxy_qws.cpp \
- embedded/qwindowsystem_qws.cpp \
- embedded/qwscommand_qws.cpp \
- embedded/qwscursor_qws.cpp \
- embedded/qwsevent_qws.cpp \
- embedded/qwsmanager_qws.cpp \
- embedded/qwsproperty_qws.cpp \
- embedded/qtransportauth_qws.cpp \
- embedded/qwslock.cpp \
- embedded/qwssharedmemory.cpp \
- embedded/qwssocket_qws.cpp \
- embedded/qwssignalhandler.cpp \
- embedded/qwsembedwidget.cpp
-
- contains(QT_CONFIG,sxe)|contains(QT_CONFIG,qtopia) {
- SOURCES += embedded/qunixsocket.cpp embedded/qunixsocketserver.cpp
- HEADERS += embedded/qunixsocket_p.h embedded/qunixsocketserver_p.h
- }
-
-#
-# Decorations
-#
- contains( decorations, default ) {
- HEADERS += embedded/qdecorationdefault_qws.h
- SOURCES += embedded/qdecorationdefault_qws.cpp
- }
- contains( decorations, styled ) {
- HEADERS += embedded/qdecorationstyled_qws.h
- SOURCES += embedded/qdecorationstyled_qws.cpp
- }
-
- contains( decorations, windows ) {
- HEADERS += embedded/qdecorationwindows_qws.h
- SOURCES += embedded/qdecorationwindows_qws.cpp
- }
-
-#
-# Qt for Embedded Linux Drivers
-#
- HEADERS += embedded/qscreendriverplugin_qws.h \
- embedded/qscreendriverfactory_qws.h \
- embedded/qkbd_qws.h \
- embedded/qkbd_qws_p.h \
- embedded/qkbd_defaultmap_qws_p.h \
- embedded/qkbddriverplugin_qws.h \
- embedded/qkbddriverfactory_qws.h \
- embedded/qmouse_qws.h \
- embedded/qmousedriverplugin_qws.h \
- embedded/qmousedriverfactory_qws.h
-
- SOURCES += embedded/qscreendriverplugin_qws.cpp \
- embedded/qscreendriverfactory_qws.cpp \
- embedded/qkbd_qws.cpp \
- embedded/qkbddriverplugin_qws.cpp \
- embedded/qkbddriverfactory_qws.cpp \
- embedded/qmouse_qws.cpp \
- embedded/qmousedriverplugin_qws.cpp \
- embedded/qmousedriverfactory_qws.cpp
-
-#
-# Graphics drivers
-#
- contains( gfx-drivers, linuxfb ) {
- HEADERS += embedded/qscreenlinuxfb_qws.h
- SOURCES += embedded/qscreenlinuxfb_qws.cpp
- }
-
- contains( gfx-drivers, qnx ) {
- HEADERS += embedded/qscreenqnx_qws.h
- SOURCES += embedded/qscreenqnx_qws.cpp
- LIBS += -lgf
- }
-
- contains( gfx-drivers, integrityfb ) {
- HEADERS += embedded/qscreenintegrityfb_qws.h
- SOURCES += embedded/qscreenintegrityfb_qws.cpp
- LIBS += -lfbdev
- }
-
- contains( gfx-drivers, qvfb ) {
- HEADERS += embedded/qscreenvfb_qws.h
- SOURCES += embedded/qscreenvfb_qws.cpp
- }
-
-
- contains( gfx-drivers, vnc ) {
- VNCDIR = $$QT_SOURCE_TREE/src/plugins/gfxdrivers/vnc
- INCLUDEPATH += $$VNCDIR
- HEADERS += $$VNCDIR/qscreenvnc_qws.h \
- $$VNCDIR/qscreenvnc_p.h
- SOURCES += $$VNCDIR/qscreenvnc_qws.cpp
- }
-
- contains( gfx-drivers, transformed ) {
- HEADERS += embedded/qscreentransformed_qws.h
- SOURCES += embedded/qscreentransformed_qws.cpp
- }
-
- contains( gfx-drivers, directfb ) {
- INCLUDEPATH += $$QT_SOURCE_TREE/src/plugins/gfxdrivers/directfb
- include($$PWD/directfb.pri)
- }
-#
-# Keyboard drivers
-#
- contains( kbd-drivers, qvfb ) {
- HEADERS +=embedded/qkbdvfb_qws.h
- SOURCES +=embedded/qkbdvfb_qws.cpp
- !contains( kbd-drivers, qvfb ) {
- kbd-drivers += qvfb
- }
- }
-
- contains( kbd-drivers, tty ) {
- HEADERS +=embedded/qkbdtty_qws.h
- SOURCES +=embedded/qkbdtty_qws.cpp
- }
-
- contains( kbd-drivers, linuxinput ) {
- HEADERS +=embedded/qkbdlinuxinput_qws.h
- SOURCES +=embedded/qkbdlinuxinput_qws.cpp
- }
-
- contains( kbd-drivers, um ) {
- HEADERS +=embedded/qkbdum_qws.h
- SOURCES +=embedded/qkbdum_qws.cpp
- }
-
- contains( kbd-drivers, qnx ) {
- HEADERS += embedded/qkbdqnx_qws.h
- SOURCES += embedded/qkbdqnx_qws.cpp
- }
-
- contains( kbd-drivers, integrity ) {
- HEADERS += embedded/qkbdintegrity_qws.h
- SOURCES += embedded/qkbdintegrity_qws.cpp
- }
-
-#
-# Mouse drivers
-#
- contains( mouse-drivers, qvfb ) {
- HEADERS +=embedded/qmousevfb_qws.h
- SOURCES +=embedded/qmousevfb_qws.cpp
- }
-
- contains( mouse-drivers, pc ) {
- HEADERS +=embedded/qmousepc_qws.h
- SOURCES +=embedded/qmousepc_qws.cpp
- }
-
- contains( mouse-drivers, linuxtp ) {
- HEADERS +=embedded/qmouselinuxtp_qws.h
- SOURCES +=embedded/qmouselinuxtp_qws.cpp
- }
-
- contains( mouse-drivers, tslib ) {
- LIBS_PRIVATE += -lts
- HEADERS +=embedded/qmousetslib_qws.h
- SOURCES +=embedded/qmousetslib_qws.cpp
- }
-
- contains( mouse-drivers, linuxinput ) {
- HEADERS +=embedded/qmouselinuxinput_qws.h
- SOURCES +=embedded/qmouselinuxinput_qws.cpp
- }
-
- contains( mouse-drivers, qnx ) {
- HEADERS += embedded/qmouseqnx_qws.h
- SOURCES += embedded/qmouseqnx_qws.cpp
- }
-
- contains( mouse-drivers, integrity ) {
- HEADERS += embedded/qmouseintegrity_qws.h
- SOURCES += embedded/qmouseintegrity_qws.cpp
- }
-}
diff --git a/src/gui/embedded/qcopchannel_qws.cpp b/src/gui/embedded/qcopchannel_qws.cpp
deleted file mode 100644
index abcedeb62a..0000000000
--- a/src/gui/embedded/qcopchannel_qws.cpp
+++ /dev/null
@@ -1,608 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qcopchannel_qws.h"
-
-#ifndef QT_NO_COP
-
-#include "qwsdisplay_qws.h"
-#include "qwscommand_qws_p.h"
-#include "qwindowsystem_qws.h"
-#include "qwindowsystem_p.h"
-#include "qlist.h"
-#include "qmap.h"
-#include "qdatastream.h"
-#include "qpointer.h"
-#include "qmutex.h"
-
-#include "qdebug.h"
-
-QT_BEGIN_NAMESPACE
-
-typedef QMap<QString, QList<QWSClient*> > QCopServerMap;
-static QCopServerMap *qcopServerMap = 0;
-
-class QCopServerRegexp
-{
-public:
- QCopServerRegexp( const QString& channel, QWSClient *client );
- QCopServerRegexp( const QCopServerRegexp& other );
-
- QString channel;
- QWSClient *client;
- QRegExp regexp;
-};
-
-QCopServerRegexp::QCopServerRegexp( const QString& channel, QWSClient *client )
-{
- this->channel = channel;
- this->client = client;
- this->regexp = QRegExp( channel, Qt::CaseSensitive, QRegExp::Wildcard );
-}
-
-QCopServerRegexp::QCopServerRegexp( const QCopServerRegexp& other )
-{
- channel = other.channel;
- client = other.client;
- regexp = other.regexp;
-}
-
-typedef QList<QCopServerRegexp> QCopServerRegexpList;
-static QCopServerRegexpList *qcopServerRegexpList = 0;
-
-typedef QMap<QString, QList< QPointer<QCopChannel> > > QCopClientMap;
-static QCopClientMap *qcopClientMap = 0;
-
-Q_GLOBAL_STATIC(QMutex, qcopClientMapMutex)
-
-// Determine if a channel name contains wildcard characters.
-static bool containsWildcards( const QString& channel )
-{
- return channel.contains(QLatin1Char('*'));
-}
-
-class QCopChannelPrivate
-{
-public:
- QString channel;
-};
-
-/*!
- \class QCopChannel
- \ingroup qws
-
- \brief The QCopChannel class provides communication capabilities
- between clients in \l{Qt for Embedded Linux}.
-
- Note that this class is only available in \l{Qt for Embedded Linux}.
-
- The Qt COmmunication Protocol (QCOP) is a many-to-many protocol
- for transferring messages across registered channels. A channel is
- registered by name, and anyone who wants to can listen to the
- channel as well as send messages through it. The QCOP protocol
- allows clients to communicate both within the same address space
- and between different processes.
-
- To send messages to a given channel, QCopChannel provides the
- static send() function. Using this function alone, the messages
- are queued until Qt re-enters the event loop. To immediately flush
- all queued messages to the registered listeners, call the static
- flush() function.
-
- To listen to the traffic on a given channel, you typically
- instantiate a QCopChannel object for the given channel and connect
- to its received() signal that is emitted whenever there is
- incoming data. Use the static isRegistered() function to query
- the server for the existence of a given channel. QCopChannel
- provides the channel() function returning the name of this
- QCopChannel object's channel.
-
- In additon, QCopChannel provides the virtual receive() function
- that can be reimplemented to filter the incoming messages and
- data. The default implementation simply emits the received()
- signal.
-
- \sa QWSServer, QWSClient, {Qt for Embedded Linux Architecture}
-*/
-
-/*!
- Constructs a QCopChannel object for the specified \a channel, with
- the given \a parent. Once created, the channel is registered by
- the server.
-
- \sa isRegistered(), channel()
-*/
-
-QCopChannel::QCopChannel(const QString& channel, QObject *parent) :
- QObject(parent)
-{
- init(channel);
-}
-
-#ifdef QT3_SUPPORT
-/*!
- Use the two argument overload instead, and call the
- QObject::setObjectName() function to \a name the instance.
-*/
-QCopChannel::QCopChannel(const QString& channel, QObject *parent, const char *name) :
- QObject(parent)
-{
- setObjectName(QString::fromAscii(name));
- init(channel);
-}
-#endif
-
-void QCopChannel::init(const QString& channel)
-{
- d = new QCopChannelPrivate;
- d->channel = channel;
-
- if (!qt_fbdpy) {
- qFatal("QCopChannel: Must construct a QApplication "
- "before QCopChannel");
- return;
- }
-
- {
- QMutexLocker locker(qcopClientMapMutex());
-
- if (!qcopClientMap)
- qcopClientMap = new QCopClientMap;
-
- // do we need a new channel list ?
- QCopClientMap::Iterator it = qcopClientMap->find(channel);
- if (it != qcopClientMap->end()) {
- it.value().append(this);
- return;
- }
-
- it = qcopClientMap->insert(channel, QList< QPointer<QCopChannel> >());
- it.value().append(QPointer<QCopChannel>(this));
- }
-
- // inform server about this channel
- qt_fbdpy->registerChannel(channel);
-}
-
-/*!
- \internal
-
- Resend all channel registrations
- */
-void QCopChannel::reregisterAll()
-{
- if(qcopClientMap)
- for(QCopClientMap::Iterator iter = qcopClientMap->begin();
- iter != qcopClientMap->end();
- ++iter)
- qt_fbdpy->registerChannel(iter.key());
-}
-
-/*!
- Destroys this QCopChannel object.
-
- The server is notified that this particular listener has closed
- its connection. The server will keep the channel open until the
- last registered listener detaches.
-
- \sa isRegistered(), channel()
-*/
-
-QCopChannel::~QCopChannel()
-{
- QMutexLocker locker(qcopClientMapMutex());
- QCopClientMap::Iterator it = qcopClientMap->find(d->channel);
- Q_ASSERT(it != qcopClientMap->end());
- it.value().removeAll(this);
- // still any clients connected locally ?
- if (it.value().isEmpty()) {
- QByteArray data;
- QDataStream s(&data, QIODevice::WriteOnly);
- s << d->channel;
- if (qt_fbdpy)
- send(QLatin1String(""), QLatin1String("detach()"), data);
- qcopClientMap->remove(d->channel);
- }
-
- delete d;
-}
-
-/*!
- Returns the name of this object's channel.
-
- \sa isRegistered()
-*/
-
-QString QCopChannel::channel() const
-{
- return d->channel;
-}
-
-/*!
- \fn void QCopChannel::receive(const QString& message, const QByteArray &data)
-
- Processes the incoming \a message and \a data.
-
- This function is called by the server when this object's channel
- receives new messages. Note that the default implementation simply
- emits the received() signal; reimplement this function to process
- the incoming \a message and \a data.
-
- Note that the format of the given \a data has to be well defined
- in order to extract the information it contains. In addition, it
- is recommended to use the DCOP convention. This is not a
- requirement, but you must ensure that the sender and receiver
- agree on the argument types. For example:
-
- \snippet doc/src/snippets/code/src_gui_embedded_qcopchannel_qws.cpp 0
-
- The above code assumes that the \c message is a DCOP-style
- function signature and the \c data contains the function's
- arguments.
-
- \sa send(), channel(), received()
- */
-void QCopChannel::receive(const QString& msg, const QByteArray &data)
-{
- emit received(msg, data);
-}
-
-/*!
- \fn void QCopChannel::received(const QString& message, const QByteArray &data)
-
- This signal is emitted whenever this object's channel receives new
- messages (i.e., it is emitted by the receive() function), passing
- the incoming \a message and \a data as parameters.
-
- \sa receive(), channel()
-*/
-
-/*!
- Queries the server for the existence of the given \a channel. Returns true
- if the channel is registered; otherwise returns false.
-
- \sa channel(), send()
-*/
-
-bool QCopChannel::isRegistered(const QString& channel)
-{
- QByteArray data;
- QDataStream s(&data, QIODevice::WriteOnly);
- s << channel;
- if (!send(QLatin1String(""), QLatin1String("isRegistered()"), data))
- return false;
-
- QWSQCopMessageEvent *e = qt_fbdpy->waitForQCopResponse();
- bool known = e->message == "known";
- delete e;
- return known;
-}
-
-/*!
- \fn bool QCopChannel::send(const QString& channel, const QString& message)
- \overload
-*/
-
-bool QCopChannel::send(const QString& channel, const QString& msg)
-{
- QByteArray data;
- return send(channel, msg, data);
-}
-
-/*!
- \fn bool QCopChannel::send(const QString& channel, const QString& message,
- const QByteArray &data)
-
- Sends the given \a message on the specified \a channel with the
- given \a data. The message will be distributed to all clients
- subscribed to the channel. Returns true if the message is sent
- successfully; otherwise returns false.
-
- It is recommended to use the DCOP convention. This is not a
- requirement, but you must ensure that the sender and receiver
- agree on the argument types.
-
- Note that QDataStream provides a convenient way to fill the byte
- array with auxiliary data. For example:
-
- \snippet doc/src/snippets/code/src_gui_embedded_qcopchannel_qws.cpp 1
-
- In the code above the channel is \c "System/Shell". The \c message
- is an arbitrary string, but in the example we've used the DCOP
- convention of passing a function signature. Such a signature is
- formatted as \c "functionname(types)" where \c types is a list of
- zero or more comma-separated type names, with no whitespace, no
- consts and no pointer or reference marks, i.e. no "*" or "&".
-
- \sa receive(), isRegistered()
-*/
-
-bool QCopChannel::send(const QString& channel, const QString& msg,
- const QByteArray &data)
-{
- if (!qt_fbdpy) {
- qFatal("QCopChannel::send: Must construct a QApplication "
- "before using QCopChannel");
- return false;
- }
-
- qt_fbdpy->sendMessage(channel, msg, data);
-
- return true;
-}
-
-/*!
- \since 4.2
-
- Flushes all queued messages to the registered listeners.
-
- Note that this function returns false if no QApplication has been
- constructed, otherwise it returns true.
-
- \sa send()
-
-*/
-bool QCopChannel::flush()
-{
- if (!qt_fbdpy) {
- qFatal("QCopChannel::flush: Must construct a QApplication "
- "before using QCopChannel");
- return false;
- }
-
- qt_fbdpy->flushCommands();
-
- return true;
-}
-
-class QWSServerSignalBridge : public QObject {
- Q_OBJECT
-
-public:
- void emitNewChannel(const QString& channel);
- void emitRemovedChannel(const QString& channel);
-
- signals:
- void newChannel(const QString& channel);
- void removedChannel(const QString& channel);
-};
-
-void QWSServerSignalBridge::emitNewChannel(const QString& channel){
- emit newChannel(channel);
-}
-
-void QWSServerSignalBridge::emitRemovedChannel(const QString& channel) {
- emit removedChannel(channel);
-}
-
-/*!
- \internal
- Server side: subscribe client \a cl on channel \a ch.
-*/
-
-void QCopChannel::registerChannel(const QString& ch, QWSClient *cl)
-{
- if (!qcopServerMap)
- qcopServerMap = new QCopServerMap;
-
- // do we need a new channel list ?
- QCopServerMap::Iterator it = qcopServerMap->find(ch);
- if (it == qcopServerMap->end())
- it = qcopServerMap->insert(ch, QList<QWSClient*>());
-
- // If the channel name contains wildcard characters, then we also
- // register it on the server regexp matching list.
- if (containsWildcards( ch )) {
- QCopServerRegexp item(ch, cl);
- if (!qcopServerRegexpList)
- qcopServerRegexpList = new QCopServerRegexpList;
- qcopServerRegexpList->append( item );
- }
-
- // If this is the first client in the channel, announce the channel as being created.
- if (it.value().count() == 0) {
- QWSServerSignalBridge* qwsBridge = new QWSServerSignalBridge();
- connect(qwsBridge, SIGNAL(newChannel(QString)), qwsServer, SIGNAL(newChannel(QString)));
- qwsBridge->emitNewChannel(ch);
- delete qwsBridge;
- }
-
- it.value().append(cl);
-}
-
-/*!
- \internal
- Server side: unsubscribe \a cl from all channels.
-*/
-
-void QCopChannel::detach(QWSClient *cl)
-{
- if (!qcopServerMap)
- return;
-
- QCopServerMap::Iterator it = qcopServerMap->begin();
- for (; it != qcopServerMap->end(); ++it) {
- if (it.value().contains(cl)) {
- it.value().removeAll(cl);
- // If this was the last client in the channel, announce the channel as dead.
- if (it.value().count() == 0) {
- QWSServerSignalBridge* qwsBridge = new QWSServerSignalBridge();
- connect(qwsBridge, SIGNAL(removedChannel(QString)), qwsServer, SIGNAL(removedChannel(QString)));
- qwsBridge->emitRemovedChannel(it.key());
- delete qwsBridge;
- }
- }
- }
-
- if (!qcopServerRegexpList)
- return;
-
- QCopServerRegexpList::Iterator it2 = qcopServerRegexpList->begin();
- while(it2 != qcopServerRegexpList->end()) {
- if ((*it2).client == cl)
- it2 = qcopServerRegexpList->erase(it2);
- else
- ++it2;
- }
-}
-
-/*!
- \internal
- Server side: transmit the message to all clients registered to the
- specified channel.
-*/
-
-void QCopChannel::answer(QWSClient *cl, const QString& ch,
- const QString& msg, const QByteArray &data)
-{
- // internal commands
- if (ch.isEmpty()) {
- if (msg == QLatin1String("isRegistered()")) {
- QString c;
- QDataStream s(data);
- s >> c;
- bool known = qcopServerMap && qcopServerMap->contains(c)
- && !((*qcopServerMap)[c]).isEmpty();
- // Yes, it's a typo, it's not user-visible, and we choose not to fix it for compatibility
- QLatin1String ans = QLatin1String(known ? "known" : "unknown");
- QWSServerPrivate::sendQCopEvent(cl, QLatin1String(""),
- ans, data, true);
- return;
- } else if (msg == QLatin1String("detach()")) {
- QString c;
- QDataStream s(data);
- s >> c;
- Q_ASSERT(qcopServerMap);
- QCopServerMap::Iterator it = qcopServerMap->find(c);
- if (it != qcopServerMap->end()) {
- //Q_ASSERT(it.value().contains(cl));
- it.value().removeAll(cl);
- if (it.value().isEmpty()) {
- // If this was the last client in the channel, announce the channel as dead
- QWSServerSignalBridge* qwsBridge = new QWSServerSignalBridge();
- connect(qwsBridge, SIGNAL(removedChannel(QString)), qwsServer, SIGNAL(removedChannel(QString)));
- qwsBridge->emitRemovedChannel(it.key());
- delete qwsBridge;
- qcopServerMap->erase(it);
- }
- }
- if (qcopServerRegexpList && containsWildcards(c)) {
- // Remove references to a wildcarded channel.
- QCopServerRegexpList::Iterator it
- = qcopServerRegexpList->begin();
- while(it != qcopServerRegexpList->end()) {
- if ((*it).client == cl && (*it).channel == c)
- it = qcopServerRegexpList->erase(it);
- else
- ++it;
- }
- }
- return;
- }
- qWarning("QCopChannel: unknown internal command %s", qPrintable(msg));
- QWSServerPrivate::sendQCopEvent(cl, QLatin1String(""),
- QLatin1String("bad"), data);
- return;
- }
-
- if (qcopServerMap) {
- QList<QWSClient*> clist = qcopServerMap->value(ch);
- for (int i=0; i < clist.size(); ++i) {
- QWSClient *c = clist.at(i);
- QWSServerPrivate::sendQCopEvent(c, ch, msg, data);
- }
- }
-
- if(qcopServerRegexpList && !containsWildcards(ch)) {
- // Search for wildcard matches and forward the message on.
- QCopServerRegexpList::ConstIterator it = qcopServerRegexpList->constBegin();
- for (; it != qcopServerRegexpList->constEnd(); ++it) {
- if ((*it).regexp.exactMatch(ch)) {
- QByteArray newData;
- {
- QDataStream stream
- (&newData, QIODevice::WriteOnly | QIODevice::Append);
- stream << ch;
- stream << msg;
- stream << data;
- // Stream is flushed and closed at this point.
- }
- QWSServerPrivate::sendQCopEvent
- ((*it).client, (*it).channel,
- QLatin1String("forwardedMessage(QString,QString,QByteArray)"),
- newData);
- }
- }
- }
-}
-
-/*!
- \internal
- Client side: distribute received event to the QCop instance managing the
- channel.
-*/
-void QCopChannel::sendLocally(const QString& ch, const QString& msg,
- const QByteArray &data)
-{
- Q_ASSERT(qcopClientMap);
-
- // filter out internal events
- if (ch.isEmpty())
- return;
-
- // feed local clients with received data
- QList< QPointer<QCopChannel> > clients;
- {
- QMutexLocker locker(qcopClientMapMutex());
- clients = (*qcopClientMap)[ch];
- }
- for (int i = 0; i < clients.size(); ++i) {
- QCopChannel *channel = (QCopChannel *)clients.at(i);
- if ( channel )
- channel->receive(msg, data);
- }
-}
-
-QT_END_NAMESPACE
-
-#include "qcopchannel_qws.moc"
-
-#endif
diff --git a/src/gui/embedded/qcopchannel_qws.h b/src/gui/embedded/qcopchannel_qws.h
deleted file mode 100644
index 0ee41b8da5..0000000000
--- a/src/gui/embedded/qcopchannel_qws.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QCOPCHANNEL_QWS_H
-#define QCOPCHANNEL_QWS_H
-
-#include <QtCore/qobject.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_COP
-
-class QWSClient;
-class QCopChannelPrivate;
-
-class Q_GUI_EXPORT QCopChannel : public QObject
-{
- Q_OBJECT
-public:
- explicit QCopChannel(const QString& channel, QObject *parent=0);
-#ifdef QT3_SUPPORT
- QT3_SUPPORT_CONSTRUCTOR QCopChannel(const QString& channel, QObject *parent, const char *name);
-#endif
- virtual ~QCopChannel();
-
- QString channel() const;
-
- static bool isRegistered(const QString& channel);
- static bool send(const QString& channel, const QString& msg);
- static bool send(const QString& channel, const QString& msg,
- const QByteArray &data);
-
- static bool flush();
-
- static void sendLocally( const QString& ch, const QString& msg,
- const QByteArray &data);
- static void reregisterAll();
-
- virtual void receive(const QString& msg, const QByteArray &data);
-
-Q_SIGNALS:
- void received(const QString& msg, const QByteArray &data);
-
-private:
- void init(const QString& channel);
-
- // server side
- static void registerChannel(const QString& ch, QWSClient *cl);
- static void detach(QWSClient *cl);
- static void answer(QWSClient *cl, const QString& ch,
- const QString& msg, const QByteArray &data);
- // client side
- QCopChannelPrivate* d;
-
- friend class QWSServer;
- friend class QWSServerPrivate;
- friend class QApplication;
-};
-
-#endif // QT_NO_COP
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QCOPCHANNEL_QWS_H
diff --git a/src/gui/embedded/qdecoration_qws.cpp b/src/gui/embedded/qdecoration_qws.cpp
deleted file mode 100644
index ffee6cbb73..0000000000
--- a/src/gui/embedded/qdecoration_qws.cpp
+++ /dev/null
@@ -1,404 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qdecoration_qws.h"
-
-#include "qapplication.h"
-#include "qdrawutil.h"
-#include "qpainter.h"
-#include "qregion.h"
-#include "qwhatsthis.h"
-
-#include "qmenu.h"
-#include "private/qwidget_p.h"
-#include "qwsmanager_qws.h"
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \class QDecoration
- \ingroup qws
-
- \brief The QDecoration class is a base class for window
- decorations in Qt for Embedded Linux
-
- Note that this class is non-portable and only available in
- \l{Qt for Embedded Linux}.
-
- \l{Qt for Embedded Linux} provides window management of top level windows
- and several ready made decorations (i.e., \c Default, \c Styled
- and \c Windows). Custom decorations can be implemented by
- subclassing the QDecoration class and creating a decoration plugin
- (derived from QDecorationPlugin). The default
- implementation of the QDecorationFactory class will automatically
- detect the plugin, and load the decoration into the application at
- run-time using Qt's \l {How to Create Qt Plugins}{plugin
- system}. To actually apply a decoration, use the
- QApplication::qwsSetDecoration() function.
-
- When creating a custom decoration, implement the paint() function
- to paint the border and title decoration, and the region()
- function to return the regions the decoration
- occupies. Reimplement the regionClicked() and
- regionDoubleClicked() functions to respond to mouse clicks (the
- default implementations responds to (single) clicks on items in a
- widget's system menu and double clicks on a widget's title).
-
- QDecoration provides the DecorationRegion enum that describes the
- various regions of the window decoration, and the regionAt()
- function to determine the region containing a given point. The
- QDecoration class also provides the DecorationState enum
- describing the state of a given region, e.g. whether it is active
- or not.
-
- In addition, it is possible to build the system menu for a given
- top level widget using the buildSysMenu() function; whenever an
- action in this menu is triggered, the menuTriggered() function is
- called automatically.
-
- Finally, the QDecoration class provides a couple of static
- functions, startMove() and startResize(), which start a move or
- resize action by making the appropriate decoration region active
- and grabbing the mouse input.
-
- \sa QDecorationFactory, QDecorationPlugin, {Qt for Embedded Linux
- Architecture}
-*/
-
-/*!
- \fn QDecoration::QDecoration()
-
- Constructs a decoration object.
-*/
-
-/*!
- \fn QDecoration::~QDecoration()
-
- Destroys this decoration object.
-*/
-
-/*!
- \enum QDecoration::DecorationRegion
-
- This enum describes the various regions of the window decoration.
-
- \value All The entire region used by the window decoration.
-
- \value Top The top border used to vertically resize the window.
- \value Bottom The bottom border used to vertically resize the window.
- \value Left The left border used to horizontally resize the window.
- \value Right The right border used to horizontally resize the window.
- \value TopLeft The top-left corner of the window used to resize the
- window both horizontally and vertically.
- \value TopRight The top-right corner of the window used to resize the
- window both horizontally and vertically.
- \value BottomLeft The bottom-left corner of the window used to resize the
- window both horizontally and vertically.
- \value BottomRight The bottom-right corner of the window used to resize the
- window both horizontally and vertically.
- \value Borders All the regions used to describe the window's borders.
-
- \value Title The region containing the window title, used
- to move the window by dragging with the mouse cursor.
- \value Close The region occupied by the close button. Clicking in this
- region closes the window.
- \value Minimize The region occupied by the minimize button. Clicking in
- this region minimizes the window.
- \value Maximize The region occupied by the maximize button. Clicking in
- this region maximizes the window.
- \value Normalize The region occupied by a button used to restore a window's
- normal size. Clicking in this region restores a maximized
- window to its previous size. The region used for this
- button is often also the Maximize region.
- \value Menu The region occupied by the window's menu button. Clicking
- in this region opens the window operations (system) menu.
- \value Help The region occupied by the window's help button. Clicking
- in this region causes the context-sensitive help function
- to be enabled.
- \value Resize The region used to resize the window.
- \value Move The region used to move the window.
- \value None No region.
-
- \sa region(), regionAt(), DecorationState
-*/
-
-/*!
- \enum QDecoration::DecorationState
-
- This enum describes the various states of a decoration region.
-
- \value Normal The region is active
- \value Disabled The region is inactive.
- \value Hover The cursor is hovering over the region.
- \value Pressed The region is pressed.
-
- \sa paint(), DecorationRegion
-*/
-
-/*!
- \fn QRegion QDecoration::region(const QWidget *widget, const QRect & rectangle, int decorationRegion)
-
- Implement this function to return the region specified by \a
- decorationRegion for the given top level \a widget.
-
- The \a rectangle parameter specifies the rectangle the decoration
- is wrapped around. The \a decorationRegion is a bitmask of the
- values described by the DecorationRegion enum.
-
- \sa regionAt(), paint()
-*/
-
-/*!
- \fn QRegion QDecoration::region(const QWidget *widget, int decorationRegion)
- \overload
-*/
-
-/*!
- \fn bool QDecoration::paint(QPainter *painter, const QWidget *widget, int decorationRegion,
- DecorationState state)
-
- Implement this function to paint the border and title decoration
- for the specified top level \a widget using the given \a painter
- and decoration \a state. The specified \a decorationRegion is a
- bitmask of the values described by the DecorationRegion enum.
-
- Note that \l{Qt for Embedded Linux} expects this function to return true if
- any of the widget's decorations are repainted; otherwise it should
- return false.
-
- \sa region()
-*/
-
-/*!
- \fn int QDecoration::regionAt(const QWidget *widget, const QPoint &point)
-
- Returns the type of the first region of the specified top level \a
- widget containing the given \a point.
-
- The return value is one of the DecorationRegion enum's values. Use
- the region() function to retrieve the actual region. If none of
- the widget's regions contain the point, this function returns \l
- None.
-
- \sa region()
-*/
-int QDecoration::regionAt(const QWidget *w, const QPoint &point)
-{
- int regions[] = {
- TopLeft, Top, TopRight, Left, Right, BottomLeft, Bottom, BottomRight, // Borders first
- Menu, Title, Help, Minimize, Normalize, Maximize, Close, // then buttons
- None
- };
-
-// char *regions_str[] = {
-// "TopLeft", "Top", "TopRight", "Left", "Right", "BottomLeft", "Bottom", "BottomRight",
-// "Menu", "Title", "Help", "Minimize", "Normalize", "Maximize", "Close",
-// "None"
-// };
-
- // First check to see if within all regions at all
- QRegion reg = region(w, w->geometry(), All);
- if (!reg.contains(point)) {
- return None;
- }
-
- int i = 0;
- while (regions[i]) {
- reg = region(w, w->geometry(), regions[i]);
- if (reg.contains(point)) {
-// qDebug("In region %s", regions_str[i]);
- return regions[i];
- }
- ++i;
- }
- return None;
-}
-
-#ifndef QT_NO_MENU
-/*!
- Builds the system menu for the given top level \a widget, adding
- \gui Restore, \gui Move, \gui Size, \gui Minimize, \gui Maximize
- and \gui Close actions to the given \a menu.
-
- \sa menuTriggered()
-*/
-void QDecoration::buildSysMenu(QWidget *widget, QMenu *menu)
-{
- QDecorationAction *act = new QDecorationAction(QLatin1String("Restore"),
- menu, Maximize);
- act->setEnabled(widget->windowState() & Qt::WindowMaximized);
- menu->addAction(act);
- act = new QDecorationAction(QLatin1String("Move"), menu, Move);
- act->setEnabled(!(widget->windowState() & Qt::WindowMaximized));
- menu->addAction(act);
- menu->addAction(new QDecorationAction(QLatin1String("Size"), menu, Resize));
- act = new QDecorationAction(QLatin1String("Minimize"), menu, Minimize);
- menu->addAction(act);
- act = new QDecorationAction(QLatin1String("Maximize"), menu, Maximize);
- act->setDisabled(widget->windowState() & Qt::WindowMaximized);
- menu->addAction(act);
- menu->addSeparator();
- menu->addAction(new QDecorationAction(QLatin1String("Close"), menu, Close));
-}
-
-/*!
- This function is called whenever an action in a top level widget's
- menu is triggered, and simply calls the regionClicked() function
- passing the \a widget and \a action parameters as arguments.
-
- \sa buildSysMenu()
-*/
-void QDecoration::menuTriggered(QWidget *widget, QAction *action)
-{
- QDecorationAction *decAction = static_cast<QDecorationAction *>(action);
- regionClicked(widget, decAction->reg);
-}
-#endif // QT_NO_MENU
-
-/*!
- \fn void QDecoration::regionClicked(QWidget *widget, int region)
-
- Handles the event that the specified \a region in the given top
- level \a widget is activated by a single click (the \a region
- parameter is described using the DecorationRegion enum).
-
- This function is called whenever a region in a top level widget is
- clicked; the default implementation responds to clicks on items in
- the system menu, performing the requested actions.
-
- \sa regionDoubleClicked(), region()
-*/
-void QDecoration::regionClicked(QWidget *widget, int reg)
-{
- switch(reg) {
- case Move:
- startMove(widget);
- break;
- case Resize:
- startResize(widget);
- break;
- case Help:
-#ifndef QT_NO_WHATSTHIS
- if (QWhatsThis::inWhatsThisMode())
- QWhatsThis::leaveWhatsThisMode();
- else
- QWhatsThis::enterWhatsThisMode();
-#endif
- break;
- case Close:
- widget->close();
- break;
- case Normalize:
- widget->showNormal();
- break;
- case Maximize:
- if (widget->windowState() & Qt::WindowMaximized)
- widget->showNormal();
- else
- widget->showMaximized();
- break;
- }
-}
-
-/*!
- \fn void QDecoration::regionDoubleClicked(QWidget *widget, int region)
-
- Handles the event that the specified \a region in the given top
- level \a widget is activated by a double click (the region
- parameter is described using the DecorationRegion enum).
-
- This function is called whenever a region in a top level widget is
- double clicked; the default implementation responds to a double
- click on the widget's title, toggling its size between the maximum
- and its normal size.
-
- \sa regionClicked(), region()
-*/
-void QDecoration::regionDoubleClicked(QWidget *widget, int reg)
-{
- switch(reg)
- {
- case Title: {
- if (widget->windowState() & Qt::WindowMaximized)
- widget->showNormal();
- else
- widget->showMaximized();
- break;
- }
- }
-}
-
-/*!
- Starts to move the given top level \a widget by making its \l
- Title region active and grabbing the mouse input.
-
- \sa startResize()
-*/
-void QDecoration::startMove(QWidget *widget)
-{
-#ifdef QT_NO_QWS_MANAGER
- Q_UNUSED(widget);
-#else
- QWSManager *manager = widget->d_func()->topData()->qwsManager;
- if (manager)
- manager->startMove();
-#endif
-}
-
-/*!
- Starts to resize the given top level \a widget by making its \l
- BottomRight region active and grabbing the mouse input.
-
- \sa startMove()
-*/
-void QDecoration::startResize(QWidget *widget)
-{
-#ifdef QT_NO_QWS_MANAGER
- Q_UNUSED(widget);
-#else
- QWSManager *manager = widget->d_func()->topData()->qwsManager;
- if (manager)
- manager->startResize();
-#endif
-}
-
-
-QT_END_NAMESPACE
diff --git a/src/gui/embedded/qdecoration_qws.h b/src/gui/embedded/qdecoration_qws.h
deleted file mode 100644
index 5e1d2773a5..0000000000
--- a/src/gui/embedded/qdecoration_qws.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDECORATION_QWS_H
-#define QDECORATION_QWS_H
-
-#include <QtGui/qregion.h>
-#include <QtGui/qwidget.h>
-#include <QtGui/qaction.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QPopupMenu;
-class QMenu;
-
-#ifndef QT_NO_ACTION
-class QDecorationAction : public QAction
-{
-public:
- QDecorationAction(const QString &text, QObject* parent, int region)
- : QAction(text, parent), reg(region) {}
- int reg;
-};
-#endif // QT_NO_ACTION
-
-/*
- Implements decoration styles
-*/
-class Q_GUI_EXPORT QDecoration
-{
-public:
- QDecoration() {}
- virtual ~QDecoration() {}
-
- /* AABBBBBBBBBBCC Items in DecorationRegion:
- AijjjjjjjklmnC
- A C A = TopLeft B = Top C = TopRight
- D E D = Left E = Right
- D E F = BottomLeft H = Bottom G = BottomRight
- F G i = Menu j = Title k = Help
- FFHHHHHHHHHHGG l = Minimize m = Maximize n = Close
-
- */
-
- enum DecorationRegion {
- None = 0x0000000000, All = 0x7fffffff,
- TopLeft = 0x0000000001, Top = 0x0000000002, TopRight = 0x0000000004,
- Left = 0x0000000008, Right = 0x0000000010,
- BottomLeft = 0x0000000020, Bottom = 0x0000000040, BottomRight = 0x0000000080,
- Borders = 0x00000000ff,
- Menu = 0x0000000100, Title = 0x0000000200, Help = 0x0000000400,
- Minimize = 0x0000000800, Maximize = 0x0000001000, Normalize = 0x0000002000,
- Close = 0x0000004000, Move = 0x0000008000, Resize = 0x0000010000
- };
-
- enum DecorationState { Normal = 0x04, Disabled = 0x08, Hover = 0x01, Pressed = 0x02 };
-
- virtual QRegion region(const QWidget *w, const QRect &rect, int decorationRegion = All ) = 0;
- QRegion region(const QWidget *w, int decorationRegion = All )
- { return region(w, w->rect(), decorationRegion); }
- virtual int regionAt(const QWidget *w, const QPoint &point);
-
- virtual void regionClicked(QWidget *widget, int region);
- virtual void regionDoubleClicked(QWidget *widget, int region);
-#ifndef QT_NO_MENU
- virtual void buildSysMenu(QWidget *widget, QMenu *menu);
- void menuTriggered(QWidget *widget, QAction *action);
-#endif
-
- static void startMove(QWidget *widget);
- static void startResize(QWidget *widget);
-
- virtual bool paint(QPainter *p, const QWidget *w, int decorationRegion = All,
- DecorationState state = Normal) = 0;
-
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QDECORATION_QWS_H
diff --git a/src/gui/embedded/qdecorationdefault_qws.cpp b/src/gui/embedded/qdecorationdefault_qws.cpp
deleted file mode 100644
index 6563d4af89..0000000000
--- a/src/gui/embedded/qdecorationdefault_qws.cpp
+++ /dev/null
@@ -1,803 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qapplication.h>
-#include <qwidget.h>
-#include <qpainter.h>
-#include <qpaintengine.h>
-#include <qdrawutil.h>
-#include "qdecorationdefault_qws.h"
-
-QT_BEGIN_NAMESPACE
-
-#if !defined(QT_NO_QWS_DECORATION_DEFAULT) || defined(QT_PLUGIN)
-
-QPixmap *QDecorationDefault::staticHelpPixmap = 0;
-QPixmap *QDecorationDefault::staticMenuPixmap = 0;
-QPixmap *QDecorationDefault::staticClosePixmap = 0;
-QPixmap *QDecorationDefault::staticMinimizePixmap = 0;
-QPixmap *QDecorationDefault::staticMaximizePixmap = 0;
-QPixmap *QDecorationDefault::staticNormalizePixmap = 0;
-
-#ifndef QT_NO_IMAGEFORMAT_XPM
-
-/* XPM */
-static const char * const default_menu_xpm[] = {
-/* width height ncolors chars_per_pixel */
-"16 16 11 1",
-/* colors */
-" c #000000",
-". c #336600",
-"X c #666600",
-"o c #99CC00",
-"O c #999933",
-"+ c #333300",
-"@ c #669900",
-"# c #999900",
-"$ c #336633",
-"% c #666633",
-"& c #99CC33",
-/* pixels */
-"oooooooooooooooo",
-"oooooooooooooooo",
-"ooooo#.++X#ooooo",
-"ooooX Xoooo",
-"oooX XO#% X&oo",
-"oo# Ooo&@O Ooo",
-"oo. Xoo#+ @X Xoo",
-"oo+ OoO+ +O# +oo",
-"oo+ #O+ +## +oo",
-"oo. %@ ++ +. Xoo",
-"oo# O@OO+ #oo",
-"oooX X##$ Ooo",
-"ooooX Xoo",
-"oooo&OX++X#OXooo",
-"oooooooooooooooo",
-"oooooooooooooooo"
-};
-
-static const char * const default_help_xpm[] = {
-"16 16 3 1",
-" s None c None",
-". c #ffffff",
-"X c #707070",
-" ",
-" ",
-" ...... ",
-" ..XXXXXX ",
-" .XX .XX ",
-" .XX .XX ",
-" ..XX ",
-" ..XX ",
-" ..XX ",
-" .XX ",
-" .XX ",
-" .. ",
-" .XX ",
-" .XX ",
-" ",
-" "};
-
-static const char * const default_close_xpm[] = {
-"16 16 3 1",
-" s None c None",
-". c #ffffff",
-"X c #707070",
-" ",
-" ",
-" .X .X ",
-" .XX .XX ",
-" .XX .XX ",
-" .XX .XX ",
-" .XX.XX ",
-" .XXX ",
-" .XXX ",
-" .XX.XX ",
-" .XX .XX ",
-" .XX .XX ",
-" .XX .XX ",
-" .X .X ",
-" ",
-" "};
-
-static const char * const default_maximize_xpm[] = {
-"16 16 3 1",
-" s None c None",
-". c #ffffff",
-"X c #707070",
-" ",
-" ",
-" ........... ",
-" .XXXXXXXXXX ",
-" .X .X ",
-" .X .X ",
-" .X .X ",
-" .X .X ",
-" .X .X ",
-" .X .X ",
-" .X .X ",
-" .X........X ",
-" .XXXXXXXXXX ",
-" ",
-" ",
-" "};
-
-static const char * const default_minimize_xpm[] = {
-"16 16 3 1",
-" s None c None",
-". c #ffffff",
-"X c #707070",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ... ",
-" . X ",
-" .XX ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" "};
-
-static const char * const default_normalize_xpm[] = {
-"16 16 3 1",
-" s None c None",
-". c #ffffff",
-"X c #707070",
-" ",
-" ",
-" ........ ",
-" .XXXXXXXX ",
-" .X .X ",
-" .X .X ",
-" ....X... .X ",
-" .XXXXXXXX .X ",
-" .X .XXXX ",
-" .X .X ",
-" .X .X ",
-" .X......X ",
-" .XXXXXXXX ",
-" ",
-" ",
-" "};
-
-#endif // QT_NO_IMAGEFORMAT_XPM
-
-/*!
- \class QDecorationDefault
- \since 4.4
- \ingroup qws
- \brief The QDecorationDefault class is a base class providing default window decorations.
-
- See the documentation for class QDecoration for a detailed
- description. This subclass of QDecoration provides standard
- icons for the decoration regions.
-
- Note that this class is non-portable and only available in
- \l{Qt for Embedded Linux}.
- */
-
-/*!
- Default constructor.
- */
-QDecorationDefault::QDecorationDefault()
- : QDecoration()
-{
- menu_width = 20;
- help_width = 20;
- close_width = 20;
- minimize_width = 20;
- maximize_width = 20;
- normalize_width = 20;
-}
-
-/*!
- The constructor deletes the static pixmaps.
- */
-QDecorationDefault::~QDecorationDefault()
-{
- delete staticMenuPixmap;
- delete staticClosePixmap;
- delete staticMinimizePixmap;
- delete staticMaximizePixmap;
- delete staticNormalizePixmap;
-
- // This makes it safe to delete and then create a QDecorationDefault
- staticMenuPixmap = 0;
- staticClosePixmap = 0;
- staticMinimizePixmap = 0;
- staticMaximizePixmap = 0;
- staticNormalizePixmap = 0;
-}
-
-/*!
- \fn const char **QDecorationDefault::xpmForRegion(int region)
-
- Returns a pointer to the X pixmap for the icon specified by
- \a region. An X pixmap is an ASCII-text-based image. The value
- of \a region must be one of a subset of the values of enum
- DecorationRegion. The supported values are \e Help, \e Menu,
- \e Close, \e Minimize, \e Maximize, and \e Normalize. Other
- values of \a region cause zero to be returned.
-
- \sa QDecoration::DecorationRegion
- */
-const char **QDecorationDefault::xpmForRegion(int reg)
-{
-#ifdef QT_NO_IMAGEFORMAT_XPM
- Q_UNUSED(reg);
-#else
- switch(reg)
- {
- case Help:
- return (const char **)default_help_xpm;
- case Menu:
- return (const char **)default_menu_xpm;
- case Close:
- return (const char **)default_close_xpm;
- case Minimize:
- return (const char **)default_minimize_xpm;
- case Maximize:
- return (const char **)default_maximize_xpm;
- case Normalize:
- return (const char **)default_normalize_xpm;
- }
-#endif
- return 0;
-}
-
-/*!
- \fn QPixmap QDecorationDefault::pixmapFor(const QWidget *widget,
- int decorationRegion, int &xoff, int &yoff)
-
- Returns a pointer to the QPixmap for the widget specified by \a widget and
- \a decorationRegion. The returned QPixmap is constructed from the default
- X pixmap obtained from xpmForRegion().
-
- \a xoff and \a yoff specify the offset for the pixmap.
-
- The value of \a decorationRegion must be one of a subset of the values
- of enum DecorationRegion. The supported values are \e Help,
- \e Menu, \e Close, \e Minimize, \e Maximize, and \e Normalize.
- Other values of \a decorationRegion return 0.
-
- \sa QDecoration::DecorationRegion
-*/
-QPixmap QDecorationDefault::pixmapFor(const QWidget *widget,
- int decorationRegion,
- int &xoff,
- int &/*yoff*/)
-{
-#ifdef QT_NO_IMAGEFORMAT_XPM
- Q_UNUSED(widget);
- Q_UNUSED(decorationRegion);
- Q_UNUSED(xoff);
- return QPixmap();
-#else
- static const char **staticHelpPixmapXPM = 0;
- static const char **staticMenuPixmapXPM = 0;
- static const char **staticClosePixmapXPM = 0;
- static const char **staticMinimizePixmapXPM = 0;
- static const char **staticMaximizePixmapXPM = 0;
- static const char **staticNormalizePixmapXPM = 0;
- const char **xpm;
-
- // Why don't we just use/extend the enum type...
-
- if (staticHelpPixmapXPM != (xpm = xpmForRegion(Help)) || !staticHelpPixmap) {
- staticHelpPixmapXPM = xpm;
- staticHelpPixmap = new QPixmap(xpm);
- }
- if (staticMenuPixmapXPM != (xpm = xpmForRegion(Menu)) || !staticMenuPixmap) {
- staticMenuPixmapXPM = xpm;
- staticMenuPixmap = new QPixmap(xpm);
- }
- if (staticClosePixmapXPM != (xpm = xpmForRegion(Close)) || !staticClosePixmap) {
- staticClosePixmapXPM = xpm;
- staticClosePixmap = new QPixmap(xpm);
- }
- if (staticMinimizePixmapXPM != (xpm = xpmForRegion(Minimize)) || !staticMinimizePixmap) {
- staticMinimizePixmapXPM = xpm;
- staticMinimizePixmap = new QPixmap(xpm);
- }
- if (staticMaximizePixmapXPM != (xpm = xpmForRegion(Maximize)) || !staticMaximizePixmap) {
- staticMaximizePixmapXPM = xpm;
- staticMaximizePixmap = new QPixmap(xpm);
- }
- if (staticNormalizePixmapXPM != (xpm = xpmForRegion(Normalize)) || !staticNormalizePixmap) {
- staticNormalizePixmapXPM = xpm;
- staticNormalizePixmap = new QPixmap(xpm);
- }
-
- const QPixmap *pm = 0;
-
- switch (decorationRegion) {
- case Help:
- pm = staticHelpPixmap;
- break;
- case Menu:
- if (!widget->windowIcon().isNull())
- return widget->windowIcon().pixmap(16,16); //##### QIcon::pixmap() needs a size !!!!!!"
- if (!pm) {
- xoff = 1;
- pm = staticMenuPixmap;
- }
- break;
- case Close:
- pm = staticClosePixmap;
- break;
- case Maximize:
- pm = staticMaximizePixmap;
- break;
- case Normalize:
- pm = staticNormalizePixmap;
- break;
- case Minimize:
- pm = staticMinimizePixmap;
- break;
- default:
- break;
- }
- return *pm;
-#endif
-}
-
-/*!
- \fn int QDecorationDefault::titleBarHeight(const QWidget *widget)
-
- Returns the title bar height in pixels for the given \a widget. It is the
- greater of 20, or the sum of the application font's line spacing value
- plus a border width fudge factor.
-*/
-int QDecorationDefault::titleBarHeight(const QWidget *)
-{
- return qMax(20, QApplication::fontMetrics().height() + BORDER_WIDTH);
-}
-
-/*!
- Returns the region specified by \a decorationRegion for the
- top-level \a widget. \a rect specifies the rectangle the decoration
- wraps. The value of \a decorationRegion is a combination of the
- bitmask values of enum DecorationRegion.
- */
-QRegion QDecorationDefault::region(const QWidget *widget,
- const QRect &rect,
- int decorationRegion)
-{
- Qt::WindowFlags flags = widget->windowFlags();
- bool hasBorder = !widget->isMaximized();
- bool hasTitle = flags & Qt::WindowTitleHint;
- bool hasSysMenu = flags & Qt::WindowSystemMenuHint;
- bool hasContextHelp = flags & Qt::WindowContextHelpButtonHint;
- bool hasMinimize = flags & Qt::WindowMinimizeButtonHint;
- bool hasMaximize = flags & Qt::WindowMaximizeButtonHint;
- int state = widget->windowState();
- bool isMinimized = state & Qt::WindowMinimized;
- bool isMaximized = state & Qt::WindowMaximized;
-
- int titleHeight = hasTitle ? titleBarHeight(widget) : 0;
- int bw = hasBorder ? BORDER_WIDTH : 0;
- int bbw = hasBorder ? BOTTOM_BORDER_WIDTH : 0;
-
- QRegion region;
- switch (decorationRegion) {
- case All: {
- QRect r(rect.left() - bw,
- rect.top() - titleHeight - bw,
- rect.width() + 2 * bw,
- rect.height() + titleHeight + bw + bbw);
- region = r;
- region -= rect;
- }
- break;
-
- case Title: {
- QRect r(rect.left()
- + (hasSysMenu ? menu_width : 0),
- rect.top() - titleHeight,
- rect.width()
- - (hasSysMenu ? menu_width : 0)
- - close_width
- - (hasMaximize ? maximize_width : 0)
- - (hasMinimize ? minimize_width : 0)
- - (hasContextHelp ? help_width : 0),
-
- titleHeight);
- if (r.width() > 0)
- region = r;
- }
- break;
-
- case Top: {
- QRect r(rect.left() + CORNER_GRAB,
- rect.top() - titleHeight - bw,
- rect.width() - 2 * CORNER_GRAB,
- bw);
- region = r;
- }
- break;
-
- case Left: {
- QRect r(rect.left() - bw,
- rect.top() - titleHeight + CORNER_GRAB,
- bw,
- rect.height() + titleHeight - 2 * CORNER_GRAB);
- region = r;
- }
- break;
-
- case Right: {
- QRect r(rect.right() + 1,
- rect.top() - titleHeight + CORNER_GRAB,
- bw,
- rect.height() + titleHeight - 2 * CORNER_GRAB);
- region = r;
- }
- break;
-
- case Bottom: {
- QRect r(rect.left() + CORNER_GRAB,
- rect.bottom() + 1,
- rect.width() - 2 * CORNER_GRAB,
- bw);
- region = r;
- }
- break;
-
- case TopLeft: {
- QRect r1(rect.left() - bw,
- rect.top() - bw - titleHeight,
- CORNER_GRAB + bw,
- bw);
-
- QRect r2(rect.left() - bw,
- rect.top() - bw - titleHeight,
- bw,
- CORNER_GRAB + bw);
-
- region = QRegion(r1) + r2;
- }
- break;
-
- case TopRight: {
- QRect r1(rect.right() - CORNER_GRAB,
- rect.top() - bw - titleHeight,
- CORNER_GRAB + bw,
- bw);
-
- QRect r2(rect.right() + 1,
- rect.top() - bw - titleHeight,
- bw,
- CORNER_GRAB + bw);
-
- region = QRegion(r1) + r2;
- }
- break;
-
- case BottomLeft: {
- QRect r1(rect.left() - bw,
- rect.bottom() + 1,
- CORNER_GRAB + bw,
- bw);
-
- QRect r2(rect.left() - bw,
- rect.bottom() - CORNER_GRAB,
- bw,
- CORNER_GRAB + bw);
- region = QRegion(r1) + r2;
- }
- break;
-
- case BottomRight: {
- QRect r1(rect.right() - CORNER_GRAB,
- rect.bottom() + 1,
- CORNER_GRAB + bw,
- bw);
-
- QRect r2(rect.right() + 1,
- rect.bottom() - CORNER_GRAB,
- bw,
- CORNER_GRAB + bw);
- region = QRegion(r1) + r2;
- }
- break;
-
- case Menu: {
- if (hasSysMenu) {
- region = QRect(rect.left(), rect.top() - titleHeight,
- menu_width, titleHeight);
- }
- }
- break;
-
- case Help: {
- if (hasContextHelp) {
- QRect r(rect.right()
- - close_width
- - (hasMaximize ? maximize_width : 0)
- - (hasMinimize ? minimize_width : 0)
- - help_width + 1, rect.top() - titleHeight,
- help_width, titleHeight);
- if (r.left() > rect.left() + titleHeight)
- region = r;
- }
- }
- break;
-
-
- case Minimize: {
- if (hasMinimize && !isMinimized) {
- QRect r(rect.right() - close_width
- - (hasMaximize ? maximize_width : 0)
- - minimize_width + 1, rect.top() - titleHeight,
- minimize_width, titleHeight);
- if (r.left() > rect.left() + titleHeight)
- region = r;
- }
- }
- break;
-
- case Maximize: {
- if (hasMaximize && !isMaximized) {
- QRect r(rect.right() - close_width - maximize_width + 1,
- rect.top() - titleHeight, maximize_width, titleHeight);
- if (r.left() > rect.left() + titleHeight)
- region = r;
- }
- }
- break;
-
- case Normalize: {
- if (hasMinimize && isMinimized) {
- QRect r(rect.right() - close_width
- - (hasMaximize ? maximize_width : 0)
- - minimize_width + 1, rect.top() - titleHeight,
- minimize_width, titleHeight);
- if (r.left() > rect.left() + titleHeight)
- region = r;
- } else if (hasMaximize && isMaximized) {
- QRect r(rect.right() - close_width - maximize_width + 1,
- rect.top() - titleHeight, maximize_width, titleHeight);
- if (r.left() > rect.left() + titleHeight)
- region = r;
- }
- }
- break;
-
- case Close: {
- QRect r(rect.right() - close_width + 1, rect.top() - titleHeight,
- close_width, titleHeight);
- if (r.left() > rect.left() + titleHeight)
- region = r;
- }
- break;
-
- default: {
- int i = 1;
- while (i) {
- if (i & decorationRegion)
- region += this->region(widget, rect, i);
- i <<= 1;
- }
- }
- break;
- }
-
- return region;
-}
-
-/*!
- Paints the border and title decoration for the top-level \a widget
- using the \a painter provided and the decoration \a state. The value
- of \a decorationRegion is a combination of the bitmask values of
- enum DecorationRegion.
-
- Note that Qt for Embedded Linux expects this function to return true if any of
- the widget's decorations are repainted; otherwise it returns false.
- */
-bool QDecorationDefault::paint(QPainter *painter,
- const QWidget *widget,
- int decorationRegion,
- DecorationState state)
-{
- if (decorationRegion == None)
- return false;
-
- const QRect titleRect = QDecoration::region(widget, Title).boundingRect();
- const QPalette pal = QApplication::palette();
- int titleHeight = titleRect.height();
- int titleWidth = titleRect.width();
- QRegion oldClipRegion = painter->clipRegion();
-
-
- Qt::WindowFlags flags = widget->windowFlags();
- bool hasBorder = !widget->isMaximized();
- bool hasTitle = flags & Qt::WindowTitleHint;
- bool hasSysMenu = flags & Qt::WindowSystemMenuHint;
- bool hasContextHelp = flags & Qt::WindowContextHelpButtonHint;
- bool hasMinimize = flags & Qt::WindowMinimizeButtonHint;
- bool hasMaximize = flags & Qt::WindowMaximizeButtonHint;
-
- bool paintAll = (decorationRegion == int(All));
- bool handled = false;
-
- bool porterDuff = painter->paintEngine()->hasFeature(QPaintEngine::PorterDuff);
-
- if ((paintAll || decorationRegion & Borders) && state == Normal && hasBorder) {
- if (hasTitle) { // reduce flicker
- QRect rect(widget->rect());
- QRect r(rect.left(), rect.top() - titleHeight,
- rect.width(), titleHeight);
- painter->setClipRegion(oldClipRegion - r);
- }
- QRect br = QDecoration::region(widget).boundingRect();
- if (porterDuff)
- painter->setCompositionMode(QPainter::CompositionMode_Source);
- qDrawWinPanel(painter, br.x(), br.y(), br.width(),
- br.height(), pal, false,
- &pal.brush(QPalette::Window));
- if (porterDuff)
- painter->setCompositionMode(QPainter::CompositionMode_SourceOver);
- handled |= true;
- }
-
- if ((paintAll || decorationRegion & Title && titleWidth > 0) && state == Normal && hasTitle) {
- painter->setClipRegion(oldClipRegion);
- QBrush titleBrush;
- QPen titlePen;
-
- if (widget == qApp->activeWindow()) {
- titleBrush = pal.brush(QPalette::Highlight);
- titlePen = pal.color(QPalette::HighlightedText);
- } else {
- titleBrush = pal.brush(QPalette::Window);
- titlePen = pal.color(QPalette::Text);
- }
-
- if (porterDuff)
- painter->setCompositionMode(QPainter::CompositionMode_Source);
- qDrawShadePanel(painter,
- titleRect.x(), titleRect.y(), titleRect.width(), titleRect.height(),
- pal, true, 1, &titleBrush);
- if (porterDuff)
- painter->setCompositionMode(QPainter::CompositionMode_SourceOver);
-
- painter->setPen(titlePen);
- painter->drawText(titleRect.x() + 4, titleRect.y(),
- titleRect.width() - 8, titleRect.height(),
- Qt::AlignVCenter, windowTitleFor(widget));
- handled |= true;
- }
-
- if (state != Hover) {
- painter->setClipRegion(oldClipRegion);
- if ((paintAll || decorationRegion & Menu) && hasSysMenu) {
- paintButton(painter, widget, Menu, state, pal);
- handled |= true;
- }
-
- if ((paintAll || decorationRegion & Help) && hasContextHelp) {
- paintButton(painter, widget, Help, state, pal);
- handled |= true;
- }
-
- if ((paintAll || decorationRegion & Minimize) && hasMinimize) {
- paintButton(painter, widget, Minimize, state, pal);
- handled |= true;
- }
-
- if ((paintAll || decorationRegion & Maximize) && hasMaximize) {
- paintButton(painter, widget,
- ((widget->windowState() & Qt::WindowMaximized)? Normalize : Maximize),
- state, pal);
- handled |= true;
- }
-
- if (paintAll || decorationRegion & Close) {
- paintButton(painter, widget, Close, state, pal);
- handled |= true;
- }
- }
- return handled;
-}
-
-/*!
- \fn void QDecorationDefault::paintButton(QPainter *painter, const
- QWidget *widget, int buttonRegion, DecorationState state,
- const QPalette &palette)
-
- Paints a region of the top-level \a widget. The region is
- painted in the specified decoration \a state using the
- \a painter and \a palette provided. The region to be painted is specified
- by \a buttonRegion, which is a combination of the bitmask values of
- DecorationRegion. If the value of \a buttonRegion is one of \e Help,
- \e Menu, \e Close, \e Minimize, \e Maximize, and \e Normalize, the
- button pixmap for that region is painted.
-
- \sa pixmapFor()
- */
-void QDecorationDefault::paintButton(QPainter *painter,
- const QWidget *widget,
- int buttonRegion,
- DecorationState state,
- const QPalette &pal)
-{
- int xoff = 2;
- int yoff = 2;
-
- const QPixmap pm = pixmapFor(widget, buttonRegion, xoff, yoff);
- QRect brect(QDecoration::region(widget, buttonRegion).boundingRect());
- bool porterDuff = painter->paintEngine()->hasFeature(QPaintEngine::PorterDuff);
-
- if (state & QDecoration::Pressed) {
- if (porterDuff)
- painter->setCompositionMode(QPainter::CompositionMode_Source);
- qDrawWinPanel(painter, brect, pal, true, &pal.brush(QPalette::Window));
- if (porterDuff)
- painter->setCompositionMode(QPainter::CompositionMode_SourceOver);
- ++xoff;
- ++yoff;
- } else {
- painter->fillRect(brect, pal.brush(QPalette::Window));
- }
-
- if (!pm.isNull())
- painter->drawPixmap(brect.x() + xoff, brect.y() + yoff, pm);
-}
-
-extern QString qt_setWindowTitle_helperHelper(const QString&, const QWidget*);
-
-/*!
- \internal
- */
-QString QDecorationDefault::windowTitleFor(const QWidget *widget) const
-{
- return qt_setWindowTitle_helperHelper(widget->windowTitle(), widget);
-}
-
-#endif // QT_NO_QWS_DECORATION_DEFAULT
-
-QT_END_NAMESPACE
diff --git a/src/gui/embedded/qdecorationdefault_qws.h b/src/gui/embedded/qdecorationdefault_qws.h
deleted file mode 100644
index 5e844b512d..0000000000
--- a/src/gui/embedded/qdecorationdefault_qws.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDECORATIONDEFAULT_QWS_H
-#define QDECORATIONDEFAULT_QWS_H
-
-#include <QtGui/qdecoration_qws.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#if !defined(QT_NO_QWS_DECORATION_DEFAULT) || defined(QT_PLUGIN)
-
-#define CORNER_GRAB 16
-#define BORDER_WIDTH 4
-#define BOTTOM_BORDER_WIDTH BORDER_WIDTH
-
-class Q_GUI_EXPORT QDecorationDefault : public QDecoration
-{
-public:
- QDecorationDefault();
- virtual ~QDecorationDefault();
-
- virtual QRegion region(const QWidget *widget, const QRect &rect, int decorationRegion = All);
- virtual bool paint(QPainter *painter, const QWidget *widget, int decorationRegion = All,
- DecorationState state = Normal);
-
-protected:
- virtual int titleBarHeight(const QWidget *widget);
-
- virtual void paintButton(QPainter *painter, const QWidget *widget, int buttonRegion,
- DecorationState state, const QPalette &pal);
- virtual QPixmap pixmapFor(const QWidget *widget, int decorationRegion, int &xoff, int &yoff);
- virtual const char **xpmForRegion(int region);
-
- QString windowTitleFor(const QWidget *widget) const;
-
- int menu_width;
- int help_width;
- int close_width;
- int minimize_width;
- int maximize_width;
- int normalize_width;
-
-private:
- static QPixmap *staticHelpPixmap;
- static QPixmap *staticMenuPixmap;
- static QPixmap *staticClosePixmap;
- static QPixmap *staticMinimizePixmap;
- static QPixmap *staticMaximizePixmap;
- static QPixmap *staticNormalizePixmap;
-
-};
-
-
-QT_END_NAMESPACE
-#endif // QT_NO_QWS_DECORATION_DEFAULT
-QT_END_HEADER
-
-#endif // QDECORATIONDEFAULT_QWS_H
diff --git a/src/gui/embedded/qdecorationfactory_qws.cpp b/src/gui/embedded/qdecorationfactory_qws.cpp
deleted file mode 100644
index 96ab49c4f1..0000000000
--- a/src/gui/embedded/qdecorationfactory_qws.cpp
+++ /dev/null
@@ -1,156 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qdecorationfactory_qws.h"
-#include "qdecorationplugin_qws.h"
-#include "private/qfactoryloader_p.h"
-#include "qmutex.h"
-
-#include "qapplication.h"
-#include "qdecorationdefault_qws.h"
-#include "qdecorationwindows_qws.h"
-#include "qdecorationstyled_qws.h"
-
-QT_BEGIN_NAMESPACE
-
-#ifndef QT_NO_LIBRARY
-Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
- (QDecorationFactoryInterface_iid,
- QLatin1String("/decorations"), Qt::CaseInsensitive))
-#endif
-
-
-
-/*!
- \class QDecorationFactory
- \ingroup qws
- \ingroup appearance
-
- \brief The QDecorationFactory class creates window decorations in
- Qt for Embedded Linux.
-
- Note that this class is only available in \l{Qt for Embedded Linux}.
-
- QDecorationFactory is used to detect and instantiate the available
- decorations, allowing \l{Qt for Embedded Linux} to load the preferred
- decoration into the application at runtime. The create() function
- returns a QDecoration object representing the decoration
- identified by a given key. The valid keys (i.e. the supported
- decorations) can be retrieved using the keys() function.
-
- \l{Qt for Embedded Linux} provides three built-in decorations: \c Default,
- \c Styled and \c Windows. In addition, custom decorations can be
- added using Qt's \l {How to Create Qt Plugins}{plugin mechanism},
- i.e. by subclassing the QDecoration class and creating a mouse
- driver plugin (QDecorationPlugin).
-
- \sa QDecoration, QDecorationPlugin
-*/
-
-/*!
- Creates the decoration specified by the given \a key. Note that
- the keys are case-insensitive.
-
- \sa keys()
-*/
-
-QDecoration *QDecorationFactory::create(const QString& key)
-{
- QDecoration *ret = 0;
- QString decoration = key.toLower();
-#ifndef QT_NO_QWS_DECORATION_DEFAULT
- if (decoration == QLatin1String("default"))
- ret = new QDecorationDefault;
- else
-#endif
-#ifndef QT_NO_QWS_DECORATION_WINDOWS
- if (decoration == QLatin1String("windows"))
- ret = new QDecorationWindows;
- else
-#endif
-#ifndef QT_NO_QWS_DECORATION_STYLED
- if (decoration == QLatin1String("styled"))
- ret = new QDecorationStyled;
- else
-#endif
- { } // Keep these here - they make the #ifdefery above work
-#ifndef QT_NO_LIBRARY
- if (!ret) {
- if (QDecorationFactoryInterface *factory = qobject_cast<QDecorationFactoryInterface*>(loader()->instance(decoration))) {
- ret = factory->create(decoration);
- }
- }
-#endif
- return ret;
-}
-
-/*!
- Returns the list of valid keys, i.e., the available decorations.
-
- \sa create()
-*/
-QStringList QDecorationFactory::keys()
-{
- QStringList list;
-#ifndef QT_NO_QWS_DECORATION_STYLED
- list << QLatin1String("Styled");
-#endif
-#ifndef QT_NO_QWS_DECORATION_DEFAULT
- list << QLatin1String("Default");
-#endif
-#ifndef QT_NO_QWS_DECORATION_WINDOWS
- list << QLatin1String("Windows");
-#endif
-
-#if !defined(Q_OS_WIN32) || defined(QT_MAKEDLL)
-#ifndef QT_NO_LIBRARY
- QStringList plugins = loader()->keys();
- for (int i = 0; i < plugins.size(); ++i) {
- if (!list.contains(plugins.at(i)))
- list += plugins.at(i);
- }
-#endif //QT_NO_LIBRARY
-#endif //QT_MAKEDLL
-
- return list;
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/embedded/qdecorationfactory_qws.h b/src/gui/embedded/qdecorationfactory_qws.h
deleted file mode 100644
index bc0605c578..0000000000
--- a/src/gui/embedded/qdecorationfactory_qws.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDECORATIONFACTORY_QWS_H
-#define QDECORATIONFACTORY_QWS_H
-
-#include <QtCore/qstringlist.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QDecoration;
-
-class Q_GUI_EXPORT QDecorationFactory
-{
-public:
- static QStringList keys();
- static QDecoration *create(const QString&);
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QDECORATIONFACTORY_QWS_H
diff --git a/src/gui/embedded/qdecorationplugin_qws.cpp b/src/gui/embedded/qdecorationplugin_qws.cpp
deleted file mode 100644
index 042189b308..0000000000
--- a/src/gui/embedded/qdecorationplugin_qws.cpp
+++ /dev/null
@@ -1,116 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qdecorationplugin_qws.h"
-#include "qdecoration_qws.h"
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \class QDecorationPlugin
- \ingroup qws
- \ingroup plugins
-
- \brief The QDecorationPlugin class is an abstract base class for
- window decoration plugins in Qt for Embedded Linux.
-
- Note that this class is only available in \l{Qt for Embedded Linux}.
-
- \l{Qt for Embedded Linux} provides three ready-made decoration styles: \c
- Default, \c Styled and \c Windows. Custom decorations can be
- implemented by subclassing the QDecoration class and creating a
- decoration plugin.
-
- A decoration plugin can be created by subclassing
- QDecorationPlugin and implementing the pure virtual keys() and
- create() functions. By exporting the derived class using the
- Q_EXPORT_PLUGIN2() macro, the default implementation of the
- QDecorationFactory class will automatically detect the plugin and
- load the driver into the application at run-time. See \l{How to
- Create Qt Plugins} for details.
-
- To actually apply a decoration, use the
- QApplication::qwsSetDecoration() function.
-
- \sa QDecoration, QDecorationFactory
-*/
-
-/*!
- \fn QStringList QDecorationPlugin::keys() const
-
- Returns the list of valid keys, i.e., the decorations supported by
- this plugin.
-
- \sa create()
-*/
-
-/*!
- \fn QDecoration *QDecorationPlugin::create(const QString &key)
-
- Creates a decoration matching the given \a key. Note that keys are
- case-insensitive.
-
- \sa keys()
-*/
-
-/*!
- Constructs a decoration plugin with the given \a parent.
-
- Note that this constructor is invoked automatically by the
- Q_EXPORT_PLUGIN2() macro, so there is no need for calling it
- explicitly.
-*/
-QDecorationPlugin::QDecorationPlugin(QObject *parent)
- : QObject(parent)
-{
-}
-
-/*!
- Destroys the decoration plugin.
-
- Note that Qt destroys a plugin automatically when it is no longer
- used, so there is no need for calling the destructor explicitly.
-*/
-QDecorationPlugin::~QDecorationPlugin()
-{
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/embedded/qdecorationplugin_qws.h b/src/gui/embedded/qdecorationplugin_qws.h
deleted file mode 100644
index b94bcba0ba..0000000000
--- a/src/gui/embedded/qdecorationplugin_qws.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDECORATIONPLUGIN_QWS_H
-#define QDECORATIONPLUGIN_QWS_H
-
-#include <QtCore/qplugin.h>
-#include <QtCore/qfactoryinterface.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QDecoration;
-
-struct Q_GUI_EXPORT QDecorationFactoryInterface : public QFactoryInterface
-{
- virtual QDecoration *create(const QString &key) = 0;
-};
-
-#define QDecorationFactoryInterface_iid "com.trolltech.Qt.QDecorationFactoryInterface"
-Q_DECLARE_INTERFACE(QDecorationFactoryInterface, QDecorationFactoryInterface_iid)
-
-class Q_GUI_EXPORT QDecorationPlugin : public QObject, public QDecorationFactoryInterface
-{
- Q_OBJECT
- Q_INTERFACES(QDecorationFactoryInterface:QFactoryInterface)
- public:
- explicit QDecorationPlugin(QObject *parent = 0);
- ~QDecorationPlugin();
-
- virtual QStringList keys() const = 0;
- virtual QDecoration *create(const QString &key) = 0;
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QDECORATIONPLUGIN_QWS_H
diff --git a/src/gui/embedded/qdecorationstyled_qws.cpp b/src/gui/embedded/qdecorationstyled_qws.cpp
deleted file mode 100644
index 61f11f67e2..0000000000
--- a/src/gui/embedded/qdecorationstyled_qws.cpp
+++ /dev/null
@@ -1,313 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qapplication.h>
-#include <qwidget.h>
-#include <qpainter.h>
-#include <qdrawutil.h>
-#include "qdecorationstyled_qws.h"
-#include "qstyle.h"
-#include "qstyleoption.h"
-#include "qpaintengine.h"
-
-QT_BEGIN_NAMESPACE
-
-#if !defined(QT_NO_QWS_DECORATION_STYLED) || defined(QT_PLUGIN)
-
-QDecorationStyled::QDecorationStyled()
- : QDecorationDefault()
-{
-}
-
-QDecorationStyled::~QDecorationStyled()
-{
-}
-
-int QDecorationStyled::titleBarHeight(const QWidget *widget)
-{
- QStyleOptionTitleBar opt;
- opt.subControls = QStyle::SC_TitleBarLabel
- | QStyle::SC_TitleBarSysMenu
- | QStyle::SC_TitleBarNormalButton
- | QStyle::SC_TitleBarContextHelpButton
- | QStyle::SC_TitleBarMinButton
- | QStyle::SC_TitleBarMaxButton
- | QStyle::SC_TitleBarCloseButton;
- opt.titleBarFlags = widget->windowFlags();
- opt.direction = QApplication::layoutDirection();
- opt.text = windowTitleFor(widget);
- opt.icon = widget->windowIcon();
- opt.rect = widget->rect();
-
- QStyle *style = QApplication::style();
- if (!style)
- return 18;
-
- return style->pixelMetric(QStyle::PM_TitleBarHeight, &opt, 0);
-}
-
-bool QDecorationStyled::paint(QPainter *painter, const QWidget *widget, int decorationRegion,
- DecorationState state)
-{
- if (decorationRegion == None)
- return false;
-
- bool isActive = (widget == qApp->activeWindow());
- QPalette pal = qApp->palette();
- //ideally, the difference between Active and Inactive should be enough, so we shouldn't need to test this
- if (!isActive) {
- //pal.setCurrentColorGroup(QPalette::Disabled); //Can't do this either, because of palette limitations
- //copied from Q3TitleBar:
- pal.setColor(QPalette::Inactive, QPalette::Highlight,
- pal.color(QPalette::Inactive, QPalette::Dark));
- pal.setColor(QPalette::Inactive, QPalette::Base,
- pal.color(QPalette::Inactive, QPalette::Dark));
- pal.setColor(QPalette::Inactive, QPalette::HighlightedText,
- pal.color(QPalette::Inactive, QPalette::Window));
- }
-
- Qt::WindowFlags flags = widget->windowFlags();
- bool hasBorder = !widget->isMaximized();
- bool hasTitle = flags & Qt::WindowTitleHint;
- bool hasSysMenu = flags & Qt::WindowSystemMenuHint;
- bool hasContextHelp = flags & Qt::WindowContextHelpButtonHint;
- bool hasMinimize = flags & Qt::WindowMinimizeButtonHint;
- bool hasMaximize = flags & Qt::WindowMaximizeButtonHint;
-
- bool paintAll = (DecorationRegion(decorationRegion) == All);
- bool handled = false;
-
- QStyle *style = QApplication::style();
-
- // In the case of a borderless title bar, the title bar must be expanded one
- // borderWidth to the left, right and up.
- bool noTitleBorder = style->styleHint(QStyle::SH_TitleBar_NoBorder, 0, widget);
- int borderWidth = style->pixelMetric(QStyle::PM_MDIFrameWidth, 0, 0);
- int titleHeight = titleBarHeight(widget) + (noTitleBorder ? borderWidth : 0);
- int titleExtra = noTitleBorder ? borderWidth : 0;
-
- if ((paintAll || decorationRegion & Borders) && state == Normal && hasBorder) {
- QRegion newClip = painter->clipRegion();
- if (hasTitle) { // reduce flicker
- QRect rect(widget->rect());
- QRect r(rect.left() - titleExtra, rect.top() - titleHeight,
- rect.width() + 2 * titleExtra, titleHeight);
- newClip -= r;
- }
- if (!newClip.isEmpty()) {
- QRect br = QDecoration::region(widget).boundingRect();
- painter->save();
- painter->setClipRegion(newClip);
-
- QStyleOptionFrame opt;
- opt.palette = pal;
- opt.rect = br;
- opt.lineWidth = borderWidth;
-
- if (isActive)
- opt.state |= QStyle::State_Active;
- bool porterDuff = painter->paintEngine()->hasFeature(QPaintEngine::PorterDuff);
- if (porterDuff)
- painter->setCompositionMode(QPainter::CompositionMode_Source);
- painter->fillRect(br, pal.window());
- if (porterDuff)
- painter->setCompositionMode(QPainter::CompositionMode_SourceOver);
- style->drawPrimitive(QStyle::PE_FrameWindow, &opt, painter, 0);
- painter->restore();
-
- decorationRegion &= (~Borders);
- handled |= true;
- }
- }
-
- if (hasTitle) {
- painter->save();
-
- QStyleOptionTitleBar opt;
- opt.subControls = (decorationRegion & Title
- ? QStyle::SC_TitleBarLabel : QStyle::SubControl(0))
- | (decorationRegion & Menu
- ? QStyle::SC_TitleBarSysMenu : QStyle::SubControl(0))
- | (decorationRegion & Help
- ? QStyle::SC_TitleBarContextHelpButton : QStyle::SubControl(0))
- | (decorationRegion & Minimize
- ? QStyle::SC_TitleBarMinButton : QStyle::SubControl(0))
- | (decorationRegion & Maximize
- ? QStyle::SC_TitleBarMaxButton : QStyle::SubControl(0))
- | (decorationRegion & (Minimize | Maximize)
- ? QStyle::SC_TitleBarNormalButton : QStyle::SubControl(0))
- | (decorationRegion & Close
- ? QStyle::SC_TitleBarCloseButton : QStyle::SubControl(0));
- opt.titleBarFlags = widget->windowFlags();
- opt.titleBarState = widget->windowState();
- if (isActive)
- opt.titleBarState |= QStyle::State_Active;
- opt.text = windowTitleFor(widget);
- opt.icon = widget->windowIcon();
- opt.palette = pal;
- opt.rect = QRect(widget->rect().x() - titleExtra, -titleHeight,
- widget->rect().width() + 2 * titleExtra, titleHeight);
-
- if (paintAll) {
- painter->setClipRegion(opt.rect);
- } else {
- const QRect widgetRect = widget->rect();
- QRegion newClip = opt.rect;
- if (!(decorationRegion & Menu) && hasSysMenu)
- newClip -= region(widget, widgetRect, Menu);
- if (!(decorationRegion & Title) && hasTitle)
- newClip -= region(widget, widgetRect, Title);
- if (!(decorationRegion & Help) && hasContextHelp)
- newClip -= region(widget, widgetRect, Help);
- if (!(decorationRegion & Minimize) && hasMinimize)
- newClip -= region(widget, widgetRect, Minimize);
- if (!(decorationRegion & Maximize) && hasMaximize)
- newClip -= region(widget, widgetRect, Maximize);
- if (!(decorationRegion & (Minimize | Maximize)) && (hasMaximize | hasMinimize))
- newClip -= region(widget, widgetRect, Normal);
- if (!(decorationRegion & Close))
- newClip -= region(widget, widgetRect, Close);
- painter->setClipRegion(newClip);
- }
-
- if (state == Pressed)
- opt.activeSubControls = opt.subControls;
-
- style->drawComplexControl(QStyle::CC_TitleBar, &opt, painter, 0);
- painter->restore();
-
- decorationRegion &= ~(Title | Menu | Help | Normalize | Minimize | Maximize | Close);
- handled |= true;
- }
-
- return handled;
-}
-
-QRegion QDecorationStyled::region(const QWidget *widget, const QRect &rect, int decorationRegion)
-{
- QStyle *style = QApplication::style();
-
- // In the case of a borderless title bar, the title bar must be expanded one
- // borderWidth to the left, right and up.
- bool noTitleBorder = style->styleHint(QStyle::SH_TitleBar_NoBorder, 0, widget);
- int borderWidth = style->pixelMetric(QStyle::PM_MDIFrameWidth, 0, 0);
- int titleHeight = titleBarHeight(widget) + (noTitleBorder ? borderWidth : 0);
- int titleExtra = noTitleBorder ? borderWidth : 0;
-
- QRect inside = QRect(rect.x() - titleExtra, rect.top() - titleHeight,
- rect.width() + 2 * titleExtra, titleHeight);
-
- Qt::WindowFlags flags = widget->windowFlags();
- bool hasSysMenu = flags & Qt::WindowSystemMenuHint;
- bool hasContextHelp = flags & Qt::WindowContextHelpButtonHint;
- bool hasMinimize = flags & Qt::WindowMinimizeButtonHint;
- bool hasMaximize = flags & Qt::WindowMaximizeButtonHint;
-
- QStyleOptionTitleBar opt;
- opt.subControls = QStyle::SC_TitleBarLabel
- | QStyle::SC_TitleBarSysMenu
- | QStyle::SC_TitleBarNormalButton
- | QStyle::SC_TitleBarMinButton
- | QStyle::SC_TitleBarMaxButton
- | QStyle::SC_TitleBarCloseButton;
- opt.titleBarFlags = widget->windowFlags();
- opt.direction = QApplication::layoutDirection();
- opt.text = windowTitleFor(widget);
- opt.icon = widget->windowIcon();
- opt.rect = inside;
-
- QRegion region;
- switch (decorationRegion) {
- case Title:
- region = style->subControlRect(QStyle::CC_TitleBar, &opt,
- QStyle::SC_TitleBarLabel, 0);
- break;
- case Menu:
- if (hasSysMenu)
- region = style->subControlRect(QStyle::CC_TitleBar, &opt,
- QStyle::SC_TitleBarSysMenu, 0);
- break;
- case Help:
- if (hasContextHelp)
- region = style->subControlRect(QStyle::CC_TitleBar, &opt,
- QStyle::SC_TitleBarContextHelpButton,
- 0);
- break;
- case Normalize:
- if (hasMaximize | hasMinimize)
- region = style->subControlRect(QStyle::CC_TitleBar, &opt,
- QStyle::SC_TitleBarNormalButton,
- 0);
- break;
- case Minimize:
- if (hasMinimize)
- region = style->subControlRect(QStyle::CC_TitleBar, &opt,
- QStyle::SC_TitleBarMinButton,
- 0);
- break;
- case Maximize:
- if (hasMaximize)
- region = style->subControlRect(QStyle::CC_TitleBar, &opt,
- QStyle::SC_TitleBarMaxButton,
- 0);
- break;
- case Close:
- region = style->subControlRect(QStyle::CC_TitleBar, &opt,
- QStyle::SC_TitleBarCloseButton, 0);
- break;
-
- default:
- region = QDecorationDefault::region(widget, rect, decorationRegion);
- }
-
- opt.rect = QRect(rect.x() - titleExtra, rect.top() - titleHeight,
- rect.width() + 2 * titleExtra,
- rect.height() + titleHeight + titleExtra);
-
- QStyleHintReturnMask mask;
- style->styleHint(QStyle::SH_WindowFrame_Mask, &opt, 0, &mask);
-
- return (mask.region.isEmpty() ? region : (region & mask.region));
-}
-
-#endif // QT_NO_QWS_DECORATION_STYLED
-
-QT_END_NAMESPACE
diff --git a/src/gui/embedded/qdecorationstyled_qws.h b/src/gui/embedded/qdecorationstyled_qws.h
deleted file mode 100644
index 1d5d3c564f..0000000000
--- a/src/gui/embedded/qdecorationstyled_qws.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDECORATIONSTYLED_QWS_H
-#define QDECORATIONSTYLED_QWS_H
-
-#include <QtGui/qdecorationdefault_qws.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#if !defined(QT_NO_QWS_DECORATION_STYLED) || defined(QT_PLUGIN)
-
-class Q_GUI_EXPORT QDecorationStyled : public QDecorationDefault
-{
-public:
- QDecorationStyled();
- virtual ~QDecorationStyled();
-
- QRegion region(const QWidget *widget, const QRect &rect, int decorationRegion = All);
- bool paint(QPainter *painter, const QWidget *widget, int decorationRegion = All,
- DecorationState state = Normal);
- int titleBarHeight(const QWidget *widget);
-};
-
-#endif // QT_NO_QWS_DECORATION_STYLED
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QDECORATIONSTYLED_QWS_H
diff --git a/src/gui/embedded/qdecorationwindows_qws.cpp b/src/gui/embedded/qdecorationwindows_qws.cpp
deleted file mode 100644
index 3de3783beb..0000000000
--- a/src/gui/embedded/qdecorationwindows_qws.cpp
+++ /dev/null
@@ -1,407 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qapplication.h>
-#include <qwidget.h>
-#include <qpainter.h>
-#include <qdrawutil.h>
-#include "qdecorationwindows_qws.h"
-
-QT_BEGIN_NAMESPACE
-
-#if !defined(QT_NO_QWS_DECORATION_WINDOWS) || defined(QT_PLUGIN)
-
-#ifndef QT_NO_IMAGEFORMAT_XPM
-
-/* XPM */
-static const char * const win_close_xpm[] = {
-"16 16 4 1",
-" s None c None",
-". c #000000",
-"X c #FFFFFF",
-"Y c #707070",
-" ",
-" ",
-" ",
-" Y. .Y ",
-" .. .. ",
-" .. .. ",
-" .YY. ",
-" Y..Y ",
-" .YY. ",
-" .. .. ",
-" .. .. ",
-" Y. .Y ",
-" ",
-" ",
-" ",
-" "};
-
-static const char * const win_help_xpm[] = {
-"16 16 3 1",
-" s None c None",
-". c #ffffff",
-"X c #000000",
-" ",
-" ",
-" ",
-" XXXXXX ",
-" XX XX ",
-" XX XX ",
-" XX ",
-" XX ",
-" XX ",
-" XX ",
-" ",
-" XX ",
-" XX ",
-" ",
-" ",
-" "};
-
-static const char * const win_maximize_xpm[] = {
-"16 16 4 1",
-" s None c None",
-". c #000000",
-"X c #FFFFFF",
-"Y c #707070",
-" ",
-" ",
-" ",
-" .......... ",
-" .......... ",
-" . . ",
-" . . ",
-" . . ",
-" . . ",
-" . . ",
-" . . ",
-" .......... ",
-" ",
-" ",
-" ",
-" "};
-
-static const char * const win_minimize_xpm[] = {
-"16 16 4 1",
-" s None c None",
-". c #000000",
-"X c #FFFFFF",
-"Y c #707070",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ........ ",
-" ........ ",
-" ",
-" ",
-" ",
-" "};
-
-static const char * const win_normalize_xpm[] = {
-"16 16 4 1",
-" s None c None",
-". c #000000",
-"X c #FFFFFF",
-"Y c #707070",
-" ",
-" ",
-" ......... ",
-" ......... ",
-" . . ",
-" . . ",
-" ......... . ",
-" ......... . ",
-" . . . ",
-" . .... ",
-" . . ",
-" . . ",
-" ......... ",
-" ",
-" ",
-" "};
-
-#endif // QT_NO_IMAGEFORMAT_XPM
-
-
-QDecorationWindows::QDecorationWindows()
- : QDecorationDefault()
-{
- menu_width = 16;
- help_width = 18;
- minimize_width = 18;
- maximize_width = 18;
- close_width = 18;
-}
-
-QDecorationWindows::~QDecorationWindows()
-{
-}
-
-const char **QDecorationWindows::xpmForRegion(int reg)
-{
-#ifdef QT_NO_IMAGEFORMAT_XPM
- Q_UNUSED(reg);
-#else
- switch(reg)
- {
- case Close:
- return (const char **)win_close_xpm;
- case Help:
- return (const char **)win_help_xpm;
- case Minimize:
- return (const char **)win_minimize_xpm;
- case Maximize:
- return (const char **)win_maximize_xpm;
- case Normalize:
- return (const char **)win_normalize_xpm;
- default:
- return QDecorationDefault::xpmForRegion(reg);
- }
-#endif
- return 0;
-}
-
-QRegion QDecorationWindows::region(const QWidget *widget, const QRect &rect, int type)
-{
- Qt::WindowFlags flags = widget->windowFlags();
- bool hasTitle = flags & Qt::WindowTitleHint;
- bool hasSysMenu = flags & Qt::WindowSystemMenuHint;
- bool hasContextHelp = flags & Qt::WindowContextHelpButtonHint;
- bool hasMinimize = flags & Qt::WindowMinimizeButtonHint;
- bool hasMaximize = flags & Qt::WindowMaximizeButtonHint;
- const QFontMetrics fontMetrics = QApplication::fontMetrics();
- int titleHeight = hasTitle ? qMax(20, fontMetrics.height()) : 0;
- int state = widget->windowState();
- bool isMinimized = state & Qt::WindowMinimized;
- bool isMaximized = state & Qt::WindowMaximized;
-
- QRegion region;
- switch (type) {
- case Menu: {
- if (hasSysMenu) {
- region = QRect(rect.left() + 2, rect.top() - titleHeight,
- menu_width, titleHeight);
- }
- }
- break;
-
- case Title: {
- QRect r(rect.left()
- + (hasSysMenu ? menu_width + 4: 0),
- rect.top() - titleHeight,
- rect.width()
- - (hasSysMenu ? menu_width : 0)
- - close_width
- - (hasMaximize ? maximize_width : 0)
- - (hasMinimize ? minimize_width : 0)
- - (hasContextHelp ? help_width : 0)
- - 3,
- titleHeight);
- if (r.width() > 0)
- region = r;
- }
- break;
- case Help: {
- if (hasContextHelp) {
- QRect r(rect.right()
- - close_width
- - (hasMaximize ? maximize_width : 0)
- - (hasMinimize ? minimize_width : 0)
- - help_width - 3, rect.top() - titleHeight,
- help_width, titleHeight);
- if (r.left() > rect.left() + titleHeight)
- region = r;
- }
- }
- break;
-
- case Minimize: {
- if (hasMinimize && !isMinimized) {
- QRect r(rect.right() - close_width
- - (hasMaximize ? maximize_width : 0)
- - minimize_width - 3, rect.top() - titleHeight,
- minimize_width, titleHeight);
- if (r.left() > rect.left() + titleHeight)
- region = r;
- }
- }
- break;
-
- case Maximize: {
- if (hasMaximize && !isMaximized) {
- QRect r(rect.right() - close_width - maximize_width - 3,
- rect.top() - titleHeight, maximize_width, titleHeight);
- if (r.left() > rect.left() + titleHeight)
- region = r;
- }
- }
- break;
-
- case Normalize: {
- if (hasMinimize && isMinimized) {
- QRect r(rect.right() - close_width
- - (hasMaximize ? maximize_width : 0)
- - minimize_width - 3, rect.top() - titleHeight,
- minimize_width, titleHeight);
- if (r.left() > rect.left() + titleHeight)
- region = r;
- } else if (hasMaximize && isMaximized) {
- QRect r(rect.right() - close_width - maximize_width - 3,
- rect.top() - titleHeight, maximize_width, titleHeight);
- if (r.left() > rect.left() + titleHeight)
- region = r;
- }
- }
- break;
-
- case Close: {
- QRect r(rect.right() - close_width - 1, rect.top() - titleHeight,
- close_width, titleHeight);
- if (r.left() > rect.left() + titleHeight)
- region = r;
- }
- break;
-
- default:
- region = QDecorationDefault::region(widget, rect, type);
- break;
- }
-
- return region;
-}
-
-bool QDecorationWindows::paint(QPainter *painter, const QWidget *widget, int decorationRegion,
- DecorationState state)
-{
- if (decorationRegion == None)
- return false;
-
- const QRect titleRect = QDecoration::region(widget, Title).boundingRect();
- const QPalette pal = QApplication::palette();
- QRegion oldClipRegion = painter->clipRegion();
-
- bool paintAll = (decorationRegion == int(All));
- if ((paintAll || decorationRegion & Title && titleRect.width() > 0) && state == Normal
- && (widget->windowFlags() & Qt::WindowTitleHint) ) {
- painter->setClipRegion(oldClipRegion);
- QColor fromBrush, toBrush;
- QPen titlePen;
-
- if (widget == qApp->activeWindow() || qApp->activeWindow() == qApp->activePopupWidget()) {
- fromBrush = pal.color(QPalette::Highlight);
- titlePen = pal.color(QPalette::HighlightedText);
- } else {
- fromBrush = pal.color(QPalette::Window);
- titlePen = pal.color(QPalette::Text);
- }
- toBrush = fromBrush.lighter(300);
-
- painter->setPen(Qt::NoPen);
- QPoint p1(titleRect.x(), titleRect.y() + titleRect.height()/2);
- QPoint p2(titleRect.right(), titleRect.y() + titleRect.height()/2);
- QLinearGradient lg(p1, p2);
- lg.setColorAt(0, fromBrush);
- lg.setColorAt(1, toBrush);
- painter->fillRect(titleRect, lg);
-
- painter->setPen(titlePen);
- painter->drawText(titleRect, Qt::AlignVCenter, windowTitleFor(widget));
- decorationRegion ^= Title;
- }
-
- return QDecorationDefault::paint(painter, widget, decorationRegion, state);
-}
-
-void QDecorationWindows::paintButton(QPainter *painter, const QWidget *widget, int buttonRegion,
- DecorationState state, const QPalette &pal)
-{
- QBrush fromBrush, toBrush;
- QPen titlePen;
-
- if (widget == qApp->activeWindow() || qApp->activeWindow() == qApp->activePopupWidget()) {
- fromBrush = pal.brush(QPalette::Highlight);
- titlePen = pal.color(QPalette::HighlightedText);
- } else {
- fromBrush = pal.brush(QPalette::Window);
- titlePen = pal.color(QPalette::Text);
- }
- toBrush = fromBrush.color().lighter(300);
-
- QRect brect(QDecoration::region(widget, buttonRegion).boundingRect());
- if (buttonRegion != Close && buttonRegion != Menu)
- painter->fillRect(brect, toBrush);
- else
- painter->fillRect(brect.x() - 2, brect.y(), brect.width() + 4, brect.height(),
- buttonRegion == Menu ? fromBrush : toBrush);
-
- int xoff = 1;
- int yoff = 2;
- const QPixmap pm = pixmapFor(widget, buttonRegion, xoff, yoff);
- if (buttonRegion != Menu) {
- if (state & Normal) {
- qDrawWinPanel(painter, brect.x(), brect.y() + 2, brect.width(),
- brect.height() - 4, pal, false, &pal.brush(QPalette::Window));
- } else if (state & Pressed) {
- qDrawWinPanel(painter, brect.x(), brect.y() + 2, brect.width(),
- brect.height() - 4, pal, true, &pal.brush(QPalette::Window));
- ++xoff;
- ++yoff;
- }
- } else {
- xoff = 0;
- yoff = 2;
- }
-
- if (!pm.isNull())
- painter->drawPixmap(brect.x() + xoff, brect.y() + yoff, pm);
-}
-
-#endif // QT_NO_QWS_DECORATION_WINDOWS || QT_PLUGIN
-
-QT_END_NAMESPACE
diff --git a/src/gui/embedded/qdecorationwindows_qws.h b/src/gui/embedded/qdecorationwindows_qws.h
deleted file mode 100644
index 9678582c02..0000000000
--- a/src/gui/embedded/qdecorationwindows_qws.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDECORATIONWINDOWS_QWS_H
-#define QDECORATIONWINDOWS_QWS_H
-
-#include <QtGui/qdecorationdefault_qws.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#if !defined(QT_NO_QWS_DECORATION_WINDOWS) || defined(QT_PLUGIN)
-
-class Q_GUI_EXPORT QDecorationWindows : public QDecorationDefault
-{
-public:
- QDecorationWindows();
- virtual ~QDecorationWindows();
-
- QRegion region(const QWidget *widget, const QRect &rect, int decorationRegion = All);
- bool paint(QPainter *painter, const QWidget *widget, int decorationRegion = All,
- DecorationState state = Normal);
-
-protected:
- void paintButton(QPainter *painter, const QWidget *widget, int buttonRegion,
- DecorationState state, const QPalette &pal);
- const char **xpmForRegion(int reg);
-};
-
-#endif // QT_NO_QWS_DECORATION_WINDOWS
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QDECORATIONWINDOWS_QWS_H
diff --git a/src/gui/embedded/qdirectpainter_qws.cpp b/src/gui/embedded/qdirectpainter_qws.cpp
deleted file mode 100644
index 16df36dcf9..0000000000
--- a/src/gui/embedded/qdirectpainter_qws.cpp
+++ /dev/null
@@ -1,682 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qdirectpainter_qws.h"
-
-#include "qscreen_qws.h"
-#include "private/qobject_p.h"
-#include "private/qapplication_p.h"
-#include "qwsdisplay_qws.h"
-#include "qwidget.h"
-#include "qimage.h"
-#include <qwsevent_qws.h>
-#include <private/qwindowsurface_qws_p.h>
-#include <private/qwsdisplay_qws_p.h>
-
-QT_BEGIN_NAMESPACE
-
-#ifdef Q_WS_QWS
-#ifndef QT_NO_DIRECTPAINTER
-
-/*!
- \class QDirectPainter
- \ingroup painting
- \ingroup qws
-
- \brief The QDirectPainter class provides direct access to the
- underlying hardware in Qt for Embedded Linux.
-
- Note that this class is only available in \l{Qt for Embedded Linux}.
-
- QDirectPainter allows a client application to reserve a region of
- the framebuffer and render directly onto the screen. There are two
- ways of using the QDirectPainter class: You can either reserve a
- region using the provided static functions, or you can instantiate
- an object and make use of its more dynamic API.
-
- \tableofcontents
-
- \section1 Dynamic Allocation
-
- By instantiating a QDirectPainter object using the default
- QDirectPainter::NonReserved surface flag, the client application
- only gets some control over the reserved region, i.e., it can
- still render directly onto the screen but the allocated region may
- change (for example, if a window with a higher focus requests
- parts of the same region). The currently allocated region can be
- retrieved using the allocatedRegion() function, while the
- requestedRegion() function returns the originally reserved
- region.
-
-
- \section1 Static Allocation
-
-
- Using the static approach, the client application gets complete
- control over the reserved region, i.e., the affected region will
- never be modified by the screen driver.
-
- To create a static region, pass the QDirectPainter::Reserved
- surface flag to the constructor. After the reserved region is
- reported through regionChanged(), the allocated region will not
- change, unless setRegion() is called.
-
- If QDirectPainter::ReservedSynchronous is passed to the
- constructor, calls to setRegion() will block until the region is
- reserved, meaning that allocatedRegion() will be available immediately.
- Note that in the current version setRegion() will cause the application
- event loop to be entered, potentially causing reentrancy issues.
-
- \section1 Rendering
-
- To draw on a given region, the application must first get hold of
- a pointer to the framebuffer. In most cases, this pointer can be
- retrieved using the QDirectPainter::frameBuffer() function. But
- note that if the current screen has subscreens, you must query the
- screen driver instead to identify the correct subscreen. A pointer
- to the current screen driver can always be retrieved using the
- static QScreen::instance() function. Then use QScreen's \l
- {QScreen::}{subScreenIndexAt()} and \l {QScreen::}{subScreens()}
- functions to access the correct subscreen, and the subscreen's \l
- {QScreen::}{base()} function to retrieve a pointer to the
- framebuffer.
-
- Depending on the hardware, it might be necessary to lock the
- framebuffer for exclusive use while writing to it. This is
- possible using the lock() and unlock() functions. Note that
- calling lock() will prevent all other applications from working
- until unlock() is called.
-
- In addition, QDirectPainter provides several functions returning
- information about the framebuffer: the linestep() function returns
- the length (in bytes) of each scanline of the framebuffer while
- the screenDepth(), screenWidth() and screenHeight() function
- return the screen metrics.
-
- \sa QScreen, QWSEmbedWidget, {Qt for Embedded Linux Architecture}
-*/
-
-/*!
- \enum QDirectPainter::SurfaceFlag
-
- This enum describes the behavior of the region reserved by this
- QDirectPainter object.
-
- \value NonReserved The allocated region may change, e.g., if a
- window with a higher focus requests parts of the same region. See
- also \l {Dynamic Allocation}.
-
- \value Reserved The allocated region will never change. See also
- \l {Static Allocation}.
-
- \value ReservedSynchronous The allocated region will never change and
- each function that changes the allocated region will be blocking.
-
- \sa allocatedRegion()
-*/
-
-/*!
- \fn QRegion QDirectPainter::region()
- \obsolete
-
- Use QDirectPainter::allocatedRegion() instead.
-*/
-
-static inline QScreen *getPrimaryScreen()
-{
- QScreen *screen = QScreen::instance();
- if (!screen->base()) {
- QList<QScreen*> subScreens = screen->subScreens();
- if (subScreens.size() < 1)
- return 0;
- screen = subScreens.at(0);
- }
- return screen;
-}
-
-static inline QSize screenS()
-{
- QScreen *screen = getPrimaryScreen();
- if (!screen)
- return QSize();
- return QSize(screen->width(), screen->height());
-}
-
-static inline QSize devS()
-{
- QScreen *screen = getPrimaryScreen();
- if (!screen)
- return QSize();
- return QSize(screen->deviceWidth(), screen->deviceHeight());
-}
-
-
-class QDirectPainterPrivate : public QObjectPrivate
-{
- Q_DECLARE_PUBLIC(QDirectPainter);
-public:
-
- QDirectPainterPrivate() : surface(0), seenRegion(false) {}
-
- ~QDirectPainterPrivate() {
- if (QPaintDevice::qwsDisplay()) { // make sure not in QApplication destructor
- qApp->d_func()->directPainters->remove(surface->windowId());
- surface->setGeometry(QRect());
- }
- delete surface;
- }
-
- QWSDirectPainterSurface *surface;
- QRegion requested_region;
-
- static QDirectPainter *staticPainter;
- bool seenRegion;
-};
-
-QDirectPainter *QDirectPainterPrivate::staticPainter = 0;
-
-void qt_directpainter_region(QDirectPainter *dp, const QRegion &alloc, int type)
-{
- QDirectPainterPrivate *d = dp->d_func();
-
- QRegion r = alloc;
- QScreen *screen = d->surface->screen();
- if (screen->isTransformed()) {
- const QSize screenSize(screen->width(), screen->height());
- r = screen->mapToDevice(r, screenSize);
- }
- if (type == QWSRegionEvent::Allocation) {
- d->surface->setClipRegion(alloc);
- d->seenRegion = true;
- if (dp != QDirectPainterPrivate::staticPainter) {
- if (!d->surface->flushingRegionEvents) // recursion guard
- dp->regionChanged(r);
- }
- }
-}
-
-#ifndef QT_NO_QWSEMBEDWIDGET
-void qt_directpainter_embedevent(QDirectPainter *dp, const QWSEmbedEvent *event)
-{
- if (event->type | QWSEmbedEvent::Region) {
- QScreen *screen = dp->d_func()->surface->screen();
- QRegion r = event->region;
- if (screen->isTransformed()) {
- const QSize screenSize(screen->width(), screen->height());
- r = screen->mapToDevice(r, screenSize);
- }
- dp->setRegion(r);
- }
-}
-#endif
-
-/*!
- Constructs a QDirectPainter object with the given \a parent and
- surface \a flag.
-*/
-QDirectPainter::QDirectPainter(QObject *parent, SurfaceFlag flag)
- :QObject(*new QDirectPainterPrivate, parent)
-{
- Q_D(QDirectPainter);
- d->surface = new QWSDirectPainterSurface(true, flag);
-
- if (flag != NonReserved)
- d->surface->setReserved();
-
- QApplicationPrivate *ad = qApp->d_func();
- if (!ad->directPainters)
- ad->directPainters = new QMap<WId, QDirectPainter*>;
- ad->directPainters->insert(d->surface->windowId(), this);
-}
-
-/*!
- Destroys this QDirectPainter object, releasing the reserved region.
-
- \sa allocatedRegion()
-*/
-QDirectPainter::~QDirectPainter()
-{
- /* should not be necessary
- if (this == QDirectPainterPrivate::staticPainter)
- QDirectPainterPrivate::staticPainter = 0;
- */
-}
-
-/*!
- \fn void QDirectPainter::setGeometry(const QRect &rectangle)
- \since 4.2
-
- Request to reserve the given \a rectangle of the framebuffer.
-
- Note that the actually allocated region might differ from the
- requested one, e.g., if the given region overlaps with the
- region of another QDirectPainter object.
-
- \sa geometry(), allocatedRegion(), setRegion()
-*/
-void QDirectPainter::setGeometry(const QRect &rect)
-{
- setRegion(rect);
-}
-
-/*!
- \since 4.2
-
- Returns the bounding rectangle of the requested region.
-
- \sa setGeometry(), requestedRegion()
-*/
-QRect QDirectPainter::geometry() const
-{
- Q_D(const QDirectPainter);
- return d->requested_region.boundingRect();
-}
-
-/*!
- \since 4.2
-
- Requests to reserve the given \a region of the framebuffer.
-
- Note that the actually allocated region might differ from the
- requested one, e.g., if the given region overlaps with the region
- of another QDirectPainter object.
-
- \sa requestedRegion(), allocatedRegion(), {Dynamic Allocation}
-*/
-void QDirectPainter::setRegion(const QRegion &region)
-{
- Q_D(QDirectPainter);
- d->requested_region = region;
-
- const QScreen *screen = d->surface->screen();
- if (screen->isTransformed()) {
- const QSize devSize(screen->deviceWidth(), screen->deviceHeight());
- const QRegion r = screen->mapFromDevice(region, devSize);
- d->surface->setRegion(r);
- } else {
- d->surface->setRegion(region);
- }
-}
-
-/*!
- \since 4.2
-
- Returns the region requested by this QDirectPainter.
-
- Note that if the QDirectPainter::Reserved flag is set, the region
- returned by this function will always be equivalent to the region
- returned by the allocatedRegion() function. Otherwise they might
- differ (see \l {Dynamic Allocation} for details).
-
- \sa geometry(), setRegion(), allocatedRegion()
-*/
-QRegion QDirectPainter::requestedRegion() const
-{
- Q_D(const QDirectPainter);
- return d->requested_region;
-}
-
-/*!
- \since 4.2
-
- Returns the currently reserved region.
-
- Note that if the QDirectPainter::Reserved flag is set, the region
- returned by this function will always be equivalent to the region
- returned by the requestedRegion() function. Otherwise they might
- differ (see \l {Dynamic Allocation} for details).
-
- \sa requestedRegion(), geometry()
-*/
-QRegion QDirectPainter::allocatedRegion() const
-{
- Q_D(const QDirectPainter);
- const QScreen *screen = d->surface->screen();
- if (screen->isTransformed()) {
- const QSize screenSize(screen->width(), screen->height());
- return screen->mapToDevice(d->surface->region(), screenSize);
- } else {
- return d->surface->region();
- }
-}
-
-/*!
- \since 4.2
-
- Returns the window system identifier of the widget.
-*/
-WId QDirectPainter::winId() const
-{
- Q_D(const QDirectPainter);
- return d->surface->windowId();
-}
-
-/*!
- \fn void QDirectPainter::regionChanged(const QRegion &newRegion)
- \since 4.2
-
- This function is called when the allocated region changes.
-
- This function is not called for region changes that happen while the
- startPainting() function is executing.
-
- Note that the given region, \a newRegion, is not guaranteed to be correct at the
- time you access the display. To prevent reentrancy problems you should
- always call startPainting() before updating the display and then use
- allocatedRegion() to retrieve the correct region.
-
- \sa allocatedRegion(), startPainting(), {Dynamic Allocation}
-*/
-void QDirectPainter::regionChanged(const QRegion &region)
-{
- Q_UNUSED(region);
-}
-
-/*!
- \since 4.2
-
- Call this function before you start updating the pixels in the
- allocated region. The hardware will be notified, if necessary,
- that you are about to start painting operations.
-
- Set \a lockDisplay if you want startPainting() and endPainting()
- to lock() and unlock() the display automatically.
-
- Note that for a NonReserved direct painter, you must call
- allocatedRegion() after calling this function, since the allocated
- region is only guaranteed to be correct after this function has
- returned.
-
- The regionChanged() function will not be called between startPainting()
- and endPainting().
-
- \sa endPainting(), flush()
-*/
-void QDirectPainter::startPainting(bool lockDisplay)
-{
- Q_D(QDirectPainter);
- d->surface->setLocking(lockDisplay);
-
- const QScreen *screen = d->surface->screen();
- if (screen->isTransformed()) {
- const QSize devSize(screen->deviceWidth(), screen->deviceHeight());
- const QRegion r = screen->mapFromDevice(d->surface->region(), devSize);
- d->surface->beginPaint(r);
- } else {
- d->surface->beginPaint(d->surface->region());
- }
-}
-
-/*!
- \since 4.2
-
- Call this function when you are done updating the screen. It will
- notify the hardware, if necessary, that your painting operations
- have ended.
-*/
-void QDirectPainter::endPainting()
-{
- Q_D(QDirectPainter);
-
- const QScreen *screen = d->surface->screen();
- if (screen->isTransformed()) {
- const QSize devSize(screen->deviceWidth(), screen->deviceHeight());
- const QRegion r = screen->mapFromDevice(d->surface->region(), devSize);
- d->surface->endPaint(r);
- } else {
- d->surface->endPaint(d->surface->region());
- }
-}
-
-/*!
- \since 4.3
- \overload
-
- This function will automatically call flush() to flush the
- \a region to the display before notifying the hardware, if
- necessary, that painting operations have ended.
-*/
-void QDirectPainter::endPainting(const QRegion &region)
-{
- endPainting();
- flush(region);
-}
-
-/*!
- \since 4.3
-
- Flushes the \a region onto the screen.
-*/
-void QDirectPainter::flush(const QRegion &region)
-{
- Q_D(QDirectPainter);
-
- const QScreen *screen = d->surface->screen();
- if (screen->isTransformed()) {
- const QSize devSize(screen->deviceWidth(), screen->deviceHeight());
- const QRegion r = screen->mapFromDevice(region, devSize);
- d->surface->flush(0, r, QPoint());
- } else {
- d->surface->flush(0, region, QPoint());
- }
-}
-
-/*!
- \since 4.2
-
- Raises the reserved region to the top of the widget stack.
-
- After this call the reserved region will be visually in front of
- any overlapping widgets.
-
- \sa lower(), requestedRegion()
-*/
-void QDirectPainter::raise()
-{
- QWidget::qwsDisplay()->setAltitude(winId(),QWSChangeAltitudeCommand::Raise);
-}
-
-/*!
- \since 4.2
-
- Lowers the reserved region to the bottom of the widget stack.
-
- After this call the reserved region will be visually behind (and
- therefore obscured by) any overlapping widgets.
-
- \sa raise(), requestedRegion()
-*/
-void QDirectPainter::lower()
-{
- QWidget::qwsDisplay()->setAltitude(winId(),QWSChangeAltitudeCommand::Lower);
-}
-
-
-/*!
- \fn QRegion QDirectPainter::reserveRegion(const QRegion &region)
-
- Attempts to reserve the \a region and returns the region that is
- actually reserved.
-
- This function also releases the previously reserved region if
- any. If not released explicitly, the region will be released on
- application exit.
-
- \sa allocatedRegion(), {Static Allocation}
-
- \obsolete
-
- Construct a QDirectPainter using QDirectPainter::ReservedSynchronous instead.
-*/
-QRegion QDirectPainter::reserveRegion(const QRegion &reg)
-{
- if (!QDirectPainterPrivate::staticPainter)
- QDirectPainterPrivate::staticPainter = new QDirectPainter(qApp, ReservedSynchronous);
-
- QDirectPainter *dp = QDirectPainterPrivate::staticPainter;
- dp->setRegion(reg);
-
- return dp->allocatedRegion();
-}
-
-/*!
- Returns a pointer to the beginning of the display memory.
-
- Note that it is the application's responsibility to limit itself
- to modifying only the reserved region.
-
- Do not use this pointer if the current screen has subscreens,
- query the screen driver instead: A pointer to the current screen
- driver can always be retrieved using the static
- QScreen::instance() function. Then use QScreen's \l
- {QScreen::}{subScreenIndexAt()} and \l {QScreen::}{subScreens()}
- functions to access the correct subscreen, and the subscreen's \l
- {QScreen::}{base()} function to retrieve a pointer to the
- framebuffer.
-
- \sa requestedRegion(), allocatedRegion(), linestep()
-*/
-uchar* QDirectPainter::frameBuffer()
-{
- QScreen *screen = getPrimaryScreen();
- if (!screen)
- return 0;
- return screen->base();
-}
-
-/*!
- \since 4.2
-
- Returns the reserved region.
-
- \sa reserveRegion(), frameBuffer()
-
- \obsolete
-
- Use allocatedRegion() instead.
-*/
-QRegion QDirectPainter::reservedRegion()
-{
- return QDirectPainterPrivate::staticPainter
- ? QDirectPainterPrivate::staticPainter->allocatedRegion() : QRegion();
-}
-
-/*!
- Returns the bit depth of the display.
-
- \sa screenHeight(), screenWidth()
-*/
-int QDirectPainter::screenDepth()
-{
- QScreen *screen = getPrimaryScreen();
- if (!screen)
- return 0;
- return screen->depth();
-}
-
-/*!
- Returns the width of the display in pixels.
-
- \sa screenHeight(), screenDepth()
-*/
-int QDirectPainter::screenWidth()
-{
- QScreen *screen = getPrimaryScreen();
- if (!screen)
- return 0;
- return screen->deviceWidth();
-}
-
-/*!
- Returns the height of the display in pixels.
-
- \sa screenWidth(), screenDepth()
-*/
-int QDirectPainter::screenHeight()
-{
- QScreen *screen = getPrimaryScreen();
- if (!screen)
- return 0;
- return screen->deviceHeight();
-}
-
-/*!
- Returns the length (in bytes) of each scanline of the framebuffer.
-
- \sa frameBuffer()
-*/
-int QDirectPainter::linestep()
-{
- QScreen *screen = getPrimaryScreen();
- if (!screen)
- return 0;
- return screen->linestep();
-}
-
-
-/*!
- Locks access to the framebuffer.
-
- Note that calling this function will prevent all other
- applications from updating the display until unlock() is called.
-
- \sa unlock()
-*/
-void QDirectPainter::lock()
-{
- QWSDisplay::grab(true);
-}
-/*!
- Unlocks the lock on the framebuffer (set using the lock()
- function), allowing other applications to access the screen.
-
- \sa lock()
- */
-void QDirectPainter::unlock()
-{
- QWSDisplay::ungrab();
-}
-
-#endif //QT_NO_DIRECTPAINTER
-
-#endif
-
-QT_END_NAMESPACE
diff --git a/src/gui/embedded/qdirectpainter_qws.h b/src/gui/embedded/qdirectpainter_qws.h
deleted file mode 100644
index b4c1d5ef9f..0000000000
--- a/src/gui/embedded/qdirectpainter_qws.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDIRECTPAINTER_QWS_H
-#define QDIRECTPAINTER_QWS_H
-
-#include <QtCore/qobject.h>
-#include <QtGui/qregion.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_DIRECTPAINTER
-class QDirectPainterPrivate;
-class QWSEmbedEvent;
-
-class Q_GUI_EXPORT QDirectPainter : public QObject {
- Q_OBJECT
- Q_DECLARE_PRIVATE(QDirectPainter)
-public:
-
- enum SurfaceFlag { NonReserved = 0,
- Reserved = 1,
- ReservedSynchronous = 3 };
-
- explicit QDirectPainter(QObject *parentObject = 0, SurfaceFlag flag = NonReserved);
- ~QDirectPainter();
-
- void setRegion(const QRegion&);
- QRegion requestedRegion() const;
- QRegion allocatedRegion() const;
-
- void setGeometry(const QRect&);
- QRect geometry() const;
-
- WId winId() const;
- virtual void regionChanged(const QRegion &exposedRegion);
-
- void startPainting(bool lockDisplay = true);
- void endPainting();
- void endPainting(const QRegion &region);
- void flush(const QRegion &region);
-
- void raise();
- void lower();
-
-
- static QRegion reserveRegion(const QRegion&);
- static QRegion reservedRegion();
- static QRegion region() { return reservedRegion(); }
-
- static uchar* frameBuffer();
- static int screenDepth();
- static int screenWidth();
- static int screenHeight();
- static int linestep();
-
- static void lock();
- static void unlock();
-private:
- friend void qt_directpainter_region(QDirectPainter *dp, const QRegion &alloc, int type);
- friend void qt_directpainter_embedevent(QDirectPainter*, const QWSEmbedEvent*);
-};
-
-#endif
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QDIRECTPAINTER_QWS_H
diff --git a/src/gui/embedded/qkbd_defaultmap_qws_p.h b/src/gui/embedded/qkbd_defaultmap_qws_p.h
deleted file mode 100644
index 5aa8f839d5..0000000000
--- a/src/gui/embedded/qkbd_defaultmap_qws_p.h
+++ /dev/null
@@ -1,806 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWSKEYBOARDHANDLER_DEFAULTMAP_H
-#define QWSKEYBOARDHANDLER_DEFAULTMAP_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-// no QT_BEGIN_NAMESPACE, since we include it internally...
-
-const QWSKeyboard::Mapping QWSKbPrivate::s_keymap_default[] = {
- { 1, 0xffff, 0x01000000, 0x00, 0x00, 0x0000 },
- { 2, 0x0031, 0x00000031, 0x00, 0x00, 0x0000 },
- { 2, 0x0021, 0x00000021, 0x01, 0x00, 0x0000 },
- { 3, 0x0032, 0x00000032, 0x00, 0x00, 0x0000 },
- { 3, 0x0040, 0x00000040, 0x01, 0x00, 0x0000 },
- { 3, 0x0040, 0x00000040, 0x02, 0x00, 0x0000 },
- { 4, 0x0033, 0x00000033, 0x00, 0x00, 0x0000 },
- { 4, 0x0023, 0x00000023, 0x01, 0x00, 0x0000 },
- { 4, 0xffff, 0x01000000, 0x04, 0x00, 0x0000 },
- { 5, 0x0034, 0x00000034, 0x00, 0x00, 0x0000 },
- { 5, 0x0024, 0x00000024, 0x01, 0x00, 0x0000 },
- { 5, 0x0024, 0x00000024, 0x02, 0x00, 0x0000 },
- { 5, 0x005c, 0x0400005c, 0x04, 0x00, 0x0000 },
- { 6, 0x0035, 0x00000035, 0x00, 0x00, 0x0000 },
- { 6, 0x0025, 0x00000025, 0x01, 0x00, 0x0000 },
- { 6, 0x005d, 0x0400005d, 0x04, 0x00, 0x0000 },
- { 7, 0x0036, 0x00000036, 0x00, 0x00, 0x0000 },
- { 7, 0x005e, 0x0000005e, 0x01, 0x00, 0x0000 },
- { 7, 0x005e, 0x01001252, 0x02, 0x01, 0x0000 },
- { 7, 0x005e, 0x0400005e, 0x04, 0x00, 0x0000 },
- { 8, 0x0037, 0x00000037, 0x00, 0x00, 0x0000 },
- { 8, 0x0026, 0x00000026, 0x01, 0x00, 0x0000 },
- { 8, 0x007b, 0x0000007b, 0x02, 0x00, 0x0000 },
- { 8, 0x005f, 0x0400005f, 0x04, 0x00, 0x0000 },
- { 9, 0x0038, 0x00000038, 0x00, 0x00, 0x0000 },
- { 9, 0x002a, 0x0000002a, 0x01, 0x00, 0x0000 },
- { 9, 0x005b, 0x0000005b, 0x02, 0x00, 0x0000 },
- { 9, 0xffff, 0x01000003, 0x04, 0x00, 0x0000 },
- { 10, 0x0039, 0x00000039, 0x00, 0x00, 0x0000 },
- { 10, 0x0028, 0x00000028, 0x01, 0x00, 0x0000 },
- { 10, 0x005d, 0x0000005d, 0x02, 0x00, 0x0000 },
- { 11, 0x0030, 0x00000030, 0x00, 0x00, 0x0000 },
- { 11, 0x0029, 0x00000029, 0x01, 0x00, 0x0000 },
- { 11, 0x007d, 0x0000007d, 0x02, 0x00, 0x0000 },
- { 12, 0x002d, 0x0000002d, 0x00, 0x00, 0x0000 },
- { 12, 0x005f, 0x0000005f, 0x01, 0x00, 0x0000 },
- { 12, 0x005c, 0x0000005c, 0x02, 0x00, 0x0000 },
- { 12, 0x005f, 0x0400005f, 0x04, 0x00, 0x0000 },
- { 12, 0x005f, 0x0400005f, 0x05, 0x00, 0x0000 },
- { 13, 0x003d, 0x0000003d, 0x00, 0x00, 0x0000 },
- { 13, 0x002b, 0x0000002b, 0x01, 0x00, 0x0000 },
- { 14, 0xffff, 0x01000003, 0x00, 0x00, 0x0000 },
- { 14, 0xffff, 0x01000000, 0x0c, 0x08, 0x0300 },
- { 15, 0xffff, 0x01000001, 0x00, 0x00, 0x0000 },
- { 16, 0x0071, 0x00000051, 0x00, 0x00, 0x0000 },
- { 16, 0x0051, 0x00000051, 0x01, 0x00, 0x0000 },
- { 16, 0x0071, 0x00000051, 0x02, 0x00, 0x0000 },
- { 16, 0x0051, 0x00000051, 0x03, 0x00, 0x0000 },
- { 16, 0x0071, 0x04000051, 0x04, 0x00, 0x0000 },
- { 16, 0x0071, 0x04000051, 0x05, 0x00, 0x0000 },
- { 16, 0x0071, 0x04000051, 0x06, 0x00, 0x0000 },
- { 16, 0x0071, 0x04000051, 0x07, 0x00, 0x0000 },
- { 16, 0x0071, 0x08000051, 0x08, 0x00, 0x0000 },
- { 16, 0x0071, 0x08000051, 0x09, 0x00, 0x0000 },
- { 16, 0x0071, 0x08000051, 0x0a, 0x00, 0x0000 },
- { 16, 0x0071, 0x08000051, 0x0b, 0x00, 0x0000 },
- { 16, 0x0071, 0x0c000051, 0x0c, 0x00, 0x0000 },
- { 16, 0x0071, 0x0c000051, 0x0d, 0x00, 0x0000 },
- { 16, 0x0071, 0x0c000051, 0x0e, 0x00, 0x0000 },
- { 16, 0x0071, 0x0c000051, 0x0f, 0x00, 0x0000 },
- { 17, 0x0077, 0x00000057, 0x00, 0x00, 0x0000 },
- { 17, 0x0057, 0x00000057, 0x01, 0x00, 0x0000 },
- { 17, 0x0077, 0x00000057, 0x02, 0x00, 0x0000 },
- { 17, 0x0057, 0x00000057, 0x03, 0x00, 0x0000 },
- { 17, 0x0077, 0x04000057, 0x04, 0x00, 0x0000 },
- { 17, 0x0077, 0x04000057, 0x05, 0x00, 0x0000 },
- { 17, 0x0077, 0x04000057, 0x06, 0x00, 0x0000 },
- { 17, 0x0077, 0x04000057, 0x07, 0x00, 0x0000 },
- { 17, 0x0077, 0x08000057, 0x08, 0x00, 0x0000 },
- { 17, 0x0077, 0x08000057, 0x09, 0x00, 0x0000 },
- { 17, 0x0077, 0x08000057, 0x0a, 0x00, 0x0000 },
- { 17, 0x0077, 0x08000057, 0x0b, 0x00, 0x0000 },
- { 17, 0x0077, 0x0c000057, 0x0c, 0x00, 0x0000 },
- { 17, 0x0077, 0x0c000057, 0x0d, 0x00, 0x0000 },
- { 17, 0x0077, 0x0c000057, 0x0e, 0x00, 0x0000 },
- { 17, 0x0077, 0x0c000057, 0x0f, 0x00, 0x0000 },
- { 18, 0x0065, 0x00000045, 0x00, 0x00, 0x0000 },
- { 18, 0x0045, 0x00000045, 0x01, 0x00, 0x0000 },
- { 18, 0x0065, 0x00000045, 0x02, 0x00, 0x0000 },
- { 18, 0x0045, 0x00000045, 0x03, 0x00, 0x0000 },
- { 18, 0x0065, 0x04000045, 0x04, 0x00, 0x0000 },
- { 18, 0x0065, 0x04000045, 0x05, 0x00, 0x0000 },
- { 18, 0x0065, 0x04000045, 0x06, 0x00, 0x0000 },
- { 18, 0x0065, 0x04000045, 0x07, 0x00, 0x0000 },
- { 18, 0x0065, 0x08000045, 0x08, 0x00, 0x0000 },
- { 18, 0x0065, 0x08000045, 0x09, 0x00, 0x0000 },
- { 18, 0x0065, 0x08000045, 0x0a, 0x00, 0x0000 },
- { 18, 0x0065, 0x08000045, 0x0b, 0x00, 0x0000 },
- { 18, 0x0065, 0x0c000045, 0x0c, 0x00, 0x0000 },
- { 18, 0x0065, 0x0c000045, 0x0d, 0x00, 0x0000 },
- { 18, 0x0065, 0x0c000045, 0x0e, 0x00, 0x0000 },
- { 18, 0x0065, 0x0c000045, 0x0f, 0x00, 0x0000 },
- { 19, 0x0072, 0x00000052, 0x00, 0x00, 0x0000 },
- { 19, 0x0052, 0x00000052, 0x01, 0x00, 0x0000 },
- { 19, 0x0072, 0x00000052, 0x02, 0x00, 0x0000 },
- { 19, 0x0052, 0x00000052, 0x03, 0x00, 0x0000 },
- { 19, 0x0072, 0x04000052, 0x04, 0x00, 0x0000 },
- { 19, 0x0072, 0x04000052, 0x05, 0x00, 0x0000 },
- { 19, 0x0072, 0x04000052, 0x06, 0x00, 0x0000 },
- { 19, 0x0072, 0x04000052, 0x07, 0x00, 0x0000 },
- { 19, 0x0072, 0x08000052, 0x08, 0x00, 0x0000 },
- { 19, 0x0072, 0x08000052, 0x09, 0x00, 0x0000 },
- { 19, 0x0072, 0x08000052, 0x0a, 0x00, 0x0000 },
- { 19, 0x0072, 0x08000052, 0x0b, 0x00, 0x0000 },
- { 19, 0x0072, 0x0c000052, 0x0c, 0x00, 0x0000 },
- { 19, 0x0072, 0x0c000052, 0x0d, 0x00, 0x0000 },
- { 19, 0x0072, 0x0c000052, 0x0e, 0x00, 0x0000 },
- { 19, 0x0072, 0x0c000052, 0x0f, 0x00, 0x0000 },
- { 20, 0x0074, 0x00000054, 0x00, 0x00, 0x0000 },
- { 20, 0x0054, 0x00000054, 0x01, 0x00, 0x0000 },
- { 20, 0x0074, 0x00000054, 0x02, 0x00, 0x0000 },
- { 20, 0x0054, 0x00000054, 0x03, 0x00, 0x0000 },
- { 20, 0x0074, 0x04000054, 0x04, 0x00, 0x0000 },
- { 20, 0x0074, 0x04000054, 0x05, 0x00, 0x0000 },
- { 20, 0x0074, 0x04000054, 0x06, 0x00, 0x0000 },
- { 20, 0x0074, 0x04000054, 0x07, 0x00, 0x0000 },
- { 20, 0x0074, 0x08000054, 0x08, 0x00, 0x0000 },
- { 20, 0x0074, 0x08000054, 0x09, 0x00, 0x0000 },
- { 20, 0x0074, 0x08000054, 0x0a, 0x00, 0x0000 },
- { 20, 0x0074, 0x08000054, 0x0b, 0x00, 0x0000 },
- { 20, 0x0074, 0x0c000054, 0x0c, 0x00, 0x0000 },
- { 20, 0x0074, 0x0c000054, 0x0d, 0x00, 0x0000 },
- { 20, 0x0074, 0x0c000054, 0x0e, 0x00, 0x0000 },
- { 20, 0x0074, 0x0c000054, 0x0f, 0x00, 0x0000 },
- { 21, 0x0079, 0x00000059, 0x00, 0x00, 0x0000 },
- { 21, 0x0059, 0x00000059, 0x01, 0x00, 0x0000 },
- { 21, 0x0079, 0x00000059, 0x02, 0x00, 0x0000 },
- { 21, 0x0059, 0x00000059, 0x03, 0x00, 0x0000 },
- { 21, 0x0079, 0x04000059, 0x04, 0x00, 0x0000 },
- { 21, 0x0079, 0x04000059, 0x05, 0x00, 0x0000 },
- { 21, 0x0079, 0x04000059, 0x06, 0x00, 0x0000 },
- { 21, 0x0079, 0x04000059, 0x07, 0x00, 0x0000 },
- { 21, 0x0079, 0x08000059, 0x08, 0x00, 0x0000 },
- { 21, 0x0079, 0x08000059, 0x09, 0x00, 0x0000 },
- { 21, 0x0079, 0x08000059, 0x0a, 0x00, 0x0000 },
- { 21, 0x0079, 0x08000059, 0x0b, 0x00, 0x0000 },
- { 21, 0x0079, 0x0c000059, 0x0c, 0x00, 0x0000 },
- { 21, 0x0079, 0x0c000059, 0x0d, 0x00, 0x0000 },
- { 21, 0x0079, 0x0c000059, 0x0e, 0x00, 0x0000 },
- { 21, 0x0079, 0x0c000059, 0x0f, 0x00, 0x0000 },
- { 22, 0x0075, 0x00000055, 0x00, 0x00, 0x0000 },
- { 22, 0x0055, 0x00000055, 0x01, 0x00, 0x0000 },
- { 22, 0x0075, 0x00000055, 0x02, 0x00, 0x0000 },
- { 22, 0x0055, 0x00000055, 0x03, 0x00, 0x0000 },
- { 22, 0x0075, 0x04000055, 0x04, 0x00, 0x0000 },
- { 22, 0x0075, 0x04000055, 0x05, 0x00, 0x0000 },
- { 22, 0x0075, 0x04000055, 0x06, 0x00, 0x0000 },
- { 22, 0x0075, 0x04000055, 0x07, 0x00, 0x0000 },
- { 22, 0x0075, 0x08000055, 0x08, 0x00, 0x0000 },
- { 22, 0x0075, 0x08000055, 0x09, 0x00, 0x0000 },
- { 22, 0x0075, 0x08000055, 0x0a, 0x00, 0x0000 },
- { 22, 0x0075, 0x08000055, 0x0b, 0x00, 0x0000 },
- { 22, 0x0075, 0x0c000055, 0x0c, 0x00, 0x0000 },
- { 22, 0x0075, 0x0c000055, 0x0d, 0x00, 0x0000 },
- { 22, 0x0075, 0x0c000055, 0x0e, 0x00, 0x0000 },
- { 22, 0x0075, 0x0c000055, 0x0f, 0x00, 0x0000 },
- { 23, 0x0069, 0x00000049, 0x00, 0x00, 0x0000 },
- { 23, 0x0049, 0x00000049, 0x01, 0x00, 0x0000 },
- { 23, 0x0069, 0x00000049, 0x02, 0x00, 0x0000 },
- { 23, 0x0049, 0x00000049, 0x03, 0x00, 0x0000 },
- { 23, 0x0069, 0x04000049, 0x04, 0x00, 0x0000 },
- { 23, 0x0069, 0x04000049, 0x05, 0x00, 0x0000 },
- { 23, 0x0069, 0x04000049, 0x06, 0x00, 0x0000 },
- { 23, 0x0069, 0x04000049, 0x07, 0x00, 0x0000 },
- { 23, 0x0069, 0x08000049, 0x08, 0x00, 0x0000 },
- { 23, 0x0069, 0x08000049, 0x09, 0x00, 0x0000 },
- { 23, 0x0069, 0x08000049, 0x0a, 0x00, 0x0000 },
- { 23, 0x0069, 0x08000049, 0x0b, 0x00, 0x0000 },
- { 23, 0x0069, 0x0c000049, 0x0c, 0x00, 0x0000 },
- { 23, 0x0069, 0x0c000049, 0x0d, 0x00, 0x0000 },
- { 23, 0x0069, 0x0c000049, 0x0e, 0x00, 0x0000 },
- { 23, 0x0069, 0x0c000049, 0x0f, 0x00, 0x0000 },
- { 24, 0x006f, 0x0000004f, 0x00, 0x00, 0x0000 },
- { 24, 0x004f, 0x0000004f, 0x01, 0x00, 0x0000 },
- { 24, 0x006f, 0x0000004f, 0x02, 0x00, 0x0000 },
- { 24, 0x004f, 0x0000004f, 0x03, 0x00, 0x0000 },
- { 24, 0x006f, 0x0400004f, 0x04, 0x00, 0x0000 },
- { 24, 0x006f, 0x0400004f, 0x05, 0x00, 0x0000 },
- { 24, 0x006f, 0x0400004f, 0x06, 0x00, 0x0000 },
- { 24, 0x006f, 0x0400004f, 0x07, 0x00, 0x0000 },
- { 24, 0x006f, 0x0800004f, 0x08, 0x00, 0x0000 },
- { 24, 0x006f, 0x0800004f, 0x09, 0x00, 0x0000 },
- { 24, 0x006f, 0x0800004f, 0x0a, 0x00, 0x0000 },
- { 24, 0x006f, 0x0800004f, 0x0b, 0x00, 0x0000 },
- { 24, 0x006f, 0x0c00004f, 0x0c, 0x00, 0x0000 },
- { 24, 0x006f, 0x0c00004f, 0x0d, 0x00, 0x0000 },
- { 24, 0x006f, 0x0c00004f, 0x0e, 0x00, 0x0000 },
- { 24, 0x006f, 0x0c00004f, 0x0f, 0x00, 0x0000 },
- { 25, 0x0070, 0x00000050, 0x00, 0x00, 0x0000 },
- { 25, 0x0050, 0x00000050, 0x01, 0x00, 0x0000 },
- { 25, 0x0070, 0x00000050, 0x02, 0x00, 0x0000 },
- { 25, 0x0050, 0x00000050, 0x03, 0x00, 0x0000 },
- { 25, 0x0070, 0x04000050, 0x04, 0x00, 0x0000 },
- { 25, 0x0070, 0x04000050, 0x05, 0x00, 0x0000 },
- { 25, 0x0070, 0x04000050, 0x06, 0x00, 0x0000 },
- { 25, 0x0070, 0x04000050, 0x07, 0x00, 0x0000 },
- { 25, 0x0070, 0x08000050, 0x08, 0x00, 0x0000 },
- { 25, 0x0070, 0x08000050, 0x09, 0x00, 0x0000 },
- { 25, 0x0070, 0x08000050, 0x0a, 0x00, 0x0000 },
- { 25, 0x0070, 0x08000050, 0x0b, 0x00, 0x0000 },
- { 25, 0x0070, 0x0c000050, 0x0c, 0x00, 0x0000 },
- { 25, 0x0070, 0x0c000050, 0x0d, 0x00, 0x0000 },
- { 25, 0x0070, 0x0c000050, 0x0e, 0x00, 0x0000 },
- { 25, 0x0070, 0x0c000050, 0x0f, 0x00, 0x0000 },
- { 26, 0x005b, 0x0000005b, 0x00, 0x00, 0x0000 },
- { 26, 0x007b, 0x0000007b, 0x01, 0x00, 0x0000 },
- { 26, 0xffff, 0x01000000, 0x04, 0x00, 0x0000 },
- { 27, 0x005d, 0x0000005d, 0x00, 0x00, 0x0000 },
- { 27, 0x007d, 0x0000007d, 0x01, 0x00, 0x0000 },
- { 27, 0x007e, 0x0000007e, 0x02, 0x00, 0x0000 },
- { 27, 0x005d, 0x0400005d, 0x04, 0x00, 0x0000 },
- { 28, 0xffff, 0x01000004, 0x00, 0x00, 0x0000 },
- { 28, 0x006d, 0x0c00004d, 0x08, 0x00, 0x0000 },
- { 29, 0xffff, 0x01000021, 0x00, 0x04, 0x0004 },
- { 30, 0x0061, 0x00000041, 0x00, 0x00, 0x0000 },
- { 30, 0x0041, 0x00000041, 0x01, 0x00, 0x0000 },
- { 30, 0x0061, 0x00000041, 0x02, 0x00, 0x0000 },
- { 30, 0x0041, 0x00000041, 0x03, 0x00, 0x0000 },
- { 30, 0x0061, 0x04000041, 0x04, 0x00, 0x0000 },
- { 30, 0x0061, 0x04000041, 0x05, 0x00, 0x0000 },
- { 30, 0x0061, 0x04000041, 0x06, 0x00, 0x0000 },
- { 30, 0x0061, 0x04000041, 0x07, 0x00, 0x0000 },
- { 30, 0x0061, 0x08000041, 0x08, 0x00, 0x0000 },
- { 30, 0x0061, 0x08000041, 0x09, 0x00, 0x0000 },
- { 30, 0x0061, 0x08000041, 0x0a, 0x00, 0x0000 },
- { 30, 0x0061, 0x08000041, 0x0b, 0x00, 0x0000 },
- { 30, 0x0061, 0x0c000041, 0x0c, 0x00, 0x0000 },
- { 30, 0x0061, 0x0c000041, 0x0d, 0x00, 0x0000 },
- { 30, 0x0061, 0x0c000041, 0x0e, 0x00, 0x0000 },
- { 30, 0x0061, 0x0c000041, 0x0f, 0x00, 0x0000 },
- { 31, 0x0073, 0x00000053, 0x00, 0x00, 0x0000 },
- { 31, 0x0053, 0x00000053, 0x01, 0x00, 0x0000 },
- { 31, 0x0073, 0x00000053, 0x02, 0x00, 0x0000 },
- { 31, 0x0053, 0x00000053, 0x03, 0x00, 0x0000 },
- { 31, 0x0073, 0x04000053, 0x04, 0x00, 0x0000 },
- { 31, 0x0073, 0x04000053, 0x05, 0x00, 0x0000 },
- { 31, 0x0073, 0x04000053, 0x06, 0x00, 0x0000 },
- { 31, 0x0073, 0x04000053, 0x07, 0x00, 0x0000 },
- { 31, 0x0073, 0x08000053, 0x08, 0x00, 0x0000 },
- { 31, 0x0073, 0x08000053, 0x09, 0x00, 0x0000 },
- { 31, 0x0073, 0x08000053, 0x0a, 0x00, 0x0000 },
- { 31, 0x0073, 0x08000053, 0x0b, 0x00, 0x0000 },
- { 31, 0x0073, 0x0c000053, 0x0c, 0x00, 0x0000 },
- { 31, 0x0073, 0x0c000053, 0x0d, 0x00, 0x0000 },
- { 31, 0x0073, 0x0c000053, 0x0e, 0x00, 0x0000 },
- { 31, 0x0073, 0x0c000053, 0x0f, 0x00, 0x0000 },
- { 32, 0x0064, 0x00000044, 0x00, 0x00, 0x0000 },
- { 32, 0x0044, 0x00000044, 0x01, 0x00, 0x0000 },
- { 32, 0x0064, 0x00000044, 0x02, 0x00, 0x0000 },
- { 32, 0x0044, 0x00000044, 0x03, 0x00, 0x0000 },
- { 32, 0x0064, 0x04000044, 0x04, 0x00, 0x0000 },
- { 32, 0x0064, 0x04000044, 0x05, 0x00, 0x0000 },
- { 32, 0x0064, 0x04000044, 0x06, 0x00, 0x0000 },
- { 32, 0x0064, 0x04000044, 0x07, 0x00, 0x0000 },
- { 32, 0x0064, 0x08000044, 0x08, 0x00, 0x0000 },
- { 32, 0x0064, 0x08000044, 0x09, 0x00, 0x0000 },
- { 32, 0x0064, 0x08000044, 0x0a, 0x00, 0x0000 },
- { 32, 0x0064, 0x08000044, 0x0b, 0x00, 0x0000 },
- { 32, 0x0064, 0x0c000044, 0x0c, 0x00, 0x0000 },
- { 32, 0x0064, 0x0c000044, 0x0d, 0x00, 0x0000 },
- { 32, 0x0064, 0x0c000044, 0x0e, 0x00, 0x0000 },
- { 32, 0x0064, 0x0c000044, 0x0f, 0x00, 0x0000 },
- { 33, 0x0066, 0x00000046, 0x00, 0x00, 0x0000 },
- { 33, 0x0046, 0x00000046, 0x01, 0x00, 0x0000 },
- { 33, 0x0066, 0x00000046, 0x02, 0x00, 0x0000 },
- { 33, 0x0046, 0x00000046, 0x03, 0x00, 0x0000 },
- { 33, 0x0066, 0x04000046, 0x04, 0x00, 0x0000 },
- { 33, 0x0066, 0x04000046, 0x05, 0x00, 0x0000 },
- { 33, 0x0066, 0x04000046, 0x06, 0x00, 0x0000 },
- { 33, 0x0066, 0x04000046, 0x07, 0x00, 0x0000 },
- { 33, 0x0066, 0x08000046, 0x08, 0x00, 0x0000 },
- { 33, 0x0066, 0x08000046, 0x09, 0x00, 0x0000 },
- { 33, 0x0066, 0x08000046, 0x0a, 0x00, 0x0000 },
- { 33, 0x0066, 0x08000046, 0x0b, 0x00, 0x0000 },
- { 33, 0x0066, 0x0c000046, 0x0c, 0x00, 0x0000 },
- { 33, 0x0066, 0x0c000046, 0x0d, 0x00, 0x0000 },
- { 33, 0x0066, 0x0c000046, 0x0e, 0x00, 0x0000 },
- { 33, 0x0066, 0x0c000046, 0x0f, 0x00, 0x0000 },
- { 34, 0x0067, 0x00000047, 0x00, 0x00, 0x0000 },
- { 34, 0x0047, 0x00000047, 0x01, 0x00, 0x0000 },
- { 34, 0x0067, 0x00000047, 0x02, 0x00, 0x0000 },
- { 34, 0x0047, 0x00000047, 0x03, 0x00, 0x0000 },
- { 34, 0x0067, 0x04000047, 0x04, 0x00, 0x0000 },
- { 34, 0x0067, 0x04000047, 0x05, 0x00, 0x0000 },
- { 34, 0x0067, 0x04000047, 0x06, 0x00, 0x0000 },
- { 34, 0x0067, 0x04000047, 0x07, 0x00, 0x0000 },
- { 34, 0x0067, 0x08000047, 0x08, 0x00, 0x0000 },
- { 34, 0x0067, 0x08000047, 0x09, 0x00, 0x0000 },
- { 34, 0x0067, 0x08000047, 0x0a, 0x00, 0x0000 },
- { 34, 0x0067, 0x08000047, 0x0b, 0x00, 0x0000 },
- { 34, 0x0067, 0x0c000047, 0x0c, 0x00, 0x0000 },
- { 34, 0x0067, 0x0c000047, 0x0d, 0x00, 0x0000 },
- { 34, 0x0067, 0x0c000047, 0x0e, 0x00, 0x0000 },
- { 34, 0x0067, 0x0c000047, 0x0f, 0x00, 0x0000 },
- { 35, 0x0068, 0x00000048, 0x00, 0x00, 0x0000 },
- { 35, 0x0048, 0x00000048, 0x01, 0x00, 0x0000 },
- { 35, 0x0068, 0x00000048, 0x02, 0x00, 0x0000 },
- { 35, 0x0048, 0x00000048, 0x03, 0x00, 0x0000 },
- { 35, 0x0068, 0x04000048, 0x04, 0x00, 0x0000 },
- { 35, 0x0068, 0x04000048, 0x05, 0x00, 0x0000 },
- { 35, 0x0068, 0x04000048, 0x06, 0x00, 0x0000 },
- { 35, 0x0068, 0x04000048, 0x07, 0x00, 0x0000 },
- { 35, 0x0068, 0x08000048, 0x08, 0x00, 0x0000 },
- { 35, 0x0068, 0x08000048, 0x09, 0x00, 0x0000 },
- { 35, 0x0068, 0x08000048, 0x0a, 0x00, 0x0000 },
- { 35, 0x0068, 0x08000048, 0x0b, 0x00, 0x0000 },
- { 35, 0x0068, 0x0c000048, 0x0c, 0x00, 0x0000 },
- { 35, 0x0068, 0x0c000048, 0x0d, 0x00, 0x0000 },
- { 35, 0x0068, 0x0c000048, 0x0e, 0x00, 0x0000 },
- { 35, 0x0068, 0x0c000048, 0x0f, 0x00, 0x0000 },
- { 36, 0x006a, 0x0000004a, 0x00, 0x00, 0x0000 },
- { 36, 0x004a, 0x0000004a, 0x01, 0x00, 0x0000 },
- { 36, 0x006a, 0x0000004a, 0x02, 0x00, 0x0000 },
- { 36, 0x004a, 0x0000004a, 0x03, 0x00, 0x0000 },
- { 36, 0x006a, 0x0400004a, 0x04, 0x00, 0x0000 },
- { 36, 0x006a, 0x0400004a, 0x05, 0x00, 0x0000 },
- { 36, 0x006a, 0x0400004a, 0x06, 0x00, 0x0000 },
- { 36, 0x006a, 0x0400004a, 0x07, 0x00, 0x0000 },
- { 36, 0x006a, 0x0800004a, 0x08, 0x00, 0x0000 },
- { 36, 0x006a, 0x0800004a, 0x09, 0x00, 0x0000 },
- { 36, 0x006a, 0x0800004a, 0x0a, 0x00, 0x0000 },
- { 36, 0x006a, 0x0800004a, 0x0b, 0x00, 0x0000 },
- { 36, 0x006a, 0x0c00004a, 0x0c, 0x00, 0x0000 },
- { 36, 0x006a, 0x0c00004a, 0x0d, 0x00, 0x0000 },
- { 36, 0x006a, 0x0c00004a, 0x0e, 0x00, 0x0000 },
- { 36, 0x006a, 0x0c00004a, 0x0f, 0x00, 0x0000 },
- { 37, 0x006b, 0x0000004b, 0x00, 0x00, 0x0000 },
- { 37, 0x004b, 0x0000004b, 0x01, 0x00, 0x0000 },
- { 37, 0x006b, 0x0000004b, 0x02, 0x00, 0x0000 },
- { 37, 0x004b, 0x0000004b, 0x03, 0x00, 0x0000 },
- { 37, 0x006b, 0x0400004b, 0x04, 0x00, 0x0000 },
- { 37, 0x006b, 0x0400004b, 0x05, 0x00, 0x0000 },
- { 37, 0x006b, 0x0400004b, 0x06, 0x00, 0x0000 },
- { 37, 0x006b, 0x0400004b, 0x07, 0x00, 0x0000 },
- { 37, 0x006b, 0x0800004b, 0x08, 0x00, 0x0000 },
- { 37, 0x006b, 0x0800004b, 0x09, 0x00, 0x0000 },
- { 37, 0x006b, 0x0800004b, 0x0a, 0x00, 0x0000 },
- { 37, 0x006b, 0x0800004b, 0x0b, 0x00, 0x0000 },
- { 37, 0x006b, 0x0c00004b, 0x0c, 0x00, 0x0000 },
- { 37, 0x006b, 0x0c00004b, 0x0d, 0x00, 0x0000 },
- { 37, 0x006b, 0x0c00004b, 0x0e, 0x00, 0x0000 },
- { 37, 0x006b, 0x0c00004b, 0x0f, 0x00, 0x0000 },
- { 38, 0x006c, 0x0000004c, 0x00, 0x00, 0x0000 },
- { 38, 0x004c, 0x0000004c, 0x01, 0x00, 0x0000 },
- { 38, 0x006c, 0x0000004c, 0x02, 0x00, 0x0000 },
- { 38, 0x004c, 0x0000004c, 0x03, 0x00, 0x0000 },
- { 38, 0x006c, 0x0400004c, 0x04, 0x00, 0x0000 },
- { 38, 0x006c, 0x0400004c, 0x05, 0x00, 0x0000 },
- { 38, 0x006c, 0x0400004c, 0x06, 0x00, 0x0000 },
- { 38, 0x006c, 0x0400004c, 0x07, 0x00, 0x0000 },
- { 38, 0x006c, 0x0800004c, 0x08, 0x00, 0x0000 },
- { 38, 0x006c, 0x0800004c, 0x09, 0x00, 0x0000 },
- { 38, 0x006c, 0x0800004c, 0x0a, 0x00, 0x0000 },
- { 38, 0x006c, 0x0800004c, 0x0b, 0x00, 0x0000 },
- { 38, 0x006c, 0x0c00004c, 0x0c, 0x00, 0x0000 },
- { 38, 0x006c, 0x0c00004c, 0x0d, 0x00, 0x0000 },
- { 38, 0x006c, 0x0c00004c, 0x0e, 0x00, 0x0000 },
- { 38, 0x006c, 0x0c00004c, 0x0f, 0x00, 0x0000 },
- { 39, 0x003b, 0x0000003b, 0x00, 0x00, 0x0000 },
- { 39, 0x003a, 0x0000003a, 0x01, 0x00, 0x0000 },
- { 40, 0x0027, 0x00000027, 0x00, 0x00, 0x0000 },
- { 40, 0x0022, 0x00000022, 0x01, 0x00, 0x0000 },
- { 40, 0x0027, 0x01001251, 0x02, 0x01, 0x0000 },
- { 40, 0x0022, 0x01001257, 0x03, 0x01, 0x0000 },
- { 40, 0x0067, 0x04000047, 0x04, 0x00, 0x0000 },
- { 41, 0x0060, 0x00000060, 0x00, 0x00, 0x0000 },
- { 41, 0x007e, 0x0000007e, 0x01, 0x00, 0x0000 },
- { 41, 0x0060, 0x01001250, 0x02, 0x01, 0x0000 },
- { 41, 0x007e, 0x01001253, 0x03, 0x01, 0x0000 },
- { 42, 0xffff, 0x01000020, 0x00, 0x04, 0x0001 },
- { 43, 0x005c, 0x0000005c, 0x00, 0x00, 0x0000 },
- { 43, 0x007c, 0x0000007c, 0x01, 0x00, 0x0000 },
- { 43, 0x005c, 0x0400005c, 0x04, 0x00, 0x0000 },
- { 44, 0x007a, 0x0000005a, 0x00, 0x00, 0x0000 },
- { 44, 0x005a, 0x0000005a, 0x01, 0x00, 0x0000 },
- { 44, 0x007a, 0x0000005a, 0x02, 0x00, 0x0000 },
- { 44, 0x005a, 0x0000005a, 0x03, 0x00, 0x0000 },
- { 44, 0x007a, 0x0400005a, 0x04, 0x00, 0x0000 },
- { 44, 0x007a, 0x0400005a, 0x05, 0x00, 0x0000 },
- { 44, 0x007a, 0x0400005a, 0x06, 0x00, 0x0000 },
- { 44, 0x007a, 0x0400005a, 0x07, 0x00, 0x0000 },
- { 44, 0x007a, 0x0800005a, 0x08, 0x00, 0x0000 },
- { 44, 0x007a, 0x0800005a, 0x09, 0x00, 0x0000 },
- { 44, 0x007a, 0x0800005a, 0x0a, 0x00, 0x0000 },
- { 44, 0x007a, 0x0800005a, 0x0b, 0x00, 0x0000 },
- { 44, 0x007a, 0x0c00005a, 0x0c, 0x00, 0x0000 },
- { 44, 0x007a, 0x0c00005a, 0x0d, 0x00, 0x0000 },
- { 44, 0x007a, 0x0c00005a, 0x0e, 0x00, 0x0000 },
- { 44, 0x007a, 0x0c00005a, 0x0f, 0x00, 0x0000 },
- { 45, 0x0078, 0x00000058, 0x00, 0x00, 0x0000 },
- { 45, 0x0058, 0x00000058, 0x01, 0x00, 0x0000 },
- { 45, 0x0078, 0x00000058, 0x02, 0x00, 0x0000 },
- { 45, 0x0058, 0x00000058, 0x03, 0x00, 0x0000 },
- { 45, 0x0078, 0x04000058, 0x04, 0x00, 0x0000 },
- { 45, 0x0078, 0x04000058, 0x05, 0x00, 0x0000 },
- { 45, 0x0078, 0x04000058, 0x06, 0x00, 0x0000 },
- { 45, 0x0078, 0x04000058, 0x07, 0x00, 0x0000 },
- { 45, 0x0078, 0x08000058, 0x08, 0x00, 0x0000 },
- { 45, 0x0078, 0x08000058, 0x09, 0x00, 0x0000 },
- { 45, 0x0078, 0x08000058, 0x0a, 0x00, 0x0000 },
- { 45, 0x0078, 0x08000058, 0x0b, 0x00, 0x0000 },
- { 45, 0x0078, 0x0c000058, 0x0c, 0x00, 0x0000 },
- { 45, 0x0078, 0x0c000058, 0x0d, 0x00, 0x0000 },
- { 45, 0x0078, 0x0c000058, 0x0e, 0x00, 0x0000 },
- { 45, 0x0078, 0x0c000058, 0x0f, 0x00, 0x0000 },
- { 46, 0x0063, 0x00000043, 0x00, 0x00, 0x0000 },
- { 46, 0x0043, 0x00000043, 0x01, 0x00, 0x0000 },
- { 46, 0x0063, 0x00000043, 0x02, 0x00, 0x0000 },
- { 46, 0x0043, 0x00000043, 0x03, 0x00, 0x0000 },
- { 46, 0x0063, 0x04000043, 0x04, 0x00, 0x0000 },
- { 46, 0x0063, 0x04000043, 0x05, 0x00, 0x0000 },
- { 46, 0x0063, 0x04000043, 0x06, 0x00, 0x0000 },
- { 46, 0x0063, 0x04000043, 0x07, 0x00, 0x0000 },
- { 46, 0x0063, 0x08000043, 0x08, 0x00, 0x0000 },
- { 46, 0x0063, 0x08000043, 0x09, 0x00, 0x0000 },
- { 46, 0x0063, 0x08000043, 0x0a, 0x00, 0x0000 },
- { 46, 0x0063, 0x08000043, 0x0b, 0x00, 0x0000 },
- { 46, 0x0063, 0x0c000043, 0x0c, 0x00, 0x0000 },
- { 46, 0x0063, 0x0c000043, 0x0d, 0x00, 0x0000 },
- { 46, 0x0063, 0x0c000043, 0x0e, 0x00, 0x0000 },
- { 46, 0x0063, 0x0c000043, 0x0f, 0x00, 0x0000 },
- { 47, 0x0076, 0x00000056, 0x00, 0x00, 0x0000 },
- { 47, 0x0056, 0x00000056, 0x01, 0x00, 0x0000 },
- { 47, 0x0076, 0x00000056, 0x02, 0x00, 0x0000 },
- { 47, 0x0056, 0x00000056, 0x03, 0x00, 0x0000 },
- { 47, 0x0076, 0x04000056, 0x04, 0x00, 0x0000 },
- { 47, 0x0076, 0x04000056, 0x05, 0x00, 0x0000 },
- { 47, 0x0076, 0x04000056, 0x06, 0x00, 0x0000 },
- { 47, 0x0076, 0x04000056, 0x07, 0x00, 0x0000 },
- { 47, 0x0076, 0x08000056, 0x08, 0x00, 0x0000 },
- { 47, 0x0076, 0x08000056, 0x09, 0x00, 0x0000 },
- { 47, 0x0076, 0x08000056, 0x0a, 0x00, 0x0000 },
- { 47, 0x0076, 0x08000056, 0x0b, 0x00, 0x0000 },
- { 47, 0x0076, 0x0c000056, 0x0c, 0x00, 0x0000 },
- { 47, 0x0076, 0x0c000056, 0x0d, 0x00, 0x0000 },
- { 47, 0x0076, 0x0c000056, 0x0e, 0x00, 0x0000 },
- { 47, 0x0076, 0x0c000056, 0x0f, 0x00, 0x0000 },
- { 48, 0x0062, 0x00000042, 0x00, 0x00, 0x0000 },
- { 48, 0x0042, 0x00000042, 0x01, 0x00, 0x0000 },
- { 48, 0x0062, 0x00000042, 0x02, 0x00, 0x0000 },
- { 48, 0x0042, 0x00000042, 0x03, 0x00, 0x0000 },
- { 48, 0x0062, 0x04000042, 0x04, 0x00, 0x0000 },
- { 48, 0x0062, 0x04000042, 0x05, 0x00, 0x0000 },
- { 48, 0x0062, 0x04000042, 0x06, 0x00, 0x0000 },
- { 48, 0x0062, 0x04000042, 0x07, 0x00, 0x0000 },
- { 48, 0x0062, 0x08000042, 0x08, 0x00, 0x0000 },
- { 48, 0x0062, 0x08000042, 0x09, 0x00, 0x0000 },
- { 48, 0x0062, 0x08000042, 0x0a, 0x00, 0x0000 },
- { 48, 0x0062, 0x08000042, 0x0b, 0x00, 0x0000 },
- { 48, 0x0062, 0x0c000042, 0x0c, 0x00, 0x0000 },
- { 48, 0x0062, 0x0c000042, 0x0d, 0x00, 0x0000 },
- { 48, 0x0062, 0x0c000042, 0x0e, 0x00, 0x0000 },
- { 48, 0x0062, 0x0c000042, 0x0f, 0x00, 0x0000 },
- { 49, 0x006e, 0x0000004e, 0x00, 0x00, 0x0000 },
- { 49, 0x004e, 0x0000004e, 0x01, 0x00, 0x0000 },
- { 49, 0x006e, 0x0000004e, 0x02, 0x00, 0x0000 },
- { 49, 0x004e, 0x0000004e, 0x03, 0x00, 0x0000 },
- { 49, 0x006e, 0x0400004e, 0x04, 0x00, 0x0000 },
- { 49, 0x006e, 0x0400004e, 0x05, 0x00, 0x0000 },
- { 49, 0x006e, 0x0400004e, 0x06, 0x00, 0x0000 },
- { 49, 0x006e, 0x0400004e, 0x07, 0x00, 0x0000 },
- { 49, 0x006e, 0x0800004e, 0x08, 0x00, 0x0000 },
- { 49, 0x006e, 0x0800004e, 0x09, 0x00, 0x0000 },
- { 49, 0x006e, 0x0800004e, 0x0a, 0x00, 0x0000 },
- { 49, 0x006e, 0x0800004e, 0x0b, 0x00, 0x0000 },
- { 49, 0x006e, 0x0c00004e, 0x0c, 0x00, 0x0000 },
- { 49, 0x006e, 0x0c00004e, 0x0d, 0x00, 0x0000 },
- { 49, 0x006e, 0x0c00004e, 0x0e, 0x00, 0x0000 },
- { 49, 0x006e, 0x0c00004e, 0x0f, 0x00, 0x0000 },
- { 50, 0x006d, 0x0000004d, 0x00, 0x00, 0x0000 },
- { 50, 0x004d, 0x0000004d, 0x01, 0x00, 0x0000 },
- { 50, 0x006d, 0x0000004d, 0x02, 0x00, 0x0000 },
- { 50, 0x004d, 0x0000004d, 0x03, 0x00, 0x0000 },
- { 50, 0x006d, 0x0400004d, 0x04, 0x00, 0x0000 },
- { 50, 0x006d, 0x0400004d, 0x05, 0x00, 0x0000 },
- { 50, 0x006d, 0x0400004d, 0x06, 0x00, 0x0000 },
- { 50, 0x006d, 0x0400004d, 0x07, 0x00, 0x0000 },
- { 50, 0x006d, 0x0800004d, 0x08, 0x00, 0x0000 },
- { 50, 0x006d, 0x0800004d, 0x09, 0x00, 0x0000 },
- { 50, 0x006d, 0x0800004d, 0x0a, 0x00, 0x0000 },
- { 50, 0x006d, 0x0800004d, 0x0b, 0x00, 0x0000 },
- { 50, 0x006d, 0x0c00004d, 0x0c, 0x00, 0x0000 },
- { 50, 0x006d, 0x0c00004d, 0x0d, 0x00, 0x0000 },
- { 50, 0x006d, 0x0c00004d, 0x0e, 0x00, 0x0000 },
- { 50, 0x006d, 0x0c00004d, 0x0f, 0x00, 0x0000 },
- { 51, 0x002c, 0x0000002c, 0x00, 0x00, 0x0000 },
- { 51, 0x003c, 0x0000003c, 0x01, 0x00, 0x0000 },
- { 51, 0x002c, 0x0100125b, 0x02, 0x01, 0x0000 },
- { 52, 0x002e, 0x0000002e, 0x00, 0x00, 0x0000 },
- { 52, 0x003e, 0x0000003e, 0x01, 0x00, 0x0000 },
- { 52, 0xffff, 0x01001120, 0x02, 0x00, 0x0000 },
- { 53, 0x002f, 0x0000002f, 0x00, 0x00, 0x0000 },
- { 53, 0x003f, 0x0000003f, 0x01, 0x00, 0x0000 },
- { 53, 0xffff, 0x01000003, 0x04, 0x00, 0x0000 },
- { 54, 0xffff, 0x01000020, 0x00, 0x04, 0x0001 },
- { 55, 0x002a, 0x2000002a, 0x00, 0x00, 0x0000 },
- { 56, 0xffff, 0x01000023, 0x00, 0x04, 0x0008 },
- { 57, 0x0020, 0x00000020, 0x00, 0x00, 0x0000 },
- { 58, 0xffff, 0x01000024, 0x00, 0x00, 0x0000 },
- { 59, 0xffff, 0x01000030, 0x00, 0x00, 0x0000 },
- { 59, 0xffff, 0x0100003c, 0x01, 0x00, 0x0000 },
- { 59, 0xffff, 0x01000048, 0x04, 0x00, 0x0000 },
- { 59, 0xffff, 0x01000000, 0x0c, 0x08, 0x0100 },
- { 60, 0xffff, 0x01000031, 0x00, 0x00, 0x0000 },
- { 60, 0xffff, 0x0100003d, 0x01, 0x00, 0x0000 },
- { 60, 0xffff, 0x01000049, 0x04, 0x00, 0x0000 },
- { 60, 0xffff, 0x01000000, 0x0c, 0x08, 0x0101 },
- { 61, 0xffff, 0x01000032, 0x00, 0x00, 0x0000 },
- { 61, 0xffff, 0x0100003e, 0x01, 0x00, 0x0000 },
- { 61, 0xffff, 0x0100004a, 0x04, 0x00, 0x0000 },
- { 61, 0xffff, 0x01000000, 0x0c, 0x08, 0x0102 },
- { 62, 0xffff, 0x01000033, 0x00, 0x00, 0x0000 },
- { 62, 0xffff, 0x0100003f, 0x01, 0x00, 0x0000 },
- { 62, 0xffff, 0x0100004b, 0x04, 0x00, 0x0000 },
- { 62, 0xffff, 0x01000000, 0x0c, 0x08, 0x0103 },
- { 63, 0xffff, 0x01000034, 0x00, 0x00, 0x0000 },
- { 63, 0xffff, 0x01000040, 0x01, 0x00, 0x0000 },
- { 63, 0xffff, 0x0100004c, 0x04, 0x00, 0x0000 },
- { 63, 0xffff, 0x01000000, 0x0c, 0x08, 0x0104 },
- { 64, 0xffff, 0x01000035, 0x00, 0x00, 0x0000 },
- { 64, 0xffff, 0x01000041, 0x01, 0x00, 0x0000 },
- { 64, 0xffff, 0x0100004d, 0x04, 0x00, 0x0000 },
- { 64, 0xffff, 0x01000000, 0x0c, 0x08, 0x0105 },
- { 65, 0xffff, 0x01000036, 0x00, 0x00, 0x0000 },
- { 65, 0xffff, 0x01000042, 0x01, 0x00, 0x0000 },
- { 65, 0xffff, 0x0100004e, 0x04, 0x00, 0x0000 },
- { 65, 0xffff, 0x01000000, 0x0c, 0x08, 0x0106 },
- { 66, 0xffff, 0x01000037, 0x00, 0x00, 0x0000 },
- { 66, 0xffff, 0x01000043, 0x01, 0x00, 0x0000 },
- { 66, 0xffff, 0x0100004f, 0x04, 0x00, 0x0000 },
- { 66, 0xffff, 0x01000000, 0x0c, 0x08, 0x0107 },
- { 67, 0xffff, 0x01000038, 0x00, 0x00, 0x0000 },
- { 67, 0xffff, 0x01000044, 0x01, 0x00, 0x0000 },
- { 67, 0xffff, 0x01000050, 0x04, 0x00, 0x0000 },
- { 67, 0xffff, 0x01000000, 0x0c, 0x08, 0x0108 },
- { 68, 0xffff, 0x01000039, 0x00, 0x00, 0x0000 },
- { 68, 0xffff, 0x01000045, 0x01, 0x00, 0x0000 },
- { 68, 0xffff, 0x01000051, 0x04, 0x00, 0x0000 },
- { 68, 0xffff, 0x01000000, 0x0c, 0x08, 0x0109 },
- { 69, 0xffff, 0x01000025, 0x00, 0x00, 0x0000 },
- { 70, 0xffff, 0x01000026, 0x00, 0x00, 0x0000 },
- { 70, 0xffff, 0x01000026, 0x08, 0x00, 0x0000 },
- { 71, 0x0037, 0x20000037, 0x00, 0x00, 0x0000 },
- { 72, 0x0038, 0x20000038, 0x00, 0x00, 0x0000 },
- { 73, 0x0039, 0x20000039, 0x00, 0x00, 0x0000 },
- { 74, 0x002d, 0x2000002d, 0x00, 0x00, 0x0000 },
- { 75, 0x0034, 0x20000034, 0x00, 0x00, 0x0000 },
- { 76, 0x0035, 0x20000035, 0x00, 0x00, 0x0000 },
- { 77, 0x0036, 0x20000036, 0x00, 0x00, 0x0000 },
- { 78, 0x002b, 0x2000002b, 0x00, 0x00, 0x0000 },
- { 79, 0x0031, 0x20000031, 0x00, 0x00, 0x0000 },
- { 80, 0x0032, 0x20000032, 0x00, 0x00, 0x0000 },
- { 81, 0x0033, 0x20000033, 0x00, 0x00, 0x0000 },
- { 82, 0x0030, 0x20000030, 0x00, 0x00, 0x0000 },
- { 83, 0x002e, 0x2000002e, 0x00, 0x00, 0x0000 },
- { 83, 0xffff, 0x01000000, 0x06, 0x08, 0x0200 },
- { 83, 0xffff, 0x01000000, 0x0c, 0x08, 0x0200 },
- { 86, 0x003c, 0x0000003c, 0x00, 0x00, 0x0000 },
- { 86, 0x003e, 0x0000003e, 0x01, 0x00, 0x0000 },
- { 86, 0x007c, 0x0000007c, 0x02, 0x00, 0x0000 },
- { 87, 0xffff, 0x0100003a, 0x00, 0x00, 0x0000 },
- { 87, 0xffff, 0x01000046, 0x01, 0x00, 0x0000 },
- { 87, 0xffff, 0x01000052, 0x04, 0x00, 0x0000 },
- { 87, 0xffff, 0x01000000, 0x0c, 0x08, 0x010a },
- { 88, 0xffff, 0x0100003b, 0x00, 0x00, 0x0000 },
- { 88, 0xffff, 0x01000047, 0x01, 0x00, 0x0000 },
- { 88, 0xffff, 0x01000000, 0x0c, 0x08, 0x010b },
- { 96, 0xffff, 0x21000005, 0x00, 0x00, 0x0000 },
- { 97, 0xffff, 0x01000021, 0x00, 0x04, 0x0004 },
- { 98, 0x002f, 0x2000002f, 0x00, 0x00, 0x0000 },
- { 99, 0x005c, 0x0400005c, 0x00, 0x00, 0x0000 },
- { 100, 0xffff, 0x01001103, 0x00, 0x04, 0x0002 },
- { 102, 0xffff, 0x01000010, 0x00, 0x00, 0x0000 },
- { 103, 0xffff, 0x01000013, 0x00, 0x00, 0x0000 },
- { 104, 0xffff, 0x01000016, 0x00, 0x00, 0x0000 },
- { 105, 0xffff, 0x01000012, 0x00, 0x00, 0x0000 },
- { 105, 0xffff, 0x01000000, 0x0c, 0x08, 0x0180 },
- { 106, 0xffff, 0x01000014, 0x00, 0x00, 0x0000 },
- { 106, 0xffff, 0x01000000, 0x0c, 0x08, 0x0181 },
- { 107, 0xffff, 0x01000011, 0x00, 0x00, 0x0000 },
- { 108, 0xffff, 0x01000015, 0x00, 0x00, 0x0000 },
- { 109, 0xffff, 0x01000017, 0x00, 0x00, 0x0000 },
- { 110, 0xffff, 0x01000006, 0x00, 0x00, 0x0000 },
- { 111, 0xffff, 0x01000007, 0x00, 0x00, 0x0000 },
- { 111, 0xffff, 0x01000000, 0x06, 0x08, 0x0200 },
- { 111, 0xffff, 0x01000000, 0x0c, 0x08, 0x0200 },
- { 113, 0xffff, 0x01000071, 0x00, 0x00, 0x0000 },
- { 114, 0xffff, 0x01000070, 0x00, 0x00, 0x0000 },
- { 115, 0xffff, 0x01000072, 0x00, 0x00, 0x0000 },
- { 116, 0xffff, 0x0100010b, 0x00, 0x00, 0x0000 },
- { 119, 0xffff, 0x01000008, 0x00, 0x00, 0x0000 },
- { 138, 0xffff, 0x01000058, 0x00, 0x00, 0x0000 },
- { 139, 0xffff, 0x01000055, 0x00, 0x00, 0x0000 },
- { 152, 0xffff, 0x010000ba, 0x00, 0x00, 0x0000 },
-
-};
-
-const QWSKeyboard::Composing QWSKbPrivate::s_keycompose_default[] = {
- { 0x0060, 0x0041, 0x00c0 },
- { 0x0060, 0x0061, 0x00e0 },
- { 0x0027, 0x0041, 0x00c1 },
- { 0x0027, 0x0061, 0x00e1 },
- { 0x005e, 0x0041, 0x00c2 },
- { 0x005e, 0x0061, 0x00e2 },
- { 0x007e, 0x0041, 0x00c3 },
- { 0x007e, 0x0061, 0x00e3 },
- { 0x0022, 0x0041, 0x00c4 },
- { 0x0022, 0x0061, 0x00e4 },
- { 0x002d, 0x0061, 0x00aa },
- { 0x002d, 0x0041, 0x00aa },
- { 0x004f, 0x0041, 0x00c5 },
- { 0x006f, 0x0061, 0x00e5 },
- { 0x0030, 0x0041, 0x00c5 },
- { 0x0030, 0x0061, 0x00e5 },
- { 0x0041, 0x0041, 0x00c5 },
- { 0x0061, 0x0061, 0x00e5 },
- { 0x00b0, 0x0041, 0x00c5 },
- { 0x00b0, 0x0061, 0x00e5 },
- { 0x0041, 0x0045, 0x00c6 },
- { 0x0061, 0x0065, 0x00e6 },
- { 0x002c, 0x0043, 0x00c7 },
- { 0x002c, 0x0063, 0x00e7 },
- { 0x005e, 0x0043, 0x00c7 },
- { 0x005e, 0x0063, 0x00e7 },
- { 0x0060, 0x0045, 0x00c8 },
- { 0x0060, 0x0065, 0x00e8 },
- { 0x0027, 0x0045, 0x00c9 },
- { 0x0027, 0x0065, 0x00e9 },
- { 0x005e, 0x0045, 0x00ca },
- { 0x005e, 0x0065, 0x00ea },
- { 0x0022, 0x0045, 0x00cb },
- { 0x0022, 0x0065, 0x00eb },
- { 0x0060, 0x0049, 0x00cc },
- { 0x0060, 0x0069, 0x00ec },
- { 0x0027, 0x0049, 0x00cd },
- { 0x0027, 0x0069, 0x00ed },
- { 0x005e, 0x0049, 0x00ce },
- { 0x005e, 0x0069, 0x00ee },
- { 0x0022, 0x0049, 0x00cf },
- { 0x0022, 0x0069, 0x00ef },
- { 0x002d, 0x0044, 0x00d0 },
- { 0x002d, 0x0064, 0x00f0 },
- { 0x005e, 0x0044, 0x00d0 },
- { 0x005e, 0x0064, 0x00f0 },
- { 0x007e, 0x004e, 0x00d1 },
- { 0x007e, 0x006e, 0x00f1 },
- { 0x005e, 0x004e, 0x00d1 },
- { 0x005e, 0x006e, 0x00f1 },
- { 0x0060, 0x004f, 0x00d2 },
- { 0x0060, 0x006f, 0x00f2 },
- { 0x0027, 0x004f, 0x00d3 },
- { 0x0027, 0x006f, 0x00f3 },
- { 0x005e, 0x004f, 0x00d4 },
- { 0x005e, 0x006f, 0x00f4 },
- { 0x007e, 0x004f, 0x00d5 },
- { 0x007e, 0x006f, 0x00f5 },
- { 0x0022, 0x004f, 0x00d6 },
- { 0x0022, 0x006f, 0x00f6 },
- { 0x002f, 0x004f, 0x00d8 },
- { 0x002f, 0x006f, 0x00f8 },
- { 0x002d, 0x006f, 0x00ba },
- { 0x002d, 0x004f, 0x00ba },
- { 0x0060, 0x0055, 0x00d9 },
- { 0x0060, 0x0075, 0x00f9 },
- { 0x0027, 0x0055, 0x00da },
- { 0x0027, 0x0075, 0x00fa },
- { 0x005e, 0x0055, 0x00db },
- { 0x005e, 0x0075, 0x00fb },
- { 0x0022, 0x0055, 0x00dc },
- { 0x0022, 0x0075, 0x00fc },
- { 0x0027, 0x0059, 0x00dd },
- { 0x0027, 0x0079, 0x00fd },
- { 0x0054, 0x0048, 0x00de },
- { 0x0074, 0x0068, 0x00fe },
- { 0x0073, 0x0073, 0x00df },
- { 0x0022, 0x0079, 0x00ff },
- { 0x0073, 0x007a, 0x00df },
- { 0x006e, 0x006e, 0x00f1 },
- { 0x006e, 0x0068, 0x00f1 },
- { 0x004e, 0x0059, 0x00d1 },
- { 0x004e, 0x004e, 0x00d1 },
- { 0x004e, 0x0048, 0x00d1 },
- { 0x004e, 0x0079, 0x00d1 },
- { 0x004e, 0x006e, 0x00d1 },
- { 0x004e, 0x0068, 0x00d1 },
- { 0x002d, 0x004c, 0x00a3 },
- { 0x003c, 0x003c, 0x00ab },
- { 0x003e, 0x003e, 0x00bb },
- { 0x003f, 0x003f, 0x00bf },
- { 0x005e, 0x003f, 0x00bf },
- { 0x0021, 0x0021, 0x00a1 },
- { 0x005e, 0x0021, 0x00a1 },
- { 0x005e, 0x0031, 0x00b9 },
- { 0x005e, 0x0032, 0x00b2 },
- { 0x005e, 0x0033, 0x00b3 },
- { 0x002b, 0x002d, 0x00b1 },
- { 0x0063, 0x003d, 0x00a2 },
- { 0x0063, 0x002f, 0x00a2 },
- { 0x002f, 0x0063, 0x00a2 },
- { 0x002d, 0x0063, 0x00a2 },
- { 0x002d, 0x0043, 0x00a2 },
- { 0x004c, 0x003d, 0x00a3 },
- { 0x002d, 0x004c, 0x00a3 },
- { 0x002d, 0x006c, 0x00a3 },
- { 0x005e, 0x002a, 0x00d7 },
- { 0x005e, 0x0078, 0x00d7 },
- { 0x0078, 0x0078, 0x00d7 },
- { 0x005e, 0x002e, 0x00b7 },
- { 0x002e, 0x002e, 0x00b7 },
- { 0x005e, 0x002f, 0x00f7 },
- { 0x005e, 0x003a, 0x00f7 },
- { 0x002d, 0x003a, 0x00f7 },
- { 0x003a, 0x002d, 0x00f7 },
- { 0x0059, 0x003d, 0x00a5 },
- { 0x002d, 0x0059, 0x00a5 },
- { 0x002d, 0x006c, 0x00a5 },
- { 0x0028, 0x0063, 0x00a9 },
- { 0x0022, 0x0063, 0x00a9 },
- { 0x002d, 0x0061, 0x00aa },
- { 0x002d, 0x0041, 0x00aa },
- { 0x002d, 0x006f, 0x00ba },
- { 0x002d, 0x004f, 0x00ba },
- { 0x0028, 0x0072, 0x00ae },
- { 0x0022, 0x0072, 0x00ae },
- { 0x006d, 0x0075, 0x00b5 },
- { 0x0031, 0x0034, 0x0152 },
- { 0x0031, 0x0032, 0x0153 },
- { 0x0033, 0x0034, 0x0178 },
- { 0x0065, 0x003d, 0x20ac },
- { 0x002d, 0x0065, 0x20ac },
- { 0x002d, 0x0045, 0x20ac },
- { 0x0076, 0x0053, 0x0160 },
- { 0x005e, 0x0053, 0x0160 },
- { 0x0076, 0x0073, 0x0161 },
- { 0x005e, 0x0073, 0x0161 },
- { 0x0076, 0x005a, 0x017d },
- { 0x005e, 0x005a, 0x017d },
- { 0x0076, 0x007a, 0x017e },
- { 0x005e, 0x007a, 0x017e },
- { 0x004f, 0x0045, 0x0152 },
- { 0x004f, 0x0065, 0x0152 },
- { 0x006f, 0x0065, 0x0153 },
- { 0x0022, 0x0059, 0x0178 },
- { 0x0069, 0x006a, 0x00ff },
- { 0x0049, 0x004a, 0x0178 },
-};
-
-#endif
diff --git a/src/gui/embedded/qkbd_qws.cpp b/src/gui/embedded/qkbd_qws.cpp
deleted file mode 100644
index 77ae47bc73..0000000000
--- a/src/gui/embedded/qkbd_qws.cpp
+++ /dev/null
@@ -1,693 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qkbd_qws.h"
-#include "qkbd_qws_p.h"
-
-#ifndef QT_NO_QWS_KEYBOARD
-
-#include <QFile>
-#include <QDataStream>
-#include <QStringList>
-
-#ifdef Q_WS_QWS
-#include "qwindowsystem_qws.h"
-#include "qscreen_qws.h"
-#endif
-
-#ifdef Q_WS_QPA
-#include <QWindowSystemInterface>
-#include <QKeyEvent>
-#endif
-
-#include "qtimer.h"
-#include <stdlib.h>
-
-//#define QT_DEBUG_KEYMAP
-
-
-QT_BEGIN_NAMESPACE
-
-class QWSKbPrivate : public QObject
-{
- Q_OBJECT
-public:
- QWSKbPrivate(QWSKeyboardHandler *h, const QString &device)
- : m_handler(h), m_modifiers(0), m_composing(0), m_dead_unicode(0xffff),
- m_no_zap(false), m_do_compose(false),
- m_keymap(0), m_keymap_size(0), m_keycompose(0), m_keycompose_size(0)
- {
- m_ar_timer = new QTimer(this);
- m_ar_timer->setSingleShot(true);
- connect(m_ar_timer, SIGNAL(timeout()), SLOT(autoRepeat()));
- m_ar_delay = 400;
- m_ar_period = 80;
-
- memset(m_locks, 0, sizeof(m_locks));
-
- QString keymap;
- QStringList args = device.split(QLatin1Char(':'));
- foreach (const QString &arg, args) {
- if (arg.startsWith(QLatin1String("keymap=")))
- keymap = arg.mid(7);
- else if (arg == QLatin1String("disable-zap"))
- m_no_zap = true;
- else if (arg == QLatin1String("enable-compose"))
- m_do_compose = true;
- else if (arg.startsWith(QLatin1String("repeat-delay=")))
- m_ar_delay = arg.mid(13).toInt();
- else if (arg.startsWith(QLatin1String("repeat-rate=")))
- m_ar_period = arg.mid(12).toInt();
- }
-
- if (keymap.isEmpty() || !loadKeymap(keymap))
- unloadKeymap();
- }
-
- ~QWSKbPrivate()
- {
- unloadKeymap();
- }
-
- void beginAutoRepeat(int uni, int code, Qt::KeyboardModifiers mod)
- {
- m_ar_unicode = uni;
- m_ar_keycode = code;
- m_ar_modifier = mod;
- m_ar_timer->start(m_ar_delay);
- }
-
- void endAutoRepeat()
- {
- m_ar_timer->stop();
- }
-
- static Qt::KeyboardModifiers toQtModifiers(quint8 mod)
- {
- Qt::KeyboardModifiers qtmod = Qt::NoModifier;
-
- if (mod & (QWSKeyboard::ModShift | QWSKeyboard::ModShiftL | QWSKeyboard::ModShiftR))
- qtmod |= Qt::ShiftModifier;
- if (mod & (QWSKeyboard::ModControl | QWSKeyboard::ModCtrlL | QWSKeyboard::ModCtrlR))
- qtmod |= Qt::ControlModifier;
- if (mod & QWSKeyboard::ModAlt)
- qtmod |= Qt::AltModifier;
-
- return qtmod;
- }
-
- void unloadKeymap();
- bool loadKeymap(const QString &file);
-
-private slots:
- void autoRepeat()
- {
- m_handler->processKeyEvent(m_ar_unicode, m_ar_keycode, m_ar_modifier, false, true);
- m_handler->processKeyEvent(m_ar_unicode, m_ar_keycode, m_ar_modifier, true, true);
- m_ar_timer->start(m_ar_period);
- }
-
-private:
- QWSKeyboardHandler *m_handler;
-
- // auto repeat simulation
- int m_ar_unicode;
- int m_ar_keycode;
- Qt::KeyboardModifiers m_ar_modifier;
- int m_ar_delay;
- int m_ar_period;
- QTimer *m_ar_timer;
-
- // keymap handling
- quint8 m_modifiers;
- quint8 m_locks[3];
- int m_composing;
- quint16 m_dead_unicode;
-
- bool m_no_zap;
- bool m_do_compose;
-
- const QWSKeyboard::Mapping *m_keymap;
- int m_keymap_size;
- const QWSKeyboard::Composing *m_keycompose;
- int m_keycompose_size;
-
- static const QWSKeyboard::Mapping s_keymap_default[];
- static const QWSKeyboard::Composing s_keycompose_default[];
-
- friend class QWSKeyboardHandler;
-};
-
-// simple builtin US keymap
-#include "qkbd_defaultmap_qws_p.h"
-
-// the unloadKeymap() function needs to be AFTER the defaultmap include,
-// since the sizeof(s_keymap_default) wouldn't work otherwise.
-
-void QWSKbPrivate::unloadKeymap()
-{
- if (m_keymap && m_keymap != s_keymap_default)
- delete [] m_keymap;
- if (m_keycompose && m_keycompose != s_keycompose_default)
- delete [] m_keycompose;
-
- m_keymap = s_keymap_default;
- m_keymap_size = sizeof(s_keymap_default) / sizeof(s_keymap_default[0]);
- m_keycompose = s_keycompose_default;
- m_keycompose_size = sizeof(s_keycompose_default) / sizeof(s_keycompose_default[0]);
-
- // reset state, so we could switch keymaps at runtime
- m_modifiers = 0;
- memset(m_locks, 0, sizeof(m_locks));
- m_composing = 0;
- m_dead_unicode = 0xffff;
-}
-
-bool QWSKbPrivate::loadKeymap(const QString &file)
-{
- QFile f(file);
-
- if (!f.open(QIODevice::ReadOnly)) {
- qWarning("Could not open keymap file '%s'", qPrintable(file));
- return false;
- }
-
- // .qmap files have a very simple structure:
- // quint32 magic (QWSKeyboard::FileMagic)
- // quint32 version (1)
- // quint32 keymap_size (# of struct QWSKeyboard::Mappings)
- // quint32 keycompose_size (# of struct QWSKeyboard::Composings)
- // all QWSKeyboard::Mappings via QDataStream::operator(<<|>>)
- // all QWSKeyboard::Composings via QDataStream::operator(<<|>>)
-
- quint32 qmap_magic, qmap_version, qmap_keymap_size, qmap_keycompose_size;
-
- QDataStream ds(&f);
-
- ds >> qmap_magic >> qmap_version >> qmap_keymap_size >> qmap_keycompose_size;
-
- if (ds.status() != QDataStream::Ok || qmap_magic != QWSKeyboard::FileMagic || qmap_version != 1 || qmap_keymap_size == 0) {
- qWarning("'%s' is ot a valid.qmap keymap file.", qPrintable(file));
- return false;
- }
-
- QWSKeyboard::Mapping *qmap_keymap = new QWSKeyboard::Mapping[qmap_keymap_size];
- QWSKeyboard::Composing *qmap_keycompose = qmap_keycompose_size ? new QWSKeyboard::Composing[qmap_keycompose_size] : 0;
-
- for (quint32 i = 0; i < qmap_keymap_size; ++i)
- ds >> qmap_keymap[i];
- for (quint32 i = 0; i < qmap_keycompose_size; ++i)
- ds >> qmap_keycompose[i];
-
- if (ds.status() != QDataStream::Ok) {
- delete [] qmap_keymap;
- delete [] qmap_keycompose;
-
- qWarning("Keymap file '%s' can not be loaded.", qPrintable(file));
- return false;
- }
-
- // unload currently active and clear state
- unloadKeymap();
-
- m_keymap = qmap_keymap;
- m_keymap_size = qmap_keymap_size;
- m_keycompose = qmap_keycompose;
- m_keycompose_size = qmap_keycompose_size;
-
- m_do_compose = true;
-
- return true;
-}
-
-
-/*!
- \class QWSKeyboardHandler
- \ingroup qws
-
- \brief The QWSKeyboardHandler class is a base class for keyboard
- drivers in Qt for Embedded Linux.
-
- Note that this class is only available in \l{Qt for Embedded Linux}.
-
- \l{Qt for Embedded Linux} provides ready-made drivers for several keyboard
- protocols, see the \l{Qt for Embedded Linux Character Input}{character
- input} documentation for details. Custom keyboard drivers can be
- implemented by subclassing the QWSKeyboardHandler class and
- creating a keyboard driver plugin (derived from
- QKbdDriverPlugin). The default implementation of the
- QKbdDriverFactory class will automatically detect the plugin, and
- load the driver into the server application at run-time using Qt's
- \l{How to Create Qt Plugins}{plugin system}.
-
- The keyboard driver receives keyboard events from the system
- device and encapsulates each event with an instance of the
- QWSEvent class which it then passes to the server application (the
- server is responsible for propagating the event to the appropriate
- client). To receive keyboard events, a QWSKeyboardHandler object
- will usually create a QSocketNotifier object for the given
- device. The QSocketNotifier class provides support for monitoring
- activity on a file descriptor. When the socket notifier receives
- data, it will call the keyboard driver's processKeyEvent()
- function to send the event to the \l{Qt for Embedded Linux} server
- application for relaying to clients.
-
-
- QWSKeyboardHandler also provides functions to control
- auto-repetion of key sequences, beginAutoRepeat() and
- endAutoRepeat(), and the transformDirKey() function enabling
- transformation of arrow keys according to the display orientation.
-
- \sa QKbdDriverPlugin, QKbdDriverFactory, {Qt for Embedded Linux Character Input}
-*/
-
-
-/*!
- Constructs a keyboard driver. The \a device argument is passed by the
- QWS_KEYBOARD environment variable.
-
- Call the QWSServer::setKeyboardHandler() function to make the
- newly created keyboard driver, the primary driver. Note that the
- primary driver is controlled by the system, i.e., the system will
- delete it upon exit.
-*/
-QWSKeyboardHandler::QWSKeyboardHandler(const QString &device)
-{
- d = new QWSKbPrivate(this, device);
-}
-
-/*!
- \overload
-*/
-QWSKeyboardHandler::QWSKeyboardHandler()
-{
- d = new QWSKbPrivate(this, QString());
-}
-
-
-
-/*!
- Destroys this keyboard driver.
-
- Do not call this function if this driver is the primary keyboard
- handler, i.e., if QWSServer::setKeyboardHandler() function has
- been called passing this driver as argument. The primary keyboard
- driver is deleted by the system.
-*/
-QWSKeyboardHandler::~QWSKeyboardHandler()
-{
- delete d;
-}
-
-
-/*!
- Sends a key event to the \l{Qt for Embedded Linux} server application.
-
- The key event is identified by its \a unicode value and the \a
- keycode, \a modifiers, \a isPress and \a autoRepeat parameters.
-
- The \a keycode parameter is the Qt keycode value as defined by the
- Qt::Key enum. The \a modifiers is an OR combination of
- Qt::KeyboardModifier values, indicating whether \gui
- Shift/Alt/Ctrl keys are pressed. The \a isPress parameter is true
- if the event is a key press event and \a autoRepeat is true if the
- event is caused by an auto-repeat mechanism and not an actual key
- press.
-
- Note that this function does not handle key mapping. Please use
- processKeycode() if you need that functionality.
-
- \sa processKeycode(), beginAutoRepeat(), endAutoRepeat(), transformDirKey()
-*/
-void QWSKeyboardHandler::processKeyEvent(int unicode, int keycode, Qt::KeyboardModifiers modifiers,
- bool isPress, bool autoRepeat)
-{
-#if defined(Q_WS_QWS)
- qwsServer->processKeyEvent(unicode, keycode, modifiers, isPress, autoRepeat);
-#elif defined(Q_WS_QPA)
- QEvent::Type type = isPress ? QEvent::KeyPress : QEvent::KeyRelease;
- QString str;
- if (unicode != 0xffff)
- str = QString(unicode);
- QWindowSystemInterface::handleKeyEvent(0, type, keycode, modifiers, str);
-#endif
-}
-
-/*!
- \fn int QWSKeyboardHandler::transformDirKey(int keycode)
-
- Transforms the arrow key specified by the given \a keycode, to the
- orientation of the display and returns the transformed keycode.
-
- The \a keycode is a Qt::Key value. The values identifying arrow
- keys are:
-
- \list
- \o Qt::Key_Left
- \o Qt::Key_Up
- \o Qt::Key_Right
- \o Qt::Key_Down
- \endlist
-
- \sa processKeyEvent()
- */
-int QWSKeyboardHandler::transformDirKey(int key)
-{
-#ifdef Q_WS_QWS
- static int dir_keyrot = -1;
- if (dir_keyrot < 0) {
- // get the rotation
- switch (qgetenv("QWS_CURSOR_ROTATION").toInt()) {
- case 90: dir_keyrot = 1; break;
- case 180: dir_keyrot = 2; break;
- case 270: dir_keyrot = 3; break;
- default: dir_keyrot = 0; break;
- }
- }
- int xf = qt_screen->transformOrientation() + dir_keyrot;
- return (key-Qt::Key_Left+xf)%4+Qt::Key_Left;
-#else
- return 0;
-#endif
-}
-
-/*!
- \fn void QWSKeyboardHandler::beginAutoRepeat(int unicode, int keycode, Qt::KeyboardModifiers modifier)
-
- Begins auto-repeating the specified key press; after a short delay
- the key press is sent periodically until the endAutoRepeat()
- function is called.
-
- The key press is specified by its \a unicode, \a keycode and \a
- modifier state.
-
- \sa endAutoRepeat(), processKeyEvent()
-*/
-void QWSKeyboardHandler::beginAutoRepeat(int uni, int code, Qt::KeyboardModifiers mod)
-{
- d->beginAutoRepeat(uni, code, mod);
-}
-
-/*!
- Stops auto-repeating a key press.
-
- \sa beginAutoRepeat(), processKeyEvent()
-*/
-void QWSKeyboardHandler::endAutoRepeat()
-{
- d->endAutoRepeat();
-}
-
-/*!
- \enum QWSKeyboardHandler::KeycodeAction
-
- This enum describes the various special actions that actual
- QWSKeyboardHandler implementations have to take care of.
-
- \value None No further action required.
-
- \value CapsLockOn Set the state of the Caps lock LED to on.
- \value CapsLockOff Set the state of the Caps lock LED to off.
- \value NumLockOn Set the state of the Num lock LED to on.
- \value NumLockOff Set the state of the Num lock LED to off.
- \value ScrollLockOn Set the state of the Scroll lock LED to on.
- \value ScrollLockOff Set the state of the Scroll lock LED to off.
-
- \value PreviousConsole Switch to the previous virtual console (by
- default Ctrl+Alt+Left on Linux).
- \value NextConsole Switch to the next virtual console (by default
- Ctrl+Alt+Right on Linux).
- \value SwitchConsoleFirst Switch to the first virtual console (0).
- \value SwitchConsoleLast Switch to the last virtual console (255).
- \value SwitchConsoleMask If the KeyAction value is between SwitchConsoleFirst
- and SwitchConsoleLast, you can use this mask to get
- the specific virtual console number to switch to.
-
- \value Reboot Reboot the machine - this is ignored in both the TTY and
- LinuxInput handlers though (by default Ctrl+Alt+Del on Linux).
-
- \sa processKeycode()
-*/
-
-/*!
- \fn QWSKeyboardHandler::KeycodeAction QWSKeyboardHandler::processKeycode(quint16 keycode, bool isPress, bool autoRepeat)
-
- \since 4.6
-
- Maps \a keycode according to a keymap and sends that key event to the
- \l{Qt for Embedded Linux} server application.
-
- Please see the \l{Qt for Embedded Linux Character Input} and the \l
- {kmap2qmap} documentations for a description on how to create and use
- keymap files.
-
- The key event is identified by its \a keycode value and the \a isPress
- and \a autoRepeat parameters.
-
- The \a keycode parameter is \bold NOT the Qt keycode value as defined by
- the Qt::Key enum. This functions expects a standard Linux 16 bit kernel
- keycode as it is used in the Linux Input Event sub-system. This
- \a keycode is transformed to a Qt::Key code by using either a
- compiled-in US keyboard layout or by dynamically loading a keymap at
- startup which can be specified via the QWS_KEYBOARD environment
- variable.
-
- The \a isPress parameter is true if the event is a key press event and
- \a autoRepeat is true if the event is caused by an auto-repeat mechanism
- and not an actual key press.
-
- The return value indicates if the actual QWSKeyboardHandler
- implementation needs to take care of a special action, like console
- switching or LED handling.
-
- If standard Linux console keymaps are used, \a keycode must be one of the
- standardized values defined in \c /usr/include/linux/input.h
-
- \sa processKeyEvent(), KeycodeAction
-*/
-
-QWSKeyboardHandler::KeycodeAction QWSKeyboardHandler::processKeycode(quint16 keycode, bool pressed, bool autorepeat)
-{
- KeycodeAction result = None;
- bool first_press = pressed && !autorepeat;
-
- const QWSKeyboard::Mapping *map_plain = 0;
- const QWSKeyboard::Mapping *map_withmod = 0;
-
- // get a specific and plain mapping for the keycode and the current modifiers
- for (int i = 0; i < d->m_keymap_size && !(map_plain && map_withmod); ++i) {
- const QWSKeyboard::Mapping *m = d->m_keymap + i;
- if (m->keycode == keycode) {
- if (m->modifiers == 0)
- map_plain = m;
-
- quint8 testmods = d->m_modifiers;
- if (d->m_locks[0] /*CapsLock*/ && (m->flags & QWSKeyboard::IsLetter))
- testmods ^= QWSKeyboard::ModShift;
- if (m->modifiers == testmods)
- map_withmod = m;
- }
- }
-
-#ifdef QT_DEBUG_KEYMAP
- qWarning("Processing key event: keycode=%3d, modifiers=%02x pressed=%d, autorepeat=%d | plain=%d, withmod=%d, size=%d", \
- keycode, d->m_modifiers, pressed ? 1 : 0, autorepeat ? 1 : 0, \
- map_plain ? map_plain - d->m_keymap : -1, \
- map_withmod ? map_withmod - d->m_keymap : -1, \
- d->m_keymap_size);
-#endif
-
- const QWSKeyboard::Mapping *it = map_withmod ? map_withmod : map_plain;
-
- if (!it) {
-#ifdef QT_DEBUG_KEYMAP
- // we couldn't even find a plain mapping
- qWarning("Could not find a suitable mapping for keycode: %3d, modifiers: %02x", keycode, d->m_modifiers);
-#endif
- return result;
- }
-
- bool skip = false;
- quint16 unicode = it->unicode;
- quint32 qtcode = it->qtcode;
-
- if ((it->flags & QWSKeyboard::IsModifier) && it->special) {
- // this is a modifier, i.e. Shift, Alt, ...
- if (pressed)
- d->m_modifiers |= quint8(it->special);
- else
- d->m_modifiers &= ~quint8(it->special);
- } else if (qtcode >= Qt::Key_CapsLock && qtcode <= Qt::Key_ScrollLock) {
- // (Caps|Num|Scroll)Lock
- if (first_press) {
- quint8 &lock = d->m_locks[qtcode - Qt::Key_CapsLock];
- lock ^= 1;
-
- switch (qtcode) {
- case Qt::Key_CapsLock : result = lock ? CapsLockOn : CapsLockOff; break;
- case Qt::Key_NumLock : result = lock ? NumLockOn : NumLockOff; break;
- case Qt::Key_ScrollLock: result = lock ? ScrollLockOn : ScrollLockOff; break;
- default : break;
- }
- }
- } else if ((it->flags & QWSKeyboard::IsSystem) && it->special && first_press) {
- switch (it->special) {
- case QWSKeyboard::SystemReboot:
- result = Reboot;
- break;
-
- case QWSKeyboard::SystemZap:
- if (!d->m_no_zap)
- qApp->quit();
- break;
-
- case QWSKeyboard::SystemConsolePrevious:
- result = PreviousConsole;
- break;
-
- case QWSKeyboard::SystemConsoleNext:
- result = NextConsole;
- break;
-
- default:
- if (it->special >= QWSKeyboard::SystemConsoleFirst &&
- it->special <= QWSKeyboard::SystemConsoleLast) {
- result = KeycodeAction(SwitchConsoleFirst + ((it->special & QWSKeyboard::SystemConsoleMask) & SwitchConsoleMask));
- }
- break;
- }
-
- skip = true; // no need to tell QWS about it
- } else if ((qtcode == Qt::Key_Multi_key) && d->m_do_compose) {
- // the Compose key was pressed
- if (first_press)
- d->m_composing = 2;
- skip = true;
- } else if ((it->flags & QWSKeyboard::IsDead) && d->m_do_compose) {
- // a Dead key was pressed
- if (first_press && d->m_composing == 1 && d->m_dead_unicode == unicode) { // twice
- d->m_composing = 0;
- qtcode = Qt::Key_unknown; // otherwise it would be Qt::Key_Dead...
- } else if (first_press && unicode != 0xffff) {
- d->m_dead_unicode = unicode;
- d->m_composing = 1;
- skip = true;
- } else {
- skip = true;
- }
- }
-
- if (!skip) {
- // a normal key was pressed
- const int modmask = Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier | Qt::KeypadModifier;
-
- // we couldn't find a specific mapping for the current modifiers,
- // or that mapping didn't have special modifiers:
- // so just report the plain mapping with additional modifiers.
- if ((it == map_plain && it != map_withmod) ||
- (map_withmod && !(map_withmod->qtcode & modmask))) {
- qtcode |= QWSKbPrivate::toQtModifiers(d->m_modifiers);
- }
-
- if (d->m_composing == 2 && first_press && !(it->flags & QWSKeyboard::IsModifier)) {
- // the last key press was the Compose key
- if (unicode != 0xffff) {
- int idx = 0;
- // check if this code is in the compose table at all
- for ( ; idx < d->m_keycompose_size; ++idx) {
- if (d->m_keycompose[idx].first == unicode)
- break;
- }
- if (idx < d->m_keycompose_size) {
- // found it -> simulate a Dead key press
- d->m_dead_unicode = unicode;
- unicode = 0xffff;
- d->m_composing = 1;
- skip = true;
- } else {
- d->m_composing = 0;
- }
- } else {
- d->m_composing = 0;
- }
- } else if (d->m_composing == 1 && first_press && !(it->flags & QWSKeyboard::IsModifier)) {
- // the last key press was a Dead key
- bool valid = false;
- if (unicode != 0xffff) {
- int idx = 0;
- // check if this code is in the compose table at all
- for ( ; idx < d->m_keycompose_size; ++idx) {
- if (d->m_keycompose[idx].first == d->m_dead_unicode && d->m_keycompose[idx].second == unicode)
- break;
- }
- if (idx < d->m_keycompose_size) {
- quint16 composed = d->m_keycompose[idx].result;
- if (composed != 0xffff) {
- unicode = composed;
- qtcode = Qt::Key_unknown;
- valid = true;
- }
- }
- }
- if (!valid) {
- unicode = d->m_dead_unicode;
- qtcode = Qt::Key_unknown;
- }
- d->m_composing = 0;
- }
-
- if (!skip) {
-#ifdef QT_DEBUG_KEYMAP
- qWarning("Processing: uni=%04x, qt=%08x, qtmod=%08x", unicode, qtcode & ~modmask, (qtcode & modmask));
-#endif
-
- // send the result to the QWS server
- processKeyEvent(unicode, qtcode & ~modmask, Qt::KeyboardModifiers(qtcode & modmask), pressed, autorepeat);
- }
- }
- return result;
-}
-
-QT_END_NAMESPACE
-
-#include "qkbd_qws.moc"
-
-#endif // QT_NO_QWS_KEYBOARD
diff --git a/src/gui/embedded/qkbd_qws.h b/src/gui/embedded/qkbd_qws.h
deleted file mode 100644
index d3be9d9997..0000000000
--- a/src/gui/embedded/qkbd_qws.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QKBD_QWS_H
-#define QKBD_QWS_H
-
-#include <QtGui/qapplication.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_QWS_KEYBOARD
-
-class QWSKbPrivate;
-
-class Q_GUI_EXPORT QWSKeyboardHandler
-{
-public:
- QWSKeyboardHandler();
- QWSKeyboardHandler(const QString &device);
- virtual ~QWSKeyboardHandler();
-
- virtual void processKeyEvent(int unicode, int keycode, Qt::KeyboardModifiers modifiers,
- bool isPress, bool autoRepeat);
-
- enum KeycodeAction {
- None = 0,
-
- CapsLockOff = 0x01000000,
- CapsLockOn = 0x01000001,
- NumLockOff = 0x02000000,
- NumLockOn = 0x02000001,
- ScrollLockOff = 0x03000000,
- ScrollLockOn = 0x03000001,
-
- Reboot = 0x04000000,
-
- PreviousConsole = 0x05000000,
- NextConsole = 0x05000001,
- SwitchConsoleFirst = 0x06000000,
- SwitchConsoleLast = 0x0600007f,
- SwitchConsoleMask = 0x0000007f,
- };
-
- KeycodeAction processKeycode(quint16 keycode, bool pressed, bool autorepeat);
-
-protected:
- int transformDirKey(int key);
- void beginAutoRepeat(int uni, int code, Qt::KeyboardModifiers mod);
- void endAutoRepeat();
-
-private:
- QWSKbPrivate *d;
-};
-
-#endif // QT_NO_QWS_KEYBOARD
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QKBD_QWS_H
diff --git a/src/gui/embedded/qkbd_qws_p.h b/src/gui/embedded/qkbd_qws_p.h
deleted file mode 100644
index bf365cb085..0000000000
--- a/src/gui/embedded/qkbd_qws_p.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWSKEYBOARD_P_H
-#define QWSKEYBOARD_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QDataStream>
-
-QT_BEGIN_NAMESPACE
-
-namespace QWSKeyboard {
- const quint32 FileMagic = 0x514d4150; // 'QMAP'
-
- struct Mapping {
- quint16 keycode;
- quint16 unicode;
- quint32 qtcode;
- quint8 modifiers;
- quint8 flags;
- quint16 special;
-
- };
-
- enum Flags {
- IsDead = 0x01,
- IsLetter = 0x02,
- IsModifier = 0x04,
- IsSystem = 0x08,
- };
-
- enum System {
- SystemConsoleFirst = 0x0100,
- SystemConsoleMask = 0x007f,
- SystemConsoleLast = 0x017f,
- SystemConsolePrevious = 0x0180,
- SystemConsoleNext = 0x0181,
- SystemReboot = 0x0200,
- SystemZap = 0x0300,
- };
-
- struct Composing {
- quint16 first;
- quint16 second;
- quint16 result;
- };
-
- enum Modifiers {
- ModPlain = 0x00,
- ModShift = 0x01,
- ModAltGr = 0x02,
- ModControl = 0x04,
- ModAlt = 0x08,
- ModShiftL = 0x10,
- ModShiftR = 0x20,
- ModCtrlL = 0x40,
- ModCtrlR = 0x80,
- // ModCapsShift = 0x100, // not supported!
- };
-};
-
-#ifndef QT_NO_DATASTREAM
-inline QDataStream &operator>>(QDataStream &ds, QWSKeyboard::Mapping &m)
-{
- return ds >> m.keycode >> m.unicode >> m.qtcode >> m.modifiers >> m.flags >> m.special;
-}
-
-inline QDataStream &operator<<(QDataStream &ds, const QWSKeyboard::Mapping &m)
-{
- return ds << m.keycode << m.unicode << m.qtcode << m.modifiers << m.flags << m.special;
-}
-
-inline QDataStream &operator>>(QDataStream &ds, QWSKeyboard::Composing &c)
-{
- return ds >> c.first >> c.second >> c.result;
-}
-
-inline QDataStream &operator<<(QDataStream &ds, const QWSKeyboard::Composing &c)
-{
- return ds << c.first << c.second << c.result;
-}
-#endif // QT_NO_DATASTREAM
-
-QT_END_NAMESPACE
-
-#endif // QWSKEYBOARD_H
diff --git a/src/gui/embedded/qkbddriverfactory_qws.cpp b/src/gui/embedded/qkbddriverfactory_qws.cpp
deleted file mode 100644
index d474b5e153..0000000000
--- a/src/gui/embedded/qkbddriverfactory_qws.cpp
+++ /dev/null
@@ -1,187 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qkbddriverfactory_qws.h"
-
-#ifndef QT_NO_QWS_KEYBOARD
-
-#include "qapplication.h"
-#include "qkbdtty_qws.h"
-#include "qkbdlinuxinput_qws.h"
-#include "qkbdum_qws.h"
-#include "qkbdvfb_qws.h"
-#include "qkbdqnx_qws.h"
-#include "qkbdintegrity_qws.h"
-#include <stdlib.h>
-#include "private/qfactoryloader_p.h"
-#include "qkbddriverplugin_qws.h"
-
-QT_BEGIN_NAMESPACE
-
-#if !defined(Q_OS_WIN32) || defined(QT_MAKEDLL)
-#ifndef QT_NO_LIBRARY
-Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
- (QWSKeyboardHandlerFactoryInterface_iid,
- QLatin1String("/kbddrivers"), Qt::CaseInsensitive))
-
-#endif //QT_NO_LIBRARY
-#endif //QT_MAKEDLL
-
-/*!
- \class QKbdDriverFactory
- \ingroup qws
-
- \brief The QKbdDriverFactory class creates keyboard drivers in
- Qt for Embedded Linux.
-
- Note that this class is only available in \l{Qt for Embedded Linux}.
-
- QKbdDriverFactory is used to detect and instantiate the available
- keyboard drivers, allowing \l{Qt for Embedded Linux} to load the preferred
- driver into the server application at runtime. The create()
- function returns a QWSKeyboardHandler object representing the
- keyboard driver identified by a given key. The valid keys
- (i.e. the supported drivers) can be retrieved using the keys()
- function.
-
- \l{Qt for Embedded Linux} provides several built-in keyboard drivers. In
- addition, custom keyboard drivers can be added using Qt's plugin
- mechanism, i.e. by subclassing the QWSKeyboardHandler class and
- creating a keyboard driver plugin (QKbdDriverPlugin). See the
- \l{Qt for Embedded Linux Character Input}{character input} documentation
- for details.
-
- \sa QWSKeyboardHandler, QKbdDriverPlugin
-*/
-
-/*!
- Creates the keyboard driver specified by the given \a key, using
- the display specified by the given \a device.
-
- Note that the keys are case-insensitive.
-
- \sa keys()
-*/
-QWSKeyboardHandler *QKbdDriverFactory::create(const QString& key, const QString& device)
-{
- QString driver = key.toLower();
-#if defined(Q_OS_QNX) && !defined(QT_NO_QWS_KBD_QNX)
- if (driver == QLatin1String("qnx") || driver.isEmpty())
- return new QWSQnxKeyboardHandler(device);
-#endif
-#if defined(Q_OS_INTEGRITY)
- if (driver == QLatin1String("integrity") || driver.isEmpty())
- return new QWSIntKeyboardHandler(device);
-#endif
-#ifndef QT_NO_QWS_KEYBOARD
-# ifndef QT_NO_QWS_KBD_TTY
- if (driver == QLatin1String("tty") || driver.isEmpty())
- return new QWSTtyKeyboardHandler(device);
-# endif
-# ifndef QT_NO_QWS_KBD_LINUXINPUT
- if (driver == QLatin1String("linuxinput") || \
- driver == QLatin1String("usb") || \
- driver == QLatin1String("linuxis"))
- return new QWSLinuxInputKeyboardHandler(device);
-# endif
-# ifndef QT_NO_QWS_KBD_UM
- if (driver == QLatin1String("um") || driver == QLatin1String("qvfbkeyboard"))
- return new QWSUmKeyboardHandler(device);
-# endif
-# ifndef QT_NO_QWS_KBD_QVFB
- if (driver == QLatin1String("qvfbkbd")
- || driver == QLatin1String("qvfbkeyboard")
- || driver == QLatin1String("qvfb"))
- return new QVFbKeyboardHandler(device);
-# endif
-#endif
-
-#if !defined(Q_OS_WIN32) || defined(QT_MAKEDLL)
-#ifndef QT_NO_LIBRARY
- if (QWSKeyboardHandlerFactoryInterface *factory = qobject_cast<QWSKeyboardHandlerFactoryInterface*>(loader()->instance(driver)))
- return factory->create(driver, device);
-#endif
-#endif
- return 0;
-}
-
-/*!
- Returns the list of valid keys, i.e. the available keyboard
- drivers.
-
- \sa create()
-*/
-QStringList QKbdDriverFactory::keys()
-{
- QStringList list;
-
-#if defined(Q_OS_QNX) && !defined(QT_NO_QWS_KBD_QNX)
- list << QLatin1String("QNX");
-#endif
-#if defined(Q_OS_INTEGRITY) && !defined(QT_NO_QWS_KBD_INTEGRITY)
- list << QLatin1String("INTEGRITY");
-#endif
-#ifndef QT_NO_QWS_KBD_TTY
- list << QLatin1String("TTY");
-#endif
-#ifndef QT_NO_QWS_KBD_LINUXINPUT
- list << QLatin1String("LinuxInput");
-#endif
-#ifndef QT_NO_QWS_KBD_UM
- list << QLatin1String("UM");
-#endif
-
-#if !defined(Q_OS_WIN32) || defined(QT_MAKEDLL)
-#ifndef QT_NO_LIBRARY
- QStringList plugins = loader()->keys();
- for (int i = 0; i < plugins.size(); ++i) {
- if (!list.contains(plugins.at(i)))
- list += plugins.at(i);
- }
-#endif //QT_NO_LIBRARY
-#endif //QT_MAKEDLL
-
- return list;
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_QWS_KEYBOARD
diff --git a/src/gui/embedded/qkbddriverfactory_qws.h b/src/gui/embedded/qkbddriverfactory_qws.h
deleted file mode 100644
index 103ceb496a..0000000000
--- a/src/gui/embedded/qkbddriverfactory_qws.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QKBDDRIVERFACTORY_QWS_H
-#define QKBDDRIVERFACTORY_QWS_H
-
-#include <QtCore/qstringlist.h>
-
-#ifndef QT_NO_QWS_KEYBOARD
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QString;
-class QWSKeyboardHandler;
-
-class Q_GUI_EXPORT QKbdDriverFactory
-{
-public:
- static QStringList keys();
- static QWSKeyboardHandler *create(const QString&, const QString&);
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QT_NO_QWS_KEYBOARD
-#endif // QKBDDRIVERFACTORY_QWS_H
diff --git a/src/gui/embedded/qkbddriverplugin_qws.cpp b/src/gui/embedded/qkbddriverplugin_qws.cpp
deleted file mode 100644
index 86cdb628d7..0000000000
--- a/src/gui/embedded/qkbddriverplugin_qws.cpp
+++ /dev/null
@@ -1,124 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qkbddriverplugin_qws.h"
-
-#ifndef QT_NO_LIBRARY
-
-#include "qkbd_qws.h"
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \class QKbdDriverPlugin
- \ingroup plugins
- \ingroup qws
-
- \brief The QKbdDriverPlugin class is an abstract base class for
- keyboard driver plugins in Qt for Embedded Linux.
-
- Note that this class is only available in \l{Qt for Embedded Linux}.
-
- \l{Qt for Embedded Linux} provides ready-made drivers for several keyboard
- protocols, see the \l{Qt for Embedded Linux Character Input}{character
- input} documentation for details. Custom keyboard drivers can be
- implemented by subclassing the QWSKeyboardHandler class and
- creating a keyboard driver plugin.
-
- A keyboard driver plugin can be created by subclassing
- QKbdDriverPlugin and reimplementing the pure virtual keys() and
- create() functions. By exporting the derived class using the
- Q_EXPORT_PLUGIN2() macro, the default implementation of the
- QKbdDriverFactory class will automatically detect the plugin and
- load the driver into the server application at run-time. See
- \l{How to Create Qt Plugins} for details.
-
- \sa QKbdDriverFactory, QWSKeyboardHandler
-*/
-
-/*!
- \fn QStringList QKbdDriverPlugin::keys() const
-
- Implement this function to return the list of valid keys, i.e. the
- keyboard drivers supported by this plugin.
-
- \l{Qt for Embedded Linux} provides ready-made drivers for several keyboard
- protocols, see the \l{Qt for Embedded Linux Character Input}{character
- input} documentation for details.
-
- \sa create()
-*/
-
-/*!
- Constructs a keyboard driver plugin with the given \a parent.
-
- Note that this constructor is invoked automatically by the
- Q_EXPORT_PLUGIN2() macro, so there is no need for calling it
- explicitly.
-*/
-QKbdDriverPlugin::QKbdDriverPlugin(QObject *parent)
- : QObject(parent)
-{
-}
-
-/*!
- Destroys the keyboard driver plugin.
-
- Note that Qt destroys a plugin automatically when it is no longer
- used, so there is no need for calling the destructor explicitly.
-*/
-QKbdDriverPlugin::~QKbdDriverPlugin()
-{
-}
-
-/*!
- \fn QScreen *QKbdDriverPlugin::create(const QString &key, const QString &device)
-
- Implement this function to create a driver matching the type
- specified by the given \a key and \a device parameters. Note that
- keys are case-insensitive.
-
- \sa keys()
-*/
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_LIBRARY
diff --git a/src/gui/embedded/qkbddriverplugin_qws.h b/src/gui/embedded/qkbddriverplugin_qws.h
deleted file mode 100644
index c9b2ad3737..0000000000
--- a/src/gui/embedded/qkbddriverplugin_qws.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QKBDDRIVERPLUGIN_QWS_H
-#define QKBDDRIVERPLUGIN_QWS_H
-
-#include <QtCore/qplugin.h>
-#include <QtCore/qfactoryinterface.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_LIBRARY
-
-class QWSKeyboardHandler;
-
-struct Q_GUI_EXPORT QWSKeyboardHandlerFactoryInterface : public QFactoryInterface
-{
- virtual QWSKeyboardHandler* create(const QString &name, const QString &device) = 0;
-};
-
-#define QWSKeyboardHandlerFactoryInterface_iid "com.trolltech.Qt.QWSKeyboardHandlerFactoryInterface"
-Q_DECLARE_INTERFACE(QWSKeyboardHandlerFactoryInterface, QWSKeyboardHandlerFactoryInterface_iid)
-
-class Q_GUI_EXPORT QKbdDriverPlugin : public QObject, public QWSKeyboardHandlerFactoryInterface
-{
- Q_OBJECT
- Q_INTERFACES(QWSKeyboardHandlerFactoryInterface:QFactoryInterface)
-public:
- explicit QKbdDriverPlugin(QObject *parent = 0);
- ~QKbdDriverPlugin();
-
- virtual QStringList keys() const = 0;
- virtual QWSKeyboardHandler* create(const QString& driver, const QString &device) = 0;
-};
-
-#endif // QT_NO_LIBRARY
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QKBDDRIVERPLUGIN_QWS_H
diff --git a/src/gui/embedded/qkbdintegrity_qws.cpp b/src/gui/embedded/qkbdintegrity_qws.cpp
deleted file mode 100644
index 2dcbb6b19b..0000000000
--- a/src/gui/embedded/qkbdintegrity_qws.cpp
+++ /dev/null
@@ -1,197 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#if !defined(QT_NO_QWS_KEYBOARD) && !defined(QT_NO_QWS_KBD_INTEGRITY)
-
-#include "qkbdintegrity_qws.h"
-#include <qwindowsystem_qws.h>
-#include <qapplication.h>
-#include <qtimer.h>
-#include <qthread.h>
-
-#include <INTEGRITY.h>
-
-
-//===========================================================================
-
-QT_BEGIN_NAMESPACE
-
-//
-// INTEGRITY keyboard
-//
-
-class QIntKeyboardListenThread;
-
-class QWSIntKbPrivate : public QObject
-{
- Q_OBJECT
- friend class QIntKeyboardListenThread;
-public:
- QWSIntKbPrivate(QWSKeyboardHandler *, const QString &device);
- ~QWSIntKbPrivate();
- void dataReady(int amount) { emit kbdDataAvailable(amount); }
- uint8_t scancodebuf[32 /* USB_SCANCODE_BUF_LEN */ ];
- uint8_t rxpost;
- uint8_t rxack;
-
-Q_SIGNALS:
- void kbdDataAvailable(int amount);
-
-private Q_SLOTS:
- void readKeyboardData(int amount);
-
-private:
- QWSKeyboardHandler *handler;
- QIntKeyboardListenThread *kbdthread;
-};
-class QIntKeyboardListenThread : public QThread
-{
-protected:
- QWSIntKbPrivate *imp;
- bool loop;
-public:
- QIntKeyboardListenThread(QWSIntKbPrivate *im) : QThread(), imp(im) {};
- ~QIntKeyboardListenThread() {};
- void run();
- void stoploop() { loop = false; };
-};
-
-
-QWSIntKeyboardHandler::QWSIntKeyboardHandler(const QString &device)
- : QWSKeyboardHandler(device)
-{
- d = new QWSIntKbPrivate(this, device);
-}
-
-QWSIntKeyboardHandler::~QWSIntKeyboardHandler()
-{
- delete d;
-}
-
-//void QWSIntKeyboardHandler::processKeyEvent(int keycode, bool isPress,
-// bool autoRepeat)
-//{
-// QWSKeyboardHandler::processKeyEvent(keycode, isPress, autoRepeat);
-//}
-
-void QIntKeyboardListenThread::run(void)
-{
- Error E;
- Buffer b;
- Connection kbdc;
- bool waitforresource = true;
- do {
- E = RequestResource((Object*)&kbdc,
- "USBKeyboardClient", "!systempassword");
- if (E == Success) {
- loop = false;
- } else {
- E = RequestResource((Object*)&kbdc,
- "KeyboardClient", "!systempassword");
- if (E == Success) {
- waitforresource = false;
- }
- }
- if (waitforresource)
- ::sleep(1);
- } while (loop && waitforresource);
- if (!loop)
- return;
- b.BufferType = DataBuffer | LastBuffer;
- b.Length = sizeof(imp->scancodebuf);
- b.TheAddress = (Address)imp->scancodebuf;
- do {
- b.Transferred = 0;
- b.TheAddress = (Address)imp->scancodebuf + imp->rxpost;
- CheckSuccess(SynchronousReceive(kbdc, &b));
- imp->rxpost += b.Transferred;
- if (imp->rxpost >= 32 /* USB_SCANCODE_BUF_LEN */)
- imp->rxpost = 0;
- if (imp->rxpost == (imp->rxack + b.Transferred) % 32 /* USB_SCANCODE_BUF_LEN */) {
- imp->kbdDataAvailable(b.Transferred);
- }
- } while (loop);
-}
-
-void QWSIntKbPrivate::readKeyboardData(int amount)
-{
- uint16_t keycode;
- do {
- if (scancodebuf[rxack] == 0xe0) {
- keycode = scancodebuf[rxack] << 8;
- rxack++;
- if (rxack >= 32 /* USB_SCANCODE_BUF_LEN */)
- rxack = 0;
- } else {
- keycode = 0;
- }
-
- handler->processKeycode(keycode + (scancodebuf[rxack] & 0x7f),
- (scancodebuf[rxack] & 0x80) == 0,
- scancodebuf[rxack] == 2);
- rxack++;
- if (rxack >= 32 /* USB_SCANCODE_BUF_LEN */)
- rxack = 0;
- } while (rxack != rxpost);
-}
-
-QWSIntKbPrivate::QWSIntKbPrivate(QWSKeyboardHandler *h, const QString &device) : handler(h)
-{
- connect(this, SIGNAL(kbdDataAvailable(int)), this, SLOT(readKeyboardData(int)));
- this->handler = handler;
- rxack = rxpost = 0;
- kbdthread = new QIntKeyboardListenThread(this);
- kbdthread->start();
-}
-
-QWSIntKbPrivate::~QWSIntKbPrivate()
-{
- kbdthread->stoploop();
- kbdthread->wait();
- delete kbdthread;
-}
-
-
-QT_END_NAMESPACE
-
-#include "qkbdintegrity_qws.moc"
-
-#endif // QT_NO_QWS_KEYBOARD || QT_NO_QWS_KBD_TTY
diff --git a/src/gui/embedded/qkbdintegrity_qws.h b/src/gui/embedded/qkbdintegrity_qws.h
deleted file mode 100644
index 811b152541..0000000000
--- a/src/gui/embedded/qkbdintegrity_qws.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QKBDINTEGRITY_QWS_H
-#define QKBDINTEGRITY_QWS_H
-
-#include <QtGui/qkbd_qws.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_QWS_KEYBOARD
-
-#ifndef QT_NO_QWS_KBD_INTEGRITY
-
-class QSocketNotifier;
-class QWSIntKbPrivate;
-
-class QWSIntKeyboardHandler : public QWSKeyboardHandler
-{
-public:
- explicit QWSIntKeyboardHandler(const QString&);
- virtual ~QWSIntKeyboardHandler();
-
-//protected:
-// virtual void processKeyEvent(int keycode, bool isPress, bool autoRepeat);
-
-private:
- QWSIntKbPrivate *d;
-};
-
-#endif // QT_NO_QWS_KBD_INTEGRITY
-
-#endif // QT_NO_QWS_KEYBOARD
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QKBDINTEGRITY_QWS_H
diff --git a/src/gui/embedded/qkbdlinuxinput_qws.cpp b/src/gui/embedded/qkbdlinuxinput_qws.cpp
deleted file mode 100644
index 376b0d0f75..0000000000
--- a/src/gui/embedded/qkbdlinuxinput_qws.cpp
+++ /dev/null
@@ -1,245 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qkbdlinuxinput_qws.h"
-
-#ifndef QT_NO_QWS_KEYBOARD
-
-#include <QSocketNotifier>
-#include <QStringList>
-
-#include <qplatformdefs.h>
-#include <private/qcore_unix_p.h> // overrides QT_OPEN
-
-#include <errno.h>
-#include <termios.h>
-
-#include <linux/kd.h>
-#include <linux/input.h>
-
-QT_BEGIN_NAMESPACE
-
-
-class QWSLinuxInputKbPrivate : public QObject
-{
- Q_OBJECT
-public:
- QWSLinuxInputKbPrivate(QWSLinuxInputKeyboardHandler *, const QString &);
- ~QWSLinuxInputKbPrivate();
-
-private:
- void switchLed(int, bool);
-
-private Q_SLOTS:
- void readKeycode();
-
-private:
- QWSLinuxInputKeyboardHandler *m_handler;
- int m_fd;
- int m_tty_fd;
- struct termios m_tty_attr;
- int m_orig_kbmode;
-};
-
-QWSLinuxInputKeyboardHandler::QWSLinuxInputKeyboardHandler(const QString &device)
- : QWSKeyboardHandler(device)
-{
- d = new QWSLinuxInputKbPrivate(this, device);
-}
-
-QWSLinuxInputKeyboardHandler::~QWSLinuxInputKeyboardHandler()
-{
- delete d;
-}
-
-bool QWSLinuxInputKeyboardHandler::filterInputEvent(quint16 &, qint32 &)
-{
- return false;
-}
-
-QWSLinuxInputKbPrivate::QWSLinuxInputKbPrivate(QWSLinuxInputKeyboardHandler *h, const QString &device)
- : m_handler(h), m_fd(-1), m_tty_fd(-1), m_orig_kbmode(K_XLATE)
-{
- setObjectName(QLatin1String("LinuxInputSubsystem Keyboard Handler"));
-
- QString dev = QLatin1String("/dev/input/event1");
- int repeat_delay = -1;
- int repeat_rate = -1;
-
- QStringList args = device.split(QLatin1Char(':'));
- foreach (const QString &arg, args) {
- if (arg.startsWith(QLatin1String("repeat-delay=")))
- repeat_delay = arg.mid(13).toInt();
- else if (arg.startsWith(QLatin1String("repeat-rate=")))
- repeat_rate = arg.mid(12).toInt();
- else if (arg.startsWith(QLatin1String("/dev/")))
- dev = arg;
- }
-
- m_fd = QT_OPEN(dev.toLocal8Bit().constData(), O_RDWR, 0);
- if (m_fd >= 0) {
- if (repeat_delay > 0 && repeat_rate > 0) {
- int kbdrep[2] = { repeat_delay, repeat_rate };
- ::ioctl(m_fd, EVIOCSREP, kbdrep);
- }
-
- QSocketNotifier *notifier;
- notifier = new QSocketNotifier(m_fd, QSocketNotifier::Read, this);
- connect(notifier, SIGNAL(activated(int)), this, SLOT(readKeycode()));
-
- // play nice in case we are started from a shell (e.g. for debugging)
- m_tty_fd = isatty(0) ? 0 : -1;
-
- if (m_tty_fd >= 0) {
- // save tty config for restore.
- tcgetattr(m_tty_fd, &m_tty_attr);
-
- struct ::termios termdata;
- tcgetattr(m_tty_fd, &termdata);
-
- // record the original mode so we can restore it again in the destructor.
- ::ioctl(m_tty_fd, KDGKBMODE, &m_orig_kbmode);
-
- // setting this translation mode is even needed in INPUT mode to prevent
- // the shell from also interpreting codes, if the process has a tty
- // attached: e.g. Ctrl+C wouldn't copy, but kill the application.
- ::ioctl(m_tty_fd, KDSKBMODE, K_MEDIUMRAW);
-
- // set the tty layer to pass-through
- termdata.c_iflag = (IGNPAR | IGNBRK) & (~PARMRK) & (~ISTRIP);
- termdata.c_oflag = 0;
- termdata.c_cflag = CREAD | CS8;
- termdata.c_lflag = 0;
- termdata.c_cc[VTIME]=0;
- termdata.c_cc[VMIN]=1;
- cfsetispeed(&termdata, 9600);
- cfsetospeed(&termdata, 9600);
- tcsetattr(m_tty_fd, TCSANOW, &termdata);
- }
- } else {
- qWarning("Cannot open keyboard input device '%s': %s", qPrintable(dev), strerror(errno));
- return;
- }
-}
-
-QWSLinuxInputKbPrivate::~QWSLinuxInputKbPrivate()
-{
- if (m_tty_fd >= 0) {
- ::ioctl(m_tty_fd, KDSKBMODE, m_orig_kbmode);
- tcsetattr(m_tty_fd, TCSANOW, &m_tty_attr);
- }
- if (m_fd >= 0)
- QT_CLOSE(m_fd);
-}
-
-void QWSLinuxInputKbPrivate::switchLed(int led, bool state)
-{
- struct ::input_event led_ie;
- ::gettimeofday(&led_ie.time, 0);
- led_ie.type = EV_LED;
- led_ie.code = led;
- led_ie.value = state;
-
- QT_WRITE(m_fd, &led_ie, sizeof(led_ie));
-}
-
-void QWSLinuxInputKbPrivate::readKeycode()
-{
- struct ::input_event buffer[32];
- int n = 0;
-
- forever {
- n = QT_READ(m_fd, reinterpret_cast<char *>(buffer) + n, sizeof(buffer) - n);
-
- if (n == 0) {
- qWarning("Got EOF from the input device.");
- return;
- } else if (n < 0 && (errno != EINTR && errno != EAGAIN)) {
- qWarning("Could not read from input device: %s", strerror(errno));
- return;
- } else if (n % sizeof(buffer[0]) == 0) {
- break;
- }
- }
-
- n /= sizeof(buffer[0]);
-
- for (int i = 0; i < n; ++i) {
- if (buffer[i].type != EV_KEY)
- continue;
-
- quint16 code = buffer[i].code;
- qint32 value = buffer[i].value;
-
- if (m_handler->filterInputEvent(code, value))
- continue;
-
- QWSKeyboardHandler::KeycodeAction ka;
- ka = m_handler->processKeycode(code, value != 0, value == 2);
-
- switch (ka) {
- case QWSKeyboardHandler::CapsLockOn:
- case QWSKeyboardHandler::CapsLockOff:
- switchLed(LED_CAPSL, ka == QWSKeyboardHandler::CapsLockOn);
- break;
-
- case QWSKeyboardHandler::NumLockOn:
- case QWSKeyboardHandler::NumLockOff:
- switchLed(LED_NUML, ka == QWSKeyboardHandler::NumLockOn);
- break;
-
- case QWSKeyboardHandler::ScrollLockOn:
- case QWSKeyboardHandler::ScrollLockOff:
- switchLed(LED_SCROLLL, ka == QWSKeyboardHandler::ScrollLockOn);
- break;
-
- default:
- // ignore console switching and reboot
- break;
- }
- }
-}
-
-QT_END_NAMESPACE
-
-#include "qkbdlinuxinput_qws.moc"
-
-#endif // QT_NO_QWS_KEYBOARD
diff --git a/src/gui/embedded/qkbdlinuxinput_qws.h b/src/gui/embedded/qkbdlinuxinput_qws.h
deleted file mode 100644
index cfc4bd6253..0000000000
--- a/src/gui/embedded/qkbdlinuxinput_qws.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QKBDLINUXINPUT_QWS_H
-#define QKBDLINUXINPUT_QWS_H
-
-#include <QtGui/qkbd_qws.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_QWS_KEYBOARD
-
-#ifndef QT_NO_QWS_KBD_LINUXINPUT
-
-class QWSLinuxInputKbPrivate;
-
-class QWSLinuxInputKeyboardHandler : public QWSKeyboardHandler
-{
-public:
- QWSLinuxInputKeyboardHandler(const QString&);
- virtual ~QWSLinuxInputKeyboardHandler();
-
- virtual bool filterInputEvent(quint16 &input_code, qint32 &input_value);
-
-private:
- QWSLinuxInputKbPrivate *d;
-};
-
-#endif // QT_NO_QWS_KBD_LINUXINPUT
-
-#endif // QT_NO_QWS_KEYBOARD
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QKBDLINUXINPUT_QWS_H
diff --git a/src/gui/embedded/qkbdqnx_qws.cpp b/src/gui/embedded/qkbdqnx_qws.cpp
deleted file mode 100644
index 5a8118d9d9..0000000000
--- a/src/gui/embedded/qkbdqnx_qws.cpp
+++ /dev/null
@@ -1,236 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qkbdqnx_qws.h"
-#include "QtCore/qsocketnotifier.h"
-#include "QtCore/qdebug.h"
-
-#include <sys/dcmd_input.h>
-#include <photon/keycodes.h>
-
-#include "qplatformdefs.h"
-#include <errno.h>
-
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \class QWSQnxKeyboardHandler
- \preliminary
- \ingroup qws
- \since 4.6
- \internal
-
- \brief The QWSQnxKeyboardHandler class implements a keyboard driver
- for the QNX \c{devi-hid} input manager.
-
- To be able to compile this mouse handler, \l{Qt for Embedded Linux}
- must be configured with the \c -qt-kbd-qnx option, see the
- \l{Qt for Embedded Linux Character Input} documentation for details.
-
- In order to use this keyboard handler, the \c{devi-hid} input manager
- must be set up and run with the resource manager interface (option \c{-r}).
- Also, Photon must not be running.
-
- Example invocation from command line: \c{/usr/photon/bin/devi-hid -Pr kbd mouse}
- Note that after running \c{devi-hid}, you will not be able to use the local
- shell anymore. It is suggested to run the command in a shell scrip, that launches
- a Qt application after invocation of \c{devi-hid}.
-
- To make \l{Qt for Embedded Linux} explicitly choose the qnx keyboard
- handler, set the QWS_KEYBOARD environment variable to \c{qnx}. By default,
- the first keyboard device (\c{/dev/devi/keyboard0}) is used. To override, pass a device
- name as the first and only parameter, for example
- \c{QWS_KEYBOARD=qnx:/dev/devi/keyboard1; export QWS_KEYBOARD}.
-
- \sa {Qt for Embedded Linux Character Input}, {Qt for Embedded Linux}
-*/
-
-/*!
- Constructs a keyboard handler for the specified \a device, defaulting to
- \c{/dev/devi/keyboard0}.
-
- Note that you should never instanciate this class, instead let QKbdDriverFactory
- handle the keyboard handlers.
-
- \sa QKbdDriverFactory
- */
-QWSQnxKeyboardHandler::QWSQnxKeyboardHandler(const QString &device)
-{
- // open the keyboard device
- keyboardFD = QT_OPEN(device.isEmpty() ? "/dev/devi/keyboard0" : device.toLatin1().constData(),
- QT_OPEN_RDONLY);
- if (keyboardFD == -1) {
- qErrnoWarning(errno, "QWSQnxKeyboardHandler: Unable to open device");
- return;
- }
-
- // create a socket notifier so we'll wake up whenever keyboard input is detected.
- QSocketNotifier *notifier = new QSocketNotifier(keyboardFD, QSocketNotifier::Read, this);
- connect(notifier, SIGNAL(activated(int)), SLOT(socketActivated()));
-
- qDebug() << "QWSQnxKeyboardHandler: connected.";
-
-}
-
-/*!
- Destroys this keyboard handler and closes the connection to the keyboard device.
- */
-QWSQnxKeyboardHandler::~QWSQnxKeyboardHandler()
-{
- QT_CLOSE(keyboardFD);
-}
-
-/*! \internal
- Translates the QNX keyboard events to Qt keyboard events
- */
-void QWSQnxKeyboardHandler::socketActivated()
-{
- _keyboard_packet packet;
-
- // read one keyboard event
- int bytesRead = QT_READ(keyboardFD, &packet, sizeof(_keyboard_packet));
- if (bytesRead == -1) {
- qErrnoWarning(errno, "QWSQnxKeyboardHandler::socketActivated(): Unable to read data.");
- return;
- }
-
- // the bytes read must be the size of a keyboard packet
- Q_ASSERT(bytesRead == sizeof(_keyboard_packet));
-
-#if 0
- qDebug() << "keyboard got scancode"
- << hex << packet.data.modifiers
- << packet.data.flags
- << packet.data.key_cap
- << packet.data.key_sym
- << packet.data.key_scan;
-#endif
-
- // QNX is nice enough to translate the raw keyboard data into a QNX data structure
- // Now we just have to translate it into a format Qt understands.
-
- // figure out whether it's a press
- bool isPress = packet.data.key_cap & KEY_DOWN;
- // figure out whether the key is still pressed and the key event is repeated
- bool isRepeat = packet.data.key_cap & KEY_REPEAT;
-
- Qt::Key key = Qt::Key_unknown;
- int unicode = 0xffff;
-
- // TODO - this switch is not complete!
- switch (packet.data.key_scan) {
- case KEYCODE_SPACE: key = Qt::Key_Space; unicode = 0x20; break;
- case KEYCODE_F1: key = Qt::Key_F1; break;
- case KEYCODE_F2: key = Qt::Key_F2; break;
- case KEYCODE_F3: key = Qt::Key_F3; break;
- case KEYCODE_F4: key = Qt::Key_F4; break;
- case KEYCODE_F5: key = Qt::Key_F5; break;
- case KEYCODE_F6: key = Qt::Key_F6; break;
- case KEYCODE_F7: key = Qt::Key_F7; break;
- case KEYCODE_F8: key = Qt::Key_F8; break;
- case KEYCODE_F9: key = Qt::Key_F9; break;
- case KEYCODE_F10: key = Qt::Key_F10; break;
- case KEYCODE_F11: key = Qt::Key_F11; break;
- case KEYCODE_F12: key = Qt::Key_F12; break;
- case KEYCODE_BACKSPACE: key = Qt::Key_Backspace; break;
- case KEYCODE_TAB: key = Qt::Key_Tab; break;
- case KEYCODE_RETURN: key = Qt::Key_Return; break;
- case KEYCODE_KP_ENTER: key = Qt::Key_Enter; break;
- case KEYCODE_UP:
- case KEYCODE_KP_UP:
- key = Qt::Key_Up; break;
- case KEYCODE_DOWN:
- case KEYCODE_KP_DOWN:
- key = Qt::Key_Down; break;
- case KEYCODE_LEFT:
- case KEYCODE_KP_LEFT:
- key = Qt::Key_Left; break;
- case KEYCODE_RIGHT:
- case KEYCODE_KP_RIGHT:
- key = Qt::Key_Right; break;
- case KEYCODE_HOME:
- case KEYCODE_KP_HOME:
- key = Qt::Key_Home; break;
- case KEYCODE_END:
- case KEYCODE_KP_END:
- key = Qt::Key_End; break;
- case KEYCODE_PG_UP:
- case KEYCODE_KP_PG_UP:
- key = Qt::Key_PageUp; break;
- case KEYCODE_PG_DOWN:
- case KEYCODE_KP_PG_DOWN:
- key = Qt::Key_PageDown; break;
- case KEYCODE_INSERT:
- case KEYCODE_KP_INSERT:
- key = Qt::Key_Insert; break;
- case KEYCODE_DELETE:
- case KEYCODE_KP_DELETE:
- key = Qt::Key_Delete; break;
- case KEYCODE_ESCAPE:
- key = Qt::Key_Escape; break;
- default: // none of the above, try the key_scan directly
- unicode = packet.data.key_scan;
- break;
- }
-
- // figure out the modifiers that are currently pressed
- Qt::KeyboardModifiers modifiers = Qt::NoModifier;
- if (packet.data.flags & KEYMOD_SHIFT)
- modifiers |= Qt::ShiftModifier;
- if (packet.data.flags & KEYMOD_CTRL)
- modifiers |= Qt::ControlModifier;
- if (packet.data.flags & KEYMOD_ALT)
- modifiers |= Qt::AltModifier;
-
- // if the unicode value is not ascii, we ignore it.
- // TODO - do a complete mapping between all QNX scan codes and Qt codes
- if (unicode != 0xffff && !isascii(unicode))
- return; // unprintable character
-
- // call processKeyEvent. This is where all the magic happens to insert a
- // key event into Qt's event loop.
- // Note that for repeated key events, isPress must be true
- // (on QNX, isPress is not set when the key event is repeated).
- processKeyEvent(unicode, key, modifiers, isPress || isRepeat, isRepeat);
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/embedded/qkbdqnx_qws.h b/src/gui/embedded/qkbdqnx_qws.h
deleted file mode 100644
index a9a8eb1655..0000000000
--- a/src/gui/embedded/qkbdqnx_qws.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QKBDQNX_QWS_H
-#define QKBDQNX_QWS_H
-
-#include <QtGui/qapplication.h>
-#include <QtGui/qkbd_qws.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#if !defined(QT_NO_QWS_KEYBOARD) && !defined(QT_NO_QWS_KBD_QNX)
-
-class Q_GUI_EXPORT QWSQnxKeyboardHandler : public QObject, public QWSKeyboardHandler
-{
- Q_OBJECT
-public:
- QWSQnxKeyboardHandler(const QString &device);
- ~QWSQnxKeyboardHandler();
-
-private Q_SLOTS:
- void socketActivated();
-
-private:
- int keyboardFD;
-};
-
-#endif // QT_NO_QWS_KEYBOARD
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QKBDQNX_QWS_H
diff --git a/src/gui/embedded/qkbdtty_qws.cpp b/src/gui/embedded/qkbdtty_qws.cpp
deleted file mode 100644
index 236769d875..0000000000
--- a/src/gui/embedded/qkbdtty_qws.cpp
+++ /dev/null
@@ -1,353 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qkbdtty_qws.h"
-
-#if !defined(QT_NO_QWS_KEYBOARD) && !defined(QT_NO_QWS_KBD_TTY)
-
-#include <QSocketNotifier>
-#include <QStringList>
-
-#include <qplatformdefs.h>
-#include <private/qcore_unix_p.h> // overrides QT_OPEN
-
-#include <errno.h>
-#include <termios.h>
-
-#if defined Q_OS_LINUX
-# include <linux/kd.h>
-# include <linux/vt.h> //TODO: move vt handling somewhere else (QLinuxFbScreen?)
-
-# include "qscreen_qws.h"
-# include "qwindowsystem_qws.h"
-# include "qapplication.h"
-# include "private/qwindowsurface_qws_p.h"
-# include "private/qwssignalhandler_p.h"
-
-# define VTACQSIG SIGUSR1
-# define VTRELSIG SIGUSR2
-#endif
-
-
-QT_BEGIN_NAMESPACE
-
-class QWSTtyKbPrivate : public QObject
-{
- Q_OBJECT
-public:
- QWSTtyKbPrivate(QWSTtyKeyboardHandler *handler, const QString &device);
- ~QWSTtyKbPrivate();
-
-private:
- void switchLed(char, bool);
- void switchConsole(int vt);
-
-private Q_SLOTS:
- void readKeycode();
- void handleConsoleSwitch(int sig);
-
-private:
- QWSTtyKeyboardHandler *m_handler;
- int m_tty_fd;
- struct termios m_tty_attr;
- char m_last_keycode;
- int m_vt_qws;
- int m_orig_kbmode;
-};
-
-
-QWSTtyKeyboardHandler::QWSTtyKeyboardHandler(const QString &device)
- : QWSKeyboardHandler(device)
-{
- d = new QWSTtyKbPrivate(this, device);
-}
-
-QWSTtyKeyboardHandler::~QWSTtyKeyboardHandler()
-{
- delete d;
-}
-
-bool QWSTtyKeyboardHandler::filterKeycode(char &)
-{
- return false;
-}
-
-QWSTtyKbPrivate::QWSTtyKbPrivate(QWSTtyKeyboardHandler *h, const QString &device)
- : m_handler(h), m_tty_fd(-1), m_last_keycode(0), m_vt_qws(0), m_orig_kbmode(K_XLATE)
-{
- setObjectName(QLatin1String("TTY Keyboard Handler"));
-#ifndef QT_NO_QWS_SIGNALHANDLER
- QWSSignalHandler::instance()->addObject(this);
-#endif
-
- QString dev = QLatin1String("/dev/tty0");
- int repeat_delay = -1;
- int repeat_rate = -1;
-
- QStringList args = device.split(QLatin1Char(':'));
- foreach (const QString &arg, args) {
- if (arg.startsWith(QLatin1String("repeat-delay=")))
- repeat_delay = arg.mid(13).toInt();
- else if (arg.startsWith(QLatin1String("repeat-rate=")))
- repeat_rate = arg.mid(12).toInt();
- else if (arg.startsWith(QLatin1String("/dev/")))
- dev = arg;
- }
-
- m_tty_fd = QT_OPEN(dev.toLocal8Bit().constData(), O_RDWR, 0);
- if (m_tty_fd >= 0) {
- if (repeat_delay > 0 && repeat_rate > 0) {
-#if defined(Q_OS_LINUX)
- struct ::kbd_repeat kbdrep = { repeat_delay, repeat_rate };
- ::ioctl(m_tty_fd, KDKBDREP, &kbdrep);
-#endif
- }
-
- QSocketNotifier *notifier;
- notifier = new QSocketNotifier(m_tty_fd, QSocketNotifier::Read, this);
- connect(notifier, SIGNAL(activated(int)), this, SLOT(readKeycode()));
-
- // save tty config for restore.
- tcgetattr(m_tty_fd, &m_tty_attr);
-
- struct ::termios termdata;
- tcgetattr(m_tty_fd, &termdata);
-
-#if defined(Q_OS_LINUX)
- // record the original mode so we can restore it again in the destructor.
- ::ioctl(m_tty_fd, KDGKBMODE, &m_orig_kbmode);
-
- // PLEASE NOTE:
- // the tty keycode interface can only report keycodes 0x01 .. 0x7f
- // KEY_MAX is however defined to 0x1ff. In practice this is sufficient
- // for a PC style keyboard though.
- // we don't support K_RAW anymore - if you need that, you have to add
- // a scan- to keycode converter yourself.
- ::ioctl(m_tty_fd, KDSKBMODE, K_MEDIUMRAW);
-#endif
-
- // set the tty layer to pass-through
- termdata.c_iflag = (IGNPAR | IGNBRK) & (~PARMRK) & (~ISTRIP);
- termdata.c_oflag = 0;
- termdata.c_cflag = CREAD | CS8;
- termdata.c_lflag = 0;
- termdata.c_cc[VTIME]=0;
- termdata.c_cc[VMIN]=1;
- cfsetispeed(&termdata, 9600);
- cfsetospeed(&termdata, 9600);
- tcsetattr(m_tty_fd, TCSANOW, &termdata);
-
-#if defined(Q_OS_LINUX)
- // VT switching is handled via unix signals
- connect(QApplication::instance(), SIGNAL(unixSignal(int)), this, SLOT(handleConsoleSwitch(int)));
- QApplication::instance()->watchUnixSignal(VTACQSIG, true);
- QApplication::instance()->watchUnixSignal(VTRELSIG, true);
-
- struct ::vt_mode vtMode;
- if (::ioctl(m_tty_fd, VT_GETMODE, &vtMode) == 0) {
- vtMode.mode = VT_PROCESS;
- vtMode.relsig = VTRELSIG;
- vtMode.acqsig = VTACQSIG;
-
- if (::ioctl(m_tty_fd, VT_SETMODE, &vtMode) == 0) {
- struct ::vt_stat vtStat;
- ::memset(&vtStat, 0, sizeof(vtStat));
-
- if (::ioctl(m_tty_fd, VT_GETSTATE, &vtStat) == 0 ) {
- m_vt_qws = vtStat.v_active;
- }
- }
- }
-
- if (!m_vt_qws)
- qWarning("Could not initialize virtual console switching");
-#endif
- } else {
- qWarning("Cannot open input device '%s': %s", qPrintable(dev), strerror(errno));
- return;
- }
-
-}
-
-QWSTtyKbPrivate::~QWSTtyKbPrivate()
-{
- if (m_tty_fd >= 0) {
-#if defined(Q_OS_LINUX)
- ::ioctl(m_tty_fd, KDSKBMODE, m_orig_kbmode);
-#endif
- tcsetattr(m_tty_fd, TCSANOW, &m_tty_attr);
- QT_CLOSE(m_tty_fd);
- }
-}
-
-
-
-void QWSTtyKbPrivate::switchLed(char led, bool state)
-{
-#if defined(Q_OS_LINUX)
- char ledstate;
-
- ::ioctl(m_tty_fd, KDGETLED, &ledstate);
- if (state)
- ledstate |= led;
- else
- ledstate &= ~led;
- ::ioctl(m_tty_fd, KDSETLED, ledstate);
-#endif
-}
-
-void QWSTtyKbPrivate::readKeycode()
-{
- char buffer[32];
- int n = 0;
-
- forever {
- n = QT_READ(m_tty_fd, buffer + n, 32 - n);
-
- if (n == 0) {
- qWarning("Got EOF from the input device.");
- return;
- } else if (n < 0 && (errno != EINTR && errno != EAGAIN)) {
- qWarning("Could not read from input device: %s", strerror(errno));
- return;
- } else {
- break;
- }
- }
-
- for (int i = 0; i < n; ++i) {
- if (m_handler->filterKeycode(buffer[i]))
- continue;
-
- QWSKeyboardHandler::KeycodeAction ka;
- ka = m_handler->processKeycode(buffer[i] & 0x7f, (buffer[i] & 0x80) == 0x00, buffer[i] == m_last_keycode);
- m_last_keycode = buffer[i];
-
- switch (ka) {
- case QWSKeyboardHandler::CapsLockOn:
- case QWSKeyboardHandler::CapsLockOff:
- switchLed(LED_CAP, ka == QWSKeyboardHandler::CapsLockOn);
- break;
-
- case QWSKeyboardHandler::NumLockOn:
- case QWSKeyboardHandler::NumLockOff:
- switchLed(LED_NUM, ka == QWSKeyboardHandler::NumLockOn);
- break;
-
- case QWSKeyboardHandler::ScrollLockOn:
- case QWSKeyboardHandler::ScrollLockOff:
- switchLed(LED_SCR, ka == QWSKeyboardHandler::ScrollLockOn);
- break;
-
- case QWSKeyboardHandler::PreviousConsole:
- switchConsole(qBound(1, m_vt_qws - 1, 10));
- break;
-
- case QWSKeyboardHandler::NextConsole:
- switchConsole(qBound(1, m_vt_qws + 1, 10));
- break;
-
- default:
- if (ka >= QWSKeyboardHandler::SwitchConsoleFirst &&
- ka <= QWSKeyboardHandler::SwitchConsoleLast) {
- switchConsole(1 + (ka & QWSKeyboardHandler::SwitchConsoleMask));
- }
- //ignore reboot
- break;
- }
- }
-}
-
-
-void QWSTtyKbPrivate::switchConsole(int vt)
-{
-#if defined(Q_OS_LINUX)
- if (m_vt_qws && vt && (m_tty_fd >= 0 ))
- ::ioctl(m_tty_fd, VT_ACTIVATE, vt);
-#endif
-}
-
-void QWSTtyKbPrivate::handleConsoleSwitch(int sig)
-{
-#if defined(Q_OS_LINUX)
- // received a notification from the kernel that the current VT is
- // changing: either enable or disable QWS painting accordingly.
-
- if (sig == VTACQSIG) {
- if (::ioctl(m_tty_fd, VT_RELDISP, VT_ACKACQ) == 0) {
- qwsServer->enablePainting(true);
- qt_screen->restore();
- qwsServer->resumeMouse();
- qwsServer->refresh();
- }
- } else if (sig == VTRELSIG) {
- qwsServer->enablePainting(false);
-
- // Check for reserved surfaces which might still do painting
- bool allWindowsHidden = true;
- const QList<QWSWindow*> windows = QWSServer::instance()->clientWindows();
- for (int i = 0; i < windows.size(); ++i) {
- const QWSWindow *w = windows.at(i);
- QWSWindowSurface *s = w->windowSurface();
- if (s && s->isRegionReserved() && !w->allocatedRegion().isEmpty()) {
- allWindowsHidden = false;
- break;
- }
- }
-
- if (!allWindowsHidden) {
- ::ioctl(m_tty_fd, VT_RELDISP, 0); // abort console switch
- qwsServer->enablePainting(true);
- } else if (::ioctl(m_tty_fd, VT_RELDISP, 1) == 0) {
- qt_screen->save();
- qwsServer->suspendMouse();
- } else {
- qwsServer->enablePainting(true);
- }
- }
-#endif
-}
-
-QT_END_NAMESPACE
-
-#include "qkbdtty_qws.moc"
-
-#endif // QT_NO_QWS_KEYBOARD || QT_NO_QWS_KBD_TTY
diff --git a/src/gui/embedded/qkbdtty_qws.h b/src/gui/embedded/qkbdtty_qws.h
deleted file mode 100644
index f989f831e4..0000000000
--- a/src/gui/embedded/qkbdtty_qws.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QKBDTTY_QWS_H
-#define QKBDTTY_QWS_H
-
-#include <QtGui/qkbd_qws.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_QWS_KEYBOARD
-
-#ifndef QT_NO_QWS_KBD_TTY
-
-class QWSTtyKbPrivate;
-
-class QWSTtyKeyboardHandler : public QWSKeyboardHandler
-{
-public:
- explicit QWSTtyKeyboardHandler(const QString&);
- virtual ~QWSTtyKeyboardHandler();
-
- virtual bool filterKeycode(char &code);
-
-private:
- QWSTtyKbPrivate *d;
-};
-
-#endif // QT_NO_QWS_KBD_TTY
-
-#endif // QT_NO_QWS_KEYBOARD
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QKBDTTY_QWS_H
diff --git a/src/gui/embedded/qkbdum_qws.cpp b/src/gui/embedded/qkbdum_qws.cpp
deleted file mode 100644
index 4fbe03e319..0000000000
--- a/src/gui/embedded/qkbdum_qws.cpp
+++ /dev/null
@@ -1,144 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qkbdum_qws.h"
-#include "qvfbhdr.h"
-
-#if !defined(QT_NO_QWS_KEYBOARD) && !defined(QT_NO_QWS_KBD_UM)
-
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-
-#include <qstring.h>
-#include <qwindowsystem_qws.h>
-#include <qsocketnotifier.h>
-#include "qplatformdefs.h"
-
-QT_BEGIN_NAMESPACE
-
-class QWSUmKeyboardHandlerPrivate : public QObject
-{
- Q_OBJECT
-
-public:
- QWSUmKeyboardHandlerPrivate(const QString&);
- ~QWSUmKeyboardHandlerPrivate();
-
-private slots:
- void readKeyboardData();
-
-private:
- int kbdFD;
- int kbdIdx;
- const int kbdBufferLen;
- unsigned char *kbdBuffer;
- QSocketNotifier *notifier;
-};
-
-QWSUmKeyboardHandlerPrivate::QWSUmKeyboardHandlerPrivate(const QString &device)
- : kbdFD(-1), kbdIdx(0), kbdBufferLen(sizeof(QVFbKeyData)*5)
-{
- kbdBuffer = new unsigned char [kbdBufferLen];
-
- if ((kbdFD = QT_OPEN((const char *)device.toLocal8Bit(), O_RDONLY | O_NDELAY, 0)) < 0) {
- qDebug("Cannot open %s (%s)", (const char *)device.toLocal8Bit(),
- strerror(errno));
- } else {
- // Clear pending input
- char buf[2];
- while (QT_READ(kbdFD, buf, 1) > 0) { }
-
- notifier = new QSocketNotifier(kbdFD, QSocketNotifier::Read, this);
- connect(notifier, SIGNAL(activated(int)),this, SLOT(readKeyboardData()));
- }
-}
-
-QWSUmKeyboardHandlerPrivate::~QWSUmKeyboardHandlerPrivate()
-{
- if (kbdFD >= 0)
- QT_CLOSE(kbdFD);
- delete [] kbdBuffer;
-}
-
-
-void QWSUmKeyboardHandlerPrivate::readKeyboardData()
-{
- int n;
- do {
- n = QT_READ(kbdFD, kbdBuffer+kbdIdx, kbdBufferLen - kbdIdx);
- if (n > 0)
- kbdIdx += n;
- } while (n > 0);
-
- int idx = 0;
- while (kbdIdx - idx >= (int)sizeof(QVFbKeyData)) {
- QVFbKeyData *kd = (QVFbKeyData *)(kbdBuffer + idx);
- // Qtopia Key filters must still work.
- QWSServer::processKeyEvent(kd->unicode, kd->keycode, kd->modifiers, kd->press, kd->repeat);
- idx += sizeof(QVFbKeyData);
- }
-
- int surplus = kbdIdx - idx;
- for (int i = 0; i < surplus; i++)
- kbdBuffer[i] = kbdBuffer[idx+i];
- kbdIdx = surplus;
-}
-
-QWSUmKeyboardHandler::QWSUmKeyboardHandler(const QString &device)
- : QWSKeyboardHandler()
-{
- d = new QWSUmKeyboardHandlerPrivate(device);
-}
-
-QWSUmKeyboardHandler::~QWSUmKeyboardHandler()
-{
- delete d;
-}
-
-QT_END_NAMESPACE
-
-#include "qkbdum_qws.moc"
-
-#endif // QT_NO_QWS_KEYBOARD && QT_NO_QWS_KBD_UM
diff --git a/src/gui/embedded/qkbdum_qws.h b/src/gui/embedded/qkbdum_qws.h
deleted file mode 100644
index dea26db833..0000000000
--- a/src/gui/embedded/qkbdum_qws.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QKBDUM_QWS_H
-#define QKBDUM_QWS_H
-
-#include <QtGui/qkbd_qws.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_QWS_KEYBOARD
-
-#ifndef QT_NO_QWS_KBD_UM
-
-class QWSUmKeyboardHandlerPrivate;
-
-class QWSUmKeyboardHandler : public QWSKeyboardHandler
-{
-public:
- QWSUmKeyboardHandler(const QString &);
- virtual ~QWSUmKeyboardHandler();
-
-private:
-
- QWSUmKeyboardHandlerPrivate *d;
-};
-#endif // QT_NO_QWS_KBD_UM
-
-#endif // QT_NO_QWS_KEYBOARD
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QKBDUM_QWS_H
diff --git a/src/gui/embedded/qkbdvfb_qws.cpp b/src/gui/embedded/qkbdvfb_qws.cpp
deleted file mode 100644
index 42ebc7cc88..0000000000
--- a/src/gui/embedded/qkbdvfb_qws.cpp
+++ /dev/null
@@ -1,124 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-
-#include <qvfbhdr.h>
-#include <qkbdvfb_qws.h>
-
-#ifndef QT_NO_QWS_KEYBOARD
-#ifndef QT_NO_QWS_KBD_QVFB
-
-#include <qwindowsystem_qws.h>
-#include <qsocketnotifier.h>
-#include <qapplication.h>
-#include <private/qcore_unix_p.h> // overrides QT_OPEN
-
-QT_BEGIN_NAMESPACE
-
-QVFbKeyboardHandler::QVFbKeyboardHandler(const QString &device)
- : QObject()
-{
- terminalName = device;
- if (terminalName.isEmpty())
- terminalName = QLatin1String("/dev/vkdb");
- kbdFD = -1;
- kbdIdx = 0;
- kbdBufferLen = sizeof(QVFbKeyData) * 5;
- kbdBuffer = new unsigned char [kbdBufferLen];
-
- if ((kbdFD = QT_OPEN(terminalName.toLatin1().constData(), O_RDONLY | O_NDELAY)) < 0) {
- qWarning("Cannot open %s (%s)", terminalName.toLatin1().constData(),
- strerror(errno));
- } else {
- // Clear pending input
- char buf[2];
- while (QT_READ(kbdFD, buf, 1) > 0) { }
-
- notifier = new QSocketNotifier(kbdFD, QSocketNotifier::Read, this);
- connect(notifier, SIGNAL(activated(int)),this, SLOT(readKeyboardData()));
- }
-}
-
-QVFbKeyboardHandler::~QVFbKeyboardHandler()
-{
- if (kbdFD >= 0)
- QT_CLOSE(kbdFD);
- delete [] kbdBuffer;
-}
-
-
-void QVFbKeyboardHandler::readKeyboardData()
-{
- int n;
- do {
- n = QT_READ(kbdFD, kbdBuffer+kbdIdx, kbdBufferLen - kbdIdx);
- if (n > 0)
- kbdIdx += n;
- } while (n > 0);
-
- int idx = 0;
- while (kbdIdx - idx >= (int)sizeof(QVFbKeyData)) {
- QVFbKeyData *kd = (QVFbKeyData *)(kbdBuffer + idx);
- if (kd->unicode == 0 && kd->keycode == 0 && kd->modifiers == 0 && kd->press) {
- // magic exit key
- qWarning("Instructed to quit by Virtual Keyboard");
- qApp->quit();
- }
- QWSServer::processKeyEvent(kd->unicode ? kd->unicode : 0xffff, kd->keycode, kd->modifiers, kd->press, kd->repeat);
- idx += sizeof(QVFbKeyData);
- }
-
- int surplus = kbdIdx - idx;
- for (int i = 0; i < surplus; i++)
- kbdBuffer[i] = kbdBuffer[idx+i];
- kbdIdx = surplus;
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_QWS_KBD_QVFB
-#endif // QT_NO_QWS_KEYBOARD
diff --git a/src/gui/embedded/qkbdvfb_qws.h b/src/gui/embedded/qkbdvfb_qws.h
deleted file mode 100644
index 620905818e..0000000000
--- a/src/gui/embedded/qkbdvfb_qws.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QKBDVFB_QWS_H
-#define QKBDVFB_QWS_H
-
-#include <QtGui/qkbd_qws.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_QWS_KEYBOARD
-
-#ifndef QT_NO_QWS_KBD_QVFB
-
-class QSocketNotifier;
-
-class QVFbKeyboardHandler : public QObject, public QWSKeyboardHandler
-{
- Q_OBJECT
-public:
- QVFbKeyboardHandler(const QString &device);
- virtual ~QVFbKeyboardHandler();
-
-private Q_SLOTS:
- void readKeyboardData();
-
-private:
- QString terminalName;
- int kbdFD;
- int kbdIdx;
- int kbdBufferLen;
- unsigned char *kbdBuffer;
- QSocketNotifier *notifier;
-};
-
-#endif // QT_NO_QWS_KBD_QVFB
-
-#endif // QT_NO_QWS_KEYBOARD
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QKBDVFB_QWS_H
diff --git a/src/gui/embedded/qlock.cpp b/src/gui/embedded/qlock.cpp
deleted file mode 100644
index bb442e4aaf..0000000000
--- a/src/gui/embedded/qlock.cpp
+++ /dev/null
@@ -1,325 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qlock_p.h"
-
-
-#ifdef QT_NO_QWS_MULTIPROCESS
-
-QT_BEGIN_NAMESPACE
-
-/* no multiprocess - use a dummy */
-
-QLock::QLock(const QString & /*filename*/, char /*id*/, bool /*create*/)
- : type(Read), data(0)
-{
-}
-
-QLock::~QLock()
-{
-}
-
-bool QLock::isValid() const
-{
- return true;
-}
-
-void QLock::lock(Type t)
-{
- data = (QLockData *)-1;
- type = t;
-}
-
-void QLock::unlock()
-{
- data = 0;
-}
-
-bool QLock::locked() const
-{
- return data;
-}
-
-QT_END_NAMESPACE
-
-#else // QT_NO_QWS_MULTIPROCESS
-
-#if defined(Q_OS_DARWIN)
-# define Q_NO_SEMAPHORE
-#endif
-
-#include "qwssignalhandler_p.h"
-
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/ipc.h>
-#if defined(Q_NO_SEMAPHORE)
-# include <sys/stat.h>
-# include <sys/file.h>
-#else
-# include <sys/sem.h>
-#endif
-#include <string.h>
-#include <errno.h>
-#include <qdebug.h>
-
-#include <private/qcore_unix_p.h> // overrides QT_OPEN
-
-QT_BEGIN_NAMESPACE
-
-#define MAX_LOCKS 200 // maximum simultaneous read locks
-
-class QLockData
-{
-public:
-#ifdef Q_NO_SEMAPHORE
- QByteArray file;
-#endif // Q_NO_SEMAPHORE
- int id;
- int count;
- bool owned;
-};
-
-/*!
- \class QLock
- \brief The QLock class is a wrapper for a System V shared semaphore.
-
- \ingroup qws
-
- \internal
-
- It is used by \l{Qt for Embedded Linux} for synchronizing access to the graphics
- card and shared memory region between processes.
-*/
-
-/*!
- \enum QLock::Type
-
- \value Read
- \value Write
-*/
-
-/*!
- \fn QLock::QLock(const QString &filename, char id, bool create)
-
- Creates a lock. \a filename is the file path of the Unix-domain
- socket the \l{Qt for Embedded Linux} client is using. \a id is the name of the
- particular lock to be created on that socket. If \a create is true
- the lock is to be created (as the Qt for Embedded Linux server does); if \a
- create is false the lock should exist already (as the Qt for Embedded Linux
- client expects).
-*/
-
-QLock::QLock(const QString &filename, char id, bool create)
-{
- data = new QLockData;
- data->count = 0;
-#ifdef Q_NO_SEMAPHORE
- data->file = QString(filename+id).toLocal8Bit().constData();
- for(int x = 0; x < 2; x++) {
- data->id = QT_OPEN(data->file, O_RDWR | (x ? O_CREAT : 0), S_IRWXU);
- if(data->id != -1 || !create) {
- data->owned = x;
- break;
- }
- }
-#else
- key_t semkey = ftok(filename.toLocal8Bit().constData(), id);
- data->id = semget(semkey,0,0);
- data->owned = create;
- if (create) {
- qt_semun arg; arg.val = 0;
- if (data->id != -1)
- semctl(data->id,0,IPC_RMID,arg);
- data->id = semget(semkey,1,IPC_CREAT|0600);
- arg.val = MAX_LOCKS;
- semctl(data->id,0,SETVAL,arg);
-
- QWSSignalHandler::instance()->addSemaphore(data->id);
- }
-#endif
- if (data->id == -1) {
- int eno = errno;
- qWarning("Cannot %s semaphore %s '%c'", (create ? "create" : "get"),
- qPrintable(filename), id);
- qDebug() << "Error" << eno << strerror(eno);
- }
-}
-
-/*!
- \fn QLock::~QLock()
-
- Destroys a lock
-*/
-
-QLock::~QLock()
-{
- if (locked())
- unlock();
-#ifdef Q_NO_SEMAPHORE
- if(isValid()) {
- QT_CLOSE(data->id);
- if(data->owned)
- unlink(data->file);
- }
-#else
- if(data->owned)
- QWSSignalHandler::instance()->removeSemaphore(data->id);
-#endif
- delete data;
-}
-
-/*!
- \fn bool QLock::isValid() const
-
- Returns true if the lock constructor was successful; returns false if
- the lock could not be created or was not available to connect to.
-*/
-
-bool QLock::isValid() const
-{
- return (data->id != -1);
-}
-
-/*!
- Locks the semaphore with a lock of type \a t. Locks can either be
- \c Read or \c Write. If a lock is \c Read, attempts by other
- processes to obtain \c Read locks will succeed, and \c Write
- attempts will block until the lock is unlocked. If locked as \c
- Write, all attempts to lock by other processes will block until
- the lock is unlocked. Locks are stacked: i.e. a given QLock can be
- locked multiple times by the same process without blocking, and
- will only be unlocked after a corresponding number of unlock()
- calls.
-*/
-
-void QLock::lock(Type t)
-{
- if (!data->count) {
-#ifdef Q_NO_SEMAPHORE
- int op = LOCK_SH;
- if(t == Write)
- op = LOCK_EX;
- for(int rv=1; rv;) {
- rv = flock(data->id, op);
- if (rv == -1 && errno != EINTR)
- qDebug("Semop lock failure %s",strerror(errno));
- }
-#else
- sembuf sops;
- sops.sem_num = 0;
- sops.sem_flg = SEM_UNDO;
-
- if (t == Write) {
- sops.sem_op = -MAX_LOCKS;
- type = Write;
- } else {
- sops.sem_op = -1;
- type = Read;
- }
-
- int rv;
- do {
- rv = semop(data->id,&sops,1);
- if (rv == -1 && errno != EINTR)
- qDebug("Semop lock failure %s",strerror(errno));
- } while (rv == -1 && errno == EINTR);
-#endif
- }
- data->count++;
-}
-
-/*!
- \fn void QLock::unlock()
-
- Unlocks the semaphore. If other processes were blocking waiting to
- lock() the semaphore, one of them will wake up and succeed in
- lock()ing.
-*/
-
-void QLock::unlock()
-{
- if(data->count) {
- data->count--;
- if(!data->count) {
-#ifdef Q_NO_SEMAPHORE
- for(int rv=1; rv;) {
- rv = flock(data->id, LOCK_UN);
- if (rv == -1 && errno != EINTR)
- qDebug("Semop lock failure %s",strerror(errno));
- }
-#else
- sembuf sops;
- sops.sem_num = 0;
- sops.sem_op = 1;
- sops.sem_flg = SEM_UNDO;
- if (type == Write)
- sops.sem_op = MAX_LOCKS;
-
- int rv;
- do {
- rv = semop(data->id,&sops,1);
- if (rv == -1 && errno != EINTR)
- qDebug("Semop unlock failure %s",strerror(errno));
- } while (rv == -1 && errno == EINTR);
-#endif
- }
- } else {
- qDebug("Unlock without corresponding lock");
- }
-}
-
-/*!
- \fn bool QLock::locked() const
-
- Returns true if the lock is currently held by the current process;
- otherwise returns false.
-*/
-
-bool QLock::locked() const
-{
- return (data->count > 0);
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_QWS_MULTIPROCESS
-
diff --git a/src/gui/embedded/qlock_p.h b/src/gui/embedded/qlock_p.h
deleted file mode 100644
index fc10c2fc36..0000000000
--- a/src/gui/embedded/qlock_p.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QLOCK_P_H
-#define QLOCK_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. This header file may
-// change from version to version without notice, or even be
-// removed.
-//
-// We mean it.
-//
-
-#include "QtCore/qstring.h"
-
-QT_BEGIN_NAMESPACE
-
-class QLockData;
-
-class Q_GUI_EXPORT QLock
-{
-public:
- QLock(const QString &filename, char id, bool create = false);
- ~QLock();
-
- enum Type { Read, Write };
-
- bool isValid() const;
- void lock(Type type);
- void unlock();
- bool locked() const;
-
-private:
- Type type;
- QLockData *data;
-};
-
-
-// Nice class for ensuring the lock is released.
-// Just create one on the stack and the lock is automatically released
-// when QLockHandle is destructed.
-class Q_GUI_EXPORT QLockHandle
-{
-public:
- QLockHandle(QLock *l, QLock::Type type) : qlock(l) { qlock->lock(type); }
- ~QLockHandle() { if (locked()) qlock->unlock(); }
-
- void lock(QLock::Type type) { qlock->lock(type); }
- void unlock() { qlock->unlock(); }
- bool locked() const { return qlock->locked(); }
-
-private:
- QLock *qlock;
-};
-
-QT_END_NAMESPACE
-
-#endif // QLOCK_P_H
diff --git a/src/gui/embedded/qmouse_qws.cpp b/src/gui/embedded/qmouse_qws.cpp
deleted file mode 100644
index f982988d58..0000000000
--- a/src/gui/embedded/qmouse_qws.cpp
+++ /dev/null
@@ -1,653 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qmouse_qws.h"
-#include "qwindowsystem_qws.h"
-#include "qscreen_qws.h"
-#include "qapplication.h"
-#include "qtextstream.h"
-#include "qfile.h"
-#include "qdebug.h"
-#include "qscreen_qws.h"
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \class QWSPointerCalibrationData
- \ingroup qws
-
- \brief The QWSPointerCalibrationData class is a container for
- mouse calibration data in Qt for Embedded Linux.
-
- Note that this class is only available in \l{Qt for Embedded Linux}.
-
- QWSPointerCalibrationData stores device and screen coordinates in
- the devPoints and screenPoints variables, respectively.
-
- A calibration program should create a QWSPointerCalibrationData
- object, fill the devPoints and screenPoints variables with its
- device and screen coordinates, and pass the object to the mouse
- driver using the QWSMouseHandler::calibrate() function.
-
- \sa QWSCalibratedMouseHandler, {Mouse Calibration Example}
-*/
-
-/*!
- \variable QWSPointerCalibrationData::devPoints
- \brief the raw device coordinates for each value of the Location enum.
-*/
-
-/*!
- \variable QWSPointerCalibrationData::screenPoints
- \brief the logical screen coordinates for each value of the Location enum.
-*/
-
-/*!
- \enum QWSPointerCalibrationData::Location
-
- This enum describes the various logical positions that can be
- specified by the devPoints and screenPoints variables.
-
- \value TopLeft Index of the top left corner of the screen.
- \value BottomLeft Index of the bottom left corner of the screen.
- \value BottomRight Index of the bottom right corner of the screen.
- \value TopRight Index of the top right corner of the screen.
- \value Center Index of the center of the screen.
- \value LastLocation Last index in the pointer arrays.
-*/
-
-class QWSMouseHandlerPrivate
-{
-public:
- QWSMouseHandlerPrivate() : screen(qt_screen) {}
-
- const QScreen *screen;
-};
-
-/*!
- \class QWSMouseHandler
- \ingroup qws
-
- \brief The QWSMouseHandler class is a base class for mouse drivers in
- Qt for Embedded Linux.
-
- Note that this class is only available in \l{Qt for Embedded Linux}.
-
- \l{Qt for Embedded Linux} provides ready-made drivers for several mouse
- protocols, see the \l{Qt for Embedded Linux Pointer Handling}{pointer
- handling} documentation for details. Custom mouse drivers can be
- implemented by subclassing the QWSMouseHandler class and creating
- a mouse driver plugin (derived from QMouseDriverPlugin).
- The default implementation of the QMouseDriverFactory class
- will automatically detect the plugin, and load the driver into the
- server application at run-time using Qt's \l {How to Create Qt
- Plugins}{plugin system}.
-
- The mouse driver receives mouse events from the system device and
- encapsulates each event with an instance of the QWSEvent class
- which it then passes to the server application (the server is
- responsible for propagating the event to the appropriate
- client). To receive mouse events, a QWSMouseHandler object will
- usually create a QSocketNotifier object for the given device. The
- QSocketNotifier class provides support for monitoring activity on
- a file descriptor. When the socket notifier receives data, it will
- call the mouse driver's mouseChanged() function to send the event
- to the \l{Qt for Embedded Linux} server application for relaying to
- clients.
-
- If you are creating a driver for a device that needs calibration
- or noise reduction, such as a touchscreen, use the
- QWSCalibratedMouseHandler subclass instead to take advantage of
- the calibrate() and clearCalibration() functions. The \l
- {qws/mousecalibration}{Mouse Calibration}
- demonstrates how to write a simple program using the mechanisms
- provided by the QWSMouseHandler class to calibrate a mouse driver.
-
- Note that when deriving from the QWSMouseHandler class, the
- resume() and suspend() functions must be reimplemented to control
- the flow of mouse input, i.e., the default implementation does
- nothing. Reimplementations of these functions typically call the
- QSocketNotifier::setEnabled() function to enable or disable the
- socket notifier, respectively.
-
- In addition, QWSMouseHandler provides the setScreen() function
- that allows you to specify a screen for your mouse driver and the
- limitToScreen() function that ensures that a given position is
- within this screen's boundaries (changing the position if
- necessary). Finally, QWSMouseHandler provides the pos() function
- returning the current mouse position.
-
- \sa QMouseDriverPlugin, QMouseDriverFactory, {Qt for Embedded Linux Pointer
- Handling}
-*/
-
-
-/*!
- \fn void QWSMouseHandler::suspend()
-
- Implement this function to suspend reading and handling of mouse
- events, e.g., call the QSocketNotifier::setEnabled() function to
- disable the socket notifier.
-
- \sa resume()
-*/
-
-/*!
- \fn void QWSMouseHandler::resume()
-
- Implement this function to resume reading and handling mouse
- events, e.g., call the QSocketNotifier::setEnabled() function to
- enable the socket notifier.
-
- \sa suspend()
-*/
-
-/*!
- \fn const QPoint &QWSMouseHandler::pos() const
-
- Returns the current mouse position.
-
- \sa mouseChanged(), limitToScreen()
-*/
-
-/*!
- Constructs a mouse driver. The \a driver and \a device arguments
- are passed by the QWS_MOUSE_PROTO environment variable.
-
- Call the QWSServer::setMouseHandler() function to make the newly
- created mouse driver, the primary driver. Note that the primary
- driver is controlled by the system, i.e., the system will delete
- it upon exit.
-*/
-QWSMouseHandler::QWSMouseHandler(const QString &, const QString &)
- : mousePos(QWSServer::mousePosition), d_ptr(new QWSMouseHandlerPrivate)
-{
-}
-
-/*!
- Destroys this mouse driver.
-
- Do not call this function if this driver is the primary mouse
- driver, i.e., if QWSServer::setMouseHandler() function has been
- called passing this driver as argument. The primary mouse
- driver is deleted by the system.
-*/
-QWSMouseHandler::~QWSMouseHandler()
-{
- delete d_ptr;
-}
-
-/*!
- Ensures that the given \a position is within the screen's
- boundaries, changing the \a position if necessary.
-
- \sa pos(), setScreen()
-*/
-
-void QWSMouseHandler::limitToScreen(QPoint &position)
-{
- position.setX(qMin(d_ptr->screen->deviceWidth() - 1, qMax(0, position.x())));
- position.setY(qMin(d_ptr->screen->deviceHeight() - 1, qMax(0, position.y())));
-}
-
-/*!
- \since 4.2
-
- Sets the screen for this mouse driver to be the given \a screen.
-
- \sa limitToScreen()
-*/
-void QWSMouseHandler::setScreen(const QScreen *screen)
-{
- d_ptr->screen = (screen ? screen : qt_screen);
-}
-
-/*!
- Notifies the system of a new mouse event.
-
- This function updates the current mouse position and sends the
- event to the \l{Qt for Embedded Linux} server application for
- delivery to the correct widget. Note that a custom mouse driver must call
- this function whenever it wants to deliver a new mouse event.
-
- The given \a position is the global position of the mouse cursor.
- The \a state parameter is a bitmask of the Qt::MouseButton enum's
- values, indicating which mouse buttons are pressed. The \a wheel
- parameter is the delta value of the mouse wheel as returned by
- QWheelEvent::delta().
-
- \sa pos()
-*/
-void QWSMouseHandler::mouseChanged(const QPoint &position, int state, int wheel)
-{
- mousePos = position + d_ptr->screen->offset();
- QWSServer::sendMouseEvent(mousePos, state, wheel);
-}
-
-/*!
- \fn QWSMouseHandler::clearCalibration()
-
- This virtual function allows subclasses of QWSMouseHandler to
- clear the calibration information. Note that the default
- implementation does nothing.
-
- \sa QWSCalibratedMouseHandler::clearCalibration(), calibrate()
-*/
-
-/*!
- \fn QWSMouseHandler::calibrate(const QWSPointerCalibrationData *data)
-
- This virtual function allows subclasses of QWSMouseHandler to set
- the calibration information passed in the given \a data. Note that
- the default implementation does nothing.
-
- \sa QWSCalibratedMouseHandler::calibrate(), clearCalibration()
-*/
-
-/*! \fn QWSMouseHandler::getCalibration(QWSPointerCalibrationData *data) const
- This virtual function allows subclasses of QWSMouseHandler
- to fill in the device coordinates in \a data with values
- that correspond to screen coordinates that are already in
- \a data. Note that the default implementation does nothing.
- */
-
-/*!
- \class QWSCalibratedMouseHandler
- \ingroup qws
-
- \brief The QWSCalibratedMouseHandler class provides mouse
- calibration and noise reduction in Qt for Embedded Linux.
-
- Note that this class is only available in \l{Qt for Embedded Linux}.
-
- \l{Qt for Embedded Linux} provides ready-made drivers for several mouse
- protocols, see the \l{Qt for Embedded Linux Pointer Handling}{pointer
- handling} documentation for details. In general, custom mouse
- drivers can be implemented by subclassing the QWSMouseHandler
- class. But when the system device does not have a fixed mapping
- between device and screen coordinates and/or produces noisy events
- (e.g., a touchscreen), you should derive from the
- QWSCalibratedMouseHandler class instead to take advantage of its
- calibration functionality. As always, you must also create a mouse
- driver plugin (derived from QMouseDriverPlugin);
- the implementation of the QMouseDriverFactory class will then
- automatically detect the plugin, and load the driver into the
- server application at run-time using Qt's
- \l{How to Create Qt Plugins}{plugin system}.
-
- QWSCalibratedMouseHandler provides an implementation of the
- calibrate() function to update the calibration parameters based on
- coordinate mapping of the given calibration data. The calibration
- data is represented by an QWSPointerCalibrationData object. The
- linear transformation between device coordinates and screen
- coordinates is performed by calling the transform() function
- explicitly on the points passed to the
- QWSMouseHandler::mouseChanged() function. Use the
- clearCalibration() function to make the mouse driver return mouse
- events in raw device coordinates and not in screen coordinates.
-
- The calibration parameters are recalculated whenever calibrate()
- is called, and they can be stored using the writeCalibration()
- function. Previously written parameters can be retrieved at any
- time using the readCalibration() function (calibration parameters
- are always read when the class is instantiated). Note that the
- calibration parameters is written to and read from the file
- currently specified by the POINTERCAL_FILE environment variable;
- the default file is \c /etc/pointercal.
-
- To achieve noise reduction, QWSCalibratedMouseHandler provides the
- sendFiltered() function. Use this function instead of
- mouseChanged() whenever a mouse event occurs. The filter's size
- can be manipulated using the setFilterSize() function.
-
- \sa QWSMouseHandler, QWSPointerCalibrationData,
- {Mouse Calibration Example}
-*/
-
-
-/*!
- \internal
- */
-
-QWSCalibratedMouseHandler::QWSCalibratedMouseHandler(const QString &, const QString &)
- : samples(5), currSample(0), numSamples(0)
-{
- clearCalibration();
- readCalibration();
-}
-
-/*!
- Fills \a cd with the device coordinates corresponding to the given
- screen coordinates.
-
- \internal
-*/
-void QWSCalibratedMouseHandler::getCalibration(QWSPointerCalibrationData *cd) const
-{
- const qint64 scale = qint64(a) * qint64(e) - qint64(b) * qint64(d);
- const qint64 xOff = qint64(b) * qint64(f) - qint64(c) * qint64(e);
- const qint64 yOff = qint64(c) * qint64(d) - qint64(a) * qint64(f);
- for (int i = 0; i <= QWSPointerCalibrationData::LastLocation; ++i) {
- const qint64 sX = cd->screenPoints[i].x();
- const qint64 sY = cd->screenPoints[i].y();
- const qint64 dX = (s*(e*sX - b*sY) + xOff) / scale;
- const qint64 dY = (s*(a*sY - d*sX) + yOff) / scale;
- cd->devPoints[i] = QPoint(dX, dY);
- }
-}
-
-/*!
- Clears the current calibration, i.e., makes the mouse
- driver return mouse events in raw device coordinates instead of
- screen coordinates.
-
- \sa calibrate()
-*/
-void QWSCalibratedMouseHandler::clearCalibration()
-{
- a = 1;
- b = 0;
- c = 0;
- d = 0;
- e = 1;
- f = 0;
- s = 1;
-}
-
-
-/*!
- Saves the current calibration parameters in \c /etc/pointercal
- (separated by whitespace and in alphabetical order).
-
- You can override the default \c /etc/pointercal by specifying
- another file using the POINTERCAL_FILE environment variable.
-
- \sa readCalibration()
-*/
-void QWSCalibratedMouseHandler::writeCalibration()
-{
- QString calFile;
- calFile = QString::fromLocal8Bit(qgetenv("POINTERCAL_FILE"));
- if (calFile.isEmpty())
- calFile = QLatin1String("/etc/pointercal");
-
-#ifndef QT_NO_TEXTSTREAM
- QFile file(calFile);
- if (file.open(QIODevice::WriteOnly)) {
- QTextStream t(&file);
- t << a << ' ' << b << ' ' << c << ' ';
- t << d << ' ' << e << ' ' << f << ' ' << s << endl;
- } else
-#endif
- {
- qCritical("QWSCalibratedMouseHandler::writeCalibration: "
- "Could not save calibration into %s", qPrintable(calFile));
- }
-}
-
-/*!
- Reads previously written calibration parameters which are stored
- in \c /etc/pointercal (separated by whitespace and in alphabetical
- order).
-
- You can override the default \c /etc/pointercal by specifying
- another file using the POINTERCAL_FILE environment variable.
-
-
- \sa writeCalibration()
-*/
-void QWSCalibratedMouseHandler::readCalibration()
-{
- QString calFile = QString::fromLocal8Bit(qgetenv("POINTERCAL_FILE"));
- if (calFile.isEmpty())
- calFile = QLatin1String("/etc/pointercal");
-
-#ifndef QT_NO_TEXTSTREAM
- QFile file(calFile);
- if (file.open(QIODevice::ReadOnly)) {
- QTextStream t(&file);
- t >> a >> b >> c >> d >> e >> f >> s;
- if (s == 0 || t.status() != QTextStream::Ok) {
- qCritical("Corrupt calibration data");
- clearCalibration();
- }
- } else
-#endif
- {
- qDebug() << "Could not read calibration:" <<calFile;
- }
-}
-
-static int ilog2(quint32 n)
-{
- int result = 0;
-
- if (n & 0xffff0000) {
- n >>= 16;
- result += 16;
- }
- if (n & 0xff00) {
- n >>= 8;
- result += 8;}
- if (n & 0xf0) {
- n >>= 4;
- result += 4;
- }
- if (n & 0xc) {
- n >>= 2;
- result += 2;
- }
- if (n & 0x2)
- result += 1;
-
- return result;
-}
-
-/*!
- Updates the calibration parameters based on coordinate mapping of
- the given \a data.
-
- Create an instance of the QWSPointerCalibrationData class, fill in
- the device and screen coordinates and pass that object to the mouse
- driver using this function.
-
- \sa clearCalibration(), transform()
-*/
-void QWSCalibratedMouseHandler::calibrate(const QWSPointerCalibrationData *data)
-{
- // Algorithm derived from
- // "How To Calibrate Touch Screens" by Carlos E. Vidales,
- // printed in Embedded Systems Programming, Vol. 15 no 6, June 2002
- // URL: http://www.embedded.com/showArticle.jhtml?articleID=9900629
-
- const QPoint pd0 = data->devPoints[QWSPointerCalibrationData::TopLeft];
- const QPoint pd1 = data->devPoints[QWSPointerCalibrationData::TopRight];
- const QPoint pd2 = data->devPoints[QWSPointerCalibrationData::BottomRight];
- const QPoint p0 = data->screenPoints[QWSPointerCalibrationData::TopLeft];
- const QPoint p1 = data->screenPoints[QWSPointerCalibrationData::TopRight];
- const QPoint p2 = data->screenPoints[QWSPointerCalibrationData::BottomRight];
-
- const qint64 xd0 = pd0.x();
- const qint64 xd1 = pd1.x();
- const qint64 xd2 = pd2.x();
- const qint64 yd0 = pd0.y();
- const qint64 yd1 = pd1.y();
- const qint64 yd2 = pd2.y();
- const qint64 x0 = p0.x();
- const qint64 x1 = p1.x();
- const qint64 x2 = p2.x();
- const qint64 y0 = p0.y();
- const qint64 y1 = p1.y();
- const qint64 y2 = p2.y();
-
- qint64 scale = ((xd0 - xd2)*(yd1 - yd2) - (xd1 - xd2)*(yd0 - yd2));
- int shift = 0;
- qint64 absScale = qAbs(scale);
- // use maximum 16 bit precision to reduce risk of integer overflow
- if (absScale > (1 << 16)) {
- shift = ilog2(absScale >> 16) + 1;
- scale >>= shift;
- }
-
- s = scale;
- a = ((x0 - x2)*(yd1 - yd2) - (x1 - x2)*(yd0 - yd2)) >> shift;
- b = ((xd0 - xd2)*(x1 - x2) - (x0 - x2)*(xd1 - xd2)) >> shift;
- c = (yd0*(xd2*x1 - xd1*x2) + yd1*(xd0*x2 - xd2*x0) + yd2*(xd1*x0 - xd0*x1)) >> shift;
- d = ((y0 - y2)*(yd1 - yd2) - (y1 - y2)*(yd0 - yd2)) >> shift;
- e = ((xd0 - xd2)*(y1 - y2) - (y0 - y2)*(xd1 - xd2)) >> shift;
- f = (yd0*(xd2*y1 - xd1*y2) + yd1*(xd0*y2 - xd2*y0) + yd2*(xd1*y0 - xd0*y1)) >> shift;
-
- writeCalibration();
-}
-
-/*!
- Transforms the given \a position from device coordinates to screen
- coordinates, and returns the transformed position.
-
- This function is typically called explicitly on the points passed
- to the QWSMouseHandler::mouseChanged() function.
-
- This implementation is a linear transformation using 7 parameters
- (\c a, \c b, \c c, \c d, \c e, \c f and \c s) to transform the
- device coordinates (\c Xd, \c Yd) into screen coordinates (\c Xs,
- \c Ys) using the following equations:
-
- \snippet doc/src/snippets/code/src_gui_embedded_qmouse_qws.cpp 0
-
- \sa mouseChanged()
-*/
-QPoint QWSCalibratedMouseHandler::transform(const QPoint &position)
-{
- QPoint tp;
-
- tp.setX((a * position.x() + b * position.y() + c) / s);
- tp.setY((d * position.x() + e * position.y() + f) / s);
-
- return tp;
-}
-
-/*!
- Sets the size of the filter used in noise reduction to the given
- \a size.
-
- The sendFiltered() function reduces noice by calculating an
- average position from a collection of mouse event positions. The
- filter size determines the number of positions that forms the
- basis for these calculations.
-
- \sa sendFiltered()
-*/
-void QWSCalibratedMouseHandler::setFilterSize(int size)
-{
- samples.resize(qMax(1, size));
- numSamples = 0;
- currSample = 0;
-}
-
-/*!
- \fn bool QWSCalibratedMouseHandler::sendFiltered(const QPoint &position, int state)
-
- Notifies the system of a new mouse event \e after applying a noise
- reduction filter. Returns true if the filtering process is
- successful; otherwise returns false. Note that if the filtering
- process failes, the system is not notified about the event.
-
- The given \a position is the global position of the mouse. The \a
- state parameter is a bitmask of the Qt::MouseButton enum's values
- indicating which mouse buttons are pressed.
-
- The noice is reduced by calculating an average position from a
- collection of mouse event positions and then calling the
- mouseChanged() function with the new position. The number of
- positions that is used is determined by the filter size.
-
- \sa mouseChanged(), setFilterSize()
-*/
-bool QWSCalibratedMouseHandler::sendFiltered(const QPoint &position, int button)
-{
- if (!button) {
- if (numSamples >= samples.count())
- mouseChanged(transform(position), 0);
- currSample = 0;
- numSamples = 0;
- return true;
- }
-
- bool sent = false;
- samples[currSample] = position;
- numSamples++;
- if (numSamples >= samples.count()) {
-
- int ignore = -1;
- if (samples.count() > 2) { // throw away the "worst" sample
- int maxd = 0;
- for (int i = 0; i < samples.count(); i++) {
- int d = (mousePos - samples[i]).manhattanLength();
- if (d > maxd) {
- maxd = d;
- ignore = i;
- }
- }
- }
-
- // average the rest
- QPoint pos(0, 0);
- int numAveraged = 0;
- for (int i = 0; i < samples.count(); i++) {
- if (ignore == i)
- continue;
- pos += samples[i];
- ++numAveraged;
- }
- if (numAveraged)
- pos /= numAveraged;
-
- mouseChanged(transform(pos), button);
- sent = true;
- }
- currSample++;
- if (currSample >= samples.count())
- currSample = 0;
-
- return sent;
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/embedded/qmouse_qws.h b/src/gui/embedded/qmouse_qws.h
deleted file mode 100644
index 42a8292c54..0000000000
--- a/src/gui/embedded/qmouse_qws.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QMOUSE_QWS_H
-#define QMOUSE_QWS_H
-
-#include <QtCore/qobject.h>
-#include <QtGui/qpolygon.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QWSMouseHandlerPrivate;
-class QScreen;
-
-class Q_GUI_EXPORT QWSPointerCalibrationData
-{
-public:
- enum Location { TopLeft = 0, BottomLeft = 1, BottomRight = 2, TopRight = 3,
- Center = 4, LastLocation = Center };
- QPoint devPoints[5];
- QPoint screenPoints[5];
-};
-
-class Q_GUI_EXPORT QWSMouseHandler
-{
-public:
- explicit QWSMouseHandler(const QString &driver = QString(),
- const QString &device = QString());
- virtual ~QWSMouseHandler();
-
- virtual void clearCalibration() {}
- virtual void calibrate(const QWSPointerCalibrationData *) {}
- virtual void getCalibration(QWSPointerCalibrationData *) const {}
-
- virtual void resume() = 0;
- virtual void suspend() = 0;
-
- void limitToScreen(QPoint &pt);
- void mouseChanged(const QPoint& pos, int bstate, int wheel = 0);
- const QPoint &pos() const { return mousePos; }
-
- void setScreen(const QScreen *screen);
-
-protected:
- QPoint &mousePos;
- QWSMouseHandlerPrivate *d_ptr;
-};
-
-
-class Q_GUI_EXPORT QWSCalibratedMouseHandler : public QWSMouseHandler
-{
-public:
- explicit QWSCalibratedMouseHandler(const QString &driver = QString(),
- const QString &device = QString());
-
- virtual void clearCalibration();
- virtual void calibrate(const QWSPointerCalibrationData *);
- virtual void getCalibration(QWSPointerCalibrationData *) const;
-
-protected:
- bool sendFiltered(const QPoint &, int button);
- QPoint transform(const QPoint &);
-
- void readCalibration();
- void writeCalibration();
- void setFilterSize(int);
-
-private:
- int a, b, c;
- int d, e, f;
- int s;
- QPolygon samples;
- int currSample;
- int numSamples;
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QMOUSE_QWS_H
diff --git a/src/gui/embedded/qmousedriverfactory_qws.cpp b/src/gui/embedded/qmousedriverfactory_qws.cpp
deleted file mode 100644
index d995bdfe53..0000000000
--- a/src/gui/embedded/qmousedriverfactory_qws.cpp
+++ /dev/null
@@ -1,197 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qmousedriverfactory_qws.h"
-
-#include "qapplication.h"
-#include "qmousepc_qws.h"
-#include "qmouselinuxtp_qws.h"
-#include "qmouselinuxinput_qws.h"
-#include "qmousevfb_qws.h"
-#include "qmousetslib_qws.h"
-#include "qmouseqnx_qws.h"
-#include "qmouseintegrity_qws.h"
-#include <stdlib.h>
-#include "private/qfactoryloader_p.h"
-#include "qmousedriverplugin_qws.h"
-#include "qdebug.h"
-
-QT_BEGIN_NAMESPACE
-
-#if !defined(Q_OS_WIN32) || defined(QT_MAKEDLL)
-#ifndef QT_NO_LIBRARY
-
-Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
- (QWSMouseHandlerFactoryInterface_iid,
- QLatin1String("/mousedrivers"), Qt::CaseInsensitive))
-
-#endif //QT_NO_LIBRARY
-#endif //QT_MAKEDLL
-
-/*!
- \class QMouseDriverFactory
- \ingroup qws
-
- \brief The QMouseDriverFactory class creates mouse drivers in
- Qt for Embedded Linux.
-
- Note that this class is only available in \l{Qt for Embedded Linux}.
-
- QMouseDriverFactory is used to detect and instantiate the
- available mouse drivers, allowing \l{Qt for Embedded Linux} to load the
- preferred driver into the server application at runtime. The
- create() function returns a QWSMouseHandler object representing
- the mouse driver identified by a given key. The valid keys
- (i.e. the supported drivers) can be retrieved using the keys()
- function.
-
- \l{Qt for Embedded Linux} provides several built-in mouse drivers. In
- addition, custom mouse drivers can be added using Qt's plugin
- mechanism, i.e. by subclassing the QWSMouseHandler class and
- creating a mouse driver plugin (QMouseDriverPlugin). See the
- \l{Qt for Embedded Linux Pointer Handling}{pointer handling}
- documentation for details.
-
- \sa QWSMouseHandler, QMouseDriverPlugin
-*/
-
-/*!
- Creates the mouse driver specified by the given \a key, using the
- display specified by the given \a device.
-
- Note that the keys are case-insensitive.
-
- \sa keys()
-*/
-QWSMouseHandler *QMouseDriverFactory::create(const QString& key, const QString &device)
-{
- QString driver = key.toLower();
-#if defined(Q_OS_QNX) && !defined(QT_NO_QWS_MOUSE_QNX)
- if (driver == QLatin1String("qnx") || driver.isEmpty())
- return new QQnxMouseHandler(key, device);
-#endif
-#if defined(Q_OS_INTEGRITY) && !defined(QT_NO_MOUSE_INTEGRITY)
- if (driver == QLatin1String("integrity") || driver.isEmpty())
- return new QIntMouseHandler(key, device);
-#endif
-#ifndef QT_NO_QWS_MOUSE_LINUXTP
- if (driver == QLatin1String("linuxtp") || driver.isEmpty())
- return new QWSLinuxTPMouseHandler(key, device);
-#endif
-#ifndef QT_NO_QWS_MOUSE_PC
- if (driver == QLatin1String("auto")
- || driver == QLatin1String("intellimouse")
- || driver == QLatin1String("microsoft")
- || driver == QLatin1String("mousesystems")
- || driver == QLatin1String("mouseman")
- || driver.isEmpty()) {
- return new QWSPcMouseHandler(key, device);
- }
-#endif
-#ifndef QT_NO_QWS_MOUSE_TSLIB
- if (driver == QLatin1String("tslib") || driver.isEmpty())
- return new QWSTslibMouseHandler(key, device);
-#endif
-# ifndef QT_NO_QWS_MOUSE_LINUXINPUT
- if (driver == QLatin1String("linuxinput") || \
- driver == QLatin1String("usb") || \
- driver == QLatin1String("linuxis"))
- return new QWSLinuxInputMouseHandler(device);
-# endif
-#ifndef QT_NO_QWS_MOUSE_QVFB
- if (driver == QLatin1String("qvfbmouse") || driver == QLatin1String("qvfb"))
- return new QVFbMouseHandler(key, device);
-#endif
-
-#if !defined(Q_OS_WIN32) || defined(QT_MAKEDLL)
-#ifndef QT_NO_LIBRARY
- if (QWSMouseHandlerFactoryInterface *factory = qobject_cast<QWSMouseHandlerFactoryInterface*>(loader()->instance(driver)))
- return factory->create(driver, device);
-#endif
-#endif
- return 0;
-}
-
-/*!
- Returns the list of valid keys, i.e. the available mouse drivers.
-
- \sa create()
-*/
-QStringList QMouseDriverFactory::keys()
-{
- QStringList list;
-
-#if defined(Q_OS_QNX) && !defined(QT_NO_QWS_MOUSE_QNX)
- list << QLatin1String("QNX");
-#endif
-#if defined(Q_OS_INTEGRITY) && !defined(QT_NO_QWS_MOUSE_INTEGRITY)
- list << QLatin1String("INTEGRITY");
-#endif
-#ifndef QT_NO_QWS_MOUSE_LINUXTP
- list << QLatin1String("LinuxTP");
-#endif
-#ifndef QT_NO_QWS_MOUSE_PC
- list << QLatin1String("Auto")
- << QLatin1String("IntelliMouse")
- << QLatin1String("Microsoft")
- << QLatin1String("MouseSystems")
- << QLatin1String("MouseMan");
-#endif
-#ifndef QT_NO_QWS_MOUSE_TSLIB
- list << QLatin1String("Tslib");
-#endif
-#ifndef QT_NO_QWS_MOUSE_LINUXINPUT
- list << QLatin1String("LinuxInput");
-#endif
-
-#if !defined(Q_OS_WIN32) || defined(QT_MAKEDLL)
-#ifndef QT_NO_LIBRARY
- QStringList plugins = loader()->keys();
- for (int i = 0; i < plugins.size(); ++i) {
- if (!list.contains(plugins.at(i)))
- list += plugins.at(i);
- }
-#endif //QT_NO_LIBRARY
-#endif //QT_MAKEDLL
- return list;
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/embedded/qmousedriverfactory_qws.h b/src/gui/embedded/qmousedriverfactory_qws.h
deleted file mode 100644
index 1bc1ffefba..0000000000
--- a/src/gui/embedded/qmousedriverfactory_qws.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QMOUSEDRIVERFACTORY_QWS_H
-#define QMOUSEDRIVERFACTORY_QWS_H
-
-#include <QtCore/qstringlist.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QString;
-class QWSMouseHandler;
-
-class Q_GUI_EXPORT QMouseDriverFactory
-{
-public:
- static QStringList keys();
- static QWSMouseHandler *create(const QString&, const QString &);
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QMOUSEDRIVERFACTORY_QWS_H
diff --git a/src/gui/embedded/qmousedriverplugin_qws.cpp b/src/gui/embedded/qmousedriverplugin_qws.cpp
deleted file mode 100644
index e828f476c1..0000000000
--- a/src/gui/embedded/qmousedriverplugin_qws.cpp
+++ /dev/null
@@ -1,124 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qmousedriverplugin_qws.h"
-
-#ifndef QT_NO_LIBRARY
-
-#include "qmouse_qws.h"
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \class QMouseDriverPlugin
- \ingroup plugins
- \ingroup qws
-
- \brief The QMouseDriverPlugin class is an abstract base class for
- mouse driver plugins in Qt for Embedded Linux.
-
- Note that this class is only available in \l{Qt for Embedded Linux}.
-
- \l{Qt for Embedded Linux} provides ready-made drivers for several mouse
- protocols, see the \l{Qt for Embedded Linux Pointer Handling}{pointer
- handling} documentation for details. Custom mouse drivers can be
- implemented by subclassing the QWSMouseHandler class and creating
- a mouse driver plugin.
-
- A mouse driver plugin can be created by subclassing
- QMouseDriverPlugin and reimplementing the pure virtual keys() and
- create() functions. By exporting the derived class using the
- Q_EXPORT_PLUGIN2() macro, The default implementation of the
- QMouseDriverFactory class will automatically detect the plugin and
- load the driver into the server application at run-time. See \l
- {How to Create Qt Plugins} for details.
-
- \sa QWSMouseHandler, QMouseDriverFactory
-*/
-
-/*!
- \fn QStringList QMouseDriverPlugin::keys() const
-
- Implement this function to return the list of valid keys, i.e. the
- mouse drivers supported by this plugin.
-
- \l{Qt for Embedded Linux} provides ready-made drivers for several mouse
- protocols, see the \l {Qt for Embedded Linux Pointer Handling}{pointer
- handling} documentation for details.
-
- \sa create()
-*/
-
-/*!
- Constructs a mouse driver plugin with the given \a parent.
-
- Note that this constructor is invoked automatically by the
- Q_EXPORT_PLUGIN2() macro, so there is no need for calling it
- explicitly.
-*/
-QMouseDriverPlugin::QMouseDriverPlugin(QObject *parent)
- : QObject(parent)
-{
-}
-
-/*!
- Destroys the mouse driver plugin.
-
- Note that Qt destroys a plugin automatically when it is no longer
- used, so there is no need for calling the destructor explicitly.
-*/
-QMouseDriverPlugin::~QMouseDriverPlugin()
-{
-}
-
-/*!
- \fn QScreen* QMouseDriverPlugin::create(const QString &key, const QString& device)
-
- Implement this function to create a driver matching the type
- specified by the given \a key and \a device parameters. Note that
- keys are case-insensitive.
-
- \sa keys()
-*/
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_LIBRARY
diff --git a/src/gui/embedded/qmousedriverplugin_qws.h b/src/gui/embedded/qmousedriverplugin_qws.h
deleted file mode 100644
index 47d6af4944..0000000000
--- a/src/gui/embedded/qmousedriverplugin_qws.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QMOUSEDRIVERPLUGIN_QWS_H
-#define QMOUSEDRIVERPLUGIN_QWS_H
-
-#include <QtCore/qplugin.h>
-#include <QtCore/qfactoryinterface.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_LIBRARY
-
-class QWSMouseHandler;
-
-struct Q_GUI_EXPORT QWSMouseHandlerFactoryInterface : public QFactoryInterface
-{
- virtual QWSMouseHandler* create(const QString &name, const QString &device) = 0;
-};
-
-#define QWSMouseHandlerFactoryInterface_iid "com.trolltech.Qt.QWSMouseHandlerFactoryInterface"
-Q_DECLARE_INTERFACE(QWSMouseHandlerFactoryInterface, QWSMouseHandlerFactoryInterface_iid)
-
-class Q_GUI_EXPORT QMouseDriverPlugin : public QObject, public QWSMouseHandlerFactoryInterface
-{
- Q_OBJECT
- Q_INTERFACES(QWSMouseHandlerFactoryInterface:QFactoryInterface)
-public:
- explicit QMouseDriverPlugin(QObject *parent = 0);
- ~QMouseDriverPlugin();
-
- virtual QStringList keys() const = 0;
- virtual QWSMouseHandler* create(const QString& driver, const QString &device) = 0;
-};
-
-#endif // QT_NO_LIBRARY
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QMOUSEDRIVERPLUGIN_QWS_H
diff --git a/src/gui/embedded/qmouseintegrity_qws.cpp b/src/gui/embedded/qmouseintegrity_qws.cpp
deleted file mode 100644
index c4ce603f55..0000000000
--- a/src/gui/embedded/qmouseintegrity_qws.cpp
+++ /dev/null
@@ -1,271 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QT_NO_QWS_MOUSE_INTEGRITY
-
-#include "qmouseintegrity_qws.h"
-#include <qwindowsystem_qws.h>
-#include <qapplication.h>
-#include <qtimer.h>
-#include <qthread.h>
-
-#include <INTEGRITY.h>
-
-
-typedef Address MOUSEHandler;
-typedef struct MOUSEMessageStruct
-{
- Value x;
- Value y;
- Value z;
- Value buttons;
-} MOUSEMessage;
-
-static Error MOUSE_Init(MOUSEHandler *handler, Boolean *isabsolute);
-static Error MOUSE_SynchronousGetPosition(MOUSEHandler handler, MOUSEMessage *msg,
- Boolean absolute);
-static Error MOUSE_ShouldFilter(MOUSEHandler handler, Boolean *filter);
-
-QT_BEGIN_NAMESPACE
-
-class QIntMouseListenThread;
-
-class QIntMousePrivate : public QObject
-{
- Q_OBJECT
- friend class QIntMouseListenTaskThread;
-Q_SIGNALS:
- void mouseDataAvailable(int x, int y, int buttons);
-public:
- QIntMousePrivate(QIntMouseHandler *handler);
- ~QIntMousePrivate();
- void dataReady(int x, int y, int buttons) { emit mouseDataAvailable(x, y, buttons); }
- bool calibrated;
- bool waitforread;
- bool suspended;
- QIntMouseListenThread *mousethread;
-
-private:
- QIntMouseHandler *handler;
-};
-
-class QIntMouseListenThread : public QThread
-{
-protected:
- QIntMousePrivate *imp;
- bool loop;
-public:
- QIntMouseListenThread(QIntMousePrivate *im) : QThread(), imp(im) {};
- ~QIntMouseListenThread() {};
- void run();
- void stoploop() { loop = false; };
-};
-
-
-QIntMouseHandler::QIntMouseHandler(const QString &driver, const QString &device)
- : QObject(), QWSCalibratedMouseHandler(driver, device)
-{
- QPoint test(1,1);
- d = new QIntMousePrivate(this);
- connect(d, SIGNAL(mouseDataAvailable(int, int, int)), this, SLOT(readMouseData(int, int, int)));
-
- d->calibrated = (test != transform(test));
-
- d->mousethread->start();
-}
-
-QIntMouseHandler::~QIntMouseHandler()
-{
- disconnect(d, SIGNAL(mouseDataAvailable(int, int, int)), this, SLOT(readMouseData(int, int, int)));
- delete d;
-}
-
-void QIntMouseHandler::resume()
-{
- d->suspended = true;
-}
-
-void QIntMouseHandler::suspend()
-{
- d->suspended = false;
-}
-
-void QIntMouseHandler::readMouseData(int x, int y, int buttons)
-{
- d->waitforread = false;
- if (d->suspended)
- return;
- if (d->calibrated) {
- sendFiltered(QPoint(x, y), buttons);
- } else {
- QPoint pos;
- pos = transform(QPoint(x, y));
- limitToScreen(pos);
- mouseChanged(pos, buttons, 0);
- }
-}
-
-void QIntMouseHandler::clearCalibration()
-{
- QWSCalibratedMouseHandler::clearCalibration();
-}
-
-void QIntMouseHandler::calibrate(const QWSPointerCalibrationData *data)
-{
- QWSCalibratedMouseHandler::calibrate(data);
-}
-
-void QIntMouseListenThread::run(void)
-{
- MOUSEHandler handler;
- MOUSEMessage msg;
- Boolean filter;
- Boolean isabsolute;
- loop = true;
- CheckSuccess(MOUSE_Init(&handler, &isabsolute));
- CheckSuccess(MOUSE_ShouldFilter(handler, &filter));
- if (!filter)
- imp->calibrated = false;
- imp->waitforread = false;
- do {
- MOUSE_SynchronousGetPosition(handler, &msg, isabsolute);
- imp->dataReady(msg.x, msg.y, msg.buttons);
- } while (loop);
- QThread::exit(0);
-}
-
-QIntMousePrivate::QIntMousePrivate(QIntMouseHandler *handler)
- : QObject()
-{
- this->handler = handler;
- suspended = false;
- mousethread = new QIntMouseListenThread(this);
-}
-
-QIntMousePrivate::~QIntMousePrivate()
-{
- mousethread->stoploop();
- mousethread->wait();
- delete mousethread;
-}
-
-QT_END_NAMESPACE
-
-#include "qmouseintegrity_qws.moc"
-
-typedef struct USBMouseStruct
-{
- Connection mouseconn;
- Buffer mousemsg[2];
- Value x;
- Value y;
-} USBMouse;
-
-USBMouse mousedev;
-
-Error MOUSE_Init(MOUSEHandler *handler, Boolean *isabsolute)
-{
- Error E;
- bool loop = true;
- memset((void*)&mousedev, 0, sizeof(USBMouse));
- mousedev.mousemsg[0].BufferType = DataImmediate;
- mousedev.mousemsg[1].BufferType = DataImmediate | LastBuffer;
- do {
- E = RequestResource((Object*)&mousedev.mouseconn,
- "MouseClient", "!systempassword");
- if (E == Success) {
- *isabsolute = true;
- loop = false;
- } else {
- E = RequestResource((Object*)&mousedev.mouseconn,
- "USBMouseClient", "!systempassword");
- if (E == Success) {
- *isabsolute = false;
- loop = false;
- }
- }
- if (loop)
- sleep(1);
- } while (loop);
- *handler = (MOUSEHandler)&mousedev;
- return Success;
-}
-
-Error MOUSE_SynchronousGetPosition(MOUSEHandler handler, MOUSEMessage *msg,
- Boolean isabsolute)
-{
- signed long x;
- signed long y;
- USBMouse *mdev = (USBMouse *)handler;
- mdev->mousemsg[0].Transferred = 0;
- mdev->mousemsg[1].Transferred = 0;
- SynchronousReceive(mdev->mouseconn, mdev->mousemsg);
- if (isabsolute) {
- x = (signed long)mdev->mousemsg[0].Length;
- y = (signed long)mdev->mousemsg[1].TheAddress;
- } else {
- x = mdev->x + (signed long)mdev->mousemsg[0].Length;
- y = mdev->y + (signed long)mdev->mousemsg[1].TheAddress;
- }
- if (x < 0)
- mdev->x = 0;
- else
- mdev->x = x;
- if (y < 0)
- mdev->y = 0;
- else
- mdev->y = y;
- msg->x = mdev->x;
- msg->y = mdev->y;
- msg->buttons = mdev->mousemsg[0].TheAddress;
- return Success;
-}
-
-Error MOUSE_ShouldFilter(MOUSEHandler handler, Boolean *filter)
-{
- if (filter == NULL)
- return Failure;
- *filter = false;
- return Success;
-}
-
-#endif // QT_NO_QWS_MOUSE_INTEGRITY
-
diff --git a/src/gui/embedded/qmouseintegrity_qws.h b/src/gui/embedded/qmouseintegrity_qws.h
deleted file mode 100644
index 5f0c2aabcd..0000000000
--- a/src/gui/embedded/qmouseintegrity_qws.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QMOUSEINTEGRITY_QWS_H
-#define QMOUSEINTEGRITY_QWS_H
-
-#include <QtGui/qmouse_qws.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_QWS_MOUSE_INTEGRITY
-
-class QSocketNotifier;
-class QIntMousePrivate;
-
-class QIntMouseHandler : public QObject, public QWSCalibratedMouseHandler {
- Q_OBJECT
-public:
- QIntMouseHandler(const QString &driver = QString(),
- const QString &device = QString());
- ~QIntMouseHandler();
-
- void resume();
- void suspend();
-
- void calibrate(const QWSPointerCalibrationData *data);
- void clearCalibration();
-
-private:
- QIntMousePrivate *d;
-private Q_SLOTS:
- void readMouseData(int x, int y, int buttons);
-};
-#endif // QT_NO_QWS_MOUSE_INTEGRITY
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QMOUSEINTEGRITY_QWS_H
diff --git a/src/gui/embedded/qmouselinuxinput_qws.cpp b/src/gui/embedded/qmouselinuxinput_qws.cpp
deleted file mode 100644
index efcf6d4267..0000000000
--- a/src/gui/embedded/qmouselinuxinput_qws.cpp
+++ /dev/null
@@ -1,205 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qmouselinuxinput_qws.h"
-
-#include <QScreen>
-#include <QSocketNotifier>
-
-#include <qplatformdefs.h>
-#include <private/qcore_unix_p.h> // overrides QT_OPEN
-
-#include <errno.h>
-
-#include <linux/input.h>
-
-QT_BEGIN_NAMESPACE
-
-
-class QWSLinuxInputMousePrivate : public QObject
-{
- Q_OBJECT
-public:
- QWSLinuxInputMousePrivate(QWSLinuxInputMouseHandler *, const QString &);
- ~QWSLinuxInputMousePrivate();
-
- void enable(bool on);
-
-private Q_SLOTS:
- void readMouseData();
-
-private:
- QWSLinuxInputMouseHandler *m_handler;
- QSocketNotifier * m_notify;
- int m_fd;
- int m_x, m_y;
- int m_buttons;
-};
-
-QWSLinuxInputMouseHandler::QWSLinuxInputMouseHandler(const QString &device)
- : QWSCalibratedMouseHandler(device)
-{
- d = new QWSLinuxInputMousePrivate(this, device);
-}
-
-QWSLinuxInputMouseHandler::~QWSLinuxInputMouseHandler()
-{
- delete d;
-}
-
-void QWSLinuxInputMouseHandler::suspend()
-{
- d->enable(false);
-}
-
-void QWSLinuxInputMouseHandler::resume()
-{
- d->enable(true);
-}
-
-QWSLinuxInputMousePrivate::QWSLinuxInputMousePrivate(QWSLinuxInputMouseHandler *h, const QString &device)
- : m_handler(h), m_notify(0), m_x(0), m_y(0), m_buttons(0)
-{
- setObjectName(QLatin1String("LinuxInputSubsystem Mouse Handler"));
-
- QString dev = QLatin1String("/dev/input/event0");
- if (device.startsWith(QLatin1String("/dev/")))
- dev = device;
-
- m_fd = QT_OPEN(dev.toLocal8Bit().constData(), O_RDONLY | O_NDELAY, 0);
- if (m_fd >= 0) {
- m_notify = new QSocketNotifier(m_fd, QSocketNotifier::Read, this);
- connect(m_notify, SIGNAL(activated(int)), this, SLOT(readMouseData()));
- } else {
- qWarning("Cannot open mouse input device '%s': %s", qPrintable(dev), strerror(errno));
- return;
- }
-}
-
-QWSLinuxInputMousePrivate::~QWSLinuxInputMousePrivate()
-{
- if (m_fd >= 0)
- QT_CLOSE(m_fd);
-}
-
-void QWSLinuxInputMousePrivate::enable(bool on)
-{
- if (m_notify)
- m_notify->setEnabled(on);
-}
-
-void QWSLinuxInputMousePrivate::readMouseData()
-{
- if (!qt_screen)
- return;
-
- struct ::input_event buffer[32];
- int n = 0;
-
- forever {
- n = QT_READ(m_fd, reinterpret_cast<char *>(buffer) + n, sizeof(buffer) - n);
-
- if (n == 0) {
- qWarning("Got EOF from the input device.");
- return;
- } else if (n < 0 && (errno != EINTR && errno != EAGAIN)) {
- qWarning("Could not read from input device: %s", strerror(errno));
- return;
- } else if (n % sizeof(buffer[0]) == 0) {
- break;
- }
- }
-
- n /= sizeof(buffer[0]);
-
- for (int i = 0; i < n; ++i) {
- struct ::input_event *data = &buffer[i];
-
- bool unknown = false;
- if (data->type == EV_ABS) {
- if (data->code == ABS_X) {
- m_x = data->value;
- } else if (data->code == ABS_Y) {
- m_y = data->value;
- } else {
- unknown = true;
- }
- } else if (data->type == EV_REL) {
- if (data->code == REL_X) {
- m_x += data->value;
- } else if (data->code == REL_Y) {
- m_y += data->value;
- } else {
- unknown = true;
- }
- } else if (data->type == EV_KEY && data->code == BTN_TOUCH) {
- m_buttons = data->value ? Qt::LeftButton : 0;
- } else if (data->type == EV_KEY) {
- int button = 0;
- switch (data->code) {
- case BTN_LEFT: button = Qt::LeftButton; break;
- case BTN_MIDDLE: button = Qt::MidButton; break;
- case BTN_RIGHT: button = Qt::RightButton; break;
- }
- if (data->value)
- m_buttons |= button;
- else
- m_buttons &= ~button;
- } else if (data->type == EV_SYN && data->code == SYN_REPORT) {
- QPoint pos(m_x, m_y);
- pos = m_handler->transform(pos);
- m_handler->limitToScreen(pos);
- m_handler->mouseChanged(pos, m_buttons);
- } else if (data->type == EV_MSC && data->code == MSC_SCAN) {
- // kernel encountered an unmapped key - just ignore it
- continue;
- } else {
- unknown = true;
- }
- if (unknown) {
- qWarning("unknown mouse event type=%x, code=%x, value=%x", data->type, data->code, data->value);
- }
- }
-}
-
-QT_END_NAMESPACE
-
-#include "qmouselinuxinput_qws.moc"
diff --git a/src/gui/embedded/qmouselinuxinput_qws.h b/src/gui/embedded/qmouselinuxinput_qws.h
deleted file mode 100644
index a02bccfde0..0000000000
--- a/src/gui/embedded/qmouselinuxinput_qws.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QMOUSELINUXINPUT_QWS_H
-#define QMOUSELINUXINPUT_QWS_H
-
-#include <QtGui/QWSCalibratedMouseHandler>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_QWS_MOUSE_LINUXINPUT
-
-class QWSLinuxInputMousePrivate;
-
-class QWSLinuxInputMouseHandler : public QWSCalibratedMouseHandler
-{
-public:
- QWSLinuxInputMouseHandler(const QString &);
- ~QWSLinuxInputMouseHandler();
-
- void suspend();
- void resume();
-
-private:
- QWSLinuxInputMousePrivate *d;
-
- friend class QWSLinuxInputMousePrivate;
-};
-
-#endif // QT_NO_QWS_MOUSE_LINUXINPUT
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QMOUSELINUXINPUT_QWS_H
diff --git a/src/gui/embedded/qmouselinuxtp_qws.cpp b/src/gui/embedded/qmouselinuxtp_qws.cpp
deleted file mode 100644
index afa6fe80da..0000000000
--- a/src/gui/embedded/qmouselinuxtp_qws.cpp
+++ /dev/null
@@ -1,335 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qmouselinuxtp_qws.h"
-
-#ifndef QT_NO_QWS_MOUSE_LINUXTP
-#include "qwindowsystem_qws.h"
-#include "qsocketnotifier.h"
-#include "qtimer.h"
-#include "qapplication.h"
-#include "qscreen_qws.h"
-#include <private/qcore_unix_p.h> // overrides QT_OPEN
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <termios.h>
-
-QT_BEGIN_NAMESPACE
-
-#if defined(QT_QWS_IPAQ)
- #define QT_QWS_IPAQ_RAW
- #define QT_QWS_SCREEN_COORDINATES
- typedef struct {
- unsigned short pressure;
- unsigned short x;
- unsigned short y;
- unsigned short pad;
- } TS_EVENT;
-#elif defined(QT_QWS_EBX)
- #define QT_QWS_EBX_RAW
- #define QT_QWS_SCREEN_COORDINATES
-#ifndef QT_QWS_SHARP
- typedef struct {
- unsigned short pressure;
- unsigned short x;
- unsigned short y;
- unsigned short pad;
- } TS_EVENT;
- #else
- typedef struct {
- long y;
- long x;
- long pressure;
- long long millisecs;
- } TS_EVENT;
- #define QT_QWS_TP_SAMPLE_SIZE 10
- #define QT_QWS_TP_MINIMUM_SAMPLES 4
- #define QT_QWS_TP_PRESSURE_THRESHOLD 500
- #define QT_QWS_TP_MOVE_LIMIT 50
- #define QT_QWS_TP_JITTER_LIMIT 2
- #endif
-#else // not IPAQ, not SHARP
- typedef struct {
- unsigned short pressure;
- unsigned short x;
- unsigned short y;
- unsigned short pad;
- } TS_EVENT;
-#endif
-
-#ifndef QT_QWS_TP_SAMPLE_SIZE
-#define QT_QWS_TP_SAMPLE_SIZE 5
-#endif
-
-#ifndef QT_QWS_TP_MINIMUM_SAMPLES
-#define QT_QWS_TP_MINIMUM_SAMPLES 5
-#endif
-
-#ifndef QT_QWS_TP_PRESSURE_THRESHOLD
-#define QT_QWS_TP_PRESSURE_THRESHOLD 1
-#endif
-
-#ifndef QT_QWS_TP_MOVE_LIMIT
-#define QT_QWS_TP_MOVE_LIMIT 100
-#endif
-
-#ifndef QT_QWS_TP_JITTER_LIMIT
-#define QT_QWS_TP_JITTER_LIMIT 2
-#endif
-
-class QWSLinuxTPMouseHandlerPrivate : public QObject
-{
- Q_OBJECT
-public:
- QWSLinuxTPMouseHandlerPrivate(QWSLinuxTPMouseHandler *h, const QString &);
- ~QWSLinuxTPMouseHandlerPrivate();
-
- void suspend();
- void resume();
-private:
- static const int mouseBufSize = 2048;
- int mouseFD;
- QPoint oldmouse;
- QPoint oldTotalMousePos;
- bool waspressed;
- QPolygon samples;
- int currSample;
- int lastSample;
- int numSamples;
- int skipCount;
- int mouseIdx;
- uchar mouseBuf[mouseBufSize];
- QWSLinuxTPMouseHandler *handler;
- QSocketNotifier *mouseNotifier;
-
-private slots:
- void readMouseData();
-};
-
-QWSLinuxTPMouseHandler::QWSLinuxTPMouseHandler(const QString &driver, const QString &device)
- : QWSCalibratedMouseHandler(driver, device)
-{
- d = new QWSLinuxTPMouseHandlerPrivate(this, device);
-}
-
-QWSLinuxTPMouseHandler::~QWSLinuxTPMouseHandler()
-{
- delete d;
-}
-
-void QWSLinuxTPMouseHandler::suspend()
-{
- d->suspend();
-}
-
-void QWSLinuxTPMouseHandler::resume()
-{
- d->resume();
-}
-
-QWSLinuxTPMouseHandlerPrivate::QWSLinuxTPMouseHandlerPrivate(QWSLinuxTPMouseHandler *h,
- const QString &device)
- : samples(QT_QWS_TP_SAMPLE_SIZE), currSample(0), lastSample(0),
- numSamples(0), skipCount(0), handler(h)
-{
- QString mousedev;
- if (device.isEmpty()) {
-#if defined(QT_QWS_IPAQ)
-# ifdef QT_QWS_IPAQ_RAW
- mousedev = QLatin1String("/dev/h3600_tsraw");
-# else
- mousedev = QLatin1String("/dev/h3600_ts");
-# endif
-#else
- mousedev = QLatin1String("/dev/ts");
-#endif
- } else {
- mousedev = device;
- }
- if ((mouseFD = QT_OPEN(mousedev.toLatin1().constData(), O_RDONLY | O_NDELAY)) < 0) {
- qWarning("Cannot open %s (%s)", qPrintable(mousedev), strerror(errno));
- return;
- }
-
- mouseNotifier = new QSocketNotifier(mouseFD, QSocketNotifier::Read,
- this);
- connect(mouseNotifier, SIGNAL(activated(int)),this, SLOT(readMouseData()));
- waspressed=false;
- mouseIdx = 0;
-}
-
-QWSLinuxTPMouseHandlerPrivate::~QWSLinuxTPMouseHandlerPrivate()
-{
- if (mouseFD >= 0)
- QT_CLOSE(mouseFD);
-}
-
-void QWSLinuxTPMouseHandlerPrivate::suspend()
-{
- if (mouseNotifier)
- mouseNotifier->setEnabled(false);
-}
-
-void QWSLinuxTPMouseHandlerPrivate::resume()
-{
- mouseIdx=0;
- currSample=0;
- lastSample=0;
- numSamples=0;
- skipCount=0;
- if (mouseNotifier)
- mouseNotifier->setEnabled(true);
-}
-
-
-void QWSLinuxTPMouseHandlerPrivate::readMouseData()
-{
- if(!qt_screen)
- return;
-
- int n;
- do {
- n = QT_READ(mouseFD, mouseBuf+mouseIdx, mouseBufSize-mouseIdx);
- if (n > 0)
- mouseIdx += n;
- } while (n > 0 && mouseIdx < mouseBufSize);
-
- //qDebug("readMouseData()");
-
- TS_EVENT *data;
- int idx = 0;
-
- // perhaps we shouldn't be reading EVERY SAMPLE.
- while (mouseIdx-idx >= (int)sizeof(TS_EVENT)) {
- uchar *mb = mouseBuf+idx;
- data = (TS_EVENT *) mb;
-
- if(data->pressure >= QT_QWS_TP_PRESSURE_THRESHOLD) {
-#ifdef QT_QWS_SHARP
- samples[currSample] = QPoint(1000 - data->x, data->y);
-#else
- samples[currSample] = QPoint(data->x, data->y);
-#endif
- numSamples++;
- if (numSamples >= QT_QWS_TP_MINIMUM_SAMPLES) {
- int sampleCount = qMin(numSamples + 1,samples.count());
-
- // average the rest
- QPoint mousePos = QPoint(0, 0);
- QPoint totalMousePos = oldTotalMousePos;
- totalMousePos += samples[currSample];
- if(numSamples >= samples.count())
- totalMousePos -= samples[lastSample];
-
- mousePos = totalMousePos / (sampleCount - 1);
-#if defined(QT_QWS_SCREEN_COORDINATES)
- mousePos = handler->transform(mousePos);
-#endif
- if(!waspressed)
- oldmouse = mousePos;
- QPoint dp = mousePos - oldmouse;
- int dxSqr = dp.x() * dp.x();
- int dySqr = dp.y() * dp.y();
- if (dxSqr + dySqr < (QT_QWS_TP_MOVE_LIMIT * QT_QWS_TP_MOVE_LIMIT)) {
- if (waspressed) {
- if ((dxSqr + dySqr > (QT_QWS_TP_JITTER_LIMIT * QT_QWS_TP_JITTER_LIMIT)) || skipCount > 2) {
- handler->mouseChanged(mousePos,Qt::LeftButton);
- oldmouse = mousePos;
- skipCount = 0;
- } else {
- skipCount++;
- }
- } else {
- handler->mouseChanged(mousePos,Qt::LeftButton);
- oldmouse=mousePos;
- waspressed=true;
- }
-
- // save recuring information
- currSample++;
- if (numSamples >= samples.count())
- lastSample++;
- oldTotalMousePos = totalMousePos;
- } else {
- numSamples--; // don't use this sample, it was bad.
- }
- } else {
- // build up the average
- oldTotalMousePos += samples[currSample];
- currSample++;
- }
- if (currSample >= samples.count())
- currSample = 0;
- if (lastSample >= samples.count())
- lastSample = 0;
- } else {
- currSample = 0;
- lastSample = 0;
- numSamples = 0;
- skipCount = 0;
- oldTotalMousePos = QPoint(0,0);
- if (waspressed) {
- handler->mouseChanged(oldmouse,0);
- oldmouse = QPoint(-100, -100);
- waspressed=false;
- }
- }
- idx += sizeof(TS_EVENT);
- }
-
- int surplus = mouseIdx - idx;
- for (int i = 0; i < surplus; i++)
- mouseBuf[i] = mouseBuf[idx+i];
- mouseIdx = surplus;
-}
-
-QT_END_NAMESPACE
-
-#include "qmouselinuxtp_qws.moc"
-
-#endif //QT_NO_QWS_MOUSE_LINUXTP
diff --git a/src/gui/embedded/qmouselinuxtp_qws.h b/src/gui/embedded/qmouselinuxtp_qws.h
deleted file mode 100644
index cef47449d5..0000000000
--- a/src/gui/embedded/qmouselinuxtp_qws.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QMOUSELINUXTP_QWS_H
-#define QMOUSELINUXTP_QWS_H
-
-#include <QtGui/qmouse_qws.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_QWS_MOUSE_LINUXTP
-
-class QWSLinuxTPMouseHandlerPrivate;
-
-class QWSLinuxTPMouseHandler : public QWSCalibratedMouseHandler
-{
- friend class QWSLinuxTPMouseHandlerPrivate;
-public:
- explicit QWSLinuxTPMouseHandler(const QString & = QString(),
- const QString & = QString());
- ~QWSLinuxTPMouseHandler();
-
- void suspend();
- void resume();
-protected:
- QWSLinuxTPMouseHandlerPrivate *d;
-};
-
-#endif // QT_NO_QWS_MOUSE_LINUXTP
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QMOUSELINUXTP_QWS_H
diff --git a/src/gui/embedded/qmousepc_qws.cpp b/src/gui/embedded/qmousepc_qws.cpp
deleted file mode 100644
index c22cab91f2..0000000000
--- a/src/gui/embedded/qmousepc_qws.cpp
+++ /dev/null
@@ -1,794 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qmousepc_qws.h"
-
-#ifndef QT_NO_QWS_MOUSE_PC
-
-#include "qwindowsystem_qws.h"
-#include "qsocketnotifier.h"
-#include "qwsevent_qws.h"
-#include "qwscommand_qws_p.h"
-#include "qwsutils_qws.h"
-
-#include "qapplication.h"
-#include "qpolygon.h"
-#include "qtimer.h"
-#include "qfile.h"
-#include "qtextstream.h"
-#include "qstringlist.h"
-#include <private/qcore_unix_p.h> // overrides QT_OPEN
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <termios.h>
-
-#include <qscreen_qws.h>
-
-QT_BEGIN_NAMESPACE
-
-//#define QWS_MOUSE_DEBUG
-
-/*
- * Automatic-detection mouse driver
- */
-
-class QWSPcMouseSubHandler {
-protected:
- enum { max_buf=32 };
-
- int fd;
-
- uchar buffer[max_buf];
- int nbuf;
-
- QPoint motion;
- int bstate;
- int wheel;
-
- int goodness;
- int badness;
-
- virtual int tryData()=0;
-
-public:
- QWSPcMouseSubHandler(int f) : fd(f)
- {
- initState();
- }
- virtual ~QWSPcMouseSubHandler() {}
-
- int file() const { return fd; }
-
- void closeIfNot(int& f)
- {
- if (fd != f) {
- f = fd;
- QT_CLOSE(fd);
- }
- }
-
- void initState() { nbuf = bstate = goodness = badness = 0; }
-
- void worse(int by=1) { badness+=by; }
- bool reliable() const { return goodness >= 5 && badness < 50; }
- int buttonState() const { return bstate; }
- bool motionPending() const { return motion!=QPoint(0,0); }
- QPoint takeMotion() { QPoint r=motion; motion=QPoint(0,0); return r; }
- int takeWheel() { int result = wheel; wheel = 0; return result; }
-
- void appendData(uchar* data, int length)
- {
- memcpy(buffer+nbuf, data, length);
- nbuf += length;
- }
-
- enum UsageResult { Insufficient, Motion, Button };
-
- UsageResult useData()
- {
- int pbstate = bstate;
- int n = tryData();
-#ifdef QWS_MOUSE_DEBUG
- if (n) {
- fprintf(stderr, "QWSPcMouseSubHandler tryData read %d bytes:", n);
- for (int i=0; i<n; ++i)
- fprintf(stderr, " %02x", buffer[i]);
- fprintf(stderr, "\n");
- }
-#endif
- if (n > 0) {
- if (n<nbuf)
- memmove(buffer, buffer+n, nbuf-n);
- nbuf -= n;
- return (wheel || pbstate != bstate) ? Button : Motion;
- }
- return Insufficient;
- }
-};
-
-class QWSPcMouseSubHandler_intellimouse : public QWSPcMouseSubHandler {
- int packetsize;
-public:
- QWSPcMouseSubHandler_intellimouse(int f) : QWSPcMouseSubHandler(f)
- {
- init();
- }
-
- void init()
- {
- int n;
- uchar reply[20];
-
- if (tcflush(fd,TCIOFLUSH) == -1) {
-#ifdef QWS_MOUSE_DEBUG
- perror("QWSPcMouseSubHandler_intellimouse: pre-init tcflush");
-#endif
- }
- static const uchar initseq[] = { 243, 200, 243, 100, 243, 80 };
- static const uchar query[] = { 0xf2 };
- if (QT_WRITE(fd, initseq, sizeof(initseq))!=sizeof(initseq)) {
- badness = 100;
- return;
- }
- usleep(10000);
- if (tcflush(fd,TCIOFLUSH) == -1) {
-#ifdef QWS_MOUSE_DEBUG
- perror("QWSPcMouseSubHandler_intellimouse: post-init tcflush");
-#endif
- }
- if (QT_WRITE(fd, query, sizeof(query))!=sizeof(query)) {
- badness = 100;
- return;
- }
- usleep(10000);
- n = QT_READ(fd, reply, 20);
- if (n > 0) {
- goodness = 10;
- switch (reply[n-1]) {
- case 3:
- case 4:
- packetsize = 4;
- break;
- default:
- packetsize = 3;
- }
- } else {
- badness = 100;
- }
- }
-
- int tryData()
- {
- if (nbuf >= packetsize) {
- //int overflow = (buffer[0]>>6)& 0x03;
-
- if (/*overflow ||*/ !(buffer[0] & 8)) {
-#ifdef QWS_MOUSE_DEBUG
- qDebug("Intellimouse: skipping (overflow)");
-#endif
- badness++;
- return 1;
- } else {
- QPoint delta((buffer[0] & 0x10) ? buffer[1]-256 : buffer[1],
- (buffer[0] & 0x20) ? 256-buffer[2] : -buffer[2]);
- motion += delta;
- int nbstate = buffer[0] & 0x7;
-#ifdef QWS_MOUSE_DEBUG
- int debugwheel =
-#endif
- wheel = packetsize > 3 ? -(signed char)buffer[3] : 0;
- if (wheel < -2 || wheel > 2)
- wheel = 0;
- wheel *= 120; // WHEEL_DELTA?
-#ifdef QWS_MOUSE_DEBUG
- qDebug("Intellimouse: motion %d,%d, state %d, raw wheel %d, wheel %d", motion.x(), motion.y(), nbstate, debugwheel, wheel);
-#endif
- if (motion.x() || motion.y() || bstate != nbstate || wheel) {
- bstate = nbstate;
- goodness++;
- } else {
- badness++;
- return 1;
- }
- }
- return packetsize;
- }
- return 0;
- }
-};
-
-class QWSPcMouseSubHandler_mouseman : public QWSPcMouseSubHandler {
- int packetsize;
-public:
- QWSPcMouseSubHandler_mouseman(int f) : QWSPcMouseSubHandler(f)
- {
- init();
- }
-
- void init()
- {
- if (tcflush(fd,TCIOFLUSH) == -1) {
-#ifdef QWS_MOUSE_DEBUG
- perror("QWSPcMouseSubHandler_mouseman: initial tcflush");
-#endif
- }
- QT_WRITE(fd,"",1);
- usleep(50000);
- QT_WRITE(fd,"@EeI!",5);
- usleep(10000);
- static const unsigned char ibuf[] = { 246, 244 };
- QT_WRITE(fd,ibuf,1);
- QT_WRITE(fd,ibuf+1,1);
- if (tcflush(fd,TCIOFLUSH) == -1) {
-#ifdef QWS_MOUSE_DEBUG
- perror("QWSPcMouseSubHandler_mouseman: tcflush");
-#endif
- }
- usleep(10000);
-
- char buf[100];
- while (QT_READ(fd, buf, 100) > 0) { } // eat unwanted replies
- }
-
- int tryData()
- {
- if (nbuf >= 3) {
- int nbstate = 0;
- if (buffer[0] & 0x01)
- nbstate |= Qt::LeftButton;
- if (buffer[0] & 0x02)
- nbstate |= Qt::RightButton;
- if (buffer[0] & 0x04)
- nbstate |= Qt::MidButton;
-
- int overflow = (buffer[0]>>6)& 0x03;
- if (overflow) {
- //### wheel events signalled with overflow bit, ignore for now
- badness++;
- return 1;
- } else {
- bool xs = buffer[0] & 0x10;
- bool ys = buffer[0] & 0x20;
- int dx = xs ? buffer[1]-256 : buffer[1];
- int dy = ys ? buffer[2]-256 : buffer[2];
-
- motion += QPoint(dx, -dy);
- if (motion.x() || motion.y() || bstate != nbstate) {
- bstate = nbstate;
- goodness++;
- } else {
- badness++;
- return 1;
- }
- }
- return 3;
- }
- return 0;
- }
-};
-
-class QWSPcMouseSubHandler_serial : public QWSPcMouseSubHandler {
-public:
- QWSPcMouseSubHandler_serial(int f) : QWSPcMouseSubHandler(f)
- {
- initSerial();
- }
-
-protected:
- void setflags(int f)
- {
- termios tty;
- if (tcgetattr(fd, &tty) == -1) {
-#ifdef QWS_MOUSE_DEBUG
- perror("QWSPcMouseSubHandler_serial: tcgetattr");
-#endif
- }
- tty.c_iflag = IGNBRK | IGNPAR;
- tty.c_oflag = 0;
- tty.c_lflag = 0;
- tty.c_cflag = f | CREAD | CLOCAL | HUPCL;
-#ifdef Q_OS_LINUX
- tty.c_line = 0;
-#endif
- tty.c_cc[VTIME] = 0;
- tty.c_cc[VMIN] = 1;
- if (tcsetattr(fd, TCSANOW, &tty) == -1) {
-#ifdef QWS_MOUSE_DEBUG
- perror("QWSPcMouseSubHandler_serial: tcgetattr");
-#endif
- }
- }
-
-private:
- void initSerial()
- {
- int speed[4] = { B9600, B4800, B2400, B1200 };
-
- for (int n = 0; n < 4; n++) {
- setflags(CSTOPB | speed[n]);
- QT_WRITE(fd, "*q", 2);
- usleep(10000);
- }
- }
-};
-
-class QWSPcMouseSubHandler_mousesystems : public QWSPcMouseSubHandler_serial {
-public:
- // ##### This driver has not been tested
-
- QWSPcMouseSubHandler_mousesystems(int f) : QWSPcMouseSubHandler_serial(f)
- {
- init();
- }
-
- void init()
- {
- setflags(B1200|CS8|CSTOPB);
- // 60Hz
- if (QT_WRITE(fd, "R", 1)!=1) {
- badness = 100;
- return;
- }
- if (tcflush(fd,TCIOFLUSH) == -1) {
-#ifdef QT_QWS_VNC_DEBUG
- perror("QWSPcMouseSubHandler_mousesystems: tcflush");
-#endif
- }
- }
-
- int tryData()
- {
- if (nbuf >= 5) {
- if ((buffer[0] & 0xf8) != 0x80) {
- badness++;
- return 1;
- }
- motion +=
- QPoint((signed char)buffer[1] + (signed char)buffer[3],
- -(signed char)buffer[2] + (signed char)buffer[4]);
- int t = ~buffer[0];
- int nbstate = ((t&3) << 1) | ((t&4) >> 2);
- if (motion.x() || motion.y() || bstate != nbstate) {
- bstate = nbstate;
- goodness++;
- } else {
- badness++;
- return 1;
- }
- return 5;
- }
- return 0;
- }
-};
-
-class QWSPcMouseSubHandler_ms : public QWSPcMouseSubHandler_serial {
- int mman;
-public:
- QWSPcMouseSubHandler_ms(int f) : QWSPcMouseSubHandler_serial(f)
- {
- mman=0;
- init();
- }
-
- void init()
- {
- setflags(B1200|CS7);
- // 60Hz
- if (QT_WRITE(fd, "R", 1)!=1) {
- badness = 100;
- return;
- }
- if (tcflush(fd,TCIOFLUSH) == -1) {
-#ifdef QWS_MOUSE_DEBUG
- perror("QWSPcMouseSubHandler_ms: tcflush");
-#endif
- }
- }
-
- int tryData()
- {
- if (!(buffer[0] & 0x40)) {
- if (buffer[0] == 0x20 && (bstate & Qt::MidButton)) {
- mman=1; // mouseman extension
- }
- return 1;
- }
- int extra = mman&&(bstate & Qt::MidButton);
- if (nbuf >= 3+extra) {
- int nbstate = 0;
- if (buffer[0] == 0x40 && !bstate && !buffer[1] && !buffer[2]) {
- nbstate = Qt::MidButton;
- } else {
- nbstate = ((buffer[0] & 0x20) >> 5)
- | ((buffer[0] & 0x10) >> 3);
- if (extra && buffer[3] == 0x20)
- nbstate = Qt::MidButton;
- }
-
- if (buffer[1] & 0x40) {
- badness++;
- return 1;
- } else {
- motion +=
- QPoint((signed char)((buffer[0]&0x3)<<6)
- |(signed char)(buffer[1]&0x3f),
- (signed char)((buffer[0]&0xc)<<4)
- |(signed char)(buffer[2]&0x3f));
- if (motion.x() || motion.y() || bstate != nbstate) {
- bstate = nbstate;
- goodness++;
- } else {
- badness++;
- return 1;
- }
- return 3+extra;
- }
- }
- return 0;
- }
-};
-
-//===========================================================================
-
-class QWSPcMouseHandlerPrivate : public QObject
-{
- Q_OBJECT
-public:
- QWSPcMouseHandlerPrivate(QWSPcMouseHandler *h, const QString &, const QString &);
- ~QWSPcMouseHandlerPrivate();
-
- void suspend();
- void resume();
-
-private:
- enum { max_dev=32 };
- QWSPcMouseSubHandler *sub[max_dev];
- QList<QSocketNotifier*> notifiers;
- int nsub;
- int retries;
-
-private slots:
- void readMouseData(int);
-
-private:
- void openDevices();
- void closeDevices();
- void notify(int fd);
- bool sendEvent(QWSPcMouseSubHandler& h);
-
-private:
- QWSPcMouseHandler *handler;
- QString driver;
- QString device;
- qreal accel;
- int accel_limit;
-};
-
-QWSPcMouseHandler::QWSPcMouseHandler(const QString &driver, const QString &device)
- : QWSMouseHandler(driver, device)
-{
- d = new QWSPcMouseHandlerPrivate(this, driver, device);
-}
-
-QWSPcMouseHandler::~QWSPcMouseHandler()
-{
- delete d;
-}
-
-void QWSPcMouseHandler::suspend()
-{
- d->suspend();
-}
-
-void QWSPcMouseHandler::resume()
-{
- d->resume();
-}
-
-
-QWSPcMouseHandlerPrivate::QWSPcMouseHandlerPrivate(QWSPcMouseHandler *h,
- const QString &drv, const QString &arg)
- : handler(h), driver(drv)
-{
- QStringList args = arg.split(QLatin1Char(':'), QString::SkipEmptyParts);
-
- int index;
-
- accel = qreal(2.0);
- QRegExp accelRegex(QLatin1String("^accel=(\\d+\\.?\\d*)$"));
- index = args.indexOf(accelRegex);
- if (index >= 0) {
- accel = qreal(accelRegex.cap(1).toDouble());
- args.removeAt(index);
- }
-
- accel_limit = 5;
- QRegExp accelLimitRegex(QLatin1String("^accel_limit=(\\d+)$"));
- index = args.indexOf(accelLimitRegex);
- if (index >= 0) {
- accel_limit = accelLimitRegex.cap(1).toInt();
- args.removeAt(index);
- }
-
- device = args.join(QString());
-
- retries = 0;
- openDevices();
-}
-
-QWSPcMouseHandlerPrivate::~QWSPcMouseHandlerPrivate()
-{
- closeDevices();
-}
-
-/*
-QWSPcMouseHandler::UsageResult QWSPcMouseHandler::useDev(Dev& d)
-{
- if (d.nbuf >= mouseData[d.protocol].bytesPerPacket) {
- uchar *mb = d.buf;
- int bstate = 0;
- int dx = 0;
- int dy = 0;
-
- switch (mouseProtocol) {
- case MouseMan:
- case IntelliMouse:
- {
- bstate = mb[0] & 0x7; // assuming Qt::*Button order
-
- int overflow = (mb[0]>>6)& 0x03;
- if (mouseProtocol == MouseMan && overflow) {
- //### wheel events signalled with overflow bit, ignore for now
- }
- else {
- bool xs = mb[0] & 0x10;
- bool ys = mb[0] & 0x20;
- dx = xs ? mb[1]-256 : mb[1];
- dy = ys ? mb[2]-256 : mb[2];
- }
- break;
- }
- case Microsoft:
- if (((mb[0] & 0x20) >> 3)) {
- bstate |= Qt::LeftButton;
- }
- if (((mb[0] & 0x10) >> 4)) {
- bstate |= Qt::RightButton;
- }
-
- dx=(signed char)(((mb[0] & 0x03) << 6) | (mb[1] & 0x3f));
- dy=-(signed char)(((mb[0] & 0x0c) << 4) | (mb[2] & 0x3f));
-
- break;
- }
- }
- }
-*/
-
-
-bool QWSPcMouseHandlerPrivate::sendEvent(QWSPcMouseSubHandler& h)
-{
- if (h.reliable()) {
- QPoint motion = h.takeMotion();
- if (qAbs(motion.x()) > accel_limit || qAbs(motion.y()) > accel_limit)
- motion *= accel;
- QPoint newPos = handler->pos() + motion;
- if (qt_screen->isTransformed()) {
- QSize s = QSize(qt_screen->width(), qt_screen->height());
- newPos = qt_screen->mapToDevice(newPos, s);
- }
- handler->limitToScreen(newPos);
-
- handler->mouseChanged(newPos, h.buttonState(), h.takeWheel());
- return true;
- } else {
- h.takeMotion();
- if (h.buttonState() & (Qt::RightButton|Qt::MidButton)) {
- // Strange for the user to press right or middle without
- // a moving mouse!
- h.worse();
- }
- return false;
- }
-}
-
-void QWSPcMouseHandlerPrivate::openDevices()
-{
- nsub=0;
- int fd = -1;
-
- QString drv = driver.toLower();
- if (!drv.isEmpty() && drv != QLatin1String("auto")) {
- // Manually specified mouse
- QByteArray dev = device.toLatin1();
- if (drv == QLatin1String("intellimouse")) {
- if (dev.isEmpty())
- dev = "/dev/psaux";
- fd = QT_OPEN(dev, O_RDWR | O_NDELAY);
- if (fd >= 0)
- sub[nsub++] = new QWSPcMouseSubHandler_intellimouse(fd);
- } else if (drv == QLatin1String("microsoft")) {
- if (dev.isEmpty())
- dev = "/dev/ttyS0";
- fd = QT_OPEN(dev, O_RDWR | O_NDELAY);
- if (fd >= 0)
- sub[nsub++] = new QWSPcMouseSubHandler_ms(fd);
- } else if (drv == QLatin1String("mousesystems")) {
- if (dev.isEmpty())
- dev = "/dev/ttyS0";
- fd = QT_OPEN(dev, O_RDWR | O_NDELAY);
- if (fd >= 0)
- sub[nsub++] = new QWSPcMouseSubHandler_mousesystems(fd);
- } else if (drv == QLatin1String("mouseman")) {
- if (dev.isEmpty())
- dev = "/dev/psaux";
- fd = QT_OPEN(dev, O_RDWR | O_NDELAY);
- if (fd >= 0)
- sub[nsub++] = new QWSPcMouseSubHandler_mouseman(fd);
- }
- if (fd >= 0)
- notify(fd);
- else
- qCritical("Error opening mouse device '%s': %s",
- dev.constData(), strerror(errno));
- } else {
- // Try automatically
- fd = QT_OPEN("/dev/psaux", O_RDWR | O_NDELAY);
- if (fd >= 0) {
- sub[nsub++] = new QWSPcMouseSubHandler_intellimouse(fd);
- notify(fd);
- }
- fd = QT_OPEN("/dev/input/mice", O_RDWR | O_NDELAY);
- if (fd >= 0) {
- sub[nsub++] = new QWSPcMouseSubHandler_intellimouse(fd);
- notify(fd);
- //qDebug("/dev/input/mice fd %d #%d", fd, nsub-1);
- }
-
-// include the code below to auto-detect serial mice, and to mess up
-// any sort of serial communication
-#if 0
- const char fn[4][11] = { "/dev/ttyS0", "/dev/ttyS1", "/dev/ttyS2", "/dev/ttyS3" };
- for (int ch = 0; ch < 4; ++ch) {
- fd = QT_OPEN(fn[ch], O_RDWR | O_NDELAY);
- if (fd >= 0) {
- //sub[nsub++] = new QWSPcMouseSubHandler_intellimouse(fd);
- sub[nsub++] = new QWSPcMouseSubHandler_mousesystems(fd);
- sub[nsub++] = new QWSPcMouseSubHandler_ms(fd);
- notify(fd);
- }
- }
-#endif
- }
-}
-
-void QWSPcMouseHandlerPrivate::closeDevices()
-{
- int pfd=-1;
- for (int i=0; i<nsub; i++) {
- sub[i]->closeIfNot(pfd);
- delete sub[i];
- }
- qDeleteAll(notifiers);
- notifiers.clear();
-}
-
-void QWSPcMouseHandlerPrivate::suspend()
-{
- for (int i=0; i<notifiers.size(); ++i)
- notifiers.at(i)->setEnabled(false);
-}
-
-void QWSPcMouseHandlerPrivate::resume()
-{
- for (int i=0; i<nsub; i++)
- sub[i]->initState();
-
- for (int i=0; i<notifiers.size(); ++i)
- notifiers.at(i)->setEnabled(true);
-}
-
-
-
-void QWSPcMouseHandlerPrivate::notify(int fd)
-{
- QSocketNotifier *mouseNotifier
- = new QSocketNotifier(fd, QSocketNotifier::Read, this);
- connect(mouseNotifier, SIGNAL(activated(int)),this, SLOT(readMouseData(int)));
- notifiers.append(mouseNotifier);
-}
-
-void QWSPcMouseHandlerPrivate::readMouseData(int fd)
-{
- for (;;) {
- uchar buf[8];
- int n = read(fd, buf, 8);
- if (n<=0)
- break;
- for (int i=0; i<nsub; i++) {
- QWSPcMouseSubHandler& h = *sub[i];
- if (h.file() == fd) {
- h.appendData(buf,n);
- for (;;) {
- switch (h.useData()) {
- case QWSPcMouseSubHandler::Button:
- sendEvent(h);
- break;
- case QWSPcMouseSubHandler::Insufficient:
- goto breakbreak;
- case QWSPcMouseSubHandler::Motion:
- break;
- }
- }
- breakbreak:
- ;
- }
- }
- }
- bool any_reliable=false;
- for (int i=0; i<nsub; i++) {
- QWSPcMouseSubHandler& h = *sub[i];
- if (h.motionPending())
- sendEvent(h);
- any_reliable = any_reliable || h.reliable();
- }
- if (any_reliable) {
- // ... get rid of all unreliable ones? All bad ones?
- } else if (retries < 2) {
- // Try again - maybe the mouse was being moved when we tried to init.
- closeDevices();
- openDevices();
- retries++;
- }
-}
-
-QT_END_NAMESPACE
-
-#include "qmousepc_qws.moc"
-
-#endif // QT_NO_MOUSE_PC
diff --git a/src/gui/embedded/qmousepc_qws.h b/src/gui/embedded/qmousepc_qws.h
deleted file mode 100644
index 0e4dfbc19b..0000000000
--- a/src/gui/embedded/qmousepc_qws.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QMOUSEPC_QWS_H
-#define QMOUSEPC_QWS_H
-
-#include <QtGui/qmouse_qws.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_QWS_MOUSE_PC
-
-class QWSPcMouseHandlerPrivate;
-
-class QWSPcMouseHandler : public QWSMouseHandler
-{
-public:
- explicit QWSPcMouseHandler(const QString & = QString(),
- const QString & = QString());
- ~QWSPcMouseHandler();
-
- void suspend();
- void resume();
-protected:
- QWSPcMouseHandlerPrivate *d;
-};
-
-#endif // QT_NO_QWS_MOUSE_PC
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QMOUSEPC_QWS_H
diff --git a/src/gui/embedded/qmouseqnx_qws.cpp b/src/gui/embedded/qmouseqnx_qws.cpp
deleted file mode 100644
index a9647c0fff..0000000000
--- a/src/gui/embedded/qmouseqnx_qws.cpp
+++ /dev/null
@@ -1,190 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qplatformdefs.h"
-#include "qmouseqnx_qws.h"
-
-#include "qsocketnotifier.h"
-#include "qdebug.h"
-
-#include <sys/dcmd_input.h>
-
-#include <errno.h>
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \class QQnxMouseHandler
- \preliminary
- \ingroup qws
- \internal
- \since 4.6
-
- \brief The QQnxMouseHandler class implements a mouse driver
- for the QNX \c{devi-hid} input manager.
-
- To be able to compile this mouse handler, \l{Qt for Embedded Linux}
- must be configured with the \c -qt-mouse-qnx option, see the
- \l{Qt for Embedded Linux Pointer Handling}{Pointer Handling} documentation for details.
-
- In order to use this mouse handler, the \c{devi-hid} input manager
- must be set up and run with the resource manager interface (option \c{-r}).
- Also, Photon must not be running.
-
- Example invocation from command line: \c{/usr/photon/bin/devi-hid -Pr kbd mouse}
- Note that after running \c{devi-hid}, you will not be able to use the local
- shell anymore. It is suggested to run the command in a shell scrip, that launches
- a Qt application after invocation of \c{devi-hid}.
-
- To make \l{Qt for Embedded Linux} explicitly choose the qnx mouse
- handler, set the QWS_MOUSE_PROTO environment variable to \c{qnx}. By default,
- the first mouse device (\c{/dev/devi/mouse0}) is used. To override, pass a device
- name as the first and only parameter, for example
- \c{QWS_MOUSE_PROTO=qnx:/dev/devi/mouse1; export QWS_MOUSE_PROTO}.
-
- \sa {Qt for Embedded Linux Pointer Handling}{Pointer Handling}, {Qt for Embedded Linux}
-*/
-
-/*!
- Constructs a mouse handler for the specified \a device, defaulting to \c{/dev/devi/mouse0}.
- The \a driver parameter must be \c{"qnx"}.
-
- Note that you should never instanciate this class, instead let QMouseDriverFactory
- handle the mouse handlers.
-
- \sa QMouseDriverFactory
- */
-QQnxMouseHandler::QQnxMouseHandler(const QString & /*driver*/, const QString &device)
-{
- // open the mouse device with O_NONBLOCK so reading won't block when there's no data
- mouseFD = QT_OPEN(device.isEmpty() ? "/dev/devi/mouse0" : device.toLatin1().constData(),
- QT_OPEN_RDONLY | O_NONBLOCK);
- if (mouseFD == -1) {
- qErrnoWarning(errno, "QQnxMouseHandler: Unable to open mouse device");
- return;
- }
-
- // register a socket notifier on the file descriptor so we'll wake up whenever
- // there's a mouse move waiting for us.
- mouseNotifier = new QSocketNotifier(mouseFD, QSocketNotifier::Read, this);
- connect(mouseNotifier, SIGNAL(activated(int)), SLOT(socketActivated()));
-
- qDebug() << "QQnxMouseHandler: connected.";
-}
-
-/*!
- Destroys this mouse handler and closes the connection to the mouse device.
- */
-QQnxMouseHandler::~QQnxMouseHandler()
-{
- QT_CLOSE(mouseFD);
-}
-
-/*! \reimp */
-void QQnxMouseHandler::resume()
-{
- if (mouseNotifier)
- mouseNotifier->setEnabled(true);
-}
-
-/*! \reimp */
-void QQnxMouseHandler::suspend()
-{
- if (mouseNotifier)
- mouseNotifier->setEnabled(false);
-}
-
-/*! \internal
-
- This function is called whenever there is activity on the mouse device.
- By default, it reads up to 10 mouse move packets and calls mouseChanged()
- for each of them.
-*/
-void QQnxMouseHandler::socketActivated()
-{
- // _mouse_packet is a QNX structure. devi-hid is nice enough to translate
- // the raw byte data from mouse devices into generic format for us.
- _mouse_packet packet;
-
- int iteration = 0;
-
- // read mouse events in batches of 10. Since we're getting quite a lot
- // of mouse events, it's better to do them in batches than to return to the
- // event loop every time.
- do {
- int bytesRead = QT_READ(mouseFD, &packet, sizeof(packet));
- if (bytesRead == -1) {
- // EAGAIN means that there are no more mouse events to read
- if (errno != EAGAIN)
- qErrnoWarning(errno, "QQnxMouseHandler: Unable to read from socket");
- return;
- }
-
- // bytes read should always be equal to the size of a packet.
- Q_ASSERT(bytesRead == sizeof(packet));
-
- // translate the coordinates from the QNX data structure to Qt coordinates
- // note the swapped y axis
- QPoint pos = mousePos;
- pos += QPoint(packet.dx, -packet.dy);
-
- // QNX only tells us relative mouse movements, not absolute ones, so limit the
- // cursor position manually to the screen
- limitToScreen(pos);
-
- // translate the QNX mouse button bitmask to Qt buttons
- int buttons = Qt::NoButton;
-
- if (packet.hdr.buttons & _POINTER_BUTTON_LEFT)
- buttons |= Qt::LeftButton;
- if (packet.hdr.buttons & _POINTER_BUTTON_MIDDLE)
- buttons |= Qt::MidButton;
- if (packet.hdr.buttons & _POINTER_BUTTON_RIGHT)
- buttons |= Qt::RightButton;
-
- // call mouseChanged() - this does all the magic to actually move the on-screen
- // mouse cursor.
- mouseChanged(pos, buttons, 0);
- } while (++iteration < 11);
-}
-
-QT_END_NAMESPACE
-
diff --git a/src/gui/embedded/qmouseqnx_qws.h b/src/gui/embedded/qmouseqnx_qws.h
deleted file mode 100644
index 2a5eef2daa..0000000000
--- a/src/gui/embedded/qmouseqnx_qws.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QMOUSE_QNX_H
-#define QMOUSE_QNX_H
-
-#include <QtCore/qobject.h>
-#include <QtGui/qmouse_qws.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QSocketNotifier;
-
-class Q_GUI_EXPORT QQnxMouseHandler : public QObject, public QWSMouseHandler
-{
- Q_OBJECT
-public:
- explicit QQnxMouseHandler(const QString &driver = QString(),
- const QString &device = QString());
- ~QQnxMouseHandler();
-
- void resume();
- void suspend();
-
-private Q_SLOTS:
- void socketActivated();
-
-private:
- QSocketNotifier *mouseNotifier;
- int mouseFD;
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QMOUSE_QWS_H
diff --git a/src/gui/embedded/qmousetslib_qws.cpp b/src/gui/embedded/qmousetslib_qws.cpp
deleted file mode 100644
index 5e2cce1d5c..0000000000
--- a/src/gui/embedded/qmousetslib_qws.cpp
+++ /dev/null
@@ -1,371 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qmousetslib_qws.h"
-
-#if !defined(QT_NO_QWS_MOUSE_TSLIB) || defined(QT_PLUGIN)
-
-#include <QtCore/qregexp.h>
-#include <QtCore/qstringlist.h>
-#include "qsocketnotifier.h"
-#include "qscreen_qws.h"
-
-#include <tslib.h>
-#include <errno.h>
-
-QT_BEGIN_NAMESPACE
-
-#ifdef TSLIBMOUSEHANDLER_DEBUG
-# include <QtCore/QDebug>
-#endif
-
-/*!
- \internal
-
- \class QWSTslibMouseHandler
- \ingroup qws
-
- \brief The QWSTslibMouseHandler class implements a mouse driver
- for the Universal Touch Screen Library, tslib.
-
- QWSTslibMouseHandler inherits the QWSCalibratedMouseHandler class,
- providing calibration and noise reduction functionality in
- addition to generating mouse events, for devices using the
- Universal Touch Screen Library.
-
- To be able to compile this mouse handler, \l{Qt for Embedded Linux}
- must be configured with the \c -qt-mouse-tslib option, see the
- \l{Pointer Handling} documentation for details. In addition, the tslib
- headers and library must be present in the build environment. The
- tslib sources can be downloaded from \l
- {http://tslib.berlios.de/}. Use the \c -L and \c -I options
- with \c configure to explicitly specify the location of the
- library and its headers:
-
- \snippet doc/src/snippets/code/src_gui_embedded_qmousetslib_qws.cpp 0
-
- In order to use this mouse handler, tslib must also be correctly
- installed on the target machine. This includes providing a \c
- ts.conf configuration file and setting the necessary environment
- variables, see the README file provided with tslib for details.
-
- The ts.conf file will usually contain the following two lines
-
- \snippet doc/src/snippets/code/src_gui_embedded_qmousetslib_qws.cpp 1
-
- To make \l{Qt for Embedded Linux} explicitly choose the tslib mouse
- handler, set the QWS_MOUSE_PROTO environment variable.
-
- \sa {Pointer Handling}, {Qt for Embedded Linux}
-*/
-
-class QWSTslibMouseHandlerPrivate : public QObject
-{
- Q_OBJECT
-public:
- QWSTslibMouseHandlerPrivate(QWSTslibMouseHandler *h,
- const QString &device);
- ~QWSTslibMouseHandlerPrivate();
-
- void suspend();
- void resume();
-
- void calibrate(const QWSPointerCalibrationData *data);
- void clearCalibration();
-
-private:
- QWSTslibMouseHandler *handler;
- struct tsdev *dev;
- QSocketNotifier *mouseNotifier;
- int jitter_limit;
-
- struct ts_sample lastSample;
- bool wasPressed;
- int lastdx;
- int lastdy;
-
- bool calibrated;
- QString devName;
-
- bool open();
- void close();
- inline bool get_sample(struct ts_sample *sample);
-
-private slots:
- void readMouseData();
-};
-
-QWSTslibMouseHandlerPrivate::QWSTslibMouseHandlerPrivate(QWSTslibMouseHandler *h,
- const QString &device)
- : handler(h), dev(0), mouseNotifier(0), jitter_limit(3)
-{
- QStringList args = device.split(QLatin1Char(':'), QString::SkipEmptyParts);
- QRegExp jitterRegex(QLatin1String("^jitter_limit=(\\d+)$"));
- int index = args.indexOf(jitterRegex);
- if (index >= 0) {
- jitter_limit = jitterRegex.cap(1).toInt();
- args.removeAt(index);
- }
-
- devName = args.join(QString());
-
- if (devName.isNull()) {
- const char *str = getenv("TSLIB_TSDEVICE");
- if (str)
- devName = QString::fromLocal8Bit(str);
- }
-
- if (devName.isNull())
- devName = QLatin1String("/dev/ts");
-
- if (!open())
- return;
-
- calibrated = true;
-
- int fd = ts_fd(dev);
- mouseNotifier = new QSocketNotifier(fd, QSocketNotifier::Read, this);
- connect(mouseNotifier, SIGNAL(activated(int)),this, SLOT(readMouseData()));
- resume();
-}
-
-QWSTslibMouseHandlerPrivate::~QWSTslibMouseHandlerPrivate()
-{
- close();
-}
-
-bool QWSTslibMouseHandlerPrivate::open()
-{
- dev = ts_open(devName.toLocal8Bit().constData(), 1);
- if (!dev) {
- qCritical("QWSTslibMouseHandlerPrivate: ts_open() failed"
- " with error: '%s'", strerror(errno));
- qCritical("Please check your tslib installation!");
- return false;
- }
-
- if (ts_config(dev)) {
- qCritical("QWSTslibMouseHandlerPrivate: ts_config() failed"
- " with error: '%s'", strerror(errno));
- qCritical("Please check your tslib installation!");
- close();
- return false;
- }
-
- return true;
-}
-
-void QWSTslibMouseHandlerPrivate::close()
-{
- if (dev)
- ts_close(dev);
-}
-
-void QWSTslibMouseHandlerPrivate::suspend()
-{
- if (mouseNotifier)
- mouseNotifier->setEnabled(false);
-}
-
-void QWSTslibMouseHandlerPrivate::resume()
-{
- memset(&lastSample, 0, sizeof(lastSample));
- wasPressed = false;
- lastdx = 0;
- lastdy = 0;
- if (mouseNotifier)
- mouseNotifier->setEnabled(true);
-}
-
-bool QWSTslibMouseHandlerPrivate::get_sample(struct ts_sample *sample)
-{
- if (!calibrated)
- return (ts_read_raw(dev, sample, 1) == 1);
-
- return (ts_read(dev, sample, 1) == 1);
-}
-
-void QWSTslibMouseHandlerPrivate::readMouseData()
-{
- if (!qt_screen)
- return;
-
- for(;;) {
- struct ts_sample sample = lastSample;
- bool pressed = wasPressed;
-
- // Fast return if there's no events.
- if (!get_sample(&sample))
- return;
- pressed = (sample.pressure > 0);
-
- // Only return last sample unless there's a press/release event.
- while (pressed == wasPressed) {
- if (!get_sample(&sample))
- break;
- pressed = (sample.pressure > 0);
- }
-
- // work around missing coordinates on mouse release in raw mode
- if (!calibrated && !pressed && sample.x == 0 && sample.y == 0) {
- sample.x = lastSample.x;
- sample.y = lastSample.y;
- }
-
- int dx = sample.x - lastSample.x;
- int dy = sample.y - lastSample.y;
-
- // Remove small movements in oppsite direction
- if (dx * lastdx < 0 && qAbs(dx) < jitter_limit) {
- sample.x = lastSample.x;
- dx = 0;
- }
- if (dy * lastdy < 0 && qAbs(dy) < jitter_limit) {
- sample.y = lastSample.y;
- dy = 0;
- }
-
- if (wasPressed == pressed && dx == 0 && dy == 0)
- return;
-
-#ifdef TSLIBMOUSEHANDLER_DEBUG
- qDebug() << "last" << QPoint(lastSample.x, lastSample.y)
- << "curr" << QPoint(sample.x, sample.y)
- << "dx,dy" << QPoint(dx, dy)
- << "ddx,ddy" << QPoint(dx*lastdx, dy*lastdy)
- << "pressed" << wasPressed << pressed;
-#endif
-
- lastSample = sample;
- wasPressed = pressed;
- if (dx != 0)
- lastdx = dx;
- if (dy != 0)
- lastdy = dy;
-
- const QPoint p(sample.x, sample.y);
- if (calibrated) {
- // tslib should do all the translation and filtering, so we send a
- // "raw" mouse event
- handler->QWSMouseHandler::mouseChanged(p, pressed);
- } else {
- handler->sendFiltered(p, pressed);
- }
- }
-}
-
-void QWSTslibMouseHandlerPrivate::clearCalibration()
-{
- suspend();
- close();
- handler->QWSCalibratedMouseHandler::clearCalibration();
- calibrated = false;
- open();
- resume();
-}
-
-void QWSTslibMouseHandlerPrivate::calibrate(const QWSPointerCalibrationData *data)
-{
- suspend();
- close();
- // default implementation writes to /etc/pointercal
- // using the same format as the tslib linear module.
- handler->QWSCalibratedMouseHandler::calibrate(data);
- calibrated = true;
- open();
- resume();
-}
-
-/*!
- \internal
-*/
-QWSTslibMouseHandler::QWSTslibMouseHandler(const QString &driver,
- const QString &device)
- : QWSCalibratedMouseHandler(driver, device)
-{
- d = new QWSTslibMouseHandlerPrivate(this, device);
-}
-
-/*!
- \internal
-*/
-QWSTslibMouseHandler::~QWSTslibMouseHandler()
-{
- delete d;
-}
-
-/*!
- \reimp
-*/
-void QWSTslibMouseHandler::suspend()
-{
- d->suspend();
-}
-
-/*!
- \reimp
-*/
-void QWSTslibMouseHandler::resume()
-{
- d->resume();
-}
-
-/*!
- \reimp
-*/
-void QWSTslibMouseHandler::clearCalibration()
-{
- d->clearCalibration();
-}
-
-/*!
- \reimp
-*/
-void QWSTslibMouseHandler::calibrate(const QWSPointerCalibrationData *data)
-{
- d->calibrate(data);
-}
-
-QT_END_NAMESPACE
-
-#include "qmousetslib_qws.moc"
-
-#endif //QT_NO_QWS_MOUSE_TSLIB
diff --git a/src/gui/embedded/qmousetslib_qws.h b/src/gui/embedded/qmousetslib_qws.h
deleted file mode 100644
index dc0d07220f..0000000000
--- a/src/gui/embedded/qmousetslib_qws.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QMOUSETSLIB_QWS_H
-#define QMOUSETSLIB_QWS_H
-
-#include <QtGui/qmouse_qws.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#if !defined(QT_NO_QWS_MOUSE_TSLIB) || defined(QT_PLUGIN)
-
-class QWSTslibMouseHandlerPrivate;
-
-class QWSTslibMouseHandler : public QWSCalibratedMouseHandler
-{
-public:
- explicit QWSTslibMouseHandler(const QString &driver = QString(),
- const QString &device = QString());
- ~QWSTslibMouseHandler();
-
- void suspend();
- void resume();
-
- void calibrate(const QWSPointerCalibrationData *data);
- void clearCalibration();
-
-protected:
- friend class QWSTslibMouseHandlerPrivate;
- QWSTslibMouseHandlerPrivate *d;
-};
-
-
-#endif // QT_NO_QWS_MOUSE_TSLIB
-QT_END_NAMESPACE
-QT_END_HEADER
-
-#endif // QMOUSETSLIB_QWS_H
diff --git a/src/gui/embedded/qmousevfb_qws.cpp b/src/gui/embedded/qmousevfb_qws.cpp
deleted file mode 100644
index 64f2a0e630..0000000000
--- a/src/gui/embedded/qmousevfb_qws.cpp
+++ /dev/null
@@ -1,133 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QT_NO_QWS_MOUSE_QVFB
-
-#include <stdlib.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <stdio.h>
-
-#include <qvfbhdr.h>
-#include <qmousevfb_qws.h>
-#include <qwindowsystem_qws.h>
-#include <qsocketnotifier.h>
-#include <qapplication.h>
-#include <qtimer.h>
-#include <private/qcore_unix_p.h> // overrides QT_OPEN
-
-QT_BEGIN_NAMESPACE
-
-QVFbMouseHandler::QVFbMouseHandler(const QString &driver, const QString &device)
- : QObject(), QWSMouseHandler(driver, device)
-{
- QString mouseDev = device;
- if (device.isEmpty())
- mouseDev = QLatin1String("/dev/vmouse");
-
- mouseFD = QT_OPEN(mouseDev.toLatin1().constData(), O_RDWR | O_NDELAY);
- if (mouseFD == -1) {
- perror("QVFbMouseHandler::QVFbMouseHandler");
- qWarning("QVFbMouseHander: Unable to open device %s",
- qPrintable(mouseDev));
- return;
- }
-
- // Clear pending input
- char buf[2];
- while (QT_READ(mouseFD, buf, 1) > 0) { }
-
- mouseIdx = 0;
-
- mouseNotifier = new QSocketNotifier(mouseFD, QSocketNotifier::Read, this);
- connect(mouseNotifier, SIGNAL(activated(int)),this, SLOT(readMouseData()));
-}
-
-QVFbMouseHandler::~QVFbMouseHandler()
-{
- if (mouseFD >= 0)
- QT_CLOSE(mouseFD);
-}
-
-void QVFbMouseHandler::resume()
-{
- mouseNotifier->setEnabled(true);
-}
-
-void QVFbMouseHandler::suspend()
-{
- mouseNotifier->setEnabled(false);
-}
-
-void QVFbMouseHandler::readMouseData()
-{
- int n;
- do {
- n = QT_READ(mouseFD, mouseBuf+mouseIdx, mouseBufSize-mouseIdx);
- if (n > 0)
- mouseIdx += n;
- } while (n > 0);
-
- int idx = 0;
- static const int packetsize = sizeof(QPoint) + 2*sizeof(int);
- while (mouseIdx-idx >= packetsize) {
- uchar *mb = mouseBuf+idx;
- QPoint mousePos = *reinterpret_cast<QPoint *>(mb);
- mb += sizeof(QPoint);
- int bstate = *reinterpret_cast<int *>(mb);
- mb += sizeof(int);
- int wheel = *reinterpret_cast<int *>(mb);
-// limitToScreen(mousePos);
- mouseChanged(mousePos, bstate, wheel);
- idx += packetsize;
- }
-
- int surplus = mouseIdx - idx;
- for (int i = 0; i < surplus; i++)
- mouseBuf[i] = mouseBuf[idx+i];
- mouseIdx = surplus;
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_QWS_MOUSE_QVFB
diff --git a/src/gui/embedded/qmousevfb_qws.h b/src/gui/embedded/qmousevfb_qws.h
deleted file mode 100644
index deea6bc437..0000000000
--- a/src/gui/embedded/qmousevfb_qws.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QMOUSEVFB_QWS_H
-#define QMOUSEVFB_QWS_H
-
-#include <QtGui/qmouse_qws.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_QWS_MOUSE_QVFB
-
-class QSocketNotifier;
-
-class QVFbMouseHandler : public QObject, public QWSMouseHandler {
- Q_OBJECT
-public:
- QVFbMouseHandler(const QString &driver = QString(),
- const QString &device = QString());
- ~QVFbMouseHandler();
-
- void resume();
- void suspend();
-
-private:
- int mouseFD;
- int mouseIdx;
- enum {mouseBufSize = 128};
- uchar mouseBuf[mouseBufSize];
- QSocketNotifier *mouseNotifier;
-
-private Q_SLOTS:
- void readMouseData();
-};
-#endif // QT_NO_QWS_MOUSE_QVFB
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QMOUSEVFB_QWS_H
diff --git a/src/gui/embedded/qscreen_qws.cpp b/src/gui/embedded/qscreen_qws.cpp
deleted file mode 100644
index 2c103574d4..0000000000
--- a/src/gui/embedded/qscreen_qws.cpp
+++ /dev/null
@@ -1,3347 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qplatformdefs.h"
-#include "qscreen_qws.h"
-
-#include "qcolormap.h"
-#include "qscreendriverfactory_qws.h"
-#include "qwindowsystem_qws.h"
-#include "qwidget.h"
-#include "qcolor.h"
-#include "qpixmap.h"
-#include "qvarlengtharray.h"
-#include "qwsdisplay_qws.h"
-#include "qpainter.h"
-#include <private/qdrawhelper_p.h>
-#include <private/qpaintengine_raster_p.h>
-#include <private/qpixmap_raster_p.h>
-#include <private/qwindowsurface_qws_p.h>
-#include <private/qpainter_p.h>
-#include <private/qwidget_p.h>
-#include <private/qgraphicssystem_qws_p.h>
-
-QT_BEGIN_NAMESPACE
-
-// #define QT_USE_MEMCPY_DUFF
-
-#ifndef QT_NO_QWS_CURSOR
-Q_GUI_EXPORT QScreenCursor * qt_screencursor = 0;
-#endif
-Q_GUI_EXPORT QScreen * qt_screen = 0;
-
-ClearCacheFunc QScreen::clearCacheFunc = 0;
-
-#ifndef QT_NO_QWS_CURSOR
-/*!
- \class QScreenCursor
- \ingroup qws
-
- \brief The QScreenCursor class is a base class for screen cursors
- in Qt for Embedded Linux.
-
- Note that this class is non-portable, and that it is only
- available in \l{Qt for Embedded Linux}.
-
- QScreenCursor implements a software cursor, but can be subclassed
- to support hardware cursors as well. When deriving from the
- QScreenCursor class it is important to maintain the cursor's
- image, position, hot spot (the point within the cursor's image
- that will be the position of the associated mouse events) and
- visibility as well as informing whether it is hardware accelerated
- or not.
-
- Note that there may only be one screen cursor at a time. Use the
- static instance() function to retrieve a pointer to the current
- screen cursor. Typically, the cursor is constructed by the QScreen
- class or one of its descendants when it is initializing the
- device; the QScreenCursor class should never be instantiated
- explicitly.
-
- Use the move() function to change the position of the cursor, and
- the set() function to alter its image or its hot spot. In
- addition, you can find out whether the cursor is accelerated or
- not, using the isAccelerated() function, and the boundingRect()
- function returns the cursor's bounding rectangle.
-
- The cursor's appearance can be controlled using the isVisible(),
- hide() and show() functions; alternatively the QWSServer class
- provides some means of controlling the cursor's appearance using
- the QWSServer::isCursorVisible() and QWSServer::setCursorVisible()
- functions.
-
- \sa QScreen, QWSServer
-*/
-
-/*!
- \fn static QScreenCursor* QScreenCursor::instance()
- \since 4.2
-
- Returns a pointer to the application's unique screen cursor.
-*/
-
-/*!
- Constructs a screen cursor
-*/
-QScreenCursor::QScreenCursor()
-{
- pos = QPoint(qt_screen->deviceWidth()/2, qt_screen->deviceHeight()/2);
- size = QSize(0,0);
- enable = true;
- hwaccel = false;
- supportsAlpha = true;
-}
-
-/*!
- Destroys the screen cursor.
-*/
-QScreenCursor::~QScreenCursor()
-{
-}
-
-/*!
- Hides the cursor from the screen.
-
- \sa show()
-*/
-void QScreenCursor::hide()
-{
- if (enable) {
- enable = false;
- if (!hwaccel)
- qt_screen->exposeRegion(boundingRect(), 0);
- }
-}
-
-/*!
- Shows the mouse cursor.
-
- \sa hide()
-*/
-void QScreenCursor::show()
-{
- if (!enable) {
- enable = true;
- if (!hwaccel)
- qt_screen->exposeRegion(boundingRect(), 0);
- }
-}
-
-/*!
- Sets the cursor's image to be the given \a image.
-
- The \a hotx and \a hoty parameters define the cursor's hot spot,
- i.e., the point within the cursor's image that will be the
- position of the associated mouse events.
-
- \sa move()
-*/
-void QScreenCursor::set(const QImage &image, int hotx, int hoty)
-{
- const QRect r = boundingRect();
-
- hotspot = QPoint(hotx, hoty);
- // These are in almost all cases the fastest formats to blend
- QImage::Format f;
- switch (qt_screen->depth()) {
- case 12:
- f = QImage::Format_ARGB4444_Premultiplied;
- break;
- case 15:
- f = QImage::Format_ARGB8555_Premultiplied;
- break;
- case 16:
- f = QImage::Format_ARGB8565_Premultiplied;
- break;
- case 18:
- f = QImage::Format_ARGB6666_Premultiplied;
- break;
- default:
- f = QImage::Format_ARGB32_Premultiplied;
- }
-
- cursor = image.convertToFormat(f);
-
- size = image.size();
-
- if (enable && !hwaccel)
- qt_screen->exposeRegion(r | boundingRect(), 0);
-}
-
-/*!
- Moves the mouse cursor to the given position, i.e., (\a x, \a y).
-
- Note that the given position defines the top-left corner of the
- cursor's image, i.e., not the cursor's hot spot (the position of
- the associated mouse events).
-
- \sa set()
-*/
-void QScreenCursor::move(int x, int y)
-{
- QRegion r = boundingRect();
- pos = QPoint(x,y);
- if (enable && !hwaccel) {
- r |= boundingRect();
- qt_screen->exposeRegion(r, 0);
- }
-}
-
-
-/*!
- \fn void QScreenCursor::initSoftwareCursor ()
-
- Initializes the screen cursor.
-
- This function is typically called from the screen driver when
- initializing the device. Alternatively, the cursor can be set
- directly using the pointer returned by the static instance()
- function.
-
- \sa QScreen::initDevice()
-*/
-void QScreenCursor::initSoftwareCursor()
-{
- qt_screencursor = new QScreenCursor;
-}
-
-
-#endif // QT_NO_QWS_CURSOR
-
-
-/*!
- \fn QRect QScreenCursor::boundingRect () const
-
- Returns the cursor's bounding rectangle.
-*/
-
-/*!
- \internal
- \fn bool QScreenCursor::enabled ()
-*/
-
-/*!
- \fn QImage QScreenCursor::image () const
-
- Returns the cursor's image.
-*/
-
-
-/*!
- \fn bool QScreenCursor::isAccelerated () const
-
- Returns true if the cursor is accelerated; otherwise false.
-*/
-
-/*!
- \fn bool QScreenCursor::isVisible () const
-
- Returns true if the cursor is visible; otherwise false.
-*/
-
-/*!
- \internal
- \fn bool QScreenCursor::supportsAlphaCursor () const
-*/
-
-/*
- \variable QScreenCursor::cursor
-
- \brief the cursor's image.
-
- \sa image()
-*/
-
-/*
- \variable QScreenCursor::size
-
- \brief the cursor's size
-*/
-
-/*
- \variable QScreenCursor::pos
-
- \brief the cursor's position, i.e., the position of the top-left
- corner of the crsor's image
-
- \sa set(), move()
-*/
-
-/*
- \variable QScreenCursor::hotspot
-
- \brief the cursor's hotspot, i.e., the point within the cursor's
- image that will be the position of the associated mouse events.
-
- \sa set(), move()
-*/
-
-/*
- \variable QScreenCursor::enable
-
- \brief whether the cursor is visible or not
-
- \sa isVisible()
-*/
-
-/*
- \variable QScreenCursor::hwaccel
-
- \brief holds whether the cursor is accelerated or not
-
- If the cursor is not accelerated, its image will be included by
- the screen when it composites the window surfaces.
-
- \sa isAccelerated()
-
-*/
-
-/*
- \variable QScreenCursor::supportsAlpha
-*/
-
-/*!
- \internal
- \macro qt_screencursor
- \relates QScreenCursor
-
- A global pointer referring to the unique screen cursor. It is
- equivalent to the pointer returned by the
- QScreenCursor::instance() function.
-*/
-
-
-
-class QScreenPrivate
-{
-public:
- QScreenPrivate(QScreen *parent, QScreen::ClassId id = QScreen::CustomClass);
- ~QScreenPrivate();
-
- inline QImage::Format preferredImageFormat() const;
-
- typedef void (*SolidFillFunc)(QScreen*, const QColor&, const QRegion&);
- typedef void (*BlitFunc)(QScreen*, const QImage&, const QPoint&, const QRegion&);
-
- SolidFillFunc solidFill;
- BlitFunc blit;
-
- QPoint offset;
- QList<QScreen*> subScreens;
- QPixmapDataFactory* pixmapFactory;
- QGraphicsSystem* graphicsSystem;
- QWSGraphicsSystem defaultGraphicsSystem; //###
- QImage::Format pixelFormat;
-#if Q_BYTE_ORDER == Q_BIG_ENDIAN
- bool fb_is_littleEndian;
-#endif
-#ifdef QT_QWS_CLIENTBLIT
- bool supportsBlitInClients;
-#endif
- int classId;
- QScreen *q_ptr;
-};
-
-template <typename T>
-static void solidFill_template(QScreen *screen, const QColor &color,
- const QRegion &region)
-{
- T *dest = reinterpret_cast<T*>(screen->base());
- const T c = qt_colorConvert<T, quint32>(color.rgba(), 0);
- const int stride = screen->linestep();
- const QVector<QRect> rects = region.rects();
-
- for (int i = 0; i < rects.size(); ++i) {
- const QRect r = rects.at(i);
- qt_rectfill(dest, c, r.x(), r.y(), r.width(), r.height(), stride);
- }
-}
-
-#ifdef QT_QWS_DEPTH_GENERIC
-static void solidFill_rgb_32bpp(QScreen *screen, const QColor &color,
- const QRegion &region)
-{
- quint32 *dest = reinterpret_cast<quint32*>(screen->base());
- const quint32 c = qt_convertToRgb<quint32>(color.rgba());
-
- const int stride = screen->linestep();
- const QVector<QRect> rects = region.rects();
-
- for (int i = 0; i < rects.size(); ++i) {
- const QRect r = rects.at(i);
- qt_rectfill(dest, c, r.x(), r.y(), r.width(), r.height(), stride);
- }
-}
-
-static void solidFill_rgb_16bpp(QScreen *screen, const QColor &color,
- const QRegion &region)
-{
- quint16 *dest = reinterpret_cast<quint16*>(screen->base());
- const quint16 c = qt_convertToRgb<quint32>(color.rgba());
-
- const int stride = screen->linestep();
- const QVector<QRect> rects = region.rects();
-
- for (int i = 0; i < rects.size(); ++i) {
- const QRect r = rects.at(i);
- qt_rectfill(dest, c, r.x(), r.y(), r.width(), r.height(), stride);
- }
-}
-#endif // QT_QWS_DEPTH_GENERIC
-
-#ifdef QT_QWS_DEPTH_4
-static inline void qt_rectfill_gray4(quint8 *dest, quint8 value,
- int x, int y, int width, int height,
- int stride)
-{
- const int pixelsPerByte = 2;
- dest += y * stride + x / pixelsPerByte;
- const int doAlign = x & 1;
- const int doTail = (width - doAlign) & 1;
- const int width8 = (width - doAlign) / pixelsPerByte;
-
- for (int j = 0; j < height; ++j) {
- if (doAlign)
- *dest = (*dest & 0xf0) | (value & 0x0f);
- if (width8)
- qt_memfill<quint8>(dest + doAlign, value, width8);
- if (doTail) {
- quint8 *d = dest + doAlign + width8;
- *d = (*d & 0x0f) | (value & 0xf0);
- }
- dest += stride;
- }
-}
-
-static void solidFill_gray4(QScreen *screen, const QColor &color,
- const QRegion &region)
-{
- quint8 *dest = reinterpret_cast<quint8*>(screen->base());
- const quint8 c = qGray(color.rgba()) >> 4;
- const quint8 c8 = (c << 4) | c;
-
- const int stride = screen->linestep();
- const QVector<QRect> rects = region.rects();
-
- for (int i = 0; i < rects.size(); ++i) {
- const QRect r = rects.at(i);
- qt_rectfill_gray4(dest, c8, r.x(), r.y(), r.width(), r.height(),
- stride);
- }
-}
-#endif // QT_QWS_DEPTH_4
-
-#ifdef QT_QWS_DEPTH_1
-static inline void qt_rectfill_mono(quint8 *dest, quint8 value,
- int x, int y, int width, int height,
- int stride)
-{
- const int pixelsPerByte = 8;
- const int alignWidth = qMin(width, (8 - (x & 7)) & 7);
- const int doAlign = (alignWidth > 0 ? 1 : 0);
- const int alignStart = pixelsPerByte - 1 - (x & 7);
- const int alignStop = alignStart - (alignWidth - 1);
- const quint8 alignMask = ((1 << alignWidth) - 1) << alignStop;
- const int tailWidth = (width - alignWidth) & 7;
- const int doTail = (tailWidth > 0 ? 1 : 0);
- const quint8 tailMask = (1 << (pixelsPerByte - tailWidth)) - 1;
- const int width8 = (width - alignWidth) / pixelsPerByte;
-
- dest += y * stride + x / pixelsPerByte;
- stride -= (doAlign + width8);
-
- for (int j = 0; j < height; ++j) {
- if (doAlign) {
- *dest = (*dest & ~alignMask) | (value & alignMask);
- ++dest;
- }
- if (width8) {
- qt_memfill<quint8>(dest, value, width8);
- dest += width8;
- }
- if (doTail)
- *dest = (*dest & tailMask) | (value & ~tailMask);
- dest += stride;
- }
-}
-
-static void solidFill_mono(QScreen *screen, const QColor &color,
- const QRegion &region)
-{
- quint8 *dest = reinterpret_cast<quint8*>(screen->base());
- const quint8 c8 = (qGray(color.rgba()) >> 7) * 0xff;
-
- const int stride = screen->linestep();
- const QVector<QRect> rects = region.rects();
-
- for (int i = 0; i < rects.size(); ++i) {
- const QRect r = rects.at(i);
- qt_rectfill_mono(dest, c8, r.x(), r.y(), r.width(), r.height(),
- stride);
- }
-}
-#endif // QT_QWS_DEPTH_1
-
-void qt_solidFill_setup(QScreen *screen, const QColor &color,
- const QRegion &region)
-{
- switch (screen->depth()) {
-#ifdef QT_QWS_DEPTH_32
- case 32:
- if (screen->pixelType() == QScreen::NormalPixel)
- screen->d_ptr->solidFill = solidFill_template<quint32>;
- else
- screen->d_ptr->solidFill = solidFill_template<qabgr8888>;
- break;
-#endif
-#ifdef QT_QWS_DEPTH_24
- case 24:
- if (screen->pixelType() == QScreen::NormalPixel)
- screen->d_ptr->solidFill = solidFill_template<qrgb888>;
- else
- screen->d_ptr->solidFill = solidFill_template<quint24>;
- break;
-#endif
-#ifdef QT_QWS_DEPTH_18
- case 18:
- screen->d_ptr->solidFill = solidFill_template<quint18>;
- break;
-#endif
-#ifdef QT_QWS_DEPTH_16
- case 16:
- if (screen->pixelType() == QScreen::NormalPixel)
- screen->d_ptr->solidFill = solidFill_template<quint16>;
- else
- screen->d_ptr->solidFill = solidFill_template<qbgr565>;
- break;
-#endif
-#ifdef QT_QWS_DEPTH_15
- case 15:
- if (screen->pixelType() == QScreen::NormalPixel)
- screen->d_ptr->solidFill = solidFill_template<qrgb555>;
- else
- screen->d_ptr->solidFill = solidFill_template<qbgr555>;
- break;
-#endif
-#ifdef QT_QWS_DEPTH_12
- case 12:
- screen->d_ptr->solidFill = solidFill_template<qrgb444>;
- break;
-#endif
-#ifdef QT_QWS_DEPTH_8
- case 8:
- screen->d_ptr->solidFill = solidFill_template<quint8>;
- break;
-#endif
-#ifdef QT_QWS_DEPTH_4
- case 4:
- screen->d_ptr->solidFill = solidFill_gray4;
- break;
-#endif
-#ifdef QT_QWS_DEPTH_1
- case 1:
- screen->d_ptr->solidFill = solidFill_mono;
- break;
-#endif
- default:
- qFatal("solidFill_setup(): Screen depth %d not supported!",
- screen->depth());
- screen->d_ptr->solidFill = 0;
- break;
- }
- screen->d_ptr->solidFill(screen, color, region);
-}
-
-template <typename DST, typename SRC>
-static void blit_template(QScreen *screen, const QImage &image,
- const QPoint &topLeft, const QRegion &region)
-{
- DST *dest = reinterpret_cast<DST*>(screen->base());
- const int screenStride = screen->linestep();
- const int imageStride = image.bytesPerLine();
-
- if (region.rectCount() == 1) {
- const QRect r = region.boundingRect();
- const SRC *src = reinterpret_cast<const SRC*>(image.scanLine(r.y()))
- + r.x();
- qt_rectconvert<DST, SRC>(dest, src,
- r.x() + topLeft.x(), r.y() + topLeft.y(),
- r.width(), r.height(),
- screenStride, imageStride);
- } else {
- const QVector<QRect> rects = region.rects();
-
- for (int i = 0; i < rects.size(); ++i) {
- const QRect r = rects.at(i);
- const SRC *src = reinterpret_cast<const SRC*>(image.scanLine(r.y()))
- + r.x();
- qt_rectconvert<DST, SRC>(dest, src,
- r.x() + topLeft.x(), r.y() + topLeft.y(),
- r.width(), r.height(),
- screenStride, imageStride);
- }
- }
-}
-
-#ifdef QT_QWS_DEPTH_32
-static void blit_32(QScreen *screen, const QImage &image,
- const QPoint &topLeft, const QRegion &region)
-{
- switch (image.format()) {
- case QImage::Format_RGB32:
- case QImage::Format_ARGB32:
- case QImage::Format_ARGB32_Premultiplied:
- blit_template<quint32, quint32>(screen, image, topLeft, region);
- return;
-#ifdef QT_QWS_DEPTH_16
- case QImage::Format_RGB16:
- blit_template<quint32, quint16>(screen, image, topLeft, region);
- return;
-#endif
- default:
- qCritical("blit_32(): Image format %d not supported!", image.format());
- }
-}
-#endif // QT_QWS_DEPTH_32
-
-#ifdef QT_QWS_DEPTH_24
-static void blit_24(QScreen *screen, const QImage &image,
- const QPoint &topLeft, const QRegion &region)
-{
- switch (image.format()) {
- case QImage::Format_RGB32:
- case QImage::Format_ARGB32:
- case QImage::Format_ARGB32_Premultiplied:
- blit_template<quint24, quint32>(screen, image, topLeft, region);
- return;
- case QImage::Format_RGB888:
- blit_template<quint24, qrgb888>(screen, image, topLeft, region);
- return;
-#ifdef QT_QWS_DEPTH_16
- case QImage::Format_RGB16:
- blit_template<quint24, quint16>(screen, image, topLeft, region);
- return;
-#endif
- default:
- qCritical("blit_24(): Image format %d not supported!", image.format());
- }
-}
-
-static void blit_qrgb888(QScreen *screen, const QImage &image,
- const QPoint &topLeft, const QRegion &region)
-{
- switch (image.format()) {
- case QImage::Format_RGB32:
- case QImage::Format_ARGB32:
- case QImage::Format_ARGB32_Premultiplied:
- blit_template<qrgb888, quint32>(screen, image, topLeft, region);
- return;
- case QImage::Format_RGB888:
- blit_template<qrgb888, qrgb888>(screen, image, topLeft, region);
- return;
-#ifdef QT_QWS_DEPTH_16
- case QImage::Format_RGB16:
- blit_template<qrgb888, quint16>(screen, image, topLeft, region);
- return;
-#endif
- default:
- qCritical("blit_24(): Image format %d not supported!", image.format());
- break;
- }
-}
-#endif // QT_QWS_DEPTH_24
-
-#ifdef QT_QWS_DEPTH_18
-static void blit_18(QScreen *screen, const QImage &image,
- const QPoint &topLeft, const QRegion &region)
-{
- switch (image.format()) {
- case QImage::Format_RGB32:
- case QImage::Format_ARGB32:
- case QImage::Format_ARGB32_Premultiplied:
- blit_template<qrgb666, quint32>(screen, image, topLeft, region);
- return;
- case QImage::Format_RGB666:
- blit_template<qrgb666, qrgb666>(screen, image, topLeft, region);
- return;
-#ifdef QT_QWS_DEPTH_16
- case QImage::Format_RGB16:
- blit_template<qrgb666, quint16>(screen, image, topLeft, region);
- return;
-#endif
- default:
- qCritical("blit_18(): Image format %d not supported!", image.format());
- }
-}
-#endif // QT_QWS_DEPTH_18
-
-#if (Q_BYTE_ORDER == Q_BIG_ENDIAN) && (defined(QT_QWS_DEPTH_16) || defined(QT_QWS_DEPTH_15))
-class quint16LE
-{
-public:
- inline quint16LE(quint32 v) {
- data = ((v & 0xff00) >> 8) | ((v & 0x00ff) << 8);
- }
-
- inline quint16LE(int v) {
- data = ((v & 0xff00) >> 8) | ((v & 0x00ff) << 8);
- }
-
- inline quint16LE(quint16 v) {
- data = ((v & 0xff00) >> 8) | ((v & 0x00ff) << 8);
- }
-
- inline quint16LE(qrgb555 v) {
- data = (( (quint16)v & 0xff00) >> 8) |
- (( (quint16)v & 0x00ff) << 8);
- }
-
- inline bool operator==(const quint16LE &v) const
- {
- return data == v.data;
- }
-
-private:
- quint16 data;
-};
-#endif
-
-#ifdef QT_QWS_DEPTH_16
-static void blit_16(QScreen *screen, const QImage &image,
- const QPoint &topLeft, const QRegion &region)
-{
- switch (image.format()) {
- case QImage::Format_RGB32:
- case QImage::Format_ARGB32:
- case QImage::Format_ARGB32_Premultiplied:
- // ### This probably doesn't work but it's a case which should never happen
- blit_template<quint16, quint32>(screen, image, topLeft, region);
- return;
- case QImage::Format_RGB16:
- blit_template<quint16, quint16>(screen, image, topLeft, region);
- return;
- default:
- qCritical("blit_16(): Image format %d not supported!", image.format());
- }
-}
-
-#if Q_BYTE_ORDER == Q_BIG_ENDIAN
-static void blit_16_bigToLittleEndian(QScreen *screen, const QImage &image,
- const QPoint &topLeft,
- const QRegion &region)
-{
- switch (image.format()) {
- case QImage::Format_RGB32:
- case QImage::Format_ARGB32:
- case QImage::Format_ARGB32_Premultiplied:
- blit_template<quint16LE, quint32>(screen, image, topLeft, region);
- return;
- case QImage::Format_RGB16:
- blit_template<quint16LE, quint16>(screen, image, topLeft, region);
- return;
- default:
- qCritical("blit_16_bigToLittleEndian(): Image format %d not supported!", image.format());
- }
-}
-
-#endif // Q_BIG_ENDIAN
-#endif // QT_QWS_DEPTH_16
-
-#ifdef QT_QWS_DEPTH_15
-static void blit_15(QScreen *screen, const QImage &image,
- const QPoint &topLeft, const QRegion &region)
-{
- switch (image.format()) {
- case QImage::Format_RGB32:
- case QImage::Format_ARGB32:
- case QImage::Format_ARGB32_Premultiplied:
- blit_template<qrgb555, quint32>(screen, image, topLeft, region);
- return;
- case QImage::Format_RGB555:
- blit_template<qrgb555, qrgb555>(screen, image, topLeft, region);
- return;
- case QImage::Format_RGB16:
- blit_template<qrgb555, quint16>(screen, image, topLeft, region);
- return;
- default:
- qCritical("blit_15(): Image format %d not supported!", image.format());
- }
-}
-
-#if Q_BYTE_ORDER == Q_BIG_ENDIAN
-static void blit_15_bigToLittleEndian(QScreen *screen, const QImage &image,
- const QPoint &topLeft,
- const QRegion &region)
-{
- switch (image.format()) {
- case QImage::Format_RGB555:
- blit_template<quint16LE, qrgb555>(screen, image, topLeft, region);
- return;
- default:
- qCritical("blit_15_bigToLittleEndian(): Image format %d not supported!", image.format());
- }
-}
-#endif // Q_BIG_ENDIAN
-#endif // QT_QWS_DEPTH_15
-
-
-#ifdef QT_QWS_DEPTH_12
-static void blit_12(QScreen *screen, const QImage &image,
- const QPoint &topLeft, const QRegion &region)
-{
- switch (image.format()) {
- case QImage::Format_ARGB4444_Premultiplied:
- blit_template<qrgb444, qargb4444>(screen, image, topLeft, region);
- return;
- case QImage::Format_RGB444:
- blit_template<qrgb444, qrgb444>(screen, image, topLeft, region);
- return;
- default:
- qCritical("blit_12(): Image format %d not supported!", image.format());
- }
-}
-#endif // QT_QWS_DEPTH_12
-
-#ifdef QT_QWS_DEPTH_8
-static void blit_8(QScreen *screen, const QImage &image,
- const QPoint &topLeft, const QRegion &region)
-{
- switch (image.format()) {
- case QImage::Format_RGB32:
- case QImage::Format_ARGB32:
- case QImage::Format_ARGB32_Premultiplied:
- blit_template<quint8, quint32>(screen, image, topLeft, region);
- return;
- case QImage::Format_RGB16:
- blit_template<quint8, quint16>(screen, image, topLeft, region);
- return;
- case QImage::Format_ARGB4444_Premultiplied:
- blit_template<quint8, qargb4444>(screen, image, topLeft, region);
- return;
- case QImage::Format_RGB444:
- blit_template<quint8, qrgb444>(screen, image, topLeft, region);
- return;
- default:
- qCritical("blit_8(): Image format %d not supported!", image.format());
- }
-}
-#endif // QT_QWS_DEPTH_8
-
-#ifdef QT_QWS_DEPTH_4
-
-struct qgray4 { quint8 dummy; } Q_PACKED;
-
-template <typename SRC>
-Q_STATIC_TEMPLATE_FUNCTION inline quint8 qt_convertToGray4(SRC color);
-
-template <>
-inline quint8 qt_convertToGray4(quint32 color)
-{
- return qGray(color) >> 4;
-}
-
-template <>
-inline quint8 qt_convertToGray4(quint16 color)
-{
- const int r = (color & 0xf800) >> 11;
- const int g = (color & 0x07e0) >> 6; // only keep 5 bit
- const int b = (color & 0x001f);
- return (r * 11 + g * 16 + b * 5) >> 6;
-}
-
-template <>
-inline quint8 qt_convertToGray4(qrgb444 color)
-{
- return qt_convertToGray4(quint32(color));
-}
-
-template <>
-inline quint8 qt_convertToGray4(qargb4444 color)
-{
- return qt_convertToGray4(quint32(color));
-}
-
-template <typename SRC>
-Q_STATIC_TEMPLATE_FUNCTION inline void qt_rectconvert_gray4(qgray4 *dest4, const SRC *src,
- int x, int y, int width, int height,
- int dstStride, int srcStride)
-{
- const int pixelsPerByte = 2;
- quint8 *dest8 = reinterpret_cast<quint8*>(dest4)
- + y * dstStride + x / pixelsPerByte;
- const int doAlign = x & 1;
- const int doTail = (width - doAlign) & 1;
- const int width8 = (width - doAlign) / pixelsPerByte;
- const int count8 = (width8 + 3) / 4;
-
- srcStride = srcStride / sizeof(SRC) - width;
- dstStride -= (width8 + doAlign);
-
- for (int i = 0; i < height; ++i) {
- if (doAlign) {
- *dest8 = (*dest8 & 0xf0) | qt_convertToGray4<SRC>(*src++);
- ++dest8;
- }
- if (count8) {
- int n = count8;
- switch (width8 & 0x03) // duff's device
- {
- case 0: do { *dest8++ = qt_convertToGray4<SRC>(src[0]) << 4
- | qt_convertToGray4<SRC>(src[1]);
- src += 2;
- case 3: *dest8++ = qt_convertToGray4<SRC>(src[0]) << 4
- | qt_convertToGray4<SRC>(src[1]);
- src += 2;
- case 2: *dest8++ = qt_convertToGray4<SRC>(src[0]) << 4
- | qt_convertToGray4<SRC>(src[1]);
- src += 2;
- case 1: *dest8++ = qt_convertToGray4<SRC>(src[0]) << 4
- | qt_convertToGray4<SRC>(src[1]);
- src += 2;
- } while (--n > 0);
- }
- }
-
- if (doTail)
- *dest8 = qt_convertToGray4<SRC>(*src++) << 4 | (*dest8 & 0x0f);
-
- dest8 += dstStride;
- src += srcStride;
- }
-}
-
-template <>
-void qt_rectconvert(qgray4 *dest, const quint32 *src,
- int x, int y, int width, int height,
- int dstStride, int srcStride)
-{
- qt_rectconvert_gray4<quint32>(dest, src, x, y, width, height,
- dstStride, srcStride);
-}
-
-template <>
-void qt_rectconvert(qgray4 *dest, const quint16 *src,
- int x, int y, int width, int height,
- int dstStride, int srcStride)
-{
- qt_rectconvert_gray4<quint16>(dest, src, x, y, width, height,
- dstStride, srcStride);
-}
-
-template <>
-void qt_rectconvert(qgray4 *dest, const qrgb444 *src,
- int x, int y, int width, int height,
- int dstStride, int srcStride)
-{
- qt_rectconvert_gray4<qrgb444>(dest, src, x, y, width, height,
- dstStride, srcStride);
-}
-
-template <>
-void qt_rectconvert(qgray4 *dest, const qargb4444 *src,
- int x, int y, int width, int height,
- int dstStride, int srcStride)
-{
- qt_rectconvert_gray4<qargb4444>(dest, src, x, y, width, height,
- dstStride, srcStride);
-}
-
-static void blit_4(QScreen *screen, const QImage &image,
- const QPoint &topLeft, const QRegion &region)
-{
- switch (image.format()) {
- case QImage::Format_ARGB32_Premultiplied:
- blit_template<qgray4, quint32>(screen, image, topLeft, region);
- return;
- case QImage::Format_RGB16:
- blit_template<qgray4, quint16>(screen, image, topLeft, region);
- return;
- case QImage::Format_RGB444:
- blit_template<qgray4, qrgb444>(screen, image, topLeft, region);
- return;
- case QImage::Format_ARGB4444_Premultiplied:
- blit_template<qgray4, qargb4444>(screen, image, topLeft, region);
- return;
- default:
- qCritical("blit_4(): Image format %d not supported!", image.format());
- }
-}
-#endif // QT_QWS_DEPTH_4
-
-#ifdef QT_QWS_DEPTH_1
-
-struct qmono { quint8 dummy; } Q_PACKED;
-
-template <typename SRC>
-Q_STATIC_TEMPLATE_FUNCTION inline quint8 qt_convertToMono(SRC color);
-
-template <>
-inline quint8 qt_convertToMono(quint32 color)
-{
- return qGray(color) >> 7;
-}
-
-template <>
-inline quint8 qt_convertToMono(quint16 color)
-{
- return (qGray(qt_colorConvert<quint32, quint16>(color, 0)) >> 7);
-}
-
-template <>
-inline quint8 qt_convertToMono(qargb4444 color)
-{
- return (qGray(quint32(color)) >> 7);
-}
-
-template <>
-inline quint8 qt_convertToMono(qrgb444 color)
-{
- return (qGray(quint32(color)) >> 7);
-}
-
-template <typename SRC>
-inline void qt_rectconvert_mono(qmono *dest, const SRC *src,
- int x, int y, int width, int height,
- int dstStride, int srcStride)
-{
- const int pixelsPerByte = 8;
- quint8 *dest8 = reinterpret_cast<quint8*>(dest)
- + y * dstStride + x / pixelsPerByte;
- const int alignWidth = qMin(width, (8 - (x & 7)) & 7);
- const int doAlign = (alignWidth > 0 ? 1 : 0);
- const int alignStart = pixelsPerByte - 1 - (x & 7);
- const int alignStop = alignStart - (alignWidth - 1);
- const quint8 alignMask = ((1 << alignWidth) - 1) << alignStop;
- const int tailWidth = (width - alignWidth) & 7;
- const int doTail = (tailWidth > 0 ? 1 : 0);
- const quint8 tailMask = (1 << (pixelsPerByte - tailWidth)) - 1;
- const int width8 = (width - alignWidth) / pixelsPerByte;
-
- srcStride = srcStride / sizeof(SRC) - (width8 * 8 + alignWidth);
- dstStride -= (width8 + doAlign);
-
- for (int j = 0; j < height; ++j) {
- if (doAlign) {
- quint8 d = *dest8 & ~alignMask;
- for (int i = alignStart; i >= alignStop; --i)
- d |= qt_convertToMono<SRC>(*src++) << i;
- *dest8++ = d;
- }
- for (int i = 0; i < width8; ++i) {
- *dest8 = (qt_convertToMono<SRC>(src[0]) << 7)
- | (qt_convertToMono<SRC>(src[1]) << 6)
- | (qt_convertToMono<SRC>(src[2]) << 5)
- | (qt_convertToMono<SRC>(src[3]) << 4)
- | (qt_convertToMono<SRC>(src[4]) << 3)
- | (qt_convertToMono<SRC>(src[5]) << 2)
- | (qt_convertToMono<SRC>(src[6]) << 1)
- | (qt_convertToMono<SRC>(src[7]));
- src += 8;
- ++dest8;
- }
- if (doTail) {
- quint8 d = *dest8 & tailMask;
- switch (tailWidth) {
- case 7: d |= qt_convertToMono<SRC>(src[6]) << 1;
- case 6: d |= qt_convertToMono<SRC>(src[5]) << 2;
- case 5: d |= qt_convertToMono<SRC>(src[4]) << 3;
- case 4: d |= qt_convertToMono<SRC>(src[3]) << 4;
- case 3: d |= qt_convertToMono<SRC>(src[2]) << 5;
- case 2: d |= qt_convertToMono<SRC>(src[1]) << 6;
- case 1: d |= qt_convertToMono<SRC>(src[0]) << 7;
- }
- *dest8 = d;
- }
-
- dest8 += dstStride;
- src += srcStride;
- }
-}
-
-template <>
-void qt_rectconvert(qmono *dest, const quint32 *src,
- int x, int y, int width, int height,
- int dstStride, int srcStride)
-{
- qt_rectconvert_mono<quint32>(dest, src, x, y, width, height,
- dstStride, srcStride);
-}
-
-template <>
-void qt_rectconvert(qmono *dest, const quint16 *src,
- int x, int y, int width, int height,
- int dstStride, int srcStride)
-{
- qt_rectconvert_mono<quint16>(dest, src, x, y, width, height,
- dstStride, srcStride);
-}
-
-template <>
-void qt_rectconvert(qmono *dest, const qrgb444 *src,
- int x, int y, int width, int height,
- int dstStride, int srcStride)
-{
- qt_rectconvert_mono<qrgb444>(dest, src, x, y, width, height,
- dstStride, srcStride);
-}
-
-template <>
-void qt_rectconvert(qmono *dest, const qargb4444 *src,
- int x, int y, int width, int height,
- int dstStride, int srcStride)
-{
- qt_rectconvert_mono<qargb4444>(dest, src, x, y, width, height,
- dstStride, srcStride);
-}
-
-static void blit_1(QScreen *screen, const QImage &image,
- const QPoint &topLeft, const QRegion &region)
-{
- switch (image.format()) {
- case QImage::Format_ARGB32_Premultiplied:
- blit_template<qmono, quint32>(screen, image, topLeft, region);
- return;
- case QImage::Format_RGB16:
- blit_template<qmono, quint16>(screen, image, topLeft, region);
- return;
- case QImage::Format_RGB444:
- blit_template<qmono, qrgb444>(screen, image, topLeft, region);
- return;
- case QImage::Format_ARGB4444_Premultiplied:
- blit_template<qmono, qargb4444>(screen, image, topLeft, region);
- return;
- default:
- qCritical("blit_1(): Image format %d not supported!", image.format());
- }
-}
-#endif // QT_QWS_DEPTH_1
-
-#ifdef QT_QWS_DEPTH_GENERIC
-
-static void blit_rgb(QScreen *screen, const QImage &image,
- const QPoint &topLeft, const QRegion &region)
-{
- switch (image.format()) {
- case QImage::Format_ARGB32_Premultiplied:
- blit_template<qrgb, quint32>(screen, image, topLeft, region);
- return;
- case QImage::Format_RGB16:
- blit_template<qrgb, quint16>(screen, image, topLeft, region);
- return;
- default:
- qCritical("blit_rgb(): Image format %d not supported!", image.format());
- }
-}
-
-void qt_set_generic_blit(QScreen *screen, int bpp,
- int len_red, int len_green, int len_blue, int len_alpha,
- int off_red, int off_green, int off_blue, int off_alpha)
-{
- qrgb::bpp = bpp / 8;
- qrgb::len_red = len_red;
- qrgb::len_green = len_green;
- qrgb::len_blue = len_blue;
- qrgb::len_alpha = len_alpha;
- qrgb::off_red = off_red;
- qrgb::off_green = off_green;
- qrgb::off_blue = off_blue;
- qrgb::off_alpha = off_alpha;
- screen->d_ptr->blit = blit_rgb;
- if (bpp == 16)
- screen->d_ptr->solidFill = solidFill_rgb_16bpp;
- else if (bpp == 32)
- screen->d_ptr->solidFill = solidFill_rgb_32bpp;
-}
-
-#endif // QT_QWS_DEPTH_GENERIC
-
-void qt_blit_setup(QScreen *screen, const QImage &image,
- const QPoint &topLeft, const QRegion &region)
-{
- switch (screen->depth()) {
-#ifdef QT_QWS_DEPTH_32
- case 32:
- if (screen->pixelType() == QScreen::NormalPixel)
- screen->d_ptr->blit = blit_32;
- else
- screen->d_ptr->blit = blit_template<qabgr8888, quint32>;
- break;
-#endif
-#ifdef QT_QWS_DEPTH_24
- case 24:
- if (screen->pixelType() == QScreen::NormalPixel)
- screen->d_ptr->blit = blit_qrgb888;
- else
- screen->d_ptr->blit = blit_24;
- break;
-#endif
-#ifdef QT_QWS_DEPTH_18
- case 18:
- screen->d_ptr->blit = blit_18;
- break;
-#endif
-#ifdef QT_QWS_DEPTH_16
- case 16:
-#if Q_BYTE_ORDER == Q_BIG_ENDIAN
- if (screen->d_ptr->fb_is_littleEndian)
- screen->d_ptr->blit = blit_16_bigToLittleEndian;
- else
-#endif
- if (screen->pixelType() == QScreen::NormalPixel)
- screen->d_ptr->blit = blit_16;
- else
- screen->d_ptr->blit = blit_template<qbgr565, quint16>;
- break;
-#endif
-#ifdef QT_QWS_DEPTH_15
- case 15:
-#if Q_BYTE_ORDER == Q_BIG_ENDIAN
- if (screen->d_ptr->fb_is_littleEndian)
- screen->d_ptr->blit = blit_15_bigToLittleEndian;
- else
-#endif // Q_BIG_ENDIAN
- if (screen->pixelType() == QScreen::NormalPixel)
- screen->d_ptr->blit = blit_15;
- else
- screen->d_ptr->blit = blit_template<qbgr555, qrgb555>;
- break;
-#endif
-#ifdef QT_QWS_DEPTH_12
- case 12:
- screen->d_ptr->blit = blit_12;
- break;
-#endif
-#ifdef QT_QWS_DEPTH_8
- case 8:
- screen->d_ptr->blit = blit_8;
- break;
-#endif
-#ifdef QT_QWS_DEPTH_4
- case 4:
- screen->d_ptr->blit = blit_4;
- break;
-#endif
-#ifdef QT_QWS_DEPTH_1
- case 1:
- screen->d_ptr->blit = blit_1;
- break;
-#endif
- default:
- qFatal("blit_setup(): Screen depth %d not supported!",
- screen->depth());
- screen->d_ptr->blit = 0;
- break;
- }
- screen->d_ptr->blit(screen, image, topLeft, region);
-}
-
-QScreenPrivate::QScreenPrivate(QScreen *parent, QScreen::ClassId id)
- : defaultGraphicsSystem(QWSGraphicsSystem(parent)),
- pixelFormat(QImage::Format_Invalid),
-#ifdef QT_QWS_CLIENTBLIT
- supportsBlitInClients(false),
-#endif
- classId(id), q_ptr(parent)
-{
- solidFill = qt_solidFill_setup;
- blit = qt_blit_setup;
-#if Q_BYTE_ORDER == Q_BIG_ENDIAN
- fb_is_littleEndian = false;
-#endif
- pixmapFactory = 0;
- graphicsSystem = &defaultGraphicsSystem;
-}
-
-QScreenPrivate::~QScreenPrivate()
-{
-}
-
-QImage::Format QScreenPrivate::preferredImageFormat() const
-{
- if (pixelFormat > QImage::Format_Indexed8)
- return pixelFormat;
-
- if (q_ptr->depth() <= 16)
- return QImage::Format_RGB16;
- else
- return QImage::Format_ARGB32_Premultiplied;
-}
-
-/*!
- \class QScreen
- \ingroup qws
-
- \brief The QScreen class is a base class for screen drivers in
- Qt for Embedded Linux.
-
- Note that this class is only available in \l{Qt for Embedded Linux}.
-
- \l{Qt for Embedded Linux} provides ready-made drivers for several screen
- protocols, see the \l{Qt for Embedded Linux Display Management}{display
- management} documentation for details. Custom screen drivers can
- be implemented by subclassing the QScreen class and creating a
- screen driver plugin (derived from QScreenDriverPlugin). The
- default implementation of the QScreenDriverFactory class
- will automatically detect the plugin, and load the driver into the
- server application at run-time using Qt's \l {How to Create Qt
- Plugins}{plugin system}.
-
- When rendering, the default behavior is for each
- client to render its widgets as well as its decorations into
- memory, while the server copies the memory content to the device's
- framebuffer using the screen driver. See the \l{Qt for Embedded Linux
- Architecture} overview for details (note that it is possible for
- the clients to manipulate and control the underlying hardware
- directly as well).
-
- Starting with Qt 4.2, it is also possible to add an
- accelerated graphics driver to take advantage of available
- hardware resources. See the \l{Adding an Accelerated Graphics
- Driver to Qt for Embedded Linux} documentation for details.
-
- \tableofcontents
-
- \section1 Framebuffer Management
-
- When a \l{Qt for Embedded Linux} application starts running, it
- calls the screen driver's connect() function to map the
- framebuffer and the accelerated drivers that the graphics card
- control registers. The connect() function should then read out the
- parameters of the framebuffer and use them as required to set this
- class's protected variables.
-
- The initDevice() function can be reimplemented to initialize the
- graphics card. Note, however, that connect() is called \e before
- the initDevice() function, so, for some hardware configurations,
- some of the initialization that would normally be done in the
- initDevice() function might have to be done in the connect()
- function.
-
- Likewise, just before a \l{Qt for Embedded Linux} application
- exits, it calls the screen driver's disconnect() function. The
- server application will in addition call the shutdownDevice()
- function before it calls disconnect(). Note that the default
- implementation of the shutdownDevice() function only hides the
- mouse cursor.
-
- QScreen also provides the save() and restore() functions, making
- it possible to save and restore the state of the graphics
- card. Note that the default implementations do nothing. Hardware
- screen drivers should reimplement these functions to save (and
- restore) its registers, enabling switching between virtual
- consoles.
-
- In addition, you can use the base() function to retrieve a pointer
- to the beginning of the framebuffer, and the region() function to
- retrieve the framebuffer's region. Use the onCard() function to
- determine whether the framebuffer is within the graphics card's
- memory, and the totalSize() function to determine the size of the
- available graphics card memory (including the screen). Finally,
- you can use the offset() function to retrieve the offset between
- the framebuffer's coordinates and the application's coordinate
- system.
-
- \section1 Palette Management
-
- QScreen provides several functions to retrieve information about
- the color palette: The clut() function returns a pointer to the
- color lookup table (i.e. its color palette). Use the colorCount()
- function to determine the number of entries in this table, and the
- alloc() function to retrieve the palette index of the color that
- is the closest match to a given RGB value.
-
- To determine if the screen driver supports a given color depth,
- use the supportsDepth() function that returns true of the
- specified depth is supported.
-
- \section1 Drawing on Screen
-
- When a screen update is required, the \l{Qt for Embedded Linux} server runs
- through all the top-level windows that intersect with the region
- that is about to be updated, and ensures that the associated
- clients have updated their memory buffer. Then the server calls
- the exposeRegion() function that composes the window surfaces and
- copies the content of memory to screen by calling the blit() and
- solidFill() functions.
-
- The blit() function copies a given region in a given image to a
- specified point using device coordinates, while the solidFill()
- function fills the given region of the screen with the specified
- color. Note that normally there is no need to call either of these
- functions explicitly.
-
- In addition, QScreen provides the blank() function that can be
- reimplemented to prevent any contents from being displayed on the
- screen, and the setDirty() function that can be reimplemented to
- indicate that a given rectangle of the screen has been
- altered. Note that the default implementations of these functions
- do nothing.
-
- Reimplement the mapFromDevice() and mapToDevice() functions to
- map objects from the framebuffer coordinate system to the
- coordinate space used by the application, and vice versa. Be aware
- that the default implementations simply return the given objects
- as they are.
-
- \section1 Properties
-
- \table
- \header \o Property \o Functions
- \row
- \o Size
- \o
-
- The size of the screen can be retrieved using the screenSize()
- function. The size is returned in bytes.
-
- The framebuffer's logical width and height can be retrieved using
- width() and height(), respectively. These functions return values
- are given in pixels. Alternatively, the physicalWidth() and
- physicalHeight() function returns the same metrics in
- millimeters. QScreen also provides the deviceWidth() and
- deviceHeight() functions returning the physical width and height
- of the device in pixels. Note that the latter metrics can differ
- from the ones used if the display is centered within the
- framebuffer.
-
- \row
- \o Resolution
- \o
-
- Reimplement the setMode() function to be able to set the
- framebuffer to a new resolution (width and height) and bit depth.
-
- The current depth of the framebuffer can be always be retrieved
- using the depth() function. Use the pixmapDepth() function to
- obtain the preferred depth for pixmaps.
-
- \row
- \o Pixmap Alignment
- \o
-
- Use the pixmapOffsetAlignment() function to retrieve the value to
- which the start address of pixmaps held in the graphics card's
- memory, should be aligned.
-
- Use the pixmapLinestepAlignment() to retrieve the value to which
- the \e {individual scanlines} of pixmaps should be aligned.
-
- \row
- \o Image Display
- \o
-
- The isInterlaced() function tells whether the screen is displaying
- images progressively, and the isTransformed() function whether it
- is rotated. The transformOrientation() function can be
- reimplemented to return the current rotation.
-
- \row
- \o Scanlines
- \o
-
- Use the linestep() function to retrieve the length of each
- scanline of the framebuffer.
-
- \row
- \o Pixel Type
- \o
-
- The pixelType() function returns the screen's pixel storage format as
- described by the PixelType enum.
-
- \endtable
-
- \section1 Subclassing and Initial Values
-
- You need to set the following members when implementing a subclass of QScreen:
-
- \table
- \header \o Member \o Initial Value
- \row \o \l{QScreen::}{data} \o A pointer to the framebuffer if possible;
- 0 otherwise.
- \row \o \l{QScreen::}{lstep} \o The number of bytes between each scanline
- in the framebuffer.
- \row \o \l{QScreen::}{w} \o The logical screen width in pixels.
- \row \o \l{QScreen::}{h} \o The logical screen height in pixels.
- \row \o \l{QScreen::}{dw} \o The real screen width in pixels.
- \row \o \l{QScreen::}{dh} \o The real screen height in pixels.
- \row \o \l{QScreen::}{d} \o The number of bits per pixel.
- \row \o \l{QScreen::}{physWidth} \o The screen width in millimeters.
- \row \o \l{QScreen::}{physHeight} \o The screen height in millimeters.
- \endtable
-
- The logical screen values are the same as the real screen values unless the
- screen is transformed in some way; e.g., rotated.
-
- See also the \l{Accelerated Graphics Driver Example} for an example that
- shows how to initialize these values.
-
- \sa QScreenDriverPlugin, QScreenDriverFactory, {Qt for Embedded Linux Display
- Management}
-*/
-
-/*!
- \enum QScreen::PixelType
-
- This enum describes the pixel storage format of the screen,
- i.e. the order of the red (R), green (G) and blue (B) components
- of a pixel.
-
- \value NormalPixel Red-green-blue (RGB)
- \value BGRPixel Blue-green-red (BGR)
-
- \sa pixelType()
-*/
-
-/*!
- \enum QScreen::ClassId
-
- This enum defines the class identifiers for the known screen subclasses.
-
- \value LinuxFBClass QLinuxFBScreen
- \value TransformedClass QTransformedScreen
- \value VNCClass QVNCScreen
- \value MultiClass QMultiScreen
- \value VFbClass QVFbScreen
- \value DirectFBClass QDirectFBScreen
- \value SvgalibClass QSvgalibScreen
- \value ProxyClass QProxyScreen
- \value GLClass QGLScreen
- \value CustomClass Unknown QScreen subclass
-
- \sa classId()
-*/
-
-/*!
- \variable QScreen::screenclut
- \brief the color table
-
- Initialize this variable in a subclass using a paletted screen mode,
- and initialize its partner, QScreen::screencols.
-
- \sa screencols
-*/
-
-/*!
- \variable QScreen::screencols
- \brief the number of entries in the color table
-
- Initialize this variable in a subclass using a paletted screen mode,
- and initialize its partner, QScreen::screenclut.
-
- \sa screenclut
-*/
-
-/*!
- \variable QScreen::data
- \brief points to the first visible pixel in the frame buffer.
-
- You must initialize this variable if you are using the default
- implementation of non-buffered painting Qt::WA_PaintOnScreen,
- QPixmap::grabWindow() or QDirectPainter::frameBuffer(). If you
- initialize this variable, you must also initialize QScreen::size and
- QScreen::mapsize.
-
- \sa QScreen::size, QScreen::mapsize
-*/
-
-/*!
- \variable QScreen::w
- \brief the logical width of the screen.
-
- This variable \e{must} be initialized by a subclass.
-*/
-
-/*!
- \variable QScreen::lstep
- \brief the number of bytes representing a line in the frame buffer.
-
- i.e., \e{line step}. \c {data[lstep * 2]} is the address of the
- first visible pixel in the third line of the frame buffer.
-
- \sa data
-*/
-
-/*!
- \variable QScreen::h
- \brief the logical height of the screen.
-
- This variable \e{must} be initialized by a subclass.
-*/
-
-/*!
- \variable QScreen::d
- \brief the pixel depth
-
- This is the number of significant bits used to set a pixel
- color. This variable \e{must} be initialized by a subclass.
-*/
-
-/*!
- \variable QScreen::pixeltype
- \brief set to BGRPixel
-
- Set this variable to BGRPixel in a subclass, if the screen pixel
- format is a BGR type and you have used setPixelFormat() to set the
- pixel format to the corresponding RGB format. e.g., you have set the
- pixel format to QImage::Format_RGB555, but your screen really uses
- BGR, not RGB.
-*/
-
-/*!
- \variable QScreen::grayscale
- \brief the gray scale screen mode flag
-
- Set this variable to true in a subclass, if you are using a
- grayscale screen mode. e.g., in an 8-bit mode where you don't want
- to use the palette, but you want to use the grayscales.
-*/
-
-/*!
- \variable QScreen::dw
- \brief the device width
-
- This is the number of pixels in a row of the physical screen. It
- \e{must} be initialized by a subclass. Normally, it should be set to
- the logical width QScreen::w, but it might be different, e.g., if
- you are doing rotations in software.
-
- \sa QScreen::w
-*/
-
-/*!
- \variable QScreen::dh
- \brief the device height
-
- This is the number of pixels in a column of the physical screen. It
- \e{must} be initialized by a subclass. Normally, it should be set to
- the logical height QScreen::h, but it might be different, e.g., if
- you are doing rotations in software.
-
- \sa QScreen::h
-*/
-
-/*!
- \variable QScreen::size
- \brief the number of bytes in the visible region of the frame buffer
-
- This is the number of bytes in the visible part of the block pointed
- to by the QScreen::data pointer. You must initialize this variable
- if you initialize the QScreen::data pointer.
-
- \sa QScreen::data, QScreen::mapsize
-*/
-
-/*!
- \variable QScreen::mapsize
- \brief the total number of bytes in the frame buffer
-
- This is the total number of bytes in the block pointed to by the
- QScreen::data pointer. You must initialize this variable if you
- initialize the QScreen::data pointer.
-
- \sa QScreen::data, QScreen::size
-*/
-
-/*!
- \variable QScreen::physWidth
- \brief the physical width of the screen in millimeters.
-
- Currently, this variable is used when calculating the screen DPI,
- which in turn is used when deciding the actual font size Qt is
- using.
-*/
-
-/*!
- \variable QScreen::physHeight
- \brief the physical height of the screen in millimeters.
-
- Currently, this variable is used when calculating the screen DPI,
- which in turn is used when deciding the actual font size Qt is
- using.
-*/
-
-/*!
- \fn static QScreen* QScreen::instance()
-
- Returns a pointer to the application's QScreen instance.
-
- If this screen consists of several subscreens, operations to the
- returned instance will affect all its subscreens. Use the
- subscreens() function to retrieve access to a particular
- subscreen.
-
- \sa subScreens(), subScreenIndexAt()
-*/
-
-/*!
- \fn QList<QScreen*> QScreen::subScreens() const
- \since 4.2
-
- Returns a list of this screen's subscreens. Use the
- subScreenIndexAt() function to retrieve the index of a screen at a
- given position.
-
- Note that if \e this screen consists of several subscreens,
- operations to \e this instance will affect all subscreens by
- default.
-
- \sa instance(), subScreenIndexAt()
-*/
-
-/*!
- \fn int QScreen::physicalWidth() const
- \since 4.2
-
- Returns the physical width of the screen in millimeters.
-
- \sa width(), deviceWidth(), physicalHeight()
-*/
-
-/*!
- \fn int QScreen::physicalHeight() const
- \since 4.2
-
- Returns the physical height of the screen in millimeters.
-
- \sa height(), deviceHeight(), physicalWidth()
-*/
-
-/*!
- \fn virtual bool QScreen::initDevice() = 0
-
- This function is called by the \l{Qt for Embedded Linux} server to
- initialize the framebuffer. Note that a server application will call the
- connect() function prior to this function.
-
- Implement this function to make accelerated drivers set up the
- graphics card. Return true to indicate success and false to indicate
- failure.
-
- \sa shutdownDevice(), connect()
-*/
-
-/*!
- \fn virtual bool QScreen::connect(const QString &displaySpec) = 0
-
- This function is called by every \l{Qt for Embedded Linux}
- application on startup, and must be implemented to map in the
- framebuffer and the accelerated drivers that the graphics card
- control registers. Note that connect must be called \e before
- the initDevice() function.
-
- Ensure that true is returned if a connection to the screen device
- is made. Otherwise, return false. Upon making the connection, the
- function should read out the parameters of the framebuffer and use
- them as required to set this class's protected variables.
-
- The \a displaySpec argument is passed by the QWS_DISPLAY
- environment variable or the -display command line parameter, and
- has the following syntax:
-
- \snippet doc/src/snippets/code/src_gui_embedded_qscreen_qws.cpp 0
-
- For example, to use the mach64 driver on fb1 as display 2:
-
- \snippet doc/src/snippets/code/src_gui_embedded_qscreen_qws.cpp 1
-
- See \l{Qt for Embedded Linux Display Management} for more details.
-
- \sa disconnect(), initDevice(), {Running Qt for Embedded Linux Applications}
-*/
-
-/*!
- \fn QScreen::disconnect()
-
- This function is called by every \l{Qt for Embedded Linux} application
- before exiting, and must be implemented to unmap the
- framebuffer. Note that a server application will call the
- shutdownDevice() function prior to this function.
-
- \sa connect(), shutdownDevice(), {Running Qt for Embedded Linux
- Applications}
-*/
-
-/*!
- \fn QScreen::setMode(int width, int height, int depth)
-
- Implement this function to reset the framebuffer's resolution (\a
- width and \a height) and bit \a depth.
-
- After the resolution has been set, existing paint engines will be
- invalid and the framebuffer should be completely redrawn. In a
- multiple-process situation, all other applications must be
- notified to reset their mode and update themselves accordingly.
-*/
-
-/*!
- \fn QScreen::blank(bool on)
-
- Prevents the screen driver form displaying any content on the
- screen.
-
- Note that the default implementation does nothing.
-
- Reimplement this function to prevent the screen driver from
- displaying any contents on the screen if \a on is true; otherwise
- the contents is expected to be shown.
-
- \sa blit()
-*/
-
-/*!
- \fn int QScreen::pixmapOffsetAlignment()
-
- Returns the value (in bits) to which the start address of pixmaps
- held in the graphics card's memory, should be aligned.
-
- Note that the default implementation returns 64; reimplement this
- function to override the return value, e.g., when implementing an
- accelerated driver (see the \l {Adding an Accelerated Graphics
- Driver to Qt for Embedded Linux}{Adding an Accelerated Graphics Driver}
- documentation for details).
-
- \sa pixmapLinestepAlignment()
-*/
-
-/*!
- \fn int QScreen::pixmapLinestepAlignment()
-
- Returns the value (in bits) to which individual scanlines of
- pixmaps held in the graphics card's memory, should be
- aligned.
-
- Note that the default implementation returns 64; reimplement this
- function to override the return value, e.g., when implementing an
- accelerated driver (see the \l {Adding an Accelerated Graphics
- Driver to Qt for Embedded Linux}{Adding an Accelerated Graphics Driver}
- documentation for details).
-
- \sa pixmapOffsetAlignment()
-*/
-
-/*!
- \fn QScreen::width() const
-
- Returns the logical width of the framebuffer in pixels.
-
- \sa deviceWidth(), physicalWidth(), height()
-*/
-
-/*!
- \fn int QScreen::height() const
-
- Returns the logical height of the framebuffer in pixels.
-
- \sa deviceHeight(), physicalHeight(), width()
-*/
-
-/*!
- \fn QScreen::depth() const
-
- Returns the depth of the framebuffer, in bits per pixel.
-
- Note that the returned depth is the number of bits each pixel
- fills rather than the number of significant bits, so 24bpp and
- 32bpp express the same range of colors (8 bits of red, green and
- blue).
-
- \sa clut(), pixmapDepth()
-*/
-
-/*!
- \fn int QScreen::pixmapDepth() const
-
- Returns the preferred depth for pixmaps, in bits per pixel.
-
- \sa depth()
-*/
-
-/*!
- \fn QScreen::linestep() const
-
- Returns the length of each scanline of the framebuffer in bytes.
-
- \sa isInterlaced()
-*/
-
-/*!
- \fn QScreen::deviceWidth() const
-
- Returns the physical width of the framebuffer device in pixels.
-
- Note that the returned width can differ from the width which
- \l{Qt for Embedded Linux} will actually use, that is if the display is
- centered within the framebuffer.
-
- \sa width(), physicalWidth(), deviceHeight()
-*/
-
-/*!
- \fn QScreen::deviceHeight() const
-
- Returns the full height of the framebuffer device in pixels.
-
- Note that the returned height can differ from the height which
- \l{Qt for Embedded Linux} will actually use, that is if the display is
- centered within the framebuffer.
-
- \sa height(), physicalHeight(), deviceWidth()
-*/
-
-/*!
- \fn uchar *QScreen::base() const
-
- Returns a pointer to the beginning of the framebuffer.
-
- \sa onCard(), region(), totalSize()
-*/
-
-/*!
- \fn uchar *QScreen::cache(int)
-
- \internal
-
- This function is used to store pixmaps in graphics memory for the
- use of the accelerated drivers. See QLinuxFbScreen (where the
- caching is implemented) for more information.
-*/
-
-/*!
- \fn QScreen::uncache(uchar *)
-
- \internal
-
- This function is called on pixmap destruction to remove them from
- graphics card memory.
-*/
-
-/*!
- \fn QScreen::screenSize() const
-
- Returns the size of the screen in bytes.
-
- The screen size is always located at the beginning of framebuffer
- memory, i.e. it can also be retrieved using the base() function.
-
- \sa base(), region()
-*/
-
-/*!
- \fn QScreen::totalSize() const
-
- Returns the size of the available graphics card memory (including
- the screen) in bytes.
-
- \sa onCard()
-*/
-
-// Unaccelerated screen/driver setup. Can be overridden by accelerated
-// drivers
-
-/*!
- \fn QScreen::QScreen(int displayId)
-
- Constructs a new screen driver.
-
- The \a displayId identifies the \l{Qt for Embedded Linux} server to connect
- to.
-*/
-
-/*!
- \fn QScreen::clut()
-
- Returns a pointer to the screen's color lookup table (i.e. its
- color palette).
-
- Note that this function only apply in paletted modes like 8-bit,
- i.e. in modes where only the palette indexes (and not the actual
- color values) are stored in memory.
-
- \sa alloc(), depth(), colorCount()
-*/
-
-/*!
- \obsolete
- \fn int QScreen::numCols()
-
- \sa colorCount()
-*/
-
-/*!
- \since 4.6
- \fn int QScreen::colorCount()
-
- Returns the number of entries in the screen's color lookup table
- (i.e. its color palette). A pointer to the color table can be
- retrieved using the clut() function.
-
- \sa clut(), alloc()
-*/
-
-/*!
- \since 4.4
-
- Constructs a new screen driver.
-
- The \a display_id identifies the \l{Qt for Embedded Linux}
- server to connect to. The \a classId specifies the class
- identifier.
-*/
-QScreen::QScreen(int display_id, ClassId classId)
- : screencols(0), data(0), entries(0), entryp(0), lowest(0),
- w(0), lstep(0), h(0), d(1), pixeltype(NormalPixel), grayscale(false),
- dw(0), dh(0), size(0), mapsize(0), displayId(display_id),
- physWidth(0), physHeight(0), d_ptr(new QScreenPrivate(this, classId))
-{
- clearCacheFunc = 0;
-}
-
-QScreen::QScreen(int display_id)
- : screencols(0), data(0), entries(0), entryp(0), lowest(0),
- w(0), lstep(0), h(0), d(1), pixeltype(NormalPixel), grayscale(false),
- dw(0), dh(0), size(0), mapsize(0), displayId(display_id),
- physWidth(0), physHeight(0), d_ptr(new QScreenPrivate(this))
-{
- clearCacheFunc = 0;
-}
-
-/*!
- Destroys this screen driver.
-*/
-
-QScreen::~QScreen()
-{
- delete d_ptr;
-}
-
-/*!
- This function is called by the \l{Qt for Embedded Linux} server before it
- calls the disconnect() function when exiting.
-
- Note that the default implementation only hides the mouse cursor;
- reimplement this function to do the necessary graphics card
- specific cleanup.
-
- \sa initDevice(), disconnect()
-*/
-
-void QScreen::shutdownDevice()
-{
-#ifndef QT_NO_QWS_CURSOR
- if (qt_screencursor)
- qt_screencursor->hide();
-#endif
-}
-
-extern bool qws_accel; //in qapplication_qws.cpp
-
-/*!
- \fn PixelType QScreen::pixelType() const
-
- Returns the pixel storage format of the screen.
-*/
-
-/*!
- Returns the pixel format of the screen, or \c QImage::Format_Invalid
- if the pixel format is not a supported image format.
-
-*/
-QImage::Format QScreen::pixelFormat() const
-{
- return d_ptr->pixelFormat;
-}
-
-/*!
- Sets the screen's pixel format to \a format.
- */
-void QScreen::setPixelFormat(QImage::Format format)
-{
- d_ptr->pixelFormat = format;
-}
-
-
-/*!
- \fn int QScreen::alloc(unsigned int red, unsigned int green, unsigned int blue)
-
- Returns the index in the screen's palette which is the closest
- match to the given RGB value (\a red, \a green, \a blue).
-
- Note that this function only apply in paletted modes like 8-bit,
- i.e. in modes where only the palette indexes (and not the actual
- color values) are stored in memory.
-
- \sa clut(), colorCount()
-*/
-
-int QScreen::alloc(unsigned int r,unsigned int g,unsigned int b)
-{
- int ret = 0;
- if (d == 8) {
- if (grayscale)
- return qGray(r, g, b);
-
- // First we look to see if we match a default color
- const int pos = (r + 25) / 51 * 36 + (g + 25) / 51 * 6 + (b + 25) / 51;
- if (pos < screencols && screenclut[pos] == qRgb(r, g, b)) {
- return pos;
- }
-
- // search for nearest color
- unsigned int mindiff = 0xffffffff;
- unsigned int diff;
- int dr,dg,db;
-
- for (int loopc = 0; loopc < screencols; ++loopc) {
- dr = qRed(screenclut[loopc]) - r;
- dg = qGreen(screenclut[loopc]) - g;
- db = qBlue(screenclut[loopc]) - b;
- diff = dr*dr + dg*dg + db*db;
-
- if (diff < mindiff) {
- ret = loopc;
- if (!diff)
- break;
- mindiff = diff;
- }
- }
- } else if (d == 4) {
- ret = qGray(r, g, b) >> 4;
- } else if (d == 1) {
- ret = qGray(r, g, b) >= 128;
- } else {
- qFatal("cannot alloc %dbpp color", d);
- }
-
- return ret;
-}
-
-/*!
- Saves the current state of the graphics card.
-
- For example, hardware screen drivers should reimplement the save()
- and restore() functions to save and restore its registers,
- enabling swintching between virtual consoles.
-
- Note that the default implementation does nothing.
-
- \sa restore()
-*/
-
-void QScreen::save()
-{
-}
-
-/*!
- Restores the previously saved state of the graphics card.
-
- For example, hardware screen drivers should reimplement the save()
- and restore() functions to save and restore its registers,
- enabling swintching between virtual consoles.
-
- Note that the default implementation does nothing.
-
- \sa save()
-*/
-
-void QScreen::restore()
-{
-}
-
-void QScreen::blank(bool)
-{
-}
-
-/*!
- \internal
-*/
-
-void QScreen::set(unsigned int, unsigned int, unsigned int, unsigned int)
-{
-}
-
-/*!
- \fn bool QScreen::supportsDepth(int depth) const
-
- Returns true if the screen supports the specified color \a depth;
- otherwise returns false.
-
- \sa clut()
-*/
-
-bool QScreen::supportsDepth(int d) const
-{
- if (false) {
- //Just to simplify the ifdeffery
-#ifdef QT_QWS_DEPTH_1
- } else if(d==1) {
- return true;
-#endif
-#ifdef QT_QWS_DEPTH_4
- } else if(d==4) {
- return true;
-#endif
-#ifdef QT_QWS_DEPTH_8
- } else if(d==8) {
- return true;
-#endif
-#ifdef QT_QWS_DEPTH_16
- } else if(d==16) {
- return true;
-#endif
-#ifdef QT_QWS_DEPTH_15
- } else if (d == 15) {
- return true;
-#endif
-#ifdef QT_QWS_DEPTH_18
- } else if(d==18 || d==19) {
- return true;
-#endif
-#ifdef QT_QWS_DEPTH_24
- } else if(d==24) {
- return true;
-#endif
-#ifdef QT_QWS_DEPTH_32
- } else if(d==32) {
- return true;
-#endif
- }
- return false;
-}
-
-/*!
- \fn bool QScreen::onCard(const unsigned char *buffer) const
-
- Returns true if the specified \a buffer is within the graphics
- card's memory; otherwise returns false (i.e. if it's in main RAM).
-
- \sa base(), totalSize()
-*/
-
-bool QScreen::onCard(const unsigned char * p) const
-{
- long t=(unsigned long)p;
- long bmin=(unsigned long)data;
- if (t < bmin)
- return false;
- if(t >= bmin+mapsize)
- return false;
- return true;
-}
-
-/*!
- \fn bool QScreen::onCard(const unsigned char * buffer, ulong& offset) const
- \overload
-
- If the specified \a buffer is within the graphics card's memory,
- this function stores the offset from the start of graphics card
- memory (in bytes), in the location specified by the \a offset
- parameter.
-*/
-
-bool QScreen::onCard(const unsigned char * p, ulong& offset) const
-{
- long t=(unsigned long)p;
- long bmin=(unsigned long)data;
- if (t < bmin)
- return false;
- long o = t - bmin;
- if (o >= mapsize)
- return false;
- offset = o;
- return true;
-}
-
-/*
-#if !defined(QT_NO_QWS_REPEATER)
- { "Repeater", qt_get_screen_repeater, 0 },
-#endif
-#if defined(QT_QWS_EE)
- { "EE", qt_get_screen_ee, 0 },
-#endif
-
-*/
-
-/*
-Given a display_id (number of the \l{Qt for Embedded Linux} server to connect to)
-and a spec (e.g. Mach64:/dev/fb0) return a QScreen-descendant.
-The QScreenDriverFactory is queried for a suitable driver and, if found,
-asked to create a driver.
-People writing new graphics drivers should either hook their own
-QScreen-descendant into QScreenDriverFactory or use the QScreenDriverPlugin
-to make a dynamically loadable driver.
-*/
-
-Q_GUI_EXPORT QScreen* qt_get_screen(int display_id, const char *spec)
-{
- QString displaySpec = QString::fromAscii(spec);
- QString driver = displaySpec;
- int colon = displaySpec.indexOf(QLatin1Char(':'));
- if (colon >= 0)
- driver.truncate(colon);
- driver = driver.trimmed();
-
- bool foundDriver = false;
- QString driverName = driver;
-
- QStringList driverList;
- if (!driver.isEmpty())
- driverList << driver;
- else
- driverList = QScreenDriverFactory::keys();
-
- for (int i = 0; i < driverList.size(); ++i) {
- const QString driverName = driverList.at(i);
- qt_screen = QScreenDriverFactory::create(driverName, display_id);
- if (qt_screen) {
- foundDriver = true;
- if (qt_screen->connect(displaySpec)) {
- return qt_screen;
- } else {
- delete qt_screen;
- qt_screen = 0;
- }
- }
- }
-
- if (driver.isNull())
- qFatal("No suitable driver found");
- else if (foundDriver)
- qFatal("%s: driver cannot connect", driver.toLatin1().constData());
- else
- qFatal("%s: driver not found", driver.toLatin1().constData());
-
- return 0;
-}
-
-#ifndef QT_NO_QWS_CURSOR
-static void blendCursor(QImage *dest, const QImage &cursor, const QPoint &offset)
-{
- QRasterBuffer rb;
- rb.prepare(dest);
-
- QSpanData spanData;
- spanData.init(&rb, 0);
- spanData.type = QSpanData::Texture;
- spanData.initTexture(&cursor, 256);
- spanData.dx = -offset.x();
- spanData.dy = -offset.y();
- if (!spanData.blend)
- return;
-
- const QRect rect = QRect(offset, cursor.size())
- & QRect(QPoint(0, 0), dest->size());
- const int w = rect.width();
- const int h = rect.height();
-
- QVarLengthArray<QT_FT_Span, 32> spans(h);
- for (int i = 0; i < h; ++i) {
- spans[i].x = rect.x();
- spans[i].len = w;
- spans[i].y = rect.y() + i;
- spans[i].coverage = 255;
- }
- spanData.blend(h, spans.constData(), &spanData);
-}
-#endif // QT_NO_QWS_CURSOR
-
-/*!
- \fn void QScreen::exposeRegion(QRegion region, int windowIndex)
-
- This function is called by the \l{Qt for Embedded Linux} server whenever a
- screen update is required. \a region is the area on the screen
- that must be updated, and \a windowIndex is the index into
- QWSServer::clientWindows() of the window that required the
- update. QWSWindow::state() gives more information about the cause.
-
- The default implementation composes the
- affected windows and paints the given \a region on screen by
- calling the blit() and solidFill() functions
-
- This function can be reimplemented to perform composition in
- hardware, or to perform transition effects.
- For simpler hardware acceleration, or to interface with
- this is typically done by reimplementing the blit() and
- solidFill() functions instead.
-
- Note that there is no need to call this function explicitly.
-
- \sa blit(), solidFill(), blank()
-*/
-void QScreen::exposeRegion(QRegion r, int windowIndex)
-{
- r &= region();
- if (r.isEmpty())
- return;
-
- int changing = windowIndex;
- // when we have just lowered a window, we have to expose all the windows below where the
- // window used to be.
- if (changing && qwsServer->clientWindows().at(changing)->state() == QWSWindow::Lowering)
- changing = 0;
-#ifdef QTOPIA_PERFTEST
- static enum { PerfTestUnknown, PerfTestOn, PerfTestOff } perfTestState = PerfTestUnknown;
- if(PerfTestUnknown == perfTestState) {
- if(::getenv("QTOPIA_PERFTEST"))
- perfTestState = PerfTestOn;
- else
- perfTestState = PerfTestOff;
- }
- if(PerfTestOn == perfTestState) {
- QWSWindow *changed = qwsServer->clientWindows().at(changing);
- if(!changed->client()->identity().isEmpty())
- qDebug() << "Performance : expose_region :"
- << changed->client()->identity()
- << r.boundingRect() << ": "
- << qPrintable( QTime::currentTime().toString( "h:mm:ss.zzz" ) );
- }
-#endif
-
- const QRect bounds = r.boundingRect();
- QRegion blendRegion;
- QImage *blendBuffer = 0;
-
-#ifndef QT_NO_QWS_CURSOR
- if (qt_screencursor && !qt_screencursor->isAccelerated()) {
- blendRegion = r & qt_screencursor->boundingRect();
- }
-#endif
- compose(0, r, blendRegion, &blendBuffer, changing);
-
- if (blendBuffer && !blendBuffer->isNull()) {
- const QPoint offset = blendRegion.boundingRect().topLeft();
-#ifndef QT_NO_QWS_CURSOR
- if (qt_screencursor && !qt_screencursor->isAccelerated()) {
- const QRect cursorRect = qt_screencursor->boundingRect();
- if (blendRegion.intersects(cursorRect)) {
- blendCursor(blendBuffer, qt_screencursor->image(),
- cursorRect.topLeft() - offset);
- }
- }
-#endif // QT_NO_QWS_CURSOR
- blit(*blendBuffer, offset, blendRegion);
- delete blendBuffer;
- }
-
- if (r.rectCount() == 1) {
- setDirty(r.boundingRect());
- } else {
- const QVector<QRect> rects = r.rects();
- for (int i = 0; i < rects.size(); ++i)
- setDirty(rects.at(i));
- }
-}
-
-/*!
- \fn void QScreen::blit(const QImage &image, const QPoint &topLeft, const QRegion &region)
-
- Copies the given \a region in the given \a image to the point
- specified by \a topLeft using device coordinates.
-
- This function is called from the exposeRegion() function; it is
- not intended to be called explicitly.
-
- Reimplement this function to make use of \l{Adding an Accelerated
- Graphics Driver to Qt for Embedded Linux}{accelerated hardware}. Note that
- this function must be reimplemented if the framebuffer format is
- not supported by \l{Qt for Embedded Linux} (See the
- \l{Qt for Embedded Linux Display Management}{Display Management}
- documentation for more details).
-
- \sa exposeRegion(), solidFill(), blank()
-*/
-void QScreen::blit(const QImage &img, const QPoint &topLeft, const QRegion &reg)
-{
- const QRect bound = (region() & QRect(topLeft, img.size())).boundingRect();
- QWSDisplay::grab();
- d_ptr->blit(this, img, topLeft - offset(),
- (reg & bound).translated(-topLeft));
- QWSDisplay::ungrab();
-}
-
-#ifdef QT_QWS_CLIENTBLIT
-/*!
- Returns true if this screen driver supports calling QScreen::blit() and
- QScreen::setDirty() directly from non-server applications, otherwise returns
- false.
-
- If available, this is used to optimize the performance of non-occluded, opaque
- client windows by removing the server round trip when they are updated.
-
- \sa setSupportsBlitInClients()
- */
-bool QScreen::supportsBlitInClients() const
-{
- return d_ptr->supportsBlitInClients;
-}
-
-/*!
- If \a supported, the screen driver is marked as supporting blitting directly
- from non-server applications.
-
- \sa supportsBlitInClients()
- */
-void QScreen::setSupportsBlitInClients(bool supported)
-{
- d_ptr->supportsBlitInClients = supported;
-}
-#endif
-
-/*!
- \internal
-*/
-
-void QScreen::blit(QWSWindow *win, const QRegion &clip)
-{
- QWSWindowSurface *surface = win->windowSurface();
- if (!surface)
- return;
-
- const QImage &img = surface->image();
- if (img.isNull())
- return;
-
- const QRegion rgn = clip & win->paintedRegion();
- if (rgn.isEmpty())
- return;
-
- surface->lock();
- blit(img, win->requestedRegion().boundingRect().topLeft(), rgn);
- surface->unlock();
-}
-
-struct fill_data {
- quint32 color;
- uchar *data;
- int lineStep;
- int x;
- int y;
- int w;
- int h;
-};
-
-/*!
- Fills the given \a region of the screen with the specified \a
- color.
-
- This function is called from the exposeRegion() function; it is
- not intended to be called explicitly.
-
- Reimplement this function to make use of \l{Adding an Accelerated
- Graphics Driver to Qt for Embedded Linux}{accelerated hardware}. Note that
- this function must be reimplemented if the framebuffer format is
- not supported by \l{Qt for Embedded Linux} (See the
- \l{Qt for Embedded Linux Display Management}{Display Management}
- documentation for more details).
-
- \sa exposeRegion(), blit(), blank()
-*/
-// the base class implementation works in device coordinates, so that transformed drivers can use it
-void QScreen::solidFill(const QColor &color, const QRegion &region)
-{
- QWSDisplay::grab();
- d_ptr->solidFill(this, color,
- region.translated(-offset()) & QRect(0, 0, dw, dh));
- QWSDisplay::ungrab();
-}
-
-/*!
- \since 4.2
-
- Creates and returns a new window surface matching the given \a
- key.
-
- The server application will call this function whenever it needs
- to create a server side representation of a window, e.g. when
- copying the content of memory to the screen using the screen
- driver.
-
- Note that this function must be reimplemented when adding an
- accelerated graphics driver. See the
- \l{Adding an Accelerated Graphics Driver to Qt for Embedded Linux}
- {Adding an Accelerated Graphics Driver} documentation for details.
-
- \sa {Qt for Embedded Linux Architecture}
-*/
-QWSWindowSurface* QScreen::createSurface(const QString &key) const
-{
-#ifndef QT_NO_PAINTONSCREEN
- if (key == QLatin1String("OnScreen"))
- return new QWSOnScreenSurface;
- else
-#endif
- if (key == QLatin1String("mem"))
- return new QWSLocalMemSurface;
-#ifndef QT_NO_QWS_MULTIPROCESS
- else if (key == QLatin1String("shm"))
- return new QWSSharedMemSurface;
-#endif
-#ifndef QT_NO_PAINT_DEBUG
- else if (key == QLatin1String("Yellow"))
- return new QWSYellowSurface;
-#endif
-#ifndef QT_NO_DIRECTPAINTER
- else if (key == QLatin1String("DirectPainter"))
- return new QWSDirectPainterSurface;
-#endif
-
- return 0;
-}
-
-#ifndef QT_NO_PAINTONSCREEN
-bool QScreen::isWidgetPaintOnScreen(const QWidget *w)
-{
- static int doOnScreen = -1;
- if (doOnScreen == -1) {
- const QByteArray env = qgetenv("QT_ONSCREEN_PAINT");
- if (env == "force")
- doOnScreen = 2;
- else
- doOnScreen = (env.toInt() > 0 ? 1 : 0);
- }
-
- if (doOnScreen == 2) // force
- return true;
-
- if (doOnScreen == 0 && !w->testAttribute(Qt::WA_PaintOnScreen))
- return false;
-
- return w->d_func()->isOpaque;
-}
-#endif
-
-/*!
- \overload
-
- Creates and returns a new window surface for the given \a widget.
-*/
-QWSWindowSurface* QScreen::createSurface(QWidget *widget) const
-{
-#ifndef QT_NO_PAINTONSCREEN
- if (isWidgetPaintOnScreen(widget) && base())
- return new QWSOnScreenSurface(widget);
- else
-#endif
- if (QApplication::type() == QApplication::GuiServer)
- return new QWSLocalMemSurface(widget);
-#ifndef QT_NO_QWS_MULTIPROCESS
- else
- return new QWSSharedMemSurface(widget);
-#endif
-
- return 0;
-}
-
-void QScreen::compose(int level, const QRegion &exposed, QRegion &blend,
- QImage **blendbuffer, int changing_level)
-{
- QRect exposed_bounds = exposed.boundingRect();
- QWSWindow *win = 0;
- do {
- win = qwsServer->clientWindows().value(level); // null is background
- ++level;
- } while (win && !win->paintedRegion().boundingRect().intersects(exposed_bounds));
-
- QWSWindowSurface *surface = (win ? win->windowSurface() : 0);
- bool above_changing = level <= changing_level; // 0 is topmost
-
- QRegion exposedBelow = exposed;
- bool opaque = true;
-
- if (win) {
- opaque = win->isOpaque() || !surface->isBuffered();
- if (opaque) {
- exposedBelow -= win->paintedRegion();
- if (above_changing || !surface->isBuffered())
- blend -= exposed & win->paintedRegion();
- } else {
- blend += exposed & win->paintedRegion();
- }
- }
- if (win && !exposedBelow.isEmpty()) {
- compose(level, exposedBelow, blend, blendbuffer, changing_level);
- } else {
- QSize blendSize = blend.boundingRect().size();
- if (!blendSize.isNull()) {
- *blendbuffer = new QImage(blendSize, d_ptr->preferredImageFormat());
- }
- }
-
- const QRegion blitRegion = exposed - blend;
- if (!win)
- paintBackground(blitRegion);
- else if (!above_changing && surface->isBuffered())
- blit(win, blitRegion);
-
- QRegion blendRegion = exposed & blend;
-
- if (win)
- blendRegion &= win->paintedRegion();
- if (!blendRegion.isEmpty()) {
-
- QPoint off = blend.boundingRect().topLeft();
-
- QRasterBuffer rb;
- rb.prepare(*blendbuffer);
- QSpanData spanData;
- spanData.init(&rb, 0);
- if (!win) {
- const QImage::Format format = (*blendbuffer)->format();
- switch (format) {
- case QImage::Format_ARGB32_Premultiplied:
- case QImage::Format_ARGB32:
- case QImage::Format_ARGB8565_Premultiplied:
- case QImage::Format_ARGB8555_Premultiplied:
- case QImage::Format_ARGB6666_Premultiplied:
- case QImage::Format_ARGB4444_Premultiplied:
- spanData.rasterBuffer->compositionMode = QPainter::CompositionMode_Source;
- break;
- default:
- break;
- }
- spanData.setup(qwsServer->backgroundBrush(), 256, QPainter::CompositionMode_Source);
- spanData.dx = off.x();
- spanData.dy = off.y();
- } else if (!surface->isBuffered()) {
- return;
- } else {
- const QImage &img = surface->image();
- QPoint winoff = off - win->requestedRegion().boundingRect().topLeft();
- // convert win->opacity() from scale [0..255] to [0..256]
- int const_alpha = win->opacity();
- const_alpha += (const_alpha >> 7);
- spanData.type = QSpanData::Texture;
- spanData.initTexture(&img, const_alpha);
- spanData.dx = winoff.x();
- spanData.dy = winoff.y();
- }
- if (!spanData.blend)
- return;
-
- if (surface)
- surface->lock();
- const QVector<QRect> rects = blendRegion.rects();
- const int nspans = 256;
- QT_FT_Span spans[nspans];
- for (int i = 0; i < rects.size(); ++i) {
- int y = rects.at(i).y() - off.y();
- int ye = y + rects.at(i).height();
- int x = rects.at(i).x() - off.x();
- int len = rects.at(i).width();
- while (y < ye) {
- int n = qMin(nspans, ye - y);
- int i = 0;
- while (i < n) {
- spans[i].x = x;
- spans[i].len = len;
- spans[i].y = y + i;
- spans[i].coverage = 255;
- ++i;
- }
- spanData.blend(n, spans, &spanData);
- y += n;
- }
- }
- if (surface)
- surface->unlock();
- }
-}
-
-void QScreen::paintBackground(const QRegion &r)
-{
- const QBrush &bg = qwsServer->backgroundBrush();
- Qt::BrushStyle bs = bg.style();
- if (bs == Qt::NoBrush || r.isEmpty())
- return;
-
- if (bs == Qt::SolidPattern) {
- solidFill(bg.color(), r);
- } else {
- const QRect br = r.boundingRect();
- QImage img(br.size(), d_ptr->preferredImageFormat());
- QPoint off = br.topLeft();
- QRasterBuffer rb;
- rb.prepare(&img);
- QSpanData spanData;
- spanData.init(&rb, 0);
- spanData.setup(bg, 256, QPainter::CompositionMode_Source);
- spanData.dx = off.x();
- spanData.dy = off.y();
- Q_ASSERT(spanData.blend);
-
- const QVector<QRect> rects = r.rects();
- const int nspans = 256;
- QT_FT_Span spans[nspans];
- for (int i = 0; i < rects.size(); ++i) {
- int y = rects.at(i).y() - off.y();
- int ye = y + rects.at(i).height();
- int x = rects.at(i).x() - off.x();
- int len = rects.at(i).width();
- while (y < ye) {
- int n = qMin(nspans, ye - y);
- int i = 0;
- while (i < n) {
- spans[i].x = x;
- spans[i].len = len;
- spans[i].y = y + i;
- spans[i].coverage = 255;
- ++i;
- }
- spanData.blend(n, spans, &spanData);
- y += n;
- }
- }
- blit(img, br.topLeft(), r);
- }
-}
-
-/*!
- \fn virtual int QScreen::sharedRamSize(void *)
-
- \internal
-*/
-
-/*!
- \fn QScreen::setDirty(const QRect& rectangle)
-
- Marks the given \a rectangle as dirty.
-
- Note that the default implementation does nothing; reimplement
- this function to indicate that the given \a rectangle has been
- altered.
-*/
-
-void QScreen::setDirty(const QRect&)
-{
-}
-
-/*!
- \fn QScreen::isTransformed() const
-
- Returns true if the screen is transformed (for instance, rotated
- 90 degrees); otherwise returns false.
-
- \sa transformOrientation(), isInterlaced()
-*/
-
-bool QScreen::isTransformed() const
-{
- return false;
-}
-
-/*!
- \fn QScreen::isInterlaced() const
-
- Returns true if the display is interlaced (i.e. is displaying
- images progressively like a television screen); otherwise returns
- false.
-
- If the display is interlaced, the drawing is altered to look
- better.
-
- \sa isTransformed(), linestep()
-*/
-
-bool QScreen::isInterlaced() const
-{
- return false;//qws_screen_is_interlaced;;
-}
-
-/*!
- \fn QScreen::mapToDevice(const QSize &size) const
-
- Maps the given \a size from the coordinate space used by the
- application to the framebuffer coordinate system. Note that the
- default implementation simply returns the given \a size as it is.
-
- Reimplement this function to use the given device's coordinate
- system when mapping.
-
- \sa mapFromDevice()
-*/
-
-QSize QScreen::mapToDevice(const QSize &s) const
-{
- return s;
-}
-
-/*!
- \fn QScreen::mapFromDevice(const QSize &size) const
-
- Maps the given \a size from the framebuffer coordinate system to
- the coordinate space used by the application. Note that the
- default implementation simply returns the given \a size as it is.
-
- Reimplement this function to use the given device's coordinate
- system when mapping.
-
- \sa mapToDevice()
-*/
-
-QSize QScreen::mapFromDevice(const QSize &s) const
-{
- return s;
-}
-
-/*!
- \fn QScreen::mapToDevice(const QPoint &point, const QSize &screenSize) const
- \overload
-
- Maps the given \a point from the coordinate space used by the
- application to the framebuffer coordinate system, passing the
- device's \a screenSize as argument. Note that the default
- implementation returns the given \a point as it is.
-*/
-
-QPoint QScreen::mapToDevice(const QPoint &p, const QSize &) const
-{
- return p;
-}
-
-/*!
- \fn QScreen::mapFromDevice(const QPoint &point, const QSize &screenSize) const
- \overload
-
- Maps the given \a point from the framebuffer coordinate system to
- the coordinate space used by the application, passing the device's
- \a screenSize as argument. Note that the default implementation
- simply returns the given \a point as it is.
-*/
-
-QPoint QScreen::mapFromDevice(const QPoint &p, const QSize &) const
-{
- return p;
-}
-
-/*!
- \fn QScreen::mapToDevice(const QRect &rectangle, const QSize &screenSize) const
- \overload
-
- Maps the given \a rectangle from the coordinate space used by the
- application to the framebuffer coordinate system, passing the
- device's \a screenSize as argument. Note that the default
- implementation returns the given \a rectangle as it is.
-*/
-
-QRect QScreen::mapToDevice(const QRect &r, const QSize &) const
-{
- return r;
-}
-
-/*!
- \fn QScreen::mapFromDevice(const QRect &rectangle, const QSize &screenSize) const
- \overload
-
- Maps the given \a rectangle from the framebuffer coordinate system to
- the coordinate space used by the application, passing the device's
- \a screenSize as argument. Note that the default implementation
- simply returns the given \a rectangle as it is.
-*/
-
-QRect QScreen::mapFromDevice(const QRect &r, const QSize &) const
-{
- return r;
-}
-
-/*!
- \fn QScreen::mapToDevice(const QImage &image) const
- \overload
-
- Maps the given \a image from the coordinate space used by the
- application to the framebuffer coordinate system. Note that the
- default implementation returns the given \a image as it is.
-*/
-
-QImage QScreen::mapToDevice(const QImage &i) const
-{
- return i;
-}
-
-/*!
- \fn QScreen::mapFromDevice(const QImage &image) const
- \overload
-
- Maps the given \a image from the framebuffer coordinate system to
- the coordinate space used by the application. Note that the
- default implementation simply returns the given \a image as it is.
-*/
-
-QImage QScreen::mapFromDevice(const QImage &i) const
-{
- return i;
-}
-
-/*!
- \fn QScreen::mapToDevice(const QRegion &region, const QSize &screenSize) const
- \overload
-
- Maps the given \a region from the coordinate space used by the
- application to the framebuffer coordinate system, passing the
- device's \a screenSize as argument. Note that the default
- implementation returns the given \a region as it is.
-*/
-
-QRegion QScreen::mapToDevice(const QRegion &r, const QSize &) const
-{
- return r;
-}
-
-/*!
- \fn QScreen::mapFromDevice(const QRegion &region, const QSize &screenSize) const
- \overload
-
- Maps the given \a region from the framebuffer coordinate system to
- the coordinate space used by the application, passing the device's
- \a screenSize as argument. Note that the default implementation
- simply returns the given \a region as it is.
-*/
-
-QRegion QScreen::mapFromDevice(const QRegion &r, const QSize &) const
-{
- return r;
-}
-
-/*!
- \fn QScreen::transformOrientation() const
-
- Returns the current rotation as an integer value.
-
- Note that the default implementation returns 0; reimplement this
- function to override this value.
-
- \sa isTransformed()
-*/
-
-int QScreen::transformOrientation() const
-{
- return 0;
-}
-
-int QScreen::pixmapDepth() const
-{
- return depth();
-}
-
-/*!
- \internal
-*/
-int QScreen::memoryNeeded(const QString&)
-{
- return 0;
-}
-
-/*!
- \internal
-*/
-void QScreen::haltUpdates()
-{
-}
-
-/*!
- \internal
-*/
-void QScreen::resumeUpdates()
-{
-}
-
-/*!
- \fn QRegion QScreen::region() const
- \since 4.2
-
- Returns the region covered by this screen driver.
-
- \sa base(), screenSize()
-*/
-
-/*!
- \internal
-*/
-void QScreen::setOffset(const QPoint &p)
-{
- d_ptr->offset = p;
-}
-
-/*!
- \since 4.2
-
- Returns the logical offset of the screen, i.e., the offset between
- (0,0) in screen coordinates and the application coordinate system.
-*/
-QPoint QScreen::offset() const
-{
- return d_ptr->offset;
-}
-
-#if Q_BYTE_ORDER == Q_BIG_ENDIAN
-void QScreen::setFrameBufferLittleEndian(bool littleEndian)
-{
- d_ptr->fb_is_littleEndian = littleEndian;
-}
-
-bool QScreen::frameBufferLittleEndian() const
-{
- return d_ptr->fb_is_littleEndian;
-}
-#endif
-
-/*!
- \fn int QScreen::subScreenIndexAt(const QPoint &position) const
- \since 4.2
-
- Returns the index of the subscreen at the given \a position;
- returns -1 if no screen is found.
-
- The index identifies the subscreen in the list of pointers
- returned by the subScreens() function.
-
- \sa instance(), subScreens()
-*/
-int QScreen::subScreenIndexAt(const QPoint &p) const
-{
- const QList<QScreen*> screens = subScreens();
- const int n = screens.count();
- for (int i = 0; i < n; ++i) {
- if (screens.at(i)->region().contains(p))
- return i;
- }
-
- return -1;
-}
-
-#if 0
-#ifdef QT_LOADABLE_MODULES
-#include <dlfcn.h>
-
-// ### needs update after driver init changes
-
-static QScreen * qt_dodriver(char * driver,char * a,unsigned char * b)
-
-{
- char buf[200];
- strcpy(buf,"/etc/qws/drivers/");
- qstrcpy(buf+17,driver);
- qDebug("Attempting driver %s",driver);
-
- void * handle;
- handle=dlopen(buf,RTLD_LAZY);
- if(handle==0) {
- qFatal("Module load error");
- }
- QScreen *(*qt_get_screen_func)(char *,unsigned char *);
- qt_get_screen_func=dlsym(handle,"qt_get_screen");
- if(qt_get_screen_func==0) {
- qFatal("Couldn't get symbol");
- }
- QScreen * ret=qt_get_screen_func(a,b);
- return ret;
-}
-
-static QScreen * qt_do_entry(char * entry)
-{
- unsigned char config[256];
-
- FILE * f=fopen(entry,"r");
- if(!f) {
- return 0;
- }
-
- int r=fread(config,256,1,f);
- if(r<1)
- return 0;
-
- fclose(f);
-
- unsigned short vendorid=*((unsigned short int *)config);
- unsigned short deviceid=*(((unsigned short int *)config)+1);
- if(config[0xb]!=3)
- return 0;
-
- if(vendorid==0x1002) {
- if(deviceid==0x4c4d) {
- qDebug("Compaq Armada/IBM Thinkpad's Mach64 card");
- return qt_dodriver("mach64.so",entry,config);
- } else if(deviceid==0x4742) {
- qDebug("Desktop Rage Pro Mach64 card");
- return qt_dodriver("mach64.so",entry,config);
- } else {
- qDebug("Unrecognised ATI card id %x",deviceid);
- return 0;
- }
- } else {
- qDebug("Unrecognised vendor");
- }
- return 0;
-}
-
-extern bool qws_accel;
-
-/// ** NOT SUPPPORTED **
-
-QScreen * qt_probe_bus()
-{
- if(!qws_accel) {
- return qt_dodriver("unaccel.so",0,0);
- }
-
- QT_DIR *dirptr = QT_OPENDIR("/proc/bus/pci");
- if(!dirptr)
- return qt_dodriver("unaccel.so",0,0);
- QT_DIR * dirptr2;
- QT_DIRENT *cards;
-
- QT_DIRENT *busses = QT_READDIR(dirptr);
-
- while(busses) {
- if(busses->d_name[0]!='.') {
- char buf[100];
- strcpy(buf,"/proc/bus/pci/");
- qstrcpy(buf+14,busses->d_name);
- int p=strlen(buf);
- dirptr2 = QT_OPENDIR(buf);
- if(dirptr2) {
- cards = QT_READDIR(dirptr2);
- while(cards) {
- if(cards->d_name[0]!='.') {
- buf[p]='/';
- qstrcpy(buf+p+1,cards->d_name);
- QScreen * ret=qt_do_entry(buf);
- if(ret)
- return ret;
- }
- cards = QT_READDIR(dirptr2);
- }
- QT_CLOSEDIR(dirptr2);
- }
- }
- busses = QT_READDIR(dirptr);
- }
- QT_CLOSEDIR(dirptr);
-
- return qt_dodriver("unaccel.so",0,0);
-}
-
-#else
-
-char *qt_qws_hardcoded_slot = "/proc/bus/pci/01/00.0";
-
-const unsigned char* qt_probe_bus()
-{
- const char * slot;
- slot=::getenv("QWS_CARD_SLOT");
- if(!slot)
- slot=qt_qws_hardcoded_slot;
- if (slot) {
- static unsigned char config[256];
- FILE * f=fopen(slot,"r");
- if(!f) {
- qDebug("Open failure for %s",slot);
- slot=0;
- } else {
- int r=fread((char*)config,256,1,f);
- fclose(f);
- if(r<1) {
- qDebug("Read failure");
- return 0;
- } else {
- return config;
- }
- }
- }
- return 0;
-}
-
-#endif
-
-#endif // 0
-
-/*!
- \internal
- \since 4.4
-*/
-void QScreen::setPixmapDataFactory(QPixmapDataFactory *factory)
-{
- static bool shownWarning = false;
- if (!shownWarning) {
- qWarning("QScreen::setPixmapDataFactory() is deprecated - use setGraphicsSystem() instead");
- shownWarning = true;
- }
-
- d_ptr->pixmapFactory = factory;
-}
-
-/*!
- \internal
- \since 4.4
-*/
-QPixmapDataFactory* QScreen::pixmapDataFactory() const
-{
- return d_ptr->pixmapFactory;
-}
-
-/*!
- \internal
- \since 4.5
-*/
-void QScreen::setGraphicsSystem(QGraphicsSystem* system)
-{
- d_ptr->graphicsSystem = system;
-}
-
-/*!
- \internal
- \since 4.5
-*/
-QGraphicsSystem* QScreen::graphicsSystem() const
-{
- return d_ptr->graphicsSystem;
-}
-
-/*!
- \since 4.4
-
- Returns the class identifier for the screen object.
-*/
-QScreen::ClassId QScreen::classId() const
-{
- return static_cast<ClassId>(d_ptr->classId);
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/embedded/qscreen_qws.h b/src/gui/embedded/qscreen_qws.h
deleted file mode 100644
index 2ecc6e7155..0000000000
--- a/src/gui/embedded/qscreen_qws.h
+++ /dev/null
@@ -1,391 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSCREEN_QWS_H
-#define QSCREEN_QWS_H
-
-#include <QtCore/qnamespace.h>
-#include <QtCore/qpoint.h>
-#include <QtCore/qlist.h>
-#include <QtGui/qrgb.h>
-#include <QtCore/qrect.h>
-#include <QtGui/qimage.h>
-#include <QtGui/qregion.h>
-
-struct fb_cmap;
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QScreenCursor;
-class QBrush;
-class QWSWindow;
-class QWSWindowSurface;
-class QGraphicsSystem;
-class QPixmapData;
-
-#ifndef QT_QWS_DEPTH16_RGB
-#define QT_QWS_DEPTH16_RGB 565
-#endif
-static const int qt_rbits = (QT_QWS_DEPTH16_RGB/100);
-static const int qt_gbits = (QT_QWS_DEPTH16_RGB/10%10);
-static const int qt_bbits = (QT_QWS_DEPTH16_RGB%10);
-static const int qt_red_shift = qt_bbits+qt_gbits-(8-qt_rbits);
-static const int qt_green_shift = qt_bbits-(8-qt_gbits);
-static const int qt_neg_blue_shift = 8-qt_bbits;
-static const int qt_blue_mask = (1<<qt_bbits)-1;
-static const int qt_green_mask = (1<<(qt_gbits+qt_bbits))-(1<<qt_bbits);
-static const int qt_red_mask = (1<<(qt_rbits+qt_gbits+qt_bbits))-(1<<(qt_gbits+qt_bbits));
-
-static const int qt_red_rounding_shift = qt_red_shift + qt_rbits;
-static const int qt_green_rounding_shift = qt_green_shift + qt_gbits;
-static const int qt_blue_rounding_shift = qt_bbits - qt_neg_blue_shift;
-
-
-inline ushort qt_convRgbTo16(const int r, const int g, const int b)
-{
- const int tr = r << qt_red_shift;
- const int tg = g << qt_green_shift;
- const int tb = b >> qt_neg_blue_shift;
-
- return (tb & qt_blue_mask) | (tg & qt_green_mask) | (tr & qt_red_mask);
-}
-
-inline ushort qt_convRgbTo16(QRgb c)
-{
- const int tr = qRed(c) << qt_red_shift;
- const int tg = qGreen(c) << qt_green_shift;
- const int tb = qBlue(c) >> qt_neg_blue_shift;
-
- return (tb & qt_blue_mask) | (tg & qt_green_mask) | (tr & qt_red_mask);
-}
-
-inline QRgb qt_conv16ToRgb(ushort c)
-{
- const int r=(c & qt_red_mask);
- const int g=(c & qt_green_mask);
- const int b=(c & qt_blue_mask);
- const int tr = r >> qt_red_shift | r >> qt_red_rounding_shift;
- const int tg = g >> qt_green_shift | g >> qt_green_rounding_shift;
- const int tb = b << qt_neg_blue_shift | b >> qt_blue_rounding_shift;
-
- return qRgb(tr,tg,tb);
-}
-
-inline void qt_conv16ToRgb(ushort c, int& r, int& g, int& b)
-{
- const int tr=(c & qt_red_mask);
- const int tg=(c & qt_green_mask);
- const int tb=(c & qt_blue_mask);
- r = tr >> qt_red_shift | tr >> qt_red_rounding_shift;
- g = tg >> qt_green_shift | tg >> qt_green_rounding_shift;
- b = tb << qt_neg_blue_shift | tb >> qt_blue_rounding_shift;
-}
-
-const int SourceSolid=0;
-const int SourcePixmap=1;
-
-#ifndef QT_NO_QWS_CURSOR
-
-class QScreenCursor;
-extern QScreenCursor *qt_screencursor;
-extern bool qws_sw_cursor;
-
-class Q_GUI_EXPORT QScreenCursor
-{
-public:
- QScreenCursor();
- virtual ~QScreenCursor();
-
- virtual void set(const QImage &image, int hotx, int hoty);
- virtual void move(int x, int y);
- virtual void show();
- virtual void hide();
-
- bool supportsAlphaCursor() const { return supportsAlpha; }
-
- static bool enabled() { return qws_sw_cursor; }
-
- QRect boundingRect() const { return QRect(pos - hotspot, size); }
- QImage image() const { return cursor; }
- bool isVisible() const { return enable; }
- bool isAccelerated() const { return hwaccel; }
-
- static void initSoftwareCursor();
- static QScreenCursor* instance() { return qt_screencursor; }
-
-protected:
- QImage cursor;
-
- QSize size;
- QPoint pos;
- QPoint hotspot;
- uint enable : 1;
- uint hwaccel : 1;
- uint supportsAlpha : 1;
-
-private:
- friend class QProxyScreenCursor;
-};
-
-#endif // QT_NO_QWS_CURSOR
-
-// A (used) chunk of offscreen memory
-
-class QPoolEntry
-{
-public:
- unsigned int start;
- unsigned int end;
- int clientId;
-};
-
-class QScreen;
-class QScreenPrivate;
-class QPixmapDataFactory;
-
-extern Q_GUI_EXPORT QScreen *qt_screen;
-typedef void(*ClearCacheFunc)(QScreen *obj, int);
-
-class Q_GUI_EXPORT QScreen {
-
-public:
- enum ClassId { LinuxFBClass, TransformedClass, VNCClass, MultiClass,
- VFbClass, DirectFBClass, SvgalibClass, ProxyClass,
- GLClass, IntfbClass, CustomClass = 1024 };
-
- QScreen(int display_id, ClassId classId);
- explicit QScreen(int display_id);
- virtual ~QScreen();
- static QScreen* instance() { return qt_screen; }
- virtual bool initDevice() = 0;
- virtual bool connect(const QString &displaySpec) = 0;
- virtual void disconnect() = 0;
- virtual void shutdownDevice();
- virtual void setMode(int,int,int) = 0;
- virtual bool supportsDepth(int) const;
-
- virtual void save();
- virtual void restore();
- virtual void blank(bool on);
-
- virtual int pixmapOffsetAlignment() { return 64; }
- virtual int pixmapLinestepAlignment() { return 64; }
- virtual int sharedRamSize(void *) { return 0; }
-
- virtual bool onCard(const unsigned char *) const;
- virtual bool onCard(const unsigned char *, ulong& out_offset) const;
-
- enum PixelType { NormalPixel, BGRPixel };
-
- // sets a single color in the colormap
- virtual void set(unsigned int,unsigned int,unsigned int,unsigned int);
- // allocates a color
- virtual int alloc(unsigned int,unsigned int,unsigned int);
-
- int width() const { return w; }
- int height() const { return h; }
- int depth() const { return d; }
- virtual int pixmapDepth() const;
- PixelType pixelType() const { return pixeltype; }
- int linestep() const { return lstep; }
- int deviceWidth() const { return dw; }
- int deviceHeight() const { return dh; }
- uchar * base() const { return data; }
- // Ask for memory from card cache with alignment
- virtual uchar * cache(int) { return 0; }
- virtual void uncache(uchar *) {}
-
- QImage::Format pixelFormat() const;
-
- int screenSize() const { return size; }
- int totalSize() const { return mapsize; }
-
- QRgb * clut() { return screenclut; }
-#ifdef QT_DEPRECATED
- QT_DEPRECATED int numCols() { return screencols; }
-#endif
- int colorCount() { return screencols; }
-
- virtual QSize mapToDevice(const QSize &) const;
- virtual QSize mapFromDevice(const QSize &) const;
- virtual QPoint mapToDevice(const QPoint &, const QSize &) const;
- virtual QPoint mapFromDevice(const QPoint &, const QSize &) const;
- virtual QRect mapToDevice(const QRect &, const QSize &) const;
- virtual QRect mapFromDevice(const QRect &, const QSize &) const;
- virtual QImage mapToDevice(const QImage &) const;
- virtual QImage mapFromDevice(const QImage &) const;
- virtual QRegion mapToDevice(const QRegion &, const QSize &) const;
- virtual QRegion mapFromDevice(const QRegion &, const QSize &) const;
- virtual int transformOrientation() const;
- virtual bool isTransformed() const;
- virtual bool isInterlaced() const;
-
- virtual void setDirty(const QRect&);
-
- virtual int memoryNeeded(const QString&);
-
- virtual void haltUpdates();
- virtual void resumeUpdates();
-
- // composition manager methods
- virtual void exposeRegion(QRegion r, int changing);
-
- // these work directly on the screen
- virtual void blit(const QImage &img, const QPoint &topLeft, const QRegion &region);
- virtual void solidFill(const QColor &color, const QRegion &region);
- void blit(QWSWindow *bs, const QRegion &clip);
-
- virtual QWSWindowSurface* createSurface(QWidget *widget) const;
- virtual QWSWindowSurface* createSurface(const QString &key) const;
-
- virtual QList<QScreen*> subScreens() const { return QList<QScreen*>(); }
- virtual QRegion region() const { return QRect(offset(), QSize(w, h)); }
- int subScreenIndexAt(const QPoint &p) const;
-
- void setOffset(const QPoint &p);
- QPoint offset() const;
-
- int physicalWidth() const { return physWidth; } // physical display size in mm
- int physicalHeight() const { return physHeight; } // physical display size in mm
-
- QPixmapDataFactory* pixmapDataFactory() const; // Deprecated, will be removed in 4.6
- QGraphicsSystem* graphicsSystem() const;
-
-#ifdef QT_QWS_CLIENTBLIT
- bool supportsBlitInClients() const;
- void setSupportsBlitInClients(bool);
-#endif
-
- ClassId classId() const;
-
-protected:
- void setPixelFormat(QImage::Format format);
- void setPixmapDataFactory(QPixmapDataFactory *factory); // Deprecated, will be removed in 4.6
- void setGraphicsSystem(QGraphicsSystem* system);
-
- QRgb screenclut[256];
- int screencols;
-
- uchar * data;
-
- // Table of allocated lumps, kept in sorted highest-to-lowest order
- // The table itself is allocated at the bottom of offscreen memory
- // i.e. it's similar to having a stack (the table) and a heap
- // (the allocated blocks). Freed space is implicitly described
- // by the gaps between the allocated lumps (this saves entries and
- // means we don't need to worry about coalescing freed lumps)
-
- QPoolEntry * entries;
- int * entryp;
- unsigned int * lowest;
-
- int w;
- int lstep;
- int h;
- int d;
- PixelType pixeltype;
- bool grayscale;
-
- int dw;
- int dh;
-
- int size; // Screen size
- int mapsize; // Total mapped memory
-
- int displayId;
-
- int physWidth;
- int physHeight;
-
- friend class QWSServer;
- friend class QWSServerPrivate;
- static ClearCacheFunc clearCacheFunc;
-
-private:
- void compose(int level, const QRegion &exposed, QRegion &blend,
- QImage **blendbuffer, int changing_level);
- void paintBackground(const QRegion &);
-
- friend class QWSOnScreenSurface;
- static bool isWidgetPaintOnScreen(const QWidget *w);
-
-#if Q_BYTE_ORDER == Q_BIG_ENDIAN
- void setFrameBufferLittleEndian(bool littleEndian);
- bool frameBufferLittleEndian() const;
- friend class QVNCScreen;
- friend class QLinuxFbScreen;
- friend class QVFbScreen;
- friend class QProxyScreen;
- friend class QIntfbScreen;
-#endif
- friend void qt_solidFill_setup(QScreen*, const QColor&, const QRegion&);
- friend void qt_blit_setup(QScreen *screen, const QImage &image,
- const QPoint &topLeft, const QRegion &region);
-#ifdef QT_QWS_DEPTH_GENERIC
- friend void qt_set_generic_blit(QScreen *screen, int bpp,
- int len_red, int len_green, int len_blue,
- int len_alpha, int off_red, int off_green,
- int off_blue, int off_alpha);
-#endif
-
- QScreenPrivate *d_ptr;
-};
-
-// This lives in loadable modules
-
-#ifndef QT_LOADABLE_MODULES
-extern "C" QScreen * qt_get_screen(int display_id, const char* spec);
-#endif
-
-// This is in main lib, loads the right module, calls qt_get_screen
-// In non-loadable cases just aliases to qt_get_screen
-
-const unsigned char * qt_probe_bus();
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QSCREEN_QWS_H
diff --git a/src/gui/embedded/qscreendriverfactory_qws.cpp b/src/gui/embedded/qscreendriverfactory_qws.cpp
deleted file mode 100644
index 710505a175..0000000000
--- a/src/gui/embedded/qscreendriverfactory_qws.cpp
+++ /dev/null
@@ -1,204 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qscreendriverfactory_qws.h"
-
-#include "qscreen_qws.h"
-#include "qapplication.h"
-#include "qscreenlinuxfb_qws.h"
-#include "qscreentransformed_qws.h"
-#include "qscreenvfb_qws.h"
-#include "qscreenmulti_qws_p.h"
-#include "qscreenqnx_qws.h"
-#include "qscreenintegrityfb_qws.h"
-#include <stdlib.h>
-#include "private/qfactoryloader_p.h"
-#include "qscreendriverplugin_qws.h"
-#ifndef QT_NO_QWS_DIRECTFB
-#include "qdirectfbscreen.h"
-#endif
-#ifndef QT_NO_QWS_VNC
-#include "qscreenvnc_qws.h"
-#endif
-
-QT_BEGIN_NAMESPACE
-
-#if !defined(Q_OS_WIN32) || defined(QT_MAKEDLL)
-#ifndef QT_NO_LIBRARY
-
-Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
- (QScreenDriverFactoryInterface_iid,
- QLatin1String("/gfxdrivers"), Qt::CaseInsensitive))
-
-#endif //QT_NO_LIBRARY
-#endif //QT_MAKEDLL
-
-/*!
- \class QScreenDriverFactory
- \ingroup qws
-
- \brief The QScreenDriverFactory class creates screen drivers in
- Qt for Embedded Linux.
-
- Note that this class is only available in \l{Qt for Embedded Linux}.
-
- QScreenDriverFactory is used to detect and instantiate the
- available screen drivers, allowing \l{Qt for Embedded Linux} to load the
- preferred driver into the server application at runtime. The
- create() function returns a QScreen object representing the screen
- driver identified by a given key. The valid keys (i.e. the
- supported drivers) can be retrieved using the keys() function.
-
-
- \l{Qt for Embedded Linux} provides several built-in screen drivers. In
- addition, custom screen drivers can be added using Qt's plugin
- mechanism, i.e. by subclassing the QScreen class and creating a
- screen driver plugin (QScreenDriverPlugin). See the
- \l{Qt for Embedded Linux Display Management}{display management}
- documentation for details.
-
- \sa QScreen, QScreenDriverPlugin
-*/
-
-/*!
- Creates the screen driver specified by the given \a key, using the
- display specified by the given \a displayId.
-
- Note that the keys are case-insensitive.
-
- \sa keys()
-*/
-QScreen *QScreenDriverFactory::create(const QString& key, int displayId)
-{
- QString driver = key.toLower();
-#if defined(Q_OS_QNX) && !defined(QT_NO_QWS_QNX)
- if (driver == QLatin1String("qnx") || driver.isEmpty())
- return new QQnxScreen(displayId);
-#endif
-#if defined(Q_OS_INTEGRITY) && !defined(QT_NO_QWS_INTEGRITY)
- if (driver == QLatin1String("integrityfb") || driver.isEmpty())
- return new QIntfbScreen(displayId);
-#endif
-#ifndef QT_NO_QWS_QVFB
- if (driver == QLatin1String("qvfb") || driver.isEmpty())
- return new QVFbScreen(displayId);
-#endif
-#ifndef QT_NO_QWS_LINUXFB
- if (driver == QLatin1String("linuxfb") || driver.isEmpty())
- return new QLinuxFbScreen(displayId);
-#endif
-#ifndef QT_NO_QWS_DIRECTFB
- if (driver == QLatin1String("directfb") || driver.isEmpty())
- return new QDirectFBScreen(displayId);
-#endif
-#ifndef QT_NO_QWS_TRANSFORMED
- if (driver == QLatin1String("transformed"))
- return new QTransformedScreen(displayId);
-#endif
-#ifndef QT_NO_QWS_VNC
- if (driver == QLatin1String("vnc"))
- return new QVNCScreen(displayId);
-#endif
-#ifndef QT_NO_QWS_MULTISCREEN
- if (driver == QLatin1String("multi"))
- return new QMultiScreen(displayId);
-#endif
-#if !defined(Q_OS_WIN32) || defined(QT_MAKEDLL)
-#ifndef QT_NO_LIBRARY
-
- if (QScreenDriverFactoryInterface *factory = qobject_cast<QScreenDriverFactoryInterface*>(loader()->instance(key)))
- return factory->create(driver, displayId);
-
-#endif
-#endif
- return 0;
-}
-
-/*!
- Returns the list of valid keys, i.e. the available screen drivers.
-
- \sa create()
-*/
-QStringList QScreenDriverFactory::keys()
-{
- QStringList list;
-
-#if defined(Q_OS_QNX) && !defined(QT_NO_QWS_QNX)
- list << QLatin1String("QNX");
-#endif
-#if defined(Q_OS_INTEGRITY) && !defined(QT_NO_QWS_INTEGRITY)
- list << QLatin1String("INTEGRITYFB");
-#endif
-#ifndef QT_NO_QWS_QVFB
- list << QLatin1String("QVFb");
-#endif
-#ifndef QT_NO_QWS_LINUXFB
- list << QLatin1String("LinuxFb");
-#endif
-#ifndef QT_NO_QWS_TRANSFORMED
- list << QLatin1String("Transformed");
-#endif
-#ifndef QT_NO_QWS_VNC
- list << QLatin1String("VNC");
-#endif
-#ifndef QT_NO_QWS_MULTISCREEN
- list << QLatin1String("Multi");
-#endif
-
-#if !defined(Q_OS_WIN32) || defined(QT_MAKEDLL)
-#ifndef QT_NO_LIBRARY
- QStringList plugins = loader()->keys();
- for (int i = 0; i < plugins.size(); ++i) {
-# ifdef QT_NO_QWS_QVFB
- // give QVFb top priority for autodetection
- if (plugins.at(i) == QLatin1String("QVFb"))
- list.prepend(plugins.at(i));
- else
-# endif
- if (!list.contains(plugins.at(i)))
- list += plugins.at(i);
- }
-#endif //QT_NO_LIBRARY
-#endif //QT_MAKEDLL
- return list;
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/embedded/qscreendriverfactory_qws.h b/src/gui/embedded/qscreendriverfactory_qws.h
deleted file mode 100644
index f51cecf2f6..0000000000
--- a/src/gui/embedded/qscreendriverfactory_qws.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSCREENDRIVERFACTORY_QWS_H
-#define QSCREENDRIVERFACTORY_QWS_H
-
-#include <QtCore/qstringlist.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QString;
-class QScreen;
-
-class Q_GUI_EXPORT QScreenDriverFactory
-{
-public:
- static QStringList keys();
- static QScreen *create(const QString&, int);
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QSCREENDRIVERFACTORY_QWS_H
diff --git a/src/gui/embedded/qscreendriverplugin_qws.cpp b/src/gui/embedded/qscreendriverplugin_qws.cpp
deleted file mode 100644
index ace8d1ee08..0000000000
--- a/src/gui/embedded/qscreendriverplugin_qws.cpp
+++ /dev/null
@@ -1,123 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qscreendriverplugin_qws.h"
-
-QT_BEGIN_NAMESPACE
-
-#ifndef QT_NO_LIBRARY
-
-/*!
- \class QScreenDriverPlugin
- \ingroup plugins
- \ingroup qws
-
- \brief The QScreenDriverPlugin class is an abstract base class for
- screen driver plugins in Qt for Embedded Linux.
-
- Note that this class is only available in \l{Qt for Embedded Linux}.
-
- \l{Qt for Embedded Linux} provides ready-made drivers for several screen
- protocols, see the \l{Qt for Embedded Linux Display Management}{display
- management} documentation for details. Custom screen drivers can be
- implemented by subclassing the QScreen class and creating a screen
- driver plugin.
-
- A screen driver plugin can be created by subclassing
- QScreenDriverPlugin and reimplementing the pure virtual keys() and
- create() functions. By exporting the derived class using the
- Q_EXPORT_PLUGIN2() macro, The default implementation of the
- QScreenDriverFactory class will automatically detect the plugin
- and load the driver into the server application at run-time. See
- \l{How to Create Qt Plugins} for details.
-
- \sa QScreen, QScreenDriverFactory
-*/
-
-/*!
- \fn QStringList QScreenDriverPlugin::keys() const
-
- Implement this function to return the list of valid keys, i.e. the
- screen drivers supported by this plugin.
-
- \l{Qt for Embedded Linux} provides ready-made drivers for several screen
- protocols, see the \l{Qt for Embedded Linux Display Management}{display
- management} documentation for details.
-
- \sa create()
-*/
-
-/*!
- Constructs a screen driver plugin with the given \a parent.
-
- Note that this constructor is invoked automatically by the
- Q_EXPORT_PLUGIN2() macro, so there is no need for calling it
- explicitly.
-*/
-QScreenDriverPlugin::QScreenDriverPlugin(QObject *parent)
- : QObject(parent)
-{
-}
-
-/*!
- Destroys this screen driver plugin.
-
- Note that Qt destroys a plugin automatically when it is no longer
- used, so there is no need for calling the destructor explicitly.
-*/
-QScreenDriverPlugin::~QScreenDriverPlugin()
-{
-}
-
-
-/*!
- \fn QScreen* QScreenDriverPlugin::create(const QString &key, int displayId)
-
- Implement this function to create a driver matching the type
- specified by the given \a key and \a displayId parameters. Note
- that keys are case-insensitive.
-
- \sa keys()
-*/
-
-#endif // QT_NO_LIBRARY
-
-QT_END_NAMESPACE
diff --git a/src/gui/embedded/qscreendriverplugin_qws.h b/src/gui/embedded/qscreendriverplugin_qws.h
deleted file mode 100644
index c880adfa72..0000000000
--- a/src/gui/embedded/qscreendriverplugin_qws.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSCREENDRIVERPLUGIN_QWS_H
-#define QSCREENDRIVERPLUGIN_QWS_H
-
-#include <QtCore/qplugin.h>
-#include <QtCore/qfactoryinterface.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_LIBRARY
-
-class QScreen;
-
-struct Q_GUI_EXPORT QScreenDriverFactoryInterface : public QFactoryInterface
-{
- virtual QScreen* create(const QString& driver, int displayId) = 0;
-};
-
-#define QScreenDriverFactoryInterface_iid "com.trolltech.Qt.QScreenDriverFactoryInterface"
-Q_DECLARE_INTERFACE(QScreenDriverFactoryInterface, QScreenDriverFactoryInterface_iid)
-
-class Q_GUI_EXPORT QScreenDriverPlugin : public QObject, public QScreenDriverFactoryInterface
-{
- Q_OBJECT
- Q_INTERFACES(QScreenDriverFactoryInterface:QFactoryInterface)
-public:
- explicit QScreenDriverPlugin(QObject *parent = 0);
- ~QScreenDriverPlugin();
-
- virtual QStringList keys() const = 0;
- virtual QScreen *create(const QString& driver, int displayId) = 0;
-};
-
-#endif // QT_NO_LIBRARY
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QSCREENDRIVERPLUGIN_QWS_H
diff --git a/src/gui/embedded/qscreenintegrityfb_qws.cpp b/src/gui/embedded/qscreenintegrityfb_qws.cpp
deleted file mode 100644
index 6f3081291b..0000000000
--- a/src/gui/embedded/qscreenintegrityfb_qws.cpp
+++ /dev/null
@@ -1,405 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QT_NO_QWS_INTEGRITYFB
-
-#include <qscreenintegrityfb_qws.h>
-#include <qwindowsystem_qws.h>
-#include <qsocketnotifier.h>
-#include <qapplication.h>
-#include <qscreen_qws.h>
-#include "qmouseintegrity_qws.h"
-#include "qkbdintegrity_qws.h"
-#include <qmousedriverfactory_qws.h>
-#include <qkbddriverfactory_qws.h>
-#include <qdebug.h>
-
-#include <INTEGRITY.h>
-#include <device/fbdriver.h>
-
-QT_BEGIN_NAMESPACE
-
-class QIntfbScreenPrivate
-{
-public:
- QIntfbScreenPrivate();
- ~QIntfbScreenPrivate();
-
- FBHandle handle;
- struct FBInfoStruct fbinfo;
-
- QWSMouseHandler *mouse;
-#ifndef QT_NO_QWS_KEYBOARD
- QWSKeyboardHandler *keyboard;
-#endif
-};
-
-QIntfbScreenPrivate::QIntfbScreenPrivate()
- : mouse(0)
-
-{
-#ifndef QT_NO_QWS_KEYBOARD
- keyboard = 0;
-#endif
-}
-
-QIntfbScreenPrivate::~QIntfbScreenPrivate()
-{
- delete mouse;
-#ifndef QT_NO_QWS_KEYBOARD
- delete keyboard;
-#endif
-}
-
-/*!
- \internal
-
- \class QIntfbScreen
- \ingroup qws
-
- \brief The QIntfbScreen class implements a screen driver for the
- INTEGRITY framebuffer drivers.
-
- Note that this class is only available in \l{Qt for INTEGRITY}.
- Custom screen drivers can be added by subclassing the
- QScreenDriverPlugin class, using the QScreenDriverFactory class to
- dynamically load the driver into the application, but there should
- only be one screen object per application.
-
- \sa QScreen, QScreenDriverPlugin, {Running Applications}
-*/
-
-/*!
- \fn bool QIntfbScreen::connect(const QString & displaySpec)
- \reimp
-*/
-
-/*!
- \fn void QIntfbScreen::disconnect()
- \reimp
-*/
-
-/*!
- \fn bool QIntfbScreen::initDevice()
- \reimp
-*/
-
-/*!
- \fn void QIntfbScreen::restore()
- \reimp
-*/
-
-/*!
- \fn void QIntfbScreen::save()
- \reimp
-*/
-
-/*!
- \fn void QIntfbScreen::setDirty(const QRect & r)
- \reimp
-*/
-
-/*!
- \fn void QIntfbScreen::setMode(int nw, int nh, int nd)
- \reimp
-*/
-
-/*!
- \fn void QIntfbScreen::shutdownDevice()
- \reimp
-*/
-
-/*!
- \fn QIntfbScreen::QIntfbScreen(int displayId)
-
- Constructs a QVNCScreen object. The \a displayId argument
- identifies the Qt for Embedded Linux server to connect to.
-*/
-QIntfbScreen::QIntfbScreen(int display_id)
- : QScreen(display_id, IntfbClass), d_ptr(new QIntfbScreenPrivate)
-{
- d_ptr->handle = 0;
- data = 0;
-}
-
-/*!
- Destroys this QIntfbScreen object.
-*/
-QIntfbScreen::~QIntfbScreen()
-{
- delete d_ptr;
-}
-
-static QIntfbScreen *connected = 0;
-
-bool QIntfbScreen::connect(const QString &displaySpec)
-{
- FBDriver *fbdev;
-
- CheckSuccess(gh_FB_get_driver(0, &fbdev));
- CheckSuccess(gh_FB_init_device(fbdev, 0, &d_ptr->handle));
- CheckSuccess(gh_FB_get_info(d_ptr->handle, &d_ptr->fbinfo));
-
- data = (uchar *)d_ptr->fbinfo.start;
-
- d = d_ptr->fbinfo.bitsperpixel;
- switch (d) {
- case 1:
- setPixelFormat(QImage::Format_Mono);
- break;
- case 8:
- setPixelFormat(QImage::Format_Indexed8);
- break;
- case 12:
- setPixelFormat(QImage::Format_RGB444);
- break;
- case 15:
- setPixelFormat(QImage::Format_RGB555);
- break;
- case 16:
- setPixelFormat(QImage::Format_RGB16);
- break;
- case 18:
- setPixelFormat(QImage::Format_RGB666);
- break;
- case 24:
- setPixelFormat(QImage::Format_RGB888);
-#ifdef QT_QWS_DEPTH_GENERIC
-#if Q_BYTE_ORDER != Q_BIG_ENDIAN
- qt_set_generic_blit(this, 24,
- d_ptr->fbinfo.redbits,
- d_ptr->fbinfo.greenbits,
- d_ptr->fbinfo.bluebits,
- d_ptr->fbinfo.alphabits,
- d_ptr->fbinfo.redoffset,
- d_ptr->fbinfo.greenoffset,
- d_ptr->fbinfo.blueoffset,
- d_ptr->fbinfo.alphaoffset);
-#else
- qt_set_generic_blit(this, 24,
- d_ptr->fbinfo.redbits,
- d_ptr->fbinfo.greenbits,
- d_ptr->fbinfo.bluebits,
- d_ptr->fbinfo.alphabits,
- 16 - d_ptr->fbinfo.redoffset,
- 16 - d_ptr->fbinfo.greenoffset,
- 16 - d_ptr->fbinfo.blueoffset,
- d_ptr->fbinfo.alphaoffset);
-#endif
-#endif
- break;
- case 32:
- setPixelFormat(QImage::Format_ARGB32_Premultiplied);
-#ifdef QT_QWS_DEPTH_GENERIC
-#if Q_BYTE_ORDER != Q_BIG_ENDIAN
- qt_set_generic_blit(this, 32,
- d_ptr->fbinfo.redbits,
- d_ptr->fbinfo.greenbits,
- d_ptr->fbinfo.bluebits,
- d_ptr->fbinfo.alphabits,
- d_ptr->fbinfo.redoffset,
- d_ptr->fbinfo.greenoffset,
- d_ptr->fbinfo.blueoffset,
- d_ptr->fbinfo.alphaoffset);
-#else
- qt_set_generic_blit(this, 32,
- d_ptr->fbinfo.redbits,
- d_ptr->fbinfo.greenbits,
- d_ptr->fbinfo.bluebits,
- d_ptr->fbinfo.alphabits,
- 24 - d_ptr->fbinfo.redoffset,
- 24 - d_ptr->fbinfo.greenoffset,
- 24 - d_ptr->fbinfo.blueoffset,
- d_ptr->fbinfo.alphaoffset ? 24 - d_ptr->fbinfo.alphaoffset : 0);
-#endif
-#endif
- break;
- }
-
- dw = w = d_ptr->fbinfo.width;
- dh = h = d_ptr->fbinfo.height;
-
- /* assumes no padding */
- lstep = w * ((d + 7) >> 3);
-
- mapsize = size = h * lstep;
-
- /* default values */
- int dpi = 72;
- physWidth = qRound(dw * 25.4 / dpi);
- physHeight = qRound(dh * 25.4 / dpi);
-
- qDebug("Connected to INTEGRITYfb server: %d x %d x %d %dx%dmm (%dx%ddpi)",
- w, h, d, physWidth, physHeight, qRound(dw*25.4/physWidth), qRound(dh*25.4/physHeight) );
-
-
- QWSServer::setDefaultMouse("integrity");
- QWSServer::setDefaultKeyboard("integrity");
-
- connected = this;
-
- return true;
-}
-
-void QIntfbScreen::disconnect()
-{
- connected = 0;
-}
-
-bool QIntfbScreen::initDevice()
-{
-
- CheckSuccess(gh_FB_set_info(d_ptr->handle, &d_ptr->fbinfo, false));
- CheckSuccess(gh_FB_get_info(d_ptr->handle, &d_ptr->fbinfo));
- data = (uchar *)d_ptr->fbinfo.start;
- d = d_ptr->fbinfo.bitsperpixel;
- dw = w = d_ptr->fbinfo.width;
- dh = h = d_ptr->fbinfo.height;
- mapsize = d_ptr->fbinfo.length;
- /* assumes no padding */
- lstep = w * ((d + 7) >> 3);
-
- mapsize = size = h * lstep;
-
- data = (uchar *)d_ptr->fbinfo.start;
-
- d = d_ptr->fbinfo.bitsperpixel;
- switch (d) {
- case 1:
- setPixelFormat(QImage::Format_Mono);
- break;
- case 8:
- setPixelFormat(QImage::Format_Indexed8);
- break;
- case 12:
- setPixelFormat(QImage::Format_RGB444);
- break;
- case 15:
- setPixelFormat(QImage::Format_RGB555);
- break;
- case 16:
- setPixelFormat(QImage::Format_RGB16);
- break;
- case 18:
- setPixelFormat(QImage::Format_RGB666);
- break;
- case 24:
- setPixelFormat(QImage::Format_RGB888);
- break;
- case 32:
- setPixelFormat(QImage::Format_ARGB32_Premultiplied);
- break;
- }
-#ifdef QT_QWS_DEPTH_GENERIC
-#if defined(__BIG_ENDIAN__)
- qt_set_generic_blit(this, d,
- d_ptr->fbinfo.redbits,
- d_ptr->fbinfo.greenbits,
- d_ptr->fbinfo.bluebits,
- d_ptr->fbinfo.alphabits,
- 24 - d_ptr->fbinfo.redoffset,
- 24 - d_ptr->fbinfo.greenoffset,
- 24 - d_ptr->fbinfo.blueoffset,
- d_ptr->fbinfo.alphaoffset ? 24 - d_ptr->fbinfo.alphaoffset : 0);
-#else
- qt_set_generic_blit(this, d,
- d_ptr->fbinfo.redbits,
- d_ptr->fbinfo.greenbits,
- d_ptr->fbinfo.bluebits,
- d_ptr->fbinfo.alphabits,
- d_ptr->fbinfo.redoffset,
- d_ptr->fbinfo.greenoffset,
- d_ptr->fbinfo.blueoffset,
- d_ptr->fbinfo.alphaoffset);
-#endif
-#endif
-
-#ifndef QT_NO_QWS_CURSOR
- QScreenCursor::initSoftwareCursor();
-#endif
- return true;
-}
-
-void QIntfbScreen::shutdownDevice()
-{
- gh_FB_close(d_ptr->handle);
-}
-
-void QIntfbScreen::setMode(int ,int ,int)
-{
-}
-
-// save the state of the graphics card
-// This is needed so that e.g. we can restore the palette when switching
-// between linux virtual consoles.
-void QIntfbScreen::save()
-{
- // nothing to do.
-}
-
-// restore the state of the graphics card.
-void QIntfbScreen::restore()
-{
-}
-void QIntfbScreen::setDirty(const QRect& rect)
-{
- FBRect fbrect;
- fbrect.dx = rect.x();
- fbrect.dy = rect.y();
- fbrect.width = rect.width();
- fbrect.height = rect.height();
- gh_FB_expose(d_ptr->handle, &fbrect);
-}
-
-void QIntfbScreen::setBrightness(int b)
-{
- if (connected) {
- }
-}
-
-void QIntfbScreen::blank(bool on)
-{
-}
-
-#endif // QT_NO_QWS_INTEGRITYFB
-
-QT_END_NAMESPACE
-
diff --git a/src/gui/embedded/qscreenintegrityfb_qws.h b/src/gui/embedded/qscreenintegrityfb_qws.h
deleted file mode 100644
index bc09e8ef1d..0000000000
--- a/src/gui/embedded/qscreenintegrityfb_qws.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSCREENINTEGRITYFB_QWS_H
-#define QSCREENINTEGRITYFB_QWS_H
-
-#include <QtGui/qscreen_qws.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_QWS_INTEGRITYFB
-
-class QIntfbScreenPrivate;
-
-class Q_GUI_EXPORT QIntfbScreen : public QScreen
-{
-public:
- explicit QIntfbScreen(int display_id);
- virtual ~QIntfbScreen();
- virtual bool initDevice();
- virtual bool connect(const QString &displaySpec);
- virtual void disconnect();
- virtual void shutdownDevice();
- virtual void save();
- virtual void restore();
- virtual void setMode(int nw,int nh,int nd);
- virtual void setDirty(const QRect& r);
- virtual void blank(bool);
- static void setBrightness(int b);
-
-private:
- QIntfbScreenPrivate *d_ptr;
-};
-
-#endif // QT_NO_QWS_INTEGRITYFB
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QSCREENINTEGRITYFB_QWS_H
diff --git a/src/gui/embedded/qscreenlinuxfb_qws.cpp b/src/gui/embedded/qscreenlinuxfb_qws.cpp
deleted file mode 100644
index 67c8a31cd9..0000000000
--- a/src/gui/embedded/qscreenlinuxfb_qws.cpp
+++ /dev/null
@@ -1,1386 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qscreenlinuxfb_qws.h"
-
-#ifndef QT_NO_QWS_LINUXFB
-//#include "qmemorymanager_qws.h"
-#include "qwsdisplay_qws.h"
-#include "qpixmap.h"
-#include <private/qwssignalhandler_p.h>
-#include <private/qcore_unix_p.h> // overrides QT_OPEN
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <sys/kd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <stdio.h>
-#include <limits.h>
-#include <signal.h>
-
-#include "qwindowsystem_qws.h"
-
-#if !defined(Q_OS_DARWIN) && !defined(Q_OS_FREEBSD)
-#include <linux/fb.h>
-
-#ifdef __i386__
-#include <asm/mtrr.h>
-#endif
-#endif
-
-QT_BEGIN_NAMESPACE
-
-extern int qws_client_id;
-
-//#define DEBUG_CACHE
-
-class QLinuxFbScreenPrivate : public QObject
-{
-public:
- QLinuxFbScreenPrivate();
- ~QLinuxFbScreenPrivate();
-
- void openTty();
- void closeTty();
-
- int fd;
- int startupw;
- int startuph;
- int startupd;
- bool blank;
- QLinuxFbScreen::DriverTypes driverType;
-
- bool doGraphicsMode;
-#ifdef QT_QWS_DEPTH_GENERIC
- bool doGenericColors;
-#endif
- int ttyfd;
- long oldKdMode;
- QString ttyDevice;
- QString displaySpec;
-};
-
-QLinuxFbScreenPrivate::QLinuxFbScreenPrivate()
- : fd(-1), blank(true), doGraphicsMode(true),
-#ifdef QT_QWS_DEPTH_GENERIC
- doGenericColors(false),
-#endif
- ttyfd(-1), oldKdMode(KD_TEXT)
-{
- QWSSignalHandler::instance()->addObject(this);
-}
-
-QLinuxFbScreenPrivate::~QLinuxFbScreenPrivate()
-{
- closeTty();
-}
-
-void QLinuxFbScreenPrivate::openTty()
-{
- const char *const devs[] = {"/dev/tty0", "/dev/tty", "/dev/console", 0};
-
- if (ttyDevice.isEmpty()) {
- for (const char * const *dev = devs; *dev; ++dev) {
- ttyfd = QT_OPEN(*dev, O_RDWR);
- if (ttyfd != -1)
- break;
- }
- } else {
- ttyfd = QT_OPEN(ttyDevice.toAscii().constData(), O_RDWR);
- }
-
- if (ttyfd == -1)
- return;
-
- if (doGraphicsMode) {
- ioctl(ttyfd, KDGETMODE, &oldKdMode);
- if (oldKdMode != KD_GRAPHICS) {
- int ret = ioctl(ttyfd, KDSETMODE, KD_GRAPHICS);
- if (ret == -1)
- doGraphicsMode = false;
- }
- }
-
- // No blankin' screen, no blinkin' cursor!, no cursor!
- const char termctl[] = "\033[9;0]\033[?33l\033[?25l\033[?1c";
- QT_WRITE(ttyfd, termctl, sizeof(termctl));
-}
-
-void QLinuxFbScreenPrivate::closeTty()
-{
- if (ttyfd == -1)
- return;
-
- if (doGraphicsMode)
- ioctl(ttyfd, KDSETMODE, oldKdMode);
-
- // Blankin' screen, blinkin' cursor!
- const char termctl[] = "\033[9;15]\033[?33h\033[?25h\033[?0c";
- QT_WRITE(ttyfd, termctl, sizeof(termctl));
-
- QT_CLOSE(ttyfd);
- ttyfd = -1;
-}
-
-/*!
- \enum QLinuxFbScreen::DriverTypes
-
- This enum describes the driver type.
-
- \value GenericDriver Generic Linux framebuffer driver
- \value EInk8Track e-Ink framebuffer driver using the 8Track chipset
- */
-
-/*!
- \fn QLinuxFbScreen::fixupScreenInfo(fb_fix_screeninfo &finfo, fb_var_screeninfo &vinfo)
-
- Adjust the values returned by the framebuffer driver, to work
- around driver bugs or nonstandard behavior in certain drivers.
- \a finfo and \a vinfo specify the fixed and variable screen info
- returned by the driver.
- */
-void QLinuxFbScreen::fixupScreenInfo(fb_fix_screeninfo &finfo, fb_var_screeninfo &vinfo)
-{
- // 8Track e-ink devices (as found in Sony PRS-505) lie
- // about their bit depth -- they claim they're 1 bit per
- // pixel while the only supported mode is 8 bit per pixel
- // grayscale.
- // Caused by this, they also miscalculate their line length.
- if(!strcmp(finfo.id, "8TRACKFB") && vinfo.bits_per_pixel == 1) {
- vinfo.bits_per_pixel = 8;
- finfo.line_length = vinfo.xres;
- }
-}
-
-/*!
- \internal
-
- \class QLinuxFbScreen
- \ingroup qws
-
- \brief The QLinuxFbScreen class implements a screen driver for the
- Linux framebuffer.
-
- Note that this class is only available in \l{Qt for Embedded Linux}.
- Custom screen drivers can be added by subclassing the
- QScreenDriverPlugin class, using the QScreenDriverFactory class to
- dynamically load the driver into the application, but there should
- only be one screen object per application.
-
- The QLinuxFbScreen class provides the cache() function allocating
- off-screen graphics memory, and the complementary uncache()
- function releasing the allocated memory. The latter function will
- first sync the graphics card to ensure the memory isn't still
- being used by a command in the graphics card FIFO queue. The
- deleteEntry() function deletes the given memory block without such
- synchronization. Given the screen instance and client id, the
- memory can also be released using the clearCache() function, but
- this should only be necessary if a client exits abnormally.
-
- In addition, when in paletted graphics modes, the set() function
- provides the possibility of setting a specified color index to a
- given RGB value.
-
- The QLinuxFbScreen class also acts as a factory for the
- unaccelerated screen cursor and the unaccelerated raster-based
- implementation of QPaintEngine (\c QRasterPaintEngine);
- accelerated drivers for Linux should derive from this class.
-
- \sa QScreen, QScreenDriverPlugin, {Running Applications}
-*/
-
-/*!
- \fn bool QLinuxFbScreen::useOffscreen()
- \internal
-*/
-
-// Unaccelerated screen/driver setup. Can be overridden by accelerated
-// drivers
-
-/*!
- \fn QLinuxFbScreen::QLinuxFbScreen(int displayId)
-
- Constructs a QLinuxFbScreen object. The \a displayId argument
- identifies the Qt for Embedded Linux server to connect to.
-*/
-
-QLinuxFbScreen::QLinuxFbScreen(int display_id)
- : QScreen(display_id, LinuxFBClass), d_ptr(new QLinuxFbScreenPrivate)
-{
- canaccel=false;
- clearCacheFunc = &clearCache;
-#ifdef QT_QWS_CLIENTBLIT
- setSupportsBlitInClients(true);
-#endif
-}
-
-/*!
- Destroys this QLinuxFbScreen object.
-*/
-
-QLinuxFbScreen::~QLinuxFbScreen()
-{
-}
-
-/*!
- \reimp
-
- This is called by \l{Qt for Embedded Linux} clients to map in the framebuffer.
- It should be reimplemented by accelerated drivers to map in
- graphics card registers; those drivers should then call this
- function in order to set up offscreen memory management. The
- device is specified in \a displaySpec; e.g. "/dev/fb".
-
- \sa disconnect()
-*/
-
-bool QLinuxFbScreen::connect(const QString &displaySpec)
-{
- d_ptr->displaySpec = displaySpec;
-
- const QStringList args = displaySpec.split(QLatin1Char(':'));
-
- if (args.contains(QLatin1String("nographicsmodeswitch")))
- d_ptr->doGraphicsMode = false;
-
-#ifdef QT_QWS_DEPTH_GENERIC
- if (args.contains(QLatin1String("genericcolors")))
- d_ptr->doGenericColors = true;
-#endif
-
- QRegExp ttyRegExp(QLatin1String("tty=(.*)"));
- if (args.indexOf(ttyRegExp) != -1)
- d_ptr->ttyDevice = ttyRegExp.cap(1);
-
-#if Q_BYTE_ORDER == Q_BIG_ENDIAN
-#ifndef QT_QWS_FRAMEBUFFER_LITTLE_ENDIAN
- if (args.contains(QLatin1String("littleendian")))
-#endif
- QScreen::setFrameBufferLittleEndian(true);
-#endif
-
- QString dev = QLatin1String("/dev/fb0");
- foreach(QString d, args) {
- if (d.startsWith(QLatin1Char('/'))) {
- dev = d;
- break;
- }
- }
-
- if (access(dev.toLatin1().constData(), R_OK|W_OK) == 0)
- d_ptr->fd = QT_OPEN(dev.toLatin1().constData(), O_RDWR);
- if (d_ptr->fd == -1) {
- if (QApplication::type() == QApplication::GuiServer) {
- perror("QScreenLinuxFb::connect");
- qCritical("Error opening framebuffer device %s", qPrintable(dev));
- return false;
- }
- if (access(dev.toLatin1().constData(), R_OK) == 0)
- d_ptr->fd = QT_OPEN(dev.toLatin1().constData(), O_RDONLY);
- }
-
- ::fb_fix_screeninfo finfo;
- ::fb_var_screeninfo vinfo;
- //#######################
- // Shut up Valgrind
- memset(&vinfo, 0, sizeof(vinfo));
- memset(&finfo, 0, sizeof(finfo));
- //#######################
-
- /* Get fixed screen information */
- if (d_ptr->fd != -1 && ioctl(d_ptr->fd, FBIOGET_FSCREENINFO, &finfo)) {
- perror("QLinuxFbScreen::connect");
- qWarning("Error reading fixed information");
- return false;
- }
-
- d_ptr->driverType = strcmp(finfo.id, "8TRACKFB") ? GenericDriver : EInk8Track;
-
- if (finfo.type == FB_TYPE_VGA_PLANES) {
- qWarning("VGA16 video mode not supported");
- return false;
- }
-
- /* Get variable screen information */
- if (d_ptr->fd != -1 && ioctl(d_ptr->fd, FBIOGET_VSCREENINFO, &vinfo)) {
- perror("QLinuxFbScreen::connect");
- qWarning("Error reading variable information");
- return false;
- }
-
- fixupScreenInfo(finfo, vinfo);
-
- grayscale = vinfo.grayscale;
- d = vinfo.bits_per_pixel;
- if (d == 24) {
- d = vinfo.red.length + vinfo.green.length + vinfo.blue.length;
- if (d <= 0)
- d = 24; // reset if color component lengths are not reported
- } else if (d == 16) {
- d = vinfo.red.length + vinfo.green.length + vinfo.blue.length;
- if (d <= 0)
- d = 16;
- }
- lstep = finfo.line_length;
-
- int xoff = vinfo.xoffset;
- int yoff = vinfo.yoffset;
- const char* qwssize;
- if((qwssize=::getenv("QWS_SIZE")) && sscanf(qwssize,"%dx%d",&w,&h)==2) {
- if (d_ptr->fd != -1) {
- if ((uint)w > vinfo.xres) w = vinfo.xres;
- if ((uint)h > vinfo.yres) h = vinfo.yres;
- }
- dw=w;
- dh=h;
- 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;
- }
-
- if (w == 0 || h == 0) {
- qWarning("QScreenLinuxFb::connect(): Unable to find screen geometry, "
- "will use 320x240.");
- dw = w = 320;
- dh = h = 240;
- }
-
- setPixelFormat(vinfo);
-
- // Handle display physical size spec.
- QStringList displayArgs = displaySpec.split(QLatin1Char(':'));
- QRegExp mmWidthRx(QLatin1String("mmWidth=?(\\d+)"));
- int dimIdxW = displayArgs.indexOf(mmWidthRx);
- QRegExp mmHeightRx(QLatin1String("mmHeight=?(\\d+)"));
- int dimIdxH = displayArgs.indexOf(mmHeightRx);
- if (dimIdxW >= 0) {
- mmWidthRx.exactMatch(displayArgs.at(dimIdxW));
- physWidth = mmWidthRx.cap(1).toInt();
- if (dimIdxH < 0)
- physHeight = dh*physWidth/dw;
- }
- if (dimIdxH >= 0) {
- mmHeightRx.exactMatch(displayArgs.at(dimIdxH));
- physHeight = mmHeightRx.cap(1).toInt();
- if (dimIdxW < 0)
- physWidth = dw*physHeight/dh;
- }
- if (dimIdxW < 0 && dimIdxH < 0) {
- if (vinfo.width != 0 && vinfo.height != 0
- && vinfo.width != UINT_MAX && vinfo.height != UINT_MAX) {
- physWidth = vinfo.width;
- physHeight = vinfo.height;
- } else {
- const int dpi = 72;
- physWidth = qRound(dw * 25.4 / dpi);
- physHeight = qRound(dh * 25.4 / dpi);
- }
- }
-
- dataoffset = yoff * lstep + xoff * d / 8;
- //qDebug("Using %dx%dx%d screen",w,h,d);
-
- /* Figure out the size of the screen in bytes */
- size = h * lstep;
-
- mapsize = finfo.smem_len;
-
- data = (unsigned char *)-1;
- if (d_ptr->fd != -1)
- data = (unsigned char *)mmap(0, mapsize, PROT_READ | PROT_WRITE,
- MAP_SHARED, d_ptr->fd, 0);
-
- if ((long)data == -1) {
- if (QApplication::type() == QApplication::GuiServer) {
- perror("QLinuxFbScreen::connect");
- qWarning("Error: failed to map framebuffer device to memory.");
- return false;
- }
- data = 0;
- } else {
- data += dataoffset;
- }
-
- canaccel = useOffscreen();
- if(canaccel)
- setupOffScreen();
-
- // Now read in palette
- if((vinfo.bits_per_pixel==8) || (vinfo.bits_per_pixel==4)) {
- screencols= (vinfo.bits_per_pixel==8) ? 256 : 16;
- int loopc;
- ::fb_cmap startcmap;
- startcmap.start=0;
- startcmap.len=screencols;
- startcmap.red=(unsigned short int *)
- malloc(sizeof(unsigned short int)*screencols);
- startcmap.green=(unsigned short int *)
- malloc(sizeof(unsigned short int)*screencols);
- startcmap.blue=(unsigned short int *)
- malloc(sizeof(unsigned short int)*screencols);
- startcmap.transp=(unsigned short int *)
- malloc(sizeof(unsigned short int)*screencols);
- if (d_ptr->fd == -1 || ioctl(d_ptr->fd, FBIOGETCMAP, &startcmap)) {
- perror("QLinuxFbScreen::connect");
- qWarning("Error reading palette from framebuffer, using default palette");
- createPalette(startcmap, vinfo, finfo);
- }
- int bits_used = 0;
- for(loopc=0;loopc<screencols;loopc++) {
- screenclut[loopc]=qRgb(startcmap.red[loopc] >> 8,
- startcmap.green[loopc] >> 8,
- startcmap.blue[loopc] >> 8);
- bits_used |= startcmap.red[loopc]
- | startcmap.green[loopc]
- | startcmap.blue[loopc];
- }
- // WORKAROUND: Some framebuffer drivers only return 8 bit
- // color values, so we need to not bit shift them..
- if ((bits_used & 0x00ff) && !(bits_used & 0xff00)) {
- for(loopc=0;loopc<screencols;loopc++) {
- screenclut[loopc] = qRgb(startcmap.red[loopc],
- startcmap.green[loopc],
- startcmap.blue[loopc]);
- }
- qWarning("8 bits cmap returned due to faulty FB driver, colors corrected");
- }
- free(startcmap.red);
- free(startcmap.green);
- free(startcmap.blue);
- free(startcmap.transp);
- } else {
- screencols=0;
- }
-
- return true;
-}
-
-/*!
- \reimp
-
- This unmaps the framebuffer.
-
- \sa connect()
-*/
-
-void QLinuxFbScreen::disconnect()
-{
- data -= dataoffset;
- if (data)
- munmap((char*)data,mapsize);
- close(d_ptr->fd);
-}
-
-// #define DEBUG_VINFO
-
-void QLinuxFbScreen::createPalette(fb_cmap &cmap, fb_var_screeninfo &vinfo, fb_fix_screeninfo &finfo)
-{
- if((vinfo.bits_per_pixel==8) || (vinfo.bits_per_pixel==4)) {
- screencols= (vinfo.bits_per_pixel==8) ? 256 : 16;
- cmap.start=0;
- cmap.len=screencols;
- cmap.red=(unsigned short int *)
- malloc(sizeof(unsigned short int)*screencols);
- cmap.green=(unsigned short int *)
- malloc(sizeof(unsigned short int)*screencols);
- cmap.blue=(unsigned short int *)
- malloc(sizeof(unsigned short int)*screencols);
- cmap.transp=(unsigned short int *)
- malloc(sizeof(unsigned short int)*screencols);
-
- if (screencols==16) {
- if (finfo.type == FB_TYPE_PACKED_PIXELS) {
- // We'll setup a grayscale cmap for 4bpp linear
- int val = 0;
- for (int idx = 0; idx < 16; ++idx, val += 17) {
- cmap.red[idx] = (val<<8)|val;
- cmap.green[idx] = (val<<8)|val;
- cmap.blue[idx] = (val<<8)|val;
- screenclut[idx]=qRgb(val, val, val);
- }
- } else {
- // Default 16 colour palette
- // Green is now trolltech green so certain images look nicer
- // black d_gray l_gray white red green blue cyan magenta yellow
- unsigned char reds[16] = { 0x00, 0x7F, 0xBF, 0xFF, 0xFF, 0xA2, 0x00, 0xFF, 0xFF, 0x00, 0x7F, 0x7F, 0x00, 0x00, 0x00, 0x82 };
- unsigned char greens[16] = { 0x00, 0x7F, 0xBF, 0xFF, 0x00, 0xC5, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x7F, 0x7F, 0x7F };
- unsigned char blues[16] = { 0x00, 0x7F, 0xBF, 0xFF, 0x00, 0x11, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x7F, 0x7F, 0x7F, 0x00, 0x00 };
-
- for (int idx = 0; idx < 16; ++idx) {
- cmap.red[idx] = ((reds[idx]) << 8)|reds[idx];
- cmap.green[idx] = ((greens[idx]) << 8)|greens[idx];
- cmap.blue[idx] = ((blues[idx]) << 8)|blues[idx];
- cmap.transp[idx] = 0;
- screenclut[idx]=qRgb(reds[idx], greens[idx], blues[idx]);
- }
- }
- } else {
- if (grayscale) {
- // Build grayscale palette
- int i;
- for(i=0;i<screencols;++i) {
- int bval = screencols == 256 ? i : (i << 4);
- ushort val = (bval << 8) | bval;
- cmap.red[i] = val;
- cmap.green[i] = val;
- cmap.blue[i] = val;
- cmap.transp[i] = 0;
- screenclut[i] = qRgb(bval,bval,bval);
- }
- } else {
- // 6x6x6 216 color cube
- int idx = 0;
- for(int ir = 0x0; ir <= 0xff; ir+=0x33) {
- for(int ig = 0x0; ig <= 0xff; ig+=0x33) {
- for(int ib = 0x0; ib <= 0xff; ib+=0x33) {
- cmap.red[idx] = (ir << 8)|ir;
- cmap.green[idx] = (ig << 8)|ig;
- cmap.blue[idx] = (ib << 8)|ib;
- cmap.transp[idx] = 0;
- screenclut[idx]=qRgb(ir, ig, ib);
- ++idx;
- }
- }
- }
- // Fill in rest with 0
- for (int loopc=0; loopc<40; ++loopc) {
- screenclut[idx]=0;
- ++idx;
- }
- screencols=idx;
- }
- }
- } else if(finfo.visual==FB_VISUAL_DIRECTCOLOR) {
- cmap.start=0;
- int rbits=0,gbits=0,bbits=0;
- switch (vinfo.bits_per_pixel) {
- case 8:
- rbits=vinfo.red.length;
- gbits=vinfo.green.length;
- bbits=vinfo.blue.length;
- if(rbits==0 && gbits==0 && bbits==0) {
- // cyber2000 driver bug hack
- rbits=3;
- gbits=3;
- bbits=2;
- }
- break;
- case 15:
- rbits=5;
- gbits=5;
- bbits=5;
- break;
- case 16:
- rbits=5;
- gbits=6;
- bbits=5;
- break;
- case 18:
- case 19:
- rbits=6;
- gbits=6;
- bbits=6;
- break;
- case 24: case 32:
- rbits=gbits=bbits=8;
- break;
- }
- screencols=cmap.len=1<<qMax(rbits,qMax(gbits,bbits));
- cmap.red=(unsigned short int *)
- malloc(sizeof(unsigned short int)*256);
- cmap.green=(unsigned short int *)
- malloc(sizeof(unsigned short int)*256);
- cmap.blue=(unsigned short int *)
- malloc(sizeof(unsigned short int)*256);
- cmap.transp=(unsigned short int *)
- malloc(sizeof(unsigned short int)*256);
- for(unsigned int i = 0x0; i < cmap.len; i++) {
- cmap.red[i] = i*65535/((1<<rbits)-1);
- cmap.green[i] = i*65535/((1<<gbits)-1);
- cmap.blue[i] = i*65535/((1<<bbits)-1);
- cmap.transp[i] = 0;
- }
- }
-}
-
-/*!
- \reimp
-
- This is called by the \l{Qt for Embedded Linux} server at startup time.
- It turns off console blinking, sets up the color palette, enables write
- combining on the framebuffer and initialises the off-screen memory
- manager.
-*/
-
-bool QLinuxFbScreen::initDevice()
-{
- d_ptr->openTty();
-
- // Grab current mode so we can reset it
- fb_var_screeninfo vinfo;
- fb_fix_screeninfo finfo;
- //#######################
- // Shut up Valgrind
- memset(&vinfo, 0, sizeof(vinfo));
- memset(&finfo, 0, sizeof(finfo));
- //#######################
-
- if (ioctl(d_ptr->fd, FBIOGET_VSCREENINFO, &vinfo)) {
- perror("QLinuxFbScreen::initDevice");
- qFatal("Error reading variable information in card init");
- return false;
- }
-
-#ifdef DEBUG_VINFO
- qDebug("Greyscale %d",vinfo.grayscale);
- qDebug("Nonstd %d",vinfo.nonstd);
- qDebug("Red %d %d %d",vinfo.red.offset,vinfo.red.length,
- vinfo.red.msb_right);
- qDebug("Green %d %d %d",vinfo.green.offset,vinfo.green.length,
- vinfo.green.msb_right);
- qDebug("Blue %d %d %d",vinfo.blue.offset,vinfo.blue.length,
- vinfo.blue.msb_right);
- qDebug("Transparent %d %d %d",vinfo.transp.offset,vinfo.transp.length,
- vinfo.transp.msb_right);
-#endif
-
- if (ioctl(d_ptr->fd, FBIOGET_FSCREENINFO, &finfo)) {
- perror("QLinuxFbScreen::initDevice");
- qCritical("Error reading fixed information in card init");
- // It's not an /error/ as such, though definitely a bad sign
- // so we return true
- return true;
- }
-
- fixupScreenInfo(finfo, vinfo);
-
- d_ptr->startupw=vinfo.xres;
- d_ptr->startuph=vinfo.yres;
- d_ptr->startupd=vinfo.bits_per_pixel;
- grayscale = vinfo.grayscale;
-
-#ifdef __i386__
- // Now init mtrr
- if(!::getenv("QWS_NOMTRR")) {
- int mfd=QT_OPEN("/proc/mtrr",O_WRONLY,0);
- // MTRR entry goes away when file is closed - i.e.
- // hopefully when QWS is killed
- if(mfd != -1) {
- mtrr_sentry sentry;
- sentry.base=(unsigned long int)finfo.smem_start;
- //qDebug("Physical framebuffer address %p",(void*)finfo.smem_start);
- // Size needs to be in 4k chunks, but that's not always
- // what we get thanks to graphics card registers. Write combining
- // these is Not Good, so we write combine what we can
- // (which is not much - 4 megs on an 8 meg card, it seems)
- unsigned int size=finfo.smem_len;
- size=size >> 22;
- size=size << 22;
- sentry.size=size;
- sentry.type=MTRR_TYPE_WRCOMB;
- if(ioctl(mfd,MTRRIOC_ADD_ENTRY,&sentry)==-1) {
- //printf("Couldn't add mtrr entry for %lx %lx, %s\n",
- //sentry.base,sentry.size,strerror(errno));
- }
- }
-
- // Should we close mfd here?
- //QT_CLOSE(mfd);
- }
-#endif
- if ((vinfo.bits_per_pixel==8) || (vinfo.bits_per_pixel==4) || (finfo.visual==FB_VISUAL_DIRECTCOLOR))
- {
- fb_cmap cmap;
- createPalette(cmap, vinfo, finfo);
- if (ioctl(d_ptr->fd, FBIOPUTCMAP, &cmap)) {
- perror("QLinuxFbScreen::initDevice");
- qWarning("Error writing palette to framebuffer");
- }
- free(cmap.red);
- free(cmap.green);
- free(cmap.blue);
- free(cmap.transp);
- }
-
- if (canaccel) {
- *entryp=0;
- *lowest = mapsize;
- insert_entry(*entryp, *lowest, *lowest); // dummy entry to mark start
- }
-
- shared->fifocount = 0;
- shared->buffer_offset = 0xffffffff; // 0 would be a sensible offset (screen)
- shared->linestep = 0;
- shared->cliptop = 0xffffffff;
- shared->clipleft = 0xffffffff;
- shared->clipright = 0xffffffff;
- shared->clipbottom = 0xffffffff;
- shared->rop = 0xffffffff;
-
-#ifdef QT_QWS_DEPTH_GENERIC
- if (pixelFormat() == QImage::Format_Invalid && screencols == 0
- && d_ptr->doGenericColors)
- {
- qt_set_generic_blit(this, vinfo.bits_per_pixel,
- vinfo.red.length, vinfo.green.length,
- vinfo.blue.length, vinfo.transp.length,
- vinfo.red.offset, vinfo.green.offset,
- vinfo.blue.offset, vinfo.transp.offset);
- }
-#endif
-
-#ifndef QT_NO_QWS_CURSOR
- QScreenCursor::initSoftwareCursor();
-#endif
- blank(false);
-
- return true;
-}
-
-/*
- The offscreen memory manager's list of entries is stored at the bottom
- of the offscreen memory area and consistes of a series of QPoolEntry's,
- each of which keep track of a block of allocated memory. Unallocated memory
- is implicitly indicated by the gap between blocks indicated by QPoolEntry's.
- The memory manager looks through any unallocated memory before the end
- of currently-allocated memory to see if a new block will fit in the gap;
- if it doesn't it allocated it from the end of currently-allocated memory.
- Memory is allocated from the top of the framebuffer downwards; if it hits
- the list of entries then offscreen memory is full and further allocations
- are made from main RAM (and hence unaccelerated). Allocated memory can
- be seen as a sort of upside-down stack; lowest keeps track of the
- bottom of the stack.
-*/
-
-void QLinuxFbScreen::delete_entry(int pos)
-{
- if (pos > *entryp || pos < 0) {
- qWarning("Attempt to delete odd pos! %d %d", pos, *entryp);
- return;
- }
-
-#ifdef DEBUG_CACHE
- qDebug("Remove entry: %d", pos);
-#endif
-
- QPoolEntry *qpe = &entries[pos];
- if (qpe->start <= *lowest) {
- // Lowest goes up again
- *lowest = entries[pos-1].start;
-#ifdef DEBUG_CACHE
- qDebug(" moved lowest to %d", *lowest);
-#endif
- }
-
- (*entryp)--;
- if (pos == *entryp)
- return;
-
- int size = (*entryp)-pos;
- memmove(&entries[pos], &entries[pos+1], size*sizeof(QPoolEntry));
-}
-
-void QLinuxFbScreen::insert_entry(int pos, int start, int end)
-{
- if (pos > *entryp) {
- qWarning("Attempt to insert odd pos! %d %d",pos,*entryp);
- return;
- }
-
-#ifdef DEBUG_CACHE
- qDebug("Insert entry: %d, %d -> %d", pos, start, end);
-#endif
-
- if (start < (int)*lowest) {
- *lowest = start;
-#ifdef DEBUG_CACHE
- qDebug(" moved lowest to %d", *lowest);
-#endif
- }
-
- if (pos == *entryp) {
- entries[pos].start = start;
- entries[pos].end = end;
- entries[pos].clientId = qws_client_id;
- (*entryp)++;
- return;
- }
-
- int size=(*entryp)-pos;
- memmove(&entries[pos+1],&entries[pos],size*sizeof(QPoolEntry));
- entries[pos].start=start;
- entries[pos].end=end;
- entries[pos].clientId=qws_client_id;
- (*entryp)++;
-}
-
-/*!
- \fn uchar * QLinuxFbScreen::cache(int amount)
-
- Requests the specified \a amount of offscreen graphics card memory
- from the memory manager, and returns a pointer to the data within
- the framebuffer (or 0 if there is no free memory).
-
- Note that the display is locked while memory is allocated in order to
- preserve the memory pool's integrity.
-
- Use the QScreen::onCard() function to retrieve an offset (in
- bytes) from the start of graphics card memory for the returned
- pointer.
-
- \sa uncache(), clearCache(), deleteEntry()
-*/
-
-uchar * QLinuxFbScreen::cache(int amount)
-{
- if (!canaccel || entryp == 0)
- return 0;
-
- qt_fbdpy->grab();
-
- int startp = cacheStart + (*entryp+1) * sizeof(QPoolEntry);
- if (startp >= (int)*lowest) {
- // We don't have room for another cache QPoolEntry.
-#ifdef DEBUG_CACHE
- qDebug("No room for pool entry in VRAM");
-#endif
- qt_fbdpy->ungrab();
- return 0;
- }
-
- int align = pixmapOffsetAlignment();
-
- if (*entryp > 1) {
- // Try to find a gap in the allocated blocks.
- for (int loopc = 0; loopc < *entryp-1; loopc++) {
- int freestart = entries[loopc+1].end;
- int freeend = entries[loopc].start;
- if (freestart != freeend) {
- while (freestart % align) {
- freestart++;
- }
- int len=freeend-freestart;
- if (len >= amount) {
- insert_entry(loopc+1, freestart, freestart+amount);
- qt_fbdpy->ungrab();
- return data+freestart;
- }
- }
- }
- }
-
- // No free blocks in already-taken memory; get some more
- // if we can
- int newlowest = (*lowest)-amount;
- if (newlowest % align) {
- newlowest -= align;
- while (newlowest % align) {
- newlowest++;
- }
- }
- if (startp >= newlowest) {
- qt_fbdpy->ungrab();
-#ifdef DEBUG_CACHE
- qDebug("No VRAM available for %d bytes", amount);
-#endif
- return 0;
- }
- insert_entry(*entryp, newlowest, *lowest);
- qt_fbdpy->ungrab();
-
- return data + newlowest;
-}
-
-/*!
- \fn void QLinuxFbScreen::uncache(uchar * memoryBlock)
-
- Deletes the specified \a memoryBlock allocated from the graphics
- card memory.
-
- Note that the display is locked while memory is unallocated in
- order to preserve the memory pool's integrity.
-
- This function will first sync the graphics card to ensure the
- memory isn't still being used by a command in the graphics card
- FIFO queue. It is possible to speed up a driver by overriding this
- function to avoid syncing. For example, the driver might delay
- deleting the memory until it detects that all commands dealing
- with the memory are no longer in the queue. Note that it will then
- be up to the driver to ensure that the specified \a memoryBlock no
- longer is being used.
-
- \sa cache(), deleteEntry(), clearCache()
- */
-void QLinuxFbScreen::uncache(uchar * c)
-{
- // need to sync graphics card
-
- deleteEntry(c);
-}
-
-/*!
- \fn void QLinuxFbScreen::deleteEntry(uchar * memoryBlock)
-
- Deletes the specified \a memoryBlock allocated from the graphics
- card memory.
-
- \sa uncache(), cache(), clearCache()
-*/
-void QLinuxFbScreen::deleteEntry(uchar * c)
-{
- qt_fbdpy->grab();
- unsigned long pos=(unsigned long)c;
- pos-=((unsigned long)data);
- unsigned int hold=(*entryp);
- for(unsigned int loopc=1;loopc<hold;loopc++) {
- if (entries[loopc].start==pos) {
- if (entries[loopc].clientId == qws_client_id)
- delete_entry(loopc);
- else
- qWarning("Attempt to delete client id %d cache entry",
- entries[loopc].clientId);
- qt_fbdpy->ungrab();
- return;
- }
- }
- qt_fbdpy->ungrab();
- qWarning("Attempt to delete unknown offset %ld",pos);
-}
-
-/*!
- Removes all entries from the cache for the specified screen \a
- instance and client identified by the given \a clientId.
-
- Calling this function should only be necessary if a client exits
- abnormally.
-
- \sa cache(), uncache(), deleteEntry()
-*/
-void QLinuxFbScreen::clearCache(QScreen *instance, int clientId)
-{
- QLinuxFbScreen *screen = (QLinuxFbScreen *)instance;
- if (!screen->canaccel || !screen->entryp)
- return;
- qt_fbdpy->grab();
- for (int loopc = 0; loopc < *(screen->entryp); loopc++) {
- if (screen->entries[loopc].clientId == clientId) {
- screen->delete_entry(loopc);
- loopc--;
- }
- }
- qt_fbdpy->ungrab();
-}
-
-
-void QLinuxFbScreen::setupOffScreen()
-{
- // Figure out position of offscreen memory
- // Set up pool entries pointer table and 64-bit align it
- int psize = size;
-
- // hw: this causes the limitation of cursors to 64x64
- // the cursor should rather use the normal pixmap mechanism
- psize += 4096; // cursor data
- psize += 8; // for alignment
- psize &= ~0x7; // align
-
- unsigned long pos = (unsigned long)data;
- pos += psize;
- entryp = ((int *)pos);
- lowest = ((unsigned int *)pos)+1;
- pos += (sizeof(int))*4;
- entries = (QPoolEntry *)pos;
-
- // beginning of offscreen memory available for pixmaps.
- cacheStart = psize + 4*sizeof(int) + sizeof(QPoolEntry);
-}
-
-/*!
- \reimp
-
- This is called by the \l{Qt for Embedded Linux} server when it shuts
- down, and should be inherited if you need to do any card-specific cleanup.
- The default version hides the screen cursor and reenables the blinking
- cursor and screen blanking.
-*/
-
-void QLinuxFbScreen::shutdownDevice()
-{
- // Causing crashes. Not needed.
- //setMode(startupw,startuph,startupd);
-/*
- if (startupd == 8) {
- ioctl(fd,FBIOPUTCMAP,startcmap);
- free(startcmap->red);
- free(startcmap->green);
- free(startcmap->blue);
- free(startcmap->transp);
- delete startcmap;
- startcmap = 0;
- }
-*/
- d_ptr->closeTty();
-}
-
-/*!
- \fn void QLinuxFbScreen::set(unsigned int index,unsigned int red,unsigned int green,unsigned int blue)
-
- Sets the specified color \a index to the specified RGB value, (\a
- red, \a green, \a blue), when in paletted graphics modes.
-*/
-
-void QLinuxFbScreen::set(unsigned int i,unsigned int r,unsigned int g,unsigned int b)
-{
- if (d_ptr->fd != -1) {
- fb_cmap cmap;
- cmap.start=i;
- cmap.len=1;
- cmap.red=(unsigned short int *)
- malloc(sizeof(unsigned short int)*256);
- cmap.green=(unsigned short int *)
- malloc(sizeof(unsigned short int)*256);
- cmap.blue=(unsigned short int *)
- malloc(sizeof(unsigned short int)*256);
- cmap.transp=(unsigned short int *)
- malloc(sizeof(unsigned short int)*256);
- cmap.red[0]=r << 8;
- cmap.green[0]=g << 8;
- cmap.blue[0]=b << 8;
- cmap.transp[0]=0;
- ioctl(d_ptr->fd, FBIOPUTCMAP, &cmap);
- free(cmap.red);
- free(cmap.green);
- free(cmap.blue);
- free(cmap.transp);
- }
- screenclut[i] = qRgb(r, g, b);
-}
-
-/*!
- \reimp
-
- Sets the framebuffer to a new resolution and bit depth. The width is
- in \a nw, the height is in \a nh, and the depth is in \a nd. After
- doing this any currently-existing paint engines will be invalid and the
- screen should be completely redrawn. In a multiple-process
- Embedded Qt situation you must signal all other applications to
- call setMode() to the same mode and redraw.
-*/
-
-void QLinuxFbScreen::setMode(int nw,int nh,int nd)
-{
- if (d_ptr->fd == -1)
- return;
-
- fb_fix_screeninfo finfo;
- fb_var_screeninfo vinfo;
- //#######################
- // Shut up Valgrind
- memset(&vinfo, 0, sizeof(vinfo));
- memset(&finfo, 0, sizeof(finfo));
- //#######################
-
- if (ioctl(d_ptr->fd, FBIOGET_VSCREENINFO, &vinfo)) {
- perror("QLinuxFbScreen::setMode");
- qFatal("Error reading variable information in mode change");
- }
-
- vinfo.xres=nw;
- vinfo.yres=nh;
- vinfo.bits_per_pixel=nd;
-
- if (ioctl(d_ptr->fd, FBIOPUT_VSCREENINFO, &vinfo)) {
- perror("QLinuxFbScreen::setMode");
- qCritical("Error writing variable information in mode change");
- }
-
- if (ioctl(d_ptr->fd, FBIOGET_VSCREENINFO, &vinfo)) {
- perror("QLinuxFbScreen::setMode");
- qFatal("Error reading changed variable information in mode change");
- }
-
- if (ioctl(d_ptr->fd, FBIOGET_FSCREENINFO, &finfo)) {
- perror("QLinuxFbScreen::setMode");
- qFatal("Error reading fixed information");
- }
-
- fixupScreenInfo(finfo, vinfo);
- disconnect();
- connect(d_ptr->displaySpec);
- exposeRegion(region(), 0);
-}
-
-// save the state of the graphics card
-// This is needed so that e.g. we can restore the palette when switching
-// between linux virtual consoles.
-
-/*!
- \reimp
-
- This doesn't do anything; accelerated drivers may wish to reimplement
- it to save graphics cards registers. It's called by the
- \l{Qt for Embedded Linux} server when the virtual console is switched.
-*/
-
-void QLinuxFbScreen::save()
-{
- // nothing to do.
-}
-
-
-// restore the state of the graphics card.
-/*!
- \reimp
-
- This is called when the virtual console is switched back to
- \l{Qt for Embedded Linux} and restores the palette.
-*/
-void QLinuxFbScreen::restore()
-{
- if (d_ptr->fd == -1)
- return;
-
- if ((d == 8) || (d == 4)) {
- fb_cmap cmap;
- cmap.start=0;
- cmap.len=screencols;
- cmap.red=(unsigned short int *)
- malloc(sizeof(unsigned short int)*256);
- cmap.green=(unsigned short int *)
- malloc(sizeof(unsigned short int)*256);
- cmap.blue=(unsigned short int *)
- malloc(sizeof(unsigned short int)*256);
- cmap.transp=(unsigned short int *)
- malloc(sizeof(unsigned short int)*256);
- for (int loopc = 0; loopc < screencols; loopc++) {
- cmap.red[loopc] = qRed(screenclut[loopc]) << 8;
- cmap.green[loopc] = qGreen(screenclut[loopc]) << 8;
- cmap.blue[loopc] = qBlue(screenclut[loopc]) << 8;
- cmap.transp[loopc] = 0;
- }
- ioctl(d_ptr->fd, FBIOPUTCMAP, &cmap);
- free(cmap.red);
- free(cmap.green);
- free(cmap.blue);
- free(cmap.transp);
- }
-}
-
-/*!
- \fn int QLinuxFbScreen::sharedRamSize(void * end)
- \internal
-*/
-
-// This works like the QScreenCursor code. end points to the end
-// of our shared structure, we return the amount of memory we reserved
-int QLinuxFbScreen::sharedRamSize(void * end)
-{
- shared=(QLinuxFb_Shared *)end;
- shared--;
- return sizeof(QLinuxFb_Shared);
-}
-
-/*!
- \reimp
-*/
-void QLinuxFbScreen::setDirty(const QRect &r)
-{
- if(d_ptr->driverType == EInk8Track) {
- // e-Ink displays need a trigger to actually show what is
- // in their framebuffer memory. The 8-Track driver does this
- // by adding custom IOCTLs - FBIO_EINK_DISP_PIC (0x46a2) takes
- // an argument specifying whether or not to flash the screen
- // while updating.
- // There doesn't seem to be a way to tell it to just update
- // a subset of the screen.
- if(r.left() == 0 && r.top() == 0 && r.width() == dw && r.height() == dh)
- ioctl(d_ptr->fd, 0x46a2, 1);
- else
- ioctl(d_ptr->fd, 0x46a2, 0);
- }
-}
-
-/*!
- \reimp
-*/
-void QLinuxFbScreen::blank(bool on)
-{
- if (d_ptr->blank == on)
- return;
-
-#if defined(QT_QWS_IPAQ)
- if (on)
- system("apm -suspend");
-#else
- if (d_ptr->fd == -1)
- return;
-// Some old kernel versions don't have this. These defines should go
-// away eventually
-#if defined(FBIOBLANK)
-#if defined(VESA_POWERDOWN) && defined(VESA_NO_BLANKING)
- ioctl(d_ptr->fd, FBIOBLANK, on ? VESA_POWERDOWN : VESA_NO_BLANKING);
-#else
- ioctl(d_ptr->fd, FBIOBLANK, on ? 1 : 0);
-#endif
-#endif
-#endif
-
- d_ptr->blank = on;
-}
-
-void QLinuxFbScreen::setPixelFormat(struct fb_var_screeninfo info)
-{
- const fb_bitfield rgba[4] = { info.red, info.green,
- info.blue, info.transp };
-
- QImage::Format format = QImage::Format_Invalid;
-
- switch (d) {
- case 32: {
- const fb_bitfield argb8888[4] = {{16, 8, 0}, {8, 8, 0},
- {0, 8, 0}, {24, 8, 0}};
- const fb_bitfield abgr8888[4] = {{0, 8, 0}, {8, 8, 0},
- {16, 8, 0}, {24, 8, 0}};
- if (memcmp(rgba, argb8888, 4 * sizeof(fb_bitfield)) == 0) {
- format = QImage::Format_ARGB32;
- } else if (memcmp(rgba, argb8888, 3 * sizeof(fb_bitfield)) == 0) {
- format = QImage::Format_RGB32;
- } else if (memcmp(rgba, abgr8888, 3 * sizeof(fb_bitfield)) == 0) {
- format = QImage::Format_RGB32;
- pixeltype = QScreen::BGRPixel;
- }
- break;
- }
- case 24: {
- const fb_bitfield rgb888[4] = {{16, 8, 0}, {8, 8, 0},
- {0, 8, 0}, {0, 0, 0}};
- const fb_bitfield bgr888[4] = {{0, 8, 0}, {8, 8, 0},
- {16, 8, 0}, {0, 0, 0}};
- if (memcmp(rgba, rgb888, 3 * sizeof(fb_bitfield)) == 0) {
- format = QImage::Format_RGB888;
- } else if (memcmp(rgba, bgr888, 3 * sizeof(fb_bitfield)) == 0) {
- format = QImage::Format_RGB888;
- pixeltype = QScreen::BGRPixel;
- }
- break;
- }
- case 18: {
- const fb_bitfield rgb666[4] = {{12, 6, 0}, {6, 6, 0},
- {0, 6, 0}, {0, 0, 0}};
- if (memcmp(rgba, rgb666, 3 * sizeof(fb_bitfield)) == 0)
- format = QImage::Format_RGB666;
- break;
- }
- case 16: {
- const fb_bitfield rgb565[4] = {{11, 5, 0}, {5, 6, 0},
- {0, 5, 0}, {0, 0, 0}};
- const fb_bitfield bgr565[4] = {{0, 5, 0}, {5, 6, 0},
- {11, 5, 0}, {0, 0, 0}};
- if (memcmp(rgba, rgb565, 3 * sizeof(fb_bitfield)) == 0) {
- format = QImage::Format_RGB16;
- } else if (memcmp(rgba, bgr565, 3 * sizeof(fb_bitfield)) == 0) {
- format = QImage::Format_RGB16;
- pixeltype = QScreen::BGRPixel;
- }
- break;
- }
- case 15: {
- const fb_bitfield rgb1555[4] = {{10, 5, 0}, {5, 5, 0},
- {0, 5, 0}, {15, 1, 0}};
- const fb_bitfield bgr1555[4] = {{0, 5, 0}, {5, 5, 0},
- {10, 5, 0}, {15, 1, 0}};
- if (memcmp(rgba, rgb1555, 3 * sizeof(fb_bitfield)) == 0) {
- format = QImage::Format_RGB555;
- } else if (memcmp(rgba, bgr1555, 3 * sizeof(fb_bitfield)) == 0) {
- format = QImage::Format_RGB555;
- pixeltype = QScreen::BGRPixel;
- }
- break;
- }
- case 12: {
- const fb_bitfield rgb444[4] = {{8, 4, 0}, {4, 4, 0},
- {0, 4, 0}, {0, 0, 0}};
- if (memcmp(rgba, rgb444, 3 * sizeof(fb_bitfield)) == 0)
- format = QImage::Format_RGB444;
- break;
- }
- case 8:
- break;
- case 1:
- format = QImage::Format_Mono; //###: LSB???
- break;
- default:
- break;
- }
-
- QScreen::setPixelFormat(format);
-}
-
-bool QLinuxFbScreen::useOffscreen()
-{
- // Not done for 8Track because on e-Ink displays,
- // everything is offscreen anyway
- if (d_ptr->driverType == EInk8Track || ((mapsize - size) < 16*1024))
- return false;
-
- return true;
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_QWS_LINUXFB
diff --git a/src/gui/embedded/qscreenlinuxfb_qws.h b/src/gui/embedded/qscreenlinuxfb_qws.h
deleted file mode 100644
index 9f45beff27..0000000000
--- a/src/gui/embedded/qscreenlinuxfb_qws.h
+++ /dev/null
@@ -1,135 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSCREENLINUXFB_QWS_H
-#define QSCREENLINUXFB_QWS_H
-
-#include <QtGui/qscreen_qws.h>
-
-struct fb_cmap;
-struct fb_var_screeninfo;
-struct fb_fix_screeninfo;
-
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_QWS_LINUXFB
-
-class QLinuxFb_Shared
-{
-public:
- volatile int lastop;
- volatile int optype;
- volatile int fifocount; // Accel drivers only
- volatile int fifomax;
- volatile int forecol; // Foreground colour caching
- volatile unsigned int buffer_offset; // Destination
- volatile int linestep;
- volatile int cliptop; // Clip rectangle
- volatile int clipleft;
- volatile int clipright;
- volatile int clipbottom;
- volatile unsigned int rop;
-
-};
-
-class QLinuxFbScreenPrivate;
-
-class Q_GUI_EXPORT QLinuxFbScreen : public QScreen
-{
-public:
- explicit QLinuxFbScreen(int display_id);
- virtual ~QLinuxFbScreen();
-
- virtual bool initDevice();
- virtual bool connect(const QString &displaySpec);
-
- virtual bool useOffscreen();
-
- enum DriverTypes { GenericDriver, EInk8Track };
-
- virtual void disconnect();
- virtual void shutdownDevice();
- virtual void setMode(int,int,int);
- virtual void save();
- virtual void restore();
- virtual void blank(bool on);
- virtual void set(unsigned int,unsigned int,unsigned int,unsigned int);
- virtual uchar * cache(int);
- virtual void uncache(uchar *);
- virtual int sharedRamSize(void *);
- virtual void setDirty(const QRect&);
-
- QLinuxFb_Shared * shared;
-
-protected:
-
- void deleteEntry(uchar *);
-
- bool canaccel;
- int dataoffset;
- int cacheStart;
-
- virtual void fixupScreenInfo(fb_fix_screeninfo &finfo, fb_var_screeninfo &vinfo);
- static void clearCache(QScreen *instance, int);
-
-private:
-
- void delete_entry(int);
- void insert_entry(int,int,int);
- void setupOffScreen();
- void createPalette(fb_cmap &cmap, fb_var_screeninfo &vinfo, fb_fix_screeninfo &finfo);
- void setPixelFormat(struct fb_var_screeninfo);
-
- QLinuxFbScreenPrivate *d_ptr;
-};
-
-#endif // QT_NO_QWS_LINUXFB
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QSCREENLINUXFB_QWS_H
diff --git a/src/gui/embedded/qscreenmulti_qws.cpp b/src/gui/embedded/qscreenmulti_qws.cpp
deleted file mode 100644
index 303b7b807a..0000000000
--- a/src/gui/embedded/qscreenmulti_qws.cpp
+++ /dev/null
@@ -1,486 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qscreenmulti_qws_p.h"
-
-#ifndef QT_NO_QWS_MULTISCREEN
-
-#include <qlist.h>
-#include <qstringlist.h>
-#include <qwidget.h>
-#include <qdebug.h>
-
-QT_BEGIN_NAMESPACE
-
-#ifndef QT_NO_QWS_CURSOR
-
-class QMultiScreenCursor : public QScreenCursor
-{
-public:
- QMultiScreenCursor() : currentCursor(qt_screencursor) { enable = false; }
- ~QMultiScreenCursor() { qt_screencursor = 0; }
-
- void set(const QImage &image, int hotx, int hoty);
- void move(int x, int y);
- void show();
- void hide();
-
- void addCursor(QScreenCursor *cursor);
-
-private:
- void setCurrentCursor(QScreenCursor *newCursor);
-
- QScreenCursor *currentCursor;
- QList<QScreenCursor*> cursors;
-};
-
-void QMultiScreenCursor::set(const QImage &image, int hotx, int hoty)
-{
- QScreenCursor::set(image, hotx, hoty);
- if (currentCursor)
- currentCursor->set(image, hotx, hoty);
-}
-
-void QMultiScreenCursor::setCurrentCursor(QScreenCursor *newCursor)
-{
- *((QScreenCursor*)this) = *newCursor;
- currentCursor = newCursor;
-}
-
-// XXX: this is a mess!
-void QMultiScreenCursor::move(int x, int y)
-{
- const int oldIndex = qt_screen->subScreenIndexAt(pos);
- QScreenCursor::move(x, y); // updates pos
- const int newIndex = qt_screen->subScreenIndexAt(pos);
-
- if (!currentCursor && oldIndex != -1)
- setCurrentCursor(cursors.at(oldIndex));
- QScreenCursor *oldCursor = currentCursor;
-
- if (oldIndex != -1) {
- const QScreen *oldScreen = qt_screen->subScreens().at(oldIndex);
- if (newIndex == -1 || oldScreen->region().contains(pos)) {
- oldCursor->move(x, y);
- return;
- }
- }
-
- if (newIndex != -1) {
- QScreenCursor *newCursor = cursors.at(newIndex);
- newCursor->set(cursor, hotspot.x(), hotspot.y());
-
- if (oldCursor) {
- if (oldCursor->isVisible())
- newCursor->show();
- oldCursor->hide();
- }
-
- newCursor->move(x, y);
-
- setCurrentCursor(newCursor);
- }
-}
-
-void QMultiScreenCursor::show()
-{
- if (currentCursor)
- currentCursor->show();
-}
-
-void QMultiScreenCursor::hide()
-{
- if (currentCursor)
- currentCursor->hide();
-}
-
-void QMultiScreenCursor::addCursor(QScreenCursor *cursor)
-{
- cursors.append(cursor);
-}
-
-#endif
-
-class QMultiScreenPrivate
-{
-public:
- QMultiScreenPrivate()
-#ifndef QT_NO_QWS_CURSOR
- : cursor(0)
-#endif
- {}
- ~QMultiScreenPrivate()
- {
-#ifndef QT_NO_QWS_CURSOR
- delete cursor;
-#endif
- }
-
- QList<QScreen*> screens;
- QRegion region;
-#ifndef QT_NO_QWS_CURSOR
- QMultiScreenCursor *cursor;
-#endif
-};
-
-QMultiScreen::QMultiScreen(int displayId)
- : QScreen(displayId, MultiClass), d_ptr(new QMultiScreenPrivate)
-{
-}
-
-QMultiScreen::~QMultiScreen()
-{
- delete d_ptr;
-}
-
-bool QMultiScreen::initDevice()
-{
- bool ok = true;
-
-#ifndef QT_NO_QWS_CURSOR
- d_ptr->cursor = new QMultiScreenCursor;
-#endif
-
- const int n = d_ptr->screens.count();
- for (int i = 0; i < n; ++i) {
- QScreen *s = d_ptr->screens.at(i);
- ok = s->initDevice() && ok;
-#ifndef QT_NO_QWS_CURSOR
- d_ptr->cursor->addCursor(qt_screencursor); // XXX
-#endif
- }
-
-#ifndef QT_NO_QWS_CURSOR
- // XXX
- qt_screencursor = d_ptr->cursor;
-#endif
-
- return ok;
-}
-
-static int getDisplayId(const QString &spec)
-{
- QRegExp regexp(QLatin1String(":(\\d+)\\b"));
- if (regexp.lastIndexIn(spec) != -1) {
- const QString capture = regexp.cap(1);
- return capture.toInt();
- }
- return 0;
-}
-
-static QPoint filterDisplayOffset(QString &spec)
-{
- QRegExp regexp(QLatin1String(":offset=(\\d+),(\\d+)\\b"));
- if (regexp.indexIn(spec) == -1)
- return QPoint();
-
- const int x = regexp.cap(1).toInt();
- const int y = regexp.cap(2).toInt();
- spec.remove(regexp.pos(0), regexp.matchedLength());
- return QPoint(x, y);
-}
-
-bool QMultiScreen::connect(const QString &displaySpec)
-{
- QString dSpec = displaySpec;
- if (dSpec.startsWith(QLatin1String("Multi:"), Qt::CaseInsensitive))
- dSpec = dSpec.mid(QString::fromLatin1("Multi:").size());
-
- const QString displayIdSpec = QString::fromLatin1(" :%1").arg(displayId);
- if (dSpec.endsWith(displayIdSpec))
- dSpec = dSpec.left(dSpec.size() - displayIdSpec.size());
-
- QStringList specs = dSpec.split(QLatin1Char(' '), QString::SkipEmptyParts);
- foreach (QString spec, specs) {
- const int id = getDisplayId(spec);
- if (spec.startsWith("vnc:", Qt::CaseInsensitive)) {
- spec.append(":noDisablePainting");
- }
- const QPoint offset = filterDisplayOffset(spec);
- QScreen *s = qt_get_screen(id, spec.toLatin1().constData());
- s->setOffset(offset);
- addSubScreen(s);
- }
-
- QScreen *firstScreen = d_ptr->screens.at(0);
- Q_ASSERT(firstScreen);
-
- // XXX
- QScreen::d = firstScreen->depth();
-
- QScreen::lstep = 0;
- QScreen::data = 0;
- QScreen::size = 0;
-
- QScreen::w = d_ptr->region.boundingRect().width();
- QScreen::h = d_ptr->region.boundingRect().height();
-
- QScreen::dw = QScreen::w;
- QScreen::dh = QScreen::h;
-
- // XXX - Extend the physical size based on the first screen
- // to encompass all screens, so that code that uses the multi
- // screen to calculate dpi values will get the right numbers.
- QScreen::physWidth = firstScreen->physicalWidth() * w / firstScreen->width();
- QScreen::physHeight = firstScreen->physicalHeight() * h / firstScreen->height();
-
- // XXXXX
- qt_screen = this;
-
- return true;
-}
-
-void QMultiScreen::disconnect()
-{
- const int n = d_ptr->screens.size();
- for (int i = 0; i < n; ++i)
- d_ptr->screens.at(i)->disconnect();
-}
-
-void QMultiScreen::shutdownDevice()
-{
- const int n = d_ptr->screens.size();
- for (int i = 0; i < n; ++i)
- d_ptr->screens.at(i)->shutdownDevice();
-}
-
-void QMultiScreen::setMode(int, int, int)
-{
- return;
-}
-
-bool QMultiScreen::supportsDepth(int) const
-{
- return false;
-}
-
-void QMultiScreen::save()
-{
- const int n = d_ptr->screens.size();
- for (int i = 0; i < n; ++i)
- d_ptr->screens.at(i)->save();
-}
-
-void QMultiScreen::restore()
-{
- const int n = d_ptr->screens.size();
- for (int i = 0; i < n; ++i)
- d_ptr->screens.at(i)->restore();
-}
-
-void QMultiScreen::blank(bool on)
-{
- const int n = d_ptr->screens.size();
- for (int i = 0; i < n; ++i)
- d_ptr->screens.at(i)->blank(on);
-}
-
-bool QMultiScreen::onCard(const unsigned char *ptr) const
-{
- const int n = d_ptr->screens.size();
- for (int i = 0; i < n; ++i)
- if (d_ptr->screens.at(i)->onCard(ptr))
- return true;
- return false;
-}
-
-bool QMultiScreen::onCard(const unsigned char *ptr, ulong &offset) const
-{
- const int n = d_ptr->screens.size();
- for (int i = 0; i < n; ++i)
- if (d_ptr->screens.at(i)->onCard(ptr, offset))
- return true;
- return false;
-}
-
-bool QMultiScreen::isInterlaced() const
-{
- const int n = d_ptr->screens.size();
- for (int i = 0; i < n; ++i)
- if (d_ptr->screens.at(i)->isInterlaced())
- return true;
-
- return false;
-}
-
-int QMultiScreen::memoryNeeded(const QString &string)
-{
- int total = 0;
- const int n = d_ptr->screens.size();
- for (int i = 0; i < n; ++i)
- total += d_ptr->screens.at(i)->memoryNeeded(string);
- return total;
-}
-
-int QMultiScreen::sharedRamSize(void *arg)
-{
- int total = 0;
- const int n = d_ptr->screens.size();
- for (int i = 0; i < n; ++i)
- total += d_ptr->screens.at(i)->sharedRamSize(arg);
- return total;
-}
-
-void QMultiScreen::haltUpdates()
-{
- const int n = d_ptr->screens.size();
- for (int i = 0; i < n; ++i)
- d_ptr->screens.at(i)->haltUpdates();
-}
-
-void QMultiScreen::resumeUpdates()
-{
- const int n = d_ptr->screens.size();
- for (int i = 0; i < n; ++i)
- d_ptr->screens.at(i)->resumeUpdates();
-}
-
-void QMultiScreen::exposeRegion(QRegion region, int changing)
-{
- const int n = d_ptr->screens.size();
- for (int i = 0; i < n; ++i) {
- QScreen *screen = d_ptr->screens.at(i);
- const QRegion r = region & screen->region();
- if (r.isEmpty())
- continue;
- screen->exposeRegion(r, changing);
- }
-}
-
-void QMultiScreen::solidFill(const QColor &color, const QRegion &region)
-{
- const int n = d_ptr->screens.size();
- for (int i = 0; i < n; ++i) {
- QScreen *screen = d_ptr->screens.at(i);
- const QRegion r = region & screen->region();
- if (r.isEmpty())
- continue;
- screen->solidFill(color, r);
- }
-}
-
-void QMultiScreen::blit(const QImage &img, const QPoint &topLeft,
- const QRegion &region)
-{
- const int n = d_ptr->screens.size();
- for (int i = 0; i < n; ++i) {
- QScreen *screen = d_ptr->screens.at(i);
- const QRegion r = region & screen->region();
- if (r.isEmpty())
- continue;
- screen->blit(img, topLeft, r);
- }
-}
-
-void QMultiScreen::blit(QWSWindow *bs, const QRegion &clip)
-{
- const int n = d_ptr->screens.size();
- for (int i = 0; i < n; ++i) {
- QScreen *screen = d_ptr->screens.at(i);
- const QRegion r = clip & screen->region();
- if (r.isEmpty())
- continue;
- screen->blit(bs, r);
- }
-}
-
-void QMultiScreen::setDirty(const QRect &rect)
-{
- const int n = d_ptr->screens.size();
- for (int i = 0; i < n; ++i) {
- QScreen *screen = d_ptr->screens.at(i);
- const QRegion r = screen->region() & rect;
- if (r.isEmpty())
- continue;
- screen->setDirty(r.boundingRect());
- }
-}
-
-
-QWSWindowSurface* QMultiScreen::createSurface(const QString &key) const
-{
- QWSWindowSurface* surf = 0;
- const int n = d_ptr->screens.size();
- for (int i = 0; i < n; ++i) {
- QScreen *screen = d_ptr->screens.at(i);
- surf = screen->createSurface(key);
- if (surf)
- break;
- }
- return surf;
-}
-
-
-QWSWindowSurface* QMultiScreen::createSurface(QWidget *widget) const
-{
- const QPoint midpoint = (widget->frameGeometry().topLeft()
- + widget->frameGeometry().bottomRight()) / 2;
- int index = subScreenIndexAt(midpoint);
- if (index == -1)
- index = 0; // XXX
- return d_ptr->screens.at(index)->createSurface(widget);
-}
-
-QList<QScreen*> QMultiScreen::subScreens() const
-{
- return d_ptr->screens;
-}
-
-QRegion QMultiScreen::region() const
-{
- return d_ptr->region;
-}
-
-void QMultiScreen::addSubScreen(QScreen *screen)
-{
- d_ptr->screens.append(screen);
- d_ptr->region += screen->region();
-}
-
-void QMultiScreen::removeSubScreen(QScreen *screen)
-{
- d_ptr->screens.removeAll(screen);
- d_ptr->region -= screen->region();
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_QWS_MULTISCREEN
diff --git a/src/gui/embedded/qscreenmulti_qws_p.h b/src/gui/embedded/qscreenmulti_qws_p.h
deleted file mode 100644
index 0cc0493202..0000000000
--- a/src/gui/embedded/qscreenmulti_qws_p.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QMULTISCREEN_QWS_P_H
-#define QMULTISCREEN_QWS_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of the QLibrary class. This header file may change from
-// version to version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <qscreen_qws.h>
-
-QT_BEGIN_NAMESPACE
-
-#ifndef QT_NO_QWS_MULTISCREEN
-
-class QMultiScreenPrivate;
-
-class QMultiScreen : public QScreen
-{
-public:
- QMultiScreen(int displayId);
- ~QMultiScreen();
- bool initDevice();
- bool connect(const QString &displaySpec);
- void disconnect();
- void shutdownDevice();
- void setMode(int,int,int);
- bool supportsDepth(int) const;
-
- void save();
- void restore();
- void blank(bool on);
-
- bool onCard(const unsigned char *) const;
- bool onCard(const unsigned char *, ulong& out_offset) const;
-
- bool isInterlaced() const;
-
- int memoryNeeded(const QString&);
- int sharedRamSize(void *);
-
- void haltUpdates();
- void resumeUpdates();
-
- void exposeRegion(QRegion r, int changing);
-
- void blit(const QImage &img, const QPoint &topLeft, const QRegion &region);
- void solidFill(const QColor &color, const QRegion &region);
- void blit(QWSWindow *bs, const QRegion &clip);
- void setDirty(const QRect&);
-
- QWSWindowSurface* createSurface(QWidget *widget) const;
- QWSWindowSurface* createSurface(const QString &key) const;
-
- QList<QScreen*> subScreens() const;
- QRegion region() const;
-
-private:
- void addSubScreen(QScreen *screen);
- void removeSubScreen(QScreen *screen);
-
- QMultiScreenPrivate *d_ptr;
-};
-
-
-QT_END_NAMESPACE
-#endif // QT_NO_QWS_MULTISCREEN
-#endif // QMULTISCREEN_QWS_P_H
diff --git a/src/gui/embedded/qscreenproxy_qws.cpp b/src/gui/embedded/qscreenproxy_qws.cpp
deleted file mode 100644
index 30f304b01c..0000000000
--- a/src/gui/embedded/qscreenproxy_qws.cpp
+++ /dev/null
@@ -1,635 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qscreenproxy_qws.h>
-
-#ifndef QT_NO_QWS_PROXYSCREEN
-
-#include <qregexp.h>
-
-QT_BEGIN_NAMESPACE
-#ifndef QT_NO_QWS_CURSOR
-
-/*!
- \class QProxyScreenCursor
- \since 4.5
- \ingroup qws
- \brief The QProxyScreenCursor class provides a generic interface to
- QScreenCursor implementations.
-*/
-
-/*!
- Constructs a proxy screen cursor.
-*/
-QProxyScreenCursor::QProxyScreenCursor()
- : QScreenCursor(), realCursor(0), d_ptr(0)
-{
-}
-
-/*!
- Destroys the proxy screen cursor.
-*/
-QProxyScreenCursor::~QProxyScreenCursor()
-{
-}
-
-/*!
- Sets the real screen cursor to be used for the proxy screen cursor to
- the \a cursor specified.
-
- \sa screenCursor()
-*/
-void QProxyScreenCursor::setScreenCursor(QScreenCursor *cursor)
-{
- realCursor = cursor;
- configure();
-}
-
-/*!
- Returns the real screen cursor used by the proxy screen cursor.
-
- \sa setScreenCursor()
-*/
-QScreenCursor* QProxyScreenCursor::screenCursor() const
-{
- return realCursor;
-}
-
-/*!
- \reimp
-*/
-void QProxyScreenCursor::set(const QImage &image, int hotx, int hoty)
-{
- if (realCursor) {
- hotspot = QPoint(hotx, hoty);
- cursor = image;
- size = image.size();
- realCursor->set(image, hotx, hoty);
- } else {
- QScreenCursor::set(image, hotx, hoty);
- }
-}
-
-/*!
- \reimp
-*/
-void QProxyScreenCursor::move(int x, int y)
-{
- if (realCursor) {
- pos = QPoint(x, y);
- realCursor->move(x, y);
- } else {
- QScreenCursor::move(x, y);
- }
-}
-
-/*!
- \reimp
-*/
-void QProxyScreenCursor::show()
-{
- if (realCursor) {
- realCursor->show();
- enable = true;
- } else {
- QScreenCursor::show();
- }
-}
-
-/*!
- \reimp
-*/
-void QProxyScreenCursor::hide()
-{
- if (realCursor) {
- realCursor->hide();
- enable = false;
- } else {
- QScreenCursor::hide();
- }
-}
-
-/*!
- \internal
-*/
-void QProxyScreenCursor::configure()
-{
- if (!realCursor)
- return;
-
- cursor = realCursor->cursor;
- size = realCursor->size;
- pos = realCursor->pos;
- hotspot = realCursor->hotspot;
- enable = realCursor->enable;
- hwaccel = realCursor->hwaccel;
- supportsAlpha = realCursor->supportsAlpha;
-}
-
-#endif // QT_NO_QWS_CURSOR
-
-/*!
- \class QProxyScreen
- \ingroup qws
- \brief The QProxyScreen class provides a generic interface to QScreen implementations.
-*/
-
-/*!
- \fn QProxyScreen::QProxyScreen(int displayId, ClassId classId)
-
- Constructs a proxy screen with the given \a displayId and \a classId.
-*/
-QProxyScreen::QProxyScreen(int displayId, QScreen::ClassId classId)
- : QScreen(displayId, classId), realScreen(0), d_ptr(0)
-{
-}
-
-/*!
- Destroys the proxy screen.
-*/
-QProxyScreen::~QProxyScreen()
-{
-}
-
-/*!
- Sets the real \a screen to be used by the proxy screen.
-
- \sa screen()
-*/
-void QProxyScreen::setScreen(QScreen *screen)
-{
- realScreen = screen;
- configure();
-}
-
-/*!
- Returns the real screen used by the proxy screen.
-
- \sa setScreen()
-*/
-QScreen* QProxyScreen::screen() const
-{
- return realScreen;
-}
-
-
-/*!
- \internal
-*/
-void QProxyScreen::configure()
-{
- if (!realScreen)
- return;
-
- d = realScreen->depth();
- w = realScreen->width();
- h = realScreen->height();
- dw = realScreen->deviceWidth();
- dh = realScreen->deviceHeight();
- lstep = realScreen->linestep();
- data = realScreen->base();
- lstep = realScreen->linestep();
- size = realScreen->screenSize();
- physWidth = realScreen->physicalWidth();
- physHeight = realScreen->physicalHeight();
- pixeltype = realScreen->pixelType();
-#if Q_BYTE_ORDER == Q_BIG_ENDIAN
- setFrameBufferLittleEndian(realScreen->frameBufferLittleEndian());
-#endif
-
- setOffset(realScreen->offset());
- setPixelFormat(realScreen->pixelFormat());
-
-#ifdef QT_QWS_CLIENTBLIT
- setSupportsBlitInClients(realScreen->supportsBlitInClients());
-#endif
-}
-
-/*!
- \internal
- Returns the display ID that corresponds to the given \a spec.
-*/
-static int getDisplayId(const QString &spec)
-{
- QRegExp regexp(QLatin1String(":(\\d+)\\b"));
- if (regexp.lastIndexIn(spec) != -1) {
- const QString capture = regexp.cap(1);
- return capture.toInt();
- }
- return 0;
-}
-
-/*!
- \reimp
-*/
-bool QProxyScreen::connect(const QString &displaySpec)
-{
- const int id = getDisplayId(displaySpec);
- realScreen = qt_get_screen(id, displaySpec.toLatin1().constData());
- configure();
-
- return true;
-}
-
-/*!
- \reimp
-*/
-void QProxyScreen::exposeRegion(QRegion r, int changing)
-{
- if (!realScreen) {
- QScreen::exposeRegion(r, changing);
- return;
- }
-
- realScreen->exposeRegion(r, changing);
- r &= realScreen->region();
-
- const QVector<QRect> rects = r.rects();
- for (int i = 0; i < rects.size(); ++i)
- setDirty(rects.at(i));
-}
-
-/*!
- \reimp
-*/
-void QProxyScreen::blit(const QImage &image, const QPoint &topLeft,
- const QRegion &region)
-{
- if (!realScreen) {
- QScreen::blit(image, topLeft, region);
- return;
- }
-
- realScreen->blit(image, topLeft, region);
-}
-
-/*!
- \reimp
-*/
-void QProxyScreen::solidFill(const QColor &color, const QRegion &region)
-{
- if (!realScreen) {
- QScreen::solidFill(color, region);
- return;
- }
- realScreen->solidFill(color, region);
-}
-
-/*!
- \reimp
-*/
-QSize QProxyScreen::mapToDevice(const QSize &s) const
-{
- if (!realScreen)
- return QScreen::mapToDevice(s);
-
- return realScreen->mapToDevice(s);
-}
-
-/*!
- \reimp
-*/
-QSize QProxyScreen::mapFromDevice(const QSize &s) const
-{
- if (!realScreen)
- return QScreen::mapFromDevice(s);
-
- return realScreen->mapFromDevice(s);
-}
-
-/*!
- \reimp
-*/
-QPoint QProxyScreen::mapToDevice(const QPoint &p, const QSize &s) const
-{
- if (!realScreen)
- return QScreen::mapToDevice(p, s);
-
- return realScreen->mapToDevice(p, s);
-}
-
-/*!
- \reimp
-*/
-QPoint QProxyScreen::mapFromDevice(const QPoint &p, const QSize &s) const
-{
- if (!realScreen)
- return QScreen::mapFromDevice(p, s);
-
- return realScreen->mapFromDevice(p, s);
-}
-
-/*!
- \reimp
-*/
-QRect QProxyScreen::mapToDevice(const QRect &r, const QSize &s) const
-{
- if (!realScreen)
- return QScreen::mapToDevice(r, s);
-
- return realScreen->mapToDevice(r, s);
-}
-
-/*!
- \reimp
-*/
-QRect QProxyScreen::mapFromDevice(const QRect &r, const QSize &s) const
-{
- if (!realScreen)
- return QScreen::mapFromDevice(r, s);
-
- return realScreen->mapFromDevice(r, s);
-}
-
-/*!
- \reimp
-*/
-QRegion QProxyScreen::mapToDevice(const QRegion &r, const QSize &s) const
-{
- if (!realScreen)
- return QScreen::mapToDevice(r, s);
-
- return realScreen->mapToDevice(r, s);
-}
-
-/*!
- \reimp
-*/
-QRegion QProxyScreen::mapFromDevice(const QRegion &r, const QSize &s) const
-{
- if (!realScreen)
- return QScreen::mapFromDevice(r, s);
-
- return realScreen->mapFromDevice(r, s);
-}
-
-/*!
- \reimp
-*/
-void QProxyScreen::disconnect()
-{
- if (realScreen) {
- realScreen->disconnect();
- delete realScreen;
- realScreen = 0;
- }
-}
-
-/*!
-*/
-bool QProxyScreen::initDevice()
-{
- if (realScreen)
- return realScreen->initDevice();
-
- return false;
-}
-
-/*!
- \reimp
-*/
-void QProxyScreen::shutdownDevice()
-{
- if (realScreen)
- realScreen->shutdownDevice();
-}
-
-/*!
- \reimp
-*/
-void QProxyScreen::setMode(int w,int h, int d)
-{
- if (realScreen) {
- realScreen->setMode(w, h, d);
- } else {
- QScreen::dw = QScreen::w = w;
- QScreen::dh = QScreen::h = h;
- QScreen::d = d;
- }
- configure();
- exposeRegion(region(), 0);
-}
-
-/*!
- \reimp
-*/
-bool QProxyScreen::supportsDepth(int depth) const
-{
- if (realScreen)
- return realScreen->supportsDepth(depth);
- return false;
-}
-
-/*!
- \reimp
-*/
-void QProxyScreen::save()
-{
- if (realScreen)
- realScreen->save();
- QScreen::save();
-}
-
-/*!
- \reimp
-*/
-void QProxyScreen::restore()
-{
- if (realScreen)
- realScreen->restore();
- QScreen::restore();
-}
-
-/*!
- \reimp
-*/
-void QProxyScreen::blank(bool on)
-{
- if (realScreen)
- realScreen->blank(on);
-}
-
-/*!
- \reimp
-*/
-bool QProxyScreen::onCard(const unsigned char *ptr) const
-{
- if (realScreen)
- return realScreen->onCard(ptr);
- return false;
-}
-
-/*!
- \reimp
-*/
-bool QProxyScreen::onCard(const unsigned char *ptr, ulong &offset) const
-{
- if (realScreen)
- return realScreen->onCard(ptr, offset);
- return false;
-}
-
-/*!
- \reimp
-*/
-bool QProxyScreen::isInterlaced() const
-{
- if (realScreen)
- return realScreen->isInterlaced();
- return false;
-}
-
-/*!
- \reimp
-*/
-bool QProxyScreen::isTransformed() const
-{
- if (realScreen)
- return realScreen->isTransformed();
- return QScreen::isTransformed();
-}
-
-/*!
- \reimp
-*/
-int QProxyScreen::transformOrientation() const
-{
- if (realScreen)
- return realScreen->transformOrientation();
- return QScreen::transformOrientation();
-}
-
-/*!
-\internal
-*/
-int QProxyScreen::memoryNeeded(const QString &str)
-{
- if (realScreen)
- return realScreen->memoryNeeded(str);
- else
- return QScreen::memoryNeeded(str);
-}
-
-/*!
-\internal
-*/
-int QProxyScreen::sharedRamSize(void *ptr)
-{
- if (realScreen)
- return realScreen->sharedRamSize(ptr);
- else
- return QScreen::sharedRamSize(ptr);
-}
-
-/*!
-\internal
-*/
-void QProxyScreen::haltUpdates()
-{
- if (realScreen)
- realScreen->haltUpdates();
-}
-
-/*!
-\internal
-*/
-void QProxyScreen::resumeUpdates()
-{
- if (realScreen)
- realScreen->resumeUpdates();
-}
-
-/*!
- \reimp
-*/
-void QProxyScreen::setDirty(const QRect &rect)
-{
- if (realScreen)
- realScreen->setDirty(rect);
-}
-
-/*!
- \reimp
-*/
-QWSWindowSurface* QProxyScreen::createSurface(QWidget *widget) const
-{
- if (realScreen)
- return realScreen->createSurface(widget);
-
- return QScreen::createSurface(widget);
-}
-
-/*!
- \reimp
-*/
-QWSWindowSurface* QProxyScreen::createSurface(const QString &key) const
-{
- if (realScreen)
- return realScreen->createSurface(key);
-
- return QScreen::createSurface(key);
-}
-
-/*!
- \reimp
-*/
-QList<QScreen*> QProxyScreen::subScreens() const
-{
- if (realScreen)
- return realScreen->subScreens();
-
- return QScreen::subScreens();
-}
-
-/*!
- \reimp
-*/
-QRegion QProxyScreen::region() const
-{
- if (realScreen)
- return realScreen->region();
- else
- return QScreen::region();
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_QWS_PROXYSCREEN
diff --git a/src/gui/embedded/qscreenproxy_qws.h b/src/gui/embedded/qscreenproxy_qws.h
deleted file mode 100644
index 6f94911680..0000000000
--- a/src/gui/embedded/qscreenproxy_qws.h
+++ /dev/null
@@ -1,153 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPROXYSCREEN_QWS_H
-#define QPROXYSCREEN_QWS_H
-
-#include <QtGui/qscreen_qws.h>
-
-#ifndef QT_NO_QWS_PROXYSCREEN
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QProxyScreenPrivate;
-
-#ifndef QT_NO_QWS_CURSOR
-
-class QProxyScreenCursorPrivate;
-
-class Q_GUI_EXPORT QProxyScreenCursor : public QScreenCursor
-{
-public:
- QProxyScreenCursor();
- ~QProxyScreenCursor();
-
- void setScreenCursor(QScreenCursor *cursor);
- QScreenCursor* screenCursor() const;
-
- void set(const QImage &image, int hotx, int hoty);
- void move(int x, int y);
- void show();
- void hide();
-
-private:
- void configure();
-
- QScreenCursor *realCursor;
- QProxyScreenCursorPrivate *d_ptr;
-};
-
-#endif // QT_NO_QWS_CURSOR
-
-class Q_GUI_EXPORT QProxyScreen : public QScreen
-{
-public:
- QProxyScreen(int display_id, ClassId = ProxyClass);
- ~QProxyScreen();
-
- void setScreen(QScreen *screen);
- QScreen *screen() const;
-
- QSize mapToDevice(const QSize &s) const;
- QSize mapFromDevice(const QSize &s) const;
-
- QPoint mapToDevice(const QPoint &, const QSize &) const;
- QPoint mapFromDevice(const QPoint &, const QSize &) const;
-
- QRect mapToDevice(const QRect &, const QSize &) const;
- QRect mapFromDevice(const QRect &, const QSize &) const;
-
- QRegion mapToDevice(const QRegion &, const QSize &) const;
- QRegion mapFromDevice(const QRegion &, const QSize &) const;
-
- bool connect(const QString &displaySpec);
- bool initDevice();
- void shutdownDevice();
- void disconnect();
-
- void setMode(int width, int height, int depth);
- bool supportsDepth(int) const;
-
- void save();
- void restore();
- void blank(bool on);
-
- bool onCard(const unsigned char *) const;
- bool onCard(const unsigned char *, ulong& out_offset) const;
-
- bool isInterlaced() const;
- bool isTransformed() const;
- int transformOrientation() const;
-
- int memoryNeeded(const QString&);
- int sharedRamSize(void *);
-
- void haltUpdates();
- void resumeUpdates();
-
- void exposeRegion(QRegion r, int changing);
- void blit(const QImage &img, const QPoint &topLeft, const QRegion &region);
- void solidFill(const QColor &color, const QRegion &region);
- void setDirty(const QRect&);
-
- QWSWindowSurface* createSurface(QWidget *widget) const;
- QWSWindowSurface* createSurface(const QString &key) const;
-
- QList<QScreen*> subScreens() const;
- QRegion region() const;
-
-private:
- void configure();
-
- QScreen *realScreen;
- QProxyScreenPrivate *d_ptr;
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QT_NO_QWS_PROXYSCREEN
-#endif // QPROXYSCREEN_QWS_H
diff --git a/src/gui/embedded/qscreenqnx_qws.cpp b/src/gui/embedded/qscreenqnx_qws.cpp
deleted file mode 100644
index 4afe087cdb..0000000000
--- a/src/gui/embedded/qscreenqnx_qws.cpp
+++ /dev/null
@@ -1,450 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qscreenqnx_qws.h"
-#include "qdebug.h"
-
-#include <gf/gf.h>
-
-QT_BEGIN_NAMESPACE
-
-// This struct holds all the pointers to QNX's internals
-struct QQnxScreenContext
-{
- inline QQnxScreenContext()
- : device(0), display(0), layer(0), hwSurface(0), memSurface(0), context(0)
- {}
-
- gf_dev_t device;
- gf_dev_info_t deviceInfo;
- gf_display_t display;
- gf_display_info_t displayInfo;
- gf_layer_t layer;
- gf_surface_t hwSurface;
- gf_surface_t memSurface;
- gf_surface_info_t memSurfaceInfo;
- gf_context_t context;
-};
-
-/*!
- \class QQnxScreen
- \preliminary
- \ingroup qws
- \since 4.6
- \internal
-
- \brief The QQnxScreen class implements a screen driver
- for QNX io-display based devices.
-
- Note - you never have to instanciate this class, the QScreenDriverFactory
- does that for us based on the \c{QWS_DISPLAY} environment variable.
-
- To activate this driver, set \c{QWS_DISPLAY} to \c{qnx}.
-
- Example:
- \c{QWS_DISPLAY=qnx; export QWS_DISPLAY}
-
- By default, the main layer of the first display of the first device is used.
- If you have multiple graphic cards, multiple displays or multiple layers and
- don't want to connect to the default, you can override that with setting
- the corresponding options \c{device}, \c{display} or \c{layer} in the \c{QWS_DISPLAY} variable:
-
- \c{QWS_DISPLAY=qnx:device=3:display=4:layer=5}
-
- In addition, it is suggested to set the physical width and height of the display.
- QQnxScreen will use that information to compute the dots per inch (DPI) in order to render
- fonts correctly. If this informaiton is omitted, QQnxScreen defaults to 72 dpi.
-
- \c{QWS_DISPLAY=qnx:mmWidth=120:mmHeight=80}
-
- \c{mmWidth} and \c{mmHeight} are the physical width/height of the screen in millimeters.
-
- \sa QScreen, QScreenDriverPlugin, {Running Qt for Embedded Linux Applications}{Running Applications}
-*/
-
-/*!
- Constructs a QQnxScreen object. The \a display_id argument
- identifies the Qt for Embedded Linux server to connect to.
-*/
-QQnxScreen::QQnxScreen(int display_id)
- : QScreen(display_id), d(new QQnxScreenContext)
-{
-}
-
-/*!
- Destroys this QQnxScreen object.
-*/
-QQnxScreen::~QQnxScreen()
-{
- delete d;
-}
-
-/*! \reimp
-*/
-bool QQnxScreen::initDevice()
-{
- // implement this if you have multiple processes that want to access the display
- // (not required if QT_NO_QWS_MULTIPROCESS is set)
- return true;
-}
-
-/*! \internal
- Attaches to the named device \a name.
-*/
-static bool attachDevice(QQnxScreenContext * const d, const char *name)
-{
- int ret = gf_dev_attach(&d->device, name, &d->deviceInfo);
- if (ret != GF_ERR_OK) {
- qWarning("QQnxScreen: gf_dev_attach(%s) failed with error code %d", name, ret);
- return false;
- }
- return true;
-}
-
-/*! \internal
- Attaches to the display at index \a displayIndex.
- */
-static bool attachDisplay(QQnxScreenContext * const d, int displayIndex)
-{
- int ret = gf_display_attach(&d->display, d->device, displayIndex, &d->displayInfo);
- if (ret != GF_ERR_OK) {
- qWarning("QQnxScreen: gf_display_attach(%d) failed with error code %d",
- displayIndex, ret);
- return false;
- }
- return true;
-}
-
-/*! \internal
- Attaches to the layer \a layerIndex.
- */
-static bool attachLayer(QQnxScreenContext * const d, int layerIndex)
-{
- int ret = gf_layer_attach(&d->layer, d->display, layerIndex, 0);
- if (ret != GF_ERR_OK) {
- qWarning("QQnxScreen: gf_layer_attach(%d) failed with error code %d", layerIndex,
- ret);
- return false;
- }
- gf_layer_enable(d->layer);
-
- return true;
-}
-
-/*! \internal
- Creates a new hardware surface (usually on the Gfx card memory) with the dimensions \a w * \a h.
- */
-static bool createHwSurface(QQnxScreenContext * const d, int w, int h)
-{
- int ret = gf_surface_create_layer(&d->hwSurface, &d->layer, 1, 0,
- w, h, GF_FORMAT_ARGB8888, 0, 0);
- if (ret != GF_ERR_OK) {
- qWarning("QQnxScreen: gf_surface_create_layer(%dx%d) failed with error code %d",
- w, h, ret);
- return false;
- }
-
- gf_layer_set_surfaces(d->layer, &d->hwSurface, 1);
-
- ret = gf_layer_update(d->layer, 0);
- if (ret != GF_ERR_OK) {
- qWarning("QQnxScreen: gf_layer_update() failed with error code %d\n", ret);
- return false;
- }
-
- return true;
-}
-
-/*! \internal
- Creates an in-memory, linear accessible surface of dimensions \a w * \a h.
- This is the main surface that QWS blits to.
- */
-static bool createMemSurface(QQnxScreenContext * const d, int w, int h)
-{
- // Note: gf_surface_attach() could also be used, so we'll create the buffer
- // and let the surface point to it. Here, we use surface_create instead.
-
- int ret = gf_surface_create(&d->memSurface, d->device, w, h,
- GF_FORMAT_ARGB8888, 0,
- GF_SURFACE_CREATE_CPU_FAST_ACCESS | GF_SURFACE_CREATE_CPU_LINEAR_ACCESSIBLE
- | GF_SURFACE_PHYS_CONTIG | GF_SURFACE_CREATE_SHAREABLE);
- if (ret != GF_ERR_OK) {
- qWarning("QQnxScreen: gf_surface_create(%dx%d) failed with error code %d",
- w, h, ret);
- return false;
- }
-
- gf_surface_get_info(d->memSurface, &d->memSurfaceInfo);
-
- if (d->memSurfaceInfo.sid == unsigned(GF_SID_INVALID)) {
- qWarning("QQnxScreen: gf_surface_get_info() failed.");
- return false;
- }
-
- return true;
-}
-
-/* \internal
- Creates a QNX gf context and sets our memory surface on it.
- */
-static bool createContext(QQnxScreenContext * const d)
-{
- int ret = gf_context_create(&d->context);
- if (ret != GF_ERR_OK) {
- qWarning("QQnxScreen: gf_context_create() failed with error code %d", ret);
- return false;
- }
-
- ret = gf_context_set_surface(d->context, d->memSurface);
- if (ret != GF_ERR_OK) {
- qWarning("QQnxScreen: gf_context_set_surface() failed with error code %d", ret);
- return false;
- }
-
- return true;
-}
-
-/*! \reimp
- Connects to QNX's io-display based device based on the \a displaySpec parameters
- from the \c{QWS_DISPLAY} environment variable. See the QQnxScreen class documentation
- for possible parameters.
-
- \sa QQnxScreen
- */
-bool QQnxScreen::connect(const QString &displaySpec)
-{
- const QStringList params = displaySpec.split(QLatin1Char(':'), QString::SkipEmptyParts);
-
- bool isOk = false;
- QRegExp deviceRegExp(QLatin1String("^device=(.+)$"));
- if (params.indexOf(deviceRegExp) != -1) {
- isOk = attachDevice(d, deviceRegExp.cap(1).toLocal8Bit().constData());
- } else {
- // no device specified - attach to device 0 (the default)
- isOk = attachDevice(d, GF_DEVICE_INDEX(0));
- }
-
- if (!isOk)
- return false;
-
- qDebug("QQnxScreen: Attached to Device, number of displays: %d", d->deviceInfo.ndisplays);
-
- // default to display 0
- int displayIndex = 0;
- QRegExp displayRegexp(QLatin1String("^display=(\\d+)$"));
- if (params.indexOf(displayRegexp) != -1) {
- displayIndex = displayRegexp.cap(1).toInt();
- }
-
- if (!attachDisplay(d, displayIndex))
- return false;
-
- qDebug("QQnxScreen: Attached to Display %d, resolution %dx%d, refresh %d Hz",
- displayIndex, d->displayInfo.xres, d->displayInfo.yres,
- d->displayInfo.refresh);
-
-
- // default to main_layer_index from the displayInfo struct
- int layerIndex = 0;
- QRegExp layerRegexp(QLatin1String("^layer=(\\d+)$"));
- if (params.indexOf(layerRegexp) != -1) {
- layerIndex = layerRegexp.cap(1).toInt();
- } else {
- layerIndex = d->displayInfo.main_layer_index;
- }
-
- if (!attachLayer(d, layerIndex))
- return false;
-
- // tell QWSDisplay the width and height of the display
- w = dw = d->displayInfo.xres;
- h = dh = d->displayInfo.yres;
-
- // we only support 32 bit displays for now.
- QScreen::d = 32;
-
- // assume 72 dpi as default, to calculate the physical dimensions if not specified
- const int defaultDpi = 72;
-
- // Handle display physical size spec.
- QRegExp mmWidthRegexp(QLatin1String("^mmWidth=(\\d+)$"));
- if (params.indexOf(mmWidthRegexp) == -1) {
- physWidth = qRound(dw * 25.4 / defaultDpi);
- } else {
- physWidth = mmWidthRegexp.cap(1).toInt();
- }
-
- QRegExp mmHeightRegexp(QLatin1String("^mmHeight=(\\d+)$"));
- if (params.indexOf(mmHeightRegexp) == -1) {
- physHeight = qRound(dh * 25.4 / defaultDpi);
- } else {
- physHeight = mmHeightRegexp.cap(1).toInt();
- }
-
- // create a hardware surface with our dimensions. In the old days, it was possible
- // to get a pointer directly to the hw surface, so we could blit directly. Now, we
- // have to use one indirection more, because it's not guaranteed that the hw surface
- // is mappable into our process.
- if (!createHwSurface(d, w, h))
- return false;
-
- // create an in-memory linear surface that is used by QWS. QWS will blit directly in here.
- if (!createMemSurface(d, w, h))
- return false;
-
- // set the address of the in-memory buffer that QWS is blitting to
- data = d->memSurfaceInfo.vaddr;
- // set the line stepping
- lstep = d->memSurfaceInfo.stride;
-
- // the overall size of the in-memory buffer is linestep * height
- size = mapsize = lstep * h;
-
- // create a QNX drawing context
- if (!createContext(d))
- return false;
-
- // we're always using a software cursor for now. Initialize it here.
- QScreenCursor::initSoftwareCursor();
-
- // done, the driver should be connected to the display now.
- return true;
-}
-
-/*! \reimp
- */
-void QQnxScreen::disconnect()
-{
- if (d->context)
- gf_context_free(d->context);
-
- if (d->memSurface)
- gf_surface_free(d->memSurface);
-
- if (d->hwSurface)
- gf_surface_free(d->hwSurface);
-
- if (d->layer)
- gf_layer_detach(d->layer);
-
- if (d->display)
- gf_display_detach(d->display);
-
- if (d->device)
- gf_dev_detach(d->device);
-
- d->memSurface = 0;
- d->hwSurface = 0;
- d->context = 0;
- d->layer = 0;
- d->display = 0;
- d->device = 0;
-}
-
-/*! \reimp
- */
-void QQnxScreen::shutdownDevice()
-{
-}
-
-
-/*! \reimp
- QQnxScreen doesn't support setting the mode, use io-display instead.
- */
-void QQnxScreen::setMode(int,int,int)
-{
- qWarning("QQnxScreen: Unable to change mode, use io-display instead.");
-}
-
-/*! \reimp
- */
-bool QQnxScreen::supportsDepth(int depth) const
-{
- // only 32-bit for the moment
- return depth == 32;
-}
-
-/*! \reimp
- */
-void QQnxScreen::exposeRegion(QRegion r, int changing)
-{
- // here is where the actual magic happens. QWS will call exposeRegion whenever
- // a region on the screen is dirty and needs to be updated on the actual screen.
-
- // first, call the parent implementation. The parent implementation will update
- // the region on our in-memory surface
- QScreen::exposeRegion(r, changing);
-
- // now our in-memory surface should be up to date with the latest changes.
- // the code below copies the region from the in-memory surface to the hardware.
-
- // just get the bounding rectangle of the region. Most screen updates are rectangular
- // anyways. Code could be optimized to blit each and every member of the region
- // individually, but in real life, the speed-up is neglectable
- const QRect br = r.boundingRect();
- if (br.isEmpty())
- return; // ignore empty regions because gf_draw_blit2 doesn't like 0x0 dimensions
-
- // start drawing.
- int ret = gf_draw_begin(d->context);
- if (ret != GF_ERR_OK) {
- qWarning("QQnxScreen: gf_draw_begin() failed with error code %d", ret);
- return;
- }
-
- // blit the changed region from the memory surface to the hardware surface
- ret = gf_draw_blit2(d->context, d->memSurface, d->hwSurface,
- br.x(), br.y(), br.right(), br.bottom(), br.x(), br.y());
- if (ret != GF_ERR_OK) {
- qWarning("QQnxScreen: gf_draw_blit2() failed with error code %d", ret);
- }
-
- // flush all drawing commands (in our case, a single blit)
- ret = gf_draw_flush(d->context);
- if (ret != GF_ERR_OK) {
- qWarning("QQnxScreen: gf_draw_flush() failed with error code %d", ret);
- }
-
- // tell QNX that we're done drawing.
- gf_draw_end(d->context);
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/embedded/qscreenqnx_qws.h b/src/gui/embedded/qscreenqnx_qws.h
deleted file mode 100644
index 38c0ac9475..0000000000
--- a/src/gui/embedded/qscreenqnx_qws.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSCREENQNX_QWS_H
-#define QSCREENQNX_QWS_H
-
-#include <QtGui/qscreen_qws.h>
-
-#ifndef QT_NO_QWS_QNX
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-struct QQnxScreenContext;
-
-class QQnxScreen : public QScreen
-{
-public:
- explicit QQnxScreen(int display_id);
- ~QQnxScreen();
-
- bool initDevice();
- bool connect(const QString &displaySpec);
- void disconnect();
- void shutdownDevice();
- void setMode(int,int,int);
- bool supportsDepth(int) const;
-
- void exposeRegion(QRegion r, int changing);
-
-private:
- QQnxScreenContext * const d;
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QT_NO_QWS_QNX
-
-#endif
diff --git a/src/gui/embedded/qscreentransformed_qws.cpp b/src/gui/embedded/qscreentransformed_qws.cpp
deleted file mode 100644
index c2b2a0761d..0000000000
--- a/src/gui/embedded/qscreentransformed_qws.cpp
+++ /dev/null
@@ -1,748 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qscreentransformed_qws.h"
-
-#ifndef QT_NO_QWS_TRANSFORMED
-#include <qscreendriverfactory_qws.h>
-#include <qvector.h>
-#include <private/qpainter_p.h>
-#include <private/qmemrotate_p.h>
-#include <qmatrix.h>
-
-#include <unistd.h>
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <fcntl.h>
-#include <errno.h>
-
-#include <qwindowsystem_qws.h>
-#include <qwsdisplay_qws.h>
-
-QT_BEGIN_NAMESPACE
-
-//#define QT_REGION_DEBUG
-
-#ifdef QT_REGION_DEBUG
-#include <QDebug>
-#endif
-
-class QTransformedScreenPrivate
-{
-public:
- QTransformedScreenPrivate(QTransformedScreen *parent);
-
- void configure();
-
- QTransformedScreen::Transformation transformation;
-#ifdef QT_QWS_DEPTH_GENERIC
- bool doGenericColors;
-#endif
- QTransformedScreen *q;
-};
-
-QTransformedScreenPrivate::QTransformedScreenPrivate(QTransformedScreen *parent)
- : transformation(QTransformedScreen::None),
-#ifdef QT_QWS_DEPTH_GENERIC
- doGenericColors(false),
-#endif
- q(parent)
-{
-}
-
-extern "C"
-#ifndef QT_BUILD_GUI_LIB
-Q_DECL_EXPORT
-#endif
-void qws_setScreenTransformation(QScreen *that, int t)
-{
- QTransformedScreen *tscreen = static_cast<QTransformedScreen*>(that);
- tscreen->setTransformation((QTransformedScreen::Transformation)t);
-}
-
-// ---------------------------------------------------------------------------
-// Transformed Screen
-// ---------------------------------------------------------------------------
-
-/*!
- \internal
-
- \class QTransformedScreen
- \ingroup qws
-
- \brief The QTransformedScreen class implements a screen driver for
- a transformed screen.
-
- Note that this class is only available in \l{Qt for Embedded Linux}.
- Custom screen drivers can be added by subclassing the
- QScreenDriverPlugin class, using the QScreenDriverFactory class to
- dynamically load the driver into the application, but there should
- only be one screen object per application.
-
- Use the QScreen::isTransformed() function to determine if a screen
- is transformed. The QTransformedScreen class itself provides means
- of rotating the screen with its setTransformation() function; the
- transformation() function returns the currently set rotation in
- terms of the \l Transformation enum (which describes the various
- available rotation settings). Alternatively, QTransformedScreen
- provides an implementation of the QScreen::transformOrientation()
- function, returning the current rotation as an integer value.
-
- \sa QScreen, QScreenDriverPlugin, {Running Applications}
-*/
-
-/*!
- \enum QTransformedScreen::Transformation
-
- This enum describes the various rotations a transformed screen can
- have.
-
- \value None No rotation
- \value Rot90 90 degrees rotation
- \value Rot180 180 degrees rotation
- \value Rot270 270 degrees rotation
-*/
-
-/*!
- \fn bool QTransformedScreen::isTransformed() const
- \reimp
-*/
-
-/*!
- Constructs a QTransformedScreen object. The \a displayId argument
- identifies the Qt for Embedded Linux server to connect to.
-*/
-QTransformedScreen::QTransformedScreen(int displayId)
- : QProxyScreen(displayId, QScreen::TransformedClass)
-{
- d_ptr = new QTransformedScreenPrivate(this);
- d_ptr->transformation = None;
-
-#ifdef QT_REGION_DEBUG
- qDebug() << "QTransformedScreen::QTransformedScreen";
-#endif
-}
-
-void QTransformedScreenPrivate::configure()
-{
- // ###: works because setTransformation recalculates unconditionally
- q->setTransformation(transformation);
-}
-
-/*!
- Destroys the QTransformedScreen object.
-*/
-QTransformedScreen::~QTransformedScreen()
-{
- delete d_ptr;
-}
-
-static int getDisplayId(const QString &spec)
-{
- QRegExp regexp(QLatin1String(":(\\d+)\\b"));
- if (regexp.lastIndexIn(spec) != -1) {
- const QString capture = regexp.cap(1);
- return capture.toInt();
- }
- return 0;
-}
-
-static QTransformedScreen::Transformation filterTransformation(QString &spec)
-{
- QRegExp regexp(QLatin1String("\\bRot(\\d+):?\\b"), Qt::CaseInsensitive);
- if (regexp.indexIn(spec) == -1)
- return QTransformedScreen::None;
-
- const int degrees = regexp.cap(1).toInt();
- spec.remove(regexp.pos(0), regexp.matchedLength());
-
- return static_cast<QTransformedScreen::Transformation>(degrees / 90);
-}
-
-/*!
- \reimp
-*/
-bool QTransformedScreen::connect(const QString &displaySpec)
-{
- QString dspec = displaySpec.trimmed();
- if (dspec.startsWith(QLatin1String("Transformed:"), Qt::CaseInsensitive))
- dspec = dspec.mid(QString::fromLatin1("Transformed:").size());
- else if (!dspec.compare(QLatin1String("Transformed"), Qt::CaseInsensitive))
- dspec = QString();
-
- const QString displayIdSpec = QString::fromLatin1(" :%1").arg(displayId);
- if (dspec.endsWith(displayIdSpec))
- dspec = dspec.left(dspec.size() - displayIdSpec.size());
-
- d_ptr->transformation = filterTransformation(dspec);
-
- QString driver = dspec;
- int colon = driver.indexOf(QLatin1Char(':'));
- if (colon >= 0)
- driver.truncate(colon);
-
- if (!QScreenDriverFactory::keys().contains(driver, Qt::CaseInsensitive))
- if (!dspec.isEmpty())
- dspec.prepend(QLatin1Char(':'));
-
- const int id = getDisplayId(dspec);
- QScreen *s = qt_get_screen(id, dspec.toLatin1().constData());
- setScreen(s);
-
-#ifdef QT_QWS_DEPTH_GENERIC
- d_ptr->doGenericColors = dspec.contains(QLatin1String("genericcolors"));
-#endif
-
- d_ptr->configure();
-
- // XXX
- qt_screen = this;
-
- return true;
-}
-
-/*!
- Returns the currently set rotation.
-
- \sa setTransformation(), QScreen::transformOrientation()
-*/
-QTransformedScreen::Transformation QTransformedScreen::transformation() const
-{
- return d_ptr->transformation;
-}
-
-/*!
- \reimp
-*/
-int QTransformedScreen::transformOrientation() const
-{
- return (int)d_ptr->transformation;
-}
-
-/*!
- \reimp
-*/
-void QTransformedScreen::exposeRegion(QRegion region, int changing)
-{
- if (!data || d_ptr->transformation == None) {
- QProxyScreen::exposeRegion(region, changing);
- return;
- }
- QScreen::exposeRegion(region, changing);
-}
-
-/*!
- Rotates this screen object according to the specified \a transformation.
-
- \sa transformation()
-*/
-void QTransformedScreen::setTransformation(Transformation transformation)
-{
- d_ptr->transformation = transformation;
- QSize size = mapFromDevice(QSize(dw, dh));
- w = size.width();
- h = size.height();
-
- const QScreen *s = screen();
- size = mapFromDevice(QSize(s->physicalWidth(), s->physicalHeight()));
- physWidth = size.width();
- physHeight = size.height();
-
-#ifdef QT_REGION_DEBUG
- qDebug() << "QTransformedScreen::setTransformation" << transformation
- << "size" << w << h << "dev size" << dw << dh;
-#endif
-
-}
-
-static inline QRect correctNormalized(const QRect &r) {
- const int x1 = qMin(r.left(), r.right());
- const int x2 = qMax(r.left(), r.right());
- const int y1 = qMin(r.top(), r.bottom());
- const int y2 = qMax(r.top(), r.bottom());
-
- return QRect( QPoint(x1,y1), QPoint(x2,y2) );
-}
-
-template <class DST, class SRC>
-static inline void blit90(QScreen *screen, const QImage &image,
- const QRect &rect, const QPoint &topLeft)
-{
- const SRC *src = (const SRC*)(image.scanLine(rect.top())) + rect.left();
- DST *dest = (DST*)(screen->base() + topLeft.y() * screen->linestep())
- + topLeft.x();
- qt_memrotate90(src, rect.width(), rect.height(), image.bytesPerLine(),
- dest, screen->linestep());
-}
-
-template <class DST, class SRC>
-static inline void blit180(QScreen *screen, const QImage &image,
- const QRect &rect, const QPoint &topLeft)
-{
- const SRC *src = (const SRC*)(image.scanLine(rect.top())) + rect.left();
- DST *dest = (DST*)(screen->base() + topLeft.y() * screen->linestep())
- + topLeft.x();
- qt_memrotate180(src, rect.width(), rect.height(), image.bytesPerLine(),
- dest, screen->linestep());
-}
-
-template <class DST, class SRC>
-static inline void blit270(QScreen *screen, const QImage &image,
- const QRect &rect, const QPoint &topLeft)
-{
- const SRC *src = (const SRC *)(image.scanLine(rect.top())) + rect.left();
- DST *dest = (DST*)(screen->base() + topLeft.y() * screen->linestep())
- + topLeft.x();
- qt_memrotate270(src, rect.width(), rect.height(), image.bytesPerLine(),
- dest, screen->linestep());
-}
-
-typedef void (*BlitFunc)(QScreen *, const QImage &, const QRect &, const QPoint &);
-
-#define SET_BLIT_FUNC(dst, src, rotation, func) \
-do { \
- switch (rotation) { \
- case Rot90: \
- func = blit90<dst, src>; \
- break; \
- case Rot180: \
- func = blit180<dst, src>; \
- break; \
- case Rot270: \
- func = blit270<dst, src>; \
- break; \
- default: \
- break; \
- } \
-} while (0)
-
-/*!
- \reimp
-*/
-void QTransformedScreen::blit(const QImage &image, const QPoint &topLeft,
- const QRegion &region)
-{
- const Transformation trans = d_ptr->transformation;
- if (trans == None) {
- QProxyScreen::blit(image, topLeft, region);
- return;
- }
-
- const QVector<QRect> rects = region.rects();
- const QRect bound = QRect(0, 0, QScreen::w, QScreen::h)
- & QRect(topLeft, image.size());
-
- BlitFunc func = 0;
-#ifdef QT_QWS_DEPTH_GENERIC
- if (d_ptr->doGenericColors && depth() == 16) {
- if (image.depth() == 16)
- SET_BLIT_FUNC(qrgb_generic16, quint16, trans, func);
- else
- SET_BLIT_FUNC(qrgb_generic16, quint32, trans, func);
- } else
-#endif
- switch (depth()) {
-#ifdef QT_QWS_DEPTH_32
- case 32:
-#ifdef QT_QWS_DEPTH_16
- if (image.depth() == 16)
- SET_BLIT_FUNC(quint32, quint16, trans, func);
- else
-#endif
- SET_BLIT_FUNC(quint32, quint32, trans, func);
- break;
-#endif
-#if defined(QT_QWS_DEPTH_24) || defined(QT_QWS_DEPTH18)
- case 24:
- case 18:
- SET_BLIT_FUNC(quint24, quint24, trans, func);
- break;
-#endif
-#if defined(QT_QWS_DEPTH_16) || defined(QT_QWS_DEPTH_15) || defined(QT_QWS_DEPTH_12)
- case 16:
-#if defined QT_QWS_ROTATE_BGR
- if (pixelType() == BGRPixel && image.depth() == 16) {
- SET_BLIT_FUNC(qbgr565, quint16, trans, func);
- break;
- } //fall-through here!!!
-#endif
- case 15:
-#if defined QT_QWS_ROTATE_BGR
- if (pixelType() == BGRPixel && image.format() == QImage::Format_RGB555) {
- SET_BLIT_FUNC(qbgr555, qrgb555, trans, func);
- break;
- } //fall-through here!!!
-#endif
- case 12:
- if (image.depth() == 16)
- SET_BLIT_FUNC(quint16, quint16, trans, func);
- else
- SET_BLIT_FUNC(quint16, quint32, trans, func);
- break;
-#endif
-#ifdef QT_QWS_DEPTH_8
- case 8:
- if (image.format() == QImage::Format_RGB444)
- SET_BLIT_FUNC(quint8, qrgb444, trans, func);
- else if (image.depth() == 16)
- SET_BLIT_FUNC(quint8, quint16, trans, func);
- else
- SET_BLIT_FUNC(quint8, quint32, trans, func);
- break;
-#endif
- default:
- return;
- }
- if (!func)
- return;
-
- QWSDisplay::grab();
- for (int i = 0; i < rects.size(); ++i) {
- const QRect r = rects.at(i) & bound;
-
- QPoint dst;
- switch (trans) {
- case Rot90:
- dst = mapToDevice(r.topRight(), QSize(w, h));
- break;
- case Rot180:
- dst = mapToDevice(r.bottomRight(), QSize(w, h));
- break;
- case Rot270:
- dst = mapToDevice(r.bottomLeft(), QSize(w, h));
- break;
- default:
- break;
- }
- func(this, image, r.translated(-topLeft), dst);
- }
- QWSDisplay::ungrab();
-
-}
-
-/*!
- \reimp
-*/
-void QTransformedScreen::solidFill(const QColor &color, const QRegion &region)
-{
- const QRegion tr = mapToDevice(region, QSize(w,h));
-
- Q_ASSERT(tr.boundingRect() == mapToDevice(region.boundingRect(), QSize(w,h)));
-
-#ifdef QT_REGION_DEBUG
- qDebug() << "QTransformedScreen::solidFill region" << region << "transformed" << tr;
-#endif
- QProxyScreen::solidFill(color, tr);
-}
-
-/*!
- \reimp
-*/
-QSize QTransformedScreen::mapToDevice(const QSize &s) const
-{
- switch (d_ptr->transformation) {
- case None:
- case Rot180:
- break;
- case Rot90:
- case Rot270:
- return QSize(s.height(), s.width());
- break;
- }
- return s;
-}
-
-/*!
- \reimp
-*/
-QSize QTransformedScreen::mapFromDevice(const QSize &s) const
-{
- switch (d_ptr->transformation) {
- case None:
- case Rot180:
- break;
- case Rot90:
- case Rot270:
- return QSize(s.height(), s.width());
- break;
- }
- return s;
-}
-
-/*!
- \reimp
-*/
-QPoint QTransformedScreen::mapToDevice(const QPoint &p, const QSize &s) const
-{
- QPoint rp(p);
-
- switch (d_ptr->transformation) {
- case None:
- break;
- case Rot90:
- rp.setX(p.y());
- rp.setY(s.width() - p.x() - 1);
- break;
- case Rot180:
- rp.setX(s.width() - p.x() - 1);
- rp.setY(s.height() - p.y() - 1);
- break;
- case Rot270:
- rp.setX(s.height() - p.y() - 1);
- rp.setY(p.x());
- break;
- }
-
- return rp;
-}
-
-/*!
- \reimp
-*/
-QPoint QTransformedScreen::mapFromDevice(const QPoint &p, const QSize &s) const
-{
- QPoint rp(p);
-
- switch (d_ptr->transformation) {
- case None:
- break;
- case Rot90:
- rp.setX(s.height() - p.y() - 1);
- rp.setY(p.x());
- break;
- case Rot180:
- rp.setX(s.width() - p.x() - 1);
- rp.setY(s.height() - p.y() - 1);
- break;
- case Rot270:
- rp.setX(p.y());
- rp.setY(s.width() - p.x() - 1);
- break;
- }
-
- return rp;
-}
-
-/*!
- \reimp
-*/
-QRect QTransformedScreen::mapToDevice(const QRect &r, const QSize &s) const
-{
- if (r.isNull())
- return QRect();
-
- QRect tr;
- switch (d_ptr->transformation) {
- case None:
- tr = r;
- break;
- case Rot90:
- tr.setCoords(r.y(), s.width() - r.x() - 1,
- r.bottom(), s.width() - r.right() - 1);
- break;
- case Rot180:
- tr.setCoords(s.width() - r.x() - 1, s.height() - r.y() - 1,
- s.width() - r.right() - 1, s.height() - r.bottom() - 1);
- break;
- case Rot270:
- tr.setCoords(s.height() - r.y() - 1, r.x(),
- s.height() - r.bottom() - 1, r.right());
- break;
- }
-
- return correctNormalized(tr);
-}
-
-/*!
- \reimp
-*/
-QRect QTransformedScreen::mapFromDevice(const QRect &r, const QSize &s) const
-{
- if (r.isNull())
- return QRect();
-
- QRect tr;
- switch (d_ptr->transformation) {
- case None:
- tr = r;
- break;
- case Rot90:
- tr.setCoords(s.height() - r.y() - 1, r.x(),
- s.height() - r.bottom() - 1, r.right());
- break;
- case Rot180:
- tr.setCoords(s.width() - r.x() - 1, s.height() - r.y() - 1,
- s.width() - r.right() - 1, s.height() - r.bottom() - 1);
- break;
- case Rot270:
- tr.setCoords(r.y(), s.width() - r.x() - 1,
- r.bottom(), s.width() - r.right() - 1);
- break;
- }
-
- return correctNormalized(tr);
-}
-
-/*!
- \reimp
-*/
-QRegion QTransformedScreen::mapToDevice(const QRegion &rgn, const QSize &s) const
-{
- if (d_ptr->transformation == None)
- return QProxyScreen::mapToDevice(rgn, s);
-
-#ifdef QT_REGION_DEBUG
- qDebug() << "mapToDevice size" << s << "rgn: " << rgn;
-#endif
- QRect tr;
- QRegion trgn;
- QVector<QRect> a = rgn.rects();
- const QRect *r = a.data();
-
- int w = s.width();
- int h = s.height();
- int size = a.size();
-
- switch (d_ptr->transformation) {
- case None:
- break;
- case Rot90:
- for (int i = 0; i < size; i++, r++) {
- tr.setCoords(r->y(), w - r->x() - 1,
- r->bottom(), w - r->right() - 1);
- trgn |= correctNormalized(tr);
- }
- break;
- case Rot180:
- for (int i = 0; i < size; i++, r++) {
- tr.setCoords(w - r->x() - 1, h - r->y() - 1,
- w - r->right() - 1, h - r->bottom() - 1);
- trgn |= correctNormalized(tr);
- }
- break;
- case Rot270:
- for (int i = 0; i < size; i++, r++) {
- tr.setCoords(h - r->y() - 1, r->x(),
- h - r->bottom() - 1, r->right());
- trgn |= correctNormalized(tr);
- }
- break;
- }
-#ifdef QT_REGION_DEBUG
- qDebug() << "mapToDevice trgn: " << trgn;
-#endif
- return trgn;
-}
-
-/*!
- \reimp
-*/
-QRegion QTransformedScreen::mapFromDevice(const QRegion &rgn, const QSize &s) const
-{
- if (d_ptr->transformation == None)
- return QProxyScreen::mapFromDevice(rgn, s);
-
-#ifdef QT_REGION_DEBUG
- qDebug() << "fromDevice: realRegion count: " << rgn.rects().size() << " isEmpty? " << rgn.isEmpty() << " bounds:" << rgn.boundingRect();
-#endif
- QRect tr;
- QRegion trgn;
- QVector<QRect> a = rgn.rects();
- const QRect *r = a.data();
-
- int w = s.width();
- int h = s.height();
- int size = a.size();
-
- switch (d_ptr->transformation) {
- case None:
- break;
- case Rot90:
- for (int i = 0; i < size; i++, r++) {
- tr.setCoords(h - r->y() - 1, r->x(),
- h - r->bottom() - 1, r->right());
- trgn |= correctNormalized(tr);
- }
- break;
- case Rot180:
- for (int i = 0; i < size; i++, r++) {
- tr.setCoords(w - r->x() - 1, h - r->y() - 1,
- w - r->right() - 1, h - r->bottom() - 1);
- trgn |= correctNormalized(tr);
- }
- break;
- case Rot270:
- for (int i = 0; i < size; i++, r++) {
- tr.setCoords(r->y(), w - r->x() - 1,
- r->bottom(), w - r->right() - 1);
- trgn |= correctNormalized(tr);
- }
- break;
- }
-#ifdef QT_REGION_DEBUG
- qDebug() << "fromDevice: transRegion count: " << trgn.rects().size() << " isEmpty? " << trgn.isEmpty() << " bounds:" << trgn.boundingRect();
-#endif
- return trgn;
-}
-
-/*!
- \reimp
-*/
-void QTransformedScreen::setDirty(const QRect& rect)
-{
- const QRect r = mapToDevice(rect, QSize(width(), height()));
- QProxyScreen::setDirty(r);
-}
-
-/*!
- \reimp
-*/
-QRegion QTransformedScreen::region() const
-{
- QRegion deviceRegion = QProxyScreen::region();
- return mapFromDevice(deviceRegion, QSize(deviceWidth(), deviceHeight()));
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_QWS_TRANSFORMED
diff --git a/src/gui/embedded/qscreentransformed_qws.h b/src/gui/embedded/qscreentransformed_qws.h
deleted file mode 100644
index 180fc2d076..0000000000
--- a/src/gui/embedded/qscreentransformed_qws.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSCREENTRANSFORMED_QWS_H
-#define QSCREENTRANSFORMED_QWS_H
-
-#include <QtGui/qscreenproxy_qws.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_QWS_TRANSFORMED
-
-class QTransformedScreenPrivate;
-
-class Q_AUTOTEST_EXPORT QTransformedScreen : public QProxyScreen
-{
-public:
- explicit QTransformedScreen(int display_id);
- ~QTransformedScreen();
-
- enum Transformation { None, Rot90, Rot180, Rot270 };
-
- void setTransformation(Transformation t);
- Transformation transformation() const;
- int transformOrientation() const;
-
- QSize mapToDevice(const QSize &s) const;
- QSize mapFromDevice(const QSize &s) const;
-
- QPoint mapToDevice(const QPoint &, const QSize &) const;
- QPoint mapFromDevice(const QPoint &, const QSize &) const;
-
- QRect mapToDevice(const QRect &, const QSize &) const;
- QRect mapFromDevice(const QRect &, const QSize &) const;
-
- QRegion mapToDevice(const QRegion &, const QSize &) const;
- QRegion mapFromDevice(const QRegion &, const QSize &) const;
-
- bool connect(const QString &displaySpec);
-
- bool isTransformed() const { return transformation() != None; }
-
- void exposeRegion(QRegion region, int changing);
- void blit(const QImage &img, const QPoint &topLeft, const QRegion &region);
- void solidFill(const QColor &color, const QRegion &region);
- void setDirty(const QRect&);
-
- QRegion region() const;
-
-private:
- friend class QTransformedScreenPrivate;
- QTransformedScreenPrivate *d_ptr;
-};
-
-#endif // QT_NO_QWS_TRANSFORMED
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QSCREENTRANSFORMED_QWS_H
diff --git a/src/gui/embedded/qscreenvfb_qws.cpp b/src/gui/embedded/qscreenvfb_qws.cpp
deleted file mode 100644
index 2dc4f83a44..0000000000
--- a/src/gui/embedded/qscreenvfb_qws.cpp
+++ /dev/null
@@ -1,445 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QT_NO_QWS_QVFB
-
-#define QTOPIA_QVFB_BRIGHTNESS
-
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/ipc.h>
-#include <sys/shm.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-
-#include <qvfbhdr.h>
-#include <qscreenvfb_qws.h>
-#include <qkbdvfb_qws.h>
-#include <qmousevfb_qws.h>
-#include <qwindowsystem_qws.h>
-#include <qsocketnotifier.h>
-#include <qapplication.h>
-#include <qscreen_qws.h>
-#include <qmousedriverfactory_qws.h>
-#include <qkbddriverfactory_qws.h>
-#include <qdebug.h>
-
-QT_BEGIN_NAMESPACE
-
-class QVFbScreenPrivate
-{
-public:
- QVFbScreenPrivate();
- ~QVFbScreenPrivate();
-
- bool success;
- unsigned char *shmrgn;
- int brightness;
- bool blank;
- QVFbHeader *hdr;
- QWSMouseHandler *mouse;
-#ifndef QT_NO_QWS_KEYBOARD
- QWSKeyboardHandler *keyboard;
-#endif
-};
-
-QVFbScreenPrivate::QVFbScreenPrivate()
- : mouse(0)
-
-{
-#ifndef QT_NO_QWS_KEYBOARD
- keyboard = 0;
-#endif
- brightness = 255;
- blank = false;
-}
-
-QVFbScreenPrivate::~QVFbScreenPrivate()
-{
- delete mouse;
-#ifndef QT_NO_QWS_KEYBOARD
- delete keyboard;
-#endif
-}
-
-/*!
- \internal
-
- \class QVFbScreen
- \ingroup qws
-
- \brief The QVFbScreen class implements a screen driver for the
- virtual framebuffer.
-
- Note that this class is only available in \l{Qt for Embedded Linux}.
- Custom screen drivers can be added by subclassing the
- QScreenDriverPlugin class, using the QScreenDriverFactory class to
- dynamically load the driver into the application, but there should
- only be one screen object per application.
-
- The Qt for Embedded Linux platform provides a \l{The Virtual
- Framebuffer}{virtual framebuffer} for development and debugging;
- the virtual framebuffer allows Qt for Embedded Linux applications to be
- developed on a desktop machine, without switching between consoles
- and X11.
-
- \sa QScreen, QScreenDriverPlugin, {Running Applications}
-*/
-
-/*!
- \fn bool QVFbScreen::connect(const QString & displaySpec)
- \reimp
-*/
-
-/*!
- \fn void QVFbScreen::disconnect()
- \reimp
-*/
-
-/*!
- \fn bool QVFbScreen::initDevice()
- \reimp
-*/
-
-/*!
- \fn void QVFbScreen::restore()
- \reimp
-*/
-
-/*!
- \fn void QVFbScreen::save()
- \reimp
-*/
-
-/*!
- \fn void QVFbScreen::setDirty(const QRect & r)
- \reimp
-*/
-
-/*!
- \fn void QVFbScreen::setMode(int nw, int nh, int nd)
- \reimp
-*/
-
-/*!
- \fn void QVFbScreen::shutdownDevice()
- \reimp
-*/
-
-/*!
- \fn QVFbScreen::QVFbScreen(int displayId)
-
- Constructs a QVNCScreen object. The \a displayId argument
- identifies the Qt for Embedded Linux server to connect to.
-*/
-QVFbScreen::QVFbScreen(int display_id)
- : QScreen(display_id, VFbClass), d_ptr(new QVFbScreenPrivate)
-{
- d_ptr->shmrgn = 0;
- d_ptr->hdr = 0;
- data = 0;
-}
-
-/*!
- Destroys this QVFbScreen object.
-*/
-QVFbScreen::~QVFbScreen()
-{
- delete d_ptr;
-}
-
-static QVFbScreen *connected = 0;
-
-bool QVFbScreen::connect(const QString &displaySpec)
-{
- QStringList displayArgs = displaySpec.split(QLatin1Char(':'));
- if (displayArgs.contains(QLatin1String("Gray")))
- grayscale = true;
-
- key_t key = ftok(QT_VFB_MOUSE_PIPE(displayId).toLocal8Bit(), 'b');
-
- if (key == -1)
- return false;
-
-#if Q_BYTE_ORDER == Q_BIG_ENDIAN
-#ifndef QT_QWS_FRAMEBUFFER_LITTLE_ENDIAN
- if (displayArgs.contains(QLatin1String("littleendian")))
-#endif
- QScreen::setFrameBufferLittleEndian(true);
-#endif
-
- int shmId = shmget(key, 0, 0);
- if (shmId != -1)
- d_ptr->shmrgn = (unsigned char *)shmat(shmId, 0, 0);
- else
- return false;
-
- if ((long)d_ptr->shmrgn == -1 || d_ptr->shmrgn == 0) {
- qDebug("No shmrgn %ld", (long)d_ptr->shmrgn);
- return false;
- }
-
- d_ptr->hdr = (QVFbHeader *)d_ptr->shmrgn;
- data = d_ptr->shmrgn + d_ptr->hdr->dataoffset;
-
- dw = w = d_ptr->hdr->width;
- dh = h = d_ptr->hdr->height;
- d = d_ptr->hdr->depth;
-
- switch (d) {
- case 1:
- setPixelFormat(QImage::Format_Mono);
- break;
- case 8:
- setPixelFormat(QImage::Format_Indexed8);
- break;
- case 12:
- setPixelFormat(QImage::Format_RGB444);
- break;
- case 15:
- setPixelFormat(QImage::Format_RGB555);
- break;
- case 16:
- setPixelFormat(QImage::Format_RGB16);
- break;
- case 18:
- setPixelFormat(QImage::Format_RGB666);
- break;
- case 24:
- setPixelFormat(QImage::Format_RGB888);
- break;
- case 32:
- setPixelFormat(QImage::Format_ARGB32_Premultiplied);
- break;
- }
-
- lstep = d_ptr->hdr->linestep;
-
- // Handle display physical size spec.
- int dimIdxW = -1;
- int dimIdxH = -1;
- for (int i = 0; i < displayArgs.size(); ++i) {
- if (displayArgs.at(i).startsWith(QLatin1String("mmWidth"))) {
- dimIdxW = i;
- break;
- }
- }
- for (int i = 0; i < displayArgs.size(); ++i) {
- if (displayArgs.at(i).startsWith(QLatin1String("mmHeight"))) {
- dimIdxH = i;
- break;
- }
- }
- if (dimIdxW >= 0) {
- bool ok;
- int pos = 7;
- if (displayArgs.at(dimIdxW).at(pos) == QLatin1Char('='))
- ++pos;
- int pw = displayArgs.at(dimIdxW).mid(pos).toInt(&ok);
- if (ok) {
- physWidth = pw;
- if (dimIdxH < 0)
- physHeight = dh*physWidth/dw;
- }
- }
- if (dimIdxH >= 0) {
- bool ok;
- int pos = 8;
- if (displayArgs.at(dimIdxH).at(pos) == QLatin1Char('='))
- ++pos;
- int ph = displayArgs.at(dimIdxH).mid(pos).toInt(&ok);
- if (ok) {
- physHeight = ph;
- if (dimIdxW < 0)
- physWidth = dw*physHeight/dh;
- }
- }
- if (dimIdxW < 0 && dimIdxH < 0) {
- const int dpi = 72;
- physWidth = qRound(dw * 25.4 / dpi);
- physHeight = qRound(dh * 25.4 / dpi);
- }
-
- qDebug("Connected to VFB server %s: %d x %d x %d %dx%dmm (%dx%ddpi)", displaySpec.toLatin1().data(),
- w, h, d, physWidth, physHeight, qRound(dw*25.4/physWidth), qRound(dh*25.4/physHeight) );
-
- size = lstep * h;
- mapsize = size;
- screencols = d_ptr->hdr->numcols;
- memcpy(screenclut, d_ptr->hdr->clut, sizeof(QRgb) * screencols);
-
- connected = this;
-
- if (qgetenv("QT_QVFB_BGR").toInt())
- pixeltype = BGRPixel;
-
- return true;
-}
-
-void QVFbScreen::disconnect()
-{
- connected = 0;
- if ((long)d_ptr->shmrgn != -1 && d_ptr->shmrgn) {
- if (qApp->type() == QApplication::GuiServer && d_ptr->hdr->dataoffset >= (int)sizeof(QVFbHeader)) {
- d_ptr->hdr->serverVersion = 0;
- }
- shmdt((char*)d_ptr->shmrgn);
- }
-}
-
-bool QVFbScreen::initDevice()
-{
-#ifndef QT_NO_QWS_MOUSE_QVFB
- const QString mouseDev = QT_VFB_MOUSE_PIPE(displayId);
- d_ptr->mouse = new QVFbMouseHandler(QLatin1String("QVFbMouse"), mouseDev);
- qwsServer->setDefaultMouse("None");
- if (d_ptr->mouse)
- d_ptr->mouse->setScreen(this);
-#endif
-
-#if !defined(QT_NO_QWS_KBD_QVFB) && !defined(QT_NO_QWS_KEYBOARD)
- const QString keyboardDev = QT_VFB_KEYBOARD_PIPE(displayId);
- d_ptr->keyboard = new QVFbKeyboardHandler(keyboardDev);
- qwsServer->setDefaultKeyboard("None");
-#endif
-
- if (d_ptr->hdr->dataoffset >= (int)sizeof(QVFbHeader))
- d_ptr->hdr->serverVersion = QT_VERSION;
-
- if(d==8) {
- screencols=256;
- if (grayscale) {
- // Build grayscale palette
- for(int loopc=0;loopc<256;loopc++) {
- screenclut[loopc]=qRgb(loopc,loopc,loopc);
- }
- } else {
- // 6x6x6 216 color cube
- int idx = 0;
- for(int ir = 0x0; ir <= 0xff; ir+=0x33) {
- for(int ig = 0x0; ig <= 0xff; ig+=0x33) {
- for(int ib = 0x0; ib <= 0xff; ib+=0x33) {
- screenclut[idx]=qRgb(ir, ig, ib);
- idx++;
- }
- }
- }
- screencols=idx;
- }
- memcpy(d_ptr->hdr->clut, screenclut, sizeof(QRgb) * screencols);
- d_ptr->hdr->numcols = screencols;
- } else if (d == 4) {
- int val = 0;
- for (int idx = 0; idx < 16; idx++, val += 17) {
- screenclut[idx] = qRgb(val, val, val);
- }
- screencols = 16;
- memcpy(d_ptr->hdr->clut, screenclut, sizeof(QRgb) * screencols);
- d_ptr->hdr->numcols = screencols;
- } else if (d == 1) {
- screencols = 2;
- screenclut[1] = qRgb(0xff, 0xff, 0xff);
- screenclut[0] = qRgb(0, 0, 0);
- memcpy(d_ptr->hdr->clut, screenclut, sizeof(QRgb) * screencols);
- d_ptr->hdr->numcols = screencols;
- }
-
-#ifndef QT_NO_QWS_CURSOR
- QScreenCursor::initSoftwareCursor();
-#endif
- return true;
-}
-
-void QVFbScreen::shutdownDevice()
-{
-}
-
-void QVFbScreen::setMode(int ,int ,int)
-{
-}
-
-// save the state of the graphics card
-// This is needed so that e.g. we can restore the palette when switching
-// between linux virtual consoles.
-void QVFbScreen::save()
-{
- // nothing to do.
-}
-
-// restore the state of the graphics card.
-void QVFbScreen::restore()
-{
-}
-void QVFbScreen::setDirty(const QRect& rect)
-{
- const QRect r = rect.translated(-offset());
- d_ptr->hdr->dirty = true;
- d_ptr->hdr->update = d_ptr->hdr->update.united(r);
-}
-
-void QVFbScreen::setBrightness(int b)
-{
- if (connected) {
- connected->d_ptr->brightness = b;
-
- QVFbHeader *hdr = connected->d_ptr->hdr;
- if (hdr->viewerVersion < 0x040400) // brightness not supported
- return;
-
- const int br = connected->d_ptr->blank ? 0 : b;
- if (hdr->brightness != br) {
- hdr->brightness = br;
- connected->setDirty(connected->region().boundingRect());
- }
- }
-}
-
-void QVFbScreen::blank(bool on)
-{
- d_ptr->blank = on;
- setBrightness(connected->d_ptr->brightness);
-}
-
-#endif // QT_NO_QWS_QVFB
-
-QT_END_NAMESPACE
diff --git a/src/gui/embedded/qscreenvfb_qws.h b/src/gui/embedded/qscreenvfb_qws.h
deleted file mode 100644
index 5701a96dc1..0000000000
--- a/src/gui/embedded/qscreenvfb_qws.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSCREENVFB_QWS_H
-#define QSCREENVFB_QWS_H
-
-#include <QtGui/qscreen_qws.h>
-#include <QtGui/qvfbhdr.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_QWS_QVFB
-
-class QVFbScreenPrivate;
-
-class Q_GUI_EXPORT QVFbScreen : public QScreen
-{
-public:
- explicit QVFbScreen(int display_id);
- virtual ~QVFbScreen();
- virtual bool initDevice();
- virtual bool connect(const QString &displaySpec);
- virtual void disconnect();
- virtual void shutdownDevice();
- virtual void save();
- virtual void restore();
- virtual void setMode(int nw,int nh,int nd);
- virtual void setDirty(const QRect& r);
- virtual void blank(bool);
-#ifdef QTOPIA_QVFB_BRIGHTNESS
- static void setBrightness(int b);
-#endif
-
-private:
- QVFbScreenPrivate *d_ptr;
-};
-
-#endif // QT_NO_QWS_QVFB
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QSCREENVFB_QWS_H
diff --git a/src/gui/embedded/qsoundqss_qws.cpp b/src/gui/embedded/qsoundqss_qws.cpp
deleted file mode 100644
index e18a5a7b53..0000000000
--- a/src/gui/embedded/qsoundqss_qws.cpp
+++ /dev/null
@@ -1,1530 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qsoundqss_qws.h"
-
-#ifndef QT_NO_SOUND
-#include <qbytearray.h>
-#include <qlist.h>
-#include <qsocketnotifier.h>
-#include <qfile.h>
-#include <qfileinfo.h>
-#include <qstringlist.h>
-#include <qevent.h>
-#include <qalgorithms.h>
-#include <qtimer.h>
-#include <qpointer.h>
-#include <qendian.h>
-#include <private/qcore_unix_p.h> // overrides QT_OPEN
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <time.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-#include <sys/soundcard.h>
-
-#include <qdebug.h>
-
-#include <qvfbhdr.h>
-
-extern int errno;
-
-QT_BEGIN_NAMESPACE
-
-#define QT_QWS_SOUND_16BIT 1 // or 0, or undefined for always 0
-#define QT_QWS_SOUND_STEREO 1 // or 0, or undefined for always 0
-
-// Zaurus SL5000D doesn't seem to return any error if setting to 44000 and it fails,
-// however 44100 works, 44100 is more common that 44000.
-static int sound_speed = 44100;
-#ifndef QT_NO_QWS_SOUNDSERVER
-extern int qws_display_id;
-#endif
-
-static char *zeroMem = 0;
-
-struct QRiffChunk {
- char id[4];
- quint32 size;
- char data[4/*size*/];
-};
-
-#if defined(QT_QWS_IPAQ)
-static const int sound_fragment_size = 12;
-#else
-static const int sound_fragment_size = 12;
-#endif
-static const int sound_buffer_size = 1 << sound_fragment_size;
-// nb. there will be an sound startup delay of
-// 2^sound_fragment_size / sound_speed seconds.
-// (eg. sound_fragment_size==12, sound_speed==44000 means 0.093s delay)
-
-#ifdef QT_QWS_SOUND_STEREO
-static int sound_stereo=QT_QWS_SOUND_STEREO;
-#else
-static const int sound_stereo=0;
-#endif
-#ifdef QT_QWS_SOUND_16BIT
-static bool sound_16bit=QT_QWS_SOUND_16BIT;
-#else
-static const bool sound_16bit=false;
-#endif
-
-#ifndef QT_NO_QWS_SOUNDSERVER
-class QWSSoundServerClient : public QObject {
- Q_OBJECT
-
-public:
- QWSSoundServerClient(QWS_SOCK_BASE *s, QObject* parent);
- ~QWSSoundServerClient();
-
-public slots:
- void sendSoundCompleted(int, int);
- void sendDeviceReady(int, int);
- void sendDeviceError(int, int, int);
-
-signals:
- void play(int, int, const QString&);
- void play(int, int, const QString&, int, int);
- void playRaw(int, int, const QString&, int, int, int, int);
-
- void pause(int, int);
- void stop(int, int);
- void resume(int, int);
- void setVolume(int, int, int, int);
- void setMute(int, int, bool);
-
- void stopAll(int);
-
- void playPriorityOnly(bool);
-
- void setSilent( bool );
-
-private slots:
- void tryReadCommand();
-
-private:
- void sendClientMessage(QString msg);
- int mCurrentID;
- int left, right;
- bool priExist;
- static int lastId;
- static int nextId() { return ++lastId; }
- QPointer<QWS_SOCK_BASE> socket;
-};
-
-int QWSSoundServerClient::lastId = 0;
-
-QWSSoundServerClient::QWSSoundServerClient(QWS_SOCK_BASE *s, QObject* parent) :
- QObject( parent )
-{
- socket = s;
- priExist = false;
- mCurrentID = nextId();
- connect(socket,SIGNAL(readyRead()),
- this,SLOT(tryReadCommand()));
- connect(socket, SIGNAL(disconnected()), this, SLOT(deleteLater()));
-}
-
-QWSSoundServerClient::~QWSSoundServerClient()
-{
- if (priExist)
- playPriorityOnly(false);
- emit stopAll(mCurrentID);
- if (socket)
- socket->deleteLater();
-}
-
-static QString getStringTok(QString &in)
-{
- int pos = in.indexOf(QLatin1Char(' '));
- QString ret;
- if (pos > 0) {
- ret = in.left(pos);
- in = in.mid(pos+1);
- } else {
- ret = in;
- in = QString::null;
- }
- return ret;
-}
-
-static int getNumTok(QString &in)
-{
- return getStringTok(in).toInt();
-}
-
-void QWSSoundServerClient::tryReadCommand()
-{
- while ( socket->canReadLine() ) {
- QString l = QString::fromAscii(socket->readLine());
- l.truncate(l.length()-1); // chomp
- QString functionName = getStringTok(l);
- int soundid = getNumTok(l);
- if (functionName == QLatin1String("PLAY")) {
- emit play(mCurrentID, soundid, l);
- } else if (functionName == QLatin1String("PLAYEXTEND")) {
- int volume = getNumTok(l);
- int flags = getNumTok(l);
- emit play(mCurrentID, soundid, l, volume, flags);
- } else if (functionName == QLatin1String("PLAYRAW")) {
- int chs = getNumTok(l);
- int freq = getNumTok(l);
- int bitspersample = getNumTok(l);
- int flags = getNumTok(l);
- emit playRaw(mCurrentID, soundid, l, freq, chs, bitspersample, flags);
- } else if (functionName == QLatin1String("PAUSE")) {
- emit pause(mCurrentID, soundid);
- } else if (functionName == QLatin1String("STOP")) {
- emit stop(mCurrentID, soundid);
- } else if (functionName == QLatin1String("RESUME")) {
- emit resume(mCurrentID, soundid);
- } else if (functionName == QLatin1String("SETVOLUME")) {
- int left = getNumTok(l);
- int right = getNumTok(l);
- emit setVolume(mCurrentID, soundid, left, right);
- } else if (functionName == QLatin1String("MUTE")) {
- emit setMute(mCurrentID, soundid, true);
- } else if (functionName == QLatin1String("UNMUTE")) {
- emit setMute(mCurrentID, soundid, false);
- } else if (functionName == QLatin1String("PRIORITYONLY")) {
- bool sPri = soundid != 0;
- if (sPri != priExist) {
- priExist = sPri;
- emit playPriorityOnly(sPri);
- }
- } else if(functionName == QLatin1String("SILENT")) {
- emit setSilent( soundid != 0 );
- }
- }
-}
-
-void QWSSoundServerClient::sendClientMessage(QString msg)
-{
-#ifndef QT_NO_TEXTCODEC
- QByteArray u = msg.toUtf8();
-#else
- QByteArray u = msg.toLatin1();
-#endif
- socket->write(u.data(), u.length());
- socket->flush();
-}
-
-void QWSSoundServerClient::sendSoundCompleted(int gid, int sid)
-{
- if (gid == mCurrentID)
- sendClientMessage(QLatin1String("SOUNDCOMPLETED ")
- + QString::number(sid) + QLatin1Char('\n'));
-}
-
-void QWSSoundServerClient::sendDeviceReady(int gid, int sid)
-{
- if (gid == mCurrentID)
- sendClientMessage(QLatin1String("DEVICEREADY ")
- + QString::number(sid) + QLatin1Char('\n'));
-}
-
-void QWSSoundServerClient::sendDeviceError(int gid, int sid, int err)
-{
- if (gid == mCurrentID)
- sendClientMessage(QLatin1String("DEVICEERROR ")
- + QString::number(sid) + QLatin1Char(' ')
- + QString::number(err) + QLatin1Char('\n'));
-}
-#endif
-
-static const int maxVolume = 100;
-static const int runinLength = 2*sound_buffer_size;
-class QWSSoundServerProvider {
-public:
- QWSSoundServerProvider(int w, int s)
- : mWid(w), mSid(s), mMuted(false)
- {
- leftVolume = maxVolume>>1;
- rightVolume = maxVolume>>1;
- isPriority = false;
- samples_due = 0;
- max1 = max2 = out = 0;// = sound_buffer_size;
- data = data1;
- max = &max1;
- sampleRunin = 0;
- dev = -1;
- }
-
- virtual ~QWSSoundServerProvider() {
- }
-
- int groupId() const { return mWid; }
- int soundId() const { return mSid; }
-
- void startSampleRunin() {
- // inteded to provide even audio return from mute/pause/dead samples.
- //sampleRunin = runinLength; // or more?
- }
-
-
- void setVolume(int lv, int rv) {
- leftVolume = qMin(maxVolume, qMax(0, lv));
- rightVolume = qMin(maxVolume, qMax(0, rv));
- }
-
- void setMute(bool m) { mMuted = m; }
- bool muted() { return mMuted; }
-
- void setPriority(bool p) {
- if (p != isPriority) {
- isPriority = p; // currently meaningless.
- }
- }
-
-
- static void setPlayPriorityOnly(bool p)
- {
- if (p)
- priorityExists++;
- else
- priorityExists--;
-
- if (priorityExists < 0)
- qDebug("QSS: got more priority offs than ons");
- }
-
- // return -1 for file broken, give up.
- // else return sampels ready for playing.
- // argument is max samples server is looking for,
- // in terms of current device status.
- virtual int readySamples(int) = 0;
-
- int getSample(int off, int bps) {
-
- //
- // 16-bit audio data is converted to native endian so that it can be scaled
- // Yes, this is ugly on a BigEndian machine
- // Perhaps it shouldn't be scaled at all
- //
- return (bps == 1) ? (data[out+off] - 128) * 128 : qToLittleEndian(((short*)data)[(out/2)+off]);
- }
-
- int add(int* mixl, int* mixr, int count)
- {
- int bytesPerSample = chunkdata.wBitsPerSample >> 3;
-
- if ( mMuted ) {
- sampleRunin -= qMin(sampleRunin,count);
- while (count && (dev != -1)) {
- if (out >= *max) {
- // switch buffers
- out = 0;
- if (data == data1 && max2 != 0) {
- data = data2;
- max = &max2;
- max1 = 0;
- } else if (data == data2 && max1 != 0) {
- data = data1;
- max = &max1;
- max2 = 0;
- } else {
- qDebug("QSS Read Error: both buffers empty");
- return 0;
- }
- }
- samples_due += sound_speed;
- while (count && samples_due >= chunkdata.samplesPerSec) {
- samples_due -= chunkdata.samplesPerSec;
- count--;
- }
- out += bytesPerSample * chunkdata.channels;
- }
- return count;
- }
-
- // This shouldn't be the case
- if ( !mixl || !mixr )
- return 0;
-
- int lVolNum = leftVolume, lVolDen = maxVolume;
- int rVolNum = rightVolume, rVolDen = maxVolume;
- if (priorityExists > 0 && !isPriority) {
- lVolNum = 0; // later, make this gradually fade in and out.
- lVolDen = 5;
- rVolNum = 0;
- rVolDen = 5;
- }
-
- while (count && (dev != -1)) {
- if (out >= *max) {
- // switch buffers
- out = 0;
- if (data == data1 && max2 != 0) {
- data = data2;
- max = &max2;
- max1 = 0;
- } else if (data == data2 && max1 != 0) {
- data = data1;
- max = &max1;
- max2 = 0;
- } else {
- qDebug("QSS Read Error: both buffers empty");
- return 0;
- }
- }
- samples_due += sound_speed;
- if (count && samples_due >= chunkdata.samplesPerSec) {
- int l = getSample(0,bytesPerSample)*lVolNum/lVolDen;
- int r = (chunkdata.channels == 2) ? getSample(1,bytesPerSample)*rVolNum/rVolDen : l;
- if (!sound_stereo && chunkdata.channels == 2)
- l += r;
- if (sampleRunin) {
- while (sampleRunin && count && samples_due >= chunkdata.samplesPerSec) {
- mixl++;
- if (sound_stereo)
- mixr++;
- samples_due -= chunkdata.samplesPerSec;
- sampleRunin--;
- count--;
- }
- }
- while (count && samples_due >= chunkdata.samplesPerSec) {
- *mixl++ += l;
- if (sound_stereo)
- *mixr++ += r;
- samples_due -= chunkdata.samplesPerSec;
- count--;
- }
- }
-
- // optimize out manipulation of sample if downsampling and we skip it
- out += bytesPerSample * chunkdata.channels;
- }
-
- return count;
- }
-
- virtual bool finished() const = 0;
-
- bool equal(int wid, int sid)
- {
- return (wid == mWid && sid == mSid);
- }
-
-protected:
-
- char * prepareBuffer( int &size)
- {
- // keep reading as long as there is 50 % or more room in off buffer.
- if (data == data1 && (max2<<1 < sound_buffer_size)) {
- size=sound_buffer_size - max2;
- return (char *)data2;
- } else if (data == data2 && (max1<<1 < sound_buffer_size)) {
- size=sound_buffer_size - max1;
- return (char *)data1;
- } else {
- size = 0;
- return 0;
- }
- }
-
- void updateBuffer(int read)
- {
- // always reads to off buffer.
- if (read >= 0) {
- if (data == data2) {
- max1 = read;
- } else {
- max2 = read;
- }
- }
- }
-
- int devSamples()
- {
- int possible = (((max1+max2-out) / ((chunkdata.wBitsPerSample>>3)*chunkdata.channels))
- *sound_speed)/chunkdata.samplesPerSec;
-
- return possible;
- }
-
-
- struct {
- qint16 formatTag;
- qint16 channels;
- qint32 samplesPerSec;
- qint32 avgBytesPerSec;
- qint16 blockAlign;
- qint16 wBitsPerSample;
- } chunkdata;
- int dev;
- int samples_due;
-private:
- int mWid;
- int mSid;
- int leftVolume;
- int rightVolume;
- bool isPriority;
- static int priorityExists;
- int *max;
- uchar *data;
- uchar data1[sound_buffer_size+4]; // +4 to handle badly aligned input data
- uchar data2[sound_buffer_size+4]; // +4 to handle badly aligned input data
- int out, max1, max2;
- int sampleRunin;
- bool mMuted;
-};
-
-int QWSSoundServerProvider::priorityExists = 0;
-
-class QWSSoundServerBucket : public QWSSoundServerProvider {
-public:
- QWSSoundServerBucket(int d, int wid, int sid)
- : QWSSoundServerProvider(wid, sid)
- {
- dev = d;
- wavedata_remaining = -1;
- mFinishedRead = false;
- mInsufficientSamples = false;
- }
- ~QWSSoundServerBucket()
- {
- //dev->close();
- ::close(dev);
- }
- bool finished() const
- {
- //return !max;
- return mInsufficientSamples && mFinishedRead ;
- }
- int readySamples(int)
- {
- int size;
- char *dest = prepareBuffer(size);
- // may want to change this to something like
- // if (data == data1 && max2<<1 < sound_buffer_size
- // ||
- // data == data2 && max1<<1 < sound_buffer_size)
- // so will keep filling off buffer while there is +50% space left
- if (size > 0 && dest != 0) {
- while ( wavedata_remaining < 0 ) {
- //max = 0;
- wavedata_remaining = -1;
- // Keep reading chunks...
- const int n = sizeof(chunk)-sizeof(chunk.data);
- int nr = ::read(dev, (void*)&chunk,n);
- if ( nr != n ) {
- // XXX check error? or don't we care?
- wavedata_remaining = 0;
- mFinishedRead = true;
- } else if ( qstrncmp(chunk.id,"data",4) == 0 ) {
- wavedata_remaining = qToLittleEndian( chunk.size );
-
- //out = max = sound_buffer_size;
-
- } else if ( qstrncmp(chunk.id,"RIFF",4) == 0 ) {
- char d[4];
- if ( read(dev, d, 4) != 4 ) {
- // XXX check error? or don't we care?
- //qDebug("couldn't read riff");
- mInsufficientSamples = true;
- mFinishedRead = true;
- return 0;
- } else if ( qstrncmp(d,"WAVE",4) != 0 ) {
- // skip
- if ( chunk.size > 1000000000 || lseek(dev,chunk.size-4, SEEK_CUR) == -1 ) {
- //qDebug("oversized wav chunk");
- mFinishedRead = true;
- }
- }
- } else if ( qstrncmp(chunk.id,"fmt ",4) == 0 ) {
- if ( ::read(dev,(char*)&chunkdata,sizeof(chunkdata)) != sizeof(chunkdata) ) {
- // XXX check error? or don't we care?
- //qDebug("couldn't ready chunkdata");
- mFinishedRead = true;
- }
-
-#define WAVE_FORMAT_PCM 1
- else
- {
- /*
- ** Endian Fix the chuck data
- */
- chunkdata.formatTag = qToLittleEndian( chunkdata.formatTag );
- chunkdata.channels = qToLittleEndian( chunkdata.channels );
- chunkdata.samplesPerSec = qToLittleEndian( chunkdata.samplesPerSec );
- chunkdata.avgBytesPerSec = qToLittleEndian( chunkdata.avgBytesPerSec );
- chunkdata.blockAlign = qToLittleEndian( chunkdata.blockAlign );
- chunkdata.wBitsPerSample = qToLittleEndian( chunkdata.wBitsPerSample );
- if ( chunkdata.formatTag != WAVE_FORMAT_PCM ) {
- qWarning("WAV file: UNSUPPORTED FORMAT %d",chunkdata.formatTag);
- mFinishedRead = true;
- }
- }
- } else {
- // ignored chunk
- if ( chunk.size > 1000000000 || lseek(dev, chunk.size, SEEK_CUR) == -1) {
- //qDebug("chunk size too big");
- mFinishedRead = true;
- }
- }
- }
- // this looks wrong.
- if (wavedata_remaining <= 0) {
- mFinishedRead = true;
- }
-
- }
- // may want to change this to something like
- // if (data == data1 && max2<<1 < sound_buffer_size
- // ||
- // data == data2 && max1<<1 < sound_buffer_size)
- // so will keep filling off buffer while there is +50% space left
-
- if (wavedata_remaining) {
- if (size > 0 && dest != 0) {
- int read = ::read(dev, dest, qMin(size, wavedata_remaining));
- // XXX check error? or don't we care?
- wavedata_remaining -= read;
- updateBuffer(read);
- if (read <= 0) // data unexpectidly ended
- mFinishedRead = true;
- }
- }
- int possible = devSamples();
- if (possible == 0)
- mInsufficientSamples = true;
- return possible;
- }
-
-protected:
- QRiffChunk chunk;
- int wavedata_remaining;
- bool mFinishedRead;
- bool mInsufficientSamples;
-};
-
-class QWSSoundServerStream : public QWSSoundServerProvider {
-public:
- QWSSoundServerStream(int d,int c, int f, int b,
- int wid, int sid)
- : QWSSoundServerProvider(wid, sid)
- {
- chunkdata.channels = c;
- chunkdata.samplesPerSec = f;
- chunkdata.wBitsPerSample = b;
- dev = d;
- //fcntl( dev, F_SETFL, O_NONBLOCK );
- lasttime = 0;
- }
-
- ~QWSSoundServerStream()
- {
- if (dev != -1) {
- ::close(dev);
- dev = -1;
- }
- }
-
- bool finished() const
- {
- return (dev == -1);
- }
-
-
- int readySamples(int)
- {
- int size;
- char *dest = prepareBuffer(size);
- if (size > 0 && dest != 0 && dev != -1) {
-
- int read = ::read(dev, dest, size);
- if (read < 0) {
- switch(errno) {
- case EAGAIN:
- case EINTR:
- // means read may yet succeed on the next attempt
- break;
- default:
- // unexpected error, fail.
- ::close(dev);
- dev = -1;
- }
- } else if (read == 0) {
- // 0 means writer has closed dev and/or
- // file is at end.
- ::close(dev);
- dev = -1;
- } else {
- updateBuffer(read);
- }
- }
- int possible = devSamples();
- if (possible == 0)
- startSampleRunin();
- return possible;
- }
-
-protected:
- time_t lasttime;
-};
-
-#ifndef QT_NO_QWS_SOUNDSERVER
-QWSSoundServerSocket::QWSSoundServerSocket(QObject *parent) :
- QWSServerSocket(QT_VFB_SOUND_PIPE(qws_display_id), parent)
-{
- connect(this, SIGNAL(newConnection()), this, SLOT(newConnection()));
-}
-
-
-#ifdef QT3_SUPPORT
-QWSSoundServerSocket::QWSSoundServerSocket(QObject *parent, const char *name) :
- QWSServerSocket(QT_VFB_SOUND_PIPE(qws_display_id), parent)
-{
- if (name)
- setObjectName(QString::fromAscii(name));
- connect(this, SIGNAL(newConnection()), this, SLOT(newConnection()));
-}
-#endif
-
-void QWSSoundServerSocket::newConnection()
-{
- while (QWS_SOCK_BASE *sock = nextPendingConnection()) {
- QWSSoundServerClient* client = new QWSSoundServerClient(sock,this);
-
- connect(client, SIGNAL(play(int,int,QString)),
- this, SIGNAL(playFile(int,int,QString)));
- connect(client, SIGNAL(play(int,int,QString,int,int)),
- this, SIGNAL(playFile(int,int,QString,int,int)));
- connect(client, SIGNAL(playRaw(int,int,QString,int,int,int,int)),
- this, SIGNAL(playRawFile(int,int,QString,int,int,int,int)));
-
- connect(client, SIGNAL(pause(int,int)),
- this, SIGNAL(pauseFile(int,int)));
- connect(client, SIGNAL(stop(int,int)),
- this, SIGNAL(stopFile(int,int)));
- connect(client, SIGNAL(playPriorityOnly(bool)),
- this, SIGNAL(playPriorityOnly(bool)));
- connect(client, SIGNAL(stopAll(int)),
- this, SIGNAL(stopAll(int)));
- connect(client, SIGNAL(resume(int,int)),
- this, SIGNAL(resumeFile(int,int)));
-
- connect(client, SIGNAL(setSilent(bool)),
- this, SIGNAL(setSilent(bool)));
-
- connect(client, SIGNAL(setMute(int,int,bool)),
- this, SIGNAL(setMute(int,int,bool)));
- connect(client, SIGNAL(setVolume(int,int,int,int)),
- this, SIGNAL(setVolume(int,int,int,int)));
-
- connect(this, SIGNAL(soundFileCompleted(int,int)),
- client, SLOT(sendSoundCompleted(int,int)));
- connect(this, SIGNAL(deviceReady(int,int)),
- client, SLOT(sendDeviceReady(int,int)));
- connect(this, SIGNAL(deviceError(int,int,int)),
- client, SLOT(sendDeviceError(int,int,int)));
- }
-}
-
-#endif
-
-class QWSSoundServerPrivate : public QObject {
- Q_OBJECT
-
-public:
- QWSSoundServerPrivate(QObject* parent=0, const char* name=0) :
- QObject(parent)
- {
- timerId = 0;
- if (name)
- setObjectName(QString::fromAscii(name));
-#ifndef QT_NO_QWS_SOUNDSERVER
- server = new QWSSoundServerSocket(this);
-
- connect(server, SIGNAL(playFile(int,int,QString)),
- this, SLOT(playFile(int,int,QString)));
- connect(server, SIGNAL(playFile(int,int,QString,int,int)),
- this, SLOT(playFile(int,int,QString,int,int)));
- connect(server, SIGNAL(playRawFile(int,int,QString,int,int,int,int)),
- this, SLOT(playRawFile(int,int,QString,int,int,int,int)));
-
- connect(server, SIGNAL(pauseFile(int,int)),
- this, SLOT(pauseFile(int,int)));
- connect(server, SIGNAL(stopFile(int,int)),
- this, SLOT(stopFile(int,int)));
- connect(server, SIGNAL(stopAll(int)),
- this, SLOT(stopAll(int)));
- connect(server, SIGNAL(playPriorityOnly(bool)),
- this, SLOT(playPriorityOnly(bool)));
- connect(server, SIGNAL(resumeFile(int,int)),
- this, SLOT(resumeFile(int,int)));
-
- connect( server, SIGNAL(setSilent(bool)),
- this, SLOT(setSilent(bool)));
-
- connect(server, SIGNAL(setMute(int,int,bool)),
- this, SLOT(setMute(int,int,bool)));
- connect(server, SIGNAL(setVolume(int,int,int,int)),
- this, SLOT(setVolume(int,int,int,int)));
-
- connect(this, SIGNAL(soundFileCompleted(int,int)),
- server, SIGNAL(soundFileCompleted(int,int)));
- connect(this, SIGNAL(deviceReady(int,int)),
- server, SIGNAL(deviceReady(int,int)));
- connect(this, SIGNAL(deviceError(int,int,int)),
- server, SIGNAL(deviceError(int,int,int)));
-
-#endif
- silent = false;
- fd = -1;
- unwritten = 0;
- can_GETOSPACE = true;
- }
-
- ~QWSSoundServerPrivate()
- {
- qDeleteAll(active);
- qDeleteAll(inactive);
- }
-
-signals:
- void soundFileCompleted(int, int);
- void deviceReady(int, int);
- void deviceError(int, int, int);
-
-public slots:
- void playRawFile(int wid, int sid, const QString &filename, int freq, int channels, int bitspersample, int flags);
- void playFile(int wid, int sid, const QString& filename);
- void playFile(int wid, int sid, const QString& filename, int v, int flags);
- void checkPresetVolumes(int wid, int sid, QWSSoundServerProvider *p);
- void pauseFile(int wid, int sid);
- void resumeFile(int wid, int sid);
- void stopFile(int wid, int sid);
- void stopAll(int wid);
- void setVolume(int wid, int sid, int lv, int rv);
- void setMute(int wid, int sid, bool m);
- void playPriorityOnly(bool p);
- void sendCompletedSignals();
- void feedDevice(int fd);
- void setSilent( bool enabled );
-
-protected:
- void timerEvent(QTimerEvent* event);
-
-private:
- int openFile(int wid, int sid, const QString& filename);
- bool openDevice();
- void closeDevice()
- {
- if (fd >= 0) {
- ::close(fd);
- fd = -1;
- }
- }
-
- QList<QWSSoundServerProvider*> active;
- QList<QWSSoundServerProvider*> inactive;
- struct PresetVolume {
- int wid;
- int sid;
- int left;
- int right;
- bool mute;
- };
- QList<PresetVolume> volumes;
- struct CompletedInfo {
- CompletedInfo( ) : groupId( 0 ), soundId( 0 ) { }
- CompletedInfo( int _groupId, int _soundId ) : groupId( _groupId ), soundId( _soundId ) { }
- int groupId;
- int soundId;
- };
- QList<CompletedInfo> completed;
-
- bool silent;
-
- int fd;
- int unwritten;
- int timerId;
- char* cursor;
- short data[sound_buffer_size*2];
- bool can_GETOSPACE;
-#ifndef QT_NO_QWS_SOUNDSERVER
- QWSSoundServerSocket *server;
-#endif
-};
-
-void QWSSoundServerPrivate::setSilent( bool enabled )
-{
- // Close output device
- closeDevice();
- if( !unwritten && !active.count() ) {
- sendCompletedSignals();
- }
- // Stop processing audio
- killTimer( timerId );
- silent = enabled;
- // If audio remaining, open output device and continue processing
- if( unwritten || active.count() ) {
- openDevice();
- }
-}
-
-void QWSSoundServerPrivate::timerEvent(QTimerEvent* event)
-{
- // qDebug("QSS timer event");
- if( event->timerId() == timerId ) {
- if (fd >= 0)
- feedDevice(fd);
- if (fd < 0) {
- killTimer(timerId);
- timerId = 0;
- }
- }
-}
-
-void QWSSoundServerPrivate::playRawFile(int wid, int sid, const QString &filename,
- int freq, int channels, int bitspersample, int flags)
-{
-#ifdef QT_NO_QWS_SOUNDSERVER
- Q_UNUSED(flags);
-#endif
- int f = openFile(wid, sid, filename);
- if ( f ) {
- QWSSoundServerStream *b = new QWSSoundServerStream(f, channels, freq, bitspersample, wid, sid);
- // check preset volumes.
- checkPresetVolumes(wid, sid, b);
-#ifndef QT_NO_QWS_SOUNDSERVER
- b->setPriority((flags & QWSSoundClient::Priority) == QWSSoundClient::Priority);
-#endif
- active.append(b);
- emit deviceReady(wid, sid);
- }
-}
-
-void QWSSoundServerPrivate::playFile(int wid, int sid, const QString& filename)
-{
- int f = openFile(wid, sid, filename);
- if ( f ) {
- QWSSoundServerProvider *b = new QWSSoundServerBucket(f, wid, sid);
- checkPresetVolumes(wid, sid, b);
- active.append( b );
- emit deviceReady(wid, sid);
- }
-}
-
-void QWSSoundServerPrivate::playFile(int wid, int sid, const QString& filename,
- int v, int flags)
-{
-#ifdef QT_NO_QWS_SOUNDSERVER
- Q_UNUSED(flags);
-#endif
- int f = openFile(wid, sid, filename);
- if ( f ) {
- QWSSoundServerProvider *b = new QWSSoundServerBucket(f, wid, sid);
- checkPresetVolumes(wid, sid, b);
- b->setVolume(v, v);
-#ifndef QT_NO_QWS_SOUNDSERVER
- b->setPriority((flags & QWSSoundClient::Priority) == QWSSoundClient::Priority);
-#endif
- active.append(b);
- emit deviceReady(wid, sid);
- }
-}
-
-void QWSSoundServerPrivate::checkPresetVolumes(int wid, int sid, QWSSoundServerProvider *p)
-{
- QList<PresetVolume>::Iterator it = volumes.begin();
- while (it != volumes.end()) {
- PresetVolume v = *it;
- if (v.wid == wid && v.sid == sid) {
- p->setVolume(v.left, v.right);
- p->setMute(v.mute);
- it = volumes.erase(it);
- return;
- } else {
- ++it;
- }
- }
-}
-
-void QWSSoundServerPrivate::pauseFile(int wid, int sid)
-{
- QWSSoundServerProvider *bucket;
- for (int i = 0; i < active.size(); ++i ) {
- bucket = active.at(i);
- if (bucket->equal(wid, sid)) {
- // found bucket....
- active.removeAt(i);
- inactive.append(bucket);
- return;
- }
- }
-}
-
-void QWSSoundServerPrivate::resumeFile(int wid, int sid)
-{
- QWSSoundServerProvider *bucket;
- for (int i = 0; i < inactive.size(); ++i ) {
- bucket = inactive.at(i);
- if (bucket->equal(wid, sid)) {
- // found bucket....
- inactive.removeAt(i);
- active.append(bucket);
- return;
- }
- }
-}
-
-void QWSSoundServerPrivate::stopFile(int wid, int sid)
-{
- QWSSoundServerProvider *bucket;
- for (int i = 0; i < active.size(); ++i ) {
- bucket = active.at(i);
- if (bucket->equal(wid, sid)) {
- active.removeAt(i);
- delete bucket;
- return;
- }
- }
- for (int i = 0; i < inactive.size(); ++i ) {
- bucket = inactive.at(i);
- if (bucket->equal(wid, sid)) {
- inactive.removeAt(i);
- delete bucket;
- return;
- }
- }
-}
-
-void QWSSoundServerPrivate::stopAll(int wid)
-{
- QWSSoundServerProvider *bucket;
- if (!active.isEmpty()) {
- QList<QWSSoundServerProvider*>::Iterator it = active.begin();
- while (it != active.end()) {
- bucket = *it;
- if (bucket->groupId() == wid) {
- it = active.erase(it);
- delete bucket;
- } else {
- ++it;
- }
- }
- }
- if (!inactive.isEmpty()) {
- QList<QWSSoundServerProvider*>::Iterator it = inactive.begin();
- while (it != inactive.end()) {
- bucket = *it;
- if (bucket->groupId() == wid) {
- it = inactive.erase(it);
- delete bucket;
- } else {
- ++it;
- }
- }
- }
-}
-
-void QWSSoundServerPrivate::setVolume(int wid, int sid, int lv, int rv)
-{
- QWSSoundServerProvider *bucket;
- for( int i = 0; i < active.size(); ++i ) {
- bucket = active.at(i);
- if (bucket->equal(wid, sid)) {
- bucket->setVolume(lv,rv);
- return;
- }
- }
- // If gotten here, then it means wid/sid wasn't set up yet.
- // first find and remove current preset volumes, then add this one.
- QList<PresetVolume>::Iterator it = volumes.begin();
- while (it != volumes.end()) {
- PresetVolume v = *it;
- if (v.wid == wid && v.sid == sid)
- it = volumes.erase(it);
- else
- ++it;
- }
- // and then add this volume
- PresetVolume nv;
- nv.wid = wid;
- nv.sid = sid;
- nv.left = lv;
- nv.right = rv;
- nv.mute = false;
- volumes.append(nv);
-}
-
-void QWSSoundServerPrivate::setMute(int wid, int sid, bool m)
-{
- QWSSoundServerProvider *bucket;
- for( int i = 0; i < active.size(); ++i ) {
- bucket = active.at(i);
- if (bucket->equal(wid, sid)) {
- bucket->setMute(m);
- return;
- }
- }
- // if gotten here then setting is being applied before item
- // is created.
- QList<PresetVolume>::Iterator it = volumes.begin();
- while (it != volumes.end()) {
- PresetVolume v = *it;
- if (v.wid == wid && v.sid == sid) {
- (*it).mute = m;
- return;
- }
- }
- if (m) {
- PresetVolume nv;
- nv.wid = wid;
- nv.sid = sid;
- nv.left = maxVolume>>1;
- nv.right = maxVolume>>1;
- nv.mute = true;
- volumes.append(nv);
- }
-}
-
-void QWSSoundServerPrivate::playPriorityOnly(bool p)
-{
- QWSSoundServerProvider::setPlayPriorityOnly(p);
-}
-
-void QWSSoundServerPrivate::sendCompletedSignals()
-{
- while( !completed.isEmpty() ) {
- emit soundFileCompleted( (*completed.begin()).groupId,
- (*completed.begin()).soundId );
- completed.erase( completed.begin() );
- }
-}
-
-
-int QWSSoundServerPrivate::openFile(int wid, int sid, const QString& filename)
-{
- stopFile(wid, sid); // close and re-open.
- int f = QT_OPEN(QFile::encodeName(filename), O_RDONLY|O_NONBLOCK);
- if (f == -1) {
- // XXX check ferror, check reason.
- qDebug("Failed opening \"%s\"",filename.toLatin1().data());
-#ifndef QT_NO_QWS_SOUNDSERVER
- emit deviceError(wid, sid, (int)QWSSoundClient::ErrOpeningFile );
-#endif
- } else if ( openDevice() ) {
- return f;
- }
-#ifndef QT_NO_QWS_SOUNDSERVER
- emit deviceError(wid, sid, (int)QWSSoundClient::ErrOpeningAudioDevice );
-#endif
- return 0;
-}
-
-bool QWSSoundServerPrivate::openDevice()
-{
- if (fd < 0) {
- if( silent ) {
- fd = QT_OPEN( "/dev/null", O_WRONLY );
- // Emulate write to audio device
- int delay = 1000*(sound_buffer_size>>(sound_stereo+sound_16bit))/sound_speed/2;
- timerId = startTimer(delay);
-
- return true;
- }
- //
- // Don't block open right away.
- //
- bool openOkay = false;
- if ((fd = QT_OPEN("/dev/dsp", O_WRONLY|O_NONBLOCK)) != -1) {
- int flags = fcntl(fd, F_GETFL);
- flags &= ~O_NONBLOCK;
- openOkay = (fcntl(fd, F_SETFL, flags) == 0);
- }
- if (!openOkay) {
- qDebug("Failed opening audio device");
- return false;
- }
-
- // Setup soundcard at 16 bit mono
- int v;
- //v=0x00010000+sound_fragment_size;
- // um the media player did this instead.
- v=0x10000 * 4 + sound_fragment_size;
- if (ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &v))
- qWarning("Could not set fragments to %08x",v);
-#ifdef QT_QWS_SOUND_16BIT
- //
- // Use native endian
- // Since we have manipulated the data volume the data
- // is now in native format, even though its stored
- // as little endian in the WAV file
- //
- v=AFMT_S16_NE; if (ioctl(fd, SNDCTL_DSP_SETFMT, &v))
- qWarning("Could not set format %d",v);
- if (AFMT_S16_NE != v)
- qDebug("Want format %d got %d", AFMT_S16_LE, v);
-#else
- v=AFMT_U8; if (ioctl(fd, SNDCTL_DSP_SETFMT, &v))
- qWarning("Could not set format %d",v);
- if (AFMT_U8 != v)
- qDebug("Want format %d got %d", AFMT_U8, v);
-#endif
- v=sound_stereo; if (ioctl(fd, SNDCTL_DSP_STEREO, &v))
- qWarning("Could not set stereo %d",v);
- if (sound_stereo != v)
- qDebug("Want stereo %d got %d", sound_stereo, v);
-#ifdef QT_QWS_SOUND_STEREO
- sound_stereo=v;
-#endif
- v=sound_speed; if (ioctl(fd, SNDCTL_DSP_SPEED, &sound_speed))
- qWarning("Could not set speed %d",v);
- if (v != sound_speed)
- qDebug("Want speed %d got %d", v, sound_speed);
-
- int delay = 1000*(sound_buffer_size>>(sound_stereo+sound_16bit))
- /sound_speed/2;
- // qDebug("QSS delay: %d", delay);
- timerId = startTimer(delay);
-
- //
- // Check system volume
- //
- int mixerHandle = QT_OPEN( "/dev/mixer", O_RDWR|O_NONBLOCK );
- if ( mixerHandle >= 0 ) {
- int volume;
- ioctl( mixerHandle, MIXER_READ(0), &volume );
- close( mixerHandle );
- if ( volume < 1<<(sound_stereo+sound_16bit) )
- qDebug("Want sound at %d got %d",
- 1<<(sound_stereo+sound_16bit), volume);
- } else
- qDebug( "get volume of audio device failed" );
-
- }
- return true;
-}
-
-void QWSSoundServerPrivate::feedDevice(int fd)
-{
- if ( !unwritten && active.size() == 0 ) {
- closeDevice();
- sendCompletedSignals();
- return;
- } else {
- sendCompletedSignals();
- }
-
- QWSSoundServerProvider* bucket;
-
- // find out how much audio is possible
- int available = sound_buffer_size;
- QList<QWSSoundServerProvider*> running;
- for (int i = 0; i < active.size(); ++i) {
- bucket = active.at(i);
- int ready = bucket->readySamples(available);
- if (ready > 0) {
- available = qMin(available, ready);
- running.append(bucket);
- }
- }
-
- audio_buf_info info;
- if (can_GETOSPACE && ioctl(fd,SNDCTL_DSP_GETOSPACE,&info)) {
- can_GETOSPACE = false;
- fcntl(fd, F_SETFL, O_NONBLOCK);
- }
- if (!can_GETOSPACE)
- info.fragments = 4; // #### configurable?
- if (info.fragments > 0) {
- if (!unwritten) {
- int left[sound_buffer_size];
- memset(left,0,available*sizeof(int));
- int right[sound_buffer_size];
- if ( sound_stereo )
- memset(right,0,available*sizeof(int));
-
- if (running.size() > 0) {
- // should do volume mod here in regards to each bucket to avoid flattened/bad peaks.
- for (int i = 0; i < running.size(); ++i ) {
- bucket = running.at(i);
- int unused = bucket->add(left,right,available);
- if (unused > 0) {
- // this error is quite serious, as
- // it will really screw up mixing.
- qDebug("provider lied about samples ready");
- }
- }
- if ( sound_16bit ) {
- short *d = (short*)data;
- for (int i=0; i<available; i++) {
- *d++ = (short)qMax(qMin(left[i],32767),-32768);
- if ( sound_stereo )
- *d++ = (short)qMax(qMin(right[i],32767),-32768);
- }
- } else {
- signed char *d = (signed char *)data;
- for (int i=0; i<available; i++) {
- *d++ = (signed char)qMax(qMin(left[i]/256,127),-128)+128;
- if ( sound_stereo )
- *d++ = (signed char)qMax(qMin(right[i]/256,127),-128)+128;
- }
- }
- unwritten = available*(sound_16bit+1)*(sound_stereo+1);
- cursor = (char*)data;
- }
- }
- // sound open, but nothing written. Should clear the buffer.
-
- int w;
- if (unwritten) {
- w = ::write(fd,cursor,unwritten);
-
- if (w < 0) {
- if (can_GETOSPACE)
- return;
- w = 0;
- }
-
- cursor += w;
- unwritten -= w;
- } else {
- // write some zeros to clear the buffer?
- if (!zeroMem)
- zeroMem = (char *)calloc(sound_buffer_size, sizeof(char));
- w = ::write(fd, zeroMem, sound_buffer_size);
- if (w < 0)
- w = 0;
- }
- }
-
- QList<QWSSoundServerProvider*>::Iterator it = active.begin();
- while (it != active.end()) {
- bucket = *it;
- if (bucket->finished()) {
- completed.append(CompletedInfo(bucket->groupId(), bucket->soundId()));
- it = active.erase(it);
- delete bucket;
- } else {
- ++it;
- }
- }
-}
-
-
-QWSSoundServer::QWSSoundServer(QObject* parent) :
- QObject(parent)
-{
- d = new QWSSoundServerPrivate(this);
-
- connect( d, SIGNAL(soundFileCompleted(int,int)),
- this, SLOT(translateSoundCompleted(int,int)) );
-}
-
-void QWSSoundServer::playFile( int sid, const QString& filename )
-{
- //wid == 0, as it is the server initiating rather than a client
- // if wid was passable, would accidently collide with server
- // sockect's wids.
- d->playFile(0, sid, filename);
-}
-
-void QWSSoundServer::pauseFile( int sid )
-{
- d->pauseFile(0, sid);
-}
-
-void QWSSoundServer::stopFile( int sid )
-{
- d->stopFile(0, sid);
-}
-
-void QWSSoundServer::resumeFile( int sid )
-{
- d->resumeFile(0, sid);
-}
-
-QWSSoundServer::~QWSSoundServer()
-{
- d->stopAll(0);
-}
-
-void QWSSoundServer::translateSoundCompleted( int, int sid )
-{
- emit soundCompleted( sid );
-}
-
-#ifndef QT_NO_QWS_SOUNDSERVER
-QWSSoundClient::QWSSoundClient(QObject* parent) :
- QWSSocket(parent)
-{
- connectToLocalFile(QT_VFB_SOUND_PIPE(qws_display_id));
- QObject::connect(this,SIGNAL(readyRead()),
- this,SLOT(tryReadCommand()));
- if( state() == QWS_SOCK_BASE::ConnectedState ) QTimer::singleShot(1, this, SIGNAL(connected()));
- else QTimer::singleShot(1, this, SLOT(emitConnectionRefused()));
-}
-
-QWSSoundClient::~QWSSoundClient( )
-{
- flush();
-}
-
-void QWSSoundClient::reconnect()
-{
- connectToLocalFile(QT_VFB_SOUND_PIPE(qws_display_id));
- if( state() == QWS_SOCK_BASE::ConnectedState ) emit connected();
- else emit error( QTcpSocket::ConnectionRefusedError );
-}
-
-void QWSSoundClient::sendServerMessage(QString msg)
-{
-#ifndef QT_NO_TEXTCODEC
- QByteArray u = msg.toUtf8();
-#else
- QByteArray u = msg.toLatin1();
-#endif
- write(u.data(), u.length());
- flush();
-}
-
-void QWSSoundClient::play( int id, const QString& filename )
-{
- QFileInfo fi(filename);
- sendServerMessage(QLatin1String("PLAY ")
- + QString::number(id) + QLatin1Char(' ')
- + fi.absoluteFilePath() + QLatin1Char('\n'));
-}
-
-void QWSSoundClient::play( int id, const QString& filename, int volume, int flags)
-{
- QFileInfo fi(filename);
- sendServerMessage(QLatin1String("PLAYEXTEND ")
- + QString::number(id) + QLatin1Char(' ')
- + QString::number(volume) + QLatin1Char(' ')
- + QString::number(flags) + QLatin1Char(' ')
- + fi.absoluteFilePath() + QLatin1Char('\n'));
-}
-
-void QWSSoundClient::pause( int id )
-{
- sendServerMessage(QLatin1String("PAUSE ")
- + QString::number(id) + QLatin1Char('\n'));
-}
-
-void QWSSoundClient::stop( int id )
-{
- sendServerMessage(QLatin1String("STOP ")
- + QString::number(id) + QLatin1Char('\n'));
-}
-
-void QWSSoundClient::resume( int id )
-{
- sendServerMessage(QLatin1String("RESUME ")
- + QString::number(id) + QLatin1Char('\n'));
-}
-
-void QWSSoundClient::playRaw( int id, const QString& filename,
- int freq, int chs, int bitspersample, int flags)
-{
- QFileInfo fi(filename);
- sendServerMessage(QLatin1String("PLAYRAW ")
- + QString::number(id) + QLatin1Char(' ')
- + QString::number(chs) + QLatin1Char(' ')
- + QString::number(freq) + QLatin1Char(' ')
- + QString::number(bitspersample) + QLatin1Char(' ')
- + QString::number(flags) + QLatin1Char(' ')
- + fi.absoluteFilePath() + QLatin1Char('\n'));
-}
-
-void QWSSoundClient::setMute( int id, bool m )
-{
- sendServerMessage(QLatin1String(m ? "MUTE " : "UNMUTE ")
- + QString::number(id) + QLatin1Char('\n'));
-}
-
-void QWSSoundClient::setVolume( int id, int leftVol, int rightVol )
-{
- sendServerMessage(QLatin1String("SETVOLUME ")
- + QString::number(id) + QLatin1Char(' ')
- + QString::number(leftVol) + QLatin1Char(' ')
- + QString::number(rightVol) + QLatin1Char('\n'));
-}
-
-void QWSSoundClient::playPriorityOnly( bool pri )
-{
- sendServerMessage(QLatin1String("PRIORITYONLY ")
- + QString::number(pri ? 1 : 0) + QLatin1Char('\n'));
-}
-
-void QWSSoundClient::setSilent( bool enable )
-{
- sendServerMessage(QLatin1String("SILENT ")
- + QString::number( enable ? 1 : 0 ) + QLatin1Char('\n'));
-}
-
-void QWSSoundClient::tryReadCommand()
-{
- while ( canReadLine() ) {
- QString l = QString::fromAscii(readLine());
- l.truncate(l.length()-1); // chomp
- QStringList token = l.split(QLatin1Char(' '));
- if (token[0] == QLatin1String("SOUNDCOMPLETED")) {
- emit soundCompleted(token[1].toInt());
- } else if (token[0] == QLatin1String("DEVICEREADY")) {
- emit deviceReady(token[1].toInt());
- } else if (token[0] == QLatin1String("DEVICEERROR")) {
- emit deviceError(token[1].toInt(),(DeviceErrors)token[2].toInt());
- }
- }
-}
-
-void QWSSoundClient::emitConnectionRefused()
-{
- emit error( QTcpSocket::ConnectionRefusedError );
-}
-#endif
-
-QT_END_NAMESPACE
-
-#include "qsoundqss_qws.moc"
-
-#endif // QT_NO_SOUND
diff --git a/src/gui/embedded/qsoundqss_qws.h b/src/gui/embedded/qsoundqss_qws.h
deleted file mode 100644
index e31633a876..0000000000
--- a/src/gui/embedded/qsoundqss_qws.h
+++ /dev/null
@@ -1,177 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSOUNDQSS_QWS_H
-#define QSOUNDQSS_QWS_H
-
-#include <QtCore/qglobal.h>
-
-#ifndef QT_NO_SOUND
-
-#include <QtNetwork/qtcpserver.h>
-#include <QtNetwork/qtcpsocket.h>
-#include <QtGui/qwssocket_qws.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#if defined(QT_NO_NETWORK) || defined(QT_NO_DNS)
-#define QT_NO_QWS_SOUNDSERVER
-#endif
-
-#ifndef Q_OS_MAC
-
-class QWSSoundServerPrivate;
-
-class Q_GUI_EXPORT QWSSoundServer : public QObject {
- Q_OBJECT
-public:
- explicit QWSSoundServer(QObject *parent=0);
- ~QWSSoundServer();
- void playFile( int id, const QString& filename );
- void stopFile( int id );
- void pauseFile( int id );
- void resumeFile( int id );
-
-Q_SIGNALS:
- void soundCompleted( int );
-
-private Q_SLOTS:
- void translateSoundCompleted( int, int );
-
-private:
- QWSSoundServerPrivate* d;
-};
-
-#ifndef QT_NO_QWS_SOUNDSERVER
-class Q_GUI_EXPORT QWSSoundClient : public QWSSocket {
- Q_OBJECT
-public:
-
- enum SoundFlags {
- Priority = 0x01,
- Streaming = 0x02 // currently ignored, but but could set up so both Raw and non raw can be done streaming or not.
- };
- enum DeviceErrors {
- ErrOpeningAudioDevice = 0x01,
- ErrOpeningFile = 0x02,
- ErrReadingFile = 0x04
- };
- explicit QWSSoundClient(QObject* parent=0);
- ~QWSSoundClient( );
- void reconnect();
- void play( int id, const QString& filename );
- void play( int id, const QString& filename, int volume, int flags = 0 );
- void playRaw( int id, const QString&, int, int, int, int flags = 0 );
-
- void pause( int id );
- void stop( int id );
- void resume( int id );
- void setVolume( int id, int left, int right );
- void setMute( int id, bool m );
-
- // to be used by server only, to protect phone conversation/rings.
- void playPriorityOnly(bool);
-
- // If silent, tell sound server to release audio device
- // Otherwise, allow sound server to regain audio device
- void setSilent(bool);
-
-Q_SIGNALS:
- void soundCompleted(int);
- void deviceReady(int id);
- void deviceError(int id, QWSSoundClient::DeviceErrors);
-
-private Q_SLOTS:
- void tryReadCommand();
- void emitConnectionRefused();
-
-private:
- void sendServerMessage(QString msg);
-};
-
-class QWSSoundServerSocket : public QWSServerSocket {
- Q_OBJECT
-
-public:
- explicit QWSSoundServerSocket(QObject *parent=0);
-public Q_SLOTS:
- void newConnection();
-
-#ifdef QT3_SUPPORT
-public:
- QT3_SUPPORT_CONSTRUCTOR QWSSoundServerSocket(QObject *parent, const char *name);
-#endif
-
-Q_SIGNALS:
- void playFile(int, int, const QString&);
- void playFile(int, int, const QString&, int, int);
- void playRawFile(int, int, const QString&, int, int, int, int);
- void pauseFile(int, int);
- void stopFile(int, int);
- void resumeFile(int, int);
- void setVolume(int, int, int, int);
- void setMute(int, int, bool);
-
- void stopAll(int);
-
- void playPriorityOnly(bool);
-
- void setSilent(bool);
-
- void soundFileCompleted(int, int);
- void deviceReady(int, int);
- void deviceError(int, int, int);
-};
-#endif
-
-#endif // Q_OS_MAC
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QT_NO_SOUND
-
-#endif // QSOUNDQSS_QWS_H
diff --git a/src/gui/embedded/qtransportauth_qws.cpp b/src/gui/embedded/qtransportauth_qws.cpp
deleted file mode 100644
index f05699f340..0000000000
--- a/src/gui/embedded/qtransportauth_qws.cpp
+++ /dev/null
@@ -1,1563 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qtransportauth_qws.h"
-#include "qtransportauth_qws_p.h"
-
-#ifndef QT_NO_SXE
-
-#include "../../3rdparty/md5/md5.h"
-#include "../../3rdparty/md5/md5.cpp"
-#include "qwsutils_qws.h"
-#include "qwssocket_qws.h"
-#include "qwscommand_qws_p.h"
-#include "qwindowsystem_qws.h"
-#include "qbuffer.h"
-#include "qthread.h"
-#include "qabstractsocket.h"
-#include "qlibraryinfo.h"
-#include "qfile.h"
-#include "qdebug.h"
-#include <private/qcore_unix_p.h> // overrides QT_OPEN
-
-#include <syslog.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/file.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <time.h>
-
-#include <QtCore/qcache.h>
-
-#define BUF_SIZE 512
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \internal
- memset for security purposes, guaranteed not to be optimized away
- http://www.faqs.org/docs/Linux-HOWTO/Secure-Programs-HOWTO.html
-*/
-Q_GUI_EXPORT void *guaranteed_memset(void *v,int c,size_t n)
-{
- volatile char *p = (char *)v; while (n--) *p++=c; return v;
-}
-
-/*!
- \class QTransportAuth
- \internal
-
- \brief Authenticate a message transport.
-
- For performance reasons, message authentication is tied to an individual
- message transport instance. For example in connection oriented transports
- the authentication cookie can be cached against the connection avoiding
- the overhead of authentication on every message.
-
- For each process there is one instance of the QTransportAuth object.
- For server processes it can determine the \link secure-exe-environ.html SXE
- Program Identity \endlink and provide access to policy data to determine if
- the message should be forwarded for action. If not actioned, the message
- may be treated as being from a flawed or malicious process.
-
- Retrieve the instance with the getInstance() method. The constructor is
- disabled and instances of QTransportAuth should never be constructed by
- calling classes.
-
- To make the Authentication easier to use a proxied QIODevice is provided
- which uses an internal QBuffer.
-
- In the server code first get a pointer to a QTransportAuth::Data object
- using the connectTransport() method:
-
- \snippet doc/src/snippets/code/src_gui_embedded_qtransportauth_qws.cpp 0
-
- Here it is asserted that the transport is trusted. See the assumptions
- listed in the \link secure-exe-environ.html SXE documentation \endlink
-
- Then proxy in the authentication device:
-
- \snippet doc/src/snippets/code/src_gui_embedded_qtransportauth_qws.cpp 1
-
- In the client code it is similar. Use the connectTransport() method
- just the same then proxy in the authentication device instead of the
- socket in write calls:
-
- \snippet doc/src/snippets/code/src_gui_embedded_qtransportauth_qws.cpp 2
-*/
-
-static int hmac_md5(
- unsigned char* text, /* pointer to data stream */
- int text_length, /* length of data stream */
- const unsigned char* key, /* pointer to authentication key */
- int key_length, /* length of authentication key */
- unsigned char * digest /* caller digest to be filled in */
- );
-
-
-
-#define KEY_CACHE_SIZE 30
-
-const char * const errorStrings[] = {
- "pending identity verification",
- "message too small to carry auth data",
- "cache miss on connection oriented transport",
- "no magic bytes on message",
- "key not found for prog id",
- "authorization key match failed",
- "key out of date"
-};
-
-const char *QTransportAuth::errorString( const Data &d )
-{
- if (( d.status & ErrMask ) == Success )
- return "success";
- int e = d.status & ErrMask;
- if ( e > OutOfDate )
- return "unknown";
- return errorStrings[e];
-}
-
-SxeRegistryLocker::SxeRegistryLocker( QObject *reg )
- : m_success( false )
- , m_reg( 0 )
-{
- if ( reg )
- if ( !QMetaObject::invokeMethod( reg, "lockManifest", Q_RETURN_ARG(bool, m_success) ))
- m_success = false;
- m_reg = reg;
-}
-
-SxeRegistryLocker::~SxeRegistryLocker()
-{
- if ( m_success )
- QMetaObject::invokeMethod( m_reg, "unlockManifest" );
-}
-
-
-QTransportAuthPrivate::QTransportAuthPrivate()
- : keyInitialised(false)
- , m_packageRegistry( 0 )
-{
-}
-
-QTransportAuthPrivate::~QTransportAuthPrivate()
-{
-}
-
-/*!
- \internal
- Construct a new QTransportAuth
-*/
-QTransportAuth::QTransportAuth() : QObject(*new QTransportAuthPrivate)
-{
- // qDebug( "creating transport auth" );
-}
-
-/*!
- \internal
- Destructor
-*/
-QTransportAuth::~QTransportAuth()
-{
- // qDebug( "deleting transport auth" );
-}
-
-/*!
- Set the process key for this currently running Qt Extended process to
- the \a authdata. \a authdata should be sizeof(struct AuthCookie)
- in length and contain the key and program id. Use this method
- when setting or changing the SXE identity of the current program.
-*/
-void QTransportAuth::setProcessKey( const char *authdata )
-{
- Q_D(QTransportAuth);
- ::memcpy(&d->authKey, authdata, sizeof(struct AuthCookie));
- QFile proc_key( QLatin1String("/proc/self/lids_key") );
- // where proc key exists use that instead
- if ( proc_key.open( QIODevice::ReadOnly ))
- {
- qint64 kb = proc_key.read( (char*)&d->authKey.key, QSXE_KEY_LEN );
-#ifdef QTRANSPORTAUTH_DEBUG
- qDebug( "Using %li bytes of /proc/%i/lids_key\n", (long int)kb, getpid() );
-#else
- Q_UNUSED( kb );
-#endif
- }
- d->keyInitialised = true;
-}
-
-
-/*!
- Apply \a key as the process key for the currently running application.
-
- \a prog is current ignored
-
- Deprecated function
-*/
-void QTransportAuth::setProcessKey( const char *key, const char *prog )
-{
- Q_UNUSED(prog);
- setProcessKey( key );
-#ifdef QTRANSPORTAUTH_DEBUG
- char displaybuf[QSXE_KEY_LEN*2+1];
- hexstring( displaybuf, (const unsigned char *)key, QSXE_KEY_LEN );
- qDebug() << "key" << displaybuf << "set";
-#endif
-}
-
-/*!
- Register \a pr as a policy handler object. The object pointed to
- by \a pr should have a slot as follows
- \snippet doc/src/snippets/code/src_gui_embedded_qtransportauth_qws.cpp 3
- All requests received by this server will then generate a call to
- this slot, and may be processed for policy compliance.
-*/
-void QTransportAuth::registerPolicyReceiver( QObject *pr )
-{
- // not every policy receiver needs setup - no error if this fails
- QMetaObject::invokeMethod( pr, "setupPolicyCheck" );
-
- connect( this, SIGNAL(policyCheck(QTransportAuth::Data&,QString)),
- pr, SLOT(policyCheck(QTransportAuth::Data&,QString)), Qt::DirectConnection );
-}
-
-/*!
- Unregister the \a pr from being a policy handler. No more policyCheck signals
- are received by this object.
-*/
-void QTransportAuth::unregisterPolicyReceiver( QObject *pr )
-{
- disconnect( pr );
- // not every policy receiver needs tear down - no error if this fails
- QMetaObject::invokeMethod( pr, "teardownPolicyCheck" );
-}
-
-/*!
- Record a new transport connection with \a properties and \a descriptor.
-
- The calling code is responsible for destroying the returned data when the
- tranport connection is closed.
-*/
-QTransportAuth::Data *QTransportAuth::connectTransport( unsigned char properties, int descriptor )
-{
- Data *data = new Data(properties, descriptor);
- data->status = Pending;
- return data;
-}
-
-/*!
- Is the transport trusted. This is true iff data written into the
- transport medium cannot be intercepted or modified by another process.
- This is for example true for Unix Domain Sockets, but not for shared
- memory or UDP sockets.
-
- There is of course an underlying assumption that the kernel implementing
- the transport is sound, ie it cannot be compromised by writing to
- /dev/kmem or loading untrusted modules
-*/
-inline bool QTransportAuth::Data::trusted() const
-{
- return (bool)(properties & Trusted);
-}
-
-/*!
- Assert that the transport is trusted.
-
- For example with respect to shared memory, if it is ensured that no untrusted
- root processes are running, and that unix permissions have been set such that
- any untrusted non-root processes do not have access rights, then a shared
- memory transport could be asserted to be trusted.
-
- \sa trusted()
-*/
-inline void QTransportAuth::Data::setTrusted( bool t )
-{
- properties = t ? properties | Trusted : properties & ~Trusted;
-}
-
-/*!
- Is the transport connection oriented. This is true iff once a connection
- has been accepted, and state established, then further messages over the
- transport are guaranteed to have come from the original connecting entity.
- This is for example true for Unix Domain Sockets, but not
- for shared memory or UDP sockets.
-
- By extension if the transport is not trusted() then it should not be
- assumed to be connection oriented, since spoofed connection information
- could be created. For example if we assume the TCP/IP transport is
- trusted, it can be treated as connection oriented; but this is only the
- case if intervening routers are trusted.
-
- Connection oriented transports have authorization cached against the
- connection, and thus authorization is only done at connect time.
-*/
-inline bool QTransportAuth::Data::connection() const
-{
- return (bool)(properties & Connection);
-}
-
-/*!
- Assert that the transport is connection oriented.
-
- \sa connection()
-*/
-inline void QTransportAuth::Data::setConnection( bool t )
-{
- properties = t ? properties | Connection : properties & ~Connection;
-}
-
-/*!
- Return a pointer to the instance of this process's QTransportAuth object
-*/
-QTransportAuth *QTransportAuth::getInstance()
-{
- static QTransportAuth theInstance;
-
- return &theInstance;
-}
-
-/*!
- Set the full path to the key file
-
- Since this is normally relative to Qtopia::qpeDir() this needs to be
- set within the Qt Extended framework.
-
- The keyfile should be protected by file permissions or by MAC rules
- such that it can only be read/written by the "qpe" server process
-*/
-void QTransportAuth::setKeyFilePath( const QString &path )
-{
- Q_D(QTransportAuth);
- d->m_keyFilePath = path;
-}
-
-QString QTransportAuth::keyFilePath() const
-{
- Q_D(const QTransportAuth);
- return d->m_keyFilePath;
-}
-
-void QTransportAuth::setLogFilePath( const QString &path )
-{
- Q_D(QTransportAuth);
- d->m_logFilePath = path;
-}
-
-QString QTransportAuth::logFilePath() const
-{
- Q_D(const QTransportAuth);
- return d->m_logFilePath;
-}
-
-void QTransportAuth::setPackageRegistry( QObject *registry )
-{
- Q_D(QTransportAuth);
- d->m_packageRegistry = registry;
-}
-
-bool QTransportAuth::isDiscoveryMode() const
-{
-#if defined(SXE_DISCOVERY)
- static bool checked = false;
- static bool yesItIs = false;
-
- if ( checked ) return yesItIs;
-
- yesItIs = ( getenv( "SXE_DISCOVERY_MODE" ) != 0 );
- if ( yesItIs )
- {
- qWarning("SXE Discovery mode on, ALLOWING ALL requests and logging to %s",
- qPrintable(logFilePath()));
- QFile::remove( logFilePath() );
- }
- checked = true;
- return yesItIs;
-#else
- return false;
-#endif
-}
-
-/*!
- \internal
- Return the authorizer device mapped to this client. Note that this
- could probably all be void* instead of QWSClient* for generality.
- Until the need for that rears its head its QWSClient* to save the casts.
-
- #### OK the need has arrived, but the public API is frozen.
-*/
-QIODevice *QTransportAuth::passThroughByClient( QWSClient *client ) const
-{
- Q_D(const QTransportAuth);
-
- if ( client == 0 ) return 0;
- if ( d->buffersByClient.contains( client ))
- {
- return d->buffersByClient[client];
- }
- // qWarning( "buffer not found for client %p", client );
- return 0;
-}
-
-/*!
- \internal
- Return a QIODevice pointer (to an internal QBuffer) which can be used
- to receive data after authorization on transport \a d.
-
- The return QIODevice will act as a pass-through.
-
- The data will be consumed from \a iod and forwarded on to the returned
- QIODevice which can be connected to readyRead() signal handlers in
- place of the original QIODevice \a iod.
-
- This will be called in the server process to handle incoming
- authenticated requests.
-
- The returned QIODevice will take ownership of \a data which will be deleted
- when the QIODevice is delected.
-
- \sa setTargetDevice()
-*/
-QAuthDevice *QTransportAuth::recvBuf( QTransportAuth::Data *data, QIODevice *iod )
-{
- return new QAuthDevice( iod, data, QAuthDevice::Receive );
-}
-
-/*!
- Return a QIODevice pointer (to an internal QBuffer) which can be used
- to write data onto, for authorization on transport \a d.
-
- The return QIODevice will act as a pass-through.
-
- The data written to the return QIODevice will be forwarded on to the
- returned QIODevice. In the case of a QTcpSocket, this will cause it
- to send out the data with the authentication information on it.
-
- This will be called in the client process to generate outgoing
- authenticated requests.
-
- The returned QIODevice will take ownership of \a data which will be deleted
- when the QIODevice is delected.
-
- \sa setTargetDevice()
-*/
-QAuthDevice *QTransportAuth::authBuf( QTransportAuth::Data *data, QIODevice *iod )
-{
- return new QAuthDevice( iod, data, QAuthDevice::Send );
-}
-
-const unsigned char *QTransportAuth::getClientKey( unsigned char progId )
-{
- Q_D(QTransportAuth);
- return d->getClientKey( progId );
-}
-
-void QTransportAuth::invalidateClientKeyCache()
-{
- Q_D(QTransportAuth);
- d->invalidateClientKeyCache();
-}
-
-QMutex *QTransportAuth::getKeyFileMutex()
-{
- Q_D(QTransportAuth);
- return &d->keyfileMutex;
-}
-
-/*
- \internal
- Respond to the destroyed(QObject*) signal of the QAuthDevice's
- client object and remove it from the buffersByClient lookup hash.
-*/
-void QTransportAuth::bufferDestroyed( QObject *cli )
-{
- Q_D(QTransportAuth);
- if ( cli == NULL ) return;
-
- if ( d->buffersByClient.contains( cli ))
- {
- d->buffersByClient.remove( cli );
- // qDebug( "@@@@@@@ client %p removed @@@@@@@@@", cli );
- }
- // qDebug( " client count %d", d->buffersByClient.count() );
-}
-
-bool QTransportAuth::authorizeRequest( QTransportAuth::Data &d, const QString &request )
-{
- bool isAuthorized = true;
-
- if ( !request.isEmpty() && request != QLatin1String("Unknown") )
- {
- d.status &= QTransportAuth::ErrMask; // clear the status
- emit policyCheck( d, request );
- isAuthorized = (( d.status & QTransportAuth::StatusMask ) == QTransportAuth::Allow );
- }
-#if defined(SXE_DISCOVERY)
- if (isDiscoveryMode()) {
-#ifndef QT_NO_TEXTSTREAM
- if (!logFilePath().isEmpty()) {
- QFile log( logFilePath() );
- if (!log.open(QIODevice::WriteOnly | QIODevice::Append)) {
- qWarning("Could not write to log in discovery mode: %s",
- qPrintable(logFilePath()));
- } else {
- QTextStream ts( &log );
- ts << d.progId << '\t' << ( isAuthorized ? "Allow" : "Deny" ) << '\t' << request << endl;
- }
- }
-#endif
- isAuthorized = true;
- }
-#endif
- if ( !isAuthorized )
- {
- qWarning( "%s - denied: for Program Id %u [PID %d]"
- , qPrintable(request), d.progId, d.processId );
-
- char linkTarget[BUF_SIZE]="";
- char exeLink[BUF_SIZE]="";
- char cmdlinePath[BUF_SIZE]="";
- char cmdline[BUF_SIZE]="";
-
- //get executable from /proc/pid/exe
- snprintf( exeLink, BUF_SIZE, "/proc/%d/exe", d.processId );
- if ( -1 == ::readlink( exeLink, linkTarget, BUF_SIZE - 1 ) )
- {
- qWarning( "SXE:- Error encountered in retrieving executable link target from /proc/%u/exe : %s",
- d.processId, strerror(errno) );
- snprintf( linkTarget, BUF_SIZE, "%s", linkTarget );
- }
-
- //get cmdline from proc/pid/cmdline
- snprintf( cmdlinePath, BUF_SIZE, "/proc/%d/cmdline", d.processId );
- int cmdlineFd = QT_OPEN( cmdlinePath, O_RDONLY );
- if ( cmdlineFd == -1 )
- {
- qWarning( "SXE:- Error encountered in opening /proc/%u/cmdline: %s",
- d.processId, strerror(errno) );
- snprintf( cmdline, BUF_SIZE, "%s", "Unknown" );
- }
- else
- {
- if ( -1 == QT_READ(cmdlineFd, cmdline, BUF_SIZE - 1 ) )
- {
- qWarning( "SXE:- Error encountered in reading /proc/%u/cmdline : %s",
- d.processId, strerror(errno) );
- snprintf( cmdline, BUF_SIZE, "%s", "Unknown" );
- }
- QT_CLOSE( cmdlineFd );
- }
-
- syslog( LOG_ERR | LOG_LOCAL6, "%s // PID:%u // ProgId:%u // Exe:%s // Request:%s // Cmdline:%s",
- "<SXE Breach>", d.processId, d.progId, linkTarget, qPrintable(request), cmdline);
- }
-
- return isAuthorized;
-}
-
-inline bool __fileOpen( QFile *f )
-{
-#ifdef QTRANSPORTAUTH_DEBUG
- if ( f->open( QIODevice::ReadOnly ))
- {
- qDebug( "Opened file: %s\n", qPrintable( f->fileName() ));
- return true;
- }
- else
- {
- qWarning( "Could not open file: %s\n", qPrintable( f->fileName() ));
- return false;
- }
-#else
- return ( f->open( QIODevice::ReadOnly ));
-#endif
-}
-
-/*!
- \internal
- Find client keys for the \a progId. If it is cached should be very
- fast, otherwise requires a read of the secret key file
-
- In the success case a pointer to the keys is returned. The pointer is
- to storage allocated for the internal cache and must be used asap.
-
- The list returned is a sequence of one or more keys which match the
- progId. There is no separator, each 16 byte sequence represents a key.
- The sequence is followed by two iterations of the SXE magic
- bytes,eg 0xBA, 0xD4, 0xD4, 0xBA, 0xBA, 0xD4, 0xD4, 0xBA
-
- NULL is returned in the following cases:
- \list
- \o the keyfiles could not be accessed - error condition
- \o there was no key for the supplied program id - key auth failed
- \endlist
-
- Note that for the keyfiles, there is multi-thread and multi-process
- concurrency issues: they can be read by the qpe process when
- QTransportAuth calls getClientKey to verify a request, and they can be
- read or written by the packagemanager when updating package data.
-
- To protect against this, the keyfileMutex & SxeRegistryLocker is used.
-
- The sxe_installer tool can also update inode and device numbers in
- the manifest file, but this only occurs outside of normal operation,
- so qpe and packagemanager are never running when this occurs.
-*/
-const unsigned char *QTransportAuthPrivate::getClientKey(unsigned char progId)
-{
- int manifestMatchCount = 0;
- struct IdBlock mr;
- int total_size = 0;
- char *result = 0;
- char *result_ptr;
- int keysFound = 0;
- bool foundKey;
- int keysRead = 0;
- struct usr_key_entry keys_list[128];
-
- if ( keyCache.contains( progId ))
- return (const unsigned char *)keyCache[progId];
-
- SxeRegistryLocker rlock( m_packageRegistry );
-
- // ### Qt 4.3: this is hacky - see documentation for setKeyFilePath
- QString manifestPath = m_keyFilePath + QLatin1String("/manifest");
- QString actualKeyPath = QLatin1String("/proc/lids/keys");
- bool noFailOnKeyMissing = true;
- if ( !QFile::exists( actualKeyPath )) {
- actualKeyPath = m_keyFilePath + QLatin1String( "/" QSXE_KEYFILE );
- }
- QFile kf( actualKeyPath );
- QFile mn( manifestPath );
- if ( !__fileOpen( &mn ))
- goto key_not_found;
- // first find how much storage is needed
- while ( mn.read( (char*)&mr, sizeof(struct IdBlock)) > 0 )
- if ( mr.progId == progId )
- manifestMatchCount++;
- if ( manifestMatchCount == 0 )
- goto key_not_found;
- if ( !__fileOpen( &kf ))
- {
- noFailOnKeyMissing = false;
- goto key_not_found;
- }
- total_size = 2 * QSXE_MAGIC_BYTES + manifestMatchCount * QSXE_KEY_LEN;
- result = (char*)malloc( total_size );
- Q_CHECK_PTR( result );
- mn.seek( 0 );
- result_ptr = result;
- /* reading whole key array in is much more efficient, 99% case is this loop only
- executes once, should not have more than 128 keyed items */
- while (( keysRead = kf.read( (char*)keys_list, sizeof(struct usr_key_entry)*128 )) > 0 )
- {
- /* qDebug("PID %d: getClientKey() - read %d bytes = %d keys from %s", getpid(), keysRead,
- keysRead/sizeof(struct usr_key_entry), qPrintable(actualKeyPath)); */
- keysRead /= sizeof(struct usr_key_entry);
- while ( mn.read( (char*)&mr, sizeof(struct IdBlock)) > 0 )
- {
- if ( mr.progId == progId )
- {
- foundKey = false;
- for ( int i = 0; i < keysRead; ++i )
- {
- /* if ( i == 0 )
- qDebug() << " pid" << getpid() << "looking for device" << (dev_t)mr.device << "inode" << (ino_t)mr.inode;
- qDebug() << " pid" << getpid() << "trying device" << keys_list[i].dev << "inode" << keys_list[i].ino; */
- if ( keys_list[i].ino == (ino_t)mr.inode && keys_list[i].dev == (dev_t)mr.device )
- {
- memcpy( result_ptr, keys_list[i].key, QSXE_KEY_LEN );
- result_ptr += QSXE_KEY_LEN;
- foundKey = true;
- break;
- }
- }
- if ( foundKey )
- {
- keysFound++;
- if ( keysFound == manifestMatchCount )
- break;
- }
- }
- }
- }
- if ( result_ptr == result ) // nothing found!
- goto key_not_found;
- // 2 x magic bytes sentinel at end of sequence
- for ( int i = 0; i < 2; ++i )
- for ( int j = 0; j < QSXE_MAGIC_BYTES; ++j )
- *result_ptr++ = magic[j];
- keyCache.insert( progId, result, total_size / 10 );
- /* qDebug( "PID %d : Found %d client keys for prog %u", getpid(), keysFound, progId ); */
- goto success_out;
-
-key_not_found:
- if ( noFailOnKeyMissing ) // return an "empty" set of keys in this case
- {
- if ( result == 0 )
- {
- result = (char*)malloc( 2 * QSXE_MAGIC_BYTES );
- Q_CHECK_PTR( result );
- }
- result_ptr = result;
- for ( int i = 0; i < 2; ++i )
- for ( int j = 0; j < QSXE_MAGIC_BYTES; ++j )
- *result_ptr++ = magic[j];
- return (unsigned char *)result;
- }
- qWarning( "PID %d : Not found client key for prog %u", getpid(), progId );
- if ( result )
- {
- free( result );
- result = 0;
- }
-success_out:
- if ( mn.isOpen() )
- mn.close();
- if ( kf.isOpen() )
- kf.close();
- return (unsigned char *)result;
-}
-
-void QTransportAuthPrivate::invalidateClientKeyCache()
-{
- keyfileMutex.lock();
- keyCache.clear();
- keyfileMutex.unlock();
-}
-
-////////////////////////////////////////////////////////////////////////
-////
-//// RequestAnalyzer definition
-////
-
-
-RequestAnalyzer::RequestAnalyzer()
- : moreData( false )
- , dataSize( 0 )
-{
-}
-
-RequestAnalyzer::~RequestAnalyzer()
-{
-}
-
-/*!
- Analzye the data in the\a msgQueue according to some protocol
- and produce a request string for policy analysis.
-
- If enough data is in the queue for analysis of a complete message,
- return a non-null string, and set a flag so requireMoreData() will
- return false; otherwise return a null string and requireMoreData()
- return true.
-
- The amount of bytes analyzed is then available via bytesAnalyzed().
-
- A null string is also returned in the case where the message was
- corrupt and could not be analyzed. In this case requireMoreData()
- returns false.
-
-Note: this method will modify the msgQueue and pull off the data
- deemed to be corrupt, in the case of corrupt data.
-
- In all other cases the msgQueue is left alone. The calling code
- should then pull off the analyzed data. Use bytesAnalzyed() to
- find how much data to pull off the queue.
-*/
-QString RequestAnalyzer::analyze( QByteArray *msgQueue )
-{
-#ifdef Q_WS_QWS
- dataSize = 0;
- moreData = false;
- QBuffer cmdBuf( msgQueue );
- cmdBuf.open( QIODevice::ReadOnly | QIODevice::Unbuffered );
- QWSCommand::Type command_type = (QWSCommand::Type)(qws_read_uint( &cmdBuf ));
- QWSCommand *command = QWSCommand::factory(command_type);
- // if NULL, factory will have already printed warning for bogus
- // command_type just purge the bad stuff and attempt to recover
- if ( command == NULL )
- {
- *msgQueue = msgQueue->mid( sizeof(int) );
- return QString();
- }
- QString request = QLatin1String(qws_getCommandTypeString(command_type));
-#ifndef QT_NO_COP
- if ( !command->read( &cmdBuf ))
- {
- // not all command arrived yet - come back later
- delete command;
- moreData = true;
- return QString();
- }
- if ( command_type == QWSCommand::QCopSend )
- {
- QWSQCopSendCommand *sendCommand = static_cast<QWSQCopSendCommand*>(command);
- request += QString::fromLatin1("/QCop/%1/%2").arg( sendCommand->channel ).arg( sendCommand->message );
- }
- if ( command_type == QWSCommand::QCopRegisterChannel )
- {
- QWSQCopRegisterChannelCommand *registerCommand = static_cast<QWSQCopRegisterChannelCommand*>(command);
- request += QString::fromLatin1("/QCop/RegisterChannel/%1").arg( registerCommand->channel );
- }
-#endif
- dataSize = QWS_PROTOCOL_ITEM_SIZE( *command );
- delete command;
- return request;
-#else
- Q_UNUSED(msgQueue);
- return QString();
-#endif
-}
-
-////////////////////////////////////////////////////////////////////////
-////
-//// AuthDevice definition
-////
-
-/*!
- Constructs a new auth device for the transport \a data and I/O device \a parent.
-
- Incoming or outgoing data will be authenticated according to the auth direction \a dir.
-
- The auth device will take ownership of the transport \a data and delete it when the device
- is destroyed.
-*/
-QAuthDevice::QAuthDevice( QIODevice *parent, QTransportAuth::Data *data, AuthDirection dir )
- : QIODevice( parent )
- , d( data )
- , way( dir )
- , m_target( parent )
- , m_client( 0 )
- , m_bytesAvailable( 0 )
- , m_skipWritten( 0 )
- , analyzer( 0 )
-{
- if ( dir == Receive ) // server side
- {
- connect( m_target, SIGNAL(readyRead()),
- this, SLOT(recvReadyRead()));
- } else {
- connect( m_target, SIGNAL(readyRead()),
- this, SIGNAL(readyRead()));
- }
- connect( m_target, SIGNAL(bytesWritten(qint64)),
- this, SLOT(targetBytesWritten(qint64)) );
- open( QIODevice::ReadWrite | QIODevice::Unbuffered );
-}
-
-QAuthDevice::~QAuthDevice()
-{
- if ( analyzer )
- delete analyzer;
- delete d;
-}
-
-/*!
- \internal
- Store a pointer to the related device or instance which this
- authorizer is proxying for
-*/
-void QAuthDevice::setClient( QObject *cli )
-{
- m_client = cli;
- QTransportAuth::getInstance()->d_func()->buffersByClient[cli] = this;
- QObject::connect( cli, SIGNAL(destroyed(QObject*)),
- QTransportAuth::getInstance(), SLOT(bufferDestroyed(QObject*)) );
- // qDebug( "@@@@@@@@@@@@ client set %p @@@@@@@@@", cli );
- // qDebug( " client count %d", QTransportAuth::getInstance()->d_func()->buffersByClient.count() );
-}
-
-QObject *QAuthDevice::client() const
-{
- return m_client;
-}
-
-/*
- \fn void QAuthDevice::authViolation(QTransportAuth::Data &)
-
- This signal is emitted if an authorization failure is generated, as
- described in checkAuth();
-
- \sa checkAuth()
-*/
-
-
-/*
- \fn void QAuthDevice::policyCheck(QTransportAuth::Data &transport, const QString &request )
-
- This signal is emitted when a transport successfully delivers a request
- and gives the opportunity to either deny or accept the request.
-
- This signal must be connected in the same thread, ie it cannot be queued.
-
- As soon as all handlers connected to this signal are processed the Allow or
- Deny state on the \a transport is checked, and the request is allowed or denied
- accordingly.
-
- \sa checkAuth()
-*/
-
-/*!
- \internal
- Reimplement QIODevice writeData method.
-
- For client end, when the device is written to the incoming data is
- processed and an authentication header calculated. This is pushed
- into the target device, followed by the actual incoming data (the
- payload).
-
- For server end, it is a fatal error to write to the device.
-*/
-qint64 QAuthDevice::writeData(const char *data, qint64 len)
-{
- if ( way == Receive ) // server
- return m_target->write( data, len );
- // client
-#ifdef QTRANSPORTAUTH_DEBUG
- char displaybuf[1024];
-#endif
- char header[QSXE_HEADER_LEN];
- ::memset( header, 0, QSXE_HEADER_LEN );
- qint64 bytes = 0;
- if ( QTransportAuth::getInstance()->authToMessage( *d, header, data, len ))
- {
- m_target->write( header, QSXE_HEADER_LEN );
-#ifdef QTRANSPORTAUTH_DEBUG
- hexstring( displaybuf, (const unsigned char *)header, QSXE_HEADER_LEN );
- qDebug( "%d QAuthDevice::writeData - CLIENT: Header written: %s", getpid(), displaybuf );
-#endif
- m_skipWritten += QSXE_HEADER_LEN;
- }
- m_target->write( data, len );
- bytes += len;
-#ifdef QTRANSPORTAUTH_DEBUG
- int bytesToDisplay = bytes;
- const unsigned char *dataptr = (const unsigned char *)data;
- while ( bytesToDisplay > 0 )
- {
- int amt = bytes < 500 ? bytes : 500;
- hexstring( displaybuf, dataptr, amt );
- qDebug( "%d QAuthDevice::writeData - CLIENT: %s", getpid(), bytes > 0 ? displaybuf : "(null)" );
- dataptr += 500;
- bytesToDisplay -= 500;
- }
-#endif
- if ( m_target->inherits( "QAbstractSocket" ))
- static_cast<QAbstractSocket*>(m_target)->flush();
- return bytes;
-}
-
-/*!
- Reimplement from QIODevice
-
- Read data out of the internal message queue, reduce the queue by the amount
- read. Note that the amount available is only ever the size of a command
- (although a command can be very big) since we need to check at command
- boundaries for new authentication headers.
-*/
-qint64 QAuthDevice::readData( char *data, qint64 maxSize )
-{
- if ( way == Send ) // client
- return m_target->read( data, maxSize );
- if ( msgQueue.size() == 0 )
- return 0;
-#ifdef QTRANSPORTAUTH_DEBUG
- char displaybuf[1024];
- hexstring( displaybuf, reinterpret_cast<const unsigned char *>(msgQueue.constData()),
- msgQueue.size() > 500 ? 500 : msgQueue.size() );
- qDebug() << getpid() << "QAuthDevice::readData() buffered/requested/avail"
- << msgQueue.size() << maxSize << m_bytesAvailable << displaybuf;
-#endif
- Q_ASSERT( m_bytesAvailable <= msgQueue.size() );
- qint64 bytes = ( maxSize > m_bytesAvailable ) ? m_bytesAvailable : maxSize;
- ::memcpy( data, msgQueue.constData(), bytes );
- msgQueue = msgQueue.mid( bytes );
- m_bytesAvailable -= bytes;
- return bytes;
-}
-
-/*!
- \internal
- Receive readyRead signal from the target recv device. In response
- authorize the data, and write results out to the recvBuf() device
- for processing by the application. Trigger the readyRead signal.
-
- Authorizing involves first checking the transport is valid, ie the
- handshake has either already been done and is cached on a trusted
- transport, or was valid with this message; then second passing the
- string representation of the service request up to any policyReceivers
-
- If either of these fail, the message is denied. In discovery mode
- denied messages are allowed, but the message is logged.
-*/
-void QAuthDevice::recvReadyRead()
-{
- qint64 bytes = m_target->bytesAvailable();
- if ( bytes <= 0 ) return;
- open( QIODevice::ReadWrite | QIODevice::Unbuffered );
- QUnixSocket *usock = static_cast<QUnixSocket*>(m_target);
- QUnixSocketMessage msg = usock->read();
- msgQueue.append( msg.bytes() );
- d->processId = msg.processId();
- // if "fragmented" packet 1/2 way through start of a command, ie
- // in the QWS msg type, cant do anything, come back later when
- // there's more of the packet
- if ( msgQueue.size() < (int)sizeof(int) )
- {
- // qDebug() << "returning: msg size too small" << msgQueue.size();
- return;
- }
-#ifdef QTRANSPORTAUTH_DEBUG
- char displaybuf[1024];
- hexstring( displaybuf, reinterpret_cast<const unsigned char *>(msgQueue.constData()),
- msgQueue.size() > 500 ? 500 : msgQueue.size() );
- qDebug( "%d ***** SERVER read %lli bytes - msg %s", getpid(), bytes, displaybuf );
-#endif
-
- bool bufHasMessages = msgQueue.size() >= (int)sizeof(int);
- while ( bufHasMessages )
- {
- unsigned char saveStatus = d->status;
- if (( d->status & QTransportAuth::ErrMask ) == QTransportAuth::NoSuchKey )
- {
- QTransportAuth::getInstance()->authorizeRequest( *d, QLatin1String("NoSuchKey") );
- break;
- }
- if ( !QTransportAuth::getInstance()->authFromMessage( *d, msgQueue, msgQueue.size() ))
- {
- // not all arrived yet? come back later
- if (( d->status & QTransportAuth::ErrMask ) == QTransportAuth::TooSmall )
- {
- d->status = saveStatus;
- return;
- }
- }
- if (( d->status & QTransportAuth::ErrMask ) == QTransportAuth::NoMagic )
- {
- // no msg auth header, don't change the success status for connections
- if ( d->connection() )
- d->status = saveStatus;
- }
- else
- {
- // msg auth header detected and auth determined, remove hdr
- msgQueue = msgQueue.mid( QSXE_HEADER_LEN );
- }
- if ( !authorizeMessage() )
- break;
- bufHasMessages = msgQueue.size() >= (int)sizeof(int);
- }
-}
-
-/**
- \internal
- Handle bytesWritten signals from the underlying target device.
- We adjust the target's value for bytes that are part of auth packets.
-*/
-void QAuthDevice::targetBytesWritten( qint64 bytes )
-{
- if ( m_skipWritten >= bytes ) {
- m_skipWritten -= bytes;
- bytes = 0;
- } else if ( m_skipWritten > 0 ) {
- bytes -= m_skipWritten;
- m_skipWritten = 0;
- }
- if ( bytes > 0 ) {
- emit bytesWritten( bytes );
- }
-}
-
-/**
- \internal
- Pre-process the message to determine what QWS command it is. This
- information is used as the "request" for the purposes of authorization.
-
- The request and other data on the connection (id, PID, etc.) are forwarded
- to all policy listeners by emitting a signal.
-
- The signal must be processed synchronously because on return the allow/deny
- status is used immediately to either drop or continue processing the message.
-*/
-bool QAuthDevice::authorizeMessage()
-{
- if ( analyzer == NULL )
- analyzer = new RequestAnalyzer();
- QString request = (*analyzer)( &msgQueue );
- if ( analyzer->requireMoreData() )
- return false;
- bool isAuthorized = true;
-
- if ( !request.isEmpty() && request != QLatin1String("Unknown") )
- {
- isAuthorized = QTransportAuth::getInstance()->authorizeRequest( *d, request );
- }
-
- bool moreToProcess = ( msgQueue.size() - analyzer->bytesAnalyzed() ) > (int)sizeof(int);
- if ( isAuthorized )
- {
-#ifdef QTRANSPORTAUTH_DEBUG
- qDebug() << getpid() << "SERVER authorized: releasing" << analyzer->bytesAnalyzed() << "byte command" << request;
-#endif
- m_bytesAvailable = analyzer->bytesAnalyzed();
- emit QIODevice::readyRead();
- return moreToProcess;
- }
- else
- {
- msgQueue = msgQueue.mid( analyzer->bytesAnalyzed() );
- }
-
- return true;
-}
-
-void QAuthDevice::setRequestAnalyzer( RequestAnalyzer *ra )
-{
- Q_ASSERT( ra );
- if ( analyzer )
- delete analyzer;
- analyzer = ra;
-}
-
-/*!
- \internal
- Add authentication header to the beginning of a message
-
- Note that the per-process auth cookie is used. This key should be rewritten in
- the binary image of the executable at install time to make it unique.
-
- For this to be secure some mechanism (eg MAC kernel or other
- permissions) must prevent other processes from reading the key.
-
- The buffer must have AUTH_SPACE(0) bytes spare at the beginning for the
- authentication header to be added.
-
- Returns true if header successfully added. Will fail if the
- per-process key has not yet been set with setProcessKey()
-*/
-bool QTransportAuth::authToMessage( QTransportAuth::Data &d, char *hdr, const char *msg, int msgLen )
-{
- // qDebug( "authToMessage(): prog id %u", d.progId );
- // only authorize connection oriented transports once, unless key has changed
- if ( d.connection() && ((d.status & QTransportAuth::ErrMask) != QTransportAuth::Pending) &&
- d_func()->authKey.progId == d.progId )
- return false;
- d.progId = d_func()->authKey.progId;
- // If Unix socket credentials are being used the key wont be set
- if ( !d_func()->keyInitialised )
- return false;
- unsigned char digest[QSXE_KEY_LEN];
- char *msgPtr = hdr;
- // magic always goes on the beginning
- for ( int m = 0; m < QSXE_MAGIC_BYTES; ++m )
- *msgPtr++ = magic[m];
- hdr[ QSXE_LEN_IDX ] = (unsigned char)msgLen;
- if ( !d.trusted())
- {
- // Use HMAC
- int rc = hmac_md5( (unsigned char *)msg, msgLen, d_func()->authKey.key, QSXE_KEY_LEN, digest );
- if ( rc == -1 )
- return false;
- memcpy( hdr + QSXE_KEY_IDX, digest, QSXE_KEY_LEN );
- }
- else
- {
- memcpy( hdr + QSXE_KEY_IDX, d_func()->authKey.key, QSXE_KEY_LEN );
- }
-
- hdr[ QSXE_PROG_IDX ] = d_func()->authKey.progId;
-
-#ifdef QTRANSPORTAUTH_DEBUG
- char keydisplay[QSXE_KEY_LEN*2+1];
- hexstring( keydisplay, d_func()->authKey.key, QSXE_KEY_LEN );
-
- qDebug( "%d CLIENT Auth to message %s against prog id %u and key %s\n",
- getpid(), msg, d_func()->authKey.progId, keydisplay );
-#endif
-
- // TODO implement sequence to prevent replay attack, not required
- // for trusted transports
- hdr[ QSXE_SEQ_IDX ] = 1; // dummy sequence
-
- d.status = ( d.status & QTransportAuth::StatusMask ) | QTransportAuth::Success;
- return true;
-}
-
-
-/*!
- Check authorization on the \a msg, which must be of size \a msgLen,
- for the transport \a d.
-
- If able to determine authorization, return the program identity of
- the message source in the reference \a progId, and return true.
-
- Otherwise return false.
-
- If data is being received on a socket, it may be that more data is yet
- needed before authentication can proceed.
-
- Also the message may not be an authenticated at all.
-
- In these cases the method returns false to indicate authorization could
- not be determined:
- \list
- \i The message is too small to carry the authentication data
- (status TooSmall is set on the \a d transport )
- \i The 4 magic bytes are missing from the message start
- (status NoMagic is set on the \a d transport )
- \i The message is too small to carry the auth + claimed payload
- (status TooSmall is set on the \a d transport )
- \endlist
-
- If however the authentication header (preceded by the magic bytes) and
- any authenticated payload is received the method will determine the
- authentication status, and return true.
-
- In the following cases as well as returning true it will also emit
- an authViolation():
- \list
- \i If the program id claimed by the message is not found in the key file
- (status NoSuchKey is set on the \a d transport )
- \i The authentication token failed against the claimed program id:
- \list
- \i in the case of trusted transports, the secret did not match
- \i in the case of untrusted transports the HMAC code did not match
- \endlist
- (status FailMatch is set on the \a d transport )
- \endlist
-
- In these cases the authViolation( QTransportAuth::Data d ) signal is emitted
- and the error string can be obtained from the status like this:
- \snippet doc/src/snippets/code/src_gui_embedded_qtransportauth_qws.cpp 4
-*/
-bool QTransportAuth::authFromMessage( QTransportAuth::Data &d, const char *msg, int msgLen )
-{
- if ( msgLen < QSXE_MAGIC_BYTES )
- {
- d.status = ( d.status & QTransportAuth::StatusMask ) | QTransportAuth::TooSmall;
- return false;
- }
- // if no magic bytes, exit straight away
- int m;
- const unsigned char *mptr = reinterpret_cast<const unsigned char *>(msg);
- for ( m = 0; m < QSXE_MAGIC_BYTES; ++m )
- {
- if ( *mptr++ != magic[m] )
- {
- d.status = ( d.status & QTransportAuth::StatusMask ) | QTransportAuth::NoMagic;
- return false;
- }
- }
-
- if ( msgLen < AUTH_SPACE(1) )
- {
- d.status = ( d.status & QTransportAuth::StatusMask ) | QTransportAuth::TooSmall;
- return false;
- }
-
- // At this point we know the header is at least long enough to contain valid auth
- // data, however the data may be spoofed. If it is not verified then the status will
- // be set to uncertified so the spoofed data will not be relied on. However we want to
- // know the program id which is being reported (even if it might be spoofed) for
- // policy debugging purposes. So set it here, rather than after verification.
- d.progId = msg[QSXE_PROG_IDX];
-
-#ifdef QTRANSPORTAUTH_DEBUG
- char authhdr[QSXE_HEADER_LEN*2+1];
- hexstring( authhdr, reinterpret_cast<const unsigned char *>(msg), QSXE_HEADER_LEN );
- qDebug( "%d SERVER authFromMessage(): message header is %s",
- getpid(), authhdr );
-#endif
-
- unsigned char authLen = (unsigned char)(msg[ QSXE_LEN_IDX ]);
-
- if ( msgLen < AUTH_SPACE(authLen) )
- {
- d.status = ( d.status & QTransportAuth::StatusMask ) | QTransportAuth::TooSmall;
- return false;
- }
-
- bool isCached = d_func()->keyCache.contains( d.progId );
- const unsigned char *clientKey = d_func()->getClientKey( d.progId );
- if ( clientKey == NULL )
- {
- d.status = ( d.status & QTransportAuth::StatusMask ) | QTransportAuth::NoSuchKey;
- return false;
- }
-
-#ifdef QTRANSPORTAUTH_DEBUG
- char keydisplay[QSXE_KEY_LEN*2+1];
- hexstring( keydisplay, clientKey, QSXE_KEY_LEN );
- qDebug( "\t\tauthFromMessage(): message %s against prog id %u and key %s\n",
- AUTH_DATA(msg), ((unsigned int)d.progId), keydisplay );
-#endif
-
- const unsigned char *auth_tok;
- unsigned char digest[QSXE_KEY_LEN];
- bool multi_tok = false;
-
- bool need_to_recheck=false;
- do
- {
- if ( !d.trusted())
- {
- hmac_md5( AUTH_DATA(msg), authLen, clientKey, QSXE_KEY_LEN, digest );
- auth_tok = digest;
- }
- else
- {
- auth_tok = clientKey;
- multi_tok = true; // 1 or more keys are in the clientKey
- }
- while( true )
- {
- if ( memcmp( auth_tok, magic, QSXE_MAGIC_BYTES ) == 0
- && memcmp( auth_tok + QSXE_MAGIC_BYTES, magic, QSXE_MAGIC_BYTES ) == 0 )
- break;
- if ( memcmp( msg + QSXE_KEY_IDX, auth_tok, QSXE_KEY_LEN ) == 0 )
- {
- d.status = ( d.status & QTransportAuth::StatusMask ) | QTransportAuth::Success;
- return true;
- }
- if ( !multi_tok )
- break;
- auth_tok += QSXE_KEY_LEN;
- }
- //the keys cached on d.progId may not contain the binary key because the cache entry was made
- //before the binary had first started, must search for client key again.
- if ( isCached )
- {
- d_func()->keyCache.remove(d.progId);
- isCached = false;
-
-#ifdef QTRANSPORTAUTH_DEBUG
- qDebug() << "QTransportAuth::authFromMessage(): key not found in set of keys cached"
- << "against prog Id =" << d.progId << ". Re-obtaining client key. ";
-#endif
- clientKey = d_func()->getClientKey( d.progId );
- if ( clientKey == NULL )
- {
- d.status = ( d.status & QTransportAuth::StatusMask ) | QTransportAuth::NoSuchKey;
- return false;
- }
- need_to_recheck = true;
- }
- else
- {
- need_to_recheck = false;
- }
- } while( need_to_recheck );
-
- d.status = ( d.status & QTransportAuth::StatusMask ) | QTransportAuth::FailMatch;
- qWarning() << "QTransportAuth::authFromMessage():failed authentication";
- FAREnforcer::getInstance()->logAuthAttempt( QDateTime::currentDateTime() );
- emit authViolation( d );
- return false;
-}
-
-
-#ifdef QTRANSPORTAUTH_DEBUG
-/*!
- sprintf into hex - dest \a buf, src \a key, \a key_len is length of key.
-
- The target buf should be [ key_len * 2 + 1 ] in size
-*/
-void hexstring( char *buf, const unsigned char* key, size_t key_len )
-{
- unsigned int i, p;
- for ( i = 0, p = 0; i < key_len; i++, p+=2 )
- {
- unsigned char lo_nibble = key[i] & 0x0f;
- unsigned char hi_nibble = key[i] >> 4;
- buf[p] = (int)hi_nibble > 9 ? hi_nibble-10 + 'A' : hi_nibble + '0';
- buf[p+1] = (int)lo_nibble > 9 ? lo_nibble-10 + 'A' : lo_nibble + '0';
- }
- buf[p] = '\0';
-}
-#endif
-
-/*
- HMAC MD5 as listed in RFC 2104
-
- This code is taken from:
-
- http://www.faqs.org/rfcs/rfc2104.html
-
- with the allowance for keys other than length 16 removed, but otherwise
- a straight cut-and-paste.
-
- The HMAC_MD5 transform looks like:
-
- \snippet doc/src/snippets/code/src.gui.embedded.qtransportauth_qws.cpp 5
-
- \list
- \i where K is an n byte key
- \i ipad is the byte 0x36 repeated 64 times
- \i opad is the byte 0x5c repeated 64 times
- \i and text is the data being protected
- \endlist
-
- Hardware is available with accelerated implementations of HMAC-MD5 and
- HMAC-SHA1. Where this hardware is available, this routine should be
- replaced with a call into the accelerated version.
-*/
-
-static int hmac_md5(
- unsigned char* text, /* pointer to data stream */
- int text_length, /* length of data stream */
- const unsigned char* key, /* pointer to authentication key */
- int key_length, /* length of authentication key */
- unsigned char * digest /* caller digest to be filled in */
- )
-{
- MD5Context context;
- unsigned char k_ipad[65]; /* inner padding - * key XORd with ipad */
- unsigned char k_opad[65]; /* outer padding - * key XORd with opad */
- int i;
-
- /* in this implementation key_length == 16 */
- if ( key_length != 16 )
- {
- fprintf( stderr, "Key length was %d - must be 16 bytes", key_length );
- return 0;
- }
-
- /* start out by storing key in pads */
- memset( k_ipad, 0, sizeof k_ipad );
- memset( k_opad, 0, sizeof k_opad );
- memcpy( k_ipad, key, key_length );
- memcpy( k_opad, key, key_length );
-
- /* XOR key with ipad and opad values */
- for (i=0; i<64; i++) {
- k_ipad[i] ^= 0x36;
- k_opad[i] ^= 0x5c;
- }
-
- /* perform inner MD5 */
- MD5Init(&context); /* init context for 1st pass */
- MD5Update(&context, k_ipad, 64); /* start with inner pad */
- MD5Update(&context, text, text_length); /* then text of datagram */
- MD5Final(&context, digest); /* finish up 1st pass */
-
- /* perform outer MD5 */
- MD5Init(&context); /* init context for 2nd pass */
- MD5Update(&context, k_opad, 64); /* start with outer pad */
- MD5Update(&context, digest, 16); /* then results of 1st * hash */
- MD5Final(&context, digest); /* finish up 2nd pass */
- return 1;
-}
-
-
-const int FAREnforcer::minutelyRate = 4; //allowed number of false authentication attempts per minute
-const QString FAREnforcer::FARMessage = QLatin1String("FAR_Exceeded");
-const QString FAREnforcer::SxeTag = QLatin1String("<SXE Breach>");
-const int FAREnforcer::minute = 60;
-
-FAREnforcer::FAREnforcer():authAttempts()
-{
- QDateTime nullDateTime = QDateTime();
- for (int i = 0; i < minutelyRate; i++ )
- authAttempts << nullDateTime;
-}
-
-
-FAREnforcer *FAREnforcer::getInstance()
-{
- static FAREnforcer theInstance;
- return &theInstance;
-}
-
-void FAREnforcer::logAuthAttempt( QDateTime time )
-{
- QDateTime dt = authAttempts.takeFirst();
-
- authAttempts.append( time );
- if ( dt.secsTo( authAttempts.last() ) <= minute )
- {
-#if defined(SXE_DISCOVERY)
- if ( QTransportAuth::getInstance()->isDiscoveryMode() ) {
- static QBasicAtomicInt reported = Q_BASIC_ATOMIC_INITIALIZER(0);
- if ( reported.testAndSetRelaxed(0,1) ) {
-#ifndef QT_NO_TEXTSTREAM
- QString logFilePath = QTransportAuth::getInstance()->logFilePath();
- if ( !logFilePath.isEmpty() ) {
- QFile log( logFilePath );
- if ( !log.open(QIODevice::WriteOnly | QIODevice::Append) ) {
- qWarning("Could not write to log in discovery mode: %s",
- qPrintable(logFilePath) );
- } else {
- QTextStream ts( &log );
- ts << "\t\tWarning: False Authentication Rate of " << minutelyRate << "\n"
- << "\t\tserver connections/authentications per minute has been exceeded,\n"
- << "\t\tno further warnings will be issued\n";
- }
- }
- }
-#endif
- reset();
- return;
- }
-#endif
- syslog( LOG_ERR | LOG_LOCAL6, "%s %s",
- qPrintable( FAREnforcer::SxeTag ),
- qPrintable( FAREnforcer::FARMessage ) );
- reset();
- }
-}
-
-void FAREnforcer::reset()
-{
- QDateTime nullDateTime = QDateTime();
- for (int i = 0; i < minutelyRate; i++ )
- authAttempts[i] = nullDateTime;
-}
-
-QT_END_NAMESPACE
-
-#include "moc_qtransportauth_qws_p.cpp"
-
-#endif // QT_NO_SXE
diff --git a/src/gui/embedded/qtransportauth_qws.h b/src/gui/embedded/qtransportauth_qws.h
deleted file mode 100644
index e13835d846..0000000000
--- a/src/gui/embedded/qtransportauth_qws.h
+++ /dev/null
@@ -1,281 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QTRANSPORTAUTH_QWS_H
-#define QTRANSPORTAUTH_QWS_H
-
-#include <QtCore/qglobal.h>
-
-#if !defined(QT_NO_SXE) || defined(SXE_INSTALLER)
-
-#include <QtCore/qobject.h>
-#include <QtCore/qhash.h>
-#include <QtCore/qstring.h>
-#include <QtCore/qbuffer.h>
-#include <QtCore/qpointer.h>
-
-#include <sys/types.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QAuthDevice;
-class QWSClient;
-class QIODevice;
-class QTransportAuthPrivate;
-class QMutex;
-
-class Q_GUI_EXPORT QTransportAuth : public QObject
-{
- Q_OBJECT
-public:
- static QTransportAuth *getInstance();
-
- enum Result {
- // Error codes
- Pending = 0x00,
- TooSmall = 0x01,
- CacheMiss = 0x02,
- NoMagic = 0x03,
- NoSuchKey = 0x04,
- FailMatch = 0x05,
- OutOfDate = 0x06,
- // reserved for expansion
- Success = 0x1e,
- ErrMask = 0x1f,
-
- // Verification codes
- Allow = 0x20,
- Deny = 0x40,
- Ask = 0x60,
- // reserved
- StatusMask = 0xe0
- };
-
- enum Properties {
- Trusted = 0x01,
- Connection = 0x02,
- UnixStreamSock = 0x04,
- SharedMemory = 0x08,
- MessageQueue = 0x10,
- UDP = 0x20,
- TCP = 0x40,
- UserDefined = 0x80,
- TransportType = 0xfc
- };
-
- struct Data
- {
- Data() { processId = -1; }
- Data( unsigned char p, int d )
- : properties( p )
- , descriptor( d )
- , processId( -1 )
- {
- if (( properties & TransportType ) == TCP ||
- ( properties & TransportType ) == UnixStreamSock )
- properties |= Connection;
- }
-
- unsigned char properties;
- unsigned char progId;
- unsigned char status;
- unsigned int descriptor; // socket fd or shmget key
- pid_t processId;
-
- bool trusted() const;
- void setTrusted( bool );
- bool connection() const;
- void setConnection( bool );
- };
-
- static const char *errorString( const QTransportAuth::Data & );
-
- QTransportAuth::Data *connectTransport( unsigned char, int );
-
- QAuthDevice *authBuf( QTransportAuth::Data *, QIODevice * );
- QAuthDevice *recvBuf( QTransportAuth::Data *, QIODevice * );
- QIODevice *passThroughByClient( QWSClient * ) const;
-
- void setKeyFilePath( const QString & );
- QString keyFilePath() const;
- const unsigned char *getClientKey( unsigned char progId );
- void invalidateClientKeyCache();
- QMutex *getKeyFileMutex();
- void setLogFilePath( const QString & );
- QString logFilePath() const;
- void setPackageRegistry( QObject *registry );
- bool isDiscoveryMode() const;
- void setProcessKey( const char * );
- void setProcessKey( const char *, const char * );
- void registerPolicyReceiver( QObject * );
- void unregisterPolicyReceiver( QObject * );
-
- bool authToMessage( QTransportAuth::Data &d, char *hdr, const char *msg, int msgLen );
- bool authFromMessage( QTransportAuth::Data &d, const char *msg, int msgLen );
-
- bool authorizeRequest( QTransportAuth::Data &d, const QString &request );
-
-Q_SIGNALS:
- void policyCheck( QTransportAuth::Data &, const QString & );
- void authViolation( QTransportAuth::Data & );
-private Q_SLOTS:
- void bufferDestroyed( QObject * );
-
-private:
- // users should never construct their own
- QTransportAuth();
- ~QTransportAuth();
-
- friend class QAuthDevice;
- Q_DECLARE_PRIVATE(QTransportAuth)
-};
-
-class Q_GUI_EXPORT RequestAnalyzer
-{
-public:
- RequestAnalyzer();
- virtual ~RequestAnalyzer();
- QString operator()( QByteArray *data ) { return analyze( data ); }
- bool requireMoreData() const { return moreData; }
- qint64 bytesAnalyzed() const { return dataSize; }
-protected:
- virtual QString analyze( QByteArray * );
- bool moreData;
- qint64 dataSize;
-};
-
-/*!
- \internal
- \class QAuthDevice
-
- \brief Pass-through QIODevice sub-class for authentication.
-
- Use this class to forward on or receive forwarded data over a real
- device for authentication.
-*/
-class Q_GUI_EXPORT QAuthDevice : public QIODevice
-{
- Q_OBJECT
-public:
- enum AuthDirection {
- Receive,
- Send
- };
- QAuthDevice( QIODevice *, QTransportAuth::Data *, AuthDirection );
- ~QAuthDevice();
- void setTarget( QIODevice *t ) { m_target = t; }
- QIODevice *target() const { return m_target; }
- void setClient( QObject* );
- QObject *client() const;
- void setRequestAnalyzer( RequestAnalyzer * );
- bool isSequential() const;
- bool atEnd() const;
- qint64 bytesAvailable() const;
- qint64 bytesToWrite() const;
- bool seek( qint64 );
- QByteArray & buffer();
-
-protected:
- qint64 readData( char *, qint64 );
- qint64 writeData(const char *, qint64 );
-private Q_SLOTS:
- void recvReadyRead();
- void targetBytesWritten( qint64 );
-private:
- bool authorizeMessage();
-
- QTransportAuth::Data *d;
- AuthDirection way;
- QIODevice *m_target;
- QObject *m_client;
- QByteArray msgQueue;
- qint64 m_bytesAvailable;
- qint64 m_skipWritten;
-
- RequestAnalyzer *analyzer;
-};
-
-inline bool QAuthDevice::isSequential() const
-{
- return true;
-}
-
-inline bool QAuthDevice::seek( qint64 )
-{
- return false;
-}
-
-inline bool QAuthDevice::atEnd() const
-{
- return msgQueue.isEmpty();
-}
-
-inline qint64 QAuthDevice::bytesAvailable() const
-{
- if ( way == Receive )
- return m_bytesAvailable;
- else
- return ( m_target ? m_target->bytesAvailable() : 0 );
-}
-
-inline qint64 QAuthDevice::bytesToWrite() const
-{
- return msgQueue.size();
-}
-
-inline QByteArray &QAuthDevice::buffer()
-{
- return msgQueue;
-}
-
-
-
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QT_NO_SXE
-#endif // QTRANSPORTAUTH_QWS_H
diff --git a/src/gui/embedded/qtransportauth_qws_p.h b/src/gui/embedded/qtransportauth_qws_p.h
deleted file mode 100644
index 3a9df09ced..0000000000
--- a/src/gui/embedded/qtransportauth_qws_p.h
+++ /dev/null
@@ -1,189 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QTRANSPORTAUTH_QWS_P_H
-#define QTRANSPORTAUTH_QWS_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/qglobal.h>
-
-#ifndef QT_NO_SXE
-
-#include "qtransportauth_qws.h"
-#include "qtransportauthdefs_qws.h"
-#include "qbuffer.h"
-
-#include <qmutex.h>
-#include <qdatetime.h>
-#include "private/qobject_p.h"
-
-#include <QtCore/qcache.h>
-
-QT_BEGIN_NAMESPACE
-
-// Uncomment to generate debug output
-// #define QTRANSPORTAUTH_DEBUG 1
-
-#ifdef QTRANSPORTAUTH_DEBUG
-void hexstring( char *buf, const unsigned char* key, size_t sz );
-#endif
-
-// proj id for ftok usage in sxe
-#define SXE_PROJ 10022
-
-/*!
- \internal
- memset for security purposes, guaranteed not to be optimized away
- http://www.faqs.org/docs/Linux-HOWTO/Secure-Programs-HOWTO.html
-*/
-void *guaranteed_memset(void *v,int c,size_t n);
-
-class QUnixSocketMessage;
-
-/*!
- \internal
- \class AuthCookie
- Struct to carry process authentication key and id
-*/
-#define QSXE_HEADER_LEN 24
-
-/*!
- \macro AUTH_ID
- Macro to manage authentication header. Format of header is:
- \table
- \header \i BYTES \i CONTENT
- \row \i 0-3 \i magic numbers
- \row \i 4 \i length of authenticated data (max 255 bytes)
- \row i\ 5 \i reserved
- \row \i 6-21 \i MAC digest, or shared secret in case of simple auth
- \row \i 22 \i program id
- \row \i 23 \i sequence number
- \endtable
- Total length of the header is 24 bytes
-
- However this may change. Instead of coding these numbers use the AUTH_ID,
- AUTH_KEY, AUTH_DATA and AUTH_SPACE macros.
-*/
-
-#define AUTH_ID(k) ((unsigned char)(k[QSXE_KEY_LEN]))
-#define AUTH_KEY(k) ((unsigned char *)(k))
-
-#define AUTH_DATA(x) (unsigned char *)((x) + QSXE_HEADER_LEN)
-#define AUTH_SPACE(x) ((x) + QSXE_HEADER_LEN)
-#define QSXE_LEN_IDX 4
-#define QSXE_KEY_IDX 6
-#define QSXE_PROG_IDX 22
-#define QSXE_SEQ_IDX 23
-
-class SxeRegistryLocker : public QObject
-{
- Q_OBJECT
-public:
- SxeRegistryLocker( QObject * );
- ~SxeRegistryLocker();
- bool success() const { return m_success; }
-private:
- bool m_success;
- QObject *m_reg;
-};
-
-class QTransportAuthPrivate : public QObjectPrivate
-{
- Q_DECLARE_PUBLIC(QTransportAuth)
-public:
- QTransportAuthPrivate();
- ~QTransportAuthPrivate();
-
- const unsigned char *getClientKey( unsigned char progId );
- void invalidateClientKeyCache();
-
- bool keyInitialised;
- QString m_logFilePath;
- QString m_keyFilePath;
- QObject *m_packageRegistry;
- AuthCookie authKey;
- QCache<unsigned char, char> keyCache;
- QHash< QObject*, QIODevice*> buffersByClient;
- QMutex keyfileMutex;
-};
-
-/*!
- \internal
- Enforces the False Authentication Rate. If more than 4 authentications
- are received per minute the sxemonitor is notified that the FAR has been exceeded
-*/
-class FAREnforcer
-{
- public:
- static FAREnforcer *getInstance();
- void logAuthAttempt( QDateTime time = QDateTime::currentDateTime() );
- void reset();
-
-#ifndef TEST_FAR_ENFORCER
- private:
-#endif
- FAREnforcer();
- FAREnforcer( const FAREnforcer & );
- FAREnforcer &operator=(FAREnforcer const & );
-
- static const QString FARMessage;
- static const int minutelyRate;
- static const QString SxeTag;
- static const int minute;
-
- QList<QDateTime> authAttempts;
-};
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_SXE
-#endif // QTRANSPORTAUTH_QWS_P_H
-
diff --git a/src/gui/embedded/qtransportauthdefs_qws.h b/src/gui/embedded/qtransportauthdefs_qws.h
deleted file mode 100644
index fc9595e235..0000000000
--- a/src/gui/embedded/qtransportauthdefs_qws.h
+++ /dev/null
@@ -1,174 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QTRANSPORTAUTHDEFS_QWS_H
-#define QTRANSPORTAUTHDEFS_QWS_H
-
-#include <sys/types.h>
-#include <string.h>
-
-#include <QtCore/qglobal.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#define QSXE_KEY_LEN 16
-#define QSXE_MAGIC_BYTES 4
-
-// Number of bytes of each message to authenticate. Just need to ensure
-// that the command at the beginning hasn't been tampered with. This value
-// does not matter for trusted transports.
-#define AMOUNT_TO_AUTHENTICATE 200
-
-#define AUTH_ID(k) ((unsigned char)(k[QSXE_KEY_LEN]))
-#define AUTH_KEY(k) ((unsigned char *)(k))
-
-// must be a largish -ve number under any endianess when cast as an int
-const unsigned char magic[QSXE_MAGIC_BYTES] = { 0xBA, 0xD4, 0xD4, 0xBA };
-const int magicInt = 0xBAD4D4BA;
-
-#define QSXE_KEYFILE "keyfile"
-
-/*
- Header in above format, less the magic bytes.
- Useful for reading off the socket
-*/
-struct AuthHeader
-{
- unsigned char len;
- unsigned char pad;
- unsigned char digest[QSXE_KEY_LEN];
- unsigned char id;
- unsigned char seq;
-};
-
-/*
- Header in a form suitable for authentication routines
-*/
-struct AuthMessage
-{
- AuthMessage()
- {
- ::memset( authData, 0, sizeof(authData) );
- ::memcpy( pad_magic, magic, QSXE_MAGIC_BYTES );
- }
- unsigned char pad_magic[QSXE_MAGIC_BYTES];
- union {
- AuthHeader hdr;
- char authData[sizeof(AuthHeader)];
- };
- char payLoad[AMOUNT_TO_AUTHENTICATE];
-};
-
-/**
- Auth data as stored in _key
-*/
-struct AuthCookie
-{
- unsigned char key[QSXE_KEY_LEN];
- unsigned char pad;
- unsigned char progId;
-};
-
-/*
- Auth data as written to the key file - SUPERSEDED by usr_key_entry
-
- This is still used internally for some functions, ie the socket
- related calls.
-*/
-struct AuthRecord
-{
- union {
- AuthCookie auth;
- char data[sizeof(struct AuthCookie)];
- };
- time_t change_time;
-};
-
-/*!
- \class usr_key_entry
- This comes from the SXE kernel patch file include/linux/lidsif.h
-
- This is the (new) data record for the key file (version 2).
-
- The key file is (now) either /proc/lids/keys (and the per-process
- keys in /proc/<pid>/lids_key) OR for desktop/development ONLY (not
- for production) it is $QPEDIR/etc/keyfile
-
- The key file maps keys to files.
-
- File are identified by inode and device numbers, not paths.
-
- (See the "installs" file for path to inode/device mapping)
-*/
-struct usr_key_entry
-{
- char key[QSXE_KEY_LEN];
- ino_t ino;
- dev_t dev;
-};
-
-
-/*!
- \class IdBlock
- \brief Data record for the manifest file.
- The manifest file maps program id's to files
-*/
-struct IdBlock
-{
- quint64 inode;
- quint64 device;
- unsigned char pad;
- unsigned char progId;
- unsigned short installId;
- unsigned int keyOffset;
- qint64 install_time;
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QTRANSPORTAUTHDEFS_QWS_H
-
diff --git a/src/gui/embedded/qunixsocket.cpp b/src/gui/embedded/qunixsocket.cpp
deleted file mode 100644
index 85de32da4a..0000000000
--- a/src/gui/embedded/qunixsocket.cpp
+++ /dev/null
@@ -1,1800 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qunixsocket_p.h"
-
-// #define QUNIXSOCKET_DEBUG 1
-
-#include <QtCore/qsocketnotifier.h>
-#include <QtCore/qqueue.h>
-#include <QtCore/qdatetime.h>
-#include "private/qcore_unix_p.h" // overrides QT_OPEN
-
-#ifdef QUNIXSOCKET_DEBUG
-#include <QtCore/qdebug.h>
-#endif
-
-extern "C" {
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-};
-
-#define UNIX_PATH_MAX 108 // From unix(7)
-
-#ifdef QT_LINUXBASE
-// LSB doesn't declare ucred
-struct ucred
-{
- pid_t pid; /* PID of sending process. */
- uid_t uid; /* UID of sending process. */
- gid_t gid; /* GID of sending process. */
-};
-
-// LSB doesn't define the ones below
-#ifndef SO_PASSCRED
-# define SO_PASSCRED 16
-#endif
-#ifndef SCM_CREDENTIALS
-# define SCM_CREDENTIALS 0x02
-#endif
-#ifndef MSG_DONTWAIT
-# define MSG_DONTWAIT 0x40
-#endif
-#ifndef MSG_NOSIGNAL
-# define MSG_NOSIGNAL 0x4000
-#endif
-
-#endif // QT_LINUXBASE
-
-QT_BEGIN_NAMESPACE
-
-///////////////////////////////////////////////////////////////////////////////
-// class QUnixSocketRights
-///////////////////////////////////////////////////////////////////////////////
-/*!
- \class QUnixSocketRights
- \internal
-
- \brief The QUnixSocketRights class encapsulates QUnixSocket rights data.
- \omit
- \ingroup Platform::DeviceSpecific
- \ingroup Platform::OS
- \ingroup Platform::Communications
- \endomit
- \ingroup qws
-
- \l QUnixSocket allows you to transfer Unix file descriptors between processes.
- A file descriptor is referred to as "rights data" as it allows one process to
- transfer its right to access a resource to another.
-
- The Unix system verifies resource permissions only when the resource is first
- opened. For example, consider a file on disk readable only by the user "qt".
- A process running as user "qt" will be able to open this file for reading.
- If, while the process was still reading from the file, the ownership was
- changed from user "qt" to user "root", the process would be allowed to
- continue reading from the file, even though attempting to reopen the file
- would be denied. Permissions are associated with special descriptors called
- file descriptors which are returned to a process after it initially opens a
- resource.
-
- File descriptors can be duplicated within a process through the dup(2) system
- call. File descriptors can be passed between processes using the
- \l QUnixSocket class in the same way. Even though the receiving process never
- opened the resource directly, it has the same permissions to access it as the
- process that did.
-
- \sa QUnixSocket
- */
-struct QUnixSocketRightsPrivate : public QSharedData
-{
- virtual ~QUnixSocketRightsPrivate() {
-#ifdef QUNIXSOCKET_DEBUG
- int closerv =
-#endif
- QT_CLOSE(fd);
-#ifdef QUNIXSOCKET_DEBUG
- if(0 != closerv) {
- qDebug() << "QUnixSocketRightsPrivate: Unable to close managed"
- " file descriptor (" << ::strerror(errno) << ')';
- }
-#endif
- }
-
- int fd;
-};
-
-/*!
- Create a new QUnixSocketRights instance containing the file descriptor \a fd.
- \a fd will be dup(2)'d internally, so the application is free to close \a fd
- following this call.
-
- If the dup(2) fails, or you pass an invalid \a fd, an
- \l {QUnixSocketRights::isValid()}{invalid } object will be
- constructed.
-
- QUnixSocketRights instances are immutable and the internal file descriptor
- will be shared between any copies made of this object. The system will
- close(2) the file descriptor once it is no longer needed.
- */
-QUnixSocketRights::QUnixSocketRights(int fd)
-{
- d = new QUnixSocketRightsPrivate();
- if(-1 == fd) {
- d->fd = -1;
- } else {
- d->fd = qt_safe_dup(fd);
-#ifdef QUNIXSOCKET_DEBUG
- if(-1 == d->fd) {
- qDebug() << "QUnixSocketRights: Unable to duplicate fd "
- << fd << " (" << ::strerror(errno) << ')';
- }
-#endif
- }
-}
-
-/*!
- \internal
-
- Construct a QUnixSocketRights instance on \a fd without dup(2)'ing the file
- descriptor.
- */
-QUnixSocketRights::QUnixSocketRights(int fd,int)
-{
- Q_ASSERT(-1 != fd);
- d = new QUnixSocketRightsPrivate();
- d->fd = fd;
-}
-
-/*!
- Destroys the QUnixSocketRights instance.
- */
-QUnixSocketRights::~QUnixSocketRights()
-{
-}
-
-/*!
- Create a copy of \a other.
- */
-QUnixSocketRights &
-QUnixSocketRights::operator=(const QUnixSocketRights & other)
-{
- d = other.d;
- return *this;
-}
-
-/*!
- Create a copy of \a other.
- */
-QUnixSocketRights::QUnixSocketRights(const QUnixSocketRights & other)
-: d(other.d)
-{
-}
-
-/*!
- Returns true if this QUnixSocketRights instance is managing a valid file
- descriptor. This method is equivalent to (-1 != peekFd()).
-
- \sa QUnixSocketRights::peekFd()
- */
-bool QUnixSocketRights::isValid() const
-{
- return d->fd != -1;
-}
-
-/*!
- Return a duplicate of the file descriptor contained in this object. If this
- is an \l {QUnixSocketRights::isValid()}{invalid } object, or the
- dup(2) call fails, an invalid file descriptor (-1) will be returned.
-
- \sa QUnixSocketRights::peekFd()
- */
-int QUnixSocketRights::dupFd() const
-{
- if(-1 == d->fd) return -1;
-
- int rv = qt_safe_dup(d->fd);
-
-#ifdef QUNIXSOCKET_DEBUG
- if(-1 == rv)
- qDebug() << "QUnixSocketRights: Unable to duplicate managed file "
- "descriptor (" << ::strerror(errno) << ')';
-#endif
-
- return rv;
-}
-
-/*!
- Returns the file descriptor contained in this object. If this
- is an \l {QUnixSocketRights::isValid()}{invalid } object an invalid
- file descriptor (-1) will be returned.
-
- The lifetime of this file descriptor is tied to the lifetime of the
- QUnixSocketRights instance. The file descriptor returned by this method
- \e may be close(2)'d when the QUnixSocketRights instance is destroyed. If
- you want to continue to use the file descriptor use
- \l QUnixSocketRights::dupFd() instead.
-
- \sa QUnixSocketRights::dupFd()
- */
-int QUnixSocketRights::peekFd() const
-{
- return d->fd;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// class QUnixSocketMessage
-///////////////////////////////////////////////////////////////////////////////
-struct QUnixSocketMessagePrivate : public QSharedData
-{
- QUnixSocketMessagePrivate()
- : state(Default), vec(0), iovecLen(0), dataSize(0) {}
- QUnixSocketMessagePrivate(const QByteArray & b)
- : bytes(b), state(Default), vec(0), iovecLen(0), dataSize(0) {}
- QUnixSocketMessagePrivate(const QByteArray & b,
- const QList<QUnixSocketRights> & r)
- : bytes(b), rights(r), state(Default), vec(0), iovecLen(0), dataSize(0) {}
-
- int size() const { return vec ? dataSize : bytes.size(); }
- void removeBytes( unsigned int );
-
- QByteArray bytes;
- QList<QUnixSocketRights> rights;
-
- enum AncillaryDataState {
- Default = 0x00,
- Truncated = 0x01,
- Credential = 0x02
- };
- AncillaryDataState state;
-
- pid_t pid;
- gid_t gid;
- uid_t uid;
-
- ::iovec *vec;
- int iovecLen; // number of vectors in array
- int dataSize; // total size of vectors = payload
-};
-
-/*!
- \internal
- Remove \a bytesToDequeue bytes from the front of this message
-*/
-void QUnixSocketMessagePrivate::removeBytes( unsigned int bytesToDequeue )
-{
- if ( vec )
- {
- ::iovec *vecPtr = vec;
- if ( bytesToDequeue > (unsigned int)dataSize ) bytesToDequeue = dataSize;
- while ( bytesToDequeue > 0 && iovecLen > 0 )
- {
- if ( vecPtr->iov_len > bytesToDequeue )
- {
- // dequeue the bytes by taking them off the front of the
- // current vector. since we don't own the iovec, its okay
- // to "leak" this away by pointing past it
- char **base = reinterpret_cast<char**>(&(vecPtr->iov_base));
- *base += bytesToDequeue;
- vecPtr->iov_len -= bytesToDequeue;
- bytesToDequeue = 0;
- }
- else
- {
- // dequeue bytes by skipping a whole vector. again, its ok
- // to lose the pointers to this data
- bytesToDequeue -= vecPtr->iov_len;
- iovecLen--;
- vecPtr++;
- }
- }
- dataSize -= bytesToDequeue;
- if ( iovecLen == 0 ) vec = 0;
- }
- else
- {
- bytes.remove(0, bytesToDequeue );
- }
-}
-
-
-/*!
- \class QUnixSocketMessage
- \internal
-
- \brief The QUnixSocketMessage class encapsulates a message sent or received
- through the QUnixSocket class.
- \omit
- \ingroup Platform::DeviceSpecific
- \ingroup Platform::OS
- \ingroup Platform::Communications
- \endomit
- \ingroup qws
-
- In addition to transmitting regular byte stream data, messages sent over Unix
- domain sockets may have special ancillary properties. QUnixSocketMessage
- instances allow programmers to retrieve and control these properties.
-
- Every QUnixSocketMessage sent has an associated set of credentials. A
- message's credentials consist of the process id, the user id and the group id
- of the sending process. Normally these credentials are set automatically for
- you by the QUnixSocketMessage class and can be queried by the receiving
- process using the \l QUnixSocketMessage::processId(),
- \l QUnixSocketMessage::userId() and \l QUnixSocketMessage::groupId() methods
- respectively.
-
- Advanced applications may wish to change the credentials that their message
- is sent with, and may do so though the \l QUnixSocketMessage::setProcessId(),
- \l QUnixSocketMessage::setUserId() and \l QUnixSocketMessage::setGroupId()
- methods. The validity of these credentials is verified by the system kernel.
- Only the root user can send messages with credentials that are not his own.
- Sending of the message will fail for any non-root user who attempts to
- fabricate credentials. Note that this failure is enforced by the system
- kernel - receivers can trust the accuracy of credential data!
-
- Unix domain socket messages may also be used to transmit Unix file descriptors
- between processes. In this context, file descriptors are known as rights data
- and are encapsulated by the \l QUnixSocketRights class. Senders can set the
- file descriptors to transmit using the \l QUnixSocketMessage::setRights() and
- receivers can retrieve this data through a call to
- \l QUnixSocketMessage::rights(). \l QUnixSocket and \l QUnixSocketRights
- discuss the specific copy and ordering semantic associated with rights data.
-
- QUnixSocketMessage messages are sent by the \l QUnixSocket::write() method.
- Like any normal network message, attempting to transmit an empty
- QUnixSocketMessage will succeed, but result in a no-op. Limitations in the
- Unix domain protocol semantic will cause a transmission of a
- QUnixSocketMessage with rights data, but no byte data portion, to fail.
-
- \sa QUnixSocket QUnixSocketRights
- */
-
-/*!
- Construct an empty QUnixSocketMessage. This instance will have not data and
- no rights information. The message's credentials will be set to the
- application's default credentials.
- */
-QUnixSocketMessage::QUnixSocketMessage()
-: d(new QUnixSocketMessagePrivate())
-{
-}
-
-/*!
- Construct a QUnixSocketMessage with an initial data payload of \a bytes. The
- message's credentials will be set to the application's default credentials.
- */
-QUnixSocketMessage::QUnixSocketMessage(const QByteArray & bytes)
-: d(new QUnixSocketMessagePrivate(bytes))
-{
-}
-
-/*!
- Construct a QUnixSocketMessage with an initial data payload of \a bytes and
- an initial rights payload of \a rights. The message's credentials will be set
- to the application's default credentials.
-
- A message with rights data but an empty data payload cannot be transmitted
- by the system.
- */
-QUnixSocketMessage::QUnixSocketMessage(const QByteArray & bytes,
- const QList<QUnixSocketRights> & rights)
-: d(new QUnixSocketMessagePrivate(bytes, rights))
-{
-}
-
-/*!
- Create a copy of \a other.
- */
-QUnixSocketMessage::QUnixSocketMessage(const QUnixSocketMessage & other)
-: d(other.d)
-{
-}
-
-/*!
- \fn QUnixSocketMessage::QUnixSocketMessage(const iovec* data, int vecLen)
-
- Construct a QUnixSocketMessage with an initial data payload of \a
- data which points to an array of \a vecLen iovec structures. The
- message's credentials will be set to the application's default
- credentials.
-
- This method can be used to avoid the overhead of copying buffers of data
- and will directly send the data pointed to by \a data on the socket. It also
- avoids the syscall overhead of making a number of small socket write calls,
- if a number of data items can be delivered with one write.
-
- Caller must ensure the iovec * \a data remains valid until the message
- is flushed. Caller retains ownership of the iovec structs.
- */
-QUnixSocketMessage::QUnixSocketMessage(const ::iovec* data, int vecLen )
-: d(new QUnixSocketMessagePrivate())
-{
- for ( int v = 0; v < vecLen; v++ )
- d->dataSize += data[v].iov_len;
- d->vec = const_cast<iovec*>(data);
- d->iovecLen = vecLen;
-}
-
-/*!
- Assign the contents of \a other to this object.
- */
-QUnixSocketMessage & QUnixSocketMessage::operator=(const QUnixSocketMessage & other)
-{
- d = other.d;
- return *this;
-}
-
-/*!
- Destroy this instance.
- */
-QUnixSocketMessage::~QUnixSocketMessage()
-{
-}
-
-/*!
- Set the data portion of the message to \a bytes.
-
- \sa QUnixSocketMessage::bytes()
- */
-void QUnixSocketMessage::setBytes(const QByteArray & bytes)
-{
- d.detach();
- d->bytes = bytes;
-}
-
-/*!
- Set the rights portion of the message to \a rights.
-
- A message with rights data but an empty byte data payload cannot be
- transmitted by the system.
-
- \sa QUnixSocketMessage::rights()
- */
-void QUnixSocketMessage::setRights(const QList<QUnixSocketRights> & rights)
-{
- d.detach();
- d->rights = rights;
-}
-
-/*!
- Return the rights portion of the message.
-
- \sa QUnixSocketMessage::setRights()
- */
-const QList<QUnixSocketRights> & QUnixSocketMessage::rights() const
-{
- return d->rights;
-}
-
-/*!
- Returns true if the rights portion of the message was truncated on reception
- due to insufficient buffer size. The rights buffer size can be adjusted
- through calls to the \l QUnixSocket::setRightsBufferSize() method.
- \l QUnixSocket contains a discussion of the buffering and truncation
- characteristics of the Unix domain protocol.
-
- \sa QUnixSocket QUnixSocket::setRightsBufferSize()
- */
-bool QUnixSocketMessage::rightsWereTruncated() const
-{
- return d->state & QUnixSocketMessagePrivate::Truncated;
-}
-
-/*!
- Return the data portion of the message.
-
- \sa QUnixSocketMessage::setBytes()
- */
-const QByteArray & QUnixSocketMessage::bytes() const
-{
- return d->bytes;
-}
-
-/*!
- Returns the process id credential associated with this message.
-
- \sa QUnixSocketMessage::setProcessId()
- */
-pid_t QUnixSocketMessage::processId() const
-{
- if(QUnixSocketMessagePrivate::Credential & d->state)
- return d->pid;
- else
- return ::getpid();
-}
-
-/*!
- Returns the user id credential associated with this message.
-
- \sa QUnixSocketMessage::setUserId()
- */
-uid_t QUnixSocketMessage::userId() const
-{
- if(QUnixSocketMessagePrivate::Credential & d->state)
- return d->uid;
- else
- return ::geteuid();
-}
-
-/*!
- Returns the group id credential associated with this message.
-
- \sa QUnixSocketMessage::setGroupId()
- */
-gid_t QUnixSocketMessage::groupId() const
-{
- if(QUnixSocketMessagePrivate::Credential & d->state)
- return d->gid;
- else
- return ::getegid();
-}
-
-/*!
- Set the process id credential associated with this message to \a pid. Unless
- you are the root user, setting a fraudulant credential will cause this message
- to fail.
-
- \sa QUnixSocketMessage::processId()
- */
-void QUnixSocketMessage::setProcessId(pid_t pid)
-{
- if(!(d->state & QUnixSocketMessagePrivate::Credential)) {
- d->state = (QUnixSocketMessagePrivate::AncillaryDataState)( d->state | QUnixSocketMessagePrivate::Credential );
- d->uid = ::geteuid();
- d->gid = ::getegid();
- }
- d->pid = pid;
-}
-
-/*!
- Set the user id credential associated with this message to \a uid. Unless
- you are the root user, setting a fraudulant credential will cause this message
- to fail.
-
- \sa QUnixSocketMessage::userId()
- */
-void QUnixSocketMessage::setUserId(uid_t uid)
-{
- if(!(d->state & QUnixSocketMessagePrivate::Credential)) {
- d->state = (QUnixSocketMessagePrivate::AncillaryDataState)( d->state | QUnixSocketMessagePrivate::Credential );
- d->pid = ::getpid();
- d->gid = ::getegid();
- }
- d->uid = uid;
-}
-
-/*!
- Set the group id credential associated with this message to \a gid. Unless
- you are the root user, setting a fraudulant credential will cause this message
- to fail.
-
- \sa QUnixSocketMessage::groupId()
- */
-void QUnixSocketMessage::setGroupId(gid_t gid)
-{
- if(!(d->state & QUnixSocketMessagePrivate::Credential)) {
- d->state = (QUnixSocketMessagePrivate::AncillaryDataState)( d->state | QUnixSocketMessagePrivate::Credential );
- d->pid = ::getpid();
- d->uid = ::geteuid();
- }
- d->gid = gid;
-}
-
-/*!
- Return true if this message is valid. A message with rights data but an empty
- byte data payload cannot be transmitted by the system and is marked as
- invalid.
- */
-bool QUnixSocketMessage::isValid() const
-{
- return d->rights.isEmpty() || !d->bytes.isEmpty();
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// class QUnixSocket
-///////////////////////////////////////////////////////////////////////////////
-#define QUNIXSOCKET_DEFAULT_READBUFFER 1024
-#define QUNIXSOCKET_DEFAULT_ANCILLARYBUFFER 0
-
-/*!
- \class QUnixSocket
- \internal
-
- \brief The QUnixSocket class provides a Unix domain socket.
-
- \omit
- \ingroup Platform::DeviceSpecific
- \ingroup Platform::OS
- \ingroup Platform::Communications
- \endomit
- \ingroup qws
-
- Unix domain sockets provide an efficient mechanism for communications between
- Unix processes on the same machine. Unix domain sockets support a reliable,
- stream-oriented, connection-oriented transport protocol, much like TCP
- sockets. Unlike IP based sockets, the connection endpoint of a Unix domain
- socket is a file on disk of type socket.
-
- In addition to transporting raw data bytes, Unix domain sockets are able to
- transmit special ancillary data. The two types of ancillary data supported
- by the QUnixSocket class are:
-
- \list
- \o Credential Data - Allows a receiver
- to reliably identify the process sending each message.
- \o \l {QUnixSocketRights}{Rights Data } - Allows Unix file descriptors
- to be transmitted between processes.
- \endlist
-
- Because of the need to support ancillary data, QUnixSocket is not a QIODevice,
- like QTcpSocket and QUdpSocket. Instead, QUnixSocket contains a number of
- read and write methods that clients must invoke directly. Rather than
- returning raw data bytes, \l QUnixSocket::read() returns \l QUnixSocketMessage
- instances that encapsulate the message's byte data and any other ancillary
- data.
-
- Ancillary data is transmitted "out of band". Every \l QUnixSocketMessage
- received will have credential data associated with it that the client can
- access through calls to \l QUnixSocketMessage::processId(),
- \l QUnixSocketMessage::groupId() and \l QUnixSocketMessage::userId().
- Likewise, message creators can set the credential data to send through calls
- to \l QUnixSocketMessage::setProcessId(), \l QUnixSocketMessage::setGroupId()
- and \l QUnixSocketMessage::setUserId() respectively. The authenticity of the
- credential values is verified by the system kernel and cannot be fabricated
- by unprivileged processes. Only processes running as the root user can
- specify credential data that does not match the sending process.
-
- Unix file descriptors, known as "rights data", transmitted between processes
- appear as though they had been dup(2)'d between the two. As Unix
- domain sockets present a continuous stream of bytes to the receiver, the
- rights data - which is transmitted out of band - must be "slotted" in at some
- point. The rights data is logically associated with the first byte - called
- the anchor byte - of the \l QUnixSocketMessage to which they are attached.
- Received rights data will be available from the
- \l QUnixSocketMessage::rights() method for the \l QUnixSocketMessage
- instance that contains the anchor byte.
-
- In addition to a \l QUnixSocket::write() that takes a \l QUnixSocketMessage
- instance - allowing a client to transmit both byte and rights data - a
- number of convenience overloads are provided for use when only transmitting
- simple byte data. Unix requires that at least one byte of raw data be
- transmitted in order to send rights data. A \l QUnixSocketMessage instance
- with rights data, but no byte data, cannot be transmitted.
-
- Unix sockets present a stream interface, such that, for example, a single
- six byte transmission might be received as two three byte messages. Rights
- data, on the other hand, is conceptually transmitted as unfragmentable
- datagrams. If the receiving buffer is not large enough to contain all the
- transmitted rights information, the data is truncated and irretreivably lost.
- Users should use the \l QUnixSocket::setRightsBufferSize() method to control
- the buffer size used for this data, and develop protocols that avoid the
- problem. If the buffer size is too small and rights data is truncated,
- the \l QUnixSocketMessage::rightsWereTruncated() flag will be set.
-
- \sa QUnixSocketMessage QUnixSocketRights
-*/
-
-/*!
- \enum QUnixSocket::SocketError
-
- The SocketError enumeration represents the various errors that can occur on
- a Unix domain socket. The most recent error for the socket is available
- through the \l QUnixSocket::error() method.
-
- \value NoError No error has occurred.
- \value InvalidPath An invalid path endpoint was passed to
- \l QUnixSocket::connect(). As defined by unix(7), invalid paths
- include an empty path, or what more than 107 characters long.
- \value ResourceError An error acquiring or manipulating the system's socket
- resources occurred. For example, if the process runs out of available
- socket descriptors, a ResourceError will occur.
- \value NonexistentPath The endpoing passed to \l QUnixSocket::connect() does
- not refer to a Unix domain socket entity on disk.
- \value ConnectionRefused The connection to the specified endpoint was refused.
- Generally this means that there is no server listening on that
- endpoint.
- \value UnknownError An unknown error has occurred.
- \value ReadFailure An error occurred while reading bytes from the connection.
- \value WriteFailure An error occurred while writing bytes into the connection.
- */
-
-/*!
- \enum QUnixSocket::SocketState
-
- The SocketState enumeration represents the connection state of a QUnixSocket
- instance.
-
- \value UnconnectedState The connection is not established.
- \value ConnectedState The connection is established.
- \value ClosingState The connection is being closed, following a call to
- \l QUnixSocket::close(). While closing, any pending data will be
- transmitted, but further writes by the application will be refused.
- */
-
-/*
- \fn QUnixSocket::bytesWritten(qint64 bytes)
-
- This signal is emitted every time a payload of data has been written to the
- connection. The \a bytes argument is set to the number of bytes that were
- written in this payload.
-
- \sa QUnixSocket::readyRead()
-*/
-
-/*
- \fn QUnixSocket::readyRead()
-
- This signal is emitted once every time new data is available for reading from
- the connection. It will only be emitted again once new data is available.
-
- \sa QUnixSocket::bytesWritten()
-*/
-
-/*!
- \fn QUnixSocket::stateChanged(SocketState socketState)
-
- This signal is emitted each time the socket changes connection state.
- \a socketState will be set to the socket's new state.
-*/
-
-class QUnixSocketPrivate : public QObject {
-Q_OBJECT
-public:
- QUnixSocketPrivate(QUnixSocket * _me)
- : me(_me), fd(-1), readNotifier(0), writeNotifier(0),
- state(QUnixSocket::UnconnectedState), error(QUnixSocket::NoError),
- writeQueueBytes(0), messageValid(false), dataBuffer(0),
- dataBufferLength(0), dataBufferCapacity(0), ancillaryBuffer(0),
- ancillaryBufferCount(0), closingTimer(0) {
- QObject::connect(this, SIGNAL(readyRead()), me, SIGNAL(readyRead()));
- QObject::connect(this, SIGNAL(bytesWritten(qint64)),
- me, SIGNAL(bytesWritten(qint64)));
- }
- ~QUnixSocketPrivate()
- {
- if(dataBuffer)
- delete [] dataBuffer;
- if(ancillaryBuffer)
- delete [] ancillaryBuffer;
- }
-
- enum { CausedAbort = 0x70000000 };
-
- QUnixSocket * me;
-
- int fd;
-
- QSocketNotifier * readNotifier;
- QSocketNotifier * writeNotifier;
-
- QUnixSocket::SocketState state;
- QUnixSocket::SocketError error;
-
- QQueue<QUnixSocketMessage> writeQueue;
- unsigned int writeQueueBytes;
-
- bool messageValid;
- ::msghdr message;
- inline void flushAncillary()
- {
- if(!messageValid) return;
- ::cmsghdr * h = (::cmsghdr *)CMSG_FIRSTHDR(&(message));
- while(h) {
-
- if(SCM_RIGHTS == h->cmsg_type) {
- int * fds = (int *)CMSG_DATA(h);
- int numFds = (h->cmsg_len - CMSG_LEN(0)) / sizeof(int);
-
- for(int ii = 0; ii < numFds; ++ii)
- QT_CLOSE(fds[ii]);
- }
-
- h = (::cmsghdr *)CMSG_NXTHDR(&(message), h);
- }
-
- messageValid = false;
- }
-
-
- char * dataBuffer;
- unsigned int dataBufferLength;
- unsigned int dataBufferCapacity;
-
- char * ancillaryBuffer;
- inline unsigned int ancillaryBufferCapacity()
- {
- return CMSG_SPACE(sizeof(::ucred)) + CMSG_SPACE(sizeof(int) * ancillaryBufferCount);
- }
- unsigned int ancillaryBufferCount;
-
- QByteArray address;
-
- int closingTimer;
-
- virtual void timerEvent(QTimerEvent *)
- {
- me->abort();
- killTimer(closingTimer);
- closingTimer = 0;
- }
-signals:
- void readyRead();
- void bytesWritten(qint64);
-
-public slots:
- void readActivated();
- qint64 writeActivated();
-};
-
-/*!
- Construct a QUnixSocket instance, with \a parent.
-
- The read buffer is initially set to 1024 bytes, and the rights buffer to 0
- entries.
-
- \sa QUnixSocket::readBufferSize() QUnixSocket::rightsBufferSize()
- */
-QUnixSocket::QUnixSocket(QObject * parent)
-: QIODevice(parent), d(new QUnixSocketPrivate(this))
-{
- setOpenMode(QIODevice::NotOpen);
- setReadBufferSize(QUNIXSOCKET_DEFAULT_READBUFFER);
- setRightsBufferSize(QUNIXSOCKET_DEFAULT_ANCILLARYBUFFER);
-}
-
-/*!
- Construct a QUnixSocket instance, with \a parent.
-
- The read buffer is initially set to \a readBufferSize bytes, and the rights
- buffer to \a rightsBufferSize entries.
-
- \sa QUnixSocket::readBufferSize() QUnixSocket::rightsBufferSize()
- */
-QUnixSocket::QUnixSocket(qint64 readBufferSize, qint64 rightsBufferSize,
- QObject * parent)
-: QIODevice(parent), d(new QUnixSocketPrivate(this))
-{
- Q_ASSERT(readBufferSize > 0 && rightsBufferSize >= 0);
-
- setOpenMode(QIODevice::NotOpen);
- setReadBufferSize(readBufferSize);
- setRightsBufferSize(rightsBufferSize);
-}
-
-/*!
- Destroys the QUnixSocket instance. Any unsent data is discarded.
- */
-QUnixSocket::~QUnixSocket()
-{
- abort();
- delete d;
-}
-
-/*!
- Attempt to connect to \a path.
-
- This method is synchronous and will return true if the connection succeeds and
- false otherwise. In the case of failure, \l QUnixSocket::error() will be set
- accordingly.
-
- Any existing connection will be aborted, and all pending data will be
- discarded.
-
- \sa QUnixSocket::close() QUnixSocket::abort() QUnixSocket::error()
- */
-bool QUnixSocket::connect(const QByteArray & path)
-{
- int _true;
- int crv;
-#ifdef QUNIXSOCKET_DEBUG
- qDebug() << "QUnixSocket: Connect requested to '"
- << path << '\'';
-#endif
-
- abort(); // Reset any existing connection
-
- if(UnconnectedState != d->state) // abort() caused a signal and someone messed
- // with us. We'll assume they know what
- // they're doing and bail. Alternative is to
- // have a special "Connecting" state
- return false;
-
-
- if(path.isEmpty() || path.size() > UNIX_PATH_MAX) {
- d->error = InvalidPath;
- return false;
- }
-
- // Create the socket
- d->fd = ::socket(PF_UNIX, SOCK_STREAM, 0);
- if(-1 == d->fd) {
-#ifdef QUNIXSOCKET_DEBUG
- qDebug() << "QUnixSocket: Unable to create socket ("
- << strerror(errno) << ')';
-#endif
- d->error = ResourceError;
- goto connect_error;
- }
-
- // Set socket options
- _true = 1;
- crv = ::setsockopt(d->fd, SOL_SOCKET, SO_PASSCRED, (void *)&_true,
- sizeof(int));
- if(-1 == crv) {
-#ifdef QUNIXSOCKET_DEBUG
- qDebug() << "QUnixSocket: Unable to configure socket ("
- << ::strerror(errno) << ')';
-#endif
- d->error = ResourceError;
-
- goto connect_error;
- }
-
- // Construct our unix address
- struct ::sockaddr_un addr;
- addr.sun_family = AF_UNIX;
- ::memcpy(addr.sun_path, path.data(), path.size());
- if(path.size() < UNIX_PATH_MAX)
- addr.sun_path[path.size()] = '\0';
-
- // Attempt the connect
- crv = ::connect(d->fd, (sockaddr *)&addr, sizeof(sockaddr_un));
- if(-1 == crv) {
-#ifdef QUNIXSOCKET_DEBUG
- qDebug() << "QUnixSocket: Unable to connect ("
- << ::strerror(errno) << ')';
-#endif
- if(ECONNREFUSED == errno)
- d->error = ConnectionRefused;
- else if(ENOENT == errno)
- d->error = NonexistentPath;
- else
- d->error = UnknownError;
-
- goto connect_error;
- }
-
- // We're connected!
- d->address = path;
- d->state = ConnectedState;
- d->readNotifier = new QSocketNotifier(d->fd, QSocketNotifier::Read, d);
- d->writeNotifier = new QSocketNotifier(d->fd, QSocketNotifier::Write, d);
- QObject::connect(d->readNotifier, SIGNAL(activated(int)),
- d, SLOT(readActivated()));
- QObject::connect(d->writeNotifier, SIGNAL(activated(int)),
- d, SLOT(writeActivated()));
- d->readNotifier->setEnabled(true);
- d->writeNotifier->setEnabled(false);
- setOpenMode(QIODevice::ReadWrite);
- emit stateChanged(ConnectedState);
-
-#ifdef QUNIXSOCKET_DEBUG
- qDebug() << "QUnixSocket: Connected to " << path;
-#endif
- return true;
-
-connect_error: // Cleanup failed connection
- if(-1 != d->fd) {
-#ifdef QUNIXSOCKET_DEBUG
- int closerv =
-#endif
- QT_CLOSE(d->fd);
-#ifdef QUNIXSOCKET_DEBUG
- if(0 != closerv) {
- qDebug() << "QUnixSocket: Unable to close file descriptor after "
- "failed connect (" << ::strerror(errno) << ')';
- }
-#endif
- }
- d->fd = -1;
- return false;
-}
-
-/*!
- Sets the socket descriptor to use to \a socketDescriptor, bypassing
- QUnixSocket's connection infrastructure, and return true on success and false
- on failure. \a socketDescriptor must be in the connected state, and must be
- a Unix domain socket descriptor. Following a successful call to this method,
- the QUnixSocket instance will be in the Connected state and will have assumed
- ownership of \a socketDescriptor.
-
- Any existing connection will be aborted, and all pending data will be
- discarded.
-
- \sa QUnixSocket::connect()
-*/
-bool QUnixSocket::setSocketDescriptor(int socketDescriptor)
-{
- abort();
-
- if(UnconnectedState != state()) // See QUnixSocket::connect()
- return false;
-
- // Attempt to set the socket options
- if(-1 == socketDescriptor) {
-#ifdef QUNIXSOCKET_DEBUG
- qDebug() << "QUnixSocket: User provided socket is invalid";
-#endif
- d->error = ResourceError;
- return false;
- }
-
- // Set socket options
- int _true = 1;
- int crv = ::setsockopt(socketDescriptor, SOL_SOCKET,
- SO_PASSCRED, (void *)&_true, sizeof(int));
- if(-1 == crv) {
-#ifdef QUNIXSOCKET_DEBUG
- qDebug() << "QUnixSocket: Unable to configure client provided socket ("
- << ::strerror(errno) << ')';
-#endif
- d->error = ResourceError;
-
- return false;
- }
-
- d->fd = socketDescriptor;
- d->state = ConnectedState;
- d->address = QByteArray();
- setOpenMode(QIODevice::ReadWrite);
- d->readNotifier = new QSocketNotifier(d->fd, QSocketNotifier::Read, d);
- d->writeNotifier = new QSocketNotifier(d->fd, QSocketNotifier::Write, d);
- QObject::connect(d->readNotifier, SIGNAL(activated(int)),
- d, SLOT(readActivated()));
- QObject::connect(d->writeNotifier, SIGNAL(activated(int)),
- d, SLOT(writeActivated()));
- d->readNotifier->setEnabled(true);
- d->writeNotifier->setEnabled(false);
- emit stateChanged(d->state);
-
- return true;
-}
-
-/*!
- Returns the socket descriptor currently in use. This method will return -1
- if the QUnixSocket instance is in the UnconnectedState \l {QUnixSocket::state()}{state. }
-
- \sa QUnixSocket::setSocketDescriptor()
- */
-int QUnixSocket::socketDescriptor() const
-{
- return d->fd;
-}
-
-/*!
- Abort the connection. This will immediately disconnect (if connected) and
- discard any pending data. Following a call to QUnixSocket::abort() the
- object will always be in the disconnected \link QUnixSocket::state() state.
- \endlink
-
- \sa QUnixSocket::close()
-*/
-void QUnixSocket::abort()
-{
- setOpenMode(QIODevice::NotOpen);
-
- // We want to be able to use QUnixSocket::abort() to cleanup our state but
- // also preserve the error message that caused the abort. It is not
- // possible to reorder code to do this:
- // abort();
- // d->error = SomeError
- // as QUnixSocket::abort() might emit a signal and we need the error to be
- // set within that signal. So, if we want an error message to be preserved
- // across a *single* call to abort(), we set the
- // QUnixSocketPrivate::CausedAbort flag in the error.
- if(d->error & QUnixSocketPrivate::CausedAbort)
- d->error = (QUnixSocket::SocketError)(d->error &
- ~QUnixSocketPrivate::CausedAbort);
- else
- d->error = NoError;
-
- if( UnconnectedState == d->state) return;
-
-#ifdef QUNIXSOCKET_DEBUG
- int closerv =
-#endif
- ::close(d->fd);
-#ifdef QUNIXSOCKET_DEBUG
- if(0 != closerv) {
- qDebug() << "QUnixSocket: Unable to close socket during abort ("
- << strerror(errno) << ')';
- }
-#endif
-
- // Reset variables
- d->fd = -1;
- d->state = UnconnectedState;
- d->dataBufferLength = 0;
- d->flushAncillary();
- d->address = QByteArray();
- if(d->readNotifier) {
- d->readNotifier->setEnabled(false);
- d->readNotifier->deleteLater();
- }
- if(d->writeNotifier) {
- d->writeNotifier->setEnabled(false);
- d->writeNotifier->deleteLater();
- }
- d->readNotifier = 0;
- d->writeNotifier = 0;
- d->writeQueue.clear();
- d->writeQueueBytes = 0;
- if(d->closingTimer) {
- d->killTimer(d->closingTimer);
- }
- d->closingTimer = 0;
- emit stateChanged(d->state);
-}
-
-/*!
- Close the connection. The instance will enter the Closing
- \l {QUnixSocket::state()}{state } until all pending data has been
- transmitted, at which point it will enter the Unconnected state.
-
- Even if there is no pending data for transmission, the object will never
- jump directly to Disconnect without first passing through the
- Closing state.
-
- \sa QUnixSocket::abort()
- */
-void QUnixSocket::close()
-{
- if(ConnectedState != state()) return;
-
- d->state = ClosingState;
- if(d->writeQueue.isEmpty()) {
- d->closingTimer = d->startTimer(0); // Start a timer to "fake"
- // completing writes
- }
- emit stateChanged(d->state);
-}
-
-/*!
- This function writes as much as possible from the internal write buffer to
- the underlying socket, without blocking. If any data was written, this
- function returns true; otherwise false is returned.
-*/
-// Note! docs partially copied from QAbstractSocket::flush()
-bool QUnixSocket::flush()
-{
- // This needs to have the same semantics as QAbstractSocket, if it is to
- // be used interchangeably with that class.
- if (d->writeQueue.isEmpty())
- return false;
-
- d->writeActivated();
- return true;
-}
-
-/*!
- Returns the last error to have occurred on this object. This method is not
- destructive, so multiple calls to QUnixSocket::error() will return the same
- value. The error is only reset by a call to \l QUnixSocket::connect() or
- \l QUnixSocket::abort()
- */
-QUnixSocket::SocketError QUnixSocket::error() const
-{
- return (QUnixSocket::SocketError)
- (d->error & ~QUnixSocketPrivate::CausedAbort);
-}
-
-/*!
- Returns the connection state of this instance.
- */
-QUnixSocket::SocketState QUnixSocket::state() const
-{
- return d->state;
-}
-
-/*!
- Returns the Unix path address passed to \l QUnixSocket::connect(). This
- method will return an empty path if the object is in the Unconnected
- \l {QUnixSocket::state()}{state } or was connected through a call
- to \l QUnixSocket::setSocketDescriptor()
-
- \sa QUnixSocket::connect() QUnixSocket::setSocketDescriptor()
- */
-QByteArray QUnixSocket::address() const
-{
- return d->address;
-}
-
-/*!
- Returns the number of bytes available for immediate retrieval through a call
- to \l QUnixSocket::read().
- */
-qint64 QUnixSocket::bytesAvailable() const
-{
- return QIODevice::bytesAvailable() + d->dataBufferLength;
-}
-
-/*!
- Returns the number of enqueued bytes still to be written to the socket.
- */
-qint64 QUnixSocket::bytesToWrite() const
-{
- return d->writeQueueBytes;
-}
-
-/*!
- Returns the size of the read buffer in bytes. The read buffer size
- determines the amount of byte data that can be read from the socket in one go.
- The read buffer size caps the maximum value that can be returned by
- \l QUnixSocket::bytesAvailable() and will always be greater than zero. By
- default, the read buffer size is 1024 bytes.
-
- The size of the read buffer is independent of the rights buffer, which can be
- queried by \l QUnixSocket::rightsBufferSize().
-
- \sa QUnixSocket::setReadBufferSize()
- */
-qint64 QUnixSocket::readBufferSize() const
-{
- return d->dataBufferCapacity;
-}
-
-/*!
- Sets the \a size of the socket's read buffer in bytes.
-
- The size of the read buffer is independent of the rights buffer, which can be
- set by \l QUnixSocket::setRightsBufferSize().
-
- Attempting to reduce the buffer size while bytes are available for reading
- (ie. while the buffer is in use) will fail.
-
- \sa QUnixSocket::readBufferSize()
- */
-void QUnixSocket::setReadBufferSize(qint64 size)
-{
- Q_ASSERT(size > 0);
- if(size == d->dataBufferCapacity || d->dataBufferLength) return;
- if(d->dataBuffer) delete [] d->dataBuffer;
- d->dataBuffer = new char[size];
- d->dataBufferCapacity = size;
-}
-
-/*!
- Returns the size of the rights buffer in rights entries. The rights buffer
- size determines the number of rights transferences that can be received in
- any message. Unlike byte stream data which can be fragmented into many
- smaller messages if the \link QUnixSocket::readBufferSize() read buffer
- \endlink is not large enough to contain all the available data, rights data
- is transmitted as unfragmentable datagrams. If the rights buffer is not
- large enough to contain this unfragmentable datagram, the datagram will be
- truncated and rights data irretrievably lost. If truncation occurs, the
- \l QUnixSocketMessage::rightsWereTruncated() flag will be set. By default
- the rights buffer size is 0 entries - rights data cannot be received.
-
- The size of the rights buffer is independent of the read buffer, which can be
- queried by \l QUnixSocket::readBufferSize().
-
- \sa QUnixSocket::setRightsBufferSize()
- */
-qint64 QUnixSocket::rightsBufferSize() const
-{
- return d->ancillaryBufferCount;
-}
-
-/*!
- Sets the \a size of the socket's rights buffer in rights entries.
-
- The size of the rights buffer is independent of the read buffer, which can be
- set by \l QUnixSocket::setReadBufferSize().
-
- Attempting to reduce the buffer size while bytes are available for reading
- (ie. while the buffer is in use) will fail.
-
- \sa QUnixSocket::rightsBufferSize()
- */
-void QUnixSocket::setRightsBufferSize(qint64 size)
-{
- Q_ASSERT(size >= 0);
-
- if((size == d->ancillaryBufferCount || d->dataBufferLength) &&
- d->ancillaryBuffer)
- return;
-
- qint64 byteSize = CMSG_SPACE(sizeof(::ucred)) +
- CMSG_SPACE(size * sizeof(int));
-
- if(d->ancillaryBuffer) delete [] d->ancillaryBuffer;
- d->ancillaryBuffer = new char[byteSize];
- d->ancillaryBufferCount = size;
-}
-
-/*!
- \overload
-
- Writes \a socketdata to the socket. In addition to failing if the socket
- is not in the Connected state, writing will fail if \a socketdata is
- \l {QUnixSocketMessage::isValid()}{invalid. }
-
- Writes through the QUnixSocket class are asynchronous. Rather than being
- written immediately, data is enqueued and written once the application
- reenters the Qt event loop and the socket becomes available for writing.
- Thus, this method will only fail if the socket is not in the Connected state
- - it is illegal to attempt a write on a Unconnected or Closing socket.
-
- Applications can monitor the progress of data writes through the
- \l QUnixSocket::bytesWritten() signal and \l QUnixSocket::bytesToWrite()
- method.
-
- \sa QUnixSocketMessage
- */
-qint64 QUnixSocket::write(const QUnixSocketMessage & socketdata)
-{
- if(ConnectedState != state() || !socketdata.isValid()) return -1;
- if(socketdata.d->size() == 0) return 0;
-
- d->writeQueue.enqueue(socketdata);
- d->writeQueueBytes += socketdata.d->size();
- d->writeNotifier->setEnabled(true);
-
- return socketdata.d->size();
-}
-
-/*!
- Return the next available message, or an empty message if none is available.
-
- To avoid retrieving empty messages, applications should connect to the
- \l QUnixSocket::readyRead() signal to be notified when new messages are
- available or periodically poll the \l QUnixSocket::bytesAvailable() method.
-
- \sa QUnixSocket::readyRead() QUnixSocket::bytesAvailable()
- */
-QUnixSocketMessage QUnixSocket::read()
-{
- QUnixSocketMessage data;
- if(!d->dataBufferLength)
- return data;
-
- data.d->state = QUnixSocketMessagePrivate::Credential;
-
- // Bytes are easy
- data.setBytes(QByteArray(d->dataBuffer, d->dataBufferLength));
-
- // Extract ancillary data
- QList<QUnixSocketRights> a;
-
- ::cmsghdr * h = (::cmsghdr *)CMSG_FIRSTHDR(&(d->message));
- while(h) {
-
- if(SCM_CREDENTIALS == h->cmsg_type) {
- ::ucred * cred = (::ucred *)CMSG_DATA(h);
-#ifdef QUNIXSOCKET_DEBUG
- qDebug( "Credentials recd: pid %lu - gid %lu - uid %lu",
- cred->pid, cred->gid, cred->uid );
-#endif
- data.d->pid = cred->pid;
- data.d->gid = cred->gid;
- data.d->uid = cred->uid;
-
- } else if(SCM_RIGHTS == h->cmsg_type) {
-
- int * fds = (int *)CMSG_DATA(h);
- int numFds = (h->cmsg_len - CMSG_LEN(0)) / sizeof(int);
-
- for(int ii = 0; ii < numFds; ++ii) {
- QUnixSocketRights qusr(fds[ii], 0);
- a.append(qusr);
- }
-
- } else {
-
-#ifdef QUNIXSOCKET_DEBUG
- qFatal("QUnixSocket: Unknown ancillary data type (%d) received.",
- h->cmsg_type);
-#endif
-
- }
-
- h = (::cmsghdr *)CMSG_NXTHDR(&(d->message), h);
- }
-
- if(d->message.msg_flags & MSG_CTRUNC) {
- data.d->state = (QUnixSocketMessagePrivate::AncillaryDataState)(QUnixSocketMessagePrivate::Truncated |
- QUnixSocketMessagePrivate::Credential );
- }
-
- if(!a.isEmpty())
- data.d->rights = a;
-
- d->dataBufferLength = 0;
- d->messageValid = false;
- d->readNotifier->setEnabled(true);
-
- return data;
-}
-
-/*! \internal */
-bool QUnixSocket::isSequential() const
-{
- return true;
-}
-
-/*! \internal */
-bool QUnixSocket::waitForReadyRead(int msecs)
-{
- if(UnconnectedState == d->state)
- return false;
-
- if(d->messageValid) {
- return true;
- }
-
- Q_ASSERT(-1 != d->fd);
-
- int timeout = msecs;
- struct timeval tv;
- struct timeval *ptrTv = 0;
- QTime stopWatch;
-
- stopWatch.start();
-
- do
- {
- fd_set readset;
-
- FD_ZERO(&readset);
- FD_SET(d->fd, &readset);
-
- if(-1 != msecs) {
- tv.tv_sec = timeout / 1000;
- tv.tv_usec = (timeout % 1000) * 1000;
- ptrTv = &tv;
- }
-
- int rv = ::select(d->fd + 1, &readset, 0, 0, ptrTv);
- switch(rv) {
- case 0:
- // timeout
- return false;
- case 1:
- // ok
- d->readActivated();
- return true;
- default:
- if (errno != EINTR)
- abort(); // error
- break;
- }
-
- timeout = msecs - stopWatch.elapsed();
- }
- while (timeout > 0);
-
- return false;
-}
-
-bool QUnixSocket::waitForBytesWritten(int msecs)
-{
- if(UnconnectedState == d->state)
- return false;
-
- Q_ASSERT(-1 != d->fd);
-
- if ( d->writeQueue.isEmpty() )
- return true;
-
- QTime stopWatch;
- stopWatch.start();
-
- while ( true )
- {
- fd_set fdwrite;
- FD_ZERO(&fdwrite);
- FD_SET(d->fd, &fdwrite);
- int timeout = msecs < 0 ? 0 : msecs - stopWatch.elapsed();
- struct timeval tv;
- struct timeval *ptrTv = 0;
- if ( -1 != msecs )
- {
- tv.tv_sec = timeout / 1000;
- tv.tv_usec = (timeout % 1000) * 1000;
- ptrTv = &tv;
- }
-
- int rv = ::select(d->fd + 1, 0, &fdwrite, 0, ptrTv);
- switch ( rv )
- {
- case 0:
- // timeout
- return false;
- case 1:
- {
- // ok to write
- qint64 bytesWritten = d->writeActivated();
- if (bytesWritten == 0) {
- // We need to retry
- int delay = 1;
- do {
- if (-1 != msecs) {
- timeout = msecs - stopWatch.elapsed();
- if (timeout <= 0) {
- // We have exceeded our allotted time
- return false;
- } else {
- if (delay > timeout)
- delay = timeout;
- }
- }
-
- // Pause before we make another attempt to send
- ::usleep(delay * 1000);
- if (delay < 1024)
- delay *= 2;
-
- bytesWritten = d->writeActivated();
- } while (bytesWritten == 0);
- }
- return (bytesWritten != -1);
- }
- default:
- // error - or an uncaught signal!!!!!!!!!
- if ( rv == EINTR )
- continue;
- abort();
- return false;
- }
- }
- return false; // fix warnings
-}
-
-/*! \internal */
-bool QUnixSocket::canReadLine() const
-{
- for(unsigned int ii = 0; ii < d->dataBufferLength; ++ii)
- if(d->dataBuffer[ii] == '\n') return true;
- return false;
-}
-
-/*! \internal */
-qint64 QUnixSocket::readData(char * data, qint64 maxSize)
-{
- Q_ASSERT(data);
- if(0 >= maxSize) return 0;
- if(!d->dataBufferLength) return 0;
-
- // Read data
- unsigned int size = d->dataBufferLength>maxSize?maxSize:d->dataBufferLength;
- memcpy(data, d->dataBuffer, size);
- if(size == d->dataBufferLength) {
- d->dataBufferLength = 0;
- } else {
- memmove(d->dataBuffer, d->dataBuffer + size, d->dataBufferLength - size);
- d->dataBufferLength -= size;
- }
-
-
- // Flush ancillary
- d->flushAncillary();
-
- if(0 == d->dataBufferLength)
- d->readNotifier->setEnabled(true);
-
- return size;
-}
-
-/*! \internal */
-qint64 QUnixSocket::writeData (const char * data, qint64 maxSize)
-{
- return write(QUnixSocketMessage(QByteArray(data, maxSize)));
-}
-
-qint64 QUnixSocketPrivate::writeActivated()
-{
- writeNotifier->setEnabled(false);
-
- QUnixSocketMessage & m = writeQueue.head();
- const QList<QUnixSocketRights> & a = m.rights();
-
- //
- // Construct the message
- //
- ::iovec vec;
- if ( !m.d->vec ) // message does not already have an iovec
- {
- vec.iov_base = (void *)m.bytes().constData();
- vec.iov_len = m.bytes().size();
- }
-
- // Allocate the control buffer
- ::msghdr sendmessage;
- ::bzero(&sendmessage, sizeof(::msghdr));
- if ( m.d->vec )
- {
- sendmessage.msg_iov = m.d->vec;
- sendmessage.msg_iovlen = m.d->iovecLen;
- }
- else
- {
- sendmessage.msg_iov = &vec;
- sendmessage.msg_iovlen = 1;
- }
- unsigned int required = CMSG_SPACE(sizeof(::ucred)) +
- a.size() * CMSG_SPACE(sizeof(int));
- sendmessage.msg_control = new char[required];
- ::bzero(sendmessage.msg_control, required);
- sendmessage.msg_controllen = required;
-
- // Create ancillary buffer
- ::cmsghdr * h = CMSG_FIRSTHDR(&sendmessage);
-
- if(m.d->state & QUnixSocketMessagePrivate::Credential) {
- h->cmsg_len = CMSG_LEN(sizeof(::ucred));
- h->cmsg_level = SOL_SOCKET;
- h->cmsg_type = SCM_CREDENTIALS;
- ((::ucred *)CMSG_DATA(h))->pid = m.d->pid;
- ((::ucred *)CMSG_DATA(h))->gid = m.d->gid;
- ((::ucred *)CMSG_DATA(h))->uid = m.d->uid;
- h = CMSG_NXTHDR(&sendmessage, h);
- } else {
- sendmessage.msg_controllen -= CMSG_SPACE(sizeof(::ucred));
- }
-
- for(int ii = 0; ii < a.count(); ++ii) {
- const QUnixSocketRights & r = a.at(ii);
-
- if(r.isValid()) {
- h->cmsg_len = CMSG_LEN(sizeof(int));
- h->cmsg_level = SOL_SOCKET;
- h->cmsg_type = SCM_RIGHTS;
- *((int *)CMSG_DATA(h)) = r.peekFd();
- h = CMSG_NXTHDR(&sendmessage, h);
- } else {
- sendmessage.msg_controllen -= CMSG_SPACE(sizeof(int));
- }
- }
-
-#ifdef QUNIXSOCKET_DEBUG
- qDebug() << "QUnixSocket: Transmitting message (length" << m.d->size() << ')';
-#endif
- ::ssize_t s = ::sendmsg(fd, &sendmessage, MSG_DONTWAIT | MSG_NOSIGNAL);
-#ifdef QUNIXSOCKET_DEBUG
- qDebug() << "QUnixSocket: Transmitted message (" << s << ')';
-#endif
-
- if(-1 == s) {
- if(EAGAIN == errno || EWOULDBLOCK == errno || EINTR == errno) {
- writeNotifier->setEnabled(true);
- } else if(EPIPE == errno) {
-#ifdef QUNIXSOCKET_DEBUG
- qDebug() << "QUnixSocket: Remote side disconnected during transmit "
- "(" << ::strerror(errno) << ')';
-#endif
- me->abort();
- } else {
-#ifdef QUNIXSOCKET_DEBUG
- qDebug() << "QUnixSocket: Unable to transmit data ("
- << ::strerror(errno) << ')';
-#endif
- error = (QUnixSocket::SocketError)(QUnixSocket::WriteFailure |
- CausedAbort);
- me->abort();
- }
- } else if(s != m.d->size()) {
-
- // A partial transmission
- writeNotifier->setEnabled(true);
- delete [] (char *)sendmessage.msg_control;
- m.d->rights = QList<QUnixSocketRights>();
- m.d->removeBytes( s );
- writeQueueBytes -= s;
- emit bytesWritten(s);
- return s;
-
- } else {
-
- // Success!
- writeQueue.dequeue();
- Q_ASSERT(writeQueueBytes >= (unsigned)s);
- writeQueueBytes -= s;
- emit bytesWritten(s);
-
- }
-
- delete [] (char *)sendmessage.msg_control;
- if(-1 != s && !writeQueue.isEmpty())
- return writeActivated();
- else if(QUnixSocket::ClosingState == me->state() && writeQueue.isEmpty())
- me->abort();
-
- if((-1 == s) && (EAGAIN == errno || EWOULDBLOCK == errno || EINTR == errno))
- // Return zero bytes written to indicate retry may be required
- return 0;
- else
- return s;
-}
-
-void QUnixSocketPrivate::readActivated()
-{
-#ifdef QUNIXSOCKET_DEBUG
- qDebug() << "QUnixSocket: readActivated";
-#endif
- readNotifier->setEnabled(false);
-
- ::iovec vec;
- vec.iov_base = dataBuffer;
- vec.iov_len = dataBufferCapacity;
-
- bzero(&message, sizeof(::msghdr));
- message.msg_iov = &vec;
- message.msg_iovlen = 1;
- message.msg_controllen = ancillaryBufferCapacity();
- message.msg_control = ancillaryBuffer;
-
- int flags = 0;
-#ifdef MSG_CMSG_CLOEXEC
- flags = MSG_CMSG_CLOEXEC;
-#endif
-
- int recvrv = ::recvmsg(fd, &message, flags);
-#ifdef QUNIXSOCKET_DEBUG
- qDebug() << "QUnixSocket: Received message (" << recvrv << ')';
-#endif
- if(-1 == recvrv) {
-#ifdef QUNIXSOCKET_DEBUG
- qDebug() << "QUnixSocket: Unable to receive data ("
- << ::strerror(errno) << ')';
-#endif
- error = (QUnixSocket::SocketError)(QUnixSocket::ReadFailure |
- CausedAbort);
- me->abort();
- } else if(0 == recvrv) {
- me->abort();
- } else {
- Q_ASSERT(recvrv);
- Q_ASSERT((unsigned)recvrv <= dataBufferCapacity);
- dataBufferLength = recvrv;
- messageValid = true;
-
-#ifdef QUNIXSOCKET_DEBUG
- qDebug() << "QUnixSocket: readyRead() " << dataBufferLength;
-#endif
- emit readyRead();
- }
-}
-
-QT_END_NAMESPACE
-
-#include "qunixsocket.moc"
diff --git a/src/gui/embedded/qunixsocket_p.h b/src/gui/embedded/qunixsocket_p.h
deleted file mode 100644
index 12b2187b30..0000000000
--- a/src/gui/embedded/qunixsocket_p.h
+++ /dev/null
@@ -1,202 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QUNIXSOCKET_P_H
-#define QUNIXSOCKET_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtNetwork/qabstractsocket.h>
-#include <QtCore/qiodevice.h>
-#include <QtCore/qlist.h>
-#include <QtCore/qshareddata.h>
-
-extern "C" {
-#include <sys/types.h>
-};
-
-QT_BEGIN_NAMESPACE
-
-class QUnixSocketRights;
-class QUnixSocketRightsPrivate;
-class QUnixSocketPrivate;
-class QUnixSocketMessagePrivate;
-struct iovec;
-
-class Q_GUI_EXPORT QUnixSocketRights {
-public:
- QUnixSocketRights(int);
- ~QUnixSocketRights();
-
- QUnixSocketRights(const QUnixSocketRights &);
- QUnixSocketRights & operator=(const QUnixSocketRights &);
-
- bool isValid() const;
-
- int dupFd() const;
- int peekFd() const;
-
-private:
- friend class QUnixSocket;
- QUnixSocketRights(int,int);
- QSharedDataPointer<QUnixSocketRightsPrivate> d;
-};
-
-class Q_GUI_EXPORT QUnixSocketMessage {
-public:
- QUnixSocketMessage();
- QUnixSocketMessage(const QByteArray &);
- QUnixSocketMessage(const QByteArray &, const QList<QUnixSocketRights> &);
- QUnixSocketMessage(const QUnixSocketMessage &);
- QUnixSocketMessage(const iovec*, int);
- QUnixSocketMessage & operator=(const QUnixSocketMessage &);
- ~QUnixSocketMessage();
-
- void setBytes(const QByteArray &);
- void setRights(const QList<QUnixSocketRights> &);
-
- const QList<QUnixSocketRights> & rights() const;
- bool rightsWereTruncated() const;
-
- const QByteArray & bytes() const;
-
- pid_t processId() const;
- uid_t userId() const;
- gid_t groupId() const;
-
- void setProcessId(pid_t);
- void setUserId(uid_t);
- void setGroupId(gid_t);
-
- bool isValid() const;
-private:
- friend class QUnixSocket;
- friend class QUnixSocketPrivate;
- QSharedDataPointer<QUnixSocketMessagePrivate> d;
-};
-
-class Q_GUI_EXPORT QUnixSocket : public QIODevice
-{
- Q_OBJECT
-public:
- QUnixSocket(QObject * = 0);
- QUnixSocket(qint64, qint64, QObject * = 0);
- virtual ~QUnixSocket();
-
- enum SocketState {
- UnconnectedState = QAbstractSocket::UnconnectedState,
- HostLookupState = QAbstractSocket::HostLookupState,
- ConnectingState = QAbstractSocket::ConnectingState,
- ConnectedState = QAbstractSocket::ConnectedState,
- BoundState = QAbstractSocket::BoundState,
- ClosingState = QAbstractSocket::ClosingState,
- ListeningState = QAbstractSocket::ListeningState,
- };
-
- enum SocketError { NoError, InvalidPath, ResourceError,
- NonexistentPath, ConnectionRefused, UnknownError,
- ReadFailure, WriteFailure };
-
- bool connect(const QByteArray & path);
- bool setSocketDescriptor(int socketDescriptor);
- int socketDescriptor() const;
- void abort();
- void close();
-
- bool flush();
-
- SocketError error() const;
-
- SocketState state() const;
- QByteArray address() const;
-
- qint64 bytesAvailable() const;
- qint64 bytesToWrite() const;
-
- qint64 readBufferSize() const;
- void setReadBufferSize(qint64 size);
- qint64 rightsBufferSize() const;
- void setRightsBufferSize(qint64 size);
-
- bool canReadLine() const;
-
- qint64 write(const char * data, qint64 maxSize)
- { return QIODevice::write(data, maxSize); }
- qint64 write(const QByteArray & byteArray)
- { return QIODevice::write(byteArray); }
- qint64 read(char * data, qint64 maxSize)
- { return QIODevice::read(data, maxSize); }
- QByteArray read(qint64 maxSize)
- { return QIODevice::read(maxSize); }
-
- qint64 write(const QUnixSocketMessage &);
- QUnixSocketMessage read();
-
- virtual bool isSequential() const;
- virtual bool waitForReadyRead(int msec = 300);
- virtual bool waitForBytesWritten(int msec = 300);
-
-Q_SIGNALS:
- void stateChanged(SocketState socketState);
-
-protected:
- virtual qint64 readData(char * data, qint64 maxSize);
- virtual qint64 writeData (const char * data, qint64 maxSize);
-
-private:
- QUnixSocket(const QUnixSocket &);
- QUnixSocket & operator=(const QUnixSocket &);
-
- QUnixSocketPrivate * d;
-};
-
-QT_END_NAMESPACE
-
-#endif // QUNIXSOCKET_P_H
diff --git a/src/gui/embedded/qunixsocketserver.cpp b/src/gui/embedded/qunixsocketserver.cpp
deleted file mode 100644
index 32eeeab65b..0000000000
--- a/src/gui/embedded/qunixsocketserver.cpp
+++ /dev/null
@@ -1,376 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qunixsocketserver_p.h"
-
-// #define QUNIXSOCKETSERVER_DEBUG
-
-#ifdef QUNIXSOCKETSERVER_DEBUG
-#include <QDebug>
-#endif
-
-#include <QtCore/qsocketnotifier.h>
-
-extern "C" {
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <unistd.h>
-#include <errno.h>
-};
-
-#define UNIX_PATH_MAX 108 // From unix(7)
-
-QT_BEGIN_NAMESPACE
-
-class QUnixSocketServerPrivate : public QObject
-{
-Q_OBJECT
-public:
- QUnixSocketServerPrivate(QUnixSocketServer * parent)
- : QObject(), me(parent), fd(-1), maxConns(30),
- error(QUnixSocketServer::NoError), acceptNotifier(0)
- {}
-
- QUnixSocketServer * me;
- int fd;
- int maxConns;
- QByteArray address;
- QUnixSocketServer::ServerError error;
- QSocketNotifier * acceptNotifier;
-public slots:
- void acceptActivated();
-};
-
-/*!
- \class QUnixSocketServer
- \internal
-
- \brief The QUnixSocketServer class provides a Unix domain socket based server.
- \omit
- \ingroup Platform::DeviceSpecific
- \ingroup Platform::OS
- \ingroup Platform::Communications
- \endomit
- \ingroup qws
-
- This class makes it possible to accept incoming Unix domain socket
- connections. Call \l QUnixSocketServer::listen() to have the server listen
- for incoming connections on a specified path. The pure virtual
- \l QUnixSocketServer::incomingConnection() is called each time a new
- connection is established. Users must inherit from QUnixSocketServer and
- implement this method.
-
- If an error occurs, \l QUnixSocketServer::serverError() returns the type of
- error. Errors can only occur during server establishment - that is, during a
- call to \l QUnixSocketServer::listen(). Calling \l QUnixSocketServer::close()
- causes QUnixSocketServer to stop listening for connections and reset its
- state.
-
- QUnixSocketServer is often used in conjunction with the \l QUnixSocket class.
-
- \sa QUnixSocket
-*/
-
-/*!
- \enum QUnixSocketServer::ServerError
-
- The ServerError enumeration represents the errors that can occur during server
- establishment. The most recent error can be retrieved through a call to
- \l QUnixSocketServer::serverError().
-
- \value NoError No error has occurred.
- \value InvalidPath An invalid path endpoint was passed to
- \l QUnixSocketServer::listen(). As defined by unix(7), invalid paths
- include an empty path, or what more than 107 characters long.
- \value ResourceError An error acquiring or manipulating the system's socket
- resources occurred. For example, if the process runs out of available
- socket descriptors, a ResourceError will occur.
- \value BindError The server was unable to bind to the specified path.
- \value ListenError The server was unable to listen on the specified path for
- incoming connections.
- */
-
-/*!
- Create a new Unix socket server with the given \a parent.
- */
-QUnixSocketServer::QUnixSocketServer(QObject *parent)
-: QObject(parent), d(0)
-{
-}
-
-/*!
- Stops listening for incoming connection and destroys the Unix socket server.
- */
-QUnixSocketServer::~QUnixSocketServer()
-{
- close();
- if(d)
- delete d;
-}
-
-/*!
- Stop listening for incoming connections and resets the Unix socket server's
- state. Calling this method while \l {QUnixSocketServer::isListening()}{not listening } for incoming connections is a no-op.
-
- \sa QUnixSocketServer::listen()
- */
-void QUnixSocketServer::close()
-{
- if(!d)
- return;
-
- if(d->acceptNotifier) {
- d->acceptNotifier->setEnabled(false);
- delete d->acceptNotifier;
- }
- d->acceptNotifier = 0;
-
- if(-1 != d->fd) {
-#ifdef QUNIXSOCKET_DEBUG
- int closerv =
-#endif
- ::close(d->fd);
-#ifdef QUNIXSOCKET_DEBUG
- if(0 != closerv) {
- qDebug() << "QUnixSocketServer: Unable to close socket ("
- << strerror(errno) << ')';
- }
-#endif
- }
- d->fd = -1;
- d->address = QByteArray();
- d->error = NoError;
-}
-
-/*!
- Returns the last server error. Errors may only occur within a call to
- \l QUnixSocketServer::listen(), and only when such a call fails.
-
- This method is not destructive, so multiple calls to
- QUnixSocketServer::serverError() will return the same value. The error is
- only reset by an explicit call to \l QUnixSocketServer::close() or
- by further calls to \l QUnixSocketServer::listen().
- */
-QUnixSocketServer::ServerError QUnixSocketServer::serverError() const
-{
- if(!d)
- return NoError;
-
- return d->error;
-}
-
-/*!
- Returns true if this server is listening for incoming connections, false
- otherwise.
-
- \sa QUnixSocketServer::listen()
- */
-bool QUnixSocketServer::isListening() const
-{
- if(!d)
- return false;
-
- return (-1 != d->fd);
-}
-
-/*!
- Tells the server to listen for incoming connections on \a path. Returns true
- if it successfully initializes, false otherwise. In the case of failure, the
- \l QUnixSocketServer::serverError() error status is set accordingly.
-
- Calling this method while the server is already running will result in the
- server begin reset, and then attempting to listen on \a path. This will not
- affect connections established prior to the server being reset, but further
- incoming connections on the previous path will be refused.
-
- The server can be explicitly reset by a call to \l QUnixSocketServer::close().
-
- \sa QUnixSocketServer::close()
- */
-bool QUnixSocketServer::listen(const QByteArray & path)
-{
- if(d) {
- close(); // Any existing server is destroyed
- } else {
- d = new QUnixSocketServerPrivate(this);
- }
-
- if(path.isEmpty() || path.size() > UNIX_PATH_MAX) {
- d->error = InvalidPath;
- return false;
- }
- unlink( path ); // ok if this fails
-
- // Create the socket
- d->fd = ::socket(PF_UNIX, SOCK_STREAM, 0);
- if(-1 == d->fd) {
-#ifdef QUNIXSOCKETSERVER_DEBUG
- qDebug() << "QUnixSocketServer: Unable to create socket ("
- << strerror(errno) << ')';
-#endif
- close();
- d->error = ResourceError;
- return false;
- }
-
- // Construct our unix address
- struct ::sockaddr_un addr;
- addr.sun_family = AF_UNIX;
- ::memcpy(addr.sun_path, path.data(), path.size());
- if(path.size() < UNIX_PATH_MAX)
- addr.sun_path[path.size()] = '\0';
-
- // Attempt to bind
- if(-1 == ::bind(d->fd, (sockaddr *)&addr, sizeof(sockaddr_un))) {
-#ifdef QUNIXSOCKETSERVER_DEBUG
- qDebug() << "QUnixSocketServer: Unable to bind socket ("
- << strerror(errno) << ')';
-#endif
- close();
- d->error = BindError;
- return false;
- }
-
- // Listen to socket
- if(-1 == ::listen(d->fd, d->maxConns)) {
-#ifdef QUNIXSOCKETSERVER_DEBUG
- qDebug() << "QUnixSocketServer: Unable to listen socket ("
- << strerror(errno) << ')';
-#endif
- close();
- d->error = ListenError;
- return false;
- }
-
- // Success!
- d->address = path;
- d->acceptNotifier = new QSocketNotifier(d->fd, QSocketNotifier::Read, d);
- d->acceptNotifier->setEnabled(true);
- QObject::connect(d->acceptNotifier, SIGNAL(activated(int)),
- d, SLOT(acceptActivated()));
-
- return true;
-}
-
-/*!
- Returns the Unix path on which this server is listening. If this server is
- not listening, and empty address will be returned.
- */
-QByteArray QUnixSocketServer::serverAddress() const
-{
- if(!d)
- return QByteArray();
- return d->address;
-}
-
-int QUnixSocketServer::socketDescriptor() const
-{
- if (!d)
- return -1;
- return d->fd;
-}
-
-
-/*!
- Returns the maximum length the queue of pending connections may grow to. That
- is, the maximum number of clients attempting to connect for which the Unix
- socket server has not yet accepted and passed to
- \l QUnixSocketServer::incomingConnection(). If a connection request arrives
- with the queue full, the client may receive a connection refused notification.
-
- By default a queue length of 30 is used.
-
- \sa QUnixSocketServer::setMaxPendingConnections()
- */
-int QUnixSocketServer::maxPendingConnections() const
-{
- if(!d)
- return 30;
-
- return d->maxConns;
-}
-
-/*!
- Sets the maximum length the queue of pending connections may grow to
- \a numConnections. This value will only apply to
- \l QUnixSocketServer::listen() calls made following the value change - it will
- not be retroactively applied.
-
- \sa QUnixSocketServer::maxPendingConnections()
- */
-void QUnixSocketServer::setMaxPendingConnections(int numConnections)
-{
- Q_ASSERT(numConnections >= 1);
- if(!d)
- d = new QUnixSocketServerPrivate(this);
-
- d->maxConns = numConnections;
-}
-
-/*!
- \fn void QUnixSocketServer::incomingConnection(int socketDescriptor)
-
- This method is invoked each time a new incoming connection is established with
- the server. Clients must reimplement this function in their QUnixSocketServer
- derived class to handle the connection.
-
- A common approach to handling the connection is to pass \a socketDescriptor to
- a QUnixSocket instance.
-
- \sa QUnixSocket
- */
-
-void QUnixSocketServerPrivate::acceptActivated()
-{
- ::sockaddr_un r;
- socklen_t len = sizeof(sockaddr_un);
- int connsock = ::accept(fd, (sockaddr *)&r, &len);
-#ifdef QUNIXSOCKETSERVER_DEBUG
- qDebug() << "QUnixSocketServer: Accept connection " << connsock;
-#endif
- if(-1 != connsock)
- me->incomingConnection(connsock);
-}
-
-QT_END_NAMESPACE
-
-#include "qunixsocketserver.moc"
diff --git a/src/gui/embedded/qunixsocketserver_p.h b/src/gui/embedded/qunixsocketserver_p.h
deleted file mode 100644
index f83297be25..0000000000
--- a/src/gui/embedded/qunixsocketserver_p.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QUNIXSOCKETSERVER_P_H
-#define QUNIXSOCKETSERVER_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/qobject.h>
-
-QT_BEGIN_NAMESPACE
-
-class QUnixSocketServerPrivate;
-class Q_GUI_EXPORT QUnixSocketServer : public QObject
-{
- Q_OBJECT
-public:
- enum ServerError { NoError, InvalidPath, ResourceError, BindError,
- ListenError };
-
- QUnixSocketServer(QObject *parent=0);
- virtual ~QUnixSocketServer();
-
- void close();
-
- ServerError serverError() const;
-
- bool isListening() const;
- bool listen(const QByteArray & path);
-
- int socketDescriptor() const;
- QByteArray serverAddress() const;
-
- int maxPendingConnections() const;
- void setMaxPendingConnections(int numConnections);
-
-protected:
- virtual void incomingConnection(int socketDescriptor) = 0;
-
-private:
- QUnixSocketServer(const QUnixSocketServer &);
- QUnixSocketServer & operator=(const QUnixSocketServer &);
-
- friend class QUnixSocketServerPrivate;
- QUnixSocketServerPrivate * d;
-};
-
-
-QT_END_NAMESPACE
-#endif // QUNIXSOCKETSERVER_P_H
-
diff --git a/src/gui/embedded/qvfbhdr.h b/src/gui/embedded/qvfbhdr.h
deleted file mode 100644
index eb954927a4..0000000000
--- a/src/gui/embedded/qvfbhdr.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QVFBHDR_H
-#define QVFBHDR_H
-
-#include <QtGui/qcolor.h>
-#include <QtGui/qwindowdefs.h>
-#include <QtCore/qrect.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_QWS_TEMP_DIR
-# define QT_QWS_TEMP_DIR QLatin1String("/tmp")
-#endif
-
-#ifdef QT_PRIVATE_QWS
-#define QT_VFB_DATADIR(DISPLAY) QString::fromLatin1("%1/qtembedded-%2-%3") \
- .arg(QT_QWS_TEMP_DIR).arg(getuid()).arg(DISPLAY)
-#define QT_VFB_MOUSE_PIPE(DISPLAY) QT_VFB_DATADIR(DISPLAY) \
- .append(QLatin1String("/qtvfb_mouse"))
-#define QT_VFB_KEYBOARD_PIPE(DISPLAY) QT_VFB_DATADIR(DISPLAY) \
- .append(QLatin1String("/qtvfb_keyboard"))
-#define QT_VFB_MAP(DISPLAY) QT_VFB_DATADIR(DISPLAY) \
- .append(QLatin1String("/qtvfb_map"))
-#define QT_VFB_SOUND_PIPE(DISPLAY) QT_VFB_DATADIR(DISPLAY) \
- .append(QLatin1String("/qt_soundserver"))
-#define QTE_PIPE(DISPLAY) QT_VFB_DATADIR(DISPLAY) \
- .append(QLatin1String("/QtEmbedded"))
-#define QTE_PIPE_QVFB(DISPLAY) QTE_PIPE(DISPLAY)
-#else
-#define QT_VFB_DATADIR(DISPLAY) QString::fromLatin1("%1/qtembedded-%2") \
- .arg(QT_QWS_TEMP_DIR).arg(DISPLAY)
-#define QT_VFB_MOUSE_PIPE(DISPLAY) QString::fromLatin1("%1/.qtvfb_mouse-%2") \
- .arg(QT_QWS_TEMP_DIR).arg(DISPLAY)
-#define QT_VFB_KEYBOARD_PIPE(DISPLAY) QString::fromLatin1("%1/.qtvfb_keyboard-%2") \
- .arg(QT_QWS_TEMP_DIR).arg(DISPLAY)
-#define QT_VFB_MAP(DISPLAY) QString::fromLatin1("%1/.qtvfb_map-%2") \
- .arg(QT_QWS_TEMP_DIR).arg(DISPLAY)
-#define QT_VFB_SOUND_PIPE(DISPLAY) QString::fromLatin1("%1/.qt_soundserver-%2") \
- .arg(QT_QWS_TEMP_DIR).arg(DISPLAY)
-#define QTE_PIPE(DISPLAY) QT_VFB_DATADIR(DISPLAY) \
- .append(QLatin1String("/QtEmbedded-%1")).arg(DISPLAY)
-#define QTE_PIPE_QVFB(DISPLAY) QTE_PIPE(DISPLAY)
-#endif
-
-struct QVFbHeader
-{
- int width;
- int height;
- int depth;
- int linestep;
- int dataoffset;
- QRect update;
- bool dirty;
- int numcols;
- QRgb clut[256];
- int viewerVersion;
- int serverVersion;
- int brightness; // since 4.4.0
- WId windowId; // since 4.5.0
-};
-
-struct QVFbKeyData
-{
- unsigned int keycode;
- Qt::KeyboardModifiers modifiers;
- unsigned short int unicode;
- bool press;
- bool repeat;
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QVFBHDR_H
diff --git a/src/gui/embedded/qwindowsystem_p.h b/src/gui/embedded/qwindowsystem_p.h
deleted file mode 100644
index 3a315bebcb..0000000000
--- a/src/gui/embedded/qwindowsystem_p.h
+++ /dev/null
@@ -1,315 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWINDOWSYSTEM_QWS_P_H
-#define QWINDOWSYSTEM_QWS_P_H
-
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of the QWSServer class. This header file may change from
-// version to version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "private/qobject_p.h"
-#include "qwindowsystem_qws.h"
-#include "qbrush.h"
-#include "qwsproperty_qws.h"
-#include "qwscommand_qws_p.h"
-#include "QtCore/qbasictimer.h"
-
-QT_BEGIN_NAMESPACE
-
-class QWSServerPrivate : public QObjectPrivate {
- friend class QCopChannel;
- friend class QWSMouseHandler;
- friend class QWSWindow;
- friend class QWSDisplay;
- friend class QWSInputMethod;
- Q_DECLARE_PUBLIC(QWSServer)
-
-public:
- QWSServerPrivate()
- : screensaverintervals(0)
- , screensavereventblocklevel(-1), screensaverblockevents(false)
- , saver(0), cursorClient(0), mouseState(0), nReserved(0)
- , doClientIsActive(false)
- {
- }
- ~QWSServerPrivate()
- {
- closeDisplay();
-
- qDeleteAll(deletedWindows);
- delete [] screensaverintervals;
- delete saver;
-
- qDeleteAll(windows);
- windows.clear();
-
- delete bgBrush;
- bgBrush = 0;
- }
- QTime screensavertime;
- QTimer* screensavertimer;
- int* screensaverintervals;
- int screensavereventblocklevel;
- bool screensaverblockevents;
- bool screensaverblockevent( int index, int *screensaverinterval, bool isDown );
- QWSScreenSaver* saver;
- QWSClient *cursorClient;
- int mouseState;
-// bool prevWin;
- QList<QWSWindow*> deletedWindows;
- QList<int> crashedClientIds;
-
- void update_regions();
-//private functions moved from class
-
-private:
- void initServer(int flags);
-#ifndef QT_NO_COP
- static void sendQCopEvent(QWSClient *c, const QString &ch,
- const QString &msg, const QByteArray &data,
- bool response = false);
-#endif
- void move_region(const QWSRegionMoveCommand *);
- void set_altitude(const QWSChangeAltitudeCommand *);
- void set_opacity(const QWSSetOpacityCommand *);
- void request_focus(const QWSRequestFocusCommand *);
- QRegion reserve_region(QWSWindow *window, const QRegion &region);
- void request_region(int winId, const QString &surfaceKey,
- const QByteArray &surfaceData,
- const QRegion &region);
- void repaint_region(int winId, int windowFlags, bool opaque, const QRegion &);
- void destroy_region(const QWSRegionDestroyCommand *);
- void name_region(const QWSRegionNameCommand *);
- void set_identity(const QWSIdentifyCommand *);
-#ifndef QT_NO_QWS_PROPERTIES
- bool get_property(int winId, int property, const char *&data, int &len);
-#endif
-#ifndef QT_NO_QWS_INPUTMETHODS
- void im_response(const QWSIMResponseCommand *);
-
- void im_update(const QWSIMUpdateCommand *);
-
- void send_im_mouse(const QWSIMMouseCommand *);
-#endif
- // not in ifndef as this results in more readable functions.
- static void sendKeyEventUnfiltered(int unicode, int keycode, Qt::KeyboardModifiers modifiers,
- bool isPress, bool autoRepeat);
- static void sendMouseEventUnfiltered(const QPoint &pos, int state, int wheel = 0);
- static void emergency_cleanup();
-
- static QBrush *bgBrush;
-
- void sendMaxWindowRectEvents(const QRect &rect);
-
- void invokeIdentify(const QWSIdentifyCommand *cmd, QWSClient *client);
- void invokeCreate(QWSCreateCommand *cmd, QWSClient *client);
- void invokeRegionName(const QWSRegionNameCommand *cmd, QWSClient *client);
- void invokeRegion(QWSRegionCommand *cmd, QWSClient *client);
- void invokeRegionMove(const QWSRegionMoveCommand *cmd, QWSClient *client);
- void invokeRegionDestroy(const QWSRegionDestroyCommand *cmd, QWSClient *client);
- void invokeSetAltitude(const QWSChangeAltitudeCommand *cmd, QWSClient *client);
- void invokeSetOpacity(const QWSSetOpacityCommand *cmd, QWSClient *client);
-#ifndef QT_NO_QWS_PROPERTIES
- void invokeAddProperty(QWSAddPropertyCommand *cmd);
- void invokeSetProperty(QWSSetPropertyCommand *cmd);
- void invokeRemoveProperty(QWSRemovePropertyCommand *cmd);
- void invokeGetProperty(QWSGetPropertyCommand *cmd, QWSClient *client);
-#endif //QT_NO_QWS_PROPERTIES
- void invokeSetSelectionOwner(QWSSetSelectionOwnerCommand *cmd);
- void invokeConvertSelection(QWSConvertSelectionCommand *cmd);
- void invokeSetFocus(const QWSRequestFocusCommand *cmd, QWSClient *client);
-
- void initIO();
- void setFocus(QWSWindow*, bool gain);
-#ifndef QT_NO_QWS_CURSOR
- void invokeDefineCursor(QWSDefineCursorCommand *cmd, QWSClient *client);
- void invokeSelectCursor(QWSSelectCursorCommand *cmd, QWSClient *client);
- void invokePositionCursor(QWSPositionCursorCommand *cmd, QWSClient *client);
-#endif
- void invokeGrabMouse(QWSGrabMouseCommand *cmd, QWSClient *client);
- void invokeGrabKeyboard(QWSGrabKeyboardCommand *cmd, QWSClient *client);
-#ifndef QT_NO_SOUND
- void invokePlaySound(QWSPlaySoundCommand *cmd, QWSClient *client);
-#endif
-#ifndef QT_NO_COP
- void invokeRegisterChannel(QWSQCopRegisterChannelCommand *cmd,
- QWSClient *client);
- void invokeQCopSend(QWSQCopSendCommand *cmd, QWSClient *client);
-#endif
- void invokeRepaintRegion(QWSRepaintRegionCommand *cmd,
- QWSClient *client);
-#ifndef QT_NO_QWSEMBEDWIDGET
- void invokeEmbed(QWSEmbedCommand *cmd, QWSClient *client);
-#endif
-#ifndef QT_NO_QWS_INPUTMETHODS
- void invokeIMResponse(const QWSIMResponseCommand *cmd,
- QWSClient *client);
- void invokeIMUpdate(const QWSIMUpdateCommand *cmd,
- QWSClient *client);
-#endif
- void invokeFont(const QWSFontCommand *cmd, QWSClient *client);
- void invokeScreenTransform(const QWSScreenTransformCommand *cmd,
- QWSClient *client);
-
- QWSMouseHandler* newMouseHandler(const QString& spec);
- void openDisplay();
- void closeDisplay();
-
- void showCursor();
- void hideCursor();
- void initializeCursor();
-
- void resetEngine();
-
-//private Q_SLOTS:
-
-#ifndef QT_NO_QWS_MULTIPROCESS
- void _q_clientClosed();
- void _q_doClient();
- void _q_deleteWindowsLater();
-#endif
-
- void _q_screenSaverWake();
- void _q_screenSaverSleep();
- void _q_screenSaverTimeout();
-#ifndef QT_NO_QWS_MULTIPROCESS
- void _q_newConnection();
-#endif
-
-//other private moved from class
-
- void disconnectClient(QWSClient *);
- void screenSave(int level);
- void doClient(QWSClient *);
- typedef QMap<int,QWSClient*>::Iterator ClientIterator;
- typedef QMap<int,QWSClient*> ClientMap;
- void handleWindowClose(QWSWindow *w);
- void releaseMouse(QWSWindow* w);
- void releaseKeyboard(QWSWindow* w);
- void updateClientCursorPos();
-
- uchar* sharedram;
- int ramlen;
-
- ClientMap clientMap;
-#ifndef QT_NO_QWS_PROPERTIES
- QWSPropertyManager propertyManager;
-#endif
- struct SelectionOwner {
- int windowid;
- struct Time {
- void set(int h, int m, int s, int s2) {
- hour = h; minute = m; sec = s; ms = s2;
- }
- int hour, minute, sec, ms;
- } time;
- } selectionOwner;
- QTime timer;
- int* screensaverinterval;
-
- QWSWindow *focusw;
- QWSWindow *mouseGrabber;
- bool mouseGrabbing;
- bool inputMethodMouseGrabbed;
- int swidth, sheight, sdepth;
-#ifndef QT_NO_QWS_CURSOR
- bool haveviscurs;
- QWSCursor *cursor; // cursor currently shown
- QWSCursor *nextCursor; // cursor to show once grabbing is off
-#endif
-
- bool disablePainting;
- QList<QWSMouseHandler*> mousehandlers;
-#ifndef QT_NO_QWS_KEYBOARD
- QList<QWSKeyboardHandler*> keyboardhandlers;
-#endif
-
- QList<QWSCommandStruct*> commandQueue;
-
- // Window management
- QList<QWSWindow*> windows; // first=topmost
- int nReserved;
- QWSWindow* newWindow(int id, QWSClient* client);
- QWSWindow* findWindow(int windowid, QWSClient* client = 0);
- void moveWindowRegion(QWSWindow*, int dx, int dy);
- void setWindowRegion(QWSWindow*, const QRegion &r);
- void raiseWindow(QWSWindow *, int = 0);
- void lowerWindow(QWSWindow *, int = -1);
- void exposeRegion(const QRegion &, int index = 0);
-
- void setCursor(QWSCursor *curs);
-
- // multimedia
-#ifndef QT_NO_SOUND
- QWSSoundServer *soundserver;
-#endif
-#ifndef QT_NO_COP
- QMap<QString, QList<QWSClient*> > channels;
-#endif
-
-#ifndef QT_NO_QWS_MULTIPROCESS
- QWSServerSocket *ssocket;
-#endif
-
- // filename -> refcount
- QMap<QByteArray, int> fontReferenceCount;
- QBasicTimer fontCleanupTimer;
- void referenceFont(QWSClientPrivate *client, const QByteArray &font);
- void dereferenceFont(QWSClientPrivate *client, const QByteArray &font);
- void cleanupFonts(bool force = false);
- void sendFontRemovedEvent(const QByteArray &font);
-
- bool doClientIsActive;
- QList<QWSClient*> pendingDoClients;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/gui/embedded/qwindowsystem_qws.cpp b/src/gui/embedded/qwindowsystem_qws.cpp
deleted file mode 100644
index 0e4e27c852..0000000000
--- a/src/gui/embedded/qwindowsystem_qws.cpp
+++ /dev/null
@@ -1,4960 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qplatformdefs.h"
-
-#include "qwindowsystem_qws.h"
-#include "qwsevent_qws.h"
-#include "qwscommand_qws_p.h"
-#include "qtransportauth_qws_p.h"
-#include "qwsutils_qws.h"
-#include "qwscursor_qws.h"
-#include "qwsdisplay_qws.h"
-#include "qmouse_qws.h"
-#include "qcopchannel_qws.h"
-#include "qwssocket_qws.h"
-
-#include "qapplication.h"
-#include "private/qapplication_p.h"
-#include "qsocketnotifier.h"
-#include "qpolygon.h"
-#include "qimage.h"
-#include "qcursor.h"
-#include <private/qpaintengine_raster_p.h>
-#include "qscreen_qws.h"
-#include "qwindowdefs.h"
-#include "private/qlock_p.h"
-#include "qwslock_p.h"
-#include "qfile.h"
-#include "qtimer.h"
-#include "qpen.h"
-#include "qdesktopwidget.h"
-#include "qevent.h"
-#include "qinputcontext.h"
-#include "qpainter.h"
-
-#include <qdebug.h>
-
-#include "qkbddriverfactory_qws.h"
-#include "qmousedriverfactory_qws.h"
-
-#include <qbuffer.h>
-#include <qdir.h>
-
-#include <private/qwindowsurface_qws_p.h>
-#include <private/qfontengine_qpf_p.h>
-
-#include "qwindowsystem_p.h"
-
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <errno.h>
-
-#ifndef QT_NO_QWS_MULTIPROCESS
-#include <sys/param.h>
-#include <sys/mount.h>
-#endif
-
-#if !defined(QT_NO_SOUND) && !defined(Q_OS_DARWIN)
-#ifdef QT_USE_OLD_QWS_SOUND
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-#include <sys/soundcard.h>
-#else
-#include "qsoundqss_qws.h"
-#endif
-#endif
-
-//#define QWS_DEBUG_FONTCLEANUP
-
-QT_BEGIN_NAMESPACE
-
-QWSServer Q_GUI_EXPORT *qwsServer=0;
-static QWSServerPrivate *qwsServerPrivate=0;
-
-#define MOUSE 0
-#define KEY 1
-//#define EVENT_BLOCK_DEBUG
-
-QWSScreenSaver::~QWSScreenSaver()
-{
-}
-
-extern QByteArray qws_display_spec;
-extern void qt_init_display(); //qapplication_qws.cpp
-extern QString qws_qtePipeFilename();
-
-extern void qt_client_enqueue(const QWSEvent *); //qapplication_qws.cpp
-extern QList<QWSCommand*> *qt_get_server_queue();
-
-Q_GLOBAL_STATIC_WITH_ARGS(QString, defaultMouse, (QLatin1String("Auto")))
-Q_GLOBAL_STATIC_WITH_ARGS(QString, defaultKeyboard, (QLatin1String("TTY")))
-static const int FontCleanupInterval = 60 * 1000;
-
-static int qws_keyModifiers = 0;
-
-static QWSWindow *keyboardGrabber;
-static bool keyboardGrabbing;
-
-static int get_object_id(int count = 1)
-{
- static int next=1000;
- int n = next;
- next += count;
- return n;
-}
-#ifndef QT_NO_QWS_INPUTMETHODS
-static QWSInputMethod *current_IM = 0;
-
-static QWSWindow *current_IM_composing_win = 0;
-static int current_IM_winId = -1;
-static bool force_reject_strokeIM = false;
-#endif
-
-static void cleanupFontsDir();
-
-//#define QWS_REGION_DEBUG
-
-/*!
- \class QWSScreenSaver
- \ingroup qws
-
- \brief The QWSScreenSaver class is a base class for screensavers
- in Qt for Embedded Linux.
-
- When running \l{Qt for Embedded Linux} applications, it is the server
- application that installs and controls the screensaver.
- \l{Qt for Embedded Linux} supports multilevel screen saving; i.e., it is possible to
- specify several different levels of screen responsiveness. For
- example, you can choose to first turn off the light before you
- fully activate the screensaver.
-
- Note that there exists no default screensaver implementation.
-
- To create a custom screensaver, derive from this class and
- reimplement the restore() and save() functions. These functions
- are called whenever the screensaver is activated or deactivated,
- respectively. Once an instance of your custom screensaver is
- created, you can use the QWSServer::setScreenSaver() function to
- install it.
-
- \sa QWSServer, QScreen, {Qt for Embedded Linux}
-*/
-
-/*!
- \fn QWSScreenSaver::~QWSScreenSaver()
-
- Reimplement this function to destroy the screensaver.
-*/
-
-/*!
- \fn QWSScreenSaver::restore()
-
- Implement this function to deactivate the screensaver, restoring
- the previously saved screen.
-
- \sa save(), QWSServer::screenSaverActivate()
-*/
-
-/*!
- \fn QWSScreenSaver::save(int level)
-
- Implement this function to activate the screensaver, saving the
- current screen.
-
- \l{Qt for Embedded Linux} supports multilevel screen saving; i.e., it is
- possible to specify several different levels of screen
- responsiveness. For example, you can choose to first turn off the
- light before you fully activate the screensaver. Use the
- QWSServer::setScreenSaverIntervals() to specify the time intervals
- between the different levels.
-
- This function should return true if the screensaver successfully
- enters the given \a level; otherwise it should return false.
-
- \sa restore(), QWSServer::screenSaverActivate()
-*/
-
-class QWSWindowPrivate
-{
-public:
- QWSWindowPrivate();
-
-#ifdef QT_QWS_CLIENTBLIT
- QRegion directPaintRegion;
-#endif
- QRegion allocatedRegion;
-#ifndef QT_NO_QWSEMBEDWIDGET
- QList<QWSWindow*> embedded;
- QWSWindow *embedder;
-#endif
- QWSWindow::State state;
- Qt::WindowFlags windowFlags;
- QRegion dirtyOnScreen;
- bool painted;
-};
-
-QWSWindowPrivate::QWSWindowPrivate()
- :
-#ifndef QT_NO_QWSEMBEDWIDGET
- embedder(0), state(QWSWindow::NoState),
-#endif
- painted(false)
-{
-}
-
-/*!
- \class QWSWindow
- \ingroup qws
-
- \brief The QWSWindow class encapsulates a top-level window in
- Qt for Embedded Linux.
-
- When you run a \l{Qt for Embedded Linux} application, it either runs as a
- server or connects to an existing server. As applications add and
- remove windows, the server process maintains information about
- each window. In \l{Qt for Embedded Linux}, top-level windows are
- encapsulated as QWSWindow objects. Note that you should never
- construct the QWSWindow class yourself; the current top-level
- windows can be retrieved using the QWSServer::clientWindows()
- function.
-
- With a window at hand, you can retrieve its caption, name, opacity
- and ID using the caption(), name(), opacity() and winId()
- functions, respectively. Use the client() function to retrieve a
- pointer to the client that owns the window.
-
- Use the isVisible() function to find out if the window is
- visible. You can find out if the window is completely obscured by
- another window or by the bounds of the screen, using the
- isFullyObscured() function. The isOpaque() function returns true
- if the window has an alpha channel equal to 255. Finally, the
- requestedRegion() function returns the region of the display the
- window wants to draw on.
-
- \sa QWSServer, QWSClient, {Qt for Embedded Linux Architecture}
-*/
-
-/*!
- \fn int QWSWindow::winId() const
-
- Returns the window's ID.
-
- \sa name(), caption()
-*/
-
-/*!
- \fn const QString &QWSWindow::name() const
-
- Returns the window's name, which is taken from the \l {QWidget::}{objectName()}
- at the time of \l {QWidget::}{show()}.
-
- \sa caption(), winId()
-*/
-
-/*!
- \fn const QString &QWSWindow::caption() const
-
- Returns the window's caption.
-
- \sa name(), winId()
-*/
-
-/*!
- \fn QWSClient* QWSWindow::client() const
-
- Returns a reference to the QWSClient object that owns this window.
-
- \sa requestedRegion()
-*/
-
-/*!
- \fn QRegion QWSWindow::requestedRegion() const
-
- Returns the region that the window has requested to draw onto,
- including any window decorations.
-
- \sa client()
-*/
-
-/*!
- \fn bool QWSWindow::isVisible() const
-
- Returns true if the window is visible; otherwise returns false.
-
- \sa isFullyObscured()
-*/
-
-/*!
- \fn bool QWSWindow::isOpaque() const
-
- Returns true if the window is opaque, i.e., if its alpha channel
- equals 255; otherwise returns false.
-
- \sa opacity()
-*/
-
-/*!
- \fn uint QWSWindow::opacity () const
-
- Returns the window's alpha channel value.
-
- \sa isOpaque()
-*/
-
-/*!
- \fn bool QWSWindow::isPartiallyObscured() const
- \internal
-
- Returns true if the window is partially obsured by another window
- or by the bounds of the screen; otherwise returns false.
-*/
-
-/*!
- \fn bool QWSWindow::isFullyObscured() const
-
- Returns true if the window is completely obsured by another window
- or by the bounds of the screen; otherwise returns false.
-
- \sa isVisible()
-*/
-
-/*!
- \fn QWSWindowSurface* QWSWindow::windowSurface() const
- \internal
-*/
-
-QWSWindow::QWSWindow(int i, QWSClient* client)
- : id(i), modified(false),
- onTop(false), c(client), last_focus_time(0), _opacity(255),
- opaque(true), d(new QWSWindowPrivate)
-{
- surface = 0;
-}
-
-
-/*!
- \enum QWSWindow::State
-
- This enum describes the state of a window. Most of the
- transitional states are set just before a call to
- QScreen::exposeRegion() and reset immediately afterwards.
-
- \value NoState Initial state before the window is properly initialized.
- \value Hidden The window is not visible.
- \value Showing The window is being shown.
- \value Visible The window is visible, and not in a transition.
- \value Hiding The window is being hidden.
- \value Raising The windoe is being raised.
- \value Lowering The window is being raised.
- \value Moving The window is being moved.
- \value ChangingGeometry The window's geometry is being changed.
- \value Destroyed The window is destroyed.
-
- \sa state(), QScreen::exposeRegion()
-*/
-
-/*!
- Returns the current state of the window.
-
- \since 4.3
-*/
-QWSWindow::State QWSWindow::state() const
-{
- return d->state;
-}
-
-/*!
- Returns the window flags of the window. This value is only available
- after the first paint event.
-
- \since 4.3
-*/
-Qt::WindowFlags QWSWindow::windowFlags() const
-{
- return d->windowFlags;
-}
-
-/*!
- Returns the region that has been repainted since the previous
- QScreen::exposeRegion(), and needs to be copied to the screen.
- \since 4.3
-*/
-QRegion QWSWindow::dirtyOnScreen() const
-{
- return d->dirtyOnScreen;
-}
-
-void QWSWindow::createSurface(const QString &key, const QByteArray &data)
-{
-#ifndef QT_NO_QWS_MULTIPROCESS
- if (surface && !surface->isBuffered())
- c->removeUnbufferedSurface();
-#endif
-
- delete surface;
- surface = qt_screen->createSurface(key);
- surface->setPermanentState(data);
-
-#ifndef QT_NO_QWS_MULTIPROCESS
- if (!surface->isBuffered())
- c->addUnbufferedSurface();
-#endif
-}
-
-/*!
- \internal
- Raises the window above all other windows except "Stay on top" windows.
-*/
-void QWSWindow::raise()
-{
- qwsServerPrivate->raiseWindow(this);
-#ifndef QT_NO_QWSEMBEDWIDGET
- const int n = d->embedded.size();
- for (int i = 0; i < n; ++i)
- d->embedded.at(i)->raise();
-#endif
-}
-
-/*!
- \internal
- Lowers the window below other windows.
-*/
-void QWSWindow::lower()
-{
- qwsServerPrivate->lowerWindow(this);
-#ifndef QT_NO_QWSEMBEDWIDGET
- const int n = d->embedded.size();
- for (int i = 0; i < n; ++i)
- d->embedded.at(i)->lower();
-#endif
-}
-
-/*!
- \internal
- Shows the window.
-*/
-void QWSWindow::show()
-{
- operation(QWSWindowOperationEvent::Show);
-#ifndef QT_NO_QWSEMBEDWIDGET
- const int n = d->embedded.size();
- for (int i = 0; i < n; ++i)
- d->embedded.at(i)->show();
-#endif
-}
-
-/*!
- \internal
- Hides the window.
-*/
-void QWSWindow::hide()
-{
- operation(QWSWindowOperationEvent::Hide);
-#ifndef QT_NO_QWSEMBEDWIDGET
- const int n = d->embedded.size();
- for (int i = 0; i < n; ++i)
- d->embedded.at(i)->hide();
-#endif
-}
-
-/*!
- \internal
- Make this the active window (i.e., sets the keyboard focus to this
- window).
-*/
-void QWSWindow::setActiveWindow()
-{
- qwsServerPrivate->setFocus(this, true);
-#ifndef QT_NO_QWSEMBEDWIDGET
- const int n = d->embedded.size();
- for (int i = 0; i < n; ++i)
- d->embedded.at(i)->setActiveWindow();
-#endif
-}
-
-void QWSWindow::setName(const QString &n)
-{
- rgnName = n;
-}
-
-/*!
- \internal
- Sets the window's caption to \a c.
-*/
-void QWSWindow::setCaption(const QString &c)
-{
- rgnCaption = c;
-}
-
-
-static int global_focus_time_counter=100;
-
-void QWSWindow::focus(bool get)
-{
- if (get)
- last_focus_time = global_focus_time_counter++;
- if (c) {
- QWSFocusEvent event;
- event.simpleData.window = id;
- event.simpleData.get_focus = get;
- c->sendEvent(&event);
- }
-}
-
-void QWSWindow::operation(QWSWindowOperationEvent::Operation o)
-{
- if (!c)
- return;
- QWSWindowOperationEvent event;
- event.simpleData.window = id;
- event.simpleData.op = o;
- c->sendEvent(&event);
-}
-
-/*!
- \internal
- Destructor.
-*/
-QWSWindow::~QWSWindow()
-{
-#ifndef QT_NO_QWS_INPUTMETHODS
- if (current_IM_composing_win == this)
- current_IM_composing_win = 0;
-#endif
-#ifndef QT_NO_QWSEMBEDWIDGET
- QWSWindow *embedder = d->embedder;
- if (embedder) {
- embedder->d->embedded.removeAll(this);
- d->embedder = 0;
- }
- while (!d->embedded.isEmpty())
- stopEmbed(d->embedded.first());
-#endif
-
-#ifndef QT_NO_QWS_MULTIPROCESS
- if (surface && !surface->isBuffered()) {
- if (c && c->d_func()) // d_func() will be 0 if client is deleted
- c->removeUnbufferedSurface();
- }
-#endif
-
- delete surface;
- delete d;
-}
-
-/*!
- \internal
-
- Returns the region that the window is allowed to draw onto,
- including any window decorations but excluding regions covered by
- other windows.
-
- \sa paintedRegion(), requestedRegion()
-*/
-QRegion QWSWindow::allocatedRegion() const
-{
- return d->allocatedRegion;
-}
-
-#ifdef QT_QWS_CLIENTBLIT
-QRegion QWSWindow::directPaintRegion() const
-{
- return d->directPaintRegion;
-}
-
-inline void QWSWindow::setDirectPaintRegion(const QRegion &r)
-{
- d->directPaintRegion = r;
-}
-#endif
-
-/*!
- \internal
-
- Returns the region that the window is known to have drawn into.
-
- \sa allocatedRegion(), requestedRegion()
-*/
-QRegion QWSWindow::paintedRegion() const
-{
- return (d->painted ? d->allocatedRegion : QRegion());
-}
-
-inline void QWSWindow::setAllocatedRegion(const QRegion &region)
-{
- d->allocatedRegion = region;
-}
-
-#ifndef QT_NO_QWSEMBEDWIDGET
-inline void QWSWindow::startEmbed(QWSWindow *w)
-{
- d->embedded.append(w);
- w->d->embedder = this;
-}
-
-inline void QWSWindow::stopEmbed(QWSWindow *w)
-{
- w->d->embedder = 0;
- w->client()->sendEmbedEvent(w->winId(), QWSEmbedEvent::Region, QRegion());
- d->embedded.removeAll(w);
-}
-#endif // QT_NO_QWSEMBEDWIDGET
-
-/*********************************************************************
- *
- * Class: QWSClient
- *
- *********************************************************************/
-
-class QWSClientPrivate : public QObjectPrivate
-{
- Q_DECLARE_PUBLIC(QWSClient)
-
-public:
- QWSClientPrivate();
- ~QWSClientPrivate();
-
- void setLockId(int id);
- void unlockCommunication();
-
-private:
-#ifndef QT_NO_QWS_MULTIPROCESS
- QWSLock *clientLock;
- bool shutdown;
- int numUnbufferedSurfaces;
-#endif
- QSet<QByteArray> usedFonts;
- friend class QWSServerPrivate;
-};
-
-QWSClientPrivate::QWSClientPrivate()
-{
-#ifndef QT_NO_QWS_MULTIPROCESS
- clientLock = 0;
- shutdown = false;
- numUnbufferedSurfaces = 0;
-#endif
-}
-
-QWSClientPrivate::~QWSClientPrivate()
-{
-#ifndef QT_NO_QWS_MULTIPROCESS
- delete clientLock;
-#endif
-}
-
-void QWSClientPrivate::setLockId(int id)
-{
-#ifdef QT_NO_QWS_MULTIPROCESS
- Q_UNUSED(id);
-#else
- clientLock = new QWSLock(id);
-#endif
-}
-
-void QWSClientPrivate::unlockCommunication()
-{
-#ifndef QT_NO_QWS_MULTIPROCESS
- if (clientLock)
- clientLock->unlock(QWSLock::Communication);
-#endif
-}
-
-/*!
- \class QWSClient
- \ingroup qws
-
- \brief The QWSClient class encapsulates a client process in Qt for Embedded Linux.
-
- When you run a \l{Qt for Embedded Linux} application, it either runs as a
- server or connects to an existing server. The server and client
- processes have different responsibilities: The client process
- performs all application specific operations. The server process
- is responsible for managing the clients as well as taking care of
- the pointer handling, character input, and screen output. In
- addition, the server provides functionality to handle input
- methods.
-
- As applications add and remove windows, the server process
- maintains information about each window. In \l{Qt for Embedded Linux},
- top-level windows are encapsulated as QWSWindow objects. A list of
- the current windows can be retrieved using the
- QWSServer::clientWindows() function, and each window can tell
- which client that owns it through its QWSWindow::client()
- function.
-
- A QWSClient object has an unique ID that can be retrieved using
- its clientId() function. QWSClient also provides the identity()
- function which typically returns the name of this client's running
- application.
-
- \sa QWSServer, QWSWindow, {Qt for Embedded Linux Architecture}
-*/
-
-/*!
- \internal
-*/
-//always use frame buffer
-QWSClient::QWSClient(QObject* parent, QWS_SOCK_BASE* sock, int id)
- : QObject(*new QWSClientPrivate, parent), command(0), cid(id)
-{
-#ifdef QT_NO_QWS_MULTIPROCESS
- Q_UNUSED(sock);
- isClosed = false;
-#else
- csocket = 0;
- if (!sock) {
- socketDescriptor = -1;
- isClosed = false;
- } else {
- csocket = static_cast<QWSSocket*>(sock); //###
- isClosed = false;
-
- csocket->flush();
- socketDescriptor = csocket->socketDescriptor();
- connect(csocket, SIGNAL(readyRead()), this, SIGNAL(readyRead()));
- connect(csocket, SIGNAL(disconnected()), this, SLOT(closeHandler()));
- connect(csocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(errorHandler()));
- }
-#endif //QT_NO_QWS_MULTIPROCESS
-}
-
-/*!
- \internal
-*/
-QWSClient::~QWSClient()
-{
- qDeleteAll(cursors);
- delete command;
-#ifndef QT_NO_QWS_MULTIPROCESS
- delete csocket;
-#endif
-}
-
-#ifndef QT_NO_QWS_MULTIPROCESS
-void QWSClient::removeUnbufferedSurface()
-{
- Q_D(QWSClient);
- --d->numUnbufferedSurfaces;
-}
-
-void QWSClient::addUnbufferedSurface()
-{
- Q_D(QWSClient);
- ++d->numUnbufferedSurfaces;
-}
-#endif // QT_NO_QWS_MULTIPROCESS
-
-/*!
- \internal
-*/
-void QWSClient::setIdentity(const QString& i)
-{
- id = i;
-}
-
-void QWSClient::closeHandler()
-{
- isClosed = true;
- emit connectionClosed();
-}
-
-void QWSClient::errorHandler()
-{
-#if defined(QWS_SOCKET_DEBUG)
- qDebug("Client %p error %s", this, csocket ? csocket->errorString().toLatin1().constData() : "(no socket)");
-#endif
- isClosed = true;
-//####Do we need to clean out the pipes?
-
- emit connectionClosed();
-}
-
-/*!
- \internal
-*/
-int QWSClient::socket() const
-{
- return socketDescriptor;
-}
-
-/*!
- \internal
-*/
-void QWSClient::sendEvent(QWSEvent* event)
-{
-#ifndef QT_NO_QWS_MULTIPROCESS
- if (csocket) {
- // qDebug() << "QWSClient::sendEvent type " << event->type << " socket state " << csocket->state();
- if ((QAbstractSocket::SocketState)(csocket->state()) == QAbstractSocket::ConnectedState) {
- event->write(csocket);
- }
- }
- else
-#endif
- {
- qt_client_enqueue(event);
- }
-}
-
-/*!
- \internal
-*/
-void QWSClient::sendRegionEvent(int winid, QRegion rgn, int type
-#ifdef QT_QWS_CLIENTBLIT
- , int id
-#endif
- )
-{
-#ifndef QT_NO_QWS_MULTIPROCESS
- Q_D(QWSClient);
- if (d->clientLock)
- d->clientLock->lock(QWSLock::RegionEvent);
-#endif
-
- QWSRegionEvent event;
- event.setData(winid, rgn, type);
-#ifdef QT_QWS_CLIENTBLIT
- event.simpleData.id = id;
-#endif
-
-// qDebug() << "Sending Region event to" << winid << "rgn" << rgn << "type" << type;
-
- sendEvent(&event);
-}
-
-extern int qt_servershmid;
-
-/*!
- \internal
-*/
-void QWSClient::sendConnectedEvent(const char *display_spec)
-{
- QWSConnectedEvent event;
- event.simpleData.window = 0;
- event.simpleData.len = strlen(display_spec) + 1;
- event.simpleData.clientId = cid;
- event.simpleData.servershmid = qt_servershmid;
- char * tmp=(char *)display_spec;
- event.setData(tmp, event.simpleData.len);
- sendEvent(&event);
-}
-
-/*!
- \internal
-*/
-void QWSClient::sendMaxWindowRectEvent(const QRect &rect)
-{
- QWSMaxWindowRectEvent event;
- event.simpleData.window = 0;
- event.simpleData.rect = rect;
- sendEvent(&event);
-}
-
-/*!
- \internal
-*/
-#ifndef QT_NO_QWS_PROPERTIES
-void QWSClient::sendPropertyNotifyEvent(int property, int state)
-{
- QWSPropertyNotifyEvent event;
- event.simpleData.window = 0; // not used yet
- event.simpleData.property = property;
- event.simpleData.state = state;
- sendEvent(&event);
-}
-
-/*!
- \internal
-*/
-void QWSClient::sendPropertyReplyEvent(int property, int len, const char *data)
-{
- QWSPropertyReplyEvent event;
- event.simpleData.window = 0; // not used yet
- event.simpleData.property = property;
- event.simpleData.len = len;
- event.setData(data, len);
- sendEvent(&event);
-}
-#endif //QT_NO_QWS_PROPERTIES
-
-/*!
- \internal
-*/
-void QWSClient::sendSelectionClearEvent(int windowid)
-{
- QWSSelectionClearEvent event;
- event.simpleData.window = windowid;
- sendEvent(&event);
-}
-
-/*!
- \internal
-*/
-void QWSClient::sendSelectionRequestEvent(QWSConvertSelectionCommand *cmd, int windowid)
-{
- QWSSelectionRequestEvent event;
- event.simpleData.window = windowid;
- event.simpleData.requestor = cmd->simpleData.requestor;
- event.simpleData.property = cmd->simpleData.selection;
- event.simpleData.mimeTypes = cmd->simpleData.mimeTypes;
- sendEvent(&event);
-}
-
-#ifndef QT_NO_QWSEMBEDWIDGET
-/*!
- \internal
-*/
-void QWSClient::sendEmbedEvent(int windowid, QWSEmbedEvent::Type type,
- const QRegion &region)
-{
- QWSEmbedEvent event;
- event.setData(windowid, type, region);
- sendEvent(&event);
-}
-#endif // QT_NO_QWSEMBEDWIDGET
-
-/*!
- \fn void QWSClient::connectionClosed()
- \internal
-*/
-
-/*!
- \fn void QWSClient::readyRead();
- \internal
-*/
-
-/*!
- \fn int QWSClient::clientId () const
-
- Returns an integer uniquely identfying this client.
-*/
-
-/*!
- \fn QString QWSClient::identity () const
-
- Returns the name of this client's running application.
-*/
-/*********************************************************************
- *
- * Class: QWSServer
- *
- *********************************************************************/
-
-/*!
- \class QWSServer
- \brief The QWSServer class encapsulates a server process in Qt for Embedded Linux.
-
- \ingroup qws
-
- When you run a \l{Qt for Embedded Linux} application, it either runs as a
- server or connects to an existing server. The server and client
- processes have different responsibilities: The client process
- performs all application specific operations. The server process
- is responsible for managing the clients as well as taking care of
- the pointer handling, character input, and screen output. In
- addition, the server provides functionality to handle input
- methods.
-
- In \l{Qt for Embedded Linux}, all system generated events are passed to the
- server application which then propagates the event to the
- appropriate client. See the \l{Qt for Embedded Linux Architecture}
- documentation for details.
-
- Note that this class is instantiated by QApplication for
- \l{Qt for Embedded Linux} server processes; you should never construct this
- class yourself. Use the instance() function to retrieve a pointer
- to the server object.
-
- Note that the static functions of the QWSServer class can only be
- used in the server process.
-
- \tableofcontents
-
- \section1 Client Administration
-
- As applications add and remove windows, the server process
- maintains information about each window. In \l{Qt for Embedded Linux},
- top-level windows are encapsulated as QWSWindow objects. Each
- window can tell which client that owns it through its
- QWSWindow::client() function. Use the clientWindows() function to
- retrieve a list of the current top-level windows. Given a
- particular position on the display, the window containing it can
- be retrieved using the windowAt() function.
-
- QWSServer also provides the windowEvent() signal which is emitted
- whenever something happens to a top level window; the WindowEvent
- enum describes the various types of events that the signal
- recognizes. In addition, the server class provides the
- markedText() signal which is emitted whenever some text has been
- selected in any of the windows, passing the selection as
- parameter.
-
- The QCopChannel class and the QCOP communication protocol enable
- transfer of messages between clients. QWSServer provides the
- newChannel() and removedChannel() signals that is emitted whenever
- a new QCopChannel object is created or destroyed, respectively.
-
- See also: QWSWindow, QWSClient and QCopChannel.
-
-
- \section1 Mouse Handling
-
- The mouse driver (represented by an instance of the
- QWSMouseHandler class) is loaded by the server application when it
- starts running, using Qt's \l {How to Create Qt Plugins}{plugin
- system}. A mouse driver receives mouse events from the device and
- encapsulates each event with an instance of the QWSEvent class
- which it then passes to the server.
-
- The openMouse() function opens the mouse devices specified by the
- QWS_MOUSE_PROTO environment variable, and the setMouseHandler()
- functions sets the primary mouse driver. Alternatively, the static
- setDefaultMouse() function provides means of specifying the mouse
- driver to use if the QWS_MOUSE_PROTO variable is not defined (note
- that the default is otherwise platform dependent). The primary
- mouse driver can be retrieved using the static mouseHandler()
- function. Use the closeMouse() function to delete the mouse
- drivers.
-
- In addition, the QWSServer class can control the flow of mouse
- input using the suspendMouse() and resumeMouse() functions.
-
- See also: QWSMouseHandler and \l{Qt for Embedded Linux Pointer Handling}.
-
- \section1 Keyboard Handling
-
- The keyboard driver (represented by an instance of the
- QWSKeyboardHandler class) is loaded by the server application when
- it starts running, using Qt's \l {How to Create Qt Plugins}{plugin
- system}. A keyboard driver receives keyboard events from the
- device and encapsulates each event with an instance of the
- QWSEvent class which it then passes to the server.
-
- The openKeyboard() function opens the keyboard devices specified
- by the QWS_KEYBOARD environment variable, and the
- setKeyboardHandler() functions sets the primary keyboard
- driver. Alternatively, the static setDefaultKeyboard() function
- provides means of specifying the keyboard driver to use if the
- QWS_KEYBOARD variable is not defined (note again that the default
- is otherwise platform dependent). The primary keyboard driver can
- be retrieved using the static keyboardHandler() function. Use the
- closeKeyboard() function to delete the keyboard drivers.
-
- In addition, the QWSServer class can handle key events from both
- physical and virtual keyboards using the processKeyEvent() and
- sendKeyEvent() functions, respectively. Use the
- addKeyboardFilter() function to filter the key events from
- physical keyboard drivers, the most recently added filter can be
- removed and deleted using the removeKeyboardFilter() function.
-
- See also: QWSKeyboardHandler and \l{Qt for Embedded Linux Character Input}.
-
- \section1 Display Handling
-
- When a screen update is required, the server runs through all the
- top-level windows that intersect with the region that is about to
- be updated, and ensures that the associated clients have updated
- their memory buffer. Then the server uses the screen driver
- (represented by an instance of the QScreen class) to copy the
- content of the memory to the screen.
-
- In addition, the QWSServer class provides some means of managing
- the screen output: Use the refresh() function to refresh the
- entire display, or alternatively a specified region of it. The
- enablePainting() function can be used to disable (and enable)
- painting onto the screen. QWSServer also provide the
- setMaxWindowRect() function restricting the area of the screen
- which \l{Qt for Embedded Linux} applications will consider to be the
- maximum area to use for windows. To set the brush used as the
- background in the absence of obscuring windows, QWSServer provides
- the static setBackground() function. The corresponding
- backgroundBrush() function returns the currently set brush.
-
- QWSServer also controls the screen saver: Use the setScreenSaver()
- to install a custom screen saver derived from the QWSScreenSaver
- class. Once installed, the screensaver can be activated using the
- screenSaverActivate() function, and the screenSaverActive()
- function returns its current status. Use the
- setScreenSaverInterval() function to specify the timeout interval.
- \l{Qt for Embedded Linux} also supports multilevel screen saving, use the
- setScreenSaverIntervals() function to specify the various levels
- and their timeout intervals.
-
- Finally, the QWSServer class controls the cursor's appearance,
- i.e., use the setCursorVisible() function to hide or show the
- cursor, and the isCursorVisible() function to determine whether
- the cursor is visible on the display or not.
-
- See also: QScreen and \l{Qt for Embedded Linux Display Management}.
-
- \section1 Input Method Handling
-
- Whenever the server receives an event, it queries its stack of
- top-level windows to find the window containing the event's
- position (each window can identify the client application that
- created it). Then the server forwards the event to the appropriate
- client. If an input method is installed, it is used as a filter
- between the server and the client application.
-
- Derive from the QWSInputMethod class to create custom input
- methods, and use the server's setCurrentInputMethod() function to
- install it. Use the sendIMEvent() and sendIMQuery() functions to
- send input method events and queries.
-
- QWSServer provides the IMMouse enum describing the various mouse
- events recognized by the QWSInputMethod::mouseHandler()
- function. The latter function allows subclasses of QWSInputMethod
- to handle mouse events within the preedit text.
-
- \sa QWSInputMethod
-*/
-
-/*!
- \enum QWSServer::IMState
- \obsolete
-
- This enum describes the various states of an input method.
-
- \value IMCompose Composing.
- \value IMStart Equivalent to IMCompose.
- \value IMEnd Finished composing.
-
- \sa QWSInputMethod::sendIMEvent()
-*/
-
-/*!
- \enum QWSServer::IMMouse
-
- This enum describes the various types of mouse events recognized
- by the QWSInputMethod::mouseHandler() function.
-
- \value MousePress An event generated by pressing a mouse button.
- \value MouseRelease An event generated by relasing a mouse button.
- \value MouseMove An event generated by moving the mouse cursor.
- \value MouseOutside This value is only reserved, i.e., it is not used in
- current implementations.
-
- \sa QWSInputMethod, setCurrentInputMethod()
-*/
-
-/*!
- \enum QWSServer::ServerFlags
- \internal
-
- This enum is used to pass various options to the window system
- server.
-
- \value DisableKeyboard Ignore all keyboard input.
- \value DisableMouse Ignore all mouse input.
-*/
-
-/*!
- \enum QWSServer::WindowEvent
-
- This enum specifies the various events that can occur in a
- top-level window.
-
- \value Create A new window has been created (by the QWidget constructor).
- \value Destroy The window has been closed and deleted (by the QWidget destructor).
- \value Hide The window has been hidden using the QWidget::hide() function.
- \value Show The window has been shown using the QWidget::show() function or similar.
- \value Raise The window has been raised to the top of the desktop.
- \value Lower The window has been lowered.
- \value Geometry The window has changed size or position.
- \value Active The window has become the active window (i.e., it has keyboard focus).
- \value Name The window has been named.
-
- \sa windowEvent()
-*/
-
-/*!
- \fn void QWSServer::markedText(const QString &selection)
-
- This signal is emitted whenever some text is selected in any of
- the running applications, passing the selected text in the \a
- selection parameter.
-
- \sa windowEvent()
-*/
-
-/*!
- \fn const QList<QWSWindow*> &QWSServer::clientWindows()
-
- Returns the list of current top-level windows.
-
- Note that the collection of top-level windows changes as
- applications add and remove widgets so it should not be stored for
- future use. The windows are sorted in stacking order from top-most
- to bottom-most.
-
- Use the QWSWindow::client() function to retrieve the client
- application that owns a given window.
-
- \sa windowAt(), instance()
-*/
-
-/*!
- \fn void QWSServer::newChannel(const QString& channel)
-
- This signal is emitted whenever a new QCopChannel object is
- created, passing the channel's name in the \a channel parameter.
-
- \sa removedChannel()
-*/
-
-/*!
- \fn void QWSServer::removedChannel(const QString& channel)
-
- This signal is emitted immediately after the given the QCopChannel
- object specified by \a channel, is destroyed.
-
- Note that a channel is not destroyed until all its listeners have
- been unregistered.
-
- \sa newChannel()
-*/
-
-/*!
- \fn QWSServer::QWSServer(int flags, QObject *parent)
- \internal
-
- Construct a QWSServer object with the given \a parent. The \a
- flags are used for keyboard and mouse settings.
-
- \warning This class is instantiated by QApplication for
- \l{Qt for Embedded Linux} server processes. You should never construct
- this class yourself.
-
- \sa {Running Applications}
-*/
-
-/*!
- \fn static QWSServer* QWSServer::instance()
- \since 4.2
-
- Returns a pointer to the server instance.
-
- Note that the pointer will be 0 if the application is not the
- server, i.e., if the QApplication::type() function doesn't return
- QApplication::GuiServer.
-
- \sa clientWindows(), windowAt()
-*/
-
-struct QWSCommandStruct
-{
- QWSCommandStruct(QWSCommand *c, QWSClient *cl) :command(c),client(cl){}
- ~QWSCommandStruct() { delete command; }
-
- QWSCommand *command;
- QWSClient *client;
-
-};
-
-QWSServer::QWSServer(int flags, QObject *parent) :
- QObject(*new QWSServerPrivate, parent)
-{
- Q_D(QWSServer);
- QT_TRY {
- d->initServer(flags);
- } QT_CATCH(...) {
- qwsServer = 0;
- qwsServerPrivate = 0;
- QT_RETHROW;
- }
-}
-
-#ifdef QT3_SUPPORT
-/*!
- Use the two-argument overload and call the
- QObject::setObjectName() function instead.
-*/
-QWSServer::QWSServer(int flags, QObject *parent, const char *name) :
- QObject(*new QWSServerPrivate, parent)
-{
- Q_D(QWSServer);
- setObjectName(QString::fromAscii(name));
- d->initServer(flags);
-}
-#endif
-
-
-#ifndef QT_NO_QWS_MULTIPROCESS
-static void ignoreSignal(int) {} // Used to eat SIGPIPE signals below
-#endif
-
-bool QWSServerPrivate::screensaverblockevent( int index, int *screensaverinterval, bool isDown )
-{
- static bool ignoreEvents[2] = { false, false };
- if ( isDown ) {
- if ( !ignoreEvents[index] ) {
- bool wake = false;
- if ( screensaverintervals ) {
- if ( screensaverinterval != screensaverintervals ) {
- wake = true;
- }
- }
- if ( screensaverblockevents && wake ) {
-#ifdef EVENT_BLOCK_DEBUG
- qDebug( "waking the screen" );
-#endif
- ignoreEvents[index] = true;
- } else if ( !screensaverblockevents ) {
-#ifdef EVENT_BLOCK_DEBUG
- qDebug( "the screen was already awake" );
-#endif
- ignoreEvents[index] = false;
- }
- }
- } else {
- if ( ignoreEvents[index] ) {
-#ifdef EVENT_BLOCK_DEBUG
- qDebug( "mouseup?" );
-#endif
- ignoreEvents[index] = false;
- return true;
- }
- }
- return ignoreEvents[index];
-}
-
-void QWSServerPrivate::initServer(int flags)
-{
- Q_Q(QWSServer);
- Q_ASSERT(!qwsServer);
- qwsServer = q;
- qwsServerPrivate = this;
- disablePainting = false;
-#ifndef QT_NO_QWS_MULTIPROCESS
- ssocket = new QWSServerSocket(qws_qtePipeFilename(), q);
- QObject::connect(ssocket, SIGNAL(newConnection()), q, SLOT(_q_newConnection()));
-
- if ( !ssocket->isListening()) {
- perror("QWSServerPrivate::initServer: server socket not listening");
- qFatal("Failed to bind to %s", qws_qtePipeFilename().toLatin1().constData());
- }
-
- struct linger tmp;
- tmp.l_onoff=1;
- tmp.l_linger=0;
- setsockopt(ssocket->socketDescriptor(),SOL_SOCKET,SO_LINGER,(char *)&tmp,sizeof(tmp));
-
-
- signal(SIGPIPE, ignoreSignal); //we get it when we read
-#endif
- focusw = 0;
- mouseGrabber = 0;
- mouseGrabbing = false;
- inputMethodMouseGrabbed = false;
- keyboardGrabber = 0;
- keyboardGrabbing = false;
-#ifndef QT_NO_QWS_CURSOR
- haveviscurs = false;
- cursor = 0;
- nextCursor = 0;
-#endif
-
-#ifndef QT_NO_QWS_MULTIPROCESS
-
- if (!geteuid()) {
-#if defined(Q_OS_LINUX) && !defined(QT_LINUXBASE)
- if(mount(0,"/var/shm", "shm", 0, 0)) {
- /* This just confuses people with 2.2 kernels
- if (errno != EBUSY)
- qDebug("Failed mounting shm fs on /var/shm: %s",strerror(errno));
- */
- }
-#endif
- }
-#endif
-
- // no selection yet
- selectionOwner.windowid = -1;
- selectionOwner.time.set(-1, -1, -1, -1);
-
- cleanupFontsDir();
-
- // initialize the font database
- // from qfontdatabase_qws.cpp
- extern void qt_qws_init_fontdb();
- qt_qws_init_fontdb();
-
- openDisplay();
-
- screensavertimer = new QTimer(q);
- screensavertimer->setSingleShot(true);
- QObject::connect(screensavertimer, SIGNAL(timeout()), q, SLOT(_q_screenSaverTimeout()));
- _q_screenSaverWake();
-
- clientMap[-1] = new QWSClient(q, 0, 0);
-
- if (!bgBrush)
- bgBrush = new QBrush(QColor(0x20, 0xb0, 0x50));
-
- initializeCursor();
-
- // input devices
- if (!(flags&QWSServer::DisableMouse)) {
- q->openMouse();
- }
-#ifndef QT_NO_QWS_KEYBOARD
- if (!(flags&QWSServer::DisableKeyboard)) {
- q->openKeyboard();
- }
-#endif
-
-#if !defined(QT_NO_SOUND) && !defined(QT_EXTERNAL_SOUND_SERVER) && !defined(Q_OS_DARWIN)
- soundserver = new QWSSoundServer(q);
-#endif
-}
-
-/*!
- \internal
- Destructs this server.
-*/
-QWSServer::~QWSServer()
-{
- closeMouse();
-#ifndef QT_NO_QWS_KEYBOARD
- closeKeyboard();
-#endif
- d_func()->cleanupFonts(/*force =*/true);
-}
-
-/*!
- \internal
- */
-void QWSServer::timerEvent(QTimerEvent *e)
-{
- Q_D(QWSServer);
- if (e->timerId() == d->fontCleanupTimer.timerId()) {
- d->cleanupFonts();
- d->fontCleanupTimer.stop();
- } else {
- QObject::timerEvent(e);
- }
-}
-
-const QList<QWSWindow*> &QWSServer::clientWindows()
-{
- Q_D(QWSServer);
- return d->windows;
-}
-
-/*!
- \internal
-*/
-void QWSServerPrivate::releaseMouse(QWSWindow* w)
-{
- if (w && mouseGrabber == w) {
- mouseGrabber = 0;
- mouseGrabbing = false;
-#ifndef QT_NO_QWS_CURSOR
- if (nextCursor) {
- // Not grabbing -> set the correct cursor
- setCursor(nextCursor);
- nextCursor = 0;
- }
-#endif
- }
-}
-
-/*!
- \internal
-*/
-void QWSServerPrivate::releaseKeyboard(QWSWindow* w)
-{
- if (keyboardGrabber == w) {
- keyboardGrabber = 0;
- keyboardGrabbing = false;
- }
-}
-
-void QWSServerPrivate::handleWindowClose(QWSWindow *w)
-{
- w->shuttingDown();
- if (focusw == w)
- setFocus(w,false);
- if (mouseGrabber == w)
- releaseMouse(w);
- if (keyboardGrabber == w)
- releaseKeyboard(w);
-}
-
-
-#ifndef QT_NO_QWS_MULTIPROCESS
-/*!
- \internal
-*/
-void QWSServerPrivate::_q_newConnection()
-{
- Q_Q(QWSServer);
- while (QWS_SOCK_BASE *sock = ssocket->nextPendingConnection()) {
- int socket = sock->socketDescriptor();
- sock->setParent(0);
-
- QWSClient *client = new QWSClient(q,sock, get_object_id());
- clientMap[socket] = client;
-
-#ifndef QT_NO_SXE
-#ifdef QTRANSPORTAUTH_DEBUG
- qDebug( "Transport auth connected: unix stream socket %d", socket );
-#endif
- // get a handle to the per-process authentication service
- QTransportAuth *a = QTransportAuth::getInstance();
-
- // assert that this transport is trusted
- QTransportAuth::Data *d = a->connectTransport(
- QTransportAuth::UnixStreamSock |
- QTransportAuth::Trusted, socket );
-
- QAuthDevice *ad = a->recvBuf( d, sock );
- ad->setClient(client);
-
- QObject::connect(ad, SIGNAL(readyRead()),
- q, SLOT(_q_doClient()));
-
- QObject::connect(client, SIGNAL(connectionClosed()),
- q, SLOT(_q_clientClosed()));
-#else
- QObject::connect(client, SIGNAL(readyRead()),
- q, SLOT(_q_doClient()));
- QObject::connect(client, SIGNAL(connectionClosed()),
- q, SLOT(_q_clientClosed()));
-#endif // QT_NO_SXE
-
- client->sendConnectedEvent(qws_display_spec.constData());
-
- if (clientMap.contains(socket)) {
- QList<QScreen*> screens = qt_screen->subScreens();
- if (screens.isEmpty())
- screens.append(qt_screen);
- for (int i = 0; i < screens.size(); ++i) {
- const QApplicationPrivate *ap = QApplicationPrivate::instance();
- QScreen *screen = screens.at(i);
- const QRect rect = ap->maxWindowRect(screen);
- if (!rect.isEmpty())
- client->sendMaxWindowRectEvent(rect);
- if (screen->isTransformed()) {
- QWSScreenTransformationEvent event;
- event.simpleData.screen = i;
- event.simpleData.transformation = screen->transformOrientation();
- client->sendEvent(&event);
- }
- }
- }
-
- // pre-provide some object id's
- QWSCreateCommand cmd(30);
- invokeCreate(&cmd, client);
- }
-}
-/*!
- \internal
-*/
-void QWSServerPrivate::_q_clientClosed()
-{
- Q_Q(QWSServer);
- QWSClient* cl = (QWSClient*)q->sender();
-
- // Remove any queued commands for this client
- int i = 0;
- while (i < commandQueue.size()) {
- QWSCommandStruct *cs = commandQueue.at(i);
- if (cs->client == cl) {
- commandQueue.removeAt(i);
- delete cs;
- } else {
- ++i;
- }
- }
-
-#ifndef QT_NO_COP
- // Enfore unsubscription from all channels.
- QCopChannel::detach(cl);
-#endif
-
- // Shut down all windows for this client
- for (int i = 0; i < windows.size(); ++i) {
- QWSWindow* w = windows.at(i);
- if (w->forClient(cl))
- w->shuttingDown();
- }
-
- // Delete all windows for this client
- QRegion exposed;
- i = 0;
- while (i < windows.size()) {
- QWSWindow* w = windows.at(i);
- if (w->forClient(cl)) {
- windows.takeAt(i);
- w->c = 0; //so we don't send events to it anymore
- releaseMouse(w);
- releaseKeyboard(w);
- exposed += w->allocatedRegion();
-// rgnMan->remove(w->allocationIndex());
- if (focusw == w)
- setFocus(focusw,0);
- if (mouseGrabber == w)
- releaseMouse(w);
- if (i < nReserved)
- --nReserved;
-#ifndef QT_NO_QWS_PROPERTIES
- propertyManager.removeProperties(w->winId());
-#endif
- emit q->windowEvent(w, QWSServer::Destroy);
- w->d->state = QWSWindow::Destroyed; //???
- deletedWindows.append(w);
- } else {
- ++i;
- }
- }
- if (deletedWindows.count())
- QTimer::singleShot(0, q, SLOT(_q_deleteWindowsLater()));
-
- QWSClientPrivate *clientPrivate = cl->d_func();
- if (!clientPrivate->shutdown) {
-#if defined(QWS_DEBUG_FONTCLEANUP)
- qDebug() << "client" << cl->clientId() << "crashed";
-#endif
- // this would be the place to emit a signal to notify about the
- // crash of a client
- crashedClientIds.append(cl->clientId());
- fontCleanupTimer.start(10, q_func());
- }
- clientPrivate->shutdown = true;
-
- while (!clientPrivate->usedFonts.isEmpty()) {
- const QByteArray font = *clientPrivate->usedFonts.begin();
-#if defined(QWS_DEBUG_FONTCLEANUP)
- qDebug() << "dereferencing font" << font << "from disconnected client";
-#endif
- dereferenceFont(clientPrivate, font);
- }
- clientPrivate->usedFonts.clear();
-
- //qDebug("removing client %d with socket %d", cl->clientId(), cl->socket());
- clientMap.remove(cl->socket());
- if (cl == cursorClient)
- cursorClient = 0;
- if (qt_screen->clearCacheFunc)
- (qt_screen->clearCacheFunc)(qt_screen, cl->clientId()); // remove any remaining cache entries.
- cl->deleteLater();
-
- update_regions();
- exposeRegion(exposed);
-}
-
-void QWSServerPrivate::_q_deleteWindowsLater()
-{
- qDeleteAll(deletedWindows);
- deletedWindows.clear();
-}
-
-#endif //QT_NO_QWS_MULTIPROCESS
-
-void QWSServerPrivate::referenceFont(QWSClientPrivate *client, const QByteArray &font)
-{
- if (!client->usedFonts.contains(font)) {
- client->usedFonts.insert(font);
-
- ++fontReferenceCount[font];
-#if defined(QWS_DEBUG_FONTCLEANUP)
- qDebug() << "Client" << client->q_func()->clientId() << "added font" << font;
- qDebug() << "Refcount is" << fontReferenceCount[font];
-#endif
- }
-}
-
-void QWSServerPrivate::dereferenceFont(QWSClientPrivate *client, const QByteArray &font)
-{
- if (client->usedFonts.contains(font)) {
- client->usedFonts.remove(font);
-
- Q_ASSERT(fontReferenceCount[font]);
- if (!--fontReferenceCount[font] && !fontCleanupTimer.isActive())
- fontCleanupTimer.start(FontCleanupInterval, q_func());
-
-#if defined(QWS_DEBUG_FONTCLEANUP)
- qDebug() << "Client" << client->q_func()->clientId() << "removed font" << font;
- qDebug() << "Refcount is" << fontReferenceCount[font];
-#endif
- }
-}
-
-static void cleanupFontsDir()
-{
- static bool dontDelete = !qgetenv("QWS_KEEP_FONTS").isEmpty();
- if (dontDelete)
- return;
-
- extern QString qws_fontCacheDir();
- QDir dir(qws_fontCacheDir(), QLatin1String("*.qsf"));
- for (uint i = 0; i < dir.count(); ++i) {
-#if defined(QWS_DEBUG_FONTCLEANUP)
- qDebug() << "removing stale font file" << dir[i];
-#endif
- dir.remove(dir[i]);
- }
-}
-
-void QWSServerPrivate::cleanupFonts(bool force)
-{
- static bool dontDelete = !qgetenv("QWS_KEEP_FONTS").isEmpty();
- if (dontDelete)
- return;
-
-#if defined(QWS_DEBUG_FONTCLEANUP)
- qDebug() << "cleanupFonts()";
-#endif
- if (!fontReferenceCount.isEmpty()) {
- QMap<QByteArray, int>::Iterator it = fontReferenceCount.begin();
- while (it != fontReferenceCount.end()) {
- if (it.value() && !force) {
- ++it;
- continue;
- }
-
- const QByteArray &fontName = it.key();
-#if defined(QWS_DEBUG_FONTCLEANUP)
- qDebug() << "removing unused font file" << fontName;
-#endif
- QT_TRY {
- QFile::remove(QFile::decodeName(fontName));
- sendFontRemovedEvent(fontName);
-
- it = fontReferenceCount.erase(it);
- } QT_CATCH(...) {
- // so we were not able to remove the font.
- // don't be angry and just continue with the next ones.
- ++it;
- }
- }
- }
-
- if (crashedClientIds.isEmpty())
- return;
-
- QList<QByteArray> removedFonts;
-#if !defined(QT_NO_QWS_QPF2) && !defined(QT_FONTS_ARE_RESOURCES)
- removedFonts = QFontEngineQPF::cleanUpAfterClientCrash(crashedClientIds);
-#endif
- crashedClientIds.clear();
-
- for (int i = 0; i < removedFonts.count(); ++i)
- sendFontRemovedEvent(removedFonts.at(i));
-}
-
-void QWSServerPrivate::sendFontRemovedEvent(const QByteArray &font)
-{
- QWSFontEvent event;
- event.simpleData.type = QWSFontEvent::FontRemoved;
- event.setData(font.constData(), font.length(), false);
-
- QMap<int,QWSClient*>::const_iterator it = clientMap.constBegin();
- for (; it != clientMap.constEnd(); ++it)
- (*it)->sendEvent(&event);
-}
-
-/*!
- \internal
-*/
-QWSCommand* QWSClient::readMoreCommand()
-{
-#ifndef QT_NO_QWS_MULTIPROCESS
- QIODevice *socket = 0;
-#endif
-#ifndef QT_NO_SXE
- if (socketDescriptor != -1) // not server socket
- socket = QTransportAuth::getInstance()->passThroughByClient( this );
-#if QTRANSPORTAUTH_DEBUG
- if (socket) {
- char displaybuf[1024];
- qint64 bytes = socket->bytesAvailable();
- if ( bytes > 511 ) bytes = 511;
- hexstring( displaybuf, ((unsigned char *)(reinterpret_cast<QAuthDevice*>(socket)->buffer().constData())), bytes );
- qDebug( "readMoreCommand: %lli bytes - %s", socket->bytesAvailable(), displaybuf );
- }
-#endif
-#endif // QT_NO_SXE
-
-#ifndef QT_NO_QWS_MULTIPROCESS
- if (!socket)
- socket = csocket; // server socket
- if (socket) {
- // read next command
- if (!command) {
- int command_type = qws_read_uint(socket);
-
- if (command_type >= 0)
- command = QWSCommand::factory(command_type);
- }
- if (command) {
- if (command->read(socket)) {
- // Finished reading a whole command.
- QWSCommand* result = command;
- command = 0;
- return result;
- }
- }
-
- // Not finished reading a whole command.
- return 0;
- } else
-#endif // QT_NO_QWS_MULTIPROCESS
- {
- QList<QWSCommand*> *serverQueue = qt_get_server_queue();
- return serverQueue->isEmpty() ? 0 : serverQueue->takeFirst();
- }
-}
-
-
-/*!
- \internal
-*/
-void QWSServer::processEventQueue()
-{
- if (qwsServerPrivate)
- qwsServerPrivate->doClient(qwsServerPrivate->clientMap.value(-1));
-}
-
-
-#ifndef QT_NO_QWS_MULTIPROCESS
-void QWSServerPrivate::_q_doClient()
-{
- Q_Q(QWSServer);
-
- QWSClient* client;
-#ifndef QT_NO_SXE
- QAuthDevice *ad = qobject_cast<QAuthDevice*>(q->sender());
- if (ad)
- client = (QWSClient*)ad->client();
- else
-#endif
- client = (QWSClient*)q->sender();
-
- if (doClientIsActive) {
- pendingDoClients.append(client);
- return;
- }
- doClientIsActive = true;
-
- doClient(client);
-
- while (!pendingDoClients.isEmpty()) {
- doClient(pendingDoClients.takeFirst());
- }
-
- doClientIsActive = false;
-}
-#endif // QT_NO_QWS_MULTIPROCESS
-
-void QWSServerPrivate::doClient(QWSClient *client)
-{
- QWSCommand* command=client->readMoreCommand();
-
- while (command) {
- QWSCommandStruct *cs = new QWSCommandStruct(command, client);
- commandQueue.append(cs);
- // Try for some more...
- command=client->readMoreCommand();
- }
-
- while (!commandQueue.isEmpty()) {
- QWSCommandStruct *cs = commandQueue.takeAt(0);
- switch (cs->command->type) {
- case QWSCommand::Identify:
- invokeIdentify((QWSIdentifyCommand*)cs->command, cs->client);
- break;
- case QWSCommand::Create:
- invokeCreate((QWSCreateCommand*)cs->command, cs->client);
- break;
-#ifndef QT_NO_QWS_MULTIPROCESS
- case QWSCommand::Shutdown:
- cs->client->d_func()->shutdown = true;
- break;
-#endif
- case QWSCommand::RegionName:
- invokeRegionName((QWSRegionNameCommand*)cs->command, cs->client);
- break;
- case QWSCommand::Region:
- invokeRegion((QWSRegionCommand*)cs->command, cs->client);
- cs->client->d_func()->unlockCommunication();
- break;
- case QWSCommand::RegionMove:
- invokeRegionMove((QWSRegionMoveCommand*)cs->command, cs->client);
- cs->client->d_func()->unlockCommunication();
- break;
- case QWSCommand::RegionDestroy:
- invokeRegionDestroy((QWSRegionDestroyCommand*)cs->command, cs->client);
- break;
-#ifndef QT_NO_QWS_PROPERTIES
- case QWSCommand::AddProperty:
- invokeAddProperty((QWSAddPropertyCommand*)cs->command);
- break;
- case QWSCommand::SetProperty:
- invokeSetProperty((QWSSetPropertyCommand*)cs->command);
- break;
- case QWSCommand::RemoveProperty:
- invokeRemoveProperty((QWSRemovePropertyCommand*)cs->command);
- break;
- case QWSCommand::GetProperty:
- invokeGetProperty((QWSGetPropertyCommand*)cs->command, cs->client);
- break;
-#endif
- case QWSCommand::SetSelectionOwner:
- invokeSetSelectionOwner((QWSSetSelectionOwnerCommand*)cs->command);
- break;
- case QWSCommand::RequestFocus:
- invokeSetFocus((QWSRequestFocusCommand*)cs->command, cs->client);
- break;
- case QWSCommand::ChangeAltitude:
- invokeSetAltitude((QWSChangeAltitudeCommand*)cs->command,
- cs->client);
- cs->client->d_func()->unlockCommunication();
- break;
- case QWSCommand::SetOpacity:
- invokeSetOpacity((QWSSetOpacityCommand*)cs->command,
- cs->client);
- break;
-
-#ifndef QT_NO_QWS_CURSOR
- case QWSCommand::DefineCursor:
- invokeDefineCursor((QWSDefineCursorCommand*)cs->command, cs->client);
- break;
- case QWSCommand::SelectCursor:
- invokeSelectCursor((QWSSelectCursorCommand*)cs->command, cs->client);
- break;
- case QWSCommand::PositionCursor:
- invokePositionCursor((QWSPositionCursorCommand*)cs->command, cs->client);
- break;
-#endif
- case QWSCommand::GrabMouse:
- invokeGrabMouse((QWSGrabMouseCommand*)cs->command, cs->client);
- break;
- case QWSCommand::GrabKeyboard:
- invokeGrabKeyboard((QWSGrabKeyboardCommand*)cs->command, cs->client);
- break;
-#if !defined(QT_NO_SOUND) && !defined(Q_OS_DARWIN)
- case QWSCommand::PlaySound:
- invokePlaySound((QWSPlaySoundCommand*)cs->command, cs->client);
- break;
-#endif
-#ifndef QT_NO_COP
- case QWSCommand::QCopRegisterChannel:
- invokeRegisterChannel((QWSQCopRegisterChannelCommand*)cs->command,
- cs->client);
- break;
- case QWSCommand::QCopSend:
- invokeQCopSend((QWSQCopSendCommand*)cs->command, cs->client);
- break;
-#endif
-#ifndef QT_NO_QWS_INPUTMETHODS
- case QWSCommand::IMUpdate:
- invokeIMUpdate((QWSIMUpdateCommand*)cs->command, cs->client);
- break;
- case QWSCommand::IMResponse:
- invokeIMResponse((QWSIMResponseCommand*)cs->command, cs->client);
- break;
- case QWSCommand::IMMouse:
- {
- if (current_IM) {
- QWSIMMouseCommand *cmd = (QWSIMMouseCommand *) cs->command;
- current_IM->mouseHandler(cmd->simpleData.index,
- cmd->simpleData.state);
- }
- }
- break;
-#endif
- case QWSCommand::Font:
- invokeFont((QWSFontCommand *)cs->command, cs->client);
- break;
- case QWSCommand::RepaintRegion:
- invokeRepaintRegion((QWSRepaintRegionCommand*)cs->command,
- cs->client);
- cs->client->d_func()->unlockCommunication();
- break;
-#ifndef QT_NO_QWSEMBEDWIDGET
- case QWSCommand::Embed:
- invokeEmbed(static_cast<QWSEmbedCommand*>(cs->command),
- cs->client);
- break;
-#endif
- case QWSCommand::ScreenTransform:
- invokeScreenTransform(static_cast<QWSScreenTransformCommand*>(cs->command),
- cs->client);
- break;
- }
- delete cs;
- }
-}
-
-
-void QWSServerPrivate::showCursor()
-{
-#ifndef QT_NO_QWS_CURSOR
- if (qt_screencursor)
- qt_screencursor->show();
-#endif
-}
-
-void QWSServerPrivate::hideCursor()
-{
-#ifndef QT_NO_QWS_CURSOR
- if (qt_screencursor)
- qt_screencursor->hide();
-#endif
-}
-
-/*!
- \fn void QWSServer::enablePainting(bool enable)
-
- Enables painting onto the screen if \a enable is true; otherwise
- painting is disabled.
-
- \sa {Qt for Embedded Linux Architecture#Drawing on Screen}{Qt for Embedded Linux
- Architecture}
-*/
-void QWSServer::enablePainting(bool enable)
-{
- Q_D(QWSServer);
-
- if (d->disablePainting == !enable)
- return;
-
- d->disablePainting = !enable;
-
- if (enable) {
- // Reset the server side allocated regions to ensure update_regions()
- // will send out region events.
- for (int i = 0; i < d->windows.size(); ++i) {
- QWSWindow *w = d->windows.at(i);
- w->setAllocatedRegion(QRegion());
-#ifdef QT_QWS_CLIENTBLIT
- w->setDirectPaintRegion(QRegion());
-#endif
- }
- d->update_regions();
- d->showCursor();
- } else {
- // Disable painting by clients by taking away their allocated region.
- // To ensure mouse events are still delivered to the correct windows,
- // the allocated regions are not modified on the server.
- for (int i = 0; i < d->windows.size(); ++i) {
- QWSWindow *w = d->windows.at(i);
- w->client()->sendRegionEvent(w->winId(), QRegion(),
- QWSRegionEvent::Allocation);
-#ifdef QT_QWS_CLIENTBLIT
- w->client()->sendRegionEvent(w->winId(), QRegion(),
- QWSRegionEvent::DirectPaint);
-#endif
- }
- d->hideCursor();
- }
-}
-
-/*!
- Refreshes the display by making the screen driver update the
- entire display.
-
- \sa QScreen::exposeRegion()
-*/
-void QWSServer::refresh()
-{
- Q_D(QWSServer);
- d->exposeRegion(QScreen::instance()->region());
-//### send repaint to non-buffered windows
-}
-
-/*!
- \fn void QWSServer::refresh(QRegion & region)
- \overload
-
- Refreshes the given \a region of the display.
-*/
-void QWSServer::refresh(QRegion & r)
-{
- Q_D(QWSServer);
- d->exposeRegion(r);
-//### send repaint to non-buffered windows
-}
-
-/*!
- \fn void QWSServer::setMaxWindowRect(const QRect& rectangle)
-
- Sets the maximum area of the screen that \l{Qt for Embedded Linux}
- applications can use, to be the given \a rectangle.
-
- Note that this function can only be used in the server process.
-
- \sa QWidget::showMaximized()
-*/
-void QWSServer::setMaxWindowRect(const QRect &rect)
-{
- QList<QScreen*> subScreens = qt_screen->subScreens();
- if (subScreens.isEmpty() && qt_screen != 0)
- subScreens.append(qt_screen);
-
- for (int i = 0; i < subScreens.size(); ++i) {
- const QScreen *screen = subScreens.at(i);
- const QRect r = (screen->region() & rect).boundingRect();
- if (r.isEmpty())
- continue;
-
- QApplicationPrivate *ap = QApplicationPrivate::instance();
- if (ap->maxWindowRect(screen) != r) {
- ap->setMaxWindowRect(screen, i, r);
- qwsServerPrivate->sendMaxWindowRectEvents(r);
- }
- }
-}
-
-/*!
- \internal
-*/
-void QWSServerPrivate::sendMaxWindowRectEvents(const QRect &rect)
-{
- QMap<int,QWSClient*>::const_iterator it = clientMap.constBegin();
- for (; it != clientMap.constEnd(); ++it)
- (*it)->sendMaxWindowRectEvent(rect);
-}
-
-/*!
- \fn void QWSServer::setDefaultMouse(const char *mouseDriver)
-
- Sets the mouse driver that will be used if the QWS_MOUSE_PROTO
- environment variable is not defined, to be the given \a
- mouseDriver.
-
- Note that the default is platform-dependent. This function can
- only be used in the server process.
-
-
- \sa setMouseHandler(), {Qt for Embedded Linux Pointer Handling}
-*/
-void QWSServer::setDefaultMouse(const char *m)
-{
- *defaultMouse() = QString::fromAscii(m);
-}
-
-/*!
- \fn void QWSServer::setDefaultKeyboard(const char *keyboardDriver)
-
- Sets the keyboard driver that will be used if the QWS_KEYBOARD
- environment variable is not defined, to be the given \a
- keyboardDriver.
-
- Note that the default is platform-dependent. This function can
- only be used in the server process.
-
- \sa setKeyboardHandler(), {Qt for Embedded Linux Character Input}
-*/
-void QWSServer::setDefaultKeyboard(const char *k)
-{
- *defaultKeyboard() = QString::fromAscii(k);
-}
-
-#ifndef QT_NO_QWS_CURSOR
-static bool prevWin;
-#endif
-
-
-extern int *qt_last_x,*qt_last_y;
-
-
-/*!
- \internal
-
- Send a mouse event. \a pos is the screen position where the mouse
- event occurred and \a state is a mask indicating which buttons are
- pressed.
-
- \a pos is in device coordinates
-*/
-void QWSServer::sendMouseEvent(const QPoint& pos, int state, int wheel)
-{
- bool block = qwsServerPrivate->screensaverblockevent(MOUSE, qwsServerPrivate->screensaverinterval, state);
-#ifdef EVENT_BLOCK_DEBUG
- qDebug() << "sendMouseEvent" << pos.x() << pos.y() << state << (block ? "block" : "pass");
-#endif
-
- if (state || wheel)
- qwsServerPrivate->_q_screenSaverWake();
-
- if ( block )
- return;
-
- QPoint tpos;
- // transformations
- if (qt_screen->isTransformed()) {
- QSize s = QSize(qt_screen->deviceWidth(), qt_screen->deviceHeight());
- tpos = qt_screen->mapFromDevice(pos, s);
- } else {
- tpos = pos;
- }
-
- if (qt_last_x) {
- *qt_last_x = tpos.x();
- *qt_last_y = tpos.y();
- }
- QWSServer::mousePosition = tpos;
- qwsServerPrivate->mouseState = state;
-
-#ifndef QT_NO_QWS_INPUTMETHODS
- const int btnMask = Qt::LeftButton | Qt::RightButton | Qt::MidButton;
- int stroke_count; // number of strokes to keep shown.
- if (force_reject_strokeIM || !current_IM)
- {
- stroke_count = 0;
- } else {
- stroke_count = current_IM->filter(tpos, state, wheel);
- }
-
- if (stroke_count == 0) {
- if (state&btnMask)
- force_reject_strokeIM = true;
- QWSServerPrivate::sendMouseEventUnfiltered(tpos, state, wheel);
- }
- // stop force reject after stroke ends.
- if (state&btnMask && force_reject_strokeIM)
- force_reject_strokeIM = false;
- // on end of stroke, force_rejct
- // and once a stroke is rejected, do not try again till pen is lifted
-#else
- QWSServerPrivate::sendMouseEventUnfiltered(tpos, state, wheel);
-#endif // end QT_NO_QWS_FSIM
-}
-
-void QWSServerPrivate::sendMouseEventUnfiltered(const QPoint &pos, int state, int wheel)
-{
- const int btnMask = Qt::LeftButton | Qt::RightButton | Qt::MidButton;
- QWSMouseEvent event;
-
- QWSWindow *win = qwsServer->windowAt(pos);
-
- QWSClient *serverClient = qwsServerPrivate->clientMap.value(-1);
- QWSClient *winClient = win ? win->client() : 0;
-
-
- bool imMouse = false;
-#ifndef QT_NO_QWS_INPUTMETHODS
- // check for input method window
- if (current_IM && current_IM_winId != -1) {
- QWSWindow *kbw = keyboardGrabber ? keyboardGrabber :
- qwsServerPrivate->focusw;
-
- imMouse = kbw == win;
- if ( !imMouse ) {
- QWidget *target = winClient == serverClient ?
- QApplication::widgetAt(pos) : 0;
- imMouse = target && (target->testAttribute(Qt::WA_InputMethodTransparent));
- }
- }
-#endif
-
- //If grabbing window disappears, grab is still active until
- //after mouse release.
- if ( qwsServerPrivate->mouseGrabber && (!imMouse || qwsServerPrivate->inputMethodMouseGrabbed)) {
- win = qwsServerPrivate->mouseGrabber;
- winClient = win ? win->client() : 0;
- }
- event.simpleData.window = win ? win->id : 0;
-
-#ifndef QT_NO_QWS_CURSOR
- if (qt_screencursor)
- qt_screencursor->move(pos.x(),pos.y());
-
- // Arrow cursor over desktop
- // prevWin remembers if the last event was over a window
- if (!win && prevWin) {
- if (!qwsServerPrivate->mouseGrabber)
- qwsServerPrivate->setCursor(QWSCursor::systemCursor(Qt::ArrowCursor));
- else
- qwsServerPrivate->nextCursor = QWSCursor::systemCursor(Qt::ArrowCursor);
- prevWin = false;
- }
- // reset prevWin
- if (win && !prevWin)
- prevWin = true;
-#endif
-
- if ((state&btnMask) && !qwsServerPrivate->mouseGrabbing) {
- qwsServerPrivate->mouseGrabber = win;
- if (imMouse)
- qwsServerPrivate->inputMethodMouseGrabbed = true;
- }
- if (!(state&btnMask))
- qwsServerPrivate->inputMethodMouseGrabbed = false;
-
- event.simpleData.x_root=pos.x();
- event.simpleData.y_root=pos.y();
- event.simpleData.state=state | qws_keyModifiers;
- event.simpleData.delta = wheel;
- event.simpleData.time=qwsServerPrivate->timer.elapsed();
-
- static int oldstate = 0;
-
-#ifndef QT_NO_QWS_INPUTMETHODS
- //tell the input method if we click on a different window that is not IM transparent
- bool isPress = state > oldstate;
- if (isPress && !imMouse && current_IM && current_IM_winId != -1)
- current_IM->mouseHandler(-1, QWSServer::MouseOutside);
-#endif
-
- if (serverClient)
- serverClient->sendEvent(&event);
- if (winClient && winClient != serverClient)
- winClient->sendEvent(&event);
-
- if ( !imMouse ) {
- // Make sure that if we leave a window, that window gets one last mouse
- // event so that it knows the mouse has left.
- QWSClient *oldClient = qwsServer->d_func()->cursorClient;
- if (oldClient && oldClient != winClient && oldClient != serverClient) {
- event.simpleData.state = oldstate | qws_keyModifiers;
- oldClient->sendEvent(&event);
- }
- }
-
- oldstate = state;
- if ( !imMouse )
- qwsServer->d_func()->cursorClient = winClient;
-
- if (!(state&btnMask) && !qwsServerPrivate->mouseGrabbing)
- qwsServerPrivate->releaseMouse(qwsServerPrivate->mouseGrabber);
-}
-
-/*!
- Returns the primary mouse driver.
-
- Note that this function can only be used in the server process.
-
- \sa setMouseHandler(), openMouse(), closeMouse()
-*/
-QWSMouseHandler *QWSServer::mouseHandler()
-{
- if (qwsServerPrivate->mousehandlers.empty())
- return 0;
- return qwsServerPrivate->mousehandlers.first();
-}
-
-/*!
- \since 4.5
-
- Returns list of all mouse handlers
-
- Note that this function can only be used in the server process.
-
- \sa mouseHandler(), setMouseHandler(), openMouse(), closeMouse()
-*/
-const QList<QWSMouseHandler*>& QWSServer::mouseHandlers()
-{
- return qwsServerPrivate->mousehandlers;
-}
-
-
-// called by QWSMouseHandler constructor, not user code.
-/*!
- \fn void QWSServer::setMouseHandler(QWSMouseHandler* driver)
-
- Sets the primary mouse driver to be the given \a driver.
-
- \l{Qt for Embedded Linux} provides several ready-made mouse drivers, and
- custom drivers are typically added using Qt's plugin
- mechanism. See the \l{Qt for Embedded Linux Pointer Handling} documentation
- for details.
-
- Note that this function can only be used in the server process.
-
- \sa mouseHandler(), setDefaultMouse()
-*/
-void QWSServer::setMouseHandler(QWSMouseHandler* mh)
-{
- if (!mh)
- return;
- qwsServerPrivate->mousehandlers.removeAll(mh);
- qwsServerPrivate->mousehandlers.prepend(mh);
-}
-
-/*!
- \internal
- \obsolete
- Caller owns data in list, and must delete contents
-*/
-QList<QWSInternalWindowInfo*> * QWSServer::windowList()
-{
- QList<QWSInternalWindowInfo*> * ret=new QList<QWSInternalWindowInfo*>;
- for (int i=0; i < qwsServerPrivate->windows.size(); ++i) {
- QWSWindow *window = qwsServerPrivate->windows.at(i);
- QWSInternalWindowInfo * qwi=new QWSInternalWindowInfo();
- qwi->winid=window->winId();
- qwi->clientid=window->client()->clientId();
- ret->append(qwi);
- }
- return ret;
-}
-
-#ifndef QT_NO_COP
-/*!
- \internal
-*/
-void QWSServerPrivate::sendQCopEvent(QWSClient *c, const QString &ch,
- const QString &msg, const QByteArray &data,
- bool response)
-{
- Q_ASSERT(c);
-
- QWSQCopMessageEvent event;
- event.channel = ch.toLatin1();
- event.message = msg.toLatin1();
- event.data = data;
- event.simpleData.is_response = response;
- event.simpleData.lchannel = ch.length();
- event.simpleData.lmessage = msg.length();
- event.simpleData.ldata = data.size();
- int l = event.simpleData.lchannel + event.simpleData.lmessage +
- event.simpleData.ldata;
-
- // combine channel, message and data into one block of raw bytes
- char *tmp = new char [l];
- char *d = tmp;
- memcpy(d, event.channel.constData(), event.simpleData.lchannel);
- d += event.simpleData.lchannel;
- memcpy(d, event.message.constData(), event.simpleData.lmessage);
- d += event.simpleData.lmessage;
- memcpy(d, data.constData(), event.simpleData.ldata);
-
- event.setDataDirect(tmp, l);
-
- c->sendEvent(&event);
-}
-#endif
-
-/*!
- \fn QWSWindow *QWSServer::windowAt(const QPoint& position)
-
- Returns the window containing the given \a position.
-
- Note that if there is no window under the specified point this
- function returns 0.
-
- \sa clientWindows(), instance()
-*/
-QWSWindow *QWSServer::windowAt(const QPoint& pos)
-{
- Q_D(QWSServer);
- for (int i=0; i<d->windows.size(); ++i) {
- QWSWindow* w = d->windows.at(i);
- if (w->allocatedRegion().contains(pos))
- return w;
- }
- return 0;
-}
-
-#ifndef QT_NO_QWS_KEYBOARD
-static int keyUnicode(int keycode)
-{
- int code = 0xffff;
-
- if (keycode >= Qt::Key_A && keycode <= Qt::Key_Z)
- code = keycode - Qt::Key_A + 'a';
- else if (keycode >= Qt::Key_0 && keycode <= Qt::Key_9)
- code = keycode - Qt::Key_0 + '0';
-
- return code;
-}
-#endif
-
-/*!
- Sends the given key event. The key is identified by its \a unicode
- value and the given \a keycode, \a modifiers, \a isPress and \a
- autoRepeat parameters.
-
- Use this function to send key events generated by "virtual
- keyboards" (note that the processKeyEvent() function is
- impelemented using this function).
-
- The \a keycode parameter is the Qt keycode value as defined by the
- Qt::Key enum. The \a modifiers is an OR combination of
- Qt::KeyboardModifier values, indicating whether \gui
- Shift/Alt/Ctrl keys are pressed. The \a isPress parameter is true
- if the event is a key press event and \a autoRepeat is true if the
- event is caused by an auto-repeat mechanism and not an actual key
- press.
-
- Note that this function can only be used in the server process.
-
- \sa processKeyEvent(), {Qt for Embedded Linux Character Input}
-*/
-void QWSServer::sendKeyEvent(int unicode, int keycode, Qt::KeyboardModifiers modifiers,
- bool isPress, bool autoRepeat)
-{
- qws_keyModifiers = modifiers;
-
- if (isPress) {
- if (keycode != Qt::Key_F34 && keycode != Qt::Key_F35)
- qwsServerPrivate->_q_screenSaverWake();
- }
-
-#ifndef QT_NO_QWS_INPUTMETHODS
-
- if (!current_IM || !current_IM->filter(unicode, keycode, modifiers, isPress, autoRepeat))
- QWSServerPrivate::sendKeyEventUnfiltered(unicode, keycode, modifiers, isPress, autoRepeat);
-#else
- QWSServerPrivate::sendKeyEventUnfiltered(unicode, keycode, modifiers, isPress, autoRepeat);
-#endif
-}
-
-void QWSServerPrivate::sendKeyEventUnfiltered(int unicode, int keycode, Qt::KeyboardModifiers modifiers,
- bool isPress, bool autoRepeat)
-{
-
- QWSKeyEvent event;
- QWSWindow *win = keyboardGrabber ? keyboardGrabber :
- qwsServerPrivate->focusw;
-
- event.simpleData.window = win ? win->winId() : 0;
-
- event.simpleData.unicode =
-#ifndef QT_NO_QWS_KEYBOARD
- unicode < 0 ? keyUnicode(keycode) :
-#endif
- unicode;
- event.simpleData.keycode = keycode;
- event.simpleData.modifiers = modifiers;
- event.simpleData.is_press = isPress;
- event.simpleData.is_auto_repeat = autoRepeat;
-
- QWSClient *serverClient = qwsServerPrivate->clientMap.value(-1);
- QWSClient *winClient = win ? win->client() : 0;
- if (serverClient)
- serverClient->sendEvent(&event);
- if (winClient && winClient != serverClient)
- winClient->sendEvent(&event);
-}
-
-/*!
- \internal
-*/
-void QWSServer::beginDisplayReconfigure()
-{
- qwsServer->enablePainting(false);
-#ifndef QT_NO_QWS_CURSOR
- if (qt_screencursor)
- qt_screencursor->hide();
-#endif
- QWSDisplay::grab(true);
- qt_screen->disconnect();
-}
-
-/*!
- \internal
-*/
-void QWSServer::endDisplayReconfigure()
-{
- qt_screen->connect(QString());
- qwsServerPrivate->swidth = qt_screen->deviceWidth();
- qwsServerPrivate->sheight = qt_screen->deviceHeight();
-
- QWSDisplay::ungrab();
-#ifndef QT_NO_QWS_CURSOR
- if (qt_screencursor)
- qt_screencursor->show();
-#endif
- QApplicationPrivate *ap = QApplicationPrivate::instance();
- ap->setMaxWindowRect(qt_screen, 0,
- QRect(0, 0, qt_screen->width(), qt_screen->height()));
- QSize olds = qApp->desktop()->size();
- qApp->desktop()->resize(qt_screen->width(), qt_screen->height());
- qApp->postEvent(qApp->desktop(), new QResizeEvent(qApp->desktop()->size(), olds));
- qwsServer->enablePainting(true);
- qwsServer->refresh();
- qDebug("Desktop size: %dx%d", qApp->desktop()->width(), qApp->desktop()->height());
-}
-
-void QWSServerPrivate::resetEngine()
-{
-#ifndef QT_NO_QWS_CURSOR
- if (!qt_screencursor)
- return;
- qt_screencursor->hide();
- qt_screencursor->show();
-#endif
-}
-
-
-#ifndef QT_NO_QWS_CURSOR
-/*!
- \fn void QWSServer::setCursorVisible(bool visible)
-
- Shows the cursor if \a visible is true: otherwise the cursor is
- hidden.
-
- Note that this function can only be used in the server process.
-
- \sa isCursorVisible()
-*/
-void QWSServer::setCursorVisible(bool vis)
-{
- if (qwsServerPrivate && qwsServerPrivate->haveviscurs != vis) {
- QWSCursor* c = qwsServerPrivate->cursor;
- qwsServerPrivate->setCursor(QWSCursor::systemCursor(Qt::BlankCursor));
- qwsServerPrivate->haveviscurs = vis;
- qwsServerPrivate->setCursor(c);
- }
-}
-
-/*!
- Returns true if the cursor is visible; otherwise returns false.
-
- Note that this function can only be used in the server process.
-
- \sa setCursorVisible()
-*/
-bool QWSServer::isCursorVisible()
-{
- return qwsServerPrivate ? qwsServerPrivate->haveviscurs : true;
-}
-#endif
-
-#ifndef QT_NO_QWS_INPUTMETHODS
-
-
-/*!
- \fn void QWSServer::sendIMEvent(const QInputMethodEvent *event)
-
- Sends the given input method \a event.
-
- The \c QInputMethodEvent class is derived from QWSEvent, i.e., it
- is a QWSEvent object of the QWSEvent::IMEvent type.
-
- If there is a window actively composing the preedit string, the
- event is sent to that window. Otherwise, the event is sent to the
- window currently in focus.
-
- \sa sendIMQuery(), QWSInputMethod::sendEvent()
-*/
-void QWSServer::sendIMEvent(const QInputMethodEvent *ime)
-{
- QWSIMEvent event;
-
- QWSWindow *win = keyboardGrabber ? keyboardGrabber :
- qwsServerPrivate->focusw;
-
- //if currently composing then event must go to the composing window
-
- if (current_IM_composing_win)
- win = current_IM_composing_win;
-
- event.simpleData.window = win ? win->winId() : 0;
- event.simpleData.replaceFrom = ime->replacementStart();;
- event.simpleData.replaceLength = ime->replacementLength();
-
- QBuffer buffer;
- buffer.open(QIODevice::WriteOnly);
- QDataStream out(&buffer);
-
- out << ime->preeditString();
- out << ime->commitString();
-
- const QList<QInputMethodEvent::Attribute> &attributes = ime->attributes();
- for (int i = 0; i < attributes.count(); ++i) {
- const QInputMethodEvent::Attribute &a = attributes.at(i);
- out << a.type << a.start << a.length << a.value;
- }
- event.setData(buffer.data(), buffer.size());
- QWSClient *serverClient = qwsServerPrivate->clientMap.value(-1);
- if (serverClient)
- serverClient->sendEvent(&event);
- if (win && win->client() && win->client() != serverClient)
- win->client()->sendEvent(&event);
-
- current_IM_composing_win = ime->preeditString().isEmpty() ? 0 : win;
- current_IM_winId = win ? win->winId() : 0;
-}
-
-
-/*!
- Sends an input method query for the given \a property.
-
- To receive responses to input method queries, the virtual
- QWSInputMethod::queryResponse() function must be reimplemented in
- a QWSInputMethod subclass that is activated using the
- setCurrentInputMethod() function.
-
- \sa sendIMEvent(), setCurrentInputMethod()
-*/
-void QWSServer::sendIMQuery(int property)
-{
- QWSIMQueryEvent event;
-
- QWSWindow *win = keyboardGrabber ? keyboardGrabber :
- qwsServerPrivate->focusw;
- if (current_IM_composing_win)
- win = current_IM_composing_win;
-
- event.simpleData.window = win ? win->winId() : 0;
- event.simpleData.property = property;
- if (win && win->client())
- win->client()->sendEvent(&event);
-}
-
-
-
-/*!
- \fn void QWSServer::setCurrentInputMethod(QWSInputMethod *method)
-
- Sets the current input method to be the given \a method.
-
- Note that this function can only be used in the server process.
-
- \sa sendIMQuery(), sendIMEvent()
-*/
-void QWSServer::setCurrentInputMethod(QWSInputMethod *im)
-{
- if (current_IM)
- current_IM->reset(); //??? send an update event instead ?
- current_IM = im;
-}
-
-/*!
- \fn static void QWSServer::resetInputMethod()
-
- \internal
-*/
-
-#endif //QT_NO_QWS_INPUTMETHODS
-
-#ifndef QT_NO_QWS_PROPERTIES
-/*!
- \internal
-*/
-void QWSServer::sendPropertyNotifyEvent(int property, int state)
-{
- Q_D(QWSServer);
- QWSServerPrivate::ClientIterator it = d->clientMap.begin();
- while (it != d->clientMap.end()) {
- QWSClient *cl = *it;
- ++it;
- cl->sendPropertyNotifyEvent(property, state);
- }
-}
-#endif
-
-void QWSServerPrivate::invokeIdentify(const QWSIdentifyCommand *cmd, QWSClient *client)
-{
- client->setIdentity(cmd->id);
-#ifndef QT_NO_QWS_MULTIPROCESS
- if (client->clientId() > 0)
- client->d_func()->setLockId(cmd->simpleData.idLock);
-#endif
-}
-
-void QWSServerPrivate::invokeCreate(QWSCreateCommand *cmd, QWSClient *client)
-{
- QWSCreationEvent event;
- event.simpleData.objectid = get_object_id(cmd->count);
- event.simpleData.count = cmd->count;
- client->sendEvent(&event);
-}
-
-void QWSServerPrivate::invokeRegionName(const QWSRegionNameCommand *cmd, QWSClient *client)
-{
- Q_Q(QWSServer);
- QWSWindow* changingw = findWindow(cmd->simpleData.windowid, client);
- if (changingw && (changingw->name() != cmd->name || changingw->caption() !=cmd->caption)) {
- changingw->setName(cmd->name);
- changingw->setCaption(cmd->caption);
- emit q->windowEvent(changingw, QWSServer::Name);
- }
-}
-
-void QWSServerPrivate::invokeRegion(QWSRegionCommand *cmd, QWSClient *client)
-{
-#ifdef QWS_REGION_DEBUG
- qDebug("QWSServer::invokeRegion %d rects (%d)",
- cmd->simpleData.nrectangles, cmd->simpleData.windowid);
-#endif
-
- QWSWindow* changingw = findWindow(cmd->simpleData.windowid, 0);
- if (!changingw) {
- qWarning("Invalid window handle %08x",cmd->simpleData.windowid);
- return;
- }
- if (!changingw->forClient(client)) {
- qWarning("Disabled: clients changing other client's window region");
- return;
- }
-
- request_region(cmd->simpleData.windowid, cmd->surfaceKey, cmd->surfaceData,
- cmd->region);
-}
-
-void QWSServerPrivate::invokeRegionMove(const QWSRegionMoveCommand *cmd, QWSClient *client)
-{
- Q_Q(QWSServer);
- QWSWindow* changingw = findWindow(cmd->simpleData.windowid, 0);
- if (!changingw) {
- qWarning("invokeRegionMove: Invalid window handle %d",cmd->simpleData.windowid);
- return;
- }
- if (!changingw->forClient(client)) {
- qWarning("Disabled: clients changing other client's window region");
- return;
- }
-
-// changingw->setNeedAck(true);
- moveWindowRegion(changingw, cmd->simpleData.dx, cmd->simpleData.dy);
- emit q->windowEvent(changingw, QWSServer::Geometry);
-}
-
-void QWSServerPrivate::invokeRegionDestroy(const QWSRegionDestroyCommand *cmd, QWSClient *client)
-{
- Q_Q(QWSServer);
- QWSWindow* changingw = findWindow(cmd->simpleData.windowid, 0);
- if (!changingw) {
- qWarning("invokeRegionDestroy: Invalid window handle %d",cmd->simpleData.windowid);
- return;
- }
- if (!changingw->forClient(client)) {
- qWarning("Disabled: clients changing other client's window region");
- return;
- }
-
- setWindowRegion(changingw, QRegion());
-// rgnMan->remove(changingw->allocationIndex());
- for (int i = 0; i < windows.size(); ++i) {
- if (windows.at(i) == changingw) {
- windows.takeAt(i);
- if (i < nReserved)
- --nReserved;
- break;
- }
- }
-
- handleWindowClose(changingw);
-#ifndef QT_NO_QWS_PROPERTIES
- propertyManager.removeProperties(changingw->winId());
-#endif
- emit q->windowEvent(changingw, QWSServer::Destroy);
- delete changingw;
-}
-
-void QWSServerPrivate::invokeSetFocus(const QWSRequestFocusCommand *cmd, QWSClient *client)
-{
- int winId = cmd->simpleData.windowid;
- int gain = cmd->simpleData.flag;
-
- if (gain != 0 && gain != 1) {
- qWarning("Only 0(lose) and 1(gain) supported");
- return;
- }
-
- QWSWindow* changingw = findWindow(winId, 0);
- if (!changingw)
- return;
-
- if (!changingw->forClient(client)) {
- qWarning("Disabled: clients changing other client's focus");
- return;
- }
-
- setFocus(changingw, gain);
-}
-
-void QWSServerPrivate::setFocus(QWSWindow* changingw, bool gain)
-{
- Q_Q(QWSServer);
-#ifndef QT_NO_QWS_INPUTMETHODS
- /*
- This is the logic:
- QWSWindow *loser = 0;
- if (gain && focusw != changingw)
- loser = focusw;
- else if (!gain && focusw == changingw)
- loser = focusw;
- But these five lines can be reduced to one:
- */
- if (current_IM) {
- QWSWindow *loser = (!gain == (focusw==changingw)) ? focusw : 0;
- if (loser && loser->winId() == current_IM_winId)
- current_IM->updateHandler(QWSInputMethod::FocusOut);
- }
-#endif
- if (gain) {
- if (focusw != changingw) {
- if (focusw) focusw->focus(0);
- focusw = changingw;
- focusw->focus(1);
- emit q->windowEvent(focusw, QWSServer::Active);
- }
- } else if (focusw == changingw) {
- if (changingw->client())
- changingw->focus(0);
- focusw = 0;
- // pass focus to window which most recently got it...
- QWSWindow* bestw=0;
- for (int i=0; i<windows.size(); ++i) {
- QWSWindow* w = windows.at(i);
- if (w != changingw && !w->hidden() &&
- (!bestw || bestw->focusPriority() < w->focusPriority()))
- bestw = w;
- }
- if (!bestw && changingw->focusPriority()) { // accept focus back?
- bestw = changingw; // must be the only one
- }
- focusw = bestw;
- if (focusw) {
- focusw->focus(1);
- emit q->windowEvent(focusw, QWSServer::Active);
- }
- }
-}
-
-
-
-void QWSServerPrivate::invokeSetOpacity(const QWSSetOpacityCommand *cmd, QWSClient *client)
-{
- Q_UNUSED( client );
- int winId = cmd->simpleData.windowid;
- int opacity = cmd->simpleData.opacity;
-
- QWSWindow* changingw = findWindow(winId, 0);
-
- if (!changingw) {
- qWarning("invokeSetOpacity: Invalid window handle %d", winId);
- return;
- }
-
- int altitude = windows.indexOf(changingw);
- const bool wasOpaque = changingw->isOpaque();
- changingw->_opacity = opacity;
- if (wasOpaque != changingw->isOpaque())
- update_regions();
- exposeRegion(changingw->allocatedRegion(), altitude);
-}
-
-void QWSServerPrivate::invokeSetAltitude(const QWSChangeAltitudeCommand *cmd,
- QWSClient *client)
-{
- Q_UNUSED(client);
-
- int winId = cmd->simpleData.windowid;
- int alt = cmd->simpleData.altitude;
- bool fixed = cmd->simpleData.fixed;
-#if 0
- qDebug("QWSServer::invokeSetAltitude winId %d alt %d)", winId, alt);
-#endif
-
- if (alt < -1 || alt > 1) {
- qWarning("QWSServer::invokeSetAltitude Only lower, raise and stays-on-top supported");
- return;
- }
-
- QWSWindow* changingw = findWindow(winId, 0);
- if (!changingw) {
- qWarning("invokeSetAltitude: Invalid window handle %d", winId);
- return;
- }
-
- if (fixed && alt >= 1) {
- changingw->onTop = true;
- }
- if (alt == QWSChangeAltitudeCommand::Lower)
- changingw->lower();
- else
- changingw->raise();
-
-// if (!changingw->forClient(client)) {
-// refresh();
-// }
-}
-
-#ifndef QT_NO_QWS_PROPERTIES
-void QWSServerPrivate::invokeAddProperty(QWSAddPropertyCommand *cmd)
-{
- propertyManager.addProperty(cmd->simpleData.windowid, cmd->simpleData.property);
-}
-
-void QWSServerPrivate::invokeSetProperty(QWSSetPropertyCommand *cmd)
-{
- Q_Q(QWSServer);
- if (propertyManager.setProperty(cmd->simpleData.windowid,
- cmd->simpleData.property,
- cmd->simpleData.mode,
- cmd->data,
- cmd->rawLen)) {
- q->sendPropertyNotifyEvent(cmd->simpleData.property,
- QWSPropertyNotifyEvent::PropertyNewValue);
-#ifndef QT_NO_QWS_INPUTMETHODS
- if (cmd->simpleData.property == QT_QWS_PROPERTY_MARKEDTEXT) {
- QString s((const QChar*)cmd->data, cmd->rawLen/2);
- emit q->markedText(s);
- }
-#endif
- }
-}
-
-void QWSServerPrivate::invokeRemoveProperty(QWSRemovePropertyCommand *cmd)
-{
- Q_Q(QWSServer);
- if (propertyManager.removeProperty(cmd->simpleData.windowid,
- cmd->simpleData.property)) {
- q->sendPropertyNotifyEvent(cmd->simpleData.property,
- QWSPropertyNotifyEvent::PropertyDeleted);
- }
-}
-
-
-bool QWSServerPrivate:: get_property(int winId, int property, const char *&data, int &len)
-{
- return propertyManager.getProperty(winId, property, data, len);
-}
-
-
-void QWSServerPrivate::invokeGetProperty(QWSGetPropertyCommand *cmd, QWSClient *client)
-{
- const char *data;
- int len;
-
- if (propertyManager.getProperty(cmd->simpleData.windowid,
- cmd->simpleData.property,
- data, len)) {
- client->sendPropertyReplyEvent(cmd->simpleData.property, len, data);
- } else {
- client->sendPropertyReplyEvent(cmd->simpleData.property, -1, 0);
- }
-}
-#endif //QT_NO_QWS_PROPERTIES
-
-void QWSServerPrivate::invokeSetSelectionOwner(QWSSetSelectionOwnerCommand *cmd)
-{
- qDebug("QWSServer::invokeSetSelectionOwner");
-
- SelectionOwner so;
- so.windowid = cmd->simpleData.windowid;
- so.time.set(cmd->simpleData.hour, cmd->simpleData.minute,
- cmd->simpleData.sec, cmd->simpleData.ms);
-
- if (selectionOwner.windowid != -1) {
- QWSWindow *win = findWindow(selectionOwner.windowid, 0);
- if (win)
- win->client()->sendSelectionClearEvent(selectionOwner.windowid);
- else
- qDebug("couldn't find window %d", selectionOwner.windowid);
- }
-
- selectionOwner = so;
-}
-
-void QWSServerPrivate::invokeConvertSelection(QWSConvertSelectionCommand *cmd)
-{
- qDebug("QWSServer::invokeConvertSelection");
-
- if (selectionOwner.windowid != -1) {
- QWSWindow *win = findWindow(selectionOwner.windowid, 0);
- if (win)
- win->client()->sendSelectionRequestEvent(cmd, selectionOwner.windowid);
- else
- qDebug("couldn't find window %d", selectionOwner.windowid);
- }
-}
-
-#ifndef QT_NO_QWS_CURSOR
-void QWSServerPrivate::invokeDefineCursor(QWSDefineCursorCommand *cmd, QWSClient *client)
-{
- if (cmd->simpleData.height > 64 || cmd->simpleData.width > 64) {
- qDebug("Cannot define cursor size > 64x64");
- return;
- }
-
- delete client->cursors.take(cmd->simpleData.id);
-
- int dataLen = cmd->simpleData.height * ((cmd->simpleData.width+7) / 8);
-
- if (dataLen > 0 && cmd->data) {
- QWSCursor *curs = new QWSCursor(cmd->data, cmd->data + dataLen,
- cmd->simpleData.width, cmd->simpleData.height,
- cmd->simpleData.hotX, cmd->simpleData.hotY);
- client->cursors.insert(cmd->simpleData.id, curs);
- }
-}
-
-void QWSServerPrivate::invokeSelectCursor(QWSSelectCursorCommand *cmd, QWSClient *client)
-{
- int id = cmd->simpleData.id;
- QWSCursor *curs = 0;
- if (id <= Qt::LastCursor) {
- curs = QWSCursor::systemCursor(id);
- }
- else {
- QWSCursorMap cursMap = client->cursors;
- QWSCursorMap::Iterator it = cursMap.find(id);
- if (it != cursMap.end()) {
- curs = it.value();
- }
- }
- if (curs == 0) {
- curs = QWSCursor::systemCursor(Qt::ArrowCursor);
- }
-
- QWSWindow* win = findWindow(cmd->simpleData.windowid, 0);
- if (mouseGrabber) {
- // If the mouse is being grabbed, we don't want just anyone to
- // be able to change the cursor. We do want the cursor to be set
- // correctly once mouse grabbing is stopped though.
- if (win != mouseGrabber)
- nextCursor = curs;
- else
- setCursor(curs);
- } else if (win && win->allocatedRegion().contains(QWSServer::mousePosition)) { //##################### cursor
- // A non-grabbing window can only set the cursor shape if the
- // cursor is within its allocated region.
- setCursor(curs);
- }
-}
-
-void QWSServerPrivate::invokePositionCursor(QWSPositionCursorCommand *cmd, QWSClient *)
-{
- Q_Q(QWSServer);
- QPoint newPos(cmd->simpleData.newX, cmd->simpleData.newY);
- if (newPos != QWSServer::mousePosition)
- q->sendMouseEvent(newPos, qwsServer->d_func()->mouseState);
-}
-#endif
-
-void QWSServerPrivate::invokeGrabMouse(QWSGrabMouseCommand *cmd, QWSClient *client)
-{
- QWSWindow* win = findWindow(cmd->simpleData.windowid, 0);
- if (!win)
- return;
-
- if (cmd->simpleData.grab) {
- if (!mouseGrabber || mouseGrabber->client() == client) {
- mouseGrabbing = true;
- mouseGrabber = win;
- }
- } else {
- releaseMouse(mouseGrabber);
- }
-}
-
-void QWSServerPrivate::invokeGrabKeyboard(QWSGrabKeyboardCommand *cmd, QWSClient *client)
-{
- QWSWindow* win = findWindow(cmd->simpleData.windowid, 0);
- if (!win)
- return;
-
- if (cmd->simpleData.grab) {
- if (!keyboardGrabber || (keyboardGrabber->client() == client)) {
- keyboardGrabbing = true;
- keyboardGrabber = win;
- }
- } else {
- releaseKeyboard(keyboardGrabber);
- }
-}
-
-#if !defined(QT_NO_SOUND)
-void QWSServerPrivate::invokePlaySound(QWSPlaySoundCommand *cmd, QWSClient *)
-{
-#if !defined(QT_EXTERNAL_SOUND_SERVER) && !defined(Q_OS_DARWIN)
- soundserver->playFile( 1, cmd->filename );
-#else
- Q_UNUSED(cmd);
-#endif
-}
-#endif
-
-#ifndef QT_NO_COP
-void QWSServerPrivate::invokeRegisterChannel(QWSQCopRegisterChannelCommand *cmd,
- QWSClient *client)
-{
- // QCopChannel will force us to emit the newChannel signal if this channel
- // didn't already exist.
- QCopChannel::registerChannel(cmd->channel, client);
-}
-
-void QWSServerPrivate::invokeQCopSend(QWSQCopSendCommand *cmd, QWSClient *client)
-{
- QCopChannel::answer(client, cmd->channel, cmd->message, cmd->data);
-}
-
-#endif
-
-#ifndef QT_NO_QWS_INPUTMETHODS
-void QWSServer::resetInputMethod()
-{
- if (current_IM && qwsServer) {
- current_IM->reset();
- }
-}
-
-void QWSServerPrivate::invokeIMResponse(const QWSIMResponseCommand *cmd,
- QWSClient *)
-{
- if (current_IM)
- current_IM->queryResponse(cmd->simpleData.property, cmd->result);
-}
-
-void QWSServerPrivate::invokeIMUpdate(const QWSIMUpdateCommand *cmd,
- QWSClient *)
-{
- if (cmd->simpleData.type == QWSInputMethod::FocusIn)
- current_IM_winId = cmd->simpleData.windowid;
-
- if (current_IM && (current_IM_winId == cmd->simpleData.windowid || cmd->simpleData.windowid == -1))
- current_IM->updateHandler(cmd->simpleData.type);
-}
-
-#endif
-
-void QWSServerPrivate::invokeFont(const QWSFontCommand *cmd, QWSClient *client)
-{
- QWSClientPrivate *priv = client->d_func();
- if (cmd->simpleData.type == QWSFontCommand::StartedUsingFont) {
- referenceFont(priv, cmd->fontName);
- } else if (cmd->simpleData.type == QWSFontCommand::StoppedUsingFont) {
- dereferenceFont(priv, cmd->fontName);
- }
-}
-
-void QWSServerPrivate::invokeRepaintRegion(QWSRepaintRegionCommand * cmd,
- QWSClient *)
-{
- QRegion r;
- r.setRects(cmd->rectangles,cmd->simpleData.nrectangles);
- repaint_region(cmd->simpleData.windowid, cmd->simpleData.windowFlags, cmd->simpleData.opaque, r);
-}
-
-#ifndef QT_NO_QWSEMBEDWIDGET
-void QWSServerPrivate::invokeEmbed(QWSEmbedCommand *cmd, QWSClient *client)
-{
- // Should find these two windows in a single loop
- QWSWindow *embedder = findWindow(cmd->simpleData.embedder, client);
- QWSWindow *embedded = findWindow(cmd->simpleData.embedded);
-
- if (!embedder) {
- qWarning("QWSServer: Embed command from window %i failed: No such id.",
- static_cast<int>(cmd->simpleData.embedder));
- return;
- }
-
- if (!embedded) {
- qWarning("QWSServer: Embed command on window %i failed: No such id.",
- static_cast<int>(cmd->simpleData.embedded));
- return;
- }
-
- switch (cmd->simpleData.type) {
- case QWSEmbedEvent::StartEmbed:
- embedder->startEmbed(embedded);
- windows.removeAll(embedded);
- windows.insert(windows.indexOf(embedder), embedded);
- break;
- case QWSEmbedEvent::StopEmbed:
- embedder->stopEmbed(embedded);
- break;
- case QWSEmbedEvent::Region:
- break;
- }
-
- embedded->client()->sendEmbedEvent(embedded->winId(),
- cmd->simpleData.type, cmd->region);
- const QRegion oldAllocated = embedded->allocatedRegion();
- update_regions();
- exposeRegion(oldAllocated - embedded->allocatedRegion(),
- windows.indexOf(embedded));
-}
-#endif // QT_NO_QWSEMBEDWIDGET
-
-void QWSServerPrivate::invokeScreenTransform(const QWSScreenTransformCommand *cmd,
- QWSClient *client)
-{
- Q_UNUSED(client);
-
- QWSScreenTransformationEvent event;
- event.simpleData.screen = cmd->simpleData.screen;
- event.simpleData.transformation = cmd->simpleData.transformation;
-
- QMap<int, QWSClient*>::const_iterator it = clientMap.constBegin();
- for (; it != clientMap.constEnd(); ++it)
- (*it)->sendEvent(&event);
-}
-
-QWSWindow* QWSServerPrivate::newWindow(int id, QWSClient* client)
-{
- Q_Q(QWSServer);
- // Make a new window, put it on top.
- QWSWindow* w = new QWSWindow(id,client);
-
- // insert after "stays on top" windows
- bool added = false;
- for (int i = nReserved; i < windows.size(); ++i) {
- QWSWindow *win = windows.at(i);
- if (!win->onTop) {
- windows.insert(i, w);
- added = true;
- break;
- }
- }
- if (!added)
- windows.append(w);
- emit q->windowEvent(w, QWSServer::Create);
- return w;
-}
-
-QWSWindow* QWSServerPrivate::findWindow(int windowid, QWSClient* client)
-{
- for (int i=0; i<windows.size(); ++i) {
- QWSWindow* w = windows.at(i);
- if (w->winId() == windowid)
- return w;
- }
- if (client)
- return newWindow(windowid,client);
- else
- return 0;
-}
-
-void QWSServerPrivate::raiseWindow(QWSWindow *changingw, int /*alt*/)
-{
- Q_Q(QWSServer);
- if (changingw == windows.first())
- return;
- QWSWindow::State oldstate = changingw->d->state;
- changingw->d->state = QWSWindow::Raising;
- // Expose regions previously overlapped by transparent windows
- const QRegion bound = changingw->allocatedRegion();
- QRegion expose;
- int windowPos = 0;
-
- //change position in list:
- for (int i = 0; i < windows.size(); ++i) {
- QWSWindow *w = windows.at(i);
- if (w == changingw) {
- windowPos = i;
- windows.takeAt(i);
- break;
- }
- if (!w->isOpaque())
- expose += (w->allocatedRegion() & bound);
- }
-
- bool onTop = changingw->onTop;
-
-#ifndef QT_NO_QWSEMBEDWIDGET
- // an embedded window is on top if the embedder is on top
- QWSWindow *embedder = changingw->d->embedder;
- while (!onTop && embedder) {
- onTop = embedder->onTop;
- embedder = embedder->d->embedder;
- }
-#endif
-
- int newPos = -1;
- if (onTop) {
- windows.insert(nReserved, changingw);
- newPos = nReserved;
- } else {
- // insert after "stays on top" windows
- bool in = false;
- for (int i = nReserved; i < windows.size(); ++i) {
- QWSWindow *w = windows.at(i);
- if (!w->onTop) {
- windows.insert(i, changingw);
- in = true;
- newPos = i;
- break;
- }
- }
- if (!in) {
- windows.append(changingw);
- newPos = windows.size()-1;
- }
- }
-
- if (windowPos != newPos) {
- update_regions();
- if (!expose.isEmpty())
- exposeRegion(expose, newPos);
- }
- changingw->d->state = oldstate;
- emit q->windowEvent(changingw, QWSServer::Raise);
-}
-
-void QWSServerPrivate::lowerWindow(QWSWindow *changingw, int /*alt*/)
-{
- Q_Q(QWSServer);
- if (changingw == windows.last())
- return;
- QWSWindow::State oldstate = changingw->d->state;
- changingw->d->state = QWSWindow::Lowering;
-
- int i = windows.indexOf(changingw);
- int newIdx = windows.size()-1;
- windows.move(i, newIdx);
-
- const QRegion bound = changingw->allocatedRegion();
-
- update_regions();
-
- // Expose regions previously overlapped by transparent window
- if (!changingw->isOpaque()) {
- QRegion expose;
- for (int j = i; j < windows.size() - 1; ++j)
- expose += (windows.at(j)->allocatedRegion() & bound);
- if (!expose.isEmpty())
- exposeRegion(expose, newIdx);
- }
-
- changingw->d->state = oldstate;
- emit q->windowEvent(changingw, QWSServer::Lower);
-}
-
-void QWSServerPrivate::update_regions()
-{
- if (disablePainting)
- return;
-
- QRegion available = QRect(0, 0, qt_screen->width(), qt_screen->height());
- QRegion transparentRegion;
-
- // only really needed if there are unbuffered surfaces...
- const bool doLock = (clientMap.size() > 1);
- if (doLock)
- QWSDisplay::grab(true);
-
- for (int i = 0; i < windows.count(); ++i) {
- QWSWindow *w = windows.at(i);
- QRegion r = (w->requested_region & available);
-
-#ifndef QT_NO_QWSEMBEDWIDGET
- // Subtract regions needed for embedded windows
- const int n = w->d->embedded.size();
- for (int i = 0; i < n; ++i)
- r -= w->d->embedded.at(i)->allocatedRegion();
-
- // Limited to the embedder region
- if (w->d->embedder)
- r &= w->d->embedder->requested_region;
-#endif // QT_NO_QWSEMBEDWIDGET
-
- QWSWindowSurface *surface = w->windowSurface();
- const bool opaque = w->isOpaque()
- && (w->d->painted || !surface || !surface->isBuffered());
-
- if (!opaque) {
- transparentRegion += r;
- } else {
- if (surface && (surface->isRegionReserved() || !surface->isBuffered()))
- r -= transparentRegion;
- available -= r;
- }
-
- if (r != w->allocatedRegion()) {
- w->setAllocatedRegion(r);
- w->client()->sendRegionEvent(w->winId(), r,
- QWSRegionEvent::Allocation);
- }
-
-#ifdef QT_QWS_CLIENTBLIT
-#ifdef QT_NO_QWS_CURSOR
- // This optimization only really works when there isn't a crazy cursor
- // wizzing around.
- QRegion directPaint = (r - transparentRegion); // in gloal coords
- if(directPaint != w->directPaintRegion()) {
- w->setDirectPaintRegion(directPaint);
- static int id = 0;
- surface->setDirectRegion(directPaint, ++id);
- w->client()->sendRegionEvent(w->winId(), directPaint,
- QWSRegionEvent::DirectPaint, id);
- }
-#endif
-#endif
- }
-
- if (doLock)
- QWSDisplay::ungrab();
-}
-
-void QWSServerPrivate::moveWindowRegion(QWSWindow *changingw, int dx, int dy)
-{
- if (!changingw)
- return;
-
- QWSWindow::State oldState = changingw->d->state;
- changingw->d->state = QWSWindow::Moving;
- const QRegion oldRegion(changingw->allocatedRegion());
- changingw->requested_region.translate(dx, dy);
-
- // hw: Even if the allocated region doesn't change, the requested region
- // region has changed and we need to send region events.
- // Resetting the allocated region to force update_regions to send events.
- changingw->setAllocatedRegion(QRegion());
- update_regions();
- const QRegion newRegion(changingw->allocatedRegion());
-
- QWSWindowSurface *surface = changingw->windowSurface();
- QRegion expose;
- if (surface)
- expose = surface->move(QPoint(dx, dy), changingw->allocatedRegion());
- else
- expose = oldRegion + newRegion;
-
- if (!changingw->d->painted && !expose.isEmpty())
- expose = oldRegion - newRegion;
-
- int idx = windows.indexOf(changingw);
- exposeRegion(expose, idx);
- changingw->d->state = oldState;
-}
-
-/*!
- Changes the requested region of window \a changingw to \a r
- If \a changingw is 0, the server's reserved region is changed.
-*/
-void QWSServerPrivate::setWindowRegion(QWSWindow* changingw, const QRegion &r)
-{
- if (!changingw) {
- qWarning("Not implemented in this release");
- return;
- }
-
- if (changingw->requested_region == r)
- return;
-
- const QRegion oldRegion(changingw->allocatedRegion());
- changingw->requested_region = r;
- update_regions();
- const QRegion newRegion(changingw->allocatedRegion());
-
- int idx = windows.indexOf(changingw);
- exposeRegion(oldRegion - newRegion, idx);
-}
-
-
-void QWSServerPrivate::exposeRegion(const QRegion &r, int changing)
-{
- if (disablePainting)
- return;
-
- if (r.isEmpty())
- return;
-
- static bool initial = true;
- if (initial) {
- changing = 0;
- initial = false;
- qt_screen->exposeRegion(qt_screen->region(), changing);
- } else {
- qt_screen->exposeRegion(r, changing);
- }
-}
-
-/*!
- Closes all pointer devices (specified by the QWS_MOUSE_PROTO
- environment variable) by deleting the associated mouse drivers.
-
- \sa openMouse(), mouseHandler()
-*/
-void QWSServer::closeMouse()
-{
- Q_D(QWSServer);
- qDeleteAll(d->mousehandlers);
- d->mousehandlers.clear();
-}
-
-/*!
- Opens the mouse devices specified by the QWS_MOUSE_PROTO
- environment variable. Be advised that closeMouse() is called first
- to delete all the existing mouse handlers. This behaviour could be
- the cause of problems if you were not expecting it.
-
- \sa closeMouse(), mouseHandler()
-*/
-void QWSServer::openMouse()
-{
- Q_D(QWSServer);
- QString mice = QString::fromLatin1(qgetenv("QWS_MOUSE_PROTO"));
-#if defined(QT_QWS_CASSIOPEIA)
- if (mice.isEmpty())
- mice = QLatin1String("TPanel:/dev/tpanel");
-#endif
- if (mice.isEmpty())
- mice = *defaultMouse();
- closeMouse();
- bool needviscurs = true;
- if (mice != QLatin1String("None")) {
- const QStringList mouse = mice.split(QLatin1Char(' '));
- for (int i = mouse.size() - 1; i >= 0; --i) {
- QWSMouseHandler *handler = d->newMouseHandler(mouse.at(i));
- setMouseHandler(handler);
- /* XXX handle mouse cursor visibility sensibly
- if (!h->inherits("QCalibratedMouseHandler"))
- needviscurs = true;
- */
- }
- }
-#ifndef QT_NO_QWS_CURSOR
- setCursorVisible(needviscurs);
-#else
- Q_UNUSED(needviscurs)
-#endif
-}
-
-/*!
- Suspends pointer handling by deactivating all the mouse drivers
- registered by the QWS_MOUSE_PROTO environment variable.
-
-
- \sa resumeMouse(), QWSMouseHandler::suspend()
-*/
-void QWSServer::suspendMouse()
-{
- Q_D(QWSServer);
- for (int i=0; i < d->mousehandlers.size(); ++i)
- d->mousehandlers.at(i)->suspend();
-}
-
-/*!
- Resumes pointer handling by reactivating all the mouse drivers
- registered by the QWS_MOUSE_PROTO environment variable.
-
- \sa suspendMouse(), QWSMouseHandler::resume()
-*/
-void QWSServer::resumeMouse()
-{
- Q_D(QWSServer);
- for (int i=0; i < d->mousehandlers.size(); ++i)
- d->mousehandlers.at(i)->resume();
-}
-
-
-
-QWSMouseHandler* QWSServerPrivate::newMouseHandler(const QString& spec)
-{
- int c = spec.indexOf(QLatin1Char(':'));
- QString mouseProto;
- QString mouseDev;
- if (c >= 0) {
- mouseProto = spec.left(c);
- mouseDev = spec.mid(c+1);
- } else {
- mouseProto = spec;
- }
-
- int screen = -1;
- const QList<QRegExp> regexps = QList<QRegExp>()
- << QRegExp(QLatin1String(":screen=(\\d+)\\b"))
- << QRegExp(QLatin1String("\\bscreen=(\\d+):"));
- for (int i = 0; i < regexps.size(); ++i) {
- QRegExp regexp = regexps.at(i);
- if (regexp.indexIn(mouseDev) == -1)
- continue;
- screen = regexp.cap(1).toInt();
- mouseDev.remove(regexp.pos(0), regexp.matchedLength());
- break;
- }
-
- QWSMouseHandler *handler = 0;
- handler = QMouseDriverFactory::create(mouseProto, mouseDev);
- if (screen != -1)
- handler->setScreen(qt_screen->subScreens().at(screen));
-
- return handler;
-}
-
-#ifndef QT_NO_QWS_KEYBOARD
-
-/*!
- Closes all the keyboard devices (specified by the QWS_KEYBOARD
- environment variable) by deleting the associated keyboard
- drivers.
-
- \sa openKeyboard(), keyboardHandler()
-*/
-void QWSServer::closeKeyboard()
-{
- Q_D(QWSServer);
- qDeleteAll(d->keyboardhandlers);
- d->keyboardhandlers.clear();
-}
-
-/*!
- Returns the primary keyboard driver.
-
- Note that this function can only be used in the server process.
-
- \sa setKeyboardHandler(), openKeyboard(), closeKeyboard()
-*/
-QWSKeyboardHandler* QWSServer::keyboardHandler()
-{
- return qwsServerPrivate->keyboardhandlers.first();
-}
-
-/*!
- \fn void QWSServer::setKeyboardHandler(QWSKeyboardHandler* driver)
-
- Sets the primary keyboard driver to be the given \a driver.
-
- \l{Qt for Embedded Linux} provides several ready-made keyboard drivers, and
- custom drivers are typically added using Qt's plugin
- mechanism. See the \l{Qt for Embedded Linux Character Input} documentation
- for details.
-
- Note that this function can only be used in the server process.
-
- \sa keyboardHandler(), setDefaultKeyboard()
-*/
-void QWSServer::setKeyboardHandler(QWSKeyboardHandler* kh)
-{
- if (!kh)
- return;
- qwsServerPrivate->keyboardhandlers.removeAll(kh);
- qwsServerPrivate->keyboardhandlers.prepend(kh);
-}
-
-/*!
- Opens the keyboard devices specified by the QWS_KEYBOARD
- environment variable.
-
- \sa closeKeyboard(), keyboardHandler()
-*/
-void QWSServer::openKeyboard()
-{
- QString keyboards = QString::fromLatin1(qgetenv("QWS_KEYBOARD"));
-#if defined(QT_QWS_CASSIOPEIA)
- if (keyboards.isEmpty())
- keyboards = QLatin1String("Buttons");
-#endif
- if (keyboards.isEmpty())
- keyboards = *defaultKeyboard();
-
- closeKeyboard();
- if (keyboards == QLatin1String("None"))
- return;
-
- QString device;
- QString type;
- QStringList keyboard = keyboards.split(QLatin1Char(' '));
- for (int i = keyboard.size() - 1; i >= 0; --i) {
- const QString spec = keyboard.at(i);
- int colon=spec.indexOf(QLatin1Char(':'));
- if (colon>=0) {
- type = spec.left(colon);
- device = spec.mid(colon+1);
- } else {
- type = spec;
- device = QString();
- }
- QWSKeyboardHandler *handler = QKbdDriverFactory::create(type, device);
- setKeyboardHandler(handler);
- }
-}
-
-#endif //QT_NO_QWS_KEYBOARD
-
-QPoint QWSServer::mousePosition;
-QBrush *QWSServerPrivate::bgBrush = 0;
-
-void QWSServerPrivate::move_region(const QWSRegionMoveCommand *cmd)
-{
- QWSClient *serverClient = clientMap.value(-1);
- invokeRegionMove(cmd, serverClient);
-}
-
-void QWSServerPrivate::set_altitude(const QWSChangeAltitudeCommand *cmd)
-{
- QWSClient *serverClient = clientMap.value(-1);
- invokeSetAltitude(cmd, serverClient);
-}
-
-void QWSServerPrivate::set_opacity(const QWSSetOpacityCommand *cmd)
-{
- QWSClient *serverClient = clientMap.value(-1);
- invokeSetOpacity(cmd, serverClient);
-}
-
-
-void QWSServerPrivate::request_focus(const QWSRequestFocusCommand *cmd)
-{
- invokeSetFocus(cmd, clientMap.value(-1));
-}
-
-void QWSServerPrivate::set_identity(const QWSIdentifyCommand *cmd)
-{
- invokeIdentify(cmd, clientMap.value(-1));
-}
-
-void QWSServerPrivate::repaint_region(int wid, int windowFlags, bool opaque,
- const QRegion &region)
-{
- QWSWindow* changingw = findWindow(wid, 0);
- if (!changingw) {
- return;
- }
-
- const bool isOpaque = changingw->opaque;
- const bool wasPainted = changingw->d->painted;
- changingw->opaque = opaque;
- changingw->d->windowFlags = QFlag(windowFlags);
- changingw->d->dirtyOnScreen |= region;
- changingw->d->painted = true;
- if (isOpaque != opaque || !wasPainted)
- update_regions();
-
- int level = windows.indexOf(changingw);
- exposeRegion(region, level);
- changingw->d->dirtyOnScreen = QRegion();
-}
-
-QRegion QWSServerPrivate::reserve_region(QWSWindow *win, const QRegion &region)
-{
- QRegion r = region;
-
- int oldPos = windows.indexOf(win);
- int newPos = oldPos < nReserved ? nReserved - 1 : nReserved;
- for (int i = 0; i < nReserved; ++i) {
- if (i != oldPos) {
- QWSWindow *w = windows.at(i);
- r -= w->requested_region;
- }
- }
- windows.move(oldPos, newPos);
- nReserved = newPos + 1;
-
- return r;
-}
-
-void QWSServerPrivate::request_region(int wid, const QString &surfaceKey,
- const QByteArray &surfaceData,
- const QRegion &region)
-{
- QWSWindow *changingw = findWindow(wid, 0);
- if (!changingw)
- return;
-
- Q_Q(QWSServer);
- QWSWindow::State windowState = QWSWindow::NoState;
-
- if (region.isEmpty()) {
- windowState = QWSWindow::Hiding;
- emit q->windowEvent(changingw, QWSServer::Hide);
- }
-
- const bool wasOpaque = changingw->opaque;
-
- changingw->createSurface(surfaceKey, surfaceData);
- QWSWindowSurface *surface = changingw->windowSurface();
-
- changingw->opaque = surface->isOpaque();
-
- QRegion r;
- if (surface->isRegionReserved())
- r = reserve_region(changingw, region);
- else
- r = region;
-
- if (!region.isEmpty()) {
- if (changingw->isVisible())
- windowState = QWSWindow::ChangingGeometry;
- else
- windowState = QWSWindow::Showing;
- }
- changingw->d->state = windowState;
-
- if (!r.isEmpty() && wasOpaque != changingw->opaque && surface->isBuffered())
- changingw->requested_region = QRegion(); // XXX: force update_regions
-
- const QRegion oldAllocated = changingw->allocatedRegion();
- setWindowRegion(changingw, r);
- if (oldAllocated == changingw->allocatedRegion()) {
- // Always send region event to the requesting window even if the
- // region didn't change. This is necessary as the client will reset
- // the clip region until an event is received.
- changingw->client()->sendRegionEvent(wid, changingw->allocatedRegion(),
- QWSRegionEvent::Allocation);
- }
-
- surface->QWindowSurface::setGeometry(r.boundingRect());
-
- if (windowState == QWSWindow::Showing)
- emit q->windowEvent(changingw, QWSServer::Show);
- else if (windowState == QWSWindow::ChangingGeometry)
- emit q->windowEvent(changingw, QWSServer::Geometry);
- if (windowState == QWSWindow::Hiding) {
- handleWindowClose(changingw);
- changingw->d->state = QWSWindow::Hidden;
- changingw->d->painted = false;
- } else {
- changingw->d->state = QWSWindow::Visible;
- }
-}
-
-void QWSServerPrivate::destroy_region(const QWSRegionDestroyCommand *cmd)
-{
- invokeRegionDestroy(cmd, clientMap.value(-1));
-}
-
-void QWSServerPrivate::name_region(const QWSRegionNameCommand *cmd)
-{
- invokeRegionName(cmd, clientMap.value(-1));
-}
-
-#ifndef QT_NO_QWS_INPUTMETHODS
-void QWSServerPrivate::im_response(const QWSIMResponseCommand *cmd)
- {
- invokeIMResponse(cmd, clientMap.value(-1));
-}
-
-void QWSServerPrivate::im_update(const QWSIMUpdateCommand *cmd)
-{
- invokeIMUpdate(cmd, clientMap.value(-1));
-}
-
-void QWSServerPrivate::send_im_mouse(const QWSIMMouseCommand *cmd)
-{
- if (current_IM)
- current_IM->mouseHandler(cmd->simpleData.index, cmd->simpleData.state);
-}
-#endif
-
-void QWSServerPrivate::openDisplay()
-{
- qt_init_display();
-
-// rgnMan = qt_fbdpy->regionManager();
- swidth = qt_screen->deviceWidth();
- sheight = qt_screen->deviceHeight();
-}
-
-void QWSServerPrivate::closeDisplay()
-{
- if (qt_screen)
- qt_screen->shutdownDevice();
-}
-
-/*!
- Returns the brush used as background in the absence of obscuring
- windows.
-
- \sa setBackground()
-*/
-const QBrush &QWSServer::backgroundBrush() const
-{
- return *QWSServerPrivate::bgBrush;
-}
-
-/*!
- Sets the brush used as background in the absence of obscuring
- windows, to be the given \a brush.
-
- Note that this function can only be used in the server process.
-
- \sa backgroundBrush()
-*/
-void QWSServer::setBackground(const QBrush &brush)
-{
- if (!QWSServerPrivate::bgBrush)
- QWSServerPrivate::bgBrush = new QBrush(brush);
- else
- *QWSServerPrivate::bgBrush = brush;
- if (!qwsServer)
- return;
- qt_screen->exposeRegion(QRect(0,0,qt_screen->width(), qt_screen->height()), 0);
-}
-
-
-#ifdef QT3_SUPPORT
-/*!
- \fn void QWSServer::setDesktopBackground(const QImage &image)
-
- Sets the image used as background in the absence of obscuring
- windows, to be the given \a image.
-
- Use the setBackground() function instead.
-
- \oldcode
- QImage image;
- setDesktopBackground(image);
- \newcode
- QImage image;
- setBackground(QBrush(image));
- \endcode
-*/
-void QWSServer::setDesktopBackground(const QImage &img)
-{
- if (img.isNull())
- setBackground(Qt::NoBrush);
- else
- setBackground(QBrush(QPixmap::fromImage(img)));
-}
-
-/*!
- \fn void QWSServer::setDesktopBackground(const QColor &color)
- \overload
-
- Sets the color used as background in the absence of obscuring
- windows, to be the given \a color.
-
- Use the setBackground() function instead.
-
- \oldcode
- QColor color;
- setDesktopBackground(color);
- \newcode
- QColor color;
- setBackground(QBrush(color));
- \endcode
-*/
-void QWSServer::setDesktopBackground(const QColor &c)
-{
- setBackground(QBrush(c));
-}
-#endif //QT3_SUPPORT
-
-/*!
- \internal
- */
-void QWSServer::startup(int flags)
-{
- if (qwsServer)
- return;
- unlink(qws_qtePipeFilename().toLatin1().constData());
- (void)new QWSServer(flags);
-}
-
-/*!
- \internal
-*/
-
-void QWSServer::closedown()
-{
- QScopedPointer<QWSServer> server(qwsServer);
- qwsServer = 0;
- QT_TRY {
- unlink(qws_qtePipeFilename().toLatin1().constData());
- } QT_CATCH(const std::bad_alloc &) {
- // ### TODO - what to do when we run out of memory
- // when calling toLatin1?
- }
-}
-
-void QWSServerPrivate::emergency_cleanup()
-{
-#ifndef QT_NO_QWS_KEYBOARD
- if (qwsServer)
- qwsServer->closeKeyboard();
-#endif
-}
-
-#ifndef QT_NO_QWS_KEYBOARD
-static QList<QWSServer::KeyboardFilter*> *keyFilters = 0;
-
-/*!
- Processes the given key event. The key is identified by its \a
- unicode value and the given \a keycode, \a modifiers, \a isPress
- and \a autoRepeat parameters.
-
- The \a keycode parameter is the Qt keycode value as defined by the
- Qt::Key enum. The \a modifiers is an OR combination of
- Qt::KeyboardModifier values, indicating whether \gui
- Shift/Alt/Ctrl keys are pressed. The \a isPress parameter is true
- if the event is a key press event and \a autoRepeat is true if the
- event is caused by an auto-repeat mechanism and not an actual key
- press.
-
- This function is typically called internally by keyboard drivers.
- Note that this function can only be used in the server process.
-
- \sa sendKeyEvent(), {Qt for Embedded Linux Character Input}
-*/
-void QWSServer::processKeyEvent(int unicode, int keycode, Qt::KeyboardModifiers modifiers,
- bool isPress, bool autoRepeat)
-{
- bool block;
- // Don't block the POWER or LIGHT keys
- if ( keycode == Qt::Key_F34 || keycode == Qt::Key_F35 )
- block = false;
- else
- block = qwsServerPrivate->screensaverblockevent(KEY, qwsServerPrivate->screensaverinterval, isPress);
-
-#ifdef EVENT_BLOCK_DEBUG
- qDebug() << "processKeyEvent" << unicode << keycode << modifiers << isPress << autoRepeat << (block ? "block" : "pass");
-#endif
-
- // If we press a key and it's going to be blocked, wake up the screen
- if ( block && isPress )
- qwsServerPrivate->_q_screenSaverWake();
-
- if ( block )
- return;
-
- if (keyFilters) {
- for (int i = 0; i < keyFilters->size(); ++i) {
- QWSServer::KeyboardFilter *keyFilter = keyFilters->at(i);
- if (keyFilter->filter(unicode, keycode, modifiers, isPress, autoRepeat))
- return;
- }
- }
- sendKeyEvent(unicode, keycode, modifiers, isPress, autoRepeat);
-}
-
-/*!
- \fn void QWSServer::addKeyboardFilter(KeyboardFilter *filter)
-
- Activates the given keyboard \a filter all key events generated by
- physical keyboard drivers (i.e., events sent using the
- processKeyEvent() function).
-
- Note that the filter is not invoked for keys generated by \e
- virtual keyboard drivers (i.e., events sent using the
- sendKeyEvent() function).
-
- Note that this function can only be used in the server process.
-
- \sa removeKeyboardFilter()
-*/
-void QWSServer::addKeyboardFilter(KeyboardFilter *f)
-{
- if (!keyFilters)
- keyFilters = new QList<QWSServer::KeyboardFilter*>;
- if (f) {
- keyFilters->prepend(f);
- }
-}
-
-/*
-//#######
- We should probably obsolete the whole keyboard filter thing since
- it's not useful for input methods anyway
-
- We could do removeKeyboardFilter(KeyboardFilter *f), but
- the "remove and delete the filter" concept does not match "user
- remembers the pointer".
-*/
-
-/*!
- Removes and deletes the most recently added filter.
-
- Note that the programmer is responsible for removing each added
- keyboard filter.
-
- Note that this function can only be used in the server process.
-
- \sa addKeyboardFilter()
-*/
-void QWSServer::removeKeyboardFilter()
-{
- if (!keyFilters || keyFilters->isEmpty())
- return;
- delete keyFilters->takeAt(0);
-}
-#endif // QT_NO_QWS_KEYBOARD
-
-/*!
- \fn void QWSServer::setScreenSaverIntervals(int* intervals)
-
- Specifies the time \a intervals (in milliseconds) between the
- different levels of screen responsiveness.
-
- \l{Qt for Embedded Linux} supports multilevel screen saving, i.e., it is
- possible to specify several different levels of screen
- responsiveness by implementing the QWSScreenSaver::save()
- function. For example, you can choose to first turn off the light
- before you fully activate the screensaver. See the QWSScreenSaver
- documentation for details.
-
- Note that an interval of 0 milliseconds will turn off the
- screensaver, and that the \a intervals array must be 0-terminated.
- This function can only be used in the server process.
-
- \sa setScreenSaverInterval(), setScreenSaverBlockLevel()
-*/
-void QWSServer::setScreenSaverIntervals(int* ms)
-{
- if (!qwsServerPrivate)
- return;
-
- delete [] qwsServerPrivate->screensaverintervals;
- if (ms) {
- int* t=ms;
- int n=0;
- while (*t++) n++;
- if (n) {
- n++; // the 0
- qwsServerPrivate->screensaverintervals = new int[n];
- memcpy(qwsServerPrivate->screensaverintervals, ms, n*sizeof(int));
- } else {
- qwsServerPrivate->screensaverintervals = 0;
- }
- } else {
- qwsServerPrivate->screensaverintervals = 0;
- }
- qwsServerPrivate->screensaverinterval = 0;
-
- qwsServerPrivate->screensavertimer->stop();
- qt_screen->blank(false);
- qwsServerPrivate->_q_screenSaverWake();
-}
-
-/*!
- \fn void QWSServer::setScreenSaverInterval(int milliseconds)
-
- Sets the timeout interval for the screensaver to the specified \a
- milliseconds. To turn off the screensaver, set the timout interval
- to 0.
-
- Note that this function can only be used in the server process.
-
- \sa setScreenSaverIntervals(), setScreenSaverBlockLevel()
-*/
-void QWSServer::setScreenSaverInterval(int ms)
-{
- int v[2];
- v[0] = ms;
- v[1] = 0;
- setScreenSaverIntervals(v);
-}
-
-/*!
- Block the key or mouse event that wakes the system from level \a eventBlockLevel or higher.
- To completely disable event blocking (the default behavior), set \a eventBlockLevel to -1.
-
- The algorithm blocks the "down", "up" as well as any "repeat" events for the same key
- but will not block other key events after the initial "down" event. For mouse events, the
- algorithm blocks all mouse events until an event with no buttons pressed is received.
-
- There are 2 keys that are never blocked, Qt::Key_F34 (POWER) and Qt::Key_F35 (LIGHT).
-
- Example usage:
-
- \snippet doc/src/snippets/code/src_gui_embedded_qwindowsystem_qws.cpp 0
-
- Note that this function can only be used in the server process.
-
- \sa setScreenSaverIntervals(), setScreenSaverInterval()
-*/
-void QWSServer::setScreenSaverBlockLevel(int eventBlockLevel)
-{
- if (!qwsServerPrivate)
- return;
- qwsServerPrivate->screensavereventblocklevel = eventBlockLevel;
-#ifdef EVENT_BLOCK_DEBUG
- qDebug() << "QWSServer::setScreenSaverBlockLevel() " << eventBlockLevel;
-#endif
-}
-
-extern bool qt_disable_lowpriority_timers; //in qeventloop_unix.cpp
-
-void QWSServerPrivate::_q_screenSaverWake()
-{
- if (screensaverintervals) {
- if (screensaverinterval != screensaverintervals) {
- if (saver) saver->restore();
- screensaverinterval = screensaverintervals;
- screensaverblockevents = false;
- } else {
- if (!screensavertimer->isActive()) {
- qt_screen->blank(false);
- if (saver) saver->restore();
- }
- }
- screensavertimer->start(*screensaverinterval);
- screensavertime.start();
- }
- qt_disable_lowpriority_timers=false;
-}
-
-void QWSServerPrivate::_q_screenSaverSleep()
-{
- qt_screen->blank(true);
-#if !defined(QT_QWS_IPAQ) && !defined(QT_QWS_EBX)
- screensavertimer->stop();
-#else
- if (screensaverinterval) {
- screensavertimer->start(*screensaverinterval);
- screensavertime.start();
- } else {
- screensavertimer->stop();
- }
-#endif
- qt_disable_lowpriority_timers=true;
-}
-
-/*!
- \fn void QWSServer::setScreenSaver(QWSScreenSaver* screenSaver)
-
- Installs the given \a screenSaver, deleting the current screen
- saver.
-
- Note that this function can only be used in the server process.
-
- \sa screenSaverActivate(), setScreenSaverInterval(), setScreenSaverIntervals(), setScreenSaverBlockLevel()
-*/
-void QWSServer::setScreenSaver(QWSScreenSaver* ss)
-{
- QWSServerPrivate *qd = qwsServer->d_func();
- delete qd->saver;
- qd->saver = ss;
-}
-
-void QWSServerPrivate::screenSave(int level)
-{
- if (saver) {
- // saver->save() may call QCoreApplication::processEvents,
- // block event before calling saver->save().
- bool oldScreensaverblockevents = screensaverblockevents;
- if (*screensaverinterval >= 1000) {
- screensaverblockevents = (screensavereventblocklevel >= 0 && screensavereventblocklevel <= level);
-#ifdef EVENT_BLOCK_DEBUG
- if (screensaverblockevents)
- qDebug("ready to block events");
-#endif
- }
- int *oldScreensaverinterval = screensaverinterval;
- if (saver->save(level)) {
- // only update screensaverinterval if it hasn't already changed
- if (oldScreensaverinterval == screensaverinterval) {
- if (screensaverinterval && screensaverinterval[1]) {
- screensavertimer->start(*++screensaverinterval);
- screensavertime.start();
- } else {
- screensaverinterval = 0;
- }
- }
- } else {
- // restore previous state
- screensaverblockevents = oldScreensaverblockevents;
-
- // for some reason, the saver don't want us to change to the
- // next level, so we'll stay at this level for another interval
- if (screensaverinterval && *screensaverinterval) {
- screensavertimer->start(*screensaverinterval);
- screensavertime.start();
- }
- }
- } else {
- screensaverinterval = 0;//screensaverintervals;
- screensaverblockevents = false;
- _q_screenSaverSleep();
- }
-}
-
-void QWSServerPrivate::_q_screenSaverTimeout()
-{
- if (screensaverinterval) {
- if (screensavertime.elapsed() > *screensaverinterval*2) {
- // bogus (eg. unsuspend, system time changed)
- _q_screenSaverWake(); // try again
- return;
- }
- screenSave(screensaverinterval - screensaverintervals);
- }
-}
-
-/*!
- Returns true if the screen saver is active; otherwise returns
- false.
-
- Note that this function can only be used in the server process.
-
- \sa screenSaverActivate()
-*/
-bool QWSServer::screenSaverActive()
-{
- return qwsServerPrivate->screensaverinterval
- && !qwsServerPrivate->screensavertimer->isActive();
-}
-
-/*!
- \internal
-*/
-void QWSServer::updateWindowRegions() const
-{
- qwsServerPrivate->update_regions();
-}
-
-/*!
- Activates the screen saver if \a activate is true; otherwise it is
- deactivated.
-
- Note that this function can only be used in the server process.
-
- \sa screenSaverActive(), setScreenSaver()
-*/
-void QWSServer::screenSaverActivate(bool activate)
-{
- if (activate)
- qwsServerPrivate->_q_screenSaverSleep();
- else
- qwsServerPrivate->_q_screenSaverWake();
-}
-
-void QWSServerPrivate::disconnectClient(QWSClient *c)
-{
- QTimer::singleShot(0, c, SLOT(closeHandler()));
-}
-
-void QWSServerPrivate::updateClientCursorPos()
-{
- Q_Q(QWSServer);
- QWSWindow *win = qwsServerPrivate->mouseGrabber ? qwsServerPrivate->mouseGrabber : qwsServer->windowAt(QWSServer::mousePosition);
- QWSClient *winClient = win ? win->client() : 0;
- if (winClient && winClient != cursorClient)
- q->sendMouseEvent(QWSServer::mousePosition, mouseState);
-}
-
-#ifndef QT_NO_QWS_INPUTMETHODS
-
-/*!
- \class QWSInputMethod
- \preliminary
- \ingroup qws
-
- \brief The QWSInputMethod class provides international input methods
- in Qt for Embedded Linux.
-
- Note that this class is only available in \l{Qt for Embedded Linux}.
-
- A \l{Qt for Embedded Linux} application requires a server application to be
- running, or to be the server application itself. All system
- generated events, including keyboard and mouse events, are passed
- to the server application which then propagates the event to the
- appropriate client.
-
- An input method consists of a filter and optionally a graphical
- interface, and is used to filter input events between the server
- and the client application.
-
- \tableofcontents
-
- \section1 Creating Custom Input Methods
-
- To implement a custom input method, derive from the QWSInputMethod
- class, and use the server's \l
- {QWSServer::}{setCurrentInputMethod()} function to install it.
-
- When subclassing QWSInputMethod, you can reimplement the filter()
- functions to handle input from both physical and virtual keyboards
- as well as mouse devices. Note that the default implementations do
- nothing. Use the setInputResolution() function to control the
- number of bits shifted when filtering mouse input, i.e., when
- going from pointer resolution to screen resolution (the current
- resolution can be retrieved using the inputResolutionShift()
- function).
-
- Reimplement the reset() function to restore the state of the input
- method. Note that the default implementation calls the sendEvent()
- function with empty preedit and commit strings if the input method
- is in compose mode (i.e., if the input method is actively
- composing a preedit string).
-
- To receive replies to an input method query (sent using the
- sendQuery() function), you must reimplement the queryResponse()
- function, while the mouseHandler() function must be reimplemented
- if you want to handle mouse events within the preedit
- text. Reimplement the updateHandler() function to handle update
- events including resets and focus changes. The UpdateType enum
- describes the various types of update events recognized by the
- input method.
-
- \section1 Using Input Methods
-
- In addition to the filter(), reset(), queryResponse(),
- mouseHandler() and updateHandler() function mentioned in the
- previous section, the QWSInputMethod provides several other
- functions helping the window system to manage the installed input
- methods.
-
- The sendEvent() function sends the given event to the focus
- widget, while the sendPreeditString() function sends the given
- preedit text (encapsulated by an event). QWSInputMethod also
- provides the sendCommitString() convenience function which sends
- an event encapsulating the given commit string to the current
- focus widget, and the sendMouseEvent() function which sends the
- given mouse event.
-
- Finally, the QWSInputMethod class provides the sendQuery()
- function for sending input method queries. This function
- encapsulates the event with a QWSEvent instance of the \l
- {QWSEvent::}{IMQuery} type.
-
- \sa QWSServer, {Qt for Embedded Linux Architecture}
-*/
-
-/*!
- Constructs a new input method.
-
- Use the QWSServer::setCurrentInputMethod() function to install it.
-*/
-
-QWSInputMethod::QWSInputMethod()
-{
-
-}
-
-/*!
- Destroys this input method, uninstalling it if it is installed.
-*/
-QWSInputMethod::~QWSInputMethod()
-{
- if (current_IM == this)
- current_IM = 0;
-}
-
-/*!
- Filters the key input identified by the given \a unicode, \a
- keycode, \a modifiers, \a isPress and \a autoRepeat parameters.
-
- Note that the default implementation does nothing; reimplement
- this function to handle input from both physical and virtual
- devices.
-
- The \a keycode is a Qt::Key value, and the \a modifiers is an OR
- combination of Qt::KeyboardModifiers. The \a isPress parameter is
- telling whether the input is a key press or key release, and the
- \a autoRepeat parameter determines whether the input is
- autorepeated ( i.e., in which case the
- QWSKeyboardHandler::beginAutoRepeat() function has been called).
-
- To block the event from further processing, return true when
- reimplementing this function; the default implementation returns
- false.
-
- \sa setInputResolution(), inputResolutionShift()
-*/
-bool QWSInputMethod::filter(int unicode, int keycode, int modifiers, bool isPress, bool autoRepeat)
-{
- Q_UNUSED(unicode);
- Q_UNUSED(keycode);
- Q_UNUSED(modifiers);
- Q_UNUSED(isPress);
- Q_UNUSED(autoRepeat);
- return false;
-}
-
-/*!
- \overload
-
- Filters the mouse input identified by the given \a position, \a
- state, and \a wheel parameters.
-*/
-bool QWSInputMethod::filter(const QPoint &position, int state, int wheel)
-{
- Q_UNUSED(position);
- Q_UNUSED(state);
- Q_UNUSED(wheel);
- return false;
-}
-
-/*!
- Resets the state of the input method.
-
- If the input method is in compose mode, i.e., the input method is
- actively composing a preedit string, the default implementation
- calls sendEvent() with empty preedit and commit strings; otherwise
- it does nothing. Reimplement this function to alter this behavior.
-
- \sa sendEvent()
-*/
-void QWSInputMethod::reset()
-{
- if (current_IM_composing_win) {
- QInputMethodEvent ime;
- sendEvent(&ime);
- }
-}
-
-/*!
- \enum QWSInputMethod::UpdateType
-
- This enum describes the various types of update events recognized
- by the input method.
-
- \value Update The input widget is updated in some way; use sendQuery() with
- Qt::ImMicroFocus as an argument for more information.
- \value FocusIn A new input widget receives focus.
- \value FocusOut The input widget loses focus.
- \value Reset The input method should be reset.
- \value Destroyed The input widget is destroyed.
-
- \sa updateHandler()
-*/
-
-/*!
- Handles update events including resets and focus changes. The
- update events are specified by the given \a type which is one of
- the UpdateType enum values.
-
- Note that reimplementations of this function must call the base
- implementation for all cases that it does not handle itself.
-
- \sa UpdateType
-*/
-void QWSInputMethod::updateHandler(int type)
-{
- switch (type) {
- case FocusOut:
- case Reset:
- reset();
- break;
-
- default:
- break;
- }
-}
-
-
-/*!
- Receive replies to an input method query.
-
- Note that the default implementation does nothing; reimplement
- this function to receive such replies.
-
- Internally, an input method query is passed encapsulated by an \l
- {QWSEvent::IMQuery}{IMQuery} event generated by the sendQuery()
- function. The queried property and the result is passed in the \a
- property and \a result parameters.
-
- \sa sendQuery(), QWSServer::sendIMQuery()
-*/
-void QWSInputMethod::queryResponse(int property, const QVariant &result)
-{
- Q_UNUSED(property);
- Q_UNUSED(result);
-}
-
-
-
-/*!
- \fn void QWSInputMethod::mouseHandler(int offset, int state)
-
- Handles mouse events within the preedit text.
-
- Note that the default implementation resets the input method on
- all mouse presses; reimplement this function to alter this
- behavior.
-
- The \a offset parameter specifies the position of the mouse event
- within the string, and \a state specifies the type of the mouse
- event as described by the QWSServer::IMMouse enum. If \a state is
- less than 0, the mouse event is inside the associated widget, but
- outside the preedit text. When clicking in a different widget, the
- \a state is QWSServer::MouseOutside.
-
- \sa sendPreeditString(), reset()
-*/
-void QWSInputMethod::mouseHandler(int, int state)
-{
- if (state == QWSServer::MousePress || state == QWSServer::MouseOutside)
- reset();
-}
-
-
-/*!
- Sends an event encapsulating the given \a preeditString, to the
- focus widget.
-
- The specified \a selectionLength is the number of characters to be
- marked as selected (starting at the given \a cursorPosition). If
- \a selectionLength is negative, the text \e before \a
- cursorPosition is marked.
-
- The preedit string is marked with QInputContext::PreeditFormat,
- and the selected part is marked with
- QInputContext::SelectionFormat.
-
- Sending an input method event with a non-empty preedit string will
- cause the input method to enter compose mode. Sending an input
- method event with an empty preedit string will cause the input
- method to leave compose mode, i.e., the input method will no longer
- be actively composing the preedit string.
-
- Internally, the event is represented by a QWSEvent object of the
- \l {QWSEvent::IMEvent}{IMEvent} type.
-
- \sa sendEvent(), sendCommitString()
-*/
-
-void QWSInputMethod::sendPreeditString(const QString &preeditString, int cursorPosition, int selectionLength)
-{
- QList<QInputMethodEvent::Attribute> attributes;
-
- int selPos = cursorPosition;
- if (selectionLength == 0) {
- selPos = 0;
- } else if (selectionLength < 0) {
- selPos += selectionLength;
- selectionLength = -selectionLength;
- }
- if (selPos > 0)
- attributes += QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, 0, selPos,
- QVariant(int(QInputContext::PreeditFormat)));
-
- if (selectionLength)
- attributes += QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, selPos, selectionLength,
- QVariant(int(QInputContext::SelectionFormat)));
-
- if (selPos + selectionLength < preeditString.length())
- attributes += QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat,
- selPos + selectionLength,
- preeditString.length() - selPos - selectionLength,
- QVariant(int(QInputContext::PreeditFormat)));
-
- attributes += QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, cursorPosition, 0, QVariant());
-
- QInputMethodEvent ime(preeditString, attributes);
- qwsServer->sendIMEvent(&ime);
-}
-
-/*!
- \fn void QWSInputMethod::sendCommitString(const QString &commitString, int replaceFromPosition, int replaceLength)
-
- Sends an event encapsulating the given \a commitString, to the
- focus widget.
-
- Note that this will cause the input method to leave compose mode,
- i.e., the input method will no longer be actively composing the
- preedit string.
-
- If the specified \a replaceLength is greater than 0, the commit
- string will replace the given number of characters of the
- receiving widget's previous text, starting at the given \a
- replaceFromPosition relative to the start of the current preedit
- string.
-
- Internally, the event is represented by a QWSEvent object of the
- \l {QWSEvent::IMEvent}{IMEvent} type.
-
- \sa sendEvent(), sendPreeditString()
-*/
-void QWSInputMethod::sendCommitString(const QString &commitString, int replaceFrom, int replaceLength)
-{
- QInputMethodEvent ime;
- ime.setCommitString(commitString, replaceFrom, replaceLength);
- qwsServer->sendIMEvent(&ime);
-}
-
-/*!
- \fn QWSInputMethod::sendIMEvent(QWSServer::IMState state, const QString &text, int cursorPosition, int selectionLength)
- \obsolete
-
- Sends a QInputMethodEvent object to the focus widget.
-
- If the specified \a state is QWSServer::IMCompose, \a text is a
- preedit string, \a cursorPosition is the cursor's position within
- the preedit string, and \a selectionLength is the number of
- characters (starting at \a cursorPosition) that should be marked
- as selected by the input widget receiving the event. If the
- specified \a state is QWSServer::IMEnd, \a text is a commit
- string.
-
- Use sendEvent(), sendPreeditString() or sendCommitString() instead.
-*/
-
-/*!
- \fn QWSInputMethod::sendEvent(const QInputMethodEvent *event)
-
- Sends the given \a event to the focus widget.
-
- The \c QInputMethodEvent class is derived from QWSEvent, i.e., the
- given \a event is a QWSEvent object of the \l
- {QWSEvent::IMEvent}{IMEvent} type.
-
- \sa sendPreeditString(), sendCommitString(), reset()
-*/
-
-
-/*!
- \fn void QWSInputMethod::sendQuery(int property)
-
- Sends an input method query (internally encapsulated by a QWSEvent
- of the \l {QWSEvent::IMQuery}{IMQuery} type) for the specified \a
- property.
-
- To receive responses to input method queries, the virtual
- queryResponse() function must be reimplemented.
-
- \sa queryResponse(), QWSServer::sendIMQuery()
-*/
-
-/*!
- Sets and returns the number of bits shifted to go from pointer
- resolution to screen resolution when filtering mouse input.
-
- If \a isHigh is true and the device has a pointer device
- resolution twice or more of the screen resolution, the positions
- passed to the filter() function will be presented at the higher
- resolution; otherwise the resolution will be equal to that of the
- screen resolution.
-
- \sa inputResolutionShift(), filter()
-*/
-uint QWSInputMethod::setInputResolution(bool isHigh)
-{
- mIResolution = isHigh;
- return inputResolutionShift();
-}
-
-/*!
- Returns the number of bits shifted to go from pointer resolution
- to screen resolution when filtering mouse input.
-
- \sa setInputResolution(), filter()
-*/
-uint QWSInputMethod::inputResolutionShift() const
-{
- return 0; // default for devices with single resolution.
-}
-
-/*!
- \fn void QWSInputMethod::sendMouseEvent( const QPoint &position, int state, int wheel )
-
- Sends a mouse event specified by the given \a position, \a state
- and \a wheel parameters.
-
- The given \a position will be transformed if the screen
- coordinates do not match the pointer device coordinates.
-
- Note that the event will be not be tested by the active input
- method, but calling the QWSServer::sendMouseEvent() function will
- make the current input method filter the event.
-
- \sa mouseHandler(), sendEvent()
-*/
-void QWSInputMethod::sendMouseEvent( const QPoint &pos, int state, int wheel )
-{
- if (qt_last_x) {
- *qt_last_x = pos.x();
- *qt_last_y = pos.y();
- }
- QWSServer::mousePosition = pos;
- qwsServerPrivate->mouseState = state;
- QWSServerPrivate::sendMouseEventUnfiltered(pos, state, wheel);
-}
-#endif // QT_NO_QWS_INPUTMETHODS
-
-/*!
- \fn QWSWindow::QWSWindow(int i, QWSClient * client)
- \internal
-
- Constructs a new top-level window, associated with the client \a
- client and giving it the id \a i.
-*/
-
-/*!
- \fn QWSServer::windowEvent(QWSWindow * window, QWSServer::WindowEvent eventType)
-
- This signal is emitted whenever something happens to a top-level
- window (e.g., it's created or destroyed), passing a pointer to the
- window and the event's type in the \a window and \a eventType
- parameters, respectively.
-
- \sa markedText()
-*/
-
-/*!
- \class QWSServer::KeyboardFilter
- \ingroup qws
-
- \brief The KeyboardFilter class is a base class for global
- keyboard event filters in Qt for Embedded Linux.
-
- Note that this class is only available in \l{Qt for Embedded Linux}.
-
- In \l{Qt for Embedded Linux}, all system generated events, including
- keyboard events, are passed to the server application which then
- propagates the event to the appropriate client. The KeyboardFilter
- class is used to implement a global, low-level filter on the
- server side. The server applies the filter to all keyboard events
- before passing them on to the clients:
-
- \image qwsserver_keyboardfilter.png
-
- This feature can, for example, be used to filter things like APM
- (advanced power management) suspended from a button without having
- to filter for it in all applications.
-
- To add a new keyboard filter you must first create the filter by
- deriving from this class, reimplementing the pure virtual filter()
- function. Then you can install the filter on the server using
- QWSServer's \l {QWSServer::}{addKeyboardFilter()}
- function. QWSServer also provides a \l
- {QWSServer::}{removeKeyboardFilter()} function.
-
- \sa {Qt for Embedded Linux Architecture}, QWSServer, QWSInputMethod
-*/
-
-/*!
- \fn QWSServer::KeyboardFilter::~KeyboardFilter()
-
- Destroys the keyboard filter.
-*/
-
-/*!
- \fn bool QWSServer::KeyboardFilter::filter(int unicode, int keycode, int modifiers, bool isPress, bool autoRepeat)
-
- Implement this function to return true if a given key event should
- be stopped from being processed any further; otherwise it should
- return false.
-
- A key event can be identified by the given \a unicode value and
- the \a keycode, \a modifiers, \a isPress and \a autoRepeat
- parameters.
-
- The \a keycode parameter is the Qt keycode value as defined by the
- Qt::Key enum. The \a modifiers is an OR combination of
- Qt::KeyboardModifier values, indicating whether \gui
- Shift/Alt/Ctrl keys are pressed. The \a isPress parameter is true
- if the event is a key press event and \a autoRepeat is true if the
- event is caused by an auto-repeat mechanism and not an actual key
- press.
-*/
-
-QT_END_NAMESPACE
-
-#include "moc_qwindowsystem_qws.cpp"
diff --git a/src/gui/embedded/qwindowsystem_qws.h b/src/gui/embedded/qwindowsystem_qws.h
deleted file mode 100644
index 0b73a76bf9..0000000000
--- a/src/gui/embedded/qwindowsystem_qws.h
+++ /dev/null
@@ -1,508 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWINDOWSYSTEM_QWS_H
-#define QWINDOWSYSTEM_QWS_H
-
-#include <QtCore/qbytearray.h>
-#include <QtCore/qmap.h>
-#include <QtCore/qdatetime.h>
-#include <QtCore/qlist.h>
-
-#include <QtGui/qwsevent_qws.h>
-#include <QtGui/qkbd_qws.h>
-#include <QtGui/qregion.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-struct QWSWindowPrivate;
-class QWSCursor;
-class QWSClient;
-class QWSRegionManager;
-class QBrush;
-class QVariant;
-class QInputMethodEvent;
-class QWSInputMethod;
-class QWSBackingStore;
-class QWSWindowSurface;
-
-#ifdef QT3_SUPPORT
-class QImage;
-class QColor;
-#endif
-
-class QWSInternalWindowInfo
-{
-public:
- int winid;
- unsigned int clientid;
- QString name; // Corresponds to QObject name of top-level widget
-};
-
-
-class Q_GUI_EXPORT QWSScreenSaver
-{
-public:
- virtual ~QWSScreenSaver();
- virtual void restore()=0;
- virtual bool save(int level)=0;
-};
-
-
-class Q_GUI_EXPORT QWSWindow
-{
- friend class QWSServer;
- friend class QWSServerPrivate;
-
-public:
- QWSWindow(int i, QWSClient* client);
- ~QWSWindow();
-
- int winId() const { return id; }
- const QString &name() const { return rgnName; }
- const QString &caption() const { return rgnCaption; }
- QWSClient* client() const { return c; }
- const QRegion &requestedRegion() const { return requested_region; }
- QRegion allocatedRegion() const;
- QRegion paintedRegion() const;
- bool isVisible() const { return !requested_region.isEmpty(); }
- bool isPartiallyObscured() const { return requested_region != allocatedRegion(); }
- bool isFullyObscured() const { return allocatedRegion().isEmpty(); }
-
- enum State { NoState, Hidden, Showing, Visible, Hiding, Raising, Lowering, Moving, ChangingGeometry, Destroyed };
- State state() const;
- Qt::WindowFlags windowFlags() const;
- QRegion dirtyOnScreen() const;
-
- void raise();
- void lower();
- void show();
- void hide();
- void setActiveWindow();
-
- bool isOpaque() const {return opaque && _opacity == 255;}
- uint opacity() const { return _opacity; }
-
- QWSWindowSurface* windowSurface() const { return surface; }
-
-private:
- bool hidden() const { return requested_region.isEmpty(); }
- bool forClient(const QWSClient* cl) const { return cl==c; }
-
- void setName(const QString &n);
- void setCaption(const QString &c);
-
- void focus(bool get);
- int focusPriority() const { return last_focus_time; }
- void operation(QWSWindowOperationEvent::Operation o);
- void shuttingDown() { last_focus_time=0; }
-
-#ifdef QT_QWS_CLIENTBLIT
- QRegion directPaintRegion() const;
- inline void setDirectPaintRegion(const QRegion &topmost);
-#endif
- inline void setAllocatedRegion(const QRegion &region);
-
- void createSurface(const QString &key, const QByteArray &data);
-
-#ifndef QT_NO_QWSEMBEDWIDGET
- void startEmbed(QWSWindow *window);
- void stopEmbed(QWSWindow *window);
-#endif
-
-private:
- int id;
- QString rgnName;
- QString rgnCaption;
- bool modified;
- bool onTop;
- QWSClient* c;
- QRegion requested_region;
- QRegion exposed;
- int last_focus_time;
- QWSWindowSurface *surface;
- uint _opacity;
- bool opaque;
- QWSWindowPrivate *d;
-#ifdef QT3_SUPPORT
- inline QT3_SUPPORT QRegion requested() const { return requested_region; }
-// inline QT3_SUPPORT QRegion allocation() const { return allocated_region; }
-#endif
-};
-
-
-#ifndef QT_NO_SOUND
-class QWSSoundServer;
-#ifdef QT_USE_OLD_QWS_SOUND
-class QWSSoundServerData;
-
-class Q_GUI_EXPORT QWSSoundServer : public QObject {
- Q_OBJECT
-public:
- QWSSoundServer(QObject* parent);
- ~QWSSoundServer();
- void playFile(const QString& filename);
-private Q_SLOTS:
- void feedDevice(int fd);
-private:
- QWSSoundServerData* d;
-};
-#endif
-#endif
-
-
-/*********************************************************************
- *
- * Class: QWSServer
- *
- *********************************************************************/
-
-class QWSMouseHandler;
-struct QWSCommandStruct;
-class QWSServerPrivate;
-class QWSServer;
-
-extern Q_GUI_EXPORT QWSServer *qwsServer;
-
-class Q_GUI_EXPORT QWSServer : public QObject
-{
- friend class QCopChannel;
- friend class QWSMouseHandler;
- friend class QWSWindow;
- friend class QWSDisplay;
- friend class QWSInputMethod;
- Q_OBJECT
- Q_DECLARE_PRIVATE(QWSServer)
-public:
- explicit QWSServer(int flags = 0, QObject *parent=0);
-#ifdef QT3_SUPPORT
- QT3_SUPPORT_CONSTRUCTOR QWSServer(int flags, QObject *parent, const char *name);
-#endif
- ~QWSServer();
- enum ServerFlags { DisableKeyboard = 0x01,
- DisableMouse = 0x02 };
-
- static void sendKeyEvent(int unicode, int keycode, Qt::KeyboardModifiers modifiers,
- bool isPress, bool autoRepeat);
-#ifndef QT_NO_QWS_KEYBOARD
- static void processKeyEvent(int unicode, int keycode, Qt::KeyboardModifiers modifiers,
- bool isPress, bool autoRepeat);
-#endif
-
- static QWSServer* instance() { return qwsServer; }
-
-#ifndef QT_NO_QWS_INPUTMETHODS
-#ifdef QT3_SUPPORT
- enum IMState { IMCompose, IMEnd, IMStart = IMCompose };
-#endif
- enum IMMouse { MousePress, MouseRelease, MouseMove, MouseOutside }; //MouseMove reserved but not used
- void sendIMEvent(const QInputMethodEvent*);
- void sendIMQuery(int property);
-#endif
-
-#ifndef QT_NO_QWS_KEYBOARD
- class KeyboardFilter
- {
- public:
- virtual ~KeyboardFilter() {}
- virtual bool filter(int unicode, int keycode, int modifiers,
- bool isPress, bool autoRepeat)=0;
- };
- static void addKeyboardFilter(KeyboardFilter *f);
- static void removeKeyboardFilter();
-#endif
-
-#ifndef QT_NO_QWS_INPUTMETHODS
- static void setCurrentInputMethod(QWSInputMethod *im);
- static void resetInputMethod();
-#endif
-
- static void setDefaultMouse(const char *);
- static void setDefaultKeyboard(const char *);
- static void setMaxWindowRect(const QRect&);
- static void sendMouseEvent(const QPoint& pos, int state, int wheel = 0);
-
- static void setBackground(const QBrush &);
-#ifdef QT3_SUPPORT
- static QT3_SUPPORT void setDesktopBackground(const QImage &img);
- static QT3_SUPPORT void setDesktopBackground(const QColor &);
-#endif
- static QWSMouseHandler *mouseHandler();
- static const QList<QWSMouseHandler*>& mouseHandlers();
- static void setMouseHandler(QWSMouseHandler*);
-#ifndef QT_NO_QWS_KEYBOARD
- static QWSKeyboardHandler* keyboardHandler();
- static void setKeyboardHandler(QWSKeyboardHandler* kh);
-#endif
- QWSWindow *windowAt(const QPoint& pos);
-
- const QList<QWSWindow*> &clientWindows();
-
- void openMouse();
- void closeMouse();
- void suspendMouse();
- void resumeMouse();
-#ifndef QT_NO_QWS_KEYBOARD
- void openKeyboard();
- void closeKeyboard();
-#endif
-
- static void setScreenSaver(QWSScreenSaver*);
- static void setScreenSaverIntervals(int* ms);
- static void setScreenSaverInterval(int);
- static void setScreenSaverBlockLevel(int);
- static bool screenSaverActive();
- static void screenSaverActivate(bool);
-
- // the following are internal.
- void refresh();
- void refresh(QRegion &);
-
- void enablePainting(bool);
- static void processEventQueue();
- static QList<QWSInternalWindowInfo*> * windowList();
-
- void sendPropertyNotifyEvent(int property, int state);
-
- static QPoint mousePosition;
-
- static void startup(int flags);
- static void closedown();
-
- static void beginDisplayReconfigure();
- static void endDisplayReconfigure();
-
-#ifndef QT_NO_QWS_CURSOR
- static void setCursorVisible(bool);
- static bool isCursorVisible();
-#endif
-
- const QBrush &backgroundBrush() const;
-
- enum WindowEvent { Create=0x0001, Destroy=0x0002, Hide=0x0004, Show=0x0008,
- Raise=0x0010, Lower=0x0020, Geometry=0x0040, Active = 0x0080,
- Name=0x0100 };
-
-Q_SIGNALS:
- void windowEvent(QWSWindow *w, QWSServer::WindowEvent e);
-
-#ifndef QT_NO_COP
- void newChannel(const QString& channel);
- void removedChannel(const QString& channel);
-
-#endif
-#ifndef QT_NO_QWS_INPUTMETHODS
- void markedText(const QString &);
-#endif
-
-protected:
- void timerEvent(QTimerEvent *e);
-
-private:
- friend class QApplicationPrivate;
- void updateWindowRegions() const;
-
-#ifdef QT3_SUPPORT
-#ifndef QT_NO_QWS_KEYBOARD
- static inline QT3_SUPPORT void setKeyboardFilter(QWSServer::KeyboardFilter *f)
- { if (f) addKeyboardFilter(f); else removeKeyboardFilter(); }
-#endif
-#endif
-
-private:
-#ifndef QT_NO_QWS_MULTIPROCESS
- Q_PRIVATE_SLOT(d_func(), void _q_clientClosed())
- Q_PRIVATE_SLOT(d_func(), void _q_doClient())
- Q_PRIVATE_SLOT(d_func(), void _q_deleteWindowsLater())
-#endif
-
- Q_PRIVATE_SLOT(d_func(), void _q_screenSaverWake())
- Q_PRIVATE_SLOT(d_func(), void _q_screenSaverSleep())
- Q_PRIVATE_SLOT(d_func(), void _q_screenSaverTimeout())
-
-#ifndef QT_NO_QWS_MULTIPROCESS
- Q_PRIVATE_SLOT(d_func(), void _q_newConnection())
-#endif
-};
-
-#ifndef QT_NO_QWS_INPUTMETHODS
-class Q_GUI_EXPORT QWSInputMethod : public QObject
-{
- Q_OBJECT
-public:
- QWSInputMethod();
- virtual ~QWSInputMethod();
-
- enum UpdateType {Update, FocusIn, FocusOut, Reset, Destroyed};
-
- virtual bool filter(int unicode, int keycode, int modifiers,
- bool isPress, bool autoRepeat);
-
- virtual bool filter(const QPoint &, int state, int wheel);
-
- virtual void reset();
- virtual void updateHandler(int type);
- virtual void mouseHandler(int pos, int state);
- virtual void queryResponse(int property, const QVariant&);
-
-protected:
- uint setInputResolution(bool isHigh);
- uint inputResolutionShift() const;
- // needed for required transform
- void sendMouseEvent(const QPoint &pos, int state, int wheel);
-
- void sendEvent(const QInputMethodEvent*);
- void sendPreeditString(const QString &preeditString, int cursorPosition, int selectionLength = 0);
- void sendCommitString(const QString &commitString, int replaceFrom = 0, int replaceLength = 0);
- void sendQuery(int property);
-
-#ifdef QT3_SUPPORT
- inline void sendIMEvent(QWSServer::IMState, const QString& txt, int cpos, int selLen = 0);
-#endif
-private:
- bool mIResolution;
-};
-
-inline void QWSInputMethod::sendEvent(const QInputMethodEvent *ime)
-{
- qwsServer->sendIMEvent(ime);
-}
-#ifdef QT3_SUPPORT
-inline void QWSInputMethod::sendIMEvent(QWSServer::IMState state, const QString& txt, int cpos, int selLen)
-{
- if (state == QWSServer::IMCompose) sendPreeditString(txt, cpos, selLen); else sendCommitString(txt);
-}
-#endif
-
-inline void QWSInputMethod::sendQuery(int property)
-{
- qwsServer->sendIMQuery(property);
-}
-
-// mouse events not inline as involve transformations.
-#endif // QT_NO_QWS_INPUTMETHODS
-
-
-
-/*********************************************************************
- *
- * Class: QWSClient
- *
- *********************************************************************/
-
-struct QWSMouseEvent;
-
-typedef QMap<int, QWSCursor*> QWSCursorMap;
-
-class QWSClientPrivate;
-class QWSCommand;
-class QWSConvertSelectionCommand;
-
-class Q_GUI_EXPORT QWSClient : public QObject
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QWSClient)
-public:
- QWSClient(QObject* parent, QWS_SOCK_BASE *, int id);
- ~QWSClient();
-
- int socket() const;
-
- void setIdentity(const QString&);
- QString identity() const { return id; }
-
- void sendEvent(QWSEvent* event);
- void sendConnectedEvent(const char *display_spec);
- void sendMaxWindowRectEvent(const QRect &rect);
- void sendPropertyNotifyEvent(int property, int state);
- void sendPropertyReplyEvent(int property, int len, const char *data);
- void sendSelectionClearEvent(int windowid);
- void sendSelectionRequestEvent(QWSConvertSelectionCommand *cmd, int windowid);
-#ifndef QT_QWS_CLIENTBLIT
- void sendRegionEvent(int winid, QRegion rgn, int type);
-#else
- void sendRegionEvent(int winid, QRegion rgn, int type, int id = 0);
-#endif
-#ifndef QT_NO_QWSEMBEDWIDGET
- void sendEmbedEvent(int winid, QWSEmbedEvent::Type type,
- const QRegion &region = QRegion());
-#endif
- QWSCommand* readMoreCommand();
-
- int clientId() const { return cid; }
-
- QWSCursorMap cursors; // cursors defined by this client
-Q_SIGNALS:
- void connectionClosed();
- void readyRead();
-private Q_SLOTS:
- void closeHandler();
- void errorHandler();
-
-private:
-#ifndef QT_NO_QWS_MULTIPROCESS
- friend class QWSWindow;
- void removeUnbufferedSurface();
- void addUnbufferedSurface();
-#endif
-
-private:
- int socketDescriptor;
-#ifndef QT_NO_QWS_MULTIPROCESS
- QWSSocket *csocket;
-#endif
- QWSCommand* command;
- uint isClosed : 1;
- QString id;
- int cid;
-
- friend class QWSServerPrivate;
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QWINDOWSYSTEM_QWS_H
diff --git a/src/gui/embedded/qwscommand_qws.cpp b/src/gui/embedded/qwscommand_qws.cpp
deleted file mode 100644
index 9e4831aec6..0000000000
--- a/src/gui/embedded/qwscommand_qws.cpp
+++ /dev/null
@@ -1,609 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qwscommand_qws_p.h"
-#include "qtransportauth_qws.h"
-#include "qtransportauth_qws_p.h"
-
-#include <unistd.h>
-
-// #define QWSCOMMAND_DEBUG 1 // Uncomment to debug client/server communication
-
-#ifdef QWSCOMMAND_DEBUG
-# include <qdebug.h>
-# include "qfile.h"
-# include <ctype.h>
-#endif
-
-QT_BEGIN_NAMESPACE
-
-#ifdef QWSCOMMAND_DEBUG
-// QWSHexDump -[ start ]---------------------------------------------
-# define QWSHEXDUMP_MAX 32
-class QWSHexDump
-{
-public:
-
- QWSHexDump(const void *address, int len, int wrapAt = 16)
- : wrap(wrapAt), dataSize(len)
- {
- init();
- data = reinterpret_cast<const char*>(address);
- if (len < 0)
- dataSize = 0;
- }
-
- QWSHexDump(const char *str, int len = -1, int wrapAt = 16)
- : wrap(wrapAt), dataSize(len)
- {
- init();
- data = str;
- if (len == -1)
- dataSize = str ? strlen(str) : 0;
- }
-
- QWSHexDump(const QByteArray &array, int wrapAt = 16)
- : wrap(wrapAt)
- {
- init();
- data = array.data();
- dataSize = array.size();
- }
-
- // Sets a customized prefix for the hexdump
- void setPrefix(const char *str) { prefix = str; }
-
- // Sets number of bytes to cluster together
- void setClusterSize(uint num) { clustering = num; }
-
- // Output hexdump to a text stream
- void intoTextStream(QTextStream &strm) {
- outstrm = &strm;
- hexDump();
- }
-
- // Output hexdump to a QString
- QString toString();
-
-protected:
- void init();
- void hexDump();
- void sideviewDump(int at);
-
-private:
- uint wrap;
- uint clustering;
- uint dataSize;
- int dataWidth;
- const char *data;
- const char *prefix;
- bool dirty;
-
- char sideviewLayout[QWSHEXDUMP_MAX + 1];
- char sideview[15];
-
- QTextStream *outstrm;
-};
-
-void QWSHexDump::init()
-{
- prefix = "> "; // Standard line prefix
- clustering = 2; // Word-size clustering by default
- if (wrap > QWSHEXDUMP_MAX) // No wider than QWSHexDump_MAX bytes
- wrap = QWSHEXDUMP_MAX;
-}
-
-void QWSHexDump::hexDump()
-{
- *outstrm << '(' << dataSize << " bytes):\n" << prefix;
- sprintf(sideviewLayout, " [%%-%us]", wrap);
- dataWidth = (2 * wrap) + (wrap / clustering);
-
- dirty = false;
- uint wrapIndex = 0;
- for (uint i = 0; i < dataSize; i++) {
- uint c = static_cast<uchar>(data[i]);
- sideview[wrapIndex = i%wrap] = isprint(c) ? c : '.';
-
- if (wrapIndex && (wrapIndex % clustering == 0))
- *outstrm << ' ';
-
- outstrm->setFieldWidth(2);
- outstrm->setPadChar('0');
- outstrm->setNumberFlags( QTextStream::ShowBase );
- *outstrm << hex << c;
- dirty = true;
-
- if (wrapIndex == wrap-1) {
- sideviewDump(wrapIndex);
- wrapIndex = 0;
- if (i+1 < dataSize)
- *outstrm << endl << prefix;
- }
-
- }
- sideviewDump(wrapIndex);
-}
-
-void QWSHexDump::sideviewDump(int at)
-{
- if (dirty) {
- dirty = false;
- ++at;
- sideview[at] = '\0';
- int currentWidth = (2 * at) + (at / clustering) - (at%clustering?0:1);
- int missing = qMax(dataWidth - currentWidth, 0);
- while (missing--)
- *outstrm << ' ';
-
- *outstrm << " [";
- outstrm->setPadChar(' ');
- outstrm->setFieldWidth(wrap);
- outstrm->setFieldAlignment( QTextStream::AlignLeft );
- *outstrm << sideview;
- *outstrm << ']';
- }
-}
-
-// Output hexdump to a QString
-QString QWSHexDump::toString() {
- QString result;
- QTextStream strm(&result, QFile::WriteOnly);
- outstrm = &strm;
- hexDump();
- return result;
-}
-
-#ifndef QT_NO_DEBUG
-QDebug &operator<<(QDebug &dbg, QWSHexDump *hd) {
- if (!hd)
- return dbg << "QWSHexDump(0x0)";
- QString result = hd->toString();
- dbg.nospace() << result;
- return dbg.space();
-}
-
-// GCC & Intel wont handle references here
-QDebug operator<<(QDebug dbg, QWSHexDump hd) {
- return dbg << &hd;
-}
-#endif
-// QWSHexDump -[ end ]-----------------------------------------------
-
-
-QDebug &operator<<(QDebug &dbg, QWSCommand::Type tp)
-{
- dbg << qws_getCommandTypeString( tp );
- return dbg;
-}
-
-#define N_EVENTS 19
-const char * eventNames[N_EVENTS] = {
- "NoEvent",
- "Connected",
- "Mouse", "Focus", "Key",
- "Region",
- "Creation",
- "PropertyNotify",
- "PropertyReply",
- "SelectionClear",
- "SelectionRequest",
- "SelectionNotify",
- "MaxWindowRect",
- "QCopMessage",
- "WindowOperation",
- "IMEvent",
- "IMQuery",
- "IMInit",
- "Font"
- };
-
-class QWSServer;
-extern QWSServer *qwsServer;
-#endif
-
-const char *qws_getCommandTypeString( QWSCommand::Type tp )
-{
- const char *typeStr;
- switch(tp) {
- case QWSCommand::Create:
- typeStr = "Create";
- break;
- case QWSCommand::Shutdown:
- typeStr = "Shutdown";
- break;
- case QWSCommand::Region:
- typeStr = "Region";
- break;
- case QWSCommand::RegionMove:
- typeStr = "RegionMove";
- break;
- case QWSCommand::RegionDestroy:
- typeStr = "RegionDestroy";
- break;
- case QWSCommand::SetProperty:
- typeStr = "SetProperty";
- break;
- case QWSCommand::AddProperty:
- typeStr = "AddProperty";
- break;
- case QWSCommand::RemoveProperty:
- typeStr = "RemoveProperty";
- break;
- case QWSCommand::GetProperty:
- typeStr = "GetProperty";
- break;
- case QWSCommand::SetSelectionOwner:
- typeStr = "SetSelectionOwner";
- break;
- case QWSCommand::ConvertSelection:
- typeStr = "ConvertSelection";
- break;
- case QWSCommand::RequestFocus:
- typeStr = "RequestFocus";
- break;
- case QWSCommand::ChangeAltitude:
- typeStr = "ChangeAltitude";
- break;
- case QWSCommand::SetOpacity:
- typeStr = "SetOpacity";
- break;
- case QWSCommand::DefineCursor:
- typeStr = "DefineCursor";
- break;
- case QWSCommand::SelectCursor:
- typeStr = "SelectCursor";
- break;
- case QWSCommand::PositionCursor:
- typeStr = "PositionCursor";
- break;
- case QWSCommand::GrabMouse:
- typeStr = "GrabMouse";
- break;
- case QWSCommand::PlaySound:
- typeStr = "PlaySound";
- break;
- case QWSCommand::QCopRegisterChannel:
- typeStr = "QCopRegisterChannel";
- break;
- case QWSCommand::QCopSend:
- typeStr = "QCopSend";
- break;
- case QWSCommand::RegionName:
- typeStr = "RegionName";
- break;
- case QWSCommand::Identify:
- typeStr = "Identify";
- break;
- case QWSCommand::GrabKeyboard:
- typeStr = "GrabKeyboard";
- break;
- case QWSCommand::RepaintRegion:
- typeStr = "RepaintRegion";
- break;
- case QWSCommand::IMMouse:
- typeStr = "IMMouse";
- break;
- case QWSCommand::IMUpdate:
- typeStr = "IMUpdate";
- break;
- case QWSCommand::IMResponse:
- typeStr = "IMResponse";
- break;
- case QWSCommand::Font:
- typeStr = "Font";
- break;
- case QWSCommand::Unknown:
- default:
- typeStr = "Unknown";
- break;
- }
- return typeStr;
-}
-
-
-/*********************************************************************
- *
- * Functions to read/write commands on/from a socket
- *
- *********************************************************************/
-
-#ifndef QT_NO_QWS_MULTIPROCESS
-void qws_write_command(QIODevice *socket, int type, char *simpleData, int simpleLen,
- char *rawData, int rawLen)
-{
-#ifdef QWSCOMMAND_DEBUG
- if (simpleLen) qDebug() << "WRITE simpleData " << QWSHexDump(simpleData, simpleLen);
- if (rawLen > 0) qDebug() << "WRITE rawData " << QWSHexDump(rawData, rawLen);
-#endif
-
-#ifndef QT_NO_SXE
- QTransportAuth *a = QTransportAuth::getInstance();
- // ###### as soon as public API can be modified get rid of horrible casts
- QIODevice *ad = a->passThroughByClient(reinterpret_cast<QWSClient*>(socket));
- if (ad)
- socket = ad;
-#endif
-
- qws_write_uint(socket, type);
-
- if (rawLen > MAX_COMMAND_SIZE) {
- qWarning("qws_write_command: Message of size %d too big. "
- "Truncated to %d", rawLen, MAX_COMMAND_SIZE);
- rawLen = MAX_COMMAND_SIZE;
- }
-
- qws_write_uint(socket, rawLen == -1 ? 0 : rawLen);
-
- if (simpleData && simpleLen)
- socket->write(simpleData, simpleLen);
-
- if (rawLen && rawData)
- socket->write(rawData, rawLen);
-}
-
-/*
- command format: [type][rawLen][simpleData][rawData]
- type is already read when entering this function
-*/
-
-bool qws_read_command(QIODevice *socket, char *&simpleData, int &simpleLen,
- char *&rawData, int &rawLen, int &bytesRead)
-{
-
- // read rawLen
- if (rawLen == -1) {
- rawLen = qws_read_uint(socket);
- if (rawLen == -1)
- return false;
- }
-
- // read simpleData, assumes socket is capable of buffering all the data
- if (simpleLen && !rawData) {
- if (socket->bytesAvailable() < uint(simpleLen))
- return false;
- int tmp = socket->read(simpleData, simpleLen);
- Q_ASSERT(tmp == simpleLen);
- Q_UNUSED(tmp);
- }
-
- if (rawLen > MAX_COMMAND_SIZE) {
- socket->close();
- qWarning("qws_read_command: Won't read command of length %d, "
- "connection closed.", rawLen);
- return false;
- }
-
- // read rawData
- if (rawLen && !rawData) {
- rawData = new char[rawLen];
- bytesRead = 0;
- }
- if (bytesRead < rawLen && socket->bytesAvailable())
- bytesRead += socket->read(rawData + bytesRead, rawLen - bytesRead);
-
- return (bytesRead == rawLen);
-}
-#endif
-
-/*********************************************************************
- *
- * QWSCommand base class - only use derived classes from that
- *
- *********************************************************************/
-QWSProtocolItem::~QWSProtocolItem() {
- if (deleteRaw)
- delete []rawDataPtr;
-}
-
-#ifndef QT_NO_QWS_MULTIPROCESS
-void QWSProtocolItem::write(QIODevice *s) {
-#ifdef QWSCOMMAND_DEBUG
- if (!qwsServer)
- qDebug() << "QWSProtocolItem::write sending type " << static_cast<QWSCommand::Type>(type);
- else
- qDebug() << "QWSProtocolItem::write sending event " << (type < N_EVENTS ? eventNames[type] : "unknown");
-#endif
- qws_write_command(s, type, simpleDataPtr, simpleLen, rawDataPtr, rawLen);
-}
-
-bool QWSProtocolItem::read(QIODevice *s) {
-#ifdef QWSCOMMAND_DEBUG
- QLatin1String reread( (rawLen == -1) ? "" : "REREAD");
- if (qwsServer)
- qDebug() << "QWSProtocolItem::read reading type " << static_cast<QWSCommand::Type>(type) << reread;
- else
- qDebug() << "QWSProtocolItem::read reading event " << (type < N_EVENTS ? eventNames[type] : "unknown") << reread;
- //qDebug("QWSProtocolItem::read reading event %s", type < N_EVENTS ? eventNames[type] : "unknown");
-#endif
- bool b = qws_read_command(s, simpleDataPtr, simpleLen, rawDataPtr, rawLen, bytesRead);
- if (b) {
- setData(rawDataPtr, rawLen, false);
- deleteRaw = true;
- }
-#ifdef QWSCOMMAND_DEBUG
- else
- {
- qDebug() << "error in reading command " << static_cast<QWSCommand::Type>(type);
- }
-#endif
- return b;
-}
-#endif // QT_NO_QWS_MULTIPROCESS
-
-void QWSProtocolItem::copyFrom(const QWSProtocolItem *item) {
- if (this == item)
- return;
- simpleLen = item->simpleLen;
- memcpy(simpleDataPtr, item->simpleDataPtr, simpleLen);
- setData(item->rawDataPtr, item->rawLen);
-}
-
-void QWSProtocolItem::setData(const char *data, int len, bool allocateMem) {
- if (deleteRaw)
- delete [] rawDataPtr;
- if (!data || len <= 0) {
- rawDataPtr = 0;
- rawLen = 0;
- return;
- }
- if (allocateMem) {
- rawDataPtr = new char[len];
- memcpy(rawDataPtr, data, len);
- deleteRaw = true;
- } else {
- rawDataPtr = const_cast<char *>(data);
- deleteRaw = false;
- }
- rawLen = len;
-}
-
-QWSCommand *QWSCommand::factory(int type)
-{
- QWSCommand *command = 0;
- switch (type) {
- case QWSCommand::Create:
- command = new QWSCreateCommand;
- break;
- case QWSCommand::Shutdown:
- command = new QWSCommand(type, 0, 0);
- break;
- case QWSCommand::Region:
- command = new QWSRegionCommand;
- break;
- case QWSCommand::RegionMove:
- command = new QWSRegionMoveCommand;
- break;
- case QWSCommand::RegionDestroy:
- command = new QWSRegionDestroyCommand;
- break;
- case QWSCommand::AddProperty:
- command = new QWSAddPropertyCommand;
- break;
- case QWSCommand::SetProperty:
- command = new QWSSetPropertyCommand;
- break;
- case QWSCommand::RemoveProperty:
- command = new QWSRemovePropertyCommand;
- break;
- case QWSCommand::GetProperty:
- command = new QWSGetPropertyCommand;
- break;
- case QWSCommand::SetSelectionOwner:
- command = new QWSSetSelectionOwnerCommand;
- break;
- case QWSCommand::RequestFocus:
- command = new QWSRequestFocusCommand;
- break;
- case QWSCommand::ChangeAltitude:
- command = new QWSChangeAltitudeCommand;
- break;
- case QWSCommand::SetOpacity:
- command = new QWSSetOpacityCommand;
- break;
- case QWSCommand::DefineCursor:
- command = new QWSDefineCursorCommand;
- break;
- case QWSCommand::SelectCursor:
- command = new QWSSelectCursorCommand;
- break;
- case QWSCommand::GrabMouse:
- command = new QWSGrabMouseCommand;
- break;
- case QWSCommand::GrabKeyboard:
- command = new QWSGrabKeyboardCommand;
- break;
-#ifndef QT_NO_SOUND
- case QWSCommand::PlaySound:
- command = new QWSPlaySoundCommand;
- break;
-#endif
-#ifndef QT_NO_COP
- case QWSCommand::QCopRegisterChannel:
- command = new QWSQCopRegisterChannelCommand;
- break;
- case QWSCommand::QCopSend:
- command = new QWSQCopSendCommand;
- break;
-#endif
- case QWSCommand::RegionName:
- command = new QWSRegionNameCommand;
- break;
- case QWSCommand::Identify:
- command = new QWSIdentifyCommand;
- break;
- case QWSCommand::RepaintRegion:
- command = new QWSRepaintRegionCommand;
- break;
-#ifndef QT_NO_QWS_INPUTMETHODS
- case QWSCommand::IMUpdate:
- command = new QWSIMUpdateCommand;
- break;
-
- case QWSCommand::IMMouse:
- command = new QWSIMMouseCommand;
- break;
-
- case QWSCommand::IMResponse:
- command = new QWSIMResponseCommand;
- break;
-#endif
- case QWSCommand::PositionCursor:
- command = new QWSPositionCursorCommand;
- break;
-#ifndef QT_NO_QWSEMBEDWIDGET
- case QWSCommand::Embed:
- command = new QWSEmbedCommand;
- break;
-#endif
- case QWSCommand::Font:
- command = new QWSFontCommand;
- break;
- case QWSCommand::ScreenTransform:
- command = new QWSScreenTransformCommand;
- break;
- default:
- qWarning("QWSCommand::factory : Type error - got %08x!", type);
- }
- return command;
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/embedded/qwscommand_qws_p.h b/src/gui/embedded/qwscommand_qws_p.h
deleted file mode 100644
index 4e0c8bebef..0000000000
--- a/src/gui/embedded/qwscommand_qws_p.h
+++ /dev/null
@@ -1,851 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWSCOMMAND_QWS_P_H
-#define QWSCOMMAND_QWS_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-// When reading commands "off the wire" in the server, the rawLen is read
-// and then that many bytes are allocated. If the rawLen is corrupted (or
-// the protocol is being attacked) too many bytes can be allocated. Set
-// a hard limit here for security.
-#define MAX_COMMAND_SIZE (16 * 1024)
-
-#include <QtCore/qbytearray.h>
-#include <QtGui/qwsutils_qws.h>
-#include <QtGui/qfont.h>
-#include <QtCore/qdatastream.h>
-#include <QtCore/qvariant.h>
-#include <QtCore/qrect.h>
-#include <QtGui/qregion.h>
-#include <QtCore/qvector.h>
-#include <QtCore/qvarlengtharray.h>
-#include <QtGui/qwsevent_qws.h>
-#include "qwsprotocolitem_qws.h"
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QRect;
-
-/*********************************************************************
- *
- * Functions to read/write commands on/from a socket
- *
- *********************************************************************/
-#ifndef QT_NO_QWS_MULTIPROCESS
-void qws_write_command(QIODevice *socket, int type, char *simpleData, int simpleLen, char *rawData, int rawLen);
-bool qws_read_command(QIODevice *socket, char *&simpleData, int &simpleLen, char *&rawData, int &rawLen, int &bytesRead);
-#endif
-
-struct QWSCommand : QWSProtocolItem
-{
- QWSCommand(int t, int len, char *ptr) : QWSProtocolItem(t,len,ptr) {}
-
- enum Type {
- Unknown = 0,
- Create,
- Shutdown,
- Region,
- RegionMove,
- RegionDestroy,
- SetProperty,
- AddProperty,
- RemoveProperty,
- GetProperty,
- SetSelectionOwner,
- ConvertSelection,
- RequestFocus,
- ChangeAltitude,
- SetOpacity,
- DefineCursor,
- SelectCursor,
- PositionCursor,
- GrabMouse,
- PlaySound,
- QCopRegisterChannel,
- QCopSend,
- RegionName,
- Identify,
- GrabKeyboard,
- RepaintRegion,
- IMMouse,
- IMUpdate,
- IMResponse,
- Embed,
- Font,
- ScreenTransform
- };
- static QWSCommand *factory(int type);
-};
-
-const char *qws_getCommandTypeString( QWSCommand::Type tp );
-
-#ifndef QT_NO_DEBUG
-class QDebug;
-QDebug &operator<<(QDebug &dbg, QWSCommand::Type tp);
-#endif // QT_NO_DEBUG
-
-/*********************************************************************
- *
- * Commands
- *
- *********************************************************************/
-
-struct QWSIdentifyCommand : public QWSCommand
-{
- QWSIdentifyCommand() :
- QWSCommand(QWSCommand::Identify,
- sizeof(simpleData), reinterpret_cast<char *>(&simpleData))
- {
- simpleData.idLen = 0;
- simpleData.idLock = -1;
- }
-
- void setData(const char *d, int len, bool allocateMem) {
- QWSCommand::setData(d, len, allocateMem);
- if ( simpleData.idLen > MAX_COMMAND_SIZE )
- {
- qWarning( "Identify command - name length %d - too big!", simpleData.idLen );
- simpleData.idLen = MAX_COMMAND_SIZE;
- }
- if ( simpleData.idLen * int(sizeof(QChar)) > len )
- {
- qWarning( "Identify command - name length %d - buffer size %d - buffer overrun!", simpleData.idLen, len );
- }
- else
- {
- id = QString(reinterpret_cast<const QChar*>(d), simpleData.idLen);
- }
- }
-
- void setId(const QString& i, int lock)
- {
- id = i;
- simpleData.idLen = id.length();
- simpleData.idLock = lock;
- setData(reinterpret_cast<const char*>(id.unicode()), simpleData.idLen*2, true);
- }
-
- struct SimpleData {
- int idLen;
- int idLock;
- } simpleData;
- QString id;
-};
-
-struct QWSCreateCommand : public QWSCommand
-{
- QWSCreateCommand(int n = 1) :
- QWSCommand(QWSCommand::Create, sizeof(count),
- reinterpret_cast<char *>(&count)), count(n) {}
- int count;
-};
-
-struct QWSRegionNameCommand : public QWSCommand
-{
- QWSRegionNameCommand() :
- QWSCommand(QWSCommand::RegionName,
- sizeof(simpleData), reinterpret_cast<char *>(&simpleData)) {}
-
- void setData(const char *d, int len, bool allocateMem) {
- QWSCommand::setData(d, len, allocateMem);
- if ( simpleData.nameLen > MAX_COMMAND_SIZE )
- {
- qWarning( "region name command - name length too big!" );
- simpleData.nameLen = MAX_COMMAND_SIZE;
- }
- if ( simpleData.captionLen > MAX_COMMAND_SIZE )
- {
- qWarning( "region name command - caption length too big!" );
- simpleData.captionLen = MAX_COMMAND_SIZE;
- }
- if ( simpleData.nameLen + simpleData.captionLen > len )
- {
- qWarning( "region name command - name length %d - caption length %d - buffer size %d - buffer overrun!",
- simpleData.nameLen, simpleData.captionLen, len );
-
- }
- else
- {
- name = QString(reinterpret_cast<const QChar*>(d), simpleData.nameLen/2);
- d += simpleData.nameLen;
- caption = QString(reinterpret_cast<const QChar*>(d), simpleData.captionLen/2);
- }
- }
-
- void setName(const QString& n, const QString &c)
- {
- name = n;
- caption = c;
- int l = simpleData.nameLen = name.length()*2;
- l += simpleData.captionLen = caption.length()*2;
- char *d = new char[l];
- memcpy(d, name.unicode(), simpleData.nameLen);
- memcpy(d+simpleData.nameLen, caption.unicode(), simpleData.captionLen);
- setData(d, l, true);
- delete[] d;
- }
-
- struct SimpleData {
- int windowid;
- int nameLen;
- int captionLen;
- } simpleData;
- QString name;
- QString caption;
-};
-
-struct QWSRegionCommand : public QWSCommand
-{
- QWSRegionCommand() :
- QWSCommand(QWSCommand::Region, sizeof(simpleData),
- reinterpret_cast<char*>(&simpleData)) {}
-
- void setData(const char *d, int len, bool allocateMem = true) {
- QWSCommand::setData(d, len, allocateMem);
-
- if( simpleData.nrectangles * int(sizeof(QRect)) + simpleData.surfacekeylength * int(sizeof(QChar)) + simpleData.surfacedatalength * int(sizeof(char)) > len )
- {
- qWarning( "region command - rectangle count %d - surface key length %d - region data size %d - buffer size %d - buffer overrun!",
- simpleData.nrectangles, simpleData.surfacekeylength, simpleData.surfacedatalength, len );
- }
- else
- {
- char *ptr = rawDataPtr;
-
- region.setRects(reinterpret_cast<QRect*>(ptr), simpleData.nrectangles);
- ptr += simpleData.nrectangles * sizeof(QRect);
-
- surfaceKey = QString(reinterpret_cast<QChar*>(ptr),
- simpleData.surfacekeylength);
- ptr += simpleData.surfacekeylength * sizeof(QChar);
-
- surfaceData = QByteArray(ptr, simpleData.surfacedatalength);
- }
- }
-
- void setData(int id, const QString &key, const QByteArray &data,
- const QRegion &reg)
- {
- surfaceKey = key;
- surfaceData = data;
- region = reg;
-
- const QVector<QRect> rects = reg.rects();
-
- simpleData.windowid = id;
- simpleData.surfacekeylength = key.size();
- simpleData.surfacedatalength = data.size();
- simpleData.nrectangles = rects.count();
-
- QVarLengthArray<char, 256> buffer;
- buffer.append(reinterpret_cast<const char*>(rects.constData()),
- rects.count() * sizeof(QRect));
- buffer.append(reinterpret_cast<const char*>(key.constData()),
- key.size() * sizeof(QChar));
- buffer.append(data, data.size());
-
- QWSCommand::setData(buffer.constData(), buffer.size(), true);
- }
-
- /* XXX this will pad out in a compiler dependent way,
- should move nrectangles to before windowtype, and
- add reserved bytes.
- Symptom will be valgrind reported uninitialized memory usage
- */
- struct SimpleData {
- int windowid;
- int surfacekeylength;
- int surfacedatalength;
- int nrectangles;
- } simpleData;
-
- QString surfaceKey;
- QByteArray surfaceData;
- QRegion region;
-};
-
-struct QWSSetOpacityCommand : public QWSCommand
-{
- QWSSetOpacityCommand() :
- QWSCommand(QWSCommand::SetOpacity, sizeof(simpleData),
- reinterpret_cast<char*>(&simpleData)) {}
-
- struct SimpleData {
- int windowid;
- uchar opacity;
- } simpleData;
-};
-
-struct QWSRegionMoveCommand : public QWSCommand
-{
- QWSRegionMoveCommand() :
- QWSCommand(QWSCommand::RegionMove, sizeof(simpleData),
- reinterpret_cast<char*>(&simpleData)) {}
-
- struct SimpleData {
- int windowid;
- int dx;
- int dy;
- } simpleData;
-
-};
-
-struct QWSRegionDestroyCommand : public QWSCommand
-{
- QWSRegionDestroyCommand() :
- QWSCommand(QWSCommand::RegionDestroy, sizeof(simpleData),
- reinterpret_cast<char*>(&simpleData)) {}
-
- struct SimpleData {
- int windowid;
- } simpleData;
-
-};
-
-struct QWSRequestFocusCommand : public QWSCommand
-{
- QWSRequestFocusCommand() :
- QWSCommand(QWSCommand::RequestFocus, sizeof(simpleData), reinterpret_cast<char*>(&simpleData)) {}
-
- struct SimpleData {
- int windowid;
- int flag;
- } simpleData;
-};
-
-struct QWSChangeAltitudeCommand : public QWSCommand
-{
- QWSChangeAltitudeCommand() :
- QWSCommand(QWSCommand::ChangeAltitude, sizeof(simpleData), reinterpret_cast<char*>(&simpleData)) {}
-
- enum Altitude {
- Lower = -1,
- Raise = 0,
- StaysOnTop = 1
- };
-
- struct SimpleData {
- int windowid;
- Altitude altitude;
- bool fixed;
- } simpleData;
-
-};
-
-
-struct QWSAddPropertyCommand : public QWSCommand
-{
- QWSAddPropertyCommand() :
- QWSCommand(QWSCommand::AddProperty, sizeof(simpleData), reinterpret_cast<char*>(&simpleData)) {}
-
- struct SimpleData {
- int windowid, property;
- } simpleData;
-
-};
-
-struct QWSSetPropertyCommand : public QWSCommand
-{
- QWSSetPropertyCommand() :
- QWSCommand(QWSCommand::SetProperty, sizeof(simpleData),
- reinterpret_cast<char*>(&simpleData)) { data = 0; }
-
- void setData(const char *d, int len, bool allocateMem = true) {
- QWSCommand::setData(d, len, allocateMem);
- data = rawDataPtr;
- }
-
- struct SimpleData {
- int windowid, property, mode;
- } simpleData;
-
- char *data;
-};
-
-struct QWSRepaintRegionCommand : public QWSCommand
-{
- QWSRepaintRegionCommand() :
- QWSCommand(QWSCommand::RepaintRegion, sizeof(simpleData),
- reinterpret_cast<char*>(&simpleData)) {}
-
- void setData(const char *d, int len, bool allocateMem = true) {
- QWSCommand::setData(d, len, allocateMem);
-
- if( simpleData.nrectangles * int(sizeof(QRect)) > len )
- {
- qWarning( "repaint region command - region rectangle count %d - buffer size %d - buffer overrun",
- simpleData.nrectangles, len );
-
- simpleData.nrectangles = len / sizeof(QRect);
- }
- rectangles = reinterpret_cast<QRect *>(rawDataPtr);
- }
-
- struct SimpleData {
- int windowid;
- int windowFlags;
- bool opaque;
- int nrectangles;
- } simpleData;
-
- QRect * rectangles;
-
-};
-
-struct QWSRemovePropertyCommand : public QWSCommand
-{
- QWSRemovePropertyCommand() :
- QWSCommand(QWSCommand::RemoveProperty, sizeof(simpleData), reinterpret_cast<char*>(&simpleData)) {}
-
- struct SimpleData {
- int windowid, property;
- } simpleData;
-
-};
-
-struct QWSGetPropertyCommand : public QWSCommand
-{
- QWSGetPropertyCommand() :
- QWSCommand(QWSCommand::GetProperty, sizeof(simpleData), reinterpret_cast<char*>(&simpleData)) {}
-
- struct SimpleData {
- int windowid, property;
- } simpleData;
-
-};
-
-struct QWSSetSelectionOwnerCommand : public QWSCommand
-{
- QWSSetSelectionOwnerCommand() :
- QWSCommand(QWSCommand::SetSelectionOwner,
- sizeof(simpleData), reinterpret_cast<char*>(&simpleData)) {}
-
- struct SimpleData {
- int windowid;
- int hour, minute, sec, ms; // time
- } simpleData;
-
-};
-
-struct QWSConvertSelectionCommand : public QWSCommand
-{
- QWSConvertSelectionCommand() :
- QWSCommand(QWSCommand::ConvertSelection,
- sizeof(simpleData), reinterpret_cast<char*>(&simpleData)) {}
-
- struct SimpleData {
- int requestor; // requestor window of the selection
- int selection; // property on requestor into which the selection should be stored
- int mimeTypes; // property ion requestor in which the mimetypes, in which the selection may be, are stored
- } simpleData;
-
-};
-
-struct QWSDefineCursorCommand : public QWSCommand
-{
- QWSDefineCursorCommand() :
- QWSCommand(QWSCommand::DefineCursor,
- sizeof(simpleData), reinterpret_cast<char *>(&simpleData)) {}
-
- void setData(const char *d, int len, bool allocateMem = true) {
- QWSCommand::setData(d, len, allocateMem);
- data = reinterpret_cast<unsigned char *>(rawDataPtr);
- if (simpleData.height * ((simpleData.width+7) / 8) > len) {
- qWarning("define cursor command - width %d height %d- buffer size %d - buffer overrun",
- simpleData.width, simpleData.height, len );
- simpleData.width = simpleData.height = 0;
- }
- }
-
- struct SimpleData {
- int width;
- int height;
- int hotX;
- int hotY;
- int id;
- } simpleData;
-
- unsigned char *data;
-};
-
-struct QWSSelectCursorCommand : public QWSCommand
-{
- QWSSelectCursorCommand() :
- QWSCommand(QWSCommand::SelectCursor,
- sizeof(simpleData), reinterpret_cast<char *>(&simpleData)) {}
-
- struct SimpleData {
- int windowid;
- int id;
- } simpleData;
-};
-
-struct QWSPositionCursorCommand : public QWSCommand
-{
- QWSPositionCursorCommand() :
- QWSCommand(QWSCommand::PositionCursor,
- sizeof(simpleData), reinterpret_cast<char *>(&simpleData)) {}
-
- struct SimpleData {
- int newX;
- int newY;
- } simpleData;
-};
-
-struct QWSGrabMouseCommand : public QWSCommand
-{
- QWSGrabMouseCommand() :
- QWSCommand(QWSCommand::GrabMouse,
- sizeof(simpleData), reinterpret_cast<char *>(&simpleData)) {}
-
- struct SimpleData {
- int windowid;
- bool grab; // grab or ungrab?
- } simpleData;
-};
-
-struct QWSGrabKeyboardCommand : public QWSCommand
-{
- QWSGrabKeyboardCommand() :
- QWSCommand(QWSCommand::GrabKeyboard,
- sizeof(simpleData), reinterpret_cast<char *>(&simpleData)) {}
-
- struct SimpleData {
- int windowid;
- bool grab; // grab or ungrab?
- } simpleData;
-};
-
-#ifndef QT_NO_SOUND
-struct QWSPlaySoundCommand : public QWSCommand
-{
- QWSPlaySoundCommand() :
- QWSCommand(QWSCommand::PlaySound,
- sizeof(simpleData), reinterpret_cast<char *>(&simpleData)) {}
-
- void setData(const char *d, int len, bool allocateMem) {
- QWSCommand::setData(d, len, allocateMem);
- filename = QString(reinterpret_cast<QChar*>(rawDataPtr),len/2);
- }
- void setFileName(const QString& n)
- {
- setData(reinterpret_cast<const char*>(n.unicode()), n.length()*2, true);
- }
-
- struct SimpleData {
- int windowid;
- } simpleData;
- QString filename;
-};
-#endif
-
-
-#ifndef QT_NO_COP
-struct QWSQCopRegisterChannelCommand : public QWSCommand
-{
- QWSQCopRegisterChannelCommand() :
- QWSCommand(QWSCommand::QCopRegisterChannel,
- sizeof(simpleData), reinterpret_cast<char *>(&simpleData)) {}
-
- void setData(const char *d, int len, bool allocateMem) {
- QWSCommand::setData(d, len, allocateMem);
- if ( simpleData.chLen > MAX_COMMAND_SIZE )
- {
- qWarning( "Command channel name too large!" );
- simpleData.chLen = MAX_COMMAND_SIZE;
- }
- if( simpleData.chLen * int(sizeof(QChar)) > len )
- {
- qWarning( "register qcop channel command - channel name length %d - buffer size %d - buffer overrun!", simpleData.chLen, len );
- }
- else
- {
- channel = QString(reinterpret_cast<const QChar*>(d), simpleData.chLen);
- }
- }
-
- void setChannel(const QString& n)
- {
- channel = n;
- simpleData.chLen = channel.length();
- setData(reinterpret_cast<const char*>(channel.unicode()), simpleData.chLen*2, true);
- }
-
- struct SimpleData {
- int chLen;
- } simpleData;
- QString channel;
-};
-
-struct QWSQCopSendCommand : public QWSCommand
-{
- QWSQCopSendCommand() :
- QWSCommand(QWSCommand::QCopSend,
- sizeof(simpleData), reinterpret_cast<char *>(&simpleData)) {}
-
- void setData(const char *d, int len, bool allocateMem) {
- QWSCommand::setData(d, len, allocateMem);
-
- if( simpleData.clen * int(sizeof(QChar)) + simpleData.mlen * int(sizeof(QChar)) + simpleData.dlen * int(sizeof(char)) > len )
- {
- qWarning( "qcop send command - channel name length %d - message name length %d - data size %d - buffer size %d - buffer overrun!",
- simpleData.clen, simpleData.mlen, simpleData.dlen, len );
- }
- else
- {
- const QChar *cd = reinterpret_cast<const QChar*>(d);
- channel = QString(cd,simpleData.clen); cd += simpleData.clen;
- message = QString(cd,simpleData.mlen);
- d += simpleData.clen*sizeof(QChar) + simpleData.mlen*sizeof(QChar);
- data = QByteArray(d, simpleData.dlen);
- }
- }
-
- void setMessage(const QString &c, const QString &m,
- const QByteArray &data)
- {
- this->channel = c;
- this->message = m;
- this->data = data;
- simpleData.clen = c.length();
- simpleData.mlen = m.length();
- simpleData.dlen = data.size();
- int l = simpleData.clen*sizeof(QChar);
- l += simpleData.mlen*sizeof(QChar);
- l += simpleData.dlen;
- char *tmp = new char[l];
- char *d = tmp;
- memcpy(d, c.unicode(), simpleData.clen*sizeof(QChar));
- d += simpleData.clen*sizeof(QChar);
- memcpy(d, m.unicode(), simpleData.mlen*sizeof(QChar));
- d += simpleData.mlen*sizeof(QChar);
- memcpy(d, data.data(), simpleData.dlen);
- QWSCommand::setData(tmp, l, false);
- deleteRaw = true;
- }
-
- struct SimpleData {
- int clen;
- int mlen;
- int dlen;
- } simpleData;
- QString channel;
- QString message;
- QByteArray data;
-};
-
-#endif
-
-
-#ifndef QT_NO_QWS_INPUTMETHODS
-
-struct QWSIMMouseCommand : public QWSCommand
-{
- QWSIMMouseCommand() :
- QWSCommand(QWSCommand::IMMouse,
- sizeof(simpleData), reinterpret_cast<char *>(&simpleData)) {}
-
- struct SimpleData {
- int windowid;
- int state;
- int index;
- } simpleData;
-};
-
-
-struct QWSIMResponseCommand : public QWSCommand
-{
- QWSIMResponseCommand() :
- QWSCommand(QWSCommand::IMResponse,
- sizeof(simpleData), reinterpret_cast<char *>(&simpleData)) {}
-
- void setData(const char *d, int len, bool allocateMem) {
- QWSCommand::setData(d, len, allocateMem);
-
- QByteArray tmp = QByteArray::fromRawData(d, len);
- QDataStream s(tmp);
- s >> result;
- }
-
- void setResult(const QVariant & v)
- {
- QByteArray tmp;
- QDataStream s(&tmp, QIODevice::WriteOnly);
- s << v;
- setData(tmp.data(), tmp.size(), true);
- }
-
- struct SimpleData {
- int windowid;
- int property;
- } simpleData;
-
- QVariant result;
-};
-
-struct QWSIMUpdateCommand: public QWSCommand
-{
- QWSIMUpdateCommand() :
- QWSCommand(QWSCommand::IMUpdate,
- sizeof(simpleData), reinterpret_cast<char *>(&simpleData)) {}
-
- struct SimpleData {
- int windowid;
- int type;
- int widgetid;
- } simpleData;
-};
-
-#endif
-
-#ifndef QT_NO_QWSEMBEDWIDGET
-struct QWSEmbedCommand : public QWSCommand
-{
- QWSEmbedCommand() : QWSCommand(QWSCommand::Embed,
- sizeof(simpleData),
- reinterpret_cast<char*>(&simpleData))
- {}
-
- void setData(const char *d, int len, bool allocateMem = true)
- {
- QWSCommand::setData(d, len, allocateMem);
-
- if( simpleData.rects * int(sizeof(QRect)) > len )
- {
- qWarning( "embed command - region rectangle count %d - buffer size %d - buffer overrun!",
- simpleData.rects, len );
- }
- else
- {
- region.setRects(reinterpret_cast<QRect*>(rawDataPtr),
- simpleData.rects);
- }
- }
-
- void setData(WId embedder, WId embedded, QWSEmbedEvent::Type type,
- const QRegion reg = QRegion())
- {
- simpleData.embedder = embedder;
- simpleData.embedded = embedded;
- simpleData.type = type;
-
- region = reg;
- const QVector<QRect> rects = reg.rects();
- simpleData.rects = rects.count();
-
- QWSCommand::setData(reinterpret_cast<const char*>(rects.constData()),
- rects.count() * sizeof(QRect));
- }
-
- struct {
- WId embedder;
- WId embedded;
- QWSEmbedEvent::Type type;
- int rects;
- } simpleData;
-
- QRegion region;
-};
-#endif // QT_NO_QWSEMBEDWIDGET
-
-struct QWSFontCommand : public QWSCommand
-{
- enum CommandType {
- StartedUsingFont,
- StoppedUsingFont
- };
-
- QWSFontCommand() :
- QWSCommand(QWSCommand::Font,
- sizeof(simpleData), reinterpret_cast<char *>(&simpleData)) {}
-
- void setData(const char *d, int len, bool allocateMem) {
- QWSCommand::setData(d, len, allocateMem);
-
- fontName = QByteArray(d, len);
- }
-
- void setFontName(const QByteArray &name)
- {
- setData(name.constData(), name.size(), true);
- }
-
- struct SimpleData {
- int type;
- } simpleData;
-
- QByteArray fontName;
-};
-
-struct QWSScreenTransformCommand : public QWSCommand
-{
- QWSScreenTransformCommand() :
- QWSCommand(QWSCommand::ScreenTransform,
- sizeof(simpleData), reinterpret_cast<char *>(&simpleData)) {}
-
- void setTransformation(int screen, int transformation)
- {
- simpleData.screen = screen;
- simpleData.transformation = transformation;
- }
-
- struct SimpleData {
- int screen;
- int transformation;
- } simpleData;
-};
-
-QT_END_NAMESPACE
-
-#endif // QWSCOMMAND_QWS_P_H
diff --git a/src/gui/embedded/qwscursor_qws.cpp b/src/gui/embedded/qwscursor_qws.cpp
deleted file mode 100644
index 9e8c235a03..0000000000
--- a/src/gui/embedded/qwscursor_qws.cpp
+++ /dev/null
@@ -1,654 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qcursor.h"
-#include "qbitmap.h"
-#include "qscreen_qws.h"
-#include "qapplication.h"
-#include "qwindowsystem_qws.h"
-#include "qwindowsystem_p.h"
-#include "qwscursor_qws.h"
-
-QT_BEGIN_NAMESPACE
-
-#ifndef QT_NO_QWS_CURSOR
-static QWSCursor *systemCursorTable[Qt::LastCursor+1];
-static bool systemCursorTableInit = false;
-
-// 16 x 16
-static const uchar cur_arrow_bits[] = {
- 0x07, 0x00, 0x39, 0x00, 0xc1, 0x01, 0x02, 0x0e, 0x02, 0x10, 0x02, 0x08,
- 0x04, 0x04, 0x04, 0x02, 0x04, 0x04, 0x88, 0x08, 0x48, 0x11, 0x28, 0x22,
- 0x10, 0x44, 0x00, 0x28, 0x00, 0x10, 0x00, 0x00 };
-static const uchar mcur_arrow_bits[] = {
- 0x07, 0x00, 0x3f, 0x00, 0xff, 0x01, 0xfe, 0x0f, 0xfe, 0x1f, 0xfe, 0x0f,
- 0xfc, 0x07, 0xfc, 0x03, 0xfc, 0x07, 0xf8, 0x0f, 0x78, 0x1f, 0x38, 0x3e,
- 0x10, 0x7c, 0x00, 0x38, 0x00, 0x10, 0x00, 0x00 };
-
-static const unsigned char cur_up_arrow_bits[] = {
- 0x80, 0x00, 0x40, 0x01, 0x40, 0x01, 0x20, 0x02, 0x20, 0x02, 0x10, 0x04,
- 0x10, 0x04, 0x08, 0x08, 0x78, 0x0f, 0x40, 0x01, 0x40, 0x01, 0x40, 0x01,
- 0x40, 0x01, 0x40, 0x01, 0x40, 0x01, 0xc0, 0x01};
-static const unsigned char mcur_up_arrow_bits[] = {
- 0x80, 0x00, 0xc0, 0x01, 0xc0, 0x01, 0xe0, 0x03, 0xe0, 0x03, 0xf0, 0x07,
- 0xf0, 0x07, 0xf8, 0x0f, 0xf8, 0x0f, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01,
- 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01};
-
-static const unsigned char cur_cross_bits[] = {
- 0xc0, 0x01, 0x40, 0x01, 0x40, 0x01, 0x40, 0x01, 0x40, 0x01, 0x40, 0x01,
- 0x7f, 0x7f, 0x01, 0x40, 0x7f, 0x7f, 0x40, 0x01, 0x40, 0x01, 0x40, 0x01,
- 0x40, 0x01, 0x40, 0x01, 0xc0, 0x01, 0x00, 0x00};
-static const unsigned char mcur_cross_bits[] = {
- 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01,
- 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01,
- 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0x00, 0x00};
-
-static const uchar cur_ibeam_bits[] = {
- 0x00, 0x00, 0xe0, 0x03, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00,
- 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00,
- 0x80, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00 };
-static const uchar mcur_ibeam_bits[] = {
- 0xf0, 0x07, 0xf0, 0x07, 0xf0, 0x07, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01,
- 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01,
- 0xf0, 0x07, 0xf0, 0x07, 0xf0, 0x07, 0x00, 0x00 };
-
-static const uchar cur_ver_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0xf0, 0x0f,
- 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0xf0, 0x0f,
- 0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01, 0x00, 0x00 };
-static const uchar mcur_ver_bits[] = {
- 0x00, 0x00, 0x80, 0x03, 0xc0, 0x07, 0xe0, 0x0f, 0xf0, 0x1f, 0xf8, 0x3f,
- 0xfc, 0x7f, 0xc0, 0x07, 0xc0, 0x07, 0xc0, 0x07, 0xfc, 0x7f, 0xf8, 0x3f,
- 0xf0, 0x1f, 0xe0, 0x0f, 0xc0, 0x07, 0x80, 0x03 };
-
-static const uchar cur_hor_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x08, 0x30, 0x18,
- 0x38, 0x38, 0xfc, 0x7f, 0xfc, 0x7f, 0x38, 0x38, 0x30, 0x18, 0x20, 0x08,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-static const uchar mcur_hor_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x40, 0x04, 0x60, 0x0c, 0x70, 0x1c, 0x78, 0x3c,
- 0xfc, 0x7f, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfc, 0x7f, 0x78, 0x3c,
- 0x70, 0x1c, 0x60, 0x0c, 0x40, 0x04, 0x00, 0x00 };
-static const uchar cur_bdiag_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x3e, 0x00, 0x3c, 0x00, 0x3e,
- 0x00, 0x37, 0x88, 0x23, 0xd8, 0x01, 0xf8, 0x00, 0x78, 0x00, 0xf8, 0x00,
- 0xf8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-static const uchar mcur_bdiag_bits[] = {
- 0x00, 0x00, 0xc0, 0x7f, 0x80, 0x7f, 0x00, 0x7f, 0x00, 0x7e, 0x04, 0x7f,
- 0x8c, 0x7f, 0xdc, 0x77, 0xfc, 0x63, 0xfc, 0x41, 0xfc, 0x00, 0xfc, 0x01,
- 0xfc, 0x03, 0xfc, 0x07, 0x00, 0x00, 0x00, 0x00 };
-static const uchar cur_fdiag_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x01, 0xf8, 0x00, 0x78, 0x00,
- 0xf8, 0x00, 0xd8, 0x01, 0x88, 0x23, 0x00, 0x37, 0x00, 0x3e, 0x00, 0x3c,
- 0x00, 0x3e, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00 };
-static const uchar mcur_fdiag_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0xfc, 0x07, 0xfc, 0x03, 0xfc, 0x01, 0xfc, 0x00,
- 0xfc, 0x41, 0xfc, 0x63, 0xdc, 0x77, 0x8c, 0x7f, 0x04, 0x7f, 0x00, 0x7e,
- 0x00, 0x7f, 0x80, 0x7f, 0xc0, 0x7f, 0x00, 0x00 };
-static const uchar cur_blank_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-
-// 20 x 20
-static const uchar forbidden_bits[] = {
- 0x00,0x00,0x00,0x80,0x1f,0x00,0xe0,0x7f,0x00,0xf0,0xf0,0x00,0x38,0xc0,0x01,
- 0x7c,0x80,0x03,0xec,0x00,0x03,0xce,0x01,0x07,0x86,0x03,0x06,0x06,0x07,0x06,
- 0x06,0x0e,0x06,0x06,0x1c,0x06,0x0e,0x38,0x07,0x0c,0x70,0x03,0x1c,0xe0,0x03,
- 0x38,0xc0,0x01,0xf0,0xe0,0x00,0xe0,0x7f,0x00,0x80,0x1f,0x00,0x00,0x00,0x00 };
-
-static const uchar forbiddenm_bits[] = {
- 0x80,0x1f,0x00,0xe0,0x7f,0x00,0xf0,0xff,0x00,0xf8,0xff,0x01,0xfc,0xf0,0x03,
- 0xfe,0xc0,0x07,0xfe,0x81,0x07,0xff,0x83,0x0f,0xcf,0x07,0x0f,0x8f,0x0f,0x0f,
- 0x0f,0x1f,0x0f,0x0f,0x3e,0x0f,0x1f,0xfc,0x0f,0x1e,0xf8,0x07,0x3e,0xf0,0x07,
- 0xfc,0xe0,0x03,0xf8,0xff,0x01,0xf0,0xff,0x00,0xe0,0x7f,0x00,0x80,0x1f,0x00};
-
-// 32 x 32
-static const uchar wait_data_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x7f, 0x00,
- 0x00, 0x04, 0x40, 0x00, 0x00, 0xfc, 0x7f, 0x00, 0x00, 0x08, 0x20, 0x00,
- 0x00, 0x08, 0x20, 0x00, 0x00, 0x08, 0x20, 0x00, 0x00, 0x08, 0x20, 0x00,
- 0x00, 0x50, 0x15, 0x00, 0x00, 0xa0, 0x0a, 0x00, 0x00, 0x40, 0x05, 0x00,
- 0x00, 0x80, 0x02, 0x00, 0x00, 0x40, 0x04, 0x00, 0x00, 0x20, 0x08, 0x00,
- 0x00, 0x10, 0x10, 0x00, 0x00, 0x08, 0x21, 0x00, 0x00, 0x88, 0x22, 0x00,
- 0x00, 0x48, 0x25, 0x00, 0x00, 0xa8, 0x2a, 0x00, 0x00, 0xfc, 0x7f, 0x00,
- 0x00, 0x04, 0x40, 0x00, 0x00, 0xfc, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-static const uchar wait_mask_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x7f, 0x00,
- 0x00, 0xfc, 0x7f, 0x00, 0x00, 0xfc, 0x7f, 0x00, 0x00, 0xf8, 0x3f, 0x00,
- 0x00, 0xf8, 0x3f, 0x00, 0x00, 0xf8, 0x3f, 0x00, 0x00, 0xf8, 0x3f, 0x00,
- 0x00, 0xf0, 0x1f, 0x00, 0x00, 0xe0, 0x0f, 0x00, 0x00, 0xc0, 0x07, 0x00,
- 0x00, 0x80, 0x03, 0x00, 0x00, 0xc0, 0x07, 0x00, 0x00, 0xe0, 0x0f, 0x00,
- 0x00, 0xf0, 0x1f, 0x00, 0x00, 0xf8, 0x3f, 0x00, 0x00, 0xf8, 0x3f, 0x00,
- 0x00, 0xf8, 0x3f, 0x00, 0x00, 0xf8, 0x3f, 0x00, 0x00, 0xfc, 0x7f, 0x00,
- 0x00, 0xfc, 0x7f, 0x00, 0x00, 0xfc, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-
-static const uchar hsplit_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00,
- 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00,
- 0x00, 0x41, 0x82, 0x00, 0x80, 0x41, 0x82, 0x01, 0xc0, 0x7f, 0xfe, 0x03,
- 0x80, 0x41, 0x82, 0x01, 0x00, 0x41, 0x82, 0x00, 0x00, 0x40, 0x02, 0x00,
- 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00,
- 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-static const uchar hsplitm_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00,
- 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe2, 0x47, 0x00, 0x00, 0xe3, 0xc7, 0x00,
- 0x80, 0xe3, 0xc7, 0x01, 0xc0, 0xff, 0xff, 0x03, 0xe0, 0xff, 0xff, 0x07,
- 0xc0, 0xff, 0xff, 0x03, 0x80, 0xe3, 0xc7, 0x01, 0x00, 0xe3, 0xc7, 0x00,
- 0x00, 0xe2, 0x47, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00,
- 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-static const uchar vsplit_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xe0, 0x03, 0x00,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xff, 0x7f, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x7f, 0x00,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00,
- 0x00, 0xc0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-static const uchar vsplitm_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
- 0x00, 0xc0, 0x01, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x00, 0xf0, 0x07, 0x00,
- 0x00, 0xf8, 0x0f, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00,
- 0x00, 0xc0, 0x01, 0x00, 0x80, 0xff, 0xff, 0x00, 0x80, 0xff, 0xff, 0x00,
- 0x80, 0xff, 0xff, 0x00, 0x80, 0xff, 0xff, 0x00, 0x80, 0xff, 0xff, 0x00,
- 0x80, 0xff, 0xff, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00,
- 0x00, 0xc0, 0x01, 0x00, 0x00, 0xf8, 0x0f, 0x00, 0x00, 0xf0, 0x07, 0x00,
- 0x00, 0xe0, 0x03, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-static const uchar phand_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00,
- 0x7e, 0x04, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x70, 0x08, 0x00, 0x00,
- 0x08, 0x08, 0x00, 0x00, 0x70, 0x14, 0x00, 0x00, 0x08, 0x22, 0x00, 0x00,
- 0x30, 0x41, 0x00, 0x00, 0xc0, 0x20, 0x00, 0x00, 0x40, 0x12, 0x00, 0x00,
- 0x80, 0x08, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-static const uchar phandm_bits[] = {
- 0xfe, 0x01, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00,
- 0xff, 0x0f, 0x00, 0x00, 0xfe, 0x1f, 0x00, 0x00, 0xf8, 0x1f, 0x00, 0x00,
- 0xfc, 0x1f, 0x00, 0x00, 0xf8, 0x3f, 0x00, 0x00, 0xfc, 0x7f, 0x00, 0x00,
- 0xf8, 0xff, 0x00, 0x00, 0xf0, 0x7f, 0x00, 0x00, 0xe0, 0x3f, 0x00, 0x00,
- 0xc0, 0x1f, 0x00, 0x00, 0x80, 0x0f, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
- 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-
-static const uchar size_all_data_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xe0, 0x03, 0x00,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x81, 0x40, 0x00, 0x80, 0x81, 0xc0, 0x00,
- 0xc0, 0xff, 0xff, 0x01, 0x80, 0x81, 0xc0, 0x00, 0x00, 0x81, 0x40, 0x00,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x00, 0xc0, 0x01, 0x00,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-static const uchar size_all_mask_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
- 0x00, 0xc0, 0x01, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x00, 0xf0, 0x07, 0x00,
- 0x00, 0xf8, 0x0f, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc2, 0x21, 0x00,
- 0x00, 0xc3, 0x61, 0x00, 0x80, 0xc3, 0xe1, 0x00, 0xc0, 0xff, 0xff, 0x01,
- 0xe0, 0xff, 0xff, 0x03, 0xc0, 0xff, 0xff, 0x01, 0x80, 0xc3, 0xe1, 0x00,
- 0x00, 0xc3, 0x61, 0x00, 0x00, 0xc2, 0x21, 0x00, 0x00, 0xc0, 0x01, 0x00,
- 0x00, 0xf8, 0x0f, 0x00, 0x00, 0xf0, 0x07, 0x00, 0x00, 0xe0, 0x03, 0x00,
- 0x00, 0xc0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-
-static const uchar whatsthis_bits[] = {
- 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0xf0, 0x07, 0x00,
- 0x09, 0x18, 0x0e, 0x00, 0x11, 0x1c, 0x0e, 0x00, 0x21, 0x1c, 0x0e, 0x00,
- 0x41, 0x1c, 0x0e, 0x00, 0x81, 0x1c, 0x0e, 0x00, 0x01, 0x01, 0x07, 0x00,
- 0x01, 0x82, 0x03, 0x00, 0xc1, 0xc7, 0x01, 0x00, 0x49, 0xc0, 0x01, 0x00,
- 0x95, 0xc0, 0x01, 0x00, 0x93, 0xc0, 0x01, 0x00, 0x21, 0x01, 0x00, 0x00,
- 0x20, 0xc1, 0x01, 0x00, 0x40, 0xc2, 0x01, 0x00, 0x40, 0x02, 0x00, 0x00,
- 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
-static const uchar whatsthism_bits[] = {
- 0x01, 0x00, 0x00, 0x00, 0x03, 0xf0, 0x07, 0x00, 0x07, 0xf8, 0x0f, 0x00,
- 0x0f, 0xfc, 0x1f, 0x00, 0x1f, 0x3e, 0x1f, 0x00, 0x3f, 0x3e, 0x1f, 0x00,
- 0x7f, 0x3e, 0x1f, 0x00, 0xff, 0x3e, 0x1f, 0x00, 0xff, 0x9d, 0x0f, 0x00,
- 0xff, 0xc3, 0x07, 0x00, 0xff, 0xe7, 0x03, 0x00, 0x7f, 0xe0, 0x03, 0x00,
- 0xf7, 0xe0, 0x03, 0x00, 0xf3, 0xe0, 0x03, 0x00, 0xe1, 0xe1, 0x03, 0x00,
- 0xe0, 0xe1, 0x03, 0x00, 0xc0, 0xe3, 0x03, 0x00, 0xc0, 0xe3, 0x03, 0x00,
- 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
-
-static const uchar busy_bits[] = {
- 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
- 0x09, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
- 0x41, 0xe0, 0xff, 0x00, 0x81, 0x20, 0x80, 0x00, 0x01, 0xe1, 0xff, 0x00,
- 0x01, 0x42, 0x40, 0x00, 0xc1, 0x47, 0x40, 0x00, 0x49, 0x40, 0x55, 0x00,
- 0x95, 0x80, 0x2a, 0x00, 0x93, 0x00, 0x15, 0x00, 0x21, 0x01, 0x0a, 0x00,
- 0x20, 0x01, 0x11, 0x00, 0x40, 0x82, 0x20, 0x00, 0x40, 0x42, 0x44, 0x00,
- 0x80, 0x41, 0x4a, 0x00, 0x00, 0x40, 0x55, 0x00, 0x00, 0xe0, 0xff, 0x00,
- 0x00, 0x20, 0x80, 0x00, 0x00, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-static const uchar busym_bits[] = {
- 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
- 0x0f, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00,
- 0x7f, 0xe0, 0xff, 0x00, 0xff, 0xe0, 0xff, 0x00, 0xff, 0xe1, 0xff, 0x00,
- 0xff, 0xc3, 0x7f, 0x00, 0xff, 0xc7, 0x7f, 0x00, 0x7f, 0xc0, 0x7f, 0x00,
- 0xf7, 0x80, 0x3f, 0x00, 0xf3, 0x00, 0x1f, 0x00, 0xe1, 0x01, 0x0e, 0x00,
- 0xe0, 0x01, 0x1f, 0x00, 0xc0, 0x83, 0x3f, 0x00, 0xc0, 0xc3, 0x7f, 0x00,
- 0x80, 0xc1, 0x7f, 0x00, 0x00, 0xc0, 0x7f, 0x00, 0x00, 0xe0, 0xff, 0x00,
- 0x00, 0xe0, 0xff, 0x00, 0x00, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-
-// 16 x 16
-static const uchar openhand_bits[] = {
- 0x80,0x01,0x58,0x0e,0x64,0x12,0x64,0x52,0x48,0xb2,0x48,0x92,
- 0x16,0x90,0x19,0x80,0x11,0x40,0x02,0x40,0x04,0x40,0x04,0x20,
- 0x08,0x20,0x10,0x10,0x20,0x10,0x00,0x00};
-static const uchar openhandm_bits[] = {
- 0x80,0x01,0xd8,0x0f,0xfc,0x1f,0xfc,0x5f,0xf8,0xff,0xf8,0xff,
- 0xfe,0xff,0xff,0xff,0xff,0x7f,0xfe,0x7f,0xfc,0x7f,0xfc,0x3f,
- 0xf8,0x3f,0xf0,0x1f,0xe0,0x1f,0x00,0x00};
-static const uchar closedhand_bits[] = {
- 0x00,0x00,0x00,0x00,0x00,0x00,0xb0,0x0d,0x48,0x32,0x08,0x50,
- 0x10,0x40,0x18,0x40,0x04,0x40,0x04,0x20,0x08,0x20,0x10,0x10,
- 0x20,0x10,0x20,0x10,0x00,0x00,0x00,0x00};
-static const uchar closedhandm_bits[] = {
- 0x00,0x00,0x00,0x00,0x00,0x00,0xb0,0x0d,0xf8,0x3f,0xf8,0x7f,
- 0xf0,0x7f,0xf8,0x7f,0xfc,0x7f,0xfc,0x3f,0xf8,0x3f,0xf0,0x1f,
- 0xe0,0x1f,0xe0,0x1f,0x00,0x00,0x00,0x00};
-
-#endif
-
-void QWSServerPrivate::initializeCursor()
-{
- Q_Q(QWSServer);
- // setup system cursors
-#ifndef QT_NO_QWS_CURSOR
-// qt_screen->initCursor(sharedram + ramlen,true);
-
- // default cursor
- cursor = 0;
- setCursor(QWSCursor::systemCursor(Qt::ArrowCursor));
-#endif
- q->sendMouseEvent(QPoint(swidth/2, sheight/2), 0);
-}
-
-void QWSServerPrivate::setCursor(QWSCursor *curs)
-{
-#ifdef QT_NO_QWS_CURSOR
- Q_UNUSED(curs);
-#else
- if (cursor == curs)
- return;
-
- cursor = curs;
-
- if (!haveviscurs || !curs)
- curs = QWSCursor::systemCursor(Qt::BlankCursor);
-
- if (qt_screencursor) {
- qt_screencursor->set(curs->image(),
- curs->hotSpot().x(),
- curs->hotSpot().y());
- }
-#endif
-}
-
-#ifndef QT_NO_QWS_CURSOR
-static void cleanupSystemCursorTable()
-{
- for (int i = 0; i <= Qt::LastCursor; i++)
- if (systemCursorTable[i]) {
- delete systemCursorTable[i];
- systemCursorTable[i] = 0;
- }
-}
-#endif
-
-void QWSCursor::createSystemCursor(int id)
-{
-#ifdef QT_NO_QWS_CURSOR
- Q_UNUSED(id);
-#else
- if (!systemCursorTableInit) {
- for (int i = 0; i <= Qt::LastCursor; i++)
- systemCursorTable[i] = 0;
- qAddPostRoutine(cleanupSystemCursorTable);
- systemCursorTableInit = true;
- }
- switch (id) {
- // 16x16 cursors
- case Qt::ArrowCursor:
- systemCursorTable[Qt::ArrowCursor] =
- new QWSCursor(cur_arrow_bits, mcur_arrow_bits, 16, 16, 0, 0);
- break;
-
- case Qt::UpArrowCursor:
- systemCursorTable[Qt::UpArrowCursor] =
- new QWSCursor(cur_up_arrow_bits, mcur_up_arrow_bits, 16, 16, 7, 0);
- break;
-
- case Qt::CrossCursor:
- systemCursorTable[Qt::CrossCursor] =
- new QWSCursor(cur_cross_bits, mcur_cross_bits, 16, 16, 7, 7);
- break;
-
- case Qt::IBeamCursor:
- systemCursorTable[Qt::IBeamCursor] =
- new QWSCursor(cur_ibeam_bits, mcur_ibeam_bits, 16, 16, 7, 7);
- break;
-
- case Qt::SizeVerCursor:
- systemCursorTable[Qt::SizeVerCursor] =
- new QWSCursor(cur_ver_bits, mcur_ver_bits, 16, 16, 7, 7);
- break;
-
- case Qt::SizeHorCursor:
- systemCursorTable[Qt::SizeHorCursor] =
- new QWSCursor(cur_hor_bits, mcur_hor_bits, 16, 16, 7, 7);
- break;
-
- case Qt::SizeBDiagCursor:
- systemCursorTable[Qt::SizeBDiagCursor] =
- new QWSCursor(cur_bdiag_bits, mcur_bdiag_bits, 16, 16, 7, 7);
- break;
-
- case Qt::SizeFDiagCursor:
- systemCursorTable[Qt::SizeFDiagCursor] =
- new QWSCursor(cur_fdiag_bits, mcur_fdiag_bits, 16, 16, 7, 7);
- break;
-
- case Qt::BlankCursor:
- systemCursorTable[Qt::BlankCursor] =
- new QWSCursor(0, 0, 0, 0, 0, 0);
- break;
-
- // 20x20 cursors
- case Qt::ForbiddenCursor:
- systemCursorTable[Qt::ForbiddenCursor] =
- new QWSCursor(forbidden_bits, forbiddenm_bits, 20, 20, 10, 10);
- break;
-
- // 32x32 cursors
- case Qt::WaitCursor:
- systemCursorTable[Qt::WaitCursor] =
- new QWSCursor(wait_data_bits, wait_mask_bits, 32, 32, 15, 15);
- break;
-
- case Qt::SplitVCursor:
- systemCursorTable[Qt::SplitVCursor] =
- new QWSCursor(vsplit_bits, vsplitm_bits, 32, 32, 15, 15);
- break;
-
- case Qt::SplitHCursor:
- systemCursorTable[Qt::SplitHCursor] =
- new QWSCursor(hsplit_bits, hsplitm_bits, 32, 32, 15, 15);
- break;
-
- case Qt::SizeAllCursor:
- systemCursorTable[Qt::SizeAllCursor] =
- new QWSCursor(size_all_data_bits, size_all_mask_bits, 32, 32, 15, 15);
- break;
-
- case Qt::PointingHandCursor:
- systemCursorTable[Qt::PointingHandCursor] =
- new QWSCursor(phand_bits, phandm_bits, 32, 32, 0, 0);
- break;
-
- case Qt::WhatsThisCursor:
- systemCursorTable[Qt::WhatsThisCursor] =
- new QWSCursor(whatsthis_bits, whatsthism_bits, 32, 32, 0, 0);
- break;
- case Qt::BusyCursor:
- systemCursorTable[Qt::BusyCursor] =
- new QWSCursor(busy_bits, busym_bits, 32, 32, 0, 0);
- break;
-
- case Qt::OpenHandCursor:
- systemCursorTable[Qt::OpenHandCursor] =
- new QWSCursor(openhand_bits, openhandm_bits, 16, 16, 8, 8);
- break;
- case Qt::ClosedHandCursor:
- systemCursorTable[Qt::ClosedHandCursor] =
- new QWSCursor(closedhand_bits, closedhandm_bits, 16, 16, 8, 8);
- break;
- default:
- qWarning("Unknown system cursor %d", id);
- }
-#endif
-}
-
-QWSCursor *QWSCursor::systemCursor(int id)
-{
- QWSCursor *cursor = 0;
-#ifdef QT_NO_QWS_CURSOR
- Q_UNUSED(id);
-#else
- if (id >= 0 && id <= Qt::LastCursor) {
- if (!systemCursorTable[id])
- createSystemCursor(id);
- cursor = systemCursorTable[id];
- }
-
- if (cursor == 0) {
- if (!systemCursorTable[Qt::ArrowCursor])
- createSystemCursor(Qt::ArrowCursor);
- cursor = systemCursorTable[Qt::ArrowCursor];
- }
-#endif
- return cursor;
-}
-
-void QWSCursor::set(const uchar *data, const uchar *mask,
- int width, int height, int hx, int hy)
-{
-#ifdef QT_NO_QWS_CURSOR
- Q_UNUSED(data);
- Q_UNUSED(mask);
- Q_UNUSED(width);
- Q_UNUSED(height);
- Q_UNUSED(hx);
- Q_UNUSED(hy);
-#else
- hot.setX(hx);
- hot.setY(hy);
-
- cursor = QImage(width,height, QImage::Format_Indexed8);
-
- if (!width || !height || !data || !mask || cursor.isNull())
- return;
-
- cursor.setColorCount(3);
- cursor.setColor(0, 0xff000000);
- cursor.setColor(1, 0xffffffff);
- cursor.setColor(2, 0x00000000);
-
- int bytesPerLine = (width + 7) / 8;
- int p = 0;
- int d, m;
-
- int x = -1, w = 0;
-
- uchar *cursor_data = cursor.bits();
- int bpl = cursor.bytesPerLine();
- for (int i = 0; i < height; i++)
- {
- for (int j = 0; j < bytesPerLine; j++, data++, mask++)
- {
- for (int b = 0; b < 8 && j*8+b < width; b++)
- {
- d = *data & (1 << b);
- m = *mask & (1 << b);
- if (d && m) p = 0;
- else if (!d && m) p = 1;
- else p = 2;
- cursor_data[j*8+b] = p;
-
- // calc region
- if (x < 0 && m)
- x = j*8+b;
- else if (x >= 0 && !m) {
- x = -1;
- w = 0;
- }
- if (m)
- w++;
- }
- }
- if (x >= 0) {
- x = -1;
- w = 0;
- }
- cursor_data += bpl;
- }
-
- if (qt_screencursor && qt_screencursor->supportsAlphaCursor())
- createDropShadow(5, 2);
-#endif
-}
-
-// now we're really silly
-void QWSCursor::createDropShadow(int dropx, int dropy)
-{
- //####
-#if 1 || defined(QT_NO_QWS_CURSOR) || defined(QT_NO_QWS_ALHPA_CURSOR)
- Q_UNUSED(dropx);
- Q_UNUSED(dropy);
-#else
- if (cursor.width() + dropx > 64 || cursor.height() + dropy > 64)
- return;
-
- if (!cursor.hasAlphaBuffer()) {
- cursor.setAlphaBuffer(true);
-
- const int nblur=4;
- const int darkness=140;
-
- QImage drop(cursor.width()+dropx+nblur, cursor.height()+dropy+nblur, 8, 18);
- drop.setColor(0, 0xff000000); // bg (black)
- drop.setColor(1, 0xffffffff); // fg (white)
- for (int i=0; i<16; i++) {
- drop.setColor(2+i, (darkness*i/16)<<24);
- }
- drop.fill(2); // all trans
- QImage drop2 = drop.copy();
-
- int cp;
-
- // made solid shadow
- for (int row = 0; row < cursor.height(); row++) {
- for (int col = 0; col < cursor.width(); col++) {
- cp = cursor.pixelIndex(col, row);
- if (cp != 2)
- drop.setPixel(col+dropx, row+dropy, 17);
- }
- }
-
- // blur shadow
- for (int blur=0; blur<nblur; blur++) {
- QImage& to((blur&1)?drop:drop2);
- QImage& from((blur&1)?drop2:drop);
- for (int row = 1; row < drop.height()-1; row++) {
- for (int col = 1; col < drop.width()-1; col++) {
- int t=0;
- for (int dx=-1; dx<=1; dx++) {
- for (int dy=-1; dy<=1; dy++) {
- t += from.pixelIndex(col+dx,row+dy)-2;
- }
- }
- to.setPixel(col,row,2+t/9);
- }
- }
- }
-
- // copy cursor
- for (int row = 0; row < cursor.height(); row++) {
- for (int col = 0; col < cursor.width(); col++) {
- cp = cursor.pixelIndex(col, row);
- if (cp != 2)
- drop.setPixel(col, row, cp);
- }
- }
-
- cursor = drop;
- }
-#endif
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/embedded/qwscursor_qws.h b/src/gui/embedded/qwscursor_qws.h
deleted file mode 100644
index 342d03d54b..0000000000
--- a/src/gui/embedded/qwscursor_qws.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWSCURSOR_QWS_H
-#define QWSCURSOR_QWS_H
-
-#include <QtGui/qimage.h>
-#include <QtGui/qregion.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QWSCursor
-{
-public:
- QWSCursor() {}
- QWSCursor(const uchar *data, const uchar *mask, int width, int height,
- int hotX, int hotY)
- { set(data, mask, width, height, hotX, hotY); }
-
- void set(const uchar *data, const uchar *mask,
- int width, int height, int hotX, int hotY);
-
- QPoint hotSpot() const { return hot; }
- QImage &image() { return cursor; }
-
- static QWSCursor *systemCursor(int id);
-
-private:
- static void createSystemCursor(int id);
- void createDropShadow(int dropx, int dropy);
-
-private:
- QPoint hot;
- QImage cursor;
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QWSCURSOR_QWS_H
diff --git a/src/gui/embedded/qwsdisplay_qws.h b/src/gui/embedded/qwsdisplay_qws.h
deleted file mode 100644
index d9382ee6a0..0000000000
--- a/src/gui/embedded/qwsdisplay_qws.h
+++ /dev/null
@@ -1,185 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWSDISPLAY_QWS_H
-#define QWSDISPLAY_QWS_H
-
-#include <QtCore/qobject.h>
-#include <QtCore/qbytearray.h>
-#include <QtGui/qregion.h>
-#include <QtGui/qimage.h>
-#include <QtGui/qwindowdefs.h>
-#include <QtCore/qlist.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QWSEvent;
-class QWSMouseEvent;
-class QWSQCopMessageEvent;
-class QVariant;
-class QLock;
-
-class QWSWindowInfo
-{
-
-public:
-
- int winid;
- unsigned int clientid;
- QString name;
-
-};
-
-#define QT_QWS_PROPERTY_CONVERTSELECTION 999
-#define QT_QWS_PROPERTY_WINDOWNAME 998
-#define QT_QWS_PROPERTY_MARKEDTEXT 997
-
-class QWSDisplay;
-extern Q_GUI_EXPORT QWSDisplay *qt_fbdpy;
-
-class Q_GUI_EXPORT QWSDisplay
-{
-public:
- QWSDisplay();
- ~QWSDisplay();
-
- static QWSDisplay* instance() { return qt_fbdpy; }
-
- bool eventPending() const;
- QWSEvent *getEvent();
-// QWSRegionManager *regionManager() const;
-
- uchar* frameBuffer() const;
- int width() const;
- int height() const;
- int depth() const;
- int pixmapDepth() const;
- bool supportsDepth(int) const;
-
- uchar *sharedRam() const;
- int sharedRamSize() const;
-
-#ifndef QT_NO_QWS_PROPERTIES
- void addProperty(int winId, int property);
- void setProperty(int winId, int property, int mode, const QByteArray &data);
- void setProperty(int winId, int property, int mode, const char * data);
- void removeProperty(int winId, int property);
- bool getProperty(int winId, int property, char *&data, int &len);
-#endif // QT_NO_QWS_PROPERTIES
-
- QList<QWSWindowInfo> windowList();
- int windowAt(const QPoint &);
-
- void setIdentity(const QString &appName);
- void nameRegion(int winId, const QString& n, const QString &c);
- void requestRegion(int winId, const QString &surfacekey,
- const QByteArray &surfaceData,
- const QRegion &region);
- void repaintRegion(int winId, int windowFlags, bool opaque, QRegion);
- void moveRegion(int winId, int dx, int dy);
- void destroyRegion(int winId);
- void requestFocus(int winId, bool get);
- void setAltitude(int winId, int altitude, bool fixed = false);
- void setOpacity(int winId, int opacity);
- int takeId();
- void setSelectionOwner(int winId, const QTime &time);
- void convertSelection(int winId, int selectionProperty, const QString &mimeTypes);
- void defineCursor(int id, const QBitmap &curs, const QBitmap &mask,
- int hotX, int hotY);
- void destroyCursor(int id);
- void selectCursor(QWidget *w, unsigned int id);
- void setCursorPosition(int x, int y);
- void grabMouse(QWidget *w, bool grab);
- void grabKeyboard(QWidget *w, bool grab);
- void playSoundFile(const QString&);
- void registerChannel(const QString &channel);
- void sendMessage(const QString &channel, const QString &msg,
- const QByteArray &data);
- void flushCommands();
-#ifndef QT_NO_QWS_INPUTMETHODS
- void sendIMUpdate(int type, int winId, int widgetid);
- void resetIM();
- void sendIMResponse(int winId, int property, const QVariant &result);
- void sendIMMouseEvent(int index, bool isPress);
-#endif
- QWSQCopMessageEvent* waitForQCopResponse();
- void sendFontCommand(int type, const QByteArray &fontName);
-
- void setWindowCaption(QWidget *w, const QString &);
-
- // Lock display for access only by this process
- static bool initLock(const QString &filename, bool create = false);
- static bool grabbed();
- static void grab();
- static void grab(bool write);
- static void ungrab();
-
- static void setTransformation(int transformation, int screenNo = -1);
- static void setRawMouseEventFilter(void (*filter)(QWSMouseEvent *));
-
-private:
- friend int qt_fork_qapplication();
- friend void qt_app_reinit( const QString& newAppName );
- friend class QApplication;
- friend class QCopChannel;
- friend class QWSEmbedWidget;
- friend class QWSEmbedWidgetPrivate;
- class Data;
- friend class Data;
- Data *d;
-
- friend class QWSMemorySurface;
- friend class QWSOnScreenSurface;
- friend class QWSDirectPainterSurface;
- int getPropertyLen;
- char *getPropertyData;
- static QLock *lock;
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QWSDISPLAY_QWS_H
diff --git a/src/gui/embedded/qwsdisplay_qws_p.h b/src/gui/embedded/qwsdisplay_qws_p.h
deleted file mode 100644
index aa174c864d..0000000000
--- a/src/gui/embedded/qwsdisplay_qws_p.h
+++ /dev/null
@@ -1,161 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWSDISPLAY_QWS_P_H
-#define QWSDISPLAY_QWS_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qwsdisplay_qws.h"
-#include "qwssocket_qws.h"
-#include "qwsevent_qws.h"
-#include <private/qwssharedmemory_p.h>
-#include "qwscommand_qws_p.h"
-#include "qwslock_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class QWSDisplay::Data
-{
-public:
- Data(QObject* parent, bool singleProcess = false);
- ~Data();
-
- void flush();
-
- bool queueNotEmpty();
- QWSEvent *dequeue();
- QWSEvent *peek();
-
- bool directServerConnection();
- void fillQueue();
-#ifndef QT_NO_QWS_MULTIPROCESS
- void connectToPipe();
- void waitForConnection();
- void waitForPropertyReply();
- void waitForRegionAck(int winId);
- void waitForRegionEvents(int winId, bool ungrabDisplay);
- bool hasPendingRegionEvents() const;
-#endif
- void waitForCreation();
-#ifndef QT_NO_COP
- void waitForQCopResponse();
-#endif
- void init();
- void reinit( const QString& newAppName );
- void create(int n = 1);
-
- void flushCommands();
- void sendCommand(QWSCommand & cmd);
- void sendSynchronousCommand(QWSCommand & cmd);
-
- QWSEvent *readMore();
-
- int takeId();
-
- void setMouseFilter(void (*filter)(QWSMouseEvent*));
-
- //####public data members
-
-// QWSRegionManager *rgnMan;
- uchar *sharedRam;
-#ifndef QT_NO_QWS_MULTIPROCESS
- QWSSharedMemory shm;
-#endif
- int sharedRamSize;
-
-#ifndef QT_NO_QWS_MULTIPROCESS
- static QWSLock *clientLock;
-
- static bool lockClient(QWSLock::LockType, int timeout = -1);
- static void unlockClient(QWSLock::LockType);
- static bool waitClient(QWSLock::LockType, int timeout = -1);
- static QWSLock* getClientLock();
-#endif // QT_NO_QWS_MULTIPROCESS
-
-private:
-#ifndef QT_NO_QWS_MULTIPROCESS
- QWSSocket *csocket;
-#endif
- QList<QWSEvent*> queue;
-
-#if 0
- void debugQueue() {
- for (int i = 0; i < queue.size(); ++i) {
- QWSEvent *e = queue.at(i);
- qDebug( " ev %d type %d sl %d rl %d", i, e->type, e->simpleLen, e->rawLen);
- }
- }
-#endif
-
- QWSConnectedEvent* connected_event;
- QWSMouseEvent* mouse_event;
- int region_events_count;
- int mouse_state;
- int mouse_winid;
- QPoint region_offset;
- int region_offset_window;
-#ifndef QT_NO_COP
- QWSQCopMessageEvent *qcop_response;
-#endif
- QWSEvent* current_event;
- QList<int> unused_identifiers;
-#ifdef QAPPLICATION_EXTRA_DEBUG
- int mouse_event_count;
-#endif
- void (*mouseFilter)(QWSMouseEvent *);
-
- enum { VariableEvent=-1 };
-
-};
-
-QT_END_NAMESPACE
-
-#endif // QWSDISPLAY_QWS_P_H
diff --git a/src/gui/embedded/qwsembedwidget.cpp b/src/gui/embedded/qwsembedwidget.cpp
deleted file mode 100644
index bbd145caa9..0000000000
--- a/src/gui/embedded/qwsembedwidget.cpp
+++ /dev/null
@@ -1,227 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qwsembedwidget.h"
-
-#ifndef QT_NO_QWSEMBEDWIDGET
-
-#include <qwsdisplay_qws.h>
-#include <private/qwidget_p.h>
-#include <private/qwsdisplay_qws_p.h>
-#include <private/qwscommand_qws_p.h>
-
-QT_BEGIN_NAMESPACE
-
-// TODO:
-// Must remove window decorations from the embedded window
-// Focus In/Out, Keyboard/Mouse...
-//
-// BUG: what if my parent change parent?
-
-class QWSEmbedWidgetPrivate : public QWidgetPrivate
-{
- Q_DECLARE_PUBLIC(QWSEmbedWidget);
-
-public:
- QWSEmbedWidgetPrivate(int winId);
- void updateWindow();
- void resize(const QSize &size);
-
- QWidget *window;
- WId windowId;
- WId embeddedId;
-};
-
-QWSEmbedWidgetPrivate::QWSEmbedWidgetPrivate(int winId)
- : window(0), windowId(0), embeddedId(winId)
-{
-}
-
-void QWSEmbedWidgetPrivate::updateWindow()
-{
- Q_Q(QWSEmbedWidget);
-
- QWidget *win = q->window();
- if (win == window)
- return;
-
- if (window) {
- window->removeEventFilter(q);
- QWSEmbedCommand command;
- command.setData(windowId, embeddedId, QWSEmbedEvent::StopEmbed);
- QWSDisplay::instance()->d->sendCommand(command);
- }
-
- window = win;
- if (!window)
- return;
- windowId = window->winId();
-
- QWSEmbedCommand command;
- command.setData(windowId, embeddedId, QWSEmbedEvent::StartEmbed);
- QWSDisplay::instance()->d->sendCommand(command);
- window->installEventFilter(q);
- q->installEventFilter(q);
-}
-
-void QWSEmbedWidgetPrivate::resize(const QSize &size)
-{
- if (!window)
- return;
-
- Q_Q(QWSEmbedWidget);
-
- QWSEmbedCommand command;
- command.setData(windowId, embeddedId, QWSEmbedEvent::Region,
- QRect(q->mapToGlobal(QPoint(0, 0)), size));
- QWSDisplay::instance()->d->sendCommand(command);
-}
-
-/*!
- \class QWSEmbedWidget
- \since 4.2
- \ingroup qws
- \ingroup advanced
-
- \brief The QWSEmbedWidget class enables embedded top-level widgets
- in Qt for Embedded Linux.
-
- Note that this class is only available in \l{Qt for Embedded Linux}.
-
- QWSEmbedWidget inherits QWidget and acts as any other widget, but
- in addition it is capable of embedding another top-level widget.
-
- An example of use is when painting directly onto the screen using
- the QDirectPainter class. Then the reserved region can be embedded
- into an instance of the QWSEmbedWidget class, providing for
- example event handling and size policies for the reserved region.
-
- All that is required to embed a top-level widget is its window ID.
-
- \sa {Qt for Embedded Linux Architecture}
-*/
-
-/*!
- Constructs a widget with the given \a parent, embedding the widget
- identified by the given window \a id.
-*/
-QWSEmbedWidget::QWSEmbedWidget(WId id, QWidget *parent)
- : QWidget(*new QWSEmbedWidgetPrivate(id), parent, 0)
-{
- Q_D(QWSEmbedWidget);
- d->updateWindow();
-}
-
-/*!
- Destroys this widget.
-*/
-QWSEmbedWidget::~QWSEmbedWidget()
-{
- Q_D(QWSEmbedWidget);
- if (!d->window)
- return;
-
- QWSEmbedCommand command;
- command.setData(d->windowId, d->embeddedId, QWSEmbedEvent::StopEmbed);
- QWSDisplay::instance()->d->sendCommand(command);
-}
-
-/*!
- \reimp
-*/
-bool QWSEmbedWidget::eventFilter(QObject *object, QEvent *event)
-{
- Q_D(QWSEmbedWidget);
- if (object == d->window && event->type() == QEvent::Move)
- resizeEvent(0);
- else if (object == this && event->type() == QEvent::Hide)
- d->resize(QSize());
- return QWidget::eventFilter(object, event);
-}
-
-/*!
- \reimp
-*/
-void QWSEmbedWidget::changeEvent(QEvent *event)
-{
- Q_D(QWSEmbedWidget);
- if (event->type() == QEvent::ParentChange)
- d->updateWindow();
-}
-
-/*!
- \reimp
-*/
-void QWSEmbedWidget::resizeEvent(QResizeEvent*)
-{
- Q_D(QWSEmbedWidget);
- d->resize(rect().size());
-}
-
-/*!
- \reimp
-*/
-void QWSEmbedWidget::moveEvent(QMoveEvent*)
-{
- resizeEvent(0);
-}
-
-/*!
- \reimp
-*/
-void QWSEmbedWidget::hideEvent(QHideEvent*)
-{
- Q_D(QWSEmbedWidget);
- d->resize(QSize());
-}
-
-/*!
- \reimp
-*/
-void QWSEmbedWidget::showEvent(QShowEvent*)
-{
- Q_D(QWSEmbedWidget);
- d->resize(rect().size());
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_QWSEMBEDWIDGET
diff --git a/src/gui/embedded/qwsembedwidget.h b/src/gui/embedded/qwsembedwidget.h
deleted file mode 100644
index d1aa0ee6f4..0000000000
--- a/src/gui/embedded/qwsembedwidget.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWSEMBEDWIDGET_H
-#define QWSEMBEDWIDGET_H
-
-#include <QtGui/qwidget.h>
-
-#ifndef QT_NO_QWSEMBEDWIDGET
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QWSEmbedWidgetPrivate;
-
-class Q_GUI_EXPORT QWSEmbedWidget : public QWidget
-{
- Q_OBJECT
-
-public:
- QWSEmbedWidget(WId winId, QWidget *parent = 0);
- ~QWSEmbedWidget();
-
-protected:
- bool eventFilter(QObject *object, QEvent *event);
- void changeEvent(QEvent *event);
- void resizeEvent(QResizeEvent *event);
- void moveEvent(QMoveEvent *event);
- void hideEvent(QHideEvent *event);
- void showEvent(QShowEvent *event);
-
-private:
- Q_DECLARE_PRIVATE(QWSEmbedWidget)
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QT_NO_QWSEMBEDWIDGET
-#endif // QWSEMBEDWIDGET_H
diff --git a/src/gui/embedded/qwsevent_qws.cpp b/src/gui/embedded/qwsevent_qws.cpp
deleted file mode 100644
index 32aa984844..0000000000
--- a/src/gui/embedded/qwsevent_qws.cpp
+++ /dev/null
@@ -1,216 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qwsevent_qws.h"
-
-QT_BEGIN_NAMESPACE
-
-QWSEvent *QWSEvent::factory(int type)
-{
- QWSEvent *event = 0;
- switch (type) {
- case QWSEvent::Connected:
- event = new QWSConnectedEvent;
- break;
- case QWSEvent::MaxWindowRect:
- event = new QWSMaxWindowRectEvent;
- break;
- case QWSEvent::Mouse:
- event = new QWSMouseEvent;
- break;
- case QWSEvent::Focus:
- event = new QWSFocusEvent;
- break;
- case QWSEvent::Key:
- event = new QWSKeyEvent;
- break;
- case QWSEvent::Region:
- event = new QWSRegionEvent;
- break;
- case QWSEvent::Creation:
- event = new QWSCreationEvent;
- break;
-#ifndef QT_NO_QWS_PROPERTIES
- case QWSEvent::PropertyNotify:
- event = new QWSPropertyNotifyEvent;
- break;
- case QWSEvent::PropertyReply:
- event = new QWSPropertyReplyEvent;
- break;
-#endif // QT_NO_QWS_PROPERTIES
- case QWSEvent::SelectionClear:
- event = new QWSSelectionClearEvent;
- break;
- case QWSEvent::SelectionRequest:
- event = new QWSSelectionRequestEvent;
- break;
- case QWSEvent::SelectionNotify:
- event = new QWSSelectionNotifyEvent;
- break;
-#ifndef QT_NO_COP
- case QWSEvent::QCopMessage:
- event = new QWSQCopMessageEvent;
- break;
-#endif
- case QWSEvent::WindowOperation:
- event = new QWSWindowOperationEvent;
- break;
-
-#ifndef QT_NO_QWS_INPUTMETHODS
- case QWSEvent::IMEvent:
- event = new QWSIMEvent;
- break;
- case QWSEvent::IMQuery:
- event = new QWSIMQueryEvent;
- break;
- case QWSEvent::IMInit:
- event = new QWSIMInitEvent;
- break;
-#endif
-#ifndef QT_NO_QWSEMBEDWIDGET
- case QWSEvent::Embed:
- event = new QWSEmbedEvent;
- break;
-#endif
- case QWSEvent::Font:
- event = new QWSFontEvent;
- break;
- case QWSEvent::ScreenTransformation:
- event = new QWSScreenTransformationEvent;
- break;
- default:
- qCritical("QWSEvent::factory() : Unknown event type %08x!", type);
- }
- return event;
-}
-
-/*!
- \class QWSEvent
- \ingroup qws
-
- \brief The QWSEvent class encapsulates an event in Qt for Embedded Linux.
-
- When running a \l{Qt for Embedded Linux} application, it either runs as a
- server or connects to an existing server. All system generated
- events are passed to the server application which then propagates
- the event to the appropriate client.
-
- Whenever the server receives an event, it queries its stack of
- top-level windows to find the window containing the event's
- position. Each window can identify the client application that
- created it, and returns its ID to the server upon
- request. Finally, the server forwards the event, encapsulated by
- an instance of the QWSEvent class, to the appropriate client.
-
- \image qt-embedded-client.png
-
- The server communicates with the client applications over the UNIX
- domain socket. You can retrieve direct access to all the events a
- client receives from the server, by reimplementing QApplication's
- \l {QApplication::}{qwsEventFilter()} function.
-
- QWSEvent provides the \l Type enum specifying the origin of the
- event. Internally, each type is represented by a QWSEvent
- subclass, e.g., \c QWSKeyEvent.
-
- \sa QWSServer, QWSClient, {Qt for Embedded Linux Architecture}
-*/
-
-/*!
- \enum QWSEvent::Type
-
- This enum describes the origin of the event.
-
- \value NoEvent No event has occurred.
- \value Connected An application has connected to the server.
- \value Mouse A mouse button is pressed or released, or the mouse cursor is moved.
- See also \l{Qt for Embedded Linux Pointer Handling}.
- \value Focus A window has lost or received focus.
- \value Key A key is pressed or released. See also \l{Qt for Embedded Linux Character Input}.
- \value Region A region has changed.
- \value Creation The server has created an ID, typically for a window.
- \value PropertyNotify A property has changed.
- \value PropertyReply The server is responding to a request for a property's value.
- \value SelectionClear A selection is deleted.
- \value SelectionRequest The server has queried for a selection.
- \value SelectionNotify A new selection has been created.
- \value MaxWindowRect The server has changed the maximum window for an application.
- \value QCopMessage A new Qt Cop message has appeared. See also QCopChannel
- \value WindowOperation A window operation, e.g. resizing, has occurred.
- \value IMEvent An input method has been used to enter text for languages with
- non-Latin alphabets. See also QWSInputMethod.
- \value IMQuery An input method query for a specified property has occurred.
- See also QWSInputMethod.
- \value NEvent The number of events has changed.
- \value Embed An event used internally to implement embedded windows. See also
- QWSEmbedWidget.
- \value ScreenTransformation An event used internally to notify the client processes
- that the screen has changed for example, rotation, etc.
- \omitvalue Font
- \omitvalue IMInit
-*/
-
-/*!
- \fn QWSMouseEvent *QWSEvent::asMouse()
- \internal
-*/
-
-/*!
- \fn int QWSEvent::window()
- \internal
-*/
-
-/*!
- \fn int QWSEvent::window() const
- \internal
-*/
-
-/*!
- \fn QWSEvent *QWSEvent::factory(int type)
- \internal
-*/
-
-/*!
- \fn QWSEvent::QWSEvent( int t, int len, char * ptr)
- \internal
-*/
-
-QT_END_NAMESPACE
diff --git a/src/gui/embedded/qwsevent_qws.h b/src/gui/embedded/qwsevent_qws.h
deleted file mode 100644
index 9bc269e193..0000000000
--- a/src/gui/embedded/qwsevent_qws.h
+++ /dev/null
@@ -1,459 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWSEVENT_QWS_H
-#define QWSEVENT_QWS_H
-
-#include <QtGui/qwsutils_qws.h>
-#include <QtGui/qwsprotocolitem_qws.h>
-#include <QtCore/qrect.h>
-#include <QtGui/qregion.h>
-#include <QtCore/qvector.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-struct QWSMouseEvent;
-
-struct QWSEvent : QWSProtocolItem {
-
- QWSEvent(int t, int len, char *ptr) : QWSProtocolItem(t,len,ptr) {}
-
-
-
- enum Type {
- NoEvent,
- Connected,
- Mouse,
- Focus,
- Key,
- Region,
- Creation,
- PropertyNotify,
- PropertyReply,
- SelectionClear,
- SelectionRequest,
- SelectionNotify,
- MaxWindowRect,
- QCopMessage,
- WindowOperation,
- IMEvent,
- IMQuery,
- IMInit,
- Embed,
- Font,
- ScreenTransformation,
- NEvent
- };
-
- QWSMouseEvent *asMouse()
- { return type == Mouse ? reinterpret_cast<QWSMouseEvent*>(this) : 0; }
- int window() { return *(reinterpret_cast<int*>(simpleDataPtr)); }
- int window() const { return *(reinterpret_cast<int*>(simpleDataPtr)); }
- static QWSEvent *factory(int type);
-};
-
-
-//All events must start with windowID
-
-struct QWSConnectedEvent : QWSEvent {
- QWSConnectedEvent()
- : QWSEvent(QWSEvent::Connected, sizeof(simpleData),
- reinterpret_cast<char*>(&simpleData)) {}
-
- void setData(const char *d, int len, bool allocateMem = true) {
- QWSEvent::setData(d, len, allocateMem);
- display = reinterpret_cast<char*>(rawDataPtr);
- }
-
- struct SimpleData {
- int window;
- int len;
- int clientId;
- int servershmid;
- } simpleData;
-
- char *display;
-};
-
-struct QWSMaxWindowRectEvent : QWSEvent {
- QWSMaxWindowRectEvent()
- : QWSEvent(MaxWindowRect, sizeof(simpleData), reinterpret_cast<char*>(&simpleData)) { }
- struct SimpleData {
- int window;
- QRect rect;
- } simpleData;
-};
-
-struct QWSMouseEvent : QWSEvent {
- QWSMouseEvent()
- : QWSEvent(QWSEvent::Mouse, sizeof(simpleData),
- reinterpret_cast<char*>(&simpleData)) {}
- struct SimpleData {
- int window;
- int x_root, y_root, state, delta;
- int time; // milliseconds
- } simpleData;
-};
-
-struct QWSFocusEvent : QWSEvent {
- QWSFocusEvent()
- : QWSEvent(QWSEvent::Focus, sizeof(simpleData), reinterpret_cast<char*>(&simpleData))
- { memset(reinterpret_cast<char*>(&simpleData),0,sizeof(simpleData)); }
- struct SimpleData {
- int window;
- uint get_focus:1;
- } simpleData;
-};
-
-struct QWSKeyEvent: QWSEvent {
- QWSKeyEvent()
- : QWSEvent(QWSEvent::Key, sizeof(simpleData),
- reinterpret_cast<char*>(&simpleData)) {}
- struct SimpleData {
- int window;
- uint keycode;
- Qt::KeyboardModifiers modifiers;
- ushort unicode;
- uint is_press:1;
- uint is_auto_repeat:1;
- } simpleData;
-};
-
-
-struct QWSCreationEvent : QWSEvent {
- QWSCreationEvent()
- : QWSEvent(QWSEvent::Creation, sizeof(simpleData),
- reinterpret_cast<char*>(&simpleData)) {}
- struct SimpleData {
- int objectid;
- int count;
- } simpleData;
-};
-
-#ifndef QT_NO_QWS_PROPERTIES
-struct QWSPropertyNotifyEvent : QWSEvent {
- QWSPropertyNotifyEvent()
- : QWSEvent(QWSEvent::PropertyNotify, sizeof(simpleData),
- reinterpret_cast<char*>(&simpleData)) {}
- enum State {
- PropertyNewValue,
- PropertyDeleted
- };
- struct SimpleData {
- int window;
- int property;
- int state;
- } simpleData;
-};
-#endif
-
-struct QWSSelectionClearEvent : QWSEvent {
- QWSSelectionClearEvent()
- : QWSEvent(QWSEvent::SelectionClear, sizeof(simpleData),
- reinterpret_cast<char*>(&simpleData)) {}
- struct SimpleData {
- int window;
- } simpleData;
-};
-
-struct QWSSelectionRequestEvent : QWSEvent {
- QWSSelectionRequestEvent()
- : QWSEvent(QWSEvent::SelectionRequest, sizeof(simpleData),
- reinterpret_cast<char*>(&simpleData)) {}
- struct SimpleData {
- int window;
- int requestor; // window which wants the selection
- int property; // property on requestor into which the selection should be stored, normally QWSProperty::PropSelection
- int mimeTypes; // Value is stored in the property mimeType on the requestor window. This value may contain
- // multiple mimeTypes separated by ;; where the order reflects the priority
- } simpleData;
-};
-
-struct QWSSelectionNotifyEvent : QWSEvent {
- QWSSelectionNotifyEvent()
- : QWSEvent(QWSEvent::SelectionNotify, sizeof(simpleData),
- reinterpret_cast<char*>(&simpleData)) {}
- struct SimpleData {
- int window;
- int requestor; // the window which wanted the selection and to which this event is sent
- int property; // property of requestor in which the data of the selection is stored
- int mimeType; // a property on the requestor in which the mime type in which the selection is, is stored
- } simpleData;
-};
-
-//complex events:
-
-struct QWSRegionEvent : QWSEvent {
- QWSRegionEvent()
- : QWSEvent(QWSEvent::Region, sizeof(simpleData),
- reinterpret_cast<char*>(&simpleData))
- { memset(reinterpret_cast<char*>(&simpleData),0,sizeof(simpleData)); }
-
- void setData(const char *d, int len, bool allocateMem = true) {
- QWSEvent::setData(d, len, allocateMem);
- rectangles = reinterpret_cast<QRect*>(rawDataPtr);
- }
-
- void setData(int winId, const QRegion &region, uint type) {
- const QVector<QRect> rects = region.rects();
- setData(reinterpret_cast<const char*>(rects.constData()),
- rects.size() * sizeof(QRect));
- simpleData.window = winId;
- simpleData.nrectangles = rects.size();
- simpleData.type = type;
-#ifdef QT_QWS_CLIENTBLIT
- simpleData.id = 0;
-#endif
- }
-
- enum Type {Allocation
-#ifdef QT_QWS_CLIENTBLIT
- , DirectPaint
-#endif
- };
- struct SimpleData {
- int window;
- int nrectangles;
-#ifdef QT_QWS_CLIENTBLIT
- int id;
-#endif
- uint type:8;
- } simpleData;
-
- QRect *rectangles;
-};
-
-#ifndef QT_NO_QWSEMBEDWIDGET
-struct QWSEmbedEvent : QWSEvent
-{
- QWSEmbedEvent() : QWSEvent(QWSEvent::Embed, sizeof(simpleData),
- reinterpret_cast<char*>(&simpleData))
- {}
-
- enum Type { StartEmbed = 1, StopEmbed = 2, Region = 4 };
-
- void setData(const char *d, int len, bool allocateMem = true) {
- QWSEvent::setData(d, len, allocateMem);
- region.setRects(reinterpret_cast<const QRect *>(rawDataPtr),
- simpleData.nrectangles);
- }
-
- void setData(int winId, Type type, const QRegion &reg = QRegion()) {
- simpleData.window = winId;
- simpleData.nrectangles = reg.rects().size();
- simpleData.type = type;
- region = reg;
- const QVector<QRect> rects = reg.rects();
- QWSEvent::setData(reinterpret_cast<const char*>(rects.data()),
- rects.size() * sizeof(QRect));
- }
-
- struct SimpleData {
- int window;
- int nrectangles;
- Type type;
- } simpleData;
-
- QRegion region;
-};
-#endif // QT_NO_QWSEMBEDWIDGET
-
-#ifndef QT_NO_QWS_PROPERTIES
-struct QWSPropertyReplyEvent : QWSEvent {
- QWSPropertyReplyEvent()
- : QWSEvent(QWSEvent::PropertyReply, sizeof(simpleData),
- reinterpret_cast<char*>(&simpleData)) {}
-
- void setData(const char *d, int len, bool allocateMem = true) {
- QWSEvent::setData(d, len, allocateMem);
- data = reinterpret_cast<char*>(rawDataPtr);
- }
-
- struct SimpleData {
- int window;
- int property;
- int len;
- } simpleData;
- char *data;
-};
-#endif //QT_NO_QWS_PROPERTIES
-
-#ifndef QT_NO_COP
-struct QWSQCopMessageEvent : QWSEvent {
- QWSQCopMessageEvent()
- : QWSEvent(QWSEvent::QCopMessage, sizeof(simpleData),
- reinterpret_cast<char*>(&simpleData))
- { memset(reinterpret_cast<char*>(&simpleData),0,sizeof(simpleData)); }
-
- void setData(const char *d, int len, bool allocateMem = true) {
- QWSEvent::setData(d, len, allocateMem);
- char* p = rawDataPtr;
- channel = QByteArray(p, simpleData.lchannel);
- p += simpleData.lchannel;
- message = QByteArray(p, simpleData.lmessage);
- p += simpleData.lmessage;
- data = QByteArray(p, simpleData.ldata);
- }
-
- void setDataDirect(const char *d, int len) {
- QWSEvent::setData(d, len, false);
- deleteRaw = true;
- }
-
- struct SimpleData {
- bool is_response;
- int lchannel;
- int lmessage;
- int ldata;
- } simpleData;
-
- QByteArray channel;
- QByteArray message;
- QByteArray data;
-};
-
-#endif
-
-struct QWSWindowOperationEvent : QWSEvent {
- QWSWindowOperationEvent()
- : QWSEvent(WindowOperation, sizeof(simpleData), reinterpret_cast<char*>(&simpleData)) { }
-
- enum Operation { Show, Hide, ShowMaximized, ShowNormal, ShowMinimized, Close };
- struct SimpleData {
- int window;
- Operation op;
- } simpleData;
-};
-
-#ifndef QT_NO_QWS_INPUTMETHODS
-
-
-struct QWSIMEvent : QWSEvent {
- QWSIMEvent()
- : QWSEvent(IMEvent, sizeof(simpleData), reinterpret_cast<char*>(&simpleData))
- { memset(reinterpret_cast<char*>(&simpleData),0,sizeof(simpleData)); }
-
- struct SimpleData {
- int window;
- int replaceFrom;
- int replaceLength;
- } simpleData;
-
- void setData(const char *d, int len, bool allocateMem = true) {
- QWSEvent::setData(d, len, allocateMem);
- streamingData = QByteArray::fromRawData(rawDataPtr, len);
- }
- QByteArray streamingData;
-};
-
-
-struct QWSIMInitEvent : QWSEvent {
- QWSIMInitEvent()
- : QWSEvent(IMInit, sizeof(simpleData), reinterpret_cast<char*>(&simpleData))
- { memset(reinterpret_cast<char*>(&simpleData),0,sizeof(simpleData)); }
-
- struct SimpleData {
- int window;
- int existence;
- } simpleData;
-
- void setData(const char *d, int len, bool allocateMem = true) {
- QWSEvent::setData(d, len, allocateMem);
- streamingData = QByteArray::fromRawData(rawDataPtr, len);
- }
- QByteArray streamingData;
-};
-
-
-struct QWSIMQueryEvent : QWSEvent {
- QWSIMQueryEvent()
- : QWSEvent(QWSEvent::IMQuery, sizeof(simpleData),
- reinterpret_cast<char*>(&simpleData)) {}
-
- struct SimpleData {
- int window;
- int property;
- } simpleData;
-
-};
-
-#endif
-
-struct QWSFontEvent : QWSEvent {
- QWSFontEvent()
- : QWSEvent(QWSEvent::Font, sizeof(simpleData),
- reinterpret_cast<char*>(&simpleData)) {}
-
- enum EventType {
- FontRemoved
- };
-
- void setData(const char *d, int len, bool allocateMem = true) {
- QWSEvent::setData(d, len, allocateMem);
- fontName = QByteArray::fromRawData(rawDataPtr, len);
- }
-
- struct SimpleData {
- uchar type;
- } simpleData;
- QByteArray fontName;
-};
-
-struct QWSScreenTransformationEvent : QWSEvent {
- QWSScreenTransformationEvent()
- : QWSEvent(QWSEvent::ScreenTransformation, sizeof(simpleData),
- reinterpret_cast<char*>(&simpleData)) {}
-
- struct SimpleData {
- int screen;
- int transformation;
- } simpleData;
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QWSEVENT_QWS_H
diff --git a/src/gui/embedded/qwslock.cpp b/src/gui/embedded/qwslock.cpp
deleted file mode 100644
index a64dc3d9c4..0000000000
--- a/src/gui/embedded/qwslock.cpp
+++ /dev/null
@@ -1,236 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qwslock_p.h"
-
-#ifndef QT_NO_QWS_MULTIPROCESS
-
-#include "qwssignalhandler_p.h"
-
-#include <qglobal.h>
-#include <qdebug.h>
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/ipc.h>
-#include <sys/sem.h>
-#include <sys/time.h>
-#include <time.h>
-#ifdef Q_OS_LINUX
-#include <linux/version.h>
-#endif
-#include <unistd.h>
-
-#include <private/qcore_unix_p.h>
-
-QT_BEGIN_NAMESPACE
-
-#ifdef QT_NO_SEMAPHORE
-#error QWSLock currently requires semaphores
-#endif
-
-QWSLock::QWSLock()
-{
- semId = semget(IPC_PRIVATE, 3, IPC_CREAT | 0666);
-
- if (semId == -1) {
- perror("QWSLock::QWSLock");
- qFatal("Unable to create semaphore");
- }
- QWSSignalHandler::instance()->addSemaphore(semId);
-
- qt_semun semval;
- semval.val = 1;
-
- if (semctl(semId, BackingStore, SETVAL, semval) == -1) {
- perror("QWSLock::QWSLock");
- qFatal("Unable to initialize backingstore semaphore");
- }
- lockCount[BackingStore] = 0;
-
- if (semctl(semId, Communication, SETVAL, semval) == -1) {
- perror("QWSLock::QWSLock");
- qFatal("Unable to initialize communication semaphore");
- }
- lockCount[Communication] = 0;
-
- semval.val = 0;
- if (semctl(semId, RegionEvent, SETVAL, semval) == -1) {
- perror("QWSLock::QWSLock");
- qFatal("Unable to initialize region event semaphore");
- }
-}
-
-QWSLock::QWSLock(int id)
-{
- semId = id;
- QWSSignalHandler::instance()->addSemaphore(semId);
- lockCount[0] = lockCount[1] = 0;
-}
-
-QWSLock::~QWSLock()
-{
- if (semId == -1)
- return;
- QWSSignalHandler::instance()->removeSemaphore(semId);
-}
-
-static bool forceLock(int semId, unsigned short semNum, int)
-{
- int ret;
- do {
- sembuf sops = { semNum, -1, 0 };
-
- // As the BackingStore lock is a mutex, and only one process may own
- // the lock, it's safe to use SEM_UNDO. On the other hand, the
- // Communication lock is locked by the client but unlocked by the
- // server and therefore can't use SEM_UNDO.
- if (semNum == QWSLock::BackingStore)
- sops.sem_flg |= SEM_UNDO;
-
- ret = semop(semId, &sops, 1);
- if (ret == -1 && errno != EINTR)
- qDebug("QWSLock::lock: %s", strerror(errno));
- } while (ret == -1 && errno == EINTR);
-
- return (ret != -1);
-}
-
-static bool up(int semId, unsigned short semNum)
-{
- int ret;
- do {
- sembuf sops = { semNum, 1, 0 };
- ret = semop(semId, &sops, 1);
- if (ret == -1 && errno != EINTR)
- qDebug("QWSLock::up: %s", strerror(errno));
- } while (ret == -1 && errno == EINTR);
-
- return (ret != -1);
-}
-
-static bool down(int semId, unsigned short semNum)
-{
- int ret;
- do {
- sembuf sops = { semNum, -1, 0 };
- ret = semop(semId, &sops, 1);
- if (ret == -1 && errno != EINTR)
- qDebug("QWSLock::down: %s", strerror(errno));
- } while (ret == -1 && errno == EINTR);
-
- return (ret != -1);
-}
-
-static int getValue(int semId, unsigned short semNum)
-{
- int ret;
- do {
- ret = semctl(semId, semNum, GETVAL, 0);
- if (ret == -1 && errno != EINTR)
- qDebug("QWSLock::getValue: %s", strerror(errno));
- } while (ret == -1 && errno == EINTR);
-
- return ret;
-}
-
-bool QWSLock::lock(LockType type, int timeout)
-{
- if (type == RegionEvent)
- return up(semId, RegionEvent);
-
- if (hasLock(type)) {
- ++lockCount[type];
- return true;
- }
-
- if (!forceLock(semId, type, timeout))
- return false;
- ++lockCount[type];
- return true;
-}
-
-bool QWSLock::hasLock(LockType type)
-{
- if (type == RegionEvent)
- return (getValue(semId, RegionEvent) == 0);
-
- return (lockCount[type] > 0);
-}
-
-void QWSLock::unlock(LockType type)
-{
- if (type == RegionEvent) {
- down(semId, RegionEvent);
- return;
- }
-
- if (hasLock(type)) {
- --lockCount[type];
- if (hasLock(type))
- return;
- }
-
- const unsigned short semNum = type;
- int ret;
- do {
- sembuf sops = {semNum, 1, 0};
- if (semNum == QWSLock::BackingStore)
- sops.sem_flg |= SEM_UNDO;
-
- ret = semop(semId, &sops, 1);
- if (ret == -1 && errno != EINTR)
- qDebug("QWSLock::unlock: %s", strerror(errno));
- } while (ret == -1 && errno == EINTR);
-}
-
-bool QWSLock::wait(LockType type, int timeout)
-{
- bool ok = forceLock(semId, type, timeout);
- if (ok)
- unlock(type);
- return ok;
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_QWS_MULTIPROCESS
diff --git a/src/gui/embedded/qwslock_p.h b/src/gui/embedded/qwslock_p.h
deleted file mode 100644
index 9a7f27979b..0000000000
--- a/src/gui/embedded/qwslock_p.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWSLOCK_P_H
-#define QWSLOCK_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. This header file may
-// change from version to version without notice, or even be
-// removed.
-//
-// We mean it.
-//
-
-#include <qglobal.h>
-
-QT_BEGIN_NAMESPACE
-
-#ifndef QT_NO_QWS_MULTIPROCESS
-
-class QWSLock
-{
-public:
- enum LockType { BackingStore, Communication, RegionEvent };
-
- QWSLock();
- QWSLock(int lockId);
- ~QWSLock();
-
- bool lock(LockType type, int timeout = -1);
- void unlock(LockType type);
- bool wait(LockType type, int timeout = -1);
- bool hasLock(LockType type);
- int id() const { return semId; }
-
-private:
- int semId;
- int lockCount[2];
-};
-
-
-QT_END_NAMESPACE
-#endif // QT_NO_QWS_MULTIPROCESS
-#endif // QWSLOCK_P_H
diff --git a/src/gui/embedded/qwsmanager_p.h b/src/gui/embedded/qwsmanager_p.h
deleted file mode 100644
index 425c4e0098..0000000000
--- a/src/gui/embedded/qwsmanager_p.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWSMANAGER_P_H
-#define QWSMANAGER_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of the QLibrary class. This header file may change from
-// version to version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "QtGui/qregion.h"
-#include "QtGui/qdecoration_qws.h"
-
-#ifndef QT_NO_QWS_MANAGER
-
-#include "QtCore/qhash.h"
-
-QT_BEGIN_NAMESPACE
-
-class QWidget;
-class QMenu;
-
-class QWSManagerPrivate : public QObjectPrivate
-{
- Q_DECLARE_PUBLIC(QWSManager)
-public:
- QWSManagerPrivate();
-
- int activeRegion;
- QWidget *managed;
- QMenu *popup;
-
- enum MenuAction {
- NormalizeAction,
- TitleAction,
- BottomRightAction,
- MinimizeAction,
- MaximizeAction,
- CloseAction,
- LastMenuAction
- };
- QAction *menuActions[LastMenuAction];
-
- static QWidget *active;
- static QPoint mousePos;
-
- // Region caching to avoid getting a regiontype's
- // QRegion for each mouse move event
- int previousRegionType;
- bool previousRegionRepainted; // Hover/Press handled
- bool entireDecorationNeedsRepaint;
- struct RegionCaching {
- int regionType;
- QRegion region;
- Qt::WindowFlags windowFlags;
- QRect windowGeometry;
- } cached_region;
-
- bool newCachedRegion(const QPoint &pos);
- int cachedRegionAt()
- { return cached_region.regionType; }
-
- void dirtyRegion(int decorationRegion,
- QDecoration::DecorationState state,
- const QRegion &clip = QRegion());
- void clearDirtyRegions();
-
- QList<int> dirtyRegions;
- QList<QDecoration::DecorationState> dirtyStates;
- QRegion dirtyClip;
-};
-
-#endif // QT_NO_QWS_MANAGER
-
-QT_END_NAMESPACE
-
-#endif // QWSMANAGER_P_H
diff --git a/src/gui/embedded/qwsmanager_qws.cpp b/src/gui/embedded/qwsmanager_qws.cpp
deleted file mode 100644
index 7612203c80..0000000000
--- a/src/gui/embedded/qwsmanager_qws.cpp
+++ /dev/null
@@ -1,537 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qwsmanager_qws.h"
-
-#ifndef QT_NO_QWS_MANAGER
-
-#include "qdrawutil.h"
-#include "qapplication.h"
-#include "qstyle.h"
-#include "qwidget.h"
-#include "qmenu.h"
-#include "qpainter.h"
-#include "private/qpainter_p.h"
-#include "qregion.h"
-#include "qevent.h"
-#include "qcursor.h"
-#include "qwsdisplay_qws.h"
-#include "qdesktopwidget.h"
-
-#include <private/qapplication_p.h>
-#include <private/qwidget_p.h>
-#include <private/qbackingstore_p.h>
-#include <private/qwindowsurface_qws_p.h>
-#include "qdecorationfactory_qws.h"
-
-#include "qlayout.h"
-
-#include "qwsmanager_p.h"
-
-#include <qdebug.h>
-
-QT_BEGIN_NAMESPACE
-
-QWidget *QWSManagerPrivate::active = 0;
-QPoint QWSManagerPrivate::mousePos;
-
-
-QWSManagerPrivate::QWSManagerPrivate()
- : QObjectPrivate(), activeRegion(QDecoration::None), managed(0), popup(0),
- previousRegionType(0), previousRegionRepainted(false), entireDecorationNeedsRepaint(false)
-{
- cached_region.regionType = 0;
-}
-
-QRegion &QWSManager::cachedRegion()
-{
- return d_func()->cached_region.region;
-}
-
-/*!
- \class QWSManager
- \ingroup qws
- \internal
-*/
-
-/*!
-
-*/
-QWSManager::QWSManager(QWidget *w)
- : QObject(*new QWSManagerPrivate, (QObject*)0)
-{
- d_func()->managed = w;
-
-}
-
-QWSManager::~QWSManager()
-{
- Q_D(QWSManager);
-#ifndef QT_NO_MENU
- if (d->popup)
- delete d->popup;
-#endif
- if (d->managed == QWSManagerPrivate::active)
- QWSManagerPrivate::active = 0;
-}
-
-QWidget *QWSManager::widget()
-{
- Q_D(QWSManager);
- return d->managed;
-}
-
-QWidget *QWSManager::grabbedMouse()
-{
- return QWSManagerPrivate::active;
-}
-
-QRegion QWSManager::region()
-{
- Q_D(QWSManager);
- return QApplication::qwsDecoration().region(d->managed, d->managed->geometry());
-}
-
-bool QWSManager::event(QEvent *e)
-{
- if (QObject::event(e))
- return true;
-
- switch (e->type()) {
- case QEvent::MouseMove:
- mouseMoveEvent((QMouseEvent*)e);
- break;
-
- case QEvent::MouseButtonPress:
- mousePressEvent((QMouseEvent*)e);
- break;
-
- case QEvent::MouseButtonRelease:
- mouseReleaseEvent((QMouseEvent*)e);
- break;
-
- case QEvent::MouseButtonDblClick:
- mouseDoubleClickEvent((QMouseEvent*)e);
- break;
-
- case QEvent::Paint:
- paintEvent((QPaintEvent*)e);
- break;
-
- default:
- return false;
- break;
- }
-
- return true;
-}
-
-void QWSManager::mousePressEvent(QMouseEvent *e)
-{
- Q_D(QWSManager);
- d->mousePos = e->globalPos();
- d->activeRegion = QApplication::qwsDecoration().regionAt(d->managed, d->mousePos);
- if(d->cached_region.regionType)
- d->previousRegionRepainted |= repaintRegion(d->cached_region.regionType, QDecoration::Pressed);
-
- if (d->activeRegion == QDecoration::Menu) {
- QPoint pos = (QApplication::layoutDirection() == Qt::LeftToRight
- ? d->managed->geometry().topLeft()
- : d->managed->geometry().topRight());
- menu(pos);
- }
- if (d->activeRegion != QDecoration::None &&
- d->activeRegion != QDecoration::Menu) {
- d->active = d->managed;
- d->managed->grabMouse();
- }
- if (d->activeRegion != QDecoration::None &&
- d->activeRegion != QDecoration::Close &&
- d->activeRegion != QDecoration::Minimize &&
- d->activeRegion != QDecoration::Menu) {
- d->managed->raise();
- }
-
- if (e->button() == Qt::RightButton) {
- menu(e->globalPos());
- }
-}
-
-void QWSManager::mouseReleaseEvent(QMouseEvent *e)
-{
- Q_D(QWSManager);
- d->managed->releaseMouse();
- if (d->cached_region.regionType && d->previousRegionRepainted && QApplication::mouseButtons() == 0) {
- bool doesHover = repaintRegion(d->cached_region.regionType, QDecoration::Hover);
- if (!doesHover) {
- repaintRegion(d->cached_region.regionType, QDecoration::Normal);
- d->previousRegionRepainted = false;
- }
- }
-
- if (e->button() == Qt::LeftButton) {
- //handleMove();
- int itm = QApplication::qwsDecoration().regionAt(d->managed, e->globalPos());
- int activatedItem = d->activeRegion;
- d->activeRegion = QDecoration::None;
- d->active = 0;
- if (activatedItem == itm)
- QApplication::qwsDecoration().regionClicked(d->managed, itm);
- } else if (d->activeRegion == QDecoration::None) {
- d->active = 0;
- }
-}
-
-void QWSManager::mouseDoubleClickEvent(QMouseEvent *e)
-{
- Q_D(QWSManager);
- if (e->button() == Qt::LeftButton)
- QApplication::qwsDecoration().regionDoubleClicked(d->managed,
- QApplication::qwsDecoration().regionAt(d->managed, e->globalPos()));
-}
-
-static inline Qt::CursorShape regionToShape(int region)
-{
- if (region == QDecoration::None)
- return Qt::ArrowCursor;
-
- static const struct {
- int region;
- Qt::CursorShape shape;
- } r2s[] = {
- { QDecoration::TopLeft, Qt::SizeFDiagCursor },
- { QDecoration::Top, Qt::SizeVerCursor},
- { QDecoration::TopRight, Qt::SizeBDiagCursor},
- { QDecoration::Left, Qt::SizeHorCursor},
- { QDecoration::Right, Qt::SizeHorCursor},
- { QDecoration::BottomLeft, Qt::SizeBDiagCursor},
- { QDecoration::Bottom, Qt::SizeVerCursor},
- { QDecoration::BottomRight, Qt::SizeFDiagCursor},
- { QDecoration::None, Qt::ArrowCursor}
- };
-
- int i = 0;
- while (region != r2s[i].region && r2s[i].region)
- ++i;
- return r2s[i].shape;
-}
-
-void QWSManager::mouseMoveEvent(QMouseEvent *e)
-{
- Q_D(QWSManager);
- if (d->newCachedRegion(e->globalPos())) {
- if(d->previousRegionType && d->previousRegionRepainted)
- repaintRegion(d->previousRegionType, QDecoration::Normal);
- if(d->cached_region.regionType) {
- d->previousRegionRepainted = repaintRegion(d->cached_region.regionType, QDecoration::Hover);
- }
- }
-
-
-#ifndef QT_NO_CURSOR
- if (d->managed->minimumSize() != d->managed->maximumSize()) {
- QWSDisplay *qwsd = QApplication::desktop()->qwsDisplay();
- qwsd->selectCursor(d->managed, regionToShape(d->cachedRegionAt()));
- }
-#endif //QT_NO_CURSOR
-
- if (d->activeRegion)
- handleMove(e->globalPos());
-}
-
-void QWSManager::handleMove(QPoint g)
-{
- Q_D(QWSManager);
-
- // don't allow dragging to where the user probably cannot click!
- QApplicationPrivate *ap = QApplicationPrivate::instance();
- const QRect maxWindowRect = ap->maxWindowRect(qt_screen);
- if (maxWindowRect.isValid()) {
- if (g.x() < maxWindowRect.x())
- g.setX(maxWindowRect.x());
- if (g.y() < maxWindowRect.y())
- g.setY(maxWindowRect.y());
- if (g.x() > maxWindowRect.right())
- g.setX(maxWindowRect.right());
- if (g.y() > maxWindowRect.bottom())
- g.setY(maxWindowRect.bottom());
- }
-
- if (g == d->mousePos)
- return;
-
- if ( d->managed->isMaximized() )
- return;
-
- int x = d->managed->geometry().x();
- int y = d->managed->geometry().y();
- int w = d->managed->width();
- int h = d->managed->height();
-
- QRect geom(d->managed->geometry());
-
- QPoint delta = g - d->mousePos;
- d->mousePos = g;
-
- if (d->activeRegion == QDecoration::Title) {
- geom = QRect(x + delta.x(), y + delta.y(), w, h);
- } else {
- bool keepTop = true;
- bool keepLeft = true;
- switch (d->activeRegion) {
- case QDecoration::Top:
- geom.setTop(geom.top() + delta.y());
- keepTop = false;
- break;
- case QDecoration::Bottom:
- geom.setBottom(geom.bottom() + delta.y());
- keepTop = true;
- break;
- case QDecoration::Left:
- geom.setLeft(geom.left() + delta.x());
- keepLeft = false;
- break;
- case QDecoration::Right:
- geom.setRight(geom.right() + delta.x());
- keepLeft = true;
- break;
- case QDecoration::TopRight:
- geom.setTopRight(geom.topRight() + delta);
- keepLeft = true;
- keepTop = false;
- break;
- case QDecoration::TopLeft:
- geom.setTopLeft(geom.topLeft() + delta);
- keepLeft = false;
- keepTop = false;
- break;
- case QDecoration::BottomLeft:
- geom.setBottomLeft(geom.bottomLeft() + delta);
- keepLeft = false;
- keepTop = true;
- break;
- case QDecoration::BottomRight:
- geom.setBottomRight(geom.bottomRight() + delta);
- keepLeft = true;
- keepTop = true;
- break;
- default:
- return;
- }
-
- QSize newSize = QLayout::closestAcceptableSize(d->managed, geom.size());
-
- int dx = newSize.width() - geom.width();
- int dy = newSize.height() - geom.height();
-
- if (keepTop) {
- geom.setBottom(geom.bottom() + dy);
- d->mousePos.ry() += dy;
- } else {
- geom.setTop(geom.top() - dy);
- d->mousePos.ry() -= dy;
- }
- if (keepLeft) {
- geom.setRight(geom.right() + dx);
- d->mousePos.rx() += dx;
- } else {
- geom.setLeft(geom.left() - dx);
- d->mousePos.rx() -= dx;
- }
- }
- if (geom != d->managed->geometry()) {
- QApplication::sendPostedEvents();
- d->managed->setGeometry(geom);
- }
-}
-
-void QWSManager::paintEvent(QPaintEvent *)
-{
- Q_D(QWSManager);
- d->dirtyRegion(QDecoration::All, QDecoration::Normal);
-}
-
-void QWSManagerPrivate::dirtyRegion(int decorationRegion,
- QDecoration::DecorationState state,
- const QRegion &clip)
-{
- QTLWExtra *topextra = managed->d_func()->extra->topextra;
- QWidgetBackingStore *bs = topextra->backingStore.data();
- const bool pendingUpdateRequest = bs->isDirty();
-
- if (decorationRegion == QDecoration::All) {
- if (clip.isEmpty())
- entireDecorationNeedsRepaint = true;
- dirtyRegions.clear();
- dirtyStates.clear();
- }
- int i = dirtyRegions.indexOf(decorationRegion);
- if (i >= 0) {
- dirtyRegions.removeAt(i);
- dirtyStates.removeAt(i);
- }
-
- dirtyRegions.append(decorationRegion);
- dirtyStates.append(state);
- if (!entireDecorationNeedsRepaint)
- dirtyClip += clip;
-
- if (!pendingUpdateRequest)
- QApplication::postEvent(managed, new QEvent(QEvent::UpdateRequest), Qt::LowEventPriority);
-}
-
-void QWSManagerPrivate::clearDirtyRegions()
-{
- dirtyRegions.clear();
- dirtyStates.clear();
- dirtyClip = QRegion();
- entireDecorationNeedsRepaint = false;
-}
-
-bool QWSManager::repaintRegion(int decorationRegion, QDecoration::DecorationState state)
-{
- Q_D(QWSManager);
-
- d->dirtyRegion(decorationRegion, state);
- return true;
-}
-
-void QWSManager::menu(const QPoint &pos)
-{
-#ifdef QT_NO_MENU
- Q_UNUSED(pos);
-#else
- Q_D(QWSManager);
- if (d->popup)
- delete d->popup;
-
- // Basic window operation menu
- d->popup = new QMenu();
- QApplication::qwsDecoration().buildSysMenu(d->managed, d->popup);
- connect(d->popup, SIGNAL(triggered(QAction*)), SLOT(menuTriggered(QAction*)));
-
- d->popup->popup(pos);
- d->activeRegion = QDecoration::None;
-#endif // QT_NO_MENU
-}
-
-void QWSManager::menuTriggered(QAction *action)
-{
-#ifdef QT_NO_MENU
- Q_UNUSED(action);
-#else
- Q_D(QWSManager);
- QApplication::qwsDecoration().menuTriggered(d->managed, action);
- d->popup->deleteLater();
- d->popup = 0;
-#endif
-}
-
-void QWSManager::startMove()
-{
- Q_D(QWSManager);
- d->mousePos = QCursor::pos();
- d->activeRegion = QDecoration::Title;
- d->active = d->managed;
- d->managed->grabMouse();
-}
-
-void QWSManager::startResize()
-{
- Q_D(QWSManager);
- d->activeRegion = QDecoration::BottomRight;
- d->active = d->managed;
- d->managed->grabMouse();
-}
-
-void QWSManager::maximize()
-{
- Q_D(QWSManager);
- // find out how much space the decoration needs
- const int screen = QApplication::desktop()->screenNumber(d->managed);
- const QRect desk = QApplication::desktop()->availableGeometry(screen);
- QRect dummy(0, 0, 1, 1);
- QRect nr;
- QRegion r = QApplication::qwsDecoration().region(d->managed, dummy);
- if (r.isEmpty()) {
- nr = desk;
- } else {
- r += dummy; // make sure we get the full window region in case of 0 width borders
- QRect rect = r.boundingRect();
- nr = QRect(desk.x()-rect.x(), desk.y()-rect.y(),
- desk.width() - (rect.width()==1 ? 0 : rect.width()-1), // ==1 -> dummy
- desk.height() - (rect.height()==1 ? 0 : rect.height()-1));
- }
- d->managed->setGeometry(nr);
-}
-
-bool QWSManagerPrivate::newCachedRegion(const QPoint &pos)
-{
- // Check if anything has changed that would affect the region caching
- if (managed->windowFlags() == cached_region.windowFlags
- && managed->geometry() == cached_region.windowGeometry
- && cached_region.region.contains(pos))
- return false;
-
- // Update the cached region
- int reg = QApplication::qwsDecoration().regionAt(managed, pos);
- if (QWidget::mouseGrabber())
- reg = QDecoration::None;
-
- previousRegionType = cached_region.regionType;
- cached_region.regionType = reg;
- cached_region.region = QApplication::qwsDecoration().region(managed, managed->geometry(),
- reg);
- // Make room for borders around the widget, even if the decoration doesn't have a frame.
- if (reg && !(reg & int(QDecoration::Borders))) {
- cached_region.region -= QApplication::qwsDecoration().region(managed, managed->geometry(), QDecoration::Borders);
- }
- cached_region.windowFlags = managed->windowFlags();
- cached_region.windowGeometry = managed->geometry();
-// QRect rec = cached_region.region.boundingRect();
-// qDebug("Updated cached region: 0x%04x (%d, %d) (%d, %d, %d, %d)",
-// reg, pos.x(), pos.y(), rec.x(), rec.y(), rec.right(), rec.bottom());
- return true;
-}
-
-QT_END_NAMESPACE
-
-#endif //QT_NO_QWS_MANAGER
diff --git a/src/gui/embedded/qwsmanager_qws.h b/src/gui/embedded/qwsmanager_qws.h
deleted file mode 100644
index be70bd8c9d..0000000000
--- a/src/gui/embedded/qwsmanager_qws.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWSMANAGER_QWS_H
-#define QWSMANAGER_QWS_H
-
-#include <QtGui/qpixmap.h>
-#include <QtCore/qobject.h>
-#include <QtGui/qdecoration_qws.h>
-#include <QtGui/qevent.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_QWS_MANAGER
-
-class QAction;
-class QPixmap;
-class QWidget;
-class QPopupMenu;
-class QRegion;
-class QMouseEvent;
-class QWSManagerPrivate;
-
-class Q_GUI_EXPORT QWSManager : public QObject
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QWSManager)
-public:
- explicit QWSManager(QWidget *);
- ~QWSManager();
-
- static QDecoration *newDefaultDecoration();
-
- QWidget *widget();
- static QWidget *grabbedMouse();
- void maximize();
- void startMove();
- void startResize();
-
- QRegion region();
- QRegion &cachedRegion();
-
-protected Q_SLOTS:
- void menuTriggered(QAction *action);
-
-protected:
- void handleMove(QPoint g);
-
- virtual bool event(QEvent *e);
- virtual void mouseMoveEvent(QMouseEvent *);
- virtual void mousePressEvent(QMouseEvent *);
- virtual void mouseReleaseEvent(QMouseEvent *);
- virtual void mouseDoubleClickEvent(QMouseEvent *);
- virtual void paintEvent(QPaintEvent *);
- bool repaintRegion(int region, QDecoration::DecorationState state);
-
- void menu(const QPoint &);
-
-private:
- friend class QWidget;
- friend class QETWidget;
- friend class QWidgetPrivate;
- friend class QApplication;
- friend class QApplicationPrivate;
- friend class QWidgetBackingStore;
- friend class QWSWindowSurface;
- friend class QGLDrawable;
-};
-
-QT_BEGIN_INCLUDE_NAMESPACE
-#include <QtGui/qdecorationdefault_qws.h>
-QT_END_INCLUDE_NAMESPACE
-
-#endif // QT_NO_QWS_MANAGER
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QWSMANAGER_QWS_H
diff --git a/src/gui/embedded/qwsproperty_qws.cpp b/src/gui/embedded/qwsproperty_qws.cpp
deleted file mode 100644
index 9cd869d3f9..0000000000
--- a/src/gui/embedded/qwsproperty_qws.cpp
+++ /dev/null
@@ -1,145 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qwsproperty_qws.h"
-
-#ifndef QT_NO_QWS_PROPERTIES
-#include "qwscommand_qws_p.h"
-#include "qwindowsystem_qws.h"
-#include "qhash.h"
-#include "qalgorithms.h"
-#include "qbytearray.h"
-
-#include <stdio.h>
-
-QT_BEGIN_NAMESPACE
-
-class QWSPropertyManager::Data {
-public:
- QByteArray find(int winId, int property)
- {
- return properties.value(winId).value(property);
- }
-
- typedef QHash<int, QHash<int, QByteArray> > PropertyHash;
- PropertyHash properties;
-};
-
-/*********************************************************************
- *
- * Class: QWSPropertyManager
- *
- *********************************************************************/
-
-QWSPropertyManager::QWSPropertyManager()
-{
- d = new Data;
-}
-
-QWSPropertyManager::~QWSPropertyManager()
-{
- delete d;
-}
-
-bool QWSPropertyManager::setProperty(int winId, int property, int mode, const char *data, int len)
-{
- QHash<int, QByteArray> props = d->properties.value(winId);
- QHash<int, QByteArray>::iterator it = props.find(property);
- if (it == props.end())
- return false;
-
- switch (mode) {
- case PropReplace:
- d->properties[winId][property] = QByteArray(data, len);
- break;
- case PropAppend:
- d->properties[winId][property].append(data);
- break;
- case PropPrepend:
- d->properties[winId][property].prepend(data);
- break;
- }
- return true;
-}
-
-bool QWSPropertyManager::hasProperty(int winId, int property)
-{
- return d->properties.value(winId).contains(property);
-}
-
-bool QWSPropertyManager::removeProperty(int winId, int property)
-{
- QWSPropertyManager::Data::PropertyHash::iterator it = d->properties.find(winId);
- if (it == d->properties.end())
- return false;
- return d->properties[winId].remove( property );
-}
-
-bool QWSPropertyManager::addProperty(int winId, int property)
-{
- if( !d->properties[winId].contains(property) )
- d->properties[winId][property] = QByteArray(); // only add if it doesn't exist
- return true;
-}
-
-bool QWSPropertyManager::getProperty(int winId, int property, const char *&data, int &len)
-{
- QHash<int, QByteArray> props = d->properties.value(winId);
- QHash<int, QByteArray>::iterator it = props.find(property);
- if (it == props.end()) {
- data = 0;
- len = -1;
- return false;
- }
- data = it.value().constData();
- len = it.value().length();
-
- return true;
-}
-
-bool QWSPropertyManager::removeProperties(int winId)
-{
- return d->properties.remove(winId);
-}
-
-QT_END_NAMESPACE
-
-#endif //QT_NO_QWS_PROPERTIES
diff --git a/src/gui/embedded/qwsproperty_qws.h b/src/gui/embedded/qwsproperty_qws.h
deleted file mode 100644
index 88406078ff..0000000000
--- a/src/gui/embedded/qwsproperty_qws.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWSPROPERTY_QWS_H
-#define QWSPROPERTY_QWS_H
-
-#include <QtCore/qglobal.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-/*********************************************************************
- *
- * Class: QWSPropertyManager
- *
- *********************************************************************/
-
-#ifndef QT_NO_QWS_PROPERTIES
-
-class QWSPropertyManager
-{
-public:
- enum Mode {
- PropReplace = 0,
- PropPrepend,
- PropAppend
- };
-
- // pre-defined properties
- enum Atom {
- PropSelection = 0
- };
-
- QWSPropertyManager();
- ~QWSPropertyManager();
-
- bool setProperty(int winId, int property, int mode, const char *data, int len);
- bool hasProperty(int winId, int property);
- bool removeProperty(int winId, int property);
- bool addProperty(int winId, int property);
- bool getProperty(int winId, int property, const char *&data, int &len);
- bool removeProperties(int winId);
-
-private:
- class Data;
- Data* d;
-};
-
-#endif // QT_NO_QWS_PROPERTIES
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QWSPROPERTY_QWS_H
diff --git a/src/gui/embedded/qwsprotocolitem_qws.h b/src/gui/embedded/qwsprotocolitem_qws.h
deleted file mode 100644
index b20c32e3d8..0000000000
--- a/src/gui/embedded/qwsprotocolitem_qws.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWSPROTOCOLITEM_QWS_H
-#define QWSPROTOCOLITEM_QWS_H
-
-/*********************************************************************
- *
- * QWSCommand base class - only use derived classes from that
- *
- *********************************************************************/
-
-#include <QtCore/qglobal.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QIODevice;
-
-struct QWSProtocolItem
-{
- // ctor - dtor
- QWSProtocolItem(int t, int len, char *ptr) : type(t),
- simpleLen(len), rawLen(-1), deleteRaw(false), simpleDataPtr(ptr),
- rawDataPtr(0), bytesRead(0) { }
- virtual ~QWSProtocolItem();
-
- // data
- int type;
- int simpleLen;
- int rawLen;
- bool deleteRaw;
-
- // functions
-#ifndef QT_NO_QWS_MULTIPROCESS
- void write(QIODevice *s);
- bool read(QIODevice *s);
-#endif
- void copyFrom(const QWSProtocolItem *item);
-
- virtual void setData(const char *data, int len, bool allocateMem = true);
-
- char *simpleDataPtr;
- char *rawDataPtr;
- // temp variables
- int bytesRead;
-};
-
-// This should probably be a method on QWSProtocolItem, but this way avoids
-// changing the API of this apparently public header
-// size = (int)type + (int)rawLenSize + simpleLen + rawLen
-#define QWS_PROTOCOL_ITEM_SIZE( item ) \
- (2 * sizeof(int)) + ((item).simpleDataPtr ? (item).simpleLen : 0) + ((item).rawDataPtr ? (item).rawLen : 0)
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QWSPROTOCOLITEM_QWS_H
diff --git a/src/gui/embedded/qwssharedmemory.cpp b/src/gui/embedded/qwssharedmemory.cpp
deleted file mode 100644
index 66bedee111..0000000000
--- a/src/gui/embedded/qwssharedmemory.cpp
+++ /dev/null
@@ -1,185 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qwssharedmemory_p.h"
-
-#if !defined(QT_NO_QWS_MULTIPROCESS)
-
-#include <sys/shm.h>
-
-QT_BEGIN_NAMESPACE
-
-QWSSharedMemory::QWSSharedMemory()
- : shmBase(0), shmSize(0), character(0), shmId(-1), key(-1)
-{
-}
-
-
-QWSSharedMemory::~QWSSharedMemory()
-{
- detach();
-}
-
-/*
- man page says:
- On Linux, it is possible to attach a shared memory segment even if it
- is already marked to be deleted. However, POSIX.1-2001 does not spec-
- ify this behaviour and many other implementations do not support it.
-*/
-
-bool QWSSharedMemory::create(int size)
-{
- if (shmId != -1)
- detach();
- shmId = shmget(IPC_PRIVATE, size, IPC_CREAT|0600);
-
- if (shmId == -1) {
-#ifdef QT_SHM_DEBUG
- perror("QWSSharedMemory::create allocating shared memory");
- qWarning("Error allocating shared memory of size %d", size);
-#endif
- return false;
- }
- shmBase = shmat(shmId,0,0);
- shmctl(shmId, IPC_RMID, 0);
- if (shmBase == (void*)-1) {
-#ifdef QT_SHM_DEBUG
- perror("QWSSharedMemory::create attaching to shared memory");
- qWarning("Error attaching to shared memory id %d", shmId);
-#endif
- shmBase = 0;
- return false;
- }
- return true;
-}
-
-bool QWSSharedMemory::attach(int id)
-{
- if (shmId == id)
- return id != -1;
- if (shmId != -1)
- detach();
-
- shmBase = shmat(id,0,0);
- if (shmBase == (void*)-1) {
-#ifdef QT_SHM_DEBUG
- perror("QWSSharedMemory::attach attaching to shared memory");
- qWarning("Error attaching to shared memory 0x%x of size %d",
- id, size());
-#endif
- shmBase = 0;
- return false;
- }
- shmId = id;
- return true;
-}
-
-
-void QWSSharedMemory::detach ()
-{
- if (!shmBase)
- return;
- shmdt (shmBase);
- shmBase = 0;
- shmSize = 0;
- shmId = -1;
-}
-
-void QWSSharedMemory::setPermissions (mode_t mode)
-{
- struct shmid_ds shm;
- shmctl (shmId, IPC_STAT, &shm);
- shm.shm_perm.mode = mode;
- shmctl (shmId, IPC_SET, &shm);
-}
-
-int QWSSharedMemory::size () const
-{
- struct shmid_ds shm;
- shmctl (shmId, IPC_STAT, &shm);
- return shm.shm_segsz;
-}
-
-
-// old API
-
-
-
-QWSSharedMemory::QWSSharedMemory (int size, const QString &filename, char c)
-{
- shmSize = size;
- shmFile = filename;
- shmBase = 0;
- shmId = -1;
- character = c;
- key = ftok (shmFile.toLatin1().constData(), c);
-}
-
-
-
-bool QWSSharedMemory::create ()
-{
- shmId = shmget (key, shmSize, IPC_CREAT | 0666);
- return (shmId != -1);
-}
-
-void QWSSharedMemory::destroy ()
-{
- if (shmId != -1)
- shmctl(shmId, IPC_RMID, 0);
-}
-
-bool QWSSharedMemory::attach ()
-{
- if (shmId == -1)
- shmId = shmget (key, shmSize, 0);
-
- shmBase = shmat (shmId, 0, 0);
- if ((long)shmBase == -1)
- shmBase = 0;
-
- return (long)shmBase != 0;
-}
-
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_QWS_MULTIPROCESS
diff --git a/src/gui/embedded/qwssharedmemory_p.h b/src/gui/embedded/qwssharedmemory_p.h
deleted file mode 100644
index 31e69c4a83..0000000000
--- a/src/gui/embedded/qwssharedmemory_p.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWSSHAREDMEMORY_P_H
-#define QWSSHAREDMEMORY_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qplatformdefs.h"
-#include "QtCore/qstring.h"
-
-QT_BEGIN_NAMESPACE
-
-#if !defined(QT_NO_QWS_MULTIPROCESS)
-
-class QWSSharedMemory {
-public:
-
- QWSSharedMemory();
- ~QWSSharedMemory();
-
- void setPermissions(mode_t mode);
- int size() const;
- void *address() { return shmBase; }
-
- int id() const { return shmId; }
-
- void detach();
-
- bool create(int size);
- bool attach(int id);
-
- //bool create(int size, const QString &filename, char c = 'Q');
- //bool attach(const QString &filename, char c = 'Q');
-// old API
-
- QWSSharedMemory(int, const QString &, char c = 'Q');
- void * base() { return address(); }
-
- bool create();
- void destroy();
-
- bool attach();
-
-private:
- void *shmBase;
- int shmSize;
- QString shmFile;
- char character;
- int shmId;
- key_t key;
-};
-
-#endif // QT_NO_QWS_MULTIPROCESS
-
-QT_END_NAMESPACE
-
-#endif // QWSSHAREDMEMORY_P_H
diff --git a/src/gui/embedded/qwssignalhandler.cpp b/src/gui/embedded/qwssignalhandler.cpp
deleted file mode 100644
index 730dbae138..0000000000
--- a/src/gui/embedded/qwssignalhandler.cpp
+++ /dev/null
@@ -1,128 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qwssignalhandler_p.h"
-
-#ifndef QT_NO_QWS_SIGNALHANDLER
-
-#include <sys/types.h>
-#ifndef QT_NO_QWS_MULTIPROCESS
-# include <sys/ipc.h>
-# include <sys/sem.h>
-
-# include <private/qcore_unix_p.h>
-#endif
-#include <signal.h>
-
-QT_BEGIN_NAMESPACE
-
-class QWSSignalHandlerPrivate : public QWSSignalHandler
-{
-public:
- QWSSignalHandlerPrivate() : QWSSignalHandler() {}
-};
-
-
-Q_GLOBAL_STATIC(QWSSignalHandlerPrivate, signalHandlerInstance);
-
-
-QWSSignalHandler* QWSSignalHandler::instance()
-{
- return signalHandlerInstance();
-}
-
-QWSSignalHandler::QWSSignalHandler()
-{
- const int signums[] = { SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, SIGFPE,
- SIGSEGV, SIGTERM, SIGBUS };
- const int n = sizeof(signums)/sizeof(int);
-
- for (int i = 0; i < n; ++i) {
- const int signum = signums[i];
- qt_sighandler_t old = signal(signum, handleSignal);
- if (old == SIG_IGN) // don't remove shm and semaphores when ignored
- signal(signum, old);
- else
- oldHandlers[signum] = (old == SIG_ERR ? SIG_DFL : old);
- }
-}
-
-QWSSignalHandler::~QWSSignalHandler()
-{
-#ifndef QT_NO_QWS_MULTIPROCESS
- while (!semaphores.isEmpty())
- removeSemaphore(semaphores.last());
-#endif
-}
-
-#ifndef QT_NO_QWS_MULTIPROCESS
-void QWSSignalHandler::removeSemaphore(int semno)
-{
- const int index = semaphores.lastIndexOf(semno);
- if (index != -1) {
- qt_semun semval;
- semval.val = 0;
- semctl(semaphores.at(index), 0, IPC_RMID, semval);
- semaphores.remove(index);
- }
-}
-#endif // QT_NO_QWS_MULTIPROCESS
-
-void QWSSignalHandler::handleSignal(int signum)
-{
- QWSSignalHandler *h = instance();
-
- signal(signum, h->oldHandlers[signum]);
-
-#ifndef QT_NO_QWS_MULTIPROCESS
- qt_semun semval;
- semval.val = 0;
- for (int i = 0; i < h->semaphores.size(); ++i)
- semctl(h->semaphores.at(i), 0, IPC_RMID, semval);
-#endif
-
- h->objects.clear();
- raise(signum);
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_QWS_NO_SIGNALHANDLER
diff --git a/src/gui/embedded/qwssignalhandler_p.h b/src/gui/embedded/qwssignalhandler_p.h
deleted file mode 100644
index dda9c76287..0000000000
--- a/src/gui/embedded/qwssignalhandler_p.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWSSIGNALHANDLER_P_H
-#define QWSSIGNALHANDLER_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of the QLibrary class. This header file may change from
-// version to version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/qglobal.h>
-
-#ifndef QT_NO_QWS_SIGNALHANDLER
-
-#include <QtCore/qmap.h>
-#include <QtCore/qvector.h>
-#include <QtCore/qobjectcleanuphandler.h>
-
-QT_BEGIN_NAMESPACE
-
-typedef void (*qt_sighandler_t)(int);
-
-class QWSSignalHandlerPrivate;
-
-class Q_GUI_EXPORT QWSSignalHandler
-{
-public:
- static QWSSignalHandler* instance();
-
- ~QWSSignalHandler();
-
-#ifndef QT_NO_QWS_MULTIPROCESS
- inline void addSemaphore(int semno) { semaphores.append(semno); }
- void removeSemaphore(int semno);
-#endif
- inline void addObject(QObject *object) { (void)objects.add(object); }
-
-private:
- QWSSignalHandler();
- static void handleSignal(int signal);
- QMap<int, qt_sighandler_t> oldHandlers;
-#ifndef QT_NO_QWS_MULTIPROCESS
- QVector<int> semaphores;
-#endif
- QObjectCleanupHandler objects;
-
- friend class QWSSignalHandlerPrivate;
-};
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_QWS_SIGNALHANDLER
-
-#endif // QWSSIGNALHANDLER_P_H
diff --git a/src/gui/embedded/qwssocket_qws.cpp b/src/gui/embedded/qwssocket_qws.cpp
deleted file mode 100644
index cec1588ebd..0000000000
--- a/src/gui/embedded/qwssocket_qws.cpp
+++ /dev/null
@@ -1,280 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qplatformdefs.h"
-#include "qwssocket_qws.h"
-
-#ifndef QT_NO_QWS_MULTIPROCESS
-
-#include <fcntl.h>
-#include <netdb.h>
-#include <errno.h>
-#include <stdio.h>
-#include <sys/file.h>
-#include <sys/time.h>
-#include <sys/un.h>
-
-#ifdef __MIPSEL__
-# ifndef SOCK_DGRAM
-# define SOCK_DGRAM 1
-# endif
-# ifndef SOCK_STREAM
-# define SOCK_STREAM 2
-# endif
-#endif
-
-#if defined(Q_OS_SOLARIS) || defined (QT_LINUXBASE)
-// uff-da apparently Solaris doesn't have the SUN_LEN macro, here is
-// an implementation of it...
-# ifndef SUN_LEN
-# define SUN_LEN(su) \
- sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path)
-# endif
-
-// nor the POSIX names of UNIX domain sockets *sigh*
-# ifndef AF_LOCAL
-# define AF_LOCAL AF_UNIX
-# endif
-# ifndef PF_LOCAL
-# define PF_LOCAL PF_UNIX
-# endif
-#endif // Q_OS_SOLARIS || QT_LINUXBASE
-
-QT_BEGIN_NAMESPACE
-
-/***********************************************************************
- *
- * QWSSocket
- *
- **********************************************************************/
-QWSSocket::QWSSocket(QObject *parent)
- : QWS_SOCK_BASE(parent)
-{
-#ifndef QT_NO_SXE
- QObject::connect( this, SIGNAL(stateChanged(SocketState)),
- this, SLOT(forwardStateChange(SocketState)));
-#endif
-}
-
-QWSSocket::~QWSSocket()
-{
-}
-
-#ifndef QT_NO_SXE
-QString QWSSocket::errorString()
-{
- switch (QUnixSocket::error()) {
- case NoError:
- return QString();
- case InvalidPath:
- case NonexistentPath:
- return QLatin1String("Bad path"); // NO_TR
- default:
- return QLatin1String("Bad socket"); // NO TR
- }
-}
-
-void QWSSocket::forwardStateChange(QUnixSocket::SocketState st )
-{
- switch ( st )
- {
- case ConnectedState:
- emit connected();
- break;
- case ClosingState:
- break;
- case UnconnectedState:
- emit disconnected();
- break;
- default:
- // nothing
- break;
- }
- if ( QUnixSocket::error() != NoError )
- emit error((QAbstractSocket::SocketError)0);
-}
-#endif
-
-bool QWSSocket::connectToLocalFile(const QString &file)
-{
-#ifndef QT_NO_SXE
- bool result = QUnixSocket::connect( file.toLocal8Bit() );
- if ( !result )
- {
- perror( "QWSSocketAuth::connectToLocalFile could not connect:" );
- emit error(QAbstractSocket::ConnectionRefusedError);
- return false;
- }
- return true;
-#else
- // create socket
- int s = ::socket(PF_LOCAL, SOCK_STREAM, 0);
-
- // connect to socket
- struct sockaddr_un a;
- memset(&a, 0, sizeof(a));
- a.sun_family = PF_LOCAL;
- strncpy(a.sun_path, file.toLocal8Bit().constData(), sizeof(a.sun_path) - 1);
- int r = ::connect(s, (struct sockaddr*)&a, SUN_LEN(&a));
- if (r == 0) {
- setSocketDescriptor(s);
- } else {
- perror("QWSSocket::connectToLocalFile could not connect:");
- ::close(s);
- emit error(ConnectionRefusedError);
- return false;
- }
-#endif
- return true;
-}
-
-
-/***********************************************************************
- *
- * QWSServerSocket
- *
- **********************************************************************/
-QWSServerSocket::QWSServerSocket(const QString& file, QObject *parent)
-#ifndef QT_NO_SXE
- : QUnixSocketServer(parent)
-#else
- : QTcpServer(parent)
-#endif
-{
- init(file);
-}
-
-void QWSServerSocket::init(const QString &file)
-{
-#ifndef QT_NO_SXE
- QByteArray fn = file.toLocal8Bit();
- bool result = QUnixSocketServer::listen( fn );
- if ( !result )
- {
- QUnixSocketServer::ServerError err = serverError();
- switch ( err )
- {
- case InvalidPath:
- qWarning("QWSServerSocket:: invalid path %s", qPrintable(file));
- break;
- case ResourceError:
- case BindError:
- case ListenError:
- qWarning("QWSServerSocket:: could not listen on path %s", qPrintable(file));
- break;
- default:
- break;
- }
- }
-#else
- int backlog = 16; //#####
-
-// create socket
- int s = ::socket(PF_LOCAL, SOCK_STREAM, 0);
- if (s == -1) {
- perror("QWSServerSocket::init");
- qWarning("QWSServerSocket: unable to create socket.");
- return;
- }
-
- QByteArray fn = file.toLocal8Bit();
- unlink(fn.constData()); // doesn't have to succeed
-
- // bind socket
- struct sockaddr_un a;
- memset(&a, 0, sizeof(a));
- a.sun_family = PF_LOCAL;
- strncpy(a.sun_path, fn.constData(), sizeof(a.sun_path) - 1);
- int r = ::bind(s, (struct sockaddr*)&a, SUN_LEN(&a));
- if (r < 0) {
- perror("QWSServerSocket::init");
- qWarning("QWSServerSocket: could not bind to file %s", fn.constData());
- ::close(s);
- return;
- }
-
- if (chmod(fn.constData(), 0600) < 0) {
- perror("QWSServerSocket::init");
- qWarning("Could not set permissions of %s", fn.constData());
- ::close(s);
- return;
- }
-
- // listen
- if (::listen(s, backlog) == 0) {
- if (!setSocketDescriptor(s))
- qWarning( "QWSServerSocket could not set descriptor %d : %s", s, errorString().toLatin1().constData());
- } else {
- perror("QWSServerSocket::init");
- qWarning("QWSServerSocket: could not listen to file %s", fn.constData());
- ::close(s);
- }
-#endif
-}
-
-QWSServerSocket::~QWSServerSocket()
-{
-}
-
-#ifndef QT_NO_SXE
-
-void QWSServerSocket::incomingConnection(int socketDescriptor)
-{
- inboundConnections.append( socketDescriptor );
- emit newConnection();
-}
-
-
-QWSSocket *QWSServerSocket::nextPendingConnection()
-{
- QMutexLocker locker( &ssmx );
- if ( inboundConnections.count() == 0 )
- return 0;
- QWSSocket *s = new QWSSocket();
- s->setSocketDescriptor( inboundConnections.takeFirst() );
- return s;
-}
-
-#endif // QT_NO_SXE
-
-QT_END_NAMESPACE
-
-#endif //QT_NO_QWS_MULTIPROCESS
diff --git a/src/gui/embedded/qwssocket_qws.h b/src/gui/embedded/qwssocket_qws.h
deleted file mode 100644
index 77a59412a1..0000000000
--- a/src/gui/embedded/qwssocket_qws.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWSSOCKET_QWS_H
-#define QWSSOCKET_QWS_H
-
-#include <QtCore/qconfig.h>
-#include <QtGui/qwsutils_qws.h>
-
-#ifndef QT_NO_QWS_MULTIPROCESS
-
-#ifndef QT_NO_SXE
-#include <QtCore/qmutex.h>
-#include <QtGui/private/qunixsocketserver_p.h>
-#include <QtGui/private/qunixsocket_p.h>
-#else
-#include <QtNetwork/qtcpsocket.h>
-#include <QtNetwork/qtcpserver.h>
-#endif
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-
-class QWSSocket : public QWS_SOCK_BASE
-{
- Q_OBJECT
-public:
- explicit QWSSocket(QObject *parent=0);
- ~QWSSocket();
-
- bool connectToLocalFile(const QString &file);
-
-#ifndef QT_NO_SXE
- QString errorString();
-Q_SIGNALS:
- void connected();
- void disconnected();
- void error(QAbstractSocket::SocketError);
-private Q_SLOTS:
- void forwardStateChange(SocketState);
-#endif
-
-private:
- Q_DISABLE_COPY(QWSSocket)
-};
-
-
-class QWSServerSocket : public QWS_SOCK_SERVER_BASE
-{
- Q_OBJECT
-public:
- QWSServerSocket(const QString& file, QObject *parent=0);
- ~QWSServerSocket();
-
-#ifndef QT_NO_SXE
- QWSSocket *nextPendingConnection();
-Q_SIGNALS:
- void newConnection();
-protected:
- void incomingConnection(int socketDescriptor);
-private:
- QMutex ssmx;
- QList<int> inboundConnections;
-#endif
-
-private:
- Q_DISABLE_COPY(QWSServerSocket)
-
- void init(const QString &file);
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QT_NO_QWS_MULTIPROCESS
-
-#endif // QWSSOCKET_QWS_H
diff --git a/src/gui/embedded/qwsutils_qws.h b/src/gui/embedded/qwsutils_qws.h
deleted file mode 100644
index 013b2e5304..0000000000
--- a/src/gui/embedded/qwsutils_qws.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWSUTILS_QWS_H
-#define QWSUTILS_QWS_H
-
-#include <QtCore/QIODevice>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_SXE
-#define QWS_SOCK_BASE QUnixSocket
-#define QWS_SOCK_SERVER_BASE QUnixSocketServer
-class QUnixSocket;
-class QUnixSocketServer;
-#else
-#define QWS_SOCK_BASE QTcpSocket
-#define QWS_SOCK_SERVER_BASE QTcpServer
-class QTcpSocket;
-class QTcpServer;
-#endif
-class QWSSocket;
-class QWSServerSocket;
-
-/********************************************************************
- *
- * Convenient socket functions
- *
- ********************************************************************/
-#ifndef QT_NO_QWS_MULTIPROCESS
-inline int qws_read_uint(QIODevice *socket)
-{
- if (!socket || socket->bytesAvailable() < (int)sizeof(int))
- return -1;
-
- int i;
- socket->read(reinterpret_cast<char*>(&i), sizeof(i));
-
- return i;
-}
-
-inline void qws_write_uint(QIODevice *socket, int i)
-{
- if (!socket)
- return;
-
- socket->write(reinterpret_cast<char*>(&i), sizeof(i));
-}
-
-#endif // QT_NO_QWS_MULTIPROCESS
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QWSUTILS_QWS_H
diff --git a/src/gui/graphicsview/qgraphicsanchorlayout.h b/src/gui/graphicsview/qgraphicsanchorlayout.h
deleted file mode 100644
index c387893467..0000000000
--- a/src/gui/graphicsview/qgraphicsanchorlayout.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGRAPHICSANCHORLAYOUT_H
-#define QGRAPHICSANCHORLAYOUT_H
-
-#include <QtGui/qgraphicsitem.h>
-#include <QtGui/qgraphicslayout.h>
-
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW
-
-class QGraphicsAnchorPrivate;
-class QGraphicsAnchorLayout;
-class QGraphicsAnchorLayoutPrivate;
-
-class Q_GUI_EXPORT QGraphicsAnchor : public QObject
-{
- Q_OBJECT
- Q_PROPERTY(qreal spacing READ spacing WRITE setSpacing RESET unsetSpacing)
- Q_PROPERTY(QSizePolicy::Policy sizePolicy READ sizePolicy WRITE setSizePolicy)
-public:
- void setSpacing(qreal spacing);
- void unsetSpacing();
- qreal spacing() const;
- void setSizePolicy(QSizePolicy::Policy policy);
- QSizePolicy::Policy sizePolicy() const;
- ~QGraphicsAnchor();
-private:
- QGraphicsAnchor(QGraphicsAnchorLayout *parent);
-
- Q_DECLARE_PRIVATE(QGraphicsAnchor)
-
- friend class QGraphicsAnchorLayoutPrivate;
- friend struct AnchorData;
-};
-
-class Q_GUI_EXPORT QGraphicsAnchorLayout : public QGraphicsLayout
-{
-public:
- QGraphicsAnchorLayout(QGraphicsLayoutItem *parent = 0);
- virtual ~QGraphicsAnchorLayout();
-
- QGraphicsAnchor *addAnchor(QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge,
- QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge);
- QGraphicsAnchor *anchor(QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge,
- QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge);
-
- void addCornerAnchors(QGraphicsLayoutItem *firstItem, Qt::Corner firstCorner,
- QGraphicsLayoutItem *secondItem, Qt::Corner secondCorner);
-
- void addAnchors(QGraphicsLayoutItem *firstItem,
- QGraphicsLayoutItem *secondItem,
- Qt::Orientations orientations = Qt::Horizontal | Qt::Vertical);
-
- void setHorizontalSpacing(qreal spacing);
- void setVerticalSpacing(qreal spacing);
- void setSpacing(qreal spacing);
- qreal horizontalSpacing() const;
- qreal verticalSpacing() const;
-
- void removeAt(int index);
- void setGeometry(const QRectF &rect);
- int count() const;
- QGraphicsLayoutItem *itemAt(int index) const;
-
- void invalidate();
-protected:
- QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const;
-
-private:
- Q_DISABLE_COPY(QGraphicsAnchorLayout)
- Q_DECLARE_PRIVATE(QGraphicsAnchorLayout)
-
- friend class QGraphicsAnchor;
-};
-
-#endif
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif
diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp
deleted file mode 100644
index eaa8ac2b50..0000000000
--- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp
+++ /dev/null
@@ -1,3015 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtGui/qwidget.h>
-#include <QtGui/qapplication.h>
-#include <QtCore/qlinkedlist.h>
-#include <QtCore/qstack.h>
-
-#ifdef QT_DEBUG
-#include <QtCore/qfile.h>
-#endif
-
-#include "qgraphicsanchorlayout_p.h"
-
-#ifndef QT_NO_GRAPHICSVIEW
-QT_BEGIN_NAMESPACE
-
-// To ensure that all variables inside the simplex solver are non-negative,
-// we limit the size of anchors in the interval [-limit, limit]. Then before
-// sending them to the simplex solver we add "limit" as an offset, so that
-// they are actually calculated in the interval [0, 2 * limit]
-// To avoid numerical errors in platforms where we use single precision,
-// we use a tighter limit for the variables range.
-const qreal g_offset = (sizeof(qreal) == sizeof(double)) ? QWIDGETSIZE_MAX : QWIDGETSIZE_MAX / 32;
-
-QGraphicsAnchorPrivate::QGraphicsAnchorPrivate(int version)
- : QObjectPrivate(version), layoutPrivate(0), data(0),
- sizePolicy(QSizePolicy::Fixed), preferredSize(0),
- hasSize(true)
-{
-}
-
-QGraphicsAnchorPrivate::~QGraphicsAnchorPrivate()
-{
- if (data) {
- // The QGraphicsAnchor was already deleted at this moment. We must clean
- // the dangling pointer to avoid double deletion in the AnchorData dtor.
- data->graphicsAnchor = 0;
-
- layoutPrivate->removeAnchor(data->from, data->to);
- }
-}
-
-void QGraphicsAnchorPrivate::setSizePolicy(QSizePolicy::Policy policy)
-{
- if (sizePolicy != policy) {
- sizePolicy = policy;
- layoutPrivate->q_func()->invalidate();
- }
-}
-
-void QGraphicsAnchorPrivate::setSpacing(qreal value)
-{
- if (!data) {
- qWarning("QGraphicsAnchor::setSpacing: The anchor does not exist.");
- return;
- }
-
- if (hasSize && (preferredSize == value))
- return;
-
- // The anchor has an user-defined size
- hasSize = true;
- preferredSize = value;
-
- layoutPrivate->q_func()->invalidate();
-}
-
-void QGraphicsAnchorPrivate::unsetSpacing()
-{
- if (!data) {
- qWarning("QGraphicsAnchor::setSpacing: The anchor does not exist.");
- return;
- }
-
- // Return to standard direction
- hasSize = false;
-
- layoutPrivate->q_func()->invalidate();
-}
-
-qreal QGraphicsAnchorPrivate::spacing() const
-{
- if (!data) {
- qWarning("QGraphicsAnchor::setSpacing: The anchor does not exist.");
- return 0;
- }
-
- return preferredSize;
-}
-
-
-static void applySizePolicy(QSizePolicy::Policy policy,
- qreal minSizeHint, qreal prefSizeHint, qreal maxSizeHint,
- qreal *minSize, qreal *prefSize,
- qreal *maxSize)
-{
- // minSize, prefSize and maxSize are initialized
- // with item's preferred Size: this is QSizePolicy::Fixed.
- //
- // Then we check each flag to find the resultant QSizePolicy,
- // according to the following table:
- //
- // constant value
- // QSizePolicy::Fixed 0
- // QSizePolicy::Minimum GrowFlag
- // QSizePolicy::Maximum ShrinkFlag
- // QSizePolicy::Preferred GrowFlag | ShrinkFlag
- // QSizePolicy::Ignored GrowFlag | ShrinkFlag | IgnoreFlag
-
- if (policy & QSizePolicy::ShrinkFlag)
- *minSize = minSizeHint;
- else
- *minSize = prefSizeHint;
-
- if (policy & QSizePolicy::GrowFlag)
- *maxSize = maxSizeHint;
- else
- *maxSize = prefSizeHint;
-
- // Note that these two initializations are affected by the previous flags
- if (policy & QSizePolicy::IgnoreFlag)
- *prefSize = *minSize;
- else
- *prefSize = prefSizeHint;
-}
-
-AnchorData::~AnchorData()
-{
- if (graphicsAnchor) {
- // Remove reference to ourself to avoid double removal in
- // QGraphicsAnchorPrivate dtor.
- graphicsAnchor->d_func()->data = 0;
-
- delete graphicsAnchor;
- }
-}
-
-
-void AnchorData::refreshSizeHints(const QLayoutStyleInfo *styleInfo)
-{
- QSizePolicy::Policy policy;
- qreal minSizeHint;
- qreal prefSizeHint;
- qreal maxSizeHint;
-
- if (item) {
- // It is an internal anchor, fetch size information from the item
- if (isLayoutAnchor) {
- minSize = 0;
- prefSize = 0;
- maxSize = QWIDGETSIZE_MAX;
- if (isCenterAnchor)
- maxSize /= 2;
-
- minPrefSize = prefSize;
- maxPrefSize = maxSize;
- return;
- } else {
- if (orientation == QGraphicsAnchorLayoutPrivate::Horizontal) {
- policy = item->sizePolicy().horizontalPolicy();
- minSizeHint = item->effectiveSizeHint(Qt::MinimumSize).width();
- prefSizeHint = item->effectiveSizeHint(Qt::PreferredSize).width();
- maxSizeHint = item->effectiveSizeHint(Qt::MaximumSize).width();
- } else {
- policy = item->sizePolicy().verticalPolicy();
- minSizeHint = item->effectiveSizeHint(Qt::MinimumSize).height();
- prefSizeHint = item->effectiveSizeHint(Qt::PreferredSize).height();
- maxSizeHint = item->effectiveSizeHint(Qt::MaximumSize).height();
- }
-
- if (isCenterAnchor) {
- minSizeHint /= 2;
- prefSizeHint /= 2;
- maxSizeHint /= 2;
- }
- }
- } else {
- // It is a user-created anchor, fetch size information from the associated QGraphicsAnchor
- Q_ASSERT(graphicsAnchor);
- QGraphicsAnchorPrivate *anchorPrivate = graphicsAnchor->d_func();
-
- // Policy, min and max sizes are straightforward
- policy = anchorPrivate->sizePolicy;
- minSizeHint = 0;
- maxSizeHint = QWIDGETSIZE_MAX;
-
- // Preferred Size
- if (anchorPrivate->hasSize) {
- // Anchor has user-defined size
- prefSizeHint = anchorPrivate->preferredSize;
- } else {
- // Fetch size information from style
- const Qt::Orientation orient = Qt::Orientation(QGraphicsAnchorLayoutPrivate::edgeOrientation(from->m_edge) + 1);
- qreal s = styleInfo->defaultSpacing(orient);
- if (s < 0) {
- QSizePolicy::ControlType controlTypeFrom = from->m_item->sizePolicy().controlType();
- QSizePolicy::ControlType controlTypeTo = to->m_item->sizePolicy().controlType();
- s = styleInfo->perItemSpacing(controlTypeFrom, controlTypeTo, orient);
-
- // ### Currently we do not support negative anchors inside the graph.
- // To avoid those being created by a negative style spacing, we must
- // make this test.
- if (s < 0)
- s = 0;
- }
- prefSizeHint = s;
- }
- }
-
- // Fill minSize, prefSize and maxSize based on policy and sizeHints
- applySizePolicy(policy, minSizeHint, prefSizeHint, maxSizeHint,
- &minSize, &prefSize, &maxSize);
-
- minPrefSize = prefSize;
- maxPrefSize = maxSize;
-
- // Set the anchor effective sizes to preferred.
- //
- // Note: The idea here is that all items should remain at their
- // preferred size unless where that's impossible. In cases where
- // the item is subject to restrictions (anchored to the layout
- // edges, for instance), the simplex solver will be run to
- // recalculate and override the values we set here.
- sizeAtMinimum = prefSize;
- sizeAtPreferred = prefSize;
- sizeAtMaximum = prefSize;
-}
-
-void ParallelAnchorData::updateChildrenSizes()
-{
- firstEdge->sizeAtMinimum = sizeAtMinimum;
- firstEdge->sizeAtPreferred = sizeAtPreferred;
- firstEdge->sizeAtMaximum = sizeAtMaximum;
-
- if (secondForward()) {
- secondEdge->sizeAtMinimum = sizeAtMinimum;
- secondEdge->sizeAtPreferred = sizeAtPreferred;
- secondEdge->sizeAtMaximum = sizeAtMaximum;
- } else {
- secondEdge->sizeAtMinimum = -sizeAtMinimum;
- secondEdge->sizeAtPreferred = -sizeAtPreferred;
- secondEdge->sizeAtMaximum = -sizeAtMaximum;
- }
-
- firstEdge->updateChildrenSizes();
- secondEdge->updateChildrenSizes();
-}
-
-/*
- \internal
-
- Initialize the parallel anchor size hints using the sizeHint information from
- its children.
-
- Note that parallel groups can lead to unfeasibility, so during calculation, we can
- find out one unfeasibility. Because of that this method return boolean. This can't
- happen in sequential, so there the method is void.
- */
-bool ParallelAnchorData::calculateSizeHints()
-{
- // Normalize second child sizes.
- // A negative anchor of sizes min, minPref, pref, maxPref and max, is equivalent
- // to a forward anchor of sizes -max, -maxPref, -pref, -minPref, -min
- qreal secondMin;
- qreal secondMinPref;
- qreal secondPref;
- qreal secondMaxPref;
- qreal secondMax;
-
- if (secondForward()) {
- secondMin = secondEdge->minSize;
- secondMinPref = secondEdge->minPrefSize;
- secondPref = secondEdge->prefSize;
- secondMaxPref = secondEdge->maxPrefSize;
- secondMax = secondEdge->maxSize;
- } else {
- secondMin = -secondEdge->maxSize;
- secondMinPref = -secondEdge->maxPrefSize;
- secondPref = -secondEdge->prefSize;
- secondMaxPref = -secondEdge->minPrefSize;
- secondMax = -secondEdge->minSize;
- }
-
- minSize = qMax(firstEdge->minSize, secondMin);
- maxSize = qMin(firstEdge->maxSize, secondMax);
-
- // This condition means that the maximum size of one anchor being simplified is smaller than
- // the minimum size of the other anchor. The consequence is that there won't be a valid size
- // for this parallel setup.
- if (minSize > maxSize) {
- return false;
- }
-
- // Preferred size calculation
- // The calculation of preferred size is done as follows:
- //
- // 1) Check whether one of the child anchors is the layout structural anchor
- // If so, we can simply copy the preferred information from the other child,
- // after bounding it to our minimum and maximum sizes.
- // If not, then we proceed with the actual calculations.
- //
- // 2) The whole algorithm for preferred size calculation is based on the fact
- // that, if a given anchor cannot remain at its preferred size, it'd rather
- // grow than shrink.
- //
- // What happens though is that while this affirmative is true for simple
- // anchors, it may not be true for sequential anchors that have one or more
- // reversed anchors inside it. That happens because when a sequential anchor
- // grows, any reversed anchors inside it may be required to shrink, something
- // we try to avoid, as said above.
- //
- // To overcome this, besides their actual preferred size "prefSize", each anchor
- // exports what we call "minPrefSize" and "maxPrefSize". These two values define
- // a surrounding interval where, if required to move, the anchor would rather
- // remain inside.
- //
- // For standard anchors, this area simply represents the region between
- // prefSize and maxSize, which makes sense since our first affirmation.
- // For composed anchors, these values are calculated as to reduce the global
- // "damage", that is, to reduce the total deviation and the total amount of
- // anchors that had to shrink.
-
- if (firstEdge->isLayoutAnchor) {
- prefSize = qBound(minSize, secondPref, maxSize);
- minPrefSize = qBound(minSize, secondMinPref, maxSize);
- maxPrefSize = qBound(minSize, secondMaxPref, maxSize);
- } else if (secondEdge->isLayoutAnchor) {
- prefSize = qBound(minSize, firstEdge->prefSize, maxSize);
- minPrefSize = qBound(minSize, firstEdge->minPrefSize, maxSize);
- maxPrefSize = qBound(minSize, firstEdge->maxPrefSize, maxSize);
- } else {
- // Calculate the intersection between the "preferred" regions of each child
- const qreal lowerBoundary =
- qBound(minSize, qMax(firstEdge->minPrefSize, secondMinPref), maxSize);
- const qreal upperBoundary =
- qBound(minSize, qMin(firstEdge->maxPrefSize, secondMaxPref), maxSize);
- const qreal prefMean =
- qBound(minSize, (firstEdge->prefSize + secondPref) / 2, maxSize);
-
- if (lowerBoundary < upperBoundary) {
- // If there is an intersection between the two regions, this intersection
- // will be used as the preferred region of the parallel anchor itself.
- // The preferred size will be the bounded average between the two preferred
- // sizes.
- prefSize = qBound(lowerBoundary, prefMean, upperBoundary);
- minPrefSize = lowerBoundary;
- maxPrefSize = upperBoundary;
- } else {
- // If there is no intersection, we have to attribute "damage" to at least
- // one of the children. The minimum total damage is achieved in points
- // inside the region that extends from (1) the upper boundary of the lower
- // region to (2) the lower boundary of the upper region.
- // Then, we expose this region as _our_ preferred region and once again,
- // use the bounded average as our preferred size.
- prefSize = qBound(upperBoundary, prefMean, lowerBoundary);
- minPrefSize = upperBoundary;
- maxPrefSize = lowerBoundary;
- }
- }
-
- // See comment in AnchorData::refreshSizeHints() about sizeAt* values
- sizeAtMinimum = prefSize;
- sizeAtPreferred = prefSize;
- sizeAtMaximum = prefSize;
-
- return true;
-}
-
-/*!
- \internal
- returns the factor in the interval [-1, 1].
- -1 is at Minimum
- 0 is at Preferred
- 1 is at Maximum
-*/
-static QPair<QGraphicsAnchorLayoutPrivate::Interval, qreal> getFactor(qreal value, qreal min,
- qreal minPref, qreal pref,
- qreal maxPref, qreal max)
-{
- QGraphicsAnchorLayoutPrivate::Interval interval;
- qreal lower;
- qreal upper;
-
- if (value < minPref) {
- interval = QGraphicsAnchorLayoutPrivate::MinimumToMinPreferred;
- lower = min;
- upper = minPref;
- } else if (value < pref) {
- interval = QGraphicsAnchorLayoutPrivate::MinPreferredToPreferred;
- lower = minPref;
- upper = pref;
- } else if (value < maxPref) {
- interval = QGraphicsAnchorLayoutPrivate::PreferredToMaxPreferred;
- lower = pref;
- upper = maxPref;
- } else {
- interval = QGraphicsAnchorLayoutPrivate::MaxPreferredToMaximum;
- lower = maxPref;
- upper = max;
- }
-
- qreal progress;
- if (upper == lower) {
- progress = 0;
- } else {
- progress = (value - lower) / (upper - lower);
- }
-
- return qMakePair(interval, progress);
-}
-
-static qreal interpolate(const QPair<QGraphicsAnchorLayoutPrivate::Interval, qreal> &factor,
- qreal min, qreal minPref, qreal pref, qreal maxPref, qreal max)
-{
- qreal lower = 0;
- qreal upper = 0;
-
- switch (factor.first) {
- case QGraphicsAnchorLayoutPrivate::MinimumToMinPreferred:
- lower = min;
- upper = minPref;
- break;
- case QGraphicsAnchorLayoutPrivate::MinPreferredToPreferred:
- lower = minPref;
- upper = pref;
- break;
- case QGraphicsAnchorLayoutPrivate::PreferredToMaxPreferred:
- lower = pref;
- upper = maxPref;
- break;
- case QGraphicsAnchorLayoutPrivate::MaxPreferredToMaximum:
- lower = maxPref;
- upper = max;
- break;
- }
-
- return lower + factor.second * (upper - lower);
-}
-
-void SequentialAnchorData::updateChildrenSizes()
-{
- // Band here refers if the value is in the Minimum To Preferred
- // band (the lower band) or the Preferred To Maximum (the upper band).
-
- const QPair<QGraphicsAnchorLayoutPrivate::Interval, qreal> minFactor =
- getFactor(sizeAtMinimum, minSize, minPrefSize, prefSize, maxPrefSize, maxSize);
- const QPair<QGraphicsAnchorLayoutPrivate::Interval, qreal> prefFactor =
- getFactor(sizeAtPreferred, minSize, minPrefSize, prefSize, maxPrefSize, maxSize);
- const QPair<QGraphicsAnchorLayoutPrivate::Interval, qreal> maxFactor =
- getFactor(sizeAtMaximum, minSize, minPrefSize, prefSize, maxPrefSize, maxSize);
-
- // XXX This is not safe if Vertex simplification takes place after the sequential
- // anchor is created. In that case, "prev" will be a group-vertex, different from
- // "from" or "to", that _contains_ one of them.
- AnchorVertex *prev = from;
-
- for (int i = 0; i < m_edges.count(); ++i) {
- AnchorData *e = m_edges.at(i);
-
- const bool edgeIsForward = (e->from == prev);
- if (edgeIsForward) {
- e->sizeAtMinimum = interpolate(minFactor, e->minSize, e->minPrefSize,
- e->prefSize, e->maxPrefSize, e->maxSize);
- e->sizeAtPreferred = interpolate(prefFactor, e->minSize, e->minPrefSize,
- e->prefSize, e->maxPrefSize, e->maxSize);
- e->sizeAtMaximum = interpolate(maxFactor, e->minSize, e->minPrefSize,
- e->prefSize, e->maxPrefSize, e->maxSize);
- prev = e->to;
- } else {
- Q_ASSERT(prev == e->to);
- e->sizeAtMinimum = interpolate(minFactor, e->maxSize, e->maxPrefSize,
- e->prefSize, e->minPrefSize, e->minSize);
- e->sizeAtPreferred = interpolate(prefFactor, e->maxSize, e->maxPrefSize,
- e->prefSize, e->minPrefSize, e->minSize);
- e->sizeAtMaximum = interpolate(maxFactor, e->maxSize, e->maxPrefSize,
- e->prefSize, e->minPrefSize, e->minSize);
- prev = e->from;
- }
-
- e->updateChildrenSizes();
- }
-}
-
-void SequentialAnchorData::calculateSizeHints()
-{
- minSize = 0;
- prefSize = 0;
- maxSize = 0;
- minPrefSize = 0;
- maxPrefSize = 0;
-
- AnchorVertex *prev = from;
-
- for (int i = 0; i < m_edges.count(); ++i) {
- AnchorData *edge = m_edges.at(i);
-
- const bool edgeIsForward = (edge->from == prev);
- if (edgeIsForward) {
- minSize += edge->minSize;
- prefSize += edge->prefSize;
- maxSize += edge->maxSize;
- minPrefSize += edge->minPrefSize;
- maxPrefSize += edge->maxPrefSize;
- prev = edge->to;
- } else {
- Q_ASSERT(prev == edge->to);
- minSize -= edge->maxSize;
- prefSize -= edge->prefSize;
- maxSize -= edge->minSize;
- minPrefSize -= edge->maxPrefSize;
- maxPrefSize -= edge->minPrefSize;
- prev = edge->from;
- }
- }
-
- // See comment in AnchorData::refreshSizeHints() about sizeAt* values
- sizeAtMinimum = prefSize;
- sizeAtPreferred = prefSize;
- sizeAtMaximum = prefSize;
-}
-
-#ifdef QT_DEBUG
-void AnchorData::dump(int indent) {
- if (type == Parallel) {
- qDebug("%*s type: parallel:", indent, "");
- ParallelAnchorData *p = static_cast<ParallelAnchorData *>(this);
- p->firstEdge->dump(indent+2);
- p->secondEdge->dump(indent+2);
- } else if (type == Sequential) {
- SequentialAnchorData *s = static_cast<SequentialAnchorData *>(this);
- int kids = s->m_edges.count();
- qDebug("%*s type: sequential(%d):", indent, "", kids);
- for (int i = 0; i < kids; ++i) {
- s->m_edges.at(i)->dump(indent+2);
- }
- } else {
- qDebug("%*s type: Normal:", indent, "");
- }
-}
-
-#endif
-
-QSimplexConstraint *GraphPath::constraint(const GraphPath &path) const
-{
- // Calculate
- QSet<AnchorData *> cPositives;
- QSet<AnchorData *> cNegatives;
- QSet<AnchorData *> intersection;
-
- cPositives = positives + path.negatives;
- cNegatives = negatives + path.positives;
-
- intersection = cPositives & cNegatives;
-
- cPositives -= intersection;
- cNegatives -= intersection;
-
- // Fill
- QSimplexConstraint *c = new QSimplexConstraint;
- QSet<AnchorData *>::iterator i;
- for (i = cPositives.begin(); i != cPositives.end(); ++i)
- c->variables.insert(*i, 1.0);
-
- for (i = cNegatives.begin(); i != cNegatives.end(); ++i)
- c->variables.insert(*i, -1.0);
-
- return c;
-}
-
-#ifdef QT_DEBUG
-QString GraphPath::toString() const
-{
- QString string(QLatin1String("Path: "));
- foreach(AnchorData *edge, positives)
- string += QString::fromAscii(" (+++) %1").arg(edge->toString());
-
- foreach(AnchorData *edge, negatives)
- string += QString::fromAscii(" (---) %1").arg(edge->toString());
-
- return string;
-}
-#endif
-
-QGraphicsAnchorLayoutPrivate::QGraphicsAnchorLayoutPrivate()
- : calculateGraphCacheDirty(true), styleInfoDirty(true)
-{
- for (int i = 0; i < NOrientations; ++i) {
- for (int j = 0; j < 3; ++j) {
- sizeHints[i][j] = -1;
- }
- interpolationProgress[i] = -1;
-
- spacings[i] = -1;
- graphHasConflicts[i] = false;
-
- layoutFirstVertex[i] = 0;
- layoutCentralVertex[i] = 0;
- layoutLastVertex[i] = 0;
- }
-}
-
-Qt::AnchorPoint QGraphicsAnchorLayoutPrivate::oppositeEdge(Qt::AnchorPoint edge)
-{
- switch (edge) {
- case Qt::AnchorLeft:
- edge = Qt::AnchorRight;
- break;
- case Qt::AnchorRight:
- edge = Qt::AnchorLeft;
- break;
- case Qt::AnchorTop:
- edge = Qt::AnchorBottom;
- break;
- case Qt::AnchorBottom:
- edge = Qt::AnchorTop;
- break;
- default:
- break;
- }
- return edge;
-}
-
-
-/*!
- * \internal
- *
- * helper function in order to avoid overflowing anchor sizes
- * the returned size will never be larger than FLT_MAX
- *
- */
-inline static qreal checkAdd(qreal a, qreal b)
-{
- if (FLT_MAX - b < a)
- return FLT_MAX;
- return a + b;
-}
-
-/*!
- \internal
-
- Adds \a newAnchor to the graph.
-
- Returns the newAnchor itself if it could be added without further changes to the graph. If a
- new parallel anchor had to be created, then returns the new parallel anchor. If a parallel anchor
- had to be created and it results in an unfeasible setup, \a feasible is set to false, otherwise
- true.
-
- Note that in the case a new parallel anchor is created, it might also take over some constraints
- from its children anchors.
-*/
-AnchorData *QGraphicsAnchorLayoutPrivate::addAnchorMaybeParallel(AnchorData *newAnchor, bool *feasible)
-{
- Orientation orientation = Orientation(newAnchor->orientation);
- Graph<AnchorVertex, AnchorData> &g = graph[orientation];
- *feasible = true;
-
- // If already exists one anchor where newAnchor is supposed to be, we create a parallel
- // anchor.
- if (AnchorData *oldAnchor = g.takeEdge(newAnchor->from, newAnchor->to)) {
- ParallelAnchorData *parallel = new ParallelAnchorData(oldAnchor, newAnchor);
-
- // The parallel anchor will "replace" its children anchors in
- // every center constraint that they appear.
-
- // ### If the dependent (center) anchors had reference(s) to their constraints, we
- // could avoid traversing all the itemCenterConstraints.
- QList<QSimplexConstraint *> &constraints = itemCenterConstraints[orientation];
-
- AnchorData *children[2] = { oldAnchor, newAnchor };
- QList<QSimplexConstraint *> *childrenConstraints[2] = { &parallel->m_firstConstraints,
- &parallel->m_secondConstraints };
-
- for (int i = 0; i < 2; ++i) {
- AnchorData *child = children[i];
- QList<QSimplexConstraint *> *childConstraints = childrenConstraints[i];
-
- // We need to fix the second child constraints if the parallel group will have the
- // opposite direction of the second child anchor. For the point of view of external
- // entities, this anchor was reversed. So if at some point we say that the parallel
- // has a value of 20, this mean that the second child (when reversed) will be
- // assigned -20.
- const bool needsReverse = i == 1 && !parallel->secondForward();
-
- if (!child->isCenterAnchor)
- continue;
-
- parallel->isCenterAnchor = true;
-
- for (int j = 0; j < constraints.count(); ++j) {
- QSimplexConstraint *c = constraints[j];
- if (c->variables.contains(child)) {
- childConstraints->append(c);
- qreal v = c->variables.take(child);
- if (needsReverse)
- v *= -1;
- c->variables.insert(parallel, v);
- }
- }
- }
-
- // At this point we can identify that the parallel anchor is not feasible, e.g. one
- // anchor minimum size is bigger than the other anchor maximum size.
- *feasible = parallel->calculateSizeHints();
- newAnchor = parallel;
- }
-
- g.createEdge(newAnchor->from, newAnchor->to, newAnchor);
- return newAnchor;
-}
-
-/*!
- \internal
-
- Takes the sequence of vertices described by (\a before, \a vertices, \a after) and removes
- all anchors connected to the vertices in \a vertices, returning one simplified anchor between
- \a before and \a after.
-
- Note that this function doesn't add the created anchor to the graph. This should be done by
- the caller.
-*/
-static AnchorData *createSequence(Graph<AnchorVertex, AnchorData> *graph,
- AnchorVertex *before,
- const QVector<AnchorVertex*> &vertices,
- AnchorVertex *after)
-{
-#if defined(QT_DEBUG) && 0
- QString strVertices;
- for (int i = 0; i < vertices.count(); ++i) {
- strVertices += QString::fromAscii("%1 - ").arg(vertices.at(i)->toString());
- }
- QString strPath = QString::fromAscii("%1 - %2%3").arg(before->toString(), strVertices, after->toString());
- qDebug("simplifying [%s] to [%s - %s]", qPrintable(strPath), qPrintable(before->toString()), qPrintable(after->toString()));
-#endif
-
- AnchorVertex *prev = before;
- QVector<AnchorData *> edges;
-
- // Take from the graph, the edges that will be simplificated
- for (int i = 0; i < vertices.count(); ++i) {
- AnchorVertex *next = vertices.at(i);
- AnchorData *ad = graph->takeEdge(prev, next);
- Q_ASSERT(ad);
- edges.append(ad);
- prev = next;
- }
-
- // Take the last edge (not covered in the loop above)
- AnchorData *ad = graph->takeEdge(vertices.last(), after);
- Q_ASSERT(ad);
- edges.append(ad);
-
- // Create sequence
- SequentialAnchorData *sequence = new SequentialAnchorData(vertices, edges);
- sequence->from = before;
- sequence->to = after;
-
- sequence->calculateSizeHints();
-
- return sequence;
-}
-
-/*!
- \internal
-
- The purpose of this function is to simplify the graph.
- Simplification serves two purposes:
- 1. Reduce the number of edges in the graph, (thus the number of variables to the equation
- solver is reduced, and the solver performs better).
- 2. Be able to do distribution of sequences of edges more intelligently (esp. with sequential
- anchors)
-
- It is essential that it must be possible to restore simplified anchors back to their "original"
- form. This is done by restoreSimplifiedAnchor().
-
- There are two types of simplification that can be done:
- 1. Sequential simplification
- Sequential simplification means that all sequences of anchors will be merged into one single
- anchor. Only anhcors that points in the same direction will be merged.
- 2. Parallel simplification
- If a simplified sequential anchor is about to be inserted between two vertices in the graph
- and there already exist an anchor between those two vertices, a parallel anchor will be
- created that serves as a placeholder for the sequential anchor and the anchor that was
- already between the two vertices.
-
- The process of simplification can be described as:
-
- 1. Simplify all sequences of anchors into one anchor.
- If no further simplification was done, go to (3)
- - If there already exist an anchor where the sequential anchor is supposed to be inserted,
- take that anchor out of the graph
- - Then create a parallel anchor that holds the sequential anchor and the anchor just taken
- out of the graph.
- 2. Go to (1)
- 3. Done
-
- When creating the parallel anchors, the algorithm might identify unfeasible situations. In this
- case the simplification process stops and returns false. Otherwise returns true.
-*/
-bool QGraphicsAnchorLayoutPrivate::simplifyGraph(Orientation orientation)
-{
- if (items.isEmpty())
- return true;
-
-#if defined(QT_DEBUG) && 0
- qDebug("Simplifying Graph for %s",
- orientation == Horizontal ? "Horizontal" : "Vertical");
-
- static int count = 0;
- if (orientation == Horizontal) {
- count++;
- dumpGraph(QString::fromAscii("%1-full").arg(count));
- }
-#endif
-
- // Vertex simplification
- if (!simplifyVertices(orientation)) {
- restoreVertices(orientation);
- return false;
- }
-
- // Anchor simplification
- bool dirty;
- bool feasible = true;
- do {
- dirty = simplifyGraphIteration(orientation, &feasible);
- } while (dirty && feasible);
-
- // Note that if we are not feasible, we fallback and make sure that the graph is fully restored
- if (!feasible) {
- restoreSimplifiedGraph(orientation);
- restoreVertices(orientation);
- return false;
- }
-
-#if defined(QT_DEBUG) && 0
- dumpGraph(QString::fromAscii("%1-simplified-%2").arg(count).arg(
- QString::fromAscii(orientation == Horizontal ? "Horizontal" : "Vertical")));
-#endif
-
- return true;
-}
-
-static AnchorVertex *replaceVertex_helper(AnchorData *data, AnchorVertex *oldV, AnchorVertex *newV)
-{
- AnchorVertex *other;
- if (data->from == oldV) {
- data->from = newV;
- other = data->to;
- } else {
- data->to = newV;
- other = data->from;
- }
- return other;
-}
-
-bool QGraphicsAnchorLayoutPrivate::replaceVertex(Orientation orientation, AnchorVertex *oldV,
- AnchorVertex *newV, const QList<AnchorData *> &edges)
-{
- Graph<AnchorVertex, AnchorData> &g = graph[orientation];
- bool feasible = true;
-
- for (int i = 0; i < edges.count(); ++i) {
- AnchorData *ad = edges[i];
- AnchorVertex *otherV = replaceVertex_helper(ad, oldV, newV);
-
-#if defined(QT_DEBUG)
- ad->name = QString::fromAscii("%1 --to--> %2").arg(ad->from->toString()).arg(ad->to->toString());
-#endif
-
- bool newFeasible;
- AnchorData *newAnchor = addAnchorMaybeParallel(ad, &newFeasible);
- feasible &= newFeasible;
-
- if (newAnchor != ad) {
- // A parallel was created, we mark that in the list of anchors created by vertex
- // simplification. This is needed because we want to restore them in a separate step
- // from the restoration of anchor simplification.
- anchorsFromSimplifiedVertices[orientation].append(newAnchor);
- }
-
- g.takeEdge(oldV, otherV);
- }
-
- return feasible;
-}
-
-/*!
- \internal
-*/
-bool QGraphicsAnchorLayoutPrivate::simplifyVertices(Orientation orientation)
-{
- Q_Q(QGraphicsAnchorLayout);
- Graph<AnchorVertex, AnchorData> &g = graph[orientation];
-
- // We'll walk through vertices
- QStack<AnchorVertex *> stack;
- stack.push(layoutFirstVertex[orientation]);
- QSet<AnchorVertex *> visited;
-
- while (!stack.isEmpty()) {
- AnchorVertex *v = stack.pop();
- visited.insert(v);
-
- // Each adjacent of 'v' is a possible vertex to be merged. So we traverse all of
- // them. Since once a merge is made, we might add new adjacents, and we don't want to
- // pass two times through one adjacent. The 'index' is used to track our position.
- QList<AnchorVertex *> adjacents = g.adjacentVertices(v);
- int index = 0;
-
- while (index < adjacents.count()) {
- AnchorVertex *next = adjacents.at(index);
- index++;
-
- AnchorData *data = g.edgeData(v, next);
- const bool bothLayoutVertices = v->m_item == q && next->m_item == q;
- const bool zeroSized = !data->minSize && !data->maxSize;
-
- if (!bothLayoutVertices && zeroSized) {
-
- // Create a new vertex pair, note that we keep a list of those vertices so we can
- // easily process them when restoring the graph.
- AnchorVertexPair *newV = new AnchorVertexPair(v, next, data);
- simplifiedVertices[orientation].append(newV);
-
- // Collect the anchors of both vertices, the new vertex pair will take their place
- // in those anchors
- const QList<AnchorVertex *> &vAdjacents = g.adjacentVertices(v);
- const QList<AnchorVertex *> &nextAdjacents = g.adjacentVertices(next);
-
- for (int i = 0; i < vAdjacents.count(); ++i) {
- AnchorVertex *adjacent = vAdjacents.at(i);
- if (adjacent != next) {
- AnchorData *ad = g.edgeData(v, adjacent);
- newV->m_firstAnchors.append(ad);
- }
- }
-
- for (int i = 0; i < nextAdjacents.count(); ++i) {
- AnchorVertex *adjacent = nextAdjacents.at(i);
- if (adjacent != v) {
- AnchorData *ad = g.edgeData(next, adjacent);
- newV->m_secondAnchors.append(ad);
-
- // We'll also add new vertices to the adjacent list of the new 'v', to be
- // created as a vertex pair and replace the current one.
- if (!adjacents.contains(adjacent))
- adjacents.append(adjacent);
- }
- }
-
- // ### merge this loop into the ones that calculated m_firstAnchors/m_secondAnchors?
- // Make newV take the place of v and next
- bool feasible = replaceVertex(orientation, v, newV, newV->m_firstAnchors);
- feasible &= replaceVertex(orientation, next, newV, newV->m_secondAnchors);
-
- // Update the layout vertex information if one of the vertices is a layout vertex.
- AnchorVertex *layoutVertex = 0;
- if (v->m_item == q)
- layoutVertex = v;
- else if (next->m_item == q)
- layoutVertex = next;
-
- if (layoutVertex) {
- // Layout vertices always have m_item == q...
- newV->m_item = q;
- changeLayoutVertex(orientation, layoutVertex, newV);
- }
-
- g.takeEdge(v, next);
-
- // If a non-feasibility is found, we leave early and cancel the simplification
- if (!feasible)
- return false;
-
- v = newV;
- visited.insert(newV);
-
- } else if (!visited.contains(next) && !stack.contains(next)) {
- // If the adjacent is not fit for merge and it wasn't visited by the outermost
- // loop, we add it to the stack.
- stack.push(next);
- }
- }
- }
-
- return true;
-}
-
-/*!
- \internal
-
- One iteration of the simplification algorithm. Returns true if another iteration is needed.
-
- The algorithm walks the graph in depth-first order, and only collects vertices that has two
- edges connected to it. If the vertex does not have two edges or if it is a layout edge, it
- will take all the previously collected vertices and try to create a simplified sequential
- anchor representing all the previously collected vertices. Once the simplified anchor is
- inserted, the collected list is cleared in order to find the next sequence to simplify.
-
- Note that there are some catches to this that are not covered by the above explanation, see
- the function comments for more details.
-*/
-bool QGraphicsAnchorLayoutPrivate::simplifyGraphIteration(QGraphicsAnchorLayoutPrivate::Orientation orientation,
- bool *feasible)
-{
- Q_Q(QGraphicsAnchorLayout);
- Graph<AnchorVertex, AnchorData> &g = graph[orientation];
-
- QSet<AnchorVertex *> visited;
- QStack<QPair<AnchorVertex *, AnchorVertex *> > stack;
- stack.push(qMakePair(static_cast<AnchorVertex *>(0), layoutFirstVertex[orientation]));
- QVector<AnchorVertex*> candidates;
-
- // Walk depth-first, in the stack we store start of the candidate sequence (beforeSequence)
- // and the vertex to be visited.
- while (!stack.isEmpty()) {
- QPair<AnchorVertex *, AnchorVertex *> pair = stack.pop();
- AnchorVertex *beforeSequence = pair.first;
- AnchorVertex *v = pair.second;
-
- // The basic idea is to determine whether we found an end of sequence,
- // if that's the case, we stop adding vertices to the candidate list
- // and do a simplification step.
- //
- // A vertex can trigger an end of sequence if
- // (a) it is a layout vertex, we don't simplify away the layout vertices;
- // (b) it does not have exactly 2 adjacents;
- // (c) its next adjacent is already visited (a cycle in the graph).
- // (d) the next anchor is a center anchor.
-
- const QList<AnchorVertex *> &adjacents = g.adjacentVertices(v);
- const bool isLayoutVertex = v->m_item == q;
- AnchorVertex *afterSequence = v;
- bool endOfSequence = false;
-
- //
- // Identify the end cases.
- //
-
- // Identifies cases (a) and (b)
- endOfSequence = isLayoutVertex || adjacents.count() != 2;
-
- if (!endOfSequence) {
- // This is a tricky part. We peek at the next vertex to find out whether
- //
- // - we already visited the next vertex (c);
- // - the next anchor is a center (d).
- //
- // Those are needed to identify the remaining end of sequence cases. Note that unlike
- // (a) and (b), we preempt the end of sequence by looking into the next vertex.
-
- // Peek at the next vertex
- AnchorVertex *after;
- if (candidates.isEmpty())
- after = (beforeSequence == adjacents.last() ? adjacents.first() : adjacents.last());
- else
- after = (candidates.last() == adjacents.last() ? adjacents.first() : adjacents.last());
-
- // ### At this point we assumed that candidates will not contain 'after', this may not hold
- // when simplifying FLOATing anchors.
- Q_ASSERT(!candidates.contains(after));
-
- const AnchorData *data = g.edgeData(v, after);
- Q_ASSERT(data);
- const bool cycleFound = visited.contains(after);
-
- // Now cases (c) and (d)...
- endOfSequence = cycleFound || data->isCenterAnchor;
-
- if (!endOfSequence) {
- // If it's not an end of sequence, then the vertex didn't trigger neither of the
- // previously three cases, so it can be added to the candidates list.
- candidates.append(v);
- } else if (cycleFound && (beforeSequence != after)) {
- afterSequence = after;
- candidates.append(v);
- }
- }
-
- //
- // Add next non-visited vertices to the stack.
- //
- for (int i = 0; i < adjacents.count(); ++i) {
- AnchorVertex *next = adjacents.at(i);
- if (visited.contains(next))
- continue;
-
- // If current vertex is an end of sequence, and it'll reset the candidates list. So
- // the next vertices will build candidates lists with the current vertex as 'before'
- // vertex. If it's not an end of sequence, we keep the original 'before' vertex,
- // since we are keeping the candidates list.
- if (endOfSequence)
- stack.push(qMakePair(v, next));
- else
- stack.push(qMakePair(beforeSequence, next));
- }
-
- visited.insert(v);
-
- if (!endOfSequence || candidates.isEmpty())
- continue;
-
- //
- // Create a sequence for (beforeSequence, candidates, afterSequence).
- //
-
- // One restriction we have is to not simplify half of an anchor and let the other half
- // unsimplified. So we remove center edges before and after the sequence.
- const AnchorData *firstAnchor = g.edgeData(beforeSequence, candidates.first());
- if (firstAnchor->isCenterAnchor) {
- beforeSequence = candidates.first();
- candidates.remove(0);
-
- // If there's not candidates to be simplified, leave.
- if (candidates.isEmpty())
- continue;
- }
-
- const AnchorData *lastAnchor = g.edgeData(candidates.last(), afterSequence);
- if (lastAnchor->isCenterAnchor) {
- afterSequence = candidates.last();
- candidates.remove(candidates.count() - 1);
-
- if (candidates.isEmpty())
- continue;
- }
-
- //
- // Add the sequence to the graph.
- //
-
- AnchorData *sequence = createSequence(&g, beforeSequence, candidates, afterSequence);
-
- // If 'beforeSequence' and 'afterSequence' already had an anchor between them, we'll
- // create a parallel anchor between the new sequence and the old anchor.
- bool newFeasible;
- AnchorData *newAnchor = addAnchorMaybeParallel(sequence, &newFeasible);
-
- if (!newFeasible) {
- *feasible = false;
- return false;
- }
-
- // When a new parallel anchor is create in the graph, we finish the iteration and return
- // true to indicate a new iteration is needed. This happens because a parallel anchor
- // changes the number of adjacents one vertex has, possibly opening up oportunities for
- // building candidate lists (when adjacents == 2).
- if (newAnchor != sequence)
- return true;
-
- // If there was no parallel simplification, we'll keep walking the graph. So we clear the
- // candidates list to start again.
- candidates.clear();
- }
-
- return false;
-}
-
-void QGraphicsAnchorLayoutPrivate::restoreSimplifiedAnchor(AnchorData *edge)
-{
-#if 0
- static const char *anchortypes[] = {"Normal",
- "Sequential",
- "Parallel"};
- qDebug("Restoring %s edge.", anchortypes[int(edge->type)]);
-#endif
-
- Graph<AnchorVertex, AnchorData> &g = graph[edge->orientation];
-
- if (edge->type == AnchorData::Normal) {
- g.createEdge(edge->from, edge->to, edge);
-
- } else if (edge->type == AnchorData::Sequential) {
- SequentialAnchorData *sequence = static_cast<SequentialAnchorData *>(edge);
-
- for (int i = 0; i < sequence->m_edges.count(); ++i) {
- AnchorData *data = sequence->m_edges.at(i);
- restoreSimplifiedAnchor(data);
- }
-
- delete sequence;
-
- } else if (edge->type == AnchorData::Parallel) {
-
- // Skip parallel anchors that were created by vertex simplification, they will be processed
- // later, when restoring vertex simplification.
- // ### we could improve this check bit having a bit inside 'edge'
- if (anchorsFromSimplifiedVertices[edge->orientation].contains(edge))
- return;
-
- ParallelAnchorData* parallel = static_cast<ParallelAnchorData*>(edge);
- restoreSimplifiedConstraints(parallel);
-
- // ### Because of the way parallel anchors are created in the anchor simplification
- // algorithm, we know that one of these will be a sequence, so it'll be safe if the other
- // anchor create an edge between the same vertices as the parallel.
- Q_ASSERT(parallel->firstEdge->type == AnchorData::Sequential
- || parallel->secondEdge->type == AnchorData::Sequential);
- restoreSimplifiedAnchor(parallel->firstEdge);
- restoreSimplifiedAnchor(parallel->secondEdge);
-
- delete parallel;
- }
-}
-
-void QGraphicsAnchorLayoutPrivate::restoreSimplifiedConstraints(ParallelAnchorData *parallel)
-{
- if (!parallel->isCenterAnchor)
- return;
-
- for (int i = 0; i < parallel->m_firstConstraints.count(); ++i) {
- QSimplexConstraint *c = parallel->m_firstConstraints.at(i);
- qreal v = c->variables[parallel];
- c->variables.remove(parallel);
- c->variables.insert(parallel->firstEdge, v);
- }
-
- // When restoring, we might have to revert constraints back. See comments on
- // addAnchorMaybeParallel().
- const bool needsReverse = !parallel->secondForward();
-
- for (int i = 0; i < parallel->m_secondConstraints.count(); ++i) {
- QSimplexConstraint *c = parallel->m_secondConstraints.at(i);
- qreal v = c->variables[parallel];
- if (needsReverse)
- v *= -1;
- c->variables.remove(parallel);
- c->variables.insert(parallel->secondEdge, v);
- }
-}
-
-void QGraphicsAnchorLayoutPrivate::restoreSimplifiedGraph(Orientation orientation)
-{
-#if 0
- qDebug("Restoring Simplified Graph for %s",
- orientation == Horizontal ? "Horizontal" : "Vertical");
-#endif
-
- // Restore anchor simplification
- Graph<AnchorVertex, AnchorData> &g = graph[orientation];
- QList<QPair<AnchorVertex*, AnchorVertex*> > connections = g.connections();
- for (int i = 0; i < connections.count(); ++i) {
- AnchorVertex *v1 = connections.at(i).first;
- AnchorVertex *v2 = connections.at(i).second;
- AnchorData *edge = g.edgeData(v1, v2);
-
- // We restore only sequential anchors and parallels that were not created by
- // vertex simplification.
- if (edge->type == AnchorData::Sequential
- || (edge->type == AnchorData::Parallel &&
- !anchorsFromSimplifiedVertices[orientation].contains(edge))) {
-
- g.takeEdge(v1, v2);
- restoreSimplifiedAnchor(edge);
- }
- }
-
- restoreVertices(orientation);
-}
-
-void QGraphicsAnchorLayoutPrivate::restoreVertices(Orientation orientation)
-{
- Q_Q(QGraphicsAnchorLayout);
-
- Graph<AnchorVertex, AnchorData> &g = graph[orientation];
- QList<AnchorVertexPair *> &toRestore = simplifiedVertices[orientation];
-
- // Since we keep a list of parallel anchors and vertices that were created during vertex
- // simplification, we can now iterate on those lists instead of traversing the graph
- // recursively.
-
- // First, restore the constraints changed when we created parallel anchors. Note that this
- // works at this point because the constraints doesn't depend on vertex information and at
- // this point it's always safe to identify whether the second child is forward or backwards.
- // In the next step, we'll change the anchors vertices so that would not be possible anymore.
- QList<AnchorData *> &parallelAnchors = anchorsFromSimplifiedVertices[orientation];
-
- for (int i = parallelAnchors.count() - 1; i >= 0; --i) {
- ParallelAnchorData *parallel = static_cast<ParallelAnchorData *>(parallelAnchors.at(i));
- restoreSimplifiedConstraints(parallel);
- }
-
- // Then, we will restore the vertices in the inverse order of creation, this way we ensure that
- // the vertex being restored was not wrapped by another simplification.
- for (int i = toRestore.count() - 1; i >= 0; --i) {
- AnchorVertexPair *pair = toRestore.at(i);
- QList<AnchorVertex *> adjacents = g.adjacentVertices(pair);
-
- // Restore the removed edge, this will also restore both vertices 'first' and 'second' to
- // the graph structure.
- AnchorVertex *first = pair->m_first;
- AnchorVertex *second = pair->m_second;
- g.createEdge(first, second, pair->m_removedAnchor);
-
- // Restore the anchors for the first child vertex
- for (int j = 0; j < pair->m_firstAnchors.count(); ++j) {
- AnchorData *ad = pair->m_firstAnchors.at(j);
- Q_ASSERT(ad->from == pair || ad->to == pair);
-
- replaceVertex_helper(ad, pair, first);
- g.createEdge(ad->from, ad->to, ad);
- }
-
- // Restore the anchors for the second child vertex
- for (int j = 0; j < pair->m_secondAnchors.count(); ++j) {
- AnchorData *ad = pair->m_secondAnchors.at(j);
- Q_ASSERT(ad->from == pair || ad->to == pair);
-
- replaceVertex_helper(ad, pair, second);
- g.createEdge(ad->from, ad->to, ad);
- }
-
- for (int j = 0; j < adjacents.count(); ++j) {
- g.takeEdge(pair, adjacents.at(j));
- }
-
- // The pair simplified a layout vertex, so place back the correct vertex in the variable
- // that track layout vertices
- if (pair->m_item == q) {
- AnchorVertex *layoutVertex = first->m_item == q ? first : second;
- Q_ASSERT(layoutVertex->m_item == q);
- changeLayoutVertex(orientation, pair, layoutVertex);
- }
-
- delete pair;
- }
- qDeleteAll(parallelAnchors);
- parallelAnchors.clear();
- toRestore.clear();
-}
-
-QGraphicsAnchorLayoutPrivate::Orientation
-QGraphicsAnchorLayoutPrivate::edgeOrientation(Qt::AnchorPoint edge)
-{
- return edge > Qt::AnchorRight ? Vertical : Horizontal;
-}
-
-/*!
- \internal
-
- Create internal anchors to connect the layout edges (Left to Right and
- Top to Bottom).
-
- These anchors doesn't have size restrictions, that will be enforced by
- other anchors and items in the layout.
-*/
-void QGraphicsAnchorLayoutPrivate::createLayoutEdges()
-{
- Q_Q(QGraphicsAnchorLayout);
- QGraphicsLayoutItem *layout = q;
-
- // Horizontal
- AnchorData *data = new AnchorData;
- addAnchor_helper(layout, Qt::AnchorLeft, layout,
- Qt::AnchorRight, data);
- data->maxSize = QWIDGETSIZE_MAX;
-
- // Save a reference to layout vertices
- layoutFirstVertex[Horizontal] = internalVertex(layout, Qt::AnchorLeft);
- layoutCentralVertex[Horizontal] = 0;
- layoutLastVertex[Horizontal] = internalVertex(layout, Qt::AnchorRight);
-
- // Vertical
- data = new AnchorData;
- addAnchor_helper(layout, Qt::AnchorTop, layout,
- Qt::AnchorBottom, data);
- data->maxSize = QWIDGETSIZE_MAX;
-
- // Save a reference to layout vertices
- layoutFirstVertex[Vertical] = internalVertex(layout, Qt::AnchorTop);
- layoutCentralVertex[Vertical] = 0;
- layoutLastVertex[Vertical] = internalVertex(layout, Qt::AnchorBottom);
-}
-
-void QGraphicsAnchorLayoutPrivate::deleteLayoutEdges()
-{
- Q_Q(QGraphicsAnchorLayout);
-
- Q_ASSERT(!internalVertex(q, Qt::AnchorHorizontalCenter));
- Q_ASSERT(!internalVertex(q, Qt::AnchorVerticalCenter));
-
- removeAnchor_helper(internalVertex(q, Qt::AnchorLeft),
- internalVertex(q, Qt::AnchorRight));
- removeAnchor_helper(internalVertex(q, Qt::AnchorTop),
- internalVertex(q, Qt::AnchorBottom));
-}
-
-void QGraphicsAnchorLayoutPrivate::createItemEdges(QGraphicsLayoutItem *item)
-{
- items.append(item);
-
- // Create horizontal and vertical internal anchors for the item and
- // refresh its size hint / policy values.
- AnchorData *data = new AnchorData;
- addAnchor_helper(item, Qt::AnchorLeft, item, Qt::AnchorRight, data);
- data->refreshSizeHints();
-
- data = new AnchorData;
- addAnchor_helper(item, Qt::AnchorTop, item, Qt::AnchorBottom, data);
- data->refreshSizeHints();
-}
-
-/*!
- \internal
-
- By default, each item in the layout is represented internally as
- a single anchor in each direction. For instance, from Left to Right.
-
- However, to support anchorage of items to the center of items, we
- must split this internal anchor into two half-anchors. From Left
- to Center and then from Center to Right, with the restriction that
- these anchors must have the same time at all times.
-*/
-void QGraphicsAnchorLayoutPrivate::createCenterAnchors(
- QGraphicsLayoutItem *item, Qt::AnchorPoint centerEdge)
-{
- Q_Q(QGraphicsAnchorLayout);
-
- Orientation orientation;
- switch (centerEdge) {
- case Qt::AnchorHorizontalCenter:
- orientation = Horizontal;
- break;
- case Qt::AnchorVerticalCenter:
- orientation = Vertical;
- break;
- default:
- // Don't create center edges unless needed
- return;
- }
-
- // Check if vertex already exists
- if (internalVertex(item, centerEdge))
- return;
-
- // Orientation code
- Qt::AnchorPoint firstEdge;
- Qt::AnchorPoint lastEdge;
-
- if (orientation == Horizontal) {
- firstEdge = Qt::AnchorLeft;
- lastEdge = Qt::AnchorRight;
- } else {
- firstEdge = Qt::AnchorTop;
- lastEdge = Qt::AnchorBottom;
- }
-
- AnchorVertex *first = internalVertex(item, firstEdge);
- AnchorVertex *last = internalVertex(item, lastEdge);
- Q_ASSERT(first && last);
-
- // Create new anchors
- QSimplexConstraint *c = new QSimplexConstraint;
-
- AnchorData *data = new AnchorData;
- c->variables.insert(data, 1.0);
- addAnchor_helper(item, firstEdge, item, centerEdge, data);
- data->isCenterAnchor = true;
- data->dependency = AnchorData::Master;
- data->refreshSizeHints();
-
- data = new AnchorData;
- c->variables.insert(data, -1.0);
- addAnchor_helper(item, centerEdge, item, lastEdge, data);
- data->isCenterAnchor = true;
- data->dependency = AnchorData::Slave;
- data->refreshSizeHints();
-
- itemCenterConstraints[orientation].append(c);
-
- // Remove old one
- removeAnchor_helper(first, last);
-
- if (item == q) {
- layoutCentralVertex[orientation] = internalVertex(q, centerEdge);
- }
-}
-
-void QGraphicsAnchorLayoutPrivate::removeCenterAnchors(
- QGraphicsLayoutItem *item, Qt::AnchorPoint centerEdge,
- bool substitute)
-{
- Q_Q(QGraphicsAnchorLayout);
-
- Orientation orientation;
- switch (centerEdge) {
- case Qt::AnchorHorizontalCenter:
- orientation = Horizontal;
- break;
- case Qt::AnchorVerticalCenter:
- orientation = Vertical;
- break;
- default:
- // Don't remove edges that not the center ones
- return;
- }
-
- // Orientation code
- Qt::AnchorPoint firstEdge;
- Qt::AnchorPoint lastEdge;
-
- if (orientation == Horizontal) {
- firstEdge = Qt::AnchorLeft;
- lastEdge = Qt::AnchorRight;
- } else {
- firstEdge = Qt::AnchorTop;
- lastEdge = Qt::AnchorBottom;
- }
-
- AnchorVertex *center = internalVertex(item, centerEdge);
- if (!center)
- return;
- AnchorVertex *first = internalVertex(item, firstEdge);
-
- Q_ASSERT(first);
- Q_ASSERT(center);
-
- Graph<AnchorVertex, AnchorData> &g = graph[orientation];
-
-
- AnchorData *oldData = g.edgeData(first, center);
- // Remove center constraint
- for (int i = itemCenterConstraints[orientation].count() - 1; i >= 0; --i) {
- if (itemCenterConstraints[orientation].at(i)->variables.contains(oldData)) {
- delete itemCenterConstraints[orientation].takeAt(i);
- break;
- }
- }
-
- if (substitute) {
- // Create the new anchor that should substitute the left-center-right anchors.
- AnchorData *data = new AnchorData;
- addAnchor_helper(item, firstEdge, item, lastEdge, data);
- data->refreshSizeHints();
-
- // Remove old anchors
- removeAnchor_helper(first, center);
- removeAnchor_helper(center, internalVertex(item, lastEdge));
-
- } else {
- // this is only called from removeAnchors()
- // first, remove all non-internal anchors
- QList<AnchorVertex*> adjacents = g.adjacentVertices(center);
- for (int i = 0; i < adjacents.count(); ++i) {
- AnchorVertex *v = adjacents.at(i);
- if (v->m_item != item) {
- removeAnchor_helper(center, internalVertex(v->m_item, v->m_edge));
- }
- }
- // when all non-internal anchors is removed it will automatically merge the
- // center anchor into a left-right (or top-bottom) anchor. We must also delete that.
- // by this time, the center vertex is deleted and merged into a non-centered internal anchor
- removeAnchor_helper(first, internalVertex(item, lastEdge));
- }
-
- if (item == q) {
- layoutCentralVertex[orientation] = 0;
- }
-}
-
-
-void QGraphicsAnchorLayoutPrivate::removeCenterConstraints(QGraphicsLayoutItem *item,
- Orientation orientation)
-{
- // Remove the item center constraints associated to this item
- // ### This is a temporary solution. We should probably use a better
- // data structure to hold items and/or their associated constraints
- // so that we can remove those easily
-
- AnchorVertex *first = internalVertex(item, orientation == Horizontal ?
- Qt::AnchorLeft :
- Qt::AnchorTop);
- AnchorVertex *center = internalVertex(item, orientation == Horizontal ?
- Qt::AnchorHorizontalCenter :
- Qt::AnchorVerticalCenter);
-
- // Skip if no center constraints exist
- if (!center)
- return;
-
- Q_ASSERT(first);
- AnchorData *internalAnchor = graph[orientation].edgeData(first, center);
-
- // Look for our anchor in all item center constraints, then remove it
- for (int i = 0; i < itemCenterConstraints[orientation].size(); ++i) {
- if (itemCenterConstraints[orientation].at(i)->variables.contains(internalAnchor)) {
- delete itemCenterConstraints[orientation].takeAt(i);
- break;
- }
- }
-}
-
-/*!
- * \internal
- * Implements the high level "addAnchor" feature. Called by the public API
- * addAnchor method.
- *
- * The optional \a spacing argument defines the size of the anchor. If not provided,
- * the anchor size is either 0 or not-set, depending on type of anchor created (see
- * matrix below).
- *
- * All anchors that remain with size not-set will assume the standard spacing,
- * set either by the layout style or through the "setSpacing" layout API.
- */
-QGraphicsAnchor *QGraphicsAnchorLayoutPrivate::addAnchor(QGraphicsLayoutItem *firstItem,
- Qt::AnchorPoint firstEdge,
- QGraphicsLayoutItem *secondItem,
- Qt::AnchorPoint secondEdge,
- qreal *spacing)
-{
- Q_Q(QGraphicsAnchorLayout);
- if ((firstItem == 0) || (secondItem == 0)) {
- qWarning("QGraphicsAnchorLayout::addAnchor(): "
- "Cannot anchor NULL items");
- return 0;
- }
-
- if (firstItem == secondItem) {
- qWarning("QGraphicsAnchorLayout::addAnchor(): "
- "Cannot anchor the item to itself");
- return 0;
- }
-
- if (edgeOrientation(secondEdge) != edgeOrientation(firstEdge)) {
- qWarning("QGraphicsAnchorLayout::addAnchor(): "
- "Cannot anchor edges of different orientations");
- return 0;
- }
-
- const QGraphicsLayoutItem *parentWidget = q->parentLayoutItem();
- if (firstItem == parentWidget || secondItem == parentWidget) {
- qWarning("QGraphicsAnchorLayout::addAnchor(): "
- "You cannot add the parent of the layout to the layout.");
- return 0;
- }
-
- // In QGraphicsAnchorLayout, items are represented in its internal
- // graph as four anchors that connect:
- // - Left -> HCenter
- // - HCenter-> Right
- // - Top -> VCenter
- // - VCenter -> Bottom
-
- // Ensure that the internal anchors have been created for both items.
- if (firstItem != q && !items.contains(firstItem)) {
- createItemEdges(firstItem);
- addChildLayoutItem(firstItem);
- }
- if (secondItem != q && !items.contains(secondItem)) {
- createItemEdges(secondItem);
- addChildLayoutItem(secondItem);
- }
-
- // Create center edges if needed
- createCenterAnchors(firstItem, firstEdge);
- createCenterAnchors(secondItem, secondEdge);
-
- // Use heuristics to find out what the user meant with this anchor.
- correctEdgeDirection(firstItem, firstEdge, secondItem, secondEdge);
-
- AnchorData *data = new AnchorData;
- QGraphicsAnchor *graphicsAnchor = acquireGraphicsAnchor(data);
-
- addAnchor_helper(firstItem, firstEdge, secondItem, secondEdge, data);
-
- if (spacing) {
- graphicsAnchor->setSpacing(*spacing);
- } else {
- // If firstItem or secondItem is the layout itself, the spacing will default to 0.
- // Otherwise, the following matrix is used (questionmark means that the spacing
- // is queried from the style):
- // from
- // to Left HCenter Right
- // Left 0 0 ?
- // HCenter 0 0 0
- // Right ? 0 0
- if (firstItem == q
- || secondItem == q
- || pickEdge(firstEdge, Horizontal) == Qt::AnchorHorizontalCenter
- || oppositeEdge(firstEdge) != secondEdge) {
- graphicsAnchor->setSpacing(0);
- } else {
- graphicsAnchor->unsetSpacing();
- }
- }
-
- return graphicsAnchor;
-}
-
-/*
- \internal
-
- This method adds an AnchorData to the internal graph. It is responsible for doing
- the boilerplate part of such task.
-
- If another AnchorData exists between the mentioned vertices, it is deleted and
- the new one is inserted.
-*/
-void QGraphicsAnchorLayoutPrivate::addAnchor_helper(QGraphicsLayoutItem *firstItem,
- Qt::AnchorPoint firstEdge,
- QGraphicsLayoutItem *secondItem,
- Qt::AnchorPoint secondEdge,
- AnchorData *data)
-{
- Q_Q(QGraphicsAnchorLayout);
-
- const Orientation orientation = edgeOrientation(firstEdge);
-
- // Create or increase the reference count for the related vertices.
- AnchorVertex *v1 = addInternalVertex(firstItem, firstEdge);
- AnchorVertex *v2 = addInternalVertex(secondItem, secondEdge);
-
- // Remove previous anchor
- if (graph[orientation].edgeData(v1, v2)) {
- removeAnchor_helper(v1, v2);
- }
-
- // If its an internal anchor, set the associated item
- if (firstItem == secondItem)
- data->item = firstItem;
-
- data->orientation = orientation;
-
- // Create a bi-directional edge in the sense it can be transversed both
- // from v1 or v2. "data" however is shared between the two references
- // so we still know that the anchor direction is from 1 to 2.
- data->from = v1;
- data->to = v2;
-#ifdef QT_DEBUG
- data->name = QString::fromAscii("%1 --to--> %2").arg(v1->toString()).arg(v2->toString());
-#endif
- // ### bit to track internal anchors, since inside AnchorData methods
- // we don't have access to the 'q' pointer.
- data->isLayoutAnchor = (data->item == q);
-
- graph[orientation].createEdge(v1, v2, data);
-}
-
-QGraphicsAnchor *QGraphicsAnchorLayoutPrivate::getAnchor(QGraphicsLayoutItem *firstItem,
- Qt::AnchorPoint firstEdge,
- QGraphicsLayoutItem *secondItem,
- Qt::AnchorPoint secondEdge)
-{
- // Do not expose internal anchors
- if (firstItem == secondItem)
- return 0;
-
- const Orientation orientation = edgeOrientation(firstEdge);
- AnchorVertex *v1 = internalVertex(firstItem, firstEdge);
- AnchorVertex *v2 = internalVertex(secondItem, secondEdge);
-
- QGraphicsAnchor *graphicsAnchor = 0;
-
- AnchorData *data = graph[orientation].edgeData(v1, v2);
- if (data) {
- // We could use "acquireGraphicsAnchor" here, but to avoid a regression where
- // an internal anchor was wrongly exposed, I want to ensure no new
- // QGraphicsAnchor instances are created by this call.
- // This assumption must hold because anchors are either user-created (and already
- // have their public object created), or they are internal (and must not reach
- // this point).
- Q_ASSERT(data->graphicsAnchor);
- graphicsAnchor = data->graphicsAnchor;
- }
- return graphicsAnchor;
-}
-
-/*!
- * \internal
- *
- * Implements the high level "removeAnchor" feature. Called by
- * the QAnchorData destructor.
- */
-void QGraphicsAnchorLayoutPrivate::removeAnchor(AnchorVertex *firstVertex,
- AnchorVertex *secondVertex)
-{
- Q_Q(QGraphicsAnchorLayout);
-
- // Save references to items while it's safe to assume the vertices exist
- QGraphicsLayoutItem *firstItem = firstVertex->m_item;
- QGraphicsLayoutItem *secondItem = secondVertex->m_item;
-
- // Delete the anchor (may trigger deletion of center vertices)
- removeAnchor_helper(firstVertex, secondVertex);
-
- // Ensure no dangling pointer is left behind
- firstVertex = secondVertex = 0;
-
- // Checking if the item stays in the layout or not
- bool keepFirstItem = false;
- bool keepSecondItem = false;
-
- QPair<AnchorVertex *, int> v;
- int refcount = -1;
-
- if (firstItem != q) {
- for (int i = Qt::AnchorLeft; i <= Qt::AnchorBottom; ++i) {
- v = m_vertexList.value(qMakePair(firstItem, static_cast<Qt::AnchorPoint>(i)));
- if (v.first) {
- if (i == Qt::AnchorHorizontalCenter || i == Qt::AnchorVerticalCenter)
- refcount = 2;
- else
- refcount = 1;
-
- if (v.second > refcount) {
- keepFirstItem = true;
- break;
- }
- }
- }
- } else
- keepFirstItem = true;
-
- if (secondItem != q) {
- for (int i = Qt::AnchorLeft; i <= Qt::AnchorBottom; ++i) {
- v = m_vertexList.value(qMakePair(secondItem, static_cast<Qt::AnchorPoint>(i)));
- if (v.first) {
- if (i == Qt::AnchorHorizontalCenter || i == Qt::AnchorVerticalCenter)
- refcount = 2;
- else
- refcount = 1;
-
- if (v.second > refcount) {
- keepSecondItem = true;
- break;
- }
- }
- }
- } else
- keepSecondItem = true;
-
- if (!keepFirstItem)
- q->removeAt(items.indexOf(firstItem));
-
- if (!keepSecondItem)
- q->removeAt(items.indexOf(secondItem));
-
- // Removing anchors invalidates the layout
- q->invalidate();
-}
-
-/*
- \internal
-
- Implements the low level "removeAnchor" feature. Called by
- private methods.
-*/
-void QGraphicsAnchorLayoutPrivate::removeAnchor_helper(AnchorVertex *v1, AnchorVertex *v2)
-{
- Q_ASSERT(v1 && v2);
-
- // Remove edge from graph
- const Orientation o = edgeOrientation(v1->m_edge);
- graph[o].removeEdge(v1, v2);
-
- // Decrease vertices reference count (may trigger a deletion)
- removeInternalVertex(v1->m_item, v1->m_edge);
- removeInternalVertex(v2->m_item, v2->m_edge);
-}
-
-AnchorVertex *QGraphicsAnchorLayoutPrivate::addInternalVertex(QGraphicsLayoutItem *item,
- Qt::AnchorPoint edge)
-{
- QPair<QGraphicsLayoutItem *, Qt::AnchorPoint> pair(item, edge);
- QPair<AnchorVertex *, int> v = m_vertexList.value(pair);
-
- if (!v.first) {
- Q_ASSERT(v.second == 0);
- v.first = new AnchorVertex(item, edge);
- }
- v.second++;
- m_vertexList.insert(pair, v);
- return v.first;
-}
-
-/**
- * \internal
- *
- * returns the AnchorVertex that was dereferenced, also when it was removed.
- * returns 0 if it did not exist.
- */
-void QGraphicsAnchorLayoutPrivate::removeInternalVertex(QGraphicsLayoutItem *item,
- Qt::AnchorPoint edge)
-{
- QPair<QGraphicsLayoutItem *, Qt::AnchorPoint> pair(item, edge);
- QPair<AnchorVertex *, int> v = m_vertexList.value(pair);
-
- if (!v.first) {
- qWarning("This item with this edge is not in the graph");
- return;
- }
-
- v.second--;
- if (v.second == 0) {
- // Remove reference and delete vertex
- m_vertexList.remove(pair);
- delete v.first;
- } else {
- // Update reference count
- m_vertexList.insert(pair, v);
-
- if ((v.second == 2) &&
- ((edge == Qt::AnchorHorizontalCenter) ||
- (edge == Qt::AnchorVerticalCenter))) {
- removeCenterAnchors(item, edge, true);
- }
- }
-}
-
-void QGraphicsAnchorLayoutPrivate::removeVertex(QGraphicsLayoutItem *item, Qt::AnchorPoint edge)
-{
- if (AnchorVertex *v = internalVertex(item, edge)) {
- Graph<AnchorVertex, AnchorData> &g = graph[edgeOrientation(edge)];
- const QList<AnchorVertex *> allVertices = graph[edgeOrientation(edge)].adjacentVertices(v);
- AnchorVertex *v2;
- foreach (v2, allVertices) {
- g.removeEdge(v, v2);
- removeInternalVertex(item, edge);
- removeInternalVertex(v2->m_item, v2->m_edge);
- }
- }
-}
-
-void QGraphicsAnchorLayoutPrivate::removeAnchors(QGraphicsLayoutItem *item)
-{
- // remove the center anchor first!!
- removeCenterAnchors(item, Qt::AnchorHorizontalCenter, false);
- removeVertex(item, Qt::AnchorLeft);
- removeVertex(item, Qt::AnchorRight);
-
- removeCenterAnchors(item, Qt::AnchorVerticalCenter, false);
- removeVertex(item, Qt::AnchorTop);
- removeVertex(item, Qt::AnchorBottom);
-}
-
-/*!
- \internal
-
- Use heuristics to determine the correct orientation of a given anchor.
-
- After API discussions, we decided we would like expressions like
- anchor(A, Left, B, Right) to mean the same as anchor(B, Right, A, Left).
- The problem with this is that anchors could become ambiguous, for
- instance, what does the anchor A, B of size X mean?
-
- "pos(B) = pos(A) + X" or "pos(A) = pos(B) + X" ?
-
- To keep the API user friendly and at the same time, keep our algorithm
- deterministic, we use an heuristic to determine a direction for each
- added anchor and then keep it. The heuristic is based on the fact
- that people usually avoid overlapping items, therefore:
-
- "A, RIGHT to B, LEFT" means that B is to the LEFT of A.
- "B, LEFT to A, RIGHT" is corrected to the above anchor.
-
- Special correction is also applied when one of the items is the
- layout. We handle Layout Left as if it was another items's Right
- and Layout Right as another item's Left.
-*/
-void QGraphicsAnchorLayoutPrivate::correctEdgeDirection(QGraphicsLayoutItem *&firstItem,
- Qt::AnchorPoint &firstEdge,
- QGraphicsLayoutItem *&secondItem,
- Qt::AnchorPoint &secondEdge)
-{
- Q_Q(QGraphicsAnchorLayout);
-
- if ((firstItem != q) && (secondItem != q)) {
- // If connection is between widgets (not the layout itself)
- // Ensure that "right-edges" sit to the left of "left-edges".
- if (firstEdge < secondEdge) {
- qSwap(firstItem, secondItem);
- qSwap(firstEdge, secondEdge);
- }
- } else if (firstItem == q) {
- // If connection involves the right or bottom of a layout, ensure
- // the layout is the second item.
- if ((firstEdge == Qt::AnchorRight) || (firstEdge == Qt::AnchorBottom)) {
- qSwap(firstItem, secondItem);
- qSwap(firstEdge, secondEdge);
- }
- } else if ((secondEdge != Qt::AnchorRight) && (secondEdge != Qt::AnchorBottom)) {
- // If connection involves the left, center or top of layout, ensure
- // the layout is the first item.
- qSwap(firstItem, secondItem);
- qSwap(firstEdge, secondEdge);
- }
-}
-
-QLayoutStyleInfo &QGraphicsAnchorLayoutPrivate::styleInfo() const
-{
- if (styleInfoDirty) {
- Q_Q(const QGraphicsAnchorLayout);
- //### Fix this if QGV ever gets support for Metal style or different Aqua sizes.
- QWidget *wid = 0;
-
- QGraphicsLayoutItem *parent = q->parentLayoutItem();
- while (parent && parent->isLayout()) {
- parent = parent->parentLayoutItem();
- }
- QGraphicsWidget *w = 0;
- if (parent) {
- QGraphicsItem *parentItem = parent->graphicsItem();
- if (parentItem && parentItem->isWidget())
- w = static_cast<QGraphicsWidget*>(parentItem);
- }
-
- QStyle *style = w ? w->style() : QApplication::style();
- cachedStyleInfo = QLayoutStyleInfo(style, wid);
- cachedStyleInfo.setDefaultSpacing(Qt::Horizontal, spacings[0]);
- cachedStyleInfo.setDefaultSpacing(Qt::Vertical, spacings[1]);
-
- styleInfoDirty = false;
- }
- return cachedStyleInfo;
-}
-
-/*!
- \internal
-
- Called on activation. Uses Linear Programming to define minimum, preferred
- and maximum sizes for the layout. Also calculates the sizes that each item
- should assume when the layout is in one of such situations.
-*/
-void QGraphicsAnchorLayoutPrivate::calculateGraphs()
-{
- if (!calculateGraphCacheDirty)
- return;
- calculateGraphs(Horizontal);
- calculateGraphs(Vertical);
- calculateGraphCacheDirty = false;
-}
-
-// ### Maybe getGraphParts could return the variables when traversing, at least
-// for trunk...
-QList<AnchorData *> getVariables(QList<QSimplexConstraint *> constraints)
-{
- QSet<AnchorData *> variableSet;
- for (int i = 0; i < constraints.count(); ++i) {
- const QSimplexConstraint *c = constraints.at(i);
- foreach (QSimplexVariable *var, c->variables.keys()) {
- variableSet += static_cast<AnchorData *>(var);
- }
- }
- return variableSet.toList();
-}
-
-/*!
- \internal
-
- Calculate graphs is the method that puts together all the helper routines
- so that the AnchorLayout can calculate the sizes of each item.
-
- In a nutshell it should do:
-
- 1) Refresh anchor nominal sizes, that is, the size that each anchor would
- have if no other restrictions applied. This is done by quering the
- layout style and the sizeHints of the items belonging to the layout.
-
- 2) Simplify the graph by grouping together parallel and sequential anchors
- into "group anchors". These have equivalent minimum, preferred and maximum
- sizeHints as the anchors they replace.
-
- 3) Check if we got to a trivial case. In some cases, the whole graph can be
- simplified into a single anchor. If so, use this information. If not,
- then call the Simplex solver to calculate the anchors sizes.
-
- 4) Once the root anchors had its sizes calculated, propagate that to the
- anchors they represent.
-*/
-void QGraphicsAnchorLayoutPrivate::calculateGraphs(
- QGraphicsAnchorLayoutPrivate::Orientation orientation)
-{
-#if defined(QT_DEBUG) || defined(Q_AUTOTEST_EXPORT)
- lastCalculationUsedSimplex[orientation] = false;
-#endif
-
- static bool simplificationEnabled = qgetenv("QT_ANCHORLAYOUT_NO_SIMPLIFICATION").isEmpty();
-
- // Reset the nominal sizes of each anchor based on the current item sizes
- refreshAllSizeHints(orientation);
-
- // Simplify the graph
- if (simplificationEnabled && !simplifyGraph(orientation)) {
- qWarning("QGraphicsAnchorLayout: anchor setup is not feasible.");
- graphHasConflicts[orientation] = true;
- return;
- }
-
- // Traverse all graph edges and store the possible paths to each vertex
- findPaths(orientation);
-
- // From the paths calculated above, extract the constraints that the current
- // anchor setup impose, to our Linear Programming problem.
- constraintsFromPaths(orientation);
-
- // Split the constraints and anchors into groups that should be fed to the
- // simplex solver independently. Currently we find two groups:
- //
- // 1) The "trunk", that is, the set of anchors (items) that are connected
- // to the two opposite sides of our layout, and thus need to stretch in
- // order to fit in the current layout size.
- //
- // 2) The floating or semi-floating anchors (items) that are those which
- // are connected to only one (or none) of the layout sides, thus are not
- // influenced by the layout size.
- QList<QList<QSimplexConstraint *> > parts = getGraphParts(orientation);
-
- // Now run the simplex solver to calculate Minimum, Preferred and Maximum sizes
- // of the "trunk" set of constraints and variables.
- // ### does trunk always exist? empty = trunk is the layout left->center->right
- QList<QSimplexConstraint *> trunkConstraints = parts.at(0);
- QList<AnchorData *> trunkVariables = getVariables(trunkConstraints);
-
- // For minimum and maximum, use the path between the two layout sides as the
- // objective function.
- AnchorVertex *v = layoutLastVertex[orientation];
- GraphPath trunkPath = graphPaths[orientation].value(v);
-
- bool feasible = calculateTrunk(orientation, trunkPath, trunkConstraints, trunkVariables);
-
- // For the other parts that not the trunk, solve only for the preferred size
- // that is the size they will remain at, since they are not stretched by the
- // layout.
-
- // Skipping the first (trunk)
- for (int i = 1; i < parts.count(); ++i) {
- if (!feasible)
- break;
-
- QList<QSimplexConstraint *> partConstraints = parts.at(i);
- QList<AnchorData *> partVariables = getVariables(partConstraints);
- Q_ASSERT(!partVariables.isEmpty());
- feasible &= calculateNonTrunk(partConstraints, partVariables);
- }
-
- // Propagate the new sizes down the simplified graph, ie. tell the
- // group anchors to set their children anchors sizes.
- updateAnchorSizes(orientation);
-
- graphHasConflicts[orientation] = !feasible;
-
- // Clean up our data structures. They are not needed anymore since
- // distribution uses just interpolation.
- qDeleteAll(constraints[orientation]);
- constraints[orientation].clear();
- graphPaths[orientation].clear(); // ###
-
- if (simplificationEnabled)
- restoreSimplifiedGraph(orientation);
-}
-
-/*!
- \internal
-
- Shift all the constraints by a certain amount. This allows us to deal with negative values in
- the linear program if they are bounded by a certain limit. Functions should be careful to
- call it again with a negative amount, to shift the constraints back.
-*/
-static void shiftConstraints(const QList<QSimplexConstraint *> &constraints, qreal amount)
-{
- for (int i = 0; i < constraints.count(); ++i) {
- QSimplexConstraint *c = constraints.at(i);
- qreal multiplier = 0;
- foreach (qreal v, c->variables.values()) {
- multiplier += v;
- }
- c->constant += multiplier * amount;
- }
-}
-
-/*!
- \internal
-
- Calculate the sizes for all anchors which are part of the trunk. This works
- on top of a (possibly) simplified graph.
-*/
-bool QGraphicsAnchorLayoutPrivate::calculateTrunk(Orientation orientation, const GraphPath &path,
- const QList<QSimplexConstraint *> &constraints,
- const QList<AnchorData *> &variables)
-{
- bool feasible = true;
- bool needsSimplex = !constraints.isEmpty();
-
-#if 0
- qDebug("Simplex %s for trunk of %s", needsSimplex ? "used" : "NOT used",
- orientation == Horizontal ? "Horizontal" : "Vertical");
-#endif
-
- if (needsSimplex) {
-
- QList<QSimplexConstraint *> sizeHintConstraints = constraintsFromSizeHints(variables);
- QList<QSimplexConstraint *> allConstraints = constraints + sizeHintConstraints;
-
- shiftConstraints(allConstraints, g_offset);
-
- // Solve min and max size hints
- qreal min, max;
- feasible = solveMinMax(allConstraints, path, &min, &max);
-
- if (feasible) {
- solvePreferred(constraints, variables);
-
- // Calculate and set the preferred size for the layout,
- // from the edge sizes that were calculated above.
- qreal pref(0.0);
- foreach (const AnchorData *ad, path.positives) {
- pref += ad->sizeAtPreferred;
- }
- foreach (const AnchorData *ad, path.negatives) {
- pref -= ad->sizeAtPreferred;
- }
-
- sizeHints[orientation][Qt::MinimumSize] = min;
- sizeHints[orientation][Qt::PreferredSize] = pref;
- sizeHints[orientation][Qt::MaximumSize] = max;
- }
-
- qDeleteAll(sizeHintConstraints);
- shiftConstraints(constraints, -g_offset);
-
- } else {
- // No Simplex is necessary because the path was simplified all the way to a single
- // anchor.
- Q_ASSERT(path.positives.count() == 1);
- Q_ASSERT(path.negatives.count() == 0);
-
- AnchorData *ad = path.positives.toList()[0];
- ad->sizeAtMinimum = ad->minSize;
- ad->sizeAtPreferred = ad->prefSize;
- ad->sizeAtMaximum = ad->maxSize;
-
- sizeHints[orientation][Qt::MinimumSize] = ad->sizeAtMinimum;
- sizeHints[orientation][Qt::PreferredSize] = ad->sizeAtPreferred;
- sizeHints[orientation][Qt::MaximumSize] = ad->sizeAtMaximum;
- }
-
-#if defined(QT_DEBUG) || defined(Q_AUTOTEST_EXPORT)
- lastCalculationUsedSimplex[orientation] = needsSimplex;
-#endif
-
- return feasible;
-}
-
-/*!
- \internal
-*/
-bool QGraphicsAnchorLayoutPrivate::calculateNonTrunk(const QList<QSimplexConstraint *> &constraints,
- const QList<AnchorData *> &variables)
-{
- shiftConstraints(constraints, g_offset);
- bool feasible = solvePreferred(constraints, variables);
-
- if (feasible) {
- // Propagate size at preferred to other sizes. Semi-floats always will be
- // in their sizeAtPreferred.
- for (int j = 0; j < variables.count(); ++j) {
- AnchorData *ad = variables.at(j);
- Q_ASSERT(ad);
- ad->sizeAtMinimum = ad->sizeAtPreferred;
- ad->sizeAtMaximum = ad->sizeAtPreferred;
- }
- }
-
- shiftConstraints(constraints, -g_offset);
- return feasible;
-}
-
-/*!
- \internal
-
- Traverse the graph refreshing the size hints. Edges will query their associated
- item or graphicsAnchor for their size hints.
-*/
-void QGraphicsAnchorLayoutPrivate::refreshAllSizeHints(Orientation orientation)
-{
- Graph<AnchorVertex, AnchorData> &g = graph[orientation];
- QList<QPair<AnchorVertex *, AnchorVertex *> > vertices = g.connections();
-
- QLayoutStyleInfo styleInf = styleInfo();
- for (int i = 0; i < vertices.count(); ++i) {
- AnchorData *data = g.edgeData(vertices.at(i).first, vertices.at(i).second);
- data->refreshSizeHints(&styleInf);
- }
-}
-
-/*!
- \internal
-
- This method walks the graph using a breadth-first search to find paths
- between the root vertex and each vertex on the graph. The edges
- directions in each path are considered and they are stored as a
- positive edge (left-to-right) or negative edge (right-to-left).
-
- The list of paths is used later to generate a list of constraints.
- */
-void QGraphicsAnchorLayoutPrivate::findPaths(Orientation orientation)
-{
- QQueue<QPair<AnchorVertex *, AnchorVertex *> > queue;
-
- QSet<AnchorData *> visited;
-
- AnchorVertex *root = layoutFirstVertex[orientation];
-
- graphPaths[orientation].insert(root, GraphPath());
-
- foreach (AnchorVertex *v, graph[orientation].adjacentVertices(root)) {
- queue.enqueue(qMakePair(root, v));
- }
-
- while(!queue.isEmpty()) {
- QPair<AnchorVertex *, AnchorVertex *> pair = queue.dequeue();
- AnchorData *edge = graph[orientation].edgeData(pair.first, pair.second);
-
- if (visited.contains(edge))
- continue;
-
- visited.insert(edge);
- GraphPath current = graphPaths[orientation].value(pair.first);
-
- if (edge->from == pair.first)
- current.positives.insert(edge);
- else
- current.negatives.insert(edge);
-
- graphPaths[orientation].insert(pair.second, current);
-
- foreach (AnchorVertex *v,
- graph[orientation].adjacentVertices(pair.second)) {
- queue.enqueue(qMakePair(pair.second, v));
- }
- }
-
- // We will walk through every reachable items (non-float) store them in a temporary set.
- // We them create a set of all items and subtract the non-floating items from the set in
- // order to get the floating items. The floating items is then stored in m_floatItems
- identifyFloatItems(visited, orientation);
-}
-
-/*!
- \internal
-
- Each vertex on the graph that has more than one path to it
- represents a contra int to the sizes of the items in these paths.
-
- This method walks the list of paths to each vertex, generate
- the constraints and store them in a list so they can be used later
- by the Simplex solver.
-*/
-void QGraphicsAnchorLayoutPrivate::constraintsFromPaths(Orientation orientation)
-{
- foreach (AnchorVertex *vertex, graphPaths[orientation].uniqueKeys())
- {
- int valueCount = graphPaths[orientation].count(vertex);
- if (valueCount == 1)
- continue;
-
- QList<GraphPath> pathsToVertex = graphPaths[orientation].values(vertex);
- for (int i = 1; i < valueCount; ++i) {
- constraints[orientation] += \
- pathsToVertex[0].constraint(pathsToVertex.at(i));
- }
- }
-}
-
-/*!
- \internal
-*/
-void QGraphicsAnchorLayoutPrivate::updateAnchorSizes(Orientation orientation)
-{
- Graph<AnchorVertex, AnchorData> &g = graph[orientation];
- const QList<QPair<AnchorVertex *, AnchorVertex *> > &vertices = g.connections();
-
- for (int i = 0; i < vertices.count(); ++i) {
- AnchorData *ad = g.edgeData(vertices.at(i).first, vertices.at(i).second);
- ad->updateChildrenSizes();
- }
-}
-
-/*!
- \internal
-
- Create LP constraints for each anchor based on its minimum and maximum
- sizes, as specified in its size hints
-*/
-QList<QSimplexConstraint *> QGraphicsAnchorLayoutPrivate::constraintsFromSizeHints(
- const QList<AnchorData *> &anchors)
-{
- if (anchors.isEmpty())
- return QList<QSimplexConstraint *>();
-
- // Look for the layout edge. That can be either the first half in case the
- // layout is split in two, or the whole layout anchor.
- Orientation orient = Orientation(anchors.first()->orientation);
- AnchorData *layoutEdge = 0;
- if (layoutCentralVertex[orient]) {
- layoutEdge = graph[orient].edgeData(layoutFirstVertex[orient], layoutCentralVertex[orient]);
- } else {
- layoutEdge = graph[orient].edgeData(layoutFirstVertex[orient], layoutLastVertex[orient]);
- }
-
- // If maxSize is less then "infinite", that means there are other anchors
- // grouped together with this one. We can't ignore its maximum value so we
- // set back the variable to NULL to prevent the continue condition from being
- // satisfied in the loop below.
- const qreal expectedMax = layoutCentralVertex[orient] ? QWIDGETSIZE_MAX / 2 : QWIDGETSIZE_MAX;
- qreal actualMax;
- if (layoutEdge->from == layoutFirstVertex[orient]) {
- actualMax = layoutEdge->maxSize;
- } else {
- actualMax = -layoutEdge->minSize;
- }
- if (actualMax != expectedMax) {
- layoutEdge = 0;
- }
-
- // For each variable, create constraints based on size hints
- QList<QSimplexConstraint *> anchorConstraints;
- bool unboundedProblem = true;
- for (int i = 0; i < anchors.size(); ++i) {
- AnchorData *ad = anchors.at(i);
-
- // Anchors that have their size directly linked to another one don't need constraints
- // For exammple, the second half of an item has exactly the same size as the first half
- // thus constraining the latter is enough.
- if (ad->dependency == AnchorData::Slave)
- continue;
-
- // To use negative variables inside simplex, we shift them so the minimum negative value is
- // mapped to zero before solving. To make sure that it works, we need to guarantee that the
- // variables are all inside a certain boundary.
- qreal boundedMin = qBound(-g_offset, ad->minSize, g_offset);
- qreal boundedMax = qBound(-g_offset, ad->maxSize, g_offset);
-
- if ((boundedMin == boundedMax) || qFuzzyCompare(boundedMin, boundedMax)) {
- QSimplexConstraint *c = new QSimplexConstraint;
- c->variables.insert(ad, 1.0);
- c->constant = boundedMin;
- c->ratio = QSimplexConstraint::Equal;
- anchorConstraints += c;
- unboundedProblem = false;
- } else {
- QSimplexConstraint *c = new QSimplexConstraint;
- c->variables.insert(ad, 1.0);
- c->constant = boundedMin;
- c->ratio = QSimplexConstraint::MoreOrEqual;
- anchorConstraints += c;
-
- // We avoid adding restrictions to the layout internal anchors. That's
- // to prevent unnecessary fair distribution from happening due to this
- // artificial restriction.
- if (ad == layoutEdge)
- continue;
-
- c = new QSimplexConstraint;
- c->variables.insert(ad, 1.0);
- c->constant = boundedMax;
- c->ratio = QSimplexConstraint::LessOrEqual;
- anchorConstraints += c;
- unboundedProblem = false;
- }
- }
-
- // If no upper boundary restriction was added, add one to avoid unbounded problem
- if (unboundedProblem) {
- QSimplexConstraint *c = new QSimplexConstraint;
- c->variables.insert(layoutEdge, 1.0);
- // The maximum size that the layout can take
- c->constant = g_offset;
- c->ratio = QSimplexConstraint::LessOrEqual;
- anchorConstraints += c;
- }
-
- return anchorConstraints;
-}
-
-/*!
- \internal
-*/
-QList< QList<QSimplexConstraint *> >
-QGraphicsAnchorLayoutPrivate::getGraphParts(Orientation orientation)
-{
- Q_ASSERT(layoutFirstVertex[orientation] && layoutLastVertex[orientation]);
-
- AnchorData *edgeL1 = 0;
- AnchorData *edgeL2 = 0;
-
- // The layout may have a single anchor between Left and Right or two half anchors
- // passing through the center
- if (layoutCentralVertex[orientation]) {
- edgeL1 = graph[orientation].edgeData(layoutFirstVertex[orientation], layoutCentralVertex[orientation]);
- edgeL2 = graph[orientation].edgeData(layoutCentralVertex[orientation], layoutLastVertex[orientation]);
- } else {
- edgeL1 = graph[orientation].edgeData(layoutFirstVertex[orientation], layoutLastVertex[orientation]);
- }
-
- QLinkedList<QSimplexConstraint *> remainingConstraints;
- for (int i = 0; i < constraints[orientation].count(); ++i) {
- remainingConstraints += constraints[orientation].at(i);
- }
- for (int i = 0; i < itemCenterConstraints[orientation].count(); ++i) {
- remainingConstraints += itemCenterConstraints[orientation].at(i);
- }
-
- QList<QSimplexConstraint *> trunkConstraints;
- QSet<QSimplexVariable *> trunkVariables;
-
- trunkVariables += edgeL1;
- if (edgeL2)
- trunkVariables += edgeL2;
-
- bool dirty;
- do {
- dirty = false;
-
- QLinkedList<QSimplexConstraint *>::iterator it = remainingConstraints.begin();
- while (it != remainingConstraints.end()) {
- QSimplexConstraint *c = *it;
- bool match = false;
-
- // Check if this constraint have some overlap with current
- // trunk variables...
- foreach (QSimplexVariable *ad, trunkVariables) {
- if (c->variables.contains(ad)) {
- match = true;
- break;
- }
- }
-
- // If so, we add it to trunk, and erase it from the
- // remaining constraints.
- if (match) {
- trunkConstraints += c;
- trunkVariables += QSet<QSimplexVariable *>::fromList(c->variables.keys());
- it = remainingConstraints.erase(it);
- dirty = true;
- } else {
- // Note that we don't erase the constraint if it's not
- // a match, since in a next iteration of a do-while we
- // can pass on it again and it will be a match.
- //
- // For example: if trunk share a variable with
- // remainingConstraints[1] and it shares with
- // remainingConstraints[0], we need a second iteration
- // of the do-while loop to match both.
- ++it;
- }
- }
- } while (dirty);
-
- QList< QList<QSimplexConstraint *> > result;
- result += trunkConstraints;
-
- if (!remainingConstraints.isEmpty()) {
- QList<QSimplexConstraint *> nonTrunkConstraints;
- QLinkedList<QSimplexConstraint *>::iterator it = remainingConstraints.begin();
- while (it != remainingConstraints.end()) {
- nonTrunkConstraints += *it;
- ++it;
- }
- result += nonTrunkConstraints;
- }
-
- return result;
-}
-
-/*!
- \internal
-
- Use all visited Anchors on findPaths() so we can identify non-float Items.
-*/
-void QGraphicsAnchorLayoutPrivate::identifyFloatItems(const QSet<AnchorData *> &visited, Orientation orientation)
-{
- QSet<QGraphicsLayoutItem *> nonFloating;
-
- foreach (const AnchorData *ad, visited)
- identifyNonFloatItems_helper(ad, &nonFloating);
-
- QSet<QGraphicsLayoutItem *> allItems;
- foreach (QGraphicsLayoutItem *item, items)
- allItems.insert(item);
- m_floatItems[orientation] = allItems - nonFloating;
-}
-
-
-/*!
- \internal
-
- Given an anchor, if it is an internal anchor and Normal we must mark it's item as non-float.
- If the anchor is Sequential or Parallel, we must iterate on its children recursively until we reach
- internal anchors (items).
-*/
-void QGraphicsAnchorLayoutPrivate::identifyNonFloatItems_helper(const AnchorData *ad, QSet<QGraphicsLayoutItem *> *nonFloatingItemsIdentifiedSoFar)
-{
- Q_Q(QGraphicsAnchorLayout);
-
- switch(ad->type) {
- case AnchorData::Normal:
- if (ad->item && ad->item != q)
- nonFloatingItemsIdentifiedSoFar->insert(ad->item);
- break;
- case AnchorData::Sequential:
- foreach (const AnchorData *d, static_cast<const SequentialAnchorData *>(ad)->m_edges)
- identifyNonFloatItems_helper(d, nonFloatingItemsIdentifiedSoFar);
- break;
- case AnchorData::Parallel:
- identifyNonFloatItems_helper(static_cast<const ParallelAnchorData *>(ad)->firstEdge, nonFloatingItemsIdentifiedSoFar);
- identifyNonFloatItems_helper(static_cast<const ParallelAnchorData *>(ad)->secondEdge, nonFloatingItemsIdentifiedSoFar);
- break;
- }
-}
-
-/*!
- \internal
-
- Use the current vertices distance to calculate and set the geometry of
- each item.
-*/
-void QGraphicsAnchorLayoutPrivate::setItemsGeometries(const QRectF &geom)
-{
- Q_Q(QGraphicsAnchorLayout);
- AnchorVertex *firstH, *secondH, *firstV, *secondV;
-
- qreal top;
- qreal left;
- qreal right;
-
- q->getContentsMargins(&left, &top, &right, 0);
- const Qt::LayoutDirection visualDir = visualDirection();
- if (visualDir == Qt::RightToLeft)
- qSwap(left, right);
-
- left += geom.left();
- top += geom.top();
- right = geom.right() - right;
-
- foreach (QGraphicsLayoutItem *item, items) {
- QRectF newGeom;
- QSizeF itemPreferredSize = item->effectiveSizeHint(Qt::PreferredSize);
- if (m_floatItems[Horizontal].contains(item)) {
- newGeom.setLeft(0);
- newGeom.setRight(itemPreferredSize.width());
- } else {
- firstH = internalVertex(item, Qt::AnchorLeft);
- secondH = internalVertex(item, Qt::AnchorRight);
-
- if (visualDir == Qt::LeftToRight) {
- newGeom.setLeft(left + firstH->distance);
- newGeom.setRight(left + secondH->distance);
- } else {
- newGeom.setLeft(right - secondH->distance);
- newGeom.setRight(right - firstH->distance);
- }
- }
-
- if (m_floatItems[Vertical].contains(item)) {
- newGeom.setTop(0);
- newGeom.setBottom(itemPreferredSize.height());
- } else {
- firstV = internalVertex(item, Qt::AnchorTop);
- secondV = internalVertex(item, Qt::AnchorBottom);
-
- newGeom.setTop(top + firstV->distance);
- newGeom.setBottom(top + secondV->distance);
- }
-
- item->setGeometry(newGeom);
- }
-}
-
-/*!
- \internal
-
- Calculate the position of each vertex based on the paths to each of
- them as well as the current edges sizes.
-*/
-void QGraphicsAnchorLayoutPrivate::calculateVertexPositions(
- QGraphicsAnchorLayoutPrivate::Orientation orientation)
-{
- QQueue<QPair<AnchorVertex *, AnchorVertex *> > queue;
- QSet<AnchorVertex *> visited;
-
- // Get root vertex
- AnchorVertex *root = layoutFirstVertex[orientation];
-
- root->distance = 0;
- visited.insert(root);
-
- // Add initial edges to the queue
- foreach (AnchorVertex *v, graph[orientation].adjacentVertices(root)) {
- queue.enqueue(qMakePair(root, v));
- }
-
- // Do initial calculation required by "interpolateEdge()"
- setupEdgesInterpolation(orientation);
-
- // Traverse the graph and calculate vertex positions
- while (!queue.isEmpty()) {
- QPair<AnchorVertex *, AnchorVertex *> pair = queue.dequeue();
- AnchorData *edge = graph[orientation].edgeData(pair.first, pair.second);
-
- if (visited.contains(pair.second))
- continue;
-
- visited.insert(pair.second);
- interpolateEdge(pair.first, edge);
-
- QList<AnchorVertex *> adjacents = graph[orientation].adjacentVertices(pair.second);
- for (int i = 0; i < adjacents.count(); ++i) {
- if (!visited.contains(adjacents.at(i)))
- queue.enqueue(qMakePair(pair.second, adjacents.at(i)));
- }
- }
-}
-
-/*!
- \internal
-
- Calculate interpolation parameters based on current Layout Size.
- Must be called once before calling "interpolateEdgeSize()" for
- the edges.
-*/
-void QGraphicsAnchorLayoutPrivate::setupEdgesInterpolation(
- Orientation orientation)
-{
- Q_Q(QGraphicsAnchorLayout);
-
- qreal current;
- current = (orientation == Horizontal) ? q->contentsRect().width() : q->contentsRect().height();
-
- QPair<Interval, qreal> result;
- result = getFactor(current,
- sizeHints[orientation][Qt::MinimumSize],
- sizeHints[orientation][Qt::PreferredSize],
- sizeHints[orientation][Qt::PreferredSize],
- sizeHints[orientation][Qt::PreferredSize],
- sizeHints[orientation][Qt::MaximumSize]);
-
- interpolationInterval[orientation] = result.first;
- interpolationProgress[orientation] = result.second;
-}
-
-/*!
- \internal
-
- Calculate the current Edge size based on the current Layout size and the
- size the edge is supposed to have when the layout is at its:
-
- - minimum size,
- - preferred size,
- - maximum size.
-
- These three key values are calculated in advance using linear
- programming (more expensive) or the simplification algorithm, then
- subsequential resizes of the parent layout require a simple
- interpolation.
-*/
-void QGraphicsAnchorLayoutPrivate::interpolateEdge(AnchorVertex *base, AnchorData *edge)
-{
- const Orientation orientation = Orientation(edge->orientation);
- const QPair<Interval, qreal> factor(interpolationInterval[orientation],
- interpolationProgress[orientation]);
-
- qreal edgeDistance = interpolate(factor, edge->sizeAtMinimum, edge->sizeAtPreferred,
- edge->sizeAtPreferred, edge->sizeAtPreferred,
- edge->sizeAtMaximum);
-
- Q_ASSERT(edge->from == base || edge->to == base);
-
- // Calculate the distance for the vertex opposite to the base
- if (edge->from == base) {
- edge->to->distance = base->distance + edgeDistance;
- } else {
- edge->from->distance = base->distance - edgeDistance;
- }
-}
-
-bool QGraphicsAnchorLayoutPrivate::solveMinMax(const QList<QSimplexConstraint *> &constraints,
- GraphPath path, qreal *min, qreal *max)
-{
- QSimplex simplex;
- bool feasible = simplex.setConstraints(constraints);
- if (feasible) {
- // Obtain the objective constraint
- QSimplexConstraint objective;
- QSet<AnchorData *>::const_iterator iter;
- for (iter = path.positives.constBegin(); iter != path.positives.constEnd(); ++iter)
- objective.variables.insert(*iter, 1.0);
-
- for (iter = path.negatives.constBegin(); iter != path.negatives.constEnd(); ++iter)
- objective.variables.insert(*iter, -1.0);
-
- const qreal objectiveOffset = (path.positives.count() - path.negatives.count()) * g_offset;
- simplex.setObjective(&objective);
-
- // Calculate minimum values
- *min = simplex.solveMin() - objectiveOffset;
-
- // Save sizeAtMinimum results
- QList<AnchorData *> variables = getVariables(constraints);
- for (int i = 0; i < variables.size(); ++i) {
- AnchorData *ad = static_cast<AnchorData *>(variables.at(i));
- ad->sizeAtMinimum = ad->result - g_offset;
- }
-
- // Calculate maximum values
- *max = simplex.solveMax() - objectiveOffset;
-
- // Save sizeAtMaximum results
- for (int i = 0; i < variables.size(); ++i) {
- AnchorData *ad = static_cast<AnchorData *>(variables.at(i));
- ad->sizeAtMaximum = ad->result - g_offset;
- }
- }
- return feasible;
-}
-
-enum slackType { Grower = -1, Shrinker = 1 };
-static QPair<QSimplexVariable *, QSimplexConstraint *> createSlack(QSimplexConstraint *sizeConstraint,
- qreal interval, slackType type)
-{
- QSimplexVariable *slack = new QSimplexVariable;
- sizeConstraint->variables.insert(slack, type);
-
- QSimplexConstraint *limit = new QSimplexConstraint;
- limit->variables.insert(slack, 1.0);
- limit->ratio = QSimplexConstraint::LessOrEqual;
- limit->constant = interval;
-
- return qMakePair(slack, limit);
-}
-
-bool QGraphicsAnchorLayoutPrivate::solvePreferred(const QList<QSimplexConstraint *> &constraints,
- const QList<AnchorData *> &variables)
-{
- QList<QSimplexConstraint *> preferredConstraints;
- QList<QSimplexVariable *> preferredVariables;
- QSimplexConstraint objective;
-
- // Fill the objective coefficients for this variable. In the
- // end the objective function will be
- //
- // z = n * (A_shrinker_hard + A_grower_hard + B_shrinker_hard + B_grower_hard + ...) +
- // (A_shrinker_soft + A_grower_soft + B_shrinker_soft + B_grower_soft + ...)
- //
- // where n is the number of variables that have
- // slacks. Note that here we use the number of variables
- // as coefficient, this is to mark the "shrinker slack
- // variable" less likely to get value than the "grower
- // slack variable".
-
- // This will fill the values for the structural constraints
- // and we now fill the values for the slack constraints (one per variable),
- // which have this form (the constant A_pref was set when creating the slacks):
- //
- // A + A_shrinker_hard + A_shrinker_soft - A_grower_hard - A_grower_soft = A_pref
- //
- for (int i = 0; i < variables.size(); ++i) {
- AnchorData *ad = variables.at(i);
-
- // The layout original structure anchors are not relevant in preferred size calculation
- if (ad->isLayoutAnchor)
- continue;
-
- // By default, all variables are equal to their preferred size. If they have room to
- // grow or shrink, such flexibility will be added by the additional variables below.
- QSimplexConstraint *sizeConstraint = new QSimplexConstraint;
- preferredConstraints += sizeConstraint;
- sizeConstraint->variables.insert(ad, 1.0);
- sizeConstraint->constant = ad->prefSize + g_offset;
-
- // Can easily shrink
- QPair<QSimplexVariable *, QSimplexConstraint *> slack;
- const qreal softShrinkInterval = ad->prefSize - ad->minPrefSize;
- if (softShrinkInterval) {
- slack = createSlack(sizeConstraint, softShrinkInterval, Shrinker);
- preferredVariables += slack.first;
- preferredConstraints += slack.second;
-
- // Add to objective with ratio == 1 (soft)
- objective.variables.insert(slack.first, 1.0);
- }
-
- // Can easily grow
- const qreal softGrowInterval = ad->maxPrefSize - ad->prefSize;
- if (softGrowInterval) {
- slack = createSlack(sizeConstraint, softGrowInterval, Grower);
- preferredVariables += slack.first;
- preferredConstraints += slack.second;
-
- // Add to objective with ratio == 1 (soft)
- objective.variables.insert(slack.first, 1.0);
- }
-
- // Can shrink if really necessary
- const qreal hardShrinkInterval = ad->minPrefSize - ad->minSize;
- if (hardShrinkInterval) {
- slack = createSlack(sizeConstraint, hardShrinkInterval, Shrinker);
- preferredVariables += slack.first;
- preferredConstraints += slack.second;
-
- // Add to objective with ratio == N (hard)
- objective.variables.insert(slack.first, variables.size());
- }
-
- // Can grow if really necessary
- const qreal hardGrowInterval = ad->maxSize - ad->maxPrefSize;
- if (hardGrowInterval) {
- slack = createSlack(sizeConstraint, hardGrowInterval, Grower);
- preferredVariables += slack.first;
- preferredConstraints += slack.second;
-
- // Add to objective with ratio == N (hard)
- objective.variables.insert(slack.first, variables.size());
- }
- }
-
- QSimplex *simplex = new QSimplex;
- bool feasible = simplex->setConstraints(constraints + preferredConstraints);
- if (feasible) {
- simplex->setObjective(&objective);
-
- // Calculate minimum values
- simplex->solveMin();
-
- // Save sizeAtPreferred results
- for (int i = 0; i < variables.size(); ++i) {
- AnchorData *ad = variables.at(i);
- ad->sizeAtPreferred = ad->result - g_offset;
- }
-
- // Make sure we delete the simplex solver -before- we delete the
- // constraints used by it.
- delete simplex;
- }
- // Delete constraints and variables we created.
- qDeleteAll(preferredConstraints);
- qDeleteAll(preferredVariables);
-
- return feasible;
-}
-
-/*!
- \internal
- Returns true if there are no arrangement that satisfies all constraints.
- Otherwise returns false.
-
- \sa addAnchor()
-*/
-bool QGraphicsAnchorLayoutPrivate::hasConflicts() const
-{
- QGraphicsAnchorLayoutPrivate *that = const_cast<QGraphicsAnchorLayoutPrivate*>(this);
- that->calculateGraphs();
-
- bool floatConflict = !m_floatItems[0].isEmpty() || !m_floatItems[1].isEmpty();
-
- return graphHasConflicts[0] || graphHasConflicts[1] || floatConflict;
-}
-
-#ifdef QT_DEBUG
-void QGraphicsAnchorLayoutPrivate::dumpGraph(const QString &name)
-{
- QFile file(QString::fromAscii("anchorlayout.%1.dot").arg(name));
- if (!file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate))
- qWarning("Could not write to %s", file.fileName().toLocal8Bit().constData());
-
- QString str = QString::fromAscii("digraph anchorlayout {\nnode [shape=\"rect\"]\n%1}");
- QString dotContents = graph[0].serializeToDot();
- dotContents += graph[1].serializeToDot();
- file.write(str.arg(dotContents).toLocal8Bit());
-
- file.close();
-}
-#endif
-
-QT_END_NAMESPACE
-#endif //QT_NO_GRAPHICSVIEW
diff --git a/src/gui/graphicsview/qgraphicsgridlayout.h b/src/gui/graphicsview/qgraphicsgridlayout.h
deleted file mode 100644
index 771c8a074c..0000000000
--- a/src/gui/graphicsview/qgraphicsgridlayout.h
+++ /dev/null
@@ -1,144 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGRAPHICSGRIDLAYOUT_H
-#define QGRAPHICSGRIDLAYOUT_H
-
-#include <QtGui/qgraphicsitem.h>
-#include <QtGui/qgraphicslayout.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW
-
-class QGraphicsGridLayoutPrivate;
-
-class Q_GUI_EXPORT QGraphicsGridLayout : public QGraphicsLayout
-{
-public:
- QGraphicsGridLayout(QGraphicsLayoutItem *parent = 0);
- virtual ~QGraphicsGridLayout();
-
- void addItem(QGraphicsLayoutItem *item, int row, int column, int rowSpan, int columnSpan,
- Qt::Alignment alignment = 0);
- inline void addItem(QGraphicsLayoutItem *item, int row, int column, Qt::Alignment alignment = 0);
-
- void setHorizontalSpacing(qreal spacing);
- qreal horizontalSpacing() const;
- void setVerticalSpacing(qreal spacing);
- qreal verticalSpacing() const;
- void setSpacing(qreal spacing);
-
- void setRowSpacing(int row, qreal spacing);
- qreal rowSpacing(int row) const;
- void setColumnSpacing(int column, qreal spacing);
- qreal columnSpacing(int column) const;
-
- void setRowStretchFactor(int row, int stretch);
- int rowStretchFactor(int row) const;
- void setColumnStretchFactor(int column, int stretch);
- int columnStretchFactor(int column) const;
-
- void setRowMinimumHeight(int row, qreal height);
- qreal rowMinimumHeight(int row) const;
- void setRowPreferredHeight(int row, qreal height);
- qreal rowPreferredHeight(int row) const;
- void setRowMaximumHeight(int row, qreal height);
- qreal rowMaximumHeight(int row) const;
- void setRowFixedHeight(int row, qreal height);
-
- void setColumnMinimumWidth(int column, qreal width);
- qreal columnMinimumWidth(int column) const;
- void setColumnPreferredWidth(int column, qreal width);
- qreal columnPreferredWidth(int column) const;
- void setColumnMaximumWidth(int column, qreal width);
- qreal columnMaximumWidth(int column) const;
- void setColumnFixedWidth(int column, qreal width);
-
- void setRowAlignment(int row, Qt::Alignment alignment);
- Qt::Alignment rowAlignment(int row) const;
- void setColumnAlignment(int column, Qt::Alignment alignment);
- Qt::Alignment columnAlignment(int column) const;
-
- void setAlignment(QGraphicsLayoutItem *item, Qt::Alignment alignment);
- Qt::Alignment alignment(QGraphicsLayoutItem *item) const;
-
- int rowCount() const;
- int columnCount() const;
-
- QGraphicsLayoutItem *itemAt(int row, int column) const;
-
- // inherited from QGraphicsLayout
- int count() const;
- QGraphicsLayoutItem *itemAt(int index) const;
- void removeAt(int index);
- void removeItem(QGraphicsLayoutItem *item);
-
- void invalidate();
-
- // inherited from QGraphicsLayoutItem
- void setGeometry(const QRectF &rect);
- QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const;
-
- // ####
- //QRect cellRect(int row, int column, int rowSpan = 1, int columnSpan = 1) const;
- //QSizePolicy::ControlTypes controlTypes(LayoutSide side) const;
-
-private:
- Q_DISABLE_COPY(QGraphicsGridLayout)
- Q_DECLARE_PRIVATE(QGraphicsGridLayout)
-};
-
-inline void QGraphicsGridLayout::addItem(QGraphicsLayoutItem *aitem, int arow, int acolumn, Qt::Alignment aalignment)
-{ addItem(aitem, arow, acolumn, 1, 1, aalignment); }
-
-#endif
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif
-
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
deleted file mode 100644
index 0c218fc9f4..0000000000
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ /dev/null
@@ -1,11603 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*!
- \class QGraphicsItem
- \brief The QGraphicsItem class is the base class for all graphical
- items in a QGraphicsScene.
- \since 4.2
-
- \ingroup graphicsview-api
-
- It provides a light-weight foundation for writing your own custom items.
- This includes defining the item's geometry, collision detection, its
- painting implementation and item interaction through its event handlers.
- QGraphicsItem is part of the \l{Graphics View Framework}
-
- \image graphicsview-items.png
-
- For convenience, Qt provides a set of standard graphics items for the most
- common shapes. These are:
-
- \list
- \o QGraphicsEllipseItem provides an ellipse item
- \o QGraphicsLineItem provides a line item
- \o QGraphicsPathItem provides an arbitrary path item
- \o QGraphicsPixmapItem provides a pixmap item
- \o QGraphicsPolygonItem provides a polygon item
- \o QGraphicsRectItem provides a rectangular item
- \o QGraphicsSimpleTextItem provides a simple text label item
- \o QGraphicsTextItem provides an advanced text browser item
- \endlist
-
- All of an item's geometric information is based on its local coordinate
- system. The item's position, pos(), is the only function that does not
- operate in local coordinates, as it returns a position in parent
- coordinates. \l {The Graphics View Coordinate System} describes the coordinate
- system in detail.
-
- You can set whether an item should be visible (i.e., drawn, and accepting
- events), by calling setVisible(). Hiding an item will also hide its
- children. Similarly, you can enable or disable an item by calling
- setEnabled(). If you disable an item, all its children will also be
- disabled. By default, items are both visible and enabled. To toggle
- whether an item is selected or not, first enable selection by setting
- the ItemIsSelectable flag, and then call setSelected(). Normally,
- selection is toggled by the scene, as a result of user interaction.
-
- To write your own graphics item, you first create a subclass of
- QGraphicsItem, and then start by implementing its two pure virtual public
- functions: boundingRect(), which returns an estimate of the area painted
- by the item, and paint(), which implements the actual painting. For
- example:
-
- \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 0
-
- The boundingRect() function has many different purposes.
- QGraphicsScene bases its item index on boundingRect(), and
- QGraphicsView uses it both for culling invisible items, and for
- determining the area that needs to be recomposed when drawing
- overlapping items. In addition, QGraphicsItem's collision
- detection mechanisms use boundingRect() to provide an efficient
- cut-off. The fine grained collision algorithm in
- collidesWithItem() is based on calling shape(), which returns an
- accurate outline of the item's shape as a QPainterPath.
-
- QGraphicsScene expects all items boundingRect() and shape() to
- remain unchanged unless it is notified. If you want to change an
- item's geometry in any way, you must first call
- prepareGeometryChange() to allow QGraphicsScene to update its
- bookkeeping.
-
- Collision detection can be done in two ways:
-
- \list 1
-
- \o Reimplement shape() to return an accurate shape for your item,
- and rely on the default implementation of collidesWithItem() to do
- shape-shape intersection. This can be rather expensive if the
- shapes are complex.
-
- \o Reimplement collidesWithItem() to provide your own custom item
- and shape collision algorithm.
-
- \endlist
-
- The contains() function can be called to determine whether the item \e
- contains a point or not. This function can also be reimplemented by the
- item. The default behavior of contains() is based on calling shape().
-
- Items can contain other items, and also be contained by other items. All
- items can have a parent item and a list of children. Unless the item has
- no parent, its position is in \e parent coordinates (i.e., the parent's
- local coordinates). Parent items propagate both their position and their
- transformation to all children.
-
- \img graphicsview-parentchild.png
-
- \target Transformations
- \section1 Transformations
-
- QGraphicsItem supports projective transformations in addition to its base
- position, pos(). There are several ways to change an item's transformation.
- For simple transformations, you can call either of the convenience
- functions setRotation() or setScale(), or you can pass any transformation
- matrix to setTransform(). For advanced transformation control you also have
- the option of setting several combined transformations by calling
- setTransformations().
-
- Item transformations accumulate from parent to child, so if both a parent
- and child item are rotated 90 degrees, the child's total transformation
- will be 180 degrees. Similarly, if the item's parent is scaled to 2x its
- original size, its children will also be twice as large. An item's
- transformation does not affect its own local geometry; all geometry
- functions (e.g., contains(), update(), and all the mapping functions) still
- operate in local coordinates. For convenience, QGraphicsItem provides the
- functions sceneTransform(), which returns the item's total transformation
- matrix (including its position and all parents' positions and
- transformations), and scenePos(), which returns its position in scene
- coordinates. To reset an item's matrix, call resetTransform().
-
- Certain transformation operations produce a different outcome depending on
- the order in which they are applied. For example, if you scale an
- transform, and then rotate it, you may get a different result than if the
- transform was rotated first. However, the order you set the transformation
- properties on QGraphicsItem does not affect the resulting transformation;
- QGraphicsItem always applies the properties in a fixed, defined order:
-
- \list
- \o The item's base transform is applied (transform())
- \o The item's transformations list is applied in order (transformations())
- \o The item is rotated relative to its transform origin point (rotation(), transformOriginPoint())
- \o The item is scaled relative to its transform origin point (scale(), transformOriginPoint())
- \endlist
-
- \section1 Painting
-
- The paint() function is called by QGraphicsView to paint the item's
- contents. The item has no background or default fill of its own; whatever
- is behind the item will shine through all areas that are not explicitly
- painted in this function. You can call update() to schedule a repaint,
- optionally passing the rectangle that needs a repaint. Depending on
- whether or not the item is visible in a view, the item may or may not be
- repainted; there is no equivalent to QWidget::repaint() in QGraphicsItem.
-
- Items are painted by the view, starting with the parent items and then
- drawing children, in ascending stacking order. You can set an item's
- stacking order by calling setZValue(), and test it by calling
- zValue(), where items with low z-values are painted before items with
- high z-values. Stacking order applies to sibling items; parents are always
- drawn before their children.
-
- \section1 Sorting
-
- All items are drawn in a defined, stable order, and this same order decides
- which items will receive mouse input first when you click on the scene.
- Normally you don't have to worry about sorting, as the items follow a
- "natural order", following the logical structure of the scene.
-
- An item's children are stacked on top of the parent, and sibling items are
- stacked by insertion order (i.e., in the same order that they were either
- added to the scene, or added to the same parent). If you add item A, and
- then B, then B will be on top of A. If you then add C, the items' stacking
- order will be A, then B, then C.
-
- \image graphicsview-zorder.png
-
- This example shows the stacking order of all limbs of the robot from the
- \l{graphicsview/dragdroprobot}{Drag and Drop Robot} example. The torso is
- the root item (all other items are children or descendants of the torso),
- so it is drawn first. Next, the head is drawn, as it is the first item in
- the torso's list of children. Then the upper left arm is drawn. As the
- lower arm is a child of the upper arm, the lower arm is then drawn,
- followed by the upper arm's next sibling, which is the upper right arm, and
- so on.
-
- For advanced users, there are ways to alter how your items are sorted:
-
- \list
- \o You can call setZValue() on an item to explicitly stack it on top of, or
- under, other sibling items. The default Z value for an item is 0. Items
- with the same Z value are stacked by insertion order.
-
- \o You can call stackBefore() to reorder the list of children. This will
- directly modify the insertion order.
-
- \o You can set the ItemStacksBehindParent flag to stack a child item behind
- its parent.
- \endlist
-
- The stacking order of two sibling items also counts for each item's
- children and descendant items. So if one item is on top of another, then
- all its children will also be on top of all the other item's children as
- well.
-
- \section1 Events
-
- QGraphicsItem receives events from QGraphicsScene through the virtual
- function sceneEvent(). This function distributes the most common events
- to a set of convenience event handlers:
-
- \list
- \o contextMenuEvent() handles context menu events
- \o focusInEvent() and focusOutEvent() handle focus in and out events
- \o hoverEnterEvent(), hoverMoveEvent(), and hoverLeaveEvent() handles
- hover enter, move and leave events
- \o inputMethodEvent() handles input events, for accessibility support
- \o keyPressEvent() and keyReleaseEvent() handle key press and release events
- \o mousePressEvent(), mouseMoveEvent(), mouseReleaseEvent(), and
- mouseDoubleClickEvent() handles mouse press, move, release, click and
- doubleclick events
- \endlist
-
- You can filter events for any other item by installing event filters. This
- functionality is separate from Qt's regular event filters (see
- QObject::installEventFilter()), which only work on subclasses of QObject. After
- installing your item as an event filter for another item by calling
- installSceneEventFilter(), the filtered events will be received by the virtual
- function sceneEventFilter(). You can remove item event filters by calling
- removeSceneEventFilter().
-
- \section1 Custom Data
-
- Sometimes it's useful to register custom data with an item, be it a custom
- item, or a standard item. You can call setData() on any item to store data
- in it using a key-value pair (the key being an integer, and the value is a
- QVariant). To get custom data from an item, call data(). This
- functionality is completely untouched by Qt itself; it is provided for the
- user's convenience.
-
- \sa QGraphicsScene, QGraphicsView, {Graphics View Framework}
-*/
-
-/*!
- \variable QGraphicsItem::Type
-
- The type value returned by the virtual type() function in standard
- graphics item classes in Qt. All such standard graphics item
- classes in Qt are associated with a unique value for Type,
- e.g. the value returned by QGraphicsPathItem::type() is 2.
-
- \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 18
-*/
-
-/*!
- \variable QGraphicsItem::UserType
-
- The lowest permitted type value for custom items (subclasses
- of QGraphicsItem or any of the standard items). This value is
- used in conjunction with a reimplementation of QGraphicsItem::type()
- and declaring a Type enum value. Example:
-
- \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 1
-
- \note UserType = 65536
-*/
-
-/*!
- \enum QGraphicsItem::GraphicsItemFlag
-
- This enum describes different flags that you can set on an item to
- toggle different features in the item's behavior.
-
- All flags are disabled by default.
-
- \value ItemIsMovable The item supports interactive movement using
- the mouse. By clicking on the item and then dragging, the item
- will move together with the mouse cursor. If the item has
- children, all children are also moved. If the item is part of a
- selection, all selected items are also moved. This feature is
- provided as a convenience through the base implementation of
- QGraphicsItem's mouse event handlers.
-
- \value ItemIsSelectable The item supports selection. Enabling this
- feature will enable setSelected() to toggle selection for the
- item. It will also let the item be selected automatically as a
- result of calling QGraphicsScene::setSelectionArea(), by clicking
- on an item, or by using rubber band selection in QGraphicsView.
-
- \value ItemIsFocusable The item supports keyboard input focus (i.e., it is
- an input item). Enabling this flag will allow the item to accept focus,
- which again allows the delivery of key events to
- QGraphicsItem::keyPressEvent() and QGraphicsItem::keyReleaseEvent().
-
- \value ItemClipsToShape The item clips to its own shape. The item cannot
- draw or receive mouse, tablet, drag and drop or hover events outside its
- shape. It is disabled by default. This behavior is enforced by
- QGraphicsView::drawItems() or QGraphicsScene::drawItems(). This flag was
- introduced in Qt 4.3.
-
- \value ItemClipsChildrenToShape The item clips the painting of all its
- descendants to its own shape. Items that are either direct or indirect
- children of this item cannot draw outside this item's shape. By default,
- this flag is disabled; children can draw anywhere. This behavior is
- enforced by QGraphicsView::drawItems() or
- QGraphicsScene::drawItems(). This flag was introduced in Qt 4.3.
-
- \value ItemIgnoresTransformations The item ignores inherited
- transformations (i.e., its position is still anchored to its parent, but
- the parent or view rotation, zoom or shear transformations are ignored).
- This flag is useful for keeping text label items horizontal and unscaled,
- so they will still be readable if the view is transformed. When set, the
- item's view geometry and scene geometry will be maintained separately. You
- must call deviceTransform() to map coordinates and detect collisions in
- the view. By default, this flag is disabled. This flag was introduced in
- Qt 4.3. \note With this flag set you can still scale the item itself, and
- that scale transformation will influence the item's children.
-
- \value ItemIgnoresParentOpacity The item ignores its parent's opacity. The
- item's effective opacity is the same as its own; it does not combine with
- the parent's opacity. This flags allows your item to keep its absolute
- opacity even if the parent is semitransparent. This flag was introduced in
- Qt 4.5.
-
- \value ItemDoesntPropagateOpacityToChildren The item doesn't propagate its
- opacity to its children. This flag allows you to create a semitransparent
- item that does not affect the opacity of its children. This flag was
- introduced in Qt 4.5.
-
- \value ItemStacksBehindParent The item is stacked behind its parent. By
- default, child items are stacked on top of the parent item. But setting
- this flag, the child will be stacked behind it. This flag is useful for
- drop shadow effects and for decoration objects that follow the parent
- item's geometry without drawing on top of it. This flag was introduced
- in Qt 4.5.
-
- \value ItemUsesExtendedStyleOption The item makes use of either
- \l{QStyleOptionGraphicsItem::} {exposedRect} or
- \l{QStyleOptionGraphicsItem::} {matrix} in
- QStyleOptionGraphicsItem. By default, the
- \l{QStyleOptionGraphicsItem::} {exposedRect} is initialized to the
- item's boundingRect() and the
- \l{QStyleOptionGraphicsItem::}{matrix} is untransformed. You can
- enable this flag for the style options to be set up with more
- fine-grained values. Note that
- QStyleOptionGraphicsItem::levelOfDetail is unaffected by this flag
- and always initialized to 1. Use
- QStyleOptionGraphicsItem::levelOfDetailFromTransform() if you need
- a higher value. This flag was introduced in Qt 4.6.
-
- \value ItemHasNoContents The item does not paint anything (i.e., calling
- paint() on the item has no effect). You should set this flag on items that
- do not need to be painted to ensure that Graphics View avoids unnecessary
- painting preparations. This flag was introduced in Qt 4.6.
-
- \value ItemSendsGeometryChanges The item enables itemChange()
- notifications for ItemPositionChange, ItemPositionHasChanged,
- ItemMatrixChange, ItemTransformChange, ItemTransformHasChanged,
- ItemRotationChange, ItemRotationHasChanged, ItemScaleChange, ItemScaleHasChanged,
- ItemTransformOriginPointChange, and ItemTransformOriginPointHasChanged. For
- performance reasons, these notifications are disabled by default. You must
- enable this flag to receive notifications for position and transform
- changes. This flag was introduced in Qt 4.6.
-
- \value ItemAcceptsInputMethod The item supports input methods typically
- used for Asian languages.
- This flag was introduced in Qt 4.6.
-
- \value ItemNegativeZStacksBehindParent The item automatically
- stacks behind it's parent if it's z-value is negative. This flag
- enables setZValue() to toggle ItemStacksBehindParent. This flag
- was introduced in Qt 4.6.
-
- \value ItemIsPanel The item is a panel. A panel provides activation and
- contained focus handling. Only one panel can be active at a time (see
- QGraphicsItem::isActive()). When no panel is active, QGraphicsScene
- activates all non-panel items. Window items (i.e.,
- QGraphicsItem::isWindow() returns true) are panels. This flag was
- introduced in Qt 4.6.
-
- \omitvalue ItemIsFocusScope \omit Internal only (for now). \endomit
-
- \value ItemSendsScenePositionChanges The item enables itemChange()
- notifications for ItemScenePositionHasChanged. For performance reasons,
- these notifications are disabled by default. You must enable this flag
- to receive notifications for scene position changes. This flag was
- introduced in Qt 4.6.
-
- \omitvalue ItemStopsClickFocusPropagation \omit The item stops propagating
- click focus to items underneath when being clicked on. This flag
- allows you create a non-focusable item that can be clicked on without
- changing the focus. \endomit
-
- \omitvalue ItemStopsFocusHandling \omit Same as
- ItemStopsClickFocusPropagation, but also suppresses focus-out. This flag
- allows you to completely take over focus handling.
- This flag was introduced in Qt 4.7. \endomit
-*/
-
-/*!
- \enum QGraphicsItem::GraphicsItemChange
-
- This enum describes the state changes that are notified by
- QGraphicsItem::itemChange(). The notifications are sent as the state
- changes, and in some cases, adjustments can be made (see the documentation
- for each change for details).
-
- Note: Be careful with calling functions on the QGraphicsItem itself inside
- itemChange(), as certain function calls can lead to unwanted
- recursion. For example, you cannot call setPos() in itemChange() on an
- ItemPositionChange notification, as the setPos() function will again call
- itemChange(ItemPositionChange). Instead, you can return the new, adjusted
- position from itemChange().
-
- \value ItemEnabledChange The item's enabled state changes. If the item is
- presently enabled, it will become disabled, and vice verca. The value
- argument is the new enabled state (i.e., true or false). Do not call
- setEnabled() in itemChange() as this notification is delivered. Instead,
- you can return the new state from itemChange().
-
- \value ItemEnabledHasChanged The item's enabled state has changed. The
- value argument is the new enabled state (i.e., true or false). Do not call
- setEnabled() in itemChange() as this notification is delivered. The return
- value is ignored.
-
- \value ItemMatrixChange The item's affine transformation matrix is
- changing. This value is obsolete; you can use ItemTransformChange instead.
-
- \value ItemPositionChange The item's position changes. This notification
- is sent if the ItemSendsGeometryChanges flag is enabled, and when the
- item's local position changes, relative to its parent (i.e., as a result
- of calling setPos() or moveBy()). The value argument is the new position
- (i.e., a QPointF). You can call pos() to get the original position. Do
- not call setPos() or moveBy() in itemChange() as this notification is
- delivered; instead, you can return the new, adjusted position from
- itemChange(). After this notification, QGraphicsItem immediately sends the
- ItemPositionHasChanged notification if the position changed.
-
- \value ItemPositionHasChanged The item's position has changed. This
- notification is sent if the ItemSendsGeometryChanges flag is enabled, and
- after the item's local position, relative to its parent, has changed. The
- value argument is the new position (the same as pos()), and QGraphicsItem
- ignores the return value for this notification (i.e., a read-only
- notification).
-
- \value ItemTransformChange The item's transformation matrix changes. This
- notification is send if the ItemSendsGeometryChanges flag is enabled, and
- when the item's local transformation matrix changes (i.e., as a result of
- calling setTransform(). The value argument is the new matrix (i.e., a
- QTransform); to get the old matrix, call transform(). Do not call
- setTransform() or set any of the transformation properties in itemChange()
- as this notification is delivered; instead, you can return the new matrix
- from itemChange(). This notification is not sent if you change the
- transformation properties.
-
- \value ItemTransformHasChanged The item's transformation matrix has
- changed either because setTransform is called, or one of the
- transformation properties is changed. This notification is sent if the
- ItemSendsGeometryChanges flag is enabled, and after the item's local
- transformation matrix has changed. The value argument is the new matrix
- (same as transform()), and QGraphicsItem ignores the return value for this
- notification (i.e., a read-only notification).
-
- \value ItemRotationChange The item's rotation property changes. This
- notification is sent if the ItemSendsGeometryChanges flag is enabled, and
- when the item's rotation property changes (i.e., as a result of calling
- setRotation()). The value argument is the new rotation (i.e., a double);
- to get the old rotation, call rotation(). Do not call setRotation() in
- itemChange() as this notification is delivered; instead, you can return
- the new rotation from itemChange().
-
- \value ItemRotationHasChanged The item's rotation property has changed.
- This notification is sent if the ItemSendsGeometryChanges flag is enabled,
- and after the item's rotation property has changed. The value argument is
- the new rotation (i.e., a double), and QGraphicsItem ignores the return
- value for this notification (i.e., a read-only notification). Do not call
- setRotation() in itemChange() as this notification is delivered.
-
- \value ItemScaleChange The item's scale property changes. This notification
- is sent if the ItemSendsGeometryChanges flag is enabled, and when the item's
- scale property changes (i.e., as a result of calling setScale()). The value
- argument is the new scale (i.e., a double); to get the old scale, call
- scale(). Do not call setScale() in itemChange() as this notification is
- delivered; instead, you can return the new scale from itemChange().
-
- \value ItemScaleHasChanged The item's scale property has changed. This
- notification is sent if the ItemSendsGeometryChanges flag is enabled, and
- after the item's scale property has changed. The value argument is the new
- scale (i.e., a double), and QGraphicsItem ignores the return value for this
- notification (i.e., a read-only notification). Do not call setScale() in
- itemChange() as this notification is delivered.
-
- \value ItemTransformOriginPointChange The item's transform origin point
- property changes. This notification is sent if the ItemSendsGeometryChanges
- flag is enabled, and when the item's transform origin point property changes
- (i.e., as a result of calling setTransformOriginPoint()). The value argument
- is the new origin point (i.e., a QPointF); to get the old origin point, call
- transformOriginPoint(). Do not call setTransformOriginPoint() in itemChange()
- as this notification is delivered; instead, you can return the new transform
- origin point from itemChange().
-
- \value ItemTransformOriginPointHasChanged The item's transform origin point
- property has changed. This notification is sent if the ItemSendsGeometryChanges
- flag is enabled, and after the item's transform origin point property has
- changed. The value argument is the new origin point (i.e., a QPointF), and
- QGraphicsItem ignores the return value for this notification (i.e., a read-only
- notification). Do not call setTransformOriginPoint() in itemChange() as this
- notification is delivered.
-
- \value ItemSelectedChange The item's selected state changes. If the item is
- presently selected, it will become unselected, and vice verca. The value
- argument is the new selected state (i.e., true or false). Do not call
- setSelected() in itemChange() as this notification is delivered; instead, you
- can return the new selected state from itemChange().
-
- \value ItemSelectedHasChanged The item's selected state has changed. The
- value argument is the new selected state (i.e., true or false). Do not
- call setSelected() in itemChange() as this notification is delivered. The
- return value is ignored.
-
- \value ItemVisibleChange The item's visible state changes. If the item is
- presently visible, it will become invisible, and vice verca. The value
- argument is the new visible state (i.e., true or false). Do not call
- setVisible() in itemChange() as this notification is delivered; instead,
- you can return the new visible state from itemChange().
-
- \value ItemVisibleHasChanged The item's visible state has changed. The
- value argument is the new visible state (i.e., true or false). Do not call
- setVisible() in itemChange() as this notification is delivered. The return
- value is ignored.
-
- \value ItemParentChange The item's parent changes. The value argument is
- the new parent item (i.e., a QGraphicsItem pointer). Do not call
- setParentItem() in itemChange() as this notification is delivered;
- instead, you can return the new parent from itemChange().
-
- \value ItemParentHasChanged The item's parent has changed. The value
- argument is the new parent (i.e., a pointer to a QGraphicsItem). Do not
- call setParentItem() in itemChange() as this notification is
- delivered. The return value is ignored.
-
- \value ItemChildAddedChange A child is added to this item. The value
- argument is the new child item (i.e., a QGraphicsItem pointer). Do not
- pass this item to any item's setParentItem() function as this notification
- is delivered. The return value is unused; you cannot adjust anything in
- this notification. Note that the new child might not be fully constructed
- when this notification is sent; calling pure virtual functions on
- the child can lead to a crash.
-
- \value ItemChildRemovedChange A child is removed from this item. The value
- argument is the child item that is about to be removed (i.e., a
- QGraphicsItem pointer). The return value is unused; you cannot adjust
- anything in this notification.
-
- \value ItemSceneChange The item is moved to a new scene. This notification is
- also sent when the item is added to its initial scene, and when it is removed.
- The item's scene() is the old scene (or 0 if the item has not been added to a
- scene yet). The value argument is the new scene (i.e., a QGraphicsScene
- pointer), or a null pointer if the item is removed from a scene. Do not
- override this change by passing this item to QGraphicsScene::addItem() as this
- notification is delivered; instead, you can return the new scene from
- itemChange(). Use this feature with caution; objecting to a scene change can
- quickly lead to unwanted recursion.
-
- \value ItemSceneHasChanged The item's scene has changed. The item's scene() is
- the new scene. This notification is also sent when the item is added to its
- initial scene, and when it is removed.The value argument is the new scene
- (i.e., a pointer to a QGraphicsScene). Do not call setScene() in itemChange()
- as this notification is delivered. The return value is ignored.
-
- \value ItemCursorChange The item's cursor changes. The value argument is
- the new cursor (i.e., a QCursor). Do not call setCursor() in itemChange()
- as this notification is delivered. Instead, you can return a new cursor
- from itemChange().
-
- \value ItemCursorHasChanged The item's cursor has changed. The value
- argument is the new cursor (i.e., a QCursor). Do not call setCursor() as
- this notification is delivered. The return value is ignored.
-
- \value ItemToolTipChange The item's tooltip changes. The value argument is
- the new tooltip (i.e., a QToolTip). Do not call setToolTip() in
- itemChange() as this notification is delivered. Instead, you can return a
- new tooltip from itemChange().
-
- \value ItemToolTipHasChanged The item's tooltip has changed. The value
- argument is the new tooltip (i.e., a QToolTip). Do not call setToolTip()
- as this notification is delivered. The return value is ignored.
-
- \value ItemFlagsChange The item's flags change. The value argument is the
- new flags (i.e., a quint32). Do not call setFlags() in itemChange() as
- this notification is delivered. Instead, you can return the new flags from
- itemChange().
-
- \value ItemFlagsHaveChanged The item's flags have changed. The value
- argument is the new flags (i.e., a quint32). Do not call setFlags() in
- itemChange() as this notification is delivered. The return value is
- ignored.
-
- \value ItemZValueChange The item's Z-value changes. The value argument is
- the new Z-value (i.e., a double). Do not call setZValue() in itemChange()
- as this notification is delivered. Instead, you can return a new Z-value
- from itemChange().
-
- \value ItemZValueHasChanged The item's Z-value has changed. The value
- argument is the new Z-value (i.e., a double). Do not call setZValue() as
- this notification is delivered. The return value is ignored.
-
- \value ItemOpacityChange The item's opacity changes. The value argument is
- the new opacity (i.e., a double). Do not call setOpacity() in itemChange()
- as this notification is delivered. Instead, you can return a new opacity
- from itemChange().
-
- \value ItemOpacityHasChanged The item's opacity has changed. The value
- argument is the new opacity (i.e., a double). Do not call setOpacity() as
- this notification is delivered. The return value is ignored.
-
- \value ItemScenePositionHasChanged The item's scene position has changed.
- This notification is sent if the ItemSendsScenePositionChanges flag is
- enabled, and after the item's scene position has changed (i.e., the
- position or transformation of the item itself or the position or
- transformation of any ancestor has changed). The value argument is the
- new scene position (the same as scenePos()), and QGraphicsItem ignores
- the return value for this notification (i.e., a read-only notification).
-*/
-
-/*!
- \enum QGraphicsItem::CacheMode
- \since 4.4
-
- This enum describes QGraphicsItem's cache modes. Caching is used to speed
- up rendering by allocating and rendering to an off-screen pixel buffer,
- which can be reused when the item requires redrawing. For some paint
- devices, the cache is stored directly in graphics memory, which makes
- rendering very quick.
-
- \value NoCache The default; all item caching is
- disabled. QGraphicsItem::paint() is called every time the item needs
- redrawing.
-
- \value ItemCoordinateCache Caching is enabled for the item's logical
- (local) coordinate system. QGraphicsItem creates an off-screen pixel
- buffer with a configurable size / resolution that you can pass to
- QGraphicsItem::setCacheMode(). Rendering quality will typically degrade,
- depending on the resolution of the cache and the item transformation. The
- first time the item is redrawn, it will render itself into the cache, and
- the cache is then reused for every subsequent expose. The cache is also
- reused as the item is transformed. To adjust the resolution of the cache,
- you can call setCacheMode() again.
-
- \value DeviceCoordinateCache Caching is enabled at the paint device level,
- in device coordinates. This mode is for items that can move, but are not
- rotated, scaled or sheared. If the item is transformed directly or
- indirectly, the cache will be regenerated automatically. Unlike
- ItemCoordinateCacheMode, DeviceCoordinateCache always renders at maximum
- quality.
-
- \sa QGraphicsItem::setCacheMode()
-*/
-
-/*!
- \enum QGraphicsItem::Extension
- \internal
-
- Note: This is provided as a hook to avoid future problems related
- to adding virtual functions. See also extension(),
- supportsExtension() and setExtension().
-*/
-
-/*!
- \enum QGraphicsItem::PanelModality
- \since 4.6
-
- This enum specifies the behavior of a modal panel. A modal panel
- is one that blocks input to other panels. Note that items that
- are children of a modal panel are not blocked.
-
- The values are:
-
- \value NonModal The panel is not modal and does not block input to
- other panels. This is the default value for panels.
-
- \value PanelModal The panel is modal to a single item hierarchy
- and blocks input to its parent pane, all grandparent panels, and
- all siblings of its parent and grandparent panels.
-
- \value SceneModal The window is modal to the entire scene and
- blocks input to all panels.
-
- \sa QGraphicsItem::setPanelModality(), QGraphicsItem::panelModality(), QGraphicsItem::ItemIsPanel
-*/
-
-#include "qgraphicsitem.h"
-
-#ifndef QT_NO_GRAPHICSVIEW
-
-#include "qgraphicsscene.h"
-#include "qgraphicsscene_p.h"
-#include "qgraphicssceneevent.h"
-#include "qgraphicsview.h"
-#include "qgraphicswidget.h"
-#include "qgraphicsproxywidget.h"
-#include "qgraphicsscenebsptreeindex_p.h"
-#include <QtCore/qbitarray.h>
-#include <QtCore/qdebug.h>
-#include <QtCore/qpoint.h>
-#include <QtCore/qstack.h>
-#include <QtCore/qtimer.h>
-#include <QtCore/qvariant.h>
-#include <QtCore/qvarlengtharray.h>
-#include <QtCore/qnumeric.h>
-#include <QtGui/qapplication.h>
-#include <QtGui/qbitmap.h>
-#include <QtGui/qpainter.h>
-#include <QtGui/qpainterpath.h>
-#include <QtGui/qpixmapcache.h>
-#include <QtGui/qstyleoption.h>
-#include <QtGui/qevent.h>
-#include <QtGui/qinputcontext.h>
-#include <QtGui/qgraphicseffect.h>
-#ifndef QT_NO_ACCESSIBILITY
-# include "qaccessible.h"
-#endif
-
-#include <private/qgraphicsitem_p.h>
-#include <private/qgraphicswidget_p.h>
-#include <private/qtextcontrol_p.h>
-#include <private/qtextdocumentlayout_p.h>
-#include <private/qtextengine_p.h>
-#include <private/qwidget_p.h>
-#include <private/qapplication_p.h>
-
-#ifdef Q_WS_X11
-#include <private/qt_x11_p.h>
-#include <private/qpixmap_x11_p.h>
-#endif
-
-#include <private/qgesturemanager_p.h>
-
-#include <math.h>
-
-QT_BEGIN_NAMESPACE
-
-static inline void _q_adjustRect(QRect *rect)
-{
- Q_ASSERT(rect);
- if (!rect->width())
- rect->adjust(0, 0, 1, 0);
- if (!rect->height())
- rect->adjust(0, 0, 0, 1);
-}
-
-/*
- ### Move this into QGraphicsItemPrivate
- */
-class QGraphicsItemCustomDataStore
-{
-public:
- QMap<const QGraphicsItem *, QMap<int, QVariant> > data;
-};
-Q_GLOBAL_STATIC(QGraphicsItemCustomDataStore, qt_dataStore)
-
-/*!
- \internal
-
- Returns a QPainterPath of \a path when stroked with the \a pen.
- Ignoring dash pattern.
-*/
-static QPainterPath qt_graphicsItem_shapeFromPath(const QPainterPath &path, const QPen &pen)
-{
- // We unfortunately need this hack as QPainterPathStroker will set a width of 1.0
- // if we pass a value of 0.0 to QPainterPathStroker::setWidth()
- const qreal penWidthZero = qreal(0.00000001);
-
- if (path == QPainterPath())
- return path;
- QPainterPathStroker ps;
- ps.setCapStyle(pen.capStyle());
- if (pen.widthF() <= 0.0)
- ps.setWidth(penWidthZero);
- else
- ps.setWidth(pen.widthF());
- ps.setJoinStyle(pen.joinStyle());
- ps.setMiterLimit(pen.miterLimit());
- QPainterPath p = ps.createStroke(path);
- p.addPath(path);
- return p;
-}
-
-/*!
- \internal
-
- Propagates the ancestor flag \a flag with value \a enabled to all this
- item's children. If \a root is false, the flag is also set on this item
- (default is true).
-*/
-void QGraphicsItemPrivate::updateAncestorFlag(QGraphicsItem::GraphicsItemFlag childFlag,
- AncestorFlag flag, bool enabled, bool root)
-{
- Q_Q(QGraphicsItem);
- if (root) {
- // For root items only. This is the item that has either enabled or
- // disabled \a childFlag, or has been reparented.
- switch (int(childFlag)) {
- case -2:
- flag = AncestorFiltersChildEvents;
- enabled = q->filtersChildEvents();
- break;
- case -1:
- flag = AncestorHandlesChildEvents;
- enabled = q->handlesChildEvents();
- break;
- case QGraphicsItem::ItemClipsChildrenToShape:
- flag = AncestorClipsChildren;
- enabled = flags & QGraphicsItem::ItemClipsChildrenToShape;
- break;
- case QGraphicsItem::ItemIgnoresTransformations:
- flag = AncestorIgnoresTransformations;
- enabled = flags & QGraphicsItem::ItemIgnoresTransformations;
- break;
- default:
- return;
- }
-
- if (parent) {
- // Inherit the enabled-state from our parents.
- if ((parent->d_ptr->ancestorFlags & flag)
- || (int(parent->d_ptr->flags & childFlag) == childFlag)
- || (childFlag == -1 && parent->d_ptr->handlesChildEvents)
- || (childFlag == -2 && parent->d_ptr->filtersDescendantEvents)) {
- enabled = true;
- ancestorFlags |= flag;
- } else {
- ancestorFlags &= ~flag;
- }
- } else {
- // Top-level root items don't have any ancestors, so there are no
- // ancestor flags either.
- ancestorFlags = 0;
- }
- } else {
- // Don't set or propagate the ancestor flag if it's already correct.
- if (((ancestorFlags & flag) && enabled) || (!(ancestorFlags & flag) && !enabled))
- return;
-
- // Set the flag.
- if (enabled)
- ancestorFlags |= flag;
- else
- ancestorFlags &= ~flag;
-
- // Don't process children if the item has the main flag set on itself.
- if ((childFlag != -1 && int(flags & childFlag) == childFlag)
- || (int(childFlag) == -1 && handlesChildEvents)
- || (int(childFlag) == -2 && filtersDescendantEvents))
- return;
- }
-
- for (int i = 0; i < children.size(); ++i)
- children.at(i)->d_ptr->updateAncestorFlag(childFlag, flag, enabled, false);
-}
-
-void QGraphicsItemPrivate::updateAncestorFlags()
-{
- int flags = 0;
- if (parent) {
- // Inherit the parent's ancestor flags.
- QGraphicsItemPrivate *pd = parent->d_ptr.data();
- flags = pd->ancestorFlags;
-
- // Add in flags from the parent.
- if (pd->filtersDescendantEvents)
- flags |= AncestorFiltersChildEvents;
- if (pd->handlesChildEvents)
- flags |= AncestorHandlesChildEvents;
- if (pd->flags & QGraphicsItem::ItemClipsChildrenToShape)
- flags |= AncestorClipsChildren;
- if (pd->flags & QGraphicsItem::ItemIgnoresTransformations)
- flags |= AncestorIgnoresTransformations;
- }
-
- if (ancestorFlags == flags)
- return; // No change; stop propagation.
- ancestorFlags = flags;
-
- // Propagate to children recursively.
- for (int i = 0; i < children.size(); ++i)
- children.at(i)->d_ptr->updateAncestorFlags();
-}
-
-/*!
- \internal
-
- Propagates item group membership.
-*/
-void QGraphicsItemPrivate::setIsMemberOfGroup(bool enabled)
-{
- Q_Q(QGraphicsItem);
- isMemberOfGroup = enabled;
- if (!qgraphicsitem_cast<QGraphicsItemGroup *>(q)) {
- foreach (QGraphicsItem *child, children)
- child->d_func()->setIsMemberOfGroup(enabled);
- }
-}
-
-/*!
- \internal
-
- Maps any item pos properties of \a event to \a item's coordinate system.
-*/
-void QGraphicsItemPrivate::remapItemPos(QEvent *event, QGraphicsItem *item)
-{
- Q_Q(QGraphicsItem);
- switch (event->type()) {
- case QEvent::GraphicsSceneMouseMove:
- case QEvent::GraphicsSceneMousePress:
- case QEvent::GraphicsSceneMouseRelease:
- case QEvent::GraphicsSceneMouseDoubleClick: {
- QGraphicsSceneMouseEvent *mouseEvent = static_cast<QGraphicsSceneMouseEvent *>(event);
- mouseEvent->setPos(item->mapFromItem(q, mouseEvent->pos()));
- mouseEvent->setLastPos(item->mapFromItem(q, mouseEvent->pos()));
- for (int i = 0x1; i <= 0x10; i <<= 1) {
- if (mouseEvent->buttons() & i) {
- Qt::MouseButton button = Qt::MouseButton(i);
- mouseEvent->setButtonDownPos(button, item->mapFromItem(q, mouseEvent->buttonDownPos(button)));
- }
- }
- break;
- }
- case QEvent::GraphicsSceneWheel: {
- QGraphicsSceneWheelEvent *wheelEvent = static_cast<QGraphicsSceneWheelEvent *>(event);
- wheelEvent->setPos(item->mapFromItem(q, wheelEvent->pos()));
- break;
- }
- case QEvent::GraphicsSceneContextMenu: {
- QGraphicsSceneContextMenuEvent *contextEvent = static_cast<QGraphicsSceneContextMenuEvent *>(event);
- contextEvent->setPos(item->mapFromItem(q, contextEvent->pos()));
- break;
- }
- case QEvent::GraphicsSceneHoverMove: {
- QGraphicsSceneHoverEvent *hoverEvent = static_cast<QGraphicsSceneHoverEvent *>(event);
- hoverEvent->setPos(item->mapFromItem(q, hoverEvent->pos()));
- break;
- }
- default:
- break;
- }
-}
-
-/*!
- \internal
-
- Maps the point \a pos from scene to item coordinates. If \a view is passed and the item
- is untransformable, this function will correctly map \a pos from the scene using the
- view's transformation.
-*/
-QPointF QGraphicsItemPrivate::genericMapFromScene(const QPointF &pos,
- const QWidget *viewport) const
-{
- Q_Q(const QGraphicsItem);
- if (!itemIsUntransformable())
- return q->mapFromScene(pos);
- QGraphicsView *view = 0;
- if (viewport)
- view = qobject_cast<QGraphicsView *>(viewport->parentWidget());
- if (!view)
- return q->mapFromScene(pos);
- // ### More ping pong than needed.
- return q->deviceTransform(view->viewportTransform()).inverted().map(view->mapFromScene(pos));
-}
-
-/*!
- \internal
-
- Combines this item's position and transform onto \a transform.
-
- If you need to change this function (e.g., adding more transformation
- modes / options), make sure to change all places marked with COMBINE.
-*/
-void QGraphicsItemPrivate::combineTransformToParent(QTransform *x, const QTransform *viewTransform) const
-{
- // COMBINE
- if (viewTransform && itemIsUntransformable()) {
- *x = q_ptr->deviceTransform(*viewTransform);
- } else {
- if (transformData)
- *x *= transformData->computedFullTransform();
- if (!pos.isNull())
- *x *= QTransform::fromTranslate(pos.x(), pos.y());
- }
-}
-
-/*!
- \internal
-
- Combines this item's position and transform onto \a transform.
-
- If you need to change this function (e.g., adding more transformation
- modes / options), make sure to change QGraphicsItem::deviceTransform() as
- well.
-*/
-void QGraphicsItemPrivate::combineTransformFromParent(QTransform *x, const QTransform *viewTransform) const
-{
- // COMBINE
- if (viewTransform && itemIsUntransformable()) {
- *x = q_ptr->deviceTransform(*viewTransform);
- } else {
- x->translate(pos.x(), pos.y());
- if (transformData)
- *x = transformData->computedFullTransform(x);
- }
-}
-
-void QGraphicsItemPrivate::updateSceneTransformFromParent()
-{
- if (parent) {
- Q_ASSERT(!parent->d_ptr->dirtySceneTransform);
- if (parent->d_ptr->sceneTransformTranslateOnly) {
- sceneTransform = QTransform::fromTranslate(parent->d_ptr->sceneTransform.dx() + pos.x(),
- parent->d_ptr->sceneTransform.dy() + pos.y());
- } else {
- sceneTransform = parent->d_ptr->sceneTransform;
- sceneTransform.translate(pos.x(), pos.y());
- }
- if (transformData) {
- sceneTransform = transformData->computedFullTransform(&sceneTransform);
- sceneTransformTranslateOnly = (sceneTransform.type() <= QTransform::TxTranslate);
- } else {
- sceneTransformTranslateOnly = parent->d_ptr->sceneTransformTranslateOnly;
- }
- } else if (!transformData) {
- sceneTransform = QTransform::fromTranslate(pos.x(), pos.y());
- sceneTransformTranslateOnly = 1;
- } else if (transformData->onlyTransform) {
- sceneTransform = transformData->transform;
- if (!pos.isNull())
- sceneTransform *= QTransform::fromTranslate(pos.x(), pos.y());
- sceneTransformTranslateOnly = (sceneTransform.type() <= QTransform::TxTranslate);
- } else if (pos.isNull()) {
- sceneTransform = transformData->computedFullTransform();
- sceneTransformTranslateOnly = (sceneTransform.type() <= QTransform::TxTranslate);
- } else {
- sceneTransform = QTransform::fromTranslate(pos.x(), pos.y());
- sceneTransform = transformData->computedFullTransform(&sceneTransform);
- sceneTransformTranslateOnly = (sceneTransform.type() <= QTransform::TxTranslate);
- }
- dirtySceneTransform = 0;
-}
-
-/*!
- \internal
-
- This helper function helped us add input method query support in
- Qt 4.4.1 without having to reimplement the inputMethodQuery()
- function in QGraphicsProxyWidget. ### Qt 5: Remove. We cannot
- remove it in 4.5+ even if we do reimplement the function properly,
- because apps compiled with 4.4 will not be able to call the
- reimplementation.
-*/
-QVariant QGraphicsItemPrivate::inputMethodQueryHelper(Qt::InputMethodQuery query) const
-{
- Q_UNUSED(query);
- return QVariant();
-}
-
-/*!
- \internal
-
- Make sure not to trigger any pure virtual function calls (e.g.,
- prepareGeometryChange) if the item is in its destructor, i.e.
- inDestructor is 1.
-*/
-void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent, const QVariant *newParentVariant,
- const QVariant *thisPointerVariant)
-{
- Q_Q(QGraphicsItem);
- if (newParent == parent)
- return;
-
- if (isWidget)
- static_cast<QGraphicsWidgetPrivate *>(this)->fixFocusChainBeforeReparenting((newParent &&
- newParent->isWidget()) ? static_cast<QGraphicsWidget *>(newParent) : 0,
- scene);
- if (scene) {
- // Deliver the change to the index
- if (scene->d_func()->indexMethod != QGraphicsScene::NoIndex)
- scene->d_func()->index->itemChange(q, QGraphicsItem::ItemParentChange, newParent);
-
- // Disable scene pos notifications for old ancestors
- if (scenePosDescendants || (flags & QGraphicsItem::ItemSendsScenePositionChanges))
- scene->d_func()->setScenePosItemEnabled(q, false);
- }
-
- if (subFocusItem && parent) {
- // Make sure none of the old parents point to this guy.
- subFocusItem->d_ptr->clearSubFocus(parent);
- }
-
- // We anticipate geometry changes. If the item is deleted, it will be
- // removed from the index at a later stage, and the whole scene will be
- // updated.
- if (!inDestructor)
- q_ptr->prepareGeometryChange();
-
- if (parent) {
- // Remove from current parent
- parent->d_ptr->removeChild(q);
- if (thisPointerVariant)
- parent->itemChange(QGraphicsItem::ItemChildRemovedChange, *thisPointerVariant);
- }
-
- // Update toplevelitem list. If this item is being deleted, its parent
- // will be 0 but we don't want to register/unregister it in the TLI list.
- if (scene && !inDestructor) {
- if (parent && !newParent) {
- scene->d_func()->registerTopLevelItem(q);
- } else if (!parent && newParent) {
- scene->d_func()->unregisterTopLevelItem(q);
- }
- }
-
- // Ensure any last parent focus scope does not point to this item or any of
- // its descendents.
- QGraphicsItem *p = parent;
- QGraphicsItem *parentFocusScopeItem = 0;
- while (p) {
- if (p->d_ptr->flags & QGraphicsItem::ItemIsFocusScope) {
- // If this item's focus scope's focus scope item points
- // to this item or a descendent, then clear it.
- QGraphicsItem *fsi = p->d_ptr->focusScopeItem;
- if (q_ptr == fsi || q_ptr->isAncestorOf(fsi)) {
- parentFocusScopeItem = fsi;
- p->d_ptr->focusScopeItem = 0;
- fsi->d_ptr->focusScopeItemChange(false);
- }
- break;
- }
- p = p->d_ptr->parent;
- }
-
- // Update graphics effect optimization flag
- if (newParent && (graphicsEffect || mayHaveChildWithGraphicsEffect))
- newParent->d_ptr->updateChildWithGraphicsEffectFlagRecursively();
-
- // Update focus scope item ptr in new scope.
- QGraphicsItem *newFocusScopeItem = subFocusItem ? subFocusItem : parentFocusScopeItem;
- if (newFocusScopeItem && newParent) {
- QGraphicsItem *p = newParent;
- while (p) {
- if (p->d_ptr->flags & QGraphicsItem::ItemIsFocusScope) {
- if (subFocusItem && subFocusItem != q_ptr) {
- // Find the subFocusItem's topmost focus scope within the new parent's focusscope
- QGraphicsItem *ancestorScope = 0;
- QGraphicsItem *p2 = subFocusItem->d_ptr->parent;
- while (p2 && p2 != p) {
- if (p2->d_ptr->flags & QGraphicsItem::ItemIsFocusScope)
- ancestorScope = p2;
- if (p2->d_ptr->flags & QGraphicsItem::ItemIsPanel)
- break;
- if (p2 == q_ptr)
- break;
- p2 = p2->d_ptr->parent;
- }
- if (ancestorScope)
- newFocusScopeItem = ancestorScope;
- }
-
- p->d_ptr->focusScopeItem = newFocusScopeItem;
- newFocusScopeItem->d_ptr->focusScopeItemChange(true);
- // Ensure the new item is no longer the subFocusItem. The
- // only way to set focus on a child of a focus scope is
- // by setting focus on the scope itself.
- if (subFocusItem && !p->focusItem())
- subFocusItem->d_ptr->clearSubFocus();
- break;
- }
- p = p->d_ptr->parent;
- }
- }
-
- // Resolve depth.
- invalidateDepthRecursively();
-
- if ((parent = newParent)) {
- if (parent->d_func()->scene && parent->d_func()->scene != scene) {
- // Move this item to its new parent's scene
- parent->d_func()->scene->addItem(q);
- } else if (!parent->d_func()->scene && scene) {
- // Remove this item from its former scene
- scene->removeItem(q);
- }
-
- parent->d_ptr->addChild(q);
- if (thisPointerVariant)
- parent->itemChange(QGraphicsItem::ItemChildAddedChange, *thisPointerVariant);
- if (scene) {
- // Re-enable scene pos notifications for new ancestors
- if (scenePosDescendants || (flags & QGraphicsItem::ItemSendsScenePositionChanges))
- scene->d_func()->setScenePosItemEnabled(q, true);
- }
-
- // Propagate dirty flags to the new parent
- markParentDirty(/*updateBoundingRect=*/true);
-
- // Inherit ancestor flags from the new parent.
- updateAncestorFlags();
-
- // Update item visible / enabled.
- if (parent->d_ptr->visible != visible) {
- if (!parent->d_ptr->visible || !explicitlyHidden)
- setVisibleHelper(parent->d_ptr->visible, /* explicit = */ false, /* update = */ false);
- }
- if (parent->isEnabled() != enabled) {
- if (!parent->d_ptr->enabled || !explicitlyDisabled)
- setEnabledHelper(parent->d_ptr->enabled, /* explicit = */ false, /* update = */ false);
- }
-
- // Auto-activate if visible and the parent is active.
- if (visible && parent->isActive())
- q->setActive(true);
- } else {
- // Inherit ancestor flags from the new parent.
- updateAncestorFlags();
-
- if (!inDestructor) {
- // Update item visible / enabled.
- if (!visible && !explicitlyHidden)
- setVisibleHelper(true, /* explicit = */ false);
- if (!enabled && !explicitlyDisabled)
- setEnabledHelper(true, /* explicit = */ false);
- }
- }
-
- dirtySceneTransform = 1;
- if (!inDestructor && (transformData || (newParent && newParent->d_ptr->transformData)))
- transformChanged();
-
- // Restore the sub focus chain.
- if (subFocusItem) {
- subFocusItem->d_ptr->setSubFocus(newParent);
- if (parent && parent->isActive())
- subFocusItem->setFocus();
- }
-
- // Deliver post-change notification
- if (newParentVariant)
- q->itemChange(QGraphicsItem::ItemParentHasChanged, *newParentVariant);
-
- if (isObject)
- emit static_cast<QGraphicsObject *>(q)->parentChanged();
-}
-
-/*!
- \internal
-
- Returns the bounding rect of this item's children (excluding itself).
-*/
-void QGraphicsItemPrivate::childrenBoundingRectHelper(QTransform *x, QRectF *rect, QGraphicsItem *topMostEffectItem)
-{
- Q_Q(QGraphicsItem);
-
- QRectF childrenRect;
- QRectF *result = rect;
- rect = &childrenRect;
- const bool setTopMostEffectItem = !topMostEffectItem;
-
- for (int i = 0; i < children.size(); ++i) {
- QGraphicsItem *child = children.at(i);
- QGraphicsItemPrivate *childd = child->d_ptr.data();
- if (setTopMostEffectItem)
- topMostEffectItem = child;
- bool hasPos = !childd->pos.isNull();
- if (hasPos || childd->transformData) {
- // COMBINE
- QTransform matrix = childd->transformToParent();
- if (x)
- matrix *= *x;
- *rect |= matrix.mapRect(child->d_ptr->effectiveBoundingRect(topMostEffectItem));
- if (!childd->children.isEmpty())
- childd->childrenBoundingRectHelper(&matrix, rect, topMostEffectItem);
- } else {
- if (x)
- *rect |= x->mapRect(child->d_ptr->effectiveBoundingRect(topMostEffectItem));
- else
- *rect |= child->d_ptr->effectiveBoundingRect(topMostEffectItem);
- if (!childd->children.isEmpty())
- childd->childrenBoundingRectHelper(x, rect, topMostEffectItem);
- }
- }
-
- if (flags & QGraphicsItem::ItemClipsChildrenToShape){
- if (x)
- *rect &= x->mapRect(q->boundingRect());
- else
- *rect &= q->boundingRect();
- }
-
- *result |= *rect;
-}
-
-void QGraphicsItemPrivate::initStyleOption(QStyleOptionGraphicsItem *option, const QTransform &worldTransform,
- const QRegion &exposedRegion, bool allItems) const
-{
- Q_ASSERT(option);
- Q_Q(const QGraphicsItem);
-
- // Initialize standard QStyleOption values.
- const QRectF brect = q->boundingRect();
- option->state = QStyle::State_None;
- option->rect = brect.toRect();
- option->levelOfDetail = 1;
- option->exposedRect = brect;
- if (selected)
- option->state |= QStyle::State_Selected;
- if (enabled)
- option->state |= QStyle::State_Enabled;
- if (q->hasFocus())
- option->state |= QStyle::State_HasFocus;
- if (scene) {
- if (scene->d_func()->hoverItems.contains(q_ptr))
- option->state |= QStyle::State_MouseOver;
- if (q == scene->mouseGrabberItem())
- option->state |= QStyle::State_Sunken;
- }
-
- if (!(flags & QGraphicsItem::ItemUsesExtendedStyleOption))
- return;
-
- // Initialize QStyleOptionGraphicsItem specific values (matrix, exposedRect).
- option->matrix = worldTransform.toAffine(); //### discards perspective
-
- if (!allItems) {
- // Determine the item's exposed area
- option->exposedRect = QRectF();
- const QTransform reverseMap = worldTransform.inverted();
- const QVector<QRect> exposedRects(exposedRegion.rects());
- for (int i = 0; i < exposedRects.size(); ++i) {
- option->exposedRect |= reverseMap.mapRect(QRectF(exposedRects.at(i)));
- if (option->exposedRect.contains(brect))
- break;
- }
- option->exposedRect &= brect;
- }
-}
-
-/*!
- \internal
-
- Empty all cached pixmaps from the pixmap cache.
-*/
-void QGraphicsItemCache::purge()
-{
- QPixmapCache::remove(key);
- key = QPixmapCache::Key();
- QMutableMapIterator<QPaintDevice *, DeviceData> it(deviceData);
- while (it.hasNext()) {
- DeviceData &data = it.next().value();
- QPixmapCache::remove(data.key);
- data.cacheIndent = QPoint();
- }
- deviceData.clear();
- allExposed = true;
- exposed.clear();
-}
-
-/*!
- Constructs a QGraphicsItem with the given \a parent item.
- It does not modify the parent object returned by QObject::parent().
-
- If \a parent is 0, you can add the item to a scene by calling
- QGraphicsScene::addItem(). The item will then become a top-level item.
-
- \sa QGraphicsScene::addItem(), setParentItem()
-*/
-QGraphicsItem::QGraphicsItem(QGraphicsItem *parent
-#ifndef Q_QDOC
- // obsolete argument
- , QGraphicsScene *scene
-#endif
- )
- : d_ptr(new QGraphicsItemPrivate)
-{
- d_ptr->q_ptr = this;
- setParentItem(parent);
-
- if (scene && parent && parent->scene() != scene) {
- qWarning("QGraphicsItem::QGraphicsItem: ignoring scene (%p), which is"
- " different from parent's scene (%p)",
- scene, parent->scene());
- return;
- }
- if (scene && !parent)
- scene->addItem(this);
-}
-
-/*!
- \internal
-*/
-QGraphicsItem::QGraphicsItem(QGraphicsItemPrivate &dd, QGraphicsItem *parent,
- QGraphicsScene *scene)
- : d_ptr(&dd)
-{
- d_ptr->q_ptr = this;
- setParentItem(parent);
-
- if (scene && parent && parent->scene() != scene) {
- qWarning("QGraphicsItem::QGraphicsItem: ignoring scene (%p), which is"
- " different from parent's scene (%p)",
- scene, parent->scene());
- return;
- }
- if (scene && !parent)
- scene->addItem(this);
-}
-
-/*!
- Destroys the QGraphicsItem and all its children. If this item is currently
- associated with a scene, the item will be removed from the scene before it
- is deleted.
-
- \note It is more efficient to remove the item from the QGraphicsScene before
- destroying the item.
-*/
-QGraphicsItem::~QGraphicsItem()
-{
- if (d_ptr->isObject) {
- QGraphicsObject *o = static_cast<QGraphicsObject *>(this);
- QObjectPrivate *p = QObjectPrivate::get(o);
- p->wasDeleted = true;
- if (p->declarativeData) {
- QAbstractDeclarativeData::destroyed(p->declarativeData, o);
- p->declarativeData = 0;
- }
- }
-
- d_ptr->inDestructor = 1;
- d_ptr->removeExtraItemCache();
-
-#ifndef QT_NO_GESTURES
- if (d_ptr->isObject && !d_ptr->gestureContext.isEmpty()) {
- QGraphicsObject *o = static_cast<QGraphicsObject *>(this);
- if (QGestureManager *manager = QGestureManager::instance()) {
- foreach (Qt::GestureType type, d_ptr->gestureContext.keys())
- manager->cleanupCachedGestures(o, type);
- }
- }
-#endif
-
- clearFocus();
-
- // Update focus scope item ptr.
- QGraphicsItem *p = d_ptr->parent;
- while (p) {
- if (p->flags() & ItemIsFocusScope) {
- if (p->d_ptr->focusScopeItem == this)
- p->d_ptr->focusScopeItem = 0;
- break;
- }
- p = p->d_ptr->parent;
- }
-
- if (!d_ptr->children.isEmpty()) {
- while (!d_ptr->children.isEmpty())
- delete d_ptr->children.first();
- Q_ASSERT(d_ptr->children.isEmpty());
- }
-
- if (d_ptr->scene) {
- d_ptr->scene->d_func()->removeItemHelper(this);
- } else {
- d_ptr->resetFocusProxy();
- setParentItem(0);
- }
-
-#ifndef QT_NO_GRAPHICSEFFECT
- delete d_ptr->graphicsEffect;
-#endif //QT_NO_GRAPHICSEFFECT
- if (d_ptr->transformData) {
- for(int i = 0; i < d_ptr->transformData->graphicsTransforms.size(); ++i) {
- QGraphicsTransform *t = d_ptr->transformData->graphicsTransforms.at(i);
- static_cast<QGraphicsTransformPrivate *>(t->d_ptr.data())->item = 0;
- delete t;
- }
- }
- delete d_ptr->transformData;
-
- if (QGraphicsItemCustomDataStore *dataStore = qt_dataStore())
- dataStore->data.remove(this);
-}
-
-/*!
- Returns the current scene for the item, or 0 if the item is not stored in
- a scene.
-
- To add or move an item to a scene, call QGraphicsScene::addItem().
-*/
-QGraphicsScene *QGraphicsItem::scene() const
-{
- return d_ptr->scene;
-}
-
-/*!
- Returns a pointer to this item's item group, or 0 if this item is not
- member of a group.
-
- \sa QGraphicsItemGroup, QGraphicsScene::createItemGroup()
-*/
-QGraphicsItemGroup *QGraphicsItem::group() const
-{
- if (!d_ptr->isMemberOfGroup)
- return 0;
- QGraphicsItem *parent = const_cast<QGraphicsItem *>(this);
- while ((parent = parent->d_ptr->parent)) {
- if (QGraphicsItemGroup *group = qgraphicsitem_cast<QGraphicsItemGroup *>(parent))
- return group;
- }
- // Unreachable; if d_ptr->isMemberOfGroup is != 0, then one parent of this
- // item is a group item.
- return 0;
-}
-
-/*!
- Adds this item to the item group \a group. If \a group is 0, this item is
- removed from any current group and added as a child of the previous
- group's parent.
-
- \sa group(), QGraphicsScene::createItemGroup()
-*/
-void QGraphicsItem::setGroup(QGraphicsItemGroup *group)
-{
- if (!group) {
- if (QGraphicsItemGroup *group = this->group())
- group->removeFromGroup(this);
- } else {
- group->addToGroup(this);
- }
-}
-
-/*!
- Returns a pointer to this item's parent item. If this item does not have a
- parent, 0 is returned.
-
- \sa setParentItem(), childItems()
-*/
-QGraphicsItem *QGraphicsItem::parentItem() const
-{
- return d_ptr->parent;
-}
-
-/*!
- Returns this item's top-level item. The top-level item is the item's
- topmost ancestor item whose parent is 0. If an item has no parent, its own
- pointer is returned (i.e., a top-level item is its own top-level item).
-
- \sa parentItem()
-*/
-QGraphicsItem *QGraphicsItem::topLevelItem() const
-{
- QGraphicsItem *parent = const_cast<QGraphicsItem *>(this);
- while (QGraphicsItem *grandPa = parent->parentItem())
- parent = grandPa;
- return parent;
-}
-
-/*!
- \since 4.6
-
- Returns a pointer to the item's parent, cast to a QGraphicsObject. returns 0 if the parent item
- is not a QGraphicsObject.
-
- \sa parentItem(), childItems()
-*/
-QGraphicsObject *QGraphicsItem::parentObject() const
-{
- QGraphicsItem *p = d_ptr->parent;
- return (p && p->d_ptr->isObject) ? static_cast<QGraphicsObject *>(p) : 0;
-}
-
-/*!
- \since 4.4
-
- Returns a pointer to the item's parent widget. The item's parent widget is
- the closest parent item that is a widget.
-
- \sa parentItem(), childItems()
-*/
-QGraphicsWidget *QGraphicsItem::parentWidget() const
-{
- QGraphicsItem *p = parentItem();
- while (p && !p->isWidget())
- p = p->parentItem();
- return (p && p->isWidget()) ? static_cast<QGraphicsWidget *>(p) : 0;
-}
-
-/*!
- \since 4.4
-
- Returns a pointer to the item's top level widget (i.e., the item's
- ancestor whose parent is 0, or whose parent is not a widget), or 0 if this
- item does not have a top level widget. If the item is its own top level
- widget, this function returns a pointer to the item itself.
-*/
-QGraphicsWidget *QGraphicsItem::topLevelWidget() const
-{
- if (const QGraphicsWidget *p = parentWidget())
- return p->topLevelWidget();
- return isWidget() ? static_cast<QGraphicsWidget *>(const_cast<QGraphicsItem *>(this)) : 0;
-}
-
-/*!
- \since 4.4
-
- Returns the item's window, or 0 if this item does not have a window. If
- the item is a window, it will return itself. Otherwise it will return the
- closest ancestor that is a window.
-
- \sa QGraphicsWidget::isWindow()
-*/
-QGraphicsWidget *QGraphicsItem::window() const
-{
- QGraphicsItem *p = panel();
- if (p && p->isWindow())
- return static_cast<QGraphicsWidget *>(p);
- return 0;
-}
-
-/*!
- \since 4.6
-
- Returns the item's panel, or 0 if this item does not have a panel. If the
- item is a panel, it will return itself. Otherwise it will return the
- closest ancestor that is a panel.
-
- \sa isPanel(), ItemIsPanel
-*/
-QGraphicsItem *QGraphicsItem::panel() const
-{
- if (d_ptr->flags & ItemIsPanel)
- return const_cast<QGraphicsItem *>(this);
- return d_ptr->parent ? d_ptr->parent->panel() : 0;
-}
-
-/*!
- \since 4.6
-
- Return the graphics item cast to a QGraphicsObject, if the class is actually a
- graphics object, 0 otherwise.
-*/
-QGraphicsObject *QGraphicsItem::toGraphicsObject()
-{
- return d_ptr->isObject ? static_cast<QGraphicsObject *>(this) : 0;
-}
-
-/*!
- \since 4.6
-
- Return the graphics item cast to a QGraphicsObject, if the class is actually a
- graphics object, 0 otherwise.
-*/
-const QGraphicsObject *QGraphicsItem::toGraphicsObject() const
-{
- return d_ptr->isObject ? static_cast<const QGraphicsObject *>(this) : 0;
-}
-
-/*!
- Sets this item's parent item to \a newParent. If this item already
- has a parent, it is first removed from the previous parent. If \a
- newParent is 0, this item will become a top-level item.
-
- Note that this implicitly adds this graphics item to the scene of
- the parent. You should not \l{QGraphicsScene::addItem()}{add} the
- item to the scene yourself.
-
- Calling this function on an item that is an ancestor of \a newParent
- have undefined behaviour.
-
- \sa parentItem(), childItems()
-*/
-void QGraphicsItem::setParentItem(QGraphicsItem *newParent)
-{
- if (newParent == this) {
- qWarning("QGraphicsItem::setParentItem: cannot assign %p as a parent of itself", this);
- return;
- }
- if (newParent == d_ptr->parent)
- return;
-
- const QVariant newParentVariant(itemChange(QGraphicsItem::ItemParentChange,
- QVariant::fromValue<QGraphicsItem *>(newParent)));
- newParent = qvariant_cast<QGraphicsItem *>(newParentVariant);
- if (newParent == d_ptr->parent)
- return;
-
- const QVariant thisPointerVariant(QVariant::fromValue<QGraphicsItem *>(this));
- d_ptr->setParentItemHelper(newParent, &newParentVariant, &thisPointerVariant);
-}
-
-/*!
- \obsolete
-
- Use childItems() instead.
-
- \sa setParentItem()
-*/
-QList<QGraphicsItem *> QGraphicsItem::children() const
-{
- return childItems();
-}
-
-/*!
- \since 4.4
-
- Returns a list of this item's children.
-
- The items are sorted by stacking order. This takes into account both the
- items' insertion order and their Z-values.
-
- \sa setParentItem(), zValue(), {QGraphicsItem#Sorting}{Sorting}
-*/
-QList<QGraphicsItem *> QGraphicsItem::childItems() const
-{
- const_cast<QGraphicsItem *>(this)->d_ptr->ensureSortedChildren();
- return d_ptr->children;
-}
-
-/*!
- \since 4.4
- Returns true if this item is a widget (i.e., QGraphicsWidget); otherwise,
- returns false.
-*/
-bool QGraphicsItem::isWidget() const
-{
- return d_ptr->isWidget;
-}
-
-/*!
- \since 4.4
- Returns true if the item is a QGraphicsWidget window, otherwise returns
- false.
-
- \sa QGraphicsWidget::windowFlags()
-*/
-bool QGraphicsItem::isWindow() const
-{
- return d_ptr->isWidget && (static_cast<const QGraphicsWidget *>(this)->windowType() & Qt::Window);
-}
-
-/*!
- \since 4.6
- Returns true if the item is a panel; otherwise returns false.
-
- \sa QGraphicsItem::panel(), ItemIsPanel
-*/
-bool QGraphicsItem::isPanel() const
-{
- return d_ptr->flags & ItemIsPanel;
-}
-
-/*!
- Returns this item's flags. The flags describe what configurable features
- of the item are enabled and not. For example, if the flags include
- ItemIsFocusable, the item can accept input focus.
-
- By default, no flags are enabled.
-
- \sa setFlags(), setFlag()
-*/
-QGraphicsItem::GraphicsItemFlags QGraphicsItem::flags() const
-{
- return GraphicsItemFlags(d_ptr->flags);
-}
-
-/*!
- If \a enabled is true, the item flag \a flag is enabled; otherwise, it is
- disabled.
-
- \sa flags(), setFlags()
-*/
-void QGraphicsItem::setFlag(GraphicsItemFlag flag, bool enabled)
-{
- if (enabled)
- setFlags(GraphicsItemFlags(d_ptr->flags) | flag);
- else
- setFlags(GraphicsItemFlags(d_ptr->flags) & ~flag);
-}
-
-/*!
- \internal
-
- Sets the flag \a flag on \a item and all its children, to \a enabled.
-*/
-static void _q_qgraphicsItemSetFlag(QGraphicsItem *item, QGraphicsItem::GraphicsItemFlag flag,
- bool enabled)
-{
- if (item->flags() & flag) {
- // If this item already has the correct flag set, we don't have to
- // propagate it.
- return;
- }
- item->setFlag(flag, enabled);
- foreach (QGraphicsItem *child, item->children())
- _q_qgraphicsItemSetFlag(child, flag, enabled);
-}
-
-/*!
- Sets the item flags to \a flags. All flags in \a flags are enabled; all
- flags not in \a flags are disabled.
-
- If the item had focus and \a flags does not enable ItemIsFocusable, the
- item loses focus as a result of calling this function. Similarly, if the
- item was selected, and \a flags does not enabled ItemIsSelectable, the
- item is automatically unselected.
-
- By default, no flags are enabled. (QGraphicsWidget enables the
- ItemSendsGeometryChanges flag by default in order to track position
- changes.)
-
- \sa flags(), setFlag()
-*/
-void QGraphicsItem::setFlags(GraphicsItemFlags flags)
-{
- // Notify change and check for adjustment.
- if (quint32(d_ptr->flags) == quint32(flags))
- return;
- flags = GraphicsItemFlags(itemChange(ItemFlagsChange, quint32(flags)).toUInt());
- if (quint32(d_ptr->flags) == quint32(flags))
- return;
- if (d_ptr->scene && d_ptr->scene->d_func()->indexMethod != QGraphicsScene::NoIndex)
- d_ptr->scene->d_func()->index->itemChange(this, ItemFlagsChange, &flags);
-
- // Flags that alter the geometry of the item (or its children).
- const quint32 geomChangeFlagsMask = (ItemClipsChildrenToShape | ItemClipsToShape | ItemIgnoresTransformations | ItemIsSelectable);
- bool fullUpdate = (quint32(flags) & geomChangeFlagsMask) != (d_ptr->flags & geomChangeFlagsMask);
- if (fullUpdate)
- d_ptr->updatePaintedViewBoundingRects(/*children=*/true);
-
- // Keep the old flags to compare the diff.
- GraphicsItemFlags oldFlags = GraphicsItemFlags(d_ptr->flags);
-
- // Update flags.
- d_ptr->flags = flags;
-
- if (!(d_ptr->flags & ItemIsFocusable) && hasFocus()) {
- // Clear focus on the item if it has focus when the focusable flag
- // is unset.
- clearFocus();
- }
-
- if (!(d_ptr->flags & ItemIsSelectable) && isSelected()) {
- // Unselect the item if it is selected when the selectable flag is
- // unset.
- setSelected(false);
- }
-
- if ((flags & ItemClipsChildrenToShape) != (oldFlags & ItemClipsChildrenToShape)) {
- // Item children clipping changes. Propagate the ancestor flag to
- // all children.
- d_ptr->updateAncestorFlag(ItemClipsChildrenToShape);
- // The childrenBoundingRect is clipped to the boundingRect in case of ItemClipsChildrenToShape,
- // which means we have to invalidate the cached childrenBoundingRect whenever this flag changes.
- d_ptr->dirtyChildrenBoundingRect = 1;
- d_ptr->markParentDirty(true);
- }
-
- if ((flags & ItemIgnoresTransformations) != (oldFlags & ItemIgnoresTransformations)) {
- // Item children clipping changes. Propagate the ancestor flag to
- // all children.
- d_ptr->updateAncestorFlag(ItemIgnoresTransformations);
- }
-
- if ((flags & ItemNegativeZStacksBehindParent) != (oldFlags & ItemNegativeZStacksBehindParent)) {
- // NB! We change the flags directly here, so we must also update d_ptr->flags.
- // Note that this has do be done before the ItemStacksBehindParent check
- // below; otherwise we will loose the change.
-
- // Update stack-behind.
- if (d_ptr->z < qreal(0.0))
- flags |= ItemStacksBehindParent;
- else
- flags &= ~ItemStacksBehindParent;
- d_ptr->flags = flags;
- }
-
- if ((flags & ItemStacksBehindParent) != (oldFlags & ItemStacksBehindParent)) {
- // NB! This check has to come after the ItemNegativeZStacksBehindParent
- // check above. Be careful.
-
- // Ensure child item sorting is up to date when toggling this flag.
- if (d_ptr->parent)
- d_ptr->parent->d_ptr->needSortChildren = 1;
- else if (d_ptr->scene)
- d_ptr->scene->d_func()->needSortTopLevelItems = 1;
- }
-
- if ((flags & ItemAcceptsInputMethod) != (oldFlags & ItemAcceptsInputMethod)) {
- // Update input method sensitivity in any views.
- if (d_ptr->scene)
- d_ptr->scene->d_func()->updateInputMethodSensitivityInViews();
- }
-
-
- if ((d_ptr->panelModality != NonModal)
- && d_ptr->scene
- && (flags & ItemIsPanel) != (oldFlags & ItemIsPanel)) {
- // update the panel's modal state
- if (flags & ItemIsPanel)
- d_ptr->scene->d_func()->enterModal(this);
- else
- d_ptr->scene->d_func()->leaveModal(this);
- }
-
- if (d_ptr->scene) {
- if ((flags & ItemSendsScenePositionChanges) != (oldFlags & ItemSendsScenePositionChanges)) {
- if (flags & ItemSendsScenePositionChanges)
- d_ptr->scene->d_func()->registerScenePosItem(this);
- else
- d_ptr->scene->d_func()->unregisterScenePosItem(this);
- }
- d_ptr->scene->d_func()->markDirty(this, QRectF(), /*invalidateChildren=*/true);
- }
-
- // Notify change.
- itemChange(ItemFlagsHaveChanged, quint32(flags));
-}
-
-/*!
- \since 4.4
- Returns the cache mode for this item. The default mode is NoCache (i.e.,
- cache is disabled and all painting is immediate).
-
- \sa setCacheMode()
-*/
-QGraphicsItem::CacheMode QGraphicsItem::cacheMode() const
-{
- return QGraphicsItem::CacheMode(d_ptr->cacheMode);
-}
-
-/*!
- \since 4.4
- Sets the item's cache mode to \a mode.
-
- The optional \a logicalCacheSize argument is used only by
- ItemCoordinateCache mode, and describes the resolution of the cache
- buffer; if \a logicalCacheSize is (100, 100), QGraphicsItem will fit the
- item into 100x100 pixels in graphics memory, regardless of the logical
- size of the item itself. By default QGraphicsItem uses the size of
- boundingRect(). For all other cache modes than ItemCoordinateCache, \a
- logicalCacheSize is ignored.
-
- Caching can speed up rendering if your item spends a significant time
- redrawing itself. In some cases the cache can also slow down rendering, in
- particular when the item spends less time redrawing than QGraphicsItem
- spends redrawing from the cache. When enabled, the item's paint() function
- will be called only once for each call to update(); for any subsequent
- repaint requests, the Graphics View framework will redraw from the
- cache. This approach works particularly well with QGLWidget, which stores
- all the cache as OpenGL textures.
-
- Be aware that QPixmapCache's cache limit may need to be changed to obtain
- optimal performance.
-
- You can read more about the different cache modes in the CacheMode
- documentation.
-
- \sa CacheMode, QPixmapCache::setCacheLimit()
-*/
-void QGraphicsItem::setCacheMode(CacheMode mode, const QSize &logicalCacheSize)
-{
- CacheMode lastMode = CacheMode(d_ptr->cacheMode);
- d_ptr->cacheMode = mode;
- bool noVisualChange = (mode == NoCache && lastMode == NoCache)
- || (mode == NoCache && lastMode == DeviceCoordinateCache)
- || (mode == DeviceCoordinateCache && lastMode == NoCache)
- || (mode == DeviceCoordinateCache && lastMode == DeviceCoordinateCache);
- if (mode == NoCache) {
- d_ptr->removeExtraItemCache();
- } else {
- QGraphicsItemCache *cache = d_ptr->extraItemCache();
-
- // Reset old cache
- cache->purge();
-
- if (mode == ItemCoordinateCache) {
- if (lastMode == mode && cache->fixedSize == logicalCacheSize)
- noVisualChange = true;
- cache->fixedSize = logicalCacheSize;
- }
- }
- if (!noVisualChange)
- update();
-}
-
-/*!
- \since 4.6
-
- Returns the modality for this item.
-*/
-QGraphicsItem::PanelModality QGraphicsItem::panelModality() const
-{
- return d_ptr->panelModality;
-}
-
-/*!
- \since 4.6
-
- Sets the modality for this item to \a panelModality.
-
- Changing the modality of a visible item takes effect immediately.
-*/
-void QGraphicsItem::setPanelModality(PanelModality panelModality)
-{
- if (d_ptr->panelModality == panelModality)
- return;
-
- PanelModality previousModality = d_ptr->panelModality;
- bool enterLeaveModal = (isPanel() && d_ptr->scene && isVisible());
- if (enterLeaveModal && panelModality == NonModal)
- d_ptr->scene->d_func()->leaveModal(this);
- d_ptr->panelModality = panelModality;
- if (enterLeaveModal && d_ptr->panelModality != NonModal)
- d_ptr->scene->d_func()->enterModal(this, previousModality);
-}
-
-/*!
- \since 4.6
-
- Returns true if this item is blocked by a modal panel, false otherwise. If \a blockingPanel is
- non-zero, \a blockingPanel will be set to the modal panel that is blocking this item. If this
- item is not blocked, \a blockingPanel will not be set by this function.
-
- This function always returns false for items not in a scene.
-
- \sa panelModality() setPanelModality() PanelModality
-*/
-bool QGraphicsItem::isBlockedByModalPanel(QGraphicsItem **blockingPanel) const
-{
- if (!d_ptr->scene)
- return false;
-
-
- QGraphicsItem *dummy = 0;
- if (!blockingPanel)
- blockingPanel = &dummy;
-
- QGraphicsScenePrivate *scene_d = d_ptr->scene->d_func();
- if (scene_d->modalPanels.isEmpty())
- return false;
-
- // ###
- if (!scene_d->popupWidgets.isEmpty() && scene_d->popupWidgets.first() == this)
- return false;
-
- for (int i = 0; i < scene_d->modalPanels.count(); ++i) {
- QGraphicsItem *modalPanel = scene_d->modalPanels.at(i);
- if (modalPanel->panelModality() == QGraphicsItem::SceneModal) {
- // Scene modal panels block all non-descendents.
- if (modalPanel != this && !modalPanel->isAncestorOf(this)) {
- *blockingPanel = modalPanel;
- return true;
- }
- } else {
- // Window modal panels block ancestors and siblings/cousins.
- if (modalPanel != this
- && !modalPanel->isAncestorOf(this)
- && commonAncestorItem(modalPanel)) {
- *blockingPanel = modalPanel;
- return true;
- }
- }
- }
- return false;
-}
-
-#ifndef QT_NO_TOOLTIP
-/*!
- Returns the item's tool tip, or an empty QString if no tool tip has been
- set.
-
- \sa setToolTip(), QToolTip
-*/
-QString QGraphicsItem::toolTip() const
-{
- return d_ptr->extra(QGraphicsItemPrivate::ExtraToolTip).toString();
-}
-
-/*!
- Sets the item's tool tip to \a toolTip. If \a toolTip is empty, the item's
- tool tip is cleared.
-
- \sa toolTip(), QToolTip
-*/
-void QGraphicsItem::setToolTip(const QString &toolTip)
-{
- const QVariant toolTipVariant(itemChange(ItemToolTipChange, toolTip));
- d_ptr->setExtra(QGraphicsItemPrivate::ExtraToolTip, toolTipVariant.toString());
- itemChange(ItemToolTipHasChanged, toolTipVariant);
-}
-#endif // QT_NO_TOOLTIP
-
-#ifndef QT_NO_CURSOR
-/*!
- Returns the current cursor shape for the item. The mouse cursor
- will assume this shape when it's over this item. See the \link
- Qt::CursorShape list of predefined cursor objects\endlink for a
- range of useful shapes.
-
- An editor item might want to use an I-beam cursor:
-
- \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 2
-
- If no cursor has been set, the cursor of the item beneath is used.
-
- \sa setCursor(), hasCursor(), unsetCursor(), QWidget::cursor,
- QApplication::overrideCursor()
-*/
-QCursor QGraphicsItem::cursor() const
-{
- return qvariant_cast<QCursor>(d_ptr->extra(QGraphicsItemPrivate::ExtraCursor));
-}
-
-/*!
- Sets the current cursor shape for the item to \a cursor. The mouse cursor
- will assume this shape when it's over this item. See the \link
- Qt::CursorShape list of predefined cursor objects\endlink for a range of
- useful shapes.
-
- An editor item might want to use an I-beam cursor:
-
- \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 3
-
- If no cursor has been set, the cursor of the item beneath is used.
-
- \sa cursor(), hasCursor(), unsetCursor(), QWidget::cursor,
- QApplication::overrideCursor()
-*/
-void QGraphicsItem::setCursor(const QCursor &cursor)
-{
- const QVariant cursorVariant(itemChange(ItemCursorChange, QVariant::fromValue<QCursor>(cursor)));
- d_ptr->setExtra(QGraphicsItemPrivate::ExtraCursor, qvariant_cast<QCursor>(cursorVariant));
- d_ptr->hasCursor = 1;
- if (d_ptr->scene) {
- d_ptr->scene->d_func()->allItemsUseDefaultCursor = false;
- foreach (QGraphicsView *view, d_ptr->scene->views()) {
- view->viewport()->setMouseTracking(true);
- // Note: Some of this logic is duplicated in QGraphicsView's mouse events.
- if (view->underMouse()) {
- foreach (QGraphicsItem *itemUnderCursor, view->items(view->mapFromGlobal(QCursor::pos()))) {
- if (itemUnderCursor->hasCursor()) {
- QMetaObject::invokeMethod(view, "_q_setViewportCursor",
- Q_ARG(QCursor, itemUnderCursor->cursor()));
- break;
- }
- }
- break;
- }
- }
- }
- itemChange(ItemCursorHasChanged, cursorVariant);
-}
-
-/*!
- Returns true if this item has a cursor set; otherwise, false is returned.
-
- By default, items don't have any cursor set. cursor() will return a
- standard pointing arrow cursor.
-
- \sa unsetCursor()
-*/
-bool QGraphicsItem::hasCursor() const
-{
- return d_ptr->hasCursor;
-}
-
-/*!
- Clears the cursor from this item.
-
- \sa hasCursor(), setCursor()
-*/
-void QGraphicsItem::unsetCursor()
-{
- d_ptr->unsetExtra(QGraphicsItemPrivate::ExtraCursor);
- d_ptr->hasCursor = 0;
- if (d_ptr->scene) {
- foreach (QGraphicsView *view, d_ptr->scene->views()) {
- if (view->underMouse() && view->itemAt(view->mapFromGlobal(QCursor::pos())) == this) {
- QMetaObject::invokeMethod(view, "_q_unsetViewportCursor");
- break;
- }
- }
- }
-}
-
-#endif // QT_NO_CURSOR
-
-/*!
- Returns true if the item is visible; otherwise, false is returned.
-
- Note that the item's general visibility is unrelated to whether or not it
- is actually being visualized by a QGraphicsView.
-
- \sa setVisible()
-*/
-bool QGraphicsItem::isVisible() const
-{
- return d_ptr->visible;
-}
-
-/*!
- \since 4.4
- Returns true if the item is visible to \a parent; otherwise, false is
- returned. \a parent can be 0, in which case this function will return
- whether the item is visible to the scene or not.
-
- An item may not be visible to its ancestors even if isVisible() is true. If
- any ancestor is hidden, the item itself will be implicitly hidden, in which
- case this function will return false.
-
- \sa isVisible(), setVisible()
-*/
-bool QGraphicsItem::isVisibleTo(const QGraphicsItem *parent) const
-{
- if (!d_ptr->visible)
- return false;
- if (parent == this)
- return true;
- if (parentItem() && parentItem()->isVisibleTo(parent))
- return true;
- if (!parent && !parentItem())
- return true;
- return false;
-}
-
-/*!
- \internal
-
- Sets this item's visibility to \a newVisible. If \a explicitly is true,
- this item will be "explicitly" \a newVisible; otherwise, it.. will not be.
-*/
-void QGraphicsItemPrivate::setVisibleHelper(bool newVisible, bool explicitly, bool update)
-{
- Q_Q(QGraphicsItem);
-
- // Update explicit bit.
- if (explicitly)
- explicitlyHidden = newVisible ? 0 : 1;
-
- // Check if there's nothing to do.
- if (visible == quint32(newVisible))
- return;
-
- // Don't show child if parent is not visible
- if (parent && newVisible && !parent->d_ptr->visible)
- return;
-
- // Modify the property.
- const QVariant newVisibleVariant(q_ptr->itemChange(QGraphicsItem::ItemVisibleChange,
- quint32(newVisible)));
- newVisible = newVisibleVariant.toBool();
- if (visible == quint32(newVisible))
- return;
- visible = newVisible;
-
- // Schedule redrawing
- if (update) {
- QGraphicsItemCache *c = (QGraphicsItemCache *)qvariant_cast<void *>(extra(ExtraCacheData));
- if (c)
- c->purge();
- if (scene) {
-#ifndef QT_NO_GRAPHICSEFFECT
- invalidateParentGraphicsEffectsRecursively();
-#endif //QT_NO_GRAPHICSEFFECT
- scene->d_func()->markDirty(q_ptr, QRectF(), /*invalidateChildren=*/false, /*force=*/true);
- }
- }
-
- // Certain properties are dropped as an item becomes invisible.
- bool hasFocus = q_ptr->hasFocus();
- if (!newVisible) {
- if (scene) {
- if (scene->d_func()->mouseGrabberItems.contains(q))
- q->ungrabMouse();
- if (scene->d_func()->keyboardGrabberItems.contains(q))
- q->ungrabKeyboard();
- if (q->isPanel() && panelModality != QGraphicsItem::NonModal)
- scene->d_func()->leaveModal(q_ptr);
- }
- if (hasFocus && scene) {
- // Hiding the closest non-panel ancestor of the focus item
- QGraphicsItem *focusItem = scene->focusItem();
- bool clear = true;
- if (isWidget && !focusItem->isPanel()) {
- do {
- if (focusItem == q_ptr) {
- clear = !static_cast<QGraphicsWidget *>(q_ptr)->focusNextPrevChild(true);
- break;
- }
- } while ((focusItem = focusItem->parentWidget()) && !focusItem->isPanel());
- }
- if (clear)
- clearFocusHelper(/* giveFocusToParent = */ false);
- }
- if (q_ptr->isSelected())
- q_ptr->setSelected(false);
- } else {
- geometryChanged = 1;
- paintedViewBoundingRectsNeedRepaint = 1;
- if (scene) {
- if (isWidget) {
- QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(q_ptr);
- if (widget->windowType() == Qt::Popup)
- scene->d_func()->addPopup(widget);
- }
- if (q->isPanel() && panelModality != QGraphicsItem::NonModal) {
- scene->d_func()->enterModal(q_ptr);
- }
- }
- }
-
- // 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, updateChildren);
- }
-
- // Update activation
- if (scene && q->isPanel()) {
- if (newVisible) {
- if (parent && parent->isActive())
- q->setActive(true);
- } else {
- if (q->isActive())
- scene->setActivePanel(parent);
- }
- }
-
- // Enable subfocus
- if (scene) {
- if (newVisible) {
- // Item is shown
- QGraphicsItem *p = parent;
- bool done = false;
- while (p) {
- if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
- QGraphicsItem *fsi = p->d_ptr->focusScopeItem;
- if (q_ptr == fsi || q_ptr->isAncestorOf(fsi)) {
- done = true;
- while (fsi->d_ptr->focusScopeItem && fsi->d_ptr->focusScopeItem->isVisible())
- fsi = fsi->d_ptr->focusScopeItem;
- fsi->d_ptr->setFocusHelper(Qt::OtherFocusReason, /* climb = */ true,
- /* focusFromHide = */ false);
- }
- break;
- }
- p = p->d_ptr->parent;
- }
- if (!done) {
- QGraphicsItem *fi = subFocusItem;
- if (fi && fi != scene->focusItem()) {
- scene->setFocusItem(fi);
- } else if (flags & QGraphicsItem::ItemIsFocusScope &&
- !scene->focusItem() &&
- q->isAncestorOf(scene->d_func()->lastFocusItem)) {
- q_ptr->setFocus();
- }
- }
- } else {
- // Item is hidden
- if (hasFocus) {
- QGraphicsItem *p = parent;
- while (p) {
- if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
- if (p->d_ptr->visible) {
- p->d_ptr->setFocusHelper(Qt::OtherFocusReason, /* climb = */ true,
- /* focusFromHide = */ true);
- }
- break;
- }
- p = p->d_ptr->parent;
- }
- }
- }
- }
-
- // Deliver post-change notification.
- q_ptr->itemChange(QGraphicsItem::ItemVisibleHasChanged, newVisibleVariant);
-
- if (isObject)
- emit static_cast<QGraphicsObject *>(q_ptr)->visibleChanged();
-}
-
-/*!
- If \a visible is true, the item is made visible. Otherwise, the item is
- made invisible. Invisible items are not painted, nor do they receive any
- events. In particular, mouse events pass right through invisible items,
- and are delivered to any item that may be behind. Invisible items are also
- unselectable, they cannot take input focus, and are not detected by
- QGraphicsScene's item location functions.
-
- If an item becomes invisible while grabbing the mouse, (i.e., while it is
- receiving mouse events,) it will automatically lose the mouse grab, and
- the grab is not regained by making the item visible again; it must receive
- a new mouse press to regain the mouse grab.
-
- Similarly, an invisible item cannot have focus, so if the item has focus
- when it becomes invisible, it will lose focus, and the focus is not
- regained by simply making the item visible again.
-
- If you hide a parent item, all its children will also be hidden. If you
- show a parent item, all children will be shown, unless they have been
- explicitly hidden (i.e., if you call setVisible(false) on a child, it will
- not be reshown even if its parent is hidden, and then shown again).
-
- Items are visible by default; it is unnecessary to call
- setVisible() on a new item.
-
- \sa isVisible(), show(), hide()
-*/
-void QGraphicsItem::setVisible(bool visible)
-{
- d_ptr->setVisibleHelper(visible, /* explicit = */ true);
-}
-
-/*!
- \fn void QGraphicsItem::hide()
-
- Hides the item. (Items are visible by default.)
-
- This convenience function is equivalent to calling \c setVisible(false).
-
- \sa show(), setVisible()
-*/
-
-/*!
- \fn void QGraphicsItem::show()
-
- Shows the item. (Items are visible by default.)
-
- This convenience function is equivalent to calling \c setVisible(true).
-
- \sa hide(), setVisible()
-*/
-
-/*!
- Returns true if the item is enabled; otherwise, false is returned.
-
- \sa setEnabled()
-*/
-bool QGraphicsItem::isEnabled() const
-{
- return d_ptr->enabled;
-}
-
-/*!
- \internal
-
- Sets this item's visibility to \a newEnabled. If \a explicitly is true,
- this item will be "explicitly" \a newEnabled; otherwise, it.. will not be.
-*/
-void QGraphicsItemPrivate::setEnabledHelper(bool newEnabled, bool explicitly, bool update)
-{
- // Update explicit bit.
- if (explicitly)
- explicitlyDisabled = newEnabled ? 0 : 1;
-
- // Check if there's nothing to do.
- if (enabled == quint32(newEnabled))
- return;
-
- // Certain properties are dropped when an item is disabled.
- if (!newEnabled) {
- if (scene && scene->mouseGrabberItem() == q_ptr)
- q_ptr->ungrabMouse();
- if (q_ptr->hasFocus()) {
- // Disabling the closest non-panel ancestor of the focus item
- // causes focus to pop to the next item, otherwise it's cleared.
- QGraphicsItem *focusItem = scene->focusItem();
- bool clear = true;
- if (isWidget && !focusItem->isPanel() && q_ptr->isAncestorOf(focusItem)) {
- do {
- if (focusItem == q_ptr) {
- clear = !static_cast<QGraphicsWidget *>(q_ptr)->focusNextPrevChild(true);
- break;
- }
- } while ((focusItem = focusItem->parentWidget()) && !focusItem->isPanel());
- }
- if (clear)
- q_ptr->clearFocus();
- }
- if (q_ptr->isSelected())
- q_ptr->setSelected(false);
- }
-
- // Modify the property.
- const QVariant newEnabledVariant(q_ptr->itemChange(QGraphicsItem::ItemEnabledChange,
- quint32(newEnabled)));
- enabled = newEnabledVariant.toBool();
-
- // Schedule redraw.
- if (update)
- q_ptr->update();
-
- foreach (QGraphicsItem *child, children) {
- if (!newEnabled || !child->d_ptr->explicitlyDisabled)
- child->d_ptr->setEnabledHelper(newEnabled, /* explicitly = */ false);
- }
-
- // Deliver post-change notification.
- q_ptr->itemChange(QGraphicsItem::ItemEnabledHasChanged, newEnabledVariant);
-
- if (isObject)
- emit static_cast<QGraphicsObject *>(q_ptr)->enabledChanged();
-}
-
-/*!
- If \a enabled is true, the item is enabled; otherwise, it is disabled.
-
- Disabled items are visible, but they do not receive any events, and cannot
- take focus nor be selected. Mouse events are discarded; they are not
- propagated unless the item is also invisible, or if it does not accept
- mouse events (see acceptedMouseButtons()). A disabled item cannot become the
- mouse grabber, and as a result of this, an item loses the grab if it
- becomes disabled when grabbing the mouse, just like it loses focus if it
- had focus when it was disabled.
-
- Disabled items are traditionally drawn using grayed-out colors (see \l
- QPalette::Disabled).
-
- If you disable a parent item, all its children will also be disabled. If
- you enable a parent item, all children will be enabled, unless they have
- been explicitly disabled (i.e., if you call setEnabled(false) on a child,
- it will not be reenabled if its parent is disabled, and then enabled
- again).
-
- Items are enabled by default.
-
- \note If you install an event filter, you can still intercept events
- before they are delivered to items; this mechanism disregards the item's
- enabled state.
-
- \sa isEnabled()
-*/
-void QGraphicsItem::setEnabled(bool enabled)
-{
- d_ptr->setEnabledHelper(enabled, /* explicitly = */ true);
-}
-
-/*!
- Returns true if this item is selected; otherwise, false is returned.
-
- Items that are in a group inherit the group's selected state.
-
- Items are not selected by default.
-
- \sa setSelected(), QGraphicsScene::setSelectionArea()
-*/
-bool QGraphicsItem::isSelected() const
-{
- if (QGraphicsItemGroup *group = this->group())
- return group->isSelected();
- return d_ptr->selected;
-}
-
-/*!
- If \a selected is true and this item is selectable, this item is selected;
- otherwise, it is unselected.
-
- If the item is in a group, the whole group's selected state is toggled by
- this function. If the group is selected, all items in the group are also
- selected, and if the group is not selected, no item in the group is
- selected.
-
- Only visible, enabled, selectable items can be selected. If \a selected
- is true and this item is either invisible or disabled or unselectable,
- this function does nothing.
-
- By default, items cannot be selected. To enable selection, set the
- ItemIsSelectable flag.
-
- This function is provided for convenience, allowing individual toggling of
- the selected state of an item. However, a more common way of selecting
- items is to call QGraphicsScene::setSelectionArea(), which will call this
- function for all visible, enabled, and selectable items within a specified
- area on the scene.
-
- \sa isSelected(), QGraphicsScene::selectedItems()
-*/
-void QGraphicsItem::setSelected(bool selected)
-{
- if (QGraphicsItemGroup *group = this->group()) {
- group->setSelected(selected);
- return;
- }
-
- if (!(d_ptr->flags & ItemIsSelectable) || !d_ptr->enabled || !d_ptr->visible)
- selected = false;
- if (d_ptr->selected == selected)
- return;
- const QVariant newSelectedVariant(itemChange(ItemSelectedChange, quint32(selected)));
- bool newSelected = newSelectedVariant.toBool();
- if (d_ptr->selected == newSelected)
- return;
- d_ptr->selected = newSelected;
-
- update();
- if (d_ptr->scene) {
- QGraphicsScenePrivate *sceneD = d_ptr->scene->d_func();
- if (selected) {
- sceneD->selectedItems << this;
- } else {
- // QGraphicsScene::selectedItems() lazily pulls out all items that are
- // no longer selected.
- }
- if (!sceneD->selectionChanging)
- emit d_ptr->scene->selectionChanged();
- }
-
- // Deliver post-change notification.
- itemChange(QGraphicsItem::ItemSelectedHasChanged, newSelectedVariant);
-}
-
-/*!
- \since 4.5
-
- Returns this item's local opacity, which is between 0.0 (transparent) and
- 1.0 (opaque). This value is combined with parent and ancestor values into
- the effectiveOpacity(). The effective opacity decides how the item is
- rendered.
-
- The opacity property decides the state of the painter passed to the
- paint() function. If the item is cached, i.e., ItemCoordinateCache or
- DeviceCoordinateCache, the effective property will be applied to the item's
- cache as it is rendered.
-
- The default opacity is 1.0; fully opaque.
-
- \sa setOpacity(), paint(), ItemIgnoresParentOpacity,
- ItemDoesntPropagateOpacityToChildren
-*/
-qreal QGraphicsItem::opacity() const
-{
- return d_ptr->opacity;
-}
-
-/*!
- \since 4.5
-
- Returns this item's \e effective opacity, which is between 0.0
- (transparent) and 1.0 (opaque). This value is a combination of this item's
- local opacity, and its parent and ancestors' opacities. The effective
- opacity decides how the item is rendered.
-
- \sa opacity(), setOpacity(), paint(), ItemIgnoresParentOpacity,
- ItemDoesntPropagateOpacityToChildren
-*/
-qreal QGraphicsItem::effectiveOpacity() const
-{
- return d_ptr->effectiveOpacity();
-}
-
-/*!
- \since 4.5
-
- Sets this item's local \a opacity, between 0.0 (transparent) and 1.0
- (opaque). The item's local opacity is combined with parent and ancestor
- opacities into the effectiveOpacity().
-
- By default, opacity propagates from parent to child, so if a parent's
- opacity is 0.5 and the child is also 0.5, the child's effective opacity
- will be 0.25.
-
- The opacity property decides the state of the painter passed to the
- paint() function. If the item is cached, i.e., ItemCoordinateCache or
- DeviceCoordinateCache, the effective property will be applied to the
- item's cache as it is rendered.
-
- There are two item flags that affect how the item's opacity is combined
- with the parent: ItemIgnoresParentOpacity and
- ItemDoesntPropagateOpacityToChildren.
-
- \sa opacity(), effectiveOpacity()
-*/
-void QGraphicsItem::setOpacity(qreal opacity)
-{
- // Notify change.
- const QVariant newOpacityVariant(itemChange(ItemOpacityChange, opacity));
-
- // Normalized opacity
- qreal newOpacity = qBound(qreal(0), newOpacityVariant.toReal(), qreal(1));
-
- // No change? Done.
- if (newOpacity == d_ptr->opacity)
- return;
-
- bool wasFullyTransparent = d_ptr->isOpacityNull();
- d_ptr->opacity = newOpacity;
-
- // Notify change.
- itemChange(ItemOpacityHasChanged, newOpacityVariant);
-
- // Update.
- if (d_ptr->scene) {
-#ifndef QT_NO_GRAPHICSEFFECT
- d_ptr->invalidateParentGraphicsEffectsRecursively();
- if (!(d_ptr->flags & ItemDoesntPropagateOpacityToChildren))
- d_ptr->invalidateChildGraphicsEffectsRecursively(QGraphicsItemPrivate::OpacityChanged);
-#endif //QT_NO_GRAPHICSEFFECT
- d_ptr->scene->d_func()->markDirty(this, QRectF(),
- /*invalidateChildren=*/true,
- /*force=*/false,
- /*ignoreOpacity=*/d_ptr->isOpacityNull());
- if (wasFullyTransparent)
- d_ptr->paintedViewBoundingRectsNeedRepaint = 1;
- }
-
- if (d_ptr->isObject)
- emit static_cast<QGraphicsObject *>(this)->opacityChanged();
-}
-
-/*!
- Returns a pointer to this item's effect if it has one; otherwise 0.
-
- \since 4.6
-*/
-#ifndef QT_NO_GRAPHICSEFFECT
-QGraphicsEffect *QGraphicsItem::graphicsEffect() const
-{
- return d_ptr->graphicsEffect;
-}
-
-/*!
- Sets \a effect as the item's effect. If there already is an effect installed
- on this item, QGraphicsItem will delete the existing effect before installing
- the new \a effect.
-
- If \a effect is the installed on a different item, setGraphicsEffect() will remove
- the effect from the item and install it on this item.
-
- QGraphicsItem takes ownership of \a effect.
-
- \note This function will apply the effect on itself and all its children.
-
- \since 4.6
-*/
-void QGraphicsItem::setGraphicsEffect(QGraphicsEffect *effect)
-{
- if (d_ptr->graphicsEffect == effect)
- return;
-
- if (d_ptr->graphicsEffect) {
- delete d_ptr->graphicsEffect;
- d_ptr->graphicsEffect = 0;
- } else if (d_ptr->parent) {
- d_ptr->parent->d_ptr->updateChildWithGraphicsEffectFlagRecursively();
- }
-
- if (effect) {
- // Set new effect.
- QGraphicsEffectSourcePrivate *sourced = new QGraphicsItemEffectSourcePrivate(this);
- QGraphicsEffectSource *source = new QGraphicsEffectSource(*sourced);
- d_ptr->graphicsEffect = effect;
- effect->d_func()->setGraphicsEffectSource(source);
- prepareGeometryChange();
- }
-}
-#endif //QT_NO_GRAPHICSEFFECT
-
-void QGraphicsItemPrivate::updateChildWithGraphicsEffectFlagRecursively()
-{
-#ifndef QT_NO_GRAPHICSEFFECT
- QGraphicsItemPrivate *itemPrivate = this;
- do {
- // parent chain already notified?
- if (itemPrivate->mayHaveChildWithGraphicsEffect)
- return;
- itemPrivate->mayHaveChildWithGraphicsEffect = 1;
- } while ((itemPrivate = itemPrivate->parent ? itemPrivate->parent->d_ptr.data() : 0));
-#endif
-}
-
-/*!
- \internal
- \since 4.6
- Returns the effective bounding rect of the given item space rect.
- If the item has no effect, the rect is returned unmodified.
- If the item has an effect, the effective rect can be extend beyond the
- item's bounding rect, depending on the effect.
-
- \sa boundingRect()
-*/
-QRectF QGraphicsItemPrivate::effectiveBoundingRect(const QRectF &rect) const
-{
-#ifndef QT_NO_GRAPHICSEFFECT
- Q_Q(const QGraphicsItem);
- QGraphicsEffect *effect = graphicsEffect;
- if (scene && effect && effect->isEnabled()) {
- if (scene->d_func()->views.isEmpty())
- return effect->boundingRectFor(rect);
- QRectF sceneRect = q->mapRectToScene(rect);
- QRectF sceneEffectRect;
- foreach (QGraphicsView *view, scene->views()) {
- QRectF deviceRect = view->d_func()->mapRectFromScene(sceneRect);
- QRect deviceEffectRect = effect->boundingRectFor(deviceRect).toAlignedRect();
- sceneEffectRect |= view->d_func()->mapRectToScene(deviceEffectRect);
- }
- return q->mapRectFromScene(sceneEffectRect);
- }
-#endif //QT_NO_GRAPHICSEFFECT
- return rect;
-}
-
-/*!
- \internal
- \since 4.6
- Returns the effective bounding rect of the item.
- If the item has no effect, this is the same as the item's bounding rect.
- If the item has an effect, the effective rect can be larger than the item's
- bouding rect, depending on the effect.
-
- \sa boundingRect()
-*/
-QRectF QGraphicsItemPrivate::effectiveBoundingRect(QGraphicsItem *topMostEffectItem) const
-{
-#ifndef QT_NO_GRAPHICSEFFECT
- Q_Q(const QGraphicsItem);
- QRectF brect = effectiveBoundingRect(q_ptr->boundingRect());
- if (ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren || topMostEffectItem == q)
- return brect;
-
- const QGraphicsItem *effectParent = parent;
- while (effectParent) {
- QGraphicsEffect *effect = effectParent->d_ptr->graphicsEffect;
- if (scene && effect && effect->isEnabled()) {
- const QRectF brectInParentSpace = q->mapRectToItem(effectParent, brect);
- const QRectF effectRectInParentSpace = effectParent->d_ptr->effectiveBoundingRect(brectInParentSpace);
- brect = effectParent->mapRectToItem(q, effectRectInParentSpace);
- }
- if (effectParent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren
- || topMostEffectItem == effectParent) {
- return brect;
- }
- effectParent = effectParent->d_ptr->parent;
- }
-
- return brect;
-#else //QT_NO_GRAPHICSEFFECT
- return q_ptr->boundingRect();
-#endif //QT_NO_GRAPHICSEFFECT
-
-}
-
-/*!
- \internal
- \since 4.6
- Returns the effective bounding rect of this item in scene coordinates,
- by combining sceneTransform() with boundingRect(), taking into account
- the effect that the item might have.
-
- If the item has no effect, this is the same as sceneBoundingRect().
-
- \sa effectiveBoundingRect(), sceneBoundingRect()
-*/
-QRectF QGraphicsItemPrivate::sceneEffectiveBoundingRect() const
-{
- // Find translate-only offset
- // COMBINE
- QPointF offset;
- const QGraphicsItem *parentItem = q_ptr;
- const QGraphicsItemPrivate *itemd;
- do {
- itemd = parentItem->d_ptr.data();
- if (itemd->transformData)
- break;
- offset += itemd->pos;
- } while ((parentItem = itemd->parent));
-
- QRectF br = effectiveBoundingRect();
- br.translate(offset);
- return !parentItem ? br : parentItem->sceneTransform().mapRect(br);
-}
-
-/*!
- Returns true if this item can accept drag and drop events; otherwise,
- returns false. By default, items do not accept drag and drop events; items
- are transparent to drag and drop.
-
- \sa setAcceptDrops()
-*/
-bool QGraphicsItem::acceptDrops() const
-{
- return d_ptr->acceptDrops;
-}
-
-/*!
- If \a on is true, this item will accept drag and drop events; otherwise,
- it is transparent for drag and drop events. By default, items do not
- accept drag and drop events.
-
- \sa acceptDrops()
-*/
-void QGraphicsItem::setAcceptDrops(bool on)
-{
- d_ptr->acceptDrops = on;
-}
-
-/*!
- Returns the mouse buttons that this item accepts mouse events for. By
- default, all mouse buttons are accepted.
-
- If an item accepts a mouse button, it will become the mouse
- grabber item when a mouse press event is delivered for that mouse
- button. However, if the item does not accept the button,
- QGraphicsScene will forward the mouse events to the first item
- beneath it that does.
-
- \sa setAcceptedMouseButtons(), mousePressEvent()
-*/
-Qt::MouseButtons QGraphicsItem::acceptedMouseButtons() const
-{
- return Qt::MouseButtons(d_ptr->acceptedMouseButtons);
-}
-
-/*!
- Sets the mouse \a buttons that this item accepts mouse events for.
-
- By default, all mouse buttons are accepted. If an item accepts a
- mouse button, it will become the mouse grabber item when a mouse
- press event is delivered for that button. However, if the item
- does not accept the mouse button, QGraphicsScene will forward the
- mouse events to the first item beneath it that does.
-
- To disable mouse events for an item (i.e., make it transparent for mouse
- events), call setAcceptedMouseButtons(0).
-
- \sa acceptedMouseButtons(), mousePressEvent()
-*/
-void QGraphicsItem::setAcceptedMouseButtons(Qt::MouseButtons buttons)
-{
- if (Qt::MouseButtons(d_ptr->acceptedMouseButtons) != buttons) {
- if (buttons == 0 && d_ptr->scene && d_ptr->scene->mouseGrabberItem() == this
- && d_ptr->scene->d_func()->lastMouseGrabberItemHasImplicitMouseGrab) {
- ungrabMouse();
- }
- d_ptr->acceptedMouseButtons = quint32(buttons);
- }
-}
-
-/*!
- \since 4.4
-
- Returns true if an item accepts hover events
- (QGraphicsSceneHoverEvent); otherwise, returns false. By default,
- items do not accept hover events.
-
- \sa setAcceptedMouseButtons()
-*/
-bool QGraphicsItem::acceptHoverEvents() const
-{
- return d_ptr->acceptsHover;
-}
-
-/*!
- \obsolete
-
- Call acceptHoverEvents() instead.
-*/
-bool QGraphicsItem::acceptsHoverEvents() const
-{
- return d_ptr->acceptsHover;
-}
-
-/*!
- \since 4.4
-
- If \a enabled is true, this item will accept hover events;
- otherwise, it will ignore them. By default, items do not accept
- hover events.
-
- Hover events are delivered when there is no current mouse grabber
- item. They are sent when the mouse cursor enters an item, when it
- moves around inside the item, and when the cursor leaves an
- item. Hover events are commonly used to highlight an item when
- it's entered, and for tracking the mouse cursor as it hovers over
- the item (equivalent to QWidget::mouseTracking).
-
- Parent items receive hover enter events before their children, and
- leave events after their children. The parent does not receive a
- hover leave event if the cursor enters a child, though; the parent
- stays "hovered" until the cursor leaves its area, including its
- children's areas.
-
- If a parent item handles child events, it will receive hover move,
- drag move, and drop events as the cursor passes through its
- children, but it does not receive hover enter and hover leave, nor
- drag enter and drag leave events on behalf of its children.
-
- A QGraphicsWidget with window decorations will accept hover events
- regardless of the value of acceptHoverEvents().
-
- \sa acceptHoverEvents(), hoverEnterEvent(), hoverMoveEvent(),
- hoverLeaveEvent()
-*/
-void QGraphicsItem::setAcceptHoverEvents(bool enabled)
-{
- if (d_ptr->acceptsHover == quint32(enabled))
- return;
- d_ptr->acceptsHover = quint32(enabled);
- if (d_ptr->acceptsHover && d_ptr->scene && d_ptr->scene->d_func()->allItemsIgnoreHoverEvents) {
- d_ptr->scene->d_func()->allItemsIgnoreHoverEvents = false;
- d_ptr->scene->d_func()->enableMouseTrackingOnViews();
- }
-}
-
-/*!
- \obsolete
-
- Use setAcceptHoverEvents(\a enabled) instead.
-*/
-void QGraphicsItem::setAcceptsHoverEvents(bool enabled)
-{
- setAcceptHoverEvents(enabled);
-}
-
-/*! \since 4.6
-
- Returns true if an item accepts \l{QTouchEvent}{touch events};
- otherwise, returns false. By default, items do not accept touch events.
-
- \sa setAcceptTouchEvents()
-*/
-bool QGraphicsItem::acceptTouchEvents() const
-{
- return d_ptr->acceptTouchEvents;
-}
-
-/*!
- \since 4.6
-
- If \a enabled is true, this item will accept \l{QTouchEvent}{touch events};
- otherwise, it will ignore them. By default, items do not accept
- touch events.
-*/
-void QGraphicsItem::setAcceptTouchEvents(bool enabled)
-{
- if (d_ptr->acceptTouchEvents == quint32(enabled))
- return;
- d_ptr->acceptTouchEvents = quint32(enabled);
- if (d_ptr->acceptTouchEvents && d_ptr->scene && d_ptr->scene->d_func()->allItemsIgnoreTouchEvents) {
- d_ptr->scene->d_func()->allItemsIgnoreTouchEvents = false;
- d_ptr->scene->d_func()->enableTouchEventsOnViews();
- }
-}
-
-/*!
- \since 4.6
-
- Returns true if this item filters child events (i.e., all events
- intended for any of its children are instead sent to this item);
- otherwise, false is returned.
-
- The default value is false; child events are not filtered.
-
- \sa setFiltersChildEvents()
-*/
-bool QGraphicsItem::filtersChildEvents() const
-{
- return d_ptr->filtersDescendantEvents;
-}
-
-/*!
- \since 4.6
-
- If \a enabled is true, this item is set to filter all events for
- all its children (i.e., all events intented for any of its
- children are instead sent to this item); otherwise, if \a enabled
- is false, this item will only handle its own events. The default
- value is false.
-
- \sa filtersChildEvents()
-*/
-void QGraphicsItem::setFiltersChildEvents(bool enabled)
-{
- if (d_ptr->filtersDescendantEvents == enabled)
- return;
-
- d_ptr->filtersDescendantEvents = enabled;
- d_ptr->updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-2));
-}
-
-/*!
- \obsolete
-
- Returns true if this item handles child events (i.e., all events
- intended for any of its children are instead sent to this item);
- otherwise, false is returned.
-
- This property is useful for item groups; it allows one item to
- handle events on behalf of its children, as opposed to its
- children handling their events individually.
-
- The default is to return false; children handle their own events.
- The exception for this is if the item is a QGraphicsItemGroup, then
- it defaults to return true.
-
- \sa setHandlesChildEvents()
-*/
-bool QGraphicsItem::handlesChildEvents() const
-{
- return d_ptr->handlesChildEvents;
-}
-
-/*!
- \obsolete
-
- If \a enabled is true, this item is set to handle all events for
- all its children (i.e., all events intented for any of its
- children are instead sent to this item); otherwise, if \a enabled
- is false, this item will only handle its own events. The default
- value is false.
-
- This property is useful for item groups; it allows one item to
- handle events on behalf of its children, as opposed to its
- children handling their events individually.
-
- If a child item accepts hover events, its parent will receive
- hover move events as the cursor passes through the child, but it
- does not receive hover enter and hover leave events on behalf of
- its child.
-
- \sa handlesChildEvents()
-*/
-void QGraphicsItem::setHandlesChildEvents(bool enabled)
-{
- if (d_ptr->handlesChildEvents == enabled)
- return;
-
- d_ptr->handlesChildEvents = enabled;
- d_ptr->updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-1));
-}
-/*!
- \since 4.6
- Returns true if this item is active; otherwise returns false.
-
- An item can only be active if the scene is active. An item is active
- if it is, or is a descendent of, an active panel. Items in non-active
- panels are not active.
-
- Items that are not part of a panel follow scene activation when the
- scene has no active panel.
-
- Only active items can gain input focus.
-
- \sa QGraphicsScene::isActive(), QGraphicsScene::activePanel(), panel(), isPanel()
-*/
-bool QGraphicsItem::isActive() const
-{
- if (!d_ptr->scene || !d_ptr->scene->isActive())
- return false;
- return panel() == d_ptr->scene->activePanel();
-}
-
-/*!
- \since 4.6
-
- If \a active is true, and the scene is active, this item's panel will be
- activated. Otherwise, the panel is deactivated.
-
- If the item is not part of an active scene, \a active will decide what
- happens to the panel when the scene becomes active or the item is added to
- the scene. If true, the item's panel will be activated when the item is
- either added to the scene or the scene is activated. Otherwise, the item
- will stay inactive independent of the scene's activated state.
-
- \sa isPanel(), QGraphicsScene::setActivePanel(), QGraphicsScene::isActive()
-*/
-void QGraphicsItem::setActive(bool active)
-{
- d_ptr->explicitActivate = 1;
- d_ptr->wantsActive = active;
- if (d_ptr->scene) {
- if (active) {
- // Activate this item.
- d_ptr->scene->setActivePanel(this);
- } else {
- // Deactivate this item, and reactivate the last active item
- // (if any).
- QGraphicsItem *lastActive = d_ptr->scene->d_func()->lastActivePanel;
- d_ptr->scene->setActivePanel(lastActive != this ? lastActive : 0);
- }
- }
-}
-
-/*!
- Returns true if this item is active, and it or its \l{focusProxy()}{focus
- proxy} has keyboard input focus; otherwise, returns false.
-
- \sa focusItem(), setFocus(), QGraphicsScene::setFocusItem(), isActive()
-*/
-bool QGraphicsItem::hasFocus() const
-{
- if (!d_ptr->scene || !d_ptr->scene->isActive())
- return false;
-
- if (d_ptr->focusProxy)
- return d_ptr->focusProxy->hasFocus();
-
- if (d_ptr->scene->d_func()->focusItem != this)
- return false;
-
- return panel() == d_ptr->scene->d_func()->activePanel;
-}
-
-/*!
- Gives keyboard input focus to this item. The \a focusReason argument will
- be passed into any \l{QFocusEvent}{focus event} generated by this function;
- it is used to give an explanation of what caused the item to get focus.
-
- Only enabled items that set the ItemIsFocusable flag can accept keyboard
- focus.
-
- If this item is not visible, not active, or not associated with a scene,
- it will not gain immediate input focus. However, it will be registered as
- the preferred focus item for its subtree of items, should it later become
- visible.
-
- As a result of calling this function, this item will receive a
- \l{focusInEvent()}{focus in event} with \a focusReason. If another item
- already has focus, that item will first receive a \l{focusOutEvent()}
- {focus out event} indicating that it has lost input focus.
-
- \sa clearFocus(), hasFocus(), focusItem(), focusProxy()
-*/
-void QGraphicsItem::setFocus(Qt::FocusReason focusReason)
-{
- d_ptr->setFocusHelper(focusReason, /* climb = */ true, /* focusFromHide = */ false);
-}
-
-/*!
- \internal
-*/
-void QGraphicsItemPrivate::setFocusHelper(Qt::FocusReason focusReason, bool climb, bool focusFromHide)
-{
- // Disabled / unfocusable items cannot accept focus.
- if (!q_ptr->isEnabled() || !(flags & QGraphicsItem::ItemIsFocusable))
- return;
-
- // Find focus proxy.
- QGraphicsItem *f = q_ptr;
- while (f->d_ptr->focusProxy)
- f = f->d_ptr->focusProxy;
-
- // Return if it already has focus.
- if (scene && scene->focusItem() == f)
- return;
-
- // Update focus scope item ptr.
- QGraphicsItem *p = parent;
- while (p) {
- if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
- QGraphicsItem *oldFocusScopeItem = p->d_ptr->focusScopeItem;
- p->d_ptr->focusScopeItem = q_ptr;
- if (!p->focusItem() && !focusFromHide) {
- if (oldFocusScopeItem)
- oldFocusScopeItem->d_ptr->focusScopeItemChange(false);
- focusScopeItemChange(true);
- // If you call setFocus on a child of a focus scope that
- // doesn't currently have a focus item, then stop.
- return;
- }
- break;
- }
- p = p->d_ptr->parent;
- }
-
- if (climb) {
- while (f->d_ptr->focusScopeItem && f->d_ptr->focusScopeItem->isVisible())
- f = f->d_ptr->focusScopeItem;
- }
-
- // Update the child focus chain.
- QGraphicsItem *commonAncestor = 0;
- if (scene && scene->focusItem()) {
- commonAncestor = scene->focusItem()->commonAncestorItem(f);
- scene->focusItem()->d_ptr->clearSubFocus(scene->focusItem(), commonAncestor);
- }
-
- f->d_ptr->setSubFocus(f, commonAncestor);
-
- // Update the scene's focus item.
- if (scene) {
- QGraphicsItem *p = q_ptr->panel();
- if ((!p && scene->isActive()) || (p && p->isActive())) {
- // Visible items immediately gain focus from scene.
- scene->d_func()->setFocusItemHelper(f, focusReason);
- }
- }
-}
-
-/*!
- Takes keyboard input focus from the item.
-
- If it has focus, a \l{focusOutEvent()}{focus out event} is sent to this
- item to tell it that it is about to lose the focus.
-
- Only items that set the ItemIsFocusable flag, or widgets that set an
- appropriate focus policy, can accept keyboard focus.
-
- \sa setFocus(), hasFocus(), QGraphicsWidget::focusPolicy
-*/
-void QGraphicsItem::clearFocus()
-{
- d_ptr->clearFocusHelper(/* giveFocusToParent = */ true);
-}
-
-/*!
- \internal
-*/
-void QGraphicsItemPrivate::clearFocusHelper(bool giveFocusToParent)
-{
- if (giveFocusToParent) {
- // Pass focus to the closest parent focus scope
- if (!inDestructor) {
- QGraphicsItem *p = parent;
- while (p) {
- if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
- if (p->d_ptr->focusScopeItem == q_ptr) {
- p->d_ptr->focusScopeItem = 0;
- if (!q_ptr->hasFocus()) //if it has focus, focusScopeItemChange is called elsewhere
- focusScopeItemChange(false);
- }
- if (q_ptr->hasFocus())
- p->d_ptr->setFocusHelper(Qt::OtherFocusReason, /* climb = */ false,
- /* focusFromHide = */ false);
- return;
- }
- p = p->d_ptr->parent;
- }
- }
- }
-
- if (q_ptr->hasFocus()) {
- // Invisible items with focus must explicitly clear subfocus.
- clearSubFocus(q_ptr);
-
- // If this item has the scene's input focus, clear it.
- scene->setFocusItem(0);
- }
-}
-
-/*!
- \since 4.6
-
- Returns this item's focus proxy, or 0 if this item has no
- focus proxy.
-
- \sa setFocusProxy(), setFocus(), hasFocus()
-*/
-QGraphicsItem *QGraphicsItem::focusProxy() const
-{
- return d_ptr->focusProxy;
-}
-
-/*!
- \since 4.6
-
- Sets the item's focus proxy to \a item.
-
- If an item has a focus proxy, the focus proxy will receive
- input focus when the item gains input focus. The item itself
- will still have focus (i.e., hasFocus() will return true),
- but only the focus proxy will receive the keyboard input.
-
- A focus proxy can itself have a focus proxy, and so on. In
- such case, keyboard input will be handled by the outermost
- focus proxy.
-
- The focus proxy \a item must belong to the same scene as
- this item.
-
- \sa focusProxy(), setFocus(), hasFocus()
-*/
-void QGraphicsItem::setFocusProxy(QGraphicsItem *item)
-{
- if (item == d_ptr->focusProxy)
- return;
- if (item == this) {
- qWarning("QGraphicsItem::setFocusProxy: cannot assign self as focus proxy");
- return;
- }
- if (item) {
- if (item->d_ptr->scene != d_ptr->scene) {
- qWarning("QGraphicsItem::setFocusProxy: focus proxy must be in same scene");
- return;
- }
- for (QGraphicsItem *f = item->focusProxy(); f != 0; f = f->focusProxy()) {
- if (f == this) {
- qWarning("QGraphicsItem::setFocusProxy: %p is already in the focus proxy chain", item);
- return;
- }
- }
- }
-
- QGraphicsItem *lastFocusProxy = d_ptr->focusProxy;
- if (lastFocusProxy)
- lastFocusProxy->d_ptr->focusProxyRefs.removeOne(&d_ptr->focusProxy);
- d_ptr->focusProxy = item;
- if (item)
- item->d_ptr->focusProxyRefs << &d_ptr->focusProxy;
-}
-
-/*!
- \since 4.6
-
- If this item, a child or descendant of this item currently has input
- focus, this function will return a pointer to that item. If
- no descendant has input focus, 0 is returned.
-
- \sa hasFocus(), setFocus(), QWidget::focusWidget()
-*/
-QGraphicsItem *QGraphicsItem::focusItem() const
-{
- return d_ptr->subFocusItem;
-}
-
-/*!
- \internal
-
- Returns this item's focus scope item.
-*/
-QGraphicsItem *QGraphicsItem::focusScopeItem() const
-{
- return d_ptr->focusScopeItem;
-}
-
-/*!
- \since 4.4
- Grabs the mouse input.
-
- This item will receive all mouse events for the scene until any of the
- following events occurs:
-
- \list
- \o The item becomes invisible
- \o The item is removed from the scene
- \o The item is deleted
- \o The item call ungrabMouse()
- \o Another item calls grabMouse(); the item will regain the mouse grab
- when the other item calls ungrabMouse().
- \endlist
-
- When an item gains the mouse grab, it receives a QEvent::GrabMouse
- event. When it loses the mouse grab, it receives a QEvent::UngrabMouse
- event. These events can be used to detect when your item gains or loses
- the mouse grab through other means than receiving mouse button events.
-
- It is almost never necessary to explicitly grab the mouse in Qt, as Qt
- grabs and releases it sensibly. In particular, Qt grabs the mouse when you
- press a mouse button, and keeps the mouse grabbed until you release the
- last mouse button. Also, Qt::Popup widgets implicitly call grabMouse()
- when shown, and ungrabMouse() when hidden.
-
- Note that only visible items can grab mouse input. Calling grabMouse() on
- an invisible item has no effect.
-
- Keyboard events are not affected.
-
- \sa QGraphicsScene::mouseGrabberItem(), ungrabMouse(), grabKeyboard()
-*/
-void QGraphicsItem::grabMouse()
-{
- if (!d_ptr->scene) {
- qWarning("QGraphicsItem::grabMouse: cannot grab mouse without scene");
- return;
- }
- if (!d_ptr->visible) {
- qWarning("QGraphicsItem::grabMouse: cannot grab mouse while invisible");
- return;
- }
- d_ptr->scene->d_func()->grabMouse(this);
-}
-
-/*!
- \since 4.4
- Releases the mouse grab.
-
- \sa grabMouse(), ungrabKeyboard()
-*/
-void QGraphicsItem::ungrabMouse()
-{
- if (!d_ptr->scene) {
- qWarning("QGraphicsItem::ungrabMouse: cannot ungrab mouse without scene");
- return;
- }
- d_ptr->scene->d_func()->ungrabMouse(this);
-}
-
-/*!
- \since 4.4
- Grabs the keyboard input.
-
- The item will receive all keyboard input to the scene until one of the
- following events occur:
-
- \list
- \o The item becomes invisible
- \o The item is removed from the scene
- \o The item is deleted
- \o The item calls ungrabKeyboard()
- \o Another item calls grabKeyboard(); the item will regain the keyboard grab
- when the other item calls ungrabKeyboard().
- \endlist
-
- When an item gains the keyboard grab, it receives a QEvent::GrabKeyboard
- event. When it loses the keyboard grab, it receives a
- QEvent::UngrabKeyboard event. These events can be used to detect when your
- item gains or loses the keyboard grab through other means than gaining
- input focus.
-
- It is almost never necessary to explicitly grab the keyboard in Qt, as Qt
- grabs and releases it sensibly. In particular, Qt grabs the keyboard when
- your item gains input focus, and releases it when your item loses input
- focus, or when the item is hidden.
-
- Note that only visible items can grab keyboard input. Calling
- grabKeyboard() on an invisible item has no effect.
-
- Keyboard events are not affected.
-
- \sa ungrabKeyboard(), grabMouse(), setFocus()
-*/
-void QGraphicsItem::grabKeyboard()
-{
- if (!d_ptr->scene) {
- qWarning("QGraphicsItem::grabKeyboard: cannot grab keyboard without scene");
- return;
- }
- if (!d_ptr->visible) {
- qWarning("QGraphicsItem::grabKeyboard: cannot grab keyboard while invisible");
- return;
- }
- d_ptr->scene->d_func()->grabKeyboard(this);
-}
-
-/*!
- \since 4.4
- Releases the keyboard grab.
-
- \sa grabKeyboard(), ungrabMouse()
-*/
-void QGraphicsItem::ungrabKeyboard()
-{
- if (!d_ptr->scene) {
- qWarning("QGraphicsItem::ungrabKeyboard: cannot ungrab keyboard without scene");
- return;
- }
- d_ptr->scene->d_func()->ungrabKeyboard(this);
-}
-
-/*!
- Returns the position of the item in parent coordinates. If the item has no
- parent, its position is given in scene coordinates.
-
- The position of the item describes its origin (local coordinate
- (0, 0)) in parent coordinates; this function returns the same as
- mapToParent(0, 0).
-
- For convenience, you can also call scenePos() to determine the
- item's position in scene coordinates, regardless of its parent.
-
- \sa x(), y(), setPos(), transform(), {The Graphics View Coordinate System}
-*/
-QPointF QGraphicsItem::pos() const
-{
- return d_ptr->pos;
-}
-
-/*!
- \fn QGraphicsItem::x() const
-
- This convenience function is equivalent to calling pos().x().
-
- \sa y()
-*/
-
-/*!
- \since 4.6
-
- Set's the \a x coordinate of the item's position. Equivalent to
- calling setPos(x, y()).
-
- \sa x(), setPos()
-*/
-void QGraphicsItem::setX(qreal x)
-{
- if (d_ptr->inDestructor)
- return;
-
- if (qIsNaN(x))
- return;
-
- setPos(QPointF(x, d_ptr->pos.y()));
-}
-
-/*!
- \fn QGraphicsItem::y() const
-
- This convenience function is equivalent to calling pos().y().
-
- \sa x()
-*/
-
-/*!
- \since 4.6
-
- Set's the \a y coordinate of the item's position. Equivalent to
- calling setPos(x(), y).
-
- \sa x(), setPos()
-*/
-void QGraphicsItem::setY(qreal y)
-{
- if (d_ptr->inDestructor)
- return;
-
- if (qIsNaN(y))
- return;
-
- setPos(QPointF(d_ptr->pos.x(), y));
-}
-
-/*!
- Returns the item's position in scene coordinates. This is
- equivalent to calling \c mapToScene(0, 0).
-
- \sa pos(), sceneTransform(), {The Graphics View Coordinate System}
-*/
-QPointF QGraphicsItem::scenePos() const
-{
- return mapToScene(0, 0);
-}
-
-/*!
- \internal
-
- Sets the position \a pos.
-*/
-void QGraphicsItemPrivate::setPosHelper(const QPointF &pos)
-{
- Q_Q(QGraphicsItem);
- inSetPosHelper = 1;
- if (scene)
- q->prepareGeometryChange();
- QPointF oldPos = this->pos;
- this->pos = pos;
- dirtySceneTransform = 1;
- inSetPosHelper = 0;
- if (isObject) {
- if (pos.x() != oldPos.x())
- emit static_cast<QGraphicsObject *>(q_ptr)->xChanged();
- if (pos.y() != oldPos.y())
- emit static_cast<QGraphicsObject *>(q_ptr)->yChanged();
- }
-}
-
-/*!
- \internal
-
- Sets the transform \a transform.
-*/
-void QGraphicsItemPrivate::setTransformHelper(const QTransform &transform)
-{
- q_ptr->prepareGeometryChange();
- transformData->transform = transform;
- dirtySceneTransform = 1;
- transformChanged();
-}
-
-/*!
- Sets the position of the item to \a pos, which is in parent
- coordinates. For items with no parent, \a pos is in scene
- coordinates.
-
- The position of the item describes its origin (local coordinate
- (0, 0)) in parent coordinates.
-
- \sa pos(), scenePos(), {The Graphics View Coordinate System}
-*/
-void QGraphicsItem::setPos(const QPointF &pos)
-{
- if (d_ptr->pos == pos)
- return;
-
- if (d_ptr->inDestructor)
- return;
-
- // Update and repositition.
- if (!(d_ptr->flags & (ItemSendsGeometryChanges | ItemSendsScenePositionChanges))) {
- d_ptr->setPosHelper(pos);
- if (d_ptr->isWidget)
- static_cast<QGraphicsWidget *>(this)->d_func()->setGeometryFromSetPos();
- if (d_ptr->scenePosDescendants)
- d_ptr->sendScenePosChange();
- return;
- }
-
- // Notify the item that the position is changing.
- const QVariant newPosVariant(itemChange(ItemPositionChange, QVariant::fromValue<QPointF>(pos)));
- QPointF newPos = newPosVariant.toPointF();
- if (newPos == d_ptr->pos)
- return;
-
- // Update and repositition.
- d_ptr->setPosHelper(newPos);
-
- // Send post-notification.
- itemChange(QGraphicsItem::ItemPositionHasChanged, newPosVariant);
- d_ptr->sendScenePosChange();
-}
-
-/*!
- \fn void QGraphicsItem::setPos(qreal x, qreal y)
- \overload
-
- This convenience function is equivalent to calling setPos(QPointF(\a x, \a
- y)).
-*/
-
-/*!
- \fn void QGraphicsItem::moveBy(qreal dx, qreal dy)
-
- Moves the item by \a dx points horizontally, and \a dy point
- vertically. This function is equivalent to calling setPos(pos() +
- QPointF(\a dx, \a dy)).
-*/
-
-/*!
- If this item is part of a scene that is viewed by a QGraphicsView, this
- convenience function will attempt to scroll the view to ensure that \a
- rect is visible inside the view's viewport. If \a rect is a null rect (the
- default), QGraphicsItem will default to the item's bounding rect. \a xmargin
- and \a ymargin are the number of pixels the view should use for margins.
-
- If the specified rect cannot be reached, the contents are scrolled to the
- nearest valid position.
-
- If this item is not viewed by a QGraphicsView, this function does nothing.
-
- \sa QGraphicsView::ensureVisible()
-*/
-void QGraphicsItem::ensureVisible(const QRectF &rect, int xmargin, int ymargin)
-{
- if (d_ptr->scene) {
- QRectF sceneRect;
- if (!rect.isNull())
- sceneRect = sceneTransform().mapRect(rect);
- else
- sceneRect = sceneBoundingRect();
- foreach (QGraphicsView *view, d_ptr->scene->d_func()->views)
- view->ensureVisible(sceneRect, xmargin, ymargin);
- }
-}
-
-/*!
- \fn void QGraphicsItem::ensureVisible(qreal x, qreal y, qreal w, qreal h,
- int xmargin = 50, int ymargin = 50)
-
- This convenience function is equivalent to calling
- ensureVisible(QRectF(\a x, \a y, \a w, \a h), \a xmargin, \a ymargin):
-*/
-
-/*!
- \obsolete
-
- Returns the item's affine transformation matrix. This is a subset or the
- item's full transformation matrix, and might not represent the item's full
- transformation.
-
- Use transform() instead.
-
- \sa setTransform(), sceneTransform()
-*/
-QMatrix QGraphicsItem::matrix() const
-{
- return transform().toAffine();
-}
-
-/*!
- \since 4.3
-
- Returns this item's transformation matrix.
-
- The transformation matrix is combined with the item's rotation(), scale()
- and transformations() into a combined transformations for the item.
-
- The default transformation matrix is an identity matrix.
-
- \sa setTransform(), sceneTransform()
-*/
-QTransform QGraphicsItem::transform() const
-{
- if (!d_ptr->transformData)
- return QTransform();
- return d_ptr->transformData->transform;
-}
-
-/*!
- \since 4.6
-
- Returns the clockwise rotation, in degrees, around the Z axis. The default
- value is 0 (i.e., the item is not rotated).
-
- The rotation is combined with the item's scale(), transform() and
- transformations() to map the item's coordinate system to the parent item.
-
- \sa setRotation(), transformOriginPoint(), {Transformations}
-*/
-qreal QGraphicsItem::rotation() const
-{
- if (!d_ptr->transformData)
- return 0;
- return d_ptr->transformData->rotation;
-}
-
-/*!
- \since 4.6
-
- Sets the clockwise rotation \a angle, in degrees, around the Z axis. The
- default value is 0 (i.e., the item is not rotated). Assigning a negative
- value will rotate the item counter-clockwise. Normally the rotation angle
- is in the range (-360, 360), but it's also possible to assign values
- outside of this range (e.g., a rotation of 370 degrees is the same as a
- rotation of 10 degrees).
-
- The item is rotated around its transform origin point, which by default
- is (0, 0). You can select a different transformation origin by calling
- setTransformOriginPoint().
-
- The rotation is combined with the item's scale(), transform() and
- transformations() to map the item's coordinate system to the parent item.
-
- \sa rotation(), setTransformOriginPoint(), {Transformations}
-*/
-void QGraphicsItem::setRotation(qreal angle)
-{
- prepareGeometryChange();
- qreal newRotation = angle;
-
- if (d_ptr->flags & ItemSendsGeometryChanges) {
- // Notify the item that the rotation is changing.
- const QVariant newRotationVariant(itemChange(ItemRotationChange, angle));
- newRotation = newRotationVariant.toReal();
- }
-
- if (!d_ptr->transformData)
- d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
-
- if (d_ptr->transformData->rotation == newRotation)
- return;
-
- d_ptr->transformData->rotation = newRotation;
- d_ptr->transformData->onlyTransform = false;
- d_ptr->dirtySceneTransform = 1;
-
- // Send post-notification.
- if (d_ptr->flags & ItemSendsGeometryChanges)
- itemChange(ItemRotationHasChanged, newRotation);
-
- if (d_ptr->isObject)
- emit static_cast<QGraphicsObject *>(this)->rotationChanged();
-
- d_ptr->transformChanged();
-}
-
-/*!
- \since 4.6
-
- Returns the scale factor of the item. The default scale factor is 1.0
- (i.e., the item is not scaled).
-
- The scale is combined with the item's rotation(), transform() and
- transformations() to map the item's coordinate system to the parent item.
-
- \sa setScale(), rotation(), {Transformations}
-*/
-qreal QGraphicsItem::scale() const
-{
- if (!d_ptr->transformData)
- return 1.;
- return d_ptr->transformData->scale;
-}
-
-/*!
- \since 4.6
-
- Sets the scale \a factor of the item. The default scale factor is 1.0
- (i.e., the item is not scaled). A scale factor of 0.0 will collapse the
- item to a single point. If you provide a negative scale factor, the
- item will be flipped and mirrored (i.e., rotated 180 degrees).
-
- The item is scaled around its transform origin point, which by default
- is (0, 0). You can select a different transformation origin by calling
- setTransformOriginPoint().
-
- The scale is combined with the item's rotation(), transform() and
- transformations() to map the item's coordinate system to the parent item.
-
- \sa scale(), setTransformOriginPoint(), {Transformations Example}
-*/
-void QGraphicsItem::setScale(qreal factor)
-{
- prepareGeometryChange();
- qreal newScale = factor;
-
- if (d_ptr->flags & ItemSendsGeometryChanges) {
- // Notify the item that the scale is changing.
- const QVariant newScaleVariant(itemChange(ItemScaleChange, factor));
- newScale = newScaleVariant.toReal();
- }
-
- if (!d_ptr->transformData)
- d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
-
- if (d_ptr->transformData->scale == newScale)
- return;
-
- d_ptr->transformData->scale = newScale;
- d_ptr->transformData->onlyTransform = false;
- d_ptr->dirtySceneTransform = 1;
-
- // Send post-notification.
- if (d_ptr->flags & ItemSendsGeometryChanges)
- itemChange(ItemScaleHasChanged, newScale);
-
- if (d_ptr->isObject)
- emit static_cast<QGraphicsObject *>(this)->scaleChanged();
-
- d_ptr->transformChanged();
-}
-
-
-/*!
- \since 4.6
-
- Returns a list of graphics transforms that currently apply to this item.
-
- QGraphicsTransform is for applying and controlling a chain of individual
- transformation operations on an item. It's particularly useful in
- animations, where each transform operation needs to be interpolated
- independently, or differently.
-
- The transformations are combined with the item's rotation(), scale() and
- transform() to map the item's coordinate system to the parent item.
-
- \sa scale(), rotation(), transformOriginPoint(), {Transformations}
-*/
-QList<QGraphicsTransform *> QGraphicsItem::transformations() const
-{
- if (!d_ptr->transformData)
- return QList<QGraphicsTransform *>();
- return d_ptr->transformData->graphicsTransforms;
-}
-
-/*!
- \since 4.6
-
- Sets a list of graphics \a transformations (QGraphicsTransform) that
- currently apply to this item.
-
- If all you want is to rotate or scale an item, you should call setRotation()
- or setScale() instead. If you want to set an arbitrary transformation on
- an item, you can call setTransform().
-
- QGraphicsTransform is for applying and controlling a chain of individual
- transformation operations on an item. It's particularly useful in
- animations, where each transform operation needs to be interpolated
- independently, or differently.
-
- The transformations are combined with the item's rotation(), scale() and
- transform() to map the item's coordinate system to the parent item.
-
- \sa scale(), setTransformOriginPoint(), {Transformations}
-*/
-void QGraphicsItem::setTransformations(const QList<QGraphicsTransform *> &transformations)
-{
- prepareGeometryChange();
- if (!d_ptr->transformData)
- d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
- d_ptr->transformData->graphicsTransforms = transformations;
- for (int i = 0; i < transformations.size(); ++i)
- transformations.at(i)->d_func()->setItem(this);
- d_ptr->transformData->onlyTransform = false;
- d_ptr->dirtySceneTransform = 1;
- d_ptr->transformChanged();
-}
-
-/*!
- \internal
-*/
-void QGraphicsItemPrivate::prependGraphicsTransform(QGraphicsTransform *t)
-{
- if (!transformData)
- transformData = new QGraphicsItemPrivate::TransformData;
- if (!transformData->graphicsTransforms.contains(t))
- transformData->graphicsTransforms.prepend(t);
-
- Q_Q(QGraphicsItem);
- t->d_func()->setItem(q);
- transformData->onlyTransform = false;
- dirtySceneTransform = 1;
- transformChanged();
-}
-
-/*!
- \internal
-*/
-void QGraphicsItemPrivate::appendGraphicsTransform(QGraphicsTransform *t)
-{
- if (!transformData)
- transformData = new QGraphicsItemPrivate::TransformData;
- if (!transformData->graphicsTransforms.contains(t))
- transformData->graphicsTransforms.append(t);
-
- Q_Q(QGraphicsItem);
- t->d_func()->setItem(q);
- transformData->onlyTransform = false;
- dirtySceneTransform = 1;
- transformChanged();
-}
-
-/*!
- \since 4.6
-
- Returns the origin point for the transformation in item coordinates.
-
- The default is QPointF(0,0).
-
- \sa setTransformOriginPoint(), {Transformations}
-*/
-QPointF QGraphicsItem::transformOriginPoint() const
-{
- if (!d_ptr->transformData)
- return QPointF(0,0);
- return QPointF(d_ptr->transformData->xOrigin, d_ptr->transformData->yOrigin);
-}
-
-/*!
- \since 4.6
-
- Sets the \a origin point for the transformation in item coordinates.
-
- \sa transformOriginPoint(), {Transformations}
-*/
-void QGraphicsItem::setTransformOriginPoint(const QPointF &origin)
-{
- prepareGeometryChange();
- QPointF newOrigin = origin;
-
- if (d_ptr->flags & ItemSendsGeometryChanges) {
- // Notify the item that the origin point is changing.
- const QVariant newOriginVariant(itemChange(ItemTransformOriginPointChange,
- QVariant::fromValue<QPointF>(origin)));
- newOrigin = newOriginVariant.toPointF();
- }
-
- if (!d_ptr->transformData)
- d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
-
- if (d_ptr->transformData->xOrigin == newOrigin.x()
- && d_ptr->transformData->yOrigin == newOrigin.y()) {
- return;
- }
-
- d_ptr->transformData->xOrigin = newOrigin.x();
- d_ptr->transformData->yOrigin = newOrigin.y();
- d_ptr->transformData->onlyTransform = false;
- d_ptr->dirtySceneTransform = 1;
-
- // Send post-notification.
- if (d_ptr->flags & ItemSendsGeometryChanges)
- itemChange(ItemTransformOriginPointHasChanged, QVariant::fromValue<QPointF>(newOrigin));
-}
-
-/*!
- \fn void QGraphicsItem::setTransformOriginPoint(qreal x, qreal y)
-
- \since 4.6
- \overload
-
- Sets the origin point for the transformation in item coordinates.
- This is equivalent to calling setTransformOriginPoint(QPointF(\a x, \a y)).
-
- \sa setTransformOriginPoint(), {Transformations}
-*/
-
-
-/*!
- \obsolete
-
- Use sceneTransform() instead.
-
- \sa transform(), setTransform(), scenePos(), {The Graphics View Coordinate System}
-*/
-QMatrix QGraphicsItem::sceneMatrix() const
-{
- d_ptr->ensureSceneTransform();
- return d_ptr->sceneTransform.toAffine();
-}
-
-
-/*!
- \since 4.3
-
- Returns this item's scene transformation matrix. This matrix can be used
- to map coordinates and geometrical shapes from this item's local
- coordinate system to the scene's coordinate system. To map coordinates
- from the scene, you must first invert the returned matrix.
-
- Example:
-
- \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 4
-
- Unlike transform(), which returns only an item's local transformation, this
- function includes the item's (and any parents') position, and all the transfomation properties.
-
- \sa transform(), setTransform(), scenePos(), {The Graphics View Coordinate System}, {Transformations}
-*/
-QTransform QGraphicsItem::sceneTransform() const
-{
- d_ptr->ensureSceneTransform();
- return d_ptr->sceneTransform;
-}
-
-/*!
- \since 4.3
-
- Returns this item's device transformation matrix, using \a
- viewportTransform to map from scene to device coordinates. This matrix can
- be used to map coordinates and geometrical shapes from this item's local
- coordinate system to the viewport's (or any device's) coordinate
- system. To map coordinates from the viewport, you must first invert the
- returned matrix.
-
- Example:
-
- \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 5
-
- This function is the same as combining this item's scene transform with
- the view's viewport transform, but it also understands the
- ItemIgnoresTransformations flag. The device transform can be used to do
- accurate coordinate mapping (and collision detection) for untransformable
- items.
-
- \sa transform(), setTransform(), scenePos(), {The Graphics View Coordinate
- System}, itemTransform()
-*/
-QTransform QGraphicsItem::deviceTransform(const QTransform &viewportTransform) const
-{
- // Ensure we return the standard transform if we're not untransformable.
- if (!d_ptr->itemIsUntransformable()) {
- d_ptr->ensureSceneTransform();
- return d_ptr->sceneTransform * viewportTransform;
- }
-
- // Find the topmost item that ignores view transformations.
- const QGraphicsItem *untransformedAncestor = this;
- QList<const QGraphicsItem *> parents;
- while (untransformedAncestor && ((untransformedAncestor->d_ptr->ancestorFlags
- & QGraphicsItemPrivate::AncestorIgnoresTransformations))) {
- parents.prepend(untransformedAncestor);
- untransformedAncestor = untransformedAncestor->parentItem();
- }
-
- if (!untransformedAncestor) {
- // Assert in debug mode, continue in release.
- Q_ASSERT_X(untransformedAncestor, "QGraphicsItem::deviceTransform",
- "Invalid object structure!");
- return QTransform();
- }
-
- // First translate the base untransformable item.
- untransformedAncestor->d_ptr->ensureSceneTransform();
- QPointF mappedPoint = (untransformedAncestor->d_ptr->sceneTransform * viewportTransform).map(QPointF(0, 0));
-
- // COMBINE
- QTransform matrix = QTransform::fromTranslate(mappedPoint.x(), mappedPoint.y());
- if (untransformedAncestor->d_ptr->transformData)
- matrix = untransformedAncestor->d_ptr->transformData->computedFullTransform(&matrix);
-
- // Then transform and translate all children.
- for (int i = 0; i < parents.size(); ++i) {
- const QGraphicsItem *parent = parents.at(i);
- parent->d_ptr->combineTransformFromParent(&matrix);
- }
-
- return matrix;
-}
-
-/*!
- \since 4.5
-
- Returns a QTransform that maps coordinates from this item to \a other. If
- \a ok is not null, and if there is no such transform, the boolean pointed
- to by \a ok will be set to false; otherwise it will be set to true.
-
- This transform provides an alternative to the mapToItem() or mapFromItem()
- functions, by returning the appropriate transform so that you can map
- shapes and coordinates yourself. It also helps you write more efficient
- code when repeatedly mapping between the same two items.
-
- \note In rare circumstances, there is no transform that maps between two
- items.
-
- \sa mapToItem(), mapFromItem(), deviceTransform()
-*/
-QTransform QGraphicsItem::itemTransform(const QGraphicsItem *other, bool *ok) const
-{
- // Catch simple cases first.
- if (other == 0) {
- qWarning("QGraphicsItem::itemTransform: null pointer passed");
- return QTransform();
- }
- if (other == this) {
- if (ok)
- *ok = true;
- return QTransform();
- }
-
- QGraphicsItem *parent = d_ptr->parent;
- const QGraphicsItem *otherParent = other->d_ptr->parent;
-
- // This is other's child
- if (parent == other) {
- if (ok)
- *ok = true;
- QTransform x;
- d_ptr->combineTransformFromParent(&x);
- return x;
- }
-
- // This is other's parent
- if (otherParent == this) {
- const QPointF &otherPos = other->d_ptr->pos;
- if (other->d_ptr->transformData) {
- QTransform otherToParent;
- other->d_ptr->combineTransformFromParent(&otherToParent);
- return otherToParent.inverted(ok);
- }
- if (ok)
- *ok = true;
- return QTransform::fromTranslate(-otherPos.x(), -otherPos.y());
- }
-
- // Siblings
- if (parent == otherParent) {
- // COMBINE
- const QPointF &itemPos = d_ptr->pos;
- const QPointF &otherPos = other->d_ptr->pos;
- if (!d_ptr->transformData && !other->d_ptr->transformData) {
- QPointF delta = itemPos - otherPos;
- if (ok)
- *ok = true;
- return QTransform::fromTranslate(delta.x(), delta.y());
- }
-
- QTransform itemToParent;
- d_ptr->combineTransformFromParent(&itemToParent);
- QTransform otherToParent;
- other->d_ptr->combineTransformFromParent(&otherToParent);
- return itemToParent * otherToParent.inverted(ok);
- }
-
- // Find the closest common ancestor. If the two items don't share an
- // ancestor, then the only way is to combine their scene transforms.
- const QGraphicsItem *commonAncestor = commonAncestorItem(other);
- if (!commonAncestor) {
- d_ptr->ensureSceneTransform();
- other->d_ptr->ensureSceneTransform();
- return d_ptr->sceneTransform * other->d_ptr->sceneTransform.inverted(ok);
- }
-
- // If the two items are cousins (in sibling branches), map both to the
- // common ancestor, and combine the two transforms.
- bool cousins = other != commonAncestor && this != commonAncestor;
- if (cousins) {
- bool good = false;
- QTransform thisToScene = itemTransform(commonAncestor, &good);
- QTransform otherToScene(Qt::Uninitialized);
- if (good)
- otherToScene = other->itemTransform(commonAncestor, &good);
- if (!good) {
- if (ok)
- *ok = false;
- return QTransform();
- }
- return thisToScene * otherToScene.inverted(ok);
- }
-
- // One is an ancestor of the other; walk the chain.
- bool parentOfOther = isAncestorOf(other);
- const QGraphicsItem *child = parentOfOther ? other : this;
- const QGraphicsItem *root = parentOfOther ? this : other;
-
- QTransform x;
- const QGraphicsItem *p = child;
- do {
- p->d_ptr.data()->combineTransformToParent(&x);
- } while ((p = p->d_ptr->parent) && p != root);
- if (parentOfOther)
- return x.inverted(ok);
- if (ok)
- *ok = true;
- return x;
-}
-
-/*!
- \obsolete
-
- Sets the item's affine transformation matrix. This is a subset or the
- item's full transformation matrix, and might not represent the item's full
- transformation.
-
- Use setTransform() instead.
-
- \sa transform(), {The Graphics View Coordinate System}
-*/
-void QGraphicsItem::setMatrix(const QMatrix &matrix, bool combine)
-{
- if (!d_ptr->transformData)
- d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
-
- QTransform newTransform(combine ? QTransform(matrix) * d_ptr->transformData->transform : QTransform(matrix));
- if (d_ptr->transformData->transform == newTransform)
- return;
-
- // Update and set the new transformation.
- if (!(d_ptr->flags & ItemSendsGeometryChanges)) {
- d_ptr->setTransformHelper(newTransform);
- return;
- }
-
- // Notify the item that the transformation matrix is changing.
- const QVariant newMatrixVariant = QVariant::fromValue<QMatrix>(newTransform.toAffine());
- newTransform = QTransform(qvariant_cast<QMatrix>(itemChange(ItemMatrixChange, newMatrixVariant)));
- if (d_ptr->transformData->transform == newTransform)
- return;
-
- // Update and set the new transformation.
- d_ptr->setTransformHelper(newTransform);
-
- // Send post-notification.
- itemChange(ItemTransformHasChanged, QVariant::fromValue<QTransform>(newTransform));
-}
-
-/*!
- \since 4.3
-
- Sets the item's current transformation matrix to \a matrix.
-
- If \a combine is true, then \a matrix is combined with the current matrix;
- otherwise, \a matrix \e replaces the current matrix. \a combine is false
- by default.
-
- To simplify interation with items using a transformed view, QGraphicsItem
- provides mapTo... and mapFrom... functions that can translate between
- items' and the scene's coordinates. For example, you can call mapToScene()
- to map an item coordiate to a scene coordinate, or mapFromScene() to map
- from scene coordinates to item coordinates.
-
- The transformation matrix is combined with the item's rotation(), scale()
- and transformations() into a combined transformation that maps the item's
- coordinate system to its parent.
-
- \sa transform(), setRotation(), setScale(), setTransformOriginPoint(), {The Graphics View Coordinate System}, {Transformations}
-*/
-void QGraphicsItem::setTransform(const QTransform &matrix, bool combine)
-{
- if (!d_ptr->transformData)
- d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
-
- QTransform newTransform(combine ? matrix * d_ptr->transformData->transform : matrix);
- if (d_ptr->transformData->transform == newTransform)
- return;
-
- // Update and set the new transformation.
- if (!(d_ptr->flags & (ItemSendsGeometryChanges | ItemSendsScenePositionChanges))) {
- d_ptr->setTransformHelper(newTransform);
- if (d_ptr->scenePosDescendants)
- d_ptr->sendScenePosChange();
- return;
- }
-
- // Notify the item that the transformation matrix is changing.
- const QVariant newTransformVariant(itemChange(ItemTransformChange,
- QVariant::fromValue<QTransform>(newTransform)));
- newTransform = qvariant_cast<QTransform>(newTransformVariant);
- if (d_ptr->transformData->transform == newTransform)
- return;
-
- // Update and set the new transformation.
- d_ptr->setTransformHelper(newTransform);
-
- // Send post-notification.
- itemChange(ItemTransformHasChanged, newTransformVariant);
- d_ptr->sendScenePosChange();
-}
-
-/*!
- \obsolete
-
- Use resetTransform() instead.
-*/
-void QGraphicsItem::resetMatrix()
-{
- resetTransform();
-}
-
-/*!
- \since 4.3
-
- Resets this item's transformation matrix to the identity matrix or
- all the transformation properties to their default values.
- This is equivalent to calling \c setTransform(QTransform()).
-
- \sa setTransform(), transform()
-*/
-void QGraphicsItem::resetTransform()
-{
- setTransform(QTransform(), false);
-}
-
-/*!
- \obsolete
-
- Use
-
- \code
- setRotation(rotation() + angle);
- \endcode
-
- instead.
-
- Rotates the current item transformation \a angle degrees clockwise around
- its origin. To translate around an arbitrary point (x, y), you need to
- combine translation and rotation with setTransform().
-
- Example:
-
- \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 6
-
- \sa setTransform(), transform(), scale(), shear(), translate()
-*/
-void QGraphicsItem::rotate(qreal angle)
-{
- setTransform(QTransform().rotate(angle), true);
-}
-
-/*!
- \obsolete
-
- Use
-
- \code
- setTransform(QTransform::fromScale(sx, sy), true);
- \endcode
-
- instead.
-
- Scales the current item transformation by (\a sx, \a sy) around its
- origin. To scale from an arbitrary point (x, y), you need to combine
- translation and scaling with setTransform().
-
- Example:
-
- \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 7
-
- \sa setTransform(), transform()
-*/
-void QGraphicsItem::scale(qreal sx, qreal sy)
-{
- setTransform(QTransform::fromScale(sx, sy), true);
-}
-
-/*!
- \obsolete
-
- Use
-
- \code
- setTransform(QTransform().shear(sh, sv), true);
- \endcode
-
- instead.
-
- Shears the current item transformation by (\a sh, \a sv).
-
- \sa setTransform(), transform()
-*/
-void QGraphicsItem::shear(qreal sh, qreal sv)
-{
- setTransform(QTransform().shear(sh, sv), true);
-}
-
-/*!
- \obsolete
-
- Use setPos() or setTransformOriginPoint() instead. For identical
- behavior, use
-
- \code
- setTransform(QTransform::fromTranslate(dx, dy), true);
- \endcode
-
- Translates the current item transformation by (\a dx, \a dy).
-
- If all you want is to move an item, you should call moveBy() or
- setPos() instead; this function changes the item's translation,
- which is conceptually separate from its position.
-
- \sa setTransform(), transform()
-*/
-void QGraphicsItem::translate(qreal dx, qreal dy)
-{
- setTransform(QTransform::fromTranslate(dx, dy), true);
-}
-
-/*!
- This virtual function is called twice for all items by the
- QGraphicsScene::advance() slot. In the first phase, all items are called
- with \a phase == 0, indicating that items on the scene are about to
- advance, and then all items are called with \a phase == 1. Reimplement
- this function to update your item if you need simple scene-controlled
- animation.
-
- The default implementation does nothing.
-
- For individual item animation, an alternative to this function is to
- either use QGraphicsItemAnimation, or to multiple-inherit from QObject and
- QGraphicsItem, and animate your item using QObject::startTimer() and
- QObject::timerEvent().
-
- \sa QGraphicsItemAnimation, QTimeLine
-*/
-void QGraphicsItem::advance(int phase)
-{
- Q_UNUSED(phase);
-}
-
-/*!
- Returns the Z-value of the item. The Z-value affects the stacking order of
- sibling (neighboring) items.
-
- The default Z-value is 0.
-
- \sa setZValue(), {QGraphicsItem#Sorting}{Sorting}, stackBefore(), ItemStacksBehindParent
-*/
-qreal QGraphicsItem::zValue() const
-{
- return d_ptr->z;
-}
-
-/*!
- Sets the Z-value of the item to \a z. The Z value decides the stacking
- order of sibling (neighboring) items. A sibling item of high Z value will
- always be drawn on top of another sibling item with a lower Z value.
-
- If you restore the Z value, the item's insertion order will decide its
- stacking order.
-
- The Z-value does not affect the item's size in any way.
-
- The default Z-value is 0.
-
- \sa zValue(), {QGraphicsItem#Sorting}{Sorting}, stackBefore(), ItemStacksBehindParent
-*/
-void QGraphicsItem::setZValue(qreal z)
-{
- const QVariant newZVariant(itemChange(ItemZValueChange, z));
- qreal newZ = newZVariant.toReal();
- if (newZ == d_ptr->z)
- return;
-
- if (d_ptr->scene && d_ptr->scene->d_func()->indexMethod != QGraphicsScene::NoIndex) {
- // Z Value has changed, we have to notify the index.
- d_ptr->scene->d_func()->index->itemChange(this, ItemZValueChange, &newZ);
- }
-
- d_ptr->z = newZ;
- if (d_ptr->parent)
- d_ptr->parent->d_ptr->needSortChildren = 1;
- else if (d_ptr->scene)
- d_ptr->scene->d_func()->needSortTopLevelItems = 1;
-
- if (d_ptr->scene)
- d_ptr->scene->d_func()->markDirty(this, QRectF(), /*invalidateChildren=*/true);
-
- itemChange(ItemZValueHasChanged, newZVariant);
-
- if (d_ptr->flags & ItemNegativeZStacksBehindParent)
- setFlag(QGraphicsItem::ItemStacksBehindParent, z < qreal(0.0));
-
- if (d_ptr->isObject)
- emit static_cast<QGraphicsObject *>(this)->zChanged();
-}
-
-/*!
- \internal
-
- Ensures that the list of children is sorted by insertion order, and that
- the siblingIndexes are packed (no gaps), and start at 0.
-
- ### This function is almost identical to
- QGraphicsScenePrivate::ensureSequentialTopLevelSiblingIndexes().
-*/
-void QGraphicsItemPrivate::ensureSequentialSiblingIndex()
-{
- if (!sequentialOrdering) {
- qSort(children.begin(), children.end(), insertionOrder);
- sequentialOrdering = 1;
- needSortChildren = 1;
- }
- if (holesInSiblingIndex) {
- holesInSiblingIndex = 0;
- for (int i = 0; i < children.size(); ++i)
- children[i]->d_ptr->siblingIndex = i;
- }
-}
-
-/*!
- \internal
-*/
-inline void QGraphicsItemPrivate::sendScenePosChange()
-{
- Q_Q(QGraphicsItem);
- if (scene) {
- if (flags & QGraphicsItem::ItemSendsScenePositionChanges)
- q->itemChange(QGraphicsItem::ItemScenePositionHasChanged, q->scenePos());
- if (scenePosDescendants) {
- foreach (QGraphicsItem *item, scene->d_func()->scenePosItems) {
- if (q->isAncestorOf(item))
- item->itemChange(QGraphicsItem::ItemScenePositionHasChanged, item->scenePos());
- }
- }
- }
-}
-
-/*!
- \since 4.6
-
- Stacks this item before \a sibling, which must be a sibling item (i.e., the
- two items must share the same parent item, or must both be toplevel items).
- The \a sibling must have the same Z value as this item, otherwise calling
- this function will have no effect.
-
- By default, all sibling items are stacked by insertion order (i.e., the
- first item you add is drawn before the next item you add). If two items' Z
- values are different, then the item with the highest Z value is drawn on
- top. When the Z values are the same, the insertion order will decide the
- stacking order.
-
- \sa setZValue(), ItemStacksBehindParent, {QGraphicsItem#Sorting}{Sorting}
-*/
-void QGraphicsItem::stackBefore(const QGraphicsItem *sibling)
-{
- if (sibling == this)
- return;
- if (!sibling || d_ptr->parent != sibling->parentItem()) {
- qWarning("QGraphicsItem::stackUnder: cannot stack under %p, which must be a sibling", sibling);
- return;
- }
- QList<QGraphicsItem *> *siblings = d_ptr->parent
- ? &d_ptr->parent->d_ptr->children
- : (d_ptr->scene ? &d_ptr->scene->d_func()->topLevelItems : 0);
- if (!siblings) {
- qWarning("QGraphicsItem::stackUnder: cannot stack under %p, which must be a sibling", sibling);
- return;
- }
-
- // First, make sure that the sibling indexes have no holes. This also
- // marks the children list for sorting.
- if (d_ptr->parent)
- d_ptr->parent->d_ptr->ensureSequentialSiblingIndex();
- else
- d_ptr->scene->d_func()->ensureSequentialTopLevelSiblingIndexes();
-
- // Only move items with the same Z value, and that need moving.
- int siblingIndex = sibling->d_ptr->siblingIndex;
- int myIndex = d_ptr->siblingIndex;
- if (myIndex >= siblingIndex) {
- siblings->move(myIndex, siblingIndex);
- // Fixup the insertion ordering.
- for (int i = 0; i < siblings->size(); ++i) {
- int &index = siblings->at(i)->d_ptr->siblingIndex;
- if (i != siblingIndex && index >= siblingIndex && index <= myIndex)
- ++index;
- }
- d_ptr->siblingIndex = siblingIndex;
- for (int i = 0; i < siblings->size(); ++i) {
- int &index = siblings->at(i)->d_ptr->siblingIndex;
- if (i != siblingIndex && index >= siblingIndex && index <= myIndex)
- siblings->at(i)->d_ptr->siblingOrderChange();
- }
- d_ptr->siblingOrderChange();
- }
-}
-
-/*!
- Returns the bounding rect of this item's descendants (i.e., its
- children, their children, etc.) in local coordinates. The
- rectangle will contain all descendants after they have been mapped
- to local coordinates. If the item has no children, this function
- returns an empty QRectF.
-
- This does not include this item's own bounding rect; it only returns
- its descendants' accumulated bounding rect. If you need to include this
- item's bounding rect, you can add boundingRect() to childrenBoundingRect()
- using QRectF::operator|().
-
- This function is linear in complexity; it determines the size of the
- returned bounding rect by iterating through all descendants.
-
- \sa boundingRect(), sceneBoundingRect()
-*/
-QRectF QGraphicsItem::childrenBoundingRect() const
-{
- if (!d_ptr->dirtyChildrenBoundingRect)
- return d_ptr->childrenBoundingRect;
-
- d_ptr->childrenBoundingRect = QRectF();
- d_ptr->childrenBoundingRectHelper(0, &d_ptr->childrenBoundingRect, 0);
- d_ptr->dirtyChildrenBoundingRect = 0;
- return d_ptr->childrenBoundingRect;
-}
-
-/*!
- \fn virtual QRectF QGraphicsItem::boundingRect() const = 0
-
- This pure virtual function defines the outer bounds of the item as
- a rectangle; all painting must be restricted to inside an item's
- bounding rect. QGraphicsView uses this to determine whether the
- item requires redrawing.
-
- Although the item's shape can be arbitrary, the bounding rect is
- always rectangular, and it is unaffected by the items'
- transformation.
-
- If you want to change the item's bounding rectangle, you must first call
- prepareGeometryChange(). This notifies the scene of the imminent change,
- so that its can update its item geometry index; otherwise, the scene will
- be unaware of the item's new geometry, and the results are undefined
- (typically, rendering artifacts are left around in the view).
-
- Reimplement this function to let QGraphicsView determine what
- parts of the widget, if any, need to be redrawn.
-
- Note: For shapes that paint an outline / stroke, it is important
- to include half the pen width in the bounding rect. It is not
- necessary to compensate for antialiasing, though.
-
- Example:
-
- \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 8
-
- \sa boundingRegion(), shape(), contains(), {The Graphics View Coordinate
- System}, prepareGeometryChange()
-*/
-
-/*!
- Returns the bounding rect of this item in scene coordinates, by combining
- sceneTransform() with boundingRect().
-
- \sa boundingRect(), {The Graphics View Coordinate System}
-*/
-QRectF QGraphicsItem::sceneBoundingRect() const
-{
- // Find translate-only offset
- // COMBINE
- QPointF offset;
- const QGraphicsItem *parentItem = this;
- const QGraphicsItemPrivate *itemd;
- do {
- itemd = parentItem->d_ptr.data();
- if (itemd->transformData)
- break;
- offset += itemd->pos;
- } while ((parentItem = itemd->parent));
-
- QRectF br = boundingRect();
- br.translate(offset);
- if (!parentItem)
- return br;
- if (parentItem->d_ptr->hasTranslateOnlySceneTransform()) {
- br.translate(parentItem->d_ptr->sceneTransform.dx(), parentItem->d_ptr->sceneTransform.dy());
- return br;
- }
- return parentItem->d_ptr->sceneTransform.mapRect(br);
-}
-
-/*!
- Returns the shape of this item as a QPainterPath in local
- coordinates. The shape is used for many things, including collision
- detection, hit tests, and for the QGraphicsScene::items() functions.
-
- The default implementation calls boundingRect() to return a simple
- rectangular shape, but subclasses can reimplement this function to return
- a more accurate shape for non-rectangular items. For example, a round item
- may choose to return an elliptic shape for better collision detection. For
- example:
-
- \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 9
-
- The outline of a shape can vary depending on the width and style of the
- pen used when drawing. If you want to include this outline in the item's
- shape, you can create a shape from the stroke using QPainterPathStroker.
-
- This function is called by the default implementations of contains() and
- collidesWithPath().
-
- \sa boundingRect(), contains(), prepareGeometryChange(), QPainterPathStroker
-*/
-QPainterPath QGraphicsItem::shape() const
-{
- QPainterPath path;
- path.addRect(boundingRect());
- return path;
-}
-
-/*!
- Returns true if this item is clipped. An item is clipped if it has either
- set the \l ItemClipsToShape flag, or if it or any of its ancestors has set
- the \l ItemClipsChildrenToShape flag.
-
- Clipping affects the item's appearance (i.e., painting), as well as mouse
- and hover event delivery.
-
- \sa clipPath(), shape(), setFlags()
-*/
-bool QGraphicsItem::isClipped() const
-{
- Q_D(const QGraphicsItem);
- return (d->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)
- || (d->flags & QGraphicsItem::ItemClipsToShape);
-}
-
-/*!
- \since 4.5
-
- Returns this item's clip path, or an empty QPainterPath if this item is
- not clipped. The clip path constrains the item's appearance and
- interaction (i.e., restricts the area the item can draw, and it also
- restricts the area that the item receives events).
-
- You can enable clipping by setting the ItemClipsToShape or
- ItemClipsChildrenToShape flags. The item's clip path is calculated by
- intersecting all clipping ancestors' shapes. If the item sets
- ItemClipsToShape, the final clip is intersected with the item's own shape.
-
- \note Clipping introduces a performance penalty for all items involved;
- you should generally avoid using clipping if you can (e.g., if your items
- always draw inside boundingRect() or shape() boundaries, clipping is not
- necessary).
-
- \sa isClipped(), shape(), setFlags()
-*/
-QPainterPath QGraphicsItem::clipPath() const
-{
- Q_D(const QGraphicsItem);
- if (!isClipped())
- return QPainterPath();
-
- const QRectF thisBoundingRect(boundingRect());
- if (thisBoundingRect.isEmpty())
- return QPainterPath();
-
- QPainterPath clip;
- // Start with the item's bounding rect.
- clip.addRect(thisBoundingRect);
-
- if (d->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) {
- const QGraphicsItem *parent = this;
- const QGraphicsItem *lastParent = this;
-
- // Intersect any in-between clips starting at the top and moving downwards.
- while ((parent = parent->d_ptr->parent)) {
- if (parent->d_ptr->flags & ItemClipsChildrenToShape) {
- // Map clip to the current parent and intersect with its shape/clipPath
- clip = lastParent->itemTransform(parent).map(clip);
- clip = clip.intersected(parent->shape());
- if (clip.isEmpty())
- return clip;
- lastParent = parent;
- }
-
- if (!(parent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren))
- break;
- }
-
- if (lastParent != this) {
- // Map clip back to the item's transform.
- // ### what if itemtransform fails
- clip = lastParent->itemTransform(this).map(clip);
- }
- }
-
- if (d->flags & ItemClipsToShape)
- clip = clip.intersected(shape());
-
- return clip;
-}
-
-/*!
- Returns true if this item contains \a point, which is in local
- coordinates; otherwise, false is returned. It is most often called from
- QGraphicsView to determine what item is under the cursor, and for that
- reason, the implementation of this function should be as light-weight as
- possible.
-
- By default, this function calls shape(), but you can reimplement it in a
- subclass to provide a (perhaps more efficient) implementation.
-
- \sa shape(), boundingRect(), collidesWithPath()
-*/
-bool QGraphicsItem::contains(const QPointF &point) const
-{
- return isClipped() ? clipPath().contains(point) : shape().contains(point);
-}
-
-/*!
-
- Returns true if this item collides with \a other; otherwise
- returns false.
-
- The \a mode is applied to \a other, and the resulting shape or
- bounding rectangle is then compared to this item's shape. The
- default value for \a mode is Qt::IntersectsItemShape; \a other
- collides with this item if it either intersects, contains, or is
- contained by this item's shape (see Qt::ItemSelectionMode for
- details).
-
- The default implementation is based on shape intersection, and it calls
- shape() on both items. Because the complexity of arbitrary shape-shape
- intersection grows with an order of magnitude when the shapes are complex,
- this operation can be noticably time consuming. You have the option of
- reimplementing this function in a subclass of QGraphicsItem to provide a
- custom algorithm. This allows you to make use of natural constraints in
- the shapes of your own items, in order to improve the performance of the
- collision detection. For instance, two untransformed perfectly circular
- items' collision can be determined very efficiently by comparing their
- positions and radii.
-
- Keep in mind that when reimplementing this function and calling shape() or
- boundingRect() on \a other, the returned coordinates must be mapped to
- this item's coordinate system before any intersection can take place.
-
- \sa contains(), shape()
-*/
-bool QGraphicsItem::collidesWithItem(const QGraphicsItem *other, Qt::ItemSelectionMode mode) const
-{
- if (other == this)
- return true;
- if (!other)
- return false;
- // The items share the same clip if their closest clipper is the same, or
- // if one clips the other.
- bool clips = (d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren);
- bool otherClips = (other->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren);
- if (clips || otherClips) {
- const QGraphicsItem *closestClipper = isAncestorOf(other) ? this : parentItem();
- while (closestClipper && !(closestClipper->flags() & ItemClipsChildrenToShape))
- closestClipper = closestClipper->parentItem();
- const QGraphicsItem *otherClosestClipper = other->isAncestorOf(this) ? other : other->parentItem();
- while (otherClosestClipper && !(otherClosestClipper->flags() & ItemClipsChildrenToShape))
- otherClosestClipper = otherClosestClipper->parentItem();
- if (closestClipper == otherClosestClipper) {
- d_ptr->localCollisionHack = 1;
- bool res = collidesWithPath(mapFromItem(other, other->shape()), mode);
- d_ptr->localCollisionHack = 0;
- return res;
- }
- }
-
- QPainterPath otherShape = other->isClipped() ? other->clipPath() : other->shape();
- return collidesWithPath(mapFromItem(other, otherShape), mode);
-}
-
-/*!
- Returns true if this item collides with \a path.
-
- The collision is determined by \a mode. The default value for \a mode is
- Qt::IntersectsItemShape; \a path collides with this item if it either
- intersects, contains, or is contained by this item's shape.
-
- Note that this function checks whether the item's shape or
- bounding rectangle (depending on \a mode) is contained within \a
- path, and not whether \a path is contained within the items shape
- or bounding rectangle.
-
- \sa collidesWithItem(), contains(), shape()
-*/
-bool QGraphicsItem::collidesWithPath(const QPainterPath &path, Qt::ItemSelectionMode mode) const
-{
- if (path.isEmpty()) {
- // No collision with empty paths.
- return false;
- }
-
- 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.
- return false;
- }
-
- // For further testing, we need this item's shape or bounding rect.
- QPainterPath thisShape;
- if (mode == Qt::IntersectsItemShape || mode == Qt::ContainsItemShape)
- thisShape = (isClipped() && !d_ptr->localCollisionHack) ? clipPath() : shape();
- else
- thisShape.addRect(rectA);
-
- if (thisShape == QPainterPath()) {
- // Empty shape? No collision.
- return false;
- }
-
- // Use QPainterPath boolean operations to determine the collision, O(N*logN).
- if (mode == Qt::IntersectsItemShape || mode == Qt::IntersectsItemBoundingRect)
- return path.intersects(thisShape);
- return path.contains(thisShape);
-}
-
-/*!
- Returns a list of all items that collide with this item.
-
- The way collisions are detected is determined by applying \a mode
- to items that are compared to this item, i.e., each item's shape
- or bounding rectangle is checked against this item's shape. The
- default value for \a mode is Qt::IntersectsItemShape.
-
- \sa collidesWithItem()
-*/
-QList<QGraphicsItem *> QGraphicsItem::collidingItems(Qt::ItemSelectionMode mode) const
-{
- if (d_ptr->scene)
- return d_ptr->scene->collidingItems(this, mode);
- return QList<QGraphicsItem *>();
-}
-
-/*!
- Returns true if this item's bounding rect is completely obscured by the
- opaque shape of any of colliding items above it (i.e., with a higher Z
- value than this item).
-
- Its implementation is based on calling isObscuredBy(), which you can
- reimplement to provide a custom obscurity algorithm.
-
- \sa opaqueArea()
-*/
-bool QGraphicsItem::isObscured() const
-{
- return isObscured(QRectF());
-}
-
-/*!
- \internal
-
- Item obscurity helper function.
-
- Returns true if the subrect \a rect of \a item's bounding rect is obscured
- by \a other (i.e., \a other's opaque area covers \a item's \a rect
- completely. \a other is assumed to already be "on top of" \a item
- wrt. stacking order.
-*/
-static bool qt_QGraphicsItem_isObscured(const QGraphicsItem *item,
- const QGraphicsItem *other,
- const QRectF &rect)
-{
- return other->mapToItem(item, other->opaqueArea()).contains(rect);
-}
-
-/*!
- \overload
- \since 4.3
-
- Returns true if \a rect is completely obscured by the opaque shape of any
- of colliding items above it (i.e., with a higher Z value than this item).
-
- Unlike the default isObscured() function, this function does not call
- isObscuredBy().
-
- \sa opaqueArea()
-*/
-bool QGraphicsItem::isObscured(const QRectF &rect) const
-{
- Q_D(const QGraphicsItem);
- if (!d->scene)
- return false;
-
- QRectF br = boundingRect();
- QRectF testRect = rect.isNull() ? br : rect;
-
- foreach (QGraphicsItem *item, d->scene->items(mapToScene(br), Qt::IntersectsItemBoundingRect)) {
- if (item == this)
- break;
- if (qt_QGraphicsItem_isObscured(this, item, testRect))
- return true;
- }
- return false;
-}
-
-/*!
- \fn bool QGraphicsItem::isObscured(qreal x, qreal y, qreal w, qreal h) const
- \since 4.3
-
- This convenience function is equivalent to calling isObscured(QRectF(\a x, \a y, \a w, \a h)).
-*/
-
-/*!
- Returns true if this item's bounding rect is completely obscured by the
- opaque shape of \a item.
-
- The base implementation maps \a item's opaqueArea() to this item's
- coordinate system, and then checks if this item's boundingRect() is fully
- contained within the mapped shape.
-
- You can reimplement this function to provide a custom algorithm for
- determining whether this item is obscured by \a item.
-
- \sa opaqueArea(), isObscured()
-*/
-bool QGraphicsItem::isObscuredBy(const QGraphicsItem *item) const
-{
- if (!item)
- return false;
- return qt_closestItemFirst(item, this)
- && qt_QGraphicsItem_isObscured(this, item, boundingRect());
-}
-
-/*!
- This virtual function returns a shape representing the area where this
- item is opaque. An area is opaque if it is filled using an opaque brush or
- color (i.e., not transparent).
-
- This function is used by isObscuredBy(), which is called by underlying
- items to determine if they are obscured by this item.
-
- The default implementation returns an empty QPainterPath, indicating that
- this item is completely transparent and does not obscure any other items.
-
- \sa isObscuredBy(), isObscured(), shape()
-*/
-QPainterPath QGraphicsItem::opaqueArea() const
-{
- return QPainterPath();
-}
-
-/*!
- \since 4.4
-
- Returns the bounding region for this item. The coordinate space of the
- returned region depends on \a itemToDeviceTransform. If you pass an
- identity QTransform as a parameter, this function will return a local
- coordinate region.
-
- The bounding region describes a coarse outline of the item's visual
- contents. Although it's expensive to calculate, it's also more precise
- than boundingRect(), and it can help to avoid unnecessary repainting when
- an item is updated. This is particularly efficient for thin items (e.g.,
- lines or simple polygons). You can tune the granularity for the bounding
- region by calling setBoundingRegionGranularity(). The default granularity
- is 0; in which the item's bounding region is the same as its bounding
- rect.
-
- \a itemToDeviceTransform is the transformation from item coordinates to
- device coordinates. If you want this function to return a QRegion in scene
- coordinates, you can pass sceneTransform() as an argument.
-
- \sa boundingRegionGranularity()
-*/
-QRegion QGraphicsItem::boundingRegion(const QTransform &itemToDeviceTransform) const
-{
- // ### Ideally we would have a better way to generate this region,
- // preferably something in the lines of QPainterPath::toRegion(QTransform)
- // coupled with a way to generate a painter path from a set of painter
- // operations (e.g., QPicture::toPainterPath() or so). The current
- // approach generates a bitmap with the size of the item's bounding rect
- // in device coordinates, scaled by b.r.granularity, then paints the item
- // 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 = itemToDeviceTransform.mapRect(boundingRect()).toRect();
- _q_adjustRect(&deviceRect);
- if (granularity == 0.0)
- return QRegion(deviceRect);
-
- int pad = 1;
- QSize bitmapSize(qMax(1, int(deviceRect.width() * granularity) + pad * 2),
- qMax(1, int(deviceRect.height() * granularity) + pad * 2));
- QImage mask(bitmapSize, QImage::Format_ARGB32_Premultiplied);
- mask.fill(0);
- QPainter p(&mask);
- p.setRenderHints(QPainter::Antialiasing);
-
- // Transform painter (### this code is from QGraphicsScene::drawItemHelper
- // and doesn't work properly with perspective transformations).
- QPointF viewOrigo = itemToDeviceTransform.map(QPointF(0, 0));
- QPointF offset = viewOrigo - deviceRect.topLeft();
- p.scale(granularity, granularity);
- p.translate(offset);
- p.translate(pad, pad);
- p.setWorldTransform(itemToDeviceTransform, true);
- p.translate(itemToDeviceTransform.inverted().map(QPointF(0, 0)));
-
- // Render
- QStyleOptionGraphicsItem option;
- const_cast<QGraphicsItem *>(this)->paint(&p, &option, 0);
- p.end();
-
- // Transform QRegion back to device space
- QTransform unscale = QTransform::fromScale(1 / granularity, 1 / granularity);
- QRegion r;
- QBitmap colorMask = QBitmap::fromImage(mask.createMaskFromColor(0));
- foreach (const QRect &rect, QRegion( colorMask ).rects()) {
- QRect xrect = unscale.mapRect(rect).translated(deviceRect.topLeft() - QPoint(pad, pad));
- r += xrect.adjusted(-1, -1, 1, 1) & deviceRect;
- }
- return r;
-}
-
-/*!
- \since 4.4
-
- Returns the item's bounding region granularity; a value between and
- including 0 and 1. The default value is 0 (i.e., the lowest granularity,
- where the bounding region corresponds to the item's bounding rectangle).
-
-\omit
-### NOTE
-\endomit
-
- \sa setBoundingRegionGranularity()
-*/
-qreal QGraphicsItem::boundingRegionGranularity() const
-{
- return d_ptr->hasBoundingRegionGranularity
- ? qvariant_cast<qreal>(d_ptr->extra(QGraphicsItemPrivate::ExtraBoundingRegionGranularity))
- : 0;
-}
-
-/*!
- \since 4.4
- Sets the bounding region granularity to \a granularity; a value between
- and including 0 and 1. The default value is 0 (i.e., the lowest
- granularity, where the bounding region corresponds to the item's bounding
- rectangle).
-
- The granularity is used by boundingRegion() to calculate how fine the
- bounding region of the item should be. The highest achievable granularity
- is 1, where boundingRegion() will return the finest outline possible for
- the respective device (e.g., for a QGraphicsView viewport, this gives you
- a pixel-perfect bounding region). The lowest possible granularity is
- 0. The value of \a granularity describes the ratio between device
- resolution and the resolution of the bounding region (e.g., a value of
- 0.25 will provide a region where each chunk corresponds to 4x4 device
- units / pixels).
-
- \sa boundingRegionGranularity()
-*/
-void QGraphicsItem::setBoundingRegionGranularity(qreal granularity)
-{
- if (granularity < 0.0 || granularity > 1.0) {
- qWarning("QGraphicsItem::setBoundingRegionGranularity: invalid granularity %g", granularity);
- return;
- }
- if (granularity == 0.0) {
- d_ptr->unsetExtra(QGraphicsItemPrivate::ExtraBoundingRegionGranularity);
- d_ptr->hasBoundingRegionGranularity = 0;
- return;
- }
- d_ptr->hasBoundingRegionGranularity = 1;
- d_ptr->setExtra(QGraphicsItemPrivate::ExtraBoundingRegionGranularity,
- QVariant::fromValue<qreal>(granularity));
-}
-
-/*!
- \fn virtual void QGraphicsItem::paint(QPainter *painter, const
- QStyleOptionGraphicsItem *option, QWidget *widget = 0) = 0
-
- This function, which is usually called by QGraphicsView, paints the
- contents of an item in local coordinates.
-
- Reimplement this function in a QGraphicsItem subclass to provide the
- item's painting implementation, using \a painter. The \a option parameter
- provides style options for the item, such as its state, exposed area and
- its level-of-detail hints. The \a widget argument is optional. If
- provided, it points to the widget that is being painted on; otherwise, it
- is 0. For cached painting, \a widget is always 0.
-
- \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 10
-
- The painter's pen is 0-width by default, and its pen is initialized to the
- QPalette::Text brush from the paint device's palette. The brush is
- initialized to QPalette::Window.
-
- Make sure to constrain all painting inside the boundaries of
- boundingRect() to avoid rendering artifacts (as QGraphicsView does not
- clip the painter for you). In particular, when QPainter renders the
- outline of a shape using an assigned QPen, half of the outline will be
- drawn outside, and half inside, the shape you're rendering (e.g., with a
- pen width of 2 units, you must draw outlines 1 unit inside
- boundingRect()). QGraphicsItem does not support use of cosmetic pens with
- a non-zero width.
-
- All painting is done in local coordinates.
-
- \sa setCacheMode(), QPen::width(), {Item Coordinates}, ItemUsesExtendedStyleOption
-*/
-
-/*!
- \internal
- Returns true if we can discard an update request; otherwise false.
-*/
-bool QGraphicsItemPrivate::discardUpdateRequest(bool ignoreVisibleBit, bool ignoreDirtyBit,
- bool ignoreOpacity) 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 !scene
- || (!visible && !ignoreVisibleBit && !this->ignoreVisible)
- || (!ignoreDirtyBit && fullUpdatePending)
- || (!ignoreOpacity && !this->ignoreOpacity && childrenCombineOpacity() && isFullyTransparent());
-}
-
-/*!
- \internal
-*/
-int QGraphicsItemPrivate::depth() const
-{
- if (itemDepth == -1)
- const_cast<QGraphicsItemPrivate *>(this)->resolveDepth();
-
- return itemDepth;
-}
-
-/*!
- \internal
-*/
-#ifndef QT_NO_GRAPHICSEFFECT
-void QGraphicsItemPrivate::invalidateParentGraphicsEffectsRecursively()
-{
- QGraphicsItemPrivate *itemPrivate = this;
- do {
- if (itemPrivate->graphicsEffect) {
- itemPrivate->notifyInvalidated = 1;
-
- if (!itemPrivate->updateDueToGraphicsEffect)
- static_cast<QGraphicsItemEffectSourcePrivate *>(itemPrivate->graphicsEffect->d_func()->source->d_func())->invalidateCache();
- }
- } while ((itemPrivate = itemPrivate->parent ? itemPrivate->parent->d_ptr.data() : 0));
-}
-
-void QGraphicsItemPrivate::invalidateChildGraphicsEffectsRecursively(QGraphicsItemPrivate::InvalidateReason reason)
-{
- if (!mayHaveChildWithGraphicsEffect)
- return;
-
- for (int i = 0; i < children.size(); ++i) {
- QGraphicsItemPrivate *childPrivate = children.at(i)->d_ptr.data();
- if (reason == OpacityChanged && (childPrivate->flags & QGraphicsItem::ItemIgnoresParentOpacity))
- continue;
- if (childPrivate->graphicsEffect) {
- childPrivate->notifyInvalidated = 1;
- static_cast<QGraphicsItemEffectSourcePrivate *>(childPrivate->graphicsEffect->d_func()->source->d_func())->invalidateCache();
- }
-
- childPrivate->invalidateChildGraphicsEffectsRecursively(reason);
- }
-}
-#endif //QT_NO_GRAPHICSEFFECT
-
-/*!
- \internal
-*/
-void QGraphicsItemPrivate::invalidateDepthRecursively()
-{
- if (itemDepth == -1)
- return;
-
- itemDepth = -1;
- for (int i = 0; i < children.size(); ++i)
- children.at(i)->d_ptr->invalidateDepthRecursively();
-}
-
-/*!
- \internal
-
- Resolves the stacking depth of this object and all its ancestors.
-*/
-void QGraphicsItemPrivate::resolveDepth()
-{
- if (!parent)
- itemDepth = 0;
- else {
- if (parent->d_ptr->itemDepth == -1)
- parent->d_ptr->resolveDepth();
- itemDepth = parent->d_ptr->itemDepth + 1;
- }
-}
-
-/*!
- \internal
-
- ### This function is almost identical to
- QGraphicsScenePrivate::registerTopLevelItem().
-*/
-void QGraphicsItemPrivate::addChild(QGraphicsItem *child)
-{
- // Remove all holes from the sibling index list. Now the max index
- // number is equal to the size of the children list.
- ensureSequentialSiblingIndex();
- needSortChildren = 1; // ### maybe 0
- child->d_ptr->siblingIndex = children.size();
- children.append(child);
- if (isObject)
- emit static_cast<QGraphicsObject *>(q_ptr)->childrenChanged();
-}
-
-/*!
- \internal
-
- ### This function is almost identical to
- QGraphicsScenePrivate::unregisterTopLevelItem().
-*/
-void QGraphicsItemPrivate::removeChild(QGraphicsItem *child)
-{
- // When removing elements in the middle of the children list,
- // there will be a "gap" in the list of sibling indexes (0,1,3,4).
- if (!holesInSiblingIndex)
- holesInSiblingIndex = child->d_ptr->siblingIndex != children.size() - 1;
- if (sequentialOrdering && !holesInSiblingIndex)
- children.removeAt(child->d_ptr->siblingIndex);
- else
- children.removeOne(child);
- // NB! Do not use children.removeAt(child->d_ptr->siblingIndex) because
- // the child is not guaranteed to be at the index after the list is sorted.
- // (see ensureSortedChildren()).
- child->d_ptr->siblingIndex = -1;
- if (isObject)
- emit static_cast<QGraphicsObject *>(q_ptr)->childrenChanged();
-}
-
-/*!
- \internal
-*/
-QGraphicsItemCache *QGraphicsItemPrivate::maybeExtraItemCache() const
-{
- return (QGraphicsItemCache *)qvariant_cast<void *>(extra(ExtraCacheData));
-}
-
-/*!
- \internal
-*/
-QGraphicsItemCache *QGraphicsItemPrivate::extraItemCache() const
-{
- QGraphicsItemCache *c = (QGraphicsItemCache *)qvariant_cast<void *>(extra(ExtraCacheData));
- if (!c) {
- QGraphicsItemPrivate *that = const_cast<QGraphicsItemPrivate *>(this);
- c = new QGraphicsItemCache;
- that->setExtra(ExtraCacheData, QVariant::fromValue<void *>(c));
- }
- return c;
-}
-
-/*!
- \internal
-*/
-void QGraphicsItemPrivate::removeExtraItemCache()
-{
- QGraphicsItemCache *c = (QGraphicsItemCache *)qvariant_cast<void *>(extra(ExtraCacheData));
- if (c) {
- c->purge();
- delete c;
- }
- unsetExtra(ExtraCacheData);
-}
-
-void QGraphicsItemPrivate::updatePaintedViewBoundingRects(bool updateChildren)
-{
- if (!scene)
- return;
-
- for (int i = 0; i < scene->d_func()->views.size(); ++i) {
- QGraphicsViewPrivate *viewPrivate = scene->d_func()->views.at(i)->d_func();
- QRect rect = paintedViewBoundingRects.value(viewPrivate->viewport);
- rect.translate(viewPrivate->dirtyScrollOffset);
- viewPrivate->updateRect(rect);
- }
-
- if (updateChildren) {
- for (int i = 0; i < children.size(); ++i)
- children.at(i)->d_ptr->updatePaintedViewBoundingRects(true);
- }
-}
-
-// Traverses all the ancestors up to the top-level and updates the pointer to
-// always point to the top-most item that has a dirty scene transform.
-// It then backtracks to the top-most dirty item and start calculating the
-// scene transform by combining the item's transform (+pos) with the parent's
-// cached scene transform (which we at this point know for sure is valid).
-void QGraphicsItemPrivate::ensureSceneTransformRecursive(QGraphicsItem **topMostDirtyItem)
-{
- Q_ASSERT(topMostDirtyItem);
-
- if (dirtySceneTransform)
- *topMostDirtyItem = q_ptr;
-
- if (parent)
- parent->d_ptr->ensureSceneTransformRecursive(topMostDirtyItem);
-
- if (*topMostDirtyItem == q_ptr) {
- if (!dirtySceneTransform)
- return; // OK, neither my ancestors nor I have dirty scene transforms.
- *topMostDirtyItem = 0;
- } else if (*topMostDirtyItem) {
- return; // Continue backtrack.
- }
-
- // This item and all its descendants have dirty scene transforms.
- // We're about to validate this item's scene transform, so we have to
- // invalidate all the children; otherwise there's no way for the descendants
- // to detect that the ancestor has changed.
- invalidateChildrenSceneTransform();
-
- // COMBINE my transform with the parent's scene transform.
- updateSceneTransformFromParent();
- Q_ASSERT(!dirtySceneTransform);
-}
-
-/*!
- \internal
-*/
-void QGraphicsItemPrivate::setSubFocus(QGraphicsItem *rootItem, QGraphicsItem *stopItem)
-{
- // Update focus child chain. Stop at panels, or if this item
- // is hidden, stop at the first item with a visible parent.
- QGraphicsItem *parent = rootItem ? rootItem : q_ptr;
- if (parent->panel() != q_ptr->panel())
- return;
-
- do {
- // Clear any existing ancestor's subFocusItem.
- if (parent != q_ptr && parent->d_ptr->subFocusItem) {
- if (parent->d_ptr->subFocusItem == q_ptr)
- break;
- parent->d_ptr->subFocusItem->d_ptr->clearSubFocus(0, stopItem);
- }
- parent->d_ptr->subFocusItem = q_ptr;
- parent->d_ptr->subFocusItemChange();
- } while (!parent->isPanel() && (parent = parent->d_ptr->parent) && (visible || !parent->d_ptr->visible));
-
- if (scene && !scene->isActive()) {
- scene->d_func()->passiveFocusItem = subFocusItem;
- scene->d_func()->lastFocusItem = subFocusItem;
- }
-}
-
-/*!
- \internal
-*/
-void QGraphicsItemPrivate::clearSubFocus(QGraphicsItem *rootItem, QGraphicsItem *stopItem)
-{
- // Reset sub focus chain.
- QGraphicsItem *parent = rootItem ? rootItem : q_ptr;
- do {
- if (parent->d_ptr->subFocusItem != q_ptr)
- break;
- parent->d_ptr->subFocusItem = 0;
- if (parent != stopItem && !parent->isAncestorOf(stopItem))
- parent->d_ptr->subFocusItemChange();
- } while (!parent->isPanel() && (parent = parent->d_ptr->parent));
-}
-
-/*!
- \internal
-
- Sets the focusProxy pointer to 0 for all items that have this item as their
- focusProxy. ### Qt 5: Use QPointer instead.
-*/
-void QGraphicsItemPrivate::resetFocusProxy()
-{
- for (int i = 0; i < focusProxyRefs.size(); ++i)
- *focusProxyRefs.at(i) = 0;
- focusProxyRefs.clear();
-}
-
-/*!
- \internal
-
- Subclasses can reimplement this function to be notified when subFocusItem
- changes.
-*/
-void QGraphicsItemPrivate::subFocusItemChange()
-{
-}
-
-/*!
- \internal
-
- Subclasses can reimplement this function to be notified when an item
- becomes a focusScopeItem (or is no longer a focusScopeItem).
-*/
-void QGraphicsItemPrivate::focusScopeItemChange(bool isSubFocusItem)
-{
- Q_UNUSED(isSubFocusItem);
-}
-
-/*!
- \internal
-
- Subclasses can reimplement this function to be notified when its
- siblingIndex order is changed.
-*/
-void QGraphicsItemPrivate::siblingOrderChange()
-{
-}
-
-/*!
- \internal
-
- Tells us if it is a proxy widget
-*/
-bool QGraphicsItemPrivate::isProxyWidget() const
-{
- return false;
-}
-
-/*!
- Schedules a redraw of the area covered by \a rect in this item. You can
- call this function whenever your item needs to be redrawn, such as if it
- changes appearance or size.
-
- This function does not cause an immediate paint; instead it schedules a
- paint request that is processed by QGraphicsView after control reaches the
- event loop. The item will only be redrawn if it is visible in any
- associated view.
-
- As a side effect of the item being repainted, other items that overlap the
- area \a rect may also be repainted.
-
- If the item is invisible (i.e., isVisible() returns false), this function
- does nothing.
-
- \sa paint(), boundingRect()
-*/
-void QGraphicsItem::update(const QRectF &rect)
-{
- if (rect.isEmpty() && !rect.isNull())
- return;
-
- // Make sure we notify effects about invalidated source.
-#ifndef QT_NO_GRAPHICSEFFECT
- d_ptr->invalidateParentGraphicsEffectsRecursively();
-#endif //QT_NO_GRAPHICSEFFECT
-
- if (CacheMode(d_ptr->cacheMode) != NoCache) {
- // Invalidate cache.
- QGraphicsItemCache *cache = d_ptr->extraItemCache();
- if (!cache->allExposed) {
- if (rect.isNull()) {
- cache->allExposed = true;
- cache->exposed.clear();
- } else {
- cache->exposed.append(rect);
- }
- }
- // Only invalidate cache; item is already dirty.
- if (d_ptr->fullUpdatePending)
- return;
- }
-
- if (d_ptr->scene)
- d_ptr->scene->d_func()->markDirty(this, rect);
-}
-
-/*!
- \since 4.4
- Scrolls the contents of \a rect by \a dx, \a dy. If \a rect is a null rect
- (the default), the item's bounding rect is scrolled.
-
- Scrolling provides a fast alternative to simply redrawing when the
- contents of the item (or parts of the item) are shifted vertically or
- horizontally. Depending on the current transformation and the capabilities
- of the paint device (i.e., the viewport), this operation may consist of
- simply moving pixels from one location to another using memmove(). In most
- cases this is faster than rerendering the entire area.
-
- After scrolling, the item will issue an update for the newly exposed
- areas. If scrolling is not supported (e.g., you are rendering to an OpenGL
- viewport, which does not benefit from scroll optimizations), this function
- is equivalent to calling update(\a rect).
-
- \bold{Note:} Scrolling is only supported when QGraphicsItem::ItemCoordinateCache
- is enabled; in all other cases calling this function is equivalent to calling
- update(\a rect). If you for sure know that the item is opaque and not overlapped
- by other items, you can map the \a rect to viewport coordinates and scroll the
- viewport.
-
- \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 19
-
- \sa boundingRect()
-*/
-void QGraphicsItem::scroll(qreal dx, qreal dy, const QRectF &rect)
-{
- Q_D(QGraphicsItem);
- if (dx == 0.0 && dy == 0.0)
- return;
- if (!d->scene)
- return;
-
- // Accelerated scrolling means moving pixels from one location to another
- // and only redraw the newly exposed area. The following requirements must
- // be fulfilled in order to do that:
- //
- // 1) Item is opaque.
- // 2) Item is not overlapped by other items.
- //
- // There's (yet) no way to detect whether an item is opaque or not, which means
- // we cannot do accelerated scrolling unless the cache is enabled. In case of using
- // DeviceCoordinate cache we also have to take the device transform into account in
- // order to determine whether we can do accelerated scrolling or not. That's left out
- // for simplicity here, but it is definitely something we can consider in the future
- // as a performance improvement.
- if (d->cacheMode != QGraphicsItem::ItemCoordinateCache
- || !qFuzzyIsNull(dx - int(dx)) || !qFuzzyIsNull(dy - int(dy))) {
- update(rect);
- return;
- }
-
- QGraphicsItemCache *cache = d->extraItemCache();
- if (cache->allExposed || cache->fixedSize.isValid()) {
- // Cache is either invalidated or item is scaled (see QGraphicsItem::setCacheMode).
- update(rect);
- return;
- }
-
- // Find pixmap in cache.
- QPixmap cachedPixmap;
- if (!QPixmapCache::find(cache->key, &cachedPixmap)) {
- update(rect);
- return;
- }
-
- QRect scrollRect = (rect.isNull() ? boundingRect() : rect).toAlignedRect();
- if (!scrollRect.intersects(cache->boundingRect))
- return; // Nothing to scroll.
-
- // Remove from cache to avoid deep copy when modifying.
- QPixmapCache::remove(cache->key);
-
- QRegion exposed;
- cachedPixmap.scroll(dx, dy, scrollRect.translated(-cache->boundingRect.topLeft()), &exposed);
-
- // Reinsert into cache.
- cache->key = QPixmapCache::insert(cachedPixmap);
-
- // Translate the existing expose.
- for (int i = 0; i < cache->exposed.size(); ++i) {
- QRectF &e = cache->exposed[i];
- if (!rect.isNull() && !e.intersects(rect))
- continue;
- e.translate(dx, dy);
- }
-
- // Append newly exposed areas. Note that the exposed region is currently
- // in pixmap coordinates, so we have to translate it to item coordinates.
- exposed.translate(cache->boundingRect.topLeft());
- const QVector<QRect> exposedRects = exposed.rects();
- for (int i = 0; i < exposedRects.size(); ++i)
- cache->exposed += exposedRects.at(i);
-
- // Trigger update. This will redraw the newly exposed area and make sure
- // the pixmap is re-blitted in case there are overlapping items.
- d->scene->d_func()->markDirty(this, rect);
-}
-
-/*!
- \fn void QGraphicsItem::update(qreal x, qreal y, qreal width, qreal height)
- \overload
-
- This convenience function is equivalent to calling update(QRectF(\a x, \a
- y, \a width, \a height)).
-*/
-
-/*!
- Maps the point \a point, which is in this item's coordinate system, to \a
- item's coordinate system, and returns the mapped coordinate.
-
- If \a item is 0, this function returns the same as mapToScene().
-
- \sa itemTransform(), mapToParent(), mapToScene(), transform(), mapFromItem(), {The Graphics
- View Coordinate System}
-*/
-QPointF QGraphicsItem::mapToItem(const QGraphicsItem *item, const QPointF &point) const
-{
- if (item)
- return itemTransform(item).map(point);
- return mapToScene(point);
-}
-
-/*!
- \fn QPointF QGraphicsItem::mapToItem(const QGraphicsItem *item, qreal x, qreal y) const
- \overload
-
- This convenience function is equivalent to calling mapToItem(\a item,
- QPointF(\a x, \a y)).
-*/
-
-/*!
- Maps the point \a point, which is in this item's coordinate system, to its
- parent's coordinate system, and returns the mapped coordinate. If the item
- has no parent, \a point will be mapped to the scene's coordinate system.
-
- \sa mapToItem(), mapToScene(), transform(), mapFromParent(), {The Graphics
- View Coordinate System}
-*/
-QPointF QGraphicsItem::mapToParent(const QPointF &point) const
-{
- // COMBINE
- if (!d_ptr->transformData)
- return point + d_ptr->pos;
- return d_ptr->transformToParent().map(point);
-}
-
-/*!
- \fn QPointF QGraphicsItem::mapToParent(qreal x, qreal y) const
- \overload
-
- This convenience function is equivalent to calling mapToParent(QPointF(\a
- x, \a y)).
-*/
-
-/*!
- Maps the point \a point, which is in this item's coordinate system, to the
- scene's coordinate system, and returns the mapped coordinate.
-
- \sa mapToItem(), mapToParent(), transform(), mapFromScene(), {The Graphics
- View Coordinate System}
-*/
-QPointF QGraphicsItem::mapToScene(const QPointF &point) const
-{
- if (d_ptr->hasTranslateOnlySceneTransform())
- return QPointF(point.x() + d_ptr->sceneTransform.dx(), point.y() + d_ptr->sceneTransform.dy());
- return d_ptr->sceneTransform.map(point);
-}
-
-/*!
- \fn QPointF QGraphicsItem::mapToScene(qreal x, qreal y) const
- \overload
-
- This convenience function is equivalent to calling mapToScene(QPointF(\a
- x, \a y)).
-*/
-
-/*!
- Maps the rectangle \a rect, which is in this item's coordinate system, to
- \a item's coordinate system, and returns the mapped rectangle as a polygon.
-
- If \a item is 0, this function returns the same as mapToScene().
-
- \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
- Graphics View Coordinate System}
-*/
-QPolygonF QGraphicsItem::mapToItem(const QGraphicsItem *item, const QRectF &rect) const
-{
- if (item)
- return itemTransform(item).map(rect);
- return mapToScene(rect);
-}
-
-/*!
- \fn QPolygonF QGraphicsItem::mapToItem(const QGraphicsItem *item, qreal x, qreal y, qreal w, qreal h) const
- \since 4.3
-
- This convenience function is equivalent to calling mapToItem(item, QRectF(\a x, \a y, \a w, \a h)).
-*/
-
-/*!
- Maps the rectangle \a rect, which is in this item's coordinate system, to
- its parent's coordinate system, and returns the mapped rectangle as a
- polygon. If the item has no parent, \a rect will be mapped to the scene's
- coordinate system.
-
- \sa mapToScene(), mapToItem(), mapFromParent(), {The Graphics View
- Coordinate System}
-*/
-QPolygonF QGraphicsItem::mapToParent(const QRectF &rect) const
-{
- // COMBINE
- if (!d_ptr->transformData)
- return rect.translated(d_ptr->pos);
- return d_ptr->transformToParent().map(rect);
-}
-
-/*!
- \fn QPolygonF QGraphicsItem::mapToParent(qreal x, qreal y, qreal w, qreal h) const
- \since 4.3
-
- This convenience function is equivalent to calling mapToParent(QRectF(\a x, \a y, \a w, \a h)).
-*/
-
-/*!
- Maps the rectangle \a rect, which is in this item's coordinate system, to
- the scene's coordinate system, and returns the mapped rectangle as a polygon.
-
- \sa mapToParent(), mapToItem(), mapFromScene(), {The Graphics View
- Coordinate System}
-*/
-QPolygonF QGraphicsItem::mapToScene(const QRectF &rect) const
-{
- if (d_ptr->hasTranslateOnlySceneTransform())
- return rect.translated(d_ptr->sceneTransform.dx(), d_ptr->sceneTransform.dy());
- return d_ptr->sceneTransform.map(rect);
-}
-
-/*!
- \fn QPolygonF QGraphicsItem::mapToScene(qreal x, qreal y, qreal w, qreal h) const
- \since 4.3
-
- This convenience function is equivalent to calling mapToScene(QRectF(\a x, \a y, \a w, \a h)).
-*/
-
-/*!
- \since 4.5
-
- Maps the rectangle \a rect, which is in this item's coordinate system, to
- \a item's coordinate system, and returns the mapped rectangle as a new
- rectangle (i.e., the bounding rectangle of the resulting polygon).
-
- If \a item is 0, this function returns the same as mapRectToScene().
-
- \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
- Graphics View Coordinate System}
-*/
-QRectF QGraphicsItem::mapRectToItem(const QGraphicsItem *item, const QRectF &rect) const
-{
- if (item)
- return itemTransform(item).mapRect(rect);
- return mapRectToScene(rect);
-}
-
-/*!
- \fn QRectF QGraphicsItem::mapRectToItem(const QGraphicsItem *item, qreal x, qreal y, qreal w, qreal h) const
- \since 4.5
-
- This convenience function is equivalent to calling mapRectToItem(item, QRectF(\a x, \a y, \a w, \a h)).
-*/
-
-/*!
- \since 4.5
-
- Maps the rectangle \a rect, which is in this item's coordinate system, to
- its parent's coordinate system, and returns the mapped rectangle as a new
- rectangle (i.e., the bounding rectangle of the resulting polygon).
-
- \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
- Graphics View Coordinate System}
-*/
-QRectF QGraphicsItem::mapRectToParent(const QRectF &rect) const
-{
- // COMBINE
- if (!d_ptr->transformData)
- return rect.translated(d_ptr->pos);
- return d_ptr->transformToParent().mapRect(rect);
-}
-
-/*!
- \fn QRectF QGraphicsItem::mapRectToParent(qreal x, qreal y, qreal w, qreal h) const
- \since 4.5
-
- This convenience function is equivalent to calling mapRectToParent(QRectF(\a x, \a y, \a w, \a h)).
-*/
-
-/*!
- \since 4.5
-
- Maps the rectangle \a rect, which is in this item's coordinate system, to
- the scene coordinate system, and returns the mapped rectangle as a new
- rectangle (i.e., the bounding rectangle of the resulting polygon).
-
- \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
- Graphics View Coordinate System}
-*/
-QRectF QGraphicsItem::mapRectToScene(const QRectF &rect) const
-{
- if (d_ptr->hasTranslateOnlySceneTransform())
- return rect.translated(d_ptr->sceneTransform.dx(), d_ptr->sceneTransform.dy());
- return d_ptr->sceneTransform.mapRect(rect);
-}
-
-/*!
- \fn QRectF QGraphicsItem::mapRectToScene(qreal x, qreal y, qreal w, qreal h) const
- \since 4.5
-
- This convenience function is equivalent to calling mapRectToScene(QRectF(\a x, \a y, \a w, \a h)).
-*/
-
-/*!
- \since 4.5
-
- Maps the rectangle \a rect, which is in \a item's coordinate system, to
- this item's coordinate system, and returns the mapped rectangle as a new
- rectangle (i.e., the bounding rectangle of the resulting polygon).
-
- If \a item is 0, this function returns the same as mapRectFromScene().
-
- \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
- Graphics View Coordinate System}
-*/
-QRectF QGraphicsItem::mapRectFromItem(const QGraphicsItem *item, const QRectF &rect) const
-{
- if (item)
- return item->itemTransform(this).mapRect(rect);
- return mapRectFromScene(rect);
-}
-
-/*!
- \fn QRectF QGraphicsItem::mapRectFromItem(const QGraphicsItem *item, qreal x, qreal y, qreal w, qreal h) const
- \since 4.5
-
- This convenience function is equivalent to calling mapRectFromItem(item, QRectF(\a x, \a y, \a w, \a h)).
-*/
-
-/*!
- \since 4.5
-
- Maps the rectangle \a rect, which is in this item's parent's coordinate
- system, to this item's coordinate system, and returns the mapped rectangle
- as a new rectangle (i.e., the bounding rectangle of the resulting
- polygon).
-
- \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
- Graphics View Coordinate System}
-*/
-QRectF QGraphicsItem::mapRectFromParent(const QRectF &rect) const
-{
- // COMBINE
- if (!d_ptr->transformData)
- return rect.translated(-d_ptr->pos);
- return d_ptr->transformToParent().inverted().mapRect(rect);
-}
-
-/*!
- \fn QRectF QGraphicsItem::mapRectFromParent(qreal x, qreal y, qreal w, qreal h) const
- \since 4.5
-
- This convenience function is equivalent to calling mapRectFromParent(QRectF(\a x, \a y, \a w, \a h)).
-*/
-
-/*!
- \since 4.5
-
- Maps the rectangle \a rect, which is in scene coordinates, to this item's
- coordinate system, and returns the mapped rectangle as a new rectangle
- (i.e., the bounding rectangle of the resulting polygon).
-
- \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
- Graphics View Coordinate System}
-*/
-QRectF QGraphicsItem::mapRectFromScene(const QRectF &rect) const
-{
- if (d_ptr->hasTranslateOnlySceneTransform())
- return rect.translated(-d_ptr->sceneTransform.dx(), -d_ptr->sceneTransform.dy());
- return d_ptr->sceneTransform.inverted().mapRect(rect);
-}
-
-/*!
- \fn QRectF QGraphicsItem::mapRectFromScene(qreal x, qreal y, qreal w, qreal h) const
- \since 4.5
-
- This convenience function is equivalent to calling mapRectFromScene(QRectF(\a x, \a y, \a w, \a h)).
-*/
-
-/*!
- Maps the polygon \a polygon, which is in this item's coordinate system, to
- \a item's coordinate system, and returns the mapped polygon.
-
- If \a item is 0, this function returns the same as mapToScene().
-
- \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
- Graphics View Coordinate System}
-*/
-QPolygonF QGraphicsItem::mapToItem(const QGraphicsItem *item, const QPolygonF &polygon) const
-{
- if (item)
- return itemTransform(item).map(polygon);
- return mapToScene(polygon);
-}
-
-/*!
- Maps the polygon \a polygon, which is in this item's coordinate system, to
- its parent's coordinate system, and returns the mapped polygon. If the
- item has no parent, \a polygon will be mapped to the scene's coordinate
- system.
-
- \sa mapToScene(), mapToItem(), mapFromParent(), {The Graphics View
- Coordinate System}
-*/
-QPolygonF QGraphicsItem::mapToParent(const QPolygonF &polygon) const
-{
- // COMBINE
- if (!d_ptr->transformData)
- return polygon.translated(d_ptr->pos);
- return d_ptr->transformToParent().map(polygon);
-}
-
-/*!
- Maps the polygon \a polygon, which is in this item's coordinate system, to
- the scene's coordinate system, and returns the mapped polygon.
-
- \sa mapToParent(), mapToItem(), mapFromScene(), {The Graphics View
- Coordinate System}
-*/
-QPolygonF QGraphicsItem::mapToScene(const QPolygonF &polygon) const
-{
- if (d_ptr->hasTranslateOnlySceneTransform())
- return polygon.translated(d_ptr->sceneTransform.dx(), d_ptr->sceneTransform.dy());
- return d_ptr->sceneTransform.map(polygon);
-}
-
-/*!
- Maps the path \a path, which is in this item's coordinate system, to
- \a item's coordinate system, and returns the mapped path.
-
- If \a item is 0, this function returns the same as mapToScene().
-
- \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
- Graphics View Coordinate System}
-*/
-QPainterPath QGraphicsItem::mapToItem(const QGraphicsItem *item, const QPainterPath &path) const
-{
- if (item)
- return itemTransform(item).map(path);
- return mapToScene(path);
-}
-
-/*!
- Maps the path \a path, which is in this item's coordinate system, to
- its parent's coordinate system, and returns the mapped path. If the
- item has no parent, \a path will be mapped to the scene's coordinate
- system.
-
- \sa mapToScene(), mapToItem(), mapFromParent(), {The Graphics View
- Coordinate System}
-*/
-QPainterPath QGraphicsItem::mapToParent(const QPainterPath &path) const
-{
- // COMBINE
- if (!d_ptr->transformData)
- return path.translated(d_ptr->pos);
- return d_ptr->transformToParent().map(path);
-}
-
-/*!
- Maps the path \a path, which is in this item's coordinate system, to
- the scene's coordinate system, and returns the mapped path.
-
- \sa mapToParent(), mapToItem(), mapFromScene(), {The Graphics View
- Coordinate System}
-*/
-QPainterPath QGraphicsItem::mapToScene(const QPainterPath &path) const
-{
- if (d_ptr->hasTranslateOnlySceneTransform())
- return path.translated(d_ptr->sceneTransform.dx(), d_ptr->sceneTransform.dy());
- return d_ptr->sceneTransform.map(path);
-}
-
-/*!
- Maps the point \a point, which is in \a item's coordinate system, to this
- item's coordinate system, and returns the mapped coordinate.
-
- If \a item is 0, this function returns the same as mapFromScene().
-
- \sa itemTransform(), mapFromParent(), mapFromScene(), transform(), mapToItem(), {The Graphics
- View Coordinate System}
-*/
-QPointF QGraphicsItem::mapFromItem(const QGraphicsItem *item, const QPointF &point) const
-{
- if (item)
- return item->itemTransform(this).map(point);
- return mapFromScene(point);
-}
-
-/*!
- \fn QPointF QGraphicsItem::mapFromItem(const QGraphicsItem *item, qreal x, qreal y) const
- \overload
-
- This convenience function is equivalent to calling mapFromItem(\a item,
- QPointF(\a x, \a y)).
-*/
-
-/*!
- Maps the point \a point, which is in this item's parent's coordinate
- system, to this item's coordinate system, and returns the mapped
- coordinate.
-
- \sa mapFromItem(), mapFromScene(), transform(), mapToParent(), {The Graphics
- View Coordinate System}
-*/
-QPointF QGraphicsItem::mapFromParent(const QPointF &point) const
-{
- // COMBINE
- if (d_ptr->transformData)
- return d_ptr->transformToParent().inverted().map(point);
- return point - d_ptr->pos;
-}
-
-/*!
- \fn QPointF QGraphicsItem::mapFromParent(qreal x, qreal y) const
- \overload
-
- This convenience function is equivalent to calling
- mapFromParent(QPointF(\a x, \a y)).
-*/
-
-/*!
- Maps the point \a point, which is in this item's scene's coordinate
- system, to this item's coordinate system, and returns the mapped
- coordinate.
-
- \sa mapFromItem(), mapFromParent(), transform(), mapToScene(), {The Graphics
- View Coordinate System}
-*/
-QPointF QGraphicsItem::mapFromScene(const QPointF &point) const
-{
- if (d_ptr->hasTranslateOnlySceneTransform())
- return QPointF(point.x() - d_ptr->sceneTransform.dx(), point.y() - d_ptr->sceneTransform.dy());
- return d_ptr->sceneTransform.inverted().map(point);
-}
-
-/*!
- \fn QPointF QGraphicsItem::mapFromScene(qreal x, qreal y) const
- \overload
-
- This convenience function is equivalent to calling mapFromScene(QPointF(\a
- x, \a y)).
-*/
-
-/*!
- Maps the rectangle \a rect, which is in \a item's coordinate system, to
- this item's coordinate system, and returns the mapped rectangle as a
- polygon.
-
- If \a item is 0, this function returns the same as mapFromScene()
-
- \sa itemTransform(), mapToItem(), mapFromParent(), transform(), {The Graphics View Coordinate
- System}
-*/
-QPolygonF QGraphicsItem::mapFromItem(const QGraphicsItem *item, const QRectF &rect) const
-{
- if (item)
- return item->itemTransform(this).map(rect);
- return mapFromScene(rect);
-}
-
-/*!
- \fn QPolygonF QGraphicsItem::mapFromItem(const QGraphicsItem *item, qreal x, qreal y, qreal w, qreal h) const
- \since 4.3
-
- This convenience function is equivalent to calling mapFromItem(item, QRectF(\a x, \a y, \a w, \a h)).
-*/
-
-/*!
- Maps the rectangle \a rect, which is in this item's parent's coordinate
- system, to this item's coordinate system, and returns the mapped rectangle
- as a polygon.
-
- \sa mapToParent(), mapFromItem(), transform(), {The Graphics View Coordinate
- System}
-*/
-QPolygonF QGraphicsItem::mapFromParent(const QRectF &rect) const
-{
- // COMBINE
- if (!d_ptr->transformData)
- return rect.translated(-d_ptr->pos);
- return d_ptr->transformToParent().inverted().map(rect);
-}
-
-/*!
- \fn QPolygonF QGraphicsItem::mapFromParent(qreal x, qreal y, qreal w, qreal h) const
- \since 4.3
-
- This convenience function is equivalent to calling mapFromItem(QRectF(\a x, \a y, \a w, \a h)).
-*/
-
-/*!
- Maps the rectangle \a rect, which is in this item's scene's coordinate
- system, to this item's coordinate system, and returns the mapped rectangle
- as a polygon.
-
- \sa mapToScene(), mapFromItem(), transform(), {The Graphics View Coordinate
- System}
-*/
-QPolygonF QGraphicsItem::mapFromScene(const QRectF &rect) const
-{
- if (d_ptr->hasTranslateOnlySceneTransform())
- return rect.translated(-d_ptr->sceneTransform.dx(), -d_ptr->sceneTransform.dy());
- return d_ptr->sceneTransform.inverted().map(rect);
-}
-
-/*!
- \fn QPolygonF QGraphicsItem::mapFromScene(qreal x, qreal y, qreal w, qreal h) const
- \since 4.3
-
- This convenience function is equivalent to calling mapFromScene(QRectF(\a x, \a y, \a w, \a h)).
-*/
-
-/*!
- Maps the polygon \a polygon, which is in \a item's coordinate system, to
- this item's coordinate system, and returns the mapped polygon.
-
- If \a item is 0, this function returns the same as mapFromScene().
-
- \sa itemTransform(), mapToItem(), mapFromParent(), transform(), {The
- Graphics View Coordinate System}
-*/
-QPolygonF QGraphicsItem::mapFromItem(const QGraphicsItem *item, const QPolygonF &polygon) const
-{
- if (item)
- return item->itemTransform(this).map(polygon);
- return mapFromScene(polygon);
-}
-
-/*!
- Maps the polygon \a polygon, which is in this item's parent's coordinate
- system, to this item's coordinate system, and returns the mapped polygon.
-
- \sa mapToParent(), mapToItem(), transform(), {The Graphics View Coordinate
- System}
-*/
-QPolygonF QGraphicsItem::mapFromParent(const QPolygonF &polygon) const
-{
- // COMBINE
- if (!d_ptr->transformData)
- return polygon.translated(-d_ptr->pos);
- return d_ptr->transformToParent().inverted().map(polygon);
-}
-
-/*!
- Maps the polygon \a polygon, which is in this item's scene's coordinate
- system, to this item's coordinate system, and returns the mapped polygon.
-
- \sa mapToScene(), mapFromParent(), transform(), {The Graphics View Coordinate
- System}
-*/
-QPolygonF QGraphicsItem::mapFromScene(const QPolygonF &polygon) const
-{
- if (d_ptr->hasTranslateOnlySceneTransform())
- return polygon.translated(-d_ptr->sceneTransform.dx(), -d_ptr->sceneTransform.dy());
- return d_ptr->sceneTransform.inverted().map(polygon);
-}
-
-/*!
- Maps the path \a path, which is in \a item's coordinate system, to
- this item's coordinate system, and returns the mapped path.
-
- If \a item is 0, this function returns the same as mapFromScene().
-
- \sa itemTransform(), mapFromParent(), mapFromScene(), mapToItem(), {The
- Graphics View Coordinate System}
-*/
-QPainterPath QGraphicsItem::mapFromItem(const QGraphicsItem *item, const QPainterPath &path) const
-{
- if (item)
- return item->itemTransform(this).map(path);
- return mapFromScene(path);
-}
-
-/*!
- Maps the path \a path, which is in this item's parent's coordinate
- system, to this item's coordinate system, and returns the mapped path.
-
- \sa mapFromScene(), mapFromItem(), mapToParent(), {The Graphics View
- Coordinate System}
-*/
-QPainterPath QGraphicsItem::mapFromParent(const QPainterPath &path) const
-{
- // COMBINE
- if (!d_ptr->transformData)
- return path.translated(-d_ptr->pos);
- return d_ptr->transformToParent().inverted().map(path);
-}
-
-/*!
- Maps the path \a path, which is in this item's scene's coordinate
- system, to this item's coordinate system, and returns the mapped path.
-
- \sa mapFromParent(), mapFromItem(), mapToScene(), {The Graphics View
- Coordinate System}
-*/
-QPainterPath QGraphicsItem::mapFromScene(const QPainterPath &path) const
-{
- if (d_ptr->hasTranslateOnlySceneTransform())
- return path.translated(-d_ptr->sceneTransform.dx(), -d_ptr->sceneTransform.dy());
- return d_ptr->sceneTransform.inverted().map(path);
-}
-
-/*!
- Returns true if this item is an ancestor of \a child (i.e., if this item
- is \a child's parent, or one of \a child's parent's ancestors).
-
- \sa parentItem()
-*/
-bool QGraphicsItem::isAncestorOf(const QGraphicsItem *child) const
-{
- if (!child || child == this)
- return false;
- if (child->d_ptr->depth() < d_ptr->depth())
- return false;
- const QGraphicsItem *ancestor = child;
- while ((ancestor = ancestor->d_ptr->parent)) {
- if (ancestor == this)
- return true;
- }
- return false;
-}
-
-/*!
- \since 4.4
-
- Returns the closest common ancestor item of this item and \a other, or 0
- if either \a other is 0, or there is no common ancestor.
-
- \sa isAncestorOf()
-*/
-QGraphicsItem *QGraphicsItem::commonAncestorItem(const QGraphicsItem *other) const
-{
- if (!other)
- return 0;
- if (other == this)
- return const_cast<QGraphicsItem *>(this);
- const QGraphicsItem *thisw = this;
- const QGraphicsItem *otherw = other;
- int thisDepth = d_ptr->depth();
- int otherDepth = other->d_ptr->depth();
- while (thisDepth > otherDepth) {
- thisw = thisw->d_ptr->parent;
- --thisDepth;
- }
- while (otherDepth > thisDepth) {
- otherw = otherw->d_ptr->parent;
- --otherDepth;
- }
- while (thisw && thisw != otherw) {
- thisw = thisw->d_ptr->parent;
- otherw = otherw->d_ptr->parent;
- }
- return const_cast<QGraphicsItem *>(thisw);
-}
-
-/*!
- \since 4,4
- Returns true if this item is currently under the mouse cursor in one of
- the views; otherwise, false is returned.
-
- \sa QGraphicsScene::views(), QCursor::pos()
-*/
-bool QGraphicsItem::isUnderMouse() const
-{
- Q_D(const QGraphicsItem);
- if (!d->scene)
- return false;
-
- QPoint cursorPos = QCursor::pos();
- foreach (QGraphicsView *view, d->scene->views()) {
- if (contains(mapFromScene(view->mapToScene(view->mapFromGlobal(cursorPos)))))
- return true;
- }
- return false;
-}
-
-/*!
- Returns this item's custom data for the key \a key as a QVariant.
-
- Custom item data is useful for storing arbitrary properties in any
- item. Example:
-
- \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 11
-
- Qt does not use this feature for storing data; it is provided solely
- for the convenience of the user.
-
- \sa setData()
-*/
-QVariant QGraphicsItem::data(int key) const
-{
- QGraphicsItemCustomDataStore *store = qt_dataStore();
- if (!store->data.contains(this))
- return QVariant();
- return store->data.value(this).value(key);
-}
-
-/*!
- Sets this item's custom data for the key \a key to \a value.
-
- Custom item data is useful for storing arbitrary properties for any
- item. Qt does not use this feature for storing data; it is provided solely
- for the convenience of the user.
-
- \sa data()
-*/
-void QGraphicsItem::setData(int key, const QVariant &value)
-{
- qt_dataStore()->data[this][key] = value;
-}
-
-/*!
- \fn T qgraphicsitem_cast(QGraphicsItem *item)
- \relates QGraphicsItem
- \since 4.2
-
- Returns the given \a item cast to type T if \a item is of type T;
- otherwise, 0 is returned.
-
- \note To make this function work correctly with custom items, reimplement
- the \l{QGraphicsItem::}{type()} function for each custom QGraphicsItem
- subclass.
-
- \sa QGraphicsItem::type(), QGraphicsItem::UserType
-*/
-
-/*!
- Returns the type of an item as an int. All standard graphicsitem classes
- are associated with a unique value; see QGraphicsItem::Type. This type
- information is used by qgraphicsitem_cast() to distinguish between types.
-
- The default implementation (in QGraphicsItem) returns UserType.
-
- To enable use of qgraphicsitem_cast() with a custom item, reimplement this
- function and declare a Type enum value equal to your custom item's type.
- Custom items must return a value larger than or equal to UserType (65536).
-
- For example:
-
- \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp QGraphicsItem type
-
- \sa UserType
-*/
-int QGraphicsItem::type() const
-{
- return (int)UserType;
-}
-
-/*!
- Installs an event filter for this item on \a filterItem, causing
- all events for this item to first pass through \a filterItem's
- sceneEventFilter() function.
-
- To filter another item's events, install this item as an event filter
- for the other item. Example:
-
- \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 12
-
- An item can only filter events for other items in the same
- scene. Also, an item cannot filter its own events; instead, you
- can reimplement sceneEvent() directly.
-
- Items must belong to a scene for scene event filters to be installed and
- used.
-
- \sa removeSceneEventFilter(), sceneEventFilter(), sceneEvent()
-*/
-void QGraphicsItem::installSceneEventFilter(QGraphicsItem *filterItem)
-{
- if (!d_ptr->scene) {
- qWarning("QGraphicsItem::installSceneEventFilter: event filters can only be installed"
- " on items in a scene.");
- return;
- }
- if (d_ptr->scene != filterItem->scene()) {
- qWarning("QGraphicsItem::installSceneEventFilter: event filters can only be installed"
- " on items in the same scene.");
- return;
- }
- d_ptr->scene->d_func()->installSceneEventFilter(this, filterItem);
-}
-
-/*!
- Removes an event filter on this item from \a filterItem.
-
- \sa installSceneEventFilter()
-*/
-void QGraphicsItem::removeSceneEventFilter(QGraphicsItem *filterItem)
-{
- if (!d_ptr->scene || d_ptr->scene != filterItem->scene())
- return;
- d_ptr->scene->d_func()->removeSceneEventFilter(this, filterItem);
-}
-
-/*!
- Filters events for the item \a watched. \a event is the filtered
- event.
-
- Reimplementing this function in a subclass makes it possible
- for the item to be used as an event filter for other items,
- intercepting all the events send to those items before they are
- able to respond.
-
- Reimplementations must return true to prevent further processing of
- a given event, ensuring that it will not be delivered to the watched
- item, or return false to indicate that the event should be propagated
- further by the event system.
-
- \sa installSceneEventFilter()
-*/
-bool QGraphicsItem::sceneEventFilter(QGraphicsItem *watched, QEvent *event)
-{
- Q_UNUSED(watched);
- Q_UNUSED(event);
- return false;
-}
-
-/*!
- This virtual function receives events to this item. Reimplement
- this function to intercept events before they are dispatched to
- the specialized event handlers contextMenuEvent(), focusInEvent(),
- focusOutEvent(), hoverEnterEvent(), hoverMoveEvent(),
- hoverLeaveEvent(), keyPressEvent(), keyReleaseEvent(),
- mousePressEvent(), mouseReleaseEvent(), mouseMoveEvent(), and
- mouseDoubleClickEvent().
-
- Returns true if the event was recognized and handled; otherwise, (e.g., if
- the event type was not recognized,) false is returned.
-
- \a event is the intercepted event.
-*/
-bool QGraphicsItem::sceneEvent(QEvent *event)
-{
- if (d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorHandlesChildEvents) {
- if (event->type() == QEvent::HoverEnter || event->type() == QEvent::HoverLeave
- || event->type() == QEvent::DragEnter || event->type() == QEvent::DragLeave) {
- // Hover enter and hover leave events for children are ignored;
- // hover move events are forwarded.
- return true;
- }
-
- QGraphicsItem *handler = this;
- do {
- handler = handler->d_ptr->parent;
- Q_ASSERT(handler);
- } while (handler->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorHandlesChildEvents);
- // Forward the event to the closest parent that handles child
- // events, mapping existing item-local coordinates to its
- // coordinate system.
- d_ptr->remapItemPos(event, handler);
- handler->sceneEvent(event);
- return true;
- }
-
- if (event->type() == QEvent::FocusOut) {
- focusOutEvent(static_cast<QFocusEvent *>(event));
- return true;
- }
-
- if (!d_ptr->visible) {
- // Eaten
- return true;
- }
-
- switch (event->type()) {
- case QEvent::FocusIn:
- focusInEvent(static_cast<QFocusEvent *>(event));
- break;
- case QEvent::GraphicsSceneContextMenu:
- contextMenuEvent(static_cast<QGraphicsSceneContextMenuEvent *>(event));
- break;
- case QEvent::GraphicsSceneDragEnter:
- dragEnterEvent(static_cast<QGraphicsSceneDragDropEvent *>(event));
- break;
- case QEvent::GraphicsSceneDragMove:
- dragMoveEvent(static_cast<QGraphicsSceneDragDropEvent *>(event));
- break;
- case QEvent::GraphicsSceneDragLeave:
- dragLeaveEvent(static_cast<QGraphicsSceneDragDropEvent *>(event));
- break;
- case QEvent::GraphicsSceneDrop:
- dropEvent(static_cast<QGraphicsSceneDragDropEvent *>(event));
- break;
- case QEvent::GraphicsSceneHoverEnter:
- hoverEnterEvent(static_cast<QGraphicsSceneHoverEvent *>(event));
- break;
- case QEvent::GraphicsSceneHoverMove:
- hoverMoveEvent(static_cast<QGraphicsSceneHoverEvent *>(event));
- break;
- case QEvent::GraphicsSceneHoverLeave:
- hoverLeaveEvent(static_cast<QGraphicsSceneHoverEvent *>(event));
- break;
- case QEvent::GraphicsSceneMouseMove:
- mouseMoveEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
- break;
- case QEvent::GraphicsSceneMousePress:
- mousePressEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
- break;
- case QEvent::GraphicsSceneMouseRelease:
- mouseReleaseEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
- break;
- case QEvent::GraphicsSceneMouseDoubleClick:
- mouseDoubleClickEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
- break;
- case QEvent::GraphicsSceneWheel:
- wheelEvent(static_cast<QGraphicsSceneWheelEvent *>(event));
- break;
- case QEvent::KeyPress: {
- QKeyEvent *k = static_cast<QKeyEvent *>(event);
- if (k->key() == Qt::Key_Tab || k->key() == Qt::Key_Backtab) {
- if (!(k->modifiers() & (Qt::ControlModifier | Qt::AltModifier))) { //### Add MetaModifier?
- bool res = false;
- if (k->key() == Qt::Key_Backtab
- || (k->key() == Qt::Key_Tab && (k->modifiers() & Qt::ShiftModifier))) {
- if (d_ptr->isWidget) {
- res = static_cast<QGraphicsWidget *>(this)->focusNextPrevChild(false);
- } else if (d_ptr->scene) {
- res = d_ptr->scene->focusNextPrevChild(false);
- }
- } else if (k->key() == Qt::Key_Tab) {
- if (d_ptr->isWidget) {
- res = static_cast<QGraphicsWidget *>(this)->focusNextPrevChild(true);
- } else if (d_ptr->scene) {
- res = d_ptr->scene->focusNextPrevChild(true);
- }
- }
- if (!res)
- event->ignore();
- return true;
- }
- }
- keyPressEvent(static_cast<QKeyEvent *>(event));
- break;
- }
- case QEvent::KeyRelease:
- keyReleaseEvent(static_cast<QKeyEvent *>(event));
- break;
- case QEvent::InputMethod:
- inputMethodEvent(static_cast<QInputMethodEvent *>(event));
- break;
- case QEvent::WindowActivate:
- case QEvent::WindowDeactivate:
- // Propagate panel activation.
- if (d_ptr->scene) {
- for (int i = 0; i < d_ptr->children.size(); ++i) {
- QGraphicsItem *child = d_ptr->children.at(i);
- if (child->isVisible() && !child->isPanel()) {
- if (!(child->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorHandlesChildEvents))
- d_ptr->scene->sendEvent(child, event);
- }
- }
- }
- break;
- default:
- return false;
- }
-
- return true;
-}
-
-/*!
- This event handler can be reimplemented in a subclass to process context
- menu events. The \a event parameter contains details about the event to
- be handled.
-
- If you ignore the event, (i.e., by calling QEvent::ignore(),) \a event
- will propagate to any item beneath this item. If no items accept the
- event, it will be ignored by the scene, and propagate to the view.
-
- It's common to open a QMenu in response to receiving a context menu
- event. Example:
-
- \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 13
-
- The default implementation ignores the event.
-
- \sa sceneEvent()
-*/
-void QGraphicsItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
-{
- event->ignore();
-}
-
-/*!
- This event handler, for event \a event, can be reimplemented to receive
- drag enter events for this item. Drag enter events are generated as the
- cursor enters the item's area.
-
- By accepting the event, (i.e., by calling QEvent::accept(),) the item will
- accept drop events, in addition to receiving drag move and drag
- leave. Otherwise, the event will be ignored and propagate to the item
- beneath. If the event is accepted, the item will receive a drag move event
- before control goes back to the event loop.
-
- A common implementation of dragEnterEvent accepts or ignores \a event
- depending on the associated mime data in \a event. Example:
-
- \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 14
-
- Items do not receive drag and drop events by default; to enable this
- feature, call \c setAcceptDrops(true).
-
- The default implementation does nothing.
-
- \sa dropEvent(), dragMoveEvent(), dragLeaveEvent()
-*/
-void QGraphicsItem::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
-{
- Q_D(QGraphicsItem);
- // binary compatibility workaround between 4.4 and 4.5
- if (d->isProxyWidget())
- static_cast<QGraphicsProxyWidget*>(this)->dragEnterEvent(event);
-}
-
-/*!
- This event handler, for event \a event, can be reimplemented to receive
- drag leave events for this item. Drag leave events are generated as the
- cursor leaves the item's area. Most often you will not need to reimplement
- this function, but it can be useful for resetting state in your item
- (e.g., highlighting).
-
- Calling QEvent::ignore() or QEvent::accept() on \a event has no effect.
-
- Items do not receive drag and drop events by default; to enable this
- feature, call \c setAcceptDrops(true).
-
- The default implementation does nothing.
-
- \sa dragEnterEvent(), dropEvent(), dragMoveEvent()
-*/
-void QGraphicsItem::dragLeaveEvent(QGraphicsSceneDragDropEvent *event)
-{
- Q_D(QGraphicsItem);
- // binary compatibility workaround between 4.4 and 4.5
- if (d->isProxyWidget())
- static_cast<QGraphicsProxyWidget*>(this)->dragLeaveEvent(event);
-}
-
-/*!
- This event handler, for event \a event, can be reimplemented to receive
- drag move events for this item. Drag move events are generated as the
- cursor moves around inside the item's area. Most often you will not need
- to reimplement this function; it is used to indicate that only parts of
- the item can accept drops.
-
- Calling QEvent::ignore() or QEvent::accept() on \a event toggles whether
- or not the item will accept drops at the position from the event. By
- default, \a event is accepted, indicating that the item allows drops at
- the specified position.
-
- Items do not receive drag and drop events by default; to enable this
- feature, call \c setAcceptDrops(true).
-
- The default implementation does nothing.
-
- \sa dropEvent(), dragEnterEvent(), dragLeaveEvent()
-*/
-void QGraphicsItem::dragMoveEvent(QGraphicsSceneDragDropEvent *event)
-{
- Q_D(QGraphicsItem);
- // binary compatibility workaround between 4.4 and 4.5
- if (d->isProxyWidget())
- static_cast<QGraphicsProxyWidget*>(this)->dragMoveEvent(event);
-}
-
-/*!
- This event handler, for event \a event, can be reimplemented to receive
- drop events for this item. Items can only receive drop events if the last
- drag move event was accepted.
-
- Calling QEvent::ignore() or QEvent::accept() on \a event has no effect.
-
- Items do not receive drag and drop events by default; to enable this
- feature, call \c setAcceptDrops(true).
-
- The default implementation does nothing.
-
- \sa dragEnterEvent(), dragMoveEvent(), dragLeaveEvent()
-*/
-void QGraphicsItem::dropEvent(QGraphicsSceneDragDropEvent *event)
-{
- Q_D(QGraphicsItem);
- // binary compatibility workaround between 4.4 and 4.5
- if (d->isProxyWidget())
- static_cast<QGraphicsProxyWidget*>(this)->dropEvent(event);
-}
-
-/*!
- This event handler, for event \a event, can be reimplemented to receive
- focus in events for this item. The default implementation calls
- ensureVisible().
-
- \sa focusOutEvent(), sceneEvent(), setFocus()
-*/
-void QGraphicsItem::focusInEvent(QFocusEvent *event)
-{
- Q_UNUSED(event);
- update();
-}
-
-/*!
- This event handler, for event \a event, can be reimplemented to receive
- focus out events for this item. The default implementation does nothing.
-
- \sa focusInEvent(), sceneEvent(), setFocus()
-*/
-void QGraphicsItem::focusOutEvent(QFocusEvent *event)
-{
- Q_UNUSED(event);
- update();
-}
-
-/*!
- This event handler, for event \a event, can be reimplemented to receive
- hover enter events for this item. The default implementation calls
- update(); otherwise it does nothing.
-
- Calling QEvent::ignore() or QEvent::accept() on \a event has no effect.
-
- \sa hoverMoveEvent(), hoverLeaveEvent(), sceneEvent(), setAcceptHoverEvents()
-*/
-void QGraphicsItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
-{
- Q_UNUSED(event);
- update();
-}
-
-/*!
- This event handler, for event \a event, can be reimplemented to receive
- hover move events for this item. The default implementation does nothing.
-
- Calling QEvent::ignore() or QEvent::accept() on \a event has no effect.
-
- \sa hoverEnterEvent(), hoverLeaveEvent(), sceneEvent(), setAcceptHoverEvents()
-*/
-void QGraphicsItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
-{
- Q_UNUSED(event);
-}
-
-/*!
- This event handler, for event \a event, can be reimplemented to receive
- hover leave events for this item. The default implementation calls
- update(); otherwise it does nothing.
-
- Calling QEvent::ignore() or QEvent::accept() on \a event has no effect.
-
- \sa hoverEnterEvent(), hoverMoveEvent(), sceneEvent(), setAcceptHoverEvents()
-*/
-void QGraphicsItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
-{
- Q_UNUSED(event);
- update();
-}
-
-/*!
- This event handler, for event \a event, can be reimplemented to
- receive key press events for this item. The default implementation
- ignores the event. If you reimplement this handler, the event will by
- default be accepted.
-
- Note that key events are only received for items that set the
- ItemIsFocusable flag, and that have keyboard input focus.
-
- \sa keyReleaseEvent(), setFocus(), QGraphicsScene::setFocusItem(),
- sceneEvent()
-*/
-void QGraphicsItem::keyPressEvent(QKeyEvent *event)
-{
- event->ignore();
-}
-
-/*!
- This event handler, for event \a event, can be reimplemented to receive
- key release events for this item. The default implementation
- ignores the event. If you reimplement this handler, the event will by
- default be accepted.
-
- Note that key events are only received for items that set the
- ItemIsFocusable flag, and that have keyboard input focus.
-
- \sa keyPressEvent(), setFocus(), QGraphicsScene::setFocusItem(),
- sceneEvent()
-*/
-void QGraphicsItem::keyReleaseEvent(QKeyEvent *event)
-{
- event->ignore();
-}
-
-/*!
- This event handler, for event \a event, can be reimplemented to
- receive mouse press events for this item. Mouse press events are
- only delivered to items that accept the mouse button that is
- pressed. By default, an item accepts all mouse buttons, but you
- can change this by calling setAcceptedMouseButtons().
-
- The mouse press event decides which item should become the mouse
- grabber (see QGraphicsScene::mouseGrabberItem()). If you do not
- reimplement this function, the press event will propagate to any
- topmost item beneath this item, and no other mouse events will be
- delivered to this item.
-
- If you do reimplement this function, \a event will by default be
- accepted (see QEvent::accept()), and this item is then the mouse
- grabber. This allows the item to receive future move, release and
- doubleclick events. If you call QEvent::ignore() on \a event, this
- item will lose the mouse grab, and \a event will propagate to any
- topmost item beneath. No further mouse events will be delivered to
- this item unless a new mouse press event is received.
-
- The default implementation handles basic item interaction, such as
- selection and moving. If you want to keep the base implementation
- when reimplementing this function, call
- QGraphicsItem::mousePressEvent() in your reimplementation.
-
- The event is \l{QEvent::ignore()}d for items that are neither
- \l{QGraphicsItem::ItemIsMovable}{movable} nor
- \l{QGraphicsItem::ItemIsSelectable}{selectable}.
-
- \sa mouseMoveEvent(), mouseReleaseEvent(),
- mouseDoubleClickEvent(), sceneEvent()
-*/
-void QGraphicsItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
-{
- if (event->button() == Qt::LeftButton && (flags() & ItemIsSelectable)) {
- bool multiSelect = (event->modifiers() & Qt::ControlModifier) != 0;
- if (!multiSelect) {
- if (!d_ptr->selected) {
- if (QGraphicsScene *scene = d_ptr->scene) {
- ++scene->d_func()->selectionChanging;
- scene->clearSelection();
- --scene->d_func()->selectionChanging;
- }
- setSelected(true);
- }
- }
- } else if (!(flags() & ItemIsMovable)) {
- event->ignore();
- }
- if (d_ptr->isWidget) {
- // Qt::Popup closes when you click outside.
- QGraphicsWidget *w = static_cast<QGraphicsWidget *>(this);
- if ((w->windowFlags() & Qt::Popup) == Qt::Popup) {
- event->accept();
- if (!w->rect().contains(event->pos()))
- w->close();
- }
- }
-}
-
-/*!
- obsolete
-*/
-bool _qt_movableAncestorIsSelected(const QGraphicsItem *item)
-{
- const QGraphicsItem *parent = item->parentItem();
- return parent && (((parent->flags() & QGraphicsItem::ItemIsMovable) && parent->isSelected()) || _qt_movableAncestorIsSelected(parent));
-}
-
-bool QGraphicsItemPrivate::movableAncestorIsSelected(const QGraphicsItem *item)
-{
- const QGraphicsItem *parent = item->d_ptr->parent;
- return parent && (((parent->flags() & QGraphicsItem::ItemIsMovable) && parent->isSelected()) || _qt_movableAncestorIsSelected(parent));
-}
-
-/*!
- This event handler, for event \a event, can be reimplemented to
- receive mouse move events for this item. If you do receive this
- event, you can be certain that this item also received a mouse
- press event, and that this item is the current mouse grabber.
-
- Calling QEvent::ignore() or QEvent::accept() on \a event has no
- effect.
-
- The default implementation handles basic item interaction, such as
- selection and moving. If you want to keep the base implementation
- when reimplementing this function, call
- QGraphicsItem::mouseMoveEvent() in your reimplementation.
-
- Please note that mousePressEvent() decides which graphics item it
- is that receives mouse events. See the mousePressEvent()
- description for details.
-
- \sa mousePressEvent(), mouseReleaseEvent(),
- mouseDoubleClickEvent(), sceneEvent()
-*/
-void QGraphicsItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
-{
- if ((event->buttons() & Qt::LeftButton) && (flags() & ItemIsMovable)) {
- // Determine the list of items that need to be moved.
- QList<QGraphicsItem *> selectedItems;
- QMap<QGraphicsItem *, QPointF> initialPositions;
- if (d_ptr->scene) {
- selectedItems = d_ptr->scene->selectedItems();
- initialPositions = d_ptr->scene->d_func()->movingItemsInitialPositions;
- if (initialPositions.isEmpty()) {
- foreach (QGraphicsItem *item, selectedItems)
- initialPositions[item] = item->pos();
- initialPositions[this] = pos();
- }
- d_ptr->scene->d_func()->movingItemsInitialPositions = initialPositions;
- }
-
- // Find the active view.
- QGraphicsView *view = 0;
- if (event->widget())
- view = qobject_cast<QGraphicsView *>(event->widget()->parentWidget());
-
- // Move all selected items
- int i = 0;
- bool movedMe = false;
- while (i <= selectedItems.size()) {
- QGraphicsItem *item = 0;
- if (i < selectedItems.size())
- item = selectedItems.at(i);
- else
- item = this;
- if (item == this) {
- // Slightly clumsy-looking way to ensure that "this" is part
- // of the list of items to move, this is to avoid allocations
- // (appending this item to the list of selected items causes a
- // detach).
- if (movedMe)
- break;
- movedMe = true;
- }
-
- if ((item->flags() & ItemIsMovable) && !QGraphicsItemPrivate::movableAncestorIsSelected(item)) {
- QPointF currentParentPos;
- QPointF buttonDownParentPos;
- if (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorIgnoresTransformations) {
- // Items whose ancestors ignore transformations need to
- // map screen coordinates to local coordinates, then map
- // those to the parent.
- QTransform viewToItemTransform = (item->deviceTransform(view->viewportTransform())).inverted();
- currentParentPos = mapToParent(viewToItemTransform.map(QPointF(view->mapFromGlobal(event->screenPos()))));
- buttonDownParentPos = mapToParent(viewToItemTransform.map(QPointF(view->mapFromGlobal(event->buttonDownScreenPos(Qt::LeftButton)))));
- } else if (item->flags() & ItemIgnoresTransformations) {
- // Root items that ignore transformations need to
- // calculate their diff by mapping viewport coordinates
- // directly to parent coordinates.
- // COMBINE
- QTransform itemTransform;
- if (item->d_ptr->transformData)
- itemTransform = item->d_ptr->transformData->computedFullTransform();
- itemTransform.translate(item->d_ptr->pos.x(), item->d_ptr->pos.y());
- QTransform viewToParentTransform = itemTransform
- * (item->sceneTransform() * view->viewportTransform()).inverted();
- currentParentPos = viewToParentTransform.map(QPointF(view->mapFromGlobal(event->screenPos())));
- buttonDownParentPos = viewToParentTransform.map(QPointF(view->mapFromGlobal(event->buttonDownScreenPos(Qt::LeftButton))));
- } else {
- // All other items simply map from the scene.
- currentParentPos = item->mapToParent(item->mapFromScene(event->scenePos()));
- buttonDownParentPos = item->mapToParent(item->mapFromScene(event->buttonDownScenePos(Qt::LeftButton)));
- }
-
- item->setPos(initialPositions.value(item) + currentParentPos - buttonDownParentPos);
-
- if (item->flags() & ItemIsSelectable)
- item->setSelected(true);
- }
- ++i;
- }
-
- } else {
- event->ignore();
- }
-}
-
-/*!
- This event handler, for event \a event, can be reimplemented to
- receive mouse release events for this item.
-
- Calling QEvent::ignore() or QEvent::accept() on \a event has no
- effect.
-
- The default implementation handles basic item interaction, such as
- selection and moving. If you want to keep the base implementation
- when reimplementing this function, call
- QGraphicsItem::mouseReleaseEvent() in your reimplementation.
-
- Please note that mousePressEvent() decides which graphics item it
- is that receives mouse events. See the mousePressEvent()
- description for details.
-
- \sa mousePressEvent(), mouseMoveEvent(), mouseDoubleClickEvent(),
- sceneEvent()
-*/
-void QGraphicsItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
-{
- if (flags() & ItemIsSelectable) {
- bool multiSelect = (event->modifiers() & Qt::ControlModifier) != 0;
- if (event->scenePos() == event->buttonDownScenePos(Qt::LeftButton)) {
- // The item didn't move
- if (multiSelect) {
- setSelected(!isSelected());
- } else {
- bool selectionChanged = false;
- if (QGraphicsScene *scene = d_ptr->scene) {
- ++scene->d_func()->selectionChanging;
- // Clear everything but this item. Bypass
- // QGraphicsScene::clearSelection()'s default behavior by
- // temporarily removing this item from the selection list.
- if (d_ptr->selected) {
- scene->d_func()->selectedItems.remove(this);
- foreach (QGraphicsItem *item, scene->d_func()->selectedItems) {
- if (item->isSelected()) {
- selectionChanged = true;
- break;
- }
- }
- }
- scene->clearSelection();
- if (d_ptr->selected)
- scene->d_func()->selectedItems.insert(this);
- --scene->d_func()->selectionChanging;
- if (selectionChanged)
- emit d_ptr->scene->selectionChanged();
- }
- setSelected(true);
- }
- }
- }
- if (d_ptr->scene && !event->buttons())
- d_ptr->scene->d_func()->movingItemsInitialPositions.clear();
-}
-
-/*!
- This event handler, for event \a event, can be reimplemented to
- receive mouse doubleclick events for this item.
-
- When doubleclicking an item, the item will first receive a mouse
- press event, followed by a release event (i.e., a click), then a
- doubleclick event, and finally a release event.
-
- Calling QEvent::ignore() or QEvent::accept() on \a event has no
- effect.
-
- The default implementation calls mousePressEvent(). If you want to
- keep the base implementation when reimplementing this function,
- call QGraphicsItem::mouseDoubleClickEvent() in your
- reimplementation.
-
- Note that an item will not receive double click events if it is
- neither \l {QGraphicsItem::ItemIsSelectable}{selectable} nor
- \l{QGraphicsItem::ItemIsMovable}{movable} (single mouse clicks are
- ignored in this case, and that stops the generation of double
- clicks).
-
- \sa mousePressEvent(), mouseMoveEvent(), mouseReleaseEvent(), sceneEvent()
-*/
-void QGraphicsItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
-{
- mousePressEvent(event);
-}
-
-/*!
- This event handler, for event \a event, can be reimplemented to receive
- wheel events for this item. If you reimplement this function, \a event
- will be accepted by default.
-
- If you ignore the event, (i.e., by calling QEvent::ignore(),) it will
- propagate to any item beneath this item. If no items accept the event, it
- will be ignored by the scene, and propagate to the view (e.g., the view's
- vertical scroll bar).
-
- The default implementation ignores the event.
-
- \sa sceneEvent()
-*/
-void QGraphicsItem::wheelEvent(QGraphicsSceneWheelEvent *event)
-{
- event->ignore();
-}
-
-/*!
- This event handler, for event \a event, can be reimplemented to receive
- input method events for this item. The default implementation ignores the
- event.
-
- \sa inputMethodQuery(), sceneEvent()
-*/
-void QGraphicsItem::inputMethodEvent(QInputMethodEvent *event)
-{
- event->ignore();
-}
-
-/*!
- This method is only relevant for input items. It is used by the
- input method to query a set of properties of the item to be able
- to support complex input method operations, such as support for
- surrounding text and reconversions. \a query specifies which
- property is queried.
-
- \sa inputMethodEvent(), QInputMethodEvent, QInputContext
-*/
-QVariant QGraphicsItem::inputMethodQuery(Qt::InputMethodQuery query) const
-{
- if (isWidget()) {
- // ### Qt 5: Remove. The reimplementation in
- // QGraphicsProxyWidget solves this problem (but requires a
- // recompile to take effect).
- return d_ptr->inputMethodQueryHelper(query);
- }
-
- Q_UNUSED(query);
- return QVariant();
-}
-
-/*!
- Returns the current input method hints of this item.
-
- Input method hints are only relevant for input items.
- The hints are used by the input method to indicate how it should operate.
- For example, if the Qt::ImhNumbersOnly flag is set, the input method may change
- its visual components to reflect that only numbers can be entered.
-
- The effect may vary between input method implementations.
-
- \since 4.6
-
- \sa setInputMethodHints(), inputMethodQuery(), QInputContext
-*/
-Qt::InputMethodHints QGraphicsItem::inputMethodHints() const
-{
- Q_D(const QGraphicsItem);
- return d->imHints;
-}
-
-/*!
- Sets the current input method hints of this item to \a hints.
-
- \since 4.6
-
- \sa inputMethodHints(), inputMethodQuery(), QInputContext
-*/
-void QGraphicsItem::setInputMethodHints(Qt::InputMethodHints hints)
-{
- Q_D(QGraphicsItem);
- d->imHints = hints;
- if (!hasFocus())
- return;
- d->scene->d_func()->updateInputMethodSensitivityInViews();
-#if !defined(QT_NO_IM) && (defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN))
- QWidget *fw = QApplication::focusWidget();
- if (!fw)
- return;
- for (int i = 0 ; i < scene()->views().count() ; ++i)
- if (scene()->views().at(i) == fw)
- if (QInputContext *inputContext = fw->inputContext())
- inputContext->update();
-#endif
-}
-
-/*!
- Updates the item's micro focus.
-
- \since 4.7
-
- \sa QInputContext
-*/
-void QGraphicsItem::updateMicroFocus()
-{
-#if !defined(QT_NO_IM) && (defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN))
- if (QWidget *fw = QApplication::focusWidget()) {
- if (scene()) {
- for (int i = 0 ; i < scene()->views().count() ; ++i) {
- if (scene()->views().at(i) == fw) {
- if (QInputContext *inputContext = fw->inputContext()) {
- inputContext->update();
-#ifndef QT_NO_ACCESSIBILITY
- // ##### is this correct
- if (toGraphicsObject())
- QAccessible::updateAccessibility(toGraphicsObject(), 0, QAccessible::StateChanged);
-#endif
- break;
- }
- }
- }
- }
- }
-#endif
-}
-
-/*!
- This virtual function is called by QGraphicsItem to notify custom items
- that some part of the item's state changes. By reimplementing this
- function, your can react to a change, and in some cases, (depending on \a
- change,) adjustments can be made.
-
- \a change is the parameter of the item that is changing. \a value is the
- new value; the type of the value depends on \a change.
-
- Example:
-
- \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 15
-
- The default implementation does nothing, and returns \a value.
-
- Note: Certain QGraphicsItem functions cannot be called in a
- reimplementation of this function; see the GraphicsItemChange
- documentation for details.
-
- \sa GraphicsItemChange
-*/
-QVariant QGraphicsItem::itemChange(GraphicsItemChange change, const QVariant &value)
-{
- Q_UNUSED(change);
- return value;
-}
-
-/*!
- \internal
-
- Note: This is provided as a hook to avoid future problems related
- to adding virtual functions.
-*/
-bool QGraphicsItem::supportsExtension(Extension extension) const
-{
- Q_UNUSED(extension);
- return false;
-}
-
-/*!
- \internal
-
- Note: This is provided as a hook to avoid future problems related
- to adding virtual functions.
-*/
-void QGraphicsItem::setExtension(Extension extension, const QVariant &variant)
-{
- Q_UNUSED(extension);
- Q_UNUSED(variant);
-}
-
-/*!
- \internal
-
- Note: This is provided as a hook to avoid future problems related
- to adding virtual functions.
-*/
-QVariant QGraphicsItem::extension(const QVariant &variant) const
-{
- Q_UNUSED(variant);
- return QVariant();
-}
-
-/*!
- \internal
-
- Adds this item to the scene's index. Called in conjunction with
- removeFromIndex() to ensure the index bookkeeping is correct when
- the item's position, transformation or shape changes.
-*/
-void QGraphicsItem::addToIndex()
-{
- if (d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) {
- // ### add to child index only if applicable
- return;
- }
- if (d_ptr->scene)
- d_ptr->scene->d_func()->index->addItem(this);
-}
-
-/*!
- \internal
-
- Removes this item from the scene's index. Called in conjunction
- with addToIndex() to ensure the index bookkeeping is correct when
- the item's position, transformation or shape changes.
-*/
-void QGraphicsItem::removeFromIndex()
-{
- if (d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) {
- // ### remove from child index only if applicable
- return;
- }
- if (d_ptr->scene)
- d_ptr->scene->d_func()->index->removeItem(this);
-}
-
-/*!
- Prepares the item for a geometry change. Call this function before
- changing the bounding rect of an item to keep QGraphicsScene's index up to
- date.
-
- prepareGeometryChange() will call update() if this is necessary.
-
- Example:
-
- \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 16
-
- \sa boundingRect()
-*/
-void QGraphicsItem::prepareGeometryChange()
-{
- if (d_ptr->inDestructor)
- return;
- if (d_ptr->scene) {
- d_ptr->scene->d_func()->dirtyGrowingItemsBoundingRect = true;
- d_ptr->geometryChanged = 1;
- d_ptr->paintedViewBoundingRectsNeedRepaint = 1;
- d_ptr->notifyBoundingRectChanged = !d_ptr->inSetPosHelper;
-
- QGraphicsScenePrivate *scenePrivate = d_ptr->scene->d_func();
- scenePrivate->index->prepareBoundingRectChange(this);
- scenePrivate->markDirty(this, QRectF(), /*invalidateChildren=*/true, /*force=*/false,
- /*ignoreOpacity=*/ false, /*removingItemFromScene=*/ false,
- /*updateBoundingRect=*/true);
-
- // For compatibility reasons, we have to update the item's old geometry
- // if someone is connected to the changed signal or the scene has no views.
- // Note that this has to be done *after* markDirty to ensure that
- // _q_processDirtyItems is called before _q_emitUpdated.
- if (scenePrivate->isSignalConnected(scenePrivate->changedSignalIndex)
- || scenePrivate->views.isEmpty()) {
- if (d_ptr->hasTranslateOnlySceneTransform()) {
- d_ptr->scene->update(boundingRect().translated(d_ptr->sceneTransform.dx(),
- d_ptr->sceneTransform.dy()));
- } else {
- d_ptr->scene->update(d_ptr->sceneTransform.mapRect(boundingRect()));
- }
- }
- }
-
- d_ptr->markParentDirty(/*updateBoundingRect=*/true);
-}
-
-/*!
- \internal
-
- Highlights \a item as selected.
-
- NOTE: This function is a duplicate of qt_graphicsItem_highlightSelected() in
- qgraphicssvgitem.cpp!
-*/
-static void qt_graphicsItem_highlightSelected(
- QGraphicsItem *item, QPainter *painter, const QStyleOptionGraphicsItem *option)
-{
- const QRectF murect = painter->transform().mapRect(QRectF(0, 0, 1, 1));
- if (qFuzzyIsNull(qMax(murect.width(), murect.height())))
- return;
-
- const QRectF mbrect = painter->transform().mapRect(item->boundingRect());
- if (qMin(mbrect.width(), mbrect.height()) < qreal(1.0))
- return;
-
- qreal itemPenWidth;
- switch (item->type()) {
- case QGraphicsEllipseItem::Type:
- itemPenWidth = static_cast<QGraphicsEllipseItem *>(item)->pen().widthF();
- break;
- case QGraphicsPathItem::Type:
- itemPenWidth = static_cast<QGraphicsPathItem *>(item)->pen().widthF();
- break;
- case QGraphicsPolygonItem::Type:
- itemPenWidth = static_cast<QGraphicsPolygonItem *>(item)->pen().widthF();
- break;
- case QGraphicsRectItem::Type:
- itemPenWidth = static_cast<QGraphicsRectItem *>(item)->pen().widthF();
- break;
- case QGraphicsSimpleTextItem::Type:
- itemPenWidth = static_cast<QGraphicsSimpleTextItem *>(item)->pen().widthF();
- break;
- case QGraphicsLineItem::Type:
- itemPenWidth = static_cast<QGraphicsLineItem *>(item)->pen().widthF();
- break;
- default:
- itemPenWidth = 1.0;
- }
- const qreal pad = itemPenWidth / 2;
-
- const qreal penWidth = 0; // cosmetic pen
-
- const QColor fgcolor = option->palette.windowText().color();
- const QColor bgcolor( // ensure good contrast against fgcolor
- fgcolor.red() > 127 ? 0 : 255,
- fgcolor.green() > 127 ? 0 : 255,
- fgcolor.blue() > 127 ? 0 : 255);
-
- painter->setPen(QPen(bgcolor, penWidth, Qt::SolidLine));
- painter->setBrush(Qt::NoBrush);
- painter->drawRect(item->boundingRect().adjusted(pad, pad, -pad, -pad));
-
- painter->setPen(QPen(option->palette.windowText(), 0, Qt::DashLine));
- painter->setBrush(Qt::NoBrush);
- painter->drawRect(item->boundingRect().adjusted(pad, pad, -pad, -pad));
-}
-
-/*!
- \class QGraphicsObject
- \brief The QGraphicsObject class provides a base class for all graphics items that
- require signals, slots and properties.
- \since 4.6
- \ingroup graphicsview-api
-
- The class extends a QGraphicsItem with QObject's signal/slot and property mechanisms.
- It maps many of QGraphicsItem's basic setters and getters to properties and adds notification
- signals for many of them.
-
- \section1 Parents and Children
-
- Each graphics object can be constructed with a parent item. This ensures that the
- item will be destroyed when its parent item is destroyed. Although QGraphicsObject
- inherits from both QObject and QGraphicsItem, you should use the functions provided
- by QGraphicsItem, \e not QObject, to manage the relationships between parent and
- child items.
-
- The relationships between items can be explored using the parentItem() and childItems()
- functions. In the hierarchy of items in a scene, the parentObject() and parentWidget()
- functions are the equivalent of the QWidget::parent() and QWidget::parentWidget()
- functions for QWidget subclasses.
-
- \sa QGraphicsWidget
-*/
-
-/*!
- Constructs a QGraphicsObject with \a parent.
-*/
-QGraphicsObject::QGraphicsObject(QGraphicsItem *parent)
- : QGraphicsItem(parent)
-{
- QGraphicsItem::d_ptr->isObject = true;
-}
-
-/*!
- \internal
-*/
-QGraphicsObject::QGraphicsObject(QGraphicsItemPrivate &dd, QGraphicsItem *parent, QGraphicsScene *scene)
- : QGraphicsItem(dd, parent, scene)
-{
- QGraphicsItem::d_ptr->isObject = true;
-}
-
-#ifndef QT_NO_GESTURES
-/*!
- Subscribes the graphics object to the given \a gesture with specific \a flags.
-
- \sa ungrabGesture(), QGestureEvent
-*/
-void QGraphicsObject::grabGesture(Qt::GestureType gesture, Qt::GestureFlags flags)
-{
- bool contains = QGraphicsItem::d_ptr->gestureContext.contains(gesture);
- QGraphicsItem::d_ptr->gestureContext.insert(gesture, flags);
- if (!contains && QGraphicsItem::d_ptr->scene)
- QGraphicsItem::d_ptr->scene->d_func()->grabGesture(this, gesture);
-}
-
-/*!
- Unsubscribes the graphics object from the given \a gesture.
-
- \sa grabGesture(), QGestureEvent
-*/
-void QGraphicsObject::ungrabGesture(Qt::GestureType gesture)
-{
- if (QGraphicsItem::d_ptr->gestureContext.remove(gesture) && QGraphicsItem::d_ptr->scene)
- QGraphicsItem::d_ptr->scene->d_func()->ungrabGesture(this, gesture);
-}
-#endif // QT_NO_GESTURES
-
-/*!
- Updates the item's micro focus. This is slot for convenience.
-
- \since 4.7
-
- \sa QInputContext
-*/
-void QGraphicsObject::updateMicroFocus()
-{
- QGraphicsItem::updateMicroFocus();
-}
-
-void QGraphicsItemPrivate::children_append(QDeclarativeListProperty<QGraphicsObject> *list, QGraphicsObject *item)
-{
- if (item) {
- QGraphicsObject *graphicsObject = static_cast<QGraphicsObject *>(list->object);
- if (QGraphicsItemPrivate::get(graphicsObject)->sendParentChangeNotification) {
- item->setParentItem(graphicsObject);
- } else {
- QGraphicsItemPrivate::get(item)->setParentItemHelper(graphicsObject, 0, 0);
- }
- }
-}
-
-int QGraphicsItemPrivate::children_count(QDeclarativeListProperty<QGraphicsObject> *list)
-{
- QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(static_cast<QGraphicsObject *>(list->object));
- return d->children.count();
-}
-
-QGraphicsObject *QGraphicsItemPrivate::children_at(QDeclarativeListProperty<QGraphicsObject> *list, int index)
-{
- QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(static_cast<QGraphicsObject *>(list->object));
- if (index >= 0 && index < d->children.count())
- return d->children.at(index)->toGraphicsObject();
- else
- return 0;
-}
-
-void QGraphicsItemPrivate::children_clear(QDeclarativeListProperty<QGraphicsObject> *list)
-{
- QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(static_cast<QGraphicsObject *>(list->object));
- int childCount = d->children.count();
- if (d->sendParentChangeNotification) {
- for (int index = 0; index < childCount; index++)
- d->children.at(0)->setParentItem(0);
- } else {
- for (int index = 0; index < childCount; index++)
- QGraphicsItemPrivate::get(d->children.at(0))->setParentItemHelper(0, 0, 0);
- }
-}
-
-/*!
- Returns a list of this item's children.
-
- The items are sorted by stacking order. This takes into account both the
- items' insertion order and their Z-values.
-
-*/
-QDeclarativeListProperty<QGraphicsObject> QGraphicsItemPrivate::childrenList()
-{
- Q_Q(QGraphicsItem);
- if (isObject) {
- QGraphicsObject *that = static_cast<QGraphicsObject *>(q);
- return QDeclarativeListProperty<QGraphicsObject>(that, &children, children_append,
- children_count, children_at, children_clear);
- } else {
- //QGraphicsItem is not supported for this property
- return QDeclarativeListProperty<QGraphicsObject>();
- }
-}
-
-/*!
- \internal
- Returns the width of the item
- Reimplemented by QGraphicsWidget
-*/
-qreal QGraphicsItemPrivate::width() const
-{
- return 0;
-}
-
-/*!
- \internal
- Set the width of the item
- Reimplemented by QGraphicsWidget
-*/
-void QGraphicsItemPrivate::setWidth(qreal w)
-{
- Q_UNUSED(w);
-}
-
-/*!
- \internal
- Reset the width of the item
- Reimplemented by QGraphicsWidget
-*/
-void QGraphicsItemPrivate::resetWidth()
-{
-}
-
-/*!
- \internal
- Returns the height of the item
- Reimplemented by QGraphicsWidget
-*/
-qreal QGraphicsItemPrivate::height() const
-{
- return 0;
-}
-
-/*!
- \internal
- Set the height of the item
- Reimplemented by QGraphicsWidget
-*/
-void QGraphicsItemPrivate::setHeight(qreal h)
-{
- Q_UNUSED(h);
-}
-
-/*!
- \internal
- Reset the height of the item
- Reimplemented by QGraphicsWidget
-*/
-void QGraphicsItemPrivate::resetHeight()
-{
-}
-
-/*!
- \property QGraphicsObject::children
- \since 4.7
- \internal
-*/
-
-/*!
- \property QGraphicsObject::width
- \since 4.7
- \internal
-*/
-
-/*!
- \property QGraphicsObject::height
- \since 4.7
- \internal
-*/
-
-/*!
- \property QGraphicsObject::parent
- \brief the parent of the item
-
- \note The item's parent is set independently of the parent object returned
- by QObject::parent().
-
- \sa QGraphicsItem::setParentItem(), QGraphicsItem::parentObject()
-*/
-
-/*!
- \property QGraphicsObject::opacity
- \brief the opacity of the item
-
- \sa QGraphicsItem::setOpacity(), QGraphicsItem::opacity()
-*/
-
-/*!
- \fn QGraphicsObject::opacityChanged()
-
- This signal gets emitted whenever the opacity of the item changes
-
- \sa QGraphicsItem::opacity()
-*/
-
-/*!
- \fn QGraphicsObject::parentChanged()
-
- This signal gets emitted whenever the parent of the item changes
-*/
-
-/*!
- \property QGraphicsObject::pos
- \brief the position of the item
-
- Describes the items position.
-
- \sa QGraphicsItem::setPos(), QGraphicsItem::pos()
-*/
-
-/*!
- \property QGraphicsObject::x
- \brief the x position of the item
-
- Describes the items x position.
-
- \sa QGraphicsItem::setX(), setPos(), xChanged()
-*/
-
-/*!
- \fn QGraphicsObject::xChanged()
-
- This signal gets emitted whenever the x position of the item changes
-
- \sa pos()
-*/
-
-/*!
- \property QGraphicsObject::y
- \brief the y position of the item
-
- Describes the items y position.
-
- \sa QGraphicsItem::setY(), setPos(), yChanged()
-*/
-
-/*!
- \fn QGraphicsObject::yChanged()
-
- This signal gets emitted whenever the y position of the item changes.
-
- \sa pos()
-*/
-
-/*!
- \property QGraphicsObject::z
- \brief the z value of the item
-
- Describes the items z value.
-
- \sa QGraphicsItem::setZValue(), zValue(), zChanged()
-*/
-
-/*!
- \fn QGraphicsObject::zChanged()
-
- This signal gets emitted whenever the z value of the item changes.
-
- \sa pos()
-*/
-
-/*!
- \property QGraphicsObject::rotation
- This property holds the rotation of the item in degrees.
-
- This specifies how many degrees to rotate the item around its transformOrigin.
- The default rotation is 0 degrees (i.e. not rotated at all).
-*/
-
-/*!
- \fn QGraphicsObject::rotationChanged()
-
- This signal gets emitted whenever the roation of the item changes.
-*/
-
-/*!
- \property QGraphicsObject::scale
- This property holds the scale of the item.
-
- A scale of less than 1 means the item will be displayed smaller than
- normal, and a scale of greater than 1 means the item will be
- displayed larger than normal. A negative scale means the item will
- be mirrored.
-
- By default, items are displayed at a scale of 1 (i.e. at their
- normal size).
-
- Scaling is from the item's transformOrigin.
-*/
-
-/*!
- \fn void QGraphicsObject::scaleChanged()
-
- This signal is emitted when the scale of the item changes.
-*/
-
-
-/*!
- \property QGraphicsObject::enabled
- \brief whether the item is enabled or not
-
- This property is declared in QGraphicsItem.
-
- By default, this property is true.
-
- \sa QGraphicsItem::isEnabled(), QGraphicsItem::setEnabled()
- \sa QGraphicsObject::enabledChanged()
-*/
-
-/*!
- \fn void QGraphicsObject::enabledChanged()
-
- This signal gets emitted whenever the item get's enabled or disabled.
-
- \sa isEnabled()
-*/
-
-/*!
- \property QGraphicsObject::visible
- \brief whether the item is visible or not
-
- This property is declared in QGraphicsItem.
-
- By default, this property is true.
-
- \sa QGraphicsItem::isVisible(), QGraphicsItem::setVisible(), visibleChanged()
-*/
-
-/*!
- \fn QGraphicsObject::visibleChanged()
-
- This signal gets emitted whenever the visibility of the item changes
-
- \sa visible
-*/
-
-/*!
- \fn const QObjectList &QGraphicsObject::children() const
- \internal
-
- This function returns the same value as QObject::children(). It's
- provided to differentiate between the obsolete member
- QGraphicsItem::children() and QObject::children(). QGraphicsItem now
- provides childItems() instead.
-*/
-
-/*!
- \property QGraphicsObject::transformOriginPoint
- \brief the transformation origin
-
- This property sets a specific point in the items coordiante system as the
- origin for scale and rotation.
-
- \sa scale, rotation, QGraphicsItem::transformOriginPoint()
-*/
-
-/*!
- \fn void QGraphicsObject::widthChanged()
- \internal
-*/
-
-/*!
- \fn void QGraphicsObject::heightChanged()
- \internal
-*/
-
-/*!
-
- \fn QGraphicsObject::childrenChanged()
-
- This signal gets emitted whenever the children list changes
- \internal
-*/
-
-/*!
- \property QGraphicsObject::effect
- \since 4.7
- \brief the effect attached to this item
-
- \sa QGraphicsItem::setGraphicsEffect(), QGraphicsItem::graphicsEffect()
-*/
-
-/*!
- \class QAbstractGraphicsShapeItem
- \brief The QAbstractGraphicsShapeItem class provides a common base for
- all path items.
- \since 4.2
- \ingroup graphicsview-api
-
- This class does not fully implement an item by itself; in particular, it
- does not implement boundingRect() and paint(), which are inherited by
- QGraphicsItem.
-
- You can subclass this item to provide a simple base implementation of
- accessors for the item's pen and brush.
-
- \sa QGraphicsRectItem, QGraphicsEllipseItem, QGraphicsPathItem,
- QGraphicsPolygonItem, QGraphicsTextItem, QGraphicsLineItem,
- QGraphicsPixmapItem, {Graphics View Framework}
-*/
-
-class QAbstractGraphicsShapeItemPrivate : public QGraphicsItemPrivate
-{
- Q_DECLARE_PUBLIC(QAbstractGraphicsShapeItem)
-public:
-
- QBrush brush;
- QPen pen;
-
- // Cached bounding rectangle
- mutable QRectF boundingRect;
-};
-
-/*!
- Constructs a QAbstractGraphicsShapeItem. \a parent is passed to
- QGraphicsItem's constructor.
-*/
-QAbstractGraphicsShapeItem::QAbstractGraphicsShapeItem(QGraphicsItem *parent
-#ifndef Q_QDOC
- // obsolete argument
- , QGraphicsScene *scene
-#endif
- )
- : QGraphicsItem(*new QAbstractGraphicsShapeItemPrivate, parent, scene)
-{
-}
-
-/*!
- \internal
-*/
-QAbstractGraphicsShapeItem::QAbstractGraphicsShapeItem(QAbstractGraphicsShapeItemPrivate &dd,
- QGraphicsItem *parent,
- QGraphicsScene *scene)
- : QGraphicsItem(dd, parent, scene)
-{
-}
-
-/*!
- Destroys a QAbstractGraphicsShapeItem.
-*/
-QAbstractGraphicsShapeItem::~QAbstractGraphicsShapeItem()
-{
-}
-
-/*!
- Returns the item's pen. If no pen has been set, this function returns
- QPen(), a default black solid line pen with 0 width.
-*/
-QPen QAbstractGraphicsShapeItem::pen() const
-{
- Q_D(const QAbstractGraphicsShapeItem);
- return d->pen;
-}
-
-/*!
- Sets the pen for this item to \a pen.
-
- The pen is used to draw the item's outline.
-
- \sa pen()
-*/
-void QAbstractGraphicsShapeItem::setPen(const QPen &pen)
-{
- Q_D(QAbstractGraphicsShapeItem);
- if (d->pen == pen)
- return;
- prepareGeometryChange();
- d->pen = pen;
- d->boundingRect = QRectF();
- update();
-}
-
-/*!
- Returns the item's brush, or an empty brush if no brush has been set.
-
- \sa setBrush()
-*/
-QBrush QAbstractGraphicsShapeItem::brush() const
-{
- Q_D(const QAbstractGraphicsShapeItem);
- return d->brush;
-}
-
-/*!
- Sets the item's brush to \a brush.
-
- The item's brush is used to fill the item.
-
- If you use a brush with a QGradient, the gradient
- is relative to the item's coordinate system.
-
- \sa brush()
-*/
-void QAbstractGraphicsShapeItem::setBrush(const QBrush &brush)
-{
- Q_D(QAbstractGraphicsShapeItem);
- if (d->brush == brush)
- return;
- d->brush = brush;
- update();
-}
-
-/*!
- \reimp
-*/
-bool QAbstractGraphicsShapeItem::isObscuredBy(const QGraphicsItem *item) const
-{
- return QGraphicsItem::isObscuredBy(item);
-}
-
-/*!
- \reimp
-*/
-QPainterPath QAbstractGraphicsShapeItem::opaqueArea() const
-{
- Q_D(const QAbstractGraphicsShapeItem);
- if (d->brush.isOpaque())
- return isClipped() ? clipPath() : shape();
- return QGraphicsItem::opaqueArea();
-}
-
-/*!
- \class QGraphicsPathItem
- \brief The QGraphicsPathItem class provides a path item that you
- can add to a QGraphicsScene.
- \since 4.2
- \ingroup graphicsview-api
-
- To set the item's path, pass a QPainterPath to QGraphicsPathItem's
- constructor, or call the setPath() function. The path() function
- returns the current path.
-
- \image graphicsview-pathitem.png
-
- QGraphicsPathItem uses the path to provide a reasonable
- implementation of boundingRect(), shape(), and contains(). The
- paint() function draws the path using the item's associated pen
- and brush, which you can set by calling the setPen() and
- setBrush() functions.
-
- \sa QGraphicsRectItem, QGraphicsEllipseItem, QGraphicsPolygonItem,
- QGraphicsTextItem, QGraphicsLineItem, QGraphicsPixmapItem, {Graphics
- View Framework}
-*/
-
-class QGraphicsPathItemPrivate : public QAbstractGraphicsShapeItemPrivate
-{
- Q_DECLARE_PUBLIC(QGraphicsPathItem)
-public:
- QPainterPath path;
-};
-
-/*!
- Constructs a QGraphicsPath item using \a path as the default path. \a
- parent is passed to QAbstractGraphicsShapeItem's constructor.
-
- \sa QGraphicsScene::addItem()
-*/
-QGraphicsPathItem::QGraphicsPathItem(const QPainterPath &path,
- QGraphicsItem *parent
-#ifndef Q_QDOC
- // obsolete argument
- , QGraphicsScene *scene
-#endif
- )
- : QAbstractGraphicsShapeItem(*new QGraphicsPathItemPrivate, parent, scene)
-{
- if (!path.isEmpty())
- setPath(path);
-}
-
-/*!
- Constructs a QGraphicsPath. \a parent is passed to
- QAbstractGraphicsShapeItem's constructor.
-
- \sa QGraphicsScene::addItem()
-*/
-QGraphicsPathItem::QGraphicsPathItem(QGraphicsItem *parent
-#ifndef Q_QDOC
- // obsolete argument
- , QGraphicsScene *scene
-#endif
- )
- : QAbstractGraphicsShapeItem(*new QGraphicsPathItemPrivate, parent, scene)
-{
-}
-
-/*!
- Destroys the QGraphicsPathItem.
-*/
-QGraphicsPathItem::~QGraphicsPathItem()
-{
-}
-
-/*!
- Returns the item's path as a QPainterPath. If no item has been set, an
- empty QPainterPath is returned.
-
- \sa setPath()
-*/
-QPainterPath QGraphicsPathItem::path() const
-{
- Q_D(const QGraphicsPathItem);
- return d->path;
-}
-
-/*!
- Sets the item's path to be the given \a path.
-
- \sa path()
-*/
-void QGraphicsPathItem::setPath(const QPainterPath &path)
-{
- Q_D(QGraphicsPathItem);
- if (d->path == path)
- return;
- prepareGeometryChange();
- d->path = path;
- d->boundingRect = QRectF();
- update();
-}
-
-/*!
- \reimp
-*/
-QRectF QGraphicsPathItem::boundingRect() const
-{
- Q_D(const QGraphicsPathItem);
- if (d->boundingRect.isNull()) {
- qreal pw = pen().widthF();
- if (pw == 0.0)
- d->boundingRect = d->path.controlPointRect();
- else {
- d->boundingRect = shape().controlPointRect();
- }
- }
- return d->boundingRect;
-}
-
-/*!
- \reimp
-*/
-QPainterPath QGraphicsPathItem::shape() const
-{
- Q_D(const QGraphicsPathItem);
- return qt_graphicsItem_shapeFromPath(d->path, d->pen);
-}
-
-/*!
- \reimp
-*/
-bool QGraphicsPathItem::contains(const QPointF &point) const
-{
- return QAbstractGraphicsShapeItem::contains(point);
-}
-
-/*!
- \reimp
-*/
-void QGraphicsPathItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
- QWidget *widget)
-{
- Q_D(QGraphicsPathItem);
- Q_UNUSED(widget);
- painter->setPen(d->pen);
- painter->setBrush(d->brush);
- painter->drawPath(d->path);
-
- if (option->state & QStyle::State_Selected)
- qt_graphicsItem_highlightSelected(this, painter, option);
-}
-
-/*!
- \reimp
-*/
-bool QGraphicsPathItem::isObscuredBy(const QGraphicsItem *item) const
-{
- return QAbstractGraphicsShapeItem::isObscuredBy(item);
-}
-
-/*!
- \reimp
-*/
-QPainterPath QGraphicsPathItem::opaqueArea() const
-{
- return QAbstractGraphicsShapeItem::opaqueArea();
-}
-
-/*!
- \reimp
-*/
-int QGraphicsPathItem::type() const
-{
- return Type;
-}
-
-/*!
- \internal
-*/
-bool QGraphicsPathItem::supportsExtension(Extension extension) const
-{
- Q_UNUSED(extension);
- return false;
-}
-
-/*!
- \internal
-*/
-void QGraphicsPathItem::setExtension(Extension extension, const QVariant &variant)
-{
- Q_UNUSED(extension);
- Q_UNUSED(variant);
-}
-
-/*!
- \internal
-*/
-QVariant QGraphicsPathItem::extension(const QVariant &variant) const
-{
- Q_UNUSED(variant);
- return QVariant();
-}
-
-/*!
- \class QGraphicsRectItem
- \brief The QGraphicsRectItem class provides a rectangle item that you
- can add to a QGraphicsScene.
- \since 4.2
- \ingroup graphicsview-api
-
- To set the item's rectangle, pass a QRectF to QGraphicsRectItem's
- constructor, or call the setRect() function. The rect() function
- returns the current rectangle.
-
- \image graphicsview-rectitem.png
-
- QGraphicsRectItem uses the rectangle and the pen width to provide
- a reasonable implementation of boundingRect(), shape(), and
- contains(). The paint() function draws the rectangle using the
- item's associated pen and brush, which you can set by calling the
- setPen() and setBrush() functions.
-
- \note The rendering of invalid rectangles, such as those with negative
- widths or heights, is undefined. If you cannot be sure that you are
- using valid rectangles (for example, if you are creating
- rectangles using data from an unreliable source) then you should
- use QRectF::normalized() to create normalized rectangles, and use
- those instead.
-
- \sa QGraphicsPathItem, QGraphicsEllipseItem, QGraphicsPolygonItem,
- QGraphicsTextItem, QGraphicsLineItem, QGraphicsPixmapItem, {Graphics
- View Framework}
-*/
-
-class QGraphicsRectItemPrivate : public QAbstractGraphicsShapeItemPrivate
-{
- Q_DECLARE_PUBLIC(QGraphicsRectItem)
-public:
- QRectF rect;
-};
-
-/*!
- Constructs a QGraphicsRectItem, using \a rect as the default rectangle.
- \a parent is passed to QAbstractGraphicsShapeItem's constructor.
-
- \sa QGraphicsScene::addItem()
-*/
-QGraphicsRectItem::QGraphicsRectItem(const QRectF &rect, QGraphicsItem *parent
-#ifndef Q_QDOC
- // obsolete argument
- , QGraphicsScene *scene
-#endif
- )
- : QAbstractGraphicsShapeItem(*new QGraphicsRectItemPrivate, parent, scene)
-{
- setRect(rect);
-}
-
-/*!
- \fn QGraphicsRectItem::QGraphicsRectItem(qreal x, qreal y, qreal width, qreal height,
- QGraphicsItem *parent)
-
- Constructs a QGraphicsRectItem with a default rectangle defined
- by (\a x, \a y) and the given \a width and \a height.
-
- \a parent is passed to QAbstractGraphicsShapeItem's constructor.
-
- \sa QGraphicsScene::addItem()
-*/
-QGraphicsRectItem::QGraphicsRectItem(qreal x, qreal y, qreal w, qreal h,
- QGraphicsItem *parent
-#ifndef Q_QDOC
- // obsolete argument
- , QGraphicsScene *scene
-#endif
- )
- : QAbstractGraphicsShapeItem(*new QGraphicsRectItemPrivate, parent, scene)
-{
- setRect(QRectF(x, y, w, h));
-}
-
-/*!
- Constructs a QGraphicsRectItem. \a parent is passed to
- QAbstractGraphicsShapeItem's constructor.
-
- \sa QGraphicsScene::addItem()
-*/
-QGraphicsRectItem::QGraphicsRectItem(QGraphicsItem *parent
-#ifndef Q_QDOC
- // obsolete argument
- , QGraphicsScene *scene
-#endif
- )
- : QAbstractGraphicsShapeItem(*new QGraphicsRectItemPrivate, parent, scene)
-{
-}
-
-/*!
- Destroys the QGraphicsRectItem.
-*/
-QGraphicsRectItem::~QGraphicsRectItem()
-{
-}
-
-/*!
- Returns the item's rectangle.
-
- \sa setRect()
-*/
-QRectF QGraphicsRectItem::rect() const
-{
- Q_D(const QGraphicsRectItem);
- return d->rect;
-}
-
-/*!
- \fn void QGraphicsRectItem::setRect(const QRectF &rectangle)
-
- Sets the item's rectangle to be the given \a rectangle.
-
- \sa rect()
-*/
-void QGraphicsRectItem::setRect(const QRectF &rect)
-{
- Q_D(QGraphicsRectItem);
- if (d->rect == rect)
- return;
- prepareGeometryChange();
- d->rect = rect;
- d->boundingRect = QRectF();
- update();
-}
-
-/*!
- \fn void QGraphicsRectItem::setRect(qreal x, qreal y, qreal width, qreal height)
- \fn void QGraphicsEllipseItem::setRect(qreal x, qreal y, qreal width, qreal height)
-
- Sets the item's rectangle to the rectangle defined by (\a x, \a y)
- and the given \a width and \a height.
-
- This convenience function is equivalent to calling \c
- {setRect(QRectF(x, y, width, height))}
-
- \sa rect()
-*/
-
-/*!
- \reimp
-*/
-QRectF QGraphicsRectItem::boundingRect() const
-{
- Q_D(const QGraphicsRectItem);
- if (d->boundingRect.isNull()) {
- qreal halfpw = pen().widthF() / 2;
- d->boundingRect = d->rect;
- if (halfpw > 0.0)
- d->boundingRect.adjust(-halfpw, -halfpw, halfpw, halfpw);
- }
- return d->boundingRect;
-}
-
-/*!
- \reimp
-*/
-QPainterPath QGraphicsRectItem::shape() const
-{
- Q_D(const QGraphicsRectItem);
- QPainterPath path;
- path.addRect(d->rect);
- return qt_graphicsItem_shapeFromPath(path, d->pen);
-}
-
-/*!
- \reimp
-*/
-bool QGraphicsRectItem::contains(const QPointF &point) const
-{
- return QAbstractGraphicsShapeItem::contains(point);
-}
-
-/*!
- \reimp
-*/
-void QGraphicsRectItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
- QWidget *widget)
-{
- Q_D(QGraphicsRectItem);
- Q_UNUSED(widget);
- painter->setPen(d->pen);
- painter->setBrush(d->brush);
- painter->drawRect(d->rect);
-
- if (option->state & QStyle::State_Selected)
- qt_graphicsItem_highlightSelected(this, painter, option);
-}
-
-/*!
- \reimp
-*/
-bool QGraphicsRectItem::isObscuredBy(const QGraphicsItem *item) const
-{
- return QAbstractGraphicsShapeItem::isObscuredBy(item);
-}
-
-/*!
- \reimp
-*/
-QPainterPath QGraphicsRectItem::opaqueArea() const
-{
- return QAbstractGraphicsShapeItem::opaqueArea();
-}
-
-/*!
- \reimp
-*/
-int QGraphicsRectItem::type() const
-{
- return Type;
-}
-
-/*!
- \internal
-*/
-bool QGraphicsRectItem::supportsExtension(Extension extension) const
-{
- Q_UNUSED(extension);
- return false;
-}
-
-/*!
- \internal
-*/
-void QGraphicsRectItem::setExtension(Extension extension, const QVariant &variant)
-{
- Q_UNUSED(extension);
- Q_UNUSED(variant);
-}
-
-/*!
- \internal
-*/
-QVariant QGraphicsRectItem::extension(const QVariant &variant) const
-{
- Q_UNUSED(variant);
- return QVariant();
-}
-
-/*!
- \class QGraphicsEllipseItem
- \brief The QGraphicsEllipseItem class provides an ellipse item that you
- can add to a QGraphicsScene.
- \since 4.2
- \ingroup graphicsview-api
-
- QGraphicsEllipseItem respresents an ellipse with a fill and an outline,
- and you can also use it for ellipse segments (see startAngle(),
- spanAngle()).
-
- \table
- \row
- \o \inlineimage graphicsview-ellipseitem.png
- \o \inlineimage graphicsview-ellipseitem-pie.png
- \endtable
-
- To set the item's ellipse, pass a QRectF to QGraphicsEllipseItem's
- constructor, or call setRect(). The rect() function returns the
- current ellipse geometry.
-
- QGraphicsEllipseItem uses the rect and the pen width to provide a
- reasonable implementation of boundingRect(), shape(), and contains(). The
- paint() function draws the ellipse using the item's associated pen and
- brush, which you can set by calling setPen() and setBrush().
-
- \sa QGraphicsPathItem, QGraphicsRectItem, QGraphicsPolygonItem,
- QGraphicsTextItem, QGraphicsLineItem, QGraphicsPixmapItem, {Graphics
- View Framework}
-*/
-
-class QGraphicsEllipseItemPrivate : public QAbstractGraphicsShapeItemPrivate
-{
- Q_DECLARE_PUBLIC(QGraphicsEllipseItem)
-public:
- inline QGraphicsEllipseItemPrivate()
- : startAngle(0), spanAngle(360 * 16)
- { }
-
- QRectF rect;
- int startAngle;
- int spanAngle;
-};
-
-/*!
- Constructs a QGraphicsEllipseItem using \a rect as the default rectangle.
- \a parent is passed to QAbstractGraphicsShapeItem's constructor.
-
- \sa QGraphicsScene::addItem()
-*/
-QGraphicsEllipseItem::QGraphicsEllipseItem(const QRectF &rect, QGraphicsItem *parent
-#ifndef Q_QDOC
- // obsolete argument
- , QGraphicsScene *scene
-#endif
- )
- : QAbstractGraphicsShapeItem(*new QGraphicsEllipseItemPrivate, parent, scene)
-{
- setRect(rect);
-}
-
-/*!
- \fn QGraphicsEllipseItem::QGraphicsEllipseItem(qreal x, qreal y, qreal width, qreal height, QGraphicsItem *parent)
- \since 4.3
-
- Constructs a QGraphicsEllipseItem using the rectangle defined by (\a x, \a
- y) and the given \a width and \a height, as the default rectangle. \a
- parent is passed to QAbstractGraphicsShapeItem's constructor.
-
- \sa QGraphicsScene::addItem()
-*/
-QGraphicsEllipseItem::QGraphicsEllipseItem(qreal x, qreal y, qreal w, qreal h,
- QGraphicsItem *parent
-#ifndef Q_QDOC
- // obsolete argument
- , QGraphicsScene *scene
-#endif
- )
- : QAbstractGraphicsShapeItem(*new QGraphicsEllipseItemPrivate, parent, scene)
-{
- setRect(x,y,w,h);
-}
-
-
-
-/*!
- Constructs a QGraphicsEllipseItem. \a parent is passed to
- QAbstractGraphicsShapeItem's constructor.
-
- \sa QGraphicsScene::addItem()
-*/
-QGraphicsEllipseItem::QGraphicsEllipseItem(QGraphicsItem *parent
-#ifndef Q_QDOC
- // obsolete argument
- , QGraphicsScene *scene
-#endif
- )
- : QAbstractGraphicsShapeItem(*new QGraphicsEllipseItemPrivate, parent, scene)
-{
-}
-
-/*!
- Destroys the QGraphicsEllipseItem.
-*/
-QGraphicsEllipseItem::~QGraphicsEllipseItem()
-{
-}
-
-/*!
- Returns the item's ellipse geometry as a QRectF.
-
- \sa setRect(), QPainter::drawEllipse()
-*/
-QRectF QGraphicsEllipseItem::rect() const
-{
- Q_D(const QGraphicsEllipseItem);
- return d->rect;
-}
-
-/*!
- Sets the item's ellipse geometry to \a rect. The rectangle's left edge
- defines the left edge of the ellipse, and the rectangle's top edge
- describes the top of the ellipse. The height and width of the rectangle
- describe the height and width of the ellipse.
-
- \sa rect(), QPainter::drawEllipse()
-*/
-void QGraphicsEllipseItem::setRect(const QRectF &rect)
-{
- Q_D(QGraphicsEllipseItem);
- if (d->rect == rect)
- return;
- prepareGeometryChange();
- d->rect = rect;
- d->boundingRect = QRectF();
- update();
-}
-
-/*!
- Returns the start angle for an ellipse segment in 16ths of a degree. This
- angle is used together with spanAngle() for representing an ellipse
- segment (a pie). By default, the start angle is 0.
-
- \sa setStartAngle(), spanAngle()
-*/
-int QGraphicsEllipseItem::startAngle() const
-{
- Q_D(const QGraphicsEllipseItem);
- return d->startAngle;
-}
-
-/*!
- Sets the start angle for an ellipse segment to \a angle, which is in 16ths
- of a degree. This angle is used together with spanAngle() for representing
- an ellipse segment (a pie). By default, the start angle is 0.
-
- \sa startAngle(), setSpanAngle(), QPainter::drawPie()
-*/
-void QGraphicsEllipseItem::setStartAngle(int angle)
-{
- Q_D(QGraphicsEllipseItem);
- if (angle != d->startAngle) {
- prepareGeometryChange();
- d->boundingRect = QRectF();
- d->startAngle = angle;
- update();
- }
-}
-
-/*!
- Returns the span angle of an ellipse segment in 16ths of a degree. This
- angle is used together with startAngle() for representing an ellipse
- segment (a pie). By default, this function returns 5760 (360 * 16, a full
- ellipse).
-
- \sa setSpanAngle(), startAngle()
-*/
-int QGraphicsEllipseItem::spanAngle() const
-{
- Q_D(const QGraphicsEllipseItem);
- return d->spanAngle;
-}
-
-/*!
- Sets the span angle for an ellipse segment to \a angle, which is in 16ths
- of a degree. This angle is used together with startAngle() to represent an
- ellipse segment (a pie). By default, the span angle is 5760 (360 * 16, a
- full ellipse).
-
- \sa spanAngle(), setStartAngle(), QPainter::drawPie()
-*/
-void QGraphicsEllipseItem::setSpanAngle(int angle)
-{
- Q_D(QGraphicsEllipseItem);
- if (angle != d->spanAngle) {
- prepareGeometryChange();
- d->boundingRect = QRectF();
- d->spanAngle = angle;
- update();
- }
-}
-
-/*!
- \reimp
-*/
-QRectF QGraphicsEllipseItem::boundingRect() const
-{
- Q_D(const QGraphicsEllipseItem);
- if (d->boundingRect.isNull()) {
- qreal pw = pen().widthF();
- if (pw == 0.0 && d->spanAngle == 360 * 16)
- d->boundingRect = d->rect;
- else
- d->boundingRect = shape().controlPointRect();
- }
- return d->boundingRect;
-}
-
-/*!
- \reimp
-*/
-QPainterPath QGraphicsEllipseItem::shape() const
-{
- Q_D(const QGraphicsEllipseItem);
- QPainterPath path;
- if (d->rect.isNull())
- return path;
- if (d->spanAngle != 360 * 16) {
- path.moveTo(d->rect.center());
- path.arcTo(d->rect, d->startAngle / 16.0, d->spanAngle / 16.0);
- } else {
- path.addEllipse(d->rect);
- }
-
- return qt_graphicsItem_shapeFromPath(path, d->pen);
-}
-
-/*!
- \reimp
-*/
-bool QGraphicsEllipseItem::contains(const QPointF &point) const
-{
- return QAbstractGraphicsShapeItem::contains(point);
-}
-
-/*!
- \reimp
-*/
-void QGraphicsEllipseItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
- QWidget *widget)
-{
- Q_D(QGraphicsEllipseItem);
- Q_UNUSED(widget);
- painter->setPen(d->pen);
- painter->setBrush(d->brush);
- if ((d->spanAngle != 0) && (qAbs(d->spanAngle) % (360 * 16) == 0))
- painter->drawEllipse(d->rect);
- else
- painter->drawPie(d->rect, d->startAngle, d->spanAngle);
-
- if (option->state & QStyle::State_Selected)
- qt_graphicsItem_highlightSelected(this, painter, option);
-}
-
-/*!
- \reimp
-*/
-bool QGraphicsEllipseItem::isObscuredBy(const QGraphicsItem *item) const
-{
- return QAbstractGraphicsShapeItem::isObscuredBy(item);
-}
-
-/*!
- \reimp
-*/
-QPainterPath QGraphicsEllipseItem::opaqueArea() const
-{
- return QAbstractGraphicsShapeItem::opaqueArea();
-}
-
-/*!
- \reimp
-*/
-int QGraphicsEllipseItem::type() const
-{
- return Type;
-}
-
-
-/*!
- \internal
-*/
-bool QGraphicsEllipseItem::supportsExtension(Extension extension) const
-{
- Q_UNUSED(extension);
- return false;
-}
-
-/*!
- \internal
-*/
-void QGraphicsEllipseItem::setExtension(Extension extension, const QVariant &variant)
-{
- Q_UNUSED(extension);
- Q_UNUSED(variant);
-}
-
-/*!
- \internal
-*/
-QVariant QGraphicsEllipseItem::extension(const QVariant &variant) const
-{
- Q_UNUSED(variant);
- return QVariant();
-}
-
-/*!
- \class QGraphicsPolygonItem
- \brief The QGraphicsPolygonItem class provides a polygon item that you
- can add to a QGraphicsScene.
- \since 4.2
- \ingroup graphicsview-api
-
- To set the item's polygon, pass a QPolygonF to
- QGraphicsPolygonItem's constructor, or call the setPolygon()
- function. The polygon() function returns the current polygon.
-
- \image graphicsview-polygonitem.png
-
- QGraphicsPolygonItem uses the polygon and the pen width to provide
- a reasonable implementation of boundingRect(), shape(), and
- contains(). The paint() function draws the polygon using the
- item's associated pen and brush, which you can set by calling the
- setPen() and setBrush() functions.
-
- \sa QGraphicsPathItem, QGraphicsRectItem, QGraphicsEllipseItem,
- QGraphicsTextItem, QGraphicsLineItem, QGraphicsPixmapItem, {Graphics
- View Framework}
-*/
-
-class QGraphicsPolygonItemPrivate : public QAbstractGraphicsShapeItemPrivate
-{
- Q_DECLARE_PUBLIC(QGraphicsPolygonItem)
-public:
- inline QGraphicsPolygonItemPrivate()
- : fillRule(Qt::OddEvenFill)
- { }
-
- QPolygonF polygon;
- Qt::FillRule fillRule;
-};
-
-/*!
- Constructs a QGraphicsPolygonItem with \a polygon as the default
- polygon. \a parent is passed to QAbstractGraphicsShapeItem's constructor.
-
- \sa QGraphicsScene::addItem()
-*/
-QGraphicsPolygonItem::QGraphicsPolygonItem(const QPolygonF &polygon,
- QGraphicsItem *parent
-#ifndef Q_QDOC
- // obsolete argument
- , QGraphicsScene *scene
-#endif
- )
- : QAbstractGraphicsShapeItem(*new QGraphicsPolygonItemPrivate, parent, scene)
-{
- setPolygon(polygon);
-}
-
-/*!
- Constructs a QGraphicsPolygonItem. \a parent is passed to
- QAbstractGraphicsShapeItem's constructor.
-
- \sa QGraphicsScene::addItem()
-*/
-QGraphicsPolygonItem::QGraphicsPolygonItem(QGraphicsItem *parent
-#ifndef Q_QDOC
- // obsolete argument
- , QGraphicsScene *scene
-#endif
- )
- : QAbstractGraphicsShapeItem(*new QGraphicsPolygonItemPrivate, parent, scene)
-{
-}
-
-/*!
- Destroys the QGraphicsPolygonItem.
-*/
-QGraphicsPolygonItem::~QGraphicsPolygonItem()
-{
-}
-
-/*!
- Returns the item's polygon, or an empty polygon if no polygon
- has been set.
-
- \sa setPolygon()
-*/
-QPolygonF QGraphicsPolygonItem::polygon() const
-{
- Q_D(const QGraphicsPolygonItem);
- return d->polygon;
-}
-
-/*!
- Sets the item's polygon to be the given \a polygon.
-
- \sa polygon()
-*/
-void QGraphicsPolygonItem::setPolygon(const QPolygonF &polygon)
-{
- Q_D(QGraphicsPolygonItem);
- if (d->polygon == polygon)
- return;
- prepareGeometryChange();
- d->polygon = polygon;
- d->boundingRect = QRectF();
- update();
-}
-
-/*!
- Returns the fill rule of the polygon. The default fill rule is
- Qt::OddEvenFill.
-
- \sa setFillRule(), QPainterPath::fillRule(), QPainter::drawPolygon()
-*/
-Qt::FillRule QGraphicsPolygonItem::fillRule() const
-{
- Q_D(const QGraphicsPolygonItem);
- return d->fillRule;
-}
-
-/*!
- Sets the fill rule of the polygon to \a rule. The default fill rule is
- Qt::OddEvenFill.
-
- \sa fillRule(), QPainterPath::fillRule(), QPainter::drawPolygon()
-*/
-void QGraphicsPolygonItem::setFillRule(Qt::FillRule rule)
-{
- Q_D(QGraphicsPolygonItem);
- if (rule != d->fillRule) {
- d->fillRule = rule;
- update();
- }
-}
-
-/*!
- \reimp
-*/
-QRectF QGraphicsPolygonItem::boundingRect() const
-{
- Q_D(const QGraphicsPolygonItem);
- if (d->boundingRect.isNull()) {
- qreal pw = pen().widthF();
- if (pw == 0.0)
- d->boundingRect = d->polygon.boundingRect();
- else
- d->boundingRect = shape().controlPointRect();
- }
- return d->boundingRect;
-}
-
-/*!
- \reimp
-*/
-QPainterPath QGraphicsPolygonItem::shape() const
-{
- Q_D(const QGraphicsPolygonItem);
- QPainterPath path;
- path.addPolygon(d->polygon);
- return qt_graphicsItem_shapeFromPath(path, d->pen);
-}
-
-/*!
- \reimp
-*/
-bool QGraphicsPolygonItem::contains(const QPointF &point) const
-{
- return QAbstractGraphicsShapeItem::contains(point);
-}
-
-/*!
- \reimp
-*/
-void QGraphicsPolygonItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
-{
- Q_D(QGraphicsPolygonItem);
- Q_UNUSED(widget);
- painter->setPen(d->pen);
- painter->setBrush(d->brush);
- painter->drawPolygon(d->polygon, d->fillRule);
-
- if (option->state & QStyle::State_Selected)
- qt_graphicsItem_highlightSelected(this, painter, option);
-}
-
-/*!
- \reimp
-*/
-bool QGraphicsPolygonItem::isObscuredBy(const QGraphicsItem *item) const
-{
- return QAbstractGraphicsShapeItem::isObscuredBy(item);
-}
-
-/*!
- \reimp
-*/
-QPainterPath QGraphicsPolygonItem::opaqueArea() const
-{
- return QAbstractGraphicsShapeItem::opaqueArea();
-}
-
-/*!
- \reimp
-*/
-int QGraphicsPolygonItem::type() const
-{
- return Type;
-}
-
-/*!
- \internal
-*/
-bool QGraphicsPolygonItem::supportsExtension(Extension extension) const
-{
- Q_UNUSED(extension);
- return false;
-}
-
-/*!
- \internal
-*/
-void QGraphicsPolygonItem::setExtension(Extension extension, const QVariant &variant)
-{
- Q_UNUSED(extension);
- Q_UNUSED(variant);
-}
-
-/*!
- \internal
-*/
-QVariant QGraphicsPolygonItem::extension(const QVariant &variant) const
-{
- Q_UNUSED(variant);
- return QVariant();
-}
-
-/*!
- \class QGraphicsLineItem
- \brief The QGraphicsLineItem class provides a line item that you can add to a
- QGraphicsScene.
- \since 4.2
- \ingroup graphicsview-api
-
- To set the item's line, pass a QLineF to QGraphicsLineItem's
- constructor, or call the setLine() function. The line() function
- returns the current line. By default the line is black with a
- width of 0, but you can change this by calling setPen().
-
- \img graphicsview-lineitem.png
-
- QGraphicsLineItem uses the line and the pen width to provide a reasonable
- implementation of boundingRect(), shape(), and contains(). The paint()
- function draws the line using the item's associated pen.
-
- \sa QGraphicsPathItem, QGraphicsRectItem, QGraphicsEllipseItem,
- QGraphicsTextItem, QGraphicsPolygonItem, QGraphicsPixmapItem,
- {Graphics View Framework}
-*/
-
-class QGraphicsLineItemPrivate : public QGraphicsItemPrivate
-{
- Q_DECLARE_PUBLIC(QGraphicsLineItem)
-public:
- QLineF line;
- QPen pen;
-};
-
-/*!
- Constructs a QGraphicsLineItem, using \a line as the default line. \a
- parent is passed to QGraphicsItem's constructor.
-
- \sa QGraphicsScene::addItem()
-*/
-QGraphicsLineItem::QGraphicsLineItem(const QLineF &line, QGraphicsItem *parent
-#ifndef Q_QDOC
- // obsolete argument
- , QGraphicsScene *scene
-#endif
- )
- : QGraphicsItem(*new QGraphicsLineItemPrivate, parent, scene)
-{
- setLine(line);
-}
-
-/*!
- Constructs a QGraphicsLineItem, using the line between (\a x1, \a y1) and
- (\a x2, \a y2) as the default line. \a parent is passed to
- QGraphicsItem's constructor.
-
- \sa QGraphicsScene::addItem()
-*/
-QGraphicsLineItem::QGraphicsLineItem(qreal x1, qreal y1, qreal x2, qreal y2, QGraphicsItem *parent
-#ifndef Q_QDOC
- // obsolete argument
- , QGraphicsScene *scene
-#endif
- )
- : QGraphicsItem(*new QGraphicsLineItemPrivate, parent, scene)
-{
- setLine(x1, y1, x2, y2);
-}
-
-
-
-/*!
- Constructs a QGraphicsLineItem. \a parent is passed to QGraphicsItem's
- constructor.
-
- \sa QGraphicsScene::addItem()
-*/
-QGraphicsLineItem::QGraphicsLineItem(QGraphicsItem *parent
-#ifndef Q_QDOC
- // obsolete argument
- , QGraphicsScene *scene
-#endif
- )
- : QGraphicsItem(*new QGraphicsLineItemPrivate, parent, scene)
-{
-}
-
-/*!
- Destroys the QGraphicsLineItem.
-*/
-QGraphicsLineItem::~QGraphicsLineItem()
-{
-}
-
-/*!
- Returns the item's pen, or a black solid 0-width pen if no pen has
- been set.
-
- \sa setPen()
-*/
-QPen QGraphicsLineItem::pen() const
-{
- Q_D(const QGraphicsLineItem);
- return d->pen;
-}
-
-/*!
- Sets the item's pen to \a pen. If no pen is set, the line will be painted
- using a black solid 0-width pen.
-
- \sa pen()
-*/
-void QGraphicsLineItem::setPen(const QPen &pen)
-{
- Q_D(QGraphicsLineItem);
- if (d->pen == pen)
- return;
- prepareGeometryChange();
- d->pen = pen;
- update();
-}
-
-/*!
- Returns the item's line, or a null line if no line has been set.
-
- \sa setLine()
-*/
-QLineF QGraphicsLineItem::line() const
-{
- Q_D(const QGraphicsLineItem);
- return d->line;
-}
-
-/*!
- Sets the item's line to be the given \a line.
-
- \sa line()
-*/
-void QGraphicsLineItem::setLine(const QLineF &line)
-{
- Q_D(QGraphicsLineItem);
- if (d->line == line)
- return;
- prepareGeometryChange();
- d->line = line;
- update();
-}
-
-/*!
- \fn void QGraphicsLineItem::setLine(qreal x1, qreal y1, qreal x2, qreal y2)
- \overload
-
- Sets the item's line to be the line between (\a x1, \a y1) and (\a
- x2, \a y2).
-
- This is the same as calling \c {setLine(QLineF(x1, y1, x2, y2))}.
-*/
-
-/*!
- \reimp
-*/
-QRectF QGraphicsLineItem::boundingRect() const
-{
- Q_D(const QGraphicsLineItem);
- if (d->pen.widthF() == 0.0) {
- const qreal x1 = d->line.p1().x();
- const qreal x2 = d->line.p2().x();
- const qreal y1 = d->line.p1().y();
- const qreal y2 = d->line.p2().y();
- qreal lx = qMin(x1, x2);
- qreal rx = qMax(x1, x2);
- qreal ty = qMin(y1, y2);
- qreal by = qMax(y1, y2);
- return QRectF(lx, ty, rx - lx, by - ty);
- }
- return shape().controlPointRect();
-}
-
-/*!
- \reimp
-*/
-QPainterPath QGraphicsLineItem::shape() const
-{
- Q_D(const QGraphicsLineItem);
- QPainterPath path;
- if (d->line == QLineF())
- return path;
-
- path.moveTo(d->line.p1());
- path.lineTo(d->line.p2());
- return qt_graphicsItem_shapeFromPath(path, d->pen);
-}
-
-/*!
- \reimp
-*/
-bool QGraphicsLineItem::contains(const QPointF &point) const
-{
- return QGraphicsItem::contains(point);
-}
-
-/*!
- \reimp
-*/
-void QGraphicsLineItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
-{
- Q_D(QGraphicsLineItem);
- Q_UNUSED(widget);
- painter->setPen(d->pen);
- painter->drawLine(d->line);
-
- if (option->state & QStyle::State_Selected)
- qt_graphicsItem_highlightSelected(this, painter, option);
-}
-
-/*!
- \reimp
-*/
-bool QGraphicsLineItem::isObscuredBy(const QGraphicsItem *item) const
-{
- return QGraphicsItem::isObscuredBy(item);
-}
-
-/*!
- \reimp
-*/
-QPainterPath QGraphicsLineItem::opaqueArea() const
-{
- return QGraphicsItem::opaqueArea();
-}
-
-/*!
- \reimp
-*/
-int QGraphicsLineItem::type() const
-{
- return Type;
-}
-
-/*!
- \internal
-*/
-bool QGraphicsLineItem::supportsExtension(Extension extension) const
-{
- Q_UNUSED(extension);
- return false;
-}
-
-/*!
- \internal
-*/
-void QGraphicsLineItem::setExtension(Extension extension, const QVariant &variant)
-{
- Q_UNUSED(extension);
- Q_UNUSED(variant);
-}
-
-/*!
- \internal
-*/
-QVariant QGraphicsLineItem::extension(const QVariant &variant) const
-{
- Q_UNUSED(variant);
- return QVariant();
-}
-
-/*!
- \class QGraphicsPixmapItem
- \brief The QGraphicsPixmapItem class provides a pixmap item that you can add to
- a QGraphicsScene.
- \since 4.2
- \ingroup graphicsview-api
-
- To set the item's pixmap, pass a QPixmap to QGraphicsPixmapItem's
- constructor, or call the setPixmap() function. The pixmap()
- function returns the current pixmap.
-
- QGraphicsPixmapItem uses pixmap's optional alpha mask to provide a
- reasonable implementation of boundingRect(), shape(), and contains().
-
- \image graphicsview-pixmapitem.png
-
- The pixmap is drawn at the item's (0, 0) coordinate, as returned by
- offset(). You can change the drawing offset by calling setOffset().
-
- You can set the pixmap's transformation mode by calling
- setTransformationMode(). By default, Qt::FastTransformation is used, which
- provides fast, non-smooth scaling. Qt::SmoothTransformation enables
- QPainter::SmoothPixmapTransform on the painter, and the quality depends on
- the platform and viewport. The result is usually not as good as calling
- QPixmap::scale() directly. Call transformationMode() to get the current
- transformation mode for the item.
-
- \sa QGraphicsPathItem, QGraphicsRectItem, QGraphicsEllipseItem,
- QGraphicsTextItem, QGraphicsPolygonItem, QGraphicsLineItem,
- {Graphics View Framework}
-*/
-
-/*!
- \enum QGraphicsPixmapItem::ShapeMode
-
- This enum describes how QGraphicsPixmapItem calculates its shape and
- opaque area.
-
- The default value is MaskShape.
-
- \value MaskShape The shape is determined by calling QPixmap::mask().
- This shape includes only the opaque pixels of the pixmap.
- Because the shape is more complex, however, it can be slower than the other modes,
- and uses more memory.
-
- \value BoundingRectShape The shape is determined by tracing the outline of
- the pixmap. This is the fastest shape mode, but it does not take into account
- any transparent areas on the pixmap.
-
- \value HeuristicMaskShape The shape is determine by calling
- QPixmap::createHeuristicMask(). The performance and memory consumption
- is similar to MaskShape.
-*/
-extern QPainterPath qt_regionToPath(const QRegion &region);
-
-class QGraphicsPixmapItemPrivate : public QGraphicsItemPrivate
-{
- Q_DECLARE_PUBLIC(QGraphicsPixmapItem)
-public:
- QGraphicsPixmapItemPrivate()
- : transformationMode(Qt::FastTransformation),
- shapeMode(QGraphicsPixmapItem::MaskShape),
- hasShape(false)
- {}
-
- QPixmap pixmap;
- Qt::TransformationMode transformationMode;
- QPointF offset;
- QGraphicsPixmapItem::ShapeMode shapeMode;
- QPainterPath shape;
- bool hasShape;
-
- void updateShape()
- {
- shape = QPainterPath();
- switch (shapeMode) {
- case QGraphicsPixmapItem::MaskShape: {
- QBitmap mask = pixmap.mask();
- if (!mask.isNull()) {
- shape = qt_regionToPath(QRegion(mask).translated(offset.toPoint()));
- break;
- }
- // FALL THROUGH
- }
- case QGraphicsPixmapItem::BoundingRectShape:
- shape.addRect(QRectF(offset.x(), offset.y(), pixmap.width(), pixmap.height()));
- break;
- case QGraphicsPixmapItem::HeuristicMaskShape:
-#ifndef QT_NO_IMAGE_HEURISTIC_MASK
- shape = qt_regionToPath(QRegion(pixmap.createHeuristicMask()).translated(offset.toPoint()));
-#else
- shape.addRect(QRectF(offset.x(), offset.y(), pixmap.width(), pixmap.height()));
-#endif
- break;
- }
- }
-};
-
-/*!
- Constructs a QGraphicsPixmapItem, using \a pixmap as the default pixmap.
- \a parent is passed to QGraphicsItem's constructor.
-
- \sa QGraphicsScene::addItem()
-*/
-QGraphicsPixmapItem::QGraphicsPixmapItem(const QPixmap &pixmap,
- QGraphicsItem *parent
-#ifndef Q_QDOC
- // obsolete argument
- , QGraphicsScene *scene
-#endif
- )
- : QGraphicsItem(*new QGraphicsPixmapItemPrivate, parent, scene)
-{
- setPixmap(pixmap);
-}
-
-/*!
- Constructs a QGraphicsPixmapItem. \a parent is passed to QGraphicsItem's
- constructor.
-
- \sa QGraphicsScene::addItem()
-*/
-QGraphicsPixmapItem::QGraphicsPixmapItem(QGraphicsItem *parent
-#ifndef Q_QDOC
- // obsolete argument
- , QGraphicsScene *scene
-#endif
- )
- : QGraphicsItem(*new QGraphicsPixmapItemPrivate, parent, scene)
-{
-}
-
-/*!
- Destroys the QGraphicsPixmapItem.
-*/
-QGraphicsPixmapItem::~QGraphicsPixmapItem()
-{
-}
-
-/*!
- Sets the item's pixmap to \a pixmap.
-
- \sa pixmap()
-*/
-void QGraphicsPixmapItem::setPixmap(const QPixmap &pixmap)
-{
- Q_D(QGraphicsPixmapItem);
- prepareGeometryChange();
- d->pixmap = pixmap;
- d->hasShape = false;
- update();
-}
-
-/*!
- Returns the item's pixmap, or an invalid QPixmap if no pixmap has been
- set.
-
- \sa setPixmap()
-*/
-QPixmap QGraphicsPixmapItem::pixmap() const
-{
- Q_D(const QGraphicsPixmapItem);
- return d->pixmap;
-}
-
-/*!
- Returns the transformation mode of the pixmap. The default mode is
- Qt::FastTransformation, which provides quick transformation with no
- smoothing.
-
- \sa setTransformationMode()
-*/
-Qt::TransformationMode QGraphicsPixmapItem::transformationMode() const
-{
- Q_D(const QGraphicsPixmapItem);
- return d->transformationMode;
-}
-
-/*!
- Sets the pixmap item's transformation mode to \a mode, and toggles an
- update of the item. The default mode is Qt::FastTransformation, which
- provides quick transformation with no smoothing.
-
- Qt::SmoothTransformation enables QPainter::SmoothPixmapTransform on the
- painter, and the quality depends on the platform and viewport. The result
- is usually not as good as calling QPixmap::scale() directly.
-
- \sa transformationMode()
-*/
-void QGraphicsPixmapItem::setTransformationMode(Qt::TransformationMode mode)
-{
- Q_D(QGraphicsPixmapItem);
- if (mode != d->transformationMode) {
- d->transformationMode = mode;
- update();
- }
-}
-
-/*!
- Returns the pixmap item's \e offset, which defines the point of the
- top-left corner of the pixmap, in local coordinates.
-
- \sa setOffset()
-*/
-QPointF QGraphicsPixmapItem::offset() const
-{
- Q_D(const QGraphicsPixmapItem);
- return d->offset;
-}
-
-/*!
- Sets the pixmap item's offset to \a offset. QGraphicsPixmapItem will draw
- its pixmap using \a offset for its top-left corner.
-
- \sa offset()
-*/
-void QGraphicsPixmapItem::setOffset(const QPointF &offset)
-{
- Q_D(QGraphicsPixmapItem);
- if (d->offset == offset)
- return;
- prepareGeometryChange();
- d->offset = offset;
- d->hasShape = false;
- update();
-}
-
-/*!
- \fn void QGraphicsPixmapItem::setOffset(qreal x, qreal y)
- \since 4.3
-
- This convenience function is equivalent to calling setOffset(QPointF(\a x, \a y)).
-*/
-
-/*!
- \reimp
-*/
-QRectF QGraphicsPixmapItem::boundingRect() const
-{
- Q_D(const QGraphicsPixmapItem);
- if (d->pixmap.isNull())
- return QRectF();
- if (d->flags & ItemIsSelectable) {
- qreal pw = 1.0;
- return QRectF(d->offset, d->pixmap.size()).adjusted(-pw/2, -pw/2, pw/2, pw/2);
- } else {
- return QRectF(d->offset, d->pixmap.size());
- }
-}
-
-/*!
- \reimp
-*/
-QPainterPath QGraphicsPixmapItem::shape() const
-{
- Q_D(const QGraphicsPixmapItem);
- if (!d->hasShape) {
- QGraphicsPixmapItemPrivate *thatD = const_cast<QGraphicsPixmapItemPrivate *>(d);
- thatD->updateShape();
- thatD->hasShape = true;
- }
- return d_func()->shape;
-}
-
-/*!
- \reimp
-*/
-bool QGraphicsPixmapItem::contains(const QPointF &point) const
-{
- return QGraphicsItem::contains(point);
-}
-
-/*!
- \reimp
-*/
-void QGraphicsPixmapItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
- QWidget *widget)
-{
- Q_D(QGraphicsPixmapItem);
- Q_UNUSED(widget);
-
- painter->setRenderHint(QPainter::SmoothPixmapTransform,
- (d->transformationMode == Qt::SmoothTransformation));
-
- painter->drawPixmap(d->offset, d->pixmap);
-
- if (option->state & QStyle::State_Selected)
- qt_graphicsItem_highlightSelected(this, painter, option);
-}
-
-/*!
- \reimp
-*/
-bool QGraphicsPixmapItem::isObscuredBy(const QGraphicsItem *item) const
-{
- return QGraphicsItem::isObscuredBy(item);
-}
-
-/*!
- \reimp
-*/
-QPainterPath QGraphicsPixmapItem::opaqueArea() const
-{
- return shape();
-}
-
-/*!
- \reimp
-*/
-int QGraphicsPixmapItem::type() const
-{
- return Type;
-}
-
-/*!
- Returns the item's shape mode. The shape mode describes how
- QGraphicsPixmapItem calculates its shape. The default mode is MaskShape.
-
- \sa setShapeMode(), ShapeMode
-*/
-QGraphicsPixmapItem::ShapeMode QGraphicsPixmapItem::shapeMode() const
-{
- return d_func()->shapeMode;
-}
-
-/*!
- Sets the item's shape mode to \a mode. The shape mode describes how
- QGraphicsPixmapItem calculates its shape. The default mode is MaskShape.
-
- \sa shapeMode(), ShapeMode
-*/
-void QGraphicsPixmapItem::setShapeMode(ShapeMode mode)
-{
- Q_D(QGraphicsPixmapItem);
- if (d->shapeMode == mode)
- return;
- d->shapeMode = mode;
- d->hasShape = false;
-}
-
-/*!
- \internal
-*/
-bool QGraphicsPixmapItem::supportsExtension(Extension extension) const
-{
- Q_UNUSED(extension);
- return false;
-}
-
-/*!
- \internal
-*/
-void QGraphicsPixmapItem::setExtension(Extension extension, const QVariant &variant)
-{
- Q_UNUSED(extension);
- Q_UNUSED(variant);
-}
-
-/*!
- \internal
-*/
-QVariant QGraphicsPixmapItem::extension(const QVariant &variant) const
-{
- Q_UNUSED(variant);
- return QVariant();
-}
-
-/*!
- \class QGraphicsTextItem
- \brief The QGraphicsTextItem class provides a text item that you can add to
- a QGraphicsScene to display formatted text.
- \since 4.2
- \ingroup graphicsview-api
-
- If you only need to show plain text in an item, consider using QGraphicsSimpleTextItem
- instead.
-
- To set the item's text, pass a QString to QGraphicsTextItem's
- constructor, or call setHtml()/setPlainText().
-
- QGraphicsTextItem uses the text's formatted size and the associated font
- to provide a reasonable implementation of boundingRect(), shape(),
- and contains(). You can set the font by calling setFont().
-
- It is possible to make the item editable by setting the Qt::TextEditorInteraction flag
- using setTextInteractionFlags().
-
- The item's preferred text width can be set using setTextWidth() and obtained
- using textWidth().
-
- \note In order to align HTML text in the center, the item's text width must be set.
-
- \img graphicsview-textitem.png
-
- \note QGraphicsTextItem accepts \l{QGraphicsItem::acceptHoverEvents()}{hover events}
- by default. You can change this with \l{QGraphicsItem::}{setAcceptHoverEvents()}.
-
- \sa QGraphicsSimpleTextItem, QGraphicsPathItem, QGraphicsRectItem,
- QGraphicsEllipseItem, QGraphicsPixmapItem, QGraphicsPolygonItem,
- QGraphicsLineItem, {Graphics View Framework}
-*/
-
-class QGraphicsTextItemPrivate
-{
-public:
- QGraphicsTextItemPrivate()
- : control(0), pageNumber(0), useDefaultImpl(false), tabChangesFocus(false), clickCausedFocus(0)
- { }
-
- mutable QTextControl *control;
- QTextControl *textControl() const;
-
- inline QPointF controlOffset() const
- { return QPointF(0., pageNumber * control->document()->pageSize().height()); }
- inline void sendControlEvent(QEvent *e)
- { if (control) control->processEvent(e, controlOffset()); }
-
- void _q_updateBoundingRect(const QSizeF &);
- void _q_update(QRectF);
- void _q_ensureVisible(QRectF);
- bool _q_mouseOnEdge(QGraphicsSceneMouseEvent *);
-
- QRectF boundingRect;
- int pageNumber;
- bool useDefaultImpl;
- bool tabChangesFocus;
-
- uint clickCausedFocus : 1;
-
- QGraphicsTextItem *qq;
-};
-
-
-/*!
- Constructs a QGraphicsTextItem, using \a text as the default plain
- text. \a parent is passed to QGraphicsItem's constructor.
-
- \sa QGraphicsScene::addItem()
-*/
-QGraphicsTextItem::QGraphicsTextItem(const QString &text, QGraphicsItem *parent
-#ifndef Q_QDOC
- // obsolete argument
- , QGraphicsScene *scene
-#endif
- )
- : QGraphicsObject(*new QGraphicsItemPrivate, parent, scene), dd(new QGraphicsTextItemPrivate)
-{
- dd->qq = this;
- if (!text.isEmpty())
- setPlainText(text);
- setAcceptDrops(true);
- setAcceptHoverEvents(true);
- setFlags(ItemUsesExtendedStyleOption);
-}
-
-/*!
- Constructs a QGraphicsTextItem. \a parent is passed to QGraphicsItem's
- constructor.
-
- \sa QGraphicsScene::addItem()
-*/
-QGraphicsTextItem::QGraphicsTextItem(QGraphicsItem *parent
-#ifndef Q_QDOC
- // obsolete argument
- , QGraphicsScene *scene
-#endif
- )
- : QGraphicsObject(*new QGraphicsItemPrivate, parent, scene), dd(new QGraphicsTextItemPrivate)
-{
- dd->qq = this;
- setAcceptDrops(true);
- setAcceptHoverEvents(true);
- setFlag(ItemUsesExtendedStyleOption);
-}
-
-/*!
- Destroys the QGraphicsTextItem.
-*/
-QGraphicsTextItem::~QGraphicsTextItem()
-{
- delete dd;
-}
-
-/*!
- Returns the item's text converted to HTML, or an empty QString if no text has been set.
-
- \sa setHtml()
-*/
-QString QGraphicsTextItem::toHtml() const
-{
-#ifndef QT_NO_TEXTHTMLPARSER
- if (dd->control)
- return dd->control->toHtml();
-#endif
- return QString();
-}
-
-/*!
- Sets the item's text to \a text, assuming that text is HTML formatted. If
- the item has keyboard input focus, this function will also call
- ensureVisible() to ensure that the text is visible in all viewports.
-
- \sa toHtml(), hasFocus(), QGraphicsSimpleTextItem
-*/
-void QGraphicsTextItem::setHtml(const QString &text)
-{
- dd->textControl()->setHtml(text);
-}
-
-/*!
- Returns the item's text converted to plain text, or an empty QString if no text has been set.
-
- \sa setPlainText()
-*/
-QString QGraphicsTextItem::toPlainText() const
-{
- if (dd->control)
- return dd->control->toPlainText();
- return QString();
-}
-
-/*!
- Sets the item's text to \a text. If the item has keyboard input focus,
- this function will also call ensureVisible() to ensure that the text is
- visible in all viewports.
-
- \sa toHtml(), hasFocus()
-*/
-void QGraphicsTextItem::setPlainText(const QString &text)
-{
- dd->textControl()->setPlainText(text);
-}
-
-/*!
- Returns the item's font, which is used to render the text.
-
- \sa setFont()
-*/
-QFont QGraphicsTextItem::font() const
-{
- if (!dd->control)
- return QFont();
- return dd->control->document()->defaultFont();
-}
-
-/*!
- Sets the font used to render the text item to \a font.
-
- \sa font()
-*/
-void QGraphicsTextItem::setFont(const QFont &font)
-{
- dd->textControl()->document()->setDefaultFont(font);
-}
-
-/*!
- Sets the color for unformatted text to \a col.
-*/
-void QGraphicsTextItem::setDefaultTextColor(const QColor &col)
-{
- QTextControl *c = dd->textControl();
- QPalette pal = c->palette();
- QColor old = pal.color(QPalette::Text);
- pal.setColor(QPalette::Text, col);
- c->setPalette(pal);
- if (old != col)
- update();
-}
-
-/*!
- Returns the default text color that is used to for unformatted text.
-*/
-QColor QGraphicsTextItem::defaultTextColor() const
-{
- return dd->textControl()->palette().color(QPalette::Text);
-}
-
-/*!
- \reimp
-*/
-QRectF QGraphicsTextItem::boundingRect() const
-{
- return dd->boundingRect;
-}
-
-/*!
- \reimp
-*/
-QPainterPath QGraphicsTextItem::shape() const
-{
- if (!dd->control)
- return QPainterPath();
- QPainterPath path;
- path.addRect(dd->boundingRect);
- return path;
-}
-
-/*!
- \reimp
-*/
-bool QGraphicsTextItem::contains(const QPointF &point) const
-{
- return dd->boundingRect.contains(point);
-}
-
-/*!
- \reimp
-*/
-void QGraphicsTextItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
- QWidget *widget)
-{
- Q_UNUSED(widget);
- if (dd->control) {
- painter->save();
- QRectF r = option->exposedRect;
- painter->translate(-dd->controlOffset());
- r.translate(dd->controlOffset());
-
- QTextDocument *doc = dd->control->document();
- QTextDocumentLayout *layout = qobject_cast<QTextDocumentLayout *>(doc->documentLayout());
-
- // the layout might need to expand the root frame to
- // the viewport if NoWrap is set
- if (layout)
- layout->setViewport(dd->boundingRect);
-
- dd->control->drawContents(painter, r);
-
- if (layout)
- layout->setViewport(QRect());
-
- painter->restore();
- }
-
- if (option->state & (QStyle::State_Selected | QStyle::State_HasFocus))
- qt_graphicsItem_highlightSelected(this, painter, option);
-}
-
-/*!
- \reimp
-*/
-bool QGraphicsTextItem::isObscuredBy(const QGraphicsItem *item) const
-{
- return QGraphicsItem::isObscuredBy(item);
-}
-
-/*!
- \reimp
-*/
-QPainterPath QGraphicsTextItem::opaqueArea() const
-{
- return QGraphicsItem::opaqueArea();
-}
-
-/*!
- \reimp
-*/
-int QGraphicsTextItem::type() const
-{
- return Type;
-}
-
-/*!
- Sets the preferred width for the item's text. If the actual text
- is wider than the specified width then it will be broken into
- multiple lines.
-
- If \a width is set to -1 then the text will not be broken into
- multiple lines unless it is enforced through an explicit line
- break or a new paragraph.
-
- The default value is -1.
-
- Note that QGraphicsTextItem keeps a QTextDocument internally,
- which is used to calculate the text width.
-
- \sa textWidth(), QTextDocument::setTextWidth()
-*/
-void QGraphicsTextItem::setTextWidth(qreal width)
-{
- dd->textControl()->setTextWidth(width);
-}
-
-/*!
- Returns the text width.
-
- The width is calculated with the QTextDocument that
- QGraphicsTextItem keeps internally.
-
- \sa setTextWidth(), QTextDocument::textWidth()
-*/
-qreal QGraphicsTextItem::textWidth() const
-{
- if (!dd->control)
- return -1;
- return dd->control->textWidth();
-}
-
-/*!
- Adjusts the text item to a reasonable size.
-*/
-void QGraphicsTextItem::adjustSize()
-{
- if (dd->control)
- dd->control->adjustSize();
-}
-
-/*!
- Sets the text document \a document on the item.
-*/
-void QGraphicsTextItem::setDocument(QTextDocument *document)
-{
- dd->textControl()->setDocument(document);
- dd->_q_updateBoundingRect(dd->control->size());
-}
-
-/*!
- Returns the item's text document.
-*/
-QTextDocument *QGraphicsTextItem::document() const
-{
- return dd->textControl()->document();
-}
-
-/*!
- \reimp
-*/
-bool QGraphicsTextItem::sceneEvent(QEvent *event)
-{
- QEvent::Type t = event->type();
- if (!dd->tabChangesFocus && (t == QEvent::KeyPress || t == QEvent::KeyRelease)) {
- int k = ((QKeyEvent *)event)->key();
- if (k == Qt::Key_Tab || k == Qt::Key_Backtab) {
- dd->sendControlEvent(event);
- return true;
- }
- }
- bool result = QGraphicsItem::sceneEvent(event);
-
- // Ensure input context is updated.
- switch (event->type()) {
- case QEvent::ContextMenu:
- case QEvent::FocusIn:
- case QEvent::FocusOut:
- case QEvent::GraphicsSceneDragEnter:
- case QEvent::GraphicsSceneDragLeave:
- case QEvent::GraphicsSceneDragMove:
- case QEvent::GraphicsSceneDrop:
- case QEvent::GraphicsSceneHoverEnter:
- case QEvent::GraphicsSceneHoverLeave:
- case QEvent::GraphicsSceneHoverMove:
- case QEvent::GraphicsSceneMouseDoubleClick:
- case QEvent::GraphicsSceneMousePress:
- case QEvent::GraphicsSceneMouseMove:
- case QEvent::GraphicsSceneMouseRelease:
- case QEvent::KeyPress:
- case QEvent::KeyRelease:
- // Reset the focus widget's input context, regardless
- // of how this item gained or lost focus.
- if (QWidget *fw = qApp->focusWidget()) {
-#ifndef QT_NO_IM
- if (QInputContext *qic = fw->inputContext()) {
- if (event->type() == QEvent::FocusIn || event->type() == QEvent::FocusOut)
- qic->reset();
- else
- qic->update();
- }
-#endif //QT_NO_IM
- }
- break;
- case QEvent::ShortcutOverride:
- dd->sendControlEvent(event);
- return true;
- default:
- break;
- }
-
- return result;
-}
-
-/*!
- \reimp
-*/
-void QGraphicsTextItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
-{
- if ((QGraphicsItem::d_ptr->flags & (ItemIsSelectable | ItemIsMovable))
- && (event->buttons() & Qt::LeftButton) && dd->_q_mouseOnEdge(event)) {
- // User left-pressed on edge of selectable/movable item, use
- // base impl.
- dd->useDefaultImpl = true;
- } else if (event->buttons() == event->button()
- && dd->control->textInteractionFlags() == Qt::NoTextInteraction) {
- // User pressed first button on non-interactive item.
- dd->useDefaultImpl = true;
- }
- if (dd->useDefaultImpl) {
- QGraphicsItem::mousePressEvent(event);
- if (!event->isAccepted())
- dd->useDefaultImpl = false;
- return;
- }
-
- dd->sendControlEvent(event);
-}
-
-/*!
- \reimp
-*/
-void QGraphicsTextItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
-{
- if (dd->useDefaultImpl) {
- QGraphicsItem::mouseMoveEvent(event);
- return;
- }
-
- dd->sendControlEvent(event);
-}
-
-/*!
- \reimp
-*/
-void QGraphicsTextItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
-{
- if (dd->useDefaultImpl) {
- QGraphicsItem::mouseReleaseEvent(event);
- if (dd->control->textInteractionFlags() == Qt::NoTextInteraction
- && !event->buttons()) {
- // User released last button on non-interactive item.
- dd->useDefaultImpl = false;
- } else if ((event->buttons() & Qt::LeftButton) == 0) {
- // User released the left button on an interactive item.
- dd->useDefaultImpl = false;
- }
- return;
- }
-
- QWidget *widget = event->widget();
- if (widget && (dd->control->textInteractionFlags() & Qt::TextEditable) && boundingRect().contains(event->pos())) {
- qt_widget_private(widget)->handleSoftwareInputPanel(event->button(), dd->clickCausedFocus);
- }
- dd->clickCausedFocus = 0;
- dd->sendControlEvent(event);
-}
-
-/*!
- \reimp
-*/
-void QGraphicsTextItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
-{
- if (dd->useDefaultImpl) {
- QGraphicsItem::mouseDoubleClickEvent(event);
- return;
- }
-
- if (!hasFocus()) {
- QGraphicsItem::mouseDoubleClickEvent(event);
- return;
- }
-
- dd->sendControlEvent(event);
-}
-
-/*!
- \reimp
-*/
-void QGraphicsTextItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
-{
- dd->sendControlEvent(event);
-}
-
-/*!
- \reimp
-*/
-void QGraphicsTextItem::keyPressEvent(QKeyEvent *event)
-{
- dd->sendControlEvent(event);
-}
-
-/*!
- \reimp
-*/
-void QGraphicsTextItem::keyReleaseEvent(QKeyEvent *event)
-{
- dd->sendControlEvent(event);
-}
-
-/*!
- \reimp
-*/
-void QGraphicsTextItem::focusInEvent(QFocusEvent *event)
-{
- dd->sendControlEvent(event);
- if (event->reason() == Qt::MouseFocusReason) {
- dd->clickCausedFocus = 1;
- }
- update();
-}
-
-/*!
- \reimp
-*/
-void QGraphicsTextItem::focusOutEvent(QFocusEvent *event)
-{
- dd->sendControlEvent(event);
- update();
-}
-
-/*!
- \reimp
-*/
-void QGraphicsTextItem::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
-{
- dd->sendControlEvent(event);
-}
-
-/*!
- \reimp
-*/
-void QGraphicsTextItem::dragLeaveEvent(QGraphicsSceneDragDropEvent *event)
-{
- dd->sendControlEvent(event);
-}
-
-/*!
- \reimp
-*/
-void QGraphicsTextItem::dragMoveEvent(QGraphicsSceneDragDropEvent *event)
-{
- dd->sendControlEvent(event);
-}
-
-/*!
- \reimp
-*/
-void QGraphicsTextItem::dropEvent(QGraphicsSceneDragDropEvent *event)
-{
- dd->sendControlEvent(event);
-}
-
-/*!
- \reimp
-*/
-void QGraphicsTextItem::inputMethodEvent(QInputMethodEvent *event)
-{
- dd->sendControlEvent(event);
-}
-
-/*!
- \reimp
-*/
-void QGraphicsTextItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
-{
- dd->sendControlEvent(event);
-}
-
-/*!
- \reimp
-*/
-void QGraphicsTextItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
-{
- dd->sendControlEvent(event);
-}
-
-/*!
- \reimp
-*/
-void QGraphicsTextItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
-{
- dd->sendControlEvent(event);
-}
-
-/*!
- \reimp
-*/
-QVariant QGraphicsTextItem::inputMethodQuery(Qt::InputMethodQuery query) const
-{
- QVariant v;
- if (dd->control)
- v = dd->control->inputMethodQuery(query);
- if (v.type() == QVariant::RectF)
- v = v.toRectF().translated(-dd->controlOffset());
- else if (v.type() == QVariant::PointF)
- v = v.toPointF() - dd->controlOffset();
- else if (v.type() == QVariant::Rect)
- v = v.toRect().translated(-dd->controlOffset().toPoint());
- else if (v.type() == QVariant::Point)
- v = v.toPoint() - dd->controlOffset().toPoint();
- return v;
-}
-
-/*!
- \internal
-*/
-bool QGraphicsTextItem::supportsExtension(Extension extension) const
-{
- Q_UNUSED(extension);
- return false;
-}
-
-/*!
- \internal
-*/
-void QGraphicsTextItem::setExtension(Extension extension, const QVariant &variant)
-{
- Q_UNUSED(extension);
- Q_UNUSED(variant);
-}
-
-/*!
- \internal
-*/
-QVariant QGraphicsTextItem::extension(const QVariant &variant) const
-{
- Q_UNUSED(variant);
- return QVariant();
-}
-
-/*!
- \internal
-*/
-void QGraphicsTextItemPrivate::_q_update(QRectF rect)
-{
- if (rect.isValid()) {
- rect.translate(-controlOffset());
- } else {
- rect = boundingRect;
- }
- if (rect.intersects(boundingRect))
- qq->update(rect);
-}
-
-/*!
- \internal
-*/
-void QGraphicsTextItemPrivate::_q_updateBoundingRect(const QSizeF &size)
-{
- if (!control) return; // can't happen
- const QSizeF pageSize = control->document()->pageSize();
- // paged items have a constant (page) size
- if (size == boundingRect.size() || pageSize.height() != -1)
- return;
- qq->prepareGeometryChange();
- boundingRect.setSize(size);
- qq->update();
-}
-
-/*!
- \internal
-*/
-void QGraphicsTextItemPrivate::_q_ensureVisible(QRectF rect)
-{
- if (qq->hasFocus()) {
- rect.translate(-controlOffset());
- qq->ensureVisible(rect, /*xmargin=*/0, /*ymargin=*/0);
- }
-}
-
-QTextControl *QGraphicsTextItemPrivate::textControl() const
-{
- if (!control) {
- QGraphicsTextItem *that = const_cast<QGraphicsTextItem *>(qq);
- control = new QTextControl(that);
- control->setTextInteractionFlags(Qt::NoTextInteraction);
-
- QObject::connect(control, SIGNAL(updateRequest(QRectF)),
- qq, SLOT(_q_update(QRectF)));
- QObject::connect(control, SIGNAL(documentSizeChanged(QSizeF)),
- qq, SLOT(_q_updateBoundingRect(QSizeF)));
- QObject::connect(control, SIGNAL(visibilityRequest(QRectF)),
- qq, SLOT(_q_ensureVisible(QRectF)));
- QObject::connect(control, SIGNAL(linkActivated(QString)),
- qq, SIGNAL(linkActivated(QString)));
- QObject::connect(control, SIGNAL(linkHovered(QString)),
- qq, SIGNAL(linkHovered(QString)));
-
- const QSizeF pgSize = control->document()->pageSize();
- if (pgSize.height() != -1) {
- qq->prepareGeometryChange();
- that->dd->boundingRect.setSize(pgSize);
- qq->update();
- } else {
- that->dd->_q_updateBoundingRect(control->size());
- }
- }
- return control;
-}
-
-/*!
- \internal
-*/
-bool QGraphicsTextItemPrivate::_q_mouseOnEdge(QGraphicsSceneMouseEvent *event)
-{
- QPainterPath path;
- path.addRect(qq->boundingRect());
-
- QPainterPath docPath;
- const QTextFrameFormat format = control->document()->rootFrame()->frameFormat();
- docPath.addRect(
- qq->boundingRect().adjusted(
- format.leftMargin(),
- format.topMargin(),
- -format.rightMargin(),
- -format.bottomMargin()));
-
- return path.subtracted(docPath).contains(event->pos());
-}
-
-/*!
- \fn QGraphicsTextItem::linkActivated(const QString &link)
-
- This signal is emitted when the user clicks on a link on a text item
- that enables Qt::LinksAccessibleByMouse or Qt::LinksAccessibleByKeyboard.
- \a link is the link that was clicked.
-
- \sa setTextInteractionFlags()
-*/
-
-/*!
- \fn QGraphicsTextItem::linkHovered(const QString &link)
-
- This signal is emitted when the user hovers over a link on a text item
- that enables Qt::LinksAccessibleByMouse. \a link is
- the link that was hovered over.
-
- \sa setTextInteractionFlags()
-*/
-
-/*!
- Sets the flags \a flags to specify how the text item should react to user
- input.
-
- The default for a QGraphicsTextItem is Qt::NoTextInteraction. This function
- also affects the ItemIsFocusable QGraphicsItem flag by setting it if \a flags
- is different from Qt::NoTextInteraction and clearing it otherwise.
-
- By default, the text is read-only. To transform the item into an editor,
- set the Qt::TextEditable flag.
-*/
-void QGraphicsTextItem::setTextInteractionFlags(Qt::TextInteractionFlags flags)
-{
- if (flags == Qt::NoTextInteraction)
- setFlags(this->flags() & ~(QGraphicsItem::ItemIsFocusable | QGraphicsItem::ItemAcceptsInputMethod));
- else
- setFlags(this->flags() | QGraphicsItem::ItemIsFocusable | QGraphicsItem::ItemAcceptsInputMethod);
-
- dd->textControl()->setTextInteractionFlags(flags);
-}
-
-/*!
- Returns the current text interaction flags.
-
- \sa setTextInteractionFlags()
-*/
-Qt::TextInteractionFlags QGraphicsTextItem::textInteractionFlags() const
-{
- if (!dd->control)
- return Qt::NoTextInteraction;
- return dd->control->textInteractionFlags();
-}
-
-/*!
- \since 4.5
-
- If \a b is true, the \gui Tab key will cause the widget to change focus;
- otherwise, the tab key will insert a tab into the document.
-
- In some occasions text edits should not allow the user to input tabulators
- or change indentation using the \gui Tab key, as this breaks the focus
- chain. The default is false.
-
- \sa tabChangesFocus(), ItemIsFocusable, textInteractionFlags()
-*/
-void QGraphicsTextItem::setTabChangesFocus(bool b)
-{
- dd->tabChangesFocus = b;
-}
-
-/*!
- \since 4.5
-
- 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
-{
- return dd->tabChangesFocus;
-}
-
-/*!
- \property QGraphicsTextItem::openExternalLinks
-
- Specifies whether QGraphicsTextItem should automatically open links using
- QDesktopServices::openUrl() instead of emitting the
- linkActivated signal.
-
- The default value is false.
-*/
-void QGraphicsTextItem::setOpenExternalLinks(bool open)
-{
- dd->textControl()->setOpenExternalLinks(open);
-}
-
-bool QGraphicsTextItem::openExternalLinks() const
-{
- if (!dd->control)
- return false;
- return dd->control->openExternalLinks();
-}
-
-/*!
- \property QGraphicsTextItem::textCursor
-
- This property represents the visible text cursor in an editable
- text item.
-
- By default, if the item's text has not been set, this property
- contains a null text cursor; otherwise it contains a text cursor
- placed at the start of the item's document.
-*/
-void QGraphicsTextItem::setTextCursor(const QTextCursor &cursor)
-{
- dd->textControl()->setTextCursor(cursor);
-}
-
-QTextCursor QGraphicsTextItem::textCursor() const
-{
- if (!dd->control)
- return QTextCursor();
- return dd->control->textCursor();
-}
-
-class QGraphicsSimpleTextItemPrivate : public QAbstractGraphicsShapeItemPrivate
-{
- Q_DECLARE_PUBLIC(QGraphicsSimpleTextItem)
-public:
- inline QGraphicsSimpleTextItemPrivate() {
- pen.setStyle(Qt::NoPen);
- brush.setStyle(Qt::SolidPattern);
- }
- QString text;
- QFont font;
- QRectF boundingRect;
-
- void updateBoundingRect();
-};
-
-static QRectF setupTextLayout(QTextLayout *layout)
-{
- layout->setCacheEnabled(true);
- layout->beginLayout();
- while (layout->createLine().isValid())
- ;
- layout->endLayout();
- qreal maxWidth = 0;
- qreal y = 0;
- for (int i = 0; i < layout->lineCount(); ++i) {
- QTextLine line = layout->lineAt(i);
- maxWidth = qMax(maxWidth, line.naturalTextWidth());
- line.setPosition(QPointF(0, y));
- y += line.height();
- }
- return QRectF(0, 0, maxWidth, y);
-}
-
-void QGraphicsSimpleTextItemPrivate::updateBoundingRect()
-{
- Q_Q(QGraphicsSimpleTextItem);
- QRectF br;
- if (text.isEmpty()) {
- br = QRectF();
- } else {
- QString tmp = text;
- tmp.replace(QLatin1Char('\n'), QChar::LineSeparator);
- QStackTextEngine engine(tmp, font);
- QTextLayout layout(&engine);
- br = setupTextLayout(&layout);
- }
- if (br != boundingRect) {
- q->prepareGeometryChange();
- boundingRect = br;
- q->update();
- }
-}
-
-/*!
- \class QGraphicsSimpleTextItem
- \brief The QGraphicsSimpleTextItem class provides a simple text path item
- that you can add to a QGraphicsScene.
- \since 4.2
- \ingroup graphicsview-api
-
- To set the item's text, you can either pass a QString to
- QGraphicsSimpleTextItem's constructor, or call setText() to change the
- text later. To set the text fill color, call setBrush().
-
- The simple text item can have both a fill and an outline; setBrush() will
- set the text fill (i.e., text color), and setPen() sets the pen that will
- be used to draw the text outline. (The latter can be slow, especially for
- complex pens, and items with long text content.) If all you want is to
- draw a simple line of text, you should call setBrush() only, and leave the
- pen unset; QGraphicsSimpleTextItem's pen is by default Qt::NoPen.
-
- QGraphicsSimpleTextItem uses the text's formatted size and the associated
- font to provide a reasonable implementation of boundingRect(), shape(),
- and contains(). You can set the font by calling setFont().
-
- QGraphicsSimpleText does not display rich text; instead, you can use
- QGraphicsTextItem, which provides full text control capabilities.
-
- \img graphicsview-simpletextitem.png
-
- \sa QGraphicsTextItem, QGraphicsPathItem, QGraphicsRectItem,
- QGraphicsEllipseItem, QGraphicsPixmapItem, QGraphicsPolygonItem,
- QGraphicsLineItem, {Graphics View Framework}
-*/
-
-/*!
- Constructs a QGraphicsSimpleTextItem.
-
- \a parent is passed to QGraphicsItem's constructor.
-
- \sa QGraphicsScene::addItem()
-*/
-QGraphicsSimpleTextItem::QGraphicsSimpleTextItem(QGraphicsItem *parent
-#ifndef Q_QDOC
- // obsolete argument
- , QGraphicsScene *scene
-#endif
- )
- : QAbstractGraphicsShapeItem(*new QGraphicsSimpleTextItemPrivate, parent, scene)
-{
-}
-
-/*!
- Constructs a QGraphicsSimpleTextItem, using \a text as the default plain text.
-
- \a parent is passed to QGraphicsItem's constructor.
-
- \sa QGraphicsScene::addItem()
-*/
-QGraphicsSimpleTextItem::QGraphicsSimpleTextItem(const QString &text, QGraphicsItem *parent
-#ifndef Q_QDOC
- // obsolete argument
- , QGraphicsScene *scene
-#endif
- )
- : QAbstractGraphicsShapeItem(*new QGraphicsSimpleTextItemPrivate, parent, scene)
-{
- setText(text);
-}
-
-/*!
- Destroys the QGraphicsSimpleTextItem.
-*/
-QGraphicsSimpleTextItem::~QGraphicsSimpleTextItem()
-{
-}
-
-/*!
- Sets the item's text to \a text. The text will be displayed as
- plain text. Newline characters ('\n') as well as characters of
- type QChar::LineSeparator will cause item to break the text into
- multiple lines.
-*/
-void QGraphicsSimpleTextItem::setText(const QString &text)
-{
- Q_D(QGraphicsSimpleTextItem);
- if (d->text == text)
- return;
- d->text = text;
- d->updateBoundingRect();
- update();
-}
-
-/*!
- Returns the item's text.
-*/
-QString QGraphicsSimpleTextItem::text() const
-{
- Q_D(const QGraphicsSimpleTextItem);
- return d->text;
-}
-
-/*!
- Sets the font that is used to draw the item's text to \a font.
-*/
-void QGraphicsSimpleTextItem::setFont(const QFont &font)
-{
- Q_D(QGraphicsSimpleTextItem);
- d->font = font;
- d->updateBoundingRect();
-}
-
-/*!
- Returns the font that is used to draw the item's text.
-*/
-QFont QGraphicsSimpleTextItem::font() const
-{
- Q_D(const QGraphicsSimpleTextItem);
- return d->font;
-}
-
-/*!
- \reimp
-*/
-QRectF QGraphicsSimpleTextItem::boundingRect() const
-{
- Q_D(const QGraphicsSimpleTextItem);
- return d->boundingRect;
-}
-
-/*!
- \reimp
-*/
-QPainterPath QGraphicsSimpleTextItem::shape() const
-{
- Q_D(const QGraphicsSimpleTextItem);
- QPainterPath path;
- path.addRect(d->boundingRect);
- return path;
-}
-
-/*!
- \reimp
-*/
-bool QGraphicsSimpleTextItem::contains(const QPointF &point) const
-{
- Q_D(const QGraphicsSimpleTextItem);
- return d->boundingRect.contains(point);
-}
-
-/*!
- \reimp
-*/
-void QGraphicsSimpleTextItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
-{
- Q_UNUSED(widget);
- Q_D(QGraphicsSimpleTextItem);
-
- painter->setFont(d->font);
-
- QString tmp = d->text;
- tmp.replace(QLatin1Char('\n'), QChar::LineSeparator);
- QStackTextEngine engine(tmp, d->font);
- QTextLayout layout(&engine);
- setupTextLayout(&layout);
-
- QPen p;
- p.setBrush(d->brush);
- painter->setPen(p);
- if (d->pen.style() == Qt::NoPen && d->brush.style() == Qt::SolidPattern) {
- painter->setBrush(Qt::NoBrush);
- } else {
- QTextLayout::FormatRange range;
- range.start = 0;
- range.length = layout.text().length();
- range.format.setTextOutline(d->pen);
- QList<QTextLayout::FormatRange> formats;
- formats.append(range);
- layout.setAdditionalFormats(formats);
- }
-
- layout.draw(painter, QPointF(0, 0));
-
- if (option->state & (QStyle::State_Selected | QStyle::State_HasFocus))
- qt_graphicsItem_highlightSelected(this, painter, option);
-}
-
-/*!
- \reimp
-*/
-bool QGraphicsSimpleTextItem::isObscuredBy(const QGraphicsItem *item) const
-{
- return QAbstractGraphicsShapeItem::isObscuredBy(item);
-}
-
-/*!
- \reimp
-*/
-QPainterPath QGraphicsSimpleTextItem::opaqueArea() const
-{
- return QAbstractGraphicsShapeItem::opaqueArea();
-}
-
-/*!
- \reimp
-*/
-int QGraphicsSimpleTextItem::type() const
-{
- return Type;
-}
-
-/*!
- \internal
-*/
-bool QGraphicsSimpleTextItem::supportsExtension(Extension extension) const
-{
- Q_UNUSED(extension);
- return false;
-}
-
-/*!
- \internal
-*/
-void QGraphicsSimpleTextItem::setExtension(Extension extension, const QVariant &variant)
-{
- Q_UNUSED(extension);
- Q_UNUSED(variant);
-}
-
-/*!
- \internal
-*/
-QVariant QGraphicsSimpleTextItem::extension(const QVariant &variant) const
-{
- Q_UNUSED(variant);
- return QVariant();
-}
-
-/*!
- \class QGraphicsItemGroup
- \brief The QGraphicsItemGroup class provides a container that treats
- a group of items as a single item.
- \since 4.2
- \ingroup graphicsview-api
-
- A QGraphicsItemGroup is a special type of compound item that
- treats itself and all its children as one item (i.e., all events
- and geometries for all children are merged together). It's common
- to use item groups in presentation tools, when the user wants to
- group several smaller items into one big item in order to simplify
- moving and copying of items.
-
- If all you want is to store items inside other items, you can use
- any QGraphicsItem directly by passing a suitable parent to
- setParentItem().
-
- The boundingRect() function of QGraphicsItemGroup returns the
- bounding rectangle of all items in the item group.
- QGraphicsItemGroup ignores the ItemIgnoresTransformations flag on
- its children (i.e., with respect to the geometry of the group
- item, the children are treated as if they were transformable).
-
- There are two ways to construct an item group. The easiest and
- most common approach is to pass a list of items (e.g., all
- selected items) to QGraphicsScene::createItemGroup(), which
- returns a new QGraphicsItemGroup item. The other approach is to
- manually construct a QGraphicsItemGroup item, add it to the scene
- calling QGraphicsScene::addItem(), and then add items to the group
- manually, one at a time by calling addToGroup(). To dismantle
- ("ungroup") an item group, you can either call
- QGraphicsScene::destroyItemGroup(), or you can manually remove all
- items from the group by calling removeFromGroup().
-
- \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 17
-
- The operation of adding and removing items preserves the items'
- scene-relative position and transformation, as opposed to calling
- setParentItem(), where only the child item's parent-relative
- position and transformation are kept.
-
- The addtoGroup() function reparents the target item to this item
- group, keeping the item's position and transformation intact
- relative to the scene. Visually, this means that items added via
- addToGroup() will remain completely unchanged as a result of this
- operation, regardless of the item or the group's current position
- or transformation; although the item's position and matrix are
- likely to change.
-
- The removeFromGroup() function has similar semantics to
- setParentItem(); it reparents the item to the parent item of the
- item group. As with addToGroup(), the item's scene-relative
- position and transformation remain intact.
-
- \sa QGraphicsItem, {Graphics View Framework}
-*/
-
-class QGraphicsItemGroupPrivate : public QGraphicsItemPrivate
-{
-public:
- QRectF itemsBoundingRect;
-};
-
-/*!
- Constructs a QGraphicsItemGroup. \a parent is passed to QGraphicsItem's
- constructor.
-
- \sa QGraphicsScene::addItem()
-*/
-QGraphicsItemGroup::QGraphicsItemGroup(QGraphicsItem *parent
-#ifndef Q_QDOC
- // obsolete argument
- , QGraphicsScene *scene
-#endif
- )
- : QGraphicsItem(*new QGraphicsItemGroupPrivate, parent, scene)
-{
- setHandlesChildEvents(true);
-}
-
-/*!
- Destroys the QGraphicsItemGroup.
-*/
-QGraphicsItemGroup::~QGraphicsItemGroup()
-{
-}
-
-/*!
- Adds the given \a item to this item group. The item will be
- reparented to this group, but its position and transformation
- relative to the scene will stay intact.
-
- \sa removeFromGroup(), QGraphicsScene::createItemGroup()
-*/
-void QGraphicsItemGroup::addToGroup(QGraphicsItem *item)
-{
- Q_D(QGraphicsItemGroup);
- if (!item) {
- qWarning("QGraphicsItemGroup::addToGroup: cannot add null item");
- return;
- }
- if (item == this) {
- qWarning("QGraphicsItemGroup::addToGroup: cannot add a group to itself");
- return;
- }
-
- // COMBINE
- bool ok;
- QTransform itemTransform = item->itemTransform(this, &ok);
-
- if (!ok) {
- qWarning("QGraphicsItemGroup::addToGroup: could not find a valid transformation from item to group coordinates");
- return;
- }
-
- QTransform newItemTransform(itemTransform);
- item->setPos(mapFromItem(item, 0, 0));
- item->setParentItem(this);
-
- // removing position from translation component of the new transform
- if (!item->pos().isNull())
- newItemTransform *= QTransform::fromTranslate(-item->x(), -item->y());
-
- // removing additional transformations properties applied with itemTransform()
- QPointF origin = item->transformOriginPoint();
- QMatrix4x4 m;
- QList<QGraphicsTransform*> transformList = item->transformations();
- for (int i = 0; i < transformList.size(); ++i)
- transformList.at(i)->applyTo(&m);
- newItemTransform *= m.toTransform().inverted();
- newItemTransform.translate(origin.x(), origin.y());
- newItemTransform.rotate(-item->rotation());
- newItemTransform.scale(1/item->scale(), 1/item->scale());
- newItemTransform.translate(-origin.x(), -origin.y());
-
- // ### Expensive, we could maybe use dirtySceneTransform bit for optimization
-
- item->setTransform(newItemTransform);
- item->d_func()->setIsMemberOfGroup(true);
- prepareGeometryChange();
- d->itemsBoundingRect |= itemTransform.mapRect(item->boundingRect() | item->childrenBoundingRect());
- update();
-}
-
-/*!
- Removes the specified \a item from this group. The item will be
- reparented to this group's parent item, or to 0 if this group has
- no parent. Its position and transformation relative to the scene
- will stay intact.
-
- \sa addToGroup(), QGraphicsScene::destroyItemGroup()
-*/
-void QGraphicsItemGroup::removeFromGroup(QGraphicsItem *item)
-{
- Q_D(QGraphicsItemGroup);
- if (!item) {
- qWarning("QGraphicsItemGroup::removeFromGroup: cannot remove null item");
- return;
- }
-
- QGraphicsItem *newParent = d_ptr->parent;
-
- // COMBINE
- bool ok;
- QTransform itemTransform;
- if (newParent)
- itemTransform = item->itemTransform(newParent, &ok);
- else
- itemTransform = item->sceneTransform();
-
- QPointF oldPos = item->mapToItem(newParent, 0, 0);
- item->setParentItem(newParent);
- item->setPos(oldPos);
-
- // removing position from translation component of the new transform
- if (!item->pos().isNull())
- itemTransform *= QTransform::fromTranslate(-item->x(), -item->y());
-
- // removing additional transformations properties applied
- // with itemTransform() or sceneTransform()
- QPointF origin = item->transformOriginPoint();
- QMatrix4x4 m;
- QList<QGraphicsTransform*> transformList = item->transformations();
- for (int i = 0; i < transformList.size(); ++i)
- transformList.at(i)->applyTo(&m);
- itemTransform *= m.toTransform().inverted();
- itemTransform.translate(origin.x(), origin.y());
- itemTransform.rotate(-item->rotation());
- itemTransform.scale(1 / item->scale(), 1 / item->scale());
- itemTransform.translate(-origin.x(), -origin.y());
-
- // ### Expensive, we could maybe use dirtySceneTransform bit for optimization
-
- item->setTransform(itemTransform);
- item->d_func()->setIsMemberOfGroup(item->group() != 0);
-
- // ### Quite expensive. But removeFromGroup() isn't called very often.
- prepareGeometryChange();
- d->itemsBoundingRect = childrenBoundingRect();
-}
-
-/*!
- \reimp
-
- Returns the bounding rect of this group item, and all its children.
-*/
-QRectF QGraphicsItemGroup::boundingRect() const
-{
- Q_D(const QGraphicsItemGroup);
- return d->itemsBoundingRect;
-}
-
-/*!
- \reimp
-*/
-void QGraphicsItemGroup::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
- QWidget *widget)
-{
- Q_UNUSED(widget);
- if (option->state & QStyle::State_Selected) {
- Q_D(QGraphicsItemGroup);
- painter->setBrush(Qt::NoBrush);
- painter->drawRect(d->itemsBoundingRect);
- }
-}
-
-/*!
- \reimp
-*/
-bool QGraphicsItemGroup::isObscuredBy(const QGraphicsItem *item) const
-{
- return QGraphicsItem::isObscuredBy(item);
-}
-
-/*!
- \reimp
-*/
-QPainterPath QGraphicsItemGroup::opaqueArea() const
-{
- return QGraphicsItem::opaqueArea();
-}
-
-/*!
- \reimp
-*/
-int QGraphicsItemGroup::type() const
-{
- return Type;
-}
-
-#ifndef QT_NO_GRAPHICSEFFECT
-QRectF QGraphicsItemEffectSourcePrivate::boundingRect(Qt::CoordinateSystem system) const
-{
- const bool deviceCoordinates = (system == Qt::DeviceCoordinates);
- if (!info && deviceCoordinates) {
- // Device coordinates without info not yet supported.
- qWarning("QGraphicsEffectSource::boundingRect: Not yet implemented, lacking device context");
- return QRectF();
- }
-
- QRectF rect = item->boundingRect();
- if (!item->d_ptr->children.isEmpty())
- rect |= item->childrenBoundingRect();
-
- if (deviceCoordinates) {
- Q_ASSERT(info->painter);
- rect = info->painter->worldTransform().mapRect(rect);
- }
-
- return rect;
-}
-
-void QGraphicsItemEffectSourcePrivate::draw(QPainter *painter)
-{
- if (!info) {
- qWarning("QGraphicsEffectSource::draw: Can only begin as a result of QGraphicsEffect::draw");
- return;
- }
-
- Q_ASSERT(item->d_ptr->scene);
- QGraphicsScenePrivate *scened = item->d_ptr->scene->d_func();
- if (painter == info->painter) {
- scened->draw(item, painter, info->viewTransform, info->transformPtr, info->exposedRegion,
- info->widget, info->opacity, info->effectTransform, info->wasDirtySceneTransform,
- info->drawItem);
- } else {
- QTransform effectTransform = info->painter->worldTransform().inverted();
- effectTransform *= painter->worldTransform();
- scened->draw(item, painter, info->viewTransform, info->transformPtr, info->exposedRegion,
- info->widget, info->opacity, &effectTransform, info->wasDirtySceneTransform,
- info->drawItem);
- }
-}
-
-// sourceRect must be in the given coordinate system
-QRect QGraphicsItemEffectSourcePrivate::paddedEffectRect(Qt::CoordinateSystem system, QGraphicsEffect::PixmapPadMode mode, const QRectF &sourceRect, bool *unpadded) const
-{
- QRectF effectRectF;
-
- if (unpadded)
- *unpadded = false;
-
- if (mode == QGraphicsEffect::PadToEffectiveBoundingRect) {
- if (info) {
- QRectF deviceRect = system == Qt::DeviceCoordinates ? sourceRect : info->painter->worldTransform().mapRect(sourceRect);
- effectRectF = item->graphicsEffect()->boundingRectFor(deviceRect);
- if (unpadded)
- *unpadded = (effectRectF.size() == sourceRect.size());
- if (info && system == Qt::LogicalCoordinates)
- effectRectF = info->painter->worldTransform().inverted().mapRect(effectRectF);
- } else {
- // no choice but to send a logical coordinate bounding rect to boundingRectFor
- effectRectF = item->graphicsEffect()->boundingRectFor(sourceRect);
- }
- } else if (mode == QGraphicsEffect::PadToTransparentBorder) {
- // adjust by 1.5 to account for cosmetic pens
- effectRectF = sourceRect.adjusted(-1.5, -1.5, 1.5, 1.5);
- } else {
- effectRectF = sourceRect;
- if (unpadded)
- *unpadded = true;
- }
-
- return effectRectF.toAlignedRect();
-}
-
-QPixmap QGraphicsItemEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QPoint *offset,
- QGraphicsEffect::PixmapPadMode mode) const
-{
- const bool deviceCoordinates = (system == Qt::DeviceCoordinates);
- if (!info && deviceCoordinates) {
- // Device coordinates without info not yet supported.
- qWarning("QGraphicsEffectSource::pixmap: Not yet implemented, lacking device context");
- return QPixmap();
- }
- if (!item->d_ptr->scene)
- return QPixmap();
- QGraphicsScenePrivate *scened = item->d_ptr->scene->d_func();
-
- bool unpadded;
- const QRectF sourceRect = boundingRect(system);
- QRect effectRect = paddedEffectRect(system, mode, sourceRect, &unpadded);
-
- if (offset)
- *offset = effectRect.topLeft();
-
- bool untransformed = !deviceCoordinates
- || info->painter->worldTransform().type() <= QTransform::TxTranslate;
- if (untransformed && unpadded && isPixmap()) {
- if (offset)
- *offset = boundingRect(system).topLeft().toPoint();
- return static_cast<QGraphicsPixmapItem *>(item)->pixmap();
- }
-
- if (effectRect.isEmpty())
- return QPixmap();
-
- QPixmap pixmap(effectRect.size());
- pixmap.fill(Qt::transparent);
- QPainter pixmapPainter(&pixmap);
- pixmapPainter.setRenderHints(info ? info->painter->renderHints() : QPainter::TextAntialiasing);
-
- QTransform effectTransform = QTransform::fromTranslate(-effectRect.x(), -effectRect.y());
- if (deviceCoordinates && info->effectTransform)
- effectTransform *= *info->effectTransform;
-
- if (!info) {
- // Logical coordinates without info.
- QTransform sceneTransform = item->sceneTransform();
- QTransform newEffectTransform = sceneTransform.inverted();
- newEffectTransform *= effectTransform;
- scened->draw(item, &pixmapPainter, 0, &sceneTransform, 0, 0, qreal(1.0),
- &newEffectTransform, false, true);
- } else if (deviceCoordinates) {
- // Device coordinates with info.
- scened->draw(item, &pixmapPainter, info->viewTransform, info->transformPtr, 0,
- info->widget, info->opacity, &effectTransform, info->wasDirtySceneTransform,
- info->drawItem);
- } else {
- // Item coordinates with info.
- QTransform newEffectTransform = info->transformPtr->inverted();
- newEffectTransform *= effectTransform;
- scened->draw(item, &pixmapPainter, info->viewTransform, info->transformPtr, 0,
- info->widget, info->opacity, &newEffectTransform, info->wasDirtySceneTransform,
- info->drawItem);
- }
-
- pixmapPainter.end();
-
- return pixmap;
-}
-#endif //QT_NO_GRAPHICSEFFECT
-
-#ifndef QT_NO_DEBUG_STREAM
-QDebug operator<<(QDebug debug, QGraphicsItem *item)
-{
- if (!item) {
- debug << "QGraphicsItem(0)";
- return debug;
- }
-
- if (QGraphicsObject *o = item->toGraphicsObject())
- debug << o->metaObject()->className();
- else
- debug << "QGraphicsItem";
- debug << "(this =" << (void*)item
- << ", parent =" << (void*)item->parentItem()
- << ", pos =" << item->pos()
- << ", z =" << item->zValue() << ", flags = "
- << item->flags() << ")";
- return debug;
-}
-
-QDebug operator<<(QDebug debug, QGraphicsObject *item)
-{
- if (!item) {
- debug << "QGraphicsObject(0)";
- return debug;
- }
-
- debug.nospace() << item->metaObject()->className() << '(' << (void*)item;
- if (!item->objectName().isEmpty())
- debug << ", name = " << item->objectName();
- debug.nospace() << ", parent = " << ((void*)item->parentItem())
- << ", pos = " << item->pos()
- << ", z = " << item->zValue() << ", flags = "
- << item->flags() << ')';
- return debug.space();
-}
-
-QDebug operator<<(QDebug debug, QGraphicsItem::GraphicsItemChange change)
-{
- const char *str = "UnknownChange";
- switch (change) {
- case QGraphicsItem::ItemChildAddedChange:
- str = "ItemChildAddedChange";
- break;
- case QGraphicsItem::ItemChildRemovedChange:
- str = "ItemChildRemovedChange";
- break;
- case QGraphicsItem::ItemCursorChange:
- str = "ItemCursorChange";
- break;
- case QGraphicsItem::ItemCursorHasChanged:
- str = "ItemCursorHasChanged";
- break;
- case QGraphicsItem::ItemEnabledChange:
- str = "ItemEnabledChange";
- break;
- case QGraphicsItem::ItemEnabledHasChanged:
- str = "ItemEnabledHasChanged";
- break;
- case QGraphicsItem::ItemFlagsChange:
- str = "ItemFlagsChange";
- break;
- case QGraphicsItem::ItemFlagsHaveChanged:
- str = "ItemFlagsHaveChanged";
- break;
- case QGraphicsItem::ItemMatrixChange:
- str = "ItemMatrixChange";
- break;
- case QGraphicsItem::ItemParentChange:
- str = "ItemParentChange";
- break;
- case QGraphicsItem::ItemParentHasChanged:
- str = "ItemParentHasChanged";
- break;
- case QGraphicsItem::ItemPositionChange:
- str = "ItemPositionChange";
- break;
- case QGraphicsItem::ItemPositionHasChanged:
- str = "ItemPositionHasChanged";
- break;
- case QGraphicsItem::ItemSceneChange:
- str = "ItemSceneChange";
- break;
- case QGraphicsItem::ItemSceneHasChanged:
- str = "ItemSceneHasChanged";
- break;
- case QGraphicsItem::ItemSelectedChange:
- str = "ItemSelectedChange";
- break;
- case QGraphicsItem::ItemSelectedHasChanged:
- str = "ItemSelectedHasChanged";
- break;
- case QGraphicsItem::ItemToolTipChange:
- str = "ItemToolTipChange";
- break;
- case QGraphicsItem::ItemToolTipHasChanged:
- str = "ItemToolTipHasChanged";
- break;
- case QGraphicsItem::ItemTransformChange:
- str = "ItemTransformChange";
- break;
- case QGraphicsItem::ItemTransformHasChanged:
- str = "ItemTransformHasChanged";
- break;
- case QGraphicsItem::ItemVisibleChange:
- str = "ItemVisibleChange";
- break;
- case QGraphicsItem::ItemVisibleHasChanged:
- str = "ItemVisibleHasChanged";
- break;
- case QGraphicsItem::ItemZValueChange:
- str = "ItemZValueChange";
- break;
- case QGraphicsItem::ItemZValueHasChanged:
- str = "ItemZValueHasChanged";
- break;
- case QGraphicsItem::ItemOpacityChange:
- str = "ItemOpacityChange";
- break;
- case QGraphicsItem::ItemOpacityHasChanged:
- str = "ItemOpacityHasChanged";
- break;
- case QGraphicsItem::ItemScenePositionHasChanged:
- str = "ItemScenePositionHasChanged";
- break;
- case QGraphicsItem::ItemRotationChange:
- str = "ItemRotationChange";
- break;
- case QGraphicsItem::ItemRotationHasChanged:
- str = "ItemRotationHasChanged";
- break;
- case QGraphicsItem::ItemScaleChange:
- str = "ItemScaleChange";
- break;
- case QGraphicsItem::ItemScaleHasChanged:
- str = "ItemScaleHasChanged";
- break;
- case QGraphicsItem::ItemTransformOriginPointChange:
- str = "ItemTransformOriginPointChange";
- break;
- case QGraphicsItem::ItemTransformOriginPointHasChanged:
- str = "ItemTransformOriginPointHasChanged";
- break;
- }
- debug << str;
- return debug;
-}
-
-QDebug operator<<(QDebug debug, QGraphicsItem::GraphicsItemFlag flag)
-{
- const char *str = "UnknownFlag";
- switch (flag) {
- case QGraphicsItem::ItemIsMovable:
- str = "ItemIsMovable";
- break;
- case QGraphicsItem::ItemIsSelectable:
- str = "ItemIsSelectable";
- break;
- case QGraphicsItem::ItemIsFocusable:
- str = "ItemIsFocusable";
- break;
- case QGraphicsItem::ItemClipsToShape:
- str = "ItemClipsToShape";
- break;
- case QGraphicsItem::ItemClipsChildrenToShape:
- str = "ItemClipsChildrenToShape";
- break;
- case QGraphicsItem::ItemIgnoresTransformations:
- str = "ItemIgnoresTransformations";
- break;
- case QGraphicsItem::ItemIgnoresParentOpacity:
- str = "ItemIgnoresParentOpacity";
- break;
- case QGraphicsItem::ItemDoesntPropagateOpacityToChildren:
- str = "ItemDoesntPropagateOpacityToChildren";
- break;
- case QGraphicsItem::ItemStacksBehindParent:
- str = "ItemStacksBehindParent";
- break;
- case QGraphicsItem::ItemUsesExtendedStyleOption:
- str = "ItemUsesExtendedStyleOption";
- break;
- case QGraphicsItem::ItemHasNoContents:
- str = "ItemHasNoContents";
- break;
- case QGraphicsItem::ItemSendsGeometryChanges:
- str = "ItemSendsGeometryChanges";
- break;
- case QGraphicsItem::ItemAcceptsInputMethod:
- str = "ItemAcceptsInputMethod";
- break;
- case QGraphicsItem::ItemNegativeZStacksBehindParent:
- str = "ItemNegativeZStacksBehindParent";
- break;
- case QGraphicsItem::ItemIsPanel:
- str = "ItemIsPanel";
- break;
- case QGraphicsItem::ItemIsFocusScope:
- str = "ItemIsFocusScope";
- break;
- case QGraphicsItem::ItemSendsScenePositionChanges:
- str = "ItemSendsScenePositionChanges";
- break;
- case QGraphicsItem::ItemStopsClickFocusPropagation:
- str = "ItemStopsClickFocusPropagation";
- break;
- case QGraphicsItem::ItemStopsFocusHandling:
- str = "ItemStopsFocusHandling";
- break;
- }
- debug << str;
- return debug;
-}
-
-QDebug operator<<(QDebug debug, QGraphicsItem::GraphicsItemFlags flags)
-{
- debug << '(';
- bool f = false;
- for (int i = 0; i < 17; ++i) {
- if (flags & (1 << i)) {
- if (f)
- debug << '|';
- f = true;
- debug << QGraphicsItem::GraphicsItemFlag(int(flags & (1 << i)));
- }
- }
- debug << ')';
- return debug;
-}
-
-#endif
-
-QT_END_NAMESPACE
-
-#include "moc_qgraphicsitem.cpp"
-
-#endif // QT_NO_GRAPHICSVIEW
diff --git a/src/gui/graphicsview/qgraphicsitem.h b/src/gui/graphicsview/qgraphicsitem.h
deleted file mode 100644
index a3443826c7..0000000000
--- a/src/gui/graphicsview/qgraphicsitem.h
+++ /dev/null
@@ -1,1172 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGRAPHICSITEM_H
-#define QGRAPHICSITEM_H
-
-#include <QtCore/qglobal.h>
-#include <QtCore/qobject.h>
-#include <QtCore/qvariant.h>
-#include <QtCore/qrect.h>
-#include <QtCore/qscopedpointer.h>
-#include <QtGui/qpainterpath.h>
-#include <QtGui/qpixmap.h>
-
-class tst_QGraphicsItem;
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW
-
-class QBrush;
-class QCursor;
-class QFocusEvent;
-class QGraphicsEffect;
-class QGraphicsItemGroup;
-class QGraphicsObject;
-class QGraphicsSceneContextMenuEvent;
-class QGraphicsSceneDragDropEvent;
-class QGraphicsSceneEvent;
-class QGraphicsSceneHoverEvent;
-class QGraphicsSceneMouseEvent;
-class QGraphicsSceneWheelEvent;
-class QGraphicsScene;
-class QGraphicsTransform;
-class QGraphicsWidget;
-class QInputMethodEvent;
-class QKeyEvent;
-class QMatrix;
-class QMenu;
-class QPainter;
-class QPen;
-class QPointF;
-class QRectF;
-class QStyleOptionGraphicsItem;
-
-class QGraphicsItemPrivate;
-class Q_GUI_EXPORT QGraphicsItem
-{
-public:
- enum GraphicsItemFlag {
- ItemIsMovable = 0x1,
- ItemIsSelectable = 0x2,
- ItemIsFocusable = 0x4,
- ItemClipsToShape = 0x8,
- ItemClipsChildrenToShape = 0x10,
- ItemIgnoresTransformations = 0x20,
- ItemIgnoresParentOpacity = 0x40,
- ItemDoesntPropagateOpacityToChildren = 0x80,
- ItemStacksBehindParent = 0x100,
- ItemUsesExtendedStyleOption = 0x200,
- ItemHasNoContents = 0x400,
- ItemSendsGeometryChanges = 0x800,
- ItemAcceptsInputMethod = 0x1000,
- ItemNegativeZStacksBehindParent = 0x2000,
- ItemIsPanel = 0x4000,
- ItemIsFocusScope = 0x8000, // internal
- ItemSendsScenePositionChanges = 0x10000,
- ItemStopsClickFocusPropagation = 0x20000,
- ItemStopsFocusHandling = 0x40000
- // NB! Don't forget to increase the d_ptr->flags bit field by 1 when adding a new flag.
- };
- Q_DECLARE_FLAGS(GraphicsItemFlags, GraphicsItemFlag)
-
- enum GraphicsItemChange {
- ItemPositionChange,
- ItemMatrixChange,
- ItemVisibleChange,
- ItemEnabledChange,
- ItemSelectedChange,
- ItemParentChange,
- ItemChildAddedChange,
- ItemChildRemovedChange,
- ItemTransformChange,
- ItemPositionHasChanged,
- ItemTransformHasChanged,
- ItemSceneChange,
- ItemVisibleHasChanged,
- ItemEnabledHasChanged,
- ItemSelectedHasChanged,
- ItemParentHasChanged,
- ItemSceneHasChanged,
- ItemCursorChange,
- ItemCursorHasChanged,
- ItemToolTipChange,
- ItemToolTipHasChanged,
- ItemFlagsChange,
- ItemFlagsHaveChanged,
- ItemZValueChange,
- ItemZValueHasChanged,
- ItemOpacityChange,
- ItemOpacityHasChanged,
- ItemScenePositionHasChanged,
- ItemRotationChange,
- ItemRotationHasChanged,
- ItemScaleChange,
- ItemScaleHasChanged,
- ItemTransformOriginPointChange,
- ItemTransformOriginPointHasChanged
- };
-
- enum CacheMode {
- NoCache,
- ItemCoordinateCache,
- DeviceCoordinateCache
- };
-
- enum PanelModality
- {
- NonModal,
- PanelModal,
- SceneModal
- };
-
- QGraphicsItem(QGraphicsItem *parent = 0
-#ifndef Q_QDOC
- // ### obsolete argument
- , QGraphicsScene *scene = 0
-#endif
- );
- virtual ~QGraphicsItem();
-
- QGraphicsScene *scene() const;
-
- QGraphicsItem *parentItem() const;
- QGraphicsItem *topLevelItem() const;
- QGraphicsObject *parentObject() const;
- QGraphicsWidget *parentWidget() const;
- QGraphicsWidget *topLevelWidget() const;
- QGraphicsWidget *window() const;
- QGraphicsItem *panel() const;
- void setParentItem(QGraphicsItem *parent);
- QList<QGraphicsItem *> children() const; // ### obsolete
- QList<QGraphicsItem *> childItems() const;
- bool isWidget() const;
- bool isWindow() const;
- bool isPanel() const;
-
- QGraphicsObject *toGraphicsObject();
- const QGraphicsObject *toGraphicsObject() const;
-
- QGraphicsItemGroup *group() const;
- void setGroup(QGraphicsItemGroup *group);
-
- GraphicsItemFlags flags() const;
- void setFlag(GraphicsItemFlag flag, bool enabled = true);
- void setFlags(GraphicsItemFlags flags);
-
- CacheMode cacheMode() const;
- void setCacheMode(CacheMode mode, const QSize &cacheSize = QSize());
-
- PanelModality panelModality() const;
- void setPanelModality(PanelModality panelModality);
- bool isBlockedByModalPanel(QGraphicsItem **blockingPanel = 0) const;
-
-#ifndef QT_NO_TOOLTIP
- QString toolTip() const;
- void setToolTip(const QString &toolTip);
-#endif
-
-#ifndef QT_NO_CURSOR
- QCursor cursor() const;
- void setCursor(const QCursor &cursor);
- bool hasCursor() const;
- void unsetCursor();
-#endif
-
- bool isVisible() const;
- bool isVisibleTo(const QGraphicsItem *parent) const;
- void setVisible(bool visible);
- inline void hide() { setVisible(false); }
- inline void show() { setVisible(true); }
-
- bool isEnabled() const;
- void setEnabled(bool enabled);
-
- bool isSelected() const;
- void setSelected(bool selected);
-
- bool acceptDrops() const;
- void setAcceptDrops(bool on);
-
- qreal opacity() const;
- qreal effectiveOpacity() const;
- void setOpacity(qreal opacity);
-
-#ifndef QT_NO_GRAPHICSEFFECT
- // Effect
- QGraphicsEffect *graphicsEffect() const;
- void setGraphicsEffect(QGraphicsEffect *effect);
-#endif //QT_NO_GRAPHICSEFFECT
-
- Qt::MouseButtons acceptedMouseButtons() const;
- void setAcceptedMouseButtons(Qt::MouseButtons buttons);
-
- bool acceptsHoverEvents() const; // ### obsolete
- void setAcceptsHoverEvents(bool enabled); // ### obsolete
- bool acceptHoverEvents() const;
- void setAcceptHoverEvents(bool enabled);
- bool acceptTouchEvents() const;
- void setAcceptTouchEvents(bool enabled);
-
- bool filtersChildEvents() const;
- void setFiltersChildEvents(bool enabled);
-
- bool handlesChildEvents() const;
- void setHandlesChildEvents(bool enabled);
-
- bool isActive() const;
- void setActive(bool active);
-
- bool hasFocus() const;
- void setFocus(Qt::FocusReason focusReason = Qt::OtherFocusReason);
- void clearFocus();
-
- QGraphicsItem *focusProxy() const;
- void setFocusProxy(QGraphicsItem *item);
-
- QGraphicsItem *focusItem() const;
- QGraphicsItem *focusScopeItem() const;
-
- void grabMouse();
- void ungrabMouse();
- void grabKeyboard();
- void ungrabKeyboard();
-
- // Positioning in scene coordinates
- QPointF pos() const;
- inline qreal x() const { return pos().x(); }
- void setX(qreal x);
- inline qreal y() const { return pos().y(); }
- void setY(qreal y);
- QPointF scenePos() const;
- void setPos(const QPointF &pos);
- inline void setPos(qreal x, qreal y);
- inline void moveBy(qreal dx, qreal dy) { setPos(pos().x() + dx, pos().y() + dy); }
-
- void ensureVisible(const QRectF &rect = QRectF(), int xmargin = 50, int ymargin = 50);
- inline void ensureVisible(qreal x, qreal y, qreal w, qreal h, int xmargin = 50, int ymargin = 50);
-
- // Local transformation
- QMatrix matrix() const;
- QMatrix sceneMatrix() const;
- void setMatrix(const QMatrix &matrix, bool combine = false);
- void resetMatrix();
- QTransform transform() const;
- QTransform sceneTransform() const;
- QTransform deviceTransform(const QTransform &viewportTransform) const;
- QTransform itemTransform(const QGraphicsItem *other, bool *ok = 0) const;
- void setTransform(const QTransform &matrix, bool combine = false);
- void resetTransform();
-
- void rotate(qreal angle); // ### obsolete
- void scale(qreal sx, qreal sy); // ### obsolete
- void shear(qreal sh, qreal sv); // ### obsolete
- void translate(qreal dx, qreal dy); // ### obsolete
-
- void setRotation(qreal angle);
- qreal rotation() const;
-
- void setScale(qreal scale);
- qreal scale() const;
-
- QList<QGraphicsTransform *> transformations() const;
- void setTransformations(const QList<QGraphicsTransform *> &transformations);
-
- QPointF transformOriginPoint() const;
- void setTransformOriginPoint(const QPointF &origin);
- inline void setTransformOriginPoint(qreal ax, qreal ay)
- { setTransformOriginPoint(QPointF(ax,ay)); }
-
- virtual void advance(int phase);
-
- // Stacking order
- qreal zValue() const;
- void setZValue(qreal z);
- void stackBefore(const QGraphicsItem *sibling);
-
- // Hit test
- virtual QRectF boundingRect() const = 0;
- QRectF childrenBoundingRect() const;
- QRectF sceneBoundingRect() const;
- virtual QPainterPath shape() const;
- bool isClipped() const;
- QPainterPath clipPath() const;
- virtual bool contains(const QPointF &point) const;
- virtual bool collidesWithItem(const QGraphicsItem *other, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const;
- virtual bool collidesWithPath(const QPainterPath &path, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const;
- QList<QGraphicsItem *> collidingItems(Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const;
- bool isObscured() const;
- bool isObscured(const QRectF &rect) const; // ### Qt 5: merge with isObscured(), add QRectF arg to isObscuredBy()
- inline bool isObscured(qreal x, qreal y, qreal w, qreal h) const;
- virtual bool isObscuredBy(const QGraphicsItem *item) const;
- virtual QPainterPath opaqueArea() const;
-
- QRegion boundingRegion(const QTransform &itemToDeviceTransform) const;
- qreal boundingRegionGranularity() const;
- void setBoundingRegionGranularity(qreal granularity);
-
- // Drawing
- virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) = 0;
- void update(const QRectF &rect = QRectF());
- inline void update(qreal x, qreal y, qreal width, qreal height);
- void scroll(qreal dx, qreal dy, const QRectF &rect = QRectF());
-
- // Coordinate mapping
- QPointF mapToItem(const QGraphicsItem *item, const QPointF &point) const;
- QPointF mapToParent(const QPointF &point) const;
- QPointF mapToScene(const QPointF &point) const;
- QPolygonF mapToItem(const QGraphicsItem *item, const QRectF &rect) const;
- QPolygonF mapToParent(const QRectF &rect) const;
- QPolygonF mapToScene(const QRectF &rect) const;
- QRectF mapRectToItem(const QGraphicsItem *item, const QRectF &rect) const;
- QRectF mapRectToParent(const QRectF &rect) const;
- QRectF mapRectToScene(const QRectF &rect) const;
- QPolygonF mapToItem(const QGraphicsItem *item, const QPolygonF &polygon) const;
- QPolygonF mapToParent(const QPolygonF &polygon) const;
- QPolygonF mapToScene(const QPolygonF &polygon) const;
- QPainterPath mapToItem(const QGraphicsItem *item, const QPainterPath &path) const;
- QPainterPath mapToParent(const QPainterPath &path) const;
- QPainterPath mapToScene(const QPainterPath &path) const;
- QPointF mapFromItem(const QGraphicsItem *item, const QPointF &point) const;
- QPointF mapFromParent(const QPointF &point) const;
- QPointF mapFromScene(const QPointF &point) const;
- QPolygonF mapFromItem(const QGraphicsItem *item, const QRectF &rect) const;
- QPolygonF mapFromParent(const QRectF &rect) const;
- QPolygonF mapFromScene(const QRectF &rect) const;
- QRectF mapRectFromItem(const QGraphicsItem *item, const QRectF &rect) const;
- QRectF mapRectFromParent(const QRectF &rect) const;
- QRectF mapRectFromScene(const QRectF &rect) const;
- QPolygonF mapFromItem(const QGraphicsItem *item, const QPolygonF &polygon) const;
- QPolygonF mapFromParent(const QPolygonF &polygon) const;
- QPolygonF mapFromScene(const QPolygonF &polygon) const;
- QPainterPath mapFromItem(const QGraphicsItem *item, const QPainterPath &path) const;
- QPainterPath mapFromParent(const QPainterPath &path) const;
- QPainterPath mapFromScene(const QPainterPath &path) const;
-
- inline QPointF mapToItem(const QGraphicsItem *item, qreal x, qreal y) const;
- inline QPointF mapToParent(qreal x, qreal y) const;
- inline QPointF mapToScene(qreal x, qreal y) const;
- inline QPolygonF mapToItem(const QGraphicsItem *item, qreal x, qreal y, qreal w, qreal h) const;
- inline QPolygonF mapToParent(qreal x, qreal y, qreal w, qreal h) const;
- inline QPolygonF mapToScene(qreal x, qreal y, qreal w, qreal h) const;
- inline QRectF mapRectToItem(const QGraphicsItem *item, qreal x, qreal y, qreal w, qreal h) const;
- inline QRectF mapRectToParent(qreal x, qreal y, qreal w, qreal h) const;
- inline QRectF mapRectToScene(qreal x, qreal y, qreal w, qreal h) const;
- inline QPointF mapFromItem(const QGraphicsItem *item, qreal x, qreal y) const;
- inline QPointF mapFromParent(qreal x, qreal y) const;
- inline QPointF mapFromScene(qreal x, qreal y) const;
- inline QPolygonF mapFromItem(const QGraphicsItem *item, qreal x, qreal y, qreal w, qreal h) const;
- inline QPolygonF mapFromParent(qreal x, qreal y, qreal w, qreal h) const;
- inline QPolygonF mapFromScene(qreal x, qreal y, qreal w, qreal h) const;
- inline QRectF mapRectFromItem(const QGraphicsItem *item, qreal x, qreal y, qreal w, qreal h) const;
- inline QRectF mapRectFromParent(qreal x, qreal y, qreal w, qreal h) const;
- inline QRectF mapRectFromScene(qreal x, qreal y, qreal w, qreal h) const;
-
- bool isAncestorOf(const QGraphicsItem *child) const;
- QGraphicsItem *commonAncestorItem(const QGraphicsItem *other) const;
- bool isUnderMouse() const;
-
- // Custom data
- QVariant data(int key) const;
- void setData(int key, const QVariant &value);
-
- Qt::InputMethodHints inputMethodHints() const;
- void setInputMethodHints(Qt::InputMethodHints hints);
-
- enum {
- Type = 1,
- UserType = 65536
- };
- virtual int type() const;
-
- void installSceneEventFilter(QGraphicsItem *filterItem);
- void removeSceneEventFilter(QGraphicsItem *filterItem);
-
-protected:
- void updateMicroFocus();
- virtual bool sceneEventFilter(QGraphicsItem *watched, QEvent *event);
- virtual bool sceneEvent(QEvent *event);
- virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent *event);
- virtual void dragEnterEvent(QGraphicsSceneDragDropEvent *event);
- virtual void dragLeaveEvent(QGraphicsSceneDragDropEvent *event);
- virtual void dragMoveEvent(QGraphicsSceneDragDropEvent *event);
- virtual void dropEvent(QGraphicsSceneDragDropEvent *event);
- virtual void focusInEvent(QFocusEvent *event);
- virtual void focusOutEvent(QFocusEvent *event);
- virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
- virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *event);
- virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
- virtual void keyPressEvent(QKeyEvent *event);
- virtual void keyReleaseEvent(QKeyEvent *event);
- virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
- virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
- virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
- virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event);
- virtual void wheelEvent(QGraphicsSceneWheelEvent *event);
- virtual void inputMethodEvent(QInputMethodEvent *event);
- virtual QVariant inputMethodQuery(Qt::InputMethodQuery query) const;
-
- virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value);
-
- enum Extension {
- UserExtension = 0x80000000
- };
- virtual bool supportsExtension(Extension extension) const;
- virtual void setExtension(Extension extension, const QVariant &variant);
- virtual QVariant extension(const QVariant &variant) const;
-
-protected:
- QGraphicsItem(QGraphicsItemPrivate &dd,
- QGraphicsItem *parent, QGraphicsScene *scene);
- QScopedPointer<QGraphicsItemPrivate> d_ptr;
-
- void addToIndex();
- void removeFromIndex();
- void prepareGeometryChange();
-
-private:
- Q_DISABLE_COPY(QGraphicsItem)
- Q_DECLARE_PRIVATE(QGraphicsItem)
- friend class QGraphicsItemGroup;
- friend class QGraphicsScene;
- friend class QGraphicsScenePrivate;
- friend class QGraphicsSceneFindItemBspTreeVisitor;
- friend class QGraphicsSceneBspTree;
- friend class QGraphicsView;
- friend class QGraphicsViewPrivate;
- friend class QGraphicsObject;
- friend class QGraphicsWidget;
- friend class QGraphicsWidgetPrivate;
- friend class QGraphicsProxyWidgetPrivate;
- friend class QGraphicsSceneIndex;
- friend class QGraphicsSceneIndexPrivate;
- friend class QGraphicsSceneBspTreeIndex;
- friend class QGraphicsSceneBspTreeIndexPrivate;
- friend class QGraphicsItemEffectSourcePrivate;
- friend class QGraphicsTransformPrivate;
-#ifndef QT_NO_GESTURES
- friend class QGestureManager;
-#endif
- friend class ::tst_QGraphicsItem;
- friend bool qt_closestLeaf(const QGraphicsItem *, const QGraphicsItem *);
- friend bool qt_closestItemFirst(const QGraphicsItem *, const QGraphicsItem *);
-};
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QGraphicsItem::GraphicsItemFlags)
-Q_DECLARE_INTERFACE(QGraphicsItem, "com.trolltech.Qt.QGraphicsItem")
-
-inline void QGraphicsItem::setPos(qreal ax, qreal ay)
-{ setPos(QPointF(ax, ay)); }
-inline void QGraphicsItem::ensureVisible(qreal ax, qreal ay, qreal w, qreal h, int xmargin, int ymargin)
-{ ensureVisible(QRectF(ax, ay, w, h), xmargin, ymargin); }
-inline void QGraphicsItem::update(qreal ax, qreal ay, qreal width, qreal height)
-{ update(QRectF(ax, ay, width, height)); }
-inline bool QGraphicsItem::isObscured(qreal ax, qreal ay, qreal w, qreal h) const
-{ return isObscured(QRectF(ax, ay, w, h)); }
-inline QPointF QGraphicsItem::mapToItem(const QGraphicsItem *item, qreal ax, qreal ay) const
-{ return mapToItem(item, QPointF(ax, ay)); }
-inline QPointF QGraphicsItem::mapToParent(qreal ax, qreal ay) const
-{ return mapToParent(QPointF(ax, ay)); }
-inline QPointF QGraphicsItem::mapToScene(qreal ax, qreal ay) const
-{ return mapToScene(QPointF(ax, ay)); }
-inline QPointF QGraphicsItem::mapFromItem(const QGraphicsItem *item, qreal ax, qreal ay) const
-{ return mapFromItem(item, QPointF(ax, ay)); }
-inline QPointF QGraphicsItem::mapFromParent(qreal ax, qreal ay) const
-{ return mapFromParent(QPointF(ax, ay)); }
-inline QPointF QGraphicsItem::mapFromScene(qreal ax, qreal ay) const
-{ return mapFromScene(QPointF(ax, ay)); }
-inline QPolygonF QGraphicsItem::mapToItem(const QGraphicsItem *item, qreal ax, qreal ay, qreal w, qreal h) const
-{ return mapToItem(item, QRectF(ax, ay, w, h)); }
-inline QPolygonF QGraphicsItem::mapToParent(qreal ax, qreal ay, qreal w, qreal h) const
-{ return mapToParent(QRectF(ax, ay, w, h)); }
-inline QPolygonF QGraphicsItem::mapToScene(qreal ax, qreal ay, qreal w, qreal h) const
-{ return mapToScene(QRectF(ax, ay, w, h)); }
-inline QRectF QGraphicsItem::mapRectToItem(const QGraphicsItem *item, qreal ax, qreal ay, qreal w, qreal h) const
-{ return mapRectToItem(item, QRectF(ax, ay, w, h)); }
-inline QRectF QGraphicsItem::mapRectToParent(qreal ax, qreal ay, qreal w, qreal h) const
-{ return mapRectToParent(QRectF(ax, ay, w, h)); }
-inline QRectF QGraphicsItem::mapRectToScene(qreal ax, qreal ay, qreal w, qreal h) const
-{ return mapRectToScene(QRectF(ax, ay, w, h)); }
-inline QPolygonF QGraphicsItem::mapFromItem(const QGraphicsItem *item, qreal ax, qreal ay, qreal w, qreal h) const
-{ return mapFromItem(item, QRectF(ax, ay, w, h)); }
-inline QPolygonF QGraphicsItem::mapFromParent(qreal ax, qreal ay, qreal w, qreal h) const
-{ return mapFromParent(QRectF(ax, ay, w, h)); }
-inline QPolygonF QGraphicsItem::mapFromScene(qreal ax, qreal ay, qreal w, qreal h) const
-{ return mapFromScene(QRectF(ax, ay, w, h)); }
-inline QRectF QGraphicsItem::mapRectFromItem(const QGraphicsItem *item, qreal ax, qreal ay, qreal w, qreal h) const
-{ return mapRectFromItem(item, QRectF(ax, ay, w, h)); }
-inline QRectF QGraphicsItem::mapRectFromParent(qreal ax, qreal ay, qreal w, qreal h) const
-{ return mapRectFromParent(QRectF(ax, ay, w, h)); }
-inline QRectF QGraphicsItem::mapRectFromScene(qreal ax, qreal ay, qreal w, qreal h) const
-{ return mapRectFromScene(QRectF(ax, ay, w, h)); }
-
-
-class Q_GUI_EXPORT QGraphicsObject : public QObject, public QGraphicsItem
-{
- Q_OBJECT
- Q_PROPERTY(QGraphicsObject * parent READ parentObject WRITE setParentItem NOTIFY parentChanged DESIGNABLE false)
- Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity NOTIFY opacityChanged FINAL)
- Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged)
- Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged FINAL)
- Q_PROPERTY(QPointF pos READ pos WRITE setPos FINAL)
- Q_PROPERTY(qreal x READ x WRITE setX NOTIFY xChanged FINAL)
- Q_PROPERTY(qreal y READ y WRITE setY NOTIFY yChanged FINAL)
- Q_PROPERTY(qreal z READ zValue WRITE setZValue NOTIFY zChanged FINAL)
- Q_PROPERTY(qreal rotation READ rotation WRITE setRotation NOTIFY rotationChanged)
- Q_PROPERTY(qreal scale READ scale WRITE setScale NOTIFY scaleChanged)
- Q_PROPERTY(QPointF transformOriginPoint READ transformOriginPoint WRITE setTransformOriginPoint)
-#ifndef QT_NO_GRAPHICSEFFECT
- Q_PROPERTY(QGraphicsEffect *effect READ graphicsEffect WRITE setGraphicsEffect)
-#endif
- Q_PRIVATE_PROPERTY(QGraphicsItem::d_func(), QDeclarativeListProperty<QGraphicsObject> children READ childrenList DESIGNABLE false NOTIFY childrenChanged)
- Q_PRIVATE_PROPERTY(QGraphicsItem::d_func(), qreal width READ width WRITE setWidth NOTIFY widthChanged RESET resetWidth FINAL)
- Q_PRIVATE_PROPERTY(QGraphicsItem::d_func(), qreal height READ height WRITE setHeight NOTIFY heightChanged RESET resetHeight FINAL)
- Q_CLASSINFO("DefaultProperty", "children")
- Q_INTERFACES(QGraphicsItem)
-public:
- QGraphicsObject(QGraphicsItem *parent = 0);
-
- // ### Qt 5: Disambiguate
-#ifdef Q_NO_USING_KEYWORD
- const QObjectList &children() const { return QObject::children(); }
-#else
- using QObject::children;
-#endif
-
-#ifndef QT_NO_GESTURES
- void grabGesture(Qt::GestureType type, Qt::GestureFlags flags = Qt::GestureFlags());
- void ungrabGesture(Qt::GestureType type);
-#endif
-
-protected Q_SLOTS:
- void updateMicroFocus();
-
-Q_SIGNALS:
- void parentChanged();
- void opacityChanged();
- void visibleChanged();
- void enabledChanged();
- void xChanged();
- void yChanged();
- void zChanged();
- void rotationChanged();
- void scaleChanged();
- void childrenChanged();
- void widthChanged();
- void heightChanged();
-
-protected:
- QGraphicsObject(QGraphicsItemPrivate &dd, QGraphicsItem *parent, QGraphicsScene *scene);
-private:
- friend class QGraphicsItem;
- friend class QGraphicsItemPrivate;
-};
-
-
-class QAbstractGraphicsShapeItemPrivate;
-class Q_GUI_EXPORT QAbstractGraphicsShapeItem : public QGraphicsItem
-{
-public:
- QAbstractGraphicsShapeItem(QGraphicsItem *parent = 0
-#ifndef Q_QDOC
- // ### obsolete argument
- , QGraphicsScene *scene = 0
-#endif
- );
- ~QAbstractGraphicsShapeItem();
-
- QPen pen() const;
- void setPen(const QPen &pen);
-
- QBrush brush() const;
- void setBrush(const QBrush &brush);
-
- bool isObscuredBy(const QGraphicsItem *item) const;
- QPainterPath opaqueArea() const;
-
-protected:
- QAbstractGraphicsShapeItem(QAbstractGraphicsShapeItemPrivate &dd,
- QGraphicsItem *parent, QGraphicsScene *scene);
-
-private:
- Q_DISABLE_COPY(QAbstractGraphicsShapeItem)
- Q_DECLARE_PRIVATE(QAbstractGraphicsShapeItem)
-};
-
-class QGraphicsPathItemPrivate;
-class Q_GUI_EXPORT QGraphicsPathItem : public QAbstractGraphicsShapeItem
-{
-public:
- QGraphicsPathItem(QGraphicsItem *parent = 0
-#ifndef Q_QDOC
- // ### obsolete argument
- , QGraphicsScene *scene = 0
-#endif
- );
- QGraphicsPathItem(const QPainterPath &path, QGraphicsItem *parent = 0
-#ifndef Q_QDOC
- // ### obsolete argument
- , QGraphicsScene *scene = 0
-#endif
- );
- ~QGraphicsPathItem();
-
- QPainterPath path() const;
- void setPath(const QPainterPath &path);
-
- QRectF boundingRect() const;
- QPainterPath shape() const;
- bool contains(const QPointF &point) const;
-
- void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
-
- bool isObscuredBy(const QGraphicsItem *item) const;
- QPainterPath opaqueArea() const;
-
- enum { Type = 2 };
- int type() const;
-
-protected:
- bool supportsExtension(Extension extension) const;
- void setExtension(Extension extension, const QVariant &variant);
- QVariant extension(const QVariant &variant) const;
-
-private:
- Q_DISABLE_COPY(QGraphicsPathItem)
- Q_DECLARE_PRIVATE(QGraphicsPathItem)
-};
-
-class QGraphicsRectItemPrivate;
-class Q_GUI_EXPORT QGraphicsRectItem : public QAbstractGraphicsShapeItem
-{
-public:
- QGraphicsRectItem(QGraphicsItem *parent = 0
-#ifndef Q_QDOC
- // ### obsolete argument
- , QGraphicsScene *scene = 0
-#endif
- );
- QGraphicsRectItem(const QRectF &rect, QGraphicsItem *parent = 0
-#ifndef Q_QDOC
- // ### obsolete argument
- , QGraphicsScene *scene = 0
-#endif
- );
- QGraphicsRectItem(qreal x, qreal y, qreal w, qreal h, QGraphicsItem *parent = 0
-#ifndef Q_QDOC
- // ### obsolete argument
- , QGraphicsScene *scene = 0
-#endif
- );
- ~QGraphicsRectItem();
-
- QRectF rect() const;
- void setRect(const QRectF &rect);
- inline void setRect(qreal x, qreal y, qreal w, qreal h);
-
- QRectF boundingRect() const;
- QPainterPath shape() const;
- bool contains(const QPointF &point) const;
-
- void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
-
- bool isObscuredBy(const QGraphicsItem *item) const;
- QPainterPath opaqueArea() const;
-
- enum { Type = 3 };
- int type() const;
-
-protected:
- bool supportsExtension(Extension extension) const;
- void setExtension(Extension extension, const QVariant &variant);
- QVariant extension(const QVariant &variant) const;
-
-private:
- Q_DISABLE_COPY(QGraphicsRectItem)
- Q_DECLARE_PRIVATE(QGraphicsRectItem)
-};
-
-inline void QGraphicsRectItem::setRect(qreal ax, qreal ay, qreal w, qreal h)
-{ setRect(QRectF(ax, ay, w, h)); }
-
-class QGraphicsEllipseItemPrivate;
-class Q_GUI_EXPORT QGraphicsEllipseItem : public QAbstractGraphicsShapeItem
-{
-public:
- QGraphicsEllipseItem(QGraphicsItem *parent = 0
-#ifndef Q_QDOC
- // ### obsolete argument
- , QGraphicsScene *scene = 0
-#endif
- );
- QGraphicsEllipseItem(const QRectF &rect, QGraphicsItem *parent = 0
-#ifndef Q_QDOC
- // ### obsolete argument
- , QGraphicsScene *scene = 0
-#endif
- );
- QGraphicsEllipseItem(qreal x, qreal y, qreal w, qreal h, QGraphicsItem *parent = 0
-#ifndef Q_QDOC
- // ### obsolete argument
- , QGraphicsScene *scene = 0
-#endif
- );
- ~QGraphicsEllipseItem();
-
- QRectF rect() const;
- void setRect(const QRectF &rect);
- inline void setRect(qreal x, qreal y, qreal w, qreal h);
-
- int startAngle() const;
- void setStartAngle(int angle);
-
- int spanAngle() const;
- void setSpanAngle(int angle);
-
- QRectF boundingRect() const;
- QPainterPath shape() const;
- bool contains(const QPointF &point) const;
-
- void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
-
- bool isObscuredBy(const QGraphicsItem *item) const;
- QPainterPath opaqueArea() const;
-
- enum { Type = 4 };
- int type() const;
-
-protected:
- bool supportsExtension(Extension extension) const;
- void setExtension(Extension extension, const QVariant &variant);
- QVariant extension(const QVariant &variant) const;
-
-private:
- Q_DISABLE_COPY(QGraphicsEllipseItem)
- Q_DECLARE_PRIVATE(QGraphicsEllipseItem)
-};
-
-inline void QGraphicsEllipseItem::setRect(qreal ax, qreal ay, qreal w, qreal h)
-{ setRect(QRectF(ax, ay, w, h)); }
-
-class QGraphicsPolygonItemPrivate;
-class Q_GUI_EXPORT QGraphicsPolygonItem : public QAbstractGraphicsShapeItem
-{
-public:
- QGraphicsPolygonItem(QGraphicsItem *parent = 0
-#ifndef Q_QDOC
- // ### obsolete argument
- , QGraphicsScene *scene = 0
-#endif
- );
- QGraphicsPolygonItem(const QPolygonF &polygon,
- QGraphicsItem *parent = 0
-#ifndef Q_QDOC
- // ### obsolete argument
- , QGraphicsScene *scene = 0
-#endif
- );
- ~QGraphicsPolygonItem();
-
- QPolygonF polygon() const;
- void setPolygon(const QPolygonF &polygon);
-
- Qt::FillRule fillRule() const;
- void setFillRule(Qt::FillRule rule);
-
- QRectF boundingRect() const;
- QPainterPath shape() const;
- bool contains(const QPointF &point) const;
-
- void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
-
- bool isObscuredBy(const QGraphicsItem *item) const;
- QPainterPath opaqueArea() const;
-
- enum { Type = 5 };
- int type() const;
-
-protected:
- bool supportsExtension(Extension extension) const;
- void setExtension(Extension extension, const QVariant &variant);
- QVariant extension(const QVariant &variant) const;
-
-private:
- Q_DISABLE_COPY(QGraphicsPolygonItem)
- Q_DECLARE_PRIVATE(QGraphicsPolygonItem)
-};
-
-class QGraphicsLineItemPrivate;
-class Q_GUI_EXPORT QGraphicsLineItem : public QGraphicsItem
-{
-public:
- QGraphicsLineItem(QGraphicsItem *parent = 0
-#ifndef Q_QDOC
- // ### obsolete argument
- , QGraphicsScene *scene = 0
-#endif
- );
- QGraphicsLineItem(const QLineF &line, QGraphicsItem *parent = 0
-#ifndef Q_QDOC
- // ### obsolete argument
- , QGraphicsScene *scene = 0
-#endif
- );
- QGraphicsLineItem(qreal x1, qreal y1, qreal x2, qreal y2, QGraphicsItem *parent = 0
-#ifndef Q_QDOC
- // ### obsolete argument
- , QGraphicsScene *scene = 0
-#endif
- );
- ~QGraphicsLineItem();
-
- QPen pen() const;
- void setPen(const QPen &pen);
-
- QLineF line() const;
- void setLine(const QLineF &line);
- inline void setLine(qreal x1, qreal y1, qreal x2, qreal y2)
- { setLine(QLineF(x1, y1, x2, y2)); }
-
- QRectF boundingRect() const;
- QPainterPath shape() const;
- bool contains(const QPointF &point) const;
-
- void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
-
- bool isObscuredBy(const QGraphicsItem *item) const;
- QPainterPath opaqueArea() const;
-
- enum { Type = 6 };
- int type() const;
-
-protected:
- bool supportsExtension(Extension extension) const;
- void setExtension(Extension extension, const QVariant &variant);
- QVariant extension(const QVariant &variant) const;
-
-private:
- Q_DISABLE_COPY(QGraphicsLineItem)
- Q_DECLARE_PRIVATE(QGraphicsLineItem)
-};
-
-class QGraphicsPixmapItemPrivate;
-class Q_GUI_EXPORT QGraphicsPixmapItem : public QGraphicsItem
-{
-public:
- enum ShapeMode {
- MaskShape,
- BoundingRectShape,
- HeuristicMaskShape
- };
-
- QGraphicsPixmapItem(QGraphicsItem *parent = 0
-#ifndef Q_QDOC
- // ### obsolete argument
- , QGraphicsScene *scene = 0
-#endif
- );
- QGraphicsPixmapItem(const QPixmap &pixmap, QGraphicsItem *parent = 0
-#ifndef Q_QDOC
- // ### obsolete argument
- , QGraphicsScene *scene = 0
-#endif
- );
- ~QGraphicsPixmapItem();
-
- QPixmap pixmap() const;
- void setPixmap(const QPixmap &pixmap);
-
- Qt::TransformationMode transformationMode() const;
- void setTransformationMode(Qt::TransformationMode mode);
-
- QPointF offset() const;
- void setOffset(const QPointF &offset);
- inline void setOffset(qreal x, qreal y);
-
- QRectF boundingRect() const;
- QPainterPath shape() const;
- bool contains(const QPointF &point) const;
-
- void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
-
- bool isObscuredBy(const QGraphicsItem *item) const;
- QPainterPath opaqueArea() const;
-
- enum { Type = 7 };
- int type() const;
-
- ShapeMode shapeMode() const;
- void setShapeMode(ShapeMode mode);
-
-protected:
- bool supportsExtension(Extension extension) const;
- void setExtension(Extension extension, const QVariant &variant);
- QVariant extension(const QVariant &variant) const;
-
-private:
- Q_DISABLE_COPY(QGraphicsPixmapItem)
- Q_DECLARE_PRIVATE(QGraphicsPixmapItem)
-};
-
-inline void QGraphicsPixmapItem::setOffset(qreal ax, qreal ay)
-{ setOffset(QPointF(ax, ay)); }
-
-class QGraphicsTextItemPrivate;
-class QTextDocument;
-class QTextCursor;
-class Q_GUI_EXPORT QGraphicsTextItem : public QGraphicsObject
-{
- Q_OBJECT
- QDOC_PROPERTY(bool openExternalLinks READ openExternalLinks WRITE setOpenExternalLinks)
- QDOC_PROPERTY(QTextCursor textCursor READ textCursor WRITE setTextCursor)
-
-public:
- QGraphicsTextItem(QGraphicsItem *parent = 0
-#ifndef Q_QDOC
- // ### obsolete argument
- , QGraphicsScene *scene = 0
-#endif
- );
- QGraphicsTextItem(const QString &text, QGraphicsItem *parent = 0
-#ifndef Q_QDOC
- // ### obsolete argument
- , QGraphicsScene *scene = 0
-#endif
- );
- ~QGraphicsTextItem();
-
- QString toHtml() const;
- void setHtml(const QString &html);
-
- QString toPlainText() const;
- void setPlainText(const QString &text);
-
- QFont font() const;
- void setFont(const QFont &font);
-
- void setDefaultTextColor(const QColor &c);
- QColor defaultTextColor() const;
-
- QRectF boundingRect() const;
- QPainterPath shape() const;
- bool contains(const QPointF &point) const;
-
- void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
-
- bool isObscuredBy(const QGraphicsItem *item) const;
- QPainterPath opaqueArea() const;
-
- enum { Type = 8 };
- int type() const;
-
- void setTextWidth(qreal width);
- qreal textWidth() const;
-
- void adjustSize();
-
- void setDocument(QTextDocument *document);
- QTextDocument *document() const;
-
- void setTextInteractionFlags(Qt::TextInteractionFlags flags);
- Qt::TextInteractionFlags textInteractionFlags() const;
-
- void setTabChangesFocus(bool b);
- bool tabChangesFocus() const;
-
- void setOpenExternalLinks(bool open);
- bool openExternalLinks() const;
-
- void setTextCursor(const QTextCursor &cursor);
- QTextCursor textCursor() const;
-
-Q_SIGNALS:
- void linkActivated(const QString &);
- void linkHovered(const QString &);
-
-protected:
- bool sceneEvent(QEvent *event);
- void mousePressEvent(QGraphicsSceneMouseEvent *event);
- void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
- void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
- void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event);
- void contextMenuEvent(QGraphicsSceneContextMenuEvent *event);
- void keyPressEvent(QKeyEvent *event);
- void keyReleaseEvent(QKeyEvent *event);
- void focusInEvent(QFocusEvent *event);
- void focusOutEvent(QFocusEvent *event);
- void dragEnterEvent(QGraphicsSceneDragDropEvent *event);
- void dragLeaveEvent(QGraphicsSceneDragDropEvent *event);
- void dragMoveEvent(QGraphicsSceneDragDropEvent *event);
- void dropEvent(QGraphicsSceneDragDropEvent *event);
- void inputMethodEvent(QInputMethodEvent *event);
- void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
- void hoverMoveEvent(QGraphicsSceneHoverEvent *event);
- void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
-
- QVariant inputMethodQuery(Qt::InputMethodQuery query) const;
-
- bool supportsExtension(Extension extension) const;
- void setExtension(Extension extension, const QVariant &variant);
- QVariant extension(const QVariant &variant) const;
-
-private:
- Q_DISABLE_COPY(QGraphicsTextItem)
- Q_PRIVATE_SLOT(dd, void _q_updateBoundingRect(const QSizeF &))
- Q_PRIVATE_SLOT(dd, void _q_update(QRectF))
- Q_PRIVATE_SLOT(dd, void _q_ensureVisible(QRectF))
- QGraphicsTextItemPrivate *dd;
- friend class QGraphicsTextItemPrivate;
-};
-
-class QGraphicsSimpleTextItemPrivate;
-class Q_GUI_EXPORT QGraphicsSimpleTextItem : public QAbstractGraphicsShapeItem
-{
-public:
- QGraphicsSimpleTextItem(QGraphicsItem *parent = 0
-#ifndef Q_QDOC
- // ### obsolete argument
- , QGraphicsScene *scene = 0
-#endif
- );
- QGraphicsSimpleTextItem(const QString &text, QGraphicsItem *parent = 0
-#ifndef Q_QDOC
- // ### obsolete argument
- , QGraphicsScene *scene = 0
-#endif
- );
- ~QGraphicsSimpleTextItem();
-
- void setText(const QString &text);
- QString text() const;
-
- void setFont(const QFont &font);
- QFont font() const;
-
- QRectF boundingRect() const;
- QPainterPath shape() const;
- bool contains(const QPointF &point) const;
-
- void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
-
- bool isObscuredBy(const QGraphicsItem *item) const;
- QPainterPath opaqueArea() const;
-
- enum { Type = 9 };
- int type() const;
-
-protected:
- bool supportsExtension(Extension extension) const;
- void setExtension(Extension extension, const QVariant &variant);
- QVariant extension(const QVariant &variant) const;
-
-private:
- Q_DISABLE_COPY(QGraphicsSimpleTextItem)
- Q_DECLARE_PRIVATE(QGraphicsSimpleTextItem)
-};
-
-class QGraphicsItemGroupPrivate;
-class Q_GUI_EXPORT QGraphicsItemGroup : public QGraphicsItem
-{
-public:
- QGraphicsItemGroup(QGraphicsItem *parent = 0
-#ifndef Q_QDOC
- // ### obsolete argument
- , QGraphicsScene *scene = 0
-#endif
- );
- ~QGraphicsItemGroup();
-
- void addToGroup(QGraphicsItem *item);
- void removeFromGroup(QGraphicsItem *item);
-
- QRectF boundingRect() const;
- void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
-
- bool isObscuredBy(const QGraphicsItem *item) const;
- QPainterPath opaqueArea() const;
-
- enum { Type = 10 };
- int type() const;
-
-private:
- Q_DISABLE_COPY(QGraphicsItemGroup)
- Q_DECLARE_PRIVATE(QGraphicsItemGroup)
-};
-
-template <class T> inline T qgraphicsitem_cast(QGraphicsItem *item)
-{
- return int(static_cast<T>(0)->Type) == int(QGraphicsItem::Type)
- || (item && int(static_cast<T>(0)->Type) == item->type()) ? static_cast<T>(item) : 0;
-}
-
-template <class T> inline T qgraphicsitem_cast(const QGraphicsItem *item)
-{
- return int(static_cast<T>(0)->Type) == int(QGraphicsItem::Type)
- || (item && int(static_cast<T>(0)->Type) == item->type()) ? static_cast<T>(item) : 0;
-}
-
-#ifndef QT_NO_DEBUG_STREAM
-Q_GUI_EXPORT QDebug operator<<(QDebug debug, QGraphicsItem *item);
-Q_GUI_EXPORT QDebug operator<<(QDebug debug, QGraphicsObject *item);
-Q_GUI_EXPORT QDebug operator<<(QDebug debug, QGraphicsItem::GraphicsItemChange change);
-Q_GUI_EXPORT QDebug operator<<(QDebug debug, QGraphicsItem::GraphicsItemFlag flag);
-Q_GUI_EXPORT QDebug operator<<(QDebug debug, QGraphicsItem::GraphicsItemFlags flags);
-#endif
-
-QT_END_NAMESPACE
-
-Q_DECLARE_METATYPE(QGraphicsItem *)
-Q_DECLARE_METATYPE(QGraphicsScene *)
-
-QT_BEGIN_NAMESPACE
-
-#endif // QT_NO_GRAPHICSVIEW
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QGRAPHICSITEM_H
diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h
deleted file mode 100644
index afcb294442..0000000000
--- a/src/gui/graphicsview/qgraphicsitem_p.h
+++ /dev/null
@@ -1,891 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGRAPHICSITEM_P_H
-#define QGRAPHICSITEM_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qgraphicsitem.h"
-#include "qset.h"
-#include "qpixmapcache.h"
-#include <private/qgraphicsview_p.h>
-#include "qgraphicstransform.h"
-#include <private/qgraphicstransform_p.h>
-
-#include <private/qgraphicseffect_p.h>
-#include <qgraphicseffect.h>
-
-#include <QtCore/qpoint.h>
-
-#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW
-
-QT_BEGIN_NAMESPACE
-
-class QGraphicsItemPrivate;
-
-#ifndef QDECLARATIVELISTPROPERTY
-#define QDECLARATIVELISTPROPERTY
-template<typename T>
-class QDeclarativeListProperty {
-public:
- typedef void (*AppendFunction)(QDeclarativeListProperty<T> *, T*);
- typedef int (*CountFunction)(QDeclarativeListProperty<T> *);
- typedef T *(*AtFunction)(QDeclarativeListProperty<T> *, int);
- typedef void (*ClearFunction)(QDeclarativeListProperty<T> *);
-
- QDeclarativeListProperty()
- : object(0), data(0), append(0), count(0), at(0), clear(0), dummy1(0), dummy2(0) {}
- QDeclarativeListProperty(QObject *o, QList<T *> &list)
- : object(o), data(&list), append(qlist_append), count(qlist_count), at(qlist_at),
- clear(qlist_clear), dummy1(0), dummy2(0) {}
- QDeclarativeListProperty(QObject *o, void *d, AppendFunction a, CountFunction c = 0, AtFunction t = 0,
- ClearFunction r = 0)
- : object(o), data(d), append(a), count(c), at(t), clear(r), dummy1(0), dummy2(0) {}
-
- bool operator==(const QDeclarativeListProperty &o) const {
- return object == o.object &&
- data == o.data &&
- append == o.append &&
- count == o.count &&
- at == o.at &&
- clear == o.clear;
- }
-
- QObject *object;
- void *data;
-
- AppendFunction append;
-
- CountFunction count;
- AtFunction at;
-
- ClearFunction clear;
-
- void *dummy1;
- void *dummy2;
-
-private:
- static void qlist_append(QDeclarativeListProperty *p, T *v) {
- ((QList<T *> *)p->data)->append(v);
- }
- static int qlist_count(QDeclarativeListProperty *p) {
- return ((QList<T *> *)p->data)->count();
- }
- static T *qlist_at(QDeclarativeListProperty *p, int idx) {
- return ((QList<T *> *)p->data)->at(idx);
- }
- static void qlist_clear(QDeclarativeListProperty *p) {
- return ((QList<T *> *)p->data)->clear();
- }
-};
-#endif
-
-class QGraphicsItemCache
-{
-public:
- QGraphicsItemCache() : allExposed(false) { }
-
- // ItemCoordinateCache only
- QRect boundingRect;
- QSize fixedSize;
- QPixmapCache::Key key;
-
- // DeviceCoordinateCache only
- struct DeviceData {
- DeviceData() {}
- QTransform lastTransform;
- QPoint cacheIndent;
- QPixmapCache::Key key;
- };
- QMap<QPaintDevice *, DeviceData> deviceData;
-
- // List of logical exposed rects
- QVector<QRectF> exposed;
- bool allExposed;
-
- // Empty cache
- void purge();
-};
-
-class Q_GUI_EXPORT QGraphicsItemPrivate
-{
- Q_DECLARE_PUBLIC(QGraphicsItem)
-public:
- enum Extra {
- ExtraToolTip,
- ExtraCursor,
- ExtraCacheData,
- ExtraMaxDeviceCoordCacheSize,
- ExtraBoundingRegionGranularity
- };
-
- enum AncestorFlag {
- NoFlag = 0,
- AncestorHandlesChildEvents = 0x1,
- AncestorClipsChildren = 0x2,
- AncestorIgnoresTransformations = 0x4,
- AncestorFiltersChildEvents = 0x8
- };
-
- inline QGraphicsItemPrivate()
- : z(0),
- opacity(1.),
- scene(0),
- parent(0),
- transformData(0),
- graphicsEffect(0),
- index(-1),
- siblingIndex(-1),
- itemDepth(-1),
- focusProxy(0),
- subFocusItem(0),
- focusScopeItem(0),
- imHints(Qt::ImhNone),
- panelModality(QGraphicsItem::NonModal),
- acceptedMouseButtons(0x1f),
- visible(1),
- explicitlyHidden(0),
- enabled(1),
- explicitlyDisabled(0),
- selected(0),
- acceptsHover(0),
- acceptDrops(0),
- isMemberOfGroup(0),
- handlesChildEvents(0),
- itemDiscovered(0),
- hasCursor(0),
- ancestorFlags(0),
- cacheMode(0),
- hasBoundingRegionGranularity(0),
- isWidget(0),
- dirty(0),
- dirtyChildren(0),
- localCollisionHack(0),
- inSetPosHelper(0),
- needSortChildren(0),
- allChildrenDirty(0),
- fullUpdatePending(0),
- dirtyChildrenBoundingRect(1),
- flags(0),
- paintedViewBoundingRectsNeedRepaint(0),
- dirtySceneTransform(1),
- geometryChanged(1),
- inDestructor(0),
- isObject(0),
- ignoreVisible(0),
- ignoreOpacity(0),
- acceptTouchEvents(0),
- acceptedTouchBeginEvent(0),
- filtersDescendantEvents(0),
- sceneTransformTranslateOnly(0),
- notifyBoundingRectChanged(0),
- notifyInvalidated(0),
- mouseSetsFocus(1),
- explicitActivate(0),
- wantsActive(0),
- holesInSiblingIndex(0),
- sequentialOrdering(1),
- updateDueToGraphicsEffect(0),
- scenePosDescendants(0),
- pendingPolish(0),
- mayHaveChildWithGraphicsEffect(0),
- isDeclarativeItem(0),
- sendParentChangeNotification(0),
- globalStackingOrder(-1),
- q_ptr(0)
- {
- }
-
- inline virtual ~QGraphicsItemPrivate()
- { }
-
- static const QGraphicsItemPrivate *get(const QGraphicsItem *item)
- {
- return item->d_ptr.data();
- }
- static QGraphicsItemPrivate *get(QGraphicsItem *item)
- {
- return item->d_ptr.data();
- }
-
- void updateChildWithGraphicsEffectFlagRecursively();
- void updateAncestorFlag(QGraphicsItem::GraphicsItemFlag childFlag,
- AncestorFlag flag = NoFlag, bool enabled = false, bool root = true);
- void updateAncestorFlags();
- void setIsMemberOfGroup(bool enabled);
- void remapItemPos(QEvent *event, QGraphicsItem *item);
- QPointF genericMapFromScene(const QPointF &pos, const QWidget *viewport) const;
- inline bool itemIsUntransformable() const
- {
- return (flags & QGraphicsItem::ItemIgnoresTransformations)
- || (ancestorFlags & AncestorIgnoresTransformations);
- }
-
- void combineTransformToParent(QTransform *x, const QTransform *viewTransform = 0) const;
- void combineTransformFromParent(QTransform *x, const QTransform *viewTransform = 0) const;
- virtual void updateSceneTransformFromParent();
-
- // ### Qt 5: Remove. Workaround for reimplementation added after Qt 4.4.
- virtual QVariant inputMethodQueryHelper(Qt::InputMethodQuery query) const;
- static bool movableAncestorIsSelected(const QGraphicsItem *item);
-
- virtual void setPosHelper(const QPointF &pos);
- void setTransformHelper(const QTransform &transform);
- void prependGraphicsTransform(QGraphicsTransform *t);
- void appendGraphicsTransform(QGraphicsTransform *t);
- void setVisibleHelper(bool newVisible, bool explicitly, bool update = true);
- void setEnabledHelper(bool newEnabled, bool explicitly, bool update = true);
- bool discardUpdateRequest(bool ignoreVisibleBit = false,
- bool ignoreDirtyBit = false, bool ignoreOpacity = false) const;
- virtual void transformChanged() {}
- int depth() const;
-#ifndef QT_NO_GRAPHICSEFFECT
- enum InvalidateReason {
- OpacityChanged
- };
- void invalidateParentGraphicsEffectsRecursively();
- void invalidateChildGraphicsEffectsRecursively(InvalidateReason reason);
-#endif //QT_NO_GRAPHICSEFFECT
- void invalidateDepthRecursively();
- void resolveDepth();
- void addChild(QGraphicsItem *child);
- void removeChild(QGraphicsItem *child);
- QDeclarativeListProperty<QGraphicsObject> childrenList();
- void setParentItemHelper(QGraphicsItem *parent, const QVariant *newParentVariant,
- const QVariant *thisPointerVariant);
- void childrenBoundingRectHelper(QTransform *x, QRectF *rect, QGraphicsItem *topMostEffectItem);
- void initStyleOption(QStyleOptionGraphicsItem *option, const QTransform &worldTransform,
- const QRegion &exposedRegion, bool allItems = false) const;
- QRectF effectiveBoundingRect(QGraphicsItem *topMostEffectItem = 0) const;
- QRectF sceneEffectiveBoundingRect() const;
-
- QRectF effectiveBoundingRect(const QRectF &rect) const;
-
- virtual void resolveFont(uint inheritedMask)
- {
- for (int i = 0; i < children.size(); ++i)
- children.at(i)->d_ptr->resolveFont(inheritedMask);
- }
-
- virtual void resolvePalette(uint inheritedMask)
- {
- for (int i = 0; i < children.size(); ++i)
- children.at(i)->d_ptr->resolveFont(inheritedMask);
- }
-
- virtual bool isProxyWidget() const;
-
- inline QVariant extra(Extra type) const
- {
- for (int i = 0; i < extras.size(); ++i) {
- const ExtraStruct &extra = extras.at(i);
- if (extra.type == type)
- return extra.value;
- }
- return QVariant();
- }
-
- inline void setExtra(Extra type, const QVariant &value)
- {
- int index = -1;
- for (int i = 0; i < extras.size(); ++i) {
- if (extras.at(i).type == type) {
- index = i;
- break;
- }
- }
-
- if (index == -1) {
- extras << ExtraStruct(type, value);
- } else {
- extras[index].value = value;
- }
- }
-
- inline void unsetExtra(Extra type)
- {
- for (int i = 0; i < extras.size(); ++i) {
- if (extras.at(i).type == type) {
- extras.removeAt(i);
- return;
- }
- }
- }
-
- struct ExtraStruct {
- ExtraStruct(Extra type, QVariant value)
- : type(type), value(value)
- { }
-
- Extra type;
- QVariant value;
-
- bool operator<(Extra extra) const
- { return type < extra; }
- };
-
- QList<ExtraStruct> extras;
-
- QGraphicsItemCache *maybeExtraItemCache() const;
- QGraphicsItemCache *extraItemCache() const;
- void removeExtraItemCache();
-
- void updatePaintedViewBoundingRects(bool updateChildren);
- void ensureSceneTransformRecursive(QGraphicsItem **topMostDirtyItem);
- inline void ensureSceneTransform()
- {
- QGraphicsItem *that = q_func();
- ensureSceneTransformRecursive(&that);
- }
-
- inline bool hasTranslateOnlySceneTransform()
- {
- ensureSceneTransform();
- return sceneTransformTranslateOnly;
- }
-
- inline void invalidateChildrenSceneTransform()
- {
- for (int i = 0; i < children.size(); ++i)
- children.at(i)->d_ptr->dirtySceneTransform = 1;
- }
-
- inline qreal calcEffectiveOpacity() const
- {
- qreal o = opacity;
- QGraphicsItem *p = parent;
- int myFlags = flags;
- while (p) {
- int parentFlags = p->d_ptr->flags;
-
- // If I have a parent, and I don't ignore my parent's opacity, and my
- // parent propagates to me, then combine my local opacity with my parent's
- // effective opacity into my effective opacity.
- if ((myFlags & QGraphicsItem::ItemIgnoresParentOpacity)
- || (parentFlags & QGraphicsItem::ItemDoesntPropagateOpacityToChildren)) {
- break;
- }
-
- o *= p->d_ptr->opacity;
- p = p->d_ptr->parent;
- myFlags = parentFlags;
- }
- return o;
- }
-
- inline bool isOpacityNull() const
- { return (opacity < qreal(0.001)); }
-
- static inline bool isOpacityNull(qreal opacity)
- { return (opacity < qreal(0.001)); }
-
- inline bool isFullyTransparent() const
- {
- if (isOpacityNull())
- return true;
- if (!parent)
- return false;
-
- return isOpacityNull(calcEffectiveOpacity());
- }
-
- inline qreal effectiveOpacity() const {
- if (!parent || !opacity)
- return opacity;
-
- return calcEffectiveOpacity();
- }
-
- inline qreal combineOpacityFromParent(qreal parentOpacity) const
- {
- if (parent && !(flags & QGraphicsItem::ItemIgnoresParentOpacity)
- && !(parent->d_ptr->flags & QGraphicsItem::ItemDoesntPropagateOpacityToChildren)) {
- return parentOpacity * opacity;
- }
- return opacity;
- }
-
- inline bool childrenCombineOpacity() const
- {
- if (!children.size())
- return true;
- if (flags & QGraphicsItem::ItemDoesntPropagateOpacityToChildren)
- return false;
-
- for (int i = 0; i < children.size(); ++i) {
- if (children.at(i)->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity)
- return false;
- }
- return true;
- }
-
- inline bool childrenClippedToShape() const
- { return (flags & QGraphicsItem::ItemClipsChildrenToShape) || children.isEmpty(); }
-
- inline bool isInvisible() const
- {
- return !visible || (childrenCombineOpacity() && isFullyTransparent());
- }
-
- inline void markParentDirty(bool updateBoundingRect = false);
-
- void setFocusHelper(Qt::FocusReason focusReason, bool climb, bool focusFromHide);
- void clearFocusHelper(bool giveFocusToParent);
- void setSubFocus(QGraphicsItem *rootItem = 0, QGraphicsItem *stopItem = 0);
- void clearSubFocus(QGraphicsItem *rootItem = 0, QGraphicsItem *stopItem = 0);
- void resetFocusProxy();
- virtual void subFocusItemChange();
- virtual void focusScopeItemChange(bool isSubFocusItem);
-
- static void children_append(QDeclarativeListProperty<QGraphicsObject> *list, QGraphicsObject *item);
- static int children_count(QDeclarativeListProperty<QGraphicsObject> *list);
- static QGraphicsObject *children_at(QDeclarativeListProperty<QGraphicsObject> *list, int);
- static void children_clear(QDeclarativeListProperty<QGraphicsObject> *list);
-
- inline QTransform transformToParent() const;
- inline void ensureSortedChildren();
- static inline bool insertionOrder(QGraphicsItem *a, QGraphicsItem *b);
- void ensureSequentialSiblingIndex();
- inline void sendScenePosChange();
- virtual void siblingOrderChange();
-
- // Private Properties
- virtual qreal width() const;
- virtual void setWidth(qreal);
- virtual void resetWidth();
-
- virtual qreal height() const;
- virtual void setHeight(qreal);
- virtual void resetHeight();
-
- QRectF childrenBoundingRect;
- QRectF needsRepaint;
- QMap<QWidget *, QRect> paintedViewBoundingRects;
- QPointF pos;
- qreal z;
- qreal opacity;
- QGraphicsScene *scene;
- QGraphicsItem *parent;
- QList<QGraphicsItem *> children;
- struct TransformData;
- TransformData *transformData;
- QGraphicsEffect *graphicsEffect;
- QTransform sceneTransform;
- int index;
- int siblingIndex;
- int itemDepth; // Lazily calculated when calling depth().
- QGraphicsItem *focusProxy;
- QList<QGraphicsItem **> focusProxyRefs;
- QGraphicsItem *subFocusItem;
- QGraphicsItem *focusScopeItem;
- Qt::InputMethodHints imHints;
- QGraphicsItem::PanelModality panelModality;
-#ifndef QT_NO_GESTURES
- QMap<Qt::GestureType, Qt::GestureFlags> gestureContext;
-#endif
-
- // Packed 32 bits
- quint32 acceptedMouseButtons : 5;
- quint32 visible : 1;
- quint32 explicitlyHidden : 1;
- quint32 enabled : 1;
- quint32 explicitlyDisabled : 1;
- quint32 selected : 1;
- quint32 acceptsHover : 1;
- quint32 acceptDrops : 1;
- quint32 isMemberOfGroup : 1;
- quint32 handlesChildEvents : 1;
- quint32 itemDiscovered : 1;
- quint32 hasCursor : 1;
- quint32 ancestorFlags : 4;
- quint32 cacheMode : 2;
- quint32 hasBoundingRegionGranularity : 1;
- quint32 isWidget : 1;
- quint32 dirty : 1;
- quint32 dirtyChildren : 1;
- quint32 localCollisionHack : 1;
- quint32 inSetPosHelper : 1;
- quint32 needSortChildren : 1;
- quint32 allChildrenDirty : 1;
- quint32 fullUpdatePending : 1;
- quint32 dirtyChildrenBoundingRect : 1;
-
- // Packed 32 bits
- quint32 flags : 19;
- quint32 paintedViewBoundingRectsNeedRepaint : 1;
- quint32 dirtySceneTransform : 1;
- quint32 geometryChanged : 1;
- quint32 inDestructor : 1;
- quint32 isObject : 1;
- quint32 ignoreVisible : 1;
- quint32 ignoreOpacity : 1;
- quint32 acceptTouchEvents : 1;
- quint32 acceptedTouchBeginEvent : 1;
- quint32 filtersDescendantEvents : 1;
- quint32 sceneTransformTranslateOnly : 1;
- quint32 notifyBoundingRectChanged : 1;
- quint32 notifyInvalidated : 1;
-
- // New 32 bits
- quint32 mouseSetsFocus : 1;
- quint32 explicitActivate : 1;
- quint32 wantsActive : 1;
- quint32 holesInSiblingIndex : 1;
- quint32 sequentialOrdering : 1;
- quint32 updateDueToGraphicsEffect : 1;
- quint32 scenePosDescendants : 1;
- quint32 pendingPolish : 1;
- quint32 mayHaveChildWithGraphicsEffect : 1;
- quint32 isDeclarativeItem : 1;
- quint32 sendParentChangeNotification : 1;
- quint32 padding : 21;
-
- // Optional stacking order
- int globalStackingOrder;
- QGraphicsItem *q_ptr;
-};
-
-struct QGraphicsItemPrivate::TransformData
-{
- QTransform transform;
- qreal scale;
- qreal rotation;
- qreal xOrigin;
- qreal yOrigin;
- QList<QGraphicsTransform *> graphicsTransforms;
- bool onlyTransform;
-
- TransformData() :
- scale(1.0), rotation(0.0),
- xOrigin(0.0), yOrigin(0.0),
- onlyTransform(true)
- { }
-
- QTransform computedFullTransform(QTransform *postmultiplyTransform = 0) const
- {
- if (onlyTransform) {
- if (!postmultiplyTransform || postmultiplyTransform->isIdentity())
- return transform;
- if (transform.isIdentity())
- return *postmultiplyTransform;
- return transform * *postmultiplyTransform;
- }
-
- QTransform x(transform);
- if (!graphicsTransforms.isEmpty()) {
- QMatrix4x4 m;
- for (int i = 0; i < graphicsTransforms.size(); ++i)
- graphicsTransforms.at(i)->applyTo(&m);
- x *= m.toTransform();
- }
- x.translate(xOrigin, yOrigin);
- x.rotate(rotation);
- x.scale(scale, scale);
- x.translate(-xOrigin, -yOrigin);
- if (postmultiplyTransform)
- x *= *postmultiplyTransform;
- return x;
- }
-};
-
-struct QGraphicsItemPaintInfo
-{
- inline QGraphicsItemPaintInfo(const QTransform *const xform1, const QTransform *const xform2,
- const QTransform *const xform3,
- QRegion *r, QWidget *w, QStyleOptionGraphicsItem *opt,
- QPainter *p, qreal o, bool b1, bool b2)
- : viewTransform(xform1), transformPtr(xform2), effectTransform(xform3), exposedRegion(r), widget(w),
- option(opt), painter(p), opacity(o), wasDirtySceneTransform(b1), drawItem(b2)
- {}
-
- const QTransform *viewTransform;
- const QTransform *transformPtr;
- const QTransform *effectTransform;
- QRegion *exposedRegion;
- QWidget *widget;
- QStyleOptionGraphicsItem *option;
- QPainter *painter;
- qreal opacity;
- quint32 wasDirtySceneTransform : 1;
- quint32 drawItem : 1;
-};
-
-#ifndef QT_NO_GRAPHICSEFFECT
-class QGraphicsItemEffectSourcePrivate : public QGraphicsEffectSourcePrivate
-{
-public:
- QGraphicsItemEffectSourcePrivate(QGraphicsItem *i)
- : QGraphicsEffectSourcePrivate(), item(i), info(0)
- {}
-
- inline void detach()
- {
- item->d_ptr->graphicsEffect = 0;
- item->prepareGeometryChange();
- }
-
- inline const QGraphicsItem *graphicsItem() const
- { return item; }
-
- inline const QWidget *widget() const
- { return 0; }
-
- inline void update() {
- item->d_ptr->updateDueToGraphicsEffect = true;
- item->update();
- item->d_ptr->updateDueToGraphicsEffect = false;
- }
-
- inline void effectBoundingRectChanged()
- { item->prepareGeometryChange(); }
-
- inline bool isPixmap() const
- {
- return item->type() == QGraphicsPixmapItem::Type
- && !(item->flags() & QGraphicsItem::ItemIsSelectable)
- && item->d_ptr->children.size() == 0;
- //|| (item->d_ptr->isObject && qobject_cast<QDeclarativeImage *>(q_func()));
- }
-
- inline const QStyleOption *styleOption() const
- { return info ? info->option : 0; }
-
- inline QRect deviceRect() const
- {
- if (!info || !info->widget) {
- qWarning("QGraphicsEffectSource::deviceRect: Not yet implemented, lacking device context");
- return QRect();
- }
- return info->widget->rect();
- }
-
- QRectF boundingRect(Qt::CoordinateSystem system) const;
- void draw(QPainter *);
- QPixmap pixmap(Qt::CoordinateSystem system,
- QPoint *offset,
- QGraphicsEffect::PixmapPadMode mode) const;
- QRect paddedEffectRect(Qt::CoordinateSystem system, QGraphicsEffect::PixmapPadMode mode, const QRectF &sourceRect, bool *unpadded = 0) const;
-
- QGraphicsItem *item;
- QGraphicsItemPaintInfo *info;
- QTransform lastEffectTransform;
-};
-#endif //QT_NO_GRAPHICSEFFECT
-
-/*!
- Returns true if \a item1 is on top of \a item2.
- The items don't need to be siblings.
-
- \internal
-*/
-inline bool qt_closestItemFirst(const QGraphicsItem *item1, const QGraphicsItem *item2)
-{
- // Siblings? Just check their z-values.
- const QGraphicsItemPrivate *d1 = item1->d_ptr.data();
- const QGraphicsItemPrivate *d2 = item2->d_ptr.data();
- if (d1->parent == d2->parent)
- return qt_closestLeaf(item1, item2);
-
- // Find common ancestor, and each item's ancestor closest to the common
- // ancestor.
- int item1Depth = d1->depth();
- int item2Depth = d2->depth();
- const QGraphicsItem *p = item1;
- const QGraphicsItem *t1 = item1;
- while (item1Depth > item2Depth && (p = p->d_ptr->parent)) {
- if (p == item2) {
- // item2 is one of item1's ancestors; item1 is on top
- return !(t1->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent);
- }
- t1 = p;
- --item1Depth;
- }
- p = item2;
- const QGraphicsItem *t2 = item2;
- while (item2Depth > item1Depth && (p = p->d_ptr->parent)) {
- if (p == item1) {
- // item1 is one of item2's ancestors; item1 is not on top
- return (t2->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent);
- }
- t2 = p;
- --item2Depth;
- }
-
- // item1Ancestor is now at the same level as item2Ancestor, but not the same.
- const QGraphicsItem *p1 = t1;
- const QGraphicsItem *p2 = t2;
- while (t1 && t1 != t2) {
- p1 = t1;
- p2 = t2;
- t1 = t1->d_ptr->parent;
- t2 = t2->d_ptr->parent;
- }
-
- // in case we have a common ancestor, we compare the immediate children in the ancestor's path.
- // otherwise we compare the respective items' topLevelItems directly.
- return qt_closestLeaf(p1, p2);
-}
-
-/*!
- Returns true if \a item2 is on top of \a item1.
- The items don't need to be siblings.
-
- \internal
-*/
-inline bool qt_closestItemLast(const QGraphicsItem *item1, const QGraphicsItem *item2)
-{
- return qt_closestItemFirst(item2, item1);
-}
-
-/*!
- \internal
-*/
-inline bool qt_closestLeaf(const QGraphicsItem *item1, const QGraphicsItem *item2)
-{
- // Return true if sibling item1 is on top of item2.
- const QGraphicsItemPrivate *d1 = item1->d_ptr.data();
- const QGraphicsItemPrivate *d2 = item2->d_ptr.data();
- bool f1 = d1->flags & QGraphicsItem::ItemStacksBehindParent;
- bool f2 = d2->flags & QGraphicsItem::ItemStacksBehindParent;
- if (f1 != f2)
- return f2;
- if (d1->z != d2->z)
- return d1->z > d2->z;
- return d1->siblingIndex > d2->siblingIndex;
-}
-
-/*!
- \internal
-*/
-inline bool qt_notclosestLeaf(const QGraphicsItem *item1, const QGraphicsItem *item2)
-{ return qt_closestLeaf(item2, item1); }
-
-/*
- return the full transform of the item to the parent. This include the position and all the transform data
-*/
-inline QTransform QGraphicsItemPrivate::transformToParent() const
-{
- QTransform matrix;
- combineTransformToParent(&matrix);
- return matrix;
-}
-
-/*!
- \internal
-*/
-inline void QGraphicsItemPrivate::ensureSortedChildren()
-{
- if (needSortChildren) {
- needSortChildren = 0;
- sequentialOrdering = 1;
- if (children.isEmpty())
- return;
- qSort(children.begin(), children.end(), qt_notclosestLeaf);
- for (int i = 0; i < children.size(); ++i) {
- if (children.at(i)->d_ptr->siblingIndex != i) {
- sequentialOrdering = 0;
- break;
- }
- }
- }
-}
-
-/*!
- \internal
-*/
-inline bool QGraphicsItemPrivate::insertionOrder(QGraphicsItem *a, QGraphicsItem *b)
-{
- return a->d_ptr->siblingIndex < b->d_ptr->siblingIndex;
-}
-
-/*!
- \internal
-*/
-inline void QGraphicsItemPrivate::markParentDirty(bool updateBoundingRect)
-{
- QGraphicsItemPrivate *parentp = this;
-#ifndef QT_NO_GRAPHICSEFFECT
- if (updateBoundingRect && parentp->graphicsEffect && !parentp->inSetPosHelper) {
- parentp->notifyInvalidated = 1;
- static_cast<QGraphicsItemEffectSourcePrivate *>(parentp->graphicsEffect->d_func()
- ->source->d_func())->invalidateCache();
- }
-#endif
- while (parentp->parent) {
- parentp = parentp->parent->d_ptr.data();
- parentp->dirtyChildren = 1;
-
- if (updateBoundingRect) {
- parentp->dirtyChildrenBoundingRect = 1;
- // ### Only do this if the parent's effect applies to the entire subtree.
- parentp->notifyBoundingRectChanged = 1;
- }
-#ifndef QT_NO_GRAPHICSEFFECT
- if (parentp->graphicsEffect) {
- if (updateBoundingRect) {
- static_cast<QGraphicsItemEffectSourcePrivate *>(parentp->graphicsEffect->d_func()
- ->source->d_func())->invalidateCache();
- parentp->notifyInvalidated = 1;
- }
- if (parentp->scene && parentp->graphicsEffect->isEnabled()) {
- parentp->dirty = 1;
- parentp->fullUpdatePending = 1;
- }
- }
-#endif
- }
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_GRAPHICSVIEW
-
-#endif
diff --git a/src/gui/graphicsview/qgraphicsitemanimation.h b/src/gui/graphicsview/qgraphicsitemanimation.h
deleted file mode 100644
index e4296cbb7b..0000000000
--- a/src/gui/graphicsview/qgraphicsitemanimation.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGRAPHICSITEMANIMATION_H
-#define QGRAPHICSITEMANIMATION_H
-
-#include <QtCore/qobject.h>
-
-#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QGraphicsItem;
-class QMatrix;
-class QPointF;
-class QTimeLine;
-template <class T1, class T2> struct QPair;
-
-class QGraphicsItemAnimationPrivate;
-class Q_GUI_EXPORT QGraphicsItemAnimation : public QObject
-{
- Q_OBJECT
-public:
- QGraphicsItemAnimation(QObject *parent = 0);
- virtual ~QGraphicsItemAnimation();
-
- QGraphicsItem *item() const;
- void setItem(QGraphicsItem *item);
-
- QTimeLine *timeLine() const;
- void setTimeLine(QTimeLine *timeLine);
-
- QPointF posAt(qreal step) const;
- QList<QPair<qreal, QPointF> > posList() const;
- void setPosAt(qreal step, const QPointF &pos);
-
- QMatrix matrixAt(qreal step) const;
-
- qreal rotationAt(qreal step) const;
- QList<QPair<qreal, qreal> > rotationList() const;
- void setRotationAt(qreal step, qreal angle);
-
- qreal xTranslationAt(qreal step) const;
- qreal yTranslationAt(qreal step) const;
- QList<QPair<qreal, QPointF> > translationList() const;
- void setTranslationAt(qreal step, qreal dx, qreal dy);
-
- qreal verticalScaleAt(qreal step) const;
- qreal horizontalScaleAt(qreal step) const;
- QList<QPair<qreal, QPointF> > scaleList() const;
- void setScaleAt(qreal step, qreal sx, qreal sy);
-
- qreal verticalShearAt(qreal step) const;
- qreal horizontalShearAt(qreal step) const;
- QList<QPair<qreal, QPointF> > shearList() const;
- void setShearAt(qreal step, qreal sh, qreal sv);
-
- void clear();
-
-public Q_SLOTS:
- void setStep(qreal x);
- void reset();
-
-protected:
- virtual void beforeAnimationStep(qreal step);
- virtual void afterAnimationStep(qreal step);
-
-private:
- Q_DISABLE_COPY(QGraphicsItemAnimation)
- QGraphicsItemAnimationPrivate *d;
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QT_NO_GRAPHICSVIEW
-#endif
diff --git a/src/gui/graphicsview/qgraphicslayout.h b/src/gui/graphicsview/qgraphicslayout.h
deleted file mode 100644
index d5bc841854..0000000000
--- a/src/gui/graphicsview/qgraphicslayout.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGRAPHICSLAYOUT_H
-#define QGRAPHICSLAYOUT_H
-
-#include <QtGui/qgraphicslayoutitem.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW
-
-class QGraphicsLayoutPrivate;
-class QGraphicsLayoutItem;
-class QGraphicsWidget;
-
-class Q_GUI_EXPORT QGraphicsLayout : public QGraphicsLayoutItem
-{
-public:
- QGraphicsLayout(QGraphicsLayoutItem *parent = 0);
- ~QGraphicsLayout();
-
- void setContentsMargins(qreal left, qreal top, qreal right, qreal bottom);
- void getContentsMargins(qreal *left, qreal *top, qreal *right, qreal *bottom) const;
-
- void activate();
- bool isActivated() const;
- virtual void invalidate();
- virtual void updateGeometry();
-
- virtual void widgetEvent(QEvent *e);
-
- virtual int count() const = 0;
- virtual QGraphicsLayoutItem *itemAt(int i) const = 0;
- virtual void removeAt(int index) = 0;
-
- static void setInstantInvalidatePropagation(bool enable);
- static bool instantInvalidatePropagation();
-protected:
- QGraphicsLayout(QGraphicsLayoutPrivate &, QGraphicsLayoutItem *);
- void addChildLayoutItem(QGraphicsLayoutItem *layoutItem);
-
-private:
- Q_DISABLE_COPY(QGraphicsLayout)
- Q_DECLARE_PRIVATE(QGraphicsLayout)
- friend class QGraphicsWidget;
-};
-
-Q_DECLARE_INTERFACE(QGraphicsLayout, "com.trolltech.Qt.QGraphicsLayout")
-
-#endif
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif
-
diff --git a/src/gui/graphicsview/qgraphicslayout_p.h b/src/gui/graphicsview/qgraphicslayout_p.h
deleted file mode 100644
index 071a2ade25..0000000000
--- a/src/gui/graphicsview/qgraphicslayout_p.h
+++ /dev/null
@@ -1,154 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGRAPHICSLAYOUT_P_H
-#define QGRAPHICSLAYOUT_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/qglobal.h>
-
-#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW
-
-#include "qgraphicslayout.h"
-#include "qgraphicslayoutitem_p.h"
-#include <QtGui/qstyle.h>
-#include <QtGui/qwidget.h>
-#include <QtGui/qstyleoption.h>
-
-QT_BEGIN_NAMESPACE
-
-class QGraphicsLayoutItem;
-class QGraphicsWidget;
-
-#ifdef QT_DEBUG
-inline bool qt_graphicsLayoutDebug()
-{
- static int checked_env = -1;
- if(checked_env == -1)
- checked_env = !!qgetenv("QT_GRAPHICSLAYOUT_DEBUG").toInt();
- return checked_env;
-}
-#endif
-
-
-class QLayoutStyleInfo
-{
-public:
- inline QLayoutStyleInfo() { invalidate(); }
- inline QLayoutStyleInfo(QStyle *style, QWidget *widget)
- : m_valid(true), m_style(style), m_widget(widget)
- {
- Q_ASSERT(style);
- if (widget) //###
- m_styleOption.initFrom(widget);
- m_defaultSpacing[0] = style->pixelMetric(QStyle::PM_LayoutHorizontalSpacing);
- m_defaultSpacing[1] = style->pixelMetric(QStyle::PM_LayoutVerticalSpacing);
- }
-
- inline void invalidate() { m_valid = false; m_style = 0; m_widget = 0; }
-
- inline QStyle *style() const { return m_style; }
- inline QWidget *widget() const { return m_widget; }
-
- inline bool operator==(const QLayoutStyleInfo &other) const
- { return m_style == other.m_style && m_widget == other.m_widget; }
- inline bool operator!=(const QLayoutStyleInfo &other) const
- { return !(*this == other); }
-
- inline void setDefaultSpacing(Qt::Orientation o, qreal spacing){
- if (spacing >= 0)
- m_defaultSpacing[o - 1] = spacing;
- }
-
- inline qreal defaultSpacing(Qt::Orientation o) const {
- return m_defaultSpacing[o - 1];
- }
-
- inline qreal perItemSpacing(QSizePolicy::ControlType control1,
- QSizePolicy::ControlType control2,
- Qt::Orientation orientation) const
- {
- Q_ASSERT(style());
- return style()->layoutSpacing(control1, control2, orientation, &m_styleOption, widget());
- }
-private:
- bool m_valid;
- QStyle *m_style;
- QWidget *m_widget;
- QStyleOption m_styleOption;
- qreal m_defaultSpacing[2];
-};
-
-class Q_AUTOTEST_EXPORT QGraphicsLayoutPrivate : public QGraphicsLayoutItemPrivate
-{
- Q_DECLARE_PUBLIC(QGraphicsLayout)
-
-public:
- QGraphicsLayoutPrivate() : QGraphicsLayoutItemPrivate(0, true), left(-1.0), top(-1.0), right(-1.0), bottom(-1.0),
- activated(true) { }
-
- void reparentChildItems(QGraphicsItem *newParent);
- void getMargin(qreal *result, qreal userMargin, QStyle::PixelMetric pm) const;
- Qt::LayoutDirection visualDirection() const;
-
- void addChildLayoutItem(QGraphicsLayoutItem *item);
- void activateRecursive(QGraphicsLayoutItem *item);
-
- qreal left, top, right, bottom;
- bool activated;
-};
-
-
-QT_END_NAMESPACE
-
-#endif //QT_NO_GRAPHICSVIEW
-
-#endif
diff --git a/src/gui/graphicsview/qgraphicslayoutitem.h b/src/gui/graphicsview/qgraphicslayoutitem.h
deleted file mode 100644
index 12c1b892c4..0000000000
--- a/src/gui/graphicsview/qgraphicslayoutitem.h
+++ /dev/null
@@ -1,155 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGRAPHICSLAYOUTITEM_H
-#define QGRAPHICSLAYOUTITEM_H
-
-#include <QtCore/qscopedpointer.h>
-#include <QtGui/qsizepolicy.h>
-#include <QtGui/qevent.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW
-
-class QGraphicsLayoutItemPrivate;
-class QGraphicsItem;
-class Q_GUI_EXPORT QGraphicsLayoutItem
-{
-public:
- QGraphicsLayoutItem(QGraphicsLayoutItem *parent = 0, bool isLayout = false);
- virtual ~QGraphicsLayoutItem();
-
- void setSizePolicy(const QSizePolicy &policy);
- void setSizePolicy(QSizePolicy::Policy hPolicy, QSizePolicy::Policy vPolicy, QSizePolicy::ControlType controlType = QSizePolicy::DefaultType);
- QSizePolicy sizePolicy() const;
-
- void setMinimumSize(const QSizeF &size);
- inline void setMinimumSize(qreal w, qreal h);
- QSizeF minimumSize() const;
- void setMinimumWidth(qreal width);
- inline qreal minimumWidth() const;
- void setMinimumHeight(qreal height);
- inline qreal minimumHeight() const;
-
- void setPreferredSize(const QSizeF &size);
- inline void setPreferredSize(qreal w, qreal h);
- QSizeF preferredSize() const;
- void setPreferredWidth(qreal width);
- inline qreal preferredWidth() const;
- void setPreferredHeight(qreal height);
- inline qreal preferredHeight() const;
-
- void setMaximumSize(const QSizeF &size);
- inline void setMaximumSize(qreal w, qreal h);
- QSizeF maximumSize() const;
- void setMaximumWidth(qreal width);
- inline qreal maximumWidth() const;
- void setMaximumHeight(qreal height);
- inline qreal maximumHeight() const;
-
- virtual void setGeometry(const QRectF &rect);
- QRectF geometry() const;
- virtual void getContentsMargins(qreal *left, qreal *top, qreal *right, qreal *bottom) const;
- QRectF contentsRect() const;
-
- QSizeF effectiveSizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const;
-
- virtual void updateGeometry(); //### rename to sizeHintChanged()
-
- QGraphicsLayoutItem *parentLayoutItem() const;
- void setParentLayoutItem(QGraphicsLayoutItem *parent);
-
- bool isLayout() const;
- // ###Qt5: Make automatic reparenting work regardless of item/object/widget type.
- QGraphicsItem *graphicsItem() const;
- bool ownedByLayout() const;
-
-protected:
- void setGraphicsItem(QGraphicsItem *item);
- void setOwnedByLayout(bool ownedByLayout);
- QGraphicsLayoutItem(QGraphicsLayoutItemPrivate &dd);
-
- virtual QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const = 0;
- QScopedPointer<QGraphicsLayoutItemPrivate> d_ptr;
-
-private:
- QSizeF *effectiveSizeHints(const QSizeF &constraint) const;
- Q_DECLARE_PRIVATE(QGraphicsLayoutItem)
-
- friend class QGraphicsLayout;
-};
-
-Q_DECLARE_INTERFACE(QGraphicsLayoutItem, "com.trolltech.Qt.QGraphicsLayoutItem")
-
-inline void QGraphicsLayoutItem::setMinimumSize(qreal aw, qreal ah)
-{ setMinimumSize(QSizeF(aw, ah)); }
-inline void QGraphicsLayoutItem::setPreferredSize(qreal aw, qreal ah)
-{ setPreferredSize(QSizeF(aw, ah)); }
-inline void QGraphicsLayoutItem::setMaximumSize(qreal aw, qreal ah)
-{ setMaximumSize(QSizeF(aw, ah)); }
-
-inline qreal QGraphicsLayoutItem::minimumWidth() const
-{ return effectiveSizeHint(Qt::MinimumSize).width(); }
-inline qreal QGraphicsLayoutItem::minimumHeight() const
-{ return effectiveSizeHint(Qt::MinimumSize).height(); }
-
-inline qreal QGraphicsLayoutItem::preferredWidth() const
-{ return effectiveSizeHint(Qt::PreferredSize).width(); }
-inline qreal QGraphicsLayoutItem::preferredHeight() const
-{ return effectiveSizeHint(Qt::PreferredSize).height(); }
-
-inline qreal QGraphicsLayoutItem::maximumWidth() const
-{ return effectiveSizeHint(Qt::MaximumSize).width(); }
-inline qreal QGraphicsLayoutItem::maximumHeight() const
-{ return effectiveSizeHint(Qt::MaximumSize).height(); }
-
-#endif
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif
diff --git a/src/gui/graphicsview/qgraphicslayoutitem_p.h b/src/gui/graphicsview/qgraphicslayoutitem_p.h
deleted file mode 100644
index c44dd81d29..0000000000
--- a/src/gui/graphicsview/qgraphicslayoutitem_p.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGRAPHICSLAYOUTITEM_P_H
-#define QGRAPHICSLAYOUTITEM_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/QSizeF>
-#include <QtGui/QSizePolicy>
-
-QT_BEGIN_NAMESPACE
-
-class QGraphicsLayoutItem;
-class Q_AUTOTEST_EXPORT QGraphicsLayoutItemPrivate
-{
- Q_DECLARE_PUBLIC(QGraphicsLayoutItem)
-public:
- virtual ~QGraphicsLayoutItemPrivate();
- QGraphicsLayoutItemPrivate(QGraphicsLayoutItem *parent, bool isLayout);
- static QGraphicsLayoutItemPrivate *get(QGraphicsLayoutItem *q) { return q->d_func();}
- static const QGraphicsLayoutItemPrivate *get(const QGraphicsLayoutItem *q) { return q->d_func();}
-
- void init();
- QSizeF *effectiveSizeHints(const QSizeF &constraint) const;
- QGraphicsItem *parentItem() const;
- void ensureUserSizeHints();
- void setSize(Qt::SizeHint which, const QSizeF &size);
- enum SizeComponent { Width, Height };
- void setSizeComponent(Qt::SizeHint which, SizeComponent component, qreal value);
-
- bool hasHeightForWidth() const;
- bool hasWidthForHeight() const;
-
- QSizePolicy sizePolicy;
- QGraphicsLayoutItem *parent;
-
- QSizeF *userSizeHints;
- mutable QSizeF cachedSizeHints[Qt::NSizeHints];
- mutable QSizeF cachedConstraint;
- mutable QSizeF cachedSizeHintsWithConstraints[Qt::NSizeHints];
-
- mutable quint32 sizeHintCacheDirty : 1;
- mutable quint32 sizeHintWithConstraintCacheDirty : 1;
- quint32 isLayout : 1;
- quint32 ownedByLayout : 1;
-
- QGraphicsLayoutItem *q_ptr;
- QRectF geom;
- QGraphicsItem *graphicsItem;
-};
-
-QT_END_NAMESPACE
-
-#endif //QGRAPHICSLAYOUTITEM_P_H
-
diff --git a/src/gui/graphicsview/qgraphicslinearlayout.h b/src/gui/graphicsview/qgraphicslinearlayout.h
deleted file mode 100644
index 031015c5eb..0000000000
--- a/src/gui/graphicsview/qgraphicslinearlayout.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGRAPHICSLINEARLAYOUT_H
-#define QGRAPHICSLINEARLAYOUT_H
-
-#include <QtGui/qgraphicsitem.h>
-#include <QtGui/qgraphicslayout.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW
-
-class QGraphicsLinearLayoutPrivate;
-
-class Q_GUI_EXPORT QGraphicsLinearLayout : public QGraphicsLayout
-{
-public:
- QGraphicsLinearLayout(QGraphicsLayoutItem *parent = 0);
- QGraphicsLinearLayout(Qt::Orientation orientation, QGraphicsLayoutItem *parent = 0);
- virtual ~QGraphicsLinearLayout();
-
- void setOrientation(Qt::Orientation orientation);
- Qt::Orientation orientation() const;
-
- inline void addItem(QGraphicsLayoutItem *item) { insertItem(-1, item); }
- inline void addStretch(int stretch = 1) { insertStretch(-1, stretch); }
-
- void insertItem(int index, QGraphicsLayoutItem *item);
- void insertStretch(int index, int stretch = 1);
-
- void removeItem(QGraphicsLayoutItem *item);
- void removeAt(int index);
-
- void setSpacing(qreal spacing);
- qreal spacing() const;
- void setItemSpacing(int index, qreal spacing);
- qreal itemSpacing(int index) const;
-
- void setStretchFactor(QGraphicsLayoutItem *item, int stretch);
- int stretchFactor(QGraphicsLayoutItem *item) const;
-
- void setAlignment(QGraphicsLayoutItem *item, Qt::Alignment alignment);
- Qt::Alignment alignment(QGraphicsLayoutItem *item) const;
-
- void setGeometry(const QRectF &rect);
-
- int count() const;
- QGraphicsLayoutItem *itemAt(int index) const;
-
- void invalidate();
- QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const;
-
-#if 0 // ###
- Q5SizePolicy::ControlTypes controlTypes(LayoutSide side) const;
-#endif
-
- void dump(int indent = 0) const;
-
-protected:
-#if 0
- QSize contentsSizeHint(Qt::SizeHint which, const QSize &constraint = QSize()) const;
-#endif
-
-private:
- Q_DISABLE_COPY(QGraphicsLinearLayout)
- Q_DECLARE_PRIVATE(QGraphicsLinearLayout)
-};
-
-#endif
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif
-
diff --git a/src/gui/graphicsview/qgraphicsproxywidget.cpp b/src/gui/graphicsview/qgraphicsproxywidget.cpp
deleted file mode 100644
index fad88f5764..0000000000
--- a/src/gui/graphicsview/qgraphicsproxywidget.cpp
+++ /dev/null
@@ -1,1569 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qglobal.h"
-
-#ifndef QT_NO_GRAPHICSVIEW
-
-#include "qgraphicslayout.h"
-#include "qgraphicsproxywidget.h"
-#include "private/qgraphicsproxywidget_p.h"
-#include "private/qwidget_p.h"
-#include "private/qapplication_p.h"
-
-#include <QtCore/qdebug.h>
-#include <QtGui/qevent.h>
-#include <QtGui/qgraphicsscene.h>
-#include <QtGui/qgraphicssceneevent.h>
-#include <QtGui/qlayout.h>
-#include <QtGui/qpainter.h>
-#include <QtGui/qstyleoption.h>
-#include <QtGui/qgraphicsview.h>
-#include <QtGui/qlistview.h>
-#include <QtGui/qlineedit.h>
-#include <QtGui/qtextedit.h>
-
-QT_BEGIN_NAMESPACE
-
-//#define GRAPHICSPROXYWIDGET_DEBUG
-
-/*!
- \class QGraphicsProxyWidget
- \brief The QGraphicsProxyWidget class provides a proxy layer for embedding
- a QWidget in a QGraphicsScene.
- \since 4.4
- \ingroup graphicsview-api
-
- QGraphicsProxyWidget embeds QWidget-based widgets, for example, a
- QPushButton, QFontComboBox, or even QFileDialog, into
- QGraphicsScene. It forwards events between the two objects and
- translates between QWidget's integer-based geometry and
- QGraphicsWidget's qreal-based geometry. QGraphicsProxyWidget
- supports all core features of QWidget, including tab focus,
- keyboard input, Drag & Drop, and popups. You can also embed
- complex widgets, e.g., widgets with subwidgets.
-
- Example:
-
- \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsproxywidget.cpp 0
-
- QGraphicsProxyWidget takes care of automatically embedding popup children
- of embedded widgets through creating a child proxy for each popup. This
- means that when an embedded QComboBox shows its popup list, a new
- QGraphicsProxyWidget is created automatically, embedding the popup, and
- positioning it correctly. This only works if the popup is child of the
- embedded widget (for example QToolButton::setMenu() requires the QMenu instance
- to be child of the QToolButton).
-
- \section1 Embedding a Widget with QGraphicsProxyWidget
-
- There are two ways to embed a widget using QGraphicsProxyWidget. The most
- common way is to pass a widget pointer to QGraphicsScene::addWidget()
- together with any relevant \l Qt::WindowFlags. This function returns a
- pointer to a QGraphicsProxyWidget. You can then choose to reparent or
- position either the proxy, or the embedded widget itself.
-
- For example, in the code snippet below, we embed a group box into the proxy:
-
- \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsproxywidget.cpp 1
-
- The image below is the output obtained with its contents margin and
- contents rect labeled.
-
- \image qgraphicsproxywidget-embed.png
-
- Alternatively, you can start by creating a new QGraphicsProxyWidget item,
- and then call setWidget() to embed a QWidget later. The widget() function
- returns a pointer to the embedded widget. QGraphicsProxyWidget shares
- ownership with QWidget, so if either of the two widgets are destroyed, the
- other widget will be automatically destroyed as well.
-
- \section1 Synchronizing Widget States
-
- QGraphicsProxyWidget keeps its state in sync with the embedded widget. For
- example, if the proxy is hidden or disabled, the embedded widget will be
- hidden or disabled as well, and vice versa. When the widget is embedded by
- calling addWidget(), QGraphicsProxyWidget copies the state from the widget
- into the proxy, and after that, the two will stay synchronized where
- possible. By default, when you embed a widget into a proxy, both the widget
- and the proxy will be visible because a QGraphicsWidget is visible when
- created (you do not have to call show()). If you explicitly hide the
- embedded widget, the proxy will also become invisible.
-
- Example:
-
- \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsproxywidget.cpp 2
-
- QGraphicsProxyWidget maintains symmetry for the following states:
-
- \table
- \header \o QWidget state \o QGraphicsProxyWidget state \o Notes
- \row \o QWidget::enabled
- \o QGraphicsProxyWidget::enabled
- \o
- \row \o QWidget::visible
- \o QGraphicsProxyWidget::visible
- \o The explicit state is also symmetric.
- \row \o QWidget::geometry
- \o QGraphicsProxyWidget::geometry
- \o Geometry is only guaranteed to be symmetric while
- the embedded widget is visible.
- \row \o QWidget::layoutDirection
- \o QGraphicsProxyWidget::layoutDirection
- \o
- \row \o QWidget::style
- \o QGraphicsProxyWidget::style
- \o
- \row \o QWidget::palette
- \o QGraphicsProxyWidget::palette
- \o
- \row \o QWidget::font
- \o QGraphicsProxyWidget::font
- \o
- \row \o QWidget::cursor
- \o QGraphicsProxyWidget::cursor
- \o The embedded widget overrides the proxy widget
- cursor. The proxy cursor changes depending on
- which embedded subwidget is currently under the
- mouse.
- \row \o QWidget::sizeHint()
- \o QGraphicsProxyWidget::sizeHint()
- \o All size hint functionality from the embedded
- widget is forwarded by the proxy.
- \row \o QWidget::getContentsMargins()
- \o QGraphicsProxyWidget::getContentsMargins()
- \o Updated once by setWidget().
- \row \o QWidget::windowTitle
- \o QGraphicsProxyWidget::windowTitle
- \o Updated once by setWidget().
- \endtable
-
- \note QGraphicsScene keeps the embedded widget in a special state that
- prevents it from disturbing other widgets (both embedded and not embedded)
- 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
-*/
-
-extern bool qt_sendSpontaneousEvent(QObject *, QEvent *);
-Q_GUI_EXPORT extern bool qt_tab_all_widgets;
-
-/*!
- \internal
-*/
-void QGraphicsProxyWidgetPrivate::init()
-{
- Q_Q(QGraphicsProxyWidget);
- q->setFocusPolicy(Qt::WheelFocus);
- q->setAcceptDrops(true);
-}
-
-/*!
- \internal
-*/
-void QGraphicsProxyWidgetPrivate::sendWidgetMouseEvent(QGraphicsSceneHoverEvent *event)
-{
- QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMouseMove);
- mouseEvent.setPos(event->pos());
- mouseEvent.setScreenPos(event->screenPos());
- mouseEvent.setButton(Qt::NoButton);
- mouseEvent.setButtons(0);
- mouseEvent.setModifiers(event->modifiers());
- sendWidgetMouseEvent(&mouseEvent);
- event->setAccepted(mouseEvent.isAccepted());
-}
-
-/*!
- \internal
-*/
-void QGraphicsProxyWidgetPrivate::sendWidgetMouseEvent(QGraphicsSceneMouseEvent *event)
-{
- if (!event || !widget || !widget->isVisible())
- return;
- Q_Q(QGraphicsProxyWidget);
-
- // Find widget position and receiver.
- QPointF pos = event->pos();
- QPointer<QWidget> alienWidget = widget->childAt(pos.toPoint());
- QPointer<QWidget> receiver = alienWidget ? alienWidget : widget;
-
- if (QWidgetPrivate::nearestGraphicsProxyWidget(receiver) != q)
- return; //another proxywidget will handle the events
-
- // Translate QGraphicsSceneMouse events to QMouseEvents.
- QEvent::Type type = QEvent::None;
- switch (event->type()) {
- case QEvent::GraphicsSceneMousePress:
- type = QEvent::MouseButtonPress;
- if (!embeddedMouseGrabber)
- embeddedMouseGrabber = receiver;
- else
- receiver = embeddedMouseGrabber;
- break;
- case QEvent::GraphicsSceneMouseRelease:
- type = QEvent::MouseButtonRelease;
- if (embeddedMouseGrabber)
- receiver = embeddedMouseGrabber;
- break;
- case QEvent::GraphicsSceneMouseDoubleClick:
- type = QEvent::MouseButtonDblClick;
- if (!embeddedMouseGrabber)
- embeddedMouseGrabber = receiver;
- else
- receiver = embeddedMouseGrabber;
- break;
- case QEvent::GraphicsSceneMouseMove:
- type = QEvent::MouseMove;
- if (embeddedMouseGrabber)
- receiver = embeddedMouseGrabber;
- break;
- default:
- Q_ASSERT_X(false, "QGraphicsProxyWidget", "internal error");
- break;
- }
-
- if (!lastWidgetUnderMouse) {
- QApplicationPrivate::dispatchEnterLeave(embeddedMouseGrabber ? embeddedMouseGrabber : receiver, 0);
- lastWidgetUnderMouse = receiver;
- }
-
- // Map event position from us to the receiver
- pos = mapToReceiver(pos, receiver);
-
- // Send mouse event.
- QMouseEvent mouseEvent(type, pos,
- receiver->mapToGlobal(pos.toPoint()), event->button(),
- event->buttons(), event->modifiers());
-
- QWidget *embeddedMouseGrabberPtr = (QWidget *)embeddedMouseGrabber;
- QApplicationPrivate::sendMouseEvent(receiver, &mouseEvent, alienWidget, widget,
- &embeddedMouseGrabberPtr, lastWidgetUnderMouse, event->spontaneous());
- embeddedMouseGrabber = embeddedMouseGrabberPtr;
-
- // Handle enter/leave events when last button is released from mouse
- // grabber child widget.
- if (embeddedMouseGrabber && type == QEvent::MouseButtonRelease && !event->buttons()) {
- Q_Q(QGraphicsProxyWidget);
- if (q->rect().contains(event->pos()) && q->acceptsHoverEvents())
- lastWidgetUnderMouse = alienWidget ? alienWidget : widget;
- else // released on the frame our outside the item, or doesn't accept hover events.
- lastWidgetUnderMouse = 0;
-
- QApplicationPrivate::dispatchEnterLeave(lastWidgetUnderMouse, embeddedMouseGrabber);
- embeddedMouseGrabber = 0;
-
-#ifndef QT_NO_CURSOR
- // ### Restore the cursor, don't override it.
- if (!lastWidgetUnderMouse)
- q->unsetCursor();
-#endif
- }
-
- event->setAccepted(mouseEvent.isAccepted());
-}
-
-void QGraphicsProxyWidgetPrivate::sendWidgetKeyEvent(QKeyEvent *event)
-{
- Q_Q(QGraphicsProxyWidget);
- if (!event || !widget || !widget->isVisible())
- return;
-
- QPointer<QWidget> receiver = widget->focusWidget();
- if (!receiver)
- receiver = widget;
- Q_ASSERT(receiver);
-
- do {
- bool res = QApplication::sendEvent(receiver, event);
- if ((res && event->isAccepted()) || (q->isWindow() && receiver == widget))
- break;
- receiver = receiver->parentWidget();
- } while (receiver);
-}
-
-/*!
- \internal
-*/
-void QGraphicsProxyWidgetPrivate::removeSubFocusHelper(QWidget *widget, Qt::FocusReason reason)
-{
- QFocusEvent event(QEvent::FocusOut, reason);
- QPointer<QWidget> widgetGuard = widget;
- QApplication::sendEvent(widget, &event);
- if (widgetGuard && event.isAccepted())
- QApplication::sendEvent(widget->style(), &event);
-}
-
-/*!
- \internal
-
- Reimplemented from QGraphicsItemPrivate. ### Qt 5: Move impl to
- reimplementation QGraphicsProxyWidget::inputMethodQuery().
-*/
-QVariant QGraphicsProxyWidgetPrivate::inputMethodQueryHelper(Qt::InputMethodQuery query) const
-{
- Q_Q(const QGraphicsProxyWidget);
- if (!widget || !q->hasFocus())
- return QVariant();
-
- QWidget *focusWidget = widget->focusWidget();
- if (!focusWidget)
- focusWidget = widget;
- QVariant v = focusWidget->inputMethodQuery(query);
- QPointF focusWidgetPos = q->subWidgetRect(focusWidget).topLeft();
- switch (v.type()) {
- case QVariant::RectF:
- v = v.toRectF().translated(focusWidgetPos);
- break;
- case QVariant::PointF:
- v = v.toPointF() + focusWidgetPos;
- break;
- case QVariant::Rect:
- v = v.toRect().translated(focusWidgetPos.toPoint());
- break;
- case QVariant::Point:
- v = v.toPoint() + focusWidgetPos.toPoint();
- break;
- default:
- break;
- }
- return v;
-}
-
-/*!
- \internal
- Some of the logic is shared with QApplicationPrivate::focusNextPrevChild_helper
-*/
-QWidget *QGraphicsProxyWidgetPrivate::findFocusChild(QWidget *child, bool next) const
-{
- if (!widget)
- return 0;
-
- // Run around the focus chain until we find a widget that can take tab focus.
- if (!child) {
- child = next ? (QWidget *)widget : widget->d_func()->focus_prev;
- } else {
- child = next ? child->d_func()->focus_next : child->d_func()->focus_prev;
- if ((next && child == widget) || (!next && child == widget->d_func()->focus_prev)) {
- return 0;
- }
- }
-
- QWidget *oldChild = child;
- uint focus_flag = qt_tab_all_widgets ? Qt::TabFocus : Qt::StrongFocus;
- do {
- if (child->isEnabled()
- && child->isVisibleTo(widget)
- && ((child->focusPolicy() & focus_flag) == focus_flag)
- && !(child->d_func()->extra && child->d_func()->extra->focus_proxy)) {
- return child;
- }
- child = next ? child->d_func()->focus_next : child->d_func()->focus_prev;
- } while (child != oldChild && !(next && child == widget) && !(!next && child == widget->d_func()->focus_prev));
- return 0;
-}
-
-/*!
- \internal
-*/
-void QGraphicsProxyWidgetPrivate::_q_removeWidgetSlot()
-{
- Q_Q(QGraphicsProxyWidget);
- widget = 0;
- delete q;
-}
-
-/*!
- \internal
-*/
-void QGraphicsProxyWidgetPrivate::updateWidgetGeometryFromProxy()
-{
-}
-
-/*!
- \internal
-*/
-void QGraphicsProxyWidgetPrivate::updateProxyGeometryFromWidget()
-{
- Q_Q(QGraphicsProxyWidget);
- if (!widget)
- return;
-
- QRectF widgetGeometry = widget->geometry();
- QWidget *parentWidget = widget->parentWidget();
- if (widget->isWindow()) {
- QGraphicsProxyWidget *proxyParent = 0;
- if (parentWidget && (proxyParent = qobject_cast<QGraphicsProxyWidget *>(q->parentWidget()))) {
- // Nested window proxy (e.g., combobox popup), map widget to the
- // parent widget's global coordinates, and map that to the parent
- // proxy's child coordinates.
- widgetGeometry.moveTo(proxyParent->subWidgetRect(parentWidget).topLeft()
- + parentWidget->mapFromGlobal(widget->pos()));
- }
- }
-
- // Adjust to size hint if the widget has never been resized.
- if (!widget->size().isValid())
- widgetGeometry.setSize(widget->sizeHint());
-
- // Assign new geometry.
- posChangeMode = QGraphicsProxyWidgetPrivate::WidgetToProxyMode;
- sizeChangeMode = QGraphicsProxyWidgetPrivate::WidgetToProxyMode;
- q->setGeometry(widgetGeometry);
- posChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
- sizeChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
-}
-
-/*!
- \internal
-*/
-void QGraphicsProxyWidgetPrivate::updateProxyInputMethodAcceptanceFromWidget()
-{
- Q_Q(QGraphicsProxyWidget);
- if (!widget)
- return;
-
- QWidget *focusWidget = widget->focusWidget();
- if (!focusWidget)
- focusWidget = widget;
- q->setFlag(QGraphicsItem::ItemAcceptsInputMethod,
- focusWidget->testAttribute(Qt::WA_InputMethodEnabled));
-}
-
-/*!
- \internal
-
- Embeds \a subWin as a subwindow of this proxy widget. \a subWin must be a top-level
- widget and a descendant of the widget managed by this proxy. A separate subproxy
- will be created as a child of this proxy widget to manage \a subWin.
-*/
-void QGraphicsProxyWidgetPrivate::embedSubWindow(QWidget *subWin)
-{
- QWExtra *extra;
- if (!((extra = subWin->d_func()->extra) && extra->proxyWidget)) {
- QGraphicsProxyWidget *subProxy = new QGraphicsProxyWidget(q_func(), subWin->windowFlags());
- subProxy->d_func()->setWidget_helper(subWin, false);
- }
-}
-
-/*!
- \internal
-
- Removes ("unembeds") \a subWin and deletes the proxy holder item. This can
- happen when QWidget::setParent() reparents the embedded window out of
- "embedded space".
-*/
-void QGraphicsProxyWidgetPrivate::unembedSubWindow(QWidget *subWin)
-{
- foreach (QGraphicsItem *child, children) {
- if (child->isWidget()) {
- if (QGraphicsProxyWidget *proxy = qobject_cast<QGraphicsProxyWidget *>(static_cast<QGraphicsWidget *>(child))) {
- if (proxy->widget() == subWin) {
- proxy->setWidget(0);
- scene->removeItem(proxy);
- delete proxy;
- return;
- }
- }
- }
- }
-}
-
-bool QGraphicsProxyWidgetPrivate::isProxyWidget() const
-{
- return true;
-}
-
-/*!
- \internal
-*/
-QPointF QGraphicsProxyWidgetPrivate::mapToReceiver(const QPointF &pos, const QWidget *receiver) const
-{
- QPointF p = pos;
- // Map event position from us to the receiver, preserving its
- // precision (don't use QWidget::mapFrom here).
- while (receiver && receiver != widget) {
- p -= QPointF(receiver->pos());
- receiver = receiver->parentWidget();
- }
- return p;
-}
-
-/*!
- Constructs a new QGraphicsProxy widget. \a parent and \a wFlags are passed
- to QGraphicsItem's constructor.
-*/
-QGraphicsProxyWidget::QGraphicsProxyWidget(QGraphicsItem *parent, Qt::WindowFlags wFlags)
- : QGraphicsWidget(*new QGraphicsProxyWidgetPrivate, parent, 0, wFlags)
-{
- Q_D(QGraphicsProxyWidget);
- d->init();
-}
-
-/*!
- Destroys the proxy widget and any embedded widget.
-*/
-QGraphicsProxyWidget::~QGraphicsProxyWidget()
-{
- Q_D(QGraphicsProxyWidget);
- if (d->widget) {
- QObject::disconnect(d->widget, SIGNAL(destroyed()), this, SLOT(_q_removeWidgetSlot()));
- delete d->widget;
- }
-}
-
-/*!
- Embeds \a widget into this proxy widget. The embedded widget must reside
- exclusively either inside or outside of Graphics View. You cannot embed a
- widget as long as it is is visible elsewhere in the UI, at the same time.
-
- \a widget must be a top-level widget whose parent is 0.
-
- When the widget is embedded, its state (e.g., visible, enabled, geometry,
- size hints) is copied into the proxy widget. If the embedded widget is
- explicitly hidden or disabled, the proxy widget will become explicitly
- hidden or disabled after embedding is complete. The class documentation
- has a full overview over the shared state.
-
- QGraphicsProxyWidget's window flags determine whether the widget, after
- embedding, will be given window decorations or not.
-
- After this function returns, QGraphicsProxyWidget will keep its state
- synchronized with that of \a widget whenever possible.
-
- If a widget is already embedded by this proxy when this function is
- called, that widget will first be automatically unembedded. Passing 0 for
- the \a widget argument will only unembed the widget, and the ownership of
- the currently embedded widget will be passed on to the caller.
- Every child widget that are embedded will also be embedded and their proxy
- widget destroyed.
-
- Note that widgets with the Qt::WA_PaintOnScreen widget attribute
- set and widgets that wrap an external application or controller
- cannot be embedded. Examples are QGLWidget and QAxWidget.
-
- \sa widget()
-*/
-void QGraphicsProxyWidget::setWidget(QWidget *widget)
-{
- Q_D(QGraphicsProxyWidget);
- d->setWidget_helper(widget, true);
-}
-
-void QGraphicsProxyWidgetPrivate::setWidget_helper(QWidget *newWidget, bool autoShow)
-{
- Q_Q(QGraphicsProxyWidget);
- if (newWidget == widget)
- return;
- if (widget) {
- QObject::disconnect(widget, SIGNAL(destroyed()), q, SLOT(_q_removeWidgetSlot()));
- widget->removeEventFilter(q);
- widget->setAttribute(Qt::WA_DontShowOnScreen, false);
- widget->d_func()->extra->proxyWidget = 0;
- resolveFont(inheritedFontResolveMask);
- resolvePalette(inheritedPaletteResolveMask);
- widget->update();
-
- foreach (QGraphicsItem *child, q->childItems()) {
- if (child->d_ptr->isProxyWidget()) {
- QGraphicsProxyWidget *childProxy = static_cast<QGraphicsProxyWidget *>(child);
- QWidget * parent = childProxy->widget();
- while (parent->parentWidget() != 0) {
- if (parent == widget)
- break;
- parent = parent->parentWidget();
- }
- if (!childProxy->widget() || parent != widget)
- continue;
- childProxy->setWidget(0);
- delete childProxy;
- }
- }
-
- widget = 0;
-#ifndef QT_NO_CURSOR
- q->unsetCursor();
-#endif
- q->setAcceptHoverEvents(false);
- if (!newWidget)
- q->update();
- }
- if (!newWidget)
- return;
- if (!newWidget->isWindow()) {
- QWExtra *extra = newWidget->parentWidget()->d_func()->extra;
- if (!extra || !extra->proxyWidget) {
- qWarning("QGraphicsProxyWidget::setWidget: cannot embed widget %p "
- "which is not a toplevel widget, and is not a child of an embedded widget", newWidget);
- return;
- }
- }
-
- // Register this proxy within the widget's private.
- // ### This is a bit backdoorish
- QWExtra *extra = newWidget->d_func()->extra;
- if (!extra) {
- newWidget->d_func()->createExtra();
- extra = newWidget->d_func()->extra;
- }
- QGraphicsProxyWidget **proxyWidget = &extra->proxyWidget;
- if (*proxyWidget) {
- if (*proxyWidget != q) {
- qWarning("QGraphicsProxyWidget::setWidget: cannot embed widget %p"
- "; already embedded", newWidget);
- }
- return;
- }
- *proxyWidget = q;
-
- newWidget->setAttribute(Qt::WA_DontShowOnScreen);
- newWidget->ensurePolished();
- // Do not wait for this widget to close before the app closes ###
- // shouldn't this widget inherit the attribute?
- newWidget->setAttribute(Qt::WA_QuitOnClose, false);
- q->setAcceptHoverEvents(true);
-
- if (newWidget->testAttribute(Qt::WA_NoSystemBackground))
- q->setAttribute(Qt::WA_NoSystemBackground);
- if (newWidget->testAttribute(Qt::WA_OpaquePaintEvent))
- q->setAttribute(Qt::WA_OpaquePaintEvent);
-
- widget = newWidget;
-
- // Changes only go from the widget to the proxy.
- enabledChangeMode = QGraphicsProxyWidgetPrivate::WidgetToProxyMode;
- visibleChangeMode = QGraphicsProxyWidgetPrivate::WidgetToProxyMode;
- posChangeMode = QGraphicsProxyWidgetPrivate::WidgetToProxyMode;
- sizeChangeMode = QGraphicsProxyWidgetPrivate::WidgetToProxyMode;
-
- if ((autoShow && !newWidget->testAttribute(Qt::WA_WState_ExplicitShowHide)) || !newWidget->testAttribute(Qt::WA_WState_Hidden)) {
- newWidget->show();
- }
-
- // Copy the state from the widget onto the proxy.
-#ifndef QT_NO_CURSOR
- if (newWidget->testAttribute(Qt::WA_SetCursor))
- q->setCursor(widget->cursor());
-#endif
- q->setEnabled(newWidget->isEnabled());
- q->setVisible(newWidget->isVisible());
- q->setLayoutDirection(newWidget->layoutDirection());
- if (newWidget->testAttribute(Qt::WA_SetStyle))
- q->setStyle(widget->style());
-
- resolveFont(inheritedFontResolveMask);
- resolvePalette(inheritedPaletteResolveMask);
-
- if (!newWidget->testAttribute(Qt::WA_Resized))
- newWidget->adjustSize();
-
- int left, top, right, bottom;
- newWidget->getContentsMargins(&left, &top, &right, &bottom);
- q->setContentsMargins(left, top, right, bottom);
- q->setWindowTitle(newWidget->windowTitle());
-
- // size policies and constraints..
- q->setSizePolicy(newWidget->sizePolicy());
- QSize sz = newWidget->minimumSize();
- q->setMinimumSize(sz.isNull() ? QSizeF() : QSizeF(sz));
- sz = newWidget->maximumSize();
- q->setMaximumSize(sz.isNull() ? QSizeF() : QSizeF(sz));
-
- updateProxyGeometryFromWidget();
-
- updateProxyInputMethodAcceptanceFromWidget();
-
- // Hook up the event filter to keep the state up to date.
- newWidget->installEventFilter(q);
- QObject::connect(newWidget, SIGNAL(destroyed()), q, SLOT(_q_removeWidgetSlot()));
-
- // Changes no longer go only from the widget to the proxy.
- enabledChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
- visibleChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
- posChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
- sizeChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
-}
-
-/*!
- Returns a pointer to the embedded widget.
-
- \sa setWidget()
-*/
-QWidget *QGraphicsProxyWidget::widget() const
-{
- Q_D(const QGraphicsProxyWidget);
- return d->widget;
-}
-
-/*!
- Returns the rectangle for \a widget, which must be a descendant of
- widget(), or widget() itself, in this proxy item's local coordinates.
-
- If no widget is embedded, \a widget is 0, or \a widget is not a
- descendant of the embedded widget, this function returns an empty QRectF.
-
- \sa widget()
-*/
-QRectF QGraphicsProxyWidget::subWidgetRect(const QWidget *widget) const
-{
- Q_D(const QGraphicsProxyWidget);
- if (!widget || !d->widget)
- return QRectF();
- if (d->widget == widget || d->widget->isAncestorOf(widget))
- return QRectF(widget->mapTo(d->widget, QPoint(0, 0)), widget->size());
- return QRectF();
-}
-
-/*!
- \reimp
-*/
-void QGraphicsProxyWidget::setGeometry(const QRectF &rect)
-{
- Q_D(QGraphicsProxyWidget);
- bool proxyResizesWidget = !d->posChangeMode && !d->sizeChangeMode;
- if (proxyResizesWidget) {
- d->posChangeMode = QGraphicsProxyWidgetPrivate::ProxyToWidgetMode;
- d->sizeChangeMode = QGraphicsProxyWidgetPrivate::ProxyToWidgetMode;
- }
- QGraphicsWidget::setGeometry(rect);
- if (proxyResizesWidget) {
- d->posChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
- d->sizeChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
- }
-}
-
-/*!
- \reimp
-*/
-QVariant QGraphicsProxyWidget::itemChange(GraphicsItemChange change,
- const QVariant &value)
-{
- Q_D(QGraphicsProxyWidget);
-
- switch (change) {
- case ItemPositionChange:
- // The item's position is either changed directly on the proxy, in
- // which case the position change should propagate to the widget,
- // otherwise it happens as a side effect when filtering QEvent::Move.
- if (!d->posChangeMode)
- d->posChangeMode = QGraphicsProxyWidgetPrivate::ProxyToWidgetMode;
- break;
- case ItemPositionHasChanged:
- // Move the internal widget if we're in widget-to-proxy
- // mode. Otherwise the widget has already moved.
- if (d->widget && d->posChangeMode != QGraphicsProxyWidgetPrivate::WidgetToProxyMode)
- d->widget->move(value.toPoint());
- if (d->posChangeMode == QGraphicsProxyWidgetPrivate::ProxyToWidgetMode)
- d->posChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
- break;
- case ItemVisibleChange:
- if (!d->visibleChangeMode)
- d->visibleChangeMode = QGraphicsProxyWidgetPrivate::ProxyToWidgetMode;
- break;
- case ItemVisibleHasChanged:
- if (d->widget && d->visibleChangeMode != QGraphicsProxyWidgetPrivate::WidgetToProxyMode)
- d->widget->setVisible(isVisible());
- if (d->visibleChangeMode == QGraphicsProxyWidgetPrivate::ProxyToWidgetMode)
- d->visibleChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
- break;
- case ItemEnabledChange:
- if (!d->enabledChangeMode)
- d->enabledChangeMode = QGraphicsProxyWidgetPrivate::ProxyToWidgetMode;
- break;
- case ItemEnabledHasChanged:
- if (d->widget && d->enabledChangeMode != QGraphicsProxyWidgetPrivate::WidgetToProxyMode)
- d->widget->setEnabled(isEnabled());
- if (d->enabledChangeMode == QGraphicsProxyWidgetPrivate::ProxyToWidgetMode)
- d->enabledChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
- break;
- default:
- break;
- }
- return QGraphicsWidget::itemChange(change, value);
-}
-
-/*!
- \reimp
-*/
-bool QGraphicsProxyWidget::event(QEvent *event)
-{
- Q_D(QGraphicsProxyWidget);
- if (!d->widget)
- return QGraphicsWidget::event(event);
-
- switch (event->type()) {
- case QEvent::StyleChange:
- // Propagate style changes to the embedded widget.
- if (!d->styleChangeMode) {
- d->styleChangeMode = QGraphicsProxyWidgetPrivate::ProxyToWidgetMode;
- d->widget->setStyle(style());
- d->styleChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
- }
- break;
- case QEvent::FontChange: {
- // Propagate to widget.
- QWidgetPrivate *wd = d->widget->d_func();
- int mask = d->font.resolve() | d->inheritedFontResolveMask;
- wd->inheritedFontResolveMask = mask;
- wd->resolveFont();
- break;
- }
- case QEvent::PaletteChange: {
- // Propagate to widget.
- QWidgetPrivate *wd = d->widget->d_func();
- int mask = d->palette.resolve() | d->inheritedPaletteResolveMask;
- wd->inheritedPaletteResolveMask = mask;
- wd->resolvePalette();
- break;
- }
- case QEvent::InputMethod: {
- // Forward input method events if the focus widget enables
- // input methods.
- // ### Qt 4.5: this code must also go into a reimplementation
- // of inputMethodEvent().
- QWidget *focusWidget = d->widget->focusWidget();
- if (focusWidget && focusWidget->testAttribute(Qt::WA_InputMethodEnabled))
- QApplication::sendEvent(focusWidget, event);
- break;
- }
- case QEvent::ShortcutOverride: {
- QWidget *focusWidget = d->widget->focusWidget();
- while (focusWidget) {
- QApplication::sendEvent(focusWidget, event);
- if (event->isAccepted())
- return true;
- focusWidget = focusWidget->parentWidget();
- }
- return false;
- }
- case QEvent::KeyPress: {
- QKeyEvent *k = static_cast<QKeyEvent *>(event);
- if (k->key() == Qt::Key_Tab || k->key() == Qt::Key_Backtab) {
- if (!(k->modifiers() & (Qt::ControlModifier | Qt::AltModifier))) { //### Add MetaModifier?
- QWidget *focusWidget = d->widget->focusWidget();
- while (focusWidget) {
- bool res = QApplication::sendEvent(focusWidget, event);
- if ((res && event->isAccepted()) || (isWindow() && focusWidget == d->widget)) {
- event->accept();
- break;
- }
- focusWidget = focusWidget->parentWidget();
- }
- return true;
- }
- }
- break;
- }
-#ifndef QT_NO_TOOLTIP
- case QEvent::GraphicsSceneHelp: {
- // Propagate the help event (for tooltip) to the widget under mouse
- if (d->lastWidgetUnderMouse) {
- QGraphicsSceneHelpEvent *he = static_cast<QGraphicsSceneHelpEvent *>(event);
- QPoint pos = d->mapToReceiver(mapFromScene(he->scenePos()), d->lastWidgetUnderMouse).toPoint();
- QHelpEvent e(QEvent::ToolTip, pos, he->screenPos());
- QApplication::sendEvent(d->lastWidgetUnderMouse, &e);
- event->setAccepted(e.isAccepted());
- return e.isAccepted();
- }
- break;
- }
- case QEvent::ToolTipChange: {
- // Propagate tooltip change to the widget
- if (!d->tooltipChangeMode) {
- d->tooltipChangeMode = QGraphicsProxyWidgetPrivate::ProxyToWidgetMode;
- d->widget->setToolTip(toolTip());
- d->tooltipChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
- }
- break;
- }
-#endif
- default:
- break;
- }
- return QGraphicsWidget::event(event);
-}
-
-/*!
- \reimp
-*/
-bool QGraphicsProxyWidget::eventFilter(QObject *object, QEvent *event)
-{
- Q_D(QGraphicsProxyWidget);
-
- if (object == d->widget) {
- switch (event->type()) {
- case QEvent::LayoutRequest:
- updateGeometry();
- break;
- case QEvent::Resize:
- // If the widget resizes itself, we resize the proxy too.
- // Prevent feed-back by checking the geometry change mode.
- if (!d->sizeChangeMode)
- d->updateProxyGeometryFromWidget();
- break;
- case QEvent::Move:
- // If the widget moves itself, we move the proxy too. Prevent
- // feed-back by checking the geometry change mode.
- if (!d->posChangeMode)
- d->updateProxyGeometryFromWidget();
- break;
- case QEvent::Hide:
- case QEvent::Show:
- // If the widget toggles its visible state, the proxy will follow.
- if (!d->visibleChangeMode) {
- d->visibleChangeMode = QGraphicsProxyWidgetPrivate::WidgetToProxyMode;
- setVisible(event->type() == QEvent::Show);
- d->visibleChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
- }
- break;
- case QEvent::EnabledChange:
- // If the widget toggles its enabled state, the proxy will follow.
- if (!d->enabledChangeMode) {
- d->enabledChangeMode = QGraphicsProxyWidgetPrivate::WidgetToProxyMode;
- setEnabled(d->widget->isEnabled());
- d->enabledChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
- }
- break;
- case QEvent::StyleChange:
- // Propagate style changes to the proxy.
- if (!d->styleChangeMode) {
- d->styleChangeMode = QGraphicsProxyWidgetPrivate::WidgetToProxyMode;
- setStyle(d->widget->style());
- d->styleChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
- }
- break;
-#ifndef QT_NO_TOOLTIP
- case QEvent::ToolTipChange:
- // Propagate tooltip change to the proxy.
- if (!d->tooltipChangeMode) {
- d->tooltipChangeMode = QGraphicsProxyWidgetPrivate::WidgetToProxyMode;
- setToolTip(d->widget->toolTip());
- d->tooltipChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
- }
- break;
-#endif
- default:
- break;
- }
- }
- return QGraphicsWidget::eventFilter(object, event);
-}
-
-/*!
- \reimp
-*/
-void QGraphicsProxyWidget::showEvent(QShowEvent *event)
-{
- Q_UNUSED(event);
-}
-
-/*!
- \reimp
-*/
-void QGraphicsProxyWidget::hideEvent(QHideEvent *event)
-{
- Q_UNUSED(event);
-}
-
-#ifndef QT_NO_CONTEXTMENU
-/*!
- \reimp
-*/
-void QGraphicsProxyWidget::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
-{
- Q_D(QGraphicsProxyWidget);
- if (!event || !d->widget || !d->widget->isVisible() || !hasFocus())
- return;
-
- // Find widget position and receiver.
- QPointF pos = event->pos();
- QPointer<QWidget> alienWidget = d->widget->childAt(pos.toPoint());
- QPointer<QWidget> receiver = alienWidget ? alienWidget : d->widget;
-
- // Map event position from us to the receiver
- pos = d->mapToReceiver(pos, receiver);
-
- QPoint globalPos = receiver->mapToGlobal(pos.toPoint());
- //If the receiver by-pass the proxy its popups
- //will be top level QWidgets therefore they need
- //the screen position. mapToGlobal expect the widget to
- //have proper coordinates in regards of the windowing system
- //but it's not true because the widget is embedded.
- if (bypassGraphicsProxyWidget(receiver))
- globalPos = event->screenPos();
-
- // Send mouse event. ### Doesn't propagate the event.
- QContextMenuEvent contextMenuEvent(QContextMenuEvent::Reason(event->reason()),
- pos.toPoint(), globalPos, event->modifiers());
- QApplication::sendEvent(receiver, &contextMenuEvent);
-
- event->setAccepted(contextMenuEvent.isAccepted());
-}
-#endif // QT_NO_CONTEXTMENU
-
-#ifndef QT_NO_DRAGANDDROP
-/*!
- \reimp
-*/
-void QGraphicsProxyWidget::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
-{
-#ifdef QT_NO_DRAGANDDROP
- Q_UNUSED(event);
-#else
- Q_D(QGraphicsProxyWidget);
- if (!d->widget)
- return;
-
- QDragEnterEvent proxyDragEnter(event->pos().toPoint(), event->dropAction(), event->mimeData(), event->buttons(), event->modifiers());
- proxyDragEnter.setAccepted(event->isAccepted());
- QApplication::sendEvent(d->widget, &proxyDragEnter);
- event->setAccepted(proxyDragEnter.isAccepted());
- if (proxyDragEnter.isAccepted()) // we discard answerRect
- event->setDropAction(proxyDragEnter.dropAction());
-#endif
-}
-/*!
- \reimp
-*/
-void QGraphicsProxyWidget::dragLeaveEvent(QGraphicsSceneDragDropEvent *event)
-{
- Q_UNUSED(event);
-#ifndef QT_NO_DRAGANDDROP
- Q_D(QGraphicsProxyWidget);
- if (!d->widget || !d->dragDropWidget)
- return;
- QDragLeaveEvent proxyDragLeave;
- QApplication::sendEvent(d->dragDropWidget, &proxyDragLeave);
- d->dragDropWidget = 0;
-#endif
-}
-
-/*!
- \reimp
-*/
-void QGraphicsProxyWidget::dragMoveEvent(QGraphicsSceneDragDropEvent *event)
-{
-#ifdef QT_NO_DRAGANDDROP
- Q_UNUSED(event);
-#else
- Q_D(QGraphicsProxyWidget);
- if (!d->widget)
- return;
- QPointF p = event->pos();
- event->ignore();
- QPointer<QWidget> subWidget = d->widget->childAt(p.toPoint());
- QPointer<QWidget> receiver = subWidget ? subWidget : d->widget;
- bool eventDelivered = false;
- for (; receiver; receiver = receiver->parentWidget()) {
- if (!receiver->isEnabled() || !receiver->acceptDrops())
- continue;
- // Map event position from us to the receiver
- QPoint receiverPos = d->mapToReceiver(p, receiver).toPoint();
- 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());
- QApplication::sendEvent(receiver, &dragEnter);
- event->setAccepted(dragEnter.isAccepted());
- event->setDropAction(dragEnter.dropAction());
- if (!event->isAccepted()) {
- // propagate to the parent widget
- continue;
- }
-
- d->lastDropAction = event->dropAction();
-
- if (d->dragDropWidget) {
- QDragLeaveEvent dragLeave;
- QApplication::sendEvent(d->dragDropWidget, &dragLeave);
- }
- d->dragDropWidget = receiver;
- }
-
- QDragMoveEvent dragMove(receiverPos, event->possibleActions(), event->mimeData(), event->buttons(), event->modifiers());
- event->setDropAction(d->lastDropAction);
- QApplication::sendEvent(receiver, &dragMove);
- event->setAccepted(dragMove.isAccepted());
- event->setDropAction(dragMove.dropAction());
- if (event->isAccepted())
- d->lastDropAction = event->dropAction();
- eventDelivered = true;
- break;
- }
-
- if (!eventDelivered) {
- if (d->dragDropWidget) {
- // Leave the last drag drop item
- QDragLeaveEvent dragLeave;
- QApplication::sendEvent(d->dragDropWidget, &dragLeave);
- d->dragDropWidget = 0;
- }
- // Propagate
- event->setDropAction(Qt::IgnoreAction);
- }
-#endif
-}
-
-/*!
- \reimp
-*/
-void QGraphicsProxyWidget::dropEvent(QGraphicsSceneDragDropEvent *event)
-{
-#ifdef QT_NO_DRAGANDDROP
- Q_UNUSED(event);
-#else
- Q_D(QGraphicsProxyWidget);
- if (d->widget && d->dragDropWidget) {
- QPoint widgetPos = d->mapToReceiver(event->pos(), d->dragDropWidget).toPoint();
- QDropEvent dropEvent(widgetPos, event->possibleActions(), event->mimeData(), event->buttons(), event->modifiers());
- QApplication::sendEvent(d->dragDropWidget, &dropEvent);
- event->setAccepted(dropEvent.isAccepted());
- d->dragDropWidget = 0;
- }
-#endif
-}
-#endif
-
-/*!
- \reimp
-*/
-void QGraphicsProxyWidget::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
-{
- Q_UNUSED(event);
-}
-
-/*!
- \reimp
-*/
-void QGraphicsProxyWidget::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
-{
- Q_UNUSED(event);
- Q_D(QGraphicsProxyWidget);
- // If hoverMove was compressed away, make sure we update properly here.
- if (d->lastWidgetUnderMouse) {
- QApplicationPrivate::dispatchEnterLeave(0, d->lastWidgetUnderMouse);
- d->lastWidgetUnderMouse = 0;
- }
-}
-
-/*!
- \reimp
-*/
-void QGraphicsProxyWidget::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
-{
- Q_D(QGraphicsProxyWidget);
-#ifdef GRAPHICSPROXYWIDGET_DEBUG
- qDebug() << "QGraphicsProxyWidget::hoverMoveEvent";
-#endif
- // Ignore events on the window frame.
- if (!d->widget || !rect().contains(event->pos())) {
- if (d->lastWidgetUnderMouse) {
- QApplicationPrivate::dispatchEnterLeave(0, d->lastWidgetUnderMouse);
- d->lastWidgetUnderMouse = 0;
- }
- return;
- }
-
- d->embeddedMouseGrabber = 0;
- d->sendWidgetMouseEvent(event);
-}
-
-/*!
- \reimp
-*/
-void QGraphicsProxyWidget::grabMouseEvent(QEvent *event)
-{
- Q_UNUSED(event);
-}
-
-/*!
- \reimp
-*/
-void QGraphicsProxyWidget::ungrabMouseEvent(QEvent *event)
-{
- Q_D(QGraphicsProxyWidget);
- Q_UNUSED(event);
- d->embeddedMouseGrabber = 0;
-}
-
-/*!
- \reimp
-*/
-void QGraphicsProxyWidget::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
-{
- Q_D(QGraphicsProxyWidget);
-#ifdef GRAPHICSPROXYWIDGET_DEBUG
- qDebug() << "QGraphicsProxyWidget::mouseMoveEvent";
-#endif
- d->sendWidgetMouseEvent(event);
-}
-
-/*!
- \reimp
-*/
-void QGraphicsProxyWidget::mousePressEvent(QGraphicsSceneMouseEvent *event)
-{
- Q_D(QGraphicsProxyWidget);
-#ifdef GRAPHICSPROXYWIDGET_DEBUG
- qDebug() << "QGraphicsProxyWidget::mousePressEvent";
-#endif
- d->sendWidgetMouseEvent(event);
-}
-
-/*!
- \reimp
-*/
-void QGraphicsProxyWidget::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
-{
- Q_D(QGraphicsProxyWidget);
-#ifdef GRAPHICSPROXYWIDGET_DEBUG
- qDebug() << "QGraphicsProxyWidget::mouseDoubleClickEvent";
-#endif
- d->sendWidgetMouseEvent(event);
-}
-
-/*!
- \reimp
-*/
-#ifndef QT_NO_WHEELEVENT
-void QGraphicsProxyWidget::wheelEvent(QGraphicsSceneWheelEvent *event)
-{
- Q_D(QGraphicsProxyWidget);
-#ifdef GRAPHICSPROXYWIDGET_DEBUG
- qDebug() << "QGraphicsProxyWidget::wheelEvent";
-#endif
- if (!d->widget)
- return;
-
- QPointF pos = event->pos();
- QPointer<QWidget> receiver = d->widget->childAt(pos.toPoint());
- if (!receiver)
- receiver = d->widget;
-
- // Map event position from us to the receiver
- pos = d->mapToReceiver(pos, receiver);
-
- // Send mouse event.
- QWheelEvent wheelEvent(pos.toPoint(), event->screenPos(), event->delta(),
- event->buttons(), event->modifiers(), event->orientation());
- QPointer<QWidget> focusWidget = d->widget->focusWidget();
- extern bool qt_sendSpontaneousEvent(QObject *, QEvent *);
- qt_sendSpontaneousEvent(receiver, &wheelEvent);
- event->setAccepted(wheelEvent.isAccepted());
-
- // ### Remove, this should be done by proper focusIn/focusOut events.
- if (focusWidget && !focusWidget->hasFocus()) {
- focusWidget->update();
- focusWidget = d->widget->focusWidget();
- if (focusWidget && focusWidget->hasFocus())
- focusWidget->update();
- }
-}
-#endif
-
-/*!
- \reimp
-*/
-void QGraphicsProxyWidget::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
-{
- Q_D(QGraphicsProxyWidget);
-#ifdef GRAPHICSPROXYWIDGET_DEBUG
- qDebug() << "QGraphicsProxyWidget::mouseReleaseEvent";
-#endif
- d->sendWidgetMouseEvent(event);
-}
-
-/*!
- \reimp
-*/
-void QGraphicsProxyWidget::keyPressEvent(QKeyEvent *event)
-{
- Q_D(QGraphicsProxyWidget);
-#ifdef GRAPHICSPROXYWIDGET_DEBUG
- qDebug() << "QGraphicsProxyWidget::keyPressEvent";
-#endif
- d->sendWidgetKeyEvent(event);
-}
-
-/*!
- \reimp
-*/
-void QGraphicsProxyWidget::keyReleaseEvent(QKeyEvent *event)
-{
- Q_D(QGraphicsProxyWidget);
-#ifdef GRAPHICSPROXYWIDGET_DEBUG
- qDebug() << "QGraphicsProxyWidget::keyReleaseEvent";
-#endif
- d->sendWidgetKeyEvent(event);
-}
-
-/*!
- \reimp
-*/
-void QGraphicsProxyWidget::focusInEvent(QFocusEvent *event)
-{
-#ifdef GRAPHICSPROXYWIDGET_DEBUG
- qDebug() << "QGraphicsProxyWidget::focusInEvent";
-#endif
- Q_D(QGraphicsProxyWidget);
-
- if (d->focusFromWidgetToProxy) {
- // Prevent recursion when the proxy autogains focus through the
- // embedded widget calling setFocus(). ### Could be done with event
- // filter on FocusIn instead?
- return;
- }
-
- d->proxyIsGivingFocus = true;
-
- switch (event->reason()) {
- case Qt::TabFocusReason: {
- if (QWidget *focusChild = d->findFocusChild(0, true))
- focusChild->setFocus(event->reason());
- break;
- }
- case Qt::BacktabFocusReason:
- if (QWidget *focusChild = d->findFocusChild(0, false))
- focusChild->setFocus(event->reason());
- break;
- default:
- if (d->widget && d->widget->focusWidget()) {
- d->widget->focusWidget()->setFocus(event->reason());
- }
- break;
- }
-
- d->proxyIsGivingFocus = false;
-}
-
-/*!
- \reimp
-*/
-void QGraphicsProxyWidget::focusOutEvent(QFocusEvent *event)
-{
-#ifdef GRAPHICSPROXYWIDGET_DEBUG
- qDebug() << "QGraphicsProxyWidget::focusOutEvent";
-#endif
- Q_D(QGraphicsProxyWidget);
- if (d->widget) {
- // We need to explicitly remove subfocus from the embedded widget's
- // focus widget.
- if (QWidget *focusWidget = d->widget->focusWidget())
- d->removeSubFocusHelper(focusWidget, event->reason());
- }
-}
-
-/*!
- \reimp
-*/
-bool QGraphicsProxyWidget::focusNextPrevChild(bool next)
-{
- Q_D(QGraphicsProxyWidget);
- if (!d->widget || !d->scene)
- return QGraphicsWidget::focusNextPrevChild(next);
-
- Qt::FocusReason reason = next ? Qt::TabFocusReason : Qt::BacktabFocusReason;
- QWidget *lastFocusChild = d->widget->focusWidget();
- if (QWidget *newFocusChild = d->findFocusChild(lastFocusChild, next)) {
- newFocusChild->setFocus(reason);
- return true;
- }
-
- return QGraphicsWidget::focusNextPrevChild(next);
-}
-
-/*!
- \reimp
-*/
-QSizeF QGraphicsProxyWidget::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
-{
- Q_D(const QGraphicsProxyWidget);
- if (!d->widget)
- return QGraphicsWidget::sizeHint(which, constraint);
-
- QSizeF sh;
- switch (which) {
- case Qt::PreferredSize:
- if (QLayout *l = d->widget->layout())
- sh = l->sizeHint();
- else
- sh = d->widget->sizeHint();
- break;
- case Qt::MinimumSize:
- if (QLayout *l = d->widget->layout())
- sh = l->minimumSize();
- else
- sh = d->widget->minimumSizeHint();
- break;
- case Qt::MaximumSize:
- if (QLayout *l = d->widget->layout())
- sh = l->maximumSize();
- else
- sh = QSizeF(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
- break;
- case Qt::MinimumDescent:
- sh = constraint;
- break;
- default:
- break;
- }
- return sh;
-}
-
-/*!
- \reimp
-*/
-void QGraphicsProxyWidget::resizeEvent(QGraphicsSceneResizeEvent *event)
-{
- Q_D(QGraphicsProxyWidget);
- if (d->widget) {
- if (d->sizeChangeMode != QGraphicsProxyWidgetPrivate::WidgetToProxyMode)
- d->widget->resize(event->newSize().toSize());
- }
- QGraphicsWidget::resizeEvent(event);
-}
-
-/*!
- \reimp
-*/
-void QGraphicsProxyWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
-{
- Q_D(QGraphicsProxyWidget);
- Q_UNUSED(widget);
- if (!d->widget || !d->widget->isVisible())
- return;
-
- // Filter out repaints on the window frame.
- const QRect exposedWidgetRect = (option->exposedRect & rect()).toAlignedRect();
- if (exposedWidgetRect.isEmpty())
- return;
-
- // Disable QPainter's default pen being cosmetic. This allows widgets and
- // styles to follow Qt's existing defaults without getting ugly cosmetic
- // lines when scaled.
- bool restore = !(painter->renderHints() & QPainter::NonCosmeticDefaultPen);
- painter->setRenderHints(QPainter::NonCosmeticDefaultPen, true);
-
- d->widget->render(painter, exposedWidgetRect.topLeft(), exposedWidgetRect);
-
- // Restore the render hints if necessary.
- if (restore)
- painter->setRenderHints(QPainter::NonCosmeticDefaultPen, false);
-}
-
-/*!
- \reimp
-*/
-int QGraphicsProxyWidget::type() const
-{
- return Type;
-}
-
-/*!
- \since 4.5
-
- Creates a proxy widget for the given \a child of the widget
- contained in this proxy.
-
- This function makes it possible to acquire proxies for
- non top-level widgets. For instance, you can embed a dialog,
- and then transform only one of its widgets.
-
- If the widget is already embedded, return the existing proxy widget.
-
- \sa newProxyWidget(), QGraphicsScene::addWidget()
-*/
-QGraphicsProxyWidget *QGraphicsProxyWidget::createProxyForChildWidget(QWidget *child)
-{
- QGraphicsProxyWidget *proxy = child->graphicsProxyWidget();
- if (proxy)
- return proxy;
- if (!child->parentWidget()) {
- qWarning("QGraphicsProxyWidget::createProxyForChildWidget: top-level widget not in a QGraphicsScene");
- return 0;
- }
-
- QGraphicsProxyWidget *parentProxy = createProxyForChildWidget(child->parentWidget());
- if (!parentProxy)
- return 0;
-
- if (!QMetaObject::invokeMethod(parentProxy, "newProxyWidget", Qt::DirectConnection,
- Q_RETURN_ARG(QGraphicsProxyWidget*, proxy), Q_ARG(const QWidget*, child)))
- return 0;
- proxy->setParent(parentProxy);
- proxy->setWidget(child);
- return proxy;
-}
-
-/*!
- \fn QGraphicsProxyWidget *QGraphicsProxyWidget::newProxyWidget(const QWidget *child)
- \since 4.5
-
- Creates a proxy widget for the given \a child of the widget contained in this
- proxy.
-
- You should not call this function directly; use
- QGraphicsProxyWidget::createProxyForChildWidget() instead.
-
- This function is a fake virtual slot that you can reimplement in
- your subclass in order to control how new proxy widgets are
- created. The default implementation returns a proxy created with
- the QGraphicsProxyWidget() constructor with this proxy widget as
- the parent.
-
- \sa createProxyForChildWidget()
-*/
-QGraphicsProxyWidget *QGraphicsProxyWidget::newProxyWidget(const QWidget *)
-{
- return new QGraphicsProxyWidget(this);
-}
-
-
-
-QT_END_NAMESPACE
-
-#include "moc_qgraphicsproxywidget.cpp"
-
-#endif //QT_NO_GRAPHICSVIEW
diff --git a/src/gui/graphicsview/qgraphicsproxywidget.h b/src/gui/graphicsview/qgraphicsproxywidget.h
deleted file mode 100644
index 3ff5ef1aac..0000000000
--- a/src/gui/graphicsview/qgraphicsproxywidget.h
+++ /dev/null
@@ -1,147 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGRAPHICSPROXYWIDGET_H
-#define QGRAPHICSPROXYWIDGET_H
-
-#include <QtGui/qgraphicswidget.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW
-
-class QGraphicsProxyWidgetPrivate;
-
-class Q_GUI_EXPORT QGraphicsProxyWidget : public QGraphicsWidget
-{
- Q_OBJECT
-public:
- QGraphicsProxyWidget(QGraphicsItem *parent = 0, Qt::WindowFlags wFlags = 0);
- ~QGraphicsProxyWidget();
-
- void setWidget(QWidget *widget);
- QWidget *widget() const;
-
- QRectF subWidgetRect(const QWidget *widget) const;
-
- void setGeometry(const QRectF &rect);
-
- void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
-
- enum {
- Type = 12
- };
- int type() const;
-
- QGraphicsProxyWidget *createProxyForChildWidget(QWidget *child);
-
-protected:
- QVariant itemChange(GraphicsItemChange change, const QVariant &value);
-
- bool event(QEvent *event);
- bool eventFilter(QObject *object, QEvent *event);
-
- void showEvent(QShowEvent *event);
- void hideEvent(QHideEvent *event);
-
-#ifndef QT_NO_CONTEXTMENU
- void contextMenuEvent(QGraphicsSceneContextMenuEvent *event);
-#endif
-
-#ifndef QT_NO_DRAGANDDROP
- void dragEnterEvent(QGraphicsSceneDragDropEvent *event);
- void dragLeaveEvent(QGraphicsSceneDragDropEvent *event);
- void dragMoveEvent(QGraphicsSceneDragDropEvent *event);
- void dropEvent(QGraphicsSceneDragDropEvent *event);
-#endif
-
- void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
- void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
- void hoverMoveEvent(QGraphicsSceneHoverEvent *event);
- void grabMouseEvent(QEvent *event);
- void ungrabMouseEvent(QEvent *event);
-
- void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
- void mousePressEvent(QGraphicsSceneMouseEvent *event);
- void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
- void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event);
-#ifndef QT_NO_WHEELEVENT
- void wheelEvent(QGraphicsSceneWheelEvent *event);
-#endif
-
- void keyPressEvent(QKeyEvent *event);
- void keyReleaseEvent(QKeyEvent *event);
-
- void focusInEvent(QFocusEvent *event);
- void focusOutEvent(QFocusEvent *event);
- bool focusNextPrevChild(bool next);
- // ### Qt 4.5:
- // QVariant inputMethodQuery(Qt::InputMethodQuery query) const;
- // void inputMethodEvent(QInputMethodEvent *event);
-
- QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const;
- void resizeEvent(QGraphicsSceneResizeEvent *event);
-
-protected Q_SLOTS:
- QGraphicsProxyWidget *newProxyWidget(const QWidget *);
-
-private:
- Q_DISABLE_COPY(QGraphicsProxyWidget)
- Q_DECLARE_PRIVATE_D(QGraphicsItem::d_ptr.data(), QGraphicsProxyWidget)
- Q_PRIVATE_SLOT(d_func(), void _q_removeWidgetSlot())
-
- friend class QWidget;
- friend class QWidgetPrivate;
- friend class QGraphicsItem;
-};
-
-#endif
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif
-
diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp
deleted file mode 100644
index 1551944a09..0000000000
--- a/src/gui/graphicsview/qgraphicsscene.cpp
+++ /dev/null
@@ -1,6504 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*!
- \class QGraphicsScene
- \brief The QGraphicsScene class provides a surface for managing a large
- number of 2D graphical items.
- \since 4.2
- \ingroup graphicsview-api
-
-
- The class serves as a container for QGraphicsItems. It is used together
- with QGraphicsView for visualizing graphical items, such as lines,
- rectangles, text, or even custom items, on a 2D surface. QGraphicsScene is
- part of the \l{Graphics View Framework}.
-
- QGraphicsScene also provides functionality that lets you efficiently
- determine both the location of items, and for determining what items are
- visible within an arbitrary area on the scene. With the QGraphicsView
- widget, you can either visualize the whole scene, or zoom in and view only
- parts of the scene.
-
- Example:
-
- \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsscene.cpp 0
-
- Note that QGraphicsScene has no visual appearance of its own; it only
- manages the items. You need to create a QGraphicsView widget to visualize
- the scene.
-
- To add items to a scene, you start off by constructing a QGraphicsScene
- object. Then, you have two options: either add your existing QGraphicsItem
- objects by calling addItem(), or you can call one of the convenience
- functions addEllipse(), addLine(), addPath(), addPixmap(), addPolygon(),
- addRect(), or addText(), which all return a pointer to the newly added item.
- The dimensions of the items added with these functions are relative to the
- item's coordinate system, and the items position is initialized to (0,
- 0) in the scene.
-
- You can then visualize the scene using QGraphicsView. When the scene
- changes, (e.g., when an item moves or is transformed) QGraphicsScene
- emits the changed() signal. To remove an item, call removeItem().
-
- QGraphicsScene uses an indexing algorithm to manage the location of items
- efficiently. By default, a BSP (Binary Space Partitioning) tree is used; an
- algorithm suitable for large scenes where most items remain static (i.e.,
- do not move around). You can choose to disable this index by calling
- setItemIndexMethod(). For more information about the available indexing
- algorithms, see the itemIndexMethod property.
-
- The scene's bounding rect is set by calling setSceneRect(). Items can be
- placed at any position on the scene, and the size of the scene is by
- default unlimited. The scene rect is used only for internal bookkeeping,
- maintaining the scene's item index. If the scene rect is unset,
- QGraphicsScene will use the bounding area of all items, as returned by
- itemsBoundingRect(), as the scene rect. However, itemsBoundingRect() is a
- relatively time consuming function, as it operates by collecting
- positional information for every item on the scene. Because of this, you
- should always set the scene rect when operating on large scenes.
-
- One of QGraphicsScene's greatest strengths is its ability to efficiently
- determine the location of items. Even with millions of items on the scene,
- the items() functions can determine the location of an item within few
- milliseconds. There are several overloads to items(): one that finds items
- at a certain position, one that finds items inside or intersecting with a
- polygon or a rectangle, and more. The list of returned items is sorted by
- stacking order, with the topmost item being the first item in the list.
- For convenience, there is also an itemAt() function that returns the
- topmost item at a given position.
-
- QGraphicsScene maintains selection information for the scene. To select
- items, call setSelectionArea(), and to clear the current selection, call
- clearSelection(). Call selectedItems() to get the list of all selected
- items.
-
- \section1 Event Handling and Propagation
-
- Another responsibility that QGraphicsScene has, is to propagate events
- from QGraphicsView. To send an event to a scene, you construct an event
- that inherits QEvent, and then send it using, for example,
- QApplication::sendEvent(). event() is responsible for dispatching
- the event to the individual items. Some common events are handled by
- convenience event handlers. For example, key press events are handled by
- keyPressEvent(), and mouse press events are handled by mousePressEvent().
-
- Key events are delivered to the \e {focus item}. To set the focus item,
- you can either call setFocusItem(), passing an item that accepts focus, or
- the item itself can call QGraphicsItem::setFocus(). Call focusItem() to
- get the current focus item. For compatibility with widgets, the scene also
- maintains its own focus information. By default, the scene does not have
- focus, and all key events are discarded. If setFocus() is called, or if an
- item on the scene gains focus, the scene automatically gains focus. If the
- scene has focus, hasFocus() will return true, and key events will be
- forwarded to the focus item, if any. If the scene loses focus, (i.e.,
- someone calls clearFocus()) while an item has focus, the scene will
- maintain its item focus information, and once the scene regains focus, it
- will make sure the last focus item regains focus.
-
- For mouse-over effects, QGraphicsScene dispatches \e {hover
- events}. If an item accepts hover events (see
- QGraphicsItem::acceptHoverEvents()), it will receive a \l
- {QEvent::}{GraphicsSceneHoverEnter} event when the mouse enters
- its area. As the mouse continues moving inside the item's area,
- QGraphicsScene will send it \l {QEvent::}{GraphicsSceneHoverMove}
- events. When the mouse leaves the item's area, the item will
- receive a \l {QEvent::}{GraphicsSceneHoverLeave} event.
-
- All mouse events are delivered to the current \e {mouse grabber}
- item. An item becomes the scene's mouse grabber if it accepts
- mouse events (see QGraphicsItem::acceptedMouseButtons()) and it
- receives a mouse press. It stays the mouse grabber until it
- receives a mouse release when no other mouse buttons are
- pressed. You can call mouseGrabberItem() to determine what item is
- currently grabbing the mouse.
-
- \sa QGraphicsItem, QGraphicsView
-*/
-
-/*!
- \enum QGraphicsScene::SceneLayer
- \since 4.3
-
- This enum describes the rendering layers in a QGraphicsScene. When
- QGraphicsScene draws the scene contents, it renders each of these layers
- separately, in order.
-
- Each layer represents a flag that can be OR'ed together when calling
- functions such as invalidate() or QGraphicsView::invalidateScene().
-
- \value ItemLayer The item layer. QGraphicsScene renders all items are in
- this layer by calling the virtual function drawItems(). The item layer is
- drawn after the background layer, but before the foreground layer.
-
- \value BackgroundLayer The background layer. QGraphicsScene renders the
- scene's background in this layer by calling the virtual function
- drawBackground(). The background layer is drawn first of all layers.
-
- \value ForegroundLayer The foreground layer. QGraphicsScene renders the
- scene's foreground in this layer by calling the virtual function
- drawForeground(). The foreground layer is drawn last of all layers.
-
- \value AllLayers All layers; this value represents a combination of all
- three layers.
-
- \sa invalidate(), QGraphicsView::invalidateScene()
-*/
-
-/*!
- \enum QGraphicsScene::ItemIndexMethod
-
- This enum describes the indexing algorithms QGraphicsScene provides for
- managing positional information about items on the scene.
-
- \value BspTreeIndex A Binary Space Partitioning tree is applied. All
- QGraphicsScene's item location algorithms are of an order close to
- logarithmic complexity, by making use of binary search. Adding, moving and
- removing items is logarithmic. This approach is best for static scenes
- (i.e., scenes where most items do not move).
-
- \value NoIndex No index is applied. Item location is of linear complexity,
- as all items on the scene are searched. Adding, moving and removing items,
- however, is done in constant time. This approach is ideal for dynamic
- scenes, where many items are added, moved or removed continuously.
-
- \sa setItemIndexMethod(), bspTreeDepth
-*/
-
-#include "qgraphicsscene.h"
-
-#ifndef QT_NO_GRAPHICSVIEW
-
-#include "qgraphicsitem.h"
-#include "qgraphicsitem_p.h"
-#include "qgraphicslayout.h"
-#include "qgraphicsscene_p.h"
-#include "qgraphicssceneevent.h"
-#include "qgraphicsview.h"
-#include "qgraphicsview_p.h"
-#include "qgraphicswidget.h"
-#include "qgraphicswidget_p.h"
-#include "qgraphicssceneindex_p.h"
-#include "qgraphicsscenebsptreeindex_p.h"
-#include "qgraphicsscenelinearindex_p.h"
-
-#include <QtCore/qdebug.h>
-#include <QtCore/qlist.h>
-#include <QtCore/qmath.h>
-#include <QtCore/qrect.h>
-#include <QtCore/qset.h>
-#include <QtCore/qstack.h>
-#include <QtCore/qtimer.h>
-#include <QtCore/qvarlengtharray.h>
-#include <QtCore/QMetaMethod>
-#include <QtGui/qapplication.h>
-#include <QtGui/qdesktopwidget.h>
-#include <QtGui/qevent.h>
-#include <QtGui/qgraphicslayout.h>
-#include <QtGui/qgraphicsproxywidget.h>
-#include <QtGui/qgraphicswidget.h>
-#include <QtGui/qmatrix.h>
-#include <QtGui/qpaintengine.h>
-#include <QtGui/qpainter.h>
-#include <QtGui/qpixmapcache.h>
-#include <QtGui/qpolygon.h>
-#include <QtGui/qstyleoption.h>
-#include <QtGui/qtooltip.h>
-#include <QtGui/qtransform.h>
-#include <QtGui/qinputcontext.h>
-#include <QtGui/qgraphicseffect.h>
-#ifndef QT_NO_ACCESSIBILITY
-# include <QtGui/qaccessible.h>
-#endif
-
-#include <private/qapplication_p.h>
-#include <private/qobject_p.h>
-#ifdef Q_WS_X11
-#include <private/qt_x11_p.h>
-#endif
-#include <private/qgraphicseffect_p.h>
-#include <private/qgesturemanager_p.h>
-#include <private/qpathclipper_p.h>
-
-// #define GESTURE_DEBUG
-#ifndef GESTURE_DEBUG
-# define DEBUG if (0) qDebug
-#else
-# define DEBUG qDebug
-#endif
-
-QT_BEGIN_NAMESPACE
-
-bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event);
-
-static void _q_hoverFromMouseEvent(QGraphicsSceneHoverEvent *hover, const QGraphicsSceneMouseEvent *mouseEvent)
-{
- hover->setWidget(mouseEvent->widget());
- hover->setPos(mouseEvent->pos());
- hover->setScenePos(mouseEvent->scenePos());
- hover->setScreenPos(mouseEvent->screenPos());
- hover->setLastPos(mouseEvent->lastPos());
- hover->setLastScenePos(mouseEvent->lastScenePos());
- hover->setLastScreenPos(mouseEvent->lastScreenPos());
- hover->setModifiers(mouseEvent->modifiers());
- hover->setAccepted(mouseEvent->isAccepted());
-}
-
-/*!
- \internal
-*/
-QGraphicsScenePrivate::QGraphicsScenePrivate()
- : indexMethod(QGraphicsScene::BspTreeIndex),
- index(0),
- lastItemCount(0),
- hasSceneRect(false),
- dirtyGrowingItemsBoundingRect(true),
- updateAll(false),
- calledEmitUpdated(false),
- processDirtyItemsEmitted(false),
- needSortTopLevelItems(true),
- holesInTopLevelSiblingIndex(false),
- topLevelSequentialOrdering(true),
- scenePosDescendantsUpdatePending(false),
- stickyFocus(false),
- hasFocus(false),
- lastMouseGrabberItemHasImplicitMouseGrab(false),
- allItemsIgnoreHoverEvents(true),
- allItemsUseDefaultCursor(true),
- painterStateProtection(true),
- sortCacheEnabled(false),
- allItemsIgnoreTouchEvents(true),
- selectionChanging(0),
- rectAdjust(2),
- focusItem(0),
- lastFocusItem(0),
- passiveFocusItem(0),
- tabFocusFirst(0),
- activePanel(0),
- lastActivePanel(0),
- activationRefCount(0),
- childExplicitActivation(0),
- lastMouseGrabberItem(0),
- dragDropItem(0),
- enterWidget(0),
- lastDropAction(Qt::IgnoreAction),
- style(0)
-{
-}
-
-/*!
- \internal
-*/
-void QGraphicsScenePrivate::init()
-{
- Q_Q(QGraphicsScene);
-
- index = new QGraphicsSceneBspTreeIndex(q);
-
- // Keep this index so we can check for connected slots later on.
- changedSignalIndex = signalIndex("changed(QList<QRectF>)");
- processDirtyItemsIndex = q->metaObject()->indexOfSlot("_q_processDirtyItems()");
- polishItemsIndex = q->metaObject()->indexOfSlot("_q_polishItems()");
-
- qApp->d_func()->scene_list.append(q);
- q->update();
-}
-
-/*!
- \internal
-*/
-QGraphicsScenePrivate *QGraphicsScenePrivate::get(QGraphicsScene *q)
-{
- return q->d_func();
-}
-
-void QGraphicsScenePrivate::_q_emitUpdated()
-{
- Q_Q(QGraphicsScene);
- calledEmitUpdated = false;
-
- if (dirtyGrowingItemsBoundingRect) {
- if (!hasSceneRect) {
- const QRectF oldGrowingItemsBoundingRect = growingItemsBoundingRect;
- growingItemsBoundingRect |= q->itemsBoundingRect();
- if (oldGrowingItemsBoundingRect != growingItemsBoundingRect)
- emit q->sceneRectChanged(growingItemsBoundingRect);
- }
- dirtyGrowingItemsBoundingRect = false;
- }
-
- // Ensure all views are connected if anything is connected. This disables
- // the optimization that items send updates directly to the views, but it
- // needs to happen in order to keep compatibility with the behavior from
- // Qt 4.4 and backward.
- if (isSignalConnected(changedSignalIndex)) {
- for (int i = 0; i < views.size(); ++i) {
- QGraphicsView *view = views.at(i);
- if (!view->d_func()->connectedToScene) {
- view->d_func()->connectedToScene = true;
- q->connect(q, SIGNAL(changed(QList<QRectF>)),
- views.at(i), SLOT(updateScene(QList<QRectF>)));
- }
- }
- } else {
- if (views.isEmpty()) {
- updateAll = false;
- return;
- }
- for (int i = 0; i < views.size(); ++i)
- views.at(i)->d_func()->processPendingUpdates();
- // It's important that we update all views before we dispatch, hence two for-loops.
- for (int i = 0; i < views.size(); ++i)
- views.at(i)->d_func()->dispatchPendingUpdateRequests();
- return;
- }
-
- // Notify the changes to anybody interested.
- QList<QRectF> oldUpdatedRects;
- oldUpdatedRects = updateAll ? (QList<QRectF>() << q->sceneRect()) : updatedRects;
- updateAll = false;
- updatedRects.clear();
- emit q->changed(oldUpdatedRects);
-}
-
-/*!
- \internal
-
- ### This function is almost identical to QGraphicsItemPrivate::addChild().
-*/
-void QGraphicsScenePrivate::registerTopLevelItem(QGraphicsItem *item)
-{
- item->d_ptr->ensureSequentialSiblingIndex();
- needSortTopLevelItems = true; // ### maybe false
- item->d_ptr->siblingIndex = topLevelItems.size();
- topLevelItems.append(item);
-}
-
-/*!
- \internal
-
- ### This function is almost identical to QGraphicsItemPrivate::removeChild().
-*/
-void QGraphicsScenePrivate::unregisterTopLevelItem(QGraphicsItem *item)
-{
- if (!holesInTopLevelSiblingIndex)
- holesInTopLevelSiblingIndex = item->d_ptr->siblingIndex != topLevelItems.size() - 1;
- if (topLevelSequentialOrdering && !holesInTopLevelSiblingIndex)
- topLevelItems.removeAt(item->d_ptr->siblingIndex);
- else
- topLevelItems.removeOne(item);
- // NB! Do not use topLevelItems.removeAt(item->d_ptr->siblingIndex) because
- // the item is not guaranteed to be at the index after the list is sorted
- // (see ensureSortedTopLevelItems()).
- item->d_ptr->siblingIndex = -1;
- if (topLevelSequentialOrdering)
- topLevelSequentialOrdering = !holesInTopLevelSiblingIndex;
-}
-
-/*!
- \internal
-*/
-void QGraphicsScenePrivate::_q_polishItems()
-{
- if (unpolishedItems.isEmpty())
- return;
-
- const QVariant booleanTrueVariant(true);
- QGraphicsItem *item = 0;
- QGraphicsItemPrivate *itemd = 0;
- const int oldUnpolishedCount = unpolishedItems.count();
-
- for (int i = 0; i < oldUnpolishedCount; ++i) {
- item = unpolishedItems.at(i);
- if (!item)
- continue;
- itemd = item->d_ptr.data();
- itemd->pendingPolish = false;
- if (!itemd->explicitlyHidden) {
- item->itemChange(QGraphicsItem::ItemVisibleChange, booleanTrueVariant);
- item->itemChange(QGraphicsItem::ItemVisibleHasChanged, booleanTrueVariant);
- }
- if (itemd->isWidget) {
- QEvent event(QEvent::Polish);
- QApplication::sendEvent((QGraphicsWidget *)item, &event);
- }
- }
-
- if (unpolishedItems.count() == oldUnpolishedCount) {
- // No new items were added to the vector.
- unpolishedItems.clear();
- } else {
- // New items were appended; keep them and remove the old ones.
- unpolishedItems.remove(0, oldUnpolishedCount);
- unpolishedItems.squeeze();
- QMetaObject::invokeMethod(q_ptr, "_q_polishItems", Qt::QueuedConnection);
- }
-}
-
-void QGraphicsScenePrivate::_q_processDirtyItems()
-{
- processDirtyItemsEmitted = false;
-
- if (updateAll) {
- Q_ASSERT(calledEmitUpdated);
- // No need for further processing (except resetting the dirty states).
- // The growingItemsBoundingRect is updated in _q_emitUpdated.
- for (int i = 0; i < topLevelItems.size(); ++i)
- resetDirtyItem(topLevelItems.at(i), /*recursive=*/true);
- return;
- }
-
- const bool wasPendingSceneUpdate = calledEmitUpdated;
- const QRectF oldGrowingItemsBoundingRect = growingItemsBoundingRect;
-
- // Process items recursively.
- for (int i = 0; i < topLevelItems.size(); ++i)
- processDirtyItemsRecursive(topLevelItems.at(i));
-
- dirtyGrowingItemsBoundingRect = false;
- if (!hasSceneRect && oldGrowingItemsBoundingRect != growingItemsBoundingRect)
- emit q_func()->sceneRectChanged(growingItemsBoundingRect);
-
- if (wasPendingSceneUpdate)
- return;
-
- for (int i = 0; i < views.size(); ++i)
- views.at(i)->d_func()->processPendingUpdates();
-
- if (calledEmitUpdated) {
- // We did a compatibility QGraphicsScene::update in processDirtyItemsRecursive
- // and we cannot wait for the control to reach the eventloop before the
- // changed signal is emitted, so we emit it now.
- _q_emitUpdated();
- }
-
- // Immediately dispatch all pending update requests on the views.
- for (int i = 0; i < views.size(); ++i)
- views.at(i)->d_func()->dispatchPendingUpdateRequests();
-}
-
-/*!
- \internal
-*/
-void QGraphicsScenePrivate::setScenePosItemEnabled(QGraphicsItem *item, bool enabled)
-{
- QGraphicsItem *p = item->d_ptr->parent;
- while (p) {
- p->d_ptr->scenePosDescendants = enabled;
- p = p->d_ptr->parent;
- }
- if (!enabled && !scenePosDescendantsUpdatePending) {
- scenePosDescendantsUpdatePending = true;
- QMetaObject::invokeMethod(q_func(), "_q_updateScenePosDescendants", Qt::QueuedConnection);
- }
-}
-
-/*!
- \internal
-*/
-void QGraphicsScenePrivate::registerScenePosItem(QGraphicsItem *item)
-{
- scenePosItems.insert(item);
- setScenePosItemEnabled(item, true);
-}
-
-/*!
- \internal
-*/
-void QGraphicsScenePrivate::unregisterScenePosItem(QGraphicsItem *item)
-{
- scenePosItems.remove(item);
- setScenePosItemEnabled(item, false);
-}
-
-/*!
- \internal
-*/
-void QGraphicsScenePrivate::_q_updateScenePosDescendants()
-{
- foreach (QGraphicsItem *item, scenePosItems) {
- QGraphicsItem *p = item->d_ptr->parent;
- while (p) {
- p->d_ptr->scenePosDescendants = 1;
- p = p->d_ptr->parent;
- }
- }
- scenePosDescendantsUpdatePending = false;
-}
-
-/*!
- \internal
-
- Schedules an item for removal. This function leaves some stale indexes
- around in the BSP tree if called from the item's destructor; these will
- be cleaned up the next time someone triggers purgeRemovedItems().
-
- Note: This function might get called from QGraphicsItem's destructor. \a item is
- being destroyed, so we cannot call any pure virtual functions on it (such
- as boundingRect()). Also, it is unnecessary to update the item's own state
- in any way.
-*/
-void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item)
-{
- Q_Q(QGraphicsScene);
-
- // Clear focus on the item to remove any reference in the focusWidget chain.
- item->clearFocus();
-
- markDirty(item, QRectF(), /*invalidateChildren=*/false, /*force=*/false,
- /*ignoreOpacity=*/false, /*removingItemFromScene=*/true);
-
- if (item->d_ptr->inDestructor) {
- // The item is actually in its destructor, we call the special method in the index.
- index->deleteItem(item);
- } else {
- // Can potentially call item->boundingRect() (virtual function), that's why
- // we only can call this function if the item is not in its destructor.
- index->removeItem(item);
- }
-
- item->d_ptr->clearSubFocus();
-
- if (item->flags() & QGraphicsItem::ItemSendsScenePositionChanges)
- unregisterScenePosItem(item);
-
- QGraphicsScene *oldScene = item->d_func()->scene;
- item->d_func()->scene = 0;
-
- //We need to remove all children first because they might use their parent
- //attributes (e.g. sceneTransform).
- if (!item->d_ptr->inDestructor) {
- // Remove all children recursively
- for (int i = 0; i < item->d_ptr->children.size(); ++i)
- q->removeItem(item->d_ptr->children.at(i));
- }
-
- if (!item->d_ptr->inDestructor && item == tabFocusFirst) {
- QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(item);
- widget->d_func()->fixFocusChainBeforeReparenting(0, oldScene, 0);
- }
-
- // Unregister focus proxy.
- item->d_ptr->resetFocusProxy();
-
- // Remove from parent, or unregister from toplevels.
- if (QGraphicsItem *parentItem = item->parentItem()) {
- if (parentItem->scene()) {
- Q_ASSERT_X(parentItem->scene() == q, "QGraphicsScene::removeItem",
- "Parent item's scene is different from this item's scene");
- item->setParentItem(0);
- }
- } else {
- unregisterTopLevelItem(item);
- }
-
- // Reset the mouse grabber and focus item data.
- if (item == focusItem)
- focusItem = 0;
- if (item == lastFocusItem)
- lastFocusItem = 0;
- if (item == passiveFocusItem)
- passiveFocusItem = 0;
- if (item == activePanel) {
- // ### deactivate...
- activePanel = 0;
- }
- if (item == lastActivePanel)
- lastActivePanel = 0;
-
- // Cancel active touches
- {
- QMap<int, QGraphicsItem *>::iterator it = itemForTouchPointId.begin();
- while (it != itemForTouchPointId.end()) {
- if (it.value() == item) {
- sceneCurrentTouchPoints.remove(it.key());
- it = itemForTouchPointId.erase(it);
- } else {
- ++it;
- }
- }
- }
-
- // Disable selectionChanged() for individual items
- ++selectionChanging;
- int oldSelectedItemsSize = selectedItems.size();
-
- // Update selected & hovered item bookkeeping
- selectedItems.remove(item);
- hoverItems.removeAll(item);
- cachedItemsUnderMouse.removeAll(item);
- if (item->d_ptr->pendingPolish) {
- const int unpolishedIndex = unpolishedItems.indexOf(item);
- if (unpolishedIndex != -1)
- unpolishedItems[unpolishedIndex] = 0;
- item->d_ptr->pendingPolish = false;
- }
- resetDirtyItem(item);
-
- //We remove all references of item from the sceneEventFilter arrays
- QMultiMap<QGraphicsItem*, QGraphicsItem*>::iterator iterator = sceneEventFilters.begin();
- while (iterator != sceneEventFilters.end()) {
- if (iterator.value() == item || iterator.key() == item)
- iterator = sceneEventFilters.erase(iterator);
- else
- ++iterator;
- }
-
- if (item->isPanel() && item->isVisible() && item->panelModality() != QGraphicsItem::NonModal)
- leaveModal(item);
-
- // Reset the mouse grabber and focus item data.
- if (mouseGrabberItems.contains(item))
- ungrabMouse(item, /* item is dying */ item->d_ptr->inDestructor);
-
- // Reset the keyboard grabber
- if (keyboardGrabberItems.contains(item))
- ungrabKeyboard(item, /* item is dying */ item->d_ptr->inDestructor);
-
- // Reset the last mouse grabber item
- if (item == lastMouseGrabberItem)
- lastMouseGrabberItem = 0;
-
- // Reset the current drop item
- if (item == dragDropItem)
- dragDropItem = 0;
-
- // Reenable selectionChanged() for individual items
- --selectionChanging;
- if (!selectionChanging && selectedItems.size() != oldSelectedItemsSize)
- emit q->selectionChanged();
-
-#ifndef QT_NO_GESTURES
- QHash<QGesture *, QGraphicsObject *>::iterator it;
- for (it = gestureTargets.begin(); it != gestureTargets.end();) {
- if (it.value() == item)
- it = gestureTargets.erase(it);
- else
- ++it;
- }
-
- QGraphicsObject *dummy = static_cast<QGraphicsObject *>(item);
- cachedTargetItems.removeOne(dummy);
- cachedItemGestures.remove(dummy);
- cachedAlreadyDeliveredGestures.remove(dummy);
-
- foreach (Qt::GestureType gesture, item->d_ptr->gestureContext.keys())
- ungrabGesture(item, gesture);
-#endif // QT_NO_GESTURES
-}
-
-/*!
- \internal
-*/
-void QGraphicsScenePrivate::setActivePanelHelper(QGraphicsItem *item, bool duringActivationEvent)
-{
- Q_Q(QGraphicsScene);
- if (item && item->scene() != q) {
- qWarning("QGraphicsScene::setActivePanel: item %p must be part of this scene",
- item);
- return;
- }
-
- // Ensure the scene has focus when we change panel activation.
- q->setFocus(Qt::ActiveWindowFocusReason);
-
- // Find the item's panel.
- QGraphicsItem *panel = item ? item->panel() : 0;
- lastActivePanel = panel ? activePanel : 0;
- if (panel == activePanel || (!q->isActive() && !duringActivationEvent))
- return;
-
- // Deactivate the last active panel.
- if (activePanel) {
- if (QGraphicsItem *fi = activePanel->focusItem()) {
- // Remove focus from the current focus item.
- if (fi == q->focusItem())
- q->setFocusItem(0, Qt::ActiveWindowFocusReason);
- }
-
- QEvent event(QEvent::WindowDeactivate);
- q->sendEvent(activePanel, &event);
- } else if (panel && !duringActivationEvent) {
- // Deactivate the scene if changing activation to a panel.
- QEvent event(QEvent::WindowDeactivate);
- foreach (QGraphicsItem *item, q->items()) {
- if (item->isVisible() && !item->isPanel() && !item->parentItem())
- q->sendEvent(item, &event);
- }
- }
-
- // Update activate state.
- activePanel = panel;
- QEvent event(QEvent::ActivationChange);
- QApplication::sendEvent(q, &event);
-
- // Activate
- if (panel) {
- QEvent event(QEvent::WindowActivate);
- q->sendEvent(panel, &event);
-
- // Set focus on the panel's focus item.
- if (QGraphicsItem *focusItem = panel->focusItem())
- focusItem->setFocus(Qt::ActiveWindowFocusReason);
- } else if (q->isActive()) {
- // Activate the scene
- QEvent event(QEvent::WindowActivate);
- foreach (QGraphicsItem *item, q->items()) {
- if (item->isVisible() && !item->isPanel() && !item->parentItem())
- q->sendEvent(item, &event);
- }
- }
-}
-
-/*!
- \internal
-*/
-void QGraphicsScenePrivate::setFocusItemHelper(QGraphicsItem *item,
- Qt::FocusReason focusReason)
-{
- Q_Q(QGraphicsScene);
- if (item == focusItem)
- return;
-
- // Clear focus if asked to set focus on something that can't
- // accept input focus.
- if (item && (!(item->flags() & QGraphicsItem::ItemIsFocusable)
- || !item->isVisible() || !item->isEnabled())) {
- item = 0;
- }
-
- // Set focus on the scene if an item requests focus.
- if (item) {
- q->setFocus(focusReason);
- if (item == focusItem)
- return;
- }
-
- if (focusItem) {
- lastFocusItem = focusItem;
-
-#ifndef QT_NO_IM
- if (lastFocusItem
- && (lastFocusItem->flags() & QGraphicsItem::ItemAcceptsInputMethod)) {
- // Close any external input method panel. This happens
- // automatically by removing WA_InputMethodEnabled on
- // the views, but if we are changing focus, we have to
- // do it ourselves.
- for (int i = 0; i < views.size(); ++i)
- if (views.at(i)->inputContext())
- views.at(i)->inputContext()->reset();
- }
-
- focusItem = 0;
- QFocusEvent event(QEvent::FocusOut, focusReason);
- sendEvent(lastFocusItem, &event);
-#endif //QT_NO_IM
- }
-
- // This handles the case that the item has been removed from the
- // scene in response to the FocusOut event.
- if (item && item->scene() != q)
- item = 0;
-
- if (item)
- focusItem = item;
- updateInputMethodSensitivityInViews();
-
-#ifndef QT_NO_ACCESSIBILITY
- if (focusItem) {
- if (QGraphicsObject *focusObj = focusItem->toGraphicsObject()) {
- QAccessible::updateAccessibility(focusObj, 0, QAccessible::Focus);
- }
- }
-#endif
- if (item) {
- QFocusEvent event(QEvent::FocusIn, focusReason);
- sendEvent(item, &event);
- }
-}
-
-/*!
- \internal
-*/
-void QGraphicsScenePrivate::addPopup(QGraphicsWidget *widget)
-{
- Q_ASSERT(widget);
- Q_ASSERT(!popupWidgets.contains(widget));
- popupWidgets << widget;
- if (QGraphicsWidget *focusWidget = widget->focusWidget()) {
- focusWidget->setFocus(Qt::PopupFocusReason);
- } else {
- grabKeyboard((QGraphicsItem *)widget);
- if (focusItem && popupWidgets.size() == 1) {
- QFocusEvent event(QEvent::FocusOut, Qt::PopupFocusReason);
- sendEvent(focusItem, &event);
- }
- }
- grabMouse((QGraphicsItem *)widget);
-}
-
-/*!
- \internal
-
- Remove \a widget from the popup list. Important notes:
-
- \a widget is guaranteed to be in the list of popups, but it might not be
- the last entry; you can hide any item in the pop list before the others,
- and this must cause all later mouse grabbers to lose the grab.
-*/
-void QGraphicsScenePrivate::removePopup(QGraphicsWidget *widget, bool itemIsDying)
-{
- Q_ASSERT(widget);
- int index = popupWidgets.indexOf(widget);
- Q_ASSERT(index != -1);
-
- for (int i = popupWidgets.size() - 1; i >= index; --i) {
- QGraphicsWidget *widget = popupWidgets.takeLast();
- ungrabMouse(widget, itemIsDying);
- if (focusItem && popupWidgets.isEmpty()) {
- QFocusEvent event(QEvent::FocusIn, Qt::PopupFocusReason);
- sendEvent(focusItem, &event);
- } else if (keyboardGrabberItems.contains(static_cast<QGraphicsItem *>(widget))) {
- ungrabKeyboard(static_cast<QGraphicsItem *>(widget), itemIsDying);
- }
- if (!itemIsDying && widget->isVisible()) {
- widget->QGraphicsItem::d_ptr->setVisibleHelper(false, /* explicit = */ false);
- }
- }
-}
-
-/*!
- \internal
-*/
-void QGraphicsScenePrivate::grabMouse(QGraphicsItem *item, bool implicit)
-{
- // Append to list of mouse grabber items, and send a mouse grab event.
- if (mouseGrabberItems.contains(item)) {
- if (mouseGrabberItems.last() == item) {
- Q_ASSERT(!implicit);
- if (!lastMouseGrabberItemHasImplicitMouseGrab) {
- qWarning("QGraphicsItem::grabMouse: already a mouse grabber");
- } else {
- // Upgrade to an explicit mouse grab
- lastMouseGrabberItemHasImplicitMouseGrab = false;
- }
- } else {
- qWarning("QGraphicsItem::grabMouse: already blocked by mouse grabber: %p",
- mouseGrabberItems.last());
- }
- return;
- }
-
- // Send ungrab event to the last grabber.
- if (!mouseGrabberItems.isEmpty()) {
- QGraphicsItem *last = mouseGrabberItems.last();
- if (lastMouseGrabberItemHasImplicitMouseGrab) {
- // Implicit mouse grab is immediately lost.
- last->ungrabMouse();
- } else {
- // Just send ungrab event to current grabber.
- QEvent ungrabEvent(QEvent::UngrabMouse);
- sendEvent(last, &ungrabEvent);
- }
- }
-
- mouseGrabberItems << item;
- lastMouseGrabberItemHasImplicitMouseGrab = implicit;
-
- // Send grab event to current grabber.
- QEvent grabEvent(QEvent::GrabMouse);
- sendEvent(item, &grabEvent);
-}
-
-/*!
- \internal
-*/
-void QGraphicsScenePrivate::ungrabMouse(QGraphicsItem *item, bool itemIsDying)
-{
- int index = mouseGrabberItems.indexOf(item);
- if (index == -1) {
- qWarning("QGraphicsItem::ungrabMouse: not a mouse grabber");
- return;
- }
-
- if (item != mouseGrabberItems.last()) {
- // Recursively ungrab the next mouse grabber until we reach this item
- // to ensure state consistency.
- ungrabMouse(mouseGrabberItems.at(index + 1), itemIsDying);
- }
- if (!popupWidgets.isEmpty() && item == popupWidgets.last()) {
- // If the item is a popup, go via removePopup to ensure state
- // consistency and that it gets hidden correctly - beware that
- // removePopup() reenters this function to continue removing the grab.
- removePopup((QGraphicsWidget *)item, itemIsDying);
- return;
- }
-
- // Send notification about mouse ungrab.
- if (!itemIsDying) {
- QEvent event(QEvent::UngrabMouse);
- sendEvent(item, &event);
- }
-
- // Remove the item from the list of grabbers. Whenever this happens, we
- // reset the implicitGrab (there can be only ever be one implicit grabber
- // in a scene, and it is always the latest grabber; if the implicit grab
- // is lost, it is not automatically regained.
- mouseGrabberItems.takeLast();
- lastMouseGrabberItemHasImplicitMouseGrab = false;
-
- // Send notification about mouse regrab. ### It's unfortunate that all the
- // items get a GrabMouse event, but this is a rare case with a simple
- // implementation and it does ensure a consistent state.
- if (!itemIsDying && !mouseGrabberItems.isEmpty()) {
- QGraphicsItem *last = mouseGrabberItems.last();
- QEvent event(QEvent::GrabMouse);
- sendEvent(last, &event);
- }
-}
-
-/*!
- \internal
-*/
-void QGraphicsScenePrivate::clearMouseGrabber()
-{
- if (!mouseGrabberItems.isEmpty())
- mouseGrabberItems.first()->ungrabMouse();
- lastMouseGrabberItem = 0;
-}
-
-/*!
- \internal
-*/
-void QGraphicsScenePrivate::grabKeyboard(QGraphicsItem *item)
-{
- if (keyboardGrabberItems.contains(item)) {
- if (keyboardGrabberItems.last() == item)
- qWarning("QGraphicsItem::grabKeyboard: already a keyboard grabber");
- else
- qWarning("QGraphicsItem::grabKeyboard: already blocked by keyboard grabber: %p",
- keyboardGrabberItems.last());
- return;
- }
-
- // Send ungrab event to the last grabber.
- if (!keyboardGrabberItems.isEmpty()) {
- // Just send ungrab event to current grabber.
- QEvent ungrabEvent(QEvent::UngrabKeyboard);
- sendEvent(keyboardGrabberItems.last(), &ungrabEvent);
- }
-
- keyboardGrabberItems << item;
-
- // Send grab event to current grabber.
- QEvent grabEvent(QEvent::GrabKeyboard);
- sendEvent(item, &grabEvent);
-}
-
-/*!
- \internal
-*/
-void QGraphicsScenePrivate::ungrabKeyboard(QGraphicsItem *item, bool itemIsDying)
-{
- int index = keyboardGrabberItems.lastIndexOf(item);
- if (index == -1) {
- qWarning("QGraphicsItem::ungrabKeyboard: not a keyboard grabber");
- return;
- }
- if (item != keyboardGrabberItems.last()) {
- // Recursively ungrab the topmost keyboard grabber until we reach this
- // item to ensure state consistency.
- ungrabKeyboard(keyboardGrabberItems.at(index + 1), itemIsDying);
- }
-
- // Send notification about keyboard ungrab.
- if (!itemIsDying) {
- QEvent event(QEvent::UngrabKeyboard);
- sendEvent(item, &event);
- }
-
- // Remove the item from the list of grabbers.
- keyboardGrabberItems.takeLast();
-
- // Send notification about mouse regrab.
- if (!itemIsDying && !keyboardGrabberItems.isEmpty()) {
- QGraphicsItem *last = keyboardGrabberItems.last();
- QEvent event(QEvent::GrabKeyboard);
- sendEvent(last, &event);
- }
-}
-
-/*!
- \internal
-*/
-void QGraphicsScenePrivate::clearKeyboardGrabber()
-{
- if (!keyboardGrabberItems.isEmpty())
- ungrabKeyboard(keyboardGrabberItems.first());
-}
-
-void QGraphicsScenePrivate::enableMouseTrackingOnViews()
-{
- foreach (QGraphicsView *view, views)
- view->viewport()->setMouseTracking(true);
-}
-
-/*!
- Returns all items for the screen position in \a event.
-*/
-QList<QGraphicsItem *> QGraphicsScenePrivate::itemsAtPosition(const QPoint &/*screenPos*/,
- const QPointF &scenePos,
- QWidget *widget) const
-{
- Q_Q(const QGraphicsScene);
- QGraphicsView *view = widget ? qobject_cast<QGraphicsView *>(widget->parentWidget()) : 0;
- if (!view)
- return q->items(scenePos, Qt::IntersectsItemShape, Qt::DescendingOrder, QTransform());
-
- const QRectF pointRect(scenePos, QSizeF(1, 1));
- if (!view->isTransformed())
- return q->items(pointRect, Qt::IntersectsItemShape, Qt::DescendingOrder);
-
- const QTransform viewTransform = view->viewportTransform();
- return q->items(pointRect, Qt::IntersectsItemShape,
- Qt::DescendingOrder, viewTransform);
-}
-
-/*!
- \internal
-*/
-void QGraphicsScenePrivate::storeMouseButtonsForMouseGrabber(QGraphicsSceneMouseEvent *event)
-{
- for (int i = 0x1; i <= 0x10; i <<= 1) {
- if (event->buttons() & i) {
- mouseGrabberButtonDownPos.insert(Qt::MouseButton(i),
- mouseGrabberItems.last()->d_ptr->genericMapFromScene(event->scenePos(),
- event->widget()));
- mouseGrabberButtonDownScenePos.insert(Qt::MouseButton(i), event->scenePos());
- mouseGrabberButtonDownScreenPos.insert(Qt::MouseButton(i), event->screenPos());
- }
- }
-}
-
-/*!
- \internal
-*/
-void QGraphicsScenePrivate::installSceneEventFilter(QGraphicsItem *watched, QGraphicsItem *filter)
-{
- sceneEventFilters.insert(watched, filter);
-}
-
-/*!
- \internal
-*/
-void QGraphicsScenePrivate::removeSceneEventFilter(QGraphicsItem *watched, QGraphicsItem *filter)
-{
- if (!sceneEventFilters.contains(watched))
- return;
-
- QMultiMap<QGraphicsItem *, QGraphicsItem *>::Iterator it = sceneEventFilters.lowerBound(watched);
- QMultiMap<QGraphicsItem *, QGraphicsItem *>::Iterator end = sceneEventFilters.upperBound(watched);
- do {
- if (it.value() == filter)
- it = sceneEventFilters.erase(it);
- else
- ++it;
- } while (it != end);
-}
-
-/*!
- \internal
-*/
-bool QGraphicsScenePrivate::filterDescendantEvent(QGraphicsItem *item, QEvent *event)
-{
- if (item && (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorFiltersChildEvents)) {
- QGraphicsItem *parent = item->parentItem();
- while (parent) {
- if (parent->d_ptr->filtersDescendantEvents && parent->sceneEventFilter(item, event))
- return true;
- if (!(parent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorFiltersChildEvents))
- return false;
- parent = parent->parentItem();
- }
- }
- return false;
-}
-
-/*!
- \internal
-*/
-bool QGraphicsScenePrivate::filterEvent(QGraphicsItem *item, QEvent *event)
-{
- if (item && !sceneEventFilters.contains(item))
- return false;
-
- QMultiMap<QGraphicsItem *, QGraphicsItem *>::Iterator it = sceneEventFilters.lowerBound(item);
- QMultiMap<QGraphicsItem *, QGraphicsItem *>::Iterator end = sceneEventFilters.upperBound(item);
- while (it != end) {
- // ### The filterer and filteree might both be deleted.
- if (it.value()->sceneEventFilter(it.key(), event))
- return true;
- ++it;
- }
- return false;
-}
-
-/*!
- \internal
-
- This is the final dispatch point for any events from the scene to the
- item. It filters the event first - if the filter returns true, the event
- is considered to have been eaten by the filter, and is therefore stopped
- (the default filter returns false). Then/otherwise, if the item is
- enabled, the event is sent; otherwise it is stopped.
-*/
-bool QGraphicsScenePrivate::sendEvent(QGraphicsItem *item, QEvent *event)
-{
- if (QGraphicsObject *object = item->toGraphicsObject()) {
-#ifndef QT_NO_GESTURES
- QGestureManager *gestureManager = QApplicationPrivate::instance()->gestureManager;
- if (gestureManager) {
- if (gestureManager->filterEvent(object, event))
- return true;
- }
-#endif // QT_NO_GESTURES
- }
-
- if (filterEvent(item, event))
- return false;
- if (filterDescendantEvent(item, event))
- return false;
- if (!item || !item->isEnabled())
- return false;
- if (QGraphicsObject *o = item->toGraphicsObject()) {
- bool spont = event->spontaneous();
- if (spont ? qt_sendSpontaneousEvent(o, event) : QApplication::sendEvent(o, event))
- return true;
- event->spont = spont;
- }
- return item->sceneEvent(event);
-}
-
-/*!
- \internal
-*/
-void QGraphicsScenePrivate::cloneDragDropEvent(QGraphicsSceneDragDropEvent *dest,
- QGraphicsSceneDragDropEvent *source)
-{
- dest->setWidget(source->widget());
- dest->setPos(source->pos());
- dest->setScenePos(source->scenePos());
- dest->setScreenPos(source->screenPos());
- dest->setButtons(source->buttons());
- dest->setModifiers(source->modifiers());
- dest->setPossibleActions(source->possibleActions());
- dest->setProposedAction(source->proposedAction());
- dest->setDropAction(source->dropAction());
- dest->setSource(source->source());
- dest->setMimeData(source->mimeData());
-}
-
-/*!
- \internal
-*/
-void QGraphicsScenePrivate::sendDragDropEvent(QGraphicsItem *item,
- QGraphicsSceneDragDropEvent *dragDropEvent)
-{
- dragDropEvent->setPos(item->d_ptr->genericMapFromScene(dragDropEvent->scenePos(), dragDropEvent->widget()));
- sendEvent(item, dragDropEvent);
-}
-
-/*!
- \internal
-*/
-void QGraphicsScenePrivate::sendHoverEvent(QEvent::Type type, QGraphicsItem *item,
- QGraphicsSceneHoverEvent *hoverEvent)
-{
- QGraphicsSceneHoverEvent event(type);
- event.setWidget(hoverEvent->widget());
- event.setPos(item->d_ptr->genericMapFromScene(hoverEvent->scenePos(), hoverEvent->widget()));
- event.setScenePos(hoverEvent->scenePos());
- event.setScreenPos(hoverEvent->screenPos());
- event.setLastPos(item->d_ptr->genericMapFromScene(hoverEvent->lastScenePos(), hoverEvent->widget()));
- event.setLastScenePos(hoverEvent->lastScenePos());
- event.setLastScreenPos(hoverEvent->lastScreenPos());
- event.setModifiers(hoverEvent->modifiers());
- sendEvent(item, &event);
-}
-
-/*!
- \internal
-*/
-void QGraphicsScenePrivate::sendMouseEvent(QGraphicsSceneMouseEvent *mouseEvent)
-{
- if (mouseEvent->button() == 0 && mouseEvent->buttons() == 0 && lastMouseGrabberItemHasImplicitMouseGrab) {
- // ### This is a temporary fix for until we get proper mouse
- // grab events.
- clearMouseGrabber();
- return;
- }
-
- QGraphicsItem *item = mouseGrabberItems.last();
- if (item->isBlockedByModalPanel())
- return;
-
- for (int i = 0x1; i <= 0x10; i <<= 1) {
- Qt::MouseButton button = Qt::MouseButton(i);
- mouseEvent->setButtonDownPos(button, mouseGrabberButtonDownPos.value(button, item->d_ptr->genericMapFromScene(mouseEvent->scenePos(), mouseEvent->widget())));
- mouseEvent->setButtonDownScenePos(button, mouseGrabberButtonDownScenePos.value(button, mouseEvent->scenePos()));
- mouseEvent->setButtonDownScreenPos(button, mouseGrabberButtonDownScreenPos.value(button, mouseEvent->screenPos()));
- }
- mouseEvent->setPos(item->d_ptr->genericMapFromScene(mouseEvent->scenePos(), mouseEvent->widget()));
- mouseEvent->setLastPos(item->d_ptr->genericMapFromScene(mouseEvent->lastScenePos(), mouseEvent->widget()));
- sendEvent(item, mouseEvent);
-}
-
-/*!
- \internal
-*/
-void QGraphicsScenePrivate::mousePressEventHandler(QGraphicsSceneMouseEvent *mouseEvent)
-{
- Q_Q(QGraphicsScene);
-
- // Ignore by default, unless we find a mouse grabber that accepts it.
- mouseEvent->ignore();
-
- // Deliver to any existing mouse grabber.
- if (!mouseGrabberItems.isEmpty()) {
- if (mouseGrabberItems.last()->isBlockedByModalPanel())
- return;
- // The event is ignored by default, but we disregard the event's
- // accepted state after delivery; the mouse is grabbed, after all.
- sendMouseEvent(mouseEvent);
- return;
- }
-
- // Start by determining the number of items at the current position.
- // Reuse value from earlier calculations if possible.
- if (cachedItemsUnderMouse.isEmpty()) {
- cachedItemsUnderMouse = itemsAtPosition(mouseEvent->screenPos(),
- mouseEvent->scenePos(),
- mouseEvent->widget());
- }
-
- // Update window activation.
- QGraphicsItem *topItem = cachedItemsUnderMouse.value(0);
- QGraphicsWidget *newActiveWindow = topItem ? topItem->window() : 0;
- if (newActiveWindow && newActiveWindow->isBlockedByModalPanel(&topItem)) {
- // pass activation to the blocking modal window
- newActiveWindow = topItem ? topItem->window() : 0;
- }
-
- if (newActiveWindow != q->activeWindow())
- q->setActiveWindow(newActiveWindow);
-
- // Set focus on the topmost enabled item that can take focus.
- bool setFocus = false;
-
- foreach (QGraphicsItem *item, cachedItemsUnderMouse) {
- if (item->isBlockedByModalPanel()
- || (item->d_ptr->flags & QGraphicsItem::ItemStopsFocusHandling)) {
- // Make sure we don't clear focus.
- setFocus = true;
- break;
- }
- if (item->isEnabled() && ((item->flags() & QGraphicsItem::ItemIsFocusable))) {
- if (!item->isWidget() || ((QGraphicsWidget *)item)->focusPolicy() & Qt::ClickFocus) {
- setFocus = true;
- if (item != q->focusItem() && item->d_ptr->mouseSetsFocus)
- q->setFocusItem(item, Qt::MouseFocusReason);
- break;
- }
- }
- if (item->isPanel())
- break;
- if (item->d_ptr->flags & QGraphicsItem::ItemStopsClickFocusPropagation)
- break;
- }
-
- // Check for scene modality.
- bool sceneModality = false;
- for (int i = 0; i < modalPanels.size(); ++i) {
- if (modalPanels.at(i)->panelModality() == QGraphicsItem::SceneModal) {
- sceneModality = true;
- break;
- }
- }
-
- // If nobody could take focus, clear it.
- if (!stickyFocus && !setFocus && !sceneModality)
- q->setFocusItem(0, Qt::MouseFocusReason);
-
- // Any item will do.
- if (sceneModality && cachedItemsUnderMouse.isEmpty())
- cachedItemsUnderMouse << modalPanels.first();
-
- // Find a mouse grabber by sending mouse press events to all mouse grabber
- // candidates one at a time, until the event is accepted. It's accepted by
- // default, so the receiver has to explicitly ignore it for it to pass
- // through.
- foreach (QGraphicsItem *item, cachedItemsUnderMouse) {
- if (!(item->acceptedMouseButtons() & mouseEvent->button())) {
- // Skip items that don't accept the event's mouse button.
- continue;
- }
-
- // Check if this item is blocked by a modal panel and deliver the mouse event to the
- // blocking panel instead of this item if blocked.
- (void) item->isBlockedByModalPanel(&item);
-
- grabMouse(item, /* implicit = */ true);
- mouseEvent->accept();
-
- // check if the item we are sending to are disabled (before we send the event)
- bool disabled = !item->isEnabled();
- bool isPanel = item->isPanel();
- if (mouseEvent->type() == QEvent::GraphicsSceneMouseDoubleClick
- && item != lastMouseGrabberItem && lastMouseGrabberItem) {
- // If this item is different from the item that received the last
- // mouse event, and mouseEvent is a doubleclick event, then the
- // event is converted to a press. Known limitation:
- // Triple-clicking will not generate a doubleclick, though.
- QGraphicsSceneMouseEvent mousePress(QEvent::GraphicsSceneMousePress);
- mousePress.spont = mouseEvent->spont;
- mousePress.accept();
- mousePress.setButton(mouseEvent->button());
- mousePress.setButtons(mouseEvent->buttons());
- mousePress.setScreenPos(mouseEvent->screenPos());
- mousePress.setScenePos(mouseEvent->scenePos());
- mousePress.setModifiers(mouseEvent->modifiers());
- mousePress.setWidget(mouseEvent->widget());
- mousePress.setButtonDownPos(mouseEvent->button(),
- mouseEvent->buttonDownPos(mouseEvent->button()));
- mousePress.setButtonDownScenePos(mouseEvent->button(),
- mouseEvent->buttonDownScenePos(mouseEvent->button()));
- mousePress.setButtonDownScreenPos(mouseEvent->button(),
- mouseEvent->buttonDownScreenPos(mouseEvent->button()));
- sendMouseEvent(&mousePress);
- mouseEvent->setAccepted(mousePress.isAccepted());
- } else {
- sendMouseEvent(mouseEvent);
- }
-
- bool dontSendUngrabEvents = mouseGrabberItems.isEmpty() || mouseGrabberItems.last() != item;
- if (disabled) {
- ungrabMouse(item, /* itemIsDying = */ dontSendUngrabEvents);
- break;
- }
- if (mouseEvent->isAccepted()) {
- if (!mouseGrabberItems.isEmpty())
- storeMouseButtonsForMouseGrabber(mouseEvent);
- lastMouseGrabberItem = item;
- return;
- }
- ungrabMouse(item, /* itemIsDying = */ dontSendUngrabEvents);
-
- // Don't propagate through panels.
- if (isPanel)
- break;
- }
-
- // Is the event still ignored? Then the mouse press goes to the scene.
- // Reset the mouse grabber, clear the selection, clear focus, and leave
- // the event ignored so that it can propagate through the originating
- // view.
- if (!mouseEvent->isAccepted()) {
- clearMouseGrabber();
-
- QGraphicsView *view = mouseEvent->widget() ? qobject_cast<QGraphicsView *>(mouseEvent->widget()->parentWidget()) : 0;
- bool dontClearSelection = view && view->dragMode() == QGraphicsView::ScrollHandDrag;
- if (!dontClearSelection) {
- // Clear the selection if the originating view isn't in scroll
- // hand drag mode. The view will clear the selection if no drag
- // happened.
- q->clearSelection();
- }
- }
-}
-
-/*!
- \internal
-
- Ensures that the list of toplevels is sorted by insertion order, and that
- the siblingIndexes are packed (no gaps), and start at 0.
-
- ### This function is almost identical to
- QGraphicsItemPrivate::ensureSequentialSiblingIndex().
-*/
-void QGraphicsScenePrivate::ensureSequentialTopLevelSiblingIndexes()
-{
- if (!topLevelSequentialOrdering) {
- qSort(topLevelItems.begin(), topLevelItems.end(), QGraphicsItemPrivate::insertionOrder);
- topLevelSequentialOrdering = true;
- needSortTopLevelItems = 1;
- }
- if (holesInTopLevelSiblingIndex) {
- holesInTopLevelSiblingIndex = 0;
- for (int i = 0; i < topLevelItems.size(); ++i)
- topLevelItems[i]->d_ptr->siblingIndex = i;
- }
-}
-
-/*!
- \internal
-
- Set the font and propagate the changes if the font is different from the
- current font.
-*/
-void QGraphicsScenePrivate::setFont_helper(const QFont &font)
-{
- if (this->font == font && this->font.resolve() == font.resolve())
- return;
- updateFont(font);
-}
-
-/*!
- \internal
-
- Resolve the scene's font against the application font, and propagate the
- changes too all items in the scene.
-*/
-void QGraphicsScenePrivate::resolveFont()
-{
- QFont naturalFont = QApplication::font();
- naturalFont.resolve(0);
- QFont resolvedFont = font.resolve(naturalFont);
- updateFont(resolvedFont);
-}
-
-/*!
- \internal
-
- Update the font, and whether or not it has changed, reresolve all fonts in
- the scene.
-*/
-void QGraphicsScenePrivate::updateFont(const QFont &font)
-{
- Q_Q(QGraphicsScene);
-
- // Update local font setting.
- this->font = font;
-
- // Resolve the fonts of all top-level widget items, or widget items
- // whose parent is not a widget.
- foreach (QGraphicsItem *item, q->items()) {
- if (!item->parentItem()) {
- // Resolvefont for an item is a noop operation, but
- // every item can be a widget, or can have a widget
- // childre.
- item->d_ptr->resolveFont(font.resolve());
- }
- }
-
- // Send the scene a FontChange event.
- QEvent event(QEvent::FontChange);
- QApplication::sendEvent(q, &event);
-}
-
-/*!
- \internal
-
- Set the palette and propagate the changes if the palette is different from
- the current palette.
-*/
-void QGraphicsScenePrivate::setPalette_helper(const QPalette &palette)
-{
- if (this->palette == palette && this->palette.resolve() == palette.resolve())
- return;
- updatePalette(palette);
-}
-
-/*!
- \internal
-
- Resolve the scene's palette against the application palette, and propagate
- the changes too all items in the scene.
-*/
-void QGraphicsScenePrivate::resolvePalette()
-{
- QPalette naturalPalette = QApplication::palette();
- naturalPalette.resolve(0);
- QPalette resolvedPalette = palette.resolve(naturalPalette);
- updatePalette(resolvedPalette);
-}
-
-/*!
- \internal
-
- Update the palette, and whether or not it has changed, reresolve all
- palettes in the scene.
-*/
-void QGraphicsScenePrivate::updatePalette(const QPalette &palette)
-{
- Q_Q(QGraphicsScene);
-
- // Update local palette setting.
- this->palette = palette;
-
- // Resolve the palettes of all top-level widget items, or widget items
- // whose parent is not a widget.
- foreach (QGraphicsItem *item, q->items()) {
- if (!item->parentItem()) {
- // Resolvefont for an item is a noop operation, but
- // every item can be a widget, or can have a widget
- // childre.
- item->d_ptr->resolvePalette(palette.resolve());
- }
- }
-
- // Send the scene a PaletteChange event.
- QEvent event(QEvent::PaletteChange);
- QApplication::sendEvent(q, &event);
-}
-
-/*!
- Constructs a QGraphicsScene object. The \a parent parameter is
- passed to QObject's constructor.
-*/
-QGraphicsScene::QGraphicsScene(QObject *parent)
- : QObject(*new QGraphicsScenePrivate, parent)
-{
- d_func()->init();
-}
-
-/*!
- Constructs a QGraphicsScene object, using \a sceneRect for its
- scene rectangle. The \a parent parameter is passed to QObject's
- constructor.
-
- \sa sceneRect
-*/
-QGraphicsScene::QGraphicsScene(const QRectF &sceneRect, QObject *parent)
- : QObject(*new QGraphicsScenePrivate, parent)
-{
- d_func()->init();
- setSceneRect(sceneRect);
-}
-
-/*!
- Constructs a QGraphicsScene object, using the rectangle specified
- by (\a x, \a y), and the given \a width and \a height for its
- scene rectangle. The \a parent parameter is passed to QObject's
- constructor.
-
- \sa sceneRect
-*/
-QGraphicsScene::QGraphicsScene(qreal x, qreal y, qreal width, qreal height, QObject *parent)
- : QObject(*new QGraphicsScenePrivate, parent)
-{
- d_func()->init();
- setSceneRect(x, y, width, height);
-}
-
-/*!
- Removes and deletes all items from the scene object
- before destroying the scene object. The scene object
- is removed from the application's global scene list,
- and it is removed from all associated views.
-*/
-QGraphicsScene::~QGraphicsScene()
-{
- Q_D(QGraphicsScene);
-
- // Remove this scene from qApp's global scene list.
- if (!QApplicationPrivate::is_app_closing)
- qApp->d_func()->scene_list.removeAll(this);
-
- clear();
-
- // Remove this scene from all associated views.
- for (int j = 0; j < d->views.size(); ++j)
- d->views.at(j)->setScene(0);
-}
-
-/*!
- \property QGraphicsScene::sceneRect
- \brief the scene rectangle; the bounding rectangle of the scene
-
- The scene rectangle defines the extent of the scene. It is
- primarily used by QGraphicsView to determine the view's default
- scrollable area, and by QGraphicsScene to manage item indexing.
-
- If unset, or if set to a null QRectF, sceneRect() will return the largest
- bounding rect of all items on the scene since the scene was created (i.e.,
- a rectangle that grows when items are added to or moved in the scene, but
- never shrinks).
-
- \sa width(), height(), QGraphicsView::sceneRect
-*/
-QRectF QGraphicsScene::sceneRect() const
-{
- Q_D(const QGraphicsScene);
- if (d->hasSceneRect)
- return d->sceneRect;
-
- if (d->dirtyGrowingItemsBoundingRect) {
- // Lazily update the growing items bounding rect
- QGraphicsScenePrivate *thatd = const_cast<QGraphicsScenePrivate *>(d);
- QRectF oldGrowingBoundingRect = thatd->growingItemsBoundingRect;
- thatd->growingItemsBoundingRect |= itemsBoundingRect();
- thatd->dirtyGrowingItemsBoundingRect = false;
- if (oldGrowingBoundingRect != thatd->growingItemsBoundingRect)
- emit const_cast<QGraphicsScene *>(this)->sceneRectChanged(thatd->growingItemsBoundingRect);
- }
- return d->growingItemsBoundingRect;
-}
-void QGraphicsScene::setSceneRect(const QRectF &rect)
-{
- Q_D(QGraphicsScene);
- if (rect != d->sceneRect) {
- d->hasSceneRect = !rect.isNull();
- d->sceneRect = rect;
- emit sceneRectChanged(d->hasSceneRect ? rect : d->growingItemsBoundingRect);
- }
-}
-
-/*!
- \fn qreal QGraphicsScene::width() const
-
- This convenience function is equivalent to calling sceneRect().width().
-
- \sa height()
-*/
-
-/*!
- \fn qreal QGraphicsScene::height() const
-
- This convenience function is equivalent to calling \c sceneRect().height().
-
- \sa width()
-*/
-
-/*!
- Renders the \a source rect from scene into \a target, using \a painter. This
- function is useful for capturing the contents of the scene onto a paint
- device, such as a QImage (e.g., to take a screenshot), or for printing
- with QPrinter. For example:
-
- \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsscene.cpp 1
-
- If \a source is a null rect, this function will use sceneRect() to
- determine what to render. If \a target is a null rect, the dimensions of \a
- painter's paint device will be used.
-
- The source rect contents will be transformed according to \a
- aspectRatioMode to fit into the target rect. By default, the aspect ratio
- is kept, and \a source is scaled to fit in \a target.
-
- \sa QGraphicsView::render()
-*/
-void QGraphicsScene::render(QPainter *painter, const QRectF &target, const QRectF &source,
- Qt::AspectRatioMode aspectRatioMode)
-{
- // ### Switch to using the recursive rendering algorithm instead.
-
- // Default source rect = scene rect
- QRectF sourceRect = source;
- if (sourceRect.isNull())
- sourceRect = sceneRect();
-
- // Default target rect = device rect
- QRectF targetRect = target;
- if (targetRect.isNull()) {
- if (painter->device()->devType() == QInternal::Picture)
- targetRect = sourceRect;
- else
- targetRect.setRect(0, 0, painter->device()->width(), painter->device()->height());
- }
-
- // Find the ideal x / y scaling ratio to fit \a source into \a target.
- qreal xratio = targetRect.width() / sourceRect.width();
- qreal yratio = targetRect.height() / sourceRect.height();
-
- // Scale according to the aspect ratio mode.
- switch (aspectRatioMode) {
- case Qt::KeepAspectRatio:
- xratio = yratio = qMin(xratio, yratio);
- break;
- case Qt::KeepAspectRatioByExpanding:
- xratio = yratio = qMax(xratio, yratio);
- break;
- case Qt::IgnoreAspectRatio:
- break;
- }
-
- // Find all items to draw, and reverse the list (we want to draw
- // in reverse order).
- QList<QGraphicsItem *> itemList = items(sourceRect, Qt::IntersectsItemBoundingRect);
- QGraphicsItem **itemArray = new QGraphicsItem *[itemList.size()];
- int numItems = itemList.size();
- for (int i = 0; i < numItems; ++i)
- itemArray[numItems - i - 1] = itemList.at(i);
- itemList.clear();
-
- painter->save();
-
- // Transform the painter.
- painter->setClipRect(targetRect, Qt::IntersectClip);
- QTransform painterTransform;
- painterTransform *= QTransform()
- .translate(targetRect.left(), targetRect.top())
- .scale(xratio, yratio)
- .translate(-sourceRect.left(), -sourceRect.top());
- painter->setWorldTransform(painterTransform, true);
-
- // Two unit vectors.
- QLineF v1(0, 0, 1, 0);
- QLineF v2(0, 0, 0, 1);
-
- // Generate the style options
- QStyleOptionGraphicsItem *styleOptionArray = new QStyleOptionGraphicsItem[numItems];
- for (int i = 0; i < numItems; ++i)
- itemArray[i]->d_ptr->initStyleOption(&styleOptionArray[i], painterTransform, targetRect.toRect());
-
- // Render the scene.
- drawBackground(painter, sourceRect);
- drawItems(painter, numItems, itemArray, styleOptionArray);
- drawForeground(painter, sourceRect);
-
- delete [] itemArray;
- delete [] styleOptionArray;
-
- painter->restore();
-}
-
-/*!
- \property QGraphicsScene::itemIndexMethod
- \brief the item indexing method.
-
- QGraphicsScene applies an indexing algorithm to the scene, to speed up
- item discovery functions like items() and itemAt(). Indexing is most
- efficient for static scenes (i.e., where items don't move around). For
- dynamic scenes, or scenes with many animated items, the index bookkeeping
- can outweight the fast lookup speeds.
-
- For the common case, the default index method BspTreeIndex works fine. If
- your scene uses many animations and you are experiencing slowness, you can
- disable indexing by calling \c setItemIndexMethod(NoIndex).
-
- \sa bspTreeDepth
-*/
-QGraphicsScene::ItemIndexMethod QGraphicsScene::itemIndexMethod() const
-{
- Q_D(const QGraphicsScene);
- return d->indexMethod;
-}
-void QGraphicsScene::setItemIndexMethod(ItemIndexMethod method)
-{
- Q_D(QGraphicsScene);
- if (d->indexMethod == method)
- return;
-
- d->indexMethod = method;
-
- QList<QGraphicsItem *> oldItems = d->index->items(Qt::DescendingOrder);
- delete d->index;
- if (method == BspTreeIndex)
- d->index = new QGraphicsSceneBspTreeIndex(this);
- else
- d->index = new QGraphicsSceneLinearIndex(this);
- for (int i = oldItems.size() - 1; i >= 0; --i)
- d->index->addItem(oldItems.at(i));
-}
-
-/*!
- \property QGraphicsScene::bspTreeDepth
- \brief the depth of QGraphicsScene's BSP index tree
- \since 4.3
-
- This property has no effect when NoIndex is used.
-
- This value determines the depth of QGraphicsScene's BSP tree. The depth
- directly affects QGraphicsScene's performance and memory usage; the latter
- growing exponentially with the depth of the tree. With an optimal tree
- depth, QGraphicsScene can instantly determine the locality of items, even
- for scenes with thousands or millions of items. This also greatly improves
- rendering performance.
-
- By default, the value is 0, in which case Qt will guess a reasonable
- default depth based on the size, location and number of items in the
- scene. If these parameters change frequently, however, you may experience
- slowdowns as QGraphicsScene retunes the depth internally. You can avoid
- potential slowdowns by fixating the tree depth through setting this
- property.
-
- The depth of the tree and the size of the scene rectangle decide the
- granularity of the scene's partitioning. The size of each scene segment is
- determined by the following algorithm:
-
- \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsscene.cpp 2
-
- The BSP tree has an optimal size when each segment contains between 0 and
- 10 items.
-
- \sa itemIndexMethod
-*/
-int QGraphicsScene::bspTreeDepth() const
-{
- Q_D(const QGraphicsScene);
- QGraphicsSceneBspTreeIndex *bspTree = qobject_cast<QGraphicsSceneBspTreeIndex *>(d->index);
- return bspTree ? bspTree->bspTreeDepth() : 0;
-}
-void QGraphicsScene::setBspTreeDepth(int depth)
-{
- Q_D(QGraphicsScene);
- if (depth < 0) {
- qWarning("QGraphicsScene::setBspTreeDepth: invalid depth %d ignored; must be >= 0", depth);
- return;
- }
-
- QGraphicsSceneBspTreeIndex *bspTree = qobject_cast<QGraphicsSceneBspTreeIndex *>(d->index);
- if (!bspTree) {
- qWarning("QGraphicsScene::setBspTreeDepth: can not apply if indexing method is not BSP");
- return;
- }
- bspTree->setBspTreeDepth(depth);
-}
-
-/*!
- \property QGraphicsScene::sortCacheEnabled
- \brief whether sort caching is enabled
- \since 4.5
- \obsolete
-
- Since Qt 4.6, this property has no effect.
-*/
-bool QGraphicsScene::isSortCacheEnabled() const
-{
- Q_D(const QGraphicsScene);
- return d->sortCacheEnabled;
-}
-void QGraphicsScene::setSortCacheEnabled(bool enabled)
-{
- Q_D(QGraphicsScene);
- if (d->sortCacheEnabled == enabled)
- return;
- d->sortCacheEnabled = enabled;
-}
-
-/*!
- Calculates and returns the bounding rect of all items on the scene. This
- function works by iterating over all items, and because if this, it can
- be slow for large scenes.
-
- \sa sceneRect()
-*/
-QRectF QGraphicsScene::itemsBoundingRect() const
-{
- // Does not take untransformable items into account.
- QRectF boundingRect;
- foreach (QGraphicsItem *item, items())
- boundingRect |= item->sceneBoundingRect();
- return boundingRect;
-}
-
-/*!
- Returns a list of all items in the scene in descending stacking order.
-
- \sa addItem(), removeItem(), {QGraphicsItem#Sorting}{Sorting}
-*/
-QList<QGraphicsItem *> QGraphicsScene::items() const
-{
- Q_D(const QGraphicsScene);
- return d->index->items(Qt::DescendingOrder);
-}
-
-/*!
- Returns an ordered list of all items on the scene. \a order decides the
- stacking order.
-
- \sa addItem(), removeItem(), {QGraphicsItem#Sorting}{Sorting}
-*/
-QList<QGraphicsItem *> QGraphicsScene::items(Qt::SortOrder order) const
-{
- Q_D(const QGraphicsScene);
- return d->index->items(order);
-}
-
-/*!
- \obsolete
-
- Returns all visible items at position \a pos in the scene. The items are
- listed in descending stacking order (i.e., the first item in the list is the
- top-most item, and the last item is the bottom-most item).
-
- This function is deprecated and returns incorrect results if the scene
- contains items that ignore transformations. Use the overload that takes
- a QTransform instead.
-
- \sa itemAt(), {QGraphicsItem#Sorting}{Sorting}
-*/
-QList<QGraphicsItem *> QGraphicsScene::items(const QPointF &pos) const
-{
- Q_D(const QGraphicsScene);
- return d->index->items(pos, Qt::IntersectsItemShape, Qt::DescendingOrder);
-}
-
-/*!
- \overload
- \obsolete
-
- Returns all visible items that, depending on \a mode, are either inside or
- intersect with the specified \a rectangle.
-
- The default value for \a mode is Qt::IntersectsItemShape; all items whose
- exact shape intersects with or is contained by \a rectangle are returned.
-
- This function is deprecated and returns incorrect results if the scene
- contains items that ignore transformations. Use the overload that takes
- a QTransform instead.
-
- \sa itemAt(), {QGraphicsItem#Sorting}{Sorting}
-*/
-QList<QGraphicsItem *> QGraphicsScene::items(const QRectF &rectangle, Qt::ItemSelectionMode mode) const
-{
- Q_D(const QGraphicsScene);
- return d->index->items(rectangle, mode, Qt::DescendingOrder);
-}
-
-/*!
- \fn QList<QGraphicsItem *> QGraphicsScene::items(qreal x, qreal y, qreal w, qreal h, Qt::ItemSelectionMode mode) const
- \obsolete
- \since 4.3
-
- This convenience function is equivalent to calling items(QRectF(\a x, \a y, \a w, \a h), \a mode).
-
- This function is deprecated and returns incorrect results if the scene
- contains items that ignore transformations. Use the overload that takes
- a QTransform instead.
-*/
-
-/*!
- \fn QList<QGraphicsItem *> QGraphicsScene::items(qreal x, qreal y, qreal w, qreal h, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const
- \overload
- \since 4.6
-
- \brief Returns all visible items that, depending on \a mode, are
- either inside or intersect with the rectangle defined by \a x, \a y,
- \a w and \a h, in a list sorted using \a order.
-
- \a deviceTransform is the transformation that applies to the view, and needs to
- be provided if the scene contains items that ignore transformations.
-*/
-
-/*!
- \fn QList<QGraphicsItem *> QGraphicsScene::items(const QPolygonF &polygon, Qt::ItemSelectionMode mode) const
- \overload
- \obsolete
-
- Returns all visible items that, depending on \a mode, are either inside or
- intersect with the polygon \a polygon.
-
- The default value for \a mode is Qt::IntersectsItemShape; all items whose
- exact shape intersects with or is contained by \a polygon are returned.
-
- This function is deprecated and returns incorrect results if the scene
- contains items that ignore transformations. Use the overload that takes
- a QTransform instead.
-
- \sa itemAt(), {QGraphicsItem#Sorting}{Sorting}
-*/
-QList<QGraphicsItem *> QGraphicsScene::items(const QPolygonF &polygon, Qt::ItemSelectionMode mode) const
-{
- Q_D(const QGraphicsScene);
- return d->index->items(polygon, mode, Qt::DescendingOrder);
-}
-
-/*!
- \fn QList<QGraphicsItem *> QGraphicsScene::items(const QPainterPath &path, Qt::ItemSelectionMode mode) const
- \overload
- \obsolete
-
- Returns all visible items that, depending on \a path, are either inside or
- intersect with the path \a path.
-
- The default value for \a mode is Qt::IntersectsItemShape; all items whose
- exact shape intersects with or is contained by \a path are returned.
-
- This function is deprecated and returns incorrect results if the scene
- contains items that ignore transformations. Use the overload that takes
- a QTransform instead.
-
- \sa itemAt(), {QGraphicsItem#Sorting}{Sorting}
-*/
-QList<QGraphicsItem *> QGraphicsScene::items(const QPainterPath &path, Qt::ItemSelectionMode mode) const
-{
- Q_D(const QGraphicsScene);
- return d->index->items(path, mode, Qt::DescendingOrder);
-}
-
-/*!
- \fn QList<QGraphicsItem *> QGraphicsScene::items(const QPointF &pos, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const
- \since 4.6
-
- \brief Returns all visible items that, depending on \a mode, are at
- the specified \a pos in a list sorted using \a order.
-
- The default value for \a mode is Qt::IntersectsItemShape; all items whose
- exact shape intersects with \a pos are returned.
-
- \a deviceTransform is the transformation that applies to the view, and needs to
- be provided if the scene contains items that ignore transformations.
-
- \sa itemAt(), {QGraphicsItem#Sorting}{Sorting}
-*/
-QList<QGraphicsItem *> QGraphicsScene::items(const QPointF &pos, Qt::ItemSelectionMode mode,
- Qt::SortOrder order, const QTransform &deviceTransform) const
-{
- Q_D(const QGraphicsScene);
- return d->index->items(pos, mode, order, deviceTransform);
-}
-
-/*!
- \fn QList<QGraphicsItem *> QGraphicsScene::items(const QRectF &rect, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const
- \overload
- \since 4.6
-
- \brief Returns all visible items that, depending on \a mode, are
- either inside or intersect with the specified \a rect and return a
- list sorted using \a order.
-
- The default value for \a mode is Qt::IntersectsItemShape; all items whose
- exact shape intersects with or is contained by \a rect are returned.
-
- \a deviceTransform is the transformation that applies to the view, and needs to
- be provided if the scene contains items that ignore transformations.
-
- \sa itemAt(), {QGraphicsItem#Sorting}{Sorting}
-*/
-QList<QGraphicsItem *> QGraphicsScene::items(const QRectF &rect, Qt::ItemSelectionMode mode,
- Qt::SortOrder order, const QTransform &deviceTransform) const
-{
- Q_D(const QGraphicsScene);
- return d->index->items(rect, mode, order, deviceTransform);
-}
-
-/*!
- \fn QList<QGraphicsItem *> QGraphicsScene::items(const QPolygonF &polygon, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const
- \overload
- \since 4.6
-
- \brief Returns all visible items that, depending on \a mode, are
- either inside or intersect with the specified \a polygon and return
- a list sorted using \a order.
-
- The default value for \a mode is Qt::IntersectsItemShape; all items whose
- exact shape intersects with or is contained by \a polygon are returned.
-
- \a deviceTransform is the transformation that applies to the view, and needs to
- be provided if the scene contains items that ignore transformations.
-
- \sa itemAt(), {QGraphicsItem#Sorting}{Sorting}
-*/
-QList<QGraphicsItem *> QGraphicsScene::items(const QPolygonF &polygon, Qt::ItemSelectionMode mode,
- Qt::SortOrder order, const QTransform &deviceTransform) const
-{
- Q_D(const QGraphicsScene);
- return d->index->items(polygon, mode, order, deviceTransform);
-}
-
-/*!
- \fn QList<QGraphicsItem *> QGraphicsScene::items(const QPainterPath &path, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const
- \overload
- \since 4.6
-
- \brief Returns all visible items that, depending on \a mode, are
- either inside or intersect with the specified \a path and return a
- list sorted using \a order.
-
- The default value for \a mode is Qt::IntersectsItemShape; all items whose
- exact shape intersects with or is contained by \a path are returned.
-
- \a deviceTransform is the transformation that applies to the view, and needs to
- be provided if the scene contains items that ignore transformations.
-
- \sa itemAt(), {QGraphicsItem#Sorting}{Sorting}
-*/
-QList<QGraphicsItem *> QGraphicsScene::items(const QPainterPath &path, Qt::ItemSelectionMode mode,
- Qt::SortOrder order, const QTransform &deviceTransform) const
-{
- Q_D(const QGraphicsScene);
- return d->index->items(path, mode, order, deviceTransform);
-}
-
-/*!
- Returns a list of all items that collide with \a item. Collisions are
- determined by calling QGraphicsItem::collidesWithItem(); the collision
- detection is determined by \a mode. By default, all items whose shape
- intersects \a item or is contained inside \a item's shape are returned.
-
- The items are returned in descending stacking order (i.e., the first item
- in the list is the uppermost item, and the last item is the lowermost
- item).
-
- \sa items(), itemAt(), QGraphicsItem::collidesWithItem(), {QGraphicsItem#Sorting}{Sorting}
-*/
-QList<QGraphicsItem *> QGraphicsScene::collidingItems(const QGraphicsItem *item,
- Qt::ItemSelectionMode mode) const
-{
- Q_D(const QGraphicsScene);
- if (!item) {
- qWarning("QGraphicsScene::collidingItems: cannot find collisions for null item");
- return QList<QGraphicsItem *>();
- }
-
- // Does not support ItemIgnoresTransformations.
- QList<QGraphicsItem *> tmp;
- foreach (QGraphicsItem *itemInVicinity, d->index->estimateItems(item->sceneBoundingRect(), Qt::DescendingOrder)) {
- if (item != itemInVicinity && item->collidesWithItem(itemInVicinity, mode))
- tmp << itemInVicinity;
- }
- return tmp;
-}
-
-/*!
- \overload
- \obsolete
-
- Returns the topmost visible item at the specified \a position, or 0 if
- there are no items at this position.
-
- This function is deprecated and returns incorrect results if the scene
- contains items that ignore transformations. Use the overload that takes
- a QTransform instead.
-
- \sa items(), collidingItems(), {QGraphicsItem#Sorting}{Sorting}
-*/
-QGraphicsItem *QGraphicsScene::itemAt(const QPointF &position) const
-{
- QList<QGraphicsItem *> itemsAtPoint = items(position);
- return itemsAtPoint.isEmpty() ? 0 : itemsAtPoint.first();
-}
-
-/*!
- \since 4.6
-
- Returns the topmost visible item at the specified \a position, or 0
- if there are no items at this position.
-
- \a deviceTransform is the transformation that applies to the view, and needs to
- be provided if the scene contains items that ignore transformations.
-
- \sa items(), collidingItems(), {QGraphicsItem#Sorting}{Sorting}
-*/
-QGraphicsItem *QGraphicsScene::itemAt(const QPointF &position, const QTransform &deviceTransform) const
-{
- QList<QGraphicsItem *> itemsAtPoint = items(position, Qt::IntersectsItemShape,
- Qt::DescendingOrder, deviceTransform);
- return itemsAtPoint.isEmpty() ? 0 : itemsAtPoint.first();
-}
-
-/*!
- \fn QGraphicsScene::itemAt(qreal x, qreal y, const QTransform &deviceTransform) const
- \overload
- \since 4.6
-
- Returns the topmost item at the position specified by (\a x, \a
- y), or 0 if there are no items at this position.
-
- \a deviceTransform is the transformation that applies to the view, and needs to
- be provided if the scene contains items that ignore transformations.
-
- This convenience function is equivalent to calling \c
- {itemAt(QPointF(x, y), deviceTransform)}.
-*/
-
-/*!
- \fn QGraphicsScene::itemAt(qreal x, qreal y) const
- \overload
- \obsolete
-
- Returns the topmost item at the position specified by (\a x, \a
- y), or 0 if there are no items at this position.
-
- This convenience function is equivalent to calling \c
- {itemAt(QPointF(x, y))}.
-
- This function is deprecated and returns incorrect results if the scene
- contains items that ignore transformations. Use the overload that takes
- a QTransform instead.
-*/
-
-/*!
- Returns a list of all currently selected items. The items are
- returned in no particular order.
-
- \sa setSelectionArea()
-*/
-QList<QGraphicsItem *> QGraphicsScene::selectedItems() const
-{
- Q_D(const QGraphicsScene);
-
- // Optimization: Lazily removes items that are not selected.
- QGraphicsScene *that = const_cast<QGraphicsScene *>(this);
- QSet<QGraphicsItem *> actuallySelectedSet;
- foreach (QGraphicsItem *item, that->d_func()->selectedItems) {
- if (item->isSelected())
- actuallySelectedSet << item;
- }
-
- that->d_func()->selectedItems = actuallySelectedSet;
-
- return d->selectedItems.values();
-}
-
-/*!
- Returns the selection area that was previously set with
- setSelectionArea(), or an empty QPainterPath if no selection area has been
- set.
-
- \sa setSelectionArea()
-*/
-QPainterPath QGraphicsScene::selectionArea() const
-{
- Q_D(const QGraphicsScene);
- return d->selectionArea;
-}
-
-/*!
- \since 4.6
-
- Sets the selection area to \a path. All items within this area are
- immediately selected, and all items outside are unselected. You can get
- the list of all selected items by calling selectedItems().
-
- \a deviceTransform is the transformation that applies to the view, and needs to
- be provided if the scene contains items that ignore transformations.
-
- For an item to be selected, it must be marked as \e selectable
- (QGraphicsItem::ItemIsSelectable).
-
- \sa clearSelection(), selectionArea()
-*/
-void QGraphicsScene::setSelectionArea(const QPainterPath &path, const QTransform &deviceTransform)
-{
- setSelectionArea(path, Qt::IntersectsItemShape, deviceTransform);
-}
-
-/*!
- \obsolete
- \overload
-
- Sets the selection area to \a path.
-
- This function is deprecated and leads to incorrect results if the scene
- contains items that ignore transformations. Use the overload that takes
- a QTransform instead.
-*/
-void QGraphicsScene::setSelectionArea(const QPainterPath &path)
-{
- setSelectionArea(path, Qt::IntersectsItemShape, QTransform());
-}
-
-/*!
- \obsolete
- \overload
- \since 4.3
-
- Sets the selection area to \a path using \a mode to determine if items are
- included in the selection area.
-
- \sa clearSelection(), selectionArea()
-*/
-void QGraphicsScene::setSelectionArea(const QPainterPath &path, Qt::ItemSelectionMode mode)
-{
- setSelectionArea(path, mode, QTransform());
-}
-
-/*!
- \overload
- \since 4.6
-
- Sets the selection area to \a path using \a mode to determine if items are
- included in the selection area.
-
- \a deviceTransform is the transformation that applies to the view, and needs to
- be provided if the scene contains items that ignore transformations.
-
- \sa clearSelection(), selectionArea()
-*/
-void QGraphicsScene::setSelectionArea(const QPainterPath &path, Qt::ItemSelectionMode mode,
- const QTransform &deviceTransform)
-{
- Q_D(QGraphicsScene);
-
- // Note: with boolean path operations, we can improve performance here
- // quite a lot by "growing" the old path instead of replacing it. That
- // allows us to only check the intersect area for changes, instead of
- // reevaluating the whole path over again.
- d->selectionArea = path;
-
- QSet<QGraphicsItem *> unselectItems = d->selectedItems;
-
- // Disable emitting selectionChanged() for individual items.
- ++d->selectionChanging;
- bool changed = false;
-
- // Set all items in path to selected.
- foreach (QGraphicsItem *item, items(path, mode, Qt::DescendingOrder, deviceTransform)) {
- if (item->flags() & QGraphicsItem::ItemIsSelectable) {
- if (!item->isSelected())
- changed = true;
- unselectItems.remove(item);
- item->setSelected(true);
- }
- }
-
- // Unselect all items outside path.
- foreach (QGraphicsItem *item, unselectItems) {
- item->setSelected(false);
- changed = true;
- }
-
- // Reenable emitting selectionChanged() for individual items.
- --d->selectionChanging;
-
- if (!d->selectionChanging && changed)
- emit selectionChanged();
-}
-
-/*!
- Clears the current selection.
-
- \sa setSelectionArea(), selectedItems()
-*/
-void QGraphicsScene::clearSelection()
-{
- Q_D(QGraphicsScene);
-
- // Disable emitting selectionChanged
- ++d->selectionChanging;
- bool changed = !d->selectedItems.isEmpty();
-
- foreach (QGraphicsItem *item, d->selectedItems)
- item->setSelected(false);
- d->selectedItems.clear();
-
- // Reenable emitting selectionChanged() for individual items.
- --d->selectionChanging;
-
- if (!d->selectionChanging && changed)
- emit selectionChanged();
-}
-
-/*!
- \since 4.4
-
- Removes and deletes all items from the scene, but otherwise leaves the
- state of the scene unchanged.
-
- \sa addItem()
-*/
-void QGraphicsScene::clear()
-{
- Q_D(QGraphicsScene);
- // NB! We have to clear the index before deleting items; otherwise the
- // index might try to access dangling item pointers.
- d->index->clear();
- // NB! QGraphicsScenePrivate::unregisterTopLevelItem() removes items
- while (!d->topLevelItems.isEmpty())
- delete d->topLevelItems.first();
- Q_ASSERT(d->topLevelItems.isEmpty());
- d->lastItemCount = 0;
- d->allItemsIgnoreHoverEvents = true;
- d->allItemsUseDefaultCursor = true;
- d->allItemsIgnoreTouchEvents = true;
-}
-
-/*!
- Groups all items in \a items into a new QGraphicsItemGroup, and returns a
- pointer to the group. The group is created with the common ancestor of \a
- items as its parent, and with position (0, 0). The items are all
- reparented to the group, and their positions and transformations are
- mapped to the group. If \a items is empty, this function will return an
- empty top-level QGraphicsItemGroup.
-
- QGraphicsScene has ownership of the group item; you do not need to delete
- it. To dismantle (ungroup) a group, call destroyItemGroup().
-
- \sa destroyItemGroup(), QGraphicsItemGroup::addToGroup()
-*/
-QGraphicsItemGroup *QGraphicsScene::createItemGroup(const QList<QGraphicsItem *> &items)
-{
- // Build a list of the first item's ancestors
- QList<QGraphicsItem *> ancestors;
- int n = 0;
- if (!items.isEmpty()) {
- QGraphicsItem *parent = items.at(n++);
- while ((parent = parent->parentItem()))
- ancestors.append(parent);
- }
-
- // Find the common ancestor for all items
- QGraphicsItem *commonAncestor = 0;
- if (!ancestors.isEmpty()) {
- while (n < items.size()) {
- int commonIndex = -1;
- QGraphicsItem *parent = items.at(n++);
- do {
- int index = ancestors.indexOf(parent, qMax(0, commonIndex));
- if (index != -1) {
- commonIndex = index;
- break;
- }
- } while ((parent = parent->parentItem()));
-
- if (commonIndex == -1) {
- commonAncestor = 0;
- break;
- }
-
- commonAncestor = ancestors.at(commonIndex);
- }
- }
-
- // Create a new group at that level
- QGraphicsItemGroup *group = new QGraphicsItemGroup(commonAncestor);
- if (!commonAncestor)
- addItem(group);
- foreach (QGraphicsItem *item, items)
- group->addToGroup(item);
- return group;
-}
-
-/*!
- Reparents all items in \a group to \a group's parent item, then removes \a
- group from the scene, and finally deletes it. The items' positions and
- transformations are mapped from the group to the group's parent.
-
- \sa createItemGroup(), QGraphicsItemGroup::removeFromGroup()
-*/
-void QGraphicsScene::destroyItemGroup(QGraphicsItemGroup *group)
-{
- foreach (QGraphicsItem *item, group->children())
- group->removeFromGroup(item);
- removeItem(group);
- delete group;
-}
-
-/*!
- Adds or moves the \a item and all its childen to this scene.
- This scene takes ownership of the \a item.
-
- If the item is visible (i.e., QGraphicsItem::isVisible() returns
- true), QGraphicsScene will emit changed() once control goes back
- to the event loop.
-
- If the item is already in a different scene, it will first be
- removed from its old scene, and then added to this scene as a
- top-level.
-
- QGraphicsScene will send ItemSceneChange notifications to \a item
- while it is added to the scene. If item does not currently belong
- to a scene, only one notification is sent. If it does belong to
- scene already (i.e., it is moved to this scene), QGraphicsScene
- will send an addition notification as the item is removed from its
- previous scene.
-
- If the item is a panel, the scene is active, and there is no
- active panel in the scene, then the item will be activated.
-
- \sa removeItem(), addEllipse(), addLine(), addPath(), addPixmap(),
- addRect(), addText(), addWidget(), {QGraphicsItem#Sorting}{Sorting}
-*/
-void QGraphicsScene::addItem(QGraphicsItem *item)
-{
- Q_D(QGraphicsScene);
- if (!item) {
- qWarning("QGraphicsScene::addItem: cannot add null item");
- return;
- }
- if (item->d_ptr->scene == this) {
- qWarning("QGraphicsScene::addItem: item has already been added to this scene");
- return;
- }
- // Remove this item from its existing scene
- if (QGraphicsScene *oldScene = item->d_ptr->scene)
- oldScene->removeItem(item);
-
- // Notify the item that its scene is changing, and allow the item to
- // react.
- const QVariant newSceneVariant(item->itemChange(QGraphicsItem::ItemSceneChange,
- QVariant::fromValue<QGraphicsScene *>(this)));
- QGraphicsScene *targetScene = qvariant_cast<QGraphicsScene *>(newSceneVariant);
- if (targetScene != this) {
- if (targetScene && item->d_ptr->scene != targetScene)
- targetScene->addItem(item);
- return;
- }
-
- // QDeclarativeItems do not rely on initial itemChanged message, as the componentComplete
- // function allows far more opportunity for delayed-construction optimization.
- if (!item->d_ptr->isDeclarativeItem) {
- if (d->unpolishedItems.isEmpty()) {
- QMetaMethod method = metaObject()->method(d->polishItemsIndex);
- method.invoke(this, Qt::QueuedConnection);
- }
- d->unpolishedItems.append(item);
- item->d_ptr->pendingPolish = true;
- }
-
- // Detach this item from its parent if the parent's scene is different
- // from this scene.
- if (QGraphicsItem *itemParent = item->d_ptr->parent) {
- if (itemParent->d_ptr->scene != this)
- item->setParentItem(0);
- }
-
- // Add the item to this scene
- item->d_func()->scene = targetScene;
-
- // Add the item in the index
- d->index->addItem(item);
-
- // Add to list of toplevels if this item is a toplevel.
- if (!item->d_ptr->parent)
- d->registerTopLevelItem(item);
-
- // Add to list of items that require an update. We cannot assume that the
- // item is fully constructed, so calling item->update() can lead to a pure
- // virtual function call to boundingRect().
- d->markDirty(item);
- d->dirtyGrowingItemsBoundingRect = true;
-
- // Disable selectionChanged() for individual items
- ++d->selectionChanging;
- int oldSelectedItemSize = d->selectedItems.size();
-
- // Enable mouse tracking if the item accepts hover events or has a cursor set.
- if (d->allItemsIgnoreHoverEvents && d->itemAcceptsHoverEvents_helper(item)) {
- d->allItemsIgnoreHoverEvents = false;
- d->enableMouseTrackingOnViews();
- }
-#ifndef QT_NO_CURSOR
- if (d->allItemsUseDefaultCursor && item->d_ptr->hasCursor) {
- d->allItemsUseDefaultCursor = false;
- if (d->allItemsIgnoreHoverEvents) // already enabled otherwise
- d->enableMouseTrackingOnViews();
- }
-#endif //QT_NO_CURSOR
-
- // Enable touch events if the item accepts touch events.
- if (d->allItemsIgnoreTouchEvents && item->d_ptr->acceptTouchEvents) {
- d->allItemsIgnoreTouchEvents = false;
- d->enableTouchEventsOnViews();
- }
-
-#ifndef QT_NO_GESTURES
- foreach (Qt::GestureType gesture, item->d_ptr->gestureContext.keys())
- d->grabGesture(item, gesture);
-#endif
-
- // Update selection lists
- if (item->isSelected())
- d->selectedItems << item;
- if (item->isWidget() && item->isVisible() && static_cast<QGraphicsWidget *>(item)->windowType() == Qt::Popup)
- d->addPopup(static_cast<QGraphicsWidget *>(item));
- if (item->isPanel() && item->isVisible() && item->panelModality() != QGraphicsItem::NonModal)
- d->enterModal(item);
-
- // Update creation order focus chain. Make sure to leave the widget's
- // internal tab order intact.
- if (item->isWidget()) {
- QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(item);
- if (!d->tabFocusFirst) {
- // No first tab focus widget - make this the first tab focus
- // widget.
- d->tabFocusFirst = widget;
- } else if (!widget->parentWidget()) {
- // Adding a widget that is not part of a tab focus chain.
- QGraphicsWidget *last = d->tabFocusFirst->d_func()->focusPrev;
- QGraphicsWidget *lastNew = widget->d_func()->focusPrev;
- last->d_func()->focusNext = widget;
- widget->d_func()->focusPrev = last;
- d->tabFocusFirst->d_func()->focusPrev = lastNew;
- lastNew->d_func()->focusNext = d->tabFocusFirst;
- }
- }
-
- // Add all children recursively
- item->d_ptr->ensureSortedChildren();
- for (int i = 0; i < item->d_ptr->children.size(); ++i)
- addItem(item->d_ptr->children.at(i));
-
- // Resolve font and palette.
- item->d_ptr->resolveFont(d->font.resolve());
- item->d_ptr->resolvePalette(d->palette.resolve());
-
-
- // Reenable selectionChanged() for individual items
- --d->selectionChanging;
- if (!d->selectionChanging && d->selectedItems.size() != oldSelectedItemSize)
- emit selectionChanged();
-
- // Deliver post-change notification
- item->itemChange(QGraphicsItem::ItemSceneHasChanged, newSceneVariant);
-
- // Update explicit activation
- bool autoActivate = true;
- if (!d->childExplicitActivation && item->d_ptr->explicitActivate)
- d->childExplicitActivation = item->d_ptr->wantsActive ? 1 : 2;
- if (d->childExplicitActivation && item->isPanel()) {
- if (d->childExplicitActivation == 1)
- setActivePanel(item);
- else
- autoActivate = false;
- d->childExplicitActivation = 0;
- } else if (!item->d_ptr->parent) {
- d->childExplicitActivation = 0;
- }
-
- // Auto-activate this item's panel if nothing else has been activated
- if (autoActivate) {
- if (!d->lastActivePanel && !d->activePanel && item->isPanel()) {
- if (isActive())
- setActivePanel(item);
- else
- d->lastActivePanel = item;
- }
- }
-
- if (item->d_ptr->flags & QGraphicsItem::ItemSendsScenePositionChanges)
- d->registerScenePosItem(item);
-
- // Ensure that newly added items that have subfocus set, gain
- // focus automatically if there isn't a focus item already.
- if (!d->focusItem && item != d->lastFocusItem && item->focusItem() == item)
- item->focusItem()->setFocus();
-
- d->updateInputMethodSensitivityInViews();
-}
-
-/*!
- Creates and adds an ellipse item to the scene, and returns the item
- pointer. The geometry of the ellipse is defined by \a rect, and its pen
- and brush are initialized to \a pen and \a brush.
-
- Note that the item's geometry is provided in item coordinates, and its
- position is initialized to (0, 0).
-
- If the item is visible (i.e., QGraphicsItem::isVisible() returns true),
- QGraphicsScene will emit changed() once control goes back to the event
- loop.
-
- \sa addLine(), addPath(), addPixmap(), addRect(), addText(), addItem(),
- addWidget()
-*/
-QGraphicsEllipseItem *QGraphicsScene::addEllipse(const QRectF &rect, const QPen &pen, const QBrush &brush)
-{
- QGraphicsEllipseItem *item = new QGraphicsEllipseItem(rect);
- item->setPen(pen);
- item->setBrush(brush);
- addItem(item);
- return item;
-}
-
-/*!
- \fn QGraphicsEllipseItem *QGraphicsScene::addEllipse(qreal x, qreal y, qreal w, qreal h, const QPen &pen, const QBrush &brush)
- \since 4.3
-
- This convenience function is equivalent to calling addEllipse(QRectF(\a x,
- \a y, \a w, \a h), \a pen, \a brush).
-*/
-
-/*!
- Creates and adds a line item to the scene, and returns the item
- pointer. The geometry of the line is defined by \a line, and its pen
- is initialized to \a pen.
-
- Note that the item's geometry is provided in item coordinates, and its
- position is initialized to (0, 0).
-
- If the item is visible (i.e., QGraphicsItem::isVisible() returns true),
- QGraphicsScene will emit changed() once control goes back to the event
- loop.
-
- \sa addEllipse(), addPath(), addPixmap(), addRect(), addText(), addItem(),
- addWidget()
-*/
-QGraphicsLineItem *QGraphicsScene::addLine(const QLineF &line, const QPen &pen)
-{
- QGraphicsLineItem *item = new QGraphicsLineItem(line);
- item->setPen(pen);
- addItem(item);
- return item;
-}
-
-/*!
- \fn QGraphicsLineItem *QGraphicsScene::addLine(qreal x1, qreal y1, qreal x2, qreal y2, const QPen &pen)
- \since 4.3
-
- This convenience function is equivalent to calling addLine(QLineF(\a x1,
- \a y1, \a x2, \a y2), \a pen).
-*/
-
-/*!
- Creates and adds a path item to the scene, and returns the item
- pointer. The geometry of the path is defined by \a path, and its pen and
- brush are initialized to \a pen and \a brush.
-
- Note that the item's geometry is provided in item coordinates, and its
- position is initialized to (0, 0).
-
- If the item is visible (i.e., QGraphicsItem::isVisible() returns true),
- QGraphicsScene will emit changed() once control goes back to the event
- loop.
-
- \sa addEllipse(), addLine(), addPixmap(), addRect(), addText(), addItem(),
- addWidget()
-*/
-QGraphicsPathItem *QGraphicsScene::addPath(const QPainterPath &path, const QPen &pen, const QBrush &brush)
-{
- QGraphicsPathItem *item = new QGraphicsPathItem(path);
- item->setPen(pen);
- item->setBrush(brush);
- addItem(item);
- return item;
-}
-
-/*!
- Creates and adds a pixmap item to the scene, and returns the item
- pointer. The pixmap is defined by \a pixmap.
-
- Note that the item's geometry is provided in item coordinates, and its
- position is initialized to (0, 0).
-
- If the item is visible (i.e., QGraphicsItem::isVisible() returns true),
- QGraphicsScene will emit changed() once control goes back to the event
- loop.
-
- \sa addEllipse(), addLine(), addPath(), addRect(), addText(), addItem(),
- addWidget()
-*/
-QGraphicsPixmapItem *QGraphicsScene::addPixmap(const QPixmap &pixmap)
-{
- QGraphicsPixmapItem *item = new QGraphicsPixmapItem(pixmap);
- addItem(item);
- return item;
-}
-
-/*!
- Creates and adds a polygon item to the scene, and returns the item
- pointer. The polygon is defined by \a polygon, and its pen and
- brush are initialized to \a pen and \a brush.
-
- Note that the item's geometry is provided in item coordinates, and its
- position is initialized to (0, 0).
-
- If the item is visible (i.e., QGraphicsItem::isVisible() returns true),
- QGraphicsScene will emit changed() once control goes back to the event
- loop.
-
- \sa addEllipse(), addLine(), addPath(), addRect(), addText(), addItem(),
- addWidget()
-*/
-QGraphicsPolygonItem *QGraphicsScene::addPolygon(const QPolygonF &polygon,
- const QPen &pen, const QBrush &brush)
-{
- QGraphicsPolygonItem *item = new QGraphicsPolygonItem(polygon);
- item->setPen(pen);
- item->setBrush(brush);
- addItem(item);
- return item;
-}
-
-/*!
- Creates and adds a rectangle item to the scene, and returns the item
- pointer. The geometry of the rectangle is defined by \a rect, and its pen
- and brush are initialized to \a pen and \a brush.
-
- Note that the item's geometry is provided in item coordinates, and its
- position is initialized to (0, 0). For example, if a QRect(50, 50, 100,
- 100) is added, its top-left corner will be at (50, 50) relative to the
- origin in the items coordinate system.
-
- If the item is visible (i.e., QGraphicsItem::isVisible() returns true),
- QGraphicsScene will emit changed() once control goes back to the event
- loop.
-
- \sa addEllipse(), addLine(), addPixmap(), addPixmap(), addText(),
- addItem(), addWidget()
-*/
-QGraphicsRectItem *QGraphicsScene::addRect(const QRectF &rect, const QPen &pen, const QBrush &brush)
-{
- QGraphicsRectItem *item = new QGraphicsRectItem(rect);
- item->setPen(pen);
- item->setBrush(brush);
- addItem(item);
- return item;
-}
-
-/*!
- \fn QGraphicsRectItem *QGraphicsScene::addRect(qreal x, qreal y, qreal w, qreal h, const QPen &pen, const QBrush &brush)
- \since 4.3
-
- This convenience function is equivalent to calling addRect(QRectF(\a x,
- \a y, \a w, \a h), \a pen, \a brush).
-*/
-
-/*!
- Creates and adds a text item to the scene, and returns the item
- pointer. The text string is initialized to \a text, and its font
- is initialized to \a font.
-
- The item's position is initialized to (0, 0).
-
- If the item is visible (i.e., QGraphicsItem::isVisible() returns true),
- QGraphicsScene will emit changed() once control goes back to the event
- loop.
-
- \sa addEllipse(), addLine(), addPixmap(), addPixmap(), addRect(),
- addItem(), addWidget()
-*/
-QGraphicsTextItem *QGraphicsScene::addText(const QString &text, const QFont &font)
-{
- QGraphicsTextItem *item = new QGraphicsTextItem(text);
- item->setFont(font);
- addItem(item);
- return item;
-}
-
-/*!
- Creates and adds a QGraphicsSimpleTextItem to the scene, and returns the
- item pointer. The text string is initialized to \a text, and its font is
- initialized to \a font.
-
- The item's position is initialized to (0, 0).
-
- If the item is visible (i.e., QGraphicsItem::isVisible() returns true),
- QGraphicsScene will emit changed() once control goes back to the event
- loop.
-
- \sa addEllipse(), addLine(), addPixmap(), addPixmap(), addRect(),
- addItem(), addWidget()
-*/
-QGraphicsSimpleTextItem *QGraphicsScene::addSimpleText(const QString &text, const QFont &font)
-{
- QGraphicsSimpleTextItem *item = new QGraphicsSimpleTextItem(text);
- item->setFont(font);
- addItem(item);
- return item;
-}
-
-/*!
- Creates a new QGraphicsProxyWidget for \a widget, adds it to the scene,
- and returns a pointer to the proxy. \a wFlags set the default window flags
- for the embedding proxy widget.
-
- The item's position is initialized to (0, 0).
-
- If the item is visible (i.e., QGraphicsItem::isVisible() returns true),
- QGraphicsScene will emit changed() once control goes back to the event
- loop.
-
- Note that widgets with the Qt::WA_PaintOnScreen widget attribute
- set and widgets that wrap an external application or controller
- are not supported. Examples are QGLWidget and QAxWidget.
-
- \sa addEllipse(), addLine(), addPixmap(), addPixmap(), addRect(),
- addText(), addSimpleText(), addItem()
-*/
-QGraphicsProxyWidget *QGraphicsScene::addWidget(QWidget *widget, Qt::WindowFlags wFlags)
-{
- QGraphicsProxyWidget *proxy = new QGraphicsProxyWidget(0, wFlags);
- proxy->setWidget(widget);
- addItem(proxy);
- return proxy;
-}
-
-/*!
- Removes the item \a item and all its children from the scene. The
- ownership of \a item is passed on to the caller (i.e.,
- QGraphicsScene will no longer delete \a item when destroyed).
-
- \sa addItem()
-*/
-void QGraphicsScene::removeItem(QGraphicsItem *item)
-{
- // ### Refactoring: This function shares much functionality with _q_removeItemLater()
- Q_D(QGraphicsScene);
- if (!item) {
- qWarning("QGraphicsScene::removeItem: cannot remove 0-item");
- return;
- }
- if (item->scene() != this) {
- qWarning("QGraphicsScene::removeItem: item %p's scene (%p)"
- " is different from this scene (%p)",
- item, item->scene(), this);
- return;
- }
-
- // Notify the item that it's scene is changing to 0, allowing the item to
- // react.
- const QVariant newSceneVariant(item->itemChange(QGraphicsItem::ItemSceneChange,
- QVariant::fromValue<QGraphicsScene *>(0)));
- QGraphicsScene *targetScene = qvariant_cast<QGraphicsScene *>(newSceneVariant);
- if (targetScene != 0 && targetScene != this) {
- targetScene->addItem(item);
- return;
- }
-
- d->removeItemHelper(item);
-
- // Deliver post-change notification
- item->itemChange(QGraphicsItem::ItemSceneHasChanged, newSceneVariant);
-
- d->updateInputMethodSensitivityInViews();
-}
-
-/*!
- When the scene is active, this functions returns the scene's current focus
- item, or 0 if no item currently has focus. When the scene is inactive, this
- functions returns the item that will gain input focus when the scene becomes
- active.
-
- The focus item receives keyboard input when the scene receives a
- key event.
-
- \sa setFocusItem(), QGraphicsItem::hasFocus(), isActive()
-*/
-QGraphicsItem *QGraphicsScene::focusItem() const
-{
- Q_D(const QGraphicsScene);
- return isActive() ? d->focusItem : d->passiveFocusItem;
-}
-
-/*!
- Sets the scene's focus item to \a item, with the focus reason \a
- focusReason, after removing focus from any previous item that may have had
- focus.
-
- If \a item is 0, or if it either does not accept focus (i.e., it does not
- have the QGraphicsItem::ItemIsFocusable flag enabled), or is not visible
- or not enabled, this function only removes focus from any previous
- focusitem.
-
- If item is not 0, and the scene does not currently have focus (i.e.,
- hasFocus() returns false), this function will call setFocus()
- automatically.
-
- \sa focusItem(), hasFocus(), setFocus()
-*/
-void QGraphicsScene::setFocusItem(QGraphicsItem *item, Qt::FocusReason focusReason)
-{
- Q_D(QGraphicsScene);
- if (item)
- item->setFocus(focusReason);
- else
- d->setFocusItemHelper(item, focusReason);
-}
-
-/*!
- Returns true if the scene has focus; otherwise returns false. If the scene
- has focus, it will will forward key events from QKeyEvent to any item that
- has focus.
-
- \sa setFocus(), setFocusItem()
-*/
-bool QGraphicsScene::hasFocus() const
-{
- Q_D(const QGraphicsScene);
- return d->hasFocus;
-}
-
-/*!
- Sets focus on the scene by sending a QFocusEvent to the scene, passing \a
- focusReason as the reason. If the scene regains focus after having
- previously lost it while an item had focus, the last focus item will
- receive focus with \a focusReason as the reason.
-
- If the scene already has focus, this function does nothing.
-
- \sa hasFocus(), clearFocus(), setFocusItem()
-*/
-void QGraphicsScene::setFocus(Qt::FocusReason focusReason)
-{
- Q_D(QGraphicsScene);
- if (d->hasFocus || !isActive())
- return;
- QFocusEvent event(QEvent::FocusIn, focusReason);
- QCoreApplication::sendEvent(this, &event);
-}
-
-/*!
- Clears focus from the scene. If any item has focus when this function is
- called, it will lose focus, and regain focus again once the scene regains
- focus.
-
- A scene that does not have focus ignores key events.
-
- \sa hasFocus(), setFocus(), setFocusItem()
-*/
-void QGraphicsScene::clearFocus()
-{
- Q_D(QGraphicsScene);
- if (d->hasFocus) {
- d->hasFocus = false;
- d->passiveFocusItem = d->focusItem;
- setFocusItem(0, Qt::OtherFocusReason);
- }
-}
-
-/*!
- \property QGraphicsScene::stickyFocus
- \brief whether clicking into the scene background will clear focus
-
- \since 4.6
-
- In a QGraphicsScene with stickyFocus set to true, focus will remain
- unchanged when the user clicks into the scene background or on an item
- that does not accept focus. Otherwise, focus will be cleared.
-
- By default, this property is false.
-
- Focus changes in response to a mouse press. You can reimplement
- mousePressEvent() in a subclass of QGraphicsScene to toggle this property
- based on where the user has clicked.
-
- \sa clearFocus(), setFocusItem()
-*/
-void QGraphicsScene::setStickyFocus(bool enabled)
-{
- Q_D(QGraphicsScene);
- d->stickyFocus = enabled;
-}
-bool QGraphicsScene::stickyFocus() const
-{
- Q_D(const QGraphicsScene);
- return d->stickyFocus;
-}
-
-/*!
- Returns the current mouse grabber item, or 0 if no item is currently
- grabbing the mouse. The mouse grabber item is the item that receives all
- mouse events sent to the scene.
-
- An item becomes a mouse grabber when it receives and accepts a
- mouse press event, and it stays the mouse grabber until either of
- the following events occur:
-
- \list
- \o If the item receives a mouse release event when there are no other
- buttons pressed, it loses the mouse grab.
- \o If the item becomes invisible (i.e., someone calls \c {item->setVisible(false)}),
- or if it becomes disabled (i.e., someone calls \c {item->setEnabled(false)}),
- it loses the mouse grab.
- \o If the item is removed from the scene, it loses the mouse grab.
- \endlist
-
- If the item loses its mouse grab, the scene will ignore all mouse events
- until a new item grabs the mouse (i.e., until a new item receives a mouse
- press event).
-*/
-QGraphicsItem *QGraphicsScene::mouseGrabberItem() const
-{
- Q_D(const QGraphicsScene);
- return !d->mouseGrabberItems.isEmpty() ? d->mouseGrabberItems.last() : 0;
-}
-
-/*!
- \property QGraphicsScene::backgroundBrush
- \brief the background brush of the scene.
-
- Set this property to changes the scene's background to a different color,
- gradient or texture. The default background brush is Qt::NoBrush. The
- background is drawn before (behind) the items.
-
- Example:
-
- \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsscene.cpp 3
-
- QGraphicsScene::render() calls drawBackground() to draw the scene
- background. For more detailed control over how the background is drawn,
- you can reimplement drawBackground() in a subclass of QGraphicsScene.
-*/
-QBrush QGraphicsScene::backgroundBrush() const
-{
- Q_D(const QGraphicsScene);
- return d->backgroundBrush;
-}
-void QGraphicsScene::setBackgroundBrush(const QBrush &brush)
-{
- Q_D(QGraphicsScene);
- d->backgroundBrush = brush;
- foreach (QGraphicsView *view, d->views) {
- view->resetCachedContent();
- view->viewport()->update();
- }
- update();
-}
-
-/*!
- \property QGraphicsScene::foregroundBrush
- \brief the foreground brush of the scene.
-
- Change this property to set the scene's foreground to a different
- color, gradient or texture.
-
- The foreground is drawn after (on top of) the items. The default
- foreground brush is Qt::NoBrush ( i.e. the foreground is not
- drawn).
-
- Example:
-
- \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsscene.cpp 4
-
- QGraphicsScene::render() calls drawForeground() to draw the scene
- foreground. For more detailed control over how the foreground is
- drawn, you can reimplement the drawForeground() function in a
- QGraphicsScene subclass.
-*/
-QBrush QGraphicsScene::foregroundBrush() const
-{
- Q_D(const QGraphicsScene);
- return d->foregroundBrush;
-}
-void QGraphicsScene::setForegroundBrush(const QBrush &brush)
-{
- Q_D(QGraphicsScene);
- d->foregroundBrush = brush;
- foreach (QGraphicsView *view, views())
- view->viewport()->update();
- update();
-}
-
-/*!
- This method is used by input methods to query a set of properties of
- the scene to be able to support complex input method operations as support
- for surrounding text and reconversions.
-
- The \a query parameter specifies which property is queried.
-
- \sa QWidget::inputMethodQuery()
-*/
-QVariant QGraphicsScene::inputMethodQuery(Qt::InputMethodQuery query) const
-{
- Q_D(const QGraphicsScene);
- if (!d->focusItem || !(d->focusItem->flags() & QGraphicsItem::ItemAcceptsInputMethod))
- return QVariant();
- const QTransform matrix = d->focusItem->sceneTransform();
- QVariant value = d->focusItem->inputMethodQuery(query);
- if (value.type() == QVariant::RectF)
- value = matrix.mapRect(value.toRectF());
- else if (value.type() == QVariant::PointF)
- value = matrix.map(value.toPointF());
- else if (value.type() == QVariant::Rect)
- value = matrix.mapRect(value.toRect());
- else if (value.type() == QVariant::Point)
- value = matrix.map(value.toPoint());
- return value;
-}
-
-/*!
- \fn void QGraphicsScene::update(const QRectF &rect)
- Schedules a redraw of the area \a rect on the scene.
-
- \sa sceneRect(), changed()
-*/
-void QGraphicsScene::update(const QRectF &rect)
-{
- Q_D(QGraphicsScene);
- if (d->updateAll || (rect.isEmpty() && !rect.isNull()))
- return;
-
- // Check if anyone's connected; if not, we can send updates directly to
- // the views. Otherwise or if there are no views, use old behavior.
- bool directUpdates = !(d->isSignalConnected(d->changedSignalIndex)) && !d->views.isEmpty();
- if (rect.isNull()) {
- d->updateAll = true;
- d->updatedRects.clear();
- if (directUpdates) {
- // Update all views.
- for (int i = 0; i < d->views.size(); ++i)
- d->views.at(i)->d_func()->fullUpdatePending = true;
- }
- } else {
- if (directUpdates) {
- // Update all views.
- for (int i = 0; i < d->views.size(); ++i) {
- QGraphicsView *view = d->views.at(i);
- if (view->isTransformed())
- view->d_func()->updateRectF(view->viewportTransform().mapRect(rect));
- else
- view->d_func()->updateRectF(rect);
- }
- } else {
- d->updatedRects << rect;
- }
- }
-
- if (!d->calledEmitUpdated) {
- d->calledEmitUpdated = true;
- QMetaObject::invokeMethod(this, "_q_emitUpdated", Qt::QueuedConnection);
- }
-}
-
-/*!
- \fn void QGraphicsScene::update(qreal x, qreal y, qreal w, qreal h)
- \overload
- \since 4.3
-
- This function is equivalent to calling update(QRectF(\a x, \a y, \a w,
- \a h));
-*/
-
-/*!
- Invalidates and schedules a redraw of the \a layers in \a rect on the
- scene. Any cached content in \a layers is unconditionally invalidated and
- redrawn.
-
- You can use this function overload to notify QGraphicsScene of changes to
- the background or the foreground of the scene. This function is commonly
- used for scenes with tile-based backgrounds to notify changes when
- QGraphicsView has enabled
- \l{QGraphicsView::CacheBackground}{CacheBackground}.
-
- Example:
-
- \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsscene.cpp 5
-
- Note that QGraphicsView currently supports background caching only (see
- QGraphicsView::CacheBackground). This function is equivalent to calling
- update() if any layer but BackgroundLayer is passed.
-
- \sa QGraphicsView::resetCachedContent()
-*/
-void QGraphicsScene::invalidate(const QRectF &rect, SceneLayers layers)
-{
- foreach (QGraphicsView *view, views())
- view->invalidateScene(rect, layers);
- update(rect);
-}
-
-/*!
- \fn void QGraphicsScene::invalidate(qreal x, qreal y, qreal w, qreal h, SceneLayers layers)
- \overload
- \since 4.3
-
- This convenience function is equivalent to calling invalidate(QRectF(\a x, \a
- y, \a w, \a h), \a layers);
-*/
-
-/*!
- Returns a list of all the views that display this scene.
-
- \sa QGraphicsView::scene()
-*/
-QList <QGraphicsView *> QGraphicsScene::views() const
-{
- Q_D(const QGraphicsScene);
- return d->views;
-}
-
-/*!
- This slot \e advances the scene by one step, by calling
- QGraphicsItem::advance() for all items on the scene. This is done in two
- phases: in the first phase, all items are notified that the scene is about
- to change, and in the second phase all items are notified that they can
- move. In the first phase, QGraphicsItem::advance() is called passing a
- value of 0 as an argument, and 1 is passed in the second phase.
-
- \sa QGraphicsItem::advance(), QGraphicsItemAnimation, QTimeLine
-*/
-void QGraphicsScene::advance()
-{
- for (int i = 0; i < 2; ++i) {
- foreach (QGraphicsItem *item, items())
- item->advance(i);
- }
-}
-
-/*!
- Processes the event \a event, and dispatches it to the respective
- event handlers.
-
- In addition to calling the convenience event handlers, this
- function is responsible for converting mouse move events to hover
- events for when there is no mouse grabber item. Hover events are
- delivered directly to items; there is no convenience function for
- them.
-
- Unlike QWidget, QGraphicsScene does not have the convenience functions
- \l{QWidget::}{enterEvent()} and \l{QWidget::}{leaveEvent()}. Use this
- function to obtain those events instead.
-
- \sa contextMenuEvent(), keyPressEvent(), keyReleaseEvent(),
- mousePressEvent(), mouseMoveEvent(), mouseReleaseEvent(),
- mouseDoubleClickEvent(), focusInEvent(), focusOutEvent()
-*/
-bool QGraphicsScene::event(QEvent *event)
-{
- Q_D(QGraphicsScene);
-
- switch (event->type()) {
- case QEvent::GraphicsSceneMousePress:
- case QEvent::GraphicsSceneMouseMove:
- case QEvent::GraphicsSceneMouseRelease:
- case QEvent::GraphicsSceneMouseDoubleClick:
- case QEvent::GraphicsSceneHoverEnter:
- case QEvent::GraphicsSceneHoverLeave:
- case QEvent::GraphicsSceneHoverMove:
- case QEvent::TouchBegin:
- case QEvent::TouchUpdate:
- case QEvent::TouchEnd:
- // Reset the under-mouse list to ensure that this event gets fresh
- // item-under-mouse data. Be careful about this list; if people delete
- // items from inside event handlers, this list can quickly end up
- // having stale pointers in it. We need to clear it before dispatching
- // events that use it.
- // ### this should only be cleared if we received a new mouse move event,
- // which relies on us fixing the replay mechanism in QGraphicsView.
- d->cachedItemsUnderMouse.clear();
- default:
- break;
- }
-
- switch (event->type()) {
- case QEvent::GraphicsSceneDragEnter:
- dragEnterEvent(static_cast<QGraphicsSceneDragDropEvent *>(event));
- break;
- case QEvent::GraphicsSceneDragMove:
- dragMoveEvent(static_cast<QGraphicsSceneDragDropEvent *>(event));
- break;
- case QEvent::GraphicsSceneDragLeave:
- dragLeaveEvent(static_cast<QGraphicsSceneDragDropEvent *>(event));
- break;
- case QEvent::GraphicsSceneDrop:
- dropEvent(static_cast<QGraphicsSceneDragDropEvent *>(event));
- break;
- case QEvent::GraphicsSceneContextMenu:
- contextMenuEvent(static_cast<QGraphicsSceneContextMenuEvent *>(event));
- break;
- case QEvent::KeyPress:
- if (!d->focusItem) {
- QKeyEvent *k = static_cast<QKeyEvent *>(event);
- if (k->key() == Qt::Key_Tab || k->key() == Qt::Key_Backtab) {
- if (!(k->modifiers() & (Qt::ControlModifier | Qt::AltModifier))) { //### Add MetaModifier?
- bool res = false;
- if (k->key() == Qt::Key_Backtab
- || (k->key() == Qt::Key_Tab && (k->modifiers() & Qt::ShiftModifier))) {
- res = focusNextPrevChild(false);
- } else if (k->key() == Qt::Key_Tab) {
- res = focusNextPrevChild(true);
- }
- if (!res)
- event->ignore();
- return true;
- }
- }
- }
- keyPressEvent(static_cast<QKeyEvent *>(event));
- break;
- case QEvent::KeyRelease:
- keyReleaseEvent(static_cast<QKeyEvent *>(event));
- break;
- case QEvent::ShortcutOverride: {
- QGraphicsItem *parent = focusItem();
- while (parent) {
- d->sendEvent(parent, event);
- if (event->isAccepted())
- return true;
- parent = parent->parentItem();
- }
- }
- return false;
- case QEvent::GraphicsSceneMouseMove:
- {
- QGraphicsSceneMouseEvent *mouseEvent = static_cast<QGraphicsSceneMouseEvent *>(event);
- d->lastSceneMousePos = mouseEvent->scenePos();
- mouseMoveEvent(mouseEvent);
- break;
- }
- case QEvent::GraphicsSceneMousePress:
- mousePressEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
- break;
- case QEvent::GraphicsSceneMouseRelease:
- mouseReleaseEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
- break;
- case QEvent::GraphicsSceneMouseDoubleClick:
- mouseDoubleClickEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
- break;
- case QEvent::GraphicsSceneWheel:
- wheelEvent(static_cast<QGraphicsSceneWheelEvent *>(event));
- break;
- case QEvent::FocusIn:
- focusInEvent(static_cast<QFocusEvent *>(event));
- break;
- case QEvent::FocusOut:
- focusOutEvent(static_cast<QFocusEvent *>(event));
- break;
- case QEvent::GraphicsSceneHoverEnter:
- case QEvent::GraphicsSceneHoverLeave:
- case QEvent::GraphicsSceneHoverMove:
- {
- QGraphicsSceneHoverEvent *hoverEvent = static_cast<QGraphicsSceneHoverEvent *>(event);
- d->lastSceneMousePos = hoverEvent->scenePos();
- d->dispatchHoverEvent(hoverEvent);
- break;
- }
- case QEvent::Leave:
- // hackieshly unpacking the viewport pointer from the leave event.
- d->leaveScene(reinterpret_cast<QWidget *>(event->d));
- break;
- case QEvent::GraphicsSceneHelp:
- helpEvent(static_cast<QGraphicsSceneHelpEvent *>(event));
- break;
- case QEvent::InputMethod:
- inputMethodEvent(static_cast<QInputMethodEvent *>(event));
- break;
- case QEvent::WindowActivate:
- if (!d->activationRefCount++) {
- if (d->lastActivePanel) {
- // Activate the last panel.
- d->setActivePanelHelper(d->lastActivePanel, true);
- } else if (d->tabFocusFirst && d->tabFocusFirst->isPanel()) {
- // Activate the panel of the first item in the tab focus
- // chain.
- d->setActivePanelHelper(d->tabFocusFirst, true);
- } else {
- // Activate all toplevel items.
- QEvent event(QEvent::WindowActivate);
- foreach (QGraphicsItem *item, items()) {
- if (item->isVisible() && !item->isPanel() && !item->parentItem())
- sendEvent(item, &event);
- }
- }
- }
- break;
- case QEvent::WindowDeactivate:
- if (!--d->activationRefCount) {
- if (d->activePanel) {
- // Deactivate the active panel (but keep it so we can
- // reactivate it later).
- QGraphicsItem *lastActivePanel = d->activePanel;
- d->setActivePanelHelper(0, true);
- d->lastActivePanel = lastActivePanel;
- } else {
- // Activate all toplevel items.
- QEvent event(QEvent::WindowDeactivate);
- foreach (QGraphicsItem *item, items()) {
- if (item->isVisible() && !item->isPanel() && !item->parentItem())
- sendEvent(item, &event);
- }
- }
- }
- break;
- case QEvent::ApplicationFontChange: {
- // Resolve the existing scene font.
- d->resolveFont();
- break;
- }
- case QEvent::FontChange:
- // Update the entire scene when the font changes.
- update();
- break;
- case QEvent::ApplicationPaletteChange: {
- // Resolve the existing scene palette.
- d->resolvePalette();
- break;
- }
- case QEvent::PaletteChange:
- // Update the entire scene when the palette changes.
- update();
- break;
- case QEvent::StyleChange:
- // Reresolve all widgets' styles. Update all top-level widgets'
- // geometries that do not have an explicit style set.
- update();
- break;
- case QEvent::TouchBegin:
- case QEvent::TouchUpdate:
- case QEvent::TouchEnd:
- d->touchEventHandler(static_cast<QTouchEvent *>(event));
- break;
-#ifndef QT_NO_GESTURES
- case QEvent::Gesture:
- case QEvent::GestureOverride:
- d->gestureEventHandler(static_cast<QGestureEvent *>(event));
- break;
-#endif // QT_NO_GESTURES
- default:
- return QObject::event(event);
- }
- return true;
-}
-
-/*!
- \reimp
-
- QGraphicsScene filters QApplication's events to detect palette and font
- changes.
-*/
-bool QGraphicsScene::eventFilter(QObject *watched, QEvent *event)
-{
- if (watched != qApp)
- return false;
-
- switch (event->type()) {
- case QEvent::ApplicationPaletteChange:
- QApplication::postEvent(this, new QEvent(QEvent::ApplicationPaletteChange));
- break;
- case QEvent::ApplicationFontChange:
- QApplication::postEvent(this, new QEvent(QEvent::ApplicationFontChange));
- break;
- default:
- break;
- }
- return false;
-}
-
-/*!
- This event handler, for event \a contextMenuEvent, can be reimplemented in
- a subclass to receive context menu events. The default implementation
- forwards the event to the topmost item that accepts context menu events at
- the position of the event. If no items accept context menu events at this
- position, the event is ignored.
-
- \sa QGraphicsItem::contextMenuEvent()
-*/
-void QGraphicsScene::contextMenuEvent(QGraphicsSceneContextMenuEvent *contextMenuEvent)
-{
- Q_D(QGraphicsScene);
- // Ignore by default.
- contextMenuEvent->ignore();
-
- // Send the event to all items at this position until one item accepts the
- // event.
- foreach (QGraphicsItem *item, d->itemsAtPosition(contextMenuEvent->screenPos(),
- contextMenuEvent->scenePos(),
- contextMenuEvent->widget())) {
- contextMenuEvent->setPos(item->d_ptr->genericMapFromScene(contextMenuEvent->scenePos(),
- contextMenuEvent->widget()));
- contextMenuEvent->accept();
- if (!d->sendEvent(item, contextMenuEvent))
- break;
-
- if (contextMenuEvent->isAccepted())
- break;
- }
-}
-
-/*!
- This event handler, for event \a event, can be reimplemented in a subclass
- to receive drag enter events for the scene.
-
- The default implementation accepts the event and prepares the scene to
- accept drag move events.
-
- \sa QGraphicsItem::dragEnterEvent(), dragMoveEvent(), dragLeaveEvent(),
- dropEvent()
-*/
-void QGraphicsScene::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
-{
- Q_D(QGraphicsScene);
- d->dragDropItem = 0;
- d->lastDropAction = Qt::IgnoreAction;
- event->accept();
-}
-
-/*!
- This event handler, for event \a event, can be reimplemented in a subclass
- to receive drag move events for the scene.
-
- \sa QGraphicsItem::dragMoveEvent(), dragEnterEvent(), dragLeaveEvent(),
- dropEvent()
-*/
-void QGraphicsScene::dragMoveEvent(QGraphicsSceneDragDropEvent *event)
-{
- Q_D(QGraphicsScene);
- event->ignore();
-
- if (!d->mouseGrabberItems.isEmpty()) {
- // Mouse grabbers that start drag events lose the mouse grab.
- d->clearMouseGrabber();
- d->mouseGrabberButtonDownPos.clear();
- d->mouseGrabberButtonDownScenePos.clear();
- d->mouseGrabberButtonDownScreenPos.clear();
- }
-
- bool eventDelivered = false;
-
- // Find the topmost enabled items under the cursor. They are all
- // candidates for accepting drag & drop events.
- foreach (QGraphicsItem *item, d->itemsAtPosition(event->screenPos(),
- event->scenePos(),
- event->widget())) {
- if (!item->isEnabled() || !item->acceptDrops())
- continue;
-
- if (item != d->dragDropItem) {
- // Enter the new drag drop item. If it accepts the event, we send
- // the leave to the parent item.
- QGraphicsSceneDragDropEvent dragEnter(QEvent::GraphicsSceneDragEnter);
- d->cloneDragDropEvent(&dragEnter, event);
- dragEnter.setDropAction(event->proposedAction());
- d->sendDragDropEvent(item, &dragEnter);
- event->setAccepted(dragEnter.isAccepted());
- event->setDropAction(dragEnter.dropAction());
- if (!event->isAccepted()) {
- // Propagate to the item under
- continue;
- }
-
- d->lastDropAction = event->dropAction();
-
- if (d->dragDropItem) {
- // Leave the last drag drop item. A perfect implementation
- // would set the position of this event to the point where
- // this event and the last event intersect with the item's
- // shape, but that's not easy to do. :-)
- QGraphicsSceneDragDropEvent dragLeave(QEvent::GraphicsSceneDragLeave);
- d->cloneDragDropEvent(&dragLeave, event);
- d->sendDragDropEvent(d->dragDropItem, &dragLeave);
- }
-
- // We've got a new drag & drop item
- d->dragDropItem = item;
- }
-
- // Send the move event.
- event->setDropAction(d->lastDropAction);
- event->accept();
- d->sendDragDropEvent(item, event);
- if (event->isAccepted())
- d->lastDropAction = event->dropAction();
- eventDelivered = true;
- break;
- }
-
- if (!eventDelivered) {
- if (d->dragDropItem) {
- // Leave the last drag drop item
- QGraphicsSceneDragDropEvent dragLeave(QEvent::GraphicsSceneDragLeave);
- d->cloneDragDropEvent(&dragLeave, event);
- d->sendDragDropEvent(d->dragDropItem, &dragLeave);
- d->dragDropItem = 0;
- }
- // Propagate
- event->setDropAction(Qt::IgnoreAction);
- }
-}
-
-/*!
- This event handler, for event \a event, can be reimplemented in a subclass
- to receive drag leave events for the scene.
-
- \sa QGraphicsItem::dragLeaveEvent(), dragEnterEvent(), dragMoveEvent(),
- dropEvent()
-*/
-void QGraphicsScene::dragLeaveEvent(QGraphicsSceneDragDropEvent *event)
-{
- Q_D(QGraphicsScene);
- if (d->dragDropItem) {
- // Leave the last drag drop item
- d->sendDragDropEvent(d->dragDropItem, event);
- d->dragDropItem = 0;
- }
-}
-
-/*!
- This event handler, for event \a event, can be reimplemented in a subclass
- to receive drop events for the scene.
-
- \sa QGraphicsItem::dropEvent(), dragEnterEvent(), dragMoveEvent(),
- dragLeaveEvent()
-*/
-void QGraphicsScene::dropEvent(QGraphicsSceneDragDropEvent *event)
-{
- Q_UNUSED(event);
- Q_D(QGraphicsScene);
- if (d->dragDropItem) {
- // Drop on the last drag drop item
- d->sendDragDropEvent(d->dragDropItem, event);
- d->dragDropItem = 0;
- }
-}
-
-/*!
- This event handler, for event \a focusEvent, can be reimplemented in a
- subclass to receive focus in events.
-
- The default implementation sets focus on the scene, and then on the last
- focus item.
-
- \sa QGraphicsItem::focusOutEvent()
-*/
-void QGraphicsScene::focusInEvent(QFocusEvent *focusEvent)
-{
- Q_D(QGraphicsScene);
-
- d->hasFocus = true;
- switch (focusEvent->reason()) {
- case Qt::TabFocusReason:
- if (!focusNextPrevChild(true))
- focusEvent->ignore();
- break;
- case Qt::BacktabFocusReason:
- if (!focusNextPrevChild(false))
- focusEvent->ignore();
- break;
- default:
- if (d->passiveFocusItem) {
- // Set focus on the last focus item
- setFocusItem(d->passiveFocusItem, focusEvent->reason());
- }
- break;
- }
-}
-
-/*!
- This event handler, for event \a focusEvent, can be reimplemented in a
- subclass to receive focus out events.
-
- The default implementation removes focus from any focus item, then removes
- focus from the scene.
-
- \sa QGraphicsItem::focusInEvent()
-*/
-void QGraphicsScene::focusOutEvent(QFocusEvent *focusEvent)
-{
- Q_D(QGraphicsScene);
- d->hasFocus = false;
- d->passiveFocusItem = d->focusItem;
- setFocusItem(0, focusEvent->reason());
-
- // Remove all popups when the scene loses focus.
- if (!d->popupWidgets.isEmpty())
- d->removePopup(d->popupWidgets.first());
-}
-
-/*!
- This event handler, for event \a helpEvent, can be
- reimplemented in a subclass to receive help events. The events
- are of type QEvent::ToolTip, which are created when a tooltip is
- requested.
-
- The default implementation shows the tooltip of the topmost
- item, i.e., the item with the highest z-value, at the mouse
- cursor position. If no item has a tooltip set, this function
- does nothing.
-
- \sa QGraphicsItem::toolTip(), QGraphicsSceneHelpEvent
-*/
-void QGraphicsScene::helpEvent(QGraphicsSceneHelpEvent *helpEvent)
-{
-#ifdef QT_NO_TOOLTIP
- Q_UNUSED(helpEvent);
-#else
- // Find the first item that does tooltips
- Q_D(QGraphicsScene);
- QList<QGraphicsItem *> itemsAtPos = d->itemsAtPosition(helpEvent->screenPos(),
- helpEvent->scenePos(),
- helpEvent->widget());
- QGraphicsItem *toolTipItem = 0;
- for (int i = 0; i < itemsAtPos.size(); ++i) {
- QGraphicsItem *tmp = itemsAtPos.at(i);
- if (tmp->d_func()->isProxyWidget()) {
- // if the item is a proxy widget, the event is forwarded to it
- sendEvent(tmp, helpEvent);
- if (helpEvent->isAccepted())
- return;
- }
- if (!tmp->toolTip().isEmpty()) {
- toolTipItem = tmp;
- break;
- }
- }
-
- // Show or hide the tooltip
- QString text;
- QPoint point;
- if (toolTipItem && !toolTipItem->toolTip().isEmpty()) {
- text = toolTipItem->toolTip();
- point = helpEvent->screenPos();
- }
- QToolTip::showText(point, text, helpEvent->widget());
- helpEvent->setAccepted(!text.isEmpty());
-#endif
-}
-
-bool QGraphicsScenePrivate::itemAcceptsHoverEvents_helper(const QGraphicsItem *item) const
-{
- return (item->d_ptr->acceptsHover
- || (item->d_ptr->isWidget
- && static_cast<const QGraphicsWidget *>(item)->d_func()->hasDecoration()))
- && !item->isBlockedByModalPanel();
-}
-
-/*!
- This event handler, for event \a hoverEvent, can be reimplemented in a
- subclass to receive hover enter events. The default implementation
- forwards the event to the topmost item that accepts hover events at the
- scene position from the event.
-
- \sa QGraphicsItem::hoverEvent(), QGraphicsItem::setAcceptHoverEvents()
-*/
-bool QGraphicsScenePrivate::dispatchHoverEvent(QGraphicsSceneHoverEvent *hoverEvent)
-{
- if (allItemsIgnoreHoverEvents)
- return false;
-
- // Find the first item that accepts hover events, reusing earlier
- // calculated data is possible.
- if (cachedItemsUnderMouse.isEmpty()) {
- cachedItemsUnderMouse = itemsAtPosition(hoverEvent->screenPos(),
- hoverEvent->scenePos(),
- hoverEvent->widget());
- }
-
- QGraphicsItem *item = 0;
- for (int i = 0; i < cachedItemsUnderMouse.size(); ++i) {
- QGraphicsItem *tmp = cachedItemsUnderMouse.at(i);
- if (itemAcceptsHoverEvents_helper(tmp)) {
- item = tmp;
- break;
- }
- }
-
- // Find the common ancestor item for the new topmost hoverItem and the
- // last item in the hoverItem list.
- QGraphicsItem *commonAncestorItem = (item && !hoverItems.isEmpty()) ? item->commonAncestorItem(hoverItems.last()) : 0;
- while (commonAncestorItem && !itemAcceptsHoverEvents_helper(commonAncestorItem))
- commonAncestorItem = commonAncestorItem->parentItem();
- if (commonAncestorItem && commonAncestorItem->panel() != item->panel()) {
- // The common ancestor isn't in the same panel as the two hovered
- // items.
- commonAncestorItem = 0;
- }
-
- // Check if the common ancestor item is known.
- int index = commonAncestorItem ? hoverItems.indexOf(commonAncestorItem) : -1;
- // Send hover leaves to any existing hovered children of the common
- // ancestor item.
- for (int i = hoverItems.size() - 1; i > index; --i) {
- QGraphicsItem *lastItem = hoverItems.takeLast();
- if (itemAcceptsHoverEvents_helper(lastItem))
- sendHoverEvent(QEvent::GraphicsSceneHoverLeave, lastItem, hoverEvent);
- }
-
- // Item is a child of a known item. Generate enter events for the
- // missing links.
- QList<QGraphicsItem *> parents;
- QGraphicsItem *parent = item;
- while (parent && parent != commonAncestorItem) {
- parents.prepend(parent);
- if (parent->isPanel()) {
- // Stop at the panel - we don't deliver beyond this point.
- break;
- }
- parent = parent->parentItem();
- }
- for (int i = 0; i < parents.size(); ++i) {
- parent = parents.at(i);
- hoverItems << parent;
- if (itemAcceptsHoverEvents_helper(parent))
- sendHoverEvent(QEvent::GraphicsSceneHoverEnter, parent, hoverEvent);
- }
-
- // Generate a move event for the item itself
- if (item
- && !hoverItems.isEmpty()
- && item == hoverItems.last()) {
- sendHoverEvent(QEvent::GraphicsSceneHoverMove, item, hoverEvent);
- return true;
- }
- return false;
-}
-
-/*!
- \internal
-
- Handles all actions necessary to clean up the scene when the mouse leaves
- the view.
-*/
-void QGraphicsScenePrivate::leaveScene(QWidget *viewport)
-{
-#ifndef QT_NO_TOOLTIP
- QToolTip::hideText();
-#endif
- QGraphicsView *view = qobject_cast<QGraphicsView *>(viewport->parent());
- // Send HoverLeave events to all existing hover items, topmost first.
- QGraphicsSceneHoverEvent hoverEvent;
- hoverEvent.setWidget(viewport);
-
- if (view) {
- QPoint cursorPos = QCursor::pos();
- hoverEvent.setScenePos(view->mapToScene(viewport->mapFromGlobal(cursorPos)));
- hoverEvent.setLastScenePos(hoverEvent.scenePos());
- hoverEvent.setScreenPos(cursorPos);
- hoverEvent.setLastScreenPos(hoverEvent.screenPos());
- }
-
- while (!hoverItems.isEmpty()) {
- QGraphicsItem *lastItem = hoverItems.takeLast();
- if (itemAcceptsHoverEvents_helper(lastItem))
- sendHoverEvent(QEvent::GraphicsSceneHoverLeave, lastItem, &hoverEvent);
- }
-}
-
-/*!
- This event handler, for event \a keyEvent, can be reimplemented in a
- subclass to receive keypress events. The default implementation forwards
- the event to current focus item.
-
- \sa QGraphicsItem::keyPressEvent(), focusItem()
-*/
-void QGraphicsScene::keyPressEvent(QKeyEvent *keyEvent)
-{
- // ### Merge this function with keyReleaseEvent; they are identical
- // ### (except this comment).
- Q_D(QGraphicsScene);
- QGraphicsItem *item = !d->keyboardGrabberItems.isEmpty() ? d->keyboardGrabberItems.last() : 0;
- if (!item)
- item = focusItem();
- if (item) {
- QGraphicsItem *p = item;
- do {
- // Accept the event by default
- keyEvent->accept();
- // Send it; QGraphicsItem::keyPressEvent ignores it. If the event
- // is filtered out, stop propagating it.
- if (p->isBlockedByModalPanel())
- break;
- if (!d->sendEvent(p, keyEvent))
- break;
- } while (!keyEvent->isAccepted() && !p->isPanel() && (p = p->parentItem()));
- } else {
- keyEvent->ignore();
- }
-}
-
-/*!
- This event handler, for event \a keyEvent, can be reimplemented in a
- subclass to receive key release events. The default implementation
- forwards the event to current focus item.
-
- \sa QGraphicsItem::keyReleaseEvent(), focusItem()
-*/
-void QGraphicsScene::keyReleaseEvent(QKeyEvent *keyEvent)
-{
- // ### Merge this function with keyPressEvent; they are identical (except
- // ### this comment).
- Q_D(QGraphicsScene);
- QGraphicsItem *item = !d->keyboardGrabberItems.isEmpty() ? d->keyboardGrabberItems.last() : 0;
- if (!item)
- item = focusItem();
- if (item) {
- QGraphicsItem *p = item;
- do {
- // Accept the event by default
- keyEvent->accept();
- // Send it; QGraphicsItem::keyPressEvent ignores it. If the event
- // is filtered out, stop propagating it.
- if (p->isBlockedByModalPanel())
- break;
- if (!d->sendEvent(p, keyEvent))
- break;
- } while (!keyEvent->isAccepted() && !p->isPanel() && (p = p->parentItem()));
- } else {
- keyEvent->ignore();
- }
-}
-
-/*!
- This event handler, for event \a mouseEvent, can be reimplemented
- in a subclass to receive mouse press events for the scene.
-
- The default implementation depends on the state of the scene. If
- there is a mouse grabber item, then the event is sent to the mouse
- grabber. Otherwise, it is forwarded to the topmost item that
- accepts mouse events at the scene position from the event, and
- that item promptly becomes the mouse grabber item.
-
- If there is no item at the given position on the scene, the
- selection area is reset, any focus item loses its input focus, and
- the event is then ignored.
-
- \sa QGraphicsItem::mousePressEvent(),
- QGraphicsItem::setAcceptedMouseButtons()
-*/
-void QGraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
-{
- Q_D(QGraphicsScene);
- if (d->mouseGrabberItems.isEmpty()) {
- // Dispatch hover events
- QGraphicsSceneHoverEvent hover;
- _q_hoverFromMouseEvent(&hover, mouseEvent);
- d->dispatchHoverEvent(&hover);
- }
-
- d->mousePressEventHandler(mouseEvent);
-}
-
-/*!
- This event handler, for event \a mouseEvent, can be reimplemented
- in a subclass to receive mouse move events for the scene.
-
- The default implementation depends on the mouse grabber state. If there is
- a mouse grabber item, the event is sent to the mouse grabber. If there
- are any items that accept hover events at the current position, the event
- is translated into a hover event and accepted; otherwise it's ignored.
-
- \sa QGraphicsItem::mousePressEvent(), QGraphicsItem::mouseReleaseEvent(),
- QGraphicsItem::mouseDoubleClickEvent(), QGraphicsItem::setAcceptedMouseButtons()
-*/
-void QGraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent)
-{
- Q_D(QGraphicsScene);
- if (d->mouseGrabberItems.isEmpty()) {
- if (mouseEvent->buttons())
- return;
- QGraphicsSceneHoverEvent hover;
- _q_hoverFromMouseEvent(&hover, mouseEvent);
- mouseEvent->setAccepted(d->dispatchHoverEvent(&hover));
- return;
- }
-
- // Forward the event to the mouse grabber
- d->sendMouseEvent(mouseEvent);
- mouseEvent->accept();
-}
-
-/*!
- This event handler, for event \a mouseEvent, can be reimplemented
- in a subclass to receive mouse release events for the scene.
-
- The default implementation depends on the mouse grabber state. If
- there is no mouse grabber, the event is ignored. Otherwise, if
- there is a mouse grabber item, the event is sent to the mouse
- grabber. If this mouse release represents the last pressed button
- on the mouse, the mouse grabber item then loses the mouse grab.
-
- \sa QGraphicsItem::mousePressEvent(), QGraphicsItem::mouseMoveEvent(),
- QGraphicsItem::mouseDoubleClickEvent(), QGraphicsItem::setAcceptedMouseButtons()
-*/
-void QGraphicsScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent)
-{
- Q_D(QGraphicsScene);
- if (d->mouseGrabberItems.isEmpty()) {
- mouseEvent->ignore();
- return;
- }
-
- // Forward the event to the mouse grabber
- d->sendMouseEvent(mouseEvent);
- mouseEvent->accept();
-
- // Reset the mouse grabber when the last mouse button has been released.
- if (!mouseEvent->buttons()) {
- if (!d->mouseGrabberItems.isEmpty()) {
- d->lastMouseGrabberItem = d->mouseGrabberItems.last();
- if (d->lastMouseGrabberItemHasImplicitMouseGrab)
- d->mouseGrabberItems.last()->ungrabMouse();
- } else {
- d->lastMouseGrabberItem = 0;
- }
-
- // Generate a hoverevent
- QGraphicsSceneHoverEvent hoverEvent;
- _q_hoverFromMouseEvent(&hoverEvent, mouseEvent);
- d->dispatchHoverEvent(&hoverEvent);
- }
-}
-
-/*!
- This event handler, for event \a mouseEvent, can be reimplemented
- in a subclass to receive mouse doubleclick events for the scene.
-
- If someone doubleclicks on the scene, the scene will first receive
- a mouse press event, followed by a release event (i.e., a click),
- then a doubleclick event, and finally a release event. If the
- doubleclick event is delivered to a different item than the one
- that received the first press and release, it will be delivered as
- a press event. However, tripleclick events are not delivered as
- doubleclick events in this case.
-
- The default implementation is similar to mousePressEvent().
-
- \sa QGraphicsItem::mousePressEvent(), QGraphicsItem::mouseMoveEvent(),
- QGraphicsItem::mouseReleaseEvent(), QGraphicsItem::setAcceptedMouseButtons()
-*/
-void QGraphicsScene::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *mouseEvent)
-{
- Q_D(QGraphicsScene);
- d->mousePressEventHandler(mouseEvent);
-}
-
-/*!
- This event handler, for event \a wheelEvent, can be reimplemented in a
- subclass to receive mouse wheel events for the scene.
-
- By default, the event is delivered to the topmost visible item under the
- cursor. If ignored, the event propagates to the item beneath, and again
- until the event is accepted, or it reaches the scene. If no items accept
- the event, it is ignored.
-
- \sa QGraphicsItem::wheelEvent()
-*/
-void QGraphicsScene::wheelEvent(QGraphicsSceneWheelEvent *wheelEvent)
-{
- Q_D(QGraphicsScene);
- QList<QGraphicsItem *> wheelCandidates = d->itemsAtPosition(wheelEvent->screenPos(),
- wheelEvent->scenePos(),
- wheelEvent->widget());
-
-#ifdef Q_WS_MAC
- // On Mac, ignore the event if the first item under the mouse is not the last opened
- // popup (or one of its descendant)
- if (!d->popupWidgets.isEmpty() && !wheelCandidates.isEmpty() && wheelCandidates.first() != d->popupWidgets.back() && !d->popupWidgets.back()->isAncestorOf(wheelCandidates.first())) {
- wheelEvent->accept();
- return;
- }
-#else
- // Find the first popup under the mouse (including the popup's descendants) starting from the last.
- // Remove all popups after the one found, or all or them if no popup is under the mouse.
- // Then continue with the event.
- QList<QGraphicsWidget *>::const_iterator iter = d->popupWidgets.end();
- while (--iter >= d->popupWidgets.begin() && !wheelCandidates.isEmpty()) {
- if (wheelCandidates.first() == *iter || (*iter)->isAncestorOf(wheelCandidates.first()))
- break;
- d->removePopup(*iter);
- }
-#endif
-
- bool hasSetFocus = false;
- foreach (QGraphicsItem *item, wheelCandidates) {
- if (!hasSetFocus && item->isEnabled()
- && ((item->flags() & QGraphicsItem::ItemIsFocusable) && item->d_ptr->mouseSetsFocus)) {
- if (item->isWidget() && static_cast<QGraphicsWidget *>(item)->focusPolicy() == Qt::WheelFocus) {
- hasSetFocus = true;
- if (item != focusItem())
- setFocusItem(item, Qt::MouseFocusReason);
- }
- }
-
- wheelEvent->setPos(item->d_ptr->genericMapFromScene(wheelEvent->scenePos(),
- wheelEvent->widget()));
- wheelEvent->accept();
- bool isPanel = item->isPanel();
- d->sendEvent(item, wheelEvent);
- if (isPanel || wheelEvent->isAccepted())
- break;
- }
-}
-
-/*!
- This event handler, for event \a event, can be reimplemented in a
- subclass to receive input method events for the scene.
-
- The default implementation forwards the event to the focusItem().
- If no item currently has focus or the current focus item does not
- accept input methods, this function does nothing.
-
- \sa QGraphicsItem::inputMethodEvent()
-*/
-void QGraphicsScene::inputMethodEvent(QInputMethodEvent *event)
-{
- Q_D(QGraphicsScene);
- if (d->focusItem && (d->focusItem->flags() & QGraphicsItem::ItemAcceptsInputMethod))
- d->sendEvent(d->focusItem, event);
-}
-
-/*!
- Draws the background of the scene using \a painter, before any items and
- the foreground are drawn. Reimplement this function to provide a custom
- background for the scene.
-
- All painting is done in \e scene coordinates. The \a rect
- parameter is the exposed rectangle.
-
- If all you want is to define a color, texture, or gradient for the
- background, you can call setBackgroundBrush() instead.
-
- \sa drawForeground(), drawItems()
-*/
-void QGraphicsScene::drawBackground(QPainter *painter, const QRectF &rect)
-{
- Q_D(QGraphicsScene);
-
- if (d->backgroundBrush.style() != Qt::NoBrush) {
- if (d->painterStateProtection)
- painter->save();
- painter->setBrushOrigin(0, 0);
- painter->fillRect(rect, backgroundBrush());
- if (d->painterStateProtection)
- painter->restore();
- }
-}
-
-/*!
- Draws the foreground of the scene using \a painter, after the background
- and all items have been drawn. Reimplement this function to provide a
- custom foreground for the scene.
-
- All painting is done in \e scene coordinates. The \a rect
- parameter is the exposed rectangle.
-
- If all you want is to define a color, texture or gradient for the
- foreground, you can call setForegroundBrush() instead.
-
- \sa drawBackground(), drawItems()
-*/
-void QGraphicsScene::drawForeground(QPainter *painter, const QRectF &rect)
-{
- Q_D(QGraphicsScene);
-
- if (d->foregroundBrush.style() != Qt::NoBrush) {
- if (d->painterStateProtection)
- painter->save();
- painter->setBrushOrigin(0, 0);
- painter->fillRect(rect, foregroundBrush());
- if (d->painterStateProtection)
- painter->restore();
- }
-}
-
-static void _q_paintItem(QGraphicsItem *item, QPainter *painter,
- const QStyleOptionGraphicsItem *option, QWidget *widget,
- bool useWindowOpacity, bool painterStateProtection)
-{
- if (!item->isWidget()) {
- item->paint(painter, option, widget);
- return;
- }
- QGraphicsWidget *widgetItem = static_cast<QGraphicsWidget *>(item);
- QGraphicsProxyWidget *proxy = qobject_cast<QGraphicsProxyWidget *>(widgetItem);
- const qreal windowOpacity = (proxy && proxy->widget() && useWindowOpacity)
- ? proxy->widget()->windowOpacity() : 1.0;
- const qreal oldPainterOpacity = painter->opacity();
-
- if (qFuzzyIsNull(windowOpacity))
- return;
- // Set new painter opacity.
- if (windowOpacity < 1.0)
- painter->setOpacity(oldPainterOpacity * windowOpacity);
-
- // set layoutdirection on the painter
- Qt::LayoutDirection oldLayoutDirection = painter->layoutDirection();
- painter->setLayoutDirection(widgetItem->layoutDirection());
-
- if (widgetItem->isWindow() && widgetItem->windowType() != Qt::Popup && widgetItem->windowType() != Qt::ToolTip
- && !(widgetItem->windowFlags() & Qt::FramelessWindowHint)) {
- if (painterStateProtection)
- painter->save();
- widgetItem->paintWindowFrame(painter, option, widget);
- if (painterStateProtection)
- painter->restore();
- } else if (widgetItem->autoFillBackground()) {
- painter->fillRect(option->exposedRect, widgetItem->palette().window());
- }
-
- widgetItem->paint(painter, option, widget);
-
- // Restore layoutdirection on the painter.
- painter->setLayoutDirection(oldLayoutDirection);
- // Restore painter opacity.
- if (windowOpacity < 1.0)
- painter->setOpacity(oldPainterOpacity);
-}
-
-static void _q_paintIntoCache(QPixmap *pix, QGraphicsItem *item, const QRegion &pixmapExposed,
- const QTransform &itemToPixmap, QPainter::RenderHints renderHints,
- const QStyleOptionGraphicsItem *option, bool painterStateProtection)
-{
- QPixmap subPix;
- QPainter pixmapPainter;
- QRect br = pixmapExposed.boundingRect();
-
- // Don't use subpixmap if we get a full update.
- if (pixmapExposed.isEmpty() || (pixmapExposed.rectCount() == 1 && br.contains(pix->rect()))) {
- pix->fill(Qt::transparent);
- pixmapPainter.begin(pix);
- } else {
- subPix = QPixmap(br.size());
- subPix.fill(Qt::transparent);
- pixmapPainter.begin(&subPix);
- pixmapPainter.translate(-br.topLeft());
- if (!pixmapExposed.isEmpty()) {
- // Applied to subPix; paint is adjusted to the coordinate space is
- // correct.
- pixmapPainter.setClipRegion(pixmapExposed);
- }
- }
-
- pixmapPainter.setRenderHints(pixmapPainter.renderHints(), false);
- pixmapPainter.setRenderHints(renderHints, true);
- pixmapPainter.setWorldTransform(itemToPixmap, true);
-
- // Render.
- _q_paintItem(item, &pixmapPainter, option, 0, false, painterStateProtection);
- pixmapPainter.end();
-
- if (!subPix.isNull()) {
- // Blit the subpixmap into the main pixmap.
- pixmapPainter.begin(pix);
- pixmapPainter.setCompositionMode(QPainter::CompositionMode_Source);
- pixmapPainter.setClipRegion(pixmapExposed);
- pixmapPainter.drawPixmap(br.topLeft(), subPix);
- pixmapPainter.end();
- }
-}
-
-// Copied from qpaintengine_vg.cpp
-// Returns true for 90, 180, and 270 degree rotations.
-static inline bool transformIsSimple(const QTransform& transform)
-{
- QTransform::TransformationType type = transform.type();
- if (type <= QTransform::TxScale) {
- return true;
- } else if (type == QTransform::TxRotate) {
- // Check for 90, and 270 degree rotations.
- qreal m11 = transform.m11();
- qreal m12 = transform.m12();
- qreal m21 = transform.m21();
- qreal m22 = transform.m22();
- if (m11 == 0.0f && m22 == 0.0f) {
- if (m12 == 1.0f && m21 == -1.0f)
- return true; // 90 degrees.
- else if (m12 == -1.0f && m21 == 1.0f)
- return true; // 270 degrees.
- else if (m12 == -1.0f && m21 == -1.0f)
- return true; // 90 degrees inverted y.
- else if (m12 == 1.0f && m21 == 1.0f)
- return true; // 270 degrees inverted y.
- }
- }
- return false;
-}
-
-/*!
- \internal
-
- Draws items directly, or using cache.
-*/
-void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painter,
- const QStyleOptionGraphicsItem *option, QWidget *widget,
- bool painterStateProtection)
-{
- QGraphicsItemPrivate *itemd = item->d_ptr.data();
- QGraphicsItem::CacheMode cacheMode = QGraphicsItem::CacheMode(itemd->cacheMode);
-
- // Render directly, using no cache.
- if (cacheMode == QGraphicsItem::NoCache
-#ifdef Q_WS_X11
- || !X11->use_xrender
-#endif
- ) {
- _q_paintItem(static_cast<QGraphicsWidget *>(item), painter, option, widget, true, painterStateProtection);
- return;
- }
-
- const qreal oldPainterOpacity = painter->opacity();
- qreal newPainterOpacity = oldPainterOpacity;
- QGraphicsProxyWidget *proxy = item->isWidget() ? qobject_cast<QGraphicsProxyWidget *>(static_cast<QGraphicsWidget *>(item)) : 0;
- if (proxy && proxy->widget()) {
- const qreal windowOpacity = proxy->widget()->windowOpacity();
- if (windowOpacity < 1.0)
- newPainterOpacity *= windowOpacity;
- }
-
- // Item's (local) bounding rect
- QRectF brect = item->boundingRect();
- QRectF adjustedBrect(brect);
- _q_adjustRect(&adjustedBrect);
- if (adjustedBrect.isEmpty())
- return;
-
- // Fetch the off-screen transparent buffer and exposed area info.
- QPixmapCache::Key pixmapKey;
- QPixmap pix;
- bool pixmapFound;
- QGraphicsItemCache *itemCache = itemd->extraItemCache();
- if (cacheMode == QGraphicsItem::ItemCoordinateCache) {
- pixmapKey = itemCache->key;
- } else {
- pixmapKey = itemCache->deviceData.value(widget).key;
- }
-
- // Find pixmap in cache.
- pixmapFound = QPixmapCache::find(pixmapKey, &pix);
-
- // Render using item coordinate cache mode.
- if (cacheMode == QGraphicsItem::ItemCoordinateCache) {
- QSize pixmapSize;
- bool fixedCacheSize = false;
- QRect br = brect.toAlignedRect();
- if ((fixedCacheSize = itemCache->fixedSize.isValid())) {
- pixmapSize = itemCache->fixedSize;
- } else {
- pixmapSize = br.size();
- }
-
- // Create or recreate the pixmap.
- int adjust = itemCache->fixedSize.isValid() ? 0 : 2;
- QSize adjustSize(adjust*2, adjust*2);
- br.adjust(-adjust, -adjust, adjust, adjust);
- if (pix.isNull() || (!fixedCacheSize && (pixmapSize + adjustSize) != pix.size())) {
- pix = QPixmap(pixmapSize + adjustSize);
- itemCache->boundingRect = br;
- itemCache->exposed.clear();
- itemCache->allExposed = true;
- } else if (itemCache->boundingRect != br) {
- itemCache->boundingRect = br;
- itemCache->exposed.clear();
- itemCache->allExposed = true;
- }
-
- // Redraw any newly exposed areas.
- if (itemCache->allExposed || !itemCache->exposed.isEmpty()) {
-
- //We know that we will modify the pixmap, removing it from the cache
- //will detach the one we have and avoid a deep copy
- if (pixmapFound)
- QPixmapCache::remove(pixmapKey);
-
- // Fit the item's bounding rect into the pixmap's coordinates.
- QTransform itemToPixmap;
- 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
- // rects to device coordinates.
- styleOptionTmp = *option;
- QRegion pixmapExposed;
- QRectF exposedRect;
- if (!itemCache->allExposed) {
- for (int i = 0; i < itemCache->exposed.size(); ++i) {
- QRectF r = itemCache->exposed.at(i);
- exposedRect |= r;
- pixmapExposed += itemToPixmap.mapRect(r).toAlignedRect();
- }
- } else {
- exposedRect = brect;
- }
- styleOptionTmp.exposedRect = exposedRect;
-
- // Render.
- _q_paintIntoCache(&pix, item, pixmapExposed, itemToPixmap, painter->renderHints(),
- &styleOptionTmp, painterStateProtection);
-
- // insert this pixmap into the cache.
- itemCache->key = QPixmapCache::insert(pix);
-
- // Reset expose data.
- itemCache->allExposed = false;
- itemCache->exposed.clear();
- }
-
- // Redraw the exposed area using the transformed painter. Depending on
- // the hardware, this may be a server-side operation, or an expensive
- // qpixmap-image-transform-pixmap roundtrip.
- if (newPainterOpacity != oldPainterOpacity) {
- painter->setOpacity(newPainterOpacity);
- painter->drawPixmap(br.topLeft(), pix);
- painter->setOpacity(oldPainterOpacity);
- } else {
- painter->drawPixmap(br.topLeft(), pix);
- }
- return;
- }
-
- // Render using device coordinate cache mode.
- if (cacheMode == QGraphicsItem::DeviceCoordinateCache) {
- // Find the item's bounds in device coordinates.
- QRectF deviceBounds = painter->worldTransform().mapRect(brect);
- QRect deviceRect = deviceBounds.toRect().adjusted(-1, -1, 1, 1);
- if (deviceRect.isEmpty())
- return;
- QRect viewRect = widget ? widget->rect() : QRect();
- if (widget && !viewRect.intersects(deviceRect))
- return;
-
- // Resort to direct rendering if the device rect exceeds the
- // (optional) maximum bounds. (QGraphicsSvgItem uses this).
- QSize maximumCacheSize =
- itemd->extra(QGraphicsItemPrivate::ExtraMaxDeviceCoordCacheSize).toSize();
- if (!maximumCacheSize.isEmpty()
- && (deviceRect.width() > maximumCacheSize.width()
- || deviceRect.height() > maximumCacheSize.height())) {
- _q_paintItem(static_cast<QGraphicsWidget *>(item), painter, option, widget,
- oldPainterOpacity != newPainterOpacity, painterStateProtection);
- return;
- }
-
- // Create or reuse offscreen pixmap, possibly scroll/blit from the old one.
- // If the world transform is rotated we always recreate the cache to avoid
- // wrong blending.
- bool pixModified = false;
- QGraphicsItemCache::DeviceData *deviceData = &itemCache->deviceData[widget];
- bool invertable = true;
- QTransform diff = deviceData->lastTransform.inverted(&invertable);
- if (invertable)
- diff *= painter->worldTransform();
- deviceData->lastTransform = painter->worldTransform();
- bool allowPartialCacheExposure = false;
- bool simpleTransform = invertable && diff.type() <= QTransform::TxTranslate
- && transformIsSimple(painter->worldTransform());
- if (!simpleTransform) {
- pixModified = true;
- itemCache->allExposed = true;
- itemCache->exposed.clear();
- deviceData->cacheIndent = QPoint();
- pix = QPixmap();
- } else if (!viewRect.isNull()) {
- allowPartialCacheExposure = deviceData->cacheIndent != QPoint();
- }
-
- // Allow partial cache exposure if the device rect isn't fully contained and
- // deviceRect is 20% taller or wider than the viewRect.
- if (!allowPartialCacheExposure && !viewRect.isNull() && !viewRect.contains(deviceRect)) {
- allowPartialCacheExposure = (viewRect.width() * 1.2 < deviceRect.width())
- || (viewRect.height() * 1.2 < deviceRect.height());
- }
-
- QRegion scrollExposure;
- if (allowPartialCacheExposure) {
- // Part of pixmap is drawn. Either device contains viewrect (big
- // item covers whole screen) or parts of device are outside the
- // viewport. In either case the device rect must be the intersect
- // between the two.
- int dx = deviceRect.left() < viewRect.left() ? viewRect.left() - deviceRect.left() : 0;
- int dy = deviceRect.top() < viewRect.top() ? viewRect.top() - deviceRect.top() : 0;
- QPoint newCacheIndent(dx, dy);
- deviceRect &= viewRect;
-
- if (pix.isNull()) {
- deviceData->cacheIndent = QPoint();
- itemCache->allExposed = true;
- itemCache->exposed.clear();
- pixModified = true;
- }
-
- // Copy / "scroll" the old pixmap onto the new ole and calculate
- // scrolled exposure.
- 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.drawPixmap(-diff, pix);
- newPixPainter.end();
- }
- QRegion exposed;
- exposed += newPix.rect();
- if (!pix.isNull())
- exposed -= QRect(-diff, pix.size());
- scrollExposure = exposed;
-
- pix = newPix;
- pixModified = true;
- }
- deviceData->cacheIndent = newCacheIndent;
- } else {
- // Full pixmap is drawn.
- deviceData->cacheIndent = QPoint();
-
- // Auto-adjust the pixmap size.
- if (deviceRect.size() != pix.size()) {
- // exposed needs to cover the whole pixmap
- pix = QPixmap(deviceRect.size());
- pixModified = true;
- itemCache->allExposed = true;
- itemCache->exposed.clear();
- }
- }
-
- // Check for newly invalidated areas.
- if (itemCache->allExposed || !itemCache->exposed.isEmpty() || !scrollExposure.isEmpty()) {
- //We know that we will modify the pixmap, removing it from the cache
- //will detach the one we have and avoid a deep copy
- if (pixmapFound)
- QPixmapCache::remove(pixmapKey);
-
- // Construct an item-to-pixmap transform.
- QPointF p = deviceRect.topLeft();
- 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;
- if (!itemCache->allExposed) {
- const QVector<QRectF> &exposed = itemCache->exposed;
- for (int i = 0; i < exposed.size(); ++i)
- pixmapExposed += itemToPixmap.mapRect(exposed.at(i)).toRect().adjusted(-1, -1, 1, 1);
- }
-
- // Calculate the style option's exposedRect.
- QRectF br;
- if (itemCache->allExposed) {
- br = item->boundingRect();
- } else {
- const QVector<QRectF> &exposed = itemCache->exposed;
- for (int i = 0; i < exposed.size(); ++i)
- br |= exposed.at(i);
- QTransform pixmapToItem = itemToPixmap.inverted();
- foreach (QRect r, scrollExposure.rects())
- br |= pixmapToItem.mapRect(r);
- }
- styleOptionTmp = *option;
- styleOptionTmp.exposedRect = br.adjusted(-1, -1, 1, 1);
-
- // Render the exposed areas.
- _q_paintIntoCache(&pix, item, pixmapExposed, itemToPixmap, painter->renderHints(),
- &styleOptionTmp, painterStateProtection);
-
- // Reset expose data.
- pixModified = true;
- itemCache->allExposed = false;
- itemCache->exposed.clear();
- }
-
- if (pixModified) {
- // Insert this pixmap into the cache.
- deviceData->key = QPixmapCache::insert(pix);
- }
-
- // Redraw the exposed area using an untransformed painter. This
- // effectively becomes a bitblit that does not transform the cache.
- QTransform restoreTransform = painter->worldTransform();
- painter->setWorldTransform(QTransform());
- if (newPainterOpacity != oldPainterOpacity) {
- painter->setOpacity(newPainterOpacity);
- painter->drawPixmap(deviceRect.topLeft(), pix);
- painter->setOpacity(oldPainterOpacity);
- } else {
- painter->drawPixmap(deviceRect.topLeft(), pix);
- }
- painter->setWorldTransform(restoreTransform);
- return;
- }
-}
-
-void QGraphicsScenePrivate::drawItems(QPainter *painter, const QTransform *const viewTransform,
- QRegion *exposedRegion, QWidget *widget)
-{
- // Make sure we don't have unpolished items before we draw.
- if (!unpolishedItems.isEmpty())
- _q_polishItems();
-
- updateAll = false;
- QRectF exposedSceneRect;
- if (exposedRegion && indexMethod != QGraphicsScene::NoIndex) {
- exposedSceneRect = exposedRegion->boundingRect().adjusted(-1, -1, 1, 1);
- if (viewTransform)
- exposedSceneRect = viewTransform->inverted().mapRect(exposedSceneRect);
- }
- const QList<QGraphicsItem *> tli = index->estimateTopLevelItems(exposedSceneRect, Qt::AscendingOrder);
- for (int i = 0; i < tli.size(); ++i)
- drawSubtreeRecursive(tli.at(i), painter, viewTransform, exposedRegion, widget);
-}
-
-void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter *painter,
- const QTransform *const viewTransform,
- QRegion *exposedRegion, QWidget *widget,
- qreal parentOpacity, const QTransform *const effectTransform)
-{
- Q_ASSERT(item);
-
- if (!item->d_ptr->visible)
- return;
-
- const bool itemHasContents = !(item->d_ptr->flags & QGraphicsItem::ItemHasNoContents);
- const bool itemHasChildren = !item->d_ptr->children.isEmpty();
- if (!itemHasContents && !itemHasChildren)
- return; // Item has neither contents nor children!(?)
-
- const qreal opacity = item->d_ptr->combineOpacityFromParent(parentOpacity);
- const bool itemIsFullyTransparent = QGraphicsItemPrivate::isOpacityNull(opacity);
- if (itemIsFullyTransparent && (!itemHasChildren || item->d_ptr->childrenCombineOpacity()))
- return;
-
- QTransform transform(Qt::Uninitialized);
- QTransform *transformPtr = 0;
- bool translateOnlyTransform = false;
-#define ENSURE_TRANSFORM_PTR \
- if (!transformPtr) { \
- Q_ASSERT(!itemIsUntransformable); \
- if (viewTransform) { \
- transform = item->d_ptr->sceneTransform; \
- transform *= *viewTransform; \
- transformPtr = &transform; \
- } else { \
- transformPtr = &item->d_ptr->sceneTransform; \
- translateOnlyTransform = item->d_ptr->sceneTransformTranslateOnly; \
- } \
- }
-
- // Update the item's scene transform if the item is transformable;
- // otherwise calculate the full transform,
- bool wasDirtyParentSceneTransform = false;
- const bool itemIsUntransformable = item->d_ptr->itemIsUntransformable();
- if (itemIsUntransformable) {
- transform = item->deviceTransform(viewTransform ? *viewTransform : QTransform());
- transformPtr = &transform;
- } else if (item->d_ptr->dirtySceneTransform) {
- item->d_ptr->updateSceneTransformFromParent();
- Q_ASSERT(!item->d_ptr->dirtySceneTransform);
- wasDirtyParentSceneTransform = true;
- }
-
- const bool itemClipsChildrenToShape = (item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape);
- bool drawItem = itemHasContents && !itemIsFullyTransparent;
- if (drawItem) {
- const QRectF brect = adjustedItemEffectiveBoundingRect(item);
- ENSURE_TRANSFORM_PTR
- QRect viewBoundingRect = translateOnlyTransform ? brect.translated(transformPtr->dx(), transformPtr->dy()).toAlignedRect()
- : transformPtr->mapRect(brect).toAlignedRect();
- viewBoundingRect.adjust(-int(rectAdjust), -int(rectAdjust), rectAdjust, rectAdjust);
- if (widget)
- item->d_ptr->paintedViewBoundingRects.insert(widget, viewBoundingRect);
- drawItem = exposedRegion ? exposedRegion->intersects(viewBoundingRect)
- : !viewBoundingRect.normalized().isEmpty();
- if (!drawItem) {
- if (!itemHasChildren)
- return;
- if (itemClipsChildrenToShape) {
- if (wasDirtyParentSceneTransform)
- item->d_ptr->invalidateChildrenSceneTransform();
- return;
- }
- }
- } // else we know for sure this item has children we must process.
-
- if (itemHasChildren && itemClipsChildrenToShape)
- ENSURE_TRANSFORM_PTR;
-
-#ifndef QT_NO_GRAPHICSEFFECT
- if (item->d_ptr->graphicsEffect && item->d_ptr->graphicsEffect->isEnabled()) {
- ENSURE_TRANSFORM_PTR;
- QGraphicsItemPaintInfo info(viewTransform, transformPtr, effectTransform, exposedRegion, widget, &styleOptionTmp,
- painter, opacity, wasDirtyParentSceneTransform, itemHasContents && !itemIsFullyTransparent);
- QGraphicsEffectSource *source = item->d_ptr->graphicsEffect->d_func()->source;
- QGraphicsItemEffectSourcePrivate *sourced = static_cast<QGraphicsItemEffectSourcePrivate *>
- (source->d_func());
- sourced->info = &info;
- const QTransform restoreTransform = painter->worldTransform();
- if (effectTransform)
- painter->setWorldTransform(*transformPtr * *effectTransform);
- else
- painter->setWorldTransform(*transformPtr);
- painter->setOpacity(opacity);
-
- if (sourced->currentCachedSystem() != Qt::LogicalCoordinates
- && sourced->lastEffectTransform != painter->worldTransform())
- {
- if (sourced->lastEffectTransform.type() <= QTransform::TxTranslate
- && painter->worldTransform().type() <= QTransform::TxTranslate)
- {
- QRectF sourceRect = sourced->boundingRect(Qt::DeviceCoordinates);
- QRect effectRect = sourced->paddedEffectRect(Qt::DeviceCoordinates, sourced->currentCachedMode(), sourceRect);
-
- sourced->setCachedOffset(effectRect.topLeft());
- } else {
- sourced->invalidateCache(QGraphicsEffectSourcePrivate::TransformChanged);
- }
-
- sourced->lastEffectTransform = painter->worldTransform();
- }
-
- item->d_ptr->graphicsEffect->draw(painter);
- painter->setWorldTransform(restoreTransform);
- sourced->info = 0;
- } else
-#endif //QT_NO_GRAPHICSEFFECT
- {
- draw(item, painter, viewTransform, transformPtr, exposedRegion, widget, opacity,
- effectTransform, wasDirtyParentSceneTransform, drawItem);
- }
-}
-
-static inline void setClip(QPainter *painter, QGraphicsItem *item)
-{
- painter->save();
- QRectF clipRect;
- const QPainterPath clipPath(item->shape());
- if (QPathClipper::pathToRect(clipPath, &clipRect))
- painter->setClipRect(clipRect, Qt::IntersectClip);
- else
- painter->setClipPath(clipPath, Qt::IntersectClip);
-}
-
-static inline void setWorldTransform(QPainter *painter, const QTransform *const transformPtr,
- const QTransform *effectTransform)
-{
- Q_ASSERT(transformPtr);
- if (effectTransform)
- painter->setWorldTransform(*transformPtr * *effectTransform);
- else
- painter->setWorldTransform(*transformPtr);
-}
-
-void QGraphicsScenePrivate::draw(QGraphicsItem *item, QPainter *painter, const QTransform *const viewTransform,
- const QTransform *const transformPtr, QRegion *exposedRegion, QWidget *widget,
- qreal opacity, const QTransform *effectTransform,
- bool wasDirtyParentSceneTransform, bool drawItem)
-{
- const bool itemIsFullyTransparent = QGraphicsItemPrivate::isOpacityNull(opacity);
- const bool itemClipsChildrenToShape = (item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape);
- const bool itemHasChildren = !item->d_ptr->children.isEmpty();
- bool setChildClip = itemClipsChildrenToShape;
- bool itemHasChildrenStackedBehind = false;
-
- int i = 0;
- if (itemHasChildren) {
- if (itemClipsChildrenToShape)
- setWorldTransform(painter, transformPtr, effectTransform);
-
- item->d_ptr->ensureSortedChildren();
- // Items with the 'ItemStacksBehindParent' flag are put in front of the list
- // so all we have to do is to check the first item.
- itemHasChildrenStackedBehind = (item->d_ptr->children.at(0)->d_ptr->flags
- & QGraphicsItem::ItemStacksBehindParent);
-
- if (itemHasChildrenStackedBehind) {
- if (itemClipsChildrenToShape) {
- setClip(painter, item);
- setChildClip = false;
- }
-
- // Draw children behind
- for (i = 0; i < item->d_ptr->children.size(); ++i) {
- QGraphicsItem *child = item->d_ptr->children.at(i);
- if (wasDirtyParentSceneTransform)
- child->d_ptr->dirtySceneTransform = 1;
- if (!(child->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent))
- break;
- if (itemIsFullyTransparent && !(child->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity))
- continue;
- drawSubtreeRecursive(child, painter, viewTransform, exposedRegion, widget, opacity, effectTransform);
- }
- }
- }
-
- // Draw item
- if (drawItem) {
- Q_ASSERT(!itemIsFullyTransparent);
- Q_ASSERT(!(item->d_ptr->flags & QGraphicsItem::ItemHasNoContents));
- Q_ASSERT(transformPtr);
- item->d_ptr->initStyleOption(&styleOptionTmp, *transformPtr, exposedRegion
- ? *exposedRegion : QRegion(), exposedRegion == 0);
-
- const bool itemClipsToShape = item->d_ptr->flags & QGraphicsItem::ItemClipsToShape;
- bool restorePainterClip = false;
-
- if (!itemHasChildren || !itemClipsChildrenToShape) {
- // Item does not have children or clip children to shape.
- setWorldTransform(painter, transformPtr, effectTransform);
- if ((restorePainterClip = itemClipsToShape))
- setClip(painter, item);
- } else if (itemHasChildrenStackedBehind){
- // Item clips children to shape and has children stacked behind, which means
- // the painter is already clipped to the item's shape.
- if (itemClipsToShape) {
- // The clip is already correct. Ensure correct world transform.
- setWorldTransform(painter, transformPtr, effectTransform);
- } else {
- // Remove clip (this also ensures correct world transform).
- painter->restore();
- setChildClip = true;
- }
- } else if (itemClipsToShape) {
- // Item clips children and itself to shape. It does not have hildren stacked
- // behind, which means the clip has not yet been set. We set it now and re-use it
- // for the children.
- setClip(painter, item);
- setChildClip = false;
- }
-
- if (painterStateProtection && !restorePainterClip)
- painter->save();
-
- painter->setOpacity(opacity);
- if (!item->d_ptr->cacheMode && !item->d_ptr->isWidget)
- item->paint(painter, &styleOptionTmp, widget);
- else
- drawItemHelper(item, painter, &styleOptionTmp, widget, painterStateProtection);
-
- if (painterStateProtection || restorePainterClip)
- painter->restore();
-
- static int drawRect = qgetenv("QT_DRAW_SCENE_ITEM_RECTS").toInt();
- if (drawRect) {
- QPen oldPen = painter->pen();
- QBrush oldBrush = painter->brush();
- quintptr ptr = reinterpret_cast<quintptr>(item);
- const QColor color = QColor::fromHsv(ptr % 255, 255, 255);
- painter->setPen(color);
- painter->setBrush(Qt::NoBrush);
- painter->drawRect(adjustedItemBoundingRect(item));
- painter->setPen(oldPen);
- painter->setBrush(oldBrush);
- }
- }
-
- // Draw children in front
- if (itemHasChildren) {
- if (setChildClip)
- setClip(painter, item);
-
- for (; i < item->d_ptr->children.size(); ++i) {
- QGraphicsItem *child = item->d_ptr->children.at(i);
- if (wasDirtyParentSceneTransform)
- child->d_ptr->dirtySceneTransform = 1;
- if (itemIsFullyTransparent && !(child->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity))
- continue;
- drawSubtreeRecursive(child, painter, viewTransform, exposedRegion, widget, opacity, effectTransform);
- }
-
- // Restore child clip
- if (itemClipsChildrenToShape)
- painter->restore();
- }
-}
-
-void QGraphicsScenePrivate::markDirty(QGraphicsItem *item, const QRectF &rect, bool invalidateChildren,
- bool force, bool ignoreOpacity, bool removingItemFromScene,
- bool updateBoundingRect)
-{
- Q_ASSERT(item);
- if (updateAll)
- return;
-
- if (removingItemFromScene && !ignoreOpacity && !item->d_ptr->ignoreOpacity) {
- // If any of the item's ancestors ignore opacity, it means that the opacity
- // was set to 0 (and the update request has not yet been processed). That
- // also means that we have to ignore the opacity for the item itself; otherwise
- // things like: parent->setOpacity(0); scene->removeItem(child) won't work.
- // Note that we only do this when removing items from the scene. In all other
- // cases the ignoreOpacity bit propagates properly in processDirtyItems, but
- // since the item is removed immediately it won't be processed there.
- QGraphicsItem *p = item->d_ptr->parent;
- while (p) {
- if (p->d_ptr->ignoreOpacity) {
- item->d_ptr->ignoreOpacity = true;
- break;
- }
- p = p->d_ptr->parent;
- }
- }
-
- if (item->d_ptr->discardUpdateRequest(/*ignoreVisibleBit=*/force,
- /*ignoreDirtyBit=*/removingItemFromScene || invalidateChildren,
- /*ignoreOpacity=*/ignoreOpacity)) {
- if (item->d_ptr->dirty) {
- // The item is already marked as dirty and will be processed later. However,
- // we have to make sure ignoreVisible and ignoreOpacity are set properly;
- // otherwise things like: item->update(); item->hide() (force is now true)
- // won't work as expected.
- if (force)
- item->d_ptr->ignoreVisible = 1;
- if (ignoreOpacity)
- item->d_ptr->ignoreOpacity = 1;
- }
- return;
- }
-
- const bool fullItemUpdate = rect.isNull();
- if (!fullItemUpdate && rect.isEmpty())
- return;
-
- if (!processDirtyItemsEmitted) {
- QMetaMethod method = q_ptr->metaObject()->method(processDirtyItemsIndex);
- method.invoke(q_ptr, Qt::QueuedConnection);
-// QMetaObject::invokeMethod(q_ptr, "_q_processDirtyItems", Qt::QueuedConnection);
- processDirtyItemsEmitted = true;
- }
-
- if (removingItemFromScene) {
- // Note that this function can be called from the item's destructor, so
- // do NOT call any virtual functions on it within this block.
- if (isSignalConnected(changedSignalIndex) || views.isEmpty()) {
- // This block of code is kept for compatibility. Since 4.5, by default
- // QGraphicsView does not connect the signal and we use the below
- // method of delivering updates.
- q_func()->update();
- return;
- }
-
- for (int i = 0; i < views.size(); ++i) {
- QGraphicsViewPrivate *viewPrivate = views.at(i)->d_func();
- QRect rect = item->d_ptr->paintedViewBoundingRects.value(viewPrivate->viewport);
- rect.translate(viewPrivate->dirtyScrollOffset);
- viewPrivate->updateRect(rect);
- }
- return;
- }
-
- bool hasNoContents = item->d_ptr->flags & QGraphicsItem::ItemHasNoContents;
- if (!hasNoContents) {
- item->d_ptr->dirty = 1;
- if (fullItemUpdate)
- item->d_ptr->fullUpdatePending = 1;
- else if (!item->d_ptr->fullUpdatePending)
- item->d_ptr->needsRepaint |= rect;
- } else if (item->d_ptr->graphicsEffect) {
- invalidateChildren = true;
- }
-
- if (invalidateChildren) {
- item->d_ptr->allChildrenDirty = 1;
- item->d_ptr->dirtyChildren = 1;
- }
-
- if (force)
- item->d_ptr->ignoreVisible = 1;
- if (ignoreOpacity)
- item->d_ptr->ignoreOpacity = 1;
-
- if (!updateBoundingRect)
- item->d_ptr->markParentDirty();
-}
-
-static inline bool updateHelper(QGraphicsViewPrivate *view, QGraphicsItemPrivate *item,
- const QRectF &rect, bool itemIsUntransformable)
-{
- Q_ASSERT(view);
- Q_ASSERT(item);
-
- QGraphicsItem *itemq = static_cast<QGraphicsItem *>(item->q_ptr);
- QGraphicsView *viewq = static_cast<QGraphicsView *>(view->q_ptr);
-
- if (itemIsUntransformable) {
- const QTransform xform = itemq->deviceTransform(viewq->viewportTransform());
- if (!item->hasBoundingRegionGranularity)
- return view->updateRectF(xform.mapRect(rect));
- return view->updateRegion(rect, xform);
- }
-
- if (item->sceneTransformTranslateOnly && view->identityMatrix) {
- const qreal dx = item->sceneTransform.dx();
- const qreal dy = item->sceneTransform.dy();
- QRectF r(rect);
- r.translate(dx - view->horizontalScroll(), dy - view->verticalScroll());
- return view->updateRectF(r);
- }
-
- if (!viewq->isTransformed()) {
- if (!item->hasBoundingRegionGranularity)
- return view->updateRectF(item->sceneTransform.mapRect(rect));
- return view->updateRegion(rect, item->sceneTransform);
- }
-
- QTransform xform = item->sceneTransform;
- xform *= viewq->viewportTransform();
- if (!item->hasBoundingRegionGranularity)
- return view->updateRectF(xform.mapRect(rect));
- return view->updateRegion(rect, xform);
-}
-
-void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool dirtyAncestorContainsChildren,
- qreal parentOpacity)
-{
- Q_Q(QGraphicsScene);
- Q_ASSERT(item);
- Q_ASSERT(!updateAll);
-
- if (!item->d_ptr->dirty && !item->d_ptr->dirtyChildren) {
- resetDirtyItem(item);
- return;
- }
-
- const bool itemIsHidden = !item->d_ptr->ignoreVisible && !item->d_ptr->visible;
- if (itemIsHidden) {
- resetDirtyItem(item, /*recursive=*/true);
- return;
- }
-
- bool itemHasContents = !(item->d_ptr->flags & QGraphicsItem::ItemHasNoContents);
- const bool itemHasChildren = !item->d_ptr->children.isEmpty();
- if (!itemHasContents) {
- if (!itemHasChildren) {
- resetDirtyItem(item);
- return; // Item has neither contents nor children!(?)
- }
- if (item->d_ptr->graphicsEffect)
- itemHasContents = true;
- }
-
- const qreal opacity = item->d_ptr->combineOpacityFromParent(parentOpacity);
- const bool itemIsFullyTransparent = !item->d_ptr->ignoreOpacity
- && QGraphicsItemPrivate::isOpacityNull(opacity);
- if (itemIsFullyTransparent && (!itemHasChildren || item->d_ptr->childrenCombineOpacity())) {
- resetDirtyItem(item, /*recursive=*/itemHasChildren);
- return;
- }
-
- bool wasDirtyParentSceneTransform = item->d_ptr->dirtySceneTransform;
- const bool itemIsUntransformable = item->d_ptr->itemIsUntransformable();
- if (wasDirtyParentSceneTransform && !itemIsUntransformable) {
- item->d_ptr->updateSceneTransformFromParent();
- Q_ASSERT(!item->d_ptr->dirtySceneTransform);
- }
-
- const bool wasDirtyParentViewBoundingRects = item->d_ptr->paintedViewBoundingRectsNeedRepaint;
- if (itemIsFullyTransparent || !itemHasContents || dirtyAncestorContainsChildren) {
- // Make sure we don't process invisible items or items with no content.
- item->d_ptr->dirty = 0;
- item->d_ptr->fullUpdatePending = 0;
- // Might have a dirty view bounding rect otherwise.
- if (itemIsFullyTransparent || !itemHasContents)
- item->d_ptr->paintedViewBoundingRectsNeedRepaint = 0;
- }
-
- if (!hasSceneRect && item->d_ptr->geometryChanged && item->d_ptr->visible) {
- // Update growingItemsBoundingRect.
- if (item->d_ptr->sceneTransformTranslateOnly) {
- growingItemsBoundingRect |= item->boundingRect().translated(item->d_ptr->sceneTransform.dx(),
- item->d_ptr->sceneTransform.dy());
- } else {
- growingItemsBoundingRect |= item->d_ptr->sceneTransform.mapRect(item->boundingRect());
- }
- }
-
- // Process item.
- if (item->d_ptr->dirty || item->d_ptr->paintedViewBoundingRectsNeedRepaint) {
- const bool useCompatUpdate = views.isEmpty() || isSignalConnected(changedSignalIndex);
- const QRectF itemBoundingRect = adjustedItemEffectiveBoundingRect(item);
-
- if (useCompatUpdate && !itemIsUntransformable && qFuzzyIsNull(item->boundingRegionGranularity())) {
- // This block of code is kept for compatibility. Since 4.5, by default
- // QGraphicsView does not connect the signal and we use the below
- // method of delivering updates.
- if (item->d_ptr->sceneTransformTranslateOnly) {
- q->update(itemBoundingRect.translated(item->d_ptr->sceneTransform.dx(),
- item->d_ptr->sceneTransform.dy()));
- } else {
- QRectF rect = item->d_ptr->sceneTransform.mapRect(itemBoundingRect);
- if (!rect.isEmpty())
- q->update(rect);
- }
- } else {
- QRectF dirtyRect;
- bool uninitializedDirtyRect = true;
-
- for (int j = 0; j < views.size(); ++j) {
- QGraphicsView *view = views.at(j);
- QGraphicsViewPrivate *viewPrivate = view->d_func();
- QRect &paintedViewBoundingRect = item->d_ptr->paintedViewBoundingRects[viewPrivate->viewport];
- if (viewPrivate->fullUpdatePending
- || viewPrivate->viewportUpdateMode == QGraphicsView::NoViewportUpdate) {
- // Okay, if we have a full update pending or no viewport update, this item's
- // paintedViewBoundingRect will be updated correctly in the next paintEvent if
- // it is inside the viewport, but for now we can pretend that it is outside.
- paintedViewBoundingRect = QRect(-1, -1, -1, -1);
- continue;
- }
-
- if (item->d_ptr->paintedViewBoundingRectsNeedRepaint) {
- paintedViewBoundingRect.translate(viewPrivate->dirtyScrollOffset);
- if (!viewPrivate->updateRect(paintedViewBoundingRect))
- paintedViewBoundingRect = QRect(-1, -1, -1, -1); // Outside viewport.
- }
-
- if (!item->d_ptr->dirty)
- continue;
-
- if (!item->d_ptr->paintedViewBoundingRectsNeedRepaint
- && paintedViewBoundingRect.x() == -1 && paintedViewBoundingRect.y() == -1
- && paintedViewBoundingRect.width() == -1 && paintedViewBoundingRect.height() == -1) {
- continue; // Outside viewport.
- }
-
- if (uninitializedDirtyRect) {
- dirtyRect = itemBoundingRect;
- if (!item->d_ptr->fullUpdatePending) {
- _q_adjustRect(&item->d_ptr->needsRepaint);
- dirtyRect &= item->d_ptr->needsRepaint;
- }
- uninitializedDirtyRect = false;
- }
-
- if (dirtyRect.isEmpty())
- continue; // Discard updates outside the bounding rect.
-
- if (!updateHelper(viewPrivate, item->d_ptr.data(), dirtyRect, itemIsUntransformable)
- && item->d_ptr->paintedViewBoundingRectsNeedRepaint) {
- paintedViewBoundingRect = QRect(-1, -1, -1, -1); // Outside viewport.
- }
- }
- }
- }
-
- // Process children.
- if (itemHasChildren && item->d_ptr->dirtyChildren) {
- const bool itemClipsChildrenToShape = item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape;
- // Items with no content are threated as 'dummy' items which means they are never drawn and
- // 'processed', so the painted view bounding rect is never up-to-date. This means that whenever
- // such an item changes geometry, its children have to take care of the update regardless
- // of whether the item clips children to shape or not.
- const bool bypassUpdateClip = !itemHasContents && wasDirtyParentViewBoundingRects;
- if (itemClipsChildrenToShape && !bypassUpdateClip) {
- // Make sure child updates are clipped to the item's bounding rect.
- for (int i = 0; i < views.size(); ++i)
- views.at(i)->d_func()->setUpdateClip(item);
- }
- if (!dirtyAncestorContainsChildren) {
- dirtyAncestorContainsChildren = item->d_ptr->fullUpdatePending
- && itemClipsChildrenToShape;
- }
- const bool allChildrenDirty = item->d_ptr->allChildrenDirty;
- const bool parentIgnoresVisible = item->d_ptr->ignoreVisible;
- const bool parentIgnoresOpacity = item->d_ptr->ignoreOpacity;
- for (int i = 0; i < item->d_ptr->children.size(); ++i) {
- QGraphicsItem *child = item->d_ptr->children.at(i);
- if (wasDirtyParentSceneTransform)
- child->d_ptr->dirtySceneTransform = 1;
- if (wasDirtyParentViewBoundingRects)
- child->d_ptr->paintedViewBoundingRectsNeedRepaint = 1;
- if (parentIgnoresVisible)
- child->d_ptr->ignoreVisible = 1;
- if (parentIgnoresOpacity)
- child->d_ptr->ignoreOpacity = 1;
- if (allChildrenDirty) {
- child->d_ptr->dirty = 1;
- child->d_ptr->fullUpdatePending = 1;
- child->d_ptr->dirtyChildren = 1;
- child->d_ptr->allChildrenDirty = 1;
- }
- processDirtyItemsRecursive(child, dirtyAncestorContainsChildren, opacity);
- }
-
- if (itemClipsChildrenToShape) {
- // Reset updateClip.
- for (int i = 0; i < views.size(); ++i)
- views.at(i)->d_func()->setUpdateClip(0);
- }
- } else if (wasDirtyParentSceneTransform) {
- item->d_ptr->invalidateChildrenSceneTransform();
- }
-
- resetDirtyItem(item);
-}
-
-/*!
- \obsolete
-
- Paints the given \a items using the provided \a painter, after the
- background has been drawn, and before the foreground has been
- drawn. All painting is done in \e scene coordinates. Before
- drawing each item, the painter must be transformed using
- QGraphicsItem::sceneTransform().
-
- The \a options parameter is the list of style option objects for
- each item in \a items. The \a numItems parameter is the number of
- items in \a items and options in \a options. The \a widget
- parameter is optional; if specified, it should point to the widget
- that is being painted on.
-
- The default implementation prepares the painter matrix, and calls
- QGraphicsItem::paint() on all items. Reimplement this function to
- provide custom painting of all items for the scene; gaining
- complete control over how each item is drawn. In some cases this
- can increase drawing performance significantly.
-
- Example:
-
- \snippet doc/src/snippets/graphicssceneadditemsnippet.cpp 0
-
- Since Qt 4.6, this function is not called anymore unless
- the QGraphicsView::IndirectPainting flag is given as an Optimization
- flag.
-
- \sa drawBackground(), drawForeground()
-*/
-void QGraphicsScene::drawItems(QPainter *painter,
- int numItems,
- QGraphicsItem *items[],
- const QStyleOptionGraphicsItem options[], QWidget *widget)
-{
- Q_D(QGraphicsScene);
- // Make sure we don't have unpolished items before we draw.
- if (!d->unpolishedItems.isEmpty())
- d->_q_polishItems();
-
- const qreal opacity = painter->opacity();
- QTransform viewTransform = painter->worldTransform();
- Q_UNUSED(options);
-
- // Determine view, expose and flags.
- QGraphicsView *view = widget ? qobject_cast<QGraphicsView *>(widget->parentWidget()) : 0;
- QRegion *expose = 0;
- const quint32 oldRectAdjust = d->rectAdjust;
- if (view) {
- d->updateAll = false;
- expose = &view->d_func()->exposedRegion;
- if (view->d_func()->optimizationFlags & QGraphicsView::DontAdjustForAntialiasing)
- d->rectAdjust = 1;
- else
- d->rectAdjust = 2;
- }
-
- // Find all toplevels, they are already sorted.
- QList<QGraphicsItem *> topLevelItems;
- for (int i = 0; i < numItems; ++i) {
- QGraphicsItem *item = items[i]->topLevelItem();
- if (!item->d_ptr->itemDiscovered) {
- topLevelItems << item;
- item->d_ptr->itemDiscovered = 1;
- d->drawSubtreeRecursive(item, painter, &viewTransform, expose, widget);
- }
- }
-
- d->rectAdjust = oldRectAdjust;
- // Reset discovery bits.
- for (int i = 0; i < topLevelItems.size(); ++i)
- topLevelItems.at(i)->d_ptr->itemDiscovered = 0;
-
- painter->setWorldTransform(viewTransform);
- painter->setOpacity(opacity);
-}
-
-/*!
- \since 4.4
-
- Finds a new widget to give the keyboard focus to, as appropriate for Tab
- and Shift+Tab, and returns true if it can find a new widget, or false if
- it cannot. If \a next is true, this function searches forward; if \a next
- is false, it searches backward.
-
- You can reimplement this function in a subclass of QGraphicsScene to
- provide fine-grained control over how tab focus passes inside your
- scene. The default implementation is based on the tab focus chain defined
- by QGraphicsWidget::setTabOrder().
-*/
-bool QGraphicsScene::focusNextPrevChild(bool next)
-{
- Q_D(QGraphicsScene);
-
- QGraphicsItem *item = focusItem();
- if (item && !item->isWidget()) {
- // Tab out of the scene.
- return false;
- }
- if (!item) {
- if (d->lastFocusItem && !d->lastFocusItem->isWidget()) {
- // Restore focus to the last focusable non-widget item that had
- // focus.
- setFocusItem(d->lastFocusItem, next ? Qt::TabFocusReason : Qt::BacktabFocusReason);
- return true;
- }
- }
- if (!d->tabFocusFirst) {
- // No widgets...
- return false;
- }
-
- // The item must be a widget.
- QGraphicsWidget *widget = 0;
- if (!item) {
- widget = next ? d->tabFocusFirst : d->tabFocusFirst->d_func()->focusPrev;
- } else {
- QGraphicsWidget *test = static_cast<QGraphicsWidget *>(item);
- widget = next ? test->d_func()->focusNext : test->d_func()->focusPrev;
- if ((next && widget == d->tabFocusFirst) || (!next && widget == d->tabFocusFirst->d_func()->focusPrev))
- return false;
- }
- QGraphicsWidget *widgetThatHadFocus = widget;
-
- // Run around the focus chain until we find a widget that can take tab focus.
- do {
- if (widget->flags() & QGraphicsItem::ItemIsFocusable
- && widget->isEnabled() && widget->isVisibleTo(0)
- && (widget->focusPolicy() & Qt::TabFocus)
- && (!item || !item->isPanel() || item->isAncestorOf(widget))
- ) {
- setFocusItem(widget, next ? Qt::TabFocusReason : Qt::BacktabFocusReason);
- return true;
- }
- widget = next ? widget->d_func()->focusNext : widget->d_func()->focusPrev;
- if ((next && widget == d->tabFocusFirst) || (!next && widget == d->tabFocusFirst->d_func()->focusPrev))
- return false;
- } while (widget != widgetThatHadFocus);
-
- return false;
-}
-
-/*!
- \fn QGraphicsScene::changed(const QList<QRectF> &region)
-
- This signal is emitted by QGraphicsScene when control reaches the
- event loop, if the scene content changes. The \a region parameter
- contains a list of scene rectangles that indicate the area that
- has been changed.
-
- \sa QGraphicsView::updateScene()
-*/
-
-/*!
- \fn QGraphicsScene::sceneRectChanged(const QRectF &rect)
-
- This signal is emitted by QGraphicsScene whenever the scene rect changes.
- The \a rect parameter is the new scene rectangle.
-
- \sa QGraphicsView::updateSceneRect()
-*/
-
-/*!
- \fn QGraphicsScene::selectionChanged()
- \since 4.3
-
- This signal is emitted by QGraphicsScene whenever the selection
- changes. You can call selectedItems() to get the new list of selected
- items.
-
- The selection changes whenever an item is selected or unselected, a
- selection area is set, cleared or otherwise changed, if a preselected item
- is added to the scene, or if a selected item is removed from the scene.
-
- QGraphicsScene emits this signal only once for group selection operations.
- For example, if you set a selection area, select or unselect a
- QGraphicsItemGroup, or if you add or remove from the scene a parent item
- that contains several selected items, selectionChanged() is emitted only
- once after the operation has completed (instead of once for each item).
-
- \sa setSelectionArea(), selectedItems(), QGraphicsItem::setSelected()
-*/
-
-/*!
- \since 4.4
-
- Returns the scene's style, or the same as QApplication::style() if the
- scene has not been explicitly assigned a style.
-
- \sa setStyle()
-*/
-QStyle *QGraphicsScene::style() const
-{
- Q_D(const QGraphicsScene);
- // ### This function, and the use of styles in general, is non-reentrant.
- return d->style ? d->style : QApplication::style();
-}
-
-/*!
- \since 4.4
-
- Sets or replaces the style of the scene to \a style, and reparents the
- style to this scene. Any previously assigned style is deleted. The scene's
- style defaults to QApplication::style(), and serves as the default for all
- QGraphicsWidget items in the scene.
-
- Changing the style, either directly by calling this function, or
- indirectly by calling QApplication::setStyle(), will automatically update
- the style for all widgets in the scene that do not have a style explicitly
- assigned to them.
-
- If \a style is 0, QGraphicsScene will revert to QApplication::style().
-
- \sa style()
-*/
-void QGraphicsScene::setStyle(QStyle *style)
-{
- Q_D(QGraphicsScene);
- // ### This function, and the use of styles in general, is non-reentrant.
- if (style == d->style)
- return;
-
- // Delete the old style,
- delete d->style;
- if ((d->style = style))
- d->style->setParent(this);
-
- // Notify the scene.
- QEvent event(QEvent::StyleChange);
- QApplication::sendEvent(this, &event);
-
- // Notify all widgets that don't have a style explicitly set.
- foreach (QGraphicsItem *item, items()) {
- if (item->isWidget()) {
- QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(item);
- if (!widget->testAttribute(Qt::WA_SetStyle))
- QApplication::sendEvent(widget, &event);
- }
- }
-}
-
-/*!
- \property QGraphicsScene::font
- \since 4.4
- \brief the scene's default font
-
- This property provides the scene's font. The scene font defaults to,
- and resolves all its entries from, QApplication::font.
-
- If the scene's font changes, either directly through setFont() or
- indirectly when the application font changes, QGraphicsScene first
- sends itself a \l{QEvent::FontChange}{FontChange} event, and it then
- sends \l{QEvent::FontChange}{FontChange} events to all top-level
- widget items in the scene. These items respond by resolving their own
- fonts to the scene, and they then notify their children, who again
- notify their children, and so on, until all widget items have updated
- their fonts.
-
- Changing the scene font, (directly or indirectly through
- QApplication::setFont(),) automatically schedules a redraw the entire
- scene.
-
- \sa QWidget::font, QApplication::setFont(), palette, style()
-*/
-QFont QGraphicsScene::font() const
-{
- Q_D(const QGraphicsScene);
- return d->font;
-}
-void QGraphicsScene::setFont(const QFont &font)
-{
- Q_D(QGraphicsScene);
- QFont naturalFont = QApplication::font();
- naturalFont.resolve(0);
- QFont resolvedFont = font.resolve(naturalFont);
- d->setFont_helper(resolvedFont);
-}
-
-/*!
- \property QGraphicsScene::palette
- \since 4.4
- \brief the scene's default palette
-
- This property provides the scene's palette. The scene palette defaults to,
- and resolves all its entries from, QApplication::palette.
-
- If the scene's palette changes, either directly through setPalette() or
- indirectly when the application palette changes, QGraphicsScene first
- sends itself a \l{QEvent::PaletteChange}{PaletteChange} event, and it then
- sends \l{QEvent::PaletteChange}{PaletteChange} events to all top-level
- widget items in the scene. These items respond by resolving their own
- palettes to the scene, and they then notify their children, who again
- notify their children, and so on, until all widget items have updated
- their palettes.
-
- Changing the scene palette, (directly or indirectly through
- QApplication::setPalette(),) automatically schedules a redraw the entire
- scene.
-
- \sa QWidget::palette, QApplication::setPalette(), font, style()
-*/
-QPalette QGraphicsScene::palette() const
-{
- Q_D(const QGraphicsScene);
- return d->palette;
-}
-void QGraphicsScene::setPalette(const QPalette &palette)
-{
- Q_D(QGraphicsScene);
- QPalette naturalPalette = QApplication::palette();
- naturalPalette.resolve(0);
- QPalette resolvedPalette = palette.resolve(naturalPalette);
- d->setPalette_helper(resolvedPalette);
-}
-
-/*!
- \since 4.6
-
- Returns true if the scene is active (e.g., it's viewed by
- at least one QGraphicsView that is active); otherwise returns false.
-
- \sa QGraphicsItem::isActive(), QWidget::isActiveWindow()
-*/
-bool QGraphicsScene::isActive() const
-{
- Q_D(const QGraphicsScene);
- return d->activationRefCount > 0;
-}
-
-/*!
- \since 4.6
- Returns the current active panel, or 0 if no panel is currently active.
-
- \sa QGraphicsScene::setActivePanel()
-*/
-QGraphicsItem *QGraphicsScene::activePanel() const
-{
- Q_D(const QGraphicsScene);
- return d->activePanel;
-}
-
-/*!
- \since 4.6
- Activates \a item, which must be an item in this scene. You
- can also pass 0 for \a item, in which case QGraphicsScene will
- deactivate any currently active panel.
-
- If the scene is currently inactive, \a item remains inactive until the
- scene becomes active (or, ir \a item is 0, no item will be activated).
-
- \sa activePanel(), isActive(), QGraphicsItem::isActive()
-*/
-void QGraphicsScene::setActivePanel(QGraphicsItem *item)
-{
- Q_D(QGraphicsScene);
- d->setActivePanelHelper(item, false);
-}
-
-/*!
- \since 4.4
-
- Returns the current active window, or 0 if no window is currently
- active.
-
- \sa QGraphicsScene::setActiveWindow()
-*/
-QGraphicsWidget *QGraphicsScene::activeWindow() const
-{
- Q_D(const QGraphicsScene);
- if (d->activePanel && d->activePanel->isWindow())
- return static_cast<QGraphicsWidget *>(d->activePanel);
- return 0;
-}
-
-/*!
- \since 4.4
- Activates \a widget, which must be a widget in this scene. You can also
- pass 0 for \a widget, in which case QGraphicsScene will deactivate any
- currently active window.
-
- \sa activeWindow(), QGraphicsWidget::isActiveWindow()
-*/
-void QGraphicsScene::setActiveWindow(QGraphicsWidget *widget)
-{
- if (widget && widget->scene() != this) {
- qWarning("QGraphicsScene::setActiveWindow: widget %p must be part of this scene",
- widget);
- return;
- }
-
- // Activate the widget's panel (all windows are panels).
- QGraphicsItem *panel = widget ? widget->panel() : 0;
- setActivePanel(panel);
-
- // Raise
- if (panel) {
- QList<QGraphicsItem *> siblingWindows;
- QGraphicsItem *parent = panel->parentItem();
- // Raise ### inefficient for toplevels
- foreach (QGraphicsItem *sibling, parent ? parent->children() : items()) {
- if (sibling != panel && sibling->isWindow())
- siblingWindows << sibling;
- }
-
- // Find the highest z value.
- qreal z = panel->zValue();
- for (int i = 0; i < siblingWindows.size(); ++i)
- z = qMax(z, siblingWindows.at(i)->zValue());
-
- // This will probably never overflow.
- const qreal litt = qreal(0.001);
- panel->setZValue(z + litt);
- }
-}
-
-/*!
- \since 4.6
-
- Sends event \a event to item \a item through possible event filters.
-
- The event is sent only if the item is enabled.
-
- Returns \c false if the event was filtered or if the item is disabled.
- Otherwise returns the value that was returned from the event handler.
-
- \sa QGraphicsItem::sceneEvent(), QGraphicsItem::sceneEventFilter()
-*/
-bool QGraphicsScene::sendEvent(QGraphicsItem *item, QEvent *event)
-{
- Q_D(QGraphicsScene);
- if (!item) {
- qWarning("QGraphicsScene::sendEvent: cannot send event to a null item");
- return false;
- }
- if (item->scene() != this) {
- qWarning("QGraphicsScene::sendEvent: item %p's scene (%p)"
- " is different from this scene (%p)",
- item, item->scene(), this);
- return false;
- }
- return d->sendEvent(item, event);
-}
-
-void QGraphicsScenePrivate::addView(QGraphicsView *view)
-{
- views << view;
-#ifndef QT_NO_GESTURES
- foreach (Qt::GestureType gesture, grabbedGestures.keys())
- view->viewport()->grabGesture(gesture);
-#endif
-}
-
-void QGraphicsScenePrivate::removeView(QGraphicsView *view)
-{
- views.removeAll(view);
-}
-
-void QGraphicsScenePrivate::updateTouchPointsForItem(QGraphicsItem *item, QTouchEvent *touchEvent)
-{
- QList<QTouchEvent::TouchPoint> touchPoints = touchEvent->touchPoints();
- for (int i = 0; i < touchPoints.count(); ++i) {
- QTouchEvent::TouchPoint &touchPoint = touchPoints[i];
- touchPoint.setRect(item->mapFromScene(touchPoint.sceneRect()).boundingRect());
- touchPoint.setStartPos(item->d_ptr->genericMapFromScene(touchPoint.startScenePos(), touchEvent->widget()));
- touchPoint.setLastPos(item->d_ptr->genericMapFromScene(touchPoint.lastScenePos(), touchEvent->widget()));
- }
- touchEvent->setTouchPoints(touchPoints);
-}
-
-int QGraphicsScenePrivate::findClosestTouchPointId(const QPointF &scenePos)
-{
- int closestTouchPointId = -1;
- qreal closestDistance = qreal(0.);
- foreach (const QTouchEvent::TouchPoint &touchPoint, sceneCurrentTouchPoints) {
- qreal distance = QLineF(scenePos, touchPoint.scenePos()).length();
- if (closestTouchPointId == -1|| distance < closestDistance) {
- closestTouchPointId = touchPoint.id();
- closestDistance = distance;
- }
- }
- return closestTouchPointId;
-}
-
-void QGraphicsScenePrivate::touchEventHandler(QTouchEvent *sceneTouchEvent)
-{
- typedef QPair<Qt::TouchPointStates, QList<QTouchEvent::TouchPoint> > StatesAndTouchPoints;
- QHash<QGraphicsItem *, StatesAndTouchPoints> itemsNeedingEvents;
-
- for (int i = 0; i < sceneTouchEvent->touchPoints().count(); ++i) {
- const QTouchEvent::TouchPoint &touchPoint = sceneTouchEvent->touchPoints().at(i);
-
- // update state
- QGraphicsItem *item = 0;
- if (touchPoint.state() == Qt::TouchPointPressed) {
- if (sceneTouchEvent->deviceType() == QTouchEvent::TouchPad) {
- // on touch-pad devices, send all touch points to the same item
- item = itemForTouchPointId.isEmpty()
- ? 0
- : itemForTouchPointId.constBegin().value();
- }
-
- if (!item) {
- // determine which item this touch point will go to
- cachedItemsUnderMouse = itemsAtPosition(touchPoint.screenPos().toPoint(),
- touchPoint.scenePos(),
- sceneTouchEvent->widget());
- item = cachedItemsUnderMouse.isEmpty() ? 0 : cachedItemsUnderMouse.first();
- }
-
- if (sceneTouchEvent->deviceType() == QTouchEvent::TouchScreen) {
- // on touch-screens, combine this touch point with the closest one we find
- int closestTouchPointId = findClosestTouchPointId(touchPoint.scenePos());
- QGraphicsItem *closestItem = itemForTouchPointId.value(closestTouchPointId);
- if (!item || (closestItem && cachedItemsUnderMouse.contains(closestItem)))
- item = closestItem;
- }
- if (!item)
- continue;
-
- itemForTouchPointId.insert(touchPoint.id(), item);
- sceneCurrentTouchPoints.insert(touchPoint.id(), touchPoint);
- } else if (touchPoint.state() == Qt::TouchPointReleased) {
- item = itemForTouchPointId.take(touchPoint.id());
- if (!item)
- continue;
-
- sceneCurrentTouchPoints.remove(touchPoint.id());
- } else {
- item = itemForTouchPointId.value(touchPoint.id());
- if (!item)
- continue;
- Q_ASSERT(sceneCurrentTouchPoints.contains(touchPoint.id()));
- sceneCurrentTouchPoints[touchPoint.id()] = touchPoint;
- }
-
- StatesAndTouchPoints &statesAndTouchPoints = itemsNeedingEvents[item];
- statesAndTouchPoints.first |= touchPoint.state();
- statesAndTouchPoints.second.append(touchPoint);
- }
-
- if (itemsNeedingEvents.isEmpty()) {
- sceneTouchEvent->accept();
- return;
- }
-
- bool ignoreSceneTouchEvent = true;
- QHash<QGraphicsItem *, StatesAndTouchPoints>::ConstIterator it = itemsNeedingEvents.constBegin();
- const QHash<QGraphicsItem *, StatesAndTouchPoints>::ConstIterator end = itemsNeedingEvents.constEnd();
- for (; it != end; ++it) {
- QGraphicsItem *item = it.key();
-
- (void) item->isBlockedByModalPanel(&item);
-
- // determine event type from the state mask
- QEvent::Type eventType;
- switch (it.value().first) {
- case Qt::TouchPointPressed:
- // all touch points have pressed state
- eventType = QEvent::TouchBegin;
- break;
- case Qt::TouchPointReleased:
- // all touch points have released state
- eventType = QEvent::TouchEnd;
- break;
- case Qt::TouchPointStationary:
- // don't send the event if nothing changed
- continue;
- default:
- // all other combinations
- eventType = QEvent::TouchUpdate;
- break;
- }
-
- QTouchEvent touchEvent(eventType);
- touchEvent.setWidget(sceneTouchEvent->widget());
- touchEvent.setDeviceType(sceneTouchEvent->deviceType());
- touchEvent.setModifiers(sceneTouchEvent->modifiers());
- touchEvent.setTouchPointStates(it.value().first);
- touchEvent.setTouchPoints(it.value().second);
-
- switch (touchEvent.type()) {
- case QEvent::TouchBegin:
- {
- // if the TouchBegin handler recurses, we assume that means the event
- // has been implicitly accepted and continue to send touch events
- item->d_ptr->acceptedTouchBeginEvent = true;
- bool res = sendTouchBeginEvent(item, &touchEvent)
- && touchEvent.isAccepted();
- if (!res) {
- // forget about these touch points, we didn't handle them
- for (int i = 0; i < touchEvent.touchPoints().count(); ++i) {
- const QTouchEvent::TouchPoint &touchPoint = touchEvent.touchPoints().at(i);
- itemForTouchPointId.remove(touchPoint.id());
- sceneCurrentTouchPoints.remove(touchPoint.id());
- }
- ignoreSceneTouchEvent = false;
- }
- break;
- }
- default:
- if (item->d_ptr->acceptedTouchBeginEvent) {
- updateTouchPointsForItem(item, &touchEvent);
- (void) sendEvent(item, &touchEvent);
- ignoreSceneTouchEvent = false;
- }
- break;
- }
- }
- sceneTouchEvent->setAccepted(ignoreSceneTouchEvent);
-}
-
-bool QGraphicsScenePrivate::sendTouchBeginEvent(QGraphicsItem *origin, QTouchEvent *touchEvent)
-{
- Q_Q(QGraphicsScene);
-
- if (cachedItemsUnderMouse.isEmpty() || cachedItemsUnderMouse.first() != origin) {
- const QTouchEvent::TouchPoint &firstTouchPoint = touchEvent->touchPoints().first();
- cachedItemsUnderMouse = itemsAtPosition(firstTouchPoint.screenPos().toPoint(),
- firstTouchPoint.scenePos(),
- touchEvent->widget());
- }
- Q_ASSERT(cachedItemsUnderMouse.first() == origin);
-
- // Set focus on the topmost enabled item that can take focus.
- bool setFocus = false;
-
- foreach (QGraphicsItem *item, cachedItemsUnderMouse) {
- if (item->isEnabled() && ((item->flags() & QGraphicsItem::ItemIsFocusable) && item->d_ptr->mouseSetsFocus)) {
- if (!item->isWidget() || ((QGraphicsWidget *)item)->focusPolicy() & Qt::ClickFocus) {
- setFocus = true;
- if (item != q->focusItem())
- q->setFocusItem(item, Qt::MouseFocusReason);
- break;
- }
- }
- if (item->isPanel())
- break;
- if (item->d_ptr->flags & QGraphicsItem::ItemStopsClickFocusPropagation)
- break;
- if (item->d_ptr->flags & QGraphicsItem::ItemStopsFocusHandling) {
- // Make sure we don't clear focus.
- setFocus = true;
- break;
- }
- }
-
- // If nobody could take focus, clear it.
- if (!stickyFocus && !setFocus)
- q->setFocusItem(0, Qt::MouseFocusReason);
-
- bool res = false;
- bool eventAccepted = touchEvent->isAccepted();
- foreach (QGraphicsItem *item, cachedItemsUnderMouse) {
- // first, try to deliver the touch event
- updateTouchPointsForItem(item, touchEvent);
- bool acceptTouchEvents = item->acceptTouchEvents();
- touchEvent->setAccepted(acceptTouchEvents);
- res = acceptTouchEvents && sendEvent(item, touchEvent);
- eventAccepted = touchEvent->isAccepted();
- if (itemForTouchPointId.value(touchEvent->touchPoints().first().id()) == 0) {
- // item was deleted
- item = 0;
- } else {
- item->d_ptr->acceptedTouchBeginEvent = (res && eventAccepted);
- }
- touchEvent->spont = false;
- if (res && eventAccepted) {
- // the first item to accept the TouchBegin gets an implicit grab.
- for (int i = 0; i < touchEvent->touchPoints().count(); ++i) {
- const QTouchEvent::TouchPoint &touchPoint = touchEvent->touchPoints().at(i);
- itemForTouchPointId[touchPoint.id()] = item; // can be zero
- }
- break;
- }
- if (item && item->isPanel())
- break;
- }
-
- touchEvent->setAccepted(eventAccepted);
- return res;
-}
-
-void QGraphicsScenePrivate::enableTouchEventsOnViews()
-{
- foreach (QGraphicsView *view, views)
- view->viewport()->setAttribute(Qt::WA_AcceptTouchEvents, true);
-}
-
-void QGraphicsScenePrivate::updateInputMethodSensitivityInViews()
-{
- for (int i = 0; i < views.size(); ++i)
- views.at(i)->d_func()->updateInputMethodSensitivity();
-}
-
-void QGraphicsScenePrivate::enterModal(QGraphicsItem *panel, QGraphicsItem::PanelModality previousModality)
-{
- Q_Q(QGraphicsScene);
- Q_ASSERT(panel && panel->isPanel());
-
- QGraphicsItem::PanelModality panelModality = panel->d_ptr->panelModality;
- if (previousModality != QGraphicsItem::NonModal) {
- // the panel is changing from one modality type to another... temporarily set it back so
- // that blockedPanels is populated correctly
- panel->d_ptr->panelModality = previousModality;
- }
-
- QSet<QGraphicsItem *> blockedPanels;
- QList<QGraphicsItem *> items = q->items(); // ### store panels separately
- for (int i = 0; i < items.count(); ++i) {
- QGraphicsItem *item = items.at(i);
- if (item->isPanel() && item->isBlockedByModalPanel())
- blockedPanels.insert(item);
- }
- // blockedPanels contains all currently blocked panels
-
- if (previousModality != QGraphicsItem::NonModal) {
- // reset the modality to the proper value, since we changed it above
- panel->d_ptr->panelModality = panelModality;
- // remove this panel so that it will be reinserted at the front of the stack
- modalPanels.removeAll(panel);
- }
-
- modalPanels.prepend(panel);
-
- if (!hoverItems.isEmpty()) {
- // send GraphicsSceneHoverLeave events to newly blocked hoverItems
- QGraphicsSceneHoverEvent hoverEvent;
- hoverEvent.setScenePos(lastSceneMousePos);
- dispatchHoverEvent(&hoverEvent);
- }
-
- if (!mouseGrabberItems.isEmpty() && lastMouseGrabberItemHasImplicitMouseGrab) {
- QGraphicsItem *item = mouseGrabberItems.last();
- if (item->isBlockedByModalPanel())
- ungrabMouse(item, /*itemIsDying =*/ false);
- }
-
- QEvent windowBlockedEvent(QEvent::WindowBlocked);
- QEvent windowUnblockedEvent(QEvent::WindowUnblocked);
- for (int i = 0; i < items.count(); ++i) {
- QGraphicsItem *item = items.at(i);
- if (item->isPanel()) {
- if (!blockedPanels.contains(item) && item->isBlockedByModalPanel()) {
- // send QEvent::WindowBlocked to newly blocked panels
- sendEvent(item, &windowBlockedEvent);
- } else if (blockedPanels.contains(item) && !item->isBlockedByModalPanel()) {
- // send QEvent::WindowUnblocked to unblocked panels when downgrading
- // a panel from SceneModal to PanelModal
- sendEvent(item, &windowUnblockedEvent);
- }
- }
- }
-}
-
-void QGraphicsScenePrivate::leaveModal(QGraphicsItem *panel)
-{
- Q_Q(QGraphicsScene);
- Q_ASSERT(panel && panel->isPanel());
-
- QSet<QGraphicsItem *> blockedPanels;
- QList<QGraphicsItem *> items = q->items(); // ### same as above
- for (int i = 0; i < items.count(); ++i) {
- QGraphicsItem *item = items.at(i);
- if (item->isPanel() && item->isBlockedByModalPanel())
- blockedPanels.insert(item);
- }
-
- modalPanels.removeAll(panel);
-
- QEvent e(QEvent::WindowUnblocked);
- for (int i = 0; i < items.count(); ++i) {
- QGraphicsItem *item = items.at(i);
- if (item->isPanel() && blockedPanels.contains(item) && !item->isBlockedByModalPanel())
- sendEvent(item, &e);
- }
-
- // send GraphicsSceneHoverEnter events to newly unblocked items
- QGraphicsSceneHoverEvent hoverEvent;
- hoverEvent.setScenePos(lastSceneMousePos);
- dispatchHoverEvent(&hoverEvent);
-}
-
-#ifndef QT_NO_GESTURES
-void QGraphicsScenePrivate::gestureTargetsAtHotSpots(const QSet<QGesture *> &gestures,
- Qt::GestureFlag flag,
- QHash<QGraphicsObject *, QSet<QGesture *> > *targets,
- QSet<QGraphicsObject *> *itemsSet,
- QSet<QGesture *> *normal,
- QSet<QGesture *> *conflicts)
-{
- QSet<QGesture *> normalGestures; // that are not in conflicted state.
- foreach (QGesture *gesture, gestures) {
- if (!gesture->hasHotSpot())
- continue;
- const Qt::GestureType gestureType = gesture->gestureType();
- QList<QGraphicsItem *> items = itemsAtPosition(QPoint(), gesture->d_func()->sceneHotSpot, 0);
- for (int j = 0; j < items.size(); ++j) {
- QGraphicsItem *item = items.at(j);
-
- // Check if the item is blocked by a modal panel and use it as
- // a target instead of this item.
- (void) item->isBlockedByModalPanel(&item);
-
- if (QGraphicsObject *itemobj = item->toGraphicsObject()) {
- QGraphicsItemPrivate *d = item->QGraphicsItem::d_func();
- QMap<Qt::GestureType, Qt::GestureFlags>::const_iterator it =
- d->gestureContext.find(gestureType);
- if (it != d->gestureContext.end() && (!flag || (it.value() & flag))) {
- if (normalGestures.contains(gesture)) {
- normalGestures.remove(gesture);
- if (conflicts)
- conflicts->insert(gesture);
- } else {
- normalGestures.insert(gesture);
- }
- if (targets)
- (*targets)[itemobj].insert(gesture);
- if (itemsSet)
- (*itemsSet).insert(itemobj);
- }
- }
- // Don't propagate through panels.
- if (item->isPanel())
- break;
- }
- }
- if (normal)
- *normal = normalGestures;
-}
-
-void QGraphicsScenePrivate::gestureEventHandler(QGestureEvent *event)
-{
- QWidget *viewport = event->widget();
- if (!viewport)
- return;
- QGraphicsView *graphicsView = qobject_cast<QGraphicsView *>(viewport->parent());
- if (!graphicsView)
- return;
-
- QList<QGesture *> allGestures = event->gestures();
- DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:"
- << "Gestures:" << allGestures;
-
- QSet<QGesture *> startedGestures;
- QPoint delta = viewport->mapFromGlobal(QPoint());
- QTransform toScene = QTransform::fromTranslate(delta.x(), delta.y())
- * graphicsView->viewportTransform().inverted();
- foreach (QGesture *gesture, allGestures) {
- // cache scene coordinates of the hot spot
- if (gesture->hasHotSpot()) {
- gesture->d_func()->sceneHotSpot = toScene.map(gesture->hotSpot());
- } else {
- gesture->d_func()->sceneHotSpot = QPointF();
- }
-
- QGraphicsObject *target = gestureTargets.value(gesture, 0);
- if (!target) {
- // when we are not in started mode but don't have a target
- // then the only one interested in gesture is the view/scene
- if (gesture->state() == Qt::GestureStarted)
- startedGestures.insert(gesture);
- }
- }
-
- if (!startedGestures.isEmpty()) {
- QSet<QGesture *> normalGestures; // that have just one target
- QSet<QGesture *> conflictedGestures; // that have multiple possible targets
- gestureTargetsAtHotSpots(startedGestures, Qt::GestureFlag(0), &cachedItemGestures, 0,
- &normalGestures, &conflictedGestures);
- cachedTargetItems = cachedItemGestures.keys();
- qSort(cachedTargetItems.begin(), cachedTargetItems.end(), qt_closestItemFirst);
- DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:"
- << "Normal gestures:" << normalGestures
- << "Conflicting gestures:" << conflictedGestures;
-
- // deliver conflicted gestures as override events AND remember
- // initial gesture targets
- if (!conflictedGestures.isEmpty()) {
- for (int i = 0; i < cachedTargetItems.size(); ++i) {
- QWeakPointer<QGraphicsObject> item = cachedTargetItems.at(i);
-
- // get gestures to deliver to the current item
- QSet<QGesture *> gestures = conflictedGestures & cachedItemGestures.value(item.data());
- if (gestures.isEmpty())
- continue;
-
- DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:"
- << "delivering override to"
- << item.data() << gestures;
- // send gesture override
- QGestureEvent ev(gestures.toList());
- ev.t = QEvent::GestureOverride;
- ev.setWidget(event->widget());
- // mark event and individual gestures as ignored
- ev.ignore();
- foreach(QGesture *g, gestures)
- ev.setAccepted(g, false);
- sendEvent(item.data(), &ev);
- // mark all accepted gestures to deliver them as normal gesture events
- foreach (QGesture *g, gestures) {
- if (ev.isAccepted() || ev.isAccepted(g)) {
- conflictedGestures.remove(g);
- // mark the item as a gesture target
- if (item) {
- gestureTargets.insert(g, item.data());
- QHash<QGraphicsObject *, QSet<QGesture *> >::iterator it, e;
- it = cachedItemGestures.begin();
- e = cachedItemGestures.end();
- for(; it != e; ++it)
- it.value().remove(g);
- cachedItemGestures[item.data()].insert(g);
- }
- DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:"
- << "override was accepted:"
- << g << item.data();
- }
- // remember the first item that received the override event
- // as it most likely become a target if no one else accepts
- // the override event
- if (!gestureTargets.contains(g) && item)
- gestureTargets.insert(g, item.data());
-
- }
- if (conflictedGestures.isEmpty())
- break;
- }
- }
- // remember the initial target item for each gesture that was not in
- // the conflicted state.
- if (!normalGestures.isEmpty()) {
- for (int i = 0; i < cachedTargetItems.size() && !normalGestures.isEmpty(); ++i) {
- QGraphicsObject *item = cachedTargetItems.at(i);
-
- // get gestures to deliver to the current item
- foreach (QGesture *g, cachedItemGestures.value(item)) {
- if (!gestureTargets.contains(g)) {
- gestureTargets.insert(g, item);
- normalGestures.remove(g);
- }
- }
- }
- }
- }
-
-
- // deliver all gesture events
- QSet<QGesture *> undeliveredGestures;
- QSet<QGesture *> parentPropagatedGestures;
- foreach (QGesture *gesture, allGestures) {
- if (QGraphicsObject *target = gestureTargets.value(gesture, 0)) {
- cachedItemGestures[target].insert(gesture);
- cachedTargetItems.append(target);
- undeliveredGestures.insert(gesture);
- QGraphicsItemPrivate *d = target->QGraphicsItem::d_func();
- const Qt::GestureFlags flags = d->gestureContext.value(gesture->gestureType());
- if (flags & Qt::IgnoredGesturesPropagateToParent)
- parentPropagatedGestures.insert(gesture);
- } else {
- DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:"
- << "no target for" << gesture << "at"
- << gesture->hotSpot() << gesture->d_func()->sceneHotSpot;
- }
- }
- qSort(cachedTargetItems.begin(), cachedTargetItems.end(), qt_closestItemFirst);
- for (int i = 0; i < cachedTargetItems.size(); ++i) {
- QWeakPointer<QGraphicsObject> receiver = cachedTargetItems.at(i);
- QSet<QGesture *> gestures =
- undeliveredGestures & cachedItemGestures.value(receiver.data());
- gestures -= cachedAlreadyDeliveredGestures.value(receiver.data());
-
- if (gestures.isEmpty())
- continue;
-
- cachedAlreadyDeliveredGestures[receiver.data()] += gestures;
- const bool isPanel = receiver.data()->isPanel();
-
- DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:"
- << "delivering to"
- << receiver.data() << gestures;
- QGestureEvent ev(gestures.toList());
- ev.setWidget(event->widget());
- sendEvent(receiver.data(), &ev);
- QSet<QGesture *> ignoredGestures;
- foreach (QGesture *g, gestures) {
- if (!ev.isAccepted() && !ev.isAccepted(g)) {
- // if the gesture was ignored by its target, we will update the
- // targetItems list with a possible target items (items that
- // want to receive partial gestures).
- // ### wont' work if the target was destroyed in the event
- // we will just stop delivering it.
- if (receiver && receiver.data() == gestureTargets.value(g, 0))
- ignoredGestures.insert(g);
- } else {
- if (receiver && g->state() == Qt::GestureStarted) {
- // someone accepted the propagated initial GestureStarted
- // event, let it be the new target for all following events.
- gestureTargets[g] = receiver.data();
- }
- undeliveredGestures.remove(g);
- }
- }
- if (undeliveredGestures.isEmpty())
- break;
-
- // ignoredGestures list is only filled when delivering to the gesture
- // target item, so it is safe to assume item == target.
- if (!ignoredGestures.isEmpty() && !isPanel) {
- // look for new potential targets for gestures that were ignored
- // and should be propagated.
-
- QSet<QGraphicsObject *> targetsSet = cachedTargetItems.toSet();
-
- if (receiver) {
- // first if the gesture should be propagated to parents only
- for (QSet<QGesture *>::iterator it = ignoredGestures.begin();
- it != ignoredGestures.end();) {
- if (parentPropagatedGestures.contains(*it)) {
- QGesture *gesture = *it;
- const Qt::GestureType gestureType = gesture->gestureType();
- QGraphicsItem *item = receiver.data();
- while (item) {
- if (QGraphicsObject *obj = item->toGraphicsObject()) {
- if (item->d_func()->gestureContext.contains(gestureType)) {
- targetsSet.insert(obj);
- cachedItemGestures[obj].insert(gesture);
- }
- }
- if (item->isPanel())
- break;
- item = item->parentItem();
- }
-
- it = ignoredGestures.erase(it);
- continue;
- }
- ++it;
- }
- }
-
- gestureTargetsAtHotSpots(ignoredGestures, Qt::ReceivePartialGestures,
- &cachedItemGestures, &targetsSet, 0, 0);
-
- cachedTargetItems = targetsSet.toList();
- qSort(cachedTargetItems.begin(), cachedTargetItems.end(), qt_closestItemFirst);
- DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:"
- << "new targets:" << cachedTargetItems;
- i = -1; // start delivery again
- continue;
- }
- }
-
- foreach (QGesture *g, startedGestures) {
- if (g->gestureCancelPolicy() == QGesture::CancelAllInContext) {
- DEBUG() << "lets try to cancel some";
- // find gestures in context in Qt::GestureStarted or Qt::GestureUpdated state and cancel them
- cancelGesturesForChildren(g);
- }
- }
-
- // forget about targets for gestures that have ended
- foreach (QGesture *g, allGestures) {
- switch (g->state()) {
- case Qt::GestureFinished:
- case Qt::GestureCanceled:
- gestureTargets.remove(g);
- break;
- default:
- break;
- }
- }
-
- cachedTargetItems.clear();
- cachedItemGestures.clear();
- cachedAlreadyDeliveredGestures.clear();
-}
-
-void QGraphicsScenePrivate::cancelGesturesForChildren(QGesture *original)
-{
- Q_ASSERT(original);
- QGraphicsItem *originalItem = gestureTargets.value(original);
- if (originalItem == 0) // we only act on accepted gestures, which implies it has a target.
- return;
-
- // iterate over all active gestures and for each find the owner
- // if the owner is part of our sub-hierarchy, cancel it.
-
- QSet<QGesture *> canceledGestures;
- QHash<QGesture *, QGraphicsObject *>::Iterator iter = gestureTargets.begin();
- while (iter != gestureTargets.end()) {
- QGraphicsObject *item = iter.value();
- // note that we don't touch the gestures for our originalItem
- if (item != originalItem && originalItem->isAncestorOf(item)) {
- DEBUG() << " found a gesture to cancel" << iter.key();
- iter.key()->d_func()->state = Qt::GestureCanceled;
- canceledGestures << iter.key();
- }
- ++iter;
- }
-
- // sort them per target item by cherry picking from almostCanceledGestures and delivering
- QSet<QGesture *> almostCanceledGestures = canceledGestures;
- QSet<QGesture *>::Iterator setIter;
- while (!almostCanceledGestures.isEmpty()) {
- QGraphicsObject *target = 0;
- QSet<QGesture*> gestures;
- setIter = almostCanceledGestures.begin();
- // sort per target item
- while (setIter != almostCanceledGestures.end()) {
- QGraphicsObject *item = gestureTargets.value(*setIter);
- if (target == 0)
- target = item;
- if (target == item) {
- gestures << *setIter;
- setIter = almostCanceledGestures.erase(setIter);
- } else {
- ++setIter;
- }
- }
- Q_ASSERT(target);
-
- QList<QGesture *> list = gestures.toList();
- QGestureEvent ev(list);
- sendEvent(target, &ev);
-
- foreach (QGesture *g, list) {
- if (ev.isAccepted() || ev.isAccepted(g))
- gestures.remove(g);
- }
-
- foreach (QGesture *g, gestures) {
- if (!g->hasHotSpot())
- continue;
-
- QList<QGraphicsItem *> items = itemsAtPosition(QPoint(), g->d_func()->sceneHotSpot, 0);
- for (int j = 0; j < items.size(); ++j) {
- QGraphicsObject *item = items.at(j)->toGraphicsObject();
- if (!item)
- continue;
- QGraphicsItemPrivate *d = item->QGraphicsItem::d_func();
- if (d->gestureContext.contains(g->gestureType())) {
- QList<QGesture *> list;
- list << g;
- QGestureEvent ev(list);
- sendEvent(item, &ev);
- if (ev.isAccepted() || ev.isAccepted(g))
- break; // successfully delivered
- }
- }
- }
- }
-
- QGestureManager *gestureManager = QApplicationPrivate::instance()->gestureManager;
- Q_ASSERT(gestureManager); // it would be very odd if we got called without a manager.
- for (setIter = canceledGestures.begin(); setIter != canceledGestures.end(); ++setIter) {
- gestureManager->recycle(*setIter);
- gestureTargets.remove(*setIter);
- }
-}
-
-void QGraphicsScenePrivate::grabGesture(QGraphicsItem *, Qt::GestureType gesture)
-{
- (void)QGestureManager::instance(); // create a gesture manager
- if (!grabbedGestures[gesture]++) {
- foreach (QGraphicsView *view, views)
- view->viewport()->grabGesture(gesture);
- }
-}
-
-void QGraphicsScenePrivate::ungrabGesture(QGraphicsItem *item, Qt::GestureType gesture)
-{
- // we know this can only be an object
- Q_ASSERT(item->d_ptr->isObject);
- QGraphicsObject *obj = static_cast<QGraphicsObject *>(item);
- QGestureManager::instance()->cleanupCachedGestures(obj, gesture);
- if (!--grabbedGestures[gesture]) {
- foreach (QGraphicsView *view, views)
- view->viewport()->ungrabGesture(gesture);
- }
-}
-#endif // QT_NO_GESTURES
-
-QT_END_NAMESPACE
-
-#include "moc_qgraphicsscene.cpp"
-
-#endif // QT_NO_GRAPHICSVIEW
diff --git a/src/gui/graphicsview/qgraphicsscene.h b/src/gui/graphicsview/qgraphicsscene.h
deleted file mode 100644
index 5aff805b76..0000000000
--- a/src/gui/graphicsview/qgraphicsscene.h
+++ /dev/null
@@ -1,329 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGRAPHICSSCENE_H
-#define QGRAPHICSSCENE_H
-
-#include <QtCore/qobject.h>
-#include <QtCore/qpoint.h>
-#include <QtCore/qrect.h>
-#include <QtGui/qbrush.h>
-#include <QtGui/qfont.h>
-#include <QtGui/qtransform.h>
-#include <QtGui/qmatrix.h>
-#include <QtGui/qpen.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW
-
-template<typename T> class QList;
-class QFocusEvent;
-class QFont;
-class QFontMetrics;
-class QGraphicsEllipseItem;
-class QGraphicsItem;
-class QGraphicsItemGroup;
-class QGraphicsLineItem;
-class QGraphicsPathItem;
-class QGraphicsPixmapItem;
-class QGraphicsPolygonItem;
-class QGraphicsProxyWidget;
-class QGraphicsRectItem;
-class QGraphicsSceneContextMenuEvent;
-class QGraphicsSceneDragDropEvent;
-class QGraphicsSceneEvent;
-class QGraphicsSceneHelpEvent;
-class QGraphicsSceneHoverEvent;
-class QGraphicsSceneMouseEvent;
-class QGraphicsSceneWheelEvent;
-class QGraphicsSimpleTextItem;
-class QGraphicsTextItem;
-class QGraphicsView;
-class QGraphicsWidget;
-class QGraphicsSceneIndex;
-class QHelpEvent;
-class QInputMethodEvent;
-class QKeyEvent;
-class QLineF;
-class QPainterPath;
-class QPixmap;
-class QPointF;
-class QPolygonF;
-class QRectF;
-class QSizeF;
-class QStyle;
-class QStyleOptionGraphicsItem;
-
-class QGraphicsScenePrivate;
-class Q_GUI_EXPORT QGraphicsScene : public QObject
-{
- Q_OBJECT
- Q_PROPERTY(QBrush backgroundBrush READ backgroundBrush WRITE setBackgroundBrush)
- Q_PROPERTY(QBrush foregroundBrush READ foregroundBrush WRITE setForegroundBrush)
- Q_PROPERTY(ItemIndexMethod itemIndexMethod READ itemIndexMethod WRITE setItemIndexMethod)
- Q_PROPERTY(QRectF sceneRect READ sceneRect WRITE setSceneRect)
- Q_PROPERTY(int bspTreeDepth READ bspTreeDepth WRITE setBspTreeDepth)
- Q_PROPERTY(QPalette palette READ palette WRITE setPalette)
- Q_PROPERTY(QFont font READ font WRITE setFont)
- Q_PROPERTY(bool sortCacheEnabled READ isSortCacheEnabled WRITE setSortCacheEnabled)
- Q_PROPERTY(bool stickyFocus READ stickyFocus WRITE setStickyFocus)
-
-public:
- enum ItemIndexMethod {
- BspTreeIndex,
- NoIndex = -1
- };
-
- enum SceneLayer {
- ItemLayer = 0x1,
- BackgroundLayer = 0x2,
- ForegroundLayer = 0x4,
- AllLayers = 0xffff
- };
- Q_DECLARE_FLAGS(SceneLayers, SceneLayer)
-
- QGraphicsScene(QObject *parent = 0);
- QGraphicsScene(const QRectF &sceneRect, QObject *parent = 0);
- QGraphicsScene(qreal x, qreal y, qreal width, qreal height, QObject *parent = 0);
- virtual ~QGraphicsScene();
-
- QRectF sceneRect() const;
- inline qreal width() const { return sceneRect().width(); }
- inline qreal height() const { return sceneRect().height(); }
- void setSceneRect(const QRectF &rect);
- inline void setSceneRect(qreal x, qreal y, qreal w, qreal h)
- { setSceneRect(QRectF(x, y, w, h)); }
-
- void render(QPainter *painter,
- const QRectF &target = QRectF(), const QRectF &source = QRectF(),
- Qt::AspectRatioMode aspectRatioMode = Qt::KeepAspectRatio);
-
- ItemIndexMethod itemIndexMethod() const;
- void setItemIndexMethod(ItemIndexMethod method);
-
- bool isSortCacheEnabled() const;
- void setSortCacheEnabled(bool enabled);
-
- int bspTreeDepth() const;
- void setBspTreeDepth(int depth);
-
- QRectF itemsBoundingRect() const;
-
- QList<QGraphicsItem *> items() const;
- QList<QGraphicsItem *> items(Qt::SortOrder order) const; // ### Qt 5: unify
-
- QList<QGraphicsItem *> items(const QPointF &pos, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const;
- QList<QGraphicsItem *> items(const QRectF &rect, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const;
- QList<QGraphicsItem *> items(const QPolygonF &polygon, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const;
- QList<QGraphicsItem *> items(const QPainterPath &path, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const;
-
- QList<QGraphicsItem *> items(const QPointF &pos) const; // ### obsolete
- QList<QGraphicsItem *> items(const QRectF &rect, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const; // ### obsolete
- QList<QGraphicsItem *> items(const QPolygonF &polygon, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const; // ### obsolete
- QList<QGraphicsItem *> items(const QPainterPath &path, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const; // ### obsolete
-
- QList<QGraphicsItem *> collidingItems(const QGraphicsItem *item, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const;
-
- QGraphicsItem *itemAt(const QPointF &pos) const; // ### obsolete
- QGraphicsItem *itemAt(const QPointF &pos, const QTransform &deviceTransform) const;
-
- inline QList<QGraphicsItem *> items(qreal x, qreal y, qreal w, qreal h, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const
- { return items(QRectF(x, y, w, h), mode); } // ### obsolete
- inline QList<QGraphicsItem *> items(qreal x, qreal y, qreal w, qreal h, Qt::ItemSelectionMode mode, Qt::SortOrder order,
- const QTransform &deviceTransform = QTransform()) const
- { return items(QRectF(x, y, w, h), mode, order, deviceTransform); }
- inline QGraphicsItem *itemAt(qreal x, qreal y) const // ### obsolete
- { return itemAt(QPointF(x, y)); }
- inline QGraphicsItem *itemAt(qreal x, qreal y, const QTransform &deviceTransform) const
- { return itemAt(QPointF(x, y), deviceTransform); }
-
- QList<QGraphicsItem *> selectedItems() const;
- QPainterPath selectionArea() const;
- void setSelectionArea(const QPainterPath &path); // ### obsolete
- void setSelectionArea(const QPainterPath &path, const QTransform &deviceTransform);
- void setSelectionArea(const QPainterPath &path, Qt::ItemSelectionMode mode); // ### obsolete
- void setSelectionArea(const QPainterPath &path, Qt::ItemSelectionMode mode, const QTransform &deviceTransform);
-
- QGraphicsItemGroup *createItemGroup(const QList<QGraphicsItem *> &items);
- void destroyItemGroup(QGraphicsItemGroup *group);
-
- void addItem(QGraphicsItem *item);
- QGraphicsEllipseItem *addEllipse(const QRectF &rect, const QPen &pen = QPen(), const QBrush &brush = QBrush());
- QGraphicsLineItem *addLine(const QLineF &line, const QPen &pen = QPen());
- QGraphicsPathItem *addPath(const QPainterPath &path, const QPen &pen = QPen(), const QBrush &brush = QBrush());
- QGraphicsPixmapItem *addPixmap(const QPixmap &pixmap);
- QGraphicsPolygonItem *addPolygon(const QPolygonF &polygon, const QPen &pen = QPen(), const QBrush &brush = QBrush());
- QGraphicsRectItem *addRect(const QRectF &rect, const QPen &pen = QPen(), const QBrush &brush = QBrush());
- QGraphicsTextItem *addText(const QString &text, const QFont &font = QFont());
- QGraphicsSimpleTextItem *addSimpleText(const QString &text, const QFont &font = QFont());
- QGraphicsProxyWidget *addWidget(QWidget *widget, Qt::WindowFlags wFlags = 0);
- inline QGraphicsEllipseItem *addEllipse(qreal x, qreal y, qreal w, qreal h, const QPen &pen = QPen(), const QBrush &brush = QBrush())
- { return addEllipse(QRectF(x, y, w, h), pen, brush); }
- inline QGraphicsLineItem *addLine(qreal x1, qreal y1, qreal x2, qreal y2, const QPen &pen = QPen())
- { return addLine(QLineF(x1, y1, x2, y2), pen); }
- inline QGraphicsRectItem *addRect(qreal x, qreal y, qreal w, qreal h, const QPen &pen = QPen(), const QBrush &brush = QBrush())
- { return addRect(QRectF(x, y, w, h), pen, brush); }
- void removeItem(QGraphicsItem *item);
-
- QGraphicsItem *focusItem() const;
- void setFocusItem(QGraphicsItem *item, Qt::FocusReason focusReason = Qt::OtherFocusReason);
- bool hasFocus() const;
- void setFocus(Qt::FocusReason focusReason = Qt::OtherFocusReason);
- void clearFocus();
-
- void setStickyFocus(bool enabled);
- bool stickyFocus() const;
-
- QGraphicsItem *mouseGrabberItem() const;
-
- QBrush backgroundBrush() const;
- void setBackgroundBrush(const QBrush &brush);
-
- QBrush foregroundBrush() const;
- void setForegroundBrush(const QBrush &brush);
-
- virtual QVariant inputMethodQuery(Qt::InputMethodQuery query) const;
-
- QList <QGraphicsView *> views() const;
-
- inline void update(qreal x, qreal y, qreal w, qreal h)
- { update(QRectF(x, y, w, h)); }
- inline void invalidate(qreal x, qreal y, qreal w, qreal h, SceneLayers layers = AllLayers)
- { invalidate(QRectF(x, y, w, h), layers); }
-
- QStyle *style() const;
- void setStyle(QStyle *style);
-
- QFont font() const;
- void setFont(const QFont &font);
-
- QPalette palette() const;
- void setPalette(const QPalette &palette);
-
- bool isActive() const;
- QGraphicsItem *activePanel() const;
- void setActivePanel(QGraphicsItem *item);
- QGraphicsWidget *activeWindow() const;
- void setActiveWindow(QGraphicsWidget *widget);
-
- bool sendEvent(QGraphicsItem *item, QEvent *event);
-
-public Q_SLOTS:
- void update(const QRectF &rect = QRectF());
- void invalidate(const QRectF &rect = QRectF(), SceneLayers layers = AllLayers);
- void advance();
- void clearSelection();
- void clear();
-
-protected:
- bool event(QEvent *event);
- bool eventFilter(QObject *watched, QEvent *event);
- virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent *event);
- virtual void dragEnterEvent(QGraphicsSceneDragDropEvent *event);
- virtual void dragMoveEvent(QGraphicsSceneDragDropEvent *event);
- virtual void dragLeaveEvent(QGraphicsSceneDragDropEvent *event);
- virtual void dropEvent(QGraphicsSceneDragDropEvent *event);
- virtual void focusInEvent(QFocusEvent *event);
- virtual void focusOutEvent(QFocusEvent *event);
- virtual void helpEvent(QGraphicsSceneHelpEvent *event);
- virtual void keyPressEvent(QKeyEvent *event);
- virtual void keyReleaseEvent(QKeyEvent *event);
- virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
- virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
- virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
- virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event);
- virtual void wheelEvent(QGraphicsSceneWheelEvent *event);
- virtual void inputMethodEvent(QInputMethodEvent *event);
-
- virtual void drawBackground(QPainter *painter, const QRectF &rect);
- virtual void drawForeground(QPainter *painter, const QRectF &rect);
- virtual void drawItems(QPainter *painter, int numItems,
- QGraphicsItem *items[],
- const QStyleOptionGraphicsItem options[],
- QWidget *widget = 0);
-
-protected Q_SLOTS:
- bool focusNextPrevChild(bool next);
-
-Q_SIGNALS:
- void changed(const QList<QRectF> &region);
- void sceneRectChanged(const QRectF &rect);
- void selectionChanged();
-
-private:
- Q_DECLARE_PRIVATE(QGraphicsScene)
- Q_DISABLE_COPY(QGraphicsScene)
- Q_PRIVATE_SLOT(d_func(), void _q_emitUpdated())
- Q_PRIVATE_SLOT(d_func(), void _q_polishItems())
- Q_PRIVATE_SLOT(d_func(), void _q_processDirtyItems())
- Q_PRIVATE_SLOT(d_func(), void _q_updateScenePosDescendants())
- friend class QGraphicsItem;
- friend class QGraphicsItemPrivate;
- friend class QGraphicsObject;
- friend class QGraphicsView;
- friend class QGraphicsViewPrivate;
- friend class QGraphicsWidget;
- friend class QGraphicsWidgetPrivate;
- friend class QGraphicsEffect;
- friend class QGraphicsSceneIndex;
- friend class QGraphicsSceneIndexPrivate;
- friend class QGraphicsSceneBspTreeIndex;
- friend class QGraphicsSceneBspTreeIndexPrivate;
- friend class QGraphicsItemEffectSourcePrivate;
-#ifndef QT_NO_GESTURES
- friend class QGesture;
-#endif
-};
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QGraphicsScene::SceneLayers)
-
-#endif // QT_NO_GRAPHICSVIEW
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif
diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h
deleted file mode 100644
index 1e5c358e40..0000000000
--- a/src/gui/graphicsview/qgraphicsscene_p.h
+++ /dev/null
@@ -1,359 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGRAPHICSSCENE_P_H
-#define QGRAPHICSSCENE_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qgraphicsscene.h"
-
-#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW
-
-#include "qgraphicssceneevent.h"
-#include "qgraphicsview.h"
-#include "qgraphicsview_p.h"
-#include "qgraphicsitem_p.h"
-
-#include <private/qobject_p.h>
-#include <QtCore/qbitarray.h>
-#include <QtCore/qlist.h>
-#include <QtCore/qmap.h>
-#include <QtCore/qset.h>
-#include <QtGui/qfont.h>
-#include <QtGui/qpalette.h>
-#include <QtGui/qstyle.h>
-#include <QtGui/qstyleoption.h>
-
-QT_BEGIN_NAMESPACE
-
-class QGraphicsSceneIndex;
-class QGraphicsView;
-class QGraphicsWidget;
-
-class Q_AUTOTEST_EXPORT QGraphicsScenePrivate : public QObjectPrivate
-{
- Q_DECLARE_PUBLIC(QGraphicsScene)
-public:
- QGraphicsScenePrivate();
- void init();
-
- static QGraphicsScenePrivate *get(QGraphicsScene *q);
-
- int changedSignalIndex;
- int processDirtyItemsIndex;
- int polishItemsIndex;
-
- QGraphicsScene::ItemIndexMethod indexMethod;
- QGraphicsSceneIndex *index;
-
- int lastItemCount;
-
- QRectF sceneRect;
-
- quint32 hasSceneRect : 1;
- quint32 dirtyGrowingItemsBoundingRect : 1;
- quint32 updateAll : 1;
- quint32 calledEmitUpdated : 1;
- quint32 processDirtyItemsEmitted : 1;
- quint32 needSortTopLevelItems : 1;
- quint32 holesInTopLevelSiblingIndex : 1;
- quint32 topLevelSequentialOrdering : 1;
- quint32 scenePosDescendantsUpdatePending : 1;
- quint32 stickyFocus : 1;
- quint32 hasFocus : 1;
- quint32 lastMouseGrabberItemHasImplicitMouseGrab : 1;
- quint32 allItemsIgnoreHoverEvents : 1;
- quint32 allItemsUseDefaultCursor : 1;
- quint32 painterStateProtection : 1;
- quint32 sortCacheEnabled : 1; // for compatibility
- quint32 allItemsIgnoreTouchEvents : 1;
- quint32 padding : 15;
-
- QRectF growingItemsBoundingRect;
-
- void _q_emitUpdated();
- QList<QRectF> updatedRects;
-
- QPainterPath selectionArea;
- int selectionChanging;
- QSet<QGraphicsItem *> selectedItems;
- QVector<QGraphicsItem *> unpolishedItems;
- QList<QGraphicsItem *> topLevelItems;
-
- QMap<QGraphicsItem *, QPointF> movingItemsInitialPositions;
- void registerTopLevelItem(QGraphicsItem *item);
- void unregisterTopLevelItem(QGraphicsItem *item);
- void _q_updateLater();
- void _q_polishItems();
-
- void _q_processDirtyItems();
-
- QSet<QGraphicsItem *> scenePosItems;
- void setScenePosItemEnabled(QGraphicsItem *item, bool enabled);
- void registerScenePosItem(QGraphicsItem *item);
- void unregisterScenePosItem(QGraphicsItem *item);
- void _q_updateScenePosDescendants();
-
- void removeItemHelper(QGraphicsItem *item);
-
- QBrush backgroundBrush;
- QBrush foregroundBrush;
-
- quint32 rectAdjust;
- QGraphicsItem *focusItem;
- QGraphicsItem *lastFocusItem;
- QGraphicsItem *passiveFocusItem;
- QGraphicsWidget *tabFocusFirst;
- QGraphicsItem *activePanel;
- QGraphicsItem *lastActivePanel;
- int activationRefCount;
- int childExplicitActivation;
- void setActivePanelHelper(QGraphicsItem *item, bool duringActivationEvent);
- void setFocusItemHelper(QGraphicsItem *item, Qt::FocusReason focusReason);
-
- QList<QGraphicsWidget *> popupWidgets;
- void addPopup(QGraphicsWidget *widget);
- void removePopup(QGraphicsWidget *widget, bool itemIsDying = false);
-
- QGraphicsItem *lastMouseGrabberItem;
- QList<QGraphicsItem *> mouseGrabberItems;
- void grabMouse(QGraphicsItem *item, bool implicit = false);
- void ungrabMouse(QGraphicsItem *item, bool itemIsDying = false);
- void clearMouseGrabber();
-
- QList<QGraphicsItem *> keyboardGrabberItems;
- void grabKeyboard(QGraphicsItem *item);
- void ungrabKeyboard(QGraphicsItem *item, bool itemIsDying = false);
- void clearKeyboardGrabber();
-
- QGraphicsItem *dragDropItem;
- QGraphicsWidget *enterWidget;
- Qt::DropAction lastDropAction;
- QList<QGraphicsItem *> cachedItemsUnderMouse;
- QList<QGraphicsItem *> hoverItems;
- QPointF lastSceneMousePos;
- void enableMouseTrackingOnViews();
- QMap<Qt::MouseButton, QPointF> mouseGrabberButtonDownPos;
- QMap<Qt::MouseButton, QPointF> mouseGrabberButtonDownScenePos;
- QMap<Qt::MouseButton, QPoint> mouseGrabberButtonDownScreenPos;
- QList<QGraphicsItem *> itemsAtPosition(const QPoint &screenPos,
- const QPointF &scenePos,
- QWidget *widget) const;
- void storeMouseButtonsForMouseGrabber(QGraphicsSceneMouseEvent *event);
-
- QList<QGraphicsView *> views;
- void addView(QGraphicsView *view);
- void removeView(QGraphicsView *view);
-
- QMultiMap<QGraphicsItem *, QGraphicsItem *> sceneEventFilters;
- void installSceneEventFilter(QGraphicsItem *watched, QGraphicsItem *filter);
- void removeSceneEventFilter(QGraphicsItem *watched, QGraphicsItem *filter);
- bool filterDescendantEvent(QGraphicsItem *item, QEvent *event);
- bool filterEvent(QGraphicsItem *item, QEvent *event);
- bool sendEvent(QGraphicsItem *item, QEvent *event);
-
- bool dispatchHoverEvent(QGraphicsSceneHoverEvent *hoverEvent);
- bool itemAcceptsHoverEvents_helper(const QGraphicsItem *item) const;
- void leaveScene(QWidget *viewport);
-
- void cloneDragDropEvent(QGraphicsSceneDragDropEvent *dest,
- QGraphicsSceneDragDropEvent *source);
- void sendDragDropEvent(QGraphicsItem *item,
- QGraphicsSceneDragDropEvent *dragDropEvent);
- void sendHoverEvent(QEvent::Type type, QGraphicsItem *item,
- QGraphicsSceneHoverEvent *hoverEvent);
- void sendMouseEvent(QGraphicsSceneMouseEvent *mouseEvent);
- void mousePressEventHandler(QGraphicsSceneMouseEvent *mouseEvent);
- QGraphicsWidget *windowForItem(const QGraphicsItem *item) const;
-
- void drawItemHelper(QGraphicsItem *item, QPainter *painter,
- const QStyleOptionGraphicsItem *option, QWidget *widget,
- bool painterStateProtection);
-
- void drawItems(QPainter *painter, const QTransform *const viewTransform,
- QRegion *exposedRegion, QWidget *widget);
-
- void drawSubtreeRecursive(QGraphicsItem *item, QPainter *painter, const QTransform *const,
- QRegion *exposedRegion, QWidget *widget, qreal parentOpacity = qreal(1.0),
- const QTransform *const effectTransform = 0);
- void draw(QGraphicsItem *, QPainter *, const QTransform *const, const QTransform *const,
- QRegion *, QWidget *, qreal, const QTransform *const, bool, bool);
-
- void markDirty(QGraphicsItem *item, const QRectF &rect = QRectF(), bool invalidateChildren = false,
- bool force = false, bool ignoreOpacity = false, bool removingItemFromScene = false,
- bool updateBoundingRect = false);
- void processDirtyItemsRecursive(QGraphicsItem *item, bool dirtyAncestorContainsChildren = false,
- qreal parentOpacity = qreal(1.0));
-
- inline void resetDirtyItem(QGraphicsItem *item, bool recursive = false)
- {
- Q_ASSERT(item);
- item->d_ptr->dirty = 0;
- item->d_ptr->paintedViewBoundingRectsNeedRepaint = 0;
- item->d_ptr->geometryChanged = 0;
- if (!item->d_ptr->dirtyChildren)
- recursive = false;
- item->d_ptr->dirtyChildren = 0;
- item->d_ptr->needsRepaint = QRectF();
- item->d_ptr->allChildrenDirty = 0;
- item->d_ptr->fullUpdatePending = 0;
- item->d_ptr->ignoreVisible = 0;
- item->d_ptr->ignoreOpacity = 0;
-#ifndef QT_NO_GRAPHICSEFFECT
- QGraphicsEffect::ChangeFlags flags;
- if (item->d_ptr->notifyBoundingRectChanged) {
- flags |= QGraphicsEffect::SourceBoundingRectChanged;
- item->d_ptr->notifyBoundingRectChanged = 0;
- }
- if (item->d_ptr->notifyInvalidated) {
- flags |= QGraphicsEffect::SourceInvalidated;
- item->d_ptr->notifyInvalidated = 0;
- }
-#endif //QT_NO_GRAPHICSEFFECT
- if (recursive) {
- for (int i = 0; i < item->d_ptr->children.size(); ++i)
- resetDirtyItem(item->d_ptr->children.at(i), recursive);
- }
-#ifndef QT_NO_GRAPHICSEFFECT
- if (flags && item->d_ptr->graphicsEffect)
- item->d_ptr->graphicsEffect->sourceChanged(flags);
-#endif //QT_NO_GRAPHICSEFFECT
- }
-
- inline void ensureSortedTopLevelItems()
- {
- if (needSortTopLevelItems) {
- qSort(topLevelItems.begin(), topLevelItems.end(), qt_notclosestLeaf);
- topLevelSequentialOrdering = false;
- needSortTopLevelItems = false;
- }
- }
-
- void ensureSequentialTopLevelSiblingIndexes();
-
- QStyle *style;
- QFont font;
- void setFont_helper(const QFont &font);
- void resolveFont();
- void updateFont(const QFont &font);
- QPalette palette;
- void setPalette_helper(const QPalette &palette);
- void resolvePalette();
- void updatePalette(const QPalette &palette);
-
- QStyleOptionGraphicsItem styleOptionTmp;
-
- QMap<int, QTouchEvent::TouchPoint> sceneCurrentTouchPoints;
- QMap<int, QGraphicsItem *> itemForTouchPointId;
- static void updateTouchPointsForItem(QGraphicsItem *item, QTouchEvent *touchEvent);
- int findClosestTouchPointId(const QPointF &scenePos);
- void touchEventHandler(QTouchEvent *touchEvent);
- bool sendTouchBeginEvent(QGraphicsItem *item, QTouchEvent *touchEvent);
- void enableTouchEventsOnViews();
-
- QList<QGraphicsObject *> cachedTargetItems;
-#ifndef QT_NO_GESTURES
- QHash<QGraphicsObject *, QSet<QGesture *> > cachedItemGestures;
- QHash<QGraphicsObject *, QSet<QGesture *> > cachedAlreadyDeliveredGestures;
- QHash<QGesture *, QGraphicsObject *> gestureTargets;
- QHash<Qt::GestureType, int> grabbedGestures;
- void gestureEventHandler(QGestureEvent *event);
- void gestureTargetsAtHotSpots(const QSet<QGesture *> &gestures,
- Qt::GestureFlag flag,
- QHash<QGraphicsObject *, QSet<QGesture *> > *targets,
- QSet<QGraphicsObject *> *itemsSet = 0,
- QSet<QGesture *> *normal = 0,
- QSet<QGesture *> *conflicts = 0);
- void cancelGesturesForChildren(QGesture *original);
- void grabGesture(QGraphicsItem *, Qt::GestureType gesture);
- void ungrabGesture(QGraphicsItem *, Qt::GestureType gesture);
-#endif // QT_NO_GESTURES
-
- void updateInputMethodSensitivityInViews();
-
- QList<QGraphicsItem *> modalPanels;
- void enterModal(QGraphicsItem *item,
- QGraphicsItem::PanelModality panelModality = QGraphicsItem::NonModal);
- void leaveModal(QGraphicsItem *item);
-};
-
-// 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 void _q_adjustRect(QRectF *rect)
-{
- Q_ASSERT(rect);
- if (!rect->width())
- rect->adjust(qreal(-0.00001), 0, qreal(0.00001), 0);
- if (!rect->height())
- rect->adjust(0, qreal(-0.00001), 0, qreal(0.00001));
-}
-
-static inline QRectF adjustedItemBoundingRect(const QGraphicsItem *item)
-{
- Q_ASSERT(item);
- QRectF boundingRect(item->boundingRect());
- _q_adjustRect(&boundingRect);
- return boundingRect;
-}
-
-static inline QRectF adjustedItemEffectiveBoundingRect(const QGraphicsItem *item)
-{
- Q_ASSERT(item);
- QRectF boundingRect(QGraphicsItemPrivate::get(item)->effectiveBoundingRect());
- _q_adjustRect(&boundingRect);
- return boundingRect;
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_GRAPHICSVIEW
-
-#endif
diff --git a/src/gui/graphicsview/qgraphicssceneevent.cpp b/src/gui/graphicsview/qgraphicssceneevent.cpp
deleted file mode 100644
index dd903be8ea..0000000000
--- a/src/gui/graphicsview/qgraphicssceneevent.cpp
+++ /dev/null
@@ -1,1674 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*!
- \class QGraphicsSceneEvent
- \brief The QGraphicsSceneEvent class provides a base class for all
- graphics view related events.
- \since 4.2
- \ingroup graphicsview-api
-
- When a QGraphicsView receives Qt mouse, keyboard, and drag and
- drop events (QMouseEvent, QKeyEvent, QDragEvent, etc.), it
- translates them into instances of QGraphicsSceneEvent subclasses
- and forwards them to the QGraphicsScene it displays. The scene
- then forwards the events to the relevant items.
-
- For example, when a QGraphicsView receives a QMouseEvent of type
- MousePress as a response to a user click, the view sends a
- QGraphicsSceneMouseEvent of type GraphicsSceneMousePress to the
- underlying QGraphicsScene through its
- \l{QGraphicsScene::}{mousePressEvent()} function. The default
- QGraphicsScene::mousePressEvent() implementation determines which
- item was clicked and forwards the event to
- QGraphicsItem::mousePressEvent().
-
- \omit ### Beskrive widget() \endomit
-
- Subclasses such as QGraphicsSceneMouseEvent and
- QGraphicsSceneContextMenuEvent provide the coordinates from the
- original QEvent in screen, scene, and item coordinates (see
- \l{QGraphicsSceneMouseEvent::}{screenPos()},
- \l{QGraphicsSceneMouseEvent::}{scenePos()}, and
- \l{QGraphicsSceneMouseEvent::}{pos()}). The item coordinates are
- set by the QGraphicsScene before it forwards the event to the
- event to a QGraphicsItem. The mouse events also add the
- possibility to retrieve the coordinates from the last event
- received by the view (see
- \l{QGraphicsSceneMouseEvent::}{lastScreenPos()},
- \l{QGraphicsSceneMouseEvent::}{lastScenePos()}, and
- \l{QGraphicsSceneMouseEvent::}{lastPos()}).
-
- \sa QEvent
-*/
-
-/*!
- \class QGraphicsSceneMouseEvent
- \brief The QGraphicsSceneMouseEvent class provides mouse events
- in the graphics view framework.
- \since 4.2
- \ingroup graphicsview-api
-
- When a QGraphicsView receives a QMouseEvent, it translates it to a
- QGraphicsSceneMouseEvent. The event is then forwarded to the
- QGraphicsScene associated with the view. If the event is not
- handled by the scene, the view may use it, e.g., for the
- \l{QGraphicsView::}{DragMode}.
-
- In addition to containing the item, scene, and screen coordinates
- of the event (as pos(), scenePos(), and screenPos()), mouse
- events also contain the coordinates of the previous mouse
- event received by the view. These can be retrieved with
- lastPos(), lastScreenPos(), and lastScenePos().
-
- \sa QGraphicsSceneContextMenuEvent,
- QGraphicsSceneHoverEvent, QGraphicsSceneWheelEvent,
- QMouseEvent
-*/
-
-/*!
- \class QGraphicsSceneWheelEvent
- \brief The QGraphicsSceneWheelEvent class provides wheel events
- in the graphics view framework.
- \brief The QGraphicsSceneWheelEvent class provides wheel events in the
- graphics view framework.
- \since 4.2
- \ingroup graphicsview-api
-
- \l{QWheelEvent}{QWheelEvent}s received by a QGraphicsView are translated
- into QGraphicsSceneWheelEvents; it translates the QWheelEvent::globalPos()
- into item, scene, and screen coordinates (pos(), scenePos(), and
- screenPos()).
-
- \sa QGraphicsSceneMouseEvent, QGraphicsSceneContextMenuEvent,
- QGraphicsSceneHoverEvent, QWheelEvent
-*/
-
-/*!
- \class QGraphicsSceneContextMenuEvent
- \brief The QGraphicsSceneContextMenuEvent class provides context
- menu events in the graphics view framework.
- \since 4.2
- \ingroup graphicsview-api
-
- A QContextMenuEvent received by a QGraphicsView is translated
- into a QGraphicsSceneContextMenuEvent. The
- QContextMenuEvent::globalPos() is translated into item, scene, and
- screen coordinates (pos(), scenePos(), and screenPos()).
-
- \sa QGraphicsSceneMouseEvent, QGraphicsSceneWheelEvent,
- QContextMenuEvent
-*/
-
-/*!
- \enum QGraphicsSceneContextMenuEvent::Reason
-
- This enum describes the reason why the context event was sent.
-
- \value Mouse The mouse caused the event to be sent. On most
- platforms, this means the right mouse button was clicked.
-
- \value Keyboard The keyboard caused this event to be sent. On
- Windows and Mac OS X, this means the menu button was pressed.
-
- \value Other The event was sent by some other means (i.e. not
- by the mouse or keyboard).
-*/
-
-/*!
- \class QGraphicsSceneHoverEvent
- \brief The QGraphicsSceneHoverEvent class provides hover events
- in the graphics view framework.
- \since 4.2
- \ingroup graphicsview-api
-
- When a QGraphicsView receives a QHoverEvent event, it translates
- it into QGraphicsSceneHoverEvent. The event is then forwarded to
- the QGraphicsScene associated with the view.
-
- \sa QGraphicsSceneMouseEvent, QGraphicsSceneContextMenuEvent,
- QGraphicsSceneWheelEvent, QHoverEvent
-*/
-
-/*!
- \class QGraphicsSceneHelpEvent
- \brief The QGraphicsSceneHelpEvent class provides events when a
- tooltip is requested.
- \since 4.2
- \ingroup graphicsview-api
-
- When a QGraphicsView receives a QEvent of type
- QEvent::ToolTip, it creates a QGraphicsSceneHelpEvent, which is
- forwarded to the scene. You can set a tooltip on a QGraphicsItem
- with \l{QGraphicsItem::}{setToolTip()}; by default QGraphicsScene
- displays the tooltip of the QGraphicsItem with the highest
- z-value (i.e, the top-most item) under the mouse position.
-
- QGraphicsView does not forward events when
- \l{QWhatsThis}{"What's This"} and \l{QStatusTipEvent}{status tip}
- help is requested. If you need this, you can reimplement
- QGraphicsView::viewportEvent() and forward QStatusTipEvent
- events and \l{QEvent}{QEvents} of type QEvent::WhatsThis to the
- scene.
-
- \sa QEvent
-*/
-
-/*!
- \class QGraphicsSceneDragDropEvent
- \brief The QGraphicsSceneDragDropEvent class provides events for
- drag and drop in the graphics view framework.
- \since 4.2
- \ingroup graphicsview-api
-
- QGraphicsView inherits the drag and drop functionality provided
- by QWidget. When it receives a drag and drop event, it translates
- it to a QGraphicsSceneDragDropEvent.
-
- QGraphicsSceneDragDropEvent stores events of type
- GraphicsSceneDragEnter, GraphicsSceneDragLeave,
- GraphicsSceneDragMove, or GraphicsSceneDrop.
-
- QGraphicsSceneDragDropEvent contains the position of the mouse
- cursor in both item, scene, and screen coordinates; this can be
- retrieved with pos(), scenePos(), and screenPos().
-
- The scene sends the event to the first QGraphicsItem under the
- mouse cursor that accepts drops; a graphics item is set to accept
- drops with \l{QGraphicsItem::}{setAcceptDrops()}.
-*/
-
-/*!
- \class QGraphicsSceneResizeEvent
- \brief The QGraphicsSceneResizeEvent class provides events for widget
- resizing in the graphics view framework.
- \since 4.4
- \ingroup graphicsview-api
-
- A QGraphicsWidget sends itself a QGraphicsSceneResizeEvent immediately
- when its geometry changes.
-
- It's similar to QResizeEvent, but its sizes, oldSize() and newSize(), use
- QSizeF instead of QSize.
-
- \sa QGraphicsWidget::setGeometry(), QGraphicsWidget::resize()
-*/
-
-/*!
- \class QGraphicsSceneMoveEvent
- \brief The QGraphicsSceneMoveEvent class provides events for widget
- moving in the graphics view framework.
- \since 4.4
- \ingroup graphicsview-api
-
- A QGraphicsWidget sends itself a QGraphicsSceneMoveEvent immediately when
- its local position changes. The delivery is implemented as part of
- QGraphicsItem::itemChange().
-
- It's similar to QMoveEvent, but its positions, oldPos() and newPos(), use
- QPointF instead of QPoint.
-
- \sa QGraphicsItem::setPos(), QGraphicsItem::ItemPositionChange,
- QGraphicsItem::ItemPositionHasChanged
-*/
-
-#include "qgraphicssceneevent.h"
-
-#ifndef QT_NO_GRAPHICSVIEW
-
-#ifndef QT_NO_DEBUG
-#include <QtCore/qdebug.h>
-#endif
-#include <QtCore/qmap.h>
-#include <QtCore/qpoint.h>
-#include <QtCore/qsize.h>
-#include <QtCore/qstring.h>
-#include "qgraphicsview.h"
-#include "qgraphicsitem.h"
-#include <QtGui/qgesture.h>
-#include <private/qevent_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QGraphicsSceneEventPrivate
-{
-public:
- inline QGraphicsSceneEventPrivate()
- : widget(0),
- q_ptr(0)
- { }
-
- inline virtual ~QGraphicsSceneEventPrivate()
- { }
-
- QWidget *widget;
- QGraphicsSceneEvent *q_ptr;
-};
-
-/*!
- \internal
-
- Constructs a generic graphics scene event of the specified \a type.
-*/
-QGraphicsSceneEvent::QGraphicsSceneEvent(Type type)
- : QEvent(type), d_ptr(new QGraphicsSceneEventPrivate)
-{
- d_ptr->q_ptr = this;
-}
-
-/*!
- \internal
-
- Constructs a generic graphics scene event.
-*/
-QGraphicsSceneEvent::QGraphicsSceneEvent(QGraphicsSceneEventPrivate &dd, Type type)
- : QEvent(type), d_ptr(&dd)
-{
- d_ptr->q_ptr = this;
-}
-
-/*!
- Destroys the event.
-*/
-QGraphicsSceneEvent::~QGraphicsSceneEvent()
-{
-}
-
-/*!
- Returns the widget where the event originated, or 0 if the event
- originates from another application.
-*/
-QWidget *QGraphicsSceneEvent::widget() const
-{
- return d_ptr->widget;
-}
-
-/*!
- \internal
-
- Sets the \a widget related to this event.
-
- \sa widget()
-*/
-void QGraphicsSceneEvent::setWidget(QWidget *widget)
-{
- d_ptr->widget = widget;
-}
-
-class QGraphicsSceneMouseEventPrivate : public QGraphicsSceneEventPrivate
-{
- Q_DECLARE_PUBLIC(QGraphicsSceneMouseEvent)
-public:
- inline QGraphicsSceneMouseEventPrivate()
- : button(Qt::NoButton),
- buttons(0), modifiers(0)
- { }
-
- QPointF pos;
- QPointF scenePos;
- QPoint screenPos;
- QPointF lastPos;
- QPointF lastScenePos;
- QPoint lastScreenPos;
- QMap<Qt::MouseButton, QPointF> buttonDownPos;
- QMap<Qt::MouseButton, QPointF> buttonDownScenePos;
- QMap<Qt::MouseButton, QPoint> buttonDownScreenPos;
- Qt::MouseButton button;
- Qt::MouseButtons buttons;
- Qt::KeyboardModifiers modifiers;
-};
-
-/*!
- \internal
-
- Constructs a generic graphics scene mouse event of the specified \a type.
-*/
-QGraphicsSceneMouseEvent::QGraphicsSceneMouseEvent(Type type)
- : QGraphicsSceneEvent(*new QGraphicsSceneMouseEventPrivate, type)
-{
-}
-
-/*!
- Destroys the event.
-*/
-QGraphicsSceneMouseEvent::~QGraphicsSceneMouseEvent()
-{
-}
-
-/*!
- Returns the mouse cursor position in item coordinates.
-
- \sa scenePos(), screenPos(), lastPos()
-*/
-QPointF QGraphicsSceneMouseEvent::pos() const
-{
- Q_D(const QGraphicsSceneMouseEvent);
- return d->pos;
-}
-
-/*!
- \internal
-*/
-void QGraphicsSceneMouseEvent::setPos(const QPointF &pos)
-{
- Q_D(QGraphicsSceneMouseEvent);
- d->pos = pos;
-}
-
-/*!
- Returns the mouse cursor position in scene coordinates.
-
- \sa pos(), screenPos(), lastScenePos()
-*/
-QPointF QGraphicsSceneMouseEvent::scenePos() const
-{
- Q_D(const QGraphicsSceneMouseEvent);
- return d->scenePos;
-}
-
-/*!
- \internal
-*/
-void QGraphicsSceneMouseEvent::setScenePos(const QPointF &pos)
-{
- Q_D(QGraphicsSceneMouseEvent);
- d->scenePos = pos;
-}
-
-/*!
- Returns the mouse cursor position in screen coordinates.
-
- \sa pos(), scenePos(), lastScreenPos()
-*/
-QPoint QGraphicsSceneMouseEvent::screenPos() const
-{
- Q_D(const QGraphicsSceneMouseEvent);
- return d->screenPos;
-}
-
-/*!
- \internal
-*/
-void QGraphicsSceneMouseEvent::setScreenPos(const QPoint &pos)
-{
- Q_D(QGraphicsSceneMouseEvent);
- d->screenPos = pos;
-}
-
-/*!
- Returns the mouse cursor position in item coordinates where the specified
- \a button was clicked.
-
- \sa buttonDownScenePos(), buttonDownScreenPos(), pos()
-*/
-QPointF QGraphicsSceneMouseEvent::buttonDownPos(Qt::MouseButton button) const
-{
- Q_D(const QGraphicsSceneMouseEvent);
- return d->buttonDownPos.value(button);
-}
-
-/*!
- \internal
-*/
-void QGraphicsSceneMouseEvent::setButtonDownPos(Qt::MouseButton button, const QPointF &pos)
-{
- Q_D(QGraphicsSceneMouseEvent);
- d->buttonDownPos.insert(button, pos);
-}
-
-/*!
- Returns the mouse cursor position in scene coordinates where the
- specified \a button was clicked.
-
- \sa buttonDownPos(), buttonDownScreenPos(), scenePos()
-*/
-QPointF QGraphicsSceneMouseEvent::buttonDownScenePos(Qt::MouseButton button) const
-{
- Q_D(const QGraphicsSceneMouseEvent);
- return d->buttonDownScenePos.value(button);
-}
-
-/*!
- \internal
-*/
-void QGraphicsSceneMouseEvent::setButtonDownScenePos(Qt::MouseButton button, const QPointF &pos)
-{
- Q_D(QGraphicsSceneMouseEvent);
- d->buttonDownScenePos.insert(button, pos);
-}
-
-/*!
- Returns the mouse cursor position in screen coordinates where the
- specified \a button was clicked.
-
- \sa screenPos(), buttonDownPos(), buttonDownScenePos()
-*/
-QPoint QGraphicsSceneMouseEvent::buttonDownScreenPos(Qt::MouseButton button) const
-{
- Q_D(const QGraphicsSceneMouseEvent);
- return d->buttonDownScreenPos.value(button);
-}
-
-/*!
- \internal
-*/
-void QGraphicsSceneMouseEvent::setButtonDownScreenPos(Qt::MouseButton button, const QPoint &pos)
-{
- Q_D(QGraphicsSceneMouseEvent);
- d->buttonDownScreenPos.insert(button, pos);
-}
-
-/*!
- Returns the last recorded mouse cursor position in item
- coordinates.
-
- \sa lastScenePos(), lastScreenPos(), pos()
-*/
-QPointF QGraphicsSceneMouseEvent::lastPos() const
-{
- Q_D(const QGraphicsSceneMouseEvent);
- return d->lastPos;
-}
-
-/*!
- \internal
-*/
-void QGraphicsSceneMouseEvent::setLastPos(const QPointF &pos)
-{
- Q_D(QGraphicsSceneMouseEvent);
- d->lastPos = pos;
-}
-
-/*!
- Returns the last recorded mouse cursor position in scene
- coordinates. The last recorded position is the position of
- the previous mouse event received by the view that created
- the event.
-
- \sa lastPos(), lastScreenPos(), scenePos()
-*/
-QPointF QGraphicsSceneMouseEvent::lastScenePos() const
-{
- Q_D(const QGraphicsSceneMouseEvent);
- return d->lastScenePos;
-}
-
-/*!
- \internal
-*/
-void QGraphicsSceneMouseEvent::setLastScenePos(const QPointF &pos)
-{
- Q_D(QGraphicsSceneMouseEvent);
- d->lastScenePos = pos;
-}
-
-/*!
- Returns the last recorded mouse cursor position in screen
- coordinates. The last recorded position is the position of
- the previous mouse event received by the view that created
- the event.
-
- \sa lastPos(), lastScenePos(), screenPos()
-*/
-QPoint QGraphicsSceneMouseEvent::lastScreenPos() const
-{
- Q_D(const QGraphicsSceneMouseEvent);
- return d->lastScreenPos;
-}
-
-/*!
- \internal
-*/
-void QGraphicsSceneMouseEvent::setLastScreenPos(const QPoint &pos)
-{
- Q_D(QGraphicsSceneMouseEvent);
- d->lastScreenPos = pos;
-}
-
-/*!
- Returns the combination of mouse buttons that were pressed at the
- time the event was sent.
-
- \sa button(), modifiers()
-*/
-Qt::MouseButtons QGraphicsSceneMouseEvent::buttons() const
-{
- Q_D(const QGraphicsSceneMouseEvent);
- return d->buttons;
-}
-
-/*!
- \internal
-*/
-void QGraphicsSceneMouseEvent::setButtons(Qt::MouseButtons buttons)
-{
- Q_D(QGraphicsSceneMouseEvent);
- d->buttons = buttons;
-}
-
-/*!
- Returns the mouse button (if any) that caused the event.
-
- \sa buttons(), modifiers()
-*/
-Qt::MouseButton QGraphicsSceneMouseEvent::button() const
-{
- Q_D(const QGraphicsSceneMouseEvent);
- return d->button;
-}
-
-/*!
- \internal
-*/
-void QGraphicsSceneMouseEvent::setButton(Qt::MouseButton button)
-{
- Q_D(QGraphicsSceneMouseEvent);
- d->button = button;
-}
-
-/*!
- Returns the keyboard modifiers in use at the time the event was
- sent.
-
- \sa buttons(), button()
-*/
-Qt::KeyboardModifiers QGraphicsSceneMouseEvent::modifiers() const
-{
- Q_D(const QGraphicsSceneMouseEvent);
- return d->modifiers;
-}
-
-/*!
- \internal
-*/
-void QGraphicsSceneMouseEvent::setModifiers(Qt::KeyboardModifiers modifiers)
-{
- Q_D(QGraphicsSceneMouseEvent);
- d->modifiers = modifiers;
-}
-
-class QGraphicsSceneWheelEventPrivate : public QGraphicsSceneEventPrivate
-{
- Q_DECLARE_PUBLIC(QGraphicsSceneWheelEvent)
-public:
- inline QGraphicsSceneWheelEventPrivate()
- : buttons(0), modifiers(0), delta(0), orientation(Qt::Horizontal)
- { }
-
- QPointF pos;
- QPointF scenePos;
- QPoint screenPos;
- Qt::MouseButtons buttons;
- Qt::KeyboardModifiers modifiers;
- int delta;
- Qt::Orientation orientation;
-};
-
-/*!
- \internal
-
- Constructs a QGraphicsSceneWheelEvent of type \a type, which
- is always QEvent::GraphicsSceneWheel.
-*/
-QGraphicsSceneWheelEvent::QGraphicsSceneWheelEvent(Type type)
- : QGraphicsSceneEvent(*new QGraphicsSceneWheelEventPrivate, type)
-{
-}
-
-/*!
- Destroys the QGraphicsSceneWheelEvent.
-*/
-QGraphicsSceneWheelEvent::~QGraphicsSceneWheelEvent()
-{
-}
-
-/*!
- Returns the position of the cursor in item coordinates when the
- wheel event occurred.
-
- \sa scenePos(), screenPos()
-*/
-QPointF QGraphicsSceneWheelEvent::pos() const
-{
- Q_D(const QGraphicsSceneWheelEvent);
- return d->pos;
-}
-
-/*!
- \internal
-*/
-void QGraphicsSceneWheelEvent::setPos(const QPointF &pos)
-{
- Q_D(QGraphicsSceneWheelEvent);
- d->pos = pos;
-}
-
-/*!
- Returns the position of the cursor in scene coordinates when the wheel
- event occurred.
-
- \sa pos(), screenPos()
-*/
-QPointF QGraphicsSceneWheelEvent::scenePos() const
-{
- Q_D(const QGraphicsSceneWheelEvent);
- return d->scenePos;
-}
-
-/*!
- \internal
-*/
-void QGraphicsSceneWheelEvent::setScenePos(const QPointF &pos)
-{
- Q_D(QGraphicsSceneWheelEvent);
- d->scenePos = pos;
-}
-
-/*!
- Returns the position of the cursor in screen coordinates when the wheel
- event occurred.
-
- \sa pos(), scenePos()
-*/
-QPoint QGraphicsSceneWheelEvent::screenPos() const
-{
- Q_D(const QGraphicsSceneWheelEvent);
- return d->screenPos;
-}
-
-/*!
- \internal
-*/
-void QGraphicsSceneWheelEvent::setScreenPos(const QPoint &pos)
-{
- Q_D(QGraphicsSceneWheelEvent);
- d->screenPos = pos;
-}
-
-/*!
- Returns the mouse buttons that were pressed when the wheel event occurred.
-
- \sa modifiers()
-*/
-Qt::MouseButtons QGraphicsSceneWheelEvent::buttons() const
-{
- Q_D(const QGraphicsSceneWheelEvent);
- return d->buttons;
-}
-
-/*!
- \internal
-*/
-void QGraphicsSceneWheelEvent::setButtons(Qt::MouseButtons buttons)
-{
- Q_D(QGraphicsSceneWheelEvent);
- d->buttons = buttons;
-}
-
-/*!
- Returns the keyboard modifiers that were active when the wheel event
- occurred.
-
- \sa buttons()
-*/
-Qt::KeyboardModifiers QGraphicsSceneWheelEvent::modifiers() const
-{
- Q_D(const QGraphicsSceneWheelEvent);
- return d->modifiers;
-}
-
-/*!
- \internal
-*/
-void QGraphicsSceneWheelEvent::setModifiers(Qt::KeyboardModifiers modifiers)
-{
- Q_D(QGraphicsSceneWheelEvent);
- d->modifiers = modifiers;
-}
-
-/*!
- Returns the distance that the wheel is rotated, in eighths (1/8s)
- of a degree. A positive value indicates that the wheel was
- rotated forwards away from the user; a negative value indicates
- that the wheel was rotated backwards toward the user.
-
- Most mouse types work in steps of 15 degrees, in which case the delta
- value is a multiple of 120 (== 15 * 8).
-*/
-int QGraphicsSceneWheelEvent::delta() const
-{
- Q_D(const QGraphicsSceneWheelEvent);
- return d->delta;
-}
-
-/*!
- \internal
-*/
-void QGraphicsSceneWheelEvent::setDelta(int delta)
-{
- Q_D(QGraphicsSceneWheelEvent);
- d->delta = delta;
-}
-
-/*!
- Returns the wheel orientation.
-*/
-Qt::Orientation QGraphicsSceneWheelEvent::orientation() const
-{
- Q_D(const QGraphicsSceneWheelEvent);
- return d->orientation;
-}
-
-/*!
- \internal
-*/
-void QGraphicsSceneWheelEvent::setOrientation(Qt::Orientation orientation)
-{
- Q_D(QGraphicsSceneWheelEvent);
- d->orientation = orientation;
-}
-
-class QGraphicsSceneContextMenuEventPrivate : public QGraphicsSceneEventPrivate
-{
- Q_DECLARE_PUBLIC(QGraphicsSceneContextMenuEvent)
- public:
- inline QGraphicsSceneContextMenuEventPrivate()
- : modifiers(0), reason(QGraphicsSceneContextMenuEvent::Other)
- { }
-
- QPointF pos;
- QPointF scenePos;
- QPoint screenPos;
- Qt::KeyboardModifiers modifiers;
- QGraphicsSceneContextMenuEvent::Reason reason;
-};
-
-/*!
- \internal
-
- Constructs a graphics scene context menu event of the specified \a type.
-*/
-QGraphicsSceneContextMenuEvent::QGraphicsSceneContextMenuEvent(Type type)
- : QGraphicsSceneEvent(*new QGraphicsSceneContextMenuEventPrivate, type)
-{
-}
-
-/*!
- Destroys the event.
-*/
-QGraphicsSceneContextMenuEvent::~QGraphicsSceneContextMenuEvent()
-{
-}
-
-/*!
- Returns the position of the mouse cursor in item coordinates at the moment
- the context menu was requested.
-
- \sa scenePos(), screenPos()
-*/
-QPointF QGraphicsSceneContextMenuEvent::pos() const
-{
- Q_D(const QGraphicsSceneContextMenuEvent);
- return d->pos;
-}
-
-/*!
- \fn void QGraphicsSceneContextMenuEvent::setPos(const QPointF &point)
- \internal
-
- Sets the position associated with the context menu to the given \a point
- in item coordinates.
-*/
-void QGraphicsSceneContextMenuEvent::setPos(const QPointF &pos)
-{
- Q_D(QGraphicsSceneContextMenuEvent);
- d->pos = pos;
-}
-
-/*!
- Returns the position of the mouse cursor in scene coordinates at the moment the
- the context menu was requested.
-
- \sa pos(), screenPos()
-*/
-QPointF QGraphicsSceneContextMenuEvent::scenePos() const
-{
- Q_D(const QGraphicsSceneContextMenuEvent);
- return d->scenePos;
-}
-
-/*!
- \fn void QGraphicsSceneContextMenuEvent::setScenePos(const QPointF &point)
- \internal
-
- Sets the position associated with the context menu to the given \a point
- in scene coordinates.
-*/
-void QGraphicsSceneContextMenuEvent::setScenePos(const QPointF &pos)
-{
- Q_D(QGraphicsSceneContextMenuEvent);
- d->scenePos = pos;
-}
-
-/*!
- Returns the position of the mouse cursor in screen coordinates at the moment the
- the context menu was requested.
-
- \sa pos(), scenePos()
-*/
-QPoint QGraphicsSceneContextMenuEvent::screenPos() const
-{
- Q_D(const QGraphicsSceneContextMenuEvent);
- return d->screenPos;
-}
-
-/*!
- \fn void QGraphicsSceneContextMenuEvent::setScreenPos(const QPoint &point)
- \internal
-
- Sets the position associated with the context menu to the given \a point
- in screen coordinates.
-*/
-void QGraphicsSceneContextMenuEvent::setScreenPos(const QPoint &pos)
-{
- Q_D(QGraphicsSceneContextMenuEvent);
- d->screenPos = pos;
-}
-
-/*!
- Returns the keyboard modifiers in use when the context menu was requested.
-*/
-Qt::KeyboardModifiers QGraphicsSceneContextMenuEvent::modifiers() const
-{
- Q_D(const QGraphicsSceneContextMenuEvent);
- return d->modifiers;
-}
-
-/*!
- \internal
-
- Sets the keyboard modifiers associated with the context menu to the \a
- modifiers specified.
-*/
-void QGraphicsSceneContextMenuEvent::setModifiers(Qt::KeyboardModifiers modifiers)
-{
- Q_D(QGraphicsSceneContextMenuEvent);
- d->modifiers = modifiers;
-}
-
-/*!
- Returns the reason for the context menu event.
-
- \sa QGraphicsSceneContextMenuEvent::Reason
-*/
-QGraphicsSceneContextMenuEvent::Reason QGraphicsSceneContextMenuEvent::reason() const
-{
- Q_D(const QGraphicsSceneContextMenuEvent);
- return d->reason;
-}
-
-/*!
- \internal
- Sets the reason for the context menu event to \a reason.
-
- \sa reason()
-*/
-void QGraphicsSceneContextMenuEvent::setReason(Reason reason)
-{
- Q_D(QGraphicsSceneContextMenuEvent);
- d->reason = reason;
-}
-
-class QGraphicsSceneHoverEventPrivate : public QGraphicsSceneEventPrivate
-{
-public:
- QPointF pos;
- QPointF scenePos;
- QPoint screenPos;
- QPointF lastPos;
- QPointF lastScenePos;
- QPoint lastScreenPos;
- Qt::KeyboardModifiers modifiers;
-};
-
-/*!
- \internal
-
- Constructs a graphics scene hover event of the specified \a type.
-*/
-QGraphicsSceneHoverEvent::QGraphicsSceneHoverEvent(Type type)
- : QGraphicsSceneEvent(*new QGraphicsSceneHoverEventPrivate, type)
-{
-}
-
-/*!
- Destroys the event.
-*/
-QGraphicsSceneHoverEvent::~QGraphicsSceneHoverEvent()
-{
-}
-
-/*!
- Returns the position of the mouse cursor in item coordinates at the moment
- the hover event was sent.
-
- \sa scenePos(), screenPos()
-*/
-QPointF QGraphicsSceneHoverEvent::pos() const
-{
- Q_D(const QGraphicsSceneHoverEvent);
- return d->pos;
-}
-
-/*!
- \fn void QGraphicsSceneHoverEvent::setPos(const QPointF &point)
- \internal
-
- Sets the position associated with the hover event to the given \a point in
- item coordinates.
-*/
-void QGraphicsSceneHoverEvent::setPos(const QPointF &pos)
-{
- Q_D(QGraphicsSceneHoverEvent);
- d->pos = pos;
-}
-
-/*!
- Returns the position of the mouse cursor in scene coordinates at the
- moment the hover event was sent.
-
- \sa pos(), screenPos()
-*/
-QPointF QGraphicsSceneHoverEvent::scenePos() const
-{
- Q_D(const QGraphicsSceneHoverEvent);
- return d->scenePos;
-}
-
-/*!
- \fn void QGraphicsSceneHoverEvent::setScenePos(const QPointF &point)
- \internal
-
- Sets the position associated with the hover event to the given \a point in
- scene coordinates.
-*/
-void QGraphicsSceneHoverEvent::setScenePos(const QPointF &pos)
-{
- Q_D(QGraphicsSceneHoverEvent);
- d->scenePos = pos;
-}
-
-/*!
- Returns the position of the mouse cursor in screen coordinates at the
- moment the hover event was sent.
-
- \sa pos(), scenePos()
-*/
-QPoint QGraphicsSceneHoverEvent::screenPos() const
-{
- Q_D(const QGraphicsSceneHoverEvent);
- return d->screenPos;
-}
-
-/*!
- \fn void QGraphicsSceneHoverEvent::setScreenPos(const QPoint &point)
- \internal
-
- Sets the position associated with the hover event to the given \a point in
- screen coordinates.
-*/
-void QGraphicsSceneHoverEvent::setScreenPos(const QPoint &pos)
-{
- Q_D(QGraphicsSceneHoverEvent);
- d->screenPos = pos;
-}
-
-/*!
- \since 4.4
-
- Returns the last recorded mouse cursor position in item coordinates.
-
- \sa lastScenePos(), lastScreenPos(), pos()
-*/
-QPointF QGraphicsSceneHoverEvent::lastPos() const
-{
- Q_D(const QGraphicsSceneHoverEvent);
- return d->lastPos;
-}
-
-/*!
- \internal
-*/
-void QGraphicsSceneHoverEvent::setLastPos(const QPointF &pos)
-{
- Q_D(QGraphicsSceneHoverEvent);
- d->lastPos = pos;
-}
-
-/*!
- \since 4.4
-
- Returns the last recorded, the scene coordinates of the previous mouse or
- hover event received by the view, that created the event mouse cursor
- position in scene coordinates.
-
- \sa lastPos(), lastScreenPos(), scenePos()
-*/
-QPointF QGraphicsSceneHoverEvent::lastScenePos() const
-{
- Q_D(const QGraphicsSceneHoverEvent);
- return d->lastScenePos;
-}
-
-/*!
- \internal
-*/
-void QGraphicsSceneHoverEvent::setLastScenePos(const QPointF &pos)
-{
- Q_D(QGraphicsSceneHoverEvent);
- d->lastScenePos = pos;
-}
-
-/*!
- \since 4.4
-
- Returns the last recorded mouse cursor position in screen coordinates. The
- last recorded position is the position of the previous mouse or hover
- event received by the view that created the event.
-
- \sa lastPos(), lastScenePos(), screenPos()
-*/
-QPoint QGraphicsSceneHoverEvent::lastScreenPos() const
-{
- Q_D(const QGraphicsSceneHoverEvent);
- return d->lastScreenPos;
-}
-
-/*!
- \internal
-*/
-void QGraphicsSceneHoverEvent::setLastScreenPos(const QPoint &pos)
-{
- Q_D(QGraphicsSceneHoverEvent);
- d->lastScreenPos = pos;
-}
-
-/*!
- \since 4.4
-
- Returns the keyboard modifiers at the moment the hover event was sent.
-*/
-Qt::KeyboardModifiers QGraphicsSceneHoverEvent::modifiers() const
-{
- Q_D(const QGraphicsSceneHoverEvent);
- return d->modifiers;
-}
-
-/*!
- \fn void QGraphicsSceneHoverEvent::setModifiers(Qt::KeyboardModifiers modifiers)
- \internal
-
- Sets the modifiers for the current hover event to \a modifiers.
-*/
-void QGraphicsSceneHoverEvent::setModifiers(Qt::KeyboardModifiers modifiers)
-{
- Q_D(QGraphicsSceneHoverEvent);
- d->modifiers = modifiers;
-}
-
-class QGraphicsSceneHelpEventPrivate : public QGraphicsSceneEventPrivate
-{
-public:
- QPointF scenePos;
- QPoint screenPos;
-};
-
-/*!
- \internal
-
- Constructs a graphics scene help event of the specified \a type.
-*/
-QGraphicsSceneHelpEvent::QGraphicsSceneHelpEvent(Type type)
- : QGraphicsSceneEvent(*new QGraphicsSceneHelpEventPrivate, type)
-{
-}
-
-/*!
- Destroys the event.
-*/
-QGraphicsSceneHelpEvent::~QGraphicsSceneHelpEvent()
-{
-}
-
-/*!
- Returns the position of the mouse cursor in scene coordinates at the
- moment the help event was sent.
-
- \sa screenPos()
-*/
-QPointF QGraphicsSceneHelpEvent::scenePos() const
-{
- Q_D(const QGraphicsSceneHelpEvent);
- return d->scenePos;
-}
-
-/*!
- \fn void QGraphicsSceneHelpEvent::setScenePos(const QPointF &point)
- \internal
-
- Sets the position associated with the context menu to the given \a point
- in scene coordinates.
-*/
-void QGraphicsSceneHelpEvent::setScenePos(const QPointF &pos)
-{
- Q_D(QGraphicsSceneHelpEvent);
- d->scenePos = pos;
-}
-
-/*!
- Returns the position of the mouse cursor in screen coordinates at the
- moment the help event was sent.
-
- \sa scenePos()
-*/
-QPoint QGraphicsSceneHelpEvent::screenPos() const
-{
- Q_D(const QGraphicsSceneHelpEvent);
- return d->screenPos;
-}
-
-/*!
- \fn void QGraphicsSceneHelpEvent::setScreenPos(const QPoint &point)
- \internal
-
- Sets the position associated with the context menu to the given \a point
- in screen coordinates.
-*/
-void QGraphicsSceneHelpEvent::setScreenPos(const QPoint &pos)
-{
- Q_D(QGraphicsSceneHelpEvent);
- d->screenPos = pos;
-}
-
-class QGraphicsSceneDragDropEventPrivate : public QGraphicsSceneEventPrivate
-{
- Q_DECLARE_PUBLIC(QGraphicsSceneDragDropEvent)
-public:
- inline QGraphicsSceneDragDropEventPrivate()
- : source(0), mimeData(0)
- { }
-
- QPointF pos;
- QPointF scenePos;
- QPoint screenPos;
- Qt::MouseButtons buttons;
- Qt::KeyboardModifiers modifiers;
- Qt::DropActions possibleActions;
- Qt::DropAction proposedAction;
- Qt::DropAction dropAction;
- QWidget *source;
- const QMimeData *mimeData;
-};
-
-/*!
- \internal
-
- Constructs a new QGraphicsSceneDragDropEvent of the
- specified \a type. The type can be either
- QEvent::GraphicsSceneDragEnter, QEvent::GraphicsSceneDragLeave,
- QEvent::GraphicsSceneDragMove, or QEvent::GraphicsSceneDrop.
-*/
-QGraphicsSceneDragDropEvent::QGraphicsSceneDragDropEvent(Type type)
- : QGraphicsSceneEvent(*new QGraphicsSceneDragDropEventPrivate, type)
-{
-}
-
-/*!
- Destroys the object.
-*/
-QGraphicsSceneDragDropEvent::~QGraphicsSceneDragDropEvent()
-{
-}
-
-/*!
- Returns the mouse position of the event relative to the
- view that sent the event.
-
- \sa QGraphicsView, screenPos(), scenePos()
-*/
-QPointF QGraphicsSceneDragDropEvent::pos() const
-{
- Q_D(const QGraphicsSceneDragDropEvent);
- return d->pos;
-}
-
-/*!
- \internal
- Sets the position of the mouse to \a pos; this should be
- relative to the widget that generated the event, which normally
- is a QGraphicsView.
-
- \sa pos(), setScenePos(), setScreenPos()
-*/
-
-void QGraphicsSceneDragDropEvent::setPos(const QPointF &pos)
-{
- Q_D(QGraphicsSceneDragDropEvent);
- d->pos = pos;
-}
-
-/*!
- Returns the position of the mouse in scene coordinates.
-
- \sa pos(), screenPos()
-*/
-QPointF QGraphicsSceneDragDropEvent::scenePos() const
-{
- Q_D(const QGraphicsSceneDragDropEvent);
- return d->scenePos;
-}
-
-/*!
- \internal
- Sets the scene position of the mouse to \a pos.
-
- \sa scenePos(), setScreenPos(), setPos()
-*/
-void QGraphicsSceneDragDropEvent::setScenePos(const QPointF &pos)
-{
- Q_D(QGraphicsSceneDragDropEvent);
- d->scenePos = pos;
-}
-
-/*!
- Returns the position of the mouse relative to the screen.
-
- \sa pos(), scenePos()
-*/
-QPoint QGraphicsSceneDragDropEvent::screenPos() const
-{
- Q_D(const QGraphicsSceneDragDropEvent);
- return d->screenPos;
-}
-
-/*!
- \internal
- Sets the mouse position relative to the screen to \a pos.
-
- \sa screenPos(), setScenePos(), setPos()
-*/
-void QGraphicsSceneDragDropEvent::setScreenPos(const QPoint &pos)
-{
- Q_D(QGraphicsSceneDragDropEvent);
- d->screenPos = pos;
-}
-
-/*!
- Returns a Qt::MouseButtons value indicating which buttons
- were pressed on the mouse when this mouse event was
- generated.
-
- \sa Qt::MouseButtons
-*/
-Qt::MouseButtons QGraphicsSceneDragDropEvent::buttons() const
-{
- Q_D(const QGraphicsSceneDragDropEvent);
- return d->buttons;
-}
-
-/*!
- \internal
- Sets the mouse buttons that were pressed when the event was
- created to \a buttons.
-
- \sa Qt::MouseButtons, buttons()
-*/
-void QGraphicsSceneDragDropEvent::setButtons(Qt::MouseButtons buttons)
-{
- Q_D(QGraphicsSceneDragDropEvent);
- d->buttons = buttons;
-}
-
-/*!
- Returns the keyboard modifiers that were pressed when the drag
- and drop event was created.
-
- \sa Qt::KeyboardModifiers
-*/
-Qt::KeyboardModifiers QGraphicsSceneDragDropEvent::modifiers() const
-{
- Q_D(const QGraphicsSceneDragDropEvent);
- return d->modifiers;
-}
-
-/*!
- \internal
- Sets the keyboard modifiers that were pressed when the event
- was created to \a modifiers.
-
- \sa Qt::KeyboardModifiers, modifiers()
-*/
-
-void QGraphicsSceneDragDropEvent::setModifiers(Qt::KeyboardModifiers modifiers)
-{
- Q_D(QGraphicsSceneDragDropEvent);
- d->modifiers = modifiers;
-}
-
-/*!
- Returns the possible drop actions that the drag and
- drop can result in.
-
- \sa Qt::DropActions
-*/
-
-Qt::DropActions QGraphicsSceneDragDropEvent::possibleActions() const
-{
- Q_D(const QGraphicsSceneDragDropEvent);
- return d->possibleActions;
-}
-
-/*!
- \internal
- Sets the possible drop actions that the drag can
- result in to \a actions.
-
- \sa Qt::DropActions, possibleActions()
-*/
-void QGraphicsSceneDragDropEvent::setPossibleActions(Qt::DropActions actions)
-{
- Q_D(QGraphicsSceneDragDropEvent);
- d->possibleActions = actions;
-}
-
-/*!
- Returns the drop action that is proposed, i.e., preferred.
- The action must be one of the possible actions as defined by
- \c possibleActions().
-
- \sa Qt::DropAction, possibleActions()
-*/
-
-Qt::DropAction QGraphicsSceneDragDropEvent::proposedAction() const
-{
- Q_D(const QGraphicsSceneDragDropEvent);
- return d->proposedAction;
-}
-
-/*!
- \internal
- Sets the proposed action to \a action. The proposed action
- is a Qt::DropAction that is one of the possible actions as
- given by \c possibleActions().
-
- \sa proposedAction(), Qt::DropAction, possibleActions()
-*/
-
-void QGraphicsSceneDragDropEvent::setProposedAction(Qt::DropAction action)
-{
- Q_D(QGraphicsSceneDragDropEvent);
- d->proposedAction = action;
-}
-
-/*!
- Sets the proposed action as accepted, i.e, the drop action
- is set to the proposed action. This is equal to:
-
- \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicssceneevent.cpp 0
-
- When using this function, one should not call \c accept().
-
- \sa dropAction(), setDropAction(), proposedAction()
-*/
-
-void QGraphicsSceneDragDropEvent::acceptProposedAction()
-{
- Q_D(QGraphicsSceneDragDropEvent);
- d->dropAction = d->proposedAction;
-}
-
-/*!
- Returns the action that was performed in this drag and drop.
- This should be set by the receiver of the drop and is
- returned by QDrag::exec().
-
- \sa setDropAction(), acceptProposedAction()
-*/
-
-Qt::DropAction QGraphicsSceneDragDropEvent::dropAction() const
-{
- Q_D(const QGraphicsSceneDragDropEvent);
- return d->dropAction;
-}
-
-/*!
- This function lets the receiver of the drop set the drop
- action that was performed to \a action, which should be one
- of the
- \l{QGraphicsSceneDragDropEvent::possibleActions()}{possible
- actions}. Call \c accept() in stead of \c
- acceptProposedAction() if you use this function.
-
- \sa dropAction(), accept(), possibleActions()
-*/
-void QGraphicsSceneDragDropEvent::setDropAction(Qt::DropAction action)
-{
- Q_D(QGraphicsSceneDragDropEvent);
- d->dropAction = action;
-}
-
-/*!
- This function returns the QGraphicsView that created the
- QGraphicsSceneDragDropEvent.
-*/
-QWidget *QGraphicsSceneDragDropEvent::source() const
-{
- Q_D(const QGraphicsSceneDragDropEvent);
- return d->source;
-}
-
-/*!
- \internal
- This function set the source widget, i.e., the widget that
- created the drop event, to \a source.
-*/
-void QGraphicsSceneDragDropEvent::setSource(QWidget *source)
-{
- Q_D(QGraphicsSceneDragDropEvent);
- d->source = source;
-}
-
-/*!
- This function returns the MIME data of the event.
-*/
-const QMimeData *QGraphicsSceneDragDropEvent::mimeData() const
-{
- Q_D(const QGraphicsSceneDragDropEvent);
- return d->mimeData;
-}
-
-/*!
- \internal
- This function sets the MIME data for the event.
-*/
-void QGraphicsSceneDragDropEvent::setMimeData(const QMimeData *data)
-{
- Q_D(QGraphicsSceneDragDropEvent);
- d->mimeData = data;
-}
-
-class QGraphicsSceneResizeEventPrivate : public QGraphicsSceneEventPrivate
-{
- Q_DECLARE_PUBLIC(QGraphicsSceneResizeEvent)
-public:
- inline QGraphicsSceneResizeEventPrivate()
- { }
-
- QSizeF oldSize;
- QSizeF newSize;
-};
-
-/*!
- Constructs a QGraphicsSceneResizeEvent.
-*/
-QGraphicsSceneResizeEvent::QGraphicsSceneResizeEvent()
- : QGraphicsSceneEvent(*new QGraphicsSceneResizeEventPrivate, QEvent::GraphicsSceneResize)
-{
-}
-
-/*!
- Destroys the QGraphicsSceneResizeEvent.
-*/
-QGraphicsSceneResizeEvent::~QGraphicsSceneResizeEvent()
-{
-}
-
-/*!
- Returns the old size (i.e., the size immediately before the widget was
- resized).
-
- \sa newSize(), QGraphicsWidget::resize()
-*/
-QSizeF QGraphicsSceneResizeEvent::oldSize() const
-{
- Q_D(const QGraphicsSceneResizeEvent);
- return d->oldSize;
-}
-
-/*!
- \internal
-*/
-void QGraphicsSceneResizeEvent::setOldSize(const QSizeF &size)
-{
- Q_D(QGraphicsSceneResizeEvent);
- d->oldSize = size;
-}
-
-/*!
- Returns the new size (i.e., the current size).
-
- \sa oldSize(), QGraphicsWidget::resize()
-*/
-QSizeF QGraphicsSceneResizeEvent::newSize() const
-{
- Q_D(const QGraphicsSceneResizeEvent);
- return d->newSize;
-}
-
-/*!
- \internal
-*/
-void QGraphicsSceneResizeEvent::setNewSize(const QSizeF &size)
-{
- Q_D(QGraphicsSceneResizeEvent);
- d->newSize = size;
-}
-
-class QGraphicsSceneMoveEventPrivate : public QGraphicsSceneEventPrivate
-{
- Q_DECLARE_PUBLIC(QGraphicsSceneMoveEvent)
-public:
- inline QGraphicsSceneMoveEventPrivate()
- { }
-
- QPointF oldPos;
- QPointF newPos;
-};
-
-/*!
- Constructs a QGraphicsSceneMoveEvent.
-*/
-QGraphicsSceneMoveEvent::QGraphicsSceneMoveEvent()
- : QGraphicsSceneEvent(*new QGraphicsSceneMoveEventPrivate, QEvent::GraphicsSceneMove)
-{
-}
-
-/*!
- Destroys the QGraphicsSceneMoveEvent.
-*/
-QGraphicsSceneMoveEvent::~QGraphicsSceneMoveEvent()
-{
-}
-
-/*!
- Returns the old position (i.e., the position immediately before the widget
- was moved).
-
- \sa newPos(), QGraphicsItem::setPos()
-*/
-QPointF QGraphicsSceneMoveEvent::oldPos() const
-{
- Q_D(const QGraphicsSceneMoveEvent);
- return d->oldPos;
-}
-
-/*!
- \internal
-*/
-void QGraphicsSceneMoveEvent::setOldPos(const QPointF &pos)
-{
- Q_D(QGraphicsSceneMoveEvent);
- d->oldPos = pos;
-}
-
-/*!
- Returns the new position (i.e., the current position).
-
- \sa oldPos(), QGraphicsItem::setPos()
-*/
-QPointF QGraphicsSceneMoveEvent::newPos() const
-{
- Q_D(const QGraphicsSceneMoveEvent);
- return d->newPos;
-}
-
-/*!
- \internal
-*/
-void QGraphicsSceneMoveEvent::setNewPos(const QPointF &pos)
-{
- Q_D(QGraphicsSceneMoveEvent);
- d->newPos = pos;
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_GRAPHICSVIEW
diff --git a/src/gui/graphicsview/qgraphicssceneevent.h b/src/gui/graphicsview/qgraphicssceneevent.h
deleted file mode 100644
index cbc211c542..0000000000
--- a/src/gui/graphicsview/qgraphicssceneevent.h
+++ /dev/null
@@ -1,326 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGRAPHICSSCENEEVENT_H
-#define QGRAPHICSSCENEEVENT_H
-
-#include <QtCore/qcoreevent.h>
-#include <QtCore/qpoint.h>
-#include <QtCore/qscopedpointer.h>
-#include <QtCore/qrect.h>
-#include <QtGui/qpolygon.h>
-#include <QtCore/qset.h>
-#include <QtCore/qhash.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW
-
-class QMimeData;
-class QPointF;
-class QSizeF;
-class QWidget;
-
-class QGraphicsSceneEventPrivate;
-class Q_GUI_EXPORT QGraphicsSceneEvent : public QEvent
-{
-public:
- QGraphicsSceneEvent(Type type);
- ~QGraphicsSceneEvent();
-
- QWidget *widget() const;
- void setWidget(QWidget *widget);
-
-protected:
- QGraphicsSceneEvent(QGraphicsSceneEventPrivate &dd, Type type = None);
- QScopedPointer<QGraphicsSceneEventPrivate> d_ptr;
- Q_DECLARE_PRIVATE(QGraphicsSceneEvent)
-private:
- Q_DISABLE_COPY(QGraphicsSceneEvent)
-};
-
-class QGraphicsSceneMouseEventPrivate;
-class Q_GUI_EXPORT QGraphicsSceneMouseEvent : public QGraphicsSceneEvent
-{
-public:
- QGraphicsSceneMouseEvent(Type type = None);
- ~QGraphicsSceneMouseEvent();
-
- QPointF pos() const;
- void setPos(const QPointF &pos);
-
- QPointF scenePos() const;
- void setScenePos(const QPointF &pos);
-
- QPoint screenPos() const;
- void setScreenPos(const QPoint &pos);
-
- QPointF buttonDownPos(Qt::MouseButton button) const;
- void setButtonDownPos(Qt::MouseButton button, const QPointF &pos);
-
- QPointF buttonDownScenePos(Qt::MouseButton button) const;
- void setButtonDownScenePos(Qt::MouseButton button, const QPointF &pos);
-
- QPoint buttonDownScreenPos(Qt::MouseButton button) const;
- void setButtonDownScreenPos(Qt::MouseButton button, const QPoint &pos);
-
- QPointF lastPos() const;
- void setLastPos(const QPointF &pos);
-
- QPointF lastScenePos() const;
- void setLastScenePos(const QPointF &pos);
-
- QPoint lastScreenPos() const;
- void setLastScreenPos(const QPoint &pos);
-
- Qt::MouseButtons buttons() const;
- void setButtons(Qt::MouseButtons buttons);
-
- Qt::MouseButton button() const;
- void setButton(Qt::MouseButton button);
-
- Qt::KeyboardModifiers modifiers() const;
- void setModifiers(Qt::KeyboardModifiers modifiers);
-
-private:
- Q_DECLARE_PRIVATE(QGraphicsSceneMouseEvent)
- Q_DISABLE_COPY(QGraphicsSceneMouseEvent)
-};
-
-class QGraphicsSceneWheelEventPrivate;
-class Q_GUI_EXPORT QGraphicsSceneWheelEvent : public QGraphicsSceneEvent
-{
-public:
- QGraphicsSceneWheelEvent(Type type = None);
- ~QGraphicsSceneWheelEvent();
-
- QPointF pos() const;
- void setPos(const QPointF &pos);
-
- QPointF scenePos() const;
- void setScenePos(const QPointF &pos);
-
- QPoint screenPos() const;
- void setScreenPos(const QPoint &pos);
-
- Qt::MouseButtons buttons() const;
- void setButtons(Qt::MouseButtons buttons);
-
- Qt::KeyboardModifiers modifiers() const;
- void setModifiers(Qt::KeyboardModifiers modifiers);
-
- int delta() const;
- void setDelta(int delta);
-
- Qt::Orientation orientation() const;
- void setOrientation(Qt::Orientation orientation);
-
-private:
- Q_DECLARE_PRIVATE(QGraphicsSceneWheelEvent)
- Q_DISABLE_COPY(QGraphicsSceneWheelEvent)
-};
-
-class QGraphicsSceneContextMenuEventPrivate;
-class Q_GUI_EXPORT QGraphicsSceneContextMenuEvent : public QGraphicsSceneEvent
-{
-public:
- enum Reason { Mouse, Keyboard, Other };
-
- QGraphicsSceneContextMenuEvent(Type type = None);
- ~QGraphicsSceneContextMenuEvent();
-
- QPointF pos() const;
- void setPos(const QPointF &pos);
-
- QPointF scenePos() const;
- void setScenePos(const QPointF &pos);
-
- QPoint screenPos() const;
- void setScreenPos(const QPoint &pos);
-
- Qt::KeyboardModifiers modifiers() const;
- void setModifiers(Qt::KeyboardModifiers modifiers);
-
- Reason reason() const;
- void setReason(Reason reason);
-
-private:
- Q_DECLARE_PRIVATE(QGraphicsSceneContextMenuEvent)
- Q_DISABLE_COPY(QGraphicsSceneContextMenuEvent)
-};
-
-class QGraphicsSceneHoverEventPrivate;
-class Q_GUI_EXPORT QGraphicsSceneHoverEvent : public QGraphicsSceneEvent
-{
-public:
- QGraphicsSceneHoverEvent(Type type = None);
- ~QGraphicsSceneHoverEvent();
-
- QPointF pos() const;
- void setPos(const QPointF &pos);
-
- QPointF scenePos() const;
- void setScenePos(const QPointF &pos);
-
- QPoint screenPos() const;
- void setScreenPos(const QPoint &pos);
-
- QPointF lastPos() const;
- void setLastPos(const QPointF &pos);
-
- QPointF lastScenePos() const;
- void setLastScenePos(const QPointF &pos);
-
- QPoint lastScreenPos() const;
- void setLastScreenPos(const QPoint &pos);
-
- Qt::KeyboardModifiers modifiers() const;
- void setModifiers(Qt::KeyboardModifiers modifiers);
-
-private:
- Q_DECLARE_PRIVATE(QGraphicsSceneHoverEvent)
- Q_DISABLE_COPY(QGraphicsSceneHoverEvent)
-};
-
-class QGraphicsSceneHelpEventPrivate;
-class Q_GUI_EXPORT QGraphicsSceneHelpEvent : public QGraphicsSceneEvent
-{
-public:
- QGraphicsSceneHelpEvent(Type type = None);
- ~QGraphicsSceneHelpEvent();
-
- QPointF scenePos() const;
- void setScenePos(const QPointF &pos);
-
- QPoint screenPos() const;
- void setScreenPos(const QPoint &pos);
-
-private:
- Q_DECLARE_PRIVATE(QGraphicsSceneHelpEvent)
- Q_DISABLE_COPY(QGraphicsSceneHelpEvent)
-};
-
-class QGraphicsSceneDragDropEventPrivate;
-class Q_GUI_EXPORT QGraphicsSceneDragDropEvent : public QGraphicsSceneEvent
-{
-public:
- QGraphicsSceneDragDropEvent(Type type = None);
- ~QGraphicsSceneDragDropEvent();
-
- QPointF pos() const;
- void setPos(const QPointF &pos);
-
- QPointF scenePos() const;
- void setScenePos(const QPointF &pos);
-
- QPoint screenPos() const;
- void setScreenPos(const QPoint &pos);
-
- Qt::MouseButtons buttons() const;
- void setButtons(Qt::MouseButtons buttons);
-
- Qt::KeyboardModifiers modifiers() const;
- void setModifiers(Qt::KeyboardModifiers modifiers);
-
- Qt::DropActions possibleActions() const;
- void setPossibleActions(Qt::DropActions actions);
-
- Qt::DropAction proposedAction() const;
- void setProposedAction(Qt::DropAction action);
- void acceptProposedAction();
-
- Qt::DropAction dropAction() const;
- void setDropAction(Qt::DropAction action);
-
- QWidget *source() const;
- void setSource(QWidget *source);
-
- const QMimeData *mimeData() const;
- void setMimeData(const QMimeData *data);
-
-private:
- Q_DECLARE_PRIVATE(QGraphicsSceneDragDropEvent)
- Q_DISABLE_COPY(QGraphicsSceneDragDropEvent)
-};
-
-class QGraphicsSceneResizeEventPrivate;
-class Q_GUI_EXPORT QGraphicsSceneResizeEvent : public QGraphicsSceneEvent
-{
- Q_DECLARE_PRIVATE(QGraphicsSceneResizeEvent)
- Q_DISABLE_COPY(QGraphicsSceneResizeEvent)
-public:
- QGraphicsSceneResizeEvent();
- ~QGraphicsSceneResizeEvent();
-
- QSizeF oldSize() const;
- void setOldSize(const QSizeF &size);
-
- QSizeF newSize() const;
- void setNewSize(const QSizeF &size);
-};
-
-class QGraphicsSceneMoveEventPrivate;
-class Q_GUI_EXPORT QGraphicsSceneMoveEvent : public QGraphicsSceneEvent
-{
- Q_DECLARE_PRIVATE(QGraphicsSceneMoveEvent)
- Q_DISABLE_COPY(QGraphicsSceneMoveEvent)
-public:
- QGraphicsSceneMoveEvent();
- ~QGraphicsSceneMoveEvent();
-
- QPointF oldPos() const;
- void setOldPos(const QPointF &pos);
-
- QPointF newPos() const;
- void setNewPos(const QPointF &pos);
-};
-
-#endif // QT_NO_GRAPHICSVIEW
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif
diff --git a/src/gui/graphicsview/qgraphicsscenelinearindex_p.h b/src/gui/graphicsview/qgraphicsscenelinearindex_p.h
deleted file mode 100644
index 07dd6a22b6..0000000000
--- a/src/gui/graphicsview/qgraphicsscenelinearindex_p.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGRAPHICSSCENELINEARINDEX_H
-#define QGRAPHICSSCENELINEARINDEX_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/qglobal.h>
-
-#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW
-
-#include <QtCore/qrect.h>
-#include <QtCore/qlist.h>
-#include <QtGui/qgraphicsitem.h>
-#include <private/qgraphicssceneindex_p.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class Q_AUTOTEST_EXPORT QGraphicsSceneLinearIndex : public QGraphicsSceneIndex
-{
- Q_OBJECT
-
-public:
- QGraphicsSceneLinearIndex(QGraphicsScene *scene = 0) : QGraphicsSceneIndex(scene)
- { }
-
- QList<QGraphicsItem *> items(Qt::SortOrder order = Qt::DescendingOrder) const
- { Q_UNUSED(order); return m_items; }
-
- virtual QList<QGraphicsItem *> estimateItems(const QRectF &rect, Qt::SortOrder order) const
- {
- Q_UNUSED(rect);
- Q_UNUSED(order);
- return m_items;
- }
-
-protected :
- virtual void clear()
- { m_items.clear(); }
-
- virtual void addItem(QGraphicsItem *item)
- { m_items << item; }
-
- virtual void removeItem(QGraphicsItem *item)
- { m_items.removeOne(item); }
-
-private:
- QList<QGraphicsItem*> m_items;
-};
-
-#endif // QT_NO_GRAPHICSVIEW
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QGRAPHICSSCENELINEARINDEX_H
diff --git a/src/gui/graphicsview/qgraphicstransform.h b/src/gui/graphicsview/qgraphicstransform.h
deleted file mode 100644
index a686edebc7..0000000000
--- a/src/gui/graphicsview/qgraphicstransform.h
+++ /dev/null
@@ -1,159 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGRAPHICSTRANSFORM_H
-#define QGRAPHICSTRANSFORM_H
-
-#include <QtCore/QObject>
-#include <QtGui/QVector3D>
-#include <QtGui/QTransform>
-#include <QtGui/QMatrix4x4>
-
-#ifndef QT_NO_GRAPHICSVIEW
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QGraphicsItem;
-class QGraphicsTransformPrivate;
-
-class Q_GUI_EXPORT QGraphicsTransform : public QObject
-{
- Q_OBJECT
-public:
- QGraphicsTransform(QObject *parent = 0);
- ~QGraphicsTransform();
-
- virtual void applyTo(QMatrix4x4 *matrix) const = 0;
-
-protected Q_SLOTS:
- void update();
-
-protected:
- QGraphicsTransform(QGraphicsTransformPrivate &p, QObject *parent);
-
-private:
- friend class QGraphicsItem;
- friend class QGraphicsItemPrivate;
- Q_DECLARE_PRIVATE(QGraphicsTransform)
-};
-
-class QGraphicsScalePrivate;
-
-class Q_GUI_EXPORT QGraphicsScale : public QGraphicsTransform
-{
- Q_OBJECT
-
- Q_PROPERTY(QVector3D origin READ origin WRITE setOrigin NOTIFY originChanged)
- Q_PROPERTY(qreal xScale READ xScale WRITE setXScale NOTIFY xScaleChanged)
- Q_PROPERTY(qreal yScale READ yScale WRITE setYScale NOTIFY yScaleChanged)
- Q_PROPERTY(qreal zScale READ zScale WRITE setZScale NOTIFY zScaleChanged)
-public:
- QGraphicsScale(QObject *parent = 0);
- ~QGraphicsScale();
-
- QVector3D origin() const;
- void setOrigin(const QVector3D &point);
-
- qreal xScale() const;
- void setXScale(qreal);
-
- qreal yScale() const;
- void setYScale(qreal);
-
- qreal zScale() const;
- void setZScale(qreal);
-
- void applyTo(QMatrix4x4 *matrix) const;
-
-Q_SIGNALS:
- void originChanged();
- void xScaleChanged();
- void yScaleChanged();
- void zScaleChanged();
- void scaleChanged();
-
-private:
- Q_DECLARE_PRIVATE(QGraphicsScale)
-};
-
-class QGraphicsRotationPrivate;
-
-class Q_GUI_EXPORT QGraphicsRotation : public QGraphicsTransform
-{
- Q_OBJECT
-
- Q_PROPERTY(QVector3D origin READ origin WRITE setOrigin NOTIFY originChanged)
- Q_PROPERTY(qreal angle READ angle WRITE setAngle NOTIFY angleChanged)
- Q_PROPERTY(QVector3D axis READ axis WRITE setAxis NOTIFY axisChanged)
-public:
- QGraphicsRotation(QObject *parent = 0);
- ~QGraphicsRotation();
-
- QVector3D origin() const;
- void setOrigin(const QVector3D &point);
-
- qreal angle() const;
- void setAngle(qreal);
-
- QVector3D axis() const;
- void setAxis(const QVector3D &axis);
- void setAxis(Qt::Axis axis);
-
- void applyTo(QMatrix4x4 *matrix) const;
-
-Q_SIGNALS:
- void originChanged();
- void angleChanged();
- void axisChanged();
-
-private:
- Q_DECLARE_PRIVATE(QGraphicsRotation)
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-#endif //QT_NO_GRAPHICSVIEW
-
-#endif // QFXTRANSFORM_H
diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp
deleted file mode 100644
index 548f79fa17..0000000000
--- a/src/gui/graphicsview/qgraphicsview.cpp
+++ /dev/null
@@ -1,3880 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-static const int QGRAPHICSVIEW_REGION_RECT_THRESHOLD = 50;
-
-static const int QGRAPHICSVIEW_PREALLOC_STYLE_OPTIONS = 503; // largest prime < 2^9
-
-/*!
- \class QGraphicsView
- \brief The QGraphicsView class provides a widget for displaying the
- contents of a QGraphicsScene.
- \since 4.2
- \ingroup graphicsview-api
-
-
- QGraphicsView visualizes the contents of a QGraphicsScene in a scrollable
- viewport. To create a scene with geometrical items, see QGraphicsScene's
- documentation. QGraphicsView is part of the \l{Graphics View Framework}.
-
- To visualize a scene, you start by constructing a QGraphicsView object,
- passing the address of the scene you want to visualize to QGraphicsView's
- constructor. Alternatively, you can call setScene() to set the scene at a
- later point. After you call show(), the view will by default scroll to the
- center of the scene and display any items that are visible at this
- point. For example:
-
- \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsview.cpp 0
-
- You can explicitly scroll to any position on the scene by using the
- scroll bars, or by calling centerOn(). By passing a point to centerOn(),
- QGraphicsView will scroll its viewport to ensure that the point is
- centered in the view. An overload is provided for scrolling to a
- QGraphicsItem, in which case QGraphicsView will see to that the center of
- the item is centered in the view. If all you want is to ensure that a
- certain area is visible, (but not necessarily centered,) you can call
- ensureVisible() instead.
-
- QGraphicsView can be used to visualize a whole scene, or only parts of it.
- The visualized area is by default detected automatically when the view is
- displayed for the first time (by calling
- QGraphicsScene::itemsBoundingRect()). To set the visualized area rectangle
- yourself, you can call setSceneRect(). This will adjust the scroll bars'
- ranges appropriately. Note that although the scene supports a virtually
- unlimited size, the range of the scroll bars will never exceed the range of
- an integer (INT_MIN, INT_MAX).
-
- QGraphicsView visualizes the scene by calling render(). By default, the
- items are drawn onto the viewport by using a regular QPainter, and using
- default render hints. To change the default render hints that
- QGraphicsView passes to QPainter when painting items, you can call
- setRenderHints().
-
- By default, QGraphicsView provides a regular QWidget for the viewport
- widget. You can access this widget by calling viewport(), or you can
- replace it by calling setViewport(). To render using OpenGL, simply call
- setViewport(new QGLWidget). QGraphicsView takes ownership of the viewport
- widget.
-
- QGraphicsView supports affine transformations, using QTransform. You can
- either pass a matrix to setTransform(), or you can call one of the
- convenience functions rotate(), scale(), translate() or shear(). The most
- two common transformations are scaling, which is used to implement
- zooming, and rotation. QGraphicsView keeps the center of the view fixed
- during a transformation. Because of the scene alignment (setAligment()),
- translating the view will have no visual impact.
-
- You can interact with the items on the scene by using the mouse and
- keyboard. QGraphicsView translates the mouse and key events into \e scene
- events, (events that inherit QGraphicsSceneEvent,), and forward them to
- the visualized scene. In the end, it's the individual item that handles
- the events and reacts to them. For example, if you click on a selectable
- item, the item will typically let the scene know that it has been
- selected, and it will also redraw itself to display a selection
- rectangle. Similiary, if you click and drag the mouse to move a movable
- item, it's the item that handles the mouse moves and moves itself. Item
- interaction is enabled by default, and you can toggle it by calling
- setInteractive().
-
- You can also provide your own custom scene interaction, by creating a
- subclass of QGraphicsView, and reimplementing the mouse and key event
- handlers. To simplify how you programmatically interact with items in the
- view, QGraphicsView provides the mapping functions mapToScene() and
- mapFromScene(), and the item accessors items() and itemAt(). These
- functions allow you to map points, rectangles, polygons and paths between
- view coordinates and scene coordinates, and to find items on the scene
- using view coordinates.
-
- \img graphicsview-view.png
-
- \sa QGraphicsScene, QGraphicsItem, QGraphicsSceneEvent
-*/
-
-/*!
- \enum QGraphicsView::ViewportAnchor
-
- This enums describe the possible anchors that QGraphicsView can
- use when the user resizes the view or when the view is
- transformed.
-
- \value NoAnchor No anchor, i.e. the view leaves the scene's
- position unchanged.
- \value AnchorViewCenter The scene point at the center of the view
- is used as the anchor.
- \value AnchorUnderMouse The point under the mouse is used as the anchor.
-
- \sa resizeAnchor, transformationAnchor
-*/
-
-/*!
- \enum QGraphicsView::ViewportUpdateMode
-
- \since 4.3
-
- This enum describes how QGraphicsView updates its viewport when the scene
- contents change or are exposed.
-
- \value FullViewportUpdate When any visible part of the scene changes or is
- reexposed, QGraphicsView will update the entire viewport. This approach is
- fastest when QGraphicsView spends more time figuring out what to draw than
- it would spend drawing (e.g., when very many small items are repeatedly
- updated). This is the preferred update mode for viewports that do not
- support partial updates, such as QGLWidget, and for viewports that need to
- disable scroll optimization.
-
- \value MinimalViewportUpdate QGraphicsView will determine the minimal
- viewport region that requires a redraw, minimizing the time spent drawing
- by avoiding a redraw of areas that have not changed. This is
- QGraphicsView's default mode. Although this approach provides the best
- performance in general, if there are many small visible changes on the
- scene, QGraphicsView might end up spending more time finding the minimal
- approach than it will spend drawing.
-
- \value SmartViewportUpdate QGraphicsView will attempt to find an optimal
- update mode by analyzing the areas that require a redraw.
-
- \value BoundingRectViewportUpdate The bounding rectangle of all changes in
- the viewport will be redrawn. This mode has the advantage that
- QGraphicsView searches only one region for changes, minimizing time spent
- determining what needs redrawing. The disadvantage is that areas that have
- not changed also need to be redrawn.
-
- \value NoViewportUpdate QGraphicsView will never update its viewport when
- the scene changes; the user is expected to control all updates. This mode
- disables all (potentially slow) item visibility testing in QGraphicsView,
- and is suitable for scenes that either require a fixed frame rate, or where
- the viewport is otherwise updated externally.
-
- \sa viewportUpdateMode
-*/
-
-/*!
- \enum QGraphicsView::OptimizationFlag
-
- \since 4.3
-
- This enum describes flags that you can enable to improve rendering
- performance in QGraphicsView. By default, none of these flags are set.
- Note that setting a flag usually imposes a side effect, and this effect
- can vary between paint devices and platforms.
-
- \value DontClipPainter This value is obsolete and has no effect.
-
- \value DontSavePainterState When rendering, QGraphicsView protects the
- painter state (see QPainter::save()) when rendering the background or
- foreground, and when rendering each item. This allows you to leave the
- painter in an altered state (i.e., you can call QPainter::setPen() or
- QPainter::setBrush() without restoring the state after painting). However,
- if the items consistently do restore the state, you should enable this
- flag to prevent QGraphicsView from doing the same.
-
- \value DontAdjustForAntialiasing Disables QGraphicsView's antialiasing
- auto-adjustment of exposed areas. Items that render antialiased lines on
- the boundaries of their QGraphicsItem::boundingRect() can end up rendering
- parts of the line outside. To prevent rendering artifacts, QGraphicsView
- expands all exposed regions by 2 pixels in all directions. If you enable
- this flag, QGraphicsView will no longer perform these adjustments,
- minimizing the areas that require redrawing, which improves performance. A
- common side effect is that items that do draw with antialiasing can leave
- painting traces behind on the scene as they are moved.
-
- \value IndirectPainting Since Qt 4.6, restore the old painting algorithm
- that calls QGraphicsView::drawItems() and QGraphicsScene::drawItems().
- To be used only for compatibility with old code.
-*/
-
-/*!
- \enum QGraphicsView::CacheModeFlag
-
- This enum describes the flags that you can set for a QGraphicsView's cache
- mode.
-
- \value CacheNone All painting is done directly onto the viewport.
-
- \value CacheBackground The background is cached. This affects both custom
- backgrounds, and backgrounds based on the backgroundBrush property. When
- this flag is enabled, QGraphicsView will allocate one pixmap with the full
- size of the viewport.
-
- \sa cacheMode
-*/
-
-/*!
- \enum QGraphicsView::DragMode
-
- This enum describes the default action for the view when pressing and
- dragging the mouse over the viewport.
-
- \value NoDrag Nothing happens; the mouse event is ignored.
-
- \value ScrollHandDrag The cursor changes into a pointing hand, and
- dragging the mouse around will scroll the scrolbars. This mode works both
- in \l{QGraphicsView::interactive}{interactive} and non-interactive mode.
-
- \value RubberBandDrag A rubber band will appear. Dragging the mouse will
- set the rubber band geometry, and all items covered by the rubber band are
- selected. This mode is disabled for non-interactive views.
-
- \sa dragMode, QGraphicsScene::setSelectionArea()
-*/
-
-#include "qgraphicsview.h"
-#include "qgraphicsview_p.h"
-
-#ifndef QT_NO_GRAPHICSVIEW
-
-#include "qgraphicsitem.h"
-#include "qgraphicsitem_p.h"
-#include "qgraphicsscene.h"
-#include "qgraphicsscene_p.h"
-#include "qgraphicssceneevent.h"
-#include "qgraphicswidget.h"
-
-#include <QtCore/qdatetime.h>
-#include <QtCore/qdebug.h>
-#include <QtCore/qmath.h>
-#include <QtGui/qapplication.h>
-#include <QtGui/qdesktopwidget.h>
-#include <QtGui/qevent.h>
-#include <QtGui/qlayout.h>
-#include <QtGui/qtransform.h>
-#include <QtGui/qmatrix.h>
-#include <QtGui/qpainter.h>
-#include <QtGui/qscrollbar.h>
-#include <QtGui/qstyleoption.h>
-#include <QtGui/qinputcontext.h>
-#ifdef Q_WS_X11
-#include <QtGui/qpaintengine.h>
-#include <private/qt_x11_p.h>
-#endif
-
-#include <private/qevent_p.h>
-
-QT_BEGIN_NAMESPACE
-
-bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event);
-
-inline int q_round_bound(qreal d) //### (int)(qreal) INT_MAX != INT_MAX for single precision
-{
- if (d <= (qreal) INT_MIN)
- return INT_MIN;
- else if (d >= (qreal) INT_MAX)
- return INT_MAX;
- return d >= 0.0 ? int(d + 0.5) : int(d - int(d-1) + 0.5) + int(d-1);
-}
-
-void QGraphicsViewPrivate::translateTouchEvent(QGraphicsViewPrivate *d, QTouchEvent *touchEvent)
-{
- QList<QTouchEvent::TouchPoint> touchPoints = touchEvent->touchPoints();
- for (int i = 0; i < touchPoints.count(); ++i) {
- QTouchEvent::TouchPoint &touchPoint = touchPoints[i];
- // the scene will set the item local pos, startPos, lastPos, and rect before delivering to
- // an item, but for now those functions are returning the view's local coordinates
- touchPoint.setSceneRect(d->mapToScene(touchPoint.rect()));
- touchPoint.setStartScenePos(d->mapToScene(touchPoint.startPos()));
- touchPoint.setLastScenePos(d->mapToScene(touchPoint.lastPos()));
-
- // screenPos, startScreenPos, lastScreenPos, and screenRect are already set
- }
-
- touchEvent->setTouchPoints(touchPoints);
-}
-
-/*!
- \internal
-*/
-QGraphicsViewPrivate::QGraphicsViewPrivate()
- : renderHints(QPainter::TextAntialiasing),
- dragMode(QGraphicsView::NoDrag),
- sceneInteractionAllowed(true), hasSceneRect(false),
- connectedToScene(false),
- useLastMouseEvent(false),
- identityMatrix(true),
- dirtyScroll(true),
- accelerateScrolling(true),
- keepLastCenterPoint(true),
- transforming(false),
- handScrolling(false),
- mustAllocateStyleOptions(false),
- mustResizeBackgroundPixmap(true),
- fullUpdatePending(true),
- hasUpdateClip(false),
- mousePressButton(Qt::NoButton),
- leftIndent(0), topIndent(0),
- lastMouseEvent(QEvent::None, QPoint(), Qt::NoButton, 0, 0),
- alignment(Qt::AlignCenter),
- transformationAnchor(QGraphicsView::AnchorViewCenter), resizeAnchor(QGraphicsView::NoAnchor),
- viewportUpdateMode(QGraphicsView::MinimalViewportUpdate),
- optimizationFlags(0),
- scene(0),
-#ifndef QT_NO_RUBBERBAND
- rubberBanding(false),
- rubberBandSelectionMode(Qt::IntersectsItemShape),
-#endif
- handScrollMotions(0), cacheMode(0),
-#ifndef QT_NO_CURSOR
- hasStoredOriginalCursor(false),
-#endif
- lastDragDropEvent(0),
- updateSceneSlotReimplementedChecked(false)
-{
- styleOptions.reserve(QGRAPHICSVIEW_PREALLOC_STYLE_OPTIONS);
-}
-
-/*!
- \internal
-*/
-void QGraphicsViewPrivate::recalculateContentSize()
-{
- Q_Q(QGraphicsView);
-
- QSize maxSize = q->maximumViewportSize();
- int width = maxSize.width();
- int height = maxSize.height();
- QRectF viewRect = matrix.mapRect(q->sceneRect());
-
- bool frameOnlyAround = (q->style()->styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents, 0, q));
- if (frameOnlyAround) {
- if (hbarpolicy == Qt::ScrollBarAlwaysOn)
- height -= frameWidth * 2;
- if (vbarpolicy == Qt::ScrollBarAlwaysOn)
- width -= frameWidth * 2;
- }
-
- // Adjust the maximum width and height of the viewport based on the width
- // of visible scroll bars.
- int scrollBarExtent = q->style()->pixelMetric(QStyle::PM_ScrollBarExtent, 0, q);
- if (frameOnlyAround)
- scrollBarExtent += frameWidth * 2;
-
- bool useHorizontalScrollBar = (viewRect.width() > width) && hbarpolicy != Qt::ScrollBarAlwaysOff;
- bool useVerticalScrollBar = (viewRect.height() > height) && vbarpolicy != Qt::ScrollBarAlwaysOff;
- if (useHorizontalScrollBar && !useVerticalScrollBar) {
- if (viewRect.height() > height - scrollBarExtent)
- useVerticalScrollBar = true;
- }
- if (useVerticalScrollBar && !useHorizontalScrollBar) {
- if (viewRect.width() > width - scrollBarExtent)
- useHorizontalScrollBar = true;
- }
- if (useHorizontalScrollBar && hbarpolicy != Qt::ScrollBarAlwaysOn)
- height -= scrollBarExtent;
- if (useVerticalScrollBar && vbarpolicy != Qt::ScrollBarAlwaysOn)
- width -= scrollBarExtent;
-
- // Setting the ranges of these scroll bars can/will cause the values to
- // change, and scrollContentsBy() will be called correspondingly. This
- // will reset the last center point.
- QPointF savedLastCenterPoint = lastCenterPoint;
-
- // Remember the former indent settings
- qreal oldLeftIndent = leftIndent;
- qreal oldTopIndent = topIndent;
-
- // If the whole scene fits horizontally, we center the scene horizontally,
- // and ignore the horizontal scroll bars.
- int left = q_round_bound(viewRect.left());
- int right = q_round_bound(viewRect.right() - width);
- if (left >= right) {
- hbar->setRange(0, 0);
-
- switch (alignment & Qt::AlignHorizontal_Mask) {
- case Qt::AlignLeft:
- leftIndent = -viewRect.left();
- break;
- case Qt::AlignRight:
- leftIndent = width - viewRect.width() - viewRect.left() - 1;
- break;
- case Qt::AlignHCenter:
- default:
- leftIndent = width / 2 - (viewRect.left() + viewRect.right()) / 2;
- break;
- }
- } else {
- hbar->setRange(left, right);
- hbar->setPageStep(width);
- hbar->setSingleStep(width / 20);
- leftIndent = 0;
- }
-
- // If the whole scene fits vertically, we center the scene vertically, and
- // ignore the vertical scroll bars.
- int top = q_round_bound(viewRect.top());
- int bottom = q_round_bound(viewRect.bottom() - height);
- if (top >= bottom) {
- vbar->setRange(0, 0);
-
- switch (alignment & Qt::AlignVertical_Mask) {
- case Qt::AlignTop:
- topIndent = -viewRect.top();
- break;
- case Qt::AlignBottom:
- topIndent = height - viewRect.height() - viewRect.top() - 1;
- break;
- case Qt::AlignVCenter:
- default:
- topIndent = height / 2 - (viewRect.top() + viewRect.bottom()) / 2;
- break;
- }
- } else {
- vbar->setRange(top, bottom);
- vbar->setPageStep(height);
- vbar->setSingleStep(height / 20);
- topIndent = 0;
- }
-
- // Restorethe center point from before the ranges changed.
- lastCenterPoint = savedLastCenterPoint;
-
- // Issue a full update if the indents change.
- // ### If the transform is still the same, we can get away with just a
- // scroll instead.
- if (oldLeftIndent != leftIndent || oldTopIndent != topIndent) {
- dirtyScroll = true;
- updateAll();
- } else if (q->isRightToLeft() && !leftIndent) {
- // In reverse mode, the horizontal scroll always changes after the content
- // size has changed, as the scroll is calculated by summing the min and
- // max values of the range and subtracting the current value. In normal
- // mode the scroll remains unchanged unless the indent has changed.
- dirtyScroll = true;
- }
-
- if (cacheMode & QGraphicsView::CacheBackground) {
- // Invalidate the background pixmap
- mustResizeBackgroundPixmap = true;
- }
-}
-
-/*!
- \internal
-*/
-void QGraphicsViewPrivate::centerView(QGraphicsView::ViewportAnchor anchor)
-{
- Q_Q(QGraphicsView);
- switch (anchor) {
- case QGraphicsView::AnchorUnderMouse: {
- if (q->underMouse()) {
- // Last scene pos: lastMouseMoveScenePoint
- // Current mouse pos:
- QPointF transformationDiff = q->mapToScene(viewport->rect().center())
- - q->mapToScene(viewport->mapFromGlobal(QCursor::pos()));
- q->centerOn(lastMouseMoveScenePoint + transformationDiff);
- } else {
- q->centerOn(lastCenterPoint);
- }
- break;
- }
- case QGraphicsView::AnchorViewCenter:
- q->centerOn(lastCenterPoint);
- break;
- case QGraphicsView::NoAnchor:
- break;
- }
-}
-
-/*!
- \internal
-*/
-void QGraphicsViewPrivate::updateLastCenterPoint()
-{
- Q_Q(QGraphicsView);
- lastCenterPoint = q->mapToScene(viewport->rect().center());
-}
-
-/*!
- \internal
-
- Returns the horizontal scroll value (the X value of the left edge of the
- viewport).
-*/
-qint64 QGraphicsViewPrivate::horizontalScroll() const
-{
- if (dirtyScroll)
- const_cast<QGraphicsViewPrivate *>(this)->updateScroll();
- return scrollX;
-}
-
-/*!
- \internal
-
- Returns the vertical scroll value (the X value of the top edge of the
- viewport).
-*/
-qint64 QGraphicsViewPrivate::verticalScroll() const
-{
- if (dirtyScroll)
- const_cast<QGraphicsViewPrivate *>(this)->updateScroll();
- return scrollY;
-}
-
-/*!
- \internal
-
- Maps the given rectangle to the scene using QTransform::mapRect()
-*/
-QRectF QGraphicsViewPrivate::mapRectToScene(const QRect &rect) const
-{
- if (dirtyScroll)
- const_cast<QGraphicsViewPrivate *>(this)->updateScroll();
- QRectF scrolled = QRectF(rect.translated(scrollX, scrollY));
- return identityMatrix ? scrolled : matrix.inverted().mapRect(scrolled);
-}
-
-
-/*!
- \internal
-
- Maps the given rectangle from the scene using QTransform::mapRect()
-*/
-QRectF QGraphicsViewPrivate::mapRectFromScene(const QRectF &rect) const
-{
- if (dirtyScroll)
- const_cast<QGraphicsViewPrivate *>(this)->updateScroll();
- return (identityMatrix ? rect : matrix.mapRect(rect)).translated(-scrollX, -scrollY);
-}
-
-/*!
- \internal
-*/
-void QGraphicsViewPrivate::updateScroll()
-{
- Q_Q(QGraphicsView);
- scrollX = qint64(-leftIndent);
- if (q->isRightToLeft()) {
- if (!leftIndent) {
- scrollX += hbar->minimum();
- scrollX += hbar->maximum();
- scrollX -= hbar->value();
- }
- } else {
- scrollX += hbar->value();
- }
-
- scrollY = qint64(vbar->value() - topIndent);
-
- dirtyScroll = false;
-}
-
-/*!
- \internal
-*/
-void QGraphicsViewPrivate::replayLastMouseEvent()
-{
- if (!useLastMouseEvent || !scene)
- return;
- mouseMoveEventHandler(&lastMouseEvent);
-}
-
-/*!
- \internal
-*/
-void QGraphicsViewPrivate::storeMouseEvent(QMouseEvent *event)
-{
- useLastMouseEvent = true;
- lastMouseEvent = QMouseEvent(QEvent::MouseMove, event->pos(), event->globalPos(),
- event->button(), event->buttons(), event->modifiers());
-}
-
-void QGraphicsViewPrivate::mouseMoveEventHandler(QMouseEvent *event)
-{
- Q_Q(QGraphicsView);
-
- storeMouseEvent(event);
- lastMouseEvent.setAccepted(false);
-
- if (!sceneInteractionAllowed)
- return;
- if (handScrolling)
- return;
- if (!scene)
- return;
-
- QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMouseMove);
- mouseEvent.setWidget(viewport);
- mouseEvent.setButtonDownScenePos(mousePressButton, mousePressScenePoint);
- mouseEvent.setButtonDownScreenPos(mousePressButton, mousePressScreenPoint);
- mouseEvent.setScenePos(q->mapToScene(event->pos()));
- mouseEvent.setScreenPos(event->globalPos());
- mouseEvent.setLastScenePos(lastMouseMoveScenePoint);
- mouseEvent.setLastScreenPos(lastMouseMoveScreenPoint);
- mouseEvent.setButtons(event->buttons());
- mouseEvent.setButton(event->button());
- mouseEvent.setModifiers(event->modifiers());
- lastMouseMoveScenePoint = mouseEvent.scenePos();
- lastMouseMoveScreenPoint = mouseEvent.screenPos();
- mouseEvent.setAccepted(false);
- if (event->spontaneous())
- qt_sendSpontaneousEvent(scene, &mouseEvent);
- else
- QApplication::sendEvent(scene, &mouseEvent);
-
- // Remember whether the last event was accepted or not.
- lastMouseEvent.setAccepted(mouseEvent.isAccepted());
-
- if (mouseEvent.isAccepted() && mouseEvent.buttons() != 0) {
- // The event was delivered to a mouse grabber; the press is likely to
- // have set a cursor, and we must not change it.
- return;
- }
-
-#ifndef QT_NO_CURSOR
- // If all the items ignore hover events, we don't look-up any items
- // in QGraphicsScenePrivate::dispatchHoverEvent, hence the
- // cachedItemsUnderMouse list will be empty. We therefore do the look-up
- // for cursor items here if not all items use the default cursor.
- if (scene->d_func()->allItemsIgnoreHoverEvents && !scene->d_func()->allItemsUseDefaultCursor
- && scene->d_func()->cachedItemsUnderMouse.isEmpty()) {
- scene->d_func()->cachedItemsUnderMouse = scene->d_func()->itemsAtPosition(mouseEvent.screenPos(),
- mouseEvent.scenePos(),
- mouseEvent.widget());
- }
- // Find the topmost item under the mouse with a cursor.
- foreach (QGraphicsItem *item, scene->d_func()->cachedItemsUnderMouse) {
- if (item->hasCursor()) {
- _q_setViewportCursor(item->cursor());
- return;
- }
- }
-
- // No items with cursors found; revert to the view cursor.
- if (hasStoredOriginalCursor) {
- // Restore the original viewport cursor.
- hasStoredOriginalCursor = false;
- viewport->setCursor(originalCursor);
- }
-#endif
-}
-
-/*!
- \internal
-*/
-#ifndef QT_NO_RUBBERBAND
-QRegion QGraphicsViewPrivate::rubberBandRegion(const QWidget *widget, const QRect &rect) const
-{
- QStyleHintReturnMask mask;
- QStyleOptionRubberBand option;
- option.initFrom(widget);
- option.rect = rect;
- option.opaque = false;
- option.shape = QRubberBand::Rectangle;
-
- QRegion tmp;
- tmp += rect;
- if (widget->style()->styleHint(QStyle::SH_RubberBand_Mask, &option, widget, &mask))
- tmp &= mask.region;
- return tmp;
-}
-#endif
-
-/*!
- \internal
-*/
-#ifndef QT_NO_CURSOR
-void QGraphicsViewPrivate::_q_setViewportCursor(const QCursor &cursor)
-{
- if (!hasStoredOriginalCursor) {
- hasStoredOriginalCursor = true;
- originalCursor = viewport->cursor();
- }
- viewport->setCursor(cursor);
-}
-#endif
-
-/*!
- \internal
-*/
-#ifndef QT_NO_CURSOR
-void QGraphicsViewPrivate::_q_unsetViewportCursor()
-{
- Q_Q(QGraphicsView);
- foreach (QGraphicsItem *item, q->items(lastMouseEvent.pos())) {
- if (item->hasCursor()) {
- _q_setViewportCursor(item->cursor());
- return;
- }
- }
-
- // Restore the original viewport cursor.
- if (hasStoredOriginalCursor) {
- hasStoredOriginalCursor = false;
- if (dragMode == QGraphicsView::ScrollHandDrag)
- viewport->setCursor(Qt::OpenHandCursor);
- else
- viewport->setCursor(originalCursor);
- }
-}
-#endif
-
-/*!
- \internal
-*/
-void QGraphicsViewPrivate::storeDragDropEvent(const QGraphicsSceneDragDropEvent *event)
-{
- delete lastDragDropEvent;
- lastDragDropEvent = new QGraphicsSceneDragDropEvent(event->type());
- lastDragDropEvent->setScenePos(event->scenePos());
- lastDragDropEvent->setScreenPos(event->screenPos());
- lastDragDropEvent->setButtons(event->buttons());
- lastDragDropEvent->setModifiers(event->modifiers());
- lastDragDropEvent->setPossibleActions(event->possibleActions());
- lastDragDropEvent->setProposedAction(event->proposedAction());
- lastDragDropEvent->setDropAction(event->dropAction());
- lastDragDropEvent->setMimeData(event->mimeData());
- lastDragDropEvent->setWidget(event->widget());
- lastDragDropEvent->setSource(event->source());
-}
-
-/*!
- \internal
-*/
-void QGraphicsViewPrivate::populateSceneDragDropEvent(QGraphicsSceneDragDropEvent *dest,
- QDropEvent *source)
-{
-#ifndef QT_NO_DRAGANDDROP
- Q_Q(QGraphicsView);
- dest->setScenePos(q->mapToScene(source->pos()));
- dest->setScreenPos(q->mapToGlobal(source->pos()));
- dest->setButtons(source->mouseButtons());
- dest->setModifiers(source->keyboardModifiers());
- dest->setPossibleActions(source->possibleActions());
- dest->setProposedAction(source->proposedAction());
- dest->setDropAction(source->dropAction());
- dest->setMimeData(source->mimeData());
- dest->setWidget(viewport);
- dest->setSource(source->source());
-#else
- Q_UNUSED(dest)
- Q_UNUSED(source)
-#endif
-}
-
-/*!
- \internal
-*/
-QRect QGraphicsViewPrivate::mapToViewRect(const QGraphicsItem *item, const QRectF &rect) const
-{
- Q_Q(const QGraphicsView);
- if (dirtyScroll)
- const_cast<QGraphicsViewPrivate *>(this)->updateScroll();
-
- if (item->d_ptr->itemIsUntransformable()) {
- QTransform itv = item->deviceTransform(q->viewportTransform());
- return itv.mapRect(rect).toAlignedRect();
- }
-
- // Translate-only
- // COMBINE
- QPointF offset;
- const QGraphicsItem *parentItem = item;
- const QGraphicsItemPrivate *itemd;
- do {
- itemd = parentItem->d_ptr.data();
- if (itemd->transformData)
- break;
- offset += itemd->pos;
- } while ((parentItem = itemd->parent));
-
- QRectF baseRect = rect.translated(offset.x(), offset.y());
- if (!parentItem) {
- if (identityMatrix) {
- baseRect.translate(-scrollX, -scrollY);
- return baseRect.toAlignedRect();
- }
- return matrix.mapRect(baseRect).translated(-scrollX, -scrollY).toAlignedRect();
- }
-
- QTransform tr = parentItem->sceneTransform();
- if (!identityMatrix)
- tr *= matrix;
- QRectF r = tr.mapRect(baseRect);
- r.translate(-scrollX, -scrollY);
- return r.toAlignedRect();
-}
-
-/*!
- \internal
-*/
-QRegion QGraphicsViewPrivate::mapToViewRegion(const QGraphicsItem *item, const QRectF &rect) const
-{
- Q_Q(const QGraphicsView);
- if (dirtyScroll)
- const_cast<QGraphicsViewPrivate *>(this)->updateScroll();
-
- // Accurate bounding region
- QTransform itv = item->deviceTransform(q->viewportTransform());
- return item->boundingRegion(itv) & itv.mapRect(rect).toAlignedRect();
-}
-
-/*!
- \internal
-*/
-void QGraphicsViewPrivate::processPendingUpdates()
-{
- if (!scene)
- return;
-
- if (fullUpdatePending) {
- viewport->update();
- } else if (viewportUpdateMode == QGraphicsView::BoundingRectViewportUpdate) {
- viewport->update(dirtyBoundingRect);
- } else {
- viewport->update(dirtyRegion); // Already adjusted in updateRect/Region.
- }
-
- dirtyBoundingRect = QRect();
- dirtyRegion = QRegion();
-}
-
-static inline bool intersectsViewport(const QRect &r, int width, int height)
-{ return !(r.left() > width) && !(r.right() < 0) && !(r.top() >= height) && !(r.bottom() < 0); }
-
-static inline bool containsViewport(const QRect &r, int width, int height)
-{ return r.left() <= 0 && r.top() <= 0 && r.right() >= width - 1 && r.bottom() >= height - 1; }
-
-static inline void QRect_unite(QRect *rect, const QRect &other)
-{
- if (rect->isEmpty()) {
- *rect = other;
- } else {
- rect->setCoords(qMin(rect->left(), other.left()), qMin(rect->top(), other.top()),
- qMax(rect->right(), other.right()), qMax(rect->bottom(), other.bottom()));
- }
-}
-
-/*
- Calling this function results in update rects being clipped to the item's
- bounding rect. Note that updates prior to this function call is not clipped.
- The clip is removed by passing 0.
-*/
-void QGraphicsViewPrivate::setUpdateClip(QGraphicsItem *item)
-{
- Q_Q(QGraphicsView);
- // We simply ignore the request if the update mode is either FullViewportUpdate
- // or NoViewportUpdate; in that case there's no point in clipping anything.
- if (!item || viewportUpdateMode == QGraphicsView::NoViewportUpdate
- || viewportUpdateMode == QGraphicsView::FullViewportUpdate) {
- hasUpdateClip = false;
- return;
- }
-
- // Calculate the clip (item's bounding rect in view coordinates).
- // Optimized version of:
- // QRect clip = item->deviceTransform(q->viewportTransform())
- // .mapRect(item->boundingRect()).toAlignedRect();
- QRect clip;
- if (item->d_ptr->itemIsUntransformable()) {
- QTransform xform = item->deviceTransform(q->viewportTransform());
- clip = xform.mapRect(item->boundingRect()).toAlignedRect();
- } else if (item->d_ptr->sceneTransformTranslateOnly && identityMatrix) {
- QRectF r(item->boundingRect());
- r.translate(item->d_ptr->sceneTransform.dx() - horizontalScroll(),
- item->d_ptr->sceneTransform.dy() - verticalScroll());
- clip = r.toAlignedRect();
- } else if (!q->isTransformed()) {
- clip = item->d_ptr->sceneTransform.mapRect(item->boundingRect()).toAlignedRect();
- } else {
- QTransform xform = item->d_ptr->sceneTransform;
- xform *= q->viewportTransform();
- clip = xform.mapRect(item->boundingRect()).toAlignedRect();
- }
-
- if (hasUpdateClip) {
- // Intersect with old clip.
- updateClip &= clip;
- } else {
- updateClip = clip;
- hasUpdateClip = true;
- }
-}
-
-bool QGraphicsViewPrivate::updateRegion(const QRectF &rect, const QTransform &xform)
-{
- if (rect.isEmpty())
- return false;
-
- if (viewportUpdateMode != QGraphicsView::MinimalViewportUpdate
- && viewportUpdateMode != QGraphicsView::SmartViewportUpdate) {
- // No point in updating with QRegion granularity; use the rect instead.
- return updateRectF(xform.mapRect(rect));
- }
-
- // Update mode is either Minimal or Smart, so we have to do a potentially slow operation,
- // which is clearly documented here: QGraphicsItem::setBoundingRegionGranularity.
- const QRegion region = xform.map(QRegion(rect.toAlignedRect()));
- QRect viewRect = region.boundingRect();
- const bool dontAdjustForAntialiasing = optimizationFlags & QGraphicsView::DontAdjustForAntialiasing;
- if (dontAdjustForAntialiasing)
- viewRect.adjust(-1, -1, 1, 1);
- else
- viewRect.adjust(-2, -2, 2, 2);
- if (!intersectsViewport(viewRect, viewport->width(), viewport->height()))
- return false; // Update region for sure outside viewport.
-
- const QVector<QRect> &rects = region.rects();
- for (int i = 0; i < rects.size(); ++i) {
- viewRect = rects.at(i);
- if (dontAdjustForAntialiasing)
- viewRect.adjust(-1, -1, 1, 1);
- else
- viewRect.adjust(-2, -2, 2, 2);
- if (hasUpdateClip)
- viewRect &= updateClip;
- dirtyRegion += viewRect;
- }
-
- return true;
-}
-
-// NB! Assumes the rect 'r' is already aligned and adjusted for antialiasing.
-// For QRectF use updateRectF(const QRectF &) to ensure proper adjustments.
-bool QGraphicsViewPrivate::updateRect(const QRect &r)
-{
- if (fullUpdatePending || viewportUpdateMode == QGraphicsView::NoViewportUpdate
- || !intersectsViewport(r, viewport->width(), viewport->height())) {
- return false;
- }
-
- switch (viewportUpdateMode) {
- case QGraphicsView::FullViewportUpdate:
- fullUpdatePending = true;
- viewport->update();
- break;
- case QGraphicsView::BoundingRectViewportUpdate:
- if (hasUpdateClip)
- QRect_unite(&dirtyBoundingRect, r & updateClip);
- else
- QRect_unite(&dirtyBoundingRect, r);
- if (containsViewport(dirtyBoundingRect, viewport->width(), viewport->height())) {
- fullUpdatePending = true;
- viewport->update();
- }
- break;
- case QGraphicsView::SmartViewportUpdate: // ### DEPRECATE
- case QGraphicsView::MinimalViewportUpdate:
- if (hasUpdateClip)
- dirtyRegion += r & updateClip;
- else
- dirtyRegion += r;
- break;
- default:
- break;
- }
-
- return true;
-}
-
-QStyleOptionGraphicsItem *QGraphicsViewPrivate::allocStyleOptionsArray(int numItems)
-{
- if (mustAllocateStyleOptions || (numItems > styleOptions.capacity()))
- // too many items, let's allocate on-the-fly
- return new QStyleOptionGraphicsItem[numItems];
-
- // expand only whenever necessary
- if (numItems > styleOptions.size())
- styleOptions.resize(numItems);
-
- mustAllocateStyleOptions = true;
- return styleOptions.data();
-}
-
-void QGraphicsViewPrivate::freeStyleOptionsArray(QStyleOptionGraphicsItem *array)
-{
- mustAllocateStyleOptions = false;
- if (array != styleOptions.data())
- delete [] array;
-}
-
-extern QPainterPath qt_regionToPath(const QRegion &region);
-
-/*!
- ### 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 QTransform &viewTransform) const
-{
- Q_Q(const QGraphicsView);
-
- // Step 1) If all items are contained within the expose region, then
- // return a list of all visible items. ### the scene's growing bounding
- // rect does not take into account untransformable items.
- const QRectF exposedRegionSceneBounds = q->mapToScene(exposedRegion.boundingRect().adjusted(-1, -1, 1, 1))
- .boundingRect();
- if (exposedRegionSceneBounds.contains(scene->sceneRect())) {
- Q_ASSERT(allItems);
- *allItems = true;
-
- // All items are guaranteed within the exposed region.
- return scene->items(Qt::AscendingOrder);
- }
-
- // 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 = exposedRegion.rectCount() == 1 && matrix.type() <= QTransform::TxScale;
- if (simpleRectLookup) {
- return scene->items(exposedRegionSceneBounds,
- Qt::IntersectsItemBoundingRect,
- Qt::AscendingOrder, viewTransform);
- }
-
- // 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 exposedScenePath(q->mapToScene(qt_regionToPath(adjustedRegion)));
- return scene->items(exposedScenePath, Qt::IntersectsItemBoundingRect,
- Qt::AscendingOrder, viewTransform);
-}
-
-/*!
- \internal
-
- Enables input methods for the view if and only if the current focus item of
- the scene accepts input methods. Call function whenever that condition has
- potentially changed.
-*/
-void QGraphicsViewPrivate::updateInputMethodSensitivity()
-{
- Q_Q(QGraphicsView);
- QGraphicsItem *focusItem = 0;
- bool enabled = scene && (focusItem = scene->focusItem())
- && (focusItem->d_ptr->flags & QGraphicsItem::ItemAcceptsInputMethod);
- q->setAttribute(Qt::WA_InputMethodEnabled, enabled);
- q->viewport()->setAttribute(Qt::WA_InputMethodEnabled, enabled);
-
- if (!enabled) {
- q->setInputMethodHints(0);
- return;
- }
-
- QGraphicsProxyWidget *proxy = focusItem->d_ptr->isWidget && focusItem->d_ptr->isProxyWidget()
- ? static_cast<QGraphicsProxyWidget *>(focusItem) : 0;
- if (!proxy) {
- q->setInputMethodHints(focusItem->inputMethodHints());
- } else if (QWidget *widget = proxy->widget()) {
- if (QWidget *fw = widget->focusWidget())
- widget = fw;
- q->setInputMethodHints(widget->inputMethodHints());
- } else {
- q->setInputMethodHints(0);
- }
-}
-
-/*!
- Constructs a QGraphicsView. \a parent is passed to QWidget's constructor.
-*/
-QGraphicsView::QGraphicsView(QWidget *parent)
- : QAbstractScrollArea(*new QGraphicsViewPrivate, parent)
-{
- setViewport(0);
- setAcceptDrops(true);
- setBackgroundRole(QPalette::Base);
- // Investigate leaving these disabled by default.
- setAttribute(Qt::WA_InputMethodEnabled);
- viewport()->setAttribute(Qt::WA_InputMethodEnabled);
-}
-
-/*!
- Constructs a QGraphicsView and sets the visualized scene to \a
- scene. \a parent is passed to QWidget's constructor.
-*/
-QGraphicsView::QGraphicsView(QGraphicsScene *scene, QWidget *parent)
- : QAbstractScrollArea(*new QGraphicsViewPrivate, parent)
-{
- setScene(scene);
- setViewport(0);
- setAcceptDrops(true);
- setBackgroundRole(QPalette::Base);
- // Investigate leaving these disabled by default.
- setAttribute(Qt::WA_InputMethodEnabled);
- viewport()->setAttribute(Qt::WA_InputMethodEnabled);
-}
-
-/*!
- \internal
- */
-QGraphicsView::QGraphicsView(QGraphicsViewPrivate &dd, QWidget *parent)
- : QAbstractScrollArea(dd, parent)
-{
- setViewport(0);
- setAcceptDrops(true);
- setBackgroundRole(QPalette::Base);
- // Investigate leaving these disabled by default.
- setAttribute(Qt::WA_InputMethodEnabled);
- viewport()->setAttribute(Qt::WA_InputMethodEnabled);
-}
-
-/*!
- Destructs the QGraphicsView object.
-*/
-QGraphicsView::~QGraphicsView()
-{
- Q_D(QGraphicsView);
- if (d->scene)
- d->scene->d_func()->views.removeAll(this);
- delete d->lastDragDropEvent;
-}
-
-/*!
- \reimp
-*/
-QSize QGraphicsView::sizeHint() const
-{
- Q_D(const QGraphicsView);
- if (d->scene) {
- QSizeF baseSize = d->matrix.mapRect(sceneRect()).size();
- baseSize += QSizeF(d->frameWidth * 2, d->frameWidth * 2);
- return baseSize.boundedTo((3 * QApplication::desktop()->size()) / 4).toSize();
- }
- return QAbstractScrollArea::sizeHint();
-}
-
-/*!
- \property QGraphicsView::renderHints
- \brief the default render hints for the view
-
- These hints are
- used to initialize QPainter before each visible item is drawn. QPainter
- uses render hints to toggle rendering features such as antialiasing and
- smooth pixmap transformation.
-
- QPainter::TextAntialiasing is enabled by default.
-
- Example:
-
- \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsview.cpp 1
-*/
-QPainter::RenderHints QGraphicsView::renderHints() const
-{
- Q_D(const QGraphicsView);
- return d->renderHints;
-}
-void QGraphicsView::setRenderHints(QPainter::RenderHints hints)
-{
- Q_D(QGraphicsView);
- if (hints == d->renderHints)
- return;
- d->renderHints = hints;
- d->updateAll();
-}
-
-/*!
- If \a enabled is true, the render hint \a hint is enabled; otherwise it
- is disabled.
-
- \sa renderHints
-*/
-void QGraphicsView::setRenderHint(QPainter::RenderHint hint, bool enabled)
-{
- Q_D(QGraphicsView);
- QPainter::RenderHints oldHints = d->renderHints;
- if (enabled)
- d->renderHints |= hint;
- else
- d->renderHints &= ~hint;
- if (oldHints != d->renderHints)
- d->updateAll();
-}
-
-/*!
- \property QGraphicsView::alignment
- \brief the alignment of the scene in the view when the whole
- scene is visible.
-
- If the whole scene is visible in the view, (i.e., there are no visible
- scroll bars,) the view's alignment will decide where the scene will be
- rendered in the view. For example, if the alignment is Qt::AlignCenter,
- which is default, the scene will be centered in the view, and if the
- alignment is (Qt::AlignLeft | Qt::AlignTop), the scene will be rendered in
- the top-left corner of the view.
-*/
-Qt::Alignment QGraphicsView::alignment() const
-{
- Q_D(const QGraphicsView);
- return d->alignment;
-}
-void QGraphicsView::setAlignment(Qt::Alignment alignment)
-{
- Q_D(QGraphicsView);
- if (d->alignment != alignment) {
- d->alignment = alignment;
- d->recalculateContentSize();
- }
-}
-
-/*!
- \property QGraphicsView::transformationAnchor
- \brief how the view should position the scene during transformations.
-
- QGraphicsView uses this property to decide how to position the scene in
- the viewport when the transformation matrix changes, and the coordinate
- system of the view is transformed. The default behavior, AnchorViewCenter,
- ensures that the scene point at the center of the view remains unchanged
- during transformations (e.g., when rotating, the scene will appear to
- rotate around the center of the view).
-
- Note that the effect of this property is noticeable when only a part of the
- scene is visible (i.e., when there are scroll bars). Otherwise, if the
- whole scene fits in the view, QGraphicsScene uses the view \l alignment to
- position the scene in the view.
-
- \sa alignment, resizeAnchor
-*/
-QGraphicsView::ViewportAnchor QGraphicsView::transformationAnchor() const
-{
- Q_D(const QGraphicsView);
- return d->transformationAnchor;
-}
-void QGraphicsView::setTransformationAnchor(ViewportAnchor anchor)
-{
- Q_D(QGraphicsView);
- d->transformationAnchor = anchor;
-
- // Ensure mouse tracking is enabled in the case we are using AnchorUnderMouse
- // in order to have up-to-date information for centering the view.
- if (d->transformationAnchor == AnchorUnderMouse)
- d->viewport->setMouseTracking(true);
-}
-
-/*!
- \property QGraphicsView::resizeAnchor
- \brief how the view should position the scene when the view is resized.
-
- QGraphicsView uses this property to decide how to position the scene in
- the viewport when the viewport widget's size changes. The default
- behavior, NoAnchor, leaves the scene's position unchanged during a resize;
- the top-left corner of the view will appear to be anchored while resizing.
-
- Note that the effect of this property is noticeable when only a part of the
- scene is visible (i.e., when there are scroll bars). Otherwise, if the
- whole scene fits in the view, QGraphicsScene uses the view \l alignment to
- position the scene in the view.
-
- \sa alignment, transformationAnchor, Qt::WNorthWestGravity
-*/
-QGraphicsView::ViewportAnchor QGraphicsView::resizeAnchor() const
-{
- Q_D(const QGraphicsView);
- return d->resizeAnchor;
-}
-void QGraphicsView::setResizeAnchor(ViewportAnchor anchor)
-{
- Q_D(QGraphicsView);
- d->resizeAnchor = anchor;
-
- // Ensure mouse tracking is enabled in the case we are using AnchorUnderMouse
- // in order to have up-to-date information for centering the view.
- if (d->resizeAnchor == AnchorUnderMouse)
- d->viewport->setMouseTracking(true);
-}
-
-/*!
- \property QGraphicsView::viewportUpdateMode
- \brief how the viewport should update its contents.
-
- \since 4.3
-
- QGraphicsView uses this property to decide how to update areas of the
- scene that have been reexposed or changed. Usually you do not need to
- modify this property, but there are some cases where doing so can improve
- rendering performance. See the ViewportUpdateMode documentation for
- specific details.
-
- The default value is MinimalViewportUpdate, where QGraphicsView will
- update as small an area of the viewport as possible when the contents
- change.
-
- \sa ViewportUpdateMode, cacheMode
-*/
-QGraphicsView::ViewportUpdateMode QGraphicsView::viewportUpdateMode() const
-{
- Q_D(const QGraphicsView);
- return d->viewportUpdateMode;
-}
-void QGraphicsView::setViewportUpdateMode(ViewportUpdateMode mode)
-{
- Q_D(QGraphicsView);
- d->viewportUpdateMode = mode;
-}
-
-/*!
- \property QGraphicsView::optimizationFlags
- \brief flags that can be used to tune QGraphicsView's performance.
-
- \since 4.3
-
- QGraphicsView uses clipping, extra bounding rect adjustments, and certain
- other aids to improve rendering quality and performance for the common
- case graphics scene. However, depending on the target platform, the scene,
- and the viewport in use, some of these operations can degrade performance.
-
- The effect varies from flag to flag; see the OptimizationFlags
- documentation for details.
-
- By default, no optimization flags are enabled.
-
- \sa setOptimizationFlag()
-*/
-QGraphicsView::OptimizationFlags QGraphicsView::optimizationFlags() const
-{
- Q_D(const QGraphicsView);
- return d->optimizationFlags;
-}
-void QGraphicsView::setOptimizationFlags(OptimizationFlags flags)
-{
- Q_D(QGraphicsView);
- d->optimizationFlags = flags;
-}
-
-/*!
- Enables \a flag if \a enabled is true; otherwise disables \a flag.
-
- \sa optimizationFlags
-*/
-void QGraphicsView::setOptimizationFlag(OptimizationFlag flag, bool enabled)
-{
- Q_D(QGraphicsView);
- if (enabled)
- d->optimizationFlags |= flag;
- else
- d->optimizationFlags &= ~flag;
-}
-
-/*!
- \property QGraphicsView::dragMode
- \brief the behavior for dragging the mouse over the scene while
- the left mouse button is pressed.
-
- This property defines what should happen when the user clicks on the scene
- background and drags the mouse (e.g., scrolling the viewport contents
- using a pointing hand cursor, or selecting multiple items with a rubber
- band). The default value, NoDrag, does nothing.
-
- This behavior only affects mouse clicks that are not handled by any item.
- You can define a custom behavior by creating a subclass of QGraphicsView
- and reimplementing mouseMoveEvent().
-*/
-QGraphicsView::DragMode QGraphicsView::dragMode() const
-{
- Q_D(const QGraphicsView);
- return d->dragMode;
-}
-void QGraphicsView::setDragMode(DragMode mode)
-{
- Q_D(QGraphicsView);
- if (d->dragMode == mode)
- return;
-
-#ifndef QT_NO_CURSOR
- if (d->dragMode == ScrollHandDrag)
- viewport()->unsetCursor();
-#endif
-
- // If dragMode is unset while dragging, e.g. via a keyEvent, we
- // don't unset the handScrolling state. When enabling scrolling
- // again the mouseMoveEvent will automatically start scrolling,
- // without a mousePress
- if (d->dragMode == ScrollHandDrag && mode == NoDrag && d->handScrolling)
- d->handScrolling = false;
-
- d->dragMode = mode;
-
-#ifndef QT_NO_CURSOR
- if (d->dragMode == ScrollHandDrag) {
- // Forget the stored viewport cursor when we enter scroll hand drag mode.
- d->hasStoredOriginalCursor = false;
- viewport()->setCursor(Qt::OpenHandCursor);
- }
-#endif
-}
-
-#ifndef QT_NO_RUBBERBAND
-/*!
- \property QGraphicsView::rubberBandSelectionMode
- \brief the behavior for selecting items with a rubber band selection rectangle.
- \since 4.3
-
- This property defines how items are selected when using the RubberBandDrag
- drag mode.
-
- The default value is Qt::IntersectsItemShape; all items whose shape
- intersects with or is contained by the rubber band are selected.
-
- \sa dragMode, items()
-*/
-Qt::ItemSelectionMode QGraphicsView::rubberBandSelectionMode() const
-{
- Q_D(const QGraphicsView);
- return d->rubberBandSelectionMode;
-}
-void QGraphicsView::setRubberBandSelectionMode(Qt::ItemSelectionMode mode)
-{
- Q_D(QGraphicsView);
- d->rubberBandSelectionMode = mode;
-}
-#endif
-
-/*!
- \property QGraphicsView::cacheMode
- \brief which parts of the view are cached
-
- QGraphicsView can cache pre-rendered content in a QPixmap, which is then
- drawn onto the viewport. The purpose of such caching is to speed up the
- total rendering time for areas that are slow to render. Texture, gradient
- and alpha blended backgrounds, for example, can be notibly slow to render;
- especially with a transformed view. The CacheBackground flag enables
- caching of the view's background. For example:
-
- \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsview.cpp 2
-
- The cache is invalidated every time the view is transformed. However, when
- scrolling, only partial invalidation is required.
-
- By default, nothing is cached.
-
- \sa resetCachedContent(), QPixmapCache
-*/
-QGraphicsView::CacheMode QGraphicsView::cacheMode() const
-{
- Q_D(const QGraphicsView);
- return d->cacheMode;
-}
-void QGraphicsView::setCacheMode(CacheMode mode)
-{
- Q_D(QGraphicsView);
- if (mode == d->cacheMode)
- return;
- d->cacheMode = mode;
- resetCachedContent();
-}
-
-/*!
- Resets any cached content. Calling this function will clear
- QGraphicsView's cache. If the current cache mode is \l CacheNone, this
- function does nothing.
-
- This function is called automatically for you when the backgroundBrush or
- QGraphicsScene::backgroundBrush properties change; you only need to call
- this function if you have reimplemented QGraphicsScene::drawBackground()
- or QGraphicsView::drawBackground() to draw a custom background, and need
- to trigger a full redraw.
-
- \sa cacheMode()
-*/
-void QGraphicsView::resetCachedContent()
-{
- Q_D(QGraphicsView);
- if (d->cacheMode == CacheNone)
- return;
-
- if (d->cacheMode & CacheBackground) {
- // Background caching is enabled.
- d->mustResizeBackgroundPixmap = true;
- d->updateAll();
- } else if (d->mustResizeBackgroundPixmap) {
- // Background caching is disabled.
- // Cleanup, free some resources.
- d->mustResizeBackgroundPixmap = false;
- d->backgroundPixmap = QPixmap();
- d->backgroundPixmapExposed = QRegion();
- }
-}
-
-/*!
- Invalidates and schedules a redraw of \a layers inside \a rect. \a rect is
- in scene coordinates. Any cached content for \a layers inside \a rect is
- unconditionally invalidated and redrawn.
-
- You can call this function to notify QGraphicsView of changes to the
- background or the foreground of the scene. It is commonly used for scenes
- with tile-based backgrounds to notify changes when QGraphicsView has
- enabled background caching.
-
- Note that QGraphicsView currently supports background caching only (see
- QGraphicsView::CacheBackground). This function is equivalent to calling update() if any
- layer but QGraphicsScene::BackgroundLayer is passed.
-
- \sa QGraphicsScene::invalidate(), update()
-*/
-void QGraphicsView::invalidateScene(const QRectF &rect, QGraphicsScene::SceneLayers layers)
-{
- Q_D(QGraphicsView);
- if ((layers & QGraphicsScene::BackgroundLayer) && !d->mustResizeBackgroundPixmap) {
- QRect viewRect = mapFromScene(rect).boundingRect();
- if (viewport()->rect().intersects(viewRect)) {
- // The updated background area is exposed; schedule this area for
- // redrawing.
- d->backgroundPixmapExposed += viewRect;
- if (d->scene)
- d->scene->update(rect);
- }
- }
-}
-
-/*!
- \property QGraphicsView::interactive
- \brief whether the view allowed scene interaction.
-
- If enabled, this view is set to allow scene interaction. Otherwise, this
- view will not allow interaction, and any mouse or key events are ignored
- (i.e., it will act as a read-only view).
-
- By default, this property is true.
-*/
-bool QGraphicsView::isInteractive() const
-{
- Q_D(const QGraphicsView);
- return d->sceneInteractionAllowed;
-}
-void QGraphicsView::setInteractive(bool allowed)
-{
- Q_D(QGraphicsView);
- d->sceneInteractionAllowed = allowed;
-}
-
-/*!
- Returns a pointer to the scene that is currently visualized in the
- view. If no scene is currently visualized, 0 is returned.
-
- \sa setScene()
-*/
-QGraphicsScene *QGraphicsView::scene() const
-{
- Q_D(const QGraphicsView);
- return d->scene;
-}
-
-/*!
- Sets the current scene to \a scene. If \a scene is already being
- viewed, this function does nothing.
-
- When a scene is set on a view, the QGraphicsScene::changed() signal
- is automatically connected to this view's updateScene() slot, and the
- view's scroll bars are adjusted to fit the size of the scene.
-*/
-void QGraphicsView::setScene(QGraphicsScene *scene)
-{
- Q_D(QGraphicsView);
- if (d->scene == scene)
- return;
-
- // Always update the viewport when the scene changes.
- d->updateAll();
-
- // Remove the previously assigned scene.
- if (d->scene) {
- disconnect(d->scene, SIGNAL(changed(QList<QRectF>)),
- this, SLOT(updateScene(QList<QRectF>)));
- disconnect(d->scene, SIGNAL(sceneRectChanged(QRectF)),
- this, SLOT(updateSceneRect(QRectF)));
- d->scene->d_func()->removeView(this);
- d->connectedToScene = false;
-
- if (isActiveWindow() && isVisible()) {
- QEvent windowDeactivate(QEvent::WindowDeactivate);
- QApplication::sendEvent(d->scene, &windowDeactivate);
- }
- if(hasFocus())
- d->scene->clearFocus();
- }
-
- // Assign the new scene and update the contents (scrollbars, etc.)).
- if ((d->scene = scene)) {
- connect(d->scene, SIGNAL(sceneRectChanged(QRectF)),
- this, SLOT(updateSceneRect(QRectF)));
- d->updateSceneSlotReimplementedChecked = false;
- d->scene->d_func()->addView(this);
- d->recalculateContentSize();
- d->lastCenterPoint = sceneRect().center();
- d->keepLastCenterPoint = true;
- // We are only interested in mouse tracking if items accept
- // hover events or use non-default cursors.
- if (!d->scene->d_func()->allItemsIgnoreHoverEvents
- || !d->scene->d_func()->allItemsUseDefaultCursor) {
- d->viewport->setMouseTracking(true);
- }
-
- // enable touch events if any items is interested in them
- if (!d->scene->d_func()->allItemsIgnoreTouchEvents)
- d->viewport->setAttribute(Qt::WA_AcceptTouchEvents);
-
- if (isActiveWindow() && isVisible()) {
- QEvent windowActivate(QEvent::WindowActivate);
- QApplication::sendEvent(d->scene, &windowActivate);
- }
- } else {
- d->recalculateContentSize();
- }
-
- d->updateInputMethodSensitivity();
-
- if (d->scene && hasFocus())
- d->scene->setFocus();
-}
-
-/*!
- \property QGraphicsView::sceneRect
- \brief the area of the scene visualized by this view.
-
- The scene rectangle defines the extent of the scene, and in the view's case,
- this means the area of the scene that you can navigate using the scroll
- bars.
-
- If unset, or if a null QRectF is set, this property has the same value as
- QGraphicsScene::sceneRect, and it changes with
- QGraphicsScene::sceneRect. Otherwise, the view's scene rect is unaffected
- by the scene.
-
- Note that, although the scene supports a virtually unlimited size, the
- range of the scroll bars will never exceed the range of an integer
- (INT_MIN, INT_MAX). When the scene is larger than the scroll bars' values,
- you can choose to use translate() to navigate the scene instead.
-
- By default, this property contains a rectangle at the origin with zero
- width and height.
-
- \sa QGraphicsScene::sceneRect
-*/
-QRectF QGraphicsView::sceneRect() const
-{
- Q_D(const QGraphicsView);
- if (d->hasSceneRect)
- return d->sceneRect;
- if (d->scene)
- return d->scene->sceneRect();
- return QRectF();
-}
-void QGraphicsView::setSceneRect(const QRectF &rect)
-{
- Q_D(QGraphicsView);
- d->hasSceneRect = !rect.isNull();
- d->sceneRect = rect;
- d->recalculateContentSize();
-}
-
-/*!
- Returns the current transformation matrix for the view. If no current
- transformation is set, the identity matrix is returned.
-
- \sa setMatrix(), transform(), rotate(), scale(), shear(), translate()
-*/
-QMatrix QGraphicsView::matrix() const
-{
- Q_D(const QGraphicsView);
- return d->matrix.toAffine();
-}
-
-/*!
- Sets the view's current transformation matrix to \a matrix.
-
- If \a combine is true, then \a matrix is combined with the current matrix;
- otherwise, \a matrix \e replaces the current matrix. \a combine is false
- by default.
-
- The transformation matrix tranforms the scene into view coordinates. Using
- the default transformation, provided by the identity matrix, one pixel in
- the view represents one unit in the scene (e.g., a 10x10 rectangular item
- is drawn using 10x10 pixels in the view). If a 2x2 scaling matrix is
- applied, the scene will be drawn in 1:2 (e.g., a 10x10 rectangular item is
- then drawn using 20x20 pixels in the view).
-
- Example:
-
- \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsview.cpp 3
-
- To simplify interation with items using a transformed view, QGraphicsView
- provides mapTo... and mapFrom... functions that can translate between
- scene and view coordinates. For example, you can call mapToScene() to map
- a view coordinate to a floating point scene coordinate, or mapFromScene()
- to map from floating point scene coordinates to view coordinates.
-
- \sa matrix(), setTransform(), rotate(), scale(), shear(), translate()
-*/
-void QGraphicsView::setMatrix(const QMatrix &matrix, bool combine)
-{
- setTransform(QTransform(matrix), combine);
-}
-
-/*!
- Resets the view transformation matrix to the identity matrix.
-
- \sa resetTransform()
-*/
-void QGraphicsView::resetMatrix()
-{
- resetTransform();
-}
-
-/*!
- Rotates the current view transformation \a angle degrees clockwise.
-
- \sa setTransform(), transform(), scale(), shear(), translate()
-*/
-void QGraphicsView::rotate(qreal angle)
-{
- Q_D(QGraphicsView);
- QTransform matrix = d->matrix;
- matrix.rotate(angle);
- setTransform(matrix);
-}
-
-/*!
- Scales the current view transformation by (\a sx, \a sy).
-
- \sa setTransform(), transform(), rotate(), shear(), translate()
-*/
-void QGraphicsView::scale(qreal sx, qreal sy)
-{
- Q_D(QGraphicsView);
- QTransform matrix = d->matrix;
- matrix.scale(sx, sy);
- setTransform(matrix);
-}
-
-/*!
- Shears the current view transformation by (\a sh, \a sv).
-
- \sa setTransform(), transform(), rotate(), scale(), translate()
-*/
-void QGraphicsView::shear(qreal sh, qreal sv)
-{
- Q_D(QGraphicsView);
- QTransform matrix = d->matrix;
- matrix.shear(sh, sv);
- setTransform(matrix);
-}
-
-/*!
- Translates the current view transformation by (\a dx, \a dy).
-
- \sa setTransform(), transform(), rotate(), shear()
-*/
-void QGraphicsView::translate(qreal dx, qreal dy)
-{
- Q_D(QGraphicsView);
- QTransform matrix = d->matrix;
- matrix.translate(dx, dy);
- setTransform(matrix);
-}
-
-/*!
- Scrolls the contents of the viewport to ensure that the scene
- coordinate \a pos, is centered in the view.
-
- Because \a pos is a floating point coordinate, and the scroll bars operate
- on integer coordinates, the centering is only an approximation.
-
- \note If the item is close to or outside the border, it will be visible
- in the view, but not centered.
-
- \sa ensureVisible()
-*/
-void QGraphicsView::centerOn(const QPointF &pos)
-{
- Q_D(QGraphicsView);
- qreal width = viewport()->width();
- qreal height = viewport()->height();
- QPointF viewPoint = d->matrix.map(pos);
- QPointF oldCenterPoint = pos;
-
- if (!d->leftIndent) {
- if (isRightToLeft()) {
- qint64 horizontal = 0;
- horizontal += horizontalScrollBar()->minimum();
- horizontal += horizontalScrollBar()->maximum();
- horizontal -= int(viewPoint.x() - width / 2.0);
- horizontalScrollBar()->setValue(horizontal);
- } else {
- horizontalScrollBar()->setValue(int(viewPoint.x() - width / 2.0));
- }
- }
- if (!d->topIndent)
- verticalScrollBar()->setValue(int(viewPoint.y() - height / 2.0));
- d->lastCenterPoint = oldCenterPoint;
-}
-
-/*!
- \fn QGraphicsView::centerOn(qreal x, qreal y)
- \overload
-
- This function is provided for convenience. It's equivalent to calling
- centerOn(QPointF(\a x, \a y)).
-*/
-
-/*!
- \overload
-
- Scrolls the contents of the viewport to ensure that \a item
- is centered in the view.
-
- \sa ensureVisible()
-*/
-void QGraphicsView::centerOn(const QGraphicsItem *item)
-{
- centerOn(item->sceneBoundingRect().center());
-}
-
-/*!
- Scrolls the contents of the viewport so that the scene rectangle \a rect
- is visible, with margins specified in pixels by \a xmargin and \a
- ymargin. If the specified rect cannot be reached, the contents are
- scrolled to the nearest valid position. The default value for both margins
- is 50 pixels.
-
- \sa centerOn()
-*/
-void QGraphicsView::ensureVisible(const QRectF &rect, int xmargin, int ymargin)
-{
- Q_D(QGraphicsView);
- qreal width = viewport()->width();
- qreal height = viewport()->height();
- QRectF viewRect = d->matrix.mapRect(rect);
-
- qreal left = d->horizontalScroll();
- qreal right = left + width;
- qreal top = d->verticalScroll();
- qreal bottom = top + height;
-
- if (viewRect.left() <= left + xmargin) {
- // need to scroll from the left
- if (!d->leftIndent)
- horizontalScrollBar()->setValue(int(viewRect.left() - xmargin - 0.5));
- }
- if (viewRect.right() >= right - xmargin) {
- // need to scroll from the right
- if (!d->leftIndent)
- horizontalScrollBar()->setValue(int(viewRect.right() - width + xmargin + 0.5));
- }
- if (viewRect.top() <= top + ymargin) {
- // need to scroll from the top
- if (!d->topIndent)
- verticalScrollBar()->setValue(int(viewRect.top() - ymargin - 0.5));
- }
- if (viewRect.bottom() >= bottom - ymargin) {
- // need to scroll from the bottom
- if (!d->topIndent)
- verticalScrollBar()->setValue(int(viewRect.bottom() - height + ymargin + 0.5));
- }
-}
-
-/*!
- \fn QGraphicsView::ensureVisible(qreal x, qreal y, qreal w, qreal h,
- int xmargin, int ymargin)
- \overload
-
- This function is provided for convenience. It's equivalent to calling
- ensureVisible(QRectF(\a x, \a y, \a w, \a h), \a xmargin, \a ymargin).
-*/
-
-/*!
- \overload
-
- Scrolls the contents of the viewport so that the center of item \a item is
- visible, with margins specified in pixels by \a xmargin and \a ymargin. If
- the specified point cannot be reached, the contents are scrolled to the
- nearest valid position. The default value for both margins is 50 pixels.
-
- \sa centerOn()
-*/
-void QGraphicsView::ensureVisible(const QGraphicsItem *item, int xmargin, int ymargin)
-{
- ensureVisible(item->sceneBoundingRect(), xmargin, ymargin);
-}
-
-/*!
- Scales the view matrix and scrolls the scroll bars to ensure that the
- scene rectangle \a rect fits inside the viewport. \a rect must be inside
- the scene rect; otherwise, fitInView() cannot guarantee that the whole
- rect is visible.
-
- This function keeps the view's rotation, translation, or shear. The view
- is scaled according to \a aspectRatioMode. \a rect will be centered in the
- view if it does not fit tightly.
-
- It's common to call fitInView() from inside a reimplementation of
- resizeEvent(), to ensure that the whole scene, or parts of the scene,
- scales automatically to fit the new size of the viewport as the view is
- resized. Note though, that calling fitInView() from inside resizeEvent()
- can lead to unwanted resize recursion, if the new transformation toggles
- the automatic state of the scrollbars. You can toggle the scrollbar
- policies to always on or always off to prevent this (see
- horizontalScrollBarPolicy() and verticalScrollBarPolicy()).
-
- If \a rect is empty, or if the viewport is too small, this
- function will do nothing.
-
- \sa setTransform(), ensureVisible(), centerOn()
-*/
-void QGraphicsView::fitInView(const QRectF &rect, Qt::AspectRatioMode aspectRatioMode)
-{
- Q_D(QGraphicsView);
- if (!d->scene || rect.isNull())
- return;
-
- // Reset the view scale to 1:1.
- QRectF unity = d->matrix.mapRect(QRectF(0, 0, 1, 1));
- if (unity.isEmpty())
- return;
- scale(1 / unity.width(), 1 / unity.height());
-
- // Find the ideal x / y scaling ratio to fit \a rect in the view.
- int margin = 2;
- QRectF viewRect = viewport()->rect().adjusted(margin, margin, -margin, -margin);
- if (viewRect.isEmpty())
- return;
- QRectF sceneRect = d->matrix.mapRect(rect);
- if (sceneRect.isEmpty())
- return;
- qreal xratio = viewRect.width() / sceneRect.width();
- qreal yratio = viewRect.height() / sceneRect.height();
-
- // Respect the aspect ratio mode.
- switch (aspectRatioMode) {
- case Qt::KeepAspectRatio:
- xratio = yratio = qMin(xratio, yratio);
- break;
- case Qt::KeepAspectRatioByExpanding:
- xratio = yratio = qMax(xratio, yratio);
- break;
- case Qt::IgnoreAspectRatio:
- break;
- }
-
- // Scale and center on the center of \a rect.
- scale(xratio, yratio);
- centerOn(rect.center());
-}
-
-/*!
- \fn void QGraphicsView::fitInView(qreal x, qreal y, qreal w, qreal h,
- Qt::AspectRatioMode aspectRatioMode = Qt::IgnoreAspectRatio)
-
- \overload
-
- This convenience function is equivalent to calling
- fitInView(QRectF(\a x, \a y, \a w, \a h), \a aspectRatioMode).
-
- \sa ensureVisible(), centerOn()
-*/
-
-/*!
- \overload
-
- Ensures that \a item fits tightly inside the view, scaling the view
- according to \a aspectRatioMode.
-
- \sa ensureVisible(), centerOn()
-*/
-void QGraphicsView::fitInView(const QGraphicsItem *item, Qt::AspectRatioMode aspectRatioMode)
-{
- QPainterPath path = item->isClipped() ? item->clipPath() : item->shape();
- if (item->d_ptr->hasTranslateOnlySceneTransform()) {
- path.translate(item->d_ptr->sceneTransform.dx(), item->d_ptr->sceneTransform.dy());
- fitInView(path.boundingRect(), aspectRatioMode);
- } else {
- fitInView(item->d_ptr->sceneTransform.map(path).boundingRect(), aspectRatioMode);
- }
-}
-
-/*!
- Renders the \a source rect, which is in view coordinates, from the scene
- into \a target, which is in paint device coordinates, using \a
- painter. This function is useful for capturing the contents of the view
- onto a paint device, such as a QImage (e.g., to take a screenshot), or for
- printing to QPrinter. For example:
-
- \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsview.cpp 4
-
- If \a source is a null rect, this function will use viewport()->rect() to
- determine what to draw. If \a target is a null rect, the full dimensions
- of \a painter's paint device (e.g., for a QPrinter, the page size) will be
- used.
-
- The source rect contents will be transformed according to \a
- aspectRatioMode to fit into the target rect. By default, the aspect ratio
- is kept, and \a source is scaled to fit in \a target.
-
- \sa QGraphicsScene::render()
-*/
-void QGraphicsView::render(QPainter *painter, const QRectF &target, const QRect &source,
- Qt::AspectRatioMode aspectRatioMode)
-{
- // ### Switch to using the recursive rendering algorithm instead.
-
- Q_D(QGraphicsView);
- if (!d->scene || !(painter && painter->isActive()))
- return;
-
- // Default source rect = viewport rect
- QRect sourceRect = source;
- if (source.isNull())
- sourceRect = viewport()->rect();
-
- // Default target rect = device rect
- QRectF targetRect = target;
- if (target.isNull()) {
- if (painter->device()->devType() == QInternal::Picture)
- targetRect = sourceRect;
- else
- targetRect.setRect(0, 0, painter->device()->width(), painter->device()->height());
- }
-
- // Find the ideal x / y scaling ratio to fit \a source into \a target.
- qreal xratio = targetRect.width() / sourceRect.width();
- qreal yratio = targetRect.height() / sourceRect.height();
-
- // Scale according to the aspect ratio mode.
- switch (aspectRatioMode) {
- case Qt::KeepAspectRatio:
- xratio = yratio = qMin(xratio, yratio);
- break;
- case Qt::KeepAspectRatioByExpanding:
- xratio = yratio = qMax(xratio, yratio);
- break;
- case Qt::IgnoreAspectRatio:
- break;
- }
-
- // Find all items to draw, and reverse the list (we want to draw
- // in reverse order).
- QPolygonF sourceScenePoly = mapToScene(sourceRect.adjusted(-1, -1, 1, 1));
- QList<QGraphicsItem *> itemList = d->scene->items(sourceScenePoly,
- Qt::IntersectsItemBoundingRect);
- QGraphicsItem **itemArray = new QGraphicsItem *[itemList.size()];
- int numItems = itemList.size();
- for (int i = 0; i < numItems; ++i)
- itemArray[numItems - i - 1] = itemList.at(i);
- itemList.clear();
-
- // Setup painter matrix.
- QTransform moveMatrix = QTransform::fromTranslate(-d->horizontalScroll(), -d->verticalScroll());
- QTransform painterMatrix = d->matrix * moveMatrix;
- painterMatrix *= QTransform()
- .translate(targetRect.left(), targetRect.top())
- .scale(xratio, yratio)
- .translate(-sourceRect.left(), -sourceRect.top());
-
- // Generate the style options
- QStyleOptionGraphicsItem *styleOptionArray = d->allocStyleOptionsArray(numItems);
- for (int i = 0; i < numItems; ++i)
- itemArray[i]->d_ptr->initStyleOption(&styleOptionArray[i], painterMatrix, targetRect.toRect());
-
- painter->save();
-
- // Clip in device coordinates to avoid QRegion transformations.
- painter->setClipRect(targetRect);
- QPainterPath path;
- path.addPolygon(sourceScenePoly);
- path.closeSubpath();
- painter->setClipPath(painterMatrix.map(path), Qt::IntersectClip);
-
- // Transform the painter.
- painter->setTransform(painterMatrix, true);
-
- // Render the scene.
- QRectF sourceSceneRect = sourceScenePoly.boundingRect();
- drawBackground(painter, sourceSceneRect);
- drawItems(painter, numItems, itemArray, styleOptionArray);
- drawForeground(painter, sourceSceneRect);
-
- delete [] itemArray;
- d->freeStyleOptionsArray(styleOptionArray);
-
- painter->restore();
-}
-
-/*!
- Returns a list of all the items in the associated scene, in descending
- stacking order (i.e., the first item in the returned list is the uppermost
- item).
-
- \sa QGraphicsScene::items(), {QGraphicsItem#Sorting}{Sorting}
-*/
-QList<QGraphicsItem *> QGraphicsView::items() const
-{
- Q_D(const QGraphicsView);
- if (!d->scene)
- return QList<QGraphicsItem *>();
- return d->scene->items();
-}
-
-/*!
- Returns a list of all the items at the position \a pos in the view. The
- items are listed in descending stacking order (i.e., the first item in the
- list is the uppermost item, and the last item is the lowermost item). \a
- pos is in viewport coordinates.
-
- This function is most commonly called from within mouse event handlers in
- a subclass in QGraphicsView. \a pos is in untransformed viewport
- coordinates, just like QMouseEvent::pos().
-
- \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsview.cpp 5
-
- \sa QGraphicsScene::items(), {QGraphicsItem#Sorting}{Sorting}
-*/
-QList<QGraphicsItem *> QGraphicsView::items(const QPoint &pos) const
-{
- Q_D(const QGraphicsView);
- if (!d->scene)
- return QList<QGraphicsItem *>();
- // ### Unify these two, and use the items(QPointF) version in
- // QGraphicsScene instead. The scene items function could use the viewport
- // transform to map the point to a rect/polygon.
- if ((d->identityMatrix || d->matrix.type() <= QTransform::TxScale)) {
- // Use the rect version
- QTransform xinv = viewportTransform().inverted();
- return d->scene->items(xinv.mapRect(QRectF(pos.x(), pos.y(), 1, 1)),
- Qt::IntersectsItemShape,
- Qt::DescendingOrder,
- viewportTransform());
- }
- // Use the polygon version
- return d->scene->items(mapToScene(pos.x(), pos.y(), 1, 1),
- Qt::IntersectsItemShape,
- Qt::DescendingOrder,
- viewportTransform());
-}
-
-/*!
- \fn QGraphicsView::items(int x, int y) const
-
- This function is provided for convenience. It's equivalent to calling
- items(QPoint(\a x, \a y)).
-*/
-
-/*!
- \overload
-
- Returns a list of all the items that, depending on \a mode, are either
- contained by or intersect with \a rect. \a rect is in viewport
- coordinates.
-
- The default value for \a mode is Qt::IntersectsItemShape; all items whose
- exact shape intersects with or is contained by \a rect are returned.
-
- The items are sorted in descending stacking order (i.e., the first item in
- the returned list is the uppermost item).
-
- \sa itemAt(), items(), mapToScene(), {QGraphicsItem#Sorting}{Sorting}
-*/
-QList<QGraphicsItem *> QGraphicsView::items(const QRect &rect, Qt::ItemSelectionMode mode) const
-{
- Q_D(const QGraphicsView);
- if (!d->scene)
- return QList<QGraphicsItem *>();
- return d->scene->items(mapToScene(rect), mode, Qt::DescendingOrder, viewportTransform());
-}
-
-/*!
- \fn QList<QGraphicsItem *> QGraphicsView::items(int x, int y, int w, int h, Qt::ItemSelectionMode mode) const
- \since 4.3
-
- This convenience function is equivalent to calling items(QRectF(\a x, \a
- y, \a w, \a h), \a mode).
-*/
-
-/*!
- \overload
-
- Returns a list of all the items that, depending on \a mode, are either
- contained by or intersect with \a polygon. \a polygon is in viewport
- coordinates.
-
- The default value for \a mode is Qt::IntersectsItemShape; all items whose
- exact shape intersects with or is contained by \a polygon are returned.
-
- The items are sorted by descending stacking order (i.e., the first item in
- the returned list is the uppermost item).
-
- \sa itemAt(), items(), mapToScene(), {QGraphicsItem#Sorting}{Sorting}
-*/
-QList<QGraphicsItem *> QGraphicsView::items(const QPolygon &polygon, Qt::ItemSelectionMode mode) const
-{
- Q_D(const QGraphicsView);
- if (!d->scene)
- return QList<QGraphicsItem *>();
- return d->scene->items(mapToScene(polygon), mode, Qt::DescendingOrder, viewportTransform());
-}
-
-/*!
- \overload
-
- Returns a list of all the items that, depending on \a mode, are either
- contained by or intersect with \a path. \a path is in viewport
- coordinates.
-
- The default value for \a mode is Qt::IntersectsItemShape; all items whose
- exact shape intersects with or is contained by \a path are returned.
-
- \sa itemAt(), items(), mapToScene(), {QGraphicsItem#Sorting}{Sorting}
-*/
-QList<QGraphicsItem *> QGraphicsView::items(const QPainterPath &path, Qt::ItemSelectionMode mode) const
-{
- Q_D(const QGraphicsView);
- if (!d->scene)
- return QList<QGraphicsItem *>();
- return d->scene->items(mapToScene(path), mode, Qt::DescendingOrder, viewportTransform());
-}
-
-/*!
- Returns the item at position \a pos, which is in viewport coordinates.
- If there are several items at this position, this function returns
- the topmost item.
-
- Example:
-
- \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsview.cpp 6
-
- \sa items(), {QGraphicsItem#Sorting}{Sorting}
-*/
-QGraphicsItem *QGraphicsView::itemAt(const QPoint &pos) const
-{
- Q_D(const QGraphicsView);
- if (!d->scene)
- return 0;
- QList<QGraphicsItem *> itemsAtPos = items(pos);
- return itemsAtPos.isEmpty() ? 0 : itemsAtPos.first();
-}
-
-/*!
- \overload
- \fn QGraphicsItem *QGraphicsView::itemAt(int x, int y) const
-
- This function is provided for convenience. It's equivalent to
- calling itemAt(QPoint(\a x, \a y)).
-*/
-
-/*!
- Returns the viewport coordinate \a point mapped to scene coordinates.
-
- Note: It can be useful to map the whole rectangle covered by the pixel at
- \a point instead of the point itself. To do this, you can call
- mapToScene(QRect(\a point, QSize(2, 2))).
-
- \sa mapFromScene()
-*/
-QPointF QGraphicsView::mapToScene(const QPoint &point) const
-{
- Q_D(const QGraphicsView);
- QPointF p = point;
- p.rx() += d->horizontalScroll();
- p.ry() += d->verticalScroll();
- return d->identityMatrix ? p : d->matrix.inverted().map(p);
-}
-
-/*!
- \fn QGraphicsView::mapToScene(int x, int y) const
-
- This function is provided for convenience. It's equivalent to calling
- mapToScene(QPoint(\a x, \a y)).
-*/
-
-/*!
- Returns the viewport rectangle \a rect mapped to a scene coordinate
- polygon.
-
- \sa mapFromScene()
-*/
-QPolygonF QGraphicsView::mapToScene(const QRect &rect) const
-{
- Q_D(const QGraphicsView);
- if (!rect.isValid())
- return QPolygonF();
-
- QPointF scrollOffset(d->horizontalScroll(), d->verticalScroll());
- QRect r = rect.adjusted(0, 0, 1, 1);
- QPointF tl = scrollOffset + r.topLeft();
- QPointF tr = scrollOffset + r.topRight();
- QPointF br = scrollOffset + r.bottomRight();
- QPointF bl = scrollOffset + r.bottomLeft();
-
- QPolygonF poly(4);
- if (!d->identityMatrix) {
- QTransform x = d->matrix.inverted();
- poly[0] = x.map(tl);
- poly[1] = x.map(tr);
- poly[2] = x.map(br);
- poly[3] = x.map(bl);
- } else {
- poly[0] = tl;
- poly[1] = tr;
- poly[2] = br;
- poly[3] = bl;
- }
- return poly;
-}
-
-/*!
- \fn QGraphicsView::mapToScene(int x, int y, int w, int h) const
-
- This function is provided for convenience. It's equivalent to calling
- mapToScene(QRect(\a x, \a y, \a w, \a h)).
-*/
-
-/*!
- Returns the viewport polygon \a polygon mapped to a scene coordinate
- polygon.
-
- \sa mapFromScene()
-*/
-QPolygonF QGraphicsView::mapToScene(const QPolygon &polygon) const
-{
- QPolygonF poly;
- foreach (const QPoint &point, polygon)
- poly << mapToScene(point);
- return poly;
-}
-
-/*!
- Returns the viewport painter path \a path mapped to a scene coordinate
- painter path.
-
- \sa mapFromScene()
-*/
-QPainterPath QGraphicsView::mapToScene(const QPainterPath &path) const
-{
- Q_D(const QGraphicsView);
- QTransform matrix = QTransform::fromTranslate(d->horizontalScroll(), d->verticalScroll());
- matrix *= d->matrix.inverted();
- return matrix.map(path);
-}
-
-/*!
- Returns the scene coordinate \a point to viewport coordinates.
-
- \sa mapToScene()
-*/
-QPoint QGraphicsView::mapFromScene(const QPointF &point) const
-{
- Q_D(const QGraphicsView);
- QPointF p = d->identityMatrix ? point : d->matrix.map(point);
- p.rx() -= d->horizontalScroll();
- p.ry() -= d->verticalScroll();
- return p.toPoint();
-}
-
-/*!
- \fn QGraphicsView::mapFromScene(qreal x, qreal y) const
-
- This function is provided for convenience. It's equivalent to
- calling mapFromScene(QPointF(\a x, \a y)).
-*/
-
-/*!
- Returns the scene rectangle \a rect to a viewport coordinate
- polygon.
-
- \sa mapToScene()
-*/
-QPolygon QGraphicsView::mapFromScene(const QRectF &rect) const
-{
- Q_D(const QGraphicsView);
- QPointF tl;
- QPointF tr;
- QPointF br;
- QPointF bl;
- if (!d->identityMatrix) {
- const QTransform &x = d->matrix;
- tl = x.map(rect.topLeft());
- tr = x.map(rect.topRight());
- br = x.map(rect.bottomRight());
- bl = x.map(rect.bottomLeft());
- } else {
- tl = rect.topLeft();
- tr = rect.topRight();
- br = rect.bottomRight();
- bl = rect.bottomLeft();
- }
- QPointF scrollOffset(d->horizontalScroll(), d->verticalScroll());
- tl -= scrollOffset;
- tr -= scrollOffset;
- br -= scrollOffset;
- bl -= scrollOffset;
-
- QPolygon poly(4);
- poly[0] = tl.toPoint();
- poly[1] = tr.toPoint();
- poly[2] = br.toPoint();
- poly[3] = bl.toPoint();
- return poly;
-}
-
-/*!
- \fn QGraphicsView::mapFromScene(qreal x, qreal y, qreal w, qreal h) const
-
- This function is provided for convenience. It's equivalent to
- calling mapFromScene(QRectF(\a x, \a y, \a w, \a h)).
-*/
-
-/*!
- Returns the scene coordinate polygon \a polygon to a viewport coordinate
- polygon.
-
- \sa mapToScene()
-*/
-QPolygon QGraphicsView::mapFromScene(const QPolygonF &polygon) const
-{
- QPolygon poly;
- foreach (const QPointF &point, polygon)
- poly << mapFromScene(point);
- return poly;
-}
-
-/*!
- Returns the scene coordinate painter path \a path to a viewport coordinate
- painter path.
-
- \sa mapToScene()
-*/
-QPainterPath QGraphicsView::mapFromScene(const QPainterPath &path) const
-{
- Q_D(const QGraphicsView);
- QTransform matrix = d->matrix;
- matrix *= QTransform::fromTranslate(-d->horizontalScroll(), -d->verticalScroll());
- return matrix.map(path);
-}
-
-/*!
- \reimp
-*/
-QVariant QGraphicsView::inputMethodQuery(Qt::InputMethodQuery query) const
-{
- Q_D(const QGraphicsView);
- if (!d->scene)
- return QVariant();
-
- QVariant value = d->scene->inputMethodQuery(query);
- if (value.type() == QVariant::RectF)
- value = d->mapRectFromScene(value.toRectF());
- else if (value.type() == QVariant::PointF)
- value = mapFromScene(value.toPointF());
- else if (value.type() == QVariant::Rect)
- value = d->mapRectFromScene(value.toRect()).toRect();
- else if (value.type() == QVariant::Point)
- value = mapFromScene(value.toPoint());
- return value;
-}
-
-/*!
- \property QGraphicsView::backgroundBrush
- \brief the background brush of the scene.
-
- This property sets the background brush for the scene in this view. It is
- used to override the scene's own background, and defines the behavior of
- drawBackground(). To provide custom background drawing for this view, you
- can reimplement drawBackground() instead.
-
- By default, this property contains a brush with the Qt::NoBrush pattern.
-
- \sa QGraphicsScene::backgroundBrush, foregroundBrush
-*/
-QBrush QGraphicsView::backgroundBrush() const
-{
- Q_D(const QGraphicsView);
- return d->backgroundBrush;
-}
-void QGraphicsView::setBackgroundBrush(const QBrush &brush)
-{
- Q_D(QGraphicsView);
- d->backgroundBrush = brush;
- d->updateAll();
-
- if (d->cacheMode & CacheBackground) {
- // Invalidate the background pixmap
- d->mustResizeBackgroundPixmap = true;
- }
-}
-
-/*!
- \property QGraphicsView::foregroundBrush
- \brief the foreground brush of the scene.
-
- This property sets the foreground brush for the scene in this view. It is
- used to override the scene's own foreground, and defines the behavior of
- drawForeground(). To provide custom foreground drawing for this view, you
- can reimplement drawForeground() instead.
-
- By default, this property contains a brush with the Qt::NoBrush pattern.
-
- \sa QGraphicsScene::foregroundBrush, backgroundBrush
-*/
-QBrush QGraphicsView::foregroundBrush() const
-{
- Q_D(const QGraphicsView);
- return d->foregroundBrush;
-}
-void QGraphicsView::setForegroundBrush(const QBrush &brush)
-{
- Q_D(QGraphicsView);
- d->foregroundBrush = brush;
- d->updateAll();
-}
-
-/*!
- Schedules an update of the scene rectangles \a rects.
-
- \sa QGraphicsScene::changed()
-*/
-void QGraphicsView::updateScene(const QList<QRectF> &rects)
-{
- // ### Note: Since 4.5, this slot is only called if the user explicitly
- // establishes a connection between the scene and the view, as the scene
- // and view are no longer connected. We need to keep it working (basically
- // leave it as it is), but the new delivery path is through
- // QGraphicsScenePrivate::itemUpdate().
- Q_D(QGraphicsView);
- if (d->fullUpdatePending || d->viewportUpdateMode == QGraphicsView::NoViewportUpdate)
- return;
-
- // Extract and reset dirty scene rect info.
- QVector<QRect> dirtyViewportRects;
- const QVector<QRect> &dirtyRects = d->dirtyRegion.rects();
- for (int i = 0; i < dirtyRects.size(); ++i)
- dirtyViewportRects += dirtyRects.at(i);
- d->dirtyRegion = QRegion();
- d->dirtyBoundingRect = QRect();
-
- bool fullUpdate = !d->accelerateScrolling || d->viewportUpdateMode == QGraphicsView::FullViewportUpdate;
- bool boundingRectUpdate = (d->viewportUpdateMode == QGraphicsView::BoundingRectViewportUpdate)
- || (d->viewportUpdateMode == QGraphicsView::SmartViewportUpdate
- && ((dirtyViewportRects.size() + rects.size()) >= QGRAPHICSVIEW_REGION_RECT_THRESHOLD));
-
- QRegion updateRegion;
- QRect boundingRect;
- QRect viewportRect = viewport()->rect();
- bool redraw = false;
- QTransform transform = viewportTransform();
-
- // Convert scene rects to viewport rects.
- foreach (const QRectF &rect, rects) {
- QRect xrect = transform.mapRect(rect).toAlignedRect();
- if (!(d->optimizationFlags & DontAdjustForAntialiasing))
- xrect.adjust(-2, -2, 2, 2);
- else
- xrect.adjust(-1, -1, 1, 1);
- if (!viewportRect.intersects(xrect))
- continue;
- dirtyViewportRects << xrect;
- }
-
- foreach (const QRect &rect, dirtyViewportRects) {
- // Add the exposed rect to the update region. In rect update
- // mode, we only count the bounding rect of items.
- if (!boundingRectUpdate) {
- updateRegion += rect;
- } else {
- boundingRect |= rect;
- }
- redraw = true;
- if (fullUpdate) {
- // If fullUpdate is true and we found a visible dirty rect,
- // we're done.
- break;
- }
- }
-
- if (!redraw)
- return;
-
- if (fullUpdate)
- viewport()->update();
- else if (boundingRectUpdate)
- viewport()->update(boundingRect);
- else
- viewport()->update(updateRegion);
-}
-
-/*!
- Notifies QGraphicsView that the scene's scene rect has changed. \a rect
- is the new scene rect. If the view already has an explicitly set scene
- rect, this function does nothing.
-
- \sa sceneRect, QGraphicsScene::sceneRectChanged()
-*/
-void QGraphicsView::updateSceneRect(const QRectF &rect)
-{
- Q_D(QGraphicsView);
- if (!d->hasSceneRect) {
- d->sceneRect = rect;
- d->recalculateContentSize();
- }
-}
-
-/*!
- This slot is called by QAbstractScrollArea after setViewport() has been
- called. Reimplement this function in a subclass of QGraphicsView to
- initialize the new viewport \a widget before it is used.
-
- \sa setViewport()
-*/
-void QGraphicsView::setupViewport(QWidget *widget)
-{
- Q_D(QGraphicsView);
-
- if (!widget) {
- qWarning("QGraphicsView::setupViewport: cannot initialize null widget");
- return;
- }
-
- const bool isGLWidget = widget->inherits("QGLWidget");
-
- d->accelerateScrolling = !(isGLWidget);
-
- widget->setFocusPolicy(Qt::StrongFocus);
-
- if (!isGLWidget) {
- // autoFillBackground enables scroll acceleration.
- widget->setAutoFillBackground(true);
- }
-
- // We are only interested in mouse tracking if items
- // accept hover events or use non-default cursors or if
- // AnchorUnderMouse is used as transformation or resize anchor.
- if ((d->scene && (!d->scene->d_func()->allItemsIgnoreHoverEvents
- || !d->scene->d_func()->allItemsUseDefaultCursor))
- || d->transformationAnchor == AnchorUnderMouse
- || d->resizeAnchor == AnchorUnderMouse) {
- widget->setMouseTracking(true);
- }
-
- // enable touch events if any items is interested in them
- if (d->scene && !d->scene->d_func()->allItemsIgnoreTouchEvents)
- widget->setAttribute(Qt::WA_AcceptTouchEvents);
-
-#ifndef QT_NO_GESTURES
- if (d->scene) {
- foreach (Qt::GestureType gesture, d->scene->d_func()->grabbedGestures.keys())
- widget->grabGesture(gesture);
- }
-#endif
-
- widget->setAcceptDrops(acceptDrops());
-}
-
-/*!
- \reimp
-*/
-bool QGraphicsView::event(QEvent *event)
-{
- Q_D(QGraphicsView);
-
- if (d->sceneInteractionAllowed) {
- switch (event->type()) {
- case QEvent::ShortcutOverride:
- if (d->scene)
- return QApplication::sendEvent(d->scene, event);
- break;
- case QEvent::KeyPress:
- if (d->scene) {
- QKeyEvent *k = static_cast<QKeyEvent *>(event);
- if (k->key() == Qt::Key_Tab || k->key() == Qt::Key_Backtab) {
- // Send the key events to the scene. This will invoke the
- // scene's tab focus handling, and if the event is
- // accepted, we return (prevent further event delivery),
- // and the base implementation will call QGraphicsView's
- // focusNextPrevChild() function. If the event is ignored,
- // we fall back to standard tab focus handling.
- QApplication::sendEvent(d->scene, event);
- if (event->isAccepted())
- return true;
- // Ensure the event doesn't propagate just because the
- // scene ignored it. If the event propagates, then tab
- // handling will be called twice (this and parent).
- event->accept();
- }
- }
- break;
- default:
- break;
- }
- }
-
- return QAbstractScrollArea::event(event);
-}
-
-/*!
- \reimp
-*/
-bool QGraphicsView::viewportEvent(QEvent *event)
-{
- Q_D(QGraphicsView);
- if (!d->scene)
- return QAbstractScrollArea::viewportEvent(event);
-
- switch (event->type()) {
- case QEvent::Enter:
- QApplication::sendEvent(d->scene, event);
- break;
- case QEvent::WindowActivate:
- QApplication::sendEvent(d->scene, event);
- break;
- case QEvent::WindowDeactivate:
- // ### This is a temporary fix for until we get proper mouse
- // grab events. mouseGrabberItem should be set to 0 if we lose
- // the mouse grab.
- // Remove all popups when the scene loses focus.
- if (!d->scene->d_func()->popupWidgets.isEmpty())
- d->scene->d_func()->removePopup(d->scene->d_func()->popupWidgets.first());
- QApplication::sendEvent(d->scene, event);
- break;
- case QEvent::Show:
- if (d->scene && isActiveWindow()) {
- QEvent windowActivate(QEvent::WindowActivate);
- QApplication::sendEvent(d->scene, &windowActivate);
- }
- break;
- case QEvent::Hide:
- // spontaneous event will generate a WindowDeactivate.
- if (!event->spontaneous() && d->scene && isActiveWindow()) {
- QEvent windowDeactivate(QEvent::WindowDeactivate);
- QApplication::sendEvent(d->scene, &windowDeactivate);
- }
- break;
- case QEvent::Leave:
- // ### This is a temporary fix for until we get proper mouse grab
- // events. activeMouseGrabberItem should be set to 0 if we lose the
- // mouse grab.
- if ((QApplication::activePopupWidget() && QApplication::activePopupWidget() != window())
- || (QApplication::activeModalWidget() && QApplication::activeModalWidget() != window())
- || (QApplication::activeWindow() != window())) {
- if (!d->scene->d_func()->popupWidgets.isEmpty())
- d->scene->d_func()->removePopup(d->scene->d_func()->popupWidgets.first());
- }
- d->useLastMouseEvent = false;
- // a hack to pass a viewport pointer to the scene inside the leave event
- Q_ASSERT(event->d == 0);
- event->d = reinterpret_cast<QEventPrivate *>(viewport());
- QApplication::sendEvent(d->scene, event);
- break;
-#ifndef QT_NO_TOOLTIP
- case QEvent::ToolTip: {
- QHelpEvent *toolTip = static_cast<QHelpEvent *>(event);
- QGraphicsSceneHelpEvent helpEvent(QEvent::GraphicsSceneHelp);
- helpEvent.setWidget(viewport());
- helpEvent.setScreenPos(toolTip->globalPos());
- helpEvent.setScenePos(mapToScene(toolTip->pos()));
- QApplication::sendEvent(d->scene, &helpEvent);
- toolTip->setAccepted(helpEvent.isAccepted());
- return true;
- }
-#endif
- case QEvent::Paint:
- // Reset full update
- d->fullUpdatePending = false;
- d->dirtyScrollOffset = QPoint();
- if (d->scene) {
- // Check if this view reimplements the updateScene slot; if it
- // does, we can't do direct update delivery and have to fall back
- // to connecting the changed signal.
- if (!d->updateSceneSlotReimplementedChecked) {
- d->updateSceneSlotReimplementedChecked = true;
- const QMetaObject *mo = metaObject();
- if (mo != &QGraphicsView::staticMetaObject) {
- if (mo->indexOfSlot("updateScene(QList<QRectF>)")
- != QGraphicsView::staticMetaObject.indexOfSlot("updateScene(QList<QRectF>)")) {
- connect(d->scene, SIGNAL(changed(QList<QRectF>)),
- this, SLOT(updateScene(QList<QRectF>)));
- }
- }
- }
- }
- break;
- case QEvent::TouchBegin:
- case QEvent::TouchUpdate:
- case QEvent::TouchEnd:
- {
- if (!isEnabled())
- return false;
-
- if (d->scene && d->sceneInteractionAllowed) {
- // Convert and deliver the touch event to the scene.
- QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event);
- touchEvent->setWidget(viewport());
- QGraphicsViewPrivate::translateTouchEvent(d, touchEvent);
- (void) QApplication::sendEvent(d->scene, touchEvent);
- }
-
- return true;
- }
-#ifndef QT_NO_GESTURES
- case QEvent::Gesture:
- case QEvent::GestureOverride:
- {
- if (!isEnabled())
- return false;
-
- if (d->scene && d->sceneInteractionAllowed) {
- QGestureEvent *gestureEvent = static_cast<QGestureEvent *>(event);
- gestureEvent->setWidget(viewport());
- (void) QApplication::sendEvent(d->scene, gestureEvent);
- }
- return true;
- }
-#endif // QT_NO_GESTURES
- default:
- break;
- }
-
- return QAbstractScrollArea::viewportEvent(event);
-}
-
-#ifndef QT_NO_CONTEXTMENU
-/*!
- \reimp
-*/
-void QGraphicsView::contextMenuEvent(QContextMenuEvent *event)
-{
- Q_D(QGraphicsView);
- if (!d->scene || !d->sceneInteractionAllowed)
- return;
-
- d->mousePressViewPoint = event->pos();
- d->mousePressScenePoint = mapToScene(d->mousePressViewPoint);
- d->mousePressScreenPoint = event->globalPos();
- d->lastMouseMoveScenePoint = d->mousePressScenePoint;
- d->lastMouseMoveScreenPoint = d->mousePressScreenPoint;
-
- QGraphicsSceneContextMenuEvent contextEvent(QEvent::GraphicsSceneContextMenu);
- contextEvent.setWidget(viewport());
- contextEvent.setScenePos(d->mousePressScenePoint);
- contextEvent.setScreenPos(d->mousePressScreenPoint);
- contextEvent.setModifiers(event->modifiers());
- contextEvent.setReason((QGraphicsSceneContextMenuEvent::Reason)(event->reason()));
- contextEvent.setAccepted(event->isAccepted());
- QApplication::sendEvent(d->scene, &contextEvent);
- event->setAccepted(contextEvent.isAccepted());
-}
-#endif // QT_NO_CONTEXTMENU
-
-/*!
- \reimp
-*/
-void QGraphicsView::dropEvent(QDropEvent *event)
-{
-#ifndef QT_NO_DRAGANDDROP
- Q_D(QGraphicsView);
- if (!d->scene || !d->sceneInteractionAllowed)
- return;
-
- // Generate a scene event.
- QGraphicsSceneDragDropEvent sceneEvent(QEvent::GraphicsSceneDrop);
- d->populateSceneDragDropEvent(&sceneEvent, event);
-
- // Send it to the scene.
- QApplication::sendEvent(d->scene, &sceneEvent);
-
- // Accept the originating event if the scene accepted the scene event.
- event->setAccepted(sceneEvent.isAccepted());
- if (sceneEvent.isAccepted())
- event->setDropAction(sceneEvent.dropAction());
-
- delete d->lastDragDropEvent;
- d->lastDragDropEvent = 0;
-
-#else
- Q_UNUSED(event)
-#endif
-}
-
-/*!
- \reimp
-*/
-void QGraphicsView::dragEnterEvent(QDragEnterEvent *event)
-{
-#ifndef QT_NO_DRAGANDDROP
- Q_D(QGraphicsView);
- if (!d->scene || !d->sceneInteractionAllowed)
- return;
-
- // Disable replaying of mouse move events.
- d->useLastMouseEvent = false;
-
- // Generate a scene event.
- QGraphicsSceneDragDropEvent sceneEvent(QEvent::GraphicsSceneDragEnter);
- d->populateSceneDragDropEvent(&sceneEvent, event);
-
- // Store it for later use.
- d->storeDragDropEvent(&sceneEvent);
-
- // Send it to the scene.
- QApplication::sendEvent(d->scene, &sceneEvent);
-
- // Accept the originating event if the scene accepted the scene event.
- if (sceneEvent.isAccepted()) {
- event->setAccepted(true);
- event->setDropAction(sceneEvent.dropAction());
- }
-#else
- Q_UNUSED(event)
-#endif
-}
-
-/*!
- \reimp
-*/
-void QGraphicsView::dragLeaveEvent(QDragLeaveEvent *event)
-{
-#ifndef QT_NO_DRAGANDDROP
- Q_D(QGraphicsView);
- if (!d->scene || !d->sceneInteractionAllowed)
- return;
- if (!d->lastDragDropEvent) {
- qWarning("QGraphicsView::dragLeaveEvent: drag leave received before drag enter");
- return;
- }
-
- // Generate a scene event.
- QGraphicsSceneDragDropEvent sceneEvent(QEvent::GraphicsSceneDragLeave);
- sceneEvent.setScenePos(d->lastDragDropEvent->scenePos());
- sceneEvent.setScreenPos(d->lastDragDropEvent->screenPos());
- sceneEvent.setButtons(d->lastDragDropEvent->buttons());
- sceneEvent.setModifiers(d->lastDragDropEvent->modifiers());
- sceneEvent.setPossibleActions(d->lastDragDropEvent->possibleActions());
- sceneEvent.setProposedAction(d->lastDragDropEvent->proposedAction());
- sceneEvent.setDropAction(d->lastDragDropEvent->dropAction());
- sceneEvent.setMimeData(d->lastDragDropEvent->mimeData());
- sceneEvent.setWidget(d->lastDragDropEvent->widget());
- sceneEvent.setSource(d->lastDragDropEvent->source());
- delete d->lastDragDropEvent;
- d->lastDragDropEvent = 0;
-
- // Send it to the scene.
- QApplication::sendEvent(d->scene, &sceneEvent);
-
- // Accept the originating event if the scene accepted the scene event.
- if (sceneEvent.isAccepted())
- event->setAccepted(true);
-#else
- Q_UNUSED(event)
-#endif
-}
-
-/*!
- \reimp
-*/
-void QGraphicsView::dragMoveEvent(QDragMoveEvent *event)
-{
-#ifndef QT_NO_DRAGANDDROP
- Q_D(QGraphicsView);
- if (!d->scene || !d->sceneInteractionAllowed)
- return;
-
- // Generate a scene event.
- QGraphicsSceneDragDropEvent sceneEvent(QEvent::GraphicsSceneDragMove);
- d->populateSceneDragDropEvent(&sceneEvent, event);
-
- // Store it for later use.
- d->storeDragDropEvent(&sceneEvent);
-
- // Send it to the scene.
- QApplication::sendEvent(d->scene, &sceneEvent);
-
- // Ignore the originating event if the scene ignored the scene event.
- event->setAccepted(sceneEvent.isAccepted());
- if (sceneEvent.isAccepted())
- event->setDropAction(sceneEvent.dropAction());
-#else
- Q_UNUSED(event)
-#endif
-}
-
-/*!
- \reimp
-*/
-void QGraphicsView::focusInEvent(QFocusEvent *event)
-{
- Q_D(QGraphicsView);
- d->updateInputMethodSensitivity();
- QAbstractScrollArea::focusInEvent(event);
- if (d->scene)
- QApplication::sendEvent(d->scene, event);
- // Pass focus on if the scene cannot accept focus.
- if (!d->scene || !event->isAccepted())
- QAbstractScrollArea::focusInEvent(event);
-}
-
-/*!
- \reimp
-*/
-bool QGraphicsView::focusNextPrevChild(bool next)
-{
- return QAbstractScrollArea::focusNextPrevChild(next);
-}
-
-/*!
- \reimp
-*/
-void QGraphicsView::focusOutEvent(QFocusEvent *event)
-{
- Q_D(QGraphicsView);
- QAbstractScrollArea::focusOutEvent(event);
- if (d->scene)
- QApplication::sendEvent(d->scene, event);
-}
-
-/*!
- \reimp
-*/
-void QGraphicsView::keyPressEvent(QKeyEvent *event)
-{
- Q_D(QGraphicsView);
- if (!d->scene || !d->sceneInteractionAllowed) {
- QAbstractScrollArea::keyPressEvent(event);
- return;
- }
- QApplication::sendEvent(d->scene, event);
- if (!event->isAccepted())
- QAbstractScrollArea::keyPressEvent(event);
-}
-
-/*!
- \reimp
-*/
-void QGraphicsView::keyReleaseEvent(QKeyEvent *event)
-{
- Q_D(QGraphicsView);
- if (!d->scene || !d->sceneInteractionAllowed)
- return;
- QApplication::sendEvent(d->scene, event);
- if (!event->isAccepted())
- QAbstractScrollArea::keyReleaseEvent(event);
-}
-
-/*!
- \reimp
-*/
-void QGraphicsView::mouseDoubleClickEvent(QMouseEvent *event)
-{
- Q_D(QGraphicsView);
- if (!d->scene || !d->sceneInteractionAllowed)
- return;
-
- d->storeMouseEvent(event);
- d->mousePressViewPoint = event->pos();
- d->mousePressScenePoint = mapToScene(d->mousePressViewPoint);
- d->mousePressScreenPoint = event->globalPos();
- d->lastMouseMoveScenePoint = d->mousePressScenePoint;
- d->lastMouseMoveScreenPoint = d->mousePressScreenPoint;
- d->mousePressButton = event->button();
-
- QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMouseDoubleClick);
- mouseEvent.setWidget(viewport());
- mouseEvent.setButtonDownScenePos(d->mousePressButton, d->mousePressScenePoint);
- mouseEvent.setButtonDownScreenPos(d->mousePressButton, d->mousePressScreenPoint);
- mouseEvent.setScenePos(mapToScene(d->mousePressViewPoint));
- mouseEvent.setScreenPos(d->mousePressScreenPoint);
- mouseEvent.setLastScenePos(d->lastMouseMoveScenePoint);
- mouseEvent.setLastScreenPos(d->lastMouseMoveScreenPoint);
- mouseEvent.setButtons(event->buttons());
- mouseEvent.setButtons(event->buttons());
- mouseEvent.setAccepted(false);
- mouseEvent.setButton(event->button());
- mouseEvent.setModifiers(event->modifiers());
- if (event->spontaneous())
- qt_sendSpontaneousEvent(d->scene, &mouseEvent);
- else
- QApplication::sendEvent(d->scene, &mouseEvent);
-}
-
-/*!
- \reimp
-*/
-void QGraphicsView::mousePressEvent(QMouseEvent *event)
-{
- Q_D(QGraphicsView);
-
- // Store this event for replaying, finding deltas, and for
- // scroll-dragging; even in non-interactive mode, scroll hand dragging is
- // allowed, so we store the event at the very top of this function.
- d->storeMouseEvent(event);
- d->lastMouseEvent.setAccepted(false);
-
- if (d->sceneInteractionAllowed) {
- // Store some of the event's button-down data.
- d->mousePressViewPoint = event->pos();
- d->mousePressScenePoint = mapToScene(d->mousePressViewPoint);
- d->mousePressScreenPoint = event->globalPos();
- d->lastMouseMoveScenePoint = d->mousePressScenePoint;
- d->lastMouseMoveScreenPoint = d->mousePressScreenPoint;
- d->mousePressButton = event->button();
-
- if (d->scene) {
- // Convert and deliver the mouse event to the scene.
- QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMousePress);
- mouseEvent.setWidget(viewport());
- mouseEvent.setButtonDownScenePos(d->mousePressButton, d->mousePressScenePoint);
- mouseEvent.setButtonDownScreenPos(d->mousePressButton, d->mousePressScreenPoint);
- mouseEvent.setScenePos(d->mousePressScenePoint);
- mouseEvent.setScreenPos(d->mousePressScreenPoint);
- mouseEvent.setLastScenePos(d->lastMouseMoveScenePoint);
- mouseEvent.setLastScreenPos(d->lastMouseMoveScreenPoint);
- mouseEvent.setButtons(event->buttons());
- mouseEvent.setButton(event->button());
- mouseEvent.setModifiers(event->modifiers());
- mouseEvent.setAccepted(false);
- if (event->spontaneous())
- qt_sendSpontaneousEvent(d->scene, &mouseEvent);
- else
- QApplication::sendEvent(d->scene, &mouseEvent);
-
- // Update the original mouse event accepted state.
- bool isAccepted = mouseEvent.isAccepted();
- event->setAccepted(isAccepted);
-
- // Update the last mouse event accepted state.
- d->lastMouseEvent.setAccepted(isAccepted);
-
- if (isAccepted)
- return;
- }
- }
-
-#ifndef QT_NO_RUBBERBAND
- if (d->dragMode == QGraphicsView::RubberBandDrag && !d->rubberBanding) {
- if (d->sceneInteractionAllowed) {
- // Rubberbanding is only allowed in interactive mode.
- event->accept();
- d->rubberBanding = true;
- d->rubberBandRect = QRect();
- if (d->scene) {
- // Initiating a rubber band always clears the selection.
- d->scene->clearSelection();
- }
- }
- } else
-#endif
- if (d->dragMode == QGraphicsView::ScrollHandDrag && event->button() == Qt::LeftButton) {
- // Left-button press in scroll hand mode initiates hand scrolling.
- event->accept();
- d->handScrolling = true;
- d->handScrollMotions = 0;
-#ifndef QT_NO_CURSOR
- viewport()->setCursor(Qt::ClosedHandCursor);
-#endif
- }
-}
-
-/*!
- \reimp
-*/
-void QGraphicsView::mouseMoveEvent(QMouseEvent *event)
-{
- Q_D(QGraphicsView);
-
-#ifndef QT_NO_RUBBERBAND
- if (d->dragMode == QGraphicsView::RubberBandDrag && d->sceneInteractionAllowed) {
- d->storeMouseEvent(event);
- if (d->rubberBanding) {
- // Check for enough drag distance
- if ((d->mousePressViewPoint - event->pos()).manhattanLength()
- < QApplication::startDragDistance()) {
- return;
- }
-
- // Update old rubberband
- if (d->viewportUpdateMode != QGraphicsView::NoViewportUpdate && !d->rubberBandRect.isEmpty()) {
- if (d->viewportUpdateMode != FullViewportUpdate)
- viewport()->update(d->rubberBandRegion(viewport(), d->rubberBandRect));
- else
- d->updateAll();
- }
-
- // Stop rubber banding if the user has let go of all buttons (even
- // if we didn't get the release events).
- if (!event->buttons()) {
- d->rubberBanding = false;
- d->rubberBandRect = QRect();
- return;
- }
-
- // Update rubberband position
- const QPoint &mp = d->mousePressViewPoint;
- QPoint ep = event->pos();
- d->rubberBandRect = QRect(qMin(mp.x(), ep.x()), qMin(mp.y(), ep.y()),
- qAbs(mp.x() - ep.x()) + 1, qAbs(mp.y() - ep.y()) + 1);
-
- // Update new rubberband
- if (d->viewportUpdateMode != QGraphicsView::NoViewportUpdate){
- if (d->viewportUpdateMode != FullViewportUpdate)
- viewport()->update(d->rubberBandRegion(viewport(), d->rubberBandRect));
- else
- d->updateAll();
- }
- // Set the new selection area
- QPainterPath selectionArea;
- selectionArea.addPolygon(mapToScene(d->rubberBandRect));
- selectionArea.closeSubpath();
- if (d->scene)
- d->scene->setSelectionArea(selectionArea, d->rubberBandSelectionMode,
- viewportTransform());
- return;
- }
- } else
-#endif // QT_NO_RUBBERBAND
- if (d->dragMode == QGraphicsView::ScrollHandDrag) {
- if (d->handScrolling) {
- QScrollBar *hBar = horizontalScrollBar();
- QScrollBar *vBar = verticalScrollBar();
- QPoint delta = event->pos() - d->lastMouseEvent.pos();
- hBar->setValue(hBar->value() + (isRightToLeft() ? delta.x() : -delta.x()));
- vBar->setValue(vBar->value() - delta.y());
-
- // Detect how much we've scrolled to disambiguate scrolling from
- // clicking.
- ++d->handScrollMotions;
- }
- }
-
- d->mouseMoveEventHandler(event);
-}
-
-/*!
- \reimp
-*/
-void QGraphicsView::mouseReleaseEvent(QMouseEvent *event)
-{
- Q_D(QGraphicsView);
-
-#ifndef QT_NO_RUBBERBAND
- if (d->dragMode == QGraphicsView::RubberBandDrag && d->sceneInteractionAllowed && !event->buttons()) {
- if (d->rubberBanding) {
- if (d->viewportUpdateMode != QGraphicsView::NoViewportUpdate){
- if (d->viewportUpdateMode != FullViewportUpdate)
- viewport()->update(d->rubberBandRegion(viewport(), d->rubberBandRect));
- else
- d->updateAll();
- }
- d->rubberBanding = false;
- d->rubberBandRect = QRect();
- }
- } else
-#endif
- if (d->dragMode == QGraphicsView::ScrollHandDrag && event->button() == Qt::LeftButton) {
-#ifndef QT_NO_CURSOR
- // Restore the open hand cursor. ### There might be items
- // under the mouse that have a valid cursor at this time, so
- // we could repeat the steps from mouseMoveEvent().
- viewport()->setCursor(Qt::OpenHandCursor);
-#endif
- d->handScrolling = false;
-
- if (d->scene && d->sceneInteractionAllowed && !d->lastMouseEvent.isAccepted() && d->handScrollMotions <= 6) {
- // If we've detected very little motion during the hand drag, and
- // no item accepted the last event, we'll interpret that as a
- // click to the scene, and reset the selection.
- d->scene->clearSelection();
- }
- }
-
- d->storeMouseEvent(event);
-
- if (!d->sceneInteractionAllowed)
- return;
-
- if (!d->scene)
- return;
-
- QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMouseRelease);
- mouseEvent.setWidget(viewport());
- mouseEvent.setButtonDownScenePos(d->mousePressButton, d->mousePressScenePoint);
- mouseEvent.setButtonDownScreenPos(d->mousePressButton, d->mousePressScreenPoint);
- mouseEvent.setScenePos(mapToScene(event->pos()));
- mouseEvent.setScreenPos(event->globalPos());
- mouseEvent.setLastScenePos(d->lastMouseMoveScenePoint);
- mouseEvent.setLastScreenPos(d->lastMouseMoveScreenPoint);
- mouseEvent.setButtons(event->buttons());
- mouseEvent.setButton(event->button());
- mouseEvent.setModifiers(event->modifiers());
- mouseEvent.setAccepted(false);
- if (event->spontaneous())
- qt_sendSpontaneousEvent(d->scene, &mouseEvent);
- else
- QApplication::sendEvent(d->scene, &mouseEvent);
-
- // Update the last mouse event selected state.
- d->lastMouseEvent.setAccepted(mouseEvent.isAccepted());
-
-#ifndef QT_NO_CURSOR
- if (mouseEvent.isAccepted() && mouseEvent.buttons() == 0 && viewport()->testAttribute(Qt::WA_SetCursor)) {
- // The last mouse release on the viewport will trigger clearing the cursor.
- d->_q_unsetViewportCursor();
- }
-#endif
-}
-
-#ifndef QT_NO_WHEELEVENT
-/*!
- \reimp
-*/
-void QGraphicsView::wheelEvent(QWheelEvent *event)
-{
- Q_D(QGraphicsView);
- if (!d->scene || !d->sceneInteractionAllowed) {
- QAbstractScrollArea::wheelEvent(event);
- return;
- }
-
- event->ignore();
-
- QGraphicsSceneWheelEvent wheelEvent(QEvent::GraphicsSceneWheel);
- wheelEvent.setWidget(viewport());
- wheelEvent.setScenePos(mapToScene(event->pos()));
- wheelEvent.setScreenPos(event->globalPos());
- wheelEvent.setButtons(event->buttons());
- wheelEvent.setModifiers(event->modifiers());
- wheelEvent.setDelta(event->delta());
- wheelEvent.setOrientation(event->orientation());
- wheelEvent.setAccepted(false);
- QApplication::sendEvent(d->scene, &wheelEvent);
- event->setAccepted(wheelEvent.isAccepted());
- if (!event->isAccepted())
- QAbstractScrollArea::wheelEvent(event);
-}
-#endif // QT_NO_WHEELEVENT
-
-/*!
- \reimp
-*/
-void QGraphicsView::paintEvent(QPaintEvent *event)
-{
- Q_D(QGraphicsView);
- if (!d->scene) {
- QAbstractScrollArea::paintEvent(event);
- return;
- }
-
- // Set up painter state protection.
- d->scene->d_func()->painterStateProtection = !(d->optimizationFlags & DontSavePainterState);
-
- // Determine the exposed region
- d->exposedRegion = event->region();
- QRectF exposedSceneRect = mapToScene(d->exposedRegion.boundingRect()).boundingRect();
-
- // Set up the painter
- QPainter painter(viewport());
-#ifndef QT_NO_RUBBERBAND
- if (d->rubberBanding && !d->rubberBandRect.isEmpty())
- painter.save();
-#endif
- // Set up render hints
- painter.setRenderHints(painter.renderHints(), false);
- painter.setRenderHints(d->renderHints, true);
-
- // Set up viewport transform
- const bool viewTransformed = isTransformed();
- if (viewTransformed)
- painter.setWorldTransform(viewportTransform());
- const QTransform viewTransform = painter.worldTransform();
-
- // Draw background
- if ((d->cacheMode & CacheBackground)
-#ifdef Q_WS_X11
- && X11->use_xrender
-#endif
- ) {
- // Recreate the background pixmap, and flag the whole background as
- // exposed.
- if (d->mustResizeBackgroundPixmap) {
- d->backgroundPixmap = QPixmap(viewport()->size());
- QBrush bgBrush = viewport()->palette().brush(viewport()->backgroundRole());
- if (!bgBrush.isOpaque())
- d->backgroundPixmap.fill(Qt::transparent);
- QPainter p(&d->backgroundPixmap);
- p.fillRect(0, 0, d->backgroundPixmap.width(), d->backgroundPixmap.height(), bgBrush);
- d->backgroundPixmapExposed = QRegion(viewport()->rect());
- d->mustResizeBackgroundPixmap = false;
- }
-
- // Redraw exposed areas
- if (!d->backgroundPixmapExposed.isEmpty()) {
- QPainter backgroundPainter(&d->backgroundPixmap);
- backgroundPainter.setClipRegion(d->backgroundPixmapExposed, Qt::ReplaceClip);
- if (viewTransformed)
- backgroundPainter.setTransform(viewTransform);
- QRectF backgroundExposedSceneRect = mapToScene(d->backgroundPixmapExposed.boundingRect()).boundingRect();
- drawBackground(&backgroundPainter, backgroundExposedSceneRect);
- d->backgroundPixmapExposed = QRegion();
- }
-
- // Blit the background from the background pixmap
- if (viewTransformed) {
- painter.setWorldTransform(QTransform());
- painter.drawPixmap(QPoint(), d->backgroundPixmap);
- painter.setWorldTransform(viewTransform);
- } else {
- painter.drawPixmap(QPoint(), d->backgroundPixmap);
- }
- } else {
- if (!(d->optimizationFlags & DontSavePainterState))
- painter.save();
- drawBackground(&painter, exposedSceneRect);
- if (!(d->optimizationFlags & DontSavePainterState))
- painter.restore();
- }
-
- // Items
- if (!(d->optimizationFlags & IndirectPainting)) {
- const quint32 oldRectAdjust = d->scene->d_func()->rectAdjust;
- if (d->optimizationFlags & QGraphicsView::DontAdjustForAntialiasing)
- d->scene->d_func()->rectAdjust = 1;
- else
- d->scene->d_func()->rectAdjust = 2;
- d->scene->d_func()->drawItems(&painter, viewTransformed ? &viewTransform : 0,
- &d->exposedRegion, viewport());
- d->scene->d_func()->rectAdjust = oldRectAdjust;
- // Make sure the painter's world transform is restored correctly when
- // drawing without painter state protection (DontSavePainterState).
- // We only change the worldTransform() so there's no need to do a full-blown
- // save() and restore(). Also note that we don't have to do this in case of
- // IndirectPainting (the else branch), because in that case we always save()
- // and restore() in QGraphicsScene::drawItems().
- if (!d->scene->d_func()->painterStateProtection)
- painter.setOpacity(1.0);
- painter.setWorldTransform(viewTransform);
- } else {
- // Make sure we don't have unpolished items before we draw
- if (!d->scene->d_func()->unpolishedItems.isEmpty())
- d->scene->d_func()->_q_polishItems();
- // We reset updateAll here (after we've issued polish events)
- // so that we can discard update requests coming from polishEvent().
- d->scene->d_func()->updateAll = false;
-
- // Find all exposed items
- bool allItems = false;
- QList<QGraphicsItem *> itemList = d->findItems(d->exposedRegion, &allItems, viewTransform);
- if (!itemList.isEmpty()) {
- // Generate the style options.
- const int numItems = itemList.size();
- QGraphicsItem **itemArray = &itemList[0]; // Relies on QList internals, but is perfectly valid.
- QStyleOptionGraphicsItem *styleOptionArray = d->allocStyleOptionsArray(numItems);
- QTransform transform(Qt::Uninitialized);
- for (int i = 0; i < numItems; ++i) {
- QGraphicsItem *item = itemArray[i];
- QGraphicsItemPrivate *itemd = item->d_ptr.data();
- itemd->initStyleOption(&styleOptionArray[i], viewTransform, d->exposedRegion, allItems);
- // Cache the item's area in view coordinates.
- // Note that we have to do this here in case the base class implementation
- // (QGraphicsScene::drawItems) is not called. If it is, we'll do this
- // operation twice, but that's the price one has to pay for using indirect
- // painting :-/.
- const QRectF brect = adjustedItemEffectiveBoundingRect(item);
- if (!itemd->itemIsUntransformable()) {
- transform = item->sceneTransform();
- if (viewTransformed)
- transform *= viewTransform;
- } else {
- transform = item->deviceTransform(viewTransform);
- }
- itemd->paintedViewBoundingRects.insert(d->viewport, transform.mapRect(brect).toRect());
- }
- // Draw the items.
- drawItems(&painter, numItems, itemArray, styleOptionArray);
- d->freeStyleOptionsArray(styleOptionArray);
- }
- }
-
- // Foreground
- drawForeground(&painter, exposedSceneRect);
-
-#ifndef QT_NO_RUBBERBAND
- // Rubberband
- if (d->rubberBanding && !d->rubberBandRect.isEmpty()) {
- painter.restore();
- QStyleOptionRubberBand option;
- option.initFrom(viewport());
- option.rect = d->rubberBandRect;
- option.shape = QRubberBand::Rectangle;
-
- QStyleHintReturnMask mask;
- if (viewport()->style()->styleHint(QStyle::SH_RubberBand_Mask, &option, viewport(), &mask)) {
- // painter clipping for masked rubberbands
- painter.setClipRegion(mask.region, Qt::IntersectClip);
- }
-
- viewport()->style()->drawControl(QStyle::CE_RubberBand, &option, &painter, viewport());
- }
-#endif
-
- painter.end();
-
- // Restore painter state protection.
- d->scene->d_func()->painterStateProtection = true;
-}
-
-/*!
- \reimp
-*/
-void QGraphicsView::resizeEvent(QResizeEvent *event)
-{
- Q_D(QGraphicsView);
- // Save the last center point - the resize may scroll the view, which
- // changes the center point.
- QPointF oldLastCenterPoint = d->lastCenterPoint;
-
- QAbstractScrollArea::resizeEvent(event);
- d->recalculateContentSize();
-
- // Restore the center point again.
- if (d->resizeAnchor == NoAnchor && !d->keepLastCenterPoint) {
- d->updateLastCenterPoint();
- } else {
- d->lastCenterPoint = oldLastCenterPoint;
- }
- d->centerView(d->resizeAnchor);
- d->keepLastCenterPoint = false;
-
- if (d->cacheMode & CacheBackground) {
- // Invalidate the background pixmap
- d->mustResizeBackgroundPixmap = true;
- }
-}
-
-/*!
- \reimp
-*/
-void QGraphicsView::scrollContentsBy(int dx, int dy)
-{
- Q_D(QGraphicsView);
- d->dirtyScroll = true;
- if (d->transforming)
- return;
- if (isRightToLeft())
- dx = -dx;
-
- if (d->viewportUpdateMode != QGraphicsView::NoViewportUpdate) {
- if (d->viewportUpdateMode != QGraphicsView::FullViewportUpdate) {
- if (d->accelerateScrolling) {
-#ifndef QT_NO_RUBBERBAND
- // 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
- d->dirtyScrollOffset.rx() += dx;
- d->dirtyScrollOffset.ry() += dy;
- d->dirtyRegion.translate(dx, dy);
- viewport()->scroll(dx, dy);
- } else {
- d->updateAll();
- }
- } else {
- d->updateAll();
- }
- }
-
- d->updateLastCenterPoint();
-
- if ((d->cacheMode & CacheBackground)
-#ifdef Q_WS_X11
- && X11->use_xrender
-#endif
- ) {
- // Scroll the background pixmap
- QRegion exposed;
- if (!d->backgroundPixmap.isNull())
- d->backgroundPixmap.scroll(dx, dy, d->backgroundPixmap.rect(), &exposed);
-
- // Invalidate the background pixmap
- d->backgroundPixmapExposed.translate(dx, dy);
- d->backgroundPixmapExposed += exposed;
- }
-
- // Always replay on scroll.
- if (d->sceneInteractionAllowed)
- d->replayLastMouseEvent();
-}
-
-/*!
- \reimp
-*/
-void QGraphicsView::showEvent(QShowEvent *event)
-{
- Q_D(QGraphicsView);
- d->recalculateContentSize();
- d->centerView(d->transformationAnchor);
- QAbstractScrollArea::showEvent(event);
-}
-
-/*!
- \reimp
-*/
-void QGraphicsView::inputMethodEvent(QInputMethodEvent *event)
-{
- Q_D(QGraphicsView);
- if (d->scene)
- QApplication::sendEvent(d->scene, event);
-}
-
-/*!
- Draws the background of the scene using \a painter, before any items and
- the foreground are drawn. Reimplement this function to provide a custom
- background for this view.
-
- If all you want is to define a color, texture or gradient for the
- background, you can call setBackgroundBrush() instead.
-
- All painting is done in \e scene coordinates. \a rect is the exposed
- rectangle.
-
- The default implementation fills \a rect using the view's backgroundBrush.
- If no such brush is defined (the default), the scene's drawBackground()
- function is called instead.
-
- \sa drawForeground(), QGraphicsScene::drawBackground()
-*/
-void QGraphicsView::drawBackground(QPainter *painter, const QRectF &rect)
-{
- Q_D(QGraphicsView);
- if (d->scene && d->backgroundBrush.style() == Qt::NoBrush) {
- d->scene->drawBackground(painter, rect);
- return;
- }
-
- painter->fillRect(rect, d->backgroundBrush);
-}
-
-/*!
- Draws the foreground of the scene using \a painter, after the background
- and all items are drawn. Reimplement this function to provide a custom
- foreground for this view.
-
- If all you want is to define a color, texture or gradient for the
- foreground, you can call setForegroundBrush() instead.
-
- All painting is done in \e scene coordinates. \a rect is the exposed
- rectangle.
-
- The default implementation fills \a rect using the view's foregroundBrush.
- If no such brush is defined (the default), the scene's drawForeground()
- function is called instead.
-
- \sa drawBackground(), QGraphicsScene::drawForeground()
-*/
-void QGraphicsView::drawForeground(QPainter *painter, const QRectF &rect)
-{
- Q_D(QGraphicsView);
- if (d->scene && d->foregroundBrush.style() == Qt::NoBrush) {
- d->scene->drawForeground(painter, rect);
- return;
- }
-
- painter->fillRect(rect, d->foregroundBrush);
-}
-
-/*!
- \obsolete
-
- Draws the items \a items in the scene using \a painter, after the
- background and before the foreground are drawn. \a numItems is the number
- of items in \a items and options in \a options. \a options is a list of
- styleoptions; one for each item. Reimplement this function to provide
- custom item drawing for this view.
-
- The default implementation calls the scene's drawItems() function.
-
- Since Qt 4.6, this function is not called anymore unless
- the QGraphicsView::IndirectPainting flag is given as an Optimization
- flag.
-
- \sa drawForeground(), drawBackground(), QGraphicsScene::drawItems()
-*/
-void QGraphicsView::drawItems(QPainter *painter, int numItems,
- QGraphicsItem *items[],
- const QStyleOptionGraphicsItem options[])
-{
- Q_D(QGraphicsView);
- if (d->scene) {
- QWidget *widget = painter->device() == viewport() ? viewport() : 0;
- d->scene->drawItems(painter, numItems, items, options, widget);
- }
-}
-
-/*!
- Returns the current transformation matrix for the view. If no current
- transformation is set, the identity matrix is returned.
-
- \sa setTransform(), rotate(), scale(), shear(), translate()
-*/
-QTransform QGraphicsView::transform() const
-{
- Q_D(const QGraphicsView);
- return d->matrix;
-}
-
-/*!
- Returns a matrix that maps viewport coordinates to scene coordinates.
-
- \sa mapToScene(), mapFromScene()
-*/
-QTransform QGraphicsView::viewportTransform() const
-{
- Q_D(const QGraphicsView);
- QTransform moveMatrix = QTransform::fromTranslate(-d->horizontalScroll(), -d->verticalScroll());
- return d->identityMatrix ? moveMatrix : d->matrix * moveMatrix;
-}
-
-/*!
- \since 4.6
-
- Returns true if the view is transformed (i.e., a non-identity transform
- has been assigned, or the scrollbars are adjusted).
-
- \sa setTransform(), horizontalScrollBar(), verticalScrollBar()
-*/
-bool QGraphicsView::isTransformed() const
-{
- Q_D(const QGraphicsView);
- return !d->identityMatrix || d->horizontalScroll() || d->verticalScroll();
-}
-
-/*!
- Sets the view's current transformation matrix to \a matrix.
-
- If \a combine is true, then \a matrix is combined with the current matrix;
- otherwise, \a matrix \e replaces the current matrix. \a combine is false
- by default.
-
- The transformation matrix tranforms the scene into view coordinates. Using
- the default transformation, provided by the identity matrix, one pixel in
- the view represents one unit in the scene (e.g., a 10x10 rectangular item
- is drawn using 10x10 pixels in the view). If a 2x2 scaling matrix is
- applied, the scene will be drawn in 1:2 (e.g., a 10x10 rectangular item is
- then drawn using 20x20 pixels in the view).
-
- Example:
-
- \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsview.cpp 7
-
- To simplify interation with items using a transformed view, QGraphicsView
- provides mapTo... and mapFrom... functions that can translate between
- scene and view coordinates. For example, you can call mapToScene() to map
- a view coordiate to a floating point scene coordinate, or mapFromScene()
- to map from floating point scene coordinates to view coordinates.
-
- \sa transform(), rotate(), scale(), shear(), translate()
-*/
-void QGraphicsView::setTransform(const QTransform &matrix, bool combine )
-{
- Q_D(QGraphicsView);
- QTransform oldMatrix = d->matrix;
- if (!combine)
- d->matrix = matrix;
- else
- d->matrix = matrix * d->matrix;
- if (oldMatrix == d->matrix)
- return;
-
- d->identityMatrix = d->matrix.isIdentity();
- d->transforming = true;
- if (d->scene) {
- d->recalculateContentSize();
- d->centerView(d->transformationAnchor);
- } else {
- d->updateLastCenterPoint();
- }
-
- if (d->sceneInteractionAllowed)
- d->replayLastMouseEvent();
- d->transforming = false;
-
- // Any matrix operation requires a full update.
- d->updateAll();
-}
-
-/*!
- Resets the view transformation to the identity matrix.
-
- \sa transform(), setTransform()
-*/
-void QGraphicsView::resetTransform()
-{
- setTransform(QTransform());
-}
-
-QPointF QGraphicsViewPrivate::mapToScene(const QPointF &point) const
-{
- QPointF p = point;
- p.rx() += horizontalScroll();
- p.ry() += verticalScroll();
- return identityMatrix ? p : matrix.inverted().map(p);
-}
-
-QRectF QGraphicsViewPrivate::mapToScene(const QRectF &rect) const
-{
- QPointF scrollOffset(horizontalScroll(), verticalScroll());
- QPointF tl = scrollOffset + rect.topLeft();
- QPointF tr = scrollOffset + rect.topRight();
- QPointF br = scrollOffset + rect.bottomRight();
- QPointF bl = scrollOffset + rect.bottomLeft();
-
- QPolygonF poly(4);
- if (!identityMatrix) {
- QTransform x = matrix.inverted();
- poly[0] = x.map(tl);
- poly[1] = x.map(tr);
- poly[2] = x.map(br);
- poly[3] = x.map(bl);
- } else {
- poly[0] = tl;
- poly[1] = tr;
- poly[2] = br;
- poly[3] = bl;
- }
- return poly.boundingRect();
-}
-
-QT_END_NAMESPACE
-
-#include "moc_qgraphicsview.cpp"
-
-#endif // QT_NO_GRAPHICSVIEW
diff --git a/src/gui/graphicsview/qgraphicsview.h b/src/gui/graphicsview/qgraphicsview.h
deleted file mode 100644
index 1447eebcb1..0000000000
--- a/src/gui/graphicsview/qgraphicsview.h
+++ /dev/null
@@ -1,316 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGRAPHICSVIEW_H
-#define QGRAPHICSVIEW_H
-
-#include <QtCore/qmetatype.h>
-#include <QtGui/qpainter.h>
-#include <QtGui/qscrollarea.h>
-#include <QtGui/qgraphicsscene.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW
-
-class QGraphicsItem;
-class QPainterPath;
-class QPolygonF;
-class QStyleOptionGraphicsItem;
-
-class QGraphicsViewPrivate;
-class Q_GUI_EXPORT QGraphicsView : public QAbstractScrollArea
-{
- Q_OBJECT
- Q_FLAGS(QPainter::RenderHints CacheMode OptimizationFlags)
- Q_ENUMS(ViewportAnchor DragMode ViewportUpdateMode)
- Q_PROPERTY(QBrush backgroundBrush READ backgroundBrush WRITE setBackgroundBrush)
- Q_PROPERTY(QBrush foregroundBrush READ foregroundBrush WRITE setForegroundBrush)
- Q_PROPERTY(bool interactive READ isInteractive WRITE setInteractive)
- Q_PROPERTY(QRectF sceneRect READ sceneRect WRITE setSceneRect)
- Q_PROPERTY(Qt::Alignment alignment READ alignment WRITE setAlignment)
- Q_PROPERTY(QPainter::RenderHints renderHints READ renderHints WRITE setRenderHints)
- Q_PROPERTY(DragMode dragMode READ dragMode WRITE setDragMode)
- Q_PROPERTY(CacheMode cacheMode READ cacheMode WRITE setCacheMode)
- Q_PROPERTY(ViewportAnchor transformationAnchor READ transformationAnchor WRITE setTransformationAnchor)
- Q_PROPERTY(ViewportAnchor resizeAnchor READ resizeAnchor WRITE setResizeAnchor)
- Q_PROPERTY(ViewportUpdateMode viewportUpdateMode READ viewportUpdateMode WRITE setViewportUpdateMode)
-#ifndef QT_NO_RUBBERBAND
- Q_PROPERTY(Qt::ItemSelectionMode rubberBandSelectionMode READ rubberBandSelectionMode WRITE setRubberBandSelectionMode)
-#endif
- Q_PROPERTY(OptimizationFlags optimizationFlags READ optimizationFlags WRITE setOptimizationFlags)
-
-public:
- enum ViewportAnchor {
- NoAnchor,
- AnchorViewCenter,
- AnchorUnderMouse
- };
-
- enum CacheModeFlag {
- CacheNone = 0x0,
- CacheBackground = 0x1
- };
- Q_DECLARE_FLAGS(CacheMode, CacheModeFlag)
-
- enum DragMode {
- NoDrag,
- ScrollHandDrag,
- RubberBandDrag
- };
-
- enum ViewportUpdateMode {
- FullViewportUpdate,
- MinimalViewportUpdate,
- SmartViewportUpdate,
- NoViewportUpdate,
- BoundingRectViewportUpdate
- };
-
- enum OptimizationFlag {
- DontClipPainter = 0x1, // obsolete
- DontSavePainterState = 0x2,
- DontAdjustForAntialiasing = 0x4,
- IndirectPainting = 0x8
- };
- Q_DECLARE_FLAGS(OptimizationFlags, OptimizationFlag)
-
- QGraphicsView(QWidget *parent = 0);
- QGraphicsView(QGraphicsScene *scene, QWidget *parent = 0);
- ~QGraphicsView();
-
- QSize sizeHint() const;
-
- QPainter::RenderHints renderHints() const;
- void setRenderHint(QPainter::RenderHint hint, bool enabled = true);
- void setRenderHints(QPainter::RenderHints hints);
-
- Qt::Alignment alignment() const;
- void setAlignment(Qt::Alignment alignment);
-
- ViewportAnchor transformationAnchor() const;
- void setTransformationAnchor(ViewportAnchor anchor);
-
- ViewportAnchor resizeAnchor() const;
- void setResizeAnchor(ViewportAnchor anchor);
-
- ViewportUpdateMode viewportUpdateMode() const;
- void setViewportUpdateMode(ViewportUpdateMode mode);
-
- OptimizationFlags optimizationFlags() const;
- void setOptimizationFlag(OptimizationFlag flag, bool enabled = true);
- void setOptimizationFlags(OptimizationFlags flags);
-
- DragMode dragMode() const;
- void setDragMode(DragMode mode);
-
-#ifndef QT_NO_RUBBERBAND
- Qt::ItemSelectionMode rubberBandSelectionMode() const;
- void setRubberBandSelectionMode(Qt::ItemSelectionMode mode);
-#endif
-
- CacheMode cacheMode() const;
- void setCacheMode(CacheMode mode);
- void resetCachedContent();
-
- bool isInteractive() const;
- void setInteractive(bool allowed);
-
- QGraphicsScene *scene() const;
- void setScene(QGraphicsScene *scene);
-
- QRectF sceneRect() const;
- void setSceneRect(const QRectF &rect);
- inline void setSceneRect(qreal x, qreal y, qreal w, qreal h);
-
- QMatrix matrix() const;
- void setMatrix(const QMatrix &matrix, bool combine = false);
- void resetMatrix();
- QTransform transform() const;
- QTransform viewportTransform() const;
- bool isTransformed() const;
- void setTransform(const QTransform &matrix, bool combine = false);
- void resetTransform();
- void rotate(qreal angle);
- void scale(qreal sx, qreal sy);
- void shear(qreal sh, qreal sv);
- void translate(qreal dx, qreal dy);
-
- void centerOn(const QPointF &pos);
- inline void centerOn(qreal x, qreal y);
- void centerOn(const QGraphicsItem *item);
- void ensureVisible(const QRectF &rect, int xmargin = 50, int ymargin = 50);
- inline void ensureVisible(qreal x, qreal y, qreal w, qreal h, int xmargin = 50, int ymargin = 50);
- void ensureVisible(const QGraphicsItem *item, int xmargin = 50, int ymargin = 50);
- void fitInView(const QRectF &rect, Qt::AspectRatioMode aspectRadioMode = Qt::IgnoreAspectRatio);
- inline void fitInView(qreal x, qreal y, qreal w, qreal h,
- Qt::AspectRatioMode aspectRadioMode = Qt::IgnoreAspectRatio);
- void fitInView(const QGraphicsItem *item,
- Qt::AspectRatioMode aspectRadioMode = Qt::IgnoreAspectRatio);
-
- void render(QPainter *painter, const QRectF &target = QRectF(), const QRect &source = QRect(),
- Qt::AspectRatioMode aspectRatioMode = Qt::KeepAspectRatio);
-
- QList<QGraphicsItem *> items() const;
- QList<QGraphicsItem *> items(const QPoint &pos) const;
- inline QList<QGraphicsItem *> items(int x, int y) const;
- QList<QGraphicsItem *> items(const QRect &rect, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const;
- inline QList<QGraphicsItem *> items(int x, int y, int w, int h, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const;
- QList<QGraphicsItem *> items(const QPolygon &polygon, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const;
- QList<QGraphicsItem *> items(const QPainterPath &path, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const;
- QGraphicsItem *itemAt(const QPoint &pos) const;
- inline QGraphicsItem *itemAt(int x, int y) const;
-
- QPointF mapToScene(const QPoint &point) const;
- QPolygonF mapToScene(const QRect &rect) const;
- QPolygonF mapToScene(const QPolygon &polygon) const;
- QPainterPath mapToScene(const QPainterPath &path) const;
- QPoint mapFromScene(const QPointF &point) const;
- QPolygon mapFromScene(const QRectF &rect) const;
- QPolygon mapFromScene(const QPolygonF &polygon) const;
- QPainterPath mapFromScene(const QPainterPath &path) const;
- inline QPointF mapToScene(int x, int y) const;
- inline QPolygonF mapToScene(int x, int y, int w, int h) const;
- inline QPoint mapFromScene(qreal x, qreal y) const;
- inline QPolygon mapFromScene(qreal x, qreal y, qreal w, qreal h) const;
-
- QVariant inputMethodQuery(Qt::InputMethodQuery query) const;
-
- QBrush backgroundBrush() const;
- void setBackgroundBrush(const QBrush &brush);
-
- QBrush foregroundBrush() const;
- void setForegroundBrush(const QBrush &brush);
-
-public Q_SLOTS:
- void updateScene(const QList<QRectF> &rects);
- void invalidateScene(const QRectF &rect = QRectF(), QGraphicsScene::SceneLayers layers = QGraphicsScene::AllLayers);
- void updateSceneRect(const QRectF &rect);
-
-protected Q_SLOTS:
- void setupViewport(QWidget *widget);
-
-protected:
- QGraphicsView(QGraphicsViewPrivate &, QWidget *parent = 0);
- bool event(QEvent *event);
- bool viewportEvent(QEvent *event);
-
-#ifndef QT_NO_CONTEXTMENU
- void contextMenuEvent(QContextMenuEvent *event);
-#endif
- void dragEnterEvent(QDragEnterEvent *event);
- void dragLeaveEvent(QDragLeaveEvent *event);
- void dragMoveEvent(QDragMoveEvent *event);
- void dropEvent(QDropEvent *event);
- void focusInEvent(QFocusEvent *event);
- bool focusNextPrevChild(bool next);
- void focusOutEvent(QFocusEvent *event);
- void keyPressEvent(QKeyEvent *event);
- void keyReleaseEvent(QKeyEvent *event);
- void mouseDoubleClickEvent(QMouseEvent *event);
- void mousePressEvent(QMouseEvent *event);
- void mouseMoveEvent(QMouseEvent *event);
- void mouseReleaseEvent(QMouseEvent *event);
-#ifndef QT_NO_WHEELEVENT
- void wheelEvent(QWheelEvent *event);
-#endif
- void paintEvent(QPaintEvent *event);
- void resizeEvent(QResizeEvent *event);
- void scrollContentsBy(int dx, int dy);
- void showEvent(QShowEvent *event);
- void inputMethodEvent(QInputMethodEvent *event);
-
- virtual void drawBackground(QPainter *painter, const QRectF &rect);
- virtual void drawForeground(QPainter *painter, const QRectF &rect);
- virtual void drawItems(QPainter *painter, int numItems,
- QGraphicsItem *items[],
- const QStyleOptionGraphicsItem options[]);
-
-private:
- Q_DECLARE_PRIVATE(QGraphicsView)
- Q_DISABLE_COPY(QGraphicsView)
-#ifndef QT_NO_CURSOR
- Q_PRIVATE_SLOT(d_func(), void _q_setViewportCursor(const QCursor &))
- Q_PRIVATE_SLOT(d_func(), void _q_unsetViewportCursor())
-#endif
- friend class QGraphicsSceneWidget;
- friend class QGraphicsScene;
- friend class QGraphicsScenePrivate;
- friend class QGraphicsItemPrivate;
-};
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QGraphicsView::CacheMode)
-Q_DECLARE_OPERATORS_FOR_FLAGS(QGraphicsView::OptimizationFlags)
-
-inline void QGraphicsView::setSceneRect(qreal ax, qreal ay, qreal aw, qreal ah)
-{ setSceneRect(QRectF(ax, ay, aw, ah)); }
-inline void QGraphicsView::centerOn(qreal ax, qreal ay)
-{ centerOn(QPointF(ax, ay)); }
-inline void QGraphicsView::ensureVisible(qreal ax, qreal ay, qreal aw, qreal ah, int xmargin, int ymargin)
-{ ensureVisible(QRectF(ax, ay, aw, ah), xmargin, ymargin); }
-inline void QGraphicsView::fitInView(qreal ax, qreal ay, qreal w, qreal h, Qt::AspectRatioMode mode)
-{ fitInView(QRectF(ax, ay, w, h), mode); }
-inline QList<QGraphicsItem *> QGraphicsView::items(int ax, int ay) const
-{ return items(QPoint(ax, ay)); }
-inline QList<QGraphicsItem *> QGraphicsView::items(int ax, int ay, int w, int h, Qt::ItemSelectionMode mode) const
-{ return items(QRect(ax, ay, w, h), mode); }
-inline QGraphicsItem *QGraphicsView::itemAt(int ax, int ay) const
-{ return itemAt(QPoint(ax, ay)); }
-inline QPointF QGraphicsView::mapToScene(int ax, int ay) const
-{ return mapToScene(QPoint(ax, ay)); }
-inline QPolygonF QGraphicsView::mapToScene(int ax, int ay, int w, int h) const
-{ return mapToScene(QRect(ax, ay, w, h)); }
-inline QPoint QGraphicsView::mapFromScene(qreal ax, qreal ay) const
-{ return mapFromScene(QPointF(ax, ay)); }
-inline QPolygon QGraphicsView::mapFromScene(qreal ax, qreal ay, qreal w, qreal h) const
-{ return mapFromScene(QRectF(ax, ay, w, h)); }
-
-#endif // QT_NO_GRAPHICSVIEW
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QGRAPHICSVIEW_H
diff --git a/src/gui/graphicsview/qgraphicsview_p.h b/src/gui/graphicsview/qgraphicsview_p.h
deleted file mode 100644
index 021ab2df3c..0000000000
--- a/src/gui/graphicsview/qgraphicsview_p.h
+++ /dev/null
@@ -1,233 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGRAPHICSVIEW_P_H
-#define QGRAPHICSVIEW_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qgraphicsview.h"
-
-#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW
-
-#include <QtGui/qevent.h>
-#include <QtCore/qcoreapplication.h>
-#include "qgraphicssceneevent.h"
-#include <QtGui/qstyleoption.h>
-#include <private/qabstractscrollarea_p.h>
-#include <private/qapplication_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class Q_GUI_EXPORT QGraphicsViewPrivate : public QAbstractScrollAreaPrivate
-{
- Q_DECLARE_PUBLIC(QGraphicsView)
-public:
- QGraphicsViewPrivate();
-
- void recalculateContentSize();
- void centerView(QGraphicsView::ViewportAnchor anchor);
-
- QPainter::RenderHints renderHints;
-
- QGraphicsView::DragMode dragMode;
-
- quint32 sceneInteractionAllowed : 1;
- quint32 hasSceneRect : 1;
- quint32 connectedToScene : 1;
- quint32 useLastMouseEvent : 1;
- quint32 identityMatrix : 1;
- quint32 dirtyScroll : 1;
- quint32 accelerateScrolling : 1;
- quint32 keepLastCenterPoint : 1;
- quint32 transforming : 1;
- quint32 handScrolling : 1;
- quint32 mustAllocateStyleOptions : 1;
- quint32 mustResizeBackgroundPixmap : 1;
- quint32 fullUpdatePending : 1;
- quint32 hasUpdateClip : 1;
- quint32 padding : 18;
-
- QRectF sceneRect;
- void updateLastCenterPoint();
-
- qint64 horizontalScroll() const;
- qint64 verticalScroll() const;
-
- QRectF mapRectToScene(const QRect &rect) const;
- QRectF mapRectFromScene(const QRectF &rect) const;
-
- QRect updateClip;
- QPointF mousePressItemPoint;
- QPointF mousePressScenePoint;
- QPoint mousePressViewPoint;
- QPoint mousePressScreenPoint;
- QPointF lastMouseMoveScenePoint;
- QPoint lastMouseMoveScreenPoint;
- QPoint dirtyScrollOffset;
- Qt::MouseButton mousePressButton;
- QTransform matrix;
- qint64 scrollX, scrollY;
- void updateScroll();
-
- qreal leftIndent;
- qreal topIndent;
-
- // Replaying mouse events
- QMouseEvent lastMouseEvent;
- void replayLastMouseEvent();
- void storeMouseEvent(QMouseEvent *event);
- void mouseMoveEventHandler(QMouseEvent *event);
-
- QPointF lastCenterPoint;
- Qt::Alignment alignment;
-
- QGraphicsView::ViewportAnchor transformationAnchor;
- QGraphicsView::ViewportAnchor resizeAnchor;
- QGraphicsView::ViewportUpdateMode viewportUpdateMode;
- QGraphicsView::OptimizationFlags optimizationFlags;
-
- QPointer<QGraphicsScene> scene;
-#ifndef QT_NO_RUBBERBAND
- QRect rubberBandRect;
- QRegion rubberBandRegion(const QWidget *widget, const QRect &rect) const;
- bool rubberBanding;
- Qt::ItemSelectionMode rubberBandSelectionMode;
-#endif
- int handScrollMotions;
-
- QGraphicsView::CacheMode cacheMode;
-
- QVector<QStyleOptionGraphicsItem> styleOptions;
- QStyleOptionGraphicsItem *allocStyleOptionsArray(int numItems);
- void freeStyleOptionsArray(QStyleOptionGraphicsItem *array);
-
- QBrush backgroundBrush;
- QBrush foregroundBrush;
- QPixmap backgroundPixmap;
- QRegion backgroundPixmapExposed;
-
-#ifndef QT_NO_CURSOR
- QCursor originalCursor;
- bool hasStoredOriginalCursor;
- void _q_setViewportCursor(const QCursor &cursor);
- void _q_unsetViewportCursor();
-#endif
-
- QGraphicsSceneDragDropEvent *lastDragDropEvent;
- void storeDragDropEvent(const QGraphicsSceneDragDropEvent *event);
- void populateSceneDragDropEvent(QGraphicsSceneDragDropEvent *dest,
- QDropEvent *source);
-
- QRect mapToViewRect(const QGraphicsItem *item, const QRectF &rect) const;
- QRegion mapToViewRegion(const QGraphicsItem *item, const QRectF &rect) const;
- QRegion dirtyRegion;
- QRect dirtyBoundingRect;
- void processPendingUpdates();
- inline void updateAll()
- {
- viewport->update();
- fullUpdatePending = true;
- dirtyBoundingRect = QRect();
- dirtyRegion = QRegion();
- }
-
- inline void dispatchPendingUpdateRequests()
- {
-#ifdef Q_WS_MAC
- // QWidget::update() works slightly different on the Mac without the raster engine;
- // it's not part of our backing store so it needs special threatment.
- if (QApplicationPrivate::graphics_system_name != QLatin1String("raster")) {
- // At this point either HIViewSetNeedsDisplay (Carbon) or setNeedsDisplay: YES (Cocoa)
- // is called, which means there's a pending update request. We want to dispatch it
- // now because otherwise graphics view updates would require two
- // round-trips in the event loop before the item is painted.
- extern void qt_mac_dispatchPendingUpdateRequests(QWidget *);
- qt_mac_dispatchPendingUpdateRequests(viewport->window());
- } else
-#endif // !Q_WS_MAC
- {
- if (qt_widget_private(viewport)->paintOnScreen())
- QCoreApplication::sendPostedEvents(viewport, QEvent::UpdateRequest);
- else
- QCoreApplication::sendPostedEvents(viewport->window(), QEvent::UpdateRequest);
- }
- }
-
- void setUpdateClip(QGraphicsItem *);
-
- inline bool updateRectF(const QRectF &rect)
- {
- if (rect.isEmpty())
- return false;
- if (optimizationFlags & QGraphicsView::DontAdjustForAntialiasing)
- return updateRect(rect.toAlignedRect().adjusted(-1, -1, 1, 1));
- return updateRect(rect.toAlignedRect().adjusted(-2, -2, 2, 2));
- }
-
- bool updateRect(const QRect &rect);
- bool updateRegion(const QRectF &rect, const QTransform &xform);
- bool updateSceneSlotReimplementedChecked;
- QRegion exposedRegion;
-
- QList<QGraphicsItem *> findItems(const QRegion &exposedRegion, bool *allItems,
- const QTransform &viewTransform) const;
-
- QPointF mapToScene(const QPointF &point) const;
- QRectF mapToScene(const QRectF &rect) const;
- static void translateTouchEvent(QGraphicsViewPrivate *d, QTouchEvent *touchEvent);
- void updateInputMethodSensitivity();
-};
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_GRAPHICSVIEW
-
-#endif
diff --git a/src/gui/graphicsview/qgraphicswidget.cpp b/src/gui/graphicsview/qgraphicswidget.cpp
deleted file mode 100644
index 804394ad85..0000000000
--- a/src/gui/graphicsview/qgraphicswidget.cpp
+++ /dev/null
@@ -1,2425 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qglobal.h"
-
-#ifndef QT_NO_GRAPHICSVIEW
-
-#include "qgraphicswidget.h"
-#include "qgraphicswidget_p.h"
-#include "qgraphicslayout.h"
-#include "qgraphicslayout_p.h"
-#include "qgraphicsscene.h"
-#include "qgraphicssceneevent.h"
-
-#ifndef QT_NO_ACTION
-#include <private/qaction_p.h>
-#endif
-#include <private/qapplication_p.h>
-#include <private/qgraphicsscene_p.h>
-#ifndef QT_NO_SHORTCUT
-#include <private/qshortcutmap_p.h>
-#endif
-#include <QtCore/qmutex.h>
-#include <QtGui/qapplication.h>
-#include <QtGui/qgraphicsview.h>
-#include <QtGui/qgraphicsproxywidget.h>
-#include <QtGui/qpalette.h>
-#include <QtGui/qstyleoption.h>
-
-#include <qdebug.h>
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \class QGraphicsWidget
- \brief The QGraphicsWidget class is the base class for all widget
- items in a QGraphicsScene.
- \since 4.4
- \ingroup graphicsview-api
-
- QGraphicsWidget is an extended base item that provides extra functionality
- over QGraphicsItem. It is similar to QWidget in many ways:
-
- \list
- \o Provides a \l palette, a \l font and a \l style().
- \o Has a defined geometry().
- \o Supports layouts with setLayout() and layout().
- \o Supports shortcuts and actions with grabShortcut() and insertAction()
- \endlist
-
- Unlike QGraphicsItem, QGraphicsWidget is not an abstract class; you can
- create instances of a QGraphicsWidget without having to subclass it.
- This approach is useful for widgets that only serve the purpose of
- organizing child widgets into a layout.
-
- QGraphicsWidget can be used as a base item for your own custom item if
- you require advanced input focus handling, e.g., tab focus and activation, or
- layouts.
-
- Since QGraphicsWidget resembles QWidget and has similar API, it is
- easier to port a widget from QWidget to QGraphicsWidget, instead of
- QGraphicsItem.
-
- \note QWidget-based widgets can be directly embedded into a
- QGraphicsScene using QGraphicsProxyWidget.
-
- Noticeable differences between QGraphicsWidget and QWidget are:
-
- \table
- \header \o QGraphicsWidget
- \o QWidget
- \row \o Coordinates and geometry are defined with qreals (doubles or
- floats, depending on the platform).
- \o QWidget uses integer geometry (QPoint, QRect).
- \row \o The widget is already visible by default; you do not have to
- call show() to display the widget.
- \o QWidget is hidden by default until you call show().
- \row \o A subset of widget attributes are supported.
- \o All widget attributes are supported.
- \row \o A top-level item's style defaults to QGraphicsScene::style
- \o A top-level widget's style defaults to QApplication::style
- \row \o Graphics View provides a custom drag and drop framework, different
- from QWidget.
- \o Standard drag and drop framework.
- \row \o Widget items do not support modality.
- \o Full modality support.
- \endtable
-
- QGraphicsWidget supports a subset of Qt's widget attributes,
- (Qt::WidgetAttribute), as shown in the table below. Any attributes not
- listed in this table are unsupported, or otherwise unused.
-
- \table
- \header \o Widget Attribute \o Usage
- \row \o Qt::WA_SetLayoutDirection
- \o Set by setLayoutDirection(), cleared by
- unsetLayoutDirection(). You can test this attribute to
- check if the widget has been explicitly assigned a
- \l{QGraphicsWidget::layoutDirection()}
- {layoutDirection}. If the attribute is not set, the
- \l{QGraphicsWidget::layoutDirection()}
- {layoutDirection()} is inherited.
- \row \o Qt::WA_RightToLeft
- \o Toggled by setLayoutDirection(). Inherited from the
- parent/scene. If set, the widget's layout will order
- horizontally arranged widgets from right to left.
- \row \o Qt::WA_SetStyle
- \o Set and cleared by setStyle(). If this attribute is
- set, the widget has been explicitly assigned a style.
- If it is unset, the widget will use the scene's or the
- application's style.
- \row \o Qt::WA_Resized
- \o Set by setGeometry() and resize().
- \row \o Qt::WA_SetPalette
- \o Set by setPalette().
- \row \o Qt::WA_SetFont
- \o Set by setPalette().
- \row \o Qt::WA_WindowPropagation
- \o Enables propagation to window widgets.
- \endtable
-
- Although QGraphicsWidget inherits from both QObject and QGraphicsItem,
- you should use the functions provided by QGraphicsItem, \e not QObject, to
- manage the relationships between parent and child items. These functions
- control the stacking order of items as well as their ownership.
-
- \note The QObject::parent() should always return 0 for QGraphicsWidgets,
- but this policy is not strictly defined.
-
- \sa QGraphicsProxyWidget, QGraphicsItem, {Widgets and Layouts}
-*/
-
-/*!
- Constructs a QGraphicsWidget instance. The optional \a parent argument is
- passed to QGraphicsItem's constructor. The optional \a wFlags argument
- specifies the widget's window flags (e.g., whether the widget should be a
- window, a tool, a popup, etc).
-*/
-QGraphicsWidget::QGraphicsWidget(QGraphicsItem *parent, Qt::WindowFlags wFlags)
- : QGraphicsObject(*new QGraphicsWidgetPrivate, 0, 0), QGraphicsLayoutItem(0, false)
-{
- Q_D(QGraphicsWidget);
- d->init(parent, wFlags);
-}
-
-/*!
- \internal
-
- Constructs a new QGraphicsWidget, using \a dd as parent.
-*/
-QGraphicsWidget::QGraphicsWidget(QGraphicsWidgetPrivate &dd, QGraphicsItem *parent, QGraphicsScene *scene, Qt::WindowFlags wFlags)
- : QGraphicsObject(dd, 0, scene), QGraphicsLayoutItem(0, false)
-{
- Q_D(QGraphicsWidget);
- d->init(parent, wFlags);
-}
-
-/*
- \internal
- \class QGraphicsWidgetStyles
-
- We use this thread-safe class to maintain a hash of styles for widgets
- styles. Note that QApplication::style() itself isn't thread-safe, QStyle
- isn't thread-safe, and we don't have a thread-safe factory for creating
- the default style, nor cloning a style.
-*/
-class QGraphicsWidgetStyles
-{
-public:
- QStyle *styleForWidget(const QGraphicsWidget *widget) const
- {
- QMutexLocker locker(&mutex);
- return styles.value(widget, 0);
- }
-
- void setStyleForWidget(QGraphicsWidget *widget, QStyle *style)
- {
- QMutexLocker locker(&mutex);
- if (style)
- styles[widget] = style;
- else
- styles.remove(widget);
- }
-
-private:
- QMap<const QGraphicsWidget *, QStyle *> styles;
- mutable QMutex mutex;
-};
-Q_GLOBAL_STATIC(QGraphicsWidgetStyles, widgetStyles)
-
-/*!
- Destroys the QGraphicsWidget instance.
-*/
-QGraphicsWidget::~QGraphicsWidget()
-{
- Q_D(QGraphicsWidget);
-#ifndef QT_NO_ACTION
- // Remove all actions from this widget
- for (int i = 0; i < d->actions.size(); ++i) {
- QActionPrivate *apriv = d->actions.at(i)->d_func();
- apriv->graphicsWidgets.removeAll(this);
- }
- d->actions.clear();
-#endif
-
- if (QGraphicsScene *scn = scene()) {
- QGraphicsScenePrivate *sceneD = scn->d_func();
- if (sceneD->tabFocusFirst == this)
- sceneD->tabFocusFirst = (d->focusNext == this ? 0 : d->focusNext);
- }
- d->focusPrev->d_func()->focusNext = d->focusNext;
- d->focusNext->d_func()->focusPrev = d->focusPrev;
-
- // Play it really safe
- d->focusNext = this;
- d->focusPrev = this;
-
- clearFocus();
-
- //we check if we have a layout previously
- if (d->layout) {
- QGraphicsLayout *temp = d->layout;
- foreach (QGraphicsItem * item, childItems()) {
- // In case of a custom layout which doesn't remove and delete items, we ensure that
- // the parent layout item does not point to the deleted layout. This code is here to
- // avoid regression from 4.4 to 4.5, because according to 4.5 docs it is not really needed.
- if (item->isWidget()) {
- QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(item);
- if (widget->parentLayoutItem() == d->layout)
- widget->setParentLayoutItem(0);
- }
- }
- d->layout = 0;
- delete temp;
- }
-
- // Remove this graphics widget from widgetStyles
- widgetStyles()->setStyleForWidget(this, 0);
-}
-
-/*!
- \property QGraphicsWidget::size
- \brief the size of the widget
-
- Calling resize() resizes the widget to a \a size bounded by minimumSize()
- and maximumSize(). This property only affects the widget's width and
- height (e.g., its right and bottom edges); the widget's position and
- top-left corner remains unaffected.
-
- Resizing a widget triggers the widget to immediately receive a
- \l{QEvent::GraphicsSceneResize}{GraphicsSceneResize} event with the
- widget's old and new size. If the widget has a layout assigned when this
- event arrives, the layout will be activated and it will automatically
- update any child widgets's geometry.
-
- This property does not affect any layout of the parent widget. If the
- widget itself is managed by a parent layout; e.g., it has a parent widget
- with a layout assigned, that layout will not activate.
-
- By default, this property contains a size with zero width and height.
-
- \sa setGeometry(), QGraphicsSceneResizeEvent, QGraphicsLayout
-*/
-QSizeF QGraphicsWidget::size() const
-{
- return QGraphicsLayoutItem::geometry().size();
-}
-
-void QGraphicsWidget::resize(const QSizeF &size)
-{
- setGeometry(QRectF(pos(), size));
-}
-
-/*!
- \fn void QGraphicsWidget::resize(qreal w, qreal h)
-
- This convenience function is equivalent to calling resize(QSizeF(w, h)).
-
- \sa setGeometry(), setTransform()
-*/
-
-/*!
- \property QGraphicsWidget::sizePolicy
- \brief the size policy for the widget
- \sa sizePolicy(), setSizePolicy(), QWidget::sizePolicy()
-*/
-
-/*!
- \fn QGraphicsWidget::geometryChanged()
-
- This signal gets emitted whenever the geometry is changed in setGeometry().
-*/
-
-/*!
- \property QGraphicsWidget::geometry
- \brief the geometry of the widget
-
- Sets the item's geometry to \a rect. The item's position and size are
- modified as a result of calling this function. The item is first moved,
- then resized.
-
- A side effect of calling this function is that the widget will receive
- a move event and a resize event. Also, if the widget has a layout
- assigned, the layout will activate.
-
- \sa geometry(), resize()
-*/
-void QGraphicsWidget::setGeometry(const QRectF &rect)
-{
- QGraphicsWidgetPrivate *wd = QGraphicsWidget::d_func();
- QGraphicsLayoutItemPrivate *d = QGraphicsLayoutItem::d_ptr.data();
- QRectF newGeom;
- QPointF oldPos = d->geom.topLeft();
- 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) {
- goto relayoutChildrenAndReturn;
- }
-
- // setPos triggers ItemPositionChange, which can adjust position
- wd->inSetGeometry = 1;
- setPos(newGeom.topLeft());
- wd->inSetGeometry = 0;
- newGeom.moveTopLeft(pos());
-
- if (newGeom == d->geom) {
- goto relayoutChildrenAndReturn;
- }
-
- // 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();
- if (moved) {
- // Send move event.
- QGraphicsSceneMoveEvent event;
- event.setOldPos(oldPos);
- event.setNewPos(pos());
- QApplication::sendEvent(this, &event);
- if (wd->inSetPos) {
- //set the new pos
- d->geom.moveTopLeft(pos());
- emit geometryChanged();
- goto relayoutChildrenAndReturn;
- }
- }
- QSizeF oldSize = size();
- QGraphicsLayoutItem::setGeometry(newGeom);
- // Send resize event
- bool resized = newGeom.size() != oldSize;
- if (resized) {
- QGraphicsSceneResizeEvent re;
- re.setOldSize(oldSize);
- re.setNewSize(newGeom.size());
- if (oldSize.width() != newGeom.size().width())
- emit widthChanged();
- if (oldSize.height() != newGeom.size().height())
- emit heightChanged();
- QGraphicsLayout *lay = wd->layout;
- if (QGraphicsLayout::instantInvalidatePropagation()) {
- if (!lay || lay->isActivated()) {
- QApplication::sendEvent(this, &re);
- }
- } else {
- QApplication::sendEvent(this, &re);
- }
- }
- }
-
- emit geometryChanged();
-relayoutChildrenAndReturn:
- if (QGraphicsLayout::instantInvalidatePropagation()) {
- if (QGraphicsLayout *lay = wd->layout) {
- if (!lay->isActivated()) {
- QEvent layoutRequest(QEvent::LayoutRequest);
- QApplication::sendEvent(this, &layoutRequest);
- }
- }
- }
-}
-
-/*!
- \fn QRectF QGraphicsWidget::rect() const
-
- Returns the item's local rect as a QRectF. This function is equivalent
- to QRectF(QPointF(), size()).
-
- \sa setGeometry(), resize()
-*/
-
-/*!
- \fn void QGraphicsWidget::setGeometry(qreal x, qreal y, qreal w, qreal h)
-
- This convenience function is equivalent to calling setGeometry(QRectF(
- \a x, \a y, \a w, \a h)).
-
- \sa geometry(), resize()
-*/
-
-/*!
- \property QGraphicsWidget::minimumSize
- \brief the minimum size of the widget
-
- \sa setMinimumSize(), minimumSize(), preferredSize, maximumSize
-*/
-
-/*!
- \property QGraphicsWidget::preferredSize
- \brief the preferred size of the widget
-
- \sa setPreferredSize(), preferredSize(), minimumSize, maximumSize
-*/
-
-/*!
- \property QGraphicsWidget::maximumSize
- \brief the maximum size of the widget
-
- \sa setMaximumSize(), maximumSize(), minimumSize, preferredSize
-*/
-
-/*!
- Sets the widget's contents margins to \a left, \a top, \a right and \a
- bottom.
-
- Contents margins are used by the assigned layout to define the placement
- of subwidgets and layouts. Margins are particularly useful for widgets
- that constrain subwidgets to only a section of its own geometry. For
- example, a group box with a layout will place subwidgets inside its frame,
- but below the title.
-
- Changing a widget's contents margins will always trigger an update(), and
- any assigned layout will be activated automatically. The widget will then
- receive a \l{QEvent::ContentsRectChange}{ContentsRectChange} event.
-
- \sa getContentsMargins(), setGeometry()
-*/
-void QGraphicsWidget::setContentsMargins(qreal left, qreal top, qreal right, qreal bottom)
-{
- Q_D(QGraphicsWidget);
-
- if (!d->margins && left == 0 && top == 0 && right == 0 && bottom == 0)
- return;
- d->ensureMargins();
- if (left == d->margins[d->Left]
- && top == d->margins[d->Top]
- && right == d->margins[d->Right]
- && bottom == d->margins[d->Bottom])
- return;
-
- d->margins[d->Left] = left;
- d->margins[d->Top] = top;
- d->margins[d->Right] = right;
- d->margins[d->Bottom] = bottom;
-
- if (QGraphicsLayout *l = d->layout)
- l->invalidate();
- else
- updateGeometry();
-
- QEvent e(QEvent::ContentsRectChange);
- QApplication::sendEvent(this, &e);
-}
-
-/*!
- Gets the widget's contents margins. The margins are stored in \a left, \a
- top, \a right and \a bottom, as pointers to qreals. Each argument can
- be \e {omitted} by passing 0.
-
- \sa setContentsMargins()
-*/
-void QGraphicsWidget::getContentsMargins(qreal *left, qreal *top, qreal *right, qreal *bottom) const
-{
- Q_D(const QGraphicsWidget);
- if (left || top || right || bottom)
- d->ensureMargins();
- if (left)
- *left = d->margins[d->Left];
- if (top)
- *top = d->margins[d->Top];
- if (right)
- *right = d->margins[d->Right];
- if (bottom)
- *bottom = d->margins[d->Bottom];
-}
-
-/*!
- Sets the widget's window frame margins to \a left, \a top, \a right and
- \a bottom. The default frame margins are provided by the style, and they
- depend on the current window flags.
-
- If you would like to draw your own window decoration, you can set your
- own frame margins to override the default margins.
-
- \sa unsetWindowFrameMargins(), getWindowFrameMargins(), windowFrameRect()
-*/
-void QGraphicsWidget::setWindowFrameMargins(qreal left, qreal top, qreal right, qreal bottom)
-{
- Q_D(QGraphicsWidget);
-
- if (!d->windowFrameMargins && left == 0 && top == 0 && right == 0 && bottom == 0)
- return;
- d->ensureWindowFrameMargins();
- bool unchanged =
- d->windowFrameMargins[d->Left] == left
- && d->windowFrameMargins[d->Top] == top
- && d->windowFrameMargins[d->Right] == right
- && d->windowFrameMargins[d->Bottom] == bottom;
- if (d->setWindowFrameMargins && unchanged)
- return;
- if (!unchanged)
- prepareGeometryChange();
- d->windowFrameMargins[d->Left] = left;
- d->windowFrameMargins[d->Top] = top;
- d->windowFrameMargins[d->Right] = right;
- d->windowFrameMargins[d->Bottom] = bottom;
- d->setWindowFrameMargins = true;
-}
-
-/*!
- Gets the widget's window frame margins. The margins are stored in \a left,
- \a top, \a right and \a bottom as pointers to qreals. Each argument can
- be \e {omitted} by passing 0.
-
- \sa setWindowFrameMargins(), windowFrameRect()
-*/
-void QGraphicsWidget::getWindowFrameMargins(qreal *left, qreal *top, qreal *right, qreal *bottom) const
-{
- Q_D(const QGraphicsWidget);
- if (left || top || right || bottom)
- d->ensureWindowFrameMargins();
- if (left)
- *left = d->windowFrameMargins[d->Left];
- if (top)
- *top = d->windowFrameMargins[d->Top];
- if (right)
- *right = d->windowFrameMargins[d->Right];
- if (bottom)
- *bottom = d->windowFrameMargins[d->Bottom];
-}
-
-/*!
- Resets the window frame margins to the default value, provided by the style.
-
- \sa setWindowFrameMargins(), getWindowFrameMargins(), windowFrameRect()
-*/
-void QGraphicsWidget::unsetWindowFrameMargins()
-{
- Q_D(QGraphicsWidget);
- if ((d->windowFlags & Qt::Window) && (d->windowFlags & Qt::WindowType_Mask) != Qt::Popup &&
- (d->windowFlags & Qt::WindowType_Mask) != Qt::ToolTip && !(d->windowFlags & Qt::FramelessWindowHint)) {
- QStyleOptionTitleBar bar;
- d->initStyleOptionTitleBar(&bar);
- QStyle *style = this->style();
- qreal margin = style->pixelMetric(QStyle::PM_MdiSubWindowFrameWidth);
- qreal titleBarHeight = d->titleBarHeight(bar);
- setWindowFrameMargins(margin, titleBarHeight, margin, margin);
- } else {
- setWindowFrameMargins(0, 0, 0, 0);
- }
- d->setWindowFrameMargins = false;
-}
-
-/*!
- Returns the widget's geometry in parent coordinates including any window
- frame.
-
- \sa windowFrameRect(), getWindowFrameMargins(), setWindowFrameMargins()
-*/
-QRectF QGraphicsWidget::windowFrameGeometry() const
-{
- Q_D(const QGraphicsWidget);
- return d->windowFrameMargins
- ? geometry().adjusted(-d->windowFrameMargins[d->Left], -d->windowFrameMargins[d->Top],
- d->windowFrameMargins[d->Right], d->windowFrameMargins[d->Bottom])
- : geometry();
-}
-
-/*!
- Returns the widget's local rect including any window frame.
-
- \sa windowFrameGeometry(), getWindowFrameMargins(), setWindowFrameMargins()
-*/
-QRectF QGraphicsWidget::windowFrameRect() const
-{
- Q_D(const QGraphicsWidget);
- return d->windowFrameMargins
- ? rect().adjusted(-d->windowFrameMargins[d->Left], -d->windowFrameMargins[d->Top],
- d->windowFrameMargins[d->Right], d->windowFrameMargins[d->Bottom])
- : rect();
-}
-
-/*!
- Populates a style option object for this widget based on its current
- state, and stores the output in \a option. The default implementation
- populates \a option with the following properties.
-
- \table
- \header
- \o Style Option Property
- \o Value
- \row
- \o state & QStyle::State_Enabled
- \o Corresponds to QGraphicsItem::isEnabled().
- \row
- \o state & QStyle::State_HasFocus
- \o Corresponds to QGraphicsItem::hasFocus().
- \row
- \o state & QStyle::State_MouseOver
- \o Corresponds to QGraphicsItem::isUnderMouse().
- \row
- \o direction
- \o Corresponds to QGraphicsWidget::layoutDirection().
- \row
- \o rect
- \o Corresponds to QGraphicsWidget::rect().toRect().
- \row
- \o palette
- \o Corresponds to QGraphicsWidget::palette().
- \row
- \o fontMetrics
- \o Corresponds to QFontMetrics(QGraphicsWidget::font()).
- \endtable
-
- Subclasses of QGraphicsWidget should call the base implementation, and
- then test the type of \a option using qstyleoption_cast<>() or test
- QStyleOption::Type before storing widget-specific options.
-
- For example:
-
- \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicswidget.cpp 0
-
- \sa QStyleOption::initFrom()
-*/
-void QGraphicsWidget::initStyleOption(QStyleOption *option) const
-{
- Q_ASSERT(option);
-
- option->state = QStyle::State_None;
- if (isEnabled())
- option->state |= QStyle::State_Enabled;
- if (hasFocus())
- option->state |= QStyle::State_HasFocus;
- // if (window->testAttribute(Qt::WA_KeyboardFocusChange)) // ### Window
- // option->state |= QStyle::State_KeyboardFocusChange;
- if (isUnderMouse())
- option->state |= QStyle::State_MouseOver;
- if (QGraphicsWidget *w = window()) {
- if (w->isActiveWindow())
- option->state |= QStyle::State_Active;
- }
- if (isWindow())
- option->state |= QStyle::State_Window;
- /*
- ###
-#ifdef Q_WS_MAC
- extern bool qt_mac_can_clickThrough(const QGraphicsWidget *w); //qwidget_mac.cpp
- if (!(option->state & QStyle::State_Active) && !qt_mac_can_clickThrough(widget))
- option->state &= ~QStyle::State_Enabled;
-
- switch (QMacStyle::widgetSizePolicy(widget)) {
- case QMacStyle::SizeSmall:
- option->state |= QStyle::State_Small;
- break;
- case QMacStyle::SizeMini:
- option->state |= QStyle::State_Mini;
- break;
- default:
- ;
- }
-#endif
-#ifdef QT_KEYPAD_NAVIGATION
- if (widget->hasEditFocus())
- state |= QStyle::State_HasEditFocus;
-#endif
- */
- option->direction = layoutDirection();
- option->rect = rect().toRect(); // ### truncation!
- option->palette = palette();
- if (!isEnabled()) {
- option->palette.setCurrentColorGroup(QPalette::Disabled);
- } else if (isActiveWindow()) {
- option->palette.setCurrentColorGroup(QPalette::Active);
- } else {
- option->palette.setCurrentColorGroup(QPalette::Inactive);
- }
- option->fontMetrics = QFontMetrics(font());
-}
-
-/*!
- \reimp
-*/
-QSizeF QGraphicsWidget::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
-{
- Q_D(const QGraphicsWidget);
- QSizeF sh;
- if (d->layout) {
- QSizeF marginSize(0,0);
- if (d->margins) {
- marginSize = QSizeF(d->margins[d->Left] + d->margins[d->Right],
- d->margins[d->Top] + d->margins[d->Bottom]);
- }
- sh = d->layout->effectiveSizeHint(which, constraint - marginSize);
- sh += marginSize;
- } else {
- switch (which) {
- case Qt::MinimumSize:
- sh = QSizeF(0, 0);
- break;
- case Qt::PreferredSize:
- sh = QSizeF(50, 50); //rather arbitrary
- break;
- case Qt::MaximumSize:
- sh = QSizeF(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
- break;
- default:
- qWarning("QGraphicsWidget::sizeHint(): Don't know how to handle the value of 'which'");
- break;
- }
- }
- return sh;
-}
-
-/*!
- \property QGraphicsWidget::layout
- \brief The layout of the widget
-
- Any existing layout manager is deleted before the new layout is assigned. If
- \a layout is 0, the widget is left without a layout. Existing subwidgets'
- geometries will remain unaffected.
-
- QGraphicsWidget takes ownership of \a layout.
-
- All widgets that are currently managed by \a layout or all of its
- sublayouts, are automatically reparented to this item. The layout is then
- invalidated, and the child widget geometries are adjusted according to
- this item's geometry() and contentsMargins(). Children who are not
- explicitly managed by \a layout remain unaffected by the layout after
- it has been assigned to this widget.
-
- If no layout is currently managing this widget, layout() will return 0.
-
-*/
-
-/*!
- \fn void QGraphicsWidget::layoutChanged()
- This signal gets emitted whenever the layout of the item changes
- \internal
-*/
-
-/*!
- Returns this widget's layout, or 0 if no layout is currently managing this
- widget.
-
- \sa setLayout()
-*/
-QGraphicsLayout *QGraphicsWidget::layout() const
-{
- Q_D(const QGraphicsWidget);
- return d->layout;
-}
-
-/*!
- \fn void QGraphicsWidget::setLayout(QGraphicsLayout *layout)
-
- Sets the layout for this widget to \a layout. Any existing layout manager
- is deleted before the new layout is assigned. If \a layout is 0, the
- widget is left without a layout. Existing subwidgets' geometries will
- remain unaffected.
-
- All widgets that are currently managed by \a layout or all of its
- sublayouts, are automatically reparented to this item. The layout is then
- invalidated, and the child widget geometries are adjusted according to
- this item's geometry() and contentsMargins(). Children who are not
- explicitly managed by \a layout remain unaffected by the layout after
- it has been assigned to this widget.
-
- QGraphicsWidget takes ownership of \a layout.
-
- \sa layout(), QGraphicsLinearLayout::addItem(), QGraphicsLayout::invalidate()
-*/
-void QGraphicsWidget::setLayout(QGraphicsLayout *l)
-{
- Q_D(QGraphicsWidget);
- if (d->layout == l)
- return;
- d->setLayout_helper(l);
- if (!l)
- return;
-
- // Prevent assigning a layout that is already assigned to another widget.
- QGraphicsLayoutItem *oldParent = l->parentLayoutItem();
- if (oldParent && oldParent != this) {
- qWarning("QGraphicsWidget::setLayout: Attempting to set a layout on %s"
- " \"%s\", when the layout already has a parent",
- metaObject()->className(), qPrintable(objectName()));
- return;
- }
-
- // Install and activate the layout.
- l->setParentLayoutItem(this);
- l->d_func()->reparentChildItems(this);
- l->invalidate();
- emit layoutChanged();
-}
-
-/*!
- Adjusts the size of the widget to its effective preferred size hint.
-
- This function is called implicitly when the item is shown for the first
- time.
-
- \sa effectiveSizeHint(), Qt::MinimumSize
-*/
-void QGraphicsWidget::adjustSize()
-{
- QSizeF sz = effectiveSizeHint(Qt::PreferredSize);
- // What if sz is not valid?!
- if (sz.isValid())
- resize(sz);
-}
-
-/*!
- \property QGraphicsWidget::layoutDirection
- \brief the layout direction for this widget.
-
- This property modifies this widget's and all of its descendants'
- Qt::WA_RightToLeft attribute. It also sets this widget's
- Qt::WA_SetLayoutDirection attribute.
-
- The widget's layout direction determines the order in which the layout
- manager horizontally arranges subwidgets of this widget. The default
- value depends on the language and locale of the application, and is
- typically in the same direction as words are read and written. With
- Qt::LeftToRight, the layout starts placing subwidgets from the left
- side of this widget towards the right. Qt::RightToLeft does the opposite -
- the layout will place widgets starting from the right edge moving towards
- the left.
-
- Subwidgets inherit their layout direction from the parent. Top-level
- widget items inherit their layout direction from
- QGraphicsScene::layoutDirection. If you change a widget's layout direction
- by calling setLayoutDirection(), the widget will send itself a
- \l{QEvent::LayoutDirectionChange}{LayoutDirectionChange} event, and then
- propagate the new layout direction to all its descendants.
-
- \sa QWidget::layoutDirection, QApplication::layoutDirection
-*/
-Qt::LayoutDirection QGraphicsWidget::layoutDirection() const
-{
- return testAttribute(Qt::WA_RightToLeft) ? Qt::RightToLeft : Qt::LeftToRight;
-}
-void QGraphicsWidget::setLayoutDirection(Qt::LayoutDirection direction)
-{
- Q_D(QGraphicsWidget);
- setAttribute(Qt::WA_SetLayoutDirection, true);
- d->setLayoutDirection_helper(direction);
-}
-void QGraphicsWidget::unsetLayoutDirection()
-{
- Q_D(QGraphicsWidget);
- setAttribute(Qt::WA_SetLayoutDirection, false);
- d->resolveLayoutDirection();
-}
-
-/*!
- Returns a pointer to the widget's style. If this widget does not have any
- explicitly assigned style, the scene's style is returned instead. In turn,
- if the scene does not have any assigned style, this function returns
- QApplication::style().
-
- \sa setStyle()
-*/
-QStyle *QGraphicsWidget::style() const
-{
- if (QStyle *style = widgetStyles()->styleForWidget(this))
- return style;
- // ### This is not thread-safe. QApplication::style() is not thread-safe.
- return scene() ? scene()->style() : QApplication::style();
-}
-
-/*!
- Sets the widget's style to \a style. QGraphicsWidget does \e not take
- ownership of \a style.
-
- If no style is assigned, or \a style is 0, the widget will use
- QGraphicsScene::style() (if this has been set). Otherwise the widget will
- use QApplication::style().
-
- This function sets the Qt::WA_SetStyle attribute if \a style is not 0;
- otherwise it clears the attribute.
-
- \sa style()
-*/
-void QGraphicsWidget::setStyle(QStyle *style)
-{
- setAttribute(Qt::WA_SetStyle, style != 0);
- widgetStyles()->setStyleForWidget(this, style);
-
- // Deliver StyleChange to the widget itself (doesn't propagate).
- QEvent event(QEvent::StyleChange);
- QApplication::sendEvent(this, &event);
-}
-
-/*!
- \property QGraphicsWidget::font
- \brief the widgets' font
-
- This property provides the widget's font.
-
- QFont consists of font properties that have been explicitly defined and
- properties implicitly inherited from the widget's parent. Hence, font()
- can return a different font compared to the one set with setFont().
- This scheme allows you to define single entries in a font without
- affecting the font's inherited entries.
-
- When a widget's font changes, it resolves its entries against its
- parent widget. If the widget does not have a parent widget, it resolves
- its entries against the scene. The widget then sends itself a
- \l{QEvent::FontChange}{FontChange} event and notifies all its
- descendants so that they can resolve their fonts as well.
-
- By default, this property contains the application's default font.
-
- \sa QApplication::font(), QGraphicsScene::font, QFont::resolve()
-*/
-QFont QGraphicsWidget::font() const
-{
- Q_D(const QGraphicsWidget);
- QFont fnt = d->font;
- fnt.resolve(fnt.resolve() | d->inheritedFontResolveMask);
- return fnt;
-}
-void QGraphicsWidget::setFont(const QFont &font)
-{
- Q_D(QGraphicsWidget);
- setAttribute(Qt::WA_SetFont, font.resolve() != 0);
-
- QFont naturalFont = d->naturalWidgetFont();
- QFont resolvedFont = font.resolve(naturalFont);
- d->setFont_helper(resolvedFont);
-}
-
-/*!
- \property QGraphicsWidget::palette
- \brief the widget's palette
-
- This property provides the widget's palette. The palette provides colors
- and brushes for color groups (e.g., QPalette::Button) and states (e.g.,
- QPalette::Inactive), loosely defining the general look of the widget and
- its children.
-
- QPalette consists of color groups that have been explicitly defined, and
- groups that are implicitly inherited from the widget's parent. Because of
- this, palette() can return a different palette than what has been set with
- setPalette(). This scheme allows you to define single entries in a palette
- without affecting the palette's inherited entries.
-
- When a widget's palette changes, it resolves its entries against its
- parent widget, or if it doesn't have a parent widget, it resolves against
- the scene. It then sends itself a \l{QEvent::PaletteChange}{PaletteChange}
- event, and notifies all its descendants so they can resolve their palettes
- as well.
-
- By default, this property contains the application's default palette.
-
- \sa QApplication::palette(), QGraphicsScene::palette, QPalette::resolve()
-*/
-QPalette QGraphicsWidget::palette() const
-{
- Q_D(const QGraphicsWidget);
- return d->palette;
-}
-void QGraphicsWidget::setPalette(const QPalette &palette)
-{
- Q_D(QGraphicsWidget);
- setAttribute(Qt::WA_SetPalette, palette.resolve() != 0);
-
- QPalette naturalPalette = d->naturalWidgetPalette();
- QPalette resolvedPalette = palette.resolve(naturalPalette);
- d->setPalette_helper(resolvedPalette);
-}
-
-/*!
- \property QGraphicsWidget::autoFillBackground
- \brief whether the widget background is filled automatically
- \since 4.7
-
- If enabled, this property will cause Qt to fill the background of the
- widget before invoking the paint() method. The color used is defined by the
- QPalette::Window color role from the widget's \l{QPalette}{palette}.
-
- In addition, Windows are always filled with QPalette::Window, unless the
- WA_OpaquePaintEvent or WA_NoSystemBackground attributes are set.
-
- By default, this property is false.
-
- \sa Qt::WA_OpaquePaintEvent, Qt::WA_NoSystemBackground,
-*/
-bool QGraphicsWidget::autoFillBackground() const
-{
- Q_D(const QGraphicsWidget);
- return d->autoFillBackground;
-}
-void QGraphicsWidget::setAutoFillBackground(bool enabled)
-{
- Q_D(QGraphicsWidget);
- if (d->autoFillBackground != enabled) {
- d->autoFillBackground = enabled;
- update();
- }
-}
-
-/*!
- If this widget is currently managed by a layout, this function notifies
- the layout that the widget's size hints have changed and the layout
- may need to resize and reposition the widget accordingly.
-
- Call this function if the widget's sizeHint() has changed.
-
- \sa QGraphicsLayout::invalidate()
-*/
-void QGraphicsWidget::updateGeometry()
-{
- QGraphicsLayoutItem::updateGeometry();
- QGraphicsLayoutItem *parentItem = parentLayoutItem();
-
- if (parentItem && parentItem->isLayout()) {
- if (QGraphicsLayout::instantInvalidatePropagation()) {
- static_cast<QGraphicsLayout *>(parentItem)->invalidate();
- } else {
- parentItem->updateGeometry();
- }
- } else {
- if (parentItem) {
- // This is for custom layouting
- QGraphicsWidget *parentWid = parentWidget(); //###
- if (parentWid->isVisible())
- QApplication::postEvent(parentWid, new QEvent(QEvent::LayoutRequest));
- } else {
- /**
- * If this is the topmost widget, post a LayoutRequest event to the widget.
- * When the event is received, it will start flowing all the way down to the leaf
- * widgets in one go. This will make a relayout flicker-free.
- */
- if (QGraphicsLayout::instantInvalidatePropagation())
- QApplication::postEvent(static_cast<QGraphicsWidget *>(this), new QEvent(QEvent::LayoutRequest));
- }
- if (!QGraphicsLayout::instantInvalidatePropagation()) {
- bool wasResized = testAttribute(Qt::WA_Resized);
- resize(size()); // this will restrict the size
- setAttribute(Qt::WA_Resized, wasResized);
- }
- }
-}
-
-/*!
- \reimp
-
- QGraphicsWidget uses the base implementation of this function to catch and
- deliver events related to state changes in the item. Because of this, it is
- very important that subclasses call the base implementation.
-
- \a change specifies the type of change, and \a value is the new value.
-
- For example, QGraphicsWidget uses ItemVisibleChange to deliver
- \l{QEvent::Show} {Show} and \l{QEvent::Hide}{Hide} events,
- ItemPositionHasChanged to deliver \l{QEvent::Move}{Move} events,
- and ItemParentChange both to deliver \l{QEvent::ParentChange}
- {ParentChange} events, and for managing the focus chain.
-
- QGraphicsWidget enables the ItemSendsGeometryChanges flag by default in
- order to track position changes.
-
- \sa QGraphicsItem::itemChange()
-*/
-QVariant QGraphicsWidget::itemChange(GraphicsItemChange change, const QVariant &value)
-{
- Q_D(QGraphicsWidget);
- switch (change) {
- case ItemEnabledHasChanged: {
- // Send EnabledChange after the enabled state has changed.
- QEvent event(QEvent::EnabledChange);
- QApplication::sendEvent(this, &event);
- break;
- }
- case ItemVisibleChange:
- if (value.toBool()) {
- // Send Show event before the item has been shown.
- QShowEvent event;
- QApplication::sendEvent(this, &event);
- bool resized = testAttribute(Qt::WA_Resized);
- if (!resized) {
- adjustSize();
- setAttribute(Qt::WA_Resized, false);
- }
- }
- break;
- case ItemVisibleHasChanged:
- if (!value.toBool()) {
- // Send Hide event after the item has been hidden.
- QHideEvent event;
- QApplication::sendEvent(this, &event);
- }
- break;
- case ItemPositionHasChanged:
- d->setGeometryFromSetPos();
- break;
- case ItemParentChange: {
- // Deliver ParentAboutToChange.
- QEvent event(QEvent::ParentAboutToChange);
- QApplication::sendEvent(this, &event);
- break;
- }
- case ItemParentHasChanged: {
- // Deliver ParentChange.
- QEvent event(QEvent::ParentChange);
- QApplication::sendEvent(this, &event);
- break;
- }
- case ItemCursorHasChanged: {
- // Deliver CursorChange.
- QEvent event(QEvent::CursorChange);
- QApplication::sendEvent(this, &event);
- break;
- }
- case ItemToolTipHasChanged: {
- // Deliver ToolTipChange.
- QEvent event(QEvent::ToolTipChange);
- QApplication::sendEvent(this, &event);
- break;
- }
- default:
- break;
- }
- return QGraphicsItem::itemChange(change, value);
-}
-
-/*!
- \internal
-
- This virtual function is used to notify changes to any property (both
- dynamic properties, and registered with Q_PROPERTY) in the
- widget. Depending on the property itself, the notification can be
- delivered before or after the value has changed.
-
- \a propertyName is the name of the property (e.g., "size" or "font"), and
- \a value is the (proposed) new value of the property. The function returns
- the new value, which may be different from \a value if the notification
- supports adjusting the property value. The base implementation simply
- returns \a value for any \a propertyName.
-
- QGraphicsWidget delivers notifications for the following properties:
-
- \table \o propertyName \o Property
- \row \o layoutDirection \o QGraphicsWidget::layoutDirection
- \row \o size \o QGraphicsWidget::size
- \row \o font \o QGraphicsWidget::font
- \row \o palette \o QGraphicsWidget::palette
- \endtable
-
- \sa itemChange()
-*/
-QVariant QGraphicsWidget::propertyChange(const QString &propertyName, const QVariant &value)
-{
- Q_UNUSED(propertyName);
- return value;
-}
-
-/*!
- QGraphicsWidget's implementation of sceneEvent() simply passes \a event to
- QGraphicsWidget::event(). You can handle all events for your widget in
- event() or in any of the convenience functions; you should not have to
- reimplement this function in a subclass of QGraphicsWidget.
-
- \sa QGraphicsItem::sceneEvent()
-*/
-bool QGraphicsWidget::sceneEvent(QEvent *event)
-{
- return QGraphicsItem::sceneEvent(event);
-}
-
-/*!
- This event handler, for \a event, receives events for the window frame if
- this widget is a window. Its base implementation provides support for
- default window frame interaction such as moving, resizing, etc.
-
- You can reimplement this handler in a subclass of QGraphicsWidget to
- provide your own custom window frame interaction support.
-
- Returns true if \a event has been recognized and processed; otherwise,
- returns false.
-
- \sa event()
-*/
-bool QGraphicsWidget::windowFrameEvent(QEvent *event)
-{
- Q_D(QGraphicsWidget);
- switch (event->type()) {
- case QEvent::GraphicsSceneMousePress:
- d->windowFrameMousePressEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
- break;
- case QEvent::GraphicsSceneMouseMove:
- d->ensureWindowData();
- if (d->windowData->grabbedSection != Qt::NoSection) {
- d->windowFrameMouseMoveEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
- event->accept();
- }
- break;
- case QEvent::GraphicsSceneMouseRelease:
- d->windowFrameMouseReleaseEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
- break;
- case QEvent::GraphicsSceneHoverMove:
- d->windowFrameHoverMoveEvent(static_cast<QGraphicsSceneHoverEvent *>(event));
- break;
- case QEvent::GraphicsSceneHoverLeave:
- d->windowFrameHoverLeaveEvent(static_cast<QGraphicsSceneHoverEvent *>(event));
- break;
- default:
- break;
- }
- return event->isAccepted();
-}
-
-/*!
- \since 4.4
-
- Returns the window frame section at position \a pos, or
- Qt::NoSection if there is no window frame section at this
- position.
-
- This function is used in QGraphicsWidget's base implementation for window
- frame interaction.
-
- You can reimplement this function if you want to customize how a window
- can be interactively moved or resized. For instance, if you only want to
- allow a window to be resized by the bottom right corner, you can
- reimplement this function to return Qt::NoSection for all sections except
- Qt::BottomRightSection.
-
- \sa windowFrameEvent(), paintWindowFrame(), windowFrameGeometry()
-*/
-Qt::WindowFrameSection QGraphicsWidget::windowFrameSectionAt(const QPointF &pos) const
-{
- Q_D(const QGraphicsWidget);
-
- const QRectF r = windowFrameRect();
- if (!r.contains(pos))
- return Qt::NoSection;
-
- const qreal left = r.left();
- const qreal top = r.top();
- const qreal right = r.right();
- const qreal bottom = r.bottom();
- const qreal x = pos.x();
- const qreal y = pos.y();
-
- const qreal cornerMargin = 20;
- //### Not sure of this one, it should be the same value for all edges.
- const qreal windowFrameWidth = d->windowFrameMargins
- ? d->windowFrameMargins[d->Left] : 0;
-
- Qt::WindowFrameSection s = Qt::NoSection;
- if (x <= left + cornerMargin) {
- if (y <= top + windowFrameWidth || (x <= left + windowFrameWidth && y <= top + cornerMargin)) {
- s = Qt::TopLeftSection;
- } else if (y >= bottom - windowFrameWidth || (x <= left + windowFrameWidth && y >= bottom - windowFrameWidth)) {
- s = Qt::BottomLeftSection;
- } else if (x <= left + windowFrameWidth) {
- s = Qt::LeftSection;
- }
- } else if (x >= right - cornerMargin) {
- if (y <= top + windowFrameWidth || (x >= right - windowFrameWidth && y <= top + cornerMargin)) {
- s = Qt::TopRightSection;
- } else if (y >= bottom - windowFrameWidth || (x >= right - windowFrameWidth && y >= bottom - windowFrameWidth)) {
- s = Qt::BottomRightSection;
- } else if (x >= right - windowFrameWidth) {
- s = Qt::RightSection;
- }
- } else if (y <= top + windowFrameWidth) {
- s = Qt::TopSection;
- } else if (y >= bottom - windowFrameWidth) {
- s = Qt::BottomSection;
- }
- if (s == Qt::NoSection) {
- QRectF r1 = r;
- r1.setHeight(d->windowFrameMargins
- ? d->windowFrameMargins[d->Top] : 0);
- if (r1.contains(pos))
- s = Qt::TitleBarArea;
- }
- return s;
-}
-
-/*!
- \reimp
-
- Handles the \a event. QGraphicsWidget handles the following
- events:
-
- \table \o Event \o Usage
- \row \o Polish
- \o Delivered to the widget some time after it has been
- shown.
- \row \o GraphicsSceneMove
- \o Delivered to the widget after its local position has
- changed.
- \row \o GraphicsSceneResize
- \o Delivered to the widget after its size has changed.
- \row \o Show
- \o Delivered to the widget before it has been shown.
- \row \o Hide
- \o Delivered to the widget after it has been hidden.
- \row \o PaletteChange
- \o Delivered to the widget after its palette has changed.
- \row \o FontChange
- \o Delivered to the widget after its font has changed.
- \row \o EnabledChange
- \o Delivered to the widget after its enabled state has
- changed.
- \row \o StyleChange
- \o Delivered to the widget after its style has changed.
- \row \o LayoutDirectionChange
- \o Delivered to the widget after its layout direction has
- changed.
- \row \o ContentsRectChange
- \o Delivered to the widget after its contents margins/
- contents rect has changed.
- \endtable
-*/
-bool QGraphicsWidget::event(QEvent *event)
-{
- Q_D(QGraphicsWidget);
- // Forward the event to the layout first.
- if (d->layout)
- d->layout->widgetEvent(event);
-
- // Handle the event itself.
- switch (event->type()) {
- case QEvent::GraphicsSceneMove:
- moveEvent(static_cast<QGraphicsSceneMoveEvent *>(event));
- break;
- case QEvent::GraphicsSceneResize:
- resizeEvent(static_cast<QGraphicsSceneResizeEvent *>(event));
- break;
- case QEvent::Show:
- showEvent(static_cast<QShowEvent *>(event));
- break;
- case QEvent::Hide:
- hideEvent(static_cast<QHideEvent *>(event));
- break;
- case QEvent::Polish:
- polishEvent();
- d->polished = true;
- if (!d->font.isCopyOf(QApplication::font()))
- d->updateFont(d->font);
- break;
- case QEvent::WindowActivate:
- case QEvent::WindowDeactivate:
- update();
- break;
- // Taken from QWidget::event
- case QEvent::ActivationChange:
- case QEvent::EnabledChange:
- case QEvent::FontChange:
- case QEvent::StyleChange:
- case QEvent::PaletteChange:
- case QEvent::ParentChange:
- case QEvent::ContentsRectChange:
- case QEvent::LayoutDirectionChange:
- changeEvent(event);
- break;
- case QEvent::Close:
- closeEvent((QCloseEvent *)event);
- break;
- case QEvent::GrabMouse:
- grabMouseEvent(event);
- break;
- case QEvent::UngrabMouse:
- ungrabMouseEvent(event);
- break;
- case QEvent::GrabKeyboard:
- grabKeyboardEvent(event);
- break;
- case QEvent::UngrabKeyboard:
- ungrabKeyboardEvent(event);
- break;
- case QEvent::GraphicsSceneMousePress:
- if (d->hasDecoration() && windowFrameEvent(event))
- return true;
- case QEvent::GraphicsSceneMouseMove:
- case QEvent::GraphicsSceneMouseRelease:
- case QEvent::GraphicsSceneMouseDoubleClick:
- d->ensureWindowData();
- if (d->hasDecoration() && d->windowData->grabbedSection != Qt::NoSection)
- return windowFrameEvent(event);
- break;
- case QEvent::GraphicsSceneHoverEnter:
- case QEvent::GraphicsSceneHoverMove:
- case QEvent::GraphicsSceneHoverLeave:
- if (d->hasDecoration()) {
- windowFrameEvent(event);
- // Filter out hover events if they were sent to us only because of the
- // decoration (special case in QGraphicsScenePrivate::dispatchHoverEvent).
- if (!acceptsHoverEvents())
- return true;
- }
- break;
- default:
- break;
- }
- return QObject::event(event);
-}
-
-/*!
- This event handler can be reimplemented to handle state changes.
-
- The state being changed in this event can be retrieved through \a event.
-
- Change events include: QEvent::ActivationChange, QEvent::EnabledChange,
- QEvent::FontChange, QEvent::StyleChange, QEvent::PaletteChange,
- QEvent::ParentChange, QEvent::LayoutDirectionChange, and
- QEvent::ContentsRectChange.
-*/
-void QGraphicsWidget::changeEvent(QEvent *event)
-{
- Q_D(QGraphicsWidget);
- switch (event->type()) {
- case QEvent::StyleChange:
- // ### Don't unset if the margins are explicitly set.
- unsetWindowFrameMargins();
- if (d->layout)
- d->layout->invalidate();
- case QEvent::FontChange:
- update();
- updateGeometry();
- break;
- case QEvent::PaletteChange:
- update();
- break;
- case QEvent::ParentChange:
- d->resolveFont(d->inheritedFontResolveMask);
- d->resolvePalette(d->inheritedPaletteResolveMask);
- break;
- default:
- break;
- }
-}
-
-/*!
- This event handler, for \a event, can be reimplemented in a subclass to
- receive widget close events. The default implementation accepts the
- event.
-
- \sa close(), QCloseEvent
-*/
-void QGraphicsWidget::closeEvent(QCloseEvent *event)
-{
- event->accept();
-}
-
-/*!
- \reimp
-*/
-void QGraphicsWidget::focusInEvent(QFocusEvent *event)
-{
- Q_UNUSED(event);
- if (focusPolicy() != Qt::NoFocus)
- update();
-}
-
-/*!
- Finds a new widget to give the keyboard focus to, as appropriate for Tab
- and Shift+Tab, and returns true if it can find a new widget; returns false
- otherwise. If \a next is true, this function searches forward; if \a next
- is false, it searches backward.
-
- Sometimes, you will want to reimplement this function to provide special
- focus handling for your widget and its subwidgets. For example, a web
- browser might reimplement it to move its current active link forward or
- backward, and call the base implementation only when it reaches the last
- or first link on the page.
-
- Child widgets call focusNextPrevChild() on their parent widgets, but only
- the window that contains the child widgets decides where to redirect
- focus. By reimplementing this function for an object, you gain control of
- focus traversal for all child widgets.
-
- \sa focusPolicy()
-*/
-bool QGraphicsWidget::focusNextPrevChild(bool next)
-{
- Q_D(QGraphicsWidget);
- // Let the parent's focusNextPrevChild implementation decide what to do.
- QGraphicsWidget *parent = 0;
- if (!isWindow() && (parent = parentWidget()))
- return parent->focusNextPrevChild(next);
- if (!d->scene)
- return false;
- if (d->scene->focusNextPrevChild(next))
- return true;
- if (isWindow()) {
- setFocus(next ? Qt::TabFocusReason : Qt::BacktabFocusReason);
- if (hasFocus())
- return true;
- }
- return false;
-}
-
-/*!
- \reimp
-*/
-void QGraphicsWidget::focusOutEvent(QFocusEvent *event)
-{
- Q_UNUSED(event);
- if (focusPolicy() != Qt::NoFocus)
- update();
-}
-
-/*!
- This event handler, for \l{QEvent::Hide}{Hide} events, is delivered after
- the widget has been hidden, for example, setVisible(false) has been called
- for the widget or one of its ancestors when the widget was previously
- shown.
-
- You can reimplement this event handler to detect when your widget is
- hidden. Calling QEvent::accept() or QEvent::ignore() on \a event has no
- effect.
-
- \sa showEvent(), QWidget::hideEvent(), ItemVisibleChange
-*/
-void QGraphicsWidget::hideEvent(QHideEvent *event)
-{
- ///### focusNextPrevChild(true), don't lose focus when the focus widget
- // is hidden.
- Q_UNUSED(event);
-}
-
-/*!
- This event handler, for \l{QEvent::GraphicsSceneMove}{GraphicsSceneMove}
- events, is delivered after the widget has moved (e.g., its local position
- has changed).
-
- This event is only delivered when the item is moved locally. Calling
- setTransform() or moving any of the item's ancestors does not affect the
- item's local position.
-
- You can reimplement this event handler to detect when your widget has
- moved. Calling QEvent::accept() or QEvent::ignore() on \a event has no
- effect.
-
- \sa ItemPositionChange, ItemPositionHasChanged
-*/
-void QGraphicsWidget::moveEvent(QGraphicsSceneMoveEvent *event)
-{
- // ### Last position is always == current position
- Q_UNUSED(event);
-}
-
-/*!
- This event is delivered to the item by the scene at some point after it
- has been constructed, but before it is shown or otherwise accessed through
- the scene. You can use this event handler to do last-minute initializations
- of the widget which require the item to be fully constructed.
-
- The base implementation does nothing.
-*/
-void QGraphicsWidget::polishEvent()
-{
-}
-
-/*!
- This event handler, for
- \l{QEvent::GraphicsSceneResize}{GraphicsSceneResize} events, is
- delivered after the widget has been resized (i.e., its local size has
- changed). \a event contains both the old and the new size.
-
- This event is only delivered when the widget is resized locally; calling
- setTransform() on the widget or any of its ancestors or view, does not
- affect the widget's local size.
-
- You can reimplement this event handler to detect when your widget has been
- resized. Calling QEvent::accept() or QEvent::ignore() on \a event has no
- effect.
-
- \sa geometry(), setGeometry()
-*/
-void QGraphicsWidget::resizeEvent(QGraphicsSceneResizeEvent *event)
-{
- Q_UNUSED(event);
-}
-
-/*!
- This event handler, for \l{QEvent::Show}{Show} events, is delivered before
- the widget has been shown, for example, setVisible(true) has been called
- for the widget or one of its ancestors when the widget was previously
- hidden.
-
- You can reimplement this event handler to detect when your widget is
- shown. Calling QEvent::accept() or QEvent::ignore() on \a event has no
- effect.
-
- \sa hideEvent(), QWidget::showEvent(), ItemVisibleChange
-*/
-void QGraphicsWidget::showEvent(QShowEvent *event)
-{
- Q_UNUSED(event);
-}
-
-/*!
- \reimp
-*/
-void QGraphicsWidget::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
-{
- Q_UNUSED(event);
-}
-
-/*!
- \reimp
-*/
-void QGraphicsWidget::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
-{
- Q_UNUSED(event);
-}
-
-/*!
- This event handler, for \a event, can be reimplemented in a subclass to
- receive notifications for Qt::GrabMouse events.
-
- \sa grabMouse(), grabKeyboard()
-*/
-void QGraphicsWidget::grabMouseEvent(QEvent *event)
-{
- Q_UNUSED(event);
-}
-
-/*!
- This event handler, for \a event, can be reimplemented in a subclass to
- receive notifications for Qt::UngrabMouse events.
-
- \sa ungrabMouse(), ungrabKeyboard()
-*/
-void QGraphicsWidget::ungrabMouseEvent(QEvent *event)
-{
- Q_UNUSED(event);
-}
-
-/*!
- This event handler, for \a event, can be reimplemented in a subclass to
- receive notifications for Qt::GrabKeyboard events.
-
- \sa grabKeyboard(), grabMouse()
-*/
-void QGraphicsWidget::grabKeyboardEvent(QEvent *event)
-{
- Q_UNUSED(event);
-}
-
-/*!
- This event handler, for \a event, can be reimplemented in a subclass to
- receive notifications for Qt::UngrabKeyboard events.
-
- \sa ungrabKeyboard(), ungrabMouse()
-*/
-void QGraphicsWidget::ungrabKeyboardEvent(QEvent *event)
-{
- Q_UNUSED(event);
-}
-
-/*!
- Returns the widgets window type.
-
- \sa windowFlags(), isWindow(), isPanel()
-*/
-Qt::WindowType QGraphicsWidget::windowType() const
-{
- return Qt::WindowType(int(windowFlags()) & Qt::WindowType_Mask);
-}
-
-/*!
- \property QGraphicsWidget::windowFlags
- \brief the widget's window flags
-
- Window flags are a combination of a window type (e.g., Qt::Dialog) and
- several flags giving hints on the behavior of the window. The behavior
- is platform-dependent.
-
- By default, this property contains no window flags.
-
- Windows are panels. If you set the Qt::Window flag, the ItemIsPanel flag
- will be set automatically. If you clear the Qt::Window flag, the
- ItemIsPanel flag is also cleared. Note that the ItemIsPanel flag can be
- set independently of Qt::Window.
-
- \sa isWindow(), isPanel()
-*/
-Qt::WindowFlags QGraphicsWidget::windowFlags() const
-{
- Q_D(const QGraphicsWidget);
- return d->windowFlags;
-}
-void QGraphicsWidget::setWindowFlags(Qt::WindowFlags wFlags)
-{
- Q_D(QGraphicsWidget);
- if (d->windowFlags == wFlags)
- return;
- bool wasPopup = (d->windowFlags & Qt::WindowType_Mask) == Qt::Popup;
-
- d->adjustWindowFlags(&wFlags);
- d->windowFlags = wFlags;
- if (!d->setWindowFrameMargins)
- unsetWindowFrameMargins();
-
- setFlag(ItemIsPanel, d->windowFlags & Qt::Window);
-
- bool isPopup = (d->windowFlags & Qt::WindowType_Mask) == Qt::Popup;
- if (d->scene && isVisible() && wasPopup != isPopup) {
- // Popup state changed; update implicit mouse grab.
- if (!isPopup)
- d->scene->d_func()->removePopup(this);
- else
- d->scene->d_func()->addPopup(this);
- }
-
- if (d->scene && d->scene->d_func()->allItemsIgnoreHoverEvents && d->hasDecoration()) {
- d->scene->d_func()->allItemsIgnoreHoverEvents = false;
- d->scene->d_func()->enableMouseTrackingOnViews();
- }
-}
-
-/*!
- Returns true if this widget's window is in the active window, or if the
- widget does not have a window but is in an active scene (i.e., a scene
- that currently has focus).
-
- The active window is the window that either contains a child widget that
- currently has input focus, or that itself has input focus.
-
- \sa QGraphicsScene::activeWindow(), QGraphicsScene::setActiveWindow(), isActive()
-*/
-bool QGraphicsWidget::isActiveWindow() const
-{
- return isActive();
-}
-
-/*!
- \property QGraphicsWidget::windowTitle
- \brief This property holds the window title (caption).
-
- This property is only used for windows.
-
- By default, if no title has been set, this property contains an
- empty string.
-*/
-void QGraphicsWidget::setWindowTitle(const QString &title)
-{
- Q_D(QGraphicsWidget);
- d->ensureWindowData();
- d->windowData->windowTitle = title;
-}
-QString QGraphicsWidget::windowTitle() const
-{
- Q_D(const QGraphicsWidget);
- return d->windowData ? d->windowData->windowTitle : QString();
-}
-
-/*!
- \property QGraphicsWidget::focusPolicy
- \brief the way the widget accepts keyboard focus
-
- The focus policy is Qt::TabFocus if the widget accepts keyboard focus by
- tabbing, Qt::ClickFocus if the widget accepts focus by clicking,
- Qt::StrongFocus if it accepts both, and Qt::NoFocus (the default) if it
- does not accept focus at all.
-
- You must enable keyboard focus for a widget if it processes keyboard
- events. This is normally done from the widget's constructor. For instance,
- the QLineEdit constructor calls setFocusPolicy(Qt::StrongFocus).
-
- If you enable a focus policy (i.e., not Qt::NoFocus), QGraphicsWidget will
- automatically enable the ItemIsFocusable flag. Setting Qt::NoFocus on a
- widget will clear the ItemIsFocusable flag. If the widget currently has
- keyboard focus, the widget will automatically lose focus.
-
- \sa focusInEvent(), focusOutEvent(), keyPressEvent(), keyReleaseEvent(), enabled
-*/
-Qt::FocusPolicy QGraphicsWidget::focusPolicy() const
-{
- Q_D(const QGraphicsWidget);
- return d->focusPolicy;
-}
-void QGraphicsWidget::setFocusPolicy(Qt::FocusPolicy policy)
-{
- Q_D(QGraphicsWidget);
- if (d->focusPolicy == policy)
- return;
- d->focusPolicy = policy;
- if (hasFocus() && policy == Qt::NoFocus)
- clearFocus();
- setFlag(ItemIsFocusable, policy != Qt::NoFocus);
-}
-
-/*!
- If this widget, a child or descendant of this widget currently has input
- focus, this function will return a pointer to that widget. If
- no descendant widget has input focus, 0 is returned.
-
- \sa QGraphicsItem::focusItem(), QWidget::focusWidget()
-*/
-QGraphicsWidget *QGraphicsWidget::focusWidget() const
-{
- Q_D(const QGraphicsWidget);
- if (d->subFocusItem && d->subFocusItem->d_ptr->isWidget)
- return static_cast<QGraphicsWidget *>(d->subFocusItem);
- return 0;
-}
-
-#ifndef QT_NO_SHORTCUT
-/*!
- \since 4.5
-
- Adds a shortcut to Qt's shortcut system that watches for the given key \a
- sequence in the given \a context. If the \a context is
- Qt::ApplicationShortcut, the shortcut applies to the application as a
- whole. Otherwise, it is either local to this widget, Qt::WidgetShortcut,
- or to the window itself, Qt::WindowShortcut. For widgets that are not part
- of a window (i.e., top-level widgets and their children),
- Qt::WindowShortcut shortcuts apply to the scene.
-
- If the same key \a sequence has been grabbed by several widgets,
- when the key \a sequence occurs a QEvent::Shortcut event is sent
- to all the widgets to which it applies in a non-deterministic
- order, but with the ``ambiguous'' flag set to true.
-
- \warning You should not normally need to use this function;
- instead create \l{QAction}s with the shortcut key sequences you
- require (if you also want equivalent menu options and toolbar
- buttons), or create \l{QShortcut}s if you just need key sequences.
- Both QAction and QShortcut handle all the event filtering for you,
- and provide signals which are triggered when the user triggers the
- key sequence, so are much easier to use than this low-level
- function.
-
- \sa releaseShortcut() setShortcutEnabled() QWidget::grabShortcut()
-*/
-int QGraphicsWidget::grabShortcut(const QKeySequence &sequence, Qt::ShortcutContext context)
-{
- Q_ASSERT(qApp);
- if (sequence.isEmpty())
- return 0;
- // ### setAttribute(Qt::WA_GrabbedShortcut);
- return qApp->d_func()->shortcutMap.addShortcut(this, sequence, context);
-}
-
-/*!
- \since 4.5
-
- Removes the shortcut with the given \a id from Qt's shortcut
- system. The widget will no longer receive QEvent::Shortcut events
- for the shortcut's key sequence (unless it has other shortcuts
- with the same key sequence).
-
- \warning You should not normally need to use this function since
- Qt's shortcut system removes shortcuts automatically when their
- parent widget is destroyed. It is best to use QAction or
- QShortcut to handle shortcuts, since they are easier to use than
- this low-level function. Note also that this is an expensive
- operation.
-
- \sa grabShortcut() setShortcutEnabled() , QWidget::releaseShortcut()
-*/
-void QGraphicsWidget::releaseShortcut(int id)
-{
- Q_ASSERT(qApp);
- if (id)
- qApp->d_func()->shortcutMap.removeShortcut(id, this, 0);
-}
-
-/*!
- \since 4.5
-
- If \a enabled is true, the shortcut with the given \a id is
- enabled; otherwise the shortcut is disabled.
-
- \warning You should not normally need to use this function since
- Qt's shortcut system enables/disables shortcuts automatically as
- widgets become hidden/visible and gain or lose focus. It is best
- to use QAction or QShortcut to handle shortcuts, since they are
- easier to use than this low-level function.
-
- \sa grabShortcut() releaseShortcut(), QWidget::setShortcutEnabled()
-*/
-void QGraphicsWidget::setShortcutEnabled(int id, bool enabled)
-{
- Q_ASSERT(qApp);
- if (id)
- qApp->d_func()->shortcutMap.setShortcutEnabled(enabled, id, this, 0);
-}
-
-/*!
- \since 4.5
-
- If \a enabled is true, auto repeat of the shortcut with the
- given \a id is enabled; otherwise it is disabled.
-
- \sa grabShortcut() releaseShortcut() QWidget::setShortcutAutoRepeat()
-*/
-void QGraphicsWidget::setShortcutAutoRepeat(int id, bool enabled)
-{
- Q_ASSERT(qApp);
- if (id)
- qApp->d_func()->shortcutMap.setShortcutAutoRepeat(enabled, id, this, 0);
-}
-#endif
-
-#ifndef QT_NO_ACTION
-/*!
- \since 4.5
-
- Appends the action \a action to this widget's list of actions.
-
- All QGraphicsWidgets have a list of \l{QAction}s, however they can be
- represented graphically in many different ways. The default use of the
- QAction list (as returned by actions()) is to create a context QMenu.
-
- A QGraphicsWidget should only have one of each action and adding an action
- it already has will not cause the same action to be in the widget twice.
-
- \sa removeAction(), insertAction(), actions(), QWidget::addAction()
-*/
-void QGraphicsWidget::addAction(QAction *action)
-{
- insertAction(0, action);
-}
-
-/*!
- \since 4.5
-
- Appends the actions \a actions to this widget's list of actions.
-
- \sa removeAction(), QMenu, addAction(), QWidget::addActions()
-*/
-void QGraphicsWidget::addActions(QList<QAction *> actions)
-{
- for (int i = 0; i < actions.count(); ++i)
- insertAction(0, actions.at(i));
-}
-
-/*!
- \since 4.5
-
- Inserts the action \a action to this widget's list of actions,
- before the action \a before. It appends the action if \a before is 0 or
- \a before is not a valid action for this widget.
-
- A QGraphicsWidget should only have one of each action.
-
- \sa removeAction(), addAction(), QMenu, actions(),
- QWidget::insertActions()
-*/
-void QGraphicsWidget::insertAction(QAction *before, QAction *action)
-{
- if (!action) {
- qWarning("QWidget::insertAction: Attempt to insert null action");
- return;
- }
-
- Q_D(QGraphicsWidget);
- int index = d->actions.indexOf(action);
- if (index != -1)
- d->actions.removeAt(index);
-
- int pos = d->actions.indexOf(before);
- if (pos < 0) {
- before = 0;
- pos = d->actions.size();
- }
- d->actions.insert(pos, action);
-
- if (index == -1) {
- QActionPrivate *apriv = action->d_func();
- apriv->graphicsWidgets.append(this);
- }
-
- QActionEvent e(QEvent::ActionAdded, action, before);
- QApplication::sendEvent(this, &e);
-}
-
-/*!
- \since 4.5
-
- Inserts the actions \a actions to this widget's list of actions,
- before the action \a before. It appends the action if \a before is 0 or
- \a before is not a valid action for this widget.
-
- A QGraphicsWidget can have at most one of each action.
-
- \sa removeAction(), QMenu, insertAction(), QWidget::insertActions()
-*/
-void QGraphicsWidget::insertActions(QAction *before, QList<QAction *> actions)
-{
- for (int i = 0; i < actions.count(); ++i)
- insertAction(before, actions.at(i));
-}
-
-/*!
- \since 4.5
-
- Removes the action \a action from this widget's list of actions.
-
- \sa insertAction(), actions(), insertAction(), QWidget::removeAction()
-*/
-void QGraphicsWidget::removeAction(QAction *action)
-{
- if (!action)
- return;
-
- Q_D(QGraphicsWidget);
-
- QActionPrivate *apriv = action->d_func();
- apriv->graphicsWidgets.removeAll(this);
-
- if (d->actions.removeAll(action)) {
- QActionEvent e(QEvent::ActionRemoved, action);
- QApplication::sendEvent(this, &e);
- }
-}
-
-/*!
- \since 4.5
-
- Returns the (possibly empty) list of this widget's actions.
-
- \sa insertAction(), removeAction(), QWidget::actions(),
- QAction::associatedWidgets(), QAction::associatedGraphicsWidgets()
-*/
-QList<QAction *> QGraphicsWidget::actions() const
-{
- Q_D(const QGraphicsWidget);
- return d->actions;
-}
-#endif
-
-/*!
- Moves the \a second widget around the ring of focus widgets so that
- keyboard focus moves from the \a first widget to the \a second widget when
- the Tab key is pressed.
-
- Note that since the tab order of the \a second widget is changed, you
- should order a chain like this:
-
- \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicswidget.cpp 1
-
- \e not like this:
-
- \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicswidget.cpp 2
-
- If \a first is 0, this indicates that \a second should be the first widget
- to receive input focus should the scene gain Tab focus (i.e., the user
- hits Tab so that focus passes into the scene). If \a second is 0, this
- indicates that \a first should be the first widget to gain focus if the
- scene gained BackTab focus.
-
- By default, tab order is defined implicitly using widget creation order.
-
- \sa focusPolicy, {Keyboard Focus}
-*/
-void QGraphicsWidget::setTabOrder(QGraphicsWidget *first, QGraphicsWidget *second)
-{
- if (!first && !second) {
- qWarning("QGraphicsWidget::setTabOrder(0, 0) is undefined");
- return;
- }
- if ((first && second) && first->scene() != second->scene()) {
- qWarning("QGraphicsWidget::setTabOrder: scenes %p and %p are different",
- first->scene(), second->scene());
- return;
- }
- QGraphicsScene *scene = first ? first->scene() : second->scene();
- if (!scene && (!first || !second)) {
- qWarning("QGraphicsWidget::setTabOrder: assigning tab order from/to the"
- " scene requires the item to be in a scene.");
- return;
- }
-
- // If either first or second are 0, the scene's tabFocusFirst is updated
- // to point to the first item in the scene's focus chain. Then first or
- // second are set to point to tabFocusFirst.
- QGraphicsScenePrivate *sceneD = scene->d_func();
- if (!first) {
- sceneD->tabFocusFirst = second;
- return;
- }
- if (!second) {
- sceneD->tabFocusFirst = first->d_func()->focusNext;
- return;
- }
-
- // Both first and second are != 0.
- QGraphicsWidget *firstFocusNext = first->d_func()->focusNext;
- if (firstFocusNext == second) {
- // Nothing to do.
- return;
- }
-
- // Update the focus chain.
- QGraphicsWidget *secondFocusPrev = second->d_func()->focusPrev;
- QGraphicsWidget *secondFocusNext = second->d_func()->focusNext;
- firstFocusNext->d_func()->focusPrev = second;
- first->d_func()->focusNext = second;
- second->d_func()->focusNext = firstFocusNext;
- second->d_func()->focusPrev = first;
- secondFocusPrev->d_func()->focusNext = secondFocusNext;
- secondFocusNext->d_func()->focusPrev = secondFocusPrev;
-
- Q_ASSERT(first->d_func()->focusNext->d_func()->focusPrev == first);
- Q_ASSERT(first->d_func()->focusPrev->d_func()->focusNext == first);
-
- Q_ASSERT(second->d_func()->focusNext->d_func()->focusPrev == second);
- Q_ASSERT(second->d_func()->focusPrev->d_func()->focusNext == second);
-
-}
-
-/*!
- If \a on is true, this function enables \a attribute; otherwise
- \a attribute is disabled.
-
- See the class documentation for QGraphicsWidget for a complete list of
- which attributes are supported, and what they are for.
-
- \sa testAttribute(), QWidget::setAttribute()
-*/
-void QGraphicsWidget::setAttribute(Qt::WidgetAttribute attribute, bool on)
-{
- Q_D(QGraphicsWidget);
- // ### most flags require some immediate action
- // ### we might want to qWarn use of unsupported attributes
- // ### we might want to not use Qt::WidgetAttribute, but roll our own instead
- d->setAttribute(attribute, on);
-}
-
-/*!
- Returns true if \a attribute is enabled for this widget; otherwise,
- returns false.
-
- \sa setAttribute()
-*/
-bool QGraphicsWidget::testAttribute(Qt::WidgetAttribute attribute) const
-{
- Q_D(const QGraphicsWidget);
- return d->testAttribute(attribute);
-}
-
-/*!
- \reimp
-*/
-int QGraphicsWidget::type() const
-{
- return Type;
-}
-
-/*!
- \reimp
-*/
-void QGraphicsWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
-{
- Q_UNUSED(painter);
- Q_UNUSED(option);
- Q_UNUSED(widget);
-}
-
-/*!
- This virtual function is called by QGraphicsScene to draw the window frame
- for windows using \a painter, \a option, and \a widget, in local
- coordinates. The base implementation uses the current style to render the
- frame and title bar.
-
- You can reimplement this function in a subclass of QGraphicsWidget to
- provide custom rendering of the widget's window frame.
-
- \sa QGraphicsItem::paint()
-*/
-void QGraphicsWidget::paintWindowFrame(QPainter *painter, const QStyleOptionGraphicsItem *option,
- QWidget *widget)
-{
- const bool fillBackground = !testAttribute(Qt::WA_OpaquePaintEvent)
- && !testAttribute(Qt::WA_NoSystemBackground);
- QGraphicsProxyWidget *proxy = qobject_cast<QGraphicsProxyWidget *>(this);
- const bool embeddedWidgetFillsOwnBackground = proxy && proxy->widget();
-
- if (rect().contains(option->exposedRect)) {
- if (fillBackground && !embeddedWidgetFillsOwnBackground)
- painter->fillRect(option->exposedRect, palette().window());
- return;
- }
-
- Q_D(QGraphicsWidget);
-
- QRect windowFrameRect = QRect(QPoint(), windowFrameGeometry().size().toSize());
- QStyleOptionTitleBar bar;
- bar.QStyleOption::operator=(*option);
- d->initStyleOptionTitleBar(&bar); // this clear flags in bar.state
- d->ensureWindowData();
- if (d->windowData->buttonMouseOver)
- bar.state |= QStyle::State_MouseOver;
- else
- bar.state &= ~QStyle::State_MouseOver;
- if (d->windowData->buttonSunken)
- bar.state |= QStyle::State_Sunken;
- else
- bar.state &= ~QStyle::State_Sunken;
-
- bar.rect = windowFrameRect;
-
- // translate painter to make the style happy
- const QPointF styleOrigin = this->windowFrameRect().topLeft();
- painter->translate(styleOrigin);
-
-#ifdef Q_WS_MAC
- const QSize pixmapSize = windowFrameRect.size();
- if (pixmapSize.width() <= 0 || pixmapSize.height() <= 0)
- return;
- QPainter *realPainter = painter;
- QPixmap pm(pixmapSize);
- painter = new QPainter(&pm);
-#endif
-
- // Fill background
- QStyleHintReturnMask mask;
- bool setMask = style()->styleHint(QStyle::SH_WindowFrame_Mask, &bar, widget, &mask) && !mask.region.isEmpty();
- bool hasBorder = !style()->styleHint(QStyle::SH_TitleBar_NoBorder, &bar, widget);
- int frameWidth = style()->pixelMetric(QStyle::PM_MDIFrameWidth, &bar, widget);
- if (setMask) {
- painter->save();
- painter->setClipRegion(mask.region, Qt::IntersectClip);
- }
- if (fillBackground) {
- if (embeddedWidgetFillsOwnBackground) {
- // Don't fill the background twice.
- QPainterPath windowFrameBackground;
- windowFrameBackground.addRect(windowFrameRect);
- // Adjust with 0.5 to avoid border artifacts between
- // widget background and frame background.
- windowFrameBackground.addRect(rect().translated(-styleOrigin).adjusted(0.5, 0.5, -0.5, -0.5));
- painter->fillPath(windowFrameBackground, palette().window());
- } else {
- painter->fillRect(windowFrameRect, palette().window());
- }
- }
- painter->setRenderHint(QPainter::NonCosmeticDefaultPen);
-
- // Draw title
- int height = (int)d->titleBarHeight(bar);
- bar.rect.setHeight(height);
- if (hasBorder) // Frame is painted by PE_FrameWindow
- bar.rect.adjust(frameWidth, frameWidth, -frameWidth, 0);
-
- painter->save();
- painter->setFont(QApplication::font("QWorkspaceTitleBar"));
- style()->drawComplexControl(QStyle::CC_TitleBar, &bar, painter, widget);
- painter->restore();
- if (setMask)
- painter->restore();
- // Draw window frame
- QStyleOptionFrame frameOptions;
- frameOptions.QStyleOption::operator=(*option);
- initStyleOption(&frameOptions);
- if (!hasBorder)
- painter->setClipRect(windowFrameRect.adjusted(0, +height, 0, 0), Qt::IntersectClip);
- if (hasFocus()) {
- frameOptions.state |= QStyle::State_HasFocus;
- } else {
- frameOptions.state &= ~QStyle::State_HasFocus;
- }
- bool isActive = isActiveWindow();
- if (isActive) {
- frameOptions.state |= QStyle::State_Active;
- } else {
- frameOptions.state &= ~QStyle::State_Active;
- }
-
- frameOptions.palette.setCurrentColorGroup(isActive ? QPalette::Active : QPalette::Normal);
- frameOptions.rect = windowFrameRect;
- frameOptions.lineWidth = style()->pixelMetric(QStyle::PM_MdiSubWindowFrameWidth, 0, widget);
- frameOptions.midLineWidth = 1;
- style()->drawPrimitive(QStyle::PE_FrameWindow, &frameOptions, painter, widget);
-
-#ifdef Q_WS_MAC
- realPainter->drawPixmap(QPoint(), pm);
- delete painter;
-#endif
-}
-
-/*!
- \reimp
-*/
-QRectF QGraphicsWidget::boundingRect() const
-{
- return windowFrameRect();
-}
-
-/*!
- \reimp
-*/
-QPainterPath QGraphicsWidget::shape() const
-{
- QPainterPath path;
- path.addRect(rect());
- return path;
-}
-
-/*!
- Call this function to close the widget.
-
- Returns true if the widget was closed; otherwise returns false.
- This slot will first send a QCloseEvent to the widget, which may or may
- not accept the event. If the event was ignored, nothing happens. If the
- event was accepted, it will hide() the widget.
-
- If the widget has the Qt::WA_DeleteOnClose attribute set it will be
- deleted.
-*/
-bool QGraphicsWidget::close()
-{
- QCloseEvent closeEvent;
- QApplication::sendEvent(this, &closeEvent);
- if (!closeEvent.isAccepted()) {
- return false;
- }
- // hide
- if (isVisible()) {
- hide();
- }
- if (testAttribute(Qt::WA_DeleteOnClose)) {
- deleteLater();
- }
- return true;
-}
-
-#ifdef Q_NO_USING_KEYWORD
-/*!
- \fn const QObjectList &QGraphicsWidget::children() const
- \internal
-
- This function returns the same value as QObject::children(). It's
- provided to differentiate between the obsolete member
- QGraphicsItem::children() and QObject::children(). QGraphicsItem now
- provides childItems() instead.
-*/
-#endif
-
-#if 0
-void QGraphicsWidget::dumpFocusChain()
-{
- qDebug() << "=========== Dumping focus chain ==============";
- int i = 0;
- QGraphicsWidget *next = this;
- QSet<QGraphicsWidget*> visited;
- do {
- if (!next) {
- qWarning("Found a focus chain that is not circular, (next == 0)");
- break;
- }
- qDebug() << i++ << QString::number(uint(next), 16) << next->className() << next->data(0) << QString::fromAscii("focusItem:%1").arg(next->hasFocus() ? '1' : '0') << QLatin1String("next:") << next->d_func()->focusNext->data(0) << QLatin1String("prev:") << next->d_func()->focusPrev->data(0);
- if (visited.contains(next)) {
- qWarning("Already visited this node. However, I expected to dump until I found myself.");
- break;
- }
- visited << next;
- next = next->d_func()->focusNext;
- } while (next != this);
-}
-#endif
-
-QT_END_NAMESPACE
-
-#endif //QT_NO_GRAPHICSVIEW
diff --git a/src/gui/graphicsview/qgraphicswidget.h b/src/gui/graphicsview/qgraphicswidget.h
deleted file mode 100644
index 063be2d102..0000000000
--- a/src/gui/graphicsview/qgraphicswidget.h
+++ /dev/null
@@ -1,257 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGRAPHICSWIDGET_H
-#define QGRAPHICSWIDGET_H
-
-#include <QtGui/qfont.h>
-#include <QtGui/qgraphicslayoutitem.h>
-#include <QtGui/qgraphicsitem.h>
-#include <QtGui/qpalette.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QFont;
-class QFontMetrics;
-class QGraphicsLayout;
-class QGraphicsSceneMoveEvent;
-class QGraphicsWidgetPrivate;
-class QGraphicsSceneResizeEvent;
-class QStyle;
-class QStyleOption;
-
-#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW
-
-class QGraphicsWidgetPrivate;
-
-class Q_GUI_EXPORT QGraphicsWidget : public QGraphicsObject, public QGraphicsLayoutItem
-{
- Q_OBJECT
- Q_INTERFACES(QGraphicsItem QGraphicsLayoutItem)
- Q_PROPERTY(QPalette palette READ palette WRITE setPalette)
- Q_PROPERTY(QFont font READ font WRITE setFont)
- Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection RESET unsetLayoutDirection)
- Q_PROPERTY(QSizeF size READ size WRITE resize NOTIFY geometryChanged)
- Q_PROPERTY(QSizeF minimumSize READ minimumSize WRITE setMinimumSize)
- Q_PROPERTY(QSizeF preferredSize READ preferredSize WRITE setPreferredSize)
- Q_PROPERTY(QSizeF maximumSize READ maximumSize WRITE setMaximumSize)
- Q_PROPERTY(QSizePolicy sizePolicy READ sizePolicy WRITE setSizePolicy)
- Q_PROPERTY(Qt::FocusPolicy focusPolicy READ focusPolicy WRITE setFocusPolicy)
- Q_PROPERTY(Qt::WindowFlags windowFlags READ windowFlags WRITE setWindowFlags)
- Q_PROPERTY(QString windowTitle READ windowTitle WRITE setWindowTitle)
- Q_PROPERTY(QRectF geometry READ geometry WRITE setGeometry NOTIFY geometryChanged)
- Q_PROPERTY(bool autoFillBackground READ autoFillBackground WRITE setAutoFillBackground)
- Q_PROPERTY(QGraphicsLayout* layout READ layout WRITE setLayout NOTIFY layoutChanged)
-public:
- QGraphicsWidget(QGraphicsItem *parent = 0, Qt::WindowFlags wFlags = 0);
- ~QGraphicsWidget();
- QGraphicsLayout *layout() const;
- void setLayout(QGraphicsLayout *layout);
- void adjustSize();
-
- Qt::LayoutDirection layoutDirection() const;
- void setLayoutDirection(Qt::LayoutDirection direction);
- void unsetLayoutDirection();
-
- QStyle *style() const;
- void setStyle(QStyle *style);
-
- QFont font() const;
- void setFont(const QFont &font);
-
- QPalette palette() const;
- void setPalette(const QPalette &palette);
-
- bool autoFillBackground() const;
- void setAutoFillBackground(bool enabled);
-
- void resize(const QSizeF &size);
- inline void resize(qreal w, qreal h) { resize(QSizeF(w, h)); }
- QSizeF size() const;
-
- void setGeometry(const QRectF &rect);
- inline void setGeometry(qreal x, qreal y, qreal w, qreal h);
- inline QRectF rect() const { return QRectF(QPointF(), size()); }
-
- void setContentsMargins(qreal left, qreal top, qreal right, qreal bottom);
- void getContentsMargins(qreal *left, qreal *top, qreal *right, qreal *bottom) const;
-
- void setWindowFrameMargins(qreal left, qreal top, qreal right, qreal bottom);
- void getWindowFrameMargins(qreal *left, qreal *top, qreal *right, qreal *bottom) const;
- void unsetWindowFrameMargins();
- QRectF windowFrameGeometry() const;
- QRectF windowFrameRect() const;
-
- // Window handling
- Qt::WindowFlags windowFlags() const;
- Qt::WindowType windowType() const;
- void setWindowFlags(Qt::WindowFlags wFlags);
- bool isActiveWindow() const;
- void setWindowTitle(const QString &title);
- QString windowTitle() const;
-
- // Focus handling
- Qt::FocusPolicy focusPolicy() const;
- void setFocusPolicy(Qt::FocusPolicy policy);
- static void setTabOrder(QGraphicsWidget *first, QGraphicsWidget *second);
- QGraphicsWidget *focusWidget() const;
-
-#ifndef QT_NO_SHORTCUT
- int grabShortcut(const QKeySequence &sequence, Qt::ShortcutContext context = Qt::WindowShortcut);
- void releaseShortcut(int id);
- void setShortcutEnabled(int id, bool enabled = true);
- void setShortcutAutoRepeat(int id, bool enabled = true);
-#endif
-
-#ifndef QT_NO_ACTION
- //actions
- void addAction(QAction *action);
- void addActions(QList<QAction*> actions);
- void insertAction(QAction *before, QAction *action);
- void insertActions(QAction *before, QList<QAction*> actions);
- void removeAction(QAction *action);
- QList<QAction*> actions() const;
-#endif
-
- void setAttribute(Qt::WidgetAttribute attribute, bool on = true);
- bool testAttribute(Qt::WidgetAttribute attribute) const;
-
- enum {
- Type = 11
- };
- int type() const;
-
- void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
- virtual void paintWindowFrame(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
- QRectF boundingRect() const;
- QPainterPath shape() const;
-
-#if 0
- void dumpFocusChain();
-#endif
-
- // ### Qt 5: Disambiguate
-#ifdef Q_NO_USING_KEYWORD
- const QObjectList &children() const { return QObject::children(); }
-#else
- using QObject::children;
-#endif
-
-Q_SIGNALS:
- void geometryChanged();
- void layoutChanged();
-
-public Q_SLOTS:
- bool close();
-
-protected:
- virtual void initStyleOption(QStyleOption *option) const;
-
- QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const;
- void updateGeometry();
-
- // Notification
- QVariant itemChange(GraphicsItemChange change, const QVariant &value);
- virtual QVariant propertyChange(const QString &propertyName, const QVariant &value);
-
- // Scene events
- bool sceneEvent(QEvent *event);
- virtual bool windowFrameEvent(QEvent *e);
- virtual Qt::WindowFrameSection windowFrameSectionAt(const QPointF& pos) const;
-
- // Base event handlers
- bool event(QEvent *event);
- //virtual void actionEvent(QActionEvent *event);
- virtual void changeEvent(QEvent *event);
- virtual void closeEvent(QCloseEvent *event);
- //void create(WId window = 0, bool initializeWindow = true, bool destroyOldWindow = true);
- //void destroy(bool destroyWindow = true, bool destroySubWindows = true);
- void focusInEvent(QFocusEvent *event);
- virtual bool focusNextPrevChild(bool next);
- void focusOutEvent(QFocusEvent *event);
- virtual void hideEvent(QHideEvent *event);
- //virtual bool macEvent(EventHandlerCallRef caller, EventRef event);
- //virtual int metric(PaintDeviceMetric m ) const;
- virtual void moveEvent(QGraphicsSceneMoveEvent *event);
- virtual void polishEvent();
- //virtual bool qwsEvent(QWSEvent *event);
- //void resetInputContext ();
- virtual void resizeEvent(QGraphicsSceneResizeEvent *event);
- virtual void showEvent(QShowEvent *event);
- //virtual void tabletEvent(QTabletEvent *event);
- //virtual bool winEvent(MSG *message, long *result);
- //virtual bool x11Event(XEvent *event);
- virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *event);
- virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
- virtual void grabMouseEvent(QEvent *event);
- virtual void ungrabMouseEvent(QEvent *event);
- virtual void grabKeyboardEvent(QEvent *event);
- virtual void ungrabKeyboardEvent(QEvent *event);
- QGraphicsWidget(QGraphicsWidgetPrivate &, QGraphicsItem *parent, QGraphicsScene *, Qt::WindowFlags wFlags = 0);
-
-private:
- Q_DISABLE_COPY(QGraphicsWidget)
- Q_DECLARE_PRIVATE_D(QGraphicsItem::d_ptr.data(), QGraphicsWidget)
- friend class QGraphicsScene;
- friend class QGraphicsScenePrivate;
- friend class QGraphicsView;
- friend class QGraphicsItem;
- friend class QGraphicsItemPrivate;
- friend class QGraphicsLayout;
- friend class QWidget;
- friend class QApplication;
-};
-
-inline void QGraphicsWidget::setGeometry(qreal ax, qreal ay, qreal aw, qreal ah)
-{ setGeometry(QRectF(ax, ay, aw, ah)); }
-
-#endif
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif
-
diff --git a/src/gui/graphicsview/qgraphicswidget_p.cpp b/src/gui/graphicsview/qgraphicswidget_p.cpp
deleted file mode 100644
index 8649dec29a..0000000000
--- a/src/gui/graphicsview/qgraphicswidget_p.cpp
+++ /dev/null
@@ -1,906 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qglobal.h"
-
-#ifndef QT_NO_GRAPHICSVIEW
-
-#include <QtCore/qdebug.h>
-#include <QtCore/qnumeric.h>
-#include "qgraphicswidget_p.h"
-#include "qgraphicslayoutitem_p.h"
-#include "qgraphicslayout.h"
-#include "qgraphicsscene_p.h"
-#include <QtGui/qapplication.h>
-#include <QtGui/qgraphicsscene.h>
-#include <QtGui/qstyleoption.h>
-#include <QtGui/QStyleOptionTitleBar>
-#include <QtGui/QGraphicsSceneMouseEvent>
-#if defined(Q_WS_MAC) && !defined(QT_NO_STYLE_MAC)
-# include <QMacStyle>
-#endif
-
-QT_BEGIN_NAMESPACE
-
-void QGraphicsWidgetPrivate::init(QGraphicsItem *parentItem, Qt::WindowFlags wFlags)
-{
- Q_Q(QGraphicsWidget);
-
- attributes = 0;
- isWidget = 1; // QGraphicsItem::isWidget() returns true.
- focusNext = focusPrev = q;
- focusPolicy = Qt::NoFocus;
-
- adjustWindowFlags(&wFlags);
- windowFlags = wFlags;
-
- if (parentItem)
- setParentItemHelper(parentItem, 0, 0);
-
- q->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred, QSizePolicy::DefaultType));
- q->setGraphicsItem(q);
-
- resolveLayoutDirection();
- q->unsetWindowFrameMargins();
- flags |= QGraphicsItem::ItemUsesExtendedStyleOption;
- flags |= QGraphicsItem::ItemSendsGeometryChanges;
- if (windowFlags & Qt::Window)
- flags |= QGraphicsItem::ItemIsPanel;
-}
-
-qreal QGraphicsWidgetPrivate::titleBarHeight(const QStyleOptionTitleBar &options) const
-{
- Q_Q(const QGraphicsWidget);
- int height = q->style()->pixelMetric(QStyle::PM_TitleBarHeight, &options);
-#if defined(Q_WS_MAC) && !defined(QT_NO_STYLE_MAC)
- if (qobject_cast<QMacStyle*>(q->style())) {
- height -=4;
- }
-#endif
- return (qreal)height;
-}
-
-/*!
- \internal
-*/
-QGraphicsWidgetPrivate::~QGraphicsWidgetPrivate()
-{
- // Remove any lazily allocated data
- delete[] margins;
- delete[] windowFrameMargins;
- delete windowData;
-}
-
-/*!
- \internal
-
- Ensures that margins is allocated.
- This function must be called before any dereferencing.
-*/
-void QGraphicsWidgetPrivate::ensureMargins() const
-{
- if (!margins) {
- margins = new qreal[4];
- for (int i = 0; i < 4; ++i)
- margins[i] = 0;
- }
-}
-
-/*!
- \internal
-
- Ensures that windowFrameMargins is allocated.
- This function must be called before any dereferencing.
-*/
-void QGraphicsWidgetPrivate::ensureWindowFrameMargins() const
-{
- if (!windowFrameMargins) {
- windowFrameMargins = new qreal[4];
- for (int i = 0; i < 4; ++i)
- windowFrameMargins[i] = 0;
- }
-}
-
-/*!
- \internal
-
- Ensures that windowData is allocated.
- This function must be called before any dereferencing.
-*/
-void QGraphicsWidgetPrivate::ensureWindowData()
-{
- if (!windowData)
- windowData = new WindowData;
-}
-
-void QGraphicsWidgetPrivate::setPalette_helper(const QPalette &palette)
-{
- if (this->palette == palette && this->palette.resolve() == palette.resolve())
- return;
- updatePalette(palette);
-}
-
-void QGraphicsWidgetPrivate::resolvePalette(uint inheritedMask)
-{
- inheritedPaletteResolveMask = inheritedMask;
- QPalette naturalPalette = naturalWidgetPalette();
- QPalette resolvedPalette = palette.resolve(naturalPalette);
- updatePalette(resolvedPalette);
-}
-
-void QGraphicsWidgetPrivate::updatePalette(const QPalette &palette)
-{
- Q_Q(QGraphicsWidget);
- // Update local palette setting.
- this->palette = palette;
-
- // Calculate new mask.
- if (q->isWindow() && !q->testAttribute(Qt::WA_WindowPropagation))
- inheritedPaletteResolveMask = 0;
- int mask = palette.resolve() | inheritedPaletteResolveMask;
-
- // Propagate to children.
- for (int i = 0; i < children.size(); ++i) {
- QGraphicsItem *item = children.at(i);
- if (item->isWidget()) {
- QGraphicsWidget *w = static_cast<QGraphicsWidget *>(item);
- if (!w->isWindow() || w->testAttribute(Qt::WA_WindowPropagation))
- w->d_func()->resolvePalette(mask);
- } else {
- item->d_ptr->resolvePalette(mask);
- }
- }
-
- // Notify change.
- QEvent event(QEvent::PaletteChange);
- QApplication::sendEvent(q, &event);
-}
-
-void QGraphicsWidgetPrivate::setLayoutDirection_helper(Qt::LayoutDirection direction)
-{
- Q_Q(QGraphicsWidget);
- if ((direction == Qt::RightToLeft) == (testAttribute(Qt::WA_RightToLeft)))
- return;
- q->setAttribute(Qt::WA_RightToLeft, (direction == Qt::RightToLeft));
-
- // Propagate this change to all children.
- for (int i = 0; i < children.size(); ++i) {
- QGraphicsItem *item = children.at(i);
- if (item->isWidget()) {
- QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(item);
- if (widget->parentWidget() && !widget->testAttribute(Qt::WA_SetLayoutDirection))
- widget->d_func()->setLayoutDirection_helper(direction);
- }
- }
-
- // Send the notification event to this widget item.
- QEvent e(QEvent::LayoutDirectionChange);
- QApplication::sendEvent(q, &e);
-}
-
-void QGraphicsWidgetPrivate::resolveLayoutDirection()
-{
- Q_Q(QGraphicsWidget);
- if (q->testAttribute(Qt::WA_SetLayoutDirection)) {
- return;
- }
- if (QGraphicsWidget *parentWidget = q->parentWidget()) {
- setLayoutDirection_helper(parentWidget->layoutDirection());
- } else if (scene) {
- // ### shouldn't the scene have a layoutdirection really? how does
- // ### QGraphicsWidget get changes from QApplication::layoutDirection?
- setLayoutDirection_helper(QApplication::layoutDirection());
- } else {
- setLayoutDirection_helper(QApplication::layoutDirection());
- }
-}
-
-QPalette QGraphicsWidgetPrivate::naturalWidgetPalette() const
-{
- Q_Q(const QGraphicsWidget);
- QPalette palette;
- if (QGraphicsWidget *parent = q->parentWidget()) {
- palette = parent->palette();
- } else if (scene) {
- palette = scene->palette();
- }
- palette.resolve(0);
- return palette;
-}
-
-void QGraphicsWidgetPrivate::setFont_helper(const QFont &font)
-{
- if (this->font == font && this->font.resolve() == font.resolve())
- return;
- updateFont(font);
-}
-
-void QGraphicsWidgetPrivate::resolveFont(uint inheritedMask)
-{
- Q_Q(QGraphicsWidget);
- inheritedFontResolveMask = inheritedMask;
- if (QGraphicsWidget *p = q->parentWidget())
- inheritedFontResolveMask |= p->d_func()->inheritedFontResolveMask;
- QFont naturalFont = naturalWidgetFont();
- QFont resolvedFont = font.resolve(naturalFont);
- updateFont(resolvedFont);
-}
-
-void QGraphicsWidgetPrivate::updateFont(const QFont &font)
-{
- Q_Q(QGraphicsWidget);
- // Update the local font setting.
- this->font = font;
-
- // Calculate new mask.
- if (q->isWindow() && !q->testAttribute(Qt::WA_WindowPropagation))
- inheritedFontResolveMask = 0;
- int mask = font.resolve() | inheritedFontResolveMask;
-
- // Propagate to children.
- for (int i = 0; i < children.size(); ++i) {
- QGraphicsItem *item = children.at(i);
- if (item->isWidget()) {
- QGraphicsWidget *w = static_cast<QGraphicsWidget *>(item);
- if (!w->isWindow() || w->testAttribute(Qt::WA_WindowPropagation))
- w->d_func()->resolveFont(mask);
- } else {
- item->d_ptr->resolveFont(mask);
- }
- }
-
- if (!polished)
- return;
- // Notify change.
- QEvent event(QEvent::FontChange);
- QApplication::sendEvent(q, &event);
-}
-
-QFont QGraphicsWidgetPrivate::naturalWidgetFont() const
-{
- Q_Q(const QGraphicsWidget);
- QFont naturalFont; // ### no application font support
- if (QGraphicsWidget *parent = q->parentWidget()) {
- naturalFont = parent->font();
- } else if (scene) {
- naturalFont = scene->font();
- }
- naturalFont.resolve(0);
- return naturalFont;
-}
-
-void QGraphicsWidgetPrivate::initStyleOptionTitleBar(QStyleOptionTitleBar *option)
-{
- Q_Q(QGraphicsWidget);
- ensureWindowData();
- q->initStyleOption(option);
- option->rect.setHeight(titleBarHeight(*option));
- option->titleBarFlags = windowFlags;
- option->subControls = QStyle::SC_TitleBarCloseButton | QStyle::SC_TitleBarLabel | QStyle::SC_TitleBarSysMenu;
- option->activeSubControls = windowData->hoveredSubControl;
- bool isActive = q->isActiveWindow();
- if (isActive) {
- option->state |= QStyle::State_Active;
- option->titleBarState = Qt::WindowActive;
- option->titleBarState |= QStyle::State_Active;
- } else {
- option->state &= ~QStyle::State_Active;
- option->titleBarState = Qt::WindowNoState;
- }
- QFont windowTitleFont = QApplication::font("QWorkspaceTitleBar");
- QRect textRect = q->style()->subControlRect(QStyle::CC_TitleBar, option, QStyle::SC_TitleBarLabel, 0);
- option->text = QFontMetrics(windowTitleFont).elidedText(
- windowData->windowTitle, Qt::ElideRight, textRect.width());
-}
-
-void QGraphicsWidgetPrivate::adjustWindowFlags(Qt::WindowFlags *flags)
-{
- bool customize = (*flags & (Qt::CustomizeWindowHint
- | Qt::FramelessWindowHint
- | Qt::WindowTitleHint
- | Qt::WindowSystemMenuHint
- | Qt::WindowMinimizeButtonHint
- | Qt::WindowMaximizeButtonHint
- | Qt::WindowContextHelpButtonHint));
-
- uint type = (*flags & Qt::WindowType_Mask);
- if (customize)
- ;
- else if (type == Qt::Dialog || type == Qt::Sheet)
- *flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowContextHelpButtonHint;
- else if (type == Qt::Tool)
- *flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint;
- else if (type == Qt::Window || type == Qt::SubWindow)
- *flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint
- | Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint;
-}
-
-void QGraphicsWidgetPrivate::windowFrameMouseReleaseEvent(QGraphicsSceneMouseEvent *event)
-{
- Q_Q(QGraphicsWidget);
- ensureWindowData();
- if (windowData->grabbedSection != Qt::NoSection) {
- if (windowData->grabbedSection == Qt::TitleBarArea) {
- windowData->buttonSunken = false;
- QStyleOptionTitleBar bar;
- initStyleOptionTitleBar(&bar);
- // make sure that the coordinates (rect and pos) we send to the style are positive.
- bar.rect = q->windowFrameRect().toRect();
- bar.rect.moveTo(0,0);
- bar.rect.setHeight(q->style()->pixelMetric(QStyle::PM_TitleBarHeight, &bar));
- QPointF pos = event->pos();
- if (windowFrameMargins) {
- pos.rx() += windowFrameMargins[Left];
- pos.ry() += windowFrameMargins[Top];
- }
- bar.subControls = QStyle::SC_TitleBarCloseButton;
- if (q->style()->subControlRect(QStyle::CC_TitleBar, &bar,
- QStyle::SC_TitleBarCloseButton,
- event->widget()).contains(pos.toPoint())) {
- q->close();
- }
- }
- if (!(static_cast<QGraphicsSceneMouseEvent *>(event)->buttons()))
- windowData->grabbedSection = Qt::NoSection;
- event->accept();
- }
-}
-
-void QGraphicsWidgetPrivate::windowFrameMousePressEvent(QGraphicsSceneMouseEvent *event)
-{
- Q_Q(QGraphicsWidget);
- if (event->button() != Qt::LeftButton)
- return;
-
- ensureWindowData();
- windowData->startGeometry = q->geometry();
- windowData->grabbedSection = q->windowFrameSectionAt(event->pos());
- ensureWindowData();
- if (windowData->grabbedSection == Qt::TitleBarArea
- && windowData->hoveredSubControl == QStyle::SC_TitleBarCloseButton) {
- windowData->buttonSunken = true;
- q->update();
- }
- event->setAccepted(windowData->grabbedSection != Qt::NoSection);
-}
-
-/*!
- Used to calculate the
- Precondition:
- \a widget should support either hfw or wfh
-
- If \a heightForWidth is set to false, this function will query the width for height
- instead. \a width will then be interpreted as height, \a minh and \a maxh will be interpreted
- as minimum width and maximum width.
- */
-static qreal minimumHeightForWidth(qreal width, qreal minh, qreal maxh,
- const QGraphicsWidget *widget,
- bool heightForWidth = true)
-{
- qreal minimumHeightForWidth = -1;
- const bool hasHFW = QGraphicsLayoutItemPrivate::get(widget)->hasHeightForWidth();
- if (hasHFW == heightForWidth) {
- minimumHeightForWidth = hasHFW
- ? widget->effectiveSizeHint(Qt::MinimumSize, QSizeF(width, -1)).height()
- : widget->effectiveSizeHint(Qt::MinimumSize, QSizeF(-1, width)).width(); //"width" is here height!
- } else {
- // widthForHeight
- const qreal constraint = width;
- while (maxh - minh > 0.1) {
- qreal middle = minh + (maxh - minh)/2;
- // ### really bad, if we are a widget with a layout it will call
- // layout->effectiveSizeHint(Qt::MiniumumSize), which again will call
- // sizeHint three times because of how the cache works
- qreal hfw = hasHFW
- ? widget->effectiveSizeHint(Qt::MinimumSize, QSizeF(middle, -1)).height()
- : widget->effectiveSizeHint(Qt::MinimumSize, QSizeF(-1, middle)).width();
- if (hfw > constraint) {
- minh = middle;
- } else if (hfw <= constraint) {
- maxh = middle;
- }
- }
- minimumHeightForWidth = maxh;
- }
- return minimumHeightForWidth;
-}
-
-static qreal minimumWidthForHeight(qreal height, qreal minw, qreal maxw,
- const QGraphicsWidget *widget)
-{
- return minimumHeightForWidth(height, minw, maxw, widget, false);
-}
-
-static QSizeF closestAcceptableSize(const QSizeF &proposed,
- const QGraphicsWidget *widget)
-{
- const QSizeF current = widget->size();
-
- qreal minw = proposed.width();
- qreal maxw = current.width();
- qreal minh = proposed.height();
- qreal maxh = current.height();
-
- qreal middlew = maxw;
- qreal middleh = maxh;
- qreal min_hfw;
- min_hfw = minimumHeightForWidth(maxw, minh, maxh, widget);
-
- do {
- if (maxw - minw < 0.1) {
- // we still havent found anything, cut off binary search
- minw = maxw;
- minh = maxh;
- }
- middlew = minw + (maxw - minw)/2.0;
- middleh = minh + (maxh - minh)/2.0;
-
- min_hfw = minimumHeightForWidth(middlew, minh, maxh, widget);
-
- if (min_hfw > middleh) {
- minw = middlew;
- minh = middleh;
- } else if (min_hfw <= middleh) {
- maxw = middlew;
- maxh = middleh;
- }
- } while (maxw != minw);
-
- min_hfw = minimumHeightForWidth(middlew, minh, maxh, widget);
-
- QSizeF result;
- if (min_hfw < maxh) {
- result = QSizeF(middlew, min_hfw);
- } else {
- // Needed because of the cut-off we do above.
- result = QSizeF(minimumWidthForHeight(maxh, proposed.width(), current.width(), widget), maxh);
- }
- return result;
-}
-
-static void _q_boundGeometryToSizeConstraints(const QRectF &startGeometry,
- QRectF *rect, Qt::WindowFrameSection section,
- const QSizeF &min, const QSizeF &max,
- const QGraphicsWidget *widget)
-{
- const QRectF proposedRect = *rect;
- qreal width = qBound(min.width(), proposedRect.width(), max.width());
- qreal height = qBound(min.height(), proposedRect.height(), max.height());
-
- const bool hasHFW = QGraphicsLayoutItemPrivate::get(widget)->hasHeightForWidth();
- const bool hasWFH = QGraphicsLayoutItemPrivate::get(widget)->hasWidthForHeight();
-
- const bool widthChanged = proposedRect.width() != widget->size().width();
- const bool heightChanged = proposedRect.height() != widget->size().height();
-
- if (hasHFW || hasWFH) {
- if (widthChanged || heightChanged) {
- qreal minExtent;
- qreal maxExtent;
- qreal constraint;
- qreal proposed;
- if (hasHFW) {
- minExtent = min.height();
- maxExtent = max.height();
- constraint = width;
- proposed = proposedRect.height();
- } else {
- // width for height
- minExtent = min.width();
- maxExtent = max.width();
- constraint = height;
- proposed = proposedRect.width();
- }
- if (minimumHeightForWidth(constraint, minExtent, maxExtent, widget, hasHFW) > proposed) {
- QSizeF effectiveSize = closestAcceptableSize(QSizeF(width, height), widget);
- width = effectiveSize.width();
- height = effectiveSize.height();
- }
- }
- }
-
- switch (section) {
- case Qt::LeftSection:
- rect->setRect(startGeometry.right() - qRound(width), startGeometry.top(),
- qRound(width), startGeometry.height());
- break;
- case Qt::TopLeftSection:
- rect->setRect(startGeometry.right() - qRound(width), startGeometry.bottom() - qRound(height),
- qRound(width), qRound(height));
- break;
- case Qt::TopSection:
- rect->setRect(startGeometry.left(), startGeometry.bottom() - qRound(height),
- startGeometry.width(), qRound(height));
- break;
- case Qt::TopRightSection:
- rect->setTop(rect->bottom() - qRound(height));
- rect->setWidth(qRound(width));
- break;
- case Qt::RightSection:
- rect->setWidth(qRound(width));
- break;
- case Qt::BottomRightSection:
- rect->setWidth(qRound(width));
- rect->setHeight(qRound(height));
- break;
- case Qt::BottomSection:
- rect->setHeight(qRound(height));
- break;
- case Qt::BottomLeftSection:
- rect->setRect(startGeometry.right() - qRound(width), startGeometry.top(),
- qRound(width), qRound(height));
- break;
- default:
- break;
- }
-}
-
-void QGraphicsWidgetPrivate::windowFrameMouseMoveEvent(QGraphicsSceneMouseEvent *event)
-{
- Q_Q(QGraphicsWidget);
- ensureWindowData();
- if (!(event->buttons() & Qt::LeftButton) || windowData->hoveredSubControl != QStyle::SC_TitleBarLabel)
- return;
-
- QLineF delta(q->mapFromScene(event->buttonDownScenePos(Qt::LeftButton)), event->pos());
- QLineF parentDelta(q->mapToParent(delta.p1()), q->mapToParent(delta.p2()));
- QLineF parentXDelta(q->mapToParent(QPointF(delta.p1().x(), 0)), q->mapToParent(QPointF(delta.p2().x(), 0)));
- QLineF parentYDelta(q->mapToParent(QPointF(0, delta.p1().y())), q->mapToParent(QPointF(0, delta.p2().y())));
-
- QRectF newGeometry;
- switch (windowData->grabbedSection) {
- case Qt::LeftSection:
- newGeometry = QRectF(windowData->startGeometry.topLeft()
- + QPointF(parentXDelta.dx(), parentXDelta.dy()),
- windowData->startGeometry.size() - QSizeF(delta.dx(), delta.dy()));
- break;
- case Qt::TopLeftSection:
- newGeometry = QRectF(windowData->startGeometry.topLeft()
- + QPointF(parentDelta.dx(), parentDelta.dy()),
- windowData->startGeometry.size() - QSizeF(delta.dx(), delta.dy()));
- break;
- case Qt::TopSection:
- newGeometry = QRectF(windowData->startGeometry.topLeft()
- + QPointF(parentYDelta.dx(), parentYDelta.dy()),
- windowData->startGeometry.size() - QSizeF(0, delta.dy()));
- break;
- case Qt::TopRightSection:
- newGeometry = QRectF(windowData->startGeometry.topLeft()
- + QPointF(parentYDelta.dx(), parentYDelta.dy()),
- windowData->startGeometry.size() - QSizeF(-delta.dx(), delta.dy()));
- break;
- case Qt::RightSection:
- newGeometry = QRectF(windowData->startGeometry.topLeft(),
- windowData->startGeometry.size() + QSizeF(delta.dx(), 0));
- break;
- case Qt::BottomRightSection:
- newGeometry = QRectF(windowData->startGeometry.topLeft(),
- windowData->startGeometry.size() + QSizeF(delta.dx(), delta.dy()));
- break;
- case Qt::BottomSection:
- newGeometry = QRectF(windowData->startGeometry.topLeft(),
- windowData->startGeometry.size() + QSizeF(0, delta.dy()));
- break;
- case Qt::BottomLeftSection:
- newGeometry = QRectF(windowData->startGeometry.topLeft()
- + QPointF(parentXDelta.dx(), parentXDelta.dy()),
- windowData->startGeometry.size() - QSizeF(delta.dx(), -delta.dy()));
- break;
- case Qt::TitleBarArea:
- newGeometry = QRectF(windowData->startGeometry.topLeft()
- + QPointF(parentDelta.dx(), parentDelta.dy()),
- windowData->startGeometry.size());
- break;
- case Qt::NoSection:
- break;
- }
-
- if (windowData->grabbedSection != Qt::NoSection) {
- _q_boundGeometryToSizeConstraints(windowData->startGeometry, &newGeometry,
- windowData->grabbedSection,
- q->effectiveSizeHint(Qt::MinimumSize),
- q->effectiveSizeHint(Qt::MaximumSize),
- q);
- q->setGeometry(newGeometry);
- }
-}
-
-void QGraphicsWidgetPrivate::windowFrameHoverMoveEvent(QGraphicsSceneHoverEvent *event)
-{
- Q_Q(QGraphicsWidget);
- if (!hasDecoration())
- return;
-
- ensureWindowData();
-
- if (q->rect().contains(event->pos())) {
- if (windowData->buttonMouseOver || windowData->hoveredSubControl != QStyle::SC_None)
- windowFrameHoverLeaveEvent(event);
- return;
- }
-
- bool wasMouseOver = windowData->buttonMouseOver;
- QRect oldButtonRect = windowData->buttonRect;
- windowData->buttonRect = QRect();
- windowData->buttonMouseOver = false;
- QPointF pos = event->pos();
- QStyleOptionTitleBar bar;
- // make sure that the coordinates (rect and pos) we send to the style are positive.
- if (windowFrameMargins) {
- pos.rx() += windowFrameMargins[Left];
- pos.ry() += windowFrameMargins[Top];
- }
- initStyleOptionTitleBar(&bar);
- bar.rect = q->windowFrameRect().toRect();
- bar.rect.moveTo(0,0);
- bar.rect.setHeight(int(titleBarHeight(bar)));
-
- Qt::CursorShape cursorShape = Qt::ArrowCursor;
- bool needsSetCursorCall = true;
- switch (q->windowFrameSectionAt(event->pos())) {
- case Qt::TopLeftSection:
- case Qt::BottomRightSection:
- cursorShape = Qt::SizeFDiagCursor;
- break;
- case Qt::TopRightSection:
- case Qt::BottomLeftSection:
- cursorShape = Qt::SizeBDiagCursor;
- break;
- case Qt::LeftSection:
- case Qt::RightSection:
- cursorShape = Qt::SizeHorCursor;
- break;
- case Qt::TopSection:
- case Qt::BottomSection:
- cursorShape = Qt::SizeVerCursor;
- break;
- case Qt::TitleBarArea:
- windowData->buttonRect = q->style()->subControlRect(
- QStyle::CC_TitleBar, &bar, QStyle::SC_TitleBarCloseButton, 0);
-#ifdef Q_WS_MAC
- // On mac we should hover if we are in the 'area' of the buttons
- windowData->buttonRect |= q->style()->subControlRect(
- QStyle::CC_TitleBar, &bar, QStyle::SC_TitleBarMinButton, 0);
- windowData->buttonRect |= q->style()->subControlRect(
- QStyle::CC_TitleBar, &bar, QStyle::SC_TitleBarMaxButton, 0);
-#endif
- if (windowData->buttonRect.contains(pos.toPoint()))
- windowData->buttonMouseOver = true;
- event->ignore();
- break;
- default:
- needsSetCursorCall = false;
- event->ignore();
- }
-#ifndef QT_NO_CURSOR
- if (needsSetCursorCall)
- q->setCursor(cursorShape);
-#endif
- // update buttons if we hover over them
- windowData->hoveredSubControl = q->style()->hitTestComplexControl(QStyle::CC_TitleBar, &bar, pos.toPoint(), 0);
- if (windowData->hoveredSubControl != QStyle::SC_TitleBarCloseButton)
- windowData->hoveredSubControl = QStyle::SC_TitleBarLabel;
-
- if (windowData->buttonMouseOver != wasMouseOver) {
- if (!oldButtonRect.isNull())
- q->update(QRectF(oldButtonRect).translated(q->windowFrameRect().topLeft()));
- if (!windowData->buttonRect.isNull())
- q->update(QRectF(windowData->buttonRect).translated(q->windowFrameRect().topLeft()));
- }
-}
-
-void QGraphicsWidgetPrivate::windowFrameHoverLeaveEvent(QGraphicsSceneHoverEvent *event)
-{
- Q_UNUSED(event);
- Q_Q(QGraphicsWidget);
- if (hasDecoration()) {
- // ### restore the cursor, don't override it
-#ifndef QT_NO_CURSOR
- q->unsetCursor();
-#endif
-
- ensureWindowData();
-
- bool needsUpdate = false;
- if (windowData->hoveredSubControl == QStyle::SC_TitleBarCloseButton
- || windowData->buttonMouseOver)
- needsUpdate = true;
-
- // update the hover state (of buttons etc...)
- windowData->hoveredSubControl = QStyle::SC_None;
- windowData->buttonMouseOver = false;
- windowData->buttonRect = QRect();
- if (needsUpdate)
- q->update(windowData->buttonRect);
- }
-}
-
-bool QGraphicsWidgetPrivate::hasDecoration() const
-{
- return (windowFlags & Qt::Window) && (windowFlags & Qt::WindowTitleHint);
-}
-
-/**
- * is called after a reparent has taken place to fix up the focus chain(s)
- */
-void QGraphicsWidgetPrivate::fixFocusChainBeforeReparenting(QGraphicsWidget *newParent, QGraphicsScene *oldScene, QGraphicsScene *newScene)
-{
- Q_Q(QGraphicsWidget);
-
- Q_ASSERT(focusNext && focusPrev);
-
- QGraphicsWidget *n = q; //last one in 'new' list
- QGraphicsWidget *o = 0; //last one in 'old' list
-
- QGraphicsWidget *w = focusNext;
-
- QGraphicsWidget *firstOld = 0;
- bool wasPreviousNew = true;
-
- while (w != q) {
- bool isCurrentNew = q->isAncestorOf(w);
- if (isCurrentNew) {
- if (!wasPreviousNew) {
- n->d_func()->focusNext = w;
- w->d_func()->focusPrev = n;
- }
- n = w;
- } else /*if (!isCurrentNew)*/ {
- if (wasPreviousNew) {
- if (o) {
- o->d_func()->focusNext = w;
- w->d_func()->focusPrev = o;
- } else {
- firstOld = w;
- }
- }
- o = w;
- }
- w = w->d_func()->focusNext;
- wasPreviousNew = isCurrentNew;
- }
-
- // repair the 'old' chain
- if (firstOld) {
- o->d_func()->focusNext = firstOld;
- firstOld->d_func()->focusPrev = o;
- }
-
- // update tabFocusFirst for oldScene if the item is going to be removed from oldScene
- if (newParent)
- newScene = newParent->scene();
-
- if (oldScene && newScene != oldScene)
- oldScene->d_func()->tabFocusFirst = (firstOld && firstOld->scene() == oldScene) ? firstOld : 0;
-
- QGraphicsItem *topLevelItem = newParent ? newParent->topLevelItem() : 0;
- QGraphicsWidget *topLevel = 0;
- if (topLevelItem && topLevelItem->isWidget())
- topLevel = static_cast<QGraphicsWidget *>(topLevelItem);
-
- if (topLevel && newParent) {
- QGraphicsWidget *last = topLevel->d_func()->focusPrev;
- // link last with new chain
- last->d_func()->focusNext = q;
- focusPrev = last;
-
- // link last in chain with
- topLevel->d_func()->focusPrev = n;
- n->d_func()->focusNext = topLevel;
- } else {
- // q is the start of the focus chain
- n->d_func()->focusNext = q;
- focusPrev = n;
- }
-
-}
-
-void QGraphicsWidgetPrivate::setLayout_helper(QGraphicsLayout *l)
-{
- delete (this->layout);
- layout = l;
- if (!l) {
- Q_Q(QGraphicsWidget);
- q->updateGeometry();
- }
-}
-
-qreal QGraphicsWidgetPrivate::width() const
-{
- Q_Q(const QGraphicsWidget);
- return q->geometry().width();
-}
-
-void QGraphicsWidgetPrivate::setWidth(qreal w)
-{
- if (qIsNaN(w))
- return;
- Q_Q(QGraphicsWidget);
- if (q->geometry().width() == w)
- return;
-
- q->setGeometry(QRectF(q->x(), q->y(), w, height()));
-}
-
-void QGraphicsWidgetPrivate::resetWidth()
-{
- Q_Q(QGraphicsWidget);
- q->setGeometry(QRectF(q->x(), q->y(), 0, height()));
-}
-
-qreal QGraphicsWidgetPrivate::height() const
-{
- Q_Q(const QGraphicsWidget);
- return q->geometry().height();
-}
-
-void QGraphicsWidgetPrivate::setHeight(qreal h)
-{
- if (qIsNaN(h))
- return;
- Q_Q(QGraphicsWidget);
- if (q->geometry().height() == h)
- return;
-
- q->setGeometry(QRectF(q->x(), q->y(), width(), h));
-}
-
-void QGraphicsWidgetPrivate::resetHeight()
-{
- Q_Q(QGraphicsWidget);
- q->setGeometry(QRectF(q->x(), q->y(), width(), 0));
-}
-
-void QGraphicsWidgetPrivate::setGeometryFromSetPos()
-{
- if (inSetGeometry)
- return;
- Q_Q(QGraphicsWidget);
- inSetPos = 1;
- // Ensure setGeometry is called (avoid recursion when setPos is
- // called from within setGeometry).
- q->setGeometry(QRectF(pos, q->size()));
- inSetPos = 0 ;
-}
-
-QT_END_NAMESPACE
-
-#endif //QT_NO_GRAPHICSVIEW
diff --git a/src/gui/graphicsview/qgraphicswidget_p.h b/src/gui/graphicsview/qgraphicswidget_p.h
deleted file mode 100644
index 398abc33ef..0000000000
--- a/src/gui/graphicsview/qgraphicswidget_p.h
+++ /dev/null
@@ -1,226 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGRAPHICSWIDGET_P_H
-#define QGRAPHICSWIDGET_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <private/qobject_p.h>
-#include "qgraphicsitem_p.h"
-#include "qgraphicswidget.h"
-#include <QtGui/qfont.h>
-#include <QtGui/qpalette.h>
-#include <QtGui/qsizepolicy.h>
-#include <QtGui/qstyle.h>
-
-QT_BEGIN_NAMESPACE
-
-class QGraphicsLayout;
-class QStyleOptionTitleBar;
-
-#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW
-
-class QGraphicsWidgetPrivate : public QGraphicsItemPrivate
-{
- Q_DECLARE_PUBLIC(QGraphicsWidget)
-public:
- QGraphicsWidgetPrivate()
- : margins(0),
- layout(0),
- inheritedPaletteResolveMask(0),
- inheritedFontResolveMask(0),
- inSetGeometry(0),
- polished(0),
- inSetPos(0),
- autoFillBackground(0),
- focusPolicy(Qt::NoFocus),
- focusNext(0),
- focusPrev(0),
- windowFlags(0),
- windowData(0),
- setWindowFrameMargins(false),
- windowFrameMargins(0)
- { }
- virtual ~QGraphicsWidgetPrivate();
-
- void init(QGraphicsItem *parentItem, Qt::WindowFlags wFlags);
- qreal titleBarHeight(const QStyleOptionTitleBar &options) const;
-
- // Margins
- enum {Left, Top, Right, Bottom};
- mutable qreal *margins;
- void ensureMargins() const;
-
- void fixFocusChainBeforeReparenting(QGraphicsWidget *newParent, QGraphicsScene *oldScene, QGraphicsScene *newScene = 0);
- void setLayout_helper(QGraphicsLayout *l);
-
- // Layouts
- QGraphicsLayout *layout;
- void setLayoutDirection_helper(Qt::LayoutDirection direction);
- void resolveLayoutDirection();
-
- // Style
- QPalette palette;
- uint inheritedPaletteResolveMask;
- void setPalette_helper(const QPalette &palette);
- void resolvePalette(uint inheritedMask);
- void updatePalette(const QPalette &palette);
- QPalette naturalWidgetPalette() const;
- QFont font;
- uint inheritedFontResolveMask;
- void setFont_helper(const QFont &font);
- void resolveFont(uint inheritedMask);
- void updateFont(const QFont &font);
- QFont naturalWidgetFont() const;
-
- // Window specific
- void initStyleOptionTitleBar(QStyleOptionTitleBar *option);
- void adjustWindowFlags(Qt::WindowFlags *wFlags);
- void windowFrameMouseReleaseEvent(QGraphicsSceneMouseEvent *event);
- void windowFrameMousePressEvent(QGraphicsSceneMouseEvent *event);
- void windowFrameMouseMoveEvent(QGraphicsSceneMouseEvent *event);
- void windowFrameHoverMoveEvent(QGraphicsSceneHoverEvent *event);
- void windowFrameHoverLeaveEvent(QGraphicsSceneHoverEvent *event);
- bool hasDecoration() const;
-
- // Private Properties
- qreal width() const;
- void setWidth(qreal);
- void resetWidth();
-
- qreal height() const;
- void setHeight(qreal);
- void resetHeight();
- void setGeometryFromSetPos();
-
- // State
- inline int attributeToBitIndex(Qt::WidgetAttribute att) const
- {
- int bit = -1;
- switch (att) {
- case Qt::WA_SetLayoutDirection: bit = 0; break;
- case Qt::WA_RightToLeft: bit = 1; break;
- case Qt::WA_SetStyle: bit = 2; break;
- case Qt::WA_Resized: bit = 3; break;
- case Qt::WA_DeleteOnClose: bit = 4; break;
- case Qt::WA_NoSystemBackground: bit = 5; break;
- case Qt::WA_OpaquePaintEvent: bit = 6; break;
- case Qt::WA_SetPalette: bit = 7; break;
- case Qt::WA_SetFont: bit = 8; break;
- case Qt::WA_WindowPropagation: bit = 9; break;
- default: break;
- }
- return bit;
- }
- inline void setAttribute(Qt::WidgetAttribute att, bool value)
- {
- int bit = attributeToBitIndex(att);
- if (bit == -1) {
- qWarning("QGraphicsWidget::setAttribute: unsupported attribute %d", int(att));
- return;
- }
- if (value)
- attributes |= (1 << bit);
- else
- attributes &= ~(1 << bit);
- }
- inline bool testAttribute(Qt::WidgetAttribute att) const
- {
- int bit = attributeToBitIndex(att);
- if (bit == -1)
- return false;
- return (attributes & (1 << bit)) != 0;
- }
- quint32 attributes : 10;
- quint32 inSetGeometry : 1;
- quint32 polished: 1;
- quint32 inSetPos : 1;
- quint32 autoFillBackground : 1;
-
- // Focus
- Qt::FocusPolicy focusPolicy;
- QGraphicsWidget *focusNext;
- QGraphicsWidget *focusPrev;
-
- // Windows
- Qt::WindowFlags windowFlags;
- struct WindowData {
- QString windowTitle;
- QStyle::SubControl hoveredSubControl;
- Qt::WindowFrameSection grabbedSection;
- uint buttonMouseOver : 1;
- uint buttonSunken : 1;
- QRectF startGeometry;
- QRect buttonRect;
- WindowData()
- : hoveredSubControl(QStyle::SC_None)
- , grabbedSection(Qt::NoSection)
- , buttonMouseOver(false)
- , buttonSunken(false)
- {}
- } *windowData;
- void ensureWindowData();
-
- bool setWindowFrameMargins;
- mutable qreal *windowFrameMargins;
- void ensureWindowFrameMargins() const;
-
-#ifndef QT_NO_ACTION
- QList<QAction *> actions;
-#endif
-};
-
-#endif //!defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW
-
-QT_END_NAMESPACE
-
-#endif //QGRAPHICSWIDGET_P_H
-
diff --git a/src/gui/gui.pro b/src/gui/gui.pro
index 58e1d6c45f..4ee9d764ec 100644
--- a/src/gui/gui.pro
+++ b/src/gui/gui.pro
@@ -8,10 +8,6 @@ CONFIG += module
MODULE_PRI = ../modules/qt_gui.pri
DEFINES += QT_BUILD_GUI_LIB QT_NO_USING_NAMESPACE
-win32-msvc*|win32-icc:QMAKE_LFLAGS += /BASE:0x65000000
-irix-cc*:QMAKE_CXXFLAGS += -no_prelink -ptused
-
-!win32:!embedded:!qpa:!mac:!symbian:CONFIG += x11
unix|win32-g++*:QMAKE_PKGCONFIG_REQUIRES = QtCore
@@ -19,54 +15,19 @@ load(qt_module_config)
HEADERS += $$QT_SOURCE_TREE/src/gui/qtguiversion.h
-contains(QT_CONFIG, x11sm):CONFIG += x11sm
-
-#platforms
-x11:include(kernel/x11.pri)
-mac:include(kernel/mac.pri)
-win32:include(kernel/win.pri)
-embedded:include(embedded/embedded.pri)
-symbian {
- include(kernel/symbian.pri)
- include(s60framework/s60framework.pri)
-}
-
-#modules
-include(animation/animation.pri)
include(kernel/kernel.pri)
include(image/image.pri)
-include(painting/painting.pri)
include(text/text.pri)
-include(styles/styles.pri)
-include(widgets/widgets.pri)
-include(dialogs/dialogs.pri)
-include(accessible/accessible.pri)
-include(itemviews/itemviews.pri)
-include(inputmethod/inputmethod.pri)
-include(graphicsview/graphicsview.pri)
+include(painting/painting.pri)
include(util/util.pri)
-include(statemachine/statemachine.pri)
include(math3d/math3d.pri)
-include(effects/effects.pri)
+include(opengl/opengl.pri)
include(egl/egl.pri)
-win32:!wince*: DEFINES += QT_NO_EGL
-embedded: QT += network
QMAKE_LIBS += $$QMAKE_LIBS_GUI
-contains(DEFINES,QT_EVAL):include($$QT_SOURCE_TREE/src/corelib/eval.pri)
-
-QMAKE_DYNAMIC_LIST_FILE = $$PWD/QtGui.dynlist
-
DEFINES += Q_INTERNAL_QAPP_SRC
-symbian {
- TARGET.UID3=0x2001B2DD
-
- # ro-section in gui can exceed default allocated space, so move rw-section a little further
- QMAKE_LFLAGS.ARMCC += --rw-base 0x800000
- QMAKE_LFLAGS.GCCE += -Tdata 0x800000
-}
neon:*-g++* {
DEFINES += QT_HAVE_NEON
diff --git a/src/gui/image/image.pri b/src/gui/image/image.pri
index 72738c9fa8..3ccfb04fcc 100644
--- a/src/gui/image/image.pri
+++ b/src/gui/image/image.pri
@@ -5,11 +5,6 @@
HEADERS += \
image/qbitmap.h \
- image/qicon.h \
- image/qicon_p.h \
- image/qiconloader_p.h \
- image/qiconengine.h \
- image/qiconengineplugin.h \
image/qimage.h \
image/qimage_p.h \
image/qimageiohandler.h \
@@ -26,18 +21,13 @@ HEADERS += \
image/qpixmap_blitter_p.h \
image/qpixmapcache.h \
image/qpixmapcache_p.h \
- image/qpixmapdata_p.h \
- image/qpixmapdatafactory_p.h \
- image/qpixmapfilter_p.h \
+ image/qplatformpixmap_qpa.h \
image/qimagepixmapcleanuphooks_p.h \
image/qvolatileimage_p.h \
- image/qvolatileimagedata_p.h \
- image/qnativeimagehandleprovider_p.h
+ image/qvolatileimagedata_p.h
SOURCES += \
image/qbitmap.cpp \
- image/qicon.cpp \
- image/qiconloader.cpp \
image/qimage.cpp \
image/qimageiohandler.cpp \
image/qimagereader.cpp \
@@ -47,11 +37,7 @@ SOURCES += \
image/qpictureformatplugin.cpp \
image/qpixmap.cpp \
image/qpixmapcache.cpp \
- image/qpixmapdata.cpp \
- image/qpixmapdatafactory.cpp \
- image/qpixmapfilter.cpp \
- image/qiconengine.cpp \
- image/qiconengineplugin.cpp \
+ image/qplatformpixmap.cpp \
image/qmovie.cpp \
image/qpixmap_raster.cpp \
image/qpixmap_blitter.cpp \
@@ -59,15 +45,12 @@ SOURCES += \
image/qimagepixmapcleanuphooks.cpp \
image/qvolatileimage.cpp
-win32 {
- SOURCES += image/qpixmap_win.cpp
-}
-else:embedded {
- SOURCES += image/qpixmap_qws.cpp
-}
-else:qpa {
+qpa: {
SOURCES += image/qpixmap_qpa.cpp
}
+else:win32 {
+ SOURCES += image/qpixmap_win.cpp
+}
else:x11 {
HEADERS += image/qpixmap_x11_p.h
SOURCES += image/qpixmap_x11.cpp
diff --git a/src/gui/image/qbitmap.cpp b/src/gui/image/qbitmap.cpp
index c0cab83926..f32c517f17 100644
--- a/src/gui/image/qbitmap.cpp
+++ b/src/gui/image/qbitmap.cpp
@@ -40,12 +40,12 @@
****************************************************************************/
#include "qbitmap.h"
-#include "qpixmapdata_p.h"
+#include "qplatformpixmap_qpa.h"
#include "qimage.h"
+#include "qscreen.h"
#include "qvariant.h"
#include <qpainter.h>
-#include <private/qgraphicssystem_p.h>
-#include <private/qapplication_p.h>
+#include <private/qguiapplication_p.h>
QT_BEGIN_NAMESPACE
@@ -102,7 +102,7 @@ QT_BEGIN_NAMESPACE
\sa QPixmap::isNull()
*/
QBitmap::QBitmap()
- : QPixmap(QSize(0, 0), QPixmapData::BitmapType)
+ : QPixmap(QSize(0, 0), QPlatformPixmap::BitmapType)
{
}
@@ -116,7 +116,7 @@ QBitmap::QBitmap()
*/
QBitmap::QBitmap(int w, int h)
- : QPixmap(QSize(w, h), QPixmapData::BitmapType)
+ : QPixmap(QSize(w, h), QPlatformPixmap::BitmapType)
{
}
@@ -128,7 +128,7 @@ QBitmap::QBitmap(int w, int h)
*/
QBitmap::QBitmap(const QSize &size)
- : QPixmap(size, QPixmapData::BitmapType)
+ : QPixmap(size, QPlatformPixmap::BitmapType)
{
}
@@ -173,7 +173,7 @@ QBitmap::QBitmap(const QPixmap &pixmap)
*/
QBitmap::QBitmap(const QString& fileName, const char *format)
- : QPixmap(QSize(0, 0), QPixmapData::BitmapType)
+ : QPixmap(QSize(0, 0), QPlatformPixmap::BitmapType)
{
load(fileName, format, Qt::MonoOnly);
}
@@ -205,20 +205,6 @@ QBitmap &QBitmap::operator=(const QPixmap &pixmap)
return *this;
}
-
-#ifdef QT3_SUPPORT
-QBitmap::QBitmap(int w, int h, const uchar *bits, bool isXbitmap)
-{
- *this = fromData(QSize(w, h), bits, isXbitmap ? QImage::Format_MonoLSB : QImage::Format_Mono);
-}
-
-
-QBitmap::QBitmap(const QSize &size, const uchar *bits, bool isXbitmap)
-{
- *this = fromData(size, bits, isXbitmap ? QImage::Format_MonoLSB : QImage::Format_Mono);
-}
-#endif
-
/*!
Destroys the bitmap.
*/
@@ -275,9 +261,7 @@ QBitmap QBitmap::fromImage(const QImage &image, Qt::ImageConversionFlags flags)
img.setColor(1, c0);
}
- QGraphicsSystem* gs = QApplicationPrivate::graphicsSystem();
- QScopedPointer<QPixmapData> data(gs ? gs->createPixmapData(QPixmapData::BitmapType)
- : QGraphicsSystem::createDefaultPixmapData(QPixmapData::BitmapType));
+ QScopedPointer<QPlatformPixmap> data(QGuiApplicationPrivate::platformIntegration()->createPlatformPixmap(QPlatformPixmap::BitmapType));
data->fromImage(img, flags | Qt::MonoOnly);
return QPixmap(data.take());
@@ -335,77 +319,4 @@ QBitmap QBitmap::transformed(const QMatrix &matrix) const
return transformed(QTransform(matrix));
}
-#ifdef QT3_SUPPORT
-/*!
- \fn QBitmap QBitmap::xForm(const QMatrix &matrix) const
-
- Returns a copy of this bitmap, transformed according to the given
- \a matrix.
-
- Use transformed() instead.
-*/
-
-/*!
- \fn QBitmap::QBitmap(const QSize &size, bool clear)
-
- Constructs a bitmap with the given \a size. If \a clear is true,
- the bits are initialized to Qt::color0.
-
- Use the corresponding QBitmap() constructor instead, and then call
- the clear() function if the \a clear parameter is true.
-*/
-
-/*!
- \fn QBitmap::QBitmap(int width, int height, bool clear)
-
- Constructs a bitmap with the given \a width and \a height. If \a
- clear is true, the bits are initialized to Qt::color0.
-
- Use the corresponding QBitmap() constructor instead, and then call
- the clear() function if the \a clear parameter is true.
-*/
-
-/*!
- \fn QBitmap::QBitmap(int width, int height, const uchar *bits, bool isXbitmap)
-
- Constructs a bitmap with the given \a width and \a height, and
- sets the contents to the \a bits supplied. The \a isXbitmap flag
- should be true if \a bits was generated by the X11 bitmap
- program.
-
- Use the static fromData() function instead. If \a isXbitmap is
- true, use the default bit order(QImage_FormatMonoLSB) otherwise
- use QImage::Format_Mono.
-
- \omit
- The X bitmap bit order is little endian. The QImage
- documentation discusses bit order of monochrome images. Opposed to
- QImage, the data has to be byte aligned.
-
- Example (creates an arrow bitmap):
- \snippet doc/src/snippets/code/src_gui_image_qbitmap.cpp 0
- \endomit
-*/
-
-
-/*!
- \fn QBitmap::QBitmap(const QSize &size, const uchar *bits, bool isXbitmap)
-
- \overload
-
- Constructs a bitmap with the given \a size, and sets the contents
- to the \a bits supplied. The \a isXbitmap flag should be true if
- \a bits was generated by the X11 bitmap program.
-
- \omit
- The X bitmap bit order is little endian. The QImage documentation
- discusses bit order of monochrome images.
- \endomit
-
- Use the static fromData() function instead. If \a isXbitmap is
- true, use the default bit order(QImage_FormatMonoLSB) otherwise
- use QImage::Format_Mono.
-*/
-#endif
-
QT_END_NAMESPACE
diff --git a/src/gui/image/qbitmap.h b/src/gui/image/qbitmap.h
index b37eed212d..a3104f5083 100644
--- a/src/gui/image/qbitmap.h
+++ b/src/gui/image/qbitmap.h
@@ -74,34 +74,11 @@ public:
QBitmap transformed(const QMatrix &) const;
QBitmap transformed(const QTransform &matrix) const;
-#ifdef QT3_SUPPORT
- inline QT3_SUPPORT_CONSTRUCTOR QBitmap(int w, int h, bool clear);
- inline QT3_SUPPORT_CONSTRUCTOR QBitmap(const QSize &, bool clear);
- QT3_SUPPORT_CONSTRUCTOR QBitmap(int w, int h, const uchar *bits, bool isXbitmap=false);
- QT3_SUPPORT_CONSTRUCTOR QBitmap(const QSize &, const uchar *bits, bool isXbitmap=false);
- inline QT3_SUPPORT QBitmap xForm(const QMatrix &matrix) const { return transformed(QTransform(matrix)); }
- QT3_SUPPORT_CONSTRUCTOR QBitmap(const QImage &image) { *this = fromImage(image); }
- QT3_SUPPORT QBitmap &operator=(const QImage &image) { *this = fromImage(image); return *this; }
-#endif
- typedef QExplicitlySharedDataPointer<QPixmapData> DataPtr;
+ typedef QExplicitlySharedDataPointer<QPlatformPixmap> DataPtr;
};
Q_DECLARE_SHARED(QBitmap)
-#ifdef QT3_SUPPORT
-inline QBitmap::QBitmap(int w, int h, bool clear)
- : QPixmap(QSize(w, h), 1)
-{
- if (clear) this->clear();
-}
-
-inline QBitmap::QBitmap(const QSize &size, bool clear)
- : QPixmap(size, 1)
-{
- if (clear) this->clear();
-}
-#endif
-
QT_END_NAMESPACE
QT_END_HEADER
diff --git a/src/gui/image/qbmphandler.cpp b/src/gui/image/qbmphandler.cpp
index 8840a83ff0..d854b1765b 100644
--- a/src/gui/image/qbmphandler.cpp
+++ b/src/gui/image/qbmphandler.cpp
@@ -692,11 +692,16 @@ bool qt_read_dib(QDataStream &s, QImage &image)
return read_dib_body(s, bi, -1, -BMP_FILEHDR_SIZE, image);
}
-QBmpHandler::QBmpHandler()
- : state(Ready)
+QBmpHandler::QBmpHandler(InternalFormat fmt) :
+ m_format(fmt), state(Ready)
{
}
+QByteArray QBmpHandler::formatName() const
+{
+ return m_format == BmpFormat ? "bmp" : "dib";
+}
+
bool QBmpHandler::readHeader()
{
state = Error;
@@ -709,7 +714,7 @@ bool QBmpHandler::readHeader()
s.setByteOrder(QDataStream::LittleEndian);
// read BMP file header
- if (!read_dib_fileheader(s, fileHeader))
+ if (m_format == BmpFormat && !read_dib_fileheader(s, fileHeader))
return false;
// read BMP info header
@@ -722,11 +727,11 @@ bool QBmpHandler::readHeader()
bool QBmpHandler::canRead() const
{
- if (state == Ready && !canRead(device()))
+ if (m_format == BmpFormat && state == Ready && !canRead(device()))
return false;
if (state != Error) {
- setFormat("bmp");
+ setFormat(formatName());
return true;
}
@@ -778,6 +783,12 @@ bool QBmpHandler::read(QImage *image)
bool QBmpHandler::write(const QImage &img)
{
+ if (m_format == DibFormat) {
+ QDataStream dibStream(device());
+ dibStream.setByteOrder(QDataStream::LittleEndian); // Intel byte order
+ return qt_write_dib(dibStream, img);
+ }
+
QImage image;
switch (img.format()) {
case QImage::Format_ARGB8565_Premultiplied:
@@ -875,7 +886,7 @@ void QBmpHandler::setOption(ImageOption option, const QVariant &value)
QByteArray QBmpHandler::name() const
{
- return "bmp";
+ return formatName();
}
QT_END_NAMESPACE
diff --git a/src/gui/image/qbmphandler_p.h b/src/gui/image/qbmphandler_p.h
index 070d904b77..373f8fbaaf 100644
--- a/src/gui/image/qbmphandler_p.h
+++ b/src/gui/image/qbmphandler_p.h
@@ -81,10 +81,20 @@ struct BMP_INFOHDR { // BMP information header
qint32 biClrImportant; // number of important colors
};
+// BMP-Handler, which is also able to read and write the DIB
+// (Device-Independent-Bitmap) format used internally in the Windows operating
+// system for OLE/clipboard operations. DIB is a subset of BMP (without file
+// header). The Windows-Lighthouse plugin accesses the DIB-functionality.
+
class QBmpHandler : public QImageIOHandler
{
public:
- QBmpHandler();
+ enum InternalFormat {
+ DibFormat,
+ BmpFormat
+ };
+
+ explicit QBmpHandler(InternalFormat fmt = BmpFormat);
bool canRead() const;
bool read(QImage *image);
bool write(const QImage &image);
@@ -99,11 +109,16 @@ public:
private:
bool readHeader();
+ inline QByteArray formatName() const;
+
enum State {
Ready,
ReadHeader,
Error
};
+
+ const InternalFormat m_format;
+
State state;
BMP_FILEHDR fileHeader;
BMP_INFOHDR infoHeader;
diff --git a/src/gui/image/qicon.cpp b/src/gui/image/qicon.cpp
deleted file mode 100644
index 724205f2fc..0000000000
--- a/src/gui/image/qicon.cpp
+++ /dev/null
@@ -1,1256 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qicon.h"
-#include "qicon_p.h"
-#include "qiconengine.h"
-#include "qiconengineplugin.h"
-#include "private/qfactoryloader_p.h"
-#include "private/qiconloader_p.h"
-#include "qapplication.h"
-#include "qstyleoption.h"
-#include "qpainter.h"
-#include "qfileinfo.h"
-#include "qstyle.h"
-#include "qpixmapcache.h"
-#include "qvariant.h"
-#include "qcache.h"
-#include "qdebug.h"
-#include "private/qguiplatformplugin_p.h"
-
-#ifdef Q_WS_MAC
-#include <private/qt_mac_p.h>
-#include <private/qt_cocoa_helpers_mac_p.h>
-#endif
-
-#ifdef Q_WS_X11
-#include "private/qt_x11_p.h"
-#include "private/qkde_p.h"
-#endif
-
-#include "private/qstylehelper_p.h"
-
-#ifndef QT_NO_ICON
-QT_BEGIN_NAMESPACE
-
-/*!
- \enum QIcon::Mode
-
- This enum type describes the mode for which a pixmap is intended
- to be used. The currently defined modes are:
-
- \value Normal
- Display the pixmap when the user is
- not interacting with the icon, but the
- functionality represented by the icon is available.
- \value Disabled
- Display the pixmap when the
- functionality represented by the icon is not available.
- \value Active
- Display the pixmap when the
- functionality represented by the icon is available and
- the user is interacting with the icon, for example, moving the
- mouse over it or clicking it.
- \value Selected
- Display the pixmap when the item represented by the icon is
- selected.
-*/
-
-/*!
- \enum QIcon::State
-
- This enum describes the state for which a pixmap is intended to be
- used. The \e state can be:
-
- \value Off Display the pixmap when the widget is in an "off" state
- \value On Display the pixmap when the widget is in an "on" state
-*/
-
-static QBasicAtomicInt serialNumCounter = Q_BASIC_ATOMIC_INITIALIZER(1);
-
-static void qt_cleanup_icon_cache();
-namespace {
- class IconCache: public QCache<QString, QIcon>
- {
- public:
- IconCache()
- {
- // ### FIXME: needs to be re-added if qApp is re-created
- qAddPostRoutine(qt_cleanup_icon_cache);
- }
- };
-}
-Q_GLOBAL_STATIC(IconCache, qtIconCache)
-
-static void qt_cleanup_icon_cache()
-{
- qtIconCache()->clear();
-}
-
-QIconPrivate::QIconPrivate()
- : engine(0),
- serialNum(serialNumCounter.fetchAndAddRelaxed(1)),
- detach_no(0),
- engine_version(2),
- v1RefCount(0)
-{
-}
-
-QPixmapIconEngine::QPixmapIconEngine()
-{
-}
-
-QPixmapIconEngine::QPixmapIconEngine(const QPixmapIconEngine &other)
- : QIconEngineV2(other), pixmaps(other.pixmaps)
-{
-}
-
-QPixmapIconEngine::~QPixmapIconEngine()
-{
-}
-
-void QPixmapIconEngine::paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state)
-{
- QSize pixmapSize = rect.size();
-#if defined(Q_WS_MAC)
- pixmapSize *= qt_mac_get_scalefactor();
-#endif
- painter->drawPixmap(rect, pixmap(pixmapSize, mode, state));
-}
-
-static inline int area(const QSize &s) { return s.width() * s.height(); }
-
-// returns the smallest of the two that is still larger than or equal to size.
-static QPixmapIconEngineEntry *bestSizeMatch( const QSize &size, QPixmapIconEngineEntry *pa, QPixmapIconEngineEntry *pb)
-{
- int s = area(size);
- if (pa->size == QSize() && pa->pixmap.isNull()) {
- pa->pixmap = QPixmap(pa->fileName);
- pa->size = pa->pixmap.size();
- }
- int a = area(pa->size);
- if (pb->size == QSize() && pb->pixmap.isNull()) {
- pb->pixmap = QPixmap(pb->fileName);
- pb->size = pb->pixmap.size();
- }
- int b = area(pb->size);
- int res = a;
- if (qMin(a,b) >= s)
- res = qMin(a,b);
- else
- res = qMax(a,b);
- if (res == a)
- return pa;
- return pb;
-}
-
-QPixmapIconEngineEntry *QPixmapIconEngine::tryMatch(const QSize &size, QIcon::Mode mode, QIcon::State state)
-{
- QPixmapIconEngineEntry *pe = 0;
- for (int i = 0; i < pixmaps.count(); ++i)
- if (pixmaps.at(i).mode == mode && pixmaps.at(i).state == state) {
- if (pe)
- pe = bestSizeMatch(size, &pixmaps[i], pe);
- else
- pe = &pixmaps[i];
- }
- return pe;
-}
-
-
-QPixmapIconEngineEntry *QPixmapIconEngine::bestMatch(const QSize &size, QIcon::Mode mode, QIcon::State state, bool sizeOnly)
-{
- QPixmapIconEngineEntry *pe = tryMatch(size, mode, state);
- while (!pe){
- QIcon::State oppositeState = (state == QIcon::On) ? QIcon::Off : QIcon::On;
- if (mode == QIcon::Disabled || mode == QIcon::Selected) {
- QIcon::Mode oppositeMode = (mode == QIcon::Disabled) ? QIcon::Selected : QIcon::Disabled;
- if ((pe = tryMatch(size, QIcon::Normal, state)))
- break;
- if ((pe = tryMatch(size, QIcon::Active, state)))
- break;
- if ((pe = tryMatch(size, mode, oppositeState)))
- break;
- if ((pe = tryMatch(size, QIcon::Normal, oppositeState)))
- break;
- if ((pe = tryMatch(size, QIcon::Active, oppositeState)))
- break;
- if ((pe = tryMatch(size, oppositeMode, state)))
- break;
- if ((pe = tryMatch(size, oppositeMode, oppositeState)))
- break;
- } else {
- QIcon::Mode oppositeMode = (mode == QIcon::Normal) ? QIcon::Active : QIcon::Normal;
- if ((pe = tryMatch(size, oppositeMode, state)))
- break;
- if ((pe = tryMatch(size, mode, oppositeState)))
- break;
- if ((pe = tryMatch(size, oppositeMode, oppositeState)))
- break;
- if ((pe = tryMatch(size, QIcon::Disabled, state)))
- break;
- if ((pe = tryMatch(size, QIcon::Selected, state)))
- break;
- if ((pe = tryMatch(size, QIcon::Disabled, oppositeState)))
- break;
- if ((pe = tryMatch(size, QIcon::Selected, oppositeState)))
- break;
- }
-
- if (!pe)
- return pe;
- }
-
- if (sizeOnly ? (pe->size.isNull() || !pe->size.isValid()) : pe->pixmap.isNull()) {
- pe->pixmap = QPixmap(pe->fileName);
- if (!pe->pixmap.isNull())
- pe->size = pe->pixmap.size();
- }
-
- return pe;
-}
-
-QPixmap QPixmapIconEngine::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state)
-{
- QPixmap pm;
- QPixmapIconEngineEntry *pe = bestMatch(size, mode, state, false);
- if (pe)
- pm = pe->pixmap;
-
- if (pm.isNull()) {
- int idx = pixmaps.count();
- while (--idx >= 0) {
- if (pe == &pixmaps[idx]) {
- pixmaps.remove(idx);
- break;
- }
- }
- if (pixmaps.isEmpty())
- return pm;
- else
- return pixmap(size, mode, state);
- }
-
- QSize actualSize = pm.size();
- if (!actualSize.isNull() && (actualSize.width() > size.width() || actualSize.height() > size.height()))
- actualSize.scale(size, Qt::KeepAspectRatio);
-
- QString key = QLatin1Literal("qt_")
- % HexString<quint64>(pm.cacheKey())
- % HexString<uint>(pe->mode)
- % HexString<quint64>(QApplication::palette().cacheKey())
- % HexString<uint>(actualSize.width())
- % HexString<uint>(actualSize.height());
-
- if (mode == QIcon::Active) {
- if (QPixmapCache::find(key % HexString<uint>(mode), pm))
- return pm; // horray
- if (QPixmapCache::find(key % HexString<uint>(QIcon::Normal), pm)) {
- QStyleOption opt(0);
- opt.palette = QApplication::palette();
- QPixmap active = QApplication::style()->generatedIconPixmap(QIcon::Active, pm, &opt);
- if (pm.cacheKey() == active.cacheKey())
- return pm;
- }
- }
-
- if (!QPixmapCache::find(key % HexString<uint>(mode), pm)) {
- if (pm.size() != actualSize)
- pm = pm.scaled(actualSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
- if (pe->mode != mode && mode != QIcon::Normal) {
- QStyleOption opt(0);
- opt.palette = QApplication::palette();
- QPixmap generated = QApplication::style()->generatedIconPixmap(mode, pm, &opt);
- if (!generated.isNull())
- pm = generated;
- }
- QPixmapCache::insert(key % HexString<uint>(mode), pm);
- }
- return pm;
-}
-
-QSize QPixmapIconEngine::actualSize(const QSize &size, QIcon::Mode mode, QIcon::State state)
-{
- QSize actualSize;
- if (QPixmapIconEngineEntry *pe = bestMatch(size, mode, state, true))
- actualSize = pe->size;
-
- if (actualSize.isNull())
- return actualSize;
-
- if (!actualSize.isNull() && (actualSize.width() > size.width() || actualSize.height() > size.height()))
- actualSize.scale(size, Qt::KeepAspectRatio);
- return actualSize;
-}
-
-void QPixmapIconEngine::addPixmap(const QPixmap &pixmap, QIcon::Mode mode, QIcon::State state)
-{
- if (!pixmap.isNull()) {
- QPixmapIconEngineEntry *pe = tryMatch(pixmap.size(), mode, state);
- if(pe && pe->size == pixmap.size()) {
- pe->pixmap = pixmap;
- pe->fileName.clear();
- } else {
- pixmaps += QPixmapIconEngineEntry(pixmap, mode, state);
- }
- }
-}
-
-void QPixmapIconEngine::addFile(const QString &fileName, const QSize &_size, QIcon::Mode mode, QIcon::State state)
-{
- if (!fileName.isEmpty()) {
- QSize size = _size;
- QPixmap pixmap;
-
- QString abs = fileName;
- if (fileName.at(0) != QLatin1Char(':'))
- abs = QFileInfo(fileName).absoluteFilePath();
-
- for (int i = 0; i < pixmaps.count(); ++i) {
- if (pixmaps.at(i).mode == mode && pixmaps.at(i).state == state) {
- QPixmapIconEngineEntry *pe = &pixmaps[i];
- if(size == QSize()) {
- pixmap = QPixmap(abs);
- size = pixmap.size();
- }
- if (pe->size == QSize() && pe->pixmap.isNull()) {
- pe->pixmap = QPixmap(pe->fileName);
- pe->size = pe->pixmap.size();
- }
- if(pe->size == size) {
- pe->pixmap = pixmap;
- pe->fileName = abs;
- return;
- }
- }
- }
- QPixmapIconEngineEntry e(abs, size, mode, state);
- e.pixmap = pixmap;
- pixmaps += e;
- }
-}
-
-QString QPixmapIconEngine::key() const
-{
- return QLatin1String("QPixmapIconEngine");
-}
-
-QIconEngineV2 *QPixmapIconEngine::clone() const
-{
- return new QPixmapIconEngine(*this);
-}
-
-bool QPixmapIconEngine::read(QDataStream &in)
-{
- int num_entries;
- QPixmap pm;
- QString fileName;
- QSize sz;
- uint mode;
- uint state;
-
- in >> num_entries;
- for (int i=0; i < num_entries; ++i) {
- if (in.atEnd()) {
- pixmaps.clear();
- return false;
- }
- in >> pm;
- in >> fileName;
- in >> sz;
- in >> mode;
- in >> state;
- if (pm.isNull()) {
- addFile(fileName, sz, QIcon::Mode(mode), QIcon::State(state));
- } else {
- QPixmapIconEngineEntry pe(fileName, sz, QIcon::Mode(mode), QIcon::State(state));
- pe.pixmap = pm;
- pixmaps += pe;
- }
- }
- return true;
-}
-
-bool QPixmapIconEngine::write(QDataStream &out) const
-{
- int num_entries = pixmaps.size();
- out << num_entries;
- for (int i=0; i < num_entries; ++i) {
- if (pixmaps.at(i).pixmap.isNull())
- out << QPixmap(pixmaps.at(i).fileName);
- else
- out << pixmaps.at(i).pixmap;
- out << pixmaps.at(i).fileName;
- out << pixmaps.at(i).size;
- out << (uint) pixmaps.at(i).mode;
- out << (uint) pixmaps.at(i).state;
- }
- return true;
-}
-
-void QPixmapIconEngine::virtual_hook(int id, void *data)
-{
- switch (id) {
- case QIconEngineV2::AvailableSizesHook: {
- QIconEngineV2::AvailableSizesArgument &arg =
- *reinterpret_cast<QIconEngineV2::AvailableSizesArgument*>(data);
- arg.sizes.clear();
- for (int i = 0; i < pixmaps.size(); ++i) {
- QPixmapIconEngineEntry &pe = pixmaps[i];
- if (pe.size == QSize() && pe.pixmap.isNull()) {
- pe.pixmap = QPixmap(pe.fileName);
- pe.size = pe.pixmap.size();
- }
- if (pe.mode == arg.mode && pe.state == arg.state && !pe.size.isEmpty())
- arg.sizes.push_back(pe.size);
- }
- break;
- }
- default:
- QIconEngineV2::virtual_hook(id, data);
- }
-}
-
-#ifndef QT_NO_LIBRARY
-Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
- (QIconEngineFactoryInterface_iid, QLatin1String("/iconengines"), Qt::CaseInsensitive))
-Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loaderV2,
- (QIconEngineFactoryInterfaceV2_iid, QLatin1String("/iconengines"), Qt::CaseInsensitive))
-#endif
-
-
-
-/*!
- \class QIcon
-
- \brief The QIcon class provides scalable icons in different modes
- and states.
-
- \ingroup painting
- \ingroup shared
-
-
- A QIcon can generate smaller, larger, active, and disabled pixmaps
- from the set of pixmaps it is given. Such pixmaps are used by Qt
- widgets to show an icon representing a particular action.
-
- The simplest use of QIcon is to create one from a QPixmap file or
- resource, and then use it, allowing Qt to work out all the required
- icon styles and sizes. For example:
-
- \snippet doc/src/snippets/code/src_gui_image_qicon.cpp 0
-
- To undo a QIcon, simply set a null icon in its place:
-
- \snippet doc/src/snippets/code/src_gui_image_qicon.cpp 1
-
- Use the QImageReader::supportedImageFormats() and
- QImageWriter::supportedImageFormats() functions to retrieve a
- complete list of the supported file formats.
-
- When you retrieve a pixmap using pixmap(QSize, Mode, State), and no
- pixmap for this given size, mode and state has been added with
- addFile() or addPixmap(), then QIcon will generate one on the
- fly. This pixmap generation happens in a QIconEngineV2. The default
- engine scales pixmaps down if required, but never up, and it uses
- the current style to calculate a disabled appearance. By using
- custom icon engines, you can customize every aspect of generated
- icons. With QIconEnginePluginV2 it is possible to register different
- icon engines for different file suffixes, making it possible for
- third parties to provide additional icon engines to those included
- with Qt.
-
- \note Since Qt 4.2, an icon engine that supports SVG is included.
-
- \section1 Making Classes that Use QIcon
-
- If you write your own widgets that have an option to set a small
- pixmap, consider allowing a QIcon to be set for that pixmap. The
- Qt class QToolButton is an example of such a widget.
-
- Provide a method to set a QIcon, and when you draw the icon, choose
- whichever pixmap is appropriate for the current state of your widget.
- For example:
- \snippet doc/src/snippets/code/src_gui_image_qicon.cpp 2
-
- You might also make use of the \c Active mode, perhaps making your
- widget \c Active when the mouse is over the widget (see \l
- QWidget::enterEvent()), while the mouse is pressed pending the
- release that will activate the function, or when it is the currently
- selected item. If the widget can be toggled, the "On" mode might be
- used to draw a different icon.
-
- \img icon.png QIcon
-
- \sa {fowler}{GUI Design Handbook: Iconic Label}, {Icons Example}
-*/
-
-
-/*!
- Constructs a null icon.
-*/
-QIcon::QIcon()
- : d(0)
-{
-}
-
-/*!
- Constructs an icon from a \a pixmap.
- */
-QIcon::QIcon(const QPixmap &pixmap)
- :d(0)
-{
- addPixmap(pixmap);
-}
-
-/*!
- Constructs a copy of \a other. This is very fast.
-*/
-QIcon::QIcon(const QIcon &other)
- :d(other.d)
-{}
-
-/*!
- Constructs an icon from the file with the given \a fileName. The
- file will be loaded on demand.
-
- If \a fileName contains a relative path (e.g. the filename only)
- the relevant file must be found relative to the runtime working
- directory.
-
- The file name can be either refer to an actual file on disk or to
- one of the application's embedded resources. See the
- \l{resources.html}{Resource System} overview for details on how to
- embed images and other resource files in the application's
- executable.
-
- Use the QImageReader::supportedImageFormats() and
- QImageWriter::supportedImageFormats() functions to retrieve a
- complete list of the supported file formats.
-*/
-QIcon::QIcon(const QString &fileName)
- : d(0)
-{
- addFile(fileName);
-}
-
-
-/*!
- Creates an icon with a specific icon \a engine. The icon takes
- ownership of the engine.
-*/
-QIcon::QIcon(QIconEngine *engine)
- :d(new QIconPrivate)
-{
- d->engine_version = 1;
- d->engine = engine;
- d->v1RefCount = new QAtomicInt(1);
-}
-
-/*!
- Creates an icon with a specific icon \a engine. The icon takes
- ownership of the engine.
-*/
-QIcon::QIcon(QIconEngineV2 *engine)
- :d(new QIconPrivate)
-{
- d->engine_version = 2;
- d->engine = engine;
-}
-
-/*!
- Destroys the icon.
-*/
-QIcon::~QIcon()
-{}
-
-/*!
- Assigns the \a other icon to this icon and returns a reference to
- this icon.
-*/
-QIcon &QIcon::operator=(const QIcon &other)
-{
- d = other.d;
- return *this;
-}
-
-/*!
- \fn void QIcon::swap(QIcon &other)
- \since 4.8
-
- Swaps icon \a other with this icon. This operation is very
- fast and never fails.
-*/
-
-/*!
- Returns the icon as a QVariant.
-*/
-QIcon::operator QVariant() const
-{
- return QVariant(QVariant::Icon, this);
-}
-
-/*! \obsolete
-
- Returns a number that identifies the contents of this
- QIcon object. Distinct QIcon objects can have
- the same serial number if they refer to the same contents
- (but they don't have to). Also, the serial number of
- a QIcon object may change during its lifetime.
-
- Use cacheKey() instead.
-
- A null icon always has a serial number of 0.
-
- Serial numbers are mostly useful in conjunction with caching.
-
- \sa QPixmap::serialNumber()
-*/
-
-int QIcon::serialNumber() const
-{
- return d ? d->serialNum : 0;
-}
-
-/*!
- Returns a number that identifies the contents of this QIcon
- object. Distinct QIcon objects can have the same key if
- they refer to the same contents.
- \since 4.3
-
- The cacheKey() will change when the icon is altered via
- addPixmap() or addFile().
-
- Cache keys are mostly useful in conjunction with caching.
-
- \sa QPixmap::cacheKey()
-*/
-qint64 QIcon::cacheKey() const
-{
- if (!d)
- return 0;
- return (((qint64) d->serialNum) << 32) | ((qint64) (d->detach_no));
-}
-
-/*!
- Returns a pixmap with the requested \a size, \a mode, and \a
- state, generating one if necessary. The pixmap might be smaller than
- requested, but never larger.
-
- \sa actualSize(), paint()
-*/
-QPixmap QIcon::pixmap(const QSize &size, Mode mode, State state) const
-{
- if (!d)
- return QPixmap();
- return d->engine->pixmap(size, mode, state);
-}
-
-/*!
- \fn QPixmap QIcon::pixmap(int w, int h, Mode mode = Normal, State state = Off) const
-
- \overload
-
- Returns a pixmap of size QSize(\a w, \a h). The pixmap might be smaller than
- requested, but never larger.
-*/
-
-/*!
- \fn QPixmap QIcon::pixmap(int extent, Mode mode = Normal, State state = Off) const
-
- \overload
-
- Returns a pixmap of size QSize(\a extent, \a extent). The pixmap might be smaller
- than requested, but never larger.
-*/
-
-/*! Returns the actual size of the icon for the requested \a size, \a
- mode, and \a state. The result might be smaller than requested, but
- never larger.
-
- \sa pixmap(), paint()
-*/
-QSize QIcon::actualSize(const QSize &size, Mode mode, State state) const
-{
- if (!d)
- return QSize();
- return d->engine->actualSize(size, mode, state);
-}
-
-
-/*!
- Uses the \a painter to paint the icon with specified \a alignment,
- required \a mode, and \a state into the rectangle \a rect.
-
- \sa actualSize(), pixmap()
-*/
-void QIcon::paint(QPainter *painter, const QRect &rect, Qt::Alignment alignment, Mode mode, State state) const
-{
- if (!d || !painter)
- return;
- QRect alignedRect = QStyle::alignedRect(painter->layoutDirection(), alignment, d->engine->actualSize(rect.size(), mode, state), rect);
- d->engine->paint(painter, alignedRect, mode, state);
-}
-
-/*!
- \fn void QIcon::paint(QPainter *painter, int x, int y, int w, int h, Qt::Alignment alignment,
- Mode mode, State state) const
-
- \overload
-
- Paints the icon into the rectangle QRect(\a x, \a y, \a w, \a h).
-*/
-
-/*!
- Returns true if the icon is empty; otherwise returns false.
-
- An icon is empty if it has neither a pixmap nor a filename.
-
- Note: Even a non-null icon might not be able to create valid
- pixmaps, eg. if the file does not exist or cannot be read.
-*/
-bool QIcon::isNull() const
-{
- return !d;
-}
-
-/*!\internal
- */
-bool QIcon::isDetached() const
-{
- return !d || d->ref == 1;
-}
-
-/*! \internal
- */
-void QIcon::detach()
-{
- if (d) {
- if (d->ref != 1) {
- QIconPrivate *x = new QIconPrivate;
- if (d->engine_version > 1) {
- QIconEngineV2 *engine = static_cast<QIconEngineV2 *>(d->engine);
- x->engine = engine->clone();
- } else {
- x->engine = d->engine;
- x->v1RefCount = d->v1RefCount;
- x->v1RefCount->ref();
- }
- x->engine_version = d->engine_version;
- d = x;
- }
- ++d->detach_no;
- }
-}
-
-/*!
- Adds \a pixmap to the icon, as a specialization for \a mode and
- \a state.
-
- Custom icon engines are free to ignore additionally added
- pixmaps.
-
- \sa addFile()
-*/
-void QIcon::addPixmap(const QPixmap &pixmap, Mode mode, State state)
-{
- if (pixmap.isNull())
- return;
- if (!d) {
- d = new QIconPrivate;
- d->engine = new QPixmapIconEngine;
- } else {
- detach();
- }
- d->engine->addPixmap(pixmap, mode, state);
-}
-
-
-/*! Adds an image from the file with the given \a fileName to the
- icon, as a specialization for \a size, \a mode and \a state. The
- file will be loaded on demand. Note: custom icon engines are free
- to ignore additionally added pixmaps.
-
- If \a fileName contains a relative path (e.g. the filename only)
- the relevant file must be found relative to the runtime working
- directory.
-
- The file name can be either refer to an actual file on disk or to
- one of the application's embedded resources. See the
- \l{resources.html}{Resource System} overview for details on how to
- embed images and other resource files in the application's
- executable.
-
- Use the QImageReader::supportedImageFormats() and
- QImageWriter::supportedImageFormats() functions to retrieve a
- complete list of the supported file formats.
-
- Note: When you add a non-empty filename to a QIcon, the icon becomes
- non-null, even if the file doesn't exist or points to a corrupt file.
-
- \sa addPixmap()
- */
-void QIcon::addFile(const QString &fileName, const QSize &size, Mode mode, State state)
-{
- if (fileName.isEmpty())
- return;
- if (!d) {
-#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
- QFileInfo info(fileName);
- QString suffix = info.suffix();
- if (!suffix.isEmpty()) {
- // first try version 2 engines..
- if (QIconEngineFactoryInterfaceV2 *factory = qobject_cast<QIconEngineFactoryInterfaceV2*>(loaderV2()->instance(suffix))) {
- if (QIconEngine *engine = factory->create(fileName)) {
- d = new QIconPrivate;
- d->engine = engine;
- }
- }
- // ..then fall back and try to load version 1 engines
- if (!d) {
- if (QIconEngineFactoryInterface *factory = qobject_cast<QIconEngineFactoryInterface*>(loader()->instance(suffix))) {
- if (QIconEngine *engine = factory->create(fileName)) {
- d = new QIconPrivate;
- d->engine = engine;
- d->engine_version = 1;
- d->v1RefCount = new QAtomicInt(1);
- }
- }
- }
- }
-#endif
- // ...then fall back to the default engine
- if (!d) {
- d = new QIconPrivate;
- d->engine = new QPixmapIconEngine;
- }
- } else {
- detach();
- }
- d->engine->addFile(fileName, size, mode, state);
-}
-
-/*!
- \since 4.5
-
- Returns a list of available icon sizes for the specified \a mode and
- \a state.
-*/
-QList<QSize> QIcon::availableSizes(Mode mode, State state) const
-{
- if (!d || !d->engine || d->engine_version < 2)
- return QList<QSize>();
- QIconEngineV2 *engine = static_cast<QIconEngineV2*>(d->engine);
- return engine->availableSizes(mode, state);
-}
-
-/*!
- \since 4.7
-
- Returns the name used to create the icon, if available.
-
- Depending on the way the icon was created, it may have an associated
- name. This is the case for icons created with fromTheme() or icons
- using a QIconEngine which supports the QIconEngineV2::IconNameHook.
-
- \sa fromTheme(), QIconEngine
-*/
-QString QIcon::name() const
-{
- if (!d || !d->engine || d->engine_version < 2)
- return QString();
- QIconEngineV2 *engine = static_cast<QIconEngineV2*>(d->engine);
- return engine->iconName();
-}
-
-/*!
- \since 4.6
-
- Sets the search paths for icon themes to \a paths.
- \sa themeSearchPaths(), fromTheme(), setThemeName()
-*/
-void QIcon::setThemeSearchPaths(const QStringList &paths)
-{
- QIconLoader::instance()->setThemeSearchPath(paths);
-}
-
-/*!
- \since 4.6
-
- Returns the search paths for icon themes.
-
- The default value will depend on the platform:
-
- On X11, the search path will use the XDG_DATA_DIRS environment
- variable if available.
-
- By default all platforms will have the resource directory
- \c{:\icons} as a fallback. You can use "rcc -project" to generate a
- resource file from your icon theme.
-
- \sa setThemeSearchPaths(), fromTheme(), setThemeName()
-*/
-QStringList QIcon::themeSearchPaths()
-{
- return QIconLoader::instance()->themeSearchPaths();
-}
-
-/*!
- \since 4.6
-
- Sets the current icon theme to \a name.
-
- The \a name should correspond to a directory name in the
- themeSearchPath() containing an index.theme
- file describing it's contents.
-
- \sa themeSearchPaths(), themeName()
-*/
-void QIcon::setThemeName(const QString &name)
-{
- QIconLoader::instance()->setThemeName(name);
-}
-
-/*!
- \since 4.6
-
- Returns the name of the current icon theme.
-
- On X11, the current icon theme depends on your desktop
- settings. On other platforms it is not set by default.
-
- \sa setThemeName(), themeSearchPaths(), fromTheme(),
- hasThemeIcon()
-*/
-QString QIcon::themeName()
-{
- return QIconLoader::instance()->themeName();
-}
-
-/*!
- \since 4.6
-
- Returns the QIcon corresponding to \a name in the current
- icon theme. If no such icon is found in the current theme
- \a fallback is returned instead.
-
- The latest version of the freedesktop icon specification and naming
- specification can be obtained here:
-
- \list
- \o \l{http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html}
- \o \l{http://standards.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html}
- \endlist
-
- To fetch an icon from the current icon theme:
-
- \snippet doc/src/snippets/code/src_gui_image_qicon.cpp 3
-
- Or if you want to provide a guaranteed fallback for platforms that
- do not support theme icons, you can use the second argument:
-
- \snippet doc/src/snippets/code/src_gui_image_qicon.cpp 4
-
- \note By default, only X11 will support themed icons. In order to
- use themed icons on Mac and Windows, you will have to bundle a
- compliant theme in one of your themeSearchPaths() and set the
- appropriate themeName().
-
- \sa themeName(), setThemeName(), themeSearchPaths()
-*/
-QIcon QIcon::fromTheme(const QString &name, const QIcon &fallback)
-{
- QIcon icon;
-
- if (qtIconCache()->contains(name)) {
- icon = *qtIconCache()->object(name);
- } else {
- QIcon *cachedIcon = new QIcon(new QIconLoaderEngine(name));
- qtIconCache()->insert(name, cachedIcon);
- icon = *cachedIcon;
- }
-
- // Note the qapp check is to allow lazy loading of static icons
- // Supporting fallbacks will not work for this case.
- if (qApp && icon.availableSizes().isEmpty())
- return fallback;
-
- return icon;
-}
-
-/*!
- \since 4.6
-
- Returns true if there is an icon available for \a name in the
- current icon theme, otherwise returns false.
-
- \sa themeSearchPaths(), fromTheme(), setThemeName()
-*/
-bool QIcon::hasThemeIcon(const QString &name)
-{
- QIcon icon = fromTheme(name);
-
- return !icon.isNull();
-}
-
-
-/*****************************************************************************
- QIcon stream functions
- *****************************************************************************/
-#if !defined(QT_NO_DATASTREAM)
-/*!
- \fn QDataStream &operator<<(QDataStream &stream, const QIcon &icon)
- \relates QIcon
- \since 4.2
-
- Writes the given \a icon to the given \a stream as a PNG
- image. If the icon contains more than one image, all images will
- be written to the stream. Note that writing the stream to a file
- will not produce a valid image file.
-*/
-
-QDataStream &operator<<(QDataStream &s, const QIcon &icon)
-{
- if (s.version() >= QDataStream::Qt_4_3) {
- if (icon.isNull()) {
- s << QString();
- } else {
- if (icon.d->engine_version > 1) {
- QIconEngineV2 *engine = static_cast<QIconEngineV2 *>(icon.d->engine);
- s << engine->key();
- engine->write(s);
- } else {
- // not really supported
- qWarning("QIcon: Cannot stream QIconEngine. Use QIconEngineV2 instead.");
- }
- }
- } else if (s.version() == QDataStream::Qt_4_2) {
- if (icon.isNull()) {
- s << 0;
- } else {
- QPixmapIconEngine *engine = static_cast<QPixmapIconEngine *>(icon.d->engine);
- int num_entries = engine->pixmaps.size();
- s << num_entries;
- for (int i=0; i < num_entries; ++i) {
- s << engine->pixmaps.at(i).pixmap;
- s << engine->pixmaps.at(i).fileName;
- s << engine->pixmaps.at(i).size;
- s << (uint) engine->pixmaps.at(i).mode;
- s << (uint) engine->pixmaps.at(i).state;
- }
- }
- } else {
- s << QPixmap(icon.pixmap(22,22));
- }
- return s;
-}
-
-/*!
- \fn QDataStream &operator>>(QDataStream &stream, QIcon &icon)
- \relates QIcon
- \since 4.2
-
- Reads an image, or a set of images, from the given \a stream into
- the given \a icon.
-*/
-
-QDataStream &operator>>(QDataStream &s, QIcon &icon)
-{
- if (s.version() >= QDataStream::Qt_4_3) {
- icon = QIcon();
- QString key;
- s >> key;
- if (key == QLatin1String("QPixmapIconEngine")) {
- icon.d = new QIconPrivate;
- QIconEngineV2 *engine = new QPixmapIconEngine;
- icon.d->engine = engine;
- engine->read(s);
- } else if (key == QLatin1String("QIconLoaderEngine")) {
- icon.d = new QIconPrivate;
- QIconEngineV2 *engine = new QIconLoaderEngine();
- icon.d->engine = engine;
- engine->read(s);
-#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
- } else if (QIconEngineFactoryInterfaceV2 *factory = qobject_cast<QIconEngineFactoryInterfaceV2*>(loaderV2()->instance(key))) {
- if (QIconEngineV2 *engine= factory->create()) {
- icon.d = new QIconPrivate;
- icon.d->engine = engine;
- engine->read(s);
- }
-#endif
- }
- } else if (s.version() == QDataStream::Qt_4_2) {
- icon = QIcon();
- int num_entries;
- QPixmap pm;
- QString fileName;
- QSize sz;
- uint mode;
- uint state;
-
- s >> num_entries;
- for (int i=0; i < num_entries; ++i) {
- s >> pm;
- s >> fileName;
- s >> sz;
- s >> mode;
- s >> state;
- if (pm.isNull())
- icon.addFile(fileName, sz, QIcon::Mode(mode), QIcon::State(state));
- else
- icon.addPixmap(pm, QIcon::Mode(mode), QIcon::State(state));
- }
- } else {
- QPixmap pm;
- s >> pm;
- icon.addPixmap(pm);
- }
- return s;
-}
-
-#endif //QT_NO_DATASTREAM
-
-
-#ifdef QT3_SUPPORT
-
-static int widths[2] = { 22, 32 };
-static int heights[2] = { 22, 32 };
-
-static QSize pixmapSizeHelper(QIcon::Size which)
-{
- int i = 0;
- if (which == QIcon::Large)
- i = 1;
- return QSize(widths[i], heights[i]);
-}
-
-/*!
- \enum QIcon::Size
- \compat
-
- \value Small Use QStyle::pixelMetric(QStyle::PM_SmallIconSize) instead.
- \value Large Use QStyle::pixelMetric(QStyle::PM_LargeIconSize) instead.
- \value Automatic N/A.
-*/
-
-/*!
- Use pixmap(QSize(...), \a mode, \a state), where the first
- argument is an appropriate QSize instead of a \l Size value.
-
- \sa pixmapSize()
-*/
-QPixmap QIcon::pixmap(Size size, Mode mode, State state) const
-{ return pixmap(pixmapSizeHelper(size), mode, state); }
-
-/*!
- Use pixmap(QSize(...), mode, \a state), where the first argument
- is an appropriate QSize instead of a \l Size value, and the
- second argument is QIcon::Normal or QIcon::Disabled, depending on
- the value of \a enabled.
-
- \sa pixmapSize()
-*/
-QPixmap QIcon::pixmap(Size size, bool enabled, State state) const
-{ return pixmap(pixmapSizeHelper(size), enabled ? Normal : Disabled, state); }
-
-/*!
- Use one of the other pixmap() overloads.
-*/
-QPixmap QIcon::pixmap() const
-{ return pixmap(pixmapSizeHelper(Small), Normal, Off); }
-
-/*!
- The pixmap() function now takes a QSize instead of a QIcon::Size,
- so there is no need for this function in new code.
-*/
-void QIcon::setPixmapSize(Size which, const QSize &size)
-{
- int i = 0;
- if (which == Large)
- i = 1;
- widths[i] = size.width();
- heights[i] = size.height();
-}
-
-/*!
- Use QStyle::pixelMetric() with QStyle::PM_SmallIconSize or
- QStyle::PM_LargeIconSize as the first argument, depending on \a
- which.
-*/
-QSize QIcon::pixmapSize(Size which)
-{
- return pixmapSizeHelper(which);
-}
-
-/*!
- \fn void QIcon::reset(const QPixmap &pixmap, Size size)
-
- Use the constructor that takes a QPixmap and operator=().
-*/
-
-/*!
- \fn void QIcon::setPixmap(const QPixmap &pixmap, Size size, Mode mode, State state)
-
- Use addPixmap(\a pixmap, \a mode, \a state) instead. The \a size
- parameter is ignored.
-*/
-
-/*!
- \fn void QIcon::setPixmap(const QString &fileName, Size size, Mode mode, State state)
-
- Use addFile(\a fileName, \a mode, \a state) instead. The \a size
- parameter is ignored.
-*/
-
-#endif // QT3_SUPPORT
-
-/*!
- \fn DataPtr &QIcon::data_ptr()
- \internal
-*/
-
-/*!
- \typedef QIcon::DataPtr
- \internal
-*/
-
-QT_END_NAMESPACE
-#endif //QT_NO_ICON
diff --git a/src/gui/image/qicon.h b/src/gui/image/qicon.h
deleted file mode 100644
index eb14384f78..0000000000
--- a/src/gui/image/qicon.h
+++ /dev/null
@@ -1,162 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QICON_H
-#define QICON_H
-
-#include <QtCore/qglobal.h>
-#include <QtCore/qsize.h>
-#include <QtCore/qlist.h>
-#include <QtGui/qpixmap.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QIconPrivate;
-class QIconEngine;
-class QIconEngineV2;
-
-class Q_GUI_EXPORT QIcon
-{
-public:
- enum Mode { Normal, Disabled, Active, Selected };
- enum State { On, Off };
-
- QIcon();
- QIcon(const QPixmap &pixmap);
- QIcon(const QIcon &other);
- explicit QIcon(const QString &fileName); // file or resource name
- explicit QIcon(QIconEngine *engine);
- explicit QIcon(QIconEngineV2 *engine);
- ~QIcon();
- QIcon &operator=(const QIcon &other);
-#ifdef Q_COMPILER_RVALUE_REFS
- inline QIcon &operator=(QIcon &&other)
- { qSwap(d, other.d); return *this; }
-#endif
- inline void swap(QIcon &other) { qSwap(d, other.d); }
-
- operator QVariant() const;
-
- QPixmap pixmap(const QSize &size, Mode mode = Normal, State state = Off) const;
- inline QPixmap pixmap(int w, int h, Mode mode = Normal, State state = Off) const
- { return pixmap(QSize(w, h), mode, state); }
- inline QPixmap pixmap(int extent, Mode mode = Normal, State state = Off) const
- { return pixmap(QSize(extent, extent), mode, state); }
-
- QSize actualSize(const QSize &size, Mode mode = Normal, State state = Off) const;
-
- QString name() const;
-
- void paint(QPainter *painter, const QRect &rect, Qt::Alignment alignment = Qt::AlignCenter, Mode mode = Normal, State state = Off) const;
- inline void paint(QPainter *painter, int x, int y, int w, int h, Qt::Alignment alignment = Qt::AlignCenter, Mode mode = Normal, State state = Off) const
- { paint(painter, QRect(x, y, w, h), alignment, mode, state); }
-
- bool isNull() const;
- bool isDetached() const;
- void detach();
-
- int serialNumber() const;
- qint64 cacheKey() const;
-
- void addPixmap(const QPixmap &pixmap, Mode mode = Normal, State state = Off);
- void addFile(const QString &fileName, const QSize &size = QSize(), Mode mode = Normal, State state = Off);
-
- QList<QSize> availableSizes(Mode mode = Normal, State state = Off) const;
-
- static QIcon fromTheme(const QString &name, const QIcon &fallback = QIcon());
- static bool hasThemeIcon(const QString &name);
-
- static QStringList themeSearchPaths();
- static void setThemeSearchPaths(const QStringList &searchpath);
-
- static QString themeName();
- static void setThemeName(const QString &path);
-
-
-#ifdef QT3_SUPPORT
- enum Size { Small, Large, Automatic = Small };
- static QT3_SUPPORT void setPixmapSize(Size which, const QSize &size);
- static QT3_SUPPORT QSize pixmapSize(Size which);
- inline QT3_SUPPORT void reset(const QPixmap &pixmap, Size /*size*/) { *this = QIcon(pixmap); }
- inline QT3_SUPPORT void setPixmap(const QPixmap &pixmap, Size, Mode mode = Normal, State state = Off)
- { addPixmap(pixmap, mode, state); }
- inline QT3_SUPPORT void setPixmap(const QString &fileName, Size, Mode mode = Normal, State state = Off)
- { addPixmap(QPixmap(fileName), mode, state); }
- QT3_SUPPORT QPixmap pixmap(Size size, Mode mode, State state = Off) const;
- QT3_SUPPORT QPixmap pixmap(Size size, bool enabled, State state = Off) const;
- QT3_SUPPORT QPixmap pixmap() const;
-#endif
-
- Q_DUMMY_COMPARISON_OPERATOR(QIcon)
-
-private:
- QExplicitlySharedDataPointer<QIconPrivate> d;
-#if !defined(QT_NO_DATASTREAM)
- friend Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QIcon &);
- friend Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QIcon &);
-#endif
-
-public:
- typedef QExplicitlySharedDataPointer<QIconPrivate> DataPtr;
- inline DataPtr &data_ptr() { return d; }
-};
-
-Q_DECLARE_SHARED(QIcon)
-Q_DECLARE_TYPEINFO(QIcon, Q_MOVABLE_TYPE);
-
-#if !defined(QT_NO_DATASTREAM)
-Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QIcon &);
-Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QIcon &);
-#endif
-
-#ifdef QT3_SUPPORT
-typedef QIcon QIconSet;
-#endif
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QICON_H
diff --git a/src/gui/image/qicon_p.h b/src/gui/image/qicon_p.h
deleted file mode 100644
index c5b4bb0ba7..0000000000
--- a/src/gui/image/qicon_p.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QICON_P_H
-#define QICON_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/qglobal.h>
-#include <QtCore/qsize.h>
-#include <QtCore/qlist.h>
-#include <QtGui/qpixmap.h>
-#include <QtGui/qicon.h>
-#include <QtGui/qiconengine.h>
-
-#ifndef QT_NO_ICON
-QT_BEGIN_NAMESPACE
-
-class QIconPrivate : public QSharedData
-{
-public:
- QIconPrivate();
-
- ~QIconPrivate() {
- if (engine_version == 1) {
- if (!v1RefCount->deref()) {
- delete engine;
- delete v1RefCount;
- }
- } else if (engine_version == 2) {
- delete engine;
- }
- }
-
- QIconEngine *engine;
-
- int serialNum;
- int detach_no;
- int engine_version;
-
- QAtomicInt *v1RefCount;
-};
-
-
-struct QPixmapIconEngineEntry
-{
- QPixmapIconEngineEntry():mode(QIcon::Normal), state(QIcon::Off){}
- QPixmapIconEngineEntry(const QPixmap &pm, QIcon::Mode m = QIcon::Normal, QIcon::State s = QIcon::Off)
- :pixmap(pm), size(pm.size()), mode(m), state(s){}
- QPixmapIconEngineEntry(const QString &file, const QSize &sz = QSize(), QIcon::Mode m = QIcon::Normal, QIcon::State s = QIcon::Off)
- :fileName(file), size(sz), mode(m), state(s){}
- QPixmap pixmap;
- QString fileName;
- QSize size;
- QIcon::Mode mode;
- QIcon::State state;
- bool isNull() const {return (fileName.isEmpty() && pixmap.isNull()); }
-};
-
-
-
-class QPixmapIconEngine : public QIconEngineV2 {
-public:
- QPixmapIconEngine();
- QPixmapIconEngine(const QPixmapIconEngine &);
- ~QPixmapIconEngine();
- void paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state);
- QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state);
- QPixmapIconEngineEntry *bestMatch(const QSize &size, QIcon::Mode mode, QIcon::State state, bool sizeOnly);
- QSize actualSize(const QSize &size, QIcon::Mode mode, QIcon::State state);
- void addPixmap(const QPixmap &pixmap, QIcon::Mode mode, QIcon::State state);
- void addFile(const QString &fileName, const QSize &size, QIcon::Mode mode, QIcon::State state);
-
- // v2 functions
- QString key() const;
- QIconEngineV2 *clone() const;
- bool read(QDataStream &in);
- bool write(QDataStream &out) const;
- void virtual_hook(int id, void *data);
-
-private:
- QPixmapIconEngineEntry *tryMatch(const QSize &size, QIcon::Mode mode, QIcon::State state);
- QVector<QPixmapIconEngineEntry> pixmaps;
-
- friend QDataStream &operator<<(QDataStream &s, const QIcon &icon);
- friend class QIconThemeEngine;
-};
-
-QT_END_NAMESPACE
-#endif //QT_NO_ICON
-#endif // QICON_P_H
diff --git a/src/gui/image/qiconengine.h b/src/gui/image/qiconengine.h
deleted file mode 100644
index bfdce557ff..0000000000
--- a/src/gui/image/qiconengine.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QICONENGINE_H
-#define QICONENGINE_H
-
-#include <QtCore/qglobal.h>
-#include <QtCore/qlist.h>
-#include <QtGui/qicon.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class Q_GUI_EXPORT QIconEngine
-{
-public:
- virtual ~QIconEngine();
- virtual void paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state) = 0;
- virtual QSize actualSize(const QSize &size, QIcon::Mode mode, QIcon::State state);
- virtual QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state);
-
- virtual void addPixmap(const QPixmap &pixmap, QIcon::Mode mode, QIcon::State state);
- virtual void addFile(const QString &fileName, const QSize &size, QIcon::Mode mode, QIcon::State state);
-
-#if 0
- virtual int frameCount(QIcon::Mode fromMode, QIcon::State fromState, QIcon::Mode toMode, QIcon::State toState);
- virtual void paintFrame(QPainter *painter, const QRect &rect, int frameNumber, QIcon::Mode fromMode, QIcon::State fromState, QIcon::Mode toMode, QIcon::State toState);
-#endif
-};
-
-// ### Qt 5: move the below into QIconEngine
-class Q_GUI_EXPORT QIconEngineV2 : public QIconEngine
-{
-public:
- virtual QString key() const;
- virtual QIconEngineV2 *clone() const;
- virtual bool read(QDataStream &in);
- virtual bool write(QDataStream &out) const;
- virtual void virtual_hook(int id, void *data);
-
-public:
- enum IconEngineHook { AvailableSizesHook = 1, IconNameHook };
-
- struct AvailableSizesArgument
- {
- QIcon::Mode mode;
- QIcon::State state;
- QList<QSize> sizes;
- };
-
- // ### Qt 5: make this function const and virtual.
- QList<QSize> availableSizes(QIcon::Mode mode = QIcon::Normal,
- QIcon::State state = QIcon::Off);
-
- // ### Qt 5: make this function const and virtual.
- QString iconName();
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QICONENGINE_H
diff --git a/src/gui/image/qiconengineplugin.h b/src/gui/image/qiconengineplugin.h
deleted file mode 100644
index 8e744b4e9c..0000000000
--- a/src/gui/image/qiconengineplugin.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QICONENGINEPLUGIN_H
-#define QICONENGINEPLUGIN_H
-
-#include <QtCore/qplugin.h>
-#include <QtCore/qfactoryinterface.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QIconEngine;
-class QIconEngineV2;
-
-struct Q_GUI_EXPORT QIconEngineFactoryInterface : public QFactoryInterface
-{
- virtual QIconEngine *create(const QString &filename) = 0;
-};
-
-#define QIconEngineFactoryInterface_iid \
- "com.trolltech.Qt.QIconEngineFactoryInterface"
-Q_DECLARE_INTERFACE(QIconEngineFactoryInterface, QIconEngineFactoryInterface_iid)
-
-class Q_GUI_EXPORT QIconEnginePlugin : public QObject, public QIconEngineFactoryInterface
-{
- Q_OBJECT
- Q_INTERFACES(QIconEngineFactoryInterface:QFactoryInterface)
-public:
- QIconEnginePlugin(QObject *parent = 0);
- ~QIconEnginePlugin();
-
- virtual QStringList keys() const = 0;
- virtual QIconEngine *create(const QString &filename) = 0;
-};
-
-// ### Qt 5: remove version 2
-struct Q_GUI_EXPORT QIconEngineFactoryInterfaceV2 : public QFactoryInterface
-{
- virtual QIconEngineV2 *create(const QString &filename = QString()) = 0;
-};
-
-#define QIconEngineFactoryInterfaceV2_iid \
- "com.trolltech.Qt.QIconEngineFactoryInterfaceV2"
-Q_DECLARE_INTERFACE(QIconEngineFactoryInterfaceV2, QIconEngineFactoryInterfaceV2_iid)
-
-class Q_GUI_EXPORT QIconEnginePluginV2 : public QObject, public QIconEngineFactoryInterfaceV2
-{
- Q_OBJECT
- Q_INTERFACES(QIconEngineFactoryInterfaceV2:QFactoryInterface)
-public:
- QIconEnginePluginV2(QObject *parent = 0);
- ~QIconEnginePluginV2();
-
- virtual QStringList keys() const = 0;
- virtual QIconEngineV2 *create(const QString &filename = QString()) = 0;
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QICONENGINEPLUGIN_H
diff --git a/src/gui/image/qiconloader.cpp b/src/gui/image/qiconloader.cpp
deleted file mode 100644
index e63043bf09..0000000000
--- a/src/gui/image/qiconloader.cpp
+++ /dev/null
@@ -1,570 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#ifndef QT_NO_ICON
-#include <private/qiconloader_p.h>
-
-#include <private/qapplication_p.h>
-#include <private/qicon_p.h>
-#include <private/qguiplatformplugin_p.h>
-
-#include <QtGui/QIconEnginePlugin>
-#include <QtGui/QPixmapCache>
-#include <QtGui/QIconEngine>
-#include <QtGui/QStyleOption>
-#include <QtCore/QList>
-#include <QtCore/QHash>
-#include <QtCore/QDir>
-#include <QtCore/QSettings>
-#include <QtGui/QPainter>
-
-#ifdef Q_WS_MAC
-#include <private/qt_cocoa_helpers_mac_p.h>
-#endif
-
-#ifdef Q_WS_X11
-#include <private/qt_x11_p.h>
-#endif
-
-#include <private/qstylehelper_p.h>
-
-QT_BEGIN_NAMESPACE
-
-Q_GLOBAL_STATIC(QIconLoader, iconLoaderInstance)
-
-/* Theme to use in last resort, if the theme does not have the icon, neither the parents */
-static QString fallbackTheme()
-{
-#ifdef Q_WS_X11
- if (X11->desktopEnvironment == DE_GNOME) {
- return QLatin1String("gnome");
- } else if (X11->desktopEnvironment == DE_KDE) {
- return X11->desktopVersion >= 4
- ? QString::fromLatin1("oxygen")
- : QString::fromLatin1("crystalsvg");
- } else {
- return QLatin1String("hicolor");
- }
-#endif
- return QString();
-}
-
-QIconLoader::QIconLoader() :
- m_themeKey(1), m_supportsSvg(false), m_initialized(false)
-{
-}
-
-// We lazily initialize the loader to make static icons
-// work. Though we do not officially support this.
-void QIconLoader::ensureInitialized()
-{
- if (!m_initialized) {
- m_initialized = true;
-
- Q_ASSERT(qApp);
-
- m_systemTheme = qt_guiPlatformPlugin()->systemIconThemeName();
- if (m_systemTheme.isEmpty())
- m_systemTheme = fallbackTheme();
-#ifndef QT_NO_LIBRARY
- QFactoryLoader iconFactoryLoader(QIconEngineFactoryInterfaceV2_iid,
- QLatin1String("/iconengines"),
- Qt::CaseInsensitive);
- if (iconFactoryLoader.keys().contains(QLatin1String("svg")))
- m_supportsSvg = true;
-#endif //QT_NO_LIBRARY
- }
-}
-
-QIconLoader *QIconLoader::instance()
-{
- return iconLoaderInstance();
-}
-
-// Queries the system theme and invalidates existing
-// icons if the theme has changed.
-void QIconLoader::updateSystemTheme()
-{
- // Only change if this is not explicitly set by the user
- if (m_userTheme.isEmpty()) {
- QString theme = qt_guiPlatformPlugin()->systemIconThemeName();
- if (theme.isEmpty())
- theme = fallbackTheme();
- if (theme != m_systemTheme) {
- m_systemTheme = theme;
- invalidateKey();
- }
- }
-}
-
-void QIconLoader::setThemeName(const QString &themeName)
-{
- m_userTheme = themeName;
- invalidateKey();
-}
-
-void QIconLoader::setThemeSearchPath(const QStringList &searchPaths)
-{
- m_iconDirs = searchPaths;
- themeList.clear();
- invalidateKey();
-}
-
-QStringList QIconLoader::themeSearchPaths() const
-{
- if (m_iconDirs.isEmpty()) {
- m_iconDirs = qt_guiPlatformPlugin()->iconThemeSearchPaths();
- // Always add resource directory as search path
- m_iconDirs.append(QLatin1String(":/icons"));
- }
- return m_iconDirs;
-}
-
-QIconTheme::QIconTheme(const QString &themeName)
- : m_valid(false)
-{
- QFile themeIndex;
-
- QList <QIconDirInfo> keyList;
- QStringList iconDirs = QIcon::themeSearchPaths();
- for ( int i = 0 ; i < iconDirs.size() ; ++i) {
- QDir iconDir(iconDirs[i]);
- QString themeDir = iconDir.path() + QLatin1Char('/') + themeName;
- themeIndex.setFileName(themeDir + QLatin1String("/index.theme"));
- if (themeIndex.exists()) {
- m_contentDir = themeDir;
- m_valid = true;
- break;
- }
- }
-#ifndef QT_NO_SETTINGS
- if (themeIndex.exists()) {
- const QSettings indexReader(themeIndex.fileName(), QSettings::IniFormat);
- QStringListIterator keyIterator(indexReader.allKeys());
- while (keyIterator.hasNext()) {
-
- const QString key = keyIterator.next();
- if (key.endsWith(QLatin1String("/Size"))) {
- // Note the QSettings ini-format does not accept
- // slashes in key names, hence we have to cheat
- if (int size = indexReader.value(key).toInt()) {
- QString directoryKey = key.left(key.size() - 5);
- QIconDirInfo dirInfo(directoryKey);
- dirInfo.size = size;
- QString type = indexReader.value(directoryKey +
- QLatin1String("/Type")
- ).toString();
-
- if (type == QLatin1String("Fixed"))
- dirInfo.type = QIconDirInfo::Fixed;
- else if (type == QLatin1String("Scalable"))
- dirInfo.type = QIconDirInfo::Scalable;
- else
- dirInfo.type = QIconDirInfo::Threshold;
-
- dirInfo.threshold = indexReader.value(directoryKey +
- QLatin1String("/Threshold"),
- 2).toInt();
-
- dirInfo.minSize = indexReader.value(directoryKey +
- QLatin1String("/MinSize"),
- size).toInt();
-
- dirInfo.maxSize = indexReader.value(directoryKey +
- QLatin1String("/MaxSize"),
- size).toInt();
- m_keyList.append(dirInfo);
- }
- }
- }
-
- // Parent themes provide fallbacks for missing icons
- m_parents = indexReader.value(
- QLatin1String("Icon Theme/Inherits")).toStringList();
-
- // Ensure a default platform fallback for all themes
- if (m_parents.isEmpty())
- m_parents.append(fallbackTheme());
-
- // Ensure that all themes fall back to hicolor
- if (!m_parents.contains(QLatin1String("hicolor")))
- m_parents.append(QLatin1String("hicolor"));
- }
-#endif //QT_NO_SETTINGS
-}
-
-QThemeIconEntries QIconLoader::findIconHelper(const QString &themeName,
- const QString &iconName,
- QStringList &visited) const
-{
- QThemeIconEntries entries;
- Q_ASSERT(!themeName.isEmpty());
-
- QPixmap pixmap;
-
- // Used to protect against potential recursions
- visited << themeName;
-
- QIconTheme theme = themeList.value(themeName);
- if (!theme.isValid()) {
- theme = QIconTheme(themeName);
- if (!theme.isValid())
- theme = QIconTheme(fallbackTheme());
-
- themeList.insert(themeName, theme);
- }
-
- QString contentDir = theme.contentDir() + QLatin1Char('/');
- QList<QIconDirInfo> subDirs = theme.keyList();
-
- const QString svgext(QLatin1String(".svg"));
- const QString pngext(QLatin1String(".png"));
-
- // Add all relevant files
- for (int i = 0; i < subDirs.size() ; ++i) {
- const QIconDirInfo &dirInfo = subDirs.at(i);
- QString subdir = dirInfo.path;
- QDir currentDir(contentDir + subdir);
- if (currentDir.exists(iconName + pngext)) {
- PixmapEntry *iconEntry = new PixmapEntry;
- iconEntry->dir = dirInfo;
- iconEntry->filename = currentDir.filePath(iconName + pngext);
- // Notice we ensure that pixmap entries always come before
- // scalable to preserve search order afterwards
- entries.prepend(iconEntry);
- } else if (m_supportsSvg &&
- currentDir.exists(iconName + svgext)) {
- ScalableEntry *iconEntry = new ScalableEntry;
- iconEntry->dir = dirInfo;
- iconEntry->filename = currentDir.filePath(iconName + svgext);
- entries.append(iconEntry);
- }
- }
-
- if (entries.isEmpty()) {
- const QStringList parents = theme.parents();
- // Search recursively through inherited themes
- for (int i = 0 ; i < parents.size() ; ++i) {
-
- const QString parentTheme = parents.at(i).trimmed();
-
- if (!visited.contains(parentTheme)) // guard against recursion
- entries = findIconHelper(parentTheme, iconName, visited);
-
- if (!entries.isEmpty()) // success
- break;
- }
- }
- return entries;
-}
-
-QThemeIconEntries QIconLoader::loadIcon(const QString &name) const
-{
- if (!themeName().isEmpty()) {
- QStringList visited;
- return findIconHelper(themeName(), name, visited);
- }
-
- return QThemeIconEntries();
-}
-
-
-// -------- Icon Loader Engine -------- //
-
-
-QIconLoaderEngine::QIconLoaderEngine(const QString& iconName)
- : m_iconName(iconName), m_key(0)
-{
-}
-
-QIconLoaderEngine::~QIconLoaderEngine()
-{
- while (!m_entries.isEmpty())
- delete m_entries.takeLast();
- Q_ASSERT(m_entries.size() == 0);
-}
-
-QIconLoaderEngine::QIconLoaderEngine(const QIconLoaderEngine &other)
- : QIconEngineV2(other),
- m_iconName(other.m_iconName),
- m_key(0)
-{
-}
-
-QIconEngineV2 *QIconLoaderEngine::clone() const
-{
- return new QIconLoaderEngine(*this);
-}
-
-bool QIconLoaderEngine::read(QDataStream &in) {
- in >> m_iconName;
- return true;
-}
-
-bool QIconLoaderEngine::write(QDataStream &out) const
-{
- out << m_iconName;
- return true;
-}
-
-bool QIconLoaderEngine::hasIcon() const
-{
- return !(m_entries.isEmpty());
-}
-
-// Lazily load the icon
-void QIconLoaderEngine::ensureLoaded()
-{
-
- iconLoaderInstance()->ensureInitialized();
-
- if (!(iconLoaderInstance()->themeKey() == m_key)) {
-
- while (!m_entries.isEmpty())
- delete m_entries.takeLast();
-
- Q_ASSERT(m_entries.size() == 0);
- m_entries = iconLoaderInstance()->loadIcon(m_iconName);
- m_key = iconLoaderInstance()->themeKey();
- }
-}
-
-void QIconLoaderEngine::paint(QPainter *painter, const QRect &rect,
- QIcon::Mode mode, QIcon::State state)
-{
- QSize pixmapSize = rect.size();
-#if defined(Q_WS_MAC)
- pixmapSize *= qt_mac_get_scalefactor();
-#endif
- painter->drawPixmap(rect, pixmap(pixmapSize, mode, state));
-}
-
-/*
- * This algorithm is defined by the freedesktop spec:
- * http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html
- */
-static bool directoryMatchesSize(const QIconDirInfo &dir, int iconsize)
-{
- if (dir.type == QIconDirInfo::Fixed) {
- return dir.size == iconsize;
-
- } else if (dir.type == QIconDirInfo::Scalable) {
- return dir.size <= dir.maxSize &&
- iconsize >= dir.minSize;
-
- } else if (dir.type == QIconDirInfo::Threshold) {
- return iconsize >= dir.size - dir.threshold &&
- iconsize <= dir.size + dir.threshold;
- }
-
- Q_ASSERT(1); // Not a valid value
- return false;
-}
-
-/*
- * This algorithm is defined by the freedesktop spec:
- * http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html
- */
-static int directorySizeDistance(const QIconDirInfo &dir, int iconsize)
-{
- if (dir.type == QIconDirInfo::Fixed) {
- return qAbs(dir.size - iconsize);
-
- } else if (dir.type == QIconDirInfo::Scalable) {
- if (iconsize < dir.minSize)
- return dir.minSize - iconsize;
- else if (iconsize > dir.maxSize)
- return iconsize - dir.maxSize;
- else
- return 0;
-
- } else if (dir.type == QIconDirInfo::Threshold) {
- if (iconsize < dir.size - dir.threshold)
- return dir.minSize - iconsize;
- else if (iconsize > dir.size + dir.threshold)
- return iconsize - dir.maxSize;
- else return 0;
- }
-
- Q_ASSERT(1); // Not a valid value
- return INT_MAX;
-}
-
-QIconLoaderEngineEntry *QIconLoaderEngine::entryForSize(const QSize &size)
-{
- int iconsize = qMin(size.width(), size.height());
-
- // Note that m_entries are sorted so that png-files
- // come first
-
- // Search for exact matches first
- for (int i = 0; i < m_entries.count(); ++i) {
- QIconLoaderEngineEntry *entry = m_entries.at(i);
- if (directoryMatchesSize(entry->dir, iconsize)) {
- return entry;
- }
- }
-
- // Find the minimum distance icon
- int minimalSize = INT_MAX;
- QIconLoaderEngineEntry *closestMatch = 0;
- for (int i = 0; i < m_entries.count(); ++i) {
- QIconLoaderEngineEntry *entry = m_entries.at(i);
- int distance = directorySizeDistance(entry->dir, iconsize);
- if (distance < minimalSize) {
- minimalSize = distance;
- closestMatch = entry;
- }
- }
- return closestMatch;
-}
-
-/*
- * Returns the actual icon size. For scalable svg's this is equivalent
- * to the requested size. Otherwise the closest match is returned but
- * we can never return a bigger size than the requested size.
- *
- */
-QSize QIconLoaderEngine::actualSize(const QSize &size, QIcon::Mode mode,
- QIcon::State state)
-{
- ensureLoaded();
-
- QIconLoaderEngineEntry *entry = entryForSize(size);
- if (entry) {
- const QIconDirInfo &dir = entry->dir;
- if (dir.type == QIconDirInfo::Scalable)
- return size;
- else {
- int result = qMin<int>(dir.size, qMin(size.width(), size.height()));
- return QSize(result, result);
- }
- }
- return QIconEngineV2::actualSize(size, mode, state);
-}
-
-QPixmap PixmapEntry::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state)
-{
- Q_UNUSED(state);
-
- // Ensure that basePixmap is lazily initialized before generating the
- // key, otherwise the cache key is not unique
- if (basePixmap.isNull())
- basePixmap.load(filename);
-
- int actualSize = qMin(size.width(), size.height());
-
- QString key = QLatin1Literal("$qt_theme_")
- % HexString<qint64>(basePixmap.cacheKey())
- % HexString<int>(mode)
- % HexString<qint64>(qApp->palette().cacheKey())
- % HexString<int>(actualSize);
-
- QPixmap cachedPixmap;
- if (QPixmapCache::find(key, &cachedPixmap)) {
- return cachedPixmap;
- } else {
- QStyleOption opt(0);
- opt.palette = qApp->palette();
- cachedPixmap = qApp->style()->generatedIconPixmap(mode, basePixmap, &opt);
- QPixmapCache::insert(key, cachedPixmap);
- }
- return cachedPixmap;
-}
-
-QPixmap ScalableEntry::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state)
-{
- if (svgIcon.isNull())
- svgIcon = QIcon(filename);
-
- // Simply reuse svg icon engine
- return svgIcon.pixmap(size, mode, state);
-}
-
-QPixmap QIconLoaderEngine::pixmap(const QSize &size, QIcon::Mode mode,
- QIcon::State state)
-{
- ensureLoaded();
-
- QIconLoaderEngineEntry *entry = entryForSize(size);
- if (entry)
- return entry->pixmap(size, mode, state);
-
- return QPixmap();
-}
-
-QString QIconLoaderEngine::key() const
-{
- return QLatin1String("QIconLoaderEngine");
-}
-
-void QIconLoaderEngine::virtual_hook(int id, void *data)
-{
- ensureLoaded();
-
- switch (id) {
- case QIconEngineV2::AvailableSizesHook:
- {
- QIconEngineV2::AvailableSizesArgument &arg
- = *reinterpret_cast<QIconEngineV2::AvailableSizesArgument*>(data);
- const QList<QIconDirInfo> directoryKey = iconLoaderInstance()->theme().keyList();
- arg.sizes.clear();
-
- // Gets all sizes from the DirectoryInfo entries
- for (int i = 0 ; i < m_entries.size() ; ++i) {
- int size = m_entries.at(i)->dir.size;
- arg.sizes.append(QSize(size, size));
- }
- }
- break;
- case QIconEngineV2::IconNameHook:
- {
- QString &name = *reinterpret_cast<QString*>(data);
- name = m_iconName;
- }
- break;
- default:
- QIconEngineV2::virtual_hook(id, data);
- }
-}
-
-QT_END_NAMESPACE
-
-#endif //QT_NO_ICON
diff --git a/src/gui/image/qiconloader_p.h b/src/gui/image/qiconloader_p.h
deleted file mode 100644
index caa0158628..0000000000
--- a/src/gui/image/qiconloader_p.h
+++ /dev/null
@@ -1,192 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDESKTOPICON_P_H
-#define QDESKTOPICON_P_H
-
-#ifndef QT_NO_ICON
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtGui/QIcon>
-#include <QtGui/QIconEngine>
-#include <QtGui/QPixmapCache>
-#include <private/qicon_p.h>
-#include <private/qfactoryloader_p.h>
-#include <QtCore/QHash>
-
-QT_BEGIN_NAMESPACE
-
-class QIconLoader;
-
-struct QIconDirInfo
-{
- enum Type { Fixed, Scalable, Threshold };
- QIconDirInfo(const QString &_path = QString()) :
- path(_path),
- size(0),
- maxSize(0),
- minSize(0),
- threshold(0),
- type(Threshold) {}
- QString path;
- short size;
- short maxSize;
- short minSize;
- short threshold;
- Type type : 4;
-};
-
-class QIconLoaderEngineEntry
- {
-public:
- virtual ~QIconLoaderEngineEntry() {}
- virtual QPixmap pixmap(const QSize &size,
- QIcon::Mode mode,
- QIcon::State state) = 0;
- QString filename;
- QIconDirInfo dir;
- static int count;
-};
-
-struct ScalableEntry : public QIconLoaderEngineEntry
-{
- QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state);
- QIcon svgIcon;
-};
-
-struct PixmapEntry : public QIconLoaderEngineEntry
-{
- QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state);
- QPixmap basePixmap;
-};
-
-typedef QList<QIconLoaderEngineEntry*> QThemeIconEntries;
-
-class QIconLoaderEngine : public QIconEngineV2
-{
-public:
- QIconLoaderEngine(const QString& iconName = QString());
- ~QIconLoaderEngine();
-
- void paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state);
- QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state);
- QSize actualSize(const QSize &size, QIcon::Mode mode, QIcon::State state);
- QIconEngineV2 *clone() const;
- bool read(QDataStream &in);
- bool write(QDataStream &out) const;
-
-private:
- QString key() const;
- bool hasIcon() const;
- void ensureLoaded();
- void virtual_hook(int id, void *data);
- QIconLoaderEngineEntry *entryForSize(const QSize &size);
- QIconLoaderEngine(const QIconLoaderEngine &other);
- QThemeIconEntries m_entries;
- QString m_iconName;
- uint m_key;
-
- friend class QIconLoader;
-};
-
-class QIconTheme
-{
-public:
- QIconTheme(const QString &name);
- QIconTheme() : m_valid(false) {}
- QStringList parents() { return m_parents; }
- QList <QIconDirInfo> keyList() { return m_keyList; }
- QString contentDir() { return m_contentDir; }
- bool isValid() { return m_valid; }
-
-private:
- QString m_contentDir;
- QList <QIconDirInfo> m_keyList;
- QStringList m_parents;
- bool m_valid;
-};
-
-class QIconLoader : public QObject
-{
-public:
- QIconLoader();
- QThemeIconEntries loadIcon(const QString &iconName) const;
- uint themeKey() const { return m_themeKey; }
-
- QString themeName() const { return m_userTheme.isEmpty() ? m_systemTheme : m_userTheme; }
- void setThemeName(const QString &themeName);
- QIconTheme theme() { return themeList.value(themeName()); }
- void setThemeSearchPath(const QStringList &searchPaths);
- QStringList themeSearchPaths() const;
- QIconDirInfo dirInfo(int dirindex);
- static QIconLoader *instance();
- void updateSystemTheme();
- void invalidateKey() { m_themeKey++; }
- void ensureInitialized();
-
-private:
- QThemeIconEntries findIconHelper(const QString &themeName,
- const QString &iconName,
- QStringList &visited) const;
- uint m_themeKey;
- bool m_supportsSvg;
- bool m_initialized;
-
- mutable QString m_userTheme;
- mutable QString m_systemTheme;
- mutable QStringList m_iconDirs;
- mutable QHash <QString, QIconTheme> themeList;
-};
-
-QT_END_NAMESPACE
-
-#endif // QDESKTOPICON_P_H
-
-#endif //QT_NO_ICON
diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp
index 14322dc929..2dbb2f4b52 100644
--- a/src/gui/image/qimage.cpp
+++ b/src/gui/image/qimage.cpp
@@ -54,9 +54,9 @@
#include <stdlib.h>
#include <limits.h>
#include <math.h>
+#include <qplatformpixmap_qpa.h>
#include <private/qdrawhelper_p.h>
#include <private/qmemrotate_p.h>
-#include <private/qpixmapdata_p.h>
#include <private/qimagescale_p.h>
#include <private/qsimd_p.h>
@@ -124,9 +124,6 @@ QBasicAtomicInt qimage_serial_number = Q_BASIC_ATOMIC_INITIALIZER(1);
QImageData::QImageData()
: ref(0), width(0), height(0), depth(0), nbytes(0), data(0),
-#ifdef QT3_SUPPORT
- jumptable(0),
-#endif
format(QImage::Format_ARGB32), bytes_per_line(0),
ser_no(qimage_serial_number.fetchAndAddRelaxed(1)),
detach_no(0),
@@ -220,11 +217,6 @@ QImageData::~QImageData()
delete paintEngine;
if (data && own_data)
free(data);
-#ifdef QT3_SUPPORT
- if (jumptable)
- free(jumptable);
- jumptable = 0;
-#endif
data = 0;
}
@@ -757,27 +749,6 @@ const uchar *qt_get_bitflip_array() // called from QPixma
return bitflip;
}
-#if defined(QT3_SUPPORT)
-static QImage::Format formatFor(int depth, QImage::Endian bitOrder)
-{
- QImage::Format format;
- if (depth == 1) {
- format = bitOrder == QImage::BigEndian ? QImage::Format_Mono : QImage::Format_MonoLSB;
- } else if (depth == 8) {
- format = QImage::Format_Indexed8;
- } else if (depth == 32) {
- format = QImage::Format_RGB32;
- } else if (depth == 24) {
- format = QImage::Format_RGB888;
- } else if (depth == 16) {
- format = QImage::Format_RGB16;
- } else {
- qWarning("QImage: Depth %d not supported", depth);
- format = QImage::Format_Invalid;
- }
- return format;
-}
-#endif
/*!
Constructs a null image.
@@ -991,42 +962,6 @@ QImage::QImage(const QString &fileName, const char *format)
load(fileName, format);
}
-/*!
- Constructs an image and tries to load the image from the file with
- the given \a fileName.
-
- The loader attempts to read the image using the specified \a
- format. If the \a format is not specified (which is the default),
- the loader probes the file for a header to guess the file format.
-
- If the loading of the image failed, this object is a null image.
-
- The file name can either refer to an actual file on disk or to one
- of the application's embedded resources. See the
- \l{resources.html}{Resource System} overview for details on how to
- embed images and other resource files in the application's
- executable.
-
- You can disable this constructor by defining \c
- QT_NO_CAST_FROM_ASCII when you compile your applications. This can
- be useful, for example, if you want to ensure that all
- user-visible strings go through QObject::tr().
-
- \sa QString::fromAscii(), isNull(), {QImage#Reading and Writing
- Image Files}{Reading and Writing Image Files}
-*/
-#ifndef QT_NO_CAST_FROM_ASCII
-QImage::QImage(const char *fileName, const char *format)
- : QPaintDevice()
-{
- // ### Qt 5: if you remove the QImage(const QByteArray &) QT3_SUPPORT
- // constructor, remove this constructor as well. The constructor here
- // exists so that QImage("foo.png") compiles without ambiguity.
- d = 0;
- load(QString::fromAscii(fileName), format);
-}
-#endif
-
#ifndef QT_NO_IMAGEFORMAT_XPM
extern bool qt_read_xpm_image_or_array(QIODevice *device, const char * const *source, QImage &image);
@@ -1097,178 +1032,6 @@ QImage::QImage(const QImage &image)
}
}
-#ifdef QT3_SUPPORT
-/*!
- \fn QImage::QImage(int width, int height, int depth, int numColors, Endian bitOrder)
-
- Constructs an image with the given \a width, \a height, \a depth,
- \a numColors colors and \a bitOrder.
-
- Use the constructor that accepts a width, a height and a format
- (i.e. specifying the depth and bit order), in combination with the
- setColorCount() function, instead.
-
- \oldcode
- QImage image(width, height, depth, numColors);
- \newcode
- QImage image(width, height, format);
-
- // For 8 bit images the default number of colors is 256. If
- // another number of colors is required it can be specified
- // using the setColorCount() function.
- image.setColorCount(numColors);
- \endcode
-*/
-
-QImage::QImage(int w, int h, int depth, int colorCount, Endian bitOrder)
- : QPaintDevice()
-{
- d = QImageData::create(QSize(w, h), formatFor(depth, bitOrder), colorCount);
-}
-
-/*!
- Constructs an image with the given \a size, \a depth, \a numColors
- and \a bitOrder.
-
- Use the constructor that accepts a size and a format
- (i.e. specifying the depth and bit order), in combination with the
- setColorCount() function, instead.
-
- \oldcode
- QSize mySize(width, height);
- QImage image(mySize, depth, numColors);
- \newcode
- QSize mySize(width, height);
- QImage image(mySize, format);
-
- // For 8 bit images the default number of colors is 256. If
- // another number of colors is required it can be specified
- // using the setColorCount() function.
- image.setColorCount(numColors);
- \endcode
-*/
-QImage::QImage(const QSize& size, int depth, int numColors, Endian bitOrder)
- : QPaintDevice()
-{
- d = QImageData::create(size, formatFor(depth, bitOrder), numColors);
-}
-
-/*!
- \fn QImage::QImage(uchar* data, int width, int height, int depth, const QRgb* colortable, int numColors, Endian bitOrder)
-
- Constructs an image with the given \a width, \a height, depth, \a
- colortable, \a numColors and \a bitOrder, that uses an existing
- memory buffer, \a data.
-
- Use the constructor that accepts a uchar pointer, a width, a
- height and a format (i.e. specifying the depth and bit order), in
- combination with the setColorTable() function, instead.
-
- \oldcode
- uchar *myData;
- QRgb *myColorTable;
-
- QImage image(myData, width, height, depth,
- myColorTable, numColors, IgnoreEndian);
- \newcode
- uchar *myData;
- QVector<QRgb> myColorTable;
-
- QImage image(myData, width, height, format);
- image.setColorTable(myColorTable);
- \endcode
-*/
-QImage::QImage(uchar* data, int w, int h, int depth, const QRgb* colortable, int numColors, Endian bitOrder)
- : QPaintDevice()
-{
- d = 0;
- Format f = formatFor(depth, bitOrder);
- if (f == Format_Invalid)
- return;
-
- const int bytes_per_line = ((w*depth+31)/32)*4; // bytes per scanline
- if (w <= 0 || h <= 0 || numColors < 0 || !data
- || INT_MAX/sizeof(uchar *) < uint(h)
- || INT_MAX/uint(depth) < uint(w)
- || bytes_per_line <= 0
- || INT_MAX/uint(bytes_per_line) < uint(h))
- return; // invalid parameter(s)
- d = new QImageData;
- d->ref.ref();
-
- d->own_data = false;
- d->data = data;
- d->width = w;
- d->height = h;
- d->depth = depth;
- d->format = f;
- if (depth == 32)
- numColors = 0;
-
- d->bytes_per_line = bytes_per_line;
- d->nbytes = d->bytes_per_line * h;
- if (colortable) {
- d->colortable.resize(numColors);
- for (int i = 0; i < numColors; ++i)
- d->colortable[i] = colortable[i];
- } else if (numColors) {
- setColorCount(numColors);
- }
-}
-
-#ifdef Q_WS_QWS
-
-/*!
- \fn QImage::QImage(uchar* data, int width, int height, int depth, int bytesPerLine, const QRgb* colortable, int numColors, Endian bitOrder)
-
- Constructs an image with the given \a width, \a height, \a depth,
- \a bytesPerLine, \a colortable, \a numColors and \a bitOrder, that
- uses an existing memory buffer, \a data. The image does not delete
- the buffer at destruction.
-
- \warning This constructor is only available in Qt for Embedded Linux.
-
- The data has to be 32-bit aligned, and each scanline of data in the image
- must also be 32-bit aligned, so it's no longer possible to specify a custom
- \a bytesPerLine value.
-*/
-QImage::QImage(uchar* data, int w, int h, int depth, int bpl, const QRgb* colortable, int numColors, Endian bitOrder)
- : QPaintDevice()
-{
- d = 0;
- Format f = formatFor(depth, bitOrder);
- if (f == Format_Invalid)
- return;
- if (!data || w <= 0 || h <= 0 || depth <= 0 || numColors < 0
- || INT_MAX/sizeof(uchar *) < uint(h)
- || INT_MAX/uint(depth) < uint(w)
- || bpl <= 0
- || INT_MAX/uint(bpl) < uint(h))
- return; // invalid parameter(s)
-
- d = new QImageData;
- d->ref.ref();
- d->own_data = false;
- d->data = data;
- d->width = w;
- d->height = h;
- d->depth = depth;
- d->format = f;
- if (depth == 32)
- numColors = 0;
- d->bytes_per_line = bpl;
- d->nbytes = d->bytes_per_line * h;
- if (colortable) {
- d->colortable.resize(numColors);
- for (int i = 0; i < numColors; ++i)
- d->colortable[i] = colortable[i];
- } else if (numColors) {
- setColorCount(numColors);
- }
-}
-#endif // Q_WS_QWS
-#endif // QT3_SUPPORT
-
/*!
Destroys the image and cleans up.
*/
@@ -1591,10 +1354,6 @@ int QImage::depth() const
\sa setColorCount()
*/
-int QImage::numColors() const
-{
- return d ? d->colortable.size() : 0;
-}
/*!
\since 4.6
@@ -1613,75 +1372,6 @@ int QImage::colorCount() const
return d ? d->colortable.size() : 0;
}
-
-#ifdef QT3_SUPPORT
-/*!
- \fn QImage::Endian QImage::bitOrder() const
-
- Returns the bit order for the image. If it is a 1-bpp image, this
- function returns either QImage::BigEndian or
- QImage::LittleEndian. Otherwise, this function returns
- QImage::IgnoreEndian.
-
- Use the format() function instead for the monochrome formats. For
- non-monochrome formats the bit order is irrelevant.
-*/
-
-/*!
- Returns a pointer to the scanline pointer table. This is the
- beginning of the data block for the image.
- Returns 0 in case of an error.
-
- Use the bits() or scanLine() function instead.
-*/
-uchar **QImage::jumpTable()
-{
- if (!d)
- return 0;
- detach();
-
- // in case detach() ran out of memory..
- if (!d)
- return 0;
-
- if (!d->jumptable) {
- d->jumptable = (uchar **)malloc(d->height*sizeof(uchar *));
- if (!d->jumptable)
- return 0;
- uchar *data = d->data;
- int height = d->height;
- uchar **p = d->jumptable;
- while (height--) {
- *p++ = data;
- data += d->bytes_per_line;
- }
- }
- return d->jumptable;
-}
-
-/*!
- \overload
-*/
-const uchar * const *QImage::jumpTable() const
-{
- if (!d)
- return 0;
- if (!d->jumptable) {
- d->jumptable = (uchar **)malloc(d->height*sizeof(uchar *));
- if (!d->jumptable)
- return 0;
- uchar *data = d->data;
- int height = d->height;
- uchar **p = d->jumptable;
- while (height--) {
- *p++ = data;
- data += d->bytes_per_line;
- }
- }
- return d->jumptable;
-}
-#endif
-
/*!
Sets the color table used to translate color indexes to QRgb
values, to the specified \a colors.
@@ -1731,10 +1421,6 @@ QVector<QRgb> QImage::colorTable() const
\sa byteCount()
*/
-int QImage::numBytes() const
-{
- return d ? d->nbytes : 0;
-}
/*!
\since 4.6
@@ -2168,10 +1854,6 @@ void QImage::invertPixels(InvertMode mode)
\sa setColorCount()
*/
-void QImage::setNumColors(int numColors)
-{
- setColorCount(numColors);
-}
/*!
\since 4.6
@@ -2224,116 +1906,6 @@ QImage::Format QImage::format() const
}
-#ifdef QT3_SUPPORT
-/*!
- Returns true if alpha buffer mode is enabled; otherwise returns
- false.
-
- Use the hasAlphaChannel() function instead.
-
-*/
-bool QImage::hasAlphaBuffer() const
-{
- if (!d)
- return false;
-
- switch (d->format) {
- case Format_ARGB32:
- case Format_ARGB32_Premultiplied:
- case Format_ARGB8565_Premultiplied:
- case Format_ARGB8555_Premultiplied:
- case Format_ARGB6666_Premultiplied:
- case Format_ARGB4444_Premultiplied:
- return true;
- default:
- return false;
- }
-}
-
-/*!
- Enables alpha buffer mode if \a enable is true, otherwise disables
- it. The alpha buffer is used to set a mask when a QImage is
- translated to a QPixmap.
-
- If a monochrome or indexed 8-bit image has alpha channels in their
- color tables they will automatically detect that they have an
- alpha channel, so this function is not required. To force alpha
- channels on 32-bit images, use the convertToFormat() function.
-*/
-
-void QImage::setAlphaBuffer(bool enable)
-{
- if (!d
- || d->format == Format_Mono
- || d->format == Format_MonoLSB
- || d->format == Format_Indexed8)
- return;
- if (enable && (d->format == Format_ARGB32 ||
- d->format == Format_ARGB32_Premultiplied ||
- d->format == Format_ARGB8565_Premultiplied ||
- d->format == Format_ARGB6666_Premultiplied ||
- d->format == Format_ARGB8555_Premultiplied ||
- d->format == Format_ARGB4444_Premultiplied))
- {
- return;
- }
- if (!enable && (d->format == Format_RGB32 ||
- d->format == Format_RGB555 ||
- d->format == Format_RGB666 ||
- d->format == Format_RGB888 ||
- d->format == Format_RGB444))
- {
- return;
- }
- detach();
- d->format = (enable ? Format_ARGB32 : Format_RGB32);
-}
-
-
-/*!
- \fn bool QImage::create(int width, int height, int depth, int numColors, Endian bitOrder)
-
- Sets the image \a width, \a height, \a depth, its number of colors
- (in \a numColors), and bit order. Returns true if successful, or
- false if the parameters are incorrect or if memory cannot be
- allocated.
-
- The \a width and \a height is limited to 32767. \a depth must be
- 1, 8, or 32. If \a depth is 1, \a bitOrder must be set to
- either QImage::LittleEndian or QImage::BigEndian. For other depths
- \a bitOrder must be QImage::IgnoreEndian.
-
- This function allocates a color table and a buffer for the image
- data. The image data is not initialized. The image buffer is
- allocated as a single block that consists of a table of scanLine()
- pointers (jumpTable()) and the image data (bits()).
-
- Use a QImage constructor instead.
-*/
-bool QImage::create(int width, int height, int depth, int numColors, Endian bitOrder)
-{
- if (d && !d->ref.deref())
- delete d;
- d = QImageData::create(QSize(width, height), formatFor(depth, bitOrder), numColors);
- return true;
-}
-
-/*!
- \fn bool QImage::create(const QSize& size, int depth, int numColors, Endian bitOrder)
- \overload
-
- The width and height are specified in the \a size argument.
-
- Use a QImage constructor instead.
-*/
-bool QImage::create(const QSize& size, int depth, int numColors, QImage::Endian bitOrder)
-{
- if (d && !d->ref.deref())
- delete d;
- d = QImageData::create(size, formatFor(depth, bitOrder), numColors);
- return true;
-}
-#endif // QT3_SUPPORT
/*****************************************************************************
Internal routines for converting image depth.
@@ -4023,30 +3595,6 @@ QImage QImage::convertToFormat(Format format, const QVector<QRgb> &colorTable, Q
return image;
}
-#ifdef QT3_SUPPORT
-/*!
- Converts the depth (bpp) of the image to the given \a depth and
- returns the converted image. The original image is not changed.
- Returns this image if \a depth is equal to the image depth, or a
- null image if this image cannot be converted. The \a depth
- argument must be 1, 8 or 32. If the image needs to be modified to
- fit in a lower-resolution result (e.g. converting from 32-bit to
- 8-bit), use the \a flags to specify how you'd prefer this to
- happen.
-
- Use the convertToFormat() function instead.
-*/
-
-QImage QImage::convertDepth(int depth, Qt::ImageConversionFlags flags) const
-{
- if (!d || d->depth == depth)
- return *this;
-
- Format format = formatFor (depth, QImage::LittleEndian);
- return convertToFormat(format, flags);
-}
-#endif
-
/*!
\fn bool QImage::valid(const QPoint &pos) const
@@ -4265,41 +3813,6 @@ void QImage::setPixel(int x, int y, uint index_or_rgb)
}
}
-#ifdef QT3_SUPPORT
-/*!
- Converts the bit order of the image to the given \a bitOrder and
- returns the converted image. The original image is not changed.
- Returns this image if the given \a bitOrder is equal to the image
- current bit order, or a null image if this image cannot be
- converted.
-
- Use convertToFormat() instead.
-*/
-
-QImage QImage::convertBitOrder(Endian bitOrder) const
-{
- if (!d || isNull() || d->depth != 1 || !(bitOrder == BigEndian || bitOrder == LittleEndian))
- return QImage();
-
- if ((d->format == Format_Mono && bitOrder == BigEndian)
- || (d->format == Format_MonoLSB && bitOrder == LittleEndian))
- return *this;
-
- QImage image(d->width, d->height, d->format == Format_Mono ? Format_MonoLSB : Format_Mono);
-
- const uchar *data = d->data;
- const uchar *end = data + d->nbytes;
- uchar *ndata = image.d->data;
- while (data < end)
- *ndata++ = bitflip[*data++];
-
- image.setDotsPerMeterX(dotsPerMeterX());
- image.setDotsPerMeterY(dotsPerMeterY());
-
- image.d->colortable = d->colortable;
- return image;
-}
-#endif
/*!
Returns true if all the colors in the image are shades of gray
(i.e. their red, green and blue components are equal); otherwise
@@ -5286,66 +4799,6 @@ QDataStream &operator>>(QDataStream &s, QImage &image)
#endif // QT_NO_DATASTREAM
-#ifdef QT3_SUPPORT
-/*!
- \fn QImage QImage::convertDepthWithPalette(int depth, QRgb* palette, int palette_count, Qt::ImageConversionFlags flags) const
-
- Returns an image with the given \a depth, using the \a
- palette_count colors pointed to by \a palette. If \a depth is 1 or
- 8, the returned image will have its color table ordered in the
- same way as \a palette.
-
- If the image needs to be modified to fit in a lower-resolution
- result (e.g. converting from 32-bit to 8-bit), use the \a flags to
- specify how you'd prefer this to happen.
-
- Note: currently no closest-color search is made. If colors are
- found that are not in the palette, the palette may not be used at
- all. This result should not be considered valid because it may
- change in future implementations.
-
- Currently inefficient for non-32-bit images.
-
- Use the convertToFormat() function in combination with the
- setColorTable() function instead.
-*/
-QImage QImage::convertDepthWithPalette(int d, QRgb* palette, int palette_count, Qt::ImageConversionFlags flags) const
-{
- Format f = formatFor(d, QImage::LittleEndian);
- QVector<QRgb> colortable;
- for (int i = 0; i < palette_count; ++i)
- colortable.append(palette[i]);
- return convertToFormat(f, colortable, flags);
-}
-
-/*!
- \relates QImage
-
- Copies a block of pixels from \a src to \a dst. The pixels
- copied from source (src) are converted according to
- \a flags if it is incompatible with the destination
- (\a dst).
-
- \a sx, \a sy is the top-left pixel in \a src, \a dx, \a dy is the
- top-left position in \a dst and \a sw, \a sh is the size of the
- copied block. The copying is clipped if areas outside \a src or \a
- dst are specified. If \a sw is -1, it is adjusted to
- src->width(). Similarly, if \a sh is -1, it is adjusted to
- src->height().
-
- Currently inefficient for non 32-bit images.
-
- Use copy() or QPainter::drawImage() instead.
-*/
-void bitBlt(QImage *dst, int dx, int dy, const QImage *src, int sx, int sy, int sw, int sh,
- Qt::ImageConversionFlags flags)
-{
- if (dst->isNull() || src->isNull())
- return;
- QPainter p(dst);
- p.drawImage(QPoint(dx, dy), *src, QRect(sx, sy, sw, sh), flags);
-}
-#endif
/*!
\fn bool QImage::operator==(const QImage & image) const
@@ -5619,15 +5072,6 @@ void QImage::setText(const QString &key, const QString &value)
The language the text is recorded in is no longer relevant since
the text is always set using QString and UTF-8 representation.
*/
-QString QImage::text(const char* key, const char* lang) const
-{
- if (!d)
- return QString();
- QString k = QString::fromAscii(key);
- if (lang && *lang)
- k += QLatin1Char('/') + QString::fromAscii(lang);
- return d->text.value(k);
-}
/*!
\fn QString QImage::text(const QImageTextKeyLang& keywordAndLanguage) const
@@ -5641,15 +5085,6 @@ QString QImage::text(const char* key, const char* lang) const
The language the text is recorded in is no longer relevant since
the text is always set using QString and UTF-8 representation.
*/
-QString QImage::text(const QImageTextKeyLang& kl) const
-{
- if (!d)
- return QString();
- QString k = QString::fromAscii(kl.key);
- if (!kl.lang.isEmpty())
- k += QLatin1Char('/') + QString::fromAscii(kl.lang);
- return d->text.value(k);
-}
/*!
\obsolete
@@ -5661,20 +5096,6 @@ QString QImage::text(const QImageTextKeyLang& kl) const
The language the text is recorded in is no longer relevant since
the text is always set using QString and UTF-8 representation.
*/
-QStringList QImage::textLanguages() const
-{
- if (!d)
- return QStringList();
- QStringList keys = textKeys();
- QStringList languages;
- for (int i = 0; i < keys.size(); ++i) {
- int index = keys.at(i).indexOf(QLatin1Char('/'));
- if (index > 0)
- languages += keys.at(i).mid(index+1);
- }
-
- return languages;
-}
/*!
\obsolete
@@ -5687,24 +5108,6 @@ QStringList QImage::textLanguages() const
The language the text is recorded in is no longer relevant since
the text is always set using QString and UTF-8 representation.
*/
-QList<QImageTextKeyLang> QImage::textList() const
-{
- QList<QImageTextKeyLang> imageTextKeys;
- if (!d)
- return imageTextKeys;
- QStringList keys = textKeys();
- for (int i = 0; i < keys.size(); ++i) {
- int index = keys.at(i).indexOf(QLatin1Char('/'));
- if (index > 0) {
- QImageTextKeyLang tkl;
- tkl.key = keys.at(i).left(index).toAscii();
- tkl.lang = keys.at(i).mid(index+1).toAscii();
- imageTextKeys += tkl;
- }
- }
-
- return imageTextKeys;
-}
/*!
\fn void QImage::setText(const char* key, const char* language, const QString& text)
@@ -5729,21 +5132,6 @@ QList<QImageTextKeyLang> QImage::textList() const
\l{http://www.rfc-editor.org/rfc/rfc1766.txt}{RFC 1766}) or 0.
\endomit
*/
-void QImage::setText(const char* key, const char* lang, const QString& s)
-{
- if (!d)
- return;
- detach();
-
- // In case detach() ran out of memory
- if (!d)
- return;
-
- QString k = QString::fromAscii(key);
- if (lang && *lang)
- k += QLatin1Char('/') + QString::fromAscii(lang);
- d->text.insert(k, s);
-}
#endif // QT_NO_IMAGE_TEXT
@@ -6325,24 +5713,6 @@ int QImage::bitPlaneCount() const
return bpc;
}
-
-#ifdef QT3_SUPPORT
-#if defined(Q_WS_X11)
-QT_BEGIN_INCLUDE_NAMESPACE
-#include <private/qt_x11_p.h>
-QT_END_INCLUDE_NAMESPACE
-#endif
-
-QImage::Endian QImage::systemBitOrder()
-{
-#if defined(Q_WS_X11)
- return BitmapBitOrder(X11->display) == MSBFirst ? BigEndian : LittleEndian;
-#else
- return BigEndian;
-#endif
-}
-#endif
-
/*!
\fn QImage QImage::copy(const QRect &rect, Qt::ImageConversionFlags flags) const
\compat
diff --git a/src/gui/image/qimage.h b/src/gui/image/qimage.h
index 57d7169789..7e8a0a28e8 100644
--- a/src/gui/image/qimage.h
+++ b/src/gui/image/qimage.h
@@ -66,8 +66,8 @@ template <class T> class QVector;
struct QImageData;
class QImageDataMisc; // internal
#ifndef QT_NO_IMAGE_TEXT
-#ifdef QT_DEPRECATED
-class Q_GUI_EXPORT QT_DEPRECATED QImageTextKeyLang {
+#if QT_DEPRECATED_SINCE(5, 0)
+class Q_GUI_EXPORT QImageTextKeyLang {
public:
QImageTextKeyLang(const char* k, const char* l) : key(k), lang(l) { }
QImageTextKeyLang() { }
@@ -134,9 +134,6 @@ public:
explicit QImage(const char * const xpm[]);
#endif
explicit QImage(const QString &fileName, const char *format = 0);
-#ifndef QT_NO_CAST_FROM_ASCII
- explicit QImage(const char *fileName, const char *format = 0);
-#endif
QImage(const QImage &);
~QImage();
@@ -173,17 +170,11 @@ public:
QRect rect() const;
int depth() const;
-#ifdef QT_DEPRECATED
- QT_DEPRECATED int numColors() const;
-#endif
int colorCount() const;
int bitPlaneCount() const;
QRgb color(int i) const;
void setColor(int i, QRgb c);
-#ifdef QT_DEPRECATED
- QT_DEPRECATED void setNumColors(int);
-#endif
void setColorCount(int);
bool allGray() const;
@@ -192,9 +183,7 @@ public:
uchar *bits();
const uchar *bits() const;
const uchar *constBits() const;
-#ifdef QT_DEPRECATED
- QT_DEPRECATED int numBytes() const;
-#endif
+
int byteCount() const;
uchar *scanLine(int);
@@ -277,57 +266,19 @@ public:
QString text(const QString &key = QString()) const;
void setText(const QString &key, const QString &value);
-#ifdef QT_DEPRECATED
- QT_DEPRECATED QString text(const char* key, const char* lang=0) const;
- QT_DEPRECATED QList<QImageTextKeyLang> textList() const;
- QT_DEPRECATED QStringList textLanguages() const;
- QT_DEPRECATED QString text(const QImageTextKeyLang&) const;
- QT_DEPRECATED void setText(const char* key, const char* lang, const QString&);
+#if QT_DEPRECATED_SINCE(5, 0)
+ inline QString text(const char* key, const char* lang=0) const;
+ inline QList<QImageTextKeyLang> textList() const;
+ inline QStringList textLanguages() const;
+ inline QString text(const QImageTextKeyLang&) const;
+ inline void setText(const char* key, const char* lang, const QString&);
#endif
#endif
-#ifdef QT3_SUPPORT
- enum Endian { BigEndian, LittleEndian, IgnoreEndian };
- QT3_SUPPORT_CONSTRUCTOR QImage(int width, int height, int depth, int numColors=0, Endian bitOrder=IgnoreEndian);
- QT3_SUPPORT_CONSTRUCTOR QImage(const QSize&, int depth, int numColors=0, Endian bitOrder=IgnoreEndian);
- QT3_SUPPORT_CONSTRUCTOR QImage(uchar *data, int w, int h, int depth, const QRgb *colortable, int numColors, Endian bitOrder);
-#ifdef Q_WS_QWS
- QT3_SUPPORT_CONSTRUCTOR QImage(uchar *data, int w, int h, int depth, int pbl, const QRgb *colortable, int numColors, Endian bitOrder);
-#endif
- inline QT3_SUPPORT Endian bitOrder() const {
- Format f = format();
- return f == Format_Mono ? BigEndian : (f == Format_MonoLSB ? LittleEndian : IgnoreEndian);
- }
- QT3_SUPPORT QImage convertDepth(int, Qt::ImageConversionFlags flags = Qt::AutoColor) const;
- QT3_SUPPORT QImage convertDepthWithPalette(int, QRgb* p, int pc, Qt::ImageConversionFlags flags = Qt::AutoColor) const;
- QT3_SUPPORT QImage convertBitOrder(Endian) const;
- QT3_SUPPORT bool hasAlphaBuffer() const;
- QT3_SUPPORT void setAlphaBuffer(bool);
- QT3_SUPPORT uchar **jumpTable();
- QT3_SUPPORT const uchar * const *jumpTable() const;
- inline QT3_SUPPORT void reset() { *this = QImage(); }
- static inline QT3_SUPPORT Endian systemByteOrder()
- { return QSysInfo::ByteOrder == QSysInfo::BigEndian ? BigEndian : LittleEndian; }
- inline QT3_SUPPORT QImage swapRGB() const { return rgbSwapped(); }
- inline QT3_SUPPORT QImage mirror(bool horizontally = false, bool vertically = true) const
- { return mirrored(horizontally, vertically); }
- QT3_SUPPORT bool create(const QSize&, int depth, int numColors=0, Endian bitOrder=IgnoreEndian);
- QT3_SUPPORT bool create(int width, int height, int depth, int numColors=0, Endian bitOrder=IgnoreEndian);
- inline QT3_SUPPORT QImage xForm(const QMatrix &matrix) const { return transformed(QTransform(matrix)); }
- inline QT3_SUPPORT QImage smoothScale(int w, int h, Qt::AspectRatioMode mode = Qt::IgnoreAspectRatio) const
- { return scaled(QSize(w, h), mode, Qt::SmoothTransformation); }
- inline QImage QT3_SUPPORT smoothScale(const QSize &s, Qt::AspectRatioMode mode = Qt::IgnoreAspectRatio) const
- { return scaled(s, mode, Qt::SmoothTransformation); }
- inline QT3_SUPPORT QImage scaleWidth(int w) const { return scaledToWidth(w); }
- inline QT3_SUPPORT QImage scaleHeight(int h) const { return scaledToHeight(h); }
- inline QT3_SUPPORT void invertPixels(bool invertAlpha) { invertAlpha ? invertPixels(InvertRgba) : invertPixels(InvertRgb); }
- inline QT3_SUPPORT QImage copy(int x, int y, int w, int h, Qt::ImageConversionFlags) const
- { return copy(QRect(x, y, w, h)); }
- inline QT3_SUPPORT QImage copy(const QRect &rect, Qt::ImageConversionFlags) const
- { return copy(rect); }
- static QT3_SUPPORT Endian systemBitOrder();
- inline QT3_SUPPORT_CONSTRUCTOR QImage(const QByteArray &data)
- { d = 0; *this = QImage::fromData(data); }
+#if QT_DEPRECATED_SINCE(5, 0)
+ QT_DEPRECATED inline int numColors() const;
+ QT_DEPRECATED inline void setNumColors(int);
+ QT_DEPRECATED inline int numBytes() const;
#endif
protected:
@@ -337,8 +288,8 @@ private:
friend class QWSOnScreenSurface;
QImageData *d;
- friend class QRasterPixmapData;
- friend class QBlittablePixmapData;
+ friend class QRasterPlatformPixmap;
+ friend class QBlittablePlatformPixmap;
friend class QPixmapCacheEntry;
friend Q_GUI_EXPORT qint64 qt_image_id(const QImage &image);
friend const QVector<QRgb> *qt_image_colortable(const QImage &image);
@@ -358,6 +309,94 @@ Q_GUI_EXPORT_INLINE int QImage::pixelIndex(const QPoint &pt) const { return pixe
Q_GUI_EXPORT_INLINE QRgb QImage::pixel(const QPoint &pt) const { return pixel(pt.x(), pt.y()); }
Q_GUI_EXPORT_INLINE void QImage::setPixel(const QPoint &pt, uint index_or_rgb) { setPixel(pt.x(), pt.y(), index_or_rgb); }
+#if QT_DEPRECATED_SINCE(5, 0)
+#ifndef QT_NO_IMAGE_TEXT
+inline QString QImage::text(const char* key, const char* lang) const
+{
+ if (!d)
+ return QString();
+ QString k = QString::fromAscii(key);
+ if (lang && *lang)
+ k += QLatin1Char('/') + QString::fromAscii(lang);
+ return d->text.value(k);
+}
+
+inline QList<QImageTextKeyLang> QImage::textList() const
+{
+ QList<QImageTextKeyLang> imageTextKeys;
+ if (!d)
+ return imageTextKeys;
+ QStringList keys = textKeys();
+ for (int i = 0; i < keys.size(); ++i) {
+ int index = keys.at(i).indexOf(QLatin1Char('/'));
+ if (index > 0) {
+ QImageTextKeyLang tkl;
+ tkl.key = keys.at(i).left(index).toAscii();
+ tkl.lang = keys.at(i).mid(index+1).toAscii();
+ imageTextKeys += tkl;
+ }
+ }
+
+ return imageTextKeys;
+}
+
+inline QStringList QImage::textLanguages() const
+{
+ if (!d)
+ return QStringList();
+ QStringList keys = textKeys();
+ QStringList languages;
+ for (int i = 0; i < keys.size(); ++i) {
+ int index = keys.at(i).indexOf(QLatin1Char('/'));
+ if (index > 0)
+ languages += keys.at(i).mid(index+1);
+ }
+
+ return languages;
+}
+
+inline QString QImage::text(const QImageTextKeyLang&) const
+{
+ if (!d)
+ return QString();
+ QString k = QString::fromAscii(kl.key);
+ if (!kl.lang.isEmpty())
+ k += QLatin1Char('/') + QString::fromAscii(kl.lang);
+ return d->text.value(k);
+}
+
+inline void QImage::setText(const char* key, const char* lang, const QString&)
+{
+ if (!d)
+ return;
+ detach();
+
+ // In case detach() ran out of memory
+ if (!d)
+ return;
+
+ QString k = QString::fromAscii(key);
+ if (lang && *lang)
+ k += QLatin1Char('/') + QString::fromAscii(lang);
+ d->text.insert(k, s);
+}
+#endif
+inline int QImage::numColors() const
+{
+ return d ? d->colortable.size() : 0;
+}
+
+inline void QImage::setNumColors(int)
+{
+ setColorCount(numColors);
+}
+
+inline int QImage::numBytes() const
+{
+ return d ? d->nbytes : 0;
+}
+#endif
+
// QImage stream functions
#if !defined(QT_NO_DATASTREAM)
@@ -365,11 +404,6 @@ Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QImage &);
Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QImage &);
#endif
-#ifdef QT3_SUPPORT
-Q_GUI_EXPORT QT3_SUPPORT void bitBlt(QImage* dst, int dx, int dy, const QImage* src,
- int sx=0, int sy=0, int sw=-1, int sh=-1, Qt::ImageConversionFlags flags = Qt::AutoColor);
-#endif
-
QT_END_NAMESPACE
QT_END_HEADER
diff --git a/src/gui/image/qimage_p.h b/src/gui/image/qimage_p.h
index 7f243770fa..bc24778415 100644
--- a/src/gui/image/qimage_p.h
+++ b/src/gui/image/qimage_p.h
@@ -79,9 +79,6 @@ struct Q_GUI_EXPORT QImageData { // internal image data
int nbytes; // number of bytes data
QVector<QRgb> colortable;
uchar *data;
-#ifdef QT3_SUPPORT
- uchar **jumptable;
-#endif
QImage::Format format;
int bytes_per_line;
int ser_no; // serial number
diff --git a/src/gui/image/qimagepixmapcleanuphooks.cpp b/src/gui/image/qimagepixmapcleanuphooks.cpp
index aa1bf8059e..7901045593 100644
--- a/src/gui/image/qimagepixmapcleanuphooks.cpp
+++ b/src/gui/image/qimagepixmapcleanuphooks.cpp
@@ -40,7 +40,7 @@
****************************************************************************/
#include "qimagepixmapcleanuphooks_p.h"
-#include "private/qpixmapdata_p.h"
+#include "qplatformpixmap_qpa.h"
#include "private/qimage_p.h"
@@ -62,12 +62,12 @@ QImagePixmapCleanupHooks *QImagePixmapCleanupHooks::instance()
return qt_image_and_pixmap_cleanup_hooks();
}
-void QImagePixmapCleanupHooks::addPixmapDataModificationHook(_qt_pixmap_cleanup_hook_pmd hook)
+void QImagePixmapCleanupHooks::addPlatformPixmapModificationHook(_qt_pixmap_cleanup_hook_pmd hook)
{
pixmapModificationHooks.append(hook);
}
-void QImagePixmapCleanupHooks::addPixmapDataDestructionHook(_qt_pixmap_cleanup_hook_pmd hook)
+void QImagePixmapCleanupHooks::addPlatformPixmapDestructionHook(_qt_pixmap_cleanup_hook_pmd hook)
{
pixmapDestructionHooks.append(hook);
}
@@ -78,12 +78,12 @@ void QImagePixmapCleanupHooks::addImageHook(_qt_image_cleanup_hook_64 hook)
imageHooks.append(hook);
}
-void QImagePixmapCleanupHooks::removePixmapDataModificationHook(_qt_pixmap_cleanup_hook_pmd hook)
+void QImagePixmapCleanupHooks::removePlatformPixmapModificationHook(_qt_pixmap_cleanup_hook_pmd hook)
{
pixmapModificationHooks.removeAll(hook);
}
-void QImagePixmapCleanupHooks::removePixmapDataDestructionHook(_qt_pixmap_cleanup_hook_pmd hook)
+void QImagePixmapCleanupHooks::removePlatformPixmapDestructionHook(_qt_pixmap_cleanup_hook_pmd hook)
{
pixmapDestructionHooks.removeAll(hook);
}
@@ -93,7 +93,7 @@ void QImagePixmapCleanupHooks::removeImageHook(_qt_image_cleanup_hook_64 hook)
imageHooks.removeAll(hook);
}
-void QImagePixmapCleanupHooks::executePixmapDataModificationHooks(QPixmapData* pmd)
+void QImagePixmapCleanupHooks::executePlatformPixmapModificationHooks(QPlatformPixmap* pmd)
{
QImagePixmapCleanupHooks *h = qt_image_and_pixmap_cleanup_hooks();
// the global destructor for the pixmap and image hooks might have
@@ -108,7 +108,7 @@ void QImagePixmapCleanupHooks::executePixmapDataModificationHooks(QPixmapData* p
qt_pixmap_cleanup_hook_64(pmd->cacheKey());
}
-void QImagePixmapCleanupHooks::executePixmapDataDestructionHooks(QPixmapData* pmd)
+void QImagePixmapCleanupHooks::executePlatformPixmapDestructionHooks(QPlatformPixmap* pmd)
{
QImagePixmapCleanupHooks *h = qt_image_and_pixmap_cleanup_hooks();
// the global destructor for the pixmap and image hooks might have
@@ -133,9 +133,9 @@ void QImagePixmapCleanupHooks::executeImageHooks(qint64 key)
}
-void QImagePixmapCleanupHooks::enableCleanupHooks(QPixmapData *pixmapData)
+void QImagePixmapCleanupHooks::enableCleanupHooks(QPlatformPixmap *handle)
{
- pixmapData->is_cached = true;
+ handle->is_cached = true;
}
void QImagePixmapCleanupHooks::enableCleanupHooks(const QPixmap &pixmap)
diff --git a/src/gui/image/qimagepixmapcleanuphooks_p.h b/src/gui/image/qimagepixmapcleanuphooks_p.h
index fe49ea0c5e..c98da6110a 100644
--- a/src/gui/image/qimagepixmapcleanuphooks_p.h
+++ b/src/gui/image/qimagepixmapcleanuphooks_p.h
@@ -58,7 +58,7 @@
QT_BEGIN_NAMESPACE
typedef void (*_qt_image_cleanup_hook_64)(qint64);
-typedef void (*_qt_pixmap_cleanup_hook_pmd)(QPixmapData*);
+typedef void (*_qt_pixmap_cleanup_hook_pmd)(QPlatformPixmap*);
class QImagePixmapCleanupHooks;
@@ -70,26 +70,26 @@ public:
static void enableCleanupHooks(const QImage &image);
static void enableCleanupHooks(const QPixmap &pixmap);
- static void enableCleanupHooks(QPixmapData *pixmapData);
+ static void enableCleanupHooks(QPlatformPixmap *handle);
static bool isImageCached(const QImage &image);
static bool isPixmapCached(const QPixmap &pixmap);
// Gets called when a pixmap data is about to be modified:
- void addPixmapDataModificationHook(_qt_pixmap_cleanup_hook_pmd);
+ void addPlatformPixmapModificationHook(_qt_pixmap_cleanup_hook_pmd);
// Gets called when a pixmap data is about to be destroyed:
- void addPixmapDataDestructionHook(_qt_pixmap_cleanup_hook_pmd);
+ void addPlatformPixmapDestructionHook(_qt_pixmap_cleanup_hook_pmd);
// Gets called when an image is about to be modified or destroyed:
void addImageHook(_qt_image_cleanup_hook_64);
- void removePixmapDataModificationHook(_qt_pixmap_cleanup_hook_pmd);
- void removePixmapDataDestructionHook(_qt_pixmap_cleanup_hook_pmd);
+ void removePlatformPixmapModificationHook(_qt_pixmap_cleanup_hook_pmd);
+ void removePlatformPixmapDestructionHook(_qt_pixmap_cleanup_hook_pmd);
void removeImageHook(_qt_image_cleanup_hook_64);
- static void executePixmapDataModificationHooks(QPixmapData*);
- static void executePixmapDataDestructionHooks(QPixmapData*);
+ static void executePlatformPixmapModificationHooks(QPlatformPixmap*);
+ static void executePlatformPixmapDestructionHooks(QPlatformPixmap*);
static void executeImageHooks(qint64 key);
private:
diff --git a/src/gui/image/qimagereader.cpp b/src/gui/image/qimagereader.cpp
index 411e5e9260..4bf4b08349 100644
--- a/src/gui/image/qimagereader.cpp
+++ b/src/gui/image/qimagereader.cpp
@@ -359,6 +359,8 @@ static QImageIOHandler *createReadHandlerHelper(QIODevice *device,
#ifndef QT_NO_IMAGEFORMAT_BMP
} else if (testFormat == "bmp") {
handler = new QBmpHandler;
+ } else if (testFormat == "dib") {
+ handler = new QBmpHandler(QBmpHandler::DibFormat);
#endif
#ifndef QT_NO_IMAGEFORMAT_XPM
} else if (testFormat == "xpm") {
diff --git a/src/gui/image/qimagewriter.cpp b/src/gui/image/qimagewriter.cpp
index 0c465a0a02..82ae64593a 100644
--- a/src/gui/image/qimagewriter.cpp
+++ b/src/gui/image/qimagewriter.cpp
@@ -201,6 +201,8 @@ static QImageIOHandler *createWriteHandlerHelper(QIODevice *device,
#ifndef QT_NO_IMAGEFORMAT_BMP
} else if (testFormat == "bmp") {
handler = new QBmpHandler;
+ } else if (testFormat == "dib") {
+ handler = new QBmpHandler(QBmpHandler::DibFormat);
#endif
#ifndef QT_NO_IMAGEFORMAT_XPM
} else if (testFormat == "xpm") {
diff --git a/src/gui/image/qmovie.h b/src/gui/image/qmovie.h
index f971e11b13..0278957091 100644
--- a/src/gui/image/qmovie.h
+++ b/src/gui/image/qmovie.h
@@ -51,11 +51,6 @@
#include <QtCore/qobject.h>
#include <QtGui/qimagereader.h>
-#ifdef QT3_SUPPORT
-#include <QtGui/qimage.h>
-#include <QtGui/qpixmap.h>
-#endif
-
QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
@@ -151,21 +146,6 @@ public Q_SLOTS:
private:
Q_DISABLE_COPY(QMovie)
Q_PRIVATE_SLOT(d_func(), void _q_loadNextFrame())
-
-#ifdef QT3_SUPPORT
-public:
- inline QT3_SUPPORT bool isNull() const { return isValid(); }
- inline QT3_SUPPORT int frameNumber() const { return currentFrameNumber(); }
- inline QT3_SUPPORT bool running() const { return state() == Running; }
- inline QT3_SUPPORT bool paused() const { return state() == Paused; }
- inline QT3_SUPPORT bool finished() const { return state() == NotRunning; }
- inline QT3_SUPPORT void restart() { stop(); start(); }
- inline QT3_SUPPORT QImage frameImage() const { return currentImage(); }
- inline QT3_SUPPORT QPixmap framePixmap() const { return currentPixmap(); }
- inline QT3_SUPPORT void step() { jumpToNextFrame(); }
- inline QT3_SUPPORT void pause() { setPaused(true); }
- inline QT3_SUPPORT void unpause() { setPaused(false); }
-#endif
};
QT_END_NAMESPACE
diff --git a/src/gui/image/qnativeimage.cpp b/src/gui/image/qnativeimage.cpp
index aebcbafd29..35bca4431d 100644
--- a/src/gui/image/qnativeimage.cpp
+++ b/src/gui/image/qnativeimage.cpp
@@ -41,18 +41,17 @@
#include <qdebug.h>
#include "qnativeimage_p.h"
-#include "qcolormap.h"
+#include "private/qguiapplication_p.h"
+#include "qscreen.h"
#include "private/qpaintengine_raster_p.h"
-#include "private/qapplication_p.h"
-#include "private/qgraphicssystem_p.h"
+#include "private/qguiapplication_p.h"
#if defined(Q_WS_X11) && !defined(QT_NO_MITSHM)
#include <qx11info_x11.h>
#include <sys/ipc.h>
#include <sys/shm.h>
-#include <qwidget.h>
#endif
#ifdef Q_WS_MAC
@@ -70,7 +69,7 @@ typedef struct {
} BITMAPINFO_MASK;
-QNativeImage::QNativeImage(int width, int height, QImage::Format format, bool isTextBuffer, QWidget *)
+QNativeImage::QNativeImage(int width, int height, QImage::Format format, bool isTextBuffer, QWindow *)
{
#ifndef Q_WS_WINCE
Q_UNUSED(isTextBuffer);
@@ -142,107 +141,14 @@ QNativeImage::~QNativeImage()
QImage::Format QNativeImage::systemFormat()
{
- if (QColormap::instance().depth() == 16)
- return QImage::Format_RGB16;
- return QImage::Format_RGB32;
-}
-
-
-#elif defined(Q_WS_X11) && !defined(QT_NO_MITSHM)
-
-QNativeImage::QNativeImage(int width, int height, QImage::Format format,bool /* isTextBuffer */, QWidget *widget)
- : xshmimg(0), xshmpm(0)
-{
- if (!X11->use_mitshm) {
- image = QImage(width, height, format);
- // follow good coding practice and set xshminfo attributes, though values not used in this case
- xshminfo.readOnly = true;
- xshminfo.shmaddr = 0;
- xshminfo.shmid = 0;
- xshminfo.shmseg = 0;
- return;
- }
-
- QX11Info info = widget->x11Info();
-
- int dd = info.depth();
- Visual *vis = (Visual*) info.visual();
-
- xshmimg = XShmCreateImage(X11->display, vis, dd, ZPixmap, 0, &xshminfo, width, height);
- if (!xshmimg) {
- qWarning("QNativeImage: Unable to create shared XImage.");
- return;
- }
-
- bool ok;
- xshminfo.shmid = shmget(IPC_PRIVATE, xshmimg->bytes_per_line * xshmimg->height,
- IPC_CREAT | 0777);
- ok = xshminfo.shmid != -1;
- if (ok) {
- xshmimg->data = (char*)shmat(xshminfo.shmid, 0, 0);
- xshminfo.shmaddr = xshmimg->data;
- ok = (xshminfo.shmaddr != (char*)-1);
- if (ok)
- image = QImage((uchar *)xshmimg->data, width, height, format);
- }
- xshminfo.readOnly = false;
- if (ok) {
- ok = XShmAttach(X11->display, &xshminfo);
- XSync(X11->display, False);
- if (shmctl(xshminfo.shmid, IPC_RMID, 0) == -1)
- qWarning() << "Error while marking the shared memory segment to be destroyed";
- }
- if (!ok) {
- qWarning() << "QNativeImage: Unable to attach to shared memory segment.";
- if (xshmimg->data) {
- free(xshmimg->data);
- xshmimg->data = 0;
- }
- XDestroyImage(xshmimg);
- xshmimg = 0;
- if (xshminfo.shmaddr)
- shmdt(xshminfo.shmaddr);
- if (xshminfo.shmid != -1)
- shmctl(xshminfo.shmid, IPC_RMID, 0);
- return;
- }
- if (X11->use_mitshm_pixmaps) {
- xshmpm = XShmCreatePixmap(X11->display, DefaultRootWindow(X11->display), xshmimg->data,
- &xshminfo, width, height, dd);
- if (!xshmpm) {
- qWarning() << "QNativeImage: Unable to create shared Pixmap.";
- }
- }
-}
-
-
-QNativeImage::~QNativeImage()
-{
- if (!xshmimg)
- return;
-
- if (xshmpm) {
- XFreePixmap(X11->display, xshmpm);
- xshmpm = 0;
- }
- XShmDetach(X11->display, &xshminfo);
- xshmimg->data = 0;
- XDestroyImage(xshmimg);
- xshmimg = 0;
- shmdt(xshminfo.shmaddr);
- shmctl(xshminfo.shmid, IPC_RMID, 0);
-}
-
-QImage::Format QNativeImage::systemFormat()
-{
- if (QX11Info::appDepth() == 16)
+ if (QGuiApplication::primaryScreen()->depth() == 16)
return QImage::Format_RGB16;
return QImage::Format_RGB32;
}
#elif defined(Q_WS_MAC)
-QNativeImage::QNativeImage(int width, int height, QImage::Format format, bool /* isTextBuffer */, QWidget *widget)
+QNativeImage::QNativeImage(int width, int height, QImage::Format format, bool /* isTextBuffer */, QWindow *)
: image(width, height, format)
{
@@ -267,7 +173,7 @@ QNativeImage::QNativeImage(int width, int height, QImage::Format format, bool /*
#endif
cg = CGBitmapContextCreate(image.bits(), width, height, 8, image.bytesPerLine(),
- QCoreGraphicsPaintEngine::macDisplayColorSpace(widget), cgflags);
+ QCoreGraphicsPaintEngine::macDisplayColorSpace(0), cgflags);
CGContextTranslateCTM(cg, 0, height);
CGContextScaleCTM(cg, 1, -1);
@@ -289,7 +195,7 @@ QImage::Format QNativeImage::systemFormat()
#else // other platforms...
-QNativeImage::QNativeImage(int width, int height, QImage::Format format, bool /* isTextBuffer */, QWidget *)
+QNativeImage::QNativeImage(int width, int height, QImage::Format format, bool /* isTextBuffer */, QWindow *)
: image(width, height, format)
{
@@ -302,11 +208,7 @@ QNativeImage::~QNativeImage()
QImage::Format QNativeImage::systemFormat()
{
-#ifdef Q_WS_QPA
- return QApplicationPrivate::platformIntegration()->screens().at(0)->format();
-#else
- return QImage::Format_RGB32;
-#endif
+ return QGuiApplication::primaryScreen()->handle()->format();
}
#endif // platforms
diff --git a/src/gui/image/qnativeimage_p.h b/src/gui/image/qnativeimage_p.h
index e468917a67..f9132de69e 100644
--- a/src/gui/image/qnativeimage_p.h
+++ b/src/gui/image/qnativeimage_p.h
@@ -58,9 +58,6 @@
#ifdef Q_WS_WIN
#include "qt_windows.h"
-#elif defined(Q_WS_X11)
-#include <private/qt_x11_p.h>
-
#elif defined(Q_WS_MAC)
#include <private/qt_mac_p.h>
@@ -68,12 +65,12 @@
QT_BEGIN_NAMESPACE
-class QWidget;
+class QWindow;
class QNativeImage
{
public:
- QNativeImage(int width, int height, QImage::Format format, bool isTextBuffer = false, QWidget *widget = 0);
+ QNativeImage(int width, int height, QImage::Format format, bool isTextBuffer = false, QWindow *window = 0);
~QNativeImage();
inline int width() const;
@@ -88,11 +85,6 @@ public:
HBITMAP bitmap;
HBITMAP null_bitmap;
-#elif defined(Q_WS_X11) && !defined(QT_NO_MITSHM)
- XImage *xshmimg;
- Pixmap xshmpm;
- XShmSegmentInfo xshminfo;
-
#elif defined(Q_WS_MAC)
CGContextRef cg;
#endif
diff --git a/src/gui/image/qnativeimagehandleprovider_p.h b/src/gui/image/qnativeimagehandleprovider_p.h
deleted file mode 100644
index b3b3e487d1..0000000000
--- a/src/gui/image/qnativeimagehandleprovider_p.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QNATIVEIMAGEHANDLEPROVIDER_P_H
-#define QNATIVEIMAGEHANDLEPROVIDER_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/qstring.h>
-
-QT_BEGIN_NAMESPACE
-
-class QNativeImageHandleProvider
-{
-public:
- virtual void get(void **handle, QString *type) = 0;
- virtual void release(void *handle, const QString &type) = 0;
-};
-
-QT_END_NAMESPACE
-
-#endif // QNATIVEIMAGEHANDLEPROVIDER_P_H
diff --git a/src/gui/image/qpicture.cpp b/src/gui/image/qpicture.cpp
index 5df469ace7..418393a1b8 100644
--- a/src/gui/image/qpicture.cpp
+++ b/src/gui/image/qpicture.cpp
@@ -47,6 +47,7 @@
#include <private/qfactoryloader_p.h>
#include <private/qpaintengine_pic_p.h>
#include <private/qfont_p.h>
+#include <qguiapplication.h>
#include "qdatastream.h"
#include "qfile.h"
@@ -1217,7 +1218,6 @@ QDataStream &operator>>(QDataStream &s, QPicture &r)
QT_BEGIN_INCLUDE_NAMESPACE
#include "qregexp.h"
-#include "qapplication.h"
#include "qpictureformatplugin.h"
QT_END_INCLUDE_NAMESPACE
diff --git a/src/gui/image/qpicture.h b/src/gui/image/qpicture.h
index 848a6f5083..1c5d3a9c8f 100644
--- a/src/gui/image/qpicture.h
+++ b/src/gui/image/qpicture.h
@@ -104,9 +104,6 @@ protected:
QPicture(QPicturePrivate &data);
int metric(PaintDeviceMetric m) const;
-#ifdef QT3_SUPPORT
- inline QT3_SUPPORT QPicture copy() const { QPicture p(*this); p.detach(); return p; }
-#endif
private:
bool exec(QPainter *p, QDataStream &ds, int i);
diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp
index 70715793a7..c2b9c6a1b9 100644
--- a/src/gui/image/qpixmap.cpp
+++ b/src/gui/image/qpixmap.cpp
@@ -42,20 +42,15 @@
#include <qglobal.h>
#include "qpixmap.h"
-#include "qpixmapdata_p.h"
+#include "qplatformpixmap_qpa.h"
#include "qimagepixmapcleanuphooks_p.h"
#include "qbitmap.h"
-#include "qcolormap.h"
#include "qimage.h"
-#include "qwidget.h"
#include "qpainter.h"
#include "qdatastream.h"
#include "qbuffer.h"
-#include "qapplication.h"
-#include <private/qapplication_p.h>
-#include <private/qgraphicssystem_p.h>
-#include <private/qwidget_p.h>
+#include <private/qguiapplication_p.h>
#include "qevent.h"
#include "qfile.h"
#include "qfileinfo.h"
@@ -65,58 +60,30 @@
#include "qimagewriter.h"
#include "qpaintengine.h"
#include "qthread.h"
-
-#ifdef Q_WS_MAC
-# include "private/qt_mac_p.h"
-# include "private/qpixmap_mac_p.h"
-#endif
+#include "qdebug.h"
#ifdef Q_WS_QPA
# include "qplatformintegration_qpa.h"
#endif
-#if defined(Q_WS_X11)
-# include "qx11info_x11.h"
-# include <private/qt_x11_p.h>
-# include <private/qpixmap_x11_p.h>
-#endif
-
-#if defined(Q_OS_SYMBIAN)
-# include <private/qt_s60_p.h>
-#endif
-
#include "qpixmap_raster_p.h"
-#include "private/qstylehelper_p.h"
+#include "private/qhexstring_p.h"
QT_BEGIN_NAMESPACE
-// ### Qt 5: remove
-Q_GUI_EXPORT qint64 qt_pixmap_id(const QPixmap &pixmap)
-{
- return pixmap.cacheKey();
-}
-
static bool qt_pixmap_thread_test()
{
- if (!qApp) {
+ if (!QCoreApplication::instance()) {
qFatal("QPixmap: Must construct a QApplication before a QPaintDevice");
return false;
}
if (qApp->thread() != QThread::currentThread()) {
bool fail = false;
-#if defined (Q_WS_X11)
- if (!QApplication::testAttribute(Qt::AA_X11InitThreads))
- fail = true;
-#elif defined (Q_WS_QPA)
- if (!QApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ThreadedPixmaps)) {
+ if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ThreadedPixmaps)) {
printf("Lighthouse plugin does not support threaded pixmaps!\n");
fail = true;
}
-#else
- if (QApplicationPrivate::graphics_system_name != QLatin1String("raster"))
- fail = true;
-#endif
if (fail) {
qWarning("QPixmap: It is not safe to use pixmaps outside the GUI thread");
return false;
@@ -125,23 +92,10 @@ static bool qt_pixmap_thread_test()
return true;
}
-void QPixmap::init(int w, int h, Type type)
-{
- init(w, h, int(type));
-}
-
-extern QApplication::Type qt_appType;
-
-void QPixmap::init(int w, int h, int type)
+void QPixmap::doInit(int w, int h, int type)
{
- if (qt_appType == QApplication::Tty) {
- qWarning("QPixmap: Cannot create a QPixmap when no GUI is being used");
- data = 0;
- return;
- }
-
- if ((w > 0 && h > 0) || type == QPixmapData::BitmapType)
- data = QPixmapData::create(w, h, (QPixmapData::PixelType) type);
+ if ((w > 0 && h > 0) || type == QPlatformPixmap::BitmapType)
+ data = QPlatformPixmap::create(w, h, (QPlatformPixmap::PixelType) type);
else
data = 0;
}
@@ -172,7 +126,7 @@ QPixmap::QPixmap()
: QPaintDevice()
{
(void) qt_pixmap_thread_test();
- init(0, 0, QPixmapData::PixmapType);
+ doInit(0, 0, QPlatformPixmap::PixmapType);
}
/*!
@@ -193,9 +147,9 @@ QPixmap::QPixmap(int w, int h)
: QPaintDevice()
{
if (!qt_pixmap_thread_test())
- init(0, 0, QPixmapData::PixmapType);
+ doInit(0, 0, QPlatformPixmap::PixmapType);
else
- init(w, h, QPixmapData::PixmapType);
+ doInit(w, h, QPlatformPixmap::PixmapType);
}
/*!
@@ -212,20 +166,9 @@ QPixmap::QPixmap(const QSize &size)
: QPaintDevice()
{
if (!qt_pixmap_thread_test())
- init(0, 0, QPixmapData::PixmapType);
- else
- init(size.width(), size.height(), QPixmapData::PixmapType);
-}
-
-/*!
- \internal
-*/
-QPixmap::QPixmap(const QSize &s, Type type)
-{
- if (!qt_pixmap_thread_test())
- init(0, 0, type);
+ doInit(0, 0, QPlatformPixmap::PixmapType);
else
- init(s.width(), s.height(), type);
+ doInit(size.width(), size.height(), QPlatformPixmap::PixmapType);
}
/*!
@@ -234,15 +177,15 @@ QPixmap::QPixmap(const QSize &s, Type type)
QPixmap::QPixmap(const QSize &s, int type)
{
if (!qt_pixmap_thread_test())
- init(0, 0, static_cast<QPixmapData::PixelType>(type));
+ doInit(0, 0, static_cast<QPlatformPixmap::PixelType>(type));
else
- init(s.width(), s.height(), static_cast<QPixmapData::PixelType>(type));
+ doInit(s.width(), s.height(), static_cast<QPlatformPixmap::PixelType>(type));
}
/*!
\internal
*/
-QPixmap::QPixmap(QPixmapData *d)
+QPixmap::QPixmap(QPlatformPixmap *d)
: QPaintDevice(), data(d)
{
}
@@ -279,7 +222,7 @@ QPixmap::QPixmap(QPixmapData *d)
QPixmap::QPixmap(const QString& fileName, const char *format, Qt::ImageConversionFlags flags)
: QPaintDevice()
{
- init(0, 0, QPixmapData::PixmapType);
+ doInit(0, 0, QPlatformPixmap::PixmapType);
if (!qt_pixmap_thread_test())
return;
@@ -296,7 +239,7 @@ QPixmap::QPixmap(const QPixmap &pixmap)
: QPaintDevice()
{
if (!qt_pixmap_thread_test()) {
- init(0, 0, QPixmapData::PixmapType);
+ doInit(0, 0, QPlatformPixmap::PixmapType);
return;
}
if (pixmap.paintingActive()) { // make a deep copy
@@ -325,13 +268,13 @@ QPixmap::QPixmap(const QPixmap &pixmap)
QPixmap::QPixmap(const char * const xpm[])
: QPaintDevice()
{
- init(0, 0, QPixmapData::PixmapType);
+ doInit(0, 0, QPlatformPixmap::PixmapType);
if (!xpm)
return;
QImage image(xpm);
if (!image.isNull()) {
- if (data && data->pixelType() == QPixmapData::BitmapType)
+ if (data && data->pixelType() == QPlatformPixmap::BitmapType)
*this = QBitmap::fromImage(image);
else
*this = fromImage(image);
@@ -386,7 +329,7 @@ QPixmap QPixmap::copy(const QRect &rect) const
if (!rect.isEmpty())
r = r.intersected(rect);
- QPixmapData *d = data->createCompatiblePixmapData();
+ QPlatformPixmap *d = data->createCompatiblePlatformPixmap();
d->copy(data.data(), r);
return QPixmap(d);
}
@@ -563,7 +506,7 @@ QMatrix QPixmap::trueMatrix(const QMatrix &m, int w, int h)
bool QPixmap::isQBitmap() const
{
- return data->type == QPixmapData::BitmapType;
+ return data->type == QPlatformPixmap::BitmapType;
}
/*!
@@ -657,65 +600,6 @@ int QPixmap::depth() const
pixmap = pixmap.copy(QRect(QPoint(0, 0), size));
\endcode
*/
-#ifdef QT3_SUPPORT
-void QPixmap::resize_helper(const QSize &s)
-{
- int w = s.width();
- int h = s.height();
- if (w < 1 || h < 1) {
- *this = QPixmap();
- return;
- }
-
- if (size() == s)
- return;
-
- // QPixmap.data member may be QRuntimePixmapData so use pixmapData() function to get
- // the actual underlaying runtime pixmap data.
- QPixmapData *pd = pixmapData();
-
- // Create new pixmap
- QPixmap pm(QSize(w, h), pd ? pd->type : QPixmapData::PixmapType);
- bool uninit = false;
-#if defined(Q_WS_X11)
- QX11PixmapData *x11Data = pd && pd->classId() == QPixmapData::X11Class ? static_cast<QX11PixmapData*>(pd) : 0;
- if (x11Data) {
- pm.x11SetScreen(x11Data->xinfo.screen());
- uninit = x11Data->flags & QX11PixmapData::Uninitialized;
- }
-#elif defined(Q_WS_MAC)
- QMacPixmapData *macData = pd && pd->classId() == QPixmapData::MacClass ? static_cast<QMacPixmapData*>(pd) : 0;
- if (macData)
- uninit = macData->uninit;
-#endif
- if (!uninit && !isNull()) {
- // Copy old pixmap
- if (hasAlphaChannel())
- pm.fill(Qt::transparent);
- QPainter p(&pm);
- p.drawPixmap(0, 0, *this, 0, 0, qMin(width(), w), qMin(height(), h));
- }
-
-#if defined(Q_WS_X11)
- if (x11Data && x11Data->x11_mask) {
- QPixmapData *newPd = pm.pixmapData();
- QX11PixmapData *pmData = (newPd && newPd->classId() == QPixmapData::X11Class)
- ? static_cast<QX11PixmapData*>(newPd) : 0;
- if (pmData) {
- pmData->x11_mask = (Qt::HANDLE)XCreatePixmap(X11->display,
- RootWindow(x11Data->xinfo.display(),
- x11Data->xinfo.screen()),
- w, h, 1);
- GC gc = XCreateGC(X11->display, pmData->x11_mask, 0, 0);
- XCopyArea(X11->display, x11Data->x11_mask, pmData->x11_mask, gc, 0, 0,
- qMin(width(), w), qMin(height(), h), 0, 0);
- XFreeGC(X11->display, gc);
- }
- }
-#endif
- *this = pm;
-}
-#endif
/*!
\fn void QPixmap::resize(int width, int height)
@@ -776,7 +660,44 @@ void QPixmap::setMask(const QBitmap &mask)
return;
detach();
- data->setMask(mask);
+
+ QImage image = data->toImage();
+ if (mask.size().isEmpty()) {
+ if (image.depth() != 1) { // hw: ????
+ image = image.convertToFormat(QImage::Format_RGB32);
+ }
+ } else {
+ const int w = image.width();
+ const int h = image.height();
+
+ switch (image.depth()) {
+ case 1: {
+ const QImage imageMask = mask.toImage().convertToFormat(image.format());
+ for (int y = 0; y < h; ++y) {
+ const uchar *mscan = imageMask.scanLine(y);
+ uchar *tscan = image.scanLine(y);
+ int bytesPerLine = image.bytesPerLine();
+ for (int i = 0; i < bytesPerLine; ++i)
+ tscan[i] &= mscan[i];
+ }
+ break;
+ }
+ default: {
+ const QImage imageMask = mask.toImage().convertToFormat(QImage::Format_MonoLSB);
+ image = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
+ for (int y = 0; y < h; ++y) {
+ const uchar *mscan = imageMask.scanLine(y);
+ QRgb *tscan = (QRgb *)image.scanLine(y);
+ for (int x = 0; x < w; ++x) {
+ if (!(mscan[x>>3] & (1 << (x&7))))
+ tscan[x] = 0;
+ }
+ }
+ break;
+ }
+ }
+ }
+ data->fromImage(image, Qt::AutoColor);
}
#ifndef QT_NO_IMAGE_HEURISTIC_MASK
@@ -823,19 +744,6 @@ QBitmap QPixmap::createMaskFromColor(const QColor &maskColor, Qt::MaskMode mode)
return QBitmap::fromImage(image.createMaskFromColor(maskColor.rgba(), mode));
}
-/*! \overload
-
- Creates and returns a mask for this pixmap based on the given \a
- maskColor. Same as calling createMaskFromColor(maskColor,
- Qt::MaskInColor)
-
- \sa createHeuristicMask(), QImage::createMaskFromColor()
-*/
-QBitmap QPixmap::createMaskFromColor(const QColor &maskColor) const
-{
- return createMaskFromColor(maskColor, Qt::MaskInColor);
-}
-
/*!
Loads a pixmap from the file with the given \a fileName. Returns
true if the pixmap was successfully loaded; otherwise returns
@@ -873,7 +781,7 @@ bool QPixmap::load(const QString &fileName, const char *format, Qt::ImageConvers
% info.absoluteFilePath()
% HexString<uint>(info.lastModified().toTime_t())
% HexString<quint64>(info.size())
- % HexString<uint>(data ? data->pixelType() : QPixmapData::PixmapType);
+ % HexString<uint>(data ? data->pixelType() : QPlatformPixmap::PixmapType);
// Note: If no extension is provided, we try to match the
// file against known plugin extensions
@@ -883,7 +791,7 @@ bool QPixmap::load(const QString &fileName, const char *format, Qt::ImageConvers
if (QPixmapCache::find(key, *this))
return true;
- QScopedPointer<QPixmapData> tmp(QPixmapData::create(0, 0, data ? data->type : QPixmapData::PixmapType));
+ QScopedPointer<QPlatformPixmap> tmp(QPlatformPixmap::create(0, 0, data ? data->type : QPlatformPixmap::PixmapType));
if (tmp->fromFile(fileName, format, flags)) {
data = tmp.take();
QPixmapCache::insert(key, *this);
@@ -918,7 +826,7 @@ bool QPixmap::loadFromData(const uchar *buf, uint len, const char *format, Qt::I
return false;
if (!data)
- data = QPixmapData::create(0, 0, QPixmapData::PixmapType);
+ data = QPlatformPixmap::create(0, 0, QPlatformPixmap::PixmapType);
return data->fromData(buf, len, format, flags);
}
@@ -986,21 +894,24 @@ bool QPixmap::doImageIO(QImageWriter *writer, int quality) const
return writer->write(toImage());
}
-
-// The implementation (and documentation) of
-// QPixmap::fill(const QWidget *, const QPoint &)
-// is in qwidget.cpp
-
/*!
- \fn void QPixmap::fill(const QWidget *widget, int x, int y)
+ \fn void QPixmap::fill(const QPaintDevice *device, int x, int y)
\overload
- Fills the pixmap with the \a widget's background color or pixmap.
+ \obsolete
+
+ Fills the pixmap with the \a device's background color or pixmap.
The given point, (\a x, \a y), defines an offset in widget
coordinates to which the pixmap's top-left pixel will be mapped
to.
*/
+void QPixmap::fill(const QPaintDevice *, const QPoint &)
+{
+ qWarning() << "QPixmap::fill(const QPaintDevice *device, const QPoint &offset) is deprecated, ignored";
+}
+
+
/*!
Fills the pixmap with the given \a color.
@@ -1029,7 +940,7 @@ void QPixmap::fill(const QColor &color)
} else {
// Don't bother to make a copy of the data object, since
// it will be filled with new pixel data anyway.
- QPixmapData *d = data->createCompatiblePixmapData();
+ QPlatformPixmap *d = data->createCompatiblePlatformPixmap();
d->resize(data->width(), data->height());
data = d;
}
@@ -1072,6 +983,7 @@ qint64 QPixmap::cacheKey() const
return data->cacheKey();
}
+#if 0
static void sendResizeEvents(QWidget *target)
{
QResizeEvent e(target->size(), QSize());
@@ -1084,9 +996,10 @@ static void sendResizeEvents(QWidget *target)
sendResizeEvents(child);
}
}
+#endif
/*!
- \fn QPixmap QPixmap::grabWidget(QWidget * widget, const QRect &rectangle)
+ \fn QPixmap QPixmap::grabWidget(QPaintDevice * widget, const QRect &rectangle)
Creates a pixmap and paints the given \a widget, restricted by the
given \a rectangle, in it. If the \a widget has any children, then
@@ -1115,33 +1028,18 @@ static void sendResizeEvents(QWidget *target)
\sa grabWindow()
*/
-QPixmap QPixmap::grabWidget(QWidget * widget, const QRect &rect)
+QPixmap QPixmap::grabWidget(QObject *widget, const QRect &rectangle)
{
+ QPixmap pixmap;
+ // ### Qt5: should we keep or remove this method?
+ // SC solution would be to install a callback form QtWidgets, but ugly.
+ qWarning("QPixmap::grabWidget is deprecated, use QWidget::grab() instead");
if (!widget)
- return QPixmap();
-
- if (widget->testAttribute(Qt::WA_PendingResizeEvent) || !widget->testAttribute(Qt::WA_WState_Created))
- sendResizeEvents(widget);
-
- widget->d_func()->prepareToRender(QRegion(),
- QWidget::DrawWindowBackground | QWidget::DrawChildren | QWidget::IgnoreMask);
-
- QRect r(rect);
- if (r.width() < 0)
- r.setWidth(widget->width() - rect.x());
- if (r.height() < 0)
- r.setHeight(widget->height() - rect.y());
-
- if (!r.intersects(widget->rect()))
- return QPixmap();
-
- QPixmap res(r.size());
- if (!qt_widget_private(widget)->isOpaque)
- res.fill(Qt::transparent);
-
- widget->d_func()->render(&res, QPoint(), r, QWidget::DrawWindowBackground
- | QWidget::DrawChildren | QWidget::IgnoreMask, true);
- return res;
+ return pixmap;
+ QMetaObject::invokeMethod(widget, "grab", Qt::DirectConnection,
+ Q_RETURN_ARG(QPixmap, pixmap),
+ Q_ARG(QRect, rectangle));
+ return pixmap;
}
/*!
@@ -1200,137 +1098,6 @@ QPixmap QPixmap::grabWidget(QWidget * widget, const QRect &rect)
*/
-#if defined(Q_WS_X11) || defined(Q_WS_QWS)
-
-/*!
- Returns the pixmap's handle to the device context.
-
- Note that, since QPixmap make use of \l {Implicit Data
- Sharing}{implicit data sharing}, the detach() function must be
- called explicitly to ensure that only \e this pixmap's data is
- modified if the pixmap data is shared.
-
- \warning This function is X11 specific; using it is non-portable.
-
- \warning Since 4.8, pixmaps do not have an X11 handle unless
- created with \l {QPixmap::}{fromX11Pixmap()}, or if the native
- graphics system is explicitly enabled.
-
- \sa detach()
- \sa QApplication::setGraphicsSystem()
-*/
-
-Qt::HANDLE QPixmap::handle() const
-{
-#if defined(Q_WS_X11)
- const QPixmapData *pd = pixmapData();
- if (pd && pd->classId() == QPixmapData::X11Class)
- return static_cast<const QX11PixmapData*>(pd)->handle();
-#endif
- return 0;
-}
-#endif
-
-
-#ifdef QT3_SUPPORT
-static Qt::ImageConversionFlags colorModeToFlags(QPixmap::ColorMode mode)
-{
- Qt::ImageConversionFlags flags = Qt::AutoColor;
- switch (mode) {
- case QPixmap::Color:
- flags |= Qt::ColorOnly;
- break;
- case QPixmap::Mono:
- flags |= Qt::MonoOnly;
- break;
- default:
- break;// Nothing.
- }
- return flags;
-}
-
-/*!
- Use the constructor that takes a Qt::ImageConversionFlag instead.
-*/
-
-QPixmap::QPixmap(const QString& fileName, const char *format, ColorMode mode)
- : QPaintDevice()
-{
- init(0, 0, QPixmapData::PixmapType);
- if (!qt_pixmap_thread_test())
- return;
-
- load(fileName, format, colorModeToFlags(mode));
-}
-
-/*!
- Constructs a pixmap from the QImage \a image.
-
- Use the static fromImage() function instead.
-*/
-QPixmap::QPixmap(const QImage& image)
- : QPaintDevice()
-{
- init(0, 0, QPixmapData::PixmapType);
- if (!qt_pixmap_thread_test())
- return;
-
- if (data && data->pixelType() == QPixmapData::BitmapType)
- *this = QBitmap::fromImage(image);
- else
- *this = fromImage(image);
-}
-
-/*!
- \overload
-
- Converts the given \a image to a pixmap that is assigned to this
- pixmap.
-
- Use the static fromImage() function instead.
-*/
-
-QPixmap &QPixmap::operator=(const QImage &image)
-{
- if (data && data->pixelType() == QPixmapData::BitmapType)
- *this = QBitmap::fromImage(image);
- else
- *this = fromImage(image);
- return *this;
-}
-
-/*!
- Use the load() function that takes a Qt::ImageConversionFlag instead.
-*/
-
-bool QPixmap::load(const QString &fileName, const char *format, ColorMode mode)
-{
- return load(fileName, format, colorModeToFlags(mode));
-}
-
-/*!
- Use the loadFromData() function that takes a Qt::ImageConversionFlag instead.
-*/
-
-bool QPixmap::loadFromData(const uchar *buf, uint len, const char *format, ColorMode mode)
-{
- return loadFromData(buf, len, format, colorModeToFlags(mode));
-}
-
-/*!
- Use the static fromImage() function instead.
-*/
-bool QPixmap::convertFromImage(const QImage &image, ColorMode mode)
-{
- if (data && data->pixelType() == QPixmapData::BitmapType)
- *this = QBitmap::fromImage(image, colorModeToFlags(mode));
- else
- *this = fromImage(image, colorModeToFlags(mode));
- return !isNull();
-}
-
-#endif
-
/*****************************************************************************
QPixmap stream functions
*****************************************************************************/
@@ -1375,34 +1142,6 @@ QDataStream &operator>>(QDataStream &stream, QPixmap &pixmap)
#endif // QT_NO_DATASTREAM
-#ifdef QT3_SUPPORT
-Q_GUI_EXPORT void copyBlt(QPixmap *dst, int dx, int dy,
- const QPixmap *src, int sx, int sy, int sw, int sh)
-{
- Q_ASSERT_X(dst, "::copyBlt", "Destination pixmap must be non-null");
- Q_ASSERT_X(src, "::copyBlt", "Source pixmap must be non-null");
-
- if (src->hasAlphaChannel()) {
- if (dst->paintEngine()->hasFeature(QPaintEngine::PorterDuff)) {
- QPainter p(dst);
- p.setCompositionMode(QPainter::CompositionMode_Source);
- p.drawPixmap(dx, dy, *src, sx, sy, sw, sh);
- } else {
- QImage image = dst->toImage().convertToFormat(QImage::Format_ARGB32_Premultiplied);
- QPainter p(&image);
- p.setCompositionMode(QPainter::CompositionMode_Source);
- p.drawPixmap(dx, dy, *src, sx, sy, sw, sh);
- p.end();
- *dst = QPixmap::fromImage(image);
- }
- } else {
- QPainter p(dst);
- p.drawPixmap(dx, dy, *src, sx, sy, sw, sh);
- }
-
-}
-#endif
-
/*!
\internal
*/
@@ -1832,23 +1571,7 @@ QPixmap QPixmap::transformed(const QMatrix &matrix, Qt::TransformationMode mode)
*/
bool QPixmap::hasAlpha() const
{
-#if defined(Q_WS_X11)
- if (data && data->hasAlphaChannel())
- return true;
- QPixmapData *pd = pixmapData();
- if (pd && pd->classId() == QPixmapData::X11Class) {
- QX11PixmapData *x11Data = static_cast<QX11PixmapData*>(pd);
-#ifndef QT_NO_XRENDER
- if (x11Data->picture && x11Data->d == 32)
- return true;
-#endif
- if (x11Data->d == 1 || x11Data->x11_mask)
- return true;
- }
- return false;
-#else
return data && data->hasAlphaChannel();
-#endif
}
/*!
@@ -1871,78 +1594,6 @@ int QPixmap::metric(PaintDeviceMetric metric) const
}
/*!
- \fn void QPixmap::setAlphaChannel(const QPixmap &alphaChannel)
- \obsolete
-
- Sets the alpha channel of this pixmap to the given \a alphaChannel
- by converting the \a alphaChannel into 32 bit and using the
- intensity of the RGB pixel values.
-
- 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}
- */
-void QPixmap::setAlphaChannel(const QPixmap &alphaChannel)
-{
- if (alphaChannel.isNull())
- return;
-
- if (paintingActive()) {
- qWarning("QPixmap::setAlphaChannel: "
- "Cannot set alpha channel while pixmap is being painted on");
- return;
- }
-
- if (width() != alphaChannel.width() && height() != alphaChannel.height()) {
- qWarning("QPixmap::setAlphaChannel: "
- "The pixmap and the alpha channel pixmap must have the same size");
- return;
- }
-
- detach();
- data->setAlphaChannel(alphaChannel);
-}
-
-/*!
- \obsolete
-
- Returns the alpha channel of the pixmap as a new grayscale QPixmap in which
- each pixel's red, green, and blue values are given the alpha value of the
- original pixmap. The color depth of the returned pixmap is the system depth
- on X11 and 8-bit on Windows and Mac OS X.
-
- You can use this function while debugging
- to get a visible image of the alpha channel. If the pixmap doesn't have an
- alpha channel, i.e., the alpha channel's value for all pixels equals
- 0xff), a null pixmap is returned. You can check this with the \c isNull()
- function.
-
- We show an example:
-
- \snippet doc/src/snippets/alphachannel.cpp 0
-
- \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. Most usecases of this
- function are covered by QPainter and compositionModes which will normally
- execute faster.
-
- \sa setAlphaChannel(), {QPixmap#Pixmap Information}{Pixmap
- Information}
-*/
-QPixmap QPixmap::alphaChannel() const
-{
- return data ? data->alphaChannel() : QPixmap();
-}
-
-/*!
\internal
*/
QPaintEngine *QPixmap::paintEngine() const
@@ -1962,7 +1613,36 @@ QPaintEngine *QPixmap::paintEngine() const
*/
QBitmap QPixmap::mask() const
{
- return data ? data->mask() : QBitmap();
+ if (!data || !hasAlphaChannel())
+ return QBitmap();
+
+ const QImage img = toImage();
+ const QImage image = (img.depth() < 32 ? img.convertToFormat(QImage::Format_ARGB32_Premultiplied) : img);
+ const int w = image.width();
+ const int h = image.height();
+
+ QImage mask(w, h, QImage::Format_MonoLSB);
+ if (mask.isNull()) // allocation failed
+ return QBitmap();
+
+ mask.setColorCount(2);
+ mask.setColor(0, QColor(Qt::color0).rgba());
+ mask.setColor(1, QColor(Qt::color1).rgba());
+
+ const int bpl = mask.bytesPerLine();
+
+ for (int y = 0; y < h; ++y) {
+ const QRgb *src = reinterpret_cast<const QRgb*>(image.scanLine(y));
+ uchar *dest = mask.scanLine(y);
+ memset(dest, 0, bpl);
+ for (int x = 0; x < w; ++x) {
+ if (qAlpha(*src) > 0)
+ dest[x >> 3] |= (1 << (x & 7));
+ ++src;
+ }
+ }
+
+ return QBitmap::fromImage(mask);
}
/*!
@@ -1977,21 +1657,7 @@ QBitmap QPixmap::mask() const
*/
int QPixmap::defaultDepth()
{
-#if defined(Q_WS_QWS)
- return QScreen::instance()->depth();
-#elif defined(Q_WS_X11)
- return QX11Info::appDepth();
-#elif defined(Q_WS_WINCE)
- return QColormap::instance().depth();
-#elif defined(Q_WS_WIN)
- return 32; // XXX
-#elif defined(Q_WS_MAC)
- return 32;
-#elif defined(Q_OS_SYMBIAN)
- return S60->screenDepth;
-#elif defined(Q_WS_QPA)
- return 32; //LITE: use graphicssystem (we should do that in general)
-#endif
+ return 32; // LITE: ### use QPlatformScreen (we should do that in general)
}
/*!
@@ -2016,50 +1682,22 @@ void QPixmap::detach()
if (!data)
return;
- // QPixmap.data member may be QRuntimePixmapData so use pixmapData() function to get
+ // QPixmap.data member may be QRuntimePlatformPixmap so use handle() function to get
// the actual underlaying runtime pixmap data.
- QPixmapData *pd = pixmapData();
- QPixmapData::ClassId id = pd->classId();
- if (id == QPixmapData::RasterClass) {
- QRasterPixmapData *rasterData = static_cast<QRasterPixmapData*>(pd);
+ QPlatformPixmap *pd = handle();
+ QPlatformPixmap::ClassId id = pd->classId();
+ if (id == QPlatformPixmap::RasterClass) {
+ QRasterPlatformPixmap *rasterData = static_cast<QRasterPlatformPixmap*>(pd);
rasterData->image.detach();
}
if (data->is_cached && data->ref == 1)
- QImagePixmapCleanupHooks::executePixmapDataModificationHooks(data.data());
-
-#if defined(Q_WS_MAC)
- QMacPixmapData *macData = id == QPixmapData::MacClass ? static_cast<QMacPixmapData*>(pd) : 0;
- if (macData) {
- if (macData->cg_mask) {
- CGImageRelease(macData->cg_mask);
- macData->cg_mask = 0;
- }
- }
-#endif
+ QImagePixmapCleanupHooks::executePlatformPixmapModificationHooks(data.data());
if (data->ref != 1) {
*this = copy();
}
++data->detach_no;
-
-#if defined(Q_WS_X11)
- if (pd->classId() == QPixmapData::X11Class) {
- QX11PixmapData *d = static_cast<QX11PixmapData*>(pd);
- d->flags &= ~QX11PixmapData::Uninitialized;
-
- // reset the cache data
- if (d->hd2) {
- XFreePixmap(X11->display, d->hd2);
- d->hd2 = 0;
- }
- }
-#elif defined(Q_WS_MAC)
- if (macData) {
- macData->macReleaseCGImageRef();
- macData->uninit = false;
- }
-#endif
}
/*!
@@ -2082,9 +1720,7 @@ QPixmap QPixmap::fromImage(const QImage &image, Qt::ImageConversionFlags flags)
if (image.isNull())
return QPixmap();
- QGraphicsSystem* gs = QApplicationPrivate::graphicsSystem();
- QScopedPointer<QPixmapData> data(gs ? gs->createPixmapData(QPixmapData::PixmapType)
- : QGraphicsSystem::createDefaultPixmapData(QPixmapData::PixmapType));
+ QScopedPointer<QPlatformPixmap> data(QGuiApplicationPrivate::platformIntegration()->createPlatformPixmap(QPlatformPixmap::PixmapType));
data->fromImage(image, flags);
return QPixmap(data.take());
}
@@ -2103,9 +1739,7 @@ QPixmap QPixmap::fromImage(const QImage &image, Qt::ImageConversionFlags flags)
*/
QPixmap QPixmap::fromImageReader(QImageReader *imageReader, Qt::ImageConversionFlags flags)
{
- QGraphicsSystem *gs = QApplicationPrivate::graphicsSystem();
- QScopedPointer<QPixmapData> data(gs ? gs->createPixmapData(QPixmapData::PixmapType)
- : QGraphicsSystem::createDefaultPixmapData(QPixmapData::PixmapType));
+ QScopedPointer<QPlatformPixmap> data(QGuiApplicationPrivate::platformIntegration()->createPlatformPixmap(QPlatformPixmap::PixmapType));
data->fromImageReader(imageReader, flags);
return QPixmap(data.take());
}
@@ -2154,14 +1788,9 @@ QPixmap QPixmap::fromImageReader(QImageReader *imageReader, Qt::ImageConversionF
/*!
\internal
*/
-QPixmapData* QPixmap::pixmapData() const
+QPlatformPixmap* QPixmap::handle() const
{
- if (data) {
- QPixmapData* pm = data.data();
- return pm->runtimeData() ? pm->runtimeData() : pm;
- }
-
- return 0;
+ return data.data();
}
diff --git a/src/gui/image/qpixmap.h b/src/gui/image/qpixmap.h
index 3012080abb..5d300d1f76 100644
--- a/src/gui/image/qpixmap.h
+++ b/src/gui/image/qpixmap.h
@@ -52,11 +52,6 @@
QT_BEGIN_HEADER
-#if defined(Q_OS_SYMBIAN)
-class CFbsBitmap;
-class RSgImage;
-#endif
-
QT_BEGIN_NAMESPACE
QT_MODULE(Gui)
@@ -66,13 +61,13 @@ class QImageReader;
class QColor;
class QVariant;
class QX11Info;
-class QPixmapData;
+class QPlatformPixmap;
class Q_GUI_EXPORT QPixmap : public QPaintDevice
{
public:
QPixmap();
- explicit QPixmap(QPixmapData *data);
+ explicit QPixmap(QPlatformPixmap *data);
QPixmap(int w, int h);
QPixmap(const QSize &);
QPixmap(const QString& fileName, const char *format = 0, Qt::ImageConversionFlags flags = Qt::AutoColor);
@@ -103,32 +98,25 @@ public:
static int defaultDepth();
void fill(const QColor &fillColor = Qt::white);
- void fill(const QWidget *widget, const QPoint &ofs);
- inline void fill(const QWidget *widget, int xofs, int yofs) { fill(widget, QPoint(xofs, yofs)); }
+ void fill(const QPaintDevice *device, const QPoint &ofs);
+ inline void fill(const QPaintDevice *device, int xofs, int yofs) { fill(device, QPoint(xofs, yofs)); }
QBitmap mask() const;
void setMask(const QBitmap &);
-#ifdef QT_DEPRECATED
- QT_DEPRECATED QPixmap alphaChannel() const;
- QT_DEPRECATED void setAlphaChannel(const QPixmap &);
-#endif
-
bool hasAlpha() const;
bool hasAlphaChannel() const;
#ifndef QT_NO_IMAGE_HEURISTIC_MASK
QBitmap createHeuristicMask(bool clipTight = true) const;
#endif
- QBitmap createMaskFromColor(const QColor &maskColor) const; // ### Qt 5: remove
- QBitmap createMaskFromColor(const QColor &maskColor, Qt::MaskMode mode) const;
+ QBitmap createMaskFromColor(const QColor &maskColor, Qt::MaskMode mode = Qt::MaskInColor) const;
static QPixmap grabWindow(WId, int x=0, int y=0, int w=-1, int h=-1);
- static QPixmap grabWidget(QWidget *widget, const QRect &rect);
- static inline QPixmap grabWidget(QWidget *widget, int x=0, int y=0, int w=-1, int h=-1)
+ static QPixmap grabWidget(QObject *widget, const QRect &rect);
+ static inline QPixmap grabWidget(QObject *widget, int x=0, int y=0, int w=-1, int h=-1)
{ return grabWidget(widget, QRect(x, y, w, h)); }
-
inline QPixmap scaled(int w, int h, Qt::AspectRatioMode aspectMode = Qt::IgnoreAspectRatio,
Qt::TransformationMode mode = Qt::FastTransformation) const
{ return scaled(QSize(w, h), aspectMode, mode); }
@@ -153,32 +141,6 @@ public:
bool convertFromImage(const QImage &img, Qt::ImageConversionFlags flags = Qt::AutoColor);
-#if defined(Q_WS_WIN)
- enum HBitmapFormat {
- NoAlpha,
- PremultipliedAlpha,
- Alpha
- };
-
- HBITMAP toWinHBITMAP(HBitmapFormat format = NoAlpha) const;
- HICON toWinHICON() const;
-
- static QPixmap fromWinHBITMAP(HBITMAP hbitmap, HBitmapFormat format = NoAlpha);
- static QPixmap fromWinHICON(HICON hicon);
-#endif
-
-#if defined(Q_WS_MAC)
- CGImageRef toMacCGImageRef() const;
- static QPixmap fromMacCGImageRef(CGImageRef image);
-#endif
-
-#if defined(Q_OS_SYMBIAN)
- CFbsBitmap *toSymbianCFbsBitmap() const;
- static QPixmap fromSymbianCFbsBitmap(CFbsBitmap *bitmap);
- RSgImage* toSymbianRSgImage() const;
- static QPixmap fromSymbianRSgImage(RSgImage *sgImage);
-#endif
-
inline QPixmap copy(int x, int y, int width, int height) const;
QPixmap copy(const QRect &rect = QRect()) const;
@@ -195,105 +157,43 @@ public:
bool isQBitmap() const;
-#if defined(Q_WS_QWS)
- const uchar *qwsBits() const;
- int qwsBytesPerLine() const;
- QRgb *clut() const;
-#ifdef QT_DEPRECATED
- QT_DEPRECATED int numCols() const;
-#endif
- int colorCount() const;
-#elif defined(Q_WS_MAC)
- Qt::HANDLE macQDHandle() const;
- Qt::HANDLE macQDAlphaHandle() const;
- Qt::HANDLE macCGHandle() const;
-#elif defined(Q_WS_X11)
- enum ShareMode { ImplicitlyShared, ExplicitlyShared };
-
- static QPixmap fromX11Pixmap(Qt::HANDLE pixmap, ShareMode mode = ImplicitlyShared);
- static int x11SetDefaultScreen(int screen);
- void x11SetScreen(int screen);
- const QX11Info &x11Info() const;
- Qt::HANDLE x11PictureHandle() const;
-#endif
-
-#if defined(Q_WS_X11) || defined(Q_WS_QWS)
- Qt::HANDLE handle() const;
-#endif
-
QPaintEngine *paintEngine() const;
inline bool operator!() const { return isNull(); }
+#if QT_DEPRECATED_SINCE(5, 0)
+ QT_DEPRECATED inline QPixmap alphaChannel() const;
+ QT_DEPRECATED inline void setAlphaChannel(const QPixmap &);
+#endif
+
protected:
int metric(PaintDeviceMetric) const;
-#ifdef QT3_SUPPORT
-public:
- enum ColorMode { Auto, Color, Mono };
- QT3_SUPPORT_CONSTRUCTOR QPixmap(const QString& fileName, const char *format, ColorMode mode);
- QT3_SUPPORT bool load(const QString& fileName, const char *format, ColorMode mode);
- QT3_SUPPORT bool loadFromData(const uchar *buf, uint len, const char* format, ColorMode mode);
- QT3_SUPPORT_CONSTRUCTOR QPixmap(const QImage& image);
- QT3_SUPPORT QPixmap &operator=(const QImage &);
- inline QT3_SUPPORT QImage convertToImage() const { return toImage(); }
- QT3_SUPPORT bool convertFromImage(const QImage &, ColorMode mode);
- inline QT3_SUPPORT operator QImage() const { return toImage(); }
- inline QT3_SUPPORT QPixmap xForm(const QMatrix &matrix) const { return transformed(QTransform(matrix)); }
- inline QT3_SUPPORT bool selfMask() const { return false; }
-private:
- void resize_helper(const QSize &s);
-public:
- inline QT3_SUPPORT void resize(const QSize &s) { resize_helper(s); }
- inline QT3_SUPPORT void resize(int width, int height) { resize_helper(QSize(width, height)); }
-#endif
-
private:
- QExplicitlySharedDataPointer<QPixmapData> data;
+ QExplicitlySharedDataPointer<QPlatformPixmap> data;
bool doImageIO(QImageWriter *io, int quality) const;
- // ### Qt5: remove the following three lines
- enum Type { PixmapType, BitmapType }; // must match QPixmapData::PixelType
- QPixmap(const QSize &s, Type);
- void init(int, int, Type = PixmapType);
-
QPixmap(const QSize &s, int type);
- void init(int, int, int);
+ void doInit(int, int, int);
void deref();
-#if defined(Q_WS_WIN)
- void initAlphaPixmap(uchar *bytes, int length, struct tagBITMAPINFO *bmi);
-#endif
Q_DUMMY_COMPARISON_OPERATOR(QPixmap)
-#ifdef Q_WS_MAC
- friend CGContextRef qt_mac_cg_context(const QPaintDevice*);
- friend CGImageRef qt_mac_create_imagemask(const QPixmap&, const QRectF&);
- friend IconRef qt_mac_create_iconref(const QPixmap&);
- friend quint32 *qt_mac_pixmap_get_base(const QPixmap*);
- friend int qt_mac_pixmap_get_bytes_per_line(const QPixmap*);
-#endif
- friend class QPixmapData;
- friend class QX11PixmapData;
- friend class QMacPixmapData;
- friend class QS60PixmapData;
+ friend class QPlatformPixmap;
friend class QBitmap;
friend class QPaintDevice;
friend class QPainter;
- friend class QGLWidget;
- friend class QX11PaintEngine;
- friend class QCoreGraphicsPaintEngine;
+ friend class QOpenGLWidget;
friend class QWidgetPrivate;
friend class QRasterBuffer;
#if !defined(QT_NO_DATASTREAM)
friend Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QPixmap &);
#endif
- friend Q_GUI_EXPORT qint64 qt_pixmap_id(const QPixmap &pixmap);
public:
- QPixmapData* pixmapData() const;
+ QPlatformPixmap* handle() const;
public:
- typedef QExplicitlySharedDataPointer<QPixmapData> DataPtr;
+ typedef QExplicitlySharedDataPointer<QPlatformPixmap> DataPtr;
inline DataPtr &data_ptr() { return data; }
};
@@ -315,6 +215,22 @@ inline bool QPixmap::loadFromData(const QByteArray &buf, const char *format,
return loadFromData(reinterpret_cast<const uchar *>(buf.constData()), buf.size(), format, flags);
}
+#if QT_DEPRECATED_SINCE(5, 0)
+inline QPixmap QPixmap::alphaChannel() const
+{
+ return toImage().alphaChannel();
+}
+
+inline void QPixmap::setAlphaChannel(const QPixmap &p)
+{
+ detach();
+ QImage image = data->toImage();
+ image.setAlphaChannel(p.toImage());
+ data->fromImage(image);
+
+}
+#endif
+
/*****************************************************************************
QPixmap stream functions
*****************************************************************************/
@@ -324,14 +240,6 @@ Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QPixmap &);
Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QPixmap &);
#endif
-/*****************************************************************************
- QPixmap (and QImage) helper functions
-*****************************************************************************/
-#ifdef QT3_SUPPORT
-QT3_SUPPORT Q_GUI_EXPORT void copyBlt(QPixmap *dst, int dx, int dy, const QPixmap *src,
- int sx=0, int sy=0, int sw=-1, int sh=-1);
-#endif // QT3_SUPPORT
-
QT_END_NAMESPACE
QT_END_HEADER
diff --git a/src/gui/image/qpixmap_blitter.cpp b/src/gui/image/qpixmap_blitter.cpp
index f3a4318032..dc0f03abdc 100644
--- a/src/gui/image/qpixmap_blitter.cpp
+++ b/src/gui/image/qpixmap_blitter.cpp
@@ -43,9 +43,9 @@
#include <qpainter.h>
#include <qimage.h>
+#include <qscreen.h>
-#include <private/qapplication_p.h>
-#include <private/qgraphicssystem_p.h>
+#include <private/qguiapplication_p.h>
#include <private/qblittable_p.h>
#include <private/qdrawhelper_p.h>
@@ -56,8 +56,8 @@ QT_BEGIN_NAMESPACE
static int global_ser_no = 0;
-QBlittablePixmapData::QBlittablePixmapData()
- : QPixmapData(QPixmapData::PixmapType,BlitterClass), m_engine(0), m_blittable(0)
+QBlittablePlatformPixmap::QBlittablePlatformPixmap()
+ : QPlatformPixmap(QPlatformPixmap::PixmapType,BlitterClass), m_engine(0), m_blittable(0)
#ifdef QT_BLITTER_RASTEROVERLAY
,m_rasterOverlay(0), m_unmergedCopy(0)
#endif //QT_BLITTER_RASTEROVERLAY
@@ -65,7 +65,7 @@ QBlittablePixmapData::QBlittablePixmapData()
setSerialNumber(++global_ser_no);
}
-QBlittablePixmapData::~QBlittablePixmapData()
+QBlittablePlatformPixmap::~QBlittablePlatformPixmap()
{
delete m_blittable;
delete m_engine;
@@ -75,23 +75,23 @@ QBlittablePixmapData::~QBlittablePixmapData()
#endif //QT_BLITTER_RASTEROVERLAY
}
-QBlittable *QBlittablePixmapData::blittable() const
+QBlittable *QBlittablePlatformPixmap::blittable() const
{
if (!m_blittable) {
- QBlittablePixmapData *that = const_cast<QBlittablePixmapData *>(this);
+ QBlittablePlatformPixmap *that = const_cast<QBlittablePlatformPixmap *>(this);
that->m_blittable = this->createBlittable(QSize(w,h));
}
return m_blittable;
}
-void QBlittablePixmapData::setBlittable(QBlittable *blittable)
+void QBlittablePlatformPixmap::setBlittable(QBlittable *blittable)
{
resize(blittable->size().width(),blittable->size().height());
m_blittable = blittable;
}
-void QBlittablePixmapData::resize(int width, int height)
+void QBlittablePlatformPixmap::resize(int width, int height)
{
delete m_blittable;
@@ -99,14 +99,14 @@ void QBlittablePixmapData::resize(int width, int height)
delete m_engine;
m_engine = 0;
#ifdef Q_WS_QPA
- d = QApplicationPrivate::platformIntegration()->screens().at(0)->depth();
+ d = QGuiApplication::primaryScreen()->depth();
#endif
w = width;
h = height;
is_null = (w <= 0 || h <= 0);
}
-int QBlittablePixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const
+int QBlittablePlatformPixmap::metric(QPaintDevice::PaintDeviceMetric metric) const
{
switch (metric) {
case QPaintDevice::PdmWidth:
@@ -126,14 +126,14 @@ int QBlittablePixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const
case QPaintDevice::PdmPhysicalDpiY:
return qt_defaultDpiY();
default:
- qWarning("QRasterPixmapData::metric(): Unhandled metric type %d", metric);
+ qWarning("QRasterPlatformPixmap::metric(): Unhandled metric type %d", metric);
break;
}
return 0;
}
-void QBlittablePixmapData::fill(const QColor &color)
+void QBlittablePlatformPixmap::fill(const QColor &color)
{
//jlind: todo: change when blittables can support non opaque fillRects
if (color.alpha() == 255 && blittable()->capabilities() & QBlittable::SolidRectCapability) {
@@ -167,22 +167,22 @@ void QBlittablePixmapData::fill(const QColor &color)
}
-QImage *QBlittablePixmapData::buffer()
+QImage *QBlittablePlatformPixmap::buffer()
{
return blittable()->lock();
}
-QImage QBlittablePixmapData::toImage() const
+QImage QBlittablePlatformPixmap::toImage() const
{
return blittable()->lock()->copy();
}
-bool QBlittablePixmapData::hasAlphaChannel() const
+bool QBlittablePlatformPixmap::hasAlphaChannel() const
{
return blittable()->lock()->hasAlphaChannel();
}
-void QBlittablePixmapData::fromImage(const QImage &image,
+void QBlittablePlatformPixmap::fromImage(const QImage &image,
Qt::ImageConversionFlags flags)
{
resize(image.width(),image.height());
@@ -204,10 +204,10 @@ void QBlittablePixmapData::fromImage(const QImage &image,
}
}
-QPaintEngine *QBlittablePixmapData::paintEngine() const
+QPaintEngine *QBlittablePlatformPixmap::paintEngine() const
{
if (!m_engine) {
- QBlittablePixmapData *that = const_cast<QBlittablePixmapData *>(this);
+ QBlittablePlatformPixmap *that = const_cast<QBlittablePlatformPixmap *>(this);
that->m_engine = new QBlitterPaintEngine(that);
}
return m_engine;
@@ -217,7 +217,7 @@ QPaintEngine *QBlittablePixmapData::paintEngine() const
static bool showRasterOverlay = !qgetenv("QT_BLITTER_RASTEROVERLAY").isEmpty();
-void QBlittablePixmapData::mergeOverlay()
+void QBlittablePlatformPixmap::mergeOverlay()
{
if (m_unmergedCopy || !showRasterOverlay)
return;
@@ -228,7 +228,7 @@ void QBlittablePixmapData::mergeOverlay()
p.end();
}
-void QBlittablePixmapData::unmergeOverlay()
+void QBlittablePlatformPixmap::unmergeOverlay()
{
if (!m_unmergedCopy || !showRasterOverlay)
return;
@@ -241,7 +241,7 @@ void QBlittablePixmapData::unmergeOverlay()
m_unmergedCopy = 0;
}
-QImage *QBlittablePixmapData::overlay()
+QImage *QBlittablePlatformPixmap::overlay()
{
if (!m_rasterOverlay||
m_rasterOverlay->size() != QSize(w,h)){
@@ -255,7 +255,7 @@ QImage *QBlittablePixmapData::overlay()
return m_rasterOverlay;
}
-void QBlittablePixmapData::markRasterOverlayImpl(const QRectF &rect)
+void QBlittablePlatformPixmap::markRasterOverlayImpl(const QRectF &rect)
{
if (!showRasterOverlay)
return;
@@ -268,7 +268,7 @@ void QBlittablePixmapData::markRasterOverlayImpl(const QRectF &rect)
}
}
-void QBlittablePixmapData::unmarkRasterOverlayImpl(const QRectF &rect)
+void QBlittablePlatformPixmap::unmarkRasterOverlayImpl(const QRectF &rect)
{
if (!showRasterOverlay)
return;
@@ -282,7 +282,7 @@ void QBlittablePixmapData::unmarkRasterOverlayImpl(const QRectF &rect)
}
}
-QRectF QBlittablePixmapData::clipAndTransformRect(const QRectF &rect) const
+QRectF QBlittablePlatformPixmap::clipAndTransformRect(const QRectF &rect) const
{
QRectF transformationRect = rect;
paintEngine();
diff --git a/src/gui/image/qpixmap_blitter_p.h b/src/gui/image/qpixmap_blitter_p.h
index 07791e548b..3ab5cb3da3 100644
--- a/src/gui/image/qpixmap_blitter_p.h
+++ b/src/gui/image/qpixmap_blitter_p.h
@@ -42,18 +42,18 @@
#ifndef QPIXMAP_BLITTER_P_H
#define QPIXMAP_BLITTER_P_H
-#include <private/qpixmapdata_p.h>
+#include <qplatformpixmap_qpa.h>
#include <private/qpaintengine_blitter_p.h>
#ifndef QT_NO_BLITTABLE
QT_BEGIN_NAMESPACE
-class Q_GUI_EXPORT QBlittablePixmapData : public QPixmapData
+class Q_GUI_EXPORT QBlittablePlatformPixmap : public QPlatformPixmap
{
-// Q_DECLARE_PRIVATE(QBlittablePixmapData);
+// Q_DECLARE_PRIVATE(QBlittablePlatformPixmap);
public:
- QBlittablePixmapData();
- ~QBlittablePixmapData();
+ QBlittablePlatformPixmap();
+ ~QBlittablePlatformPixmap();
virtual QBlittable *createBlittable(const QSize &size) const = 0;
QBlittable *blittable() const;
@@ -98,7 +98,7 @@ protected:
};
-inline void QBlittablePixmapData::markRasterOverlay(const QRectF &rect)
+inline void QBlittablePlatformPixmap::markRasterOverlay(const QRectF &rect)
{
#ifdef QT_BLITTER_RASTEROVERLAY
markRasterOverlayImpl(rect);
@@ -107,7 +107,7 @@ inline void QBlittablePixmapData::markRasterOverlay(const QRectF &rect)
#endif
}
-inline void QBlittablePixmapData::markRasterOverlay(const QVectorPath &path)
+inline void QBlittablePlatformPixmap::markRasterOverlay(const QVectorPath &path)
{
#ifdef QT_BLITTER_RASTEROVERLAY
markRasterOverlayImpl(path.convertToPainterPath().boundingRect());
@@ -116,7 +116,7 @@ inline void QBlittablePixmapData::markRasterOverlay(const QVectorPath &path)
#endif
}
-inline void QBlittablePixmapData::markRasterOverlay(const QPointF &pos, const QTextItem &ti)
+inline void QBlittablePlatformPixmap::markRasterOverlay(const QPointF &pos, const QTextItem &ti)
{
#ifdef QT_BLITTER_RASTEROVERLAY
QFontMetricsF fm(ti.font());
@@ -129,7 +129,7 @@ inline void QBlittablePixmapData::markRasterOverlay(const QPointF &pos, const QT
#endif
}
-inline void QBlittablePixmapData::markRasterOverlay(const QRect *rects, int rectCount)
+inline void QBlittablePlatformPixmap::markRasterOverlay(const QRect *rects, int rectCount)
{
#ifdef QT_BLITTER_RASTEROVERLAY
for (int i = 0; i < rectCount; i++) {
@@ -140,7 +140,7 @@ inline void QBlittablePixmapData::markRasterOverlay(const QRect *rects, int rect
Q_UNUSED(rectCount)
#endif
}
-inline void QBlittablePixmapData::markRasterOverlay(const QRectF *rects, int rectCount)
+inline void QBlittablePlatformPixmap::markRasterOverlay(const QRectF *rects, int rectCount)
{
#ifdef QT_BLITTER_RASTEROVERLAY
for (int i = 0; i < rectCount; i++) {
@@ -152,7 +152,7 @@ inline void QBlittablePixmapData::markRasterOverlay(const QRectF *rects, int rec
#endif
}
-inline void QBlittablePixmapData::unmarkRasterOverlay(const QRectF &rect)
+inline void QBlittablePlatformPixmap::unmarkRasterOverlay(const QRectF &rect)
{
#ifdef QT_BLITTER_RASTEROVERLAY
unmarkRasterOverlayImpl(rect);
diff --git a/src/gui/image/qpixmap_mac.cpp b/src/gui/image/qpixmap_mac.cpp
deleted file mode 100644
index 47b6eef761..0000000000
--- a/src/gui/image/qpixmap_mac.cpp
+++ /dev/null
@@ -1,1233 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qpixmap.h"
-#include "qimage.h"
-#include "qapplication.h"
-#include "qbitmap.h"
-#include "qmatrix.h"
-#include "qtransform.h"
-#include "qlibrary.h"
-#include "qvarlengtharray.h"
-#include "qdebug.h"
-#include <private/qdrawhelper_p.h>
-#include <private/qpixmap_mac_p.h>
-#include <private/qpixmap_raster_p.h>
-#include <private/qpaintengine_mac_p.h>
-#include <private/qt_mac_p.h>
-#include <private/qt_cocoa_helpers_mac_p.h>
-#include <private/qapplication_p.h>
-
-#include <limits.h>
-#include <string.h>
-
-QT_BEGIN_NAMESPACE
-
-/*****************************************************************************
- Externals
- *****************************************************************************/
-extern const uchar *qt_get_bitflip_array(); //qimage.cpp
-extern CGContextRef qt_mac_cg_context(const QPaintDevice *pdev); //qpaintdevice_mac.cpp
-extern RgnHandle qt_mac_get_rgn(); //qregion_mac.cpp
-extern void qt_mac_dispose_rgn(RgnHandle r); //qregion_mac.cpp
-extern QRegion qt_mac_convert_mac_region(RgnHandle rgn); //qregion_mac.cpp
-
-static int qt_pixmap_serial = 0;
-
-Q_GUI_EXPORT quint32 *qt_mac_pixmap_get_base(const QPixmap *pix)
-{
- if (QApplicationPrivate::graphics_system_name == QLatin1String("raster"))
- return reinterpret_cast<quint32 *>(static_cast<QRasterPixmapData*>(pix->data.data())->buffer()->bits());
- else
- return static_cast<QMacPixmapData*>(pix->data.data())->pixels;
-}
-
-Q_GUI_EXPORT int qt_mac_pixmap_get_bytes_per_line(const QPixmap *pix)
-{
- if (QApplicationPrivate::graphics_system_name == QLatin1String("raster"))
- return static_cast<QRasterPixmapData*>(pix->data.data())->buffer()->bytesPerLine();
- else
- return static_cast<QMacPixmapData*>(pix->data.data())->bytesPerRow;
-}
-
-void qt_mac_cgimage_data_free(void *info, const void *memoryToFree, size_t)
-{
- QMacPixmapData *pmdata = static_cast<QMacPixmapData *>(info);
- if (!pmdata) {
- free(const_cast<void *>(memoryToFree));
- } else {
- if (QMacPixmapData::validDataPointers.contains(pmdata) == false) {
- free(const_cast<void *>(memoryToFree));
- return;
- }
- if (pmdata->pixels == pmdata->pixelsToFree) {
- // something we aren't expecting, just free it.
- Q_ASSERT(memoryToFree != pmdata->pixelsToFree);
- free(const_cast<void *>(memoryToFree));
- } else {
- free(pmdata->pixelsToFree);
- pmdata->pixelsToFree = static_cast<quint32 *>(const_cast<void *>(memoryToFree));
- }
- pmdata->cg_dataBeingReleased = 0;
- }
-}
-
-CGImageRef qt_mac_image_to_cgimage(const QImage &image)
-{
- int bitsPerColor = 8;
- int bitsPerPixel = 32;
- if (image.depth() == 1) {
- bitsPerColor = 1;
- bitsPerPixel = 1;
- }
- QCFType<CGDataProviderRef> provider =
- CGDataProviderCreateWithData(0, image.bits(), image.bytesPerLine() * image.height(),
- 0);
-
- uint cgflags = kCGImageAlphaPremultipliedFirst;
-#ifdef kCGBitmapByteOrder32Host //only needed because CGImage.h added symbols in the minor version
- cgflags |= kCGBitmapByteOrder32Host;
-#endif
-
- CGImageRef cgImage = CGImageCreate(image.width(), image.height(), bitsPerColor, bitsPerPixel,
- image.bytesPerLine(),
- QCoreGraphicsPaintEngine::macGenericColorSpace(),
- cgflags, provider,
- 0,
- 0,
- kCGRenderingIntentDefault);
-
- return cgImage;
-}
-
-/*****************************************************************************
- QPixmap member functions
- *****************************************************************************/
-
-static inline QRgb qt_conv16ToRgb(ushort c) {
- static const int qt_rbits = (565/100);
- static const int qt_gbits = (565/10%10);
- static const int qt_bbits = (565%10);
- static const int qt_red_shift = qt_bbits+qt_gbits-(8-qt_rbits);
- static const int qt_green_shift = qt_bbits-(8-qt_gbits);
- static const int qt_neg_blue_shift = 8-qt_bbits;
- static const int qt_blue_mask = (1<<qt_bbits)-1;
- static const int qt_green_mask = (1<<(qt_gbits+qt_bbits))-((1<<qt_bbits)-1);
- static const int qt_red_mask = (1<<(qt_rbits+qt_gbits+qt_bbits))-(1<<(qt_gbits+qt_bbits));
-
- const int r=(c & qt_red_mask);
- const int g=(c & qt_green_mask);
- const int b=(c & qt_blue_mask);
- const int tr = r >> qt_red_shift;
- const int tg = g >> qt_green_shift;
- const int tb = b << qt_neg_blue_shift;
-
- return qRgb(tr,tg,tb);
-}
-
-QSet<QMacPixmapData*> QMacPixmapData::validDataPointers;
-
-QMacPixmapData::QMacPixmapData(PixelType type)
- : QPixmapData(type, MacClass), has_alpha(0), has_mask(0),
- uninit(true), pixels(0), pixelsSize(0), pixelsToFree(0),
- bytesPerRow(0), cg_data(0), cg_dataBeingReleased(0), cg_mask(0),
- pengine(0)
-{
-}
-
-QPixmapData *QMacPixmapData::createCompatiblePixmapData() const
-{
- return new QMacPixmapData(pixelType());
-}
-
-#define BEST_BYTE_ALIGNMENT 16
-#define COMPTUE_BEST_BYTES_PER_ROW(bpr) \
- (((bpr) + (BEST_BYTE_ALIGNMENT - 1)) & ~(BEST_BYTE_ALIGNMENT - 1))
-
-void QMacPixmapData::resize(int width, int height)
-{
- setSerialNumber(++qt_pixmap_serial);
-
- w = width;
- h = height;
- is_null = (w <= 0 || h <= 0);
- d = (pixelType() == BitmapType ? 1 : 32);
- bool make_null = w <= 0 || h <= 0; // create null pixmap
- if (make_null || d == 0) {
- w = 0;
- h = 0;
- is_null = true;
- d = 0;
- if (!make_null)
- qWarning("Qt: QPixmap: Invalid pixmap parameters");
- return;
- }
-
- if (w < 1 || h < 1)
- return;
-
- //create the pixels
- bytesPerRow = w * sizeof(quint32); // Minimum bytes per row.
-
- // Quartz2D likes things as a multple of 16 (for now).
- bytesPerRow = COMPTUE_BEST_BYTES_PER_ROW(bytesPerRow);
- macCreatePixels();
-}
-
-#undef COMPUTE_BEST_BYTES_PER_ROW
-
-void QMacPixmapData::fromImage(const QImage &img,
- Qt::ImageConversionFlags flags)
-{
- setSerialNumber(++qt_pixmap_serial);
-
- // the conversion code only handles format >=
- // Format_ARGB32_Premultiplied at the moment..
- if (img.format() > QImage::Format_ARGB32_Premultiplied) {
- QImage image;
- if (img.hasAlphaChannel())
- image = img.convertToFormat(QImage::Format_ARGB32_Premultiplied);
- else
- image = img.convertToFormat(QImage::Format_RGB32);
- fromImage(image, flags);
- return;
- }
-
- w = img.width();
- h = img.height();
- is_null = (w <= 0 || h <= 0);
- d = (pixelType() == BitmapType ? 1 : img.depth());
-
- QImage image = img;
- int dd = QPixmap::defaultDepth();
- bool force_mono = (dd == 1 ||
- (flags & Qt::ColorMode_Mask)==Qt::MonoOnly);
- if (force_mono) { // must be monochrome
- if (d != 1) {
- image = image.convertToFormat(QImage::Format_MonoLSB, flags); // dither
- d = 1;
- }
- } else { // can be both
- bool conv8 = false;
- if(d > 8 && dd <= 8) { // convert to 8 bit
- if ((flags & Qt::DitherMode_Mask) == Qt::AutoDither)
- flags = (flags & ~Qt::DitherMode_Mask)
- | Qt::PreferDither;
- conv8 = true;
- } else if ((flags & Qt::ColorMode_Mask) == Qt::ColorOnly) {
- conv8 = d == 1; // native depth wanted
- } else if (d == 1) {
- if (image.colorCount() == 2) {
- QRgb c0 = image.color(0); // Auto: convert to best
- QRgb c1 = image.color(1);
- conv8 = qMin(c0,c1) != qRgb(0,0,0) || qMax(c0,c1) != qRgb(255,255,255);
- } else {
- // eg. 1-color monochrome images (they do exist).
- conv8 = true;
- }
- }
- if (conv8) {
- image = image.convertToFormat(QImage::Format_Indexed8, flags);
- d = 8;
- }
- }
-
- if (image.depth()==1) {
- image.setColor(0, QColor(Qt::color0).rgba());
- image.setColor(1, QColor(Qt::color1).rgba());
- }
-
- if (d == 16 || d == 24) {
- image = image.convertToFormat(QImage::Format_RGB32, flags);
- fromImage(image, flags);
- return;
- }
-
- // different size or depth, make a new pixmap
- resize(w, h);
-
- quint32 *dptr = pixels, *drow;
- const uint dbpr = bytesPerRow;
-
- const QImage::Format sfmt = image.format();
- const unsigned short sbpr = image.bytesPerLine();
-
- // use const_cast to prevent a detach
- const uchar *sptr = const_cast<const QImage &>(image).bits(), *srow;
-
- for (int y = 0; y < h; ++y) {
- drow = dptr + (y * (dbpr / 4));
- srow = sptr + (y * sbpr);
- switch(sfmt) {
- case QImage::Format_MonoLSB:
- case QImage::Format_Mono:{
- for (int x = 0; x < w; ++x) {
- char one_bit = *(srow + (x / 8));
- if (sfmt == QImage::Format_Mono)
- one_bit = one_bit >> (7 - (x % 8));
- else
- one_bit = one_bit >> (x % 8);
- if ((one_bit & 0x01))
- *(drow+x) = 0xFF000000;
- else
- *(drow+x) = 0xFFFFFFFF;
- }
- break;
- }
- case QImage::Format_Indexed8: {
- int numColors = image.numColors();
- if (numColors > 0) {
- for (int x = 0; x < w; ++x) {
- int index = *(srow + x);
- *(drow+x) = PREMUL(image.color(qMin(index, numColors)));
- }
- }
- } break;
- case QImage::Format_RGB32:
- for (int x = 0; x < w; ++x)
- *(drow+x) = *(((quint32*)srow) + x) | 0xFF000000;
- break;
- case QImage::Format_ARGB32:
- case QImage::Format_ARGB32_Premultiplied:
- for (int x = 0; x < w; ++x) {
- if(sfmt == QImage::Format_RGB32)
- *(drow+x) = 0xFF000000 | (*(((quint32*)srow) + x) & 0x00FFFFFF);
- else if(sfmt == QImage::Format_ARGB32_Premultiplied)
- *(drow+x) = *(((quint32*)srow) + x);
- else
- *(drow+x) = PREMUL(*(((quint32*)srow) + x));
- }
- break;
- default:
- qWarning("Qt: internal: Oops: Forgot a format [%d] %s:%d", sfmt,
- __FILE__, __LINE__);
- break;
- }
- }
- if (sfmt != QImage::Format_RGB32) { //setup the alpha
- bool alphamap = image.depth() == 32;
- if (sfmt == QImage::Format_Indexed8) {
- const QVector<QRgb> rgb = image.colorTable();
- for (int i = 0, count = image.colorCount(); i < count; ++i) {
- const int alpha = qAlpha(rgb[i]);
- if (alpha != 0xff) {
- alphamap = true;
- break;
- }
- }
- }
- macSetHasAlpha(alphamap);
- }
- uninit = false;
-}
-
-int get_index(QImage * qi,QRgb mycol)
-{
- int loopc;
- for(loopc=0;loopc<qi->colorCount();loopc++) {
- if(qi->color(loopc)==mycol)
- return loopc;
- }
- qi->setColorCount(qi->colorCount()+1);
- qi->setColor(qi->colorCount(),mycol);
- return qi->colorCount();
-}
-
-QImage QMacPixmapData::toImage() const
-{
- QImage::Format format = QImage::Format_MonoLSB;
- if (d != 1) //Doesn't support index color modes
- format = (has_alpha ? QImage::Format_ARGB32_Premultiplied :
- QImage::Format_RGB32);
-
- QImage image(w, h, format);
- quint32 *sptr = pixels, *srow;
- const uint sbpr = bytesPerRow;
- if (format == QImage::Format_MonoLSB) {
- image.fill(0);
- image.setColorCount(2);
- image.setColor(0, QColor(Qt::color0).rgba());
- image.setColor(1, QColor(Qt::color1).rgba());
- for (int y = 0; y < h; ++y) {
- uchar *scanLine = image.scanLine(y);
- srow = sptr + (y * (sbpr/4));
- for (int x = 0; x < w; ++x) {
- if (!(*(srow + x) & RGB_MASK))
- scanLine[x >> 3] |= (1 << (x & 7));
- }
- }
- } else {
- for (int y = 0; y < h; ++y) {
- srow = sptr + (y * (sbpr / 4));
- memcpy(image.scanLine(y), srow, w * 4);
- }
-
- }
-
- return image;
-}
-
-void QMacPixmapData::fill(const QColor &fillColor)
-
-{
- { //we don't know what backend to use so we cannot paint here
- quint32 *dptr = pixels;
- Q_ASSERT_X(dptr, "QPixmap::fill", "No dptr");
- const quint32 colr = PREMUL(fillColor.rgba());
- const int nbytes = bytesPerRow * h;
- if (!colr) {
- memset(dptr, 0, nbytes);
- } else {
- for (uint i = 0; i < nbytes / sizeof(quint32); ++i)
- *(dptr + i) = colr;
- }
- }
-
- // If we had an alpha channel from before, don't
- // switch it off. Only go from no alpha to alpha:
- if (fillColor.alpha() != 255)
- macSetHasAlpha(true);
-}
-
-QPixmap QMacPixmapData::alphaChannel() const
-{
- if (!has_alpha)
- return QPixmap();
-
- QMacPixmapData *alpha = new QMacPixmapData(PixmapType);
- alpha->resize(w, h);
- macGetAlphaChannel(alpha, false);
- return QPixmap(alpha);
-}
-
-void QMacPixmapData::setAlphaChannel(const QPixmap &alpha)
-{
- has_mask = true;
- QMacPixmapData *alphaData = static_cast<QMacPixmapData*>(alpha.data.data());
- macSetAlphaChannel(alphaData, false);
-}
-
-QBitmap QMacPixmapData::mask() const
-{
- if (!has_mask && !has_alpha)
- return QBitmap();
-
- QMacPixmapData *mask = new QMacPixmapData(BitmapType);
- mask->resize(w, h);
- macGetAlphaChannel(mask, true);
- return QPixmap(mask);
-}
-
-void QMacPixmapData::setMask(const QBitmap &mask)
-{
- if (mask.isNull()) {
- QMacPixmapData opaque(PixmapType);
- opaque.resize(w, h);
- opaque.fill(QColor(255, 255, 255, 255));
- macSetAlphaChannel(&opaque, true);
- has_alpha = has_mask = false;
- return;
- }
-
- has_alpha = false;
- has_mask = true;
- QMacPixmapData *maskData = static_cast<QMacPixmapData*>(mask.data.data());
- macSetAlphaChannel(maskData, true);
-}
-
-int QMacPixmapData::metric(QPaintDevice::PaintDeviceMetric theMetric) const
-{
- switch (theMetric) {
- case QPaintDevice::PdmWidth:
- return w;
- case QPaintDevice::PdmHeight:
- return h;
- case QPaintDevice::PdmWidthMM:
- return qRound(metric(QPaintDevice::PdmWidth) * 25.4 / qreal(metric(QPaintDevice::PdmDpiX)));
- case QPaintDevice::PdmHeightMM:
- return qRound(metric(QPaintDevice::PdmHeight) * 25.4 / qreal(metric(QPaintDevice::PdmDpiY)));
- case QPaintDevice::PdmNumColors:
- return 1 << d;
- case QPaintDevice::PdmDpiX:
- case QPaintDevice::PdmPhysicalDpiX: {
- extern float qt_mac_defaultDpi_x(); //qpaintdevice_mac.cpp
- return int(qt_mac_defaultDpi_x());
- }
- case QPaintDevice::PdmDpiY:
- case QPaintDevice::PdmPhysicalDpiY: {
- extern float qt_mac_defaultDpi_y(); //qpaintdevice_mac.cpp
- return int(qt_mac_defaultDpi_y());
- }
- case QPaintDevice::PdmDepth:
- return d;
- default:
- qWarning("QPixmap::metric: Invalid metric command");
- }
- return 0;
-}
-
-QMacPixmapData::~QMacPixmapData()
-{
- validDataPointers.remove(this);
- if (cg_mask) {
- CGImageRelease(cg_mask);
- cg_mask = 0;
- }
-
- delete pengine; // Make sure we aren't drawing on the context anymore.
- if (cg_data) {
- CGImageRelease(cg_data);
- } else if (!cg_dataBeingReleased && pixels != pixelsToFree) {
- free(pixels);
- }
- free(pixelsToFree);
-}
-
-void QMacPixmapData::macSetAlphaChannel(const QMacPixmapData *pix, bool asMask)
-{
- if (!pixels || !h || !w || pix->w != w || pix->h != h)
- return;
-
- quint32 *dptr = pixels, *drow;
- const uint dbpr = bytesPerRow;
- const unsigned short sbpr = pix->bytesPerRow;
- quint32 *sptr = pix->pixels, *srow;
- for (int y=0; y < h; ++y) {
- drow = dptr + (y * (dbpr/4));
- srow = sptr + (y * (sbpr/4));
- if(d == 1) {
- for (int x=0; x < w; ++x) {
- if((*(srow+x) & RGB_MASK))
- *(drow+x) = 0xFFFFFFFF;
- }
- } else if(d == 8) {
- for (int x=0; x < w; ++x)
- *(drow+x) = (*(drow+x) & RGB_MASK) | (*(srow+x) << 24);
- } else if(asMask) {
- for (int x=0; x < w; ++x) {
- if(*(srow+x) & RGB_MASK)
- *(drow+x) = (*(drow+x) & RGB_MASK);
- else
- *(drow+x) = (*(drow+x) & RGB_MASK) | 0xFF000000;
- *(drow+x) = PREMUL(*(drow+x));
- }
- } else {
- for (int x=0; x < w; ++x) {
- const uchar alpha = qGray(qRed(*(srow+x)), qGreen(*(srow+x)), qBlue(*(srow+x)));
- const uchar destAlpha = qt_div_255(alpha * qAlpha(*(drow+x)));
-#if 1
- *(drow+x) = (*(drow+x) & RGB_MASK) | (destAlpha << 24);
-#else
- *(drow+x) = qRgba(qt_div_255(qRed(*(drow+x) * alpha)),
- qt_div_255(qGreen(*(drow+x) * alpha)),
- qt_div_255(qBlue(*(drow+x) * alpha)), destAlpha);
-#endif
- *(drow+x) = PREMUL(*(drow+x));
- }
- }
- }
- macSetHasAlpha(true);
-}
-
-void QMacPixmapData::macGetAlphaChannel(QMacPixmapData *pix, bool asMask) const
-{
- quint32 *dptr = pix->pixels, *drow;
- const uint dbpr = pix->bytesPerRow;
- const unsigned short sbpr = bytesPerRow;
- quint32 *sptr = pixels, *srow;
- for(int y=0; y < h; ++y) {
- drow = dptr + (y * (dbpr/4));
- srow = sptr + (y * (sbpr/4));
- if(asMask) {
- for (int x = 0; x < w; ++x) {
- if (*(srow + x) & qRgba(0, 0, 0, 255))
- *(drow + x) = 0x00000000;
- else
- *(drow + x) = 0xFFFFFFFF;
- }
- } else {
- for (int x = 0; x < w; ++x) {
- const int alpha = qAlpha(*(srow + x));
- *(drow + x) = qRgb(alpha, alpha, alpha);
- }
- }
- }
-}
-
-void QMacPixmapData::macSetHasAlpha(bool b)
-{
- has_alpha = b;
- macReleaseCGImageRef();
-}
-
-void QMacPixmapData::macCreateCGImageRef()
-{
- Q_ASSERT(cg_data == 0);
- //create the cg data
- CGColorSpaceRef colorspace = QCoreGraphicsPaintEngine::macDisplayColorSpace();
- QCFType<CGDataProviderRef> provider = CGDataProviderCreateWithData(this,
- pixels, bytesPerRow * h,
- qt_mac_cgimage_data_free);
- validDataPointers.insert(this);
- uint cgflags = kCGImageAlphaPremultipliedFirst;
-#ifdef kCGBitmapByteOrder32Host //only needed because CGImage.h added symbols in the minor version
- cgflags |= kCGBitmapByteOrder32Host;
-#endif
- cg_data = CGImageCreate(w, h, 8, 32, bytesPerRow, colorspace,
- cgflags, provider, 0, 0, kCGRenderingIntentDefault);
-}
-
-void QMacPixmapData::macReleaseCGImageRef()
-{
- if (!cg_data)
- return; // There's nothing we need to do
-
- cg_dataBeingReleased = cg_data;
- CGImageRelease(cg_data);
- cg_data = 0;
-
- if (pixels != pixelsToFree) {
- macCreatePixels();
- } else {
- pixelsToFree = 0;
- }
-}
-
-
-// We create our space in memory to paint on here. If we already have existing pixels
-// copy them over. This is to preserve the fact that CGImageRef's are immutable.
-void QMacPixmapData::macCreatePixels()
-{
- const int numBytes = bytesPerRow * h;
- quint32 *base_pixels;
- if (pixelsToFree && pixelsToFree != pixels) {
- // Reuse unused block of memory lying around from a previous callback.
- base_pixels = pixelsToFree;
- pixelsToFree = 0;
- } else {
- // We need a block of memory to do stuff with.
- base_pixels = static_cast<quint32 *>(malloc(numBytes));
- }
-
- if (pixels)
- memcpy(base_pixels, pixels, qMin(pixelsSize, (uint) numBytes));
- pixels = base_pixels;
- pixelsSize = numBytes;
-}
-
-#if 0
-QPixmap QMacPixmapData::transformed(const QTransform &transform,
- Qt::TransformationMode mode) const
-{
- int w, h; // size of target pixmap
- const int ws = width();
- const int hs = height();
-
- QTransform mat(transform.m11(), transform.m12(),
- transform.m21(), transform.m22(), 0., 0.);
- if (transform.m12() == 0.0F && transform.m21() == 0.0F &&
- transform.m11() >= 0.0F && transform.m22() >= 0.0F)
- {
- h = int(qAbs(mat.m22()) * hs + 0.9999);
- w = int(qAbs(mat.m11()) * ws + 0.9999);
- h = qAbs(h);
- w = qAbs(w);
- } else { // rotation or shearing
- QPolygonF a(QRectF(0,0,ws+1,hs+1));
- a = mat.map(a);
- QRectF r = a.boundingRect().normalized();
- w = int(r.width() + 0.9999);
- h = int(r.height() + 0.9999);
- }
- mat = QPixmap::trueMatrix(mat, ws, hs);
- if (!h || !w)
- return QPixmap();
-
- // create destination
- QMacPixmapData *pm = new QMacPixmapData(pixelType(), w, h);
- const quint32 *sptr = pixels;
- quint32 *dptr = pm->pixels;
- memset(dptr, 0, (pm->bytesPerRow * pm->h));
-
- // do the transform
- if (mode == Qt::SmoothTransformation) {
-#warning QMacPixmapData::transformed not properly implemented
- qWarning("QMacPixmapData::transformed not properly implemented");
-#if 0
- QPainter p(&pm);
- p.setRenderHint(QPainter::Antialiasing);
- p.setRenderHint(QPainter::SmoothPixmapTransform);
- p.setTransform(mat);
- p.drawPixmap(0, 0, *this);
-#endif
- } else {
- bool invertible;
- mat = mat.inverted(&invertible);
- if (!invertible)
- return QPixmap();
-
- const int bpp = 32;
- const int xbpl = (w * bpp) / 8;
- if (!qt_xForm_helper(mat, 0, QT_XFORM_TYPE_MSBFIRST, bpp,
- (uchar*)dptr, xbpl, (pm->bytesPerRow) - xbpl,
- h, (uchar*)sptr, (bytesPerRow), ws, hs)) {
- qWarning("QMacPixmapData::transform(): failure");
- return QPixmap();
- }
- }
-
- // update the alpha
- pm->macSetHasAlpha(true);
- return QPixmap(pm);
-}
-#endif
-
-QT_BEGIN_INCLUDE_NAMESPACE
-#include <OpenGL/OpenGL.h>
-#include <OpenGL/gl.h>
-QT_END_INCLUDE_NAMESPACE
-
-// Load and resolve the symbols we need from OpenGL manually so QtGui doesn't have to link against the OpenGL framework.
-typedef CGLError (*PtrCGLChoosePixelFormat)(const CGLPixelFormatAttribute *, CGLPixelFormatObj *, long *);
-typedef CGLError (*PtrCGLClearDrawable)(CGLContextObj);
-typedef CGLError (*PtrCGLCreateContext)(CGLPixelFormatObj, CGLContextObj, CGLContextObj *);
-typedef CGLError (*PtrCGLDestroyContext)(CGLContextObj);
-typedef CGLError (*PtrCGLDestroyPixelFormat)(CGLPixelFormatObj);
-typedef CGLError (*PtrCGLSetCurrentContext)(CGLContextObj);
-typedef CGLError (*PtrCGLSetFullScreen)(CGLContextObj);
-typedef void (*PtrglFinish)();
-typedef void (*PtrglPixelStorei)(GLenum, GLint);
-typedef void (*PtrglReadBuffer)(GLenum);
-typedef void (*PtrglReadPixels)(GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, GLvoid *);
-
-static PtrCGLChoosePixelFormat ptrCGLChoosePixelFormat = 0;
-static PtrCGLClearDrawable ptrCGLClearDrawable = 0;
-static PtrCGLCreateContext ptrCGLCreateContext = 0;
-static PtrCGLDestroyContext ptrCGLDestroyContext = 0;
-static PtrCGLDestroyPixelFormat ptrCGLDestroyPixelFormat = 0;
-static PtrCGLSetCurrentContext ptrCGLSetCurrentContext = 0;
-static PtrCGLSetFullScreen ptrCGLSetFullScreen = 0;
-static PtrglFinish ptrglFinish = 0;
-static PtrglPixelStorei ptrglPixelStorei = 0;
-static PtrglReadBuffer ptrglReadBuffer = 0;
-static PtrglReadPixels ptrglReadPixels = 0;
-
-static bool resolveOpenGLSymbols()
-{
- if (ptrCGLChoosePixelFormat == 0) {
- QLibrary library(QLatin1String("/System/Library/Frameworks/OpenGL.framework/OpenGL"));
- ptrCGLChoosePixelFormat = (PtrCGLChoosePixelFormat)(library.resolve("CGLChoosePixelFormat"));
- ptrCGLClearDrawable = (PtrCGLClearDrawable)(library.resolve("CGLClearDrawable"));
- ptrCGLCreateContext = (PtrCGLCreateContext)(library.resolve("CGLCreateContext"));
- ptrCGLDestroyContext = (PtrCGLDestroyContext)(library.resolve("CGLDestroyContext"));
- ptrCGLDestroyPixelFormat = (PtrCGLDestroyPixelFormat)(library.resolve("CGLDestroyPixelFormat"));
- ptrCGLSetCurrentContext = (PtrCGLSetCurrentContext)(library.resolve("CGLSetCurrentContext"));
- ptrCGLSetFullScreen = (PtrCGLSetFullScreen)(library.resolve("CGLSetFullScreen"));
- ptrglFinish = (PtrglFinish)(library.resolve("glFinish"));
- ptrglPixelStorei = (PtrglPixelStorei)(library.resolve("glPixelStorei"));
- ptrglReadBuffer = (PtrglReadBuffer)(library.resolve("glReadBuffer"));
- ptrglReadPixels = (PtrglReadPixels)(library.resolve("glReadPixels"));
- }
- return ptrCGLChoosePixelFormat && ptrCGLClearDrawable && ptrCGLCreateContext
- && ptrCGLDestroyContext && ptrCGLDestroyPixelFormat && ptrCGLSetCurrentContext
- && ptrCGLSetFullScreen && ptrglFinish && ptrglPixelStorei
- && ptrglReadBuffer && ptrglReadPixels;
-}
-
-// Inverts the given pixmap in the y direction.
-static void qt_mac_flipPixmap(void *data, int rowBytes, int height)
-{
- int bottom = height - 1;
- void *base = data;
- void *buffer = malloc(rowBytes);
-
- int top = 0;
- while ( top < bottom )
- {
- void *topP = (void *)((top * rowBytes) + (intptr_t)base);
- void *bottomP = (void *)((bottom * rowBytes) + (intptr_t)base);
-
- bcopy( topP, buffer, rowBytes );
- bcopy( bottomP, topP, rowBytes );
- bcopy( buffer, bottomP, rowBytes );
-
- ++top;
- --bottom;
- }
- free(buffer);
-}
-
-// Grabs displayRect from display and places it into buffer.
-static void qt_mac_grabDisplayRect(CGDirectDisplayID display, const QRect &displayRect, void *buffer)
-{
- if (display == kCGNullDirectDisplay)
- return;
-
- CGLPixelFormatAttribute attribs[] = {
- kCGLPFAFullScreen,
- kCGLPFADisplayMask,
- (CGLPixelFormatAttribute)0, /* Display mask bit goes here */
- (CGLPixelFormatAttribute)0
- };
-
- attribs[2] = (CGLPixelFormatAttribute)CGDisplayIDToOpenGLDisplayMask(display);
-
- // Build a full-screen GL context
- CGLPixelFormatObj pixelFormatObj;
- long numPixelFormats;
-
- ptrCGLChoosePixelFormat( attribs, &pixelFormatObj, &numPixelFormats );
-
- if (!pixelFormatObj) // No full screen context support
- return;
-
- CGLContextObj glContextObj;
- ptrCGLCreateContext(pixelFormatObj, 0, &glContextObj);
- ptrCGLDestroyPixelFormat(pixelFormatObj) ;
- if (!glContextObj)
- return;
-
- ptrCGLSetCurrentContext(glContextObj);
- ptrCGLSetFullScreen(glContextObj) ;
-
- ptrglReadBuffer(GL_FRONT);
-
- ptrglFinish(); // Finish all OpenGL commands
- ptrglPixelStorei(GL_PACK_ALIGNMENT, 4); // Force 4-byte alignment
- ptrglPixelStorei(GL_PACK_ROW_LENGTH, 0);
- ptrglPixelStorei(GL_PACK_SKIP_ROWS, 0);
- ptrglPixelStorei(GL_PACK_SKIP_PIXELS, 0);
-
- // Fetch the data in XRGB format, matching the bitmap context.
- ptrglReadPixels(GLint(displayRect.x()), GLint(displayRect.y()),
- GLint(displayRect.width()), GLint(displayRect.height()),
-#ifdef __BIG_ENDIAN__
- GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, buffer
-#else
- GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, buffer
-#endif
- );
-
- ptrCGLSetCurrentContext(0);
- ptrCGLClearDrawable(glContextObj); // disassociate from full screen
- ptrCGLDestroyContext(glContextObj); // and destroy the context
-}
-
-#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6)
-// Returns a pixmap containing the screen contents at rect.
-static QPixmap qt_mac_grabScreenRect_10_6(const QRect &rect)
-{
- const int maxDisplays = 128; // 128 displays should be enough for everyone.
- CGDirectDisplayID displays[maxDisplays];
- CGDisplayCount displayCount;
- const CGRect cgRect = CGRectMake(rect.x(), rect.y(), rect.width(), rect.height());
- const CGDisplayErr err = CGGetDisplaysWithRect(cgRect, maxDisplays, displays, &displayCount);
-
- if (err && displayCount == 0)
- return QPixmap();
- QPixmap windowPixmap(rect.size());
- for (uint i = 0; i < displayCount; ++i) {
- const CGRect bounds = CGDisplayBounds(displays[i]);
- // Translate to display-local coordinates
- QRect displayRect = rect.translated(qRound(-bounds.origin.x), qRound(-bounds.origin.y));
- QCFType<CGImageRef> image = CGDisplayCreateImageForRect(displays[i],
- CGRectMake(displayRect.x(), displayRect.y(), displayRect.width(), displayRect.height()));
- QPixmap pix = QPixmap::fromMacCGImageRef(image);
- QPainter painter(&windowPixmap);
- painter.drawPixmap(-bounds.origin.x, -bounds.origin.y, pix);
- }
- return windowPixmap;
-}
-#endif
-
-static QPixmap qt_mac_grabScreenRect(const QRect &rect)
-{
- if (!resolveOpenGLSymbols())
- return QPixmap();
-
- const int maxDisplays = 128; // 128 displays should be enough for everyone.
- CGDirectDisplayID displays[maxDisplays];
- CGDisplayCount displayCount;
- const CGRect cgRect = CGRectMake(rect.x(), rect.y(), rect.width(), rect.height());
- const CGDisplayErr err = CGGetDisplaysWithRect(cgRect, maxDisplays, displays, &displayCount);
-
- if (err && displayCount == 0)
- return QPixmap();
-
- long bytewidth = rect.width() * 4; // Assume 4 bytes/pixel for now
- bytewidth = (bytewidth + 3) & ~3; // Align to 4 bytes
- QVarLengthArray<char> buffer(rect.height() * bytewidth);
-
- for (uint i = 0; i < displayCount; ++i) {
- const CGRect bounds = CGDisplayBounds(displays[i]);
- // Translate to display-local coordinates
- QRect displayRect = rect.translated(qRound(-bounds.origin.x), qRound(-bounds.origin.y));
- // Adjust for inverted y axis.
- displayRect.moveTop(qRound(bounds.size.height) - displayRect.y() - rect.height());
- qt_mac_grabDisplayRect(displays[i], displayRect, buffer.data());
- }
-
- qt_mac_flipPixmap(buffer.data(), bytewidth, rect.height());
- QCFType<CGContextRef> bitmap = CGBitmapContextCreate(buffer.data(), rect.width(),
- rect.height(), 8, bytewidth,
- QCoreGraphicsPaintEngine::macGenericColorSpace(),
- kCGImageAlphaNoneSkipFirst);
- QCFType<CGImageRef> image = CGBitmapContextCreateImage(bitmap);
- return QPixmap::fromMacCGImageRef(image);
-}
-
-#ifndef QT_MAC_USE_COCOA // no QuickDraw in 64-bit mode
-static QPixmap qt_mac_grabScreenRect_10_3(int x, int y, int w, int h, QWidget *widget)
-{
- QPixmap pm = QPixmap(w, h);
- extern WindowPtr qt_mac_window_for(const QWidget *); // qwidget_mac.cpp
- const BitMap *windowPort = 0;
- if((widget->windowType() == Qt::Desktop)) {
- GDHandle gdh;
- if(!(gdh=GetMainDevice()))
- qDebug("Qt: internal: Unexpected condition reached: %s:%d", __FILE__, __LINE__);
- windowPort = (BitMap*)(*(*gdh)->gdPMap);
- } else {
- windowPort = GetPortBitMapForCopyBits(GetWindowPort(qt_mac_window_for(widget)));
- }
- const BitMap *pixmapPort = GetPortBitMapForCopyBits(static_cast<GWorldPtr>(pm.macQDHandle()));
- Rect macSrcRect, macDstRect;
- SetRect(&macSrcRect, x, y, x + w, y + h);
- SetRect(&macDstRect, 0, 0, w, h);
- CopyBits(windowPort, pixmapPort, &macSrcRect, &macDstRect, srcCopy, 0);
- return pm;
-}
-#endif
-
-QPixmap QPixmap::grabWindow(WId window, int x, int y, int w, int h)
-{
- QWidget *widget = QWidget::find(window);
- if (widget == 0)
- return QPixmap();
-
- if(w == -1)
- w = widget->width() - x;
- if(h == -1)
- h = widget->height() - y;
-
- QPoint globalCoord(0, 0);
- globalCoord = widget->mapToGlobal(globalCoord);
- QRect rect(globalCoord.x() + x, globalCoord.y() + y, w, h);
-
-#ifdef QT_MAC_USE_COCOA
-#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6)
- if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_6)
- return qt_mac_grabScreenRect_10_6(rect);
- else
-#endif
- return qt_mac_grabScreenRect(rect);
-#else
-#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4)
- if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4) {
- return qt_mac_grabScreenRect(rect);
- } else
-#endif
- {
- return qt_mac_grabScreenRect_10_3(x, y, w, h, widget);
- }
-#endif // ifdef Q_WS_MAC64
-}
-
-/*! \internal
-
- Returns the QuickDraw CGrafPtr of the pixmap. 0 is returned if it can't
- be obtained. Do not hold the pointer around for long as it can be
- relocated.
-
- \warning This function is only available on Mac OS X.
- \warning As of Qt 4.6, this function \e{always} returns zero.
-*/
-
-Qt::HANDLE QPixmap::macQDHandle() const
-{
- return 0;
-}
-
-/*! \internal
-
- Returns the QuickDraw CGrafPtr of the pixmap's alpha channel. 0 is
- returned if it can't be obtained. Do not hold the pointer around for
- long as it can be relocated.
-
- \warning This function is only available on Mac OS X.
- \warning As of Qt 4.6, this function \e{always} returns zero.
-*/
-
-Qt::HANDLE QPixmap::macQDAlphaHandle() const
-{
- return 0;
-}
-
-/*! \internal
-
- Returns the CoreGraphics CGContextRef of the pixmap. 0 is returned if
- it can't be obtained. It is the caller's responsiblity to
- CGContextRelease the context when finished using it.
-
- \warning This function is only available on Mac OS X.
-*/
-
-Qt::HANDLE QPixmap::macCGHandle() const
-{
- if (isNull())
- return 0;
-
- if (data->classId() == QPixmapData::MacClass) {
- QMacPixmapData *d = static_cast<QMacPixmapData *>(data.data());
- if (!d->cg_data)
- d->macCreateCGImageRef();
- CGImageRef ret = d->cg_data;
- CGImageRetain(ret);
- return ret;
- } else if (data->classId() == QPixmapData::RasterClass) {
- return qt_mac_image_to_cgimage(static_cast<QRasterPixmapData *>(data.data())->image);
- }
- return 0;
-}
-
-bool QMacPixmapData::hasAlphaChannel() const
-{
- return has_alpha;
-}
-
-CGImageRef qt_mac_create_imagemask(const QPixmap &pixmap, const QRectF &sr)
-{
- QMacPixmapData *px = static_cast<QMacPixmapData*>(pixmap.data.data());
- if (px->cg_mask) {
- if (px->cg_mask_rect == sr) {
- CGImageRetain(px->cg_mask); //reference for the caller
- return px->cg_mask;
- }
- CGImageRelease(px->cg_mask);
- px->cg_mask = 0;
- }
-
- const int sx = qRound(sr.x()), sy = qRound(sr.y()), sw = qRound(sr.width()), sh = qRound(sr.height());
- const int sbpr = px->bytesPerRow;
- const uint nbytes = sw * sh;
- // alpha is always 255 for bitmaps, ignore it in this case.
- const quint32 mask = px->depth() == 1 ? 0x00ffffff : 0xffffffff;
- quint8 *dptr = static_cast<quint8 *>(malloc(nbytes));
- quint32 *sptr = px->pixels, *srow;
- for(int y = sy, offset=0; y < sh; ++y) {
- srow = sptr + (y * (sbpr / 4));
- for(int x = sx; x < sw; ++x)
- *(dptr+(offset++)) = (*(srow+x) & mask) ? 255 : 0;
- }
- QCFType<CGDataProviderRef> provider = CGDataProviderCreateWithData(0, dptr, nbytes, qt_mac_cgimage_data_free);
- px->cg_mask = CGImageMaskCreate(sw, sh, 8, 8, nbytes / sh, provider, 0, 0);
- px->cg_mask_rect = sr;
- CGImageRetain(px->cg_mask); //reference for the caller
- return px->cg_mask;
-}
-
-#ifndef QT_MAC_USE_COCOA
-IconRef qt_mac_create_iconref(const QPixmap &px)
-{
- if (px.isNull())
- return 0;
-
- //create icon
- IconFamilyHandle iconFamily = reinterpret_cast<IconFamilyHandle>(NewHandle(0));
- //create data
- {
- struct {
- OSType mac_type;
- int width, height, depth;
- bool mask;
- } images[] = {
- { kThumbnail32BitData, 128, 128, 32, false },
- { kThumbnail8BitMask, 128, 128, 8, true },
- { 0, 0, 0, 0, false } //end marker
- };
- for(int i = 0; images[i].mac_type; i++) {
- //get QPixmap data
- QImage scaled_px = px.toImage().scaled(images[i].width, images[i].height);
-
- quint32 *sptr = (quint32 *) scaled_px.bits();
- quint32 *srow;
- uint sbpr = scaled_px.bytesPerLine();
-
- //get Handle data
- const int dbpr = images[i].width * (images[i].depth/8);
- Handle hdl = NewHandle(dbpr*images[i].height);
- if(!sptr) { //handle null pixmap
- memset((*hdl), '\0', dbpr*images[i].height);
- } else if(images[i].mask) {
- if(images[i].mac_type == kThumbnail8BitMask) {
- for(int y = 0, hindex = 0; y < images[i].height; ++y) {
- srow = sptr + (y * (sbpr/4));
- for(int x = 0; x < images[i].width; ++x)
- *((*hdl)+(hindex++)) = qAlpha(*(srow+x));
- }
- }
- } else {
- char *dest = (*hdl);
-#if defined(__i386__)
- if(images[i].depth == 32) {
- for(int y = 0; y < images[i].height; ++y) {
- uint *source = (uint*)((const uchar*)sptr+(sbpr*y));
- for(int x = 0; x < images[i].width; ++x, dest += 4)
- *((uint*)dest) = CFSwapInt32(*(source + x));
- }
- } else
-#endif
- {
- for(int y = 0; y < images[i].height; ++y)
- memcpy(dest+(y*dbpr), ((const uchar*)sptr+(sbpr*y)), dbpr);
- }
- }
-
- //set the family data to the Handle
- OSStatus set = SetIconFamilyData(iconFamily, images[i].mac_type, hdl);
- if(set != noErr)
- qWarning("%s: %d -- Unable to create icon data[%d]!! %ld",
- __FILE__, __LINE__, i, long(set));
- DisposeHandle(hdl);
- }
- }
-
- //acquire and cleanup
- IconRef ret;
- static int counter = 0;
- const OSType kQtCreator = 'CUTE';
- RegisterIconRefFromIconFamily(kQtCreator, (OSType)counter, iconFamily, &ret);
- AcquireIconRef(ret);
- UnregisterIconRef(kQtCreator, (OSType)counter);
- DisposeHandle(reinterpret_cast<Handle>(iconFamily));
- counter++;
- return ret;
-
-}
-#endif
-
-/*! \internal */
-QPaintEngine* QMacPixmapData::paintEngine() const
-{
- if (!pengine) {
- QMacPixmapData *that = const_cast<QMacPixmapData*>(this);
- that->pengine = new QCoreGraphicsPaintEngine();
- }
- return pengine;
-}
-
-void QMacPixmapData::copy(const QPixmapData *data, const QRect &rect)
-{
- if (data->pixelType() == BitmapType) {
- QBitmap::fromImage(toImage().copy(rect));
- return;
- }
-
- const QMacPixmapData *macData = static_cast<const QMacPixmapData*>(data);
-
- resize(rect.width(), rect.height());
-
- has_alpha = macData->has_alpha;
- has_mask = macData->has_mask;
- uninit = false;
-
- const int x = rect.x();
- const int y = rect.y();
- char *dest = reinterpret_cast<char*>(pixels);
- const char *src = reinterpret_cast<const char*>(macData->pixels + x) + y * macData->bytesPerRow;
- for (int i = 0; i < h; ++i) {
- memcpy(dest, src, w * 4);
- dest += bytesPerRow;
- src += macData->bytesPerRow;
- }
-
- has_alpha = macData->has_alpha;
- has_mask = macData->has_mask;
-}
-
-bool QMacPixmapData::scroll(int dx, int dy, const QRect &rect)
-{
- Q_UNUSED(dx);
- Q_UNUSED(dy);
- Q_UNUSED(rect);
- return false;
-}
-
-/*!
- \since 4.2
-
- Creates a \c CGImageRef equivalent to the QPixmap. Returns the \c CGImageRef handle.
-
- It is the caller's responsibility to release the \c CGImageRef data
- after use.
-
- \warning This function is only available on Mac OS X.
-
- \sa fromMacCGImageRef()
-*/
-CGImageRef QPixmap::toMacCGImageRef() const
-{
- return (CGImageRef)macCGHandle();
-}
-
-/*!
- \since 4.2
-
- Returns a QPixmap that is equivalent to the given \a image.
-
- \warning This function is only available on Mac OS X.
-
- \sa toMacCGImageRef(), {QPixmap#Pixmap Conversion}{Pixmap Conversion}
-*/
-QPixmap QPixmap::fromMacCGImageRef(CGImageRef image)
-{
- const size_t w = CGImageGetWidth(image),
- h = CGImageGetHeight(image);
- QPixmap ret(w, h);
- ret.fill(Qt::transparent);
- CGRect rect = CGRectMake(0, 0, w, h);
- CGContextRef ctx = qt_mac_cg_context(&ret);
- qt_mac_drawCGImage(ctx, &rect, image);
- CGContextRelease(ctx);
- return ret;
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/image/qpixmap_mac_p.h b/src/gui/image/qpixmap_mac_p.h
deleted file mode 100644
index 3a5d97dc4a..0000000000
--- a/src/gui/image/qpixmap_mac_p.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPIXMAP_MAC_P_H
-#define QPIXMAP_MAC_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtGui/private/qpixmapdata_p.h>
-#include <QtGui/private/qpixmapdatafactory_p.h>
-#include <QtGui/private/qt_mac_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QMacPixmapData : public QPixmapData
-{
-public:
- QMacPixmapData(PixelType type);
- ~QMacPixmapData();
-
- QPixmapData *createCompatiblePixmapData() const;
-
- void resize(int width, int height);
- void fromImage(const QImage &image, Qt::ImageConversionFlags flags);
- void copy(const QPixmapData *data, const QRect &rect);
- bool scroll(int dx, int dy, const QRect &rect);
-
- int metric(QPaintDevice::PaintDeviceMetric metric) const;
- void fill(const QColor &color);
- QBitmap mask() const;
- void setMask(const QBitmap &mask);
- bool hasAlphaChannel() const;
-// QPixmap transformed(const QTransform &matrix,
-// Qt::TransformationMode mode) const;
- void setAlphaChannel(const QPixmap &alphaChannel);
- QPixmap alphaChannel() const;
- QImage toImage() const;
- QPaintEngine* paintEngine() const;
-
-private:
-
- uint has_alpha : 1, has_mask : 1, uninit : 1;
-
- void macSetHasAlpha(bool b);
- void macGetAlphaChannel(QMacPixmapData *, bool asMask) const;
- void macSetAlphaChannel(const QMacPixmapData *, bool asMask);
- void macCreateCGImageRef();
- void macCreatePixels();
- void macReleaseCGImageRef();
- /*
- pixels stores the pixmap data. pixelsToFree is either 0 or some memory
- block that was bound to a CGImageRef and released, and for which the
- release callback has been called. There are two uses to pixelsToFree:
-
- 1. If pixels == pixelsToFree, then we know that the CGImageRef is done\
- with the data and we can modify pixels without breaking CGImageRef's
- mutability invariant.
-
- 2. If pixels != pixelsToFree and pixelsToFree != 0, then we can reuse
- pixelsToFree later on instead of malloc'ing memory.
- */
- quint32 *pixels;
- uint pixelsSize;
- quint32 *pixelsToFree;
- uint bytesPerRow;
- QRectF cg_mask_rect;
- CGImageRef cg_data, cg_dataBeingReleased, cg_mask;
- static QSet<QMacPixmapData*> validDataPointers;
-
- QPaintEngine *pengine;
-
- friend class QPixmap;
- friend class QRasterBuffer;
- friend class QRasterPaintEngine;
- friend class QCoreGraphicsPaintEngine;
- friend CGImageRef qt_mac_create_imagemask(const QPixmap&, const QRectF&);
- friend quint32 *qt_mac_pixmap_get_base(const QPixmap*);
- friend int qt_mac_pixmap_get_bytes_per_line(const QPixmap*);
- friend void qt_mac_cgimage_data_free(void *, const void*, size_t);
- friend IconRef qt_mac_create_iconref(const QPixmap&);
- friend CGContextRef qt_mac_cg_context(const QPaintDevice*);
- friend QColor qcolorForThemeTextColor(ThemeTextColor themeColor);
-};
-
-QT_END_NAMESPACE
-
-#endif // QPIXMAP_MAC_P_H
diff --git a/src/gui/image/qpixmap_qpa.cpp b/src/gui/image/qpixmap_qpa.cpp
index 095dd3ae76..9c69ddef7e 100644
--- a/src/gui/image/qpixmap_qpa.cpp
+++ b/src/gui/image/qpixmap_qpa.cpp
@@ -40,10 +40,10 @@
****************************************************************************/
#include <qpixmap.h>
-#include <private/qgraphicssystem_p.h>
-#include <private/qapplication_p.h>
+#include <qscreen.h>
+#include <private/qguiapplication_p.h>
QPixmap QPixmap::grabWindow(WId window, int x, int y, int w, int h)
{
- return QApplicationPrivate::platformIntegration()->grabWindow(window, x, y, w, h);
+ return QGuiApplication::primaryScreen()->handle()->grabWindow(window, x, y, w, h);
}
diff --git a/src/gui/image/qpixmap_qws.cpp b/src/gui/image/qpixmap_qws.cpp
deleted file mode 100644
index 804483898c..0000000000
--- a/src/gui/image/qpixmap_qws.cpp
+++ /dev/null
@@ -1,160 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qpixmap.h>
-#include <qapplication.h>
-#include <qwidget.h>
-#include <qdesktopwidget.h>
-#include <qscreen_qws.h>
-#include <qwsdisplay_qws.h>
-#include <private/qdrawhelper_p.h>
-#include <private/qpixmap_raster_p.h>
-
-
-QT_BEGIN_NAMESPACE
-
-QPixmap QPixmap::grabWindow(WId window, int x, int y, int w, int h)
-{
- QWidget *widget = QWidget::find(window);
- if (!widget)
- return QPixmap();
-
- QRect grabRect = widget->frameGeometry();
- if (!widget->isWindow())
- grabRect.translate(widget->parentWidget()->mapToGlobal(QPoint()));
- if (w < 0)
- w = widget->width() - x;
- if (h < 0)
- h = widget->height() - y;
- grabRect &= QRect(x, y, w, h).translated(widget->mapToGlobal(QPoint()));
-
- QScreen *screen = qt_screen;
- QDesktopWidget *desktop = QApplication::desktop();
- if (!desktop)
- return QPixmap();
- if (desktop->numScreens() > 1) {
- const int screenNo = desktop->screenNumber(widget);
- if (screenNo != -1)
- screen = qt_screen->subScreens().at(screenNo);
- grabRect = grabRect.translated(-screen->region().boundingRect().topLeft());
- }
-
- if (screen->pixelFormat() == QImage::Format_Invalid) {
- qWarning("QPixmap::grabWindow(): Unable to copy pixels from framebuffer");
- return QPixmap();
- }
-
- if (screen->isTransformed()) {
- const QSize screenSize(screen->width(), screen->height());
- grabRect = screen->mapToDevice(grabRect, screenSize);
- }
-
- QWSDisplay::grab(false);
- QPixmap pixmap;
- QImage img(screen->base(),
- screen->deviceWidth(), screen->deviceHeight(),
- screen->linestep(), screen->pixelFormat());
- img = img.copy(grabRect);
- QWSDisplay::ungrab();
-
- if (screen->isTransformed()) {
- QMatrix matrix;
- switch (screen->transformOrientation()) {
- case 1: matrix.rotate(90); break;
- case 2: matrix.rotate(180); break;
- case 3: matrix.rotate(270); break;
- default: break;
- }
- img = img.transformed(matrix);
- }
-
- if (screen->pixelType() == QScreen::BGRPixel)
- img = img.rgbSwapped();
-
- return QPixmap::fromImage(img);
-}
-
-QRgb* QPixmap::clut() const
-{
- if (data && data->classId() == QPixmapData::RasterClass) {
- const QRasterPixmapData *d = static_cast<const QRasterPixmapData*>(data.data());
- return d->image.colorTable().data();
- }
-
- return 0;
-}
-
-int QPixmap::numCols() const
-{
- return colorCount();
-}
-
-int QPixmap::colorCount() const
-{
- if (data && data->classId() == QPixmapData::RasterClass) {
- const QRasterPixmapData *d = static_cast<const QRasterPixmapData*>(data.data());
- return d->image.colorCount();
- }
-
- return 0;
-}
-
-const uchar* QPixmap::qwsBits() const
-{
- if (data && data->classId() == QPixmapData::RasterClass) {
- const QRasterPixmapData *d = static_cast<const QRasterPixmapData*>(data.data());
- return d->image.bits();
- }
-
- return 0;
-}
-
-int QPixmap::qwsBytesPerLine() const
-{
- if (data && data->classId() == QPixmapData::RasterClass) {
- const QRasterPixmapData *d = static_cast<const QRasterPixmapData*>(data.data());
- return d->image.bytesPerLine();
- }
-
- return 0;
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/image/qpixmap_raster.cpp b/src/gui/image/qpixmap_raster.cpp
index 6355222da1..ce7d66043c 100644
--- a/src/gui/image/qpixmap_raster.cpp
+++ b/src/gui/image/qpixmap_raster.cpp
@@ -54,20 +54,16 @@
#include <QImageReader>
#include <private/qimage_p.h>
#include <private/qsimd_p.h>
-#include <private/qwidget_p.h>
#include <private/qdrawhelper_p.h>
QT_BEGIN_NAMESPACE
-const uchar qt_pixmap_bit_mask[] = { 0x01, 0x02, 0x04, 0x08,
- 0x10, 0x20, 0x40, 0x80 };
-
QPixmap qt_toRasterPixmap(const QImage &image)
{
- QPixmapData *data =
- new QRasterPixmapData(image.depth() == 1
- ? QPixmapData::BitmapType
- : QPixmapData::PixmapType);
+ QPlatformPixmap *data =
+ new QRasterPlatformPixmap(image.depth() == 1
+ ? QPlatformPixmap::BitmapType
+ : QPlatformPixmap::PixmapType);
data->fromImage(image, Qt::AutoColor);
@@ -79,27 +75,27 @@ QPixmap qt_toRasterPixmap(const QPixmap &pixmap)
if (pixmap.isNull())
return QPixmap();
- if (QPixmap(pixmap).data_ptr()->classId() == QPixmapData::RasterClass)
+ if (QPixmap(pixmap).data_ptr()->classId() == QPlatformPixmap::RasterClass)
return pixmap;
return qt_toRasterPixmap(pixmap.toImage());
}
-QRasterPixmapData::QRasterPixmapData(PixelType type)
- : QPixmapData(type, RasterClass)
+QRasterPlatformPixmap::QRasterPlatformPixmap(PixelType type)
+ : QPlatformPixmap(type, RasterClass)
{
}
-QRasterPixmapData::~QRasterPixmapData()
+QRasterPlatformPixmap::~QRasterPlatformPixmap()
{
}
-QPixmapData *QRasterPixmapData::createCompatiblePixmapData() const
+QPlatformPixmap *QRasterPlatformPixmap::createCompatiblePlatformPixmap() const
{
- return new QRasterPixmapData(pixelType());
+ return new QRasterPlatformPixmap(pixelType());
}
-void QRasterPixmapData::resize(int width, int height)
+void QRasterPlatformPixmap::resize(int width, int height)
{
QImage::Format format;
#ifdef Q_WS_QWS
@@ -134,7 +130,7 @@ void QRasterPixmapData::resize(int width, int height)
setSerialNumber(image.serialNumber());
}
-bool QRasterPixmapData::fromData(const uchar *buffer, uint len, const char *format,
+bool QRasterPlatformPixmap::fromData(const uchar *buffer, uint len, const char *format,
Qt::ImageConversionFlags flags)
{
QByteArray a = QByteArray::fromRawData(reinterpret_cast<const char *>(buffer), len);
@@ -148,7 +144,7 @@ bool QRasterPixmapData::fromData(const uchar *buffer, uint len, const char *form
return !isNull();
}
-void QRasterPixmapData::fromImage(const QImage &sourceImage,
+void QRasterPlatformPixmap::fromImage(const QImage &sourceImage,
Qt::ImageConversionFlags flags)
{
Q_UNUSED(flags);
@@ -156,7 +152,7 @@ void QRasterPixmapData::fromImage(const QImage &sourceImage,
createPixmapForImage(image, flags, /* inplace = */false);
}
-void QRasterPixmapData::fromImageReader(QImageReader *imageReader,
+void QRasterPlatformPixmap::fromImageReader(QImageReader *imageReader,
Qt::ImageConversionFlags flags)
{
Q_UNUSED(flags);
@@ -170,19 +166,19 @@ void QRasterPixmapData::fromImageReader(QImageReader *imageReader,
// from qwindowsurface.cpp
extern void qt_scrollRectInImage(QImage &img, const QRect &rect, const QPoint &offset);
-void QRasterPixmapData::copy(const QPixmapData *data, const QRect &rect)
+void QRasterPlatformPixmap::copy(const QPlatformPixmap *data, const QRect &rect)
{
fromImage(data->toImage(rect).copy(), Qt::NoOpaqueDetection);
}
-bool QRasterPixmapData::scroll(int dx, int dy, const QRect &rect)
+bool QRasterPlatformPixmap::scroll(int dx, int dy, const QRect &rect)
{
if (!image.isNull())
qt_scrollRectInImage(image, rect, QPoint(dx, dy));
return true;
}
-void QRasterPixmapData::fill(const QColor &color)
+void QRasterPlatformPixmap::fill(const QColor &color)
{
uint pixel;
@@ -266,51 +262,12 @@ void QRasterPixmapData::fill(const QColor &color)
image.fill(pixel);
}
-void QRasterPixmapData::setMask(const QBitmap &mask)
-{
- if (mask.size().isEmpty()) {
- if (image.depth() != 1) { // hw: ????
- image = image.convertToFormat(QImage::Format_RGB32);
- }
- } else {
- const int w = image.width();
- const int h = image.height();
-
- switch (image.depth()) {
- case 1: {
- const QImage imageMask = mask.toImage().convertToFormat(image.format());
- for (int y = 0; y < h; ++y) {
- const uchar *mscan = imageMask.scanLine(y);
- uchar *tscan = image.scanLine(y);
- int bytesPerLine = image.bytesPerLine();
- for (int i = 0; i < bytesPerLine; ++i)
- tscan[i] &= mscan[i];
- }
- break;
- }
- default: {
- const QImage imageMask = mask.toImage().convertToFormat(QImage::Format_MonoLSB);
- image = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
- for (int y = 0; y < h; ++y) {
- const uchar *mscan = imageMask.scanLine(y);
- QRgb *tscan = (QRgb *)image.scanLine(y);
- for (int x = 0; x < w; ++x) {
- if (!(mscan[x>>3] & qt_pixmap_bit_mask[x&7]))
- tscan[x] = 0;
- }
- }
- break;
- }
- }
- }
-}
-
-bool QRasterPixmapData::hasAlphaChannel() const
+bool QRasterPlatformPixmap::hasAlphaChannel() const
{
return image.hasAlphaChannel();
}
-QImage QRasterPixmapData::toImage() const
+QImage QRasterPlatformPixmap::toImage() const
{
if (!image.isNull()) {
QImageData *data = const_cast<QImage &>(image).data_ptr();
@@ -324,7 +281,7 @@ QImage QRasterPixmapData::toImage() const
return image;
}
-QImage QRasterPixmapData::toImage(const QRect &rect) const
+QImage QRasterPlatformPixmap::toImage(const QRect &rect) const
{
if (rect.isNull())
return image;
@@ -338,17 +295,12 @@ QImage QRasterPixmapData::toImage(const QRect &rect) const
return image.copy(clipped);
}
-void QRasterPixmapData::setAlphaChannel(const QPixmap &alphaChannel)
-{
- image.setAlphaChannel(alphaChannel.toImage());
-}
-
-QPaintEngine* QRasterPixmapData::paintEngine() const
+QPaintEngine* QRasterPlatformPixmap::paintEngine() const
{
return image.paintEngine();
}
-int QRasterPixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const
+int QRasterPlatformPixmap::metric(QPaintDevice::PaintDeviceMetric metric) const
{
QImageData *d = image.d;
if (!d)
@@ -375,14 +327,14 @@ int QRasterPixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const
case QPaintDevice::PdmPhysicalDpiY:
return qt_defaultDpiY();
default:
- qWarning("QRasterPixmapData::metric(): Unhandled metric type %d", metric);
+ qWarning("QRasterPlatformPixmap::metric(): Unhandled metric type %d", metric);
break;
}
return 0;
}
-void QRasterPixmapData::createPixmapForImage(QImage &sourceImage, Qt::ImageConversionFlags flags, bool inPlace)
+void QRasterPlatformPixmap::createPixmapForImage(QImage &sourceImage, Qt::ImageConversionFlags flags, bool inPlace)
{
QImage::Format format;
if (flags & Qt::NoFormatConversion)
@@ -484,7 +436,7 @@ void QRasterPixmapData::createPixmapForImage(QImage &sourceImage, Qt::ImageConve
setSerialNumber(image.serialNumber());
}
-QImage* QRasterPixmapData::buffer()
+QImage* QRasterPlatformPixmap::buffer()
{
return &image;
}
diff --git a/src/gui/image/qpixmap_raster_p.h b/src/gui/image/qpixmap_raster_p.h
index decbd10b5f..c451a94858 100644
--- a/src/gui/image/qpixmap_raster_p.h
+++ b/src/gui/image/qpixmap_raster_p.h
@@ -53,8 +53,7 @@
// We mean it.
//
-#include <QtGui/private/qpixmapdata_p.h>
-#include <QtGui/private/qpixmapdatafactory_p.h>
+#include <QtGui/qplatformpixmap_qpa.h>
#ifdef Q_WS_WIN
# include "qt_windows.h"
@@ -62,13 +61,13 @@
QT_BEGIN_NAMESPACE
-class Q_GUI_EXPORT QRasterPixmapData : public QPixmapData
+class Q_GUI_EXPORT QRasterPlatformPixmap : public QPlatformPixmap
{
public:
- QRasterPixmapData(PixelType type);
- ~QRasterPixmapData();
+ QRasterPlatformPixmap(PixelType type);
+ ~QRasterPlatformPixmap();
- QPixmapData *createCompatiblePixmapData() const;
+ QPlatformPixmap *createCompatiblePlatformPixmap() const;
void resize(int width, int height);
void fromFile(const QString &filename, Qt::ImageConversionFlags flags);
@@ -76,12 +75,10 @@ public:
void fromImage(const QImage &image, Qt::ImageConversionFlags flags);
void fromImageReader(QImageReader *imageReader, Qt::ImageConversionFlags flags);
- void copy(const QPixmapData *data, const QRect &rect);
+ void copy(const QPlatformPixmap *data, const QRect &rect);
bool scroll(int dx, int dy, const QRect &rect);
void fill(const QColor &color);
- void setMask(const QBitmap &mask);
bool hasAlphaChannel() const;
- void setAlphaChannel(const QPixmap &alphaChannel);
QImage toImage() const;
QImage toImage(const QRect &rect) const;
QPaintEngine* paintEngine() const;
diff --git a/src/gui/image/qpixmap_s60.cpp b/src/gui/image/qpixmap_s60.cpp
deleted file mode 100644
index ac29f5dea4..0000000000
--- a/src/gui/image/qpixmap_s60.cpp
+++ /dev/null
@@ -1,1040 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#include <exception>
-#include <w32std.h>
-#include <fbs.h>
-
-#include <private/qapplication_p.h>
-#include <private/qgraphicssystem_p.h>
-#include <private/qt_s60_p.h>
-#include <private/qpaintengine_s60_p.h>
-#include <private/qfont_p.h>
-
-#include "qpixmap.h"
-#include "qpixmap_raster_p.h"
-#include <qwidget.h>
-#include "qpixmap_s60_p.h"
-#include "qnativeimage_p.h"
-#include "qbitmap.h"
-#include "qimage.h"
-#include "qimage_p.h"
-
-#include <fbs.h>
-
-QT_BEGIN_NAMESPACE
-
-const uchar qt_pixmap_bit_mask[] = { 0x01, 0x02, 0x04, 0x08,
- 0x10, 0x20, 0x40, 0x80 };
-
-static bool cleanup_function_registered = false;
-static QS60PixmapData *firstPixmap = 0;
-
-// static
-void QS60PixmapData::qt_symbian_register_pixmap(QS60PixmapData *pd)
-{
- if (!cleanup_function_registered) {
- qAddPostRoutine(qt_symbian_release_pixmaps);
- cleanup_function_registered = true;
- }
-
- pd->next = firstPixmap;
- pd->prev = 0;
- if (firstPixmap)
- firstPixmap->prev = pd;
- firstPixmap = pd;
-}
-
-// static
-void QS60PixmapData::qt_symbian_unregister_pixmap(QS60PixmapData *pd)
-{
- if (pd->next)
- pd->next->prev = pd->prev;
- if (pd->prev)
- pd->prev->next = pd->next;
- else
- firstPixmap = pd->next;
-}
-
-// static
-void QS60PixmapData::qt_symbian_release_pixmaps()
-{
- // Scan all QS60PixmapData objects in the system and destroy them.
- QS60PixmapData *pd = firstPixmap;
- while (pd != 0) {
- pd->release();
- pd = pd->next;
- }
-}
-
-/*
- \class QSymbianFbsClient
- \since 4.6
- \internal
-
- Symbian Font And Bitmap server client that is
- used to lock the global bitmap heap. Only used in
- S60 v3.1 and S60 v3.2.
-*/
-_LIT(KFBSERVLargeBitmapAccessName,"FbsLargeBitmapAccess");
-class QSymbianFbsClient
-{
-public:
-
- QSymbianFbsClient() : heapLocked(false)
- {
- heapLock.OpenGlobal(KFBSERVLargeBitmapAccessName);
- }
-
- ~QSymbianFbsClient()
- {
- heapLock.Close();
- }
-
- bool lockHeap()
- {
- bool wasLocked = heapLocked;
-
- if (heapLock.Handle() && !heapLocked) {
- heapLock.Wait();
- heapLocked = true;
- }
-
- return wasLocked;
- }
-
- bool unlockHeap()
- {
- bool wasLocked = heapLocked;
-
- if (heapLock.Handle() && heapLocked) {
- heapLock.Signal();
- heapLocked = false;
- }
-
- return wasLocked;
- }
-
-
-private:
-
- RMutex heapLock;
- bool heapLocked;
-};
-
-Q_GLOBAL_STATIC(QSymbianFbsClient, qt_symbianFbsClient);
-
-
-
-// QSymbianFbsHeapLock
-
-QSymbianFbsHeapLock::QSymbianFbsHeapLock(LockAction a)
-: action(a), wasLocked(false)
-{
- QSysInfo::SymbianVersion symbianVersion = QSysInfo::symbianVersion();
- if (symbianVersion == QSysInfo::SV_9_2 || symbianVersion == QSysInfo::SV_9_3)
- wasLocked = qt_symbianFbsClient()->unlockHeap();
-}
-
-QSymbianFbsHeapLock::~QSymbianFbsHeapLock()
-{
- // Do nothing
-}
-
-void QSymbianFbsHeapLock::relock()
-{
- QSysInfo::SymbianVersion symbianVersion = QSysInfo::symbianVersion();
- if (wasLocked && (symbianVersion == QSysInfo::SV_9_2 || symbianVersion == QSysInfo::SV_9_3))
- qt_symbianFbsClient()->lockHeap();
-}
-
-/*
- \class QSymbianBitmapDataAccess
- \since 4.6
- \internal
-
- Data access class that is used to locks/unlocks pixel data
- when drawing or modifying CFbsBitmap pixel data.
-*/
-class QSymbianBitmapDataAccess
-{
-public:
-
- static int heapRefCount;
- QSysInfo::SymbianVersion symbianVersion;
-
- explicit QSymbianBitmapDataAccess()
- {
- symbianVersion = QSysInfo::symbianVersion();
- };
-
- ~QSymbianBitmapDataAccess() {};
-
- inline void beginDataAccess(CFbsBitmap *bitmap)
- {
- if (symbianVersion == QSysInfo::SV_9_2) {
- if (heapRefCount == 0)
- qt_symbianFbsClient()->lockHeap();
- } else {
- bitmap->LockHeap(ETrue);
- }
-
- heapRefCount++;
- }
-
- inline void endDataAccess(CFbsBitmap *bitmap)
- {
- heapRefCount--;
-
- if (symbianVersion == QSysInfo::SV_9_2) {
- if (heapRefCount == 0)
- qt_symbianFbsClient()->unlockHeap();
- } else {
- bitmap->UnlockHeap(ETrue);
- }
- }
-};
-
-int QSymbianBitmapDataAccess::heapRefCount = 0;
-
-
-#define UPDATE_BUFFER() \
- { \
- beginDataAccess(); \
- endDataAccess(); \
-}
-
-
-static CFbsBitmap* createSymbianCFbsBitmap(const TSize& size, TDisplayMode mode)
-{
- QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock);
-
- CFbsBitmap* bitmap = 0;
- QT_TRAP_THROWING(bitmap = new (ELeave) CFbsBitmap);
-
- if (bitmap->Create(size, mode) != KErrNone) {
- delete bitmap;
- bitmap = 0;
- }
-
- lock.relock();
-
- return bitmap;
-}
-
-static CFbsBitmap* uncompress(CFbsBitmap* bitmap)
-{
- if(bitmap->IsCompressedInRAM()) {
- QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock);
-
- CFbsBitmap *uncompressed = 0;
- QT_TRAP_THROWING(uncompressed = new (ELeave) CFbsBitmap);
-
- if (uncompressed->Create(bitmap->SizeInPixels(), bitmap->DisplayMode()) != KErrNone) {
- delete bitmap;
- bitmap = 0;
- lock.relock();
-
- return bitmap;
- }
-
- lock.relock();
-
- CFbsBitmapDevice* bitmapDevice = 0;
- CFbsBitGc *bitmapGc = 0;
- QT_TRAP_THROWING(bitmapDevice = CFbsBitmapDevice::NewL(uncompressed));
- QT_TRAP_THROWING(bitmapGc = CFbsBitGc::NewL());
- bitmapGc->Activate(bitmapDevice);
-
- bitmapGc->BitBlt(TPoint(), bitmap);
-
- delete bitmapGc;
- delete bitmapDevice;
-
- return uncompressed;
- } else {
- return bitmap;
- }
-}
-
-QPixmap QPixmap::grabWindow(WId winId, int x, int y, int w, int h)
-{
- CWsScreenDevice* screenDevice = S60->screenDevice();
- TSize screenSize = screenDevice->SizeInPixels();
-
- TSize srcSize;
- // Find out if this is one of our windows.
- QSymbianControl *sControl;
- sControl = winId->MopGetObject(sControl);
- if (sControl && sControl->widget()->windowType() == Qt::Desktop) {
- // Grabbing desktop widget
- srcSize = screenSize;
- } else {
- TPoint relativePos = winId->PositionRelativeToScreen();
- x += relativePos.iX;
- y += relativePos.iY;
- srcSize = winId->Size();
- }
-
- TRect srcRect(TPoint(x, y), srcSize);
- // Clip to the screen
- srcRect.Intersection(TRect(screenSize));
-
- if (w > 0 && h > 0) {
- TRect subRect(TPoint(x, y), TSize(w, h));
- // Clip to the subRect
- srcRect.Intersection(subRect);
- }
-
- if (srcRect.IsEmpty())
- return QPixmap();
-
- CFbsBitmap* temporary = createSymbianCFbsBitmap(srcRect.Size(), screenDevice->DisplayMode());
-
- QPixmap pix;
-
- if (temporary && screenDevice->CopyScreenToBitmap(temporary, srcRect) == KErrNone) {
- pix = QPixmap::fromSymbianCFbsBitmap(temporary);
- }
-
- delete temporary;
- return pix;
-}
-
-/*!
- \fn CFbsBitmap *QPixmap::toSymbianCFbsBitmap() const
- \since 4.6
-
- Creates a \c CFbsBitmap that is equivalent to the QPixmap. Internally this
- function will try to duplicate the handle instead of copying the data,
- however in scenarios where this is not possible the data will be copied.
- If the creation fails or the pixmap is null, then this function returns 0.
-
- It is the caller's responsibility to release the \c CFbsBitmap data
- after use either by deleting the bitmap or calling \c Reset().
-
- \warning On S60 3.1 and S60 3.2, semi-transparent pixmaps are always copied
- and not duplicated.
- \warning This function is only available on Symbian OS.
-
- \sa fromSymbianCFbsBitmap()
-*/
-CFbsBitmap *QPixmap::toSymbianCFbsBitmap() const
-{
- QPixmapData *data = pixmapData();
- if (!data || data->isNull())
- return 0;
-
- return reinterpret_cast<CFbsBitmap*>(data->toNativeType(QPixmapData::FbsBitmap));
-}
-
-/*!
- \fn QPixmap QPixmap::fromSymbianCFbsBitmap(CFbsBitmap *bitmap)
- \since 4.6
-
- Creates a QPixmap from a \c CFbsBitmap \a bitmap. Internally this function
- will try to duplicate the bitmap handle instead of copying the data, however
- in scenarios where this is not possible the data will be copied.
- To be sure that QPixmap does not modify your original instance, you should
- make a copy of your \c CFbsBitmap before calling this function.
- If the CFbsBitmap is not valid this function will return a null QPixmap.
- For performance reasons it is recommended to use a \a bitmap with a display
- mode of EColor16MAP or EColor16MU whenever possible.
-
- \warning This function is only available on Symbian OS.
-
- \sa toSymbianCFbsBitmap(), {QPixmap#Pixmap Conversion}{Pixmap Conversion}
-*/
-QPixmap QPixmap::fromSymbianCFbsBitmap(CFbsBitmap *bitmap)
-{
- if (!bitmap)
- return QPixmap();
-
- QScopedPointer<QPixmapData> data(QPixmapData::create(0,0, QPixmapData::PixmapType));
- data->fromNativeType(reinterpret_cast<void*>(bitmap), QPixmapData::FbsBitmap);
- QPixmap pixmap(data.take());
- return pixmap;
-}
-
-QS60PixmapData::QS60PixmapData(PixelType type) : QRasterPixmapData(type),
- symbianBitmapDataAccess(new QSymbianBitmapDataAccess),
- cfbsBitmap(0),
- pengine(0),
- bytes(0),
- formatLocked(false),
- next(0),
- prev(0)
-{
- qt_symbian_register_pixmap(this);
-}
-
-QS60PixmapData::~QS60PixmapData()
-{
- release();
- delete symbianBitmapDataAccess;
- qt_symbian_unregister_pixmap(this);
-}
-
-void QS60PixmapData::resize(int width, int height)
-{
- if (width <= 0 || height <= 0) {
- w = width;
- h = height;
- is_null = true;
-
- release();
- return;
- } else if (!cfbsBitmap) {
- TDisplayMode mode;
- if (pixelType() == BitmapType)
- mode = EGray2;
- else
- mode = EColor16MU;
-
- CFbsBitmap* bitmap = createSymbianCFbsBitmap(TSize(width, height), mode);
- fromSymbianBitmap(bitmap);
- } else {
-
- TSize newSize(width, height);
-
- if(cfbsBitmap->SizeInPixels() != newSize) {
- cfbsBitmap->Resize(TSize(width, height));
- if(pengine) {
- delete pengine;
- pengine = 0;
- }
- }
-
- UPDATE_BUFFER();
- }
-}
-
-void QS60PixmapData::release()
-{
- if (cfbsBitmap) {
- QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock);
- delete cfbsBitmap;
- lock.relock();
- }
-
- delete pengine;
- image = QImage();
- cfbsBitmap = 0;
- pengine = 0;
- bytes = 0;
-}
-
-/*!
- * Takes ownership of bitmap. Used by window surface
- */
-void QS60PixmapData::fromSymbianBitmap(CFbsBitmap* bitmap, bool lockFormat)
-{
- Q_ASSERT(bitmap);
-
- release();
-
- cfbsBitmap = bitmap;
- formatLocked = lockFormat;
-
- setSerialNumber(cfbsBitmap->Handle());
-
- UPDATE_BUFFER();
-
- // Create default palette if needed
- if (cfbsBitmap->DisplayMode() == EGray2) {
- image.setColorCount(2);
- image.setColor(0, QColor(Qt::color0).rgba());
- image.setColor(1, QColor(Qt::color1).rgba());
-
- //Symbian thinks set pixels are white/transparent, Qt thinks they are foreground/solid
- //So invert mono bitmaps so that masks work correctly.
- image.invertPixels();
- } else if (cfbsBitmap->DisplayMode() == EGray256) {
- for (int i=0; i < 256; ++i)
- image.setColor(i, qRgb(i, i, i));
- } else if (cfbsBitmap->DisplayMode() == EColor256) {
- const TColor256Util *palette = TColor256Util::Default();
- for (int i=0; i < 256; ++i)
- image.setColor(i, (QRgb)(palette->Color256(i).Value()));
- }
-}
-
-QImage QS60PixmapData::toImage(const QRect &r) const
-{
- QS60PixmapData *that = const_cast<QS60PixmapData*>(this);
- that->beginDataAccess();
- QImage copy = that->image.copy(r);
- that->endDataAccess();
-
- return copy;
-}
-
-void QS60PixmapData::fromImage(const QImage &img, Qt::ImageConversionFlags flags)
-{
- release();
-
- QImage sourceImage;
-
- if (pixelType() == BitmapType) {
- sourceImage = img.convertToFormat(QImage::Format_MonoLSB);
- } else {
- if (img.depth() == 1) {
- sourceImage = img.hasAlphaChannel()
- ? img.convertToFormat(QImage::Format_ARGB32_Premultiplied)
- : img.convertToFormat(QImage::Format_RGB32);
- } else {
-
- QImage::Format opaqueFormat = QNativeImage::systemFormat();
- QImage::Format alphaFormat = QImage::Format_ARGB32_Premultiplied;
-
- if (!img.hasAlphaChannel()
- || ((flags & Qt::NoOpaqueDetection) == 0
- && !const_cast<QImage &>(img).data_ptr()->checkForAlphaPixels())) {
- sourceImage = img.convertToFormat(opaqueFormat);
- } else {
- sourceImage = img.convertToFormat(alphaFormat);
- }
- }
- }
-
-
- QImage::Format destFormat = sourceImage.format();
- TDisplayMode mode;
- switch (destFormat) {
- case QImage::Format_MonoLSB:
- mode = EGray2;
- break;
- case QImage::Format_RGB32:
- mode = EColor16MU;
- break;
- case QImage::Format_ARGB32_Premultiplied:
- if (S60->supportsPremultipliedAlpha) {
- mode = Q_SYMBIAN_ECOLOR16MAP;
- break;
- } else {
- destFormat = QImage::Format_ARGB32;
- }
- // Fall through intended
- case QImage::Format_ARGB32:
- mode = EColor16MA;
- break;
- case QImage::Format_Invalid:
- return;
- default:
- qWarning("Image format not supported: %d", image.format());
- return;
- }
-
- cfbsBitmap = createSymbianCFbsBitmap(TSize(sourceImage.width(), sourceImage.height()), mode);
- if (!cfbsBitmap) {
- qWarning("Could not create CFbsBitmap");
- release();
- return;
- }
-
- setSerialNumber(cfbsBitmap->Handle());
-
- const uchar *sptr = const_cast<const QImage &>(sourceImage).bits();
- symbianBitmapDataAccess->beginDataAccess(cfbsBitmap);
- uchar *dptr = (uchar*)cfbsBitmap->DataAddress();
- Mem::Copy(dptr, sptr, sourceImage.byteCount());
- symbianBitmapDataAccess->endDataAccess(cfbsBitmap);
-
- UPDATE_BUFFER();
-
- if (destFormat == QImage::Format_MonoLSB) {
- image.setColorCount(2);
- image.setColor(0, QColor(Qt::color0).rgba());
- image.setColor(1, QColor(Qt::color1).rgba());
- } else {
- image.setColorTable(sourceImage.colorTable());
- }
-}
-
-void QS60PixmapData::copy(const QPixmapData *data, const QRect &rect)
-{
- const QS60PixmapData *s60Data = static_cast<const QS60PixmapData*>(data);
- fromImage(s60Data->toImage(rect), Qt::AutoColor | Qt::OrderedAlphaDither);
-}
-
-bool QS60PixmapData::scroll(int dx, int dy, const QRect &rect)
-{
- beginDataAccess();
- bool res = QRasterPixmapData::scroll(dx, dy, rect);
- endDataAccess();
- return res;
-}
-
-int QS60PixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const
-{
- if (!cfbsBitmap)
- return 0;
-
- switch (metric) {
- case QPaintDevice::PdmWidth:
- return cfbsBitmap->SizeInPixels().iWidth;
- case QPaintDevice::PdmHeight:
- return cfbsBitmap->SizeInPixels().iHeight;
- case QPaintDevice::PdmWidthMM:
- return qRound(cfbsBitmap->SizeInPixels().iWidth * 25.4 / qt_defaultDpiX());
- case QPaintDevice::PdmHeightMM:
- return qRound(cfbsBitmap->SizeInPixels().iHeight * 25.4 / qt_defaultDpiY());
- case QPaintDevice::PdmNumColors:
- return TDisplayModeUtils::NumDisplayModeColors(cfbsBitmap->DisplayMode());
- case QPaintDevice::PdmDpiX:
- case QPaintDevice::PdmPhysicalDpiX:
- return qt_defaultDpiX();
- case QPaintDevice::PdmDpiY:
- case QPaintDevice::PdmPhysicalDpiY:
- return qt_defaultDpiY();
- case QPaintDevice::PdmDepth:
- return TDisplayModeUtils::NumDisplayModeBitsPerPixel(cfbsBitmap->DisplayMode());
- default:
- qWarning("QPixmap::metric: Invalid metric command");
- }
- return 0;
-
-}
-
-void QS60PixmapData::fill(const QColor &color)
-{
- if (color.alpha() != 255) {
- QImage im(width(), height(), QImage::Format_ARGB32_Premultiplied);
- im.fill(PREMUL(color.rgba()));
- release();
- fromImage(im, Qt::AutoColor | Qt::OrderedAlphaDither);
- } else {
- beginDataAccess();
- QRasterPixmapData::fill(color);
- endDataAccess();
- }
-}
-
-void QS60PixmapData::setMask(const QBitmap &mask)
-{
- if (mask.size().isEmpty()) {
- if (image.depth() != 1) {
- QImage newImage = image.convertToFormat(QImage::Format_RGB32);
- release();
- fromImage(newImage, Qt::AutoColor | Qt::OrderedAlphaDither);
- }
- } else if (image.depth() == 1) {
- beginDataAccess();
- QRasterPixmapData::setMask(mask);
- endDataAccess();
- } else {
- const int w = image.width();
- const int h = image.height();
-
- const QImage imageMask = mask.toImage().convertToFormat(QImage::Format_MonoLSB);
- QImage newImage = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
- for (int y = 0; y < h; ++y) {
- const uchar *mscan = imageMask.scanLine(y);
- QRgb *tscan = (QRgb *)newImage.scanLine(y);
- for (int x = 0; x < w; ++x) {
- if (!(mscan[x>>3] & qt_pixmap_bit_mask[x&7]))
- tscan[x] = 0;
- }
- }
- release();
- fromImage(newImage, Qt::AutoColor | Qt::OrderedAlphaDither);
- }
-}
-
-void QS60PixmapData::setAlphaChannel(const QPixmap &alphaChannel)
-{
- QImage img(toImage());
- img.setAlphaChannel(alphaChannel.toImage());
- release();
- fromImage(img, Qt::OrderedDither | Qt::OrderedAlphaDither);
-}
-
-QImage QS60PixmapData::toImage() const
-{
- return toImage(QRect());
-}
-
-QPaintEngine* QS60PixmapData::paintEngine() const
-{
- if (!pengine) {
- QS60PixmapData *that = const_cast<QS60PixmapData*>(this);
- that->pengine = new QS60PaintEngine(&that->image, that);
- }
- return pengine;
-}
-
-void QS60PixmapData::beginDataAccess()
-{
- if(!cfbsBitmap)
- return;
-
- symbianBitmapDataAccess->beginDataAccess(cfbsBitmap);
-
- uchar* newBytes = (uchar*)cfbsBitmap->DataAddress();
-
- TSize size = cfbsBitmap->SizeInPixels();
-
- if (newBytes == bytes && image.width() == size.iWidth && image.height() == size.iHeight)
- return;
-
- bytes = newBytes;
- TDisplayMode mode = cfbsBitmap->DisplayMode();
- QImage::Format format = qt_TDisplayMode2Format(mode);
- // On S60 3.1, premultiplied alpha pixels are stored in a bitmap with 16MA type.
- // S60 window surface needs backing store pixmap for transparent window in ARGB32 format.
- // In that case formatLocked is true.
- if (!formatLocked && format == QImage::Format_ARGB32)
- format = QImage::Format_ARGB32_Premultiplied; // pixel data is actually in premultiplied format
-
- QVector<QRgb> savedColorTable;
- if (!image.isNull())
- savedColorTable = image.colorTable();
-
- image = QImage(bytes, size.iWidth, size.iHeight, format);
-
- // Restore the palette or create a default
- if (!savedColorTable.isEmpty()) {
- image.setColorTable(savedColorTable);
- }
-
- w = size.iWidth;
- h = size.iHeight;
- d = image.depth();
- is_null = (w <= 0 || h <= 0);
-
- if (pengine) {
- QS60PaintEngine *engine = static_cast<QS60PaintEngine *>(pengine);
- engine->prepare(&image);
- }
-}
-
-void QS60PixmapData::endDataAccess(bool readOnly) const
-{
- Q_UNUSED(readOnly);
-
- if(!cfbsBitmap)
- return;
-
- symbianBitmapDataAccess->endDataAccess(cfbsBitmap);
-}
-
-/*!
- \since 4.6
-
- Returns a QPixmap that wraps given \a sgImage graphics resource.
- The data should be valid even when original RSgImage handle has been
- closed.
-
- \warning This function is only available on Symbian OS.
-
- \sa toSymbianRSgImage(), {QPixmap#Pixmap Conversion}{Pixmap Conversion}
-*/
-
-QPixmap QPixmap::fromSymbianRSgImage(RSgImage *sgImage)
-{
- // It is expected that RSgImage will
- // CURRENTLY be used in conjuction with
- // OpenVG graphics system
- //
- // Surely things might change in future
-
- if (!sgImage)
- return QPixmap();
-
- QScopedPointer<QPixmapData> data(QPixmapData::create(0,0, QPixmapData::PixmapType));
- data->fromNativeType(reinterpret_cast<void*>(sgImage), QPixmapData::SgImage);
- QPixmap pixmap(data.take());
- return pixmap;
-}
-
-/*!
-\since 4.6
-
-Returns a \c RSgImage that is equivalent to the QPixmap by copying the data.
-
-It is the caller's responsibility to close/delete the \c RSgImage after use.
-
-\warning This function is only available on Symbian OS.
-
-\sa fromSymbianRSgImage()
-*/
-
-RSgImage *QPixmap::toSymbianRSgImage() const
-{
- // It is expected that RSgImage will
- // CURRENTLY be used in conjuction with
- // OpenVG graphics system
- //
- // Surely things might change in future
-
- if (isNull())
- return 0;
-
- RSgImage *sgImage = reinterpret_cast<RSgImage*>(pixmapData()->toNativeType(QPixmapData::SgImage));
-
- return sgImage;
-}
-
-void* QS60PixmapData::toNativeType(NativeType type)
-{
- if (type == QPixmapData::SgImage) {
- return 0;
- } else if (type == QPixmapData::FbsBitmap) {
-
- if (isNull() || !cfbsBitmap)
- return 0;
-
- bool convertToArgb32 = false;
- bool needsCopy = false;
-
- if (!(S60->supportsPremultipliedAlpha)) {
- // Convert argb32_premultiplied to argb32 since Symbian 9.2 does
- // not support premultipied format.
-
- if (image.format() == QImage::Format_ARGB32_Premultiplied) {
- needsCopy = true;
- convertToArgb32 = true;
- }
- }
-
- CFbsBitmap *bitmap = 0;
-
- TDisplayMode displayMode = cfbsBitmap->DisplayMode();
-
- if(displayMode == EGray2) {
- //Symbian thinks set pixels are white/transparent, Qt thinks they are foreground/solid
- //So invert mono bitmaps so that masks work correctly.
- beginDataAccess();
- image.invertPixels();
- endDataAccess();
- needsCopy = true;
- }
-
- if (needsCopy) {
- QImage source;
-
- if (convertToArgb32) {
- beginDataAccess();
- source = image.convertToFormat(QImage::Format_ARGB32);
- endDataAccess();
- displayMode = EColor16MA;
- } else {
- source = image;
- }
-
- CFbsBitmap *newBitmap = createSymbianCFbsBitmap(TSize(source.width(), source.height()), displayMode);
- const uchar *sptr = source.bits();
- symbianBitmapDataAccess->beginDataAccess(newBitmap);
-
- uchar *dptr = (uchar*)newBitmap->DataAddress();
- Mem::Copy(dptr, sptr, source.byteCount());
-
- symbianBitmapDataAccess->endDataAccess(newBitmap);
-
- bitmap = newBitmap;
- } else {
-
- QT_TRAP_THROWING(bitmap = new (ELeave) CFbsBitmap);
-
- TInt err = bitmap->Duplicate(cfbsBitmap->Handle());
- if (err != KErrNone) {
- qWarning("Could not duplicate CFbsBitmap");
- delete bitmap;
- bitmap = 0;
- }
- }
-
- if(displayMode == EGray2) {
- // restore pixels
- beginDataAccess();
- image.invertPixels();
- endDataAccess();
- }
-
- return reinterpret_cast<void*>(bitmap);
-
- }
-
- return 0;
-}
-
-void QS60PixmapData::fromNativeType(void* pixmap, NativeType nativeType)
-{
- if (nativeType == QPixmapData::SgImage) {
- return;
- } else if (nativeType == QPixmapData::FbsBitmap && pixmap) {
-
- CFbsBitmap *bitmap = reinterpret_cast<CFbsBitmap*>(pixmap);
-
- bool deleteSourceBitmap = false;
- bool needsCopy = false;
-
-#ifdef Q_SYMBIAN_HAS_EXTENDED_BITMAP_TYPE
-
- // Rasterize extended bitmaps
-
- TUid extendedBitmapType = bitmap->ExtendedBitmapType();
- if (extendedBitmapType != KNullUid) {
- CFbsBitmap *rasterBitmap = createSymbianCFbsBitmap(bitmap->SizeInPixels(), EColor16MA);
-
- CFbsBitmapDevice *rasterBitmapDev = 0;
- QT_TRAP_THROWING(rasterBitmapDev = CFbsBitmapDevice::NewL(rasterBitmap));
-
- CFbsBitGc *rasterBitmapGc = 0;
- TInt err = rasterBitmapDev->CreateContext(rasterBitmapGc);
- if (err != KErrNone) {
- delete rasterBitmap;
- delete rasterBitmapDev;
- rasterBitmapDev = 0;
- return;
- }
-
- rasterBitmapGc->BitBlt(TPoint( 0, 0), bitmap);
-
- bitmap = rasterBitmap;
-
- delete rasterBitmapDev;
- delete rasterBitmapGc;
-
- rasterBitmapDev = 0;
- rasterBitmapGc = 0;
-
- deleteSourceBitmap = true;
- }
-#endif
-
-
- deleteSourceBitmap = bitmap->IsCompressedInRAM();
- CFbsBitmap *sourceBitmap = uncompress(bitmap);
-
- TDisplayMode displayMode = sourceBitmap->DisplayMode();
- QImage::Format format = qt_TDisplayMode2Format(displayMode);
-
- QImage::Format opaqueFormat = QNativeImage::systemFormat();
- QImage::Format alphaFormat = QImage::Format_ARGB32_Premultiplied;
-
- if (format != opaqueFormat && format != alphaFormat && format != QImage::Format_MonoLSB)
- needsCopy = true;
-
-
- type = (format != QImage::Format_MonoLSB)
- ? QPixmapData::PixmapType
- : QPixmapData::BitmapType;
-
- if (needsCopy) {
-
- TSize size = sourceBitmap->SizeInPixels();
- int bytesPerLine = sourceBitmap->ScanLineLength(size.iWidth, displayMode);
-
- QSymbianBitmapDataAccess da;
- da.beginDataAccess(sourceBitmap);
- uchar *bytes = (uchar*)sourceBitmap->DataAddress();
- QImage img = QImage(bytes, size.iWidth, size.iHeight, bytesPerLine, format);
- img = img.copy();
- da.endDataAccess(sourceBitmap);
-
- if(displayMode == EGray2) {
- //Symbian thinks set pixels are white/transparent, Qt thinks they are foreground/solid
- //So invert mono bitmaps so that masks work correctly.
- img.invertPixels();
- } else if(displayMode == EColor16M) {
- img = img.rgbSwapped(); // EColor16M is BGR
- }
-
- fromImage(img, Qt::AutoColor);
-
- if(deleteSourceBitmap)
- delete sourceBitmap;
- } else {
- CFbsBitmap* duplicate = 0;
- QT_TRAP_THROWING(duplicate = new (ELeave) CFbsBitmap);
-
- TInt err = duplicate->Duplicate(sourceBitmap->Handle());
- if (err != KErrNone) {
- qWarning("Could not duplicate CFbsBitmap");
-
- if(deleteSourceBitmap)
- delete sourceBitmap;
-
- delete duplicate;
- return;
- }
-
- fromSymbianBitmap(duplicate);
-
- if(deleteSourceBitmap)
- delete sourceBitmap;
- }
- }
-}
-
-void QS60PixmapData::convertToDisplayMode(int mode)
-{
- const TDisplayMode displayMode = static_cast<TDisplayMode>(mode);
- if (!cfbsBitmap || cfbsBitmap->DisplayMode() == displayMode)
- return;
- if (image.depth() != TDisplayModeUtils::NumDisplayModeBitsPerPixel(displayMode)) {
- qWarning("Cannot convert display mode due to depth mismatch");
- return;
- }
-
- const TSize size = cfbsBitmap->SizeInPixels();
- QScopedPointer<CFbsBitmap> newBitmap(createSymbianCFbsBitmap(size, displayMode));
-
- const uchar *sptr = const_cast<const QImage &>(image).bits();
- symbianBitmapDataAccess->beginDataAccess(newBitmap.data());
- uchar *dptr = (uchar*)newBitmap->DataAddress();
- Mem::Copy(dptr, sptr, image.byteCount());
- symbianBitmapDataAccess->endDataAccess(newBitmap.data());
-
- QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock);
- delete cfbsBitmap;
- lock.relock();
- cfbsBitmap = newBitmap.take();
- setSerialNumber(cfbsBitmap->Handle());
- UPDATE_BUFFER();
-}
-
-QPixmapData *QS60PixmapData::createCompatiblePixmapData() const
-{
- return new QS60PixmapData(pixelType());
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/image/qpixmap_s60_p.h b/src/gui/image/qpixmap_s60_p.h
deleted file mode 100644
index e48154963b..0000000000
--- a/src/gui/image/qpixmap_s60_p.h
+++ /dev/null
@@ -1,141 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPIXMAPDATA_S60_P_H
-#define QPIXMAPDATA_S60_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtGui/private/qpixmap_raster_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class CFbsBitmap;
-class CFbsBitmapDevice;
-class CFbsBitGc;
-
-class QSymbianBitmapDataAccess;
-
-class QSymbianFbsHeapLock
-{
-public:
-
- enum LockAction {
- Unlock
- };
-
- explicit QSymbianFbsHeapLock(LockAction a);
- ~QSymbianFbsHeapLock();
- void relock();
-
-private:
-
- LockAction action;
- bool wasLocked;
-};
-
-class QS60PixmapData : public QRasterPixmapData
-{
-public:
- QS60PixmapData(PixelType type);
- ~QS60PixmapData();
-
- QPixmapData *createCompatiblePixmapData() const;
-
- void resize(int width, int height);
- void fromImage(const QImage &image, Qt::ImageConversionFlags flags);
- void copy(const QPixmapData *data, const QRect &rect);
- bool scroll(int dx, int dy, const QRect &rect);
-
- int metric(QPaintDevice::PaintDeviceMetric metric) const;
- void fill(const QColor &color);
- void setMask(const QBitmap &mask);
- void setAlphaChannel(const QPixmap &alphaChannel);
- QImage toImage() const;
- QPaintEngine* paintEngine() const;
-
- void beginDataAccess();
- void endDataAccess(bool readOnly=false) const;
-
- void* toNativeType(NativeType type);
- void fromNativeType(void* pixmap, NativeType type);
-
- void convertToDisplayMode(int mode);
-
-private:
- void release();
- void fromSymbianBitmap(CFbsBitmap* bitmap, bool lockFormat=false);
- QImage toImage(const QRect &r) const;
-
- QSymbianBitmapDataAccess *symbianBitmapDataAccess;
-
- CFbsBitmap *cfbsBitmap;
- QPaintEngine *pengine;
- uchar* bytes;
-
- bool formatLocked;
-
- QS60PixmapData *next;
- QS60PixmapData *prev;
-
- static void qt_symbian_register_pixmap(QS60PixmapData *pd);
- static void qt_symbian_unregister_pixmap(QS60PixmapData *pd);
- static void qt_symbian_release_pixmaps();
-
- friend class QPixmap;
- friend class QS60WindowSurface;
- friend class QS60PaintEngine;
- friend class QS60Data;
-};
-
-QT_END_NAMESPACE
-
-#endif // QPIXMAPDATA_S60_P_H
-
diff --git a/src/gui/image/qpixmap_win.cpp b/src/gui/image/qpixmap_win.cpp
deleted file mode 100644
index 0aaf30b8fd..0000000000
--- a/src/gui/image/qpixmap_win.cpp
+++ /dev/null
@@ -1,477 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qpixmap.h"
-#include "qpixmap_raster_p.h"
-
-#include "qbitmap.h"
-#include "qimage.h"
-#include "qwidget.h"
-#include "qpainter.h"
-#include "qdatastream.h"
-#include "qbuffer.h"
-#include "qapplication.h"
-#include "qevent.h"
-#include "qfile.h"
-#include "qfileinfo.h"
-#include "qdatetime.h"
-#include "qpixmapcache.h"
-#include "qimagereader.h"
-#include "qimagewriter.h"
-#include "qdebug.h"
-#include "qt_windows.h"
-
-#if defined(Q_WS_WINCE)
-#include <winbase.h>
-#include "qguifunctions_wince.h"
-extern bool qt_wince_is_high_dpi();
-extern bool qt_wince_is_pocket_pc();
-#endif
-
-#ifndef CAPTUREBLT
-#define CAPTUREBLT ((DWORD)0x40000000)
-#endif
-
-QT_BEGIN_NAMESPACE
-
-QPixmap QPixmap::grabWindow(WId winId, int x, int y, int w, int h )
-{
- RECT r;
- GetClientRect(winId, &r);
-
- if (w < 0) w = r.right - r.left;
- if (h < 0) h = r.bottom - r.top;
-
-#ifdef Q_WS_WINCE_WM
- if (qt_wince_is_pocket_pc()) {
- QWidget *widget = QWidget::find(winId);
- if (qobject_cast<QDesktopWidget *>(widget)) {
- RECT rect = {0,0,0,0};
- AdjustWindowRectEx(&rect, WS_BORDER | WS_CAPTION, FALSE, 0);
- int magicNumber = qt_wince_is_high_dpi() ? 4 : 2;
- y += rect.top - magicNumber;
- }
- }
-#endif
-
- // Create and setup bitmap
- HDC display_dc = GetDC(0);
- HDC bitmap_dc = CreateCompatibleDC(display_dc);
- HBITMAP bitmap = CreateCompatibleBitmap(display_dc, w, h);
- HGDIOBJ null_bitmap = SelectObject(bitmap_dc, bitmap);
-
- // copy data
- HDC window_dc = GetDC(winId);
- BitBlt(bitmap_dc, 0, 0, w, h, window_dc, x, y, SRCCOPY
-#ifndef Q_WS_WINCE
- | CAPTUREBLT
-#endif
- );
-
- // clean up all but bitmap
- ReleaseDC(winId, window_dc);
- SelectObject(bitmap_dc, null_bitmap);
- DeleteDC(bitmap_dc);
-
- QPixmap pixmap = QPixmap::fromWinHBITMAP(bitmap);
-
- DeleteObject(bitmap);
- ReleaseDC(0, display_dc);
-
- return pixmap;
-}
-
-HBITMAP QPixmap::toWinHBITMAP(HBitmapFormat format) const
-{
- if (isNull())
- return 0;
-
- HBITMAP bitmap = 0;
- if (data->classId() == QPixmapData::RasterClass) {
- QRasterPixmapData* d = static_cast<QRasterPixmapData*>(data.data());
- int w = d->image.width();
- int h = d->image.height();
-
- HDC display_dc = GetDC(0);
-
- // Define the header
- BITMAPINFO bmi;
- memset(&bmi, 0, sizeof(bmi));
- bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- bmi.bmiHeader.biWidth = w;
- bmi.bmiHeader.biHeight = -h;
- bmi.bmiHeader.biPlanes = 1;
- bmi.bmiHeader.biBitCount = 32;
- bmi.bmiHeader.biCompression = BI_RGB;
- bmi.bmiHeader.biSizeImage = w * h * 4;
-
- // Create the pixmap
- uchar *pixels = 0;
- bitmap = CreateDIBSection(display_dc, &bmi, DIB_RGB_COLORS, (void **) &pixels, 0, 0);
- ReleaseDC(0, display_dc);
- if (!bitmap) {
- qErrnoWarning("QPixmap::toWinHBITMAP(), failed to create dibsection");
- return 0;
- }
- if (!pixels) {
- qErrnoWarning("QPixmap::toWinHBITMAP(), did not allocate pixel data");
- return 0;
- }
-
- // Copy over the data
- QImage::Format imageFormat = QImage::Format_ARGB32;
- if (format == NoAlpha)
- imageFormat = QImage::Format_RGB32;
- else if (format == PremultipliedAlpha)
- imageFormat = QImage::Format_ARGB32_Premultiplied;
- const QImage image = d->image.convertToFormat(imageFormat);
- int bytes_per_line = w * 4;
- for (int y=0; y<h; ++y)
- memcpy(pixels + y * bytes_per_line, image.scanLine(y), bytes_per_line);
-
- } else {
- QPixmapData *data = new QRasterPixmapData(depth() == 1 ?
- QPixmapData::BitmapType : QPixmapData::PixmapType);
- data->fromImage(toImage(), Qt::AutoColor);
- return QPixmap(data).toWinHBITMAP(format);
- }
- return bitmap;
-}
-
-QPixmap QPixmap::fromWinHBITMAP(HBITMAP bitmap, HBitmapFormat format)
-{
- // Verify size
- BITMAP bitmap_info;
- memset(&bitmap_info, 0, sizeof(BITMAP));
-
- int res = GetObject(bitmap, sizeof(BITMAP), &bitmap_info);
- if (!res) {
- qErrnoWarning("QPixmap::fromWinHBITMAP(), failed to get bitmap info");
- return QPixmap();
- }
- int w = bitmap_info.bmWidth;
- int h = bitmap_info.bmHeight;
-
- BITMAPINFO bmi;
- memset(&bmi, 0, sizeof(bmi));
- bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- bmi.bmiHeader.biWidth = w;
- bmi.bmiHeader.biHeight = -h;
- bmi.bmiHeader.biPlanes = 1;
- bmi.bmiHeader.biBitCount = 32;
- bmi.bmiHeader.biCompression = BI_RGB;
- bmi.bmiHeader.biSizeImage = w * h * 4;
-
- QImage result;
- // Get bitmap bits
- uchar *data = (uchar *) qMalloc(bmi.bmiHeader.biSizeImage);
-
- HDC display_dc = GetDC(0);
- if (GetDIBits(display_dc, bitmap, 0, h, data, &bmi, DIB_RGB_COLORS)) {
-
- QImage::Format imageFormat = QImage::Format_ARGB32_Premultiplied;
- uint mask = 0;
- if (format == NoAlpha) {
- imageFormat = QImage::Format_RGB32;
- mask = 0xff000000;
- }
-
- // Create image and copy data into image.
- QImage image(w, h, imageFormat);
- if (!image.isNull()) { // failed to alloc?
- int bytes_per_line = w * sizeof(QRgb);
- for (int y=0; y<h; ++y) {
- QRgb *dest = (QRgb *) image.scanLine(y);
- const QRgb *src = (const QRgb *) (data + y * bytes_per_line);
- for (int x=0; x<w; ++x) {
- const uint pixel = src[x];
- if ((pixel & 0xff000000) == 0 && (pixel & 0x00ffffff) != 0)
- dest[x] = pixel | 0xff000000;
- else
- dest[x] = pixel | mask;
- }
- }
- }
- result = image;
- } else {
- qWarning("QPixmap::fromWinHBITMAP(), failed to get bitmap bits");
- }
- ReleaseDC(0, display_dc);
- qFree(data);
- return fromImage(result);
-}
-
-HBITMAP qt_createIconMask(const QBitmap &bitmap)
-{
- QImage bm = bitmap.toImage().convertToFormat(QImage::Format_Mono);
- int w = bm.width();
- int h = bm.height();
- int bpl = ((w+15)/16)*2; // bpl, 16 bit alignment
- uchar *bits = new uchar[bpl*h];
- bm.invertPixels();
- for (int y=0; y<h; y++)
- memcpy(bits+y*bpl, bm.scanLine(y), bpl);
- HBITMAP hbm = CreateBitmap(w, h, 1, 1, bits);
- delete [] bits;
- return hbm;
-}
-
-HICON QPixmap::toWinHICON() const
-{
- QBitmap maskBitmap = mask();
- if (maskBitmap.isNull()) {
- maskBitmap= QBitmap(size());
- maskBitmap.fill(Qt::color1);
- }
-
- ICONINFO ii;
- ii.fIcon = true;
- ii.hbmMask = qt_createIconMask(maskBitmap);
- ii.hbmColor = toWinHBITMAP(QPixmap::Alpha);
- ii.xHotspot = 0;
- ii.yHotspot = 0;
-
- HICON hIcon = CreateIconIndirect(&ii);
-
- DeleteObject(ii.hbmColor);
- DeleteObject(ii.hbmMask);
-
- return hIcon;
-}
-
-#ifdef Q_WS_WIN
-#ifndef Q_WS_WINCE
-
-static QImage qt_fromWinHBITMAP(HDC hdc, HBITMAP bitmap, int w, int h)
-{
- BITMAPINFO bmi;
- memset(&bmi, 0, sizeof(bmi));
- bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- bmi.bmiHeader.biWidth = w;
- bmi.bmiHeader.biHeight = -h;
- bmi.bmiHeader.biPlanes = 1;
- bmi.bmiHeader.biBitCount = 32;
- bmi.bmiHeader.biCompression = BI_RGB;
- bmi.bmiHeader.biSizeImage = w * h * 4;
-
- QImage image(w, h, QImage::Format_ARGB32_Premultiplied);
- if (image.isNull())
- return image;
-
- // Get bitmap bits
- uchar *data = (uchar *) qMalloc(bmi.bmiHeader.biSizeImage);
-
- if (GetDIBits(hdc, bitmap, 0, h, data, &bmi, DIB_RGB_COLORS)) {
- // Create image and copy data into image.
- for (int y=0; y<h; ++y) {
- void *dest = (void *) image.scanLine(y);
- void *src = data + y * image.bytesPerLine();
- memcpy(dest, src, image.bytesPerLine());
- }
- } else {
- qWarning("qt_fromWinHBITMAP(), failed to get bitmap bits");
- }
- qFree(data);
-
- return image;
-}
-
-QPixmap QPixmap::fromWinHICON(HICON icon)
-{
- bool foundAlpha = false;
- HDC screenDevice = GetDC(0);
- HDC hdc = CreateCompatibleDC(screenDevice);
- ReleaseDC(0, screenDevice);
-
- ICONINFO iconinfo;
- bool result = GetIconInfo(icon, &iconinfo); //x and y Hotspot describes the icon center
- if (!result)
- qWarning("QPixmap::fromWinHICON(), failed to GetIconInfo()");
-
- int w = iconinfo.xHotspot * 2;
- int h = iconinfo.yHotspot * 2;
-
- BITMAPINFOHEADER bitmapInfo;
- bitmapInfo.biSize = sizeof(BITMAPINFOHEADER);
- bitmapInfo.biWidth = w;
- bitmapInfo.biHeight = h;
- bitmapInfo.biPlanes = 1;
- bitmapInfo.biBitCount = 32;
- bitmapInfo.biCompression = BI_RGB;
- bitmapInfo.biSizeImage = 0;
- bitmapInfo.biXPelsPerMeter = 0;
- bitmapInfo.biYPelsPerMeter = 0;
- bitmapInfo.biClrUsed = 0;
- bitmapInfo.biClrImportant = 0;
- DWORD* bits;
-
- HBITMAP winBitmap = CreateDIBSection(hdc, (BITMAPINFO*)&bitmapInfo, DIB_RGB_COLORS, (VOID**)&bits, NULL, 0);
- HGDIOBJ oldhdc = (HBITMAP)SelectObject(hdc, winBitmap);
- DrawIconEx( hdc, 0, 0, icon, iconinfo.xHotspot * 2, iconinfo.yHotspot * 2, 0, 0, DI_NORMAL);
- QImage image = qt_fromWinHBITMAP(hdc, winBitmap, w, h);
-
- for (int y = 0 ; y < h && !foundAlpha ; y++) {
- QRgb *scanLine= reinterpret_cast<QRgb *>(image.scanLine(y));
- for (int x = 0; x < w ; x++) {
- if (qAlpha(scanLine[x]) != 0) {
- foundAlpha = true;
- break;
- }
- }
- }
- if (!foundAlpha) {
- //If no alpha was found, we use the mask to set alpha values
- DrawIconEx( hdc, 0, 0, icon, w, h, 0, 0, DI_MASK);
- QImage mask = qt_fromWinHBITMAP(hdc, winBitmap, w, h);
-
- for (int y = 0 ; y < h ; y++){
- QRgb *scanlineImage = reinterpret_cast<QRgb *>(image.scanLine(y));
- QRgb *scanlineMask = mask.isNull() ? 0 : reinterpret_cast<QRgb *>(mask.scanLine(y));
- for (int x = 0; x < w ; x++){
- if (scanlineMask && qRed(scanlineMask[x]) != 0)
- scanlineImage[x] = 0; //mask out this pixel
- else
- scanlineImage[x] |= 0xff000000; // set the alpha channel to 255
- }
- }
- }
- //dispose resources created by iconinfo call
- DeleteObject(iconinfo.hbmMask);
- DeleteObject(iconinfo.hbmColor);
-
- SelectObject(hdc, oldhdc); //restore state
- DeleteObject(winBitmap);
- DeleteDC(hdc);
- return QPixmap::fromImage(image);
-}
-#else //ifndef Q_WS_WINCE
-QPixmap QPixmap::fromWinHICON(HICON icon)
-{
- HDC screenDevice = GetDC(0);
- HDC hdc = CreateCompatibleDC(screenDevice);
- ReleaseDC(0, screenDevice);
-
- ICONINFO iconinfo;
- bool result = GetIconInfo(icon, &iconinfo);
- if (!result)
- qWarning("QPixmap::fromWinHICON(), failed to GetIconInfo()");
-
- int w = 0;
- int h = 0;
- if (!iconinfo.xHotspot || !iconinfo.yHotspot) {
- // We could not retrieve the icon size via GetIconInfo,
- // so we try again using the icon bitmap.
- BITMAP bm;
- int result = GetObject(iconinfo.hbmColor, sizeof(BITMAP), &bm);
- if (!result) result = GetObject(iconinfo.hbmMask, sizeof(BITMAP), &bm);
- if (!result) {
- qWarning("QPixmap::fromWinHICON(), failed to retrieve icon size");
- return QPixmap();
- }
- w = bm.bmWidth;
- h = bm.bmHeight;
- } else {
- // x and y Hotspot describes the icon center
- w = iconinfo.xHotspot * 2;
- h = iconinfo.yHotspot * 2;
- }
- const DWORD dwImageSize = w * h * 4;
-
- BITMAPINFO bmi;
- memset(&bmi, 0, sizeof(bmi));
- bmi.bmiHeader.biSize = sizeof(BITMAPINFO);
- bmi.bmiHeader.biWidth = w;
- bmi.bmiHeader.biHeight = -h;
- bmi.bmiHeader.biPlanes = 1;
- bmi.bmiHeader.biBitCount = 32;
- bmi.bmiHeader.biCompression = BI_RGB;
- bmi.bmiHeader.biSizeImage = dwImageSize;
-
- uchar* bits;
-
- HBITMAP winBitmap = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, (void**) &bits, 0, 0);
- if (winBitmap )
- memset(bits, 0xff, dwImageSize);
- if (!winBitmap) {
- qWarning("QPixmap::fromWinHICON(), failed to CreateDIBSection()");
- return QPixmap();
- }
-
- HGDIOBJ oldhdc = (HBITMAP)SelectObject(hdc, winBitmap);
- if (!DrawIconEx( hdc, 0, 0, icon, w, h, 0, 0, DI_NORMAL))
- qWarning("QPixmap::fromWinHICON(), failed to DrawIcon()");
-
- uint mask = 0xff000000;
- // Create image and copy data into image.
- QImage image(w, h, QImage::Format_ARGB32);
-
- if (!image.isNull()) { // failed to alloc?
- int bytes_per_line = w * sizeof(QRgb);
- for (int y=0; y < h; ++y) {
- QRgb *dest = (QRgb *) image.scanLine(y);
- const QRgb *src = (const QRgb *) (bits + y * bytes_per_line);
- for (int x=0; x < w; ++x) {
- dest[x] = src[x];
- }
- }
- }
- if (!DrawIconEx( hdc, 0, 0, icon, w, h, 0, 0, DI_MASK))
- qWarning("QPixmap::fromWinHICON(), failed to DrawIcon()");
- if (!image.isNull()) { // failed to alloc?
- int bytes_per_line = w * sizeof(QRgb);
- for (int y=0; y < h; ++y) {
- QRgb *dest = (QRgb *) image.scanLine(y);
- const QRgb *src = (const QRgb *) (bits + y * bytes_per_line);
- for (int x=0; x < w; ++x) {
- if (!src[x])
- dest[x] = dest[x] | mask;
- }
- }
- }
- SelectObject(hdc, oldhdc); //restore state
- DeleteObject(winBitmap);
- DeleteDC(hdc);
- return QPixmap::fromImage(image);
-}
-#endif //ifndef Q_WS_WINCE
-#endif //ifdef Q_WS_WIN
-
-QT_END_NAMESPACE
diff --git a/src/gui/image/qpixmap_x11.cpp b/src/gui/image/qpixmap_x11.cpp
deleted file mode 100644
index 77c2a2a9d9..0000000000
--- a/src/gui/image/qpixmap_x11.cpp
+++ /dev/null
@@ -1,2419 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-// Uncomment the next line to enable the MIT Shared Memory extension
-//
-// WARNING: This has some problems:
-//
-// 1. Consumes a 800x600 pixmap
-// 2. Qt does not handle the ShmCompletion message, so you will
-// get strange effects if you xForm() repeatedly.
-//
-// #define QT_MITSHM
-
-#if defined(Q_OS_WIN32) && defined(QT_MITSHM)
-#undef QT_MITSHM
-#endif
-
-#include "qplatformdefs.h"
-
-#include "qdebug.h"
-#include "qiodevice.h"
-#include "qpixmap_x11_p.h"
-#include "qbitmap.h"
-#include "qcolormap.h"
-#include "qimage.h"
-#include "qmatrix.h"
-#include "qapplication.h"
-#include <private/qpaintengine_x11_p.h>
-#include <private/qt_x11_p.h>
-#include "qx11info_x11.h"
-#include <private/qdrawhelper_p.h>
-#include <private/qimage_p.h>
-#include <private/qimagepixmapcleanuphooks_p.h>
-
-#include <stdlib.h>
-
-#if defined(Q_CC_MIPS)
-# define for if(0){}else for
-#endif
-
-QT_BEGIN_NAMESPACE
-
-QPixmap qt_toX11Pixmap(const QImage &image)
-{
- QPixmapData *data =
- new QX11PixmapData(image.depth() == 1
- ? QPixmapData::BitmapType
- : QPixmapData::PixmapType);
-
- data->fromImage(image, Qt::AutoColor);
-
- return QPixmap(data);
-}
-
-QPixmap qt_toX11Pixmap(const QPixmap &pixmap)
-{
- if (pixmap.isNull())
- return QPixmap();
-
- if (QPixmap(pixmap).data_ptr()->classId() == QPixmapData::X11Class)
- return pixmap;
-
- return qt_toX11Pixmap(pixmap.toImage());
-}
-
-// For thread-safety:
-// image->data does not belong to X11, so we must free it ourselves.
-
-inline static void qSafeXDestroyImage(XImage *x)
-{
- if (x->data) {
- free(x->data);
- x->data = 0;
- }
- XDestroyImage(x);
-}
-
-QBitmap QX11PixmapData::mask_to_bitmap(int screen) const
-{
- if (!x11_mask)
- return QBitmap();
- QPixmap::x11SetDefaultScreen(screen);
- QBitmap bm(w, h);
- GC gc = XCreateGC(X11->display, bm.handle(), 0, 0);
- XCopyArea(X11->display, x11_mask, bm.handle(), gc, 0, 0,
- bm.data->width(), bm.data->height(), 0, 0);
- XFreeGC(X11->display, gc);
- return bm;
-}
-
-Qt::HANDLE QX11PixmapData::bitmap_to_mask(const QBitmap &bitmap, int screen)
-{
- if (bitmap.isNull())
- return 0;
- QBitmap bm = bitmap;
- bm.x11SetScreen(screen);
-
- Pixmap mask = XCreatePixmap(X11->display, RootWindow(X11->display, screen),
- bm.data->width(), bm.data->height(), 1);
- GC gc = XCreateGC(X11->display, mask, 0, 0);
- XCopyArea(X11->display, bm.handle(), mask, gc, 0, 0,
- bm.data->width(), bm.data->height(), 0, 0);
- XFreeGC(X11->display, gc);
- return mask;
-}
-
-
-/*****************************************************************************
- MIT Shared Memory Extension support: makes xForm noticeably (~20%) faster.
- *****************************************************************************/
-
-#if defined(QT_MITSHM)
-
-static bool xshminit = false;
-static XShmSegmentInfo xshminfo;
-static XImage *xshmimg = 0;
-static Pixmap xshmpm = 0;
-
-static void qt_cleanup_mitshm()
-{
- if (xshmimg == 0)
- return;
- Display *dpy = QX11Info::appDisplay();
- if (xshmpm) {
- XFreePixmap(dpy, xshmpm);
- xshmpm = 0;
- }
- XShmDetach(dpy, &xshminfo); xshmimg->data = 0;
- qSafeXDestroyImage(xshmimg); xshmimg = 0;
- shmdt(xshminfo.shmaddr);
- shmctl(xshminfo.shmid, IPC_RMID, 0);
-}
-
-static bool qt_create_mitshm_buffer(const QPaintDevice* dev, int w, int h)
-{
- static int major, minor;
- static Bool pixmaps_ok;
- Display *dpy = dev->data->xinfo->display();
- int dd = dev->x11Depth();
- Visual *vis = (Visual*)dev->x11Visual();
-
- if (xshminit) {
- qt_cleanup_mitshm();
- } else {
- if (!XShmQueryVersion(dpy, &major, &minor, &pixmaps_ok))
- return false; // MIT Shm not supported
- qAddPostRoutine(qt_cleanup_mitshm);
- xshminit = true;
- }
-
- xshmimg = XShmCreateImage(dpy, vis, dd, ZPixmap, 0, &xshminfo, w, h);
- if (!xshmimg)
- return false;
-
- bool ok;
- xshminfo.shmid = shmget(IPC_PRIVATE,
- xshmimg->bytes_per_line * xshmimg->height,
- IPC_CREAT | 0777);
- ok = xshminfo.shmid != -1;
- if (ok) {
- xshmimg->data = (char*)shmat(xshminfo.shmid, 0, 0);
- xshminfo.shmaddr = xshmimg->data;
- ok = (xshminfo.shmaddr != (char*)-1);
- }
- xshminfo.readOnly = false;
- if (ok)
- ok = XShmAttach(dpy, &xshminfo);
- if (!ok) {
- qSafeXDestroyImage(xshmimg);
- xshmimg = 0;
- if (xshminfo.shmaddr)
- shmdt(xshminfo.shmaddr);
- if (xshminfo.shmid != -1)
- shmctl(xshminfo.shmid, IPC_RMID, 0);
- return false;
- }
- if (pixmaps_ok)
- xshmpm = XShmCreatePixmap(dpy, DefaultRootWindow(dpy), xshmimg->data,
- &xshminfo, w, h, dd);
-
- return true;
-}
-
-#else
-
-// If extern, need a dummy.
-//
-// static bool qt_create_mitshm_buffer(QPaintDevice*, int, int)
-// {
-// return false;
-// }
-
-#endif // QT_MITSHM
-
-
-/*****************************************************************************
- Internal functions
- *****************************************************************************/
-
-extern const uchar *qt_get_bitflip_array(); // defined in qimage.cpp
-
-// Returns position of highest bit set or -1 if none
-static int highest_bit(uint v)
-{
- int i;
- uint b = (uint)1 << 31;
- for (i=31; ((b & v) == 0) && i>=0; i--)
- b >>= 1;
- return i;
-}
-
-// Returns position of lowest set bit in 'v' as an integer (0-31), or -1
-static int lowest_bit(uint v)
-{
- int i;
- ulong lb;
- lb = 1;
- for (i=0; ((v & lb) == 0) && i<32; i++, lb<<=1) {}
- return i==32 ? -1 : i;
-}
-
-// Counts the number of bits set in 'v'
-static uint n_bits(uint v)
-{
- int i = 0;
- while (v) {
- v = v & (v - 1);
- i++;
- }
- return i;
-}
-
-static uint *red_scale_table = 0;
-static uint *green_scale_table = 0;
-static uint *blue_scale_table = 0;
-
-static void cleanup_scale_tables()
-{
- delete[] red_scale_table;
- delete[] green_scale_table;
- delete[] blue_scale_table;
-}
-
-/*
- Could do smart bitshifting, but the "obvious" algorithm only works for
- nBits >= 4. This is more robust.
-*/
-static void build_scale_table(uint **table, uint nBits)
-{
- if (nBits > 7) {
- qWarning("build_scale_table: internal error, nBits = %i", nBits);
- return;
- }
- if (!*table) {
- static bool firstTable = true;
- if (firstTable) {
- qAddPostRoutine(cleanup_scale_tables);
- firstTable = false;
- }
- *table = new uint[256];
- }
- int maxVal = (1 << nBits) - 1;
- int valShift = 8 - nBits;
- int i;
- for(i = 0 ; i < maxVal + 1 ; i++)
- (*table)[i << valShift] = i*255/maxVal;
-}
-
-static int defaultScreen = -1;
-
-/*****************************************************************************
- QPixmap member functions
- *****************************************************************************/
-
-QBasicAtomicInt qt_pixmap_serial = Q_BASIC_ATOMIC_INITIALIZER(0);
-int Q_GUI_EXPORT qt_x11_preferred_pixmap_depth = 0;
-
-QX11PixmapData::QX11PixmapData(PixelType type)
- : QPixmapData(type, X11Class), gl_surface(0), hd(0),
- flags(Uninitialized), x11_mask(0), picture(0), mask_picture(0), hd2(0),
- share_mode(QPixmap::ImplicitlyShared), pengine(0)
-{
-}
-
-QPixmapData *QX11PixmapData::createCompatiblePixmapData() const
-{
- return new QX11PixmapData(pixelType());
-}
-
-void QX11PixmapData::resize(int width, int height)
-{
- setSerialNumber(qt_pixmap_serial.fetchAndAddRelaxed(1));
-
- w = width;
- h = height;
- is_null = (w <= 0 || h <= 0);
-
- if (defaultScreen >= 0 && defaultScreen != xinfo.screen()) {
- QX11InfoData* xd = xinfo.getX11Data(true);
- xd->screen = defaultScreen;
- xd->depth = QX11Info::appDepth(xd->screen);
- xd->cells = QX11Info::appCells(xd->screen);
- xd->colormap = QX11Info::appColormap(xd->screen);
- xd->defaultColormap = QX11Info::appDefaultColormap(xd->screen);
- xd->visual = (Visual *)QX11Info::appVisual(xd->screen);
- xd->defaultVisual = QX11Info::appDefaultVisual(xd->screen);
- xinfo.setX11Data(xd);
- }
-
- int dd = xinfo.depth();
-
- if (qt_x11_preferred_pixmap_depth)
- dd = qt_x11_preferred_pixmap_depth;
-
- bool make_null = w <= 0 || h <= 0; // create null pixmap
- d = (pixelType() == BitmapType ? 1 : dd);
- if (make_null || d == 0) {
- w = 0;
- h = 0;
- is_null = true;
- hd = 0;
- picture = 0;
- d = 0;
- if (!make_null)
- qWarning("QPixmap: Invalid pixmap parameters");
- return;
- }
- hd = (Qt::HANDLE)XCreatePixmap(X11->display,
- RootWindow(X11->display, xinfo.screen()),
- w, h, d);
-#ifndef QT_NO_XRENDER
- if (X11->use_xrender) {
- XRenderPictFormat *format = d == 1
- ? XRenderFindStandardFormat(X11->display, PictStandardA1)
- : XRenderFindVisualFormat(X11->display, (Visual *)xinfo.visual());
- picture = XRenderCreatePicture(X11->display, hd, format, 0, 0);
- }
-#endif // QT_NO_XRENDER
-}
-
-struct QX11AlphaDetector
-{
- bool hasAlpha() const {
- if (checked)
- return has;
- // Will implicitly also check format and return quickly for opaque types...
- checked = true;
- has = image->isNull() ? false : const_cast<QImage *>(image)->data_ptr()->checkForAlphaPixels();
- return has;
- }
-
- bool hasXRenderAndAlpha() const {
- if (!X11->use_xrender)
- return false;
- return hasAlpha();
- }
-
- QX11AlphaDetector(const QImage *i, Qt::ImageConversionFlags flags)
- : image(i), checked(false), has(false)
- {
- if (flags & Qt::NoOpaqueDetection) {
- checked = true;
- has = image->hasAlphaChannel();
- }
- }
-
- const QImage *image;
- mutable bool checked;
- mutable bool has;
-};
-
-void QX11PixmapData::fromImage(const QImage &img,
- Qt::ImageConversionFlags flags)
-{
- setSerialNumber(qt_pixmap_serial.fetchAndAddRelaxed(1));
-
- w = img.width();
- h = img.height();
- d = img.depth();
- is_null = (w <= 0 || h <= 0);
-
- if (is_null) {
- w = h = 0;
- return;
- }
-
- if (defaultScreen >= 0 && defaultScreen != xinfo.screen()) {
- QX11InfoData* xd = xinfo.getX11Data(true);
- xd->screen = defaultScreen;
- xd->depth = QX11Info::appDepth(xd->screen);
- xd->cells = QX11Info::appCells(xd->screen);
- xd->colormap = QX11Info::appColormap(xd->screen);
- xd->defaultColormap = QX11Info::appDefaultColormap(xd->screen);
- xd->visual = (Visual *)QX11Info::appVisual(xd->screen);
- xd->defaultVisual = QX11Info::appDefaultVisual(xd->screen);
- xinfo.setX11Data(xd);
- }
-
- if (pixelType() == BitmapType) {
- bitmapFromImage(img);
- return;
- }
-
- if (uint(w) >= 32768 || uint(h) >= 32768) {
- w = h = 0;
- is_null = true;
- return;
- }
-
- QX11AlphaDetector alphaCheck(&img, flags);
- int dd = alphaCheck.hasXRenderAndAlpha() ? 32 : xinfo.depth();
-
- if (qt_x11_preferred_pixmap_depth)
- dd = qt_x11_preferred_pixmap_depth;
-
- QImage image = img;
-
- // must be monochrome
- if (dd == 1 || (flags & Qt::ColorMode_Mask) == Qt::MonoOnly) {
- if (d != 1) {
- // dither
- image = image.convertToFormat(QImage::Format_MonoLSB, flags);
- d = 1;
- }
- } else { // can be both
- bool conv8 = false;
- if (d > 8 && dd <= 8) { // convert to 8 bit
- if ((flags & Qt::DitherMode_Mask) == Qt::AutoDither)
- flags = (flags & ~Qt::DitherMode_Mask)
- | Qt::PreferDither;
- conv8 = true;
- } else if ((flags & Qt::ColorMode_Mask) == Qt::ColorOnly) {
- conv8 = (d == 1); // native depth wanted
- } else if (d == 1) {
- if (image.colorCount() == 2) {
- QRgb c0 = image.color(0); // Auto: convert to best
- QRgb c1 = image.color(1);
- conv8 = qMin(c0,c1) != qRgb(0,0,0) || qMax(c0,c1) != qRgb(255,255,255);
- } else {
- // eg. 1-color monochrome images (they do exist).
- conv8 = true;
- }
- }
- if (conv8) {
- image = image.convertToFormat(QImage::Format_Indexed8, flags);
- d = 8;
- }
- }
-
- if (d == 1 || d == 16 || d == 24) {
- image = image.convertToFormat(QImage::Format_RGB32, flags);
- fromImage(image, Qt::AutoColor);
- return;
- }
-
- Display *dpy = X11->display;
- Visual *visual = (Visual *)xinfo.visual();
- XImage *xi = 0;
- bool trucol = (visual->c_class >= TrueColor);
- int nbytes = image.byteCount();
- uchar *newbits= 0;
-
-#ifndef QT_NO_XRENDER
- if (alphaCheck.hasXRenderAndAlpha()) {
- const QImage &cimage = image;
-
- d = 32;
-
- if (QX11Info::appDepth() != d) {
- if (xinfo.x11data) {
- xinfo.x11data->depth = d;
- } else {
- QX11InfoData *xd = xinfo.getX11Data(true);
- xd->screen = QX11Info::appScreen();
- xd->depth = d;
- xd->cells = QX11Info::appCells();
- xd->colormap = QX11Info::appColormap();
- xd->defaultColormap = QX11Info::appDefaultColormap();
- xd->visual = (Visual *)QX11Info::appVisual();
- xd->defaultVisual = QX11Info::appDefaultVisual();
- xinfo.setX11Data(xd);
- }
- }
-
- hd = (Qt::HANDLE)XCreatePixmap(dpy, RootWindow(dpy, xinfo.screen()),
- w, h, d);
- picture = XRenderCreatePicture(X11->display, hd,
- XRenderFindStandardFormat(X11->display, PictStandardARGB32), 0, 0);
-
- xi = XCreateImage(dpy, visual, d, ZPixmap, 0, 0, w, h, 32, 0);
- Q_CHECK_PTR(xi);
- newbits = (uchar *)malloc(xi->bytes_per_line*h);
- Q_CHECK_PTR(newbits);
- xi->data = (char *)newbits;
-
- switch(cimage.format()) {
- case QImage::Format_Indexed8: {
- QVector<QRgb> colorTable = cimage.colorTable();
- uint *xidata = (uint *)xi->data;
- for (int y = 0; y < h; ++y) {
- const uchar *p = cimage.scanLine(y);
- for (int x = 0; x < w; ++x) {
- const QRgb rgb = colorTable[p[x]];
- const int a = qAlpha(rgb);
- if (a == 0xff)
- *xidata = rgb;
- else
- // RENDER expects premultiplied alpha
- *xidata = qRgba(qt_div_255(qRed(rgb) * a),
- qt_div_255(qGreen(rgb) * a),
- qt_div_255(qBlue(rgb) * a),
- a);
- ++xidata;
- }
- }
- }
- break;
- case QImage::Format_RGB32: {
- uint *xidata = (uint *)xi->data;
- for (int y = 0; y < h; ++y) {
- const QRgb *p = (const QRgb *) cimage.scanLine(y);
- for (int x = 0; x < w; ++x)
- *xidata++ = p[x] | 0xff000000;
- }
- }
- break;
- case QImage::Format_ARGB32: {
- uint *xidata = (uint *)xi->data;
- for (int y = 0; y < h; ++y) {
- const QRgb *p = (const QRgb *) cimage.scanLine(y);
- for (int x = 0; x < w; ++x) {
- const QRgb rgb = p[x];
- const int a = qAlpha(rgb);
- if (a == 0xff)
- *xidata = rgb;
- else
- // RENDER expects premultiplied alpha
- *xidata = qRgba(qt_div_255(qRed(rgb) * a),
- qt_div_255(qGreen(rgb) * a),
- qt_div_255(qBlue(rgb) * a),
- a);
- ++xidata;
- }
- }
-
- }
- break;
- case QImage::Format_ARGB32_Premultiplied: {
- uint *xidata = (uint *)xi->data;
- for (int y = 0; y < h; ++y) {
- const QRgb *p = (const QRgb *) cimage.scanLine(y);
- memcpy(xidata, p, w*sizeof(QRgb));
- xidata += w;
- }
- }
- break;
- default:
- Q_ASSERT(false);
- }
-
- if ((xi->byte_order == MSBFirst) != (QSysInfo::ByteOrder == QSysInfo::BigEndian)) {
- uint *xidata = (uint *)xi->data;
- uint *xiend = xidata + w*h;
- while (xidata < xiend) {
- *xidata = (*xidata >> 24)
- | ((*xidata >> 8) & 0xff00)
- | ((*xidata << 8) & 0xff0000)
- | (*xidata << 24);
- ++xidata;
- }
- }
-
- GC gc = XCreateGC(dpy, hd, 0, 0);
- XPutImage(dpy, hd, gc, xi, 0, 0, 0, 0, w, h);
- XFreeGC(dpy, gc);
-
- qSafeXDestroyImage(xi);
-
- return;
- }
-#endif // QT_NO_XRENDER
-
- if (trucol) { // truecolor display
- if (image.format() == QImage::Format_ARGB32_Premultiplied)
- image = image.convertToFormat(QImage::Format_ARGB32);
-
- const QImage &cimage = image;
- QRgb pix[256]; // pixel translation table
- const bool d8 = (d == 8);
- const uint red_mask = (uint)visual->red_mask;
- const uint green_mask = (uint)visual->green_mask;
- const uint blue_mask = (uint)visual->blue_mask;
- const int red_shift = highest_bit(red_mask) - 7;
- const int green_shift = highest_bit(green_mask) - 7;
- const int blue_shift = highest_bit(blue_mask) - 7;
- const uint rbits = highest_bit(red_mask) - lowest_bit(red_mask) + 1;
- const uint gbits = highest_bit(green_mask) - lowest_bit(green_mask) + 1;
- const uint bbits = highest_bit(blue_mask) - lowest_bit(blue_mask) + 1;
-
- if (d8) { // setup pixel translation
- QVector<QRgb> ctable = cimage.colorTable();
- for (int i=0; i < cimage.colorCount(); i++) {
- int r = qRed (ctable[i]);
- int g = qGreen(ctable[i]);
- int b = qBlue (ctable[i]);
- r = red_shift > 0 ? r << red_shift : r >> -red_shift;
- g = green_shift > 0 ? g << green_shift : g >> -green_shift;
- b = blue_shift > 0 ? b << blue_shift : b >> -blue_shift;
- pix[i] = (b & blue_mask) | (g & green_mask) | (r & red_mask)
- | ~(blue_mask | green_mask | red_mask);
- }
- }
-
- xi = XCreateImage(dpy, visual, dd, ZPixmap, 0, 0, w, h, 32, 0);
- Q_CHECK_PTR(xi);
- newbits = (uchar *)malloc(xi->bytes_per_line*h);
- Q_CHECK_PTR(newbits);
- if (!newbits) // no memory
- return;
- int bppc = xi->bits_per_pixel;
-
- bool contig_bits = n_bits(red_mask) == rbits &&
- n_bits(green_mask) == gbits &&
- n_bits(blue_mask) == bbits;
- bool dither_tc =
- // Want it?
- (flags & Qt::Dither_Mask) != Qt::ThresholdDither &&
- (flags & Qt::DitherMode_Mask) != Qt::AvoidDither &&
- // Need it?
- bppc < 24 && !d8 &&
- // Can do it? (Contiguous bits?)
- contig_bits;
-
- static bool init=false;
- static int D[16][16];
- if (dither_tc && !init) {
- // I also contributed this code to XV - WWA.
- /*
- The dither matrix, D, is obtained with this formula:
-
- D2 = [0 2]
- [3 1]
-
-
- D2*n = [4*Dn 4*Dn+2*Un]
- [4*Dn+3*Un 4*Dn+1*Un]
- */
- int n,i,j;
- init=1;
-
- /* Set D2 */
- D[0][0]=0;
- D[1][0]=2;
- D[0][1]=3;
- D[1][1]=1;
-
- /* Expand using recursive definition given above */
- for (n=2; n<16; n*=2) {
- for (i=0; i<n; i++) {
- for (j=0; j<n; j++) {
- D[i][j]*=4;
- D[i+n][j]=D[i][j]+2;
- D[i][j+n]=D[i][j]+3;
- D[i+n][j+n]=D[i][j]+1;
- }
- }
- }
- init=true;
- }
-
- enum { BPP8,
- BPP16_565, BPP16_555,
- BPP16_MSB, BPP16_LSB,
- BPP24_888,
- BPP24_MSB, BPP24_LSB,
- BPP32_8888,
- BPP32_MSB, BPP32_LSB
- } mode = BPP8;
-
- bool same_msb_lsb = (xi->byte_order == MSBFirst) == (QSysInfo::ByteOrder == QSysInfo::BigEndian);
-
- if(bppc == 8) // 8 bit
- mode = BPP8;
- else if(bppc == 16) { // 16 bit MSB/LSB
- if(red_shift == 8 && green_shift == 3 && blue_shift == -3 && !d8 && same_msb_lsb)
- mode = BPP16_565;
- else if(red_shift == 7 && green_shift == 2 && blue_shift == -3 && !d8 && same_msb_lsb)
- mode = BPP16_555;
- else
- mode = (xi->byte_order == LSBFirst) ? BPP16_LSB : BPP16_MSB;
- } else if(bppc == 24) { // 24 bit MSB/LSB
- if (red_shift == 16 && green_shift == 8 && blue_shift == 0 && !d8 && same_msb_lsb)
- mode = BPP24_888;
- else
- mode = (xi->byte_order == LSBFirst) ? BPP24_LSB : BPP24_MSB;
- } else if(bppc == 32) { // 32 bit MSB/LSB
- if(red_shift == 16 && green_shift == 8 && blue_shift == 0 && !d8 && same_msb_lsb)
- mode = BPP32_8888;
- else
- mode = (xi->byte_order == LSBFirst) ? BPP32_LSB : BPP32_MSB;
- } else
- qFatal("Logic error 3");
-
-#define GET_PIXEL \
- uint pixel; \
- if (d8) pixel = pix[*src++]; \
- else { \
- int r = qRed (*p); \
- int g = qGreen(*p); \
- int b = qBlue (*p++); \
- r = red_shift > 0 \
- ? r << red_shift : r >> -red_shift; \
- g = green_shift > 0 \
- ? g << green_shift : g >> -green_shift; \
- b = blue_shift > 0 \
- ? b << blue_shift : b >> -blue_shift; \
- pixel = (r & red_mask)|(g & green_mask) | (b & blue_mask) \
- | ~(blue_mask | green_mask | red_mask); \
- }
-
-#define GET_PIXEL_DITHER_TC \
- int r = qRed (*p); \
- int g = qGreen(*p); \
- int b = qBlue (*p++); \
- const int thres = D[x%16][y%16]; \
- if (r <= (255-(1<<(8-rbits))) && ((r<<rbits) & 255) \
- > thres) \
- r += (1<<(8-rbits)); \
- if (g <= (255-(1<<(8-gbits))) && ((g<<gbits) & 255) \
- > thres) \
- g += (1<<(8-gbits)); \
- if (b <= (255-(1<<(8-bbits))) && ((b<<bbits) & 255) \
- > thres) \
- b += (1<<(8-bbits)); \
- r = red_shift > 0 \
- ? r << red_shift : r >> -red_shift; \
- g = green_shift > 0 \
- ? g << green_shift : g >> -green_shift; \
- b = blue_shift > 0 \
- ? b << blue_shift : b >> -blue_shift; \
- uint pixel = (r & red_mask)|(g & green_mask) | (b & blue_mask);
-
-// again, optimized case
-// can't be optimized that much :(
-#define GET_PIXEL_DITHER_TC_OPT(red_shift,green_shift,blue_shift,red_mask,green_mask,blue_mask, \
- rbits,gbits,bbits) \
- const int thres = D[x%16][y%16]; \
- int r = qRed (*p); \
- if (r <= (255-(1<<(8-rbits))) && ((r<<rbits) & 255) \
- > thres) \
- r += (1<<(8-rbits)); \
- int g = qGreen(*p); \
- if (g <= (255-(1<<(8-gbits))) && ((g<<gbits) & 255) \
- > thres) \
- g += (1<<(8-gbits)); \
- int b = qBlue (*p++); \
- if (b <= (255-(1<<(8-bbits))) && ((b<<bbits) & 255) \
- > thres) \
- b += (1<<(8-bbits)); \
- uint pixel = ((r red_shift) & red_mask) \
- | ((g green_shift) & green_mask) \
- | ((b blue_shift) & blue_mask);
-
-#define CYCLE(body) \
- for (int y=0; y<h; y++) { \
- const uchar* src = cimage.scanLine(y); \
- uchar* dst = newbits + xi->bytes_per_line*y; \
- const QRgb* p = (const QRgb *)src; \
- body \
- }
-
- if (dither_tc) {
- switch (mode) {
- case BPP16_565:
- CYCLE(
- quint16* dst16 = (quint16*)dst;
- for (int x=0; x<w; x++) {
- GET_PIXEL_DITHER_TC_OPT(<<8,<<3,>>3,0xf800,0x7e0,0x1f,5,6,5)
- *dst16++ = pixel;
- }
- )
- break;
- case BPP16_555:
- CYCLE(
- quint16* dst16 = (quint16*)dst;
- for (int x=0; x<w; x++) {
- GET_PIXEL_DITHER_TC_OPT(<<7,<<2,>>3,0x7c00,0x3e0,0x1f,5,5,5)
- *dst16++ = pixel;
- }
- )
- break;
- case BPP16_MSB: // 16 bit MSB
- CYCLE(
- for (int x=0; x<w; x++) {
- GET_PIXEL_DITHER_TC
- *dst++ = (pixel >> 8);
- *dst++ = pixel;
- }
- )
- break;
- case BPP16_LSB: // 16 bit LSB
- CYCLE(
- for (int x=0; x<w; x++) {
- GET_PIXEL_DITHER_TC
- *dst++ = pixel;
- *dst++ = pixel >> 8;
- }
- )
- break;
- default:
- qFatal("Logic error");
- }
- } else {
- switch (mode) {
- case BPP8: // 8 bit
- CYCLE(
- Q_UNUSED(p);
- for (int x=0; x<w; x++)
- *dst++ = pix[*src++];
- )
- break;
- case BPP16_565:
- CYCLE(
- quint16* dst16 = (quint16*)dst;
- for (int x = 0; x < w; x++) {
- *dst16++ = ((*p >> 8) & 0xf800)
- | ((*p >> 5) & 0x7e0)
- | ((*p >> 3) & 0x1f);
- ++p;
- }
- )
- break;
- case BPP16_555:
- CYCLE(
- quint16* dst16 = (quint16*)dst;
- for (int x=0; x<w; x++) {
- *dst16++ = ((*p >> 9) & 0x7c00)
- | ((*p >> 6) & 0x3e0)
- | ((*p >> 3) & 0x1f);
- ++p;
- }
- )
- break;
- case BPP16_MSB: // 16 bit MSB
- CYCLE(
- for (int x=0; x<w; x++) {
- GET_PIXEL
- *dst++ = (pixel >> 8);
- *dst++ = pixel;
- }
- )
- break;
- case BPP16_LSB: // 16 bit LSB
- CYCLE(
- for (int x=0; x<w; x++) {
- GET_PIXEL
- *dst++ = pixel;
- *dst++ = pixel >> 8;
- }
- )
- break;
- case BPP24_888: // 24 bit MSB
- CYCLE(
- for (int x=0; x<w; x++) {
- *dst++ = qRed (*p);
- *dst++ = qGreen(*p);
- *dst++ = qBlue (*p++);
- }
- )
- break;
- case BPP24_MSB: // 24 bit MSB
- CYCLE(
- for (int x=0; x<w; x++) {
- GET_PIXEL
- *dst++ = pixel >> 16;
- *dst++ = pixel >> 8;
- *dst++ = pixel;
- }
- )
- break;
- case BPP24_LSB: // 24 bit LSB
- CYCLE(
- for (int x=0; x<w; x++) {
- GET_PIXEL
- *dst++ = pixel;
- *dst++ = pixel >> 8;
- *dst++ = pixel >> 16;
- }
- )
- break;
- case BPP32_8888:
- CYCLE(
- memcpy(dst, p, w * 4);
- )
- break;
- case BPP32_MSB: // 32 bit MSB
- CYCLE(
- for (int x=0; x<w; x++) {
- GET_PIXEL
- *dst++ = pixel >> 24;
- *dst++ = pixel >> 16;
- *dst++ = pixel >> 8;
- *dst++ = pixel;
- }
- )
- break;
- case BPP32_LSB: // 32 bit LSB
- CYCLE(
- for (int x=0; x<w; x++) {
- GET_PIXEL
- *dst++ = pixel;
- *dst++ = pixel >> 8;
- *dst++ = pixel >> 16;
- *dst++ = pixel >> 24;
- }
- )
- break;
- default:
- qFatal("Logic error 2");
- }
- }
- xi->data = (char *)newbits;
- }
-
- if (d == 8 && !trucol) { // 8 bit pixmap
- int pop[256]; // pixel popularity
-
- if (image.colorCount() == 0)
- image.setColorCount(1);
-
- const QImage &cimage = image;
- memset(pop, 0, sizeof(int)*256); // reset popularity array
- for (int i = 0; i < h; i++) { // for each scanline...
- const uchar* p = cimage.scanLine(i);
- const uchar *end = p + w;
- while (p < end) // compute popularity
- pop[*p++]++;
- }
-
- newbits = (uchar *)malloc(nbytes); // copy image into newbits
- Q_CHECK_PTR(newbits);
- if (!newbits) // no memory
- return;
- uchar* p = newbits;
- memcpy(p, cimage.bits(), nbytes); // copy image data into newbits
-
- /*
- * The code below picks the most important colors. It is based on the
- * diversity algorithm, implemented in XV 3.10. XV is (C) by John Bradley.
- */
-
- struct PIX { // pixel sort element
- uchar r,g,b,n; // color + pad
- int use; // popularity
- int index; // index in colormap
- int mindist;
- };
- int ncols = 0;
- for (int i=0; i< cimage.colorCount(); i++) { // compute number of colors
- if (pop[i] > 0)
- ncols++;
- }
- for (int i = cimage.colorCount(); i < 256; i++) // ignore out-of-range pixels
- pop[i] = 0;
-
- // works since we make sure above to have at least
- // one color in the image
- if (ncols == 0)
- ncols = 1;
-
- PIX pixarr[256]; // pixel array
- PIX pixarr_sorted[256]; // pixel array (sorted)
- memset(pixarr, 0, ncols*sizeof(PIX));
- PIX *px = &pixarr[0];
- int maxpop = 0;
- int maxpix = 0;
- uint j = 0;
- QVector<QRgb> ctable = cimage.colorTable();
- for (int i = 0; i < 256; i++) { // init pixel array
- if (pop[i] > 0) {
- px->r = qRed (ctable[i]);
- px->g = qGreen(ctable[i]);
- px->b = qBlue (ctable[i]);
- px->n = 0;
- px->use = pop[i];
- if (pop[i] > maxpop) { // select most popular entry
- maxpop = pop[i];
- maxpix = j;
- }
- px->index = i;
- px->mindist = 1000000;
- px++;
- j++;
- }
- }
- pixarr_sorted[0] = pixarr[maxpix];
- pixarr[maxpix].use = 0;
-
- for (int i = 1; i < ncols; i++) { // sort pixels
- int minpix = -1, mindist = -1;
- px = &pixarr_sorted[i-1];
- int r = px->r;
- int g = px->g;
- int b = px->b;
- int dist;
- if ((i & 1) || i<10) { // sort on max distance
- for (int j=0; j<ncols; j++) {
- px = &pixarr[j];
- if (px->use) {
- dist = (px->r - r)*(px->r - r) +
- (px->g - g)*(px->g - g) +
- (px->b - b)*(px->b - b);
- if (px->mindist > dist)
- px->mindist = dist;
- if (px->mindist > mindist) {
- mindist = px->mindist;
- minpix = j;
- }
- }
- }
- } else { // sort on max popularity
- for (int j=0; j<ncols; j++) {
- px = &pixarr[j];
- if (px->use) {
- dist = (px->r - r)*(px->r - r) +
- (px->g - g)*(px->g - g) +
- (px->b - b)*(px->b - b);
- if (px->mindist > dist)
- px->mindist = dist;
- if (px->use > mindist) {
- mindist = px->use;
- minpix = j;
- }
- }
- }
- }
- pixarr_sorted[i] = pixarr[minpix];
- pixarr[minpix].use = 0;
- }
-
- QColormap cmap = QColormap::instance(xinfo.screen());
- uint pix[256]; // pixel translation table
- px = &pixarr_sorted[0];
- for (int i = 0; i < ncols; i++) { // allocate colors
- QColor c(px->r, px->g, px->b);
- pix[px->index] = cmap.pixel(c);
- px++;
- }
-
- p = newbits;
- for (int i = 0; i < nbytes; i++) { // translate pixels
- *p = pix[*p];
- p++;
- }
- }
-
- if (!xi) { // X image not created
- xi = XCreateImage(dpy, visual, dd, ZPixmap, 0, 0, w, h, 32, 0);
- if (xi->bits_per_pixel == 16) { // convert 8 bpp ==> 16 bpp
- ushort *p2;
- int p2inc = xi->bytes_per_line/sizeof(ushort);
- ushort *newerbits = (ushort *)malloc(xi->bytes_per_line * h);
- Q_CHECK_PTR(newerbits);
- if (!newerbits) // no memory
- return;
- uchar* p = newbits;
- for (int y = 0; y < h; y++) { // OOPS: Do right byte order!!
- p2 = newerbits + p2inc*y;
- for (int x = 0; x < w; x++)
- *p2++ = *p++;
- }
- free(newbits);
- newbits = (uchar *)newerbits;
- } else if (xi->bits_per_pixel != 8) {
- qWarning("QPixmap::fromImage: Display not supported "
- "(bpp=%d)", xi->bits_per_pixel);
- }
- xi->data = (char *)newbits;
- }
-
- hd = (Qt::HANDLE)XCreatePixmap(X11->display,
- RootWindow(X11->display, xinfo.screen()),
- w, h, dd);
-
- GC gc = XCreateGC(dpy, hd, 0, 0);
- XPutImage(dpy, hd, gc, xi, 0, 0, 0, 0, w, h);
- XFreeGC(dpy, gc);
-
- qSafeXDestroyImage(xi);
- d = dd;
-
-#ifndef QT_NO_XRENDER
- if (X11->use_xrender) {
- XRenderPictFormat *format = d == 1
- ? XRenderFindStandardFormat(X11->display, PictStandardA1)
- : XRenderFindVisualFormat(X11->display, (Visual *)xinfo.visual());
- picture = XRenderCreatePicture(X11->display, hd, format, 0, 0);
- }
-#endif
-
- if (alphaCheck.hasAlpha()) {
- QBitmap m = QBitmap::fromImage(image.createAlphaMask(flags));
- setMask(m);
- }
-}
-
-Qt::HANDLE QX11PixmapData::createBitmapFromImage(const QImage &image)
-{
- QImage img = image.convertToFormat(QImage::Format_MonoLSB);
- const QRgb c0 = QColor(Qt::black).rgb();
- const QRgb c1 = QColor(Qt::white).rgb();
- if (img.color(0) == c0 && img.color(1) == c1) {
- img.invertPixels();
- img.setColor(0, c1);
- img.setColor(1, c0);
- }
-
- char *bits;
- uchar *tmp_bits;
- int w = img.width();
- int h = img.height();
- int bpl = (w + 7) / 8;
- int ibpl = img.bytesPerLine();
- if (bpl != ibpl) {
- tmp_bits = new uchar[bpl*h];
- bits = (char *)tmp_bits;
- uchar *p, *b;
- int y;
- b = tmp_bits;
- p = img.scanLine(0);
- for (y = 0; y < h; y++) {
- memcpy(b, p, bpl);
- b += bpl;
- p += ibpl;
- }
- } else {
- bits = (char *)img.bits();
- tmp_bits = 0;
- }
- Qt::HANDLE hd = (Qt::HANDLE)XCreateBitmapFromData(X11->display,
- QX11Info::appRootWindow(),
- bits, w, h);
- if (tmp_bits) // Avoid purify complaint
- delete [] tmp_bits;
- return hd;
-}
-
-void QX11PixmapData::bitmapFromImage(const QImage &image)
-{
- w = image.width();
- h = image.height();
- d = 1;
- is_null = (w <= 0 || h <= 0);
- hd = createBitmapFromImage(image);
-#ifndef QT_NO_XRENDER
- if (X11->use_xrender)
- picture = XRenderCreatePicture(X11->display, hd,
- XRenderFindStandardFormat(X11->display, PictStandardA1), 0, 0);
-#endif // QT_NO_XRENDER
-}
-
-void QX11PixmapData::fill(const QColor &fillColor)
-{
- if (fillColor.alpha() != 255) {
-#ifndef QT_NO_XRENDER
- if (X11->use_xrender) {
- if (!picture || d != 32)
- convertToARGB32(/*preserveContents = */false);
-
- ::Picture src = X11->getSolidFill(xinfo.screen(), fillColor);
- XRenderComposite(X11->display, PictOpSrc, src, 0, picture,
- 0, 0, width(), height(),
- 0, 0, width(), height());
- } else
-#endif
- {
- QImage im(width(), height(), QImage::Format_ARGB32_Premultiplied);
- im.fill(PREMUL(fillColor.rgba()));
- release();
- fromImage(im, Qt::AutoColor | Qt::OrderedAlphaDither);
- }
- return;
- }
-
- GC gc = XCreateGC(X11->display, hd, 0, 0);
- if (depth() == 1) {
- XSetForeground(X11->display, gc, qGray(fillColor.rgb()) > 127 ? 0 : 1);
- } else if (X11->use_xrender && d >= 24) {
- XSetForeground(X11->display, gc, fillColor.rgba());
- } else {
- XSetForeground(X11->display, gc,
- QColormap::instance(xinfo.screen()).pixel(fillColor));
- }
- XFillRectangle(X11->display, hd, gc, 0, 0, width(), height());
- XFreeGC(X11->display, gc);
-}
-
-QX11PixmapData::~QX11PixmapData()
-{
- // Cleanup hooks have to be called before the handles are freed
- if (is_cached) {
- QImagePixmapCleanupHooks::executePixmapDataDestructionHooks(this);
- is_cached = false;
- }
-
- release();
-}
-
-void QX11PixmapData::release()
-{
- delete pengine;
- pengine = 0;
-
- if (!X11) {
- // At this point, the X server will already have freed our resources,
- // so there is nothing to do.
- return;
- }
-
- if (x11_mask) {
-#ifndef QT_NO_XRENDER
- if (mask_picture)
- XRenderFreePicture(X11->display, mask_picture);
- mask_picture = 0;
-#endif
- XFreePixmap(X11->display, x11_mask);
- x11_mask = 0;
- }
-
- if (hd) {
-#ifndef QT_NO_XRENDER
- if (picture) {
- XRenderFreePicture(X11->display, picture);
- picture = 0;
- }
-#endif // QT_NO_XRENDER
-
- if (hd2) {
- XFreePixmap(xinfo.display(), hd2);
- hd2 = 0;
- }
- if (!(flags & Readonly))
- XFreePixmap(xinfo.display(), hd);
- hd = 0;
- }
-}
-
-QPixmap QX11PixmapData::alphaChannel() const
-{
- if (!hasAlphaChannel()) {
- QPixmap pm(w, h);
- pm.fill(Qt::white);
- return pm;
- }
- QImage im(toImage());
- return QPixmap::fromImage(im.alphaChannel(), Qt::OrderedDither);
-}
-
-void QX11PixmapData::setAlphaChannel(const QPixmap &alpha)
-{
- QImage image(toImage());
- image.setAlphaChannel(alpha.toImage());
- release();
- fromImage(image, Qt::OrderedDither | Qt::OrderedAlphaDither);
-}
-
-
-QBitmap QX11PixmapData::mask() const
-{
- QBitmap mask;
-#ifndef QT_NO_XRENDER
- if (picture && d == 32) {
- // #### slow - there must be a better way..
- mask = QBitmap::fromImage(toImage().createAlphaMask());
- } else
-#endif
- if (d == 1) {
- QX11PixmapData *that = const_cast<QX11PixmapData*>(this);
- mask = QPixmap(that);
- } else {
- mask = mask_to_bitmap(xinfo.screen());
- }
- return mask;
-}
-
-/*!
- Sets a mask bitmap.
-
- The \a newmask bitmap defines the clip mask for this pixmap. Every
- pixel in \a newmask corresponds to a pixel in this pixmap. Pixel
- value 1 means opaque and pixel value 0 means transparent. The mask
- must have the same size as this pixmap.
-
- \warning Setting the mask on a pixmap will cause any alpha channel
- data to be cleared. For example:
- \snippet doc/src/snippets/image/image.cpp 2
- Now, alpha and alphacopy are visually different.
-
- Setting a null mask resets the mask.
-
- The effect of this function is undefined when the pixmap is being
- painted on.
-
- \sa mask(), {QPixmap#Pixmap Transformations}{Pixmap
- Transformations}, QBitmap
-*/
-void QX11PixmapData::setMask(const QBitmap &newmask)
-{
- if (newmask.isNull()) { // clear mask
-#ifndef QT_NO_XRENDER
- if (picture && d == 32) {
- QX11PixmapData newData(pixelType());
- newData.resize(w, h);
- newData.fill(Qt::black);
- XRenderComposite(X11->display, PictOpOver,
- picture, 0, newData.picture,
- 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;
- newData.mask_picture = 0;
- newData.hd2 = 0;
- } else
-#endif
- if (x11_mask) {
-#ifndef QT_NO_XRENDER
- if (picture) {
- XRenderPictureAttributes attrs;
- attrs.alpha_map = 0;
- XRenderChangePicture(X11->display, picture, CPAlphaMap,
- &attrs);
- }
- if (mask_picture)
- XRenderFreePicture(X11->display, mask_picture);
- mask_picture = 0;
-#endif
- XFreePixmap(X11->display, x11_mask);
- x11_mask = 0;
- }
- return;
- }
-
-#ifndef QT_NO_XRENDER
- if (picture && d == 32) {
- XRenderComposite(X11->display, PictOpSrc,
- picture, newmask.x11PictureHandle(),
- picture, 0, 0, 0, 0, 0, 0, w, h);
- } else
-#endif
- if (depth() == 1) {
- XGCValues vals;
- vals.function = GXand;
- GC gc = XCreateGC(X11->display, hd, GCFunction, &vals);
- XCopyArea(X11->display, newmask.handle(), hd, gc, 0, 0,
- width(), height(), 0, 0);
- XFreeGC(X11->display, gc);
- } else {
- // ##### should or the masks together
- if (x11_mask) {
- XFreePixmap(X11->display, x11_mask);
-#ifndef QT_NO_XRENDER
- if (mask_picture)
- XRenderFreePicture(X11->display, mask_picture);
-#endif
- }
- x11_mask = QX11PixmapData::bitmap_to_mask(newmask, xinfo.screen());
-#ifndef QT_NO_XRENDER
- if (picture) {
- mask_picture = XRenderCreatePicture(X11->display, x11_mask,
- XRenderFindStandardFormat(X11->display, PictStandardA1), 0, 0);
- XRenderPictureAttributes attrs;
- attrs.alpha_map = mask_picture;
- XRenderChangePicture(X11->display, picture, CPAlphaMap, &attrs);
- }
-#endif
- }
-}
-
-int QX11PixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const
-{
- switch (metric) {
- case QPaintDevice::PdmWidth:
- return w;
- case QPaintDevice::PdmHeight:
- return h;
- case QPaintDevice::PdmNumColors:
- return 1 << d;
- case QPaintDevice::PdmDepth:
- return d;
- case QPaintDevice::PdmWidthMM: {
- const int screen = xinfo.screen();
- const int mm = DisplayWidthMM(X11->display, screen) * w
- / DisplayWidth(X11->display, screen);
- return mm;
- }
- case QPaintDevice::PdmHeightMM: {
- const int screen = xinfo.screen();
- const int mm = (DisplayHeightMM(X11->display, screen) * h)
- / DisplayHeight(X11->display, screen);
- return mm;
- }
- case QPaintDevice::PdmDpiX:
- case QPaintDevice::PdmPhysicalDpiX:
- return QX11Info::appDpiX(xinfo.screen());
- case QPaintDevice::PdmDpiY:
- case QPaintDevice::PdmPhysicalDpiY:
- return QX11Info::appDpiY(xinfo.screen());
- default:
- qWarning("QX11PixmapData::metric(): Invalid metric");
- return 0;
- }
-}
-
-struct QXImageWrapper
-{
- XImage *xi;
-};
-
-bool QX11PixmapData::canTakeQImageFromXImage(const QXImageWrapper &xiWrapper) const
-{
- XImage *xi = xiWrapper.xi;
-
- // ARGB32_Premultiplied
- if (picture && depth() == 32)
- return true;
-
- Visual *visual = (Visual *)xinfo.visual();
-
- // RGB32
- if (depth() == 24 && xi->bits_per_pixel == 32 && visual->red_mask == 0xff0000
- && visual->green_mask == 0xff00 && visual->blue_mask == 0xff)
- return true;
-
- // RGB16
- if (depth() == 16 && xi->bits_per_pixel == 16 && visual->red_mask == 0xf800
- && visual->green_mask == 0x7e0 && visual->blue_mask == 0x1f)
- return true;
-
- return false;
-}
-
-QImage QX11PixmapData::takeQImageFromXImage(const QXImageWrapper &xiWrapper) const
-{
- XImage *xi = xiWrapper.xi;
-
- QImage::Format format = QImage::Format_ARGB32_Premultiplied;
- if (depth() == 24)
- format = QImage::Format_RGB32;
- else if (depth() == 16)
- format = QImage::Format_RGB16;
-
- QImage image((uchar *)xi->data, xi->width, xi->height, xi->bytes_per_line, format);
- // take ownership
- image.data_ptr()->own_data = true;
- xi->data = 0;
-
- // we may have to swap the byte order
- if ((QSysInfo::ByteOrder == QSysInfo::LittleEndian && xi->byte_order == MSBFirst)
- || (QSysInfo::ByteOrder == QSysInfo::BigEndian && xi->byte_order == LSBFirst))
- {
- for (int i=0; i < image.height(); i++) {
- if (depth() == 16) {
- ushort *p = (ushort*)image.scanLine(i);
- ushort *end = p + image.width();
- while (p < end) {
- *p = ((*p << 8) & 0xff00) | ((*p >> 8) & 0x00ff);
- p++;
- }
- } else {
- uint *p = (uint*)image.scanLine(i);
- uint *end = p + image.width();
- while (p < end) {
- *p = ((*p << 24) & 0xff000000) | ((*p << 8) & 0x00ff0000)
- | ((*p >> 8) & 0x0000ff00) | ((*p >> 24) & 0x000000ff);
- p++;
- }
- }
- }
- }
-
- // fix-up alpha channel
- if (format == QImage::Format_RGB32) {
- QRgb *p = (QRgb *)image.bits();
- for (int y = 0; y < xi->height; ++y) {
- for (int x = 0; x < xi->width; ++x)
- p[x] |= 0xff000000;
- p += xi->bytes_per_line / 4;
- }
- }
-
- XDestroyImage(xi);
- return image;
-}
-
-QImage QX11PixmapData::toImage(const QRect &rect) const
-{
- QXImageWrapper xiWrapper;
- xiWrapper.xi = XGetImage(X11->display, hd, rect.x(), rect.y(), rect.width(), rect.height(),
- AllPlanes, (depth() == 1) ? XYPixmap : ZPixmap);
-
- Q_CHECK_PTR(xiWrapper.xi);
- if (!xiWrapper.xi)
- return QImage();
-
- if (!x11_mask && canTakeQImageFromXImage(xiWrapper))
- return takeQImageFromXImage(xiWrapper);
-
- QImage image = toImage(xiWrapper, rect);
- qSafeXDestroyImage(xiWrapper.xi);
- return image;
-}
-
-/*!
- Converts the pixmap to a QImage. Returns a null image if the
- conversion fails.
-
- If the pixmap has 1-bit depth, the returned image will also be 1
- bit deep. If the pixmap has 2- to 8-bit depth, the returned image
- has 8-bit depth. If the pixmap has greater than 8-bit depth, the
- returned image has 32-bit depth.
-
- Note that for the moment, alpha masks on monochrome images are
- ignored.
-
- \sa fromImage(), {QImage#Image Formats}{Image Formats}
-*/
-
-QImage QX11PixmapData::toImage() const
-{
- return toImage(QRect(0, 0, w, h));
-}
-
-QImage QX11PixmapData::toImage(const QXImageWrapper &xiWrapper, const QRect &rect) const
-{
- XImage *xi = xiWrapper.xi;
-
- int d = depth();
- Visual *visual = (Visual *)xinfo.visual();
- bool trucol = (visual->c_class >= TrueColor) && d > 1;
-
- QImage::Format format = QImage::Format_Mono;
- if (d > 1 && d <= 8) {
- d = 8;
- format = QImage::Format_Indexed8;
- }
- // we could run into the situation where d == 8 AND trucol is true, which can
- // cause problems when converting to and from images. in this case, always treat
- // the depth as 32...
- if (d > 8 || trucol) {
- d = 32;
- format = QImage::Format_RGB32;
- }
-
- if (d == 1 && xi->bitmap_bit_order == LSBFirst)
- format = QImage::Format_MonoLSB;
- if (x11_mask && format == QImage::Format_RGB32)
- format = QImage::Format_ARGB32;
-
- QImage image(xi->width, xi->height, format);
- if (image.isNull()) // could not create image
- return image;
-
- QImage alpha;
- if (x11_mask) {
- if (rect.contains(QRect(0, 0, w, h)))
- alpha = mask().toImage();
- else
- alpha = mask().toImage().copy(rect);
- }
- bool ale = alpha.format() == QImage::Format_MonoLSB;
-
- if (trucol) { // truecolor
- const uint red_mask = (uint)visual->red_mask;
- const uint green_mask = (uint)visual->green_mask;
- const uint blue_mask = (uint)visual->blue_mask;
- const int red_shift = highest_bit(red_mask) - 7;
- const int green_shift = highest_bit(green_mask) - 7;
- const int blue_shift = highest_bit(blue_mask) - 7;
-
- const uint red_bits = n_bits(red_mask);
- const uint green_bits = n_bits(green_mask);
- const uint blue_bits = n_bits(blue_mask);
-
- static uint red_table_bits = 0;
- static uint green_table_bits = 0;
- static uint blue_table_bits = 0;
-
- if (red_bits < 8 && red_table_bits != red_bits) {
- build_scale_table(&red_scale_table, red_bits);
- red_table_bits = red_bits;
- }
- if (blue_bits < 8 && blue_table_bits != blue_bits) {
- build_scale_table(&blue_scale_table, blue_bits);
- blue_table_bits = blue_bits;
- }
- if (green_bits < 8 && green_table_bits != green_bits) {
- build_scale_table(&green_scale_table, green_bits);
- green_table_bits = green_bits;
- }
-
- int r, g, b;
-
- QRgb *dst;
- uchar *src;
- uint pixel;
- int bppc = xi->bits_per_pixel;
-
- if (bppc > 8 && xi->byte_order == LSBFirst)
- bppc++;
-
- for (int y = 0; y < xi->height; ++y) {
- uchar* asrc = x11_mask ? alpha.scanLine(y) : 0;
- dst = (QRgb *)image.scanLine(y);
- src = (uchar *)xi->data + xi->bytes_per_line*y;
- for (int x = 0; x < xi->width; x++) {
- switch (bppc) {
- case 8:
- pixel = *src++;
- break;
- case 16: // 16 bit MSB
- pixel = src[1] | (uint)src[0] << 8;
- src += 2;
- break;
- case 17: // 16 bit LSB
- pixel = src[0] | (uint)src[1] << 8;
- src += 2;
- break;
- case 24: // 24 bit MSB
- pixel = src[2] | (uint)src[1] << 8 | (uint)src[0] << 16;
- src += 3;
- break;
- case 25: // 24 bit LSB
- pixel = src[0] | (uint)src[1] << 8 | (uint)src[2] << 16;
- src += 3;
- break;
- case 32: // 32 bit MSB
- pixel = src[3] | (uint)src[2] << 8 | (uint)src[1] << 16 | (uint)src[0] << 24;
- src += 4;
- break;
- case 33: // 32 bit LSB
- pixel = src[0] | (uint)src[1] << 8 | (uint)src[2] << 16 | (uint)src[3] << 24;
- src += 4;
- break;
- default: // should not really happen
- x = xi->width; // leave loop
- y = xi->height;
- pixel = 0; // eliminate compiler warning
- qWarning("QPixmap::convertToImage: Invalid depth %d", bppc);
- }
- if (red_shift > 0)
- r = (pixel & red_mask) >> red_shift;
- else
- r = (pixel & red_mask) << -red_shift;
- if (green_shift > 0)
- g = (pixel & green_mask) >> green_shift;
- else
- g = (pixel & green_mask) << -green_shift;
- if (blue_shift > 0)
- b = (pixel & blue_mask) >> blue_shift;
- else
- b = (pixel & blue_mask) << -blue_shift;
-
- if (red_bits < 8)
- r = red_scale_table[r];
- if (green_bits < 8)
- g = green_scale_table[g];
- if (blue_bits < 8)
- b = blue_scale_table[b];
-
- if (x11_mask) {
- if (ale) {
- *dst++ = (asrc[x >> 3] & (1 << (x & 7))) ? qRgba(r, g, b, 0xff) : 0;
- } else {
- *dst++ = (asrc[x >> 3] & (0x80 >> (x & 7))) ? qRgba(r, g, b, 0xff) : 0;
- }
- } else {
- *dst++ = qRgb(r, g, b);
- }
- }
- }
- } else if (xi->bits_per_pixel == d) { // compatible depth
- char *xidata = xi->data; // copy each scanline
- int bpl = qMin(image.bytesPerLine(),xi->bytes_per_line);
- for (int y=0; y<xi->height; y++) {
- memcpy(image.scanLine(y), xidata, bpl);
- xidata += xi->bytes_per_line;
- }
- } else {
- /* Typically 2 or 4 bits display depth */
- qWarning("QPixmap::convertToImage: Display not supported (bpp=%d)",
- xi->bits_per_pixel);
- return QImage();
- }
-
- if (d == 1) { // bitmap
- image.setColorCount(2);
- image.setColor(0, qRgb(255,255,255));
- image.setColor(1, qRgb(0,0,0));
- } else if (!trucol) { // pixmap with colormap
- register uchar *p;
- uchar *end;
- uchar use[256]; // pixel-in-use table
- uchar pix[256]; // pixel translation table
- int ncols, bpl;
- memset(use, 0, 256);
- memset(pix, 0, 256);
- bpl = image.bytesPerLine();
-
- if (x11_mask) { // which pixels are used?
- for (int i = 0; i < xi->height; i++) {
- uchar* asrc = alpha.scanLine(i);
- p = image.scanLine(i);
- if (ale) {
- for (int x = 0; x < xi->width; x++) {
- if (asrc[x >> 3] & (1 << (x & 7)))
- use[*p] = 1;
- ++p;
- }
- } else {
- for (int x = 0; x < xi->width; x++) {
- if (asrc[x >> 3] & (0x80 >> (x & 7)))
- use[*p] = 1;
- ++p;
- }
- }
- }
- } else {
- for (int i = 0; i < xi->height; i++) {
- p = image.scanLine(i);
- end = p + bpl;
- while (p < end)
- use[*p++] = 1;
- }
- }
- ncols = 0;
- for (int i = 0; i < 256; i++) { // build translation table
- if (use[i])
- pix[i] = ncols++;
- }
- for (int i = 0; i < xi->height; i++) { // translate pixels
- p = image.scanLine(i);
- end = p + bpl;
- while (p < end) {
- *p = pix[*p];
- p++;
- }
- }
- if (x11_mask) {
- int trans;
- if (ncols < 256) {
- trans = ncols++;
- image.setColorCount(ncols); // create color table
- image.setColor(trans, 0x00000000);
- } else {
- image.setColorCount(ncols); // create color table
- // oh dear... no spare "transparent" pixel.
- // use first pixel in image (as good as any).
- trans = image.scanLine(0)[0];
- }
- for (int i = 0; i < xi->height; i++) {
- uchar* asrc = alpha.scanLine(i);
- p = image.scanLine(i);
- if (ale) {
- for (int x = 0; x < xi->width; x++) {
- if (!(asrc[x >> 3] & (1 << (x & 7))))
- *p = trans;
- ++p;
- }
- } else {
- for (int x = 0; x < xi->width; x++) {
- if (!(asrc[x >> 3] & (1 << (7 -(x & 7)))))
- *p = trans;
- ++p;
- }
- }
- }
- } else {
- image.setColorCount(ncols); // create color table
- }
- QVector<QColor> colors = QColormap::instance(xinfo.screen()).colormap();
- int j = 0;
- for (int i=0; i<colors.size(); i++) { // translate pixels
- if (use[i])
- image.setColor(j++, 0xff000000 | colors.at(i).rgb());
- }
- }
-
- return image;
-}
-
-/*!
- Returns a copy of the pixmap that is transformed using the given
- transformation \a matrix and transformation \a mode. The original
- pixmap is not changed.
-
- The transformation \a matrix is internally adjusted to compensate
- for unwanted translation; i.e. the pixmap produced is the smallest
- pixmap that contains all the transformed points of the original
- pixmap. Use the trueMatrix() function to retrieve the actual
- matrix used for transforming the pixmap.
-
- This function is slow because it involves transformation to a
- QImage, non-trivial computations and a transformation back to a
- QPixmap.
-
- \sa trueMatrix(), {QPixmap#Pixmap Transformations}{Pixmap
- Transformations}
-*/
-QPixmap QX11PixmapData::transformed(const QTransform &transform,
- Qt::TransformationMode mode ) const
-{
- if (mode == Qt::SmoothTransformation || transform.type() >= QTransform::TxProject) {
- QImage image = toImage();
- return QPixmap::fromImage(image.transformed(transform, mode));
- }
-
- uint w = 0;
- uint h = 0; // size of target pixmap
- uint ws, hs; // size of source pixmap
- uchar *dptr; // data in target pixmap
- uint dbpl, dbytes; // bytes per line/bytes total
- uchar *sptr; // data in original pixmap
- int sbpl; // bytes per line in original
- int bpp; // bits per pixel
- bool depth1 = depth() == 1;
- Display *dpy = X11->display;
-
- ws = width();
- hs = height();
-
- QTransform mat(transform.m11(), transform.m12(), transform.m13(),
- transform.m21(), transform.m22(), transform.m23(),
- 0., 0., 1);
- bool complex_xform = false;
- qreal scaledWidth;
- qreal scaledHeight;
-
- if (mat.type() <= QTransform::TxScale) {
- scaledHeight = qAbs(mat.m22()) * hs + 0.9999;
- scaledWidth = qAbs(mat.m11()) * ws + 0.9999;
- h = qAbs(int(scaledHeight));
- w = qAbs(int(scaledWidth));
- } else { // rotation or shearing
- QPolygonF a(QRectF(0, 0, ws, hs));
- a = mat.map(a);
- QRect r = a.boundingRect().toAlignedRect();
- w = r.width();
- h = r.height();
- scaledWidth = w;
- scaledHeight = h;
- complex_xform = true;
- }
- mat = QPixmap::trueMatrix(mat, ws, hs); // true matrix
-
- bool invertible;
- mat = mat.inverted(&invertible); // invert matrix
-
- if (h == 0 || w == 0 || !invertible
- || qAbs(scaledWidth) >= 32768 || qAbs(scaledHeight) >= 32768 )
- // error, return null pixmap
- return QPixmap();
-
-#if defined(QT_MITSHM)
- static bool try_once = true;
- if (try_once) {
- try_once = false;
- if (!xshminit)
- qt_create_mitshm_buffer(this, 800, 600);
- }
-
- bool use_mitshm = xshmimg && !depth1 &&
- xshmimg->width >= w && xshmimg->height >= h;
-#endif
- XImage *xi = XGetImage(X11->display, handle(), 0, 0, ws, hs, AllPlanes,
- depth1 ? XYPixmap : ZPixmap);
-
- if (!xi)
- return QPixmap();
-
- sbpl = xi->bytes_per_line;
- sptr = (uchar *)xi->data;
- bpp = xi->bits_per_pixel;
-
- if (depth1)
- dbpl = (w+7)/8;
- else
- dbpl = ((w*bpp+31)/32)*4;
- dbytes = dbpl*h;
-
-#if defined(QT_MITSHM)
- if (use_mitshm) {
- dptr = (uchar *)xshmimg->data;
- uchar fillbyte = bpp == 8 ? white.pixel() : 0xff;
- for (int y=0; y<h; y++)
- memset(dptr + y*xshmimg->bytes_per_line, fillbyte, dbpl);
- } else {
-#endif
- dptr = (uchar *)malloc(dbytes); // create buffer for bits
- Q_CHECK_PTR(dptr);
- if (depth1) // fill with zeros
- memset(dptr, 0, dbytes);
- else if (bpp == 8) // fill with background color
- memset(dptr, WhitePixel(X11->display, xinfo.screen()), dbytes);
- else
- memset(dptr, 0, dbytes);
-#if defined(QT_MITSHM)
- }
-#endif
-
- // #define QT_DEBUG_XIMAGE
-#if defined(QT_DEBUG_XIMAGE)
- qDebug("----IMAGE--INFO--------------");
- qDebug("width............. %d", xi->width);
- qDebug("height............ %d", xi->height);
- qDebug("xoffset........... %d", xi->xoffset);
- qDebug("format............ %d", xi->format);
- qDebug("byte order........ %d", xi->byte_order);
- qDebug("bitmap unit....... %d", xi->bitmap_unit);
- qDebug("bitmap bit order.. %d", xi->bitmap_bit_order);
- qDebug("depth............. %d", xi->depth);
- qDebug("bytes per line.... %d", xi->bytes_per_line);
- qDebug("bits per pixel.... %d", xi->bits_per_pixel);
-#endif
-
- int type;
- if (xi->bitmap_bit_order == MSBFirst)
- type = QT_XFORM_TYPE_MSBFIRST;
- else
- type = QT_XFORM_TYPE_LSBFIRST;
- int xbpl, p_inc;
- if (depth1) {
- xbpl = (w+7)/8;
- p_inc = dbpl - xbpl;
- } else {
- xbpl = (w*bpp)/8;
- p_inc = dbpl - xbpl;
-#if defined(QT_MITSHM)
- if (use_mitshm)
- p_inc = xshmimg->bytes_per_line - xbpl;
-#endif
- }
-
- if (!qt_xForm_helper(mat, xi->xoffset, type, bpp, dptr, xbpl, p_inc, h, sptr, sbpl, ws, hs)){
- qWarning("QPixmap::transform: display not supported (bpp=%d)",bpp);
- QPixmap pm;
- return pm;
- }
-
- qSafeXDestroyImage(xi);
-
- if (depth1) { // mono bitmap
- QBitmap bm = QBitmap::fromData(QSize(w, h), dptr,
- BitmapBitOrder(X11->display) == MSBFirst
- ? QImage::Format_Mono
- : QImage::Format_MonoLSB);
- free(dptr);
- return bm;
- } else { // color pixmap
- QX11PixmapData *x11Data = new QX11PixmapData(QPixmapData::PixmapType);
- QPixmap pm(x11Data);
- x11Data->flags &= ~QX11PixmapData::Uninitialized;
- x11Data->xinfo = xinfo;
- x11Data->d = d;
- x11Data->w = w;
- x11Data->h = h;
- x11Data->is_null = (w <= 0 || h <= 0);
- x11Data->hd = (Qt::HANDLE)XCreatePixmap(X11->display,
- RootWindow(X11->display, xinfo.screen()),
- w, h, d);
- x11Data->setSerialNumber(qt_pixmap_serial.fetchAndAddRelaxed(1));
-
-#ifndef QT_NO_XRENDER
- if (X11->use_xrender) {
- XRenderPictFormat *format = x11Data->d == 32
- ? XRenderFindStandardFormat(X11->display, PictStandardARGB32)
- : XRenderFindVisualFormat(X11->display, (Visual *) x11Data->xinfo.visual());
- x11Data->picture = XRenderCreatePicture(X11->display, x11Data->hd, format, 0, 0);
- }
-#endif // QT_NO_XRENDER
-
- GC gc = XCreateGC(X11->display, x11Data->hd, 0, 0);
-#if defined(QT_MITSHM)
- if (use_mitshm) {
- XCopyArea(dpy, xshmpm, x11Data->hd, gc, 0, 0, w, h, 0, 0);
- } else
-#endif
- {
- xi = XCreateImage(dpy, (Visual*)x11Data->xinfo.visual(),
- x11Data->d,
- ZPixmap, 0, (char *)dptr, w, h, 32, 0);
- XPutImage(dpy, pm.handle(), gc, xi, 0, 0, 0, 0, w, h);
- qSafeXDestroyImage(xi);
- }
- XFreeGC(X11->display, gc);
-
- if (x11_mask) { // xform mask, too
- pm.setMask(mask_to_bitmap(xinfo.screen()).transformed(transform));
- } else if (d != 32 && complex_xform) { // need a mask!
- QBitmap mask(ws, hs);
- mask.fill(Qt::color1);
- pm.setMask(mask.transformed(transform));
- }
- return pm;
- }
-}
-
-int QPixmap::x11SetDefaultScreen(int screen)
-{
- int old = defaultScreen;
- defaultScreen = screen;
- return old;
-}
-
-void QPixmap::x11SetScreen(int screen)
-{
- if (paintingActive()) {
- qWarning("QPixmap::x11SetScreen(): Cannot change screens during painting");
- return;
- }
-
- if (isNull())
- return;
-
- if (data->classId() != QPixmapData::X11Class)
- return;
-
- if (screen < 0)
- screen = QX11Info::appScreen();
-
- QX11PixmapData *x11Data = static_cast<QX11PixmapData*>(data.data());
- if (screen == x11Data->xinfo.screen())
- return; // nothing to do
-
- if (isNull()) {
- QX11InfoData* xd = x11Data->xinfo.getX11Data(true);
- xd->screen = screen;
- xd->depth = QX11Info::appDepth(screen);
- xd->cells = QX11Info::appCells(screen);
- xd->colormap = QX11Info::appColormap(screen);
- xd->defaultColormap = QX11Info::appDefaultColormap(screen);
- xd->visual = (Visual *)QX11Info::appVisual(screen);
- xd->defaultVisual = QX11Info::appDefaultVisual(screen);
- x11Data->xinfo.setX11Data(xd);
- return;
- }
-#if 0
- qDebug("QPixmap::x11SetScreen for %p from %d to %d. Size is %d/%d", x11Data, x11Data->xinfo.screen(), screen, width(), height());
-#endif
-
- x11SetDefaultScreen(screen);
- *this = qt_toX11Pixmap(toImage());
-}
-
-QPixmap QPixmap::grabWindow(WId window, int x, int y, int w, int h)
-{
- if (w == 0 || h == 0)
- return QPixmap();
-
- Display *dpy = X11->display;
- XWindowAttributes window_attr;
- if (!XGetWindowAttributes(dpy, window, &window_attr))
- return QPixmap();
-
- if (w < 0)
- w = window_attr.width - x;
- if (h < 0)
- h = window_attr.height - y;
-
- // determine the screen
- int scr;
- for (scr = 0; scr < ScreenCount(dpy); ++scr) {
- if (window_attr.root == RootWindow(dpy, scr)) // found it
- break;
- }
- if (scr >= ScreenCount(dpy)) // sanity check
- return QPixmap();
-
-
- // get the depth of the root window
- XWindowAttributes root_attr;
- if (!XGetWindowAttributes(dpy, window_attr.root, &root_attr))
- return QPixmap();
-
- if (window_attr.depth == root_attr.depth) {
- // if the depth of the specified window and the root window are the
- // same, grab pixels from the root window (so that we get the any
- // overlapping windows and window manager frames)
-
- // map x and y to the root window
- WId unused;
- if (!XTranslateCoordinates(dpy, window, window_attr.root, x, y,
- &x, &y, &unused))
- return QPixmap();
-
- window = window_attr.root;
- window_attr = root_attr;
- }
-
- QX11PixmapData *data = new QX11PixmapData(QPixmapData::PixmapType);
-
- void qt_x11_getX11InfoForWindow(QX11Info * xinfo, const XWindowAttributes &a);
- qt_x11_getX11InfoForWindow(&data->xinfo,window_attr);
-
- data->resize(w, h);
-
- QPixmap pm(data);
-
- data->flags &= ~QX11PixmapData::Uninitialized;
- pm.x11SetScreen(scr);
-
- GC gc = XCreateGC(dpy, pm.handle(), 0, 0);
- XSetSubwindowMode(dpy, gc, IncludeInferiors);
- XCopyArea(dpy, window, pm.handle(), gc, x, y, w, h, 0, 0);
- XFreeGC(dpy, gc);
-
- return pm;
-}
-
-bool QX11PixmapData::hasAlphaChannel() const
-{
- return d == 32;
-}
-
-const QX11Info &QPixmap::x11Info() const
-{
- if (data && data->classId() == QPixmapData::X11Class)
- return static_cast<QX11PixmapData*>(data.data())->xinfo;
- else {
- static QX11Info nullX11Info;
- return nullX11Info;
- }
-}
-
-#if !defined(QT_NO_XRENDER)
-static XRenderPictFormat *qt_renderformat_for_depth(const QX11Info &xinfo, int depth)
-{
- if (depth == 1)
- return XRenderFindStandardFormat(X11->display, PictStandardA1);
- else if (depth == 32)
- return XRenderFindStandardFormat(X11->display, PictStandardARGB32);
- else
- return XRenderFindVisualFormat(X11->display, (Visual *)xinfo.visual());
-}
-#endif
-
-QPaintEngine* QX11PixmapData::paintEngine() const
-{
- QX11PixmapData *that = const_cast<QX11PixmapData*>(this);
-
- if ((flags & Readonly) && share_mode == QPixmap::ImplicitlyShared) {
- // if someone wants to draw onto us, copy the shared contents
- // and turn it into a fully fledged QPixmap
- ::Pixmap hd_copy = XCreatePixmap(X11->display, RootWindow(X11->display, xinfo.screen()),
- w, h, d);
-#if !defined(QT_NO_XRENDER)
- XRenderPictFormat *format = qt_renderformat_for_depth(xinfo, d);
- ::Picture picture_copy = XRenderCreatePicture(X11->display, hd_copy, format, 0, 0);
-
- if (picture && d == 32) {
- XRenderComposite(X11->display, PictOpSrc, picture, 0, picture_copy,
- 0, 0, 0, 0, 0, 0, w, h);
- XRenderFreePicture(X11->display, picture);
- that->picture = picture_copy;
- } else
-#endif
- {
- GC gc = XCreateGC(X11->display, hd_copy, 0, 0);
- XCopyArea(X11->display, hd, hd_copy, gc, 0, 0, w, h, 0, 0);
- XFreeGC(X11->display, gc);
- }
- that->hd = hd_copy;
- that->flags &= ~QX11PixmapData::Readonly;
- }
-
- if (!that->pengine)
- that->pengine = new QX11PaintEngine;
- return that->pengine;
-}
-
-Qt::HANDLE QPixmap::x11PictureHandle() const
-{
-#ifndef QT_NO_XRENDER
- if (data && data->classId() == QPixmapData::X11Class)
- return static_cast<const QX11PixmapData*>(data.data())->picture;
- else
- return 0;
-#else
- return 0;
-#endif // QT_NO_XRENDER
-}
-
-Qt::HANDLE QX11PixmapData::x11ConvertToDefaultDepth()
-{
-#ifndef QT_NO_XRENDER
- if (d == QX11Info::appDepth() || !X11->use_xrender)
- return hd;
- if (!hd2) {
- hd2 = XCreatePixmap(xinfo.display(), hd, w, h, QX11Info::appDepth());
- XRenderPictFormat *format = XRenderFindVisualFormat(xinfo.display(),
- (Visual*) xinfo.visual());
- Picture pic = XRenderCreatePicture(xinfo.display(), hd2, format, 0, 0);
- XRenderComposite(xinfo.display(), PictOpSrc, picture,
- XNone, pic, 0, 0, 0, 0, 0, 0, w, h);
- XRenderFreePicture(xinfo.display(), pic);
- }
- return hd2;
-#else
- return hd;
-#endif
-}
-
-void QX11PixmapData::copy(const QPixmapData *data, const QRect &rect)
-{
- if (data->pixelType() == BitmapType) {
- fromImage(data->toImage().copy(rect), Qt::AutoColor);
- return;
- }
-
- const QX11PixmapData *x11Data = static_cast<const QX11PixmapData*>(data);
-
- setSerialNumber(qt_pixmap_serial.fetchAndAddRelaxed(1));
-
- flags &= ~Uninitialized;
- xinfo = x11Data->xinfo;
- d = x11Data->d;
- w = rect.width();
- h = rect.height();
- is_null = (w <= 0 || h <= 0);
- hd = (Qt::HANDLE)XCreatePixmap(X11->display,
- RootWindow(X11->display, x11Data->xinfo.screen()),
- w, h, d);
-#ifndef QT_NO_XRENDER
- if (X11->use_xrender) {
- XRenderPictFormat *format = d == 32
- ? XRenderFindStandardFormat(X11->display, PictStandardARGB32)
- : XRenderFindVisualFormat(X11->display, (Visual *)xinfo.visual());
- picture = XRenderCreatePicture(X11->display, hd, format, 0, 0);
- }
-#endif // QT_NO_XRENDER
- if (x11Data->x11_mask) {
- x11_mask = XCreatePixmap(X11->display, hd, w, h, 1);
-#ifndef QT_NO_XRENDER
- if (X11->use_xrender) {
- mask_picture = XRenderCreatePicture(X11->display, x11_mask,
- XRenderFindStandardFormat(X11->display, PictStandardA1), 0, 0);
- XRenderPictureAttributes attrs;
- attrs.alpha_map = x11Data->mask_picture;
- XRenderChangePicture(X11->display, x11Data->picture, CPAlphaMap, &attrs);
- }
-#endif
- }
-
-#if !defined(QT_NO_XRENDER)
- if (x11Data->picture && x11Data->d == 32) {
- XRenderComposite(X11->display, PictOpSrc,
- x11Data->picture, 0, picture,
- rect.x(), rect.y(), 0, 0, 0, 0, w, h);
- } else
-#endif
- {
- GC gc = XCreateGC(X11->display, hd, 0, 0);
- XCopyArea(X11->display, x11Data->hd, hd, gc,
- rect.x(), rect.y(), w, h, 0, 0);
- if (x11Data->x11_mask) {
- GC monogc = XCreateGC(X11->display, x11_mask, 0, 0);
- XCopyArea(X11->display, x11Data->x11_mask, x11_mask, monogc,
- rect.x(), rect.y(), w, h, 0, 0);
- XFreeGC(X11->display, monogc);
- }
- XFreeGC(X11->display, gc);
- }
-}
-
-bool QX11PixmapData::scroll(int dx, int dy, const QRect &rect)
-{
- GC gc = XCreateGC(X11->display, hd, 0, 0);
- XCopyArea(X11->display, hd, hd, gc,
- rect.left(), rect.top(), rect.width(), rect.height(),
- rect.left() + dx, rect.top() + dy);
- XFreeGC(X11->display, gc);
- return true;
-}
-
-#if !defined(QT_NO_XRENDER)
-void QX11PixmapData::convertToARGB32(bool preserveContents)
-{
- if (!X11->use_xrender)
- return;
-
- // Q_ASSERT(count == 1);
- if ((flags & Readonly) && share_mode == QPixmap::ExplicitlyShared)
- return;
-
- Pixmap pm = XCreatePixmap(X11->display, RootWindow(X11->display, xinfo.screen()),
- w, h, 32);
- Picture p = XRenderCreatePicture(X11->display, pm,
- XRenderFindStandardFormat(X11->display, PictStandardARGB32), 0, 0);
- if (picture) {
- if (preserveContents)
- XRenderComposite(X11->display, PictOpSrc, picture, 0, p, 0, 0, 0, 0, 0, 0, w, h);
- if (!(flags & Readonly))
- XRenderFreePicture(X11->display, picture);
- }
- if (hd && !(flags & Readonly))
- XFreePixmap(X11->display, hd);
- if (x11_mask) {
- XFreePixmap(X11->display, x11_mask);
- if (mask_picture)
- XRenderFreePicture(X11->display, mask_picture);
- x11_mask = 0;
- mask_picture = 0;
- }
- hd = pm;
- picture = p;
- d = 32;
-}
-#endif
-
-QPixmap QPixmap::fromX11Pixmap(Qt::HANDLE pixmap, QPixmap::ShareMode mode)
-{
- Window root;
- int x;
- int y;
- uint width;
- uint height;
- uint border_width;
- uint depth;
- XWindowAttributes win_attribs;
- int num_screens = ScreenCount(X11->display);
- int screen = 0;
-
- XGetGeometry(X11->display, pixmap, &root, &x, &y, &width, &height, &border_width, &depth);
- XGetWindowAttributes(X11->display, root, &win_attribs);
-
- for (; screen < num_screens; ++screen) {
- if (win_attribs.screen == ScreenOfDisplay(X11->display, screen))
- break;
- }
-
- QX11PixmapData *data = new QX11PixmapData(depth == 1 ? QPixmapData::BitmapType : QPixmapData::PixmapType);
- data->setSerialNumber(qt_pixmap_serial.fetchAndAddRelaxed(1));
- data->flags = QX11PixmapData::Readonly;
- data->share_mode = mode;
- data->w = width;
- data->h = height;
- data->is_null = (width <= 0 || height <= 0);
- data->d = depth;
- data->hd = pixmap;
-
- if (defaultScreen >= 0 && defaultScreen != screen) {
- QX11InfoData* xd = data->xinfo.getX11Data(true);
- xd->screen = defaultScreen;
- xd->depth = QX11Info::appDepth(xd->screen);
- xd->cells = QX11Info::appCells(xd->screen);
- xd->colormap = QX11Info::appColormap(xd->screen);
- xd->defaultColormap = QX11Info::appDefaultColormap(xd->screen);
- xd->visual = (Visual *)QX11Info::appVisual(xd->screen);
- xd->defaultVisual = QX11Info::appDefaultVisual(xd->screen);
- data->xinfo.setX11Data(xd);
- }
-
-#ifndef QT_NO_XRENDER
- if (X11->use_xrender) {
- XRenderPictFormat *format = qt_renderformat_for_depth(data->xinfo, depth);
- data->picture = XRenderCreatePicture(X11->display, data->hd, format, 0, 0);
- }
-#endif // QT_NO_XRENDER
-
- return QPixmap(data);
-}
-
-
-QT_END_NAMESPACE
diff --git a/src/gui/image/qpixmap_x11_p.h b/src/gui/image/qpixmap_x11_p.h
deleted file mode 100644
index 7cd80e62f9..0000000000
--- a/src/gui/image/qpixmap_x11_p.h
+++ /dev/null
@@ -1,156 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPIXMAPDATA_X11_P_H
-#define QPIXMAPDATA_X11_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtGui/private/qpixmapdata_p.h>
-#include <QtGui/private/qpixmapdatafactory_p.h>
-
-#include "QtGui/qx11info_x11.h"
-
-QT_BEGIN_NAMESPACE
-
-class QX11PaintEngine;
-
-struct QXImageWrapper;
-
-class Q_GUI_EXPORT QX11PixmapData : public QPixmapData
-{
-public:
- QX11PixmapData(PixelType type);
-// QX11PixmapData(PixelType type, int width, int height);
-// QX11PixmapData(PixelType type, const QImage &image,
-// Qt::ImageConversionFlags flags);
- ~QX11PixmapData();
-
- QPixmapData *createCompatiblePixmapData() const;
-
- void resize(int width, int height);
- void fromImage(const QImage &image, Qt::ImageConversionFlags flags);
- void copy(const QPixmapData *data, const QRect &rect);
- bool scroll(int dx, int dy, const QRect &rect);
-
- void fill(const QColor &color);
- QBitmap mask() const;
- void setMask(const QBitmap &mask);
- bool hasAlphaChannel() const;
- void setAlphaChannel(const QPixmap &alphaChannel);
- QPixmap alphaChannel() const;
- QPixmap transformed(const QTransform &transform,
- Qt::TransformationMode mode) const;
- QImage toImage() const;
- QImage toImage(const QRect &rect) const;
- QPaintEngine* paintEngine() const;
-
- Qt::HANDLE handle() const { return hd; }
- Qt::HANDLE x11ConvertToDefaultDepth();
-
- static Qt::HANDLE createBitmapFromImage(const QImage &image);
-
- void* gl_surface;
-#ifndef QT_NO_XRENDER
- void convertToARGB32(bool preserveContents = true);
-#endif
-
-protected:
- int metric(QPaintDevice::PaintDeviceMetric metric) const;
-
-private:
- friend class QPixmap;
- friend class QBitmap;
- friend class QX11PaintEngine;
- friend class QX11WindowSurface;
- friend class QRasterWindowSurface;
- friend class QGLContextPrivate; // Needs to access xinfo, gl_surface & flags
- friend class QEglContext; // Needs gl_surface
- friend class QGLContext; // Needs gl_surface
- friend class QX11GLPixmapData; // Needs gl_surface
- friend class QMeeGoLivePixmapData; // Needs gl_surface and flags
- friend bool qt_createEGLSurfaceForPixmap(QPixmapData*, bool); // Needs gl_surface
-
- void release();
-
- QImage toImage(const QXImageWrapper &xi, const QRect &rect) const;
-
- QBitmap mask_to_bitmap(int screen) const;
- static Qt::HANDLE bitmap_to_mask(const QBitmap &, int screen);
- void bitmapFromImage(const QImage &image);
-
- bool canTakeQImageFromXImage(const QXImageWrapper &xi) const;
- QImage takeQImageFromXImage(const QXImageWrapper &xi) const;
-
- Qt::HANDLE hd;
-
- enum Flag {
- NoFlags = 0x0,
- Uninitialized = 0x1,
- Readonly = 0x2,
- InvertedWhenBoundToTexture = 0x4,
- GlSurfaceCreatedWithAlpha = 0x8
- };
- uint flags;
-
- QX11Info xinfo;
- Qt::HANDLE x11_mask;
- Qt::HANDLE picture;
- Qt::HANDLE mask_picture;
- Qt::HANDLE hd2; // sorted in the default display depth
- QPixmap::ShareMode share_mode;
-
- QX11PaintEngine *pengine;
-};
-
-QT_END_NAMESPACE
-
-#endif // QPIXMAPDATA_X11_P_H
-
diff --git a/src/gui/image/qpixmapcache_p.h b/src/gui/image/qpixmapcache_p.h
index 336c0f01d4..7b96f5a2cf 100644
--- a/src/gui/image/qpixmapcache_p.h
+++ b/src/gui/image/qpixmapcache_p.h
@@ -81,9 +81,9 @@ class QPixmapCacheEntry : public QPixmap
public:
QPixmapCacheEntry(const QPixmapCache::Key &key, const QPixmap &pix) : QPixmap(pix), key(key)
{
- QPixmapData *pd = pixmapData();
- if (pd && pd->classId() == QPixmapData::RasterClass) {
- QRasterPixmapData *d = static_cast<QRasterPixmapData*>(pd);
+ QPlatformPixmap *pd = handle();
+ if (pd && pd->classId() == QPlatformPixmap::RasterClass) {
+ QRasterPlatformPixmap *d = static_cast<QRasterPlatformPixmap*>(pd);
if (!d->image.isNull() && d->image.d->paintEngine
&& !d->image.d->paintEngine->isActive())
{
diff --git a/src/gui/image/qpixmapdata.cpp b/src/gui/image/qpixmapdata.cpp
deleted file mode 100644
index c46429cf40..0000000000
--- a/src/gui/image/qpixmapdata.cpp
+++ /dev/null
@@ -1,290 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qpixmapdata_p.h"
-#include <QtCore/qbuffer.h>
-#include <QtGui/qbitmap.h>
-#include <QtGui/qimagereader.h>
-#include <private/qgraphicssystem_p.h>
-#include <private/qapplication_p.h>
-#include <private/qimagepixmapcleanuphooks_p.h>
-
-QT_BEGIN_NAMESPACE
-
-const uchar qt_pixmap_bit_mask[] = { 0x01, 0x02, 0x04, 0x08,
- 0x10, 0x20, 0x40, 0x80 };
-
-QPixmapData *QPixmapData::create(int w, int h, PixelType type)
-{
- QPixmapData *data;
- QGraphicsSystem* gs = QApplicationPrivate::graphicsSystem();
- if (gs)
- data = gs->createPixmapData(static_cast<QPixmapData::PixelType>(type));
- else
- data = QGraphicsSystem::createDefaultPixmapData(static_cast<QPixmapData::PixelType>(type));
- data->resize(w, h);
- return data;
-}
-
-
-QPixmapData::QPixmapData(PixelType pixelType, int objectId)
- : w(0),
- h(0),
- d(0),
- is_null(true),
- ref(0),
- detach_no(0),
- type(pixelType),
- id(objectId),
- ser_no(0),
- is_cached(false)
-{
-}
-
-QPixmapData::~QPixmapData()
-{
- // Sometimes the pixmap cleanup hooks will be called from derrived classes, which will
- // then set is_cached to false. For example, on X11 QtOpenGL needs to delete the GLXPixmap
- // or EGL Pixmap Surface for a given pixmap _before_ the native X11 pixmap is deleted,
- // otherwise some drivers will leak the GL surface. In this case, QX11PixmapData will
- // call the cleanup hooks itself before deleting the native pixmap and set is_cached to
- // false.
- if (is_cached) {
- QImagePixmapCleanupHooks::executePixmapDataDestructionHooks(this);
- is_cached = false;
- }
-}
-
-QPixmapData *QPixmapData::createCompatiblePixmapData() const
-{
- QPixmapData *d;
- QGraphicsSystem *gs = QApplicationPrivate::graphicsSystem();
- if (gs)
- d = gs->createPixmapData(pixelType());
- else
- d = QGraphicsSystem::createDefaultPixmapData(pixelType());
- return d;
-}
-
-static QImage makeBitmapCompliantIfNeeded(QPixmapData *d, const QImage &image, Qt::ImageConversionFlags flags)
-{
- if (d->pixelType() == QPixmapData::BitmapType) {
- QImage img = image.convertToFormat(QImage::Format_MonoLSB, flags);
-
- // make sure image.color(0) == Qt::color0 (white)
- // and image.color(1) == Qt::color1 (black)
- const QRgb c0 = QColor(Qt::black).rgb();
- const QRgb c1 = QColor(Qt::white).rgb();
- if (img.color(0) == c0 && img.color(1) == c1) {
- img.invertPixels();
- img.setColor(0, c1);
- img.setColor(1, c0);
- }
- return img;
- }
-
- return image;
-}
-
-void QPixmapData::fromImageReader(QImageReader *imageReader,
- Qt::ImageConversionFlags flags)
-{
- const QImage image = imageReader->read();
- fromImage(image, flags);
-}
-
-bool QPixmapData::fromFile(const QString &fileName, const char *format,
- Qt::ImageConversionFlags flags)
-{
- QImage image = QImageReader(fileName, format).read();
- if (image.isNull())
- return false;
- fromImage(makeBitmapCompliantIfNeeded(this, image, flags), flags);
- return !isNull();
-}
-
-bool QPixmapData::fromData(const uchar *buf, uint len, const char *format, Qt::ImageConversionFlags flags)
-{
- QByteArray a = QByteArray::fromRawData(reinterpret_cast<const char *>(buf), len);
- QBuffer b(&a);
- b.open(QIODevice::ReadOnly);
- QImage image = QImageReader(&b, format).read();
- fromImage(makeBitmapCompliantIfNeeded(this, image, flags), flags);
- return !isNull();
-}
-
-void QPixmapData::copy(const QPixmapData *data, const QRect &rect)
-{
- fromImage(data->toImage(rect), Qt::NoOpaqueDetection);
-}
-
-bool QPixmapData::scroll(int dx, int dy, const QRect &rect)
-{
- Q_UNUSED(dx);
- Q_UNUSED(dy);
- Q_UNUSED(rect);
- return false;
-}
-
-void QPixmapData::setMask(const QBitmap &mask)
-{
- if (mask.size().isEmpty()) {
- if (depth() != 1)
- fromImage(toImage().convertToFormat(QImage::Format_RGB32),
- Qt::AutoColor);
- } else {
- QImage image = toImage();
- const int w = image.width();
- const int h = image.height();
-
- switch (image.depth()) {
- case 1: {
- const QImage imageMask = mask.toImage().convertToFormat(image.format());
- for (int y = 0; y < h; ++y) {
- const uchar *mscan = imageMask.scanLine(y);
- uchar *tscan = image.scanLine(y);
- int bytesPerLine = image.bytesPerLine();
- for (int i = 0; i < bytesPerLine; ++i)
- tscan[i] &= mscan[i];
- }
- break;
- }
- default: {
- const QImage imageMask = mask.toImage().convertToFormat(QImage::Format_MonoLSB);
- image = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
- for (int y = 0; y < h; ++y) {
- const uchar *mscan = imageMask.scanLine(y);
- QRgb *tscan = (QRgb *)image.scanLine(y);
- for (int x = 0; x < w; ++x) {
- if (!(mscan[x>>3] & qt_pixmap_bit_mask[x&7]))
- tscan[x] = 0;
- }
- }
- break;
- }
- }
- fromImage(image, Qt::AutoColor);
- }
-}
-
-QBitmap QPixmapData::mask() const
-{
- if (!hasAlphaChannel())
- return QBitmap();
-
- const QImage img = toImage();
- const QImage image = (img.depth() < 32 ? img.convertToFormat(QImage::Format_ARGB32_Premultiplied) : img);
- const int w = image.width();
- const int h = image.height();
-
- QImage mask(w, h, QImage::Format_MonoLSB);
- if (mask.isNull()) // allocation failed
- return QBitmap();
-
- mask.setColorCount(2);
- mask.setColor(0, QColor(Qt::color0).rgba());
- mask.setColor(1, QColor(Qt::color1).rgba());
-
- const int bpl = mask.bytesPerLine();
-
- for (int y = 0; y < h; ++y) {
- const QRgb *src = reinterpret_cast<const QRgb*>(image.scanLine(y));
- uchar *dest = mask.scanLine(y);
- memset(dest, 0, bpl);
- for (int x = 0; x < w; ++x) {
- if (qAlpha(*src) > 0)
- dest[x >> 3] |= qt_pixmap_bit_mask[x & 7];
- ++src;
- }
- }
-
- return QBitmap::fromImage(mask);
-}
-
-QPixmap QPixmapData::transformed(const QTransform &matrix,
- Qt::TransformationMode mode) const
-{
- return QPixmap::fromImage(toImage().transformed(matrix, mode));
-}
-
-void QPixmapData::setAlphaChannel(const QPixmap &alphaChannel)
-{
- QImage image = toImage();
- image.setAlphaChannel(alphaChannel.toImage());
- fromImage(image, Qt::AutoColor);
-}
-
-QPixmap QPixmapData::alphaChannel() const
-{
- return QPixmap::fromImage(toImage().alphaChannel());
-}
-
-void QPixmapData::setSerialNumber(int serNo)
-{
- ser_no = serNo;
-}
-
-QImage QPixmapData::toImage(const QRect &rect) const
-{
- if (rect.contains(QRect(0, 0, w, h)))
- return toImage();
- else
- return toImage().copy(rect);
-}
-
-QImage* QPixmapData::buffer()
-{
- return 0;
-}
-
-#if defined(Q_OS_SYMBIAN)
-void* QPixmapData::toNativeType(NativeType /* type */)
-{
- return 0;
-}
-
-void QPixmapData::fromNativeType(void* /* pixmap */, NativeType /* typre */)
-{
- return;
-}
-#endif
-
-QT_END_NAMESPACE
diff --git a/src/gui/image/qpixmapdata_p.h b/src/gui/image/qpixmapdata_p.h
deleted file mode 100644
index 5b75aa102b..0000000000
--- a/src/gui/image/qpixmapdata_p.h
+++ /dev/null
@@ -1,180 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPIXMAPDATA_P_H
-#define QPIXMAPDATA_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtGui/qpixmap.h>
-#include <QtCore/qatomic.h>
-
-QT_BEGIN_NAMESPACE
-
-class QImageReader;
-
-class Q_GUI_EXPORT QPixmapData
-{
-public:
- enum PixelType {
- // WARNING: Do not change the first two
- // Must match QPixmap::Type
- PixmapType, BitmapType
- };
-#if defined(Q_OS_SYMBIAN)
- enum NativeType {
- FbsBitmap,
- SgImage,
- VolatileImage,
- NativeImageHandleProvider
- };
-#endif
- enum ClassId { RasterClass, X11Class, MacClass, DirectFBClass,
- OpenGLClass, OpenVGClass, RuntimeClass, BlitterClass,
- CustomClass = 1024 };
-
- QPixmapData(PixelType pixelType, int classId);
- virtual ~QPixmapData();
-
- virtual QPixmapData *createCompatiblePixmapData() const;
-
- virtual void resize(int width, int height) = 0;
- virtual void fromImage(const QImage &image,
- Qt::ImageConversionFlags flags) = 0;
- virtual void fromImageReader(QImageReader *imageReader,
- Qt::ImageConversionFlags flags);
-
- virtual bool fromFile(const QString &filename, const char *format,
- Qt::ImageConversionFlags flags);
- virtual bool fromData(const uchar *buffer, uint len, const char *format,
- Qt::ImageConversionFlags flags);
-
- virtual void copy(const QPixmapData *data, const QRect &rect);
- virtual bool scroll(int dx, int dy, const QRect &rect);
-
- virtual int metric(QPaintDevice::PaintDeviceMetric metric) const = 0;
- virtual void fill(const QColor &color) = 0;
- virtual QBitmap mask() const;
- virtual void setMask(const QBitmap &mask);
- virtual bool hasAlphaChannel() const = 0;
- virtual QPixmap transformed(const QTransform &matrix,
- Qt::TransformationMode mode) const;
- virtual void setAlphaChannel(const QPixmap &alphaChannel);
- virtual QPixmap alphaChannel() const;
- virtual QImage toImage() const = 0;
- virtual QImage toImage(const QRect &rect) const;
- virtual QPaintEngine* paintEngine() const = 0;
-
- inline int serialNumber() const { return ser_no; }
-
- inline PixelType pixelType() const { return type; }
- inline ClassId classId() const { return static_cast<ClassId>(id); }
-
- virtual QImage* buffer();
-
- inline int width() const { return w; }
- inline int height() const { return h; }
- QT_DEPRECATED inline int numColors() const { return metric(QPaintDevice::PdmNumColors); }
- inline int colorCount() const { return metric(QPaintDevice::PdmNumColors); }
- inline int depth() const { return d; }
- inline bool isNull() const { return is_null; }
- inline qint64 cacheKey() const {
- int classKey = id;
- if (classKey >= 1024)
- classKey = -(classKey >> 10);
- return ((((qint64) classKey) << 56)
- | (((qint64) ser_no) << 32)
- | ((qint64) detach_no));
- }
-
-#if defined(Q_OS_SYMBIAN)
- virtual void* toNativeType(NativeType type);
- virtual void fromNativeType(void* pixmap, NativeType type);
-#endif
-
- static QPixmapData *create(int w, int h, PixelType type);
-
- virtual QPixmapData *runtimeData() const { return 0; }
-
-protected:
-
- void setSerialNumber(int serNo);
- int w;
- int h;
- int d;
- bool is_null;
-
-private:
- friend class QPixmap;
- friend class QX11PixmapData;
- friend class QS60PixmapData;
- friend class QImagePixmapCleanupHooks; // Needs to set is_cached
- friend class QGLTextureCache; //Needs to check the reference count
- friend class QExplicitlySharedDataPointer<QPixmapData>;
-
- QAtomicInt ref;
- int detach_no;
-
- PixelType type;
- int id;
- int ser_no;
- uint is_cached;
-};
-
-# define QT_XFORM_TYPE_MSBFIRST 0
-# define QT_XFORM_TYPE_LSBFIRST 1
-# if defined(Q_WS_WIN)
-# define QT_XFORM_TYPE_WINDOWSPIXMAP 2
-# endif
-extern bool qt_xForm_helper(const QTransform&, int, int, int, uchar*, int, int, int, const uchar*, int, int, int);
-
-QT_END_NAMESPACE
-
-#endif // QPIXMAPDATA_P_H
diff --git a/src/gui/image/qpixmapdatafactory.cpp b/src/gui/image/qpixmapdatafactory.cpp
deleted file mode 100644
index f7c79880ca..0000000000
--- a/src/gui/image/qpixmapdatafactory.cpp
+++ /dev/null
@@ -1,115 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qpixmapdatafactory_p.h"
-
-#ifdef Q_WS_QWS
-# include <QtGui/qscreen_qws.h>
-#endif
-#ifdef Q_WS_X11
-# include <private/qpixmap_x11_p.h>
-#endif
-#if defined(Q_WS_WIN)
-# include <private/qpixmap_raster_p.h>
-#endif
-#ifdef Q_WS_MAC
-# include <private/qpixmap_mac_p.h>
-#endif
-#ifdef Q_WS_QPA
-# include <private/qpixmap_raster_p.h>
-#endif
-#ifdef Q_OS_SYMBIAN
-# include <private/qpixmap_s60_p.h>
-#endif
-
-#include "private/qapplication_p.h"
-#include "private/qgraphicssystem_p.h"
-
-QT_BEGIN_NAMESPACE
-
-#if !defined(Q_WS_QWS)
-
-class QSimplePixmapDataFactory : public QPixmapDataFactory
-{
-public:
- ~QSimplePixmapDataFactory() {}
- QPixmapData* create(QPixmapData::PixelType type);
-};
-
-QPixmapData* QSimplePixmapDataFactory::create(QPixmapData::PixelType type)
-{
- if (QApplicationPrivate::graphicsSystem())
- return QApplicationPrivate::graphicsSystem()->createPixmapData(type);
-
-#if defined(Q_WS_X11)
- return new QX11PixmapData(type);
-#elif defined(Q_WS_WIN)
- return new QRasterPixmapData(type);
-#elif defined(Q_WS_MAC)
- return new QMacPixmapData(type);
-#elif defined(Q_WS_QPA)
- return new QRasterPixmapData(type);
-#elif defined(Q_OS_SYMBIAN)
- return new QS60PixmapData(type);
-#else
-#error QSimplePixmapDataFactory::create() not implemented
-#endif
-}
-
-Q_GLOBAL_STATIC(QSimplePixmapDataFactory, factory)
-
-#endif // !defined(Q_WS_QWS)
-
-QPixmapDataFactory::~QPixmapDataFactory()
-{
-}
-
-QPixmapDataFactory* QPixmapDataFactory::instance(int screen)
-{
- Q_UNUSED(screen);
-#ifdef Q_WS_QWS
- return QScreen::instance()->pixmapDataFactory();
-#else
- return factory();
-#endif
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/image/qpixmapdatafactory_p.h b/src/gui/image/qpixmapdatafactory_p.h
deleted file mode 100644
index a539d672c3..0000000000
--- a/src/gui/image/qpixmapdatafactory_p.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPIXMAPDATAFACTORY_P_H
-#define QPIXMAPDATAFACTORY_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/qstring.h>
-#include <QtGui/qimage.h>
-#include <QtGui/private/qpixmapdata_p.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QPixmapData;
-
-class QPixmapDataFactory
-{
-public:
- static QPixmapDataFactory* instance(int screen = 0);
- virtual ~QPixmapDataFactory();
-
- virtual QPixmapData* create(QPixmapData::PixelType type) = 0;
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QPIXMAPDATAFACTORY_P_H
diff --git a/src/gui/image/qpixmapfilter.cpp b/src/gui/image/qpixmapfilter.cpp
deleted file mode 100644
index a33e173f70..0000000000
--- a/src/gui/image/qpixmapfilter.cpp
+++ /dev/null
@@ -1,1382 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qglobal.h>
-
-#include <QDebug>
-
-#include "qpainter.h"
-#include "qpixmap.h"
-#include "qpixmapfilter_p.h"
-#include "qvarlengtharray.h"
-
-#include "private/qapplication_p.h"
-#include "private/qgraphicssystem_p.h"
-#include "private/qpaintengineex_p.h"
-#include "private/qpaintengine_raster_p.h"
-#include "qmath.h"
-#include "private/qmath_p.h"
-#include "private/qmemrotate_p.h"
-#include "private/qdrawhelper_p.h"
-
-#ifndef QT_NO_GRAPHICSEFFECT
-QT_BEGIN_NAMESPACE
-
-class QPixmapFilterPrivate : public QObjectPrivate
-{
- Q_DECLARE_PUBLIC(QPixmapFilter)
-public:
- QPixmapFilter::FilterType type;
-};
-
-/*!
- \class QPixmapFilter
- \since 4.5
- \ingroup painting
-
- \brief The QPixmapFilter class provides the basic functionality for
- pixmap filter classes. Pixmap filter can be for example colorize or blur.
-
- QPixmapFilter is the base class for every pixmap filter. QPixmapFilter is
- an abstract class and cannot itself be instantiated. It provides a standard
- interface for filter processing.
-
- \internal
-*/
-
-/*!
- \enum QPixmapFilter::FilterType
-
- \internal
-
- This enum describes the types of filter that can be applied to pixmaps.
-
- \value ConvolutionFilter A filter that is used to calculate the convolution
- of the image with a kernel. See
- QPixmapConvolutionFilter for more information.
- \value ColorizeFilter A filter that is used to change the overall color
- of an image. See QPixmapColorizeFilter for more
- information.
- \value DropShadowFilter A filter that is used to add a drop shadow to an
- image. See QPixmapDropShadowFilter for more
- information.
- \value BlurFilter A filter that is used to blur an image using
- a simple blur radius. See QPixmapBlurFilter
- for more information.
-
- \value UserFilter The first filter type that can be used for
- application-specific purposes.
-*/
-
-
-/*!
- Constructs a default QPixmapFilter with the given \a type.
-
- This constructor should be used when subclassing QPixmapFilter to
- create custom user filters.
-
- \internal
-*/
-QPixmapFilter::QPixmapFilter(FilterType type, QObject *parent)
- : QObject(*new QPixmapFilterPrivate, parent)
-{
- d_func()->type = type;
-}
-
-
-
-/*!
- \internal
-*/
-QPixmapFilter::QPixmapFilter(QPixmapFilterPrivate&d, QPixmapFilter::FilterType type, QObject *parent)
- : QObject(d, parent)
-{
- d_func()->type = type;
-}
-
-
-/*!
- Destroys the pixmap filter.
-
- \internal
-*/
-QPixmapFilter::~QPixmapFilter()
-{
-}
-
-/*!
- Returns the type of the filter. All standard pixmap filter classes
- are associated with a unique value.
-
- \internal
-*/
-QPixmapFilter::FilterType QPixmapFilter::type() const
-{
- Q_D(const QPixmapFilter);
- return d->type;
-}
-
-/*!
- Returns the bounding rectangle that is affected by the pixmap
- filter if the filter is applied to the specified \a rect.
-
- \internal
-*/
-QRectF QPixmapFilter::boundingRectFor(const QRectF &rect) const
-{
- return rect;
-}
-
-/*!
- \fn void QPixmapFilter::draw(QPainter *painter, const QPointF &p, const QPixmap &src, const QRectF& srcRect) const
-
- Uses \a painter to draw filtered result of \a src at the point
- specified by \a p. If \a srcRect is specified the it will
- be used as a source rectangle to only draw a part of the source.
-
- draw() will affect the area which boundingRectFor() returns.
-
- \internal
-*/
-
-/*!
- \class QPixmapConvolutionFilter
- \since 4.5
- \ingroup painting
-
- \brief The QPixmapConvolutionFilter class provides convolution
- filtering for pixmaps.
-
- QPixmapConvolutionFilter implements a convolution pixmap filter,
- which is applied when \l{QPixmapFilter::}{draw()} is called. A
- convolution filter lets you distort an image by setting the values
- of a matrix of qreal values called its
- \l{setConvolutionKernel()}{kernel}. The matrix's values are
- usually between -1.0 and 1.0.
-
- \omit
- In convolution filtering, the pixel value is calculated from the
- neighboring pixels based on the weighting convolution kernel.
- This needs explaining to be useful.
- \endomit
-
- Example:
- \snippet doc/src/snippets/code/src_gui_image_qpixmapfilter.cpp 1
-
- \sa {Pixmap Filters Example}, QPixmapColorizeFilter, QPixmapDropShadowFilter
-
-
- \internal
-*/
-
-class QPixmapConvolutionFilterPrivate : public QPixmapFilterPrivate
-{
-public:
- QPixmapConvolutionFilterPrivate(): convolutionKernel(0), kernelWidth(0), kernelHeight(0), convoluteAlpha(false) {}
- ~QPixmapConvolutionFilterPrivate() {
- delete[] convolutionKernel;
- }
-
- qreal *convolutionKernel;
- int kernelWidth;
- int kernelHeight;
- bool convoluteAlpha;
-};
-
-
-/*!
- Constructs a pixmap convolution filter.
-
- By default there is no convolution kernel.
-
- \internal
-*/
-QPixmapConvolutionFilter::QPixmapConvolutionFilter(QObject *parent)
- : QPixmapFilter(*new QPixmapConvolutionFilterPrivate, ConvolutionFilter, parent)
-{
- Q_D(QPixmapConvolutionFilter);
- d->convoluteAlpha = true;
-}
-
-/*!
- Destructor of pixmap convolution filter.
-
- \internal
-*/
-QPixmapConvolutionFilter::~QPixmapConvolutionFilter()
-{
-}
-
-/*!
- Sets convolution kernel with the given number of \a rows and \a columns.
- Values from \a kernel are copied to internal data structure.
-
- To preserve the intensity of the pixmap, the sum of all the
- values in the convolution kernel should add up to 1.0. A sum
- greater than 1.0 produces a lighter result and a sum less than 1.0
- produces a darker and transparent result.
-
- \internal
-*/
-void QPixmapConvolutionFilter::setConvolutionKernel(const qreal *kernel, int rows, int columns)
-{
- Q_D(QPixmapConvolutionFilter);
- delete [] d->convolutionKernel;
- d->convolutionKernel = new qreal[rows * columns];
- memcpy(d->convolutionKernel, kernel, sizeof(qreal) * rows * columns);
- d->kernelWidth = columns;
- d->kernelHeight = rows;
-}
-
-/*!
- Gets the convolution kernel data.
-
- \internal
-*/
-const qreal *QPixmapConvolutionFilter::convolutionKernel() const
-{
- Q_D(const QPixmapConvolutionFilter);
- return d->convolutionKernel;
-}
-
-/*!
- Gets the number of rows in the convolution kernel.
-
- \internal
-*/
-int QPixmapConvolutionFilter::rows() const
-{
- Q_D(const QPixmapConvolutionFilter);
- return d->kernelHeight;
-}
-
-/*!
- Gets the number of columns in the convolution kernel.
-
- \internal
-*/
-int QPixmapConvolutionFilter::columns() const
-{
- Q_D(const QPixmapConvolutionFilter);
- return d->kernelWidth;
-}
-
-
-/*!
- \internal
-*/
-QRectF QPixmapConvolutionFilter::boundingRectFor(const QRectF &rect) const
-{
- Q_D(const QPixmapConvolutionFilter);
- return rect.adjusted(-d->kernelWidth / 2, -d->kernelHeight / 2, (d->kernelWidth - 1) / 2, (d->kernelHeight - 1) / 2);
-}
-
-// Convolutes the image
-static void convolute(
- QImage *destImage,
- const QPointF &pos,
- const QImage &srcImage,
- const QRectF &srcRect,
- QPainter::CompositionMode mode,
- qreal *kernel,
- int kernelWidth,
- int kernelHeight )
-{
- const QImage processImage = (srcImage.format() != QImage::Format_ARGB32_Premultiplied ) ? srcImage.convertToFormat(QImage::Format_ARGB32_Premultiplied) : srcImage;
- // TODO: support also other formats directly without copying
-
- int *fixedKernel = new int[kernelWidth*kernelHeight];
- for(int i = 0; i < kernelWidth*kernelHeight; i++)
- {
- fixedKernel[i] = (int)(65536 * kernel[i]);
- }
- QRectF trect = srcRect.isNull() ? processImage.rect() : srcRect;
- trect.moveTo(pos);
- QRectF bounded = trect.adjusted(-kernelWidth / 2, -kernelHeight / 2, (kernelWidth - 1) / 2, (kernelHeight - 1) / 2);
- QRect rect = bounded.toAlignedRect();
- QRect targetRect = rect.intersected(destImage->rect());
-
- QRectF srect = srcRect.isNull() ? processImage.rect() : srcRect;
- QRectF sbounded = srect.adjusted(-kernelWidth / 2, -kernelHeight / 2, (kernelWidth - 1) / 2, (kernelHeight - 1) / 2);
- QPoint srcStartPoint = sbounded.toAlignedRect().topLeft()+(targetRect.topLeft()-rect.topLeft());
-
- const uint *sourceStart = (uint*)processImage.scanLine(0);
- uint *outputStart = (uint*)destImage->scanLine(0);
-
- int yk = srcStartPoint.y();
- for (int y = targetRect.top(); y <= targetRect.bottom(); y++) {
- uint* output = outputStart + (destImage->bytesPerLine()/sizeof(uint))*y+targetRect.left();
- int xk = srcStartPoint.x();
- for(int x = targetRect.left(); x <= targetRect.right(); x++) {
- int r = 0;
- int g = 0;
- int b = 0;
- int a = 0;
-
- // some out of bounds pre-checking to avoid inner-loop ifs
- int kernely = -kernelHeight/2;
- int starty = 0;
- int endy = kernelHeight;
- if(yk+kernely+endy >= srcImage.height())
- endy = kernelHeight-((yk+kernely+endy)-srcImage.height())-1;
- if(yk+kernely < 0)
- starty = -(yk+kernely);
-
- int kernelx = -kernelWidth/2;
- int startx = 0;
- int endx = kernelWidth;
- if(xk+kernelx+endx >= srcImage.width())
- endx = kernelWidth-((xk+kernelx+endx)-srcImage.width())-1;
- if(xk+kernelx < 0)
- startx = -(xk+kernelx);
-
- for (int ys = starty; ys < endy; ys ++) {
- const uint *pix = sourceStart + (processImage.bytesPerLine()/sizeof(uint))*(yk+kernely+ys) + ((xk+kernelx+startx));
- const uint *endPix = pix+endx-startx;
- int kernelPos = ys*kernelWidth+startx;
- while (pix < endPix) {
- int factor = fixedKernel[kernelPos++];
- a += (((*pix) & 0xff000000)>>24) * factor;
- r += (((*pix) & 0x00ff0000)>>16) * factor;
- g += (((*pix) & 0x0000ff00)>>8 ) * factor;
- b += (((*pix) & 0x000000ff) ) * factor;
- pix++;
- }
- }
-
- r = qBound((int)0, r >> 16, (int)255);
- g = qBound((int)0, g >> 16, (int)255);
- b = qBound((int)0, b >> 16, (int)255);
- a = qBound((int)0, a >> 16, (int)255);
- // composition mode checking could be moved outside of loop
- if(mode == QPainter::CompositionMode_Source) {
- uint color = (a<<24)+(r<<16)+(g<<8)+b;
- *output++ = color;
- } else {
- uint current = *output;
- uchar ca = (current&0xff000000)>>24;
- uchar cr = (current&0x00ff0000)>>16;
- uchar cg = (current&0x0000ff00)>>8;
- uchar cb = (current&0x000000ff);
- uint color =
- (((ca*(255-a) >> 8)+a) << 24)+
- (((cr*(255-a) >> 8)+r) << 16)+
- (((cg*(255-a) >> 8)+g) << 8)+
- (((cb*(255-a) >> 8)+b));
- *output++ = color;;
- }
- xk++;
- }
- yk++;
- }
- delete[] fixedKernel;
-}
-
-/*!
- \internal
-*/
-void QPixmapConvolutionFilter::draw(QPainter *painter, const QPointF &p, const QPixmap &src, const QRectF& srcRect) const
-{
- Q_D(const QPixmapConvolutionFilter);
- if (!painter->isActive())
- return;
-
- if(d->kernelWidth<=0 || d->kernelHeight <= 0)
- return;
-
- if (src.isNull())
- return;
-
- QPixmapFilter *filter = painter->paintEngine() && painter->paintEngine()->isExtended() ?
- static_cast<QPaintEngineEx *>(painter->paintEngine())->pixmapFilter(type(), this) : 0;
- QPixmapConvolutionFilter *convolutionFilter = static_cast<QPixmapConvolutionFilter*>(filter);
- if (convolutionFilter) {
- convolutionFilter->setConvolutionKernel(d->convolutionKernel, d->kernelWidth, d->kernelHeight);
- convolutionFilter->d_func()->convoluteAlpha = d->convoluteAlpha;
- convolutionFilter->draw(painter, p, src, srcRect);
- return;
- }
-
- // falling back to raster implementation
-
- QImage *target = 0;
- if (painter->paintEngine()->paintDevice()->devType() == QInternal::Image) {
- target = static_cast<QImage *>(painter->paintEngine()->paintDevice());
-
- QTransform mat = painter->combinedTransform();
-
- if (mat.type() > QTransform::TxTranslate) {
- // Disabled because of transformation...
- target = 0;
- } else {
- QRasterPaintEngine *pe = static_cast<QRasterPaintEngine *>(painter->paintEngine());
- if (pe->clipType() == QRasterPaintEngine::ComplexClip)
- // disabled because of complex clipping...
- target = 0;
- else {
- QRectF clip = pe->clipBoundingRect();
- QRectF rect = boundingRectFor(srcRect.isEmpty() ? src.rect() : srcRect);
- QTransform x = painter->deviceTransform();
- if (!clip.contains(rect.translated(x.dx() + p.x(), x.dy() + p.y()))) {
- target = 0;
- }
-
- }
- }
- }
-
- if (target) {
- QTransform x = painter->deviceTransform();
- QPointF offset(x.dx(), x.dy());
-
- convolute(target, p+offset, src.toImage(), srcRect, QPainter::CompositionMode_SourceOver, d->convolutionKernel, d->kernelWidth, d->kernelHeight);
- } else {
- QRect srect = srcRect.isNull() ? src.rect() : srcRect.toRect();
- QRect rect = boundingRectFor(srect).toRect();
- QImage result = QImage(rect.size(), QImage::Format_ARGB32_Premultiplied);
- QPoint offset = srect.topLeft() - rect.topLeft();
- convolute(&result,
- offset,
- src.toImage(),
- srect,
- QPainter::CompositionMode_Source,
- d->convolutionKernel,
- d->kernelWidth,
- d->kernelHeight);
- painter->drawImage(p - offset, result);
- }
-}
-
-/*!
- \class QPixmapBlurFilter
- \since 4.6
- \ingroup multimedia
-
- \brief The QPixmapBlurFilter class provides blur filtering
- for pixmaps.
-
- QPixmapBlurFilter implements a blur pixmap filter,
- which is applied when \l{QPixmapFilter::}{draw()} is called.
-
- The filter lets you specialize the radius of the blur as well
- as hints as to whether to prefer performance or quality.
-
- By default, the blur effect is produced by applying an exponential
- filter generated from the specified blurRadius(). Paint engines
- may override this with a custom blur that is faster on the
- underlying hardware.
-
- \sa {Pixmap Filters Example}, QPixmapConvolutionFilter, QPixmapDropShadowFilter
-
- \internal
-*/
-
-class QPixmapBlurFilterPrivate : public QPixmapFilterPrivate
-{
-public:
- QPixmapBlurFilterPrivate() : radius(5), hints(QGraphicsBlurEffect::PerformanceHint) {}
-
- qreal radius;
- QGraphicsBlurEffect::BlurHints hints;
-};
-
-
-/*!
- Constructs a pixmap blur filter.
-
- \internal
-*/
-QPixmapBlurFilter::QPixmapBlurFilter(QObject *parent)
- : QPixmapFilter(*new QPixmapBlurFilterPrivate, BlurFilter, parent)
-{
-}
-
-/*!
- Destructor of pixmap blur filter.
-
- \internal
-*/
-QPixmapBlurFilter::~QPixmapBlurFilter()
-{
-}
-
-/*!
- Sets the radius of the blur filter. Higher radius produces increased blurriness.
-
- \internal
-*/
-void QPixmapBlurFilter::setRadius(qreal radius)
-{
- Q_D(QPixmapBlurFilter);
- d->radius = radius;
-}
-
-/*!
- Gets the radius of the blur filter.
-
- \internal
-*/
-qreal QPixmapBlurFilter::radius() const
-{
- Q_D(const QPixmapBlurFilter);
- return d->radius;
-}
-
-/*!
- Setting the blur hints to PerformanceHint causes the implementation
- to trade off visual quality to blur the image faster. Setting the
- blur hints to QualityHint causes the implementation to improve
- visual quality at the expense of speed.
-
- AnimationHint causes the implementation to optimize for animating
- the blur radius, possibly by caching blurred versions of the source
- pixmap.
-
- The implementation is free to ignore this value if it only has a single
- blur algorithm.
-
- \internal
-*/
-void QPixmapBlurFilter::setBlurHints(QGraphicsBlurEffect::BlurHints hints)
-{
- Q_D(QPixmapBlurFilter);
- d->hints = hints;
-}
-
-/*!
- Gets the blur hints of the blur filter.
-
- \internal
-*/
-QGraphicsBlurEffect::BlurHints QPixmapBlurFilter::blurHints() const
-{
- Q_D(const QPixmapBlurFilter);
- return d->hints;
-}
-
-const qreal radiusScale = qreal(2.5);
-
-/*!
- \internal
-*/
-QRectF QPixmapBlurFilter::boundingRectFor(const QRectF &rect) const
-{
- Q_D(const QPixmapBlurFilter);
- const qreal delta = radiusScale * d->radius + 1;
- return rect.adjusted(-delta, -delta, delta, delta);
-}
-
-template <int shift>
-inline int qt_static_shift(int value)
-{
- if (shift == 0)
- return value;
- else if (shift > 0)
- return value << (uint(shift) & 0x1f);
- else
- return value >> (uint(-shift) & 0x1f);
-}
-
-template<int aprec, int zprec>
-inline void qt_blurinner(uchar *bptr, int &zR, int &zG, int &zB, int &zA, int alpha)
-{
- QRgb *pixel = (QRgb *)bptr;
-
-#define Z_MASK (0xff << zprec)
- const int A_zprec = qt_static_shift<zprec - 24>(*pixel) & Z_MASK;
- const int R_zprec = qt_static_shift<zprec - 16>(*pixel) & Z_MASK;
- const int G_zprec = qt_static_shift<zprec - 8>(*pixel) & Z_MASK;
- const int B_zprec = qt_static_shift<zprec>(*pixel) & Z_MASK;
-#undef Z_MASK
-
- const int zR_zprec = zR >> aprec;
- const int zG_zprec = zG >> aprec;
- const int zB_zprec = zB >> aprec;
- const int zA_zprec = zA >> aprec;
-
- zR += alpha * (R_zprec - zR_zprec);
- zG += alpha * (G_zprec - zG_zprec);
- zB += alpha * (B_zprec - zB_zprec);
- zA += alpha * (A_zprec - zA_zprec);
-
-#define ZA_MASK (0xff << (zprec + aprec))
- *pixel =
- qt_static_shift<24 - zprec - aprec>(zA & ZA_MASK)
- | qt_static_shift<16 - zprec - aprec>(zR & ZA_MASK)
- | qt_static_shift<8 - zprec - aprec>(zG & ZA_MASK)
- | qt_static_shift<-zprec - aprec>(zB & ZA_MASK);
-#undef ZA_MASK
-}
-
-const int alphaIndex = (QSysInfo::ByteOrder == QSysInfo::BigEndian ? 0 : 3);
-
-template<int aprec, int zprec>
-inline void qt_blurinner_alphaOnly(uchar *bptr, int &z, int alpha)
-{
- const int A_zprec = int(*(bptr)) << zprec;
- const int z_zprec = z >> aprec;
- z += alpha * (A_zprec - z_zprec);
- *(bptr) = z >> (zprec + aprec);
-}
-
-template<int aprec, int zprec, bool alphaOnly>
-inline void qt_blurrow(QImage & im, int line, int alpha)
-{
- uchar *bptr = im.scanLine(line);
-
- int zR = 0, zG = 0, zB = 0, zA = 0;
-
- if (alphaOnly && im.format() != QImage::Format_Indexed8)
- bptr += alphaIndex;
-
- const int stride = im.depth() >> 3;
- const int im_width = im.width();
- for (int index = 0; index < im_width; ++index) {
- if (alphaOnly)
- qt_blurinner_alphaOnly<aprec, zprec>(bptr, zA, alpha);
- else
- qt_blurinner<aprec, zprec>(bptr, zR, zG, zB, zA, alpha);
- bptr += stride;
- }
-
- bptr -= stride;
-
- for (int index = im_width - 2; index >= 0; --index) {
- bptr -= stride;
- if (alphaOnly)
- qt_blurinner_alphaOnly<aprec, zprec>(bptr, zA, alpha);
- else
- qt_blurinner<aprec, zprec>(bptr, zR, zG, zB, zA, alpha);
- }
-}
-
-/*
-* expblur(QImage &img, int radius)
-*
-* Based on exponential blur algorithm by Jani Huhtanen
-*
-* In-place blur of image 'img' with kernel
-* of approximate radius 'radius'.
-*
-* Blurs with two sided exponential impulse
-* response.
-*
-* aprec = precision of alpha parameter
-* in fixed-point format 0.aprec
-*
-* zprec = precision of state parameters
-* zR,zG,zB and zA in fp format 8.zprec
-*/
-template <int aprec, int zprec, bool alphaOnly>
-void expblur(QImage &img, qreal radius, bool improvedQuality = false, int transposed = 0)
-{
- // halve the radius if we're using two passes
- if (improvedQuality)
- radius *= qreal(0.5);
-
- Q_ASSERT(img.format() == QImage::Format_ARGB32_Premultiplied
- || img.format() == QImage::Format_RGB32
- || img.format() == QImage::Format_Indexed8);
-
- // choose the alpha such that pixels at radius distance from a fully
- // saturated pixel will have an alpha component of no greater than
- // the cutOffIntensity
- const qreal cutOffIntensity = 2;
- int alpha = radius <= qreal(1e-5)
- ? ((1 << aprec)-1)
- : qRound((1<<aprec)*(1 - qPow(cutOffIntensity * (1 / qreal(255)), 1 / radius)));
-
- int img_height = img.height();
- for (int row = 0; row < img_height; ++row) {
- for (int i = 0; i <= int(improvedQuality); ++i)
- qt_blurrow<aprec, zprec, alphaOnly>(img, row, alpha);
- }
-
- QImage temp(img.height(), img.width(), img.format());
- if (transposed >= 0) {
- if (img.depth() == 8) {
- qt_memrotate270(reinterpret_cast<const quint8*>(img.bits()),
- img.width(), img.height(), img.bytesPerLine(),
- reinterpret_cast<quint8*>(temp.bits()),
- temp.bytesPerLine());
- } else {
- qt_memrotate270(reinterpret_cast<const quint32*>(img.bits()),
- img.width(), img.height(), img.bytesPerLine(),
- reinterpret_cast<quint32*>(temp.bits()),
- temp.bytesPerLine());
- }
- } else {
- if (img.depth() == 8) {
- qt_memrotate90(reinterpret_cast<const quint8*>(img.bits()),
- img.width(), img.height(), img.bytesPerLine(),
- reinterpret_cast<quint8*>(temp.bits()),
- temp.bytesPerLine());
- } else {
- qt_memrotate90(reinterpret_cast<const quint32*>(img.bits()),
- img.width(), img.height(), img.bytesPerLine(),
- reinterpret_cast<quint32*>(temp.bits()),
- temp.bytesPerLine());
- }
- }
-
- img_height = temp.height();
- for (int row = 0; row < img_height; ++row) {
- for (int i = 0; i <= int(improvedQuality); ++i)
- qt_blurrow<aprec, zprec, alphaOnly>(temp, row, alpha);
- }
-
- if (transposed == 0) {
- if (img.depth() == 8) {
- qt_memrotate90(reinterpret_cast<const quint8*>(temp.bits()),
- temp.width(), temp.height(), temp.bytesPerLine(),
- reinterpret_cast<quint8*>(img.bits()),
- img.bytesPerLine());
- } else {
- qt_memrotate90(reinterpret_cast<const quint32*>(temp.bits()),
- temp.width(), temp.height(), temp.bytesPerLine(),
- reinterpret_cast<quint32*>(img.bits()),
- img.bytesPerLine());
- }
- } else {
- img = temp;
- }
-}
-#define AVG(a,b) ( ((((a)^(b)) & 0xfefefefeUL) >> 1) + ((a)&(b)) )
-#define AVG16(a,b) ( ((((a)^(b)) & 0xf7deUL) >> 1) + ((a)&(b)) )
-
-Q_GUI_EXPORT QImage qt_halfScaled(const QImage &source)
-{
- if (source.width() < 2 || source.height() < 2)
- return QImage();
-
- QImage srcImage = source;
-
- if (source.format() == QImage::Format_Indexed8) {
- // assumes grayscale
- QImage dest(source.width() / 2, source.height() / 2, srcImage.format());
-
- const uchar *src = reinterpret_cast<const uchar*>(const_cast<const QImage &>(srcImage).bits());
- int sx = srcImage.bytesPerLine();
- int sx2 = sx << 1;
-
- uchar *dst = reinterpret_cast<uchar*>(dest.bits());
- int dx = dest.bytesPerLine();
- int ww = dest.width();
- int hh = dest.height();
-
- for (int y = hh; y; --y, dst += dx, src += sx2) {
- const uchar *p1 = src;
- const uchar *p2 = src + sx;
- uchar *q = dst;
- for (int x = ww; x; --x, ++q, p1 += 2, p2 += 2)
- *q = ((int(p1[0]) + int(p1[1]) + int(p2[0]) + int(p2[1])) + 2) >> 2;
- }
-
- return dest;
- } else if (source.format() == QImage::Format_ARGB8565_Premultiplied) {
- QImage dest(source.width() / 2, source.height() / 2, srcImage.format());
-
- const uchar *src = reinterpret_cast<const uchar*>(const_cast<const QImage &>(srcImage).bits());
- int sx = srcImage.bytesPerLine();
- int sx2 = sx << 1;
-
- uchar *dst = reinterpret_cast<uchar*>(dest.bits());
- int dx = dest.bytesPerLine();
- int ww = dest.width();
- int hh = dest.height();
-
- for (int y = hh; y; --y, dst += dx, src += sx2) {
- const uchar *p1 = src;
- const uchar *p2 = src + sx;
- uchar *q = dst;
- for (int x = ww; x; --x, q += 3, p1 += 6, p2 += 6) {
- // alpha
- q[0] = AVG(AVG(p1[0], p1[3]), AVG(p2[0], p2[3]));
- // rgb
- const quint16 p16_1 = (p1[2] << 8) | p1[1];
- const quint16 p16_2 = (p1[5] << 8) | p1[4];
- const quint16 p16_3 = (p2[2] << 8) | p2[1];
- const quint16 p16_4 = (p2[5] << 8) | p2[4];
- const quint16 result = AVG16(AVG16(p16_1, p16_2), AVG16(p16_3, p16_4));
- q[1] = result & 0xff;
- q[2] = result >> 8;
- }
- }
-
- return dest;
- } else if (source.format() != QImage::Format_ARGB32_Premultiplied
- && source.format() != QImage::Format_RGB32)
- {
- srcImage = source.convertToFormat(QImage::Format_ARGB32_Premultiplied);
- }
-
- QImage dest(source.width() / 2, source.height() / 2, srcImage.format());
-
- const quint32 *src = reinterpret_cast<const quint32*>(const_cast<const QImage &>(srcImage).bits());
- int sx = srcImage.bytesPerLine() >> 2;
- int sx2 = sx << 1;
-
- quint32 *dst = reinterpret_cast<quint32*>(dest.bits());
- int dx = dest.bytesPerLine() >> 2;
- int ww = dest.width();
- int hh = dest.height();
-
- for (int y = hh; y; --y, dst += dx, src += sx2) {
- const quint32 *p1 = src;
- const quint32 *p2 = src + sx;
- quint32 *q = dst;
- for (int x = ww; x; --x, q++, p1 += 2, p2 += 2)
- *q = AVG(AVG(p1[0], p1[1]), AVG(p2[0], p2[1]));
- }
-
- return dest;
-}
-
-Q_GUI_EXPORT void qt_blurImage(QPainter *p, QImage &blurImage, qreal radius, bool quality, bool alphaOnly, int transposed = 0)
-{
- if (blurImage.format() != QImage::Format_ARGB32_Premultiplied
- && blurImage.format() != QImage::Format_RGB32)
- {
- blurImage = blurImage.convertToFormat(QImage::Format_ARGB32_Premultiplied);
- }
-
- qreal scale = 1;
- if (radius >= 4 && blurImage.width() >= 2 && blurImage.height() >= 2) {
- blurImage = qt_halfScaled(blurImage);
- scale = 2;
- radius *= qreal(0.5);
- }
-
- if (alphaOnly)
- expblur<12, 10, true>(blurImage, radius, quality, transposed);
- else
- expblur<12, 10, false>(blurImage, radius, quality, transposed);
-
- if (p) {
- p->scale(scale, scale);
- p->setRenderHint(QPainter::SmoothPixmapTransform);
- p->drawImage(QRect(0, 0, blurImage.width(), blurImage.height()), blurImage);
- }
-}
-
-Q_GUI_EXPORT void qt_blurImage(QImage &blurImage, qreal radius, bool quality, int transposed = 0)
-{
- if (blurImage.format() == QImage::Format_Indexed8)
- expblur<12, 10, true>(blurImage, radius, quality, transposed);
- else
- expblur<12, 10, false>(blurImage, radius, quality, transposed);
-}
-
-Q_GUI_EXPORT bool qt_scaleForTransform(const QTransform &transform, qreal *scale);
-
-/*!
- \internal
-*/
-void QPixmapBlurFilter::draw(QPainter *painter, const QPointF &p, const QPixmap &src, const QRectF &rect) const
-{
- Q_D(const QPixmapBlurFilter);
- if (!painter->isActive())
- return;
-
- if (src.isNull())
- return;
-
- QRectF srcRect = rect;
- if (srcRect.isNull())
- srcRect = src.rect();
-
- if (d->radius <= 1) {
- painter->drawPixmap(srcRect.translated(p), src, srcRect);
- return;
- }
-
- qreal scaledRadius = radiusScale * d->radius;
- qreal scale;
- if (qt_scaleForTransform(painter->transform(), &scale))
- scaledRadius /= scale;
-
- QPixmapFilter *filter = painter->paintEngine() && painter->paintEngine()->isExtended() ?
- static_cast<QPaintEngineEx *>(painter->paintEngine())->pixmapFilter(type(), this) : 0;
- QPixmapBlurFilter *blurFilter = static_cast<QPixmapBlurFilter*>(filter);
- if (blurFilter) {
- blurFilter->setRadius(scaledRadius);
- blurFilter->setBlurHints(d->hints);
- blurFilter->draw(painter, p, src, srcRect);
- return;
- }
-
- QImage srcImage;
- QImage destImage;
-
- if (srcRect == src.rect()) {
- srcImage = src.toImage();
- } else {
- QRect rect = srcRect.toAlignedRect().intersected(src.rect());
- srcImage = src.copy(rect).toImage();
- }
-
- QTransform transform = painter->worldTransform();
- painter->translate(p);
- qt_blurImage(painter, srcImage, scaledRadius, (d->hints & QGraphicsBlurEffect::QualityHint), false);
- painter->setWorldTransform(transform);
-}
-
-// grayscales the image to dest (could be same). If rect isn't defined
-// destination image size is used to determine the dimension of grayscaling
-// process.
-static void grayscale(const QImage &image, QImage &dest, const QRect& rect = QRect())
-{
- QRect destRect = rect;
- QRect srcRect = rect;
- if (rect.isNull()) {
- srcRect = dest.rect();
- destRect = dest.rect();
- }
- if (&image != &dest) {
- destRect.moveTo(QPoint(0, 0));
- }
-
- unsigned int *data = (unsigned int *)image.bits();
- unsigned int *outData = (unsigned int *)dest.bits();
-
- if (dest.size() == image.size() && image.rect() == srcRect) {
- // a bit faster loop for grayscaling everything
- int pixels = dest.width() * dest.height();
- for (int i = 0; i < pixels; ++i) {
- int val = qGray(data[i]);
- outData[i] = qRgba(val, val, val, qAlpha(data[i]));
- }
- } else {
- int yd = destRect.top();
- for (int y = srcRect.top(); y <= srcRect.bottom() && y < image.height(); y++) {
- data = (unsigned int*)image.scanLine(y);
- outData = (unsigned int*)dest.scanLine(yd++);
- int xd = destRect.left();
- for (int x = srcRect.left(); x <= srcRect.right() && x < image.width(); x++) {
- int val = qGray(data[x]);
- outData[xd++] = qRgba(val, val, val, qAlpha(data[x]));
- }
- }
- }
-}
-
-/*!
- \class QPixmapColorizeFilter
- \since 4.5
- \ingroup painting
-
- \brief The QPixmapColorizeFilter class provides colorizing
- filtering for pixmaps.
-
- A colorize filter gives the pixmap a tint of its color(). The
- filter first grayscales the pixmap and then converts those to
- colorized values using QPainter::CompositionMode_Screen with the
- chosen color. The alpha-channel is not changed.
-
- Example:
- \snippet doc/src/snippets/code/src_gui_image_qpixmapfilter.cpp 0
-
- \sa QPainter::CompositionMode
-
- \internal
-*/
-class QPixmapColorizeFilterPrivate : public QPixmapFilterPrivate
-{
- Q_DECLARE_PUBLIC(QPixmapColorizeFilter)
-public:
- QColor color;
- qreal strength;
- quint32 opaque : 1;
- quint32 alphaBlend : 1;
- quint32 padding : 30;
-};
-
-/*!
- Constructs an pixmap colorize filter.
-
- Default color value for colorizing is QColor(0, 0, 192).
-
- \internal
-*/
-QPixmapColorizeFilter::QPixmapColorizeFilter(QObject *parent)
- : QPixmapFilter(*new QPixmapColorizeFilterPrivate, ColorizeFilter, parent)
-{
- Q_D(QPixmapColorizeFilter);
- d->color = QColor(0, 0, 192);
- d->strength = qreal(1);
- d->opaque = true;
- d->alphaBlend = false;
-}
-
-/*!
- Gets the color of the colorize filter.
-
- \internal
-*/
-QColor QPixmapColorizeFilter::color() const
-{
- Q_D(const QPixmapColorizeFilter);
- return d->color;
-}
-
-/*!
- Sets the color of the colorize filter to the \a color specified.
-
- \internal
-*/
-void QPixmapColorizeFilter::setColor(const QColor &color)
-{
- Q_D(QPixmapColorizeFilter);
- d->color = color;
-}
-
-/*!
- Gets the strength of the colorize filter, 1.0 means full colorized while
- 0.0 equals to no filtering at all.
-
- \internal
-*/
-qreal QPixmapColorizeFilter::strength() const
-{
- Q_D(const QPixmapColorizeFilter);
- return d->strength;
-}
-
-/*!
- Sets the strength of the colorize filter to \a strength.
-
- \internal
-*/
-void QPixmapColorizeFilter::setStrength(qreal strength)
-{
- Q_D(QPixmapColorizeFilter);
- d->strength = qBound(qreal(0), strength, qreal(1));
- d->opaque = !qFuzzyIsNull(d->strength);
- d->alphaBlend = !qFuzzyIsNull(d->strength - 1);
-}
-
-/*!
- \internal
-*/
-void QPixmapColorizeFilter::draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect) const
-{
- Q_D(const QPixmapColorizeFilter);
-
- if (src.isNull())
- return;
-
- QPixmapFilter *filter = painter->paintEngine() && painter->paintEngine()->isExtended() ?
- static_cast<QPaintEngineEx *>(painter->paintEngine())->pixmapFilter(type(), this) : 0;
- QPixmapColorizeFilter *colorizeFilter = static_cast<QPixmapColorizeFilter*>(filter);
- if (colorizeFilter) {
- colorizeFilter->setColor(d->color);
- colorizeFilter->setStrength(d->strength);
- colorizeFilter->draw(painter, dest, src, srcRect);
- return;
- }
-
- // falling back to raster implementation
-
- if (!d->opaque) {
- painter->drawPixmap(dest, src, srcRect);
- return;
- }
-
- QImage srcImage;
- QImage destImage;
-
- if (srcRect.isNull()) {
- srcImage = src.toImage();
- srcImage = srcImage.convertToFormat(srcImage.hasAlphaChannel() ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32);
- destImage = QImage(srcImage.size(), srcImage.format());
- } else {
- QRect rect = srcRect.toAlignedRect().intersected(src.rect());
-
- srcImage = src.copy(rect).toImage();
- srcImage = srcImage.convertToFormat(srcImage.hasAlphaChannel() ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32);
- destImage = QImage(rect.size(), srcImage.format());
- }
-
- // do colorizing
- QPainter destPainter(&destImage);
- grayscale(srcImage, destImage, srcImage.rect());
- destPainter.setCompositionMode(QPainter::CompositionMode_Screen);
- destPainter.fillRect(srcImage.rect(), d->color);
- destPainter.end();
-
- if (d->alphaBlend) {
- // alpha blending srcImage and destImage
- QImage buffer = srcImage;
- QPainter bufPainter(&buffer);
- bufPainter.setOpacity(d->strength);
- bufPainter.drawImage(0, 0, destImage);
- bufPainter.end();
- destImage = buffer;
- }
-
- if (srcImage.hasAlphaChannel())
- destImage.setAlphaChannel(srcImage.alphaChannel());
-
- painter->drawImage(dest, destImage);
-}
-
-class QPixmapDropShadowFilterPrivate : public QPixmapFilterPrivate
-{
-public:
- QPixmapDropShadowFilterPrivate()
- : offset(8, 8), color(63, 63, 63, 180), radius(1) {}
-
- QPointF offset;
- QColor color;
- qreal radius;
-};
-
-/*!
- \class QPixmapDropShadowFilter
- \since 4.5
- \ingroup painting
-
- \brief The QPixmapDropShadowFilter class is a convenience class
- for drawing pixmaps with drop shadows.
-
- The drop shadow is produced by taking a copy of the source pixmap
- and applying a color to the copy using a
- QPainter::CompositionMode_DestinationIn operation. This produces a
- homogeneously-colored pixmap which is then drawn using a
- QPixmapConvolutionFilter at an offset. The original pixmap is
- drawn on top.
-
- The QPixmapDropShadowFilter class provides some customization
- options to specify how the drop shadow should appear. The color of
- the drop shadow can be modified using the setColor() function, the
- drop shadow offset can be modified using the setOffset() function,
- and the blur radius of the drop shadow can be changed through the
- setBlurRadius() function.
-
- By default, the drop shadow is a dark gray shadow, blurred with a
- radius of 1 at an offset of 8 pixels towards the lower right.
-
- Example:
- \snippet doc/src/snippets/code/src_gui_image_qpixmapfilter.cpp 2
-
- \sa QPixmapColorizeFilter, QPixmapConvolutionFilter
-
- \internal
- */
-
-/*!
- Constructs drop shadow filter.
-
- \internal
-*/
-QPixmapDropShadowFilter::QPixmapDropShadowFilter(QObject *parent)
- : QPixmapFilter(*new QPixmapDropShadowFilterPrivate, DropShadowFilter, parent)
-{
-}
-
-/*!
- Destroys drop shadow filter.
-
- \internal
-*/
-QPixmapDropShadowFilter::~QPixmapDropShadowFilter()
-{
-}
-
-/*!
- Returns the radius in pixels of the blur on the drop shadow.
-
- A smaller radius results in a sharper shadow.
-
- \sa color(), offset()
-
- \internal
-*/
-qreal QPixmapDropShadowFilter::blurRadius() const
-{
- Q_D(const QPixmapDropShadowFilter);
- return d->radius;
-}
-
-/*!
- Sets the radius in pixels of the blur on the drop shadow to the \a radius specified.
-
- Using a smaller radius results in a sharper shadow.
-
- \sa setColor(), setOffset()
-
- \internal
-*/
-void QPixmapDropShadowFilter::setBlurRadius(qreal radius)
-{
- Q_D(QPixmapDropShadowFilter);
- d->radius = radius;
-}
-
-/*!
- Returns the color of the drop shadow.
-
- \sa blurRadius(), offset()
-
- \internal
-*/
-QColor QPixmapDropShadowFilter::color() const
-{
- Q_D(const QPixmapDropShadowFilter);
- return d->color;
-}
-
-/*!
- Sets the color of the drop shadow to the \a color specified.
-
- \sa setBlurRadius(), setOffset()
-
- \internal
-*/
-void QPixmapDropShadowFilter::setColor(const QColor &color)
-{
- Q_D(QPixmapDropShadowFilter);
- d->color = color;
-}
-
-/*!
- Returns the shadow offset in pixels.
-
- \sa blurRadius(), color()
-
- \internal
-*/
-QPointF QPixmapDropShadowFilter::offset() const
-{
- Q_D(const QPixmapDropShadowFilter);
- return d->offset;
-}
-
-/*!
- Sets the shadow offset in pixels to the \a offset specified.
-
- \sa setBlurRadius(), setColor()
-
- \internal
-*/
-void QPixmapDropShadowFilter::setOffset(const QPointF &offset)
-{
- Q_D(QPixmapDropShadowFilter);
- d->offset = offset;
-}
-
-/*!
- \fn void QPixmapDropShadowFilter::setOffset(qreal dx, qreal dy)
- \overload
-
- Sets the shadow offset in pixels to be the displacement specified by the
- horizontal \a dx and vertical \a dy coordinates.
-
- \sa setBlurRadius(), setColor()
-
- \internal
-*/
-
-/*!
- \internal
- */
-QRectF QPixmapDropShadowFilter::boundingRectFor(const QRectF &rect) const
-{
- Q_D(const QPixmapDropShadowFilter);
- return rect.united(rect.translated(d->offset).adjusted(-d->radius, -d->radius, d->radius, d->radius));
-}
-
-/*!
- \internal
- */
-void QPixmapDropShadowFilter::draw(QPainter *p,
- const QPointF &pos,
- const QPixmap &px,
- const QRectF &src) const
-{
- Q_D(const QPixmapDropShadowFilter);
-
- if (px.isNull())
- return;
-
- QPixmapFilter *filter = p->paintEngine() && p->paintEngine()->isExtended() ?
- static_cast<QPaintEngineEx *>(p->paintEngine())->pixmapFilter(type(), this) : 0;
- QPixmapDropShadowFilter *dropShadowFilter = static_cast<QPixmapDropShadowFilter*>(filter);
- if (dropShadowFilter) {
- dropShadowFilter->setColor(d->color);
- dropShadowFilter->setBlurRadius(d->radius);
- dropShadowFilter->setOffset(d->offset);
- dropShadowFilter->draw(p, pos, px, src);
- return;
- }
-
- QImage tmp(px.size(), QImage::Format_ARGB32_Premultiplied);
- tmp.fill(0);
- QPainter tmpPainter(&tmp);
- tmpPainter.setCompositionMode(QPainter::CompositionMode_Source);
- tmpPainter.drawPixmap(d->offset, px);
- tmpPainter.end();
-
- // blur the alpha channel
- QImage blurred(tmp.size(), QImage::Format_ARGB32_Premultiplied);
- blurred.fill(0);
- QPainter blurPainter(&blurred);
- qt_blurImage(&blurPainter, tmp, d->radius, false, true);
- blurPainter.end();
-
- tmp = blurred;
-
- // blacken the image...
- tmpPainter.begin(&tmp);
- tmpPainter.setCompositionMode(QPainter::CompositionMode_SourceIn);
- tmpPainter.fillRect(tmp.rect(), d->color);
- tmpPainter.end();
-
- // draw the blurred drop shadow...
- p->drawImage(pos, tmp);
-
- // Draw the actual pixmap...
- p->drawPixmap(pos, px, src);
-}
-
-QT_END_NAMESPACE
-
-#endif //QT_NO_GRAPHICSEFFECT
diff --git a/src/gui/image/qpixmapfilter_p.h b/src/gui/image/qpixmapfilter_p.h
deleted file mode 100644
index 4ece5876bd..0000000000
--- a/src/gui/image/qpixmapfilter_p.h
+++ /dev/null
@@ -1,196 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPIXMAPFILTER_H
-#define QPIXMAPFILTER_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/qnamespace.h>
-#include <QtGui/qpixmap.h>
-#include <QtGui/qgraphicseffect.h>
-
-#ifndef QT_NO_GRAPHICSEFFECT
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QPainter;
-class QPixmapData;
-
-class QPixmapFilterPrivate;
-
-class Q_GUI_EXPORT QPixmapFilter : public QObject
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QPixmapFilter)
-public:
- virtual ~QPixmapFilter() = 0;
-
- enum FilterType {
- ConvolutionFilter,
- ColorizeFilter,
- DropShadowFilter,
- BlurFilter,
-
- UserFilter = 1024
- };
-
- FilterType type() const;
-
- virtual QRectF boundingRectFor(const QRectF &rect) const;
-
- virtual void draw(QPainter *painter, const QPointF &p, const QPixmap &src, const QRectF &srcRect = QRectF()) const = 0;
-
-protected:
- QPixmapFilter(QPixmapFilterPrivate &d, FilterType type, QObject *parent);
- QPixmapFilter(FilterType type, QObject *parent);
-};
-
-class QPixmapConvolutionFilterPrivate;
-
-class Q_GUI_EXPORT QPixmapConvolutionFilter : public QPixmapFilter
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QPixmapConvolutionFilter)
-
-public:
- QPixmapConvolutionFilter(QObject *parent = 0);
- ~QPixmapConvolutionFilter();
-
- void setConvolutionKernel(const qreal *matrix, int rows, int columns);
-
- QRectF boundingRectFor(const QRectF &rect) const;
- void draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect = QRectF()) const;
-
-private:
- friend class QGLPixmapConvolutionFilter;
- friend class QVGPixmapConvolutionFilter;
- const qreal *convolutionKernel() const;
- int rows() const;
- int columns() const;
-};
-
-class QPixmapBlurFilterPrivate;
-
-class Q_GUI_EXPORT QPixmapBlurFilter : public QPixmapFilter
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QPixmapBlurFilter)
-
-public:
- QPixmapBlurFilter(QObject *parent = 0);
- ~QPixmapBlurFilter();
-
- void setRadius(qreal radius);
- void setBlurHints(QGraphicsBlurEffect::BlurHints hints);
-
- qreal radius() const;
- QGraphicsBlurEffect::BlurHints blurHints() const;
-
- QRectF boundingRectFor(const QRectF &rect) const;
- void draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect = QRectF()) const;
-
-private:
- friend class QGLPixmapBlurFilter;
-};
-
-class QPixmapColorizeFilterPrivate;
-
-class Q_GUI_EXPORT QPixmapColorizeFilter : public QPixmapFilter
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QPixmapColorizeFilter)
-
-public:
- QPixmapColorizeFilter(QObject *parent = 0);
-
- void setColor(const QColor& color);
- QColor color() const;
-
- void setStrength(qreal strength);
- qreal strength() const;
-
- void draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect = QRectF()) const;
-};
-
-class QPixmapDropShadowFilterPrivate;
-
-class Q_GUI_EXPORT QPixmapDropShadowFilter : public QPixmapFilter
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QPixmapDropShadowFilter)
-
-public:
- QPixmapDropShadowFilter(QObject *parent = 0);
- ~QPixmapDropShadowFilter();
-
- QRectF boundingRectFor(const QRectF &rect) const;
- void draw(QPainter *p, const QPointF &pos, const QPixmap &px, const QRectF &src = QRectF()) const;
-
- qreal blurRadius() const;
- void setBlurRadius(qreal radius);
-
- QColor color() const;
- void setColor(const QColor &color);
-
- QPointF offset() const;
- void setOffset(const QPointF &offset);
- inline void setOffset(qreal dx, qreal dy) { setOffset(QPointF(dx, dy)); }
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif //QT_NO_GRAPHICSEFFECT
-#endif // QPIXMAPFILTER_H
diff --git a/src/gui/image/qplatformpixmap.cpp b/src/gui/image/qplatformpixmap.cpp
new file mode 100644
index 0000000000..a214f397ed
--- /dev/null
+++ b/src/gui/image/qplatformpixmap.cpp
@@ -0,0 +1,189 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qplatformpixmap_qpa.h"
+#include <QtCore/qbuffer.h>
+#include <QtGui/qbitmap.h>
+#include <QtGui/qimagereader.h>
+#include <private/qguiapplication_p.h>
+#include <private/qimagepixmapcleanuphooks_p.h>
+
+QT_BEGIN_NAMESPACE
+
+QPlatformPixmap *QPlatformPixmap::create(int w, int h, PixelType type)
+{
+ QPlatformPixmap *data = QGuiApplicationPrivate::platformIntegration()->createPlatformPixmap(static_cast<QPlatformPixmap::PixelType>(type));
+ data->resize(w, h);
+ return data;
+}
+
+
+QPlatformPixmap::QPlatformPixmap(PixelType pixelType, int objectId)
+ : w(0),
+ h(0),
+ d(0),
+ is_null(true),
+ ref(0),
+ detach_no(0),
+ type(pixelType),
+ id(objectId),
+ ser_no(0),
+ is_cached(false)
+{
+}
+
+QPlatformPixmap::~QPlatformPixmap()
+{
+ // Sometimes the pixmap cleanup hooks will be called from derrived classes, which will
+ // then set is_cached to false. For example, on X11 QtGui needs to delete the GLXPixmap
+ // or EGL Pixmap Surface for a given pixmap _before_ the native X11 pixmap is deleted,
+ // otherwise some drivers will leak the GL surface. In this case, QX11PlatformPixmap will
+ // call the cleanup hooks itself before deleting the native pixmap and set is_cached to
+ // false.
+ if (is_cached) {
+ QImagePixmapCleanupHooks::executePlatformPixmapDestructionHooks(this);
+ is_cached = false;
+ }
+}
+
+QPlatformPixmap *QPlatformPixmap::createCompatiblePlatformPixmap() const
+{
+ QPlatformPixmap *d = QGuiApplicationPrivate::platformIntegration()->createPlatformPixmap(pixelType());
+ return d;
+}
+
+static QImage makeBitmapCompliantIfNeeded(QPlatformPixmap *d, const QImage &image, Qt::ImageConversionFlags flags)
+{
+ if (d->pixelType() == QPlatformPixmap::BitmapType) {
+ QImage img = image.convertToFormat(QImage::Format_MonoLSB, flags);
+
+ // make sure image.color(0) == Qt::color0 (white)
+ // and image.color(1) == Qt::color1 (black)
+ const QRgb c0 = QColor(Qt::black).rgb();
+ const QRgb c1 = QColor(Qt::white).rgb();
+ if (img.color(0) == c0 && img.color(1) == c1) {
+ img.invertPixels();
+ img.setColor(0, c1);
+ img.setColor(1, c0);
+ }
+ return img;
+ }
+
+ return image;
+}
+
+void QPlatformPixmap::fromImageReader(QImageReader *imageReader,
+ Qt::ImageConversionFlags flags)
+{
+ const QImage image = imageReader->read();
+ fromImage(image, flags);
+}
+
+bool QPlatformPixmap::fromFile(const QString &fileName, const char *format,
+ Qt::ImageConversionFlags flags)
+{
+ QImage image = QImageReader(fileName, format).read();
+ if (image.isNull())
+ return false;
+ fromImage(makeBitmapCompliantIfNeeded(this, image, flags), flags);
+ return !isNull();
+}
+
+bool QPlatformPixmap::fromData(const uchar *buf, uint len, const char *format, Qt::ImageConversionFlags flags)
+{
+ QByteArray a = QByteArray::fromRawData(reinterpret_cast<const char *>(buf), len);
+ QBuffer b(&a);
+ b.open(QIODevice::ReadOnly);
+ QImage image = QImageReader(&b, format).read();
+ fromImage(makeBitmapCompliantIfNeeded(this, image, flags), flags);
+ return !isNull();
+}
+
+void QPlatformPixmap::copy(const QPlatformPixmap *data, const QRect &rect)
+{
+ fromImage(data->toImage(rect), Qt::NoOpaqueDetection);
+}
+
+bool QPlatformPixmap::scroll(int dx, int dy, const QRect &rect)
+{
+ Q_UNUSED(dx);
+ Q_UNUSED(dy);
+ Q_UNUSED(rect);
+ return false;
+}
+
+QPixmap QPlatformPixmap::transformed(const QTransform &matrix,
+ Qt::TransformationMode mode) const
+{
+ return QPixmap::fromImage(toImage().transformed(matrix, mode));
+}
+
+void QPlatformPixmap::setSerialNumber(int serNo)
+{
+ ser_no = serNo;
+}
+
+QImage QPlatformPixmap::toImage(const QRect &rect) const
+{
+ if (rect.contains(QRect(0, 0, w, h)))
+ return toImage();
+ else
+ return toImage().copy(rect);
+}
+
+QImage* QPlatformPixmap::buffer()
+{
+ return 0;
+}
+
+#if defined(Q_OS_SYMBIAN)
+void* QPlatformPixmap::toNativeType(NativeType /* type */)
+{
+ return 0;
+}
+
+void QPlatformPixmap::fromNativeType(void* /* pixmap */, NativeType /* typre */)
+{
+ return;
+}
+#endif
+
+QT_END_NAMESPACE
diff --git a/src/gui/image/qplatformpixmap_qpa.h b/src/gui/image/qplatformpixmap_qpa.h
new file mode 100644
index 0000000000..d528f4138f
--- /dev/null
+++ b/src/gui/image/qplatformpixmap_qpa.h
@@ -0,0 +1,160 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPIXMAPDATA_P_H
+#define QPIXMAPDATA_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtGui/qpixmap.h>
+#include <QtCore/qatomic.h>
+
+QT_BEGIN_NAMESPACE
+
+class QImageReader;
+
+class Q_GUI_EXPORT QPlatformPixmap
+{
+public:
+ enum PixelType {
+ // WARNING: Do not change the first two
+ // Must match QPixmap::Type
+ PixmapType, BitmapType
+ };
+
+ enum ClassId { RasterClass, DirectFBClass,
+ BlitterClass, CustomClass = 1024 };
+
+ QPlatformPixmap(PixelType pixelType, int classId);
+ virtual ~QPlatformPixmap();
+
+ virtual QPlatformPixmap *createCompatiblePlatformPixmap() const;
+
+ virtual void resize(int width, int height) = 0;
+ virtual void fromImage(const QImage &image,
+ Qt::ImageConversionFlags flags) = 0;
+ virtual void fromImageReader(QImageReader *imageReader,
+ Qt::ImageConversionFlags flags);
+
+ virtual bool fromFile(const QString &filename, const char *format,
+ Qt::ImageConversionFlags flags);
+ virtual bool fromData(const uchar *buffer, uint len, const char *format,
+ Qt::ImageConversionFlags flags);
+
+ virtual void copy(const QPlatformPixmap *data, const QRect &rect);
+ virtual bool scroll(int dx, int dy, const QRect &rect);
+
+ virtual int metric(QPaintDevice::PaintDeviceMetric metric) const = 0;
+ virtual void fill(const QColor &color) = 0;
+
+ virtual bool hasAlphaChannel() const = 0;
+ virtual QPixmap transformed(const QTransform &matrix,
+ Qt::TransformationMode mode) const;
+
+ virtual QImage toImage() const = 0;
+ virtual QImage toImage(const QRect &rect) const;
+ virtual QPaintEngine* paintEngine() const = 0;
+
+ inline int serialNumber() const { return ser_no; }
+
+ inline PixelType pixelType() const { return type; }
+ inline ClassId classId() const { return static_cast<ClassId>(id); }
+
+ virtual QImage* buffer();
+
+ inline int width() const { return w; }
+ inline int height() const { return h; }
+ inline int colorCount() const { return metric(QPaintDevice::PdmNumColors); }
+ inline int depth() const { return d; }
+ inline bool isNull() const { return is_null; }
+ inline qint64 cacheKey() const {
+ int classKey = id;
+ if (classKey >= 1024)
+ classKey = -(classKey >> 10);
+ return ((((qint64) classKey) << 56)
+ | (((qint64) ser_no) << 32)
+ | ((qint64) detach_no));
+ }
+
+ static QPlatformPixmap *create(int w, int h, PixelType type);
+
+protected:
+
+ void setSerialNumber(int serNo);
+ int w;
+ int h;
+ int d;
+ bool is_null;
+
+private:
+ friend class QPixmap;
+ friend class QImagePixmapCleanupHooks; // Needs to set is_cached
+ friend class QOpenGLTextureCache; //Needs to check the reference count
+ friend class QExplicitlySharedDataPointer<QPlatformPixmap>;
+
+ QAtomicInt ref;
+ int detach_no;
+
+ PixelType type;
+ int id;
+ int ser_no;
+ uint is_cached;
+};
+
+# define QT_XFORM_TYPE_MSBFIRST 0
+# define QT_XFORM_TYPE_LSBFIRST 1
+# if defined(Q_WS_WIN)
+# define QT_XFORM_TYPE_WINDOWSPIXMAP 2
+# endif
+extern bool qt_xForm_helper(const QTransform&, int, int, int, uchar*, int, int, int, const uchar*, int, int, int);
+
+QT_END_NAMESPACE
+
+#endif // QPIXMAPDATA_P_H
diff --git a/src/gui/image/qvolatileimage.cpp b/src/gui/image/qvolatileimage.cpp
index aa3759a9ec..f7fe70c496 100644
--- a/src/gui/image/qvolatileimage.cpp
+++ b/src/gui/image/qvolatileimage.cpp
@@ -42,7 +42,7 @@
#include "qvolatileimage_p.h"
#include "qvolatileimagedata_p.h"
#include <QtGui/private/qpaintengine_raster_p.h>
-#include <QtGui/private/qpixmapdata_p.h>
+#include <QtGui/qplatformpixmap_qpa.h>
QT_BEGIN_NAMESPACE
@@ -200,15 +200,6 @@ void *QVolatileImage::duplicateNativeImage() const
return d->duplicateNativeImage();
}
-void QVolatileImage::setAlphaChannel(const QPixmap &alphaChannel)
-{
- ensureFormat(QImage::Format_ARGB32_Premultiplied);
- beginDataAccess();
- imageRef().setAlphaChannel(alphaChannel.toImage());
- endDataAccess();
- d->ensureImage();
-}
-
void QVolatileImage::fill(uint pixelValue)
{
beginDataAccess();
@@ -245,7 +236,7 @@ void QVolatileImage::copyFrom(QVolatileImage *source, const QRect &rect)
}
/*!
- To be called from the PixmapData's paintEngine().
+ To be called from the PlatformPixmap's paintEngine().
*/
QPaintEngine *QVolatileImage::paintEngine()
{
@@ -284,7 +275,7 @@ bool QVolatileImagePaintEngine::end()
void QVolatileImagePaintEngine::drawPixmap(const QPointF &p, const QPixmap &pm)
{
#ifdef Q_OS_SYMBIAN
- void *nativeData = pm.pixmapData()->toNativeType(QPixmapData::VolatileImage);
+ void *nativeData = pm.handle()->toNativeType(QPlatformPixmap::VolatileImage);
if (nativeData) {
QVolatileImage *img = static_cast<QVolatileImage *>(nativeData);
img->beginDataAccess();
@@ -301,7 +292,7 @@ void QVolatileImagePaintEngine::drawPixmap(const QPointF &p, const QPixmap &pm)
void QVolatileImagePaintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr)
{
#ifdef Q_OS_SYMBIAN
- void *nativeData = pm.pixmapData()->toNativeType(QPixmapData::VolatileImage);
+ void *nativeData = pm.handle()->toNativeType(QPlatformPixmap::VolatileImage);
if (nativeData) {
QVolatileImage *img = static_cast<QVolatileImage *>(nativeData);
img->beginDataAccess();
diff --git a/src/gui/image/qvolatileimage_p.h b/src/gui/image/qvolatileimage_p.h
index 911b61224d..91f8ce3598 100644
--- a/src/gui/image/qvolatileimage_p.h
+++ b/src/gui/image/qvolatileimage_p.h
@@ -87,7 +87,6 @@ public:
QImage toImage() const;
QImage &imageRef();
QPaintEngine *paintEngine();
- void setAlphaChannel(const QPixmap &alphaChannel);
void fill(uint pixelValue);
void *duplicateNativeImage() const;
void copyFrom(QVolatileImage *source, const QRect &rect);
diff --git a/src/gui/inputmethod/inputmethod.pri b/src/gui/inputmethod/inputmethod.pri
deleted file mode 100644
index d4394380dc..0000000000
--- a/src/gui/inputmethod/inputmethod.pri
+++ /dev/null
@@ -1,31 +0,0 @@
-# Qt inputmethod module
-
-HEADERS +=inputmethod/qinputcontextfactory.h \
- inputmethod/qinputcontextplugin.h \
- inputmethod/qinputcontext_p.h \
- inputmethod/qinputcontext.h
-SOURCES +=inputmethod/qinputcontextfactory.cpp \
- inputmethod/qinputcontextplugin.cpp \
- inputmethod/qinputcontext.cpp
-x11 {
- HEADERS += inputmethod/qximinputcontext_p.h
- SOURCES += inputmethod/qximinputcontext_x11.cpp
-}
-win32 {
- HEADERS += inputmethod/qwininputcontext_p.h
- SOURCES += inputmethod/qwininputcontext_win.cpp
-}
-embedded {
- HEADERS += inputmethod/qwsinputcontext_p.h
- SOURCES += inputmethod/qwsinputcontext_qws.cpp
-}
-mac:!embedded:!qpa {
- HEADERS += inputmethod/qmacinputcontext_p.h
- SOURCES += inputmethod/qmacinputcontext_mac.cpp
-}
-symbian:contains(QT_CONFIG, s60) {
- HEADERS += inputmethod/qcoefepinputcontext_p.h
- SOURCES += inputmethod/qcoefepinputcontext_s60.cpp
- LIBS += -lfepbase -lakninputlanguage
-}
-
diff --git a/src/gui/inputmethod/qcoefepinputcontext_p.h b/src/gui/inputmethod/qcoefepinputcontext_p.h
deleted file mode 100644
index 913d19887c..0000000000
--- a/src/gui/inputmethod/qcoefepinputcontext_p.h
+++ /dev/null
@@ -1,176 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QCOEFEPINPUTCONTEXT_P_H
-#define QCOEFEPINPUTCONTEXT_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#ifndef QT_NO_IM
-
-#include "qinputcontext.h"
-#include <qhash.h>
-#include <qtimer.h>
-#include <private/qcore_symbian_p.h>
-#include <private/qt_s60_p.h>
-
-#include <fepbase.h>
-#include <aknedsts.h>
-
-QT_BEGIN_NAMESPACE
-
-class Q_AUTOTEST_EXPORT QCoeFepInputContext : public QInputContext,
- public MCoeFepAwareTextEditor,
- public MCoeFepAwareTextEditor_Extension1,
- public MObjectProvider
-{
- Q_OBJECT
-
-public:
- QCoeFepInputContext(QObject *parent = 0);
- ~QCoeFepInputContext();
-
- QString identifierName() { return QLatin1String("coefep"); }
- QString language();
-
- void reset();
- void update();
-
- bool filterEvent(const QEvent *event);
- bool symbianFilterEvent(QWidget *keyWidget, const QSymbianEvent *event);
- void mouseHandler( int x, QMouseEvent *event);
- bool isComposing() const { return !m_preeditString.isEmpty(); }
-
- void setFocusWidget(QWidget * w);
- void widgetDestroyed(QWidget *w);
-
- TCoeInputCapabilities inputCapabilities();
-
- void resetSplitViewWidget(bool keepInputWidget = false);
- void ensureFocusWidgetVisible(QWidget *widget);
-
-protected:
- void timerEvent(QTimerEvent *timerEvent);
-
-private:
- void commitCurrentString(bool cancelFepTransaction);
- void updateHints(bool mustUpdateInputCapabilities);
- void applyHints(Qt::InputMethodHints hints);
- void applyFormat(QList<QInputMethodEvent::Attribute> *attributes);
- void queueInputCapabilitiesChanged();
- bool needsInputPanel();
- void commitTemporaryPreeditString();
- bool isWidgetVisible(QWidget *widget, int offset = 0);
-
-private Q_SLOTS:
- void ensureInputCapabilitiesChanged();
- void translateInputWidget();
-
- // From MCoeFepAwareTextEditor
-public:
- void StartFepInlineEditL(const TDesC& aInitialInlineText, TInt aPositionOfInsertionPointInInlineText,
- TBool aCursorVisibility, const MFormCustomDraw* aCustomDraw,
- MFepInlineTextFormatRetriever& aInlineTextFormatRetriever,
- MFepPointerEventHandlerDuringInlineEdit& aPointerEventHandlerDuringInlineEdit);
- void UpdateFepInlineTextL(const TDesC& aNewInlineText, TInt aPositionOfInsertionPointInInlineText);
- void SetInlineEditingCursorVisibilityL(TBool aCursorVisibility);
- void CancelFepInlineEdit();
- TInt DocumentLengthForFep() const;
- TInt DocumentMaximumLengthForFep() const;
- void SetCursorSelectionForFepL(const TCursorSelection& aCursorSelection);
- void GetCursorSelectionForFep(TCursorSelection& aCursorSelection) const;
- void GetEditorContentForFep(TDes& aEditorContent, TInt aDocumentPosition, TInt aLengthToRetrieve) const;
- void GetFormatForFep(TCharFormat& aFormat, TInt aDocumentPosition) const;
- void GetScreenCoordinatesForFepL(TPoint& aLeftSideOfBaseLine, TInt& aHeight, TInt& aAscent,
- TInt aDocumentPosition) const;
-private:
- void DoCommitFepInlineEditL();
- MCoeFepAwareTextEditor_Extension1* Extension1(TBool& aSetToTrue);
- void ReportAknEdStateEvent(MAknEdStateObserver::EAknEdwinStateEvent aEventType);
-
- // From MCoeFepAwareTextEditor_Extension1
-public:
- void SetStateTransferingOwnershipL(MCoeFepAwareTextEditor_Extension1::CState* aState, TUid aTypeSafetyUid);
- MCoeFepAwareTextEditor_Extension1::CState* State(TUid aTypeSafetyUid);
-
- // From MObjectProvider
-public:
- TTypeUid::Ptr MopSupplyObject(TTypeUid id);
- MObjectProvider *MopNext();
-
-private:
- QSymbianControl *m_parent;
- CAknEdwinState *m_fepState;
- QString m_preeditString;
- Qt::InputMethodHints m_lastImHints;
- TUint m_textCapabilities;
- bool m_inDestruction;
- bool m_pendingInputCapabilitiesChanged;
- int m_cursorVisibility;
- int m_inlinePosition;
- MFepInlineTextFormatRetriever *m_formatRetriever;
- MFepPointerEventHandlerDuringInlineEdit *m_pointerHandler;
- QBasicTimer m_tempPreeditStringTimeout;
- bool m_hasTempPreeditString;
-
- int m_splitViewResizeBy;
- Qt::WindowStates m_splitViewPreviousWindowStates;
- QRectF m_transformation;
-
- friend class tst_QInputContext;
-};
-
-Q_GUI_EXPORT void qt_s60_setPartialScreenInputMode(bool enable);
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_IM
-
-#endif // QCOEFEPINPUTCONTEXT_P_H
diff --git a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
deleted file mode 100644
index a00aa50bd3..0000000000
--- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
+++ /dev/null
@@ -1,1200 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QT_NO_IM
-
-#include "qcoefepinputcontext_p.h"
-#include <qapplication.h>
-#include <qtextformat.h>
-#include <qgraphicsview.h>
-#include <qgraphicsscene.h>
-#include <qgraphicswidget.h>
-#include <qsymbianevent.h>
-#include <qlayout.h>
-#include <qdesktopwidget.h>
-#include <private/qcore_symbian_p.h>
-
-#include <fepitfr.h>
-#include <hal.h>
-
-#include <limits.h>
-// You only find these enumerations on SDK 5 onwards, so we need to provide our own
-// to remain compatible with older releases. They won't be called by pre-5.0 SDKs.
-
-// MAknEdStateObserver::EAknCursorPositionChanged
-#define QT_EAknCursorPositionChanged MAknEdStateObserver::EAknEdwinStateEvent(6)
-// MAknEdStateObserver::EAknActivatePenInputRequest
-#define QT_EAknActivatePenInputRequest MAknEdStateObserver::EAknEdwinStateEvent(7)
-
-// EAknEditorFlagSelectionVisible is only valid from 3.2 onwards.
-// Sym^3 AVKON FEP manager expects that this flag is used for FEP-aware editors
-// that support text selection.
-#define QT_EAknEditorFlagSelectionVisible 0x100000
-
-// EAknEditorFlagEnablePartialScreen is only valid from Sym^3 onwards.
-#define QT_EAknEditorFlagEnablePartialScreen 0x200000
-
-QT_BEGIN_NAMESPACE
-
-Q_GUI_EXPORT void qt_s60_setPartialScreenInputMode(bool enable)
-{
- S60->partial_keyboard = enable;
-
- QInputContext *ic = 0;
- if (QApplication::focusWidget()) {
- ic = QApplication::focusWidget()->inputContext();
- } else if (qApp && qApp->inputContext()) {
- ic = qApp->inputContext();
- }
- if (ic)
- ic->update();
-}
-
-QCoeFepInputContext::QCoeFepInputContext(QObject *parent)
- : QInputContext(parent),
- m_fepState(q_check_ptr(new CAknEdwinState)), // CBase derived object needs check on new
- m_lastImHints(Qt::ImhNone),
- m_textCapabilities(TCoeInputCapabilities::EAllText),
- m_inDestruction(false),
- m_pendingInputCapabilitiesChanged(false),
- m_cursorVisibility(1),
- m_inlinePosition(0),
- m_formatRetriever(0),
- m_pointerHandler(0),
- m_hasTempPreeditString(false),
- m_splitViewResizeBy(0),
- m_splitViewPreviousWindowStates(Qt::WindowNoState)
-{
- m_fepState->SetObjectProvider(this);
- int defaultFlags = EAknEditorFlagDefault;
- if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0) {
- if (S60->partial_keyboard) {
- defaultFlags |= QT_EAknEditorFlagEnablePartialScreen;
- }
- defaultFlags |= QT_EAknEditorFlagSelectionVisible;
- }
- m_fepState->SetFlags(defaultFlags);
- m_fepState->SetDefaultInputMode( EAknEditorTextInputMode );
- m_fepState->SetPermittedInputModes( EAknEditorAllInputModes );
- m_fepState->SetDefaultCase( EAknEditorTextCase );
- m_fepState->SetPermittedCases( EAknEditorAllCaseModes );
- m_fepState->SetSpecialCharacterTableResourceId(R_AVKON_SPECIAL_CHARACTER_TABLE_DIALOG);
- m_fepState->SetNumericKeymap(EAknEditorAlphanumericNumberModeKeymap);
-}
-
-QCoeFepInputContext::~QCoeFepInputContext()
-{
- m_inDestruction = true;
-
- // This is to make sure that the FEP manager "forgets" about us,
- // otherwise we may get callbacks even after we're destroyed.
- // The call below is essentially equivalent to InputCapabilitiesChanged(),
- // but is synchronous, rather than asynchronous.
- CCoeEnv::Static()->SyncNotifyFocusObserversOfChangeInFocus();
-
- if (m_fepState)
- delete m_fepState;
-}
-
-void QCoeFepInputContext::reset()
-{
- commitCurrentString(true);
-}
-
-void QCoeFepInputContext::ReportAknEdStateEvent(MAknEdStateObserver::EAknEdwinStateEvent aEventType)
-{
- QT_TRAP_THROWING(m_fepState->ReportAknEdStateEventL(aEventType));
-}
-
-void QCoeFepInputContext::update()
-{
- updateHints(false);
-
- // For pre-5.0 SDKs, we don't do text updates on S60 side.
- if (QSysInfo::s60Version() < QSysInfo::SV_S60_5_0) {
- return;
- }
-
- // Don't be fooled (as I was) by the name of this enumeration.
- // What it really does is tell the virtual keyboard UI that the text has been
- // updated and it should be reflected in the internal display of the VK.
- ReportAknEdStateEvent(QT_EAknCursorPositionChanged);
-}
-
-void QCoeFepInputContext::setFocusWidget(QWidget *w)
-{
- commitCurrentString(true);
-
- QInputContext::setFocusWidget(w);
-
- updateHints(true);
-}
-
-void QCoeFepInputContext::widgetDestroyed(QWidget *w)
-{
- // Make sure that the input capabilities of whatever new widget got focused are queried.
- CCoeControl *ctrl = w->effectiveWinId();
- if (ctrl->IsFocused()) {
- queueInputCapabilitiesChanged();
- }
-}
-
-QString QCoeFepInputContext::language()
-{
- TLanguage lang = m_fepState->LocalLanguage();
- const QByteArray localeName = qt_symbianLocaleName(lang);
- if (!localeName.isEmpty()) {
- return QString::fromLatin1(localeName);
- } else {
- return QString::fromLatin1("C");
- }
-}
-
-bool QCoeFepInputContext::needsInputPanel()
-{
- switch (QSysInfo::s60Version()) {
- case QSysInfo::SV_S60_3_1:
- case QSysInfo::SV_S60_3_2:
- // There are no touch phones for pre-5.0 SDKs.
- return false;
-#ifdef Q_CC_NOKIAX86
- default:
- // For emulator we assume that we need an input panel, since we can't
- // separate between phone types.
- return true;
-#else
- case QSysInfo::SV_S60_5_0: {
- // For SDK == 5.0, we need phone specific detection, since the HAL API
- // is no good on most phones. However, all phones at the time of writing use the
- // input panel, except N97 in landscape mode, but in this mode it refuses to bring
- // up the panel anyway, so we don't have to care.
- return true;
- }
- default:
- // For unknown/newer types, we try to use the HAL API.
- int keyboardEnabled;
- int keyboardType;
- int err[2];
- err[0] = HAL::Get(HAL::EKeyboard, keyboardType);
- err[1] = HAL::Get(HAL::EKeyboardState, keyboardEnabled);
- if (err[0] == KErrNone && err[1] == KErrNone
- && keyboardType != 0 && keyboardEnabled)
- // Means that we have some sort of keyboard.
- return false;
-
- // Fall back to using the input panel.
- return true;
-#endif // !Q_CC_NOKIAX86
- }
-}
-
-bool QCoeFepInputContext::filterEvent(const QEvent *event)
-{
- // The CloseSoftwareInputPanel event is not handled here, because the VK will automatically
- // close when it discovers that the underlying widget does not have input capabilities.
-
- if (!focusWidget())
- return false;
-
- switch (event->type()) {
- case QEvent::MouseButtonPress:
- // Alphanumeric keypad doesn't like it when we click and text is still getting displayed
- // It ignores the mouse event, so we need to commit and send a selection event (which will get triggered
- // after the commit)
- if (!m_preeditString.isEmpty()) {
- commitCurrentString(true);
-
- int pos = focusWidget()->inputMethodQuery(Qt::ImCursorPosition).toInt();
-
- QList<QInputMethodEvent::Attribute> selectAttributes;
- selectAttributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, pos, 0, QVariant());
- QInputMethodEvent selectEvent(QLatin1String(""), selectAttributes);
- sendEvent(selectEvent);
- }
- break;
- case QEvent::KeyPress:
- commitTemporaryPreeditString();
- // fall through intended
- case QEvent::KeyRelease:
- const QKeyEvent *keyEvent = static_cast<const QKeyEvent *>(event);
- //If proxy exists, always use hints from proxy.
- QWidget *proxy = focusWidget()->focusProxy();
- Qt::InputMethodHints currentHints = proxy ? proxy->inputMethodHints() : focusWidget()->inputMethodHints();
-
- switch (keyEvent->key()) {
- case Qt::Key_F20:
- Q_ASSERT(m_lastImHints == currentHints);
- if (m_lastImHints & Qt::ImhHiddenText) {
- // Special case in Symbian. On editors with secret text, F20 is for some reason
- // considered to be a backspace.
- QKeyEvent modifiedEvent(keyEvent->type(), Qt::Key_Backspace, keyEvent->modifiers(),
- keyEvent->text(), keyEvent->isAutoRepeat(), keyEvent->count());
- QApplication::sendEvent(focusWidget(), &modifiedEvent);
- return true;
- }
- break;
- case Qt::Key_Select:
- if (!m_preeditString.isEmpty()) {
- commitCurrentString(true);
- return true;
- }
- break;
- default:
- break;
- }
-
- QString widgetText = focusWidget()->inputMethodQuery(Qt::ImSurroundingText).toString();
- bool validLength;
- int maxLength = focusWidget()->inputMethodQuery(Qt::ImMaximumTextLength).toInt(&validLength);
- if (!keyEvent->text().isEmpty() && validLength
- && widgetText.size() + m_preeditString.size() >= maxLength) {
- // Don't send key events with string content if the widget is "full".
- return true;
- }
-
- if (keyEvent->type() == QEvent::KeyPress
- && currentHints & Qt::ImhHiddenText
- && !keyEvent->text().isEmpty()) {
- // Send some temporary preedit text in order to make text visible for a moment.
- m_preeditString = keyEvent->text();
- QList<QInputMethodEvent::Attribute> attributes;
- QInputMethodEvent imEvent(m_preeditString, attributes);
- sendEvent(imEvent);
- m_tempPreeditStringTimeout.start(1000, this);
- m_hasTempPreeditString = true;
- update();
- return true;
- }
- break;
- }
-
- if (!needsInputPanel())
- return false;
-
- if (event->type() == QEvent::RequestSoftwareInputPanel) {
- // Notify S60 that we want the virtual keyboard to show up.
- QSymbianControl *sControl;
- sControl = focusWidget()->effectiveWinId()->MopGetObject(sControl);
- Q_ASSERT(sControl);
-
- // The FEP UI temporarily steals focus when it shows up the first time, causing
- // all sorts of weird effects on the focused widgets. Since it will immediately give
- // back focus to us, we temporarily disable focus handling until the job's done.
- if (sControl) {
- sControl->setIgnoreFocusChanged(true);
- }
-
- ensureInputCapabilitiesChanged();
- m_fepState->ReportAknEdStateEventL(MAknEdStateObserver::QT_EAknActivatePenInputRequest);
-
- if (sControl) {
- sControl->setIgnoreFocusChanged(false);
- }
- return true;
- }
-
- return false;
-}
-
-bool QCoeFepInputContext::symbianFilterEvent(QWidget *keyWidget, const QSymbianEvent *event)
-{
- Q_UNUSED(keyWidget);
- if (event->type() == QSymbianEvent::CommandEvent)
- // A command basically means the same as a button being pushed. With Qt buttons
- // that would normally result in a reset of the input method due to the focus change.
- // This should also happen for commands.
- reset();
-
- if (event->type() == QSymbianEvent::WindowServerEvent
- && event->windowServerEvent()
- && event->windowServerEvent()->Type() == EEventWindowVisibilityChanged
- && S60->splitViewLastWidget) {
-
- QGraphicsView *gv = qobject_cast<QGraphicsView*>(S60->splitViewLastWidget);
- const bool alwaysResize = (gv && gv->verticalScrollBarPolicy() != Qt::ScrollBarAlwaysOff);
-
- if (alwaysResize) {
- TUint visibleFlags = event->windowServerEvent()->VisibilityChanged()->iFlags;
- if (visibleFlags & TWsVisibilityChangedEvent::EPartiallyVisible)
- ensureFocusWidgetVisible(S60->splitViewLastWidget);
- if (visibleFlags & TWsVisibilityChangedEvent::ENotVisible)
- resetSplitViewWidget(true);
- }
- }
-
- return false;
-}
-
-void QCoeFepInputContext::timerEvent(QTimerEvent *timerEvent)
-{
- if (timerEvent->timerId() == m_tempPreeditStringTimeout.timerId())
- commitTemporaryPreeditString();
-}
-
-void QCoeFepInputContext::commitTemporaryPreeditString()
-{
- if (m_tempPreeditStringTimeout.isActive())
- m_tempPreeditStringTimeout.stop();
-
- if (!m_hasTempPreeditString)
- return;
-
- commitCurrentString(false);
-}
-
-void QCoeFepInputContext::mouseHandler( int x, QMouseEvent *event)
-{
- Q_ASSERT(focusWidget());
-
- if (event->type() == QEvent::MouseButtonPress && event->button() == Qt::LeftButton) {
- commitCurrentString(true);
- int pos = focusWidget()->inputMethodQuery(Qt::ImCursorPosition).toInt();
-
- QList<QInputMethodEvent::Attribute> attributes;
- attributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, pos + x, 0, QVariant());
- QInputMethodEvent event(QLatin1String(""), attributes);
- sendEvent(event);
- }
-}
-
-TCoeInputCapabilities QCoeFepInputContext::inputCapabilities()
-{
- if (m_inDestruction || !focusWidget()) {
- return TCoeInputCapabilities(TCoeInputCapabilities::ENone, 0, 0);
- }
-
- return TCoeInputCapabilities(m_textCapabilities, this, 0);
-}
-
-void QCoeFepInputContext::resetSplitViewWidget(bool keepInputWidget)
-{
- QGraphicsView *gv = qobject_cast<QGraphicsView*>(S60->splitViewLastWidget);
-
- if (!gv) {
- return;
- }
-
- QSymbianControl *symControl = static_cast<QSymbianControl*>(gv->effectiveWinId());
- symControl->CancelLongTapTimer();
-
- const bool alwaysResize = (gv->verticalScrollBarPolicy() != Qt::ScrollBarAlwaysOff);
- QWidget *windowToMove = gv->window();
-
- bool userResize = gv->testAttribute(Qt::WA_Resized);
-
- windowToMove->setUpdatesEnabled(false);
-
- if (!alwaysResize) {
- if (gv->scene()) {
- if (gv->scene()->focusItem()) {
- // Check if the widget contains cursorPositionChanged signal and disconnect from it.
- QByteArray signal = QMetaObject::normalizedSignature(SIGNAL(cursorPositionChanged()));
- int index = gv->scene()->focusItem()->toGraphicsObject()->metaObject()->indexOfSignal(signal.right(signal.length() - 1));
- if (index != -1)
- disconnect(gv->scene()->focusItem()->toGraphicsObject(), SIGNAL(cursorPositionChanged()), this, SLOT(translateInputWidget()));
- }
-
- QGraphicsItem *rootItem = 0;
- foreach (QGraphicsItem *item, gv->scene()->items()) {
- if (!item->parentItem()) {
- rootItem = item;
- break;
- }
- }
- if (rootItem)
- rootItem->resetTransform();
- }
- } else {
- if (m_splitViewResizeBy)
- gv->resize(gv->rect().width(), m_splitViewResizeBy);
- }
- // Resizing might have led to widget losing its original windowstate.
- // Restore previous window state.
-
- if (m_splitViewPreviousWindowStates != windowToMove->windowState())
- windowToMove->setWindowState(m_splitViewPreviousWindowStates);
-
- windowToMove->setUpdatesEnabled(true);
-
- gv->setAttribute(Qt::WA_Resized, userResize); //not a user resize
-
- m_splitViewResizeBy = 0;
- if (!keepInputWidget) {
- m_splitViewPreviousWindowStates = Qt::WindowNoState;
- S60->splitViewLastWidget = 0;
- }
-}
-
-// Checks if a given widget is visible in the splitview rect. The offset
-// parameter can be used to validate if moving widget upwards or downwards
-// by the offset would make a difference for the visibility.
-
-bool QCoeFepInputContext::isWidgetVisible(QWidget *widget, int offset)
-{
- bool visible = false;
- if (widget) {
- QRect splitViewRect = qt_TRect2QRect(static_cast<CEikAppUi*>(S60->appUi())->ClientRect());
- QWidget *window = QApplication::activeWindow();
- QGraphicsView *gv = qobject_cast<QGraphicsView*>(widget);
- if (gv && window) {
- if (QGraphicsScene *scene = gv->scene()) {
- if (QGraphicsItem *focusItem = scene->focusItem()) {
- QPoint cursorPos = window->mapToGlobal(focusItem->cursor().pos());
- cursorPos.setY(cursorPos.y() + offset);
- if (splitViewRect.contains(cursorPos)) {
- visible = true;
- }
- }
- }
- }
- }
- return visible;
-}
-
-// Ensure that the input widget is visible in the splitview rect.
-
-void QCoeFepInputContext::ensureFocusWidgetVisible(QWidget *widget)
-{
- // Native side opening and closing its virtual keyboard when it changes the keyboard layout,
- // has an adverse impact on long tap timer. Cancel the timer when splitview opens to avoid this.
- QSymbianControl *symControl = static_cast<QSymbianControl*>(widget->effectiveWinId());
- symControl->CancelLongTapTimer();
-
- // Graphicsviews that have vertical scrollbars should always be resized to the splitview area.
- // Graphicsviews without scrollbars should be translated.
-
- QGraphicsView *gv = qobject_cast<QGraphicsView*>(widget);
- if (!gv)
- return;
-
- const bool alwaysResize = (gv && gv->verticalScrollBarPolicy() != Qt::ScrollBarAlwaysOff);
- const bool moveWithinVisibleArea = (S60->splitViewLastWidget != 0);
-
- QWidget *windowToMove = gv ? gv : symControl->widget();
- if (!windowToMove->isWindow())
- windowToMove = windowToMove->window();
- if (!windowToMove) {
- return;
- }
-
- // When opening the keyboard (not moving within the splitview area), save the original
- // window state. In some cases, ensuring input widget visibility might lead to window
- // states getting changed.
-
- if (!moveWithinVisibleArea) {
- // Check if the widget contains cursorPositionChanged signal and connect to it.
- QByteArray signal = QMetaObject::normalizedSignature(SIGNAL(cursorPositionChanged()));
- if (gv->scene() && gv->scene()->focusItem()) {
- int index = gv->scene()->focusItem()->toGraphicsObject()->metaObject()->indexOfSignal(signal.right(signal.length() - 1));
- if (index != -1)
- connect(gv->scene()->focusItem()->toGraphicsObject(), SIGNAL(cursorPositionChanged()), this, SLOT(translateInputWidget()));
- }
- S60->splitViewLastWidget = widget;
- m_splitViewPreviousWindowStates = windowToMove->windowState();
- }
-
- int windowTop = widget->window()->pos().y();
-
- const bool userResize = widget->testAttribute(Qt::WA_Resized);
-
- QRect splitViewRect = qt_TRect2QRect(static_cast<CEikAppUi*>(S60->appUi())->ClientRect());
-
-
- // When resizing a window widget, it will lose its maximized window state.
- // Native applications hide statuspane in splitview state, so lets move to
- // fullscreen mode. This makes available area slightly bigger, which helps usability
- // and greatly reduces event passing in orientation switch cases,
- // as the statuspane size is not changing.
-
- if (alwaysResize)
- windowToMove->setUpdatesEnabled(false);
-
- if (!(windowToMove->windowState() & Qt::WindowFullScreen)) {
- windowToMove->setWindowState(
- (windowToMove->windowState() & ~(Qt::WindowMinimized | Qt::WindowFullScreen)) | Qt::WindowFullScreen);
- }
-
- if (alwaysResize) {
- if (!moveWithinVisibleArea) {
- m_splitViewResizeBy = widget->height();
- windowTop = widget->geometry().top();
- widget->resize(widget->width(), splitViewRect.height() - windowTop);
- }
-
- if (gv->scene()) {
- const QRectF microFocusRect = gv->scene()->inputMethodQuery(Qt::ImMicroFocus).toRectF();
- gv->ensureVisible(microFocusRect);
- }
- } else {
- translateInputWidget();
- }
-
- if (alwaysResize)
- windowToMove->setUpdatesEnabled(true);
-
- widget->setAttribute(Qt::WA_Resized, userResize); //not a user resize
-}
-
-static QTextCharFormat qt_TCharFormat2QTextCharFormat(const TCharFormat &cFormat, bool validStyleColor)
-{
- QTextCharFormat qFormat;
-
- if (validStyleColor) {
- QBrush foreground(QColor(cFormat.iFontPresentation.iTextColor.Internal()));
- qFormat.setForeground(foreground);
- }
-
- qFormat.setFontStrikeOut(cFormat.iFontPresentation.iStrikethrough == EStrikethroughOn);
- qFormat.setFontUnderline(cFormat.iFontPresentation.iUnderline == EUnderlineOn);
-
- return qFormat;
-}
-
-void QCoeFepInputContext::updateHints(bool mustUpdateInputCapabilities)
-{
- QWidget *w = focusWidget();
- if (w) {
- QWidget *proxy = w->focusProxy();
- Qt::InputMethodHints hints = proxy ? proxy->inputMethodHints() : w->inputMethodHints();
-
- // Since splitview support works like an input method hint, yet it is private flag,
- // we need to update its state separately.
- if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0) {
- TInt currentFlags = m_fepState->Flags();
- if (S60->partial_keyboard)
- currentFlags |= QT_EAknEditorFlagEnablePartialScreen;
- else
- currentFlags &= ~QT_EAknEditorFlagEnablePartialScreen;
- if (currentFlags != m_fepState->Flags())
- m_fepState->SetFlags(currentFlags);
- }
-
- if (hints != m_lastImHints) {
- m_lastImHints = hints;
- applyHints(hints);
- } else if (!mustUpdateInputCapabilities) {
- // Optimization. Return immediately if there was no change.
- return;
- }
- }
- queueInputCapabilitiesChanged();
-}
-
-void QCoeFepInputContext::applyHints(Qt::InputMethodHints hints)
-{
- using namespace Qt;
-
- commitTemporaryPreeditString();
-
- const bool anynumbermodes = hints & (ImhDigitsOnly | ImhFormattedNumbersOnly | ImhDialableCharactersOnly);
- const bool anytextmodes = hints & (ImhUppercaseOnly | ImhLowercaseOnly | ImhEmailCharactersOnly | ImhUrlCharactersOnly);
- const bool numbersOnly = anynumbermodes && !anytextmodes;
- const bool noOnlys = !(hints & ImhExclusiveInputMask);
- // if alphanumeric input, or if multiple incompatible number modes are selected;
- // then make all symbols available in numeric mode too.
- const bool needsCharMap= !numbersOnly || ((hints & ImhFormattedNumbersOnly) && (hints & ImhDialableCharactersOnly));
- TInt flags;
- Qt::InputMethodHints oldHints = hints;
-
- // Some sanity checking. Make sure that only one preference is set.
- InputMethodHints prefs = ImhPreferNumbers | ImhPreferUppercase | ImhPreferLowercase;
- prefs &= hints;
- if (prefs != ImhPreferNumbers && prefs != ImhPreferUppercase && prefs != ImhPreferLowercase) {
- hints &= ~prefs;
- }
- if (!noOnlys) {
- // Make sure that the preference is within the permitted set.
- if (hints & ImhPreferNumbers && !anynumbermodes) {
- hints &= ~ImhPreferNumbers;
- } else if (hints & ImhPreferUppercase && !(hints & ImhUppercaseOnly)) {
- hints &= ~ImhPreferUppercase;
- } else if (hints & ImhPreferLowercase && !(hints & ImhLowercaseOnly)) {
- hints &= ~ImhPreferLowercase;
- }
- // If there is no preference, set it to something within the permitted set.
- if (!(hints & ImhPreferNumbers || hints & ImhPreferUppercase || hints & ImhPreferLowercase)) {
- if (hints & ImhLowercaseOnly) {
- hints |= ImhPreferLowercase;
- } else if (hints & ImhUppercaseOnly) {
- hints |= ImhPreferUppercase;
- } else if (numbersOnly) {
- hints |= ImhPreferNumbers;
- }
- }
- }
-
- if (hints & ImhPreferNumbers) {
- m_fepState->SetDefaultInputMode(EAknEditorNumericInputMode);
- m_fepState->SetCurrentInputMode(EAknEditorNumericInputMode);
- } else {
- m_fepState->SetDefaultInputMode(EAknEditorTextInputMode);
- m_fepState->SetCurrentInputMode(EAknEditorTextInputMode);
- }
- flags = 0;
- if (noOnlys || (anynumbermodes && anytextmodes)) {
- flags = EAknEditorAllInputModes;
- }
- else if (anynumbermodes) {
- flags |= EAknEditorNumericInputMode;
- if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0
- && ((hints & ImhFormattedNumbersOnly) || (hints & ImhDialableCharactersOnly))) {
- //workaround - the * key does not launch the symbols menu, making it impossible to use these modes unless text mode is enabled.
- flags |= EAknEditorTextInputMode;
- }
- }
- else if (anytextmodes) {
- flags |= EAknEditorTextInputMode;
- }
- else {
- flags = EAknEditorAllInputModes;
- }
- m_fepState->SetPermittedInputModes(flags);
- ReportAknEdStateEvent(MAknEdStateObserver::EAknEdwinStateInputModeUpdate);
-
- if (hints & ImhPreferLowercase) {
- m_fepState->SetDefaultCase(EAknEditorLowerCase);
- m_fepState->SetCurrentCase(EAknEditorLowerCase);
- } else if (hints & ImhPreferUppercase) {
- m_fepState->SetDefaultCase(EAknEditorUpperCase);
- m_fepState->SetCurrentCase(EAknEditorUpperCase);
- } else if (hints & ImhNoAutoUppercase) {
- m_fepState->SetDefaultCase(EAknEditorLowerCase);
- m_fepState->SetCurrentCase(EAknEditorLowerCase);
- } else {
- m_fepState->SetDefaultCase(EAknEditorTextCase);
- m_fepState->SetCurrentCase(EAknEditorTextCase);
- }
- flags = 0;
- if (hints & ImhUppercaseOnly) {
- flags |= EAknEditorUpperCase;
- }
- if (hints & ImhLowercaseOnly) {
- flags |= EAknEditorLowerCase;
- }
- if (flags == 0) {
- flags = EAknEditorAllCaseModes;
- if (hints & ImhNoAutoUppercase) {
- flags &= ~EAknEditorTextCase;
- }
- }
- m_fepState->SetPermittedCases(flags);
- ReportAknEdStateEvent(MAknEdStateObserver::EAknEdwinStateCaseModeUpdate);
-
- flags = 0;
- if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0) {
- if (S60->partial_keyboard)
- flags |= QT_EAknEditorFlagEnablePartialScreen;
- flags |= QT_EAknEditorFlagSelectionVisible;
- }
- if (hints & ImhUppercaseOnly && !(hints & ImhLowercaseOnly)
- || hints & ImhLowercaseOnly && !(hints & ImhUppercaseOnly)) {
- flags |= EAknEditorFlagFixedCase;
- }
- // Using T9 and hidden text together may actually crash the FEP, so check for hidden text too.
- if (hints & ImhNoPredictiveText || hints & ImhHiddenText) {
- flags |= EAknEditorFlagNoT9;
- }
- if (needsCharMap)
- flags |= EAknEditorFlagUseSCTNumericCharmap;
- m_fepState->SetFlags(flags);
- ReportAknEdStateEvent(MAknEdStateObserver::EAknEdwinStateFlagsUpdate);
-
- if (hints & ImhDialableCharactersOnly) {
- // This is first, because if (ImhDialableCharactersOnly | ImhFormattedNumbersOnly)
- // is specified, this one is more natural (# key enters a #)
- flags = EAknEditorStandardNumberModeKeymap;
- } else if (hints & ImhFormattedNumbersOnly) {
- // # key enters decimal point
- flags = EAknEditorCalculatorNumberModeKeymap;
- } else if (hints & ImhDigitsOnly) {
- // This is last, because it is most restrictive (# key is inactive)
- flags = EAknEditorPlainNumberModeKeymap;
- } else {
- flags = EAknEditorStandardNumberModeKeymap;
- }
- m_fepState->SetNumericKeymap(static_cast<TAknEditorNumericKeymap>(flags));
-
- if (hints & ImhUrlCharactersOnly) {
- // URL characters is everything except space, so a superset of the other restrictions
- m_fepState->SetSpecialCharacterTableResourceId(R_AVKON_URL_SPECIAL_CHARACTER_TABLE_DIALOG);
- } else if (hints & ImhEmailCharactersOnly) {
- m_fepState->SetSpecialCharacterTableResourceId(R_AVKON_EMAIL_ADDR_SPECIAL_CHARACTER_TABLE_DIALOG);
- } else if (needsCharMap) {
- m_fepState->SetSpecialCharacterTableResourceId(R_AVKON_SPECIAL_CHARACTER_TABLE_DIALOG);
- } else if ((hints & ImhFormattedNumbersOnly) || (hints & ImhDialableCharactersOnly)) {
- m_fepState->SetSpecialCharacterTableResourceId(R_AVKON_SPECIAL_CHARACTER_TABLE_DIALOG);
- } else {
- m_fepState->SetSpecialCharacterTableResourceId(0);
- }
-
- if (hints & ImhHiddenText) {
- m_textCapabilities = TCoeInputCapabilities::EAllText | TCoeInputCapabilities::ESecretText;
- } else {
- m_textCapabilities = TCoeInputCapabilities::EAllText;
- }
-}
-
-void QCoeFepInputContext::applyFormat(QList<QInputMethodEvent::Attribute> *attributes)
-{
- TCharFormat cFormat;
- QColor styleTextColor;
- if (QWidget *focused = focusWidget()) {
- QGraphicsView *gv = qobject_cast<QGraphicsView*>(focused);
- if (!gv) // could be either the QGV or its viewport that has focus
- gv = qobject_cast<QGraphicsView*>(focused->parentWidget());
- if (gv) {
- if (QGraphicsScene *scene = gv->scene()) {
- if (QGraphicsItem *focusItem = scene->focusItem()) {
- if (focusItem->isWidget()) {
- styleTextColor = static_cast<QGraphicsWidget*>(focusItem)->palette().text().color();
- }
- }
- }
- } else {
- styleTextColor = focused->palette().text().color();
- }
- } else {
- styleTextColor = QApplication::palette("QLineEdit").text().color();
- }
-
- if (styleTextColor.isValid()) {
- const TLogicalRgb fontColor(TRgb(styleTextColor.red(), styleTextColor.green(), styleTextColor.blue(), styleTextColor.alpha()));
- cFormat.iFontPresentation.iTextColor = fontColor;
- }
-
- TInt numChars = 0;
- TInt charPos = 0;
- int oldSize = attributes->size();
- while (m_formatRetriever) {
- m_formatRetriever->GetFormatOfFepInlineText(cFormat, numChars, charPos);
- if (numChars <= 0) {
- // This shouldn't happen according to S60 docs, but apparently does sometimes.
- break;
- }
- attributes->append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat,
- charPos,
- numChars,
- QVariant(qt_TCharFormat2QTextCharFormat(cFormat, styleTextColor.isValid()))));
- charPos += numChars;
- if (charPos >= m_preeditString.size()) {
- break;
- }
- }
-
- if (attributes->size() == oldSize) {
- // S60 didn't provide any format, so let's give our own instead.
- attributes->append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat,
- 0,
- m_preeditString.size(),
- standardFormat(PreeditFormat)));
- }
-}
-
-void QCoeFepInputContext::queueInputCapabilitiesChanged()
-{
- if (m_pendingInputCapabilitiesChanged)
- return;
-
- // Call ensureInputCapabilitiesChanged asynchronously. This is done to improve performance
- // by not updating input capabilities too often. The reason we don't call the Symbian
- // asynchronous version of InputCapabilitiesChanged is because we need to ensure that it
- // is synchronous in some specific cases. Those will call ensureInputCapabilitesChanged.
- QMetaObject::invokeMethod(this, "ensureInputCapabilitiesChanged", Qt::QueuedConnection);
- m_pendingInputCapabilitiesChanged = true;
-}
-
-void QCoeFepInputContext::ensureInputCapabilitiesChanged()
-{
- if (!m_pendingInputCapabilitiesChanged)
- return;
-
- // The call below is essentially equivalent to InputCapabilitiesChanged(),
- // but is synchronous, rather than asynchronous.
- CCoeEnv::Static()->SyncNotifyFocusObserversOfChangeInFocus();
- m_pendingInputCapabilitiesChanged = false;
-}
-
-void QCoeFepInputContext::translateInputWidget()
-{
- QGraphicsView *gv = qobject_cast<QGraphicsView *>(S60->splitViewLastWidget);
- QRect splitViewRect = qt_TRect2QRect(static_cast<CEikAppUi*>(S60->appUi())->ClientRect());
-
- QRectF cursor = gv->scene()->inputMethodQuery(Qt::ImMicroFocus).toRectF();
- QPolygon cursorP = gv->mapFromScene(cursor);
- QRectF vkbRect = QRectF(splitViewRect.bottomLeft(), qApp->desktop()->rect().bottomRight());
- if (cursor.isEmpty() || vkbRect.isEmpty())
- return;
-
- // Fetch root item (i.e. graphicsitem with no parent)
- QGraphicsItem *rootItem = 0;
- foreach (QGraphicsItem *item, gv->scene()->items()) {
- if (!item->parentItem()) {
- rootItem = item;
- break;
- }
- }
- if (!rootItem)
- return;
-
- m_transformation = (rootItem->transform().isTranslating()) ? QRectF(0,0, gv->width(), rootItem->transform().dy()) : QRectF();
-
- // Do nothing if the cursor is visible in the splitview area.
- if (splitViewRect.contains(cursorP.boundingRect()))
- return;
-
- // New Y position should be ideally at the center of the splitview area.
- // If that would expose unpainted canvas, limit the tranformation to the visible scene bottom.
-
- const qreal maxY = gv->sceneRect().bottom() - splitViewRect.bottom() + m_transformation.height();
- qreal dy = -(qMin(maxY, (cursor.bottom() - vkbRect.top() / 2)));
-
- // Do not allow transform above screen top.
- if (m_transformation.height() + dy > 0)
- return;
-
- rootItem->setTransform(QTransform::fromTranslate(0, dy), true);
-}
-
-void QCoeFepInputContext::StartFepInlineEditL(const TDesC& aInitialInlineText,
- TInt aPositionOfInsertionPointInInlineText, TBool aCursorVisibility, const MFormCustomDraw* /*aCustomDraw*/,
- MFepInlineTextFormatRetriever& aInlineTextFormatRetriever,
- MFepPointerEventHandlerDuringInlineEdit& aPointerEventHandlerDuringInlineEdit)
-{
- QWidget *w = focusWidget();
- if (!w)
- return;
-
- commitTemporaryPreeditString();
-
- QList<QInputMethodEvent::Attribute> attributes;
-
- m_cursorVisibility = aCursorVisibility ? 1 : 0;
- m_inlinePosition = aPositionOfInsertionPointInInlineText;
- m_preeditString = qt_TDesC2QString(aInitialInlineText);
-
- m_formatRetriever = &aInlineTextFormatRetriever;
- m_pointerHandler = &aPointerEventHandlerDuringInlineEdit;
-
- // With T9 aInitialInlineText is typically empty when StartFepInlineEditL is called,
- // but FEP requires that selected text is always removed at StartFepInlineEditL.
- // Let's remove the selected text if aInitialInlineText is empty and there is selected text
- if (m_preeditString.isEmpty()) {
- int anchor = w->inputMethodQuery(Qt::ImAnchorPosition).toInt();
- int cursorPos = w->inputMethodQuery(Qt::ImCursorPosition).toInt();
- int replacementLength = qAbs(cursorPos-anchor);
- if (replacementLength > 0) {
- int replacementStart = cursorPos < anchor ? 0 : -replacementLength;
- QList<QInputMethodEvent::Attribute> clearSelectionAttributes;
- QInputMethodEvent clearSelectionEvent(QLatin1String(""), clearSelectionAttributes);
- clearSelectionEvent.setCommitString(QLatin1String(""), replacementStart, replacementLength);
- sendEvent(clearSelectionEvent);
- }
- }
-
- applyFormat(&attributes);
-
- attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor,
- m_inlinePosition,
- m_cursorVisibility,
- QVariant()));
- QInputMethodEvent event(m_preeditString, attributes);
- sendEvent(event);
-}
-
-void QCoeFepInputContext::UpdateFepInlineTextL(const TDesC& aNewInlineText,
- TInt aPositionOfInsertionPointInInlineText)
-{
- QWidget *w = focusWidget();
- if (!w)
- return;
-
- commitTemporaryPreeditString();
-
- m_inlinePosition = aPositionOfInsertionPointInInlineText;
-
- QList<QInputMethodEvent::Attribute> attributes;
- applyFormat(&attributes);
- attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor,
- m_inlinePosition,
- m_cursorVisibility,
- QVariant()));
- QString newPreeditString = qt_TDesC2QString(aNewInlineText);
- QInputMethodEvent event(newPreeditString, attributes);
- if (newPreeditString.isEmpty() && m_preeditString.isEmpty()) {
- // In Symbian world this means "erase last character".
- event.setCommitString(QLatin1String(""), -1, 1);
- }
- m_preeditString = newPreeditString;
- sendEvent(event);
-}
-
-void QCoeFepInputContext::SetInlineEditingCursorVisibilityL(TBool aCursorVisibility)
-{
- QWidget *w = focusWidget();
- if (!w)
- return;
-
- m_cursorVisibility = aCursorVisibility ? 1 : 0;
-
- QList<QInputMethodEvent::Attribute> attributes;
- attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor,
- m_inlinePosition,
- m_cursorVisibility,
- QVariant()));
- QInputMethodEvent event(m_preeditString, attributes);
- sendEvent(event);
-}
-
-void QCoeFepInputContext::CancelFepInlineEdit()
-{
- // We are not supposed to ever have a tempPreeditString and a real preedit string
- // from S60 at the same time, so it should be safe to rely on this test to determine
- // whether we should honor S60's request to clear the text or not.
- if (m_hasTempPreeditString)
- return;
-
- QList<QInputMethodEvent::Attribute> attributes;
- QInputMethodEvent event(QLatin1String(""), attributes);
- event.setCommitString(QLatin1String(""), 0, 0);
- m_preeditString.clear();
- m_inlinePosition = 0;
- sendEvent(event);
-}
-
-TInt QCoeFepInputContext::DocumentLengthForFep() const
-{
- QWidget *w = focusWidget();
- if (!w)
- return 0;
-
- QVariant variant = w->inputMethodQuery(Qt::ImSurroundingText);
- return variant.value<QString>().size() + m_preeditString.size();
-}
-
-TInt QCoeFepInputContext::DocumentMaximumLengthForFep() const
-{
- QWidget *w = focusWidget();
- if (!w)
- return 0;
-
- QVariant variant = w->inputMethodQuery(Qt::ImMaximumTextLength);
- int size;
- if (variant.isValid()) {
- size = variant.toInt();
- } else {
- size = INT_MAX; // Sensible default for S60.
- }
- return size;
-}
-
-void QCoeFepInputContext::SetCursorSelectionForFepL(const TCursorSelection& aCursorSelection)
-{
- QWidget *w = focusWidget();
- if (!w)
- return;
-
- commitTemporaryPreeditString();
-
- int pos = aCursorSelection.iAnchorPos;
- int length = aCursorSelection.iCursorPos - pos;
-
- QList<QInputMethodEvent::Attribute> attributes;
- attributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, pos, length, QVariant());
- QInputMethodEvent event(m_preeditString, attributes);
- sendEvent(event);
-}
-
-void QCoeFepInputContext::GetCursorSelectionForFep(TCursorSelection& aCursorSelection) const
-{
- QWidget *w = focusWidget();
- if (!w) {
- aCursorSelection.SetSelection(0,0);
- return;
- }
-
- int cursor = w->inputMethodQuery(Qt::ImCursorPosition).toInt() + m_preeditString.size();
- int anchor = w->inputMethodQuery(Qt::ImAnchorPosition).toInt() + m_preeditString.size();
- QString text = w->inputMethodQuery(Qt::ImSurroundingText).value<QString>();
- int combinedSize = text.size() + m_preeditString.size();
- if (combinedSize < anchor || combinedSize < cursor) {
- // ### TODO! FIXME! QTBUG-5050
- // This is a hack to prevent crashing in 4.6 with QLineEdits that use input masks.
- // The root problem is that cursor position is relative to displayed text instead of the
- // actual text we get.
- //
- // To properly fix this we would need to know the displayText of QLineEdits instead
- // of just the text, which on itself should be a trivial change. The difficulties start
- // when we need to commit the changes back to the QLineEdit, which would have to be somehow
- // able to handle displayText, too.
- //
- // Until properly fixed, the cursor and anchor positions will not reflect correct positions
- // for masked QLineEdits, unless all the masked positions are filled in order so that
- // cursor position relative to the displayed text matches position relative to actual text.
- aCursorSelection.iAnchorPos = combinedSize;
- aCursorSelection.iCursorPos = combinedSize;
- } else {
- aCursorSelection.iAnchorPos = anchor;
- aCursorSelection.iCursorPos = cursor;
- }
-}
-
-void QCoeFepInputContext::GetEditorContentForFep(TDes& aEditorContent, TInt aDocumentPosition,
- TInt aLengthToRetrieve) const
-{
- QWidget *w = focusWidget();
- if (!w) {
- aEditorContent.FillZ(aLengthToRetrieve);
- return;
- }
-
- QString text = w->inputMethodQuery(Qt::ImSurroundingText).value<QString>();
- // FEP expects the preedit string to be part of the editor content, so let's mix it in.
- int cursor = w->inputMethodQuery(Qt::ImCursorPosition).toInt();
- text.insert(cursor, m_preeditString);
- aEditorContent.Copy(qt_QString2TPtrC(text.mid(aDocumentPosition, aLengthToRetrieve)));
-}
-
-void QCoeFepInputContext::GetFormatForFep(TCharFormat& aFormat, TInt /* aDocumentPosition */) const
-{
- QWidget *w = focusWidget();
- if (!w) {
- aFormat = TCharFormat();
- return;
- }
-
- QFont font = w->inputMethodQuery(Qt::ImFont).value<QFont>();
- QFontMetrics metrics(font);
- //QString name = font.rawName();
- QString name = font.defaultFamily(); // TODO! FIXME! Should be the above.
- QHBufC hBufC(name);
- aFormat = TCharFormat(hBufC->Des(), metrics.height());
-}
-
-void QCoeFepInputContext::GetScreenCoordinatesForFepL(TPoint& aLeftSideOfBaseLine, TInt& aHeight,
- TInt& aAscent, TInt /* aDocumentPosition */) const
-{
- QWidget *w = focusWidget();
- if (!w) {
- aLeftSideOfBaseLine = TPoint(0,0);
- aHeight = 0;
- aAscent = 0;
- return;
- }
-
- QRect rect = w->inputMethodQuery(Qt::ImMicroFocus).value<QRect>();
- aLeftSideOfBaseLine.iX = rect.left();
- aLeftSideOfBaseLine.iY = rect.bottom();
-
- QFont font = w->inputMethodQuery(Qt::ImFont).value<QFont>();
- QFontMetrics metrics(font);
- aHeight = metrics.height();
- aAscent = metrics.ascent();
-}
-
-void QCoeFepInputContext::DoCommitFepInlineEditL()
-{
- commitCurrentString(false);
- if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0)
- ReportAknEdStateEvent(QT_EAknCursorPositionChanged);
-
-}
-
-void QCoeFepInputContext::commitCurrentString(bool cancelFepTransaction)
-{
- QList<QInputMethodEvent::Attribute> attributes;
- QInputMethodEvent event(QLatin1String(""), attributes);
- event.setCommitString(m_preeditString, 0, 0);
- m_preeditString.clear();
- m_inlinePosition = 0;
- sendEvent(event);
-
- m_hasTempPreeditString = false;
-
- if (cancelFepTransaction) {
- CCoeFep* fep = CCoeEnv::Static()->Fep();
- if (fep)
- fep->CancelTransaction();
- }
-}
-
-MCoeFepAwareTextEditor_Extension1* QCoeFepInputContext::Extension1(TBool& aSetToTrue)
-{
- aSetToTrue = ETrue;
- return this;
-}
-
-void QCoeFepInputContext::SetStateTransferingOwnershipL(MCoeFepAwareTextEditor_Extension1::CState* aState,
- TUid /*aTypeSafetyUid*/)
-{
- // Note: The S60 docs are wrong! See the State() function.
- if (m_fepState)
- delete m_fepState;
- m_fepState = static_cast<CAknEdwinState *>(aState);
-}
-
-MCoeFepAwareTextEditor_Extension1::CState* QCoeFepInputContext::State(TUid /*aTypeSafetyUid*/)
-{
- // Note: The S60 docs are horribly wrong when describing the
- // SetStateTransferingOwnershipL function and this function. They say that the former
- // sets a CState object identified by the TUid, and the latter retrieves it.
- // In reality, the CState is expected to always be a CAknEdwinState (even if it was not
- // previously set), and the TUid is ignored. All in all, there is a single CAknEdwinState
- // per QCoeFepInputContext, which should be deleted if the SetStateTransferingOwnershipL
- // function is used to set a new one.
- return m_fepState;
-}
-
-TTypeUid::Ptr QCoeFepInputContext::MopSupplyObject(TTypeUid /*id*/)
-{
- return TTypeUid::Null();
-}
-
-MObjectProvider *QCoeFepInputContext::MopNext()
-{
- QWidget *w = focusWidget();
- if (w)
- return w->effectiveWinId();
- return 0;
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_IM
diff --git a/src/gui/inputmethod/qinputcontext.cpp b/src/gui/inputmethod/qinputcontext.cpp
deleted file mode 100644
index e461df59af..0000000000
--- a/src/gui/inputmethod/qinputcontext.cpp
+++ /dev/null
@@ -1,500 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/****************************************************************************
-**
-** Implementation of QInputContext class
-**
-** Copyright (C) 2003-2004 immodule for Qt Project. All rights reserved.
-**
-** This file is written to contribute to Nokia Corporation and/or its subsidiary(-ies) under their own
-** license. You may use this file under your Qt license. Following
-** description is copied from their original file headers. Contact
-** immodule-qt@freedesktop.org if any conditions of this licensing are
-** not clear to you.
-**
-****************************************************************************/
-
-//#define QT_NO_IM_PREEDIT_RELOCATION
-
-#include "qinputcontext.h"
-#include "qinputcontext_p.h"
-
-#ifndef QT_NO_IM
-
-#include "qplatformdefs.h"
-
-#include "qapplication.h"
-#include "qmenu.h"
-#include "qtextformat.h"
-#include "qpalette.h"
-
-#include <stdlib.h>
-#include <limits.h>
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \class QInputContext
- \brief The QInputContext class abstracts the input method dependent data and composing state.
-
- \ingroup i18n
-
- An input method is responsible for inputting complex text that cannot
- be inputted via simple keymap. It converts a sequence of input
- events (typically key events) into a text string through the input
- method specific converting process. The class of the processes are
- widely ranging from simple finite state machine to complex text
- translator that pools a whole paragraph of a text with text
- editing capability to perform grammar and semantic analysis.
-
- To abstract such different input method specific intermediate
- information, Qt offers the QInputContext as base class. The
- concept is well known as 'input context' in the input method
- domain. An input context is created for a text widget in response
- to a demand. It is ensured that an input context is prepared for
- an input method before input to a text widget.
-
- Multiple input contexts that belong to a single input method
- may concurrently coexist. Suppose multi-window text editor. Each
- text widget of window A and B holds different QInputContext
- instance which contains different state information such as
- partially composed text.
-
- \section1 Groups of Functions
-
- \table
- \header \o Context \o Functions
-
- \row \o Receiving information \o
- x11FilterEvent(),
- filterEvent(),
- mouseHandler()
-
- \row \o Sending back composed text \o
- sendEvent()
-
- \row \o State change notification \o
- setFocusWidget(),
- reset()
-
- \row \o Context information \o
- identifierName(),
- language(),
- font(),
- isComposing()
-
- \endtable
-
- \section1 Licensing Information
-
- \legalese
- Copyright (C) 2003-2004 immodule for Qt Project. All rights reserved.
-
- This file is written to contribute to Nokia Corporation and/or its subsidiary(-ies) under their own
- license. You may use this file under your Qt license. Following
- description is copied from their original file headers. Contact
- immodule-qt@freedesktop.org if any conditions of this licensing are
- not clear to you.
- \endlegalese
-
- \sa QInputContextPlugin, QInputContextFactory, QApplication::setInputContext()
-*/
-
-/*!
- Constructs an input context with the given \a parent.
-*/
-QInputContext::QInputContext(QObject* parent)
- : QObject(*new QInputContextPrivate, parent)
-{
-}
-
-
-/*!
- Destroys the input context.
-*/
-QInputContext::~QInputContext()
-{
-}
-
-/*!
- Returns the widget that has an input focus for this input
- context.
-
- The return value may differ from holderWidget() if the input
- context is shared between several text widgets.
-
- \warning To ensure platform independence and support flexible
- configuration of widgets, ordinary input methods should not call
- this function directly.
-
- \sa setFocusWidget()
-*/
-QWidget *QInputContext::focusWidget() const
-{
- Q_D(const QInputContext);
- return d->focusWidget;
-}
-
-
-/*!
- Sets the \a widget that has an input focus for this input context.
-
- \warning Ordinary input methods must not call this function
- directly.
-
- \sa focusWidget()
-*/
-void QInputContext::setFocusWidget(QWidget *widget)
-{
- Q_ASSERT(!widget || widget->testAttribute(Qt::WA_InputMethodEnabled));
- Q_D(QInputContext);
- d->focusWidget = widget;
-}
-
-/*!
- \fn bool QInputContext::isComposing() const
-
- This function indicates whether InputMethodStart event had been
- sent to the current focus widget. It is ensured that an input
- context can send InputMethodCompose or InputMethodEnd event safely
- if this function returned true.
-
- The state is automatically being tracked through sendEvent().
-
- \sa sendEvent()
-*/
-
-/*!
- This function can be reimplemented in a subclass to filter input
- events.
-
- Return true if the \a event has been consumed. Otherwise, the
- unfiltered \a event will be forwarded to widgets as ordinary
- way. Although the input events have accept() and ignore()
- methods, leave it untouched.
-
- \a event is currently restricted to events of these types:
-
- \list
- \i CloseSoftwareInputPanel
- \i KeyPress
- \i KeyRelease
- \i MouseButtonDblClick
- \i MouseButtonPress
- \i MouseButtonRelease
- \i MouseMove
- \i RequestSoftwareInputPanel
- \endlist
-
- But some input method related events such as QWheelEvent or
- QTabletEvent may be added in future.
-
- The filtering opportunity is always given to the input context as
- soon as possible. It has to be taken place before any other key
- event consumers such as eventfilters and accelerators because some
- input methods require quite various key combination and
- sequences. It often conflicts with accelerators and so on, so we
- must give the input context the filtering opportunity first to
- ensure all input methods work properly regardless of application
- design.
-
- Ordinary input methods require discrete key events to work
- properly, so Qt's key compression is always disabled for any input
- contexts.
-
- \sa QKeyEvent, x11FilterEvent()
-*/
-bool QInputContext::filterEvent(const QEvent * /*event*/)
-{
- return false;
-}
-
-/*!
- Sends an input method event specified by \a event to the current focus
- widget. Implementations of QInputContext should call this method to
- send the generated input method events and not
- QApplication::sendEvent(), as the events might have to get dispatched
- to a different application on some platforms.
-
- Some complex input methods route the handling to several child
- contexts (e.g. to enable language switching). To account for this,
- QInputContext will check if the parent object is a QInputContext. If
- yes, it will call the parents sendEvent() implementation instead of
- sending the event directly.
-
- \sa QInputMethodEvent
-*/
-void QInputContext::sendEvent(const QInputMethodEvent &event)
-{
- // route events over input context parents to make chaining possible.
- QInputContext *p = qobject_cast<QInputContext *>(parent());
- if (p) {
- p->sendEvent(event);
- return;
- }
-
- QWidget *focus = focusWidget();
- if (!focus)
- return;
-
- QInputMethodEvent e(event);
- QApplication::sendEvent(focus, &e);
-}
-
-
-/*!
- This function can be reimplemented in a subclass to handle mouse
- press, release, double-click, and move events within the preedit
- text. You can use the function to implement mouse-oriented user
- interface such as text selection or popup menu for candidate
- selection.
-
- The \a x parameter is the offset within the string that was sent
- with the InputMethodCompose event. The alteration boundary of \a
- x is ensured as character boundary of preedit string accurately.
-
- The \a event parameter is the event that was sent to the editor
- widget. The event type is QEvent::MouseButtonPress,
- QEvent::MouseButtonRelease, QEvent::MouseButtonDblClick or
- QEvent::MouseMove. The event's button and state indicate
- the kind of operation that was performed.
-*/
-void QInputContext::mouseHandler(int /*x*/, QMouseEvent *event)
-{
- // Default behavior for simple ephemeral input contexts. Some
- // complex input contexts should not be reset here.
- if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonDblClick)
- reset();
-}
-
-
-/*!
- Returns the font of the current input widget
-*/
-QFont QInputContext::font() const
-{
- Q_D(const QInputContext);
- if (!d->focusWidget)
- return QApplication::font();
-
- return qvariant_cast<QFont>(d->focusWidget->inputMethodQuery(Qt::ImFont));
-}
-
-/*!
- This virtual function is called when a state in the focus widget
- has changed. QInputContext can then use
- QWidget::inputMethodQuery() to query the new state of the widget.
-*/
-void QInputContext::update()
-{
-}
-
-/*!
- This virtual function is called when the specified \a widget is
- destroyed. The \a widget is a widget on which this input context
- is installed.
-*/
-void QInputContext::widgetDestroyed(QWidget *widget)
-{
- Q_D(QInputContext);
- if (widget == d->focusWidget)
- setFocusWidget(0);
-}
-
-/*!
- \fn void QInputContext::reset()
-
- This function can be reimplemented in a subclass to reset the
- state of the input method.
-
- This function is called by several widgets to reset input
- state. For example, a text widget call this function before
- inserting a text to make widget ready to accept a text.
-
- Default implementation is sufficient for simple input method. You
- can override this function to reset external input method engines
- in complex input method. In the case, call QInputContext::reset()
- to ensure proper termination of inputting.
-
- In a reimplementation of reset(), you must not send any
- QInputMethodEvent containing preedit text. You can only commit
- string and attributes; otherwise, you risk breaking input state
- consistency.
-*/
-
-
-/*!
- \fn QString QInputContext::identifierName()
-
- This function must be implemented in any subclasses to return the
- identifier name of the input method.
-
- Return value is the name to identify and specify input methods for
- the input method switching mechanism and so on. The name has to be
- consistent with QInputContextPlugin::keys(). The name has to
- consist of ASCII characters only.
-
- There are two different names with different responsibility in the
- input method domain. This function returns one of them. Another
- name is called 'display name' that stands for the name for
- endusers appeared in a menu and so on.
-
- \sa QInputContextPlugin::keys(), QInputContextPlugin::displayName()
-*/
-
-
-/*!
- \fn QString QInputContext::language()
-
- This function must be implemented in any subclasses to return a
- language code (e.g. "zh_CN", "zh_TW", "zh_HK", "ja", "ko", ...)
- of the input context. If the input context can handle multiple
- languages, return the currently used one. The name has to be
- consistent with QInputContextPlugin::language().
-
- This information will be used by language tagging feature in
- QInputMethodEvent. It is required to distinguish unified han characters
- correctly. It enables proper font and character code
- handling. Suppose CJK-awared multilingual web browser
- (that automatically modifies fonts in CJK-mixed text) and XML editor
- (that automatically inserts lang attr).
-*/
-
-
-/*!
- This is a preliminary interface for Qt 4.
-*/
-QList<QAction *> QInputContext::actions()
-{
- return QList<QAction *>();
-}
-
-/*!
- \enum QInputContext::StandardFormat
-
- \value PreeditFormat The preedit text.
- \value SelectionFormat The selection text.
-
- \sa standardFormat()
-*/
-
-/*!
- Returns a QTextFormat object that specifies the format for
- component \a s.
-*/
-QTextFormat QInputContext::standardFormat(StandardFormat s) const
-{
- QWidget *focus = focusWidget();
- const QPalette &pal = focus ? focus->palette() : QApplication::palette();
-
- QTextCharFormat fmt;
- QColor bg;
- switch (s) {
- case QInputContext::PreeditFormat: {
- fmt.setUnderlineStyle(QTextCharFormat::DashUnderline);
- break;
- }
- case QInputContext::SelectionFormat: {
- bg = pal.text().color();
- fmt.setBackground(QBrush(bg));
- fmt.setForeground(pal.background());
- break;
- }
- }
- return fmt;
-}
-
-#ifdef Q_WS_X11
-/*!
- This function may be overridden only if input method is depending
- on X11 and you need raw XEvent. Otherwise, this function must not.
-
- This function is designed to filter raw key events for XIM, but
- other input methods may use this to implement some special
- features such as distinguishing Shift_L and Shift_R.
-
- Return true if the \a event has been consumed. Otherwise, the
- unfiltered \a event will be translated into QEvent and forwarded
- to filterEvent(). Filtering at both x11FilterEvent() and
- filterEvent() in single input method is allowed.
-
- \a keywidget is a client widget into which a text is inputted. \a
- event is inputted XEvent.
-
- \sa filterEvent()
-*/
-bool QInputContext::x11FilterEvent(QWidget * /*keywidget*/, XEvent * /*event*/)
-{
- return false;
-}
-#endif // Q_WS_X11
-
-#ifdef Q_OS_SYMBIAN
-/*!
- \since 4.6
-
- This function may be overridden only if input method is depending
- on Symbian and you need raw Symbian events. Otherwise, this function must not.
-
- This function is designed to filter raw key events on Symbian, but
- other input methods may use this to implement some special
- features.
-
- Return true if the \a event has been consumed. Otherwise, the
- unfiltered \a event will be translated into QEvent and forwarded
- to filterEvent(). Filtering at both symbianFilterEvent() and
- filterEvent() in single input method is allowed.
-
- \a keywidget is a client widget into which a text is inputted. \a
- event is inputted QSymbianEvent.
-
- \sa filterEvent()
-*/
-bool QInputContext::symbianFilterEvent(QWidget * /*keywidget*/, const QSymbianEvent * /*event*/)
-{
- return false;
-}
-#endif // Q_OS_SYMBIAN
-
-QT_END_NAMESPACE
-
-#endif //Q_NO_IM
diff --git a/src/gui/inputmethod/qinputcontext.h b/src/gui/inputmethod/qinputcontext.h
deleted file mode 100644
index 04f1baf3c5..0000000000
--- a/src/gui/inputmethod/qinputcontext.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/****************************************************************************
-**
-** Definition of QInputContext class
-**
-** Copyright (C) 2003-2004 immodule for Qt Project. All rights reserved.
-**
-** This file is written to contribute to Nokia Corporation and/or its subsidiary(-ies) under their own
-** license. You may use this file under your Qt license. Following
-** description is copied from their original file headers. Contact
-** immodule-qt@freedesktop.org if any conditions of this licensing are
-** not clear to you.
-**
-****************************************************************************/
-
-#ifndef QINPUTCONTEXT_H
-#define QINPUTCONTEXT_H
-
-#include <QtCore/qobject.h>
-#include <QtCore/qglobal.h>
-#include <QtGui/qevent.h>
-#include <QtCore/qstring.h>
-#include <QtCore/qlist.h>
-#include <QtGui/qaction.h>
-
-#ifndef QT_NO_IM
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QWidget;
-class QFont;
-class QPopupMenu;
-class QInputContextPrivate;
-#ifdef Q_OS_SYMBIAN
-class QSymbianEvent;
-#endif
-
-class Q_GUI_EXPORT QInputContext : public QObject
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QInputContext)
-public:
- explicit QInputContext(QObject* parent = 0);
- virtual ~QInputContext();
-
- virtual QString identifierName() = 0;
- virtual QString language() = 0;
-
- virtual void reset() = 0;
- virtual void update();
-
- virtual void mouseHandler( int x, QMouseEvent *event);
- virtual QFont font() const;
- virtual bool isComposing() const = 0;
-
- QWidget *focusWidget() const;
- virtual void setFocusWidget( QWidget *w );
-
- virtual void widgetDestroyed(QWidget *w);
-
- virtual QList<QAction *> actions();
-
-#if defined(Q_WS_X11)
- virtual bool x11FilterEvent( QWidget *keywidget, XEvent *event );
-#endif // Q_WS_X11
-#if defined(Q_OS_SYMBIAN)
- virtual bool symbianFilterEvent( QWidget *keywidget, const QSymbianEvent *event );
-#endif // Q_OS_SYMBIAN
- virtual bool filterEvent( const QEvent *event );
-
- void sendEvent(const QInputMethodEvent &event);
-
- enum StandardFormat {
- PreeditFormat,
- SelectionFormat
- };
- QTextFormat standardFormat(StandardFormat s) const;
-private:
- friend class QWidget;
- friend class QWidgetPrivate;
- friend class QInputContextFactory;
- friend class QApplication;
-private: // Disabled copy constructor and operator=
- QInputContext( const QInputContext & );
- QInputContext &operator=( const QInputContext & );
-
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif //Q_NO_IM
-
-#endif // QINPUTCONTEXT_H
diff --git a/src/gui/inputmethod/qinputcontext_p.h b/src/gui/inputmethod/qinputcontext_p.h
deleted file mode 100644
index 9251700565..0000000000
--- a/src/gui/inputmethod/qinputcontext_p.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-/****************************************************************************
-**
-** Implementation of QInputContext class
-**
-** Copyright (C) 2003-2004 immodule for Qt Project. All rights reserved.
-**
-** This file is written to contribute to Nokia Corporation and/or its subsidiary(-ies) under their own
-** license. You may use this file under your Qt license. Following
-** description is copied from their original file headers. Contact
-** immodule-qt@freedesktop.org if any conditions of this licensing are
-** not clear to you.
-**
-****************************************************************************/
-
-#ifndef QINPUTCONTEXT_P_H
-#define QINPUTCONTEXT_P_H
-
-#include "private/qobject_p.h"
-#include "qwidget.h"
-#include "qinputcontext.h"
-
-#ifndef QT_NO_IM
-
-QT_BEGIN_NAMESPACE
-
-class QInputContextPrivate : public QObjectPrivate
-{
- Q_DECLARE_PUBLIC(QInputContext)
-public:
- QInputContextPrivate()
- : focusWidget(0)
- {}
-
- QWidget *focusWidget;
-};
-
-QT_END_NAMESPACE
-
-#endif
-
-#endif
-
diff --git a/src/gui/inputmethod/qinputcontextfactory.cpp b/src/gui/inputmethod/qinputcontextfactory.cpp
deleted file mode 100644
index d85b655650..0000000000
--- a/src/gui/inputmethod/qinputcontextfactory.cpp
+++ /dev/null
@@ -1,354 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/****************************************************************************
-**
-** Implementation of QInputContextFactory class
-**
-** Copyright (C) 2003-2004 immodule for Qt Project. All rights reserved.
-**
-** This file is written to contribute to Nokia Corporation and/or its subsidiary(-ies) under their own
-** license. You may use this file under your Qt license. Following
-** description is copied from their original file headers. Contact
-** immodule-qt@freedesktop.org if any conditions of this licensing are
-** not clear to you.
-**
-****************************************************************************/
-
-#include "qinputcontextfactory.h"
-
-#ifndef QT_NO_IM
-
-#include "qcoreapplication.h"
-#include "qinputcontext.h"
-#include "qinputcontextplugin.h"
-
-#ifdef Q_WS_X11
-#include "private/qt_x11_p.h"
-#include "qximinputcontext_p.h"
-#endif
-#ifdef Q_WS_WIN
-#include "qwininputcontext_p.h"
-#endif
-#ifdef Q_WS_MAC
-#include "qmacinputcontext_p.h"
-#endif
-#ifdef Q_WS_S60
-#include "qcoefepinputcontext_p.h"
-#include "AknInputLanguageInfo.h"
-#endif
-
-#include "private/qfactoryloader_p.h"
-#include "qmutex.h"
-
-QT_BEGIN_NAMESPACE
-
-#ifndef QT_NO_LIBRARY
-Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
- (QInputContextFactoryInterface_iid, QLatin1String("/inputmethods")))
-#endif
-
-/*!
- \class QInputContextFactory
- \brief The QInputContextFactory class creates QInputContext objects.
-
-
- The input context factory creates a QInputContext object for a
- given key with QInputContextFactory::create().
-
- The input contexts are either built-in or dynamically loaded from
- an input context plugin (see QInputContextPlugin).
-
- keys() returns a list of valid keys. The
- keys are the names used, for example, to identify and specify
- input methods for the input method switching mechanism. The names
- have to be consistent with QInputContext::identifierName(), and
- may only contain ASCII characters.
-
- A key can be used to retrieve the associated input context's
- supported languages using languages(). You
- can retrieve the input context's description using
- description() and finally you can get a user
- friendly internationalized name of the QInputContext object
- specified by the key using displayName().
-
- \legalese
- Copyright (C) 2003-2004 immodule for Qt Project. All rights reserved.
-
- This file is written to contribute to Nokia Corporation and/or its subsidiary(-ies) under their own
- license. You may use this file under your Qt license. Following
- description is copied from their original file headers. Contact
- immodule-qt@freedesktop.org if any conditions of this licensing are
- not clear to you.
- \endlegalese
-
- \sa QInputContext, QInputContextPlugin
-*/
-
-/*!
- Creates and returns a QInputContext object for the input context
- specified by \a key with the given \a parent. Keys are case
- sensitive.
-
- \sa keys()
-*/
-QInputContext *QInputContextFactory::create( const QString& key, QObject *parent )
-{
- QInputContext *result = 0;
-#if defined(Q_WS_X11) && !defined(QT_NO_XIM)
- if (key == QLatin1String("xim")) {
- result = new QXIMInputContext;
- }
-#endif
-#if defined(Q_WS_WIN)
- if (key == QLatin1String("win")) {
- result = new QWinInputContext;
- }
-#endif
-#if defined(Q_WS_MAC)
- if (key == QLatin1String("mac")) {
- result = new QMacInputContext;
- }
-#endif
-#if defined(Q_WS_S60)
- if (key == QLatin1String("coefep")) {
- result = new QCoeFepInputContext;
- }
-#endif
-#ifdef QT_NO_LIBRARY
- Q_UNUSED(key);
-#else
- if (QInputContextFactoryInterface *factory =
- qobject_cast<QInputContextFactoryInterface*>(loader()->instance(key))) {
- result = factory->create(key);
- }
-#endif
- if (result)
- result->setParent(parent);
- return result;
-}
-
-
-/*!
- Returns the list of keys this factory can create input contexts
- for.
-
- The keys are the names used, for example, to identify and specify
- input methods for the input method switching mechanism. The names
- have to be consistent with QInputContext::identifierName(), and
- may only contain ASCII characters.
-
- \sa create(), displayName(), QInputContext::identifierName()
-*/
-QStringList QInputContextFactory::keys()
-{
- QStringList result;
-#if defined(Q_WS_X11) && !defined(QT_NO_XIM)
- result << QLatin1String("xim");
-#endif
-#if defined(Q_WS_WIN) && !defined(QT_NO_XIM)
- result << QLatin1String("win");
-#endif
-#if defined(Q_WS_MAC)
- result << QLatin1String("mac");
-#endif
-#if defined(Q_WS_S60)
- result << QLatin1String("coefep");
-#endif
-#ifndef QT_NO_LIBRARY
- result += loader()->keys();
-#endif // QT_NO_LIBRARY
- return result;
-}
-
-#if defined(Q_WS_S60)
-/*!
- \internal
-
- This function contains pure Symbian exception handling code for
- getting S60 language list.
- Returned object ownership is transferred to caller.
-*/
-static CAknInputLanguageList* s60LangListL()
-{
- CAknInputLanguageInfo *langInfo = AknInputLanguageInfoFactory::CreateInputLanguageInfoL();
- CleanupStack::PushL(langInfo);
- // In rare phone there is more than 7 languages installed -> use 7 as an array granularity
- CAknInputLanguageList *langList = new (ELeave) CAknInputLanguageList(7);
- CleanupStack::PushL(langList);
- langInfo->AppendAvailableLanguagesL(langList);
- CleanupStack::Pop(langList);
- CleanupStack::PopAndDestroy(langInfo);
- return langList;
-}
-
-/*!
- \internal
-
- This function utility function return S60 language list.
- Returned object ownership is transferred to caller.
-*/
-static CAknInputLanguageList* s60LangList()
-{
- CAknInputLanguageList *langList = NULL;
- TRAP_IGNORE(langList = s60LangListL());
- q_check_ptr(langList);
- return langList;
-}
-#endif
-
-/*!
- Returns the languages supported by the QInputContext object
- specified by \a key.
-
- The languages are expressed as language code (e.g. "zh_CN",
- "zh_TW", "zh_HK", "ja", "ko", ...). An input context that supports
- multiple languages can return all supported languages as a
- QStringList. The name has to be consistent with
- QInputContext::language().
-
- This information may be used to optimize a user interface.
-
- \sa keys(), QInputContext::language(), QLocale
-*/
-QStringList QInputContextFactory::languages( const QString &key )
-{
- QStringList result;
-#if defined(Q_WS_X11) && !defined(QT_NO_XIM)
- if (key == QLatin1String("xim"))
- return QStringList(QString());
-#endif
-#if defined(Q_WS_WIN)
- if (key == QLatin1String("win"))
- return QStringList(QString());
-#endif
-#if defined(Q_WS_MAC)
- if (key == QLatin1String("mac"))
- return QStringList(QString());
-#endif
-#if defined(Q_WS_S60)
- if (key == QLatin1String("coefep"))
- {
- CAknInputLanguageList *langList = s60LangList();
- int count = langList->Count();
- for (int i = 0; i < count; ++i)
- {
- result.append(QString(qt_symbianLocaleName(langList->At(i)->LanguageCode())));
- }
- delete langList;
- }
-#endif
-#if defined(QT_NO_LIBRARY) || defined(QT_NO_SETTINGS)
- Q_UNUSED(key);
-#else
- if (QInputContextFactoryInterface *factory =
- qobject_cast<QInputContextFactoryInterface*>(loader()->instance(key)))
- result = factory->languages(key);
-#endif // QT_NO_LIBRARY
- return result;
-}
-
-/*!
- Returns a user friendly internationalized name of the
- QInputContext object specified by \a key. You can, for example,
- use this name in a menu.
-
- \sa keys(), QInputContext::identifierName()
-*/
-QString QInputContextFactory::displayName( const QString &key )
-{
- QString result;
-#if defined(Q_WS_X11) && !defined(QT_NO_XIM)
- if (key == QLatin1String("xim"))
- return QInputContext::tr( "XIM" );
-#endif
-#ifdef Q_WS_S60
- if (key == QLatin1String("coefep"))
- return QInputContext::tr( "FEP" );
-#endif
-#if defined(QT_NO_LIBRARY) || defined(QT_NO_SETTINGS)
- Q_UNUSED(key);
-#else
- if (QInputContextFactoryInterface *factory =
- qobject_cast<QInputContextFactoryInterface*>(loader()->instance(key)))
- return factory->displayName(key);
-#endif // QT_NO_LIBRARY
- return QString();
-}
-
-/*!
- Returns an internationalized brief description of the QInputContext
- object specified by \a key. You can, for example, use this
- description in a user interface.
-
- \sa keys(), displayName()
-*/
-QString QInputContextFactory::description( const QString &key )
-{
-#if defined(Q_WS_X11) && !defined(QT_NO_XIM)
- if (key == QLatin1String("xim"))
- return QInputContext::tr( "XIM input method" );
-#endif
-#if defined(Q_WS_WIN) && !defined(QT_NO_XIM)
- if (key == QLatin1String("win"))
- return QInputContext::tr( "Windows input method" );
-#endif
-#if defined(Q_WS_MAC)
- if (key == QLatin1String("mac"))
- return QInputContext::tr( "Mac OS X input method" );
-#endif
-#if defined(Q_WS_S60)
- if (key == QLatin1String("coefep"))
- return QInputContext::tr( "S60 FEP input method" );
-#endif
-#if defined(QT_NO_LIBRARY) || defined(QT_NO_SETTINGS)
- Q_UNUSED(key);
-#else
- if (QInputContextFactoryInterface *factory =
- qobject_cast<QInputContextFactoryInterface*>(loader()->instance(key)))
- return factory->description(key);
-#endif // QT_NO_LIBRARY
- return QString();
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_IM
diff --git a/src/gui/inputmethod/qinputcontextfactory.h b/src/gui/inputmethod/qinputcontextfactory.h
deleted file mode 100644
index e7513a13bc..0000000000
--- a/src/gui/inputmethod/qinputcontextfactory.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/****************************************************************************
-**
-** Definition of QInputContextFactory class
-**
-** Copyright (C) 2003-2004 immodule for Qt Project. All rights reserved.
-**
-** This file is written to contribute to Nokia Corporation and/or its subsidiary(-ies) under their own
-** license. You may use this file under your Qt license. Following
-** description is copied from their original file headers. Contact
-** immodule-qt@freedesktop.org if any conditions of this licensing are
-** not clear to you.
-**
-****************************************************************************/
-
-#ifndef QINPUTCONTEXTFACTORY_H
-#define QINPUTCONTEXTFACTORY_H
-
-#include <QtCore/qstringlist.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_IM
-
-class QInputContext;
-class QWidget;
-
-class Q_GUI_EXPORT QInputContextFactory
-{
-public:
- static QStringList keys();
- static QInputContext *create( const QString &key, QObject *parent ); // should be a toplevel widget
- static QStringList languages( const QString &key );
- static QString displayName( const QString &key );
- static QString description( const QString &key );
-};
-
-#endif // QT_NO_IM
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QINPUTCONTEXTFACTORY_H
diff --git a/src/gui/inputmethod/qinputcontextplugin.cpp b/src/gui/inputmethod/qinputcontextplugin.cpp
deleted file mode 100644
index 5921b936ab..0000000000
--- a/src/gui/inputmethod/qinputcontextplugin.cpp
+++ /dev/null
@@ -1,178 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/****************************************************************************
-**
-** Implementation of QInputContext class
-**
-** Copyright (C) 2003-2004 immodule for Qt Project. All rights reserved.
-**
-** This file is written to contribute to Nokia Corporation and/or its subsidiary(-ies) under their own
-** license. You may use this file under your Qt license. Following
-** description is copied from their original file headers. Contact
-** immodule-qt@freedesktop.org if any conditions of this licensing are
-** not clear to you.
-**
-****************************************************************************/
-
-#include "qinputcontextplugin.h"
-
-#ifndef QT_NO_IM
-#ifndef QT_NO_LIBRARY
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \class QInputContextPlugin
- \brief The QInputContextPlugin class provides an abstract base for custom QInputContext plugins.
-
- \reentrant
- \ingroup plugins
-
- The input context plugin is a simple plugin interface that makes it
- easy to create custom input contexts that can be loaded dynamically
- into applications.
-
- To create an input context plugin you subclass this base class,
- reimplement the pure virtual functions keys(), create(),
- languages(), displayName(), and description(), and export the
- class with the Q_EXPORT_PLUGIN2() macro.
-
- \legalese
- Copyright (C) 2003-2004 immodule for Qt Project. All rights reserved.
-
- This file is written to contribute to Nokia Corporation and/or its subsidiary(-ies) under their own
- license. You may use this file under your Qt license. Following
- description is copied from their original file headers. Contact
- immodule-qt@freedesktop.org if any conditions of this licensing are
- not clear to you.
- \endlegalese
-
- \sa QInputContext, {How to Create Qt Plugins}
-*/
-
-/*!
- \fn QStringList QInputContextPlugin::keys() const
-
- Returns the list of QInputContext keys this plugin provides.
-
- These keys are usually the class names of the custom input context
- that are implemented in the plugin. The names are used, for
- example, to identify and specify input methods for the input
- method switching mechanism. They have to be consistent with
- QInputContext::identifierName(), and may only contain ASCII
- characters.
-
- \sa create(), displayName(), QInputContext::identifierName()
-*/
-
-/*!
- \fn QInputContext* QInputContextPlugin::create( const QString& key )
-
- Creates and returns a QInputContext object for the input context
- key \a key. The input context key is usually the class name of
- the required input method.
-
- \sa keys()
-*/
-
-/*!
- \fn QStringList QInputContextPlugin::languages(const QString &key)
-
- Returns the languages supported by the QInputContext object
- specified by \a key.
-
- The languages are expressed as language code (e.g. "zh_CN",
- "zh_TW", "zh_HK", "ja", "ko", ...). An input context that supports
- multiple languages can return all supported languages as
- QStringList. The name has to be consistent with
- QInputContext::language().
-
- This information may be used to optimize user interface.
-
- \sa keys(), QInputContext::language(), QLocale
-*/
-
-/*!
- \fn QString QInputContextPlugin::displayName(const QString &key)
-
- Returns a user friendly internationalized name of the
- QInputContext object specified by \a key. You can, for example,
- use this name in a menu.
-
- \sa keys(), QInputContext::identifierName()
-*/
-
-/*!
- \fn QString QInputContextPlugin::description(const QString &key)
-
- Returns an internationalized brief description of the QInputContext
- object specified by \a key. You can, for example, use this
- description in a user interface.
-
- \sa keys(), displayName()
-*/
-
-
-/*!
- Constructs a input context plugin with the given \a parent. This
- is invoked automatically by the Q_EXPORT_PLUGIN2() macro.
-*/
-QInputContextPlugin::QInputContextPlugin(QObject *parent)
- :QObject(parent)
-{
-}
-
-/*!
- Destroys the input context plugin.
-
- You never have to call this explicitly. Qt destroys a plugin
- automatically when it's no longer used.
-*/
-QInputContextPlugin::~QInputContextPlugin()
-{
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_LIBRARY
-
-#endif // QT_NO_IM
diff --git a/src/gui/inputmethod/qinputcontextplugin.h b/src/gui/inputmethod/qinputcontextplugin.h
deleted file mode 100644
index 0bcb7453de..0000000000
--- a/src/gui/inputmethod/qinputcontextplugin.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/****************************************************************************
-**
-** Definition of QInputContextPlugin class
-**
-** Copyright (C) 2003-2004 immodule for Qt Project. All rights reserved.
-**
-** This file is written to contribute to Nokia Corporation and/or its subsidiary(-ies) under their own
-** license. You may use this file under your Qt license. Following
-** description is copied from their original file headers. Contact
-** immodule-qt@freedesktop.org if any conditions of this licensing are
-** not clear to you.
-**
-****************************************************************************/
-
-#ifndef QINPUTCONTEXTPLUGIN_H
-#define QINPUTCONTEXTPLUGIN_H
-
-#include <QtCore/qplugin.h>
-#include <QtCore/qfactoryinterface.h>
-#include <QtCore/qstringlist.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#if !defined(QT_NO_IM)
-
-class QInputContext;
-class QInputContextPluginPrivate;
-
-struct Q_GUI_EXPORT QInputContextFactoryInterface : public QFactoryInterface
-{
- virtual QInputContext *create( const QString &key ) = 0;
- virtual QStringList languages( const QString &key ) = 0;
- virtual QString displayName( const QString &key ) = 0;
- virtual QString description( const QString &key ) = 0;
-};
-
-#define QInputContextFactoryInterface_iid "com.trolltech.Qt.QInputContextFactoryInterface"
-Q_DECLARE_INTERFACE(QInputContextFactoryInterface, QInputContextFactoryInterface_iid)
-
-class Q_GUI_EXPORT QInputContextPlugin : public QObject, public QInputContextFactoryInterface
-{
- Q_OBJECT
- Q_INTERFACES(QInputContextFactoryInterface:QFactoryInterface)
-public:
- explicit QInputContextPlugin(QObject *parent = 0);
- ~QInputContextPlugin();
-
- virtual QStringList keys() const = 0;
- virtual QInputContext *create( const QString &key ) = 0;
- virtual QStringList languages( const QString &key ) = 0;
- virtual QString displayName( const QString &key ) = 0;
- virtual QString description( const QString &key ) = 0;
-};
-
-#endif // QT_NO_IM
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QINPUTCONTEXTPLUGIN_H
diff --git a/src/gui/inputmethod/qmacinputcontext_p.h b/src/gui/inputmethod/qmacinputcontext_p.h
deleted file mode 100644
index 15d2f77b9c..0000000000
--- a/src/gui/inputmethod/qmacinputcontext_p.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QMACINPUTCONTEXT_P_H
-#define QMACINPUTCONTEXT_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "QtGui/qinputcontext.h"
-#include "private/qt_mac_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class Q_GUI_EXPORT QMacInputContext : public QInputContext
-{
- Q_OBJECT
- //Q_DECLARE_PRIVATE(QMacInputContext)
- void createTextDocument();
-public:
- explicit QMacInputContext(QObject* parent = 0);
- virtual ~QMacInputContext();
-
- virtual void setFocusWidget(QWidget *w);
- virtual QString identifierName() { return QLatin1String("mac"); }
- virtual QString language();
-
- virtual void reset();
-
- virtual bool isComposing() const;
-
- static OSStatus globalEventProcessor(EventHandlerCallRef, EventRef, void *);
- static void initialize();
- static void cleanup();
-
- EventRef lastKeydownEvent() { return keydownEvent; }
- void setLastKeydownEvent(EventRef);
-
-protected:
- void mouseHandler(int pos, QMouseEvent *);
-private:
- bool composing;
- bool recursionGuard;
- TSMDocumentID textDocument;
- QString currentText;
- EventRef keydownEvent;
-};
-
-QT_END_NAMESPACE
-
-#endif // QMACINPUTCONTEXT_P_H
diff --git a/src/gui/inputmethod/qwininputcontext_p.h b/src/gui/inputmethod/qwininputcontext_p.h
deleted file mode 100644
index a3a7290a16..0000000000
--- a/src/gui/inputmethod/qwininputcontext_p.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWININPUTCONTEXT_P_H
-#define QWININPUTCONTEXT_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of qinputcontext.cpp. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "QtGui/qinputcontext.h"
-#include "QtCore/qt_windows.h"
-
-#if !defined(IMR_RECONVERTSTRING)
-typedef struct tagRECONVERTSTRING {
- DWORD dwSize;
- DWORD dwVersion;
- DWORD dwStrLen;
- DWORD dwStrOffset;
- DWORD dwCompStrLen;
- DWORD dwCompStrOffset;
- DWORD dwTargetStrLen;
- DWORD dwTargetStrOffset;
-} RECONVERTSTRING, *PRECONVERTSTRING;
-#endif
-
-QT_BEGIN_NAMESPACE
-
-class QWinInputContext : public QInputContext
-{
- Q_OBJECT
-public:
- explicit QWinInputContext(QObject* parent = 0);
- virtual ~QWinInputContext();
-
- virtual QString identifierName() { return QLatin1String("win"); }
- virtual QString language();
-
- virtual void reset();
- virtual void update();
-
- virtual void mouseHandler(int x, QMouseEvent *event);
- virtual bool isComposing() const;
-
- virtual void setFocusWidget(QWidget *w);
-
- bool startComposition();
- bool endComposition();
- bool composition(LPARAM lparam);
- int reconvertString(RECONVERTSTRING *reconv);
-
- static void TranslateMessage(const MSG *msg);
- static LRESULT DefWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
-
- static void updateImeStatus(QWidget *w, bool hasFocus);
- static void enablePopupChild(QWidget *w, bool e);
- static void enable(QWidget *w, bool e);
-
-private:
- void init();
- bool recursionGuard;
-};
-
-QT_END_NAMESPACE
-
-#endif // QWININPUTCONTEXT_P_H
diff --git a/src/gui/inputmethod/qwsinputcontext_p.h b/src/gui/inputmethod/qwsinputcontext_p.h
deleted file mode 100644
index bf69fe178b..0000000000
--- a/src/gui/inputmethod/qwsinputcontext_p.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWSINPUTCONTEXT_P_H
-#define QWSINPUTCONTEXT_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of the QLibrary class. This header file may change from
-// version to version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "QtGui/qinputcontext.h"
-
-#ifndef QT_NO_QWS_INPUTMETHODS
-
-QT_BEGIN_NAMESPACE
-
-class QWSIMEvent;
-class QWSIMQueryEvent;
-class QWSIMInitEvent;
-
-class QWSInputContext : public QInputContext
-{
- Q_OBJECT
-public:
- explicit QWSInputContext(QObject* parent = 0);
- ~QWSInputContext() {}
-
-
- QString identifierName() { return QString(); }
- QString language() { return QString(); }
-
- void reset();
- void update();
- void mouseHandler( int x, QMouseEvent *event);
-
- void setFocusWidget( QWidget *w );
- void widgetDestroyed(QWidget *w);
-
- bool isComposing() const;
-
- static QWidget *activeWidget();
- static bool translateIMEvent(QWidget *w, const QWSIMEvent *e);
- static bool translateIMQueryEvent(QWidget *w, const QWSIMQueryEvent *e);
- static bool translateIMInitEvent(const QWSIMInitEvent *e);
- static void updateImeStatus(QWidget *w, bool hasFocus);
-};
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_QWS_INPUTMETHODS
-
-#endif // QWSINPUTCONTEXT_P_H
diff --git a/src/gui/inputmethod/qwsinputcontext_qws.cpp b/src/gui/inputmethod/qwsinputcontext_qws.cpp
deleted file mode 100644
index 30fefc365e..0000000000
--- a/src/gui/inputmethod/qwsinputcontext_qws.cpp
+++ /dev/null
@@ -1,246 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qwsinputcontext_p.h"
-#include "qinputcontext_p.h"
-#include "qwsdisplay_qws.h"
-#include "qwsevent_qws.h"
-#include "private/qwscommand_qws_p.h"
-#include "qwindowsystem_qws.h"
-#include "qevent.h"
-#include "qtextformat.h"
-
-#include <qbuffer.h>
-
-#include <qdebug.h>
-
-#ifndef QT_NO_QWS_INPUTMETHODS
-
-QT_BEGIN_NAMESPACE
-
-static QWidget* activeWidget = 0;
-
-//#define EXTRA_DEBUG
-
-QWSInputContext::QWSInputContext(QObject *parent)
- :QInputContext(parent)
-{
-}
-
-void QWSInputContext::reset()
-{
- QPaintDevice::qwsDisplay()->resetIM();
-}
-
-
-void QWSInputContext::setFocusWidget( QWidget *w )
-{
- QWidget *oldFocus = focusWidget();
- if (oldFocus == w)
- return;
-
- if (w) {
- QWSInputContext::updateImeStatus(w, true);
- } else {
- if (oldFocus)
- QWSInputContext::updateImeStatus(oldFocus, false);
- }
-
- if (oldFocus) {
- QWidget *tlw = oldFocus->window();
- int winid = tlw->internalWinId();
-
- int widgetid = oldFocus->internalWinId();
- QPaintDevice::qwsDisplay()->sendIMUpdate(QWSInputMethod::FocusOut, winid, widgetid);
- }
-
- QInputContext::setFocusWidget(w);
-
- if (!w)
- return;
-
- QWidget *tlw = w->window();
- int winid = tlw->winId();
-
- int widgetid = w->winId();
- QPaintDevice::qwsDisplay()->sendIMUpdate(QWSInputMethod::FocusIn, winid, widgetid);
-
- //setfocus ???
-
- update();
-}
-
-
-void QWSInputContext::widgetDestroyed(QWidget *w)
-{
- if (w == QT_PREPEND_NAMESPACE(activeWidget))
- QT_PREPEND_NAMESPACE(activeWidget) = 0;
- QInputContext::widgetDestroyed(w);
-}
-
-void QWSInputContext::update()
-{
- QWidget *w = focusWidget();
- if (!w)
- return;
-
- QWidget *tlw = w->window();
- int winid = tlw->winId();
-
- int widgetid = w->winId();
- QPaintDevice::qwsDisplay()->sendIMUpdate(QWSInputMethod::Update, winid, widgetid);
-
-}
-
-void QWSInputContext::mouseHandler( int x, QMouseEvent *event)
-{
- if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonRelease)
- QPaintDevice::qwsDisplay()->sendIMMouseEvent( x, event->type() == QEvent::MouseButtonPress );
-}
-
-QWidget *QWSInputContext::activeWidget()
-{
- return QT_PREPEND_NAMESPACE(activeWidget);
-}
-
-
-bool QWSInputContext::isComposing() const
-{
- return QT_PREPEND_NAMESPACE(activeWidget) != 0;
-}
-
-bool QWSInputContext::translateIMQueryEvent(QWidget *w, const QWSIMQueryEvent *e)
-{
- Qt::InputMethodQuery type = static_cast<Qt::InputMethodQuery>(e->simpleData.property);
- QVariant result = w->inputMethodQuery(type);
- QWidget *tlw = w->window();
- int winId = tlw->winId();
-
- if ( type == Qt::ImMicroFocus ) {
- // translate to relative to tlw
- QRect mf = result.toRect();
- mf.moveTopLeft(w->mapTo(tlw,mf.topLeft()));
- result = mf;
- }
-
- QPaintDevice::qwsDisplay()->sendIMResponse(winId, e->simpleData.property, result);
-
- return false;
-}
-
-bool QWSInputContext::translateIMInitEvent(const QWSIMInitEvent *e)
-{
- Q_UNUSED(e);
- qDebug("### QWSInputContext::translateIMInitEvent not implemented ###");
- return false;
-}
-
-bool QWSInputContext::translateIMEvent(QWidget *w, const QWSIMEvent *e)
-{
- QDataStream stream(e->streamingData);
- QString preedit;
- QString commit;
-
- stream >> preedit;
- stream >> commit;
-
- if (preedit.isEmpty() && QT_PREPEND_NAMESPACE(activeWidget))
- w = QT_PREPEND_NAMESPACE(activeWidget);
-
- QInputContext *qic = w->inputContext();
- if (!qic)
- return false;
-
- QList<QInputMethodEvent::Attribute> attrs;
-
-
- while (!stream.atEnd()) {
- int type = -1;
- int start = -1;
- int length = -1;
- QVariant data;
- stream >> type >> start >> length >> data;
- if (stream.status() != QDataStream::Ok) {
- qWarning("corrupted QWSIMEvent");
- //qic->reset(); //???
- return false;
- }
- if (type == QInputMethodEvent::TextFormat)
- data = qic->standardFormat(static_cast<QInputContext::StandardFormat>(data.toInt()));
- attrs << QInputMethodEvent::Attribute(static_cast<QInputMethodEvent::AttributeType>(type), start, length, data);
- }
-#ifdef EXTRA_DEBUG
- qDebug() << "preedit" << preedit << "len" << preedit.length() <<"commit" << commit << "len" << commit.length()
- << "n attr" << attrs.count();
-#endif
-
- if (preedit.isEmpty())
- QT_PREPEND_NAMESPACE(activeWidget) = 0;
- else
- QT_PREPEND_NAMESPACE(activeWidget) = w;
-
-
- QInputMethodEvent ime(preedit, attrs);
- if (!commit.isEmpty() || e->simpleData.replaceLength > 0)
- ime.setCommitString(commit, e->simpleData.replaceFrom, e->simpleData.replaceLength);
-
-
- extern bool qt_sendSpontaneousEvent(QObject *, QEvent *); //qapplication_qws.cpp
- qt_sendSpontaneousEvent(w, &ime);
-
- return true;
-}
-
-Q_GUI_EXPORT void (*qt_qws_inputMethodStatusChanged)(QWidget*) = 0;
-
-void QWSInputContext::updateImeStatus(QWidget *w, bool hasFocus)
-{
- Q_UNUSED(hasFocus);
-
- if (!w || !qt_qws_inputMethodStatusChanged)
- return;
- qt_qws_inputMethodStatusChanged(w);
-}
-
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_QWS_INPUTMETHODS
diff --git a/src/gui/inputmethod/qximinputcontext_p.h b/src/gui/inputmethod/qximinputcontext_p.h
deleted file mode 100644
index 1f89a08745..0000000000
--- a/src/gui/inputmethod/qximinputcontext_p.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/****************************************************************************
-**
-** Definition of QXIMInputContext class
-**
-** Copyright (C) 2003-2004 immodule for Qt Project. All rights reserved.
-**
-** This file is written to contribute to Nokia Corporation and/or its subsidiary(-ies) under their own
-** license. You may use this file under your Qt license. Following
-** description is copied from their original file headers. Contact
-** immodule-qt@freedesktop.org if any conditions of this licensing are
-** not clear to you.
-**
-****************************************************************************/
-
-#ifndef QXIMINPUTCONTEXT_P_H
-#define QXIMINPUTCONTEXT_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#if !defined(Q_NO_IM)
-
-#include "QtCore/qglobal.h"
-#include "QtGui/qinputcontext.h"
-#include "QtGui/qfont.h"
-#include "QtCore/qhash.h"
-#ifdef Q_WS_X11
-#include "QtCore/qlist.h"
-#include "QtCore/qbitarray.h"
-#include "QtGui/qwindowdefs.h"
-#include "private/qt_x11_p.h"
-#endif
-
-QT_BEGIN_NAMESPACE
-
-class QKeyEvent;
-class QWidget;
-class QFont;
-class QString;
-
-class QXIMInputContext : public QInputContext
-{
- Q_OBJECT
-public:
- struct ICData {
- XIC ic;
- XFontSet fontset;
- QWidget *widget;
- QString text;
- QBitArray selectedChars;
- bool composing;
- bool preeditEmpty;
- void clear();
- };
-
- QXIMInputContext();
- ~QXIMInputContext();
-
- QString identifierName();
- QString language();
-
- void reset();
-
- void mouseHandler( int x, QMouseEvent *event);
- bool isComposing() const;
-
- void setFocusWidget( QWidget *w );
- void widgetDestroyed(QWidget *w);
-
- void create_xim();
- void close_xim();
-
- void update();
-
- ICData *icData() const;
-protected:
- bool x11FilterEvent( QWidget *keywidget, XEvent *event );
-
-private:
- static XIMStyle xim_style;
-
- QString _language;
- XIM xim;
- QHash<WId, ICData *> ximData;
-
- ICData *createICData(QWidget *w);
-};
-
-QT_END_NAMESPACE
-
-#endif // Q_NO_IM
-
-#endif // QXIMINPUTCONTEXT_P_H
diff --git a/src/gui/itemviews/itemviews.pri b/src/gui/itemviews/itemviews.pri
deleted file mode 100644
index 149bfd67b0..0000000000
--- a/src/gui/itemviews/itemviews.pri
+++ /dev/null
@@ -1,72 +0,0 @@
-# Qt gui library, itemviews
-
-HEADERS += \
- itemviews/qabstractitemview.h \
- itemviews/qabstractitemview_p.h \
- itemviews/qheaderview.h \
- itemviews/qidentityproxymodel.h \
- itemviews/qlistview.h \
- itemviews/qlistview_p.h \
- itemviews/qbsptree_p.h \
- itemviews/qtableview.h \
- itemviews/qtableview_p.h \
- itemviews/qtreeview.h \
- itemviews/qtreeview_p.h \
- itemviews/qabstractitemdelegate.h \
- itemviews/qitemdelegate.h \
- itemviews/qitemselectionmodel.h \
- itemviews/qitemselectionmodel_p.h \
- itemviews/qdirmodel.h \
- itemviews/qlistwidget.h \
- itemviews/qlistwidget_p.h \
- itemviews/qtablewidget.h \
- itemviews/qtablewidget_p.h \
- itemviews/qtreewidget.h \
- itemviews/qtreewidget_p.h \
- itemviews/qwidgetitemdata_p.h \
- itemviews/qproxymodel.h \
- itemviews/qproxymodel_p.h \
- itemviews/qabstractproxymodel.h \
- itemviews/qabstractproxymodel_p.h \
- itemviews/qsortfilterproxymodel.h \
- itemviews/qitemeditorfactory.h \
- itemviews/qitemeditorfactory_p.h \
- itemviews/qstandarditemmodel.h \
- itemviews/qstandarditemmodel_p.h \
- itemviews/qstringlistmodel.h \
- itemviews/qtreewidgetitemiterator.h \
- itemviews/qdatawidgetmapper.h \
- itemviews/qfileiconprovider.h \
- itemviews/qcolumnviewgrip_p.h \
- itemviews/qcolumnview.h \
- itemviews/qcolumnview_p.h \
- itemviews/qstyleditemdelegate.h
-
-SOURCES += \
- itemviews/qabstractitemview.cpp \
- itemviews/qheaderview.cpp \
- itemviews/qidentityproxymodel.cpp \
- itemviews/qlistview.cpp \
- itemviews/qbsptree.cpp \
- itemviews/qtableview.cpp \
- itemviews/qtreeview.cpp \
- itemviews/qabstractitemdelegate.cpp \
- itemviews/qitemdelegate.cpp \
- itemviews/qitemselectionmodel.cpp \
- itemviews/qdirmodel.cpp \
- itemviews/qlistwidget.cpp \
- itemviews/qtablewidget.cpp \
- itemviews/qtreewidget.cpp \
- itemviews/qproxymodel.cpp \
- itemviews/qabstractproxymodel.cpp \
- itemviews/qsortfilterproxymodel.cpp \
- itemviews/qitemeditorfactory.cpp \
- itemviews/qstandarditemmodel.cpp \
- itemviews/qstringlistmodel.cpp \
- itemviews/qtreewidgetitemiterator.cpp \
- itemviews/qdatawidgetmapper.cpp \
- itemviews/qfileiconprovider.cpp \
- itemviews/qcolumnview.cpp \
- itemviews/qcolumnviewgrip.cpp \
- itemviews/qstyleditemdelegate.cpp
-
diff --git a/src/gui/itemviews/qabstractitemdelegate.h b/src/gui/itemviews/qabstractitemdelegate.h
deleted file mode 100644
index 19d73b11b9..0000000000
--- a/src/gui/itemviews/qabstractitemdelegate.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QABSTRACTITEMDELEGATE_H
-#define QABSTRACTITEMDELEGATE_H
-
-#include <QtCore/qobject.h>
-#include <QtGui/qstyleoption.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_ITEMVIEWS
-
-class QPainter;
-class QModelIndex;
-class QAbstractItemModel;
-class QAbstractItemView;
-class QHelpEvent;
-
-class Q_GUI_EXPORT QAbstractItemDelegate : public QObject
-{
- Q_OBJECT
-
-public:
-
- enum EndEditHint {
- NoHint,
- EditNextItem,
- EditPreviousItem,
- SubmitModelCache,
- RevertModelCache
- };
-
- explicit QAbstractItemDelegate(QObject *parent = 0);
- virtual ~QAbstractItemDelegate();
-
- // painting
- virtual void paint(QPainter *painter,
- const QStyleOptionViewItem &option,
- const QModelIndex &index) const = 0;
-
- virtual QSize sizeHint(const QStyleOptionViewItem &option,
- const QModelIndex &index) const = 0;
-
- // editing
- virtual QWidget *createEditor(QWidget *parent,
- const QStyleOptionViewItem &option,
- const QModelIndex &index) const;
-
- virtual void setEditorData(QWidget *editor, const QModelIndex &index) const;
-
- virtual void setModelData(QWidget *editor,
- QAbstractItemModel *model,
- const QModelIndex &index) const;
-
- virtual void updateEditorGeometry(QWidget *editor,
- const QStyleOptionViewItem &option,
- const QModelIndex &index) const;
-
- // for non-widget editors
- virtual bool editorEvent(QEvent *event,
- QAbstractItemModel *model,
- const QStyleOptionViewItem &option,
- const QModelIndex &index);
-
- static QString elidedText(const QFontMetrics &fontMetrics, int width,
- Qt::TextElideMode mode, const QString &text);
-
-public Q_SLOTS:
- bool helpEvent(QHelpEvent *event,
- QAbstractItemView *view,
- const QStyleOptionViewItem &option,
- const QModelIndex &index);
-
-Q_SIGNALS:
- void commitData(QWidget *editor);
- void closeEditor(QWidget *editor, QAbstractItemDelegate::EndEditHint hint = NoHint);
- void sizeHintChanged(const QModelIndex &);
-
-protected:
- QAbstractItemDelegate(QObjectPrivate &, QObject *parent = 0);
-private:
- Q_DISABLE_COPY(QAbstractItemDelegate)
-};
-
-#endif // QT_NO_ITEMVIEWS
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QABSTRACTITEMDELEGATE_H
diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp
deleted file mode 100644
index d3875c8961..0000000000
--- a/src/gui/itemviews/qabstractitemview.cpp
+++ /dev/null
@@ -1,4320 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qabstractitemview.h"
-
-#ifndef QT_NO_ITEMVIEWS
-#include <qpointer.h>
-#include <qapplication.h>
-#include <qclipboard.h>
-#include <qpainter.h>
-#include <qstyle.h>
-#include <qdrag.h>
-#include <qevent.h>
-#include <qscrollbar.h>
-#include <qwhatsthis.h>
-#include <qtooltip.h>
-#include <qdatetime.h>
-#include <qlineedit.h>
-#include <qspinbox.h>
-#include <qstyleditemdelegate.h>
-#include <private/qabstractitemview_p.h>
-#include <private/qabstractitemmodel_p.h>
-#ifndef QT_NO_ACCESSIBILITY
-#include <qaccessible.h>
-#include <qaccessible2.h>
-#endif
-#include <private/qsoftkeymanager_p.h>
-#ifndef QT_NO_GESTURE
-# include <qscroller.h>
-#endif
-
-QT_BEGIN_NAMESPACE
-
-QAbstractItemViewPrivate::QAbstractItemViewPrivate()
- : model(QAbstractItemModelPrivate::staticEmptyModel()),
- itemDelegate(0),
- selectionModel(0),
- ctrlDragSelectionFlag(QItemSelectionModel::NoUpdate),
- noSelectionOnMousePress(false),
- selectionMode(QAbstractItemView::ExtendedSelection),
- selectionBehavior(QAbstractItemView::SelectItems),
- currentlyCommittingEditor(0),
- pressedModifiers(Qt::NoModifier),
- pressedPosition(QPoint(-1, -1)),
- pressedAlreadySelected(false),
- viewportEnteredNeeded(false),
- state(QAbstractItemView::NoState),
- stateBeforeAnimation(QAbstractItemView::NoState),
- editTriggers(QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed),
- lastTrigger(QAbstractItemView::NoEditTriggers),
- tabKeyNavigation(false),
-#ifndef QT_NO_DRAGANDDROP
- showDropIndicator(true),
- dragEnabled(false),
- dragDropMode(QAbstractItemView::NoDragDrop),
- overwrite(false),
- dropIndicatorPosition(QAbstractItemView::OnItem),
- defaultDropAction(Qt::IgnoreAction),
-#endif
-#ifdef QT_SOFTKEYS_ENABLED
- doneSoftKey(0),
-#endif
- autoScroll(true),
- autoScrollMargin(16),
- autoScrollCount(0),
- shouldScrollToCurrentOnShow(false),
- shouldClearStatusTip(false),
- alternatingColors(false),
- textElideMode(Qt::ElideRight),
- verticalScrollMode(QAbstractItemView::ScrollPerItem),
- horizontalScrollMode(QAbstractItemView::ScrollPerItem),
- currentIndexSet(false),
- wrapItemText(false),
- delayedPendingLayout(true),
- moveCursorUpdatedView(false)
-{
- keyboardInputTime.invalidate();
-}
-
-QAbstractItemViewPrivate::~QAbstractItemViewPrivate()
-{
-}
-
-void QAbstractItemViewPrivate::init()
-{
- Q_Q(QAbstractItemView);
- q->setItemDelegate(new QStyledItemDelegate(q));
-
- vbar->setRange(0, 0);
- hbar->setRange(0, 0);
-
- QObject::connect(vbar, SIGNAL(actionTriggered(int)),
- q, SLOT(verticalScrollbarAction(int)));
- QObject::connect(hbar, SIGNAL(actionTriggered(int)),
- q, SLOT(horizontalScrollbarAction(int)));
- QObject::connect(vbar, SIGNAL(valueChanged(int)),
- q, SLOT(verticalScrollbarValueChanged(int)));
- QObject::connect(hbar, SIGNAL(valueChanged(int)),
- q, SLOT(horizontalScrollbarValueChanged(int)));
-
- viewport->setBackgroundRole(QPalette::Base);
-
- q->setAttribute(Qt::WA_InputMethodEnabled);
-
-#ifdef QT_SOFTKEYS_ENABLED
- doneSoftKey = QSoftKeyManager::createKeyedAction(QSoftKeyManager::DoneSoftKey, Qt::Key_Back, q);
-#endif
-}
-
-void QAbstractItemViewPrivate::setHoverIndex(const QPersistentModelIndex &index)
-{
- Q_Q(QAbstractItemView);
- if (hover == index)
- return;
-
- if (selectionBehavior != QAbstractItemView::SelectRows) {
- q->update(hover); //update the old one
- q->update(index); //update the new one
- } else {
- QRect oldHoverRect = q->visualRect(hover);
- QRect newHoverRect = q->visualRect(index);
- viewport->update(QRect(0, newHoverRect.y(), viewport->width(), newHoverRect.height()));
- viewport->update(QRect(0, oldHoverRect.y(), viewport->width(), oldHoverRect.height()));
- }
- hover = index;
-}
-
-void QAbstractItemViewPrivate::checkMouseMove(const QPersistentModelIndex &index)
-{
- //we take a persistent model index because the model might change by emitting signals
- Q_Q(QAbstractItemView);
- setHoverIndex(index);
- if (viewportEnteredNeeded || enteredIndex != index) {
- viewportEnteredNeeded = false;
-
- if (index.isValid()) {
- emit q->entered(index);
-#ifndef QT_NO_STATUSTIP
- QString statustip = model->data(index, Qt::StatusTipRole).toString();
- if (parent && (shouldClearStatusTip || !statustip.isEmpty())) {
- QStatusTipEvent tip(statustip);
- QApplication::sendEvent(parent, &tip);
- shouldClearStatusTip = !statustip.isEmpty();
- }
-#endif
- } else {
-#ifndef QT_NO_STATUSTIP
- if (parent && shouldClearStatusTip) {
- QString emptyString;
- QStatusTipEvent tip( emptyString );
- QApplication::sendEvent(parent, &tip);
- }
-#endif
- emit q->viewportEntered();
- }
- enteredIndex = index;
- }
-}
-
-#ifndef QT_NO_GESTURES
-
-// stores and restores the selection and current item when flicking
-void QAbstractItemViewPrivate::_q_scrollerStateChanged()
-{
- Q_Q(QAbstractItemView);
-
- if (QScroller *scroller = QScroller::scroller(viewport)) {
- switch (scroller->state()) {
- case QScroller::Pressed:
- // store the current selection in case we start scrolling
- if (q->selectionModel()) {
- oldSelection = q->selectionModel()->selection();
- oldCurrent = q->selectionModel()->currentIndex();
- }
- break;
-
- case QScroller::Dragging:
- // restore the old selection if we really start scrolling
- if (q->selectionModel()) {
- q->selectionModel()->select(oldSelection, QItemSelectionModel::ClearAndSelect);
- q->selectionModel()->setCurrentIndex(oldCurrent, QItemSelectionModel::NoUpdate);
- }
- // fall through
-
- default:
- oldSelection = QItemSelection();
- oldCurrent = QModelIndex();
- break;
- }
- }
-}
-
-#endif // QT_NO_GESTURES
-
-/*!
- \class QAbstractItemView
-
- \brief The QAbstractItemView class provides the basic functionality for
- item view classes.
-
- \ingroup model-view
-
-
- QAbstractItemView class is the base class for every standard view
- that uses a QAbstractItemModel. QAbstractItemView is an abstract
- class and cannot itself be instantiated. It provides a standard
- interface for interoperating with models through the signals and
- slots mechanism, enabling subclasses to be kept up-to-date with
- changes to their models. This class provides standard support for
- keyboard and mouse navigation, viewport scrolling, item editing,
- and selections. The keyboard navigation implements this
- functionality:
-
- \table
- \header
- \o Keys
- \o Functionality
- \row
- \o Arrow keys
- \o Changes the current item and selects it.
- \row
- \o Ctrl+Arrow keys
- \o Changes the current item but does not select it.
- \row
- \o Shift+Arrow keys
- \o Changes the current item and selects it. The previously
- selected item(s) is not deselected.
- \row
- \o Ctr+Space
- \o Toggles selection of the current item.
- \row
- \o Tab/Backtab
- \o Changes the current item to the next/previous item.
- \row
- \o Home/End
- \o Selects the first/last item in the model.
- \row
- \o Page up/Page down
- \o Scrolls the rows shown up/down by the number of
- visible rows in the view.
- \row
- \o Ctrl+A
- \o Selects all items in the model.
- \endtable
-
- Note that the above table assumes that the
- \l{selectionMode}{selection mode} allows the operations. For
- instance, you cannot select items if the selection mode is
- QAbstractItemView::NoSelection.
-
- The QAbstractItemView class is one of the \l{Model/View Classes}
- and is part of Qt's \l{Model/View Programming}{model/view framework}.
-
- The view classes that inherit QAbstractItemView only need
- to implement their own view-specific functionality, such as
- drawing items, returning the geometry of items, finding items,
- etc.
-
- QAbstractItemView provides common slots such as edit() and
- setCurrentIndex(). Many protected slots are also provided, including
- dataChanged(), rowsInserted(), rowsAboutToBeRemoved(), selectionChanged(),
- and currentChanged().
-
- The root item is returned by rootIndex(), and the current item by
- currentIndex(). To make sure that an item is visible use
- scrollTo().
-
- Some of QAbstractItemView's functions are concerned with
- scrolling, for example setHorizontalScrollMode() and
- setVerticalScrollMode(). To set the range of the scroll bars, you
- can, for example, reimplement the view's resizeEvent() function:
-
- \snippet doc/src/snippets/code/src_gui_itemviews_qabstractitemview.cpp 0
-
- Note that the range is not updated until the widget is shown.
-
- Several other functions are concerned with selection control; for
- example setSelectionMode(), and setSelectionBehavior(). This class
- provides a default selection model to work with
- (selectionModel()), but this can be replaced by using
- setSelectionModel() with an instance of QItemSelectionModel.
-
- For complete control over the display and editing of items you can
- specify a delegate with setItemDelegate().
-
- QAbstractItemView provides a lot of protected functions. Some are
- concerned with editing, for example, edit(), and commitData(),
- whilst others are keyboard and mouse event handlers.
-
- \note If you inherit QAbstractItemView and intend to update the contents
- of the viewport, you should use viewport->update() instead of
- \l{QWidget::update()}{update()} as all painting operations take place on the
- viewport.
-
- \sa {View Classes}, {Model/View Programming}, QAbstractItemModel, {Chart Example}
-*/
-
-/*!
- \enum QAbstractItemView::SelectionMode
-
- This enum indicates how the view responds to user selections:
-
- \value SingleSelection When the user selects an item, any already-selected
- item becomes unselected, and the user cannot unselect the selected item by
- clicking on it.
-
- \value ContiguousSelection When the user selects an item in the usual way,
- the selection is cleared and the new item selected. However, if the user
- presses the Shift key while clicking on an item, all items between the
- current item and the clicked item are selected or unselected, depending on
- the state of the clicked item.
-
- \value ExtendedSelection When the user selects an item in the usual way,
- the selection is cleared and the new item selected. However, if the user
- presses the Ctrl key when clicking on an item, the clicked item gets
- toggled and all other items are left untouched. If the user presses the
- Shift key while clicking on an item, all items between the current item
- and the clicked item are selected or unselected, depending on the state of
- the clicked item. Multiple items can be selected by dragging the mouse over
- them.
-
- \value MultiSelection When the user selects an item in the usual way, the
- selection status of that item is toggled and the other items are left
- alone. Multiple items can be toggled by dragging the mouse over them.
-
- \value NoSelection Items cannot be selected.
-
- The most commonly used modes are SingleSelection and ExtendedSelection.
-*/
-
-/*!
- \enum QAbstractItemView::SelectionBehavior
-
- \value SelectItems Selecting single items.
- \value SelectRows Selecting only rows.
- \value SelectColumns Selecting only columns.
-*/
-
-/*!
- \enum QAbstractItemView::ScrollHint
-
- \value EnsureVisible Scroll to ensure that the item is visible.
- \value PositionAtTop Scroll to position the item at the top of the
- viewport.
- \value PositionAtBottom Scroll to position the item at the bottom of the
- viewport.
- \value PositionAtCenter Scroll to position the item at the center of the
- viewport.
-*/
-
-
-/*!
- \enum QAbstractItemView::EditTrigger
-
- This enum describes actions which will initiate item editing.
-
- \value NoEditTriggers No editing possible.
- \value CurrentChanged Editing start whenever current item changes.
- \value DoubleClicked Editing starts when an item is double clicked.
- \value SelectedClicked Editing starts when clicking on an already selected
- item.
- \value EditKeyPressed Editing starts when the platform edit key has been
- pressed over an item.
- \value AnyKeyPressed Editing starts when any key is pressed over an item.
- \value AllEditTriggers Editing starts for all above actions.
-*/
-
-/*!
- \enum QAbstractItemView::CursorAction
-
- This enum describes the different ways to navigate between items,
- \sa moveCursor()
-
- \value MoveUp Move to the item above the current item.
- \value MoveDown Move to the item below the current item.
- \value MoveLeft Move to the item left of the current item.
- \value MoveRight Move to the item right of the current item.
- \value MoveHome Move to the top-left corner item.
- \value MoveEnd Move to the bottom-right corner item.
- \value MovePageUp Move one page up above the current item.
- \value MovePageDown Move one page down below the current item.
- \value MoveNext Move to the item after the current item.
- \value MovePrevious Move to the item before the current item.
-*/
-
-/*!
- \enum QAbstractItemView::State
-
- Describes the different states the view can be in. This is usually
- only interesting when reimplementing your own view.
-
- \value NoState The is the default state.
- \value DraggingState The user is dragging items.
- \value DragSelectingState The user is selecting items.
- \value EditingState The user is editing an item in a widget editor.
- \value ExpandingState The user is opening a branch of items.
- \value CollapsingState The user is closing a branch of items.
- \value AnimatingState The item view is performing an animation.
-*/
-
-/*!
- \since 4.2
- \enum QAbstractItemView::ScrollMode
-
- \value ScrollPerItem The view will scroll the contents one item at a time.
- \value ScrollPerPixel The view will scroll the contents one pixel at a time.
-*/
-
-/*!
- \fn QRect QAbstractItemView::visualRect(const QModelIndex &index) const = 0
- Returns the rectangle on the viewport occupied by the item at \a index.
-
- If your item is displayed in several areas then visualRect should return
- the primary area that contains index and not the complete area that index
- might encompasses, touch or cause drawing.
-
- In the base class this is a pure virtual function.
-
- \sa indexAt(), visualRegionForSelection()
-*/
-
-/*!
- \fn void QAbstractItemView::scrollTo(const QModelIndex &index, ScrollHint hint) = 0
-
- Scrolls the view if necessary to ensure that the item at \a index
- is visible. The view will try to position the item according to the given \a hint.
-
- In the base class this is a pure virtual function.
-*/
-
-/*!
- \fn QModelIndex QAbstractItemView::indexAt(const QPoint &point) const = 0
-
- Returns the model index of the item at the viewport coordinates \a point.
-
- In the base class this is a pure virtual function.
-
- \sa visualRect()
-*/
-
-/*!
- \fn void QAbstractItemView::activated(const QModelIndex &index)
-
- This signal is emitted when the item specified by \a index is
- activated by the user. How to activate items depends on the
- platform; e.g., by single- or double-clicking the item, or by
- pressing the Return or Enter key when the item is current.
-
- \sa clicked(), doubleClicked(), entered(), pressed()
-*/
-
-/*!
- \fn void QAbstractItemView::entered(const QModelIndex &index)
-
- This signal is emitted when the mouse cursor enters the item
- specified by \a index.
- Mouse tracking needs to be enabled for this feature to work.
-
- \sa viewportEntered(), activated(), clicked(), doubleClicked(), pressed()
-*/
-
-/*!
- \fn void QAbstractItemView::viewportEntered()
-
- This signal is emitted when the mouse cursor enters the viewport.
- Mouse tracking needs to be enabled for this feature to work.
-
- \sa entered()
-*/
-
-/*!
- \fn void QAbstractItemView::pressed(const QModelIndex &index)
-
- This signal is emitted when a mouse button is pressed. The item
- the mouse was pressed on is specified by \a index. The signal is
- only emitted when the index is valid.
-
- Use the QApplication::mouseButtons() function to get the state
- of the mouse buttons.
-
- \sa activated(), clicked(), doubleClicked(), entered()
-*/
-
-/*!
- \fn void QAbstractItemView::clicked(const QModelIndex &index)
-
- This signal is emitted when a mouse button is clicked. The item
- the mouse was clicked on is specified by \a index. The signal is
- only emitted when the index is valid.
-
- \sa activated(), doubleClicked(), entered(), pressed()
-*/
-
-/*!
- \fn void QAbstractItemView::doubleClicked(const QModelIndex &index)
-
- This signal is emitted when a mouse button is double-clicked. The
- item the mouse was double-clicked on is specified by \a index.
- The signal is only emitted when the index is valid.
-
- \sa clicked(), activated()
-*/
-
-/*!
- \fn QModelIndex QAbstractItemView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers) = 0
-
- Returns a QModelIndex object pointing to the next object in the view,
- based on the given \a cursorAction and keyboard modifiers specified
- by \a modifiers.
-
- In the base class this is a pure virtual function.
-*/
-
-/*!
- \fn int QAbstractItemView::horizontalOffset() const = 0
-
- Returns the horizontal offset of the view.
-
- In the base class this is a pure virtual function.
-
- \sa verticalOffset()
-*/
-
-/*!
- \fn int QAbstractItemView::verticalOffset() const = 0
-
- Returns the vertical offset of the view.
-
- In the base class this is a pure virtual function.
-
- \sa horizontalOffset()
-*/
-
-/*!
- \fn bool QAbstractItemView::isIndexHidden(const QModelIndex &index) const
-
- Returns true if the item referred to by the given \a index is hidden in the view,
- otherwise returns false.
-
- Hiding is a view specific feature. For example in TableView a column can be marked
- as hidden or a row in the TreeView.
-
- In the base class this is a pure virtual function.
-*/
-
-/*!
- \fn void QAbstractItemView::setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags flags)
-
- Applies the selection \a flags to the items in or touched by the
- rectangle, \a rect.
-
- When implementing your own itemview setSelection should call
- selectionModel()->select(selection, flags) where selection
- is either an empty QModelIndex or a QItemSelection that contains
- all items that are contained in \a rect.
-
- \sa selectionCommand(), selectedIndexes()
-*/
-
-/*!
- \fn QRegion QAbstractItemView::visualRegionForSelection(const QItemSelection &selection) const = 0
-
- Returns the region from the viewport of the items in the given
- \a selection.
-
- In the base class this is a pure virtual function.
-
- \sa visualRect(), selectedIndexes()
-*/
-
-/*!
- \fn void QAbstractItemView::update()
- \internal
-*/
-
-/*!
- Constructs an abstract item view with the given \a parent.
-*/
-QAbstractItemView::QAbstractItemView(QWidget *parent)
- : QAbstractScrollArea(*(new QAbstractItemViewPrivate), parent)
-{
- d_func()->init();
-}
-
-/*!
- \internal
-*/
-QAbstractItemView::QAbstractItemView(QAbstractItemViewPrivate &dd, QWidget *parent)
- : QAbstractScrollArea(dd, parent)
-{
- d_func()->init();
-}
-
-/*!
- Destroys the view.
-*/
-QAbstractItemView::~QAbstractItemView()
-{
- Q_D(QAbstractItemView);
- // stop these timers here before ~QObject
- d->delayedReset.stop();
- d->updateTimer.stop();
- d->delayedEditing.stop();
- d->delayedAutoScroll.stop();
- d->autoScrollTimer.stop();
- d->delayedLayout.stop();
- d->fetchMoreTimer.stop();
-}
-
-/*!
- Sets the \a model for the view to present.
-
- This function will create and set a new selection model, replacing any
- model that was previously set with setSelectionModel(). However, the old
- selection model will not be deleted as it may be shared between several
- views. We recommend that you delete the old selection model if it is no
- longer required. This is done with the following code:
-
- \snippet doc/src/snippets/code/src_gui_itemviews_qabstractitemview.cpp 2
-
- If both the old model and the old selection model do not have parents, or
- if their parents are long-lived objects, it may be preferable to call their
- deleteLater() functions to explicitly delete them.
-
- The view \e{does not} take ownership of the model unless it is the model's
- parent object because the model may be shared between many different views.
-
- \sa selectionModel(), setSelectionModel()
-*/
-void QAbstractItemView::setModel(QAbstractItemModel *model)
-{
- Q_D(QAbstractItemView);
- if (model == d->model)
- return;
- if (d->model && d->model != QAbstractItemModelPrivate::staticEmptyModel()) {
- disconnect(d->model, SIGNAL(destroyed()),
- this, SLOT(_q_modelDestroyed()));
- disconnect(d->model, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
- this, SLOT(dataChanged(QModelIndex,QModelIndex)));
- disconnect(d->model, SIGNAL(headerDataChanged(Qt::Orientation,int,int)),
- this, SLOT(_q_headerDataChanged()));
- disconnect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)),
- this, SLOT(rowsInserted(QModelIndex,int,int)));
- disconnect(d->model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
- this, SLOT(rowsAboutToBeRemoved(QModelIndex,int,int)));
- disconnect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
- this, SLOT(_q_rowsRemoved(QModelIndex,int,int)));
- disconnect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)),
- this, SLOT(_q_rowsInserted(QModelIndex,int,int)));
- disconnect(d->model, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)),
- this, SLOT(_q_columnsAboutToBeRemoved(QModelIndex,int,int)));
- disconnect(d->model, SIGNAL(columnsRemoved(QModelIndex,int,int)),
- this, SLOT(_q_columnsRemoved(QModelIndex,int,int)));
- disconnect(d->model, SIGNAL(columnsInserted(QModelIndex,int,int)),
- this, SLOT(_q_columnsInserted(QModelIndex,int,int)));
-
- disconnect(d->model, SIGNAL(modelReset()), this, SLOT(reset()));
- disconnect(d->model, SIGNAL(layoutChanged()), this, SLOT(_q_layoutChanged()));
- }
- d->model = (model ? model : QAbstractItemModelPrivate::staticEmptyModel());
-
- // These asserts do basic sanity checking of the model
- Q_ASSERT_X(d->model->index(0,0) == d->model->index(0,0),
- "QAbstractItemView::setModel",
- "A model should return the exact same index "
- "(including its internal id/pointer) when asked for it twice in a row.");
- Q_ASSERT_X(!d->model->index(0,0).parent().isValid(),
- "QAbstractItemView::setModel",
- "The parent of a top level index should be invalid");
-
- if (d->model != QAbstractItemModelPrivate::staticEmptyModel()) {
- connect(d->model, SIGNAL(destroyed()),
- this, SLOT(_q_modelDestroyed()));
- connect(d->model, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
- this, SLOT(dataChanged(QModelIndex,QModelIndex)));
- connect(d->model, SIGNAL(headerDataChanged(Qt::Orientation,int,int)),
- this, SLOT(_q_headerDataChanged()));
- connect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)),
- this, SLOT(rowsInserted(QModelIndex,int,int)));
- connect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)),
- this, SLOT(_q_rowsInserted(QModelIndex,int,int)));
- connect(d->model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
- this, SLOT(rowsAboutToBeRemoved(QModelIndex,int,int)));
- connect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
- this, SLOT(_q_rowsRemoved(QModelIndex,int,int)));
- connect(d->model, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)),
- this, SLOT(_q_columnsAboutToBeRemoved(QModelIndex,int,int)));
- connect(d->model, SIGNAL(columnsRemoved(QModelIndex,int,int)),
- this, SLOT(_q_columnsRemoved(QModelIndex,int,int)));
- connect(d->model, SIGNAL(columnsInserted(QModelIndex,int,int)),
- this, SLOT(_q_columnsInserted(QModelIndex,int,int)));
-
- connect(d->model, SIGNAL(modelReset()), this, SLOT(reset()));
- connect(d->model, SIGNAL(layoutChanged()), this, SLOT(_q_layoutChanged()));
- }
-
- QItemSelectionModel *selection_model = new QItemSelectionModel(d->model, this);
- connect(d->model, SIGNAL(destroyed()), selection_model, SLOT(deleteLater()));
- setSelectionModel(selection_model);
-
- reset(); // kill editors, set new root and do layout
-}
-
-/*!
- Returns the model that this view is presenting.
-*/
-QAbstractItemModel *QAbstractItemView::model() const
-{
- Q_D(const QAbstractItemView);
- return (d->model == QAbstractItemModelPrivate::staticEmptyModel() ? 0 : d->model);
-}
-
-/*!
- Sets the current selection model to the given \a selectionModel.
-
- Note that, if you call setModel() after this function, the given \a selectionModel
- will be replaced by one created by the view.
-
- \note It is up to the application to delete the old selection model if it is no
- longer needed; i.e., if it is not being used by other views. This will happen
- automatically when its parent object is deleted. However, if it does not have a
- parent, or if the parent is a long-lived object, it may be preferable to call its
- deleteLater() function to explicitly delete it.
-
- \sa selectionModel(), setModel(), clearSelection()
-*/
-void QAbstractItemView::setSelectionModel(QItemSelectionModel *selectionModel)
-{
- // ### if the given model is null, we should use the original selection model
- Q_ASSERT(selectionModel);
- Q_D(QAbstractItemView);
-
- if (selectionModel->model() != d->model) {
- qWarning("QAbstractItemView::setSelectionModel() failed: "
- "Trying to set a selection model, which works on "
- "a different model than the view.");
- return;
- }
-
- if (d->selectionModel) {
- disconnect(d->selectionModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
- this, SLOT(selectionChanged(QItemSelection,QItemSelection)));
- disconnect(d->selectionModel, SIGNAL(currentChanged(QModelIndex,QModelIndex)),
- this, SLOT(currentChanged(QModelIndex,QModelIndex)));
- }
-
- d->selectionModel = selectionModel;
-
- if (d->selectionModel) {
- connect(d->selectionModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
- this, SLOT(selectionChanged(QItemSelection,QItemSelection)));
- connect(d->selectionModel, SIGNAL(currentChanged(QModelIndex,QModelIndex)),
- this, SLOT(currentChanged(QModelIndex,QModelIndex)));
- }
-}
-
-/*!
- Returns the current selection model.
-
- \sa setSelectionModel(), selectedIndexes()
-*/
-QItemSelectionModel* QAbstractItemView::selectionModel() const
-{
- Q_D(const QAbstractItemView);
- return d->selectionModel;
-}
-
-/*!
- Sets the item delegate for this view and its model to \a delegate.
- This is useful if you want complete control over the editing and
- display of items.
-
- Any existing delegate will be removed, but not deleted. QAbstractItemView
- does not take ownership of \a delegate.
-
- \warning You should not share the same instance of a delegate between views.
- Doing so can cause incorrect or unintuitive editing behavior since each
- view connected to a given delegate may receive the \l{QAbstractItemDelegate::}{closeEditor()}
- signal, and attempt to access, modify or close an editor that has already been closed.
-
- \sa itemDelegate()
-*/
-void QAbstractItemView::setItemDelegate(QAbstractItemDelegate *delegate)
-{
- Q_D(QAbstractItemView);
- if (delegate == d->itemDelegate)
- return;
-
- if (d->itemDelegate) {
- if (d->delegateRefCount(d->itemDelegate) == 1) {
- disconnect(d->itemDelegate, SIGNAL(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)),
- this, SLOT(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)));
- disconnect(d->itemDelegate, SIGNAL(commitData(QWidget*)), this, SLOT(commitData(QWidget*)));
- disconnect(d->itemDelegate, SIGNAL(sizeHintChanged(QModelIndex)), this, SLOT(doItemsLayout()));
- }
- }
-
- if (delegate) {
- if (d->delegateRefCount(delegate) == 0) {
- connect(delegate, SIGNAL(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)),
- this, SLOT(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)));
- connect(delegate, SIGNAL(commitData(QWidget*)), this, SLOT(commitData(QWidget*)));
- qRegisterMetaType<QModelIndex>("QModelIndex");
- connect(delegate, SIGNAL(sizeHintChanged(QModelIndex)), this, SLOT(doItemsLayout()), Qt::QueuedConnection);
- }
- }
- d->itemDelegate = delegate;
- viewport()->update();
-}
-
-/*!
- Returns the item delegate used by this view and model. This is
- either one set with setItemDelegate(), or the default one.
-
- \sa setItemDelegate()
-*/
-QAbstractItemDelegate *QAbstractItemView::itemDelegate() const
-{
- return d_func()->itemDelegate;
-}
-
-/*!
- \reimp
-*/
-QVariant QAbstractItemView::inputMethodQuery(Qt::InputMethodQuery query) const
-{
- const QModelIndex current = currentIndex();
- if (!current.isValid() || query != Qt::ImMicroFocus)
- return QAbstractScrollArea::inputMethodQuery(query);
- return visualRect(current);
-}
-
-/*!
- \since 4.2
-
- Sets the given item \a delegate used by this view and model for the given
- \a row. All items on \a row will be drawn and managed by \a delegate
- instead of using the default delegate (i.e., itemDelegate()).
-
- Any existing row delegate for \a row will be removed, but not
- deleted. QAbstractItemView does not take ownership of \a delegate.
-
- \note If a delegate has been assigned to both a row and a column, the row
- delegate (i.e., this delegate) will take precedence and manage the
- intersecting cell index.
-
- \warning You should not share the same instance of a delegate between views.
- Doing so can cause incorrect or unintuitive editing behavior since each
- view connected to a given delegate may receive the \l{QAbstractItemDelegate::}{closeEditor()}
- signal, and attempt to access, modify or close an editor that has already been closed.
-
- \sa itemDelegateForRow(), setItemDelegateForColumn(), itemDelegate()
-*/
-void QAbstractItemView::setItemDelegateForRow(int row, QAbstractItemDelegate *delegate)
-{
- Q_D(QAbstractItemView);
- if (QAbstractItemDelegate *rowDelegate = d->rowDelegates.value(row, 0)) {
- if (d->delegateRefCount(rowDelegate) == 1) {
- disconnect(rowDelegate, SIGNAL(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)),
- this, SLOT(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)));
- disconnect(rowDelegate, SIGNAL(commitData(QWidget*)), this, SLOT(commitData(QWidget*)));
- }
- d->rowDelegates.remove(row);
- }
- if (delegate) {
- if (d->delegateRefCount(delegate) == 0) {
- connect(delegate, SIGNAL(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)),
- this, SLOT(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)));
- connect(delegate, SIGNAL(commitData(QWidget*)), this, SLOT(commitData(QWidget*)));
- }
- d->rowDelegates.insert(row, delegate);
- }
- viewport()->update();
-}
-
-/*!
- \since 4.2
-
- Returns the item delegate used by this view and model for the given \a row,
- or 0 if no delegate has been assigned. You can call itemDelegate() to get a
- pointer to the current delegate for a given index.
-
- \sa setItemDelegateForRow(), itemDelegateForColumn(), setItemDelegate()
-*/
-QAbstractItemDelegate *QAbstractItemView::itemDelegateForRow(int row) const
-{
- Q_D(const QAbstractItemView);
- return d->rowDelegates.value(row, 0);
-}
-
-/*!
- \since 4.2
-
- Sets the given item \a delegate used by this view and model for the given
- \a column. All items on \a column will be drawn and managed by \a delegate
- instead of using the default delegate (i.e., itemDelegate()).
-
- Any existing column delegate for \a column will be removed, but not
- deleted. QAbstractItemView does not take ownership of \a delegate.
-
- \note If a delegate has been assigned to both a row and a column, the row
- delegate will take precedence and manage the intersecting cell index.
-
- \warning You should not share the same instance of a delegate between views.
- Doing so can cause incorrect or unintuitive editing behavior since each
- view connected to a given delegate may receive the \l{QAbstractItemDelegate::}{closeEditor()}
- signal, and attempt to access, modify or close an editor that has already been closed.
-
- \sa itemDelegateForColumn(), setItemDelegateForRow(), itemDelegate()
-*/
-void QAbstractItemView::setItemDelegateForColumn(int column, QAbstractItemDelegate *delegate)
-{
- Q_D(QAbstractItemView);
- if (QAbstractItemDelegate *columnDelegate = d->columnDelegates.value(column, 0)) {
- if (d->delegateRefCount(columnDelegate) == 1) {
- disconnect(columnDelegate, SIGNAL(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)),
- this, SLOT(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)));
- disconnect(columnDelegate, SIGNAL(commitData(QWidget*)), this, SLOT(commitData(QWidget*)));
- }
- d->columnDelegates.remove(column);
- }
- if (delegate) {
- if (d->delegateRefCount(delegate) == 0) {
- connect(delegate, SIGNAL(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)),
- this, SLOT(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)));
- connect(delegate, SIGNAL(commitData(QWidget*)), this, SLOT(commitData(QWidget*)));
- }
- d->columnDelegates.insert(column, delegate);
- }
- viewport()->update();
-}
-
-/*!
- \since 4.2
-
- Returns the item delegate used by this view and model for the given \a
- column. You can call itemDelegate() to get a pointer to the current delegate
- for a given index.
-
- \sa setItemDelegateForColumn(), itemDelegateForRow(), itemDelegate()
-*/
-QAbstractItemDelegate *QAbstractItemView::itemDelegateForColumn(int column) const
-{
- Q_D(const QAbstractItemView);
- return d->columnDelegates.value(column, 0);
-}
-
-/*!
- Returns the item delegate used by this view and model for
- the given \a index.
-*/
-QAbstractItemDelegate *QAbstractItemView::itemDelegate(const QModelIndex &index) const
-{
- Q_D(const QAbstractItemView);
- return d->delegateForIndex(index);
-}
-
-/*!
- \property QAbstractItemView::selectionMode
- \brief which selection mode the view operates in
-
- This property controls whether the user can select one or many items
- and, in many-item selections, whether the selection must be a
- continuous range of items.
-
- \sa SelectionMode SelectionBehavior
-*/
-void QAbstractItemView::setSelectionMode(SelectionMode mode)
-{
- Q_D(QAbstractItemView);
- d->selectionMode = mode;
-}
-
-QAbstractItemView::SelectionMode QAbstractItemView::selectionMode() const
-{
- Q_D(const QAbstractItemView);
- return d->selectionMode;
-}
-
-/*!
- \property QAbstractItemView::selectionBehavior
- \brief which selection behavior the view uses
-
- This property holds whether selections are done
- in terms of single items, rows or columns.
-
- \sa SelectionMode SelectionBehavior
-*/
-
-void QAbstractItemView::setSelectionBehavior(QAbstractItemView::SelectionBehavior behavior)
-{
- Q_D(QAbstractItemView);
- d->selectionBehavior = behavior;
-}
-
-QAbstractItemView::SelectionBehavior QAbstractItemView::selectionBehavior() const
-{
- Q_D(const QAbstractItemView);
- return d->selectionBehavior;
-}
-
-/*!
- Sets the current item to be the item at \a index.
-
- Unless the current selection mode is
- \l{QAbstractItemView::}{NoSelection}, the item is also be selected.
- Note that this function also updates the starting position for any
- new selections the user performs.
-
- To set an item as the current item without selecting it, call
-
- \c{selectionModel()->setCurrentIndex(index, QItemSelectionModel::NoUpdate);}
-
- \sa currentIndex(), currentChanged(), selectionMode
-*/
-void QAbstractItemView::setCurrentIndex(const QModelIndex &index)
-{
- Q_D(QAbstractItemView);
- if (d->selectionModel && (!index.isValid() || d->isIndexEnabled(index))) {
- QItemSelectionModel::SelectionFlags command = selectionCommand(index, 0);
- d->selectionModel->setCurrentIndex(index, command);
- d->currentIndexSet = true;
- if ((command & QItemSelectionModel::Current) == 0)
- d->pressedPosition = visualRect(currentIndex()).center() + d->offset();
- }
-}
-
-/*!
- Returns the model index of the current item.
-
- \sa setCurrentIndex()
-*/
-QModelIndex QAbstractItemView::currentIndex() const
-{
- Q_D(const QAbstractItemView);
- return d->selectionModel ? d->selectionModel->currentIndex() : QModelIndex();
-}
-
-
-/*!
- Reset the internal state of the view.
-
- \warning This function will reset open editors, scroll bar positions,
- selections, etc. Existing changes will not be committed. If you would like
- to save your changes when resetting the view, you can reimplement this
- function, commit your changes, and then call the superclass'
- implementation.
-*/
-void QAbstractItemView::reset()
-{
- Q_D(QAbstractItemView);
- d->delayedReset.stop(); //make sure we stop the timer
- foreach (const QEditorInfo &info, d->indexEditorHash) {
- if (info.widget)
- d->releaseEditor(info.widget.data());
- }
- d->editorIndexHash.clear();
- d->indexEditorHash.clear();
- d->persistent.clear();
- d->currentIndexSet = false;
- setState(NoState);
- setRootIndex(QModelIndex());
- if (d->selectionModel)
- d->selectionModel->reset();
-#ifndef QT_NO_ACCESSIBILITY
-#ifdef Q_WS_X11
- if (QAccessible::isActive()) {
- QAccessible::queryAccessibleInterface(this)->table2Interface()->modelReset();
- QAccessible::updateAccessibility(this, 0, QAccessible::TableModelChanged);
- }
-#endif
-#endif
-}
-
-/*!
- Sets the root item to the item at the given \a index.
-
- \sa rootIndex()
-*/
-void QAbstractItemView::setRootIndex(const QModelIndex &index)
-{
- Q_D(QAbstractItemView);
- if (index.isValid() && index.model() != d->model) {
- qWarning("QAbstractItemView::setRootIndex failed : index must be from the currently set model");
- return;
- }
- d->root = index;
- d->doDelayedItemsLayout();
-}
-
-/*!
- Returns the model index of the model's root item. The root item is
- the parent item to the view's toplevel items. The root can be invalid.
-
- \sa setRootIndex()
-*/
-QModelIndex QAbstractItemView::rootIndex() const
-{
- return QModelIndex(d_func()->root);
-}
-
-/*!
- Selects all items in the view.
- This function will use the selection behavior
- set on the view when selecting.
-
- \sa setSelection(), selectedIndexes(), clearSelection()
-*/
-void QAbstractItemView::selectAll()
-{
- Q_D(QAbstractItemView);
- SelectionMode mode = d->selectionMode;
- if (mode == MultiSelection || mode == ExtendedSelection)
- d->selectAll(QItemSelectionModel::ClearAndSelect
- |d->selectionBehaviorFlags());
- else if (mode != SingleSelection)
- d->selectAll(selectionCommand(d->model->index(0, 0, d->root)));
-}
-
-/*!
- Starts editing the item corresponding to the given \a index if it is
- editable.
-
- Note that this function does not change the current index. Since the current
- index defines the next and previous items to edit, users may find that
- keyboard navigation does not work as expected. To provide consistent navigation
- behavior, call setCurrentIndex() before this function with the same model
- index.
-
- \sa QModelIndex::flags()
-*/
-void QAbstractItemView::edit(const QModelIndex &index)
-{
- Q_D(QAbstractItemView);
- if (!d->isIndexValid(index))
- qWarning("edit: index was invalid");
- if (!edit(index, AllEditTriggers, 0))
- qWarning("edit: editing failed");
-}
-
-/*!
- Deselects all selected items. The current index will not be changed.
-
- \sa setSelection(), selectAll()
-*/
-void QAbstractItemView::clearSelection()
-{
- Q_D(QAbstractItemView);
- if (d->selectionModel)
- d->selectionModel->clearSelection();
-}
-
-/*!
- \internal
-
- This function is intended to lay out the items in the view.
- The default implementation just calls updateGeometries() and updates the viewport.
-*/
-void QAbstractItemView::doItemsLayout()
-{
- Q_D(QAbstractItemView);
- d->interruptDelayedItemsLayout();
- updateGeometries();
- d->viewport->update();
-}
-
-/*!
- \property QAbstractItemView::editTriggers
- \brief which actions will initiate item editing
-
- This property is a selection of flags defined by
- \l{EditTrigger}, combined using the OR
- operator. The view will only initiate the editing of an item if the
- action performed is set in this property.
-*/
-void QAbstractItemView::setEditTriggers(EditTriggers actions)
-{
- Q_D(QAbstractItemView);
- d->editTriggers = actions;
-}
-
-QAbstractItemView::EditTriggers QAbstractItemView::editTriggers() const
-{
- Q_D(const QAbstractItemView);
- return d->editTriggers;
-}
-
-/*!
- \since 4.2
- \property QAbstractItemView::verticalScrollMode
- \brief how the view scrolls its contents in the vertical direction
-
- This property controls how the view scroll its contents vertically.
- Scrolling can be done either per pixel or per item.
-*/
-
-void QAbstractItemView::setVerticalScrollMode(ScrollMode mode)
-{
- Q_D(QAbstractItemView);
- if (mode == d->verticalScrollMode)
- return;
- QModelIndex topLeft = indexAt(QPoint(0, 0));
- d->verticalScrollMode = mode;
- updateGeometries(); // update the scroll bars
- scrollTo(topLeft, QAbstractItemView::PositionAtTop);
-}
-
-QAbstractItemView::ScrollMode QAbstractItemView::verticalScrollMode() const
-{
- Q_D(const QAbstractItemView);
- return d->verticalScrollMode;
-}
-
-/*!
- \since 4.2
- \property QAbstractItemView::horizontalScrollMode
- \brief how the view scrolls its contents in the horizontal direction
-
- This property controls how the view scroll its contents horizontally.
- Scrolling can be done either per pixel or per item.
-*/
-
-void QAbstractItemView::setHorizontalScrollMode(ScrollMode mode)
-{
- Q_D(QAbstractItemView);
- d->horizontalScrollMode = mode;
- updateGeometries(); // update the scroll bars
-}
-
-QAbstractItemView::ScrollMode QAbstractItemView::horizontalScrollMode() const
-{
- Q_D(const QAbstractItemView);
- return d->horizontalScrollMode;
-}
-
-#ifndef QT_NO_DRAGANDDROP
-/*!
- \since 4.2
- \property QAbstractItemView::dragDropOverwriteMode
- \brief the view's drag and drop behavior
-
- If its value is \c true, the selected data will overwrite the
- existing item data when dropped, while moving the data will clear
- the item. If its value is \c false, the selected data will be
- inserted as a new item when the data is dropped. When the data is
- moved, the item is removed as well.
-
- The default value is \c false, as in the QListView and QTreeView
- subclasses. In the QTableView subclass, on the other hand, the
- property has been set to \c true.
-
- Note: This is not intended to prevent overwriting of items.
- The model's implementation of flags() should do that by not
- returning Qt::ItemIsDropEnabled.
-
- \sa dragDropMode
-*/
-void QAbstractItemView::setDragDropOverwriteMode(bool overwrite)
-{
- Q_D(QAbstractItemView);
- d->overwrite = overwrite;
-}
-
-bool QAbstractItemView::dragDropOverwriteMode() const
-{
- Q_D(const QAbstractItemView);
- return d->overwrite;
-}
-#endif
-
-/*!
- \property QAbstractItemView::autoScroll
- \brief whether autoscrolling in drag move events is enabled
-
- If this property is set to true (the default), the
- QAbstractItemView automatically scrolls the contents of the view
- if the user drags within 16 pixels of the viewport edge. If the current
- item changes, then the view will scroll automatically to ensure that the
- current item is fully visible.
-
- This property only works if the viewport accepts drops. Autoscroll is
- switched off by setting this property to false.
-*/
-
-void QAbstractItemView::setAutoScroll(bool enable)
-{
- Q_D(QAbstractItemView);
- d->autoScroll = enable;
-}
-
-bool QAbstractItemView::hasAutoScroll() const
-{
- Q_D(const QAbstractItemView);
- return d->autoScroll;
-}
-
-/*!
- \since 4.4
- \property QAbstractItemView::autoScrollMargin
- \brief the size of the area when auto scrolling is triggered
-
- This property controls the size of the area at the edge of the viewport that
- triggers autoscrolling. The default value is 16 pixels.
-*/
-void QAbstractItemView::setAutoScrollMargin(int margin)
-{
- Q_D(QAbstractItemView);
- d->autoScrollMargin = margin;
-}
-
-int QAbstractItemView::autoScrollMargin() const
-{
- Q_D(const QAbstractItemView);
- return d->autoScrollMargin;
-}
-
-/*!
- \property QAbstractItemView::tabKeyNavigation
- \brief whether item navigation with tab and backtab is enabled.
-*/
-
-void QAbstractItemView::setTabKeyNavigation(bool enable)
-{
- Q_D(QAbstractItemView);
- d->tabKeyNavigation = enable;
-}
-
-bool QAbstractItemView::tabKeyNavigation() const
-{
- Q_D(const QAbstractItemView);
- return d->tabKeyNavigation;
-}
-
-#ifndef QT_NO_DRAGANDDROP
-/*!
- \property QAbstractItemView::showDropIndicator
- \brief whether the drop indicator is shown when dragging items and dropping.
-
- \sa dragEnabled DragDropMode dragDropOverwriteMode acceptDrops
-*/
-
-void QAbstractItemView::setDropIndicatorShown(bool enable)
-{
- Q_D(QAbstractItemView);
- d->showDropIndicator = enable;
-}
-
-bool QAbstractItemView::showDropIndicator() const
-{
- Q_D(const QAbstractItemView);
- return d->showDropIndicator;
-}
-
-/*!
- \property QAbstractItemView::dragEnabled
- \brief whether the view supports dragging of its own items
-
- \sa showDropIndicator DragDropMode dragDropOverwriteMode acceptDrops
-*/
-
-void QAbstractItemView::setDragEnabled(bool enable)
-{
- Q_D(QAbstractItemView);
- d->dragEnabled = enable;
-}
-
-bool QAbstractItemView::dragEnabled() const
-{
- Q_D(const QAbstractItemView);
- return d->dragEnabled;
-}
-
-/*!
- \since 4.2
- \enum QAbstractItemView::DragDropMode
-
- Describes the various drag and drop events the view can act upon.
- By default the view does not support dragging or dropping (\c
- NoDragDrop).
-
- \value NoDragDrop Does not support dragging or dropping.
- \value DragOnly The view supports dragging of its own items
- \value DropOnly The view accepts drops
- \value DragDrop The view supports both dragging and dropping
- \value InternalMove The view accepts move (\bold{not copy}) operations only
- from itself.
-
- Note that the model used needs to provide support for drag and drop operations.
-
- \sa setDragDropMode() {Using drag and drop with item views}
-*/
-
-/*!
- \property QAbstractItemView::dragDropMode
- \brief the drag and drop event the view will act upon
-
- \since 4.2
- \sa showDropIndicator dragDropOverwriteMode
-*/
-void QAbstractItemView::setDragDropMode(DragDropMode behavior)
-{
- Q_D(QAbstractItemView);
- d->dragDropMode = behavior;
- setDragEnabled(behavior == DragOnly || behavior == DragDrop || behavior == InternalMove);
- setAcceptDrops(behavior == DropOnly || behavior == DragDrop || behavior == InternalMove);
-}
-
-QAbstractItemView::DragDropMode QAbstractItemView::dragDropMode() const
-{
- Q_D(const QAbstractItemView);
- DragDropMode setBehavior = d->dragDropMode;
- if (!dragEnabled() && !acceptDrops())
- return NoDragDrop;
-
- if (dragEnabled() && !acceptDrops())
- return DragOnly;
-
- if (!dragEnabled() && acceptDrops())
- return DropOnly;
-
- if (dragEnabled() && acceptDrops()) {
- if (setBehavior == InternalMove)
- return setBehavior;
- else
- return DragDrop;
- }
-
- return NoDragDrop;
-}
-
-/*!
- \property QAbstractItemView::defaultDropAction
- \brief the drop action that will be used by default in QAbstractItemView::drag()
-
- If the property is not set, the drop action is CopyAction when the supported
- actions support CopyAction.
-
- \since 4.6
- \sa showDropIndicator dragDropOverwriteMode
-*/
-void QAbstractItemView::setDefaultDropAction(Qt::DropAction dropAction)
-{
- Q_D(QAbstractItemView);
- d->defaultDropAction = dropAction;
-}
-
-Qt::DropAction QAbstractItemView::defaultDropAction() const
-{
- Q_D(const QAbstractItemView);
- return d->defaultDropAction;
-}
-
-#endif // QT_NO_DRAGANDDROP
-
-/*!
- \property QAbstractItemView::alternatingRowColors
- \brief whether to draw the background using alternating colors
-
- If this property is true, the item background will be drawn using
- QPalette::Base and QPalette::AlternateBase; otherwise the background
- will be drawn using the QPalette::Base color.
-
- By default, this property is false.
-*/
-void QAbstractItemView::setAlternatingRowColors(bool enable)
-{
- Q_D(QAbstractItemView);
- d->alternatingColors = enable;
- if (isVisible())
- d->viewport->update();
-}
-
-bool QAbstractItemView::alternatingRowColors() const
-{
- Q_D(const QAbstractItemView);
- return d->alternatingColors;
-}
-
-/*!
- \property QAbstractItemView::iconSize
- \brief the size of items' icons
-
- Setting this property when the view is visible will cause the
- items to be laid out again.
-*/
-void QAbstractItemView::setIconSize(const QSize &size)
-{
- Q_D(QAbstractItemView);
- if (size == d->iconSize)
- return;
- d->iconSize = size;
- d->doDelayedItemsLayout();
-}
-
-QSize QAbstractItemView::iconSize() const
-{
- Q_D(const QAbstractItemView);
- return d->iconSize;
-}
-
-/*!
- \property QAbstractItemView::textElideMode
-
- \brief the position of the "..." in elided text.
-
- The default value for all item views is Qt::ElideRight.
-*/
-void QAbstractItemView::setTextElideMode(Qt::TextElideMode mode)
-{
- Q_D(QAbstractItemView);
- d->textElideMode = mode;
-}
-
-Qt::TextElideMode QAbstractItemView::textElideMode() const
-{
- return d_func()->textElideMode;
-}
-
-/*!
- \reimp
-*/
-bool QAbstractItemView::focusNextPrevChild(bool next)
-{
- Q_D(QAbstractItemView);
- if (d->tabKeyNavigation && isEnabled() && d->viewport->isEnabled()) {
- QKeyEvent event(QEvent::KeyPress, next ? Qt::Key_Tab : Qt::Key_Backtab, Qt::NoModifier);
- keyPressEvent(&event);
- if (event.isAccepted())
- return true;
- }
- return QAbstractScrollArea::focusNextPrevChild(next);
-}
-
-/*!
- \reimp
-*/
-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
- if (d->shouldScrollToCurrentOnShow) {
- d->shouldScrollToCurrentOnShow = false;
- const QModelIndex current = currentIndex();
- if (current.isValid() && (d->state == QAbstractItemView::EditingState || d->autoScroll))
- scrollTo(current);
- }
- break;
- case QEvent::LocaleChange:
- viewport()->update();
- break;
- case QEvent::LayoutDirectionChange:
- case QEvent::ApplicationLayoutDirectionChange:
- updateGeometries();
- break;
- case QEvent::StyleChange:
- doItemsLayout();
- break;
- case QEvent::FocusOut:
- d->checkPersistentEditorFocus();
- break;
- case QEvent::FontChange:
- d->doDelayedItemsLayout(); // the size of the items will change
- break;
-#ifdef QT_SOFTKEYS_ENABLED
- case QEvent::LanguageChange:
- d->doneSoftKey->setText(QSoftKeyManager::standardSoftKeyText(QSoftKeyManager::DoneSoftKey));
- break;
-#endif
- default:
- break;
- }
- return QAbstractScrollArea::event(event);
-}
-
-/*!
- \fn bool QAbstractItemView::viewportEvent(QEvent *event)
-
- This function is used to handle tool tips, and What's
- This? mode, if the given \a event is a QEvent::ToolTip,or a
- QEvent::WhatsThis. It passes all other
- events on to its base class viewportEvent() handler.
-*/
-bool QAbstractItemView::viewportEvent(QEvent *event)
-{
- Q_D(QAbstractItemView);
- switch (event->type()) {
- case QEvent::HoverMove:
- case QEvent::HoverEnter:
- d->setHoverIndex(indexAt(static_cast<QHoverEvent*>(event)->pos()));
- break;
- case QEvent::HoverLeave:
- d->setHoverIndex(QModelIndex());
- break;
- case QEvent::Enter:
- d->viewportEnteredNeeded = true;
- break;
- case QEvent::Leave:
- #ifndef QT_NO_STATUSTIP
- if (d->shouldClearStatusTip && d->parent) {
- QString empty;
- QStatusTipEvent tip(empty);
- QApplication::sendEvent(d->parent, &tip);
- d->shouldClearStatusTip = false;
- }
- #endif
- d->enteredIndex = QModelIndex();
- break;
- case QEvent::ToolTip:
- case QEvent::QueryWhatsThis:
- case QEvent::WhatsThis: {
- QHelpEvent *he = static_cast<QHelpEvent*>(event);
- const QModelIndex index = indexAt(he->pos());
- QStyleOptionViewItemV4 option = d->viewOptionsV4();
- option.rect = visualRect(index);
- option.state |= (index == currentIndex() ? QStyle::State_HasFocus : QStyle::State_None);
- bool retval = false;
- // ### Qt 5: make this a normal function call to a virtual function
- QMetaObject::invokeMethod(d->delegateForIndex(index), "helpEvent",
- Q_RETURN_ARG(bool, retval),
- Q_ARG(QHelpEvent *, he),
- Q_ARG(QAbstractItemView *, this),
- Q_ARG(QStyleOptionViewItem, option),
- Q_ARG(QModelIndex, index));
- return retval;
- }
- case QEvent::FontChange:
- d->doDelayedItemsLayout(); // the size of the items will change
- break;
- case QEvent::WindowActivate:
- case QEvent::WindowDeactivate:
- d->viewport->update();
- break;
- case QEvent::ScrollPrepare:
- executeDelayedItemsLayout();
-#ifndef QT_NO_GESTURES
- connect(QScroller::scroller(d->viewport), SIGNAL(stateChanged(QScroller::State)), this, SLOT(_q_scrollerStateChanged()), Qt::UniqueConnection);
-#endif
- break;
-
- default:
- break;
- }
- return QAbstractScrollArea::viewportEvent(event);
-}
-
-/*!
- This function is called with the given \a event when a mouse button is pressed
- while the cursor is inside the widget. If a valid item is pressed on it is made
- into the current item. This function emits the pressed() signal.
-*/
-void QAbstractItemView::mousePressEvent(QMouseEvent *event)
-{
- Q_D(QAbstractItemView);
- d->delayedAutoScroll.stop(); //any interaction with the view cancel the auto scrolling
- QPoint pos = event->pos();
- QPersistentModelIndex index = indexAt(pos);
-
- if (!d->selectionModel
- || (d->state == EditingState && d->hasEditor(index)))
- return;
-
- d->pressedAlreadySelected = d->selectionModel->isSelected(index);
- d->pressedIndex = index;
- d->pressedModifiers = event->modifiers();
- QItemSelectionModel::SelectionFlags command = selectionCommand(index, event);
- d->noSelectionOnMousePress = command == QItemSelectionModel::NoUpdate || !index.isValid();
- QPoint offset = d->offset();
- if ((command & QItemSelectionModel::Current) == 0)
- d->pressedPosition = pos + offset;
- else if (!indexAt(d->pressedPosition - offset).isValid())
- d->pressedPosition = visualRect(currentIndex()).center() + offset;
-
- if (edit(index, NoEditTriggers, event))
- return;
-
- if (index.isValid() && d->isIndexEnabled(index)) {
- // we disable scrollTo for mouse press so the item doesn't change position
- // when the user is interacting with it (ie. clicking on it)
- bool autoScroll = d->autoScroll;
- d->autoScroll = false;
- d->selectionModel->setCurrentIndex(index, QItemSelectionModel::NoUpdate);
- d->autoScroll = autoScroll;
- QRect rect(d->pressedPosition - offset, pos);
- if (command.testFlag(QItemSelectionModel::Toggle)) {
- command &= ~QItemSelectionModel::Toggle;
- d->ctrlDragSelectionFlag = d->selectionModel->isSelected(index) ? QItemSelectionModel::Deselect : QItemSelectionModel::Select;
- command |= d->ctrlDragSelectionFlag;
- }
- setSelection(rect, command);
-
- // signal handlers may change the model
- emit pressed(index);
- if (d->autoScroll) {
- //we delay the autoscrolling to filter out double click event
- //100 is to be sure that there won't be a double-click misinterpreted as a 2 single clicks
- d->delayedAutoScroll.start(QApplication::doubleClickInterval()+100, this);
- }
-
- } else {
- // Forces a finalize() even if mouse is pressed, but not on a item
- d->selectionModel->select(QModelIndex(), QItemSelectionModel::Select);
- }
-}
-
-/*!
- This function is called with the given \a event when a mouse move event is
- sent to the widget. If a selection is in progress and new items are moved
- over the selection is extended; if a drag is in progress it is continued.
-*/
-void QAbstractItemView::mouseMoveEvent(QMouseEvent *event)
-{
- Q_D(QAbstractItemView);
- QPoint topLeft;
- QPoint bottomRight = event->pos();
-
- if (state() == ExpandingState || state() == CollapsingState)
- return;
-
-#ifndef QT_NO_DRAGANDDROP
- if (state() == DraggingState) {
- topLeft = d->pressedPosition - d->offset();
- if ((topLeft - bottomRight).manhattanLength() > QApplication::startDragDistance()) {
- d->pressedIndex = QModelIndex();
- startDrag(d->model->supportedDragActions());
- setState(NoState); // the startDrag will return when the dnd operation is done
- stopAutoScroll();
- }
- return;
- }
-#endif // QT_NO_DRAGANDDROP
-
- QPersistentModelIndex index = indexAt(bottomRight);
- QModelIndex buddy = d->model->buddy(d->pressedIndex);
- if ((state() == EditingState && d->hasEditor(buddy))
- || edit(index, NoEditTriggers, event))
- return;
-
- if (d->selectionMode != SingleSelection)
- topLeft = d->pressedPosition - d->offset();
- else
- topLeft = bottomRight;
-
- d->checkMouseMove(index);
-
-#ifndef QT_NO_DRAGANDDROP
- if (d->pressedIndex.isValid()
- && d->dragEnabled
- && (state() != DragSelectingState)
- && (event->buttons() != Qt::NoButton)
- && !d->selectedDraggableIndexes().isEmpty()) {
- setState(DraggingState);
- return;
- }
-#endif
-
- if ((event->buttons() & Qt::LeftButton) && d->selectionAllowed(index) && d->selectionModel) {
- setState(DragSelectingState);
- QItemSelectionModel::SelectionFlags command = selectionCommand(index, event);
- if (d->ctrlDragSelectionFlag != QItemSelectionModel::NoUpdate && command.testFlag(QItemSelectionModel::Toggle)) {
- command &= ~QItemSelectionModel::Toggle;
- command |= d->ctrlDragSelectionFlag;
- }
-
- // Do the normalize ourselves, since QRect::normalized() is flawed
- QRect selectionRect = QRect(topLeft, bottomRight);
- setSelection(selectionRect, command);
-
- // set at the end because it might scroll the view
- if (index.isValid()
- && (index != d->selectionModel->currentIndex())
- && d->isIndexEnabled(index))
- d->selectionModel->setCurrentIndex(index, QItemSelectionModel::NoUpdate);
- }
-}
-
-/*!
- This function is called with the given \a event when a mouse button is released,
- after a mouse press event on the widget. If a user presses the mouse inside your
- widget and then drags the mouse to another location before releasing the mouse button,
- your widget receives the release event. The function will emit the clicked() signal if an
- item was being pressed.
-*/
-void QAbstractItemView::mouseReleaseEvent(QMouseEvent *event)
-{
- Q_D(QAbstractItemView);
-
- QPoint pos = event->pos();
- QPersistentModelIndex index = indexAt(pos);
-
- if (state() == EditingState) {
- if (d->isIndexValid(index)
- && d->isIndexEnabled(index)
- && d->sendDelegateEvent(index, event))
- update(index);
- return;
- }
-
- bool click = (index == d->pressedIndex && index.isValid());
- bool selectedClicked = click && (event->button() & Qt::LeftButton) && d->pressedAlreadySelected;
- EditTrigger trigger = (selectedClicked ? SelectedClicked : NoEditTriggers);
- bool edited = edit(index, trigger, event);
-
- d->ctrlDragSelectionFlag = QItemSelectionModel::NoUpdate;
-
- if (d->selectionModel && d->noSelectionOnMousePress) {
- d->noSelectionOnMousePress = false;
- d->selectionModel->select(index, selectionCommand(index, event));
- }
-
- setState(NoState);
-
- if (click) {
- emit clicked(index);
- if (edited)
- return;
- QStyleOptionViewItemV4 option = d->viewOptionsV4();
- if (d->pressedAlreadySelected)
- option.state |= QStyle::State_Selected;
- if (style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick, &option, this))
- emit activated(index);
- }
-}
-
-/*!
- This function is called with the given \a event when a mouse button is
- double clicked inside the widget. If the double-click is on a valid item it
- emits the doubleClicked() signal and calls edit() on the item.
-*/
-void QAbstractItemView::mouseDoubleClickEvent(QMouseEvent *event)
-{
- Q_D(QAbstractItemView);
-
- QModelIndex index = indexAt(event->pos());
- if (!index.isValid()
- || !d->isIndexEnabled(index)
- || (d->pressedIndex != index)) {
- QMouseEvent me(QEvent::MouseButtonPress,
- event->pos(), event->button(),
- event->buttons(), event->modifiers());
- mousePressEvent(&me);
- return;
- }
- // signal handlers may change the model
- QPersistentModelIndex persistent = index;
- emit doubleClicked(persistent);
- if ((event->button() & Qt::LeftButton) && !edit(persistent, DoubleClicked, event)
- && !style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick, 0, this))
- emit activated(persistent);
-}
-
-#ifndef QT_NO_DRAGANDDROP
-
-/*!
- This function is called with the given \a event when a drag and drop operation enters
- the widget. If the drag is over a valid dropping place (e.g. over an item that
- accepts drops), the event is accepted; otherwise it is ignored.
-
- \sa dropEvent() startDrag()
-*/
-void QAbstractItemView::dragEnterEvent(QDragEnterEvent *event)
-{
- if (dragDropMode() == InternalMove
- && (event->source() != this|| !(event->possibleActions() & Qt::MoveAction)))
- return;
-
- if (d_func()->canDecode(event)) {
- event->accept();
- setState(DraggingState);
- } else {
- event->ignore();
- }
-}
-
-/*!
- This function is called continuously with the given \a event during a drag and
- drop operation over the widget. It can cause the view to scroll if, for example,
- the user drags a selection to view's right or bottom edge. In this case, the
- event will be accepted; otherwise it will be ignored.
-
- \sa dropEvent() startDrag()
-*/
-void QAbstractItemView::dragMoveEvent(QDragMoveEvent *event)
-{
- Q_D(QAbstractItemView);
- if (dragDropMode() == InternalMove
- && (event->source() != this || !(event->possibleActions() & Qt::MoveAction)))
- return;
-
- // ignore by default
- event->ignore();
-
- QModelIndex index = indexAt(event->pos());
- d->hover = index;
- if (!d->droppingOnItself(event, index)
- && d->canDecode(event)) {
-
- if (index.isValid() && d->showDropIndicator) {
- QRect rect = visualRect(index);
- d->dropIndicatorPosition = d->position(event->pos(), rect, index);
- switch (d->dropIndicatorPosition) {
- case AboveItem:
- if (d->isIndexDropEnabled(index.parent())) {
- d->dropIndicatorRect = QRect(rect.left(), rect.top(), rect.width(), 0);
- event->accept();
- } else {
- d->dropIndicatorRect = QRect();
- }
- break;
- case BelowItem:
- if (d->isIndexDropEnabled(index.parent())) {
- d->dropIndicatorRect = QRect(rect.left(), rect.bottom(), rect.width(), 0);
- event->accept();
- } else {
- d->dropIndicatorRect = QRect();
- }
- break;
- case OnItem:
- if (d->isIndexDropEnabled(index)) {
- d->dropIndicatorRect = rect;
- event->accept();
- } else {
- d->dropIndicatorRect = QRect();
- }
- break;
- case OnViewport:
- d->dropIndicatorRect = QRect();
- if (d->isIndexDropEnabled(rootIndex())) {
- event->accept(); // allow dropping in empty areas
- }
- break;
- }
- } else {
- d->dropIndicatorRect = QRect();
- d->dropIndicatorPosition = OnViewport;
- if (d->isIndexDropEnabled(rootIndex())) {
- event->accept(); // allow dropping in empty areas
- }
- }
- d->viewport->update();
- } // can decode
-
- if (d->shouldAutoScroll(event->pos()))
- startAutoScroll();
-}
-
-/*!
- \internal
- Return true if this is a move from ourself and \a index is a child of the selection that
- is being moved.
- */
-bool QAbstractItemViewPrivate::droppingOnItself(QDropEvent *event, const QModelIndex &index)
-{
- Q_Q(QAbstractItemView);
- Qt::DropAction dropAction = event->dropAction();
- if (q->dragDropMode() == QAbstractItemView::InternalMove)
- dropAction = Qt::MoveAction;
- if (event->source() == q
- && event->possibleActions() & Qt::MoveAction
- && dropAction == Qt::MoveAction) {
- QModelIndexList selectedIndexes = q->selectedIndexes();
- QModelIndex child = index;
- while (child.isValid() && child != root) {
- if (selectedIndexes.contains(child))
- return true;
- child = child.parent();
- }
- }
- return false;
-}
-
-/*!
- \fn void QAbstractItemView::dragLeaveEvent(QDragLeaveEvent *event)
-
- This function is called when the item being dragged leaves the view.
- The \a event describes the state of the drag and drop operation.
-*/
-void QAbstractItemView::dragLeaveEvent(QDragLeaveEvent *)
-{
- Q_D(QAbstractItemView);
- stopAutoScroll();
- setState(NoState);
- d->hover = QModelIndex();
- d->viewport->update();
-}
-
-/*!
- This function is called with the given \a event when a drop event occurs over
- the widget. If the model accepts the even position the drop event is accepted;
- otherwise it is ignored.
-
- \sa startDrag()
-*/
-void QAbstractItemView::dropEvent(QDropEvent *event)
-{
- Q_D(QAbstractItemView);
- if (dragDropMode() == InternalMove) {
- if (event->source() != this || !(event->possibleActions() & Qt::MoveAction))
- return;
- }
-
- QModelIndex index;
- int col = -1;
- int row = -1;
- if (d->dropOn(event, &row, &col, &index)) {
- if (d->model->dropMimeData(event->mimeData(),
- dragDropMode() == InternalMove ? Qt::MoveAction : event->dropAction(), row, col, index)) {
- if (dragDropMode() == InternalMove)
- event->setDropAction(Qt::MoveAction);
- event->accept();
- }
- }
- stopAutoScroll();
- setState(NoState);
- d->viewport->update();
-}
-
-/*!
- If the event hasn't already been accepted, determines the index to drop on.
-
- if (row == -1 && col == -1)
- // append to this drop index
- else
- // place at row, col in drop index
-
- If it returns true a drop can be done, and dropRow, dropCol and dropIndex reflects the position of the drop.
- \internal
- */
-bool QAbstractItemViewPrivate::dropOn(QDropEvent *event, int *dropRow, int *dropCol, QModelIndex *dropIndex)
-{
- Q_Q(QAbstractItemView);
- if (event->isAccepted())
- return false;
-
- QModelIndex index;
- // rootIndex() (i.e. the viewport) might be a valid index
- if (viewport->rect().contains(event->pos())) {
- index = q->indexAt(event->pos());
- if (!index.isValid() || !q->visualRect(index).contains(event->pos()))
- index = root;
- }
-
- // If we are allowed to do the drop
- if (model->supportedDropActions() & event->dropAction()) {
- int row = -1;
- int col = -1;
- if (index != root) {
- dropIndicatorPosition = position(event->pos(), q->visualRect(index), index);
- switch (dropIndicatorPosition) {
- case QAbstractItemView::AboveItem:
- row = index.row();
- col = index.column();
- index = index.parent();
- break;
- case QAbstractItemView::BelowItem:
- row = index.row() + 1;
- col = index.column();
- index = index.parent();
- break;
- case QAbstractItemView::OnItem:
- case QAbstractItemView::OnViewport:
- break;
- }
- } else {
- dropIndicatorPosition = QAbstractItemView::OnViewport;
- }
- *dropIndex = index;
- *dropRow = row;
- *dropCol = col;
- if (!droppingOnItself(event, index))
- return true;
- }
- return false;
-}
-
-QAbstractItemView::DropIndicatorPosition
-QAbstractItemViewPrivate::position(const QPoint &pos, const QRect &rect, const QModelIndex &index) const
-{
- QAbstractItemView::DropIndicatorPosition r = QAbstractItemView::OnViewport;
- if (!overwrite) {
- const int margin = 2;
- if (pos.y() - rect.top() < margin) {
- r = QAbstractItemView::AboveItem;
- } else if (rect.bottom() - pos.y() < margin) {
- r = QAbstractItemView::BelowItem;
- } else if (rect.contains(pos, true)) {
- r = QAbstractItemView::OnItem;
- }
- } else {
- QRect touchingRect = rect;
- touchingRect.adjust(-1, -1, 1, 1);
- if (touchingRect.contains(pos, false)) {
- r = QAbstractItemView::OnItem;
- }
- }
-
- if (r == QAbstractItemView::OnItem && (!(model->flags(index) & Qt::ItemIsDropEnabled)))
- r = pos.y() < rect.center().y() ? QAbstractItemView::AboveItem : QAbstractItemView::BelowItem;
-
- return r;
-}
-
-#endif // QT_NO_DRAGANDDROP
-
-/*!
- This function is called with the given \a event when the widget obtains the focus.
- By default, the event is ignored.
-
- \sa setFocus(), focusOutEvent()
-*/
-void QAbstractItemView::focusInEvent(QFocusEvent *event)
-{
- Q_D(QAbstractItemView);
- QAbstractScrollArea::focusInEvent(event);
-
- const QItemSelectionModel* model = selectionModel();
- const bool currentIndexValid = currentIndex().isValid();
-
- if (model
- && !d->currentIndexSet
- && !currentIndexValid) {
- bool autoScroll = d->autoScroll;
- d->autoScroll = false;
- QModelIndex index = moveCursor(MoveNext, Qt::NoModifier); // first visible index
- if (index.isValid() && d->isIndexEnabled(index) && event->reason() != Qt::MouseFocusReason)
- selectionModel()->setCurrentIndex(index, QItemSelectionModel::NoUpdate);
- d->autoScroll = autoScroll;
- }
-
- if (model && currentIndexValid) {
- if (currentIndex().flags() != Qt::ItemIsEditable)
- setAttribute(Qt::WA_InputMethodEnabled, false);
- else
- setAttribute(Qt::WA_InputMethodEnabled);
- }
-
- if (!currentIndexValid)
- setAttribute(Qt::WA_InputMethodEnabled, false);
-
- d->viewport->update();
-}
-
-/*!
- This function is called with the given \a event when the widget
- looses the focus. By default, the event is ignored.
-
- \sa clearFocus(), focusInEvent()
-*/
-void QAbstractItemView::focusOutEvent(QFocusEvent *event)
-{
- Q_D(QAbstractItemView);
- QAbstractScrollArea::focusOutEvent(event);
- d->viewport->update();
-
-#ifdef QT_SOFTKEYS_ENABLED
- if(!hasEditFocus())
- removeAction(d->doneSoftKey);
-#endif
-}
-
-/*!
- This function is called with the given \a event when a key event is sent to
- the widget. The default implementation handles basic cursor movement, e.g. Up,
- Down, Left, Right, Home, PageUp, and PageDown; the activated() signal is
- emitted if the current index is valid and the activation key is pressed
- (e.g. Enter or Return, depending on the platform).
- This function is where editing is initiated by key press, e.g. if F2 is
- pressed.
-
- \sa edit(), moveCursor(), keyboardSearch(), tabKeyNavigation
-*/
-void QAbstractItemView::keyPressEvent(QKeyEvent *event)
-{
- Q_D(QAbstractItemView);
- d->delayedAutoScroll.stop(); //any interaction with the view cancel the auto scrolling
-
-#ifdef QT_KEYPAD_NAVIGATION
- switch (event->key()) {
- case Qt::Key_Select:
- if (QApplication::keypadNavigationEnabled()) {
- if (!hasEditFocus()) {
- setEditFocus(true);
-#ifdef QT_SOFTKEYS_ENABLED
- // If we can't keypad navigate to any direction, there is no sense to add
- // "Done" softkey, since it basically does nothing when there is
- // only one widget in screen
- if(QWidgetPrivate::canKeypadNavigate(Qt::Horizontal)
- || QWidgetPrivate::canKeypadNavigate(Qt::Vertical))
- addAction(d->doneSoftKey);
-#endif
- return;
- }
- }
- break;
- case Qt::Key_Back:
- if (QApplication::keypadNavigationEnabled() && hasEditFocus()) {
-#ifdef QT_SOFTKEYS_ENABLED
- removeAction(d->doneSoftKey);
-#endif
- setEditFocus(false);
- } else {
- event->ignore();
- }
- return;
- case Qt::Key_Down:
- case Qt::Key_Up:
- // Let's ignore vertical navigation events, only if there is no other widget
- // what can take the focus in vertical direction. This means widget can handle navigation events
- // even the widget don't have edit focus, and there is no other widget in requested direction.
- if(QApplication::keypadNavigationEnabled() && !hasEditFocus()
- && QWidgetPrivate::canKeypadNavigate(Qt::Vertical)) {
- event->ignore();
- return;
- }
- break;
- case Qt::Key_Left:
- case Qt::Key_Right:
- // Similar logic as in up and down events
- if(QApplication::keypadNavigationEnabled() && !hasEditFocus()
- && (QWidgetPrivate::canKeypadNavigate(Qt::Horizontal) || QWidgetPrivate::inTabWidget(this))) {
- event->ignore();
- return;
- }
- break;
- default:
- if (QApplication::keypadNavigationEnabled() && !hasEditFocus()) {
- event->ignore();
- return;
- }
- }
-#endif
-
-#if !defined(QT_NO_CLIPBOARD) && !defined(QT_NO_SHORTCUT)
- if (event == QKeySequence::Copy) {
- QVariant variant;
- if (d->model)
- variant = d->model->data(currentIndex(), Qt::DisplayRole);
- if (variant.type() == QVariant::String)
- QApplication::clipboard()->setText(variant.toString());
- event->accept();
- }
-#endif
-
- QPersistentModelIndex newCurrent;
- d->moveCursorUpdatedView = false;
- switch (event->key()) {
- case Qt::Key_Down:
- newCurrent = moveCursor(MoveDown, event->modifiers());
- break;
- case Qt::Key_Up:
- newCurrent = moveCursor(MoveUp, event->modifiers());
- break;
- case Qt::Key_Left:
- newCurrent = moveCursor(MoveLeft, event->modifiers());
- break;
- case Qt::Key_Right:
- newCurrent = moveCursor(MoveRight, event->modifiers());
- break;
- case Qt::Key_Home:
- newCurrent = moveCursor(MoveHome, event->modifiers());
- break;
- case Qt::Key_End:
- newCurrent = moveCursor(MoveEnd, event->modifiers());
- break;
- case Qt::Key_PageUp:
- newCurrent = moveCursor(MovePageUp, event->modifiers());
- break;
- case Qt::Key_PageDown:
- newCurrent = moveCursor(MovePageDown, event->modifiers());
- break;
- case Qt::Key_Tab:
- if (d->tabKeyNavigation)
- newCurrent = moveCursor(MoveNext, event->modifiers());
- break;
- case Qt::Key_Backtab:
- if (d->tabKeyNavigation)
- newCurrent = moveCursor(MovePrevious, event->modifiers());
- break;
- }
-
- QPersistentModelIndex oldCurrent = currentIndex();
- if (newCurrent != oldCurrent && newCurrent.isValid() && d->isIndexEnabled(newCurrent)) {
- if (!hasFocus() && QApplication::focusWidget() == indexWidget(oldCurrent))
- setFocus();
- QItemSelectionModel::SelectionFlags command = selectionCommand(newCurrent, event);
- if (command != QItemSelectionModel::NoUpdate
- || style()->styleHint(QStyle::SH_ItemView_MovementWithoutUpdatingSelection, 0, this)) {
- // note that we don't check if the new current index is enabled because moveCursor() makes sure it is
- if (command & QItemSelectionModel::Current) {
- d->selectionModel->setCurrentIndex(newCurrent, QItemSelectionModel::NoUpdate);
- if (!indexAt(d->pressedPosition - d->offset()).isValid())
- d->pressedPosition = visualRect(oldCurrent).center() + d->offset();
- QRect rect(d->pressedPosition - d->offset(), visualRect(newCurrent).center());
- setSelection(rect, command);
- } else {
- d->selectionModel->setCurrentIndex(newCurrent, command);
- d->pressedPosition = visualRect(newCurrent).center() + d->offset();
- if (newCurrent.isValid()) {
- // We copy the same behaviour as for mousePressEvent().
- QRect rect(d->pressedPosition - d->offset(), QSize(1, 1));
- setSelection(rect, command);
- }
- }
- event->accept();
- return;
- }
- }
-
- switch (event->key()) {
- // ignored keys
- case Qt::Key_Down:
- case Qt::Key_Up:
-#ifdef QT_KEYPAD_NAVIGATION
- if (QApplication::keypadNavigationEnabled() && QWidgetPrivate::canKeypadNavigate(Qt::Vertical)) {
- event->accept(); // don't change focus
- break;
- }
-#endif
- case Qt::Key_Left:
- case Qt::Key_Right:
-#ifdef QT_KEYPAD_NAVIGATION
- if (QApplication::navigationMode() == Qt::NavigationModeKeypadDirectional
- && (QWidgetPrivate::canKeypadNavigate(Qt::Horizontal)
- || (QWidgetPrivate::inTabWidget(this) && d->model->columnCount(d->root) > 1))) {
- event->accept(); // don't change focus
- break;
- }
-#endif // QT_KEYPAD_NAVIGATION
- case Qt::Key_Home:
- case Qt::Key_End:
- case Qt::Key_PageUp:
- case Qt::Key_PageDown:
- case Qt::Key_Escape:
- case Qt::Key_Shift:
- case Qt::Key_Control:
- case Qt::Key_Delete:
- case Qt::Key_Backspace:
- event->ignore();
- break;
- case Qt::Key_Space:
- case Qt::Key_Select:
- if (!edit(currentIndex(), AnyKeyPressed, event) && d->selectionModel)
- d->selectionModel->select(currentIndex(), selectionCommand(currentIndex(), event));
-#ifdef QT_KEYPAD_NAVIGATION
- if ( event->key()==Qt::Key_Select ) {
- // Also do Key_Enter action.
- if (currentIndex().isValid()) {
- if (state() != EditingState)
- emit activated(currentIndex());
- } else {
- event->ignore();
- }
- }
-#endif
- break;
-#ifdef Q_WS_MAC
- case Qt::Key_Enter:
- case Qt::Key_Return:
- // Propagate the enter if you couldn't edit the item and there are no
- // current editors (if there are editors, the event was most likely propagated from it).
- if (!edit(currentIndex(), EditKeyPressed, event) && d->editorIndexHash.isEmpty())
- event->ignore();
- break;
-#else
- case Qt::Key_F2:
- if (!edit(currentIndex(), EditKeyPressed, event))
- event->ignore();
- break;
- case Qt::Key_Enter:
- case Qt::Key_Return:
- // ### we can't open the editor on enter, becuse
- // some widgets will forward the enter event back
- // to the viewport, starting an endless loop
- if (state() != EditingState || hasFocus()) {
- if (currentIndex().isValid())
- emit activated(currentIndex());
- event->ignore();
- }
- break;
-#endif
- case Qt::Key_A:
- if (event->modifiers() & Qt::ControlModifier) {
- selectAll();
- break;
- }
- default: {
-#ifdef Q_WS_MAC
- if (event->key() == Qt::Key_O && event->modifiers() & Qt::ControlModifier && currentIndex().isValid()) {
- emit activated(currentIndex());
- break;
- }
-#endif
- bool modified = (event->modifiers() & (Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier));
- if (!event->text().isEmpty() && !modified && !edit(currentIndex(), AnyKeyPressed, event)) {
- keyboardSearch(event->text());
- event->accept();
- } else {
- event->ignore();
- }
- break; }
- }
- if (d->moveCursorUpdatedView)
- event->accept();
-}
-
-/*!
- This function is called with the given \a event when a resize event is sent to
- the widget.
-
- \sa QWidget::resizeEvent()
-*/
-void QAbstractItemView::resizeEvent(QResizeEvent *event)
-{
- QAbstractScrollArea::resizeEvent(event);
- updateGeometries();
-}
-
-/*!
- This function is called with the given \a event when a timer event is sent
- to the widget.
-
- \sa QObject::timerEvent()
-*/
-void QAbstractItemView::timerEvent(QTimerEvent *event)
-{
- Q_D(QAbstractItemView);
- if (event->timerId() == d->fetchMoreTimer.timerId())
- d->fetchMore();
- else if (event->timerId() == d->delayedReset.timerId())
- reset();
- else if (event->timerId() == d->autoScrollTimer.timerId())
- doAutoScroll();
- else if (event->timerId() == d->updateTimer.timerId())
- d->updateDirtyRegion();
- else if (event->timerId() == d->delayedEditing.timerId()) {
- d->delayedEditing.stop();
- edit(currentIndex());
- } else if (event->timerId() == d->delayedLayout.timerId()) {
- d->delayedLayout.stop();
- if (isVisible()) {
- d->interruptDelayedItemsLayout();
- doItemsLayout();
- const QModelIndex current = currentIndex();
- if (current.isValid() && d->state == QAbstractItemView::EditingState)
- scrollTo(current);
- }
- } else if (event->timerId() == d->delayedAutoScroll.timerId()) {
- d->delayedAutoScroll.stop();
- //end of the timer: if the current item is still the same as the one when the mouse press occurred
- //we only get here if there was no double click
- if (d->pressedIndex.isValid() && d->pressedIndex == currentIndex())
- scrollTo(d->pressedIndex);
- }
-}
-
-/*!
- \reimp
-*/
-void QAbstractItemView::inputMethodEvent(QInputMethodEvent *event)
-{
- if (event->commitString().isEmpty() && event->preeditString().isEmpty()) {
- event->ignore();
- return;
- }
- if (!edit(currentIndex(), AnyKeyPressed, event)) {
- if (!event->commitString().isEmpty())
- keyboardSearch(event->commitString());
- event->ignore();
- }
-}
-
-#ifndef QT_NO_DRAGANDDROP
-/*!
- \enum QAbstractItemView::DropIndicatorPosition
-
- This enum indicates the position of the drop indicator in
- relation to the index at the current mouse position:
-
- \value OnItem The item will be dropped on the index.
-
- \value AboveItem The item will be dropped above the index.
-
- \value BelowItem The item will be dropped below the index.
-
- \value OnViewport The item will be dropped onto a region of the viewport with
- no items. The way each view handles items dropped onto the viewport depends on
- the behavior of the underlying model in use.
-*/
-
-
-/*!
- \since 4.1
-
- Returns the position of the drop indicator in relation to the closest item.
-*/
-QAbstractItemView::DropIndicatorPosition QAbstractItemView::dropIndicatorPosition() const
-{
- Q_D(const QAbstractItemView);
- return d->dropIndicatorPosition;
-}
-#endif
-
-/*!
- This convenience function returns a list of all selected and
- non-hidden item indexes in the view. The list contains no
- duplicates, and is not sorted.
-
- \sa QItemSelectionModel::selectedIndexes()
-*/
-QModelIndexList QAbstractItemView::selectedIndexes() const
-{
- Q_D(const QAbstractItemView);
- QModelIndexList indexes;
- if (d->selectionModel) {
- indexes = d->selectionModel->selectedIndexes();
- QList<QModelIndex>::iterator it = indexes.begin();
- while (it != indexes.end())
- if (isIndexHidden(*it))
- it = indexes.erase(it);
- else
- ++it;
- }
- return indexes;
-}
-
-/*!
- Starts editing the item at \a index, creating an editor if
- necessary, and returns true if the view's \l{State} is now
- EditingState; otherwise returns false.
-
- The action that caused the editing process is described by
- \a trigger, and the associated event is specified by \a event.
-
- Editing can be forced by specifying the \a trigger to be
- QAbstractItemView::AllEditTriggers.
-
- \sa closeEditor()
-*/
-bool QAbstractItemView::edit(const QModelIndex &index, EditTrigger trigger, QEvent *event)
-{
- Q_D(QAbstractItemView);
-
- if (!d->isIndexValid(index))
- return false;
-
- if (QWidget *w = (d->persistent.isEmpty() ? static_cast<QWidget*>(0) : d->editorForIndex(index).widget.data())) {
- if (w->focusPolicy() == Qt::NoFocus)
- return false;
- w->setFocus();
- return true;
- }
-
- if (trigger == DoubleClicked) {
- d->delayedEditing.stop();
- d->delayedAutoScroll.stop();
- } else if (trigger == CurrentChanged) {
- d->delayedEditing.stop();
- }
-
- if (d->sendDelegateEvent(index, event)) {
- update(index);
- return true;
- }
-
- // save the previous trigger before updating
- EditTriggers lastTrigger = d->lastTrigger;
- d->lastTrigger = trigger;
-
- if (!d->shouldEdit(trigger, d->model->buddy(index)))
- return false;
-
- if (d->delayedEditing.isActive())
- return false;
-
- // we will receive a mouseButtonReleaseEvent after a
- // mouseDoubleClickEvent, so we need to check the previous trigger
- if (lastTrigger == DoubleClicked && trigger == SelectedClicked)
- return false;
-
- // we may get a double click event later
- if (trigger == SelectedClicked)
- d->delayedEditing.start(QApplication::doubleClickInterval(), this);
- else
- d->openEditor(index, d->shouldForwardEvent(trigger, event) ? event : 0);
-
- return true;
-}
-
-/*!
- \internal
- Updates the data shown in the open editor widgets in the view.
-*/
-void QAbstractItemView::updateEditorData()
-{
- Q_D(QAbstractItemView);
- d->updateEditorData(QModelIndex(), QModelIndex());
-}
-
-/*!
- \internal
- Updates the geometry of the open editor widgets in the view.
-*/
-void QAbstractItemView::updateEditorGeometries()
-{
- Q_D(QAbstractItemView);
- if(d->editorIndexHash.isEmpty())
- return;
- QStyleOptionViewItemV4 option = d->viewOptionsV4();
- QEditorIndexHash::iterator it = d->editorIndexHash.begin();
- QWidgetList editorsToRelease;
- QWidgetList editorsToHide;
- while (it != d->editorIndexHash.end()) {
- QModelIndex index = it.value();
- QWidget *editor = it.key();
- if (index.isValid() && editor) {
- option.rect = visualRect(index);
- if (option.rect.isValid()) {
- editor->show();
- QAbstractItemDelegate *delegate = d->delegateForIndex(index);
- if (delegate)
- delegate->updateEditorGeometry(editor, option, index);
- } else {
- editorsToHide << editor;
- }
- ++it;
- } else {
- d->indexEditorHash.remove(it.value());
- it = d->editorIndexHash.erase(it);
- editorsToRelease << editor;
- }
- }
-
- //we hide and release the editor outside of the loop because it might change the focus and try
- //to change the editors hashes.
- for (int i = 0; i < editorsToHide.count(); ++i) {
- editorsToHide.at(i)->hide();
- }
- for (int i = 0; i < editorsToRelease.count(); ++i) {
- d->releaseEditor(editorsToRelease.at(i));
- }
-}
-
-/*!
- \since 4.4
-
- Updates the geometry of the child widgets of the view.
-*/
-void QAbstractItemView::updateGeometries()
-{
- updateEditorGeometries();
- d_func()->fetchMoreTimer.start(0, this); //fetch more later
-}
-
-/*!
- \internal
-*/
-void QAbstractItemView::verticalScrollbarValueChanged(int value)
-{
- Q_D(QAbstractItemView);
- if (verticalScrollBar()->maximum() == value && d->model->canFetchMore(d->root))
- d->model->fetchMore(d->root);
- QPoint posInVp = viewport()->mapFromGlobal(QCursor::pos());
- if (viewport()->rect().contains(posInVp))
- d->checkMouseMove(posInVp);
-}
-
-/*!
- \internal
-*/
-void QAbstractItemView::horizontalScrollbarValueChanged(int value)
-{
- Q_D(QAbstractItemView);
- if (horizontalScrollBar()->maximum() == value && d->model->canFetchMore(d->root))
- d->model->fetchMore(d->root);
- QPoint posInVp = viewport()->mapFromGlobal(QCursor::pos());
- if (viewport()->rect().contains(posInVp))
- d->checkMouseMove(posInVp);
-}
-
-/*!
- \internal
-*/
-void QAbstractItemView::verticalScrollbarAction(int)
-{
- //do nothing
-}
-
-/*!
- \internal
-*/
-void QAbstractItemView::horizontalScrollbarAction(int)
-{
- //do nothing
-}
-
-/*!
- Closes the given \a editor, and releases it. The \a hint is
- used to specify how the view should respond to the end of the editing
- operation. For example, the hint may indicate that the next item in
- the view should be opened for editing.
-
- \sa edit(), commitData()
-*/
-
-void QAbstractItemView::closeEditor(QWidget *editor, QAbstractItemDelegate::EndEditHint hint)
-{
- Q_D(QAbstractItemView);
-
- // Close the editor
- if (editor) {
- bool isPersistent = d->persistent.contains(editor);
- bool hadFocus = editor->hasFocus();
- QModelIndex index = d->indexForEditor(editor);
- if (!index.isValid())
- return; // the editor was not registered
-
- if (!isPersistent) {
- setState(NoState);
- QModelIndex index = d->indexForEditor(editor);
- editor->removeEventFilter(d->delegateForIndex(index));
- d->removeEditor(editor);
- }
- if (hadFocus)
- setFocus(); // this will send a focusLost event to the editor
- else
- d->checkPersistentEditorFocus();
-
- QPointer<QWidget> ed = editor;
- QApplication::sendPostedEvents(editor, 0);
- editor = ed;
-
- if (!isPersistent && editor)
- d->releaseEditor(editor);
- }
-
- // The EndEditHint part
- QItemSelectionModel::SelectionFlags flags = QItemSelectionModel::ClearAndSelect
- | d->selectionBehaviorFlags();
- switch (hint) {
- case QAbstractItemDelegate::EditNextItem: {
- QModelIndex index = moveCursor(MoveNext, Qt::NoModifier);
- if (index.isValid()) {
- QPersistentModelIndex persistent(index);
- d->selectionModel->setCurrentIndex(persistent, flags);
- // currentChanged signal would have already started editing
- if (index.flags() & Qt::ItemIsEditable
- && (!(editTriggers() & QAbstractItemView::CurrentChanged)))
- edit(persistent);
- } break; }
- case QAbstractItemDelegate::EditPreviousItem: {
- QModelIndex index = moveCursor(MovePrevious, Qt::NoModifier);
- if (index.isValid()) {
- QPersistentModelIndex persistent(index);
- d->selectionModel->setCurrentIndex(persistent, flags);
- // currentChanged signal would have already started editing
- if (index.flags() & Qt::ItemIsEditable
- && (!(editTriggers() & QAbstractItemView::CurrentChanged)))
- edit(persistent);
- } break; }
- case QAbstractItemDelegate::SubmitModelCache:
- d->model->submit();
- break;
- case QAbstractItemDelegate::RevertModelCache:
- d->model->revert();
- break;
- default:
- break;
- }
-}
-
-/*!
- Commit the data in the \a editor to the model.
-
- \sa closeEditor()
-*/
-void QAbstractItemView::commitData(QWidget *editor)
-{
- Q_D(QAbstractItemView);
- if (!editor || !d->itemDelegate || d->currentlyCommittingEditor)
- return;
- QModelIndex index = d->indexForEditor(editor);
- if (!index.isValid())
- return;
- d->currentlyCommittingEditor = editor;
- QAbstractItemDelegate *delegate = d->delegateForIndex(index);
- editor->removeEventFilter(delegate);
- delegate->setModelData(editor, d->model, index);
- editor->installEventFilter(delegate);
- d->currentlyCommittingEditor = 0;
-}
-
-/*!
- This function is called when the given \a editor has been destroyed.
-
- \sa closeEditor()
-*/
-void QAbstractItemView::editorDestroyed(QObject *editor)
-{
- Q_D(QAbstractItemView);
- QWidget *w = qobject_cast<QWidget*>(editor);
- d->removeEditor(w);
- d->persistent.remove(w);
- if (state() == EditingState)
- setState(NoState);
-}
-
-/*!
- \obsolete
- Sets the horizontal scroll bar's steps per item to \a steps.
-
- This is the number of steps used by the horizontal scroll bar to
- represent the width of an item.
-
- Note that if the view has a horizontal header, the item steps
- will be ignored and the header section size will be used instead.
-
- \sa horizontalStepsPerItem() setVerticalStepsPerItem()
-*/
-void QAbstractItemView::setHorizontalStepsPerItem(int steps)
-{
- Q_UNUSED(steps)
- // do nothing
-}
-
-/*!
- \obsolete
- Returns the horizontal scroll bar's steps per item.
-
- \sa setHorizontalStepsPerItem() verticalStepsPerItem()
-*/
-int QAbstractItemView::horizontalStepsPerItem() const
-{
- return 1;
-}
-
-/*!
- \obsolete
- Sets the vertical scroll bar's steps per item to \a steps.
-
- This is the number of steps used by the vertical scroll bar to
- represent the height of an item.
-
- Note that if the view has a vertical header, the item steps
- will be ignored and the header section size will be used instead.
-
- \sa verticalStepsPerItem() setHorizontalStepsPerItem()
-*/
-void QAbstractItemView::setVerticalStepsPerItem(int steps)
-{
- Q_UNUSED(steps)
- // do nothing
-}
-
-/*!
- \obsolete
- Returns the vertical scroll bar's steps per item.
-
- \sa setVerticalStepsPerItem() horizontalStepsPerItem()
-*/
-int QAbstractItemView::verticalStepsPerItem() const
-{
- return 1;
-}
-
-/*!
- Moves to and selects the item best matching the string \a search.
- If no item is found nothing happens.
-
- In the default implementation, the search is reset if \a search is empty, or
- the time interval since the last search has exceeded
- QApplication::keyboardInputInterval().
-*/
-void QAbstractItemView::keyboardSearch(const QString &search)
-{
- Q_D(QAbstractItemView);
- if (!d->model->rowCount(d->root) || !d->model->columnCount(d->root))
- return;
-
- QModelIndex start = currentIndex().isValid() ? currentIndex()
- : d->model->index(0, 0, d->root);
- bool skipRow = false;
- bool keyboardTimeWasValid = d->keyboardInputTime.isValid();
- qint64 keyboardInputTimeElapsed = d->keyboardInputTime.restart();
- if (search.isEmpty() || !keyboardTimeWasValid
- || keyboardInputTimeElapsed > QApplication::keyboardInputInterval()) {
- d->keyboardInput = search;
- skipRow = currentIndex().isValid(); //if it is not valid we should really start at QModelIndex(0,0)
- } else {
- d->keyboardInput += search;
- }
-
- // special case for searches with same key like 'aaaaa'
- bool sameKey = false;
- if (d->keyboardInput.length() > 1) {
- int c = d->keyboardInput.count(d->keyboardInput.at(d->keyboardInput.length() - 1));
- sameKey = (c == d->keyboardInput.length());
- if (sameKey)
- skipRow = true;
- }
-
- // skip if we are searching for the same key or a new search started
- if (skipRow) {
- QModelIndex parent = start.parent();
- int newRow = (start.row() < d->model->rowCount(parent) - 1) ? start.row() + 1 : 0;
- start = d->model->index(newRow, start.column(), parent);
- }
-
- // search from start with wraparound
- const QString searchString = sameKey ? QString(d->keyboardInput.at(0)) : d->keyboardInput;
- QModelIndex current = start;
- QModelIndexList match;
- QModelIndex firstMatch;
- QModelIndex startMatch;
- QModelIndexList previous;
- do {
- match = d->model->match(current, Qt::DisplayRole, searchString);
- if (match == previous)
- break;
- firstMatch = match.value(0);
- previous = match;
- if (firstMatch.isValid()) {
- if (d->isIndexEnabled(firstMatch)) {
- setCurrentIndex(firstMatch);
- break;
- }
- int row = firstMatch.row() + 1;
- if (row >= d->model->rowCount(firstMatch.parent()))
- row = 0;
- current = firstMatch.sibling(row, firstMatch.column());
-
- //avoid infinite loop if all the matching items are disabled.
- if (!startMatch.isValid())
- startMatch = firstMatch;
- else if (startMatch == firstMatch)
- break;
- }
- } while (current != start && firstMatch.isValid());
-}
-
-/*!
- Returns the size hint for the item with the specified \a index or
- an invalid size for invalid indexes.
-
- \sa sizeHintForRow(), sizeHintForColumn()
-*/
-QSize QAbstractItemView::sizeHintForIndex(const QModelIndex &index) const
-{
- Q_D(const QAbstractItemView);
- if (!d->isIndexValid(index) || !d->itemDelegate)
- return QSize();
- return d->delegateForIndex(index)->sizeHint(d->viewOptionsV4(), index);
-}
-
-/*!
- Returns the height size hint for the specified \a row or -1 if
- there is no model.
-
- The returned height is calculated using the size hints of the
- given \a row's items, i.e. the returned value is the maximum
- height among the items. Note that to control the height of a row,
- you must reimplement the QAbstractItemDelegate::sizeHint()
- function.
-
- This function is used in views with a vertical header to find the
- size hint for a header section based on the contents of the given
- \a row.
-
- \sa sizeHintForColumn()
-*/
-int QAbstractItemView::sizeHintForRow(int row) const
-{
- Q_D(const QAbstractItemView);
-
- if (row < 0 || row >= d->model->rowCount(d->root))
- return -1;
-
- ensurePolished();
-
- QStyleOptionViewItemV4 option = d->viewOptionsV4();
- int height = 0;
- int colCount = d->model->columnCount(d->root);
- QModelIndex index;
- for (int c = 0; c < colCount; ++c) {
- index = d->model->index(row, c, d->root);
- if (QWidget *editor = d->editorForIndex(index).widget.data())
- height = qMax(height, editor->height());
- int hint = d->delegateForIndex(index)->sizeHint(option, index).height();
- height = qMax(height, hint);
- }
- return height;
-}
-
-/*!
- Returns the width size hint for the specified \a column or -1 if there is no model.
-
- This function is used in views with a horizontal header to find the size hint for
- a header section based on the contents of the given \a column.
-
- \sa sizeHintForRow()
-*/
-int QAbstractItemView::sizeHintForColumn(int column) const
-{
- Q_D(const QAbstractItemView);
-
- if (column < 0 || column >= d->model->columnCount(d->root))
- return -1;
-
- ensurePolished();
-
- QStyleOptionViewItemV4 option = d->viewOptionsV4();
- int width = 0;
- int rows = d->model->rowCount(d->root);
- QModelIndex index;
- for (int r = 0; r < rows; ++r) {
- index = d->model->index(r, column, d->root);
- if (QWidget *editor = d->editorForIndex(index).widget.data())
- width = qMax(width, editor->sizeHint().width());
- int hint = d->delegateForIndex(index)->sizeHint(option, index).width();
- width = qMax(width, hint);
- }
- return width;
-}
-
-/*!
- Opens a persistent editor on the item at the given \a index.
- If no editor exists, the delegate will create a new editor.
-
- \sa closePersistentEditor()
-*/
-void QAbstractItemView::openPersistentEditor(const QModelIndex &index)
-{
- Q_D(QAbstractItemView);
- QStyleOptionViewItemV4 options = d->viewOptionsV4();
- options.rect = visualRect(index);
- options.state |= (index == currentIndex() ? QStyle::State_HasFocus : QStyle::State_None);
-
- QWidget *editor = d->editor(index, options);
- if (editor) {
- editor->show();
- d->persistent.insert(editor);
- }
-}
-
-/*!
- Closes the persistent editor for the item at the given \a index.
-
- \sa openPersistentEditor()
-*/
-void QAbstractItemView::closePersistentEditor(const QModelIndex &index)
-{
- Q_D(QAbstractItemView);
- if (QWidget *editor = d->editorForIndex(index).widget.data()) {
- if (index == selectionModel()->currentIndex())
- closeEditor(editor, QAbstractItemDelegate::RevertModelCache);
- d->persistent.remove(editor);
- d->removeEditor(editor);
- d->releaseEditor(editor);
- }
-}
-
-/*!
- \since 4.1
-
- Sets the given \a widget on the item at the given \a index, passing the
- ownership of the widget to the viewport.
-
- If \a index is invalid (e.g., if you pass the root index), this function
- will do nothing.
-
- 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 item at the given \a index.
-
- If index widget A is replaced with index widget B, index widget A will be
- deleted. For example, in the code snippet below, the QLineEdit object will
- be deleted.
-
- \snippet doc/src/snippets/code/src_gui_itemviews_qabstractitemview.cpp 1
-
- This function should only be used to display static content within the
- visible area corresponding to an item of data. If you want to display
- custom dynamic content or implement a custom editor widget, subclass
- QItemDelegate instead.
-
- \sa {Delegate Classes}
-*/
-void QAbstractItemView::setIndexWidget(const QModelIndex &index, QWidget *widget)
-{
- Q_D(QAbstractItemView);
- if (!d->isIndexValid(index))
- return;
- if (QWidget *oldWidget = indexWidget(index)) {
- d->persistent.remove(oldWidget);
- d->removeEditor(oldWidget);
- oldWidget->deleteLater();
- }
- if (widget) {
- widget->setParent(viewport());
- d->persistent.insert(widget);
- d->addEditor(index, widget, true);
- widget->show();
- dataChanged(index, index); // update the geometry
- if (!d->delayedPendingLayout)
- widget->setGeometry(visualRect(index));
- }
-}
-
-/*!
- \since 4.1
-
- Returns the widget for the item at the given \a index.
-*/
-QWidget* QAbstractItemView::indexWidget(const QModelIndex &index) const
-{
- Q_D(const QAbstractItemView);
- if (d->isIndexValid(index))
- if (QWidget *editor = d->editorForIndex(index).widget.data())
- return editor;
-
- return 0;
-}
-
-/*!
- \since 4.1
-
- Scrolls the view to the top.
-
- \sa scrollTo(), scrollToBottom()
-*/
-void QAbstractItemView::scrollToTop()
-{
- verticalScrollBar()->setValue(verticalScrollBar()->minimum());
-}
-
-/*!
- \since 4.1
-
- Scrolls the view to the bottom.
-
- \sa scrollTo(), scrollToTop()
-*/
-void QAbstractItemView::scrollToBottom()
-{
- Q_D(QAbstractItemView);
- if (d->delayedPendingLayout) {
- d->executePostedLayout();
- updateGeometries();
- }
- verticalScrollBar()->setValue(verticalScrollBar()->maximum());
-}
-
-/*!
- \since 4.3
-
- Updates the area occupied by the given \a index.
-
-*/
-void QAbstractItemView::update(const QModelIndex &index)
-{
- Q_D(QAbstractItemView);
- if (index.isValid()) {
- const QRect rect = visualRect(index);
- //this test is important for peformance reason
- //For example in dataChanged we simply update all the cells without checking
- //it can be a major bottleneck to update rects that aren't even part of the viewport
- if (d->viewport->rect().intersects(rect))
- d->viewport->update(rect);
- }
-}
-
-/*!
- This slot is called when items are changed in the model. The
- changed items are those from \a topLeft to \a bottomRight
- inclusive. If just one item is changed \a topLeft == \a
- bottomRight.
-*/
-void QAbstractItemView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
-{
- // Single item changed
- Q_D(QAbstractItemView);
- if (topLeft == bottomRight && topLeft.isValid()) {
- const QEditorInfo &editorInfo = d->editorForIndex(topLeft);
- //we don't update the edit data if it is static
- if (!editorInfo.isStatic && editorInfo.widget) {
- QAbstractItemDelegate *delegate = d->delegateForIndex(topLeft);
- if (delegate) {
- delegate->setEditorData(editorInfo.widget.data(), topLeft);
- }
- }
- if (isVisible() && !d->delayedPendingLayout) {
- // otherwise the items will be update later anyway
- update(topLeft);
- }
- return;
- }
- d->updateEditorData(topLeft, bottomRight);
- if (!isVisible() || d->delayedPendingLayout)
- return; // no need to update
- d->viewport->update();
-}
-
-/*!
- This slot is called when rows are inserted. The new rows are those
- under the given \a parent from \a start to \a end inclusive. The
- base class implementation calls fetchMore() on the model to check
- for more data.
-
- \sa rowsAboutToBeRemoved()
-*/
-void QAbstractItemView::rowsInserted(const QModelIndex &, int, int)
-{
- if (!isVisible())
- d_func()->fetchMoreTimer.start(0, this); //fetch more later
- else
- updateEditorGeometries();
-}
-
-/*!
- This slot is called when rows are about to be removed. The deleted rows are
- those under the given \a parent from \a start to \a end inclusive.
-
- \sa rowsInserted()
-*/
-void QAbstractItemView::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
-{
- Q_D(QAbstractItemView);
-
- setState(CollapsingState);
-
- // Ensure one selected item in single selection mode.
- QModelIndex current = currentIndex();
- if (d->selectionMode == SingleSelection
- && current.isValid()
- && current.row() >= start
- && current.row() <= end
- && current.parent() == parent) {
- int totalToRemove = end - start + 1;
- if (d->model->rowCount(parent) <= totalToRemove) { // no more children
- QModelIndex index = parent;
- while (index != d->root && !d->isIndexEnabled(index))
- index = index.parent();
- if (index != d->root)
- setCurrentIndex(index);
- } else {
- int row = end + 1;
- QModelIndex next;
- do { // find the next visible and enabled item
- next = d->model->index(row++, current.column(), current.parent());
- } while (next.isValid() && (isIndexHidden(next) || !d->isIndexEnabled(next)));
- if (row > d->model->rowCount(parent)) {
- row = start - 1;
- do { // find the previous visible and enabled item
- next = d->model->index(row--, current.column(), current.parent());
- } while (next.isValid() && (isIndexHidden(next) || !d->isIndexEnabled(next)));
- }
- setCurrentIndex(next);
- }
- }
-
- // Remove all affected editors; this is more efficient than waiting for updateGeometries() to clean out editors for invalid indexes
- QEditorIndexHash::iterator i = d->editorIndexHash.begin();
- while (i != d->editorIndexHash.end()) {
- const QModelIndex index = i.value();
- if (index.row() >= start && index.row() <= end && d->model->parent(index) == parent) {
- QWidget *editor = i.key();
- QEditorInfo info = d->indexEditorHash.take(index);
- i = d->editorIndexHash.erase(i);
- if (info.widget)
- d->releaseEditor(editor);
- } else {
- ++i;
- }
- }
-}
-
-/*!
- \internal
-
- This slot is called when rows have been removed. The deleted
- rows are those under the given \a parent from \a start to \a end
- inclusive.
-*/
-void QAbstractItemViewPrivate::_q_rowsRemoved(const QModelIndex &index, int start, int end)
-{
- Q_UNUSED(index)
- Q_UNUSED(start)
- Q_UNUSED(end)
-
- Q_Q(QAbstractItemView);
- if (q->isVisible())
- q->updateEditorGeometries();
- q->setState(QAbstractItemView::NoState);
-#ifndef QT_NO_ACCESSIBILITY
-#ifdef Q_WS_X11
- if (QAccessible::isActive()) {
- QAccessible::queryAccessibleInterface(q)->table2Interface()->rowsRemoved(index, start, end);
- QAccessible::updateAccessibility(q, 0, QAccessible::TableModelChanged);
- }
-#endif
-#endif
-}
-
-/*!
- \internal
-
- This slot is called when columns are about to be removed. The deleted
- columns are those under the given \a parent from \a start to \a end
- inclusive.
-*/
-void QAbstractItemViewPrivate::_q_columnsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
-{
- Q_Q(QAbstractItemView);
-
- q->setState(QAbstractItemView::CollapsingState);
-
- // Ensure one selected item in single selection mode.
- QModelIndex current = q->currentIndex();
- if (current.isValid()
- && selectionMode == QAbstractItemView::SingleSelection
- && current.column() >= start
- && current.column() <= end) {
- int totalToRemove = end - start + 1;
- if (model->columnCount(parent) < totalToRemove) { // no more columns
- QModelIndex index = parent;
- while (index.isValid() && !isIndexEnabled(index))
- index = index.parent();
- if (index.isValid())
- q->setCurrentIndex(index);
- } else {
- int column = end;
- QModelIndex next;
- do { // find the next visible and enabled item
- next = model->index(current.row(), column++, current.parent());
- } while (next.isValid() && (q->isIndexHidden(next) || !isIndexEnabled(next)));
- q->setCurrentIndex(next);
- }
- }
-
- // Remove all affected editors; this is more efficient than waiting for updateGeometries() to clean out editors for invalid indexes
- QEditorIndexHash::iterator it = editorIndexHash.begin();
- while (it != editorIndexHash.end()) {
- QModelIndex index = it.value();
- if (index.column() <= start && index.column() >= end && model->parent(index) == parent) {
- QWidget *editor = it.key();
- QEditorInfo info = indexEditorHash.take(it.value());
- it = editorIndexHash.erase(it);
- if (info.widget)
- releaseEditor(editor);
- } else {
- ++it;
- }
- }
-
-}
-
-/*!
- \internal
-
- This slot is called when columns have been removed. The deleted
- rows are those under the given \a parent from \a start to \a end
- inclusive.
-*/
-void QAbstractItemViewPrivate::_q_columnsRemoved(const QModelIndex &index, int start, int end)
-{
- Q_UNUSED(index)
- Q_UNUSED(start)
- Q_UNUSED(end)
-
- Q_Q(QAbstractItemView);
- if (q->isVisible())
- q->updateEditorGeometries();
- q->setState(QAbstractItemView::NoState);
-#ifndef QT_NO_ACCESSIBILITY
-#ifdef Q_WS_X11
- if (QAccessible::isActive()) {
- QAccessible::queryAccessibleInterface(q)->table2Interface()->columnsRemoved(index, start, end);
- QAccessible::updateAccessibility(q, 0, QAccessible::TableModelChanged);
- }
-#endif
-#endif
-}
-
-
-/*!
- \internal
-
- This slot is called when rows have been inserted.
-*/
-void QAbstractItemViewPrivate::_q_rowsInserted(const QModelIndex &index, int start, int end)
-{
- Q_UNUSED(index)
- Q_UNUSED(start)
- Q_UNUSED(end)
-
- Q_Q(QAbstractItemView);
-#ifndef QT_NO_ACCESSIBILITY
-#ifdef Q_WS_X11
- if (QAccessible::isActive()) {
- QAccessible::queryAccessibleInterface(q)->table2Interface()->rowsInserted(index, start, end);
- QAccessible::updateAccessibility(q, 0, QAccessible::TableModelChanged);
- }
-#endif
-#endif
-}
-
-/*!
- \internal
-
- This slot is called when columns have been inserted.
-*/
-void QAbstractItemViewPrivate::_q_columnsInserted(const QModelIndex &index, int start, int end)
-{
- Q_UNUSED(index)
- Q_UNUSED(start)
- Q_UNUSED(end)
-
- Q_Q(QAbstractItemView);
- if (q->isVisible())
- q->updateEditorGeometries();
-#ifndef QT_NO_ACCESSIBILITY
-#ifdef Q_WS_X11
- if (QAccessible::isActive()) {
- QAccessible::queryAccessibleInterface(q)->table2Interface()->columnsInserted(index, start, end);
- QAccessible::updateAccessibility(q, 0, QAccessible::TableModelChanged);
- }
-#endif
-#endif
-}
-
-/*!
- \internal
-*/
-void QAbstractItemViewPrivate::_q_modelDestroyed()
-{
- model = QAbstractItemModelPrivate::staticEmptyModel();
- doDelayedReset();
-}
-
-/*!
- \internal
-
- This slot is called when the layout is changed.
-*/
-void QAbstractItemViewPrivate::_q_layoutChanged()
-{
- Q_Q(QAbstractItemView);
- doDelayedItemsLayout();
-#ifndef QT_NO_ACCESSIBILITY
-#ifdef Q_WS_X11
- if (QAccessible::isActive()) {
- QAccessible::queryAccessibleInterface(q)->table2Interface()->modelReset();
- QAccessible::updateAccessibility(q, 0, QAccessible::TableModelChanged);
- }
-#endif
-#endif
-}
-
-/*!
- This slot is called when the selection is changed. The previous
- selection (which may be empty), is specified by \a deselected, and the
- new selection by \a selected.
-
- \sa setSelection()
-*/
-void QAbstractItemView::selectionChanged(const QItemSelection &selected,
- const QItemSelection &deselected)
-{
- Q_D(QAbstractItemView);
- if (isVisible() && updatesEnabled()) {
- d->viewport->update(visualRegionForSelection(deselected) | visualRegionForSelection(selected));
- }
-}
-
-/*!
- This slot is called when a new item becomes the current item.
- The previous current item is specified by the \a previous index, and the new
- item by the \a current index.
-
- If you want to know about changes to items see the
- dataChanged() signal.
-*/
-void QAbstractItemView::currentChanged(const QModelIndex &current, const QModelIndex &previous)
-{
- Q_D(QAbstractItemView);
- Q_ASSERT(d->model);
-
- if (previous.isValid()) {
- QModelIndex buddy = d->model->buddy(previous);
- QWidget *editor = d->editorForIndex(buddy).widget.data();
- if (editor && !d->persistent.contains(editor)) {
- commitData(editor);
- if (current.row() != previous.row())
- closeEditor(editor, QAbstractItemDelegate::SubmitModelCache);
- else
- closeEditor(editor, QAbstractItemDelegate::NoHint);
- }
- if (isVisible()) {
- update(previous);
- }
- }
-
- if (current.isValid() && !d->autoScrollTimer.isActive()) {
- if (isVisible()) {
- if (d->autoScroll)
- scrollTo(current);
- update(current);
- edit(current, CurrentChanged, 0);
- if (current.row() == (d->model->rowCount(d->root) - 1))
- d->fetchMore();
- } else {
- d->shouldScrollToCurrentOnShow = d->autoScroll;
- }
- }
-}
-
-#ifndef QT_NO_DRAGANDDROP
-/*!
- Starts a drag by calling drag->exec() using the given \a supportedActions.
-*/
-void QAbstractItemView::startDrag(Qt::DropActions supportedActions)
-{
- Q_D(QAbstractItemView);
- QModelIndexList indexes = d->selectedDraggableIndexes();
- if (indexes.count() > 0) {
- QMimeData *data = d->model->mimeData(indexes);
- if (!data)
- return;
- QRect rect;
- QPixmap pixmap = d->renderToPixmap(indexes, &rect);
- rect.adjust(horizontalOffset(), verticalOffset(), 0, 0);
- QDrag *drag = new QDrag(this);
- drag->setPixmap(pixmap);
- drag->setMimeData(data);
- drag->setHotSpot(d->pressedPosition - rect.topLeft());
- Qt::DropAction defaultDropAction = Qt::IgnoreAction;
- if (d->defaultDropAction != Qt::IgnoreAction && (supportedActions & d->defaultDropAction))
- defaultDropAction = d->defaultDropAction;
- else if (supportedActions & Qt::CopyAction && dragDropMode() != QAbstractItemView::InternalMove)
- defaultDropAction = Qt::CopyAction;
- if (drag->exec(supportedActions, defaultDropAction) == Qt::MoveAction)
- d->clearOrRemove();
- }
-}
-#endif // QT_NO_DRAGANDDROP
-
-/*!
- Returns a QStyleOptionViewItem structure populated with the view's
- palette, font, state, alignments etc.
-*/
-QStyleOptionViewItem QAbstractItemView::viewOptions() const
-{
- Q_D(const QAbstractItemView);
- QStyleOptionViewItem option;
- option.init(this);
- option.state &= ~QStyle::State_MouseOver;
- option.font = font();
-
-#ifndef Q_WS_MAC
- // On mac the focus appearance follows window activation
- // not widget activation
- if (!hasFocus())
- option.state &= ~QStyle::State_Active;
-#endif
-
- option.state &= ~QStyle::State_HasFocus;
- if (d->iconSize.isValid()) {
- option.decorationSize = d->iconSize;
- } else {
- int pm = style()->pixelMetric(QStyle::PM_SmallIconSize, 0, this);
- option.decorationSize = QSize(pm, pm);
- }
- option.decorationPosition = QStyleOptionViewItem::Left;
- option.decorationAlignment = Qt::AlignCenter;
- option.displayAlignment = Qt::AlignLeft|Qt::AlignVCenter;
- option.textElideMode = d->textElideMode;
- option.rect = QRect();
- option.showDecorationSelected = style()->styleHint(QStyle::SH_ItemView_ShowDecorationSelected, 0, this);
- return option;
-}
-
-QStyleOptionViewItemV4 QAbstractItemViewPrivate::viewOptionsV4() const
-{
- Q_Q(const QAbstractItemView);
- QStyleOptionViewItemV4 option = q->viewOptions();
- if (wrapItemText)
- option.features = QStyleOptionViewItemV2::WrapText;
- option.locale = q->locale();
- option.locale.setNumberOptions(QLocale::OmitGroupSeparator);
- option.widget = q;
- return option;
-}
-
-/*!
- Returns the item view's state.
-
- \sa setState()
-*/
-QAbstractItemView::State QAbstractItemView::state() const
-{
- Q_D(const QAbstractItemView);
- return d->state;
-}
-
-/*!
- Sets the item view's state to the given \a state.
-
- \sa state()
-*/
-void QAbstractItemView::setState(State state)
-{
- Q_D(QAbstractItemView);
- d->state = state;
-}
-
-/*!
- Schedules a layout of the items in the view to be executed when the
- event processing starts.
-
- Even if scheduleDelayedItemsLayout() is called multiple times before
- events are processed, the view will only do the layout once.
-
- \sa executeDelayedItemsLayout()
-*/
-void QAbstractItemView::scheduleDelayedItemsLayout()
-{
- Q_D(QAbstractItemView);
- d->doDelayedItemsLayout();
-}
-
-/*!
- Executes the scheduled layouts without waiting for the event processing
- to begin.
-
- \sa scheduleDelayedItemsLayout()
-*/
-void QAbstractItemView::executeDelayedItemsLayout()
-{
- Q_D(QAbstractItemView);
- d->executePostedLayout();
-}
-
-/*!
- \since 4.1
-
- Marks the given \a region as dirty and schedules it to be updated.
- You only need to call this function if you are implementing
- your own view subclass.
-
- \sa scrollDirtyRegion(), dirtyRegionOffset()
-*/
-
-void QAbstractItemView::setDirtyRegion(const QRegion &region)
-{
- Q_D(QAbstractItemView);
- d->setDirtyRegion(region);
-}
-
-/*!
- Prepares the view for scrolling by (\a{dx},\a{dy}) pixels by moving the dirty regions in the
- opposite direction. You only need to call this function if you are implementing a scrolling
- viewport in your view subclass.
-
- If you implement scrollContentsBy() in a subclass of QAbstractItemView, call this function
- before you call QWidget::scroll() on the viewport. Alternatively, just call update().
-
- \sa scrollContentsBy(), dirtyRegionOffset(), setDirtyRegion()
-*/
-void QAbstractItemView::scrollDirtyRegion(int dx, int dy)
-{
- Q_D(QAbstractItemView);
- d->scrollDirtyRegion(dx, dy);
-}
-
-/*!
- Returns the offset of the dirty regions in the view.
-
- If you use scrollDirtyRegion() and implement a paintEvent() in a subclass of
- QAbstractItemView, you should translate the area given by the paint event with
- the offset returned from this function.
-
- \sa scrollDirtyRegion(), setDirtyRegion()
-*/
-QPoint QAbstractItemView::dirtyRegionOffset() const
-{
- Q_D(const QAbstractItemView);
- return d->scrollDelayOffset;
-}
-
-/*!
- \internal
-*/
-void QAbstractItemView::startAutoScroll()
-{
- d_func()->startAutoScroll();
-}
-
-/*!
- \internal
-*/
-void QAbstractItemView::stopAutoScroll()
-{
- d_func()->stopAutoScroll();
-}
-
-/*!
- \internal
-*/
-void QAbstractItemView::doAutoScroll()
-{
- // find how much we should scroll with
- Q_D(QAbstractItemView);
- int verticalStep = verticalScrollBar()->pageStep();
- int horizontalStep = horizontalScrollBar()->pageStep();
- if (d->autoScrollCount < qMax(verticalStep, horizontalStep))
- ++d->autoScrollCount;
-
- int margin = d->autoScrollMargin;
- int verticalValue = verticalScrollBar()->value();
- int horizontalValue = horizontalScrollBar()->value();
-
- QPoint pos = d->viewport->mapFromGlobal(QCursor::pos());
- QRect area = static_cast<QAbstractItemView*>(d->viewport)->d_func()->clipRect(); // access QWidget private by bending C++ rules
-
- // do the scrolling if we are in the scroll margins
- if (pos.y() - area.top() < margin)
- verticalScrollBar()->setValue(verticalValue - d->autoScrollCount);
- else if (area.bottom() - pos.y() < margin)
- verticalScrollBar()->setValue(verticalValue + d->autoScrollCount);
- if (pos.x() - area.left() < margin)
- horizontalScrollBar()->setValue(horizontalValue - d->autoScrollCount);
- else if (area.right() - pos.x() < margin)
- horizontalScrollBar()->setValue(horizontalValue + d->autoScrollCount);
- // if nothing changed, stop scrolling
- bool verticalUnchanged = (verticalValue == verticalScrollBar()->value());
- bool horizontalUnchanged = (horizontalValue == horizontalScrollBar()->value());
- if (verticalUnchanged && horizontalUnchanged) {
- stopAutoScroll();
- } else {
-#ifndef QT_NO_DRAGANDDROP
- d->dropIndicatorRect = QRect();
- d->dropIndicatorPosition = QAbstractItemView::OnViewport;
-#endif
- d->viewport->update();
- }
-}
-
-/*!
- Returns the SelectionFlags to be used when updating a selection with
- to include the \a index specified. The \a event is a user input event,
- such as a mouse or keyboard event.
-
- Reimplement this function to define your own selection behavior.
-
- \sa setSelection()
-*/
-QItemSelectionModel::SelectionFlags QAbstractItemView::selectionCommand(const QModelIndex &index,
- const QEvent *event) const
-{
- Q_D(const QAbstractItemView);
- switch (d->selectionMode) {
- case NoSelection: // Never update selection model
- return QItemSelectionModel::NoUpdate;
- case SingleSelection: // ClearAndSelect on valid index otherwise NoUpdate
- if (event && event->type() == QEvent::MouseButtonRelease)
- return QItemSelectionModel::NoUpdate;
- return QItemSelectionModel::ClearAndSelect|d->selectionBehaviorFlags();
- case MultiSelection:
- return d->multiSelectionCommand(index, event);
- case ExtendedSelection:
- return d->extendedSelectionCommand(index, event);
- case ContiguousSelection:
- return d->contiguousSelectionCommand(index, event);
- }
- return QItemSelectionModel::NoUpdate;
-}
-
-QItemSelectionModel::SelectionFlags QAbstractItemViewPrivate::multiSelectionCommand(
- const QModelIndex &index, const QEvent *event) const
-{
- Q_UNUSED(index)
-
- if (event) {
- switch (event->type()) {
- case QEvent::KeyPress:
- if (static_cast<const QKeyEvent*>(event)->key() == Qt::Key_Space
- || static_cast<const QKeyEvent*>(event)->key() == Qt::Key_Select)
- return QItemSelectionModel::Toggle|selectionBehaviorFlags();
- break;
- case QEvent::MouseButtonPress:
- if (static_cast<const QMouseEvent*>(event)->button() == Qt::LeftButton)
- return QItemSelectionModel::Toggle|selectionBehaviorFlags(); // toggle
- break;
- case QEvent::MouseButtonRelease:
- if (static_cast<const QMouseEvent*>(event)->button() == Qt::LeftButton)
- return QItemSelectionModel::NoUpdate|selectionBehaviorFlags(); // finalize
- break;
- case QEvent::MouseMove:
- if (static_cast<const QMouseEvent*>(event)->buttons() & Qt::LeftButton)
- return QItemSelectionModel::ToggleCurrent|selectionBehaviorFlags(); // toggle drag select
- default:
- break;
- }
- return QItemSelectionModel::NoUpdate;
- }
-
- return QItemSelectionModel::Toggle|selectionBehaviorFlags();
-}
-
-QItemSelectionModel::SelectionFlags QAbstractItemViewPrivate::extendedSelectionCommand(
- const QModelIndex &index, const QEvent *event) const
-{
- Qt::KeyboardModifiers modifiers = QApplication::keyboardModifiers();
- if (event) {
- switch (event->type()) {
- case QEvent::MouseMove: {
- // Toggle on MouseMove
- modifiers = static_cast<const QMouseEvent*>(event)->modifiers();
- if (modifiers & Qt::ControlModifier)
- return QItemSelectionModel::ToggleCurrent|selectionBehaviorFlags();
- break;
- }
- case QEvent::MouseButtonPress: {
- modifiers = static_cast<const QMouseEvent*>(event)->modifiers();
- const Qt::MouseButton button = static_cast<const QMouseEvent*>(event)->button();
- const bool rightButtonPressed = button & Qt::RightButton;
- const bool shiftKeyPressed = modifiers & Qt::ShiftModifier;
- const bool controlKeyPressed = modifiers & Qt::ControlModifier;
- const bool indexIsSelected = selectionModel->isSelected(index);
- if ((shiftKeyPressed || controlKeyPressed) && rightButtonPressed)
- return QItemSelectionModel::NoUpdate;
- if (!shiftKeyPressed && !controlKeyPressed && indexIsSelected)
- return QItemSelectionModel::NoUpdate;
- if (!index.isValid() && !rightButtonPressed && !shiftKeyPressed && !controlKeyPressed)
- return QItemSelectionModel::Clear;
- if (!index.isValid())
- return QItemSelectionModel::NoUpdate;
- break;
- }
- case QEvent::MouseButtonRelease: {
- // ClearAndSelect on MouseButtonRelease if MouseButtonPress on selected item or empty area
- modifiers = static_cast<const QMouseEvent*>(event)->modifiers();
- const Qt::MouseButton button = static_cast<const QMouseEvent*>(event)->button();
- const bool rightButtonPressed = button & Qt::RightButton;
- const bool shiftKeyPressed = modifiers & Qt::ShiftModifier;
- const bool controlKeyPressed = modifiers & Qt::ControlModifier;
- if (((index == pressedIndex && selectionModel->isSelected(index))
- || !index.isValid()) && state != QAbstractItemView::DragSelectingState
- && !shiftKeyPressed && !controlKeyPressed && (!rightButtonPressed || !index.isValid()))
- return QItemSelectionModel::ClearAndSelect|selectionBehaviorFlags();
- return QItemSelectionModel::NoUpdate;
- }
- case QEvent::KeyPress: {
- // NoUpdate on Key movement and Ctrl
- modifiers = static_cast<const QKeyEvent*>(event)->modifiers();
- switch (static_cast<const QKeyEvent*>(event)->key()) {
- case Qt::Key_Backtab:
- modifiers = modifiers & ~Qt::ShiftModifier; // special case for backtab
- case Qt::Key_Down:
- case Qt::Key_Up:
- case Qt::Key_Left:
- case Qt::Key_Right:
- case Qt::Key_Home:
- case Qt::Key_End:
- case Qt::Key_PageUp:
- case Qt::Key_PageDown:
- case Qt::Key_Tab:
- if (modifiers & Qt::ControlModifier
-#ifdef QT_KEYPAD_NAVIGATION
- // Preserve historical tab order navigation behavior
- || QApplication::navigationMode() == Qt::NavigationModeKeypadTabOrder
-#endif
- )
- return QItemSelectionModel::NoUpdate;
- break;
- case Qt::Key_Select:
- return QItemSelectionModel::Toggle|selectionBehaviorFlags();
- case Qt::Key_Space:// Toggle on Ctrl-Qt::Key_Space, Select on Space
- if (modifiers & Qt::ControlModifier)
- return QItemSelectionModel::Toggle|selectionBehaviorFlags();
- return QItemSelectionModel::Select|selectionBehaviorFlags();
- default:
- break;
- }
- }
- default:
- break;
- }
- }
-
- if (modifiers & Qt::ShiftModifier)
- return QItemSelectionModel::SelectCurrent|selectionBehaviorFlags();
- if (modifiers & Qt::ControlModifier)
- return QItemSelectionModel::Toggle|selectionBehaviorFlags();
- if (state == QAbstractItemView::DragSelectingState) {
- //when drag-selecting we need to clear any previous selection and select the current one
- return QItemSelectionModel::Clear|QItemSelectionModel::SelectCurrent|selectionBehaviorFlags();
- }
-
- return QItemSelectionModel::ClearAndSelect|selectionBehaviorFlags();
-}
-
-QItemSelectionModel::SelectionFlags
-QAbstractItemViewPrivate::contiguousSelectionCommand(const QModelIndex &index,
- const QEvent *event) const
-{
- QItemSelectionModel::SelectionFlags flags = extendedSelectionCommand(index, event);
- const int Mask = QItemSelectionModel::Clear | QItemSelectionModel::Select
- | QItemSelectionModel::Deselect | QItemSelectionModel::Toggle
- | QItemSelectionModel::Current;
-
- switch (flags & Mask) {
- case QItemSelectionModel::Clear:
- case QItemSelectionModel::ClearAndSelect:
- case QItemSelectionModel::SelectCurrent:
- return flags;
- case QItemSelectionModel::NoUpdate:
- if (event &&
- (event->type() == QEvent::MouseButtonPress
- || event->type() == QEvent::MouseButtonRelease))
- return flags;
- return QItemSelectionModel::ClearAndSelect|selectionBehaviorFlags();
- default:
- return QItemSelectionModel::SelectCurrent|selectionBehaviorFlags();
- }
-}
-
-void QAbstractItemViewPrivate::fetchMore()
-{
- fetchMoreTimer.stop();
- if (!model->canFetchMore(root))
- return;
- int last = model->rowCount(root) - 1;
- if (last < 0) {
- model->fetchMore(root);
- return;
- }
-
- QModelIndex index = model->index(last, 0, root);
- QRect rect = q_func()->visualRect(index);
- if (viewport->rect().intersects(rect))
- model->fetchMore(root);
-}
-
-bool QAbstractItemViewPrivate::shouldEdit(QAbstractItemView::EditTrigger trigger,
- const QModelIndex &index) const
-{
- if (!index.isValid())
- return false;
- Qt::ItemFlags flags = model->flags(index);
- if (((flags & Qt::ItemIsEditable) == 0) || ((flags & Qt::ItemIsEnabled) == 0))
- return false;
- if (state == QAbstractItemView::EditingState)
- return false;
- if (hasEditor(index))
- return false;
- if (trigger == QAbstractItemView::AllEditTriggers) // force editing
- return true;
- if ((trigger & editTriggers) == QAbstractItemView::SelectedClicked
- && !selectionModel->isSelected(index))
- return false;
- return (trigger & editTriggers);
-}
-
-bool QAbstractItemViewPrivate::shouldForwardEvent(QAbstractItemView::EditTrigger trigger,
- const QEvent *event) const
-{
- if (!event || (trigger & editTriggers) != QAbstractItemView::AnyKeyPressed)
- return false;
-
- switch (event->type()) {
- case QEvent::KeyPress:
- case QEvent::MouseButtonDblClick:
- case QEvent::MouseButtonPress:
- case QEvent::MouseButtonRelease:
- case QEvent::MouseMove:
- return true;
- default:
- break;
- };
-
- return false;
-}
-
-bool QAbstractItemViewPrivate::shouldAutoScroll(const QPoint &pos) const
-{
- if (!autoScroll)
- return false;
- QRect area = static_cast<QAbstractItemView*>(viewport)->d_func()->clipRect(); // access QWidget private by bending C++ rules
- return (pos.y() - area.top() < autoScrollMargin)
- || (area.bottom() - pos.y() < autoScrollMargin)
- || (pos.x() - area.left() < autoScrollMargin)
- || (area.right() - pos.x() < autoScrollMargin);
-}
-
-void QAbstractItemViewPrivate::doDelayedItemsLayout(int delay)
-{
- if (!delayedPendingLayout) {
- delayedPendingLayout = true;
- delayedLayout.start(delay, q_func());
- }
-}
-
-void QAbstractItemViewPrivate::interruptDelayedItemsLayout() const
-{
- delayedLayout.stop();
- delayedPendingLayout = false;
-}
-
-
-
-QWidget *QAbstractItemViewPrivate::editor(const QModelIndex &index,
- const QStyleOptionViewItem &options)
-{
- Q_Q(QAbstractItemView);
- QWidget *w = editorForIndex(index).widget.data();
- if (!w) {
- QAbstractItemDelegate *delegate = delegateForIndex(index);
- if (!delegate)
- return 0;
- w = delegate->createEditor(viewport, options, index);
- if (w) {
- w->installEventFilter(delegate);
- QObject::connect(w, SIGNAL(destroyed(QObject*)), q, SLOT(editorDestroyed(QObject*)));
- delegate->updateEditorGeometry(w, options, index);
- delegate->setEditorData(w, index);
- addEditor(index, w, false);
- if (w->parent() == viewport)
- QWidget::setTabOrder(q, w);
-
- // Special cases for some editors containing QLineEdit
- QWidget *focusWidget = w;
- while (QWidget *fp = focusWidget->focusProxy())
- focusWidget = fp;
-#ifndef QT_NO_LINEEDIT
- if (QLineEdit *le = qobject_cast<QLineEdit*>(focusWidget))
- le->selectAll();
-#endif
-#ifndef QT_NO_SPINBOX
- if (QSpinBox *sb = qobject_cast<QSpinBox*>(focusWidget))
- sb->selectAll();
- else if (QDoubleSpinBox *dsb = qobject_cast<QDoubleSpinBox*>(focusWidget))
- dsb->selectAll();
-#endif
- }
- }
-
- return w;
-}
-
-void QAbstractItemViewPrivate::updateEditorData(const QModelIndex &tl, const QModelIndex &br)
-{
- // we are counting on having relatively few editors
- const bool checkIndexes = tl.isValid() && br.isValid();
- const QModelIndex parent = tl.parent();
- QIndexEditorHash::const_iterator it = indexEditorHash.constBegin();
- for (; it != indexEditorHash.constEnd(); ++it) {
- QWidget *editor = it.value().widget.data();
- const QModelIndex index = it.key();
- if (it.value().isStatic || !editor || !index.isValid() ||
- (checkIndexes
- && (index.row() < tl.row() || index.row() > br.row()
- || index.column() < tl.column() || index.column() > br.column()
- || index.parent() != parent)))
- continue;
-
- QAbstractItemDelegate *delegate = delegateForIndex(index);
- if (delegate) {
- delegate->setEditorData(editor, index);
- }
- }
-}
-
-/*!
- \internal
-
- In DND if something has been moved then this is called.
- Typically this means you should "remove" the selected item or row,
- but the behavior is view dependant (table just clears the selected indexes for example).
-
- Either remove the selected rows or clear them
-*/
-void QAbstractItemViewPrivate::clearOrRemove()
-{
-#ifndef QT_NO_DRAGANDDROP
- const QItemSelection selection = selectionModel->selection();
- QList<QItemSelectionRange>::const_iterator it = selection.constBegin();
-
- if (!overwrite) {
- for (; it != selection.constEnd(); ++it) {
- QModelIndex parent = (*it).parent();
- if ((*it).left() != 0)
- continue;
- if ((*it).right() != (model->columnCount(parent) - 1))
- continue;
- int count = (*it).bottom() - (*it).top() + 1;
- model->removeRows((*it).top(), count, parent);
- }
- } else {
- // we can't remove the rows so reset the items (i.e. the view is like a table)
- QModelIndexList list = selection.indexes();
- for (int i=0; i < list.size(); ++i) {
- QModelIndex index = list.at(i);
- QMap<int, QVariant> roles = model->itemData(index);
- for (QMap<int, QVariant>::Iterator it = roles.begin(); it != roles.end(); ++it)
- it.value() = QVariant();
- model->setItemData(index, roles);
- }
- }
-#endif
-}
-
-/*!
- \internal
-
- When persistent aeditor gets/loses focus, we need to check
- and setcorrectly the current index.
-*/
-void QAbstractItemViewPrivate::checkPersistentEditorFocus()
-{
- Q_Q(QAbstractItemView);
- if (QWidget *widget = QApplication::focusWidget()) {
- if (persistent.contains(widget)) {
- //a persistent editor has gained the focus
- QModelIndex index = indexForEditor(widget);
- if (selectionModel->currentIndex() != index)
- q->setCurrentIndex(index);
- }
- }
-}
-
-
-const QEditorInfo & QAbstractItemViewPrivate::editorForIndex(const QModelIndex &index) const
-{
- static QEditorInfo nullInfo;
-
- QIndexEditorHash::const_iterator it = indexEditorHash.find(index);
- if (it == indexEditorHash.end())
- return nullInfo;
-
- return it.value();
-}
-
-QModelIndex QAbstractItemViewPrivate::indexForEditor(QWidget *editor) const
-{
- QEditorIndexHash::const_iterator it = editorIndexHash.find(editor);
- if (it == editorIndexHash.end())
- return QModelIndex();
-
- return it.value();
-}
-
-void QAbstractItemViewPrivate::removeEditor(QWidget *editor)
-{
- QEditorIndexHash::iterator it = editorIndexHash.find(editor);
- if (it != editorIndexHash.end())
- {
- indexEditorHash.remove(it.value());
- editorIndexHash.erase(it);
- }
-}
-
-void QAbstractItemViewPrivate::addEditor(const QModelIndex &index, QWidget *editor, bool isStatic)
-{
- editorIndexHash.insert(editor, index);
- indexEditorHash.insert(index, QEditorInfo(editor, isStatic));
-}
-
-bool QAbstractItemViewPrivate::sendDelegateEvent(const QModelIndex &index, QEvent *event) const
-{
- Q_Q(const QAbstractItemView);
- QModelIndex buddy = model->buddy(index);
- QStyleOptionViewItemV4 options = viewOptionsV4();
- options.rect = q->visualRect(buddy);
- options.state |= (buddy == q->currentIndex() ? QStyle::State_HasFocus : QStyle::State_None);
- QAbstractItemDelegate *delegate = delegateForIndex(index);
- return (event && delegate && delegate->editorEvent(event, model, options, buddy));
-}
-
-bool QAbstractItemViewPrivate::openEditor(const QModelIndex &index, QEvent *event)
-{
- Q_Q(QAbstractItemView);
-
- QModelIndex buddy = model->buddy(index);
- QStyleOptionViewItemV4 options = viewOptionsV4();
- options.rect = q->visualRect(buddy);
- options.state |= (buddy == q->currentIndex() ? QStyle::State_HasFocus : QStyle::State_None);
-
- QWidget *w = editor(buddy, options);
- if (!w)
- return false;
-
- q->setState(QAbstractItemView::EditingState);
- w->show();
- w->setFocus();
-
- if (event)
- QApplication::sendEvent(w->focusProxy() ? w->focusProxy() : w, event);
-
- return true;
-}
-
-/*
- \internal
-
- returns the pair QRect/QModelIndex that should be painted on the viewports's rect
-*/
-
-QItemViewPaintPairs QAbstractItemViewPrivate::draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const
-{
- Q_ASSERT(r);
- Q_Q(const QAbstractItemView);
- QRect &rect = *r;
- const QRect viewportRect = viewport->rect();
- QItemViewPaintPairs ret;
- for (int i = 0; i < indexes.count(); ++i) {
- const QModelIndex &index = indexes.at(i);
- const QRect current = q->visualRect(index);
- if (current.intersects(viewportRect)) {
- ret += qMakePair(current, index);
- rect |= current;
- }
- }
- rect &= viewportRect;
- return ret;
-}
-
-QPixmap QAbstractItemViewPrivate::renderToPixmap(const QModelIndexList &indexes, QRect *r) const
-{
- Q_ASSERT(r);
- QItemViewPaintPairs paintPairs = draggablePaintPairs(indexes, r);
- if (paintPairs.isEmpty())
- return QPixmap();
- QPixmap pixmap(r->size());
- pixmap.fill(Qt::transparent);
- QPainter painter(&pixmap);
- QStyleOptionViewItemV4 option = viewOptionsV4();
- option.state |= QStyle::State_Selected;
- for (int j = 0; j < paintPairs.count(); ++j) {
- option.rect = paintPairs.at(j).first.translated(-r->topLeft());
- const QModelIndex &current = paintPairs.at(j).second;
- delegateForIndex(current)->paint(&painter, option, current);
- }
- return pixmap;
-}
-
-void QAbstractItemViewPrivate::selectAll(QItemSelectionModel::SelectionFlags command)
-{
- if (!selectionModel)
- return;
-
- QItemSelection selection;
- QModelIndex tl = model->index(0, 0, root);
- QModelIndex br = model->index(model->rowCount(root) - 1,
- model->columnCount(root) - 1,
- root);
- selection.append(QItemSelectionRange(tl, br));
- selectionModel->select(selection, command);
-}
-
-QModelIndexList QAbstractItemViewPrivate::selectedDraggableIndexes() const
-{
- Q_Q(const QAbstractItemView);
- QModelIndexList indexes = q->selectedIndexes();
- for(int i = indexes.count() - 1 ; i >= 0; --i) {
- if (!isIndexDragEnabled(indexes.at(i)))
- indexes.removeAt(i);
- }
- return indexes;
-}
-
-
-QT_END_NAMESPACE
-
-#include "moc_qabstractitemview.cpp"
-
-#endif // QT_NO_ITEMVIEWS
diff --git a/src/gui/itemviews/qabstractitemview.h b/src/gui/itemviews/qabstractitemview.h
deleted file mode 100644
index e49ce0b6d0..0000000000
--- a/src/gui/itemviews/qabstractitemview.h
+++ /dev/null
@@ -1,381 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QABSTRACTITEMVIEW_H
-#define QABSTRACTITEMVIEW_H
-
-#include <QtGui/qabstractscrollarea.h>
-#include <QtCore/qabstractitemmodel.h>
-#include <QtGui/qitemselectionmodel.h>
-#include <QtGui/qabstractitemdelegate.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_ITEMVIEWS
-
-class QMenu;
-class QDrag;
-class QEvent;
-class QAbstractItemViewPrivate;
-
-class Q_GUI_EXPORT QAbstractItemView : public QAbstractScrollArea
-{
- Q_OBJECT
- Q_ENUMS(SelectionMode SelectionBehavior ScrollHint ScrollMode DragDropMode)
- Q_FLAGS(EditTriggers)
- Q_PROPERTY(bool autoScroll READ hasAutoScroll WRITE setAutoScroll)
- Q_PROPERTY(int autoScrollMargin READ autoScrollMargin WRITE setAutoScrollMargin)
- Q_PROPERTY(EditTriggers editTriggers READ editTriggers WRITE setEditTriggers)
- Q_PROPERTY(bool tabKeyNavigation READ tabKeyNavigation WRITE setTabKeyNavigation)
-#ifndef QT_NO_DRAGANDDROP
- Q_PROPERTY(bool showDropIndicator READ showDropIndicator WRITE setDropIndicatorShown)
- Q_PROPERTY(bool dragEnabled READ dragEnabled WRITE setDragEnabled)
- Q_PROPERTY(bool dragDropOverwriteMode READ dragDropOverwriteMode WRITE setDragDropOverwriteMode)
- Q_PROPERTY(DragDropMode dragDropMode READ dragDropMode WRITE setDragDropMode)
- Q_PROPERTY(Qt::DropAction defaultDropAction READ defaultDropAction WRITE setDefaultDropAction)
-#endif
- Q_PROPERTY(bool alternatingRowColors READ alternatingRowColors WRITE setAlternatingRowColors)
- Q_PROPERTY(SelectionMode selectionMode READ selectionMode WRITE setSelectionMode)
- Q_PROPERTY(SelectionBehavior selectionBehavior READ selectionBehavior WRITE setSelectionBehavior)
- Q_PROPERTY(QSize iconSize READ iconSize WRITE setIconSize)
- Q_PROPERTY(Qt::TextElideMode textElideMode READ textElideMode WRITE setTextElideMode)
- Q_PROPERTY(ScrollMode verticalScrollMode READ verticalScrollMode WRITE setVerticalScrollMode)
- Q_PROPERTY(ScrollMode horizontalScrollMode READ horizontalScrollMode WRITE setHorizontalScrollMode)
-
-public:
- enum SelectionMode {
- NoSelection,
- SingleSelection,
- MultiSelection,
- ExtendedSelection,
- ContiguousSelection
- };
-
- enum SelectionBehavior {
- SelectItems,
- SelectRows,
- SelectColumns
- };
-
- enum ScrollHint {
- EnsureVisible,
- PositionAtTop,
- PositionAtBottom,
- PositionAtCenter
- };
-
- enum EditTrigger {
- NoEditTriggers = 0,
- CurrentChanged = 1,
- DoubleClicked = 2,
- SelectedClicked = 4,
- EditKeyPressed = 8,
- AnyKeyPressed = 16,
- AllEditTriggers = 31
- };
-
- Q_DECLARE_FLAGS(EditTriggers, EditTrigger)
-
- enum ScrollMode {
- ScrollPerItem,
- ScrollPerPixel
- };
-
- explicit QAbstractItemView(QWidget *parent = 0);
- ~QAbstractItemView();
-
- virtual void setModel(QAbstractItemModel *model);
- QAbstractItemModel *model() const;
-
- virtual void setSelectionModel(QItemSelectionModel *selectionModel);
- QItemSelectionModel *selectionModel() const;
-
- void setItemDelegate(QAbstractItemDelegate *delegate);
- QAbstractItemDelegate *itemDelegate() const;
-
- void setSelectionMode(QAbstractItemView::SelectionMode mode);
- QAbstractItemView::SelectionMode selectionMode() const;
-
- void setSelectionBehavior(QAbstractItemView::SelectionBehavior behavior);
- QAbstractItemView::SelectionBehavior selectionBehavior() const;
-
- QModelIndex currentIndex() const;
- QModelIndex rootIndex() const;
-
- void setEditTriggers(EditTriggers triggers);
- EditTriggers editTriggers() const;
-
- void setVerticalScrollMode(ScrollMode mode);
- ScrollMode verticalScrollMode() const;
-
- void setHorizontalScrollMode(ScrollMode mode);
- ScrollMode horizontalScrollMode() const;
-
- void setAutoScroll(bool enable);
- bool hasAutoScroll() const;
-
- void setAutoScrollMargin(int margin);
- int autoScrollMargin() const;
-
- void setTabKeyNavigation(bool enable);
- bool tabKeyNavigation() const;
-
-#ifndef QT_NO_DRAGANDDROP
- void setDropIndicatorShown(bool enable);
- bool showDropIndicator() const;
-
- void setDragEnabled(bool enable);
- bool dragEnabled() const;
-
- void setDragDropOverwriteMode(bool overwrite);
- bool dragDropOverwriteMode() const;
-
- enum DragDropMode {
- NoDragDrop,
- DragOnly,
- DropOnly,
- DragDrop,
- InternalMove
- };
-
- void setDragDropMode(DragDropMode behavior);
- DragDropMode dragDropMode() const;
-
- void setDefaultDropAction(Qt::DropAction dropAction);
- Qt::DropAction defaultDropAction() const;
-#endif
-
- void setAlternatingRowColors(bool enable);
- bool alternatingRowColors() const;
-
- void setIconSize(const QSize &size);
- QSize iconSize() const;
-
- void setTextElideMode(Qt::TextElideMode mode);
- Qt::TextElideMode textElideMode() const;
-
- virtual void keyboardSearch(const QString &search);
-
- virtual QRect visualRect(const QModelIndex &index) const = 0;
- virtual void scrollTo(const QModelIndex &index, ScrollHint hint = EnsureVisible) = 0;
- virtual QModelIndex indexAt(const QPoint &point) const = 0;
-
- QSize sizeHintForIndex(const QModelIndex &index) const;
- virtual int sizeHintForRow(int row) const;
- virtual int sizeHintForColumn(int column) const;
-
- void openPersistentEditor(const QModelIndex &index);
- void closePersistentEditor(const QModelIndex &index);
-
- void setIndexWidget(const QModelIndex &index, QWidget *widget);
- QWidget *indexWidget(const QModelIndex &index) const;
-
- void setItemDelegateForRow(int row, QAbstractItemDelegate *delegate);
- QAbstractItemDelegate *itemDelegateForRow(int row) const;
-
- void setItemDelegateForColumn(int column, QAbstractItemDelegate *delegate);
- QAbstractItemDelegate *itemDelegateForColumn(int column) const;
-
- QAbstractItemDelegate *itemDelegate(const QModelIndex &index) const;
-
- virtual QVariant inputMethodQuery(Qt::InputMethodQuery query) const;
-
-#ifdef Q_NO_USING_KEYWORD
- inline void update() { QAbstractScrollArea::update(); }
-#else
- using QAbstractScrollArea::update;
-#endif
-
-public Q_SLOTS:
- virtual void reset();
- virtual void setRootIndex(const QModelIndex &index);
- virtual void doItemsLayout();
- virtual void selectAll();
- void edit(const QModelIndex &index);
- void clearSelection();
- void setCurrentIndex(const QModelIndex &index);
- void scrollToTop();
- void scrollToBottom();
- void update(const QModelIndex &index);
-
-protected Q_SLOTS:
- virtual void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
- virtual void rowsInserted(const QModelIndex &parent, int start, int end);
- virtual void rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end);
- virtual void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
- virtual void currentChanged(const QModelIndex &current, const QModelIndex &previous);
- virtual void updateEditorData();
- virtual void updateEditorGeometries();
- virtual void updateGeometries();
- virtual void verticalScrollbarAction(int action);
- virtual void horizontalScrollbarAction(int action);
- virtual void verticalScrollbarValueChanged(int value);
- virtual void horizontalScrollbarValueChanged(int value);
- virtual void closeEditor(QWidget *editor, QAbstractItemDelegate::EndEditHint hint);
- virtual void commitData(QWidget *editor);
- virtual void editorDestroyed(QObject *editor);
-
-Q_SIGNALS:
- void pressed(const QModelIndex &index);
- void clicked(const QModelIndex &index);
- void doubleClicked(const QModelIndex &index);
-
- void activated(const QModelIndex &index);
- void entered(const QModelIndex &index);
- void viewportEntered();
-
-protected:
- QAbstractItemView(QAbstractItemViewPrivate &, QWidget *parent = 0);
-
- void setHorizontalStepsPerItem(int steps);
- int horizontalStepsPerItem() const;
- void setVerticalStepsPerItem(int steps);
- int verticalStepsPerItem() const;
-
- enum CursorAction { MoveUp, MoveDown, MoveLeft, MoveRight,
- MoveHome, MoveEnd, MovePageUp, MovePageDown,
- MoveNext, MovePrevious };
- virtual QModelIndex moveCursor(CursorAction cursorAction,
- Qt::KeyboardModifiers modifiers) = 0;
-
- virtual int horizontalOffset() const = 0;
- virtual int verticalOffset() const = 0;
-
- virtual bool isIndexHidden(const QModelIndex &index) const = 0;
-
- virtual void setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags command) = 0;
- virtual QRegion visualRegionForSelection(const QItemSelection &selection) const = 0;
- virtual QModelIndexList selectedIndexes() const;
-
- virtual bool edit(const QModelIndex &index, EditTrigger trigger, QEvent *event);
-
- virtual QItemSelectionModel::SelectionFlags selectionCommand(const QModelIndex &index,
- const QEvent *event = 0) const;
-
-#ifndef QT_NO_DRAGANDDROP
- virtual void startDrag(Qt::DropActions supportedActions);
-#endif
-
- virtual QStyleOptionViewItem viewOptions() const;
-
- enum State {
- NoState,
- DraggingState,
- DragSelectingState,
- EditingState,
- ExpandingState,
- CollapsingState,
- AnimatingState
- };
-
- State state() const;
- void setState(State state);
-
- void scheduleDelayedItemsLayout();
- void executeDelayedItemsLayout();
-
- void setDirtyRegion(const QRegion &region);
- void scrollDirtyRegion(int dx, int dy);
- QPoint dirtyRegionOffset() const;
-
- void startAutoScroll();
- void stopAutoScroll();
- void doAutoScroll();
-
- bool focusNextPrevChild(bool next);
- bool event(QEvent *event);
- bool viewportEvent(QEvent *event);
- void mousePressEvent(QMouseEvent *event);
- void mouseMoveEvent(QMouseEvent *event);
- void mouseReleaseEvent(QMouseEvent *event);
- void mouseDoubleClickEvent(QMouseEvent *event);
-#ifndef QT_NO_DRAGANDDROP
- void dragEnterEvent(QDragEnterEvent *event);
- void dragMoveEvent(QDragMoveEvent *event);
- void dragLeaveEvent(QDragLeaveEvent *event);
- void dropEvent(QDropEvent *event);
-#endif
- void focusInEvent(QFocusEvent *event);
- void focusOutEvent(QFocusEvent *event);
- void keyPressEvent(QKeyEvent *event);
- void resizeEvent(QResizeEvent *event);
- void timerEvent(QTimerEvent *event);
- void inputMethodEvent(QInputMethodEvent *event);
-
-#ifndef QT_NO_DRAGANDDROP
- enum DropIndicatorPosition { OnItem, AboveItem, BelowItem, OnViewport };
- DropIndicatorPosition dropIndicatorPosition() const;
-#endif
-
-private:
- Q_DECLARE_PRIVATE(QAbstractItemView)
- Q_DISABLE_COPY(QAbstractItemView)
- Q_PRIVATE_SLOT(d_func(), void _q_columnsAboutToBeRemoved(const QModelIndex&, int, int))
- Q_PRIVATE_SLOT(d_func(), void _q_columnsRemoved(const QModelIndex&, int, int))
- Q_PRIVATE_SLOT(d_func(), void _q_columnsInserted(const QModelIndex&, int, int))
- Q_PRIVATE_SLOT(d_func(), void _q_rowsInserted(const QModelIndex&, int, int))
- Q_PRIVATE_SLOT(d_func(), void _q_rowsRemoved(const QModelIndex&, int, int))
- Q_PRIVATE_SLOT(d_func(), void _q_modelDestroyed())
- Q_PRIVATE_SLOT(d_func(), void _q_layoutChanged())
- Q_PRIVATE_SLOT(d_func(), void _q_headerDataChanged())
-#ifndef QT_NO_GESTURES
- Q_PRIVATE_SLOT(d_func(), void _q_scrollerStateChanged())
-#endif
-
- friend class QTreeViewPrivate; // needed to compile with MSVC
- friend class QAccessibleItemRow;
- friend class QListModeViewBase;
- friend class QListViewPrivate; // needed to compile for Symbian emulator
-};
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QAbstractItemView::EditTriggers)
-
-#endif // QT_NO_ITEMVIEWS
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QABSTRACTITEMVIEW_H
diff --git a/src/gui/itemviews/qabstractitemview_p.h b/src/gui/itemviews/qabstractitemview_p.h
deleted file mode 100644
index c1b4ca3e12..0000000000
--- a/src/gui/itemviews/qabstractitemview_p.h
+++ /dev/null
@@ -1,458 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QABSTRACTITEMVIEW_P_H
-#define QABSTRACTITEMVIEW_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "private/qabstractscrollarea_p.h"
-#include "private/qabstractitemmodel_p.h"
-#include "QtGui/qapplication.h"
-#include "QtGui/qevent.h"
-#include "QtGui/qmime.h"
-#include "QtGui/qpainter.h"
-#include "QtCore/qpair.h"
-#include "QtGui/qregion.h"
-#include "QtCore/qdebug.h"
-#include "QtGui/qpainter.h"
-#include "QtCore/qbasictimer.h"
-#include "QtCore/qelapsedtimer.h"
-
-#ifndef QT_NO_ITEMVIEWS
-
-QT_BEGIN_NAMESPACE
-
-struct QEditorInfo {
- QEditorInfo(QWidget *e, bool s): widget(QWeakPointer<QWidget>(e)), isStatic(s) {}
- QEditorInfo(): isStatic(false) {}
-
- QWeakPointer<QWidget> widget;
- bool isStatic;
-};
-
-// Fast associativity between Persistent editors and indices.
-typedef QHash<QWidget *, QPersistentModelIndex> QEditorIndexHash;
-typedef QHash<QPersistentModelIndex, QEditorInfo> QIndexEditorHash;
-
-typedef QPair<QRect, QModelIndex> QItemViewPaintPair;
-typedef QList<QItemViewPaintPair> QItemViewPaintPairs;
-
-class QEmptyModel : public QAbstractItemModel
-{
-public:
- explicit QEmptyModel(QObject *parent = 0) : QAbstractItemModel(parent) {}
- QModelIndex index(int, int, const QModelIndex &) const { return QModelIndex(); }
- QModelIndex parent(const QModelIndex &) const { return QModelIndex(); }
- int rowCount(const QModelIndex &) const { return 0; }
- int columnCount(const QModelIndex &) const { return 0; }
- bool hasChildren(const QModelIndex &) const { return false; }
- QVariant data(const QModelIndex &, int) const { return QVariant(); }
-};
-
-class Q_AUTOTEST_EXPORT QAbstractItemViewPrivate : public QAbstractScrollAreaPrivate
-{
- Q_DECLARE_PUBLIC(QAbstractItemView)
-
-public:
- QAbstractItemViewPrivate();
- virtual ~QAbstractItemViewPrivate();
-
- void init();
-
- virtual void _q_rowsRemoved(const QModelIndex &parent, int start, int end);
- virtual void _q_rowsInserted(const QModelIndex &parent, int start, int end);
- virtual void _q_columnsAboutToBeRemoved(const QModelIndex &parent, int start, int end);
- virtual void _q_columnsRemoved(const QModelIndex &parent, int start, int end);
- virtual void _q_columnsInserted(const QModelIndex &parent, int start, int end);
- virtual void _q_modelDestroyed();
- virtual void _q_layoutChanged();
- void _q_headerDataChanged() { doDelayedItemsLayout(); }
- void _q_scrollerStateChanged();
-
- void fetchMore();
-
- bool shouldEdit(QAbstractItemView::EditTrigger trigger, const QModelIndex &index) const;
- bool shouldForwardEvent(QAbstractItemView::EditTrigger trigger, const QEvent *event) const;
- bool shouldAutoScroll(const QPoint &pos) const;
- void doDelayedItemsLayout(int delay = 0);
- void interruptDelayedItemsLayout() const;
-
- void startAutoScroll()
- { // ### it would be nice to make this into a style hint one day
- int scrollInterval = (verticalScrollMode == QAbstractItemView::ScrollPerItem) ? 150 : 50;
- autoScrollTimer.start(scrollInterval, q_func());
- autoScrollCount = 0;
- }
- void stopAutoScroll() { autoScrollTimer.stop(); autoScrollCount = 0;}
-
-#ifndef QT_NO_DRAGANDDROP
- virtual bool dropOn(QDropEvent *event, int *row, int *col, QModelIndex *index);
-#endif
- bool droppingOnItself(QDropEvent *event, const QModelIndex &index);
-
- QWidget *editor(const QModelIndex &index, const QStyleOptionViewItem &options);
- bool sendDelegateEvent(const QModelIndex &index, QEvent *event) const;
- bool openEditor(const QModelIndex &index, QEvent *event);
- void updateEditorData(const QModelIndex &topLeft, const QModelIndex &bottomRight);
-
- QItemSelectionModel::SelectionFlags multiSelectionCommand(const QModelIndex &index,
- const QEvent *event) const;
- QItemSelectionModel::SelectionFlags extendedSelectionCommand(const QModelIndex &index,
- const QEvent *event) const;
- QItemSelectionModel::SelectionFlags contiguousSelectionCommand(const QModelIndex &index,
- const QEvent *event) const;
- virtual void selectAll(QItemSelectionModel::SelectionFlags command);
-
- void setHoverIndex(const QPersistentModelIndex &index);
-
- void checkMouseMove(const QPersistentModelIndex &index);
- inline void checkMouseMove(const QPoint &pos) { checkMouseMove(q_func()->indexAt(pos)); }
-
- inline QItemSelectionModel::SelectionFlags selectionBehaviorFlags() const
- {
- switch (selectionBehavior) {
- case QAbstractItemView::SelectRows: return QItemSelectionModel::Rows;
- case QAbstractItemView::SelectColumns: return QItemSelectionModel::Columns;
- case QAbstractItemView::SelectItems: default: return QItemSelectionModel::NoUpdate;
- }
- }
-
-#ifndef QT_NO_DRAGANDDROP
- virtual QAbstractItemView::DropIndicatorPosition position(const QPoint &pos, const QRect &rect, const QModelIndex &idx) const;
-
- inline bool canDecode(QDropEvent *e) const {
- QStringList modelTypes = model->mimeTypes();
- const QMimeData *mime = e->mimeData();
- for (int i = 0; i < modelTypes.count(); ++i)
- if (mime->hasFormat(modelTypes.at(i))
- && (e->dropAction() & model->supportedDropActions()))
- return true;
- return false;
- }
-
- inline void paintDropIndicator(QPainter *painter)
- {
- if (showDropIndicator && state == QAbstractItemView::DraggingState
-#ifndef QT_NO_CURSOR
- && viewport->cursor().shape() != Qt::ForbiddenCursor
-#endif
- ) {
- QStyleOption opt;
- opt.init(q_func());
- opt.rect = dropIndicatorRect;
- q_func()->style()->drawPrimitive(QStyle::PE_IndicatorItemViewItemDrop, &opt, painter, q_func());
- }
- }
-
-#endif
- virtual QItemViewPaintPairs draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const;
-
- inline void releaseEditor(QWidget *editor) const {
- if (editor) {
- QObject::disconnect(editor, SIGNAL(destroyed(QObject*)),
- q_func(), SLOT(editorDestroyed(QObject*)));
- editor->removeEventFilter(itemDelegate);
- editor->hide();
- editor->deleteLater();
- }
- }
-
- inline void executePostedLayout() const {
- if (delayedPendingLayout && state != QAbstractItemView::CollapsingState) {
- interruptDelayedItemsLayout();
- const_cast<QAbstractItemView*>(q_func())->doItemsLayout();
- }
- }
-
- inline void setDirtyRegion(const QRegion &visualRegion) {
- updateRegion += visualRegion;
- if (!updateTimer.isActive())
- updateTimer.start(0, q_func());
- }
-
- inline void scrollDirtyRegion(int dx, int dy) {
- scrollDelayOffset = QPoint(-dx, -dy);
- updateDirtyRegion();
- scrollDelayOffset = QPoint(0, 0);
- }
-
- inline void scrollContentsBy(int dx, int dy) {
- scrollDirtyRegion(dx, dy);
- viewport->scroll(dx, dy);
- }
-
- void updateDirtyRegion() {
- updateTimer.stop();
- viewport->update(updateRegion);
- updateRegion = QRegion();
- }
-
- void clearOrRemove();
- void checkPersistentEditorFocus();
-
- QPixmap renderToPixmap(const QModelIndexList &indexes, QRect *r) const;
-
- inline QPoint offset() const {
- const Q_Q(QAbstractItemView);
- return QPoint(q->isRightToLeft() ? -q->horizontalOffset()
- : q->horizontalOffset(), q->verticalOffset());
- }
-
- const QEditorInfo &editorForIndex(const QModelIndex &index) const;
- inline bool hasEditor(const QModelIndex &index) const {
- return indexEditorHash.find(index) != indexEditorHash.constEnd();
- }
-
- QModelIndex indexForEditor(QWidget *editor) const;
- void addEditor(const QModelIndex &index, QWidget *editor, bool isStatic);
- void removeEditor(QWidget *editor);
-
- inline bool isAnimating() const {
- return state == QAbstractItemView::AnimatingState;
- }
-
- inline QAbstractItemDelegate *delegateForIndex(const QModelIndex &index) const {
- QAbstractItemDelegate *del;
- if ((del = rowDelegates.value(index.row(), 0))) return del;
- if ((del = columnDelegates.value(index.column(), 0))) return del;
- return itemDelegate;
- }
-
- inline bool isIndexValid(const QModelIndex &index) const {
- return (index.row() >= 0) && (index.column() >= 0) && (index.model() == model);
- }
- inline bool isIndexSelectable(const QModelIndex &index) const {
- return (model->flags(index) & Qt::ItemIsSelectable);
- }
- inline bool isIndexEnabled(const QModelIndex &index) const {
- return (model->flags(index) & Qt::ItemIsEnabled);
- }
- inline bool isIndexDropEnabled(const QModelIndex &index) const {
- return (model->flags(index) & Qt::ItemIsDropEnabled);
- }
- inline bool isIndexDragEnabled(const QModelIndex &index) const {
- return (model->flags(index) & Qt::ItemIsDragEnabled);
- }
-
- virtual bool selectionAllowed(const QModelIndex &index) const {
- // in some views we want to go ahead with selections, even if the index is invalid
- return isIndexValid(index) && isIndexSelectable(index);
- }
-
- // reimplemented from QAbstractScrollAreaPrivate
- virtual QPoint contentsOffset() const {
- Q_Q(const QAbstractItemView);
- return QPoint(q->horizontalOffset(), q->verticalOffset());
- }
-
- /**
- * For now, assume that we have few editors, if we need a more efficient implementation
- * we should add a QMap<QAbstractItemDelegate*, int> member.
- */
- int delegateRefCount(const QAbstractItemDelegate *delegate) const
- {
- int ref = 0;
- if (itemDelegate == delegate)
- ++ref;
-
- for (int maps = 0; maps < 2; ++maps) {
- const QMap<int, QPointer<QAbstractItemDelegate> > *delegates = maps ? &columnDelegates : &rowDelegates;
- for (QMap<int, QPointer<QAbstractItemDelegate> >::const_iterator it = delegates->begin();
- it != delegates->end(); ++it) {
- if (it.value() == delegate) {
- ++ref;
- // optimization, we are only interested in the ref count values 0, 1 or >=2
- if (ref >= 2) {
- return ref;
- }
- }
- }
- }
- return ref;
- }
-
- /**
- * return true if the index is registered as a QPersistentModelIndex
- */
- inline bool isPersistent(const QModelIndex &index) const
- {
- return static_cast<QAbstractItemModelPrivate *>(model->d_ptr.data())->persistent.indexes.contains(index);
- }
-
- QModelIndexList selectedDraggableIndexes() const;
-
- QStyleOptionViewItemV4 viewOptionsV4() const;
-
- void doDelayedReset()
- {
- //we delay the reset of the timer because some views (QTableView)
- //with headers can't handle the fact that the model has been destroyed
- //all _q_modelDestroyed slots must have been called
- if (!delayedReset.isActive())
- delayedReset.start(0, q_func());
- }
-
- QAbstractItemModel *model;
- QPointer<QAbstractItemDelegate> itemDelegate;
- QMap<int, QPointer<QAbstractItemDelegate> > rowDelegates;
- QMap<int, QPointer<QAbstractItemDelegate> > columnDelegates;
- QPointer<QItemSelectionModel> selectionModel;
- QItemSelectionModel::SelectionFlag ctrlDragSelectionFlag;
- bool noSelectionOnMousePress;
-
- QAbstractItemView::SelectionMode selectionMode;
- QAbstractItemView::SelectionBehavior selectionBehavior;
-
- QEditorIndexHash editorIndexHash;
- QIndexEditorHash indexEditorHash;
- QSet<QWidget*> persistent;
- QWidget *currentlyCommittingEditor;
-
- QPersistentModelIndex enteredIndex;
- QPersistentModelIndex pressedIndex;
- Qt::KeyboardModifiers pressedModifiers;
- QPoint pressedPosition;
- bool pressedAlreadySelected;
-
- //forces the next mouseMoveEvent to send the viewportEntered signal
- //if the mouse is over the viewport and not over an item
- bool viewportEnteredNeeded;
-
- QAbstractItemView::State state;
- QAbstractItemView::State stateBeforeAnimation;
- QAbstractItemView::EditTriggers editTriggers;
- QAbstractItemView::EditTrigger lastTrigger;
-
- QPersistentModelIndex root;
- QPersistentModelIndex hover;
-
- bool tabKeyNavigation;
-
-#ifndef QT_NO_DRAGANDDROP
- bool showDropIndicator;
- QRect dropIndicatorRect;
- bool dragEnabled;
- QAbstractItemView::DragDropMode dragDropMode;
- bool overwrite;
- QAbstractItemView::DropIndicatorPosition dropIndicatorPosition;
- Qt::DropAction defaultDropAction;
-#endif
-
-#ifdef QT_SOFTKEYS_ENABLED
- QAction *doneSoftKey;
-#endif
-
- QString keyboardInput;
- QElapsedTimer keyboardInputTime;
-
- bool autoScroll;
- QBasicTimer autoScrollTimer;
- int autoScrollMargin;
- int autoScrollCount;
- bool shouldScrollToCurrentOnShow; //used to know if we should scroll to current on show event
- bool shouldClearStatusTip; //if there is a statustip currently shown that need to be cleared when leaving.
-
- bool alternatingColors;
-
- QSize iconSize;
- Qt::TextElideMode textElideMode;
-
- QRegion updateRegion; // used for the internal update system
- QPoint scrollDelayOffset;
-
- QBasicTimer updateTimer;
- QBasicTimer delayedEditing;
- QBasicTimer delayedAutoScroll; //used when an item is clicked
- QBasicTimer delayedReset;
-
- QAbstractItemView::ScrollMode verticalScrollMode;
- QAbstractItemView::ScrollMode horizontalScrollMode;
-
-#ifndef QT_NO_GESTURES
- // the selection before the last mouse down. In case we have to restore it for scrolling
- QItemSelection oldSelection;
- QModelIndex oldCurrent;
-#endif
-
- bool currentIndexSet;
-
- bool wrapItemText;
- mutable bool delayedPendingLayout;
- bool moveCursorUpdatedView;
-
-private:
- mutable QBasicTimer delayedLayout;
- mutable QBasicTimer fetchMoreTimer;
-};
-
-QT_BEGIN_INCLUDE_NAMESPACE
-#include <qvector.h>
-QT_END_INCLUDE_NAMESPACE
-
-template <typename T>
-inline int qBinarySearch(const QVector<T> &vec, const T &item, int start, int end)
-{
- int i = (start + end + 1) >> 1;
- while (end - start > 0) {
- if (vec.at(i) > item)
- end = i - 1;
- else
- start = i;
- i = (start + end + 1) >> 1;
- }
- return i;
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_ITEMVIEWS
-
-#endif // QABSTRACTITEMVIEW_P_H
diff --git a/src/gui/itemviews/qabstractproxymodel.h b/src/gui/itemviews/qabstractproxymodel.h
deleted file mode 100644
index 1c2c8ea722..0000000000
--- a/src/gui/itemviews/qabstractproxymodel.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QABSTRACTPROXYMODEL_H
-#define QABSTRACTPROXYMODEL_H
-
-#include <QtCore/qabstractitemmodel.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_PROXYMODEL
-
-class QAbstractProxyModelPrivate;
-class QItemSelection;
-
-class Q_GUI_EXPORT QAbstractProxyModel : public QAbstractItemModel
-{
- Q_OBJECT
-
-public:
- QAbstractProxyModel(QObject *parent = 0);
- ~QAbstractProxyModel();
-
- virtual void setSourceModel(QAbstractItemModel *sourceModel);
- QAbstractItemModel *sourceModel() const;
-
- virtual QModelIndex mapToSource(const QModelIndex &proxyIndex) const = 0;
- virtual QModelIndex mapFromSource(const QModelIndex &sourceIndex) const = 0;
-
- virtual QItemSelection mapSelectionToSource(const QItemSelection &selection) const;
- virtual QItemSelection mapSelectionFromSource(const QItemSelection &selection) const;
-
- bool submit();
- void revert();
-
- QVariant data(const QModelIndex &proxyIndex, int role = Qt::DisplayRole) const;
- QVariant headerData(int section, Qt::Orientation orientation, int role) const;
- QMap<int, QVariant> itemData(const QModelIndex &index) const;
- Qt::ItemFlags flags(const QModelIndex &index) const;
-
- bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
- bool setItemData(const QModelIndex& index, const QMap<int, QVariant> &roles);
- bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role = Qt::EditRole);
-
- QModelIndex buddy(const QModelIndex &index) const;
- bool canFetchMore(const QModelIndex &parent) const;
- void fetchMore(const QModelIndex &parent);
- void sort(int column, Qt::SortOrder order = Qt::AscendingOrder);
- QSize span(const QModelIndex &index) const;
- bool hasChildren(const QModelIndex &parent = QModelIndex()) const;
-
- QMimeData* mimeData(const QModelIndexList &indexes) const;
- QStringList mimeTypes() const;
- Qt::DropActions supportedDropActions() const;
-
-protected:
- QAbstractProxyModel(QAbstractProxyModelPrivate &, QObject *parent);
-
-private:
- Q_DECLARE_PRIVATE(QAbstractProxyModel)
- Q_DISABLE_COPY(QAbstractProxyModel)
- Q_PRIVATE_SLOT(d_func(), void _q_sourceModelDestroyed())
-};
-
-#endif // QT_NO_PROXYMODEL
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QABSTRACTPROXYMODEL_H
diff --git a/src/gui/itemviews/qcolumnview.h b/src/gui/itemviews/qcolumnview.h
deleted file mode 100644
index ec20c9d7ad..0000000000
--- a/src/gui/itemviews/qcolumnview.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QCOLUMNVIEW_H
-#define QCOLUMNVIEW_H
-
-#include <QtGui/qabstractitemview.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_COLUMNVIEW
-
-class QColumnViewPrivate;
-
-class Q_GUI_EXPORT QColumnView : public QAbstractItemView {
-
-Q_OBJECT
- Q_PROPERTY(bool resizeGripsVisible READ resizeGripsVisible WRITE setResizeGripsVisible)
-
-Q_SIGNALS:
- void updatePreviewWidget(const QModelIndex &index);
-
-public:
- explicit QColumnView(QWidget *parent = 0);
- ~QColumnView();
-
- // QAbstractItemView overloads
- QModelIndex indexAt(const QPoint &point) const;
- void scrollTo(const QModelIndex &index, ScrollHint hint = EnsureVisible);
- QSize sizeHint() const;
- QRect visualRect(const QModelIndex &index) const;
- void setModel(QAbstractItemModel *model);
- void setSelectionModel(QItemSelectionModel * selectionModel);
- void setRootIndex(const QModelIndex &index);
- void selectAll();
-
- // QColumnView functions
- void setResizeGripsVisible(bool visible);
- bool resizeGripsVisible() const;
-
- QWidget *previewWidget() const;
- void setPreviewWidget(QWidget *widget);
-
- void setColumnWidths(const QList<int> &list);
- QList<int> columnWidths() const;
-
-protected:
- QColumnView(QColumnViewPrivate &dd, QWidget *parent = 0);
-
- // QAbstractItemView overloads
- bool isIndexHidden(const QModelIndex &index) const;
- QModelIndex moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers);
- void resizeEvent(QResizeEvent *event);
- void setSelection(const QRect & rect, QItemSelectionModel::SelectionFlags command);
- QRegion visualRegionForSelection(const QItemSelection &selection) const;
- int horizontalOffset() const;
- int verticalOffset() const;
- void rowsInserted(const QModelIndex &parent, int start, int end);
- void currentChanged(const QModelIndex &current, const QModelIndex &previous);
-
- // QColumnView functions
- void scrollContentsBy(int dx, int dy);
- virtual QAbstractItemView* createColumn(const QModelIndex &rootIndex);
- void initializeColumn(QAbstractItemView *column) const;
-
-private:
- Q_DECLARE_PRIVATE(QColumnView)
- Q_DISABLE_COPY(QColumnView)
- Q_PRIVATE_SLOT(d_func(), void _q_gripMoved(int))
- Q_PRIVATE_SLOT(d_func(), void _q_changeCurrentColumn())
- Q_PRIVATE_SLOT(d_func(), void _q_clicked(const QModelIndex &))
-};
-
-#endif // QT_NO_COLUMNVIEW
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QCOLUMNVIEW_H
-
diff --git a/src/gui/itemviews/qcolumnview_p.h b/src/gui/itemviews/qcolumnview_p.h
deleted file mode 100644
index e7f8b9a311..0000000000
--- a/src/gui/itemviews/qcolumnview_p.h
+++ /dev/null
@@ -1,189 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QCOLUMNVIEW_P_H
-#define QCOLUMNVIEW_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qcolumnview.h"
-
-#ifndef QT_NO_QCOLUMNVIEW
-
-#include <private/qabstractitemview_p.h>
-
-#include <QtCore/qabstractitemmodel.h>
-#include <QtCore/qpropertyanimation.h>
-#include <QtGui/qabstractitemdelegate.h>
-#include <QtGui/qabstractitemview.h>
-#include <QtGui/qitemdelegate.h>
-#include <qlistview.h>
-#include <qevent.h>
-#include <qscrollbar.h>
-
-QT_BEGIN_NAMESPACE
-
-class QColumnViewPreviewColumn : public QAbstractItemView {
-
-public:
- QColumnViewPreviewColumn(QWidget *parent) : QAbstractItemView(parent), previewWidget(0) {
- }
-
- void setPreviewWidget(QWidget *widget) {
- previewWidget = widget;
- setMinimumWidth(previewWidget->minimumWidth());
- }
-
- void resizeEvent(QResizeEvent * event){
- if (!previewWidget)
- return;
- previewWidget->resize(
- qMax(previewWidget->minimumWidth(), event->size().width()),
- previewWidget->height());
- QSize p = viewport()->size();
- QSize v = previewWidget->size();
- horizontalScrollBar()->setRange(0, v.width() - p.width());
- horizontalScrollBar()->setPageStep(p.width());
- verticalScrollBar()->setRange(0, v.height() - p.height());
- verticalScrollBar()->setPageStep(p.height());
-
- QAbstractScrollArea::resizeEvent(event);
- }
-
- QRect visualRect(const QModelIndex &) const
- {
- return QRect();
- }
- void scrollTo(const QModelIndex &, ScrollHint)
- {
- }
- QModelIndex indexAt(const QPoint &) const
- {
- return QModelIndex();
- }
- QModelIndex moveCursor(CursorAction, Qt::KeyboardModifiers)
- {
- return QModelIndex();
- }
- int horizontalOffset () const {
- return 0;
- }
- int verticalOffset () const {
- return 0;
- }
- QRegion visualRegionForSelection(const QItemSelection &) const
- {
- return QRegion();
- }
- bool isIndexHidden(const QModelIndex &) const
- {
- return false;
- }
- void setSelection(const QRect &, QItemSelectionModel::SelectionFlags)
- {
- }
-private:
- QWidget *previewWidget;
-};
-
-class Q_AUTOTEST_EXPORT QColumnViewPrivate : public QAbstractItemViewPrivate
-{
- Q_DECLARE_PUBLIC(QColumnView)
-
-public:
- QColumnViewPrivate();
- ~QColumnViewPrivate();
- void initialize();
-
- QAbstractItemView *createColumn(const QModelIndex &index, bool show);
-
- void updateScrollbars();
- void closeColumns(const QModelIndex &parent = QModelIndex(), bool build = false);
- void doLayout();
- void setPreviewWidget(QWidget *widget);
- void checkColumnCreation(const QModelIndex &parent);
-
-
- void _q_gripMoved(int offset);
- void _q_changeCurrentColumn();
- void _q_clicked(const QModelIndex &index);
- void _q_columnsInserted(const QModelIndex &parent, int start, int end);
-
- QList<QAbstractItemView*> columns;
- QVector<int> columnSizes; // used during init and corner moving
- bool showResizeGrips;
- int offset;
-#ifndef QT_NO_ANIMATION
- QPropertyAnimation currentAnimation;
-#endif
- QWidget *previewWidget;
- QAbstractItemView *previewColumn;
-};
-
-/*!
- * This is a delegate that will paint the triangle
- */
-class QColumnViewDelegate : public QItemDelegate
-{
-
-public:
- explicit QColumnViewDelegate(QObject *parent = 0) : QItemDelegate(parent) {}
- ~QColumnViewDelegate() {}
-
- void paint(QPainter *painter,
- const QStyleOptionViewItem &option,
- const QModelIndex &index) const;
-};
-#endif // QT_NO_QCOLUMNVIEW
-
-
-QT_END_NAMESPACE
-#endif //QCOLUMNVIEW_P_H
-
diff --git a/src/gui/itemviews/qdatawidgetmapper.h b/src/gui/itemviews/qdatawidgetmapper.h
deleted file mode 100644
index c1d47d3fc2..0000000000
--- a/src/gui/itemviews/qdatawidgetmapper.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDATAWIDGETMAPPER_H
-#define QDATAWIDGETMAPPER_H
-
-#include "QtCore/qobject.h"
-
-#ifndef QT_NO_DATAWIDGETMAPPER
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QAbstractItemDelegate;
-class QAbstractItemModel;
-class QModelIndex;
-class QDataWidgetMapperPrivate;
-
-class Q_GUI_EXPORT QDataWidgetMapper: public QObject
-{
- Q_OBJECT
-
- Q_ENUMS(SubmitPolicy)
- Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged)
- Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation)
- Q_PROPERTY(SubmitPolicy submitPolicy READ submitPolicy WRITE setSubmitPolicy)
-
-public:
- QDataWidgetMapper(QObject *parent = 0);
- ~QDataWidgetMapper();
-
- void setModel(QAbstractItemModel *model);
- QAbstractItemModel *model() const;
-
- void setItemDelegate(QAbstractItemDelegate *delegate);
- QAbstractItemDelegate *itemDelegate() const;
-
- void setRootIndex(const QModelIndex &index);
- QModelIndex rootIndex() const;
-
- void setOrientation(Qt::Orientation aOrientation);
- Qt::Orientation orientation() const;
-
- enum SubmitPolicy { AutoSubmit, ManualSubmit };
- void setSubmitPolicy(SubmitPolicy policy);
- SubmitPolicy submitPolicy() const;
-
- void addMapping(QWidget *widget, int section);
- void addMapping(QWidget *widget, int section, const QByteArray &propertyName);
- void removeMapping(QWidget *widget);
- int mappedSection(QWidget *widget) const;
- QByteArray mappedPropertyName(QWidget *widget) const;
- QWidget *mappedWidgetAt(int section) const;
- void clearMapping();
-
- int currentIndex() const;
-
-public Q_SLOTS:
- void revert();
- bool submit();
-
- void toFirst();
- void toLast();
- void toNext();
- void toPrevious();
- virtual void setCurrentIndex(int index);
- void setCurrentModelIndex(const QModelIndex &index);
-
-Q_SIGNALS:
- void currentIndexChanged(int index);
-
-private:
- Q_DECLARE_PRIVATE(QDataWidgetMapper)
- Q_DISABLE_COPY(QDataWidgetMapper)
- Q_PRIVATE_SLOT(d_func(), void _q_dataChanged(const QModelIndex &, const QModelIndex &))
- Q_PRIVATE_SLOT(d_func(), void _q_commitData(QWidget *))
- Q_PRIVATE_SLOT(d_func(), void _q_closeEditor(QWidget *, QAbstractItemDelegate::EndEditHint))
- Q_PRIVATE_SLOT(d_func(), void _q_modelDestroyed())
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QT_NO_DATAWIDGETMAPPER
-#endif
-
diff --git a/src/gui/itemviews/qdirmodel.h b/src/gui/itemviews/qdirmodel.h
deleted file mode 100644
index 8ba0450b1d..0000000000
--- a/src/gui/itemviews/qdirmodel.h
+++ /dev/null
@@ -1,160 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDIRMODEL_H
-#define QDIRMODEL_H
-
-#include <QtCore/qabstractitemmodel.h>
-#include <QtCore/qdir.h>
-#include <QtGui/qfileiconprovider.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_DIRMODEL
-
-class QDirModelPrivate;
-
-class Q_GUI_EXPORT QDirModel : public QAbstractItemModel
-{
- Q_OBJECT
- Q_PROPERTY(bool resolveSymlinks READ resolveSymlinks WRITE setResolveSymlinks)
- Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly)
- Q_PROPERTY(bool lazyChildCount READ lazyChildCount WRITE setLazyChildCount)
-
-public:
- enum Roles {
- FileIconRole = Qt::DecorationRole,
- FilePathRole = Qt::UserRole + 1,
- FileNameRole
- };
-
- QDirModel(const QStringList &nameFilters, QDir::Filters filters,
- QDir::SortFlags sort, QObject *parent = 0);
- explicit QDirModel(QObject *parent = 0);
- ~QDirModel();
-
- QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
- QModelIndex parent(const QModelIndex &child) const;
-
- int rowCount(const QModelIndex &parent = QModelIndex()) const;
- int columnCount(const QModelIndex &parent = QModelIndex()) const;
-
- QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
- bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
-
- QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
-
- bool hasChildren(const QModelIndex &index = QModelIndex()) const;
- Qt::ItemFlags flags(const QModelIndex &index) const;
-
- void sort(int column, Qt::SortOrder order = Qt::AscendingOrder);
-
- QStringList mimeTypes() const;
- QMimeData *mimeData(const QModelIndexList &indexes) const;
- bool dropMimeData(const QMimeData *data, Qt::DropAction action,
- int row, int column, const QModelIndex &parent);
- Qt::DropActions supportedDropActions() const;
-
- // QDirModel specific API
-
- void setIconProvider(QFileIconProvider *provider);
- QFileIconProvider *iconProvider() const;
-
- void setNameFilters(const QStringList &filters);
- QStringList nameFilters() const;
-
- void setFilter(QDir::Filters filters);
- QDir::Filters filter() const;
-
- void setSorting(QDir::SortFlags sort);
- QDir::SortFlags sorting() const;
-
- void setResolveSymlinks(bool enable);
- bool resolveSymlinks() const;
-
- void setReadOnly(bool enable);
- bool isReadOnly() const;
-
- void setLazyChildCount(bool enable);
- bool lazyChildCount() const;
-
- QModelIndex index(const QString &path, int column = 0) const;
-
- bool isDir(const QModelIndex &index) const;
- QModelIndex mkdir(const QModelIndex &parent, const QString &name);
- bool rmdir(const QModelIndex &index);
- bool remove(const QModelIndex &index);
-
- QString filePath(const QModelIndex &index) const;
- QString fileName(const QModelIndex &index) const;
- QIcon fileIcon(const QModelIndex &index) const;
- QFileInfo fileInfo(const QModelIndex &index) const;
-
-#ifdef Q_NO_USING_KEYWORD
- inline QObject *parent() const { return QObject::parent(); }
-#else
- using QObject::parent;
-#endif
-
-public Q_SLOTS:
- void refresh(const QModelIndex &parent = QModelIndex());
-
-protected:
- QDirModel(QDirModelPrivate &, QObject *parent = 0);
- friend class QFileDialogPrivate;
-
-private:
- Q_DECLARE_PRIVATE(QDirModel)
- Q_DISABLE_COPY(QDirModel)
- Q_PRIVATE_SLOT(d_func(), void _q_refresh())
-};
-
-#endif // QT_NO_DIRMODEL
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QDIRMODEL_H
diff --git a/src/gui/itemviews/qfileiconprovider.h b/src/gui/itemviews/qfileiconprovider.h
deleted file mode 100644
index 3fab0b142a..0000000000
--- a/src/gui/itemviews/qfileiconprovider.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QFILEICONPROVIDER_H
-#define QFILEICONPROVIDER_H
-
-#include <QtCore/qfileinfo.h>
-#include <QtCore/qscopedpointer.h>
-#include <QtGui/qicon.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_FILEICONPROVIDER
-
-class QFileIconProviderPrivate;
-
-class Q_GUI_EXPORT QFileIconProvider
-{
-public:
- QFileIconProvider();
- virtual ~QFileIconProvider();
- enum IconType { Computer, Desktop, Trashcan, Network, Drive, Folder, File };
- virtual QIcon icon(IconType type) const;
- virtual QIcon icon(const QFileInfo &info) const;
- virtual QString type(const QFileInfo &info) const;
-
-private:
- Q_DECLARE_PRIVATE(QFileIconProvider)
- QScopedPointer<QFileIconProviderPrivate> d_ptr;
- Q_DISABLE_COPY(QFileIconProvider)
-};
-
-#endif // QT_NO_FILEICONPROVIDER
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QFILEICONPROVIDER_H
-
diff --git a/src/gui/itemviews/qheaderview.h b/src/gui/itemviews/qheaderview.h
deleted file mode 100644
index b2e684d20e..0000000000
--- a/src/gui/itemviews/qheaderview.h
+++ /dev/null
@@ -1,250 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QHEADERVIEW_H
-#define QHEADERVIEW_H
-
-#include <QtGui/qabstractitemview.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_ITEMVIEWS
-
-class QHeaderViewPrivate;
-class QStyleOptionHeader;
-
-class Q_GUI_EXPORT QHeaderView : public QAbstractItemView
-{
- Q_OBJECT
- Q_PROPERTY(bool showSortIndicator READ isSortIndicatorShown WRITE setSortIndicatorShown)
- Q_PROPERTY(bool highlightSections READ highlightSections WRITE setHighlightSections)
- Q_PROPERTY(bool stretchLastSection READ stretchLastSection WRITE setStretchLastSection)
- Q_PROPERTY(bool cascadingSectionResizes READ cascadingSectionResizes WRITE setCascadingSectionResizes)
- Q_PROPERTY(int defaultSectionSize READ defaultSectionSize WRITE setDefaultSectionSize)
- Q_PROPERTY(int minimumSectionSize READ minimumSectionSize WRITE setMinimumSectionSize)
- Q_PROPERTY(Qt::Alignment defaultAlignment READ defaultAlignment WRITE setDefaultAlignment)
- Q_ENUMS(ResizeMode)
-
-public:
-
- enum ResizeMode
- {
- Interactive,
- Stretch,
- Fixed,
- ResizeToContents,
- Custom = Fixed
- };
-
- explicit QHeaderView(Qt::Orientation orientation, QWidget *parent = 0);
- virtual ~QHeaderView();
-
- void setModel(QAbstractItemModel *model);
-
- Qt::Orientation orientation() const;
- int offset() const;
- int length() const;
- QSize sizeHint() const;
- int sectionSizeHint(int logicalIndex) const;
-
- int visualIndexAt(int position) const;
- int logicalIndexAt(int position) const;
-
- inline int logicalIndexAt(int x, int y) const;
- inline int logicalIndexAt(const QPoint &pos) const;
-
- int sectionSize(int logicalIndex) const;
- int sectionPosition(int logicalIndex) const;
- int sectionViewportPosition(int logicalIndex) const;
-
- void moveSection(int from, int to);
- void swapSections(int first, int second);
- void resizeSection(int logicalIndex, int size);
- void resizeSections(QHeaderView::ResizeMode mode);
-
- bool isSectionHidden(int logicalIndex) const;
- void setSectionHidden(int logicalIndex, bool hide);
- int hiddenSectionCount() const;
-
- inline void hideSection(int logicalIndex);
- inline void showSection(int logicalIndex);
-
- int count() const;
- int visualIndex(int logicalIndex) const;
- int logicalIndex(int visualIndex) const;
-
- void setMovable(bool movable);
- bool isMovable() const;
-
- void setClickable(bool clickable);
- bool isClickable() const;
-
- void setHighlightSections(bool highlight);
- bool highlightSections() const;
-
- void setResizeMode(ResizeMode mode);
- void setResizeMode(int logicalIndex, ResizeMode mode);
- ResizeMode resizeMode(int logicalIndex) const;
- int stretchSectionCount() const;
-
- void setSortIndicatorShown(bool show);
- bool isSortIndicatorShown() const;
-
- void setSortIndicator(int logicalIndex, Qt::SortOrder order);
- int sortIndicatorSection() const;
- Qt::SortOrder sortIndicatorOrder() const;
-
- bool stretchLastSection() const;
- void setStretchLastSection(bool stretch);
-
- bool cascadingSectionResizes() const;
- void setCascadingSectionResizes(bool enable);
-
- int defaultSectionSize() const;
- void setDefaultSectionSize(int size);
-
- int minimumSectionSize() const;
- void setMinimumSectionSize(int size);
-
- Qt::Alignment defaultAlignment() const;
- void setDefaultAlignment(Qt::Alignment alignment);
-
- void doItemsLayout();
- bool sectionsMoved() const;
- bool sectionsHidden() const;
-
-#ifndef QT_NO_DATASTREAM
- QByteArray saveState() const;
- bool restoreState(const QByteArray &state);
-#endif
-
- void reset();
-
-public Q_SLOTS:
- void setOffset(int offset);
- void setOffsetToSectionPosition(int visualIndex);
- void setOffsetToLastSection();
- void headerDataChanged(Qt::Orientation orientation, int logicalFirst, int logicalLast);
-
-Q_SIGNALS:
- void sectionMoved(int logicalIndex, int oldVisualIndex, int newVisualIndex);
- void sectionResized(int logicalIndex, int oldSize, int newSize);
- void sectionPressed(int logicalIndex);
- void sectionClicked(int logicalIndex);
- void sectionEntered(int logicalIndex);
- void sectionDoubleClicked(int logicalIndex);
- void sectionCountChanged(int oldCount, int newCount);
- void sectionHandleDoubleClicked(int logicalIndex);
- void sectionAutoResize(int logicalIndex, QHeaderView::ResizeMode mode);
- void geometriesChanged();
- void sortIndicatorChanged(int logicalIndex, Qt::SortOrder order);
-
-protected Q_SLOTS:
- void updateSection(int logicalIndex);
- void resizeSections();
- void sectionsInserted(const QModelIndex &parent, int logicalFirst, int logicalLast);
- void sectionsAboutToBeRemoved(const QModelIndex &parent, int logicalFirst, int logicalLast);
-
-protected:
- QHeaderView(QHeaderViewPrivate &dd, Qt::Orientation orientation, QWidget *parent = 0);
- void initialize();
-
- void initializeSections();
- void initializeSections(int start, int end);
- void currentChanged(const QModelIndex &current, const QModelIndex &old);
-
- bool event(QEvent *e);
- void paintEvent(QPaintEvent *e);
- void mousePressEvent(QMouseEvent *e);
- void mouseMoveEvent(QMouseEvent *e);
- void mouseReleaseEvent(QMouseEvent *e);
- void mouseDoubleClickEvent(QMouseEvent *e);
- bool viewportEvent(QEvent *e);
-
- virtual void paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const;
- virtual QSize sectionSizeFromContents(int logicalIndex) const;
-
- int horizontalOffset() const;
- int verticalOffset() const;
- void updateGeometries();
- void scrollContentsBy(int dx, int dy);
-
- void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
- void rowsInserted(const QModelIndex &parent, int start, int end);
-
- QRect visualRect(const QModelIndex &index) const;
- void scrollTo(const QModelIndex &index, ScrollHint hint);
-
- QModelIndex indexAt(const QPoint &p) const;
- bool isIndexHidden(const QModelIndex &index) const;
-
- QModelIndex moveCursor(CursorAction, Qt::KeyboardModifiers);
- void setSelection(const QRect& rect, QItemSelectionModel::SelectionFlags flags);
- QRegion visualRegionForSelection(const QItemSelection &selection) const;
- void initStyleOption(QStyleOptionHeader *option) const;
-
-private:
- Q_PRIVATE_SLOT(d_func(), void _q_sectionsRemoved(const QModelIndex &parent, int logicalFirst, int logicalLast))
- Q_PRIVATE_SLOT(d_func(), void _q_layoutAboutToBeChanged())
- Q_DECLARE_PRIVATE(QHeaderView)
- Q_DISABLE_COPY(QHeaderView)
-};
-
-inline int QHeaderView::logicalIndexAt(int ax, int ay) const
-{ return orientation() == Qt::Horizontal ? logicalIndexAt(ax) : logicalIndexAt(ay); }
-inline int QHeaderView::logicalIndexAt(const QPoint &apos) const
-{ return logicalIndexAt(apos.x(), apos.y()); }
-inline void QHeaderView::hideSection(int alogicalIndex)
-{ setSectionHidden(alogicalIndex, true); }
-inline void QHeaderView::showSection(int alogicalIndex)
-{ setSectionHidden(alogicalIndex, false); }
-
-#endif // QT_NO_ITEMVIEWS
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QHEADERVIEW_H
diff --git a/src/gui/itemviews/qheaderview_p.h b/src/gui/itemviews/qheaderview_p.h
deleted file mode 100644
index 5a9e1854b9..0000000000
--- a/src/gui/itemviews/qheaderview_p.h
+++ /dev/null
@@ -1,366 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QHEADERVIEW_P_H
-#define QHEADERVIEW_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "private/qabstractitemview_p.h"
-
-#ifndef QT_NO_ITEMVIEWS
-
-#include "QtCore/qbitarray.h"
-#include "QtGui/qapplication.h"
-#include "QtGui/qlabel.h"
-
-QT_BEGIN_NAMESPACE
-
-class QHeaderViewPrivate: public QAbstractItemViewPrivate
-{
- Q_DECLARE_PUBLIC(QHeaderView)
-
-public:
- enum StateVersion { VersionMarker = 0xff };
-
- QHeaderViewPrivate()
- : state(NoState),
- offset(0),
- sortIndicatorOrder(Qt::DescendingOrder),
- sortIndicatorSection(0),
- sortIndicatorShown(false),
- lastPos(-1),
- firstPos(-1),
- originalSize(-1),
- section(-1),
- target(-1),
- pressed(-1),
- hover(-1),
- length(0),
- sectionCount(0),
- movableSections(false),
- clickableSections(false),
- highlightSelected(false),
- stretchLastSection(false),
- cascadingResizing(false),
- resizeRecursionBlock(false),
- stretchSections(0),
- contentsSections(0),
- minimumSectionSize(-1),
- lastSectionSize(0),
- sectionIndicatorOffset(0),
- sectionIndicator(0),
- globalResizeMode(QHeaderView::Interactive)
- {}
-
-
- int lastVisibleVisualIndex() const;
- int sectionHandleAt(int position);
- void setupSectionIndicator(int section, int position);
- void updateSectionIndicator(int section, int position);
- void updateHiddenSections(int logicalFirst, int logicalLast);
- void resizeSections(QHeaderView::ResizeMode globalMode, bool useGlobalMode = false);
- void _q_sectionsRemoved(const QModelIndex &,int,int);
- void _q_layoutAboutToBeChanged();
- void _q_layoutChanged();
-
- bool isSectionSelected(int section) const;
-
- inline bool rowIntersectsSelection(int row) const {
- return (selectionModel ? selectionModel->rowIntersectsSelection(row, root) : false);
- }
-
- inline bool columnIntersectsSelection(int column) const {
- return (selectionModel ? selectionModel->columnIntersectsSelection(column, root) : false);
- }
-
- inline bool sectionIntersectsSelection(int logical) const {
- return (orientation == Qt::Horizontal ? columnIntersectsSelection(logical) : rowIntersectsSelection(logical));
- }
-
- inline bool isRowSelected(int row) const {
- return (selectionModel ? selectionModel->isRowSelected(row, root) : false);
- }
-
- inline bool isColumnSelected(int column) const {
- return (selectionModel ? selectionModel->isColumnSelected(column, root) : false);
- }
-
- inline void prepareSectionSelected() {
- if (!selectionModel || !selectionModel->hasSelection())
- sectionSelected.clear();
- else if (sectionSelected.count() != sectionCount * 2)
- sectionSelected.fill(false, sectionCount * 2);
- else sectionSelected.fill(false);
- }
-
- inline bool reverse() const {
- return orientation == Qt::Horizontal && q_func()->isRightToLeft();
- }
-
- inline int logicalIndex(int visualIndex) const {
- return logicalIndices.isEmpty() ? visualIndex : logicalIndices.at(visualIndex);
- }
-
- inline int visualIndex(int logicalIndex) const {
- return visualIndices.isEmpty() ? logicalIndex : visualIndices.at(logicalIndex);
- }
-
- inline void setDefaultValues(Qt::Orientation o) {
- orientation = o;
- defaultSectionSize = (o == Qt::Horizontal ? 100
- : qMax(q_func()->minimumSectionSize(), 30));
- defaultAlignment = (o == Qt::Horizontal
- ? Qt::Alignment(Qt::AlignCenter)
- : Qt::AlignLeft|Qt::AlignVCenter);
- }
-
- inline bool isVisualIndexHidden(int visual) const {
- return !sectionHidden.isEmpty() && sectionHidden.at(visual);
- }
-
- inline void setVisualIndexHidden(int visual, bool hidden) {
- if (!sectionHidden.isEmpty()) sectionHidden.setBit(visual, hidden);
- }
-
- inline bool hasAutoResizeSections() const {
- return stretchSections || stretchLastSection || contentsSections;
- }
-
- QStyleOptionHeader getStyleOption() const;
-
- inline void invalidateCachedSizeHint() const {
- cachedSizeHint = QSize();
- }
-
- inline void initializeIndexMapping() const {
- if (visualIndices.count() != sectionCount
- || logicalIndices.count() != sectionCount) {
- visualIndices.resize(sectionCount);
- logicalIndices.resize(sectionCount);
- for (int s = 0; s < sectionCount; ++s) {
- visualIndices[s] = s;
- logicalIndices[s] = s;
- }
- }
- }
-
- inline void clearCascadingSections() {
- firstCascadingSection = sectionCount;
- lastCascadingSection = 0;
- cascadingSectionSize.clear();
- }
-
- inline void saveCascadingSectionSize(int visual, int size) {
- if (!cascadingSectionSize.contains(visual)) {
- cascadingSectionSize.insert(visual, size);
- firstCascadingSection = qMin(firstCascadingSection, visual);
- lastCascadingSection = qMax(lastCascadingSection, visual);
- }
- }
-
- inline bool sectionIsCascadable(int visual) const {
- return headerSectionResizeMode(visual) == QHeaderView::Interactive;
- }
-
- inline int modelSectionCount() const {
- return (orientation == Qt::Horizontal
- ? model->columnCount(root)
- : model->rowCount(root));
- }
-
- inline bool modelIsEmpty() const {
- return (model->rowCount(root) == 0 || model->columnCount(root) == 0);
- }
-
- inline void doDelayedResizeSections() {
- if (!delayedResize.isActive())
- delayedResize.start(0, q_func());
- }
-
- inline void executePostedResize() const {
- if (delayedResize.isActive() && state == NoState) {
- const_cast<QHeaderView*>(q_func())->resizeSections();
- }
- }
-
- void clear();
- void flipSortIndicator(int section);
- void cascadingResize(int visual, int newSize);
-
- enum State { NoState, ResizeSection, MoveSection, SelectSections, NoClear } state;
-
- int offset;
- Qt::Orientation orientation;
- Qt::SortOrder sortIndicatorOrder;
- int sortIndicatorSection;
- bool sortIndicatorShown;
-
- mutable QVector<int> visualIndices; // visualIndex = visualIndices.at(logicalIndex)
- mutable QVector<int> logicalIndices; // logicalIndex = row or column in the model
- mutable QBitArray sectionSelected; // from logical index to bit
- mutable QBitArray sectionHidden; // from visual index to bit
- mutable QHash<int, int> hiddenSectionSize; // from logical index to section size
- mutable QHash<int, int> cascadingSectionSize; // from visual index to section size
- mutable QSize cachedSizeHint;
- mutable QBasicTimer delayedResize;
-
- int firstCascadingSection;
- int lastCascadingSection;
-
- int lastPos;
- int firstPos;
- int originalSize;
- int section; // used for resizing and moving sections
- int target;
- int pressed;
- int hover;
-
- int length;
- int sectionCount;
- bool movableSections;
- bool clickableSections;
- bool highlightSelected;
- bool stretchLastSection;
- bool cascadingResizing;
- bool resizeRecursionBlock;
- int stretchSections;
- int contentsSections;
- int defaultSectionSize;
- int minimumSectionSize;
- int lastSectionSize; // $$$
- int sectionIndicatorOffset;
- Qt::Alignment defaultAlignment;
- QLabel *sectionIndicator;
- QHeaderView::ResizeMode globalResizeMode;
- QList<QPersistentModelIndex> persistentHiddenSections;
-
- // header section spans
-
- struct SectionSpan {
- int size;
- int count;
- QHeaderView::ResizeMode resizeMode;
- inline SectionSpan() : size(0), count(0), resizeMode(QHeaderView::Interactive) {}
- inline SectionSpan(int length, int sections, QHeaderView::ResizeMode mode)
- : size(length), count(sections), resizeMode(mode) {}
- inline int sectionSize() const { return (count > 0 ? size / count : 0); }
-#ifndef QT_NO_DATASTREAM
- inline void write(QDataStream &out) const
- { out << size; out << count; out << (int)resizeMode; }
- inline void read(QDataStream &in)
- { in >> size; in >> count; int m; in >> m; resizeMode = (QHeaderView::ResizeMode)m; }
-#endif
- };
-
- QVector<SectionSpan> sectionSpans;
-
- void createSectionSpan(int start, int end, int size, QHeaderView::ResizeMode mode);
- void removeSectionsFromSpans(int start, int end);
- void resizeSectionSpan(int visualIndex, int oldSize, int newSize);
- void setDefaultSectionSize(int size);
-
- inline int headerSectionCount() const { // for debugging
- int count = 0;
- for (int i = 0; i < sectionSpans.count(); ++i)
- count += sectionSpans.at(i).count;
- return count;
- }
-
- inline int headerLength() const { // for debugging
- int len = 0;
- for (int i = 0; i < sectionSpans.count(); ++i)
- len += sectionSpans.at(i).size;
- return len;
- }
-
- inline void removeSpans(const QList<int> &spans) {
- for (int i = spans.count() - 1; i >= 0; --i) {
- length -= sectionSpans.at(spans.at(i)).size;
- sectionSpans.remove(spans.at(i));
- }
- }
-
- inline int sectionSpanIndex(int visual) const {
- int section_start = 0;
- for (int i = 0; i < sectionSpans.count(); ++i) {
- int section_end = section_start + sectionSpans.at(i).count - 1;
- if (visual >= section_start && visual <= section_end)
- return i;
- section_start = section_end + 1;
- }
- return -1;
- }
-
- int headerSectionSize(int visual) const;
- int headerSectionPosition(int visual) const;
- int headerVisualIndexAt(int position) const;
-
- // resize mode
- void setHeaderSectionResizeMode(int visual, QHeaderView::ResizeMode mode);
- QHeaderView::ResizeMode headerSectionResizeMode(int visual) const;
- void setGlobalHeaderResizeMode(QHeaderView::ResizeMode mode);
-
- // other
- int viewSectionSizeHint(int logical) const;
- int adjustedVisualIndex(int visualIndex) const;
-
-#ifndef QT_NO_DATASTREAM
- void write(QDataStream &out) const;
- bool read(QDataStream &in);
-#endif
-
-};
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_ITEMVIEWS
-
-#endif // QHEADERVIEW_P_H
diff --git a/src/gui/itemviews/qidentityproxymodel.h b/src/gui/itemviews/qidentityproxymodel.h
deleted file mode 100644
index 40ad67358a..0000000000
--- a/src/gui/itemviews/qidentityproxymodel.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Stephen Kelly <stephen.kelly@kdab.com>
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#ifndef QIDENTITYPROXYMODEL_H
-#define QIDENTITYPROXYMODEL_H
-
-#include <QtGui/qabstractproxymodel.h>
-
-#ifndef QT_NO_IDENTITYPROXYMODEL
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QIdentityProxyModelPrivate;
-
-class Q_GUI_EXPORT QIdentityProxyModel : public QAbstractProxyModel
-{
- Q_OBJECT
-public:
- explicit QIdentityProxyModel(QObject* parent = 0);
- ~QIdentityProxyModel();
-
- int columnCount(const QModelIndex& parent = QModelIndex()) const;
- QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const;
- QModelIndex mapFromSource(const QModelIndex& sourceIndex) const;
- QModelIndex mapToSource(const QModelIndex& proxyIndex) const;
- QModelIndex parent(const QModelIndex& child) const;
- int rowCount(const QModelIndex& parent = QModelIndex()) const;
- bool dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent);
-
- QItemSelection mapSelectionFromSource(const QItemSelection& selection) const;
- QItemSelection mapSelectionToSource(const QItemSelection& selection) const;
- QModelIndexList match(const QModelIndex& start, int role, const QVariant& value, int hits = 1, Qt::MatchFlags flags = Qt::MatchFlags(Qt::MatchStartsWith|Qt::MatchWrap)) const;
- void setSourceModel(QAbstractItemModel* sourceModel);
-
- bool insertColumns(int column, int count, const QModelIndex& parent = QModelIndex());
- bool insertRows(int row, int count, const QModelIndex& parent = QModelIndex());
- bool removeColumns(int column, int count, const QModelIndex& parent = QModelIndex());
- bool removeRows(int row, int count, const QModelIndex& parent = QModelIndex());
-
-protected:
- QIdentityProxyModel(QIdentityProxyModelPrivate &dd, QObject* parent);
-
-private:
- Q_DECLARE_PRIVATE(QIdentityProxyModel)
- Q_DISABLE_COPY(QIdentityProxyModel)
-
- Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsAboutToBeInserted(QModelIndex,int,int))
- Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsInserted(QModelIndex,int,int))
- Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsAboutToBeRemoved(QModelIndex,int,int))
- Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsRemoved(QModelIndex,int,int))
- Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int))
- Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsMoved(QModelIndex,int,int,QModelIndex,int))
-
- Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsAboutToBeInserted(QModelIndex,int,int))
- Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsInserted(QModelIndex,int,int))
- Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsAboutToBeRemoved(QModelIndex,int,int))
- Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsRemoved(QModelIndex,int,int))
- Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int))
- Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsMoved(QModelIndex,int,int,QModelIndex,int))
-
- Q_PRIVATE_SLOT(d_func(), void _q_sourceDataChanged(QModelIndex,QModelIndex))
- Q_PRIVATE_SLOT(d_func(), void _q_sourceHeaderDataChanged(Qt::Orientation orientation, int first, int last))
-
- Q_PRIVATE_SLOT(d_func(), void _q_sourceLayoutAboutToBeChanged())
- Q_PRIVATE_SLOT(d_func(), void _q_sourceLayoutChanged())
- Q_PRIVATE_SLOT(d_func(), void _q_sourceModelAboutToBeReset())
- Q_PRIVATE_SLOT(d_func(), void _q_sourceModelReset())
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QT_NO_IDENTITYPROXYMODEL
-
-#endif // QIDENTITYPROXYMODEL_H
-
diff --git a/src/gui/itemviews/qitemdelegate.cpp b/src/gui/itemviews/qitemdelegate.cpp
deleted file mode 100644
index c1f957b638..0000000000
--- a/src/gui/itemviews/qitemdelegate.cpp
+++ /dev/null
@@ -1,1341 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qitemdelegate.h"
-
-#ifndef QT_NO_ITEMVIEWS
-#include <qabstractitemmodel.h>
-#include <qapplication.h>
-#include <qbrush.h>
-#include <qlineedit.h>
-#include <qtextedit.h>
-#include <qplaintextedit.h>
-#include <qpainter.h>
-#include <qpalette.h>
-#include <qpoint.h>
-#include <qrect.h>
-#include <qsize.h>
-#include <qstyle.h>
-#include <qdatetime.h>
-#include <qstyleoption.h>
-#include <qevent.h>
-#include <qpixmap.h>
-#include <qbitmap.h>
-#include <qpixmapcache.h>
-#include <qitemeditorfactory.h>
-#include <qmetaobject.h>
-#include <qtextlayout.h>
-#include <private/qobject_p.h>
-#include <private/qdnd_p.h>
-#include <private/qtextengine_p.h>
-#include <qdebug.h>
-#include <qlocale.h>
-#include <qdialog.h>
-#include <qmath.h>
-
-#include <limits.h>
-
-#ifndef DBL_DIG
-# define DBL_DIG 10
-#endif
-
-QT_BEGIN_NAMESPACE
-
-class QItemDelegatePrivate : public QObjectPrivate
-{
- Q_DECLARE_PUBLIC(QItemDelegate)
-
-public:
- QItemDelegatePrivate() : f(0), clipPainting(true) {}
-
- inline const QItemEditorFactory *editorFactory() const
- { return f ? f : QItemEditorFactory::defaultFactory(); }
-
- inline QIcon::Mode iconMode(QStyle::State state) const
- {
- if (!(state & QStyle::State_Enabled)) return QIcon::Disabled;
- if (state & QStyle::State_Selected) return QIcon::Selected;
- return QIcon::Normal;
- }
-
- inline QIcon::State iconState(QStyle::State state) const
- { return state & QStyle::State_Open ? QIcon::On : QIcon::Off; }
-
- inline static QString replaceNewLine(QString text)
- {
- const QChar nl = QLatin1Char('\n');
- for (int i = 0; i < text.count(); ++i)
- if (text.at(i) == nl)
- text[i] = QChar::LineSeparator;
- return text;
- }
-
- static QString valueToText(const QVariant &value, const QStyleOptionViewItemV4 &option);
-
- void _q_commitDataAndCloseEditor(QWidget *editor);
-
- QItemEditorFactory *f;
- bool clipPainting;
-
- QRect textLayoutBounds(const QStyleOptionViewItemV2 &options) const;
- QSizeF doTextLayout(int lineWidth) const;
- mutable QTextLayout textLayout;
- mutable QTextOption textOption;
-
- const QWidget *widget(const QStyleOptionViewItem &option) const
- {
- if (const QStyleOptionViewItemV3 *v3 = qstyleoption_cast<const QStyleOptionViewItemV3 *>(&option))
- return v3->widget;
-
- return 0;
- }
-
- // ### temporary hack until we have QStandardItemDelegate
- mutable struct Icon {
- QIcon icon;
- QIcon::Mode mode;
- QIcon::State state;
- } tmp;
-};
-
-void QItemDelegatePrivate::_q_commitDataAndCloseEditor(QWidget *editor)
-{
- Q_Q(QItemDelegate);
- emit q->commitData(editor);
- emit q->closeEditor(editor, QAbstractItemDelegate::SubmitModelCache);
-}
-
-QRect QItemDelegatePrivate::textLayoutBounds(const QStyleOptionViewItemV2 &option) const
-{
- QRect rect = option.rect;
- const bool wrapText = option.features & QStyleOptionViewItemV2::WrapText;
- switch (option.decorationPosition) {
- case QStyleOptionViewItem::Left:
- case QStyleOptionViewItem::Right:
- rect.setWidth(wrapText && rect.isValid() ? rect.width() : (QFIXED_MAX));
- break;
- case QStyleOptionViewItem::Top:
- case QStyleOptionViewItem::Bottom:
- rect.setWidth(wrapText ? option.decorationSize.width() : (QFIXED_MAX));
- break;
- }
-
- return rect;
-}
-
-QSizeF QItemDelegatePrivate::doTextLayout(int lineWidth) const
-{
- qreal height = 0;
- qreal widthUsed = 0;
- textLayout.beginLayout();
- while (true) {
- QTextLine line = textLayout.createLine();
- if (!line.isValid())
- break;
- line.setLineWidth(lineWidth);
- line.setPosition(QPointF(0, height));
- height += line.height();
- widthUsed = qMax(widthUsed, line.naturalTextWidth());
- }
- textLayout.endLayout();
- return QSizeF(widthUsed, height);
-}
-
-/*!
- \class QItemDelegate
-
- \brief The QItemDelegate class provides display and editing facilities for
- data items from a model.
-
- \ingroup model-view
-
-
- QItemDelegate can be used to provide custom display features and editor
- widgets for item views based on QAbstractItemView subclasses. Using a
- delegate for this purpose allows the display and editing mechanisms to be
- customized and developed independently from the model and view.
-
- The QItemDelegate class is one of the \l{Model/View Classes} and
- is part of Qt's \l{Model/View Programming}{model/view framework}.
- Note that QStyledItemDelegate has taken over the job of drawing
- Qt's item views. We recommend the use of QStyledItemDelegate when
- creating new delegates.
-
- When displaying items from a custom model in a standard view, it is
- often sufficient to simply ensure that the model returns appropriate
- data for each of the \l{Qt::ItemDataRole}{roles} that determine the
- appearance of items in views. The default delegate used by Qt's
- standard views uses this role information to display items in most
- of the common forms expected by users. However, it is sometimes
- necessary to have even more control over the appearance of items than
- the default delegate can provide.
-
- This class provides default implementations of the functions for
- painting item data in a view and editing data from item models.
- Default implementations of the paint() and sizeHint() virtual
- functions, defined in QAbstractItemDelegate, are provided to
- ensure that the delegate implements the correct basic behavior
- expected by views. You can reimplement these functions in
- subclasses to customize the appearance of items.
-
- When editing data in an item view, QItemDelegate provides an
- editor widget, which is a widget that is placed on top of the view
- while editing takes place. Editors are created with a
- QItemEditorFactory; a default static instance provided by
- QItemEditorFactory is installed on all item delegates. You can set
- a custom factory using setItemEditorFactory() or set a new default
- factory with QItemEditorFactory::setDefaultFactory(). It is the
- data stored in the item model with the Qt::EditRole that is edited.
-
- Only the standard editing functions for widget-based delegates are
- reimplemented here:
-
- \list
- \o createEditor() returns the widget used to change data from the model
- and can be reimplemented to customize editing behavior.
- \o setEditorData() provides the widget with data to manipulate.
- \o updateEditorGeometry() ensures that the editor is displayed correctly
- with respect to the item view.
- \o setModelData() returns updated data to the model.
- \endlist
-
- The closeEditor() signal indicates that the user has completed editing the data,
- and that the editor widget can be destroyed.
-
- \section1 Standard Roles and Data Types
-
- The default delegate used by the standard views supplied with Qt
- associates each standard role (defined by Qt::ItemDataRole) with certain
- data types. Models that return data in these types can influence the
- appearance of the delegate as described in the following table.
-
- \table
- \header \o Role \o Accepted Types
- \omit
- \row \o \l Qt::AccessibleDescriptionRole \o QString
- \row \o \l Qt::AccessibleTextRole \o QString
- \endomit
- \row \o \l Qt::BackgroundRole \o QBrush
- \row \o \l Qt::BackgroundColorRole \o QColor (obsolete; use Qt::BackgroundRole instead)
- \row \o \l Qt::CheckStateRole \o Qt::CheckState
- \row \o \l Qt::DecorationRole \o QIcon, QPixmap and QColor
- \row \o \l Qt::DisplayRole \o QString and types with a string representation
- \row \o \l Qt::EditRole \o See QItemEditorFactory for details
- \row \o \l Qt::FontRole \o QFont
- \row \o \l Qt::SizeHintRole \o QSize
- \omit
- \row \o \l Qt::StatusTipRole \o
- \endomit
- \row \o \l Qt::TextAlignmentRole \o Qt::Alignment
- \row \o \l Qt::ForegroundRole \o QBrush
- \row \o \l Qt::TextColorRole \o QColor (obsolete; use Qt::ForegroundRole instead)
- \omit
- \row \o \l Qt::ToolTipRole
- \row \o \l Qt::WhatsThisRole
- \endomit
- \endtable
-
- If the default delegate does not allow the level of customization that
- you need, either for display purposes or for editing data, it is possible to
- subclass QItemDelegate to implement the desired behavior.
-
- \section1 Subclassing
-
- When subclassing QItemDelegate to create a delegate that displays items
- using a custom renderer, it is important to ensure that the delegate can
- render items suitably for all the required states; e.g. selected,
- disabled, checked. The documentation for the paint() function contains
- some hints to show how this can be achieved.
-
- You can provide custom editors by using a QItemEditorFactory. The
- \l{Color Editor Factory Example} shows how a custom editor can be
- made available to delegates with the default item editor
- factory. This way, there is no need to subclass QItemDelegate. An
- alternative is to reimplement createEditor(), setEditorData(),
- 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}
-*/
-
-/*!
- Constructs an item delegate with the given \a parent.
-*/
-
-QItemDelegate::QItemDelegate(QObject *parent)
- : QAbstractItemDelegate(*new QItemDelegatePrivate(), parent)
-{
-
-}
-
-/*!
- Destroys the item delegate.
-*/
-
-QItemDelegate::~QItemDelegate()
-{
-}
-
-/*!
- \property QItemDelegate::clipping
- \brief if the delegate should clip the paint events
- \since 4.2
-
- This property will set the paint clip to the size of the item.
- The default value is on. It is useful for cases such
- as when images are larger than the size of the item.
-*/
-
-bool QItemDelegate::hasClipping() const
-{
- Q_D(const QItemDelegate);
- return d->clipPainting;
-}
-
-void QItemDelegate::setClipping(bool clip)
-{
- Q_D(QItemDelegate);
- d->clipPainting = clip;
-}
-
-QString QItemDelegatePrivate::valueToText(const QVariant &value, const QStyleOptionViewItemV4 &option)
-{
- QString text;
- switch (value.userType()) {
- case QMetaType::Float:
- text = option.locale.toString(value.toFloat(), 'g');
- break;
- case QVariant::Double:
- text = option.locale.toString(value.toDouble(), 'g', DBL_DIG);
- break;
- case QVariant::Int:
- case QVariant::LongLong:
- text = option.locale.toString(value.toLongLong());
- break;
- case QVariant::UInt:
- case QVariant::ULongLong:
- text = option.locale.toString(value.toULongLong());
- break;
- case QVariant::Date:
- text = option.locale.toString(value.toDate(), QLocale::ShortFormat);
- break;
- case QVariant::Time:
- text = option.locale.toString(value.toTime(), QLocale::ShortFormat);
- break;
- case QVariant::DateTime:
- text = option.locale.toString(value.toDateTime().date(), QLocale::ShortFormat);
- text += QLatin1Char(' ');
- text += option.locale.toString(value.toDateTime().time(), QLocale::ShortFormat);
- break;
- default:
- text = replaceNewLine(value.toString());
- break;
- }
- return text;
-}
-
-/*!
- Renders the delegate using the given \a painter and style \a option for
- the item specified by \a index.
-
- When reimplementing this function in a subclass, you should update the area
- held by the option's \l{QStyleOption::rect}{rect} variable, using the
- option's \l{QStyleOption::state}{state} variable to determine the state of
- the item to be displayed, and adjust the way it is painted accordingly.
-
- For example, a selected item may need to be displayed differently to
- unselected items, as shown in the following code:
-
- \snippet examples/itemviews/pixelator/pixeldelegate.cpp 2
- \dots
-
- After painting, you should ensure that the painter is returned to its
- the state it was supplied in when this function was called. For example,
- it may be useful to call QPainter::save() before painting and
- QPainter::restore() afterwards.
-
- \sa QStyle::State
-*/
-void QItemDelegate::paint(QPainter *painter,
- const QStyleOptionViewItem &option,
- const QModelIndex &index) const
-{
- Q_D(const QItemDelegate);
- Q_ASSERT(index.isValid());
-
- QStyleOptionViewItemV4 opt = setOptions(index, option);
-
- const QStyleOptionViewItemV2 *v2 = qstyleoption_cast<const QStyleOptionViewItemV2 *>(&option);
- opt.features = v2 ? v2->features
- : QStyleOptionViewItemV2::ViewItemFeatures(QStyleOptionViewItemV2::None);
- const QStyleOptionViewItemV3 *v3 = qstyleoption_cast<const QStyleOptionViewItemV3 *>(&option);
- opt.locale = v3 ? v3->locale : QLocale();
- opt.widget = v3 ? v3->widget : 0;
-
- // prepare
- painter->save();
- if (d->clipPainting)
- painter->setClipRect(opt.rect);
-
- // get the data and the rectangles
-
- QVariant value;
-
- QPixmap pixmap;
- QRect decorationRect;
- value = index.data(Qt::DecorationRole);
- if (value.isValid()) {
- // ### we need the pixmap to call the virtual function
- pixmap = decoration(opt, value);
- if (value.type() == QVariant::Icon) {
- d->tmp.icon = qvariant_cast<QIcon>(value);
- d->tmp.mode = d->iconMode(option.state);
- d->tmp.state = d->iconState(option.state);
- const QSize size = d->tmp.icon.actualSize(option.decorationSize,
- d->tmp.mode, d->tmp.state);
- decorationRect = QRect(QPoint(0, 0), size);
- } else {
- d->tmp.icon = QIcon();
- decorationRect = QRect(QPoint(0, 0), pixmap.size());
- }
- } else {
- d->tmp.icon = QIcon();
- decorationRect = QRect();
- }
-
- QString text;
- QRect displayRect;
- value = index.data(Qt::DisplayRole);
- if (value.isValid() && !value.isNull()) {
- text = QItemDelegatePrivate::valueToText(value, opt);
- displayRect = textRectangle(painter, d->textLayoutBounds(opt), opt.font, text);
- }
-
- QRect checkRect;
- Qt::CheckState checkState = Qt::Unchecked;
- value = index.data(Qt::CheckStateRole);
- if (value.isValid()) {
- checkState = static_cast<Qt::CheckState>(value.toInt());
- checkRect = check(opt, opt.rect, value);
- }
-
- // do the layout
-
- doLayout(opt, &checkRect, &decorationRect, &displayRect, false);
-
- // draw the item
-
- drawBackground(painter, opt, index);
- drawCheck(painter, opt, checkRect, checkState);
- drawDecoration(painter, opt, decorationRect, pixmap);
- drawDisplay(painter, opt, displayRect, text);
- drawFocus(painter, opt, displayRect);
-
- // done
- painter->restore();
-}
-
-/*!
- Returns the size needed by the delegate to display the item
- specified by \a index, taking into account the style information
- provided by \a option.
-
- When reimplementing this function, note that in case of text
- items, QItemDelegate adds a margin (i.e. 2 *
- QStyle::PM_FocusFrameHMargin) to the length of the text.
-*/
-
-QSize QItemDelegate::sizeHint(const QStyleOptionViewItem &option,
- const QModelIndex &index) const
-{
- QVariant value = index.data(Qt::SizeHintRole);
- if (value.isValid())
- return qvariant_cast<QSize>(value);
- QRect decorationRect = rect(option, index, Qt::DecorationRole);
- QRect displayRect = rect(option, index, Qt::DisplayRole);
- QRect checkRect = rect(option, index, Qt::CheckStateRole);
-
- doLayout(option, &checkRect, &decorationRect, &displayRect, true);
-
- return (decorationRect|displayRect|checkRect).size();
-}
-
-/*!
- Returns the widget used to edit the item specified by \a index
- for editing. The \a parent widget and style \a option are used to
- control how the editor widget appears.
-
- \sa QAbstractItemDelegate::createEditor()
-*/
-
-QWidget *QItemDelegate::createEditor(QWidget *parent,
- const QStyleOptionViewItem &,
- const QModelIndex &index) const
-{
- Q_D(const QItemDelegate);
- if (!index.isValid())
- return 0;
- QVariant::Type t = static_cast<QVariant::Type>(index.data(Qt::EditRole).userType());
- const QItemEditorFactory *factory = d->f;
- if (factory == 0)
- factory = QItemEditorFactory::defaultFactory();
- return factory->createEditor(t, parent);
-}
-
-/*!
- Sets the data to be displayed and edited by the \a editor from the
- data model item specified by the model \a index.
-
- The default implementation stores the data in the \a editor
- widget's \l {Qt's Property System} {user property}.
-
- \sa QMetaProperty::isUser()
-*/
-
-void QItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
-{
-#ifdef QT_NO_PROPERTIES
- Q_UNUSED(editor);
- Q_UNUSED(index);
-#else
- Q_D(const QItemDelegate);
- QVariant v = index.data(Qt::EditRole);
- QByteArray n = editor->metaObject()->userProperty().name();
-
- // ### Qt 5: remove
- // A work-around for missing "USER true" in qdatetimeedit.h for
- // QTimeEdit's time property and QDateEdit's date property.
- // It only triggers if the default user property "dateTime" is
- // reported for QTimeEdit and QDateEdit.
- if (n == "dateTime") {
- if (editor->inherits("QTimeEdit"))
- n = "time";
- else if (editor->inherits("QDateEdit"))
- n = "date";
- }
-
- // ### Qt 5: give QComboBox a USER property
- if (n.isEmpty() && editor->inherits("QComboBox"))
- n = d->editorFactory()->valuePropertyName(static_cast<QVariant::Type>(v.userType()));
- if (!n.isEmpty()) {
- if (!v.isValid())
- v = QVariant(editor->property(n).userType(), (const void *)0);
- editor->setProperty(n, v);
- }
-#endif
-}
-
-/*!
- Gets data from the \a editor widget and stores it in the specified
- \a model at the item \a index.
-
- The default implementation gets the value to be stored in the data
- model from the \a editor widget's \l {Qt's Property System} {user
- property}.
-
- \sa QMetaProperty::isUser()
-*/
-
-void QItemDelegate::setModelData(QWidget *editor,
- QAbstractItemModel *model,
- const QModelIndex &index) const
-{
-#ifdef QT_NO_PROPERTIES
- Q_UNUSED(model);
- Q_UNUSED(editor);
- Q_UNUSED(index);
-#else
- Q_D(const QItemDelegate);
- Q_ASSERT(model);
- Q_ASSERT(editor);
- QByteArray n = editor->metaObject()->userProperty().name();
- if (n.isEmpty())
- n = d->editorFactory()->valuePropertyName(
- static_cast<QVariant::Type>(model->data(index, Qt::EditRole).userType()));
- if (!n.isEmpty())
- model->setData(index, editor->property(n), Qt::EditRole);
-#endif
-}
-
-/*!
- Updates the \a editor for the item specified by \a index
- according to the style \a option given.
-*/
-
-void QItemDelegate::updateEditorGeometry(QWidget *editor,
- const QStyleOptionViewItem &option,
- const QModelIndex &index) const
-{
- if (!editor)
- return;
- Q_ASSERT(index.isValid());
- QPixmap pixmap = decoration(option, index.data(Qt::DecorationRole));
- QString text = QItemDelegatePrivate::replaceNewLine(index.data(Qt::DisplayRole).toString());
- QRect pixmapRect = QRect(QPoint(0, 0), option.decorationSize).intersected(pixmap.rect());
- QRect textRect = textRectangle(0, option.rect, option.font, text);
- QRect checkRect = check(option, textRect, index.data(Qt::CheckStateRole));
- QStyleOptionViewItem opt = option;
- opt.showDecorationSelected = true; // let the editor take up all available space
- doLayout(opt, &checkRect, &pixmapRect, &textRect, false);
- editor->setGeometry(textRect);
-}
-
-/*!
- Returns the editor factory used by the item delegate.
- If no editor factory is set, the function will return null.
-
- \sa setItemEditorFactory()
-*/
-QItemEditorFactory *QItemDelegate::itemEditorFactory() const
-{
- Q_D(const QItemDelegate);
- return d->f;
-}
-
-/*!
- Sets the editor factory to be used by the item delegate to be the \a factory
- specified. If no editor factory is set, the item delegate will use the
- default editor factory.
-
- \sa itemEditorFactory()
-*/
-void QItemDelegate::setItemEditorFactory(QItemEditorFactory *factory)
-{
- Q_D(QItemDelegate);
- d->f = factory;
-}
-
-/*!
- Renders the item view \a text within the rectangle specified by \a rect
- using the given \a painter and style \a option.
-*/
-
-void QItemDelegate::drawDisplay(QPainter *painter, const QStyleOptionViewItem &option,
- const QRect &rect, const QString &text) const
-{
- Q_D(const QItemDelegate);
-
- QPalette::ColorGroup cg = option.state & QStyle::State_Enabled
- ? QPalette::Normal : QPalette::Disabled;
- if (cg == QPalette::Normal && !(option.state & QStyle::State_Active))
- cg = QPalette::Inactive;
- if (option.state & QStyle::State_Selected) {
- painter->fillRect(rect, option.palette.brush(cg, QPalette::Highlight));
- painter->setPen(option.palette.color(cg, QPalette::HighlightedText));
- } else {
- painter->setPen(option.palette.color(cg, QPalette::Text));
- }
-
- if (text.isEmpty())
- return;
-
- if (option.state & QStyle::State_Editing) {
- painter->save();
- painter->setPen(option.palette.color(cg, QPalette::Text));
- painter->drawRect(rect.adjusted(0, 0, -1, -1));
- painter->restore();
- }
-
- const QStyleOptionViewItemV4 opt = option;
-
- const QWidget *widget = d->widget(option);
- QStyle *style = widget ? widget->style() : QApplication::style();
- const int textMargin = style->pixelMetric(QStyle::PM_FocusFrameHMargin, 0, widget) + 1;
- QRect textRect = rect.adjusted(textMargin, 0, -textMargin, 0); // remove width padding
- const bool wrapText = opt.features & QStyleOptionViewItemV2::WrapText;
- d->textOption.setWrapMode(wrapText ? QTextOption::WordWrap : QTextOption::ManualWrap);
- d->textOption.setTextDirection(option.direction);
- d->textOption.setAlignment(QStyle::visualAlignment(option.direction, option.displayAlignment));
- d->textLayout.setTextOption(d->textOption);
- d->textLayout.setFont(option.font);
- d->textLayout.setText(QItemDelegatePrivate::replaceNewLine(text));
-
- QSizeF textLayoutSize = d->doTextLayout(textRect.width());
-
- if (textRect.width() < textLayoutSize.width()
- || textRect.height() < textLayoutSize.height()) {
- QString elided;
- int start = 0;
- int end = text.indexOf(QChar::LineSeparator, start);
- if (end == -1) {
- elided += option.fontMetrics.elidedText(text, option.textElideMode, textRect.width());
- } else {
- while (end != -1) {
- elided += option.fontMetrics.elidedText(text.mid(start, end - start),
- option.textElideMode, textRect.width());
- elided += QChar::LineSeparator;
- start = end + 1;
- end = text.indexOf(QChar::LineSeparator, start);
- }
- //let's add the last line (after the last QChar::LineSeparator)
- elided += option.fontMetrics.elidedText(text.mid(start),
- option.textElideMode, textRect.width());
- }
- d->textLayout.setText(elided);
- textLayoutSize = d->doTextLayout(textRect.width());
- }
-
- const QSize layoutSize(textRect.width(), int(textLayoutSize.height()));
- const QRect layoutRect = QStyle::alignedRect(option.direction, option.displayAlignment,
- layoutSize, textRect);
- // if we still overflow even after eliding the text, enable clipping
- if (!hasClipping() && (textRect.width() < textLayoutSize.width()
- || textRect.height() < textLayoutSize.height())) {
- painter->save();
- painter->setClipRect(layoutRect);
- d->textLayout.draw(painter, layoutRect.topLeft(), QVector<QTextLayout::FormatRange>(), layoutRect);
- painter->restore();
- } else {
- d->textLayout.draw(painter, layoutRect.topLeft(), QVector<QTextLayout::FormatRange>(), layoutRect);
- }
-}
-
-/*!
- Renders the decoration \a pixmap within the rectangle specified by
- \a rect using the given \a painter and style \a option.
-*/
-void QItemDelegate::drawDecoration(QPainter *painter, const QStyleOptionViewItem &option,
- const QRect &rect, const QPixmap &pixmap) const
-{
- Q_D(const QItemDelegate);
- // if we have an icon, we ignore the pixmap
- if (!d->tmp.icon.isNull()) {
- d->tmp.icon.paint(painter, rect, option.decorationAlignment,
- d->tmp.mode, d->tmp.state);
- return;
- }
-
- if (pixmap.isNull() || !rect.isValid())
- return;
- QPoint p = QStyle::alignedRect(option.direction, option.decorationAlignment,
- pixmap.size(), rect).topLeft();
- if (option.state & QStyle::State_Selected) {
- QPixmap *pm = selected(pixmap, option.palette, option.state & QStyle::State_Enabled);
- painter->drawPixmap(p, *pm);
- } else {
- painter->drawPixmap(p, pixmap);
- }
-}
-
-/*!
- Renders the region within the rectangle specified by \a rect, indicating
- that it has the focus, using the given \a painter and style \a option.
-*/
-
-void QItemDelegate::drawFocus(QPainter *painter,
- const QStyleOptionViewItem &option,
- const QRect &rect) const
-{
- Q_D(const QItemDelegate);
- if ((option.state & QStyle::State_HasFocus) == 0 || !rect.isValid())
- return;
- QStyleOptionFocusRect o;
- o.QStyleOption::operator=(option);
- o.rect = rect;
- o.state |= QStyle::State_KeyboardFocusChange;
- o.state |= QStyle::State_Item;
- QPalette::ColorGroup cg = (option.state & QStyle::State_Enabled)
- ? QPalette::Normal : QPalette::Disabled;
- o.backgroundColor = option.palette.color(cg, (option.state & QStyle::State_Selected)
- ? QPalette::Highlight : QPalette::Window);
- const QWidget *widget = d->widget(option);
- QStyle *style = widget ? widget->style() : QApplication::style();
- style->drawPrimitive(QStyle::PE_FrameFocusRect, &o, painter, widget);
-}
-
-/*!
- Renders a check indicator within the rectangle specified by \a
- rect, using the given \a painter and style \a option, using the
- given \a state.
-*/
-
-void QItemDelegate::drawCheck(QPainter *painter,
- const QStyleOptionViewItem &option,
- const QRect &rect, Qt::CheckState state) const
-{
- Q_D(const QItemDelegate);
- if (!rect.isValid())
- return;
-
- QStyleOptionViewItem opt(option);
- opt.rect = rect;
- opt.state = opt.state & ~QStyle::State_HasFocus;
-
- switch (state) {
- case Qt::Unchecked:
- opt.state |= QStyle::State_Off;
- break;
- case Qt::PartiallyChecked:
- opt.state |= QStyle::State_NoChange;
- break;
- case Qt::Checked:
- opt.state |= QStyle::State_On;
- break;
- }
-
- const QWidget *widget = d->widget(option);
- QStyle *style = widget ? widget->style() : QApplication::style();
- style->drawPrimitive(QStyle::PE_IndicatorViewItemCheck, &opt, painter, widget);
-}
-
-/*!
- \since 4.2
-
- Renders the item background for the given \a index,
- using the given \a painter and style \a option.
-*/
-
-void QItemDelegate::drawBackground(QPainter *painter,
- const QStyleOptionViewItem &option,
- const QModelIndex &index) const
-{
- if (option.showDecorationSelected && (option.state & QStyle::State_Selected)) {
- QPalette::ColorGroup cg = option.state & QStyle::State_Enabled
- ? QPalette::Normal : QPalette::Disabled;
- if (cg == QPalette::Normal && !(option.state & QStyle::State_Active))
- cg = QPalette::Inactive;
-
- painter->fillRect(option.rect, option.palette.brush(cg, QPalette::Highlight));
- } else {
- QVariant value = index.data(Qt::BackgroundRole);
- if (value.canConvert<QBrush>()) {
- QPointF oldBO = painter->brushOrigin();
- painter->setBrushOrigin(option.rect.topLeft());
- painter->fillRect(option.rect, qvariant_cast<QBrush>(value));
- painter->setBrushOrigin(oldBO);
- }
- }
-}
-
-
-/*!
- \internal
-
- Code duplicated in QCommonStylePrivate::viewItemLayout
-*/
-
-void QItemDelegate::doLayout(const QStyleOptionViewItem &option,
- QRect *checkRect, QRect *pixmapRect, QRect *textRect,
- bool hint) const
-{
- Q_ASSERT(checkRect && pixmapRect && textRect);
- Q_D(const QItemDelegate);
- const QWidget *widget = d->widget(option);
- QStyle *style = widget ? widget->style() : QApplication::style();
- const bool hasCheck = checkRect->isValid();
- const bool hasPixmap = pixmapRect->isValid();
- const bool hasText = textRect->isValid();
- const int textMargin = hasText ? style->pixelMetric(QStyle::PM_FocusFrameHMargin, 0, widget) + 1 : 0;
- const int pixmapMargin = hasPixmap ? style->pixelMetric(QStyle::PM_FocusFrameHMargin, 0, widget) + 1 : 0;
- const int checkMargin = hasCheck ? style->pixelMetric(QStyle::PM_FocusFrameHMargin, 0, widget) + 1 : 0;
- int x = option.rect.left();
- int y = option.rect.top();
- int w, h;
-
- textRect->adjust(-textMargin, 0, textMargin, 0); // add width padding
- if (textRect->height() == 0 && (!hasPixmap || !hint)) {
- //if there is no text, we still want to have a decent height for the item sizeHint and the editor size
- textRect->setHeight(option.fontMetrics.height());
- }
-
- QSize pm(0, 0);
- if (hasPixmap) {
- pm = pixmapRect->size();
- pm.rwidth() += 2 * pixmapMargin;
- }
- if (hint) {
- h = qMax(checkRect->height(), qMax(textRect->height(), pm.height()));
- if (option.decorationPosition == QStyleOptionViewItem::Left
- || option.decorationPosition == QStyleOptionViewItem::Right) {
- w = textRect->width() + pm.width();
- } else {
- w = qMax(textRect->width(), pm.width());
- }
- } else {
- w = option.rect.width();
- h = option.rect.height();
- }
-
- int cw = 0;
- QRect check;
- if (hasCheck) {
- cw = checkRect->width() + 2 * checkMargin;
- if (hint) w += cw;
- if (option.direction == Qt::RightToLeft) {
- check.setRect(x + w - cw, y, cw, h);
- } else {
- check.setRect(x + checkMargin, y, cw, h);
- }
- }
-
- // at this point w should be the *total* width
-
- QRect display;
- QRect decoration;
- switch (option.decorationPosition) {
- case QStyleOptionViewItem::Top: {
- if (hasPixmap)
- pm.setHeight(pm.height() + pixmapMargin); // add space
- h = hint ? textRect->height() : h - pm.height();
-
- if (option.direction == Qt::RightToLeft) {
- decoration.setRect(x, y, w - cw, pm.height());
- display.setRect(x, y + pm.height(), w - cw, h);
- } else {
- decoration.setRect(x + cw, y, w - cw, pm.height());
- display.setRect(x + cw, y + pm.height(), w - cw, h);
- }
- break; }
- case QStyleOptionViewItem::Bottom: {
- if (hasText)
- textRect->setHeight(textRect->height() + textMargin); // add space
- h = hint ? textRect->height() + pm.height() : h;
-
- if (option.direction == Qt::RightToLeft) {
- display.setRect(x, y, w - cw, textRect->height());
- decoration.setRect(x, y + textRect->height(), w - cw, h - textRect->height());
- } else {
- display.setRect(x + cw, y, w - cw, textRect->height());
- decoration.setRect(x + cw, y + textRect->height(), w - cw, h - textRect->height());
- }
- break; }
- case QStyleOptionViewItem::Left: {
- if (option.direction == Qt::LeftToRight) {
- decoration.setRect(x + cw, y, pm.width(), h);
- display.setRect(decoration.right() + 1, y, w - pm.width() - cw, h);
- } else {
- display.setRect(x, y, w - pm.width() - cw, h);
- decoration.setRect(display.right() + 1, y, pm.width(), h);
- }
- break; }
- case QStyleOptionViewItem::Right: {
- if (option.direction == Qt::LeftToRight) {
- display.setRect(x + cw, y, w - pm.width() - cw, h);
- decoration.setRect(display.right() + 1, y, pm.width(), h);
- } else {
- decoration.setRect(x, y, pm.width(), h);
- display.setRect(decoration.right() + 1, y, w - pm.width() - cw, h);
- }
- break; }
- default:
- qWarning("doLayout: decoration position is invalid");
- decoration = *pixmapRect;
- break;
- }
-
- if (!hint) { // we only need to do the internal layout if we are going to paint
- *checkRect = QStyle::alignedRect(option.direction, Qt::AlignCenter,
- checkRect->size(), check);
- *pixmapRect = QStyle::alignedRect(option.direction, option.decorationAlignment,
- pixmapRect->size(), decoration);
- // the text takes up all available space, unless the decoration is not shown as selected
- if (option.showDecorationSelected)
- *textRect = display;
- else
- *textRect = QStyle::alignedRect(option.direction, option.displayAlignment,
- textRect->size().boundedTo(display.size()), display);
- } else {
- *checkRect = check;
- *pixmapRect = decoration;
- *textRect = display;
- }
-}
-
-/*!
- \internal
-
- Returns the pixmap used to decorate the root of the item view.
- The style \a option controls the appearance of the root; the \a variant
- refers to the data associated with an item.
-*/
-
-QPixmap QItemDelegate::decoration(const QStyleOptionViewItem &option, const QVariant &variant) const
-{
- Q_D(const QItemDelegate);
- switch (variant.type()) {
- case QVariant::Icon: {
- QIcon::Mode mode = d->iconMode(option.state);
- QIcon::State state = d->iconState(option.state);
- return qvariant_cast<QIcon>(variant).pixmap(option.decorationSize, mode, state); }
- case QVariant::Color: {
- static QPixmap pixmap(option.decorationSize);
- pixmap.fill(qvariant_cast<QColor>(variant));
- return pixmap; }
- default:
- break;
- }
-
- return qvariant_cast<QPixmap>(variant);
-}
-
-// hacky but faster version of "QString::sprintf("%d-%d", i, enabled)"
-static QString qPixmapSerial(quint64 i, bool enabled)
-{
- ushort arr[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '-', ushort('0' + enabled) };
- ushort *ptr = &arr[16];
-
- while (i > 0) {
- // hey - it's our internal representation, so use the ascii character after '9'
- // instead of 'a' for hex
- *(--ptr) = '0' + i % 16;
- i >>= 4;
- }
-
- return QString((const QChar *)ptr, int(&arr[sizeof(arr) / sizeof(ushort)] - ptr));
-}
-
-/*!
- \internal
- Returns the selected version of the given \a pixmap using the given \a palette.
- The \a enabled argument decides whether the normal or disabled highlight color of
- the palette is used.
-*/
-QPixmap *QItemDelegate::selected(const QPixmap &pixmap, const QPalette &palette, bool enabled) const
-{
- QString key = qPixmapSerial(qt_pixmap_id(pixmap), enabled);
- QPixmap *pm = QPixmapCache::find(key);
- if (!pm) {
- QImage img = pixmap.toImage().convertToFormat(QImage::Format_ARGB32_Premultiplied);
-
- QColor color = palette.color(enabled ? QPalette::Normal : QPalette::Disabled,
- QPalette::Highlight);
- color.setAlphaF((qreal)0.3);
-
- QPainter painter(&img);
- painter.setCompositionMode(QPainter::CompositionMode_SourceAtop);
- painter.fillRect(0, 0, img.width(), img.height(), color);
- painter.end();
-
- QPixmap selected = QPixmap(QPixmap::fromImage(img));
- int n = (img.byteCount() >> 10) + 1;
- if (QPixmapCache::cacheLimit() < n)
- QPixmapCache::setCacheLimit(n);
-
- QPixmapCache::insert(key, selected);
- pm = QPixmapCache::find(key);
- }
- return pm;
-}
-
-/*!
- \internal
-*/
-
-QRect QItemDelegate::rect(const QStyleOptionViewItem &option,
- const QModelIndex &index, int role) const
-{
- Q_D(const QItemDelegate);
- QVariant value = index.data(role);
- if (role == Qt::CheckStateRole)
- return check(option, option.rect, value);
- if (value.isValid() && !value.isNull()) {
- switch (value.type()) {
- case QVariant::Invalid:
- break;
- case QVariant::Pixmap:
- return QRect(QPoint(0, 0), qvariant_cast<QPixmap>(value).size());
- case QVariant::Image:
- return QRect(QPoint(0, 0), qvariant_cast<QImage>(value).size());
- case QVariant::Icon: {
- QIcon::Mode mode = d->iconMode(option.state);
- QIcon::State state = d->iconState(option.state);
- QIcon icon = qvariant_cast<QIcon>(value);
- QSize size = icon.actualSize(option.decorationSize, mode, state);
- return QRect(QPoint(0, 0), size); }
- case QVariant::Color:
- return QRect(QPoint(0, 0), option.decorationSize);
- case QVariant::String:
- default: {
- QString text = QItemDelegatePrivate::valueToText(value, option);
- value = index.data(Qt::FontRole);
- QFont fnt = qvariant_cast<QFont>(value).resolve(option.font);
- return textRectangle(0, d->textLayoutBounds(option), fnt, text); }
- }
- }
- return QRect();
-}
-
-/*!
- \internal
-
- Note that on Mac, if /usr/include/AssertMacros.h is included prior
- to QItemDelegate, and the application is building in debug mode, the
- check(assertion) will conflict with QItemDelegate::check.
-
- To avoid this problem, add
-
- #ifdef check
- #undef check
- #endif
-
- after including AssertMacros.h
-*/
-QRect QItemDelegate::check(const QStyleOptionViewItem &option,
- const QRect &bounding, const QVariant &value) const
-{
- if (value.isValid()) {
- Q_D(const QItemDelegate);
- QStyleOptionButton opt;
- opt.QStyleOption::operator=(option);
- opt.rect = bounding;
- const QWidget *widget = d->widget(option); // cast
- QStyle *style = widget ? widget->style() : QApplication::style();
- return style->subElementRect(QStyle::SE_ViewItemCheckIndicator, &opt, widget);
- }
- return QRect();
-}
-
-/*!
- \internal
-*/
-QRect QItemDelegate::textRectangle(QPainter * /*painter*/, const QRect &rect,
- const QFont &font, const QString &text) const
-{
- Q_D(const QItemDelegate);
- d->textOption.setWrapMode(QTextOption::WordWrap);
- d->textLayout.setTextOption(d->textOption);
- d->textLayout.setFont(font);
- d->textLayout.setText(QItemDelegatePrivate::replaceNewLine(text));
- QSizeF fpSize = d->doTextLayout(rect.width());
- const QSize size = QSize(qCeil(fpSize.width()), qCeil(fpSize.height()));
- // ###: textRectangle should take style option as argument
- const int textMargin = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1;
- return QRect(0, 0, size.width() + 2 * textMargin, size.height());
-}
-
-/*!
- \fn bool QItemDelegate::eventFilter(QObject *editor, QEvent *event)
-
- Returns true if the given \a editor is a valid QWidget and the
- given \a event is handled; otherwise returns false. The following
- key press events are handled by default:
-
- \list
- \o \gui Tab
- \o \gui Backtab
- \o \gui Enter
- \o \gui Return
- \o \gui Esc
- \endlist
-
- In the case of \gui Tab, \gui Backtab, \gui Enter and \gui Return
- key press events, the \a editor's data is comitted to the model
- and the editor is closed. If the \a event is a \gui Tab key press
- the view will open an editor on the next item in the
- view. Likewise, if the \a event is a \gui Backtab key press the
- view will open an editor on the \e previous item in the view.
-
- If the event is a \gui Esc key press event, the \a editor is
- closed \e without committing its data.
-
- \sa commitData(), closeEditor()
-*/
-
-bool QItemDelegate::eventFilter(QObject *object, QEvent *event)
-{
- QWidget *editor = qobject_cast<QWidget*>(object);
- if (!editor)
- return false;
- if (event->type() == QEvent::KeyPress) {
- switch (static_cast<QKeyEvent *>(event)->key()) {
- case Qt::Key_Tab:
- emit commitData(editor);
- emit closeEditor(editor, QAbstractItemDelegate::EditNextItem);
- return true;
- case Qt::Key_Backtab:
- emit commitData(editor);
- emit closeEditor(editor, QAbstractItemDelegate::EditPreviousItem);
- return true;
- case Qt::Key_Enter:
- case Qt::Key_Return:
-#ifndef QT_NO_TEXTEDIT
- if (qobject_cast<QTextEdit *>(editor) || qobject_cast<QPlainTextEdit *>(editor))
- return false; // don't filter enter key events for QTextEdit
- // We want the editor to be able to process the key press
- // before committing the data (e.g. so it can do
- // validation/fixup of the input).
-#endif // QT_NO_TEXTEDIT
-#ifndef QT_NO_LINEEDIT
- if (QLineEdit *e = qobject_cast<QLineEdit*>(editor))
- if (!e->hasAcceptableInput())
- return false;
-#endif // QT_NO_LINEEDIT
- QMetaObject::invokeMethod(this, "_q_commitDataAndCloseEditor",
- Qt::QueuedConnection, Q_ARG(QWidget*, editor));
- return false;
- case Qt::Key_Escape:
- // don't commit data
- emit closeEditor(editor, QAbstractItemDelegate::RevertModelCache);
- break;
- default:
- return false;
- }
- if (editor->parentWidget())
- editor->parentWidget()->setFocus();
- return true;
- } else if (event->type() == QEvent::FocusOut || (event->type() == QEvent::Hide && editor->isWindow())) {
- //the Hide event will take care of he editors that are in fact complete dialogs
- if (!editor->isActiveWindow() || (QApplication::focusWidget() != editor)) {
- QWidget *w = QApplication::focusWidget();
- while (w) { // don't worry about focus changes internally in the editor
- if (w == editor)
- return false;
- w = w->parentWidget();
- }
-#ifndef QT_NO_DRAGANDDROP
- // The window may lose focus during an drag operation.
- // i.e when dragging involves the taskbar on Windows.
- if (QDragManager::self() && QDragManager::self()->object != 0)
- return false;
-#endif
-
- emit commitData(editor);
- emit closeEditor(editor, NoHint);
- }
- } else if (event->type() == QEvent::ShortcutOverride) {
- if (static_cast<QKeyEvent*>(event)->key() == Qt::Key_Escape) {
- event->accept();
- return true;
- }
- }
- return false;
-}
-
-/*!
- \reimp
-*/
-
-bool QItemDelegate::editorEvent(QEvent *event,
- QAbstractItemModel *model,
- const QStyleOptionViewItem &option,
- const QModelIndex &index)
-{
- Q_ASSERT(event);
- Q_ASSERT(model);
-
- // make sure that the item is checkable
- Qt::ItemFlags flags = model->flags(index);
- if (!(flags & Qt::ItemIsUserCheckable) || !(option.state & QStyle::State_Enabled)
- || !(flags & Qt::ItemIsEnabled))
- return false;
-
- // make sure that we have a check state
- QVariant value = index.data(Qt::CheckStateRole);
- if (!value.isValid())
- return false;
-
- // make sure that we have the right event type
- if ((event->type() == QEvent::MouseButtonRelease)
- || (event->type() == QEvent::MouseButtonDblClick)
- || (event->type() == QEvent::MouseButtonPress)) {
- QRect checkRect = check(option, option.rect, Qt::Checked);
- QRect emptyRect;
- doLayout(option, &checkRect, &emptyRect, &emptyRect, false);
- QMouseEvent *me = static_cast<QMouseEvent*>(event);
- if (me->button() != Qt::LeftButton || !checkRect.contains(me->pos()))
- return false;
-
- // eat the double click events inside the check rect
- if ((event->type() == QEvent::MouseButtonPress)
- || (event->type() == QEvent::MouseButtonDblClick))
- return true;
-
- } else if (event->type() == QEvent::KeyPress) {
- if (static_cast<QKeyEvent*>(event)->key() != Qt::Key_Space
- && static_cast<QKeyEvent*>(event)->key() != Qt::Key_Select)
- return false;
- } else {
- return false;
- }
-
- Qt::CheckState state = (static_cast<Qt::CheckState>(value.toInt()) == Qt::Checked
- ? Qt::Unchecked : Qt::Checked);
- return model->setData(index, state, Qt::CheckStateRole);
-}
-
-/*!
- \internal
-*/
-
-QStyleOptionViewItem QItemDelegate::setOptions(const QModelIndex &index,
- const QStyleOptionViewItem &option) const
-{
- QStyleOptionViewItem opt = option;
-
- // set font
- QVariant value = index.data(Qt::FontRole);
- if (value.isValid()){
- opt.font = qvariant_cast<QFont>(value).resolve(opt.font);
- opt.fontMetrics = QFontMetrics(opt.font);
- }
-
- // set text alignment
- value = index.data(Qt::TextAlignmentRole);
- if (value.isValid())
- opt.displayAlignment = Qt::Alignment(value.toInt());
-
- // set foreground brush
- value = index.data(Qt::ForegroundRole);
- if (value.canConvert<QBrush>())
- opt.palette.setBrush(QPalette::Text, qvariant_cast<QBrush>(value));
-
- return opt;
-}
-
-QT_END_NAMESPACE
-
-#include "moc_qitemdelegate.cpp"
-
-#endif // QT_NO_ITEMVIEWS
diff --git a/src/gui/itemviews/qitemdelegate.h b/src/gui/itemviews/qitemdelegate.h
deleted file mode 100644
index 8562f32a60..0000000000
--- a/src/gui/itemviews/qitemdelegate.h
+++ /dev/null
@@ -1,141 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QITEMDELEGATE_H
-#define QITEMDELEGATE_H
-
-#include <QtGui/qabstractitemdelegate.h>
-#include <QtCore/qstring.h>
-#include <QtGui/qpixmap.h>
-#include <QtCore/qvariant.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_ITEMVIEWS
-
-class QItemDelegatePrivate;
-class QItemEditorFactory;
-
-class Q_GUI_EXPORT QItemDelegate : public QAbstractItemDelegate
-{
- Q_OBJECT
- Q_PROPERTY(bool clipping READ hasClipping WRITE setClipping)
-
-public:
- explicit QItemDelegate(QObject *parent = 0);
- ~QItemDelegate();
-
- bool hasClipping() const;
- void setClipping(bool clip);
-
- // painting
- void paint(QPainter *painter,
- const QStyleOptionViewItem &option,
- const QModelIndex &index) const;
- QSize sizeHint(const QStyleOptionViewItem &option,
- const QModelIndex &index) const;
-
- // editing
- QWidget *createEditor(QWidget *parent,
- const QStyleOptionViewItem &option,
- const QModelIndex &index) const;
-
- void setEditorData(QWidget *editor, const QModelIndex &index) const;
- void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
-
- void updateEditorGeometry(QWidget *editor,
- const QStyleOptionViewItem &option,
- const QModelIndex &index) const;
-
- // editor factory
- QItemEditorFactory *itemEditorFactory() const;
- void setItemEditorFactory(QItemEditorFactory *factory);
-
-protected:
- virtual void drawDisplay(QPainter *painter, const QStyleOptionViewItem &option,
- const QRect &rect, const QString &text) const;
- virtual void drawDecoration(QPainter *painter, const QStyleOptionViewItem &option,
- const QRect &rect, const QPixmap &pixmap) const;
- virtual void drawFocus(QPainter *painter, const QStyleOptionViewItem &option,
- const QRect &rect) const;
- virtual void drawCheck(QPainter *painter, const QStyleOptionViewItem &option,
- const QRect &rect, Qt::CheckState state) const;
- void drawBackground(QPainter *painter, const QStyleOptionViewItem &option,
- const QModelIndex &index) const;
-
- void doLayout(const QStyleOptionViewItem &option,
- QRect *checkRect, QRect *iconRect, QRect *textRect, bool hint) const;
-
- QRect rect(const QStyleOptionViewItem &option, const QModelIndex &index, int role) const;
-
- bool eventFilter(QObject *object, QEvent *event);
- bool editorEvent(QEvent *event, QAbstractItemModel *model,
- const QStyleOptionViewItem &option, const QModelIndex &index);
-
- QStyleOptionViewItem setOptions(const QModelIndex &index,
- const QStyleOptionViewItem &option) const;
-
- QPixmap decoration(const QStyleOptionViewItem &option, const QVariant &variant) const;
- QPixmap *selected(const QPixmap &pixmap, const QPalette &palette, bool enabled) const;
-
- QRect check(const QStyleOptionViewItem &option, const QRect &bounding,
- const QVariant &variant) const;
- QRect textRectangle(QPainter *painter, const QRect &rect,
- const QFont &font, const QString &text) const;
-
-private:
- Q_DECLARE_PRIVATE(QItemDelegate)
- Q_DISABLE_COPY(QItemDelegate)
-
- Q_PRIVATE_SLOT(d_func(), void _q_commitDataAndCloseEditor(QWidget*))
-};
-
-#endif // QT_NO_ITEMVIEWS
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QITEMDELEGATE_H
diff --git a/src/gui/itemviews/qitemeditorfactory.h b/src/gui/itemviews/qitemeditorfactory.h
deleted file mode 100644
index 5b70e6ac8b..0000000000
--- a/src/gui/itemviews/qitemeditorfactory.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QITEMEDITORFACTORY_H
-#define QITEMEDITORFACTORY_H
-
-#include <QtCore/qmetaobject.h>
-#include <QtCore/qbytearray.h>
-#include <QtCore/qhash.h>
-#include <QtCore/qvariant.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_ITEMVIEWS
-
-class QWidget;
-
-class Q_GUI_EXPORT QItemEditorCreatorBase
-{
-public:
- virtual ~QItemEditorCreatorBase() {}
-
- virtual QWidget *createWidget(QWidget *parent) const = 0;
- virtual QByteArray valuePropertyName() const = 0;
-};
-
-template <class T>
-class QItemEditorCreator : public QItemEditorCreatorBase
-{
-public:
- inline QItemEditorCreator(const QByteArray &valuePropertyName);
- inline QWidget *createWidget(QWidget *parent) const { return new T(parent); }
- inline QByteArray valuePropertyName() const { return propertyName; }
-
-private:
- QByteArray propertyName;
-};
-
-template <class T>
-class QStandardItemEditorCreator: public QItemEditorCreatorBase
-{
-public:
- inline QStandardItemEditorCreator()
- : propertyName(T::staticMetaObject.userProperty().name())
- {}
- inline QWidget *createWidget(QWidget *parent) const { return new T(parent); }
- inline QByteArray valuePropertyName() const { return propertyName; }
-
-private:
- QByteArray propertyName;
-};
-
-
-template <class T>
-Q_INLINE_TEMPLATE QItemEditorCreator<T>::QItemEditorCreator(const QByteArray &avaluePropertyName)
- : propertyName(avaluePropertyName) {}
-
-class Q_GUI_EXPORT QItemEditorFactory
-{
-public:
- inline QItemEditorFactory() {}
- virtual ~QItemEditorFactory();
-
- virtual QWidget *createEditor(QVariant::Type type, QWidget *parent) const;
- virtual QByteArray valuePropertyName(QVariant::Type type) const;
-
- void registerEditor(QVariant::Type type, QItemEditorCreatorBase *creator);
-
- static const QItemEditorFactory *defaultFactory();
- static void setDefaultFactory(QItemEditorFactory *factory);
-
-private:
- QHash<QVariant::Type, QItemEditorCreatorBase *> creatorMap;
-};
-
-#endif // QT_NO_ITEMVIEWS
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QITEMEDITORFACTORY_H
diff --git a/src/gui/itemviews/qitemselectionmodel.h b/src/gui/itemviews/qitemselectionmodel.h
deleted file mode 100644
index 3f4aa72008..0000000000
--- a/src/gui/itemviews/qitemselectionmodel.h
+++ /dev/null
@@ -1,255 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QITEMSELECTIONMODEL_H
-#define QITEMSELECTIONMODEL_H
-
-#include <QtCore/qset.h>
-#include <QtCore/qvector.h>
-#include <QtCore/qlist.h>
-#include <QtCore/qabstractitemmodel.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_ITEMVIEWS
-
-class Q_GUI_EXPORT QItemSelectionRange
-{
-
-public:
- inline QItemSelectionRange() {}
- inline QItemSelectionRange(const QItemSelectionRange &other)
- : tl(other.tl), br(other.br) {}
- inline QItemSelectionRange(const QModelIndex &topLeft, const QModelIndex &bottomRight);
- explicit inline QItemSelectionRange(const QModelIndex &index)
- { tl = index; br = tl; }
-
- inline int top() const { return tl.row(); }
- inline int left() const { return tl.column(); }
- inline int bottom() const { return br.row(); }
- inline int right() const { return br.column(); }
- inline int width() const { return br.column() - tl.column() + 1; }
- inline int height() const { return br.row() - tl.row() + 1; }
-
- inline QModelIndex topLeft() const { return QModelIndex(tl); }
- inline QModelIndex bottomRight() const { return QModelIndex(br); }
- inline QModelIndex parent() const { return tl.parent(); }
- inline const QAbstractItemModel *model() const { return tl.model(); }
-
- inline bool contains(const QModelIndex &index) const
- {
- return (parent() == index.parent()
- && tl.row() <= index.row() && tl.column() <= index.column()
- && br.row() >= index.row() && br.column() >= index.column());
- }
-
- inline bool contains(int row, int column, const QModelIndex &parentIndex) const
- {
- return (parent() == parentIndex
- && tl.row() <= row && tl.column() <= column
- && br.row() >= row && br.column() >= column);
- }
-
- bool intersects(const QItemSelectionRange &other) const;
- QItemSelectionRange intersect(const QItemSelectionRange &other) const; // ### Qt 5: make QT4_SUPPORT
- inline QItemSelectionRange intersected(const QItemSelectionRange &other) const
- { return intersect(other); }
-
- inline bool operator==(const QItemSelectionRange &other) const
- { return (tl == other.tl && br == other.br); }
- inline bool operator!=(const QItemSelectionRange &other) const
- { return !operator==(other); }
- inline bool operator<(const QItemSelectionRange &other) const
- {
- // Comparing parents will compare the models, but if two equivalent ranges
- // in two different models have invalid parents, they would appear the same
- if (other.tl.model() == tl.model()) {
- // parent has to be calculated, so we only do so once.
- const QModelIndex topLeftParent = tl.parent();
- const QModelIndex otherTopLeftParent = other.tl.parent();
- if (topLeftParent == otherTopLeftParent) {
- if (other.tl.row() == tl.row()) {
- if (other.tl.column() == tl.column()) {
- if (other.br.row() == br.row()) {
- return br.column() < other.br.column();
- }
- return br.row() < other.br.row();
- }
- return tl.column() < other.tl.column();
- }
- return tl.row() < other.tl.row();
- }
- return topLeftParent < otherTopLeftParent;
- }
- return tl.model() < other.tl.model();
- }
-
- inline bool isValid() const
- {
- return (tl.isValid() && br.isValid() && tl.parent() == br.parent()
- && top() <= bottom() && left() <= right());
- }
-
- bool isEmpty() const;
-
- QModelIndexList indexes() const;
-
-private:
- QPersistentModelIndex tl, br;
-};
-Q_DECLARE_TYPEINFO(QItemSelectionRange, Q_MOVABLE_TYPE);
-
-inline QItemSelectionRange::QItemSelectionRange(const QModelIndex &atopLeft,
- const QModelIndex &abottomRight)
-{ tl = atopLeft; br = abottomRight; }
-
-class QItemSelection;
-class QItemSelectionModelPrivate;
-
-class Q_GUI_EXPORT QItemSelectionModel : public QObject
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QItemSelectionModel)
- Q_FLAGS(SelectionFlags)
-
-public:
-
- enum SelectionFlag {
- NoUpdate = 0x0000,
- Clear = 0x0001,
- Select = 0x0002,
- Deselect = 0x0004,
- Toggle = 0x0008,
- Current = 0x0010,
- Rows = 0x0020,
- Columns = 0x0040,
- SelectCurrent = Select | Current,
- ToggleCurrent = Toggle | Current,
- ClearAndSelect = Clear | Select
- };
-
- Q_DECLARE_FLAGS(SelectionFlags, SelectionFlag)
-
- explicit QItemSelectionModel(QAbstractItemModel *model);
- explicit QItemSelectionModel(QAbstractItemModel *model, QObject *parent);
- virtual ~QItemSelectionModel();
-
- QModelIndex currentIndex() const;
-
- bool isSelected(const QModelIndex &index) const;
- bool isRowSelected(int row, const QModelIndex &parent) const;
- bool isColumnSelected(int column, const QModelIndex &parent) const;
-
- bool rowIntersectsSelection(int row, const QModelIndex &parent) const;
- bool columnIntersectsSelection(int column, const QModelIndex &parent) const;
-
- bool hasSelection() const;
-
- QModelIndexList selectedIndexes() const;
- QModelIndexList selectedRows(int column = 0) const;
- QModelIndexList selectedColumns(int row = 0) const;
- const QItemSelection selection() const;
-
- const QAbstractItemModel *model() const;
-
-public Q_SLOTS:
- void setCurrentIndex(const QModelIndex &index, QItemSelectionModel::SelectionFlags command);
- virtual void select(const QModelIndex &index, QItemSelectionModel::SelectionFlags command);
- virtual void select(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command);
- virtual void clear();
- virtual void reset();
-
- void clearSelection();
-
-Q_SIGNALS:
- void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
- void currentChanged(const QModelIndex &current, const QModelIndex &previous);
- void currentRowChanged(const QModelIndex &current, const QModelIndex &previous);
- void currentColumnChanged(const QModelIndex &current, const QModelIndex &previous);
-
-protected:
- QItemSelectionModel(QItemSelectionModelPrivate &dd, QAbstractItemModel *model);
- void emitSelectionChanged(const QItemSelection &newSelection, const QItemSelection &oldSelection);
-
-private:
- Q_DISABLE_COPY(QItemSelectionModel)
- Q_PRIVATE_SLOT(d_func(), void _q_columnsAboutToBeRemoved(const QModelIndex&, int, int))
- Q_PRIVATE_SLOT(d_func(), void _q_rowsAboutToBeRemoved(const QModelIndex&, int, int))
- Q_PRIVATE_SLOT(d_func(), void _q_columnsAboutToBeInserted(const QModelIndex&, int, int))
- Q_PRIVATE_SLOT(d_func(), void _q_rowsAboutToBeInserted(const QModelIndex&, int, int))
- Q_PRIVATE_SLOT(d_func(), void _q_layoutAboutToBeChanged())
- Q_PRIVATE_SLOT(d_func(), void _q_layoutChanged())
-};
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QItemSelectionModel::SelectionFlags)
-
-// dummy implentation of qHash() necessary for instantiating QList<QItemSelectionRange>::toSet() with MSVC
-inline uint qHash(const QItemSelectionRange &) { return 0; }
-
-class Q_GUI_EXPORT QItemSelection : public QList<QItemSelectionRange>
-{
-public:
- QItemSelection() {}
- QItemSelection(const QModelIndex &topLeft, const QModelIndex &bottomRight);
- void select(const QModelIndex &topLeft, const QModelIndex &bottomRight);
- bool contains(const QModelIndex &index) const;
- QModelIndexList indexes() const;
- void merge(const QItemSelection &other, QItemSelectionModel::SelectionFlags command);
- static void split(const QItemSelectionRange &range,
- const QItemSelectionRange &other,
- QItemSelection *result);
-};
-
-#ifndef QT_NO_DEBUG_STREAM
-Q_GUI_EXPORT QDebug operator<<(QDebug, const QItemSelectionRange &);
-#endif
-
-#endif // QT_NO_ITEMVIEWS
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QITEMSELECTIONMODEL_H
diff --git a/src/gui/itemviews/qlistview.cpp b/src/gui/itemviews/qlistview.cpp
deleted file mode 100644
index a0955d256e..0000000000
--- a/src/gui/itemviews/qlistview.cpp
+++ /dev/null
@@ -1,3224 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qlistview.h"
-
-#ifndef QT_NO_LISTVIEW
-#include <qabstractitemdelegate.h>
-#include <qapplication.h>
-#include <qpainter.h>
-#include <qbitmap.h>
-#include <qvector.h>
-#include <qstyle.h>
-#include <qevent.h>
-#include <qscrollbar.h>
-#include <qrubberband.h>
-#include <private/qlistview_p.h>
-#include <qdebug.h>
-#ifndef QT_NO_ACCESSIBILITY
-#include <qaccessible.h>
-#endif
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \class QListView
-
- \brief The QListView class provides a list or icon view onto a model.
-
- \ingroup model-view
- \ingroup advanced
-
-
- A QListView presents items stored in a model, either as a simple
- non-hierarchical list, or as a collection of icons. This class is used
- to provide lists and icon views that were previously provided by the
- \c QListBox and \c QIconView classes, but using the more flexible
- approach provided by Qt's model/view architecture.
-
- The QListView class is one of the \l{Model/View Classes}
- and is part of Qt's \l{Model/View Programming}{model/view framework}.
-
- This view does not display horizontal or vertical headers; to display
- a list of items with a horizontal header, use QTreeView instead.
-
- QListView implements the interfaces defined by the
- QAbstractItemView class to allow it to display data provided by
- models derived from the QAbstractItemModel class.
-
- Items in a list view can be displayed using one of two view modes:
- In \l ListMode, the items are displayed in the form of a simple list;
- in \l IconMode, the list view takes the form of an \e{icon view} in
- which the items are displayed with icons like files in a file manager.
- By default, the list view is in \l ListMode. To change the view mode,
- use the setViewMode() function, and to determine the current view mode,
- use viewMode().
-
- Items in these views are laid out in the direction specified by the
- flow() of the list view. The items may be fixed in place, or allowed
- to move, depending on the view's movement() state.
-
- If the items in the model cannot be completely laid out in the
- direction of flow, they can be wrapped at the boundary of the view
- widget; this depends on isWrapping(). This property is useful when the
- items are being represented by an icon view.
-
- The resizeMode() and layoutMode() govern how and when the items are
- laid out. Items are spaced according to their spacing(), and can exist
- within a notional grid of size specified by gridSize(). The items can
- be rendered as large or small icons depending on their iconSize().
-
- \table 100%
- \row \o \inlineimage windowsxp-listview.png Screenshot of a Windows XP style list view
- \o \inlineimage macintosh-listview.png Screenshot of a Macintosh style table view
- \o \inlineimage plastique-listview.png Screenshot of a Plastique style table view
- \row \o A \l{Windows XP Style Widget Gallery}{Windows XP style} list view.
- \o A \l{Macintosh Style Widget Gallery}{Macintosh style} list view.
- \o A \l{Plastique Style Widget Gallery}{Plastique style} list view.
- \endtable
-
- \section1 Improving Performance
-
- It is possible to give the view hints about the data it is handling in order
- to improve its performance when displaying large numbers of items. One approach
- that can be taken for views that are intended to display items with equal sizes
- is to set the \l uniformItemSizes property to true.
-
- \sa {View Classes}, QTreeView, QTableView, QListWidget
-*/
-
-/*!
- \enum QListView::ViewMode
-
- \value ListMode The items are laid out using TopToBottom flow, with Small size and Static movement
- \value IconMode The items are laid out using LeftToRight flow, with Large size and Free movement
-*/
-
-/*!
- \enum QListView::Movement
-
- \value Static The items cannot be moved by the user.
- \value Free The items can be moved freely by the user.
- \value Snap The items snap to the specified grid when moved; see
- setGridSize().
-*/
-
-/*!
- \enum QListView::Flow
-
- \value LeftToRight The items are laid out in the view from the left
- to the right.
- \value TopToBottom The items are laid out in the view from the top
- to the bottom.
-*/
-
-/*!
- \enum QListView::ResizeMode
-
- \value Fixed The items will only be laid out the first time the view is shown.
- \value Adjust The items will be laid out every time the view is resized.
-*/
-
-/*!
- \enum QListView::LayoutMode
-
- \value SinglePass The items are laid out all at once.
- \value Batched The items are laid out in batches of \l batchSize items.
- \sa batchSize
-*/
-
-/*!
- \since 4.2
- \fn void QListView::indexesMoved(const QModelIndexList &indexes)
-
- This signal is emitted when the specified \a indexes are moved in the view.
-*/
-
-/*!
- Creates a new QListView with the given \a parent to view a model.
- Use setModel() to set the model.
-*/
-QListView::QListView(QWidget *parent)
- : QAbstractItemView(*new QListViewPrivate, parent)
-{
- setViewMode(ListMode);
- setSelectionMode(SingleSelection);
- setAttribute(Qt::WA_MacShowFocusRect);
- Q_D(QListView); // We rely on a qobject_cast for PM_DefaultFrameWidth to change
- d->updateStyledFrameWidths(); // hence we have to force an update now that the object has been constructed
-}
-
-/*!
- \internal
-*/
-QListView::QListView(QListViewPrivate &dd, QWidget *parent)
- : QAbstractItemView(dd, parent)
-{
- setViewMode(ListMode);
- setSelectionMode(SingleSelection);
- setAttribute(Qt::WA_MacShowFocusRect);
- Q_D(QListView); // We rely on a qobject_cast for PM_DefaultFrameWidth to change
- d->updateStyledFrameWidths(); // hence we have to force an update now that the object has been constructed
-}
-
-/*!
- Destroys the view.
-*/
-QListView::~QListView()
-{
-}
-
-/*!
- \property QListView::movement
- \brief whether the items can be moved freely, are snapped to a
- grid, or cannot be moved at all.
-
- This property determines how the user can move the items in the
- view. \l Static means that the items can't be moved the user. \l
- Free means that the user can drag and drop the items to any
- position in the view. \l Snap means that the user can drag and
- drop the items, but only to the positions in a notional grid
- signified by the gridSize property.
-
- Setting this property when the view is visible will cause the
- items to be laid out again.
-
- By default, this property is set to \l Static.
-
- \sa gridSize, resizeMode, viewMode
-*/
-void QListView::setMovement(Movement movement)
-{
- Q_D(QListView);
- d->modeProperties |= uint(QListViewPrivate::Movement);
- d->movement = movement;
-
-#ifndef QT_NO_DRAGANDDROP
- bool movable = (movement != Static);
- setDragEnabled(movable);
- d->viewport->setAcceptDrops(movable);
-#endif
- d->doDelayedItemsLayout();
-}
-
-QListView::Movement QListView::movement() const
-{
- Q_D(const QListView);
- return d->movement;
-}
-
-/*!
- \property QListView::flow
- \brief which direction the items layout should flow.
-
- If this property is \l LeftToRight, the items will be laid out left
- to right. If the \l isWrapping property is true, the layout will wrap
- when it reaches the right side of the visible area. If this
- property is \l TopToBottom, the items will be laid out from the top
- of the visible area, wrapping when it reaches the bottom.
-
- Setting this property when the view is visible will cause the
- items to be laid out again.
-
- By default, this property is set to \l TopToBottom.
-
- \sa viewMode
-*/
-void QListView::setFlow(Flow flow)
-{
- Q_D(QListView);
- d->modeProperties |= uint(QListViewPrivate::Flow);
- d->flow = flow;
- d->doDelayedItemsLayout();
-}
-
-QListView::Flow QListView::flow() const
-{
- Q_D(const QListView);
- return d->flow;
-}
-
-/*!
- \property QListView::isWrapping
- \brief whether the items layout should wrap.
-
- This property holds whether the layout should wrap when there is
- no more space in the visible area. The point at which the layout wraps
- depends on the \l flow property.
-
- Setting this property when the view is visible will cause the
- items to be laid out again.
-
- By default, this property is false.
-
- \sa viewMode
-*/
-void QListView::setWrapping(bool enable)
-{
- Q_D(QListView);
- d->modeProperties |= uint(QListViewPrivate::Wrap);
- d->setWrapping(enable);
- d->doDelayedItemsLayout();
-}
-
-bool QListView::isWrapping() const
-{
- Q_D(const QListView);
- return d->isWrapping();
-}
-
-/*!
- \property QListView::resizeMode
- \brief whether the items are laid out again when the view is resized.
-
- If this property is \l Adjust, the items will be laid out again
- when the view is resized. If the value is \l Fixed, the items will
- not be laid out when the view is resized.
-
- By default, this property is set to \l Fixed.
-
- \sa movement, gridSize, viewMode
-*/
-void QListView::setResizeMode(ResizeMode mode)
-{
- Q_D(QListView);
- d->modeProperties |= uint(QListViewPrivate::ResizeMode);
- d->resizeMode = mode;
-}
-
-QListView::ResizeMode QListView::resizeMode() const
-{
- Q_D(const QListView);
- return d->resizeMode;
-}
-
-/*!
- \property QListView::layoutMode
- \brief determines whether the layout of items should happen immediately or be delayed.
-
- This property holds the layout mode for the items. When the mode
- is \l SinglePass (the default), the items are laid out all in one go.
- When the mode is \l Batched, the items are laid out in batches of \l batchSize
- items, while processing events. This makes it possible to
- instantly view and interact with the visible items while the rest
- are being laid out.
-
- \sa viewMode
-*/
-void QListView::setLayoutMode(LayoutMode mode)
-{
- Q_D(QListView);
- d->layoutMode = mode;
-}
-
-QListView::LayoutMode QListView::layoutMode() const
-{
- Q_D(const QListView);
- return d->layoutMode;
-}
-
-/*!
- \property QListView::spacing
- \brief the space around the items in the layout
-
- This property is the size of the empty space that is padded around
- an item in the layout.
-
- Setting this property when the view is visible will cause the
- items to be laid out again.
-
- By default, this property contains a value of 0.
-
- \sa viewMode
-*/
-// ### Qt5: Use same semantic as layouts (spacing is the size of space
-// *between* items)
-void QListView::setSpacing(int space)
-{
- Q_D(QListView);
- d->modeProperties |= uint(QListViewPrivate::Spacing);
- d->setSpacing(space);
- d->doDelayedItemsLayout();
-}
-
-int QListView::spacing() const
-{
- Q_D(const QListView);
- return d->spacing();
-}
-
-/*!
- \property QListView::batchSize
- \brief the number of items laid out in each batch if \l layoutMode is
- set to \l Batched
-
- The default value is 100.
-
- \since 4.2
-*/
-
-void QListView::setBatchSize(int batchSize)
-{
- Q_D(QListView);
- if (batchSize <= 0) {
- qWarning("Invalid batchSize (%d)", batchSize);
- return;
- }
- d->batchSize = batchSize;
-}
-
-int QListView::batchSize() const
-{
- Q_D(const QListView);
- return d->batchSize;
-}
-
-/*!
- \property QListView::gridSize
- \brief the size of the layout grid
-
- This property is the size of the grid in which the items are laid
- out. The default is an empty size which means that there is no
- grid and the layout is not done in a grid. Setting this property
- to a non-empty size switches on the grid layout. (When a grid
- layout is in force the \l spacing property is ignored.)
-
- Setting this property when the view is visible will cause the
- items to be laid out again.
-
- \sa viewMode
-*/
-void QListView::setGridSize(const QSize &size)
-{
- Q_D(QListView);
- d->modeProperties |= uint(QListViewPrivate::GridSize);
- d->setGridSize(size);
- d->doDelayedItemsLayout();
-}
-
-QSize QListView::gridSize() const
-{
- Q_D(const QListView);
- return d->gridSize();
-}
-
-/*!
- \property QListView::viewMode
- \brief the view mode of the QListView.
-
- This property will change the other unset properties to conform
- with the set view mode. QListView-specific properties that have already been set
- will not be changed, unless clearPropertyFlags() has been called.
-
- Setting the view mode will enable or disable drag and drop based on the
- selected movement. For ListMode, the default movement is \l Static
- (drag and drop disabled); for IconMode, the default movement is
- \l Free (drag and drop enabled).
-
- \sa isWrapping, spacing, gridSize, flow, movement, resizeMode
-*/
-void QListView::setViewMode(ViewMode mode)
-{
- Q_D(QListView);
- if (d->commonListView && d->viewMode == mode)
- return;
- d->viewMode = mode;
-
- delete d->commonListView;
- if (mode == ListMode) {
- d->commonListView = new QListModeViewBase(this, d);
- if (!(d->modeProperties & QListViewPrivate::Wrap))
- d->setWrapping(false);
- if (!(d->modeProperties & QListViewPrivate::Spacing))
- d->setSpacing(0);
- if (!(d->modeProperties & QListViewPrivate::GridSize))
- d->setGridSize(QSize());
- if (!(d->modeProperties & QListViewPrivate::Flow))
- d->flow = TopToBottom;
- if (!(d->modeProperties & QListViewPrivate::Movement))
- d->movement = Static;
- if (!(d->modeProperties & QListViewPrivate::ResizeMode))
- d->resizeMode = Fixed;
- if (!(d->modeProperties & QListViewPrivate::SelectionRectVisible))
- d->showElasticBand = false;
- } else {
- d->commonListView = new QIconModeViewBase(this, d);
- if (!(d->modeProperties & QListViewPrivate::Wrap))
- d->setWrapping(true);
- if (!(d->modeProperties & QListViewPrivate::Spacing))
- d->setSpacing(0);
- if (!(d->modeProperties & QListViewPrivate::GridSize))
- d->setGridSize(QSize());
- if (!(d->modeProperties & QListViewPrivate::Flow))
- d->flow = LeftToRight;
- if (!(d->modeProperties & QListViewPrivate::Movement))
- d->movement = Free;
- if (!(d->modeProperties & QListViewPrivate::ResizeMode))
- d->resizeMode = Fixed;
- if (!(d->modeProperties & QListViewPrivate::SelectionRectVisible))
- d->showElasticBand = true;
- }
-
-#ifndef QT_NO_DRAGANDDROP
- bool movable = (d->movement != Static);
- setDragEnabled(movable);
- setAcceptDrops(movable);
-#endif
- d->clear();
- d->doDelayedItemsLayout();
-}
-
-QListView::ViewMode QListView::viewMode() const
-{
- Q_D(const QListView);
- return d->viewMode;
-}
-
-/*!
- Clears the QListView-specific property flags. See \l{viewMode}.
-
- Properties inherited from QAbstractItemView are not covered by the
- property flags. Specifically, \l{QAbstractItemView::dragEnabled}
- {dragEnabled} and \l{QAbstractItemView::acceptDrops}
- {acceptsDrops} are computed by QListView when calling
- setMovement() or setViewMode().
-*/
-void QListView::clearPropertyFlags()
-{
- Q_D(QListView);
- d->modeProperties = 0;
-}
-
-/*!
- Returns true if the \a row is hidden; otherwise returns false.
-*/
-bool QListView::isRowHidden(int row) const
-{
- Q_D(const QListView);
- return d->isHidden(row);
-}
-
-/*!
- If \a hide is true, the given \a row will be hidden; otherwise
- the \a row will be shown.
-*/
-void QListView::setRowHidden(int row, bool hide)
-{
- Q_D(QListView);
- const bool hidden = d->isHidden(row);
- if (hide && !hidden)
- d->commonListView->appendHiddenRow(row);
- else if (!hide && hidden)
- d->commonListView->removeHiddenRow(row);
- d->doDelayedItemsLayout();
- d->viewport->update();
-}
-
-/*!
- \reimp
-*/
-QRect QListView::visualRect(const QModelIndex &index) const
-{
- Q_D(const QListView);
- return d->mapToViewport(rectForIndex(index));
-}
-
-/*!
- \reimp
-*/
-void QListView::scrollTo(const QModelIndex &index, ScrollHint hint)
-{
- Q_D(QListView);
-
- if (index.parent() != d->root || index.column() != d->column)
- return;
-
- const QRect rect = visualRect(index);
- if (hint == EnsureVisible && d->viewport->rect().contains(rect)) {
- d->viewport->update(rect);
- return;
- }
-
- if (d->flow == QListView::TopToBottom || d->isWrapping()) // vertical
- verticalScrollBar()->setValue(d->verticalScrollToValue(index, rect, hint));
-
- if (d->flow == QListView::LeftToRight || d->isWrapping()) // horizontal
- horizontalScrollBar()->setValue(d->horizontalScrollToValue(index, rect, hint));
-}
-
-int QListViewPrivate::horizontalScrollToValue(const QModelIndex &index, const QRect &rect,
- QListView::ScrollHint hint) const
-{
- Q_Q(const QListView);
- const QRect area = viewport->rect();
- const bool leftOf = q->isRightToLeft()
- ? (rect.left() < area.left()) && (rect.right() < area.right())
- : rect.left() < area.left();
- const bool rightOf = q->isRightToLeft()
- ? rect.right() > area.right()
- : (rect.right() > area.right()) && (rect.left() > area.left());
- return commonListView->horizontalScrollToValue(q->visualIndex(index), hint, leftOf, rightOf, area, rect);
-}
-
-int QListViewPrivate::verticalScrollToValue(const QModelIndex &index, const QRect &rect,
- QListView::ScrollHint hint) const
-{
- Q_Q(const QListView);
- const QRect area = viewport->rect();
- const bool above = (hint == QListView::EnsureVisible && rect.top() < area.top());
- const bool below = (hint == QListView::EnsureVisible && rect.bottom() > area.bottom());
- return commonListView->verticalScrollToValue(q->visualIndex(index), hint, above, below, area, rect);
-}
-
-void QListViewPrivate::selectAll(QItemSelectionModel::SelectionFlags command)
-{
- if (!selectionModel)
- return;
-
- QItemSelection selection;
- QModelIndex topLeft;
- int row = 0;
- const int colCount = model->columnCount(root);
- for(; row < model->rowCount(root); ++row) {
- if (isHidden(row)) {
- //it might be the end of a selection range
- if (topLeft.isValid()) {
- QModelIndex bottomRight = model->index(row - 1, colCount - 1, root);
- selection.append(QItemSelectionRange(topLeft, bottomRight));
- topLeft = QModelIndex();
- }
- continue;
- }
-
- if (!topLeft.isValid()) //start of a new selection range
- topLeft = model->index(row, 0, root);
- }
-
- if (topLeft.isValid()) {
- //last selected range
- QModelIndex bottomRight = model->index(row - 1, colCount - 1, root);
- selection.append(QItemSelectionRange(topLeft, bottomRight));
- }
-
- if (!selection.isEmpty())
- selectionModel->select(selection, command);
-}
-
-/*!
- \reimp
-
- We have a QListView way of knowing what elements are on the viewport
- through the intersectingSet function
-*/
-QItemViewPaintPairs QListViewPrivate::draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const
-{
- Q_ASSERT(r);
- Q_Q(const QListView);
- QRect &rect = *r;
- const QRect viewportRect = viewport->rect();
- QItemViewPaintPairs ret;
- const QSet<QModelIndex> visibleIndexes = intersectingSet(viewportRect).toList().toSet();
- for (int i = 0; i < indexes.count(); ++i) {
- const QModelIndex &index = indexes.at(i);
- if (visibleIndexes.contains(index)) {
- const QRect current = q->visualRect(index);
- ret += qMakePair(current, index);
- rect |= current;
- }
- }
- rect &= viewportRect;
- return ret;
-}
-
-/*!
- \internal
-*/
-void QListView::reset()
-{
- Q_D(QListView);
- d->clear();
- d->hiddenRows.clear();
- QAbstractItemView::reset();
-}
-
-/*!
- \internal
-*/
-void QListView::setRootIndex(const QModelIndex &index)
-{
- Q_D(QListView);
- d->column = qBound(0, d->column, d->model->columnCount(index) - 1);
- QAbstractItemView::setRootIndex(index);
- // sometimes we get an update before reset() is called
- d->clear();
- d->hiddenRows.clear();
-}
-
-/*!
- \internal
-
- Scroll the view contents by \a dx and \a dy.
-*/
-
-void QListView::scrollContentsBy(int dx, int dy)
-{
- Q_D(QListView);
- d->delayedAutoScroll.stop(); // auto scroll was canceled by the user scrolling
- d->commonListView->scrollContentsBy(dx, dy, d->state == QListView::DragSelectingState);
-}
-
-/*!
- \internal
-
- Resize the internal contents to \a width and \a height and set the
- scroll bar ranges accordingly.
-*/
-void QListView::resizeContents(int width, int height)
-{
- Q_D(QListView);
- d->setContentsSize(width, height);
-}
-
-/*!
- \internal
-*/
-QSize QListView::contentsSize() const
-{
- Q_D(const QListView);
- return d->contentsSize();
-}
-
-/*!
- \reimp
-*/
-void QListView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
-{
- d_func()->commonListView->dataChanged(topLeft, bottomRight);
- QAbstractItemView::dataChanged(topLeft, bottomRight);
-}
-
-/*!
- \reimp
-*/
-void QListView::rowsInserted(const QModelIndex &parent, int start, int end)
-{
- Q_D(QListView);
- // ### be smarter about inserted items
- d->clear();
- d->doDelayedItemsLayout();
- QAbstractItemView::rowsInserted(parent, start, end);
-}
-
-/*!
- \reimp
-*/
-void QListView::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
-{
- Q_D(QListView);
- // if the parent is above d->root in the tree, nothing will happen
- QAbstractItemView::rowsAboutToBeRemoved(parent, start, end);
- if (parent == d->root) {
- QSet<QPersistentModelIndex>::iterator it = d->hiddenRows.begin();
- while (it != d->hiddenRows.end()) {
- int hiddenRow = it->row();
- if (hiddenRow >= start && hiddenRow <= end) {
- it = d->hiddenRows.erase(it);
- } else {
- ++it;
- }
- }
- }
- d->clear();
- d->doDelayedItemsLayout();
-}
-
-/*!
- \reimp
-*/
-void QListView::mouseMoveEvent(QMouseEvent *e)
-{
- if (!isVisible())
- return;
- Q_D(QListView);
- QAbstractItemView::mouseMoveEvent(e);
- if (state() == DragSelectingState
- && d->showElasticBand
- && d->selectionMode != SingleSelection
- && d->selectionMode != NoSelection) {
- QRect rect(d->pressedPosition, e->pos() + QPoint(horizontalOffset(), verticalOffset()));
- rect = rect.normalized();
- d->viewport->update(d->mapToViewport(rect.united(d->elasticBand)));
- d->elasticBand = rect;
- }
-}
-
-/*!
- \reimp
-*/
-void QListView::mouseReleaseEvent(QMouseEvent *e)
-{
- Q_D(QListView);
- QAbstractItemView::mouseReleaseEvent(e);
- // #### move this implementation into a dynamic class
- if (d->showElasticBand && d->elasticBand.isValid()) {
- d->viewport->update(d->mapToViewport(d->elasticBand));
- d->elasticBand = QRect();
- }
-}
-
-/*!
- \reimp
-*/
-void QListView::timerEvent(QTimerEvent *e)
-{
- Q_D(QListView);
- if (e->timerId() == d->batchLayoutTimer.timerId()) {
- if (d->doItemsLayout(d->batchSize)) { // layout is done
- d->batchLayoutTimer.stop();
- updateGeometries();
- d->viewport->update();
- }
- }
- QAbstractItemView::timerEvent(e);
-}
-
-/*!
- \reimp
-*/
-void QListView::resizeEvent(QResizeEvent *e)
-{
- Q_D(QListView);
- if (d->delayedPendingLayout)
- return;
-
- QSize delta = e->size() - e->oldSize();
-
- if (delta.isNull())
- return;
-
- bool listWrap = (d->viewMode == ListMode) && d->wrapItemText;
- bool flowDimensionChanged = (d->flow == LeftToRight && delta.width() != 0)
- || (d->flow == TopToBottom && delta.height() != 0);
-
- // We post a delayed relayout in the following cases :
- // - we're wrapping
- // - the state is NoState, we're adjusting and the size has changed in the flowing direction
- if (listWrap
- || (state() == NoState && d->resizeMode == Adjust && flowDimensionChanged)) {
- d->doDelayedItemsLayout(100); // wait 1/10 sec before starting the layout
- } else {
- QAbstractItemView::resizeEvent(e);
- }
-}
-
-#ifndef QT_NO_DRAGANDDROP
-
-/*!
- \reimp
-*/
-void QListView::dragMoveEvent(QDragMoveEvent *e)
-{
- Q_D(QListView);
- if (!d->commonListView->filterDragMoveEvent(e)) {
- if (viewMode() == QListView::ListMode && flow() == QListView::LeftToRight)
- static_cast<QListModeViewBase *>(d->commonListView)->dragMoveEvent(e);
- else
- QAbstractItemView::dragMoveEvent(e);
- }
-}
-
-
-/*!
- \reimp
-*/
-void QListView::dragLeaveEvent(QDragLeaveEvent *e)
-{
- if (!d_func()->commonListView->filterDragLeaveEvent(e))
- QAbstractItemView::dragLeaveEvent(e);
-}
-
-/*!
- \reimp
-*/
-void QListView::dropEvent(QDropEvent *e)
-{
- if (!d_func()->commonListView->filterDropEvent(e))
- QAbstractItemView::dropEvent(e);
-}
-
-/*!
- \reimp
-*/
-void QListView::startDrag(Qt::DropActions supportedActions)
-{
- if (!d_func()->commonListView->filterStartDrag(supportedActions))
- QAbstractItemView::startDrag(supportedActions);
-}
-
-/*!
- \internal
-
- Called whenever items from the view is dropped on the viewport.
- The \a event provides additional information.
-*/
-void QListView::internalDrop(QDropEvent *event)
-{
- // ### Qt5: remove that function
- Q_UNUSED(event);
-}
-
-/*!
- \internal
-
- Called whenever the user starts dragging items and the items are movable,
- enabling internal dragging and dropping of items.
-*/
-void QListView::internalDrag(Qt::DropActions supportedActions)
-{
- // ### Qt5: remove that function
- Q_UNUSED(supportedActions);
-}
-
-#endif // QT_NO_DRAGANDDROP
-
-/*!
- \reimp
-*/
-QStyleOptionViewItem QListView::viewOptions() const
-{
- Q_D(const QListView);
- QStyleOptionViewItem option = QAbstractItemView::viewOptions();
- if (!d->iconSize.isValid()) { // otherwise it was already set in abstractitemview
- int pm = (d->viewMode == ListMode
- ? style()->pixelMetric(QStyle::PM_ListViewIconSize, 0, this)
- : style()->pixelMetric(QStyle::PM_IconViewIconSize, 0, this));
- option.decorationSize = QSize(pm, pm);
- }
- if (d->viewMode == IconMode) {
- option.showDecorationSelected = false;
- option.decorationPosition = QStyleOptionViewItem::Top;
- option.displayAlignment = Qt::AlignCenter;
- } else {
- option.decorationPosition = QStyleOptionViewItem::Left;
- }
- return option;
-}
-
-
-/*!
- \reimp
-*/
-void QListView::paintEvent(QPaintEvent *e)
-{
- Q_D(QListView);
- if (!d->itemDelegate)
- return;
- QStyleOptionViewItemV4 option = d->viewOptionsV4();
- QPainter painter(d->viewport);
-
- const QVector<QModelIndex> toBeRendered = d->intersectingSet(e->rect().translated(horizontalOffset(), verticalOffset()), false);
-
- const QModelIndex current = currentIndex();
- const QModelIndex hover = d->hover;
- const QAbstractItemModel *itemModel = d->model;
- const QItemSelectionModel *selections = d->selectionModel;
- const bool focus = (hasFocus() || d->viewport->hasFocus()) && current.isValid();
- const bool alternate = d->alternatingColors;
- const QStyle::State state = option.state;
- const QAbstractItemView::State viewState = this->state();
- const bool enabled = (state & QStyle::State_Enabled) != 0;
-
- bool alternateBase = false;
- int previousRow = -2; // trigger the alternateBase adjustment on first pass
-
- int maxSize = (flow() == TopToBottom)
- ? qMax(viewport()->size().width(), d->contentsSize().width()) - 2 * d->spacing()
- : qMax(viewport()->size().height(), d->contentsSize().height()) - 2 * d->spacing();
-
- QVector<QModelIndex>::const_iterator end = toBeRendered.constEnd();
- for (QVector<QModelIndex>::const_iterator it = toBeRendered.constBegin(); it != end; ++it) {
- Q_ASSERT((*it).isValid());
- option.rect = visualRect(*it);
-
- if (flow() == TopToBottom)
- option.rect.setWidth(qMin(maxSize, option.rect.width()));
- else
- option.rect.setHeight(qMin(maxSize, option.rect.height()));
-
- option.state = state;
- if (selections && selections->isSelected(*it))
- option.state |= QStyle::State_Selected;
- if (enabled) {
- QPalette::ColorGroup cg;
- if ((itemModel->flags(*it) & Qt::ItemIsEnabled) == 0) {
- option.state &= ~QStyle::State_Enabled;
- cg = QPalette::Disabled;
- } else {
- cg = QPalette::Normal;
- }
- option.palette.setCurrentColorGroup(cg);
- }
- if (focus && current == *it) {
- option.state |= QStyle::State_HasFocus;
- if (viewState == EditingState)
- option.state |= QStyle::State_Editing;
- }
- if (*it == hover)
- option.state |= QStyle::State_MouseOver;
- else
- option.state &= ~QStyle::State_MouseOver;
-
- if (alternate) {
- int row = (*it).row();
- if (row != previousRow + 1) {
- // adjust alternateBase according to rows in the "gap"
- if (!d->hiddenRows.isEmpty()) {
- for (int r = qMax(previousRow + 1, 0); r < row; ++r) {
- if (!d->isHidden(r))
- alternateBase = !alternateBase;
- }
- } else {
- alternateBase = (row & 1) != 0;
- }
- }
- if (alternateBase) {
- option.features |= QStyleOptionViewItemV2::Alternate;
- } else {
- option.features &= ~QStyleOptionViewItemV2::Alternate;
- }
-
- // draw background of the item (only alternate row). rest of the background
- // is provided by the delegate
- QStyle::State oldState = option.state;
- option.state &= ~QStyle::State_Selected;
- style()->drawPrimitive(QStyle::PE_PanelItemViewRow, &option, &painter, this);
- option.state = oldState;
-
- alternateBase = !alternateBase;
- previousRow = row;
- }
-
- d->delegateForIndex(*it)->paint(&painter, option, *it);
- }
-
-#ifndef QT_NO_DRAGANDDROP
- d->commonListView->paintDragDrop(&painter);
-#endif
-
-#ifndef QT_NO_RUBBERBAND
- // #### move this implementation into a dynamic class
- if (d->showElasticBand && d->elasticBand.isValid()) {
- QStyleOptionRubberBand opt;
- opt.initFrom(this);
- opt.shape = QRubberBand::Rectangle;
- opt.opaque = false;
- opt.rect = d->mapToViewport(d->elasticBand, false).intersected(
- d->viewport->rect().adjusted(-16, -16, 16, 16));
- painter.save();
- style()->drawControl(QStyle::CE_RubberBand, &opt, &painter);
- painter.restore();
- }
-#endif
-}
-
-/*!
- \reimp
-*/
-QModelIndex QListView::indexAt(const QPoint &p) const
-{
- Q_D(const QListView);
- QRect rect(p.x() + horizontalOffset(), p.y() + verticalOffset(), 1, 1);
- const QVector<QModelIndex> intersectVector = d->intersectingSet(rect);
- QModelIndex index = intersectVector.count() > 0
- ? intersectVector.last() : QModelIndex();
- if (index.isValid() && visualRect(index).contains(p))
- return index;
- return QModelIndex();
-}
-
-/*!
- \reimp
-*/
-int QListView::horizontalOffset() const
-{
- return d_func()->commonListView->horizontalOffset();
-}
-
-/*!
- \reimp
-*/
-int QListView::verticalOffset() const
-{
- return d_func()->commonListView->verticalOffset();
-}
-
-/*!
- \reimp
-*/
-QModelIndex QListView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers)
-{
- Q_D(QListView);
- Q_UNUSED(modifiers);
-
- QModelIndex current = currentIndex();
- if (!current.isValid()) {
- int rowCount = d->model->rowCount(d->root);
- if (!rowCount)
- return QModelIndex();
- int row = 0;
- while (row < rowCount && d->isHiddenOrDisabled(row))
- ++row;
- if (row >= rowCount)
- return QModelIndex();
- return d->model->index(row, d->column, d->root);
- }
-
- const QRect initialRect = rectForIndex(current);
- QRect rect = initialRect;
- if (rect.isEmpty()) {
- return d->model->index(0, d->column, d->root);
- }
- if (d->gridSize().isValid()) rect.setSize(d->gridSize());
-
- QSize contents = d->contentsSize();
- QVector<QModelIndex> intersectVector;
-
- switch (cursorAction) {
- case MoveLeft:
- while (intersectVector.isEmpty()) {
- rect.translate(-rect.width(), 0);
- if (rect.right() <= 0)
- return current;
- if (rect.left() < 0)
- rect.setLeft(0);
- intersectVector = d->intersectingSet(rect);
- d->removeCurrentAndDisabled(&intersectVector, current);
- }
- return d->closestIndex(initialRect, intersectVector);
- case MoveRight:
- while (intersectVector.isEmpty()) {
- rect.translate(rect.width(), 0);
- if (rect.left() >= contents.width())
- return current;
- if (rect.right() > contents.width())
- rect.setRight(contents.width());
- intersectVector = d->intersectingSet(rect);
- d->removeCurrentAndDisabled(&intersectVector, current);
- }
- return d->closestIndex(initialRect, intersectVector);
- case MovePageUp:
- // move current by (visibileRowCount - 1) items.
- // rect.translate(0, -rect.height()); will happen in the switch fallthrough for MoveUp.
- rect.moveTop(rect.top() - d->viewport->height() + 2 * rect.height());
- if (rect.top() < rect.height())
- rect.moveTop(rect.height());
- case MovePrevious:
- case MoveUp:
- while (intersectVector.isEmpty()) {
- rect.translate(0, -rect.height());
- if (rect.bottom() <= 0) {
-#ifdef QT_KEYPAD_NAVIGATION
- if (QApplication::keypadNavigationEnabled()) {
- int row = d->batchStartRow() - 1;
- while (row >= 0 && d->isHiddenOrDisabled(row))
- --row;
- if (row >= 0)
- return d->model->index(row, d->column, d->root);
- }
-#endif
- return current;
- }
- if (rect.top() < 0)
- rect.setTop(0);
- intersectVector = d->intersectingSet(rect);
- d->removeCurrentAndDisabled(&intersectVector, current);
- }
- return d->closestIndex(initialRect, intersectVector);
- case MovePageDown:
- // move current by (visibileRowCount - 1) items.
- // rect.translate(0, rect.height()); will happen in the switch fallthrough for MoveDown.
- rect.moveTop(rect.top() + d->viewport->height() - 2 * rect.height());
- if (rect.bottom() > contents.height() - rect.height())
- rect.moveBottom(contents.height() - rect.height());
- case MoveNext:
- case MoveDown:
- while (intersectVector.isEmpty()) {
- rect.translate(0, rect.height());
- if (rect.top() >= contents.height()) {
-#ifdef QT_KEYPAD_NAVIGATION
- if (QApplication::keypadNavigationEnabled()) {
- int rowCount = d->model->rowCount(d->root);
- int row = 0;
- while (row < rowCount && d->isHiddenOrDisabled(row))
- ++row;
- if (row < rowCount)
- return d->model->index(row, d->column, d->root);
- }
-#endif
- return current;
- }
- if (rect.bottom() > contents.height())
- rect.setBottom(contents.height());
- intersectVector = d->intersectingSet(rect);
- d->removeCurrentAndDisabled(&intersectVector, current);
- }
- return d->closestIndex(initialRect, intersectVector);
- case MoveHome:
- return d->model->index(0, d->column, d->root);
- case MoveEnd:
- return d->model->index(d->batchStartRow() - 1, d->column, d->root);}
-
- return current;
-}
-
-/*!
- Returns the rectangle of the item at position \a index in the
- model. The rectangle is in contents coordinates.
-
- \sa visualRect()
-*/
-QRect QListView::rectForIndex(const QModelIndex &index) const
-{
- return d_func()->rectForIndex(index);
-}
-
-/*!
- \since 4.1
-
- Sets the contents position of the item at \a index in the model to the given
- \a position.
- If the list view's movement mode is Static or its view mode is ListView,
- this function will have no effect.
-*/
-void QListView::setPositionForIndex(const QPoint &position, const QModelIndex &index)
-{
- Q_D(QListView);
- if (d->movement == Static
- || !d->isIndexValid(index)
- || index.parent() != d->root
- || index.column() != d->column)
- return;
-
- d->executePostedLayout();
- d->commonListView->setPositionForIndex(position, index);
-}
-
-/*!
- \reimp
-*/
-void QListView::setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags command)
-{
- Q_D(QListView);
- if (!d->selectionModel)
- return;
-
- // if we are wrapping, we can only selecte inside the contents rectangle
- int w = qMax(d->contentsSize().width(), d->viewport->width());
- int h = qMax(d->contentsSize().height(), d->viewport->height());
- if (d->wrap && !QRect(0, 0, w, h).intersects(rect))
- return;
-
- QItemSelection selection;
-
- if (rect.width() == 1 && rect.height() == 1) {
- const QVector<QModelIndex> intersectVector = d->intersectingSet(rect.translated(horizontalOffset(), verticalOffset()));
- QModelIndex tl;
- if (!intersectVector.isEmpty())
- tl = intersectVector.last(); // special case for mouse press; only select the top item
- if (tl.isValid() && d->isIndexEnabled(tl))
- selection.select(tl, tl);
- } else {
- if (state() == DragSelectingState) { // visual selection mode (rubberband selection)
- selection = d->selection(rect.translated(horizontalOffset(), verticalOffset()));
- } else { // logical selection mode (key and mouse click selection)
- QModelIndex tl, br;
- // get the first item
- const QRect topLeft(rect.left() + horizontalOffset(), rect.top() + verticalOffset(), 1, 1);
- QVector<QModelIndex> intersectVector = d->intersectingSet(topLeft);
- if (!intersectVector.isEmpty())
- tl = intersectVector.last();
- // get the last item
- const QRect bottomRight(rect.right() + horizontalOffset(), rect.bottom() + verticalOffset(), 1, 1);
- intersectVector = d->intersectingSet(bottomRight);
- if (!intersectVector.isEmpty())
- br = intersectVector.last();
-
- // get the ranges
- if (tl.isValid() && br.isValid()
- && d->isIndexEnabled(tl)
- && d->isIndexEnabled(br)) {
- QRect first = rectForIndex(tl);
- QRect last = rectForIndex(br);
- QRect middle;
- if (d->flow == LeftToRight) {
- QRect &top = first;
- QRect &bottom = last;
- // if bottom is above top, swap them
- if (top.center().y() > bottom.center().y()) {
- QRect tmp = top;
- top = bottom;
- bottom = tmp;
- }
- // if the rect are on differnet lines, expand
- if (top.top() != bottom.top()) {
- // top rectangle
- if (isRightToLeft())
- top.setLeft(0);
- else
- top.setRight(contentsSize().width());
- // bottom rectangle
- if (isRightToLeft())
- bottom.setRight(contentsSize().width());
- else
- bottom.setLeft(0);
- } else if (top.left() > bottom.right()) {
- if (isRightToLeft())
- bottom.setLeft(top.right());
- else
- bottom.setRight(top.left());
- } else {
- if (isRightToLeft())
- top.setLeft(bottom.right());
- else
- top.setRight(bottom.left());
- }
- // middle rectangle
- if (top.bottom() < bottom.top()) {
- if (gridSize().isValid() && !gridSize().isNull())
- middle.setTop(top.top() + gridSize().height());
- else
- middle.setTop(top.bottom() + 1);
- middle.setLeft(qMin(top.left(), bottom.left()));
- middle.setBottom(bottom.top() - 1);
- middle.setRight(qMax(top.right(), bottom.right()));
- }
- } else { // TopToBottom
- QRect &left = first;
- QRect &right = last;
- if (left.center().x() > right.center().x())
- qSwap(left, right);
-
- int ch = contentsSize().height();
- if (left.left() != right.left()) {
- // left rectangle
- if (isRightToLeft())
- left.setTop(0);
- else
- left.setBottom(ch);
-
- // top rectangle
- if (isRightToLeft())
- right.setBottom(ch);
- else
- right.setTop(0);
- // only set middle if the
- middle.setTop(0);
- middle.setBottom(ch);
- if (gridSize().isValid() && !gridSize().isNull())
- middle.setLeft(left.left() + gridSize().width());
- else
- middle.setLeft(left.right() + 1);
- middle.setRight(right.left() - 1);
- } else if (left.bottom() < right.top()) {
- left.setBottom(right.top() - 1);
- } else {
- right.setBottom(left.top() - 1);
- }
- }
-
- // do the selections
- QItemSelection topSelection = d->selection(first);
- QItemSelection middleSelection = d->selection(middle);
- QItemSelection bottomSelection = d->selection(last);
- // merge
- selection.merge(topSelection, QItemSelectionModel::Select);
- selection.merge(middleSelection, QItemSelectionModel::Select);
- selection.merge(bottomSelection, QItemSelectionModel::Select);
- }
- }
- }
-
- d->selectionModel->select(selection, command);
-}
-
-/*!
- \reimp
-
- Since 4.7, the returned region only contains rectangles intersecting
- (or included in) the viewport.
-*/
-QRegion QListView::visualRegionForSelection(const QItemSelection &selection) const
-{
- Q_D(const QListView);
- // ### NOTE: this is a potential bottleneck in non-static mode
- int c = d->column;
- QRegion selectionRegion;
- const QRect &viewportRect = d->viewport->rect();
- for (int i = 0; i < selection.count(); ++i) {
- if (!selection.at(i).isValid())
- continue;
- QModelIndex parent = selection.at(i).topLeft().parent();
- //we only display the children of the root in a listview
- //we're not interested in the other model indexes
- if (parent != d->root)
- continue;
- int t = selection.at(i).topLeft().row();
- int b = selection.at(i).bottomRight().row();
- if (d->viewMode == IconMode || d->isWrapping()) { // in non-static mode, we have to go through all selected items
- for (int r = t; r <= b; ++r) {
- const QRect &rect = visualRect(d->model->index(r, c, parent));
- if (viewportRect.intersects(rect))
- selectionRegion += rect;
- }
- } else { // in static mode, we can optimize a bit
- while (t <= b && d->isHidden(t)) ++t;
- while (b >= t && d->isHidden(b)) --b;
- const QModelIndex top = d->model->index(t, c, parent);
- const QModelIndex bottom = d->model->index(b, c, parent);
- QRect rect(visualRect(top).topLeft(),
- visualRect(bottom).bottomRight());
- if (viewportRect.intersects(rect))
- selectionRegion += rect;
- }
- }
-
- return selectionRegion;
-}
-
-/*!
- \reimp
-*/
-QModelIndexList QListView::selectedIndexes() const
-{
- Q_D(const QListView);
- if (!d->selectionModel)
- return QModelIndexList();
-
- QModelIndexList viewSelected = d->selectionModel->selectedIndexes();
- for (int i = 0; i < viewSelected.count(); ++i) {
- const QModelIndex &index = viewSelected.at(i);
- if (!isIndexHidden(index) && index.parent() == d->root && index.column() == d->column)
- ++i;
- else
- viewSelected.removeAt(i);
- }
- return viewSelected;
-}
-
-/*!
- \internal
-
- Layout the items according to the flow and wrapping properties.
-*/
-void QListView::doItemsLayout()
-{
- Q_D(QListView);
- // showing the scroll bars will trigger a resize event,
- // so we set the state to expanding to avoid
- // triggering another layout
- QAbstractItemView::State oldState = state();
- setState(ExpandingState);
- if (d->model->columnCount(d->root) > 0) { // no columns means no contents
- d->resetBatchStartRow();
- if (layoutMode() == SinglePass)
- d->doItemsLayout(d->model->rowCount(d->root)); // layout everything
- else if (!d->batchLayoutTimer.isActive()) {
- if (!d->doItemsLayout(d->batchSize)) // layout is done
- d->batchLayoutTimer.start(0, this); // do a new batch as fast as possible
- }
- }
- QAbstractItemView::doItemsLayout();
- setState(oldState); // restoring the oldState
-}
-
-/*!
- \reimp
-*/
-void QListView::updateGeometries()
-{
- Q_D(QListView);
- if (d->model->rowCount(d->root) <= 0 || d->model->columnCount(d->root) <= 0) {
- horizontalScrollBar()->setRange(0, 0);
- verticalScrollBar()->setRange(0, 0);
- } else {
- QModelIndex index = d->model->index(0, d->column, d->root);
- QStyleOptionViewItemV4 option = d->viewOptionsV4();
- QSize step = d->itemSize(option, index);
- d->commonListView->updateHorizontalScrollBar(step);
- d->commonListView->updateVerticalScrollBar(step);
- }
-
- QAbstractItemView::updateGeometries();
-
- // if the scroll bars are turned off, we resize the contents to the viewport
- if (d->movement == Static && !d->isWrapping()) {
- const QSize maxSize = maximumViewportSize();
- if (d->flow == TopToBottom) {
- if (horizontalScrollBarPolicy() == Qt::ScrollBarAlwaysOff) {
- d->setContentsSize(maxSize.width(), contentsSize().height());
- horizontalScrollBar()->setRange(0, 0); // we see all the contents anyway
- }
- } else { // LeftToRight
- if (verticalScrollBarPolicy() == Qt::ScrollBarAlwaysOff) {
- d->setContentsSize(contentsSize().width(), maxSize.height());
- verticalScrollBar()->setRange(0, 0); // we see all the contents anyway
- }
- }
- }
-
-}
-
-/*!
- \reimp
-*/
-bool QListView::isIndexHidden(const QModelIndex &index) const
-{
- Q_D(const QListView);
- return (d->isHidden(index.row())
- && (index.parent() == d->root)
- && index.column() == d->column);
-}
-
-/*!
- \property QListView::modelColumn
- \brief the column in the model that is visible
-
- By default, this property contains 0, indicating that the first
- column in the model will be shown.
-*/
-void QListView::setModelColumn(int column)
-{
- Q_D(QListView);
- if (column < 0 || column >= d->model->columnCount(d->root))
- return;
- d->column = column;
- d->doDelayedItemsLayout();
-}
-
-int QListView::modelColumn() const
-{
- Q_D(const QListView);
- return d->column;
-}
-
-/*!
- \property QListView::uniformItemSizes
- \brief whether all items in the listview have the same size
- \since 4.1
-
- This property should only be set to true if it is guaranteed that all items
- in the view have the same size. This enables the view to do some
- optimizations for performance purposes.
-
- By default, this property is false.
-*/
-void QListView::setUniformItemSizes(bool enable)
-{
- Q_D(QListView);
- d->uniformItemSizes = enable;
-}
-
-bool QListView::uniformItemSizes() const
-{
- Q_D(const QListView);
- return d->uniformItemSizes;
-}
-
-/*!
- \property QListView::wordWrap
- \brief the item text word-wrapping policy
- \since 4.2
-
- If this property is true then the item text is wrapped where
- necessary at word-breaks; otherwise it is not wrapped at all.
- This property is false by default.
-
- Please note that even if wrapping is enabled, the cell will not be
- expanded to make room for the text. It will print ellipsis for
- text that cannot be shown, according to the view's
- \l{QAbstractItemView::}{textElideMode}.
-*/
-void QListView::setWordWrap(bool on)
-{
- Q_D(QListView);
- if (d->wrapItemText == on)
- return;
- d->wrapItemText = on;
- d->doDelayedItemsLayout();
-}
-
-bool QListView::wordWrap() const
-{
- Q_D(const QListView);
- return d->wrapItemText;
-}
-
-/*!
- \property QListView::selectionRectVisible
- \brief if the selection rectangle should be visible
- \since 4.3
-
- If this property is true then the selection rectangle is visible;
- otherwise it will be hidden.
-
- \note The selection rectangle will only be visible if the selection mode
- is in a mode where more than one item can be selected; i.e., it will not
- draw a selection rectangle if the selection mode is
- QAbstractItemView::SingleSelection.
-
- By default, this property is false.
-*/
-void QListView::setSelectionRectVisible(bool show)
-{
- Q_D(QListView);
- d->modeProperties |= uint(QListViewPrivate::SelectionRectVisible);
- d->setSelectionRectVisible(show);
-}
-
-bool QListView::isSelectionRectVisible() const
-{
- Q_D(const QListView);
- return d->isSelectionRectVisible();
-}
-
-/*!
- \reimp
-*/
-bool QListView::event(QEvent *e)
-{
- return QAbstractItemView::event(e);
-}
-
-/*
- * private object implementation
- */
-
-QListViewPrivate::QListViewPrivate()
- : QAbstractItemViewPrivate(),
- commonListView(0),
- wrap(false),
- space(0),
- flow(QListView::TopToBottom),
- movement(QListView::Static),
- resizeMode(QListView::Fixed),
- layoutMode(QListView::SinglePass),
- viewMode(QListView::ListMode),
- modeProperties(0),
- column(0),
- uniformItemSizes(false),
- batchSize(100),
- showElasticBand(false)
-{
-}
-
-QListViewPrivate::~QListViewPrivate()
-{
- delete commonListView;
-}
-
-void QListViewPrivate::clear()
-{
- // initialization of data structs
- cachedItemSize = QSize();
- commonListView->clear();
-}
-
-void QListViewPrivate::prepareItemsLayout()
-{
- Q_Q(QListView);
- clear();
-
- //take the size as if there were scrollbar in order to prevent scrollbar to blink
- layoutBounds = QRect(QPoint(), q->maximumViewportSize());
-
- int frameAroundContents = 0;
- if (q->style()->styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents))
- frameAroundContents = q->style()->pixelMetric(QStyle::PM_DefaultFrameWidth) * 2;
-
- // maximumViewportSize() already takes scrollbar into account if policy is
- // Qt::ScrollBarAlwaysOn but scrollbar extent must be deduced if policy
- // is Qt::ScrollBarAsNeeded
- int verticalMargin = vbarpolicy==Qt::ScrollBarAsNeeded
- ? q->style()->pixelMetric(QStyle::PM_ScrollBarExtent, 0, vbar) + frameAroundContents
- : 0;
- int horizontalMargin = hbarpolicy==Qt::ScrollBarAsNeeded
- ? q->style()->pixelMetric(QStyle::PM_ScrollBarExtent, 0, hbar) + frameAroundContents
- : 0;
-
- layoutBounds.adjust(0, 0, -verticalMargin, -horizontalMargin);
-
- int rowCount = model->columnCount(root) <= 0 ? 0 : model->rowCount(root);
- commonListView->setRowCount(rowCount);
-}
-
-/*!
- \internal
-*/
-bool QListViewPrivate::doItemsLayout(int delta)
-{
- int max = model->rowCount(root) - 1;
- int first = batchStartRow();
- int last = qMin(first + delta - 1, max);
-
- if (first == 0) {
- layoutChildren(); // make sure the viewport has the right size
- prepareItemsLayout();
- }
-
- if (max < 0 || last < first) {
- return true; // nothing to do
- }
-
- QListViewLayoutInfo info;
- info.bounds = layoutBounds;
- info.grid = gridSize();
- info.spacing = (info.grid.isValid() ? 0 : spacing());
- info.first = first;
- info.last = last;
- info.wrap = isWrapping();
- info.flow = flow;
- info.max = max;
-
- return commonListView->doBatchedItemLayout(info, max);
-}
-
-QListViewItem QListViewPrivate::indexToListViewItem(const QModelIndex &index) const
-{
- if (!index.isValid() || isHidden(index.row()))
- return QListViewItem();
-
- return commonListView->indexToListViewItem(index);
-}
-
-QRect QListViewPrivate::mapToViewport(const QRect &rect, bool extend) const
-{
- Q_Q(const QListView);
- if (!rect.isValid())
- return rect;
-
- QRect result = extend ? commonListView->mapToViewport(rect) : rect;
- int dx = -q->horizontalOffset();
- int dy = -q->verticalOffset();
- return result.adjusted(dx, dy, dx, dy);
-}
-
-QModelIndex QListViewPrivate::closestIndex(const QRect &target,
- const QVector<QModelIndex> &candidates) const
-{
- int distance = 0;
- int shortest = INT_MAX;
- QModelIndex closest;
- QVector<QModelIndex>::const_iterator it = candidates.begin();
-
- for (; it != candidates.end(); ++it) {
- if (!(*it).isValid())
- continue;
-
- const QRect indexRect = indexToListViewItem(*it).rect();
-
- //if the center x (or y) position of an item is included in the rect of the other item,
- //we define the distance between them as the difference in x (or y) of their respective center.
- // Otherwise, we use the nahattan length between the 2 items
- if ((target.center().x() >= indexRect.x() && target.center().x() < indexRect.right())
- || (indexRect.center().x() >= target.x() && indexRect.center().x() < target.right())) {
- //one item's center is at the vertical of the other
- distance = qAbs(indexRect.center().y() - target.center().y());
- } else if ((target.center().y() >= indexRect.y() && target.center().y() < indexRect.bottom())
- || (indexRect.center().y() >= target.y() && indexRect.center().y() < target.bottom())) {
- //one item's center is at the vertical of the other
- distance = qAbs(indexRect.center().x() - target.center().x());
- } else {
- distance = (indexRect.center() - target.center()).manhattanLength();
- }
- if (distance < shortest) {
- shortest = distance;
- closest = *it;
- }
- }
- return closest;
-}
-
-QSize QListViewPrivate::itemSize(const QStyleOptionViewItem &option, const QModelIndex &index) const
-{
- if (!uniformItemSizes) {
- const QAbstractItemDelegate *delegate = delegateForIndex(index);
- return delegate ? delegate->sizeHint(option, index) : QSize();
- }
- if (!cachedItemSize.isValid()) { // the last item is probaly the largest, so we use its size
- int row = model->rowCount(root) - 1;
- QModelIndex sample = model->index(row, column, root);
- const QAbstractItemDelegate *delegate = delegateForIndex(sample);
- cachedItemSize = delegate ? delegate->sizeHint(option, sample) : QSize();
- }
- return cachedItemSize;
-}
-
-QItemSelection QListViewPrivate::selection(const QRect &rect) const
-{
- QItemSelection selection;
- QModelIndex tl, br;
- const QVector<QModelIndex> intersectVector = intersectingSet(rect);
- QVector<QModelIndex>::const_iterator it = intersectVector.begin();
- for (; it != intersectVector.end(); ++it) {
- if (!tl.isValid() && !br.isValid()) {
- tl = br = *it;
- } else if ((*it).row() == (tl.row() - 1)) {
- tl = *it; // expand current range
- } else if ((*it).row() == (br.row() + 1)) {
- br = (*it); // expand current range
- } else {
- selection.select(tl, br); // select current range
- tl = br = *it; // start new range
- }
- }
-
- if (tl.isValid() && br.isValid())
- selection.select(tl, br);
- else if (tl.isValid())
- selection.select(tl, tl);
- else if (br.isValid())
- selection.select(br, br);
-
- return selection;
-}
-
-#ifndef QT_NO_DRAGANDDROP
-QAbstractItemView::DropIndicatorPosition QListViewPrivate::position(const QPoint &pos, const QRect &rect, const QModelIndex &idx) const
-{
- if (viewMode == QListView::ListMode && flow == QListView::LeftToRight)
- return static_cast<QListModeViewBase *>(commonListView)->position(pos, rect, idx);
- else
- return QAbstractItemViewPrivate::position(pos, rect, idx);
-}
-
-bool QListViewPrivate::dropOn(QDropEvent *event, int *dropRow, int *dropCol, QModelIndex *dropIndex)
-{
- if (viewMode == QListView::ListMode && flow == QListView::LeftToRight)
- return static_cast<QListModeViewBase *>(commonListView)->dropOn(event, dropRow, dropCol, dropIndex);
- else
- return QAbstractItemViewPrivate::dropOn(event, dropRow, dropCol, dropIndex);
-}
-#endif
-
-/*
- * Common ListView Implementation
-*/
-
-void QCommonListViewBase::appendHiddenRow(int row)
-{
- dd->hiddenRows.insert(dd->model->index(row, 0, qq->rootIndex()));
-}
-
-void QCommonListViewBase::removeHiddenRow(int row)
-{
- dd->hiddenRows.remove(dd->model->index(row, 0, qq->rootIndex()));
-}
-
-void QCommonListViewBase::updateHorizontalScrollBar(const QSize &step)
-{
- horizontalScrollBar()->setSingleStep(step.width() + spacing());
- horizontalScrollBar()->setPageStep(viewport()->width());
- horizontalScrollBar()->setRange(0, contentsSize.width() - viewport()->width());
-}
-
-void QCommonListViewBase::updateVerticalScrollBar(const QSize &step)
-{
- verticalScrollBar()->setSingleStep(step.height() + spacing());
- verticalScrollBar()->setPageStep(viewport()->height());
- verticalScrollBar()->setRange(0, contentsSize.height() - viewport()->height());
-}
-
-void QCommonListViewBase::scrollContentsBy(int dx, int dy, bool /*scrollElasticBand*/)
-{
- dd->scrollContentsBy(isRightToLeft() ? -dx : dx, dy);
-}
-
-int QCommonListViewBase::verticalScrollToValue(int /*index*/, QListView::ScrollHint hint,
- bool above, bool below, const QRect &area, const QRect &rect) const
-{
- int verticalValue = verticalScrollBar()->value();
- QRect adjusted = rect.adjusted(-spacing(), -spacing(), spacing(), spacing());
- if (hint == QListView::PositionAtTop || above)
- verticalValue += adjusted.top();
- else if (hint == QListView::PositionAtBottom || below)
- verticalValue += qMin(adjusted.top(), adjusted.bottom() - area.height() + 1);
- else if (hint == QListView::PositionAtCenter)
- verticalValue += adjusted.top() - ((area.height() - adjusted.height()) / 2);
- return verticalValue;
-}
-
-int QCommonListViewBase::horizontalOffset() const
-{
- return (isRightToLeft() ? horizontalScrollBar()->maximum() - horizontalScrollBar()->value() : horizontalScrollBar()->value());
-}
-
-int QCommonListViewBase::horizontalScrollToValue(const int /*index*/, QListView::ScrollHint hint,
- bool leftOf, bool rightOf, const QRect &area, const QRect &rect) const
-{
- int horizontalValue = horizontalScrollBar()->value();
- if (isRightToLeft()) {
- if (hint == QListView::PositionAtCenter) {
- horizontalValue += ((area.width() - rect.width()) / 2) - rect.left();
- } else {
- if (leftOf)
- horizontalValue -= rect.left();
- else if (rightOf)
- horizontalValue += qMin(rect.left(), area.width() - rect.right());
- }
- } else {
- if (hint == QListView::PositionAtCenter) {
- horizontalValue += rect.left() - ((area.width()- rect.width()) / 2);
- } else {
- if (leftOf)
- horizontalValue += rect.left();
- else if (rightOf)
- horizontalValue += qMin(rect.left(), rect.right() - area.width());
- }
- }
- return horizontalValue;
-}
-
-/*
- * ListMode ListView Implementation
-*/
-
-#ifndef QT_NO_DRAGANDDROP
-void QListModeViewBase::paintDragDrop(QPainter *painter)
-{
- // FIXME: Until the we can provide a proper drop indicator
- // in IconMode, it makes no sense to show it
- dd->paintDropIndicator(painter);
-}
-
-QAbstractItemView::DropIndicatorPosition QListModeViewBase::position(const QPoint &pos, const QRect &rect, const QModelIndex &index) const
-{
- QAbstractItemView::DropIndicatorPosition r = QAbstractItemView::OnViewport;
- if (!dd->overwrite) {
- const int margin = 2;
- if (pos.x() - rect.left() < margin) {
- r = QAbstractItemView::AboveItem; // Visually, on the left
- } else if (rect.right() - pos.x() < margin) {
- r = QAbstractItemView::BelowItem; // Visually, on the right
- } else if (rect.contains(pos, true)) {
- r = QAbstractItemView::OnItem;
- }
- } else {
- QRect touchingRect = rect;
- touchingRect.adjust(-1, -1, 1, 1);
- if (touchingRect.contains(pos, false)) {
- r = QAbstractItemView::OnItem;
- }
- }
-
- if (r == QAbstractItemView::OnItem && (!(dd->model->flags(index) & Qt::ItemIsDropEnabled)))
- r = pos.x() < rect.center().x() ? QAbstractItemView::AboveItem : QAbstractItemView::BelowItem;
-
- return r;
-}
-
-void QListModeViewBase::dragMoveEvent(QDragMoveEvent *event)
-{
- if (qq->dragDropMode() == QAbstractItemView::InternalMove
- && (event->source() != qq || !(event->possibleActions() & Qt::MoveAction)))
- return;
-
- // ignore by default
- event->ignore();
-
- // can't use indexAt, doesn't account for spacing.
- QPoint p = event->pos();
- QRect rect(p.x() + horizontalOffset(), p.y() + verticalOffset(), 1, 1);
- rect.adjust(-dd->spacing(), -dd->spacing(), dd->spacing(), dd->spacing());
- const QVector<QModelIndex> intersectVector = dd->intersectingSet(rect);
- QModelIndex index = intersectVector.count() > 0
- ? intersectVector.last() : QModelIndex();
- dd->hover = index;
- if (!dd->droppingOnItself(event, index)
- && dd->canDecode(event)) {
-
- if (index.isValid() && dd->showDropIndicator) {
- QRect rect = qq->visualRect(index);
- dd->dropIndicatorPosition = position(event->pos(), rect, index);
- // if spacing, should try to draw between items, not just next to item.
- switch (dd->dropIndicatorPosition) {
- case QAbstractItemView::AboveItem:
- if (dd->isIndexDropEnabled(index.parent())) {
- dd->dropIndicatorRect = QRect(rect.left()-dd->spacing(), rect.top(), 0, rect.height());
- event->accept();
- } else {
- dd->dropIndicatorRect = QRect();
- }
- break;
- case QAbstractItemView::BelowItem:
- if (dd->isIndexDropEnabled(index.parent())) {
- dd->dropIndicatorRect = QRect(rect.right()+dd->spacing(), rect.top(), 0, rect.height());
- event->accept();
- } else {
- dd->dropIndicatorRect = QRect();
- }
- break;
- case QAbstractItemView::OnItem:
- if (dd->isIndexDropEnabled(index)) {
- dd->dropIndicatorRect = rect;
- event->accept();
- } else {
- dd->dropIndicatorRect = QRect();
- }
- break;
- case QAbstractItemView::OnViewport:
- dd->dropIndicatorRect = QRect();
- if (dd->isIndexDropEnabled(qq->rootIndex())) {
- event->accept(); // allow dropping in empty areas
- }
- break;
- }
- } else {
- dd->dropIndicatorRect = QRect();
- dd->dropIndicatorPosition = QAbstractItemView::OnViewport;
- if (dd->isIndexDropEnabled(qq->rootIndex())) {
- event->accept(); // allow dropping in empty areas
- }
- }
- dd->viewport->update();
- } // can decode
-
- if (dd->shouldAutoScroll(event->pos()))
- qq->startAutoScroll();
-}
-
-/*!
- If the event hasn't already been accepted, determines the index to drop on.
-
- if (row == -1 && col == -1)
- // append to this drop index
- else
- // place at row, col in drop index
-
- If it returns true a drop can be done, and dropRow, dropCol and dropIndex reflects the position of the drop.
- \internal
- */
-bool QListModeViewBase::dropOn(QDropEvent *event, int *dropRow, int *dropCol, QModelIndex *dropIndex)
-{
- if (event->isAccepted())
- return false;
-
- QModelIndex index;
- if (dd->viewport->rect().contains(event->pos())) {
- // can't use indexAt, doesn't account for spacing.
- QPoint p = event->pos();
- QRect rect(p.x() + horizontalOffset(), p.y() + verticalOffset(), 1, 1);
- rect.adjust(-dd->spacing(), -dd->spacing(), dd->spacing(), dd->spacing());
- const QVector<QModelIndex> intersectVector = dd->intersectingSet(rect);
- index = intersectVector.count() > 0
- ? intersectVector.last() : QModelIndex();
- if (!index.isValid())
- index = dd->root;
- }
-
- // If we are allowed to do the drop
- if (dd->model->supportedDropActions() & event->dropAction()) {
- int row = -1;
- int col = -1;
- if (index != dd->root) {
- dd->dropIndicatorPosition = position(event->pos(), qq->visualRect(index), index);
- switch (dd->dropIndicatorPosition) {
- case QAbstractItemView::AboveItem:
- row = index.row();
- col = index.column();
- index = index.parent();
- break;
- case QAbstractItemView::BelowItem:
- row = index.row() + 1;
- col = index.column();
- index = index.parent();
- break;
- case QAbstractItemView::OnItem:
- case QAbstractItemView::OnViewport:
- break;
- }
- } else {
- dd->dropIndicatorPosition = QAbstractItemView::OnViewport;
- }
- *dropIndex = index;
- *dropRow = row;
- *dropCol = col;
- if (!dd->droppingOnItself(event, index))
- return true;
- }
- return false;
-}
-
-#endif //QT_NO_DRAGANDDROP
-
-void QListModeViewBase::updateVerticalScrollBar(const QSize &step)
-{
- if (verticalScrollMode() == QAbstractItemView::ScrollPerItem
- && ((flow() == QListView::TopToBottom && !isWrapping())
- || (flow() == QListView::LeftToRight && isWrapping()))) {
- const int steps = (flow() == QListView::TopToBottom ? scrollValueMap : segmentPositions).count() - 1;
- if (steps > 0) {
- const int pageSteps = perItemScrollingPageSteps(viewport()->height(), contentsSize.height(), isWrapping());
- verticalScrollBar()->setSingleStep(1);
- verticalScrollBar()->setPageStep(pageSteps);
- verticalScrollBar()->setRange(0, steps - pageSteps);
- } else {
- verticalScrollBar()->setRange(0, 0);
- }
- // } else if (vertical && d->isWrapping() && d->movement == Static) {
- // ### wrapped scrolling in flow direction
- } else {
- QCommonListViewBase::updateVerticalScrollBar(step);
- }
-}
-
-void QListModeViewBase::updateHorizontalScrollBar(const QSize &step)
-{
- if (horizontalScrollMode() == QAbstractItemView::ScrollPerItem
- && ((flow() == QListView::TopToBottom && isWrapping())
- || (flow() == QListView::LeftToRight && !isWrapping()))) {
- int steps = (flow() == QListView::TopToBottom ? segmentPositions : scrollValueMap).count() - 1;
- if (steps > 0) {
- const int pageSteps = perItemScrollingPageSteps(viewport()->width(), contentsSize.width(), isWrapping());
- horizontalScrollBar()->setSingleStep(1);
- horizontalScrollBar()->setPageStep(pageSteps);
- horizontalScrollBar()->setRange(0, steps - pageSteps);
- } else {
- horizontalScrollBar()->setRange(0, 0);
- }
- } else {
- QCommonListViewBase::updateHorizontalScrollBar(step);
- }
-}
-
-int QListModeViewBase::verticalScrollToValue(int index, QListView::ScrollHint hint,
- bool above, bool below, const QRect &area, const QRect &rect) const
-{
- if (verticalScrollMode() == QAbstractItemView::ScrollPerItem) {
- int value;
- if (scrollValueMap.isEmpty())
- value = 0;
- else
- value = qBound(0, scrollValueMap.at(verticalScrollBar()->value()), flowPositions.count() - 1);
- if (above)
- hint = QListView::PositionAtTop;
- else if (below)
- hint = QListView::PositionAtBottom;
- if (hint == QListView::EnsureVisible)
- return value;
-
- return perItemScrollToValue(index, value, area.height(), hint, Qt::Vertical, isWrapping(), rect.height());
- }
-
- return QCommonListViewBase::verticalScrollToValue(index, hint, above, below, area, rect);
-}
-
-int QListModeViewBase::horizontalOffset() const
-{
- if (horizontalScrollMode() == QAbstractItemView::ScrollPerItem) {
- if (isWrapping()) {
- if (flow() == QListView::TopToBottom && !segmentPositions.isEmpty()) {
- const int max = segmentPositions.count() - 1;
- int currentValue = qBound(0, horizontalScrollBar()->value(), max);
- int position = segmentPositions.at(currentValue);
- int maximumValue = qBound(0, horizontalScrollBar()->maximum(), max);
- int maximum = segmentPositions.at(maximumValue);
- return (isRightToLeft() ? maximum - position : position);
- }
- } else if (flow() == QListView::LeftToRight && !flowPositions.isEmpty()) {
- int position = flowPositions.at(scrollValueMap.at(horizontalScrollBar()->value()));
- int maximum = flowPositions.at(scrollValueMap.at(horizontalScrollBar()->maximum()));
- return (isRightToLeft() ? maximum - position : position);
- }
- }
- return QCommonListViewBase::horizontalOffset();
-}
-
-int QListModeViewBase::verticalOffset() const
-{
- if (verticalScrollMode() == QAbstractItemView::ScrollPerItem) {
- if (isWrapping()) {
- if (flow() == QListView::LeftToRight && !segmentPositions.isEmpty()) {
- int value = verticalScrollBar()->value();
- if (value >= segmentPositions.count())
- return 0;
- return segmentPositions.at(value) - spacing();
- }
- } else if (flow() == QListView::TopToBottom && !flowPositions.isEmpty()) {
- int value = verticalScrollBar()->value();
- if (value > scrollValueMap.count())
- return 0;
- return flowPositions.at(scrollValueMap.at(value)) - spacing();
- }
- }
- return QCommonListViewBase::verticalOffset();
-}
-
-int QListModeViewBase::horizontalScrollToValue(int index, QListView::ScrollHint hint,
- bool leftOf, bool rightOf, const QRect &area, const QRect &rect) const
-{
- if (horizontalScrollMode() != QAbstractItemView::ScrollPerItem)
- return QCommonListViewBase::horizontalScrollToValue(index, hint, leftOf, rightOf, area, rect);
-
- int value;
- if (scrollValueMap.isEmpty())
- value = 0;
- else
- value = qBound(0, scrollValueMap.at(horizontalScrollBar()->value()), flowPositions.count() - 1);
- if (leftOf)
- hint = QListView::PositionAtTop;
- else if (rightOf)
- hint = QListView::PositionAtBottom;
- if (hint == QListView::EnsureVisible)
- return value;
-
- return perItemScrollToValue(index, value, area.width(), hint, Qt::Horizontal, isWrapping(), rect.width());
-}
-
-void QListModeViewBase::scrollContentsBy(int dx, int dy, bool scrollElasticBand)
-{
- // ### reorder this logic
- const int verticalValue = verticalScrollBar()->value();
- const int horizontalValue = horizontalScrollBar()->value();
- const bool vertical = (verticalScrollMode() == QAbstractItemView::ScrollPerItem);
- const bool horizontal = (horizontalScrollMode() == QAbstractItemView::ScrollPerItem);
-
- if (isWrapping()) {
- if (segmentPositions.isEmpty())
- return;
- const int max = segmentPositions.count() - 1;
- if (horizontal && flow() == QListView::TopToBottom && dx != 0) {
- int currentValue = qBound(0, horizontalValue, max);
- int previousValue = qBound(0, currentValue + dx, max);
- int currentCoordinate = segmentPositions.at(currentValue) - spacing();
- int previousCoordinate = segmentPositions.at(previousValue) - spacing();
- dx = previousCoordinate - currentCoordinate;
- } else if (vertical && flow() == QListView::LeftToRight && dy != 0) {
- int currentValue = qBound(0, verticalValue, max);
- int previousValue = qBound(0, currentValue + dy, max);
- int currentCoordinate = segmentPositions.at(currentValue) - spacing();
- int previousCoordinate = segmentPositions.at(previousValue) - spacing();
- dy = previousCoordinate - currentCoordinate;
- }
- } else {
- if (flowPositions.isEmpty())
- return;
- const int max = scrollValueMap.count() - 1;
- if (vertical && flow() == QListView::TopToBottom && dy != 0) {
- int currentValue = qBound(0, verticalValue, max);
- int previousValue = qBound(0, currentValue + dy, max);
- int currentCoordinate = flowPositions.at(scrollValueMap.at(currentValue));
- int previousCoordinate = flowPositions.at(scrollValueMap.at(previousValue));
- dy = previousCoordinate - currentCoordinate;
- } else if (horizontal && flow() == QListView::LeftToRight && dx != 0) {
- int currentValue = qBound(0, horizontalValue, max);
- int previousValue = qBound(0, currentValue + dx, max);
- int currentCoordinate = flowPositions.at(scrollValueMap.at(currentValue));
- int previousCoordinate = flowPositions.at(scrollValueMap.at(previousValue));
- dx = previousCoordinate - currentCoordinate;
- }
- }
- QCommonListViewBase::scrollContentsBy(dx, dy, scrollElasticBand);
-}
-
-bool QListModeViewBase::doBatchedItemLayout(const QListViewLayoutInfo &info, int max)
-{
- doStaticLayout(info);
- if (batchStartRow > max) { // stop items layout
- flowPositions.resize(flowPositions.count());
- segmentPositions.resize(segmentPositions.count());
- segmentStartRows.resize(segmentStartRows.count());
- return true; // done
- }
- return false; // not done
-}
-
-QListViewItem QListModeViewBase::indexToListViewItem(const QModelIndex &index) const
-{
- if (flowPositions.isEmpty()
- || segmentPositions.isEmpty()
- || index.row() >= flowPositions.count())
- return QListViewItem();
-
- const int segment = qBinarySearch<int>(segmentStartRows, index.row(),
- 0, segmentStartRows.count() - 1);
-
-
- QStyleOptionViewItemV4 options = viewOptions();
- options.rect.setSize(contentsSize);
- QSize size = (uniformItemSizes() && cachedItemSize().isValid())
- ? cachedItemSize() : itemSize(options, index);
-
- QPoint pos;
- if (flow() == QListView::LeftToRight) {
- pos.setX(flowPositions.at(index.row()));
- pos.setY(segmentPositions.at(segment));
- } else { // TopToBottom
- pos.setY(flowPositions.at(index.row()));
- pos.setX(segmentPositions.at(segment));
- if (isWrapping()) { // make the items as wide as the segment
- int right = (segment + 1 >= segmentPositions.count()
- ? contentsSize.width()
- : segmentPositions.at(segment + 1));
- size.setWidth(right - pos.x());
- } else { // make the items as wide as the viewport
- size.setWidth(qMax(size.width(), viewport()->width()));
- }
- }
-
- return QListViewItem(QRect(pos, size), index.row());
-}
-
-QPoint QListModeViewBase::initStaticLayout(const QListViewLayoutInfo &info)
-{
- int x, y;
- if (info.first == 0) {
- flowPositions.clear();
- segmentPositions.clear();
- segmentStartRows.clear();
- segmentExtents.clear();
- scrollValueMap.clear();
- x = info.bounds.left() + info.spacing;
- y = info.bounds.top() + info.spacing;
- segmentPositions.append(info.flow == QListView::LeftToRight ? y : x);
- segmentStartRows.append(0);
- } else if (info.wrap) {
- if (info.flow == QListView::LeftToRight) {
- x = batchSavedPosition;
- y = segmentPositions.last();
- } else { // flow == QListView::TopToBottom
- x = segmentPositions.last();
- y = batchSavedPosition;
- }
- } else { // not first and not wrap
- if (info.flow == QListView::LeftToRight) {
- x = batchSavedPosition;
- y = info.bounds.top() + info.spacing;
- } else { // flow == QListView::TopToBottom
- x = info.bounds.left() + info.spacing;
- y = batchSavedPosition;
- }
- }
- return QPoint(x, y);
-}
-
-/*!
- \internal
-*/
-void QListModeViewBase::doStaticLayout(const QListViewLayoutInfo &info)
-{
- const bool useItemSize = !info.grid.isValid();
- const QPoint topLeft = initStaticLayout(info);
- QStyleOptionViewItemV4 option = viewOptions();
- option.rect = info.bounds;
- option.rect.adjust(info.spacing, info.spacing, -info.spacing, -info.spacing);
-
- // The static layout data structures are as follows:
- // One vector contains the coordinate in the direction of layout flow.
- // Another vector contains the coordinates of the segments.
- // A third vector contains the index (model row) of the first item
- // of each segment.
-
- int segStartPosition;
- int segEndPosition;
- int deltaFlowPosition;
- int deltaSegPosition;
- int deltaSegHint;
- int flowPosition;
- int segPosition;
-
- if (info.flow == QListView::LeftToRight) {
- segStartPosition = info.bounds.left();
- segEndPosition = info.bounds.width();
- flowPosition = topLeft.x();
- segPosition = topLeft.y();
- deltaFlowPosition = info.grid.width(); // dx
- deltaSegPosition = useItemSize ? batchSavedDeltaSeg : info.grid.height(); // dy
- deltaSegHint = info.grid.height();
- } else { // flow == QListView::TopToBottom
- segStartPosition = info.bounds.top();
- segEndPosition = info.bounds.height();
- flowPosition = topLeft.y();
- segPosition = topLeft.x();
- deltaFlowPosition = info.grid.height(); // dy
- deltaSegPosition = useItemSize ? batchSavedDeltaSeg : info.grid.width(); // dx
- deltaSegHint = info.grid.width();
- }
-
- for (int row = info.first; row <= info.last; ++row) {
- if (isHidden(row)) { // ###
- flowPositions.append(flowPosition);
- } else {
- // if we are not using a grid, we need to find the deltas
- if (useItemSize) {
- QSize hint = itemSize(option, modelIndex(row));
- if (info.flow == QListView::LeftToRight) {
- deltaFlowPosition = hint.width() + info.spacing;
- deltaSegHint = hint.height() + info.spacing;
- } else { // TopToBottom
- deltaFlowPosition = hint.height() + info.spacing;
- deltaSegHint = hint.width() + info.spacing;
- }
- }
- // create new segment
- if (info.wrap && (flowPosition + deltaFlowPosition >= segEndPosition)) {
- segmentExtents.append(flowPosition);
- flowPosition = info.spacing + segStartPosition;
- segPosition += deltaSegPosition;
- if (info.wrap)
- segPosition += info.spacing;
- segmentPositions.append(segPosition);
- segmentStartRows.append(row);
- deltaSegPosition = 0;
- }
- // save the flow position of this item
- scrollValueMap.append(flowPositions.count());
- flowPositions.append(flowPosition);
- // prepare for the next item
- deltaSegPosition = qMax(deltaSegHint, deltaSegPosition);
- flowPosition += info.spacing + deltaFlowPosition;
- }
- }
- // used when laying out next batch
- batchSavedPosition = flowPosition;
- batchSavedDeltaSeg = deltaSegPosition;
- batchStartRow = info.last + 1;
- if (info.last == info.max)
- flowPosition -= info.spacing; // remove extra spacing
- // set the contents size
- QRect rect = info.bounds;
- if (info.flow == QListView::LeftToRight) {
- rect.setRight(segmentPositions.count() == 1 ? flowPosition : info.bounds.right());
- rect.setBottom(segPosition + deltaSegPosition);
- } else { // TopToBottom
- rect.setRight(segPosition + deltaSegPosition);
- rect.setBottom(segmentPositions.count() == 1 ? flowPosition : info.bounds.bottom());
- }
- contentsSize = QSize(rect.right(), rect.bottom());
- // if it is the last batch, save the end of the segments
- if (info.last == info.max) {
- segmentExtents.append(flowPosition);
- scrollValueMap.append(flowPositions.count());
- flowPositions.append(flowPosition);
- segmentPositions.append(info.wrap ? segPosition + deltaSegPosition : INT_MAX);
- }
- // if the new items are visble, update the viewport
- QRect changedRect(topLeft, rect.bottomRight());
- if (clipRect().intersects(changedRect))
- viewport()->update();
-}
-
-/*!
- \internal
- Finds the set of items intersecting with \a area.
- In this function, itemsize is counted from topleft to the start of the next item.
-*/
-QVector<QModelIndex> QListModeViewBase::intersectingSet(const QRect &area) const
-{
- QVector<QModelIndex> ret;
- int segStartPosition;
- int segEndPosition;
- int flowStartPosition;
- int flowEndPosition;
- if (flow() == QListView::LeftToRight) {
- segStartPosition = area.top();
- segEndPosition = area.bottom();
- flowStartPosition = area.left();
- flowEndPosition = area.right();
- } else {
- segStartPosition = area.left();
- segEndPosition = area.right();
- flowStartPosition = area.top();
- flowEndPosition = area.bottom();
- }
- if (segmentPositions.count() < 2 || flowPositions.isEmpty())
- return ret;
- // the last segment position is actually the edge of the last segment
- const int segLast = segmentPositions.count() - 2;
- int seg = qBinarySearch<int>(segmentPositions, segStartPosition, 0, segLast + 1);
- for (; seg <= segLast && segmentPositions.at(seg) <= segEndPosition; ++seg) {
- int first = segmentStartRows.at(seg);
- int last = (seg < segLast ? segmentStartRows.at(seg + 1) : batchStartRow) - 1;
- if (segmentExtents.at(seg) < flowStartPosition)
- continue;
- int row = qBinarySearch<int>(flowPositions, flowStartPosition, first, last);
- for (; row <= last && flowPositions.at(row) <= flowEndPosition; ++row) {
- if (isHidden(row))
- continue;
- QModelIndex index = modelIndex(row);
- if (index.isValid())
- ret += index;
-#if 0 // for debugging
- else
- qWarning("intersectingSet: row %d was invalid", row);
-#endif
- }
- }
- return ret;
-}
-
-void QListModeViewBase::dataChanged(const QModelIndex &, const QModelIndex &)
-{
- dd->doDelayedItemsLayout();
-}
-
-
-QRect QListModeViewBase::mapToViewport(const QRect &rect) const
-{
- if (isWrapping())
- return rect;
- // If the listview is in "listbox-mode", the items are as wide as the view.
- // But we don't shrink the items.
- QRect result = rect;
- if (flow() == QListView::TopToBottom) {
- result.setLeft(spacing());
- result.setWidth(qMax(rect.width(), qMax(contentsSize.width(), viewport()->width()) - 2 * spacing()));
- } else { // LeftToRight
- result.setTop(spacing());
- result.setHeight(qMax(rect.height(), qMax(contentsSize.height(), viewport()->height()) - 2 * spacing()));
- }
- return result;
-}
-
-int QListModeViewBase::perItemScrollingPageSteps(int length, int bounds, bool wrap) const
-{
- QVector<int> positions;
- if (wrap)
- positions = segmentPositions;
- else if (!flowPositions.isEmpty()) {
- positions.reserve(scrollValueMap.size());
- foreach (int itemShown, scrollValueMap)
- positions.append(flowPositions.at(itemShown));
- }
- if (positions.isEmpty() || bounds <= length)
- return positions.count();
- if (uniformItemSizes()) {
- for (int i = 1; i < positions.count(); ++i)
- if (positions.at(i) > 0)
- return length / positions.at(i);
- return 0; // all items had height 0
- }
- int pageSteps = 0;
- int steps = positions.count() - 1;
- int max = qMax(length, bounds);
- int min = qMin(length, bounds);
- int pos = min - (max - positions.last());
-
- while (pos >= 0 && steps > 0) {
- pos -= (positions.at(steps) - positions.at(steps - 1));
- if (pos >= 0) //this item should be visible
- ++pageSteps;
- --steps;
- }
-
- // at this point we know that positions has at least one entry
- return qMax(pageSteps, 1);
-}
-
-int QListModeViewBase::perItemScrollToValue(int index, int scrollValue, int viewportSize,
- QAbstractItemView::ScrollHint hint,
- Qt::Orientation orientation, bool wrap, int itemExtent) const
-{
- if (index < 0)
- return scrollValue;
- if (!wrap) {
- int topIndex = index;
- const int bottomIndex = topIndex;
- const int bottomCoordinate = flowPositions.at(index);
-
- while (topIndex > 0 &&
- (bottomCoordinate - flowPositions.at(topIndex-1) + itemExtent) <= (viewportSize)) {
- topIndex--;
- }
-
- const int itemCount = bottomIndex - topIndex + 1;
- switch (hint) {
- case QAbstractItemView::PositionAtTop:
- return index;
- case QAbstractItemView::PositionAtBottom:
- return index - itemCount + 1;
- case QAbstractItemView::PositionAtCenter:
- return index - (itemCount / 2);
- default:
- break;
- }
- } else { // wrapping
- Qt::Orientation flowOrientation = (flow() == QListView::LeftToRight
- ? Qt::Horizontal : Qt::Vertical);
- if (flowOrientation == orientation) { // scrolling in the "flow" direction
- // ### wrapped scrolling in the flow direction
- return flowPositions.at(index); // ### always pixel based for now
- } else if (!segmentStartRows.isEmpty()) { // we are scrolling in the "segment" direction
- int segment = qBinarySearch<int>(segmentStartRows, index, 0, segmentStartRows.count() - 1);
- int leftSegment = segment;
- const int rightSegment = leftSegment;
- const int bottomCoordinate = segmentPositions.at(segment);
-
- while (leftSegment > scrollValue &&
- (bottomCoordinate - segmentPositions.at(leftSegment-1) + itemExtent) <= (viewportSize)) {
- leftSegment--;
- }
-
- const int segmentCount = rightSegment - leftSegment + 1;
- switch (hint) {
- case QAbstractItemView::PositionAtTop:
- return segment;
- case QAbstractItemView::PositionAtBottom:
- return segment - segmentCount + 1;
- case QAbstractItemView::PositionAtCenter:
- return segment - (segmentCount / 2);
- default:
- break;
- }
- }
- }
- return scrollValue;
-}
-
-void QListModeViewBase::clear()
-{
- flowPositions.clear();
- segmentPositions.clear();
- segmentStartRows.clear();
- segmentExtents.clear();
- batchSavedPosition = 0;
- batchStartRow = 0;
- batchSavedDeltaSeg = 0;
-}
-
-/*
- * IconMode ListView Implementation
-*/
-
-void QIconModeViewBase::setPositionForIndex(const QPoint &position, const QModelIndex &index)
-{
- if (index.row() >= items.count())
- return;
- const QSize oldContents = contentsSize;
- qq->update(index); // update old position
- moveItem(index.row(), position);
- qq->update(index); // update new position
-
- if (contentsSize != oldContents)
- dd->viewUpdateGeometries(); // update the scroll bars
-}
-
-void QIconModeViewBase::appendHiddenRow(int row)
-{
- if (row >= 0 && row < items.count()) //remove item
- tree.removeLeaf(items.at(row).rect(), row);
- QCommonListViewBase::appendHiddenRow(row);
-}
-
-void QIconModeViewBase::removeHiddenRow(int row)
-{
- QCommonListViewBase::removeHiddenRow(row);
- if (row >= 0 && row < items.count()) //insert item
- tree.insertLeaf(items.at(row).rect(), row);
-}
-
-#ifndef QT_NO_DRAGANDDROP
-void QIconModeViewBase::paintDragDrop(QPainter *painter)
-{
- if (!draggedItems.isEmpty() && viewport()->rect().contains(draggedItemsPos)) {
- //we need to draw the items that arre dragged
- painter->translate(draggedItemsDelta());
- QStyleOptionViewItemV4 option = viewOptions();
- option.state &= ~QStyle::State_MouseOver;
- QVector<QModelIndex>::const_iterator it = draggedItems.begin();
- QListViewItem item = indexToListViewItem(*it);
- for (; it != draggedItems.end(); ++it) {
- item = indexToListViewItem(*it);
- option.rect = viewItemRect(item);
- delegate(*it)->paint(painter, option, *it);
- }
- }
-}
-
-bool QIconModeViewBase::filterStartDrag(Qt::DropActions supportedActions)
-{
- // This function does the same thing as in QAbstractItemView::startDrag(),
- // plus adding viewitems to the draggedItems list.
- // We need these items to draw the drag items
- QModelIndexList indexes = dd->selectionModel->selectedIndexes();
- if (indexes.count() > 0 ) {
- if (viewport()->acceptDrops()) {
- QModelIndexList::ConstIterator it = indexes.constBegin();
- for (; it != indexes.constEnd(); ++it)
- if (dd->model->flags(*it) & Qt::ItemIsDragEnabled
- && (*it).column() == dd->column)
- draggedItems.push_back(*it);
- }
- QDrag *drag = new QDrag(qq);
- drag->setMimeData(dd->model->mimeData(indexes));
- Qt::DropAction action = drag->exec(supportedActions, Qt::CopyAction);
- draggedItems.clear();
- if (action == Qt::MoveAction)
- dd->clearOrRemove();
- }
- return true;
-}
-
-bool QIconModeViewBase::filterDropEvent(QDropEvent *e)
-{
- if (e->source() != qq)
- return false;
-
- const QSize contents = contentsSize;
- QPoint offset(horizontalOffset(), verticalOffset());
- QPoint end = e->pos() + offset;
- if (qq->acceptDrops()) {
- const Qt::ItemFlags dropableFlags = Qt::ItemIsDropEnabled|Qt::ItemIsEnabled;
- const QVector<QModelIndex> &dropIndices = intersectingSet(QRect(end, QSize(1, 1)));
- foreach (const QModelIndex &index, dropIndices)
- if ((index.flags() & dropableFlags) == dropableFlags)
- return false;
- }
- QPoint start = dd->pressedPosition;
- QPoint delta = (dd->movement == QListView::Snap ? snapToGrid(end) - snapToGrid(start) : end - start);
- QList<QModelIndex> indexes = dd->selectionModel->selectedIndexes();
- for (int i = 0; i < indexes.count(); ++i) {
- QModelIndex index = indexes.at(i);
- QRect rect = dd->rectForIndex(index);
- viewport()->update(dd->mapToViewport(rect, false));
- QPoint dest = rect.topLeft() + delta;
- if (qq->isRightToLeft())
- dest.setX(dd->flipX(dest.x()) - rect.width());
- moveItem(index.row(), dest);
- qq->update(index);
- }
- dd->stopAutoScroll();
- draggedItems.clear();
- dd->emitIndexesMoved(indexes);
- e->accept(); // we have handled the event
- // if the size has not grown, we need to check if it has shrinked
- if (contentsSize != contents) {
- if ((contentsSize.width() <= contents.width()
- || contentsSize.height() <= contents.height())) {
- updateContentsSize();
- }
- dd->viewUpdateGeometries();
- }
- return true;
-}
-
-bool QIconModeViewBase::filterDragLeaveEvent(QDragLeaveEvent *e)
-{
- viewport()->update(draggedItemsRect()); // erase the area
- draggedItemsPos = QPoint(-1, -1); // don't draw the dragged items
- return QCommonListViewBase::filterDragLeaveEvent(e);
-}
-
-bool QIconModeViewBase::filterDragMoveEvent(QDragMoveEvent *e)
-{
- if (e->source() != qq || !dd->canDecode(e))
- return false;
-
- // ignore by default
- e->ignore();
- // get old dragged items rect
- QRect itemsRect = this->itemsRect(draggedItems);
- viewport()->update(itemsRect.translated(draggedItemsDelta()));
- // update position
- draggedItemsPos = e->pos();
- // get new items rect
- viewport()->update(itemsRect.translated(draggedItemsDelta()));
- // set the item under the cursor to current
- QModelIndex index;
- if (movement() == QListView::Snap) {
- QRect rect(snapToGrid(e->pos() + offset()), gridSize());
- const QVector<QModelIndex> intersectVector = intersectingSet(rect);
- index = intersectVector.count() > 0 ? intersectVector.last() : QModelIndex();
- } else {
- index = qq->indexAt(e->pos());
- }
- // check if we allow drops here
- if (draggedItems.contains(index))
- e->accept(); // allow changing item position
- else if (dd->model->flags(index) & Qt::ItemIsDropEnabled)
- e->accept(); // allow dropping on dropenabled items
- else if (!index.isValid())
- e->accept(); // allow dropping in empty areas
-
- // the event was treated. do autoscrolling
- if (dd->shouldAutoScroll(e->pos()))
- dd->startAutoScroll();
- return true;
-}
-#endif // QT_NO_DRAGANDDROP
-
-void QIconModeViewBase::setRowCount(int rowCount)
-{
- tree.create(qMax(rowCount - hiddenCount(), 0));
-}
-
-void QIconModeViewBase::scrollContentsBy(int dx, int dy, bool scrollElasticBand)
-{
- if (scrollElasticBand)
- dd->scrollElasticBandBy(isRightToLeft() ? -dx : dx, dy);
-
- QCommonListViewBase::scrollContentsBy(dx, dy, scrollElasticBand);
- if (!draggedItems.isEmpty())
- viewport()->update(draggedItemsRect().translated(dx, dy));
-}
-
-void QIconModeViewBase::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
-{
- if (column() >= topLeft.column() && column() <= bottomRight.column()) {
- QStyleOptionViewItemV4 option = viewOptions();
- int bottom = qMin(items.count(), bottomRight.row() + 1);
- for (int row = topLeft.row(); row < bottom; ++row)
- items[row].resize(itemSize(option, modelIndex(row)));
- }
-}
-
-bool QIconModeViewBase::doBatchedItemLayout(const QListViewLayoutInfo &info, int max)
-{
- if (info.last >= items.count()) {
- //first we create the items
- QStyleOptionViewItemV4 option = viewOptions();
- for (int row = items.count(); row <= info.last; ++row) {
- QSize size = itemSize(option, modelIndex(row));
- QListViewItem item(QRect(0, 0, size.width(), size.height()), row); // default pos
- items.append(item);
- }
- doDynamicLayout(info);
- }
- return (batchStartRow > max); // done
-}
-
-QListViewItem QIconModeViewBase::indexToListViewItem(const QModelIndex &index) const
-{
- if (index.isValid() && index.row() < items.count())
- return items.at(index.row());
- return QListViewItem();
-}
-
-void QIconModeViewBase::initBspTree(const QSize &contents)
-{
- // remove all items from the tree
- int leafCount = tree.leafCount();
- for (int l = 0; l < leafCount; ++l)
- tree.leaf(l).clear();
- // we have to get the bounding rect of the items before we can initialize the tree
- QBspTree::Node::Type type = QBspTree::Node::Both; // 2D
- // simple heuristics to get better bsp
- if (contents.height() / contents.width() >= 3)
- type = QBspTree::Node::HorizontalPlane;
- else if (contents.width() / contents.height() >= 3)
- type = QBspTree::Node::VerticalPlane;
- // build tree for the bounding rect (not just the contents rect)
- tree.init(QRect(0, 0, contents.width(), contents.height()), type);
-}
-
-QPoint QIconModeViewBase::initDynamicLayout(const QListViewLayoutInfo &info)
-{
- int x, y;
- if (info.first == 0) {
- x = info.bounds.x() + info.spacing;
- y = info.bounds.y() + info.spacing;
- items.reserve(rowCount() - hiddenCount());
- } else {
- int idx = info.first - 1;
- while (idx > 0 && !items.at(idx).isValid())
- --idx;
- const QListViewItem &item = items.at(idx);
- x = item.x;
- y = item.y;
- if (info.flow == QListView::LeftToRight)
- x += (info.grid.isValid() ? info.grid.width() : item.w) + info.spacing;
- else
- y += (info.grid.isValid() ? info.grid.height() : item.h) + info.spacing;
- }
- return QPoint(x, y);
-}
-
-/*!
- \internal
-*/
-void QIconModeViewBase::doDynamicLayout(const QListViewLayoutInfo &info)
-{
- const bool useItemSize = !info.grid.isValid();
- const QPoint topLeft = initDynamicLayout(info);
-
- int segStartPosition;
- int segEndPosition;
- int deltaFlowPosition;
- int deltaSegPosition;
- int deltaSegHint;
- int flowPosition;
- int segPosition;
-
- if (info.flow == QListView::LeftToRight) {
- segStartPosition = info.bounds.left() + info.spacing;
- segEndPosition = info.bounds.right();
- deltaFlowPosition = info.grid.width(); // dx
- deltaSegPosition = (useItemSize ? batchSavedDeltaSeg : info.grid.height()); // dy
- deltaSegHint = info.grid.height();
- flowPosition = topLeft.x();
- segPosition = topLeft.y();
- } else { // flow == QListView::TopToBottom
- segStartPosition = info.bounds.top() + info.spacing;
- segEndPosition = info.bounds.bottom();
- deltaFlowPosition = info.grid.height(); // dy
- deltaSegPosition = (useItemSize ? batchSavedDeltaSeg : info.grid.width()); // dx
- deltaSegHint = info.grid.width();
- flowPosition = topLeft.y();
- segPosition = topLeft.x();
- }
-
- if (moved.count() != items.count())
- moved.resize(items.count());
-
- QRect rect(QPoint(), topLeft);
- QListViewItem *item = 0;
- for (int row = info.first; row <= info.last; ++row) {
- item = &items[row];
- if (isHidden(row)) {
- item->invalidate();
- } else {
- // if we are not using a grid, we need to find the deltas
- if (useItemSize) {
- if (info.flow == QListView::LeftToRight)
- deltaFlowPosition = item->w + info.spacing;
- else
- deltaFlowPosition = item->h + info.spacing;
- } else {
- item->w = qMin<int>(info.grid.width(), item->w);
- item->h = qMin<int>(info.grid.height(), item->h);
- }
-
- // create new segment
- if (info.wrap
- && flowPosition + deltaFlowPosition > segEndPosition
- && flowPosition > segStartPosition) {
- flowPosition = segStartPosition;
- segPosition += deltaSegPosition;
- if (useItemSize)
- deltaSegPosition = 0;
- }
- // We must delay calculation of the seg adjustment, as this item
- // may have caused a wrap to occur
- if (useItemSize) {
- if (info.flow == QListView::LeftToRight)
- deltaSegHint = item->h + info.spacing;
- else
- deltaSegHint = item->w + info.spacing;
- deltaSegPosition = qMax(deltaSegPosition, deltaSegHint);
- }
-
- // set the position of the item
- // ### idealy we should have some sort of alignment hint for the item
- // ### (normally that would be a point between the icon and the text)
- if (!moved.testBit(row)) {
- if (info.flow == QListView::LeftToRight) {
- if (useItemSize) {
- item->x = flowPosition;
- item->y = segPosition;
- } else { // use grid
- item->x = flowPosition + ((deltaFlowPosition - item->w) / 2);
- item->y = segPosition;
- }
- } else { // TopToBottom
- if (useItemSize) {
- item->y = flowPosition;
- item->x = segPosition;
- } else { // use grid
- item->y = flowPosition + ((deltaFlowPosition - item->h) / 2);
- item->x = segPosition;
- }
- }
- }
-
- // let the contents contain the new item
- if (useItemSize)
- rect |= item->rect();
- else if (info.flow == QListView::LeftToRight)
- rect |= QRect(flowPosition, segPosition, deltaFlowPosition, deltaSegPosition);
- else // flow == TopToBottom
- rect |= QRect(segPosition, flowPosition, deltaSegPosition, deltaFlowPosition);
-
- // prepare for next item
- flowPosition += deltaFlowPosition; // current position + item width + gap
- }
- }
- batchSavedDeltaSeg = deltaSegPosition;
- batchStartRow = info.last + 1;
- bool done = (info.last >= rowCount() - 1);
- // resize the content area
- if (done || !info.bounds.contains(item->rect())) {
- contentsSize = rect.size();
- if (info.flow == QListView::LeftToRight)
- contentsSize.rheight() += info.spacing;
- else
- contentsSize.rwidth() += info.spacing;
- }
- if (rect.size().isEmpty())
- return;
- // resize tree
- int insertFrom = info.first;
- if (done || info.first == 0) {
- initBspTree(rect.size());
- insertFrom = 0;
- }
- // insert items in tree
- for (int row = insertFrom; row <= info.last; ++row)
- tree.insertLeaf(items.at(row).rect(), row);
- // if the new items are visble, update the viewport
- QRect changedRect(topLeft, rect.bottomRight());
- if (clipRect().intersects(changedRect))
- viewport()->update();
-}
-
-QVector<QModelIndex> QIconModeViewBase::intersectingSet(const QRect &area) const
-{
- QIconModeViewBase *that = const_cast<QIconModeViewBase*>(this);
- QBspTree::Data data(static_cast<void*>(that));
- QVector<QModelIndex> res;
- that->interSectingVector = &res;
- that->tree.climbTree(area, &QIconModeViewBase::addLeaf, data);
- that->interSectingVector = 0;
- return res;
-}
-
-QRect QIconModeViewBase::itemsRect(const QVector<QModelIndex> &indexes) const
-{
- QVector<QModelIndex>::const_iterator it = indexes.begin();
- QListViewItem item = indexToListViewItem(*it);
- QRect rect(item.x, item.y, item.w, item.h);
- for (; it != indexes.end(); ++it) {
- item = indexToListViewItem(*it);
- rect |= viewItemRect(item);
- }
- return rect;
-}
-
-int QIconModeViewBase::itemIndex(const QListViewItem &item) const
-{
- if (!item.isValid())
- return -1;
- int i = item.indexHint;
- if (i < items.count()) {
- if (items.at(i) == item)
- return i;
- } else {
- i = items.count() - 1;
- }
-
- int j = i;
- int c = items.count();
- bool a = true;
- bool b = true;
-
- while (a || b) {
- if (a) {
- if (items.at(i) == item) {
- items.at(i).indexHint = i;
- return i;
- }
- a = ++i < c;
- }
- if (b) {
- if (items.at(j) == item) {
- items.at(j).indexHint = j;
- return j;
- }
- b = --j > -1;
- }
- }
- return -1;
-}
-
-void QIconModeViewBase::addLeaf(QVector<int> &leaf, const QRect &area,
- uint visited, QBspTree::Data data)
-{
- QListViewItem *vi;
- QIconModeViewBase *_this = static_cast<QIconModeViewBase *>(data.ptr);
- for (int i = 0; i < leaf.count(); ++i) {
- int idx = leaf.at(i);
- if (idx < 0 || idx >= _this->items.count())
- continue;
- vi = &_this->items[idx];
- Q_ASSERT(vi);
- if (vi->isValid() && vi->rect().intersects(area) && vi->visited != visited) {
- QModelIndex index = _this->dd->listViewItemToIndex(*vi);
- Q_ASSERT(index.isValid());
- _this->interSectingVector->append(index);
- vi->visited = visited;
- }
- }
-}
-
-void QIconModeViewBase::moveItem(int index, const QPoint &dest)
-{
- // does not impact on the bintree itself or the contents rect
- QListViewItem *item = &items[index];
- QRect rect = item->rect();
-
- // move the item without removing it from the tree
- tree.removeLeaf(rect, index);
- item->move(dest);
- tree.insertLeaf(QRect(dest, rect.size()), index);
-
- // resize the contents area
- contentsSize = (QRect(QPoint(0, 0), contentsSize)|QRect(dest, rect.size())).size();
-
- // mark the item as moved
- if (moved.count() != items.count())
- moved.resize(items.count());
- moved.setBit(index, true);
-}
-
-QPoint QIconModeViewBase::snapToGrid(const QPoint &pos) const
-{
- int x = pos.x() - (pos.x() % gridSize().width());
- int y = pos.y() - (pos.y() % gridSize().height());
- return QPoint(x, y);
-}
-
-QPoint QIconModeViewBase::draggedItemsDelta() const
-{
- if (movement() == QListView::Snap) {
- QPoint snapdelta = QPoint((offset().x() % gridSize().width()),
- (offset().y() % gridSize().height()));
- return snapToGrid(draggedItemsPos + snapdelta) - snapToGrid(pressedPosition()) - snapdelta;
- }
- return draggedItemsPos - pressedPosition();
-}
-
-QRect QIconModeViewBase::draggedItemsRect() const
-{
- QRect rect = itemsRect(draggedItems);
- rect.translate(draggedItemsDelta());
- return rect;
-}
-
-void QListViewPrivate::scrollElasticBandBy(int dx, int dy)
-{
- if (dx > 0) // right
- elasticBand.moveRight(elasticBand.right() + dx);
- else if (dx < 0) // left
- elasticBand.moveLeft(elasticBand.left() - dx);
- if (dy > 0) // down
- elasticBand.moveBottom(elasticBand.bottom() + dy);
- else if (dy < 0) // up
- elasticBand.moveTop(elasticBand.top() - dy);
-}
-
-void QIconModeViewBase::clear()
-{
- tree.destroy();
- items.clear();
- moved.clear();
- batchStartRow = 0;
- batchSavedDeltaSeg = 0;
-}
-
-void QIconModeViewBase::updateContentsSize()
-{
- QRect bounding;
- for (int i = 0; i < items.count(); ++i)
- bounding |= items.at(i).rect();
- contentsSize = bounding.size();
-}
-
-/*!
- \reimp
-*/
-void QListView::currentChanged(const QModelIndex &current, const QModelIndex &previous)
-{
-#ifndef QT_NO_ACCESSIBILITY
- if (QAccessible::isActive()) {
- if (current.isValid()) {
- int entry = visualIndex(current) + 1;
-#ifdef Q_WS_X11
- QAccessible::updateAccessibility(this, entry, QAccessible::Focus);
-#else
- QAccessible::updateAccessibility(viewport(), entry, QAccessible::Focus);
-#endif
- }
- }
-#endif
- QAbstractItemView::currentChanged(current, previous);
-}
-
-/*!
- \reimp
-*/
-void QListView::selectionChanged(const QItemSelection &selected,
- const QItemSelection &deselected)
-{
-#ifndef QT_NO_ACCESSIBILITY
- if (QAccessible::isActive()) {
- // ### does not work properly for selection ranges.
- QModelIndex sel = selected.indexes().value(0);
- if (sel.isValid()) {
- int entry = visualIndex(sel) + 1;
-#ifdef Q_WS_X11
- QAccessible::updateAccessibility(this, entry, QAccessible::Selection);
-#else
- QAccessible::updateAccessibility(viewport(), entry, QAccessible::Selection);
-#endif
- }
- QModelIndex desel = deselected.indexes().value(0);
- if (desel.isValid()) {
- int entry = visualIndex(desel) + 1;
-#ifdef Q_WS_X11
- QAccessible::updateAccessibility(this, entry, QAccessible::SelectionRemove);
-#else
- QAccessible::updateAccessibility(viewport(), entry, QAccessible::SelectionRemove);
-#endif
- }
- }
-#endif
- QAbstractItemView::selectionChanged(selected, deselected);
-}
-
-int QListView::visualIndex(const QModelIndex &index) const
-{
- Q_D(const QListView);
- d->executePostedLayout();
- QListViewItem itm = d->indexToListViewItem(index);
- return d->commonListView->itemIndex(itm);
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_LISTVIEW
diff --git a/src/gui/itemviews/qlistview.h b/src/gui/itemviews/qlistview.h
deleted file mode 100644
index d51d9e66da..0000000000
--- a/src/gui/itemviews/qlistview.h
+++ /dev/null
@@ -1,203 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QLISTVIEW_H
-#define QLISTVIEW_H
-
-#include <QtGui/qabstractitemview.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_LISTVIEW
-
-class QListViewPrivate;
-
-class Q_GUI_EXPORT QListView : public QAbstractItemView
-{
- Q_OBJECT
- Q_ENUMS(Movement Flow ResizeMode LayoutMode ViewMode)
- Q_PROPERTY(Movement movement READ movement WRITE setMovement)
- Q_PROPERTY(Flow flow READ flow WRITE setFlow)
- Q_PROPERTY(bool isWrapping READ isWrapping WRITE setWrapping)
- Q_PROPERTY(ResizeMode resizeMode READ resizeMode WRITE setResizeMode)
- Q_PROPERTY(LayoutMode layoutMode READ layoutMode WRITE setLayoutMode)
- Q_PROPERTY(int spacing READ spacing WRITE setSpacing)
- Q_PROPERTY(QSize gridSize READ gridSize WRITE setGridSize)
- Q_PROPERTY(ViewMode viewMode READ viewMode WRITE setViewMode)
- Q_PROPERTY(int modelColumn READ modelColumn WRITE setModelColumn)
- Q_PROPERTY(bool uniformItemSizes READ uniformItemSizes WRITE setUniformItemSizes)
- Q_PROPERTY(int batchSize READ batchSize WRITE setBatchSize)
- Q_PROPERTY(bool wordWrap READ wordWrap WRITE setWordWrap)
- Q_PROPERTY(bool selectionRectVisible READ isSelectionRectVisible WRITE setSelectionRectVisible)
-
-public:
- enum Movement { Static, Free, Snap };
- enum Flow { LeftToRight, TopToBottom };
- enum ResizeMode { Fixed, Adjust };
- enum LayoutMode { SinglePass, Batched };
- enum ViewMode { ListMode, IconMode };
-
- explicit QListView(QWidget *parent = 0);
- ~QListView();
-
- void setMovement(Movement movement);
- Movement movement() const;
-
- void setFlow(Flow flow);
- Flow flow() const;
-
- void setWrapping(bool enable);
- bool isWrapping() const;
-
- void setResizeMode(ResizeMode mode);
- ResizeMode resizeMode() const;
-
- void setLayoutMode(LayoutMode mode);
- LayoutMode layoutMode() const;
-
- void setSpacing(int space);
- int spacing() const;
-
- void setBatchSize(int batchSize);
- int batchSize() const;
-
- void setGridSize(const QSize &size);
- QSize gridSize() const;
-
- void setViewMode(ViewMode mode);
- ViewMode viewMode() const;
-
- void clearPropertyFlags();
-
- bool isRowHidden(int row) const;
- void setRowHidden(int row, bool hide);
-
- void setModelColumn(int column);
- int modelColumn() const;
-
- void setUniformItemSizes(bool enable);
- bool uniformItemSizes() const;
-
- void setWordWrap(bool on);
- bool wordWrap() const;
-
- void setSelectionRectVisible(bool show);
- bool isSelectionRectVisible() const;
-
- QRect visualRect(const QModelIndex &index) const;
- void scrollTo(const QModelIndex &index, ScrollHint hint = EnsureVisible);
- QModelIndex indexAt(const QPoint &p) const;
-
- void doItemsLayout();
- void reset();
- void setRootIndex(const QModelIndex &index);
-
-Q_SIGNALS:
- void indexesMoved(const QModelIndexList &indexes);
-
-protected:
- QListView(QListViewPrivate &, QWidget *parent = 0);
-
- bool event(QEvent *e);
-
- void scrollContentsBy(int dx, int dy);
-
- void resizeContents(int width, int height);
- QSize contentsSize() const;
-
- void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
- void rowsInserted(const QModelIndex &parent, int start, int end);
- void rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end);
-
- void mouseMoveEvent(QMouseEvent *e);
- void mouseReleaseEvent(QMouseEvent *e);
-
- void timerEvent(QTimerEvent *e);
- void resizeEvent(QResizeEvent *e);
-#ifndef QT_NO_DRAGANDDROP
- void dragMoveEvent(QDragMoveEvent *e);
- void dragLeaveEvent(QDragLeaveEvent *e);
- void dropEvent(QDropEvent *e);
- void startDrag(Qt::DropActions supportedActions);
-
- void internalDrop(QDropEvent *e);
- void internalDrag(Qt::DropActions supportedActions);
-#endif // QT_NO_DRAGANDDROP
-
- QStyleOptionViewItem viewOptions() const;
- void paintEvent(QPaintEvent *e);
-
- int horizontalOffset() const;
- int verticalOffset() const;
- QModelIndex moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers);
- QRect rectForIndex(const QModelIndex &index) const;
- void setPositionForIndex(const QPoint &position, const QModelIndex &index);
-
- void setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags command);
- QRegion visualRegionForSelection(const QItemSelection &selection) const;
- QModelIndexList selectedIndexes() const;
-
- void updateGeometries();
-
- bool isIndexHidden(const QModelIndex &index) const;
-
- void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
- void currentChanged(const QModelIndex &current, const QModelIndex &previous);
-
-private:
- friend class QAccessibleItemView;
- int visualIndex(const QModelIndex &index) const;
-
- Q_DECLARE_PRIVATE(QListView)
- Q_DISABLE_COPY(QListView)
-};
-
-#endif // QT_NO_LISTVIEW
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QLISTVIEW_H
diff --git a/src/gui/itemviews/qlistwidget.h b/src/gui/itemviews/qlistwidget.h
deleted file mode 100644
index f16f6744ba..0000000000
--- a/src/gui/itemviews/qlistwidget.h
+++ /dev/null
@@ -1,335 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QLISTWIDGET_H
-#define QLISTWIDGET_H
-
-#include <QtGui/qlistview.h>
-#include <QtCore/qvariant.h>
-#include <QtCore/qvector.h>
-#include <QtGui/qitemselectionmodel.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_LISTWIDGET
-
-class QListWidget;
-class QListModel;
-class QWidgetItemData;
-class QListWidgetItemPrivate;
-
-class Q_GUI_EXPORT QListWidgetItem
-{
- friend class QListModel;
- friend class QListWidget;
-public:
- enum ItemType { Type = 0, UserType = 1000 };
- explicit QListWidgetItem(QListWidget *view = 0, int type = Type);
- explicit QListWidgetItem(const QString &text, QListWidget *view = 0, int type = Type);
- explicit QListWidgetItem(const QIcon &icon, const QString &text,
- QListWidget *view = 0, int type = Type);
- QListWidgetItem(const QListWidgetItem &other);
- virtual ~QListWidgetItem();
-
- virtual QListWidgetItem *clone() const;
-
- inline QListWidget *listWidget() const { return view; }
-
- inline void setSelected(bool select);
- inline bool isSelected() const;
-
- inline void setHidden(bool hide);
- inline bool isHidden() const;
-
- inline Qt::ItemFlags flags() const { return itemFlags; }
- void setFlags(Qt::ItemFlags flags);
-
- inline QString text() const
- { return data(Qt::DisplayRole).toString(); }
- inline void setText(const QString &text);
-
- inline QIcon icon() const
- { return qvariant_cast<QIcon>(data(Qt::DecorationRole)); }
- inline void setIcon(const QIcon &icon);
-
- inline QString statusTip() const
- { return data(Qt::StatusTipRole).toString(); }
- inline void setStatusTip(const QString &statusTip);
-
-#ifndef QT_NO_TOOLTIP
- inline QString toolTip() const
- { return data(Qt::ToolTipRole).toString(); }
- inline void setToolTip(const QString &toolTip);
-#endif
-
-#ifndef QT_NO_WHATSTHIS
- inline QString whatsThis() const
- { return data(Qt::WhatsThisRole).toString(); }
- inline void setWhatsThis(const QString &whatsThis);
-#endif
-
- inline QFont font() const
- { return qvariant_cast<QFont>(data(Qt::FontRole)); }
- inline void setFont(const QFont &font);
-
- inline int textAlignment() const
- { return data(Qt::TextAlignmentRole).toInt(); }
- inline void setTextAlignment(int alignment)
- { setData(Qt::TextAlignmentRole, alignment); }
-
- inline QColor backgroundColor() const
- { return qvariant_cast<QColor>(data(Qt::BackgroundColorRole)); }
- virtual void setBackgroundColor(const QColor &color)
- { setData(Qt::BackgroundColorRole, color); }
-
- inline QBrush background() const
- { return qvariant_cast<QBrush>(data(Qt::BackgroundRole)); }
- inline void setBackground(const QBrush &brush)
- { setData(Qt::BackgroundRole, brush); }
-
- inline QColor textColor() const
- { return qvariant_cast<QColor>(data(Qt::TextColorRole)); }
- inline void setTextColor(const QColor &color)
- { setData(Qt::TextColorRole, color); }
-
- inline QBrush foreground() const
- { return qvariant_cast<QBrush>(data(Qt::ForegroundRole)); }
- inline void setForeground(const QBrush &brush)
- { setData(Qt::ForegroundRole, brush); }
-
- inline Qt::CheckState checkState() const
- { return static_cast<Qt::CheckState>(data(Qt::CheckStateRole).toInt()); }
- inline void setCheckState(Qt::CheckState state)
- { setData(Qt::CheckStateRole, static_cast<int>(state)); }
-
- inline QSize sizeHint() const
- { return qvariant_cast<QSize>(data(Qt::SizeHintRole)); }
- inline void setSizeHint(const QSize &size)
- { setData(Qt::SizeHintRole, size); }
-
- virtual QVariant data(int role) const;
- virtual void setData(int role, const QVariant &value);
-
- virtual bool operator<(const QListWidgetItem &other) const;
-
-#ifndef QT_NO_DATASTREAM
- virtual void read(QDataStream &in);
- virtual void write(QDataStream &out) const;
-#endif
- QListWidgetItem &operator=(const QListWidgetItem &other);
-
- inline int type() const { return rtti; }
-
-private:
- int rtti;
- QVector<void *> dummy;
- QListWidget *view;
- QListWidgetItemPrivate *d;
- Qt::ItemFlags itemFlags;
-};
-
-inline void QListWidgetItem::setText(const QString &atext)
-{ setData(Qt::DisplayRole, atext); }
-
-inline void QListWidgetItem::setIcon(const QIcon &aicon)
-{ setData(Qt::DecorationRole, aicon); }
-
-inline void QListWidgetItem::setStatusTip(const QString &astatusTip)
-{ setData(Qt::StatusTipRole, astatusTip); }
-
-#ifndef QT_NO_TOOLTIP
-inline void QListWidgetItem::setToolTip(const QString &atoolTip)
-{ setData(Qt::ToolTipRole, atoolTip); }
-#endif
-
-#ifndef QT_NO_WHATSTHIS
-inline void QListWidgetItem::setWhatsThis(const QString &awhatsThis)
-{ setData(Qt::WhatsThisRole, awhatsThis); }
-#endif
-
-inline void QListWidgetItem::setFont(const QFont &afont)
-{ setData(Qt::FontRole, afont); }
-
-#ifndef QT_NO_DATASTREAM
-Q_GUI_EXPORT QDataStream &operator<<(QDataStream &out, const QListWidgetItem &item);
-Q_GUI_EXPORT QDataStream &operator>>(QDataStream &in, QListWidgetItem &item);
-#endif
-
-class QListWidgetPrivate;
-
-class Q_GUI_EXPORT QListWidget : public QListView
-{
- Q_OBJECT
- Q_PROPERTY(int count READ count)
- Q_PROPERTY(int currentRow READ currentRow WRITE setCurrentRow NOTIFY currentRowChanged USER true)
- Q_PROPERTY(bool sortingEnabled READ isSortingEnabled WRITE setSortingEnabled)
-
- friend class QListWidgetItem;
- friend class QListModel;
-public:
- explicit QListWidget(QWidget *parent = 0);
- ~QListWidget();
-
- QListWidgetItem *item(int row) const;
- int row(const QListWidgetItem *item) const;
- void insertItem(int row, QListWidgetItem *item);
- void insertItem(int row, const QString &label);
- void insertItems(int row, const QStringList &labels);
- inline void addItem(const QString &label) { insertItem(count(), label); }
- inline void addItem(QListWidgetItem *item);
- inline void addItems(const QStringList &labels) { insertItems(count(), labels); }
- QListWidgetItem *takeItem(int row);
- int count() const;
-
- QListWidgetItem *currentItem() const;
- void setCurrentItem(QListWidgetItem *item);
- void setCurrentItem(QListWidgetItem *item, QItemSelectionModel::SelectionFlags command);
-
- int currentRow() const;
- void setCurrentRow(int row);
- void setCurrentRow(int row, QItemSelectionModel::SelectionFlags command);
-
- QListWidgetItem *itemAt(const QPoint &p) const;
- inline QListWidgetItem *itemAt(int x, int y) const;
- QRect visualItemRect(const QListWidgetItem *item) const;
-
- void sortItems(Qt::SortOrder order = Qt::AscendingOrder);
- void setSortingEnabled(bool enable);
- bool isSortingEnabled() const;
-
- void editItem(QListWidgetItem *item);
- void openPersistentEditor(QListWidgetItem *item);
- void closePersistentEditor(QListWidgetItem *item);
-
- QWidget *itemWidget(QListWidgetItem *item) const;
- void setItemWidget(QListWidgetItem *item, QWidget *widget);
- inline void removeItemWidget(QListWidgetItem *item);
-
- bool isItemSelected(const QListWidgetItem *item) const;
- void setItemSelected(const QListWidgetItem *item, bool select);
- QList<QListWidgetItem*> selectedItems() const;
- QList<QListWidgetItem*> findItems(const QString &text, Qt::MatchFlags flags) const;
-
- bool isItemHidden(const QListWidgetItem *item) const;
- void setItemHidden(const QListWidgetItem *item, bool hide);
- void dropEvent(QDropEvent *event);
-
-public Q_SLOTS:
- void scrollToItem(const QListWidgetItem *item, QAbstractItemView::ScrollHint hint = EnsureVisible);
- void clear();
-
-Q_SIGNALS:
- void itemPressed(QListWidgetItem *item);
- void itemClicked(QListWidgetItem *item);
- void itemDoubleClicked(QListWidgetItem *item);
- void itemActivated(QListWidgetItem *item);
- void itemEntered(QListWidgetItem *item);
- void itemChanged(QListWidgetItem *item);
-
- void currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous);
- void currentTextChanged(const QString &currentText);
- void currentRowChanged(int currentRow);
-
- void itemSelectionChanged();
-
-protected:
- bool event(QEvent *e);
- virtual QStringList mimeTypes() const;
- virtual QMimeData *mimeData(const QList<QListWidgetItem*> items) const;
-#ifndef QT_NO_DRAGANDDROP
- virtual bool dropMimeData(int index, const QMimeData *data, Qt::DropAction action);
- virtual Qt::DropActions supportedDropActions() const;
-#endif
- QList<QListWidgetItem*> items(const QMimeData *data) const;
-
- QModelIndex indexFromItem(QListWidgetItem *item) const;
- QListWidgetItem *itemFromIndex(const QModelIndex &index) const;
-
-private:
- void setModel(QAbstractItemModel *model);
- Qt::SortOrder sortOrder() const;
-
- Q_DECLARE_PRIVATE(QListWidget)
- Q_DISABLE_COPY(QListWidget)
-
- Q_PRIVATE_SLOT(d_func(), void _q_emitItemPressed(const QModelIndex &index))
- Q_PRIVATE_SLOT(d_func(), void _q_emitItemClicked(const QModelIndex &index))
- Q_PRIVATE_SLOT(d_func(), void _q_emitItemDoubleClicked(const QModelIndex &index))
- Q_PRIVATE_SLOT(d_func(), void _q_emitItemActivated(const QModelIndex &index))
- Q_PRIVATE_SLOT(d_func(), void _q_emitItemEntered(const QModelIndex &index))
- Q_PRIVATE_SLOT(d_func(), void _q_emitItemChanged(const QModelIndex &index))
- Q_PRIVATE_SLOT(d_func(), void _q_emitCurrentItemChanged(const QModelIndex &previous, const QModelIndex &current))
- Q_PRIVATE_SLOT(d_func(), void _q_sort())
- Q_PRIVATE_SLOT(d_func(), void _q_dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight))
-};
-
-inline void QListWidget::removeItemWidget(QListWidgetItem *aItem)
-{ setItemWidget(aItem, 0); }
-
-inline void QListWidget::addItem(QListWidgetItem *aitem)
-{ insertItem(count(), aitem); }
-
-inline QListWidgetItem *QListWidget::itemAt(int ax, int ay) const
-{ return itemAt(QPoint(ax, ay)); }
-
-inline void QListWidgetItem::setSelected(bool aselect)
-{ if (view) view->setItemSelected(this, aselect); }
-
-inline bool QListWidgetItem::isSelected() const
-{ return (view ? view->isItemSelected(this) : false); }
-
-inline void QListWidgetItem::setHidden(bool ahide)
-{ if (view) view->setItemHidden(this, ahide); }
-
-inline bool QListWidgetItem::isHidden() const
-{ return (view ? view->isItemHidden(this) : false); }
-
-#endif // QT_NO_LISTWIDGET
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QLISTWIDGET_H
diff --git a/src/gui/itemviews/qlistwidget_p.h b/src/gui/itemviews/qlistwidget_p.h
deleted file mode 100644
index c94e151081..0000000000
--- a/src/gui/itemviews/qlistwidget_p.h
+++ /dev/null
@@ -1,175 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QLISTWIDGET_P_H
-#define QLISTWIDGET_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. This header file may change
-// from version to version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/qabstractitemmodel.h>
-#include <QtGui/qabstractitemview.h>
-#include <QtGui/qlistwidget.h>
-#include <qitemdelegate.h>
-#include <private/qlistview_p.h>
-#include <private/qwidgetitemdata_p.h>
-
-#ifndef QT_NO_LISTWIDGET
-
-QT_BEGIN_NAMESPACE
-
-class QListModelLessThan
-{
-public:
- inline bool operator()(QListWidgetItem *i1, QListWidgetItem *i2) const
- { return *i1 < *i2; }
-};
-
-class QListModelGreaterThan
-{
-public:
- inline bool operator()(QListWidgetItem *i1, QListWidgetItem *i2) const
- { return *i2 < *i1; }
-};
-
-class Q_AUTOTEST_EXPORT QListModel : public QAbstractListModel
-{
- Q_OBJECT
-public:
- QListModel(QListWidget *parent);
- ~QListModel();
-
- void clear();
- QListWidgetItem *at(int row) const;
- void insert(int row, QListWidgetItem *item);
- void insert(int row, const QStringList &items);
- void remove(QListWidgetItem *item);
- QListWidgetItem *take(int row);
- void move(int srcRow, int dstRow);
-
- int rowCount(const QModelIndex &parent = QModelIndex()) const;
-
- QModelIndex index(QListWidgetItem *item) const;
- QModelIndex index(int row, int column = 0, const QModelIndex &parent = QModelIndex()) const;
-
- QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
- bool setData(const QModelIndex &index, const QVariant &value, int role);
-
- QMap<int, QVariant> itemData(const QModelIndex &index) const;
-
- bool insertRows(int row, int count = 1, const QModelIndex &parent = QModelIndex());
- bool removeRows(int row, int count = 1, const QModelIndex &parent = QModelIndex());
-
- Qt::ItemFlags flags(const QModelIndex &index) const;
-
- void sort(int column, Qt::SortOrder order);
- void ensureSorted(int column, Qt::SortOrder order, int start, int end);
- static bool itemLessThan(const QPair<QListWidgetItem*,int> &left,
- const QPair<QListWidgetItem*,int> &right);
- static bool itemGreaterThan(const QPair<QListWidgetItem*,int> &left,
- const QPair<QListWidgetItem*,int> &right);
- static QList<QListWidgetItem*>::iterator sortedInsertionIterator(
- const QList<QListWidgetItem*>::iterator &begin,
- const QList<QListWidgetItem*>::iterator &end,
- Qt::SortOrder order, QListWidgetItem *item);
-
- void itemChanged(QListWidgetItem *item);
-
- // dnd
- QStringList mimeTypes() const;
- QMimeData *mimeData(const QModelIndexList &indexes) const;
-#ifndef QT_NO_DRAGANDDROP
- bool dropMimeData(const QMimeData *data, Qt::DropAction action,
- int row, int column, const QModelIndex &parent);
- Qt::DropActions supportedDropActions() const;
-#endif
-
- QMimeData *internalMimeData() const;
-private:
- QList<QListWidgetItem*> items;
-
- // A cache must be mutable if get-functions should have const modifiers
- mutable QModelIndexList cachedIndexes;
-};
-
-
-
-class QListWidgetPrivate : public QListViewPrivate
-{
- Q_DECLARE_PUBLIC(QListWidget)
-public:
- QListWidgetPrivate() : QListViewPrivate(), sortOrder(Qt::AscendingOrder), sortingEnabled(false) {}
- inline QListModel *listModel() const { return qobject_cast<QListModel*>(model); }
- void setup();
- void _q_emitItemPressed(const QModelIndex &index);
- void _q_emitItemClicked(const QModelIndex &index);
- void _q_emitItemDoubleClicked(const QModelIndex &index);
- void _q_emitItemActivated(const QModelIndex &index);
- void _q_emitItemEntered(const QModelIndex &index);
- void _q_emitItemChanged(const QModelIndex &index);
- void _q_emitCurrentItemChanged(const QModelIndex &current, const QModelIndex &previous);
- void _q_sort();
- void _q_dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
- Qt::SortOrder sortOrder;
- bool sortingEnabled;
-};
-
-class QListWidgetItemPrivate
-{
-public:
- QListWidgetItemPrivate(QListWidgetItem *item) : q(item), theid(-1) {}
- QListWidgetItem *q;
- QVector<QWidgetItemData> values;
- int theid;
-};
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_LISTWIDGET
-
-#endif // QLISTWIDGET_P_H
diff --git a/src/gui/itemviews/qproxymodel.h b/src/gui/itemviews/qproxymodel.h
deleted file mode 100644
index 49145bb1d7..0000000000
--- a/src/gui/itemviews/qproxymodel.h
+++ /dev/null
@@ -1,143 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPROXYMODEL_H
-#define QPROXYMODEL_H
-
-#include <QtCore/qabstractitemmodel.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_PROXYMODEL
-
-class QProxyModelPrivate;
-
-class Q_GUI_EXPORT QProxyModel : public QAbstractItemModel
-{
- Q_OBJECT
-
-public:
- explicit QProxyModel(QObject *parent = 0);
- ~QProxyModel();
-
- virtual void setModel(QAbstractItemModel *model);
- QAbstractItemModel *model() const;
-
- // implementing model interface
-
- QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
- QModelIndex parent(const QModelIndex &child) const;
-
- int rowCount(const QModelIndex &parent = QModelIndex()) const;
- int columnCount(const QModelIndex &parent = QModelIndex()) const;
- bool hasChildren(const QModelIndex &parent = QModelIndex()) const;
-
- QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
- bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
-
- QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
- bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value,
- int role = Qt::EditRole);
-
- QStringList mimeTypes() const;
- QMimeData *mimeData(const QModelIndexList &indexes) const;
- bool dropMimeData(const QMimeData *data, Qt::DropAction action,
- int row, int column, const QModelIndex &parent);
- Qt::DropActions supportedDropActions() const;
-
- bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex());
- bool insertColumns(int column, int count, const QModelIndex &parent = QModelIndex());
-
- void fetchMore(const QModelIndex &parent);
- Qt::ItemFlags flags(const QModelIndex &index) const;
-
- void sort(int column, Qt::SortOrder order = Qt::AscendingOrder);
-
- QModelIndexList match(const QModelIndex &start, int role, const QVariant &value,
- int hits = 1, Qt::MatchFlags flags =
- Qt::MatchFlags(Qt::MatchStartsWith|Qt::MatchWrap)) const;
-
- QSize span(const QModelIndex &index) const;
-
- bool submit();
- void revert();
-
-#ifdef Q_NO_USING_KEYWORD
- inline QObject *parent() const { return QObject::parent(); }
-#else
- using QObject::parent;
-#endif
-
-protected:
- QProxyModel(QProxyModelPrivate &, QObject *parent = 0);
-
- QModelIndex setProxyModel(const QModelIndex &source_index) const;
- QModelIndex setSourceModel(const QModelIndex &proxy_index) const;
-
- void connectToModel(const QAbstractItemModel *model) const;
- void disconnectFromModel(const QAbstractItemModel *model) const;
-
-private:
- Q_DECLARE_PRIVATE(QProxyModel)
- Q_DISABLE_COPY(QProxyModel)
-
- Q_PRIVATE_SLOT(d_func(), void _q_sourceDataChanged(const QModelIndex&,const QModelIndex&))
- Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsAboutToBeInserted(const QModelIndex&,int,int))
- Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsInserted(const QModelIndex&,int,int))
- Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsAboutToBeRemoved(const QModelIndex&,int,int))
- Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsRemoved(const QModelIndex&,int,int))
- Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsAboutToBeInserted(const QModelIndex&,int,int))
- Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsInserted(const QModelIndex&,int,int))
- Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsAboutToBeRemoved(const QModelIndex&,int,int))
- Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsRemoved(const QModelIndex&,int,int))
-};
-
-#endif // QT_NO_PROXYMODEL
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QPROXYMODEL_H
diff --git a/src/gui/itemviews/qsortfilterproxymodel.h b/src/gui/itemviews/qsortfilterproxymodel.h
deleted file mode 100644
index da132869b4..0000000000
--- a/src/gui/itemviews/qsortfilterproxymodel.h
+++ /dev/null
@@ -1,201 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSORTFILTERPROXYMODEL_H
-#define QSORTFILTERPROXYMODEL_H
-
-#include <QtGui/qabstractproxymodel.h>
-
-#ifndef QT_NO_SORTFILTERPROXYMODEL
-
-#include <QtCore/qregexp.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QSortFilterProxyModelPrivate;
-class QSortFilterProxyModelLessThan;
-class QSortFilterProxyModelGreaterThan;
-
-class Q_GUI_EXPORT QSortFilterProxyModel : public QAbstractProxyModel
-{
- friend class QSortFilterProxyModelLessThan;
- friend class QSortFilterProxyModelGreaterThan;
-
- Q_OBJECT
- Q_PROPERTY(QRegExp filterRegExp READ filterRegExp WRITE setFilterRegExp)
- Q_PROPERTY(int filterKeyColumn READ filterKeyColumn WRITE setFilterKeyColumn)
- Q_PROPERTY(bool dynamicSortFilter READ dynamicSortFilter WRITE setDynamicSortFilter)
- Q_PROPERTY(Qt::CaseSensitivity filterCaseSensitivity READ filterCaseSensitivity WRITE setFilterCaseSensitivity)
- Q_PROPERTY(Qt::CaseSensitivity sortCaseSensitivity READ sortCaseSensitivity WRITE setSortCaseSensitivity)
- Q_PROPERTY(bool isSortLocaleAware READ isSortLocaleAware WRITE setSortLocaleAware)
- Q_PROPERTY(int sortRole READ sortRole WRITE setSortRole)
- Q_PROPERTY(int filterRole READ filterRole WRITE setFilterRole)
-
-public:
- QSortFilterProxyModel(QObject *parent = 0);
- ~QSortFilterProxyModel();
-
- void setSourceModel(QAbstractItemModel *sourceModel);
-
- QModelIndex mapToSource(const QModelIndex &proxyIndex) const;
- QModelIndex mapFromSource(const QModelIndex &sourceIndex) const;
-
- QItemSelection mapSelectionToSource(const QItemSelection &proxySelection) const;
- QItemSelection mapSelectionFromSource(const QItemSelection &sourceSelection) const;
-
- QRegExp filterRegExp() const;
- void setFilterRegExp(const QRegExp &regExp);
-
- int filterKeyColumn() const;
- void setFilterKeyColumn(int column);
-
- Qt::CaseSensitivity filterCaseSensitivity() const;
- void setFilterCaseSensitivity(Qt::CaseSensitivity cs);
-
- Qt::CaseSensitivity sortCaseSensitivity() const;
- void setSortCaseSensitivity(Qt::CaseSensitivity cs);
-
- bool isSortLocaleAware() const;
- void setSortLocaleAware(bool on);
-
- int sortColumn() const;
- Qt::SortOrder sortOrder() const;
-
- bool dynamicSortFilter() const;
- void setDynamicSortFilter(bool enable);
-
- int sortRole() const;
- void setSortRole(int role);
-
- int filterRole() const;
- void setFilterRole(int role);
-
-public Q_SLOTS:
- void setFilterRegExp(const QString &pattern);
- void setFilterWildcard(const QString &pattern);
- void setFilterFixedString(const QString &pattern);
- void clear();
- void invalidate();
-
-protected:
- virtual bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const;
- virtual bool filterAcceptsColumn(int source_column, const QModelIndex &source_parent) const;
- virtual bool lessThan(const QModelIndex &left, const QModelIndex &right) const;
-
- void filterChanged();
- void invalidateFilter();
-
-public:
-#ifdef Q_NO_USING_KEYWORD
- inline QObject *parent() const { return QObject::parent(); }
-#else
- using QObject::parent;
-#endif
-
- QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
- QModelIndex parent(const QModelIndex &child) const;
-
- int rowCount(const QModelIndex &parent = QModelIndex()) const;
- int columnCount(const QModelIndex &parent = QModelIndex()) const;
- bool hasChildren(const QModelIndex &parent = QModelIndex()) const;
-
- QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
- bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
-
- QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
- bool setHeaderData(int section, Qt::Orientation orientation,
- const QVariant &value, int role = Qt::EditRole);
-
- QMimeData *mimeData(const QModelIndexList &indexes) const;
- bool dropMimeData(const QMimeData *data, Qt::DropAction action,
- int row, int column, const QModelIndex &parent);
-
- bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex());
- bool insertColumns(int column, int count, const QModelIndex &parent = QModelIndex());
- bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex());
- bool removeColumns(int column, int count, const QModelIndex &parent = QModelIndex());
-
- void fetchMore(const QModelIndex &parent);
- bool canFetchMore(const QModelIndex &parent) const;
- Qt::ItemFlags flags(const QModelIndex &index) const;
-
- QModelIndex buddy(const QModelIndex &index) const;
- QModelIndexList match(const QModelIndex &start, int role,
- const QVariant &value, int hits = 1,
- Qt::MatchFlags flags =
- Qt::MatchFlags(Qt::MatchStartsWith|Qt::MatchWrap)) const;
- QSize span(const QModelIndex &index) const;
- void sort(int column, Qt::SortOrder order = Qt::AscendingOrder);
-
- QStringList mimeTypes() const;
- Qt::DropActions supportedDropActions() const;
-private:
- Q_DECLARE_PRIVATE(QSortFilterProxyModel)
- Q_DISABLE_COPY(QSortFilterProxyModel)
-
- Q_PRIVATE_SLOT(d_func(), void _q_sourceDataChanged(const QModelIndex &source_top_left, const QModelIndex &source_bottom_right))
- Q_PRIVATE_SLOT(d_func(), void _q_sourceHeaderDataChanged(Qt::Orientation orientation, int start, int end))
- Q_PRIVATE_SLOT(d_func(), void _q_sourceAboutToBeReset())
- Q_PRIVATE_SLOT(d_func(), void _q_sourceReset())
- Q_PRIVATE_SLOT(d_func(), void _q_sourceLayoutAboutToBeChanged())
- Q_PRIVATE_SLOT(d_func(), void _q_sourceLayoutChanged())
- Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsAboutToBeInserted(const QModelIndex &source_parent, int start, int end))
- Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsInserted(const QModelIndex &source_parent, int start, int end))
- Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsAboutToBeRemoved(const QModelIndex &source_parent, int start, int end))
- Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsRemoved(const QModelIndex &source_parent, int start, int end))
- Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsAboutToBeInserted(const QModelIndex &source_parent, int start, int end))
- Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsInserted(const QModelIndex &source_parent, int start, int end))
- Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsAboutToBeRemoved(const QModelIndex &source_parent, int start, int end))
- Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsRemoved(const QModelIndex &source_parent, int start, int end))
- Q_PRIVATE_SLOT(d_func(), void _q_clearMapping())
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QT_NO_SORTFILTERPROXYMODEL
-
-#endif // QSORTFILTERPROXYMODEL_H
diff --git a/src/gui/itemviews/qstandarditemmodel.h b/src/gui/itemviews/qstandarditemmodel.h
deleted file mode 100644
index d3219df526..0000000000
--- a/src/gui/itemviews/qstandarditemmodel.h
+++ /dev/null
@@ -1,456 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSTANDARDITEMMODEL_H
-#define QSTANDARDITEMMODEL_H
-
-#include <QtCore/qabstractitemmodel.h>
-#include <QtGui/qbrush.h>
-#include <QtGui/qfont.h>
-#include <QtGui/qicon.h>
-#ifndef QT_NO_DATASTREAM
-#include <QtCore/qdatastream.h>
-#endif
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_STANDARDITEMMODEL
-
-template <class T> class QList;
-
-class QStandardItemModel;
-
-class QStandardItemPrivate;
-class Q_GUI_EXPORT QStandardItem
-{
-public:
- QStandardItem();
- QStandardItem(const QString &text);
- QStandardItem(const QIcon &icon, const QString &text);
- explicit QStandardItem(int rows, int columns = 1);
- virtual ~QStandardItem();
-
- virtual QVariant data(int role = Qt::UserRole + 1) const;
- virtual void setData(const QVariant &value, int role = Qt::UserRole + 1);
-
- inline QString text() const {
- return qvariant_cast<QString>(data(Qt::DisplayRole));
- }
- inline void setText(const QString &text);
-
- inline QIcon icon() const {
- return qvariant_cast<QIcon>(data(Qt::DecorationRole));
- }
- inline void setIcon(const QIcon &icon);
-
-#ifndef QT_NO_TOOLTIP
- inline QString toolTip() const {
- return qvariant_cast<QString>(data(Qt::ToolTipRole));
- }
- inline void setToolTip(const QString &toolTip);
-#endif
-
-#ifndef QT_NO_STATUSTIP
- inline QString statusTip() const {
- return qvariant_cast<QString>(data(Qt::StatusTipRole));
- }
- inline void setStatusTip(const QString &statusTip);
-#endif
-
-#ifndef QT_NO_WHATSTHIS
- inline QString whatsThis() const {
- return qvariant_cast<QString>(data(Qt::WhatsThisRole));
- }
- inline void setWhatsThis(const QString &whatsThis);
-#endif
-
- inline QSize sizeHint() const {
- return qvariant_cast<QSize>(data(Qt::SizeHintRole));
- }
- inline void setSizeHint(const QSize &sizeHint);
-
- inline QFont font() const {
- return qvariant_cast<QFont>(data(Qt::FontRole));
- }
- inline void setFont(const QFont &font);
-
- inline Qt::Alignment textAlignment() const {
- return Qt::Alignment(qvariant_cast<int>(data(Qt::TextAlignmentRole)));
- }
- inline void setTextAlignment(Qt::Alignment textAlignment);
-
- inline QBrush background() const {
- return qvariant_cast<QBrush>(data(Qt::BackgroundRole));
- }
- inline void setBackground(const QBrush &brush);
-
- inline QBrush foreground() const {
- return qvariant_cast<QBrush>(data(Qt::ForegroundRole));
- }
- inline void setForeground(const QBrush &brush);
-
- inline Qt::CheckState checkState() const {
- return Qt::CheckState(qvariant_cast<int>(data(Qt::CheckStateRole)));
- }
- inline void setCheckState(Qt::CheckState checkState);
-
- inline QString accessibleText() const {
- return qvariant_cast<QString>(data(Qt::AccessibleTextRole));
- }
- inline void setAccessibleText(const QString &accessibleText);
-
- inline QString accessibleDescription() const {
- return qvariant_cast<QString>(data(Qt::AccessibleDescriptionRole));
- }
- inline void setAccessibleDescription(const QString &accessibleDescription);
-
- Qt::ItemFlags flags() const;
- void setFlags(Qt::ItemFlags flags);
-
- inline bool isEnabled() const {
- return (flags() & Qt::ItemIsEnabled) != 0;
- }
- void setEnabled(bool enabled);
-
- inline bool isEditable() const {
- return (flags() & Qt::ItemIsEditable) != 0;
- }
- void setEditable(bool editable);
-
- inline bool isSelectable() const {
- return (flags() & Qt::ItemIsSelectable) != 0;
- }
- void setSelectable(bool selectable);
-
- inline bool isCheckable() const {
- return (flags() & Qt::ItemIsUserCheckable) != 0;
- }
- void setCheckable(bool checkable);
-
- inline bool isTristate() const {
- return (flags() & Qt::ItemIsTristate) != 0;
- }
- void setTristate(bool tristate);
-
-#ifndef QT_NO_DRAGANDDROP
- inline bool isDragEnabled() const {
- return (flags() & Qt::ItemIsDragEnabled) != 0;
- }
- void setDragEnabled(bool dragEnabled);
-
- inline bool isDropEnabled() const {
- return (flags() & Qt::ItemIsDropEnabled) != 0;
- }
- void setDropEnabled(bool dropEnabled);
-#endif // QT_NO_DRAGANDDROP
-
- QStandardItem *parent() const;
- int row() const;
- int column() const;
- QModelIndex index() const;
- QStandardItemModel *model() const;
-
- int rowCount() const;
- void setRowCount(int rows);
- int columnCount() const;
- void setColumnCount(int columns);
-
- bool hasChildren() const;
- QStandardItem *child(int row, int column = 0) const;
- void setChild(int row, int column, QStandardItem *item);
- inline void setChild(int row, QStandardItem *item);
-
- void insertRow(int row, const QList<QStandardItem*> &items);
- void insertColumn(int column, const QList<QStandardItem*> &items);
- void insertRows(int row, const QList<QStandardItem*> &items);
- void insertRows(int row, int count);
- void insertColumns(int column, int count);
-
- void removeRow(int row);
- void removeColumn(int column);
- void removeRows(int row, int count);
- void removeColumns(int column, int count);
-
- inline void appendRow(const QList<QStandardItem*> &items);
- inline void appendRows(const QList<QStandardItem*> &items);
- inline void appendColumn(const QList<QStandardItem*> &items);
- inline void insertRow(int row, QStandardItem *item);
- inline void appendRow(QStandardItem *item);
-
- QStandardItem *takeChild(int row, int column = 0);
- QList<QStandardItem*> takeRow(int row);
- QList<QStandardItem*> takeColumn(int column);
-
- void sortChildren(int column, Qt::SortOrder order = Qt::AscendingOrder);
-
- virtual QStandardItem *clone() const;
-
- enum ItemType { Type = 0, UserType = 1000 };
- virtual int type() const;
-
-#ifndef QT_NO_DATASTREAM
- virtual void read(QDataStream &in);
- virtual void write(QDataStream &out) const;
-#endif
- virtual bool operator<(const QStandardItem &other) const;
-
-protected:
- QStandardItem(const QStandardItem &other);
- QStandardItem(QStandardItemPrivate &dd);
- QStandardItem &operator=(const QStandardItem &other);
- QScopedPointer<QStandardItemPrivate> d_ptr;
-
- void emitDataChanged();
-
-private:
- Q_DECLARE_PRIVATE(QStandardItem)
- friend class QStandardItemModelPrivate;
- friend class QStandardItemModel;
-};
-
-inline void QStandardItem::setText(const QString &atext)
-{ setData(atext, Qt::DisplayRole); }
-
-inline void QStandardItem::setIcon(const QIcon &aicon)
-{ setData(aicon, Qt::DecorationRole); }
-
-#ifndef QT_NO_TOOLTIP
-inline void QStandardItem::setToolTip(const QString &atoolTip)
-{ setData(atoolTip, Qt::ToolTipRole); }
-#endif
-
-#ifndef QT_NO_STATUSTIP
-inline void QStandardItem::setStatusTip(const QString &astatusTip)
-{ setData(astatusTip, Qt::StatusTipRole); }
-#endif
-
-#ifndef QT_NO_WHATSTHIS
-inline void QStandardItem::setWhatsThis(const QString &awhatsThis)
-{ setData(awhatsThis, Qt::WhatsThisRole); }
-#endif
-
-inline void QStandardItem::setSizeHint(const QSize &asizeHint)
-{ setData(asizeHint, Qt::SizeHintRole); }
-
-inline void QStandardItem::setFont(const QFont &afont)
-{ setData(afont, Qt::FontRole); }
-
-inline void QStandardItem::setTextAlignment(Qt::Alignment atextAlignment)
-{ setData(int(atextAlignment), Qt::TextAlignmentRole); }
-
-inline void QStandardItem::setBackground(const QBrush &abrush)
-{ setData(abrush, Qt::BackgroundRole); }
-
-inline void QStandardItem::setForeground(const QBrush &abrush)
-{ setData(abrush, Qt::ForegroundRole); }
-
-inline void QStandardItem::setCheckState(Qt::CheckState acheckState)
-{ setData(acheckState, Qt::CheckStateRole); }
-
-inline void QStandardItem::setAccessibleText(const QString &aaccessibleText)
-{ setData(aaccessibleText, Qt::AccessibleTextRole); }
-
-inline void QStandardItem::setAccessibleDescription(const QString &aaccessibleDescription)
-{ setData(aaccessibleDescription, Qt::AccessibleDescriptionRole); }
-
-inline void QStandardItem::setChild(int arow, QStandardItem *aitem)
-{ setChild(arow, 0, aitem); }
-
-inline void QStandardItem::appendRow(const QList<QStandardItem*> &aitems)
-{ insertRow(rowCount(), aitems); }
-
-inline void QStandardItem::appendRows(const QList<QStandardItem*> &aitems)
-{ insertRows(rowCount(), aitems); }
-
-inline void QStandardItem::appendColumn(const QList<QStandardItem*> &aitems)
-{ insertColumn(columnCount(), aitems); }
-
-inline void QStandardItem::insertRow(int arow, QStandardItem *aitem)
-{ insertRow(arow, QList<QStandardItem*>() << aitem); }
-
-inline void QStandardItem::appendRow(QStandardItem *aitem)
-{ insertRow(rowCount(), aitem); }
-
-class QStandardItemModelPrivate;
-
-class Q_GUI_EXPORT QStandardItemModel : public QAbstractItemModel
-{
- Q_OBJECT
- Q_PROPERTY(int sortRole READ sortRole WRITE setSortRole)
-
-public:
- explicit QStandardItemModel(QObject *parent = 0);
- QStandardItemModel(int rows, int columns, QObject *parent = 0);
- ~QStandardItemModel();
-
- QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
- QModelIndex parent(const QModelIndex &child) const;
-
- int rowCount(const QModelIndex &parent = QModelIndex()) const;
- int columnCount(const QModelIndex &parent = QModelIndex()) const;
- bool hasChildren(const QModelIndex &parent = QModelIndex()) const;
-
- QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
- bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
-
- QVariant headerData(int section, Qt::Orientation orientation,
- int role = Qt::DisplayRole) const;
- bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value,
- int role = Qt::EditRole);
-
- bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex());
- bool insertColumns(int column, int count, const QModelIndex &parent = QModelIndex());
- bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex());
- bool removeColumns(int column, int count, const QModelIndex &parent = QModelIndex());
-
- Qt::ItemFlags flags(const QModelIndex &index) const;
- Qt::DropActions supportedDropActions() const;
-
- QMap<int, QVariant> itemData(const QModelIndex &index) const;
- bool setItemData(const QModelIndex &index, const QMap<int, QVariant> &roles);
-
- void clear();
-
-#ifdef Q_NO_USING_KEYWORD
- inline QObject *parent() const { return QObject::parent(); }
-#else
- using QObject::parent;
-#endif
-
- void sort(int column, Qt::SortOrder order = Qt::AscendingOrder);
-
- QStandardItem *itemFromIndex(const QModelIndex &index) const;
- QModelIndex indexFromItem(const QStandardItem *item) const;
-
- QStandardItem *item(int row, int column = 0) const;
- void setItem(int row, int column, QStandardItem *item);
- inline void setItem(int row, QStandardItem *item);
- QStandardItem *invisibleRootItem() const;
-
- QStandardItem *horizontalHeaderItem(int column) const;
- void setHorizontalHeaderItem(int column, QStandardItem *item);
- QStandardItem *verticalHeaderItem(int row) const;
- void setVerticalHeaderItem(int row, QStandardItem *item);
-
- void setHorizontalHeaderLabels(const QStringList &labels);
- void setVerticalHeaderLabels(const QStringList &labels);
-
- void setRowCount(int rows);
- void setColumnCount(int columns);
-
- void appendRow(const QList<QStandardItem*> &items);
- void appendColumn(const QList<QStandardItem*> &items);
- inline void appendRow(QStandardItem *item);
-
- void insertRow(int row, const QList<QStandardItem*> &items);
- void insertColumn(int column, const QList<QStandardItem*> &items);
- inline void insertRow(int row, QStandardItem *item);
-
- inline bool insertRow(int row, const QModelIndex &parent = QModelIndex());
- inline bool insertColumn(int column, const QModelIndex &parent = QModelIndex());
-
- QStandardItem *takeItem(int row, int column = 0);
- QList<QStandardItem*> takeRow(int row);
- QList<QStandardItem*> takeColumn(int column);
-
- QStandardItem *takeHorizontalHeaderItem(int column);
- QStandardItem *takeVerticalHeaderItem(int row);
-
- const QStandardItem *itemPrototype() const;
- void setItemPrototype(const QStandardItem *item);
-
- QList<QStandardItem*> findItems(const QString &text,
- Qt::MatchFlags flags = Qt::MatchExactly,
- int column = 0) const;
-
- int sortRole() const;
- void setSortRole(int role);
-
- QStringList mimeTypes() const;
- QMimeData *mimeData(const QModelIndexList &indexes) const;
- bool dropMimeData (const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent);
-
-Q_SIGNALS:
- void itemChanged(QStandardItem *item);
-
-protected:
- QStandardItemModel(QStandardItemModelPrivate &dd, QObject *parent = 0);
-
-private:
- friend class QStandardItemPrivate;
- friend class QStandardItem;
- Q_DISABLE_COPY(QStandardItemModel)
- Q_DECLARE_PRIVATE(QStandardItemModel)
-
- Q_PRIVATE_SLOT(d_func(), void _q_emitItemChanged(const QModelIndex &topLeft,
- const QModelIndex &bottomRight))
-};
-
-inline void QStandardItemModel::setItem(int arow, QStandardItem *aitem)
-{ setItem(arow, 0, aitem); }
-
-inline void QStandardItemModel::appendRow(QStandardItem *aitem)
-{ appendRow(QList<QStandardItem*>() << aitem); }
-
-inline void QStandardItemModel::insertRow(int arow, QStandardItem *aitem)
-{ insertRow(arow, QList<QStandardItem*>() << aitem); }
-
-inline bool QStandardItemModel::insertRow(int arow, const QModelIndex &aparent)
-{ return QAbstractItemModel::insertRow(arow, aparent); }
-inline bool QStandardItemModel::insertColumn(int acolumn, const QModelIndex &aparent)
-{ return QAbstractItemModel::insertColumn(acolumn, aparent); }
-
-#ifndef QT_NO_DATASTREAM
-Q_GUI_EXPORT QDataStream &operator>>(QDataStream &in, QStandardItem &item);
-Q_GUI_EXPORT QDataStream &operator<<(QDataStream &out, const QStandardItem &item);
-#endif
-
-#endif // QT_NO_STANDARDITEMMODEL
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif //QSTANDARDITEMMODEL_H
diff --git a/src/gui/itemviews/qstringlistmodel.h b/src/gui/itemviews/qstringlistmodel.h
deleted file mode 100644
index bdfe4d8d3b..0000000000
--- a/src/gui/itemviews/qstringlistmodel.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSTRINGLISTMODEL_H
-#define QSTRINGLISTMODEL_H
-
-#include <QtCore/qstringlist.h>
-#include <QtGui/qabstractitemview.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_STRINGLISTMODEL
-
-class Q_GUI_EXPORT QStringListModel : public QAbstractListModel
-{
- Q_OBJECT
-public:
- explicit QStringListModel(QObject *parent = 0);
- QStringListModel(const QStringList &strings, QObject *parent = 0);
-
- int rowCount(const QModelIndex &parent = QModelIndex()) const;
-
- QVariant data(const QModelIndex &index, int role) const;
- bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
-
- Qt::ItemFlags flags(const QModelIndex &index) const;
-
- bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex());
- bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex());
-
- void sort(int column, Qt::SortOrder order = Qt::AscendingOrder);
-
- QStringList stringList() const;
- void setStringList(const QStringList &strings);
-
- Qt::DropActions supportedDropActions() const;
-
-private:
- Q_DISABLE_COPY(QStringListModel)
- QStringList lst;
-};
-
-#endif // QT_NO_STRINGLISTMODEL
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QSTRINGLISTMODEL_H
diff --git a/src/gui/itemviews/qstyleditemdelegate.h b/src/gui/itemviews/qstyleditemdelegate.h
deleted file mode 100644
index 8b2bc14a81..0000000000
--- a/src/gui/itemviews/qstyleditemdelegate.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSTYLEDITEMDELEGATE_H
-#define QSTYLEDITEMDELEGATE_H
-
-#include <QtGui/qabstractitemdelegate.h>
-#include <QtCore/qstring.h>
-#include <QtGui/qpixmap.h>
-#include <QtCore/qvariant.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_ITEMVIEWS
-
-class QStyledItemDelegatePrivate;
-class QItemEditorFactory;
-
-class Q_GUI_EXPORT QStyledItemDelegate : public QAbstractItemDelegate
-{
- Q_OBJECT
-
-public:
- explicit QStyledItemDelegate(QObject *parent = 0);
- ~QStyledItemDelegate();
-
- // painting
- void paint(QPainter *painter,
- const QStyleOptionViewItem &option, const QModelIndex &index) const;
- QSize sizeHint(const QStyleOptionViewItem &option,
- const QModelIndex &index) const;
-
- // editing
- QWidget *createEditor(QWidget *parent,
- const QStyleOptionViewItem &option,
- const QModelIndex &index) const;
-
- void setEditorData(QWidget *editor, const QModelIndex &index) const;
- void setModelData(QWidget *editor,
- QAbstractItemModel *model,
- const QModelIndex &index) const;
-
- void updateEditorGeometry(QWidget *editor,
- const QStyleOptionViewItem &option,
- const QModelIndex &index) const;
-
- // editor factory
- QItemEditorFactory *itemEditorFactory() const;
- void setItemEditorFactory(QItemEditorFactory *factory);
-
- virtual QString displayText(const QVariant &value, const QLocale &locale) const;
-
-protected:
- virtual void initStyleOption(QStyleOptionViewItem *option,
- const QModelIndex &index) const;
-
- bool eventFilter(QObject *object, QEvent *event);
- bool editorEvent(QEvent *event, QAbstractItemModel *model,
- const QStyleOptionViewItem &option, const QModelIndex &index);
-
-private:
- Q_DECLARE_PRIVATE(QStyledItemDelegate)
- Q_DISABLE_COPY(QStyledItemDelegate)
-
- Q_PRIVATE_SLOT(d_func(), void _q_commitDataAndCloseEditor(QWidget*))
-};
-
-#endif // QT_NO_ITEMVIEWS
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QSTYLEDITEMDELEGATE_H
diff --git a/src/gui/itemviews/qtableview.h b/src/gui/itemviews/qtableview.h
deleted file mode 100644
index 27b2dccf3f..0000000000
--- a/src/gui/itemviews/qtableview.h
+++ /dev/null
@@ -1,198 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QTABLEVIEW_H
-#define QTABLEVIEW_H
-
-#include <QtGui/qabstractitemview.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_TABLEVIEW
-
-class QHeaderView;
-class QTableViewPrivate;
-
-class Q_GUI_EXPORT QTableView : public QAbstractItemView
-{
- Q_OBJECT
- Q_PROPERTY(bool showGrid READ showGrid WRITE setShowGrid)
- Q_PROPERTY(Qt::PenStyle gridStyle READ gridStyle WRITE setGridStyle)
- Q_PROPERTY(bool sortingEnabled READ isSortingEnabled WRITE setSortingEnabled)
- Q_PROPERTY(bool wordWrap READ wordWrap WRITE setWordWrap)
- Q_PROPERTY(bool cornerButtonEnabled READ isCornerButtonEnabled WRITE setCornerButtonEnabled)
-
-public:
- explicit QTableView(QWidget *parent = 0);
- ~QTableView();
-
- void setModel(QAbstractItemModel *model);
- void setRootIndex(const QModelIndex &index);
- void setSelectionModel(QItemSelectionModel *selectionModel);
- void doItemsLayout();
-
- QHeaderView *horizontalHeader() const;
- QHeaderView *verticalHeader() const;
- void setHorizontalHeader(QHeaderView *header);
- void setVerticalHeader(QHeaderView *header);
-
- int rowViewportPosition(int row) const;
- int rowAt(int y) const;
-
- void setRowHeight(int row, int height);
- int rowHeight(int row) const;
-
- int columnViewportPosition(int column) const;
- int columnAt(int x) const;
-
- void setColumnWidth(int column, int width);
- int columnWidth(int column) const;
-
- bool isRowHidden(int row) const;
- void setRowHidden(int row, bool hide);
-
- bool isColumnHidden(int column) const;
- void setColumnHidden(int column, bool hide);
-
- void setSortingEnabled(bool enable);
- bool isSortingEnabled() const;
-
- bool showGrid() const;
-
- Qt::PenStyle gridStyle() const;
- void setGridStyle(Qt::PenStyle style);
-
- void setWordWrap(bool on);
- bool wordWrap() const;
-
- void setCornerButtonEnabled(bool enable);
- bool isCornerButtonEnabled() const;
-
- QRect visualRect(const QModelIndex &index) const;
- void scrollTo(const QModelIndex &index, ScrollHint hint = EnsureVisible);
- QModelIndex indexAt(const QPoint &p) const;
-
- void setSpan(int row, int column, int rowSpan, int columnSpan);
- int rowSpan(int row, int column) const;
- int columnSpan(int row, int column) const;
- void clearSpans();
-
- void sortByColumn(int column, Qt::SortOrder order);
-
-public Q_SLOTS:
- void selectRow(int row);
- void selectColumn(int column);
- void hideRow(int row);
- void hideColumn(int column);
- void showRow(int row);
- void showColumn(int column);
- void resizeRowToContents(int row);
- void resizeRowsToContents();
- void resizeColumnToContents(int column);
- void resizeColumnsToContents();
- void sortByColumn(int column);
- void setShowGrid(bool show);
-
-protected Q_SLOTS:
- void rowMoved(int row, int oldIndex, int newIndex);
- void columnMoved(int column, int oldIndex, int newIndex);
- void rowResized(int row, int oldHeight, int newHeight);
- void columnResized(int column, int oldWidth, int newWidth);
- void rowCountChanged(int oldCount, int newCount);
- void columnCountChanged(int oldCount, int newCount);
-
-protected:
- QTableView(QTableViewPrivate &, QWidget *parent);
- void scrollContentsBy(int dx, int dy);
-
- QStyleOptionViewItem viewOptions() const;
- void paintEvent(QPaintEvent *e);
-
- void timerEvent(QTimerEvent *event);
-
- int horizontalOffset() const;
- int verticalOffset() const;
- QModelIndex moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers);
-
- void setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags command);
- QRegion visualRegionForSelection(const QItemSelection &selection) const;
- QModelIndexList selectedIndexes() const;
-
- void updateGeometries();
-
- int sizeHintForRow(int row) const;
- int sizeHintForColumn(int column) const;
-
- void verticalScrollbarAction(int action);
- void horizontalScrollbarAction(int action);
-
- bool isIndexHidden(const QModelIndex &index) const;
-
- void selectionChanged(const QItemSelection &selected,
- const QItemSelection &deselected);
- void currentChanged(const QModelIndex &current,
- const QModelIndex &previous);
-
-private:
- friend class QAccessibleItemView;
- int visualIndex(const QModelIndex &index) const;
-
- Q_DECLARE_PRIVATE(QTableView)
- Q_DISABLE_COPY(QTableView)
- Q_PRIVATE_SLOT(d_func(), void _q_selectRow(int))
- Q_PRIVATE_SLOT(d_func(), void _q_selectColumn(int))
- Q_PRIVATE_SLOT(d_func(), void _q_updateSpanInsertedRows(QModelIndex,int,int))
- Q_PRIVATE_SLOT(d_func(), void _q_updateSpanInsertedColumns(QModelIndex,int,int))
- Q_PRIVATE_SLOT(d_func(), void _q_updateSpanRemovedRows(QModelIndex,int,int))
- Q_PRIVATE_SLOT(d_func(), void _q_updateSpanRemovedColumns(QModelIndex,int,int))
-};
-
-#endif // QT_NO_TABLEVIEW
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QTABLEVIEW_H
diff --git a/src/gui/itemviews/qtablewidget.h b/src/gui/itemviews/qtablewidget.h
deleted file mode 100644
index 30b9348535..0000000000
--- a/src/gui/itemviews/qtablewidget.h
+++ /dev/null
@@ -1,377 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QTABLEWIDGET_H
-#define QTABLEWIDGET_H
-
-#include <QtGui/qtableview.h>
-#include <QtCore/qvariant.h>
-#include <QtCore/qvector.h>
-//#include <QtGui/qitemselectionmodel.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_TABLEWIDGET
-
-class Q_GUI_EXPORT QTableWidgetSelectionRange
-{
-public:
- QTableWidgetSelectionRange();
- QTableWidgetSelectionRange(int top, int left, int bottom, int right);
- QTableWidgetSelectionRange(const QTableWidgetSelectionRange &other);
- ~QTableWidgetSelectionRange();
-
- inline int topRow() const { return top; }
- inline int bottomRow() const { return bottom; }
- inline int leftColumn() const { return left; }
- inline int rightColumn() const { return right; }
- inline int rowCount() const { return bottom - top + 1; }
- inline int columnCount() const { return right - left + 1; }
-
-private:
- int top, left, bottom, right;
-};
-
-class QTableWidget;
-class QTableModel;
-class QWidgetItemData;
-class QTableWidgetItemPrivate;
-
-class Q_GUI_EXPORT QTableWidgetItem
-{
- friend class QTableWidget;
- friend class QTableModel;
-public:
- enum ItemType { Type = 0, UserType = 1000 };
- QTableWidgetItem(int type = Type);
- explicit QTableWidgetItem(const QString &text, int type = Type);
- explicit QTableWidgetItem(const QIcon &icon, const QString &text, int type = Type);
- QTableWidgetItem(const QTableWidgetItem &other);
- virtual ~QTableWidgetItem();
-
- virtual QTableWidgetItem *clone() const;
-
- inline QTableWidget *tableWidget() const { return view; }
-
- inline int row() const;
- inline int column() const;
-
- inline void setSelected(bool select);
- inline bool isSelected() const;
-
- inline Qt::ItemFlags flags() const { return itemFlags; }
- void setFlags(Qt::ItemFlags flags);
-
- inline QString text() const
- { return data(Qt::DisplayRole).toString(); }
- inline void setText(const QString &text);
-
- inline QIcon icon() const
- { return qvariant_cast<QIcon>(data(Qt::DecorationRole)); }
- inline void setIcon(const QIcon &icon);
-
- inline QString statusTip() const
- { return data(Qt::StatusTipRole).toString(); }
- inline void setStatusTip(const QString &statusTip);
-
-#ifndef QT_NO_TOOLTIP
- inline QString toolTip() const
- { return data(Qt::ToolTipRole).toString(); }
- inline void setToolTip(const QString &toolTip);
-#endif
-
-#ifndef QT_NO_WHATSTHIS
- inline QString whatsThis() const
- { return data(Qt::WhatsThisRole).toString(); }
- inline void setWhatsThis(const QString &whatsThis);
-#endif
-
- inline QFont font() const
- { return qvariant_cast<QFont>(data(Qt::FontRole)); }
- inline void setFont(const QFont &font);
-
- inline int textAlignment() const
- { return data(Qt::TextAlignmentRole).toInt(); }
- inline void setTextAlignment(int alignment)
- { setData(Qt::TextAlignmentRole, alignment); }
-
- inline QColor backgroundColor() const
- { return qvariant_cast<QColor>(data(Qt::BackgroundColorRole)); }
- inline void setBackgroundColor(const QColor &color)
- { setData(Qt::BackgroundColorRole, color); }
-
- inline QBrush background() const
- { return qvariant_cast<QBrush>(data(Qt::BackgroundRole)); }
- inline void setBackground(const QBrush &brush)
- { setData(Qt::BackgroundRole, brush); }
-
- inline QColor textColor() const
- { return qvariant_cast<QColor>(data(Qt::TextColorRole)); }
- inline void setTextColor(const QColor &color)
- { setData(Qt::TextColorRole, color); }
-
- inline QBrush foreground() const
- { return qvariant_cast<QBrush>(data(Qt::ForegroundRole)); }
- inline void setForeground(const QBrush &brush)
- { setData(Qt::ForegroundRole, brush); }
-
- inline Qt::CheckState checkState() const
- { return static_cast<Qt::CheckState>(data(Qt::CheckStateRole).toInt()); }
- inline void setCheckState(Qt::CheckState state)
- { setData(Qt::CheckStateRole, state); }
-
- inline QSize sizeHint() const
- { return qvariant_cast<QSize>(data(Qt::SizeHintRole)); }
- inline void setSizeHint(const QSize &size)
- { setData(Qt::SizeHintRole, size); }
-
- virtual QVariant data(int role) const;
- virtual void setData(int role, const QVariant &value);
-
- virtual bool operator<(const QTableWidgetItem &other) const;
-
-#ifndef QT_NO_DATASTREAM
- virtual void read(QDataStream &in);
- virtual void write(QDataStream &out) const;
-#endif
- QTableWidgetItem &operator=(const QTableWidgetItem &other);
-
- inline int type() const { return rtti; }
-
-private:
- int rtti;
- QVector<QWidgetItemData> values;
- QTableWidget *view;
- QTableWidgetItemPrivate *d;
- Qt::ItemFlags itemFlags;
-};
-
-inline void QTableWidgetItem::setText(const QString &atext)
-{ setData(Qt::DisplayRole, atext); }
-
-inline void QTableWidgetItem::setIcon(const QIcon &aicon)
-{ setData(Qt::DecorationRole, aicon); }
-
-inline void QTableWidgetItem::setStatusTip(const QString &astatusTip)
-{ setData(Qt::StatusTipRole, astatusTip); }
-
-#ifndef QT_NO_TOOLTIP
-inline void QTableWidgetItem::setToolTip(const QString &atoolTip)
-{ setData(Qt::ToolTipRole, atoolTip); }
-#endif
-
-#ifndef QT_NO_WHATSTHIS
-inline void QTableWidgetItem::setWhatsThis(const QString &awhatsThis)
-{ setData(Qt::WhatsThisRole, awhatsThis); }
-#endif
-
-inline void QTableWidgetItem::setFont(const QFont &afont)
-{ setData(Qt::FontRole, afont); }
-
-#ifndef QT_NO_DATASTREAM
-Q_GUI_EXPORT QDataStream &operator>>(QDataStream &in, QTableWidgetItem &item);
-Q_GUI_EXPORT QDataStream &operator<<(QDataStream &out, const QTableWidgetItem &item);
-#endif
-
-class QTableWidgetPrivate;
-
-class Q_GUI_EXPORT QTableWidget : public QTableView
-{
- Q_OBJECT
- Q_PROPERTY(int rowCount READ rowCount WRITE setRowCount)
- Q_PROPERTY(int columnCount READ columnCount WRITE setColumnCount)
-
- friend class QTableModel;
-public:
- explicit QTableWidget(QWidget *parent = 0);
- QTableWidget(int rows, int columns, QWidget *parent = 0);
- ~QTableWidget();
-
- void setRowCount(int rows);
- int rowCount() const;
-
- void setColumnCount(int columns);
- int columnCount() const;
-
- int row(const QTableWidgetItem *item) const;
- int column(const QTableWidgetItem *item) const;
-
- QTableWidgetItem *item(int row, int column) const;
- void setItem(int row, int column, QTableWidgetItem *item);
- QTableWidgetItem *takeItem(int row, int column);
-
- QTableWidgetItem *verticalHeaderItem(int row) const;
- void setVerticalHeaderItem(int row, QTableWidgetItem *item);
- QTableWidgetItem *takeVerticalHeaderItem(int row);
-
- QTableWidgetItem *horizontalHeaderItem(int column) const;
- void setHorizontalHeaderItem(int column, QTableWidgetItem *item);
- QTableWidgetItem *takeHorizontalHeaderItem(int column);
- void setVerticalHeaderLabels(const QStringList &labels);
- void setHorizontalHeaderLabels(const QStringList &labels);
-
- int currentRow() const;
- int currentColumn() const;
- QTableWidgetItem *currentItem() const;
- void setCurrentItem(QTableWidgetItem *item);
- void setCurrentItem(QTableWidgetItem *item, QItemSelectionModel::SelectionFlags command);
- void setCurrentCell(int row, int column);
- void setCurrentCell(int row, int column, QItemSelectionModel::SelectionFlags command);
-
- void sortItems(int column, Qt::SortOrder order = Qt::AscendingOrder);
- void setSortingEnabled(bool enable);
- bool isSortingEnabled() const;
-
- void editItem(QTableWidgetItem *item);
- void openPersistentEditor(QTableWidgetItem *item);
- void closePersistentEditor(QTableWidgetItem *item);
-
- QWidget *cellWidget(int row, int column) const;
- void setCellWidget(int row, int column, QWidget *widget);
- inline void removeCellWidget(int row, int column);
-
- bool isItemSelected(const QTableWidgetItem *item) const;
- void setItemSelected(const QTableWidgetItem *item, bool select);
- void setRangeSelected(const QTableWidgetSelectionRange &range, bool select);
-
- QList<QTableWidgetSelectionRange> selectedRanges() const;
- QList<QTableWidgetItem*> selectedItems();
- QList<QTableWidgetItem*> findItems(const QString &text, Qt::MatchFlags flags) const;
-
- int visualRow(int logicalRow) const;
- int visualColumn(int logicalColumn) const;
-
- QTableWidgetItem *itemAt(const QPoint &p) const;
- inline QTableWidgetItem *itemAt(int x, int y) const;
- QRect visualItemRect(const QTableWidgetItem *item) const;
-
- const QTableWidgetItem *itemPrototype() const;
- void setItemPrototype(const QTableWidgetItem *item);
-
-public Q_SLOTS:
- void scrollToItem(const QTableWidgetItem *item, QAbstractItemView::ScrollHint hint = EnsureVisible);
- void insertRow(int row);
- void insertColumn(int column);
- void removeRow(int row);
- void removeColumn(int column);
- void clear();
- void clearContents();
-
-Q_SIGNALS:
- void itemPressed(QTableWidgetItem *item);
- void itemClicked(QTableWidgetItem *item);
- void itemDoubleClicked(QTableWidgetItem *item);
-
- void itemActivated(QTableWidgetItem *item);
- void itemEntered(QTableWidgetItem *item);
- void itemChanged(QTableWidgetItem *item);
-
- void currentItemChanged(QTableWidgetItem *current, QTableWidgetItem *previous);
- void itemSelectionChanged();
-
- void cellPressed(int row, int column);
- void cellClicked(int row, int column);
- void cellDoubleClicked(int row, int column);
-
- void cellActivated(int row, int column);
- void cellEntered(int row, int column);
- void cellChanged(int row, int column);
-
- void currentCellChanged(int currentRow, int currentColumn, int previousRow, int previousColumn);
-
-protected:
- bool event(QEvent *e);
- virtual QStringList mimeTypes() const;
- virtual QMimeData *mimeData(const QList<QTableWidgetItem*> items) const;
- virtual bool dropMimeData(int row, int column, const QMimeData *data, Qt::DropAction action);
- virtual Qt::DropActions supportedDropActions() const;
- QList<QTableWidgetItem*> items(const QMimeData *data) const;
-
- QModelIndex indexFromItem(QTableWidgetItem *item) const;
- QTableWidgetItem *itemFromIndex(const QModelIndex &index) const;
- void dropEvent(QDropEvent *event);
-
-private:
- void setModel(QAbstractItemModel *model);
-
- Q_DECLARE_PRIVATE(QTableWidget)
- Q_DISABLE_COPY(QTableWidget)
-
- Q_PRIVATE_SLOT(d_func(), void _q_emitItemPressed(const QModelIndex &index))
- Q_PRIVATE_SLOT(d_func(), void _q_emitItemClicked(const QModelIndex &index))
- Q_PRIVATE_SLOT(d_func(), void _q_emitItemDoubleClicked(const QModelIndex &index))
- Q_PRIVATE_SLOT(d_func(), void _q_emitItemActivated(const QModelIndex &index))
- Q_PRIVATE_SLOT(d_func(), void _q_emitItemEntered(const QModelIndex &index))
- Q_PRIVATE_SLOT(d_func(), void _q_emitItemChanged(const QModelIndex &index))
- Q_PRIVATE_SLOT(d_func(), void _q_emitCurrentItemChanged(const QModelIndex &previous, const QModelIndex &current))
- Q_PRIVATE_SLOT(d_func(), void _q_sort())
- Q_PRIVATE_SLOT(d_func(), void _q_dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight))
-};
-
-inline void QTableWidget::removeCellWidget(int arow, int acolumn)
-{ setCellWidget(arow, acolumn, 0); }
-
-inline QTableWidgetItem *QTableWidget::itemAt(int ax, int ay) const
-{ return itemAt(QPoint(ax, ay)); }
-
-inline int QTableWidgetItem::row() const
-{ return (view ? view->row(this) : -1); }
-
-inline int QTableWidgetItem::column() const
-{ return (view ? view->column(this) : -1); }
-
-inline void QTableWidgetItem::setSelected(bool aselect)
-{ if (view) view->setItemSelected(this, aselect); }
-
-inline bool QTableWidgetItem::isSelected() const
-{ return (view ? view->isItemSelected(this) : false); }
-
-#endif // QT_NO_TABLEWIDGET
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QTABLEWIDGET_H
diff --git a/src/gui/itemviews/qtreeview.h b/src/gui/itemviews/qtreeview.h
deleted file mode 100644
index b77da4e89a..0000000000
--- a/src/gui/itemviews/qtreeview.h
+++ /dev/null
@@ -1,242 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QTREEVIEW_H
-#define QTREEVIEW_H
-
-#include <QtGui/qabstractitemview.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_TREEVIEW
-
-class QTreeViewPrivate;
-class QHeaderView;
-
-class Q_GUI_EXPORT QTreeView : public QAbstractItemView
-{
- Q_OBJECT
- Q_PROPERTY(int autoExpandDelay READ autoExpandDelay WRITE setAutoExpandDelay)
- Q_PROPERTY(int indentation READ indentation WRITE setIndentation)
- Q_PROPERTY(bool rootIsDecorated READ rootIsDecorated WRITE setRootIsDecorated)
- Q_PROPERTY(bool uniformRowHeights READ uniformRowHeights WRITE setUniformRowHeights)
- Q_PROPERTY(bool itemsExpandable READ itemsExpandable WRITE setItemsExpandable)
- Q_PROPERTY(bool sortingEnabled READ isSortingEnabled WRITE setSortingEnabled)
- Q_PROPERTY(bool animated READ isAnimated WRITE setAnimated)
- Q_PROPERTY(bool allColumnsShowFocus READ allColumnsShowFocus WRITE setAllColumnsShowFocus)
- Q_PROPERTY(bool wordWrap READ wordWrap WRITE setWordWrap)
- Q_PROPERTY(bool headerHidden READ isHeaderHidden WRITE setHeaderHidden)
- Q_PROPERTY(bool expandsOnDoubleClick READ expandsOnDoubleClick WRITE setExpandsOnDoubleClick)
-
-public:
- explicit QTreeView(QWidget *parent = 0);
- ~QTreeView();
-
- void setModel(QAbstractItemModel *model);
- void setRootIndex(const QModelIndex &index);
- void setSelectionModel(QItemSelectionModel *selectionModel);
-
- QHeaderView *header() const;
- void setHeader(QHeaderView *header);
-
- int autoExpandDelay() const;
- void setAutoExpandDelay(int delay);
-
- int indentation() const;
- void setIndentation(int i);
-
- bool rootIsDecorated() const;
- void setRootIsDecorated(bool show);
-
- bool uniformRowHeights() const;
- void setUniformRowHeights(bool uniform);
-
- bool itemsExpandable() const;
- void setItemsExpandable(bool enable);
-
- bool expandsOnDoubleClick() const;
- void setExpandsOnDoubleClick(bool enable);
-
- int columnViewportPosition(int column) const;
- int columnWidth(int column) const;
- void setColumnWidth(int column, int width);
- int columnAt(int x) const;
-
- bool isColumnHidden(int column) const;
- void setColumnHidden(int column, bool hide);
-
- bool isHeaderHidden() const;
- void setHeaderHidden(bool hide);
-
- bool isRowHidden(int row, const QModelIndex &parent) const;
- void setRowHidden(int row, const QModelIndex &parent, bool hide);
-
- bool isFirstColumnSpanned(int row, const QModelIndex &parent) const;
- void setFirstColumnSpanned(int row, const QModelIndex &parent, bool span);
-
- bool isExpanded(const QModelIndex &index) const;
- void setExpanded(const QModelIndex &index, bool expand);
-
- void setSortingEnabled(bool enable);
- bool isSortingEnabled() const;
-
- void setAnimated(bool enable);
- bool isAnimated() const;
-
- void setAllColumnsShowFocus(bool enable);
- bool allColumnsShowFocus() const;
-
- void setWordWrap(bool on);
- bool wordWrap() const;
-
- void keyboardSearch(const QString &search);
-
- QRect visualRect(const QModelIndex &index) const;
- void scrollTo(const QModelIndex &index, ScrollHint hint = EnsureVisible);
- QModelIndex indexAt(const QPoint &p) const;
- QModelIndex indexAbove(const QModelIndex &index) const;
- QModelIndex indexBelow(const QModelIndex &index) const;
-
- void doItemsLayout();
- void reset();
-
- void sortByColumn(int column, Qt::SortOrder order);
-
- void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
- void selectAll();
-
-Q_SIGNALS:
- void expanded(const QModelIndex &index);
- void collapsed(const QModelIndex &index);
-
-public Q_SLOTS:
- void hideColumn(int column);
- void showColumn(int column);
- void expand(const QModelIndex &index);
- void collapse(const QModelIndex &index);
- void resizeColumnToContents(int column);
- void sortByColumn(int column);
- void expandAll();
- void collapseAll();
- void expandToDepth(int depth);
-
-protected Q_SLOTS:
- void columnResized(int column, int oldSize, int newSize);
- void columnCountChanged(int oldCount, int newCount);
- void columnMoved();
- void reexpand();
- void rowsRemoved(const QModelIndex &parent, int first, int last);
-
-protected:
- QTreeView(QTreeViewPrivate &dd, QWidget *parent = 0);
- void scrollContentsBy(int dx, int dy);
- void rowsInserted(const QModelIndex &parent, int start, int end);
- void rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end);
-
- QModelIndex moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers);
- int horizontalOffset() const;
- int verticalOffset() const;
-
- void setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags command);
- QRegion visualRegionForSelection(const QItemSelection &selection) const;
- QModelIndexList selectedIndexes() const;
-
- void timerEvent(QTimerEvent *event);
- void paintEvent(QPaintEvent *event);
-
- void drawTree(QPainter *painter, const QRegion &region) const;
- virtual void drawRow(QPainter *painter,
- const QStyleOptionViewItem &options,
- const QModelIndex &index) const;
- virtual void drawBranches(QPainter *painter,
- const QRect &rect,
- const QModelIndex &index) const;
-
- void mousePressEvent(QMouseEvent *event);
- void mouseReleaseEvent(QMouseEvent *event);
- void mouseDoubleClickEvent(QMouseEvent *event);
- void mouseMoveEvent(QMouseEvent *event);
- void keyPressEvent(QKeyEvent *event);
-#ifndef QT_NO_DRAGANDDROP
- void dragMoveEvent(QDragMoveEvent *event);
-#endif
- bool viewportEvent(QEvent *event);
-
- void updateGeometries();
-
- int sizeHintForColumn(int column) const;
- int indexRowSizeHint(const QModelIndex &index) const;
- int rowHeight(const QModelIndex &index) const;
-
- void horizontalScrollbarAction(int action);
-
- bool isIndexHidden(const QModelIndex &index) const;
- void selectionChanged(const QItemSelection &selected,
- const QItemSelection &deselected);
- void currentChanged(const QModelIndex &current, const QModelIndex &previous);
-
-private:
- friend class QAccessibleItemView;
- friend class QAccessibleTable2;
- friend class QAccessibleTree;
- friend class QAccessibleTable2Cell;
- int visualIndex(const QModelIndex &index) const;
-
- Q_DECLARE_PRIVATE(QTreeView)
- Q_DISABLE_COPY(QTreeView)
-#ifndef QT_NO_ANIMATION
- Q_PRIVATE_SLOT(d_func(), void _q_endAnimatedOperation())
-#endif //QT_NO_ANIMATION
- Q_PRIVATE_SLOT(d_func(), void _q_modelAboutToBeReset())
- Q_PRIVATE_SLOT(d_func(), void _q_sortIndicatorChanged(int column, Qt::SortOrder order))
-};
-
-#endif // QT_NO_TREEVIEW
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QTREEVIEW_H
diff --git a/src/gui/itemviews/qtreeview_p.h b/src/gui/itemviews/qtreeview_p.h
deleted file mode 100644
index a9dc452398..0000000000
--- a/src/gui/itemviews/qtreeview_p.h
+++ /dev/null
@@ -1,255 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QTREEVIEW_P_H
-#define QTREEVIEW_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "private/qabstractitemview_p.h"
-#include <QtCore/qvariantanimation.h>
-#include <QtCore/qabstractitemmodel.h>
-
-#ifndef QT_NO_TREEVIEW
-
-QT_BEGIN_NAMESPACE
-
-struct QTreeViewItem
-{
- QTreeViewItem() : parentItem(-1), expanded(false), spanning(false), hasChildren(false),
- hasMoreSiblings(false), total(0), level(0), height(0) {}
- QModelIndex index; // we remove items whenever the indexes are invalidated
- int parentItem; // parent item index in viewItems
- uint expanded : 1;
- uint spanning : 1;
- uint hasChildren : 1; // if the item has visible children (even if collapsed)
- uint hasMoreSiblings : 1;
- uint total : 28; // total number of children visible
- uint level : 16; // indentation
- int height : 16; // row height
-};
-
-Q_DECLARE_TYPEINFO(QTreeViewItem, Q_MOVABLE_TYPE);
-
-class Q_GUI_EXPORT QTreeViewPrivate : public QAbstractItemViewPrivate
-{
- Q_DECLARE_PUBLIC(QTreeView)
-public:
-
- QTreeViewPrivate()
- : QAbstractItemViewPrivate(),
- header(0), indent(20), lastViewedItem(0), defaultItemHeight(-1),
- uniformRowHeights(false), rootDecoration(true),
- itemsExpandable(true), sortingEnabled(false),
- expandsOnDoubleClick(true),
- allColumnsShowFocus(false), current(0), spanning(false),
- animationsEnabled(false), columnResizeTimerID(0),
- autoExpandDelay(-1), hoverBranch(-1), geometryRecursionBlock(false), hasRemovedItems(false) {}
-
- ~QTreeViewPrivate() {}
- void initialize();
-
- QItemViewPaintPairs draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const;
-
-#ifndef QT_NO_ANIMATION
- struct AnimatedOperation : public QVariantAnimation
- {
- int item;
- QPixmap before;
- QPixmap after;
- QWidget *viewport;
- AnimatedOperation() : item(0) { setEasingCurve(QEasingCurve::InOutQuad); }
- int top() const { return startValue().toInt(); }
- QRect rect() const { QRect rect = viewport->rect(); rect.moveTop(top()); return rect; }
- void updateCurrentValue(const QVariant &) { viewport->update(rect()); }
- void updateState(State state, State) { if (state == Stopped) before = after = QPixmap(); }
- } animatedOperation;
- void prepareAnimatedOperation(int item, QVariantAnimation::Direction d);
- void beginAnimatedOperation();
- void drawAnimatedOperation(QPainter *painter) const;
- QPixmap renderTreeToPixmapForAnimation(const QRect &rect) const;
- void _q_endAnimatedOperation();
-#endif //QT_NO_ANIMATION
-
- void expand(int item, bool emitSignal);
- void collapse(int item, bool emitSignal);
-
- void _q_columnsAboutToBeRemoved(const QModelIndex &, int, int);
- void _q_columnsRemoved(const QModelIndex &, int, int);
- void _q_modelAboutToBeReset();
- void _q_sortIndicatorChanged(int column, Qt::SortOrder order);
- void _q_modelDestroyed();
-
- void layout(int item, bool recusiveExpanding = false, bool afterIsUninitialized = false);
-
- int pageUp(int item) const;
- int pageDown(int item) const;
-
- int itemHeight(int item) const;
- int indentationForItem(int item) const;
- int coordinateForItem(int item) const;
- int itemAtCoordinate(int coordinate) const;
-
- int viewIndex(const QModelIndex &index) const;
- QModelIndex modelIndex(int i, int column = 0) const;
-
- void insertViewItems(int pos, int count, const QTreeViewItem &viewItem);
- void removeViewItems(int pos, int count);
-#if 0
- bool checkViewItems() const;
-#endif
-
- int firstVisibleItem(int *offset = 0) const;
- int columnAt(int x) const;
- bool hasVisibleChildren( const QModelIndex& parent) const;
-
- bool expandOrCollapseItemAtPos(const QPoint &pos);
-
- void updateScrollBars();
-
- int itemDecorationAt(const QPoint &pos) const;
- QRect itemDecorationRect(const QModelIndex &index) const;
-
-
- QList<QPair<int, int> > columnRanges(const QModelIndex &topIndex, const QModelIndex &bottomIndex) const;
- void select(const QModelIndex &start, const QModelIndex &stop, QItemSelectionModel::SelectionFlags command);
-
- QPair<int,int> startAndEndColumns(const QRect &rect) const;
-
- void updateChildCount(const int parentItem, const int delta);
-
- void paintAlternatingRowColors(QPainter *painter, QStyleOptionViewItemV4 *option, int y, int bottom) const;
-
- QHeaderView *header;
- int indent;
-
- mutable QVector<QTreeViewItem> viewItems;
- mutable int lastViewedItem;
- int defaultItemHeight; // this is just a number; contentsHeight() / numItems
- bool uniformRowHeights; // used when all rows have the same height
- bool rootDecoration;
- bool itemsExpandable;
- bool sortingEnabled;
- bool expandsOnDoubleClick;
- bool allColumnsShowFocus;
-
- // used for drawing
- mutable QPair<int,int> leftAndRight;
- mutable int current;
- mutable bool spanning;
-
- // used when expanding and collapsing items
- QSet<QPersistentModelIndex> expandedIndexes;
- bool animationsEnabled;
-
- inline bool storeExpanded(const QPersistentModelIndex &idx) {
- if (expandedIndexes.contains(idx))
- return false;
- expandedIndexes.insert(idx);
- return true;
- }
-
- inline bool isIndexExpanded(const QModelIndex &idx) const {
- //We first check if the idx is a QPersistentModelIndex, because creating QPersistentModelIndex is slow
- return isPersistent(idx) && expandedIndexes.contains(idx);
- }
-
- // used when hiding and showing items
- QSet<QPersistentModelIndex> hiddenIndexes;
-
- inline bool isRowHidden(const QModelIndex &idx) const {
- //We first check if the idx is a QPersistentModelIndex, because creating QPersistentModelIndex is slow
- return isPersistent(idx) && hiddenIndexes.contains(idx);
- }
-
- inline bool isItemHiddenOrDisabled(int i) const {
- if (i < 0 || i >= viewItems.count())
- return false;
- const QModelIndex index = viewItems.at(i).index;
- return isRowHidden(index) || !isIndexEnabled(index);
- }
-
- inline int above(int item) const
- { int i = item; while (isItemHiddenOrDisabled(--item)){} return item < 0 ? i : item; }
- inline int below(int item) const
- { int i = item; while (isItemHiddenOrDisabled(++item)){} return item >= viewItems.count() ? i : item; }
- inline void invalidateHeightCache(int item) const
- { viewItems[item].height = 0; }
-
- inline int accessibleTable2Index(const QModelIndex &index) const {
- return (viewIndex(index) + (header ? 1 : 0)) * model->columnCount()+index.column() + 1;
- }
-
- // used for spanning rows
- QVector<QPersistentModelIndex> spanningIndexes;
-
- // used for updating resized columns
- int columnResizeTimerID;
- QList<int> columnsToUpdate;
-
- // used for the automatic opening of nodes during DND
- int autoExpandDelay;
- QBasicTimer openTimer;
-
- // used for drawing hilighted expand/collapse indicators
- int hoverBranch;
-
- // used for blocking recursion when calling setViewportMargins from updateGeometries
- bool geometryRecursionBlock;
-
- // If we should clean the set
- bool hasRemovedItems;
-};
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_TREEVIEW
-
-#endif // QTREEVIEW_P_H
diff --git a/src/gui/itemviews/qtreewidget.h b/src/gui/itemviews/qtreewidget.h
deleted file mode 100644
index 5561ba9948..0000000000
--- a/src/gui/itemviews/qtreewidget.h
+++ /dev/null
@@ -1,432 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QTREEWIDGET_H
-#define QTREEWIDGET_H
-
-#include <QtGui/qtreeview.h>
-#include <QtGui/qtreewidgetitemiterator.h>
-#include <QtCore/qvariant.h>
-#include <QtCore/qvector.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_TREEWIDGET
-
-class QTreeWidget;
-class QTreeModel;
-class QWidgetItemData;
-class QTreeWidgetItemPrivate;
-
-class Q_GUI_EXPORT QTreeWidgetItem
-{
- friend class QTreeModel;
- friend class QTreeWidget;
- friend class QTreeWidgetPrivate;
- friend class QTreeWidgetItemIterator;
- friend class QTreeWidgetItemPrivate;
-public:
- enum ItemType { Type = 0, UserType = 1000 };
- explicit QTreeWidgetItem(int type = Type);
- QTreeWidgetItem(const QStringList &strings, int type = Type);
- explicit QTreeWidgetItem(QTreeWidget *view, int type = Type);
- QTreeWidgetItem(QTreeWidget *view, const QStringList &strings, int type = Type);
- QTreeWidgetItem(QTreeWidget *view, QTreeWidgetItem *after, int type = Type);
- explicit QTreeWidgetItem(QTreeWidgetItem *parent, int type = Type);
- QTreeWidgetItem(QTreeWidgetItem *parent, const QStringList &strings, int type = Type);
- QTreeWidgetItem(QTreeWidgetItem *parent, QTreeWidgetItem *after, int type = Type);
- QTreeWidgetItem(const QTreeWidgetItem &other);
- virtual ~QTreeWidgetItem();
-
- virtual QTreeWidgetItem *clone() const;
-
- inline QTreeWidget *treeWidget() const { return view; }
-
- inline void setSelected(bool select);
- inline bool isSelected() const;
-
- inline void setHidden(bool hide);
- inline bool isHidden() const;
-
- inline void setExpanded(bool expand);
- inline bool isExpanded() const;
-
- inline void setFirstColumnSpanned(bool span);
- inline bool isFirstColumnSpanned() const;
-
- inline void setDisabled(bool disabled);
- inline bool isDisabled() const;
-
- enum ChildIndicatorPolicy { ShowIndicator, DontShowIndicator, DontShowIndicatorWhenChildless };
- void setChildIndicatorPolicy(QTreeWidgetItem::ChildIndicatorPolicy policy);
- QTreeWidgetItem::ChildIndicatorPolicy childIndicatorPolicy() const;
-
- Qt::ItemFlags flags() const;
- void setFlags(Qt::ItemFlags flags);
-
- inline QString text(int column) const
- { return data(column, Qt::DisplayRole).toString(); }
- inline void setText(int column, const QString &text);
-
- inline QIcon icon(int column) const
- { return qvariant_cast<QIcon>(data(column, Qt::DecorationRole)); }
- inline void setIcon(int column, const QIcon &icon);
-
- inline QString statusTip(int column) const
- { return data(column, Qt::StatusTipRole).toString(); }
- inline void setStatusTip(int column, const QString &statusTip);
-
-#ifndef QT_NO_TOOLTIP
- inline QString toolTip(int column) const
- { return data(column, Qt::ToolTipRole).toString(); }
- inline void setToolTip(int column, const QString &toolTip);
-#endif
-
-#ifndef QT_NO_WHATSTHIS
- inline QString whatsThis(int column) const
- { return data(column, Qt::WhatsThisRole).toString(); }
- inline void setWhatsThis(int column, const QString &whatsThis);
-#endif
-
- inline QFont font(int column) const
- { return qvariant_cast<QFont>(data(column, Qt::FontRole)); }
- inline void setFont(int column, const QFont &font);
-
- inline int textAlignment(int column) const
- { return data(column, Qt::TextAlignmentRole).toInt(); }
- inline void setTextAlignment(int column, int alignment)
- { setData(column, Qt::TextAlignmentRole, alignment); }
-
- inline QColor backgroundColor(int column) const
- { return qvariant_cast<QColor>(data(column, Qt::BackgroundColorRole)); }
- inline void setBackgroundColor(int column, const QColor &color)
- { setData(column, Qt::BackgroundColorRole, color); }
-
- inline QBrush background(int column) const
- { return qvariant_cast<QBrush>(data(column, Qt::BackgroundRole)); }
- inline void setBackground(int column, const QBrush &brush)
- { setData(column, Qt::BackgroundRole, brush); }
-
- inline QColor textColor(int column) const
- { return qvariant_cast<QColor>(data(column, Qt::TextColorRole)); }
- inline void setTextColor(int column, const QColor &color)
- { setData(column, Qt::TextColorRole, color); }
-
- inline QBrush foreground(int column) const
- { return qvariant_cast<QBrush>(data(column, Qt::ForegroundRole)); }
- inline void setForeground(int column, const QBrush &brush)
- { setData(column, Qt::ForegroundRole, brush); }
-
- inline Qt::CheckState checkState(int column) const
- { return static_cast<Qt::CheckState>(data(column, Qt::CheckStateRole).toInt()); }
- inline void setCheckState(int column, Qt::CheckState state)
- { setData(column, Qt::CheckStateRole, state); }
-
- inline QSize sizeHint(int column) const
- { return qvariant_cast<QSize>(data(column, Qt::SizeHintRole)); }
- inline void setSizeHint(int column, const QSize &size)
- { setData(column, Qt::SizeHintRole, size); }
-
- virtual QVariant data(int column, int role) const;
- virtual void setData(int column, int role, const QVariant &value);
-
- virtual bool operator<(const QTreeWidgetItem &other) const;
-
-#ifndef QT_NO_DATASTREAM
- virtual void read(QDataStream &in);
- virtual void write(QDataStream &out) const;
-#endif
- QTreeWidgetItem &operator=(const QTreeWidgetItem &other);
-
- inline QTreeWidgetItem *parent() const { return par; }
- inline QTreeWidgetItem *child(int index) const {
- if (index < 0 || index >= children.size())
- return 0;
- executePendingSort();
- return children.at(index);
- }
- inline int childCount() const { return children.count(); }
- inline int columnCount() const { return values.count(); }
- inline int indexOfChild(QTreeWidgetItem *child) const;
-
- void addChild(QTreeWidgetItem *child);
- void insertChild(int index, QTreeWidgetItem *child);
- void removeChild(QTreeWidgetItem *child);
- QTreeWidgetItem *takeChild(int index);
-
- void addChildren(const QList<QTreeWidgetItem*> &children);
- void insertChildren(int index, const QList<QTreeWidgetItem*> &children);
- QList<QTreeWidgetItem*> takeChildren();
-
- inline int type() const { return rtti; }
- inline void sortChildren(int column, Qt::SortOrder order)
- { sortChildren(column, order, false); }
-
-protected:
- void emitDataChanged();
-
-private:
- void sortChildren(int column, Qt::SortOrder order, bool climb);
- QVariant childrenCheckState(int column) const;
- void itemChanged();
- void executePendingSort() const;
-
- int rtti;
- // One item has a vector of column entries. Each column has a vector of (role, value) pairs.
- QVector< QVector<QWidgetItemData> > values;
- QTreeWidget *view;
- QTreeWidgetItemPrivate *d;
- QTreeWidgetItem *par;
- QList<QTreeWidgetItem*> children;
- Qt::ItemFlags itemFlags;
-};
-
-inline void QTreeWidgetItem::setText(int column, const QString &atext)
-{ setData(column, Qt::DisplayRole, atext); }
-
-inline void QTreeWidgetItem::setIcon(int column, const QIcon &aicon)
-{ setData(column, Qt::DecorationRole, aicon); }
-
-#ifndef QT_NO_STATUSTIP
-inline void QTreeWidgetItem::setStatusTip(int column, const QString &astatusTip)
-{ setData(column, Qt::StatusTipRole, astatusTip); }
-#endif
-
-#ifndef QT_NO_TOOLTIP
-inline void QTreeWidgetItem::setToolTip(int column, const QString &atoolTip)
-{ setData(column, Qt::ToolTipRole, atoolTip); }
-#endif
-
-#ifndef QT_NO_WHATSTHIS
-inline void QTreeWidgetItem::setWhatsThis(int column, const QString &awhatsThis)
-{ setData(column, Qt::WhatsThisRole, awhatsThis); }
-#endif
-
-inline void QTreeWidgetItem::setFont(int column, const QFont &afont)
-{ setData(column, Qt::FontRole, afont); }
-
-inline int QTreeWidgetItem::indexOfChild(QTreeWidgetItem *achild) const
-{ executePendingSort(); return children.indexOf(achild); }
-
-#ifndef QT_NO_DATASTREAM
-Q_GUI_EXPORT QDataStream &operator<<(QDataStream &out, const QTreeWidgetItem &item);
-Q_GUI_EXPORT QDataStream &operator>>(QDataStream &in, QTreeWidgetItem &item);
-#endif
-
-class QTreeWidgetPrivate;
-
-class Q_GUI_EXPORT QTreeWidget : public QTreeView
-{
- Q_OBJECT
- Q_PROPERTY(int columnCount READ columnCount WRITE setColumnCount)
- Q_PROPERTY(int topLevelItemCount READ topLevelItemCount)
-
- friend class QTreeModel;
- friend class QTreeWidgetItem;
-public:
- explicit QTreeWidget(QWidget *parent = 0);
- ~QTreeWidget();
-
- int columnCount() const;
- void setColumnCount(int columns);
-
- QTreeWidgetItem *invisibleRootItem() const;
- QTreeWidgetItem *topLevelItem(int index) const;
- int topLevelItemCount() const;
- void insertTopLevelItem(int index, QTreeWidgetItem *item);
- void addTopLevelItem(QTreeWidgetItem *item);
- QTreeWidgetItem *takeTopLevelItem(int index);
- int indexOfTopLevelItem(QTreeWidgetItem *item); // ### Qt 5: remove me
- int indexOfTopLevelItem(QTreeWidgetItem *item) const;
-
- void insertTopLevelItems(int index, const QList<QTreeWidgetItem*> &items);
- void addTopLevelItems(const QList<QTreeWidgetItem*> &items);
-
- QTreeWidgetItem *headerItem() const;
- void setHeaderItem(QTreeWidgetItem *item);
- void setHeaderLabels(const QStringList &labels);
- inline void setHeaderLabel(const QString &label);
-
- QTreeWidgetItem *currentItem() const;
- int currentColumn() const;
- void setCurrentItem(QTreeWidgetItem *item);
- void setCurrentItem(QTreeWidgetItem *item, int column);
- void setCurrentItem(QTreeWidgetItem *item, int column, QItemSelectionModel::SelectionFlags command);
-
- QTreeWidgetItem *itemAt(const QPoint &p) const;
- inline QTreeWidgetItem *itemAt(int x, int y) const;
- QRect visualItemRect(const QTreeWidgetItem *item) const;
-
- int sortColumn() const;
- void sortItems(int column, Qt::SortOrder order);
- void setSortingEnabled(bool enable);
- bool isSortingEnabled() const;
-
- void editItem(QTreeWidgetItem *item, int column = 0);
- void openPersistentEditor(QTreeWidgetItem *item, int column = 0);
- void closePersistentEditor(QTreeWidgetItem *item, int column = 0);
-
- QWidget *itemWidget(QTreeWidgetItem *item, int column) const;
- void setItemWidget(QTreeWidgetItem *item, int column, QWidget *widget);
- inline void removeItemWidget(QTreeWidgetItem *item, int column);
-
- bool isItemSelected(const QTreeWidgetItem *item) const;
- void setItemSelected(const QTreeWidgetItem *item, bool select);
- QList<QTreeWidgetItem*> selectedItems() const;
- QList<QTreeWidgetItem*> findItems(const QString &text, Qt::MatchFlags flags,
- int column = 0) const;
-
- bool isItemHidden(const QTreeWidgetItem *item) const;
- void setItemHidden(const QTreeWidgetItem *item, bool hide);
-
- bool isItemExpanded(const QTreeWidgetItem *item) const;
- void setItemExpanded(const QTreeWidgetItem *item, bool expand);
-
- bool isFirstItemColumnSpanned(const QTreeWidgetItem *item) const;
- void setFirstItemColumnSpanned(const QTreeWidgetItem *item, bool span);
-
- QTreeWidgetItem *itemAbove(const QTreeWidgetItem *item) const;
- QTreeWidgetItem *itemBelow(const QTreeWidgetItem *item) const;
-
- void setSelectionModel(QItemSelectionModel *selectionModel);
-
-public Q_SLOTS:
- void scrollToItem(const QTreeWidgetItem *item,
- QAbstractItemView::ScrollHint hint = EnsureVisible);
- void expandItem(const QTreeWidgetItem *item);
- void collapseItem(const QTreeWidgetItem *item);
- void clear();
-
-Q_SIGNALS:
- void itemPressed(QTreeWidgetItem *item, int column);
- void itemClicked(QTreeWidgetItem *item, int column);
- void itemDoubleClicked(QTreeWidgetItem *item, int column);
- void itemActivated(QTreeWidgetItem *item, int column);
- void itemEntered(QTreeWidgetItem *item, int column);
- void itemChanged(QTreeWidgetItem *item, int column);
- void itemExpanded(QTreeWidgetItem *item);
- void itemCollapsed(QTreeWidgetItem *item);
- void currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous);
- void itemSelectionChanged();
-
-protected:
- bool event(QEvent *e);
- virtual QStringList mimeTypes() const;
- virtual QMimeData *mimeData(const QList<QTreeWidgetItem*> items) const;
- virtual bool dropMimeData(QTreeWidgetItem *parent, int index,
- const QMimeData *data, Qt::DropAction action);
- virtual Qt::DropActions supportedDropActions() const;
- QList<QTreeWidgetItem*> items(const QMimeData *data) const;
-
- QModelIndex indexFromItem(QTreeWidgetItem *item, int column = 0) const;
- QTreeWidgetItem *itemFromIndex(const QModelIndex &index) const;
- void dropEvent(QDropEvent *event);
-
-private:
- void setModel(QAbstractItemModel *model);
-
- Q_DECLARE_PRIVATE(QTreeWidget)
- Q_DISABLE_COPY(QTreeWidget)
-
- Q_PRIVATE_SLOT(d_func(), void _q_emitItemPressed(const QModelIndex &index))
- Q_PRIVATE_SLOT(d_func(), void _q_emitItemClicked(const QModelIndex &index))
- Q_PRIVATE_SLOT(d_func(), void _q_emitItemDoubleClicked(const QModelIndex &index))
- Q_PRIVATE_SLOT(d_func(), void _q_emitItemActivated(const QModelIndex &index))
- Q_PRIVATE_SLOT(d_func(), void _q_emitItemEntered(const QModelIndex &index))
- Q_PRIVATE_SLOT(d_func(), void _q_emitItemChanged(const QModelIndex &index))
- Q_PRIVATE_SLOT(d_func(), void _q_emitItemExpanded(const QModelIndex &index))
- Q_PRIVATE_SLOT(d_func(), void _q_emitItemCollapsed(const QModelIndex &index))
- Q_PRIVATE_SLOT(d_func(), void _q_emitCurrentItemChanged(const QModelIndex &previous, const QModelIndex &current))
- Q_PRIVATE_SLOT(d_func(), void _q_sort())
- Q_PRIVATE_SLOT(d_func(), void _q_dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight))
- Q_PRIVATE_SLOT(d_func(), void _q_selectionChanged(const QItemSelection &selected, const QItemSelection &deselected))
-};
-
-inline void QTreeWidget::removeItemWidget(QTreeWidgetItem *item, int column)
-{ setItemWidget(item, column, 0); }
-
-inline QTreeWidgetItem *QTreeWidget::itemAt(int ax, int ay) const
-{ return itemAt(QPoint(ax, ay)); }
-
-inline void QTreeWidget::setHeaderLabel(const QString &alabel)
-{ setHeaderLabels(QStringList(alabel)); }
-
-inline void QTreeWidgetItem::setSelected(bool aselect)
-{ if (view) view->setItemSelected(this, aselect); }
-
-inline bool QTreeWidgetItem::isSelected() const
-{ return (view ? view->isItemSelected(this) : false); }
-
-inline void QTreeWidgetItem::setHidden(bool ahide)
-{ if (view) view->setItemHidden(this, ahide); }
-
-inline bool QTreeWidgetItem::isHidden() const
-{ return (view ? view->isItemHidden(this) : false); }
-
-inline void QTreeWidgetItem::setExpanded(bool aexpand)
-{ if (view) view->setItemExpanded(this, aexpand); }
-
-inline bool QTreeWidgetItem::isExpanded() const
-{ return (view ? view->isItemExpanded(this) : false); }
-
-inline void QTreeWidgetItem::setFirstColumnSpanned(bool aspan)
-{ if (view) view->setFirstItemColumnSpanned(this, aspan); }
-
-inline bool QTreeWidgetItem::isFirstColumnSpanned() const
-{ return (view ? view->isFirstItemColumnSpanned(this) : false); }
-
-inline void QTreeWidgetItem::setDisabled(bool disabled)
-{ setFlags(disabled ? (flags() & ~Qt::ItemIsEnabled) : flags() | Qt::ItemIsEnabled); }
-
-inline bool QTreeWidgetItem::isDisabled() const
-{ return !(flags() & Qt::ItemIsEnabled); }
-
-#endif // QT_NO_TREEWIDGET
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QTREEWIDGET_H
diff --git a/src/gui/itemviews/qtreewidget_p.h b/src/gui/itemviews/qtreewidget_p.h
deleted file mode 100644
index 8386f03f6e..0000000000
--- a/src/gui/itemviews/qtreewidget_p.h
+++ /dev/null
@@ -1,248 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QTREEWIDGET_P_H
-#define QTREEWIDGET_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. This header file may change
-// from version to version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/qabstractitemmodel.h>
-#include <private/qabstractitemmodel_p.h>
-#include <QtCore/qpair.h>
-#include <QtCore/qbasictimer.h>
-#include <QtGui/qtreewidget.h>
-#include <private/qtreeview_p.h>
-#include <QtGui/qheaderview.h>
-
-#ifndef QT_NO_TREEWIDGET
-
-QT_BEGIN_NAMESPACE
-
-class QTreeWidgetItem;
-class QTreeWidgetItemIterator;
-class QTreeModelPrivate;
-
-class QTreeModel : public QAbstractItemModel
-{
- Q_OBJECT
- friend class QTreeWidget;
- friend class QTreeWidgetPrivate;
- friend class QTreeWidgetItem;
- friend class QTreeWidgetItemPrivate;
- friend class QTreeWidgetItemIterator;
- friend class QTreeWidgetItemIteratorPrivate;
-
-public:
- explicit QTreeModel(int columns = 0, QTreeWidget *parent = 0);
- ~QTreeModel();
-
- inline QTreeWidget *view() const
- { return qobject_cast<QTreeWidget*>(QObject::parent()); }
-
- void clear();
- void setColumnCount(int columns);
-
- QTreeWidgetItem *item(const QModelIndex &index) const;
- void itemChanged(QTreeWidgetItem *item);
-
- QModelIndex index(const QTreeWidgetItem *item, int column) const;
- QModelIndex index(int row, int column, const QModelIndex &parent) const;
- QModelIndex parent(const QModelIndex &child) const;
- int rowCount(const QModelIndex &parent) const;
- int columnCount(const QModelIndex &parent = QModelIndex()) const;
- bool hasChildren(const QModelIndex &parent) const;
-
- QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
- bool setData(const QModelIndex &index, const QVariant &value, int role);
-
- QMap<int, QVariant> itemData(const QModelIndex &index) const;
-
- QVariant headerData(int section, Qt::Orientation orientation, int role) const;
- bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value,
- int role);
-
- Qt::ItemFlags flags(const QModelIndex &index) const;
-
- void sort(int column, Qt::SortOrder order);
- void ensureSorted(int column, Qt::SortOrder order,
- int start, int end, const QModelIndex &parent);
- static bool itemLessThan(const QPair<QTreeWidgetItem*,int> &left,
- const QPair<QTreeWidgetItem*,int> &right);
- static bool itemGreaterThan(const QPair<QTreeWidgetItem*,int> &left,
- const QPair<QTreeWidgetItem*,int> &right);
- static QList<QTreeWidgetItem*>::iterator sortedInsertionIterator(
- const QList<QTreeWidgetItem*>::iterator &begin,
- const QList<QTreeWidgetItem*>::iterator &end,
- Qt::SortOrder order, QTreeWidgetItem *item);
-
- bool insertRows(int row, int count, const QModelIndex &);
- bool insertColumns(int column, int count, const QModelIndex &);
-
- bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex());
-
- // dnd
- QStringList mimeTypes() const;
- QMimeData *mimeData(const QModelIndexList &indexes) const;
- bool dropMimeData(const QMimeData *data, Qt::DropAction action,
- int row, int column, const QModelIndex &parent);
- Qt::DropActions supportedDropActions() const;
-
- QMimeData *internalMimeData() const;
-
- inline QModelIndex createIndexFromItem(int row, int col, QTreeWidgetItem *item) const
- { return createIndex(row, col, item); }
-
-protected:
- QTreeModel(QTreeModelPrivate &, QTreeWidget *parent = 0);
- void emitDataChanged(QTreeWidgetItem *item, int column);
- void beginInsertItems(QTreeWidgetItem *parent, int row, int count);
- void endInsertItems();
- void beginRemoveItems(QTreeWidgetItem *parent, int row, int count);
- void endRemoveItems();
- void sortItems(QList<QTreeWidgetItem*> *items, int column, Qt::SortOrder order);
- void timerEvent(QTimerEvent *);
-
-private:
- QTreeWidgetItem *rootItem;
- QTreeWidgetItem *headerItem;
-
- mutable QModelIndexList cachedIndexes;
- QList<QTreeWidgetItemIterator*> iterators;
-
- mutable QBasicTimer sortPendingTimer;
- mutable bool skipPendingSort; //while doing internal operation we don't care about sorting
- bool inline executePendingSort() const;
-
- bool isChanging() const;
-
-private:
- Q_DECLARE_PRIVATE(QTreeModel)
-public:
- struct SkipSorting
- {
- const QTreeModel * const model;
- const bool previous;
- SkipSorting(const QTreeModel *m) : model(m), previous(model->skipPendingSort)
- { model->skipPendingSort = true; }
- ~SkipSorting() { model->skipPendingSort = previous; }
- };
- friend struct SkipSorting;
-};
-
-QT_BEGIN_INCLUDE_NAMESPACE
-#include "private/qabstractitemmodel_p.h"
-QT_END_INCLUDE_NAMESPACE
-
-class QTreeModelPrivate : public QAbstractItemModelPrivate
-{
- Q_DECLARE_PUBLIC(QTreeModel)
-};
-
-class QTreeWidgetItemPrivate
-{
-public:
- QTreeWidgetItemPrivate(QTreeWidgetItem *item)
- : q(item), disabled(false), selected(false), rowGuess(-1), policy(QTreeWidgetItem::DontShowIndicatorWhenChildless) {}
- void propagateDisabled(QTreeWidgetItem *item);
- void sortChildren(int column, Qt::SortOrder order, bool climb);
- QTreeWidgetItem *q;
- QVariantList display;
- uint disabled : 1;
- uint selected : 1;
- int rowGuess;
- QTreeWidgetItem::ChildIndicatorPolicy policy;
-};
-
-
-inline bool QTreeModel::executePendingSort() const
-{
- if (!skipPendingSort && sortPendingTimer.isActive() && !isChanging()) {
- sortPendingTimer.stop();
- int column = view()->header()->sortIndicatorSection();
- Qt::SortOrder order = view()->header()->sortIndicatorOrder();
- QTreeModel *that = const_cast<QTreeModel*>(this);
- that->sort(column, order);
- return true;
- }
- return false;
-}
-
-class QTreeWidgetPrivate : public QTreeViewPrivate
-{
- friend class QTreeModel;
- Q_DECLARE_PUBLIC(QTreeWidget)
-public:
- QTreeWidgetPrivate() : QTreeViewPrivate(), explicitSortColumn(-1) {}
- inline QTreeModel *treeModel() const { return qobject_cast<QTreeModel*>(model); }
- inline QModelIndex index(const QTreeWidgetItem *item, int column = 0) const
- { return treeModel()->index(item, column); }
- inline QTreeWidgetItem *item(const QModelIndex &index) const
- { return treeModel()->item(index); }
- void _q_emitItemPressed(const QModelIndex &index);
- void _q_emitItemClicked(const QModelIndex &index);
- void _q_emitItemDoubleClicked(const QModelIndex &index);
- void _q_emitItemActivated(const QModelIndex &index);
- void _q_emitItemEntered(const QModelIndex &index);
- void _q_emitItemChanged(const QModelIndex &index);
- void _q_emitItemExpanded(const QModelIndex &index);
- void _q_emitItemCollapsed(const QModelIndex &index);
- void _q_emitCurrentItemChanged(const QModelIndex &previous, const QModelIndex &index);
- void _q_sort();
- void _q_dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
- void _q_selectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
-
- // used by QTreeWidgetItem::sortChildren to make sure the column argument is used
- int explicitSortColumn;
-};
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_TREEWIDGET
-
-#endif // QTREEWIDGET_P_H
diff --git a/src/gui/itemviews/qtreewidgetitemiterator.h b/src/gui/itemviews/qtreewidgetitemiterator.h
deleted file mode 100644
index 396e18abe2..0000000000
--- a/src/gui/itemviews/qtreewidgetitemiterator.h
+++ /dev/null
@@ -1,159 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QTREEWIDGETITEMITERATOR_H
-#define QTREEWIDGETITEMITERATOR_H
-
-#include <QtCore/qglobal.h>
-#include <QtCore/qscopedpointer.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_TREEWIDGET
-
-class QTreeWidget;
-class QTreeWidgetItem;
-class QTreeModel;
-
-class QTreeWidgetItemIteratorPrivate;
-class Q_GUI_EXPORT QTreeWidgetItemIterator
-{
- friend class QTreeModel;
-
-public:
- enum IteratorFlag {
- All = 0x00000000,
- Hidden = 0x00000001,
- NotHidden = 0x00000002,
- Selected = 0x00000004,
- Unselected = 0x00000008,
- Selectable = 0x00000010,
- NotSelectable = 0x00000020,
- DragEnabled = 0x00000040,
- DragDisabled = 0x00000080,
- DropEnabled = 0x00000100,
- DropDisabled = 0x00000200,
- HasChildren = 0x00000400,
- NoChildren = 0x00000800,
- Checked = 0x00001000,
- NotChecked = 0x00002000,
- Enabled = 0x00004000,
- Disabled = 0x00008000,
- Editable = 0x00010000,
- NotEditable = 0x00020000,
- UserFlag = 0x01000000 // The first flag that can be used by the user.
- };
- Q_DECLARE_FLAGS(IteratorFlags, IteratorFlag)
-
- QTreeWidgetItemIterator(const QTreeWidgetItemIterator &it);
- explicit QTreeWidgetItemIterator(QTreeWidget *widget, IteratorFlags flags = All);
- explicit QTreeWidgetItemIterator(QTreeWidgetItem *item, IteratorFlags flags = All);
- ~QTreeWidgetItemIterator();
-
- QTreeWidgetItemIterator &operator=(const QTreeWidgetItemIterator &it);
-
- QTreeWidgetItemIterator &operator++();
- inline const QTreeWidgetItemIterator operator++(int);
- inline QTreeWidgetItemIterator &operator+=(int n);
-
- QTreeWidgetItemIterator &operator--();
- inline const QTreeWidgetItemIterator operator--(int);
- inline QTreeWidgetItemIterator &operator-=(int n);
-
- inline QTreeWidgetItem *operator*() const;
-
-private:
- bool matchesFlags(const QTreeWidgetItem *item) const;
- QScopedPointer<QTreeWidgetItemIteratorPrivate> d_ptr;
- QTreeWidgetItem *current;
- IteratorFlags flags;
- Q_DECLARE_PRIVATE(QTreeWidgetItemIterator)
-};
-
-inline const QTreeWidgetItemIterator QTreeWidgetItemIterator::operator++(int)
-{
- QTreeWidgetItemIterator it = *this;
- ++(*this);
- return it;
-}
-
-inline const QTreeWidgetItemIterator QTreeWidgetItemIterator::operator--(int)
-{
- QTreeWidgetItemIterator it = *this;
- --(*this);
- return it;
-}
-
-inline QTreeWidgetItemIterator &QTreeWidgetItemIterator::operator+=(int n)
-{
- if (n < 0)
- return (*this) -= (-n);
- while (current && n--)
- ++(*this);
- return *this;
-}
-
-inline QTreeWidgetItemIterator &QTreeWidgetItemIterator::operator-=(int n)
-{
- if (n < 0)
- return (*this) += (-n);
- while (current && n--)
- --(*this);
- return *this;
-}
-
-inline QTreeWidgetItem *QTreeWidgetItemIterator::operator*() const
-{
- return current;
-}
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QTreeWidgetItemIterator::IteratorFlags)
-
-
-QT_END_NAMESPACE
-#endif // QT_NO_TREEWIDGET
-QT_END_HEADER
-
-#endif // QTREEWIDGETITEMITERATOR_H
diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri
index 3c57368bab..5195b2e3f5 100644
--- a/src/gui/kernel/kernel.pri
+++ b/src/gui/kernel/kernel.pri
@@ -6,324 +6,91 @@ PRECOMPILED_HEADER = kernel/qt_gui_pch.h
KERNEL_P= kernel
HEADERS += \
- kernel/qaction.h \
- kernel/qaction_p.h \
- kernel/qactiongroup.h \
- kernel/qapplication.h \
- kernel/qapplication_p.h \
- kernel/qboxlayout.h \
- kernel/qclipboard.h \
- kernel/qcursor.h \
- kernel/qdesktopwidget.h \
- kernel/qdrag.h \
- kernel/qdnd_p.h \
- kernel/qevent.h \
- kernel/qevent_p.h \
- kernel/qformlayout.h \
- kernel/qgridlayout.h \
- kernel/qkeysequence.h \
- kernel/qlayout.h \
- kernel/qlayout_p.h \
- kernel/qlayoutengine_p.h \
- kernel/qlayoutitem.h \
- kernel/qmime.h \
- kernel/qsessionmanager.h \
- kernel/qshortcut.h \
- kernel/qshortcutmap_p.h \
- kernel/qsizepolicy.h \
- kernel/qpalette.h \
- kernel/qstackedlayout.h \
- kernel/qtooltip.h \
- kernel/qwhatsthis.h \
- kernel/qwidget.h \
- kernel/qwidget_p.h \
- kernel/qwidgetaction.h \
- kernel/qwidgetaction_p.h \
- kernel/qwindowdefs.h \
- kernel/qkeymapper_p.h \
- kernel/qgesture.h \
- kernel/qgesture_p.h \
- kernel/qstandardgestures_p.h \
- kernel/qgesturerecognizer.h \
- kernel/qgesturemanager_p.h \
- kernel/qsoftkeymanager_p.h \
- kernel/qsoftkeymanager_common_p.h \
- kernel/qguiplatformplugin_p.h \
+ kernel/qclipboard.h \
+ kernel/qcursor.h \
+ kernel/qcursor_p.h \
+ kernel/qdrag.h \
+ kernel/qdnd_p.h \
+ kernel/qevent.h \
+ kernel/qevent_p.h \
+ kernel/qinputpanel.h \
+ kernel/qinputpanel_p.h \
+ kernel/qkeysequence.h \
+ kernel/qkeysequence_p.h \
+ kernel/qkeymapper_p.h \
+ kernel/qmime.h \
+ kernel/qpalette.h \
+ kernel/qsessionmanager.h \
+ kernel/qwindowdefs.h \
+ kernel/qscreen.h \
+ kernel/qstylehints.h
SOURCES += \
- kernel/qaction.cpp \
- kernel/qactiongroup.cpp \
- kernel/qapplication.cpp \
- kernel/qboxlayout.cpp \
- kernel/qclipboard.cpp \
- kernel/qcursor.cpp \
- kernel/qdrag.cpp \
- kernel/qdnd.cpp \
- kernel/qevent.cpp \
- kernel/qformlayout.cpp \
- kernel/qgridlayout.cpp \
- kernel/qkeysequence.cpp \
- kernel/qlayout.cpp \
- kernel/qlayoutengine.cpp \
- kernel/qlayoutitem.cpp \
- kernel/qmime.cpp \
- kernel/qpalette.cpp \
- kernel/qshortcut.cpp \
- kernel/qshortcutmap.cpp \
- kernel/qstackedlayout.cpp \
- kernel/qtooltip.cpp \
- kernel/qguivariant.cpp \
- kernel/qwhatsthis.cpp \
- kernel/qwidget.cpp \
- kernel/qwidgetaction.cpp \
- kernel/qkeymapper.cpp \
- kernel/qgesture.cpp \
- kernel/qstandardgestures.cpp \
- kernel/qgesturerecognizer.cpp \
- kernel/qgesturemanager.cpp \
- kernel/qsoftkeymanager.cpp \
- kernel/qdesktopwidget.cpp \
- kernel/qguiplatformplugin.cpp
-
-win32 {
- DEFINES += QT_NO_DIRECTDRAW
-
- HEADERS += \
- kernel/qwinnativepangesturerecognizer_win_p.h
-
- SOURCES += \
- kernel/qapplication_win.cpp \
- kernel/qclipboard_win.cpp \
- kernel/qcursor_win.cpp \
- kernel/qdesktopwidget_win.cpp \
- kernel/qdnd_win.cpp \
- kernel/qmime_win.cpp \
- kernel/qsound_win.cpp \
- kernel/qwidget_win.cpp \
- kernel/qole_win.cpp \
- kernel/qkeymapper_win.cpp \
- kernel/qwinnativepangesturerecognizer_win.cpp
-
- !contains(DEFINES, QT_NO_DIRECTDRAW):LIBS += ddraw.lib
-}
-
-symbian {
- exists($${EPOCROOT}epoc32/include/platform/mw/akntranseffect.h): DEFINES += QT_SYMBIAN_HAVE_AKNTRANSEFFECT_H
-
- SOURCES += \
- kernel/qapplication_s60.cpp \
- kernel/qeventdispatcher_s60.cpp \
- kernel/qwidget_s60.cpp \
- kernel/qcursor_s60.cpp \
- kernel/qdesktopwidget_s60.cpp \
- kernel/qkeymapper_s60.cpp\
- kernel/qclipboard_s60.cpp\
- kernel/qdnd_s60.cpp \
- kernel/qsound_s60.cpp
-
- HEADERS += \
- kernel/qt_s60_p.h \
- kernel/qeventdispatcher_s60_p.h
-
- LIBS += -lbafl -lestor
-
- INCLUDEPATH += $$MW_LAYER_SYSTEMINCLUDE
- INCLUDEPATH += ../3rdparty/s60
-
- contains(QT_CONFIG, s60) {
- SOURCES += kernel/qsoftkeymanager_s60.cpp
- HEADERS += kernel/qsoftkeymanager_s60_p.h
- }
-}
-
-
-unix:x11 {
- INCLUDEPATH += ../3rdparty/xorg
- HEADERS += \
- kernel/qx11embed_x11.h \
- kernel/qx11info_x11.h \
- kernel/qkde_p.h
-
- SOURCES += \
- kernel/qapplication_x11.cpp \
- kernel/qclipboard_x11.cpp \
- kernel/qcursor_x11.cpp \
- kernel/qdnd_x11.cpp \
- kernel/qdesktopwidget_x11.cpp \
- kernel/qmotifdnd_x11.cpp \
- kernel/qsound_x11.cpp \
- kernel/qwidget_x11.cpp \
- kernel/qwidgetcreate_x11.cpp \
- kernel/qx11embed_x11.cpp \
- kernel/qx11info_x11.cpp \
- kernel/qkeymapper_x11.cpp \
- kernel/qkde.cpp
-
- contains(QT_CONFIG, glib) {
- SOURCES += \
- kernel/qguieventdispatcher_glib.cpp
- HEADERS += \
- kernel/qguieventdispatcher_glib_p.h
- QMAKE_CXXFLAGS += $$QT_CFLAGS_GLIB
- LIBS_PRIVATE +=$$QT_LIBS_GLIB
- }
- SOURCES += \
- kernel/qeventdispatcher_x11.cpp
- HEADERS += \
- kernel/qeventdispatcher_x11_p.h
-}
-
-embedded {
- HEADERS += \
- kernel/qeventdispatcher_qws_p.h
-
- SOURCES += \
- kernel/qapplication_qws.cpp \
- kernel/qclipboard_qws.cpp \
- kernel/qcursor_qws.cpp \
- kernel/qdesktopwidget_qws.cpp \
- kernel/qdnd_qws.cpp \
- kernel/qeventdispatcher_qws.cpp \
- kernel/qsound_qws.cpp \
- kernel/qwidget_qws.cpp \
- kernel/qkeymapper_qws.cpp \
- kernel/qsessionmanager_qws.cpp
-
- contains(QT_CONFIG, glib) {
- SOURCES += \
- kernel/qeventdispatcher_glib_qws.cpp
- HEADERS += \
- kernel/qeventdispatcher_glib_qws_p.h
- QMAKE_CXXFLAGS += $$QT_CFLAGS_GLIB
- LIBS_PRIVATE +=$$QT_LIBS_GLIB
- }
-}
-
-!qpa {
- HEADERS += \
- kernel/qsound.h \
- kernel/qsound_p.h
-
- SOURCES += \
- kernel/qsound.cpp
-}
+ kernel/qclipboard.cpp \
+ kernel/qcursor.cpp \
+ kernel/qdrag.cpp \
+ kernel/qdnd.cpp \
+ kernel/qevent.cpp \
+ kernel/qinputpanel.cpp \
+ kernel/qkeysequence.cpp \
+ kernel/qkeymapper.cpp \
+ kernel/qkeymapper_qpa.cpp \
+ kernel/qmime.cpp \
+ kernel/qpalette.cpp \
+ kernel/qguivariant.cpp \
+ kernel/qscreen.cpp \
+ kernel/qstylehints.cpp
qpa {
HEADERS += \
- kernel/qgenericpluginfactory_qpa.h \
+ kernel/qgenericpluginfactory_qpa.h \
kernel/qgenericplugin_qpa.h \
- kernel/qeventdispatcher_qpa_p.h \
kernel/qwindowsysteminterface_qpa.h \
kernel/qwindowsysteminterface_qpa_p.h \
kernel/qplatformintegration_qpa.h \
+ kernel/qplatformdrag_qpa.h \
kernel/qplatformscreen_qpa.h \
+ kernel/qplatforminputcontext_qpa.h \
kernel/qplatformintegrationfactory_qpa_p.h \
kernel/qplatformintegrationplugin_qpa.h \
kernel/qplatformwindow_qpa.h \
- kernel/qplatformwindowformat_qpa.h \
- kernel/qplatformglcontext_qpa.h \
- kernel/qdesktopwidget_qpa_p.h \
- kernel/qplatformeventloopintegration_qpa.h \
+ kernel/qplatformopenglcontext_qpa.h \
+ kernel/qopenglcontext.h \
+ kernel/qopenglcontext_p.h \
kernel/qplatformcursor_qpa.h \
kernel/qplatformclipboard_qpa.h \
- kernel/qplatformnativeinterface_qpa.h
+ kernel/qplatformnativeinterface_qpa.h \
+ kernel/qsurfaceformat.h \
+ kernel/qguiapplication.h \
+ kernel/qguiapplication_p.h \
+ kernel/qwindow_p.h \
+ kernel/qwindow.h \
+ kernel/qplatformsurface_qpa.h \
+ kernel/qsurface.h
SOURCES += \
- kernel/qapplication_qpa.cpp \
- kernel/qclipboard_qpa.cpp \
- kernel/qcursor_qpa.cpp \
- kernel/qdnd_qws.cpp \
- kernel/qdesktopwidget_qpa.cpp \
- kernel/qgenericpluginfactory_qpa.cpp \
- kernel/qgenericplugin_qpa.cpp \
- kernel/qkeymapper_qws.cpp \
- kernel/qwidget_qpa.cpp \
- kernel/qeventdispatcher_qpa.cpp \
+ kernel/qclipboard_qpa.cpp \
+ kernel/qcursor_qpa.cpp \
+ kernel/qgenericpluginfactory_qpa.cpp \
+ kernel/qgenericplugin_qpa.cpp \
kernel/qwindowsysteminterface_qpa.cpp \
+ kernel/qplatforminputcontext_qpa.cpp \
kernel/qplatformintegration_qpa.cpp \
kernel/qplatformscreen_qpa.cpp \
kernel/qplatformintegrationfactory_qpa.cpp \
kernel/qplatformintegrationplugin_qpa.cpp \
kernel/qplatformwindow_qpa.cpp \
- kernel/qplatformwindowformat_qpa.cpp \
- kernel/qplatformeventloopintegration_qpa.cpp \
- kernel/qplatformglcontext_qpa.cpp \
+ kernel/qplatformopenglcontext_qpa.cpp \
+ kernel/qopenglcontext.cpp \
kernel/qplatformcursor_qpa.cpp \
kernel/qplatformclipboard_qpa.cpp \
kernel/qplatformnativeinterface_qpa.cpp \
- kernel/qsessionmanager_qpa.cpp
-
- contains(QT_CONFIG, glib) {
- SOURCES += \
- kernel/qeventdispatcher_glib_qpa.cpp
- HEADERS += \
- kernel/qeventdispatcher_glib_qpa_p.h
- QMAKE_CXXFLAGS += $$QT_CFLAGS_GLIB
- LIBS_PRIVATE +=$$QT_LIBS_GLIB
- }
+ kernel/qsessionmanager_qpa.cpp \
+ kernel/qsurfaceformat.cpp \
+ kernel/qguiapplication.cpp \
+ kernel/qwindow.cpp \
+ kernel/qplatformsurface_qpa.cpp \
+ kernel/qsurface.cpp
}
-!embedded:!qpa:!x11:mac {
- SOURCES += \
- kernel/qclipboard_mac.cpp \
- kernel/qmime_mac.cpp \
- kernel/qt_mac.cpp \
- kernel/qkeymapper_mac.cpp
-
- OBJECTIVE_HEADERS += \
- qcocoawindow_mac_p.h \
- qcocoapanel_mac_p.h \
- qcocoawindowdelegate_mac_p.h \
- qcocoaview_mac_p.h \
- qcocoaapplication_mac_p.h \
- qcocoaapplicationdelegate_mac_p.h \
- qmacgesturerecognizer_mac_p.h \
- qmultitouch_mac_p.h \
- qcocoasharedwindowmethods_mac_p.h \
- qcocoaintrospection_p.h
-
- OBJECTIVE_SOURCES += \
- kernel/qcursor_mac.mm \
- kernel/qdnd_mac.mm \
- kernel/qsound_mac.mm \
- kernel/qapplication_mac.mm \
- kernel/qwidget_mac.mm \
- kernel/qcocoapanel_mac.mm \
- kernel/qcocoaview_mac.mm \
- kernel/qcocoawindow_mac.mm \
- kernel/qcocoawindowdelegate_mac.mm \
- kernel/qcocoamenuloader_mac.mm \
- kernel/qcocoaapplication_mac.mm \
- kernel/qcocoaapplicationdelegate_mac.mm \
- kernel/qt_cocoa_helpers_mac.mm \
- kernel/qdesktopwidget_mac.mm \
- kernel/qeventdispatcher_mac.mm \
- kernel/qcocoawindowcustomthemeframe_mac.mm \
- kernel/qmacgesturerecognizer_mac.mm \
- kernel/qmultitouch_mac.mm \
- kernel/qcocoaintrospection_mac.mm
-
- HEADERS += \
- kernel/qt_cocoa_helpers_mac_p.h \
- kernel/qcocoaapplication_mac_p.h \
- kernel/qcocoaapplicationdelegate_mac_p.h \
- kernel/qeventdispatcher_mac_p.h
-
- MENU_NIB.files = mac/qt_menu.nib
- MENU_NIB.path = Resources
- MENU_NIB.version = Versions
- QMAKE_BUNDLE_DATA += MENU_NIB
- RESOURCES += mac/macresources.qrc
-
- LIBS_PRIVATE += -framework AppKit
-}
-
-wince*: {
- HEADERS += \
- ../corelib/kernel/qfunctions_wince.h \
- kernel/qguifunctions_wince.h
-
- SOURCES += \
- ../corelib/kernel/qfunctions_wince.cpp \
- kernel/qguifunctions_wince.cpp
-}
+win32:HEADERS+=kernel/qwindowdefs_win.h
diff --git a/src/gui/kernel/mac.pri b/src/gui/kernel/mac.pri
deleted file mode 100644
index 21acd06e65..0000000000
--- a/src/gui/kernel/mac.pri
+++ /dev/null
@@ -1,4 +0,0 @@
-!x11:!embedded:!qpa:mac {
- LIBS_PRIVATE += -framework Carbon -lz
- *-mwerks:INCLUDEPATH += compat
-}
diff --git a/src/gui/kernel/qaction.h b/src/gui/kernel/qaction.h
deleted file mode 100644
index e18257c6ab..0000000000
--- a/src/gui/kernel/qaction.h
+++ /dev/null
@@ -1,264 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QACTION_H
-#define QACTION_H
-
-#include <QtGui/qkeysequence.h>
-#include <QtCore/qstring.h>
-#include <QtGui/qwidget.h>
-#include <QtCore/qvariant.h>
-#include <QtGui/qicon.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_ACTION
-
-class QMenu;
-class QActionGroup;
-class QActionPrivate;
-class QGraphicsWidget;
-
-class Q_GUI_EXPORT QAction : public QObject
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QAction)
-
- Q_ENUMS(MenuRole)
- Q_ENUMS(SoftKeyRole)
- Q_ENUMS(Priority)
- Q_PROPERTY(bool checkable READ isCheckable WRITE setCheckable NOTIFY changed)
- Q_PROPERTY(bool checked READ isChecked WRITE setChecked DESIGNABLE isCheckable NOTIFY toggled)
- Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY changed)
- Q_PROPERTY(QIcon icon READ icon WRITE setIcon NOTIFY changed)
- Q_PROPERTY(QString text READ text WRITE setText NOTIFY changed)
- Q_PROPERTY(QString iconText READ iconText WRITE setIconText NOTIFY changed)
- Q_PROPERTY(QString toolTip READ toolTip WRITE setToolTip NOTIFY changed)
- Q_PROPERTY(QString statusTip READ statusTip WRITE setStatusTip NOTIFY changed)
- Q_PROPERTY(QString whatsThis READ whatsThis WRITE setWhatsThis NOTIFY changed)
- Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY changed)
-#ifndef QT_NO_SHORTCUT
- Q_PROPERTY(QKeySequence shortcut READ shortcut WRITE setShortcut NOTIFY changed)
- Q_PROPERTY(Qt::ShortcutContext shortcutContext READ shortcutContext WRITE setShortcutContext NOTIFY changed)
- Q_PROPERTY(bool autoRepeat READ autoRepeat WRITE setAutoRepeat NOTIFY changed)
-#endif
- Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY changed)
- Q_PROPERTY(MenuRole menuRole READ menuRole WRITE setMenuRole NOTIFY changed)
- Q_PROPERTY(SoftKeyRole softKeyRole READ softKeyRole WRITE setSoftKeyRole NOTIFY changed)
- Q_PROPERTY(bool iconVisibleInMenu READ isIconVisibleInMenu WRITE setIconVisibleInMenu NOTIFY changed)
- Q_PROPERTY(Priority priority READ priority WRITE setPriority)
-
-public:
- enum MenuRole { NoRole, TextHeuristicRole, ApplicationSpecificRole, AboutQtRole,
- AboutRole, PreferencesRole, QuitRole };
- enum SoftKeyRole {
- NoSoftKey, PositiveSoftKey, NegativeSoftKey, SelectSoftKey };
- enum Priority { LowPriority = 0,
- NormalPriority = 128,
- HighPriority = 256};
- explicit QAction(QObject* parent);
- QAction(const QString &text, QObject* parent);
- QAction(const QIcon &icon, const QString &text, QObject* parent);
-
-#ifdef QT3_SUPPORT
- QT3_SUPPORT_CONSTRUCTOR QAction(QObject* parent, const char* name);
- QT3_SUPPORT_CONSTRUCTOR QAction(const QString &text, const QKeySequence &shortcut,
- QObject* parent, const char* name);
- QT3_SUPPORT_CONSTRUCTOR QAction(const QIcon &icon, const QString &text,
- const QKeySequence &shortcut,
- QObject* parent, const char* name);
-#endif
- ~QAction();
-
- void setActionGroup(QActionGroup *group);
- QActionGroup *actionGroup() const;
- void setIcon(const QIcon &icon);
- QIcon icon() const;
-
- void setText(const QString &text);
- QString text() const;
-
- void setIconText(const QString &text);
- QString iconText() const;
-
- void setToolTip(const QString &tip);
- QString toolTip() const;
-
- void setStatusTip(const QString &statusTip);
- QString statusTip() const;
-
- void setWhatsThis(const QString &what);
- QString whatsThis() const;
-
- void setPriority(Priority priority);
- Priority priority() const;
-
-#ifndef QT_NO_MENU
- QMenu *menu() const;
- void setMenu(QMenu *menu);
-#endif
-
- void setSeparator(bool b);
- bool isSeparator() const;
-
-#ifndef QT_NO_SHORTCUT
- void setShortcut(const QKeySequence &shortcut);
- QKeySequence shortcut() const;
-
- void setShortcuts(const QList<QKeySequence> &shortcuts);
- void setShortcuts(QKeySequence::StandardKey);
- QList<QKeySequence> shortcuts() const;
-
- void setShortcutContext(Qt::ShortcutContext context);
- Qt::ShortcutContext shortcutContext() const;
-
- void setAutoRepeat(bool);
- bool autoRepeat() const;
-#endif
-
- void setFont(const QFont &font);
- QFont font() const;
-
- void setCheckable(bool);
- bool isCheckable() const;
-
- QVariant data() const;
- void setData(const QVariant &var);
-
- bool isChecked() const;
-
- bool isEnabled() const;
-
- bool isVisible() const;
-
- enum ActionEvent { Trigger, Hover };
- void activate(ActionEvent event);
- bool showStatusText(QWidget *widget=0);
-
- void setMenuRole(MenuRole menuRole);
- MenuRole menuRole() const;
-
- void setSoftKeyRole(SoftKeyRole softKeyRole);
- SoftKeyRole softKeyRole() const;
-
- void setIconVisibleInMenu(bool visible);
- bool isIconVisibleInMenu() const;
-
-#ifdef QT3_SUPPORT
- inline QT3_SUPPORT void setMenuText(const QString &text) { setText(text); }
- inline QT3_SUPPORT QString menuText() const { return text(); }
- inline QT3_SUPPORT bool isOn() const { return isChecked(); }
- inline QT3_SUPPORT bool isToggleAction() const { return isCheckable(); }
- inline QT3_SUPPORT void setToggleAction(bool b) { setCheckable(b); }
- inline QT3_SUPPORT void setIconSet(const QIcon &i) { setIcon(i); }
- inline QT3_SUPPORT QIcon iconSet() const { return icon(); }
- inline QT3_SUPPORT bool addTo(QWidget *w) { w->addAction(this); return true; }
- inline QT3_SUPPORT bool removeFrom(QWidget *w) { w->removeAction(this); return true; }
- inline QT3_SUPPORT void setAccel(const QKeySequence &shortcut) { setShortcut(shortcut); }
- inline QT3_SUPPORT QKeySequence accel() const { return shortcut(); }
-#endif
-
- QWidget *parentWidget() const;
-
- QList<QWidget *> associatedWidgets() const;
-#ifndef QT_NO_GRAPHICSVIEW
- QList<QGraphicsWidget *> associatedGraphicsWidgets() const; // ### suboptimal
-#endif
-
-protected:
- bool event(QEvent *);
- QAction(QActionPrivate &dd, QObject *parent);
-
-public Q_SLOTS:
-#ifdef QT3_SUPPORT
- inline QT_MOC_COMPAT void setOn(bool b) { setChecked(b); }
-#endif
- void trigger() { activate(Trigger); }
- void hover() { activate(Hover); }
- void setChecked(bool);
- void toggle();
- void setEnabled(bool);
- inline void setDisabled(bool b) { setEnabled(!b); }
- void setVisible(bool);
-
-Q_SIGNALS:
- void changed();
- void triggered(bool checked = false);
- void hovered();
- void toggled(bool);
-#ifdef QT3_SUPPORT
- QT_MOC_COMPAT void activated(int = 0);
-#endif
-
-private:
- Q_DISABLE_COPY(QAction)
-
-#ifdef QT3_SUPPORT
- friend class QMenuItem;
-#endif
- friend class QGraphicsWidget;
- friend class QWidget;
- friend class QActionGroup;
- friend class QMenu;
- friend class QMenuPrivate;
- friend class QMenuBar;
- friend class QShortcutMap;
- friend class QToolButton;
-#ifdef Q_WS_MAC
- friend void qt_mac_clear_status_text(QAction *action);
-#endif
-};
-
-QT_BEGIN_INCLUDE_NAMESPACE
-#include <QtGui/qactiongroup.h>
-QT_END_INCLUDE_NAMESPACE
-
-#endif // QT_NO_ACTION
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QACTION_H
diff --git a/src/gui/kernel/qaction_p.h b/src/gui/kernel/qaction_p.h
deleted file mode 100644
index e4738eacbd..0000000000
--- a/src/gui/kernel/qaction_p.h
+++ /dev/null
@@ -1,144 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QACTION_P_H
-#define QACTION_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "QtGui/qaction.h"
-#include "QtGui/qmenu.h"
-#include "private/qgraphicswidget_p.h"
-#include "private/qobject_p.h"
-
-QT_BEGIN_NAMESPACE
-
-#ifndef QT_NO_ACTION
-
-#ifdef QT3_SUPPORT
-class QMenuItemEmitter;
-#endif
-
-class QShortcutMap;
-
-class Q_AUTOTEST_EXPORT QActionPrivate : public QObjectPrivate
-{
- Q_DECLARE_PUBLIC(QAction)
-public:
- QActionPrivate();
- ~QActionPrivate();
-
- static QActionPrivate *get(QAction *q)
- {
- return q->d_func();
- }
-
- bool showStatusText(QWidget *w, const QString &str);
-
- QPointer<QActionGroup> group;
- QString text;
- QString iconText;
- QIcon icon;
- QString tooltip;
- QString statustip;
- QString whatsthis;
-#ifndef QT_NO_SHORTCUT
- QKeySequence shortcut;
- QList<QKeySequence> alternateShortcuts;
-#endif
- QVariant userData;
-#ifndef QT_NO_SHORTCUT
- int shortcutId;
- QList<int> alternateShortcutIds;
- Qt::ShortcutContext shortcutContext;
- uint autorepeat : 1;
-#endif
- QFont font;
- QPointer<QMenu> menu;
- uint enabled : 1, forceDisabled : 1;
- uint visible : 1, forceInvisible : 1;
- uint checkable : 1;
- uint checked : 1;
- uint separator : 1;
- uint fontSet : 1;
-
- //for soft keys management
- uint forceEnabledInSoftkeys : 1;
- uint menuActionSoftkeys : 1;
- int iconVisibleInMenu : 3; // Only has values -1, 0, and 1
-
- QAction::MenuRole menuRole;
- QAction::SoftKeyRole softKeyRole;
- QAction::Priority priority;
-
- QList<QWidget *> widgets;
-#ifndef QT_NO_GRAPHICSVIEW
- QList<QGraphicsWidget *> graphicsWidgets;
-#endif
-#ifndef QT_NO_SHORTCUT
- void redoGrab(QShortcutMap &map);
- void redoGrabAlternate(QShortcutMap &map);
- void setShortcutEnabled(bool enable, QShortcutMap &map);
-
- static QShortcutMap *globalMap;
-#endif // QT_NO_SHORTCUT
-
-#ifdef QT3_SUPPORT //for menubar/menu compat
- QMenuItemEmitter *act_signal;
- int id, param;
-#endif
- void sendDataChanged();
-};
-
-#endif // QT_NO_ACTION
-
-QT_END_NAMESPACE
-
-#endif // QACTION_P_H
diff --git a/src/gui/kernel/qactiongroup.h b/src/gui/kernel/qactiongroup.h
deleted file mode 100644
index 84945d47d0..0000000000
--- a/src/gui/kernel/qactiongroup.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QACTIONGROUP_H
-#define QACTIONGROUP_H
-
-#include <QtGui/qaction.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_ACTION
-
-class QActionGroupPrivate;
-
-class Q_GUI_EXPORT QActionGroup : public QObject
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QActionGroup)
-
- Q_PROPERTY(bool exclusive READ isExclusive WRITE setExclusive)
- Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled)
- Q_PROPERTY(bool visible READ isVisible WRITE setVisible)
-
-public:
- explicit QActionGroup(QObject* parent);
- ~QActionGroup();
-
- QAction *addAction(QAction* a);
- QAction *addAction(const QString &text);
- QAction *addAction(const QIcon &icon, const QString &text);
- void removeAction(QAction *a);
- QList<QAction*> actions() const;
-
- QAction *checkedAction() const;
- bool isExclusive() const;
- bool isEnabled() const;
- bool isVisible() const;
-
-#ifdef QT3_SUPPORT
- inline QT3_SUPPORT void add(QAction* a) { addAction(a); }
- inline QT3_SUPPORT void addSeparator()
- { QAction *act = new QAction(this); act->setSeparator(true); addAction(act); }
- inline QT3_SUPPORT bool addTo(QWidget *w) { w->addActions(actions()); return true; }
-#endif
-
-public Q_SLOTS:
- void setEnabled(bool);
- inline void setDisabled(bool b) { setEnabled(!b); }
- void setVisible(bool);
- void setExclusive(bool);
-
-Q_SIGNALS:
- void triggered(QAction *);
- QT_MOC_COMPAT void selected(QAction *);
- void hovered(QAction *);
-
-private:
- Q_DISABLE_COPY(QActionGroup)
- Q_PRIVATE_SLOT(d_func(), void _q_actionTriggered())
- Q_PRIVATE_SLOT(d_func(), void _q_actionChanged())
- Q_PRIVATE_SLOT(d_func(), void _q_actionHovered())
-};
-
-#endif // QT_NO_ACTION
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QACTIONGROUP_H
diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp
deleted file mode 100644
index 593a3209a8..0000000000
--- a/src/gui/kernel/qapplication.cpp
+++ /dev/null
@@ -1,6141 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qplatformdefs.h"
-#include "qabstracteventdispatcher.h"
-#include "qaccessible.h"
-#include "qapplication.h"
-#include "qclipboard.h"
-#include "qcursor.h"
-#include "qdesktopwidget.h"
-#include "qdir.h"
-#include "qevent.h"
-#include "qfile.h"
-#include "qfileinfo.h"
-#include "qgraphicsscene.h"
-#include "qhash.h"
-#include "qset.h"
-#include "qlayout.h"
-#include "qsessionmanager.h"
-#include "qstyle.h"
-#include "qstylefactory.h"
-#include "qtextcodec.h"
-#include "qtranslator.h"
-#include "qvariant.h"
-#include "qwidget.h"
-#include "qdnd_p.h"
-#include "qcolormap.h"
-#include "qdebug.h"
-#include "private/qgraphicssystemfactory_p.h"
-#include "private/qgraphicssystem_p.h"
-#include "private/qstylesheetstyle_p.h"
-#include "private/qstyle_p.h"
-#include "qmessagebox.h"
-#include <QtGui/qgraphicsproxywidget.h>
-
-#ifdef QT_GRAPHICSSYSTEM_RUNTIME
-#include "private/qgraphicssystem_runtime_p.h"
-#endif
-
-#include "qinputcontext.h"
-#include "qkeymapper_p.h"
-
-#ifdef Q_WS_X11
-#include <private/qt_x11_p.h>
-#endif
-
-#if defined(Q_WS_X11) || defined(Q_OS_SYMBIAN)
-#include "qinputcontextfactory.h"
-#endif
-
-#include "qguiplatformplugin_p.h"
-
-#include <qthread.h>
-#include <private/qthread_p.h>
-
-#include <private/qfont_p.h>
-
-#include <stdlib.h>
-
-#if defined(Q_WS_X11) && !defined(QT_NO_EGL)
-#include <link.h>
-#endif
-
-#include "qapplication_p.h"
-#include "qevent_p.h"
-#include "qwidget_p.h"
-
-#include "qapplication.h"
-
-#include "qgesture.h"
-#include "private/qgesturemanager_p.h"
-
-#ifndef QT_NO_LIBRARY
-#include "qlibrary.h"
-#endif
-
-#ifdef Q_WS_WINCE
-#include "qdatetime.h"
-#include "qguifunctions_wince.h"
-extern bool qt_wince_is_smartphone(); //qguifunctions_wince.cpp
-extern bool qt_wince_is_mobile(); //qguifunctions_wince.cpp
-extern bool qt_wince_is_pocket_pc(); //qguifunctions_wince.cpp
-#endif
-
-#include "qdatetime.h"
-
-#ifdef QT_MAC_USE_COCOA
-#include <private/qt_cocoa_helpers_mac_p.h>
-#endif
-
-//#define ALIEN_DEBUG
-
-#if defined(Q_OS_SYMBIAN)
-#include "qt_s60_p.h"
-#endif
-
-static void initResources()
-{
-#if defined(Q_WS_WINCE)
- Q_INIT_RESOURCE_EXTERN(qstyle_wince)
- Q_INIT_RESOURCE(qstyle_wince);
-#elif defined(Q_OS_SYMBIAN)
- Q_INIT_RESOURCE_EXTERN(qstyle_s60)
- Q_INIT_RESOURCE(qstyle_s60);
-#else
- Q_INIT_RESOURCE_EXTERN(qstyle)
- Q_INIT_RESOURCE(qstyle);
-#endif
- Q_INIT_RESOURCE_EXTERN(qmessagebox)
- Q_INIT_RESOURCE(qmessagebox);
-#if !defined(QT_NO_PRINTDIALOG)
- Q_INIT_RESOURCE_EXTERN(qprintdialog)
- Q_INIT_RESOURCE(qprintdialog);
-#endif
-
-}
-
-QT_BEGIN_NAMESPACE
-
-Q_CORE_EXPORT void qt_call_post_routines();
-
-QApplication::Type qt_appType=QApplication::Tty;
-QApplicationPrivate *QApplicationPrivate::self = 0;
-
-QInputContext *QApplicationPrivate::inputContext = 0;
-
-bool QApplicationPrivate::quitOnLastWindowClosed = true;
-
-#ifdef Q_WS_WINCE
-int QApplicationPrivate::autoMaximizeThreshold = -1;
-bool QApplicationPrivate::autoSipEnabled = false;
-#else
-bool QApplicationPrivate::autoSipEnabled = true;
-#endif
-
-QApplicationPrivate::QApplicationPrivate(int &argc, char **argv, QApplication::Type type, int flags)
- : QCoreApplicationPrivate(argc, argv, flags)
-{
- application_type = type;
- qt_appType = type;
-
-#ifndef QT_NO_SESSIONMANAGER
- is_session_restored = false;
-#endif
-
- quitOnLastWindowClosed = true;
-
-#ifdef QT3_SUPPORT
- qt_compat_used = 0;
- qt_compat_resolved = 0;
- qt_tryAccelEvent = 0;
- qt_tryComposeUnicode = 0;
- qt_dispatchAccelEvent = 0;
-#endif
-#if defined(Q_WS_QWS) && !defined(QT_NO_DIRECTPAINTER)
- directPainters = 0;
-#endif
-
-#ifndef QT_NO_GESTURES
- gestureManager = 0;
- gestureWidget = 0;
-#endif // QT_NO_GESTURES
-
-#if defined(Q_WS_X11) || defined(Q_WS_WIN)
- move_cursor = 0;
- copy_cursor = 0;
- link_cursor = 0;
-#endif
-#if defined(Q_WS_WIN)
- ignore_cursor = 0;
-#endif
-
- if (!self)
- self = this;
-}
-
-QApplicationPrivate::~QApplicationPrivate()
-{
- if (self == this)
- self = 0;
-}
-
-/*!
- \class QApplication
- \brief The QApplication class manages the GUI application's control
- flow and main settings.
-
- 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, finalization, and provides session
- management. In addition, QApplication handles most of the system-wide and
- application-wide settings.
-
- For any GUI application using Qt, there is precisely \bold 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
-
- Since the QApplication object does so much initialization, it \e{must} be
- created before any other objects related to the user interface are created.
- QApplication also deals with common command line arguments. Hence, 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
-*/
-
-/*!
- \enum QApplication::Type
-
- \value Tty a console application
- \value GuiClient a GUI client application
- \value GuiServer a GUI server application (for Qt for Embedded Linux)
-*/
-
-/*!
- \enum QApplication::ColorSpec
-
- \value NormalColor the default color allocation policy
- \value CustomColor the same as NormalColor for X11; allocates colors
- to a palette on demand under Windows
- \value ManyColor the right choice for applications that use thousands of
- colors
-
- See setColorSpec() for full details.
-*/
-
-/*!
- \fn QWidget *QApplication::topLevelAt(const QPoint &point)
-
- 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)
-
- \overload
-
- Returns the top-level widget at the point (\a{x}, \a{y}); returns
- 0 if there is no such widget.
-*/
-
-
-/*
- The qt_init() and qt_cleanup() functions are implemented in the
- qapplication_xyz.cpp file.
-*/
-
-void qt_init(QApplicationPrivate *priv, int type
-#ifdef Q_WS_X11
- , Display *display = 0, Qt::HANDLE visual = 0, Qt::HANDLE colormap = 0
-#endif
- );
-void qt_cleanup();
-
-Qt::MouseButtons QApplicationPrivate::mouse_buttons = Qt::NoButton;
-Qt::KeyboardModifiers QApplicationPrivate::modifier_buttons = Qt::NoModifier;
-
-QStyle *QApplicationPrivate::app_style = 0; // default application style
-QString QApplicationPrivate::styleOverride; // style override
-
-#ifndef QT_NO_STYLE_STYLESHEET
-QString QApplicationPrivate::styleSheet; // default application stylesheet
-#endif
-QPointer<QWidget> QApplicationPrivate::leaveAfterRelease = 0;
-
-int QApplicationPrivate::app_cspec = QApplication::NormalColor;
-QPalette *QApplicationPrivate::app_pal = 0; // default application palette
-QPalette *QApplicationPrivate::sys_pal = 0; // default system palette
-QPalette *QApplicationPrivate::set_pal = 0; // default palette set by programmer
-
-QGraphicsSystem *QApplicationPrivate::graphics_system = 0; // default graphics system
-#if defined(Q_WS_QPA)
-QPlatformIntegration *QApplicationPrivate::platform_integration = 0;
-#endif
-QString QApplicationPrivate::graphics_system_name; // graphics system id - for delayed initialization
-bool QApplicationPrivate::runtime_graphics_system = false;
-
-Q_GLOBAL_STATIC(QMutex, applicationFontMutex)
-QFont *QApplicationPrivate::app_font = 0; // default application font
-QFont *QApplicationPrivate::sys_font = 0; // default system font
-QFont *QApplicationPrivate::set_font = 0; // default font set by programmer
-
-QIcon *QApplicationPrivate::app_icon = 0;
-QWidget *QApplicationPrivate::main_widget = 0; // main application widget
-QWidget *QApplicationPrivate::focus_widget = 0; // has keyboard input focus
-QWidget *QApplicationPrivate::hidden_focus_widget = 0; // will get keyboard input focus after show()
-QWidget *QApplicationPrivate::active_window = 0; // toplevel with keyboard focus
-bool QApplicationPrivate::obey_desktop_settings = true; // use winsys resources
-int QApplicationPrivate::cursor_flash_time = 1000; // text caret flash time
-int QApplicationPrivate::mouse_double_click_time = 400; // mouse dbl click limit
-int QApplicationPrivate::keyboard_input_time = 400; // keyboard input interval
-#ifndef QT_NO_WHEELEVENT
-int QApplicationPrivate::wheel_scroll_lines; // number of lines to scroll
-#endif
-bool qt_is_gui_used;
-bool Q_GUI_EXPORT qt_tab_all_widgets = true;
-bool qt_in_tab_key_event = false;
-int qt_antialiasing_threshold = -1;
-static int drag_time = 500;
-#ifndef QT_GUI_DRAG_DISTANCE
-#define QT_GUI_DRAG_DISTANCE 4
-#endif
-#ifdef Q_OS_SYMBIAN
-// The screens are a bit too small to for your thumb when using only 4 pixels drag distance.
-static int drag_distance = 12; //XXX move to qplatformdefs.h
-#else
-static int drag_distance = QT_GUI_DRAG_DISTANCE;
-#endif
-static Qt::LayoutDirection layout_direction = Qt::LeftToRight;
-QSize QApplicationPrivate::app_strut = QSize(0,0); // no default application strut
-bool QApplicationPrivate::animate_ui = true;
-bool QApplicationPrivate::animate_menu = false;
-bool QApplicationPrivate::fade_menu = false;
-bool QApplicationPrivate::animate_combo = false;
-bool QApplicationPrivate::animate_tooltip = false;
-bool QApplicationPrivate::fade_tooltip = false;
-bool QApplicationPrivate::animate_toolbox = false;
-bool QApplicationPrivate::widgetCount = false;
-bool QApplicationPrivate::load_testability = false;
-QString QApplicationPrivate::qmljs_debug_arguments;
-#ifdef QT_KEYPAD_NAVIGATION
-# ifdef Q_OS_SYMBIAN
-Qt::NavigationMode QApplicationPrivate::navigationMode = Qt::NavigationModeKeypadDirectional;
-# else
-Qt::NavigationMode QApplicationPrivate::navigationMode = Qt::NavigationModeKeypadTabOrder;
-# endif
-QWidget *QApplicationPrivate::oldEditFocus = 0;
-#endif
-
-bool qt_tabletChokeMouse = false;
-static bool force_reverse = false;
-
-inline bool QApplicationPrivate::isAlien(QWidget *widget)
-{
- if (!widget)
- return false;
-#if defined(Q_WS_QWS) || defined(Q_WS_QPA)
- return !widget->isWindow()
-# ifdef Q_BACKINGSTORE_SUBSURFACES
- && !(widget->d_func()->maybeTopData() && widget->d_func()->maybeTopData()->windowSurface)
-# endif
- ;
-#else
- return !widget->internalWinId();
-#endif
-}
-
-// ######## move to QApplicationPrivate
-// Default application palettes and fonts (per widget type)
-Q_GLOBAL_STATIC(PaletteHash, app_palettes)
-PaletteHash *qt_app_palettes_hash()
-{
- return app_palettes();
-}
-
-Q_GLOBAL_STATIC(FontHash, app_fonts)
-FontHash *qt_app_fonts_hash()
-{
- return app_fonts();
-}
-
-QWidgetList *QApplicationPrivate::popupWidgets = 0; // has keyboard input focus
-
-QDesktopWidget *qt_desktopWidget = 0; // root window widgets
-#ifndef QT_NO_CLIPBOARD
-QClipboard *qt_clipboard = 0; // global clipboard object
-#endif
-QWidgetList * qt_modal_stack=0; // stack of modal widgets
-
-/*!
- \internal
-*/
-void QApplicationPrivate::process_cmdline()
-{
- // process platform-indep command line
- if (!qt_is_gui_used || !argc)
- return;
-
- int i, j;
-
- j = 1;
- for (i=1; i<argc; i++) { // if you add anything here, modify QCoreApplication::arguments()
- if (argv[i] && *argv[i] != '-') {
- argv[j++] = argv[i];
- continue;
- }
- QByteArray arg = argv[i];
- arg = arg;
- QString s;
- if (arg == "-qdevel" || arg == "-qdebug") {
- // obsolete argument
- } else if (arg.indexOf("-qmljsdebugger=", 0) != -1) {
- qmljs_debug_arguments = QString::fromLocal8Bit(arg.right(arg.length() - 15));
- } else if (arg.indexOf("-style=", 0) != -1) {
- s = QString::fromLocal8Bit(arg.right(arg.length() - 7).toLower());
- } else if (arg == "-style" && i < argc-1) {
- s = QString::fromLocal8Bit(argv[++i]).toLower();
-#ifndef QT_NO_SESSIONMANAGER
- } else if (arg == "-session" && i < argc-1) {
- ++i;
- if (argv[i] && *argv[i]) {
- session_id = QString::fromLatin1(argv[i]);
- int p = session_id.indexOf(QLatin1Char('_'));
- if (p >= 0) {
- session_key = session_id.mid(p +1);
- session_id = session_id.left(p);
- }
- is_session_restored = true;
- }
-#endif
-#ifndef QT_NO_STYLE_STYLESHEET
- } else if (arg == "-stylesheet" && i < argc -1) {
- styleSheet = QLatin1String("file:///");
- styleSheet.append(QString::fromLocal8Bit(argv[++i]));
- } else if (arg.indexOf("-stylesheet=") != -1) {
- styleSheet = QLatin1String("file:///");
- styleSheet.append(QString::fromLocal8Bit(arg.right(arg.length() - 12)));
-#endif
- } else if (qstrcmp(arg, "-reverse") == 0) {
- force_reverse = true;
- QApplication::setLayoutDirection(Qt::RightToLeft);
- } else if (qstrcmp(arg, "-widgetcount") == 0) {
- widgetCount = true;
- } else if (qstrcmp(arg, "-testability") == 0) {
- load_testability = true;
- } else if (arg == "-graphicssystem" && i < argc-1) {
- graphics_system_name = QString::fromLocal8Bit(argv[++i]);
- } else {
- argv[j++] = argv[i];
- }
- if (!s.isEmpty()) {
- if (app_style) {
- delete app_style;
- app_style = 0;
- }
- styleOverride = s;
- }
- }
-
- if(j < argc) {
- argv[j] = 0;
- argc = j;
- }
-}
-
-/*!
- 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}.
- \o -qmljsdebugger=, activates the QML/JS debugger with a specified port.
- The value must be of format port:1234[,block], where block is optional
- and will make the application wait until a debugger connects to it.
- \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. Note that
- this option is ignored when Qt is built with fontconfig support enabled.
- \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
-
- \section1 X11 Notes
-
- If QApplication fails to open the X11 display, it will terminate
- the process. This behavior is consistent with most X11
- applications.
-
- \sa arguments()
-*/
-
-QApplication::QApplication(int &argc, char **argv)
- : QCoreApplication(*new QApplicationPrivate(argc, argv, GuiClient, 0x040000))
-{ Q_D(QApplication); d->construct(); }
-
-QApplication::QApplication(int &argc, char **argv, int _internal)
- : QCoreApplication(*new QApplicationPrivate(argc, argv, GuiClient, _internal))
-{ Q_D(QApplication); d->construct(); }
-
-
-/*!
- 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.
-
- 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 Mac OS, 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.
-
- \snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 0
-*/
-
-QApplication::QApplication(int &argc, char **argv, bool GUIenabled )
- : QCoreApplication(*new QApplicationPrivate(argc, argv, GUIenabled ? GuiClient : Tty, 0x040000))
-{ Q_D(QApplication); d->construct(); }
-
-QApplication::QApplication(int &argc, char **argv, bool GUIenabled , int _internal)
- : QCoreApplication(*new QApplicationPrivate(argc, argv, GUIenabled ? GuiClient : Tty, _internal))
-{ Q_D(QApplication); d->construct();}
-
-
-
-/*!
- 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.
-
- 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, 0x040000))
-{ Q_D(QApplication); d->construct(); }
-
-QApplication::QApplication(int &argc, char **argv, Type type , int _internal)
- : QCoreApplication(*new QApplicationPrivate(argc, argv, type, _internal))
-{ Q_D(QApplication); d->construct(); }
-
-#if defined(Q_WS_X11) && !defined(QT_NO_EGL)
-static int qt_matchLibraryName(dl_phdr_info *info, size_t, void *data)
-{
- const char *name = static_cast<const char *>(data);
- return strstr(info->dlpi_name, name) != 0;
-}
-#endif
-
-/*!
- \internal
-*/
-void QApplicationPrivate::construct(
-#ifdef Q_WS_X11
- Display *dpy, Qt::HANDLE visual, Qt::HANDLE cmap
-#endif
- )
-{
- initResources();
-
- qt_is_gui_used = (qt_appType != QApplication::Tty);
- process_cmdline();
- // the environment variable has the lowest precedence of runtime graphicssystem switches
- if (graphics_system_name.isEmpty())
- graphics_system_name = QString::fromLocal8Bit(qgetenv("QT_GRAPHICSSYSTEM"));
-
-#if defined(Q_WS_X11) && !defined(QT_NO_EGL)
- if (graphics_system_name.isEmpty()) {
- bool linksWithMeeGoTouch = dl_iterate_phdr(qt_matchLibraryName, const_cast<char *>("libmeegotouchcore"));
- bool linksWithMeeGoGraphicsSystemHelper = dl_iterate_phdr(qt_matchLibraryName, const_cast<char *>("libQtMeeGoGraphicsSystemHelper"));
-
- if (linksWithMeeGoTouch && !linksWithMeeGoGraphicsSystemHelper) {
- qWarning("Running non-meego graphics system enabled MeeGo touch, forcing native graphicssystem\n");
- graphics_system_name = QLatin1String("native");
- }
- }
-#endif
-
- // Must be called before initialize()
- qt_init(this, qt_appType
-#ifdef Q_WS_X11
- , dpy, visual, cmap
-#endif
- );
- initialize();
- eventDispatcher->startingUp();
-
-#ifdef QT_EVAL
- extern void qt_gui_eval_init(uint);
- qt_gui_eval_init(application_type);
-#endif
-
-#if defined(Q_OS_SYMBIAN) && !defined(QT_NO_SYSTEMLOCALE)
- symbianInit();
-#endif
-
-#ifndef QT_NO_LIBRARY
- if(load_testability) {
- QLibrary testLib(QLatin1String("qttestability"));
- if (testLib.load()) {
- typedef void (*TasInitialize)(void);
- TasInitialize initFunction = (TasInitialize)testLib.resolve("qt_testability_init");
-#ifdef Q_OS_SYMBIAN
- // resolving method by name does not work on Symbian OS so need to use ordinal
- if(!initFunction) {
- initFunction = (TasInitialize)testLib.resolve("1");
- }
-#endif
- if (initFunction) {
- initFunction();
- } else {
- qCritical("Library qttestability resolve failed!");
- }
- } else {
- qCritical("Library qttestability load failed!");
- }
- }
-
- //make sure the plugin is loaded
- if (qt_is_gui_used)
- qt_guiPlatformPlugin();
-#endif
-}
-
-#if defined(Q_WS_X11)
-// ### a string literal is a cont char*
-// ### using it as a char* is wrong and could lead to segfaults
-// ### if aargv is modified someday
-// ########## make it work with argc == argv == 0
-static int aargc = 1;
-static char *aargv[] = { (char*)"unknown", 0 };
-
-/*!
- \fn QApplication::QApplication(Display* display, Qt::HANDLE visual, Qt::HANDLE colormap)
-
- 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.
-
- This function is only available on X11.
-*/
-QApplication::QApplication(Display* dpy, Qt::HANDLE visual, Qt::HANDLE colormap)
- : QCoreApplication(*new QApplicationPrivate(aargc, aargv, GuiClient, 0x040000))
-{
- if (! dpy)
- qWarning("QApplication: Invalid Display* argument");
- Q_D(QApplication);
- d->construct(dpy, visual, colormap);
-}
-
-QApplication::QApplication(Display* dpy, Qt::HANDLE visual, Qt::HANDLE colormap, int _internal)
- : QCoreApplication(*new QApplicationPrivate(aargc, aargv, GuiClient, _internal))
-{
- if (! dpy)
- qWarning("QApplication: Invalid Display* argument");
- Q_D(QApplication);
- d->construct(dpy, visual, colormap);
- QApplicationPrivate::app_compile_version = _internal;
-}
-
-/*!
- \fn QApplication::QApplication(Display *display, int &argc, char **argv,
- Qt::HANDLE visual, Qt::HANDLE colormap)
-
- 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 function is only available on X11.
-*/
-QApplication::QApplication(Display *dpy, int &argc, char **argv,
- Qt::HANDLE visual, Qt::HANDLE colormap)
- : QCoreApplication(*new QApplicationPrivate(argc, argv, GuiClient, 0x040000))
-{
- if (! dpy)
- qWarning("QApplication: Invalid Display* argument");
- Q_D(QApplication);
- d->construct(dpy, visual, colormap);
-}
-
-QApplication::QApplication(Display *dpy, int &argc, char **argv,
- Qt::HANDLE visual, Qt::HANDLE colormap, int _internal)
- : QCoreApplication(*new QApplicationPrivate(argc, argv, GuiClient, _internal))
-{
- if (! dpy)
- qWarning("QApplication: Invalid Display* argument");
- Q_D(QApplication);
- d->construct(dpy, visual, colormap);
- QApplicationPrivate::app_compile_version = _internal;
-}
-
-#endif // Q_WS_X11
-
-extern void qInitDrawhelperAsm();
-extern void qInitImageConversions();
-extern int qRegisterGuiVariant();
-extern int qUnregisterGuiVariant();
-#ifndef QT_NO_STATEMACHINE
-extern int qRegisterGuiStateMachine();
-extern int qUnregisterGuiStateMachine();
-#endif
-
-/*!
- \fn void QApplicationPrivate::initialize()
-
- Initializes the QApplication object, called from the constructors.
-*/
-void QApplicationPrivate::initialize()
-{
- QWidgetPrivate::mapper = new QWidgetMapper;
- QWidgetPrivate::allWidgets = new QWidgetSet;
-
-#if !defined(Q_WS_X11) && !defined(Q_WS_QWS) && !defined(Q_WS_QPA)
- // initialize the graphics system - on X11 this is initialized inside
- // qt_init() in qapplication_x11.cpp because of several reasons.
- // On QWS, the graphics system is set by the QScreen plugin.
- // We don't use graphics systems in Qt QPA
- graphics_system = QGraphicsSystemFactory::create(graphics_system_name);
-#endif
-
- if (qt_appType != QApplication::Tty)
- (void) QApplication::style(); // trigger creation of application style
- // trigger registering of QVariant's GUI types
- qRegisterGuiVariant();
-#ifndef QT_NO_STATEMACHINE
- // trigger registering of QStateMachine's GUI types
- qRegisterGuiStateMachine();
-#endif
-
- is_app_running = true; // no longer starting up
-
- Q_Q(QApplication);
-#ifndef QT_NO_SESSIONMANAGER
- // connect to the session manager
- session_manager = new QSessionManager(q, session_id, session_key);
-#endif
-
- if (qgetenv("QT_USE_NATIVE_WINDOWS").toInt() > 0)
- q->setAttribute(Qt::AA_NativeWindows);
-
-#ifdef Q_WS_WINCE
-#ifdef QT_AUTO_MAXIMIZE_THRESHOLD
- autoMaximizeThreshold = QT_AUTO_MAXIMIZE_THRESHOLD;
-#else
- if (qt_wince_is_mobile())
- autoMaximizeThreshold = 50;
- else
- autoMaximizeThreshold = -1;
-#endif //QT_AUTO_MAXIMIZE_THRESHOLD
-#endif //Q_WS_WINCE
-
- // Set up which span functions should be used in raster engine...
- qInitDrawhelperAsm();
- // and QImage conversion functions
- qInitImageConversions();
-
-#ifndef QT_NO_WHEELEVENT
- QApplicationPrivate::wheel_scroll_lines = 3;
-#endif
-
- if (qt_is_gui_used)
- initializeMultitouch();
-}
-
-/*!
- Returns the type of application (\l Tty, GuiClient, or
- GuiServer). The type is set when constructing the QApplication
- object.
-*/
-QApplication::Type QApplication::type()
-{
- return qt_appType;
-}
-
-/*****************************************************************************
- Functions returning the active popup and modal widgets.
- *****************************************************************************/
-
-/*!
- 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.
-
- 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()
-*/
-
-QWidget *QApplication::activePopupWidget()
-{
- return QApplicationPrivate::popupWidgets && !QApplicationPrivate::popupWidgets->isEmpty() ?
- QApplicationPrivate::popupWidgets->last() : 0;
-}
-
-
-/*!
- 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.
-
- Modal widgets are organized in a stack. This function returns the active
- modal widget at the top of the stack.
-
- \sa activePopupWidget(), topLevelWidgets()
-*/
-
-QWidget *QApplication::activeModalWidget()
-{
- return qt_modal_stack && !qt_modal_stack->isEmpty() ? qt_modal_stack->first() : 0;
-}
-
-/*!
- Cleans up any window system resources that were allocated by this
- application. Sets the global variable \c qApp to 0.
-*/
-
-QApplication::~QApplication()
-{
- Q_D(QApplication);
-
-#ifndef QT_NO_CLIPBOARD
- // flush clipboard contents
- if (qt_clipboard) {
- QEvent event(QEvent::Clipboard);
- QApplication::sendEvent(qt_clipboard, &event);
- }
-#endif
-
- //### this should probable be done even later
- qt_call_post_routines();
-
- // kill timers before closing down the dispatcher
- d->toolTipWakeUp.stop();
- d->toolTipFallAsleep.stop();
-
- d->eventDispatcher->closingDown();
- d->eventDispatcher = 0;
- QApplicationPrivate::is_app_closing = true;
- QApplicationPrivate::is_app_running = false;
-
- delete QWidgetPrivate::mapper;
- QWidgetPrivate::mapper = 0;
-
- // delete all widgets
- if (QWidgetPrivate::allWidgets) {
- QWidgetSet *mySet = QWidgetPrivate::allWidgets;
- QWidgetPrivate::allWidgets = 0;
- for (QWidgetSet::ConstIterator it = mySet->constBegin(); it != mySet->constEnd(); ++it) {
- register QWidget *w = *it;
- if (!w->parent()) // window
- w->destroy(true, true);
- }
- delete mySet;
- }
-
- delete qt_desktopWidget;
- qt_desktopWidget = 0;
-
-#ifndef QT_NO_CLIPBOARD
- delete qt_clipboard;
- qt_clipboard = 0;
-#endif
-
-#if defined(Q_WS_X11) || defined(Q_WS_WIN)
- delete d->move_cursor; d->move_cursor = 0;
- delete d->copy_cursor; d->copy_cursor = 0;
- delete d->link_cursor; d->link_cursor = 0;
-#endif
-#if defined(Q_WS_WIN)
- delete d->ignore_cursor; d->ignore_cursor = 0;
-#endif
-
- delete QApplicationPrivate::app_pal;
- QApplicationPrivate::app_pal = 0;
- delete QApplicationPrivate::sys_pal;
- QApplicationPrivate::sys_pal = 0;
- delete QApplicationPrivate::set_pal;
- QApplicationPrivate::set_pal = 0;
- app_palettes()->clear();
-
- {
- QMutexLocker locker(applicationFontMutex());
- delete QApplicationPrivate::app_font;
- QApplicationPrivate::app_font = 0;
- }
- delete QApplicationPrivate::sys_font;
- QApplicationPrivate::sys_font = 0;
- delete QApplicationPrivate::set_font;
- QApplicationPrivate::set_font = 0;
- app_fonts()->clear();
-
- delete QApplicationPrivate::app_style;
- QApplicationPrivate::app_style = 0;
- delete QApplicationPrivate::app_icon;
- QApplicationPrivate::app_icon = 0;
- delete QApplicationPrivate::graphics_system;
- QApplicationPrivate::graphics_system = 0;
-#ifndef QT_NO_CURSOR
- d->cursor_list.clear();
-#endif
-
-#ifndef QT_NO_DRAGANDDROP
- if (qt_is_gui_used)
- delete QDragManager::self();
-#endif
-
- d->cleanupMultitouch();
-
- qt_cleanup();
-
- if (QApplicationPrivate::widgetCount)
- qDebug("Widgets left: %i Max widgets: %i \n", QWidgetPrivate::instanceCounter, QWidgetPrivate::maxInstances);
-#ifndef QT_NO_SESSIONMANAGER
- delete d->session_manager;
- d->session_manager = 0;
-#endif //QT_NO_SESSIONMANAGER
-
- QApplicationPrivate::obey_desktop_settings = true;
- QApplicationPrivate::cursor_flash_time = 1000;
- QApplicationPrivate::mouse_double_click_time = 400;
- QApplicationPrivate::keyboard_input_time = 400;
-
- drag_time = 500;
- drag_distance = 4;
- layout_direction = Qt::LeftToRight;
- QApplicationPrivate::app_strut = QSize(0, 0);
- QApplicationPrivate::animate_ui = true;
- QApplicationPrivate::animate_menu = false;
- QApplicationPrivate::fade_menu = false;
- QApplicationPrivate::animate_combo = false;
- QApplicationPrivate::animate_tooltip = false;
- QApplicationPrivate::fade_tooltip = false;
- QApplicationPrivate::widgetCount = false;
-
-#ifndef QT_NO_STATEMACHINE
- // trigger unregistering of QStateMachine's GUI types
- qUnregisterGuiStateMachine();
-#endif
- // trigger unregistering of QVariant's GUI types
- qUnregisterGuiVariant();
-}
-
-
-/*!
- \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.
-
- This function can be slow.
-
- \sa QCursor::pos(), QWidget::grabMouse(), QWidget::grabKeyboard()
-*/
-QWidget *QApplication::widgetAt(const QPoint &p)
-{
- QWidget *window = QApplication::topLevelAt(p);
- if (!window)
- return 0;
-
- QWidget *child = 0;
-
- if (!window->testAttribute(Qt::WA_TransparentForMouseEvents))
- child = window->childAt(window->mapFromGlobal(p));
-
- if (child)
- return child;
-
- if (window->testAttribute(Qt::WA_TransparentForMouseEvents)) {
- //shoot a hole in the widget and try once again,
- //suboptimal on Qt for Embedded Linux where we do
- //know the stacking order of the toplevels.
- int x = p.x();
- int y = p.y();
- QRegion oldmask = window->mask();
- QPoint wpoint = window->mapFromGlobal(QPoint(x, y));
- QRegion newmask = (oldmask.isEmpty() ? QRegion(window->rect()) : oldmask)
- - QRegion(wpoint.x(), wpoint.y(), 1, 1);
- window->setMask(newmask);
- QWidget *recurse = 0;
- if (QApplication::topLevelAt(p) != window) // verify recursion will terminate
- recurse = widgetAt(x, y);
- if (oldmask.isEmpty())
- window->clearMask();
- else
- window->setMask(oldmask);
- return recurse;
- }
- return window;
-}
-
-/*!
- \fn QWidget *QApplication::widgetAt(int x, int y)
-
- \overload
-
- Returns the widget at global screen position (\a x, \a y), or 0 if there is
- no Qt widget there.
-*/
-
-/*!
- \fn void QApplication::setArgs(int argc, char **argv)
- \internal
-*/
-
-
-
-/*!
- \internal
-*/
-bool QApplication::compressEvent(QEvent *event, QObject *receiver, QPostEventList *postedEvents)
-{
- if ((event->type() == QEvent::UpdateRequest
-#ifdef QT3_SUPPORT
- || event->type() == QEvent::LayoutHint
-#endif
- || event->type() == QEvent::LayoutRequest
- || event->type() == QEvent::Resize
- || event->type() == QEvent::Move
- || event->type() == QEvent::LanguageChange
- || event->type() == QEvent::UpdateSoftKeys
- || event->type() == QEvent::InputMethod)) {
- for (QPostEventList::const_iterator it = postedEvents->constBegin(); it != postedEvents->constEnd(); ++it) {
- const QPostEvent &cur = *it;
- if (cur.receiver != receiver || cur.event == 0 || cur.event->type() != event->type())
- continue;
- if (cur.event->type() == QEvent::LayoutRequest
-#ifdef QT3_SUPPORT
- || cur.event->type() == QEvent::LayoutHint
-#endif
- || cur.event->type() == QEvent::UpdateRequest) {
- ;
- } else if (cur.event->type() == QEvent::Resize) {
- ((QResizeEvent *)(cur.event))->s = ((QResizeEvent *)event)->s;
- } else if (cur.event->type() == QEvent::Move) {
- ((QMoveEvent *)(cur.event))->p = ((QMoveEvent *)event)->p;
- } else if (cur.event->type() == QEvent::LanguageChange) {
- ;
- } else if (cur.event->type() == QEvent::UpdateSoftKeys) {
- ;
- } else if ( cur.event->type() == QEvent::InputMethod ) {
- *(QInputMethodEvent *)(cur.event) = *(QInputMethodEvent *)event;
- } else {
- continue;
- }
- delete event;
- return true;
- }
- return false;
- }
- return QCoreApplication::compressEvent(event, receiver, postedEvents);
-}
-
-/*!
- \property QApplication::styleSheet
- \brief the application style sheet
- \since 4.2
-
- By default, this property returns an empty string unless the user specifies
- the \c{-stylesheet} option on the command line when running the application.
-
- \sa QWidget::setStyle(), {Qt Style Sheets}
-*/
-
-/*!
- \property QApplication::autoMaximizeThreshold
- \since 4.4
- \brief defines a threshold for auto maximizing widgets
-
- \bold{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 cause the window to be maximized
- automatically.
-
- Setting the threshold to 100 or greater means that the widget will always
- be maximized. Alternatively, setting the threshold to 50 means that the
- widget will be maximized only if the vertical minimum size hint is at least
- 50% of the vertical screen size.
-
- Setting the threshold to -1 disables the feature.
-
- On Windows CE the default is -1 (i.e., it is disabled).
- On Windows Mobile the default is 40.
-*/
-
-/*!
- \property QApplication::autoSipEnabled
- \since 4.5
- \brief toggles automatic SIP (software input panel) visibility
-
- Set this property to \c true to automatically display the SIP when entering
- widgets that accept keyboard input. This property only affects widgets with
- the WA_InputMethodEnabled attribute set, and is typically used to launch
- a virtual keyboard on devices which have very few or no keys.
-
- \bold{ The property only has an effect on platforms which use software input
- panels, such as Windows CE and Symbian.}
-
- The default is platform dependent.
-*/
-
-#ifdef Q_WS_WINCE
-void QApplication::setAutoMaximizeThreshold(const int threshold)
-{
- QApplicationPrivate::autoMaximizeThreshold = threshold;
-}
-
-int QApplication::autoMaximizeThreshold() const
-{
- return QApplicationPrivate::autoMaximizeThreshold;
-}
-#endif
-
-void QApplication::setAutoSipEnabled(const bool enabled)
-{
- QApplicationPrivate::autoSipEnabled = enabled;
-}
-
-bool QApplication::autoSipEnabled() const
-{
- return QApplicationPrivate::autoSipEnabled;
-}
-
-#ifndef QT_NO_STYLE_STYLESHEET
-
-QString QApplication::styleSheet() const
-{
- return QApplicationPrivate::styleSheet;
-}
-
-void QApplication::setStyleSheet(const QString& styleSheet)
-{
- QApplicationPrivate::styleSheet = styleSheet;
- QStyleSheetStyle *proxy = qobject_cast<QStyleSheetStyle*>(QApplicationPrivate::app_style);
- if (styleSheet.isEmpty()) { // application style sheet removed
- if (!proxy)
- return; // there was no stylesheet before
- setStyle(proxy->base);
- } else if (proxy) { // style sheet update, just repolish
- proxy->repolish(qApp);
- } else { // stylesheet set the first time
- QStyleSheetStyle *newProxy = new QStyleSheetStyle(QApplicationPrivate::app_style);
- QApplicationPrivate::app_style->setParent(newProxy);
- setStyle(newProxy);
- }
-}
-
-#endif // QT_NO_STYLE_STYLESHEET
-
-/*!
- Returns the application's style object.
-
- \sa setStyle(), QStyle
-*/
-QStyle *QApplication::style()
-{
- if (QApplicationPrivate::app_style)
- return QApplicationPrivate::app_style;
- if (!qt_is_gui_used) {
- Q_ASSERT(!"No style available in non-gui applications!");
- return 0;
- }
-
- if (!QApplicationPrivate::app_style) {
- // Compile-time search for default style
- //
- QString style;
-#ifdef QT_BUILD_INTERNAL
- QString envStyle = QString::fromLocal8Bit(qgetenv("QT_STYLE_OVERRIDE"));
-#else
- QString envStyle;
-#endif
- if (!QApplicationPrivate::styleOverride.isEmpty()) {
- style = QApplicationPrivate::styleOverride;
- } else if (!envStyle.isEmpty()) {
- style = envStyle;
- } else {
- style = QApplicationPrivate::desktopStyleKey();
- }
-
- QStyle *&app_style = QApplicationPrivate::app_style;
- app_style = QStyleFactory::create(style);
- if (!app_style) {
- QStringList styles = QStyleFactory::keys();
- for (int i = 0; i < styles.size(); ++i) {
- if ((app_style = QStyleFactory::create(styles.at(i))))
- break;
- }
- }
- if (!app_style) {
- Q_ASSERT(!"No styles available!");
- return 0;
- }
- }
- // take ownership of the style
- QApplicationPrivate::app_style->setParent(qApp);
-
- if (!QApplicationPrivate::sys_pal)
- QApplicationPrivate::setSystemPalette(QApplicationPrivate::app_style->standardPalette());
- if (QApplicationPrivate::set_pal) // repolish set palette with the new style
- QApplication::setPalette(*QApplicationPrivate::set_pal);
-
-#ifndef QT_NO_STYLE_STYLESHEET
- if (!QApplicationPrivate::styleSheet.isEmpty()) {
- qApp->setStyleSheet(QApplicationPrivate::styleSheet);
- } else
-#endif
- QApplicationPrivate::app_style->polish(qApp);
-
- return QApplicationPrivate::app_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.
-
- 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.
-
- 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.
-
- \sa style(), QStyle, setPalette(), desktopSettingsAware()
-*/
-void QApplication::setStyle(QStyle *style)
-{
- if (!style || style == QApplicationPrivate::app_style)
- return;
-
- QWidgetList all = allWidgets();
-
- // clean up the old style
- if (QApplicationPrivate::app_style) {
- if (QApplicationPrivate::is_app_running && !QApplicationPrivate::is_app_closing) {
- for (QWidgetList::ConstIterator it = all.constBegin(); it != all.constEnd(); ++it) {
- register QWidget *w = *it;
- if (!(w->windowType() == Qt::Desktop) && // except desktop
- w->testAttribute(Qt::WA_WState_Polished)) { // has been polished
- QApplicationPrivate::app_style->unpolish(w);
- }
- }
- }
- QApplicationPrivate::app_style->unpolish(qApp);
- }
-
- QStyle *old = QApplicationPrivate::app_style; // save
-
-#ifndef QT_NO_STYLE_STYLESHEET
- if (!QApplicationPrivate::styleSheet.isEmpty() && !qobject_cast<QStyleSheetStyle *>(style)) {
- // we have a stylesheet already and a new style is being set
- QStyleSheetStyle *newProxy = new QStyleSheetStyle(style);
- style->setParent(newProxy);
- QApplicationPrivate::app_style = newProxy;
- } else
-#endif // QT_NO_STYLE_STYLESHEET
- QApplicationPrivate::app_style = style;
- QApplicationPrivate::app_style->setParent(qApp); // take ownership
-
- // take care of possible palette requirements of certain gui
- // styles. Do it before polishing the application since the style
- // might call QApplication::setPalette() itself
- if (QApplicationPrivate::set_pal) {
- QApplication::setPalette(*QApplicationPrivate::set_pal);
- } else if (QApplicationPrivate::sys_pal) {
- QApplicationPrivate::initializeWidgetPaletteHash();
- QApplicationPrivate::setPalette_helper(*QApplicationPrivate::sys_pal, /*className=*/0, /*clearWidgetPaletteHash=*/false);
- } else if (!QApplicationPrivate::sys_pal) {
- // Initialize the sys_pal if it hasn't happened yet...
- QApplicationPrivate::setSystemPalette(QApplicationPrivate::app_style->standardPalette());
- }
-
- // initialize the application with the new style
- QApplicationPrivate::app_style->polish(qApp);
-
- // re-polish existing widgets if necessary
- if (QApplicationPrivate::is_app_running && !QApplicationPrivate::is_app_closing) {
- for (QWidgetList::ConstIterator it1 = all.constBegin(); it1 != all.constEnd(); ++it1) {
- register QWidget *w = *it1;
- if (w->windowType() != Qt::Desktop && w->testAttribute(Qt::WA_WState_Polished)) {
- if (w->style() == QApplicationPrivate::app_style)
- QApplicationPrivate::app_style->polish(w); // repolish
-#ifndef QT_NO_STYLE_STYLESHEET
- else
- w->setStyleSheet(w->styleSheet()); // touch
-#endif
- }
- }
-
- for (QWidgetList::ConstIterator it2 = all.constBegin(); it2 != all.constEnd(); ++it2) {
- register QWidget *w = *it2;
- if (w->windowType() != Qt::Desktop && !w->testAttribute(Qt::WA_SetStyle)) {
- QEvent e(QEvent::StyleChange);
- QApplication::sendEvent(w, &e);
-#ifdef QT3_SUPPORT
- if (old)
- w->styleChange(*old);
-#endif
- w->update();
- }
- }
- }
-
-#ifndef QT_NO_STYLE_STYLESHEET
- if (QStyleSheetStyle *oldProxy = qobject_cast<QStyleSheetStyle *>(old)) {
- oldProxy->deref();
- } else
-#endif
- if (old && old->parent() == qApp) {
- delete old;
- }
-
- if (QApplicationPrivate::focus_widget) {
- QFocusEvent in(QEvent::FocusIn, Qt::OtherFocusReason);
- QApplication::sendEvent(QApplicationPrivate::focus_widget->style(), &in);
- QApplicationPrivate::focus_widget->update();
- }
-}
-
-/*!
- \overload
-
- 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.
-
- 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.
-*/
-QStyle* QApplication::setStyle(const QString& style)
-{
- QStyle *s = QStyleFactory::create(style);
- if (!s)
- return 0;
-
- setStyle(s);
- return s;
-}
-
-/*!
- \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"}.
-
- There are several ways to set the graphics backend, in order of decreasing
- precedence:
- \list
- \o the application commandline \c{-graphicssystem} switch
- \o QApplication::setGraphicsSystem()
- \o the QT_GRAPHICSSYSTEM environment variable
- \o the Qt configure \c{-graphicssystem} switch
- \endlist
- If the highest precedence switch sets an invalid name, the error will be
- ignored and the default backend will be used.
-
- \warning This function is only effective before the QApplication constructor
- is called.
-
- \note The \c{"opengl"} option is currently experimental.
-*/
-
-void QApplication::setGraphicsSystem(const QString &system)
-{
-#ifdef Q_WS_QPA
- Q_UNUSED(system);
-#else
-# ifdef QT_GRAPHICSSYSTEM_RUNTIME
- if (QApplicationPrivate::graphics_system_name == QLatin1String("runtime")) {
- QRuntimeGraphicsSystem *r =
- static_cast<QRuntimeGraphicsSystem *>(QApplicationPrivate::graphics_system);
- r->setGraphicsSystem(system);
- } else
-# endif
- QApplicationPrivate::graphics_system_name = system;
-#endif
-}
-
-/*!
- Returns the color specification.
-
- \sa QApplication::setColorSpec()
-*/
-
-int QApplication::colorSpec()
-{
- return QApplicationPrivate::app_cspec;
-}
-
-/*!
- 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 the Windows platform, 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
-
- 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:
-
- \snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 2
-
- \sa colorSpec()
-*/
-
-void QApplication::setColorSpec(int spec)
-{
- if (qApp)
- qWarning("QApplication::setColorSpec: This function must be "
- "called before the QApplication object is created");
- QApplicationPrivate::app_cspec = spec;
-}
-
-/*!
- \property QApplication::globalStrut
- \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.
-
- Example:
-
- \snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 3
-
- By default, this property contains a QSize object with zero width and height.
-*/
-QSize QApplication::globalStrut()
-{
- return QApplicationPrivate::app_strut;
-}
-
-void QApplication::setGlobalStrut(const QSize& strut)
-{
- QApplicationPrivate::app_strut = strut;
-}
-
-/*!
- Returns the application palette.
-
- \sa setPalette(), QWidget::palette()
-*/
-QPalette QApplication::palette()
-{
- if (!QApplicationPrivate::app_pal)
- QApplicationPrivate::app_pal = new QPalette(Qt::black);
- return *QApplicationPrivate::app_pal;
-}
-
-/*!
- \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 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()
-*/
-QPalette QApplication::palette(const QWidget* w)
-{
- PaletteHash *hash = app_palettes();
- if (w && hash && hash->size()) {
- QHash<QByteArray, QPalette>::ConstIterator it = hash->constFind(w->metaObject()->className());
- if (it != hash->constEnd())
- return *it;
- for (it = hash->constBegin(); it != hash->constEnd(); ++it) {
- if (w->inherits(it.key()))
- return it.value();
- }
- }
- return palette();
-}
-
-/*!
- \overload
-
- Returns the palette for widgets of the given \a className.
-
- \sa setPalette(), QWidget::palette()
-*/
-QPalette QApplication::palette(const char *className)
-{
- if (!QApplicationPrivate::app_pal)
- palette();
- PaletteHash *hash = app_palettes();
- if (className && hash && hash->size()) {
- QHash<QByteArray, QPalette>::ConstIterator it = hash->constFind(className);
- if (it != hash->constEnd())
- return *it;
- }
- return *QApplicationPrivate::app_pal;
-}
-
-void QApplicationPrivate::setPalette_helper(const QPalette &palette, const char* className, bool clearWidgetPaletteHash)
-{
- QPalette pal = palette;
-
- if (QApplicationPrivate::app_style)
- QApplicationPrivate::app_style->polish(pal); // NB: non-const reference
-
- bool all = false;
- PaletteHash *hash = app_palettes();
- if (!className) {
- if (QApplicationPrivate::app_pal && pal.isCopyOf(*QApplicationPrivate::app_pal))
- return;
- if (!QApplicationPrivate::app_pal)
- QApplicationPrivate::app_pal = new QPalette(pal);
- else
- *QApplicationPrivate::app_pal = pal;
- if (hash && hash->size()) {
- all = true;
- if (clearWidgetPaletteHash)
- hash->clear();
- }
- } else if (hash) {
- hash->insert(className, pal);
- }
-
- if (QApplicationPrivate::is_app_running && !QApplicationPrivate::is_app_closing) {
- // Send ApplicationPaletteChange to qApp itself, and to the widgets.
- QEvent e(QEvent::ApplicationPaletteChange);
- QApplication::sendEvent(QApplication::instance(), &e);
-
- QWidgetList wids = QApplication::allWidgets();
- for (QWidgetList::ConstIterator it = wids.constBegin(); it != wids.constEnd(); ++it) {
- register QWidget *w = *it;
- if (all || (!className && w->isWindow()) || w->inherits(className)) // matching class
- QApplication::sendEvent(w, &e);
- }
-
- // Send to all scenes as well.
-#ifndef QT_NO_GRAPHICSVIEW
- QList<QGraphicsScene *> &scenes = qApp->d_func()->scene_list;
- for (QList<QGraphicsScene *>::ConstIterator it = scenes.constBegin();
- it != scenes.constEnd(); ++it) {
- QApplication::sendEvent(*it, &e);
- }
-#endif //QT_NO_GRAPHICSVIEW
- }
- if (!className && (!QApplicationPrivate::sys_pal || !palette.isCopyOf(*QApplicationPrivate::sys_pal))) {
- if (!QApplicationPrivate::set_pal)
- QApplicationPrivate::set_pal = new QPalette(palette);
- else
- *QApplicationPrivate::set_pal = 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.
-
- 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".
-
- \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()
-*/
-
-void QApplication::setPalette(const QPalette &palette, const char* className)
-{
- QApplicationPrivate::setPalette_helper(palette, className, /*clearWidgetPaletteHash=*/ true);
-}
-
-
-
-void QApplicationPrivate::setSystemPalette(const QPalette &pal)
-{
- QPalette adjusted;
-
-#if 0
- // adjust the system palette to avoid dithering
- QColormap cmap = QColormap::instance();
- if (cmap.depths() > 4 && cmap.depths() < 24) {
- for (int g = 0; g < QPalette::NColorGroups; g++)
- for (int i = 0; i < QPalette::NColorRoles; i++) {
- QColor color = pal.color((QPalette::ColorGroup)g, (QPalette::ColorRole)i);
- color = cmap.colorAt(cmap.pixel(color));
- adjusted.setColor((QPalette::ColorGroup)g, (QPalette::ColorRole) i, color);
- }
- }
-#else
- adjusted = pal;
-#endif
-
- if (!sys_pal)
- sys_pal = new QPalette(adjusted);
- else
- *sys_pal = adjusted;
-
-
- if (!QApplicationPrivate::set_pal)
- QApplication::setPalette(*sys_pal);
-}
-
-/*!
- Returns the default application font.
-
- \sa fontMetrics(), QWidget::font()
-*/
-QFont QApplication::font()
-{
- QMutexLocker locker(applicationFontMutex());
- if (!QApplicationPrivate::app_font)
- QApplicationPrivate::app_font = new QFont(QLatin1String("Helvetica"));
- return *QApplicationPrivate::app_font;
-}
-
-/*!
- \overload
-
- Returns the default font for the \a widget.
-
- \sa fontMetrics(), QWidget::setFont()
-*/
-
-QFont QApplication::font(const QWidget *widget)
-{
- FontHash *hash = app_fonts();
-
-#ifdef Q_WS_MAC
- // short circuit for small and mini controls
- if (widget->testAttribute(Qt::WA_MacSmallSize)) {
- return hash->value("QSmallFont");
- } else if (widget->testAttribute(Qt::WA_MacMiniSize)) {
- return hash->value("QMiniFont");
- }
-#endif
- if (widget && hash && hash->size()) {
- QHash<QByteArray, QFont>::ConstIterator it =
- hash->constFind(widget->metaObject()->className());
- if (it != hash->constEnd())
- return it.value();
- for (it = hash->constBegin(); it != hash->constEnd(); ++it) {
- if (widget->inherits(it.key()))
- return it.value();
- }
- }
- return font();
-}
-
-/*!
- \overload
-
- Returns the font for widgets of the given \a className.
-
- \sa setFont(), QWidget::font()
-*/
-QFont QApplication::font(const char *className)
-{
- FontHash *hash = app_fonts();
- if (className && hash && hash->size()) {
- QHash<QByteArray, QFont>::ConstIterator it = hash->constFind(className);
- if (it != hash->constEnd())
- return *it;
- }
- return font();
-}
-
-
-/*!
- 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.
-
- \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
- property. To set a bold font for all QPushButtons, set the application
- styleSheet() as "QPushButton { font: bold }"
-
- \sa font(), fontMetrics(), QWidget::setFont()
-*/
-
-void QApplication::setFont(const QFont &font, const char *className)
-{
- bool all = false;
- FontHash *hash = app_fonts();
- if (!className) {
- QMutexLocker locker(applicationFontMutex());
- if (!QApplicationPrivate::app_font)
- QApplicationPrivate::app_font = new QFont(font);
- else
- *QApplicationPrivate::app_font = font;
- if (hash && hash->size()) {
- all = true;
- hash->clear();
- }
- } else if (hash) {
- hash->insert(className, font);
- }
- if (QApplicationPrivate::is_app_running && !QApplicationPrivate::is_app_closing) {
- // Send ApplicationFontChange to qApp itself, and to the widgets.
- QEvent e(QEvent::ApplicationFontChange);
- QApplication::sendEvent(QApplication::instance(), &e);
-
- QWidgetList wids = QApplication::allWidgets();
- for (QWidgetList::ConstIterator it = wids.constBegin(); it != wids.constEnd(); ++it) {
- register QWidget *w = *it;
- if (all || (!className && w->isWindow()) || w->inherits(className)) // matching class
- sendEvent(w, &e);
- }
-
-#ifndef QT_NO_GRAPHICSVIEW
- // Send to all scenes as well.
- QList<QGraphicsScene *> &scenes = qApp->d_func()->scene_list;
- for (QList<QGraphicsScene *>::ConstIterator it = scenes.constBegin();
- it != scenes.constEnd(); ++it) {
- QApplication::sendEvent(*it, &e);
- }
-#endif //QT_NO_GRAPHICSVIEW
- }
- if (!className && (!QApplicationPrivate::sys_font || !font.isCopyOf(*QApplicationPrivate::sys_font))) {
- if (!QApplicationPrivate::set_font)
- QApplicationPrivate::set_font = new QFont(font);
- else
- *QApplicationPrivate::set_font = font;
- }
-}
-
-/*! \internal
-*/
-void QApplicationPrivate::setSystemFont(const QFont &font)
-{
- if (!sys_font)
- sys_font = new QFont(font);
- else
- *sys_font = font;
-
- if (!QApplicationPrivate::set_font)
- QApplication::setFont(*sys_font);
-}
-
-/*! \internal
-*/
-QString QApplicationPrivate::desktopStyleKey()
-{
- return qt_guiPlatformPlugin()->styleName();
-}
-
-/*!
- \property QApplication::windowIcon
- \brief the default window icon
-
- \sa QWidget::setWindowIcon(), {Setting the Application Icon}
-*/
-QIcon QApplication::windowIcon()
-{
- return QApplicationPrivate::app_icon ? *QApplicationPrivate::app_icon : QIcon();
-}
-
-void QApplication::setWindowIcon(const QIcon &icon)
-{
- if (!QApplicationPrivate::app_icon)
- QApplicationPrivate::app_icon = new QIcon();
- *QApplicationPrivate::app_icon = icon;
- if (QApplicationPrivate::is_app_running && !QApplicationPrivate::is_app_closing) {
-#ifdef Q_WS_MAC
- void qt_mac_set_app_icon(const QPixmap &); //qapplication_mac.cpp
- QSize size = QApplicationPrivate::app_icon->actualSize(QSize(128, 128));
- qt_mac_set_app_icon(QApplicationPrivate::app_icon->pixmap(size));
-#endif
- QEvent e(QEvent::ApplicationWindowIconChange);
- QWidgetList all = QApplication::allWidgets();
- for (QWidgetList::ConstIterator it = all.constBegin(); it != all.constEnd(); ++it) {
- register QWidget *w = *it;
- if (w->isWindow())
- sendEvent(w, &e);
- }
- }
-}
-
-/*!
- Returns a list of the top-level widgets (windows) in the application.
-
- \note Some of the top-level widgets may be hidden, for example a tooltip if
- no tooltip is currently shown.
-
- Example:
-
- \snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 4
-
- \sa allWidgets(), QWidget::isWindow(), QWidget::isHidden()
-*/
-QWidgetList QApplication::topLevelWidgets()
-{
- QWidgetList list;
- QWidgetList all = allWidgets();
-
- for (QWidgetList::ConstIterator it = all.constBegin(); it != all.constEnd(); ++it) {
- QWidget *w = *it;
- if (w->isWindow() && w->windowType() != Qt::Desktop)
- list.append(w);
- }
- return list;
-}
-
-/*!
- Returns a list of all the widgets in the application.
-
- The list is empty (QList::isEmpty()) if there are no widgets.
-
- \note Some of the widgets may be hidden.
-
- Example:
- \snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 5
-
- \sa topLevelWidgets(), QWidget::isVisible()
-*/
-
-QWidgetList QApplication::allWidgets()
-{
- if (QWidgetPrivate::allWidgets)
- return QWidgetPrivate::allWidgets->toList();
- return QWidgetList();
-}
-
-/*!
- 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()
-*/
-
-QWidget *QApplication::focusWidget()
-{
- return QApplicationPrivate::focus_widget;
-}
-
-void QApplicationPrivate::setFocusWidget(QWidget *focus, Qt::FocusReason reason)
-{
-#ifndef QT_NO_GRAPHICSVIEW
- if (focus && focus->window()->graphicsProxyWidget())
- return;
-#endif
-
- hidden_focus_widget = 0;
-
- if (focus != focus_widget) {
- if (focus && focus->isHidden()) {
- hidden_focus_widget = focus;
- return;
- }
-
- if (focus && (reason == Qt::BacktabFocusReason || reason == Qt::TabFocusReason)
- && qt_in_tab_key_event)
- focus->window()->setAttribute(Qt::WA_KeyboardFocusChange);
- else if (focus && reason == Qt::ShortcutFocusReason) {
- focus->window()->setAttribute(Qt::WA_KeyboardFocusChange);
- }
- QWidget *prev = focus_widget;
- focus_widget = focus;
-#ifndef QT_NO_IM
- 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);
- }
- }
-#endif //QT_NO_IM
-
- if(focus_widget)
- focus_widget->d_func()->setFocus_sys();
-
- if (reason != Qt::NoFocusReason) {
-
- //send events
- if (prev) {
-#ifdef QT_KEYPAD_NAVIGATION
- if (QApplication::keypadNavigationEnabled()) {
- if (prev->hasEditFocus() && reason != Qt::PopupFocusReason
-#ifdef Q_OS_SYMBIAN
- && reason != Qt::ActiveWindowFocusReason
-#endif
- )
- prev->setEditFocus(false);
- }
-#endif
-#ifndef QT_NO_IM
- if (focus) {
- QInputContext *prevIc;
- prevIc = prev->inputContext();
- if (prevIc && prevIc != focus->inputContext()) {
- QEvent closeSIPEvent(QEvent::CloseSoftwareInputPanel);
- QApplication::sendEvent(prev, &closeSIPEvent);
- }
- }
-#endif
- QFocusEvent out(QEvent::FocusOut, reason);
- QPointer<QWidget> that = prev;
- QApplication::sendEvent(prev, &out);
- if (that)
- QApplication::sendEvent(that->style(), &out);
- }
- if(focus && QApplicationPrivate::focus_widget == focus) {
-#ifndef QT_NO_IM
- if (focus->testAttribute(Qt::WA_InputMethodEnabled)) {
- QInputContext *qic = focus->inputContext();
- if (qic && focus->testAttribute(Qt::WA_WState_Created)
- && focus->isEnabled())
- qic->setFocusWidget(focus);
- }
-#endif //QT_NO_IM
- QFocusEvent in(QEvent::FocusIn, reason);
- QPointer<QWidget> that = focus;
- QApplication::sendEvent(focus, &in);
- if (that)
- QApplication::sendEvent(that->style(), &in);
- }
- emit qApp->focusChanged(prev, focus_widget);
- }
- }
-}
-
-
-/*!
- 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()
-*/
-
-QWidget *QApplication::activeWindow()
-{
- return QApplicationPrivate::active_window;
-}
-
-/*!
- Returns display (screen) font metrics for the application font.
-
- \sa font(), setFont(), QWidget::fontMetrics(), QPainter::fontMetrics()
-*/
-
-QFontMetrics QApplication::fontMetrics()
-{
- return desktop()->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:
-
- \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.
-
- \sa quitOnLastWindowClosed, lastWindowClosed(), QWidget::close(),
- QWidget::closeEvent(), lastWindowClosed(), quit(), topLevelWidgets(),
- QWidget::isWindow()
-*/
-void QApplication::closeAllWindows()
-{
- bool did_close = true;
- QWidget *w;
- while ((w = activeModalWidget()) && did_close) {
- if (!w->isVisible() || w->data->is_closing)
- break;
- did_close = w->close();
- }
- QWidgetList list = QApplication::topLevelWidgets();
- for (int i = 0; did_close && i < list.size(); ++i) {
- w = list.at(i);
- if (w->isVisible()
- && w->windowType() != Qt::Desktop
- && !w->data->is_closing) {
- did_close = w->close();
- list = QApplication::topLevelWidgets();
- i = -1;
- }
- }
-}
-
-/*!
- 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 function is a convenience slot for QMessageBox::aboutQt().
-*/
-void QApplication::aboutQt()
-{
-#ifndef QT_NO_MESSAGEBOX
- QMessageBox::aboutQt(
-#ifdef Q_WS_MAC
- 0
-#else
- activeWindow()
-#endif // Q_WS_MAC
- );
-#endif // QT_NO_MESSAGEBOX
-}
-
-
-/*!
- \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.
-
- By default,
-
- \list
- \o this attribute is set for all widgets except transient windows such
- as splash screens, tool windows, and popup menus
-
- \o QApplication implicitly quits when this signal is emitted.
- \endlist
-
- This feature can be turned off by setting \l quitOnLastWindowClosed to
- false.
-
- \sa QWidget::close()
-*/
-
-/*!
- \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. 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.
-
- \sa QWidget::setFocus(), QWidget::clearFocus(), Qt::FocusReason
-*/
-
-/*!
- \since 4.5
- \fn void QApplication::fontDatabaseChanged()
-
- This signal is emitted when application fonts are loaded or removed.
-
- \sa QFontDatabase::addApplicationFont(),
- QFontDatabase::addApplicationFontFromData(),
- QFontDatabase::removeAllApplicationFonts(),
- QFontDatabase::removeApplicationFont()
-*/
-
-#ifndef QT_NO_TRANSLATION
-static bool qt_detectRTLLanguage()
-{
- return force_reverse ^
- (QApplication::tr("QT_LAYOUT_DIRECTION",
- "Translate this string to the string 'LTR' in left-to-right"
- " languages or to 'RTL' in right-to-left languages (such as Hebrew"
- " and Arabic) to get proper widget layout.") == QLatin1String("RTL"));
-}
-#if defined(Q_WS_MAC)
-static const char *application_menu_strings[] = {
- QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Services"),
- QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Hide %1"),
- QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Hide Others"),
- QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Show All"),
- QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Preferences..."),
- QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Quit %1"),
- QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","About %1")
- };
-QString qt_mac_applicationmenu_string(int type)
-{
- QString menuString = QString::fromLatin1(application_menu_strings[type]);
- QString translated = qApp->translate("QMenuBar", application_menu_strings[type]);
- if (translated != menuString)
- return translated;
- else
- return qApp->translate("MAC_APPLICATION_MENU",
- application_menu_strings[type]);
-}
-#endif
-#endif
-
-/*!\reimp
-
-*/
-bool QApplication::event(QEvent *e)
-{
- Q_D(QApplication);
- if(e->type() == QEvent::Close) {
-#if defined(Q_OS_SYMBIAN)
- // In order to have proper application-exit effects on Symbian, certain
- // native APIs have to be called _before_ closing/destroying the widgets.
- bool effectStarted = qt_beginFullScreenEffect();
-#endif
- QCloseEvent *ce = static_cast<QCloseEvent*>(e);
- ce->accept();
- closeAllWindows();
-
- QWidgetList list = topLevelWidgets();
- for (int i = 0; i < list.size(); ++i) {
- QWidget *w = list.at(i);
- if (w->isVisible() && !(w->windowType() == Qt::Desktop) && !(w->windowType() == Qt::Popup) &&
- (!(w->windowType() == Qt::Dialog) || !w->parentWidget())) {
- ce->ignore();
- break;
- }
- }
- if (ce->isAccepted()) {
- return true;
- } else {
-#if defined(Q_OS_SYMBIAN)
- if (effectStarted)
- qt_abortFullScreenEffect();
-#endif
- }
- } else if(e->type() == QEvent::LanguageChange) {
-#ifndef QT_NO_TRANSLATION
- setLayoutDirection(qt_detectRTLLanguage()?Qt::RightToLeft:Qt::LeftToRight);
-#endif
-#if defined(QT_MAC_USE_COCOA)
- qt_mac_post_retranslateAppMenu();
-#endif
- QWidgetList list = topLevelWidgets();
- for (int i = 0; i < list.size(); ++i) {
- QWidget *w = list.at(i);
- if (!(w->windowType() == Qt::Desktop))
- postEvent(w, new QEvent(QEvent::LanguageChange));
- }
-#ifndef Q_OS_WIN
- } else if (e->type() == QEvent::LocaleChange) {
- // on Windows the event propagation is taken care by the
- // WM_SETTINGCHANGE event handler.
- QWidgetList list = topLevelWidgets();
- for (int i = 0; i < list.size(); ++i) {
- QWidget *w = list.at(i);
- if (!(w->windowType() == Qt::Desktop)) {
- if (!w->testAttribute(Qt::WA_SetLocale))
- w->d_func()->setLocale_helper(QLocale(), true);
- }
- }
-#endif
- } else if (e->type() == QEvent::Timer) {
- QTimerEvent *te = static_cast<QTimerEvent*>(e);
- Q_ASSERT(te != 0);
- if (te->timerId() == d->toolTipWakeUp.timerId()) {
- d->toolTipWakeUp.stop();
- if (d->toolTipWidget) {
- QWidget *w = d->toolTipWidget->window();
- // show tooltip if WA_AlwaysShowToolTips is set, or if
- // any ancestor of d->toolTipWidget is the active
- // window
- bool showToolTip = w->testAttribute(Qt::WA_AlwaysShowToolTips);
- while (w && !showToolTip) {
- showToolTip = w->isActiveWindow();
- w = w->parentWidget();
- w = w ? w->window() : 0;
- }
- if (showToolTip) {
- QHelpEvent e(QEvent::ToolTip, d->toolTipPos, d->toolTipGlobalPos);
- QApplication::sendEvent(d->toolTipWidget, &e);
- if (e.isAccepted())
- d->toolTipFallAsleep.start(2000, this);
- }
- }
- } else if (te->timerId() == d->toolTipFallAsleep.timerId()) {
- d->toolTipFallAsleep.stop();
- }
- }
- return QCoreApplication::event(e);
-}
-#if !defined(Q_WS_X11)
-
-// The doc and X implementation of this function is in qapplication_x11.cpp
-
-void QApplication::syncX() {} // do nothing
-
-#endif
-
-/*!
- \fn Qt::WindowsVersion QApplication::winVersion()
-
- Use \l QSysInfo::WindowsVersion instead.
-*/
-
-/*!
- \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.
-
- \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.
-
- \sa activeWindow(), QWidget::activateWindow()
-*/
-void QApplication::setActiveWindow(QWidget* act)
-{
- QWidget* window = act?act->window():0;
-
- if (QApplicationPrivate::active_window == window)
- return;
-
-#ifndef QT_NO_GRAPHICSVIEW
- if (window && window->graphicsProxyWidget()) {
- // Activate the proxy's view->viewport() ?
- return;
- }
-#endif
-
- QWidgetList toBeActivated;
- QWidgetList toBeDeactivated;
-
- if (QApplicationPrivate::active_window) {
- if (style()->styleHint(QStyle::SH_Widget_ShareActivation, 0, QApplicationPrivate::active_window)) {
- QWidgetList list = topLevelWidgets();
- for (int i = 0; i < list.size(); ++i) {
- QWidget *w = list.at(i);
- if (w->isVisible() && w->isActiveWindow())
- toBeDeactivated.append(w);
- }
- } else {
- toBeDeactivated.append(QApplicationPrivate::active_window);
- }
- }
-
-#if !defined(Q_WS_MAC)
- QWidget *previousActiveWindow = QApplicationPrivate::active_window;
-#endif
- QApplicationPrivate::active_window = window;
-
- if (QApplicationPrivate::active_window) {
- if (style()->styleHint(QStyle::SH_Widget_ShareActivation, 0, QApplicationPrivate::active_window)) {
- QWidgetList list = topLevelWidgets();
- for (int i = 0; i < list.size(); ++i) {
- QWidget *w = list.at(i);
- if (w->isVisible() && w->isActiveWindow())
- toBeActivated.append(w);
- }
- } else {
- toBeActivated.append(QApplicationPrivate::active_window);
- }
-
- }
-
- // first the activation/deactivation events
- QEvent activationChange(QEvent::ActivationChange);
- QEvent windowActivate(QEvent::WindowActivate);
- QEvent windowDeactivate(QEvent::WindowDeactivate);
-
-#if !defined(Q_WS_MAC)
- if (!previousActiveWindow) {
- QEvent appActivate(QEvent::ApplicationActivate);
- sendSpontaneousEvent(qApp, &appActivate);
- }
-#endif
-
- for (int i = 0; i < toBeActivated.size(); ++i) {
- QWidget *w = toBeActivated.at(i);
- sendSpontaneousEvent(w, &windowActivate);
- sendSpontaneousEvent(w, &activationChange);
- }
-
-#ifdef QT_MAC_USE_COCOA
- // In case the user clicked on a child window, we need to
- // reestablish the stacking order of the window so
- // it pops in front of other child windows in cocoa:
- qt_cocoaStackChildWindowOnTopOfOtherChildren(window);
-#endif
-
- for(int i = 0; i < toBeDeactivated.size(); ++i) {
- QWidget *w = toBeDeactivated.at(i);
- sendSpontaneousEvent(w, &windowDeactivate);
- sendSpontaneousEvent(w, &activationChange);
- }
-
-#if !defined(Q_WS_MAC)
- if (!QApplicationPrivate::active_window) {
- QEvent appDeactivate(QEvent::ApplicationDeactivate);
- sendSpontaneousEvent(qApp, &appDeactivate);
- }
-#endif
-
- if (QApplicationPrivate::popupWidgets == 0) { // !inPopupMode()
- // then focus events
- if (!QApplicationPrivate::active_window && QApplicationPrivate::focus_widget) {
- QApplicationPrivate::setFocusWidget(0, Qt::ActiveWindowFocusReason);
- } else if (QApplicationPrivate::active_window) {
- QWidget *w = QApplicationPrivate::active_window->focusWidget();
- if (w && w->isVisible() /*&& w->focusPolicy() != QWidget::NoFocus*/)
- w->setFocus(Qt::ActiveWindowFocusReason);
- else {
- w = QApplicationPrivate::focusNextPrevChild_helper(QApplicationPrivate::active_window, true);
- if (w) {
- w->setFocus(Qt::ActiveWindowFocusReason);
- } else {
- // If the focus widget is not in the activate_window, clear the focus
- w = QApplicationPrivate::focus_widget;
- 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);
- }
- }
- }
- }
-}
-
-/*!internal
- * Helper function that returns the new focus widget, but does not set the focus reason.
- * Returns 0 if a new focus widget could not be found.
- * Shared with QGraphicsProxyWidgetPrivate::findFocusChild()
-*/
-QWidget *QApplicationPrivate::focusNextPrevChild_helper(QWidget *toplevel, bool next)
-{
- uint focus_flag = qt_tab_all_widgets ? Qt::TabFocus : Qt::StrongFocus;
-
- QWidget *f = toplevel->focusWidget();
- if (!f)
- f = toplevel;
-
- QWidget *w = f;
- QWidget *test = f->d_func()->focus_next;
- while (test && test != f) {
- if ((test->focusPolicy() & focus_flag) == focus_flag
- && !(test->d_func()->extra && test->d_func()->extra->focus_proxy)
- && test->isVisibleTo(toplevel) && test->isEnabled()
- && !(w->windowType() == Qt::SubWindow && !w->isAncestorOf(test))
- && (toplevel->windowType() != Qt::SubWindow || toplevel->isAncestorOf(test))) {
- w = test;
- if (next)
- break;
- }
- test = test->d_func()->focus_next;
- }
- if (w == f) {
- if (qt_in_tab_key_event) {
- w->window()->setAttribute(Qt::WA_KeyboardFocusChange);
- w->update();
- }
- return 0;
- }
- return w;
-}
-
-/*!
- \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.
- */
-void QApplicationPrivate::dispatchEnterLeave(QWidget* enter, QWidget* leave) {
-#if 0
- if (leave) {
- QEvent e(QEvent::Leave);
- QApplication::sendEvent(leave, & e);
- }
- if (enter) {
- QEvent e(QEvent::Enter);
- QApplication::sendEvent(enter, & e);
- }
- return;
-#endif
-
- QWidget* w ;
- if ((!enter && !leave) || (enter == leave))
- return;
-#ifdef ALIEN_DEBUG
- qDebug() << "QApplicationPrivate::dispatchEnterLeave, ENTER:" << enter << "LEAVE:" << leave;
-#endif
- QWidgetList leaveList;
- QWidgetList enterList;
-
- bool sameWindow = leave && enter && leave->window() == enter->window();
- if (leave && !sameWindow) {
- w = leave;
- do {
- leaveList.append(w);
- } while (!w->isWindow() && (w = w->parentWidget()));
- }
- if (enter && !sameWindow) {
- w = enter;
- do {
- enterList.prepend(w);
- } while (!w->isWindow() && (w = w->parentWidget()));
- }
- if (sameWindow) {
- int enterDepth = 0;
- int leaveDepth = 0;
- w = enter;
- while (!w->isWindow() && (w = w->parentWidget()))
- enterDepth++;
- w = leave;
- while (!w->isWindow() && (w = w->parentWidget()))
- leaveDepth++;
- QWidget* wenter = enter;
- QWidget* wleave = leave;
- while (enterDepth > leaveDepth) {
- wenter = wenter->parentWidget();
- enterDepth--;
- }
- while (leaveDepth > enterDepth) {
- wleave = wleave->parentWidget();
- leaveDepth--;
- }
- while (!wenter->isWindow() && wenter != wleave) {
- wenter = wenter->parentWidget();
- wleave = wleave->parentWidget();
- }
-
- w = leave;
- while (w != wleave) {
- leaveList.append(w);
- w = w->parentWidget();
- }
- w = enter;
- while (w != wenter) {
- enterList.prepend(w);
- w = w->parentWidget();
- }
- }
-
- QEvent leaveEvent(QEvent::Leave);
- for (int i = 0; i < leaveList.size(); ++i) {
- w = leaveList.at(i);
- if (!QApplication::activeModalWidget() || QApplicationPrivate::tryModalHelper(w, 0)) {
-#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined(Q_WS_MAC)
- if (leaveAfterRelease == w)
- leaveAfterRelease = 0;
-#endif
- QApplication::sendEvent(w, &leaveEvent);
- if (w->testAttribute(Qt::WA_Hover) &&
- (!QApplication::activePopupWidget() || QApplication::activePopupWidget() == w->window())) {
- Q_ASSERT(instance());
- QHoverEvent he(QEvent::HoverLeave, QPoint(-1, -1), w->mapFromGlobal(QApplicationPrivate::instance()->hoverGlobalPos),
- QApplication::keyboardModifiers());
- qApp->d_func()->notify_helper(w, &he);
- }
- }
- }
- QPoint posEnter = QCursor::pos();
- QEvent enterEvent(QEvent::Enter);
- for (int i = 0; i < enterList.size(); ++i) {
- w = enterList.at(i);
- if (!QApplication::activeModalWidget() || QApplicationPrivate::tryModalHelper(w, 0)) {
- QApplication::sendEvent(w, &enterEvent);
- if (w->testAttribute(Qt::WA_Hover) &&
- (!QApplication::activePopupWidget() || QApplication::activePopupWidget() == w->window())) {
- QHoverEvent he(QEvent::HoverEnter, w->mapFromGlobal(posEnter), QPoint(-1, -1),
- QApplication::keyboardModifiers());
- qApp->d_func()->notify_helper(w, &he);
- }
- }
- }
-
-#ifndef QT_NO_CURSOR
- // Update cursor for alien/graphics widgets.
-
- const bool enterOnAlien = (enter && (isAlien(enter) || enter->testAttribute(Qt::WA_DontShowOnScreen)));
-#if defined(Q_WS_X11) || defined(Q_WS_QPA)
- //Whenever we leave an alien widget on X11, we need to reset its nativeParentWidget()'s cursor.
- // This is not required on Windows as the cursor is reset on every single mouse move.
- QWidget *parentOfLeavingCursor = 0;
- for (int i = 0; i < leaveList.size(); ++i) {
- w = leaveList.at(i);
- if (!isAlien(w))
- break;
- if (w->testAttribute(Qt::WA_SetCursor)) {
- QWidget *parent = w->parentWidget();
- while (parent && parent->d_func()->data.in_destructor)
- parent = parent->parentWidget();
- parentOfLeavingCursor = parent;
- //continue looping, we need to find the downest alien widget with a cursor.
- // (downest on the screen)
- }
- }
- //check that we will not call qt_x11_enforce_cursor twice with the same native widget
- if (parentOfLeavingCursor && (!enterOnAlien
- || parentOfLeavingCursor->effectiveWinId() != enter->effectiveWinId())) {
-#ifndef QT_NO_GRAPHICSVIEW
- if (!parentOfLeavingCursor->window()->graphicsProxyWidget())
-#endif
- {
-#if defined(Q_WS_X11)
- qt_x11_enforce_cursor(parentOfLeavingCursor,true);
-#elif defined(Q_WS_QPA)
- if (enter == QApplication::desktop()) {
- qt_qpa_set_cursor(enter, true);
- } else {
- qt_qpa_set_cursor(parentOfLeavingCursor, true);
- }
-#endif
- }
- }
-#endif
- if (enterOnAlien) {
- QWidget *cursorWidget = enter;
- while (!cursorWidget->isWindow() && !cursorWidget->isEnabled())
- cursorWidget = cursorWidget->parentWidget();
-
- if (!cursorWidget)
- return;
-
-#ifndef QT_NO_GRAPHICSVIEW
- if (cursorWidget->window()->graphicsProxyWidget()) {
- QWidgetPrivate::nearestGraphicsProxyWidget(cursorWidget)->setCursor(cursorWidget->cursor());
- } else
-#endif
- {
-#if defined(Q_WS_WIN)
- qt_win_set_cursor(cursorWidget, true);
-#elif defined(Q_WS_X11)
- qt_x11_enforce_cursor(cursorWidget, true);
-#elif defined(Q_OS_SYMBIAN)
- qt_symbian_set_cursor(cursorWidget, true);
-#elif defined(Q_WS_QPA)
- qt_qpa_set_cursor(cursorWidget, true);
-#endif
- }
- }
-#endif
-}
-
-/* exported for the benefit of testing tools */
-Q_GUI_EXPORT bool qt_tryModalHelper(QWidget *widget, QWidget **rettop)
-{
- return QApplicationPrivate::tryModalHelper(widget, rettop);
-}
-
-/*! \internal
- Returns true if \a widget is blocked by a modal window.
- */
-bool QApplicationPrivate::isBlockedByModal(QWidget *widget)
-{
- widget = widget->window();
- if (!modalState())
- return false;
- if (QApplication::activePopupWidget() == widget)
- return false;
-
- for (int i = 0; i < qt_modal_stack->size(); ++i) {
- QWidget *modalWidget = qt_modal_stack->at(i);
-
- {
- // check if the active modal widget is our widget or a parent of our widget
- QWidget *w = widget;
- while (w) {
- if (w == modalWidget)
- return false;
- w = w->parentWidget();
- }
-#ifdef Q_WS_WIN
- if ((widget->testAttribute(Qt::WA_WState_Created) || widget->data->winid)
- && (modalWidget->testAttribute(Qt::WA_WState_Created) || modalWidget->data->winid)
- && IsChild(modalWidget->data->winid, widget->data->winid))
- return false;
-#endif
- }
-
- Qt::WindowModality windowModality = modalWidget->windowModality();
- if (windowModality == Qt::NonModal) {
- // determine the modality type if it hasn't been set on the
- // modalWidget, this normally happens when waiting for a
- // native dialog. use WindowModal if we are the child of a
- // group leader; otherwise use ApplicationModal.
- QWidget *m = modalWidget;
- while (m && !m->testAttribute(Qt::WA_GroupLeader)) {
- m = m->parentWidget();
- if (m)
- m = m->window();
- }
- windowModality = (m && m->testAttribute(Qt::WA_GroupLeader))
- ? Qt::WindowModal
- : Qt::ApplicationModal;
- }
-
- switch (windowModality) {
- case Qt::ApplicationModal:
- {
- QWidget *groupLeaderForWidget = widget;
- while (groupLeaderForWidget && !groupLeaderForWidget->testAttribute(Qt::WA_GroupLeader))
- groupLeaderForWidget = groupLeaderForWidget->parentWidget();
-
- if (groupLeaderForWidget) {
- // if \a widget has WA_GroupLeader, it can only be blocked by ApplicationModal children
- QWidget *m = modalWidget;
- while (m && m != groupLeaderForWidget && !m->testAttribute(Qt::WA_GroupLeader))
- m = m->parentWidget();
- if (m == groupLeaderForWidget)
- return true;
- } else if (modalWidget != widget) {
- return true;
- }
- break;
- }
- case Qt::WindowModal:
- {
- QWidget *w = widget;
- do {
- QWidget *m = modalWidget;
- do {
- if (m == w)
- return true;
- m = m->parentWidget();
- if (m)
- m = m->window();
- } while (m);
- w = w->parentWidget();
- if (w)
- w = w->window();
- } while (w);
- break;
- }
- default:
- Q_ASSERT_X(false, "QApplication", "internal error, a modal widget cannot be modeless");
- break;
- }
- }
- return false;
-}
-
-/*!\internal
- */
-void QApplicationPrivate::enterModal(QWidget *widget)
-{
- QSet<QWidget*> blocked;
- QList<QWidget*> windows = QApplication::topLevelWidgets();
- for (int i = 0; i < windows.count(); ++i) {
- QWidget *window = windows.at(i);
- if (window->windowType() != Qt::Tool && isBlockedByModal(window))
- blocked.insert(window);
- }
-
- enterModal_sys(widget);
-
- windows = QApplication::topLevelWidgets();
- QEvent e(QEvent::WindowBlocked);
- for (int i = 0; i < windows.count(); ++i) {
- QWidget *window = windows.at(i);
- if (!blocked.contains(window) && window->windowType() != Qt::Tool && isBlockedByModal(window))
- QApplication::sendEvent(window, &e);
- }
-}
-
-/*!\internal
- */
-void QApplicationPrivate::leaveModal(QWidget *widget)
-{
- QSet<QWidget*> blocked;
- QList<QWidget*> windows = QApplication::topLevelWidgets();
- for (int i = 0; i < windows.count(); ++i) {
- QWidget *window = windows.at(i);
- if (window->windowType() != Qt::Tool && isBlockedByModal(window))
- blocked.insert(window);
- }
-
- leaveModal_sys(widget);
-
- windows = QApplication::topLevelWidgets();
- QEvent e(QEvent::WindowUnblocked);
- for (int i = 0; i < windows.count(); ++i) {
- QWidget *window = windows.at(i);
- if(blocked.contains(window) && window->windowType() != Qt::Tool && !isBlockedByModal(window))
- QApplication::sendEvent(window, &e);
- }
-}
-
-
-
-/*!\internal
-
- Called from qapplication_\e{platform}.cpp, returns true
- if the widget should accept the event.
- */
-bool QApplicationPrivate::tryModalHelper(QWidget *widget, QWidget **rettop)
-{
- QWidget *top = QApplication::activeModalWidget();
- if (rettop)
- *rettop = top;
-
- // the active popup widget always gets the input event
- if (QApplication::activePopupWidget())
- return true;
-
-#if defined(Q_WS_MAC) && defined(QT_MAC_USE_COCOA)
- top = QApplicationPrivate::tryModalHelper_sys(top);
- if (rettop)
- *rettop = top;
-#endif
-
- return !isBlockedByModal(widget->window());
-}
-
-/*
- \internal
-*/
-QWidget *QApplicationPrivate::pickMouseReceiver(QWidget *candidate, const QPoint &globalPos,
- QPoint &pos, QEvent::Type type,
- Qt::MouseButtons buttons, QWidget *buttonDown,
- QWidget *alienWidget)
-{
- Q_ASSERT(candidate);
-
- QWidget *mouseGrabber = QWidget::mouseGrabber();
- if (((type == QEvent::MouseMove && buttons) || (type == QEvent::MouseButtonRelease))
- && !buttonDown && !mouseGrabber) {
- return 0;
- }
-
- if (alienWidget && alienWidget->internalWinId())
- alienWidget = 0;
-
- QWidget *receiver = candidate;
-
- if (!mouseGrabber)
- mouseGrabber = (buttonDown && !isBlockedByModal(buttonDown)) ? buttonDown : alienWidget;
-
- if (mouseGrabber && mouseGrabber != candidate) {
- receiver = mouseGrabber;
- pos = receiver->mapFromGlobal(globalPos);
-#ifdef ALIEN_DEBUG
- qDebug() << " ** receiver adjusted to:" << receiver << "pos:" << pos;
-#endif
- }
-
- return receiver;
-
-}
-
-/*
- \internal
-*/
-bool QApplicationPrivate::sendMouseEvent(QWidget *receiver, QMouseEvent *event,
- QWidget *alienWidget, QWidget *nativeWidget,
- QWidget **buttonDown, QPointer<QWidget> &lastMouseReceiver,
- bool spontaneous)
-{
- Q_ASSERT(receiver);
- Q_ASSERT(event);
- Q_ASSERT(nativeWidget);
- Q_ASSERT(buttonDown);
-
- if (alienWidget && !isAlien(alienWidget))
- alienWidget = 0;
-
- QPointer<QWidget> receiverGuard = receiver;
- QPointer<QWidget> nativeGuard = nativeWidget;
- QPointer<QWidget> alienGuard = alienWidget;
- QPointer<QWidget> activePopupWidget = QApplication::activePopupWidget();
-
- const bool graphicsWidget = nativeWidget->testAttribute(Qt::WA_DontShowOnScreen);
-
- if (*buttonDown) {
- if (!graphicsWidget) {
- // Register the widget that shall receive a leave event
- // after the last button is released.
- if ((alienWidget || !receiver->internalWinId()) && !leaveAfterRelease && !QWidget::mouseGrabber())
- leaveAfterRelease = *buttonDown;
- if (event->type() == QEvent::MouseButtonRelease && !event->buttons())
- *buttonDown = 0;
- }
- } else if (lastMouseReceiver) {
- // Dispatch enter/leave if we move:
- // 1) from an alien widget to another alien widget or
- // from a native widget to an alien widget (first OR case)
- // 2) from an alien widget to a native widget (second OR case)
- if ((alienWidget && alienWidget != lastMouseReceiver)
- || (isAlien(lastMouseReceiver) && !alienWidget)) {
- if (activePopupWidget) {
- if (!QWidget::mouseGrabber())
- dispatchEnterLeave(alienWidget ? alienWidget : nativeWidget, lastMouseReceiver);
- } else {
- dispatchEnterLeave(receiver, lastMouseReceiver);
- }
-
- }
- }
-
-#ifdef ALIEN_DEBUG
- qDebug() << "QApplicationPrivate::sendMouseEvent: receiver:" << receiver
- << "pos:" << event->pos() << "alien" << alienWidget << "button down"
- << *buttonDown << "last" << lastMouseReceiver << "leave after release"
- << leaveAfterRelease;
-#endif
-
- // We need this quard in case someone opens a modal dialog / popup. If that's the case
- // leaveAfterRelease is set to null, but we shall not update lastMouseReceiver.
- const bool wasLeaveAfterRelease = leaveAfterRelease != 0;
- bool result;
- if (spontaneous)
- result = QApplication::sendSpontaneousEvent(receiver, event);
- else
- result = QApplication::sendEvent(receiver, event);
-
- if (!graphicsWidget && leaveAfterRelease && event->type() == QEvent::MouseButtonRelease
- && !event->buttons() && QWidget::mouseGrabber() != leaveAfterRelease) {
- // Dispatch enter/leave if:
- // 1) the mouse grabber is an alien widget
- // 2) the button is released on an alien widget
- QWidget *enter = 0;
- if (nativeGuard)
- enter = alienGuard ? alienWidget : nativeWidget;
- else // The receiver is typically deleted on mouse release with drag'n'drop.
- enter = QApplication::widgetAt(event->globalPos());
- dispatchEnterLeave(enter, leaveAfterRelease);
- leaveAfterRelease = 0;
- lastMouseReceiver = enter;
- } else if (!wasLeaveAfterRelease) {
- if (activePopupWidget) {
- if (!QWidget::mouseGrabber())
- lastMouseReceiver = alienGuard ? alienWidget : (nativeGuard ? nativeWidget : 0);
- } else {
- lastMouseReceiver = receiverGuard ? receiver : QApplication::widgetAt(event->globalPos());
- }
- }
-
- return result;
-}
-
-#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_WS_MAC) || defined(Q_WS_QPA)
-/*
- This function should only be called when the widget changes visibility, i.e.
- when the \a widget is shown, hidden or deleted. This function does nothing
- if the widget is a top-level or native, i.e. not an alien widget. In that
- case enter/leave events are genereated by the underlying windowing system.
-*/
-extern QPointer<QWidget> qt_last_mouse_receiver;
-extern QWidget *qt_button_down;
-void QApplicationPrivate::sendSyntheticEnterLeave(QWidget *widget)
-{
-#ifndef QT_NO_CURSOR
-#if defined(Q_WS_QWS) || defined(Q_WS_QPA)
- if (!widget || widget->isWindow())
- return;
-#else
- if (!widget || widget->internalWinId() || widget->isWindow())
- return;
-#endif
- const bool widgetInShow = widget->isVisible() && !widget->data->in_destructor;
- if (!widgetInShow && widget != qt_last_mouse_receiver)
- return; // Widget was not under the cursor when it was hidden/deleted.
-
- if (widgetInShow && widget->parentWidget()->data->in_show)
- return; // Ingore recursive show.
-
- QWidget *mouseGrabber = QWidget::mouseGrabber();
- if (mouseGrabber && mouseGrabber != widget)
- return; // Someone else has the grab; enter/leave should not occur.
-
- QWidget *tlw = widget->window();
- if (tlw->data->in_destructor || tlw->data->is_closing)
- return; // Closing down the business.
-
- if (widgetInShow && (!qt_last_mouse_receiver || qt_last_mouse_receiver->window() != tlw))
- return; // Mouse cursor not inside the widget's top-level.
-
- const QPoint globalPos(QCursor::pos());
- QPoint pos = tlw->mapFromGlobal(globalPos);
-
- // Find the current widget under the mouse. If this function was called from
- // the widget's destructor, we have to make sure childAt() doesn't take into
- // account widgets that are about to be destructed.
- QWidget *widgetUnderCursor = tlw->d_func()->childAt_helper(pos, widget->data->in_destructor);
- if (!widgetUnderCursor)
- widgetUnderCursor = tlw;
- else
- pos = widgetUnderCursor->mapFrom(tlw, pos);
-
- if (widgetInShow && widgetUnderCursor != widget && !widget->isAncestorOf(widgetUnderCursor))
- return; // Mouse cursor not inside the widget or any of its children.
-
- if (widget->data->in_destructor && qt_button_down == widget)
- qt_button_down = 0;
-
- // Send enter/leave events followed by a mouse move on the entered widget.
- QMouseEvent e(QEvent::MouseMove, pos, globalPos, Qt::NoButton, Qt::NoButton, Qt::NoModifier);
- sendMouseEvent(widgetUnderCursor, &e, widgetUnderCursor, tlw, &qt_button_down, qt_last_mouse_receiver);
-#endif // QT_NO_CURSOR
-}
-#endif // Q_WS_WIN || Q_WS_X11 || Q_WS_MAC
-
-/*!
- Returns the desktop widget (also called the root window).
-
- 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.
-*/
-QDesktopWidget *QApplication::desktop()
-{
- if (!qt_desktopWidget || // not created yet
- !(qt_desktopWidget->windowType() == Qt::Desktop)) { // reparented away
- qt_desktopWidget = new QDesktopWidget();
- }
- return qt_desktopWidget;
-}
-
-#ifndef QT_NO_CLIPBOARD
-/*!
- Returns a pointer to the application global clipboard.
-
- \note The QApplication object should already be constructed before
- accessing the clipboard.
-*/
-QClipboard *QApplication::clipboard()
-{
- if (qt_clipboard == 0) {
- if (!qApp) {
- qWarning("QApplication: Must construct a QApplication before accessing a QClipboard");
- return 0;
- }
- qt_clipboard = new QClipboard(0);
- }
- return qt_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.
-
- This function must be called before creating the QApplication object, like
- this:
-
- \snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 6
-
- \sa desktopSettingsAware()
-*/
-void QApplication::setDesktopSettingsAware(bool on)
-{
- QApplicationPrivate::obey_desktop_settings = on;
-}
-
-/*!
- Returns true if Qt is set to use the system's standard colors, fonts, etc.;
- otherwise returns false. The default is true.
-
- \sa setDesktopSettingsAware()
-*/
-bool QApplication::desktopSettingsAware()
-{
- return QApplicationPrivate::obey_desktop_settings;
-}
-
-/*!
- 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.
-
- \sa mouseButtons(), queryKeyboardModifiers()
-*/
-
-Qt::KeyboardModifiers QApplication::keyboardModifiers()
-{
- return QApplicationPrivate::modifier_buttons;
-}
-
-/*!
- \fn Qt::KeyboardModifiers QApplication::queryKeyboardModifiers()
-
- Queries and returns the state of the modifier keys on the keyboard.
- Unlike keyboardModifiers, this method returns the actual keys held
- on the input device at the time of calling the method.
-
- It does not rely on the keypress events having been received by this
- process, which makes it possible to check the modifiers while moving
- a window, for instance. Note that in most cases, you should use
- keyboardModifiers(), which is faster and more accurate since it contains
- the state of the modifiers as they were when the currently processed
- event was received.
-
- \sa keyboardModifiers()
-
- \since 4.8
-*/
-
-/*!
- 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 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()
-*/
-
-Qt::MouseButtons QApplication::mouseButtons()
-{
- return QApplicationPrivate::mouse_buttons;
-}
-
-/*!
- \fn bool QApplication::isSessionRestored() const
-
- Returns true if the application has been restored from an earlier
- \l{Session Management}{session}; otherwise returns false.
-
- \sa sessionId(), commitData(), saveState()
-*/
-
-
-/*!
- \fn QString QApplication::sessionId() const
-
- 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. 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()
-*/
-
-/*!
- \fn QString QApplication::sessionKey() const
-
- 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.
-
- The session key changes with every call of commitData() or saveState().
-
- \sa isSessionRestored(), sessionId(), commitData(), saveState()
-*/
-#ifndef QT_NO_SESSIONMANAGER
-bool QApplication::isSessionRestored() const
-{
- Q_D(const QApplication);
- return d->is_session_restored;
-}
-
-QString QApplication::sessionId() const
-{
- Q_D(const QApplication);
- return d->session_id;
-}
-
-QString QApplication::sessionKey() const
-{
- Q_D(const QApplication);
- return d->session_key;
-}
-#endif
-
-
-
-/*!
- \since 4.2
- \fn void QApplication::commitDataRequest(QSessionManager &manager)
-
- 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.
-
- 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.
-
- \note You should use Qt::DirectConnection when connecting to this signal.
-
- \sa isSessionRestored(), sessionId(), saveState(), {Session Management}
-*/
-
-/*!
- 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.
-
- 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.
-
- 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}
-*/
-#ifndef QT_NO_SESSIONMANAGER
-void QApplication::commitData(QSessionManager& manager )
-{
- emit commitDataRequest(manager);
- if (manager.allowsInteraction()) {
- QWidgetList done;
- QWidgetList list = QApplication::topLevelWidgets();
- bool cancelled = false;
- for (int i = 0; !cancelled && i < list.size(); ++i) {
- QWidget* w = list.at(i);
- if (w->isVisible() && !done.contains(w)) {
- cancelled = !w->close();
- if (!cancelled)
- done.append(w);
- list = QApplication::topLevelWidgets();
- i = -1;
- }
- }
- if (cancelled)
- manager.cancel();
- }
-}
-
-/*!
- \since 4.2
- \fn void QApplication::saveStateRequest(QSessionManager &manager)
-
- 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.
-
- 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.
-
- \note You should use Qt::DirectConnection when connecting to this signal.
-
- \sa isSessionRestored(), sessionId(), commitData(), {Session Management}
-*/
-
-/*!
- 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.
-
- 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.
-
- \sa isSessionRestored(), sessionId(), commitData(), {Session Management}
-*/
-
-void QApplication::saveState(QSessionManager &manager)
-{
- emit saveStateRequest(manager);
-}
-#endif //QT_NO_SESSIONMANAGER
-/*
- Sets the time after which a drag should start to \a ms ms.
-
- \sa startDragTime()
-*/
-
-void QApplication::setStartDragTime(int ms)
-{
- drag_time = ms;
-}
-
-/*!
- \property QApplication::startDragTime
- \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.
-
- Qt also uses this delay internally, e.g. in QTextEdit and QLineEdit, for
- starting a drag.
-
- The default value is 500 ms.
-
- \sa startDragDistance(), {Drag and Drop}
-*/
-
-int QApplication::startDragTime()
-{
- return drag_time;
-}
-
-/*
- Sets the distance after which a drag should start to \a l pixels.
-
- \sa startDragDistance()
-*/
-
-void QApplication::setStartDragDistance(int l)
-{
- drag_distance = 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.
-
- 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
-
- Qt uses this value internally, e.g. in QFileDialog.
-
- The default value is 4 pixels.
-
- \sa startDragTime() QPoint::manhattanLength() {Drag and Drop}
-*/
-
-int QApplication::startDragDistance()
-{
- return drag_distance;
-}
-
-/*!
- \fn void QApplication::setReverseLayout(bool reverse)
-
- Use setLayoutDirection() instead.
-*/
-
-/*!
- \fn void QApplication::reverseLayout()
-
- Use layoutDirection() instead.
-*/
-
-/*!
- \fn bool QApplication::isRightToLeft()
-
- Returns true if the application's layout direction is
- Qt::RightToLeft; otherwise returns false.
-
- \sa layoutDirection(), isLeftToRight()
-*/
-
-/*!
- \fn bool QApplication::isLeftToRight()
-
- Returns true if the application's layout direction is
- Qt::LeftToRight; otherwise returns false.
-
- \sa layoutDirection(), isRightToLeft()
-*/
-
-/*!
- \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.
-
- \sa QWidget::layoutDirection, isLeftToRight(), isRightToLeft()
- */
-
-void QApplication::setLayoutDirection(Qt::LayoutDirection direction)
-{
- if (layout_direction == direction || direction == Qt::LayoutDirectionAuto)
- return;
-
- layout_direction = direction;
-
- QWidgetList list = topLevelWidgets();
- for (int i = 0; i < list.size(); ++i) {
- QWidget *w = list.at(i);
- QEvent ev(QEvent::ApplicationLayoutDirectionChange);
- sendEvent(w, &ev);
- }
-}
-
-Qt::LayoutDirection QApplication::layoutDirection()
-{
- return layout_direction;
-}
-
-
-/*!
- \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.
-*/
-
-#ifdef QT3_SUPPORT
-Qt::Alignment QApplication::horizontalAlignment(Qt::Alignment align)
-{
- return QStyle::visualAlignment(layoutDirection(), align);
-}
-#endif
-
-
-/*!
- \fn QCursor *QApplication::overrideCursor()
-
- 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).
-
- \sa setOverrideCursor(), restoreOverrideCursor()
-*/
-#ifndef QT_NO_CURSOR
-QCursor *QApplication::overrideCursor()
-{
- return qApp->d_func()->cursor_list.isEmpty() ? 0 : &qApp->d_func()->cursor_list.first();
-}
-
-/*!
- Changes the currently active application override cursor to \a cursor.
-
- This function has no effect if setOverrideCursor() was not called.
-
- \sa setOverrideCursor(), overrideCursor(), restoreOverrideCursor(),
- QWidget::setCursor()
- */
-void QApplication::changeOverrideCursor(const QCursor &cursor)
-{
- if (qApp->d_func()->cursor_list.isEmpty())
- return;
- qApp->d_func()->cursor_list.removeFirst();
- setOverrideCursor(cursor);
-}
-#endif
-
-/*!
- \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).
-*/
-
-/*!
- Enters the main event loop and waits until exit() is called, then returns
- 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.
-
- 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.
-
- 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. This is because, on some platforms the
- QApplication::exec() call may not return. For example, on the Windows
- platform, when the user logs off, the system terminates the process after Qt
- closes all top-level windows. Hence, there is \e{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()
-*/
-int QApplication::exec()
-{
-#ifndef QT_NO_ACCESSIBILITY
- QAccessible::setRootObject(qApp);
-#endif
- return QCoreApplication::exec();
-}
-
-/*! \reimp
- */
-bool QApplication::notify(QObject *receiver, QEvent *e)
-{
- Q_D(QApplication);
- // no events are delivered after ~QCoreApplication() has started
- if (QApplicationPrivate::is_app_closing)
- return true;
-
- if (receiver == 0) { // serious error
- qWarning("QApplication::notify: Unexpected null receiver");
- return true;
- }
-
-#ifndef QT_NO_DEBUG
- d->checkReceiverThread(receiver);
-#endif
-
- // capture the current mouse/keyboard state
- if(e->spontaneous()) {
- if (e->type() == QEvent::KeyPress
- || e->type() == QEvent::KeyRelease) {
- QKeyEvent *ke = static_cast<QKeyEvent*>(e);
- QApplicationPrivate::modifier_buttons = ke->modifiers();
- } else if(e->type() == QEvent::MouseButtonPress
- || e->type() == QEvent::MouseButtonRelease) {
- QMouseEvent *me = static_cast<QMouseEvent*>(e);
- QApplicationPrivate::modifier_buttons = me->modifiers();
- if(me->type() == QEvent::MouseButtonPress)
- QApplicationPrivate::mouse_buttons |= me->button();
- else
- QApplicationPrivate::mouse_buttons &= ~me->button();
- }
-#if !defined(QT_NO_WHEELEVENT) || !defined(QT_NO_TABLETEVENT)
- else if (false
-# ifndef QT_NO_WHEELEVENT
- || e->type() == QEvent::Wheel
-# endif
-# ifndef QT_NO_TABLETEVENT
- || e->type() == QEvent::TabletMove
- || e->type() == QEvent::TabletPress
- || e->type() == QEvent::TabletRelease
-# endif
- ) {
- QInputEvent *ie = static_cast<QInputEvent*>(e);
- QApplicationPrivate::modifier_buttons = ie->modifiers();
- }
-#endif // !QT_NO_WHEELEVENT || !QT_NO_TABLETEVENT
- }
-
-#ifndef QT_NO_GESTURES
- // walk through parents and check for gestures
- if (d->gestureManager) {
- switch (e->type()) {
- case QEvent::Paint:
- case QEvent::MetaCall:
- case QEvent::DeferredDelete:
- case QEvent::DragEnter: case QEvent::DragMove: case QEvent::DragLeave:
- case QEvent::Drop: case QEvent::DragResponse:
- case QEvent::ChildAdded: case QEvent::ChildPolished:
-#ifdef QT3_SUPPORT
- case QEvent::ChildInsertedRequest:
- case QEvent::ChildInserted:
- case QEvent::LayoutHint:
-#endif
- case QEvent::ChildRemoved:
- case QEvent::UpdateRequest:
- case QEvent::UpdateLater:
- case QEvent::AccessibilityPrepare:
- case QEvent::LocaleChange:
- case QEvent::Style:
- case QEvent::IconDrag:
- case QEvent::StyleChange:
- case QEvent::AccessibilityHelp:
- case QEvent::AccessibilityDescription:
- case QEvent::GraphicsSceneDragEnter:
- case QEvent::GraphicsSceneDragMove:
- case QEvent::GraphicsSceneDragLeave:
- case QEvent::GraphicsSceneDrop:
- case QEvent::DynamicPropertyChange:
- case QEvent::NetworkReplyUpdated:
- break;
- default:
- if (receiver->isWidgetType()) {
- if (d->gestureManager->filterEvent(static_cast<QWidget *>(receiver), e))
- return true;
- } else {
- // a special case for events that go to QGesture objects.
- // We pass the object to the gesture manager and it'll figure
- // out if it's QGesture or not.
- if (d->gestureManager->filterEvent(receiver, e))
- return true;
- }
- }
- }
-#endif // QT_NO_GESTURES
-
- // User input and window activation makes tooltips sleep
- switch (e->type()) {
- case QEvent::Wheel:
- case QEvent::ActivationChange:
- case QEvent::KeyPress:
- case QEvent::KeyRelease:
- case QEvent::FocusOut:
- case QEvent::FocusIn:
- case QEvent::MouseButtonPress:
- case QEvent::MouseButtonRelease:
- case QEvent::MouseButtonDblClick:
- d->toolTipFallAsleep.stop();
- // fall-through
- case QEvent::Leave:
- d->toolTipWakeUp.stop();
- default:
- break;
- }
-
- bool res = false;
- if (!receiver->isWidgetType()) {
- res = d->notify_helper(receiver, e);
- } else switch (e->type()) {
-#if defined QT3_SUPPORT && !defined(QT_NO_SHORTCUT)
- case QEvent::Accel:
- {
- if (d->use_compat()) {
- QKeyEvent* key = static_cast<QKeyEvent*>(e);
- res = d->notify_helper(receiver, e);
-
- if (!res && !key->isAccepted())
- res = d->qt_dispatchAccelEvent(static_cast<QWidget *>(receiver), key);
-
- // next lines are for compatibility with Qt <= 3.0.x: old
- // QAccel was listening on toplevel widgets
- if (!res && !key->isAccepted() && !static_cast<QWidget *>(receiver)->isWindow())
- res = d->notify_helper(static_cast<QWidget *>(receiver)->window(), e);
- }
- break;
- }
-#endif //QT3_SUPPORT && !QT_NO_SHORTCUT
- case QEvent::ShortcutOverride:
- case QEvent::KeyPress:
- case QEvent::KeyRelease:
- {
- bool isWidget = receiver->isWidgetType();
- bool isGraphicsWidget = false;
-#ifndef QT_NO_GRAPHICSVIEW
- isGraphicsWidget = !isWidget && qobject_cast<QGraphicsWidget *>(receiver);
-#endif
- if (!isWidget && !isGraphicsWidget) {
- res = d->notify_helper(receiver, e);
- break;
- }
-
- QKeyEvent* key = static_cast<QKeyEvent*>(e);
-#if defined QT3_SUPPORT && !defined(QT_NO_SHORTCUT)
- if (d->use_compat() && d->qt_tryComposeUnicode(static_cast<QWidget*>(receiver), key))
- break;
-#endif
- if (key->type()==QEvent::KeyPress) {
-#ifndef QT_NO_SHORTCUT
- // Try looking for a Shortcut before sending key events
- if ((res = qApp->d_func()->shortcutMap.tryShortcutEvent(receiver, key)))
- return res;
-#endif
- qt_in_tab_key_event = (key->key() == Qt::Key_Backtab
- || key->key() == Qt::Key_Tab
- || key->key() == Qt::Key_Left
- || key->key() == Qt::Key_Up
- || key->key() == Qt::Key_Right
- || key->key() == Qt::Key_Down);
- }
- bool def = key->isAccepted();
- QPointer<QObject> pr = receiver;
- while (receiver) {
- if (def)
- key->accept();
- else
- key->ignore();
- res = d->notify_helper(receiver, e);
- QWidget *w = isWidget ? static_cast<QWidget *>(receiver) : 0;
-#ifndef QT_NO_GRAPHICSVIEW
- QGraphicsWidget *gw = isGraphicsWidget ? static_cast<QGraphicsWidget *>(receiver) : 0;
-#endif
-
- if ((res && key->isAccepted())
- /*
- QLineEdit will emit a signal on Key_Return, but
- ignore the event, and sometimes the connected
- slot deletes the QLineEdit (common in itemview
- delegates), so we have to check if the widget
- was destroyed even if the event was ignored (to
- prevent a crash)
-
- note that we don't have to reset pw while
- propagating (because the original receiver will
- be destroyed if one of its ancestors is)
- */
- || !pr
- || (isWidget && (w->isWindow() || !w->parentWidget()))
-#ifndef QT_NO_GRAPHICSVIEW
- || (isGraphicsWidget && (gw->isWindow() || !gw->parentWidget()))
-#endif
- ) {
- break;
- }
-
-#ifndef QT_NO_GRAPHICSVIEW
- receiver = w ? (QObject *)w->parentWidget() : (QObject *)gw->parentWidget();
-#else
- receiver = w->parentWidget();
-#endif
- }
- qt_in_tab_key_event = false;
- }
- break;
- case QEvent::MouseButtonPress:
- case QEvent::MouseButtonRelease:
- case QEvent::MouseButtonDblClick:
- case QEvent::MouseMove:
- {
- QWidget* w = static_cast<QWidget *>(receiver);
-
- QMouseEvent* mouse = static_cast<QMouseEvent*>(e);
- QPoint relpos = mouse->pos();
-
- if (e->spontaneous()) {
-#ifndef QT_NO_IM
- QInputContext *ic = w->inputContext();
- if (ic
- && w->testAttribute(Qt::WA_InputMethodEnabled)
- && ic->filterEvent(mouse))
- return true;
-#endif
-
- if (e->type() == QEvent::MouseButtonPress) {
- QApplicationPrivate::giveFocusAccordingToFocusPolicy(w,
- Qt::ClickFocus,
- Qt::MouseFocusReason);
- }
-
- // ### Qt 5 These dynamic tool tips should be an OPT-IN feature. Some platforms
- // like Mac OS X (probably others too), can optimize their views by not
- // dispatching mouse move events. We have attributes to control hover,
- // and mouse tracking, but as long as we are deciding to implement this
- // feature without choice of opting-in or out, you ALWAYS have to have
- // tracking enabled. Therefore, the other properties give a false sense of
- // performance enhancement.
- if (e->type() == QEvent::MouseMove && mouse->buttons() == 0) {
- d->toolTipWidget = w;
- d->toolTipPos = relpos;
- d->toolTipGlobalPos = mouse->globalPos();
- d->toolTipWakeUp.start(d->toolTipFallAsleep.isActive()?20:700, this);
- }
- }
-
- bool eventAccepted = mouse->isAccepted();
-
- QPointer<QWidget> pw = w;
- while (w) {
- QMouseEvent me(mouse->type(), relpos, mouse->globalPos(), mouse->button(), mouse->buttons(),
- mouse->modifiers());
- me.spont = mouse->spontaneous();
- // throw away any mouse-tracking-only mouse events
- if (!w->hasMouseTracking()
- && mouse->type() == QEvent::MouseMove && mouse->buttons() == 0) {
- // but still send them through all application event filters (normally done by notify_helper)
- for (int i = 0; i < d->eventFilters.size(); ++i) {
- register QObject *obj = d->eventFilters.at(i);
- if (!obj)
- continue;
- if (obj->d_func()->threadData != w->d_func()->threadData) {
- qWarning("QApplication: Object event filter cannot be in a different thread.");
- continue;
- }
- if (obj->eventFilter(w, w == receiver ? mouse : &me))
- break;
- }
- res = true;
- } else {
- w->setAttribute(Qt::WA_NoMouseReplay, false);
- res = d->notify_helper(w, w == receiver ? mouse : &me);
- e->spont = false;
- }
- eventAccepted = (w == receiver ? mouse : &me)->isAccepted();
- if (res && eventAccepted)
- break;
- if (w->isWindow() || w->testAttribute(Qt::WA_NoMousePropagation))
- break;
- relpos += w->pos();
- w = w->parentWidget();
- }
-
- mouse->setAccepted(eventAccepted);
-
- if (e->type() == QEvent::MouseMove) {
- if (!pw)
- break;
-
- w = static_cast<QWidget *>(receiver);
- relpos = mouse->pos();
- QPoint diff = relpos - w->mapFromGlobal(d->hoverGlobalPos);
- while (w) {
- if (w->testAttribute(Qt::WA_Hover) &&
- (!QApplication::activePopupWidget() || QApplication::activePopupWidget() == w->window())) {
- QHoverEvent he(QEvent::HoverMove, relpos, relpos - diff, mouse->modifiers());
- d->notify_helper(w, &he);
- }
- if (w->isWindow() || w->testAttribute(Qt::WA_NoMousePropagation))
- break;
- relpos += w->pos();
- w = w->parentWidget();
- }
- }
-
- d->hoverGlobalPos = mouse->globalPos();
- }
- break;
-#ifndef QT_NO_WHEELEVENT
- case QEvent::Wheel:
- {
- QWidget* w = static_cast<QWidget *>(receiver);
- QWheelEvent* wheel = static_cast<QWheelEvent*>(e);
- QPoint relpos = wheel->pos();
- bool eventAccepted = wheel->isAccepted();
-
- if (e->spontaneous()) {
- QApplicationPrivate::giveFocusAccordingToFocusPolicy(w,
- Qt::WheelFocus,
- Qt::MouseFocusReason);
- }
-
- while (w) {
- QWheelEvent we(relpos, wheel->globalPos(), wheel->delta(), wheel->buttons(),
- wheel->modifiers(), wheel->orientation());
- we.spont = wheel->spontaneous();
- res = d->notify_helper(w, w == receiver ? wheel : &we);
- eventAccepted = ((w == receiver) ? wheel : &we)->isAccepted();
- e->spont = false;
- if ((res && eventAccepted)
- || w->isWindow() || w->testAttribute(Qt::WA_NoMousePropagation))
- break;
-
- relpos += w->pos();
- w = w->parentWidget();
- }
- wheel->setAccepted(eventAccepted);
- }
- break;
-#endif
-#ifndef QT_NO_CONTEXTMENU
- case QEvent::ContextMenu:
- {
- QWidget* w = static_cast<QWidget *>(receiver);
- QContextMenuEvent *context = static_cast<QContextMenuEvent*>(e);
- QPoint relpos = context->pos();
- bool eventAccepted = context->isAccepted();
- while (w) {
- QContextMenuEvent ce(context->reason(), relpos, context->globalPos(), context->modifiers());
- ce.spont = e->spontaneous();
- res = d->notify_helper(w, w == receiver ? context : &ce);
- eventAccepted = ((w == receiver) ? context : &ce)->isAccepted();
- e->spont = false;
-
- if ((res && eventAccepted)
- || w->isWindow() || w->testAttribute(Qt::WA_NoMousePropagation))
- break;
-
- relpos += w->pos();
- w = w->parentWidget();
- }
- context->setAccepted(eventAccepted);
- }
- break;
-#endif // QT_NO_CONTEXTMENU
-#ifndef QT_NO_TABLETEVENT
- case QEvent::TabletMove:
- case QEvent::TabletPress:
- case QEvent::TabletRelease:
- {
- QWidget *w = static_cast<QWidget *>(receiver);
- QTabletEvent *tablet = static_cast<QTabletEvent*>(e);
- QPoint relpos = tablet->pos();
- bool eventAccepted = tablet->isAccepted();
- while (w) {
- QTabletEvent te(tablet->type(), relpos, tablet->globalPos(),
- tablet->hiResGlobalPos(), tablet->device(), tablet->pointerType(),
- tablet->pressure(), tablet->xTilt(), tablet->yTilt(),
- tablet->tangentialPressure(), tablet->rotation(), tablet->z(),
- tablet->modifiers(), tablet->uniqueId());
- te.spont = e->spontaneous();
- res = d->notify_helper(w, w == receiver ? tablet : &te);
- eventAccepted = ((w == receiver) ? tablet : &te)->isAccepted();
- e->spont = false;
- if ((res && eventAccepted)
- || w->isWindow()
- || w->testAttribute(Qt::WA_NoMousePropagation))
- break;
-
- relpos += w->pos();
- w = w->parentWidget();
- }
- tablet->setAccepted(eventAccepted);
- qt_tabletChokeMouse = tablet->isAccepted();
- }
- break;
-#endif // QT_NO_TABLETEVENT
-
-#if !defined(QT_NO_TOOLTIP) || !defined(QT_NO_WHATSTHIS)
- case QEvent::ToolTip:
- case QEvent::WhatsThis:
- case QEvent::QueryWhatsThis:
- {
- QWidget* w = static_cast<QWidget *>(receiver);
- QHelpEvent *help = static_cast<QHelpEvent*>(e);
- QPoint relpos = help->pos();
- bool eventAccepted = help->isAccepted();
- while (w) {
- QHelpEvent he(help->type(), relpos, help->globalPos());
- he.spont = e->spontaneous();
- res = d->notify_helper(w, w == receiver ? help : &he);
- e->spont = false;
- eventAccepted = (w == receiver ? help : &he)->isAccepted();
- if ((res && eventAccepted) || w->isWindow())
- break;
-
- relpos += w->pos();
- w = w->parentWidget();
- }
- help->setAccepted(eventAccepted);
- }
- break;
-#endif
-#if !defined(QT_NO_STATUSTIP) || !defined(QT_NO_WHATSTHIS)
- case QEvent::StatusTip:
- case QEvent::WhatsThisClicked:
- {
- QWidget *w = static_cast<QWidget *>(receiver);
- while (w) {
- res = d->notify_helper(w, e);
- if ((res && e->isAccepted()) || w->isWindow())
- break;
- w = w->parentWidget();
- }
- }
- break;
-#endif
-
-#ifndef QT_NO_DRAGANDDROP
- case QEvent::DragEnter: {
- QWidget* w = static_cast<QWidget *>(receiver);
- QDragEnterEvent *dragEvent = static_cast<QDragEnterEvent *>(e);
-#ifdef Q_WS_MAC
- // HIView has a slight difference in how it delivers events to children and parents
- // It will not give a leave to a child's parent when it enters a child.
- QWidget *currentTarget = QDragManager::self()->currentTarget();
- if (currentTarget) {
- // Assume currentTarget did not get a leave
- QDragLeaveEvent event;
- QApplication::sendEvent(currentTarget, &event);
- }
-#endif
-#ifndef QT_NO_GRAPHICSVIEW
- // QGraphicsProxyWidget handles its own propagation,
- // and we must not change QDragManagers currentTarget.
- QWExtra *extra = w->window()->d_func()->extra;
- if (extra && extra->proxyWidget) {
- res = d->notify_helper(w, dragEvent);
- break;
- }
-#endif
- while (w) {
- if (w->isEnabled() && w->acceptDrops()) {
- res = d->notify_helper(w, dragEvent);
- if (res && dragEvent->isAccepted()) {
- QDragManager::self()->setCurrentTarget(w);
- break;
- }
- }
- if (w->isWindow())
- break;
- dragEvent->p = w->mapToParent(dragEvent->p);
- w = w->parentWidget();
- }
- }
- break;
- case QEvent::DragMove:
- case QEvent::Drop:
- case QEvent::DragLeave: {
- QWidget* w = static_cast<QWidget *>(receiver);
-#ifndef QT_NO_GRAPHICSVIEW
- // QGraphicsProxyWidget handles its own propagation,
- // and we must not change QDragManagers currentTarget.
- QWExtra *extra = w->window()->d_func()->extra;
- bool isProxyWidget = extra && extra->proxyWidget;
- if (!isProxyWidget)
-#endif
- w = QDragManager::self()->currentTarget();
-
- if (!w) {
-#ifdef Q_WS_MAC
- // HIView has a slight difference in how it delivers events to children and parents
- // It will not give an enter to a child's parent when it leaves the child.
- if (e->type() == QEvent::DragLeave)
- break;
- // Assume that w did not get an enter.
- QDropEvent *dropEvent = static_cast<QDropEvent *>(e);
- QDragEnterEvent dragEnterEvent(dropEvent->pos(), dropEvent->possibleActions(),
- dropEvent->mimeData(), dropEvent->mouseButtons(),
- dropEvent->keyboardModifiers());
- QApplication::sendEvent(receiver, &dragEnterEvent);
- w = QDragManager::self()->currentTarget();
- if (!w)
-#endif
- break;
- }
- if (e->type() == QEvent::DragMove || e->type() == QEvent::Drop) {
- QDropEvent *dragEvent = static_cast<QDropEvent *>(e);
- QWidget *origReciver = static_cast<QWidget *>(receiver);
- while (origReciver && w != origReciver) {
- dragEvent->p = origReciver->mapToParent(dragEvent->p);
- origReciver = origReciver->parentWidget();
- }
- }
- res = d->notify_helper(w, e);
- if (e->type() != QEvent::DragMove
-#ifndef QT_NO_GRAPHICSVIEW
- && !isProxyWidget
-#endif
- )
- QDragManager::self()->setCurrentTarget(0, e->type() == QEvent::Drop);
- }
- break;
-#endif
- case QEvent::TouchBegin:
- // Note: TouchUpdate and TouchEnd events are never propagated
- {
- QWidget *widget = static_cast<QWidget *>(receiver);
- QTouchEvent *touchEvent = static_cast<QTouchEvent *>(e);
- bool eventAccepted = touchEvent->isAccepted();
- if (widget->testAttribute(Qt::WA_AcceptTouchEvents) && e->spontaneous()) {
- // give the widget focus if the focus policy allows it
- QApplicationPrivate::giveFocusAccordingToFocusPolicy(widget,
- Qt::ClickFocus,
- Qt::MouseFocusReason);
- }
-
- while (widget) {
- // first, try to deliver the touch event
- bool acceptTouchEvents = widget->testAttribute(Qt::WA_AcceptTouchEvents);
- touchEvent->setWidget(widget);
- touchEvent->setAccepted(acceptTouchEvents);
- QWeakPointer<QWidget> p = widget;
- res = acceptTouchEvents && d->notify_helper(widget, touchEvent);
- eventAccepted = touchEvent->isAccepted();
- if (p.isNull()) {
- // widget was deleted
- widget = 0;
- } else {
- widget->setAttribute(Qt::WA_WState_AcceptedTouchBeginEvent, res && eventAccepted);
- }
- touchEvent->spont = false;
- if (res && eventAccepted) {
- // the first widget to accept the TouchBegin gets an implicit grab.
- for (int i = 0; i < touchEvent->touchPoints().count(); ++i) {
- const QTouchEvent::TouchPoint &touchPoint = touchEvent->touchPoints().at(i);
- d->widgetForTouchPointId[touchPoint.id()] = widget;
- }
- break;
- } else if (p.isNull() || widget->isWindow() || widget->testAttribute(Qt::WA_NoMousePropagation)) {
- break;
- }
- QPoint offset = widget->pos();
- widget = widget->parentWidget();
- touchEvent->setWidget(widget);
- for (int i = 0; i < touchEvent->_touchPoints.size(); ++i) {
- QTouchEvent::TouchPoint &pt = touchEvent->_touchPoints[i];
- QRectF rect = pt.rect();
- rect.moveCenter(offset);
- pt.d->rect = rect;
- pt.d->startPos = pt.startPos() + offset;
- pt.d->lastPos = pt.lastPos() + offset;
- }
- }
-
- touchEvent->setAccepted(eventAccepted);
- break;
- }
- case QEvent::RequestSoftwareInputPanel:
- case QEvent::CloseSoftwareInputPanel:
-#ifndef QT_NO_IM
- if (receiver->isWidgetType()) {
- QWidget *w = static_cast<QWidget *>(receiver);
- QInputContext *ic = w->inputContext();
- if (ic && ic->filterEvent(e)) {
- break;
- }
- }
-#endif
- res = d->notify_helper(receiver, e);
- break;
-
-#ifndef QT_NO_GESTURES
- case QEvent::NativeGesture:
- {
- // only propagate the first gesture event (after the GID_BEGIN)
- QWidget *w = static_cast<QWidget *>(receiver);
- while (w) {
- e->ignore();
- res = d->notify_helper(w, e);
- if ((res && e->isAccepted()) || w->isWindow())
- break;
- w = w->parentWidget();
- }
- break;
- }
- case QEvent::Gesture:
- case QEvent::GestureOverride:
- {
- if (receiver->isWidgetType()) {
- QWidget *w = static_cast<QWidget *>(receiver);
- QGestureEvent *gestureEvent = static_cast<QGestureEvent *>(e);
- QList<QGesture *> allGestures = gestureEvent->gestures();
-
- bool eventAccepted = gestureEvent->isAccepted();
- bool wasAccepted = eventAccepted;
- while (w) {
- // send only gestures the widget expects
- QList<QGesture *> gestures;
- QWidgetPrivate *wd = w->d_func();
- for (int i = 0; i < allGestures.size();) {
- QGesture *g = allGestures.at(i);
- Qt::GestureType type = g->gestureType();
- QMap<Qt::GestureType, Qt::GestureFlags>::iterator contextit =
- wd->gestureContext.find(type);
- bool deliver = contextit != wd->gestureContext.end() &&
- (g->state() == Qt::GestureStarted || w == receiver ||
- (contextit.value() & Qt::ReceivePartialGestures));
- if (deliver) {
- allGestures.removeAt(i);
- gestures.append(g);
- } else {
- ++i;
- }
- }
- if (!gestures.isEmpty()) { // we have gestures for this w
- QGestureEvent ge(gestures);
- ge.t = gestureEvent->t;
- ge.spont = gestureEvent->spont;
- ge.m_accept = wasAccepted;
- ge.d_func()->accepted = gestureEvent->d_func()->accepted;
- res = d->notify_helper(w, &ge);
- gestureEvent->spont = false;
- eventAccepted = ge.isAccepted();
- for (int i = 0; i < gestures.size(); ++i) {
- QGesture *g = gestures.at(i);
- // Ignore res [event return value] because handling of multiple gestures
- // packed into a single QEvent depends on not consuming the event
- if (eventAccepted || ge.isAccepted(g)) {
- // if the gesture was accepted, mark the target widget for it
- gestureEvent->d_func()->targetWidgets[g->gestureType()] = w;
- gestureEvent->setAccepted(g, true);
- } else {
- // if the gesture was explicitly ignored by the application,
- // put it back so a parent can get it
- allGestures.append(g);
- }
- }
- }
- if (allGestures.isEmpty()) // everything delivered
- break;
- if (w->isWindow())
- break;
- w = w->parentWidget();
- }
- foreach (QGesture *g, allGestures)
- gestureEvent->setAccepted(g, false);
- gestureEvent->m_accept = false; // to make sure we check individual gestures
- } else {
- res = d->notify_helper(receiver, e);
- }
- break;
- }
-#endif // QT_NO_GESTURES
-#ifdef QT_MAC_USE_COCOA
- case QEvent::Enter:
- if (receiver->isWidgetType()) {
- QWidget *w = static_cast<QWidget *>(receiver);
- if (w->testAttribute(Qt::WA_AcceptTouchEvents))
- qt_widget_private(w)->registerTouchWindow(true);
- }
- res = d->notify_helper(receiver, e);
- break;
- case QEvent::Leave:
- if (receiver->isWidgetType()) {
- QWidget *w = static_cast<QWidget *>(receiver);
- if (w->testAttribute(Qt::WA_AcceptTouchEvents))
- qt_widget_private(w)->registerTouchWindow(false);
- }
- res = d->notify_helper(receiver, e);
- break;
-#endif
- default:
- res = d->notify_helper(receiver, e);
- break;
- }
-
- return res;
-}
-
-bool QApplicationPrivate::notify_helper(QObject *receiver, QEvent * e)
-{
- // send to all application event filters
- if (sendThroughApplicationEventFilters(receiver, e))
- return true;
-
- if (receiver->isWidgetType()) {
- QWidget *widget = static_cast<QWidget *>(receiver);
-
-#if !defined(Q_WS_WINCE) || (defined(GWES_ICONCURS) && !defined(QT_NO_CURSOR))
- // toggle HasMouse widget state on enter and leave
- if ((e->type() == QEvent::Enter || e->type() == QEvent::DragEnter) &&
- (!QApplication::activePopupWidget() || QApplication::activePopupWidget() == widget->window()))
- widget->setAttribute(Qt::WA_UnderMouse, true);
- else if (e->type() == QEvent::Leave || e->type() == QEvent::DragLeave)
- widget->setAttribute(Qt::WA_UnderMouse, false);
-#endif
-
- if (QLayout *layout=widget->d_func()->layout) {
- layout->widgetEvent(e);
- }
- }
-
- // send to all receiver event filters
- if (sendThroughObjectEventFilters(receiver, e))
- return true;
-
- // deliver the event
- bool consumed = receiver->event(e);
- e->spont = false;
- return consumed;
-}
-
-
-/*!
- \class QSessionManager
- \brief The QSessionManager class provides access to the session manager.
-
- 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:
-
- \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 RestartImmediately The application wants to be started immediately
- whenever it is not running.
-
- \value RestartNever The application does not want to be restarted
- automatically.
-
- The default hint is \c RestartIfRunning.
-*/
-
-
-/*!
- \fn QString QSessionManager::sessionId() const
-
- 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 the earlier session.
-
- \sa sessionKey(), QApplication::sessionId()
-*/
-
-/*!
- \fn QString QSessionManager::sessionKey() const
-
- 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.
-
- The session key changes with every call of commitData() or saveState().
-
- \sa sessionId(), QApplication::sessionKey()
-*/
-
-/*!
- \fn void* QSessionManager::handle() const
-
- \internal
-*/
-
-/*!
- \fn bool QSessionManager::allowsInteraction()
-
- 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.
-
- 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().
-
- 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
-
- If an error occurred within the application while saving its data, you may
- want to try allowsErrorInteraction() instead.
-
- \sa QApplication::commitData(), release(), cancel()
-*/
-
-
-/*!
- \fn bool QSessionManager::allowsErrorInteraction()
-
- 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.
-
- \sa allowsInteraction(), release(), cancel()
-*/
-
-/*!
- \fn void QSessionManager::release()
-
- Releases the session manager's interaction semaphore after an interaction
- phase.
-
- \sa allowsInteraction(), allowsErrorInteraction()
-*/
-
-/*!
- \fn void QSessionManager::cancel()
-
- 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)
-
- Sets the application's restart hint to \a hint. On application startup, the
- hint is set to \c RestartIfRunning.
-
- \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.
-
- \sa restartHint()
-*/
-
-/*!
- \fn QSessionManager::RestartHint QSessionManager::restartHint() const
-
- Returns the application's current restart hint. The default is
- \c RestartIfRunning.
-
- \sa setRestartHint()
-*/
-
-/*!
- \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
-
- \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.
-
- 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()
-*/
-
-/*!
- \fn QStringList QSessionManager::restartCommand() const
-
- Returns the currently set restart command.
-
- To iterate over the list, you can use the \l foreach pseudo-keyword:
-
- \snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 10
-
- \sa setRestartCommand(), restartHint()
-*/
-
-/*!
- \fn void QSessionManager::setDiscardCommand(const QStringList& list)
-
- Sets the discard command to the given \a list.
-
- \sa discardCommand(), setRestartCommand()
-*/
-
-
-/*!
- \fn QStringList QSessionManager::discardCommand() const
-
- Returns the currently set discard command.
-
- To iterate over the list, you can use the \l foreach pseudo-keyword:
-
- \snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 11
-
- \sa setDiscardCommand(), restartCommand(), setRestartCommand()
-*/
-
-/*!
- \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.
-
- The property called \a name has its value set to the string \a 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.
-
- The property called \a name has its value set to the string list \a value.
-*/
-
-/*!
- \fn bool QSessionManager::isPhase2() const
-
- Returns true if the session manager is currently performing a second
- session management phase; otherwise returns false.
-
- \sa 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.
-
- 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 If another application has requested a second phase it may get called
- before, simultaneously with, or after your application's second phase.
-
- \sa isPhase2()
-*/
-
-/*****************************************************************************
- Stubbed session management support
- *****************************************************************************/
-#ifndef QT_NO_SESSIONMANAGER
-#if defined(Q_WS_WIN) || defined(Q_WS_MAC) || defined(Q_WS_QWS)
-
-#if defined(Q_OS_WINCE)
-HRESULT qt_CoCreateGuid(GUID* guid)
-{
- // We will use the following information to create the GUID
- // 1. absolute path to application
- wchar_t tempFilename[MAX_PATH];
- if (!GetModuleFileName(0, tempFilename, MAX_PATH))
- return S_FALSE;
- unsigned int hash = qHash(QString::fromWCharArray(tempFilename));
- guid->Data1 = hash;
- // 2. creation time of file
- QFileInfo info(QString::fromWCharArray(tempFilename));
- guid->Data2 = qHash(info.created().toTime_t());
- // 3. current system time
- guid->Data3 = qHash(QDateTime::currentDateTime().toTime_t());
- return S_OK;
-}
-#if !defined(OLE32_MCOMGUID) || defined(QT_WINCE_FORCE_CREATE_GUID)
-#define CoCreateGuid qt_CoCreateGuid
-#endif
-
-#endif
-
-class QSessionManagerPrivate : public QObjectPrivate
-{
-public:
- QStringList restartCommand;
- QStringList discardCommand;
- QString sessionId;
- QString sessionKey;
- QSessionManager::RestartHint restartHint;
-};
-
-QSessionManager* qt_session_manager_self = 0;
-QSessionManager::QSessionManager(QApplication * app, QString &id, QString &key)
- : QObject(*new QSessionManagerPrivate, app)
-{
- Q_D(QSessionManager);
- setObjectName(QLatin1String("qt_sessionmanager"));
- qt_session_manager_self = this;
-#if defined(Q_WS_WIN)
- wchar_t guidstr[40];
- GUID guid;
- CoCreateGuid(&guid);
- StringFromGUID2(guid, guidstr, 40);
- id = QString::fromWCharArray(guidstr);
- CoCreateGuid(&guid);
- StringFromGUID2(guid, guidstr, 40);
- key = QString::fromWCharArray(guidstr);
-#endif
- d->sessionId = id;
- d->sessionKey = key;
- d->restartHint = RestartIfRunning;
-}
-
-QSessionManager::~QSessionManager()
-{
- qt_session_manager_self = 0;
-}
-
-QString QSessionManager::sessionId() const
-{
- Q_D(const QSessionManager);
- return d->sessionId;
-}
-
-QString QSessionManager::sessionKey() const
-{
- Q_D(const QSessionManager);
- return d->sessionKey;
-}
-
-
-#if defined(Q_WS_X11) || defined(Q_WS_MAC)
-void* QSessionManager::handle() const
-{
- return 0;
-}
-#endif
-
-#if !defined(Q_WS_WIN)
-bool QSessionManager::allowsInteraction()
-{
- return true;
-}
-
-bool QSessionManager::allowsErrorInteraction()
-{
- return true;
-}
-void QSessionManager::release()
-{
-}
-
-void QSessionManager::cancel()
-{
-}
-#endif
-
-
-void QSessionManager::setRestartHint(QSessionManager::RestartHint hint)
-{
- Q_D(QSessionManager);
- d->restartHint = hint;
-}
-
-QSessionManager::RestartHint QSessionManager::restartHint() const
-{
- Q_D(const QSessionManager);
- return d->restartHint;
-}
-
-void QSessionManager::setRestartCommand(const QStringList& command)
-{
- Q_D(QSessionManager);
- d->restartCommand = command;
-}
-
-QStringList QSessionManager::restartCommand() const
-{
- Q_D(const QSessionManager);
- return d->restartCommand;
-}
-
-void QSessionManager::setDiscardCommand(const QStringList& command)
-{
- Q_D(QSessionManager);
- d->discardCommand = command;
-}
-
-QStringList QSessionManager::discardCommand() const
-{
- Q_D(const QSessionManager);
- return d->discardCommand;
-}
-
-void QSessionManager::setManagerProperty(const QString&, const QString&)
-{
-}
-
-void QSessionManager::setManagerProperty(const QString&, const QStringList&)
-{
-}
-
-bool QSessionManager::isPhase2() const
-{
- return false;
-}
-
-void QSessionManager::requestPhase2()
-{
-}
-
-#endif
-#endif // QT_NO_SESSIONMANAGER
-
-/*!
- \fn Qt::MacintoshVersion QApplication::macVersion()
-
- Use QSysInfo::MacintoshVersion instead.
-*/
-
-/*!
- \fn QApplication::ColorMode QApplication::colorMode()
-
- Use colorSpec() instead, and use ColorSpec as the enum type.
-*/
-
-/*!
- \fn void QApplication::setColorMode(ColorMode mode)
-
- Use setColorSpec() instead, and pass a ColorSpec value instead.
-*/
-
-/*!
- \fn bool QApplication::hasGlobalMouseTracking()
-
- 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.
-*/
-
-/*!
- \fn void QApplication::flushX()
-
- Use flush() instead.
-*/
-
-/*!
- \fn void QApplication::setWinStyleHighlightColor(const QColor &c)
-
- Use the palette instead.
-
- \oldcode
- app.setWinStyleHighlightColor(color);
- \newcode
- QPalette palette(QApplication::palette());
- palette.setColor(QPalette::Highlight, color);
- QApplication::setPalette(palette);
- \endcode
-*/
-
-/*!
- \fn void QApplication::setPalette(const QPalette &pal, bool b, const char* className = 0)
-
- Use the two-argument overload instead.
-*/
-
-/*!
- \fn void QApplication::setFont(const QFont &font, bool b, const char* className = 0)
-
- Use the two-argument overload instead.
-*/
-
-/*!
- \fn const QColor &QApplication::winStyleHighlightColor()
-
- Use QApplication::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:
-
- \snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 12
-*/
-
-/*!
- \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:
-
- \snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 13
-*/
-
-#ifdef QT3_SUPPORT
-QWidget *QApplication::mainWidget()
-{
- return QApplicationPrivate::main_widget;
-}
-#endif
-bool QApplicationPrivate::inPopupMode() const
-{
- return QApplicationPrivate::popupWidgets != 0;
-}
-
-/*!
- \property QApplication::quitOnLastWindowClosed
-
- \brief whether the application implicitly quits when the last window is
- closed.
-
- The default is true.
-
- If this property is true, the applications quits when the last visible
- primary window (i.e. window with no parent) with the Qt::WA_QuitOnClose
- attribute set is closed. By default this attribute is set for all widgets
- except for sub-windows. Refer to \l{Qt::WindowType} for a detailed list of
- Qt::Window objects.
-
- \sa quit(), QWidget::close()
- */
-
-void QApplication::setQuitOnLastWindowClosed(bool quit)
-{
- QApplicationPrivate::quitOnLastWindowClosed = quit;
-}
-
-bool QApplication::quitOnLastWindowClosed()
-{
- return QApplicationPrivate::quitOnLastWindowClosed;
-}
-
-void QApplicationPrivate::emitLastWindowClosed()
-{
- if (qApp && qApp->d_func()->in_exec) {
- if (QApplicationPrivate::quitOnLastWindowClosed) {
- // get ready to quit, this event might be removed if the
- // event loop is re-entered, however
- QApplication::postEvent(qApp, new QEvent(QEvent::Quit));
- }
- emit qApp->lastWindowClosed();
- }
-}
-
-#ifdef QT_KEYPAD_NAVIGATION
-/*!
- Sets the kind of focus navigation Qt should use to \a mode.
-
- This feature is available in Qt for Embedded Linux, Symbian and Windows CE
- only.
-
- \note On Windows CE this feature is disabled by default for touch device
- mkspecs. To enable keypad navigation, build Qt with
- QT_KEYPAD_NAVIGATION defined.
-
- \note On Symbian, setting the mode to Qt::NavigationModeCursorAuto will enable a
- virtual mouse cursor on non touchscreen devices, which is controlled
- by the cursor keys if there is no analog pointer device.
- On other platforms and on touchscreen devices, it has the same
- meaning as Qt::NavigationModeNone.
-
- \since 4.6
-
- \sa keypadNavigationEnabled()
-*/
-void QApplication::setNavigationMode(Qt::NavigationMode mode)
-{
-#ifdef Q_OS_SYMBIAN
- QApplicationPrivate::setNavigationMode(mode);
-#else
- QApplicationPrivate::navigationMode = mode;
-#endif
-}
-
-/*!
- Returns what kind of focus navigation Qt is using.
-
- This feature is available in Qt for Embedded Linux, Symbian and Windows CE
- only.
-
- \note On Windows CE this feature is disabled by default for touch device
- mkspecs. To enable keypad navigation, build Qt with
- QT_KEYPAD_NAVIGATION defined.
-
- \note On Symbian, the default mode is Qt::NavigationModeNone for touch
- devices, and Qt::NavigationModeKeypadDirectional.
-
- \since 4.6
-
- \sa keypadNavigationEnabled()
-*/
-Qt::NavigationMode QApplication::navigationMode()
-{
- return QApplicationPrivate::navigationMode;
-}
-
-/*!
- Sets whether Qt should use focus navigation suitable for use with a
- minimal keypad.
-
- This feature is available in Qt for Embedded Linux, Symbian and Windows CE
- only.
-
- \note On Windows CE this feature is disabled by default for touch device
- mkspecs. To enable keypad navigation, build Qt with
- QT_KEYPAD_NAVIGATION defined.
-
- \deprecated
-
- \sa setNavigationMode()
-*/
-void QApplication::setKeypadNavigationEnabled(bool enable)
-{
- if (enable) {
-#ifdef Q_OS_SYMBIAN
- QApplication::setNavigationMode(Qt::NavigationModeKeypadDirectional);
-#else
- QApplication::setNavigationMode(Qt::NavigationModeKeypadTabOrder);
-#endif
- }
- else {
- QApplication::setNavigationMode(Qt::NavigationModeNone);
- }
-}
-
-/*!
- Returns true if Qt is set to use keypad navigation; otherwise returns
- false. The default value is true on Symbian, but false on other platforms.
-
- This feature is available in Qt for Embedded Linux, Symbian and Windows CE
- only.
-
- \note On Windows CE this feature is disabled by default for touch device
- mkspecs. To enable keypad navigation, build Qt with
- QT_KEYPAD_NAVIGATION defined.
-
- \deprecated
-
- \sa navigationMode()
-*/
-bool QApplication::keypadNavigationEnabled()
-{
- return QApplicationPrivate::navigationMode == Qt::NavigationModeKeypadTabOrder ||
- QApplicationPrivate::navigationMode == Qt::NavigationModeKeypadDirectional;
-}
-#endif
-
-/*!
- \fn void QApplication::alert(QWidget *widget, int msec)
- \since 4.3
-
- Causes an alert to be shown for \a widget if the window is not the active
- window. The alert is shown for \a msec miliseconds. If \a msec is zero (the
- default), then the alert is shown indefinitely until the window becomes
- active again.
-
- Currently this function does nothing on Qt for Embedded Linux.
-
- 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
- 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
- visible in some sort of way) in order for this to work.
-*/
-
-/*!
- \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 default value on X11 is 1000 milliseconds. On Windows, the
- \gui{Control Panel} value is used and setting this property sets the cursor
- flash time for all applications.
-
- We recommend that widgets do not cache this value as it may change at any
- time if the user changes the global desktop settings.
-*/
-
-/*!
- \property QApplication::doubleClickInterval
- \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, the
- operating system's value is used. However, on Windows and Symbian OS,
- calling this function sets the double click interval for all applications.
-*/
-
-/*!
- \property QApplication::keyboardInputInterval
- \brief the time limit in milliseconds that distinguishes a key press
- from two consecutive key presses
- \since 4.2
-
- The default value on X11 is 400 milliseconds. On Windows and Mac OS, the
- operating system's value is used.
-*/
-
-/*!
- \property QApplication::wheelScrollLines
- \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}.
-
- By default, this property has a value of 3.
-*/
-
-/*!
- \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.
-
- \note All effects are disabled on screens running at less than 16-bit color
- depth.
-
- \sa isEffectEnabled(), Qt::UIEffect, setDesktopSettingsAware()
-*/
-
-/*!
- \fn bool QApplication::isEffectEnabled(Qt::UIEffect effect)
-
- Returns true if \a effect is enabled; otherwise returns false.
-
- 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.
-
- \sa setEffectEnabled(), Qt::UIEffect
-*/
-
-/*!
- \fn QWidget *QApplication::mainWidget()
-
- Returns the main application widget, or 0 if there is no main widget.
-*/
-
-/*!
- \fn void QApplication::setMainWidget(QWidget *mainWidget)
-
- 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. 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.
-
- On 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()
-*/
-
-/*!
- \fn void QApplication::beep()
-
- Sounds the bell, using the default volume and sound. The function is \e not
- available in Qt for Embedded Linux.
-*/
-
-/*!
- \fn void QApplication::setOverrideCursor(const QCursor &cursor)
-
- 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.
-
- 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 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()
-*/
-
-/*!
- \fn void QApplication::restoreOverrideCursor()
-
- 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.
-
- \sa setOverrideCursor(), overrideCursor()
-*/
-
-/*!
- \macro qApp
- \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.
-
- Only one application object can be created.
-
- \sa QCoreApplication::instance()
-*/
-
-#ifndef QT_NO_IM
-// ************************************************************************
-// Input Method support
-// ************************************************************************
-
-/*!
- This function replaces the QInputContext instance used by the application
- with \a inputContext.
-
- Qt takes ownership of the given \a inputContext.
-
- \sa inputContext()
-*/
-void QApplication::setInputContext(QInputContext *inputContext)
-{
- if (inputContext == QApplicationPrivate::inputContext)
- return;
- if (!inputContext) {
- qWarning("QApplication::setInputContext: called with 0 input context");
- return;
- }
- delete QApplicationPrivate::inputContext;
- QApplicationPrivate::inputContext = inputContext;
- QApplicationPrivate::inputContext->setParent(this);
-}
-
-/*!
- Returns the QInputContext instance used by the application.
-
- \sa setInputContext()
-*/
-QInputContext *QApplication::inputContext() const
-{
- Q_D(const QApplication);
- Q_UNUSED(d);// only static members being used.
- if (QApplicationPrivate::is_app_closing)
- return d->inputContext;
-#ifdef Q_WS_X11
- if (!X11)
- return 0;
- if (!d->inputContext) {
- QApplication *that = const_cast<QApplication *>(this);
- 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;
- }
-#elif defined(Q_OS_SYMBIAN)
- if (!d->inputContext) {
- QApplication *that = const_cast<QApplication *>(this);
- const QStringList keys = QInputContextFactory::keys();
- // Try hbim and coefep first, then try others.
- if (keys.contains(QLatin1String("hbim"))) {
- that->d_func()->inputContext = QInputContextFactory::create(QLatin1String("hbim"), that);
- } else if (keys.contains(QLatin1String("coefep"))) {
- that->d_func()->inputContext = QInputContextFactory::create(QLatin1String("coefep"), that);
- } else {
- for (int c = 0; c < keys.size() && !d->inputContext; ++c) {
- that->d_func()->inputContext = QInputContextFactory::create(keys[c], that);
- }
- }
- }
-#endif
- return d->inputContext;
-}
-#endif // QT_NO_IM
-
-//Returns the current platform used by keyBindings
-uint QApplicationPrivate::currentPlatform(){
- uint platform = KB_Win;
-#ifdef Q_WS_MAC
- platform = KB_Mac;
-#elif defined Q_WS_X11
- platform = KB_X11;
- if (X11->desktopEnvironment == DE_KDE)
- platform |= KB_KDE;
- if (X11->desktopEnvironment == DE_GNOME)
- platform |= KB_Gnome;
- if (X11->desktopEnvironment == DE_CDE)
- platform |= KB_CDE;
-#elif defined(Q_OS_SYMBIAN)
- platform = KB_S60;
-#endif
- return platform;
-}
-
-bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event)
-{
- return QCoreApplication::sendSpontaneousEvent(receiver, event);
-}
-
-
-/*!
- \since 4.2
-
- Returns the current keyboard input locale.
-*/
-QLocale QApplication::keyboardInputLocale()
-{
- if (!QApplicationPrivate::checkInstance("keyboardInputLocale"))
- return QLocale::c();
- return qt_keymapper_private()->keyboardInputLocale;
-}
-
-/*!
- \since 4.2
-
- Returns the current keyboard input direction.
-*/
-Qt::LayoutDirection QApplication::keyboardInputDirection()
-{
- if (!QApplicationPrivate::checkInstance("keyboardInputDirection"))
- return Qt::LeftToRight;
- return qt_keymapper_private()->keyboardInputDirection;
-}
-
-void QApplicationPrivate::giveFocusAccordingToFocusPolicy(QWidget *widget,
- Qt::FocusPolicy focusPolicy,
- Qt::FocusReason focusReason)
-{
- QWidget *focusWidget = widget;
- while (focusWidget) {
- if (focusWidget->isEnabled()
- && QApplicationPrivate::shouldSetFocus(focusWidget, focusPolicy)) {
- focusWidget->setFocus(focusReason);
- break;
- }
- if (focusWidget->isWindow())
- break;
- focusWidget = focusWidget->parentWidget();
- }
-}
-
-bool QApplicationPrivate::shouldSetFocus(QWidget *w, Qt::FocusPolicy policy)
-{
- QWidget *f = w;
- while (f->d_func()->extra && f->d_func()->extra->focus_proxy)
- f = f->d_func()->extra->focus_proxy;
-
- if ((w->focusPolicy() & policy) != policy)
- return false;
- if (w != f && (f->focusPolicy() & policy) != policy)
- return false;
- return true;
-}
-
-/*! \fn QDecoration &QApplication::qwsDecoration()
- Return the QWSDecoration used for decorating windows.
-
- \warning This method is non-portable. It is only available in
- Qt for Embedded Linux.
-
- \sa QDecoration
-*/
-
-/*!
- \fn void QApplication::qwsSetDecoration(QDecoration *decoration)
-
- Sets the QDecoration derived class to use for decorating the
- windows used by Qt for Embedded Linux to the \a decoration
- specified.
-
- This method is non-portable. It is only available in Qt for Embedded Linux.
-
- \sa QDecoration
-*/
-
-/*! \fn QDecoration* QApplication::qwsSetDecoration(const QString &decoration)
- \overload
-
- Requests a QDecoration object for \a decoration from the
- QDecorationFactory.
-
- The string must be one of the QDecorationFactory::keys(). Keys are case
- insensitive.
-
- A later call to the QApplication constructor will override the requested
- style when a "-style" option is passed in as a commandline parameter.
-
- Returns 0 if an unknown \a decoration is passed, otherwise the QStyle object
- returned is set as the application's GUI style.
-*/
-
-/*!
- \fn bool QApplication::qwsEventFilter(QWSEvent *event)
-
- This virtual function is only implemented under Qt for Embedded Linux.
-
- If you create an application that inherits QApplication and
- reimplement this function, you get direct access to all QWS (Q
- Window System) events that the are received from the QWS master
- process. The events are passed in the \a event parameter.
-
- Return true if you want to stop the event from being processed.
- Return false for normal event dispatching. The default
- implementation returns false.
-*/
-
-/*! \fn void QApplication::qwsSetCustomColors(QRgb *colorTable, int start, int numColors)
- Set Qt for Embedded Linux custom color table.
-
- Qt for Embedded Linux on 8-bpp displays allocates a standard 216 color cube.
- The remaining 40 colors may be used by setting a custom color
- table in the QWS master process before any clients connect.
-
- \a colorTable is an array of up to 40 custom colors. \a start is
- the starting index (0-39) and \a numColors is the number of colors
- to be set (1-40).
-
- This method is non-portable. It is available \e only in
- Qt for Embedded Linux.
-
- \note The custom colors will not be used by the default screen
- driver. To make use of the new colors, implement a custom screen
- driver, or use QDirectPainter.
-*/
-
-/*! \fn int QApplication::qwsProcessEvent(QWSEvent* event)
- \internal
-*/
-
-/*! \fn int QApplication::x11ClientMessage(QWidget* w, XEvent* event, bool passive_only)
- \internal
-*/
-
-/*! \fn int QApplication::x11ProcessEvent(XEvent* event)
- This function does the core processing of individual X
- \a{event}s, normally by dispatching Qt events to the right
- destination.
-
- It returns 1 if the event was consumed by special handling, 0 if
- the \a event was consumed by normal handling, and -1 if the \a
- event was for an unrecognized widget.
-
- \sa x11EventFilter()
-*/
-
-/*!
- \fn bool QApplication::x11EventFilter(XEvent *event)
-
- \warning This virtual function is only implemented under X11.
-
- If you create an application that inherits QApplication and
- reimplement this function, you get direct access to all X events
- that the are received from the X server. The events are passed in
- the \a event parameter.
-
- Return true if you want to stop the event from being processed.
- Return false for normal event dispatching. The default
- implementation returns false.
-
- It is only the directly addressed messages that are filtered.
- You must install an event filter directly on the event
- dispatcher, which is returned by
- QAbstractEventDispatcher::instance(), to handle system wide
- messages.
-
- \sa x11ProcessEvent()
-*/
-
-/*! \fn void QApplication::winFocus(QWidget *widget, bool gotFocus)
- \internal
- \since 4.1
-
- If \a gotFocus is true, \a widget will become the active window.
- Otherwise the active window is reset to 0.
-*/
-
-/*! \fn void QApplication::winMouseButtonUp()
- \internal
- */
-
-/*! \fn void QApplication::syncX()
- Synchronizes with the X server in the X11 implementation.
- This normally takes some time. Does nothing on other platforms.
-*/
-
-void QApplicationPrivate::updateTouchPointsForWidget(QWidget *widget, QTouchEvent *touchEvent)
-{
- for (int i = 0; i < touchEvent->touchPoints().count(); ++i) {
- QTouchEvent::TouchPoint &touchPoint = touchEvent->_touchPoints[i];
-
- // preserve the sub-pixel resolution
- QRectF rect = touchPoint.screenRect();
- const QPointF screenPos = rect.center();
- const QPointF delta = screenPos - screenPos.toPoint();
-
- rect.moveCenter(widget->mapFromGlobal(screenPos.toPoint()) + delta);
- touchPoint.d->rect = rect;
- if (touchPoint.state() == Qt::TouchPointPressed) {
- touchPoint.d->startPos = widget->mapFromGlobal(touchPoint.startScreenPos().toPoint()) + delta;
- touchPoint.d->lastPos = widget->mapFromGlobal(touchPoint.lastScreenPos().toPoint()) + delta;
- }
- }
-}
-
-void QApplicationPrivate::initializeMultitouch()
-{
- widgetForTouchPointId.clear();
- appCurrentTouchPoints.clear();
-
- initializeMultitouch_sys();
-}
-
-void QApplicationPrivate::cleanupMultitouch()
-{
- cleanupMultitouch_sys();
-
- widgetForTouchPointId.clear();
- appCurrentTouchPoints.clear();
-}
-
-int QApplicationPrivate::findClosestTouchPointId(const QPointF &screenPos)
-{
- int closestTouchPointId = -1;
- qreal closestDistance = qreal(0.);
- foreach (const QTouchEvent::TouchPoint &touchPoint, appCurrentTouchPoints) {
- qreal distance = QLineF(screenPos, touchPoint.screenPos()).length();
- if (closestTouchPointId == -1 || distance < closestDistance) {
- closestTouchPointId = touchPoint.id();
- closestDistance = distance;
- }
- }
- return closestTouchPointId;
-}
-
-void QApplicationPrivate::translateRawTouchEvent(QWidget *window,
- QTouchEvent::DeviceType deviceType,
- const QList<QTouchEvent::TouchPoint> &touchPoints)
-{
- QApplicationPrivate *d = self;
- typedef QPair<Qt::TouchPointStates, QList<QTouchEvent::TouchPoint> > StatesAndTouchPoints;
- QHash<QWidget *, StatesAndTouchPoints> widgetsNeedingEvents;
-
- for (int i = 0; i < touchPoints.count(); ++i) {
- QTouchEvent::TouchPoint touchPoint = touchPoints.at(i);
- // explicitly detach from the original touch point that we got, so even
- // if the touchpoint structs are reused, we will make a copy that we'll
- // deliver to the user (which might want to store the struct for later use).
- touchPoint.d = touchPoint.d->detach();
-
- // update state
- QWeakPointer<QWidget> widget;
- switch (touchPoint.state()) {
- case Qt::TouchPointPressed:
- {
- if (deviceType == QTouchEvent::TouchPad) {
- // on touch-pads, send all touch points to the same widget
- widget = d->widgetForTouchPointId.isEmpty()
- ? QWeakPointer<QWidget>()
- : d->widgetForTouchPointId.constBegin().value();
- }
-
- if (!widget) {
- // determine which widget this event will go to
- if (!window)
- window = QApplication::topLevelAt(touchPoint.screenPos().toPoint());
- if (!window)
- continue;
- widget = window->childAt(window->mapFromGlobal(touchPoint.screenPos().toPoint()));
- if (!widget)
- widget = window;
- }
-
- if (deviceType == QTouchEvent::TouchScreen) {
- int closestTouchPointId = d->findClosestTouchPointId(touchPoint.screenPos());
- QWidget *closestWidget = d->widgetForTouchPointId.value(closestTouchPointId).data();
- if (closestWidget
- && (widget.data()->isAncestorOf(closestWidget) || closestWidget->isAncestorOf(widget.data()))) {
- widget = closestWidget;
- }
- }
-
- d->widgetForTouchPointId[touchPoint.id()] = widget;
- touchPoint.d->startScreenPos = touchPoint.screenPos();
- touchPoint.d->lastScreenPos = touchPoint.screenPos();
- touchPoint.d->startNormalizedPos = touchPoint.normalizedPos();
- touchPoint.d->lastNormalizedPos = touchPoint.normalizedPos();
- if (touchPoint.pressure() < qreal(0.))
- touchPoint.d->pressure = qreal(1.);
-
- d->appCurrentTouchPoints.insert(touchPoint.id(), touchPoint);
- break;
- }
- case Qt::TouchPointReleased:
- {
- widget = d->widgetForTouchPointId.take(touchPoint.id());
- if (!widget)
- continue;
-
- QTouchEvent::TouchPoint previousTouchPoint = d->appCurrentTouchPoints.take(touchPoint.id());
- touchPoint.d->startScreenPos = previousTouchPoint.startScreenPos();
- touchPoint.d->lastScreenPos = previousTouchPoint.screenPos();
- touchPoint.d->startPos = previousTouchPoint.startPos();
- touchPoint.d->lastPos = previousTouchPoint.pos();
- touchPoint.d->startNormalizedPos = previousTouchPoint.startNormalizedPos();
- touchPoint.d->lastNormalizedPos = previousTouchPoint.normalizedPos();
- if (touchPoint.pressure() < qreal(0.))
- touchPoint.d->pressure = qreal(0.);
- break;
- }
- default:
- widget = d->widgetForTouchPointId.value(touchPoint.id());
- if (!widget)
- continue;
-
- Q_ASSERT(d->appCurrentTouchPoints.contains(touchPoint.id()));
- QTouchEvent::TouchPoint previousTouchPoint = d->appCurrentTouchPoints.value(touchPoint.id());
- touchPoint.d->startScreenPos = previousTouchPoint.startScreenPos();
- touchPoint.d->lastScreenPos = previousTouchPoint.screenPos();
- touchPoint.d->startPos = previousTouchPoint.startPos();
- touchPoint.d->lastPos = previousTouchPoint.pos();
- touchPoint.d->startNormalizedPos = previousTouchPoint.startNormalizedPos();
- touchPoint.d->lastNormalizedPos = previousTouchPoint.normalizedPos();
- if (touchPoint.pressure() < qreal(0.))
- touchPoint.d->pressure = qreal(1.);
- d->appCurrentTouchPoints[touchPoint.id()] = touchPoint;
- break;
- }
- Q_ASSERT(widget.data() != 0);
-
- // make the *scene* functions return the same as the *screen* functions
- touchPoint.d->sceneRect = touchPoint.screenRect();
- touchPoint.d->startScenePos = touchPoint.startScreenPos();
- touchPoint.d->lastScenePos = touchPoint.lastScreenPos();
-
- StatesAndTouchPoints &maskAndPoints = widgetsNeedingEvents[widget.data()];
- maskAndPoints.first |= touchPoint.state();
- if (touchPoint.isPrimary())
- maskAndPoints.first |= Qt::TouchPointPrimary;
- maskAndPoints.second.append(touchPoint);
- }
-
- if (widgetsNeedingEvents.isEmpty())
- return;
-
- QHash<QWidget *, StatesAndTouchPoints>::ConstIterator it = widgetsNeedingEvents.constBegin();
- const QHash<QWidget *, StatesAndTouchPoints>::ConstIterator end = widgetsNeedingEvents.constEnd();
- for (; it != end; ++it) {
- QWidget *widget = it.key();
- if (!QApplicationPrivate::tryModalHelper(widget, 0))
- continue;
-
- QEvent::Type eventType;
- switch (it.value().first & Qt::TouchPointStateMask) {
- case Qt::TouchPointPressed:
- eventType = QEvent::TouchBegin;
- break;
- case Qt::TouchPointReleased:
- eventType = QEvent::TouchEnd;
- break;
- case Qt::TouchPointStationary:
- // don't send the event if nothing changed
- continue;
- default:
- eventType = QEvent::TouchUpdate;
- break;
- }
-
- QTouchEvent touchEvent(eventType,
- deviceType,
- QApplication::keyboardModifiers(),
- it.value().first,
- it.value().second);
- updateTouchPointsForWidget(widget, &touchEvent);
-
- switch (touchEvent.type()) {
- case QEvent::TouchBegin:
- {
- // if the TouchBegin handler recurses, we assume that means the event
- // has been implicitly accepted and continue to send touch events
- widget->setAttribute(Qt::WA_WState_AcceptedTouchBeginEvent);
- (void ) QApplication::sendSpontaneousEvent(widget, &touchEvent);
- break;
- }
- default:
- if (widget->testAttribute(Qt::WA_WState_AcceptedTouchBeginEvent)) {
- if (touchEvent.type() == QEvent::TouchEnd)
- widget->setAttribute(Qt::WA_WState_AcceptedTouchBeginEvent, false);
- (void) QApplication::sendSpontaneousEvent(widget, &touchEvent);
- }
- break;
- }
- }
-}
-
-Q_GUI_EXPORT void qt_translateRawTouchEvent(QWidget *window,
- QTouchEvent::DeviceType deviceType,
- const QList<QTouchEvent::TouchPoint> &touchPoints)
-{
- QApplicationPrivate::translateRawTouchEvent(window, deviceType, touchPoints);
-}
-
-#ifndef QT_NO_GESTURES
-QGestureManager* QGestureManager::instance()
-{
- QApplicationPrivate *qAppPriv = QApplicationPrivate::instance();
- if (!qAppPriv)
- return 0;
- if (!qAppPriv->gestureManager)
- qAppPriv->gestureManager = new QGestureManager(qApp);
- return qAppPriv->gestureManager;
-}
-#endif // QT_NO_GESTURES
-
-// These pixmaps approximate the images in the Windows User Interface Guidelines.
-
-// XPM
-
-static const char * const move_xpm[] = {
-"11 20 3 1",
-". c None",
-#if defined(Q_WS_WIN)
-"a c #000000",
-"X c #FFFFFF", // Windows cursor is traditionally white
-#else
-"a c #FFFFFF",
-"X c #000000", // X11 cursor is traditionally black
-#endif
-"aa.........",
-"aXa........",
-"aXXa.......",
-"aXXXa......",
-"aXXXXa.....",
-"aXXXXXa....",
-"aXXXXXXa...",
-"aXXXXXXXa..",
-"aXXXXXXXXa.",
-"aXXXXXXXXXa",
-"aXXXXXXaaaa",
-"aXXXaXXa...",
-"aXXaaXXa...",
-"aXa..aXXa..",
-"aa...aXXa..",
-"a.....aXXa.",
-"......aXXa.",
-".......aXXa",
-".......aXXa",
-"........aa."};
-
-#ifdef Q_WS_WIN
-/* XPM */
-static const char * const ignore_xpm[] = {
-"24 30 3 1",
-". c None",
-"a c #000000",
-"X c #FFFFFF",
-"aa......................",
-"aXa.....................",
-"aXXa....................",
-"aXXXa...................",
-"aXXXXa..................",
-"aXXXXXa.................",
-"aXXXXXXa................",
-"aXXXXXXXa...............",
-"aXXXXXXXXa..............",
-"aXXXXXXXXXa.............",
-"aXXXXXXaaaa.............",
-"aXXXaXXa................",
-"aXXaaXXa................",
-"aXa..aXXa...............",
-"aa...aXXa...............",
-"a.....aXXa..............",
-"......aXXa.....XXXX.....",
-".......aXXa..XXaaaaXX...",
-".......aXXa.XaaaaaaaaX..",
-"........aa.XaaaXXXXaaaX.",
-"...........XaaaaX..XaaX.",
-"..........XaaXaaaX..XaaX",
-"..........XaaXXaaaX.XaaX",
-"..........XaaX.XaaaXXaaX",
-"..........XaaX..XaaaXaaX",
-"...........XaaX..XaaaaX.",
-"...........XaaaXXXXaaaX.",
-"............XaaaaaaaaX..",
-".............XXaaaaXX...",
-"...............XXXX....."};
-#endif
-
-/* XPM */
-static const char * const copy_xpm[] = {
-"24 30 3 1",
-". c None",
-"a c #000000",
-"X c #FFFFFF",
-#if defined(Q_WS_WIN) // Windows cursor is traditionally white
-"aa......................",
-"aXa.....................",
-"aXXa....................",
-"aXXXa...................",
-"aXXXXa..................",
-"aXXXXXa.................",
-"aXXXXXXa................",
-"aXXXXXXXa...............",
-"aXXXXXXXXa..............",
-"aXXXXXXXXXa.............",
-"aXXXXXXaaaa.............",
-"aXXXaXXa................",
-"aXXaaXXa................",
-"aXa..aXXa...............",
-"aa...aXXa...............",
-"a.....aXXa..............",
-"......aXXa..............",
-".......aXXa.............",
-".......aXXa.............",
-"........aa...aaaaaaaaaaa",
-#else
-"XX......................",
-"XaX.....................",
-"XaaX....................",
-"XaaaX...................",
-"XaaaaX..................",
-"XaaaaaX.................",
-"XaaaaaaX................",
-"XaaaaaaaX...............",
-"XaaaaaaaaX..............",
-"XaaaaaaaaaX.............",
-"XaaaaaaXXXX.............",
-"XaaaXaaX................",
-"XaaXXaaX................",
-"XaX..XaaX...............",
-"XX...XaaX...............",
-"X.....XaaX..............",
-"......XaaX..............",
-".......XaaX.............",
-".......XaaX.............",
-"........XX...aaaaaaaaaaa",
-#endif
-".............aXXXXXXXXXa",
-".............aXXXXXXXXXa",
-".............aXXXXaXXXXa",
-".............aXXXXaXXXXa",
-".............aXXaaaaaXXa",
-".............aXXXXaXXXXa",
-".............aXXXXaXXXXa",
-".............aXXXXXXXXXa",
-".............aXXXXXXXXXa",
-".............aaaaaaaaaaa"};
-
-/* XPM */
-static const char * const link_xpm[] = {
-"24 30 3 1",
-". c None",
-"a c #000000",
-"X c #FFFFFF",
-#if defined(Q_WS_WIN) // Windows cursor is traditionally white
-"aa......................",
-"aXa.....................",
-"aXXa....................",
-"aXXXa...................",
-"aXXXXa..................",
-"aXXXXXa.................",
-"aXXXXXXa................",
-"aXXXXXXXa...............",
-"aXXXXXXXXa..............",
-"aXXXXXXXXXa.............",
-"aXXXXXXaaaa.............",
-"aXXXaXXa................",
-"aXXaaXXa................",
-"aXa..aXXa...............",
-"aa...aXXa...............",
-"a.....aXXa..............",
-"......aXXa..............",
-".......aXXa.............",
-".......aXXa.............",
-"........aa...aaaaaaaaaaa",
-#else
-"XX......................",
-"XaX.....................",
-"XaaX....................",
-"XaaaX...................",
-"XaaaaX..................",
-"XaaaaaX.................",
-"XaaaaaaX................",
-"XaaaaaaaX...............",
-"XaaaaaaaaX..............",
-"XaaaaaaaaaX.............",
-"XaaaaaaXXXX.............",
-"XaaaXaaX................",
-"XaaXXaaX................",
-"XaX..XaaX...............",
-"XX...XaaX...............",
-"X.....XaaX..............",
-"......XaaX..............",
-".......XaaX.............",
-".......XaaX.............",
-"........XX...aaaaaaaaaaa",
-#endif
-".............aXXXXXXXXXa",
-".............aXXXaaaaXXa",
-".............aXXXXaaaXXa",
-".............aXXXaaaaXXa",
-".............aXXaaaXaXXa",
-".............aXXaaXXXXXa",
-".............aXXaXXXXXXa",
-".............aXXXaXXXXXa",
-".............aXXXXXXXXXa",
-".............aaaaaaaaaaa"};
-
-QPixmap QApplicationPrivate::getPixmapCursor(Qt::CursorShape cshape)
-{
-#if defined(Q_WS_X11) || defined(Q_WS_WIN)
- if (!move_cursor) {
- move_cursor = new QPixmap((const char **)move_xpm);
- copy_cursor = new QPixmap((const char **)copy_xpm);
- link_cursor = new QPixmap((const char **)link_xpm);
-#ifdef Q_WS_WIN
- ignore_cursor = new QPixmap((const char **)ignore_xpm);
-#endif
- }
-
- switch (cshape) {
- case Qt::DragMoveCursor:
- return *move_cursor;
- case Qt::DragCopyCursor:
- return *copy_cursor;
- case Qt::DragLinkCursor:
- return *link_cursor;
-#ifdef Q_WS_WIN
- case Qt::ForbiddenCursor:
- return *ignore_cursor;
-#endif
- default:
- break;
- }
-#else
- Q_UNUSED(cshape);
-#endif
- return QPixmap();
-}
-
-QString QApplicationPrivate::qmljsDebugArgumentsString()
-{
- return qmljs_debug_arguments;
-}
-
-QT_END_NAMESPACE
-
-#include "moc_qapplication.cpp"
diff --git a/src/gui/kernel/qapplication.h b/src/gui/kernel/qapplication.h
deleted file mode 100644
index 15488490d1..0000000000
--- a/src/gui/kernel/qapplication.h
+++ /dev/null
@@ -1,431 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QAPPLICATION_H
-#define QAPPLICATION_H
-
-#include <QtCore/qcoreapplication.h>
-#include <QtGui/qwindowdefs.h>
-#include <QtCore/qpoint.h>
-#include <QtCore/qsize.h>
-#include <QtGui/qcursor.h>
-#ifdef QT_INCLUDE_COMPAT
-# include <QtGui/qdesktopwidget.h>
-#endif
-#ifdef QT3_SUPPORT
-# include <QtGui/qwidget.h>
-# include <QtGui/qpalette.h>
-#endif
-#ifdef Q_WS_QWS
-# include <QtGui/qrgb.h>
-# include <QtGui/qtransportauth_qws.h>
-#endif
-
-QT_BEGIN_HEADER
-
-#if defined(Q_OS_SYMBIAN)
-class CApaApplication;
-#endif
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QSessionManager;
-class QDesktopWidget;
-class QStyle;
-class QEventLoop;
-class QIcon;
-class QInputContext;
-template <typename T> class QList;
-class QLocale;
-#if defined(Q_WS_QWS)
-class QDecoration;
-#elif defined(Q_WS_QPA)
-class QPlatformNativeInterface;
-#endif
-#if defined(Q_OS_SYMBIAN)
-class QSymbianEvent;
-#endif
-
-class QApplication;
-class QApplicationPrivate;
-#if defined(qApp)
-#undef qApp
-#endif
-#define qApp (static_cast<QApplication *>(QCoreApplication::instance()))
-
-
-class Q_GUI_EXPORT QApplication : public QCoreApplication
-{
- Q_OBJECT
- Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection)
- Q_PROPERTY(QIcon windowIcon READ windowIcon WRITE setWindowIcon)
- Q_PROPERTY(int cursorFlashTime READ cursorFlashTime WRITE setCursorFlashTime)
- Q_PROPERTY(int doubleClickInterval READ doubleClickInterval WRITE setDoubleClickInterval)
- Q_PROPERTY(int keyboardInputInterval READ keyboardInputInterval WRITE setKeyboardInputInterval)
-#ifndef QT_NO_WHEELEVENT
- Q_PROPERTY(int wheelScrollLines READ wheelScrollLines WRITE setWheelScrollLines)
-#endif
- Q_PROPERTY(QSize globalStrut READ globalStrut WRITE setGlobalStrut)
- Q_PROPERTY(int startDragTime READ startDragTime WRITE setStartDragTime)
- Q_PROPERTY(int startDragDistance READ startDragDistance WRITE setStartDragDistance)
- Q_PROPERTY(bool quitOnLastWindowClosed READ quitOnLastWindowClosed WRITE setQuitOnLastWindowClosed)
-#ifndef QT_NO_STYLE_STYLESHEET
- Q_PROPERTY(QString styleSheet READ styleSheet WRITE setStyleSheet)
-#endif
-#ifdef Q_WS_WINCE
- Q_PROPERTY(int autoMaximizeThreshold READ autoMaximizeThreshold WRITE setAutoMaximizeThreshold)
-#endif
- Q_PROPERTY(bool autoSipEnabled READ autoSipEnabled WRITE setAutoSipEnabled)
-
-public:
- enum Type { Tty, GuiClient, GuiServer };
-
-#ifdef Q_OS_SYMBIAN
- typedef CApaApplication * (*QS60MainApplicationFactory)();
-#endif
-
-#ifndef qdoc
- QApplication(int &argc, char **argv, int = ApplicationFlags);
- QApplication(int &argc, char **argv, bool GUIenabled, int = ApplicationFlags);
- QApplication(int &argc, char **argv, Type, int = ApplicationFlags);
-#if defined(Q_WS_X11)
- QApplication(Display* dpy, Qt::HANDLE visual = 0, Qt::HANDLE cmap = 0, int = ApplicationFlags);
- QApplication(Display *dpy, int &argc, char **argv, Qt::HANDLE visual = 0, Qt::HANDLE cmap= 0, int = ApplicationFlags);
-#endif
-#if defined(Q_OS_SYMBIAN)
- QApplication(QApplication::QS60MainApplicationFactory factory, int &argc, char **argv, int = ApplicationFlags);
-#endif
-#endif
- virtual ~QApplication();
-
- static Type type();
-
- static QStyle *style();
- static void setStyle(QStyle*);
- static QStyle *setStyle(const QString&);
- enum ColorSpec { NormalColor=0, CustomColor=1, ManyColor=2 };
- static int colorSpec();
- static void setColorSpec(int);
- static void setGraphicsSystem(const QString &);
-
-#ifndef QT_NO_CURSOR
- static QCursor *overrideCursor();
- static void setOverrideCursor(const QCursor &);
- static void changeOverrideCursor(const QCursor &);
- static void restoreOverrideCursor();
-#endif
- static QPalette palette();
- static QPalette palette(const QWidget *);
- static QPalette palette(const char *className);
- static void setPalette(const QPalette &, const char* className = 0);
- static QFont font();
- static QFont font(const QWidget*);
- static QFont font(const char *className);
- static void setFont(const QFont &, const char* className = 0);
- static QFontMetrics fontMetrics();
-
- static void setWindowIcon(const QIcon &icon);
- static QIcon windowIcon();
-
-
-#ifdef QT3_SUPPORT
- static QT3_SUPPORT QWidget *mainWidget();
- static QT3_SUPPORT void setMainWidget(QWidget *);
-#endif
-
- static QWidgetList allWidgets();
- static QWidgetList topLevelWidgets();
-
- static QDesktopWidget *desktop();
-
- static QWidget *activePopupWidget();
- static QWidget *activeModalWidget();
-#ifndef QT_NO_CLIPBOARD
- static QClipboard *clipboard();
-#endif
- static QWidget *focusWidget();
-
- static QWidget *activeWindow();
- static void setActiveWindow(QWidget* act);
-
- static QWidget *widgetAt(const QPoint &p);
- static inline QWidget *widgetAt(int x, int y) { return widgetAt(QPoint(x, y)); }
- static QWidget *topLevelAt(const QPoint &p);
- static inline QWidget *topLevelAt(int x, int y) { return topLevelAt(QPoint(x, y)); }
-
- static void syncX();
- static void beep();
- static void alert(QWidget *widget, int duration = 0);
-
- static Qt::KeyboardModifiers keyboardModifiers();
- static Qt::KeyboardModifiers queryKeyboardModifiers();
- static Qt::MouseButtons mouseButtons();
-
- static void setDesktopSettingsAware(bool);
- static bool desktopSettingsAware();
-
- static void setCursorFlashTime(int);
- static int cursorFlashTime();
-
- static void setDoubleClickInterval(int);
- static int doubleClickInterval();
-
- static void setKeyboardInputInterval(int);
- static int keyboardInputInterval();
-
-#ifndef QT_NO_WHEELEVENT
- static void setWheelScrollLines(int);
- static int wheelScrollLines();
-#endif
- static void setGlobalStrut(const QSize &);
- static QSize globalStrut();
-
- static void setStartDragTime(int ms);
- static int startDragTime();
- static void setStartDragDistance(int l);
- static int startDragDistance();
-
- static void setLayoutDirection(Qt::LayoutDirection direction);
- static Qt::LayoutDirection layoutDirection();
-
- static inline bool isRightToLeft() { return layoutDirection() == Qt::RightToLeft; }
- static inline bool isLeftToRight() { return layoutDirection() == Qt::LeftToRight; }
-
- static bool isEffectEnabled(Qt::UIEffect);
- static void setEffectEnabled(Qt::UIEffect, bool enable = true);
-
-#if defined(Q_WS_MAC)
- virtual bool macEventFilter(EventHandlerCallRef, EventRef);
-#endif
-#if defined(Q_WS_X11)
- virtual bool x11EventFilter(XEvent *);
- virtual int x11ClientMessage(QWidget*, XEvent*, bool passive_only);
- int x11ProcessEvent(XEvent*);
-#endif
-#if defined(Q_OS_SYMBIAN)
- int symbianProcessEvent(const QSymbianEvent *event);
- virtual bool symbianEventFilter(const QSymbianEvent *event);
-#endif
-#if defined(Q_WS_QWS)
- virtual bool qwsEventFilter(QWSEvent *);
- int qwsProcessEvent(QWSEvent*);
- void qwsSetCustomColors(QRgb *colortable, int start, int numColors);
-#ifndef QT_NO_QWS_MANAGER
- static QDecoration &qwsDecoration();
- static void qwsSetDecoration(QDecoration *);
- static QDecoration *qwsSetDecoration(const QString &decoration);
-#endif
-#endif
-
-#if defined(Q_WS_QPA)
- static QPlatformNativeInterface *platformNativeInterface();
-#endif
-
-
-#if defined(Q_WS_WIN)
- void winFocus(QWidget *, bool);
- static void winMouseButtonUp();
-#endif
-#ifndef QT_NO_SESSIONMANAGER
- // session management
- bool isSessionRestored() const;
- QString sessionId() const;
- QString sessionKey() const;
- virtual void commitData(QSessionManager& sm);
- virtual void saveState(QSessionManager& sm);
-#endif
-
-#ifndef QT_NO_IM
- void setInputContext(QInputContext *);
- QInputContext *inputContext() const;
-#endif
-
- static QLocale keyboardInputLocale();
- static Qt::LayoutDirection keyboardInputDirection();
-
- static int exec();
- bool notify(QObject *, QEvent *);
-
-
- static void setQuitOnLastWindowClosed(bool quit);
- static bool quitOnLastWindowClosed();
-
-#ifdef QT_KEYPAD_NAVIGATION
- static Q_DECL_DEPRECATED void setKeypadNavigationEnabled(bool);
- static bool keypadNavigationEnabled();
- static void setNavigationMode(Qt::NavigationMode mode);
- static Qt::NavigationMode navigationMode();
-#endif
-
-Q_SIGNALS:
- void lastWindowClosed();
- void focusChanged(QWidget *old, QWidget *now);
- void fontDatabaseChanged();
-#ifndef QT_NO_SESSIONMANAGER
- void commitDataRequest(QSessionManager &sessionManager);
- void saveStateRequest(QSessionManager &sessionManager);
-#endif
-
-public:
- QString styleSheet() const;
-public Q_SLOTS:
-#ifndef QT_NO_STYLE_STYLESHEET
- void setStyleSheet(const QString& sheet);
-#endif
-#ifdef Q_WS_WINCE
- void setAutoMaximizeThreshold(const int threshold);
- int autoMaximizeThreshold() const;
-#endif
- void setAutoSipEnabled(const bool enabled);
- bool autoSipEnabled() const;
- static void closeAllWindows();
- static void aboutQt();
-
-protected:
-#if defined(Q_WS_QWS)
- void setArgs(int, char **);
-#endif
- bool event(QEvent *);
- bool compressEvent(QEvent *, QObject *receiver, QPostEventList *);
-
-#ifdef QT3_SUPPORT
-public:
- static inline QT3_SUPPORT void setReverseLayout(bool b) { setLayoutDirection(b?Qt::RightToLeft:Qt::LeftToRight); }
- static inline bool QT3_SUPPORT reverseLayout() { return layoutDirection() == Qt::RightToLeft; }
- static QT3_SUPPORT Qt::Alignment horizontalAlignment(Qt::Alignment align);
- typedef int ColorMode;
- enum { NormalColors = NormalColor, CustomColors = CustomColor };
- static inline QT3_SUPPORT ColorMode colorMode() { return static_cast<ColorMode>(colorSpec()); }
- static inline QT3_SUPPORT void setColorMode(ColorMode mode) { setColorSpec(int(mode)); }
-#if defined(Q_OS_WIN32) || defined(Q_OS_CYGWIN)
- static QT3_SUPPORT Qt::WindowsVersion winVersion() { return (Qt::WindowsVersion)QSysInfo::WindowsVersion; }
-#endif
-#if defined(Q_OS_MAC)
- static QT3_SUPPORT Qt::MacintoshVersion macVersion() { return (Qt::MacintoshVersion)QSysInfo::MacintoshVersion; }
-#endif
-# ifndef QT_NO_CURSOR
- inline static QT3_SUPPORT void setOverrideCursor(const QCursor &cursor, bool replace)
- { if (replace) changeOverrideCursor(cursor); else setOverrideCursor(cursor); }
-# endif
- inline static QT3_SUPPORT bool hasGlobalMouseTracking() {return true;}
- inline static QT3_SUPPORT void setGlobalMouseTracking(bool) {}
- inline static QT3_SUPPORT void flushX() { flush(); }
- static inline QT3_SUPPORT void setWinStyleHighlightColor(const QColor &c) {
- QPalette p(palette());
- p.setColor(QPalette::Highlight, c);
- setPalette(p);
- }
- static inline QT3_SUPPORT const QColor &winStyleHighlightColor()
- { return palette().color(QPalette::Active, QPalette::Highlight); }
- static inline QT3_SUPPORT void setPalette(const QPalette &pal, bool, const char* className = 0)
- { setPalette(pal, className); }
- static inline QT3_SUPPORT void setFont(const QFont &font, bool, const char* className = 0)
- { setFont(font, className); }
-
- static inline QT3_SUPPORT QWidget *widgetAt(int x, int y, bool child)
- { QWidget *w = widgetAt(x, y); return child ? w : (w ? w->window() : 0); }
- static inline QT3_SUPPORT QWidget *widgetAt(const QPoint &p, bool child)
- { QWidget *w = widgetAt(p); return child ? w : (w ? w->window() : 0); }
-#endif // QT3_SUPPORT
-
-#if defined(Q_INTERNAL_QAPP_SRC) || defined(qdoc)
- QApplication(int &argc, char **argv);
- QApplication(int &argc, char **argv, bool GUIenabled);
- QApplication(int &argc, char **argv, Type);
-#if defined(Q_WS_X11)
- QApplication(Display* dpy, Qt::HANDLE visual = 0, Qt::HANDLE cmap = 0);
- QApplication(Display *dpy, int &argc, char **argv, Qt::HANDLE visual = 0, Qt::HANDLE cmap= 0);
-#endif
-#if defined(Q_OS_SYMBIAN) || defined(qdoc)
- QApplication(QApplication::QS60MainApplicationFactory factory, int &argc, char **argv);
-#endif
-#endif
-
-private:
- Q_DISABLE_COPY(QApplication)
- Q_DECLARE_PRIVATE(QApplication)
-
- friend class QGraphicsWidget;
- friend class QGraphicsItem;
- friend class QGraphicsScene;
- friend class QGraphicsScenePrivate;
- friend class QWidget;
- friend class QWidgetPrivate;
- friend class QETWidget;
- friend class Q3AccelManager;
- friend class QTranslator;
- friend class QWidgetAnimator;
-#ifndef QT_NO_SHORTCUT
- friend class QShortcut;
- friend class QLineEdit;
- friend class QTextControl;
-#endif
- friend class QAction;
- friend class QFontDatabasePrivate;
-
-#if defined(Q_WS_QWS)
- friend class QInputContext;
- friend class QWSDirectPainterSurface;
- friend class QDirectPainter;
- friend class QDirectPainterPrivate;
-#endif
-#ifndef QT_NO_GESTURES
- friend class QGestureManager;
-#endif
-
-#if defined(Q_WS_MAC) || defined(Q_WS_X11)
- Q_PRIVATE_SLOT(d_func(), void _q_alertTimeOut())
-#endif
-#if defined(QT_RX71_MULTITOUCH)
- Q_PRIVATE_SLOT(d_func(), void _q_readRX71MultiTouchEvents())
-#endif
-#if defined(Q_OS_SYMBIAN)
- Q_PRIVATE_SLOT(d_func(), void _q_aboutToQuit())
-#endif
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QAPPLICATION_H
diff --git a/src/gui/kernel/qapplication_mac.mm b/src/gui/kernel/qapplication_mac.mm
deleted file mode 100644
index e06756c86a..0000000000
--- a/src/gui/kernel/qapplication_mac.mm
+++ /dev/null
@@ -1,3137 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/****************************************************************************
-**
-** Copyright (c) 2007-2008, Apple, Inc.
-**
-** All rights reserved.
-**
-** Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are met:
-**
-** * Redistributions of source code must retain the above copyright notice,
-** this list of conditions and the following disclaimer.
-**
-** * Redistributions in binary form must reproduce the above copyright notice,
-** this list of conditions and the following disclaimer in the documentation
-** and/or other materials provided with the distribution.
-**
-** * Neither the name of Apple, Inc. nor the names of its contributors
-** may be used to endorse or promote products derived from this software
-** without specific prior written permission.
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-**
-****************************************************************************/
-
-#include <Cocoa/Cocoa.h>
-
-#include "qapplication.h"
-#include "qbitarray.h"
-#include "qclipboard.h"
-#include "qcursor.h"
-#include "qdatastream.h"
-#include "qdatetime.h"
-#include "qdesktopwidget.h"
-#include "qdockwidget.h"
-#include "qevent.h"
-#include "qhash.h"
-#include "qlayout.h"
-#include "qmenubar.h"
-#include "qmessagebox.h"
-#include "qmime.h"
-#include "qpixmapcache.h"
-#include "qpointer.h"
-#include "qsessionmanager.h"
-#include "qsettings.h"
-#include "qsocketnotifier.h"
-#include "qstyle.h"
-#include "qstylefactory.h"
-#include "qtextcodec.h"
-#include "qtoolbar.h"
-#include "qvariant.h"
-#include "qwidget.h"
-#include "qcolormap.h"
-#include "qdir.h"
-#include "qdebug.h"
-#include "qtimer.h"
-#include "qurl.h"
-#include "private/qmacinputcontext_p.h"
-#include "private/qpaintengine_mac_p.h"
-#include "private/qcursor_p.h"
-#include "private/qapplication_p.h"
-#include "private/qcolor_p.h"
-#include "private/qwidget_p.h"
-#include "private/qkeymapper_p.h"
-#include "private/qeventdispatcher_mac_p.h"
-#include "private/qeventdispatcher_unix_p.h"
-#include <private/qcocoamenuloader_mac_p.h>
-#include <private/qcocoaapplication_mac_p.h>
-#include <private/qcocoaapplicationdelegate_mac_p.h>
-#include <private/qt_cocoa_helpers_mac_p.h>
-#include <private/qcocoawindow_mac_p.h>
-#include <private/qpixmap_mac_p.h>
-#include <private/qdesktopwidget_mac_p.h>
-#include <private/qeventdispatcher_mac_p.h>
-#include <qvarlengtharray.h>
-
-#ifndef QT_NO_ACCESSIBILITY
-# include "qaccessible.h"
-#endif
-
-#ifndef QT_NO_THREAD
-# include "qmutex.h"
-#endif
-
-#include <unistd.h>
-#include <string.h>
-#include <sys/time.h>
-#include <sys/select.h>
-
-/*****************************************************************************
- QApplication debug facilities
- *****************************************************************************/
-//#define DEBUG_EVENTS //like EventDebug but more specific to Qt
-//#define DEBUG_DROPPED_EVENTS
-//#define DEBUG_MOUSE_MAPS
-//#define DEBUG_MODAL_EVENTS
-//#define DEBUG_PLATFORM_SETTINGS
-
-#define QMAC_SPEAK_TO_ME
-#ifdef QMAC_SPEAK_TO_ME
-#include "qregexp.h"
-#endif
-
-#ifndef kThemeBrushAlternatePrimaryHighlightColor
-#define kThemeBrushAlternatePrimaryHighlightColor -5
-#endif
-
-#define kCMDeviceUnregisteredNotification CFSTR("CMDeviceUnregisteredNotification")
-#define kCMDefaultDeviceNotification CFSTR("CMDefaultDeviceNotification")
-#define kCMDeviceProfilesNotification CFSTR("CMDeviceProfilesNotification")
-#define kCMDefaultDeviceProfileNotification CFSTR("CMDefaultDeviceProfileNotification")
-
-QT_BEGIN_NAMESPACE
-
-//for qt_mac.h
-QPaintDevice *qt_mac_safe_pdev = 0;
-QList<QMacWindowChangeEvent*> *QMacWindowChangeEvent::change_events = 0;
-QPointer<QWidget> topLevelAt_cache = 0;
-
-/*****************************************************************************
- Internal variables and functions
- *****************************************************************************/
-static struct {
- bool use_qt_time_limit;
- QPointer<QWidget> last_widget;
- int last_x, last_y;
- int last_modifiers, last_button;
- EventTime last_time;
-} qt_mac_dblclick = { false, 0, -1, -1, 0, 0, -2 };
-
-static bool app_do_modal = false; // modal mode
-extern QWidgetList *qt_modal_stack; // stack of modal widgets
-extern bool qt_tab_all_widgets; // from qapplication.cpp
-bool qt_mac_app_fullscreen = false;
-bool qt_scrollbar_jump_to_pos = false;
-static bool qt_mac_collapse_on_dblclick = true;
-extern int qt_antialiasing_threshold; // from qapplication.cpp
-QWidget * qt_button_down; // widget got last button-down
-QPointer<QWidget> qt_last_mouse_receiver;
-#ifndef QT_MAC_USE_COCOA
-static bool qt_button_down_in_content; // whether the button_down was in the content area.
-static bool qt_mac_previous_press_in_popup_mode = false;
-static bool qt_mac_no_click_through_mode = false;
-static int tablet_button_state = 0;
-#endif
-#if defined(QT_DEBUG)
-static bool appNoGrab = false; // mouse/keyboard grabbing
-#endif
-#ifndef QT_MAC_USE_COCOA
-static EventHandlerRef app_proc_handler = 0;
-static EventHandlerUPP app_proc_handlerUPP = 0;
-#endif
-static AEEventHandlerUPP app_proc_ae_handlerUPP = NULL;
-static EventHandlerRef tablet_proximity_handler = 0;
-static EventHandlerUPP tablet_proximity_UPP = 0;
-bool QApplicationPrivate::native_modal_dialog_active;
-
-Q_GUI_EXPORT bool qt_applefontsmoothing_enabled;
-
-/*****************************************************************************
- External functions
- *****************************************************************************/
-extern void qt_mac_beep(); //qsound_mac.mm
-extern Qt::KeyboardModifiers qt_mac_get_modifiers(int keys); //qkeymapper_mac.cpp
-extern bool qt_mac_can_clickThrough(const QWidget *); //qwidget_mac.cpp
-extern bool qt_mac_is_macdrawer(const QWidget *); //qwidget_mac.cpp
-extern OSWindowRef qt_mac_window_for(const QWidget*); //qwidget_mac.cpp
-extern QWidget *qt_mac_find_window(OSWindowRef); //qwidget_mac.cpp
-extern void qt_mac_set_cursor(const QCursor *); //qcursor_mac.cpp
-extern bool qt_mac_is_macsheet(const QWidget *); //qwidget_mac.cpp
-extern QString qt_mac_from_pascal_string(const Str255); //qglobal.cpp
-extern void qt_mac_command_set_enabled(MenuRef, UInt32, bool); //qmenu_mac.cpp
-extern bool qt_sendSpontaneousEvent(QObject *obj, QEvent *event); // qapplication.cpp
-extern void qt_mac_update_cursor(); // qcursor_mac.mm
-
-// Forward Decls
-void onApplicationWindowChangedActivation( QWidget*widget, bool activated );
-void onApplicationChangedActivation( bool activated );
-
-static void qt_mac_read_fontsmoothing_settings()
-{
- qt_applefontsmoothing_enabled = true;
- int w = 10, h = 10;
- QImage image(w, h, QImage::Format_RGB32);
- image.fill(0xffffffff);
- QPainter p(&image);
- p.drawText(0, h, "X\\");
- p.end();
-
- const int *bits = (const int *) ((const QImage &) image).bits();
- int bpl = image.bytesPerLine() / 4;
- for (int y=0; y<w; ++y) {
- for (int x=0; x<h; ++x) {
- int r = qRed(bits[x]);
- int g = qGreen(bits[x]);
- int b = qBlue(bits[x]);
- if (r != g || r != b) {
- qt_applefontsmoothing_enabled = true;
- return;
- }
- }
- bits += bpl;
- }
- qt_applefontsmoothing_enabled = false;
-}
-
-Q_GUI_EXPORT bool qt_mac_execute_apple_script(const char *script, long script_len, AEDesc *ret) {
- OSStatus err;
- AEDesc scriptTextDesc;
- ComponentInstance theComponent = 0;
- OSAID scriptID = kOSANullScript, resultID = kOSANullScript;
-
- // set up locals to a known state
- AECreateDesc(typeNull, 0, 0, &scriptTextDesc);
- scriptID = kOSANullScript;
- resultID = kOSANullScript;
-
- // open the scripting component
- theComponent = OpenDefaultComponent(kOSAComponentType, typeAppleScript);
- if (!theComponent) {
- err = paramErr;
- goto bail;
- }
-
- // put the script text into an aedesc
- err = AECreateDesc(typeUTF8Text, script, script_len, &scriptTextDesc);
- if (err != noErr)
- goto bail;
-
- // compile the script
- err = OSACompile(theComponent, &scriptTextDesc, kOSAModeNull, &scriptID);
- if (err != noErr)
- goto bail;
-
- // run the script
- err = OSAExecute(theComponent, scriptID, kOSANullScript, kOSAModeNull, &resultID);
-
- // collect the results - if any
- if (ret) {
- AECreateDesc(typeNull, 0, 0, ret);
- if (err == errOSAScriptError)
- OSAScriptError(theComponent, kOSAErrorMessage, typeChar, ret);
- else if (err == noErr && resultID != kOSANullScript)
- OSADisplay(theComponent, resultID, typeChar, kOSAModeNull, ret);
- }
-bail:
- AEDisposeDesc(&scriptTextDesc);
- if (scriptID != kOSANullScript)
- OSADispose(theComponent, scriptID);
- if (resultID != kOSANullScript)
- OSADispose(theComponent, resultID);
- if (theComponent)
- CloseComponent(theComponent);
- return err == noErr;
-}
-
-Q_GUI_EXPORT bool qt_mac_execute_apple_script(const char *script, AEDesc *ret)
-{
- return qt_mac_execute_apple_script(script, qstrlen(script), ret);
-}
-
-Q_GUI_EXPORT bool qt_mac_execute_apple_script(const QString &script, AEDesc *ret)
-{
- const QByteArray l = script.toUtf8(); return qt_mac_execute_apple_script(l.constData(), l.size(), ret);
-}
-
-/* Resolution change magic */
-void qt_mac_display_change_callbk(CGDirectDisplayID, CGDisplayChangeSummaryFlags flags, void *)
-{
-#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
- const bool resized = flags & kCGDisplayDesktopShapeChangedFlag;
-#else
- Q_UNUSED(flags);
- const bool resized = true;
-#endif
- if (resized && qApp) {
- if (QDesktopWidget *dw = qApp->desktop()) {
- QResizeEvent *re = new QResizeEvent(dw->size(), dw->size());
- QApplication::postEvent(dw, re);
- QCoreGraphicsPaintEngine::cleanUpMacColorSpaces();
- }
- }
-}
-
-#ifdef DEBUG_PLATFORM_SETTINGS
-static void qt_mac_debug_palette(const QPalette &pal, const QPalette &pal2, const QString &where)
-{
- const char *const groups[] = {"Active", "Disabled", "Inactive" };
- const char *const roles[] = { "WindowText", "Button", "Light", "Midlight", "Dark", "Mid",
- "Text", "BrightText", "ButtonText", "Base", "Window", "Shadow",
- "Highlight", "HighlightedText", "Link", "LinkVisited" };
- if (!where.isNull())
- qDebug("qt-internal: %s", where.toLatin1().constData());
- for(int grp = 0; grp < QPalette::NColorGroups; grp++) {
- for(int role = 0; role < QPalette::NColorRoles; role++) {
- QBrush b = pal.brush((QPalette::ColorGroup)grp, (QPalette::ColorRole)role);
- QPixmap pm = b.texture();
- qDebug(" %s::%s %d::%d::%d [%p]%s", groups[grp], roles[role], b.color().red(),
- b.color().green(), b.color().blue(), pm.isNull() ? 0 : &pm,
- pal2.brush((QPalette::ColorGroup)grp, (QPalette::ColorRole)role) != b ? " (*)" : "");
- }
- }
-
-}
-#else
-#define qt_mac_debug_palette(x, y, z)
-#endif
-
-//raise a notification
-#ifndef QT_MAC_USE_COCOA
-static NMRec qt_mac_notification = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-#endif
-void qt_mac_send_notification()
-{
-#ifndef QT_MAC_USE_COCOA
- //send it
- qt_mac_notification.nmMark = 1; //non-zero magic number
- qt_mac_notification.qType = nmType;
- NMInstall(&qt_mac_notification);
-#else
- QMacCocoaAutoReleasePool pool;
- [[NSApplication sharedApplication] requestUserAttention:NSInformationalRequest];
-#endif
-}
-
-void qt_mac_cancel_notification()
-{
-#ifndef QT_MAC_USE_COCOA
- NMRemove(&qt_mac_notification);
-#else
- QMacCocoaAutoReleasePool pool;
- [[NSApplication sharedApplication] cancelUserAttentionRequest:NSInformationalRequest];
-#endif
-}
-
-#ifndef QT_MAC_USE_COCOA
-//find widget (and part) at a given point
-static short qt_mac_window_at(int x, int y, QWidget **w=0)
-{
- Point p;
- p.h = x;
- p.v = y;
- OSWindowRef wp;
- WindowPartCode wpc;
- OSStatus err = FindWindowOfClass(&p, kAllWindowClasses, &wp, &wpc);
- if(err != noErr) {
- if(w)
- (*w) = 0;
- return wpc;
- }
- if(w) {
- if(wp) {
- *w = qt_mac_find_window(wp);
-#if 0
- if(!*w)
- qWarning("QApplication: qt_mac_window_at: Couldn't find %d",(int)wp);
-#endif
- } else {
- *w = 0;
- }
- }
- return wpc;
-}
-
-#endif
-
-void qt_mac_set_app_icon(const QPixmap &pixmap)
-{
-#ifndef QT_MAC_USE_COCOA
- if(pixmap.isNull()) {
- RestoreApplicationDockTileImage();
- } else {
- CGImageRef img = (CGImageRef)pixmap.macCGHandle();
- SetApplicationDockTileImage(img);
- CGImageRelease(img);
- }
-#else
- QMacCocoaAutoReleasePool pool;
- NSImage *image = NULL;
- if (pixmap.isNull()) {
- // Get Application icon from bundle
- image = [[NSImage imageNamed:@"NSApplicationIcon"] retain]; // released below
- } else {
- image = static_cast<NSImage *>(qt_mac_create_nsimage(pixmap));
- }
-
- [NSApp setApplicationIconImage:image];
- [image release];
-#endif
-}
-
-Q_GUI_EXPORT void qt_mac_set_press_and_hold_context(bool b)
-{
- Q_UNUSED(b);
- qWarning("qt_mac_set_press_and_hold_context: This functionality is no longer available");
-}
-
-bool qt_nograb() // application no-grab option
-{
-#if defined(QT_DEBUG)
- return appNoGrab;
-#else
- return false;
-#endif
-}
-
-void qt_mac_update_os_settings()
-{
- if (!qApp)
- return;
- if (!QApplication::startingUp()) {
- static bool needToPolish = true;
- if (needToPolish) {
- QApplication::style()->polish(qApp);
- needToPolish = false;
- }
- }
- //focus mode
- /* First worked as of 10.2.3 */
- QSettings appleSettings(QLatin1String("apple.com"));
- QVariant appleValue = appleSettings.value(QLatin1String("AppleKeyboardUIMode"), 0);
- qt_tab_all_widgets = (appleValue.toInt() & 0x2);
- //paging mode
- /* First worked as of 10.2.3 */
- appleValue = appleSettings.value(QLatin1String("AppleScrollerPagingBehavior"), false);
- qt_scrollbar_jump_to_pos = appleValue.toBool();
- //collapse
- /* First worked as of 10.3.3 */
- appleValue = appleSettings.value(QLatin1String("AppleMiniaturizeOnDoubleClick"), true);
- qt_mac_collapse_on_dblclick = appleValue.toBool();
-
- // Anti-aliasing threshold
- appleValue = appleSettings.value(QLatin1String("AppleAntiAliasingThreshold"));
- if (appleValue.isValid())
- qt_antialiasing_threshold = appleValue.toInt();
-
-#ifdef DEBUG_PLATFORM_SETTINGS
- qDebug("qt_mac_update_os_settings *********************************************************************");
-#endif
- { // setup the global palette
- QColor qc;
- (void) QApplication::style(); // trigger creation of application style and system palettes
- QPalette pal = *QApplicationPrivate::sys_pal;
-
- pal.setBrush( QPalette::Active, QPalette::Highlight, qcolorForTheme(kThemeBrushPrimaryHighlightColor) );
- pal.setBrush( QPalette::Inactive, QPalette::Highlight, qcolorForTheme(kThemeBrushSecondaryHighlightColor) );
-
- pal.setBrush( QPalette::Disabled, QPalette::Highlight, qcolorForTheme(kThemeBrushSecondaryHighlightColor) );
- pal.setBrush( QPalette::Active, QPalette::Shadow, qcolorForTheme(kThemeBrushButtonActiveDarkShadow) );
-
- pal.setBrush( QPalette::Inactive, QPalette::Shadow, qcolorForTheme(kThemeBrushButtonInactiveDarkShadow) );
- pal.setBrush( QPalette::Disabled, QPalette::Shadow, qcolorForTheme(kThemeBrushButtonInactiveDarkShadow) );
-
- qc = qcolorForThemeTextColor(kThemeTextColorDialogActive);
- pal.setColor(QPalette::Active, QPalette::Text, qc);
- pal.setColor(QPalette::Active, QPalette::WindowText, qc);
- pal.setColor(QPalette::Active, QPalette::HighlightedText, qc);
-
- qc = qcolorForThemeTextColor(kThemeTextColorDialogInactive);
- pal.setColor(QPalette::Inactive, QPalette::Text, qc);
- pal.setColor(QPalette::Inactive, QPalette::WindowText, qc);
- pal.setColor(QPalette::Inactive, QPalette::HighlightedText, qc);
- pal.setColor(QPalette::Disabled, QPalette::Text, qc);
- pal.setColor(QPalette::Disabled, QPalette::WindowText, qc);
- pal.setColor(QPalette::Disabled, QPalette::HighlightedText, qc);
- pal.setBrush(QPalette::ToolTipBase, QColor(255, 255, 199));
-
- if (!QApplicationPrivate::sys_pal || *QApplicationPrivate::sys_pal != pal) {
- QApplicationPrivate::setSystemPalette(pal);
- QApplication::setPalette(pal);
- }
-#ifdef DEBUG_PLATFORM_SETTINGS
- qt_mac_debug_palette(pal, QApplication::palette(), "Global Palette");
-#endif
- }
-
- QFont fnt = qfontForThemeFont(kThemeApplicationFont);
-#ifdef DEBUG_PLATFORM_SETTINGS
- qDebug("qt-internal: Font for Application [%s::%d::%d::%d]",
- fnt.family().toLatin1().constData(), fnt.pointSize(), fnt.bold(), fnt.italic());
-#endif
- if (!QApplicationPrivate::sys_font || *QApplicationPrivate::sys_font != fnt)
- QApplicationPrivate::setSystemFont(fnt);
-
- { //setup the fonts
- struct FontMap {
- FontMap(const char *qc, short fk) : qt_class(qc), font_key(fk) { }
- const char *const qt_class;
- short font_key;
- } mac_widget_fonts[] = {
- FontMap("QPushButton", kThemePushButtonFont),
- FontMap("QListView", kThemeViewsFont),
- FontMap("QListBox", kThemeViewsFont),
- FontMap("QTitleBar", kThemeWindowTitleFont),
- FontMap("QMenuBar", kThemeMenuTitleFont),
- FontMap("QMenu", kThemeMenuItemFont),
- FontMap("QComboMenuItem", kThemeSystemFont),
- FontMap("QHeaderView", kThemeSmallSystemFont),
- FontMap("Q3Header", kThemeSmallSystemFont),
- FontMap("QTipLabel", kThemeSmallSystemFont),
- FontMap("QLabel", kThemeSystemFont),
- FontMap("QToolButton", kThemeSmallSystemFont),
- FontMap("QMenuItem", kThemeMenuItemFont), // It doesn't exist, but its unique.
- FontMap("QComboLineEdit", kThemeViewsFont), // It doesn't exist, but its unique.
- FontMap("QSmallFont", kThemeSmallSystemFont), // It doesn't exist, but its unique.
- FontMap("QMiniFont", kThemeMiniSystemFont), // It doesn't exist, but its unique.
- FontMap(0, 0) };
- for(int i = 0; mac_widget_fonts[i].qt_class; i++) {
- QFont fnt = qfontForThemeFont(mac_widget_fonts[i].font_key);
- bool set_font = true;
- FontHash *hash = qt_app_fonts_hash();
- if (!hash->isEmpty()) {
- FontHash::const_iterator it
- = hash->constFind(mac_widget_fonts[i].qt_class);
- if (it != hash->constEnd())
- set_font = (fnt != *it);
- }
- if (set_font) {
- QApplication::setFont(fnt, mac_widget_fonts[i].qt_class);
-#ifdef DEBUG_PLATFORM_SETTINGS
- qDebug("qt-internal: Font for %s [%s::%d::%d::%d]", mac_widget_fonts[i].qt_class,
- fnt.family().toLatin1().constData(), fnt.pointSize(), fnt.bold(), fnt.italic());
-#endif
- }
- }
- }
- QApplicationPrivate::initializeWidgetPaletteHash();
-#ifdef DEBUG_PLATFORM_SETTINGS
- qDebug("qt_mac_update_os_settings END !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
-#endif
-}
-
-void QApplicationPrivate::initializeWidgetPaletteHash()
-{
- { //setup the palette
- struct PaletteMap {
- inline PaletteMap(const char *qc, ThemeBrush a, ThemeBrush i) :
- qt_class(qc), active(a), inactive(i) { }
- const char *const qt_class;
- ThemeBrush active, inactive;
- } mac_widget_colors[] = {
- PaletteMap("QToolButton", kThemeTextColorBevelButtonActive, kThemeTextColorBevelButtonInactive),
- PaletteMap("QAbstractButton", kThemeTextColorPushButtonActive, kThemeTextColorPushButtonInactive),
- PaletteMap("QHeaderView", kThemeTextColorPushButtonActive, kThemeTextColorPushButtonInactive),
- PaletteMap("Q3Header", kThemeTextColorPushButtonActive, kThemeTextColorPushButtonInactive),
- PaletteMap("QComboBox", kThemeTextColorPopupButtonActive, kThemeTextColorPopupButtonInactive),
- PaletteMap("QAbstractItemView", kThemeTextColorListView, kThemeTextColorDialogInactive),
- PaletteMap("QMessageBoxLabel", kThemeTextColorAlertActive, kThemeTextColorAlertInactive),
- PaletteMap("QTabBar", kThemeTextColorTabFrontActive, kThemeTextColorTabFrontInactive),
- PaletteMap("QLabel", kThemeTextColorPlacardActive, kThemeTextColorPlacardInactive),
- PaletteMap("QGroupBox", kThemeTextColorPlacardActive, kThemeTextColorPlacardInactive),
- PaletteMap("QMenu", kThemeTextColorPopupLabelActive, kThemeTextColorPopupLabelInactive),
- PaletteMap("QTextEdit", 0, 0),
- PaletteMap("QTextControl", 0, 0),
- PaletteMap("QLineEdit", 0, 0),
- PaletteMap(0, 0, 0) };
- QColor qc;
- for(int i = 0; mac_widget_colors[i].qt_class; i++) {
- QPalette pal;
- if (mac_widget_colors[i].active != 0) {
- qc = qcolorForThemeTextColor(mac_widget_colors[i].active);
- pal.setColor(QPalette::Active, QPalette::Text, qc);
- pal.setColor(QPalette::Active, QPalette::WindowText, qc);
- pal.setColor(QPalette::Active, QPalette::HighlightedText, qc);
- qc = qcolorForThemeTextColor(mac_widget_colors[i].inactive);
- pal.setColor(QPalette::Inactive, QPalette::Text, qc);
- pal.setColor(QPalette::Disabled, QPalette::Text, qc);
- pal.setColor(QPalette::Inactive, QPalette::WindowText, qc);
- pal.setColor(QPalette::Disabled, QPalette::WindowText, qc);
- pal.setColor(QPalette::Inactive, QPalette::HighlightedText, qc);
- pal.setColor(QPalette::Disabled, QPalette::HighlightedText, qc);
- }
- if (!strcmp(mac_widget_colors[i].qt_class, "QMenu")) {
- qc = qcolorForThemeTextColor(kThemeTextColorMenuItemActive);
- pal.setBrush(QPalette::ButtonText, qc);
- qc = qcolorForThemeTextColor(kThemeTextColorMenuItemSelected);
- pal.setBrush(QPalette::HighlightedText, qc);
- qc = qcolorForThemeTextColor(kThemeTextColorMenuItemDisabled);
- pal.setBrush(QPalette::Disabled, QPalette::Text, qc);
- } else if (!strcmp(mac_widget_colors[i].qt_class, "QAbstractButton")
- || !strcmp(mac_widget_colors[i].qt_class, "QHeaderView")
- || !strcmp(mac_widget_colors[i].qt_class, "Q3Header")) { //special
- pal.setColor(QPalette::Disabled, QPalette::ButtonText,
- pal.color(QPalette::Disabled, QPalette::Text));
- pal.setColor(QPalette::Inactive, QPalette::ButtonText,
- pal.color(QPalette::Inactive, QPalette::Text));
- pal.setColor(QPalette::Active, QPalette::ButtonText,
- pal.color(QPalette::Active, QPalette::Text));
- } else if (!strcmp(mac_widget_colors[i].qt_class, "QAbstractItemView")) {
- pal.setBrush(QPalette::Active, QPalette::Highlight,
- qcolorForTheme(kThemeBrushAlternatePrimaryHighlightColor));
- qc = qcolorForThemeTextColor(kThemeTextColorMenuItemSelected);
- pal.setBrush(QPalette::Active, QPalette::HighlightedText, qc);
-#if 1
- pal.setBrush(QPalette::Inactive, QPalette::Text,
- pal.brush(QPalette::Active, QPalette::Text));
- pal.setBrush(QPalette::Inactive, QPalette::HighlightedText,
- pal.brush(QPalette::Active, QPalette::Text));
-#endif
- } else if (!strcmp(mac_widget_colors[i].qt_class, "QTextEdit")
- || !strcmp(mac_widget_colors[i].qt_class, "QTextControl")) {
- pal.setBrush(QPalette::Inactive, QPalette::Text,
- pal.brush(QPalette::Active, QPalette::Text));
- pal.setBrush(QPalette::Inactive, QPalette::HighlightedText,
- pal.brush(QPalette::Active, QPalette::Text));
- } else if (!strcmp(mac_widget_colors[i].qt_class, "QLineEdit")) {
- pal.setBrush(QPalette::Disabled, QPalette::Base,
- pal.brush(QPalette::Active, QPalette::Base));
- }
-
- bool set_palette = true;
- PaletteHash *phash = qt_app_palettes_hash();
- if (!phash->isEmpty()) {
- PaletteHash::const_iterator it
- = phash->constFind(mac_widget_colors[i].qt_class);
- if (it != phash->constEnd())
- set_palette = (pal != *it);
- }
- if (set_palette) {
- QApplication::setPalette(pal, mac_widget_colors[i].qt_class);
-#ifdef DEBUG_PLATFORM_SETTINGS
- qt_mac_debug_palette(pal, QApplication::palette(), QLatin1String("Palette for ") + QString::fromLatin1(mac_widget_colors[i].qt_class));
-#endif
- }
- }
- }
-}
-
-static void qt_mac_event_release(EventRef &event)
-{
- ReleaseEvent(event);
- event = 0;
-}
-#ifndef QT_MAC_USE_COCOA
-static void qt_mac_event_release(QWidget *w, EventRef &event)
-{
- if (event) {
- QWidget *widget = 0;
- if (GetEventParameter(event, kEventParamQWidget, typeQWidget, 0, sizeof(widget), 0, &widget) == noErr
- && w == widget) {
- if (IsEventInQueue(GetMainEventQueue(), event))
- RemoveEventFromQueue(GetMainEventQueue(), event);
- qt_mac_event_release(event);
- }
- }
-}
-
-static bool qt_mac_event_remove(EventRef &event)
-{
- if (event) {
- if (IsEventInQueue(GetMainEventQueue(), event))
- RemoveEventFromQueue(GetMainEventQueue(), event);
- qt_mac_event_release(event);
- return true;
- }
- return false;
-}
-#endif
-
-/* sheets */
-#ifndef QT_MAC_USE_COCOA
-static EventRef request_showsheet_pending = 0;
-#endif
-void qt_event_request_showsheet(QWidget *w)
-{
- Q_ASSERT(qt_mac_is_macsheet(w));
-#ifdef QT_MAC_USE_COCOA
- [NSApp beginSheet:qt_mac_window_for(w) modalForWindow:qt_mac_window_for(w->parentWidget())
- modalDelegate:nil didEndSelector:nil contextInfo:0];
-#else
- qt_mac_event_remove(request_showsheet_pending);
- CreateEvent(0, kEventClassQt, kEventQtRequestShowSheet, GetCurrentEventTime(),
- kEventAttributeUserEvent, &request_showsheet_pending);
- SetEventParameter(request_showsheet_pending, kEventParamQWidget, typeQWidget, sizeof(w), &w);
- PostEventToQueue(GetMainEventQueue(), request_showsheet_pending, kEventPriorityStandard);
-#endif
-}
-
-static void qt_post_window_change_event(QWidget *widget)
-{
- qt_widget_private(widget)->needWindowChange = true;
- QEvent *glWindowChangeEvent = new QEvent(QEvent::MacGLWindowChange);
- QApplication::postEvent(widget, glWindowChangeEvent);
-}
-
-/*
- Posts updates to all child and grandchild OpenGL widgets for the given widget.
-*/
-static void qt_mac_update_child_gl_widgets(QWidget *widget)
-{
- // Update all OpenGL child widgets for the given widget.
- QList<QWidgetPrivate::GlWidgetInfo> &glWidgets = qt_widget_private(widget)->glWidgets;
- QList<QWidgetPrivate::GlWidgetInfo>::iterator end = glWidgets.end();
- QList<QWidgetPrivate::GlWidgetInfo>::iterator it = glWidgets.begin();
-
- for (;it != end; ++it) {
- qt_post_window_change_event(it->widget);
- }
-}
-
-/*
- Sends updates to all child and grandchild gl widgets that have updates pending.
-*/
-void qt_mac_send_posted_gl_updates(QWidget *widget)
-{
- QList<QWidgetPrivate::GlWidgetInfo> &glWidgets = qt_widget_private(widget)->glWidgets;
- QList<QWidgetPrivate::GlWidgetInfo>::iterator end = glWidgets.end();
- QList<QWidgetPrivate::GlWidgetInfo>::iterator it = glWidgets.begin();
-
- for (;it != end; ++it) {
- QWidget *glWidget = it->widget;
- if (qt_widget_private(glWidget)->needWindowChange) {
- QEvent glChangeEvent(QEvent::MacGLWindowChange);
- QApplication::sendEvent(glWidget, &glChangeEvent);
- }
- }
-}
-
-/*
- Posts updates to all OpenGL widgets within the window that the given widget intersects.
-*/
-static void qt_mac_update_intersected_gl_widgets(QWidget *widget)
-{
-#ifndef QT_MAC_USE_COCOA
- QList<QWidgetPrivate::GlWidgetInfo> &glWidgets = qt_widget_private(widget->window())->glWidgets;
- if (glWidgets.isEmpty())
- return;
-
- // Exit if the window has not been created yet (mapToGlobal/size will force create it)
- if (widget->testAttribute(Qt::WA_WState_Created) == false || HIViewGetWindow(qt_mac_nativeview_for(widget)) == 0)
- return;
-
- const QRect globalWidgetRect = QRect(widget->mapToGlobal(QPoint(0, 0)), widget->size());
-
- QList<QWidgetPrivate::GlWidgetInfo>::iterator end = glWidgets.end();
- QList<QWidgetPrivate::GlWidgetInfo>::iterator it = glWidgets.begin();
-
- for (;it != end; ++it){
- QWidget *glWidget = it->widget;
- const QRect globalGlWidgetRect = QRect(glWidget->mapToGlobal(QPoint(0, 0)), glWidget->size());
- if (globalWidgetRect.intersects(globalGlWidgetRect)) {
- qt_post_window_change_event(glWidget);
- it->lastUpdateWidget = widget;
- } else if (it->lastUpdateWidget == widget) {
- // Update the gl wigets that the widget intersected the last time around,
- // and that we are not intersecting now. This prevents paint errors when the
- // intersecting widget leaves a gl widget.
- qt_post_window_change_event(glWidget);
- it->lastUpdateWidget = 0;
- }
- }
-#else
- Q_UNUSED(widget);
-#endif
-}
-
-/*
- Posts a kEventQtRequestWindowChange event to the main Carbon event queue.
-*/
-static EventRef request_window_change_pending = 0;
-Q_GUI_EXPORT void qt_event_request_window_change()
-{
- if(request_window_change_pending)
- return;
-
- CreateEvent(0, kEventClassQt, kEventQtRequestWindowChange, GetCurrentEventTime(),
- kEventAttributeUserEvent, &request_window_change_pending);
- PostEventToQueue(GetMainEventQueue(), request_window_change_pending, kEventPriorityHigh);
-}
-
-/* window changing. This is a hack around Apple's missing functionality, pending the toolbox
- team fix. --Sam */
-Q_GUI_EXPORT void qt_event_request_window_change(QWidget *widget)
-{
- if (!widget)
- return;
-
- // Post a kEventQtRequestWindowChange event. This event is semi-public,
- // don't remove this line!
- qt_event_request_window_change();
-
- // Post update request on gl widgets unconditionally.
- if (qt_widget_private(widget)->isGLWidget == true) {
- qt_post_window_change_event(widget);
- return;
- }
-
- qt_mac_update_child_gl_widgets(widget);
- qt_mac_update_intersected_gl_widgets(widget);
-}
-
-/* activation */
-static struct {
- QPointer<QWidget> widget;
- EventRef event;
- EventLoopTimerRef timer;
- EventLoopTimerUPP timerUPP;
-} request_activate_pending = { 0, 0, 0, 0 };
-bool qt_event_remove_activate()
-{
- if (request_activate_pending.timer) {
- RemoveEventLoopTimer(request_activate_pending.timer);
- request_activate_pending.timer = 0;
- }
- if (request_activate_pending.event)
- qt_mac_event_release(request_activate_pending.event);
- return true;
-}
-
-void qt_event_activate_timer_callbk(EventLoopTimerRef r, void *)
-{
- EventLoopTimerRef otc = request_activate_pending.timer;
- qt_event_remove_activate();
- if (r == otc && !request_activate_pending.widget.isNull()) {
- const QWidget *tlw = request_activate_pending.widget->window();
- Qt::WindowType wt = tlw->windowType();
- if (tlw->isVisible()
- && ((wt != Qt::Desktop && wt != Qt::Popup && wt != Qt::Tool) || tlw->isModal())) {
- CreateEvent(0, kEventClassQt, kEventQtRequestActivate, GetCurrentEventTime(),
- kEventAttributeUserEvent, &request_activate_pending.event);
- PostEventToQueue(GetMainEventQueue(), request_activate_pending.event, kEventPriorityHigh);
- }
- }
-}
-
-void qt_event_request_activate(QWidget *w)
-{
- if (w == request_activate_pending.widget)
- return;
-
- /* We put these into a timer because due to order of events being sent we need to be sure this
- comes from inside of the event loop */
- qt_event_remove_activate();
- if (!request_activate_pending.timerUPP)
- request_activate_pending.timerUPP = NewEventLoopTimerUPP(qt_event_activate_timer_callbk);
- request_activate_pending.widget = w;
- InstallEventLoopTimer(GetMainEventLoop(), 0, 0, request_activate_pending.timerUPP, 0, &request_activate_pending.timer);
-}
-
-
-/* menubars */
-#ifndef QT_MAC_USE_COCOA
-static EventRef request_menubarupdate_pending = 0;
-#endif
-void qt_event_request_menubarupdate()
-{
-#ifndef QT_MAC_USE_COCOA
- if (request_menubarupdate_pending) {
- if (IsEventInQueue(GetMainEventQueue(), request_menubarupdate_pending))
- return;
-#ifdef DEBUG_DROPPED_EVENTS
- qDebug("%s:%d Whoa, we dropped an event on the floor!", __FILE__, __LINE__);
-#endif
- }
-
- CreateEvent(0, kEventClassQt, kEventQtRequestMenubarUpdate, GetCurrentEventTime(),
- kEventAttributeUserEvent, &request_menubarupdate_pending);
- PostEventToQueue(GetMainEventQueue(), request_menubarupdate_pending, kEventPriorityHigh);
-#else
- // Just call this. The request has the benefit that we don't call this multiple times, but
- // we can optimize this.
- QMenuBar::macUpdateMenuBar();
-#endif
-}
-
-#ifndef QT_MAC_USE_COCOA
-//context menu
-static EventRef request_context_pending = 0;
-static void qt_event_request_context(QWidget *w=0, EventRef *where=0)
-{
- if (!where)
- where = &request_context_pending;
- if (*where)
- return;
- CreateEvent(0, kEventClassQt, kEventQtRequestContext, GetCurrentEventTime(),
- kEventAttributeUserEvent, where);
- if (w)
- SetEventParameter(*where, kEventParamQWidget, typeQWidget, sizeof(w), &w);
- PostEventToQueue(GetMainEventQueue(), *where, kEventPriorityStandard);
-}
-#endif
-
-void QApplicationPrivate::createEventDispatcher()
-{
- Q_Q(QApplication);
- if (q->type() != QApplication::Tty)
- eventDispatcher = new QEventDispatcherMac(q);
- else
- eventDispatcher = new QEventDispatcherUNIX(q);
-}
-
-/* clipboard */
-void qt_event_send_clipboard_changed()
-{
-#ifndef QT_MAC_USE_COCOA
- AppleEvent ae;
- if (AECreateAppleEvent(kEventClassQt, typeAEClipboardChanged, 0, kAutoGenerateReturnID, kAnyTransactionID, &ae) != noErr)
- qDebug("Can't happen!!");
- AppleEvent reply;
- AESend(&ae, &reply, kAENoReply, kAENormalPriority, kAEDefaultTimeout, 0, 0);
-#endif
-}
-
-/* app menu */
-static QMenu *qt_mac_dock_menu = 0;
-Q_GUI_EXPORT void qt_mac_set_dock_menu(QMenu *menu)
-{
- qt_mac_dock_menu = menu;
-#ifdef QT_MAC_USE_COCOA
- [NSApp setDockMenu:menu->macMenu()];
-#else
- SetApplicationDockTileMenu(menu->macMenu());
-#endif
-}
-
-/* events that hold pointers to widgets, must be cleaned up like this */
-void qt_mac_event_release(QWidget *w)
-{
- if (w) {
-#ifndef QT_MAC_USE_COCOA
- qt_mac_event_release(w, request_showsheet_pending);
- qt_mac_event_release(w, request_context_pending);
-#endif
- if (w == qt_mac_dock_menu) {
- qt_mac_dock_menu = 0;
-#ifndef QT_MAC_USE_COCOA
- SetApplicationDockTileMenu(0);
-#else
- [NSApp setDockMenu:0];
-#endif
- }
- }
-}
-
-struct QMacAppleEventTypeSpec {
- AEEventClass mac_class;
- AEEventID mac_id;
-} app_apple_events[] = {
- { kCoreEventClass, kAEQuitApplication },
- { kCoreEventClass, kAEOpenDocuments },
- { kInternetEventClass, kAEGetURL },
-};
-
-#ifndef QT_MAC_USE_COCOA
-
-#if (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5)
-enum
-{
- kEventMouseScroll = 11,
- kEventParamMouseWheelSmoothVerticalDelta = 'saxy',
- kEventParamMouseWheelSmoothHorizontalDelta = 'saxx',
-};
-#endif
-
-/* watched events */
-static EventTypeSpec app_events[] = {
- { kEventClassQt, kEventQtRequestWindowChange },
- { kEventClassQt, kEventQtRequestShowSheet },
- { kEventClassQt, kEventQtRequestContext },
- { kEventClassQt, kEventQtRequestActivate },
- { kEventClassQt, kEventQtRequestMenubarUpdate },
-
- { kEventClassWindow, kEventWindowActivated },
- { kEventClassWindow, kEventWindowDeactivated },
-
- { kEventClassMouse, kEventMouseScroll },
- { kEventClassMouse, kEventMouseWheelMoved },
- { kEventClassMouse, kEventMouseDown },
- { kEventClassMouse, kEventMouseUp },
- { kEventClassMouse, kEventMouseDragged },
- { kEventClassMouse, kEventMouseMoved },
-
- { kEventClassTablet, kEventTabletProximity },
-
- { kEventClassApplication, kEventAppActivated },
- { kEventClassApplication, kEventAppDeactivated },
- { kEventClassApplication, kEventAppAvailableWindowBoundsChanged },
-
- // { kEventClassTextInput, kEventTextInputUnicodeForKeyEvent },
- { kEventClassKeyboard, kEventRawKeyModifiersChanged },
- { kEventClassKeyboard, kEventRawKeyRepeat },
- { kEventClassKeyboard, kEventRawKeyUp },
- { kEventClassKeyboard, kEventRawKeyDown },
-
- { kEventClassCommand, kEventCommandProcess },
-
- { kEventClassAppleEvent, kEventAppleEvent },
-
- { kAppearanceEventClass, kAEAppearanceChanged }
-};
-
-void qt_init_app_proc_handler()
-{
- InstallEventHandler(GetApplicationEventTarget(), app_proc_handlerUPP,
- GetEventTypeCount(app_events), app_events, (void *)qApp,
- &app_proc_handler);
-}
-#endif // QT_MAC_USE_COCOA
-
-static void qt_init_tablet_proximity_handler()
-{
- EventTypeSpec tabletProximityEvent = { kEventClassTablet, kEventTabletProximity };
- InstallEventHandler(GetEventMonitorTarget(), tablet_proximity_UPP,
- 1, &tabletProximityEvent, qApp, &tablet_proximity_handler);
-}
-
-static void qt_release_tablet_proximity_handler()
-{
- RemoveEventHandler(tablet_proximity_handler);
-}
-
-QString QApplicationPrivate::appName() const
-{
- static QString applName;
- if (applName.isEmpty()) {
- applName = QCoreApplicationPrivate::macMenuBarName();
- ProcessSerialNumber psn;
- if (applName.isEmpty() && qt_is_gui_used && GetCurrentProcess(&psn) == noErr) {
- QCFString cfstr;
- CopyProcessName(&psn, &cfstr);
- applName = cfstr;
- }
- }
- return applName;
-}
-
-void qt_release_app_proc_handler()
-{
-#ifndef QT_MAC_USE_COCOA
- if (app_proc_handler) {
- RemoveEventHandler(app_proc_handler);
- app_proc_handler = 0;
- }
-#endif
-}
-
-void qt_color_profile_changed(CFNotificationCenterRef, void *, CFStringRef, const void *,
- CFDictionaryRef)
-{
- QCoreGraphicsPaintEngine::cleanUpMacColorSpaces();
-}
-/* platform specific implementations */
-void qt_init(QApplicationPrivate *priv, int)
-{
- if (qt_is_gui_used) {
- CGDisplayRegisterReconfigurationCallback(qt_mac_display_change_callbk, 0);
- CFNotificationCenterRef center = CFNotificationCenterGetDistributedCenter();
- CFNotificationCenterAddObserver(center, qApp, qt_color_profile_changed,
- kCMDeviceUnregisteredNotification, 0,
- CFNotificationSuspensionBehaviorDeliverImmediately);
- CFNotificationCenterAddObserver(center, qApp, qt_color_profile_changed,
- kCMDefaultDeviceNotification, 0,
- CFNotificationSuspensionBehaviorDeliverImmediately);
- CFNotificationCenterAddObserver(center, qApp, qt_color_profile_changed,
- kCMDeviceProfilesNotification, 0,
- CFNotificationSuspensionBehaviorDeliverImmediately);
- CFNotificationCenterAddObserver(center, qApp, qt_color_profile_changed,
- kCMDefaultDeviceProfileNotification, 0,
- CFNotificationSuspensionBehaviorDeliverImmediately);
- ProcessSerialNumber psn;
- if (GetCurrentProcess(&psn) == noErr) {
- // Jambi needs to transform itself since most people aren't "used"
- // to putting things in bundles, but other people may actually not
- // want to tranform the process (running as a helper or something)
- // so don't do that for them. This means checking both LSUIElement
- // and LSBackgroundOnly. If you set them both... well, you
- // shouldn't do that.
-
- bool forceTransform = true;
- CFTypeRef value = CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(),
- CFSTR("LSUIElement"));
- if (value) {
- CFTypeID valueType = CFGetTypeID(value);
- // Officially it's supposed to be a string, a boolean makes sense, so we'll check.
- // A number less so, but OK.
- if (valueType == CFStringGetTypeID())
- forceTransform = !(QCFString::toQString(static_cast<CFStringRef>(value)).toInt());
- else if (valueType == CFBooleanGetTypeID())
- forceTransform = !CFBooleanGetValue(static_cast<CFBooleanRef>(value));
- else if (valueType == CFNumberGetTypeID()) {
- int valueAsInt;
- CFNumberGetValue(static_cast<CFNumberRef>(value), kCFNumberIntType, &valueAsInt);
- forceTransform = !valueAsInt;
- }
- }
-
- if (forceTransform) {
- value = CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(),
- CFSTR("LSBackgroundOnly"));
- if (value) {
- CFTypeID valueType = CFGetTypeID(value);
- if (valueType == CFBooleanGetTypeID())
- forceTransform = !CFBooleanGetValue(static_cast<CFBooleanRef>(value));
- else if (valueType == CFStringGetTypeID())
- forceTransform = !(QCFString::toQString(static_cast<CFStringRef>(value)).toInt());
- else if (valueType == CFNumberGetTypeID()) {
- int valueAsInt;
- CFNumberGetValue(static_cast<CFNumberRef>(value), kCFNumberIntType, &valueAsInt);
- forceTransform = !valueAsInt;
- }
- }
- }
-
-
- if (forceTransform) {
- TransformProcessType(&psn, kProcessTransformToForegroundApplication);
- }
- }
- }
-
- char **argv = priv->argv;
-
- // Get command line params
- if (int argc = priv->argc) {
- int i, j = 1;
- QString passed_psn;
- for(i=1; i < argc; i++) {
- if (argv[i] && *argv[i] != '-') {
- argv[j++] = argv[i];
- continue;
- }
- QByteArray arg(argv[i]);
-#if defined(QT_DEBUG)
- if (arg == "-nograb")
- appNoGrab = !appNoGrab;
- else
-#endif // QT_DEBUG
- if (arg.left(5) == "-psn_") {
- passed_psn = QString::fromLatin1(arg.mid(6));
- } else {
- argv[j++] = argv[i];
- }
- }
- if (j < priv->argc) {
- priv->argv[j] = 0;
- priv->argc = j;
- }
-
- //special hack to change working directory (for an app bundle) when running from finder
- if (!passed_psn.isNull() && QDir::currentPath() == QLatin1String("/")) {
- QCFType<CFURLRef> bundleURL(CFBundleCopyBundleURL(CFBundleGetMainBundle()));
- QString qbundlePath = QCFString(CFURLCopyFileSystemPath(bundleURL,
- kCFURLPOSIXPathStyle));
- if (qbundlePath.endsWith(QLatin1String(".app")))
- QDir::setCurrent(qbundlePath.section(QLatin1Char('/'), 0, -2));
- }
- }
-
- QMacPasteboardMime::initialize();
-
- qApp->setObjectName(priv->appName());
- if (qt_is_gui_used) {
- QColormap::initialize();
- QFont::initialize();
- QCursorData::initialize();
- QCoreGraphicsPaintEngine::initialize();
-#ifndef QT_NO_ACCESSIBILITY
- QAccessible::initialize();
-#endif
- QMacInputContext::initialize();
- QApplicationPrivate::inputContext = new QMacInputContext;
-
- if (QApplication::desktopSettingsAware())
- qt_mac_update_os_settings();
-#ifndef QT_MAC_USE_COCOA
- if (!app_proc_handler) {
- app_proc_handlerUPP = NewEventHandlerUPP(QApplicationPrivate::globalEventProcessor);
- qt_init_app_proc_handler();
- }
-
-#endif
- if (!app_proc_ae_handlerUPP && !QApplication::testAttribute(Qt::AA_MacPluginApplication)) {
- app_proc_ae_handlerUPP = AEEventHandlerUPP(QApplicationPrivate::globalAppleEventProcessor);
- for(uint i = 0; i < sizeof(app_apple_events) / sizeof(QMacAppleEventTypeSpec); ++i) {
- // Install apple event handler, but avoid overwriting an already
- // existing handler (it means a 3rd party application has installed one):
- SRefCon refCon = 0;
- AEEventHandlerUPP current_handler = NULL;
- AEGetEventHandler(app_apple_events[i].mac_class, app_apple_events[i].mac_id, &current_handler, &refCon, false);
- if (!current_handler)
- AEInstallEventHandler(app_apple_events[i].mac_class, app_apple_events[i].mac_id,
- app_proc_ae_handlerUPP, SRefCon(qApp), false);
- }
- }
-
- if (QApplicationPrivate::app_style) {
- QEvent ev(QEvent::Style);
- qt_sendSpontaneousEvent(QApplicationPrivate::app_style, &ev);
- }
- }
- if (QApplication::desktopSettingsAware())
- QApplicationPrivate::qt_mac_apply_settings();
-
- // Cocoa application delegate
-#ifdef QT_MAC_USE_COCOA
- NSApplication *cocoaApp = [QNSApplication sharedApplication];
- qt_redirectNSApplicationSendEvent();
-
- QMacCocoaAutoReleasePool pool;
- id oldDelegate = [cocoaApp delegate];
- QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) *newDelegate = [QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) sharedDelegate];
- Q_ASSERT(newDelegate);
- [newDelegate setQtPrivate:priv];
- // Only do things that make sense to do once, otherwise we crash.
- if (oldDelegate != newDelegate && !QApplication::testAttribute(Qt::AA_MacPluginApplication)) {
- [newDelegate setReflectionDelegate:oldDelegate];
- [cocoaApp setDelegate:newDelegate];
-
- QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *qtMenuLoader = [[QT_MANGLE_NAMESPACE(QCocoaMenuLoader) alloc] init];
- if ([NSBundle loadNibNamed:@"qt_menu" owner:qtMenuLoader] == false) {
- qFatal("Qt internal error: qt_menu.nib could not be loaded. The .nib file"
- " should be placed in QtGui.framework/Versions/Current/Resources/ "
- " or in the resources directory of your application bundle.");
- }
-
- [cocoaApp setMenu:[qtMenuLoader menu]];
- [newDelegate setMenuLoader:qtMenuLoader];
- [qtMenuLoader release];
- }
-#endif
- // Register for Carbon tablet proximity events on the event monitor target.
- // This means that we should receive proximity events even when we aren't the active application.
- if (!tablet_proximity_handler) {
- tablet_proximity_UPP = NewEventHandlerUPP(QApplicationPrivate::tabletProximityCallback);
- qt_init_tablet_proximity_handler();
- }
- priv->native_modal_dialog_active = false;
-
- qt_mac_read_fontsmoothing_settings();
-}
-
-void qt_release_apple_event_handler()
-{
- if(app_proc_ae_handlerUPP) {
- for(uint i = 0; i < sizeof(app_apple_events) / sizeof(QMacAppleEventTypeSpec); ++i)
- AERemoveEventHandler(app_apple_events[i].mac_class, app_apple_events[i].mac_id,
- app_proc_ae_handlerUPP, true);
- DisposeAEEventHandlerUPP(app_proc_ae_handlerUPP);
- app_proc_ae_handlerUPP = 0;
- }
-}
-
-/*****************************************************************************
- qt_cleanup() - cleans up when the application is finished
- *****************************************************************************/
-
-void qt_cleanup()
-{
- CGDisplayRemoveReconfigurationCallback(qt_mac_display_change_callbk, 0);
- CFNotificationCenterRef center = CFNotificationCenterGetDistributedCenter();
- CFNotificationCenterRemoveObserver(center, qApp, kCMDeviceUnregisteredNotification, 0);
- CFNotificationCenterRemoveObserver(center, qApp, kCMDefaultDeviceNotification, 0);
- CFNotificationCenterRemoveObserver(center, qApp, kCMDeviceProfilesNotification, 0);
- CFNotificationCenterRemoveObserver(center, qApp, kCMDefaultDeviceProfileNotification, 0);
-
-#ifndef QT_MAC_USE_COCOA
- qt_release_app_proc_handler();
- if (app_proc_handlerUPP) {
- DisposeEventHandlerUPP(app_proc_handlerUPP);
- app_proc_handlerUPP = 0;
- }
-#endif
- qt_release_apple_event_handler();
- qt_release_tablet_proximity_handler();
- if (tablet_proximity_UPP)
- DisposeEventHandlerUPP(tablet_proximity_UPP);
-
- QPixmapCache::clear();
- if (qt_is_gui_used) {
-#ifndef QT_NO_ACCESSIBILITY
- QAccessible::cleanup();
-#endif
- QMacInputContext::cleanup();
- QCursorData::cleanup();
- QFont::cleanup();
- QColormap::cleanup();
- if (qt_mac_safe_pdev) {
- delete qt_mac_safe_pdev;
- qt_mac_safe_pdev = 0;
- }
- extern void qt_mac_unregister_widget(); // qapplication_mac.cpp
- qt_mac_unregister_widget();
- }
-}
-
-/*****************************************************************************
- Platform specific global and internal functions
- *****************************************************************************/
-void qt_updated_rootinfo()
-{
-}
-
-bool qt_wstate_iconified(WId)
-{
- return false;
-}
-
-/*****************************************************************************
- Platform specific QApplication members
- *****************************************************************************/
-extern QWidget * mac_mouse_grabber;
-extern QWidget * mac_keyboard_grabber;
-
-#ifdef QT3_SUPPORT
-void QApplication::setMainWidget(QWidget *mainWidget)
-{
- QApplicationPrivate::main_widget = mainWidget;
- if (QApplicationPrivate::main_widget && windowIcon().isNull()
- && QApplicationPrivate::main_widget->testAttribute(Qt::WA_SetWindowIcon))
- setWindowIcon(QApplicationPrivate::main_widget->windowIcon());
-}
-#endif
-#ifndef QT_NO_CURSOR
-
-/*****************************************************************************
- QApplication cursor stack
- *****************************************************************************/
-
-void QApplication::setOverrideCursor(const QCursor &cursor)
-{
- qApp->d_func()->cursor_list.prepend(cursor);
-
-#ifdef QT_MAC_USE_COCOA
- qt_mac_update_cursor();
-#else
- if (qApp && qApp->activeWindow())
- qt_mac_set_cursor(&qApp->d_func()->cursor_list.first());
-#endif
-}
-
-void QApplication::restoreOverrideCursor()
-{
- if (qApp->d_func()->cursor_list.isEmpty())
- return;
- qApp->d_func()->cursor_list.removeFirst();
-
-#ifdef QT_MAC_USE_COCOA
- qt_mac_update_cursor();
-#else
- if (qApp && qApp->activeWindow()) {
- const QCursor def(Qt::ArrowCursor);
- qt_mac_set_cursor(qApp->d_func()->cursor_list.isEmpty() ? &def : &qApp->d_func()->cursor_list.first());
- }
-#endif
-}
-#endif // QT_NO_CURSOR
-
-Qt::KeyboardModifiers QApplication::queryKeyboardModifiers()
-{
- return qt_mac_get_modifiers(GetCurrentEventKeyModifiers());
-}
-
-QWidget *QApplication::topLevelAt(const QPoint &p)
-{
-#ifndef QT_MAC_USE_COCOA
- QWidget *widget;
- qt_mac_window_at(p.x(), p.y(), &widget);
- return widget;
-#else
- // Use a cache to avoid iterate through the whole list of windows for all
- // calls to to topLevelAt. We e.g. do this for each and every mouse
- // move since we need to find the widget under mouse:
- if (topLevelAt_cache && topLevelAt_cache->frameGeometry().contains(p))
- return topLevelAt_cache;
-
- // INVARIANT: Cache miss. Go through the list if windows instead:
- QMacCocoaAutoReleasePool pool;
- NSPoint cocoaPoint = flipPoint(p);
- NSInteger windowCount;
- NSCountWindows(&windowCount);
- if (windowCount <= 0)
- return 0; // There's no window to find!
-
- QVarLengthArray<NSInteger> windowList(windowCount);
- NSWindowList(windowCount, windowList.data());
- int firstQtWindowFound = -1;
- for (int i = 0; i < windowCount; ++i) {
- NSWindow *window = [NSApp windowWithWindowNumber:windowList[i]];
- if (window) {
- QWidget *candidateWindow = [window QT_MANGLE_NAMESPACE(qt_qwidget)];
- if (candidateWindow && firstQtWindowFound == -1)
- firstQtWindowFound = i;
-
- if (NSPointInRect(cocoaPoint, [window frame])) {
- // Check to see if there's a hole in the window where the mask is.
- // If there is, we should just continue to see if there is a window below.
- if (candidateWindow && !candidateWindow->mask().isEmpty()) {
- QPoint localPoint = candidateWindow->mapFromGlobal(p);
- if (!candidateWindow->mask().contains(localPoint))
- continue;
- else
- return candidateWindow;
- } else {
- if (i == firstQtWindowFound) {
- // The cache will only work when the window under mouse is
- // top most (that is, not partially obscured by other windows.
- // And we only set it if no mask is present to optimize for the common case:
- topLevelAt_cache = candidateWindow;
- }
- return candidateWindow;
- }
- }
- }
- }
-
- topLevelAt_cache = 0;
- return 0;
-#endif
-}
-
-/*****************************************************************************
- Main event loop
- *****************************************************************************/
-
-bool QApplicationPrivate::modalState()
-{
- return app_do_modal;
-}
-
-#ifdef QT_MAC_USE_COCOA
-#endif
-
-void QApplicationPrivate::enterModal_sys(QWidget *widget)
-{
-#ifdef DEBUG_MODAL_EVENTS
- Q_ASSERT(widget);
- qDebug("Entering modal state with %s::%s::%p (%d)", widget->metaObject()->className(), widget->objectName().toLocal8Bit().constData(),
- widget, qt_modal_stack ? (int)qt_modal_stack->count() : -1);
-#endif
- if (!qt_modal_stack)
- qt_modal_stack = new QWidgetList;
-
- dispatchEnterLeave(0, qt_last_mouse_receiver);
- qt_last_mouse_receiver = 0;
-
- qt_modal_stack->insert(0, widget);
- if (!app_do_modal)
- qt_event_request_menubarupdate();
- app_do_modal = true;
- qt_button_down = 0;
-
-#ifdef QT_MAC_USE_COCOA
- if (!qt_mac_is_macsheet(widget))
- QEventDispatcherMacPrivate::beginModalSession(widget);
-#endif
-}
-
-void QApplicationPrivate::leaveModal_sys(QWidget *widget)
-{
- if (qt_modal_stack && qt_modal_stack->removeAll(widget)) {
-#ifdef DEBUG_MODAL_EVENTS
- qDebug("Leaving modal state with %s::%s::%p (%d)", widget->metaObject()->className(), widget->objectName().toLocal8Bit().constData(),
- widget, qt_modal_stack->count());
-#endif
- if (qt_modal_stack->isEmpty()) {
- delete qt_modal_stack;
- qt_modal_stack = 0;
- QPoint p(QCursor::pos());
- app_do_modal = false;
- QWidget* w = 0;
- if (QWidget *grabber = QWidget::mouseGrabber())
- w = grabber;
- else
- w = QApplication::widgetAt(p.x(), p.y());
- dispatchEnterLeave(w, qt_last_mouse_receiver); // send synthetic enter event
- qt_last_mouse_receiver = w;
- }
-#ifdef QT_MAC_USE_COCOA
- if (!qt_mac_is_macsheet(widget))
- QEventDispatcherMacPrivate::endModalSession(widget);
-#endif
- }
-#ifdef DEBUG_MODAL_EVENTS
- else qDebug("Failure to remove %s::%s::%p -- %p", widget->metaObject()->className(), widget->objectName().toLocal8Bit().constData(), widget, qt_modal_stack);
-#endif
- app_do_modal = (qt_modal_stack != 0);
- if (!app_do_modal)
- qt_event_request_menubarupdate();
-}
-
-QWidget *QApplicationPrivate::tryModalHelper_sys(QWidget *top)
-{
-#ifndef QT_MAC_USE_COCOA
- if(top && qt_mac_is_macsheet(top) && !IsWindowVisible(qt_mac_window_for(top))) {
- if(OSWindowRef wp = GetFrontWindowOfClass(kSheetWindowClass, true)) {
- if(QWidget *sheet = qt_mac_find_window(wp))
- top = sheet;
- }
- }
-#endif
- return top;
-}
-
-#ifndef QT_MAC_USE_COCOA
-static bool qt_try_modal(QWidget *widget, EventRef event)
-{
- QWidget * top = 0;
-
- if (QApplicationPrivate::tryModalHelper(widget, &top))
- return true;
-
- // INVARIANT: widget is modally shaddowed within its
- // window, and should therefore not handle the event.
- // However, if the window is not active, the event
- // might suggest that we should bring it to front:
-
- bool block_event = false;
-
- if (event) {
- switch (GetEventClass(event)) {
- case kEventClassMouse:
- case kEventClassKeyboard:
- block_event = true;
- break;
- }
- }
-
- QWidget *activeWidget = QApplication::activeWindow();
- if ((!activeWidget || QApplicationPrivate::isBlockedByModal(activeWidget)) &&
- top->isWindow() && block_event && !QApplicationPrivate::native_modal_dialog_active)
- top->raise();
-
-#ifdef DEBUG_MODAL_EVENTS
- qDebug("%s:%d -- final decision! (%s)", __FILE__, __LINE__, block_event ? "false" : "true");
-#endif
- return !block_event;
-}
-#endif
-
-OSStatus QApplicationPrivate::tabletProximityCallback(EventHandlerCallRef, EventRef carbonEvent,
- void *)
-{
- OSType eventClass = GetEventClass(carbonEvent);
- UInt32 eventKind = GetEventKind(carbonEvent);
- if (eventClass != kEventClassTablet || eventKind != kEventTabletProximity)
- return eventNotHandledErr;
-
- // Get the current point of the device and its unique ID.
- ::TabletProximityRec proxRec;
- GetEventParameter(carbonEvent, kEventParamTabletProximityRec, typeTabletProximityRec, 0,
- sizeof(proxRec), 0, &proxRec);
- qt_dispatchTabletProximityEvent(proxRec);
- return noErr;
-}
-
-OSStatus
-QApplicationPrivate::globalEventProcessor(EventHandlerCallRef er, EventRef event, void *data)
-{
-#ifndef QT_MAC_USE_COCOA
- QApplication *app = (QApplication *)data;
- QScopedLoopLevelCounter loopLevelCounter(app->d_func()->threadData);
- long result;
- if (app->filterEvent(&event, &result))
- return result;
- if(app->macEventFilter(er, event)) //someone else ate it
- return noErr;
- QPointer<QWidget> widget;
-
- /*We assume all events are handled and in
- the code below we set it to false when we know we didn't handle it, this
- will let rogue events through (shouldn't really happen, but better safe
- than sorry) */
- bool handled_event=true;
- UInt32 ekind = GetEventKind(event), eclass = GetEventClass(event);
- switch(eclass)
- {
- case kEventClassQt:
- if(ekind == kEventQtRequestShowSheet) {
- request_showsheet_pending = 0;
- QWidget *widget = 0;
- GetEventParameter(event, kEventParamQWidget, typeQWidget, 0,
- sizeof(widget), 0, &widget);
- if(widget) {
- if (widget->macEvent(er, event))
- return noErr;
- WindowPtr window = qt_mac_window_for(widget);
- bool just_show = !qt_mac_is_macsheet(widget);
- if(!just_show) {
- OSStatus err = ShowSheetWindow(window, qt_mac_window_for(widget->parentWidget()));
- if(err != noErr)
- qWarning("Qt: QWidget: Unable to show as sheet %s::%s [%ld]", widget->metaObject()->className(),
- widget->objectName().toLocal8Bit().constData(), long(err));
- just_show = true;
- }
- if(just_show) //at least the window will be visible, but the sheet flag doesn't work sadly (probalby too many sheets)
- ShowHide(window, true);
- }
- } else if(ekind == kEventQtRequestWindowChange) {
- qt_mac_event_release(request_window_change_pending);
- } else if(ekind == kEventQtRequestMenubarUpdate) {
- qt_mac_event_release(request_menubarupdate_pending);
- QMenuBar::macUpdateMenuBar();
- } else if(ekind == kEventQtRequestActivate) {
- qt_mac_event_release(request_activate_pending.event);
- if(request_activate_pending.widget) {
- QWidget *tlw = request_activate_pending.widget->window();
- if (tlw->macEvent(er, event))
- return noErr;
- request_activate_pending.widget = 0;
- tlw->activateWindow();
- SelectWindow(qt_mac_window_for(tlw));
- }
- } else if(ekind == kEventQtRequestContext) {
- bool send = false;
- if ((send = (event == request_context_pending)))
- qt_mac_event_release(request_context_pending);
- if(send) {
- //figure out which widget to send it to
- QPoint where = QCursor::pos();
- QWidget *widget = 0;
- GetEventParameter(event, kEventParamQWidget, typeQWidget, 0,
- sizeof(widget), 0, &widget);
- if(!widget) {
- if(qt_button_down)
- widget = qt_button_down;
- else
- widget = QApplication::widgetAt(where.x(), where.y());
- }
- if(widget && !isBlockedByModal(widget)) {
- if (widget->macEvent(er, event))
- return noErr;
- QPoint plocal(widget->mapFromGlobal(where));
- const Qt::KeyboardModifiers keyboardModifiers = qt_mac_get_modifiers(GetCurrentEventKeyModifiers());
- QContextMenuEvent qme(QContextMenuEvent::Mouse, plocal, where, keyboardModifiers);
- QApplication::sendEvent(widget, &qme);
- if(qme.isAccepted()) { //once this happens the events before are pitched
- qt_button_down = 0;
- qt_mac_dblclick.last_widget = 0;
- }
- } else {
- handled_event = false;
- }
- }
- } else {
- handled_event = false;
- }
- break;
- case kEventClassTablet:
- switch (ekind) {
- case kEventTabletProximity:
- // Get the current point of the device and its unique ID.
- ::TabletProximityRec proxRec;
- GetEventParameter(event, kEventParamTabletProximityRec, typeTabletProximityRec, 0,
- sizeof(proxRec), 0, &proxRec);
- qt_dispatchTabletProximityEvent(proxRec);
- }
- break;
- case kEventClassMouse:
- {
- static const int kEventParamQAppSeenMouseEvent = 'QASM';
- // Check if we've seen the event, if we have we shouldn't process
- // it again as it may lead to spurious "double events"
- bool seenEvent;
- if (GetEventParameter(event, kEventParamQAppSeenMouseEvent,
- typeBoolean, 0, sizeof(bool), 0, &seenEvent) == noErr) {
- if (seenEvent)
- return eventNotHandledErr;
- }
- seenEvent = true;
- SetEventParameter(event, kEventParamQAppSeenMouseEvent, typeBoolean,
- sizeof(bool), &seenEvent);
-
- Point where;
- bool inNonClientArea = false;
- GetEventParameter(event, kEventParamMouseLocation, typeQDPoint, 0,
- sizeof(where), 0, &where);
-#if defined(DEBUG_MOUSE_MAPS)
- const char *edesc = 0;
- switch(ekind) {
- case kEventMouseDown: edesc = "MouseButtonPress"; break;
- case kEventMouseUp: edesc = "MouseButtonRelease"; break;
- case kEventMouseDragged: case kEventMouseMoved: edesc = "MouseMove"; break;
- case kEventMouseScroll: edesc = "MouseWheelScroll"; break;
- case kEventMouseWheelMoved: edesc = "MouseWheelMove"; break;
- }
- if(ekind == kEventMouseDown || ekind == kEventMouseUp)
- qDebug("Handling mouse: %s", edesc);
-#endif
- QEvent::Type etype = QEvent::None;
- Qt::KeyboardModifiers modifiers;
- {
- UInt32 mac_modifiers = 0;
- GetEventParameter(event, kEventParamKeyModifiers, typeUInt32, 0,
- sizeof(mac_modifiers), 0, &mac_modifiers);
- modifiers = qt_mac_get_modifiers(mac_modifiers);
- }
- Qt::MouseButtons buttons;
- {
- UInt32 mac_buttons = 0;
- GetEventParameter(event, kEventParamMouseChord, typeUInt32, 0,
- sizeof(mac_buttons), 0, &mac_buttons);
- if (ekind != kEventMouseWheelMoved)
- buttons = qt_mac_get_buttons(mac_buttons);
- else
- buttons = QApplication::mouseButtons();
- }
-
- int wheel_deltaX = 0;
- int wheel_deltaY = 0;
- static EventRef compatibilityEvent = 0;
-
- if (ekind == kEventMouseScroll) {
- // kEventMouseScroll is the new way of dealing with mouse wheel
- // events (kEventMouseWheelMoved was the old). kEventMouseScroll results
- // in much smoother scrolling when using Mighty Mouse or TrackPad. For
- // compatibility with older applications, carbon will also send us
- // kEventMouseWheelMoved events if we dont eat this event
- // (actually two events; one for horizontal and one for vertical).
- // As a results of this, and to make sure we dont't receive duplicate events,
- // we try to detect when this happend by checking the 'compatibilityEvent'.
- // Since delta is delivered as pixels rather than degrees, we need to
- // convert from pixels to degrees in a sensible manner.
- // It looks like 1/4 degrees per pixel behaves most native.
- // (NB: Qt expects the unit for delta to be 8 per degree):
- const int pixelsToDegrees = 2;
- SInt32 mdelt = 0;
- GetEventParameter(event, kEventParamMouseWheelSmoothHorizontalDelta, typeSInt32, 0,
- sizeof(mdelt), 0, &mdelt);
- wheel_deltaX = mdelt * pixelsToDegrees;
- mdelt = 0;
- GetEventParameter(event, kEventParamMouseWheelSmoothVerticalDelta, typeSInt32, 0,
- sizeof(mdelt), 0, &mdelt);
- wheel_deltaY = mdelt * pixelsToDegrees;
- GetEventParameter(event, kEventParamEventRef, typeEventRef, 0,
- sizeof(compatibilityEvent), 0, &compatibilityEvent);
- } else if (ekind == kEventMouseWheelMoved) {
- if (event != compatibilityEvent) {
- compatibilityEvent = 0;
- int mdelt = 0;
- GetEventParameter(event, kEventParamMouseWheelDelta, typeSInt32, 0,
- sizeof(mdelt), 0, &mdelt);
- EventMouseWheelAxis axis;
- GetEventParameter(event, kEventParamMouseWheelAxis, typeMouseWheelAxis, 0,
- sizeof(axis), 0, &axis);
-
- // Remove acceleration, and use either -120 or 120 as delta:
- if (axis == kEventMouseWheelAxisX)
- wheel_deltaX = qBound(-120, int(mdelt * 10000), 120);
- else
- wheel_deltaY = qBound(-120, int(mdelt * 10000), 120);
- }
- }
-
- Qt::MouseButton button = Qt::NoButton;
- if(ekind == kEventMouseDown || ekind == kEventMouseUp) {
- EventMouseButton mac_button = 0;
- GetEventParameter(event, kEventParamMouseButton, typeMouseButton, 0,
- sizeof(mac_button), 0, &mac_button);
- button = qt_mac_get_button(mac_button);
- }
-
- switch(ekind) {
- case kEventMouseDown:
- etype = QEvent::MouseButtonPress;
- break;
- case kEventMouseUp:
- etype = QEvent::MouseButtonRelease;
- break;
- case kEventMouseDragged:
- case kEventMouseMoved:
- etype = QEvent::MouseMove;
- break;
- }
-
- const bool inPopupMode = app->d_func()->inPopupMode();
-
- // A click outside a popup closes the popup. Make sure
- // that no events are generated for the release part of that click.
- // (The press goes to the popup and closes it.)
- if (etype == QEvent::MouseButtonPress) {
- qt_mac_previous_press_in_popup_mode = inPopupMode;
- } else if (qt_mac_previous_press_in_popup_mode && !inPopupMode && etype == QEvent::MouseButtonRelease) {
- qt_mac_previous_press_in_popup_mode = false;
- handled_event = true;
-#if defined(DEBUG_MOUSE_MAPS)
- qDebug("Bail out early due to qt_mac_previous_press_in_popup_mode");
-#endif
- break; // break from case kEventClassMouse
- }
-
- //figure out which widget to send it to
- if(inPopupMode) {
- QWidget *popup = qApp->activePopupWidget();
- if (qt_button_down && qt_button_down->window() == popup) {
- widget = qt_button_down;
- } else {
- QPoint pos = popup->mapFromGlobal(QPoint(where.h, where.v));
- widget = popup->childAt(pos);
- }
- if(!widget)
- widget = popup;
- } else {
- if(mac_mouse_grabber) {
- widget = mac_mouse_grabber;
- } else if (qt_button_down) {
- widget = qt_button_down;
- } else {
- {
- WindowPtr window = 0;
- if(GetEventParameter(event, kEventParamWindowRef, typeWindowRef, 0,
- sizeof(window), 0, &window) != noErr)
- FindWindowOfClass(&where, kAllWindowClasses, &window, 0);
- if(window) {
- HIViewRef hiview;
- if(HIViewGetViewForMouseEvent(HIViewGetRoot(window), event, &hiview) == noErr) {
- widget = QWidget::find((WId)hiview);
- if (widget) {
- // Make sure we didn't pass over a widget with a "fake hole" in it.
- QWidget *otherWidget = QApplication::widgetAt(where.h, where.v);
- if (otherWidget && otherWidget->testAttribute(Qt::WA_MouseNoMask))
- widget = otherWidget;
- }
- }
- }
- }
- if(!widget) //fallback
- widget = QApplication::widgetAt(where.h, where.v);
- if(ekind == kEventMouseUp && widget) {
- short part = qt_mac_window_at(where.h, where.v);
- if(part == inDrag) {
- UInt32 count = 0;
- GetEventParameter(event, kEventParamClickCount, typeUInt32, NULL,
- sizeof(count), NULL, &count);
- if(count == 2 && qt_mac_collapse_on_dblclick) {
- if (widget->macEvent(er, event))
- return noErr;
- widget->setWindowState(widget->windowState() | Qt::WindowMinimized);
- //we send a hide to be like X11/Windows
- QEvent e(QEvent::Hide);
- QApplication::sendSpontaneousEvent(widget, &e);
- break;
- }
- }
- }
- }
- }
- if (widget && widget->macEvent(er, event))
- return noErr;
- WindowPartCode wpc = qt_mac_window_at(where.h, where.v, 0);
- if (wpc == inProxyIcon && modifiers == Qt::ControlModifier && buttons != Qt::NoButton) {
- QIconDragEvent e;
- QApplication::sendSpontaneousEvent(widget, &e);
- if (e.isAccepted()) {
- return noErr; // IconDrag ate it.
- }
- }
- if (inPopupMode == false
- && (qt_button_down == 0 || qt_button_down_in_content == false)
- && (wpc != inContent && wpc != inStructure)) {
- inNonClientArea = true;
- switch (etype) {
- case QEvent::MouseButtonPress: {
- UInt32 count = 0;
- GetEventParameter(event, kEventParamClickCount, typeUInt32, 0,
- sizeof(count), 0, &count);
- if(count % 2 || count == 0) {
- etype = QEvent::NonClientAreaMouseButtonPress;
- } else {
- etype = QEvent::NonClientAreaMouseButtonDblClick;
- }} break;
- case QEvent::MouseButtonRelease:
- etype = QEvent::NonClientAreaMouseButtonRelease;
- break;
- case QEvent::MouseMove:
- if (widget == 0 || widget->hasMouseTracking())
- etype = QEvent::NonClientAreaMouseMove;
- break;
- default:
- break;
- }
- }
-
- if(qt_mac_find_window((FrontWindow()))) { //set the cursor up
- QCursor cursor(Qt::ArrowCursor);
- QWidget *cursor_widget = widget;
- if(cursor_widget && cursor_widget == qt_button_down && ekind == kEventMouseUp)
- cursor_widget = QApplication::widgetAt(where.h, where.v);
- if(cursor_widget) { //only over the app, do we set a cursor..
- if(!qApp->d_func()->cursor_list.isEmpty()) {
- cursor = qApp->d_func()->cursor_list.first();
- } else {
- for(; cursor_widget; cursor_widget = cursor_widget->parentWidget()) {
- QWExtra *extra = cursor_widget->d_func()->extraData();
- if(extra && extra->curs && cursor_widget->isEnabled()) {
- cursor = *extra->curs;
- break;
- }
- }
- }
- }
- qt_mac_set_cursor(&cursor);
- }
-
- //This mouse button state stuff looks like this on purpose
- //although it looks hacky it is VERY intentional..
- if(widget && app_do_modal && !qt_try_modal(widget, event)) {
- if(ekind == kEventMouseDown && qt_mac_is_macsheet(QApplication::activeModalWidget()))
- QApplication::activeModalWidget()->parentWidget()->activateWindow(); //sheets have a parent
- handled_event = false;
-#if defined(DEBUG_MOUSE_MAPS)
- qDebug("Bail out early due to qt_try_modal");
-#endif
- break;
- }
-
- UInt32 tabletEventType = 0;
- GetEventParameter(event, kEventParamTabletEventType, typeUInt32, 0,
- sizeof(tabletEventType), 0, &tabletEventType);
- if (tabletEventType == kEventTabletPoint) {
- TabletPointRec tabletPointRec;
- GetEventParameter(event, kEventParamTabletPointRec, typeTabletPointRec, 0,
- sizeof(tabletPointRec), 0, &tabletPointRec);
- QEvent::Type t = QEvent::TabletMove; //default
- int new_tablet_button_state = tabletPointRec.buttons ? 1 : 0;
- if (new_tablet_button_state != tablet_button_state)
- if (new_tablet_button_state)
- t = QEvent::TabletPress;
- else
- t = QEvent::TabletRelease;
- tablet_button_state = new_tablet_button_state;
-
- QMacTabletHash *tabletHash = qt_mac_tablet_hash();
- if (!tabletHash->contains(tabletPointRec.deviceID) && t != QEvent::TabletRelease) {
- // Never discard TabletRelease events as they may be delivered *after* TabletLeaveProximity events
- qWarning("handleTabletEvent: This tablet device is unknown"
- " (received no proximity event for it). Discarding event.");
- return false;
- }
- QTabletDeviceData &deviceData = tabletHash->operator[](tabletPointRec.deviceID);
- if (t == QEvent::TabletPress) {
- deviceData.widgetToGetPress = widget;
- } else if (t == QEvent::TabletRelease && deviceData.widgetToGetPress) {
- widget = deviceData.widgetToGetPress;
- deviceData.widgetToGetPress = 0;
- }
-
- if (widget) {
- int tiltX = ((int)tabletPointRec.tiltX)/(32767/64); // 32K -> 60
- int tiltY = ((int)tabletPointRec.tiltY)/(-32767/64); // 32K -> 60
- HIPoint hiPoint;
- GetEventParameter(event, kEventParamMouseLocation, typeHIPoint, 0, sizeof(HIPoint), 0, &hiPoint);
- QPointF hiRes(hiPoint.x, hiPoint.y);
- QPoint global(where.h, where.v);
-
-
-
- QPoint local(widget->mapFromGlobal(global));
- int z = 0;
- qreal rotation = 0.0;
- qreal tp = 0.0;
- // Again from the Wacom.h header
-
- if (deviceData.capabilityMask & 0x0200) // Z-axis
- z = tabletPointRec.absZ;
-
- if (deviceData.capabilityMask & 0x0800) // Tangential pressure
- tp = tabletPointRec.tangentialPressure / 32767.0;
-
- if (deviceData.capabilityMask & 0x2000) // Rotation
- rotation = qreal(tabletPointRec.rotation) / 64.0;
-
- QTabletEvent e(t, local, global, hiRes, deviceData.tabletDeviceType,
- deviceData.tabletPointerType,
- qreal(tabletPointRec.pressure / qreal(0xffff)), tiltX, tiltY,
- tp, rotation, z, modifiers, deviceData.tabletUniqueID);
- QApplication::sendSpontaneousEvent(widget, &e);
- if (e.isAccepted()) {
- if (t == QEvent::TabletPress) {
- qt_button_down = widget;
- } else if (t == QEvent::TabletRelease) {
- qt_button_down = 0;
- }
-#if defined(DEBUG_MOUSE_MAPS)
- qDebug("Bail out early due to tablet acceptance");
-#endif
- break;
- }
- }
- }
-
- if(ekind == kEventMouseDown) {
- qt_mac_no_click_through_mode = false;
- const short windowPart = qt_mac_window_at(where.h, where.v, 0);
- // Menubar almost always wins.
- if (!inPopupMode && windowPart == inMenuBar) {
- MenuSelect(where); //allow menu tracking
- return noErr;
- }
-
- if (widget && !(GetCurrentKeyModifiers() & cmdKey)) {
- extern bool qt_isGenuineQWidget(const QWidget *); // qwidget_mac.cpp
- QWidget *window = widget->window();
- bool genuineQtWidget = qt_isGenuineQWidget(widget); // the widget, not the window.
- window->raise();
-
- bool needActivate = (window->windowType() != Qt::Desktop)
- && (window->windowType() != Qt::Popup)
- && !qt_mac_is_macsheet(window);
- if (needActivate && (!window->isModal() && qobject_cast<QDockWidget *>(window)))
- needActivate = false;
-
- if (genuineQtWidget && needActivate)
- needActivate = !window->isActiveWindow()
- || !IsWindowActive(qt_mac_window_for(window));
-
- if (needActivate) {
- window->activateWindow();
- if (!qt_mac_can_clickThrough(widget)) {
- qt_mac_no_click_through_mode = true;
- handled_event = false;
-#if defined(DEBUG_MOUSE_MAPS)
- qDebug("Bail out early due to qt_mac_canClickThrough %s::%s", widget->metaObject()->className(),
- widget->objectName().toLocal8Bit().constData());
-#endif
- break;
- }
- }
- }
-
- if(qt_mac_dblclick.last_widget &&
- qt_mac_dblclick.last_x != -1 && qt_mac_dblclick.last_y != -1 &&
- QRect(qt_mac_dblclick.last_x-2, qt_mac_dblclick.last_y-2, 4, 4).contains(QPoint(where.h, where.v))) {
- if(qt_mac_dblclick.use_qt_time_limit) {
- EventTime now = GetEventTime(event);
- if(qt_mac_dblclick.last_time != -2 && qt_mac_dblclick.last_widget == widget &&
- now - qt_mac_dblclick.last_time <= ((double)QApplicationPrivate::mouse_double_click_time)/1000 &&
- qt_mac_dblclick.last_button == button)
- etype = QEvent::MouseButtonDblClick;
- } else {
- UInt32 count = 0;
- GetEventParameter(event, kEventParamClickCount, typeUInt32, 0,
- sizeof(count), 0, &count);
- if(!(count % 2) && qt_mac_dblclick.last_modifiers == modifiers &&
- qt_mac_dblclick.last_widget == widget && qt_mac_dblclick.last_button == button)
- etype = QEvent::MouseButtonDblClick;
- }
- if(etype == QEvent::MouseButtonDblClick)
- qt_mac_dblclick.last_widget = 0;
- }
- if(etype != QEvent::MouseButtonDblClick) {
- qt_mac_dblclick.last_x = where.h;
- qt_mac_dblclick.last_y = where.v;
- } else {
- qt_mac_dblclick.last_x = qt_mac_dblclick.last_y = -1;
- }
- } else if(qt_mac_no_click_through_mode) {
- if(ekind == kEventMouseUp)
- qt_mac_no_click_through_mode = false;
- handled_event = false;
-#if defined(DEBUG_MOUSE_MAPS)
- qDebug("Bail out early due to qt_mac_no_click_through_mode");
-#endif
- break;
- }
-
- QPointer<QWidget> leaveAfterRelease = 0;
- switch(ekind) {
- case kEventMouseUp:
- if (!buttons) {
- if (!inPopupMode && !QWidget::mouseGrabber())
- leaveAfterRelease = qt_button_down;
- qt_button_down = 0;
- }
- break;
- case kEventMouseDown: {
- if (!qt_button_down)
- qt_button_down = widget;
- WindowPartCode wpc = qt_mac_window_at(where.h, where.v, 0);
- qt_button_down_in_content = (wpc == inContent || wpc == inStructure);
- break; }
- }
-
- // Check if we should send enter/leave events:
- switch(ekind) {
- case kEventMouseDragged:
- case kEventMouseMoved:
- case kEventMouseUp:
- case kEventMouseDown: {
- // If we are in popup mode, widget will point to the current popup no matter
- // where the mouse cursor is. In that case find out if the mouse cursor is
- // really over the popup in order to send correct enter / leave envents.
- QWidget * const enterLeaveWidget = (inPopupMode || ekind == kEventMouseUp) ?
- QApplication::widgetAt(where.h, where.v) : static_cast<QWidget*>(widget);
-
- if ((QWidget *) qt_last_mouse_receiver != enterLeaveWidget || inNonClientArea) {
-#ifdef DEBUG_MOUSE_MAPS
- qDebug("Entering: %p - %s (%s), Leaving %s (%s)", (QWidget*)enterLeaveWidget,
- enterLeaveWidget ? enterLeaveWidget->metaObject()->className() : "none",
- enterLeaveWidget ? enterLeaveWidget->objectName().toLocal8Bit().constData() : "",
- qt_last_mouse_receiver ? qt_last_mouse_receiver->metaObject()->className() : "none",
- qt_last_mouse_receiver ? qt_last_mouse_receiver->objectName().toLocal8Bit().constData() : "");
-#endif
-
- QWidget * const mouseGrabber = QWidget::mouseGrabber();
-
- if (inPopupMode) {
- QWidget *enter = enterLeaveWidget;
- QWidget *leave = qt_last_mouse_receiver;
- if (mouseGrabber) {
- QWidget * const popupWidget = qApp->activePopupWidget();
- if (leave == popupWidget)
- enter = mouseGrabber;
- if (enter == popupWidget)
- leave = mouseGrabber;
- if ((enter == mouseGrabber && leave == popupWidget)
- || (leave == mouseGrabber && enter == popupWidget)) {
- QApplicationPrivate::dispatchEnterLeave(enter, leave);
- qt_last_mouse_receiver = enter;
- }
- } else {
- QApplicationPrivate::dispatchEnterLeave(enter, leave);
- qt_last_mouse_receiver = enter;
- }
- } else if ((!qt_button_down || !qt_last_mouse_receiver) && !mouseGrabber && !leaveAfterRelease) {
- QApplicationPrivate::dispatchEnterLeave(enterLeaveWidget, qt_last_mouse_receiver);
- qt_last_mouse_receiver = enterLeaveWidget;
- }
- }
- break; }
- }
-
- if(widget) {
- QPoint p(where.h, where.v);
- QPoint plocal(widget->mapFromGlobal(p));
- if(etype == QEvent::MouseButtonPress) {
- qt_mac_dblclick.last_widget = widget;
- qt_mac_dblclick.last_modifiers = modifiers;
- qt_mac_dblclick.last_button = button;
- qt_mac_dblclick.last_time = GetEventTime(event);
- }
-
- if (wheel_deltaX || wheel_deltaY) {
-#ifndef QT_NO_WHEELEVENT
- if (wheel_deltaX) {
- QWheelEvent qwe(plocal, p, wheel_deltaX, buttons, modifiers, Qt::Horizontal);
- QApplication::sendSpontaneousEvent(widget, &qwe);
- if (!qwe.isAccepted() && QApplicationPrivate::focus_widget && QApplicationPrivate::focus_widget != widget) {
- QWheelEvent qwe2(QApplicationPrivate::focus_widget->mapFromGlobal(p), p,
- wheel_deltaX, buttons, modifiers, Qt::Horizontal);
- QApplication::sendSpontaneousEvent(QApplicationPrivate::focus_widget, &qwe2);
- if (!qwe2.isAccepted())
- handled_event = false;
- }
- }
- if (wheel_deltaY) {
- QWheelEvent qwe(plocal, p, wheel_deltaY, buttons, modifiers, Qt::Vertical);
- QApplication::sendSpontaneousEvent(widget, &qwe);
- if (!qwe.isAccepted() && QApplicationPrivate::focus_widget && QApplicationPrivate::focus_widget != widget) {
- QWheelEvent qwe2(QApplicationPrivate::focus_widget->mapFromGlobal(p), p,
- wheel_deltaY, buttons, modifiers, Qt::Vertical);
- QApplication::sendSpontaneousEvent(QApplicationPrivate::focus_widget, &qwe2);
- if (!qwe2.isAccepted())
- handled_event = false;
- }
- }
-#endif // QT_NO_WHEELEVENT
- } else {
-#ifdef QMAC_SPEAK_TO_ME
- const int speak_keys = Qt::AltModifier | Qt::ShiftModifier;
- if(etype == QMouseEvent::MouseButtonDblClick && ((modifiers & speak_keys) == speak_keys)) {
- QVariant v = widget->property("displayText");
- if(!v.isValid()) v = widget->property("text");
- if(!v.isValid()) v = widget->property("windowTitle");
- if(v.isValid()) {
- QString s = v.toString();
- s.replace(QRegExp(QString::fromLatin1("(\\&|\\<[^\\>]*\\>)")), QLatin1String(""));
- SpeechChannel ch;
- NewSpeechChannel(0, &ch);
- SpeakText(ch, s.toLatin1().constData(), s.length());
- DisposeSpeechChannel(ch);
- }
- }
-#endif
- Qt::MouseButton buttonToSend = button;
- static bool lastButtonTranslated = false;
- if(ekind == kEventMouseDown &&
- button == Qt::LeftButton && (modifiers & Qt::MetaModifier)) {
- buttonToSend = Qt::RightButton;
- lastButtonTranslated = true;
- } else if(ekind == kEventMouseUp && lastButtonTranslated) {
- buttonToSend = Qt::RightButton;
- lastButtonTranslated = false;
- }
- QMouseEvent qme(etype, plocal, p, buttonToSend, buttons, modifiers);
- QApplication::sendSpontaneousEvent(widget, &qme);
- if(!qme.isAccepted() || inNonClientArea)
- handled_event = false;
- }
-
- if (leaveAfterRelease) {
- QWidget *enter = QApplication::widgetAt(where.h, where.v);
- QApplicationPrivate::dispatchEnterLeave(enter, leaveAfterRelease);
- qt_last_mouse_receiver = enter;
- leaveAfterRelease = 0;
- }
-
- if(ekind == kEventMouseDown &&
- ((button == Qt::RightButton) ||
- (button == Qt::LeftButton && (modifiers & Qt::MetaModifier))))
- qt_event_request_context();
-
-#ifdef DEBUG_MOUSE_MAPS
- const char *event_desc = edesc;
- if(etype == QEvent::MouseButtonDblClick)
- event_desc = "Double Click";
- else if(etype == QEvent::NonClientAreaMouseButtonPress)
- event_desc = "NonClientMousePress";
- else if(etype == QEvent::NonClientAreaMouseButtonRelease)
- event_desc = "NonClientMouseRelease";
- else if(etype == QEvent::NonClientAreaMouseMove)
- event_desc = "NonClientMouseMove";
- else if(etype == QEvent::NonClientAreaMouseButtonDblClick)
- event_desc = "NonClientMouseDblClick";
- qDebug("%d %d (%d %d) - Would send (%s) event to %p %s %s (%d 0x%08x 0x%08x %d)", p.x(), p.y(),
- plocal.x(), plocal.y(), event_desc, (QWidget*)widget,
- widget ? widget->objectName().toLocal8Bit().constData() : "*Unknown*",
- widget ? widget->metaObject()->className() : "*Unknown*",
- button, (int)buttons, (int)modifiers, wheel_deltaX);
-#endif
- } else {
- handled_event = false;
- }
- break;
- }
- case kEventClassTextInput:
- case kEventClassKeyboard: {
- EventRef key_event = event;
- if(eclass == kEventClassTextInput) {
- Q_ASSERT(ekind == kEventTextInputUnicodeForKeyEvent);
- OSStatus err = GetEventParameter(event, kEventParamTextInputSendKeyboardEvent, typeEventRef, 0,
- sizeof(key_event), 0, &key_event);
- Q_ASSERT(err == noErr);
- Q_UNUSED(err);
- }
- const UInt32 key_ekind = GetEventKind(key_event);
- Q_ASSERT(GetEventClass(key_event) == kEventClassKeyboard);
-
- if(key_ekind == kEventRawKeyDown)
- qt_keymapper_private()->updateKeyMap(er, key_event, data);
- if(mac_keyboard_grabber)
- widget = mac_keyboard_grabber;
- else if (app->activePopupWidget())
- widget = (app->activePopupWidget()->focusWidget() ?
- app->activePopupWidget()->focusWidget() : app->activePopupWidget());
- else if(QApplication::focusWidget())
- widget = QApplication::focusWidget();
- else
- widget = app->activeWindow();
-
- if (widget) {
- if (widget->macEvent(er, event))
- return noErr;
- } else {
- // Darn, I need to update tho modifier state, even though
- // Qt itself isn't getting them, otherwise the keyboard state get inconsistent.
- if (key_ekind == kEventRawKeyModifiersChanged) {
- UInt32 modifiers = 0;
- GetEventParameter(key_event, kEventParamKeyModifiers, typeUInt32, 0,
- sizeof(modifiers), 0, &modifiers);
- extern void qt_mac_send_modifiers_changed(quint32 modifiers, QObject *object); // qkeymapper_mac.cpp
- // Just send it to the qApp for the time being.
- qt_mac_send_modifiers_changed(modifiers, qApp);
- }
- handled_event = false;
- break;
- }
-
- if(app_do_modal && !qt_try_modal(widget, key_event))
- break;
- if (eclass == kEventClassTextInput) {
- handled_event = false;
- } else {
- handled_event = qt_keymapper_private()->translateKeyEvent(widget, er, key_event, data,
- widget == mac_keyboard_grabber);
- }
- break; }
- case kEventClassWindow: {
- WindowRef wid = 0;
- GetEventParameter(event, kEventParamDirectObject, typeWindowRef, 0,
- sizeof(WindowRef), 0, &wid);
- widget = qt_mac_find_window(wid);
- if (widget && widget->macEvent(er, event))
- return noErr;
- if(ekind == kEventWindowActivated) {
- if(QApplicationPrivate::app_style) {
- QEvent ev(QEvent::Style);
- QApplication::sendSpontaneousEvent(QApplicationPrivate::app_style, &ev);
- }
-
- if(widget && app_do_modal && !qt_try_modal(widget, event))
- break;
-
- if(widget && widget->window()->isVisible()) {
- QWidget *tlw = widget->window();
- if(tlw->isWindow() && !(tlw->windowType() == Qt::Popup)
- && !qt_mac_is_macdrawer(tlw)
- && (!tlw->parentWidget() || tlw->isModal()
- || !(tlw->windowType() == Qt::Tool))) {
- bool just_send_event = false;
- {
- WindowActivationScope scope;
- if(GetWindowActivationScope((WindowRef)wid, &scope) == noErr &&
- scope == kWindowActivationScopeIndependent) {
- if(GetFrontWindowOfClass(kAllWindowClasses, true) != wid)
- just_send_event = true;
- }
- }
- if(just_send_event) {
- QEvent e(QEvent::WindowActivate);
- QApplication::sendSpontaneousEvent(widget, &e);
- } else {
- app->setActiveWindow(tlw);
- }
- }
- QMenuBar::macUpdateMenuBar();
- }
- } else if(ekind == kEventWindowDeactivated) {
- if(widget && QApplicationPrivate::active_window == widget)
- app->setActiveWindow(0);
- } else {
- handled_event = false;
- }
- break; }
- case kEventClassApplication:
- if(ekind == kEventAppActivated) {
- if(QApplication::desktopSettingsAware())
- qt_mac_update_os_settings();
- if(qt_clipboard) { //manufacture an event so the clipboard can see if it has changed
- QEvent ev(QEvent::Clipboard);
- QApplication::sendSpontaneousEvent(qt_clipboard, &ev);
- }
- if(app) {
- QEvent ev(QEvent::ApplicationActivate);
- QApplication::sendSpontaneousEvent(app, &ev);
- }
- if(!app->activeWindow()) {
- WindowPtr wp = ActiveNonFloatingWindow();
- if(QWidget *tmp_w = qt_mac_find_window(wp))
- app->setActiveWindow(tmp_w);
- }
- QMenuBar::macUpdateMenuBar();
- } else if(ekind == kEventAppDeactivated) {
- //qt_mac_no_click_through_mode = false;
- while(app->d_func()->inPopupMode())
- app->activePopupWidget()->close();
- if(app) {
- QEvent ev(QEvent::ApplicationDeactivate);
- QApplication::sendSpontaneousEvent(app, &ev);
- }
- app->setActiveWindow(0);
- } else if(ekind == kEventAppAvailableWindowBoundsChanged) {
- QDesktopWidgetImplementation::instance()->onResize();
- } else {
- handled_event = false;
- }
- break;
- case kAppearanceEventClass:
- if(ekind == kAEAppearanceChanged) {
- if(QApplication::desktopSettingsAware())
- qt_mac_update_os_settings();
- if(QApplicationPrivate::app_style) {
- QEvent ev(QEvent::Style);
- QApplication::sendSpontaneousEvent(QApplicationPrivate::app_style, &ev);
- }
- } else {
- handled_event = false;
- }
- break;
- case kEventClassAppleEvent:
- if(ekind == kEventAppleEvent) {
- EventRecord erec;
- if(!ConvertEventRefToEventRecord(event, &erec))
- qDebug("Qt: internal: WH0A, unexpected condition reached. %s:%d", __FILE__, __LINE__);
- else if(AEProcessAppleEvent(&erec) != noErr)
- handled_event = false;
- } else {
- handled_event = false;
- }
- break;
- case kEventClassCommand:
- if(ekind == kEventCommandProcess) {
- HICommand cmd;
- GetEventParameter(event, kEventParamDirectObject, typeHICommand,
- 0, sizeof(cmd), 0, &cmd);
- handled_event = false;
- if(!cmd.menu.menuRef && GetApplicationDockTileMenu()) {
- EventRef copy = CopyEvent(event);
- HICommand copy_cmd;
- GetEventParameter(event, kEventParamDirectObject, typeHICommand,
- 0, sizeof(copy_cmd), 0, &copy_cmd);
- copy_cmd.menu.menuRef = GetApplicationDockTileMenu();
- SetEventParameter(copy, kEventParamDirectObject, typeHICommand, sizeof(copy_cmd), &copy_cmd);
- if(SendEventToMenu(copy, copy_cmd.menu.menuRef) == noErr)
- handled_event = true;
- }
- if(!handled_event) {
- if(cmd.commandID == kHICommandQuit) {
- // Quitting the application is not Qt's responsibility if
- // used in a plugin or just embedded into a native application.
- // In that case, let the event pass down to the native apps event handler.
- if (!QApplication::testAttribute(Qt::AA_MacPluginApplication)) {
- handled_event = true;
- HiliteMenu(0);
- bool handle_quit = true;
- if(QApplicationPrivate::modalState()) {
- int visible = 0;
- const QWidgetList tlws = QApplication::topLevelWidgets();
- for(int i = 0; i < tlws.size(); ++i) {
- if(tlws.at(i)->isVisible())
- ++visible;
- }
- handle_quit = (visible <= 1);
- }
- if(handle_quit) {
- QCloseEvent ev;
- QApplication::sendSpontaneousEvent(app, &ev);
- if(ev.isAccepted())
- app->quit();
- } else {
- QApplication::beep();
- }
- }
- } else if(cmd.commandID == kHICommandSelectWindow) {
- if((GetCurrentKeyModifiers() & cmdKey))
- handled_event = true;
- } else if(cmd.commandID == kHICommandAbout) {
- QMessageBox::aboutQt(0);
- HiliteMenu(0);
- handled_event = true;
- }
- }
- }
- break;
- }
-
-#ifdef DEBUG_EVENTS
- qDebug("%shandled event %c%c%c%c %d", handled_event ? "(*) " : "",
- char(eclass >> 24), char((eclass >> 16) & 255), char((eclass >> 8) & 255),
- char(eclass & 255), (int)ekind);
-#endif
- if(!handled_event) //let the event go through
- return eventNotHandledErr;
- return noErr; //we eat the event
-#else
- Q_UNUSED(er);
- Q_UNUSED(event);
- Q_UNUSED(data);
- return eventNotHandledErr;
-#endif
-}
-
-#ifdef QT_MAC_USE_COCOA
-void QApplicationPrivate::qt_initAfterNSAppStarted()
-{
- setupAppleEvents();
- qt_mac_update_cursor();
-}
-
-void QApplicationPrivate::setupAppleEvents()
-{
- // This function is called from the event dispatcher when NSApplication has
- // finished initialization, which appears to be just after [NSApplication run] has
- // started to execute. By setting up our apple events handlers this late, we override
- // the ones set up by NSApplication.
-
- // If Qt is used as a plugin, we let the 3rd party application handle events
- // like quit and open file events. Otherwise, if we install our own handlers, we
- // easily end up breaking functionallity the 3rd party application depend on:
- if (QApplication::testAttribute(Qt::AA_MacPluginApplication))
- return;
-
- QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) *newDelegate = [QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) sharedDelegate];
- NSAppleEventManager *eventManager = [NSAppleEventManager sharedAppleEventManager];
- [eventManager setEventHandler:newDelegate andSelector:@selector(appleEventQuit:withReplyEvent:)
- forEventClass:kCoreEventClass andEventID:kAEQuitApplication];
- [eventManager setEventHandler:newDelegate andSelector:@selector(getUrl:withReplyEvent:)
- forEventClass:kInternetEventClass andEventID:kAEGetURL];
-}
-#endif
-
-// In Carbon this is your one stop for apple events.
-// In Cocoa, it ISN'T. This is the catch-all Apple Event handler that exists
-// for the time between instantiating the NSApplication, but before the
-// NSApplication has installed it's OWN Apple Event handler. When Cocoa has
-// that set up, we remove this. So, if you are debugging problems, you likely
-// want to check out QCocoaApplicationDelegate instead.
-OSStatus QApplicationPrivate::globalAppleEventProcessor(const AppleEvent *ae, AppleEvent *, long handlerRefcon)
-{
- QApplication *app = (QApplication *)handlerRefcon;
- bool handled_event=false;
- OSType aeID=typeWildCard, aeClass=typeWildCard;
- AEGetAttributePtr(ae, keyEventClassAttr, typeType, 0, &aeClass, sizeof(aeClass), 0);
- AEGetAttributePtr(ae, keyEventIDAttr, typeType, 0, &aeID, sizeof(aeID), 0);
- if(aeClass == kCoreEventClass) {
- switch(aeID) {
- case kAEQuitApplication: {
- extern bool qt_mac_quit_menu_item_enabled; // qmenu_mac.cpp
- if (qt_mac_quit_menu_item_enabled) {
- QCloseEvent ev;
- QApplication::sendSpontaneousEvent(app, &ev);
- if(ev.isAccepted()) {
- handled_event = true;
- app->quit();
- }
- } else {
- QApplication::beep(); // Sorry, you can't quit right now.
- }
- break; }
- case kAEOpenDocuments: {
- AEDescList docs;
- if(AEGetParamDesc(ae, keyDirectObject, typeAEList, &docs) == noErr) {
- long cnt = 0;
- AECountItems(&docs, &cnt);
- UInt8 *str_buffer = NULL;
- for(int i = 0; i < cnt; i++) {
- FSRef ref;
- if(AEGetNthPtr(&docs, i+1, typeFSRef, 0, 0, &ref, sizeof(ref), 0) != noErr)
- continue;
- if(!str_buffer)
- str_buffer = (UInt8 *)malloc(1024);
- FSRefMakePath(&ref, str_buffer, 1024);
- QFileOpenEvent ev(QString::fromUtf8((const char *)str_buffer));
- QApplication::sendSpontaneousEvent(app, &ev);
- }
- if(str_buffer)
- free(str_buffer);
- }
- break; }
- default:
- break;
- }
- } else if (aeClass == kInternetEventClass) {
- switch (aeID) {
- case kAEGetURL: {
- char urlData[1024];
- Size actualSize;
- if (AEGetParamPtr(ae, keyDirectObject, typeChar, 0, urlData,
- sizeof(urlData) - 1, &actualSize) == noErr) {
- urlData[actualSize] = 0;
- QFileOpenEvent ev(QUrl(QString::fromUtf8(urlData)));
- QApplication::sendSpontaneousEvent(app, &ev);
- }
- break;
- }
- default:
- break;
- }
- }
-#ifdef DEBUG_EVENTS
- qDebug("Qt: internal: %shandled Apple event! %c%c%c%c %c%c%c%c", handled_event ? "(*)" : "",
- char(aeID >> 24), char((aeID >> 16) & 255), char((aeID >> 8) & 255),char(aeID & 255),
- char(aeClass >> 24), char((aeClass >> 16) & 255), char((aeClass >> 8) & 255),char(aeClass & 255));
-#else
- if(!handled_event) //let the event go through
- return eventNotHandledErr;
- return noErr; //we eat the event
-#endif
-}
-
-/*!
- \fn bool QApplication::macEventFilter(EventHandlerCallRef caller, EventRef event)
-
- \warning This virtual function is only used under Mac OS X, and behaves different
- depending on if Qt is based on Carbon or Cocoa.
-
- For the Carbon port, If you create an application that inherits QApplication and reimplement
- this function, you get direct access to all Carbon Events that Qt registers
- for from Mac OS X with this function being called with the \a caller and
- the \a event.
-
- For the Cocoa port, If you create an application that inherits QApplication and reimplement
- this function, you get direct access to all Cocoa Events that Qt receives
- from Mac OS X with this function being called with the \a caller being 0 and
- the \a event being an NSEvent pointer:
-
- NSEvent *e = reinterpret_cast<NSEvent *>(event);
-
- Return true if you want to stop the event from being processed.
- Return false for normal event dispatching. The default
- implementation returns false.
-*/
-bool QApplication::macEventFilter(EventHandlerCallRef, EventRef)
-{
- return false;
-}
-
-/*!
- \internal
-*/
-void QApplicationPrivate::openPopup(QWidget *popup)
-{
- if (!QApplicationPrivate::popupWidgets) // create list
- QApplicationPrivate::popupWidgets = new QWidgetList;
- QApplicationPrivate::popupWidgets->append(popup); // add to end of list
-
- // popups are not focus-handled by the window system (the first
- // popup grabbed the keyboard), so we have to do that manually: A
- // new popup gets the focus
- if (popup->focusWidget()) {
- popup->focusWidget()->setFocus(Qt::PopupFocusReason);
- } else if (QApplicationPrivate::popupWidgets->count() == 1) { // this was the first popup
- popup->setFocus(Qt::PopupFocusReason);
- }
-}
-
-/*!
- \internal
-*/
-void QApplicationPrivate::closePopup(QWidget *popup)
-{
- Q_Q(QApplication);
- if (!QApplicationPrivate::popupWidgets)
- return;
-
- QApplicationPrivate::popupWidgets->removeAll(popup);
- if (popup == qt_button_down)
- qt_button_down = 0;
- if (QApplicationPrivate::popupWidgets->isEmpty()) { // this was the last popup
- delete QApplicationPrivate::popupWidgets;
- QApplicationPrivate::popupWidgets = 0;
-
- // Special case for Tool windows: since they are activated and deactived together
- // with a normal window they never become the QApplicationPrivate::active_window.
- QWidget *appFocusWidget = QApplication::focusWidget();
- if (appFocusWidget && appFocusWidget->window()->windowType() == Qt::Tool) {
- appFocusWidget->setFocus(Qt::PopupFocusReason);
- } else if (QApplicationPrivate::active_window) {
- if (QWidget *fw = QApplicationPrivate::active_window->focusWidget()) {
- if (fw != QApplication::focusWidget()) {
- fw->setFocus(Qt::PopupFocusReason);
- } else {
- QFocusEvent e(QEvent::FocusIn, Qt::PopupFocusReason);
- q->sendEvent(fw, &e);
- }
- }
- }
- } else {
- // popups are not focus-handled by the window system (the
- // first popup grabbed the keyboard), so we have to do that
- // manually: A popup was closed, so the previous popup gets
- // the focus.
- QWidget* aw = QApplicationPrivate::popupWidgets->last();
- if (QWidget *fw = aw->focusWidget())
- fw->setFocus(Qt::PopupFocusReason);
- }
-}
-
-void QApplication::beep()
-{
- qt_mac_beep();
-}
-
-void QApplication::alert(QWidget *widget, int duration)
-{
- if (!QApplicationPrivate::checkInstance("alert"))
- return;
-
- QWidgetList windowsToMark;
- if (!widget)
- windowsToMark += topLevelWidgets();
- else
- windowsToMark.append(widget->window());
-
- bool needNotification = false;
- for (int i = 0; i < windowsToMark.size(); ++i) {
- QWidget *window = windowsToMark.at(i);
- if (!window->isActiveWindow() && window->isVisible()) {
- needNotification = true; // yeah, we may set it multiple times, but that's OK.
- if (duration != 0) {
- QTimer *timer = new QTimer(qApp);
- timer->setSingleShot(true);
- connect(timer, SIGNAL(timeout()), qApp, SLOT(_q_alertTimeOut()));
- if (QTimer *oldTimer = qApp->d_func()->alertTimerHash.value(widget)) {
- qApp->d_func()->alertTimerHash.remove(widget);
- delete oldTimer;
- }
- qApp->d_func()->alertTimerHash.insert(widget, timer);
- timer->start(duration);
- }
- }
- }
- if (needNotification)
- qt_mac_send_notification();
-}
-
-void QApplicationPrivate::_q_alertTimeOut()
-{
- if (QTimer *timer = qobject_cast<QTimer *>(q_func()->sender())) {
- QHash<QWidget *, QTimer *>::iterator it = alertTimerHash.begin();
- while (it != alertTimerHash.end()) {
- if (it.value() == timer) {
- alertTimerHash.erase(it);
- timer->deleteLater();
- break;
- }
- ++it;
- }
- if (alertTimerHash.isEmpty()) {
- qt_mac_cancel_notification();
- }
- }
-}
-
-void QApplication::setCursorFlashTime(int msecs)
-{
- QApplicationPrivate::cursor_flash_time = msecs;
-}
-
-int QApplication::cursorFlashTime()
-{
- return QApplicationPrivate::cursor_flash_time;
-}
-
-void QApplication::setDoubleClickInterval(int ms)
-{
- qt_mac_dblclick.use_qt_time_limit = true;
- QApplicationPrivate::mouse_double_click_time = ms;
-}
-
-int QApplication::doubleClickInterval()
-{
- if (!qt_mac_dblclick.use_qt_time_limit) { //get it from the system
- QSettings appleSettings(QLatin1String("apple.com"));
- /* First worked as of 10.3.3 */
- double dci = appleSettings.value(QLatin1String("com/apple/mouse/doubleClickThreshold"), 0.5).toDouble();
- return int(dci * 1000);
- }
- return QApplicationPrivate::mouse_double_click_time;
-}
-
-void QApplication::setKeyboardInputInterval(int ms)
-{
- QApplicationPrivate::keyboard_input_time = ms;
-}
-
-int QApplication::keyboardInputInterval()
-{
- // FIXME: get from the system
- return QApplicationPrivate::keyboard_input_time;
-}
-
-#ifndef QT_NO_WHEELEVENT
-void QApplication::setWheelScrollLines(int n)
-{
- QApplicationPrivate::wheel_scroll_lines = n;
-}
-
-int QApplication::wheelScrollLines()
-{
- return QApplicationPrivate::wheel_scroll_lines;
-}
-#endif
-
-void QApplication::setEffectEnabled(Qt::UIEffect effect, bool enable)
-{
- switch (effect) {
- case Qt::UI_FadeMenu:
- QApplicationPrivate::fade_menu = enable;
- break;
- case Qt::UI_AnimateMenu:
- QApplicationPrivate::animate_menu = enable;
- break;
- case Qt::UI_FadeTooltip:
- QApplicationPrivate::fade_tooltip = enable;
- break;
- case Qt::UI_AnimateTooltip:
- QApplicationPrivate::animate_tooltip = enable;
- break;
- case Qt::UI_AnimateCombo:
- QApplicationPrivate::animate_combo = enable;
- break;
- case Qt::UI_AnimateToolBox:
- QApplicationPrivate::animate_toolbox = enable;
- break;
- case Qt::UI_General:
- QApplicationPrivate::fade_tooltip = true;
- break;
- default:
- QApplicationPrivate::animate_ui = enable;
- break;
- }
-
- if (enable)
- QApplicationPrivate::animate_ui = true;
-}
-
-bool QApplication::isEffectEnabled(Qt::UIEffect effect)
-{
- if (QColormap::instance().depth() < 16 || !QApplicationPrivate::animate_ui)
- return false;
-
- switch(effect) {
- case Qt::UI_AnimateMenu:
- return QApplicationPrivate::animate_menu;
- case Qt::UI_FadeMenu:
- return QApplicationPrivate::fade_menu;
- case Qt::UI_AnimateCombo:
- return QApplicationPrivate::animate_combo;
- case Qt::UI_AnimateTooltip:
- return QApplicationPrivate::animate_tooltip;
- case Qt::UI_FadeTooltip:
- return QApplicationPrivate::fade_tooltip;
- case Qt::UI_AnimateToolBox:
- return QApplicationPrivate::animate_toolbox;
- default:
- break;
- }
- return QApplicationPrivate::animate_ui;
-}
-
-/*!
- \internal
-*/
-bool QApplicationPrivate::qt_mac_apply_settings()
-{
- QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
- settings.beginGroup(QLatin1String("Qt"));
-
- /*
- Qt settings. This is how they are written into the datastream.
- Palette/ * - QPalette
- font - QFont
- libraryPath - QStringList
- style - QString
- doubleClickInterval - int
- cursorFlashTime - int
- wheelScrollLines - int
- colorSpec - QString
- defaultCodec - QString
- globalStrut/width - int
- globalStrut/height - int
- GUIEffects - QStringList
- Font Substitutions/ * - QStringList
- Font Substitutions/... - QStringList
- */
-
- // read library (ie. plugin) path list
- QString libpathkey =
- QString::fromLatin1("%1.%2/libraryPath")
- .arg(QT_VERSION >> 16)
- .arg((QT_VERSION & 0xff00) >> 8);
- QStringList pathlist = settings.value(libpathkey).toString().split(QLatin1Char(':'));
- if (!pathlist.isEmpty()) {
- QStringList::ConstIterator it = pathlist.begin();
- while(it != pathlist.end())
- QApplication::addLibraryPath(*it++);
- }
-
- QString defaultcodec = settings.value(QLatin1String("defaultCodec"), QVariant(QLatin1String("none"))).toString();
- if (defaultcodec != QLatin1String("none")) {
- QTextCodec *codec = QTextCodec::codecForName(defaultcodec.toLatin1().constData());
- if (codec)
- QTextCodec::setCodecForTr(codec);
- }
-
- if (qt_is_gui_used) {
- QString str;
- QStringList strlist;
- int num;
-
- // read new palette
- int i;
- QPalette pal(QApplication::palette());
- strlist = settings.value(QLatin1String("Palette/active")).toStringList();
- if (strlist.count() == QPalette::NColorRoles) {
- for (i = 0; i < QPalette::NColorRoles; i++)
- pal.setColor(QPalette::Active, (QPalette::ColorRole) i,
- QColor(strlist[i]));
- }
- strlist = settings.value(QLatin1String("Palette/inactive")).toStringList();
- if (strlist.count() == QPalette::NColorRoles) {
- for (i = 0; i < QPalette::NColorRoles; i++)
- pal.setColor(QPalette::Inactive, (QPalette::ColorRole) i,
- QColor(strlist[i]));
- }
- strlist = settings.value(QLatin1String("Palette/disabled")).toStringList();
- if (strlist.count() == QPalette::NColorRoles) {
- for (i = 0; i < QPalette::NColorRoles; i++)
- pal.setColor(QPalette::Disabled, (QPalette::ColorRole) i,
- QColor(strlist[i]));
- }
-
- if (pal != QApplication::palette())
- QApplication::setPalette(pal);
-
- // read new font
- QFont font(QApplication::font());
- str = settings.value(QLatin1String("font")).toString();
- if (!str.isEmpty()) {
- font.fromString(str);
- if (font != QApplication::font())
- QApplication::setFont(font);
- }
-
- // read new QStyle
- QString stylename = settings.value(QLatin1String("style")).toString();
- if (! stylename.isNull() && ! stylename.isEmpty()) {
- QStyle *style = QStyleFactory::create(stylename);
- if (style)
- QApplication::setStyle(style);
- else
- stylename = QLatin1String("default");
- } else {
- stylename = QLatin1String("default");
- }
-
- num = settings.value(QLatin1String("doubleClickInterval"),
- QApplication::doubleClickInterval()).toInt();
- QApplication::setDoubleClickInterval(num);
-
- num = settings.value(QLatin1String("cursorFlashTime"),
- QApplication::cursorFlashTime()).toInt();
- QApplication::setCursorFlashTime(num);
-
-#ifndef QT_NO_WHEELEVENT
- num = settings.value(QLatin1String("wheelScrollLines"),
- QApplication::wheelScrollLines()).toInt();
- QApplication::setWheelScrollLines(num);
-#endif
-
- QString colorspec = settings.value(QLatin1String("colorSpec"),
- QVariant(QLatin1String("default"))).toString();
- if (colorspec == QLatin1String("normal"))
- QApplication::setColorSpec(QApplication::NormalColor);
- else if (colorspec == QLatin1String("custom"))
- QApplication::setColorSpec(QApplication::CustomColor);
- else if (colorspec == QLatin1String("many"))
- QApplication::setColorSpec(QApplication::ManyColor);
- else if (colorspec != QLatin1String("default"))
- colorspec = QLatin1String("default");
-
- int w = settings.value(QLatin1String("globalStrut/width")).toInt();
- int h = settings.value(QLatin1String("globalStrut/height")).toInt();
- QSize strut(w, h);
- if (strut.isValid())
- QApplication::setGlobalStrut(strut);
-
- QStringList effects = settings.value(QLatin1String("GUIEffects")).toStringList();
- if (!effects.isEmpty()) {
- if (effects.contains(QLatin1String("none")))
- QApplication::setEffectEnabled(Qt::UI_General, false);
- if (effects.contains(QLatin1String("general")))
- QApplication::setEffectEnabled(Qt::UI_General, true);
- if (effects.contains(QLatin1String("animatemenu")))
- QApplication::setEffectEnabled(Qt::UI_AnimateMenu, true);
- if (effects.contains(QLatin1String("fademenu")))
- QApplication::setEffectEnabled(Qt::UI_FadeMenu, true);
- if (effects.contains(QLatin1String("animatecombo")))
- QApplication::setEffectEnabled(Qt::UI_AnimateCombo, true);
- if (effects.contains(QLatin1String("animatetooltip")))
- QApplication::setEffectEnabled(Qt::UI_AnimateTooltip, true);
- if (effects.contains(QLatin1String("fadetooltip")))
- QApplication::setEffectEnabled(Qt::UI_FadeTooltip, true);
- if (effects.contains(QLatin1String("animatetoolbox")))
- QApplication::setEffectEnabled(Qt::UI_AnimateToolBox, true);
- } else {
- QApplication::setEffectEnabled(Qt::UI_General, true);
- }
-
- settings.beginGroup(QLatin1String("Font Substitutions"));
- QStringList fontsubs = settings.childKeys();
- if (!fontsubs.isEmpty()) {
- QStringList::Iterator it = fontsubs.begin();
- for (; it != fontsubs.end(); ++it) {
- QString fam = QString::fromLatin1((*it).toLatin1().constData());
- QStringList subs = settings.value(fam).toStringList();
- QFont::insertSubstitutions(fam, subs);
- }
- }
- settings.endGroup();
- }
-
- settings.endGroup();
- return true;
-}
-
-// DRSWAT
-
-bool QApplicationPrivate::canQuit()
-{
-#ifndef QT_MAC_USE_COCOA
- return true;
-#else
- Q_Q(QApplication);
-#ifdef QT_MAC_USE_COCOA
- [[NSApp mainMenu] cancelTracking];
-#else
- HiliteMenu(0);
-#endif
-
- bool handle_quit = true;
- if (QApplicationPrivate::modalState() && [[[[QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) sharedDelegate]
- menuLoader] quitMenuItem] isEnabled]) {
- int visible = 0;
- const QWidgetList tlws = QApplication::topLevelWidgets();
- for(int i = 0; i < tlws.size(); ++i) {
- if (tlws.at(i)->isVisible())
- ++visible;
- }
- handle_quit = (visible <= 1);
- }
- if (handle_quit) {
- QCloseEvent ev;
- QApplication::sendSpontaneousEvent(q, &ev);
- if (ev.isAccepted()) {
- return true;
- }
- }
- return false;
-#endif
-}
-
-void onApplicationWindowChangedActivation(QWidget *widget, bool activated)
-{
-#if QT_MAC_USE_COCOA
- if (!widget)
- return;
-
- if (activated) {
- if (QApplicationPrivate::app_style) {
- QEvent ev(QEvent::Style);
- qt_sendSpontaneousEvent(QApplicationPrivate::app_style, &ev);
- }
- qApp->setActiveWindow(widget);
- } else { // deactivated
- if (QApplicationPrivate::active_window == widget)
- qApp->setActiveWindow(0);
- }
-
- QMenuBar::macUpdateMenuBar();
- qt_mac_update_cursor();
-#else
- Q_UNUSED(widget);
- Q_UNUSED(activated);
-#endif
-}
-
-
-void onApplicationChangedActivation( bool activated )
-{
-#if QT_MAC_USE_COCOA
- QApplication *app = qApp;
-
-//NSLog(@"App Changed Activation\n");
-
- if ( activated ) {
- if (QApplication::desktopSettingsAware())
- qt_mac_update_os_settings();
-
- if (qt_clipboard) { //manufacture an event so the clipboard can see if it has changed
- QEvent ev(QEvent::Clipboard);
- qt_sendSpontaneousEvent(qt_clipboard, &ev);
- }
-
- if (app) {
- QEvent ev(QEvent::ApplicationActivate);
- qt_sendSpontaneousEvent(app, &ev);
- }
-
- if (!app->activeWindow()) {
- OSWindowRef wp = [NSApp keyWindow];
- if (QWidget *tmp_w = qt_mac_find_window(wp))
- app->setActiveWindow(tmp_w);
- }
- QMenuBar::macUpdateMenuBar();
- qt_mac_update_cursor();
- } else { // de-activated
- QApplicationPrivate *priv = [[QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) sharedDelegate] qAppPrivate];
- while (priv->inPopupMode())
- app->activePopupWidget()->close();
- if (app) {
- QEvent ev(QEvent::ApplicationDeactivate);
- qt_sendSpontaneousEvent(app, &ev);
- }
- app->setActiveWindow(0);
- }
-#else
- Q_UNUSED(activated);
-#endif
-}
-
-void QApplicationPrivate::initializeMultitouch_sys()
-{ }
-void QApplicationPrivate::cleanupMultitouch_sys()
-{ }
-
-QT_END_NAMESPACE
diff --git a/src/gui/kernel/qapplication_p.h b/src/gui/kernel/qapplication_p.h
deleted file mode 100644
index e1252a9589..0000000000
--- a/src/gui/kernel/qapplication_p.h
+++ /dev/null
@@ -1,683 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QAPPLICATION_P_H
-#define QAPPLICATION_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of qapplication_*.cpp, qwidget*.cpp, qcolor_x11.cpp, qfiledialog.cpp
-// and many other. This header file may change from version to version
-// without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "QtGui/qapplication.h"
-#include "QtGui/qevent.h"
-#include "QtGui/qfont.h"
-#include "QtGui/qcursor.h"
-#include "QtGui/qregion.h"
-#include "QtCore/qmutex.h"
-#include "QtCore/qtranslator.h"
-#include "QtCore/qbasictimer.h"
-#include "QtCore/qhash.h"
-#include "QtCore/qpointer.h"
-#include "private/qcoreapplication_p.h"
-#include "QtGui/private/qshortcutmap_p.h"
-#include <private/qthread_p.h>
-#include "QtCore/qpoint.h"
-#include <QTime>
-#ifdef Q_WS_QWS
-#include "QtGui/qscreen_qws.h"
-#include <private/qgraphicssystem_qws_p.h>
-#endif
-#ifdef Q_OS_SYMBIAN
-#include <w32std.h>
-#endif
-#ifdef Q_WS_QPA
-#include <QWindowSystemInterface>
-#include "qwindowsysteminterface_qpa_p.h"
-#include "QtGui/qplatformintegration_qpa.h"
-#endif
-
-QT_BEGIN_NAMESPACE
-
-class QClipboard;
-class QGraphicsScene;
-class QGraphicsSystem;
-class QInputContext;
-class QObject;
-class QWidget;
-class QSocketNotifier;
-#ifndef QT_NO_GESTURES
-class QGestureManager;
-#endif
-
-extern bool qt_is_gui_used;
-#ifndef QT_NO_CLIPBOARD
-extern QClipboard *qt_clipboard;
-#endif
-
-#if defined (Q_OS_WIN32) || defined (Q_OS_CYGWIN) || defined(Q_OS_WINCE)
-extern QSysInfo::WinVersion qt_winver;
-enum { QT_TABLET_NPACKETQSIZE = 128 };
-# ifdef Q_OS_WINCE
- extern DWORD qt_cever;
-# endif
-#elif defined (Q_OS_MAC)
-extern QSysInfo::MacVersion qt_macver;
-#endif
-#if defined(Q_WS_QWS)
-class QWSManager;
-class QDirectPainter;
-struct QWSServerCleaner { ~QWSServerCleaner(); };
-#endif
-
-#ifndef QT_NO_TABLET
-struct QTabletDeviceData
-{
-#ifndef Q_WS_MAC
- int minPressure;
- int maxPressure;
- int minTanPressure;
- int maxTanPressure;
- int minX, maxX, minY, maxY, minZ, maxZ;
- inline QPointF scaleCoord(int coordX, int coordY, int outOriginX, int outExtentX,
- int outOriginY, int outExtentY) const;
-#endif
-
-#if defined(Q_WS_X11) || (defined(Q_WS_MAC) && !defined(QT_MAC_USE_COCOA))
- QPointer<QWidget> widgetToGetPress;
-#endif
-
-#ifdef Q_WS_X11
- int deviceType;
- enum {
- TOTAL_XINPUT_EVENTS = 64
- };
- void *device;
- int eventCount;
- long unsigned int eventList[TOTAL_XINPUT_EVENTS]; // XEventClass is in fact a long unsigned int
-
- int xinput_motion;
- int xinput_key_press;
- int xinput_key_release;
- int xinput_button_press;
- int xinput_button_release;
- int xinput_proximity_in;
- int xinput_proximity_out;
-#elif defined(Q_WS_WIN)
- qint64 llId;
- int currentDevice;
- int currentPointerType;
-#elif defined(Q_WS_MAC)
- quint64 tabletUniqueID;
- int tabletDeviceType;
- int tabletPointerType;
- int capabilityMask;
-#endif
-};
-
-static inline int sign(int x)
-{
- return x >= 0 ? 1 : -1;
-}
-
-#ifndef Q_WS_MAC
-inline QPointF QTabletDeviceData::scaleCoord(int coordX, int coordY,
- int outOriginX, int outExtentX,
- int outOriginY, int outExtentY) const
-{
- QPointF ret;
-
- if (sign(outExtentX) == sign(maxX))
- ret.setX(((coordX - minX) * qAbs(outExtentX) / qAbs(qreal(maxX - minX))) + outOriginX);
- else
- ret.setX(((qAbs(maxX) - (coordX - minX)) * qAbs(outExtentX) / qAbs(qreal(maxX - minX)))
- + outOriginX);
-
- if (sign(outExtentY) == sign(maxY))
- ret.setY(((coordY - minY) * qAbs(outExtentY) / qAbs(qreal(maxY - minY))) + outOriginY);
- else
- ret.setY(((qAbs(maxY) - (coordY - minY)) * qAbs(outExtentY) / qAbs(qreal(maxY - minY)))
- + outOriginY);
-
- return ret;
-}
-#endif
-
-typedef QList<QTabletDeviceData> QTabletDeviceDataList;
-QTabletDeviceDataList *qt_tablet_devices();
-# if defined(Q_WS_MAC)
-typedef QHash<int, QTabletDeviceData> QMacTabletHash;
-QMacTabletHash *qt_mac_tablet_hash();
-# endif
-#endif
-
-#ifdef QT3_SUPPORT
-extern "C" {
- typedef bool (*Ptrqt_tryAccelEvent)(QWidget *w, QKeyEvent *e);
- typedef bool (*Ptrqt_tryComposeUnicode)(QWidget *w, QKeyEvent *e);
- typedef bool (*Ptrqt_dispatchAccelEvent)(QWidget *w, QKeyEvent *e);
-}
-#endif
-
-#if defined(Q_WS_WIN)
-typedef BOOL (WINAPI *PtrRegisterTouchWindow)(HWND, ULONG);
-typedef BOOL (WINAPI *PtrGetTouchInputInfo)(HANDLE, UINT, PVOID, int);
-typedef BOOL (WINAPI *PtrCloseTouchInputHandle)(HANDLE);
-
-#ifndef QT_NO_GESTURES
-typedef BOOL (WINAPI *PtrGetGestureInfo)(HANDLE, PVOID);
-typedef BOOL (WINAPI *PtrGetGestureExtraArgs)(HANDLE, UINT, PBYTE);
-typedef BOOL (WINAPI *PtrCloseGestureInfoHandle)(HANDLE);
-typedef BOOL (WINAPI *PtrSetGestureConfig)(HWND, DWORD, UINT, PVOID, UINT);
-typedef BOOL (WINAPI *PtrGetGestureConfig)(HWND, DWORD, DWORD, PUINT, PVOID, UINT);
-
-typedef BOOL (WINAPI *PtrBeginPanningFeedback)(HWND);
-typedef BOOL (WINAPI *PtrUpdatePanningFeedback)(HWND, LONG, LONG, BOOL);
-typedef BOOL (WINAPI *PtrEndPanningFeedback)(HWND, BOOL);
-
-#ifndef WM_GESTURE
-# define WM_GESTURE 0x0119
-
-# define GID_BEGIN 1
-# define GID_END 2
-# define GID_ZOOM 3
-# define GID_PAN 4
-# define GID_ROTATE 5
-# define GID_TWOFINGERTAP 6
-# define GID_ROLLOVER 7
-
-typedef struct tagGESTUREINFO
-{
- UINT cbSize;
- DWORD dwFlags;
- DWORD dwID;
- HWND hwndTarget;
- POINTS ptsLocation;
- DWORD dwInstanceID;
- DWORD dwSequenceID;
- ULONGLONG ullArguments;
- UINT cbExtraArgs;
-} GESTUREINFO;
-
-# define GC_PAN 0x00000001
-# define GC_PAN_WITH_SINGLE_FINGER_VERTICALLY 0x00000002
-# define GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY 0x00000004
-
-# define GC_ZOOM 0x00000001
-# define GC_ROTATE 0x00000001
-
-typedef struct tagGESTURECONFIG
-{
- DWORD dwID;
- DWORD dwWant;
- DWORD dwBlock;
-} GESTURECONFIG;
-
-# define GID_ROTATE_ANGLE_FROM_ARGUMENT(arg) ((((double)(arg) / 65535.0) * 4.0 * 3.14159265) - 2.0*3.14159265)
-
-#endif // WM_GESTURE
-
-#if defined(Q_WS_WINCE_WM) && defined(QT_WINCE_GESTURES)
-#undef GID_ZOOM
-#define GID_ZOOM 0xf000
-#undef GID_ROTATE
-#define GID_ROTATE 0xf001
-#undef GID_TWOFINGERTAP
-#define GID_TWOFINGERTAP 0xf002
-#undef GID_ROLLOVER
-#define GID_ROLLOVER 0xf003
-#endif
-
-#endif // QT_NO_GESTURES
-
-#endif // Q_WS_WIN
-
-class QScopedLoopLevelCounter
-{
- QThreadData *threadData;
-public:
- QScopedLoopLevelCounter(QThreadData *threadData)
- : threadData(threadData)
- { ++threadData->loopLevel; }
- ~QScopedLoopLevelCounter()
- { --threadData->loopLevel; }
-};
-
-typedef QHash<QByteArray, QFont> FontHash;
-FontHash *qt_app_fonts_hash();
-
-typedef QHash<QByteArray, QPalette> PaletteHash;
-PaletteHash *qt_app_palettes_hash();
-
-class Q_GUI_EXPORT QApplicationPrivate : public QCoreApplicationPrivate
-{
- Q_DECLARE_PUBLIC(QApplication)
-public:
- QApplicationPrivate(int &argc, char **argv, QApplication::Type type, int flags);
- ~QApplicationPrivate();
-
-#if defined(Q_WS_X11)
-#ifndef QT_NO_SETTINGS
- static bool x11_apply_settings();
-#endif
- static void reset_instance_pointer();
-#elif defined(Q_WS_QWS)
- static bool qws_apply_settings();
- static QWidget *findWidget(const QObjectList&, const QPoint &, bool rec);
-#endif
- static bool quitOnLastWindowClosed;
- static void emitLastWindowClosed();
-#ifdef Q_WS_WINCE
- static int autoMaximizeThreshold;
-#endif
- static bool autoSipEnabled;
- static QString desktopStyleKey();
-
- static QGraphicsSystem *graphicsSystem()
-#if defined(Q_WS_QWS)
- { return QScreen::instance()->graphicsSystem(); }
-#else
- { return graphics_system; }
-#endif
-
-#if defined(Q_WS_QPA)
- static QPlatformIntegration *platformIntegration()
- { return platform_integration; }
-
- static QAbstractEventDispatcher *qt_qpa_core_dispatcher()
- { return QCoreApplication::instance()->d_func()->threadData->eventDispatcher; }
-#endif
-
- void createEventDispatcher();
- QString appName() const;
- static void dispatchEnterLeave(QWidget *enter, QWidget *leave);
-
- //modality
- static void enterModal(QWidget*);
- static void leaveModal(QWidget*);
- static void enterModal_sys(QWidget*);
- static void leaveModal_sys(QWidget*);
- static bool isBlockedByModal(QWidget *widget);
- static bool modalState();
- static bool tryModalHelper(QWidget *widget, QWidget **rettop = 0);
-#ifdef Q_WS_MAC
- static QWidget *tryModalHelper_sys(QWidget *top);
- bool canQuit();
-#endif
-
- bool notify_helper(QObject *receiver, QEvent * e);
-
- void construct(
-#ifdef Q_WS_X11
- Display *dpy = 0, Qt::HANDLE visual = 0, Qt::HANDLE cmap = 0
-#endif
- );
- void initialize();
- void process_cmdline();
-
-#if defined(Q_WS_X11)
- static void x11_initialize_style();
-#endif
-
- enum KeyPlatform {
- KB_Win = 1,
- KB_Mac = 2,
- KB_X11 = 4,
- KB_KDE = 8,
- KB_Gnome = 16,
- KB_CDE = 32,
- KB_S60 = 64,
- KB_All = 0xffff
- };
-
- static uint currentPlatform();
- bool inPopupMode() const;
- void closePopup(QWidget *popup);
- void openPopup(QWidget *popup);
- static void setFocusWidget(QWidget *focus, Qt::FocusReason reason);
- static QWidget *focusNextPrevChild_helper(QWidget *toplevel, bool next);
-
-#ifndef QT_NO_SESSIONMANAGER
- QSessionManager *session_manager;
- QString session_id;
- QString session_key;
- bool is_session_restored;
-#endif
-
-#ifndef QT_NO_CURSOR
- QList<QCursor> cursor_list;
-#endif
-#ifndef QT_NO_GRAPHICSVIEW
- // Maintain a list of all scenes to ensure font and palette propagation to
- // all scenes.
- QList<QGraphicsScene *> scene_list;
-#endif
-
- QBasicTimer toolTipWakeUp, toolTipFallAsleep;
- QPoint toolTipPos, toolTipGlobalPos, hoverGlobalPos;
- QPointer<QWidget> toolTipWidget;
-#ifndef QT_NO_SHORTCUT
- QShortcutMap shortcutMap;
-#endif
-
-#ifdef QT3_SUPPORT
- bool qt_compat_used;
- bool qt_compat_resolved;
- Ptrqt_tryAccelEvent qt_tryAccelEvent;
- Ptrqt_tryComposeUnicode qt_tryComposeUnicode;
- Ptrqt_dispatchAccelEvent qt_dispatchAccelEvent;
-
- bool use_compat() {
- return qt_tryAccelEvent
- && qt_tryComposeUnicode
- && qt_dispatchAccelEvent;
- }
-#endif
- static QInputContext *inputContext;
-
- static Qt::MouseButtons mouse_buttons;
- static Qt::KeyboardModifiers modifier_buttons;
-
- static QSize app_strut;
- static QWidgetList *popupWidgets;
- static QStyle *app_style;
- static int app_cspec;
- static QPalette *app_pal;
- static QPalette *sys_pal;
- static QPalette *set_pal;
- static QGraphicsSystem *graphics_system;
- static QString graphics_system_name;
- static bool runtime_graphics_system;
-#ifdef Q_WS_QPA
- static QPlatformIntegration *platform_integration;
-#endif
-
-private:
- static QFont *app_font; // private for a reason! Always use QApplication::font() instead!
-public:
- static QFont *sys_font;
- static QFont *set_font;
- static QWidget *main_widget;
- static QWidget *focus_widget;
- static QWidget *hidden_focus_widget;
- static QWidget *active_window;
- static QIcon *app_icon;
- static bool obey_desktop_settings;
- static int cursor_flash_time;
- static int mouse_double_click_time;
- static int keyboard_input_time;
-#ifndef QT_NO_WHEELEVENT
- static int wheel_scroll_lines;
-#endif
-
- static bool animate_ui;
- static bool animate_menu;
- static bool animate_tooltip;
- static bool animate_combo;
- static bool fade_menu;
- static bool fade_tooltip;
- static bool animate_toolbox;
- static bool widgetCount; // Coupled with -widgetcount switch
- static bool load_testability; // Coupled with -testability switch
- static QString qmljs_debug_arguments; // a string containing arguments for js/qml debugging.
- static QString qmljsDebugArgumentsString(); // access string from other libraries
-
-#ifdef Q_WS_MAC
- static bool native_modal_dialog_active;
-#endif
-
- static void setSystemPalette(const QPalette &pal);
- static void setPalette_helper(const QPalette &palette, const char* className, bool clearWidgetPaletteHash);
- static void initializeWidgetPaletteHash();
- static void setSystemFont(const QFont &font);
-
-#if defined(Q_WS_X11)
- static void applyX11SpecificCommandLineArguments(QWidget *main_widget);
-#elif defined(Q_WS_QWS)
- static void applyQWSSpecificCommandLineArguments(QWidget *main_widget);
-#endif
-
-#ifdef Q_WS_MAC
- static OSStatus globalEventProcessor(EventHandlerCallRef, EventRef, void *);
- static OSStatus globalAppleEventProcessor(const AppleEvent *, AppleEvent *, long);
- static OSStatus tabletProximityCallback(EventHandlerCallRef, EventRef, void *);
-#ifdef QT_MAC_USE_COCOA
- static void qt_initAfterNSAppStarted();
- static void setupAppleEvents();
-#endif
- static bool qt_mac_apply_settings();
-#endif
-
-#ifdef Q_WS_QPA
- static void processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent *e);
- static void processKeyEvent(QWindowSystemInterfacePrivate::KeyEvent *e);
- static void processWheelEvent(QWindowSystemInterfacePrivate::WheelEvent *e);
- static void processTouchEvent(QWindowSystemInterfacePrivate::TouchEvent *e);
-
- static void processCloseEvent(QWindowSystemInterfacePrivate::CloseEvent *e);
-
- static void processGeometryChangeEvent(QWindowSystemInterfacePrivate::GeometryChangeEvent *e);
-
- static void processEnterEvent(QWindowSystemInterfacePrivate::EnterEvent *e);
- static void processLeaveEvent(QWindowSystemInterfacePrivate::LeaveEvent *e);
-
- static void processActivatedEvent(QWindowSystemInterfacePrivate::ActivatedWindowEvent *e);
-
- static void processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *e);
-
-// static void reportScreenCount(int count);
- static void reportScreenCount(QWindowSystemInterfacePrivate::ScreenCountEvent *e);
-// static void reportGeometryChange(int screenIndex);
- static void reportGeometryChange(QWindowSystemInterfacePrivate::ScreenGeometryEvent *e);
-// static void reportAvailableGeometryChange(int screenIndex);
- static void reportAvailableGeometryChange(QWindowSystemInterfacePrivate::ScreenAvailableGeometryEvent *e);
-
-#endif
-
-#ifdef Q_WS_QWS
- QPointer<QWSManager> last_manager;
- QWSServerCleaner qwsServerCleaner;
-# ifndef QT_NO_DIRECTPAINTER
- QMap<WId, QDirectPainter *> *directPainters;
-# endif
- QRect maxWindowRect(const QScreen *screen) const { return maxWindowRects[screen]; }
- void setMaxWindowRect(const QScreen *screen, int screenNo, const QRect &rect);
- void setScreenTransformation(QScreen *screen, int screenNo, int transformation);
-#endif
-
- static QApplicationPrivate *instance() { return self; }
-
- static QString styleOverride;
-
-#ifdef QT_KEYPAD_NAVIGATION
- static QWidget *oldEditFocus;
- static Qt::NavigationMode navigationMode;
-#endif
-
-#if defined(Q_WS_MAC) || defined(Q_WS_X11)
- void _q_alertTimeOut();
- QHash<QWidget *, QTimer *> alertTimerHash;
-#endif
-#ifndef QT_NO_STYLE_STYLESHEET
- static QString styleSheet;
-#endif
- static QPointer<QWidget> leaveAfterRelease;
- static QWidget *pickMouseReceiver(QWidget *candidate, const QPoint &globalPos, QPoint &pos,
- QEvent::Type type, Qt::MouseButtons buttons,
- QWidget *buttonDown, QWidget *alienWidget);
- static bool sendMouseEvent(QWidget *receiver, QMouseEvent *event, QWidget *alienWidget,
- QWidget *native, QWidget **buttonDown, QPointer<QWidget> &lastMouseReceiver,
- bool spontaneous = true);
-#ifdef Q_OS_SYMBIAN
- static void setNavigationMode(Qt::NavigationMode mode);
- static TUint resolveS60ScanCode(TInt scanCode, TUint keysym);
- QSet<WId> nativeWindows;
-
- int symbianProcessWsEvent(const QSymbianEvent *symbianEvent);
- int symbianHandleCommand(const QSymbianEvent *symbianEvent);
- int symbianResourceChange(const QSymbianEvent *symbianEvent);
-
- void _q_aboutToQuit();
-#endif
-#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) || defined(Q_WS_MAC) || defined(Q_WS_QPA)
- void sendSyntheticEnterLeave(QWidget *widget);
-#endif
-
-#ifndef QT_NO_GESTURES
- QGestureManager *gestureManager;
- QWidget *gestureWidget;
-#endif
-#if defined(Q_WS_X11) || defined(Q_WS_WIN)
- QPixmap *move_cursor;
- QPixmap *copy_cursor;
- QPixmap *link_cursor;
-#endif
-#if defined(Q_WS_WIN)
- QPixmap *ignore_cursor;
-#endif
- QPixmap getPixmapCursor(Qt::CursorShape cshape);
-
- QMap<int, QWeakPointer<QWidget> > widgetForTouchPointId;
- QMap<int, QTouchEvent::TouchPoint> appCurrentTouchPoints;
- static void updateTouchPointsForWidget(QWidget *widget, QTouchEvent *touchEvent);
- void initializeMultitouch();
- void initializeMultitouch_sys();
- void cleanupMultitouch();
- void cleanupMultitouch_sys();
- int findClosestTouchPointId(const QPointF &screenPos);
- void appendTouchPoint(const QTouchEvent::TouchPoint &touchPoint);
- void removeTouchPoint(int touchPointId);
- static void translateRawTouchEvent(QWidget *widget,
- QTouchEvent::DeviceType deviceType,
- const QList<QTouchEvent::TouchPoint> &touchPoints);
-
-#if defined(Q_WS_WIN)
- static bool HasTouchSupport;
- static PtrRegisterTouchWindow RegisterTouchWindow;
- static PtrGetTouchInputInfo GetTouchInputInfo;
- static PtrCloseTouchInputHandle CloseTouchInputHandle;
-
- QHash<DWORD, int> touchInputIDToTouchPointID;
- bool translateTouchEvent(const MSG &msg);
-
-#ifndef QT_NO_GESTURES
- PtrGetGestureInfo GetGestureInfo;
- PtrGetGestureExtraArgs GetGestureExtraArgs;
- PtrCloseGestureInfoHandle CloseGestureInfoHandle;
- PtrSetGestureConfig SetGestureConfig;
- PtrGetGestureConfig GetGestureConfig;
- PtrBeginPanningFeedback BeginPanningFeedback;
- PtrUpdatePanningFeedback UpdatePanningFeedback;
- PtrEndPanningFeedback EndPanningFeedback;
-#endif // QT_NO_GESTURES
-#endif
-
-#ifdef QT_RX71_MULTITOUCH
- bool hasRX71MultiTouch;
-
- struct RX71TouchPointState {
- QSocketNotifier *socketNotifier;
- QTouchEvent::TouchPoint touchPoint;
-
- int minX, maxX, scaleX;
- int minY, maxY, scaleY;
- int minZ, maxZ;
- };
- QList<RX71TouchPointState> allRX71TouchPoints;
-
- bool readRX71MultiTouchEvents(int deviceNumber);
- void fakeMouseEventFromRX71TouchEvent();
- void _q_readRX71MultiTouchEvents();
-#endif
-
-#if defined(Q_OS_SYMBIAN)
- int pressureSupported;
- int maxTouchPressure;
- QList<QTouchEvent::TouchPoint> appAllTouchPoints;
-
- bool useTranslucentEGLSurfaces;
-#endif
-
-private:
-#ifdef Q_WS_QWS
- QMap<const QScreen*, QRect> maxWindowRects;
-#endif
-
-#ifdef Q_OS_SYMBIAN
- QHash<TInt, TUint> scanCodeCache;
-#endif
-
- static QApplicationPrivate *self;
-
- static void giveFocusAccordingToFocusPolicy(QWidget *w,
- Qt::FocusPolicy focusPolicy,
- Qt::FocusReason focusReason);
- static bool shouldSetFocus(QWidget *w, Qt::FocusPolicy policy);
-
-
- static bool isAlien(QWidget *);
-};
-
-Q_GUI_EXPORT void qt_translateRawTouchEvent(QWidget *window,
- QTouchEvent::DeviceType deviceType,
- const QList<QTouchEvent::TouchPoint> &touchPoints);
-
-#if defined(Q_WS_WIN)
- extern void qt_win_set_cursor(QWidget *, bool);
-#elif defined(Q_WS_X11)
- extern void qt_x11_enforce_cursor(QWidget *, bool);
- extern void qt_x11_enforce_cursor(QWidget *);
-#elif defined(Q_OS_SYMBIAN)
- extern void qt_symbian_set_cursor(QWidget *, bool);
-#elif defined (Q_WS_QPA)
- extern void qt_qpa_set_cursor(QWidget *, bool);
-#endif
-
-QT_END_NAMESPACE
-
-#endif // QAPPLICATION_P_H
diff --git a/src/gui/kernel/qapplication_qpa.cpp b/src/gui/kernel/qapplication_qpa.cpp
deleted file mode 100644
index dfac850716..0000000000
--- a/src/gui/kernel/qapplication_qpa.cpp
+++ /dev/null
@@ -1,968 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qapplication_p.h"
-#include "qcolormap.h"
-#include "qpixmapcache.h"
-#if !defined(QT_NO_GLIB)
-#include "qeventdispatcher_glib_qpa_p.h"
-#endif
-#include "qeventdispatcher_qpa_p.h"
-#ifndef QT_NO_CURSOR
-#include "private/qcursor_p.h"
-#endif
-
-#include "private/qwidget_p.h"
-#include "private/qevent_p.h"
-
-#include "qgenericpluginfactory_qpa.h"
-#include "qplatformintegrationfactory_qpa_p.h"
-#include <qdesktopwidget.h>
-
-#include <qinputcontext.h>
-#include <QPlatformCursor>
-#include <qdebug.h>
-#include <QWindowSystemInterface>
-#include "qwindowsysteminterface_qpa_p.h"
-#include <QPlatformIntegration>
-
-#include "qdesktopwidget_qpa_p.h"
-
-QT_BEGIN_NAMESPACE
-
-static QString appName;
-static QString appFont;
-
-QWidget *qt_button_down = 0; // widget got last button-down
-
-static bool app_do_modal = false;
-extern QWidgetList *qt_modal_stack; // stack of modal widgets
-
-qreal qt_last_x = 0;
-qreal qt_last_y = 0;
-QPointer<QWidget> qt_last_mouse_receiver = 0;
-
-static Qt::MouseButtons buttons = Qt::NoButton;
-static ulong mousePressTime;
-static Qt::MouseButton mousePressButton = Qt::NoButton;
-static int mousePressX;
-static int mousePressY;
-static int mouse_double_click_distance = 5;
-
-void QApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *e)
-{
- switch(e->type) {
- case QWindowSystemInterfacePrivate::Mouse:
- QApplicationPrivate::processMouseEvent(static_cast<QWindowSystemInterfacePrivate::MouseEvent *>(e));
- break;
- case QWindowSystemInterfacePrivate::Wheel:
- QApplicationPrivate::processWheelEvent(static_cast<QWindowSystemInterfacePrivate::WheelEvent *>(e));
- break;
- case QWindowSystemInterfacePrivate::Key:
- QApplicationPrivate::processKeyEvent(static_cast<QWindowSystemInterfacePrivate::KeyEvent *>(e));
- break;
- case QWindowSystemInterfacePrivate::Touch:
- QApplicationPrivate::processTouchEvent(static_cast<QWindowSystemInterfacePrivate::TouchEvent *>(e));
- break;
- case QWindowSystemInterfacePrivate::GeometryChange:
- QApplicationPrivate::processGeometryChangeEvent(static_cast<QWindowSystemInterfacePrivate::GeometryChangeEvent*>(e));
- break;
- case QWindowSystemInterfacePrivate::Enter:
- QApplicationPrivate::processEnterEvent(static_cast<QWindowSystemInterfacePrivate::EnterEvent *>(e));
- break;
- case QWindowSystemInterfacePrivate::Leave:
- QApplicationPrivate::processLeaveEvent(static_cast<QWindowSystemInterfacePrivate::LeaveEvent *>(e));
- break;
- case QWindowSystemInterfacePrivate::ActivatedWindow:
- QApplicationPrivate::processActivatedEvent(static_cast<QWindowSystemInterfacePrivate::ActivatedWindowEvent *>(e));
- break;
- case QWindowSystemInterfacePrivate::Close:
- QApplicationPrivate::processCloseEvent(
- static_cast<QWindowSystemInterfacePrivate::CloseEvent *>(e));
- break;
- case QWindowSystemInterfacePrivate::ScreenCountChange:
- QApplicationPrivate::reportScreenCount(
- static_cast<QWindowSystemInterfacePrivate::ScreenCountEvent *>(e));
- break;
- case QWindowSystemInterfacePrivate::ScreenGeometry:
- QApplicationPrivate::reportGeometryChange(
- static_cast<QWindowSystemInterfacePrivate::ScreenGeometryEvent *>(e));
- break;
- case QWindowSystemInterfacePrivate::ScreenAvailableGeometry:
- QApplicationPrivate::reportAvailableGeometryChange(
- static_cast<QWindowSystemInterfacePrivate::ScreenAvailableGeometryEvent *>(e));
- break;
- default:
- qWarning() << "Unknown user input event type:" << e->type;
- break;
- }
-}
-
-QString QApplicationPrivate::appName() const
-{
- return QT_PREPEND_NAMESPACE(appName);
-}
-
-void QApplicationPrivate::createEventDispatcher()
-{
- Q_Q(QApplication);
-#if !defined(QT_NO_GLIB)
- if (qgetenv("QT_NO_GLIB").isEmpty() && QEventDispatcherGlib::versionSupported())
- eventDispatcher = new QPAEventDispatcherGlib(q);
- else
-#endif
- eventDispatcher = new QEventDispatcherQPA(q);
-}
-
-static bool qt_try_modal(QWidget *widget, QEvent::Type type)
-{
- QWidget * top = 0;
-
- if (QApplicationPrivate::tryModalHelper(widget, &top))
- return true;
-
- bool block_event = false;
- bool paint_event = false;
-
- switch (type) {
-#if 0
- case QEvent::Focus:
- if (!static_cast<QWSFocusEvent*>(event)->simpleData.get_focus)
- break;
- // drop through
-#endif
- case QEvent::MouseButtonPress: // disallow mouse/key events
- case QEvent::MouseButtonRelease:
- case QEvent::MouseMove:
- case QEvent::KeyPress:
- case QEvent::KeyRelease:
- block_event = true;
- break;
- default:
- break;
- }
-
- if ((block_event || paint_event) && top->parentWidget() == 0)
- top->raise();
-
- return !block_event;
-}
-
-
-
-void QApplicationPrivate::enterModal_sys(QWidget *widget)
-{
- if (!qt_modal_stack)
- qt_modal_stack = new QWidgetList;
- qt_modal_stack->insert(0, widget);
- app_do_modal = true;
-}
-
-void QApplicationPrivate::leaveModal_sys(QWidget *widget )
-{
- if (qt_modal_stack && qt_modal_stack->removeAll(widget)) {
- if (qt_modal_stack->isEmpty()) {
- delete qt_modal_stack;
- qt_modal_stack = 0;
- }
- }
- app_do_modal = qt_modal_stack != 0;
-}
-
-bool QApplicationPrivate::modalState()
-{
- return app_do_modal;
-}
-
-void QApplicationPrivate::closePopup(QWidget *popup)
-{
- Q_Q(QApplication);
- if (!popupWidgets)
- return;
- popupWidgets->removeAll(popup);
-
-//###
-// if (popup == qt_popup_down) {
-// qt_button_down = 0;
-// qt_popup_down = 0;
-// }
-
- if (QApplicationPrivate::popupWidgets->count() == 0) { // this was the last popup
- delete QApplicationPrivate::popupWidgets;
- QApplicationPrivate::popupWidgets = 0;
-
- //### replay mouse event?
-
- //### transfer/release mouse grab
-
- //### transfer/release keyboard grab
-
- //give back focus
-
- if (active_window) {
- if (QWidget *fw = active_window->focusWidget()) {
- if (fw != QApplication::focusWidget()) {
- fw->setFocus(Qt::PopupFocusReason);
- } else {
- QFocusEvent e(QEvent::FocusIn, Qt::PopupFocusReason);
- q->sendEvent(fw, &e);
- }
- }
- }
-
- } else {
- // A popup was closed, so the previous popup gets the focus.
-
- QWidget* aw = QApplicationPrivate::popupWidgets->last();
- if (QWidget *fw = aw->focusWidget())
- fw->setFocus(Qt::PopupFocusReason);
-
- //### regrab the keyboard and mouse in case 'popup' lost the grab
-
-
- }
-
-}
-
-static int openPopupCount = 0;
-void QApplicationPrivate::openPopup(QWidget *popup)
-{
- openPopupCount++;
- if (!popupWidgets) { // create list
- popupWidgets = new QWidgetList;
-
- /* only grab if you are the first/parent popup */
- //#### ->grabMouse(popup,true);
- //#### ->grabKeyboard(popup,true);
- //### popupGrabOk = true;
- }
- popupWidgets->append(popup); // add to end of list
-
- // popups are not focus-handled by the window system (the first
- // popup grabbed the keyboard), so we have to do that manually: A
- // new popup gets the focus
- if (popup->focusWidget()) {
- popup->focusWidget()->setFocus(Qt::PopupFocusReason);
- } else if (popupWidgets->count() == 1) { // this was the first popup
- if (QWidget *fw = QApplication::focusWidget()) {
- QFocusEvent e(QEvent::FocusOut, Qt::PopupFocusReason);
- QApplication::sendEvent(fw, &e);
- }
- }
-}
-
-void QApplicationPrivate::initializeMultitouch_sys()
-{
-}
-
-void QApplicationPrivate::cleanupMultitouch_sys()
-{
-}
-
-void QApplicationPrivate::initializeWidgetPaletteHash()
-{
-}
-
-void QApplication::setCursorFlashTime(int msecs)
-{
- QApplicationPrivate::cursor_flash_time = msecs;
-}
-
-int QApplication::cursorFlashTime()
-{
- return QApplicationPrivate::cursor_flash_time;
-}
-
-void QApplication::setDoubleClickInterval(int ms)
-{
- QApplicationPrivate::mouse_double_click_time = ms;
-}
-
-int QApplication::doubleClickInterval()
-{
- return QApplicationPrivate::mouse_double_click_time;
-}
-
-void QApplication::setKeyboardInputInterval(int ms)
-{
- QApplicationPrivate::keyboard_input_time = ms;
-}
-
-int QApplication::keyboardInputInterval()
-{
- return QApplicationPrivate::keyboard_input_time;
-}
-
-#ifndef QT_NO_WHEELEVENT
-void QApplication::setWheelScrollLines(int lines)
-{
- QApplicationPrivate::wheel_scroll_lines = lines;
-}
-
-int QApplication::wheelScrollLines()
-{
- return QApplicationPrivate::wheel_scroll_lines;
-}
-#endif
-
-void QApplication::setEffectEnabled(Qt::UIEffect effect, bool enable)
-{
- switch (effect) {
- case Qt::UI_AnimateMenu:
- QApplicationPrivate::animate_menu = enable;
- break;
- case Qt::UI_FadeMenu:
- if (enable)
- QApplicationPrivate::animate_menu = true;
- QApplicationPrivate::fade_menu = enable;
- break;
- case Qt::UI_AnimateCombo:
- QApplicationPrivate::animate_combo = enable;
- break;
- case Qt::UI_AnimateTooltip:
- QApplicationPrivate::animate_tooltip = enable;
- break;
- case Qt::UI_FadeTooltip:
- if (enable)
- QApplicationPrivate::animate_tooltip = true;
- QApplicationPrivate::fade_tooltip = enable;
- break;
- case Qt::UI_AnimateToolBox:
- QApplicationPrivate::animate_toolbox = enable;
- break;
- default:
- QApplicationPrivate::animate_ui = enable;
- break;
- }
-}
-
-bool QApplication::isEffectEnabled(Qt::UIEffect effect)
-{
- if (QColormap::instance().depth() < 16 || !QApplicationPrivate::animate_ui)
- return false;
-
- switch(effect) {
- case Qt::UI_AnimateMenu:
- return QApplicationPrivate::animate_menu;
- case Qt::UI_FadeMenu:
- return QApplicationPrivate::fade_menu;
- case Qt::UI_AnimateCombo:
- return QApplicationPrivate::animate_combo;
- case Qt::UI_AnimateTooltip:
- return QApplicationPrivate::animate_tooltip;
- case Qt::UI_FadeTooltip:
- return QApplicationPrivate::fade_tooltip;
- case Qt::UI_AnimateToolBox:
- return QApplicationPrivate::animate_toolbox;
- default:
- return QApplicationPrivate::animate_ui;
- }
-}
-
-#ifndef QT_NO_CURSOR
-void QApplication::setOverrideCursor(const QCursor &cursor)
-{
- qApp->d_func()->cursor_list.prepend(cursor);
- qt_qpa_set_cursor(0, false);
-}
-
-void QApplication::restoreOverrideCursor()
-{
- if (qApp->d_func()->cursor_list.isEmpty())
- return;
- qApp->d_func()->cursor_list.removeFirst();
- qt_qpa_set_cursor(0, false);
-}
-
-#endif// QT_NO_CURSOR
-
-QWidget *QApplication::topLevelAt(const QPoint &pos)
-{
- QPlatformIntegration *pi = QApplicationPrivate::platformIntegration();
-
- QList<QPlatformScreen *> screens = pi->screens();
- QList<QPlatformScreen *>::const_iterator screen = screens.constBegin();
- QList<QPlatformScreen *>::const_iterator end = screens.constEnd();
-
- // The first screen in a virtual environment should know about all top levels
- if (pi->isVirtualDesktop()) {
- QWidget *w = (*screen)->topLevelAt(pos);
- return w;
- }
-
- while (screen != end) {
- if ((*screen)->geometry().contains(pos))
- return (*screen)->topLevelAt(pos);
- ++screen;
- }
- return 0;
-}
-
-void QApplication::beep()
-{
-}
-
-void QApplication::alert(QWidget *, int)
-{
-}
-
-/*!
- \internal
-*/
-QPlatformNativeInterface *QApplication::platformNativeInterface()
-{
- QPlatformIntegration *pi = QApplicationPrivate::platformIntegration();
- return pi->nativeInterface();
-}
-
-static void init_platform(const QString &name, const QString &platformPluginPath)
-{
- QApplicationPrivate::platform_integration = QPlatformIntegrationFactory::create(name, platformPluginPath);
- if (!QApplicationPrivate::platform_integration) {
- QStringList keys = QPlatformIntegrationFactory::keys(platformPluginPath);
- QString fatalMessage =
- QString::fromLatin1("Failed to load platform plugin \"%1\". Available platforms are: \n").arg(name);
- foreach(QString key, keys) {
- fatalMessage.append(key + QString::fromLatin1("\n"));
- }
- qFatal("%s", fatalMessage.toLocal8Bit().constData());
-
- }
-
-}
-
-
-static void cleanup_platform()
-{
- delete QApplicationPrivate::platform_integration;
- QApplicationPrivate::platform_integration = 0;
-}
-
-static void init_plugins(const QList<QByteArray> pluginList)
-{
- for (int i = 0; i < pluginList.count(); ++i) {
- QByteArray pluginSpec = pluginList.at(i);
- qDebug() << "init_plugins" << i << pluginSpec;
- int colonPos = pluginSpec.indexOf(':');
- QObject *plugin;
- if (colonPos < 0)
- plugin = QGenericPluginFactory::create(QLatin1String(pluginSpec), QString());
- else
- plugin = QGenericPluginFactory::create(QLatin1String(pluginSpec.mid(0, colonPos)),
- QLatin1String(pluginSpec.mid(colonPos+1)));
- qDebug() << " created" << plugin;
- }
-}
-
-#ifndef QT_NO_QWS_INPUTMETHODS
-class QDummyInputContext : public QInputContext
-{
-public:
- explicit QDummyInputContext(QObject* parent = 0) : QInputContext(parent) {}
- ~QDummyInputContext() {}
- QString identifierName() { return QString(); }
- QString language() { return QString(); }
-
- void reset() {}
- bool isComposing() const { return false; }
-
-};
-#endif // QT_NO_QWS_INPUTMETHODS
-
-void qt_init(QApplicationPrivate *priv, int type)
-{
- Q_UNUSED(type);
-
- qApp->setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);
- char *p;
- char **argv = priv->argv;
- int argc = priv->argc;
-
- if (argv && *argv) { //apparently, we allow people to pass 0 on the other platforms
- p = strrchr(argv[0], '/');
- appName = QString::fromLocal8Bit(p ? p + 1 : argv[0]);
- }
-
- QList<QByteArray> pluginList;
- QString platformPluginPath = QLatin1String(qgetenv("QT_QPA_PLATFORM_PLUGIN_PATH"));
- QByteArray platformName;
-#ifdef QT_QPA_DEFAULT_PLATFORM_NAME
- platformName = QT_QPA_DEFAULT_PLATFORM_NAME;
-#endif
- QByteArray platformNameEnv = qgetenv("QT_QPA_PLATFORM");
- if (!platformNameEnv.isEmpty()) {
- platformName = platformNameEnv;
- }
-
- // Get command line params
-
- int j = argc ? 1 : 0;
- for (int i=1; i<argc; i++) {
- if (argv[i] && *argv[i] != '-') {
- argv[j++] = argv[i];
- continue;
- }
- QByteArray arg = argv[i];
- if (arg == "-fn" || arg == "-font") {
- if (++i < argc)
- appFont = QString::fromLocal8Bit(argv[i]);
- } else if (arg == "-platformpluginpath") {
- if (++i < argc)
- platformPluginPath = QLatin1String(argv[i]);
- } else if (arg == "-platform") {
- if (++i < argc)
- platformName = argv[i];
- } else if (arg == "-plugin") {
- if (++i < argc)
- pluginList << argv[i];
- } else {
- argv[j++] = argv[i];
- }
- }
-
- if (j < priv->argc) {
- priv->argv[j] = 0;
- priv->argc = j;
- }
-
-#if 0
- QByteArray pluginEnv = qgetenv("QT_QPA_PLUGINS");
- if (!pluginEnv.isEmpty()) {
- pluginList.append(pluginEnv.split(';'));
- }
-#endif
-
- init_platform(QLatin1String(platformName), platformPluginPath);
- init_plugins(pluginList);
-
- QColormap::initialize();
- QFont::initialize();
-#ifndef QT_NO_CURSOR
-// QCursorData::initialize();
-#endif
-
- qApp->setObjectName(appName);
-
-#ifndef QT_NO_QWS_INPUTMETHODS
- qApp->setInputContext(new QDummyInputContext(qApp));
-#endif
-}
-
-void qt_cleanup()
-{
- cleanup_platform();
-
- QPixmapCache::clear();
-#ifndef QT_NO_CURSOR
- QCursorData::cleanup();
-#endif
- QFont::cleanup();
- QColormap::cleanup();
- delete QApplicationPrivate::inputContext;
- QApplicationPrivate::inputContext = 0;
-
- QApplicationPrivate::active_window = 0; //### this should not be necessary
-}
-
-
-#ifdef QT3_SUPPORT
-void QApplication::setMainWidget(QWidget *mainWidget)
-{
- QApplicationPrivate::main_widget = mainWidget;
- if (QApplicationPrivate::main_widget && windowIcon().isNull()
- && QApplicationPrivate::main_widget->testAttribute(Qt::WA_SetWindowIcon))
- setWindowIcon(QApplicationPrivate::main_widget->windowIcon());
-}
-#endif
-
-void QApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent *e)
-{
- // qDebug() << "handleMouseEvent" << tlw << ev.pos() << ev.globalPos() << hex << ev.buttons();
- static QWeakPointer<QWidget> implicit_mouse_grabber;
-
- QEvent::Type type;
- // move first
- Qt::MouseButtons stateChange = e->buttons ^ buttons;
- if (e->globalPos != QPointF(qt_last_x, qt_last_y) && (stateChange != Qt::NoButton)) {
- QWindowSystemInterfacePrivate::MouseEvent * newMouseEvent =
- new QWindowSystemInterfacePrivate::MouseEvent(e->widget.data(), e->timestamp, e->localPos, e->globalPos, e->buttons);
- QWindowSystemInterfacePrivate::windowSystemEventQueue.prepend(newMouseEvent); // just in case the move triggers a new event loop
- stateChange = Qt::NoButton;
- }
-
- QWidget * tlw = e->widget.data();
-
- QPointF localPoint = e->localPos;
- QPointF globalPoint = e->globalPos;
- QWidget *mouseWindow = tlw;
-
- Qt::MouseButton button = Qt::NoButton;
-
-
- if (qt_last_x != globalPoint.x() || qt_last_y != globalPoint.y()) {
- type = QEvent::MouseMove;
- qt_last_x = globalPoint.x();
- qt_last_y = globalPoint.y();
- if (qAbs(globalPoint.x() - mousePressX) > mouse_double_click_distance||
- qAbs(globalPoint.y() - mousePressY) > mouse_double_click_distance)
- mousePressButton = Qt::NoButton;
- }
- else { // check to see if a new button has been pressed/released
- for (int check = Qt::LeftButton;
- check <= Qt::XButton2;
- check = check << 1) {
- if (check & stateChange) {
- button = Qt::MouseButton(check);
- break;
- }
- }
- if (button == Qt::NoButton) {
- // Ignore mouse events that don't change the current state
- return;
- }
- buttons = e->buttons;
- if (button & e->buttons) {
- if ((e->timestamp - mousePressTime) < static_cast<ulong>(QApplication::doubleClickInterval()) && button == mousePressButton) {
- type = QEvent::MouseButtonDblClick;
- mousePressButton = Qt::NoButton;
- }
- else {
- type = QEvent::MouseButtonPress;
- mousePressTime = e->timestamp;
- mousePressButton = button;
- mousePressX = qt_last_x;
- mousePressY = qt_last_y;
- }
- }
- else
- type = QEvent::MouseButtonRelease;
- }
-
- if (self->inPopupMode()) {
- //popup mouse handling is magical...
- mouseWindow = qApp->activePopupWidget();
-
- implicit_mouse_grabber.clear();
- //### how should popup mode and implicit mouse grab interact?
-
- } else if (tlw && app_do_modal && !qt_try_modal(tlw, QEvent::MouseButtonRelease) ) {
- //even if we're blocked by modality, we should deliver the mouse release event..
- //### this code is not completely correct: multiple buttons can be pressed simultaneously
- if (!(implicit_mouse_grabber && buttons == Qt::NoButton)) {
- //qDebug() << "modal blocked mouse event to" << tlw;
- return;
- }
- }
-
- // find the tlw if we didn't get it from the plugin
- if (!mouseWindow) {
- mouseWindow = QApplication::topLevelAt(globalPoint.toPoint());
- }
-
- if (!mouseWindow && !implicit_mouse_grabber)
- mouseWindow = QApplication::desktop();
-
- if (mouseWindow && mouseWindow != tlw) {
- //we did not get a sensible localPoint from the window system, so let's calculate it
- localPoint = mouseWindow->mapFromGlobal(globalPoint.toPoint());
- }
-
- // which child should have it?
- QWidget *mouseWidget = mouseWindow;
- if (mouseWindow) {
- QWidget *w = mouseWindow->childAt(localPoint.toPoint());
- if (w) {
- mouseWidget = w;
- }
- }
-
- //handle implicit mouse grab
- if (type == QEvent::MouseButtonPress && !implicit_mouse_grabber) {
- implicit_mouse_grabber = mouseWidget;
-
- Q_ASSERT(mouseWindow);
- mouseWindow->activateWindow(); //focus
- } else if (implicit_mouse_grabber) {
- mouseWidget = implicit_mouse_grabber.data();
- mouseWindow = mouseWidget->window();
- if (mouseWindow != tlw)
- localPoint = mouseWindow->mapFromGlobal(globalPoint.toPoint());
- }
-
- Q_ASSERT(mouseWidget);
-
- //localPoint is local to mouseWindow, but it needs to be local to mouseWidget
- localPoint = mouseWidget->mapFrom(mouseWindow, localPoint.toPoint());
-
- if (buttons == Qt::NoButton) {
- //qDebug() << "resetting mouse grabber";
- implicit_mouse_grabber.clear();
- }
-
- if (mouseWidget != qt_last_mouse_receiver) {
- dispatchEnterLeave(mouseWidget, qt_last_mouse_receiver);
- qt_last_mouse_receiver = mouseWidget;
- }
-
- // Remember, we might enter a modal event loop when sending the event,
- // so think carefully before adding code below this point.
-
- // qDebug() << "sending mouse ev." << ev.type() << localPoint << globalPoint << ev.button() << ev.buttons() << mouseWidget << "mouse grabber" << implicit_mouse_grabber;
-
- QMouseEvent ev(type, localPoint, globalPoint, button, buttons, QApplication::keyboardModifiers());
-
- QList<QWeakPointer<QPlatformCursor> > cursors = QPlatformCursorPrivate::getInstances();
- foreach (QWeakPointer<QPlatformCursor> cursor, cursors) {
- if (cursor)
- cursor.data()->pointerEvent(ev);
- }
-
- int oldOpenPopupCount = openPopupCount;
- QApplication::sendSpontaneousEvent(mouseWidget, &ev);
-
-#ifndef QT_NO_CONTEXTMENU
- if (type == QEvent::MouseButtonPress && button == Qt::RightButton && (openPopupCount == oldOpenPopupCount)) {
- QContextMenuEvent e(QContextMenuEvent::Mouse, localPoint.toPoint(), globalPoint.toPoint(), QApplication::keyboardModifiers());
- QApplication::sendSpontaneousEvent(mouseWidget, &e);
- }
-#endif // QT_NO_CONTEXTMENU
-}
-
-
-//### there's a lot of duplicated logic here -- refactoring required!
-
-void QApplicationPrivate::processWheelEvent(QWindowSystemInterfacePrivate::WheelEvent *e)
-{
-// QPoint localPoint = ev.pos();
- QPointF globalPoint = e->globalPos;
-// bool trustLocalPoint = !!tlw; //is there something the local point can be local to?
- QWidget *mouseWidget;
-
- qt_last_x = globalPoint.x();
- qt_last_y = globalPoint.y();
-
- QWidget *mouseWindow = e->widget.data();
-
- // find the tlw if we didn't get it from the plugin
- if (!mouseWindow) {
- mouseWindow = QApplication::topLevelAt(globalPoint.toPoint());
- }
-
- if (!mouseWindow)
- return;
-
- mouseWidget = mouseWindow;
-
- if (app_do_modal && !qt_try_modal(mouseWindow, QEvent::Wheel) ) {
- qDebug() << "modal blocked wheel event" << mouseWindow;
- return;
- }
- QPointF p = mouseWindow->mapFromGlobal(globalPoint.toPoint());
- QWidget *w = mouseWindow->childAt(p.toPoint());
- if (w) {
- mouseWidget = w;
- p = mouseWidget->mapFromGlobal(globalPoint.toPoint());
- }
-
- QWheelEvent ev(p, globalPoint, e->delta, buttons, QApplication::keyboardModifiers(),
- e->orient);
- QApplication::sendSpontaneousEvent(mouseWidget, &ev);
-}
-
-
-
-// Remember, Qt convention is: keyboard state is state *before*
-
-void QApplicationPrivate::processKeyEvent(QWindowSystemInterfacePrivate::KeyEvent *e)
-{
- QWidget *focusW = 0;
- if (self->inPopupMode()) {
- QWidget *popupW = qApp->activePopupWidget();
- focusW = popupW->focusWidget() ? popupW->focusWidget() : popupW;
- }
- if (!focusW)
- focusW = QApplication::focusWidget();
- if (!focusW) {
- focusW = e->widget.data();
- }
- if (!focusW)
- focusW = QApplication::activeWindow();
-
- //qDebug() << "handleKeyEvent" << hex << e->key() << e->modifiers() << e->text() << "widget" << focusW;
-
- if (!focusW)
- return;
- if (app_do_modal && !qt_try_modal(focusW, e->keyType))
- return;
-
- if (e->nativeScanCode || e->nativeVirtualKey || e->nativeModifiers) {
- QKeyEventEx ev(e->keyType, e->key, e->modifiers, e->unicode, e->repeat, e->repeatCount,
- e->nativeScanCode, e->nativeVirtualKey, e->nativeModifiers);
- QApplication::sendSpontaneousEvent(focusW, &ev);
- } else {
- QKeyEvent ev(e->keyType, e->key, e->modifiers, e->unicode, e->repeat, e->repeatCount);
- QApplication::sendSpontaneousEvent(focusW, &ev);
- }
-}
-
-void QApplicationPrivate::processEnterEvent(QWindowSystemInterfacePrivate::EnterEvent *e)
-{
- QApplicationPrivate::dispatchEnterLeave(e->enter.data(),0);
- qt_last_mouse_receiver = e->enter.data();
-}
-
-void QApplicationPrivate::processLeaveEvent(QWindowSystemInterfacePrivate::LeaveEvent *e)
-{
- QApplicationPrivate::dispatchEnterLeave(0,qt_last_mouse_receiver);
-
- if (e->leave.data() && !e->leave.data()->isAncestorOf(qt_last_mouse_receiver)) //(???) this should not happen
- QApplicationPrivate::dispatchEnterLeave(0, e->leave.data());
- qt_last_mouse_receiver = 0;
-
-}
-
-void QApplicationPrivate::processActivatedEvent(QWindowSystemInterfacePrivate::ActivatedWindowEvent *e)
-{
- QApplication::setActiveWindow(e->activated.data());
-}
-
-void QApplicationPrivate::processGeometryChangeEvent(QWindowSystemInterfacePrivate::GeometryChangeEvent *e)
-{
- if (e->tlw.isNull())
- return;
- QWidget *tlw = e->tlw.data();
- if (!tlw->isWindow())
- return; //geo of native child widgets is controlled by lighthouse
- //so we already have sent the events; besides this new rect
- //is not mapped to parent
-
- QRect newRect = e->newGeometry;
- QRect cr(tlw->geometry());
- bool isResize = cr.size() != newRect.size();
- bool isMove = cr.topLeft() != newRect.topLeft();
- tlw->data->crect = newRect;
- if (isResize) {
- QResizeEvent e(tlw->data->crect.size(), cr.size());
- QApplication::sendSpontaneousEvent(tlw, &e);
- tlw->update();
- }
-
- if (isMove) {
- //### frame geometry
- QMoveEvent e(tlw->data->crect.topLeft(), cr.topLeft());
- QApplication::sendSpontaneousEvent(tlw, &e);
- }
-}
-
-void QApplicationPrivate::processCloseEvent(QWindowSystemInterfacePrivate::CloseEvent *e)
-{
- if (e->topLevel.isNull()) {
- //qDebug() << "QApplicationPrivate::processCloseEvent NULL";
- return;
- }
- e->topLevel.data()->d_func()->close_helper(QWidgetPrivate::CloseWithSpontaneousEvent);
-}
-
-void QApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::TouchEvent *e)
-{
- translateRawTouchEvent(e->widget.data(), e->devType, e->points);
-}
-
-void QApplicationPrivate::reportScreenCount(QWindowSystemInterfacePrivate::ScreenCountEvent *e)
-{
- // This operation only makes sense after the QApplication constructor runs
- if (QCoreApplication::startingUp())
- return;
-
- QApplication::desktop()->d_func()->updateScreenList();
- // signal anything listening for creation or deletion of screens
- QDesktopWidget *desktop = QApplication::desktop();
- emit desktop->screenCountChanged(e->count);
-}
-
-void QApplicationPrivate::reportGeometryChange(QWindowSystemInterfacePrivate::ScreenGeometryEvent *e)
-{
- // This operation only makes sense after the QApplication constructor runs
- if (QCoreApplication::startingUp())
- return;
-
- QApplication::desktop()->d_func()->updateScreenList();
-
- // signal anything listening for screen geometry changes
- QDesktopWidget *desktop = QApplication::desktop();
- emit desktop->resized(e->index);
-
- // make sure maximized and fullscreen windows are updated
- QWidgetList list = QApplication::topLevelWidgets();
- for (int i = list.size() - 1; i >= 0; --i) {
- QWidget *w = list.at(i);
- if (w->isFullScreen())
- w->d_func()->setFullScreenSize_helper();
- else if (w->isMaximized())
- w->d_func()->setMaxWindowState_helper();
- }
-}
-
-void QApplicationPrivate::reportAvailableGeometryChange(
- QWindowSystemInterfacePrivate::ScreenAvailableGeometryEvent *e)
-{
- // This operation only makes sense after the QApplication constructor runs
- if (QCoreApplication::startingUp())
- return;
-
- QApplication::desktop()->d_func()->updateScreenList();
-
- // signal anything listening for screen geometry changes
- QDesktopWidget *desktop = QApplication::desktop();
- emit desktop->workAreaResized(e->index);
-
- // make sure maximized and fullscreen windows are updated
- QWidgetList list = QApplication::topLevelWidgets();
- for (int i = list.size() - 1; i >= 0; --i) {
- QWidget *w = list.at(i);
- if (w->isFullScreen())
- w->d_func()->setFullScreenSize_helper();
- else if (w->isMaximized())
- w->d_func()->setMaxWindowState_helper();
- }
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/kernel/qapplication_qws.cpp b/src/gui/kernel/qapplication_qws.cpp
deleted file mode 100644
index 428f558023..0000000000
--- a/src/gui/kernel/qapplication_qws.cpp
+++ /dev/null
@@ -1,3802 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qglobal.h"
-#include "qlibrary.h"
-#include "qcursor.h"
-#include "qapplication.h"
-#include "private/qapplication_p.h"
-#include "qwidget.h"
-#include "qbitarray.h"
-#include "qpainter.h"
-#include "qpixmapcache.h"
-#include "qdatetime.h"
-#include "qtextcodec.h"
-#include "qdatastream.h"
-#include "qbuffer.h"
-#include "qsocketnotifier.h"
-#include "qsessionmanager.h"
-#include "qclipboard.h"
-#include "qbitmap.h"
-#include "qwssocket_qws.h"
-#include "qtransportauth_qws.h"
-#include "private/qtransportauth_qws_p.h"
-#include "qwsevent_qws.h"
-#include "private/qwscommand_qws_p.h"
-#include "qwsproperty_qws.h"
-#include "qscreen_qws.h"
-#include "qscreenproxy_qws.h"
-#include "qcopchannel_qws.h"
-#include "private/qlock_p.h"
-#include "private/qwslock_p.h"
-//#include "qmemorymanager_qws.h"
-#include "qwsmanager_qws.h"
-//#include "qwsregionmanager_qws.h"
-#include "qwindowsystem_qws.h"
-#include "private/qwindowsystem_p.h"
-#include "qdecorationfactory_qws.h"
-
-#include "qwsdisplay_qws.h"
-#include "private/qwsdisplay_qws_p.h"
-#include "private/qwsinputcontext_p.h"
-#include "qfile.h"
-#include "qhash.h"
-#include "qdesktopwidget.h"
-#include "qcolormap.h"
-#include "private/qcursor_p.h"
-#include "qsettings.h"
-#include "qdebug.h"
-#include "qeventdispatcher_qws_p.h"
-#if !defined(QT_NO_GLIB)
-# include "qeventdispatcher_glib_qws_p.h"
-#endif
-
-
-#include "private/qwidget_p.h"
-#include "private/qbackingstore_p.h"
-#include "private/qwindowsurface_qws_p.h"
-#include "private/qfont_p.h"
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <locale.h>
-#include <errno.h>
-#include <fcntl.h>
-#ifdef Q_OS_VXWORKS
-# include <sys/times.h>
-#else
-# include <sys/time.h>
-#endif
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include <qvfbhdr.h>
-
-#ifndef QT_NO_QWS_MULTIPROCESS
-#ifdef QT_NO_QSHM
-#include <sys/ipc.h>
-#include <sys/shm.h>
-#ifndef Q_OS_DARWIN
-# include <sys/sem.h>
-#endif
-#include <sys/socket.h>
-#else
-#include "private/qwssharedmemory_p.h"
-#endif
-#endif
-
-QT_BEGIN_NAMESPACE
-
-#ifndef QT_NO_DIRECTPAINTER
-class QDirectPainter;
-extern void qt_directpainter_region(QDirectPainter *dp, const QRegion &alloc, int type);
-#ifndef QT_NO_QWSEMBEDWIDGET
-extern void qt_directpainter_embedevent(QDirectPainter *dp,
- const QWSEmbedEvent *e);
-#endif
-#endif // QT_NO_DIRECTPAINTER
-
-const int qwsSharedRamSize = 1 * 1024; // misc data, written by server, read by clients
-
-extern QApplication::Type qt_appType;
-extern QDesktopWidget *qt_desktopWidget;
-
-//these used to be environment variables, they are initialized from
-//environment variables in
-
-bool qws_savefonts = false;
-bool qws_screen_is_interlaced=false; //### should be detected
-bool qws_shared_memory = false;
-bool qws_sw_cursor = true;
-bool qws_accel = true; // ### never set
-QByteArray qws_display_spec(":0");
-Q_GUI_EXPORT int qws_display_id = 0;
-Q_GUI_EXPORT int qws_client_id = 0;
-QWidget *qt_pressGrab = 0;
-QWidget *qt_mouseGrb = 0;
-int *qt_last_x = 0;
-int *qt_last_y = 0;
-
-static int mouse_x_root = -1;
-static int mouse_y_root = -1;
-static int mouse_state = 0;
-static int mouse_double_click_distance = 5;
-
-int qt_servershmid = -1;
-
-bool qws_overrideCursor = false;
-#ifndef QT_NO_QWS_MANAGER
-
-extern Q_GUI_EXPORT QWSServer *qwsServer;
-
-static QDecoration *qws_decoration = 0;
-#endif
-
-#if defined(QT_DEBUG)
-/*
-extern "C" void dumpmem(const char* m)
-{
- static int init=0;
- static int prev=0;
- FILE* f = fopen("/proc/meminfo","r");
- // char line[100];
- int total=0,used=0,free=0,shared=0,buffers=0,cached=0;
- fscanf(f,"%*[^M]Mem: %d %d %d %d %d %d",&total,&used,&free,&shared,&buffers,&cached);
- used -= buffers + cached;
- if (!init) {
- init=used;
- } else {
- printf("%40s: %+8d = %8d\n",m,used-init-prev,used-init);
- prev = used-init;
- }
- fclose(f);
-}
-*/
-#endif
-
-// Get the name of the directory where Qt for Embedded Linux temporary data should
-// live.
-QString qws_dataDir()
-{
- static QString result;
- if (!result.isEmpty())
- return result;
- result = QT_VFB_DATADIR(qws_display_id);
- QByteArray dataDir = result.toLocal8Bit();
-
-#if defined(Q_OS_INTEGRITY)
- /* ensure filesystem is ready before starting requests */
- WaitForFileSystemInitialization();
-#endif
-
- if (QT_MKDIR(dataDir, 0700)) {
- if (errno != EEXIST) {
- qFatal("Cannot create Qt for Embedded Linux data directory: %s", dataDir.constData());
- }
- }
-
- QT_STATBUF buf;
- if (QT_LSTAT(dataDir, &buf))
- qFatal("stat failed for Qt for Embedded Linux data directory: %s", dataDir.constData());
-
- if (!S_ISDIR(buf.st_mode))
- qFatal("%s is not a directory", dataDir.constData());
-
-#if !defined(Q_OS_INTEGRITY) && !defined(Q_OS_VXWORKS)
- if (buf.st_uid != getuid())
- qFatal("Qt for Embedded Linux data directory is not owned by user %d", getuid());
-
- if ((buf.st_mode & 0677) != 0600)
- qFatal("Qt for Embedded Linux data directory has incorrect permissions: %s", dataDir.constData());
-#endif
-
- result.append("/");
- return result;
-}
-
-// Get the filename of the pipe Qt for Embedded Linux uses for server/client comms
-Q_GUI_EXPORT QString qws_qtePipeFilename()
-{
- qws_dataDir();
- return QTE_PIPE(qws_display_id);
-}
-
-static void setMaxWindowRect(const QRect &rect)
-{
- const QList<QScreen*> subScreens = qt_screen->subScreens();
- QScreen *screen = qt_screen;
- int screenNo = 0;
- for (int i = 0; i < subScreens.size(); ++i) {
- if (subScreens.at(i)->region().contains(rect)) {
- screen = subScreens.at(i);
- screenNo = i;
- break;
- }
- }
-
- QApplicationPrivate *ap = QApplicationPrivate::instance();
- ap->setMaxWindowRect(screen, screenNo, rect);
-}
-
-void QApplicationPrivate::setMaxWindowRect(const QScreen *screen, int screenNo,
- const QRect &rect)
-{
- if (maxWindowRects.value(screen) == rect)
- return;
-
- maxWindowRects[screen] = rect;
-
- // Re-resize any maximized windows
- QWidgetList l = QApplication::topLevelWidgets();
- for (int i = 0; i < l.size(); ++i) {
- QWidget *w = l.at(i);
- QScreen *s = w->d_func()->getScreen();
- if (w->isMaximized() && s == screen)
- w->d_func()->setMaxWindowState_helper();
- }
-
- if ( qt_desktopWidget ) // XXX workaround crash
- emit QApplication::desktop()->workAreaResized(screenNo);
-}
-
-#ifndef QT_NO_QWS_DYNAMICSCREENTRANSFORMATION
-
-typedef void (*TransformFunc)(QScreen *, int);
-#ifndef QT_NO_QWS_TRANSFORMED
-extern "C" void qws_setScreenTransformation(QScreen *, int);
-#endif
-static TransformFunc getTransformationFunction()
-{
- static TransformFunc func = 0;
-
- if (!func) {
-#ifdef QT_NO_QWS_TRANSFORMED
-# ifndef QT_NO_LIBRARY
- // symbol is not built into the library, search for the plugin
- const QStringList paths = QApplication::libraryPaths();
- foreach (const QString &path, paths) {
- const QString file = path + QLatin1String("/gfxdrivers/libqgfxtransformed");
- func = (TransformFunc)QLibrary::resolve(file,
- "qws_setScreenTransformation");
- if (func)
- break;
- }
-# endif
-#else
- func = qws_setScreenTransformation;
-#endif
- if (!func)
- func = (TransformFunc)-1;
- }
-
- if (func == (TransformFunc)-1)
- return 0;
-
- return func;
-}
-
-static void setScreenTransformation(int screenNo, int transformation)
-{
- QScreen *screen = QScreen::instance();
- const QList<QScreen*> subScreens = screen->subScreens();
-
- if (screenNo == -1)
- screenNo = 0;
-
- if (screenNo == -1 && !subScreens.isEmpty())
- screenNo = 0;
-
- if (subScreens.isEmpty() && screenNo == 0) {
- // nothing
- } else if (screenNo < 0 || screenNo >= subScreens.size()) {
- qWarning("setScreenTransformation: invalid screen %i", screenNo);
- return;
- }
-
- if (screenNo < subScreens.size())
- screen = subScreens.at(screenNo);
-
- QApplicationPrivate *ap = QApplicationPrivate::instance();
- ap->setScreenTransformation(screen, screenNo, transformation);
-}
-
-void QApplicationPrivate::setScreenTransformation(QScreen *screen,
- int screenNo,
- int transformation)
-{
- QScreen *transformed = screen;
-
- while (transformed->classId() == QScreen::ProxyClass)
- transformed = static_cast<QProxyScreen*>(transformed)->screen();
-
- if (transformed->classId() != QScreen::TransformedClass)
- return;
-
- TransformFunc setScreenTransformation = getTransformationFunction();
- if (!setScreenTransformation)
- return;
-
- setScreenTransformation(transformed, transformation);
-
- // need to re-configure() proxies bottom-up
- if (screen->classId() == QScreen::ProxyClass) {
- QList<QProxyScreen*> proxies;
- QScreen *s = screen;
-
- do {
- QProxyScreen *proxy = static_cast<QProxyScreen*>(s);
- proxies.append(proxy);
- s = proxy->screen();
- } while (s->classId() == QScreen::ProxyClass);
-
- do {
- QProxyScreen *proxy = proxies.takeLast();
- proxy->setScreen(proxy->screen()); // triggers configure()
- } while (!proxies.isEmpty());
- }
-
- if (qt_desktopWidget) { // XXX workaround crash for early screen transform events
- QDesktopWidget *desktop = QApplication::desktop();
-
- emit desktop->resized(screenNo);
- if (maxWindowRect(screen).isEmpty()) // not explicitly set
- emit desktop->workAreaResized(screenNo);
- }
-
- QWSServer *server = QWSServer::instance();
- if (server) {
- server->updateWindowRegions();
- QRegion r = screen->region();
- server->refresh(r);
- }
-
- // make sure maximized and fullscreen windows are updated
- QWidgetList list = QApplication::topLevelWidgets();
- for (int i = list.size() - 1; i >= 0; --i) {
- QWidget *w = list.at(i);
- if (w->isFullScreen())
- w->d_func()->setFullScreenSize_helper();
- else if (w->isMaximized())
- w->d_func()->setMaxWindowState_helper();
- }
-}
-
-#endif // QT_NO_QWS_DYNAMICSCREENTRANSFORMATION
-
-/*****************************************************************************
- Internal variables and functions
- *****************************************************************************/
-
-
-static QString appName; // application name
-static const char *appFont = 0; // application font
-static const char *appBGCol = 0; // application bg color
-static const char *appFGCol = 0; // application fg color
-static const char *appBTNCol = 0; // application btn color
-static const char *mwGeometry = 0; // main widget geometry
-static const char *mwTitle = 0; // main widget title
-//static bool mwIconic = false; // main widget iconified
-
-static bool app_do_modal = false; // modal mode
-Q_GUI_EXPORT QWSDisplay *qt_fbdpy = 0; // QWS `display'
-QLock *QWSDisplay::lock = 0;
-
-static int mouseButtonPressed = 0; // last mouse button pressed
-static int mouseButtonPressTime = 0; // when was a button pressed
-static short mouseXPos, mouseYPos; // mouse position in act window
-
-extern QWidgetList *qt_modal_stack; // stack of modal widgets
-
-static QWidget *popupButtonFocus = 0;
-static QWidget *popupOfPopupButtonFocus = 0;
-static bool popupCloseDownMode = false;
-static bool popupGrabOk;
-static QPointer<QWidget> *mouseInWidget = 0;
-QPointer<QWidget> qt_last_mouse_receiver = 0;
-
-static bool sm_blockUserInput = false; // session management
-
-QWidget *qt_button_down = 0; // widget got last button-down
-WId qt_last_cursor = 0xffffffff; // Was -1, but WIds are unsigned
-
-class QWSMouseEvent;
-class QWSKeyEvent;
-
-class QETWidget : public QWidget // event translator widget
-{
-public:
- bool translateMouseEvent(const QWSMouseEvent *, int oldstate);
- bool translateKeyEvent(const QWSKeyEvent *, bool grab);
- bool translateRegionEvent(const QWSRegionEvent *);
-#ifndef QT_NO_QWSEMBEDWIDGET
- void translateEmbedEvent(const QWSEmbedEvent *event);
-#endif
- bool translateWheelEvent(const QWSMouseEvent *me);
- void repaintDecoration(QRegion r, bool post);
- void updateRegion();
-
- bool raiseOnClick()
- {
- // With limited windowmanagement/taskbar/etc., raising big windows
- // (eg. spreadsheet) over the top of everything else (eg. calculator)
- // is just annoying.
- return !isMaximized() && !isFullScreen();
- }
-};
-
-void QApplicationPrivate::createEventDispatcher()
-{
- Q_Q(QApplication);
-#if !defined(QT_NO_GLIB)
- if (qgetenv("QT_NO_GLIB").isEmpty() && QEventDispatcherGlib::versionSupported())
- eventDispatcher = (q->type() != QApplication::Tty
- ? new QWSEventDispatcherGlib(q)
- : new QEventDispatcherGlib(q));
- else
-#endif
- eventDispatcher = (q->type() != QApplication::Tty
- ? new QEventDispatcherQWS(q)
- : new QEventDispatcherUNIX(q));
-}
-
-// Single-process stuff. This should maybe move into qwindowsystem_qws.cpp
-
-static bool qws_single_process;
-static QList<QWSEvent*> incoming;
-static QList<QWSCommand*> outgoing;
-
-void qt_client_enqueue(const QWSEvent *event)
-{
- QWSEvent *copy = QWSEvent::factory(event->type);
- copy->copyFrom(event);
- incoming.append(copy);
-}
-
-QList<QWSCommand*> *qt_get_server_queue()
-{
- return &outgoing;
-}
-
-void qt_server_enqueue(const QWSCommand *command)
-{
- QWSCommand *copy = QWSCommand::factory(command->type);
- QT_TRY {
- copy->copyFrom(command);
- outgoing.append(copy);
- } QT_CATCH(...) {
- delete copy;
- QT_RETHROW;
- }
-}
-
-QWSDisplay::Data::Data(QObject* parent, bool singleProcess)
-{
-#ifdef QT_NO_QWS_MULTIPROCESS
- Q_UNUSED(parent);
- Q_UNUSED(singleProcess);
-#else
- if (singleProcess)
- csocket = 0;
- else {
- csocket = new QWSSocket(parent);
- QObject::connect(csocket, SIGNAL(disconnected()),
- qApp, SLOT(quit()));
- }
- clientLock = 0;
-#endif
- init();
-}
-
-QWSDisplay::Data::~Data()
-{
-// delete rgnMan; rgnMan = 0;
-// delete memorymanager; memorymanager = 0;
- qt_screen->disconnect();
- delete qt_screen; qt_screen = 0;
-#ifndef QT_NO_QWS_CURSOR
- delete qt_screencursor; qt_screencursor = 0;
-#endif
-#ifndef QT_NO_QWS_MULTIPROCESS
- shm.detach();
- if (csocket) {
- QWSCommand shutdownCmd(QWSCommand::Shutdown, 0, 0);
- shutdownCmd.write(csocket);
- csocket->flush(); // may be pending QCop message, eg.
- delete csocket;
- }
- delete clientLock;
- clientLock = 0;
-#endif
- delete connected_event;
- delete mouse_event;
- delete current_event;
- qDeleteAll(queue);
-#ifndef QT_NO_COP
- delete qcop_response;
-#endif
-}
-
-#ifndef QT_NO_QWS_MULTIPROCESS
-bool QWSDisplay::Data::lockClient(QWSLock::LockType type, int timeout)
-{
- return !clientLock || clientLock->lock(type, timeout);
-}
-
-void QWSDisplay::Data::unlockClient(QWSLock::LockType type)
-{
- if (clientLock) clientLock->unlock(type);
-}
-
-bool QWSDisplay::Data::waitClient(QWSLock::LockType type, int timeout)
-{
- return !clientLock || clientLock->wait(type, timeout);
-}
-
-QWSLock* QWSDisplay::Data::getClientLock()
-{
- return clientLock;
-}
-#endif // QT_NO_QWS_MULTIPROCESS
-
-void QWSDisplay::Data::flush()
-{
-#ifndef QT_NO_QWS_MULTIPROCESS
- if (csocket) {
- csocket->waitForReadyRead(0);
- csocket->flush();
- }
-#endif
-}
-
-#if 0
-void QWSDisplay::Data::debugQueue() {
- for (int i = 0; i < queue.size(); ++i) {
- QWSEvent *e = queue.at(i);
- qDebug( " ev %d type %d sl %d rl %d", i, e->type, e->simpleLen, e->rawLen);
- }
-}
-#endif
-
-bool QWSDisplay::Data::queueNotEmpty()
-{
- return mouse_event/*||region_event*/||queue.count() > 0;
-}
-QWSEvent* QWSDisplay::Data::dequeue()
-{
- QWSEvent *r=0;
- if (queue.count()) {
- r = queue.first();
- queue.removeFirst();
- if (r->type == QWSEvent::Region)
- region_events_count--;
- } else if (mouse_event) {
- r = mouse_event;
- mouse_event = 0;
-#ifdef QAPPLICATION_EXTRA_DEBUG
- mouse_event_count = 0;
-#endif
- }
- return r;
-}
-
-QWSEvent* QWSDisplay::Data::peek()
-{
- return queue.first();
-}
-
-bool QWSDisplay::Data::directServerConnection()
-{
-#ifndef QT_NO_QWS_MULTIPROCESS
- return csocket == 0;
-#else
- return true;
-#endif
-}
-
-void QWSDisplay::Data::create(int n)
-{
- QWSCreateCommand cmd(n);
- sendCommand(cmd);
-}
-
-void QWSDisplay::Data::flushCommands()
-{
-#ifndef QT_NO_QWS_MULTIPROCESS
- if (csocket)
- csocket->flush();
-#endif
-}
-
-void QWSDisplay::Data::sendCommand(QWSCommand & cmd)
-{
-#ifndef QT_NO_QWS_MULTIPROCESS
- if (csocket)
- cmd.write(csocket);
- else
-#endif
- qt_server_enqueue(&cmd);
-}
-
-void QWSDisplay::Data::sendSynchronousCommand(QWSCommand & cmd)
-{
-#ifndef QT_NO_QWS_MULTIPROCESS
- if (csocket) {
- lockClient(QWSLock::Communication);
- cmd.write(csocket);
- bool ok = true;
- while (csocket->bytesToWrite() > 0) {
- if (!csocket->waitForBytesWritten(-1)) {
- qCritical("QWSDisplay::Data::sendSynchronousCommand: %s",
- qPrintable(csocket->errorString()));
- ok = false;
- break;
- }
- }
- if (ok)
- waitClient(QWSLock::Communication);
- } else
-#endif
- qt_server_enqueue(&cmd);
-}
-
-int QWSDisplay::Data::takeId()
-{
- int unusedIdCount = unused_identifiers.count();
- if (unusedIdCount <= 10)
- create(15);
- if (unusedIdCount == 0) {
- create(1); // Make sure we have an incoming id to wait for, just in case we're recursive
- waitForCreation();
- }
-
- return unused_identifiers.takeFirst();
-}
-
-void QWSDisplay::Data::setMouseFilter(void (*filter)(QWSMouseEvent*))
-{
- mouseFilter = filter;
-}
-
-#ifndef QT_NO_QWS_MULTIPROCESS
-
-QWSLock* QWSDisplay::Data::clientLock = 0;
-
-void Q_GUI_EXPORT qt_app_reinit( const QString& newAppName )
-{
- qt_fbdpy->d->reinit( newAppName );
-}
-
-#endif // QT_NO_QWS_MULTIPROCESS
-
-class QDesktopWidget;
-
-#ifndef QT_NO_QWS_MULTIPROCESS
-void QWSDisplay::Data::reinit( const QString& newAppName )
-{
- Q_ASSERT(csocket);
-
- delete connected_event;
- connected_event = 0;
- region_events_count = 0;
-// region_ack = 0;
- delete mouse_event;
- mouse_event = 0;
-// region_event = 0;
- region_offset_window = 0;
-#ifndef QT_NO_COP
- delete qcop_response;
- qcop_response = 0;
-#endif
- delete current_event;
- current_event = 0;
-#ifdef QAPPLICATION_EXTRA_DEBUG
- mouse_event_count = 0;
-#endif
- mouseFilter = 0;
-
- qt_desktopWidget = 0;
- delete QWSDisplay::Data::clientLock;
- QWSDisplay::Data::clientLock = 0;
-
- QString pipe = qws_qtePipeFilename();
-
- // QWS client
- // Cleanup all cached ids
- unused_identifiers.clear();
- delete csocket;
-
- appName = newAppName;
- qApp->setObjectName( appName );
-
- csocket = new QWSSocket();
- QObject::connect(csocket, SIGNAL(disconnected()),
- qApp, SLOT(quit()));
- csocket->connectToLocalFile(pipe);
-
- QWSDisplay::Data::clientLock = new QWSLock();
-
- QWSIdentifyCommand cmd;
- cmd.setId(appName, QWSDisplay::Data::clientLock->id());
-
-#ifndef QT_NO_SXE
- QTransportAuth *a = QTransportAuth::getInstance();
- QTransportAuth::Data *d = a->connectTransport(
- QTransportAuth::UnixStreamSock |
- QTransportAuth::Trusted,
- csocket->socketDescriptor());
- QAuthDevice *ad = a->authBuf( d, csocket );
- ad->setClient( csocket );
-
- cmd.write(ad);
-#else
- cmd.write(csocket);
-#endif
-
- // wait for connect confirmation
- waitForConnection();
-
- qws_client_id = connected_event->simpleData.clientId;
-
- if (!QWSDisplay::initLock(pipe, false))
- qFatal("Cannot get display lock");
-
- if (shm.attach(connected_event->simpleData.servershmid)) {
- sharedRam = static_cast<uchar *>(shm.address());
- QScreen *s = qt_get_screen(qws_display_id, qws_display_spec.constData());
- if (s)
- sharedRamSize += s->memoryNeeded(QLatin1String(qws_display_spec.constData()));
- } else {
- perror("QWSDisplay::Data::init");
- qFatal("Client can't attach to main ram memory.");
- }
-
- qApp->desktop();
-
- // We wait for creation mainly so that we can process important
- // initialization events such as MaxWindowRect that are sent
- // before object id creation. Waiting here avoids later window
- // resizing since we have the MWR before windows are displayed.
- waitForCreation();
-
- sharedRamSize -= sizeof(int);
- qt_last_x = reinterpret_cast<int *>(sharedRam + sharedRamSize);
- sharedRamSize -= sizeof(int);
- qt_last_y = reinterpret_cast<int *>(sharedRam + sharedRamSize);
-
-#ifndef QT_NO_COP
- QCopChannel::reregisterAll();
-#endif
- csocket->flush();
-}
-#endif
-
-void QWSDisplay::Data::init()
-{
- connected_event = 0;
- region_events_count = 0;
-// region_ack = 0;
- mouse_event = 0;
- mouse_state = -1;
- mouse_winid = 0;
-// region_event = 0;
- region_offset_window = 0;
-#ifndef QT_NO_COP
- qcop_response = 0;
-#endif
- current_event = 0;
-#ifdef QAPPLICATION_EXTRA_DEBUG
- mouse_event_count = 0;
-#endif
- mouseFilter = 0;
-
- QString pipe = qws_qtePipeFilename();
-
- sharedRamSize = qwsSharedRamSize;
-
-#ifndef QT_NO_QWS_MULTIPROCESS
- if (csocket) {
- // QWS client
-
- connectToPipe();
-
- QWSDisplay::Data::clientLock = new QWSLock();
-
- QWSIdentifyCommand cmd;
- cmd.setId(appName, QWSDisplay::Data::clientLock->id());
-#ifndef QT_NO_SXE
- QTransportAuth *a = QTransportAuth::getInstance();
- QTransportAuth::Data *d = a->connectTransport(
- QTransportAuth::UnixStreamSock |
- QTransportAuth::Trusted,
- csocket->socketDescriptor());
- QAuthDevice *ad = a->authBuf( d, csocket );
- ad->setClient( csocket );
- cmd.write(ad);
-#else
- cmd.write(csocket);
-#endif
-
- // create(30); // not necessary, server will send ids anyway
- waitForConnection();
-
- qws_client_id = connected_event->simpleData.clientId;
-
- // now we want to get the exact display spec to use if we haven't
- // specified anything.
- if (qws_display_spec.at(0) == ':')
- qws_display_spec = connected_event->display;
-
- if (!QWSDisplay::initLock(pipe, false))
- qFatal("Cannot get display lock");
-
- if (shm.attach(connected_event->simpleData.servershmid)) {
- sharedRam = static_cast<uchar *>(shm.address());
- QScreen *s = qt_get_screen(qws_display_id, qws_display_spec.constData());
- if (s)
- sharedRamSize += s->memoryNeeded(QLatin1String(qws_display_spec.constData()));
- } else {
- perror("QWSDisplay::Data::init");
- qFatal("Client can't attach to main ram memory.");
- }
-
- // We wait for creation mainly so that we can process important
- // initialization events such as MaxWindowRect that are sent
- // before object id creation. Waiting here avoids later window
- // resizing since we have the MWR before windows are displayed.
- waitForCreation();
- } else
-#endif
- {
- create(30);
-
- // QWS server
- if (!QWSDisplay::initLock(pipe, true))
- qFatal("Cannot get display lock");
-
- QScreen *s = qt_get_screen(qws_display_id, qws_display_spec.constData());
- if (s)
- sharedRamSize += s->memoryNeeded(QLatin1String(qws_display_spec.constData()));
-
-#ifndef QT_NO_QWS_MULTIPROCESS
-
- if (!shm.create(sharedRamSize)) {
- perror("Cannot create main ram shared memory\n");
- qFatal("Unable to allocate %d bytes of shared memory", sharedRamSize);
- }
- qt_servershmid = shm.id();
- sharedRam = static_cast<uchar *>(shm.address());
-#else
- sharedRam=static_cast<uchar *>(malloc(sharedRamSize));
-#endif
- // Need to zero index count at end of block, might as well zero
- // the rest too
- memset(sharedRam,0,sharedRamSize);
-
- QWSIdentifyCommand cmd;
- cmd.setId(appName, -1);
- qt_server_enqueue(&cmd);
- }
-
- // Allow some memory for the graphics driver too
- //### Note that sharedRamSize() has side effects; it must be called
- //### once, and only once, and before initDevice()
- sharedRamSize -= qt_screen->sharedRamSize(sharedRam+sharedRamSize);
-
-#ifndef QT_NO_QWS_MULTIPROCESS
- if(!csocket)
-#endif
- {
- //QWS server process
- if (!qt_screen->initDevice())
- qFatal("Unable to initialize screen driver!");
- }
-
- sharedRamSize -= sizeof(int);
- qt_last_x = reinterpret_cast<int *>(sharedRam + sharedRamSize);
- sharedRamSize -= sizeof(int);
- qt_last_y = reinterpret_cast<int *>(sharedRam + sharedRamSize);
-
- /* Initialise framebuffer memory manager */
- /* Add 4k for luck and to avoid clobbering hardware cursor */
-// int screensize=qt_screen->screenSize();
-// memorymanager=new QMemoryManager(qt_screen->base()+screensize+4096,
-// qt_screen->totalSize()-(screensize+4096),0);
-
-// #ifndef QT_NO_QWS_MULTIPROCESS
-// rgnMan = new QWSRegionManager(pipe, csocket);
-// #else
-// rgnMan = new QWSRegionManager(pipe, 0); //####### not necessary
-// #endif
-#ifndef QT_NO_QWS_MULTIPROCESS
- if (csocket)
- csocket->flush();
-#endif
-}
-
-
-QWSEvent* QWSDisplay::Data::readMore()
-{
-#ifdef QT_NO_QWS_MULTIPROCESS
- return incoming.isEmpty() ? 0 : incoming.takeFirst();
-#else
- if (!csocket)
- return incoming.isEmpty() ? 0 : incoming.takeFirst();
- // read next event
- if (!current_event) {
- int event_type = qws_read_uint(csocket);
-
- if (event_type >= 0) {
- current_event = QWSEvent::factory(event_type);
- }
- }
-
- if (current_event) {
- if (current_event->read(csocket)) {
- // Finished reading a whole event.
- QWSEvent* result = current_event;
- current_event = 0;
- return result;
- }
- }
-
- // Not finished reading a whole event.
- return 0;
-#endif
-}
-
-void QWSDisplay::Data::fillQueue()
-{
- QWSServer::processEventQueue();
- QWSEvent *e = readMore();
-#ifndef QT_NO_QWS_MULTIPROCESS
- int bytesAvailable = csocket ? csocket->bytesAvailable() : 0;
- int bytesRead = 0;
-#endif
- while (e) {
-#ifndef QT_NO_QWS_MULTIPROCESS
- bytesRead += QWS_PROTOCOL_ITEM_SIZE((*e));
-#endif
- if (e->type == QWSEvent::Connected) {
- connected_event = static_cast<QWSConnectedEvent *>(e);
- return;
- } else if (e->type == QWSEvent::Creation) {
- QWSCreationEvent *ce = static_cast<QWSCreationEvent*>(e);
- int id = ce->simpleData.objectid;
- int count = ce->simpleData.count;
- for (int i = 0; i < count; ++i)
- unused_identifiers.append(id++);
- delete e;
- } else if (e->type == QWSEvent::Mouse) {
- if (!qt_screen) {
- delete e;
- } else {
- QWSMouseEvent *me = static_cast<QWSMouseEvent*>(e);
- if (mouseFilter)
- mouseFilter(me);
-#ifdef QAPPLICATION_EXTRA_DEBUG
- static const char *defaultAction= "INITIAL";
- const char * action = defaultAction;
-#endif
- delete mouse_event;
- if (mouse_winid != me->window ()
- || mouse_state != me->simpleData.state) {
- queue.append(me);
- mouse_winid = me->window();
- mouse_state = me->simpleData.state;
- mouse_event = 0;
-#ifdef QAPPLICATION_EXTRA_DEBUG
- mouse_event_count = 0;
- action = "ENQUEUE";
-#endif
- } else {
-#ifdef QAPPLICATION_EXTRA_DEBUG
- if (mouse_event)
- action = "COMPRESS";
- mouse_event_count++;
-#endif
- mouse_event = me;
- }
-#ifdef QAPPLICATION_EXTRA_DEBUG
- if (me->simpleData.state !=0 || action != defaultAction || mouse_event_count != 0)
- qDebug("fillQueue %s (%d,%d), state %x win %d count %d", action,
- me->simpleData.x_root, me->simpleData.y_root, me->simpleData.state,
- me->window(), mouse_event_count);
-#endif
- }
-#ifndef QT_NO_QWS_MULTIPROCESS
- } else if (e->type == QWSEvent::Region && clientLock) {
- // not really an unlock, decrements the semaphore
- region_events_count++;
- clientLock->unlock(QWSLock::RegionEvent);
- queue.append(e);
-#endif
-#ifndef QT_NO_QWS_PROPERTIES
- } else if (e->type == QWSEvent::PropertyReply) {
- QWSPropertyReplyEvent *pe = static_cast<QWSPropertyReplyEvent*>(e);
- int len = pe->simpleData.len;
- char *data;
- if (len <= 0) {
- data = 0;
- } else {
- data = new char[len];
- memcpy(data, pe->data, len) ;
- }
- QPaintDevice::qwsDisplay()->getPropertyLen = len;
- QPaintDevice::qwsDisplay()->getPropertyData = data;
- delete e;
-#endif // QT_NO_QWS_PROPERTIES
- } else if (e->type==QWSEvent::MaxWindowRect && qt_screen) {
- // Process this ASAP, in case new widgets are created (startup)
- setMaxWindowRect((static_cast<QWSMaxWindowRectEvent*>(e))->simpleData.rect);
- delete e;
-#ifndef QT_NO_QWS_DYNAMICSCREENTRANSFORMATION
- } else if (e->type == QWSEvent::ScreenTransformation) {
- QWSScreenTransformationEvent *pe = static_cast<QWSScreenTransformationEvent*>(e);
- setScreenTransformation(pe->simpleData.screen,
- pe->simpleData.transformation);
- delete e;
-#endif
-#ifndef QT_NO_COP
- } else if (e->type == QWSEvent::QCopMessage) {
- QWSQCopMessageEvent *pe = static_cast<QWSQCopMessageEvent*>(e);
- if (pe->simpleData.is_response) {
- qcop_response = pe;
- } else {
- queue.append(e);
- }
-#endif
- } else {
- queue.append(e);
- }
- //debugQueue();
-#ifndef QT_NO_QWS_MULTIPROCESS
- if (csocket && bytesRead >= bytesAvailable)
- break;
-#endif
- e = readMore();
- }
-}
-
-#ifndef QT_NO_QWS_MULTIPROCESS
-
-static int qws_connection_timeout = 5;
-
-void QWSDisplay::Data::connectToPipe()
-{
- Q_ASSERT(csocket);
-
- int timeout = qgetenv("QWS_CONNECTION_TIMEOUT").toInt();
- if (timeout)
- qws_connection_timeout = timeout;
-
- const QString pipe = qws_qtePipeFilename();
- int i = 0;
- while (!csocket->connectToLocalFile(pipe)) {
- if (++i > qws_connection_timeout) {
- qWarning("No Qt for Embedded Linux server appears to be running.");
- qWarning("If you want to run this program as a server,");
- qWarning("add the \"-qws\" command-line option.");
- exit(1);
- }
- sleep(1);
- }
-}
-
-void QWSDisplay::Data::waitForConnection()
-{
- connected_event = 0;
-
- for (int i = 0; i < qws_connection_timeout; i++) {
- fillQueue();
- if (connected_event)
- return;
- csocket->flush();
- csocket->waitForReadyRead(1000);
- }
-
- csocket->flush();
- if (!connected_event)
- qFatal("Did not receive a connection event from the qws server");
-}
-
-void QWSDisplay::Data::waitForRegionAck(int winId)
-{
- QWSEvent *ack = 0;
-
- if (csocket) { // GuiClient
- int i = 0;
- while (!ack) {
- fillQueue();
-
- while (i < queue.size()) {
- QWSEvent *e = queue.at(i);
- if (e->type == QWSEvent::Region && e->window() == winId) {
- ack = e;
- queue.removeAt(i);
- break;
- }
- ++i;
- }
-
- if (!ack) {
- csocket->flush();
- csocket->waitForReadyRead(1000);
- }
- }
- } else { // GuiServer
- fillQueue();
- for (int i = 0; i < queue.size(); /* nothing */) {
- QWSEvent *e = queue.at(i);
- if (e->type == QWSEvent::Region && e->window() == winId) {
- ack = e;
- queue.removeAt(i);
- break;
- }
- ++i;
- }
- if (!ack) // already processed
- return;
- }
-
- Q_ASSERT(ack);
-
- qApp->qwsProcessEvent(ack);
- delete ack;
- region_events_count--;
-}
-
-void QWSDisplay::Data::waitForRegionEvents(int winId, bool ungrabDisplay)
-{
- if (!clientLock)
- return;
-
- int removedEventsCount = 0;
-
- // fill queue with unreceived region events
- if (!clientLock->hasLock(QWSLock::RegionEvent)) {
- bool ungrabbed = false;
- if (ungrabDisplay && QWSDisplay::grabbed()) {
- QWSDisplay::ungrab();
- ungrabbed = true;
- }
-
- for (;;) {
- fillQueue();
- if (clientLock->hasLock(QWSLock::RegionEvent))
- break;
- csocket->flush();
- csocket->waitForReadyRead(1000);
- }
-
- if (ungrabbed)
- QWSDisplay::grab(true);
- }
-
- // check the queue for pending region events
- QWSEvent *regionEvent = 0;
- for (int i = 0; i < queue.size(); /* nothing */) {
- QWSEvent *e = queue.at(i);
- if (e->type == QWSEvent::Region && e->window() == winId) {
- QWSRegionEvent *re = static_cast<QWSRegionEvent*>(e);
- if (re->simpleData.type == QWSRegionEvent::Allocation) {
- delete regionEvent;
- regionEvent = re;
- }
- queue.removeAt(i);
- removedEventsCount++;
- } else {
- ++i;
- }
- }
-
- if (regionEvent) {
- qApp->qwsProcessEvent(regionEvent);
- delete regionEvent;
- }
- region_events_count -= removedEventsCount;
-}
-
-bool QWSDisplay::Data::hasPendingRegionEvents() const
-{
- if (clientLock && !clientLock->hasLock(QWSLock::RegionEvent))
- return true;
-
- return region_events_count > 0;
-}
-
-#endif // QT_NO_QWS_MULTIPROCESS
-
-void QWSDisplay::Data::waitForCreation()
-{
- fillQueue();
-#ifndef QT_NO_QWS_MULTIPROCESS
- while (unused_identifiers.count() == 0) {
- if (csocket) {
- csocket->flush();
- csocket->waitForReadyRead(1000);
- }
- fillQueue();
- }
-#endif
-}
-
-
-#ifndef QT_NO_QWS_MULTIPROCESS
-void QWSDisplay::Data::waitForPropertyReply()
-{
- if (!csocket)
- return;
- fillQueue();
- while (qt_fbdpy->getPropertyLen == -2) {
- csocket->flush();
- csocket->waitForReadyRead(1000);
- fillQueue();
- }
-}
-#endif
-
-#ifndef QT_NO_COP
-void QWSDisplay::Data::waitForQCopResponse()
-{
- for (;;) {
- fillQueue();
- if (qcop_response)
- break;
-#ifndef QT_NO_QWS_MULTIPROCESS
- if (csocket) {
- csocket->flush();
- csocket->waitForReadyRead(1000);
- }
-#endif
- }
- queue.prepend(qcop_response);
- qcop_response = 0;
-}
-#endif
-
-/*!
- \class QWSDisplay
- \brief The QWSDisplay class provides a display for QWS; it is an internal class.
-
- \internal
-
- \ingroup qws
-*/
-
-QWSDisplay::QWSDisplay()
-{
- d = new Data(0, qws_single_process);
-}
-
-QWSDisplay::~QWSDisplay()
-{
- delete d;
- delete lock;
- lock = 0;
-}
-
-bool QWSDisplay::grabbed()
-{
- return lock->locked();
-}
-
-void QWSDisplay::grab()
-{
- lock->lock(QLock::Read);
-}
-
-void QWSDisplay::grab(bool write)
-{
- lock->lock(write ? QLock::Write : QLock::Read);
-
-}
-void QWSDisplay::ungrab()
-{
- lock->unlock();
-}
-
-#if 0
-QWSRegionManager *QWSDisplay::regionManager() const
-{
- return d->rgnMan;
-}
-#endif
-
-bool QWSDisplay::eventPending() const
-{
-#ifndef QT_NO_QWS_MULTIPROCESS
- d->flush();
-#endif
- d->fillQueue();
- return d->queueNotEmpty();
-}
-
-
-/*
- Caller must delete return value!
- */
-QWSEvent *QWSDisplay::getEvent()
-{
- d->fillQueue();
- Q_ASSERT(d->queueNotEmpty());
- QWSEvent* e = d->dequeue();
-
- return e;
-}
-
-uchar* QWSDisplay::frameBuffer() const { return qt_screen->base(); }
-int QWSDisplay::width() const { return qt_screen->width(); }
-int QWSDisplay::height() const { return qt_screen->height(); }
-int QWSDisplay::depth() const { return qt_screen->depth(); }
-int QWSDisplay::pixmapDepth() const { return qt_screen->pixmapDepth(); }
-bool QWSDisplay::supportsDepth(int depth) const { return qt_screen->supportsDepth(depth); }
-uchar *QWSDisplay::sharedRam() const { return d->sharedRam; }
-int QWSDisplay::sharedRamSize() const { return d->sharedRamSize; }
-
-#ifndef QT_NO_QWS_PROPERTIES
-
-void QWSDisplay::addProperty(int winId, int property)
-{
- QWSAddPropertyCommand cmd;
- cmd.simpleData.windowid = winId;
- cmd.simpleData.property = property;
- d->sendCommand(cmd);
-}
-
-void QWSDisplay::setProperty(int winId, int property, int mode, const QByteArray &data)
-{
- QWSSetPropertyCommand cmd;
- cmd.simpleData.windowid = winId;
- cmd.simpleData.property = property;
- cmd.simpleData.mode = mode;
- cmd.setData(data.constData(), data.size());
- d->sendCommand(cmd);
-}
-
-void QWSDisplay::setProperty(int winId, int property, int mode,
- const char * data)
-{
- QWSSetPropertyCommand cmd;
- cmd.simpleData.windowid = winId;
- cmd.simpleData.property = property;
- cmd.simpleData.mode = mode;
- cmd.setData(data, strlen(data));
- d->sendCommand(cmd);
-}
-
-void QWSDisplay::removeProperty(int winId, int property)
-{
- QWSRemovePropertyCommand cmd;
- cmd.simpleData.windowid = winId;
- cmd.simpleData.property = property;
- d->sendCommand(cmd);
-}
-
-/*
- It is the caller's responsibility to delete[] \a data.
- */
-bool QWSDisplay::getProperty(int winId, int property, char *&data, int &len)
-{
- if (d->directServerConnection()) {
- const char *propertyData;
- bool retval = qwsServer->d_func()->get_property(winId, property, propertyData, len);
- if (len <= 0) {
- data = 0;
- } else {
- data = new char[len];
- memcpy(data, propertyData, len) ;
- }
- return retval;
- }
- QWSGetPropertyCommand cmd;
- cmd.simpleData.windowid = winId;
- cmd.simpleData.property = property;
- d->sendCommand(cmd);
-
- getPropertyLen = -2;
- getPropertyData = 0;
-
-#ifndef QT_NO_QWS_MULTIPROCESS
- d->waitForPropertyReply();
-#endif
-
- len = getPropertyLen;
- data = getPropertyData;
-
- getPropertyLen = -2;
- getPropertyData = 0;
-
- return len != -1;
-}
-
-#endif // QT_NO_QWS_PROPERTIES
-
-void QWSDisplay::setAltitude(int winId, int alt, bool fixed)
-{
- QWSChangeAltitudeCommand cmd;
-#ifdef QT_DEBUG
- memset(cmd.simpleDataPtr, 0, sizeof(cmd.simpleData)); //shut up Valgrind
-#endif
- cmd.simpleData.windowid = winId;
- cmd.simpleData.altitude = QWSChangeAltitudeCommand::Altitude(alt);
- cmd.simpleData.fixed = fixed;
- if (d->directServerConnection()) {
- qwsServer->d_func()->set_altitude(&cmd);
- } else {
- d->sendSynchronousCommand(cmd);
- }
-}
-
-void QWSDisplay::setOpacity(int winId, int opacity)
-{
- QWSSetOpacityCommand cmd;
- cmd.simpleData.windowid = winId;
- cmd.simpleData.opacity = opacity;
- if (d->directServerConnection()) {
- qwsServer->d_func()->set_opacity(&cmd);
- } else {
- d->sendCommand(cmd);
- }
-}
-
-
-
-void QWSDisplay::requestFocus(int winId, bool get)
-{
- QWSRequestFocusCommand cmd;
- cmd.simpleData.windowid = winId;
- cmd.simpleData.flag = get;
- if (d->directServerConnection())
- qwsServer->d_func()->request_focus(&cmd);
- else
- d->sendCommand(cmd);
-}
-
-void QWSDisplay::setIdentity(const QString &appName)
-{
- QWSIdentifyCommand cmd;
-#ifdef QT_NO_QWS_MULTIPROCESS
- const int id = -1;
-#else
- const int id = QWSDisplay::Data::clientLock ? QWSDisplay::Data::clientLock->id() : -1;
-#endif
- cmd.setId(appName, id);
- if (d->directServerConnection())
- qwsServer->d_func()->set_identity(&cmd);
- else
- d->sendCommand(cmd);
-}
-
-void QWSDisplay::nameRegion(int winId, const QString& n, const QString &c)
-{
- QWSRegionNameCommand cmd;
- cmd.simpleData.windowid = winId;
- cmd.setName(n, c);
- if (d->directServerConnection())
- qwsServer->d_func()->name_region(&cmd);
- else
- d->sendCommand(cmd);
-}
-
-void QWSDisplay::requestRegion(int winId, const QString &surfaceKey,
- const QByteArray &surfaceData,
- const QRegion &region)
-{
- if (d->directServerConnection()) {
- qwsServer->d_func()->request_region(winId, surfaceKey,
- surfaceData, region);
- } else {
- QWSRegionCommand cmd;
- cmd.setData(winId, surfaceKey, surfaceData, region);
- d->sendSynchronousCommand(cmd);
- }
-}
-
-void QWSDisplay::repaintRegion(int winId, int windowFlags, bool opaque, QRegion r)
-{
- if (d->directServerConnection()) {
- qwsServer->d_func()->repaint_region(winId, windowFlags, opaque, r);
- } else {
- QVector<QRect> ra = r.rects();
-
- /*
- for (int i = 0; i < ra.size(); i++) {
- QRect r(ra[i]);
- qDebug("rect: %d %d %d %d", r.x(), r.y(), r.right(), r.bottom());
- }
- */
-
- QWSRepaintRegionCommand cmd;
- /* XXX QWSRegionCommand is padded out in a compiler dependent way.
- Zeroed out to avoid valgrind reporting uninitialized memory usage.
- */
-#ifdef QT_DEBUG
- memset(cmd.simpleDataPtr, 0, sizeof(cmd.simpleData)); //shut up Valgrind
-#endif
- cmd.simpleData.windowid = winId;
- cmd.simpleData.windowFlags = windowFlags;
- cmd.simpleData.opaque = opaque;
- cmd.simpleData.nrectangles = ra.count();
- cmd.setData(reinterpret_cast<const char *>(ra.constData()),
- ra.count() * sizeof(QRect), false);
-
- d->sendSynchronousCommand(cmd);
- }
-}
-
-
-void QWSDisplay::moveRegion(int winId, int dx, int dy)
-{
- QWSRegionMoveCommand cmd;
- cmd.simpleData.windowid = winId;
- cmd.simpleData.dx = dx;
- cmd.simpleData.dy = dy;
-
- if (d->directServerConnection()) {
- qwsServer->d_func()->move_region(&cmd);
- } else {
- d->sendSynchronousCommand(cmd);
- }
-// d->offsetPendingExpose(winId, QPoint(cmd.simpleData.dx, cmd.simpleData.dy));
-}
-
-void QWSDisplay::destroyRegion(int winId)
-{
- QWSRegionDestroyCommand cmd;
- cmd.simpleData.windowid = winId;
- if (d->directServerConnection()) {
- qwsServer->d_func()->destroy_region(&cmd);
- } else {
- d->sendCommand(cmd);
- }
-}
-
-#ifndef QT_NO_QWS_INPUTMETHODS
-
-void QWSDisplay::sendIMUpdate(int type, int winId, int widgetid)
-{
- QWSIMUpdateCommand cmd;
- cmd.simpleData.windowid = winId;
- cmd.simpleData.widgetid = widgetid;
-
- cmd.simpleData.type = type;
-
- if (d->directServerConnection()) {
- qwsServer->d_func()->im_update(&cmd);
- } else {
- d->sendCommand(cmd);
- }
-}
-
-void QWSDisplay::sendIMResponse(int winId, int property, const QVariant &result)
-{
- QWSIMResponseCommand cmd;
- cmd.simpleData.windowid = winId;
- cmd.simpleData.property = property;
-
- cmd.setResult(result);
-
- if (d->directServerConnection()) {
- qwsServer->d_func()->im_response(&cmd);
- } else {
- d->sendCommand(cmd);
- }
-}
-
-void QWSDisplay::resetIM()
-{
- sendIMUpdate(QWSInputMethod::Reset, -1, -1);
-}
-
-void QWSDisplay::sendIMMouseEvent(int index, bool isPress)
-{
- QWSIMMouseCommand cmd;
- cmd.simpleData.index = index;
- cmd.simpleData.state = isPress ? QWSServer::MousePress : QWSServer::MouseRelease;
- if (d->directServerConnection()) {
- qwsServer->d_func()->send_im_mouse(&cmd);
- } else {
- d->sendCommand(cmd);
- }
-}
-
-#endif
-
-int QWSDisplay::takeId()
-{
- return d->takeId();
-}
-
-bool QWSDisplay::initLock(const QString &filename, bool create)
-{
- if (!lock) {
- lock = new QLock(filename, 'd', create);
-
- if (!lock->isValid()) {
- delete lock;
- lock = 0;
- return false;
- }
- }
-
- return true;
-}
-
-void QWSDisplay::setSelectionOwner(int winId, const QTime &time)
-{
- QWSSetSelectionOwnerCommand cmd;
- cmd.simpleData.windowid = winId;
- cmd.simpleData.hour = time.hour();
- cmd.simpleData.minute = time.minute();
- cmd.simpleData.sec = time.second();
- cmd.simpleData.ms = time.msec();
- d->sendCommand(cmd);
-}
-
-void QWSDisplay::convertSelection(int winId, int selectionProperty, const QString &mimeTypes)
-{
-#ifdef QT_NO_QWS_PROPERTIES
- Q_UNUSED(mimeTypes);
-#else
- // ### we need the atom/property thingy like in X here
- addProperty(winId, QT_QWS_PROPERTY_CONVERTSELECTION);
- setProperty(winId, QT_QWS_PROPERTY_CONVERTSELECTION,
- int(QWSPropertyManager::PropReplace), mimeTypes.toLatin1());
-#endif
- QWSConvertSelectionCommand cmd;
- cmd.simpleData.requestor = winId;
- cmd.simpleData.selection = selectionProperty;
- cmd.simpleData.mimeTypes = QT_QWS_PROPERTY_CONVERTSELECTION;
- d->sendCommand(cmd);
-}
-
-void QWSDisplay::defineCursor(int id, const QBitmap &curs, const QBitmap &mask,
- int hotX, int hotY)
-{
- const QImage cursImg = curs.toImage().convertToFormat(QImage::Format_MonoLSB);
- const QImage maskImg = mask.toImage().convertToFormat(QImage::Format_MonoLSB);
-
- QWSDefineCursorCommand cmd;
- cmd.simpleData.width = curs.width();
- cmd.simpleData.height = curs.height();
- cmd.simpleData.hotX = hotX;
- cmd.simpleData.hotY = hotY;
- cmd.simpleData.id = id;
-
-
- // must copy each scanline since there might be gaps between them
- const int height = curs.height();
- const int width = curs.width();
- const int dst_bpl = (width + 7) / 8;
-
- int dataLen = dst_bpl * height;
- uchar *data = new uchar[dataLen*2];
- uchar *dst = data;
-
- int src_bpl = cursImg.bytesPerLine();
- const uchar *cursSrc = cursImg.bits();
- for (int i = 0; i < height; ++i) {
- memcpy(dst, cursSrc + i*src_bpl, dst_bpl);
- dst += dst_bpl;
- }
-
- src_bpl = maskImg.bytesPerLine();
- const uchar *maskSrc = maskImg.bits();
- for (int i = 0; i < height; ++i) {
- memcpy(dst, maskSrc + i*src_bpl, dst_bpl);
- dst += dst_bpl;
- }
-
- cmd.setData(reinterpret_cast<char*>(data), dataLen*2);
- delete [] data;
- d->sendCommand(cmd);
-}
-
-void QWSDisplay::destroyCursor(int id)
-{
- QWSDefineCursorCommand cmd;
- cmd.simpleData.width = 0;
- cmd.simpleData.height = 0;
- cmd.simpleData.hotX = 0;
- cmd.simpleData.hotY = 0;
- cmd.simpleData.id = id;
- cmd.setData(0, 0);
-
- d->sendCommand(cmd);
-}
-
-#ifndef QT_NO_SOUND
-void QWSDisplay::playSoundFile(const QString& f)
-{
- QWSPlaySoundCommand cmd;
- cmd.setFileName(f);
- d->sendCommand(cmd);
-}
-#endif
-
-#ifndef QT_NO_COP
-void QWSDisplay::registerChannel(const QString& channel)
-{
- QWSQCopRegisterChannelCommand reg;
- reg.setChannel(channel);
- qt_fbdpy->d->sendCommand(reg);
-}
-
-void QWSDisplay::sendMessage(const QString &channel, const QString &msg,
- const QByteArray &data)
-{
- QWSQCopSendCommand com;
- com.setMessage(channel, msg, data);
- qt_fbdpy->d->sendCommand(com);
-}
-
-void QWSDisplay::flushCommands()
-{
- qt_fbdpy->d->flushCommands();
-}
-
-/*
- caller deletes result
-*/
-QWSQCopMessageEvent* QWSDisplay::waitForQCopResponse()
-{
- qt_fbdpy->d->waitForQCopResponse();
- QWSQCopMessageEvent *e = static_cast<QWSQCopMessageEvent*>(qt_fbdpy->d->dequeue());
- Q_ASSERT(e->type == QWSEvent::QCopMessage);
- return e;
-}
-#endif
-
-void QWSDisplay::sendFontCommand(int type, const QByteArray &fontName)
-{
- QWSFontCommand cmd;
- cmd.simpleData.type = type;
- cmd.setFontName(fontName);
- d->sendCommand(cmd);
-}
-
-void QWSDisplay::setWindowCaption(QWidget *w, const QString &c)
-{
- if (w->isWindow()) {
- nameRegion(w->internalWinId(), w->objectName(), c);
- static_cast<QETWidget *>(w)->repaintDecoration(qApp->desktop()->rect(), true);
- }
-}
-
-void QWSDisplay::selectCursor(QWidget *w, unsigned int cursId)
-{
- if (cursId != qt_last_cursor)
- {
- QWidget *top = w->window();
- qt_last_cursor = cursId;
- QWSSelectCursorCommand cmd;
- cmd.simpleData.windowid = top->internalWinId();
- cmd.simpleData.id = cursId;
- d->sendCommand(cmd);
- d->flush();
- }
-}
-
-void QWSDisplay::setCursorPosition(int x, int y)
-{
- QWSPositionCursorCommand cmd;
- cmd.simpleData.newX = x;
- cmd.simpleData.newY = y;
- d->sendCommand(cmd);
- d->flush();
-}
-
-void QWSDisplay::grabMouse(QWidget *w, bool grab)
-{
- QWidget *top = w->window();
- QWSGrabMouseCommand cmd;
-#ifdef QT_DEBUG
- memset(cmd.simpleDataPtr, 0, sizeof(cmd.simpleData)); //shut up Valgrind
-#endif
- cmd.simpleData.windowid = top->winId();
- cmd.simpleData.grab = grab;
- d->sendCommand(cmd);
- d->flush();
-}
-
-void QWSDisplay::grabKeyboard(QWidget *w, bool grab)
-{
- QWidget *top = w->window();
- QWSGrabKeyboardCommand cmd;
-#ifdef QT_DEBUG
- memset(cmd.simpleDataPtr, 0, sizeof(cmd.simpleData)); //shut up Valgrind
-#endif
- cmd.simpleData.windowid = top->winId();
- cmd.simpleData.grab = grab;
- d->sendCommand(cmd);
- d->flush();
-}
-
-QList<QWSWindowInfo> QWSDisplay::windowList()
-{
- QList<QWSWindowInfo> ret;
- if(d->directServerConnection()) {
- QList<QWSInternalWindowInfo*> * qin=QWSServer::windowList();
- for (int i = 0; i < qin->count(); ++i) {
- QWSInternalWindowInfo * qwi = qin->at(i);
- QWSWindowInfo tmp;
- tmp.winid = qwi->winid;
- tmp.clientid = qwi->clientid;
- tmp.name = QString(qwi->name);
- ret.append(tmp);
- }
- qDeleteAll(*qin);
- delete qin;
- }
- return ret;
-}
-
-int QWSDisplay::windowAt(const QPoint &p)
-{
- //### currently only implemented for the server process
- int ret = 0;
- if(d->directServerConnection()) {
- QWSWindow *win = qwsServer->windowAt(p);
- if (win)
- return win->winId();
- }
- return ret;
-}
-
-void QWSDisplay::setRawMouseEventFilter(void (*filter)(QWSMouseEvent *))
-{
- if (qt_fbdpy)
- qt_fbdpy->d->setMouseFilter(filter);
-}
-
-/*!
- \relates QScreen
-
- Here it is. \a transformation and \a screenNo
- */
-void QWSDisplay::setTransformation(int transformation, int screenNo)
-{
- QWSScreenTransformCommand cmd;
- cmd.setTransformation(screenNo, transformation);
- QWSDisplay::instance()->d->sendCommand(cmd);
-}
-
-static bool qt_try_modal(QWidget *, QWSEvent *);
-
-/*****************************************************************************
- qt_init() - initializes Qt/FB
- *****************************************************************************/
-
-static void qt_set_qws_resources()
-
-{
- if (QApplication::desktopSettingsAware())
- QApplicationPrivate::qws_apply_settings();
-
- if (appFont)
- QApplication::setFont(QFont(QString::fromLocal8Bit(appFont)));
-
- if (appBGCol || appBTNCol || appFGCol) {
- (void) QApplication::style(); // trigger creation of application style and system palettes
- QColor btn;
- QColor bg;
- QColor fg;
- if (appBGCol)
- bg = QColor(appBGCol);
- else
- bg = QApplicationPrivate::sys_pal->color(QPalette::Window);
- if (appFGCol)
- fg = QColor(appFGCol);
- else
- fg = QApplicationPrivate::sys_pal->color(QPalette::WindowText);
- if (appBTNCol)
- btn = QColor(appBTNCol);
- else
- btn = QApplicationPrivate::sys_pal->color(QPalette::Button);
-
- int h,s,v;
- fg.getHsv(&h,&s,&v);
- QColor base = Qt::white;
- bool bright_mode = false;
- if (v >= 255 - 50) {
- base = btn.darker(150);
- bright_mode = true;
- }
-
- QPalette pal(fg, btn, btn.lighter(), btn.darker(), btn.darker(150), fg, Qt::white, base, bg);
- if (bright_mode) {
- pal.setColor(QPalette::HighlightedText, base);
- pal.setColor(QPalette::Highlight, Qt::white);
- } else {
- pal.setColor(QPalette::HighlightedText, Qt::white);
- pal.setColor(QPalette::Highlight, Qt::darkBlue);
- }
- QColor disabled((fg.red() + btn.red()) / 2,
- (fg.green() + btn.green())/ 2,
- (fg.blue() + btn.blue()) / 2);
- pal.setColorGroup(QPalette::Disabled, disabled, btn, btn.lighter(125),
- btn.darker(), btn.darker(150), disabled, Qt::white, Qt::white, bg);
- if (bright_mode) {
- pal.setColor(QPalette::Disabled, QPalette::HighlightedText, base);
- pal.setColor(QPalette::Disabled, QPalette::Highlight, Qt::white);
- } else {
- pal.setColor(QPalette::Disabled, QPalette::HighlightedText, Qt::white);
- pal.setColor(QPalette::Disabled, QPalette::Highlight, Qt::darkBlue);
- }
- QApplicationPrivate::setSystemPalette(pal);
-
- }
-}
-
-void QApplicationPrivate::initializeWidgetPaletteHash()
-{
-}
-
-/*! \internal
- apply the settings to the application
-*/
-bool QApplicationPrivate::qws_apply_settings()
-{
-#ifndef QT_NO_SETTINGS
- QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
- settings.beginGroup(QLatin1String("Qt"));
-
- QStringList strlist;
- int i;
- QPalette pal(Qt::black);
- int groupCount = 0;
- strlist = settings.value(QLatin1String("Palette/active")).toStringList();
- if (strlist.count() == QPalette::NColorRoles) {
- ++groupCount;
- for (i = 0; i < QPalette::NColorRoles; i++)
- pal.setColor(QPalette::Active, (QPalette::ColorRole) i,
- QColor(strlist[i]));
- }
- strlist = settings.value(QLatin1String("Palette/inactive")).toStringList();
- if (strlist.count() == QPalette::NColorRoles) {
- ++groupCount;
- for (i = 0; i < QPalette::NColorRoles; i++)
- pal.setColor(QPalette::Inactive, (QPalette::ColorRole) i,
- QColor(strlist[i]));
- }
- strlist = settings.value(QLatin1String("Palette/disabled")).toStringList();
- if (strlist.count() == QPalette::NColorRoles) {
- ++groupCount;
- for (i = 0; i < QPalette::NColorRoles; i++)
- pal.setColor(QPalette::Disabled, (QPalette::ColorRole) i,
- QColor(strlist[i]));
- }
-
-
- if (groupCount == QPalette::NColorGroups)
- QApplicationPrivate::setSystemPalette(pal);
-
- QString str = settings.value(QLatin1String("font")).toString();
- if (!str.isEmpty()) {
- QFont font(QApplication::font());
- font.fromString(str);
- QApplicationPrivate::setSystemFont(font);
- }
-
- // read library (ie. plugin) path list
- QString libpathkey =
- QString::fromLatin1("%1.%2/libraryPath")
- .arg(QT_VERSION >> 16)
- .arg((QT_VERSION & 0xff00) >> 8);
- QStringList pathlist = settings.value(libpathkey).toString().split(QLatin1Char(':'));
-#ifndef QT_NO_LIBRARY
- if (! pathlist.isEmpty()) {
- QStringList::ConstIterator it = pathlist.constBegin();
- while (it != pathlist.constEnd())
- QApplication::addLibraryPath(*it++);
- }
-#endif
-
- // read new QStyle
- QString stylename = settings.value(QLatin1String("style")).toString();
- if (QCoreApplication::startingUp()) {
- if (!stylename.isEmpty() && QApplicationPrivate::styleOverride.isNull())
- QApplicationPrivate::styleOverride = stylename;
- } else {
- QApplication::setStyle(stylename);
- }
-
- int num =
- settings.value(QLatin1String("doubleClickInterval"),
- QApplication::doubleClickInterval()).toInt();
- QApplication::setDoubleClickInterval(num);
-
- num =
- settings.value(QLatin1String("cursorFlashTime"),
- QApplication::cursorFlashTime()).toInt();
- QApplication::setCursorFlashTime(num);
-
-#ifndef QT_NO_WHEELEVENT
- num =
- settings.value(QLatin1String("wheelScrollLines"),
- QApplication::wheelScrollLines()).toInt();
- QApplication::setWheelScrollLines(num);
-#endif
-
- QString colorspec = settings.value(QLatin1String("colorSpec"),
- QVariant(QLatin1String("default"))).toString();
- if (colorspec == QLatin1String("normal"))
- QApplication::setColorSpec(QApplication::NormalColor);
- else if (colorspec == QLatin1String("custom"))
- QApplication::setColorSpec(QApplication::CustomColor);
- else if (colorspec == QLatin1String("many"))
- QApplication::setColorSpec(QApplication::ManyColor);
- else if (colorspec != QLatin1String("default"))
- colorspec = QLatin1String("default");
-
-#ifndef QT_NO_TEXTCODEC
- QString defaultcodec = settings.value(QLatin1String("defaultCodec"),
- QVariant(QLatin1String("none"))).toString();
- if (defaultcodec != QLatin1String("none")) {
- QTextCodec *codec = QTextCodec::codecForName(defaultcodec.toLatin1());
- if (codec)
- QTextCodec::setCodecForTr(codec);
- }
-#endif
-
- int w = settings.value(QLatin1String("globalStrut/width")).toInt();
- int h = settings.value(QLatin1String("globalStrut/height")).toInt();
- QSize strut(w, h);
- if (strut.isValid())
- QApplication::setGlobalStrut(strut);
-
- QStringList effects = settings.value(QLatin1String("GUIEffects")).toStringList();
- QApplication::setEffectEnabled(Qt::UI_General,
- effects.contains(QLatin1String("general")));
- QApplication::setEffectEnabled(Qt::UI_AnimateMenu,
- effects.contains(QLatin1String("animatemenu")));
- QApplication::setEffectEnabled(Qt::UI_FadeMenu,
- effects.contains(QLatin1String("fademenu")));
- QApplication::setEffectEnabled(Qt::UI_AnimateCombo,
- effects.contains(QLatin1String("animatecombo")));
- QApplication::setEffectEnabled(Qt::UI_AnimateTooltip,
- effects.contains(QLatin1String("animatetooltip")));
- QApplication::setEffectEnabled(Qt::UI_FadeTooltip,
- effects.contains(QLatin1String("fadetooltip")));
- QApplication::setEffectEnabled(Qt::UI_AnimateToolBox,
- effects.contains(QLatin1String("animatetoolbox")));
-
- settings.beginGroup(QLatin1String("Font Substitutions"));
- QStringList fontsubs = settings.childKeys();
- if (!fontsubs.isEmpty()) {
- QStringList::Iterator it = fontsubs.begin();
- for (; it != fontsubs.end(); ++it) {
- QString fam = *it;
- QStringList subs = settings.value(fam).toStringList();
- QFont::insertSubstitutions(fam, subs);
- }
- }
- settings.endGroup();
-
- settings.endGroup(); // Qt
-
- settings.beginGroup(QLatin1String("QWS Font Fallbacks"));
- if (!settings.childKeys().isEmpty()) {
- // from qfontdatabase_qws.cpp
- extern void qt_applyFontDatabaseSettings(const QSettings &);
- qt_applyFontDatabaseSettings(settings);
- }
- settings.endGroup();
-
- return true;
-#else
- return false;
-#endif // QT_NO_SETTINGS
-}
-
-
-
-static void init_display()
-{
- if (qt_fbdpy) return; // workaround server==client case
-
- // Connect to FB server
- qt_fbdpy = new QWSDisplay();
-
- // Get display parameters
- // Set paintdevice parameters
- // XXX initial info sent from server
- // Misc. initialization
-
- QColormap::initialize();
- QFont::initialize();
-#ifndef QT_NO_CURSOR
- QCursorData::initialize();
-#endif
-
- qApp->setObjectName(appName);
-
- if (!QApplicationPrivate::sys_font) {
-#ifdef QT_NO_FREETYPE
- QFont f = QFont(QLatin1String("helvetica"), 10);
-#else
- QFont f = QFont(QLatin1String("DejaVu Sans"), 12);
-#endif
- QApplicationPrivate::setSystemFont(f);
- }
- qt_set_qws_resources();
-}
-
-void qt_init_display()
-{
- qt_is_gui_used = true;
- qws_single_process = true;
- init_display();
-}
-
-static bool read_bool_env_var(const char *var, bool defaultvalue)
-{
- // returns true if env variable is set to non-zero
- // returns false if env var is set to zero
- // returns defaultvalue if env var not set
- char *x = ::getenv(var);
- return (x && *x) ? (strcmp(x,"0") != 0) : defaultvalue;
-}
-
-static int read_int_env_var(const char *var, int defaultvalue)
-{
- bool ok;
- int r = qgetenv(var).toInt(&ok);
- return ok ? r : defaultvalue;
-}
-
-void qt_init(QApplicationPrivate *priv, int type)
-{
-#ifdef QT_NO_QWS_MULTIPROCESS
- if (type == QApplication::GuiClient)
- type = QApplication::GuiServer;
-#endif
- if (type == QApplication::GuiServer)
- qt_is_gui_used = false; //we'll turn it on in a second
- qws_sw_cursor = read_bool_env_var("QWS_SW_CURSOR",qws_sw_cursor);
- qws_screen_is_interlaced = read_bool_env_var("QWS_INTERLACE",false);
-
- const char *display = ::getenv("QWS_DISPLAY");
- if (display)
- qws_display_spec = display; // since we setenv later!
-
- //qws_savefonts = qgetenv("QWS_SAVEFONTS") != 0;
- //qws_shared_memory = qgetenv("QWS_NOSHARED") == 0;
-
- mouse_double_click_distance = read_int_env_var("QWS_DBLCLICK_DISTANCE", 5);
-
- priv->inputContext = 0;
-
- int flags = 0;
- char *p;
- int argc = priv->argc;
- char **argv = priv->argv;
- int j;
-
- // Set application name
-
- if (argv && *argv) { //apparently, we allow people to pass 0 on the other platforms
- p = strrchr(argv[0], '/');
- appName = QString::fromLocal8Bit(p ? p + 1 : argv[0]);
- }
-
- // Get command line params
-
- j = argc ? 1 : 0;
- QString decoration;
- for (int i=1; i<argc; i++) {
- if (argv[i] && *argv[i] != '-') {
- argv[j++] = argv[i];
- continue;
- }
- QByteArray arg = argv[i];
- if (arg == "-fn" || arg == "-font") {
- if (++i < argc)
- appFont = argv[i];
- } else if (arg == "-bg" || arg == "-background") {
- if (++i < argc)
- appBGCol = argv[i];
- } else if (arg == "-btn" || arg == "-button") {
- if (++i < argc)
- appBTNCol = argv[i];
- } else if (arg == "-fg" || arg == "-foreground") {
- if (++i < argc)
- appFGCol = argv[i];
- } else if (arg == "-name") {
- if (++i < argc)
- appName = QString::fromLocal8Bit(argv[i]);
- } else if (arg == "-title") {
- if (++i < argc)
- mwTitle = argv[i];
- } else if (arg == "-geometry") {
- if (++i < argc)
- mwGeometry = argv[i];
- } else if (arg == "-shared") {
- qws_shared_memory = true;
- } else if (arg == "-noshared") {
- qws_shared_memory = false;
- } else if (arg == "-savefonts") {
- qws_savefonts = true;
- } else if (arg == "-nosavefonts") {
- qws_savefonts = false;
- } else if (arg == "-swcursor") {
- qws_sw_cursor = true;
- } else if (arg == "-noswcursor") {
- qws_sw_cursor = false;
- } else if (arg == "-keyboard") {
- flags &= ~QWSServer::DisableKeyboard;
- } else if (arg == "-nokeyboard") {
- flags |= QWSServer::DisableKeyboard;
- } else if (arg == "-mouse") {
- flags &= ~QWSServer::DisableMouse;
- } else if (arg == "-nomouse") {
- flags |= QWSServer::DisableMouse;
- } else if (arg == "-qws") {
- type = QApplication::GuiServer;
- } else if (arg == "-interlaced") {
- qws_screen_is_interlaced = true;
- } else if (arg == "-display") {
- if (++i < argc)
- qws_display_spec = argv[i];
- } else if (arg == "-decoration") {
- if (++i < argc)
- decoration = QString::fromLocal8Bit(argv[i]);
- } else {
- argv[j++] = argv[i];
- }
- }
- if(j < priv->argc) {
- priv->argv[j] = 0;
- priv->argc = j;
- }
-
- mouseInWidget = new QPointer<QWidget>;
-
- const QString disp = QString::fromLatin1(qws_display_spec);
- QRegExp regexp(QLatin1String(":(\\d+)$"));
- if (regexp.lastIndexIn(disp) != -1) {
- const QString capture = regexp.cap(1);
- bool ok = false;
- int id = capture.toInt(&ok);
- if (ok)
- qws_display_id = id;
- }
-
- if (type == QApplication::GuiServer) {
- qt_appType = QApplication::Type(type);
- qws_single_process = true;
- QWSServer::startup(flags);
- if (!display) // if not already set
- qputenv("QWS_DISPLAY", qws_display_spec);
- }
-
- if(qt_is_gui_used) {
- init_display();
-#ifndef QT_NO_QWS_MANAGER
- if (decoration.isEmpty() && !qws_decoration) {
- const QStringList keys = QDecorationFactory::keys();
- if (!keys.isEmpty())
- decoration = keys.first();
- }
- if (!decoration.isEmpty())
- qws_decoration = QApplication::qwsSetDecoration(decoration);
-#endif // QT_NO_QWS_MANAGER
-#ifndef QT_NO_QWS_INPUTMETHODS
- qApp->setInputContext(new QWSInputContext(qApp));
-#endif
- }
-
-/*### convert interlace style
- if (qws_screen_is_interlaced)
- QApplication::setStyle(new QInterlaceStyle);
-*/
-}
-
-/*****************************************************************************
- qt_cleanup() - cleans up when the application is finished
- *****************************************************************************/
-
-void qt_cleanup()
-{
- QPixmapCache::clear();
-#ifndef QT_NO_CURSOR
- QCursorData::cleanup();
-#endif
- QFont::cleanup();
- QColormap::cleanup();
-
- if (qws_single_process) {
- QWSServer::closedown();
- }
-
- qDeleteAll(outgoing);
- outgoing.clear();
- qDeleteAll(incoming);
- incoming.clear();
-
- if (qt_is_gui_used) {
- delete qt_fbdpy;
- }
- qt_fbdpy = 0;
-
-#ifndef QT_NO_QWS_MANAGER
- delete qws_decoration;
- qws_decoration = 0;
-#endif
-
- delete mouseInWidget;
- mouseInWidget = 0;
-
-#if !defined(QT_NO_IM)
- delete QApplicationPrivate::inputContext;
- QApplicationPrivate::inputContext = 0;
-#endif
-}
-
-
-/*****************************************************************************
- Platform specific global and internal functions
- *****************************************************************************/
-
-QString QApplicationPrivate::appName() const // get application name
-{
- return QT_PREPEND_NAMESPACE(appName);
-}
-
-/*****************************************************************************
- Platform specific QApplication members
- *****************************************************************************/
-
-#define NoValue 0x0000
-#define XValue 0x0001
-#define YValue 0x0002
-#define WidthValue 0x0004
-#define HeightValue 0x0008
-#define AllValues 0x000F
-#define XNegative 0x0010
-#define YNegative 0x0020
-
-/* Copyright notice for ReadInteger and parseGeometry
-
-Copyright (c) 1985, 1986, 1987 X Consortium
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be included
-in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
-OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of the X Consortium shall
-not be used in advertising or otherwise to promote the sale, use or
-other dealings in this Software without prior written authorization
-from the X Consortium.
-
-*/
-/*
- * XParseGeometry parses strings of the form
- * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
- * width, height, xoffset, and yoffset are unsigned integers.
- * Example: "=80x24+300-49"
- * The equal sign is optional.
- * It returns a bitmask that indicates which of the four values
- * were actually found in the string. For each value found,
- * the corresponding argument is updated; for each value
- * not found, the corresponding argument is left unchanged.
- */
-
-static int
-ReadInteger(char *string, char **NextString)
-{
- register int Result = 0;
- int Sign = 1;
-
- if (*string == '+')
- string++;
- else if (*string == '-')
- {
- string++;
- Sign = -1;
- }
- for (; (*string >= '0') && (*string <= '9'); string++)
- {
- Result = (Result * 10) + (*string - '0');
- }
- *NextString = string;
- if (Sign >= 0)
- return Result;
- else
- return -Result;
-}
-
-static int parseGeometry(const char* string,
- int* x, int* y, int* width, int* height)
-{
- int mask = NoValue;
- register char *strind;
- unsigned int tempWidth=0, tempHeight=0;
- int tempX=0, tempY=0;
- char *nextCharacter;
-
- if (!string || (*string == '\0')) return mask;
- if (*string == '=')
- string++; /* ignore possible '=' at beg of geometry spec */
-
- strind = const_cast<char *>(string);
- if (*strind != '+' && *strind != '-' && *strind != 'x') {
- tempWidth = ReadInteger(strind, &nextCharacter);
- if (strind == nextCharacter)
- return 0;
- strind = nextCharacter;
- mask |= WidthValue;
- }
-
- if (*strind == 'x' || *strind == 'X') {
- strind++;
- tempHeight = ReadInteger(strind, &nextCharacter);
- if (strind == nextCharacter)
- return 0;
- strind = nextCharacter;
- mask |= HeightValue;
- }
-
- if ((*strind == '+') || (*strind == '-')) {
- if (*strind == '-') {
- strind++;
- tempX = -ReadInteger(strind, &nextCharacter);
- if (strind == nextCharacter)
- return 0;
- strind = nextCharacter;
- mask |= XNegative;
-
- }
- else
- { strind++;
- tempX = ReadInteger(strind, &nextCharacter);
- if (strind == nextCharacter)
- return 0;
- strind = nextCharacter;
- }
- mask |= XValue;
- if ((*strind == '+') || (*strind == '-')) {
- if (*strind == '-') {
- strind++;
- tempY = -ReadInteger(strind, &nextCharacter);
- if (strind == nextCharacter)
- return 0;
- strind = nextCharacter;
- mask |= YNegative;
-
- }
- else
- {
- strind++;
- tempY = ReadInteger(strind, &nextCharacter);
- if (strind == nextCharacter)
- return 0;
- strind = nextCharacter;
- }
- mask |= YValue;
- }
- }
-
- /* If strind isn't at the end of the string then it's an invalid
- geometry specification. */
-
- if (*strind != '\0') return 0;
-
- if (mask & XValue)
- *x = tempX;
- if (mask & YValue)
- *y = tempY;
- if (mask & WidthValue)
- *width = tempWidth;
- if (mask & HeightValue)
- *height = tempHeight;
- return mask;
-}
-
-#ifdef QT3_SUPPORT
-void QApplication::setMainWidget(QWidget *mainWidget)
-{
- QApplicationPrivate::main_widget = mainWidget;
- if (QApplicationPrivate::main_widget) // give WM command line
- QApplicationPrivate::applyQWSSpecificCommandLineArguments(QApplicationPrivate::main_widget);
-}
-#endif
-
-void QApplicationPrivate::applyQWSSpecificCommandLineArguments(QWidget *main_widget)
-{
- static bool beenHereDoneThat = false;
- if (beenHereDoneThat)
- return;
- beenHereDoneThat = true;
- if (qApp->windowIcon().isNull() && main_widget->testAttribute(Qt::WA_SetWindowIcon))
- qApp->setWindowIcon(main_widget->windowIcon());
- if (mwTitle) // && main_widget->windowTitle().isEmpty())
- main_widget->setWindowTitle(QString::fromLocal8Bit(mwTitle));
- if (mwGeometry) { // parse geometry
- int x = 0;
- int y = 0;
- int w = 0;
- int h = 0;
- int m = parseGeometry(mwGeometry, &x, &y, &w, &h);
- QSize minSize = main_widget->minimumSize();
- QSize maxSize = main_widget->maximumSize();
- if ((m & XValue) == 0)
- x = main_widget->geometry().x();
- if ((m & YValue) == 0)
- y = main_widget->geometry().y();
- if ((m & WidthValue) == 0)
- w = main_widget->width();
- if ((m & HeightValue) == 0)
- h = main_widget->height();
- w = qMin(w,maxSize.width());
- h = qMin(h,maxSize.height());
- w = qMax(w,minSize.width());
- h = qMax(h,minSize.height());
- if ((m & XNegative)) {
- x = qApp->desktop()->width() + x - w;
- x -= (main_widget->frameGeometry().width() - main_widget->width()) / 2;
- } else {
- x += (main_widget->geometry().x() - main_widget->x());
- }
- if ((m & YNegative)) {
- y = qApp->desktop()->height() + y - h;
- } else {
- y += (main_widget->geometry().y() - main_widget->y());
- }
-
- main_widget->setGeometry(x, y, w, h);
- }
-}
-
-/*****************************************************************************
- QApplication cursor stack
- *****************************************************************************/
-#ifndef QT_NO_CURSOR
-void QApplication::setOverrideCursor(const QCursor &cursor)
-{
- qApp->d_func()->cursor_list.prepend(cursor);
-
- QWidget *w = QWidget::mouseGrabber();
- if (!w && qt_last_x)
- w = topLevelAt(*qt_last_x, *qt_last_y);
- if (!w)
- w = desktop();
- QPaintDevice::qwsDisplay()->selectCursor(w, qApp->d_func()->cursor_list.first().handle());
-}
-
-void QApplication::restoreOverrideCursor()
-{
- if (qApp->d_func()->cursor_list.isEmpty())
- return;
- qApp->d_func()->cursor_list.removeFirst();
-
- QWidget *w = QWidget::mouseGrabber();
- if (!w && qt_last_x)
- w = topLevelAt(*qt_last_x, *qt_last_y);
- if (!w)
- w = desktop();
-
- int cursor_handle = Qt::ArrowCursor;
- if (qApp->d_func()->cursor_list.isEmpty()) {
- qws_overrideCursor = false;
- QWidget *upw = QApplication::widgetAt(*qt_last_x, *qt_last_y);
- if (upw)
- cursor_handle = upw->cursor().handle();
- } else {
- cursor_handle = qApp->d_func()->cursor_list.first().handle();
- }
- QPaintDevice::qwsDisplay()->selectCursor(w, cursor_handle);
-}
-#endif// QT_NO_CURSOR
-
-
-
-/*****************************************************************************
- Routines to find a Qt widget from a screen position
- *****************************************************************************/
-
-/*!
- \internal
-*/
-QWidget *QApplicationPrivate::findWidget(const QObjectList& list,
- const QPoint &pos, bool rec)
-{
- QWidget *w;
-
- for (int i = list.size()-1; i >= 0; --i) {
- if (list.at(i)->isWidgetType()) {
- w = static_cast<QWidget*>(list.at(i));
- if (w->isVisible() && !w->testAttribute(Qt::WA_TransparentForMouseEvents) && w->geometry().contains(pos)
- && (!w->d_func()->extra || w->d_func()->extra->mask.isEmpty() || w->d_func()->extra->mask.contains(pos - w->geometry().topLeft()) )) {
- if (!rec)
- return w;
- QWidget *c = w->childAt(w->mapFromParent(pos));
- return c ? c : w;
- }
- }
- }
- return 0;
-}
-
-
-QWidget *QApplication::topLevelAt(const QPoint &pos)
-{
- //### QWSDisplay::windowAt() is currently only implemented in the server process
- int winId = QPaintDevice::qwsDisplay()->windowAt(pos);
- if (winId !=0)
- return QWidget::find(winId);
-
-#if 1
- // fallback implementation for client processes
-//### This is slightly wrong: we have no guarantee that the list is in
-//### stacking order, so if the topmost window is transparent, we may
-//### return the wrong widget
-
- QWidgetList list = topLevelWidgets();
- for (int i = list.size()-1; i >= 0; --i) {
- QWidget *w = list[i];
- if (w != QApplication::desktop() &&
- w->isVisible() && w->d_func()->localAllocatedRegion().contains(w->mapFromParent(pos))
- )
- return w;
- }
-#endif
- return 0;
-}
-
-void QApplication::beep()
-{
-}
-
-void QApplication::alert(QWidget *, int)
-{
-}
-
-Qt::KeyboardModifiers QApplication::queryKeyboardModifiers()
-{
- return keyboardModifiers(); // TODO proper implementation
-}
-
-int QApplication::qwsProcessEvent(QWSEvent* event)
-{
- Q_D(QApplication);
- QScopedLoopLevelCounter loopLevelCounter(d->threadData);
- int oldstate = -1;
- bool isMove = false;
- if (event->type == QWSEvent::Mouse) {
- QWSMouseEvent::SimpleData &mouse = event->asMouse()->simpleData;
- isMove = mouse_x_root != mouse.x_root || mouse_y_root != mouse.y_root;
- oldstate = mouse_state;
- mouse_x_root = mouse.x_root;
- mouse_y_root = mouse.y_root;
- mouse_state = mouse.state;
- }
-
- long unused;
- if (filterEvent(event, &unused)) // send through app filter
- return 1;
-
- if (qwsEventFilter(event)) // send through app filter
- return 1;
-
-
-#ifndef QT_NO_QWS_PROPERTIES
- if (event->type == QWSEvent::PropertyNotify) {
- QWSPropertyNotifyEvent *e = static_cast<QWSPropertyNotifyEvent*>(event);
- if (e->simpleData.property == 424242) { // Clipboard
-#ifndef QT_NO_CLIPBOARD
- if (qt_clipboard) {
- QClipboardEvent e(reinterpret_cast<QEventPrivate*>(event));
- QApplication::sendEvent(qt_clipboard, &e);
- }
-#endif
- }
- }
-#endif //QT_NO_QWS_PROPERTIES
-#ifndef QT_NO_COP
- else if (event->type == QWSEvent::QCopMessage) {
- QWSQCopMessageEvent *e = static_cast<QWSQCopMessageEvent*>(event);
- QCopChannel::sendLocally(QLatin1String(e->channel), QLatin1String(e->message), e->data);
- return 0;
- }
-#endif
-#if !defined(QT_NO_QWS_QPF2)
- else if (event->type == QWSEvent::Font) {
- QWSFontEvent *e = static_cast<QWSFontEvent *>(event);
- if (e->simpleData.type == QWSFontEvent::FontRemoved) {
- QFontCache::instance()->removeEngineForFont(e->fontName);
- }
- }
-#endif
-
- QPointer<QETWidget> widget = static_cast<QETWidget*>(QWidget::find(WId(event->window())));
-#ifdef Q_BACKINGSTORE_SUBSURFACES
- if (!widget) { // XXX: hw: hack for accessing subsurfaces
- extern QWSWindowSurface* qt_findWindowSurface(int);
- QWSWindowSurface *s = qt_findWindowSurface(event->window());
- if (s)
- widget = static_cast<QETWidget*>(s->window());
- }
-#endif
-
-#ifndef QT_NO_DIRECTPAINTER
- if (!widget && d->directPainters) {
- QDirectPainter *dp = d->directPainters->value(WId(event->window()));
- if (dp == 0) {
- } else if (event->type == QWSEvent::Region) {
- QWSRegionEvent *e = static_cast<QWSRegionEvent*>(event);
- QRegion reg;
- reg.setRects(e->rectangles, e->simpleData.nrectangles);
- qt_directpainter_region(dp, reg, e->simpleData.type);
- return 1;
-#ifndef QT_NO_QWSEMBEDWIDGET
- } else if (event->type == QWSEvent::Embed) {
- QWSEmbedEvent *e = static_cast<QWSEmbedEvent*>(event);
- qt_directpainter_embedevent(dp, e);
- return 1;
- #endif // QT_NO_QWSEMBEDWIDGET
- }
- }
-#endif // QT_NO_DIRECTPAINTER
-
-#ifndef QT_NO_QWS_MANAGER
- if (d->last_manager && event->type == QWSEvent::Mouse) {
- QPoint pos(event->asMouse()->simpleData.x_root, event->asMouse()->simpleData.y_root);
- if (!d->last_manager->cachedRegion().contains(pos)) {
- // MouseEvent not yet delivered, so QCursor::pos() is not yet updated, sending 2 x pos
- QMouseEvent outside(QEvent::MouseMove, pos, pos, Qt::NoButton, 0, 0);
- QApplication::sendSpontaneousEvent(d->last_manager, &outside);
- d->last_manager = 0;
- qt_last_cursor = 0xffffffff; //decoration is like another window; must redo cursor
- }
- }
-#endif // QT_NO_QWS_MANAGER
-
- QETWidget *keywidget=0;
- bool grabbed=false;
- if (event->type==QWSEvent::Key || event->type == QWSEvent::IMEvent || event->type == QWSEvent::IMQuery) {
- keywidget = static_cast<QETWidget*>(QWidget::keyboardGrabber());
- if (keywidget) {
- grabbed = true;
- } else {
- if (QWidget *popup = QApplication::activePopupWidget()) {
- if (popup->focusWidget())
- keywidget = static_cast<QETWidget*>(popup->focusWidget());
- else
- keywidget = static_cast<QETWidget*>(popup);
- } else if (QApplicationPrivate::focus_widget && QApplicationPrivate::focus_widget->isVisible())
- keywidget = static_cast<QETWidget*>(QApplicationPrivate::focus_widget);
- else if (widget)
- keywidget = static_cast<QETWidget*>(widget->window());
- }
- } else if (event->type==QWSEvent::MaxWindowRect) {
- QRect r = static_cast<QWSMaxWindowRectEvent*>(event)->simpleData.rect;
- setMaxWindowRect(r);
- return 0;
-#ifndef QT_NO_QWS_DYNAMICSCREENTRANSFORMATION
- } else if (event->type == QWSEvent::ScreenTransformation) {
- QWSScreenTransformationEvent *pe = static_cast<QWSScreenTransformationEvent*>(event);
- setScreenTransformation(pe->simpleData.screen,
- pe->simpleData.transformation);
- return 0;
-#endif
- } else if (widget && event->type==QWSEvent::Mouse) {
- // The mouse event is to one of my top-level widgets
- // which one?
- const int btnMask = Qt::LeftButton | Qt::RightButton | Qt::MidButton;
- QPoint p(event->asMouse()->simpleData.x_root,
- event->asMouse()->simpleData.y_root);
- int mouseButtonState = event->asMouse()->simpleData.state & btnMask;
- static int btnstate = 0;
-
- QETWidget *w = static_cast<QETWidget*>(QWidget::mouseGrabber());
- if (w && !mouseButtonState && qt_pressGrab == w)
- qt_pressGrab = 0;
-#ifndef QT_NO_QWS_MANAGER
- if (!w)
- w = static_cast<QETWidget*>(QWSManager::grabbedMouse());
-#endif
- if (w) {
- // Our mouse is grabbed - send it.
- widget = w;
- btnstate = mouseButtonState;
- } else {
- static QWidget *gw = 0;
- // Three jobs to do here:
- // 1. find the child widget this event belongs to.
- // 2. make sure the cursor is correct.
- // 3. handle implicit mouse grab due to button press.
- w = widget; // w is the widget the cursor is in.
-
- //### ??? alloc_region
- //#### why should we get events outside alloc_region ????
- if (1 /*widget->data->alloc_region.contains(dp) */) {
- // Find the child widget that the cursor is in.
- w = static_cast<QETWidget*>(widget->childAt(widget->mapFromParent(p)));
- if (!w)
- w = widget;
-#ifndef QT_NO_CURSOR
- // Update Cursor.
- if (!gw || gw != w || qt_last_cursor == 0xffffffff) {
- QCursor *curs = 0;
- if (!qApp->d_func()->cursor_list.isEmpty())
- curs = &qApp->d_func()->cursor_list.first();
- else if (w->d_func()->extraData())
- curs = w->d_func()->extraData()->curs;
- QWidget *pw = w;
- // If this widget has no cursor set, try parent.
- while (!curs) {
- pw = pw->parentWidget();
- if (!pw)
- break;
- if (pw->d_func()->extraData())
- curs = pw->d_func()->extraData()->curs;
- }
- if (!qws_overrideCursor) {
- if (curs)
- QPaintDevice::qwsDisplay()->selectCursor(widget, curs->handle());
- else
- QPaintDevice::qwsDisplay()->selectCursor(widget, Qt::ArrowCursor);
- }
- }
-#endif
- gw = w;
- } else {
- // This event is not for any of our widgets
- gw = 0;
- }
- if (mouseButtonState && !btnstate) {
- // The server has grabbed the mouse for us.
- // Remember which of my widgets has it.
- qt_pressGrab = w;
- if (!widget->isActiveWindow() &&
- (!app_do_modal || QApplication::activeModalWidget() == widget) &&
- !((widget->windowFlags() & Qt::FramelessWindowHint) || (widget->windowType() == Qt::Tool))) {
- widget->activateWindow();
- if (widget->raiseOnClick())
- widget->raise();
- }
- }
- btnstate = mouseButtonState;
- widget = w;
- }
- }
-
- if (!widget) { // don't know this window
- if (!QWidget::mouseGrabber()
-#ifndef QT_NO_QWS_MANAGER
- && !QWSManager::grabbedMouse()
-#endif
- ) {
- qt_last_cursor = 0xffffffff; // cursor can be changed by another application
- }
-
- QWidget* popup = QApplication::activePopupWidget();
- if (popup) {
-
- /*
- That is more than suboptimal. The real solution should
- do some keyevent and buttonevent translation, so that
- the popup still continues to work as the user expects.
- Unfortunately this translation is currently only
- possible with a known widget. I'll change that soon
- (Matthias).
- */
-
- // Danger - make sure we don't lock the server
- switch (event->type) {
- case QWSEvent::Mouse:
- case QWSEvent::Key:
- do {
- popup->close();
- } while ((popup = qApp->activePopupWidget()));
- return 1;
- }
- }
- if (event->type == QWSEvent::Mouse && *mouseInWidget) {
- QApplicationPrivate::dispatchEnterLeave(0, *mouseInWidget);
- (*mouseInWidget) = 0;
- }
- return -1;
- }
-
- if (app_do_modal) // modal event handling
- if (!qt_try_modal(widget, event)) {
- return 1;
- }
-
- if (widget->qwsEvent(event)) // send through widget filter
- return 1;
- switch (event->type) {
-
- case QWSEvent::Mouse: { // mouse event
- QWSMouseEvent *me = event->asMouse();
- QWSMouseEvent::SimpleData &mouse = me->simpleData;
-
- // Translate a QWS event into separate move
- // and press/release events
- // Beware of reentrancy: we can enter a modal state
- // inside translateMouseEvent
-
- if (isMove) {
- QWSMouseEvent move = *me;
- move.simpleData.state = oldstate;
- widget->translateMouseEvent(&move, oldstate);
- }
- if ((mouse.state&Qt::MouseButtonMask) != (oldstate&Qt::MouseButtonMask)) {
- widget->translateMouseEvent(me, oldstate);
- }
-
- if (mouse.delta != 0)
- widget->translateWheelEvent(me);
-
- if (qt_button_down && (mouse_state & Qt::MouseButtonMask) == 0)
- qt_button_down = 0;
-
- break;
- }
- case QWSEvent::Key: // keyboard event
- if (keywidget) // should always exist
- keywidget->translateKeyEvent(static_cast<QWSKeyEvent*>(event), grabbed);
- break;
-
-#ifndef QT_NO_QWS_INPUTMETHODS
- case QWSEvent::IMEvent:
- if (keywidget) // should always exist
- QWSInputContext::translateIMEvent(keywidget, static_cast<QWSIMEvent*>(event));
- break;
-
- case QWSEvent::IMQuery:
- if (keywidget) // should always exist
- QWSInputContext::translateIMQueryEvent(keywidget, static_cast<QWSIMQueryEvent*>(event));
- break;
-
- case QWSEvent::IMInit:
- QWSInputContext::translateIMInitEvent(static_cast<QWSIMInitEvent*>(event));
- break;
-#endif
- case QWSEvent::Region:
- widget->translateRegionEvent(static_cast<QWSRegionEvent*>(event));
- break;
- case QWSEvent::Focus:
- if ((static_cast<QWSFocusEvent*>(event))->simpleData.get_focus) {
- if (widget == static_cast<QWidget *>(desktop()))
- return true; // not interesting
- if (activeWindow() != widget) {
- setActiveWindow(widget);
- if (QApplicationPrivate::active_window)
- static_cast<QETWidget *>(QApplicationPrivate::active_window)->repaintDecoration(desktop()->rect(), false);
- if (widget && !d->inPopupMode()) {
- QWidget *w = widget->focusWidget();
- while (w && w->focusProxy())
- w = w->focusProxy();
- if (w && (w->focusPolicy() != Qt::NoFocus))
- w->setFocus();
- else
- widget->QWidget::focusNextPrevChild(true);
- if (!QApplicationPrivate::focus_widget) {
- if (widget->focusWidget())
- widget->focusWidget()->setFocus();
- else
- widget->window()->setFocus();
- }
- }
- }
- } else { // lost focus
- if (widget == static_cast<QWidget *>(desktop()))
- return true; // not interesting
- if (QApplicationPrivate::focus_widget) {
- QETWidget *old = static_cast<QETWidget *>(QApplicationPrivate::active_window);
- setActiveWindow(0);
- qt_last_cursor = 0xffffffff;
- //QApplicationPrivate::active_window = 0;
- if (old)
- old->repaintDecoration(desktop()->rect(), false);
- /* activateWindow() sends focus events
- QApplication::setFocusWidget(0);
- */
- }
- }
- break;
-
- case QWSEvent::WindowOperation:
- if (static_cast<QWidget *>(widget) == desktop())
- return true;
- switch ((static_cast<QWSWindowOperationEvent *>(event))->simpleData.op) {
- case QWSWindowOperationEvent::Show:
- widget->show();
- break;
- case QWSWindowOperationEvent::Hide:
- widget->hide();
- break;
- case QWSWindowOperationEvent::ShowMaximized:
- widget->showMaximized();
- break;
- case QWSWindowOperationEvent::ShowMinimized:
- widget->showMinimized();
- break;
- case QWSWindowOperationEvent::ShowNormal:
- widget->showNormal();
- break;
- case QWSWindowOperationEvent::Close:
- widget->d_func()->close_helper(QWidgetPrivate::CloseWithSpontaneousEvent);
- break;
- }
- break;
-#ifndef QT_NO_QWSEMBEDWIDGET
- case QWSEvent::Embed:
- widget->translateEmbedEvent(static_cast<QWSEmbedEvent*>(event));
- break;
-#endif
- default:
- break;
- }
-
- return 0;
-}
-
-bool QApplication::qwsEventFilter(QWSEvent *)
-{
- return false;
-}
-
-void QApplication::qwsSetCustomColors(QRgb *colorTable, int start, int numColors)
-{
- if (start < 0 || start > 39) {
- qWarning("QApplication::qwsSetCustomColors: start < 0 || start > 39");
- return;
- }
- if (start + numColors > 40) {
- numColors = 40 - start;
- qWarning("QApplication::qwsSetCustomColors: Too many colors");
- }
- start += 216;
- for (int i = 0; i < numColors; i++) {
- qt_screen->set(start + i, qRed(colorTable[i]), qGreen(colorTable[i]),
- qBlue(colorTable[i]));
- }
-}
-
-#ifndef QT_NO_QWS_MANAGER
-QDecoration &QApplication::qwsDecoration()
-{
- return *qws_decoration;
-}
-
-void QApplication::qwsSetDecoration(QDecoration *dec)
-{
- if (dec) {
- delete qws_decoration;
- qws_decoration = dec;
- QWidgetList widgets = topLevelWidgets();
- for (int i = 0; i < widgets.size(); ++i) {
- QWidget *w = widgets[i];
- if (w->isVisible() && w != desktop()) {
- static_cast<QETWidget *>(w)->updateRegion();
- static_cast<QETWidget *>(w)->repaintDecoration(desktop()->rect(), false);
- if (w->isMaximized())
- w->showMaximized();
- }
- }
- }
-}
-
-QDecoration* QApplication::qwsSetDecoration(const QString &decoration)
-{
- QDecoration *decore = QDecorationFactory::create(decoration);
- if (!decore)
- return 0;
-
- qwsSetDecoration(decore);
- return decore;
-}
-
-#endif
-
-bool QApplicationPrivate::modalState()
-{
- return app_do_modal;
-}
-
-void QApplicationPrivate::enterModal_sys(QWidget *widget)
-{
- if (!qt_modal_stack)
- qt_modal_stack = new QWidgetList;
- qt_modal_stack->insert(0, widget);
- app_do_modal = true;
-}
-
-void QApplicationPrivate::leaveModal_sys(QWidget *widget)
-{
- if (qt_modal_stack && qt_modal_stack->removeAll(widget)) {
- if (qt_modal_stack->isEmpty()) {
- delete qt_modal_stack;
- qt_modal_stack = 0;
- }
- }
- app_do_modal = qt_modal_stack != 0;
-}
-
-static bool qt_try_modal(QWidget *widget, QWSEvent *event)
-{
- QWidget * top = 0;
-
- if (QApplicationPrivate::tryModalHelper(widget, &top))
- return true;
-
- bool block_event = false;
- bool paint_event = false;
-
- switch (event->type) {
- case QWSEvent::Focus:
- if (!static_cast<QWSFocusEvent*>(event)->simpleData.get_focus)
- break;
- // drop through
- case QWSEvent::Mouse: // disallow mouse/key events
- case QWSEvent::Key:
- block_event = true;
- break;
- }
-
- if (top->parentWidget() == 0 && (block_event || paint_event))
- top->raise();
-
- return !block_event;
-}
-
-static int openPopupCount = 0;
-void QApplicationPrivate::openPopup(QWidget *popup)
-{
- openPopupCount++;
- if (!popupWidgets) { // create list
- popupWidgets = new QWidgetList;
-
- /* only grab if you are the first/parent popup */
- QPaintDevice::qwsDisplay()->grabMouse(popup,true);
- QPaintDevice::qwsDisplay()->grabKeyboard(popup,true);
- popupGrabOk = true;
- }
- popupWidgets->append(popup); // add to end of list
-
- // popups are not focus-handled by the window system (the first
- // popup grabbed the keyboard), so we have to do that manually: A
- // new popup gets the focus
- if (popup->focusWidget()) {
- popup->focusWidget()->setFocus(Qt::PopupFocusReason);
- } else if (popupWidgets->count() == 1) { // this was the first popup
- if (QWidget *fw = QApplication::focusWidget()) {
- QFocusEvent e(QEvent::FocusOut, Qt::PopupFocusReason);
- QApplication::sendEvent(fw, &e);
- }
- }
-}
-
-void QApplicationPrivate::closePopup(QWidget *popup)
-{
- if (!popupWidgets)
- return;
-
- popupWidgets->removeAll(popup);
- if (popup == popupOfPopupButtonFocus) {
- popupButtonFocus = 0;
- popupOfPopupButtonFocus = 0;
- }
- if (popupWidgets->count() == 0) { // this was the last popup
- popupCloseDownMode = true; // control mouse events
- delete popupWidgets;
- popupWidgets = 0;
- if (popupGrabOk) { // grabbing not disabled
- QPaintDevice::qwsDisplay()->grabMouse(popup,false);
- QPaintDevice::qwsDisplay()->grabKeyboard(popup,false);
- popupGrabOk = false;
- // XXX ungrab keyboard
- }
- if (active_window) {
- if (QWidget *fw = active_window->focusWidget()) {
- if (fw != QApplication::focusWidget()) {
- fw->setFocus(Qt::PopupFocusReason);
- } else {
- QFocusEvent e(QEvent::FocusIn, Qt::PopupFocusReason);
- QApplication::sendEvent(fw, &e);
- }
- }
- }
- } else {
- // popups are not focus-handled by the window system (the
- // first popup grabbed the keyboard), so we have to do that
- // manually: A popup was closed, so the previous popup gets
- // the focus.
- QWidget* aw = popupWidgets->last();
- if (QWidget *fw = aw->focusWidget())
- fw->setFocus(Qt::PopupFocusReason);
- }
-}
-
-/*****************************************************************************
- Event translation; translates FB events to Qt events
- *****************************************************************************/
-
-//
-// Mouse event translation
-//
-// FB doesn't give mouse double click events, so we generate them by
-// comparing window, time and position between two mouse press events.
-//
-
-
-// Needed for QCursor::pos
-
-static const int AnyButton = (Qt::LeftButton | Qt::MidButton | Qt::RightButton);
-
-
-
-//
-// Wheel event translation
-//
-bool QETWidget::translateWheelEvent(const QWSMouseEvent *me)
-{
-#ifdef QT_NO_WHEELEVENT
- Q_UNUSED(me);
- return false;
-#else
- const QWSMouseEvent::SimpleData &mouse = me->simpleData;
-
- // Figure out wheeling direction:
- // Horizontal wheel w/o Alt
- // OR Vertical wheel w/ Alt ==> Horizontal wheeling
- // ..all other permutations ==> Vertical wheeling
- int axis = mouse.delta / 120; // WHEEL_DELTA?
- Qt::Orientation orient = ((axis == 2 || axis == -2) && ((mouse.state & Qt::AltModifier) == 0))
- ||((axis == 1 || axis == -1) && mouse.state & Qt::AltModifier)
- ? Qt::Horizontal : Qt::Vertical;
-
- QPoint mousePoint = QPoint(mouse.x_root, mouse.y_root);
-
- // send the event to the widget or its ancestors
- QWidget* popup = qApp->activePopupWidget();
- if (popup && window() != popup)
- popup->close();
- QWheelEvent we(mapFromGlobal(mousePoint), mousePoint, mouse.delta,
- Qt::MouseButtons(mouse.state & Qt::MouseButtonMask),
- Qt::KeyboardModifiers(mouse.state & Qt::KeyboardModifierMask), orient);
- if (QApplication::sendSpontaneousEvent(this, &we))
- return true;
-
- // send the event to the widget that has the focus or its ancestors, if different
- QWidget *w = this;
- if (w != qApp->focusWidget() && (w = qApp->focusWidget())) {
- QWidget* popup = qApp->activePopupWidget();
- if (popup && w != popup)
- popup->hide();
- if (QApplication::sendSpontaneousEvent(w, &we))
- return true;
- }
- return false;
-#endif
-}
-
-bool QETWidget::translateMouseEvent(const QWSMouseEvent *event, int prevstate)
-{
- static bool manualGrab = false;
- QPoint pos;
- QPoint globalPos;
- int button = 0;
-
- if (sm_blockUserInput) // block user interaction during session management
- return true;
- const QWSMouseEvent::SimpleData &mouse = event->simpleData;
- pos = mapFromGlobal(QPoint(mouse.x_root, mouse.y_root));
-// if (qt_last_x) {
-// *qt_last_x=mouse.x_root;
-// *qt_last_y=mouse.y_root;
-// }
- globalPos.rx() = mouse.x_root;
- globalPos.ry() = mouse.y_root;
-
- QEvent::Type type = QEvent::None;
-
- Qt::MouseButtons buttonstate = Qt::MouseButtons(mouse.state & Qt::MouseButtonMask);
- Qt::KeyboardModifiers keystate = Qt::KeyboardModifiers(mouse.state & Qt::KeyboardModifierMask);
-
- if (mouse.state == prevstate) {
- // mouse move
- type = QEvent::MouseMove;
- } else if ((mouse.state&AnyButton) != (prevstate&AnyButton)) {
- Qt::MouseButtons current_buttons = Qt::MouseButtons(prevstate&Qt::MouseButtonMask);
- for (button = Qt::LeftButton; !type && button <= Qt::MidButton; button<<=1) {
- if ((mouse.state&button) != (current_buttons&button)) {
- // button press or release
- current_buttons = Qt::MouseButtons(current_buttons ^ button);
-
-#ifndef QT_NO_QWS_INPUTMETHODS
- //############ We used to do a QInputContext::reset(oldFocus);
- // when we changed the focus widget. See change 93389 for where the
- // focus code went. The IM code was (after testing for ClickToFocus):
- //if (mouse.state&button && w != QInputContext::microFocusWidget()) //button press
- // QInputContext::reset(oldFocus);
-
-#endif
- if (mouse.state&button) { //button press
- qt_button_down = childAt(pos);
- if (!qt_button_down)
- qt_button_down = this;
- if (/*XXX mouseActWindow == this &&*/
- mouseButtonPressed == button &&
- long(mouse.time) -long(mouseButtonPressTime)
- < QApplication::doubleClickInterval() &&
- qAbs(mouse.x_root - mouseXPos) < mouse_double_click_distance &&
- qAbs(mouse.y_root - mouseYPos) < mouse_double_click_distance ) {
- type = QEvent::MouseButtonDblClick;
- mouseButtonPressTime -= 2000; // no double-click next time
- } else {
- type = QEvent::MouseButtonPress;
- mouseButtonPressTime = mouse.time;
- }
- mouseButtonPressed = button; // save event params for
- mouseXPos = globalPos.x(); // future double click tests
- mouseYPos = globalPos.y();
- } else { // mouse button released
- if (manualGrab) { // release manual grab
- manualGrab = false;
- // XXX XUngrabPointer(x11Display(), CurrentTime);
- }
-
- type = QEvent::MouseButtonRelease;
- }
- }
- }
- button >>= 1;
- }
- //XXX mouseActWindow = winId(); // save some event params
-
- if (type == 0) { // event consumed
- return false; //EXIT in the normal case
- }
-
- if (qApp->d_func()->inPopupMode()) { // in popup mode
- QWidget *popup = qApp->activePopupWidget();
- // in X11, this would be the window we are over.
- // in QWS this is the top level popup. to allow mouse
- // events to other widgets, need to go through qApp->QApplicationPrivate::popupWidgets.
- QSize s(qt_screen->width(), qt_screen->height());
- for (int i = 0; i < QApplicationPrivate::popupWidgets->size(); ++i) {
- QWidget *w = QApplicationPrivate::popupWidgets->at(i);
-
- if ((w->windowType() == Qt::Popup) && w->d_func()->localAllocatedRegion().contains(globalPos - w->geometry().topLeft()))
- {
- popup = w;
- break;
- }
- }
- pos = popup->mapFromGlobal(globalPos);
- bool releaseAfter = false;
- QWidget *popupChild = popup->childAt(pos);
- QWidget *popupTarget = popupChild ? popupChild : popup;
-
- if (popup != popupOfPopupButtonFocus){
- popupButtonFocus = 0;
- popupOfPopupButtonFocus = 0;
- }
-
- if (!popupTarget->isEnabled()) {
- return false; //EXIT special case
- }
-
- switch (type) {
- case QEvent::MouseButtonPress:
- case QEvent::MouseButtonDblClick:
- popupButtonFocus = popupChild;
- popupOfPopupButtonFocus = popup;
- break;
- case QEvent::MouseButtonRelease:
- releaseAfter = true;
- break;
- default:
- break; // nothing for mouse move
- }
-
- int oldOpenPopupCount = openPopupCount;
-
- if (popupButtonFocus) {
- QMouseEvent e(type, popupButtonFocus->mapFromGlobal(globalPos),
- globalPos, Qt::MouseButton(button), buttonstate, keystate);
- QApplication::sendSpontaneousEvent(popupButtonFocus, & e);
- if (releaseAfter) {
- popupButtonFocus = 0;
- popupOfPopupButtonFocus = 0;
- }
- } else if (popupChild) {
- QMouseEvent e(type, popupChild->mapFromGlobal(globalPos),
- globalPos, Qt::MouseButton(button), buttonstate, keystate);
- QApplication::sendSpontaneousEvent(popupChild, & e);
- } else {
- QMouseEvent e(type, pos, globalPos, Qt::MouseButton(button), buttonstate, keystate);
- QApplication::sendSpontaneousEvent(popupChild ? popupChild : popup, & e);
- }
-#ifndef QT_NO_CONTEXTMENU
- if (type == QEvent::MouseButtonPress && button == Qt::RightButton && (openPopupCount == oldOpenPopupCount)) {
- QWidget *popupEvent = popup;
- if(popupButtonFocus)
- popupEvent = popupButtonFocus;
- else if(popupChild)
- popupEvent = popupChild;
- QContextMenuEvent e(QContextMenuEvent::Mouse, pos, globalPos, keystate);
- QApplication::sendSpontaneousEvent(popupEvent, &e);
- }
-#endif // QT_NO_CONTEXTMENU
-
- if (releaseAfter)
- qt_button_down = 0;
-
- } else { //qApp not in popup mode
- QWidget *widget = this;
- QWidget *w = QWidget::mouseGrabber();
- if (!w && qt_button_down)
- w = qt_button_down;
- if (w && w != this) {
- widget = w;
- pos = mapToGlobal(pos);
- pos = w->mapFromGlobal(pos);
- }
-
- if (popupCloseDownMode) {
- popupCloseDownMode = false;
- if ((windowType() == Qt::Popup)) // ignore replayed event
- return true; //EXIT
- }
-
- QPointer<QWidget> leaveAfterRelease = 0;
- if (type == QEvent::MouseButtonRelease &&
- (mouse.state & (~button) & (Qt::LeftButton |
- Qt::MidButton |
- Qt::RightButton)) == 0) {
- // Button released outside the widget -> leave the widget after the
- // release event has been delivered.
- if (widget == qt_button_down && (pos.x() < 0 || pos.y() < 0))
- leaveAfterRelease = qt_button_down;
- qt_button_down = 0;
- }
-
- int oldOpenPopupCount = openPopupCount;
-
- QMouseEvent e(type, pos, globalPos, Qt::MouseButton(button), buttonstate, keystate);
-#ifndef QT_NO_QWS_MANAGER
- if (widget->isWindow() && widget->d_func()->topData()->qwsManager
- && (widget->d_func()->topData()->qwsManager->region().contains(globalPos)
- || QWSManager::grabbedMouse() )) {
- if ((*mouseInWidget)) {
- QApplicationPrivate::dispatchEnterLeave(0, *mouseInWidget);
- (*mouseInWidget) = 0;
- }
- QApplication::sendSpontaneousEvent(widget->d_func()->topData()->qwsManager, &e);
- qApp->d_func()->last_manager = widget->d_func()->topData()->qwsManager;
- } else
-#endif
- {
- if (widget != (*mouseInWidget)) {
- QApplicationPrivate::dispatchEnterLeave(widget, *mouseInWidget);
- (*mouseInWidget) = widget;
- qt_last_mouse_receiver = widget;
- }
- QApplication::sendSpontaneousEvent(widget, &e);
- if (leaveAfterRelease && !QWidget::mouseGrabber()) {
- *mouseInWidget = QApplication::widgetAt(globalPos);
- qt_last_mouse_receiver = *mouseInWidget;
- QApplicationPrivate::dispatchEnterLeave(*mouseInWidget, leaveAfterRelease);
- leaveAfterRelease = 0;
- }
- }
-#ifndef QT_NO_CONTEXTMENU
- if (type == QEvent::MouseButtonPress && button == Qt::RightButton && (openPopupCount == oldOpenPopupCount)) {
- QContextMenuEvent e(QContextMenuEvent::Mouse, pos, globalPos, keystate);
- QApplication::sendSpontaneousEvent(widget, &e);
- }
-#endif // QT_NO_CONTEXTMENU
- }
- return true;
-}
-
-
-bool QETWidget::translateKeyEvent(const QWSKeyEvent *event, bool grab) /* grab is used in the #ifdef */
-{
- int code = -1;
- //### Qt assumes keyboard state is state *before*, while QWS uses state after the event
- static Qt::KeyboardModifiers oldstate;
- Qt::KeyboardModifiers state = oldstate;
- oldstate = event->simpleData.modifiers;
-
- if (sm_blockUserInput) // block user interaction during session management
- return true;
-
- if (!isEnabled())
- return true;
-
- QEvent::Type type = event->simpleData.is_press ?
- QEvent::KeyPress : QEvent::KeyRelease;
- bool autor = event->simpleData.is_auto_repeat;
- QString text;
- char ascii = 0;
- if (event->simpleData.unicode) {
- QChar ch(event->simpleData.unicode);
- if (ch.unicode() != 0xffff)
- text += ch;
- ascii = ch.toLatin1();
- }
- code = event->simpleData.keycode;
-
-#if defined QT3_SUPPORT && !defined(QT_NO_SHORTCUT)
- if (type == QEvent::KeyPress && !grab
- && static_cast<QApplicationPrivate*>(qApp->d_ptr.data())->use_compat()) {
- // send accel events if the keyboard is not grabbed
- QKeyEvent a(type, code, state, text, autor, int(text.length()));
- if (static_cast<QApplicationPrivate*>(qApp->d_ptr.data())->qt_tryAccelEvent(this, &a))
- return true;
- }
-#else
- Q_UNUSED(grab);
-#endif
- if (!text.isEmpty() && testAttribute(Qt::WA_KeyCompression)) {
- // the widget wants key compression so it gets it
-
- // XXX not implemented
- }
-
- QKeyEvent e(type, code, state, text, autor, int(text.length()));
- return QApplication::sendSpontaneousEvent(this, &e);
-}
-
-bool QETWidget::translateRegionEvent(const QWSRegionEvent *event)
-{
- QWSWindowSurface *surface = static_cast<QWSWindowSurface*>(windowSurface());
- Q_ASSERT(surface);
-
- QRegion region;
- region.setRects(event->rectangles, event->simpleData.nrectangles);
-
- switch (event->simpleData.type) {
- case QWSRegionEvent::Allocation:
- region.translate(-mapToGlobal(QPoint()));
- surface->setClipRegion(region);
- break;
-#ifdef QT_QWS_CLIENTBLIT
- case QWSRegionEvent::DirectPaint:
- surface->setDirectRegion(region, event->simpleData.id);
- break;
-#endif
- default:
- break;
- }
-
- return true;
-}
-
-#ifndef QT_NO_QWSEMBEDWIDGET
-void QETWidget::translateEmbedEvent(const QWSEmbedEvent *event)
-{
- if (event->simpleData.type | QWSEmbedEvent::Region) {
- const QRegion region = event->region;
- setGeometry(region.boundingRect());
- setVisible(!region.isEmpty());
- }
-}
-#endif // QT_NO_QWSEMBEDWIDGET
-
-void QETWidget::repaintDecoration(QRegion r, bool post)
-{
- Q_UNUSED(post);
-#ifdef QT_NO_QWS_MANAGER
- Q_UNUSED(r);
-#else
- //please note that qwsManager is a QObject, not a QWidget.
- //therefore, normal ways of painting do not work.
- // However, it does listen to paint events.
-
- Q_D(QWidget);
- if (isWindow() && d->topData()->qwsManager && isVisible()) {
- QWSManager *manager = d->topData()->qwsManager;
- r &= manager->region();
- if (!r.isEmpty())
- manager->repaintRegion(QDecoration::All, QDecoration::Normal);
- }
-#endif
-}
-
-void QETWidget::updateRegion()
-{
- Q_D(QWidget);
-
- QTLWExtra *topextra = d->maybeTopData();
- if (!topextra)
- return;
-
- QRegion myregion = d->localRequestedRegion();
- myregion.translate(geometry().topLeft());
-
-#ifndef QT_NO_QWS_MANAGER
- QWSManager *manager = topextra->qwsManager;
- if (manager)
- myregion += manager->region();
-#endif
-
- QRect br(myregion.boundingRect());
- topextra->frameStrut.setCoords(d->data.crect.x() - br.x(),
- d->data.crect.y() - br.y(),
- br.right() - d->data.crect.right(),
- br.bottom() - d->data.crect.bottom());
-}
-
-void QApplication::setCursorFlashTime(int msecs)
-{
- QApplicationPrivate::cursor_flash_time = msecs;
-}
-
-
-int QApplication::cursorFlashTime()
-{
- return QApplicationPrivate::cursor_flash_time;
-}
-
-void QApplication::setDoubleClickInterval(int ms)
-{
- QApplicationPrivate::mouse_double_click_time = ms;
-}
-
-int QApplication::doubleClickInterval()
-{
- return QApplicationPrivate::mouse_double_click_time;
-}
-
-void QApplication::setKeyboardInputInterval(int ms)
-{
- QApplicationPrivate::keyboard_input_time = ms;
-}
-
-int QApplication::keyboardInputInterval()
-{
- return QApplicationPrivate::keyboard_input_time;
-}
-
-#ifndef QT_NO_WHEELEVENT
-void QApplication::setWheelScrollLines(int lines)
-{
- QApplicationPrivate::wheel_scroll_lines = lines;
-}
-
-int QApplication::wheelScrollLines()
-{
- return QApplicationPrivate::wheel_scroll_lines;
-}
-#endif
-
-void QApplication::setEffectEnabled(Qt::UIEffect effect, bool enable)
-{
- switch (effect) {
- case Qt::UI_AnimateMenu:
- QApplicationPrivate::animate_menu = enable;
- break;
- case Qt::UI_FadeMenu:
- if (enable)
- QApplicationPrivate::animate_menu = true;
- QApplicationPrivate::fade_menu = enable;
- break;
- case Qt::UI_AnimateCombo:
- QApplicationPrivate::animate_combo = enable;
- break;
- case Qt::UI_AnimateTooltip:
- QApplicationPrivate::animate_tooltip = enable;
- break;
- case Qt::UI_FadeTooltip:
- if (enable)
- QApplicationPrivate::animate_tooltip = true;
- QApplicationPrivate::fade_tooltip = enable;
- break;
- case Qt::UI_AnimateToolBox:
- QApplicationPrivate::animate_toolbox = enable;
- break;
- default:
- QApplicationPrivate::animate_ui = enable;
- break;
- }
-}
-
-bool QApplication::isEffectEnabled(Qt::UIEffect effect)
-{
- if (QColormap::instance().depth() < 16 || !QApplicationPrivate::animate_ui)
- return false;
-
- switch(effect) {
- case Qt::UI_AnimateMenu:
- return QApplicationPrivate::animate_menu;
- case Qt::UI_FadeMenu:
- return QApplicationPrivate::fade_menu;
- case Qt::UI_AnimateCombo:
- return QApplicationPrivate::animate_combo;
- case Qt::UI_AnimateTooltip:
- return QApplicationPrivate::animate_tooltip;
- case Qt::UI_FadeTooltip:
- return QApplicationPrivate::fade_tooltip;
- case Qt::UI_AnimateToolBox:
- return QApplicationPrivate::animate_toolbox;
- default:
- return QApplicationPrivate::animate_ui;
- }
-}
-
-void QApplication::setArgs(int c, char **v)
-{
- Q_D(QApplication);
- d->argc = c;
- d->argv = v;
-}
-
-void QApplicationPrivate::initializeMultitouch_sys()
-{ }
-void QApplicationPrivate::cleanupMultitouch_sys()
-{ }
-
-/* \internal
- This is used to clean up the qws server
- in case the QApplication constructor threw an exception
-*/
-QWSServerCleaner::~QWSServerCleaner()
-{
- if (qwsServer && qws_single_process)
- QWSServer::closedown();
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp
deleted file mode 100644
index e277765eff..0000000000
--- a/src/gui/kernel/qapplication_s60.cpp
+++ /dev/null
@@ -1,2723 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qapplication_p.h"
-#include "qsessionmanager.h"
-#include "qevent.h"
-#include "qsymbianevent.h"
-#include "qeventdispatcher_s60_p.h"
-#include "qwidget.h"
-#include "qdesktopwidget.h"
-#include "private/qbackingstore_p.h"
-#include "qt_s60_p.h"
-#include "private/qevent_p.h"
-#include "qstring.h"
-#include "qdebug.h"
-#include "qimage.h"
-#include "qcombobox.h"
-#include "private/qkeymapper_p.h"
-#include "private/qfont_p.h"
-#ifndef QT_NO_STYLE_S60
-#include "private/qs60style_p.h"
-#endif
-#include "private/qwindowsurface_s60_p.h"
-#include "qpaintengine.h"
-#include "private/qmenubar_p.h"
-#include "private/qsoftkeymanager_p.h"
-#ifdef QT_GRAPHICSSYSTEM_RUNTIME
-#include "private/qgraphicssystem_runtime_p.h"
-#endif
-
-#include "apgwgnam.h" // For CApaWindowGroupName
-#include <mdaaudiotoneplayer.h> // For CMdaAudioToneUtility
-
-#if defined(Q_OS_SYMBIAN)
-# include <private/qs60mainapplication_p.h>
-# include <centralrepository.h>
-# include "qs60mainappui.h"
-# include "qinputcontext.h"
-#endif
-
-#if defined(Q_WS_S60)
-# if !defined(QT_NO_IM)
-# include <private/qcoefepinputcontext_p.h>
-# endif
-#endif
-
-#include "private/qstylesheetstyle_p.h"
-
-#include <hal.h>
-#include <hal_data.h>
-
-#ifdef Q_SYMBIAN_TRANSITION_EFFECTS
-#include <graphics/wstfxconst.h>
-#endif
-
-QT_BEGIN_NAMESPACE
-
-// Goom Events through Window Server
-static const int KGoomMemoryLowEvent = 0x10282DBF;
-static const int KGoomMemoryGoodEvent = 0x20026790;
-// Split view open/close events from AVKON
-static const int KSplitViewOpenEvent = 0x2001E2C0;
-static const int KSplitViewCloseEvent = 0x2001E2C1;
-
-#if defined(QT_DEBUG)
-static bool appNoGrab = false; // Grabbing enabled
-#endif
-static bool app_do_modal = false; // modal mode
-Q_GLOBAL_STATIC(QS60Data, qt_s60Data);
-
-extern bool qt_sendSpontaneousEvent(QObject*,QEvent*);
-extern QWidgetList *qt_modal_stack; // stack of modal widgets
-extern QDesktopWidget *qt_desktopWidget; // qapplication.cpp
-
-QWidget *qt_button_down = 0; // widget got last button-down
-
-QSymbianControl *QSymbianControl::lastFocusedControl = 0;
-
-static Qt::KeyboardModifiers app_keyboardModifiers = Qt::NoModifier;
-
-QS60Data* qGlobalS60Data()
-{
- return qt_s60Data();
-}
-
-#ifdef Q_WS_S60
-void QS60Data::setStatusPaneAndButtonGroupVisibility(bool statusPaneVisible, bool buttonGroupVisible)
-{
- bool buttonGroupVisibilityChanged = false;
- if (CEikButtonGroupContainer *const b = buttonGroupContainer()) {
- buttonGroupVisibilityChanged = (b->IsVisible() != buttonGroupVisible);
- b->MakeVisible(buttonGroupVisible);
- }
- bool statusPaneVisibilityChanged = false;
- if (CEikStatusPane *const s = statusPane()) {
- statusPaneVisibilityChanged = (s->IsVisible() != statusPaneVisible);
- s->MakeVisible(statusPaneVisible);
- }
- if (buttonGroupVisibilityChanged || statusPaneVisibilityChanged) {
- const QSize size = qt_TRect2QRect(static_cast<CEikAppUi*>(S60->appUi())->ClientRect()).size();
- const QSize oldSize; // note that QDesktopWidget::resizeEvent ignores the QResizeEvent contents
- QResizeEvent event(size, oldSize);
- QApplication::instance()->sendEvent(QApplication::desktop(), &event);
- }
- if (buttonGroupVisibilityChanged && !statusPaneVisibilityChanged && QApplication::activeWindow())
- // Ensure that control rectangle is updated
- static_cast<QSymbianControl *>(QApplication::activeWindow()->winId())->handleClientAreaChange();
-}
-
-bool QS60Data::setRecursiveDecorationsVisibility(QWidget *window, Qt::WindowStates newState)
-{
- // Show statusbar:
- // Topmost parent: Show unless fullscreen/minimized.
- // Child windows: Follow topmost parent, unless fullscreen, in which case do not show statusbar
- // Show CBA:
- // Topmost parent: Show unless fullscreen/minimized.
- // Exception: Show if fullscreen with Qt::WindowSoftkeysVisibleHint.
- // Child windows:
- // Minimized: Unclear if there is an use case for having focused minimized window at all.
- // Always follow topmost parent just to be safe.
- // Maximized and normal: follow topmost parent.
- // Exception: If topmost parent is not showing CBA, show CBA if any softkey actions are
- // defined.
- // Fullscreen: Show only if Qt::WindowSoftkeysVisibleHint set.
-
- Qt::WindowStates comparisonState = newState;
- QWidget *parentWindow = window->parentWidget();
- if (parentWindow) {
- while (parentWindow->parentWidget())
- parentWindow = parentWindow->parentWidget();
- comparisonState = parentWindow->windowState();
- } else {
- parentWindow = window;
- }
-
- bool decorationsVisible = !(comparisonState & (Qt::WindowFullScreen | Qt::WindowMinimized));
- const bool parentIsFullscreen = comparisonState & Qt::WindowFullScreen;
- const bool parentCbaVisibilityHint = parentWindow->windowFlags() & Qt::WindowSoftkeysVisibleHint;
- bool buttonGroupVisibility = (decorationsVisible || (parentIsFullscreen && parentCbaVisibilityHint));
-
- // Do extra checking for child windows
- if (window->parentWidget()) {
- if (newState & Qt::WindowFullScreen) {
- decorationsVisible = false;
- if (window->windowFlags() & Qt::WindowSoftkeysVisibleHint)
- buttonGroupVisibility = true;
- else
- buttonGroupVisibility = false;
- } else if (!(newState & Qt::WindowMinimized) && !buttonGroupVisibility) {
- for (int i = 0; i < window->actions().size(); ++i) {
- if (window->actions().at(i)->softKeyRole() != QAction::NoSoftKey) {
- buttonGroupVisibility = true;
- break;
- }
- }
- }
- }
-
- S60->setStatusPaneAndButtonGroupVisibility(decorationsVisible, buttonGroupVisibility);
-
- return decorationsVisible;
-}
-#endif
-
-void QS60Data::controlVisibilityChanged(CCoeControl *control, bool visible)
-{
- if (QWidgetPrivate::mapper && QWidgetPrivate::mapper->contains(control)) {
- QWidget *const widget = QWidgetPrivate::mapper->value(control);
- QWidget *const window = widget->window();
- if (QTLWExtra *topData = qt_widget_private(window)->maybeTopData()) {
- QWidgetBackingStoreTracker &backingStore = topData->backingStore;
- if (visible) {
- if (backingStore.data()) {
- backingStore.registerWidget(widget);
- } else {
- backingStore.create(window);
- backingStore.registerWidget(widget);
- qt_widget_private(widget)->invalidateBuffer(widget->rect());
- widget->repaint();
- }
- } else {
- // In certain special scenarios we may get an ENotVisible event
- // without a previous EPartiallyVisible. The backingstore must
- // still be destroyed, hence the registerWidget() call below.
- if (backingStore.data() && widget->internalWinId()
- && qt_widget_private(widget)->maybeBackingStore() == backingStore.data())
- backingStore.registerWidget(widget);
- backingStore.unregisterWidget(widget);
- // In order to ensure that any resources used by the window surface
- // are immediately freed, we flush the WSERV command buffer.
- S60->wsSession().Flush();
- }
- }
- }
-}
-
-bool qt_nograb() // application no-grab option
-{
-#if defined(QT_DEBUG)
- return appNoGrab;
-#else
- return false;
-#endif
-}
-
-// Modified from http://www3.symbian.com/faq.nsf/0/0F1464EE96E737E780256D5E00503DD1?OpenDocument
-class QS60Beep : public CBase, public MMdaAudioToneObserver
-{
-public:
- static QS60Beep* NewL(TInt aFrequency, TTimeIntervalMicroSeconds iDuration);
- void Play();
- ~QS60Beep();
-private:
- void ConstructL(TInt aFrequency, TTimeIntervalMicroSeconds iDuration);
- void MatoPrepareComplete(TInt aError);
- void MatoPlayComplete(TInt aError);
-private:
- typedef enum
- {
- EBeepNotPrepared,
- EBeepPrepared,
- EBeepPlaying
- } TBeepState;
-private:
- CMdaAudioToneUtility* iToneUtil;
- TBeepState iState;
- TInt iFrequency;
- TTimeIntervalMicroSeconds iDuration;
-};
-
-static QS60Beep* qt_S60Beep = 0;
-
-QS60Beep::~QS60Beep()
-{
- if (iToneUtil) {
- switch (iState) {
- case EBeepPlaying:
- iToneUtil->CancelPlay();
- break;
- case EBeepNotPrepared:
- iToneUtil->CancelPrepare();
- break;
- }
- }
- delete iToneUtil;
-}
-
-QS60Beep* QS60Beep::NewL(TInt aFrequency, TTimeIntervalMicroSeconds aDuration)
-{
- QS60Beep* self = new (ELeave) QS60Beep();
- CleanupStack::PushL(self);
- self->ConstructL(aFrequency, aDuration);
- CleanupStack::Pop();
- return self;
-}
-
-void QS60Beep::ConstructL(TInt aFrequency, TTimeIntervalMicroSeconds aDuration)
-{
- iToneUtil = CMdaAudioToneUtility::NewL(*this);
- iState = EBeepNotPrepared;
- iFrequency = aFrequency;
- iDuration = aDuration;
- iToneUtil->PrepareToPlayTone(iFrequency, iDuration);
-}
-
-void QS60Beep::Play()
-{
- if (iState == EBeepPlaying) {
- iToneUtil->CancelPlay();
- iState = EBeepPrepared;
- }
-
- iToneUtil->Play();
- iState = EBeepPlaying;
-}
-
-void QS60Beep::MatoPrepareComplete(TInt aError)
-{
- if (aError == KErrNone) {
- iState = EBeepPrepared;
- Play();
- }
-}
-
-void QS60Beep::MatoPlayComplete(TInt aError)
-{
- Q_UNUSED(aError);
- iState = EBeepPrepared;
-}
-
-
-static Qt::KeyboardModifiers mapToQtModifiers(TUint s60Modifiers)
-{
- Qt::KeyboardModifiers result = Qt::NoModifier;
-
- if (s60Modifiers & EModifierKeypad)
- result |= Qt::KeypadModifier;
- if (s60Modifiers & EModifierShift || s60Modifiers & EModifierLeftShift
- || s60Modifiers & EModifierRightShift)
- result |= Qt::ShiftModifier;
- if (s60Modifiers & EModifierCtrl || s60Modifiers & EModifierLeftCtrl
- || s60Modifiers & EModifierRightCtrl)
- result |= Qt::ControlModifier;
- if (s60Modifiers & EModifierAlt || s60Modifiers & EModifierLeftAlt
- || s60Modifiers & EModifierRightAlt)
- result |= Qt::AltModifier;
-
- return result;
-}
-
-static void mapS60MouseEventTypeToQt(QEvent::Type *type, Qt::MouseButton *button, const TPointerEvent *pEvent)
-{
- switch (pEvent->iType) {
- case TPointerEvent::EButton1Down:
- *type = QEvent::MouseButtonPress;
- *button = Qt::LeftButton;
- break;
- case TPointerEvent::EButton1Up:
- *type = QEvent::MouseButtonRelease;
- *button = Qt::LeftButton;
- break;
- case TPointerEvent::EButton2Down:
- *type = QEvent::MouseButtonPress;
- *button = Qt::MidButton;
- break;
- case TPointerEvent::EButton2Up:
- *type = QEvent::MouseButtonRelease;
- *button = Qt::MidButton;
- break;
- case TPointerEvent::EButton3Down:
- *type = QEvent::MouseButtonPress;
- *button = Qt::RightButton;
- break;
- case TPointerEvent::EButton3Up:
- *type = QEvent::MouseButtonRelease;
- *button = Qt::RightButton;
- break;
- case TPointerEvent::EDrag:
- *type = QEvent::MouseMove;
- *button = Qt::NoButton;
- break;
- case TPointerEvent::EMove:
- // Qt makes no distinction between move and drag
- *type = QEvent::MouseMove;
- *button = Qt::NoButton;
- break;
- default:
- *type = QEvent::None;
- *button = Qt::NoButton;
- break;
- }
- if (pEvent->iModifiers & EModifierDoubleClick){
- *type = QEvent::MouseButtonDblClick;
- }
-
- if (*type == QEvent::MouseButtonPress || *type == QEvent::MouseButtonDblClick)
- QApplicationPrivate::mouse_buttons = QApplicationPrivate::mouse_buttons | (*button);
- else if (*type == QEvent::MouseButtonRelease)
- QApplicationPrivate::mouse_buttons = QApplicationPrivate::mouse_buttons &(~(*button));
-
- QApplicationPrivate::mouse_buttons = QApplicationPrivate::mouse_buttons & Qt::MouseButtonMask;
-}
-
-//### Can be replaced with CAknLongTapDetector if animation is required.
-//NOTE: if CAknLongTapDetector is used make sure it gets variated out of 3.1 and 3.2,.
-//also MLongTapObserver needs to be changed to MAknLongTapDetectorCallBack if CAknLongTapDetector is used.
-class QLongTapTimer : public CTimer
-{
-public:
- static QLongTapTimer* NewL(QAbstractLongTapObserver *observer);
- QLongTapTimer(QAbstractLongTapObserver *observer);
- void ConstructL();
-public:
- void PointerEventL(const TPointerEvent &event);
- void RunL();
-protected:
-private:
- QAbstractLongTapObserver *m_observer;
- TPointerEvent m_event;
- QPoint m_pressedCoordinates;
- int m_dragDistance;
-};
-
-QLongTapTimer* QLongTapTimer::NewL(QAbstractLongTapObserver *observer)
-{
- QLongTapTimer* self = new QLongTapTimer(observer);
- self->ConstructL();
- return self;
-}
-void QLongTapTimer::ConstructL()
-{
- CTimer::ConstructL();
-}
-
-QLongTapTimer::QLongTapTimer(QAbstractLongTapObserver *observer):CTimer(CActive::EPriorityHigh)
-{
- m_observer = observer;
- m_dragDistance = qApp->startDragDistance();
- CActiveScheduler::Add(this);
-}
-
-void QLongTapTimer::PointerEventL(const TPointerEvent& event)
-{
- if ( event.iType == TPointerEvent::EDrag || event.iType == TPointerEvent::EButtonRepeat)
- {
- QPoint diff(QPoint(event.iPosition.iX,event.iPosition.iY) - m_pressedCoordinates);
- if (diff.manhattanLength() < m_dragDistance)
- return;
- }
- Cancel();
- m_event = event;
- if (event.iType == TPointerEvent::EButton1Down)
- {
- m_pressedCoordinates = QPoint(event.iPosition.iX,event.iPosition.iY);
- // must be same as KLongTapDelay in aknlongtapdetector.h
- After(800000);
- }
-}
-void QLongTapTimer::RunL()
-{
- if (m_observer)
- m_observer->HandleLongTapEventL(m_event.iPosition, m_event.iParentPosition);
-}
-
-QSymbianControl::QSymbianControl(QWidget *w)
- : CCoeControl()
- , qwidget(w)
- , m_longTapDetector(0)
- , m_ignoreFocusChanged(0)
- , m_symbianPopupIsOpen(0)
- , m_inExternalScreenOverride(false)
- , m_lastStatusPaneVisibility(0)
-{
-}
-
-void QSymbianControl::ConstructL(bool isWindowOwning, bool desktop)
-{
- if (!desktop)
- {
- if (isWindowOwning || !qwidget->parentWidget()
- || qwidget->parentWidget()->windowType() == Qt::Desktop) {
- RWindowGroup &wg(S60->windowGroup(qwidget));
- CreateWindowL(wg);
- } else {
- /**
- * TODO: in order to avoid creating windows for all ancestors of
- * this widget up to the root window, the parameter passed to
- * CreateWindowL should be
- * qwidget->parentWidget()->effectiveWinId(). However, if we do
- * this, then we need to take care of re-parenting when a window
- * is created for a widget between this one and the root window.
- */
- CreateWindowL(qwidget->parentWidget()->winId());
- }
-
- // Necessary in order to be able to track the activation status of
- // the control's window
- qwidget->d_func()->createExtra();
-
- SetFocusing(true);
- m_longTapDetector = QLongTapTimer::NewL(this);
- m_doubleClickTimer.invalidate();
-
- DrawableWindow()->SetPointerGrab(ETrue);
- }
-
-#ifdef Q_SYMBIAN_TRANSITION_EFFECTS
- if (OwnsWindow()) {
- TTfxWindowPurpose windowPurpose(ETfxPurposeNone);
- switch (qwidget->windowType()) {
- case Qt::Dialog:
- windowPurpose = ETfxPurposeDialogWindow;
- break;
- case Qt::Popup:
- windowPurpose = ETfxPurposePopupWindow;
- break;
- case Qt::Tool:
- windowPurpose = ETfxPurposeToolWindow;
- break;
- case Qt::ToolTip:
- windowPurpose = ETfxPurposeToolTipWindow;
- break;
- case Qt::SplashScreen:
- windowPurpose = ETfxPurposeSplashScreenWindow;
- break;
- default:
- windowPurpose = (isWindowOwning || !qwidget->parentWidget() || qwidget->parentWidget()->windowType() == Qt::Desktop)
- ? ETfxPurposeWindow : ETfxPurposeChildWindow;
- break;
- }
- Window().SetPurpose(windowPurpose);
- }
-#endif
-}
-
-QSymbianControl::~QSymbianControl()
-{
- // Ensure backing store is deleted before the top-level
- // window is destroyed
- qt_widget_private(qwidget)->topData()->backingStore.destroy();
-
- if (S60->curWin == this)
- S60->curWin = 0;
- if (!QApplicationPrivate::is_app_closing) {
- QT_TRY {
- setFocusSafely(false);
- } QT_CATCH(const std::exception&) {
- // ignore exceptions, nothing can be done
- }
- }
- S60->appUi()->RemoveFromStack(this);
- delete m_longTapDetector;
-}
-
-void QSymbianControl::setWidget(QWidget *w)
-{
- qwidget = w;
-}
-
-QPoint QSymbianControl::translatePointForFixedNativeOrientation(const TPoint &pointerEventPos) const
-{
- QPoint pos(pointerEventPos.iX, pointerEventPos.iY);
- if (qwidget->d_func()->fixNativeOrientationCalled) {
- QSize wsize = qwidget->size();
- TSize size = Size();
- if (size.iWidth == wsize.height() && size.iHeight == wsize.width()) {
- qreal x = pos.x();
- qreal y = pos.y();
- pos.setX(size.iHeight - y);
- pos.setY(x);
- }
- }
- return pos;
-}
-
-TRect QSymbianControl::translateRectForFixedNativeOrientation(const TRect &controlRect) const
-{
- TRect rect = controlRect;
- if (qwidget->d_func()->fixNativeOrientationCalled) {
- QPoint a = translatePointForFixedNativeOrientation(rect.iTl);
- QPoint b = translatePointForFixedNativeOrientation(rect.iBr);
- if (a.x() < b.x()) {
- rect.iTl.iX = a.x();
- rect.iBr.iX = b.x();
- } else {
- rect.iTl.iX = b.x();
- rect.iBr.iX = a.x();
- }
- if (a.y() < b.y()) {
- rect.iTl.iY = a.y();
- rect.iBr.iY = b.y();
- } else {
- rect.iTl.iY = b.y();
- rect.iBr.iY = a.y();
- }
- }
- return rect;
-}
-
-void QSymbianControl::HandleLongTapEventL( const TPoint& aPenEventLocation, const TPoint& aPenEventScreenLocation )
-{
- QWidget *alienWidget;
- QPoint widgetPos = translatePointForFixedNativeOrientation(aPenEventLocation);
- QPoint globalPos = translatePointForFixedNativeOrientation(aPenEventScreenLocation);
- alienWidget = qwidget->childAt(widgetPos);
- if (!alienWidget)
- alienWidget = qwidget;
-
-#if !defined(QT_NO_CONTEXTMENU)
- QContextMenuEvent contextMenuEvent(QContextMenuEvent::Mouse, widgetPos, globalPos, Qt::NoModifier);
- qt_sendSpontaneousEvent(alienWidget, &contextMenuEvent);
-#endif
-}
-
-#ifdef QT_SYMBIAN_SUPPORTS_ADVANCED_POINTER
-void QSymbianControl::translateAdvancedPointerEvent(const TAdvancedPointerEvent *event)
-{
- QApplicationPrivate *d = QApplicationPrivate::instance();
- QPointF screenPos = qwidget->mapToGlobal(translatePointForFixedNativeOrientation(event->iPosition));
- qreal pressure;
- if(d->pressureSupported
- && event->Pressure() > 0) //workaround for misconfigured HAL
- pressure = event->Pressure() / qreal(d->maxTouchPressure);
- else
- pressure = qreal(1.0);
- processTouchEvent(event->PointerNumber(), event->iType, screenPos, pressure);
-}
-#endif
-
-void QSymbianControl::processTouchEvent(int pointerNumber, TPointerEvent::TType type, QPointF screenPos, qreal pressure)
-{
- QRect screenGeometry = qApp->desktop()->screenGeometry(qwidget);
-
- QApplicationPrivate *d = QApplicationPrivate::instance();
-
- QList<QTouchEvent::TouchPoint> points = d->appAllTouchPoints;
- while (points.count() <= pointerNumber)
- points.append(QTouchEvent::TouchPoint(points.count()));
-
- Qt::TouchPointStates allStates = 0;
- for (int i = 0; i < points.count(); ++i) {
- QTouchEvent::TouchPoint &touchPoint = points[i];
-
- if (touchPoint.id() == pointerNumber) {
- Qt::TouchPointStates state;
- switch (type) {
- case TPointerEvent::EButton1Down:
-#ifdef QT_SYMBIAN_SUPPORTS_ADVANCED_POINTER
- case TPointerEvent::EEnterHighPressure:
-#endif
- state = Qt::TouchPointPressed;
- break;
- case TPointerEvent::EButton1Up:
-#ifdef QT_SYMBIAN_SUPPORTS_ADVANCED_POINTER
- case TPointerEvent::EExitCloseProximity:
-#endif
- state = Qt::TouchPointReleased;
- break;
- case TPointerEvent::EDrag:
- state = Qt::TouchPointMoved;
- break;
- default:
- // how likely is this to happen?
- state = Qt::TouchPointStationary;
- break;
- }
- if (pointerNumber == 0)
- state |= Qt::TouchPointPrimary;
- touchPoint.setState(state);
-
- touchPoint.setScreenPos(screenPos);
- touchPoint.setNormalizedPos(QPointF(screenPos.x() / screenGeometry.width(),
- screenPos.y() / screenGeometry.height()));
-
- touchPoint.setPressure(pressure);
- } else if (touchPoint.state() != Qt::TouchPointReleased) {
- // all other active touch points should be marked as stationary
- touchPoint.setState(Qt::TouchPointStationary);
- }
-
- allStates |= touchPoint.state();
- }
-
- if ((allStates & Qt::TouchPointStateMask) == Qt::TouchPointReleased) {
- // all touch points released
- d->appAllTouchPoints.clear();
- } else {
- d->appAllTouchPoints = points;
- }
-
- QApplicationPrivate::translateRawTouchEvent(qwidget,
- QTouchEvent::TouchScreen,
- points);
-}
-
-void QSymbianControl::HandlePointerEventL(const TPointerEvent& pEvent)
-{
-#ifdef QT_SYMBIAN_SUPPORTS_ADVANCED_POINTER
- if (pEvent.IsAdvancedPointerEvent()) {
- const TAdvancedPointerEvent *advancedPointerEvent = pEvent.AdvancedPointerEvent();
- translateAdvancedPointerEvent(advancedPointerEvent);
- if (advancedPointerEvent->PointerNumber() != 0) {
- // only send mouse events for the first touch point
- return;
- }
- }
-#endif
-
- m_longTapDetector->PointerEventL(pEvent);
- QT_TRYCATCH_LEAVING(HandlePointerEvent(pEvent));
-}
-
-void QSymbianControl::HandlePointerEvent(const TPointerEvent& pEvent)
-{
- QMouseEvent::Type type;
- Qt::MouseButton button;
- mapS60MouseEventTypeToQt(&type, &button, &pEvent);
- Qt::KeyboardModifiers modifiers = mapToQtModifiers(pEvent.iModifiers);
- app_keyboardModifiers = modifiers;
-
- QPoint widgetPos = translatePointForFixedNativeOrientation(pEvent.iPosition);
- TPoint controlScreenPos = PositionRelativeToScreen();
- QPoint globalPos = QPoint(controlScreenPos.iX, controlScreenPos.iY) + widgetPos;
- S60->lastCursorPos = globalPos;
- S60->lastPointerEventPos = widgetPos;
-
- QWidget *mouseGrabber = QWidget::mouseGrabber();
-
- QWidget *popupWidget = qApp->activePopupWidget();
- QWidget *popupReceiver = 0;
- if (popupWidget) {
- QWidget *popupChild = popupWidget->childAt(popupWidget->mapFromGlobal(globalPos));
- popupReceiver = popupChild ? popupChild : popupWidget;
- }
-
- if (mouseGrabber) {
- if (popupReceiver) {
- sendMouseEvent(popupReceiver, type, globalPos, button, modifiers);
- } else {
- sendMouseEvent(mouseGrabber, type, globalPos, button, modifiers);
- }
- // No Enter/Leave events in grabbing mode.
- return;
- }
-
- QWidget *widgetUnderPointer = qwidget->childAt(widgetPos);
- if (!widgetUnderPointer)
- widgetUnderPointer = qwidget;
-
- QApplicationPrivate::dispatchEnterLeave(widgetUnderPointer, S60->lastPointerEventTarget);
- S60->lastPointerEventTarget = widgetUnderPointer;
-
- QWidget *receiver;
- if (!popupReceiver && S60->mousePressTarget && type != QEvent::MouseButtonPress) {
- receiver = S60->mousePressTarget;
- if (type == QEvent::MouseButtonRelease)
- S60->mousePressTarget = 0;
- } else {
- receiver = popupReceiver ? popupReceiver : widgetUnderPointer;
- if (type == QEvent::MouseButtonPress)
- S60->mousePressTarget = receiver;
- }
-
-#if !defined(QT_NO_CURSOR) && !defined(Q_SYMBIAN_FIXED_POINTER_CURSORS)
- if (S60->brokenPointerCursors)
- qt_symbian_move_cursor_sprite();
-#endif
-
-//Generate single touch event for S60 5.0 (has touchscreen, does not have advanced pointers)
-#ifndef QT_SYMBIAN_SUPPORTS_ADVANCED_POINTER
- if (S60->hasTouchscreen) {
- processTouchEvent(0, pEvent.iType, QPointF(globalPos), 1.0);
- }
-#endif
-
- sendMouseEvent(receiver, type, globalPos, button, modifiers);
-}
-
-#ifdef Q_WS_S60
-void QSymbianControl::HandleStatusPaneSizeChange()
-{
- QS60MainAppUi *s60AppUi = static_cast<QS60MainAppUi *>(S60->appUi());
- s60AppUi->HandleStatusPaneSizeChange();
-}
-#endif
-
-void QSymbianControl::sendMouseEvent(
- QWidget *receiver,
- QEvent::Type type,
- const QPoint &globalPos,
- Qt::MouseButton button,
- Qt::KeyboardModifiers modifiers)
-{
- Q_ASSERT(receiver);
- QMouseEvent mEvent(type, receiver->mapFromGlobal(globalPos), globalPos,
- button, QApplicationPrivate::mouse_buttons, modifiers);
- QEventDispatcherS60 *dispatcher;
- // It is theoretically possible for someone to install a different event dispatcher.
- if ((dispatcher = qobject_cast<QEventDispatcherS60 *>(receiver->d_func()->threadData->eventDispatcher)) != 0) {
- if (dispatcher->excludeUserInputEvents()) {
- dispatcher->saveInputEvent(this, receiver, new QMouseEvent(mEvent));
- return;
- }
- }
-
- sendMouseEvent(receiver, &mEvent);
-}
-
-bool QSymbianControl::sendMouseEvent(QWidget *widget, QMouseEvent *mEvent)
-{
- return qt_sendSpontaneousEvent(widget, mEvent);
-}
-
-TKeyResponse QSymbianControl::OfferKeyEventL(const TKeyEvent& keyEvent, TEventCode type)
-{
- TKeyResponse r = EKeyWasNotConsumed;
- QT_TRYCATCH_LEAVING(r = OfferKeyEvent(keyEvent, type));
- return r;
-}
-
-TKeyResponse QSymbianControl::OfferKeyEvent(const TKeyEvent& keyEvent, TEventCode type)
-{
- /*
- S60 has a confusing way of delivering key events. There are three types of
- events: EEventKey, EEventKeyDown and EEventKeyUp. When a key is pressed,
- EEventKeyDown is first generated, followed by EEventKey. Then, when the key is
- released, EEventKeyUp is generated.
- However, it is possible that only the EEventKey is generated alone, typically
- in relation to virtual keyboards. In that case we need to take care to
- generate both press and release events in Qt, since applications expect that.
- We do this by having three states for each used scan code, depending on the
- events received. See the switch below for what happens in each state
- transition.
- */
-
- if (type != EEventKeyDown)
- if (handleVirtualMouse(keyEvent, type) == EKeyWasConsumed)
- return EKeyWasConsumed;
-
- TKeyResponse ret = EKeyWasNotConsumed;
-#define GET_RETURN(x) (ret = ((x) == EKeyWasConsumed) ? EKeyWasConsumed : ret)
-
- // This top level switch corresponds to the states, and the inner switches
- // correspond to the transitions.
- QS60Data::ScanCodeState &scanCodeState = S60->scanCodeStates[keyEvent.iScanCode];
- switch (scanCodeState) {
- case QS60Data::Unpressed:
- switch (type) {
- case EEventKeyDown:
- scanCodeState = QS60Data::KeyDown;
- break;
- case EEventKey:
- GET_RETURN(sendSymbianKeyEvent(keyEvent, QEvent::KeyPress));
- GET_RETURN(sendSymbianKeyEvent(keyEvent, QEvent::KeyRelease));
- break;
- case EEventKeyUp:
- // No action.
- break;
- }
- break;
- case QS60Data::KeyDown:
- switch (type) {
- case EEventKeyDown:
- // This should never happen, just stay in this state to be safe.
- break;
- case EEventKey:
- GET_RETURN(sendSymbianKeyEvent(keyEvent, QEvent::KeyPress));
- scanCodeState = QS60Data::KeyDownAndKey;
- break;
- case EEventKeyUp:
- scanCodeState = QS60Data::Unpressed;
- break;
- }
- break;
- case QS60Data::KeyDownAndKey:
- switch (type) {
- case EEventKeyDown:
- // This should never happen, just stay in this state to be safe.
- break;
- case EEventKey:
- GET_RETURN(sendSymbianKeyEvent(keyEvent, QEvent::KeyRelease));
- GET_RETURN(sendSymbianKeyEvent(keyEvent, QEvent::KeyPress));
- break;
- case EEventKeyUp:
- GET_RETURN(sendSymbianKeyEvent(keyEvent, QEvent::KeyRelease));
- scanCodeState = QS60Data::Unpressed;
- break;
- }
- break;
- }
- return ret;
-
-#undef GET_RETURN
-}
-
-TKeyResponse QSymbianControl::sendSymbianKeyEvent(const TKeyEvent &keyEvent, QEvent::Type type)
-{
- // Because S60 does not generate keysyms for EKeyEventDown and EKeyEventUp
- // events, we need to cache the keysyms from the EKeyEvent events. This is what
- // resolveS60ScanCode does.
- TUint s60Keysym = QApplicationPrivate::resolveS60ScanCode(keyEvent.iScanCode,
- keyEvent.iCode);
- int keyCode;
- if (s60Keysym == EKeyNull){ //some key events have 0 in iCode, for them iScanCode should be used
- keyCode = qt_keymapper_private()->mapS60ScanCodesToQt(keyEvent.iScanCode);
- } else if (s60Keysym >= 0x20 && s60Keysym < ENonCharacterKeyBase) {
- // Normal characters keys.
- keyCode = s60Keysym;
- } else {
- // Special S60 keys.
- keyCode = qt_keymapper_private()->mapS60KeyToQt(s60Keysym);
- }
-
- Qt::KeyboardModifiers mods = mapToQtModifiers(keyEvent.iModifiers);
- QKeyEventEx qKeyEvent(type, keyCode, mods, qt_keymapper_private()->translateKeyEvent(keyCode, mods),
- (keyEvent.iRepeats != 0), 1, keyEvent.iScanCode, s60Keysym, keyEvent.iModifiers);
- QWidget *widget;
- widget = QWidget::keyboardGrabber();
- if (!widget) {
- if (QApplicationPrivate::popupWidgets != 0) {
- widget = QApplication::activePopupWidget()->focusWidget();
- if (!widget) {
- widget = QApplication::activePopupWidget();
- }
- } else {
- widget = QApplicationPrivate::focus_widget;
- if (!widget) {
- widget = qwidget;
- }
- }
- }
-
- QEventDispatcherS60 *dispatcher;
- // It is theoretically possible for someone to install a different event dispatcher.
- if ((dispatcher = qobject_cast<QEventDispatcherS60 *>(widget->d_func()->threadData->eventDispatcher)) != 0) {
- if (dispatcher->excludeUserInputEvents()) {
- dispatcher->saveInputEvent(this, widget, new QKeyEventEx(qKeyEvent));
- return EKeyWasConsumed;
- }
- }
- return sendKeyEvent(widget, &qKeyEvent);
-}
-
-TKeyResponse QSymbianControl::handleVirtualMouse(const TKeyEvent& keyEvent,TEventCode type)
-{
-#ifndef QT_NO_CURSOR
- if (S60->mouseInteractionEnabled && S60->virtualMouseRequired) {
- //translate keys to pointer
- if ((keyEvent.iScanCode >= EStdKeyLeftArrow && keyEvent.iScanCode <= EStdKeyDownArrow) ||
- (keyEvent.iScanCode >= EStdKeyDevice10 && keyEvent.iScanCode <= EStdKeyDevice13) ||
- keyEvent.iScanCode == EStdKeyDevice3) {
- QPoint pos = QCursor::pos();
- TPointerEvent fakeEvent;
- fakeEvent.iType = (TPointerEvent::TType)(-1);
- fakeEvent.iModifiers = keyEvent.iModifiers;
- TInt x = pos.x();
- TInt y = pos.y();
- if (type == EEventKeyUp) {
- S60->virtualMouseAccelTimeout.start();
- switch (keyEvent.iScanCode) {
- case EStdKeyLeftArrow:
- S60->virtualMousePressedKeys &= ~QS60Data::Left;
- break;
- case EStdKeyRightArrow:
- S60->virtualMousePressedKeys &= ~QS60Data::Right;
- break;
- case EStdKeyUpArrow:
- S60->virtualMousePressedKeys &= ~QS60Data::Up;
- break;
- case EStdKeyDownArrow:
- S60->virtualMousePressedKeys &= ~QS60Data::Down;
- break;
- // diagonal keys (named aliases don't exist in 3.1 SDK)
- case EStdKeyDevice10:
- S60->virtualMousePressedKeys &= ~QS60Data::LeftUp;
- break;
- case EStdKeyDevice11:
- S60->virtualMousePressedKeys &= ~QS60Data::RightUp;
- break;
- case EStdKeyDevice12:
- S60->virtualMousePressedKeys &= ~QS60Data::RightDown;
- break;
- case EStdKeyDevice13:
- S60->virtualMousePressedKeys &= ~QS60Data::LeftDown;
- break;
- case EStdKeyDevice3: //select
- if (S60->virtualMousePressedKeys & QS60Data::Select)
- fakeEvent.iType = TPointerEvent::EButton1Up;
- S60->virtualMousePressedKeys &= ~QS60Data::Select;
- break;
- }
- }
- else if (type == EEventKey) {
- int dx = 0;
- int dy = 0;
- if (keyEvent.iScanCode != EStdKeyDevice3) {
- m_doubleClickTimer.invalidate();
- //reset mouse accelleration after a short time with no moves
- const int maxTimeBetweenKeyEventsMs = 500;
- if (S60->virtualMouseAccelTimeout.isValid() &&
- S60->virtualMouseAccelTimeout.hasExpired(maxTimeBetweenKeyEventsMs)) {
- S60->virtualMouseAccelDX = 0;
- S60->virtualMouseAccelDY = 0;
- }
- S60->virtualMouseAccelTimeout.invalidate();
- }
- switch (keyEvent.iScanCode) {
- case EStdKeyLeftArrow:
- S60->virtualMousePressedKeys |= QS60Data::Left;
- dx = -1;
- fakeEvent.iType = TPointerEvent::EMove;
- break;
- case EStdKeyRightArrow:
- S60->virtualMousePressedKeys |= QS60Data::Right;
- dx = 1;
- fakeEvent.iType = TPointerEvent::EMove;
- break;
- case EStdKeyUpArrow:
- S60->virtualMousePressedKeys |= QS60Data::Up;
- dy = -1;
- fakeEvent.iType = TPointerEvent::EMove;
- break;
- case EStdKeyDownArrow:
- S60->virtualMousePressedKeys |= QS60Data::Down;
- dy = 1;
- fakeEvent.iType = TPointerEvent::EMove;
- break;
- case EStdKeyDevice10:
- S60->virtualMousePressedKeys |= QS60Data::LeftUp;
- dx = -1;
- dy = -1;
- fakeEvent.iType = TPointerEvent::EMove;
- break;
- case EStdKeyDevice11:
- S60->virtualMousePressedKeys |= QS60Data::RightUp;
- dx = 1;
- dy = -1;
- fakeEvent.iType = TPointerEvent::EMove;
- break;
- case EStdKeyDevice12:
- S60->virtualMousePressedKeys |= QS60Data::RightDown;
- dx = 1;
- dy = 1;
- fakeEvent.iType = TPointerEvent::EMove;
- break;
- case EStdKeyDevice13:
- S60->virtualMousePressedKeys |= QS60Data::LeftDown;
- dx = -1;
- dy = 1;
- fakeEvent.iType = TPointerEvent::EMove;
- break;
- case EStdKeyDevice3:
- // Platform bug. If you start pressing several keys simultaneously (for
- // example for drag'n'drop), Symbian starts producing spurious up and
- // down messages for some keys. Therefore, make sure we have a clean slate
- // of pressed keys before starting a new button press.
- if (S60->virtualMousePressedKeys & QS60Data::Select) {
- return EKeyWasConsumed;
- } else {
- S60->virtualMousePressedKeys |= QS60Data::Select;
- fakeEvent.iType = TPointerEvent::EButton1Down;
- if (m_doubleClickTimer.isValid()
- && !m_doubleClickTimer.hasExpired(QApplication::doubleClickInterval())) {
- fakeEvent.iModifiers |= EModifierDoubleClick;
- m_doubleClickTimer.invalidate();
- } else {
- m_doubleClickTimer.start();
- }
- }
- break;
- }
- if (dx) {
- int cdx = S60->virtualMouseAccelDX;
- //reset accel on change of sign, else double accel
- if (dx * cdx <= 0)
- cdx = dx;
- else
- cdx *= 4;
- //cap accelleration
- if (dx * cdx > S60->virtualMouseMaxAccel)
- cdx = dx * S60->virtualMouseMaxAccel;
- //move mouse position
- x += cdx;
- S60->virtualMouseAccelDX = cdx;
- }
-
- if (dy) {
- int cdy = S60->virtualMouseAccelDY;
- if (dy * cdy <= 0)
- cdy = dy;
- else
- cdy *= 4;
- if (dy * cdy > S60->virtualMouseMaxAccel)
- cdy = dy * S60->virtualMouseMaxAccel;
- y += cdy;
- S60->virtualMouseAccelDY = cdy;
- }
- }
- //clip to screen size (window server allows a sprite hotspot to be outside the screen)
- int screenNumber = S60->screenNumberForWidget(qwidget);
- if (x < 0)
- x = 0;
- else if (x >= S60->screenWidthInPixelsForScreen[screenNumber])
- x = S60->screenWidthInPixelsForScreen[screenNumber] - 1;
- if (y < 0)
- y = 0;
- else if (y >= S60->screenHeightInPixelsForScreen[screenNumber])
- y = S60->screenHeightInPixelsForScreen[screenNumber] - 1;
- TPoint epos(x, y);
- TPoint cpos = epos - PositionRelativeToScreen();
- fakeEvent.iPosition = cpos;
- fakeEvent.iParentPosition = epos;
- if(fakeEvent.iType != -1)
- HandlePointerEvent(fakeEvent);
- return EKeyWasConsumed;
- }
- }
-#endif
-
- return EKeyWasNotConsumed;
-}
-
-void QSymbianControl::sendInputEvent(QWidget *widget, QInputEvent *inputEvent)
-{
- switch (inputEvent->type()) {
- case QEvent::KeyPress:
- case QEvent::KeyRelease:
- sendKeyEvent(widget, static_cast<QKeyEvent *>(inputEvent));
- break;
- case QEvent::MouseButtonDblClick:
- case QEvent::MouseButtonPress:
- case QEvent::MouseButtonRelease:
- case QEvent::MouseMove:
- sendMouseEvent(widget, static_cast<QMouseEvent *>(inputEvent));
- break;
- default:
- // Shouldn't get here.
- Q_ASSERT_X(0 == 1, "QSymbianControl::sendInputEvent()", "inputEvent->type() is unknown");
- break;
- }
-}
-
-TKeyResponse QSymbianControl::sendKeyEvent(QWidget *widget, QKeyEvent *keyEvent)
-{
-#if !defined(QT_NO_IM) && defined(Q_WS_S60)
- if (widget && widget->isEnabled() && widget->testAttribute(Qt::WA_InputMethodEnabled)) {
- QInputContext *qic = widget->inputContext();
- if (qic && qic->filterEvent(keyEvent))
- return EKeyWasConsumed;
- }
-#endif // !defined(QT_NO_IM) && defined(Q_OS_SYMBIAN)
-
- if (widget && qt_sendSpontaneousEvent(widget, keyEvent))
- if (keyEvent->isAccepted())
- return EKeyWasConsumed;
-
- return EKeyWasNotConsumed;
-}
-
-#if !defined(QT_NO_IM) && defined(Q_WS_S60)
-TCoeInputCapabilities QSymbianControl::InputCapabilities() const
-{
- QWidget *w = 0;
-
- if (qwidget->hasFocus())
- w = qwidget;
- else
- w = qwidget->focusWidget();
-
- QCoeFepInputContext *ic;
- if (w && w->isEnabled() && w->testAttribute(Qt::WA_InputMethodEnabled)
- && (ic = qobject_cast<QCoeFepInputContext *>(w->inputContext()))) {
- return ic->inputCapabilities();
- } else {
- return TCoeInputCapabilities(TCoeInputCapabilities::ENone, 0, 0);
- }
-}
-#endif
-
-void QSymbianControl::Draw(const TRect& controlRect) const
-{
- // Set flag to avoid calling DrawNow in window surface
- QWidget *window = qwidget->window();
- Q_ASSERT(window);
- QTLWExtra *topExtra = window->d_func()->maybeTopData();
- Q_ASSERT(topExtra);
-
- TRect wcontrolRect = translateRectForFixedNativeOrientation(controlRect);
-
- if (!topExtra->inExpose) {
- topExtra->inExpose = true;
- if (!qwidget->isWindow()) {
- // If we get here, then it means we have a native child window
- // Since no content should ever be painted to these windows, we
- // erase them with a transparent brush when they get an expose.
- CWindowGc &gc = SystemGc();
- gc.SetBrushColor(TRgb(0, 0, 0, 0));
- gc.Clear(controlRect);
- }
- QRect exposeRect = qt_TRect2QRect(wcontrolRect);
- qwidget->d_func()->syncBackingStore(exposeRect);
- topExtra->inExpose = false;
- }
-
- QWindowSurface *surface = qwidget->windowSurface();
- QPaintEngine *engine = surface ? surface->paintDevice()->paintEngine() : NULL;
-
- if (!engine)
- return;
-
- const bool sendNativePaintEvents = qwidget->d_func()->extraData()->receiveNativePaintEvents;
- if (sendNativePaintEvents) {
- const QRect r = qt_TRect2QRect(wcontrolRect);
- QMetaObject::invokeMethod(qwidget, "beginNativePaintEvent", Qt::DirectConnection, Q_ARG(QRect, r));
- }
-
- // Map source rectangle into coordinates of the backing store.
- const QPoint controlBase(controlRect.iTl.iX, controlRect.iTl.iY);
- const QPoint backingStoreBase = qwidget->mapTo(qwidget->window(), controlBase);
- const TRect backingStoreRect(TPoint(backingStoreBase.x(), backingStoreBase.y()), controlRect.Size());
-
- if (engine->type() == QPaintEngine::Raster) {
- QS60WindowSurface *s60Surface;
-#ifdef QT_GRAPHICSSYSTEM_RUNTIME
- if (QApplicationPrivate::runtime_graphics_system) {
- QRuntimeWindowSurface *rtSurface =
- static_cast<QRuntimeWindowSurface*>(qwidget->windowSurface());
- s60Surface = static_cast<QS60WindowSurface *>(rtSurface->m_windowSurface.data());
- } else
-#endif
- s60Surface = static_cast<QS60WindowSurface *>(qwidget->windowSurface());
-
- CFbsBitmap *bitmap = s60Surface->symbianBitmap();
- CWindowGc &gc = SystemGc();
-
- QWExtra::NativePaintMode nativePaintMode = qwidget->d_func()->extraData()->nativePaintMode;
- if(qwidget->d_func()->paintOnScreen())
- nativePaintMode = QWExtra::Disable;
-
- switch(nativePaintMode) {
- case QWExtra::Disable:
- // Do nothing
- break;
- case QWExtra::Blit:
- case QWExtra::BlitWriteAlpha:
- if (qwidget->d_func()->isOpaque || nativePaintMode == QWExtra::BlitWriteAlpha)
- gc.SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha);
- gc.BitBlt(controlRect.iTl, bitmap, backingStoreRect);
- break;
- case QWExtra::ZeroFill:
- if (Window().DisplayMode() == EColor16MA
- || Window().DisplayMode() == Q_SYMBIAN_ECOLOR16MAP) {
- gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
- gc.SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha);
- gc.SetBrushColor(TRgb::Color16MA(0));
- gc.Clear(controlRect);
- } else {
- gc.SetBrushColor(TRgb(0x000000));
- gc.Clear(controlRect);
- };
- break;
- default:
- Q_ASSERT(false);
- }
- }
-
- if (sendNativePaintEvents) {
- const QRect r = qt_TRect2QRect(wcontrolRect);
- // The draw ops aren't actually sent to WSERV until the graphics
- // context is deactivated, which happens in the function calling
- // this one. We therefore delay the delivery of endNativePaintEvent,
- // to ensure that drawing has completed by the time the widget
- // receives the event. Note that, if the widget needs to ensure
- // that the draw ops have actually been executed into the output
- // framebuffer, a call to RWsSession::Flush is required in the
- // endNativePaintEvent implementation.
- QMetaObject::invokeMethod(qwidget, "endNativePaintEvent", Qt::QueuedConnection, Q_ARG(QRect, r));
- }
-}
-
-void QSymbianControl::qwidgetResize_helper(const QSize &newSize)
-{
- QRect cr = qwidget->geometry();
- QSize oldSize(cr.size());
- cr.setSize(newSize);
- qwidget->data->crect = cr;
- if (qwidget->isVisible()) {
- QTLWExtra *tlwExtra = qwidget->d_func()->maybeTopData();
- bool slowResize = qgetenv("QT_SLOW_TOPLEVEL_RESIZE").toInt();
- if (!slowResize && tlwExtra)
- tlwExtra->inTopLevelResize = true;
- QResizeEvent e(newSize, oldSize);
- qt_sendSpontaneousEvent(qwidget, &e);
- if (!qwidget->testAttribute(Qt::WA_StaticContents))
- qwidget->d_func()->syncBackingStore();
- if (!slowResize && tlwExtra)
- tlwExtra->inTopLevelResize = false;
- } else {
- if (!qwidget->testAttribute(Qt::WA_PendingResizeEvent)) {
- QResizeEvent *e = new QResizeEvent(newSize, oldSize);
- QApplication::postEvent(qwidget, e);
- }
- }
-}
-
-void QSymbianControl::SizeChanged()
-{
- CCoeControl::SizeChanged();
-
- // When FixNativeOrientation had been called, the RWindow/CCoeControl size
- // and the surface/QWidget size have nothing to do with each other.
- if (qwidget->d_func()->fixNativeOrientationCalled)
- return;
-
- QSize oldSize = qwidget->size();
- QSize newSize(Size().iWidth, Size().iHeight);
-
- if (oldSize != newSize) {
- // Enforce the proper size for fullscreen widgets on the secondary screen.
- const bool isFullscreen = qwidget->windowState() & Qt::WindowFullScreen;
- const int screenNumber = S60->screenNumberForWidget(qwidget);
- if (!m_inExternalScreenOverride && isFullscreen && screenNumber > 0) {
- int screenWidth = S60->screenWidthInPixelsForScreen[screenNumber];
- int screenHeight = S60->screenHeightInPixelsForScreen[screenNumber];
- TSize screenSize(screenWidth, screenHeight);
- if (screenWidth > 0 && screenHeight > 0 && screenSize != Size()) {
- m_inExternalScreenOverride = true;
- SetExtent(TPoint(0, 0), screenSize);
- return;
- }
- }
-
- qwidgetResize_helper(newSize);
- }
-
- m_inExternalScreenOverride = false;
-
- // CCoeControl::SetExtent calls SizeChanged, but does not call
- // PositionChanged, so we call it here to ensure that the widget's
- // position is updated.
- PositionChanged();
-}
-
-void QSymbianControl::PositionChanged()
-{
- CCoeControl::PositionChanged();
-
- QPoint oldPos = qwidget->geometry().topLeft();
- QPoint newPos(Position().iX, Position().iY);
-
- if (oldPos != newPos) {
- QRect cr = qwidget->geometry();
- cr.moveTopLeft(newPos);
- qwidget->data->crect = cr;
- QTLWExtra *top = qwidget->d_func()->maybeTopData();
- if (top && (qwidget->windowState() & (~Qt::WindowActive)) == Qt::WindowNoState)
- top->normalGeometry.moveTopLeft(newPos);
- if (qwidget->isVisible()) {
- QMoveEvent e(newPos, oldPos);
- qt_sendSpontaneousEvent(qwidget, &e);
- } else {
- QMoveEvent * e = new QMoveEvent(newPos, oldPos);
- QApplication::postEvent(qwidget, e);
- }
- }
-}
-
-void QSymbianControl::FocusChanged(TDrawNow /* aDrawNow */)
-{
- if (m_ignoreFocusChanged || (qwidget->windowType() & Qt::WindowType_Mask) == Qt::Desktop)
- return;
-
-#ifdef Q_WS_S60
- if (S60->splitViewLastWidget)
- return;
-#endif
-
- // Popups never get focused, but still receive the FocusChanged when they are hidden.
- if (QApplicationPrivate::popupWidgets != 0
- || (qwidget->windowType() & Qt::Popup) == Qt::Popup)
- return;
-
- if (IsFocused() && IsVisible()) {
- if (m_symbianPopupIsOpen) {
- QWidget *fw = QApplication::focusWidget();
- if (fw) {
- QFocusEvent event(QEvent::FocusIn, Qt::PopupFocusReason);
- QCoreApplication::sendEvent(fw, &event);
- }
- m_symbianPopupIsOpen = false;
- }
-
- QApplication::setActiveWindow(qwidget->window());
- qwidget->d_func()->setWindowIcon_sys(true);
- qwidget->d_func()->setWindowTitle_sys(qwidget->windowTitle());
-#ifdef Q_WS_S60
- if (qwidget->isWindow())
- S60->setRecursiveDecorationsVisibility(qwidget, qwidget->windowState());
-#endif
- } else if (QApplication::activeWindow() == qwidget->window()) {
- bool focusedControlFound = false;
- WId winId = 0;
- for (QWidget *w = qwidget->parentWidget(); w && (winId = w->internalWinId()); w = w->parentWidget()) {
- if (winId->IsFocused() && winId->IsVisible()) {
- focusedControlFound = true;
- break;
- } else if (w->isWindow())
- break;
- }
- if (!focusedControlFound) {
- if (CCoeEnv::Static()->AppUi()->IsDisplayingMenuOrDialog() || S60->menuBeingConstructed) {
- QWidget *fw = QApplication::focusWidget();
- if (fw) {
- QFocusEvent event(QEvent::FocusOut, Qt::PopupFocusReason);
- QCoreApplication::sendEvent(fw, &event);
- }
- m_symbianPopupIsOpen = true;
- return;
- }
-
- QApplication::setActiveWindow(0);
- }
- }
- // else { We don't touch the active window unless we were explicitly activated or deactivated }
-}
-
-void QSymbianControl::handleClientAreaChange()
-{
- const bool cbaVisibilityHint = qwidget->windowFlags() & Qt::WindowSoftkeysVisibleHint;
- if (qwidget->isFullScreen() && !cbaVisibilityHint) {
- SetExtentToWholeScreen();
- } else if (qwidget->isMaximized() || (qwidget->isFullScreen() && cbaVisibilityHint)) {
- TRect r = static_cast<CEikAppUi*>(S60->appUi())->ClientRect();
- SetExtent(r.iTl, r.Size());
- } else if (!qwidget->isMinimized()) { // Normal geometry
- if (!qwidget->testAttribute(Qt::WA_Resized)) {
- qwidget->adjustSize();
- qwidget->setAttribute(Qt::WA_Resized, false); //not a user resize
- }
- if (!qwidget->testAttribute(Qt::WA_Moved) && qwidget->windowType() != Qt::Dialog) {
- TRect r = static_cast<CEikAppUi*>(S60->appUi())->ClientRect();
- SetPosition(r.iTl);
- qwidget->setAttribute(Qt::WA_Moved, false); // not really an explicit position
- }
- }
-}
-
-bool QSymbianControl::isSplitViewWidget(QWidget *widget) {
- bool returnValue = true;
- //Ignore events sent to non-active windows, not visible widgets and not parents of input widget.
- if (!qwidget->isActiveWindow()
- || !qwidget->isVisible()
- || !qwidget->isAncestorOf(widget)) {
-
- returnValue = false;
- }
- return returnValue;
-}
-
-void QSymbianControl::HandleResourceChange(int resourceType)
-{
- switch (resourceType) {
- case KSplitViewCloseEvent: //intentional fall-through
- case KSplitViewOpenEvent: {
-#if !defined(QT_NO_IM) && defined(Q_WS_S60)
-
- //Fetch widget getting the text input
- QWidget *widget = QWidget::keyboardGrabber();
- if (!widget) {
- if (QApplicationPrivate::popupWidgets) {
- widget = QApplication::activePopupWidget()->focusWidget();
- if (!widget) {
- widget = QApplication::activePopupWidget();
- }
- } else {
- widget = QApplicationPrivate::focus_widget;
- if (!widget) {
- widget = qwidget;
- }
- }
- }
- if (widget) {
- QCoeFepInputContext *ic = qobject_cast<QCoeFepInputContext *>(widget->inputContext());
- if (!ic) {
- ic = qobject_cast<QCoeFepInputContext *>(qApp->inputContext());
- }
- if (ic && isSplitViewWidget(widget)) {
- if (resourceType == KSplitViewCloseEvent) {
- ic->resetSplitViewWidget();
- } else {
- ic->ensureFocusWidgetVisible(widget);
- }
- }
- }
-#endif // !defined(QT_NO_IM) && defined(Q_WS_S60)
- }
- break;
- case KInternalStatusPaneChange:
- // When status pane is not visible, only handle client area change if status pane was
- // previously visible, as size changes to hidden status pane should not affect
- // client area.
- if (S60->statusPane() && (S60->statusPane()->IsVisible() || m_lastStatusPaneVisibility)) {
- m_lastStatusPaneVisibility = S60->statusPane()->IsVisible();
- handleClientAreaChange();
- }
- if (IsFocused() && IsVisible()) {
- qwidget->d_func()->setWindowIcon_sys(true);
- qwidget->d_func()->setWindowTitle_sys(qwidget->windowTitle());
- }
- break;
- case KUidValueCoeFontChangeEvent:
- // font change event
- break;
-#ifdef Q_WS_S60
- case KEikDynamicLayoutVariantSwitch:
- {
- handleClientAreaChange();
- // Send resize event to trigger desktopwidget workAreaResized signal
- if (qt_desktopWidget) {
- QResizeEvent e(qt_desktopWidget->size(), qt_desktopWidget->size());
- QApplication::sendEvent(qt_desktopWidget, &e);
- }
- break;
- }
-#endif
- default:
- break;
- }
-
- CCoeControl::HandleResourceChange(resourceType);
-
-}
-void QSymbianControl::CancelLongTapTimer()
-{
- m_longTapDetector->Cancel();
-}
-
-TTypeUid::Ptr QSymbianControl::MopSupplyObject(TTypeUid id)
-{
- if (id.iUid == ETypeId)
- return id.MakePtr(this);
-
- return CCoeControl::MopSupplyObject(id);
-}
-
-void QSymbianControl::setFocusSafely(bool focus)
-{
- // The stack hack in here is very unfortunate, but it is the only way to ensure proper
- // focus in Symbian. If this is not executed, the control which happens to be on
- // the top of the stack may randomly be assigned focus by Symbian, for example
- // when creating new windows (specifically in CCoeAppUi::HandleStackChanged()).
-
- // Close any popups.
- CEikonEnv::Static()->EikAppUi()->StopDisplayingMenuBar();
-
- if (focus) {
- S60->appUi()->RemoveFromStack(this);
- // Symbian doesn't automatically remove focus from the last focused control, so we need to
- // remember it and clear focus ourselves.
- if (lastFocusedControl && lastFocusedControl != this)
- lastFocusedControl->SetFocus(false);
- QT_TRAP_THROWING(S60->appUi()->AddToStackL(this,
- ECoeStackPriorityDefault + 1, ECoeStackFlagStandard)); // Note the + 1
- lastFocusedControl = this;
- this->SetFocus(true);
- } else {
- S60->appUi()->RemoveFromStack(this);
- QT_TRAP_THROWING(S60->appUi()->AddToStackL(this,
- ECoeStackPriorityDefault, ECoeStackFlagStandard));
- if(this == lastFocusedControl)
- lastFocusedControl = 0;
- this->SetFocus(false);
- }
-}
-
-bool QSymbianControl::isControlActive()
-{
- return IsActivated() ? true : false;
-}
-
-void QSymbianControl::ensureFixNativeOrientation()
-{
-#if defined(Q_SYMBIAN_SUPPORTS_FIXNATIVEORIENTATION)
- if (!qwidget->isWindow() || qwidget->windowType() == Qt::Desktop)
- return;
- if (S60->screenNumberForWidget(qwidget) > 0)
- return;
- const bool isFixed = qwidget->d_func()->fixNativeOrientationCalled;
- const bool isFixEnabled = qwidget->testAttribute(Qt::WA_SymbianNoSystemRotation);
- const bool isFullScreen = qwidget->windowState().testFlag(Qt::WindowFullScreen);
- if (isFullScreen && isFixEnabled) {
- const bool surfaceBasedGs =
- QApplicationPrivate::graphics_system_name == QLatin1String("openvg")
- || QApplicationPrivate::graphics_system_name == QLatin1String("opengl");
- if (!surfaceBasedGs)
- qwidget->setAttribute(Qt::WA_SymbianNoSystemRotation, false);
- if (!isFixed && surfaceBasedGs) {
- if (Window().FixNativeOrientation() == KErrNone) {
- qwidget->d_func()->fixNativeOrientationCalled = true;
- // The EGL window surface is now fixed to the native orientation
- // of the device, no matter what size we pass when creating it.
- // Enforce the same size for the QWidget too. For the underlying
- // CCoeControl and RWindow it is up to the system to resize them
- // when the standard auto-rotation mechanism is in use, we must not
- // change that behavior by forcing any size for those. In practice
- // this means that the QWidget and the underlying native control
- // dimensions will be out of sync when FixNativeOrientation was
- // called and the device is turned to the non-native (typically
- // landscape) orientation. The pointer event handling and certain
- // functions like Draw() will need to compensate for this.
- QSize newSize(S60->nativeScreenWidthInPixels, S60->nativeScreenHeightInPixels);
- if (qwidget->size() != newSize)
- qwidgetResize_helper(newSize);
- } else {
- qwidget->setAttribute(Qt::WA_SymbianNoSystemRotation, false);
- }
- }
- } else if (isFixed) {
- qwidget->setAttribute(Qt::WA_SymbianNoSystemRotation, false);
- qwidget->d_func()->fixNativeOrientationCalled = false;
- qwidget->hide();
- qwidget->d_func()->create_sys(0, false, true);
- qwidget->show();
- }
-#else
- qwidget->setAttribute(Qt::WA_SymbianNoSystemRotation, false);
-#endif
-}
-
-/*!
- \typedef QApplication::QS60MainApplicationFactory
- \since 4.6
-
- This is a typedef for a pointer to a function with the following
- signature:
-
- \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 47
-
- \sa QApplication::QApplication()
-*/
-
-/*!
- \since 4.6
-
- Creates an application using the application factory given in
- \a factory, and using \a argc command line arguments in \a argv.
- \a factory can be leaving, but the error will be converted to a
- standard exception.
-
- This function is only available on S60.
-*/
-QApplication::QApplication(QApplication::QS60MainApplicationFactory factory, int &argc, char **argv)
- : QCoreApplication(*new QApplicationPrivate(argc, argv, GuiClient, 0x040000))
-{
- Q_D(QApplication);
- S60->s60ApplicationFactory = factory;
- d->construct();
-}
-
-QApplication::QApplication(QApplication::QS60MainApplicationFactory factory, int &argc, char **argv, int _internal)
- : QCoreApplication(*new QApplicationPrivate(argc, argv, GuiClient, _internal))
-{
- Q_D(QApplication);
- S60->s60ApplicationFactory = factory;
- d->construct();
- QApplicationPrivate::app_compile_version = _internal;
-}
-
-void qt_init(QApplicationPrivate * /* priv */, int)
-{
- if (!CCoeEnv::Static()) {
- // The S60 framework creates a new trap handler which will render any existing traps
- // invalid as long as it is active. This means that all code in main() that occurs after
- // the QApplication construction needs to be surrounded by a new trap, despite having
- // an outer one already. To avoid this, we save the original trap handler here, and set
- // it back after the S60 framework is constructed. Then we restore it right before the S60
- // framework destruction.
- TTrapHandler *origTrapHandler = User::TrapHandler();
-
- // The S60 framework has not been initialized. We need to do it.
- TApaApplicationFactory factory(S60->s60ApplicationFactory ?
- S60->s60ApplicationFactory : newS60Application);
- CApaCommandLine* commandLine = q_check_ptr(QCoreApplicationPrivate::symbianCommandLine());
- if (commandLine) {
- // After this construction, CEikonEnv will be available from CEikonEnv::Static().
- // (much like our qApp).
- QtEikonEnv* coe = new QtEikonEnv;
- //not using QT_TRAP_THROWING, because coe owns the cleanupstack so it can't be pushed there.
- TRAPD(err, coe->ConstructAppFromCommandLineL(factory, *commandLine));
- if(err != KErrNone) {
- qWarning() << "qt_init: Eikon application construct failed ("
- << err
- << "), maybe missing resource file on S60 3.1?";
- delete coe;
- qt_symbian_throwIfError(err);
- }
- }
-
- S60->s60InstalledTrapHandler = User::SetTrapHandler(origTrapHandler);
-
- S60->qtOwnsS60Environment = true;
- } else {
- S60->qtOwnsS60Environment = false;
- }
-
-#ifdef QT_NO_DEBUG
- if (!qgetenv("QT_S60_AUTO_FLUSH_WSERV").isEmpty())
-#endif
- S60->wsSession().SetAutoFlush(ETrue);
-
-#ifdef Q_SYMBIAN_WINDOW_SIZE_CACHE
- TRAP_IGNORE(S60->wsSession().EnableWindowSizeCacheL());
-#endif
-
- S60->updateScreenSize();
-
-
- TDisplayMode mode = S60->screenDevice()->DisplayMode();
- S60->screenDepth = TDisplayModeUtils::NumDisplayModeBitsPerPixel(mode);
-
- //NB: RWsSession::GetColorModeList tells you what window modes are supported,
- //not what bitmap formats.
- if(QSysInfo::symbianVersion() == QSysInfo::SV_9_2)
- S60->supportsPremultipliedAlpha = 0;
- else
- S60->supportsPremultipliedAlpha = 1;
-
- RProcess me;
- TSecureId securId = me.SecureId();
- S60->uid = securId.operator TUid();
-
- // enable focus events - used to re-enable mouse after focus changed between mouse and non mouse app,
- // and for dimming behind modal windows
- S60->windowGroup().EnableFocusChangeEvents();
-
- //Check if mouse interaction is supported (either EMouse=1 in the HAL, or EMachineUID is one of the phones known to support this)
- const TInt KMachineUidSamsungI8510 = 0x2000C51E;
- // HAL::Get(HALData::EPen, TInt& result) may set 'result' to 1 on some 3.1 systems (e.g. N95).
- // But we know that S60 systems below 5.0 did not support touch.
- static const bool touchIsUnsupportedOnSystem =
- QSysInfo::s60Version() == QSysInfo::SV_S60_3_1
- || QSysInfo::s60Version() == QSysInfo::SV_S60_3_2;
- TInt machineUID;
- TInt mouse;
- TInt touch;
- TInt err;
- err = HAL::Get(HALData::EMouse, mouse);
- if (err != KErrNone)
- mouse = 0;
- err = HAL::Get(HALData::EMachineUid, machineUID);
- if (err != KErrNone)
- machineUID = 0;
- err = HAL::Get(HALData::EPen, touch);
- if (err != KErrNone || touchIsUnsupportedOnSystem)
- touch = 0;
-#ifdef __WINS__
- if(QSysInfo::symbianVersion() <= QSysInfo::SV_9_4) {
- //for symbian SDK emulator, force values to match typical devices.
- mouse = 0;
- touch = touchIsUnsupportedOnSystem ? 0 : 1;
- }
-#endif
- if (mouse || machineUID == KMachineUidSamsungI8510) {
- S60->hasTouchscreen = false;
- S60->virtualMouseRequired = false;
- }
- else if (!touch) {
- S60->hasTouchscreen = false;
- S60->virtualMouseRequired = true;
- }
- else {
- S60->hasTouchscreen = true;
- S60->virtualMouseRequired = false;
- }
-
- S60->avkonComponentsSupportTransparency = false;
- S60->menuBeingConstructed = false;
-
-#ifdef Q_WS_S60
- TUid KCRUidAvkon = { 0x101F876E };
- TUint32 KAknAvkonTransparencyEnabled = 0x0000000D;
-
- CRepository* repository = 0;
- TRAP(err, repository = CRepository::NewL(KCRUidAvkon));
-
- if(err == KErrNone) {
- TInt value = 0;
- err = repository->Get(KAknAvkonTransparencyEnabled, value);
- if(err == KErrNone) {
- S60->avkonComponentsSupportTransparency = (value==1) ? true : false;
- }
- }
- delete repository;
- repository = 0;
-#endif
-
- qt_keymapper_private()->updateInputLanguage();
-
-#ifdef QT_KEYPAD_NAVIGATION
- if (touch) {
- QApplicationPrivate::navigationMode = Qt::NavigationModeNone;
- } else {
- QApplicationPrivate::navigationMode = Qt::NavigationModeKeypadDirectional;
- }
-#endif
-
-#ifndef QT_NO_CURSOR
- //Check if window server pointer cursors are supported or not
-#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
- //In generic binary, use the HAL and OS version
- //Any other known good phones should be added here.
- if (machineUID == KMachineUidSamsungI8510 || (QSysInfo::symbianVersion() != QSysInfo::SV_9_4
- && QSysInfo::symbianVersion() != QSysInfo::SV_9_3 && QSysInfo::symbianVersion()
- != QSysInfo::SV_9_2)) {
- S60->brokenPointerCursors = false;
- qt_symbian_setWindowGroupCursor(Qt::ArrowCursor, S60->windowGroup());
- }
- else
- S60->brokenPointerCursors = true;
-#endif
-
- if (S60->mouseInteractionEnabled) {
-#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
- if (S60->brokenPointerCursors) {
- qt_symbian_set_pointer_sprite(Qt::ArrowCursor);
- qt_symbian_show_pointer_sprite();
- }
- else
-#endif
- S60->wsSession().SetPointerCursorMode(EPointerCursorNormal);
- }
-#endif
-
- QFont systemFont;
- systemFont.setFamily(systemFont.defaultFamily());
- QApplicationPrivate::setSystemFont(systemFont);
-
- QObject::connect(qApp, SIGNAL(aboutToQuit()), qApp, SLOT(_q_aboutToQuit()));
-
-#ifdef Q_SYMBIAN_SEMITRANSPARENT_BG_SURFACE
- QApplicationPrivate::instance()->useTranslucentEGLSurfaces = true;
-
- const TUid KIvePropertyCat = {0x2726beef};
- enum TIvePropertyChipType {
- EVCBCM2727B1 = 0x00000000,
- EVCBCM2763A0 = 0x04000100,
- EVCBCM2763B0 = 0x04000102,
- EVCBCM2763C0 = 0x04000103,
- EVCBCM2763C1 = 0x04000104,
- EVCBCMUnknown = 0x7fffffff
- };
-
- TInt chipType = EVCBCMUnknown;
- if (RProperty::Get(KIvePropertyCat, 0 /*chip type*/, chipType) == KErrNone) {
- if (chipType == EVCBCM2727B1) {
- // We have only 32MB GPU memory. Use raster surfaces
- // for transparent TLWs.
- QApplicationPrivate::instance()->useTranslucentEGLSurfaces = false;
- }
- } else {
- QApplicationPrivate::instance()->useTranslucentEGLSurfaces = false;
- }
- if (QApplicationPrivate::graphics_system_name == QLatin1String("raster"))
- QApplicationPrivate::instance()->useTranslucentEGLSurfaces = false;
-#else
- QApplicationPrivate::instance()->useTranslucentEGLSurfaces = false;
-#endif
-/*
- ### Commented out for now as parameter handling not needed in SOS(yet). Code below will break testlib with -o flag
- int argc = priv->argc;
- char **argv = priv->argv;
-
- // Get command line params
- int j = argc ? 1 : 0;
- for (int i=1; i<argc; i++) {
- if (argv[i] && *argv[i] != '-') {
- argv[j++] = argv[i];
- continue;
- }
-
-#if defined(QT_DEBUG)
- if (qstrcmp(argv[i], "-nograb") == 0)
- appNoGrab = !appNoGrab;
- else
-#endif // QT_DEBUG
- ;
- }
-*/
-
- // Register WId with the metatype system. This is to enable
- // QWidgetPrivate::create_sys to used delayed slot invocation in order
- // to destroy WId objects during reparenting.
- qRegisterMetaType<WId>("WId");
-}
-
-#ifdef QT_NO_FREETYPE
-extern void qt_cleanup_symbianFontDatabase(); // qfontdatabase_s60.cpp
-#endif
-
-/*****************************************************************************
- qt_cleanup() - cleans up when the application is finished
- *****************************************************************************/
-void qt_cleanup()
-{
-#ifdef Q_WS_S60
- S60->setButtonGroupContainer(0);
-#endif
- if(qt_S60Beep) {
- delete qt_S60Beep;
- qt_S60Beep = 0;
- }
- QFontCache::cleanup(); // Has to happen now, since QFontEngineS60 has FBS handles
- QPixmapCache::clear(); // Has to happen now, since QS60PixmapData has FBS handles
-
-#ifdef QT_NO_FREETYPE
- qt_cleanup_symbianFontDatabase();
-#endif
-// S60 structure and window server session are freed in eventdispatcher destructor as they are needed there
-
- // It's important that this happens here, before the event dispatcher gets
- // deleted, because the input context needs the event loop one last time before
- // it dies.
- delete QApplicationPrivate::inputContext;
- QApplicationPrivate::inputContext = 0;
-
- //Change mouse pointer back
- S60->wsSession().SetPointerCursorMode(EPointerCursorNone);
-
-#ifdef Q_WS_S60
- // Clear CBA
- CEikonEnv::Static()->AppUiFactory()->SwapButtonGroup(0);
- delete S60->buttonGroupContainer();
- S60->setButtonGroupContainer(0);
-#endif
-
- // Call EndFullScreen() to prevent confusing the system effect state machine.
- qt_endFullScreenEffect();
-
- if (S60->qtOwnsS60Environment) {
- // Restore the S60 framework trap handler. See qt_init().
- User::SetTrapHandler(S60->s60InstalledTrapHandler);
-
- CEikonEnv* coe = CEikonEnv::Static();
- coe->PrepareToExit();
- // The CEikonEnv itself is destroyed in here.
- coe->DestroyEnvironment();
- }
-}
-
-void QApplicationPrivate::initializeWidgetPaletteHash()
-{
- // TODO: Implement QApplicationPrivate::initializeWidgetPaletteHash()
- // Possibly a task fot the S60Style guys
-}
-
-void QApplicationPrivate::createEventDispatcher()
-{
- Q_Q(QApplication);
- eventDispatcher = new QEventDispatcherS60(q);
-}
-
-QString QApplicationPrivate::appName() const
-{
- return QCoreApplicationPrivate::appName();
-}
-
-bool QApplicationPrivate::modalState()
-{
- return app_do_modal;
-}
-
-void QApplicationPrivate::enterModal_sys(QWidget *widget)
-{
-#ifdef Q_SYMBIAN_TRANSITION_EFFECTS
- S60->wsSession().SendEffectCommand(ETfxCmdAppModalModeEnter);
-#endif
- if (widget) {
- static_cast<QSymbianControl *>(widget->effectiveWinId())->FadeBehindPopup(ETrue);
- // Modal partial screen dialogs (like queries) capture pointer events.
- // ### FixMe: Add specialized behaviour for fullscreen modal dialogs
- widget->effectiveWinId()->SetGloballyCapturing(ETrue);
- widget->effectiveWinId()->SetPointerCapture(ETrue);
- }
- if (!qt_modal_stack)
- qt_modal_stack = new QWidgetList;
- qt_modal_stack->insert(0, widget);
- app_do_modal = true;
-}
-
-void QApplicationPrivate::leaveModal_sys(QWidget *widget)
-{
-#ifdef Q_SYMBIAN_TRANSITION_EFFECTS
- S60->wsSession().SendEffectCommand(ETfxCmdAppModalModeExit);
-#endif
- if (widget) {
- static_cast<QSymbianControl *>(widget->effectiveWinId())->FadeBehindPopup(EFalse);
- // ### FixMe: Add specialized behaviour for fullscreen modal dialogs
- widget->effectiveWinId()->SetGloballyCapturing(EFalse);
- widget->effectiveWinId()->SetPointerCapture(EFalse);
- }
- if (qt_modal_stack && qt_modal_stack->removeAll(widget)) {
- if (qt_modal_stack->isEmpty()) {
- delete qt_modal_stack;
- qt_modal_stack = 0;
- }
- }
- app_do_modal = qt_modal_stack != 0;
-}
-
-void QApplicationPrivate::openPopup(QWidget *popup)
-{
- if (popup && qobject_cast<QComboBox *>(popup->parentWidget()))
- static_cast<QSymbianControl *>(popup->effectiveWinId())->FadeBehindPopup(ETrue);
-
- if (!QApplicationPrivate::popupWidgets)
- QApplicationPrivate::popupWidgets = new QWidgetList;
- QApplicationPrivate::popupWidgets->append(popup);
-
- // Cancel focus widget pointer capture and long tap timer
- if (QApplication::focusWidget()) {
- static_cast<QSymbianControl*>(QApplication::focusWidget()->effectiveWinId())->CancelLongTapTimer();
- QApplication::focusWidget()->effectiveWinId()->SetPointerCapture(false);
- }
-
- if (!qt_nograb()) {
- // Cancel pointer capture and long tap timer for earlier popup
- int popupCount = QApplicationPrivate::popupWidgets->count();
- if (popupCount > 1) {
- QWidget* prevPopup = QApplicationPrivate::popupWidgets->at(popupCount-2);
- static_cast<QSymbianControl*>(prevPopup->effectiveWinId())->CancelLongTapTimer();
- prevPopup->effectiveWinId()->SetPointerCapture(false);
- }
-
- // Enable pointer capture for this (topmost) popup
- Q_ASSERT(popup->testAttribute(Qt::WA_WState_Created));
- WId id = popup->effectiveWinId();
- id->SetPointerCapture(true);
- }
-
- // popups are not focus-handled by the window system (the first
- // popup grabbed the keyboard), so we have to do that manually: A
- // new popup gets the focus
- QWidget *fw = popup->focusWidget();
- if (fw) {
- fw->setFocus(Qt::PopupFocusReason);
- } else if (QApplicationPrivate::popupWidgets->count() == 1) { // this was the first popup
- fw = QApplication::focusWidget();
- if (fw) {
- QFocusEvent e(QEvent::FocusOut, Qt::PopupFocusReason);
- q_func()->sendEvent(fw, &e);
- }
- }
-}
-
-void QApplicationPrivate::closePopup(QWidget *popup)
-{
- if (popup && qobject_cast<QComboBox *>(popup->parentWidget()))
- static_cast<QSymbianControl *>(popup->effectiveWinId())->FadeBehindPopup(EFalse);
-
- if (!QApplicationPrivate::popupWidgets)
- return;
- QApplicationPrivate::popupWidgets->removeAll(popup);
-
- // Cancel pointer capture and long tap for this popup
- WId id = popup->effectiveWinId();
- id->SetPointerCapture(false);
- static_cast<QSymbianControl*>(id)->CancelLongTapTimer();
-
- if (QApplicationPrivate::popupWidgets->isEmpty()) { // this was the last popup
- delete QApplicationPrivate::popupWidgets;
- QApplicationPrivate::popupWidgets = 0;
- if (!qt_nograb()) { // grabbing not disabled
- Q_ASSERT(popup->testAttribute(Qt::WA_WState_Created));
- if (QWidgetPrivate::mouseGrabber != 0)
- QWidgetPrivate::mouseGrabber->grabMouse();
-
- if (QWidgetPrivate::keyboardGrabber != 0)
- QWidgetPrivate::keyboardGrabber->grabKeyboard();
-
- QWidget *fw = QApplicationPrivate::active_window ? QApplicationPrivate::active_window->focusWidget()
- : q_func()->focusWidget();
- if (fw) {
- if(fw->window()->isModal()) // restore pointer capture for modal window
- fw->effectiveWinId()->SetPointerCapture(true);
-
- if (fw != q_func()->focusWidget()) {
- fw->setFocus(Qt::PopupFocusReason);
- } else {
- QFocusEvent e(QEvent::FocusIn, Qt::PopupFocusReason);
- q_func()->sendEvent(fw, &e);
- }
- }
- }
- } else {
-
- // popups are not focus-handled by the window system (the
- // first popup grabbed the keyboard), so we have to do that
- // manually: A popup was closed, so the previous popup gets
- // the focus.
- QWidget* aw = QApplicationPrivate::popupWidgets->last();
- if (QWidget *fw = QApplication::focusWidget()) {
- QFocusEvent e(QEvent::FocusOut, Qt::PopupFocusReason);
- q_func()->sendEvent(fw, &e);
- }
-
- // Enable pointer capture for previous popup
- if (aw) {
- aw->effectiveWinId()->SetPointerCapture(true);
- }
- }
-}
-
-QWidget * QApplication::topLevelAt(QPoint const& point)
-{
- QWidget *found = 0;
- int lowestZ = INT_MAX;
- QWidgetList list = QApplication::topLevelWidgets();
- for (int i = 0; i < list.count(); ++i) {
- QWidget *widget = list.at(i);
- if (widget->isVisible() && !(widget->windowType() == Qt::Desktop)) {
- Q_ASSERT(widget->testAttribute(Qt::WA_WState_Created));
- if (widget->geometry().adjusted(0,0,1,1).contains(point)) {
- // At this point we know there is a Qt widget under the point.
- // Now we need to make sure it is the top most in the z-order.
- RDrawableWindow *const window = widget->effectiveWinId()->DrawableWindow();
- int z = window->OrdinalPosition();
- if (z < lowestZ) {
- lowestZ = z;
- found = widget;
- }
- }
- }
- }
- return found;
-}
-
-void QApplication::alert(QWidget * /* widget */, int /* duration */)
-{
- // TODO: Implement QApplication::alert(QWidget *widget, int duration)
-}
-
-int QApplication::doubleClickInterval()
-{
- TTimeIntervalMicroSeconds32 us;
- TInt distance;
- S60->wsSession().GetDoubleClickSettings(us, distance);
- return (us.Int() / 1000);
-}
-
-void QApplication::setDoubleClickInterval(int ms)
-{
- TTimeIntervalMicroSeconds32 newUs( ms * 1000);
- TTimeIntervalMicroSeconds32 us;
- TInt distance;
- S60->wsSession().GetDoubleClickSettings(us, distance);
- if (us != newUs)
- S60->wsSession().SetDoubleClick(newUs, distance);
-}
-
-int QApplication::keyboardInputInterval()
-{
- return QApplicationPrivate::keyboard_input_time;
-}
-
-void QApplication::setKeyboardInputInterval(int ms)
-{
- QApplicationPrivate::keyboard_input_time = ms;
-}
-
-int QApplication::cursorFlashTime()
-{
- return QApplicationPrivate::cursor_flash_time;
-}
-
-void QApplication::setCursorFlashTime(int msecs)
-{
- QApplicationPrivate::cursor_flash_time = msecs;
-}
-
-void QApplication::beep()
-{
- if (!qt_S60Beep) {
- TInt frequency = 880;
- TTimeIntervalMicroSeconds duration(500000);
- TRAP_IGNORE(qt_S60Beep=QS60Beep::NewL(frequency, duration));
- }
- if (qt_S60Beep)
- qt_S60Beep->Play();
-}
-
-static inline bool callSymbianEventFilters(const QSymbianEvent *event)
-{
- long unused;
- return qApp->filterEvent(const_cast<QSymbianEvent *>(event), &unused);
-}
-
-/*!
- \warning This function is only available on Symbian.
- \since 4.6
-
- This function processes an individual Symbian event
- \a event. It returns 1 if the event was handled, 0 if
- the \a event was not handled, and -1 if the event was
- not handled because the event is not known to Qt.
- */
-
-int QApplication::symbianProcessEvent(const QSymbianEvent *event)
-{
- Q_D(QApplication);
-
- QScopedLoopLevelCounter counter(d->threadData);
-
- if (d->eventDispatcher->filterEvent(const_cast<QSymbianEvent *>(event)))
- return 1;
-
- QWidget *w = qApp ? qApp->focusWidget() : 0;
- if (w) {
- QInputContext *ic = w->inputContext();
- if (ic && ic->symbianFilterEvent(w, event))
- return 1;
- }
-
- if (symbianEventFilter(event))
- return 1;
-
- switch (event->type()) {
- case QSymbianEvent::WindowServerEvent:
- return d->symbianProcessWsEvent(event);
- case QSymbianEvent::CommandEvent:
- return d->symbianHandleCommand(event);
- case QSymbianEvent::ResourceChangeEvent:
- return d->symbianResourceChange(event);
- default:
- return -1;
- }
-}
-
-int QApplicationPrivate::symbianProcessWsEvent(const QSymbianEvent *symbianEvent)
-{
- // Qt event handling. Handle some events regardless of if the handle is in our
- // widget map or not.
- const TWsEvent *event = symbianEvent->windowServerEvent();
- CCoeControl* control = reinterpret_cast<CCoeControl*>(event->Handle());
- const bool controlInMap = QWidgetPrivate::mapper && QWidgetPrivate::mapper->contains(control);
- switch (event->Type()) {
- case EEventPointerEnter:
- if (controlInMap) {
- callSymbianEventFilters(symbianEvent);
- return 1; // Qt::Enter will be generated in HandlePointerL
- }
- break;
- case EEventPointerExit:
- if (controlInMap) {
- if (callSymbianEventFilters(symbianEvent))
- return 1;
- if (S60) {
- // mouseEvent outside our window, send leave event to last focused widget
- QMouseEvent mEvent(QEvent::Leave, S60->lastPointerEventPos, S60->lastCursorPos,
- Qt::NoButton, QApplicationPrivate::mouse_buttons, Qt::NoModifier);
- if (S60->lastPointerEventTarget)
- qt_sendSpontaneousEvent(S60->lastPointerEventTarget,&mEvent);
- S60->lastPointerEventTarget = 0;
- }
- return 1;
- }
- break;
- case EEventScreenDeviceChanged: // fallthrough
-#if defined(Q_SYMBIAN_SUPPORTS_MULTIPLE_SCREENS)
- case EEventDisplayChanged:
-#endif
- if (callSymbianEventFilters(symbianEvent))
- return 1;
- if (S60)
- S60->updateScreenSize();
- if (qt_desktopWidget) {
- QSize oldSize = qt_desktopWidget->size();
- qt_desktopWidget->data->crect.setWidth(S60->screenWidthInPixels);
- qt_desktopWidget->data->crect.setHeight(S60->screenHeightInPixels);
- QResizeEvent e(qt_desktopWidget->size(), oldSize);
- QApplication::sendEvent(qt_desktopWidget, &e);
- }
- return 0; // Propagate to CONE
- case EEventWindowVisibilityChanged:
- if (controlInMap) {
- if (callSymbianEventFilters(symbianEvent))
- return 1;
- const TWsVisibilityChangedEvent *visChangedEvent = event->VisibilityChanged();
- if (visChangedEvent->iFlags & TWsVisibilityChangedEvent::ENotVisible)
- S60->controlVisibilityChanged(control, false);
- else if (visChangedEvent->iFlags & TWsVisibilityChangedEvent::EPartiallyVisible)
- S60->controlVisibilityChanged(control, true);
- return 1;
- }
- break;
- case EEventFocusGained:
- if (callSymbianEventFilters(symbianEvent))
- return 1;
-#ifndef QT_NO_CURSOR
- //re-enable mouse interaction
- if (S60->mouseInteractionEnabled) {
-#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
- if (S60->brokenPointerCursors)
- qt_symbian_show_pointer_sprite();
- else
-#endif
- S60->wsSession().SetPointerCursorMode(EPointerCursorNormal);
- }
-#endif
-#ifdef QT_SOFTKEYS_ENABLED
- if (!CEikonEnv::Static()->EikAppUi()->IsDisplayingMenuOrDialog())
- QSoftKeyManager::updateSoftKeys();
-#endif
- break;
- case EEventFocusLost:
- if (callSymbianEventFilters(symbianEvent))
- return 1;
-#ifndef QT_NO_CURSOR
- //disable mouse as may be moving to application that does not support it
- if (S60->mouseInteractionEnabled) {
-#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
- if (S60->brokenPointerCursors)
- qt_symbian_hide_pointer_sprite();
- else
-#endif
- S60->wsSession().SetPointerCursorMode(EPointerCursorNone);
- }
-#endif
- break;
- case KGoomMemoryLowEvent:
-#ifdef QT_DEBUG
- qDebug() << "QApplicationPrivate::symbianProcessWsEvent - KGoomMemoryLowEvent";
-#endif
- if (callSymbianEventFilters(symbianEvent))
- return 1;
-#ifdef QT_GRAPHICSSYSTEM_RUNTIME
- if(QApplicationPrivate::runtime_graphics_system) {
- bool switchToSwRendering(false);
-
- foreach (QWidget *w, QApplication::topLevelWidgets()) {
- if(w->d_func()->topData()->backingStore) {
- switchToSwRendering = true;
- break;
- }
- }
-
- if (switchToSwRendering) {
- QRuntimeGraphicsSystem *gs =
- static_cast<QRuntimeGraphicsSystem*>(QApplicationPrivate::graphics_system);
- gs->setGraphicsSystem(QLatin1String("raster"));
- }
- }
-#endif
- break;
- case KGoomMemoryGoodEvent:
-#ifdef QT_DEBUG
- qDebug() << "QApplicationPrivate::symbianProcessWsEvent - KGoomMemoryGoodEvent";
-#endif
- if (callSymbianEventFilters(symbianEvent))
- return 1;
-#ifdef QT_GRAPHICSSYSTEM_RUNTIME
- if(QApplicationPrivate::runtime_graphics_system) {
- QRuntimeGraphicsSystem *gs =
- static_cast<QRuntimeGraphicsSystem*>(QApplicationPrivate::graphics_system);
- gs->setGraphicsSystem(QLatin1String("openvg"));
- }
-#endif
- break;
-#ifdef Q_SYMBIAN_SUPPORTS_SURFACES
- case EEventUser:
- {
- // GOOM is looking for candidates to kill so indicate that we are
- // capable of cleaning up by handling this event
- TInt32 *data = reinterpret_cast<TInt32 *>(event->EventData());
- if (data[0] == EApaSystemEventShutdown && data[1] == KGoomMemoryLowEvent)
- return 1;
- }
- break;
-#endif
-
-#ifdef Q_WS_S60
- case KEikInputLanguageChange:
- qt_keymapper_private()->updateInputLanguage();
- break;
-#endif
-
- default:
- break;
- }
-
- if (!controlInMap)
- return -1;
-
- return 0;
-}
-
-/*!
- \warning This virtual function is only available on Symbian.
- \since 4.6
-
- If you create an application that inherits QApplication and reimplement
- this function, you get direct access to events that the are received
- from Symbian. The events are passed in the \a event parameter.
-
- Return true if you want to stop the event from being processed. Return
- false for normal event dispatching. The default implementation returns
- false, and does nothing with \a event.
- */
-bool QApplication::symbianEventFilter(const QSymbianEvent *event)
-{
- Q_UNUSED(event);
- return false;
-}
-
-/*!
- \warning This function is only available on Symbian.
- \since 4.6
-
- Handles \a{command}s which are typically handled by
- CAknAppUi::HandleCommandL(). Qts Ui integration into Symbian is
- partially achieved by deriving from CAknAppUi. Currently, exit,
- menu and softkey commands are handled.
-
- \sa s60EventFilter(), s60ProcessEvent()
-*/
-int QApplicationPrivate::symbianHandleCommand(const QSymbianEvent *symbianEvent)
-{
- Q_Q(QApplication);
- int ret = 0;
-
- if (callSymbianEventFilters(symbianEvent))
- return 1;
-
- int command = symbianEvent->command();
-
- switch (command) {
-#ifdef Q_WS_S60
- case EAknSoftkeyExit: {
- QCloseEvent ev;
- QApplication::sendSpontaneousEvent(q, &ev);
- if (ev.isAccepted()) {
- q->quit();
- ret = 1;
- }
- break;
- }
-#endif
- case EEikCmdExit:
- q->quit();
- ret = 1;
- break;
- default:
-#ifdef Q_WS_S60
- bool handled = QSoftKeyManager::handleCommand(command);
- if (handled)
- ret = 1;
- else
- ret = QMenuBarPrivate::symbianCommands(command);
-#endif
- break;
- }
-
- return ret;
-}
-
-/*!
- \warning This function is only available on Symbian.
- \since 4.6
-
- Handles the resource change specified by \a type.
-
- Currently, KEikDynamicLayoutVariantSwitch and
- KAknsMessageSkinChange are handled.
- */
-int QApplicationPrivate::symbianResourceChange(const QSymbianEvent *symbianEvent)
-{
- int ret = 0;
-
- int type = symbianEvent->resourceChangeType();
-
- switch (type) {
-#ifdef Q_WS_S60
- case KEikDynamicLayoutVariantSwitch:
- {
- if (callSymbianEventFilters(symbianEvent))
- return 1;
- if (S60)
- S60->updateScreenSize();
-
-#ifndef QT_NO_STYLE_S60
- QS60Style *s60Style = 0;
-
-#ifndef QT_NO_STYLE_STYLESHEET
- QStyleSheetStyle *proxy = qobject_cast<QStyleSheetStyle*>(QApplication::style());
- if (proxy)
- s60Style = qobject_cast<QS60Style*>(proxy->baseStyle());
- else
-#endif
- s60Style = qobject_cast<QS60Style*>(QApplication::style());
-
- if (s60Style) {
- s60Style->d_func()->handleDynamicLayoutVariantSwitch();
- ret = 1;
- }
-#endif
- }
- break;
-
-#ifndef QT_NO_STYLE_S60
- case KAknsMessageSkinChange:
- if (callSymbianEventFilters(symbianEvent))
- return 1;
- if (QS60Style *s60Style = qobject_cast<QS60Style*>(QApplication::style())) {
- s60Style->d_func()->handleSkinChange();
- ret = 1;
- }
- break;
-#endif
-#endif // Q_WS_S60
- default:
- break;
- }
-
- return ret;
-}
-
-#ifndef QT_NO_WHEELEVENT
-int QApplication::wheelScrollLines()
-{
- return QApplicationPrivate::wheel_scroll_lines;
-}
-
-void QApplication::setWheelScrollLines(int n)
-{
- QApplicationPrivate::wheel_scroll_lines = n;
-}
-#endif //QT_NO_WHEELEVENT
-
-bool QApplication::isEffectEnabled(Qt::UIEffect /* effect */)
-{
- // TODO: Implement QApplication::isEffectEnabled(Qt::UIEffect effect)
- return false;
-}
-
-void QApplication::setEffectEnabled(Qt::UIEffect /* effect */, bool /* enable */)
-{
- // TODO: Implement QApplication::setEffectEnabled(Qt::UIEffect effect, bool enable)
-}
-
-Qt::KeyboardModifiers QApplication::queryKeyboardModifiers()
-{
- return app_keyboardModifiers;
-}
-
-TUint QApplicationPrivate::resolveS60ScanCode(TInt scanCode, TUint keysym)
-{
- if (!scanCode)
- return keysym;
-
- QApplicationPrivate *d = QApplicationPrivate::instance();
-
- if (keysym) {
- // If keysym is specified, cache it.
- d->scanCodeCache.insert(scanCode, keysym);
- return keysym;
- } else {
- // If not, retrieve the cached version.
- return d->scanCodeCache[scanCode];
- }
-}
-
-void QApplicationPrivate::initializeMultitouch_sys()
-{
-#ifdef QT_SYMBIAN_SUPPORTS_ADVANCED_POINTER
- if (HAL::Get(HALData::EPointer3DPressureSupported, pressureSupported) != KErrNone)
- pressureSupported = 0;
- if (HAL::Get(HALData::EPointer3DMaxPressure, maxTouchPressure) != KErrNone)
- maxTouchPressure = KMaxTInt;
-#else
- pressureSupported = 0;
- maxTouchPressure = KMaxTInt;
-#endif
-}
-
-void QApplicationPrivate::cleanupMultitouch_sys()
-{ }
-
-#ifndef QT_NO_SESSIONMANAGER
-QSessionManager::QSessionManager(QApplication * /* app */, QString & /* id */, QString& /* key */)
-{
-
-}
-
-QSessionManager::~QSessionManager()
-{
-
-}
-
-bool QSessionManager::allowsInteraction()
-{
- return false;
-}
-
-void QSessionManager::cancel()
-{
-
-}
-#endif //QT_NO_SESSIONMANAGER
-
-#ifdef QT_KEYPAD_NAVIGATION
-/*
- * Show/Hide the mouse cursor depending on phone type and chosen mode
- */
-void QApplicationPrivate::setNavigationMode(Qt::NavigationMode mode)
-{
-#ifndef QT_NO_CURSOR
- const bool wasCursorOn = (QApplicationPrivate::navigationMode == Qt::NavigationModeCursorAuto
- && !S60->hasTouchscreen)
- || QApplicationPrivate::navigationMode == Qt::NavigationModeCursorForceVisible;
- const bool isCursorOn = (mode == Qt::NavigationModeCursorAuto
- && !S60->hasTouchscreen)
- || mode == Qt::NavigationModeCursorForceVisible;
-
- if (!wasCursorOn && isCursorOn) {
- //Show the cursor, when changing from another mode to cursor mode
- qt_symbian_set_cursor_visible(true);
- }
- else if (wasCursorOn && !isCursorOn) {
- //Hide the cursor, when leaving cursor mode
- qt_symbian_set_cursor_visible(false);
- }
-#endif
- QApplicationPrivate::navigationMode = mode;
-}
-#endif
-
-#ifndef QT_NO_CURSOR
-/*****************************************************************************
- QApplication cursor stack
- *****************************************************************************/
-
-void QApplication::setOverrideCursor(const QCursor &cursor)
-{
- qApp->d_func()->cursor_list.prepend(cursor);
- qt_symbian_setGlobalCursor(cursor);
-}
-
-void QApplication::restoreOverrideCursor()
-{
- if (qApp->d_func()->cursor_list.isEmpty())
- return;
- qApp->d_func()->cursor_list.removeFirst();
-
- if (!qApp->d_func()->cursor_list.isEmpty()) {
- qt_symbian_setGlobalCursor(qApp->d_func()->cursor_list.first());
- }
- else {
- //determine which widget has focus
- QWidget *w = QApplication::widgetAt(QCursor::pos());
-#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
- if (S60->brokenPointerCursors) {
- qt_symbian_set_pointer_sprite(w ? w->cursor() : Qt::ArrowCursor);
- }
- else
-#endif
- {
- //because of the internals of window server, we need to force the cursor
- //to be set in all child windows too, otherwise when the cursor is over
- //the child window it may show a widget cursor or arrow cursor instead,
- //depending on construction order.
- QListIterator<WId> iter(QWidgetPrivate::mapper->uniqueKeys());
- while (iter.hasNext()) {
- CCoeControl *ctrl = iter.next();
- if(ctrl->OwnsWindow()) {
- ctrl->DrawableWindow()->ClearPointerCursor();
- }
- }
- if (w)
- qt_symbian_setWindowCursor(w->cursor(), w->effectiveWinId());
- else
- qt_symbian_setWindowGroupCursor(Qt::ArrowCursor, S60->windowGroup());
- }
- }
-}
-
-#endif // QT_NO_CURSOR
-
-void QApplicationPrivate::_q_aboutToQuit()
-{
- qt_beginFullScreenEffect();
-
-#ifdef Q_SYMBIAN_TRANSITION_EFFECTS
- // Send the shutdown tfx command
- S60->wsSession().SendEffectCommand(ETfxCmdAppShutDown);
-#endif
-}
-
-QS60ThreadLocalData::QS60ThreadLocalData()
-{
- CCoeEnv *env = CCoeEnv::Static();
- if (env) {
- //if this is the UI thread, share objects owned by CONE
- usingCONEinstances = true;
- wsSession = env->WsSession();
- screenDevice = env->ScreenDevice();
- }
- else {
- usingCONEinstances = false;
- qt_symbian_throwIfError(wsSession.Connect(qt_s60GetRFs()));
- screenDevice = new CWsScreenDevice(wsSession);
- screenDevice->Construct();
- }
-}
-
-QS60ThreadLocalData::~QS60ThreadLocalData()
-{
- for (int i = 0; i < releaseFuncs.count(); ++i)
- releaseFuncs[i]();
- releaseFuncs.clear();
- if (!usingCONEinstances) {
- delete screenDevice;
- wsSession.Close();
- }
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp
deleted file mode 100644
index 756cb56b58..0000000000
--- a/src/gui/kernel/qapplication_win.cpp
+++ /dev/null
@@ -1,4253 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifdef Q_WS_WINCE
-#include "qguifunctions_wince.h"
-#include "qmenubar.h"
-extern bool qt_wince_is_mobile(); //defined in qguifunctions_wince.cpp
-extern bool qt_wince_is_high_dpi(); //defined in qguifunctions_wince.cpp
-extern bool qt_wince_is_smartphone(); //defined in qguifunctions_wince.cpp
-extern bool qt_wince_is_pocket_pc(); //defined in qguifunctions_wince.cpp
-extern void qt_wince_hide_taskbar(HWND hwnd); //defined in qguifunctions_wince.cpp
-#endif
-#ifdef Q_WS_WINCE_WM
-#include <windowsm.h>
-#include <tpcshell.h>
-#ifdef QT_WINCE_GESTURES
-#ifndef QT_NO_GESTURES
-#include <gesture.h>
-#endif
-#endif
-#endif
-
-#include "qapplication.h"
-#include "qdesktopwidget.h"
-#include "qevent.h"
-#include "private/qeventdispatcher_win_p.h"
-#include "qeventloop.h"
-#include "qclipboard.h"
-#include "qcursor.h"
-#include "qdatetime.h"
-#include "qpointer.h"
-#include "qhash.h"
-#include "qmetaobject.h"
-#include "qmime.h"
-#include "qpainter.h"
-#include "qpixmapcache.h"
-#include "qsessionmanager.h"
-#include "qstyle.h"
-#include "qwhatsthis.h" // ######## dependency
-#include "qwidget.h"
-#include "qcolormap.h"
-#include "qlayout.h"
-#include "qtooltip.h"
-#include "qt_windows.h"
-#include "qscrollbar.h"
-#if defined(QT_NON_COMMERCIAL)
-#include "qnc_win.h"
-#endif
-#include "private/qwininputcontext_p.h"
-#include "private/qcursor_p.h"
-#include "private/qmath_p.h"
-#include "private/qapplication_p.h"
-#include "private/qbackingstore_p.h"
-#include "private/qwindowsurface_raster_p.h"
-#include "qdebug.h"
-#include <private/qkeymapper_p.h>
-#include <private/qlocale_p.h>
-#include <private/qsystemlibrary_p.h>
-#include "qevent_p.h"
-
-//#define ALIEN_DEBUG
-
-#ifndef QT_NO_THREAD
-#include "qmutex.h"
-#endif
-
-#ifndef QT_NO_ACCESSIBILITY
-#include "qaccessible.h"
-
-#include <oleacc.h>
-#ifndef WM_GETOBJECT
-#define WM_GETOBJECT 0x003D
-#endif
-#endif // QT_NO_ACCESSIBILITY
-
-#if !defined(WINABLEAPI)
-# if defined(Q_WS_WINCE)
-# include <bldver.h>
-# endif
-# if !defined(Q_WS_WINCE)
-# include <winable.h>
-# endif
-#endif
-
-#ifndef QT_NO_GESTURES
-# ifndef GID_ZOOM
-# define GID_ZOOM 3
-# define GID_TWOFINGERTAP 6
-# define GID_PRESSANDTAP 7
-# define GID_ROLLOVER GID_PRESSANDTAP
-# endif
-#endif
-
-#ifndef WM_TOUCH
-# define WM_TOUCH 0x0240
-#endif
-
-#ifndef TOUCHEVENTF_MOVE
-# define TOUCHEVENTF_MOVE 0x0001
-# define TOUCHEVENTF_DOWN 0x0002
-# define TOUCHEVENTF_UP 0x0004
-# define TOUCHEVENTF_INRANGE 0x0008
-# define TOUCHEVENTF_PRIMARY 0x0010
-# define TOUCHEVENTF_NOCOALESCE 0x0020
-# define TOUCHEVENTF_PEN 0x0040
-# define TOUCHEVENTF_PALM 0x0080
-
-# define TOUCHINPUTMASKF_TIMEFROMSYSTEM 0x0001
-# define TOUCHINPUTMASKF_EXTRAINFO 0x0002
-# define TOUCHINPUTMASKF_CONTACTAREA 0x0004
-
-typedef struct tagTOUCHINPUT
-{
- LONG x;
- LONG y;
- HANDLE hSource;
- DWORD dwID;
- DWORD dwFlags;
- DWORD dwMask;
- DWORD dwTime;
- ULONG_PTR dwExtraInfo;
- DWORD cxContact;
- DWORD cyContact;
-} TOUCHINPUT, *PTOUCHINPUT;
-
-#endif
-
-#include <windowsx.h>
-#include <limits.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <math.h>
-
-#define PACKETDATA (PK_X | PK_Y | PK_BUTTONS | PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE \
- | PK_ORIENTATION | PK_CURSOR | PK_Z)
-#define PACKETMODE 0
-
-#include <wintab.h>
-#ifndef CSR_TYPE
-#define CSR_TYPE 20 // Some old Wacom wintab.h may not provide this constant.
-#endif
-#include <pktdef.h>
-
-#if defined(__CYGWIN32__)
-#define __INSIDE_CYGWIN32__
-#include <mywinsock.h>
-#endif
-
-#ifndef IMR_RECONVERTSTRING
-#define IMR_RECONVERTSTRING 4
-#endif
-
-#ifndef IMR_CONFIRMRECONVERTSTRING
-#define IMR_CONFIRMRECONVERTSTRING 0x0005
-#endif
-QT_BEGIN_NAMESPACE
-
-#ifdef Q_WS_WINCE
-#ifndef SHRG_RETURNCMD
-struct SHRGINFO {
- DWORD cbSize;
- HWND hwndClient;
- POINT ptDown;
- DWORD dwFlags;
-};
-#define GN_CONTEXTMENU 1000
-#define SHRG_RETURNCMD 0x00000001
-#define SHRG_NOANIMATION 0x00000010
-#endif
-
-#ifndef SPI_SETSIPINFO
-#define SPI_SETSIPINFO 224
-#endif
-
-#ifndef QT_NO_GESTURES
-typedef DWORD (API *AygRecognizeGesture)(SHRGINFO*);
-static AygRecognizeGesture ptrRecognizeGesture = 0;
-static bool aygResolved = false;
-static void resolveAygLibs()
-{
- if (!aygResolved) {
- aygResolved = true;
- QSystemLibrary ayglib(QLatin1String("aygshell"));
- ptrRecognizeGesture = (AygRecognizeGesture) ayglib.resolve("SHRecognizeGesture");
- }
-}
-#endif // QT_NO_GESTURES
-
-#endif
-
-#ifndef SPI_SETFONTSMOOTHINGTYPE
-# define SPI_SETFONTSMOOTHINGTYPE 0x200B
-#endif
-#ifndef SPI_GETFONTSMOOTHINGTYPE
-# define SPI_GETFONTSMOOTHINGTYPE 0x200A
-#endif
-#ifndef FE_FONTSMOOTHINGCLEARTYPE
-# define FE_FONTSMOOTHINGCLEARTYPE 0x0002
-#endif
-
-Q_GUI_EXPORT qreal qt_fontsmoothing_gamma;
-Q_GUI_EXPORT bool qt_cleartype_enabled;
-Q_GUI_EXPORT bool qt_win_owndc_required; // CS_OWNDC is required if we use the GL graphicssystem as default
-
-typedef HCTX (API *PtrWTOpen)(HWND, LPLOGCONTEXT, BOOL);
-typedef BOOL (API *PtrWTClose)(HCTX);
-typedef UINT (API *PtrWTInfo)(UINT, UINT, LPVOID);
-typedef BOOL (API *PtrWTEnable)(HCTX, BOOL);
-typedef BOOL (API *PtrWTOverlap)(HCTX, BOOL);
-typedef int (API *PtrWTPacketsGet)(HCTX, int, LPVOID);
-typedef BOOL (API *PtrWTGet)(HCTX, LPLOGCONTEXT);
-typedef int (API *PtrWTQueueSizeGet)(HCTX);
-typedef BOOL (API *PtrWTQueueSizeSet)(HCTX, int);
-
-static PtrWTInfo ptrWTInfo = 0;
-static PtrWTEnable ptrWTEnable = 0;
-static PtrWTOverlap ptrWTOverlap = 0;
-static PtrWTPacketsGet ptrWTPacketsGet = 0;
-static PtrWTGet ptrWTGet = 0;
-
-static PACKET localPacketBuf[QT_TABLET_NPACKETQSIZE]; // our own tablet packet queue.
-HCTX qt_tablet_context; // the hardware context for the tablet (like a window handle)
-bool qt_tablet_tilt_support;
-
-#ifndef QT_NO_TABLETEVENT
-static void tabletInit(const quint64 uniqueId, const UINT csr_type, HCTX hTab);
-static void tabletUpdateCursor(QTabletDeviceData &tdd, const UINT currentCursor);
-static void initWinTabFunctions(); // resolve the WINTAB api functions
-#endif // QT_NO_TABLETEVENT
-
-
-#ifndef QT_NO_ACCESSIBILITY
-extern IAccessible *qt_createWindowsAccessible(QAccessibleInterface *object);
-#endif // QT_NO_ACCESSIBILITY
-
-extern bool qt_tabletChokeMouse;
-extern QWidget* qt_get_tablet_widget();
-extern bool qt_sendSpontaneousEvent(QObject*, QEvent*);
-extern QRegion qt_dirtyRegion(QWidget *);
-
-typedef QHash<quint64, QTabletDeviceData> QTabletCursorInfo;
-Q_GLOBAL_STATIC(QTabletCursorInfo, tCursorInfo)
-QTabletDeviceData currentTabletPointer;
-
-// from qregion_win.cpp
-extern HRGN qt_tryCreateRegion(QRegion::RegionType type, int left, int top, int right, int bottom);
-
-// support for on-the-fly changes of the XP theme engine
-#ifndef WM_THEMECHANGED
-#define WM_THEMECHANGED 0x031A
-#endif
-#ifndef COLOR_MENUHILIGHT
-#define COLOR_MENUHILIGHT 29
-#define COLOR_MENUBAR 30
-#endif
-
-// support for xbuttons
-#ifndef WM_XBUTTONDOWN
-#define WM_XBUTTONDOWN 0x020B
-#define WM_XBUTTONUP 0x020C
-#define WM_XBUTTONDBLCLK 0x020D
-#endif
-#ifndef GET_KEYSTATE_WPARAM
-#define GET_KEYSTATE_WPARAM(wParam) (LOWORD(wParam))
-#define GET_XBUTTON_WPARAM(wParam) (HIWORD(wParam))
-#define XBUTTON1 0x0001
-#define XBUTTON2 0x0002
-#endif
-#ifndef MK_XBUTTON1
-#define MK_XBUTTON1 0x0020
-#define MK_XBUTTON2 0x0040
-#endif
-
-// support for multi-media-keys
-#ifndef WM_APPCOMMAND
-#define WM_APPCOMMAND 0x0319
-#endif
-
-#ifndef FAPPCOMMAND_MOUSE
-#define FAPPCOMMAND_MOUSE 0x8000
-#define FAPPCOMMAND_KEY 0
-#define FAPPCOMMAND_OEM 0x1000
-#define FAPPCOMMAND_MASK 0xF000
-#define GET_APPCOMMAND_LPARAM(lParam) ((short)(HIWORD(lParam) & ~FAPPCOMMAND_MASK))
-#define GET_DEVICE_LPARAM(lParam) ((WORD)(HIWORD(lParam) & FAPPCOMMAND_MASK))
-#define GET_MOUSEORKEY_LPARAM GET_DEVICE_LPARAM
-#define GET_FLAGS_LPARAM(lParam) (LOWORD(lParam))
-#define GET_KEYSTATE_LPARAM(lParam) GET_FLAGS_LPARAM(lParam)
-
-#define APPCOMMAND_BROWSER_BACKWARD 1
-#define APPCOMMAND_BROWSER_FORWARD 2
-#define APPCOMMAND_BROWSER_REFRESH 3
-#define APPCOMMAND_BROWSER_STOP 4
-#define APPCOMMAND_BROWSER_SEARCH 5
-#define APPCOMMAND_BROWSER_FAVORITES 6
-#define APPCOMMAND_BROWSER_HOME 7
-#define APPCOMMAND_VOLUME_MUTE 8
-#define APPCOMMAND_VOLUME_DOWN 9
-#define APPCOMMAND_VOLUME_UP 10
-#define APPCOMMAND_MEDIA_NEXTTRACK 11
-#define APPCOMMAND_MEDIA_PREVIOUSTRACK 12
-#define APPCOMMAND_MEDIA_STOP 13
-#define APPCOMMAND_MEDIA_PLAY_PAUSE 14
-#define APPCOMMAND_LAUNCH_MAIL 15
-#define APPCOMMAND_LAUNCH_MEDIA_SELECT 16
-#define APPCOMMAND_LAUNCH_APP1 17
-#define APPCOMMAND_LAUNCH_APP2 18
-#define APPCOMMAND_BASS_DOWN 19
-#define APPCOMMAND_BASS_BOOST 20
-#define APPCOMMAND_BASS_UP 21
-#define APPCOMMAND_TREBLE_DOWN 22
-#define APPCOMMAND_TREBLE_UP 23
-#endif // FAPPCOMMAND_MOUSE
-
-// New commands from Windows XP (some even Sp1)
-#ifndef APPCOMMAND_MICROPHONE_VOLUME_MUTE
-#define APPCOMMAND_MICROPHONE_VOLUME_MUTE 24
-#define APPCOMMAND_MICROPHONE_VOLUME_DOWN 25
-#define APPCOMMAND_MICROPHONE_VOLUME_UP 26
-#define APPCOMMAND_HELP 27
-#define APPCOMMAND_FIND 28
-#define APPCOMMAND_NEW 29
-#define APPCOMMAND_OPEN 30
-#define APPCOMMAND_CLOSE 31
-#define APPCOMMAND_SAVE 32
-#define APPCOMMAND_PRINT 33
-#define APPCOMMAND_UNDO 34
-#define APPCOMMAND_REDO 35
-#define APPCOMMAND_COPY 36
-#define APPCOMMAND_CUT 37
-#define APPCOMMAND_PASTE 38
-#define APPCOMMAND_REPLY_TO_MAIL 39
-#define APPCOMMAND_FORWARD_MAIL 40
-#define APPCOMMAND_SEND_MAIL 41
-#define APPCOMMAND_SPELL_CHECK 42
-#define APPCOMMAND_DICTATE_OR_COMMAND_CONTROL_TOGGLE 43
-#define APPCOMMAND_MIC_ON_OFF_TOGGLE 44
-#define APPCOMMAND_CORRECTION_LIST 45
-#define APPCOMMAND_MEDIA_PLAY 46
-#define APPCOMMAND_MEDIA_PAUSE 47
-#define APPCOMMAND_MEDIA_RECORD 48
-#define APPCOMMAND_MEDIA_FAST_FORWARD 49
-#define APPCOMMAND_MEDIA_REWIND 50
-#define APPCOMMAND_MEDIA_CHANNEL_UP 51
-#define APPCOMMAND_MEDIA_CHANNEL_DOWN 52
-#endif // APPCOMMAND_MICROPHONE_VOLUME_MUTE
-
-#if (_WIN32_WINNT < 0x0400)
-// This struct is defined in winuser.h if the _WIN32_WINNT >= 0x0400 -- in the
-// other cases we have to define it on our own.
-typedef struct tagTRACKMOUSEEVENT {
- DWORD cbSize;
- DWORD dwFlags;
- HWND hwndTrack;
- DWORD dwHoverTime;
-} TRACKMOUSEEVENT, *LPTRACKMOUSEEVENT;
-#endif
-#ifndef WM_MOUSELEAVE
-#define WM_MOUSELEAVE 0x02A3
-#endif
-
-QT_BEGIN_INCLUDE_NAMESPACE
-#include "private/qwidget_p.h"
-QT_END_INCLUDE_NAMESPACE
-
-static int translateButtonState(int s, int type, int button);
-
-// ##### get rid of this!
-QRgb qt_colorref2qrgb(COLORREF col)
-{
- return qRgb(GetRValue(col),GetGValue(col),GetBValue(col));
-}
-
-
-/*****************************************************************************
- Internal variables and functions
- *****************************************************************************/
-
-static HWND curWin = 0; // current window
-static HDC displayDC = 0; // display device context
-
-// Session management
-static bool sm_blockUserInput = false;
-static bool sm_smActive = false;
-extern QSessionManager* qt_session_manager_self;
-static bool sm_cancel;
-
-static bool replayPopupMouseEvent = false; // replay handling when popups close
-
-// ignore the next release event if return from a modal widget
-Q_GUI_EXPORT bool qt_win_ignoreNextMouseReleaseEvent = false;
-
-
-#if defined(QT_DEBUG)
-static bool appNoGrab = false; // mouse/keyboard grabbing
-#endif
-
-static bool app_do_modal = false; // modal mode
-extern QWidgetList *qt_modal_stack;
-extern QDesktopWidget *qt_desktopWidget;
-static QPointer<QWidget> popupButtonFocus;
-static bool qt_try_modal(QWidget *, MSG *, int& ret);
-
-QWidget *qt_button_down = 0; // widget got last button-down
-QPointer<QWidget> qt_last_mouse_receiver = 0;
-
-static HWND autoCaptureWnd = 0;
-static HWND imeParentWnd = 0;
-static void setAutoCapture(HWND); // automatic capture
-static void releaseAutoCapture();
-
-static void unregWinClasses();
-
-extern QCursor *qt_grab_cursor();
-
-#if defined(Q_WS_WIN)
-#define __export
-#endif
-
-extern "C" LRESULT QT_WIN_CALLBACK QtWndProc(HWND, UINT, WPARAM, LPARAM);
-
-class QETWidget : public QWidget // event translator widget
-{
-public:
- QWExtra *xtra() { return d_func()->extraData(); }
- QTLWExtra *topData() { return d_func()->topData(); }
- QTLWExtra *maybeTopData() { return d_func()->maybeTopData(); }
- void syncBackingStore(const QRegion &rgn) { d_func()->syncBackingStore(rgn); }
- void syncBackingStore() { d_func()->syncBackingStore(); }
- QWidgetData *dataPtr() { return data; }
- QWidgetPrivate *dptr() { return d_func(); }
- QRect frameStrut() const { return d_func()->frameStrut(); }
- bool winEvent(MSG *m, long *r) { return QWidget::winEvent(m, r); }
- void markFrameStrutDirty() { data->fstrut_dirty = 1; }
- bool translateMouseEvent(const MSG &msg);
- bool translateWheelEvent(const MSG &msg);
- bool translatePaintEvent(const MSG &msg);
- bool translateConfigEvent(const MSG &msg);
- bool translateCloseEvent(const MSG &msg);
- bool translateTabletEvent(const MSG &msg, PACKET *localPacketBuf, int numPackets);
-#ifndef QT_NO_GESTURES
- bool translateGestureEvent(const MSG &msg, const GESTUREINFO &gi);
-#endif
- void repolishStyle(QStyle &style);
- inline void showChildren(bool spontaneous) { d_func()->showChildren(spontaneous); }
- inline void hideChildren(bool spontaneous) { d_func()->hideChildren(spontaneous); }
- inline uint testWindowState(uint teststate){ return dataPtr()->window_state & teststate; }
- inline void setWindowTitle_helper(const QString &title) { d_func()->setWindowTitle_helper(title); }
- inline void forceUpdate() {
- QTLWExtra *tlwExtra = window()->d_func()->maybeTopData();
- if (tlwExtra && tlwExtra->backingStore)
- tlwExtra->backingStore->markDirty(rect(), this, true, true);
- }
-};
-
-// need to get default font?
-extern bool qt_app_has_font;
-
-extern QFont qt_LOGFONTtoQFont(LOGFONT& lf,bool scale);
-
-static void qt_set_windows_color_resources()
-{
- // Do the color settings
- QPalette pal;
- pal.setColor(QPalette::WindowText,
- QColor(qt_colorref2qrgb(GetSysColor(COLOR_WINDOWTEXT))));
- pal.setColor(QPalette::Button,
- QColor(qt_colorref2qrgb(GetSysColor(COLOR_BTNFACE))));
- pal.setColor(QPalette::Light,
- QColor(qt_colorref2qrgb(GetSysColor(COLOR_BTNHIGHLIGHT))));
- pal.setColor(QPalette::Dark,
- QColor(qt_colorref2qrgb(GetSysColor(COLOR_BTNSHADOW))));
- pal.setColor(QPalette::Mid, pal.button().color().darker(150));
- pal.setColor(QPalette::Text,
- QColor(qt_colorref2qrgb(GetSysColor(COLOR_WINDOWTEXT))));
- pal.setColor(QPalette::BrightText,
- QColor(qt_colorref2qrgb(GetSysColor(COLOR_BTNHIGHLIGHT))));
- pal.setColor(QPalette::Base,
- QColor(qt_colorref2qrgb(GetSysColor(COLOR_WINDOW))));
- pal.setColor(QPalette::Window,
- QColor(qt_colorref2qrgb(GetSysColor(COLOR_BTNFACE))));
- pal.setColor(QPalette::ButtonText,
- QColor(qt_colorref2qrgb(GetSysColor(COLOR_BTNTEXT))));
- pal.setColor(QPalette::Midlight,
- QColor(qt_colorref2qrgb(GetSysColor(COLOR_3DLIGHT))));
- pal.setColor(QPalette::Shadow,
- QColor(qt_colorref2qrgb(GetSysColor(COLOR_3DDKSHADOW))));
- pal.setColor(QPalette::Highlight,
- QColor(qt_colorref2qrgb(GetSysColor(COLOR_HIGHLIGHT))));
- pal.setColor(QPalette::HighlightedText,
- QColor(qt_colorref2qrgb(GetSysColor(COLOR_HIGHLIGHTTEXT))));
-
-#if defined(Q_WS_WINCE)
- // ### hardcoded until I find out how to get it from the system settings.
- pal.setColor(QPalette::LinkVisited, pal.highlight().color().dark(150));
- pal.setColor(QPalette::Link, pal.highlight().color().light(130));
- // Background == Base on Windows CE
- if (qt_wince_is_smartphone() || qt_wince_is_pocket_pc())
- pal.setColor(QPalette::Background, pal.base().color());
-#else
- pal.setColor(QPalette::Link, Qt::blue);
- pal.setColor(QPalette::LinkVisited, Qt::magenta);
-#endif
-
-
-
- pal.setColor(QPalette::Inactive, QPalette::Button, pal.button().color());
- pal.setColor(QPalette::Inactive, QPalette::Window, pal.background().color());
- pal.setColor(QPalette::Inactive, QPalette::Light, pal.light().color());
- pal.setColor(QPalette::Inactive, QPalette::Dark, pal.dark().color());
-
- if (pal.midlight() == pal.button())
- pal.setColor(QPalette::Midlight, pal.button().color().lighter(110));
- if (pal.background() != pal.base()) {
- pal.setColor(QPalette::Inactive, QPalette::Highlight, pal.color(QPalette::Inactive, QPalette::Window));
- pal.setColor(QPalette::Inactive, QPalette::HighlightedText, pal.color(QPalette::Inactive, QPalette::Text));
- }
-
- const QColor bg = pal.background().color();
- const QColor fg = pal.foreground().color(), btn = pal.button().color();
- QColor disabled((fg.red()+btn.red())/2,(fg.green()+btn.green())/2,
- (fg.blue()+btn.blue())/2);
- pal.setColorGroup(QPalette::Disabled, pal.foreground(), pal.button(), pal.light(),
- pal.dark(), pal.mid(), pal.text(), pal.brightText(), pal.base(), pal.background() );
- pal.setColor(QPalette::Disabled, QPalette::WindowText, disabled);
- pal.setColor(QPalette::Disabled, QPalette::Text, disabled);
- pal.setColor(QPalette::Disabled, QPalette::ButtonText, disabled);
- pal.setColor(QPalette::Disabled, QPalette::Highlight,
- QColor(qt_colorref2qrgb(GetSysColor(COLOR_HIGHLIGHT))));
- pal.setColor(QPalette::Disabled, QPalette::HighlightedText,
- QColor(qt_colorref2qrgb(GetSysColor(COLOR_HIGHLIGHTTEXT))));
- pal.setColor(QPalette::Disabled, QPalette::Base, bg);
-
- QApplicationPrivate::setSystemPalette(pal);
-
- QApplicationPrivate::initializeWidgetPaletteHash();
-
- QColor ttip(qt_colorref2qrgb(GetSysColor(COLOR_INFOBK)));
-
- QColor ttipText(qt_colorref2qrgb(GetSysColor(COLOR_INFOTEXT)));
- {
-#ifndef QT_NO_TOOLTIP
- QPalette tiplabel(pal);
- tiplabel.setColor(QPalette::All, QPalette::Button, ttip);
- tiplabel.setColor(QPalette::All, QPalette::Window, ttip);
- tiplabel.setColor(QPalette::All, QPalette::Text, ttipText);
- tiplabel.setColor(QPalette::All, QPalette::WindowText, ttipText);
- tiplabel.setColor(QPalette::All, QPalette::ButtonText, ttipText);
- tiplabel.setColor(QPalette::All, QPalette::Button, ttip);
- tiplabel.setColor(QPalette::All, QPalette::Window, ttip);
- tiplabel.setColor(QPalette::All, QPalette::Text, ttipText);
- tiplabel.setColor(QPalette::All, QPalette::WindowText, ttipText);
- tiplabel.setColor(QPalette::All, QPalette::ButtonText, ttipText);
- const QColor fg = tiplabel.foreground().color(), btn = tiplabel.button().color();
- QColor disabled((fg.red()+btn.red())/2,(fg.green()+btn.green())/2,
- (fg.blue()+btn.blue())/2);
- tiplabel.setColor(QPalette::Disabled, QPalette::WindowText, disabled);
- tiplabel.setColor(QPalette::Disabled, QPalette::Text, disabled);
- tiplabel.setColor(QPalette::Disabled, QPalette::Base, Qt::white);
- tiplabel.setColor(QPalette::Disabled, QPalette::BrightText, Qt::white);
- QToolTip::setPalette(tiplabel);
-#endif //QT_NO_TOOLTIP
- }
-}
-
-static void qt_set_windows_font_resources()
-{
-#ifndef Q_WS_WINCE
- NONCLIENTMETRICS ncm;
- ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICS, lfMessageFont) + sizeof(LOGFONT);
- SystemParametersInfo(SPI_GETNONCLIENTMETRICS, ncm.cbSize , &ncm, 0);
-
- QFont menuFont = qt_LOGFONTtoQFont(ncm.lfMenuFont, true);
- QFont messageFont = qt_LOGFONTtoQFont(ncm.lfMessageFont, true);
- QFont statusFont = qt_LOGFONTtoQFont(ncm.lfStatusFont, true);
- QFont titleFont = qt_LOGFONTtoQFont(ncm.lfCaptionFont, true);
-
- LOGFONT lfIconTitleFont;
- SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lfIconTitleFont), &lfIconTitleFont, 0);
- QFont iconTitleFont = qt_LOGFONTtoQFont(lfIconTitleFont, true);
-
- QApplication::setFont(menuFont, "QMenu");
- QApplication::setFont(menuFont, "QMenuBar");
- QApplication::setFont(messageFont, "QMessageBox");
- QApplication::setFont(statusFont, "QTipLabel");
- QApplication::setFont(statusFont, "QStatusBar");
- QApplication::setFont(titleFont, "Q3TitleBar");
- QApplication::setFont(titleFont, "QWorkspaceTitleBar");
- QApplication::setFont(iconTitleFont, "QAbstractItemView");
- QApplication::setFont(iconTitleFont, "QDockWidgetTitle");
-
-#else
- LOGFONT lf;
- HGDIOBJ stockFont = GetStockObject(SYSTEM_FONT);
- GetObject(stockFont, sizeof(lf), &lf);
- QFont systemFont = qt_LOGFONTtoQFont(lf, true);
- QApplicationPrivate::setSystemFont(systemFont);
- QFont smallerFont = systemFont;
- if (qt_wince_is_mobile()) {
- smallerFont.setPointSize(systemFont.pointSize()-1);
- QApplication::setFont(smallerFont, "QTabBar");
- smallerFont.setBold(true);
- QApplication::setFont(smallerFont, "QAbstractButton");
- }
-#endif// Q_WS_WINCE
-}
-
-static void qt_win_read_cleartype_settings()
-{
- UINT result = 0;
-#ifdef Q_OS_WINCE
- if (SystemParametersInfo(SPI_GETFONTSMOOTHING, 0, &result, 0))
- qt_cleartype_enabled = result;
-#else
- if (SystemParametersInfo(SPI_GETFONTSMOOTHINGTYPE, 0, &result, 0))
- qt_cleartype_enabled = (result == FE_FONTSMOOTHINGCLEARTYPE);
-#endif
-
- int winSmooth;
- if (SystemParametersInfo(0x200C /* SPI_GETFONTSMOOTHINGCONTRAST */, 0, &winSmooth, 0)) {
- qt_fontsmoothing_gamma = winSmooth / qreal(1000.0);
- } else {
- qt_fontsmoothing_gamma = 1.0;
- }
-
- // Safeguard ourselves against corrupt registry values...
- if (qt_fontsmoothing_gamma > 5 || qt_fontsmoothing_gamma < 1)
- qt_fontsmoothing_gamma = qreal(1.4);
-}
-
-static void qt_set_windows_resources()
-{
- if (QApplication::type() != QApplication::Tty)
- (void) QApplication::style(); // trigger creation of application style
- qt_set_windows_font_resources();
- qt_set_windows_color_resources();
-}
-
-void QApplicationPrivate::initializeWidgetPaletteHash()
-{
- QPalette pal = *QApplicationPrivate::sys_pal;
- QColor menuCol(qt_colorref2qrgb(GetSysColor(COLOR_MENU)));
- QColor menuText(qt_colorref2qrgb(GetSysColor(COLOR_MENUTEXT)));
- BOOL isFlat = false;
- if ((QSysInfo::WindowsVersion >= QSysInfo::WV_XP
- && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based))
- SystemParametersInfo(SPI_GETFLATMENU, 0, &isFlat, 0);
- QPalette menu(pal);
- // we might need a special color group for the menu.
- menu.setColor(QPalette::Active, QPalette::Button, menuCol);
- menu.setColor(QPalette::Active, QPalette::Text, menuText);
- menu.setColor(QPalette::Active, QPalette::WindowText, menuText);
- menu.setColor(QPalette::Active, QPalette::ButtonText, menuText);
- const QColor fg = menu.foreground().color(), btn = menu.button().color();
- QColor disabled(qt_colorref2qrgb(GetSysColor(COLOR_GRAYTEXT)));
- menu.setColor(QPalette::Disabled, QPalette::WindowText, disabled);
- menu.setColor(QPalette::Disabled, QPalette::Text, disabled);
- menu.setColor(QPalette::Disabled, QPalette::Highlight,
- QColor(qt_colorref2qrgb(GetSysColor(
- (QSysInfo::WindowsVersion >= QSysInfo::WV_XP
- && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)
- && isFlat ? COLOR_MENUHILIGHT : COLOR_HIGHLIGHT))));
- menu.setColor(QPalette::Disabled, QPalette::HighlightedText, disabled);
- menu.setColor(QPalette::Disabled, QPalette::Button,
- menu.color(QPalette::Active, QPalette::Button));
- menu.setColor(QPalette::Inactive, QPalette::Button,
- menu.color(QPalette::Active, QPalette::Button));
- menu.setColor(QPalette::Inactive, QPalette::Text,
- menu.color(QPalette::Active, QPalette::Text));
- menu.setColor(QPalette::Inactive, QPalette::WindowText,
- menu.color(QPalette::Active, QPalette::WindowText));
- menu.setColor(QPalette::Inactive, QPalette::ButtonText,
- menu.color(QPalette::Active, QPalette::ButtonText));
- menu.setColor(QPalette::Inactive, QPalette::Highlight,
- menu.color(QPalette::Active, QPalette::Highlight));
- menu.setColor(QPalette::Inactive, QPalette::HighlightedText,
- menu.color(QPalette::Active, QPalette::HighlightedText));
- menu.setColor(QPalette::Inactive, QPalette::ButtonText,
- pal.color(QPalette::Inactive, QPalette::Dark));
- QApplication::setPalette(menu, "QMenu");
-
- if ((QSysInfo::WindowsVersion >= QSysInfo::WV_XP
- && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based) && isFlat) {
- QColor menubar(qt_colorref2qrgb(GetSysColor(COLOR_MENUBAR)));
- menu.setColor(QPalette::Active, QPalette::Button, menubar);
- menu.setColor(QPalette::Disabled, QPalette::Button, menubar);
- menu.setColor(QPalette::Inactive, QPalette::Button, menubar);
- }
- QApplication::setPalette(menu, "QMenuBar");
-}
-
-static void qt_set_windows_updateScrollBar(QWidget *widget)
-{
- QList<QObject*> children = widget->children();
- for (int i = 0; i < children.size(); ++i) {
- QObject *o = children.at(i);
- if(!o->isWidgetType())
- continue;
- if (QWidget *w = static_cast<QWidget *>(o))
- qt_set_windows_updateScrollBar(w);
- }
-#ifndef QT_NO_SCROLLBAR
- if (qobject_cast<QScrollBar*>(widget))
- widget->updateGeometry();
-#endif
-}
-
-
-/*****************************************************************************
- qt_init() - initializes Qt for Windows
- *****************************************************************************/
-
-typedef BOOL (WINAPI *PtrSetProcessDPIAware) (VOID);
-static PtrSetProcessDPIAware ptrSetProcessDPIAware = 0;
-PtrUpdateLayeredWindow ptrUpdateLayeredWindow = 0;
-PtrUpdateLayeredWindowIndirect ptrUpdateLayeredWindowIndirect = 0;
-static BOOL WINAPI qt_updateLayeredWindowIndirect(HWND hwnd, const Q_UPDATELAYEREDWINDOWINFO *info)
-{
- return (*ptrUpdateLayeredWindow)(hwnd, info->hdcDst, info->pptDst, info->psize, info->hdcSrc,
- info->pptSrc, info->crKey, info->pblend, info->dwFlags);
-}
-
-void qt_init(QApplicationPrivate *priv, int)
-{
-
- int argc = priv->argc;
- char **argv = priv->argv;
- int i, j;
-
- // Get command line params
-
- j = argc ? 1 : 0;
- for (i=1; i<argc; i++) {
- if (argv[i] && *argv[i] != '-') {
- argv[j++] = argv[i];
- continue;
- }
-#if defined(QT_DEBUG)
- if (qstrcmp(argv[i], "-nograb") == 0)
- appNoGrab = !appNoGrab;
- else
-#endif // QT_DEBUG
- argv[j++] = argv[i];
- }
- if(j < priv->argc) {
- priv->argv[j] = 0;
- priv->argc = j;
- }
-
-#ifndef Q_WS_WINCE
- // No message boxes but important ones
- SetErrorMode(SetErrorMode(0) | SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX);
-#endif
-
-#ifndef Q_WS_WINCE
- // Initialize OLE/COM
- // S_OK means success and S_FALSE means that it has already
- // been initialized
- HRESULT r;
- r = OleInitialize(0);
- if (r != S_OK && r != S_FALSE) {
- qWarning("Qt: Could not initialize OLE (error %x)", (unsigned int)r);
- }
-#endif
-
- // Misc. initialization
-#if defined(QT_DEBUG) && !defined(Q_WS_WINCE)
- GdiSetBatchLimit(1);
-#endif
-
- // initialize key mapper
- QKeyMapper::changeKeyboard();
-
- QColormap::initialize();
- QFont::initialize();
-#ifndef QT_NO_CURSOR
- QCursorData::initialize();
-#endif
- qApp->setObjectName(priv->appName());
-
- // default font
-#ifndef Q_WS_WINCE
- HGDIOBJ stockFont = GetStockObject(DEFAULT_GUI_FONT);
-#else
- HGDIOBJ stockFont = GetStockObject(SYSTEM_FONT);
-#endif
-
- LOGFONT lf;
- GetObject(stockFont, sizeof(lf), &lf);
- QFont systemFont = qt_LOGFONTtoQFont(lf, true);
-
-#ifndef Q_WS_WINCE
- if (systemFont.family() == QLatin1String("MS Shell Dlg")) {
- systemFont.setFamily(QLatin1String("MS Shell Dlg 2"));
- }
-#endif
-
- QApplicationPrivate::setSystemFont(systemFont);
-
- // QFont::locale_init(); ### Uncomment when it does something on Windows
-
- if (QApplication::desktopSettingsAware())
- qt_set_windows_resources();
-
-#ifndef QT_NO_TABLETEVENT
- initWinTabFunctions();
-#endif // QT_NO_TABLETEVENT
- QApplicationPrivate::inputContext = new QWinInputContext(0);
-
- // Read the initial cleartype settings...
- qt_win_read_cleartype_settings();
- qt_win_owndc_required = false;
-
- extern void qt_win_initialize_directdraw();
- qt_win_initialize_directdraw();
-
-#ifndef Q_OS_WINCE
- ptrUpdateLayeredWindowIndirect =
- (PtrUpdateLayeredWindowIndirect) QSystemLibrary::resolve(QLatin1String("user32"),
- "UpdateLayeredWindowIndirect");
- ptrUpdateLayeredWindow =
- (PtrUpdateLayeredWindow) QSystemLibrary::resolve(QLatin1String("user32"),
- "UpdateLayeredWindow");
-
- if (ptrUpdateLayeredWindow && !ptrUpdateLayeredWindowIndirect)
- ptrUpdateLayeredWindowIndirect = qt_updateLayeredWindowIndirect;
-
- // Notify Vista and Windows 7 that we support highter DPI settings
- ptrSetProcessDPIAware = (PtrSetProcessDPIAware)
- QSystemLibrary::resolve(QLatin1String("user32"), "SetProcessDPIAware");
- if (ptrSetProcessDPIAware)
- ptrSetProcessDPIAware();
-#endif
-
-#ifndef QT_NO_GESTURES
- priv->GetGestureInfo = 0;
- priv->GetGestureExtraArgs = 0;
- priv->CloseGestureInfoHandle = 0;
- priv->SetGestureConfig = 0;
- priv->GetGestureConfig = 0;
- priv->BeginPanningFeedback = 0;
- priv->UpdatePanningFeedback = 0;
- priv->EndPanningFeedback = 0;
-
-#if defined(Q_WS_WINCE_WM) && defined(QT_WINCE_GESTURES)
- priv->GetGestureInfo = (PtrGetGestureInfo) &TKGetGestureInfo;
- priv->GetGestureExtraArgs = (PtrGetGestureExtraArgs) &TKGetGestureExtraArguments;
-#elif !defined(Q_WS_WINCE)
- #if !defined(QT_NO_NATIVE_GESTURES)
- priv->GetGestureInfo =
- (PtrGetGestureInfo)QSystemLibrary::resolve(QLatin1String("user32"),
- "GetGestureInfo");
- priv->GetGestureExtraArgs =
- (PtrGetGestureExtraArgs)QSystemLibrary::resolve(QLatin1String("user32"),
- "GetGestureExtraArgs");
- priv->CloseGestureInfoHandle =
- (PtrCloseGestureInfoHandle)QSystemLibrary::resolve(QLatin1String("user32"),
- "CloseGestureInfoHandle");
- priv->SetGestureConfig =
- (PtrSetGestureConfig)QSystemLibrary::resolve(QLatin1String("user32"),
- "SetGestureConfig");
- priv->GetGestureConfig =
- (PtrGetGestureConfig)QSystemLibrary::resolve(QLatin1String("user32"),
- "GetGestureConfig");
- #endif // QT_NO_NATIVE_GESTURES
- QSystemLibrary libTheme(QLatin1String("uxtheme"));
- priv->BeginPanningFeedback =
- (PtrBeginPanningFeedback)libTheme.resolve("BeginPanningFeedback");
- priv->UpdatePanningFeedback =
- (PtrUpdatePanningFeedback)libTheme.resolve("UpdatePanningFeedback");
- priv->EndPanningFeedback =
- (PtrEndPanningFeedback)libTheme.resolve("EndPanningFeedback");
-#endif
-#endif // QT_NO_GESTURES
-}
-
-/*****************************************************************************
- qt_cleanup() - cleans up when the application is finished
- *****************************************************************************/
-
-void qt_cleanup()
-{
- unregWinClasses();
- QPixmapCache::clear();
-
-#ifndef QT_NO_CURSOR
- QCursorData::cleanup();
-#endif
- QFont::cleanup();
- QColormap::cleanup();
- if (displayDC) {
- ReleaseDC(0, displayDC);
- displayDC = 0;
- }
-
- delete QApplicationPrivate::inputContext;
- QApplicationPrivate::inputContext = 0;
-
-#ifndef Q_WS_WINCE
- // Deinitialize OLE/COM
- OleUninitialize();
-#endif
-}
-
-
-/*****************************************************************************
- Platform specific global and internal functions
- *****************************************************************************/
-
-Q_GUI_EXPORT HDC qt_win_display_dc() // get display DC
-{
- Q_ASSERT(qApp && qApp->thread() == QThread::currentThread());
- if (!displayDC)
- displayDC = GetDC(0);
- return displayDC;
-}
-
-bool qt_nograb() // application no-grab option
-{
-#if defined(QT_DEBUG)
- return appNoGrab;
-#else
- return false;
-#endif
-}
-
-typedef QHash<QString, int> WinClassNameHash;
-Q_GLOBAL_STATIC(WinClassNameHash, winclassNames)
-
-//
-// If 0 is passed as the widget pointer, register a window class
-// for QWidget as default. This is used in QGLTemporaryContext
-// during GL initialization, where we don't want to use temporary
-// QWidgets or QGLWidgets, neither do we want to have separate code
-// to register window classes.
-//
-const QString qt_reg_winclass(QWidget *w) // register window class
-{
- Qt::WindowFlags flags = w ? w->windowFlags() : (Qt::WindowFlags)0;
- Qt::WindowFlags type = flags & Qt::WindowType_Mask;
-
- uint style;
- bool icon;
- QString cname;
- if (w && qt_widget_private(w)->isGLWidget) {
- cname = QLatin1String("QGLWidget");
- style = CS_DBLCLKS;
-#ifndef Q_WS_WINCE
- style |= CS_OWNDC;
-#endif
- icon = true;
- } else if (w && (flags & Qt::MSWindowsOwnDC)) {
- cname = QLatin1String("QWidgetOwnDC");
- style = CS_DBLCLKS;
-#ifndef Q_WS_WINCE
- style |= CS_OWNDC;
-#endif
- icon = true;
- } else if (w && (type == Qt::Tool || type == Qt::ToolTip)) {
- style = CS_DBLCLKS;
- if (w->inherits("QTipLabel") || w->inherits("QAlphaWidget")) {
- if ((QSysInfo::WindowsVersion >= QSysInfo::WV_XP
- && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)) {
- style |= CS_DROPSHADOW;
- }
- cname = QLatin1String("QToolTip");
- } else {
- cname = QLatin1String("QTool");
- }
-#ifndef Q_WS_WINCE
- style |= CS_SAVEBITS;
-#endif
- icon = false;
- } else if (w && (type == Qt::Popup)) {
- cname = QLatin1String("QPopup");
- style = CS_DBLCLKS;
-#ifndef Q_WS_WINCE
- style |= CS_SAVEBITS;
-#endif
- if ((QSysInfo::WindowsVersion >= QSysInfo::WV_XP
- && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based))
- style |= CS_DROPSHADOW;
- icon = false;
- } else {
- cname = QLatin1String("QWidget");
- style = CS_DBLCLKS;
- icon = true;
- }
-
-#ifndef Q_WS_WINCE
- // force CS_OWNDC when the GL graphics system is
- // used as the default renderer
- if (qt_win_owndc_required)
- style |= CS_OWNDC;
-#endif
-
-#ifdef Q_OS_WINCE
- // We need to register the classes with the
- // unique ID on WinCE to make sure we can
- // move the windows to the front when starting
- // a second instance.
- wchar_t uniqueAppID[MAX_PATH];
- GetModuleFileName(0, uniqueAppID, MAX_PATH);
- cname = QString::number(RegisterWindowMessage(
- (const wchar_t *) QString::fromWCharArray(uniqueAppID).toLower().replace(QLatin1Char('\\'),
- QLatin1Char('_')).utf16()));
-#endif
-
- // since multiple Qt versions can be used in one process
- // each one has to have window class names with a unique name
- // The first instance gets the unmodified name; if the class
- // has already been registered by another instance of Qt then
- // add an instance-specific ID, the address of the window proc.
- static int classExists = -1;
-
- if (classExists == -1) {
- WNDCLASS wcinfo;
- classExists = GetClassInfo((HINSTANCE)qWinAppInst(), (wchar_t*)cname.utf16(), &wcinfo);
- classExists = classExists && wcinfo.lpfnWndProc != QtWndProc;
- }
-
- if (classExists)
- cname += QString::number((quintptr)QtWndProc);
-
- if (winclassNames()->contains(cname)) // already registered in our list
- return cname;
-
-#ifndef Q_WS_WINCE
- WNDCLASSEX wc;
- wc.cbSize = sizeof(WNDCLASSEX);
-#else
- WNDCLASS wc;
-#endif
- wc.style = style;
- wc.lpfnWndProc = (WNDPROC)QtWndProc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 0;
- wc.hInstance = qWinAppInst();
- if (icon) {
- wc.hIcon = (HICON)LoadImage(qWinAppInst(), L"IDI_ICON1", IMAGE_ICON, 0, 0, LR_DEFAULTSIZE);
-#ifndef Q_WS_WINCE
- if (wc.hIcon) {
- int sw = GetSystemMetrics(SM_CXSMICON);
- int sh = GetSystemMetrics(SM_CYSMICON);
- wc.hIconSm = (HICON)LoadImage(qWinAppInst(), L"IDI_ICON1", IMAGE_ICON, sw, sh, 0);
- } else {
- wc.hIcon = (HICON)LoadImage(0, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
- wc.hIconSm = 0;
- }
-#endif
- } else {
- wc.hIcon = 0;
-#ifndef Q_WS_WINCE
- wc.hIconSm = 0;
-#endif
- }
- wc.hCursor = 0;
-#ifndef Q_WS_WINCE
- HBRUSH brush = 0;
- if (w && !qt_widget_private(w)->isGLWidget)
- brush = (HBRUSH)GetSysColorBrush(COLOR_WINDOW);
- wc.hbrBackground = brush;
-#else
- wc.hbrBackground = 0;
-#endif
- wc.lpszMenuName = 0;
- wc.lpszClassName = (wchar_t*)cname.utf16();
-
-#ifndef Q_WS_WINCE
- ATOM atom = RegisterClassEx(&wc);
-#else
- ATOM atom = RegisterClass(&wc);
-#endif
-
-#ifndef QT_NO_DEBUG
- if (!atom)
- qErrnoWarning("QApplication::regClass: Registering window class failed.");
-#else
- Q_UNUSED(atom);
-#endif
-
- winclassNames()->insert(cname, 1);
- return cname;
-}
-
-Q_GUI_EXPORT const QString qt_getRegisteredWndClass()
-{
- return qt_reg_winclass(0);
-}
-
-static void unregWinClasses()
-{
- WinClassNameHash *hash = winclassNames();
- QHash<QString, int>::ConstIterator it = hash->constBegin();
- while (it != hash->constEnd()) {
- UnregisterClass((wchar_t*)it.key().utf16(), qWinAppInst());
- ++it;
- }
- hash->clear();
-}
-
-
-/*****************************************************************************
- Safe configuration (move,resize,setGeometry) mechanism to avoid
- recursion when processing messages.
- *****************************************************************************/
-
-struct QWinConfigRequest {
- WId id; // widget to be configured
- int req; // 0=move, 1=resize, 2=setGeo
- int x, y, w, h; // request parameters
-};
-
-static QList<QWinConfigRequest*> *configRequests = 0;
-
-void qWinRequestConfig(WId id, int req, int x, int y, int w, int h)
-{
- if (!configRequests) // create queue
- configRequests = new QList<QWinConfigRequest*>;
- QWinConfigRequest *r = new QWinConfigRequest;
- r->id = id; // create new request
- r->req = req;
- r->x = x;
- r->y = y;
- r->w = w;
- r->h = h;
- configRequests->append(r); // store request in queue
-}
-
-static void qWinProcessConfigRequests() // perform requests in queue
-{
- if (!configRequests)
- return;
- QWinConfigRequest *r;
- for (;;) {
- if (configRequests->isEmpty())
- break;
- r = configRequests->takeLast();
- QWidget *w = QWidget::find(r->id);
- QRect rect(r->x, r->y, r->w, r->h);
- int req = r->req;
- delete r;
-
- if ( w ) { // widget exists
- if (w->testAttribute(Qt::WA_WState_ConfigPending))
- return; // biting our tail
- if (req == 0)
- w->move(rect.topLeft());
- else if (req == 1)
- w->resize(rect.size());
- else
- w->setGeometry(rect);
- }
- }
- delete configRequests;
- configRequests = 0;
-}
-
-
-/*****************************************************************************
- GUI event dispatcher
- *****************************************************************************/
-
-class QGuiEventDispatcherWin32 : public QEventDispatcherWin32
-{
- Q_DECLARE_PRIVATE(QEventDispatcherWin32)
-public:
- QGuiEventDispatcherWin32(QObject *parent = 0);
- bool processEvents(QEventLoop::ProcessEventsFlags flags);
-};
-
-QGuiEventDispatcherWin32::QGuiEventDispatcherWin32(QObject *parent)
- : QEventDispatcherWin32(parent)
-{
- createInternalHwnd();
-}
-
-bool QGuiEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags)
-{
- if (!QEventDispatcherWin32::processEvents(flags))
- return false;
-
- if (configRequests) // any pending configs?
- qWinProcessConfigRequests();
-
- return true;
-}
-
-void QApplicationPrivate::createEventDispatcher()
-{
- Q_Q(QApplication);
- if (q->type() != QApplication::Tty)
- eventDispatcher = new QGuiEventDispatcherWin32(q);
- else
- eventDispatcher = new QEventDispatcherWin32(q);
-}
-
-/*****************************************************************************
- Platform specific QApplication members
- *****************************************************************************/
-
-#ifdef QT3_SUPPORT
-void QApplication::setMainWidget(QWidget *mainWidget)
-{
- QApplicationPrivate::main_widget = mainWidget;
- if (QApplicationPrivate::main_widget && windowIcon().isNull()
- && QApplicationPrivate::main_widget->testAttribute(Qt::WA_SetWindowIcon))
- setWindowIcon(QApplicationPrivate::main_widget->windowIcon());
-}
-#endif
-
-#ifndef QT_NO_CURSOR
-
-/*****************************************************************************
- QApplication cursor stack
- *****************************************************************************/
-
-void QApplication::setOverrideCursor(const QCursor &cursor)
-{
- qApp->d_func()->cursor_list.prepend(cursor);
- SetCursor(qApp->d_func()->cursor_list.first().handle());
-}
-
-void QApplication::restoreOverrideCursor()
-{
- if (qApp->d_func()->cursor_list.isEmpty())
- return;
- qApp->d_func()->cursor_list.removeFirst();
-
- if (!qApp->d_func()->cursor_list.isEmpty()) {
- SetCursor(qApp->d_func()->cursor_list.first().handle());
- } else {
- QWidget *w = QWidget::find(curWin);
- if (w)
- SetCursor(w->cursor().handle());
- else
- SetCursor(QCursor(Qt::ArrowCursor).handle());
- }
-}
-
-#endif
-
-/*
- Internal function called from QWidget::setCursor()
- force is true if this function is called from dispatchEnterLeave, it means that the
- mouse is actually directly under this widget.
-*/
-
-#ifndef QT_NO_CURSOR
-void qt_win_set_cursor(QWidget *w, bool force)
-{
- static QPointer<QWidget> lastUnderMouse = 0;
- if (force) {
- lastUnderMouse = w;
- } else if (w->testAttribute(Qt::WA_WState_Created) && lastUnderMouse
- && lastUnderMouse->effectiveWinId() == w->effectiveWinId()) {
- w = lastUnderMouse;
- }
-
- if (!curWin && w && w->internalWinId())
- return;
- QWidget* cW = w && !w->internalWinId() ? w : QWidget::find(curWin);
- if (!cW || cW->window() != w->window() ||
- !cW->isVisible() || !cW->underMouse() || QApplication::overrideCursor())
- return;
-
- SetCursor(cW->cursor().handle());
-}
-#endif // QT_NO_CURSOR
-
-Qt::KeyboardModifiers qt_win_getKeyboardModifiers()
-{
- Qt::KeyboardModifiers modifiers = Qt::NoModifier;
- if (GetKeyState(VK_SHIFT) < 0)
- modifiers |= Qt::ShiftModifier;
- if (GetKeyState(VK_CONTROL) < 0)
- modifiers |= Qt::ControlModifier;
- if (GetKeyState(VK_MENU) < 0)
- modifiers |= Qt::AltModifier;
- return modifiers;
-}
-
-Qt::KeyboardModifiers QApplication::queryKeyboardModifiers()
-{
- return qt_win_getKeyboardModifiers();
-}
-
-/*****************************************************************************
- Routines to find a Qt widget from a screen position
- *****************************************************************************/
-
-QWidget *QApplication::topLevelAt(const QPoint &pos)
-{
- POINT p;
- HWND win;
- QWidget *w;
- p.x = pos.x();
- p.y = pos.y();
- win = WindowFromPoint(p);
- if (!win)
- return 0;
-
- w = QWidget::find(win);
- while (!w && win) {
- win = GetParent(win);
- w = QWidget::find(win);
- }
- return w ? w->window() : 0;
-}
-
-void QApplication::beep()
-{
- MessageBeep(MB_OK);
-}
-
-static void alert_widget(QWidget *widget, int duration)
-{
-#ifdef Q_OS_WINCE
- Q_UNUSED(widget);
- Q_UNUSED(duration);
-#else
- bool stopFlash = duration < 0;
-
- if (widget && (!widget->isActiveWindow() || stopFlash)) {
- DWORD timeOut = GetCaretBlinkTime();
- if (timeOut <= 0)
- timeOut = 250;
-
- UINT flashCount;
- if (duration == 0)
- flashCount = 10;
- else
- flashCount = duration/timeOut;
-
- FLASHWINFO info;
- info.cbSize = sizeof(info);
- info.hwnd = widget->window()->winId();
- info.dwFlags = stopFlash ? FLASHW_STOP : FLASHW_TRAY;
- info.dwTimeout = stopFlash ? 0 : timeOut;
- info.uCount = stopFlash ? 0 : flashCount;
-
- FlashWindowEx(&info);
- }
-#endif
-}
-
-void QApplication::alert(QWidget *widget, int duration)
-{
- if (!QApplicationPrivate::checkInstance("alert"))
- return;
-
- if (widget) {
- alert_widget(widget, duration);
- } else {
- const QWidgetList toplevels(topLevelWidgets());
- for (int i = 0; i < toplevels.count(); ++i) {
- QWidget *topLevel = toplevels.at(i);
- alert_widget(topLevel, duration);
- }
- }
-}
-
-QString QApplicationPrivate::appName() const
-{
- return QCoreApplicationPrivate::appName();
-}
-
-
-/*****************************************************************************
- Main event loop
- *****************************************************************************/
-
-extern uint qGlobalPostedEventsCount();
-
-void QApplication::winFocus(QWidget *widget, bool gotFocus)
-{
- if (d_func()->inPopupMode()) // some delayed focus event to ignore
- return;
- if (gotFocus) {
- setActiveWindow(widget);
- if (QApplicationPrivate::active_window
- && (QApplicationPrivate::active_window->windowType() == Qt::Dialog)) {
- // raise the entire application, not just the dialog
- QWidget* mw = QApplicationPrivate::active_window;
-#ifndef Q_WS_WINCE
- while(mw->parentWidget() && (mw->windowType() == Qt::Dialog))
- mw = mw->parentWidget()->window();
- if (mw->testAttribute(Qt::WA_WState_Created) && mw != QApplicationPrivate::active_window)
- SetWindowPos(mw->internalWinId(), HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
-#else
- // On Desktop Windows, we set the first parent of the dialog on top
- // Child windows will be automatically set above again.
- // On Windows CE we pass no parent in CreateWindowEx as otherwise
- // dialogs get embedded into the parent window. Thus we need to
- // manually iterate and reactivate all windows from bottom up.
- QList<QWidget*> raiseList;
- raiseList.push_back(mw);
- while(mw->parentWidget() && (mw->windowType() == Qt::Dialog)) {
- mw = mw->parentWidget()->window();
- raiseList.push_back(mw);
- }
- while(!raiseList.isEmpty()) {
- mw = raiseList.takeLast();
- if (mw->testAttribute(Qt::WA_WState_Created)) {
- HWND state = HWND_TOP;
- if (mw->windowFlags() & Qt::WindowStaysOnBottomHint)
- state = HWND_BOTTOM;
- else if (mw->windowFlags() & Qt::WindowStaysOnTopHint)
- state = HWND_TOPMOST;
- SetWindowPos(mw->internalWinId(), state, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
- }
- }
-#endif
- }
- } else {
- setActiveWindow(0);
- }
-}
-
-
-//
-// QtWndProc() receives all messages from the main event loop
-//
-
-static bool inLoop = false;
-static int inputcharset = CP_ACP;
-
-#define RETURN(x) { inLoop=false;return x; }
-
-static bool qt_is_translatable_mouse_event(UINT message)
-{
- return (((message >= WM_MOUSEFIRST && message <= WM_MOUSELAST) ||
- (message >= WM_XBUTTONDOWN && message <= WM_XBUTTONDBLCLK))
- && message != WM_MOUSEWHEEL
- && message != WM_MOUSEHWHEEL)
-
-#ifndef Q_WS_WINCE
- || (message >= WM_NCMOUSEMOVE && message <= WM_NCMBUTTONDBLCLK)
-#endif
- ;
-}
-
-extern "C" LRESULT QT_WIN_CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
-{
- bool result = true;
- QEvent::Type evt_type = QEvent::None;
- QETWidget *widget = 0;
-
- // there is no need to process pakcets from tablet unless
- // it is actually on the tablet, a flag to let us know...
- int nPackets; // the number of packets we get from the queue
-
- long res = 0;
- if (!qApp) // unstable app state
- RETURN(QWinInputContext::DefWindowProc(hwnd,message,wParam,lParam))
-
- QScopedLoopLevelCounter loopLevelCounter(QThreadData::get2(qApp->thread()));
-
-#if 0
- // make sure we update widgets also when the user resizes
- if (inLoop && qApp->loopLevel())
- qApp->sendPostedEvents(0, QEvent::Paint);
-#endif
-
- inLoop = true;
-
- MSG msg;
- msg.hwnd = hwnd; // create MSG structure
- msg.message = message; // time and pt fields ignored
- msg.wParam = wParam;
- msg.lParam = lParam;
- msg.pt.x = GET_X_LPARAM(lParam);
- msg.pt.y = GET_Y_LPARAM(lParam);
- // If it's a non-client-area message the coords are screen coords, otherwise they are
- // client coords.
-#ifndef Q_WS_WINCE
- if (message < WM_NCMOUSEMOVE || message > WM_NCMBUTTONDBLCLK)
-#endif
- ClientToScreen(msg.hwnd, &msg.pt);
-
- /*
- // sometimes the autograb is not released, so the clickevent is sent
- // to the wrong window. We ignore this for now, because it doesn't
- // cause any problems.
- if (msg.message == WM_LBUTTONDOWN || msg.message == WM_RBUTTONDOWN || msg.message == WM_MBUTTONDOWN) {
- HWND handle = WindowFromPoint(msg.pt);
- if (msg.hwnd != handle) {
- msg.hwnd = handle;
- hwnd = handle;
- }
- }
- */
-
-#if defined(QT_NON_COMMERCIAL)
- QT_NC_WNDPROC
-#endif
-
- // send through app filter
- if (qApp->filterEvent(&msg, &res))
- return res;
-
- // close any opened ime candidate window (enabled only on a popup widget)
- if (imeParentWnd && QApplication::activePopupWidget()
- && (message == WM_MBUTTONDOWN || message == WM_XBUTTONDOWN
- || message == WM_LBUTTONDOWN || message == WM_RBUTTONDOWN
-#ifndef Q_WS_WINCE
- || message == WM_NCMBUTTONDOWN || message == WM_NCLBUTTONDOWN
- || message == WM_NCRBUTTONDOWN)) {
-#else
- )) {
-#endif
- ::SendMessage(imeParentWnd, WM_IME_ENDCOMPOSITION, 0, 0);
- }
-
- switch (message) {
-#ifndef Q_WS_WINCE
-#ifndef QT_NO_SESSIONMANAGER
- case WM_QUERYENDSESSION: {
- if (sm_smActive) // bogus message from windows
- RETURN(true);
-
- sm_smActive = true;
- sm_blockUserInput = true; // prevent user-interaction outside interaction windows
- sm_cancel = false;
- if (qt_session_manager_self)
- qApp->commitData(*qt_session_manager_self);
- if (lParam & ENDSESSION_LOGOFF) {
- _flushall();
- }
- RETURN(!sm_cancel);
- }
- case WM_ENDSESSION: {
- sm_smActive = false;
- sm_blockUserInput = false;
- bool endsession = (bool) wParam;
-
- // we receive the message for each toplevel window included internal hidden ones,
- // but the aboutToQuit signal should be emitted only once.
- QApplicationPrivate *qAppPriv = QApplicationPrivate::instance();
- if (endsession && !qAppPriv->aboutToQuitEmitted) {
- qAppPriv->aboutToQuitEmitted = true;
- int index = QApplication::staticMetaObject.indexOfSignal("aboutToQuit()");
- qApp->qt_metacall(QMetaObject::InvokeMetaMethod, index,0);
- // since the process will be killed immediately quit() has no real effect
- QApplication::quit();
- }
-
- RETURN(0);
- }
-#endif
- case WM_DISPLAYCHANGE:
- if (QApplication::type() == QApplication::Tty)
- break;
- if (qt_desktopWidget) {
- qt_desktopWidget->move(GetSystemMetrics(76), GetSystemMetrics(77));
- QSize sz(GetSystemMetrics(78), GetSystemMetrics(79));
- if (sz == qt_desktopWidget->size()) {
- // a screen resized without changing size of the virtual desktop
- QResizeEvent rs(sz, qt_desktopWidget->size());
- QApplication::sendEvent(qt_desktopWidget, &rs);
- } else {
- qt_desktopWidget->resize(sz);
- }
- }
- break;
-#endif
-
- case WM_SETTINGCHANGE:
-#ifdef Q_WS_WINCE
- // CE SIP hide/show
- if (qt_desktopWidget && wParam == SPI_SETSIPINFO) {
- QResizeEvent re(QSize(0, 0), QSize(0, 0)); // Calculated by QDesktopWidget
- QApplication::sendEvent(qt_desktopWidget, &re);
- break;
- }
-#endif
- // ignore spurious XP message when user logs in again after locking
- if (QApplication::type() == QApplication::Tty)
- break;
- if (QApplication::desktopSettingsAware() && wParam != SPI_SETWORKAREA) {
- widget = (QETWidget*)QWidget::find(hwnd);
- if (widget) {
- if (wParam == SPI_SETNONCLIENTMETRICS)
- widget->markFrameStrutDirty();
- }
- }
- else if (qt_desktopWidget && wParam == SPI_SETWORKAREA) {
- qt_desktopWidget->move(GetSystemMetrics(76), GetSystemMetrics(77));
- QSize sz(GetSystemMetrics(78), GetSystemMetrics(79));
- if (sz == qt_desktopWidget->size()) {
- // a screen resized without changing size of the virtual desktop
- QResizeEvent rs(sz, qt_desktopWidget->size());
- QApplication::sendEvent(qt_desktopWidget, &rs);
- } else {
- qt_desktopWidget->resize(sz);
- }
- }
-
- if (wParam == SPI_SETFONTSMOOTHINGTYPE) {
- qt_win_read_cleartype_settings();
- foreach (QWidget *w, QApplication::topLevelWidgets()) {
- if (!w->isVisible())
- continue;
- ((QETWidget *) w)->forceUpdate();
- }
- }
-
- break;
- case WM_SYSCOLORCHANGE:
- if (QApplication::type() == QApplication::Tty)
- break;
- if (QApplication::desktopSettingsAware()) {
- widget = (QETWidget*)QWidget::find(hwnd);
- if (widget && !widget->parentWidget())
- qt_set_windows_color_resources();
- }
- break;
-
- case WM_LBUTTONDOWN:
- case WM_MBUTTONDOWN:
- case WM_RBUTTONDOWN:
- case WM_XBUTTONDOWN:
- case WM_LBUTTONDBLCLK:
- case WM_RBUTTONDBLCLK:
- case WM_MBUTTONDBLCLK:
- case WM_XBUTTONDBLCLK:
- if (qt_win_ignoreNextMouseReleaseEvent)
- qt_win_ignoreNextMouseReleaseEvent = false;
- break;
-
- case WM_LBUTTONUP:
- case WM_MBUTTONUP:
- case WM_RBUTTONUP:
- case WM_XBUTTONUP:
- if (qt_win_ignoreNextMouseReleaseEvent) {
- qt_win_ignoreNextMouseReleaseEvent = false;
- if (qt_button_down && qt_button_down->internalWinId() == autoCaptureWnd) {
- releaseAutoCapture();
- qt_button_down = 0;
- }
-
- RETURN(0);
- }
- break;
-
- default:
- break;
- }
-
- if (!widget)
- widget = (QETWidget*)QWidget::find(hwnd);
- if (!widget) // don't know this widget
- goto do_default;
-
- if (app_do_modal) { // modal event handling
- int ret = 0;
- if (!qt_try_modal(widget, &msg, ret))
- RETURN(ret);
- }
-
- res = 0;
- if (widget->winEvent(&msg, &res)) // send through widget filter
- RETURN(res);
-
- if (qt_is_translatable_mouse_event(message)) {
- if (QApplication::activePopupWidget() != 0) { // in popup mode
- POINT curPos = msg.pt;
- QWidget* w = QApplication::widgetAt(curPos.x, curPos.y);
- if (w)
- widget = (QETWidget*)w;
- }
-
- if (!qt_tabletChokeMouse) {
- result = widget->translateMouseEvent(msg); // mouse event
-#if defined(Q_WS_WINCE) && !defined(QT_NO_CONTEXTMENU)
- if (message == WM_LBUTTONDOWN && widget != QApplication::activePopupWidget()) {
- QWidget* alienWidget = widget;
- if ((alienWidget != QApplication::activePopupWidget()) && (alienWidget->contextMenuPolicy() != Qt::PreventContextMenu)) {
- QPoint pos(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
- QPoint globalPos(msg.pt.x, msg.pt.y);
- // In case we are using Alien, then the widget to
- // send the context menu event is a different one
- if (!alienWidget->testAttribute(Qt::WA_NativeWindow) && !alienWidget->testAttribute(Qt::WA_PaintOnScreen)) {
- alienWidget = QApplication::widgetAt(globalPos);
- if (alienWidget)
- pos = alienWidget->mapFromGlobal(globalPos);
- }
- if (alienWidget) {
- SHRGINFO shrg;
- shrg.cbSize = sizeof(shrg);
- shrg.hwndClient = hwnd;
- shrg.ptDown.x = GET_X_LPARAM(lParam);
- shrg.ptDown.y = GET_Y_LPARAM(lParam);
- shrg.dwFlags = SHRG_RETURNCMD | SHRG_NOANIMATION;
- resolveAygLibs();
-#ifndef QT_NO_GESTURES
- if (ptrRecognizeGesture && (ptrRecognizeGesture(&shrg) == GN_CONTEXTMENU)) {
- if (QApplication::activePopupWidget())
- QApplication::activePopupWidget()->close();
- QContextMenuEvent e(QContextMenuEvent::Mouse, pos, globalPos);
- result = qt_sendSpontaneousEvent(alienWidget, &e);
- }
-#endif // QT_NO_GESTURES
- }
- }
- }
-#endif
- } else {
- // Sometimes we only get a WM_MOUSEMOVE message
- // and sometimes we get both a WM_MOUSEMOVE and
- // a WM_LBUTTONDOWN/UP, this creates a spurious mouse
- // press/release event, using the PeekMessage
- // will help us fix this. This leaves us with a
- // question:
- // This effectively kills using the mouse AND the
- // tablet simultaneously, well creates wacky input.
- // Is this going to be a problem? (probably not)
- bool next_is_button = false;
- bool is_mouse_move = (message == WM_MOUSEMOVE);
- if (is_mouse_move) {
- MSG msg1;
- if (PeekMessage(&msg1, msg.hwnd, WM_MOUSEFIRST,
- WM_MOUSELAST, PM_NOREMOVE))
- next_is_button = (msg1.message == WM_LBUTTONUP
- || msg1.message == WM_LBUTTONDOWN);
- }
- if (!is_mouse_move || (is_mouse_move && !next_is_button))
- qt_tabletChokeMouse = false;
- }
- } else {
- switch (message) {
- case WM_TOUCH:
- result = QApplicationPrivate::instance()->translateTouchEvent(msg);
- break;
- case WM_KEYDOWN: // keyboard event
- case WM_SYSKEYDOWN:
- qt_keymapper_private()->updateKeyMap(msg);
- // fall-through intended
- case WM_KEYUP:
- case WM_SYSKEYUP:
-#if Q_OS_WINCE_WM
- case WM_HOTKEY:
- if(HIWORD(msg.lParam) == VK_TBACK) {
- const bool hotKeyDown = !(LOWORD(msg.lParam) & MOD_KEYUP);
- msg.lParam = 0x69 << 16;
- msg.wParam = VK_BACK;
- if (hotKeyDown) {
- msg.message = WM_KEYDOWN;
- qt_keymapper_private()->updateKeyMap(msg);
- } else {
- msg.message = WM_KEYUP;
- }
- }
- // fall-through intended
-#endif
- case WM_IME_CHAR:
- case WM_IME_KEYDOWN:
- case WM_CHAR: {
- MSG msg1;
- bool anyMsg = PeekMessage(&msg1, msg.hwnd, 0, 0, PM_NOREMOVE);
- if (anyMsg && msg1.message == WM_DEADCHAR) {
- result = true; // consume event since there is a dead char next
- break;
- }
- QWidget *g = QWidget::keyboardGrabber();
- if (g && qt_get_tablet_widget() && hwnd == qt_get_tablet_widget()->winId()) {
- // if we get an event for the internal tablet widget,
- // then don't send it to the keyboard grabber, but
- // send it to the widget itself (we don't use it right
- // now, just in case).
- g = 0;
- }
- if (g)
- widget = (QETWidget*)g;
- else if (QApplication::activePopupWidget())
- widget = (QETWidget*)QApplication::activePopupWidget()->focusWidget()
- ? (QETWidget*)QApplication::activePopupWidget()->focusWidget()
- : (QETWidget*)QApplication::activePopupWidget();
- else if (QApplication::focusWidget())
- widget = (QETWidget*)QApplication::focusWidget();
- else if (!widget || widget->internalWinId() == GetFocus()) // We faked the message to go to exactly that widget.
- widget = (QETWidget*)widget->window();
- if (widget->isEnabled())
- result = sm_blockUserInput
- ? true
- : qt_keymapper_private()->translateKeyEvent(widget, msg, g != 0);
- break;
- }
- case WM_SYSCHAR:
- result = true; // consume event
- break;
-
- case WM_MOUSEWHEEL:
- case WM_MOUSEHWHEEL:
- result = widget->translateWheelEvent(msg);
- break;
-
- case WM_APPCOMMAND:
- {
- uint cmd = GET_APPCOMMAND_LPARAM(lParam);
- uint uDevice = GET_DEVICE_LPARAM(lParam);
- uint dwKeys = GET_KEYSTATE_LPARAM(lParam);
-
- int state = translateButtonState(dwKeys, QEvent::KeyPress, 0);
-
- switch (uDevice) {
- case FAPPCOMMAND_KEY:
- {
- int key = 0;
-
- switch(cmd) {
- case APPCOMMAND_BASS_BOOST:
- key = Qt::Key_BassBoost;
- break;
- case APPCOMMAND_BASS_DOWN:
- key = Qt::Key_BassDown;
- break;
- case APPCOMMAND_BASS_UP:
- key = Qt::Key_BassUp;
- break;
- case APPCOMMAND_TREBLE_DOWN:
- key = Qt::Key_TrebleDown;
- break;
- case APPCOMMAND_TREBLE_UP:
- key = Qt::Key_TrebleUp;
- break;
- case APPCOMMAND_HELP:
- key = Qt::Key_Help;
- break;
- case APPCOMMAND_FIND:
- key = Qt::Key_Search;
- break;
- default:
- break;
- }
- if (key) {
- bool res = false;
- QWidget *g = QWidget::keyboardGrabber();
- if (g)
- widget = (QETWidget*)g;
- else if (QApplication::focusWidget())
- widget = (QETWidget*)QApplication::focusWidget();
- else
- widget = (QETWidget*)widget->window();
- if (widget->isEnabled()) {
- res = QKeyMapper::sendKeyEvent(widget, g != 0, QEvent::KeyPress, key,
- Qt::KeyboardModifier(state),
- QString(), false, 0, 0, 0, 0);
- }
- if (res)
- return true;
- }
- }
- break;
-
- default:
- break;
- }
-
- result = false;
- }
- break;
-
-#ifndef Q_WS_WINCE
- case WM_NCHITTEST:
- if (widget->isWindow()) {
- QPoint pos = widget->mapFromGlobal(QPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)));
- // don't show resize-cursors for fixed-size widgets
- QRect fs = widget->frameStrut();
- if (!widget->isMinimized()) {
- if (widget->minimumHeight() == widget->maximumHeight()) {
- if (pos.y() < -(fs.top() - fs.left()))
- return HTCAPTION;
- if (pos.y() >= widget->height())
- return HTBORDER;
- }
- if (widget->minimumWidth() == widget->maximumWidth() && (pos.x() < 0 || pos.x() >= widget->width()))
- return HTBORDER;
- }
- }
-
- result = false;
- break;
-#endif
-
- case WM_SYSCOMMAND: {
-#ifndef Q_WS_WINCE
- bool window_state_change = false;
- Qt::WindowStates oldstate = Qt::WindowStates(widget->dataPtr()->window_state);
- // MSDN:In WM_SYSCOMMAND messages, the four low-order bits of the wParam parameter are
- // used internally by the system. To obtain the correct result when testing the value of
- // wParam, an application must combine the value 0xFFF0 with the wParam value by using
- // the bitwise AND operator.
- switch(0xfff0 & wParam) {
- case SC_CONTEXTHELP:
-#ifndef QT_NO_WHATSTHIS
- QWhatsThis::enterWhatsThisMode();
-#endif
- DefWindowProc(hwnd, WM_NCPAINT, 1, 0);
- break;
-#if defined(QT_NON_COMMERCIAL)
- QT_NC_SYSCOMMAND
-#endif
- case SC_MINIMIZE:
- window_state_change = true;
- widget->dataPtr()->window_state |= Qt::WindowMinimized;
- if (widget->isVisible()) {
- QHideEvent e;
- qt_sendSpontaneousEvent(widget, &e);
- widget->hideChildren(true);
- const QString title = widget->windowIconText();
- if (!title.isEmpty())
- widget->setWindowTitle_helper(title);
- }
- result = false;
- break;
- case SC_MAXIMIZE:
- if(widget->isWindow())
- widget->topData()->normalGeometry = widget->geometry();
- case SC_RESTORE:
- window_state_change = true;
- if ((0xfff0 & wParam) == SC_MAXIMIZE)
- widget->dataPtr()->window_state |= Qt::WindowMaximized;
- else if (!widget->isMinimized())
- widget->dataPtr()->window_state &= ~Qt::WindowMaximized;
-
- if (widget->isMinimized()) {
- widget->dataPtr()->window_state &= ~Qt::WindowMinimized;
- widget->showChildren(true);
- QShowEvent e;
- qt_sendSpontaneousEvent(widget, &e);
- const QString title = widget->windowTitle();
- if (!title.isEmpty())
- widget->setWindowTitle_helper(title);
- }
- result = false;
- break;
- default:
- result = false;
- break;
- }
-
- if (window_state_change) {
- QWindowStateChangeEvent e(oldstate);
- qt_sendSpontaneousEvent(widget, &e);
- }
-#endif // #ifndef Q_OS_WINCE
-
- break;
- }
-
- case WM_SETTINGCHANGE:
- if ( QApplication::type() == QApplication::Tty )
- break;
-
- if (!msg.wParam) {
-#ifdef Q_WS_WINCE
- // On Windows CE, lParam parameter is a constant, not a char pointer.
- if (msg.lParam == INI_INTL) {
-#else
- QString area = QString::fromWCharArray((wchar_t*)msg.lParam);
- if (area == QLatin1String("intl")) {
-#endif
- QLocalePrivate::updateSystemPrivate();
- if (!widget->testAttribute(Qt::WA_SetLocale))
- widget->dptr()->setLocale_helper(QLocale(), true);
- QEvent e(QEvent::LocaleChange);
- QApplication::sendEvent(qApp, &e);
- }
- }
- else if (msg.wParam == SPI_SETICONTITLELOGFONT) {
- if (QApplication::desktopSettingsAware()) {
- widget = (QETWidget*)QWidget::find(hwnd);
- if (widget && !widget->parentWidget()) {
- qt_set_windows_font_resources();
- }
- }
- }
- else if (msg.wParam == SPI_SETNONCLIENTMETRICS) {
- widget = (QETWidget*)QWidget::find(hwnd);
- if (widget && !widget->parentWidget()) {
- qt_set_windows_updateScrollBar(widget);
- QEvent e(QEvent::LayoutRequest);
- QApplication::sendEvent(widget, &e);
- }
- }
-
- break;
-
- case WM_PAINT: // paint event
- case WM_ERASEBKGND: // erase window background
- result = widget->translatePaintEvent(msg);
- break;
-
-#ifndef Q_WS_WINCE
- case WM_ENTERSIZEMOVE:
- autoCaptureWnd = hwnd;
- break;
- case WM_EXITSIZEMOVE:
- autoCaptureWnd = 0;
- break;
-#endif
- case WM_MOVE: // move window
- case WM_SIZE: // resize window
- result = widget->translateConfigEvent(msg);
- break;
-
- case WM_ACTIVATEAPP:
- if (wParam == FALSE) {
- QApplication::setActiveWindow(0);
- // Another application was activated while our popups are open,
- // then close all popups. In case some popup refuses to close,
- // we give up after 1024 attempts (to avoid an infinite loop).
- int maxiter = 1024;
- QWidget *popup;
- while ((popup=QApplication::activePopupWidget()) && maxiter--)
- popup->close();
- }
- break;
-
- case WM_ACTIVATE:
- if ( QApplication::type() == QApplication::Tty )
- break;
-
- if (ptrWTOverlap && ptrWTEnable) {
- // cooperate with other tablet applications, but when
- // we get focus, I want to use the tablet...
- if (qt_tablet_context && GET_WM_ACTIVATE_STATE(wParam, lParam)) {
- if (ptrWTEnable(qt_tablet_context, true))
- ptrWTOverlap(qt_tablet_context, true);
- }
- }
- if (QApplication::activePopupWidget() && LOWORD(wParam) == WA_INACTIVE &&
- QWidget::find((HWND)lParam) == 0) {
- // Another application was activated while our popups are open,
- // then close all popups. In case some popup refuses to close,
- // we give up after 1024 attempts (to avoid an infinite loop).
- int maxiter = 1024;
- QWidget *popup;
- while ((popup=QApplication::activePopupWidget()) && maxiter--)
- popup->close();
- }
-
- if (LOWORD(wParam) != WA_INACTIVE) {
- // WM_ACTIVATEAPP handles the "true" false case, as this is only when the application
- // loses focus. Doing it here would result in the widget getting focus to not know
- // where it got it from; it would simply get a 0 value as the old focus widget.
-#ifdef Q_WS_WINCE
- {
-#ifdef Q_WS_WINCE_WM
- // On Windows mobile we do not receive WM_SYSCOMMAND / SC_MINIMIZE messages.
- // Thus we have to unset the minimized state explicitly. We must do this for all
- // top-level widgets, because we get the HWND of a random widget here.
- foreach (QWidget* tlw, QApplication::topLevelWidgets()) {
- if (tlw->isMinimized())
- tlw->setWindowState(tlw->windowState() & ~Qt::WindowMinimized);
- }
-#else
- // On Windows CE we do not receive WM_SYSCOMMAND / SC_MINIMIZE messages.
- // Thus we have to unset the minimized state explicitly.
- if (widget->windowState() & Qt::WindowMinimized)
- widget->setWindowState(widget->windowState() & ~Qt::WindowMinimized);
-#endif // Q_WS_WINCE_WM
-
-#else
- if (!(widget->windowState() & Qt::WindowMinimized)) {
-#endif
- // Ignore the activate message send by WindowsXP to a minimized window
-#ifdef Q_WS_WINCE_WM
- if (widget->windowState() & Qt::WindowFullScreen)
- qt_wince_hide_taskbar(widget->winId());
-#endif
- qApp->winFocus(widget, true);
- // reset any window alert flashes
- alert_widget(widget, -1);
- }
- }
-
- // Windows tries to activate a modally blocked window.
- // This happens when restoring an application after "Show Desktop"
- if (app_do_modal && LOWORD(wParam) == WA_ACTIVE) {
- QWidget *top = 0;
- if (!QApplicationPrivate::tryModalHelper(widget, &top) && top && widget != top) {
- if (top->isVisible()) {
- top->activateWindow();
- } else {
- // This is the case when native file dialogs are shown
- QWidget *p = (top->parentWidget() ? top->parentWidget()->window() : 0);
- if (p && p->isVisible())
- p->activateWindow();
- }
- }
- }
- break;
-
-#ifndef Q_WS_WINCE
- case WM_MOUSEACTIVATE:
- if (widget->window()->windowType() == Qt::Tool) {
- QWidget *w = widget;
- if (!w->window()->focusWidget()) {
- while (w && (w->focusPolicy() & Qt::ClickFocus) == 0) {
- if (w->isWindow()) {
- QWidget *fw = w;
- while ((fw = fw->nextInFocusChain()) != w && fw->focusPolicy() == Qt::NoFocus)
- ;
- if (fw != w)
- break;
- QWidget *pw = w->parentWidget();
- while (pw) {
- pw = pw->window();
- if (pw && pw->isVisible() && pw->focusWidget()) {
- Q_ASSERT(pw->testAttribute(Qt::WA_WState_Created));
- SetWindowPos(pw->internalWinId(), HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
- break;
- }
- pw = pw->parentWidget();
- }
- RETURN(MA_NOACTIVATE);
- }
- w = w->parentWidget();
- }
- }
- }
- RETURN(MA_ACTIVATE);
- break;
-#endif
- case WM_SHOWWINDOW:
- if (lParam == SW_PARENTOPENING) {
- if (widget->testAttribute(Qt::WA_WState_Hidden))
- RETURN(0);
- }
- if (widget->isWindow() && widget->testAttribute(Qt::WA_WState_Visible)
- && !widget->testWindowState(Qt::WindowMinimized)) {
- if (lParam == SW_PARENTOPENING) {
- QShowEvent e;
- qt_sendSpontaneousEvent(widget, &e);
- widget->showChildren(true);
- } else if (lParam == SW_PARENTCLOSING) {
- QHideEvent e;
- qt_sendSpontaneousEvent(widget, &e);
- widget->hideChildren(true);
- }
- }
- if (!wParam && autoCaptureWnd == widget->internalWinId())
- releaseAutoCapture();
- result = false;
- break;
-
- case WM_PALETTECHANGED: // our window changed palette
- if (QColormap::hPal() && (WId)wParam == widget->internalWinId())
- RETURN(0); // otherwise: FALL THROUGH!
- // FALL THROUGH
- case WM_QUERYNEWPALETTE: // realize own palette
- if (QColormap::hPal()) {
- Q_ASSERT(widget->testAttribute(Qt::WA_WState_Created));
- HDC hdc = GetDC(widget->internalWinId());
- HPALETTE hpalOld = SelectPalette(hdc, QColormap::hPal(), FALSE);
- uint n = RealizePalette(hdc);
- if (n)
- InvalidateRect(widget->internalWinId(), 0, TRUE);
- SelectPalette(hdc, hpalOld, TRUE);
- RealizePalette(hdc);
- ReleaseDC(widget->internalWinId(), hdc);
- RETURN(n);
- }
- break;
- case WM_CLOSE: // close window
- widget->translateCloseEvent(msg);
- RETURN(0); // always handled
-
- case WM_DESTROY: // destroy window
- if (hwnd == curWin) {
- QWidget *enter = QWidget::mouseGrabber();
- if (enter == widget)
- enter = 0;
- QApplicationPrivate::dispatchEnterLeave(enter, widget);
- curWin = enter ? enter->effectiveWinId() : 0;
- qt_last_mouse_receiver = enter;
- }
- if (widget == popupButtonFocus)
- popupButtonFocus = 0;
- result = false;
- break;
-
-#ifndef Q_WS_WINCE
- case WM_WINDOWPOSCHANGING:
- {
- result = false;
- if (widget->isWindow()) {
- WINDOWPOS *winPos = (WINDOWPOS *)lParam;
- if (widget->layout() && widget->layout()->hasHeightForWidth()
- && !(winPos->flags & (SWP_NOCOPYBITS | SWP_NOSIZE))) {
- QRect fs = widget->frameStrut();
- QRect rect = widget->geometry();
- QRect newRect = QRect(winPos->x + fs.left(),
- winPos->y + fs.top(),
- winPos->cx - fs.left() - fs.right(),
- winPos->cy - fs.top() - fs.bottom());
-
- QSize newSize = QLayout::closestAcceptableSize(widget, newRect.size());
-
- int dh = newSize.height() - newRect.height();
- int dw = newSize.width() - newRect.width();
- if (!dw && ! dh)
- break; // Size OK
-
- if (rect.y() != newRect.y()) {
- newRect.setTop(newRect.top() - dh);
- } else {
- newRect.setBottom(newRect.bottom() + dh);
- }
-
- if (rect.x() != newRect.x()) {
- newRect.setLeft(newRect.left() - dw);
- } else {
- newRect.setRight(newRect.right() + dw);
- }
-
- winPos->x = newRect.x() - fs.left();
- winPos->y = newRect.y() - fs.top();
- winPos->cx = newRect.width() + fs.left() + fs.right();
- winPos->cy = newRect.height() + fs.top() + fs.bottom();
-
- RETURN(0);
- }
- if (widget->windowFlags() & Qt::WindowStaysOnBottomHint) {
- winPos->hwndInsertAfter = HWND_BOTTOM;
- }
- }
- }
- break;
-
- case WM_GETMINMAXINFO:
- if (widget->xtra()) {
- MINMAXINFO *mmi = (MINMAXINFO *)lParam;
- QWExtra *x = widget->xtra();
- QRect fs = widget->frameStrut();
- if ( x->minw > 0 )
- mmi->ptMinTrackSize.x = x->minw + fs.right() + fs.left();
- if ( x->minh > 0 )
- mmi->ptMinTrackSize.y = x->minh + fs.top() + fs.bottom();
- qint32 maxw = (x->maxw >= x->minw) ? x->maxw : x->minw;
- qint32 maxh = (x->maxh >= x->minh) ? x->maxh : x->minh;
- if ( maxw < QWIDGETSIZE_MAX ) {
- mmi->ptMaxTrackSize.x = maxw + fs.right() + fs.left();
- // windows with title bar have an implicit size limit of 112 pixels
- if (widget->windowFlags() & Qt::WindowTitleHint)
- mmi->ptMaxTrackSize.x = qMax<long>(mmi->ptMaxTrackSize.x, 112);
- }
- if ( maxh < QWIDGETSIZE_MAX )
- mmi->ptMaxTrackSize.y = maxh + fs.top() + fs.bottom();
- RETURN(0);
- }
- break;
-
-#ifndef QT_NO_CONTEXTMENU
- case WM_CONTEXTMENU:
- {
- // it's not VK_APPS or Shift+F10, but a click in the NC area
- if (lParam != (int)0xffffffff) {
- result = false;
- break;
- }
-
- QWidget *fw = QWidget::keyboardGrabber();
- if (!fw) {
- if (QApplication::activePopupWidget())
- fw = (QApplication::activePopupWidget()->focusWidget()
- ? QApplication::activePopupWidget()->focusWidget()
- : QApplication::activePopupWidget());
- else if (QApplication::focusWidget())
- fw = QApplication::focusWidget();
- else if (widget)
- fw = widget->window();
- }
- if (fw && fw->isEnabled()) {
- QPoint pos = fw->inputMethodQuery(Qt::ImMicroFocus).toRect().center();
- QContextMenuEvent e(QContextMenuEvent::Keyboard, pos, fw->mapToGlobal(pos),
- qt_win_getKeyboardModifiers());
- result = qt_sendSpontaneousEvent(fw, &e);
- }
- }
- break;
-#endif
-#endif
-
- case WM_IME_STARTCOMPOSITION:
- case WM_IME_ENDCOMPOSITION:
- case WM_IME_COMPOSITION: {
- QWidget *fw = QApplication::focusWidget();
- QWinInputContext *im = fw ? qobject_cast<QWinInputContext *>(fw->inputContext()) : 0;
- if (fw && im) {
- if(message == WM_IME_STARTCOMPOSITION)
- result = im->startComposition();
- else if (message == WM_IME_ENDCOMPOSITION)
- result = im->endComposition();
- else if (message == WM_IME_COMPOSITION)
- result = im->composition(lParam);
- }
- break;
- }
- case WM_IME_REQUEST: {
- QWidget *fw = QApplication::focusWidget();
- QWinInputContext *im = fw ? qobject_cast<QWinInputContext *>(fw->inputContext()) : 0;
- if (fw && im) {
- if(wParam == IMR_RECONVERTSTRING) {
- int ret = im->reconvertString((RECONVERTSTRING *)lParam);
- if (ret == -1) {
- result = false;
- } else {
- return ret;
- }
- } else if (wParam == IMR_CONFIRMRECONVERTSTRING) {
- RETURN(TRUE);
- } else {
- // in all other cases, call DefWindowProc()
- result = false;
- }
- }
- break;
- }
-#ifndef Q_WS_WINCE
- case WM_CHANGECBCHAIN:
- case WM_DRAWCLIPBOARD:
-#endif
- case WM_RENDERFORMAT:
- case WM_RENDERALLFORMATS:
-#ifndef QT_NO_CLIPBOARD
- case WM_DESTROYCLIPBOARD:
- if (qt_clipboard) {
- QClipboardEvent e(reinterpret_cast<QEventPrivate *>(&msg));
- qt_sendSpontaneousEvent(qt_clipboard, &e);
- RETURN(0);
- }
- result = false;
- break;
-#endif //QT_NO_CLIPBOARD
-#ifndef QT_NO_ACCESSIBILITY
- case WM_GETOBJECT:
- {
- /* On Win64, lParam can be 0x00000000fffffffc or 0xfffffffffffffffc (!),
- but MSDN says that lParam should be converted to a DWORD
- before its compared against OBJID_CLIENT
- */
- const DWORD dwObjId = (DWORD)lParam;
- // Ignoring all requests while starting up
- if (QApplication::startingUp() || QApplication::closingDown() || dwObjId != OBJID_CLIENT) {
- result = false;
- break;
- }
-
- typedef LRESULT (WINAPI *PtrLresultFromObject)(REFIID, WPARAM, LPUNKNOWN);
- static PtrLresultFromObject ptrLresultFromObject = 0;
- static bool oleaccChecked = false;
-
- if (!oleaccChecked) {
- oleaccChecked = true;
-#if !defined(Q_OS_WINCE)
- ptrLresultFromObject = (PtrLresultFromObject)QSystemLibrary::resolve(QLatin1String("oleacc"), "LresultFromObject");
-#endif
- }
- if (ptrLresultFromObject) {
- QAccessibleInterface *acc = QAccessible::queryAccessibleInterface(widget);
- if (!acc) {
- result = false;
- break;
- }
-
- // and get an instance of the IAccessibile implementation
- IAccessible *iface = qt_createWindowsAccessible(acc);
- res = ptrLresultFromObject(IID_IAccessible, wParam, iface); // ref == 2
- iface->Release(); // the client will release the object again, and then it will destroy itself
-
- if (res > 0)
- RETURN(res);
- }
- }
- result = false;
- break;
- case WM_GETTEXT:
- if (!widget->isWindow()) {
- int ret = 0;
- QAccessibleInterface *acc = QAccessible::queryAccessibleInterface(widget);
- if (acc) {
- QString text = acc->text(QAccessible::Name, 0);
- if (text.isEmpty())
- text = widget->objectName();
- ret = qMin<int>(wParam - 1, text.size());
- text.resize(ret);
- memcpy((void *)lParam, text.utf16(), (text.size() + 1) * sizeof(ushort));
- delete acc;
- }
- if (!ret) {
- result = false;
- break;
- }
- RETURN(ret);
- }
- result = false;
- break;
-#endif
- case WT_PACKET:
- if (ptrWTPacketsGet) {
- if ((nPackets = ptrWTPacketsGet(qt_tablet_context, QT_TABLET_NPACKETQSIZE, &localPacketBuf))) {
- result = widget->translateTabletEvent(msg, localPacketBuf, nPackets);
- }
- }
- break;
- case WT_PROXIMITY:
-
- #ifndef QT_NO_TABLETEVENT
- if (ptrWTPacketsGet && ptrWTInfo) {
- const bool enteredProximity = LOWORD(lParam) != 0;
- PACKET proximityBuffer[1]; // we are only interested in the first packet in this case
- const int totalPacks = ptrWTPacketsGet(qt_tablet_context, 1, proximityBuffer);
- if (totalPacks > 0) {
- const UINT currentCursor = proximityBuffer[0].pkCursor;
-
- UINT csr_physid;
- ptrWTInfo(WTI_CURSORS + currentCursor, CSR_PHYSID, &csr_physid);
- UINT csr_type;
- ptrWTInfo(WTI_CURSORS + currentCursor, CSR_TYPE, &csr_type);
- const UINT deviceIdMask = 0xFF6; // device type mask && device color mask
- quint64 uniqueId = (csr_type & deviceIdMask);
- uniqueId = (uniqueId << 32) | csr_physid;
-
- // initialising and updating the cursor should be done in response to
- // WT_CSRCHANGE. We do it in WT_PROXIMITY because some wintab never send
- // the event WT_CSRCHANGE even if asked with CXO_CSRMESSAGES
- const QTabletCursorInfo *const globalCursorInfo = tCursorInfo();
- if (!globalCursorInfo->contains(uniqueId))
- tabletInit(uniqueId, csr_type, qt_tablet_context);
-
- currentTabletPointer = globalCursorInfo->value(uniqueId);
- tabletUpdateCursor(currentTabletPointer, currentCursor);
- }
- qt_tabletChokeMouse = false;
-
- QTabletEvent tabletProximity(enteredProximity ? QEvent::TabletEnterProximity
- : QEvent::TabletLeaveProximity,
- QPoint(), QPoint(), QPointF(), currentTabletPointer.currentDevice, currentTabletPointer.currentPointerType, 0, 0,
- 0, 0, 0, 0, 0, currentTabletPointer.llId);
- QApplication::sendEvent(qApp, &tabletProximity);
- }
- #endif // QT_NO_TABLETEVENT
-
- break;
-#ifdef Q_WS_WINCE_WM
- case WM_SETFOCUS: {
- HIMC hC;
- hC = ImmGetContext(hwnd);
- ImmSetOpenStatus(hC, TRUE);
- ImmEscape(NULL, hC, IME_ESC_SET_MODE, (LPVOID)IM_SPELL);
- result = false;
- }
- break;
-#endif
- case WM_KILLFOCUS:
- if (!QWidget::find((HWND)wParam)) { // we don't get focus, so unset it now
- if (!widget->hasFocus()) // work around Windows bug after minimizing/restoring
- widget = (QETWidget*)QApplication::focusWidget();
- HWND focus = ::GetFocus();
- //if there is a current widget and the new widget belongs to the same toplevel window
- //or if the current widget was embedded into non-qt window (i.e. we won't get WM_ACTIVATEAPP)
- //then we clear the focus on the widget
- //in case the new widget belongs to a different widget hierarchy, clearing the focus
- //will be handled because the active window will change
- const bool embedded = widget && ((QETWidget*)widget->window())->topData()->embedded;
- if (widget && (embedded || ::IsChild(widget->window()->internalWinId(), focus))) {
- widget->clearFocus();
- result = true;
- } else {
- result = false;
- }
- } else {
- result = false;
- }
- break;
- case WM_THEMECHANGED:
- if ((widget->windowType() == Qt::Desktop) || !qApp || QApplication::closingDown()
- || QApplication::type() == QApplication::Tty)
- break;
-
- if (widget->testAttribute(Qt::WA_WState_Polished))
- QApplication::style()->unpolish(widget);
-
- if (widget->testAttribute(Qt::WA_WState_Polished))
- QApplication::style()->polish(widget);
- widget->repolishStyle(*QApplication::style());
- if (widget->isVisible())
- widget->update();
- break;
-
-#ifndef Q_WS_WINCE
- case WM_INPUTLANGCHANGE: {
- wchar_t info[7];
- if (!GetLocaleInfo(MAKELCID(lParam, SORT_DEFAULT), LOCALE_IDEFAULTANSICODEPAGE, info, 6)) {
- inputcharset = CP_ACP;
- } else {
- inputcharset = QString::fromWCharArray(info).toInt();
- }
- QKeyMapper::changeKeyboard();
- break;
- }
-#else
- case WM_COMMAND: {
- bool OkCommand = (LOWORD(wParam) == 0x1);
- bool CancelCommand = (LOWORD(wParam) == 0x2);
- if (OkCommand)
- QApplication::postEvent(widget, new QEvent(QEvent::OkRequest));
- if (CancelCommand)
- widget->showMinimized();
- else
-#ifndef QT_NO_MENUBAR
- QMenuBar::wceCommands(LOWORD(wParam));
-#endif
- result = true;
- }
- break;
- case WM_HELP:
- QApplication::postEvent(widget, new QEvent(QEvent::HelpRequest));
- result = true;
- break;
-#endif
-
- case WM_MOUSELEAVE:
- // We receive a mouse leave for curWin, meaning
- // the mouse was moved outside our widgets
- if (widget->internalWinId() == curWin) {
- bool dispatch = !widget->underMouse();
- // hasMouse is updated when dispatching enter/leave,
- // so test if it is actually up-to-date
- if (!dispatch) {
- QRect geom = widget->geometry();
- if (widget->parentWidget() && !widget->isWindow()) {
- QPoint gp = widget->parentWidget()->mapToGlobal(widget->pos());
- geom.setX(gp.x());
- geom.setY(gp.y());
- }
- QPoint cpos = QCursor::pos();
- dispatch = !geom.contains(cpos);
- if ( !dispatch && !QWidget::mouseGrabber()) {
- QWidget *hittest = QApplication::widgetAt(cpos);
- dispatch = !hittest || hittest->internalWinId() != curWin;
- }
- if (!dispatch) {
- HRGN hrgn = qt_tryCreateRegion(QRegion::Rectangle, 0,0,0,0);
- if (GetWindowRgn(curWin, hrgn) != ERROR) {
- QPoint lcpos = widget->mapFromGlobal(cpos);
- dispatch = !PtInRegion(hrgn, lcpos.x(), lcpos.y());
- }
- DeleteObject(hrgn);
- }
- }
- if (dispatch) {
- if (qt_last_mouse_receiver && !qt_last_mouse_receiver->internalWinId())
- QApplicationPrivate::dispatchEnterLeave(0, qt_last_mouse_receiver);
- else
- QApplicationPrivate::dispatchEnterLeave(0, QWidget::find((WId)curWin));
- curWin = 0;
- qt_last_mouse_receiver = 0;
- }
- }
- break;
-
- case WM_CANCELMODE:
- {
- // this goes through QMenuBar's event filter
- QEvent e(QEvent::ActivationChange);
- QApplication::sendEvent(qApp, &e);
- }
- break;
-
- case WM_IME_NOTIFY:
- // special handling for ime, only for widgets in a popup
- if (wParam == IMN_OPENCANDIDATE) {
- imeParentWnd = hwnd;
- if (QApplication::activePopupWidget()) {
- // temporarily disable the mouse grab to allow mouse input in
- // the ime candidate window. The actual handle is untouched
- if (autoCaptureWnd)
- ReleaseCapture();
- }
- } else if (wParam == IMN_CLOSECANDIDATE) {
- imeParentWnd = 0;
- if (QApplication::activePopupWidget()) {
- // undo the action above, when candidate window is closed
- if (autoCaptureWnd)
- SetCapture(autoCaptureWnd);
- }
- }
- result = false;
- break;
-#ifndef QT_NO_GESTURES
-#if !defined(Q_WS_WINCE) || defined(QT_WINCE_GESTURES)
- case WM_GESTURE: {
- GESTUREINFO gi;
- memset(&gi, 0, sizeof(GESTUREINFO));
- gi.cbSize = sizeof(GESTUREINFO);
-
- QApplicationPrivate *qAppPriv = QApplicationPrivate::instance();
- BOOL bResult = false;
- if (qAppPriv->GetGestureInfo)
- bResult = qAppPriv->GetGestureInfo((HANDLE)msg.lParam, &gi);
- if (bResult) {
- if (gi.dwID == GID_BEGIN) {
- // find the alien widget for the gesture position.
- // This might not be accurate as the position is the center
- // point of two fingers for multi-finger gestures.
- QPoint pt(gi.ptsLocation.x, gi.ptsLocation.y);
- QWidget *w = widget->childAt(widget->mapFromGlobal(pt));
- qAppPriv->gestureWidget = w ? w : widget;
- }
- if (qAppPriv->gestureWidget)
- static_cast<QETWidget*>(qAppPriv->gestureWidget)->translateGestureEvent(msg, gi);
- if (qAppPriv->CloseGestureInfoHandle)
- qAppPriv->CloseGestureInfoHandle((HANDLE)msg.lParam);
- if (gi.dwID == GID_END)
- qAppPriv->gestureWidget = 0;
- } else {
- DWORD dwErr = GetLastError();
- if (dwErr > 0)
- qWarning() << "translateGestureEvent: error = " << dwErr;
- }
- result = true;
- break;
- }
-#endif // !defined(Q_WS_WINCE) || defined(QT_WINCE_GESTURES)
-#endif // QT_NO_GESTURES
-#ifndef QT_NO_CURSOR
- case WM_SETCURSOR: {
- QCursor *ovr = QApplication::overrideCursor();
- if (ovr) {
- SetCursor(ovr->handle());
- RETURN(TRUE);
- }
- result = false;
- break;
- }
-#endif
- default:
- result = false; // event was not processed
- break;
- }
- }
-
- if (evt_type != QEvent::None) { // simple event
- QEvent e(evt_type);
- result = qt_sendSpontaneousEvent(widget, &e);
- }
-
- if (result)
- RETURN(false);
-
-do_default:
- RETURN(QWinInputContext::DefWindowProc(hwnd,message,wParam,lParam))
-}
-
-
-/*****************************************************************************
- Modal widgets; We have implemented our own modal widget mechanism
- to get total control.
- A modal widget without a parent becomes application-modal.
- A modal widget with a parent becomes modal to its parent and grandparents..
-
- QApplicationPrivate::enterModal()
- Enters modal state
- Arguments:
- QWidget *widget A modal widget
-
- QApplicationPrivate::leaveModal()
- Leaves modal state for a widget
- Arguments:
- QWidget *widget A modal widget
- *****************************************************************************/
-
-bool QApplicationPrivate::modalState()
-{
- return app_do_modal;
-}
-
-void QApplicationPrivate::enterModal_sys(QWidget *widget)
-{
- if (!qt_modal_stack)
- qt_modal_stack = new QWidgetList;
-
- releaseAutoCapture();
- ClipCursor(0);
- QWidget *leave = qt_last_mouse_receiver;
- if (!leave)
- leave = QWidget::find((WId)curWin);
- QApplicationPrivate::dispatchEnterLeave(0, leave);
- qt_modal_stack->insert(0, widget);
- app_do_modal = true;
- curWin = 0;
- qt_last_mouse_receiver = 0;
- qt_win_ignoreNextMouseReleaseEvent = false;
-}
-
-void QApplicationPrivate::leaveModal_sys(QWidget *widget)
-{
- if (qt_modal_stack && qt_modal_stack->removeAll(widget)) {
- if (qt_modal_stack->isEmpty()) {
- delete qt_modal_stack;
- qt_modal_stack = 0;
- QPoint p(QCursor::pos());
- app_do_modal = false; // necessary, we may get recursively into qt_try_modal below
- QWidget* w = QApplication::widgetAt(p.x(), p.y());
- QWidget *leave = qt_last_mouse_receiver;
- if (!leave)
- leave = QWidget::find((WId)curWin);
- if (QWidget *grabber = QWidget::mouseGrabber()) {
- w = grabber;
- if (leave == w)
- leave = 0;
- }
- QApplicationPrivate::dispatchEnterLeave(w, leave); // send synthetic enter event
- curWin = w ? w->effectiveWinId() : 0;
- qt_last_mouse_receiver = w;
- }
- qt_win_ignoreNextMouseReleaseEvent = true;
- }
- app_do_modal = qt_modal_stack != 0;
-}
-
-bool qt_try_modal(QWidget *widget, MSG *msg, int& ret)
-{
-#if defined(Q_OS_WINCE)
- Q_UNUSED(ret);
-#endif
- QWidget * top = 0;
-
- if (QApplicationPrivate::tryModalHelper(widget, &top))
- return true;
-
- int type = msg->message;
-
- bool block_event = false;
-#ifndef Q_WS_WINCE
- if (type != WM_NCHITTEST) {
-#endif
- if ((type >= WM_MOUSEFIRST && type <= WM_MOUSELAST) ||
- type == WM_MOUSEWHEEL || type == WM_MOUSEHWHEEL ||
- type == WM_MOUSELEAVE ||
- (type >= WM_KEYFIRST && type <= WM_KEYLAST)
-#ifndef Q_WS_WINCE
- || type == WM_NCMOUSEMOVE
-#endif
- ) {
- if (type == WM_MOUSEMOVE
-#ifndef Q_WS_WINCE
- || type == WM_NCMOUSEMOVE
-#endif
- ) {
-#ifndef QT_NO_CURSOR
- QCursor *c = qt_grab_cursor();
- if (!c)
- c = QApplication::overrideCursor();
- if (c) // application cursor defined
- SetCursor(c->handle());
- else
- SetCursor(QCursor(Qt::ArrowCursor).handle());
-#endif // QT_NO_CURSOR
- }
- block_event = true;
- } else if (type == WM_CLOSE) {
- block_event = true;
- }
-#ifndef Q_WS_WINCE
- else if (type == WM_MOUSEACTIVATE || type == WM_NCLBUTTONDOWN){
- if (!top->isActiveWindow()) {
- top->activateWindow();
- } else {
- QApplication::beep();
- }
- block_event = true;
- ret = MA_NOACTIVATEANDEAT;
- } else if (type == WM_SYSCOMMAND) {
- if (!(msg->wParam == SC_RESTORE && widget->isMinimized()))
- block_event = true;
- }
- }
-#endif
-
- return !block_event;
-}
-
-
-/*****************************************************************************
- Popup widget mechanism
-
- openPopup()
- Adds a widget to the list of popup widgets
- Arguments:
- QWidget *widget The popup widget to be added
-
- closePopup()
- Removes a widget from the list of popup widgets
- Arguments:
- QWidget *widget The popup widget to be removed
- *****************************************************************************/
-
-void QApplicationPrivate::openPopup(QWidget *popup)
-{
- if (!QApplicationPrivate::popupWidgets)
- QApplicationPrivate::popupWidgets = new QWidgetList;
- QApplicationPrivate::popupWidgets->append(popup);
- if (!popup->isEnabled())
- return;
-
- // close any opened 'ime candidate window'
- if (imeParentWnd)
- ::SendMessage(imeParentWnd, WM_IME_ENDCOMPOSITION, 0, 0);
-
- if (QApplicationPrivate::popupWidgets->count() == 1 && !qt_nograb()) {
- Q_ASSERT(popup->testAttribute(Qt::WA_WState_Created));
- setAutoCapture(popup->internalWinId()); // grab mouse/keyboard
- }
- // Popups are not focus-handled by the window system (the first
- // popup grabbed the keyboard), so we have to do that manually: A
- // new popup gets the focus
- if (popup->focusWidget()) {
- popup->focusWidget()->setFocus(Qt::PopupFocusReason);
- } else if (QApplicationPrivate::popupWidgets->count() == 1) { // this was the first popup
- if (QWidget *fw = QApplication::focusWidget()) {
- QFocusEvent e(QEvent::FocusOut, Qt::PopupFocusReason);
- QApplication::sendEvent(fw, &e);
- }
- }
-}
-
-void QApplicationPrivate::closePopup(QWidget *popup)
-{
- if (!QApplicationPrivate::popupWidgets)
- return;
- QApplicationPrivate::popupWidgets->removeAll(popup);
- POINT curPos;
- GetCursorPos(&curPos);
-
- // close any opened 'ime candidate window'
- if (imeParentWnd)
- ::SendMessage(imeParentWnd, WM_IME_ENDCOMPOSITION, 0, 0);
-
- if (QApplicationPrivate::popupWidgets->isEmpty()) { // this was the last popup
- delete QApplicationPrivate::popupWidgets;
- QApplicationPrivate::popupWidgets = 0;
- replayPopupMouseEvent = (!popup->geometry().contains(QPoint(curPos.x, curPos.y))
- && !popup->testAttribute(Qt::WA_NoMouseReplay));
- if (!popup->isEnabled())
- return;
- if (!qt_nograb()) // grabbing not disabled
- releaseAutoCapture();
- QWidget *fw = QApplicationPrivate::active_window ? QApplicationPrivate::active_window->focusWidget()
- : QApplication::focusWidget();
- if (fw) {
- if (fw != QApplication::focusWidget()) {
- fw->setFocus(Qt::PopupFocusReason);
- } else {
- QFocusEvent e(QEvent::FocusIn, Qt::PopupFocusReason);
- QApplication::sendEvent(fw, &e);
- }
- }
- } else {
- // Popups are not focus-handled by the window system (the
- // first popup grabbed the keyboard), so we have to do that
- // manually: A popup was closed, so the previous popup gets
- // the focus.
- QWidget* aw = QApplicationPrivate::popupWidgets->last();
- if (QApplicationPrivate::popupWidgets->count() == 1) {
- Q_ASSERT(aw->testAttribute(Qt::WA_WState_Created));
- setAutoCapture(aw->internalWinId());
- }
- if (QWidget *fw = aw->focusWidget())
- fw->setFocus(Qt::PopupFocusReason);
- }
-}
-
-
-
-
-/*****************************************************************************
- Event translation; translates Windows events to Qt events
- *****************************************************************************/
-
-//
-// Auto-capturing for mouse press and mouse release
-//
-
-static void setAutoCapture(HWND h)
-{
- if (autoCaptureWnd)
- releaseAutoCapture();
- autoCaptureWnd = h;
- SetCapture(h);
-}
-
-static void releaseAutoCapture()
-{
- if (autoCaptureWnd) {
- ReleaseCapture();
- autoCaptureWnd = 0;
- }
-}
-
-
-//
-// Mouse event translation
-//
-// Non-client mouse messages are not translated
-//
-
-static const ushort mouseTbl[] = {
- WM_MOUSEMOVE, QEvent::MouseMove, 0,
- WM_LBUTTONDOWN, QEvent::MouseButtonPress, Qt::LeftButton,
- WM_LBUTTONUP, QEvent::MouseButtonRelease, Qt::LeftButton,
- WM_LBUTTONDBLCLK, QEvent::MouseButtonDblClick, Qt::LeftButton,
- WM_RBUTTONDOWN, QEvent::MouseButtonPress, Qt::RightButton,
- WM_RBUTTONUP, QEvent::MouseButtonRelease, Qt::RightButton,
- WM_RBUTTONDBLCLK, QEvent::MouseButtonDblClick, Qt::RightButton,
- WM_MBUTTONDOWN, QEvent::MouseButtonPress, Qt::MidButton,
- WM_MBUTTONUP, QEvent::MouseButtonRelease, Qt::MidButton,
- WM_MBUTTONDBLCLK, QEvent::MouseButtonDblClick, Qt::MidButton,
- // use XButton1 for now, the real X button is decided later
- WM_XBUTTONDOWN, QEvent::MouseButtonPress, Qt::XButton1,
- WM_XBUTTONUP, QEvent::MouseButtonRelease, Qt::XButton1,
- WM_XBUTTONDBLCLK, QEvent::MouseButtonDblClick, Qt::XButton1,
-
-#ifndef Q_WS_WINCE
- WM_NCMOUSEMOVE, QEvent::NonClientAreaMouseMove, 0,
- WM_NCLBUTTONDOWN, QEvent::NonClientAreaMouseButtonPress, Qt::LeftButton,
- WM_NCLBUTTONUP, QEvent::NonClientAreaMouseButtonRelease, Qt::LeftButton,
- WM_NCLBUTTONDBLCLK, QEvent::NonClientAreaMouseButtonDblClick, Qt::LeftButton,
- WM_NCRBUTTONDOWN, QEvent::NonClientAreaMouseButtonPress, Qt::RightButton,
- WM_NCRBUTTONUP, QEvent::NonClientAreaMouseButtonRelease, Qt::RightButton,
- WM_NCRBUTTONDBLCLK, QEvent::NonClientAreaMouseButtonDblClick, Qt::RightButton,
- WM_NCMBUTTONDOWN, QEvent::NonClientAreaMouseButtonPress, Qt::MidButton,
- WM_NCMBUTTONUP, QEvent::NonClientAreaMouseButtonRelease, Qt::MidButton,
- WM_NCMBUTTONDBLCLK, QEvent::NonClientAreaMouseButtonDblClick, Qt::MidButton,
-#endif
-
- 0, 0, 0
-};
-
-static int translateButtonState(int s, int type, int button)
-{
- Q_UNUSED(type);
- Q_UNUSED(button);
- int bst = 0;
- if (s & MK_LBUTTON)
- bst |= Qt::LeftButton;
- if (s & MK_MBUTTON)
- bst |= Qt::MidButton;
- if (s & MK_RBUTTON)
- bst |= Qt::RightButton;
- if (s & MK_SHIFT)
- bst |= Qt::ShiftModifier;
- if (s & MK_CONTROL)
- bst |= Qt::ControlModifier;
-
- if (s & MK_XBUTTON1)
- bst |= Qt::XButton1;
- if (s & MK_XBUTTON2)
- bst |= Qt::XButton2;
-
- if (GetKeyState(VK_MENU) < 0)
- bst |= Qt::AltModifier;
-
- if ((GetKeyState(VK_LWIN) < 0) ||
- (GetKeyState(VK_RWIN) < 0))
- bst |= Qt::MetaModifier;
-
- return bst;
-}
-
-void qt_win_eatMouseMove()
-{
- // after closing a windows dialog with a double click (i.e. open a file)
- // the message queue still contains a dubious WM_MOUSEMOVE message where
- // the left button is reported to be down (wParam != 0).
- // remove all those messages (usually 1) and post the last one with a
- // reset button state
-
- MSG msg = {0, 0, 0, 0, 0, {0, 0} };
- while (PeekMessage(&msg, 0, WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE))
- ;
- if (msg.message == WM_MOUSEMOVE)
- PostMessage(msg.hwnd, msg.message, 0, msg.lParam);
-}
-
-// In DnD, the mouse release event never appears, so the
-// mouse button state machine must be manually reset
-void QApplication::winMouseButtonUp()
-{
- qt_button_down = 0;
- releaseAutoCapture();
-}
-
-void QETWidget::repolishStyle(QStyle &)
-{
- QEvent e(QEvent::StyleChange);
- QApplication::sendEvent(this, &e);
-}
-
-bool QETWidget::translateMouseEvent(const MSG &msg)
-{
- if (!isWindow() && testAttribute(Qt::WA_NativeWindow))
- Q_ASSERT(internalWinId());
-
- static QPoint pos;
- static POINT gpos={-1,-1};
- QEvent::Type type; // event parameters
- int button;
- int state;
- int i;
-
- if (sm_blockUserInput) //block user interaction during session management
- return true;
-
- // Compress mouse move events
- if (msg.message == WM_MOUSEMOVE) {
- MSG mouseMsg;
- while (PeekMessage(&mouseMsg, msg.hwnd, WM_MOUSEFIRST,
- WM_MOUSELAST, PM_NOREMOVE)) {
- if (mouseMsg.message == WM_MOUSEMOVE) {
-#define PEEKMESSAGE_IS_BROKEN 1
-#ifdef PEEKMESSAGE_IS_BROKEN
- // Since the Windows PeekMessage() function doesn't
- // correctly return the wParam for WM_MOUSEMOVE events
- // if there is a key release event in the queue
- // _before_ the mouse event, we have to also consider
- // key release events (kls 2003-05-13):
- MSG keyMsg;
- bool done = false;
- while (PeekMessage(&keyMsg, 0, WM_KEYFIRST, WM_KEYLAST,
- PM_NOREMOVE)) {
- if (keyMsg.time < mouseMsg.time) {
- if ((keyMsg.lParam & 0xC0000000) == 0x40000000) {
- PeekMessage(&keyMsg, 0, keyMsg.message,
- keyMsg.message, PM_REMOVE);
- } else {
- done = true;
- break;
- }
- } else {
- break; // no key event before the WM_MOUSEMOVE event
- }
- }
- if (done)
- break;
-#else
- // Actually the following 'if' should work instead of
- // the above key event checking, but apparently
- // PeekMessage() is broken :-(
- if (mouseMsg.wParam != msg.wParam)
- break; // leave the message in the queue because
- // the key state has changed
-#endif
- MSG *msgPtr = (MSG *)(&msg);
- // Update the passed in MSG structure with the
- // most recent one.
- msgPtr->lParam = mouseMsg.lParam;
- msgPtr->wParam = mouseMsg.wParam;
- // Extract the x,y coordinates from the lParam as we do in the WndProc
- msgPtr->pt.x = GET_X_LPARAM(mouseMsg.lParam);
- msgPtr->pt.y = GET_Y_LPARAM(mouseMsg.lParam);
- ClientToScreen(msg.hwnd, &(msgPtr->pt));
- // Remove the mouse move message
- PeekMessage(&mouseMsg, msg.hwnd, WM_MOUSEMOVE,
- WM_MOUSEMOVE, PM_REMOVE);
- } else {
- break; // there was no more WM_MOUSEMOVE event
- }
- }
- }
-
- for (i=0; (UINT)mouseTbl[i] != msg.message && mouseTbl[i]; i += 3)
- ;
- if (!mouseTbl[i])
- return false;
- type = (QEvent::Type)mouseTbl[++i]; // event type
- button = mouseTbl[++i]; // which button
- if (button == Qt::XButton1) {
- switch(GET_XBUTTON_WPARAM(msg.wParam)) {
- case XBUTTON1:
- button = Qt::XButton1;
- break;
- case XBUTTON2:
- button = Qt::XButton2;
- break;
- }
- }
-#ifndef Q_OS_WINCE
- static bool trackMouseEventLookup = false;
- typedef BOOL (WINAPI *PtrTrackMouseEvent)(LPTRACKMOUSEEVENT);
- static PtrTrackMouseEvent ptrTrackMouseEvent = 0;
-#endif
- state = translateButtonState(msg.wParam, type, button); // button state
- const QPoint widgetPos = mapFromGlobal(QPoint(msg.pt.x, msg.pt.y));
- QWidget *alienWidget = !internalWinId() ? this : childAt(widgetPos);
- if (alienWidget && alienWidget->internalWinId())
- alienWidget = 0;
-
- if (type == QEvent::MouseMove || type == QEvent::NonClientAreaMouseMove
- || type == QEvent::TabletMove) {
-
- if (!(state & Qt::MouseButtonMask))
- qt_button_down = 0;
-#ifndef QT_NO_CURSOR
- QCursor *c = qt_grab_cursor();
- if (!c)
- c = QApplication::overrideCursor();
- if (c) // application cursor defined
- SetCursor(c->handle());
- else if (type != QEvent::NonClientAreaMouseMove && !qt_button_down) {
- // use widget cursor if widget is enabled
- QWidget *w = alienWidget ? alienWidget : this;
- while (!w->isWindow() && !w->isEnabled())
- w = w->parentWidget();
- SetCursor(w->cursor().handle());
- }
-#endif // QT_NO_CURSOR
-
- HWND id = effectiveWinId();
- QWidget *mouseGrabber = QWidget::mouseGrabber();
- QWidget *activePopupWidget = QApplication::activePopupWidget();
- if (mouseGrabber) {
- if (!activePopupWidget || (activePopupWidget == this && !rect().contains(widgetPos)))
- id = mouseGrabber->effectiveWinId();
- } else if (type == QEvent::NonClientAreaMouseMove) {
- id = 0;
- }
-
- if (curWin != id) { // new current window
- if (id == 0) {
- QWidget *leave = qt_last_mouse_receiver;
- if (!leave)
- leave = QWidget::find(curWin);
- QApplicationPrivate::dispatchEnterLeave(0, leave);
- qt_last_mouse_receiver = 0;
- curWin = 0;
- } else {
- QWidget *leave = 0;
- if (curWin && qt_last_mouse_receiver)
- leave = qt_last_mouse_receiver;
- else
- leave = QWidget::find(curWin);
- QWidget *enter = alienWidget ? alienWidget : this;
- if (mouseGrabber && activePopupWidget) {
- if (leave != mouseGrabber)
- enter = mouseGrabber;
- else
- enter = activePopupWidget == this ? this : mouseGrabber;
- }
- QApplicationPrivate::dispatchEnterLeave(enter, leave);
- qt_last_mouse_receiver = enter;
- curWin = enter ? enter->effectiveWinId() : 0;
- }
-#ifndef Q_OS_WINCE
-
- if (curWin != 0) {
- if (!trackMouseEventLookup) {
- trackMouseEventLookup = true;
- ptrTrackMouseEvent = (PtrTrackMouseEvent)QSystemLibrary::resolve(QLatin1String("comctl32"), "_TrackMouseEvent");
- }
- if (ptrTrackMouseEvent && !qApp->d_func()->inPopupMode()) {
- // We always have to set the tracking, since
- // Windows detects more leaves than we do..
- TRACKMOUSEEVENT tme;
- tme.cbSize = sizeof(TRACKMOUSEEVENT);
- tme.dwFlags = 0x00000002; // TME_LEAVE
- tme.hwndTrack = curWin; // Track on window receiving msgs
- tme.dwHoverTime = (DWORD)-1; // HOVER_DEFAULT
- ptrTrackMouseEvent(&tme);
- }
- }
-#endif // Q_OS_WINCE
- }
-
- POINT curPos = msg.pt;
- if (curPos.x == gpos.x && curPos.y == gpos.y)
- return true; // same global position
- gpos = curPos;
-
- Q_ASSERT(testAttribute(Qt::WA_WState_Created));
- ScreenToClient(internalWinId(), &curPos);
-
- pos.rx() = curPos.x;
- pos.ry() = curPos.y;
- pos = d_func()->mapFromWS(pos);
- } else {
- gpos = msg.pt;
- pos = mapFromGlobal(QPoint(gpos.x, gpos.y));
-
- // mouse button pressed
- if (!qt_button_down && (type == QEvent::MouseButtonPress || type == QEvent::MouseButtonDblClick)) {
- QWidget *tlw = window();
- if (QWidget *child = tlw->childAt(mapTo(tlw, pos)))
- qt_button_down = child;
- else
- qt_button_down = this;
- }
- }
-
- bool res = false;
-
- bool nonClientAreaEvent = type >= QEvent::NonClientAreaMouseMove
- && type <= QEvent::NonClientAreaMouseButtonDblClick;
-
- if (qApp->d_func()->inPopupMode()) { // in popup mode
-
- if (nonClientAreaEvent)
- return false;
-
- replayPopupMouseEvent = false;
- QWidget* activePopupWidget = QApplication::activePopupWidget();
- QWidget *target = activePopupWidget;
- const QPoint globalPos(gpos.x, gpos.y);
-
- if (target != this) {
- if ((windowType() == Qt::Popup) && rect().contains(pos) && 0)
- target = this;
- else // send to last popup
- pos = target->mapFromGlobal(globalPos);
- }
- QWidget *popupChild = target->childAt(pos);
- bool releaseAfter = false;
- switch (type) {
- case QEvent::MouseButtonPress:
- case QEvent::MouseButtonDblClick:
- popupButtonFocus = popupChild;
- break;
- case QEvent::MouseButtonRelease:
- case QEvent::TabletRelease:
-
- releaseAfter = true;
- break;
- default:
- break; // nothing for mouse move
- }
-
- if (target->isEnabled()) {
- if (popupButtonFocus) {
- target = popupButtonFocus;
- } else if (popupChild) {
- target = popupChild;
- }
-
- pos = target->mapFromGlobal(globalPos);
- QMouseEvent e(type, pos, globalPos,
- Qt::MouseButton(button),
- Qt::MouseButtons(state & Qt::MouseButtonMask),
- Qt::KeyboardModifiers(state & Qt::KeyboardModifierMask));
- res = QApplicationPrivate::sendMouseEvent(target, &e, alienWidget, this, &qt_button_down,
- qt_last_mouse_receiver);
- res = res && e.isAccepted();
- } else {
- // close disabled popups when a mouse button is pressed or released
- switch (type) {
- case QEvent::MouseButtonPress:
- case QEvent::MouseButtonDblClick:
- case QEvent::MouseButtonRelease:
- target->close();
- break;
- default:
- break;
- }
- }
-
- if (releaseAfter) {
- popupButtonFocus = 0;
- qt_button_down = 0;
- }
-
-#ifndef Q_OS_WINCE
- if (type == QEvent::MouseButtonPress
- && QApplication::activePopupWidget() != activePopupWidget
- && ptrTrackMouseEvent
- && curWin) {
- // Since curWin is already the window we clicked on,
- // we have to setup the mouse tracking here.
- TRACKMOUSEEVENT tme;
- tme.cbSize = sizeof(TRACKMOUSEEVENT);
- tme.dwFlags = 0x00000002; // TME_LEAVE
- tme.hwndTrack = curWin; // Track on window receiving msgs
- tme.dwHoverTime = (DWORD)-1; // HOVER_DEFAULT
- ptrTrackMouseEvent(&tme);
- }
-#endif
- if (type == QEvent::MouseButtonPress
- && QApplication::activePopupWidget() != activePopupWidget
- && replayPopupMouseEvent) {
- // the popup disappeared. Replay the event
- QWidget* w = QApplication::widgetAt(gpos.x, gpos.y);
- if (w && !QApplicationPrivate::isBlockedByModal(w)) {
- Q_ASSERT(w->testAttribute(Qt::WA_WState_Created));
- HWND hwndTarget = w->effectiveWinId();
- if (QWidget::mouseGrabber() == 0)
- setAutoCapture(hwndTarget);
- if (!w->isActiveWindow())
- w->activateWindow();
- POINT widgetpt = gpos;
- ScreenToClient(hwndTarget, &widgetpt);
- LPARAM lParam = MAKELPARAM(widgetpt.x, widgetpt.y);
- PostMessage(hwndTarget, msg.message, msg.wParam, lParam);
- }
- } else if (type == QEvent::MouseButtonRelease && button == Qt::RightButton
- && QApplication::activePopupWidget() == activePopupWidget) {
- // popup still alive and received right-button-release
-#if !defined(QT_NO_CONTEXTMENU)
- QContextMenuEvent e2(QContextMenuEvent::Mouse, pos, globalPos,
- qt_win_getKeyboardModifiers());
- bool res2 = QApplication::sendSpontaneousEvent( target, &e2 );
- if (!res) // RMB not accepted
- res = res2 && e2.isAccepted();
-#endif
- }
- } else { // not popup mode
- int bs = state & Qt::MouseButtonMask;
- if ((type == QEvent::MouseButtonPress ||
- type == QEvent::MouseButtonDblClick) && bs == button) {
- Q_ASSERT(testAttribute(Qt::WA_WState_Created));
- if (QWidget::mouseGrabber() == 0)
- setAutoCapture(internalWinId());
- } else if (type == QEvent::MouseButtonRelease && bs == 0) {
- if (QWidget::mouseGrabber() == 0)
- releaseAutoCapture();
- }
-
- const QPoint globalPos(gpos.x,gpos.y);
- QWidget *widget = QApplicationPrivate::pickMouseReceiver(this, globalPos, pos, type,
- Qt::MouseButtons(bs),
- qt_button_down, alienWidget);
- if (!widget)
- return false; // don't send event
-
- QMouseEvent e(type, pos, globalPos, Qt::MouseButton(button),
- Qt::MouseButtons(state & Qt::MouseButtonMask),
- Qt::KeyboardModifiers(state & Qt::KeyboardModifierMask));
-
- res = QApplicationPrivate::sendMouseEvent(widget, &e, alienWidget, this, &qt_button_down,
- qt_last_mouse_receiver);
-
- // non client area events are only informational, you cannot "handle" them
- res = res && e.isAccepted() && !nonClientAreaEvent;
-#if !defined(QT_NO_CONTEXTMENU)
- if (type == QEvent::MouseButtonRelease && button == Qt::RightButton) {
- QContextMenuEvent e2(QContextMenuEvent::Mouse, pos, globalPos,
- qt_win_getKeyboardModifiers());
- bool res2 = QApplication::sendSpontaneousEvent(widget, &e2);
- if (!res)
- res = res2 && e2.isAccepted();
- }
-#endif
-
- if (type != QEvent::MouseMove)
- pos.rx() = pos.ry() = -9999; // init for move compression
- }
- return res;
-}
-
-bool QETWidget::translateWheelEvent(const MSG &msg)
-{
- int state = 0;
-
- if (sm_blockUserInput) // block user interaction during session management
- return true;
-
- state = translateButtonState(GET_KEYSTATE_WPARAM(msg.wParam), 0, 0);
-
- int delta;
- if (msg.message == WM_MOUSEWHEEL || msg.message == WM_MOUSEHWHEEL)
- delta = (short) HIWORD (msg.wParam);
- else
- delta = (int) msg.wParam;
-
- Qt::Orientation orient = (msg.message == WM_MOUSEHWHEEL || state&Qt::AltModifier
-#if 0
- // disabled for now - Trenton's one-wheel mouse makes trouble...
- // "delta" for usual wheels is +-120. +-240 seems to indicate
- // the second wheel see more recent MSDN for WM_MOUSEWHEEL
-
- ( // <- parantheses added to make update happy, remove if the
- // #if 0 is removed
- || delta == 240 || delta == -240)?Qt::Horizontal:Vertical;
- if (delta == 240 || delta == -240)
- delta /= 2;
-#endif
- ) ? Qt::Horizontal : Qt::Vertical;
-
- // according to the MSDN documentation on WM_MOUSEHWHEEL:
- // a positive value indicates that the wheel was rotated to the right;
- // a negative value indicates that the wheel was rotated to the left.
- // Qt defines this value as the exact opposite, so we have to flip the value!
- if (msg.message == WM_MOUSEHWHEEL)
- delta = -delta;
-
- QPoint globalPos;
-
- globalPos.rx() = (short)LOWORD (msg.lParam);
- globalPos.ry() = (short)HIWORD (msg.lParam);
-
-
- // if there is a widget under the mouse and it is not shadowed
- // by modality, we send the event to it first
- int ret = 0;
- QWidget* w = QApplication::widgetAt(globalPos);
- if (!w || !qt_try_modal(w, (MSG*)&msg, ret)) {
- //synaptics touchpad shows its own widget at this position
- //so widgetAt() will fail with that HWND, try child of this widget
- w = this->childAt(this->mapFromGlobal(globalPos));
- if (!w)
- w = this;
- }
-
- // send the event to the widget or its ancestors
- {
- QWidget* popup = QApplication::activePopupWidget();
- if (popup && w->window() != popup)
- popup->close();
-#ifndef QT_NO_WHEELEVENT
- QWheelEvent e(w->mapFromGlobal(globalPos), globalPos, delta,
- Qt::MouseButtons(state & Qt::MouseButtonMask),
- Qt::KeyboardModifier(state & Qt::KeyboardModifierMask), orient);
-
- if (QApplication::sendSpontaneousEvent(w, &e))
-#else
- Q_UNUSED(orient);
-#endif //QT_NO_WHEELEVENT
- return true;
- }
-
- // send the event to the widget that has the focus or its ancestors, if different
- if (w != QApplication::focusWidget() && (w = QApplication::focusWidget())) {
- QWidget* popup = QApplication::activePopupWidget();
- if (popup && w->window() != popup)
- popup->close();
-#ifndef QT_NO_WHEELEVENT
- QWheelEvent e(w->mapFromGlobal(globalPos), globalPos, delta,
- Qt::MouseButtons(state & Qt::MouseButtonMask),
- Qt::KeyboardModifier(state & Qt::KeyboardModifierMask), orient);
- if (QApplication::sendSpontaneousEvent(w, &e))
-#endif //QT_NO_WHEELEVENT
- return true;
- }
- return false;
-}
-
-
-//
-// Windows Wintab to QTabletEvent translation
-//
-
-// the following is adapted from the wintab syspress example (public domain)
-/* -------------------------------------------------------------------------- */
-// Initialize the "static" information of a cursor device (pen, airbrush, etc).
-// The QTabletDeviceData is initialized with the data that do not change in time
-// (number of button, type of device, etc) but do not initialize the variable data
-// (e.g.: pen or eraser)
-#ifndef QT_NO_TABLETEVENT
-
-static void tabletInit(const quint64 uniqueId, const UINT csr_type, HCTX hTab)
-{
- Q_ASSERT(ptrWTInfo);
- Q_ASSERT(ptrWTGet);
-
- Q_ASSERT(!tCursorInfo()->contains(uniqueId));
-
- /* browse WinTab's many info items to discover pressure handling. */
- AXIS np;
- LOGCONTEXT lc;
-
- /* get the current context for its device variable. */
- ptrWTGet(hTab, &lc);
-
- /* get the size of the pressure axis. */
- QTabletDeviceData tdd;
- tdd.llId = uniqueId;
-
- ptrWTInfo(WTI_DEVICES + lc.lcDevice, DVC_NPRESSURE, &np);
- tdd.minPressure = int(np.axMin);
- tdd.maxPressure = int(np.axMax);
-
- ptrWTInfo(WTI_DEVICES + lc.lcDevice, DVC_TPRESSURE, &np);
- tdd.minTanPressure = int(np.axMin);
- tdd.maxTanPressure = int(np.axMax);
-
- LOGCONTEXT lcMine;
-
- /* get default region */
- ptrWTInfo(WTI_DEFCONTEXT, 0, &lcMine);
-
- tdd.minX = 0;
- tdd.maxX = int(lcMine.lcInExtX) - int(lcMine.lcInOrgX);
-
- tdd.minY = 0;
- tdd.maxY = int(lcMine.lcInExtY) - int(lcMine.lcInOrgY);
-
- tdd.minZ = 0;
- tdd.maxZ = int(lcMine.lcInExtZ) - int(lcMine.lcInOrgZ);
-
- const uint cursorTypeBitMask = 0x0F06; // bitmask to find the specific cursor type (see Wacom FAQ)
- if (((csr_type & 0x0006) == 0x0002) && ((csr_type & cursorTypeBitMask) != 0x0902)) {
- tdd.currentDevice = QTabletEvent::Stylus;
- } else {
- switch (csr_type & cursorTypeBitMask) {
- case 0x0802:
- tdd.currentDevice = QTabletEvent::Stylus;
- break;
- case 0x0902:
- tdd.currentDevice = QTabletEvent::Airbrush;
- break;
- case 0x0004:
- tdd.currentDevice = QTabletEvent::FourDMouse;
- break;
- case 0x0006:
- tdd.currentDevice = QTabletEvent::Puck;
- break;
- case 0x0804:
- tdd.currentDevice = QTabletEvent::RotationStylus;
- break;
- default:
- tdd.currentDevice = QTabletEvent::NoDevice;
- }
- }
- tCursorInfo()->insert(uniqueId, tdd);
-}
-#endif // QT_NO_TABLETEVENT
-
-// Update the "dynamic" information of a cursor device (pen, airbrush, etc).
-// The dynamic information is the information of QTabletDeviceData that can change
-// in time (eraser or pen if a device is turned around).
-#ifndef QT_NO_TABLETEVENT
-
-static void tabletUpdateCursor(QTabletDeviceData &tdd, const UINT currentCursor)
-{
- switch (currentCursor % 3) { // %3 for dual track
- case 0:
- tdd.currentPointerType = QTabletEvent::Cursor;
- break;
- case 1:
- tdd.currentPointerType = QTabletEvent::Pen;
- break;
- case 2:
- tdd.currentPointerType = QTabletEvent::Eraser;
- break;
- default:
- tdd.currentPointerType = QTabletEvent::UnknownPointer;
- }
-}
-#endif // QT_NO_TABLETEVENT
-
-bool QETWidget::translateTabletEvent(const MSG &msg, PACKET *localPacketBuf,
- int numPackets)
-{
- Q_UNUSED(msg);
- POINT ptNew;
- static DWORD btnNew, btnOld, btnChange;
- qreal prsNew;
- ORIENTATION ort;
- static bool button_pressed = false;
- int i,
- tiltX,
- tiltY;
- bool sendEvent = false;
- QEvent::Type t;
- int z = 0;
- qreal rotation = 0.0;
- qreal tangentialPressure;
-
- // the most common event that we get...
- t = QEvent::TabletMove;
- for (i = 0; i < numPackets; i++) {
- // get the unique ID of the device...
- btnOld = btnNew;
- btnNew = localPacketBuf[i].pkButtons;
- btnChange = btnOld ^ btnNew;
-
- if (btnNew & btnChange) {
- button_pressed = true;
- t = QEvent::TabletPress;
- }
- ptNew.x = UINT(localPacketBuf[i].pkX);
- ptNew.y = UINT(localPacketBuf[i].pkY);
-#ifndef QT_NO_TABLETEVENT
- z = (currentTabletPointer.currentDevice == QTabletEvent::FourDMouse) ? UINT(localPacketBuf[i].pkZ) : 0;
-#else
- Q_UNUSED(z);
-#endif // QT_NO_TABLETEVENT
- prsNew = 0.0;
- QRect desktopArea = QApplication::desktop()->geometry();
- QPointF hiResGlobal = currentTabletPointer.scaleCoord(ptNew.x, ptNew.y, desktopArea.left(),
- desktopArea.width(), desktopArea.top(),
- desktopArea.height());
-
- if (btnNew) {
-#ifndef QT_NO_TABLETEVENT
- if (currentTabletPointer.currentPointerType == QTabletEvent::Pen || currentTabletPointer.currentPointerType == QTabletEvent::Eraser)
- prsNew = localPacketBuf[i].pkNormalPressure
- / qreal(currentTabletPointer.maxPressure
- - currentTabletPointer.minPressure);
- else
-#endif // QT_NO_TABLETEVENT
- prsNew = 0;
- } else if (button_pressed) {
- // One button press, should only give one button release
- t = QEvent::TabletRelease;
- button_pressed = false;
- }
- QPoint globalPos(qRound(hiResGlobal.x()), qRound(hiResGlobal.y()));
-
- if (t == QEvent::TabletPress)
- {
- qt_button_down = QApplication::widgetAt(globalPos);
- }
-
- // make sure the tablet event get's sent to the proper widget...
- QWidget *w = 0;
-
- if (qt_button_down)
- w = qt_button_down; // Pass it to the thing that's grabbed it.
- else
- w = QApplication::widgetAt(globalPos);
-
- if (!w)
- w = this;
-
- if (t == QEvent::TabletRelease)
- {
- if (qt_win_ignoreNextMouseReleaseEvent) {
- qt_win_ignoreNextMouseReleaseEvent = false;
- if (qt_button_down && qt_button_down->internalWinId() == autoCaptureWnd) {
- releaseAutoCapture();
- qt_button_down = 0;
- }
- }
-
- }
-
- QPoint localPos = w->mapFromGlobal(globalPos);
-#ifndef QT_NO_TABLETEVENT
- if (currentTabletPointer.currentDevice == QTabletEvent::Airbrush) {
- tangentialPressure = localPacketBuf[i].pkTangentPressure
- / qreal(currentTabletPointer.maxTanPressure
- - currentTabletPointer.minTanPressure);
- } else {
- tangentialPressure = 0.0;
- }
-#else
- tangentialPressure = 0.0;
-#endif // QT_NO_TABLETEVENT
-
- if (!qt_tablet_tilt_support) {
- tiltX = tiltY = 0;
- rotation = 0.0;
- } else {
- ort = localPacketBuf[i].pkOrientation;
- // convert from azimuth and altitude to x tilt and y tilt
- // what follows is the optimized version. Here are the equations
- // I used to get to this point (in case things change :)
- // X = sin(azimuth) * cos(altitude)
- // Y = cos(azimuth) * cos(altitude)
- // Z = sin(altitude)
- // X Tilt = arctan(X / Z)
- // Y Tilt = arctan(Y / Z)
- double radAzim = (ort.orAzimuth / 10) * (Q_PI / 180);
- //double radAlt = abs(ort.orAltitude / 10) * (Q_PI / 180);
- double tanAlt = tan((abs(ort.orAltitude / 10)) * (Q_PI / 180));
-
- double degX = atan(sin(radAzim) / tanAlt);
- double degY = atan(cos(radAzim) / tanAlt);
- tiltX = int(degX * (180 / Q_PI));
- tiltY = int(-degY * (180 / Q_PI));
- rotation = ort.orTwist;
- }
-#ifndef QT_NO_TABLETEVENT
- QTabletEvent e(t, localPos, globalPos, hiResGlobal, currentTabletPointer.currentDevice,
- currentTabletPointer.currentPointerType, prsNew, tiltX, tiltY,
- tangentialPressure, rotation, z, QApplication::keyboardModifiers(), currentTabletPointer.llId);
- sendEvent = QApplication::sendSpontaneousEvent(w, &e);
-#endif // QT_NO_TABLETEVENT
- }
- return sendEvent;
-}
-
-extern bool qt_is_gui_used;
-
-
-#ifndef QT_NO_TABLETEVENT
-
-static void initWinTabFunctions()
-{
-#if defined(Q_OS_WINCE)
- return;
-#else
- if (!qt_is_gui_used)
- return;
-
- QSystemLibrary library(QLatin1String("wintab32"));
- ptrWTInfo = (PtrWTInfo)library.resolve("WTInfoW");
- ptrWTGet = (PtrWTGet)library.resolve("WTGetW");
- ptrWTEnable = (PtrWTEnable)library.resolve("WTEnable");
- ptrWTOverlap = (PtrWTEnable)library.resolve("WTOverlap");
- ptrWTPacketsGet = (PtrWTPacketsGet)library.resolve("WTPacketsGet");
-#endif // Q_OS_WINCE
-}
-#endif // QT_NO_TABLETEVENT
-
-
-//
-// Paint event translation
-//
-bool QETWidget::translatePaintEvent(const MSG &msg)
-{
- if (!isWindow() && testAttribute(Qt::WA_NativeWindow))
- Q_ASSERT(internalWinId());
-
- Q_ASSERT(testAttribute(Qt::WA_WState_Created));
- if (!GetUpdateRect(internalWinId(), 0, FALSE)) { // The update bounding rect is invalid
- d_func()->hd = 0;
- setAttribute(Qt::WA_PendingUpdate, false);
- return false;
- }
-
- if (msg.message == WM_ERASEBKGND)
- return true;
-
- setAttribute(Qt::WA_PendingUpdate, false);
-
- if (d_func()->isGLWidget) {
- if (d_func()->usesDoubleBufferedGLContext)
- InvalidateRect(internalWinId(), 0, false);
- } else {
- const QRegion dirtyInBackingStore(qt_dirtyRegion(this));
- // Make sure the invalidated region contains the region we're about to repaint.
- // BeginPaint will set the clip to the invalidated region and it is impossible
- // to enlarge it afterwards (only shrink it). Using GetDCEx is not suffient
- // as it may return an invalid context (especially on Windows Vista).
- if (!dirtyInBackingStore.isEmpty())
- InvalidateRgn(internalWinId(), dirtyInBackingStore.handle(), false);
- }
- PAINTSTRUCT ps;
- d_func()->hd = BeginPaint(internalWinId(), &ps);
-
- const QRect updateRect(QPoint(ps.rcPaint.left, ps.rcPaint.top),
- QPoint(ps.rcPaint.right, ps.rcPaint.bottom));
-
- // Mapping region from system to qt (32 bit) coordinate system.
- d_func()->syncBackingStore(updateRect.translated(data->wrect.topLeft()));
-
- d_func()->hd = 0;
- EndPaint(internalWinId(), &ps);
-
- return true;
-}
-
-//
-// Window move and resize (configure) events
-//
-
-bool QETWidget::translateConfigEvent(const MSG &msg)
-{
- if (!testAttribute(Qt::WA_WState_Created)) // in QWidget::create()
- return true;
- if (testAttribute(Qt::WA_WState_ConfigPending))
- return true;
- if (testAttribute(Qt::WA_DontShowOnScreen))
- return true;
- if (!isWindow())
- return true;
- setAttribute(Qt::WA_WState_ConfigPending); // set config flag
- QRect cr = geometry();
- if (msg.message == WM_SIZE) { // resize event
- WORD a = LOWORD(msg.lParam);
- WORD b = HIWORD(msg.lParam);
- QSize oldSize = size();
- QSize newSize(a, b);
-#ifdef Q_WS_WINCE_WM
- if (isFullScreen() && (oldSize.width() == newSize.height()) && (oldSize.height() == newSize.width()))
- qt_wince_hide_taskbar(internalWinId());
-#endif
- cr.setSize(newSize);
- if (msg.wParam != SIZE_MINIMIZED)
- data->crect = cr;
- if (isWindow()) { // update title/icon text
- d_func()->createTLExtra();
- // Capture SIZE_MINIMIZED without preceding WM_SYSCOMMAND
- // (like Windows+M)
- if (msg.wParam == SIZE_MINIMIZED && !isMinimized()) {
-#ifndef Q_WS_WINCE
- const QString title = windowIconText();
- if (!title.isEmpty())
- d_func()->setWindowTitle_helper(title);
-#endif
- data->window_state |= Qt::WindowMinimized;
- if (isVisible()) {
- QHideEvent e;
- QApplication::sendSpontaneousEvent(this, &e);
- hideChildren(true);
- }
- } else if (msg.wParam != SIZE_MINIMIZED) {
- bool window_state_changed = false;
- Qt::WindowStates oldstate = Qt::WindowStates(dataPtr()->window_state);
- if (isMinimized()) {
-#ifndef Q_WS_WINCE
- const QString title = windowTitle();
- if (!title.isEmpty())
- d_func()->setWindowTitle_helper(title);
-#endif
- data->window_state &= ~Qt::WindowMinimized;
- showChildren(true);
- QShowEvent e;
- QApplication::sendSpontaneousEvent(this, &e);
- // Capture SIZE_MAXIMIZED and SIZE_RESTORED without preceding WM_SYSCOMMAND
- // (Aero Snap on Win7)
- } else if (msg.wParam == SIZE_MAXIMIZED && !isMaximized()) {
- data->window_state |= Qt::WindowMaximized;
- window_state_changed = true;
- } else if (msg.wParam == SIZE_RESTORED && isMaximized()) {
- data->window_state &= ~(Qt::WindowMaximized);
- window_state_changed = true;
- }
- if (window_state_changed) {
- QWindowStateChangeEvent e(oldstate);
- QApplication::sendSpontaneousEvent(this, &e);
- }
- }
- }
- if (msg.wParam != SIZE_MINIMIZED && oldSize != newSize) {
- if (isVisible()) {
- QTLWExtra *tlwExtra = maybeTopData();
- static bool slowResize = qgetenv("QT_SLOW_TOPLEVEL_RESIZE").toInt();
- const bool hasStaticContents = tlwExtra && tlwExtra->backingStore
- && tlwExtra->backingStore->hasStaticContents();
- // If we have a backing store with static contents, we have to disable the top-level
- // resize optimization in order to get invalidated regions for resized widgets.
- // The optimization discards all invalidateBuffer() calls since we're going to
- // repaint everything anyways, but that's not the case with static contents.
- if (!slowResize && tlwExtra && !hasStaticContents)
- tlwExtra->inTopLevelResize = true;
- QResizeEvent e(newSize, oldSize);
- QApplication::sendSpontaneousEvent(this, &e);
- if (d_func()->paintOnScreen()) {
- QRegion updateRegion(rect());
- if (testAttribute(Qt::WA_StaticContents))
- updateRegion -= QRect(0, 0, oldSize.width(), oldSize.height());
- d_func()->syncBackingStore(updateRegion);
- } else {
- d_func()->syncBackingStore();
- }
- if (!slowResize && tlwExtra)
- tlwExtra->inTopLevelResize = false;
- } else {
- QResizeEvent *e = new QResizeEvent(newSize, oldSize);
- QApplication::postEvent(this, e);
- }
- }
- } else if (msg.message == WM_MOVE) { // move event
- int a = (int) (short) LOWORD(msg.lParam);
- int b = (int) (short) HIWORD(msg.lParam);
- QPoint oldPos = geometry().topLeft();
- QPoint newCPos(a, b);
- // Ignore silly Windows move event to wild pos after iconify.
-#if !defined(Q_WS_WINCE)
- if (!IsIconic(internalWinId()) && newCPos != oldPos) {
-#endif
- cr.moveTopLeft(newCPos);
- data->crect = cr;
- if (isVisible()) {
- QMoveEvent e(newCPos, oldPos); // cpos (client position)
- QApplication::sendSpontaneousEvent(this, &e);
- } else {
- QMoveEvent * e = new QMoveEvent(newCPos, oldPos);
- QApplication::postEvent(this, e);
- }
-#if !defined(Q_WS_WINCE)
- }
-#endif
- }
- setAttribute(Qt::WA_WState_ConfigPending, false); // clear config flag
- return true;
-}
-
-
-//
-// Close window event translation.
-//
-// This class is a friend of QApplication because it needs to emit the
-// lastWindowClosed() signal when the last top level widget is closed.
-//
-
-bool QETWidget::translateCloseEvent(const MSG &)
-{
- return d_func()->close_helper(QWidgetPrivate::CloseWithSpontaneousEvent);
-}
-
-#ifndef QT_NO_GESTURES
-bool QETWidget::translateGestureEvent(const MSG &, const GESTUREINFO &gi)
-{
- const QPoint widgetPos = QPoint(gi.ptsLocation.x, gi.ptsLocation.y);
- QWidget *alienWidget = !internalWinId() ? this : childAt(widgetPos);
- if (alienWidget && alienWidget->internalWinId())
- alienWidget = 0;
- QWidget *widget = alienWidget ? alienWidget : this;
-
- QNativeGestureEvent event;
- event.sequenceId = gi.dwSequenceID;
- event.position = QPoint(gi.ptsLocation.x, gi.ptsLocation.y);
- event.argument = gi.ullArguments;
-
- switch (gi.dwID) {
- case GID_BEGIN:
- event.gestureType = QNativeGestureEvent::GestureBegin;
- break;
- case GID_END:
- event.gestureType = QNativeGestureEvent::GestureEnd;
- break;
- case GID_ZOOM:
- event.gestureType = QNativeGestureEvent::Zoom;
- break;
- case GID_PAN:
- event.gestureType = QNativeGestureEvent::Pan;
- break;
- case GID_ROTATE:
- event.gestureType = QNativeGestureEvent::Rotate;
- break;
- case GID_TWOFINGERTAP:
- case GID_ROLLOVER:
- default:
- break;
- }
- if (event.gestureType != QNativeGestureEvent::None)
- qt_sendSpontaneousEvent(widget, &event);
- return true;
-}
-#endif // QT_NO_GESTURES
-
-void QApplication::setCursorFlashTime(int msecs)
-{
- SetCaretBlinkTime(msecs / 2);
- QApplicationPrivate::cursor_flash_time = msecs;
-}
-
-
-int QApplication::cursorFlashTime()
-{
- int blink = (int)GetCaretBlinkTime();
- if (!blink)
- return QApplicationPrivate::cursor_flash_time;
- if (blink > 0)
- return 2*blink;
- return 0;
-}
-
-
-void QApplication::setDoubleClickInterval(int ms)
-{
-#ifndef Q_WS_WINCE
- SetDoubleClickTime(ms);
-#endif
- QApplicationPrivate::mouse_double_click_time = ms;
-}
-
-int QApplication::doubleClickInterval()
-{
- int ms = GetDoubleClickTime();
- if (ms != 0)
- return ms;
- return QApplicationPrivate::mouse_double_click_time;
-}
-
-
-void QApplication::setKeyboardInputInterval(int ms)
-{
- QApplicationPrivate::keyboard_input_time = ms;
-}
-
-int QApplication::keyboardInputInterval()
-{
- // FIXME: get from the system
- return QApplicationPrivate::keyboard_input_time;
-}
-
-#ifndef QT_NO_WHEELEVENT
-void QApplication::setWheelScrollLines(int n)
-{
-#ifdef SPI_SETWHEELSCROLLLINES
- if (n < 0)
- n = 0;
- SystemParametersInfo(SPI_SETWHEELSCROLLLINES, (uint)n, 0, 0);
-#else
- QApplicationPrivate::wheel_scroll_lines = n;
-#endif
-}
-
-int QApplication::wheelScrollLines()
-{
-#ifdef SPI_GETWHEELSCROLLLINES
- uint i = 3;
- SystemParametersInfo(SPI_GETWHEELSCROLLLINES, sizeof(uint), &i, 0);
- if (i > INT_MAX)
- i = INT_MAX;
- return i;
-#else
- return QApplicationPrivate::wheel_scroll_lines;
-#endif
-}
-#endif //QT_NO_WHEELEVENT
-
-static bool effect_override = false;
-
-void QApplication::setEffectEnabled(Qt::UIEffect effect, bool enable)
-{
- effect_override = true;
- switch (effect) {
- case Qt::UI_AnimateMenu:
- QApplicationPrivate::animate_menu = enable;
- break;
- case Qt::UI_FadeMenu:
- QApplicationPrivate::fade_menu = enable;
- break;
- case Qt::UI_AnimateCombo:
- QApplicationPrivate::animate_combo = enable;
- break;
- case Qt::UI_AnimateTooltip:
- QApplicationPrivate::animate_tooltip = enable;
- break;
- case Qt::UI_FadeTooltip:
- QApplicationPrivate::fade_tooltip = enable;
- break;
- case Qt::UI_AnimateToolBox:
- QApplicationPrivate::animate_toolbox = enable;
- break;
- default:
- QApplicationPrivate::animate_ui = enable;
- break;
- }
-}
-
-bool QApplication::isEffectEnabled(Qt::UIEffect effect)
-{
- if (QColormap::instance().depth() < 16)
- return false;
-
- if (!effect_override && desktopSettingsAware()) {
- // we know that they can be used when we are here
- BOOL enabled = false;
- UINT api;
- switch (effect) {
- case Qt::UI_AnimateMenu:
- api = SPI_GETMENUANIMATION;
- break;
- case Qt::UI_FadeMenu:
- api = SPI_GETMENUFADE;
- break;
- case Qt::UI_AnimateCombo:
- api = SPI_GETCOMBOBOXANIMATION;
- break;
- case Qt::UI_AnimateTooltip:
- api = SPI_GETTOOLTIPANIMATION;
- break;
- case Qt::UI_FadeTooltip:
- api = SPI_GETTOOLTIPFADE;
- break;
- default:
- api = SPI_GETUIEFFECTS;
- break;
- }
- SystemParametersInfo(api, 0, &enabled, 0);
- return enabled;
- }
-
- switch(effect) {
- case Qt::UI_AnimateMenu:
- return QApplicationPrivate::animate_menu;
- case Qt::UI_FadeMenu:
- return QApplicationPrivate::fade_menu;
- case Qt::UI_AnimateCombo:
- return QApplicationPrivate::animate_combo;
- case Qt::UI_AnimateTooltip:
- return QApplicationPrivate::animate_tooltip;
- case Qt::UI_FadeTooltip:
- return QApplicationPrivate::fade_tooltip;
- case Qt::UI_AnimateToolBox:
- return QApplicationPrivate::animate_toolbox;
- default:
- return QApplicationPrivate::animate_ui;
- }
-}
-
-#ifndef QT_NO_SESSIONMANAGER
-
-bool QSessionManager::allowsInteraction()
-{
- sm_blockUserInput = false;
- return true;
-}
-
-bool QSessionManager::allowsErrorInteraction()
-{
- sm_blockUserInput = false;
- return true;
-}
-
-void QSessionManager::release()
-{
- if (sm_smActive)
- sm_blockUserInput = true;
-}
-
-void QSessionManager::cancel()
-{
- sm_cancel = true;
-}
-
-#endif //QT_NO_SESSIONMANAGER
-
-
-bool QApplicationPrivate::HasTouchSupport = false;
-PtrRegisterTouchWindow QApplicationPrivate::RegisterTouchWindow = 0;
-PtrGetTouchInputInfo QApplicationPrivate::GetTouchInputInfo = 0;
-PtrCloseTouchInputHandle QApplicationPrivate::CloseTouchInputHandle = 0;
-
-void QApplicationPrivate::initializeMultitouch_sys()
-{
- if (QSysInfo::windowsVersion() >= QSysInfo::WV_WINDOWS7) {
- static const int QT_SM_DIGITIZER = 94;
- int value = GetSystemMetrics(QT_SM_DIGITIZER);
- static const int QT_NID_INTEGRATED_TOUCH = 0x01;
- static const int QT_NID_EXTERNAL_TOUCH = 0x02;
- static const int QT_NID_MULTI_INPUT = 0x40;
- QApplicationPrivate::HasTouchSupport =
- value & (QT_NID_INTEGRATED_TOUCH | QT_NID_EXTERNAL_TOUCH | QT_NID_MULTI_INPUT);
- }
-
- QSystemLibrary library(QLatin1String("user32"));
- // MinGW (g++ 3.4.5) accepts only C casts.
- RegisterTouchWindow = (PtrRegisterTouchWindow)(library.resolve("RegisterTouchWindow"));
- GetTouchInputInfo = (PtrGetTouchInputInfo)(library.resolve("GetTouchInputInfo"));
- CloseTouchInputHandle = (PtrCloseTouchInputHandle)(library.resolve("CloseTouchInputHandle"));
-
- touchInputIDToTouchPointID.clear();
-}
-
-void QApplicationPrivate::cleanupMultitouch_sys()
-{
- touchInputIDToTouchPointID.clear();
-}
-
-bool QApplicationPrivate::translateTouchEvent(const MSG &msg)
-{
- QWidget *widgetForHwnd = QWidget::find(msg.hwnd);
- if (!widgetForHwnd)
- return false;
-
- QRect screenGeometry = QApplication::desktop()->screenGeometry(widgetForHwnd);
-
- QList<QTouchEvent::TouchPoint> touchPoints;
-
- QVector<TOUCHINPUT> winTouchInputs(msg.wParam);
- memset(winTouchInputs.data(), 0, sizeof(TOUCHINPUT) * winTouchInputs.count());
- Qt::TouchPointStates allStates = 0;
- QApplicationPrivate::GetTouchInputInfo((HANDLE) msg.lParam, msg.wParam, winTouchInputs.data(), sizeof(TOUCHINPUT));
- for (int i = 0; i < winTouchInputs.count(); ++i) {
- const TOUCHINPUT &touchInput = winTouchInputs.at(i);
-
- int touchPointID = touchInputIDToTouchPointID.value(touchInput.dwID, -1);
- if (touchPointID == -1) {
- touchPointID = touchInputIDToTouchPointID.count();
- touchInputIDToTouchPointID.insert(touchInput.dwID, touchPointID);
- }
-
- QTouchEvent::TouchPoint touchPoint(touchPointID);
-
- // update state
- QPointF screenPos(qreal(touchInput.x) / qreal(100.), qreal(touchInput.y) / qreal(100.));
- QRectF screenRect;
- if (touchInput.dwMask & TOUCHINPUTMASKF_CONTACTAREA)
- screenRect.setSize(QSizeF(qreal(touchInput.cxContact) / qreal(100.),
- qreal(touchInput.cyContact) / qreal(100.)));
- screenRect.moveCenter(screenPos);
-
- Qt::TouchPointStates state;
- if (touchInput.dwFlags & TOUCHEVENTF_DOWN) {
- state = Qt::TouchPointPressed;
- } else if (touchInput.dwFlags & TOUCHEVENTF_UP) {
- state = Qt::TouchPointReleased;
- } else {
- state = (screenPos == touchPoint.screenPos()
- ? Qt::TouchPointStationary
- : Qt::TouchPointMoved);
- }
- if (touchInput.dwFlags & TOUCHEVENTF_PRIMARY)
- state |= Qt::TouchPointPrimary;
- touchPoint.setState(state);
- touchPoint.setScreenRect(screenRect);
- touchPoint.setNormalizedPos(QPointF(screenPos.x() / screenGeometry.width(),
- screenPos.y() / screenGeometry.height()));
-
- allStates |= state;
-
- touchPoints.append(touchPoint);
- }
- QApplicationPrivate::CloseTouchInputHandle((HANDLE) msg.lParam);
-
- if ((allStates & Qt::TouchPointStateMask) == Qt::TouchPointReleased) {
- // all touch points released, forget the ids we've seen, they may not be reused
- touchInputIDToTouchPointID.clear();
- }
-
- translateRawTouchEvent(widgetForHwnd, QTouchEvent::TouchScreen, touchPoints);
- return true;
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp
deleted file mode 100644
index 311b147976..0000000000
--- a/src/gui/kernel/qapplication_x11.cpp
+++ /dev/null
@@ -1,6254 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-// ### 4.0: examine Q_EXPORT's below. The respective symbols had all
-// been in use (e.g. in the KDE wm) before the introduction of a version
-// map. One might want to turn some of them into proper public API and
-// provide a proper alternative for others. See also the exports in
-// qapplication_win.cpp, which suggest a unification.
-
-#include "qplatformdefs.h"
-
-#include "qcolormap.h"
-#include "qdesktopwidget.h"
-#include "qapplication.h"
-#include "qapplication_p.h"
-#include "qcursor.h"
-#include "qwidget.h"
-#include "qbitarray.h"
-#include "qpainter.h"
-#include "qfile.h"
-#include "qpixmapcache.h"
-#include "qdatetime.h"
-#include "qtextcodec.h"
-#include "qdatastream.h"
-#include "qbuffer.h"
-#include "qsocketnotifier.h"
-#include "qsessionmanager.h"
-#include "qclipboard.h"
-#include "qwhatsthis.h"
-#include "qsettings.h"
-#include "qstylefactory.h"
-#include "qfileinfo.h"
-#include "qdir.h"
-#include "qhash.h"
-#include "qevent.h"
-#include "qevent_p.h"
-#include "qvarlengtharray.h"
-#include "qdebug.h"
-#include <private/qcrashhandler_p.h>
-#include <private/qcolor_p.h>
-#include <private/qcursor_p.h>
-#include <private/qiconloader_p.h>
-#include <qgtkstyle.h>
-#include "qstyle.h"
-#include "qmetaobject.h"
-#include "qtimer.h"
-#include "qlibrary.h"
-#include <private/qgraphicssystemfactory_p.h>
-#include "qguiplatformplugin_p.h"
-#include "qkde_p.h"
-
-#if !defined (QT_NO_TABLET)
-extern "C" {
-# define class c_class //XIproto.h has a name member named 'class' which the c++ compiler doesn't like
-# include <wacomcfg.h>
-# undef class
-}
-#endif
-
-#ifndef QT_GUI_DOUBLE_CLICK_RADIUS
-#define QT_GUI_DOUBLE_CLICK_RADIUS 5
-#endif
-
-
-//#define ALIEN_DEBUG
-
-#if !defined(QT_NO_GLIB)
-# include "qguieventdispatcher_glib_p.h"
-#endif
-#include "qeventdispatcher_x11_p.h"
-#include <private/qpaintengine_x11_p.h>
-
-#include <private/qkeymapper_p.h>
-
-// Input method stuff
-#ifndef QT_NO_IM
-#include "qinputcontext.h"
-#include "qinputcontextfactory.h"
-#endif // QT_NO_IM
-
-#ifndef QT_NO_XFIXES
-#include <X11/extensions/Xfixes.h>
-#endif // QT_NO_XFIXES
-
-#include "qt_x11_p.h"
-#include "qx11info_x11.h"
-
-#define XK_MISCELLANY
-#include <X11/keysymdef.h>
-#if !defined(QT_NO_XINPUT)
-#include <X11/extensions/XI.h>
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <locale.h>
-
-#include "qwidget_p.h"
-
-#include <private/qbackingstore_p.h>
-
-#ifdef QT_RX71_MULTITOUCH
-# include <qsocketnotifier.h>
-# include <linux/input.h>
-# include <errno.h>
-#endif
-
-#if _POSIX_VERSION+0 < 200112L && !defined(Q_OS_BSD4)
-# define QT_NO_UNSETENV
-#endif
-
-QT_BEGIN_NAMESPACE
-
-//#define X_NOT_BROKEN
-#ifdef X_NOT_BROKEN
-// Some X libraries are built with setlocale #defined to _Xsetlocale,
-// even though library users are then built WITHOUT such a definition.
-// This creates a problem - Qt might setlocale() one value, but then
-// X looks and doesn't see the value Qt set. The solution here is to
-// implement _Xsetlocale just in case X calls it - redirecting it to
-// the real libC version.
-//
-# ifndef setlocale
-extern "C" char *_Xsetlocale(int category, const char *locale);
-char *_Xsetlocale(int category, const char *locale)
-{
- //qDebug("_Xsetlocale(%d,%s),category,locale");
- return setlocale(category,locale);
-}
-# endif // setlocale
-#endif // X_NOT_BROKEN
-
-/* Warning: if you modify this string, modify the list of atoms in qt_x11_p.h as well! */
-static const char * x11_atomnames = {
- // window-manager <-> client protocols
- "WM_PROTOCOLS\0"
- "WM_DELETE_WINDOW\0"
- "WM_TAKE_FOCUS\0"
- "_NET_WM_PING\0"
- "_NET_WM_CONTEXT_HELP\0"
- "_NET_WM_SYNC_REQUEST\0"
- "_NET_WM_SYNC_REQUEST_COUNTER\0"
-
- // ICCCM window state
- "WM_STATE\0"
- "WM_CHANGE_STATE\0"
-
- // Session management
- "WM_CLIENT_LEADER\0"
- "WM_WINDOW_ROLE\0"
- "SM_CLIENT_ID\0"
-
- // Clipboard
- "CLIPBOARD\0"
- "INCR\0"
- "TARGETS\0"
- "MULTIPLE\0"
- "TIMESTAMP\0"
- "SAVE_TARGETS\0"
- "CLIP_TEMPORARY\0"
- "_QT_SELECTION\0"
- "_QT_CLIPBOARD_SENTINEL\0"
- "_QT_SELECTION_SENTINEL\0"
- "CLIPBOARD_MANAGER\0"
-
- "RESOURCE_MANAGER\0"
-
- "_XSETROOT_ID\0"
-
- "_QT_SCROLL_DONE\0"
- "_QT_INPUT_ENCODING\0"
-
- "_MOTIF_WM_HINTS\0"
-
- "DTWM_IS_RUNNING\0"
- "ENLIGHTENMENT_DESKTOP\0"
- "_DT_SAVE_MODE\0"
- "_SGI_DESKS_MANAGER\0"
-
- // EWMH (aka NETWM)
- "_NET_SUPPORTED\0"
- "_NET_VIRTUAL_ROOTS\0"
- "_NET_WORKAREA\0"
-
- "_NET_MOVERESIZE_WINDOW\0"
- "_NET_WM_MOVERESIZE\0"
-
- "_NET_WM_NAME\0"
- "_NET_WM_ICON_NAME\0"
- "_NET_WM_ICON\0"
-
- "_NET_WM_PID\0"
-
- "_NET_WM_WINDOW_OPACITY\0"
-
- "_NET_WM_STATE\0"
- "_NET_WM_STATE_ABOVE\0"
- "_NET_WM_STATE_BELOW\0"
- "_NET_WM_STATE_FULLSCREEN\0"
- "_NET_WM_STATE_MAXIMIZED_HORZ\0"
- "_NET_WM_STATE_MAXIMIZED_VERT\0"
- "_NET_WM_STATE_MODAL\0"
- "_NET_WM_STATE_STAYS_ON_TOP\0"
- "_NET_WM_STATE_DEMANDS_ATTENTION\0"
-
- "_NET_WM_USER_TIME\0"
- "_NET_WM_USER_TIME_WINDOW\0"
- "_NET_WM_FULL_PLACEMENT\0"
-
- "_NET_WM_WINDOW_TYPE\0"
- "_NET_WM_WINDOW_TYPE_DESKTOP\0"
- "_NET_WM_WINDOW_TYPE_DOCK\0"
- "_NET_WM_WINDOW_TYPE_TOOLBAR\0"
- "_NET_WM_WINDOW_TYPE_MENU\0"
- "_NET_WM_WINDOW_TYPE_UTILITY\0"
- "_NET_WM_WINDOW_TYPE_SPLASH\0"
- "_NET_WM_WINDOW_TYPE_DIALOG\0"
- "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU\0"
- "_NET_WM_WINDOW_TYPE_POPUP_MENU\0"
- "_NET_WM_WINDOW_TYPE_TOOLTIP\0"
- "_NET_WM_WINDOW_TYPE_NOTIFICATION\0"
- "_NET_WM_WINDOW_TYPE_COMBO\0"
- "_NET_WM_WINDOW_TYPE_DND\0"
- "_NET_WM_WINDOW_TYPE_NORMAL\0"
- "_KDE_NET_WM_WINDOW_TYPE_OVERRIDE\0"
-
- "_KDE_NET_WM_FRAME_STRUT\0"
-
- "_NET_STARTUP_INFO\0"
- "_NET_STARTUP_INFO_BEGIN\0"
-
- "_NET_SUPPORTING_WM_CHECK\0"
-
- "_NET_WM_CM_S0\0"
-
- "_NET_SYSTEM_TRAY_VISUAL\0"
-
- "_NET_ACTIVE_WINDOW\0"
-
- // Property formats
- "COMPOUND_TEXT\0"
- "TEXT\0"
- "UTF8_STRING\0"
-
- // xdnd
- "XdndEnter\0"
- "XdndPosition\0"
- "XdndStatus\0"
- "XdndLeave\0"
- "XdndDrop\0"
- "XdndFinished\0"
- "XdndTypeList\0"
- "XdndActionList\0"
-
- "XdndSelection\0"
-
- "XdndAware\0"
- "XdndProxy\0"
-
- "XdndActionCopy\0"
- "XdndActionLink\0"
- "XdndActionMove\0"
- "XdndActionPrivate\0"
-
- // Motif DND
- "_MOTIF_DRAG_AND_DROP_MESSAGE\0"
- "_MOTIF_DRAG_INITIATOR_INFO\0"
- "_MOTIF_DRAG_RECEIVER_INFO\0"
- "_MOTIF_DRAG_WINDOW\0"
- "_MOTIF_DRAG_TARGETS\0"
-
- "XmTRANSFER_SUCCESS\0"
- "XmTRANSFER_FAILURE\0"
-
- // Xkb
- "_XKB_RULES_NAMES\0"
-
- // XEMBED
- "_XEMBED\0"
- "_XEMBED_INFO\0"
-
- // Wacom old. (before version 0.10)
- "Wacom Stylus\0"
- "Wacom Cursor\0"
- "Wacom Eraser\0"
-
- // Tablet
- "STYLUS\0"
- "ERASER\0"
-};
-
-Q_GUI_EXPORT QX11Data *qt_x11Data = 0;
-
-/*****************************************************************************
- Internal variables and functions
- *****************************************************************************/
-static const char *appName = 0; // application name
-static const char *appClass = 0; // application class
-static const char *appFont = 0; // application font
-static const char *appBGCol = 0; // application bg color
-static const char *appFGCol = 0; // application fg color
-static const char *appBTNCol = 0; // application btn color
-static const char *mwGeometry = 0; // main widget geometry
-static const char *mwTitle = 0; // main widget title
-char *qt_ximServer = 0; // XIM Server will connect to
-static bool appSync = false; // X11 synchronization
-#if defined(QT_DEBUG)
-static bool appNoGrab = false; // X11 grabbing enabled
-static bool appDoGrab = false; // X11 grabbing override (gdb)
-#endif
-static bool app_save_rootinfo = false; // save root info
-static bool app_do_modal = false; // modal mode
-static Window curWin = 0; // current window
-
-
-// function to update the workarea of the screen - in qdesktopwidget_x11.cpp
-extern void qt_desktopwidget_update_workarea();
-
-// Function to change the window manager state (from qwidget_x11.cpp)
-extern void qt_change_net_wm_state(const QWidget *w, bool set, Atom one, Atom two = 0);
-
-// modifier masks for alt, meta, super, hyper, and mode_switch - detected when the application starts
-// and/or keyboard layout changes
-uchar qt_alt_mask = 0;
-uchar qt_meta_mask = 0;
-uchar qt_super_mask = 0;
-uchar qt_hyper_mask = 0;
-uchar qt_mode_switch_mask = 0;
-
-// flags for extensions for special Languages, currently only for RTL languages
-bool qt_use_rtl_extensions = false;
-
-static Window mouseActWindow = 0; // window where mouse is
-static Qt::MouseButton mouseButtonPressed = Qt::NoButton; // last mouse button pressed
-static Qt::MouseButtons mouseButtonState = Qt::NoButton; // mouse button state
-static Time mouseButtonPressTime = 0; // when was a button pressed
-static short mouseXPos, mouseYPos; // mouse pres position in act window
-static short mouseGlobalXPos, mouseGlobalYPos; // global mouse press position
-
-extern QWidgetList *qt_modal_stack; // stack of modal widgets
-
-// window where mouse buttons have been pressed
-static Window pressed_window = XNone;
-
-// popup control
-static bool replayPopupMouseEvent = false;
-static bool popupGrabOk;
-
-bool qt_sm_blockUserInput = false; // session management
-
-Q_GUI_EXPORT int qt_xfocusout_grab_counter = 0;
-
-#if !defined (QT_NO_TABLET)
-Q_GLOBAL_STATIC(QTabletDeviceDataList, tablet_devices)
-QTabletDeviceDataList *qt_tablet_devices()
-{
- return tablet_devices();
-}
-
-extern bool qt_tabletChokeMouse;
-#endif
-
-typedef bool(*QX11FilterFunction)(XEvent *event);
-
-Q_GLOBAL_STATIC(QList<QX11FilterFunction>, x11Filters)
-
-Q_GUI_EXPORT void qt_installX11EventFilter(QX11FilterFunction func)
-{
- Q_ASSERT(func);
-
- if (QList<QX11FilterFunction> *list = x11Filters())
- list->append(func);
-}
-
-Q_GUI_EXPORT void qt_removeX11EventFilter(QX11FilterFunction func)
-{
- Q_ASSERT(func);
-
- if (QList<QX11FilterFunction> *list = x11Filters())
- list->removeOne(func);
-}
-
-
-static bool qt_x11EventFilter(XEvent* ev)
-{
- long unused;
- if (qApp->filterEvent(ev, &unused))
- return true;
- if (const QList<QX11FilterFunction> *list = x11Filters()) {
- for (QList<QX11FilterFunction>::const_iterator it = list->constBegin(); it != list->constEnd(); ++it) {
- if ((*it)(ev))
- return true;
- }
- }
-
- return qApp->x11EventFilter(ev);
-}
-
-#if !defined(QT_NO_XIM)
-XIMStyle qt_xim_preferred_style = 0;
-#endif
-int qt_ximComposingKeycode=0;
-QTextCodec * qt_input_mapper = 0;
-
-extern bool qt_check_clipboard_sentinel(); //def in qclipboard_x11.cpp
-extern bool qt_check_selection_sentinel(); //def in qclipboard_x11.cpp
-extern bool qt_xfixes_clipboard_changed(Window clipboardOwner, Time timestamp); //def in qclipboard_x11.cpp
-extern bool qt_xfixes_selection_changed(Window selectionOwner, Time timestamp); //def in qclipboard_x11.cpp
-
-static void qt_save_rootinfo();
-Q_GUI_EXPORT bool qt_try_modal(QWidget *, XEvent *);
-
-QWidget *qt_button_down = 0; // last widget to be pressed with the mouse
-QPointer<QWidget> qt_last_mouse_receiver = 0;
-static QWidget *qt_popup_down = 0; // popup that contains the pressed widget
-
-extern bool qt_xdnd_dragging;
-
-// gui or non-gui from qapplication.cpp
-extern bool qt_is_gui_used;
-
-/*!
- \internal
- Try to resolve a \a symbol from \a library with the version specified
- by \a vernum.
-
- Note that, in the case of the Xfixes library, \a vernum is not the same as
- \c XFIXES_MAJOR - it is a part of soname and may differ from the Xfixes
- version.
-*/
-static QFunctionPointer qt_load_library_runtime(const char *library, int vernum,
- int highestVernum, const char *symbol)
-{
- QList<int> versions;
- // we try to load in the following order:
- // explicit version -> the default one -> (from the highest (highestVernum) to the lowest (vernum) )
- if (vernum != -1)
- versions << vernum;
- versions << -1;
- if (vernum != -1) {
- for(int i = highestVernum; i > vernum; --i)
- versions << i;
- }
- Q_FOREACH(int version, versions) {
- QLatin1String libName(library);
- QLibrary xfixesLib(libName, version);
- QFunctionPointer ptr = xfixesLib.resolve(symbol);
- if (ptr)
- return ptr;
- }
- return 0;
-}
-
-#ifndef QT_NO_XINPUT
-# ifdef QT_RUNTIME_XINPUT
-# define XINPUT_LOAD_RUNTIME(vernum, symbol, symbol_type) \
- (symbol_type)qt_load_library_runtime("libXi", vernum, 6, #symbol);
-# define XINPUT_LOAD(symbol) \
- XINPUT_LOAD_RUNTIME(1, symbol, Ptr##symbol)
-# else // not runtime XInput
-# define XINPUT_LOAD(symbol) symbol
-# endif // QT_RUNTIME_XINPUT
-#else // not using Xinput at all
-# define XINPUT_LOAD(symbol) 0
-#endif // QT_NO_XINPUT
-
-#ifndef QT_NO_XFIXES
-# ifdef QT_RUNTIME_XFIXES
-# define XFIXES_LOAD_RUNTIME(vernum, symbol, symbol_type) \
- (symbol_type)qt_load_library_runtime("libXfixes", vernum, 4, #symbol);
-# define XFIXES_LOAD_V1(symbol) \
- XFIXES_LOAD_RUNTIME(1, symbol, Ptr##symbol)
-# define XFIXES_LOAD_V2(symbol) \
- XFIXES_LOAD_RUNTIME(2, symbol, Ptr##symbol)
-
-# else // not runtime Xfixes
-
-# if XFIXES_MAJOR >= 2
-# define XFIXES_LOAD_V1(symbol) symbol
-# define XFIXES_LOAD_V2(symbol) symbol
-# elif XFIXES_MAJOR >= 1
-# define XFIXES_LOAD_V1(symbol) symbol
-# define XFIXES_LOAD_V2(symbol) 0
-# else
-# error Unsupported version of Xfixes
-# endif
-# endif // QT_RUNTIME_XFIXES
-#else // not using Xfixes at all
-# define XFIXES_LOAD_V1(symbol) 0
-# define XFIXES_LOAD_V2(symbol) 0
-#endif // QT_NO_XFIXES
-
-#ifndef QT_NO_XFIXES
-
-struct qt_xfixes_selection_event_data
-{
- // which selection to filter out.
- Atom selection;
-};
-
-#if defined(Q_C_CALLBACKS)
-extern "C" {
-#endif
-
-static Bool qt_xfixes_scanner(Display*, XEvent *event, XPointer arg)
-{
- qt_xfixes_selection_event_data *data =
- reinterpret_cast<qt_xfixes_selection_event_data*>(arg);
- if (event->type == X11->xfixes_eventbase + XFixesSelectionNotify) {
- XFixesSelectionNotifyEvent *xfixes_event = reinterpret_cast<XFixesSelectionNotifyEvent*>(event);
- if (xfixes_event->selection == data->selection)
- return true;
- }
- return false;
-}
-
-#if defined(Q_C_CALLBACKS)
-}
-#endif
-
-#endif // QT_NO_XFIXES
-
-class QETWidget : public QWidget // event translator widget
-{
-public:
- QWidgetPrivate* d_func() { return QWidget::d_func(); }
- bool translateMouseEvent(const XEvent *);
- void translatePaintEvent(const XEvent *);
- bool translateConfigEvent(const XEvent *);
- bool translateCloseEvent(const XEvent *);
- bool translateScrollDoneEvent(const XEvent *);
- bool translateWheelEvent(int global_x, int global_y, int delta, Qt::MouseButtons buttons,
- Qt::KeyboardModifiers modifiers, Qt::Orientation orient);
-#if !defined (QT_NO_TABLET)
- bool translateXinputEvent(const XEvent*, QTabletDeviceData *tablet);
-#endif
- bool translatePropertyEvent(const XEvent *);
-
- void doDeferredMap()
- {
- Q_ASSERT(testAttribute(Qt::WA_WState_Created));
- if (!testAttribute(Qt::WA_Resized)) {
- adjustSize();
- setAttribute(Qt::WA_Resized, false);
- }
-
- /*
- workaround for WM's that throw away ConfigureRequests from the following:
-
- window->hide();
- window->move(x, y); // could also be resize(), move()+resize(), or setGeometry()
- window->show();
- */
- QRect r = geometry();
-
- XMoveResizeWindow(X11->display,
- internalWinId(),
- r.x(),
- r.y(),
- r.width(),
- r.height());
-
- // static gravity!
- XSizeHints sh;
- long unused;
- XGetWMNormalHints(X11->display, internalWinId(), &sh, &unused);
- sh.flags |= USPosition | PPosition | USSize | PSize | PWinGravity;
- sh.x = r.x();
- sh.y = r.y();
- sh.width = r.width();
- sh.height = r.height();
- sh.win_gravity = StaticGravity;
- XSetWMNormalHints(X11->display, internalWinId(), &sh);
-
- setAttribute(Qt::WA_Mapped);
- if (testAttribute(Qt::WA_DontShowOnScreen))
- return;
- d_func()->topData()->waitingForMapNotify = 1;
- XMapWindow(X11->display, internalWinId());
- }
-};
-
-
-void QApplicationPrivate::createEventDispatcher()
-{
- Q_Q(QApplication);
-#if !defined(QT_NO_GLIB)
- if (qgetenv("QT_NO_GLIB").isEmpty() && QEventDispatcherGlib::versionSupported())
- eventDispatcher = (q->type() != QApplication::Tty
- ? new QGuiEventDispatcherGlib(q)
- : new QEventDispatcherGlib(q));
- else
-#endif
- eventDispatcher = (q->type() != QApplication::Tty
- ? new QEventDispatcherX11(q)
- : new QEventDispatcherUNIX(q));
-}
-
-/*****************************************************************************
- Default X error handlers
- *****************************************************************************/
-
-#if defined(Q_C_CALLBACKS)
-extern "C" {
-#endif
-
-static int (*original_x_errhandler)(Display *dpy, XErrorEvent *);
-static int (*original_xio_errhandler)(Display *dpy);
-
-static int qt_x_errhandler(Display *dpy, XErrorEvent *err)
-{
- if (X11->display != dpy) {
- // only handle X errors for our display
- return 0;
- }
-
- switch (err->error_code) {
- case BadAtom:
- if (err->request_code == 20 /* X_GetProperty */
- && (err->resourceid == XA_RESOURCE_MANAGER
- || err->resourceid == XA_RGB_DEFAULT_MAP
- || err->resourceid == ATOM(_NET_SUPPORTED)
- || err->resourceid == ATOM(_NET_SUPPORTING_WM_CHECK)
- || err->resourceid == ATOM(XdndProxy)
- || err->resourceid == ATOM(XdndAware))) {
- // Perhaps we're running under SECURITY reduction? :/
- return 0;
- }
- break;
-
- case BadWindow:
- if (err->request_code == 2 /* X_ChangeWindowAttributes */
- || err->request_code == 38 /* X_QueryPointer */) {
- for (int i = 0; i < ScreenCount(dpy); ++i) {
- if (err->resourceid == RootWindow(dpy, i)) {
- // Perhaps we're running under SECURITY reduction? :/
- return 0;
- }
- }
- }
- X11->seen_badwindow = true;
- if (err->request_code == 25 /* X_SendEvent */) {
- for (int i = 0; i < ScreenCount(dpy); ++i) {
- if (err->resourceid == RootWindow(dpy, i)) {
- // Perhaps we're running under SECURITY reduction? :/
- return 0;
- }
- }
- if (X11->xdndHandleBadwindow()) {
- qDebug("xdndHandleBadwindow returned true");
- return 0;
- }
- }
- if (X11->ignore_badwindow)
- return 0;
- break;
-
- default:
-#if !defined(QT_NO_XINPUT)
- if (err->request_code == X11->xinput_major
- && err->error_code == (X11->xinput_errorbase + XI_BadDevice)
- && err->minor_code == 3 /* X_OpenDevice */) {
- return 0;
- }
-#endif
- break;
- }
-
- char errstr[256];
- XGetErrorText( dpy, err->error_code, errstr, 256 );
- char buffer[256];
- char request_str[256];
- qsnprintf(buffer, 256, "%d", err->request_code);
- XGetErrorDatabaseText(dpy, "XRequest", buffer, "", request_str, 256);
- if (err->request_code < 128) {
- // X error for a normal protocol request
- qWarning( "X Error: %s %d\n"
- " Major opcode: %d (%s)\n"
- " Resource id: 0x%lx",
- errstr, err->error_code,
- err->request_code,
- request_str,
- err->resourceid );
- } else {
- // X error for an extension request
- const char *extensionName = 0;
- if (err->request_code == X11->xrender_major)
- extensionName = "RENDER";
- else if (err->request_code == X11->xrandr_major)
- extensionName = "RANDR";
- else if (err->request_code == X11->xinput_major)
- extensionName = "XInputExtension";
- else if (err->request_code == X11->mitshm_major)
- extensionName = "MIT-SHM";
-#ifndef QT_NO_XKB
- else if(err->request_code == X11->xkb_major)
- extensionName = "XKEYBOARD";
-#endif
-
- char minor_str[256];
- if (extensionName) {
- qsnprintf(buffer, 256, "%s.%d", extensionName, err->minor_code);
- XGetErrorDatabaseText(dpy, "XRequest", buffer, "", minor_str, 256);
- } else {
- extensionName = "Uknown extension";
- qsnprintf(minor_str, 256, "Unknown request");
- }
- qWarning( "X Error: %s %d\n"
- " Extension: %d (%s)\n"
- " Minor opcode: %d (%s)\n"
- " Resource id: 0x%lx",
- errstr, err->error_code,
- err->request_code,
- extensionName,
- err->minor_code,
- minor_str,
- err->resourceid );
- }
-
- // ### we really should distinguish between severe, non-severe and
- // ### application specific errors
-
- return 0;
-}
-
-
-static int qt_xio_errhandler(Display *)
-{
- qWarning("%s: Fatal IO error: client killed", appName);
- QApplicationPrivate::reset_instance_pointer();
- exit(1);
- //### give the application a chance for a proper shutdown instead,
- //### exit(1) doesn't help.
- return 0;
-}
-
-#if defined(Q_C_CALLBACKS)
-}
-#endif
-
-#ifndef QT_NO_XSYNC
-struct qt_sync_request_event_data
-{
- WId window;
-};
-
-#if defined(Q_C_CALLBACKS)
-extern "C" {
-#endif
-
-static Bool qt_sync_request_scanner(Display*, XEvent *event, XPointer arg)
-{
- qt_sync_request_event_data *data =
- reinterpret_cast<qt_sync_request_event_data*>(arg);
- if (event->type == ClientMessage &&
- event->xany.window == data->window &&
- event->xclient.message_type == ATOM(WM_PROTOCOLS) &&
- (Atom)event->xclient.data.l[0] == ATOM(_NET_WM_SYNC_REQUEST)) {
- QWidget *w = QWidget::find(event->xany.window);
- if (QTLWExtra *tlw = ((QETWidget*)w)->d_func()->maybeTopData()) {
- const ulong timestamp = (const ulong) event->xclient.data.l[1];
- if (timestamp > X11->time)
- X11->time = timestamp;
- if (timestamp == CurrentTime || timestamp > tlw->syncRequestTimestamp) {
- tlw->syncRequestTimestamp = timestamp;
- tlw->newCounterValueLo = event->xclient.data.l[2];
- tlw->newCounterValueHi = event->xclient.data.l[3];
- }
- }
- return true;
- }
- return false;
-}
-
-#if defined(Q_C_CALLBACKS)
-}
-#endif
-#endif // QT_NO_XSYNC
-
-static void qt_x11_create_intern_atoms()
-{
- const char *names[QX11Data::NAtoms];
- const char *ptr = x11_atomnames;
-
- int i = 0;
- while (*ptr) {
- names[i++] = ptr;
- while (*ptr)
- ++ptr;
- ++ptr;
- }
-
- Q_ASSERT(i == QX11Data::NPredefinedAtoms);
-
- QByteArray settings_atom_name("_QT_SETTINGS_TIMESTAMP_");
- settings_atom_name += XDisplayName(X11->displayName);
- names[i++] = settings_atom_name;
-
- Q_ASSERT(i == QX11Data::NAtoms);
-#if defined(XlibSpecificationRelease) && (XlibSpecificationRelease >= 6)
- XInternAtoms(X11->display, (char **)names, i, False, X11->atoms);
-#else
- for (i = 0; i < QX11Data::NAtoms; ++i)
- X11->atoms[i] = XInternAtom(X11->display, (char *)names[i], False);
-#endif
-}
-
-Q_GUI_EXPORT void qt_x11_apply_settings_in_all_apps()
-{
- QByteArray stamp;
- QDataStream s(&stamp, QIODevice::WriteOnly);
- s << QDateTime::currentDateTime();
-
- XChangeProperty(QX11Info::display(), QX11Info::appRootWindow(0),
- ATOM(_QT_SETTINGS_TIMESTAMP), ATOM(_QT_SETTINGS_TIMESTAMP), 8,
- PropModeReplace, (unsigned char *)stamp.data(), stamp.size());
-}
-
-/*! \internal
- apply the settings to the application
-*/
-bool QApplicationPrivate::x11_apply_settings()
-{
- QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
-
- settings.beginGroup(QLatin1String("Qt"));
-
- /*
- Qt settings. This is now they are written into the datastream.
-
- Palette / * - QPalette
- font - QFont
- libraryPath - QStringList
- style - QString
- doubleClickInterval - int
- keyboardInputInterval - int
- cursorFlashTime - int
- wheelScrollLines - int
- colorSpec - QString
- defaultCodec - QString
- globalStrut/width - int
- globalStrut/height - int
- GUIEffects - QStringList
- Font Substitutions/ * - QStringList
- Font Substitutions/... - QStringList
- */
-
- QStringList strlist;
- int i;
- QPalette pal(Qt::black);
- int groupCount = 0;
- strlist = settings.value(QLatin1String("Palette/active")).toStringList();
- if (!strlist.isEmpty()) {
- ++groupCount;
- for (i = 0; i < qMin(strlist.count(), int(QPalette::NColorRoles)); i++)
- pal.setColor(QPalette::Active, (QPalette::ColorRole) i,
- QColor(strlist[i]));
- }
- strlist = settings.value(QLatin1String("Palette/inactive")).toStringList();
- if (!strlist.isEmpty()) {
- ++groupCount;
- for (i = 0; i < qMin(strlist.count(), int(QPalette::NColorRoles)); i++)
- pal.setColor(QPalette::Inactive, (QPalette::ColorRole) i,
- QColor(strlist[i]));
- }
- strlist = settings.value(QLatin1String("Palette/disabled")).toStringList();
- if (!strlist.isEmpty()) {
- ++groupCount;
- for (i = 0; i < qMin(strlist.count(), int(QPalette::NColorRoles)); i++)
- pal.setColor(QPalette::Disabled, (QPalette::ColorRole) i,
- QColor(strlist[i]));
- }
-
- // ### Fix properly for 4.6
- bool usingGtkSettings = QApplicationPrivate::app_style && QApplicationPrivate::app_style->inherits("QGtkStyle");
- if (!usingGtkSettings) {
- if (groupCount == QPalette::NColorGroups)
- QApplicationPrivate::setSystemPalette(pal);
- }
-
- if (!appFont) {
- // ### Fix properly for 4.6
- if (!usingGtkSettings) {
- QFont font(QApplication::font());
- QString fontDescription;
- // Override Qt font if KDE4 settings can be used
- if (X11->desktopVersion == 4) {
- QSettings kdeSettings(QKde::kdeHome() + QLatin1String("/share/config/kdeglobals"), QSettings::IniFormat);
- fontDescription = kdeSettings.value(QLatin1String("font")).toString();
- if (fontDescription.isEmpty()) {
- // KDE stores fonts without quotes
- fontDescription = kdeSettings.value(QLatin1String("font")).toStringList().join(QLatin1String(","));
- }
- }
- if (fontDescription.isEmpty())
- fontDescription = settings.value(QLatin1String("font")).toString();
- if (!fontDescription .isEmpty()) {
- font.fromString(fontDescription );
- QApplicationPrivate::setSystemFont(font);
- }
- }
- }
-
- // read library (ie. plugin) path list
- QString libpathkey =
- QString::fromLatin1("%1.%2/libraryPath")
- .arg(QT_VERSION >> 16)
- .arg((QT_VERSION & 0xff00) >> 8);
- QStringList pathlist = settings.value(libpathkey).toString().split(QLatin1Char(':'));
- if (! pathlist.isEmpty()) {
- QStringList::ConstIterator it = pathlist.constBegin();
- while (it != pathlist.constEnd())
- QApplication::addLibraryPath(*it++);
- }
-
- // read new QStyle
- QString stylename = settings.value(QLatin1String("style")).toString();
-
- if (stylename.isEmpty() && QApplicationPrivate::styleOverride.isNull() && X11->use_xrender) {
- stylename = qt_guiPlatformPlugin()->styleName();
- }
-
- static QString currentStyleName = stylename;
- if (QCoreApplication::startingUp()) {
- if (!stylename.isEmpty() && QApplicationPrivate::styleOverride.isNull())
- QApplicationPrivate::styleOverride = stylename;
- } else {
- if (currentStyleName != stylename) {
- currentStyleName = stylename;
- QApplication::setStyle(stylename);
- }
- }
-
- int num =
- settings.value(QLatin1String("doubleClickInterval"),
- QApplication::doubleClickInterval()).toInt();
- QApplication::setDoubleClickInterval(num);
-
- num =
- settings.value(QLatin1String("cursorFlashTime"),
- QApplication::cursorFlashTime()).toInt();
- QApplication::setCursorFlashTime(num);
-
-#ifndef QT_NO_WHEELEVENT
- num =
- settings.value(QLatin1String("wheelScrollLines"),
- QApplication::wheelScrollLines()).toInt();
- QApplication::setWheelScrollLines(num);
-#endif
-
- QString colorspec = settings.value(QLatin1String("colorSpec"),
- QVariant(QLatin1String("default"))).toString();
- if (colorspec == QLatin1String("normal"))
- QApplication::setColorSpec(QApplication::NormalColor);
- else if (colorspec == QLatin1String("custom"))
- QApplication::setColorSpec(QApplication::CustomColor);
- else if (colorspec == QLatin1String("many"))
- QApplication::setColorSpec(QApplication::ManyColor);
- else if (colorspec != QLatin1String("default"))
- colorspec = QLatin1String("default");
-
- QString defaultcodec = settings.value(QLatin1String("defaultCodec"),
- QVariant(QLatin1String("none"))).toString();
- if (defaultcodec != QLatin1String("none")) {
- QTextCodec *codec = QTextCodec::codecForName(defaultcodec.toLatin1());
- if (codec)
- QTextCodec::setCodecForTr(codec);
- }
-
- int w = settings.value(QLatin1String("globalStrut/width")).toInt();
- int h = settings.value(QLatin1String("globalStrut/height")).toInt();
- QSize strut(w, h);
- if (strut.isValid())
- QApplication::setGlobalStrut(strut);
-
- QStringList effects = settings.value(QLatin1String("GUIEffects")).toStringList();
- QApplication::setEffectEnabled(Qt::UI_General,
- effects.contains(QLatin1String("general")));
- QApplication::setEffectEnabled(Qt::UI_AnimateMenu,
- effects.contains(QLatin1String("animatemenu")));
- QApplication::setEffectEnabled(Qt::UI_FadeMenu,
- effects.contains(QLatin1String("fademenu")));
- QApplication::setEffectEnabled(Qt::UI_AnimateCombo,
- effects.contains(QLatin1String("animatecombo")));
- QApplication::setEffectEnabled(Qt::UI_AnimateTooltip,
- effects.contains(QLatin1String("animatetooltip")));
- QApplication::setEffectEnabled(Qt::UI_FadeTooltip,
- effects.contains(QLatin1String("fadetooltip")));
- QApplication::setEffectEnabled(Qt::UI_AnimateToolBox,
- effects.contains(QLatin1String("animatetoolbox")));
-
- if (!X11->has_fontconfig) {
- settings.beginGroup(QLatin1String("Font Substitutions"));
- QStringList fontsubs = settings.childKeys();
- if (!fontsubs.isEmpty()) {
- QStringList::Iterator it = fontsubs.begin();
- for (; it != fontsubs.end(); ++it) {
- QString fam = *it;
- QStringList subs = settings.value(fam).toStringList();
- QFont::insertSubstitutions(fam, subs);
- }
- }
- settings.endGroup();
- }
-
- qt_use_rtl_extensions =
- settings.value(QLatin1String("useRtlExtensions"), false).toBool();
-
-#ifndef QT_NO_XIM
- if (qt_xim_preferred_style == 0) {
- QString ximInputStyle = settings.value(QLatin1String("XIMInputStyle"),
- QVariant(QLatin1String("on the spot"))).toString().toLower();
- if (ximInputStyle == QLatin1String("on the spot"))
- qt_xim_preferred_style = XIMPreeditCallbacks | XIMStatusNothing;
- else if (ximInputStyle == QLatin1String("over the spot"))
- qt_xim_preferred_style = XIMPreeditPosition | XIMStatusNothing;
- else if (ximInputStyle == QLatin1String("off the spot"))
- qt_xim_preferred_style = XIMPreeditArea | XIMStatusArea;
- else if (ximInputStyle == QLatin1String("root"))
- qt_xim_preferred_style = XIMPreeditNothing | XIMStatusNothing;
- }
-#endif
- QStringList inputMethods = QInputContextFactory::keys();
- if (inputMethods.size() > 2 && inputMethods.contains(QLatin1String("imsw-multi"))) {
- X11->default_im = QLatin1String("imsw-multi");
- } else {
- X11->default_im = settings.value(QLatin1String("DefaultInputMethod"),
- QLatin1String("xim")).toString();
- }
-
- settings.endGroup(); // Qt
-
- return true;
-}
-
-
-/*! \internal
- Resets the QApplication::instance() pointer to zero
-*/
-void QApplicationPrivate::reset_instance_pointer()
-{ QApplication::self = 0; }
-
-
-// read the _QT_INPUT_ENCODING property and apply the settings to
-// the application
-static void qt_set_input_encoding()
-{
- Atom type;
- int format;
- ulong nitems, after = 1;
- unsigned char *data = 0;
-
- int e = XGetWindowProperty(X11->display, QX11Info::appRootWindow(),
- ATOM(_QT_INPUT_ENCODING), 0, 1024,
- False, XA_STRING, &type, &format, &nitems,
- &after, &data);
- if (e != Success || !nitems || type == XNone) {
- // Always use the locale codec, since we have no examples of non-local
- // XIMs, and since we cannot get a sensible answer about the encoding
- // from the XIM.
- qt_input_mapper = QTextCodec::codecForLocale();
-
- } else {
- if (!qstricmp((char *)data, "locale"))
- qt_input_mapper = QTextCodec::codecForLocale();
- else
- qt_input_mapper = QTextCodec::codecForName((char *)data);
- // make sure we have an input codec
- if(!qt_input_mapper)
- qt_input_mapper = QTextCodec::codecForName("ISO 8859-1");
- }
- if (qt_input_mapper && qt_input_mapper->mibEnum() == 11) // 8859-8
- qt_input_mapper = QTextCodec::codecForName("ISO 8859-8-I");
- if(data)
- XFree((char *)data);
-}
-
-// set font, foreground and background from x11 resources. The
-// arguments may override the resource settings.
-static void qt_set_x11_resources(const char* font = 0, const char* fg = 0,
- const char* bg = 0, const char* button = 0)
-{
-
- QString resFont, resFG, resBG, resButton, resEF, sysFont, selectBackground, selectForeground;
-
- QApplication::setEffectEnabled(Qt::UI_General, false);
- QApplication::setEffectEnabled(Qt::UI_AnimateMenu, false);
- QApplication::setEffectEnabled(Qt::UI_FadeMenu, false);
- QApplication::setEffectEnabled(Qt::UI_AnimateCombo, false);
- QApplication::setEffectEnabled(Qt::UI_AnimateTooltip, false);
- QApplication::setEffectEnabled(Qt::UI_FadeTooltip, false);
- QApplication::setEffectEnabled(Qt::UI_AnimateToolBox, false);
-
- bool paletteAlreadySet = false;
- if (QApplication::desktopSettingsAware()) {
- // first, read from settings
- QApplicationPrivate::x11_apply_settings();
- // the call to QApplication::style() below creates the system
- // palette, which breaks the logic after the RESOURCE_MANAGER
- // loop... so I have to save this value to be able to use it later
- paletteAlreadySet = (QApplicationPrivate::sys_pal != 0);
-
- // second, parse the RESOURCE_MANAGER property
- int format;
- ulong nitems, after = 1;
- QString res;
- long offset = 0;
- Atom type = XNone;
-
- while (after > 0) {
- uchar *data = 0;
- if (XGetWindowProperty(X11->display, QX11Info::appRootWindow(0),
- ATOM(RESOURCE_MANAGER),
- offset, 8192, False, AnyPropertyType,
- &type, &format, &nitems, &after,
- &data) != Success) {
- res = QString();
- break;
- }
- if (type == XA_STRING)
- res += QString::fromLatin1((char*)data);
- else
- res += QString::fromLocal8Bit((char*)data);
- offset += 2048; // offset is in 32bit quantities... 8192/4 == 2048
- if (data)
- XFree((char *)data);
- }
-
- QString key, value;
- int l = 0, r;
- QString apn = QString::fromLocal8Bit(appName);
- QString apc = QString::fromLocal8Bit(appClass);
- int apnl = apn.length();
- int apcl = apc.length();
- int resl = res.length();
-
- while (l < resl) {
- r = res.indexOf(QLatin1Char('\n'), l);
- if (r < 0)
- r = resl;
- while (res.at(l).isSpace())
- l++;
- bool mine = false;
- QChar sc = res.at(l + 1);
- if (res.at(l) == QLatin1Char('*') &&
- (sc == QLatin1Char('f') || sc == QLatin1Char('b') || sc == QLatin1Char('g') ||
- sc == QLatin1Char('F') || sc == QLatin1Char('B') || sc == QLatin1Char('G') ||
- sc == QLatin1Char('s') || sc == QLatin1Char('S')
- // capital T only, since we're looking for "Text.selectSomething"
- || sc == QLatin1Char('T'))) {
- // OPTIMIZED, since we only want "*[fbgsT].."
- QString item = res.mid(l, r - l).simplified();
- int i = item.indexOf(QLatin1Char(':'));
- key = item.left(i).trimmed().mid(1).toLower();
- value = item.right(item.length() - i - 1).trimmed();
- mine = true;
- } else if ((apnl && res.at(l) == apn.at(0)) || (appClass && apcl && res.at(l) == apc.at(0))) {
- if (res.mid(l,apnl) == apn && (res.at(l+apnl) == QLatin1Char('.')
- || res.at(l+apnl) == QLatin1Char('*'))) {
- QString item = res.mid(l, r - l).simplified();
- int i = item.indexOf(QLatin1Char(':'));
- key = item.left(i).trimmed().mid(apnl+1).toLower();
- value = item.right(item.length() - i - 1).trimmed();
- mine = true;
- } else if (res.mid(l,apcl) == apc && (res.at(l+apcl) == QLatin1Char('.')
- || res.at(l+apcl) == QLatin1Char('*'))) {
- QString item = res.mid(l, r - l).simplified();
- int i = item.indexOf(QLatin1Char(':'));
- key = item.left(i).trimmed().mid(apcl+1).toLower();
- value = item.right(item.length() - i - 1).trimmed();
- mine = true;
- }
- }
-
- if (mine) {
- if (!font && key == QLatin1String("systemfont"))
- sysFont = value.left(value.lastIndexOf(QLatin1Char(':')));
- if (!font && key == QLatin1String("font"))
- resFont = value;
- else if (!fg && !paletteAlreadySet) {
- if (key == QLatin1String("foreground"))
- resFG = value;
- else if (!bg && key == QLatin1String("background"))
- resBG = value;
- else if (!bg && !button && key == QLatin1String("button.background"))
- resButton = value;
- else if (key == QLatin1String("text.selectbackground")) {
- selectBackground = value;
- } else if (key == QLatin1String("text.selectforeground")) {
- selectForeground = value;
- }
- } else if (key == QLatin1String("guieffects"))
- resEF = value;
- // NOTE: if you add more, change the [fbg] stuff above
- }
-
- l = r + 1;
- }
- }
- if (!sysFont.isEmpty())
- resFont = sysFont;
- if (resFont.isEmpty())
- resFont = QString::fromLocal8Bit(font);
- if (resFG.isEmpty())
- resFG = QString::fromLocal8Bit(fg);
- if (resBG.isEmpty())
- resBG = QString::fromLocal8Bit(bg);
- if (resButton.isEmpty())
- resButton = QString::fromLocal8Bit(button);
- if (!resFont.isEmpty()
- && !X11->has_fontconfig
- && !QApplicationPrivate::sys_font) {
- // set application font
- QFont fnt;
- fnt.setRawName(resFont);
-
- // the font we get may actually be an alias for another font,
- // so we reset the application font to the real font info.
- if (! fnt.exactMatch()) {
- QFontInfo fontinfo(fnt);
- fnt.setFamily(fontinfo.family());
- fnt.setRawMode(fontinfo.rawMode());
-
- if (! fnt.rawMode()) {
- fnt.setItalic(fontinfo.italic());
- fnt.setWeight(fontinfo.weight());
- fnt.setUnderline(fontinfo.underline());
- fnt.setStrikeOut(fontinfo.strikeOut());
- fnt.setStyleHint(fontinfo.styleHint());
-
- if (fnt.pointSize() <= 0 && fnt.pixelSize() <= 0) {
- // size is all wrong... fix it
- qreal pointSize = fontinfo.pixelSize() * 72. / (float) QX11Info::appDpiY();
- if (pointSize <= 0)
- pointSize = 12;
- fnt.setPointSize(qRound(pointSize));
- }
- }
- }
-
- QApplicationPrivate::setSystemFont(fnt);
- }
- // QGtkStyle sets it's own system palette
- bool gtkStyle = QApplicationPrivate::app_style && QApplicationPrivate::app_style->inherits("QGtkStyle");
- bool kdeColors = (QApplication::desktopSettingsAware() && X11->desktopEnvironment == DE_KDE);
- if (!gtkStyle && (kdeColors || (button || !resBG.isEmpty() || !resFG.isEmpty()))) {// set app colors
- bool allowX11ColorNames = QColor::allowX11ColorNames();
- QColor::setAllowX11ColorNames(true);
-
- (void) QApplication::style(); // trigger creation of application style and system palettes
- QColor btn;
- QColor bg;
- QColor fg;
- QColor bfg;
- QColor wfg;
- if (!resBG.isEmpty())
- bg = QColor(resBG);
- if (!bg.isValid())
- bg = QApplicationPrivate::sys_pal->color(QPalette::Active, QPalette::Window);
-
- if (!resFG.isEmpty())
- fg = QColor(resFG);
- if (!fg.isValid())
- fg = QApplicationPrivate::sys_pal->color(QPalette::Active, QPalette::WindowText);
-
- if (!resButton.isEmpty())
- btn = QColor(resButton);
- else if (!resBG.isEmpty())
- btn = bg;
- if (!btn.isValid())
- btn = QApplicationPrivate::sys_pal->color(QPalette::Active, QPalette::Button);
-
- int h,s,v;
- fg.getHsv(&h,&s,&v);
- QColor base = Qt::white;
- bool bright_mode = false;
- if (v >= 255 - 50) {
- base = btn.darker(150);
- bright_mode = true;
- }
-
- QPalette pal(fg, btn, btn.lighter(125), btn.darker(130), btn.darker(120), wfg.isValid() ? wfg : fg, Qt::white, base, bg);
- QColor disabled((fg.red() + btn.red()) / 2,
- (fg.green() + btn.green())/ 2,
- (fg.blue() + btn.blue()) / 2);
- pal.setColorGroup(QPalette::Disabled, disabled, btn, btn.lighter(125),
- btn.darker(130), btn.darker(150), disabled, Qt::white, Qt::white, bg);
-
- QColor highlight, highlightText;
- if (!selectBackground.isEmpty() && !selectForeground.isEmpty()) {
- highlight = QColor(selectBackground);
- highlightText = QColor(selectForeground);
- }
-
- if (highlight.isValid() && highlightText.isValid()) {
- pal.setColor(QPalette::Highlight, highlight);
- pal.setColor(QPalette::HighlightedText, highlightText);
-
- // calculate disabled colors by removing saturation
- highlight.setHsv(highlight.hue(), 0, highlight.value(), highlight.alpha());
- highlightText.setHsv(highlightText.hue(), 0, highlightText.value(), highlightText.alpha());
- pal.setColor(QPalette::Disabled, QPalette::Highlight, highlight);
- pal.setColor(QPalette::Disabled, QPalette::HighlightedText, highlightText);
- } else if (bright_mode) {
- pal.setColor(QPalette::HighlightedText, base);
- pal.setColor(QPalette::Highlight, Qt::white);
- pal.setColor(QPalette::Disabled, QPalette::HighlightedText, base);
- pal.setColor(QPalette::Disabled, QPalette::Highlight, Qt::white);
- } else {
- pal.setColor(QPalette::HighlightedText, Qt::white);
- pal.setColor(QPalette::Highlight, Qt::darkBlue);
- pal.setColor(QPalette::Disabled, QPalette::HighlightedText, Qt::white);
- pal.setColor(QPalette::Disabled, QPalette::Highlight, Qt::darkBlue);
- }
-
- pal = qt_guiPlatformPlugin()->palette().resolve(pal);
- QApplicationPrivate::setSystemPalette(pal);
- QColor::setAllowX11ColorNames(allowX11ColorNames);
- }
-
- if (!resEF.isEmpty()) {
- QStringList effects = resEF.split(QLatin1Char(' '));
- QApplication::setEffectEnabled(Qt::UI_General, effects.contains(QLatin1String("general")));
- QApplication::setEffectEnabled(Qt::UI_AnimateMenu,
- effects.contains(QLatin1String("animatemenu")));
- QApplication::setEffectEnabled(Qt::UI_FadeMenu,
- effects.contains(QLatin1String("fademenu")));
- QApplication::setEffectEnabled(Qt::UI_AnimateCombo,
- effects.contains(QLatin1String("animatecombo")));
- QApplication::setEffectEnabled(Qt::UI_AnimateTooltip,
- effects.contains(QLatin1String("animatetooltip")));
- QApplication::setEffectEnabled(Qt::UI_FadeTooltip,
- effects.contains(QLatin1String("fadetooltip")));
- QApplication::setEffectEnabled(Qt::UI_AnimateToolBox,
- effects.contains(QLatin1String("animatetoolbox")));
- }
-
- QIconLoader::instance()->updateSystemTheme();
-}
-
-
-// update the supported array
-static void qt_get_net_supported()
-{
- Atom type;
- int format;
- long offset = 0;
- unsigned long nitems, after;
- unsigned char *data = 0;
-
- int e = XGetWindowProperty(X11->display, QX11Info::appRootWindow(),
- ATOM(_NET_SUPPORTED), 0, 0,
- False, XA_ATOM, &type, &format, &nitems, &after, &data);
- if (data)
- XFree(data);
-
- if (X11->net_supported_list)
- delete [] X11->net_supported_list;
- X11->net_supported_list = 0;
-
- if (e == Success && type == XA_ATOM && format == 32) {
- QBuffer ts;
- ts.open(QIODevice::WriteOnly);
-
- while (after > 0) {
- XGetWindowProperty(X11->display, QX11Info::appRootWindow(),
- ATOM(_NET_SUPPORTED), offset, 1024,
- False, XA_ATOM, &type, &format, &nitems, &after, &data);
-
- if (type == XA_ATOM && format == 32) {
- ts.write(reinterpret_cast<char *>(data), nitems * sizeof(long));
- offset += nitems;
- } else
- after = 0;
- if (data)
- XFree(data);
- }
-
- // compute nitems
- QByteArray buffer(ts.buffer());
- nitems = buffer.size() / sizeof(Atom);
- X11->net_supported_list = new Atom[nitems + 1];
- Atom *a = (Atom *) buffer.data();
- uint i;
- for (i = 0; i < nitems; i++)
- X11->net_supported_list[i] = a[i];
- X11->net_supported_list[nitems] = 0;
- }
-}
-
-
-bool QX11Data::isSupportedByWM(Atom atom)
-{
- if (!X11->net_supported_list)
- return false;
-
- bool supported = false;
- int i = 0;
- while (X11->net_supported_list[i] != 0) {
- if (X11->net_supported_list[i++] == atom) {
- supported = true;
- break;
- }
- }
-
- return supported;
-}
-
-
-// update the virtual roots array
-static void qt_get_net_virtual_roots()
-{
- if (X11->net_virtual_root_list)
- delete [] X11->net_virtual_root_list;
- X11->net_virtual_root_list = 0;
-
- if (!X11->isSupportedByWM(ATOM(_NET_VIRTUAL_ROOTS)))
- return;
-
- Atom type;
- int format;
- long offset = 0;
- unsigned long nitems, after;
- unsigned char *data;
-
- int e = XGetWindowProperty(X11->display, QX11Info::appRootWindow(),
- ATOM(_NET_VIRTUAL_ROOTS), 0, 0,
- False, XA_ATOM, &type, &format, &nitems, &after, &data);
- if (data)
- XFree(data);
-
- if (e == Success && type == XA_ATOM && format == 32) {
- QBuffer ts;
- ts.open(QIODevice::WriteOnly);
-
- while (after > 0) {
- XGetWindowProperty(X11->display, QX11Info::appRootWindow(),
- ATOM(_NET_VIRTUAL_ROOTS), offset, 1024,
- False, XA_ATOM, &type, &format, &nitems, &after, &data);
-
- if (type == XA_ATOM && format == 32) {
- ts.write(reinterpret_cast<char *>(data), nitems * 4);
- offset += nitems;
- } else
- after = 0;
- if (data)
- XFree(data);
- }
-
- // compute nitems
- QByteArray buffer(ts.buffer());
- nitems = buffer.size() / sizeof(Window);
- X11->net_virtual_root_list = new Window[nitems + 1];
- Window *a = (Window *) buffer.data();
- uint i;
- for (i = 0; i < nitems; i++)
- X11->net_virtual_root_list[i] = a[i];
- X11->net_virtual_root_list[nitems] = 0;
- }
-}
-
-void qt_net_remove_user_time(QWidget *tlw)
-{
- Q_ASSERT(tlw);
- QTLWExtra *extra = tlw->d_func()->maybeTopData();
- if (extra && extra->userTimeWindow) {
- Q_ASSERT(tlw->internalWinId());
- XDeleteProperty(X11->display, tlw->internalWinId(), ATOM(_NET_WM_USER_TIME_WINDOW));
- XDestroyWindow(X11->display, extra->userTimeWindow);
- extra->userTimeWindow = 0;
- }
-}
-
-void qt_net_update_user_time(QWidget *tlw, unsigned long timestamp)
-{
- Q_ASSERT(tlw);
- Q_ASSERT(tlw->isWindow());
- Q_ASSERT(tlw->testAttribute(Qt::WA_WState_Created));
- QTLWExtra *extra = tlw->d_func()->topData();
- WId wid = tlw->internalWinId();
- const bool isSupportedByWM = X11->isSupportedByWM(ATOM(_NET_WM_USER_TIME_WINDOW));
- if (extra->userTimeWindow || isSupportedByWM) {
- if (!extra->userTimeWindow) {
- extra->userTimeWindow = XCreateSimpleWindow(X11->display,
- tlw->internalWinId(),
- -1, -1, 1, 1, 0, 0, 0);
- wid = extra->userTimeWindow;
- XChangeProperty(X11->display, tlw->internalWinId(), ATOM(_NET_WM_USER_TIME_WINDOW),
- XA_WINDOW, 32, PropModeReplace,
- (unsigned char *)&wid, 1);
- XDeleteProperty(X11->display, tlw->internalWinId(), ATOM(_NET_WM_USER_TIME));
- } else if (!isSupportedByWM) {
- // WM no longer supports it, then we should remove the
- // _NET_WM_USER_TIME_WINDOW atom.
- qt_net_remove_user_time(tlw);
- } else {
- wid = extra->userTimeWindow;
- }
- }
- XChangeProperty(X11->display, wid, ATOM(_NET_WM_USER_TIME),
- XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &timestamp, 1);
-}
-
-static void qt_check_focus_model()
-{
- Window fw = XNone;
- int unused;
- XGetInputFocus(X11->display, &fw, &unused);
- if (fw == PointerRoot)
- X11->focus_model = QX11Data::FM_PointerRoot;
- else
- X11->focus_model = QX11Data::FM_Other;
-}
-
-#ifndef QT_NO_TABLET
-
-#if !defined (Q_OS_IRIX)
-// from include/Xwacom.h
-# define XWACOM_PARAM_TOOLID 322
-# define XWACOM_PARAM_TOOLSERIAL 323
-
-typedef WACOMCONFIG * (*PtrWacomConfigInit) (Display*, WACOMERRORFUNC);
-typedef WACOMDEVICE * (*PtrWacomConfigOpenDevice) (WACOMCONFIG*, const char*);
-typedef int *(*PtrWacomConfigGetRawParam) (WACOMDEVICE*, int, int*, int, unsigned*);
-typedef int (*PtrWacomConfigCloseDevice) (WACOMDEVICE *);
-typedef void (*PtrWacomConfigTerm) (WACOMCONFIG *);
-
-static PtrWacomConfigInit ptrWacomConfigInit = 0;
-static PtrWacomConfigOpenDevice ptrWacomConfigOpenDevice = 0;
-static PtrWacomConfigGetRawParam ptrWacomConfigGetRawParam = 0;
-static PtrWacomConfigCloseDevice ptrWacomConfigCloseDevice = 0;
-static PtrWacomConfigTerm ptrWacomConfigTerm = 0;
-Q_GLOBAL_STATIC(QByteArray, wacomDeviceName)
-#endif
-
-#endif
-
-/*****************************************************************************
- qt_init() - initializes Qt for X11
- *****************************************************************************/
-
-#if !defined(QT_NO_FONTCONFIG)
-static void getXDefault(const char *group, const char *key, int *val)
-{
- char *str = XGetDefault(X11->display, group, key);
- if (str) {
- char *end = 0;
- int v = strtol(str, &end, 0);
- if (str != end)
- *val = v;
- // otherwise use fontconfig to convert the string to integer
- else
- FcNameConstant((FcChar8 *) str, val);
- }
-}
-
-static void getXDefault(const char *group, const char *key, double *val)
-{
- char *str = XGetDefault(X11->display, group, key);
- if (str) {
- bool ok;
- double v = QByteArray(str).toDouble(&ok);
- if (ok)
- *val = v;
- }
-}
-
-static void getXDefault(const char *group, const char *key, bool *val)
-{
- char *str = XGetDefault(X11->display, group, key);
- if (str) {
- char c = str[0];
- if (isupper((int)c))
- c = tolower(c);
- if (c == 't' || c == 'y' || c == '1')
- *val = true;
- else if (c == 'f' || c == 'n' || c == '0')
- *val = false;
- if (c == 'o') {
- c = str[1];
- if (isupper((int)c))
- c = tolower(c);
- if (c == 'n')
- *val = true;
- if (c == 'f')
- *val = false;
- }
- }
-}
-#endif
-
-// ### This should be static but it isn't because of the friend declaration
-// ### in qpaintdevice.h which then should have a static too but can't have
-// ### it because "storage class specifiers invalid in friend function
-// ### declarations" :-) Ideas anyone?
-void qt_init(QApplicationPrivate *priv, int,
- Display *display, Qt::HANDLE visual, Qt::HANDLE colormap)
-{
- X11 = new QX11Data;
- X11->display = display;
- X11->displayName = 0;
- X11->foreignDisplay = (display != 0);
- X11->focus_model = -1;
-
- // RANDR
- X11->use_xrandr = false;
- X11->xrandr_major = 0;
- X11->xrandr_eventbase = 0;
- X11->xrandr_errorbase = 0;
-
- // RENDER
- X11->use_xrender = false;
- X11->xrender_major = 0;
- X11->xrender_version = 0;
-
- // XFIXES
- X11->use_xfixes = false;
- X11->xfixes_major = 0;
- X11->xfixes_eventbase = 0;
- X11->xfixes_errorbase = 0;
-
- // XInputExtension
- X11->use_xinput = false;
- X11->xinput_major = 0;
- X11->xinput_eventbase = 0;
- X11->xinput_errorbase = 0;
-
- X11->use_xkb = false;
- X11->xkb_major = 0;
- X11->xkb_eventbase = 0;
- X11->xkb_errorbase = 0;
-
- // MIT-SHM
- X11->use_mitshm = false;
- X11->use_mitshm_pixmaps = false;
- X11->mitshm_major = 0;
-
- X11->sip_serial = 0;
- X11->net_supported_list = 0;
- X11->net_virtual_root_list = 0;
- X11->wm_client_leader = 0;
- X11->screens = 0;
- X11->argbVisuals = 0;
- X11->argbColormaps = 0;
- X11->screenCount = 0;
- X11->time = CurrentTime;
- X11->userTime = CurrentTime;
- X11->ignore_badwindow = false;
- X11->seen_badwindow = false;
-
- X11->motifdnd_active = false;
-
- X11->default_im = QLatin1String("imsw-multi");
- priv->inputContext = 0;
-
- // colormap control
- X11->visual_class = -1;
- X11->visual_id = -1;
- X11->color_count = 0;
- X11->custom_cmap = false;
-
- // outside visual/colormap
- X11->visual = reinterpret_cast<Visual *>(visual);
- X11->colormap = colormap;
-
- // Fontconfig
- X11->has_fontconfig = false;
-#if !defined(QT_NO_FONTCONFIG)
- if (qgetenv("QT_X11_NO_FONTCONFIG").isNull())
- X11->has_fontconfig = FcInit();
- X11->fc_antialias = true;
-#endif
-
-#ifndef QT_NO_XRENDER
- memset(X11->solid_fills, 0, sizeof(X11->solid_fills));
- for (int i = 0; i < X11->solid_fill_count; ++i)
- X11->solid_fills[i].screen = -1;
- memset(X11->pattern_fills, 0, sizeof(X11->pattern_fills));
- for (int i = 0; i < X11->pattern_fill_count; ++i)
- X11->pattern_fills[i].screen = -1;
-#endif
-
- X11->startupId = 0;
-
- int argc = priv->argc;
- char **argv = priv->argv;
-
- if (X11->display) {
- // Qt part of other application
-
- // Set application name and class
- appName = qstrdup("Qt-subapplication");
- char *app_class = 0;
- if (argv) {
- const char* p = strrchr(argv[0], '/');
- app_class = qstrdup(p ? p + 1 : argv[0]);
- if (app_class[0])
- app_class[0] = toupper(app_class[0]);
- }
- appClass = app_class;
- } else {
- // Qt controls everything (default)
-
- // With the threaded QML renderer, we always need this.
- XInitThreads();
-
- // Set application name and class
- char *app_class = 0;
- if (argv && argv[0]) {
- const char *p = strrchr(argv[0], '/');
- appName = p ? p + 1 : argv[0];
- app_class = qstrdup(appName);
- if (app_class[0])
- app_class[0] = toupper(app_class[0]);
- }
- appClass = app_class;
- }
-
- // Install default error handlers
- original_x_errhandler = XSetErrorHandler(qt_x_errhandler);
- original_xio_errhandler = XSetIOErrorHandler(qt_xio_errhandler);
-
- // Get command line params
- int j = argc ? 1 : 0;
- for (int i=1; i<argc; i++) {
- if (argv[i] && *argv[i] != '-') {
- argv[j++] = argv[i];
- continue;
- }
- QByteArray arg(argv[i]);
- if (arg == "-display") {
- if (++i < argc && !X11->display)
- X11->displayName = argv[i];
- } else if (arg == "-fn" || arg == "-font") {
- if (++i < argc)
- appFont = argv[i];
- } else if (arg == "-bg" || arg == "-background") {
- if (++i < argc)
- appBGCol = argv[i];
- } else if (arg == "-btn" || arg == "-button") {
- if (++i < argc)
- appBTNCol = argv[i];
- } else if (arg == "-fg" || arg == "-foreground") {
- if (++i < argc)
- appFGCol = argv[i];
- } else if (arg == "-name") {
- if (++i < argc)
- appName = argv[i];
- } else if (arg == "-title") {
- if (++i < argc)
- mwTitle = argv[i];
- } else if (arg == "-geometry") {
- if (++i < argc)
- mwGeometry = argv[i];
- } else if (arg == "-im") {
- if (++i < argc)
- qt_ximServer = argv[i];
- } else if (arg == "-ncols") { // xv and netscape use this name
- if (++i < argc)
- X11->color_count = qMax(0,atoi(argv[i]));
- } else if (arg == "-visual") { // xv and netscape use this name
- if (++i < argc && !X11->visual) {
- QString s = QString::fromLocal8Bit(argv[i]).toLower();
- if (s == QLatin1String("staticgray"))
- X11->visual_class = StaticGray;
- else if (s == QLatin1String("grayscale"))
- X11->visual_class = XGrayScale;
- else if (s == QLatin1String("staticcolor"))
- X11->visual_class = StaticColor;
- else if (s == QLatin1String("pseudocolor"))
- X11->visual_class = PseudoColor;
- else if (s == QLatin1String("truecolor"))
- X11->visual_class = TrueColor;
- else if (s == QLatin1String("directcolor"))
- X11->visual_class = DirectColor;
- else
- X11->visual_id = static_cast<int>(strtol(argv[i], 0, 0));
- }
-#ifndef QT_NO_XIM
- } else if (arg == "-inputstyle") {
- if (++i < argc) {
- QString s = QString::fromLocal8Bit(argv[i]).toLower();
- if (s == QLatin1String("onthespot"))
- qt_xim_preferred_style = XIMPreeditCallbacks |
- XIMStatusNothing;
- else if (s == QLatin1String("overthespot"))
- qt_xim_preferred_style = XIMPreeditPosition |
- XIMStatusNothing;
- else if (s == QLatin1String("offthespot"))
- qt_xim_preferred_style = XIMPreeditArea |
- XIMStatusArea;
- else if (s == QLatin1String("root"))
- qt_xim_preferred_style = XIMPreeditNothing |
- XIMStatusNothing;
- }
-#endif
- } else if (arg == "-cmap") { // xv uses this name
- if (!X11->colormap)
- X11->custom_cmap = true;
- }
- else if (arg == "-sync")
- appSync = !appSync;
-#if defined(QT_DEBUG)
- else if (arg == "-nograb")
- appNoGrab = !appNoGrab;
- else if (arg == "-dograb")
- appDoGrab = !appDoGrab;
-#endif
- else
- argv[j++] = argv[i];
- }
-
- priv->argc = j;
-
-#if defined(QT_DEBUG) && defined(Q_OS_LINUX)
- if (!appNoGrab && !appDoGrab) {
- QString s;
- s.sprintf("/proc/%d/cmdline", getppid());
- QFile f(s);
- if (f.open(QIODevice::ReadOnly)) {
- s.clear();
- char c;
- while (f.getChar(&c) && c) {
- if (c == '/')
- s.clear();
- else
- s += QLatin1Char(c);
- }
- if (s == QLatin1String("gdb")) {
- appNoGrab = true;
- qDebug("Qt: gdb: -nograb added to command-line options.\n"
- "\t Use the -dograb option to enforce grabbing.");
- }
- f.close();
- }
- }
-#endif
-
- // Connect to X server
- if (qt_is_gui_used && !X11->display) {
- if ((X11->display = XOpenDisplay(X11->displayName)) == 0) {
- qWarning("%s: cannot connect to X server %s", appName,
- XDisplayName(X11->displayName));
- QApplicationPrivate::reset_instance_pointer();
- exit(1);
- }
-
- if (appSync) // if "-sync" argument
- XSynchronize(X11->display, true);
- }
-
- // Common code, regardless of whether display is foreign.
-
- // Get X parameters
-
- if (qt_is_gui_used) {
- X11->defaultScreen = DefaultScreen(X11->display);
- X11->screenCount = ScreenCount(X11->display);
-
- X11->screens = new QX11InfoData[X11->screenCount];
- X11->argbVisuals = new Visual *[X11->screenCount];
- X11->argbColormaps = new Colormap[X11->screenCount];
-
- for (int s = 0; s < X11->screenCount; s++) {
- QX11InfoData *screen = X11->screens + s;
- screen->ref = 1; // ensures it doesn't get deleted
- screen->screen = s;
-
- int widthMM = DisplayWidthMM(X11->display, s);
- if (widthMM != 0) {
- screen->dpiX = (DisplayWidth(X11->display, s) * 254 + widthMM * 5) / (widthMM * 10);
- } else {
- screen->dpiX = 72;
- }
-
- int heightMM = DisplayHeightMM(X11->display, s);
- if (heightMM != 0) {
- screen->dpiY = (DisplayHeight(X11->display, s) * 254 + heightMM * 5) / (heightMM * 10);
- } else {
- screen->dpiY = 72;
- }
-
- X11->argbVisuals[s] = 0;
- X11->argbColormaps[s] = 0;
- }
-
-
-#ifndef QT_NO_XRENDER
- int xrender_eventbase, xrender_errorbase;
- // See if XRender is supported on the connected display
- if (XQueryExtension(X11->display, "RENDER", &X11->xrender_major,
- &xrender_eventbase, &xrender_errorbase)
- && XRenderQueryExtension(X11->display, &xrender_eventbase,
- &xrender_errorbase)) {
- // Check the version as well - we need v0.4 or higher
- int major = 0;
- int minor = 0;
- XRenderQueryVersion(X11->display, &major, &minor);
- if (qgetenv("QT_X11_NO_XRENDER").isNull()) {
- X11->use_xrender = (major >= 0 && minor >= 5);
- X11->xrender_version = major*100+minor;
- // workaround for broken XServer on Ubuntu Breezy (6.8 compiled with 7.0
- // protocol headers)
- if (X11->xrender_version == 10
- && VendorRelease(X11->display) < 60900000
- && QByteArray(ServerVendor(X11->display)).contains("X.Org"))
- X11->xrender_version = 9;
- }
- }
-#endif // QT_NO_XRENDER
-
-#ifndef QT_NO_MITSHM
- int mitshm_minor;
- int mitshm_major;
- int mitshm_eventbase;
- int mitshm_errorbase;
- int mitshm_pixmaps;
- if (XQueryExtension(X11->display, "MIT-SHM", &X11->mitshm_major,
- &mitshm_eventbase, &mitshm_errorbase)
- && XShmQueryVersion(X11->display, &mitshm_major, &mitshm_minor,
- &mitshm_pixmaps))
- {
- QString displayName = QLatin1String(XDisplayName(NULL));
-
- // MITSHM only works for local displays, so do a quick check here
- // to determine whether the display is local or not (not 100 % accurate).
- // BGR server layouts are not supported either, since it requires the raster
- // engine to work on a QImage with BGR layout.
- bool local = displayName.isEmpty() || displayName.lastIndexOf(QLatin1Char(':')) == 0;
- if (local && (qgetenv("QT_X11_NO_MITSHM").toInt() == 0)) {
- Visual *defaultVisual = DefaultVisual(X11->display, DefaultScreen(X11->display));
- X11->use_mitshm = ((defaultVisual->red_mask == 0xff0000
- || defaultVisual->red_mask == 0xf800)
- && (defaultVisual->green_mask == 0xff00
- || defaultVisual->green_mask == 0x7e0)
- && (defaultVisual->blue_mask == 0xff
- || defaultVisual->blue_mask == 0x1f));
- X11->use_mitshm_pixmaps = X11->use_mitshm && mitshm_pixmaps;
- }
- }
-#endif // QT_NO_MITSHM
-
- // initialize the graphics system - order is imporant here - it must be done before
- // the QColormap::initialize() call
- QApplicationPrivate::graphics_system = QGraphicsSystemFactory::create(QApplicationPrivate::graphics_system_name);
- QColormap::initialize();
-
- // Support protocols
- X11->xdndSetup();
-
- // Finally create all atoms
- qt_x11_create_intern_atoms();
-
- // initialize NET lists
- qt_get_net_supported();
- qt_get_net_virtual_roots();
-
-#ifndef QT_NO_XRANDR
- // See if XRandR is supported on the connected display
- if (XQueryExtension(X11->display, "RANDR", &X11->xrandr_major,
- &X11->xrandr_eventbase, &X11->xrandr_errorbase)) {
-
-# ifdef QT_RUNTIME_XRANDR
- X11->ptrXRRSelectInput = 0;
- X11->ptrXRRUpdateConfiguration = 0;
- X11->ptrXRRRootToScreen = 0;
- X11->ptrXRRQueryExtension = 0;
- QLibrary xrandrLib(QLatin1String("Xrandr"), 2);
- if (!xrandrLib.load()) { // try without the version number
- xrandrLib.setFileName(QLatin1String("Xrandr"));
- xrandrLib.load();
- }
- if (xrandrLib.isLoaded()) {
- X11->ptrXRRSelectInput =
- (PtrXRRSelectInput) xrandrLib.resolve("XRRSelectInput");
- X11->ptrXRRUpdateConfiguration =
- (PtrXRRUpdateConfiguration) xrandrLib.resolve("XRRUpdateConfiguration");
- X11->ptrXRRRootToScreen =
- (PtrXRRRootToScreen) xrandrLib.resolve("XRRRootToScreen");
- X11->ptrXRRQueryExtension =
- (PtrXRRQueryExtension) xrandrLib.resolve("XRRQueryExtension");
- X11->ptrXRRSizes =
- (PtrXRRSizes) xrandrLib.resolve("XRRSizes");
- }
-# else
- X11->ptrXRRSelectInput = XRRSelectInput;
- X11->ptrXRRUpdateConfiguration = XRRUpdateConfiguration;
- X11->ptrXRRRootToScreen = XRRRootToScreen;
- X11->ptrXRRQueryExtension = XRRQueryExtension;
- X11->ptrXRRSizes = XRRSizes;
-# endif
-
- if (X11->ptrXRRQueryExtension
- && X11->ptrXRRQueryExtension(X11->display, &X11->xrandr_eventbase, &X11->xrandr_errorbase)) {
- // XRandR is supported
- X11->use_xrandr = true;
- }
- }
-#endif // QT_NO_XRANDR
-
-#ifndef QT_NO_XRENDER
- if (X11->use_xrender) {
- // XRender is supported, let's see if we have a PictFormat for the
- // default visual
- XRenderPictFormat *format =
- XRenderFindVisualFormat(X11->display,
- (Visual *) QX11Info::appVisual(X11->defaultScreen));
-
- if (!format) {
- X11->use_xrender = false;
- }
- }
-#endif // QT_NO_XRENDER
-
-#ifndef QT_NO_XFIXES
- // See if Xfixes is supported on the connected display
- if (XQueryExtension(X11->display, "XFIXES", &X11->xfixes_major,
- &X11->xfixes_eventbase, &X11->xfixes_errorbase)) {
- X11->ptrXFixesQueryExtension = XFIXES_LOAD_V1(XFixesQueryExtension);
- X11->ptrXFixesQueryVersion = XFIXES_LOAD_V1(XFixesQueryVersion);
- X11->ptrXFixesSetCursorName = XFIXES_LOAD_V2(XFixesSetCursorName);
- X11->ptrXFixesSelectSelectionInput = XFIXES_LOAD_V2(XFixesSelectSelectionInput);
-
- if(X11->ptrXFixesQueryExtension && X11->ptrXFixesQueryVersion
- && X11->ptrXFixesQueryExtension(X11->display, &X11->xfixes_eventbase,
- &X11->xfixes_errorbase)) {
- // Xfixes is supported.
- // Note: the XFixes protocol version is negotiated using QueryVersion.
- // We supply the highest version we support, the X server replies with
- // the highest version it supports, but no higher than the version we
- // asked for. The version sent back is the protocol version the X server
- // will use to talk us. If this call is removed, the behavior of the
- // X server when it receives an XFixes request is undefined.
- int major = 3;
- int minor = 0;
- X11->ptrXFixesQueryVersion(X11->display, &major, &minor);
- X11->use_xfixes = (major >= 1);
- X11->xfixes_major = major;
- }
- }
-#endif // QT_NO_XFIXES
-
-#ifndef QT_NO_XCURSOR
-#ifdef QT_RUNTIME_XCURSOR
- X11->ptrXcursorLibraryLoadCursor = 0;
- QLibrary xcursorLib(QLatin1String("Xcursor"), 1);
- bool xcursorFound = xcursorLib.load();
- if (!xcursorFound) { //try without the version number
- xcursorLib.setFileName(QLatin1String("Xcursor"));
- xcursorFound = xcursorLib.load();
- }
- if (xcursorFound) {
- X11->ptrXcursorLibraryLoadCursor =
- (PtrXcursorLibraryLoadCursor) xcursorLib.resolve("XcursorLibraryLoadCursor");
- }
-#else
- X11->ptrXcursorLibraryLoadCursor = XcursorLibraryLoadCursor;
-#endif // QT_RUNTIME_XCURSOR
-#endif // QT_NO_XCURSOR
-
-#ifndef QT_NO_XSYNC
- int xsync_evbase, xsync_errbase;
- int major, minor;
- if (XSyncQueryExtension(X11->display, &xsync_evbase, &xsync_errbase))
- XSyncInitialize(X11->display, &major, &minor);
-#endif // QT_NO_XSYNC
-
-#ifndef QT_NO_XINERAMA
-#ifdef QT_RUNTIME_XINERAMA
- X11->ptrXineramaQueryExtension = 0;
- X11->ptrXineramaIsActive = 0;
- X11->ptrXineramaQueryScreens = 0;
- QLibrary xineramaLib(QLatin1String("Xinerama"), 1);
- bool xineramaFound = xineramaLib.load();
- if (!xineramaFound) { //try without the version number
- xineramaLib.setFileName(QLatin1String("Xinerama"));
- xineramaFound = xineramaLib.load();
- }
- if (xineramaFound) {
- X11->ptrXineramaQueryExtension =
- (PtrXineramaQueryExtension) xineramaLib.resolve("XineramaQueryExtension");
- X11->ptrXineramaIsActive =
- (PtrXineramaIsActive) xineramaLib.resolve("XineramaIsActive");
- X11->ptrXineramaQueryScreens =
- (PtrXineramaQueryScreens) xineramaLib.resolve("XineramaQueryScreens");
- }
-#else
- X11->ptrXineramaQueryScreens = XineramaQueryScreens;
- X11->ptrXineramaIsActive = XineramaIsActive;
- X11->ptrXineramaQueryExtension = XineramaQueryExtension;
-#endif // QT_RUNTIME_XINERAMA
-#endif // QT_NO_XINERAMA
-
-#ifndef QT_NO_XINPUT
- // See if Xinput is supported on the connected display
- X11->ptrXCloseDevice = 0;
- X11->ptrXListInputDevices = 0;
- X11->ptrXOpenDevice = 0;
- X11->ptrXFreeDeviceList = 0;
- X11->ptrXSelectExtensionEvent = 0;
- X11->use_xinput = XQueryExtension(X11->display, "XInputExtension", &X11->xinput_major,
- &X11->xinput_eventbase, &X11->xinput_errorbase);
- if (X11->use_xinput) {
- X11->ptrXCloseDevice = XINPUT_LOAD(XCloseDevice);
- X11->ptrXListInputDevices = XINPUT_LOAD(XListInputDevices);
- X11->ptrXOpenDevice = XINPUT_LOAD(XOpenDevice);
- X11->ptrXFreeDeviceList = XINPUT_LOAD(XFreeDeviceList);
- X11->ptrXSelectExtensionEvent = XINPUT_LOAD(XSelectExtensionEvent);
- }
-#endif // QT_NO_XINPUT
-
-#ifndef QT_NO_XKB
- int xkblibMajor = XkbMajorVersion;
- int xkblibMinor = XkbMinorVersion;
- X11->use_xkb = XkbQueryExtension(X11->display,
- &X11->xkb_major,
- &X11->xkb_eventbase,
- &X11->xkb_errorbase,
- &xkblibMajor,
- &xkblibMinor);
- if (X11->use_xkb) {
- // If XKB is detected, set the GrabsUseXKBState option so input method
- // compositions continue to work (ie. deadkeys)
- unsigned int state = XkbPCF_GrabsUseXKBStateMask;
- (void) XkbSetPerClientControls(X11->display, state, &state);
-
- // select for group change events
- XkbSelectEventDetails(X11->display,
- XkbUseCoreKbd,
- XkbStateNotify,
- XkbAllStateComponentsMask,
- XkbGroupStateMask);
-
- // current group state is queried when creating the keymapper, no need to do it here
- }
-#endif
-
-
-#if !defined(QT_NO_FONTCONFIG)
- int dpi = 0;
- getXDefault("Xft", FC_DPI, &dpi);
- if (dpi) {
- for (int s = 0; s < ScreenCount(X11->display); ++s) {
- QX11Info::setAppDpiX(s, dpi);
- QX11Info::setAppDpiY(s, dpi);
- }
- }
- double fc_scale = 1.;
- getXDefault("Xft", FC_SCALE, &fc_scale);
- X11->fc_scale = fc_scale;
- for (int s = 0; s < ScreenCount(X11->display); ++s) {
- int subpixel = FC_RGBA_UNKNOWN;
-#if !defined(QT_NO_XRENDER) && (RENDER_MAJOR > 0 || RENDER_MINOR >= 6)
- if (X11->use_xrender) {
- int rsp = XRenderQuerySubpixelOrder(X11->display, s);
- switch (rsp) {
- default:
- case SubPixelUnknown:
- subpixel = FC_RGBA_UNKNOWN;
- break;
- case SubPixelHorizontalRGB:
- subpixel = FC_RGBA_RGB;
- break;
- case SubPixelHorizontalBGR:
- subpixel = FC_RGBA_BGR;
- break;
- case SubPixelVerticalRGB:
- subpixel = FC_RGBA_VRGB;
- break;
- case SubPixelVerticalBGR:
- subpixel = FC_RGBA_VBGR;
- break;
- case SubPixelNone:
- subpixel = FC_RGBA_NONE;
- break;
- }
- }
-#endif
-
- char *rgba = XGetDefault(X11->display, "Xft", FC_RGBA);
- if (rgba) {
- char *end = 0;
- int v = strtol(rgba, &end, 0);
- if (rgba != end) {
- subpixel = v;
- } else if (qstrncmp(rgba, "unknown", 7) == 0) {
- subpixel = FC_RGBA_UNKNOWN;
- } else if (qstrncmp(rgba, "rgb", 3) == 0) {
- subpixel = FC_RGBA_RGB;
- } else if (qstrncmp(rgba, "bgr", 3) == 0) {
- subpixel = FC_RGBA_BGR;
- } else if (qstrncmp(rgba, "vrgb", 4) == 0) {
- subpixel = FC_RGBA_VRGB;
- } else if (qstrncmp(rgba, "vbgr", 4) == 0) {
- subpixel = FC_RGBA_VBGR;
- } else if (qstrncmp(rgba, "none", 4) == 0) {
- subpixel = FC_RGBA_NONE;
- }
- }
- X11->screens[s].subpixel = subpixel;
- }
- getXDefault("Xft", FC_ANTIALIAS, &X11->fc_antialias);
-#ifdef FC_HINT_STYLE
- X11->fc_hint_style = -1;
- getXDefault("Xft", FC_HINT_STYLE, &X11->fc_hint_style);
-#endif
-#if 0
- // ###### these are implemented by Xft, not sure we need them
- getXDefault("Xft", FC_AUTOHINT, &X11->fc_autohint);
- getXDefault("Xft", FC_HINTING, &X11->fc_autohint);
- getXDefault("Xft", FC_MINSPACE, &X11->fc_autohint);
-#endif
-#endif // QT_NO_XRENDER
-
- // initialize key mapper
- QKeyMapper::changeKeyboard();
-
- // Misc. initialization
-#if 0 //disabled for now..
- QSegfaultHandler::initialize(priv->argv, priv->argc);
-#endif
- QCursorData::initialize();
- }
- QFont::initialize();
-
- if(qt_is_gui_used) {
- qApp->setObjectName(QString::fromLocal8Bit(appName));
-
- int screen;
- for (screen = 0; screen < X11->screenCount; ++screen) {
- XSelectInput(X11->display, QX11Info::appRootWindow(screen),
- KeymapStateMask | EnterWindowMask | LeaveWindowMask | PropertyChangeMask);
-
-#ifndef QT_NO_XRANDR
- if (X11->use_xrandr)
- X11->ptrXRRSelectInput(X11->display, QX11Info::appRootWindow(screen), True);
-#endif // QT_NO_XRANDR
- }
- }
-
- if (qt_is_gui_used) {
- // Attempt to determine the current running X11 Desktop Enviornment
- // Use dbus if/when we can, but fall back to using windowManagerName() for now
-
-#ifndef QT_NO_XFIXES
- if (X11->ptrXFixesSelectSelectionInput)
- X11->ptrXFixesSelectSelectionInput(X11->display, QX11Info::appRootWindow(), ATOM(_NET_WM_CM_S0),
- XFixesSetSelectionOwnerNotifyMask
- | XFixesSelectionWindowDestroyNotifyMask
- | XFixesSelectionClientCloseNotifyMask);
-#endif // QT_NO_XFIXES
- X11->compositingManagerRunning = XGetSelectionOwner(X11->display,
- ATOM(_NET_WM_CM_S0));
- X11->desktopEnvironment = DE_UNKNOWN;
- X11->desktopVersion = 0;
-
- Atom type;
- int format;
- unsigned long length, after;
- uchar *data = 0;
- int rc;
-
- do {
- if (!qgetenv("KDE_FULL_SESSION").isEmpty()) {
- X11->desktopEnvironment = DE_KDE;
- X11->desktopVersion = qgetenv("KDE_SESSION_VERSION").toInt();
- break;
- }
-
- if (qgetenv("DESKTOP_SESSION") == "gnome") {
- X11->desktopEnvironment = DE_GNOME;
- break;
- }
-
- // GNOME_DESKTOP_SESSION_ID is deprecated for some reason, but still check it
- if (!qgetenv("GNOME_DESKTOP_SESSION_ID").isEmpty()) {
- X11->desktopEnvironment = DE_GNOME;
- break;
- }
-
- rc = XGetWindowProperty(X11->display, QX11Info::appRootWindow(), ATOM(_DT_SAVE_MODE),
- 0, 2, False, XA_STRING, &type, &format, &length,
- &after, &data);
- if (rc == Success && length) {
- if (!strcmp(reinterpret_cast<char *>(data), "xfce4")) {
- // Pretend that xfce4 is gnome, as it uses the same libraries.
- // The detection above is stolen from xdg-open.
- X11->desktopEnvironment = DE_GNOME;
- break;
- }
-
- // We got the property but it wasn't xfce4. Free data before it gets overwritten.
- XFree(data);
- data = 0;
- }
-
- rc = XGetWindowProperty(X11->display, QX11Info::appRootWindow(), ATOM(DTWM_IS_RUNNING),
- 0, 1, False, AnyPropertyType, &type, &format, &length,
- &after, &data);
- if (rc == Success && length) {
- // DTWM is running, meaning most likely CDE is running...
- X11->desktopEnvironment = DE_CDE;
- break;
- }
-
- rc = XGetWindowProperty(X11->display, QX11Info::appRootWindow(),
- ATOM(_SGI_DESKS_MANAGER), 0, 1, False, XA_WINDOW,
- &type, &format, &length, &after, &data);
- if (rc == Success && length) {
- X11->desktopEnvironment = DE_4DWM;
- break;
- }
-
- if (XGetWindowProperty(X11->display, QX11Info::appRootWindow(),
- ATOM(_NET_SUPPORTING_WM_CHECK),
- 0, 1024, False, XA_WINDOW, &type,
- &format, &length, &after, &data) == Success) {
- if (type == XA_WINDOW && format == 32) {
- Window windowManagerWindow = *((Window*) data);
- XFree(data);
- data = 0;
-
- if (windowManagerWindow != XNone) {
- Atom utf8atom = ATOM(UTF8_STRING);
- if (XGetWindowProperty(QX11Info::display(), windowManagerWindow, ATOM(_NET_WM_NAME),
- 0, 1024, False, utf8atom, &type,
- &format, &length, &after, &data) == Success) {
- if (type == utf8atom && format == 8) {
- if (qstrcmp((const char *)data, "MCompositor") == 0)
- X11->desktopEnvironment = DE_MEEGO_COMPOSITOR;
- }
- }
- }
- }
- }
-
- } while(0);
-
- if (data)
- XFree((char *)data);
-
-#if !defined(QT_NO_STYLE_GTK)
- if (X11->desktopEnvironment == DE_GNOME) {
- static bool menusHaveIcons = QGtkStyle::getGConfBool(QLatin1String("/desktop/gnome/interface/menus_have_icons"), true);
- QApplication::setAttribute(Qt::AA_DontShowIconsInMenus, !menusHaveIcons);
- }
-#endif
- qt_set_input_encoding();
-
- qt_set_x11_resources(appFont, appFGCol, appBGCol, appBTNCol);
-
- // be smart about the size of the default font. most X servers have helvetica
- // 12 point available at 2 resolutions:
- // 75dpi (12 pixels) and 100dpi (17 pixels).
- // At 95 DPI, a 12 point font should be 16 pixels tall - in which case a 17
- // pixel font is a closer match than a 12 pixel font
- int ptsz = (X11->use_xrender
- ? 9
- : (int) (((QX11Info::appDpiY() >= 95 ? 17. : 12.) *
- 72. / (float) QX11Info::appDpiY()) + 0.5));
-
- if (!QApplicationPrivate::sys_font) {
- // no font from settings or RESOURCE_MANAGER, provide a fallback
- QFont f(X11->has_fontconfig ? QLatin1String("Sans Serif") : QLatin1String("Helvetica"),
- ptsz);
- QApplicationPrivate::setSystemFont(f);
- }
-
-#if !defined (QT_NO_TABLET)
- if (X11->use_xinput) {
- int ndev,
- i,
- j;
- bool gotStylus,
- gotEraser;
- XDeviceInfo *devices = 0, *devs;
- XInputClassInfo *ip;
- XAnyClassPtr any;
- XValuatorInfoPtr v;
- XAxisInfoPtr a;
- XDevice *dev = 0;
-
- if (X11->ptrXListInputDevices) {
- devices = X11->ptrXListInputDevices(X11->display, &ndev);
- if (!devices)
- qWarning("QApplication: Failed to get list of tablet devices");
- }
- if (!devices)
- ndev = -1;
- QTabletEvent::TabletDevice deviceType;
- for (devs = devices, i = 0; i < ndev && devs; i++, devs++) {
- dev = 0;
- deviceType = QTabletEvent::NoDevice;
- gotStylus = false;
- gotEraser = false;
-
-#if defined(Q_OS_IRIX)
- QString devName = QString::fromLocal8Bit(devs->name).toLower();
- if (devName == QLatin1String(WACOM_NAME)) {
- deviceType = QTabletEvent::Stylus;
- gotStylus = true;
- }
-#else
- if (devs->type == ATOM(XWacomStylus) || devs->type == ATOM(XTabletStylus)) {
- deviceType = QTabletEvent::Stylus;
- if (wacomDeviceName()->isEmpty())
- wacomDeviceName()->append(devs->name);
- gotStylus = true;
- } else if (devs->type == ATOM(XWacomEraser) || devs->type == ATOM(XTabletEraser)) {
- deviceType = QTabletEvent::XFreeEraser;
- gotEraser = true;
- }
-#endif
- if (deviceType == QTabletEvent::NoDevice)
- continue;
-
- if (gotStylus || gotEraser) {
- if (X11->ptrXOpenDevice)
- dev = X11->ptrXOpenDevice(X11->display, devs->id);
-
- if (!dev)
- continue;
-
- QTabletDeviceData device_data;
- device_data.deviceType = deviceType;
- device_data.eventCount = 0;
- device_data.device = dev;
- device_data.xinput_motion = -1;
- device_data.xinput_key_press = -1;
- device_data.xinput_key_release = -1;
- device_data.xinput_button_press = -1;
- device_data.xinput_button_release = -1;
- device_data.xinput_proximity_in = -1;
- device_data.xinput_proximity_out = -1;
- device_data.widgetToGetPress = 0;
-
- if (dev->num_classes > 0) {
- for (ip = dev->classes, j = 0; j < dev->num_classes;
- ip++, j++) {
- switch (ip->input_class) {
- case KeyClass:
- DeviceKeyPress(dev, device_data.xinput_key_press,
- device_data.eventList[device_data.eventCount]);
- if (device_data.eventList[device_data.eventCount])
- ++device_data.eventCount;
- DeviceKeyRelease(dev, device_data.xinput_key_release,
- device_data.eventList[device_data.eventCount]);
- if (device_data.eventList[device_data.eventCount])
- ++device_data.eventCount;
- break;
- case ButtonClass:
- DeviceButtonPress(dev, device_data.xinput_button_press,
- device_data.eventList[device_data.eventCount]);
- if (device_data.eventList[device_data.eventCount])
- ++device_data.eventCount;
- DeviceButtonRelease(dev, device_data.xinput_button_release,
- device_data.eventList[device_data.eventCount]);
- if (device_data.eventList[device_data.eventCount])
- ++device_data.eventCount;
- break;
- case ValuatorClass:
- // I'm only going to be interested in motion when the
- // stylus is already down anyway!
- DeviceMotionNotify(dev, device_data.xinput_motion,
- device_data.eventList[device_data.eventCount]);
- if (device_data.eventList[device_data.eventCount])
- ++device_data.eventCount;
- ProximityIn(dev, device_data.xinput_proximity_in, device_data.eventList[device_data.eventCount]);
- if (device_data.eventList[device_data.eventCount])
- ++device_data.eventCount;
- ProximityOut(dev, device_data.xinput_proximity_out, device_data.eventList[device_data.eventCount]);
- if (device_data.eventList[device_data.eventCount])
- ++device_data.eventCount;
- default:
- break;
- }
- }
- }
-
- // get the min/max value for pressure!
- any = (XAnyClassPtr) (devs->inputclassinfo);
- for (j = 0; j < devs->num_classes; j++) {
- if (any->c_class == ValuatorClass) {
- v = (XValuatorInfoPtr) any;
- a = (XAxisInfoPtr) ((char *) v +
- sizeof (XValuatorInfo));
-#if defined (Q_OS_IRIX)
- // I'm not exaclty wild about this, but the
- // dimensions of the tablet are more relevant here
- // than the min and max values from the axis
- // (actually it seems to be 2/3 or what is in the
- // axis. So we'll try to parse it from this
- // string. --tws
- char returnString[SGIDeviceRtrnLen];
- int tmp;
- if (XSGIMiscQueryExtension(X11->display, &tmp, &tmp)
- && XSGIDeviceQuery(X11->display, devs->id,
- "dimensions", returnString)) {
- QString str = QLatin1String(returnString);
- int comma = str.indexOf(',');
- device_data.minX = 0;
- device_data.minY = 0;
- device_data.maxX = str.left(comma).toInt();
- device_data.maxY = str.mid(comma + 1).toInt();
- } else {
- device_data.minX = a[WAC_XCOORD_I].min_value;
- device_data.maxX = a[WAC_XCOORD_I].max_value;
- device_data.minY = a[WAC_YCOORD_I].min_value;
- device_data.maxY = a[WAC_YCOORD_I].max_value;
- }
- device_data.minPressure = a[WAC_PRESSURE_I].min_value;
- device_data.maxPressure = a[WAC_PRESSURE_I].max_value;
- device_data.minTanPressure = a[WAC_TAN_PRESSURE_I].min_value;
- device_data.maxTanPressure = a[WAC_TAN_PRESSURE_I].max_value;
- device_data.minZ = a[WAC_ZCOORD_I].min_value;
- device_data.maxZ = a[WAC_ZCOORD_I].max_value;
-#else
- device_data.minX = a[0].min_value;
- device_data.maxX = a[0].max_value;
- device_data.minY = a[1].min_value;
- device_data.maxY = a[1].max_value;
- device_data.minPressure = a[2].min_value;
- device_data.maxPressure = a[2].max_value;
- device_data.minTanPressure = 0;
- device_data.maxTanPressure = 0;
- device_data.minZ = 0;
- device_data.maxZ = 0;
-#endif
-
- // got the max pressure no need to go further...
- break;
- }
- any = (XAnyClassPtr) ((char *) any + any->length);
- } // end of for loop
-
- tablet_devices()->append(device_data);
- } // if (gotStylus || gotEraser)
- }
- if (X11->ptrXFreeDeviceList)
- X11->ptrXFreeDeviceList(devices);
- }
-#endif // QT_NO_TABLET
-
- X11->startupId = getenv("DESKTOP_STARTUP_ID");
- if (X11->startupId) {
-#ifndef QT_NO_UNSETENV
- unsetenv("DESKTOP_STARTUP_ID");
-#else
- // it's a small memory leak, however we won't crash if Qt is
- // unloaded and someones tries to use the envoriment.
- putenv(strdup("DESKTOP_STARTUP_ID="));
-#endif
- }
- } else {
- // read some non-GUI settings when not using the X server...
-
- if (QApplication::desktopSettingsAware()) {
- QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
- settings.beginGroup(QLatin1String("Qt"));
-
- // read library (ie. plugin) path list
- QString libpathkey = QString::fromLatin1("%1.%2/libraryPath")
- .arg(QT_VERSION >> 16)
- .arg((QT_VERSION & 0xff00) >> 8);
- QStringList pathlist =
- settings.value(libpathkey).toString().split(QLatin1Char(':'));
- if (! pathlist.isEmpty()) {
- QStringList::ConstIterator it = pathlist.constBegin();
- while (it != pathlist.constEnd())
- QApplication::addLibraryPath(*it++);
- }
-
- QString defaultcodec = settings.value(QLatin1String("defaultCodec"),
- QVariant(QLatin1String("none"))).toString();
- if (defaultcodec != QLatin1String("none")) {
- QTextCodec *codec = QTextCodec::codecForName(defaultcodec.toLatin1());
- if (codec)
- QTextCodec::setCodecForTr(codec);
- }
-
- settings.endGroup(); // Qt
- }
- }
-
-#if !defined (Q_OS_IRIX) && !defined (QT_NO_TABLET)
- QLibrary wacom(QString::fromLatin1("wacomcfg"), 0); // version 0 is the latest release at time of writing this.
- // NOTE: C casts instead of reinterpret_cast for GCC 3.3.x
- ptrWacomConfigInit = (PtrWacomConfigInit)wacom.resolve("WacomConfigInit");
- ptrWacomConfigOpenDevice = (PtrWacomConfigOpenDevice)wacom.resolve("WacomConfigOpenDevice");
- ptrWacomConfigGetRawParam = (PtrWacomConfigGetRawParam)wacom.resolve("WacomConfigGetRawParam");
- ptrWacomConfigCloseDevice = (PtrWacomConfigCloseDevice)wacom.resolve("WacomConfigCloseDevice");
- ptrWacomConfigTerm = (PtrWacomConfigTerm)wacom.resolve("WacomConfigTerm");
-
- if (ptrWacomConfigInit == 0 || ptrWacomConfigOpenDevice == 0 || ptrWacomConfigGetRawParam == 0
- || ptrWacomConfigCloseDevice == 0 || ptrWacomConfigTerm == 0) { // either we have all, or we have none.
- ptrWacomConfigInit = 0;
- ptrWacomConfigOpenDevice = 0;
- ptrWacomConfigGetRawParam = 0;
- ptrWacomConfigCloseDevice = 0;
- ptrWacomConfigTerm = 0;
- }
-#endif
-}
-
-void QApplicationPrivate::initializeWidgetPaletteHash()
-{
-}
-
-/*****************************************************************************
- qt_cleanup() - cleans up when the application is finished
- *****************************************************************************/
-
-void qt_cleanup()
-{
- if (app_save_rootinfo) // root window must keep state
- qt_save_rootinfo();
-
- if (qt_is_gui_used) {
- QPixmapCache::clear();
- QCursorData::cleanup();
- QFont::cleanup();
- QColormap::cleanup();
-
-#if !defined (QT_NO_TABLET)
- QTabletDeviceDataList *devices = qt_tablet_devices();
- if (X11->ptrXCloseDevice)
- for (int i = 0; i < devices->size(); ++i)
- X11->ptrXCloseDevice(X11->display, (XDevice*)devices->at(i).device);
- devices->clear();
-#endif
- }
-
-#ifndef QT_NO_XRENDER
- for (int i = 0; i < X11->solid_fill_count; ++i) {
- if (X11->solid_fills[i].picture)
- XRenderFreePicture(X11->display, X11->solid_fills[i].picture);
- }
- for (int i = 0; i < X11->pattern_fill_count; ++i) {
- if (X11->pattern_fills[i].picture)
- XRenderFreePicture(X11->display, X11->pattern_fills[i].picture);
- }
-#endif
-
-#if !defined(QT_NO_IM)
- delete QApplicationPrivate::inputContext;
- QApplicationPrivate::inputContext = 0;
-#endif
-
- // Reset the error handlers
- if (qt_is_gui_used)
- XSync(X11->display, False); // sync first to process all possible errors
- XSetErrorHandler(original_x_errhandler);
- XSetIOErrorHandler(original_xio_errhandler);
-
- if (X11->argbColormaps) {
- for (int s = 0; s < X11->screenCount; s++) {
- if (X11->argbColormaps[s])
- XFreeColormap(X11->display, X11->argbColormaps[s]);
- }
- }
-
- if (qt_is_gui_used && !X11->foreignDisplay)
- XCloseDisplay(X11->display); // close X display
- X11->display = 0;
-
- delete [] X11->screens;
- delete [] X11->argbVisuals;
- delete [] X11->argbColormaps;
-
- if (X11->foreignDisplay) {
- delete [] (char *)appName;
- appName = 0;
- }
-
- delete [] (char *)appClass;
- appClass = 0;
-
- if (X11->net_supported_list)
- delete [] X11->net_supported_list;
- X11->net_supported_list = 0;
-
- if (X11->net_virtual_root_list)
- delete [] X11->net_virtual_root_list;
- X11->net_virtual_root_list = 0;
-
- delete X11;
- X11 = 0;
-}
-
-
-/*****************************************************************************
- Platform specific global and internal functions
- *****************************************************************************/
-
-void qt_save_rootinfo() // save new root info
-{
- Atom type;
- int format;
- unsigned long length, after;
- uchar *data = 0;
-
- if (ATOM(_XSETROOT_ID)) { // kill old pixmap
- if (XGetWindowProperty(X11->display, QX11Info::appRootWindow(),
- ATOM(_XSETROOT_ID), 0, 1,
- True, AnyPropertyType, &type, &format,
- &length, &after, &data) == Success) {
- if (type == XA_PIXMAP && format == 32 && length == 1 &&
- after == 0 && data) {
- XKillClient(X11->display, *((Pixmap*)data));
- }
- Pixmap dummy = XCreatePixmap(X11->display, QX11Info::appRootWindow(),
- 1, 1, 1);
- XChangeProperty(X11->display, QX11Info::appRootWindow(),
- ATOM(_XSETROOT_ID), XA_PIXMAP, 32,
- PropModeReplace, (uchar *)&dummy, 1);
- XSetCloseDownMode(X11->display, RetainPermanent);
- }
- }
- if (data)
- XFree((char *)data);
-}
-
-void qt_updated_rootinfo()
-{
- app_save_rootinfo = true;
-}
-
-// ### Cleanup, this function is not in use!
-bool qt_wstate_iconified(WId winid)
-{
- Atom type;
- int format;
- unsigned long length, after;
- uchar *data = 0;
- int r = XGetWindowProperty(X11->display, winid, ATOM(WM_STATE), 0, 2,
- False, AnyPropertyType, &type, &format,
- &length, &after, &data);
- bool iconic = false;
- if (r == Success && data && format == 32) {
- // quint32 *wstate = (quint32*)data;
- unsigned long *wstate = (unsigned long *) data;
- iconic = (*wstate == IconicState);
- XFree((char *)data);
- }
- return iconic;
-}
-
-QString QApplicationPrivate::appName() const
-{
- return QString::fromLocal8Bit(QT_PREPEND_NAMESPACE(appName));
-}
-
-const char *QX11Info::appClass() // get application class
-{
- return QT_PREPEND_NAMESPACE(appClass);
-}
-
-bool qt_nograb() // application no-grab option
-{
-#if defined(QT_DEBUG)
- return appNoGrab;
-#else
- return false;
-#endif
-}
-
-
-/*****************************************************************************
- Platform specific QApplication members
- *****************************************************************************/
-
-#ifdef QT3_SUPPORT
-void QApplication::setMainWidget(QWidget *mainWidget)
-{
-#ifndef QT_NO_DEBUG
- if (mainWidget && mainWidget->parentWidget() && mainWidget->isWindow())
- qWarning("QApplication::setMainWidget: New main widget (%s/%s) "
- "has a parent",
- mainWidget->metaObject()->className(), mainWidget->objectName().toLocal8Bit().constData());
-#endif
- if (mainWidget)
- mainWidget->d_func()->createWinId();
- QApplicationPrivate::main_widget = mainWidget;
- if (QApplicationPrivate::main_widget) // give WM command line
- QApplicationPrivate::applyX11SpecificCommandLineArguments(QApplicationPrivate::main_widget);
-}
-#endif
-
-void QApplicationPrivate::applyX11SpecificCommandLineArguments(QWidget *main_widget)
-{
- static bool beenHereDoneThat = false;
- if (beenHereDoneThat)
- return;
- beenHereDoneThat = true;
- Q_ASSERT(main_widget->testAttribute(Qt::WA_WState_Created));
- if (mwTitle) {
- XStoreName(X11->display, main_widget->effectiveWinId(), (char*)mwTitle);
- QByteArray net_wm_name = QString::fromLocal8Bit(mwTitle).toUtf8();
- XChangeProperty(X11->display, main_widget->effectiveWinId(), ATOM(_NET_WM_NAME), ATOM(UTF8_STRING), 8,
- PropModeReplace, (unsigned char *)net_wm_name.data(), net_wm_name.size());
- }
- if (mwGeometry) { // parse geometry
- int x, y;
- int w, h;
- int m = XParseGeometry((char*)mwGeometry, &x, &y, (uint*)&w, (uint*)&h);
- QSize minSize = main_widget->minimumSize();
- QSize maxSize = main_widget->maximumSize();
- if ((m & XValue) == 0)
- x = main_widget->geometry().x();
- if ((m & YValue) == 0)
- y = main_widget->geometry().y();
- if ((m & WidthValue) == 0)
- w = main_widget->width();
- if ((m & HeightValue) == 0)
- h = main_widget->height();
- w = qMin(w,maxSize.width());
- h = qMin(h,maxSize.height());
- w = qMax(w,minSize.width());
- h = qMax(h,minSize.height());
- if ((m & XNegative)) {
- x = QApplication::desktop()->width() + x - w;
- }
- if ((m & YNegative)) {
- y = QApplication::desktop()->height() + y - h;
- }
- main_widget->setGeometry(x, y, w, h);
- }
-}
-
-#ifndef QT_NO_CURSOR
-
-/*****************************************************************************
- QApplication cursor stack
- *****************************************************************************/
-
-void QApplication::setOverrideCursor(const QCursor &cursor)
-{
- qApp->d_func()->cursor_list.prepend(cursor);
-
- QWidgetList all = allWidgets();
- for (QWidgetList::ConstIterator it = all.constBegin(); it != all.constEnd(); ++it) {
- register QWidget *w = *it;
- if ((w->testAttribute(Qt::WA_SetCursor) || w->isWindow()) && (w->windowType() != Qt::Desktop))
- qt_x11_enforce_cursor(w);
- }
- XFlush(X11->display); // make X execute it NOW
-}
-
-void QApplication::restoreOverrideCursor()
-{
- if (qApp->d_func()->cursor_list.isEmpty())
- return;
- qApp->d_func()->cursor_list.removeFirst();
-
- if (QWidgetPrivate::mapper != 0 && !closingDown()) {
- QWidgetList all = allWidgets();
- for (QWidgetList::ConstIterator it = all.constBegin(); it != all.constEnd(); ++it) {
- register QWidget *w = *it;
- if ((w->testAttribute(Qt::WA_SetCursor) || w->isWindow()) && (w->windowType() != Qt::Desktop))
- qt_x11_enforce_cursor(w);
- }
- XFlush(X11->display);
- }
-}
-
-#endif
-
-
-/*****************************************************************************
- Routines to find a Qt widget from a screen position
- *****************************************************************************/
-
-Window QX11Data::findClientWindow(Window win, Atom property, bool leaf)
-{
- Atom type = XNone;
- int format, i;
- ulong nitems, after;
- uchar *data = 0;
- Window root, parent, target=0, *children=0;
- uint nchildren;
- if (XGetWindowProperty(X11->display, win, property, 0, 0, false, AnyPropertyType,
- &type, &format, &nitems, &after, &data) == Success) {
- if (data)
- XFree((char *)data);
- if (type)
- return win;
- }
- if (!XQueryTree(X11->display,win,&root,&parent,&children,&nchildren)) {
- if (children)
- XFree((char *)children);
- return 0;
- }
- for (i=nchildren-1; !target && i >= 0; i--)
- target = X11->findClientWindow(children[i], property, leaf);
- if (children)
- XFree((char *)children);
- return target;
-}
-
-QWidget *QApplication::topLevelAt(const QPoint &p)
-{
-#ifdef QT_NO_CURSOR
- Q_UNUSED(p);
- return 0;
-#else
- int screen = QCursor::x11Screen();
- int unused;
-
- int x = p.x();
- int y = p.y();
- Window target;
- if (!XTranslateCoordinates(X11->display,
- QX11Info::appRootWindow(screen),
- QX11Info::appRootWindow(screen),
- x, y, &unused, &unused, &target)) {
- return 0;
- }
- if (!target || target == QX11Info::appRootWindow(screen))
- return 0;
- QWidget *w;
- w = QWidget::find((WId)target);
-
- if (!w) {
- X11->ignoreBadwindow();
- target = X11->findClientWindow(target, ATOM(WM_STATE), true);
- if (X11->badwindow())
- return 0;
- w = QWidget::find((WId)target);
- if (!w) {
- // Perhaps the widget at (x,y) is inside a foreign application?
- // Search all toplevel widgets to see if one is within target
- QWidgetList list = QApplication::topLevelWidgets();
- for (int i = 0; i < list.count(); ++i) {
- QWidget *widget = list.at(i);
- Window ctarget = target;
- if (widget->isVisible() && !(widget->windowType() == Qt::Desktop)) {
- Q_ASSERT(widget->testAttribute(Qt::WA_WState_Created));
- Window wid = widget->internalWinId();
- while (ctarget && !w) {
- X11->ignoreBadwindow();
- if (!XTranslateCoordinates(X11->display,
- QX11Info::appRootWindow(screen),
- ctarget, x, y, &unused, &unused, &ctarget)
- || X11->badwindow())
- break;
- if (ctarget == wid) {
- // Found!
- w = widget;
- break;
- }
- }
- }
- if (w)
- break;
- }
- }
- }
- return w ? w->window() : 0;
-#endif
-}
-
-void QApplication::syncX()
-{
- if (X11->display)
- XSync(X11->display, False); // don't discard events
-}
-
-
-void QApplication::beep()
-{
- if (X11->display)
- XBell(X11->display, 0);
- else
- printf("\7");
-}
-
-void QApplication::alert(QWidget *widget, int msec)
-{
- if (!QApplicationPrivate::checkInstance("alert"))
- return;
-
- QWidgetList windowsToMark;
- if (!widget) {
- windowsToMark += topLevelWidgets();
- } else {
- windowsToMark.append(widget->window());
- }
-
- for (int i = 0; i < windowsToMark.size(); ++i) {
- QWidget *window = windowsToMark.at(i);
- if (!window->isActiveWindow()) {
- qt_change_net_wm_state(window, true, ATOM(_NET_WM_STATE_DEMANDS_ATTENTION));
- if (msec != 0) {
- QTimer *timer = new QTimer(qApp);
- timer->setSingleShot(true);
- connect(timer, SIGNAL(timeout()), qApp, SLOT(_q_alertTimeOut()));
- if (QTimer *oldTimer = qApp->d_func()->alertTimerHash.value(window)) {
- qApp->d_func()->alertTimerHash.remove(window);
- delete oldTimer;
- }
- qApp->d_func()->alertTimerHash.insert(window, timer);
- timer->start(msec);
- }
- }
- }
-}
-
-void QApplicationPrivate::_q_alertTimeOut()
-{
- if (QTimer *timer = qobject_cast<QTimer *>(q_func()->sender())) {
- QHash<QWidget *, QTimer *>::iterator it = alertTimerHash.begin();
- while (it != alertTimerHash.end()) {
- if (it.value() == timer) {
- QWidget *window = it.key();
- qt_change_net_wm_state(window, false, ATOM(_NET_WM_STATE_DEMANDS_ATTENTION));
- alertTimerHash.erase(it);
- timer->deleteLater();
- break;
- }
- ++it;
- }
- }
-}
-
-Qt::KeyboardModifiers QApplication::queryKeyboardModifiers()
-{
- Window root;
- Window child;
- int root_x, root_y, win_x, win_y;
- uint keybstate;
- for (int i = 0; i < ScreenCount(X11->display); ++i) {
- if (XQueryPointer(X11->display, QX11Info::appRootWindow(i), &root, &child,
- &root_x, &root_y, &win_x, &win_y, &keybstate))
- return X11->translateModifiers(keybstate & 0x00ff);
- }
- return 0;
-
-}
-
-/*****************************************************************************
- Special lookup functions for windows that have been reparented recently
- *****************************************************************************/
-
-static QWidgetMapper *wPRmapper = 0; // alternative widget mapper
-
-void qPRCreate(const QWidget *widget, Window oldwin)
-{ // QWidget::reparent mechanism
- if (!wPRmapper)
- wPRmapper = new QWidgetMapper;
-
- QETWidget *w = static_cast<QETWidget *>(const_cast<QWidget *>(widget));
- wPRmapper->insert((int)oldwin, w); // add old window to mapper
- w->setAttribute(Qt::WA_WState_Reparented); // set reparented flag
-}
-
-void qPRCleanup(QWidget *widget)
-{
- QETWidget *etw = static_cast<QETWidget *>(const_cast<QWidget *>(widget));
- if (!(wPRmapper && widget->testAttribute(Qt::WA_WState_Reparented)))
- return; // not a reparented widget
- QWidgetMapper::Iterator it = wPRmapper->begin();
- while (it != wPRmapper->constEnd()) {
- QWidget *w = *it;
- if (w == etw) { // found widget
- etw->setAttribute(Qt::WA_WState_Reparented, false); // clear flag
- it = wPRmapper->erase(it);// old window no longer needed
- } else {
- ++it;
- }
- }
- if (wPRmapper->size() == 0) { // became empty
- delete wPRmapper; // then reset alt mapper
- wPRmapper = 0;
- }
-}
-
-static QETWidget *qPRFindWidget(Window oldwin)
-{
- return wPRmapper ? (QETWidget*)wPRmapper->value((int)oldwin, 0) : 0;
-}
-
-int QApplication::x11ClientMessage(QWidget* w, XEvent* event, bool passive_only)
-{
- if (w && !w->internalWinId())
- return 0;
- QETWidget *widget = (QETWidget*)w;
- if (event->xclient.format == 32 && event->xclient.message_type) {
- if (event->xclient.message_type == ATOM(WM_PROTOCOLS)) {
- Atom a = event->xclient.data.l[0];
- if (a == ATOM(WM_DELETE_WINDOW)) {
- if (passive_only) return 0;
- widget->translateCloseEvent(event);
- }
- else if (a == ATOM(WM_TAKE_FOCUS)) {
- if ((ulong) event->xclient.data.l[1] > X11->time)
- X11->time = event->xclient.data.l[1];
- QWidget *amw = activeModalWidget();
- if (amw && amw->testAttribute(Qt::WA_X11DoNotAcceptFocus))
- amw = 0;
- if (amw && !QApplicationPrivate::tryModalHelper(widget, 0)) {
- QWidget *p = amw->parentWidget();
- while (p && p != widget)
- p = p->parentWidget();
- if (!p || !X11->net_supported_list)
- amw->raise(); // help broken window managers
- amw->activateWindow();
- }
-#ifndef QT_NO_WHATSTHIS
- } else if (a == ATOM(_NET_WM_CONTEXT_HELP)) {
- QWhatsThis::enterWhatsThisMode();
-#endif // QT_NO_WHATSTHIS
- } else if (a == ATOM(_NET_WM_PING)) {
- // avoid send/reply loops
- Window root = RootWindow(X11->display, w->x11Info().screen());
- if (event->xclient.window != root) {
- event->xclient.window = root;
- XSendEvent(event->xclient.display, event->xclient.window,
- False, SubstructureNotifyMask|SubstructureRedirectMask, event);
- }
-#ifndef QT_NO_XSYNC
- } else if (a == ATOM(_NET_WM_SYNC_REQUEST)) {
- const ulong timestamp = (const ulong) event->xclient.data.l[1];
- if (timestamp > X11->time)
- X11->time = timestamp;
- if (QTLWExtra *tlw = w->d_func()->maybeTopData()) {
- if (timestamp == CurrentTime || timestamp > tlw->syncRequestTimestamp) {
- tlw->syncRequestTimestamp = timestamp;
- tlw->newCounterValueLo = event->xclient.data.l[2];
- tlw->newCounterValueHi = event->xclient.data.l[3];
- }
- }
-#endif
- }
- } else if (event->xclient.message_type == ATOM(_QT_SCROLL_DONE)) {
- widget->translateScrollDoneEvent(event);
- } else if (event->xclient.message_type == ATOM(XdndPosition)) {
- X11->xdndHandlePosition(widget, event, passive_only);
- } else if (event->xclient.message_type == ATOM(XdndEnter)) {
- X11->xdndHandleEnter(widget, event, passive_only);
- } else if (event->xclient.message_type == ATOM(XdndStatus)) {
- X11->xdndHandleStatus(widget, event, passive_only);
- } else if (event->xclient.message_type == ATOM(XdndLeave)) {
- X11->xdndHandleLeave(widget, event, passive_only);
- } else if (event->xclient.message_type == ATOM(XdndDrop)) {
- X11->xdndHandleDrop(widget, event, passive_only);
- } else if (event->xclient.message_type == ATOM(XdndFinished)) {
- X11->xdndHandleFinished(widget, event, passive_only);
- } else {
- if (passive_only) return 0;
- // All other are interactions
- }
- } else {
- X11->motifdndHandle(widget, event, passive_only);
- }
-
- return 0;
-}
-
-int QApplication::x11ProcessEvent(XEvent* event)
-{
- Q_D(QApplication);
- QScopedLoopLevelCounter loopLevelCounter(d->threadData);
-
-#ifdef ALIEN_DEBUG
- //qDebug() << "QApplication::x11ProcessEvent:" << event->type;
-#endif
- switch (event->type) {
- case ButtonPress:
- pressed_window = event->xbutton.window;
- X11->userTime = event->xbutton.time;
- // fallthrough intended
- case ButtonRelease:
- X11->time = event->xbutton.time;
- break;
- case MotionNotify:
- X11->time = event->xmotion.time;
- break;
- case XKeyPress:
- X11->userTime = event->xkey.time;
- // fallthrough intended
- case XKeyRelease:
- X11->time = event->xkey.time;
- break;
- case PropertyNotify:
- X11->time = event->xproperty.time;
- break;
- case EnterNotify:
- case LeaveNotify:
- X11->time = event->xcrossing.time;
- break;
- case SelectionClear:
- X11->time = event->xselectionclear.time;
- break;
- default:
- break;
- }
-#ifndef QT_NO_XFIXES
- if (X11->use_xfixes && event->type == (X11->xfixes_eventbase + XFixesSelectionNotify)) {
- XFixesSelectionNotifyEvent *req =
- reinterpret_cast<XFixesSelectionNotifyEvent *>(event);
- X11->time = req->selection_timestamp;
- if (req->selection == ATOM(_NET_WM_CM_S0))
- X11->compositingManagerRunning = req->owner;
- }
-#endif
-
- QETWidget *widget = (QETWidget*)QWidget::find((WId)event->xany.window);
-
- if (wPRmapper) { // just did a widget reparent?
- if (widget == 0) { // not in std widget mapper
- switch (event->type) { // only for mouse/key events
- case ButtonPress:
- case ButtonRelease:
- case MotionNotify:
- case XKeyPress:
- case XKeyRelease:
- widget = qPRFindWidget(event->xany.window);
- break;
- }
- }
- else if (widget->testAttribute(Qt::WA_WState_Reparented))
- qPRCleanup(widget); // remove from alt mapper
- }
-
- QETWidget *keywidget=0;
- bool grabbed=false;
- if (event->type==XKeyPress || event->type==XKeyRelease) {
- keywidget = (QETWidget*)QWidget::keyboardGrabber();
- if (keywidget) {
- grabbed = true;
- } else if (!keywidget) {
- if (d->inPopupMode()) // no focus widget, see if we have a popup
- keywidget = (QETWidget*) (activePopupWidget()->focusWidget() ? activePopupWidget()->focusWidget() : activePopupWidget());
- else if (QApplicationPrivate::focus_widget)
- keywidget = (QETWidget*)QApplicationPrivate::focus_widget;
- else if (widget)
- keywidget = (QETWidget*)widget->window();
- }
- }
-
-#ifndef QT_NO_IM
- // Filtering input events by the input context. It has to be taken
- // place before any other key event consumers such as eventfilters
- // and accelerators because some input methods require quite
- // various key combination and sequences. It often conflicts with
- // accelerators and so on, so we must give the input context the
- // filtering opportunity first to ensure all input methods work
- // properly regardless of application design.
-
- if(keywidget && keywidget->isEnabled() && keywidget->testAttribute(Qt::WA_InputMethodEnabled)) {
- // block user interaction during session management
- if((event->type==XKeyPress || event->type==XKeyRelease) && qt_sm_blockUserInput)
- return true;
-
- // for XIM handling
- QInputContext *qic = keywidget->inputContext();
- if(qic && qic->x11FilterEvent(keywidget, event))
- return true;
-
- // filterEvent() accepts QEvent *event rather than preexpanded
- // key event attribute values. This is intended to pass other
- // QInputEvent in future. Other non IM-related events should
- // not be forwarded to input contexts to prevent weird event
- // handling.
- if ((event->type == XKeyPress || event->type == XKeyRelease)) {
- int code = -1;
- int count = 0;
- Qt::KeyboardModifiers modifiers;
- QEvent::Type type;
- QString text;
- KeySym keySym;
-
- qt_keymapper_private()->translateKeyEventInternal(keywidget, event, keySym, count,
- text, modifiers, code, type, false);
-
- // both key press/release is required for some complex
- // input methods. don't eliminate anything.
- QKeyEventEx keyevent(type, code, modifiers, text, false, qMax(qMax(count, 1), text.length()),
- event->xkey.keycode, keySym, event->xkey.state);
- if(qic && qic->filterEvent(&keyevent))
- return true;
- }
- } else
-#endif // QT_NO_IM
- {
- if (XFilterEvent(event, XNone))
- return true;
- }
-
- if (qt_x11EventFilter(event)) // send through app filter
- return 1;
-
- if (event->type == MappingNotify) {
- // keyboard mapping changed
- XRefreshKeyboardMapping(&event->xmapping);
-
- QKeyMapper::changeKeyboard();
- return 0;
- }
-#ifndef QT_NO_XKB
- else if (X11->use_xkb && event->type == X11->xkb_eventbase) {
- XkbAnyEvent *xkbevent = (XkbAnyEvent *) event;
- switch (xkbevent->xkb_type) {
- case XkbStateNotify:
- {
- XkbStateNotifyEvent *xkbstateevent = (XkbStateNotifyEvent *) xkbevent;
- if ((xkbstateevent->changed & XkbGroupStateMask) != 0) {
- qt_keymapper_private()->xkb_currentGroup = xkbstateevent->group;
- QKeyMapper::changeKeyboard();
- }
- break;
- }
- default:
- break;
- }
- }
-#endif
-
- if (!widget) { // don't know this windows
- QWidget* popup = QApplication::activePopupWidget();
- if (popup) {
-
- /*
- That is more than suboptimal. The real solution should
- do some keyevent and buttonevent translation, so that
- the popup still continues to work as the user expects.
- Unfortunately this translation is currently only
- possible with a known widget. I'll change that soon
- (Matthias).
- */
-
- // Danger - make sure we don't lock the server
- switch (event->type) {
- case ButtonPress:
- case ButtonRelease:
- case XKeyPress:
- case XKeyRelease:
- do {
- popup->close();
- } while ((popup = qApp->activePopupWidget()));
- return 1;
- }
- }
- return -1;
- }
-
- if (event->type == XKeyPress || event->type == XKeyRelease)
- widget = keywidget; // send XKeyEvents through keywidget->x11Event()
-
- if (app_do_modal) // modal event handling
- if (!qt_try_modal(widget, event)) {
- if (event->type == ClientMessage && !widget->x11Event(event))
- x11ClientMessage(widget, event, true);
- return 1;
- }
-
-
- if (widget->x11Event(event)) // send through widget filter
- return 1;
-#if !defined (QT_NO_TABLET)
- if (!qt_xdnd_dragging) {
- QTabletDeviceDataList *tablets = qt_tablet_devices();
- for (int i = 0; i < tablets->size(); ++i) {
- QTabletDeviceData &tab = tablets->operator [](i);
- if (event->type == tab.xinput_motion
- || event->type == tab.xinput_button_release
- || event->type == tab.xinput_button_press
- || event->type == tab.xinput_proximity_in
- || event->type == tab.xinput_proximity_out) {
- widget->translateXinputEvent(event, &tab);
- return 0;
- }
- }
- }
-#endif
-
-#ifndef QT_NO_XRANDR
- if (X11->use_xrandr && event->type == (X11->xrandr_eventbase + RRScreenChangeNotify)) {
- // update Xlib internals with the latest screen configuration
- X11->ptrXRRUpdateConfiguration(event);
-
- // update the size for desktop widget
- int scr = X11->ptrXRRRootToScreen(X11->display, event->xany.window);
- 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));
- QResizeEvent e(w->size(), oldSize);
- QApplication::sendEvent(w, &e);
- if (w != desktop)
- QApplication::sendEvent(desktop, &e);
- }
-#endif // QT_NO_XRANDR
-
-#ifndef QT_NO_XFIXES
- if (X11->use_xfixes && event->type == (X11->xfixes_eventbase + XFixesSelectionNotify)) {
- XFixesSelectionNotifyEvent *req = reinterpret_cast<XFixesSelectionNotifyEvent *>(event);
-
- // compress all XFixes events related to this selection
- // we don't want to handle old SelectionNotify events.
- qt_xfixes_selection_event_data xfixes_event;
- xfixes_event.selection = req->selection;
- for (XEvent ev;;) {
- if (!XCheckIfEvent(X11->display, &ev, &qt_xfixes_scanner, (XPointer)&xfixes_event))
- break;
- }
-
- if (req->selection == ATOM(CLIPBOARD)) {
- if (qt_xfixes_clipboard_changed(req->owner, req->selection_timestamp)) {
- emit clipboard()->changed(QClipboard::Clipboard);
- emit clipboard()->dataChanged();
- }
- } else if (req->selection == XA_PRIMARY) {
- if (qt_xfixes_selection_changed(req->owner, req->selection_timestamp)) {
- emit clipboard()->changed(QClipboard::Selection);
- emit clipboard()->selectionChanged();
- }
- }
- }
-#endif // QT_NO_XFIXES
-
- switch (event->type) {
-
- case ButtonRelease: // mouse event
- if (!d->inPopupMode() && !QWidget::mouseGrabber() && pressed_window != widget->internalWinId()
- && (widget = (QETWidget*) QWidget::find((WId)pressed_window)) == 0)
- break;
- // fall through intended
- case ButtonPress:
- if (event->xbutton.root != RootWindow(X11->display, widget->x11Info().screen())
- && ! qt_xdnd_dragging) {
- while (activePopupWidget())
- activePopupWidget()->close();
- return 1;
- }
- if (event->type == ButtonPress)
- qt_net_update_user_time(widget->window(), X11->userTime);
- // fall through intended
- case MotionNotify:
-#if !defined(QT_NO_TABLET)
- if (!qt_tabletChokeMouse) {
-#endif
- if (widget->testAttribute(Qt::WA_TransparentForMouseEvents)) {
- QPoint pos(event->xbutton.x, event->xbutton.y);
- pos = widget->d_func()->mapFromWS(pos);
- QWidget *window = widget->window();
- pos = widget->mapTo(window, pos);
- if (QWidget *child = window->childAt(pos)) {
- widget = static_cast<QETWidget *>(child);
- pos = child->mapFrom(window, pos);
- event->xbutton.x = pos.x();
- event->xbutton.y = pos.y();
- }
- }
- widget->translateMouseEvent(event);
-#if !defined(QT_NO_TABLET)
- } else {
- qt_tabletChokeMouse = false;
- }
-#endif
- break;
-
- case XKeyPress: // keyboard event
- qt_net_update_user_time(widget->window(), X11->userTime);
- // fallthrough intended
- case XKeyRelease:
- {
- if (keywidget && keywidget->isEnabled()) { // should always exist
- // qDebug("sending key event");
- qt_keymapper_private()->translateKeyEvent(keywidget, event, grabbed);
- }
- break;
- }
-
- case GraphicsExpose:
- case Expose: // paint event
- widget->translatePaintEvent(event);
- break;
-
- case ConfigureNotify: // window move/resize event
- if (event->xconfigure.event == event->xconfigure.window)
- widget->translateConfigEvent(event);
- break;
-
- case XFocusIn: { // got focus
- if ((widget->windowType() == Qt::Desktop))
- break;
- if (d->inPopupMode()) // some delayed focus event to ignore
- break;
- if (!widget->isWindow())
- break;
- if (event->xfocus.detail != NotifyAncestor &&
- event->xfocus.detail != NotifyInferior &&
- event->xfocus.detail != NotifyNonlinear)
- break;
- setActiveWindow(widget);
- if (X11->focus_model == QX11Data::FM_PointerRoot) {
- // We got real input focus from somewhere, but we were in PointerRoot
- // mode, so we don't trust this event. Check the focus model to make
- // sure we know what focus mode we are using...
- qt_check_focus_model();
- }
- }
- break;
-
- case XFocusOut: // lost focus
- if ((widget->windowType() == Qt::Desktop))
- break;
- if (!widget->isWindow())
- break;
- if (event->xfocus.mode == NotifyGrab) {
- qt_xfocusout_grab_counter++;
- break;
- }
- if (event->xfocus.detail != NotifyAncestor &&
- event->xfocus.detail != NotifyNonlinearVirtual &&
- event->xfocus.detail != NotifyNonlinear)
- break;
- if (!d->inPopupMode() && widget == QApplicationPrivate::active_window) {
- XEvent ev;
- bool focus_will_change = false;
- if (XCheckTypedEvent(X11->display, XFocusIn, &ev)) {
- // we're about to get an XFocusIn, if we know we will
- // get a new active window, we don't want to set the
- // active window to 0 now
- QWidget *w2 = QWidget::find(ev.xany.window);
- if (w2
- && w2->windowType() != Qt::Desktop
- && !d->inPopupMode() // some delayed focus event to ignore
- && w2->isWindow()
- && (ev.xfocus.detail == NotifyAncestor
- || ev.xfocus.detail == NotifyInferior
- || ev.xfocus.detail == NotifyNonlinear))
- focus_will_change = true;
-
- XPutBackEvent(X11->display, &ev);
- }
- if (!focus_will_change)
- setActiveWindow(0);
- }
- break;
-
- case EnterNotify: { // enter window
- if (QWidget::mouseGrabber() && (!d->inPopupMode() || widget->window() != activePopupWidget()))
- break;
- if ((event->xcrossing.mode != NotifyNormal
- && event->xcrossing.mode != NotifyUngrab)
- || event->xcrossing.detail == NotifyVirtual
- || event->xcrossing.detail == NotifyNonlinearVirtual)
- break;
- if (event->xcrossing.focus &&
- !(widget->windowType() == Qt::Desktop) && !widget->isActiveWindow()) {
- if (X11->focus_model == QX11Data::FM_Unknown) // check focus model
- qt_check_focus_model();
- if (X11->focus_model == QX11Data::FM_PointerRoot) // PointerRoot mode
- setActiveWindow(widget);
- }
-
- if (qt_button_down && !d->inPopupMode())
- break;
-
- QWidget *alien = widget->childAt(widget->d_func()->mapFromWS(QPoint(event->xcrossing.x,
- event->xcrossing.y)));
- QWidget *enter = alien ? alien : widget;
- QWidget *leave = 0;
- if (qt_last_mouse_receiver && !qt_last_mouse_receiver->internalWinId())
- leave = qt_last_mouse_receiver;
- else
- leave = QWidget::find(curWin);
-
- // ### Alien: enter/leave might be wrong here with overlapping siblings
- // if the enter widget is native and stacked under a non-native widget.
- QApplicationPrivate::dispatchEnterLeave(enter, leave);
- curWin = widget->internalWinId();
- qt_last_mouse_receiver = enter;
- if (!d->inPopupMode() || widget->window() == activePopupWidget())
- widget->translateMouseEvent(event); //we don't get MotionNotify, emulate it
- }
- break;
- case LeaveNotify: { // leave window
- QWidget *mouseGrabber = QWidget::mouseGrabber();
- if (mouseGrabber && !d->inPopupMode())
- break;
- if (curWin && widget->internalWinId() != curWin)
- break;
- if ((event->xcrossing.mode != NotifyNormal
- && event->xcrossing.mode != NotifyUngrab)
- || event->xcrossing.detail == NotifyInferior)
- break;
- if (!(widget->windowType() == Qt::Desktop))
- widget->translateMouseEvent(event); //we don't get MotionNotify, emulate it
-
- QWidget* enter = 0;
- QPoint enterPoint;
- XEvent ev;
- while (XCheckMaskEvent(X11->display, EnterWindowMask | LeaveWindowMask , &ev)
- && !qt_x11EventFilter(&ev)) {
- QWidget* event_widget = QWidget::find(ev.xcrossing.window);
- if(event_widget && event_widget->x11Event(&ev))
- break;
- if (ev.type == LeaveNotify
- || (ev.xcrossing.mode != NotifyNormal
- && ev.xcrossing.mode != NotifyUngrab)
- || ev.xcrossing.detail == NotifyVirtual
- || ev.xcrossing.detail == NotifyNonlinearVirtual)
- continue;
- enter = event_widget;
- if (enter)
- enterPoint = enter->d_func()->mapFromWS(QPoint(ev.xcrossing.x, ev.xcrossing.y));
- if (ev.xcrossing.focus &&
- enter && !(enter->windowType() == Qt::Desktop) && !enter->isActiveWindow()) {
- if (X11->focus_model == QX11Data::FM_Unknown) // check focus model
- qt_check_focus_model();
- if (X11->focus_model == QX11Data::FM_PointerRoot) // PointerRoot mode
- setActiveWindow(enter);
- }
- break;
- }
-
- if ((! enter || (enter->windowType() == Qt::Desktop)) &&
- event->xcrossing.focus && widget == QApplicationPrivate::active_window &&
- X11->focus_model == QX11Data::FM_PointerRoot // PointerRoot mode
- ) {
- setActiveWindow(0);
- }
-
- if (qt_button_down && !d->inPopupMode())
- break;
-
- if (!curWin)
- QApplicationPrivate::dispatchEnterLeave(widget, 0);
-
- if (enter) {
- QWidget *alienEnter = enter->childAt(enterPoint);
- if (alienEnter)
- enter = alienEnter;
- }
-
- QWidget *leave = qt_last_mouse_receiver ? qt_last_mouse_receiver : widget;
- QWidget *activePopupWidget = qApp->activePopupWidget();
-
- if (mouseGrabber && activePopupWidget && leave == activePopupWidget)
- enter = mouseGrabber;
- else if (enter != widget && mouseGrabber) {
- if (!widget->rect().contains(widget->d_func()->mapFromWS(QPoint(event->xcrossing.x,
- event->xcrossing.y))))
- break;
- }
-
- QApplicationPrivate::dispatchEnterLeave(enter, leave);
- qt_last_mouse_receiver = enter;
-
- if (enter && QApplicationPrivate::tryModalHelper(enter, 0)) {
- QWidget *nativeEnter = enter->internalWinId() ? enter : enter->nativeParentWidget();
- curWin = nativeEnter->internalWinId();
- static_cast<QETWidget *>(nativeEnter)->translateMouseEvent(&ev); //we don't get MotionNotify, emulate it
- } else {
- curWin = 0;
- qt_last_mouse_receiver = 0;
- }
- }
- break;
-
- case UnmapNotify: // window hidden
- if (widget->isWindow()) {
- Q_ASSERT(widget->testAttribute(Qt::WA_WState_Created));
- widget->d_func()->topData()->waitingForMapNotify = 0;
-
- if (widget->windowType() != Qt::Popup && !widget->testAttribute(Qt::WA_DontShowOnScreen)) {
- widget->setAttribute(Qt::WA_Mapped, false);
- if (widget->isVisible()) {
- widget->d_func()->topData()->spont_unmapped = 1;
- QHideEvent e;
- QApplication::sendSpontaneousEvent(widget, &e);
- widget->d_func()->hideChildren(true);
- }
- }
-
- if (!widget->d_func()->topData()->validWMState && X11->deferred_map.removeAll(widget))
- widget->doDeferredMap();
- }
- break;
-
- case MapNotify: // window shown
- if (widget->isWindow()) {
- // if we got a MapNotify when we were not waiting for it, it most
- // likely means the user has already asked to hide the window before
- // it ever being shown, so we try to withdraw a window after sending
- // the QShowEvent.
- bool pendingHide = widget->testAttribute(Qt::WA_WState_ExplicitShowHide) && widget->testAttribute(Qt::WA_WState_Hidden);
- widget->d_func()->topData()->waitingForMapNotify = 0;
-
- if (widget->windowType() != Qt::Popup) {
- widget->setAttribute(Qt::WA_Mapped);
- if (widget->d_func()->topData()->spont_unmapped) {
- widget->d_func()->topData()->spont_unmapped = 0;
- widget->d_func()->showChildren(true);
- QShowEvent e;
- QApplication::sendSpontaneousEvent(widget, &e);
-
- // show() must have been called on this widget in
- // order to reach this point, but we could have
- // cleared these 2 attributes in case something
- // previously forced us into WithdrawnState
- // (e.g. kdocker)
- widget->setAttribute(Qt::WA_WState_ExplicitShowHide, true);
- widget->setAttribute(Qt::WA_WState_Visible, true);
- }
- }
- if (pendingHide) // hide the window
- XWithdrawWindow(X11->display, widget->internalWinId(), widget->x11Info().screen());
- }
- break;
-
- case ClientMessage: // client message
- return x11ClientMessage(widget,event,False);
-
- case ReparentNotify: { // window manager reparents
- // compress old reparent events to self
- XEvent ev;
- while (XCheckTypedWindowEvent(X11->display,
- widget->effectiveWinId(),
- ReparentNotify,
- &ev)) {
- if (ev.xreparent.window != ev.xreparent.event) {
- XPutBackEvent(X11->display, &ev);
- break;
- }
- }
- if (widget->isWindow()) {
- QTLWExtra *topData = widget->d_func()->topData();
-
- // store the parent. Useful for many things, embedding for instance.
- topData->parentWinId = event->xreparent.parent;
-
- // the widget frame strut should also be invalidated
- widget->data->fstrut_dirty = 1;
-
- // work around broken window managers... if we get a
- // ReparentNotify before the MapNotify, we assume that
- // we're being managed by a reparenting window
- // manager.
- //
- // however, the WM_STATE property may not have been set
- // yet, but we are going to assume that it will
- // be... otherwise we could try to map again after getting
- // an UnmapNotify... which could then, in turn, trigger a
- // race in the window manager which causes the window to
- // disappear when it really should be hidden.
- if (topData->waitingForMapNotify && !topData->validWMState) {
- topData->waitingForMapNotify = 0;
- topData->validWMState = 1;
- }
-
- if (X11->focus_model != QX11Data::FM_Unknown) {
- // toplevel reparented...
- QWidget *newparent = QWidget::find(event->xreparent.parent);
- if (! newparent || (newparent->windowType() == Qt::Desktop)) {
- // we don't know about the new parent (or we've been
- // reparented to root), perhaps a window manager
- // has been (re)started? reset the focus model to unknown
- X11->focus_model = QX11Data::FM_Unknown;
- }
- }
- }
- break;
- }
- case SelectionRequest: {
- XSelectionRequestEvent *req = &event->xselectionrequest;
- if (! req)
- break;
-
- if (ATOM(XdndSelection) && req->selection == ATOM(XdndSelection)) {
- X11->xdndHandleSelectionRequest(req);
-
- } else if (qt_clipboard) {
- QClipboardEvent e(reinterpret_cast<QEventPrivate*>(event));
- QApplication::sendSpontaneousEvent(qt_clipboard, &e);
- }
- break;
- }
- case SelectionClear: {
- XSelectionClearEvent *req = &event->xselectionclear;
- // don't deliver dnd events to the clipboard, it gets confused
- if (! req || (ATOM(XdndSelection) && req->selection == ATOM(XdndSelection)))
- break;
-
- if (qt_clipboard && !X11->use_xfixes) {
- QClipboardEvent e(reinterpret_cast<QEventPrivate*>(event));
- QApplication::sendSpontaneousEvent(qt_clipboard, &e);
- }
- break;
- }
-
- case SelectionNotify: {
- XSelectionEvent *req = &event->xselection;
- // don't deliver dnd events to the clipboard, it gets confused
- if (! req || (ATOM(XdndSelection) && req->selection == ATOM(XdndSelection)))
- break;
-
- if (qt_clipboard) {
- QClipboardEvent e(reinterpret_cast<QEventPrivate*>(event));
- QApplication::sendSpontaneousEvent(qt_clipboard, &e);
- }
- break;
- }
- case PropertyNotify:
- // some properties changed
- if (event->xproperty.window == QX11Info::appRootWindow(0)) {
- // root properties for the first screen
- if (!X11->use_xfixes && event->xproperty.atom == ATOM(_QT_CLIPBOARD_SENTINEL)) {
- if (qt_check_clipboard_sentinel()) {
- emit clipboard()->changed(QClipboard::Clipboard);
- emit clipboard()->dataChanged();
- }
- } else if (!X11->use_xfixes && event->xproperty.atom == ATOM(_QT_SELECTION_SENTINEL)) {
- if (qt_check_selection_sentinel()) {
- emit clipboard()->changed(QClipboard::Selection);
- emit clipboard()->selectionChanged();
- }
- } else if (QApplicationPrivate::obey_desktop_settings) {
- if (event->xproperty.atom == ATOM(RESOURCE_MANAGER))
- qt_set_x11_resources();
- else if (event->xproperty.atom == ATOM(_QT_SETTINGS_TIMESTAMP))
- qt_set_x11_resources();
- }
- }
- if (event->xproperty.window == QX11Info::appRootWindow()) {
- // root properties for the default screen
- if (event->xproperty.atom == ATOM(_QT_INPUT_ENCODING)) {
- qt_set_input_encoding();
- } else if (event->xproperty.atom == ATOM(_NET_SUPPORTED)) {
- qt_get_net_supported();
- } else if (event->xproperty.atom == ATOM(_NET_VIRTUAL_ROOTS)) {
- qt_get_net_virtual_roots();
- } else if (event->xproperty.atom == ATOM(_NET_WORKAREA)) {
- qt_desktopwidget_update_workarea();
-
- // emit the workAreaResized() signal
- QDesktopWidget *desktop = QApplication::desktop();
- int numScreens = desktop->numScreens();
- for (int i = 0; i < numScreens; ++i)
- emit desktop->workAreaResized(i);
- }
- } else if (widget) {
- widget->translatePropertyEvent(event);
- } else {
- return -1; // don't know this window
- }
- break;
-
- default:
- break;
- }
-
- return 0;
-}
-
-bool QApplication::x11EventFilter(XEvent *)
-{
- return false;
-}
-
-
-
-/*****************************************************************************
- Modal widgets; Since Xlib has little support for this we roll our own
- modal widget mechanism.
- A modal widget without a parent becomes application-modal.
- A modal widget with a parent becomes modal to its parent and grandparents..
-
- QApplicationPrivate::enterModal()
- Enters modal state
- Arguments:
- QWidget *widget A modal widget
-
- QApplicationPrivate::leaveModal()
- Leaves modal state for a widget
- Arguments:
- QWidget *widget A modal widget
- *****************************************************************************/
-
-bool QApplicationPrivate::modalState()
-{
- return app_do_modal;
-}
-
-void QApplicationPrivate::enterModal_sys(QWidget *widget)
-{
- if (!qt_modal_stack)
- qt_modal_stack = new QWidgetList;
-
- QWidget *leave = qt_last_mouse_receiver;
- if (!leave)
- leave = QWidget::find((WId)curWin);
- QApplicationPrivate::dispatchEnterLeave(0, leave);
- qt_modal_stack->insert(0, widget);
- app_do_modal = true;
- curWin = 0;
- qt_last_mouse_receiver = 0;
-}
-
-void QApplicationPrivate::leaveModal_sys(QWidget *widget)
-{
- if (qt_modal_stack && qt_modal_stack->removeAll(widget)) {
- if (qt_modal_stack->isEmpty()) {
- delete qt_modal_stack;
- qt_modal_stack = 0;
- QPoint p(QCursor::pos());
- QWidget* w = QApplication::widgetAt(p.x(), p.y());
- QWidget *leave = qt_last_mouse_receiver;
- if (!leave)
- leave = QWidget::find((WId)curWin);
- if (QWidget *grabber = QWidget::mouseGrabber()) {
- w = grabber;
- if (leave == w)
- leave = 0;
- }
- QApplicationPrivate::dispatchEnterLeave(w, leave); // send synthetic enter event
- curWin = w ? w->effectiveWinId() : 0;
- qt_last_mouse_receiver = w;
- }
- }
- app_do_modal = qt_modal_stack != 0;
-}
-
-bool qt_try_modal(QWidget *widget, XEvent *event)
-{
- if (qt_xdnd_dragging) {
- // allow mouse events while DnD is active
- switch (event->type) {
- case ButtonPress:
- case ButtonRelease:
- case MotionNotify:
- return true;
- default:
- break;
- }
- }
-
- // allow mouse release events to be sent to widgets that have been pressed
- if (event->type == ButtonRelease) {
- QWidget *alienWidget = widget->childAt(widget->mapFromGlobal(QPoint(event->xbutton.x_root,
- event->xbutton.y_root)));
- if (widget == qt_button_down || (alienWidget && alienWidget == qt_button_down))
- return true;
- }
-
- if (QApplicationPrivate::tryModalHelper(widget))
- return true;
-
- // disallow mouse/key events
- switch (event->type) {
- case ButtonPress:
- case ButtonRelease:
- case MotionNotify:
- case XKeyPress:
- case XKeyRelease:
- case EnterNotify:
- case LeaveNotify:
- case ClientMessage:
- return false;
- default:
- break;
- }
-
- return true;
-}
-
-
-/*****************************************************************************
- Popup widget mechanism
-
- openPopup()
- Adds a widget to the list of popup widgets
- Arguments:
- QWidget *widget The popup widget to be added
-
- closePopup()
- Removes a widget from the list of popup widgets
- Arguments:
- QWidget *widget The popup widget to be removed
- *****************************************************************************/
-
-
-static int openPopupCount = 0;
-void QApplicationPrivate::openPopup(QWidget *popup)
-{
- Q_Q(QApplication);
- openPopupCount++;
- if (!QApplicationPrivate::popupWidgets) { // create list
- QApplicationPrivate::popupWidgets = new QWidgetList;
- }
- QApplicationPrivate::popupWidgets->append(popup); // add to end of list
- Display *dpy = X11->display;
- if (QApplicationPrivate::popupWidgets->count() == 1 && !qt_nograb()){ // grab mouse/keyboard
- Q_ASSERT(popup->testAttribute(Qt::WA_WState_Created));
- int r = XGrabKeyboard(dpy, popup->effectiveWinId(), false,
- GrabModeAsync, GrabModeAsync, X11->time);
- if ((popupGrabOk = (r == GrabSuccess))) {
- r = XGrabPointer(dpy, popup->effectiveWinId(), true,
- (ButtonPressMask | ButtonReleaseMask | ButtonMotionMask
- | EnterWindowMask | LeaveWindowMask | PointerMotionMask),
- GrabModeAsync, GrabModeAsync, XNone, XNone, X11->time);
- if (!(popupGrabOk = (r == GrabSuccess))) {
- // transfer grab back to the keyboard grabber if any
- if (QWidgetPrivate::keyboardGrabber != 0)
- QWidgetPrivate::keyboardGrabber->grabKeyboard();
- else
- XUngrabKeyboard(dpy, X11->time);
- }
- }
- }
-
- // popups are not focus-handled by the window system (the first
- // popup grabbed the keyboard), so we have to do that manually: A
- // new popup gets the focus
- if (popup->focusWidget()) {
- popup->focusWidget()->setFocus(Qt::PopupFocusReason);
- } else if (QApplicationPrivate::popupWidgets->count() == 1) { // this was the first popup
- if (QWidget *fw = QApplication::focusWidget()) {
- QFocusEvent e(QEvent::FocusOut, Qt::PopupFocusReason);
- q->sendEvent(fw, &e);
- }
- }
-}
-
-void QApplicationPrivate::closePopup(QWidget *popup)
-{
- Q_Q(QApplication);
- if (!QApplicationPrivate::popupWidgets)
- return;
- QApplicationPrivate::popupWidgets->removeAll(popup);
- if (popup == qt_popup_down) {
- qt_button_down = 0;
- qt_popup_down = 0;
- }
- if (QApplicationPrivate::popupWidgets->count() == 0) { // this was the last popup
- delete QApplicationPrivate::popupWidgets;
- QApplicationPrivate::popupWidgets = 0;
- if (!qt_nograb() && popupGrabOk) { // grabbing not disabled
- Display *dpy = X11->display;
- if (popup->geometry().contains(QPoint(mouseGlobalXPos, mouseGlobalYPos))
- || popup->testAttribute(Qt::WA_NoMouseReplay)) {
- // mouse release event or inside
- replayPopupMouseEvent = false;
- } else { // mouse press event
- mouseButtonPressTime -= 10000; // avoid double click
- replayPopupMouseEvent = true;
- }
- // transfer grab back to mouse grabber if any, otherwise release the grab
- if (QWidgetPrivate::mouseGrabber != 0)
- QWidgetPrivate::mouseGrabber->grabMouse();
- else
- XUngrabPointer(dpy, X11->time);
-
- // transfer grab back to keyboard grabber if any, otherwise release the grab
- if (QWidgetPrivate::keyboardGrabber != 0)
- QWidgetPrivate::keyboardGrabber->grabKeyboard();
- else
- XUngrabKeyboard(dpy, X11->time);
-
- XFlush(dpy);
- }
- if (QApplicationPrivate::active_window) {
- if (QWidget *fw = QApplicationPrivate::active_window->focusWidget()) {
- if (fw != QApplication::focusWidget()) {
- fw->setFocus(Qt::PopupFocusReason);
- } else {
- QFocusEvent e(QEvent::FocusIn, Qt::PopupFocusReason);
- q->sendEvent(fw, &e);
- }
- }
- }
- } else {
- // popups are not focus-handled by the window system (the
- // first popup grabbed the keyboard), so we have to do that
- // manually: A popup was closed, so the previous popup gets
- // the focus.
- QWidget* aw = QApplicationPrivate::popupWidgets->last();
- if (QWidget *fw = aw->focusWidget())
- fw->setFocus(Qt::PopupFocusReason);
-
- // regrab the keyboard and mouse in case 'popup' lost the grab
- if (QApplicationPrivate::popupWidgets->count() == 1 && !qt_nograb()){ // grab mouse/keyboard
- Display *dpy = X11->display;
- Q_ASSERT(aw->testAttribute(Qt::WA_WState_Created));
- int r = XGrabKeyboard(dpy, aw->effectiveWinId(), false,
- GrabModeAsync, GrabModeAsync, X11->time);
- if ((popupGrabOk = (r == GrabSuccess))) {
- r = XGrabPointer(dpy, aw->effectiveWinId(), true,
- (ButtonPressMask | ButtonReleaseMask | ButtonMotionMask
- | EnterWindowMask | LeaveWindowMask | PointerMotionMask),
- GrabModeAsync, GrabModeAsync, XNone, XNone, X11->time);
- if (!(popupGrabOk = (r == GrabSuccess))) {
- // transfer grab back to keyboard grabber
- if (QWidgetPrivate::keyboardGrabber != 0)
- QWidgetPrivate::keyboardGrabber->grabKeyboard();
- else
- XUngrabKeyboard(dpy, X11->time);
- }
- }
- }
- }
-}
-
-/*****************************************************************************
- Event translation; translates X11 events to Qt events
- *****************************************************************************/
-
-//
-// Mouse event translation
-//
-// Xlib doesn't give mouse double click events, so we generate them by
-// comparing window, time and position between two mouse press events.
-//
-
-static Qt::MouseButtons translateMouseButtons(int s)
-{
- Qt::MouseButtons ret = 0;
- if (s & Button1Mask)
- ret |= Qt::LeftButton;
- if (s & Button2Mask)
- ret |= Qt::MidButton;
- if (s & Button3Mask)
- ret |= Qt::RightButton;
- return ret;
-}
-
-Qt::KeyboardModifiers QX11Data::translateModifiers(int s)
-{
- Qt::KeyboardModifiers ret = 0;
- if (s & ShiftMask)
- ret |= Qt::ShiftModifier;
- if (s & ControlMask)
- ret |= Qt::ControlModifier;
- if (s & qt_alt_mask)
- ret |= Qt::AltModifier;
- if (s & qt_meta_mask)
- ret |= Qt::MetaModifier;
- if (s & qt_mode_switch_mask)
- ret |= Qt::GroupSwitchModifier;
- return ret;
-}
-
-bool QETWidget::translateMouseEvent(const XEvent *event)
-{
- if (!isWindow() && testAttribute(Qt::WA_NativeWindow))
- Q_ASSERT(internalWinId());
-
- Q_D(QWidget);
- QEvent::Type type; // event parameters
- QPoint pos;
- QPoint globalPos;
- Qt::MouseButton button = Qt::NoButton;
- Qt::MouseButtons buttons;
- Qt::KeyboardModifiers modifiers;
- XEvent nextEvent;
-
- if (qt_sm_blockUserInput) // block user interaction during session management
- return true;
-
- if (event->type == MotionNotify) { // mouse move
- if (event->xmotion.root != RootWindow(X11->display, x11Info().screen()) &&
- ! qt_xdnd_dragging)
- return false;
-
- XMotionEvent lastMotion = event->xmotion;
- while(XPending(X11->display)) { // compress mouse moves
- XNextEvent(X11->display, &nextEvent);
- if (nextEvent.type == ConfigureNotify
- || nextEvent.type == PropertyNotify
- || nextEvent.type == Expose
- || nextEvent.type == GraphicsExpose
- || nextEvent.type == NoExpose
- || nextEvent.type == KeymapNotify
- || ((nextEvent.type == EnterNotify || nextEvent.type == LeaveNotify)
- && qt_button_down == this)
- || (nextEvent.type == ClientMessage
- && (nextEvent.xclient.message_type == ATOM(_QT_SCROLL_DONE) ||
- (nextEvent.xclient.message_type == ATOM(WM_PROTOCOLS) &&
- (Atom)nextEvent.xclient.data.l[0] == ATOM(_NET_WM_SYNC_REQUEST))))) {
- qApp->x11ProcessEvent(&nextEvent);
- continue;
- } else if (nextEvent.type != MotionNotify ||
- nextEvent.xmotion.window != event->xmotion.window ||
- nextEvent.xmotion.state != event->xmotion.state) {
- XPutBackEvent(X11->display, &nextEvent);
- break;
- }
- if (!qt_x11EventFilter(&nextEvent)
- && !x11Event(&nextEvent)) // send event through filter
- lastMotion = nextEvent.xmotion;
- else
- break;
- }
- type = QEvent::MouseMove;
- pos.rx() = lastMotion.x;
- pos.ry() = lastMotion.y;
- pos = d->mapFromWS(pos);
- globalPos.rx() = lastMotion.x_root;
- globalPos.ry() = lastMotion.y_root;
- buttons = translateMouseButtons(lastMotion.state);
- modifiers = X11->translateModifiers(lastMotion.state);
- if (qt_button_down && !buttons)
- qt_button_down = 0;
- } else if (event->type == EnterNotify || event->type == LeaveNotify) {
- XEvent *xevent = (XEvent *)event;
- //unsigned int xstate = event->xcrossing.state;
- type = QEvent::MouseMove;
- pos.rx() = xevent->xcrossing.x;
- pos.ry() = xevent->xcrossing.y;
- pos = d->mapFromWS(pos);
- globalPos.rx() = xevent->xcrossing.x_root;
- globalPos.ry() = xevent->xcrossing.y_root;
- buttons = translateMouseButtons(xevent->xcrossing.state);
- modifiers = X11->translateModifiers(xevent->xcrossing.state);
- if (qt_button_down && !buttons)
- qt_button_down = 0;
- if (qt_button_down)
- return true;
- } else { // button press or release
- pos.rx() = event->xbutton.x;
- pos.ry() = event->xbutton.y;
- pos = d->mapFromWS(pos);
- globalPos.rx() = event->xbutton.x_root;
- globalPos.ry() = event->xbutton.y_root;
- buttons = translateMouseButtons(event->xbutton.state);
- modifiers = X11->translateModifiers(event->xbutton.state);
- switch (event->xbutton.button) {
- case Button1: button = Qt::LeftButton; break;
- case Button2: button = Qt::MidButton; break;
- case Button3: button = Qt::RightButton; break;
- case Button4:
- case Button5:
- case 6:
- case 7:
- // the fancy mouse wheel.
-
- // We are only interested in ButtonPress.
- if (event->type == ButtonPress){
- // compress wheel events (the X Server will simply
- // send a button press for each single notch,
- // regardless whether the application can catch up
- // or not)
- int delta = 1;
- XEvent xevent;
- while (XCheckTypedWindowEvent(X11->display, effectiveWinId(), ButtonPress, &xevent)){
- if (xevent.xbutton.button != event->xbutton.button){
- XPutBackEvent(X11->display, &xevent);
- break;
- }
- delta++;
- }
-
- // the delta is defined as multiples of
- // WHEEL_DELTA, which is set to 120. Future wheels
- // may offer a finer-resolution. A positive delta
- // indicates forward rotation, a negative one
- // backward rotation respectively.
- int btn = event->xbutton.button;
- delta *= 120 * ((btn == Button4 || btn == 6) ? 1 : -1);
- bool hor = (((btn == Button4 || btn == Button5) && (modifiers & Qt::AltModifier)) ||
- (btn == 6 || btn == 7));
- translateWheelEvent(globalPos.x(), globalPos.y(), delta, buttons,
- modifiers, (hor) ? Qt::Horizontal: Qt::Vertical);
- }
- return true;
- case 8: button = Qt::XButton1; break;
- case 9: button = Qt::XButton2; break;
- }
- if (event->type == ButtonPress) { // mouse button pressed
- buttons |= button;
-#if defined(Q_OS_IRIX) && !defined(QT_NO_TABLET)
- QTabletDeviceDataList *tablets = qt_tablet_devices();
- for (int i = 0; i < tablets->size(); ++i) {
- QTabletDeviceData &tab = tablets->operator[](i);
- XEvent myEv;
- if (XCheckTypedEvent(X11->display, tab.xinput_button_press, &myEv)) {
- if (translateXinputEvent(&myEv, &tab)) {
- //Spontaneous event sent. Check if we need to continue.
- if (qt_tabletChokeMouse) {
- qt_tabletChokeMouse = false;
- return false;
- }
- }
- }
- }
-#endif
- if (!qt_button_down) {
- qt_button_down = childAt(pos); //magic for masked widgets
- if (!qt_button_down)
- qt_button_down = this;
- }
- if (mouseActWindow == event->xbutton.window &&
- mouseButtonPressed == button &&
- (long)event->xbutton.time -(long)mouseButtonPressTime
- < QApplication::doubleClickInterval() &&
- qAbs(event->xbutton.x - mouseXPos) < QT_GUI_DOUBLE_CLICK_RADIUS &&
- qAbs(event->xbutton.y - mouseYPos) < QT_GUI_DOUBLE_CLICK_RADIUS) {
- type = QEvent::MouseButtonDblClick;
- mouseButtonPressTime -= 2000; // no double-click next time
- } else {
- type = QEvent::MouseButtonPress;
- mouseButtonPressTime = event->xbutton.time;
- }
- mouseButtonPressed = button; // save event params for
- mouseXPos = event->xbutton.x; // future double click tests
- mouseYPos = event->xbutton.y;
- mouseGlobalXPos = globalPos.x();
- mouseGlobalYPos = globalPos.y();
- } else { // mouse button released
- buttons &= ~button;
-#if defined(Q_OS_IRIX) && !defined(QT_NO_TABLET)
- QTabletDeviceDataList *tablets = qt_tablet_devices();
- for (int i = 0; i < tablets->size(); ++i) {
- QTabletDeviceData &tab = tablets->operator[](i);
- XEvent myEv;
- if (XCheckTypedEvent(X11->display, tab.xinput_button_press, &myEv)) {
- if (translateXinputEvent(&myEv, &tab)) {
- //Spontaneous event sent. Check if we need to continue.
- if (qt_tabletChokeMouse) {
- qt_tabletChokeMouse = false;
- return false;
- }
- }
- }
- }
-#endif
- type = QEvent::MouseButtonRelease;
- }
- }
- mouseActWindow = effectiveWinId(); // save some event params
- mouseButtonState = buttons;
- if (type == 0) // don't send event
- return false;
-
- if (qApp->d_func()->inPopupMode()) { // in popup mode
- QWidget *activePopupWidget = qApp->activePopupWidget();
- QWidget *popup = qApp->activePopupWidget();
- if (popup != this) {
- if (event->type == LeaveNotify)
- return false;
- if ((windowType() == Qt::Popup) && rect().contains(pos) && 0)
- popup = this;
- else // send to last popup
- pos = popup->mapFromGlobal(globalPos);
- }
- bool releaseAfter = false;
- QWidget *popupChild = popup->childAt(pos);
-
- if (popup != qt_popup_down){
- qt_button_down = 0;
- qt_popup_down = 0;
- }
-
- switch (type) {
- case QEvent::MouseButtonPress:
- case QEvent::MouseButtonDblClick:
- qt_button_down = popupChild;
- qt_popup_down = popup;
- break;
- case QEvent::MouseButtonRelease:
- releaseAfter = true;
- break;
- default:
- break; // nothing for mouse move
- }
-
- int oldOpenPopupCount = openPopupCount;
-
- if (popup->isEnabled()) {
- // deliver event
- replayPopupMouseEvent = false;
- QWidget *receiver = popup;
- QPoint widgetPos = pos;
- if (qt_button_down)
- receiver = qt_button_down;
- else if (popupChild)
- receiver = popupChild;
- if (receiver != popup)
- widgetPos = receiver->mapFromGlobal(globalPos);
- QWidget *alien = childAt(mapFromGlobal(globalPos));
- QMouseEvent e(type, widgetPos, globalPos, button, buttons, modifiers);
- QApplicationPrivate::sendMouseEvent(receiver, &e, alien, this, &qt_button_down, qt_last_mouse_receiver);
- } else {
- // close disabled popups when a mouse button is pressed or released
- switch (type) {
- case QEvent::MouseButtonPress:
- case QEvent::MouseButtonDblClick:
- case QEvent::MouseButtonRelease:
- popup->close();
- break;
- default:
- break;
- }
- }
-
- if (qApp->activePopupWidget() != activePopupWidget
- && replayPopupMouseEvent) {
- // the active popup was closed, replay the mouse event
- if (!(windowType() == Qt::Popup)) {
-#if 1
- qt_button_down = 0;
-#else
- if (buttons == button)
- qt_button_down = this;
- QMouseEvent e(type, mapFromGlobal(globalPos), globalPos, button,
- buttons, modifiers);
- QApplication::sendSpontaneousEvent(this, &e);
-
- if (type == QEvent::MouseButtonPress
- && button == Qt::RightButton
- && (openPopupCount == oldOpenPopupCount)) {
- QContextMenuEvent e(QContextMenuEvent::Mouse, mapFromGlobal(globalPos),
- globalPos, modifiers);
- QApplication::sendSpontaneousEvent(this, &e);
- }
-#endif
- }
- replayPopupMouseEvent = false;
- } else if (type == QEvent::MouseButtonPress
- && button == Qt::RightButton
- && (openPopupCount == oldOpenPopupCount)) {
- QWidget *popupEvent = popup;
- if (qt_button_down)
- popupEvent = qt_button_down;
- else if(popupChild)
- popupEvent = popupChild;
- QContextMenuEvent e(QContextMenuEvent::Mouse, pos, globalPos, modifiers);
- QApplication::sendSpontaneousEvent(popupEvent, &e);
- }
-
- if (releaseAfter) {
- qt_button_down = 0;
- qt_popup_down = 0;
- }
- } else {
- QWidget *alienWidget = childAt(pos);
- QWidget *widget = QApplicationPrivate::pickMouseReceiver(this, globalPos, pos, type, buttons,
- qt_button_down, alienWidget);
- if (!widget) {
- if (type == QEvent::MouseButtonRelease)
- QApplicationPrivate::mouse_buttons &= ~button;
- return false; // don't send event
- }
-
- int oldOpenPopupCount = openPopupCount;
- QMouseEvent e(type, pos, globalPos, button, buttons, modifiers);
- QApplicationPrivate::sendMouseEvent(widget, &e, alienWidget, this, &qt_button_down,
- qt_last_mouse_receiver);
- if (type == QEvent::MouseButtonPress
- && button == Qt::RightButton
- && (openPopupCount == oldOpenPopupCount)) {
- QContextMenuEvent e(QContextMenuEvent::Mouse, pos, globalPos, modifiers);
- QApplication::sendSpontaneousEvent(widget, &e);
- }
- }
- return true;
-}
-
-
-//
-// Wheel event translation
-//
-bool QETWidget::translateWheelEvent(int global_x, int global_y, int delta,
- Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers,
- Qt::Orientation orient)
-{
- const QPoint globalPos = QPoint(global_x, global_y);
- QPoint pos = mapFromGlobal(globalPos);
- QWidget *widget = childAt(pos);
- if (!widget)
- widget = this;
- else if (!widget->internalWinId())
- pos = widget->mapFromGlobal(globalPos);
-
-#ifdef ALIEN_DEBUG
- qDebug() << "QETWidget::translateWheelEvent: receiver:" << widget << "pos:" << pos;
-#endif
-
- // send the event to the widget or its ancestors
- {
- QWidget* popup = qApp->activePopupWidget();
- if (popup && window() != popup)
- popup->close();
-#ifndef QT_NO_WHEELEVENT
- QWheelEvent e(pos, globalPos, delta, buttons, modifiers, orient);
- if (QApplication::sendSpontaneousEvent(widget, &e))
-#endif
- return true;
- }
-
- // send the event to the widget that has the focus or its ancestors, if different
- if (widget != qApp->focusWidget() && (widget = qApp->focusWidget())) {
- if (widget && !widget->internalWinId())
- pos = widget->mapFromGlobal(globalPos);
- QWidget* popup = qApp->activePopupWidget();
- if (popup && widget != popup)
- popup->hide();
-#ifndef QT_NO_WHEELEVENT
- QWheelEvent e(pos, globalPos, delta, buttons, modifiers, orient);
- if (QApplication::sendSpontaneousEvent(widget, &e))
-#endif
- return true;
- }
- return false;
-}
-
-
-//
-// XInput Translation Event
-//
-#if !defined (QT_NO_TABLET)
-
-#if !defined (Q_OS_IRIX)
-void fetchWacomToolId(int &deviceType, qint64 &serialId)
-{
- if (ptrWacomConfigInit == 0) // we actually have the lib
- return;
- WACOMCONFIG *config = ptrWacomConfigInit(X11->display, 0);
- if (config == 0)
- return;
- WACOMDEVICE *device = ptrWacomConfigOpenDevice (config, wacomDeviceName()->constData());
- if (device == 0)
- return;
- unsigned keys[1];
- int serialInt;
- ptrWacomConfigGetRawParam (device, XWACOM_PARAM_TOOLSERIAL, &serialInt, 1, keys);
- serialId = serialInt;
- int toolId;
- ptrWacomConfigGetRawParam (device, XWACOM_PARAM_TOOLID, &toolId, 1, keys);
- switch(toolId) {
- case 0x007: /* Mouse 4D and 2D */
- case 0x017: /* Intuos3 2D Mouse */
- case 0x094:
- case 0x09c:
- deviceType = QTabletEvent::FourDMouse;
- break;
- case 0x096: /* Lens cursor */
- case 0x097: /* Intuos3 Lens cursor */
- deviceType = QTabletEvent::Puck;
- break;
- case 0x0fa:
- case 0x81b: /* Intuos3 Classic Pen Eraser */
- case 0x82a: /* Eraser */
- case 0x82b: /* Intuos3 Grip Pen Eraser */
- case 0x85a:
- case 0x91a:
- case 0x91b: /* Intuos3 Airbrush Eraser */
- case 0xd1a:
- deviceType = QTabletEvent::XFreeEraser;
- break;
- case 0x112:
- case 0x912:
- case 0x913: /* Intuos3 Airbrush */
- case 0xd12:
- deviceType = QTabletEvent::Airbrush;
- break;
- case 0x012:
- case 0x022:
- case 0x032:
- case 0x801: /* Intuos3 Inking pen */
- case 0x812: /* Inking pen */
- case 0x813: /* Intuos3 Classic Pen */
- case 0x822: /* Pen */
- case 0x823: /* Intuos3 Grip Pen */
- case 0x832: /* Stroke pen */
- case 0x842:
- case 0x852:
- case 0x885: /* Intuos3 Marker Pen */
- default: /* Unknown tool */
- deviceType = QTabletEvent::Stylus;
- }
-
- /* Close device and return */
- ptrWacomConfigCloseDevice (device);
- ptrWacomConfigTerm(config);
-}
-#endif
-
-struct qt_tablet_motion_data
-{
- bool filterByWidget;
- const QWidget *widget;
- const QWidget *etWidget;
- int tabletMotionType;
- bool error; // found a reason to stop searching
-};
-
-static Bool qt_mouseMotion_scanner(Display *, XEvent *event, XPointer arg)
-{
- qt_tablet_motion_data *data = (qt_tablet_motion_data *) arg;
- if (data->error)
- return false;
-
- if (event->type == MotionNotify)
- return true;
-
- data->error = event->type != data->tabletMotionType; // we stop compression when another event gets in between.
- return false;
-}
-
-static Bool qt_tabletMotion_scanner(Display *, XEvent *event, XPointer arg)
-{
- qt_tablet_motion_data *data = (qt_tablet_motion_data *) arg;
- if (data->error)
- return false;
- if (event->type == data->tabletMotionType) {
- const XDeviceMotionEvent *const motion = reinterpret_cast<const XDeviceMotionEvent*>(event);
- if (data->filterByWidget) {
- const QPoint curr(motion->x, motion->y);
- const QWidget *w = data->etWidget;
- const QWidget *const child = w->childAt(curr);
- if (child) {
- w = child;
- }
- if (w == data->widget)
- return true;
- } else {
- return true;
- }
- }
-
- data->error = event->type != MotionNotify; // we stop compression when another event gets in between.
- return false;
-}
-
-bool QETWidget::translateXinputEvent(const XEvent *ev, QTabletDeviceData *tablet)
-{
-#if defined (Q_OS_IRIX)
- // Wacom has put defines in their wacom.h file so it would be quite wise
- // to use them, need to think of a decent way of not using
- // it when it doesn't exist...
- XDeviceState *s;
- XInputClass *iClass;
- XValuatorState *vs;
- int j;
-#endif
-
- Q_ASSERT(tablet != 0);
-
- QWidget *w = this;
- QPoint global,
- curr;
- QPointF hiRes;
- qreal pressure = 0;
- int xTilt = 0,
- yTilt = 0,
- z = 0;
- qreal tangentialPressure = 0;
- qreal rotation = 0;
- int deviceType = QTabletEvent::NoDevice;
- int pointerType = QTabletEvent::UnknownPointer;
- const XDeviceMotionEvent *motion = 0;
- XDeviceButtonEvent *button = 0;
- const XProximityNotifyEvent *proximity = 0;
- QEvent::Type t;
- Qt::KeyboardModifiers modifiers = 0;
-#if !defined (Q_OS_IRIX)
- XID device_id;
-#endif
-
- if (ev->type == tablet->xinput_motion) {
- motion = reinterpret_cast<const XDeviceMotionEvent*>(ev);
- t = QEvent::TabletMove;
- global = QPoint(motion->x_root, motion->y_root);
- curr = QPoint(motion->x, motion->y);
-#if !defined (Q_OS_IRIX)
- device_id = motion->deviceid;
-#endif
- } else if (ev->type == tablet->xinput_button_press || ev->type == tablet->xinput_button_release) {
- if (ev->type == tablet->xinput_button_press) {
- t = QEvent::TabletPress;
- } else {
- t = QEvent::TabletRelease;
- }
- button = (XDeviceButtonEvent*)ev;
-
- global = QPoint(button->x_root, button->y_root);
- curr = QPoint(button->x, button->y);
-#if !defined (Q_OS_IRIX)
- device_id = button->deviceid;
-#endif
- } else { // Proximity
- if (ev->type == tablet->xinput_proximity_in)
- t = QEvent::TabletEnterProximity;
- else
- t = QEvent::TabletLeaveProximity;
- proximity = (const XProximityNotifyEvent*)ev;
-#if !defined (Q_OS_IRIX)
- device_id = proximity->deviceid;
-#endif
- }
-
- qint64 uid = 0;
-#if defined (Q_OS_IRIX)
- QRect screenArea = qApp->desktop()->screenGeometry(this);
- s = XQueryDeviceState(X11->display, static_cast<XDevice *>(tablet->device));
- if (!s)
- return false;
- iClass = s->data;
- for (j = 0; j < s->num_classes; j++) {
- if (iClass->c_class == ValuatorClass) {
- vs = reinterpret_cast<XValuatorState *>(iClass);
- // figure out what device we have, based on bitmasking...
- if (vs->valuators[WAC_TRANSDUCER_I]
- & WAC_TRANSDUCER_PROX_MSK) {
- switch (vs->valuators[WAC_TRANSDUCER_I]
- & WAC_TRANSDUCER_MSK) {
- case WAC_PUCK_ID:
- pointerType = QTabletEvent::Puck;
- break;
- case WAC_STYLUS_ID:
- pointerType = QTabletEvent::Pen;
- break;
- case WAC_ERASER_ID:
- pointerType = QTabletEvent::Eraser;
- break;
- }
- // Get a Unique Id for the device, Wacom gives us this ability
- uid = vs->valuators[WAC_TRANSDUCER_I] & WAC_TRANSDUCER_ID_MSK;
- uid = (uid << 24) | vs->valuators[WAC_SERIAL_NUM_I];
- switch (WAC_TRANSDUCER_I & 0x0F0600) {
- case 0x080200:
- deviceType = QTabletEvent::Stylus;
- break;
- case 0x090200:
- deviceType = QTabletEvent::Airbrush;
- break;
- case 0x000400:
- deviceType = QTabletEvent::FourDMouse;
- break;
- case 0x000600:
- deviceType = QTabletEvent::Puck;
- break;
- case 0x080400:
- deviceType = QTabletEvent::RotationStylus;
- break;
- }
- } else {
- pointerType = QTabletEvent::UnknownPointer;
- deviceType = QTabletEvent::NoDevice;
- uid = 0;
- }
-
- if (!proximity) {
- // apparently Wacom needs a cast for the +/- values to make sense
- xTilt = short(vs->valuators[WAC_XTILT_I]);
- yTilt = short(vs->valuators[WAC_YTILT_I]);
- pressure = vs->valuators[WAC_PRESSURE_I];
- if (deviceType == QTabletEvent::FourDMouse
- || deviceType == QTabletEvent::RotationStylus) {
- rotation = vs->valuators[WAC_ROTATION_I] / 64.0;
- if (deviceType == QTabletEvent::FourDMouse)
- z = vs->valuators[WAC_ZCOORD_I];
- } else if (deviceType == QTabletEvent::Airbrush) {
- tangentialPressure = vs->valuators[WAC_TAN_PRESSURE_I]
- / qreal(tablet->maxTanPressure - tablet->minTanPressure);
- }
-
- hiRes = tablet->scaleCoord(vs->valuators[WAC_XCOORD_I], vs->valuators[WAC_YCOORD_I],
- screenArea.x(), screenArea.width(),
- screenArea.y(), screenArea.height());
- }
- break;
- }
- iClass = reinterpret_cast<XInputClass*>(reinterpret_cast<char*>(iClass) + iClass->length);
- }
- XFreeDeviceState(s);
-#else
- QTabletDeviceDataList *tablet_list = qt_tablet_devices();
- for (int i = 0; i < tablet_list->size(); ++i) {
- const QTabletDeviceData &t = tablet_list->at(i);
- if (device_id == static_cast<XDevice *>(t.device)->device_id) {
- deviceType = t.deviceType;
- if (t.deviceType == QTabletEvent::XFreeEraser) {
- deviceType = QTabletEvent::Stylus;
- pointerType = QTabletEvent::Eraser;
- } else if (t.deviceType == QTabletEvent::Stylus) {
- pointerType = QTabletEvent::Pen;
- }
- break;
- }
- }
-
- fetchWacomToolId(deviceType, uid);
-
- QRect screenArea = qApp->desktop()->rect();
- if (motion) {
- xTilt = (short) motion->axis_data[3];
- yTilt = (short) motion->axis_data[4];
- rotation = ((short) motion->axis_data[5]) / 64.0;
- pressure = (short) motion->axis_data[2];
- modifiers = X11->translateModifiers(motion->state);
- hiRes = tablet->scaleCoord(motion->axis_data[0], motion->axis_data[1],
- screenArea.x(), screenArea.width(),
- screenArea.y(), screenArea.height());
- } else if (button) {
- xTilt = (short) button->axis_data[3];
- yTilt = (short) button->axis_data[4];
- rotation = ((short) button->axis_data[5]) / 64.0;
- pressure = (short) button->axis_data[2];
- modifiers = X11->translateModifiers(button->state);
- hiRes = tablet->scaleCoord(button->axis_data[0], button->axis_data[1],
- screenArea.x(), screenArea.width(),
- screenArea.y(), screenArea.height());
- } else if (proximity) {
- pressure = 0;
- modifiers = 0;
- }
- if (deviceType == QTabletEvent::Airbrush) {
- tangentialPressure = rotation;
- rotation = 0.;
- }
-#endif
-
- if (tablet->widgetToGetPress) {
- w = tablet->widgetToGetPress;
- } else {
- QWidget *child = w->childAt(curr);
- if (child)
- w = child;
- }
- curr = w->mapFromGlobal(global);
-
- if (t == QEvent::TabletPress) {
- tablet->widgetToGetPress = w;
- } else if (t == QEvent::TabletRelease && tablet->widgetToGetPress) {
- w = tablet->widgetToGetPress;
- curr = w->mapFromGlobal(global);
- tablet->widgetToGetPress = 0;
- }
-
- QTabletEvent e(t, curr, global, hiRes,
- deviceType, pointerType,
- qreal(pressure / qreal(tablet->maxPressure - tablet->minPressure)),
- xTilt, yTilt, tangentialPressure, rotation, z, modifiers, uid);
- if (proximity) {
- QApplication::sendSpontaneousEvent(qApp, &e);
- } else {
- QApplication::sendSpontaneousEvent(w, &e);
- const bool accepted = e.isAccepted();
- if (!accepted && ev->type == tablet->xinput_motion) {
- // If the widget does not accept tablet events, we drop the next ones from the event queue
- // for this widget so it is not overloaded with the numerous tablet events.
- qt_tablet_motion_data tabletMotionData;
- tabletMotionData.tabletMotionType = tablet->xinput_motion;
- tabletMotionData.widget = w;
- tabletMotionData.etWidget = this;
- // if nothing is pressed, the events are filtered by position
- tabletMotionData.filterByWidget = (tablet->widgetToGetPress == 0);
-
- bool reinsertMouseEvent = false;
- XEvent mouseMotionEvent;
- while (true) {
- // Find first mouse event since we expect them in pairs inside Qt
- tabletMotionData.error =false;
- if (XCheckIfEvent(X11->display, &mouseMotionEvent, &qt_mouseMotion_scanner, (XPointer) &tabletMotionData)) {
- reinsertMouseEvent = true;
- } else {
- break;
- }
-
- // Now discard any duplicate tablet events.
- tabletMotionData.error = false;
- XEvent dummy;
- while (XCheckIfEvent(X11->display, &dummy, &qt_tabletMotion_scanner, (XPointer) &tabletMotionData)) {
- // just discard the event
- }
- }
-
- if (reinsertMouseEvent) {
- XPutBackEvent(X11->display, &mouseMotionEvent);
- }
- }
- }
- return true;
-}
-#endif
-
-bool QETWidget::translatePropertyEvent(const XEvent *event)
-{
- Q_D(QWidget);
- if (!isWindow()) return true;
-
- Atom ret;
- int format, e;
- unsigned char *data = 0;
- unsigned long nitems, after;
-
- if (event->xproperty.atom == ATOM(_KDE_NET_WM_FRAME_STRUT)) {
- this->data->fstrut_dirty = 1;
-
- if (event->xproperty.state == PropertyNewValue) {
- e = XGetWindowProperty(X11->display, event->xproperty.window, ATOM(_KDE_NET_WM_FRAME_STRUT),
- 0, 4, // struts are 4 longs
- False, XA_CARDINAL, &ret, &format, &nitems, &after, &data);
-
- if (e == Success && ret == XA_CARDINAL &&
- format == 32 && nitems == 4) {
- long *strut = (long *) data;
- d->topData()->frameStrut.setCoords(strut[0], strut[2], strut[1], strut[3]);
- this->data->fstrut_dirty = 0;
- }
- }
- } else if (event->xproperty.atom == ATOM(_NET_WM_STATE)) {
- bool max = false;
- bool full = false;
- Qt::WindowStates oldState = Qt::WindowStates(this->data->window_state);
-
- if (event->xproperty.state == PropertyNewValue) {
- // using length of 1024 should be safe for all current and
- // possible NET states...
- e = XGetWindowProperty(X11->display, event->xproperty.window, ATOM(_NET_WM_STATE), 0, 1024,
- False, XA_ATOM, &ret, &format, &nitems, &after, &data);
-
- if (e == Success && ret == XA_ATOM && format == 32 && nitems > 0) {
- Atom *states = (Atom *) data;
-
- unsigned long i;
- uint maximized = 0;
- for (i = 0; i < nitems; i++) {
- if (states[i] == ATOM(_NET_WM_STATE_MAXIMIZED_VERT))
- maximized |= 1;
- else if (states[i] == ATOM(_NET_WM_STATE_MAXIMIZED_HORZ))
- maximized |= 2;
- else if (states[i] == ATOM(_NET_WM_STATE_FULLSCREEN))
- full = true;
- }
- if (maximized == 3) {
- // only set maximized if both horizontal and vertical properties are set
- max = true;
- }
- }
- }
-
- bool send_event = false;
-
- if (X11->isSupportedByWM(ATOM(_NET_WM_STATE_MAXIMIZED_VERT))
- && X11->isSupportedByWM(ATOM(_NET_WM_STATE_MAXIMIZED_HORZ))) {
- if (max && !isMaximized()) {
- this->data->window_state = this->data->window_state | Qt::WindowMaximized;
- send_event = true;
- } else if (!max && isMaximized()) {
- this->data->window_state &= ~Qt::WindowMaximized;
- send_event = true;
- }
- }
-
- if (X11->isSupportedByWM(ATOM(_NET_WM_STATE_FULLSCREEN))) {
- if (full && !isFullScreen()) {
- this->data->window_state = this->data->window_state | Qt::WindowFullScreen;
- send_event = true;
- } else if (!full && isFullScreen()) {
- this->data->window_state &= ~Qt::WindowFullScreen;
- send_event = true;
- }
- }
-
- if (send_event) {
- QWindowStateChangeEvent e(oldState);
- QApplication::sendSpontaneousEvent(this, &e);
- }
- } else if (event->xproperty.atom == ATOM(WM_STATE)) {
- // the widget frame strut should also be invalidated
- this->data->fstrut_dirty = 1;
-
- if (event->xproperty.state == PropertyDelete) {
- // the window manager has removed the WM State property,
- // so it is now in the withdrawn state (ICCCM 4.1.3.1) and
- // we are free to reuse this window
- d->topData()->parentWinId = 0;
- d->topData()->validWMState = 0;
- // map the window if we were waiting for a transition to
- // withdrawn
- if (X11->deferred_map.removeAll(this)) {
- doDeferredMap();
- } else if (isVisible()
- && !testAttribute(Qt::WA_Mapped)
- && !testAttribute(Qt::WA_OutsideWSRange)) {
- // so that show() will work again. As stated in the
- // ICCCM section 4.1.4: "Only the client can effect a
- // transition into or out of the Withdrawn state.",
- // but apparently this particular window manager
- // doesn't seem to care
- setAttribute(Qt::WA_WState_ExplicitShowHide, false);
- setAttribute(Qt::WA_WState_Visible, false);
- }
- } else {
- // the window manager has changed the WM State property...
- // we are wanting to see if we are withdrawn so that we
- // can reuse this window...
- e = XGetWindowProperty(X11->display, internalWinId(), ATOM(WM_STATE), 0, 2, False,
- ATOM(WM_STATE), &ret, &format, &nitems, &after, &data);
-
- if (e == Success && ret == ATOM(WM_STATE) && format == 32 && nitems > 0) {
- long *state = (long *) data;
- switch (state[0]) {
- case WithdrawnState:
- // if we are in the withdrawn state, we are free
- // to reuse this window provided we remove the
- // WM_STATE property (ICCCM 4.1.3.1)
- XDeleteProperty(X11->display, internalWinId(), ATOM(WM_STATE));
-
- // set the parent id to zero, so that show() will
- // work again
- d->topData()->parentWinId = 0;
- d->topData()->validWMState = 0;
- // map the window if we were waiting for a
- // transition to withdrawn
- if (X11->deferred_map.removeAll(this)) {
- doDeferredMap();
- } else if (isVisible()
- && !testAttribute(Qt::WA_Mapped)
- && !testAttribute(Qt::WA_OutsideWSRange)) {
- // so that show() will work again. As stated
- // in the ICCCM section 4.1.4: "Only the
- // client can effect a transition into or out
- // of the Withdrawn state.", but apparently
- // this particular window manager doesn't seem
- // to care
- setAttribute(Qt::WA_WState_ExplicitShowHide, false);
- setAttribute(Qt::WA_WState_Visible, false);
- }
- break;
-
- case IconicState:
- d->topData()->validWMState = 1;
- if (!isMinimized()) {
- // window was minimized
- this->data->window_state = this->data->window_state | Qt::WindowMinimized;
- QWindowStateChangeEvent e(Qt::WindowStates(this->data->window_state & ~Qt::WindowMinimized));
- QApplication::sendSpontaneousEvent(this, &e);
- }
- break;
-
- default:
- d->topData()->validWMState = 1;
- if (isMinimized()) {
- // window was un-minimized
- this->data->window_state &= ~Qt::WindowMinimized;
- QWindowStateChangeEvent e(Qt::WindowStates(this->data->window_state | Qt::WindowMinimized));
- QApplication::sendSpontaneousEvent(this, &e);
- }
- break;
- }
- }
- }
- } else if (event->xproperty.atom == ATOM(_NET_WM_WINDOW_OPACITY)) {
- // the window opacity was changed
- if (event->xproperty.state == PropertyNewValue) {
- e = XGetWindowProperty(event->xclient.display,
- event->xclient.window,
- ATOM(_NET_WM_WINDOW_OPACITY),
- 0, 1, False, XA_CARDINAL,
- &ret, &format, &nitems, &after, &data);
-
- if (e == Success && ret == XA_CARDINAL && format == 32 && nitems == 1
- && after == 0 && data) {
- ulong value = *(ulong*)(data);
- d->topData()->opacity = uint(value >> 24);
- }
- } else
- d->topData()->opacity = 255;
- }
-
- if (data)
- XFree(data);
-
- return true;
-}
-
-
-//
-// Paint event translation
-//
-// When receiving many expose events, we compress them (union of all expose
-// rectangles) into one event which is sent to the widget.
-
-struct PaintEventInfo {
- Window window;
-};
-
-#if defined(Q_C_CALLBACKS)
-extern "C" {
-#endif
-
-static Bool isPaintOrScrollDoneEvent(Display *, XEvent *ev, XPointer a)
-{
- PaintEventInfo *info = (PaintEventInfo *)a;
- if (ev->type == Expose || ev->type == GraphicsExpose
- || (ev->type == ClientMessage && ev->xclient.message_type == ATOM(_QT_SCROLL_DONE)))
- {
- if (ev->xexpose.window == info->window)
- return True;
- }
- return False;
-}
-
-#if defined(Q_C_CALLBACKS)
-}
-#endif
-
-
-
-static
-bool translateBySips(QWidget* that, QRect& paintRect)
-{
- int dx=0, dy=0;
- int sips=0;
- for (int i = 0; i < X11->sip_list.size(); ++i) {
- const QX11Data::ScrollInProgress &sip = X11->sip_list.at(i);
- if (sip.scrolled_widget == that) {
- if (sips) {
- dx += sip.dx;
- dy += sip.dy;
- }
- sips++;
- }
- }
- if (sips > 1) {
- paintRect.translate(dx, dy);
- return true;
- }
- return false;
-}
-
-void QETWidget::translatePaintEvent(const XEvent *event)
-{
- if (!isWindow() && testAttribute(Qt::WA_NativeWindow))
- Q_ASSERT(internalWinId());
-
- Q_D(QWidget);
- QRect paintRect(event->xexpose.x, event->xexpose.y,
- event->xexpose.width, event->xexpose.height);
- XEvent xevent;
- PaintEventInfo info;
- info.window = internalWinId();
- translateBySips(this, paintRect);
- paintRect = d->mapFromWS(paintRect);
-
- QRegion paintRegion = paintRect;
-
- // WARNING: this is O(number_of_events * number_of_matching_events)
- while (XCheckIfEvent(X11->display,&xevent,isPaintOrScrollDoneEvent,
- (XPointer)&info) &&
- !qt_x11EventFilter(&xevent) &&
- !x11Event(&xevent)) // send event through filter
- {
- if (xevent.type == Expose || xevent.type == GraphicsExpose) {
- QRect exposure(xevent.xexpose.x,
- xevent.xexpose.y,
- xevent.xexpose.width,
- xevent.xexpose.height);
- translateBySips(this, exposure);
- exposure = d->mapFromWS(exposure);
- paintRegion |= exposure;
- } else {
- translateScrollDoneEvent(&xevent);
- }
- }
-
- if (!paintRegion.isEmpty() && !testAttribute(Qt::WA_WState_ConfigPending))
- d->syncBackingStore(paintRegion);
-}
-
-//
-// Scroll-done event translation.
-//
-
-bool QETWidget::translateScrollDoneEvent(const XEvent *event)
-{
- long id = event->xclient.data.l[0];
-
- // Remove any scroll-in-progress record for the given id.
- for (int i = 0; i < X11->sip_list.size(); ++i) {
- const QX11Data::ScrollInProgress &sip = X11->sip_list.at(i);
- if (sip.id == id) {
- X11->sip_list.removeAt(i);
- return true;
- }
- }
-
- return false;
-}
-
-//
-// ConfigureNotify (window move and resize) event translation
-
-bool QETWidget::translateConfigEvent(const XEvent *event)
-{
- Q_ASSERT((!isWindow() && !testAttribute(Qt::WA_NativeWindow)) ? internalWinId() : true);
-
- Q_D(QWidget);
- bool wasResize = testAttribute(Qt::WA_WState_ConfigPending); // set in QWidget::setGeometry_sys()
- setAttribute(Qt::WA_WState_ConfigPending, false);
-
- if (testAttribute(Qt::WA_OutsideWSRange)) {
- // discard events for windows that have a geometry X can't handle
- XEvent xevent;
- while (XCheckTypedWindowEvent(X11->display,internalWinId(), ConfigureNotify,&xevent) &&
- !qt_x11EventFilter(&xevent) &&
- !x11Event(&xevent)) // send event through filter
- ;
- return true;
- }
-
- const QSize oldSize = size();
-
- if (isWindow()) {
- QPoint newCPos(geometry().topLeft());
- QSize newSize(event->xconfigure.width, event->xconfigure.height);
-
- bool trust = isVisible()
- && (d->topData()->parentWinId == XNone ||
- d->topData()->parentWinId == QX11Info::appRootWindow());
- bool isCPos = false;
-
- if (event->xconfigure.send_event || trust) {
- // if a ConfigureNotify comes from a real sendevent request, we can
- // trust its values.
- newCPos.rx() = event->xconfigure.x + event->xconfigure.border_width;
- newCPos.ry() = event->xconfigure.y + event->xconfigure.border_width;
- isCPos = true;
- }
- if (isVisible())
- QApplication::syncX();
-
- if (d->extra->compress_events) {
- // ConfigureNotify compression for faster opaque resizing
- XEvent otherEvent;
- while (XCheckTypedWindowEvent(X11->display, internalWinId(), ConfigureNotify,
- &otherEvent)) {
- if (qt_x11EventFilter(&otherEvent))
- continue;
-
- if (x11Event(&otherEvent))
- continue;
-
- if (otherEvent.xconfigure.event != otherEvent.xconfigure.window)
- continue;
-
- newSize.setWidth(otherEvent.xconfigure.width);
- newSize.setHeight(otherEvent.xconfigure.height);
-
- if (otherEvent.xconfigure.send_event || trust) {
- newCPos.rx() = otherEvent.xconfigure.x +
- otherEvent.xconfigure.border_width;
- newCPos.ry() = otherEvent.xconfigure.y +
- otherEvent.xconfigure.border_width;
- isCPos = true;
- }
- }
-#ifndef QT_NO_XSYNC
- qt_sync_request_event_data sync_event;
- sync_event.window = internalWinId();
- for (XEvent ev;;) {
- if (!XCheckIfEvent(X11->display, &ev, &qt_sync_request_scanner, (XPointer)&sync_event))
- break;
- }
-#endif // QT_NO_XSYNC
- }
-
- if (!isCPos) {
- // we didn't get an updated position of the toplevel.
- // either we haven't moved or there is a bug in the window manager.
- // anyway, let's query the position to be certain.
- int x, y;
- Window child;
- XTranslateCoordinates(X11->display, internalWinId(),
- QApplication::desktop()->screen(d->xinfo.screen())->internalWinId(),
- 0, 0, &x, &y, &child);
- newCPos.rx() = x;
- newCPos.ry() = y;
- }
-
- QRect cr (geometry());
- if (newCPos != cr.topLeft()) { // compare with cpos (exluding frame)
- QPoint oldPos = geometry().topLeft();
- cr.moveTopLeft(newCPos);
- data->crect = cr;
- if (isVisible()) {
- QMoveEvent e(newCPos, oldPos); // pos (including frame), not cpos
- QApplication::sendSpontaneousEvent(this, &e);
- } else {
- setAttribute(Qt::WA_PendingMoveEvent, true);
- }
- }
- if (newSize != cr.size()) { // size changed
- cr.setSize(newSize);
- data->crect = cr;
-
- uint old_state = data->window_state;
- if (!X11->isSupportedByWM(ATOM(_NET_WM_STATE_MAXIMIZED_VERT))
- && !X11->isSupportedByWM(ATOM(_NET_WM_STATE_MAXIMIZED_HORZ)))
- data->window_state &= ~Qt::WindowMaximized;
- if (!X11->isSupportedByWM(ATOM(_NET_WM_STATE_FULLSCREEN)))
- data->window_state &= ~Qt::WindowFullScreen;
-
- if (old_state != data->window_state) {
- QWindowStateChangeEvent e((Qt::WindowStates) old_state);
- QApplication::sendEvent(this, &e);
- }
-
- if (!isVisible())
- setAttribute(Qt::WA_PendingResizeEvent, true);
- wasResize = true;
- }
-
- } else {
- XEvent xevent;
- while (XCheckTypedWindowEvent(X11->display,internalWinId(), ConfigureNotify,&xevent) &&
- !qt_x11EventFilter(&xevent) &&
- !x11Event(&xevent)) // send event through filter
- ;
- }
-
- if (wasResize) {
- if (isVisible() && data->crect.size() != oldSize) {
- Q_ASSERT(d->extra->topextra);
- QWidgetBackingStore *bs = d->extra->topextra->backingStore.data();
- const bool hasStaticContents = bs && bs->hasStaticContents();
- // If we have a backing store with static contents, we have to disable the top-level
- // resize optimization in order to get invalidated regions for resized widgets.
- // The optimization discards all invalidateBuffer() calls since we're going to
- // repaint everything anyways, but that's not the case with static contents.
- if (!hasStaticContents)
- d->extra->topextra->inTopLevelResize = true;
- QResizeEvent e(data->crect.size(), oldSize);
- QApplication::sendSpontaneousEvent(this, &e);
- }
-
- const bool waitingForMapNotify = d->extra->topextra && d->extra->topextra->waitingForMapNotify;
- if (!waitingForMapNotify) {
- if (d->paintOnScreen()) {
- QRegion updateRegion(rect());
- if (testAttribute(Qt::WA_StaticContents))
- updateRegion -= QRect(0, 0, oldSize.width(), oldSize.height());
- d->syncBackingStore(updateRegion);
- } else {
- d->syncBackingStore();
- }
- }
-
- if (d->extra && d->extra->topextra)
- d->extra->topextra->inTopLevelResize = false;
- }
-#ifndef QT_NO_XSYNC
- if (QTLWExtra *tlwExtra = d->maybeTopData()) {
- if (tlwExtra->newCounterValueLo != 0 || tlwExtra->newCounterValueHi != 0) {
- XSyncValue value;
- XSyncIntsToValue(&value,
- tlwExtra->newCounterValueLo,
- tlwExtra->newCounterValueHi);
-
- XSyncSetCounter(X11->display, tlwExtra->syncUpdateCounter, value);
- tlwExtra->newCounterValueHi = 0;
- tlwExtra->newCounterValueLo = 0;
- }
- }
-#endif
- return true;
-}
-
-//
-// Close window event translation.
-//
-bool QETWidget::translateCloseEvent(const XEvent *)
-{
- Q_D(QWidget);
- return d->close_helper(QWidgetPrivate::CloseWithSpontaneousEvent);
-}
-
-
-void QApplication::setCursorFlashTime(int msecs)
-{
- QApplicationPrivate::cursor_flash_time = msecs;
-}
-
-int QApplication::cursorFlashTime()
-{
- return QApplicationPrivate::cursor_flash_time;
-}
-
-void QApplication::setDoubleClickInterval(int ms)
-{
- QApplicationPrivate::mouse_double_click_time = ms;
-}
-
-int QApplication::doubleClickInterval()
-{
- return QApplicationPrivate::mouse_double_click_time;
-}
-
-void QApplication::setKeyboardInputInterval(int ms)
-{
- QApplicationPrivate::keyboard_input_time = ms;
-}
-
-int QApplication::keyboardInputInterval()
-{
- return QApplicationPrivate::keyboard_input_time;
-}
-
-#ifndef QT_NO_WHEELEVENT
-void QApplication::setWheelScrollLines(int n)
-{
- QApplicationPrivate::wheel_scroll_lines = n;
-}
-
-int QApplication::wheelScrollLines()
-{
- return QApplicationPrivate::wheel_scroll_lines;
-}
-#endif
-
-void QApplication::setEffectEnabled(Qt::UIEffect effect, bool enable)
-{
- switch (effect) {
- case Qt::UI_AnimateMenu:
- if (enable) QApplicationPrivate::fade_menu = false;
- QApplicationPrivate::animate_menu = enable;
- break;
- case Qt::UI_FadeMenu:
- if (enable)
- QApplicationPrivate::animate_menu = true;
- QApplicationPrivate::fade_menu = enable;
- break;
- case Qt::UI_AnimateCombo:
- QApplicationPrivate::animate_combo = enable;
- break;
- case Qt::UI_AnimateTooltip:
- if (enable) QApplicationPrivate::fade_tooltip = false;
- QApplicationPrivate::animate_tooltip = enable;
- break;
- case Qt::UI_FadeTooltip:
- if (enable)
- QApplicationPrivate::animate_tooltip = true;
- QApplicationPrivate::fade_tooltip = enable;
- break;
- case Qt::UI_AnimateToolBox:
- QApplicationPrivate::animate_toolbox = enable;
- break;
- default:
- QApplicationPrivate::animate_ui = enable;
- break;
- }
-}
-
-bool QApplication::isEffectEnabled(Qt::UIEffect effect)
-{
- if (QColormap::instance().depth() < 16 || !QApplicationPrivate::animate_ui)
- return false;
-
- switch(effect) {
- case Qt::UI_AnimateMenu:
- return QApplicationPrivate::animate_menu;
- case Qt::UI_FadeMenu:
- return QApplicationPrivate::fade_menu;
- case Qt::UI_AnimateCombo:
- return QApplicationPrivate::animate_combo;
- case Qt::UI_AnimateTooltip:
- return QApplicationPrivate::animate_tooltip;
- case Qt::UI_FadeTooltip:
- return QApplicationPrivate::fade_tooltip;
- case Qt::UI_AnimateToolBox:
- return QApplicationPrivate::animate_toolbox;
- default:
- return QApplicationPrivate::animate_ui;
- }
-}
-
-/*****************************************************************************
- Session management support
- *****************************************************************************/
-
-#ifndef QT_NO_SESSIONMANAGER
-
-QT_BEGIN_INCLUDE_NAMESPACE
-#include <X11/SM/SMlib.h>
-QT_END_INCLUDE_NAMESPACE
-
-class QSessionManagerPrivate : public QObjectPrivate
-{
-public:
- QSessionManagerPrivate(QSessionManager* mgr, QString& id, QString& key)
- : QObjectPrivate(), sm(mgr), sessionId(id), sessionKey(key),
- restartHint(QSessionManager::RestartIfRunning), eventLoop(0) {}
- QSessionManager* sm;
- QStringList restartCommand;
- QStringList discardCommand;
- QString& sessionId;
- QString& sessionKey;
- QSessionManager::RestartHint restartHint;
- QEventLoop *eventLoop;
-};
-
-class QSmSocketReceiver : public QObject
-{
- Q_OBJECT
-public:
- QSmSocketReceiver(int socket)
- {
- QSocketNotifier* sn = new QSocketNotifier(socket, QSocketNotifier::Read, this);
- connect(sn, SIGNAL(activated(int)), this, SLOT(socketActivated(int)));
- }
-
-public slots:
- void socketActivated(int);
-};
-
-
-static SmcConn smcConnection = 0;
-static bool sm_interactionActive;
-static bool sm_smActive;
-static int sm_interactStyle;
-static int sm_saveType;
-static bool sm_cancel;
-// static bool sm_waitingForPhase2; ### never used?!?
-static bool sm_waitingForInteraction;
-static bool sm_isshutdown;
-// static bool sm_shouldbefast; ### never used?!?
-static bool sm_phase2;
-static bool sm_in_phase2;
-
-static QSmSocketReceiver* sm_receiver = 0;
-
-static void resetSmState();
-static void sm_setProperty(const char* name, const char* type,
- int num_vals, SmPropValue* vals);
-static void sm_saveYourselfCallback(SmcConn smcConn, SmPointer clientData,
- int saveType, Bool shutdown , int interactStyle, Bool fast);
-static void sm_saveYourselfPhase2Callback(SmcConn smcConn, SmPointer clientData) ;
-static void sm_dieCallback(SmcConn smcConn, SmPointer clientData) ;
-static void sm_shutdownCancelledCallback(SmcConn smcConn, SmPointer clientData);
-static void sm_saveCompleteCallback(SmcConn smcConn, SmPointer clientData);
-static void sm_interactCallback(SmcConn smcConn, SmPointer clientData);
-static void sm_performSaveYourself(QSessionManagerPrivate*);
-
-static void resetSmState()
-{
-// sm_waitingForPhase2 = false; ### never used?!?
- sm_waitingForInteraction = false;
- sm_interactionActive = false;
- sm_interactStyle = SmInteractStyleNone;
- sm_smActive = false;
- qt_sm_blockUserInput = false;
- sm_isshutdown = false;
-// sm_shouldbefast = false; ### never used?!?
- sm_phase2 = false;
- sm_in_phase2 = false;
-}
-
-
-// theoretically it's possible to set several properties at once. For
-// simplicity, however, we do just one property at a time
-static void sm_setProperty(const char* name, const char* type,
- int num_vals, SmPropValue* vals)
-{
- if (num_vals) {
- SmProp prop;
- prop.name = (char*)name;
- prop.type = (char*)type;
- prop.num_vals = num_vals;
- prop.vals = vals;
-
- SmProp* props[1];
- props[0] = &prop;
- SmcSetProperties(smcConnection, 1, props);
- }
- else {
- char* names[1];
- names[0] = (char*) name;
- SmcDeleteProperties(smcConnection, 1, names);
- }
-}
-
-static void sm_setProperty(const QString& name, const QString& value)
-{
- QByteArray v = value.toUtf8();
- SmPropValue prop;
- prop.length = v.length();
- prop.value = (SmPointer) v.constData();
- sm_setProperty(name.toLatin1().data(), SmARRAY8, 1, &prop);
-}
-
-static void sm_setProperty(const QString& name, const QStringList& value)
-{
- SmPropValue *prop = new SmPropValue[value.count()];
- int count = 0;
- QList<QByteArray> vl;
- for (QStringList::ConstIterator it = value.begin(); it != value.end(); ++it) {
- prop[count].length = (*it).length();
- vl.append((*it).toUtf8());
- prop[count].value = (char*)vl.last().data();
- ++count;
- }
- sm_setProperty(name.toLatin1().data(), SmLISTofARRAY8, count, prop);
- delete [] prop;
-}
-
-
-// workaround for broken libsm, see below
-struct QT_smcConn {
- unsigned int save_yourself_in_progress : 1;
- unsigned int shutdown_in_progress : 1;
-};
-
-static void sm_saveYourselfCallback(SmcConn smcConn, SmPointer clientData,
- int saveType, Bool shutdown , int interactStyle, Bool /*fast*/)
-{
- if (smcConn != smcConnection)
- return;
- sm_cancel = false;
- sm_smActive = true;
- sm_isshutdown = shutdown;
- sm_saveType = saveType;
- sm_interactStyle = interactStyle;
-// sm_shouldbefast = fast; ### never used?!?
-
- // ugly workaround for broken libSM. libSM should do that _before_
- // actually invoking the callback in sm_process.c
- ((QT_smcConn*)smcConn)->save_yourself_in_progress = true;
- if (sm_isshutdown)
- ((QT_smcConn*)smcConn)->shutdown_in_progress = true;
-
- sm_performSaveYourself((QSessionManagerPrivate*) clientData);
- if (!sm_isshutdown) // we cannot expect a confirmation message in that case
- resetSmState();
-}
-
-static void sm_performSaveYourself(QSessionManagerPrivate* smd)
-{
- if (sm_isshutdown)
- qt_sm_blockUserInput = true;
-
- QSessionManager* sm = smd->sm;
-
- // generate a new session key
- timeval tv;
- gettimeofday(&tv, 0);
- smd->sessionKey = QString::number(qulonglong(tv.tv_sec)) + QLatin1Char('_') + QString::number(qulonglong(tv.tv_usec));
-
- QStringList arguments = qApp->arguments();
- QString argument0 = arguments.isEmpty() ? qApp->applicationFilePath() : arguments.at(0);
-
- // tell the session manager about our program in best POSIX style
- sm_setProperty(QString::fromLatin1(SmProgram), argument0);
- // tell the session manager about our user as well.
- struct passwd *entryPtr = 0;
-#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) && (_POSIX_THREAD_SAFE_FUNCTIONS - 0 > 0)
- QVarLengthArray<char, 1024> buf(qMax<long>(sysconf(_SC_GETPW_R_SIZE_MAX), 1024L));
- struct passwd entry;
- while (getpwuid_r(geteuid(), &entry, buf.data(), buf.size(), &entryPtr) == ERANGE) {
- if (buf.size() >= 32768) {
- // too big already, fail
- static char badusername[] = "";
- entryPtr = &entry;
- entry.pw_name = badusername;
- break;
- }
-
- // retry with a bigger buffer
- buf.resize(buf.size() * 2);
- }
-#else
- entryPtr = getpwuid(geteuid());
-#endif
- if (entryPtr)
- sm_setProperty(QString::fromLatin1(SmUserID), QString::fromLatin1(entryPtr->pw_name));
-
- // generate a restart and discard command that makes sense
- QStringList restart;
- restart << argument0 << QLatin1String("-session")
- << smd->sessionId + QLatin1Char('_') + smd->sessionKey;
- if (qstricmp(appName, QX11Info::appClass()) != 0)
- restart << QLatin1String("-name") << qAppName();
- sm->setRestartCommand(restart);
- QStringList discard;
- sm->setDiscardCommand(discard);
-
- switch (sm_saveType) {
- case SmSaveBoth:
- qApp->commitData(*sm);
- if (sm_isshutdown && sm_cancel)
- break; // we cancelled the shutdown, no need to save state
- // fall through
- case SmSaveLocal:
- qApp->saveState(*sm);
- break;
- case SmSaveGlobal:
- qApp->commitData(*sm);
- break;
- default:
- break;
- }
-
- if (sm_phase2 && !sm_in_phase2) {
- SmcRequestSaveYourselfPhase2(smcConnection, sm_saveYourselfPhase2Callback, (SmPointer*) smd);
- qt_sm_blockUserInput = false;
- }
- else {
- // close eventual interaction monitors and cancel the
- // shutdown, if required. Note that we can only cancel when
- // performing a shutdown, it does not work for checkpoints
- if (sm_interactionActive) {
- SmcInteractDone(smcConnection, sm_isshutdown && sm_cancel);
- sm_interactionActive = false;
- }
- else if (sm_cancel && sm_isshutdown) {
- if (sm->allowsErrorInteraction()) {
- SmcInteractDone(smcConnection, True);
- sm_interactionActive = false;
- }
- }
-
- // set restart and discard command in session manager
- sm_setProperty(QString::fromLatin1(SmRestartCommand), sm->restartCommand());
- sm_setProperty(QString::fromLatin1(SmDiscardCommand), sm->discardCommand());
-
- // set the restart hint
- SmPropValue prop;
- prop.length = sizeof(int);
- int value = sm->restartHint();
- prop.value = (SmPointer) &value;
- sm_setProperty(SmRestartStyleHint, SmCARD8, 1, &prop);
-
- // we are done
- SmcSaveYourselfDone(smcConnection, !sm_cancel);
- }
-}
-
-static void sm_dieCallback(SmcConn smcConn, SmPointer /* clientData */)
-{
- if (smcConn != smcConnection)
- return;
- resetSmState();
- QEvent quitEvent(QEvent::Quit);
- QApplication::sendEvent(qApp, &quitEvent);
-}
-
-static void sm_shutdownCancelledCallback(SmcConn smcConn, SmPointer clientData)
-{
- if (smcConn != smcConnection)
- return;
- if (sm_waitingForInteraction)
- ((QSessionManagerPrivate *) clientData)->eventLoop->exit();
- resetSmState();
-}
-
-static void sm_saveCompleteCallback(SmcConn smcConn, SmPointer /*clientData */)
-{
- if (smcConn != smcConnection)
- return;
- resetSmState();
-}
-
-static void sm_interactCallback(SmcConn smcConn, SmPointer clientData)
-{
- if (smcConn != smcConnection)
- return;
- if (sm_waitingForInteraction)
- ((QSessionManagerPrivate *) clientData)->eventLoop->exit();
-}
-
-static void sm_saveYourselfPhase2Callback(SmcConn smcConn, SmPointer clientData)
-{
- if (smcConn != smcConnection)
- return;
- sm_in_phase2 = true;
- sm_performSaveYourself((QSessionManagerPrivate*) clientData);
-}
-
-
-void QSmSocketReceiver::socketActivated(int)
-{
- IceProcessMessages(SmcGetIceConnection(smcConnection), 0, 0);
-}
-
-
-#undef Bool
-QT_BEGIN_INCLUDE_NAMESPACE
-#include "qapplication_x11.moc"
-QT_END_INCLUDE_NAMESPACE
-
-QSessionManager::QSessionManager(QApplication * app, QString &id, QString& key)
- : QObject(*new QSessionManagerPrivate(this, id, key), app)
-{
- Q_D(QSessionManager);
- d->restartHint = RestartIfRunning;
-
- resetSmState();
- char cerror[256];
- char* myId = 0;
- QByteArray b_id = id.toLatin1();
- char* prevId = b_id.data();
-
- SmcCallbacks cb;
- cb.save_yourself.callback = sm_saveYourselfCallback;
- cb.save_yourself.client_data = (SmPointer) d;
- cb.die.callback = sm_dieCallback;
- cb.die.client_data = (SmPointer) d;
- cb.save_complete.callback = sm_saveCompleteCallback;
- cb.save_complete.client_data = (SmPointer) d;
- cb.shutdown_cancelled.callback = sm_shutdownCancelledCallback;
- cb.shutdown_cancelled.client_data = (SmPointer) d;
-
- // avoid showing a warning message below
- if (qgetenv("SESSION_MANAGER").isEmpty())
- return;
-
- smcConnection = SmcOpenConnection(0, 0, 1, 0,
- SmcSaveYourselfProcMask |
- SmcDieProcMask |
- SmcSaveCompleteProcMask |
- SmcShutdownCancelledProcMask,
- &cb,
- prevId,
- &myId,
- 256, cerror);
-
- id = QString::fromLatin1(myId);
- ::free(myId); // it was allocated by C
-
- QString error = QString::fromLocal8Bit(cerror);
- if (!smcConnection) {
- qWarning("Qt: Session management error: %s", qPrintable(error));
- }
- else {
- sm_receiver = new QSmSocketReceiver(IceConnectionNumber(SmcGetIceConnection(smcConnection)));
- }
-}
-
-QSessionManager::~QSessionManager()
-{
- if (smcConnection)
- SmcCloseConnection(smcConnection, 0, 0);
- smcConnection = 0;
- delete sm_receiver;
-}
-
-QString QSessionManager::sessionId() const
-{
- Q_D(const QSessionManager);
- return d->sessionId;
-}
-
-QString QSessionManager::sessionKey() const
-{
- Q_D(const QSessionManager);
- return d->sessionKey;
-}
-
-
-void* QSessionManager::handle() const
-{
- return (void*) smcConnection;
-}
-
-
-bool QSessionManager::allowsInteraction()
-{
- Q_D(QSessionManager);
- if (sm_interactionActive)
- return true;
-
- if (sm_waitingForInteraction)
- return false;
-
- if (sm_interactStyle == SmInteractStyleAny) {
- sm_waitingForInteraction = SmcInteractRequest(smcConnection, SmDialogNormal,
- sm_interactCallback, (SmPointer*) d);
- }
- if (sm_waitingForInteraction) {
- QEventLoop eventLoop;
- d->eventLoop = &eventLoop;
- (void) eventLoop.exec();
- d->eventLoop = 0;
-
- sm_waitingForInteraction = false;
- if (sm_smActive) { // not cancelled
- sm_interactionActive = true;
- qt_sm_blockUserInput = false;
- return true;
- }
- }
- return false;
-}
-
-bool QSessionManager::allowsErrorInteraction()
-{
- Q_D(QSessionManager);
- if (sm_interactionActive)
- return true;
-
- if (sm_waitingForInteraction)
- return false;
-
- if (sm_interactStyle == SmInteractStyleAny || sm_interactStyle == SmInteractStyleErrors) {
- sm_waitingForInteraction = SmcInteractRequest(smcConnection, SmDialogError,
- sm_interactCallback, (SmPointer*) d);
- }
- if (sm_waitingForInteraction) {
- QEventLoop eventLoop;
- d->eventLoop = &eventLoop;
- (void) eventLoop.exec();
- d->eventLoop = 0;
-
- sm_waitingForInteraction = false;
- if (sm_smActive) { // not cancelled
- sm_interactionActive = true;
- qt_sm_blockUserInput = false;
- return true;
- }
- }
- return false;
-}
-
-void QSessionManager::release()
-{
- if (sm_interactionActive) {
- SmcInteractDone(smcConnection, False);
- sm_interactionActive = false;
- if (sm_smActive && sm_isshutdown)
- qt_sm_blockUserInput = true;
- }
-}
-
-void QSessionManager::cancel()
-{
- sm_cancel = true;
-}
-
-void QSessionManager::setRestartHint(QSessionManager::RestartHint hint)
-{
- Q_D(QSessionManager);
- d->restartHint = hint;
-}
-
-QSessionManager::RestartHint QSessionManager::restartHint() const
-{
- Q_D(const QSessionManager);
- return d->restartHint;
-}
-
-void QSessionManager::setRestartCommand(const QStringList& command)
-{
- Q_D(QSessionManager);
- d->restartCommand = command;
-}
-
-QStringList QSessionManager::restartCommand() const
-{
- Q_D(const QSessionManager);
- return d->restartCommand;
-}
-
-void QSessionManager::setDiscardCommand(const QStringList& command)
-{
- Q_D(QSessionManager);
- d->discardCommand = command;
-}
-
-QStringList QSessionManager::discardCommand() const
-{
- Q_D(const QSessionManager);
- return d->discardCommand;
-}
-
-void QSessionManager::setManagerProperty(const QString& name, const QString& value)
-{
- sm_setProperty(name, value);
-}
-
-void QSessionManager::setManagerProperty(const QString& name, const QStringList& value)
-{
- sm_setProperty(name, value);
-}
-
-bool QSessionManager::isPhase2() const
-{
- return sm_in_phase2;
-}
-
-void QSessionManager::requestPhase2()
-{
- sm_phase2 = true;
-}
-
-#endif // QT_NO_SESSIONMANAGER
-
-#if defined(QT_RX71_MULTITOUCH)
-
-static inline int testBit(const char *array, int bit)
-{
- return (array[bit/8] & (1<<(bit%8)));
-}
-
-static int openRX71Device(const QByteArray &deviceName)
-{
- int fd = open(deviceName, O_RDONLY | O_NONBLOCK);
- if (fd == -1) {
- fd = -errno;
- return fd;
- }
-
- // fetch the event type mask and check that the device reports absolute coordinates
- char eventTypeMask[(EV_MAX + sizeof(char) - 1) * sizeof(char) + 1];
- memset(eventTypeMask, 0, sizeof(eventTypeMask));
- if (ioctl(fd, EVIOCGBIT(0, sizeof(eventTypeMask)), eventTypeMask) < 0) {
- close(fd);
- return -1;
- }
- if (!testBit(eventTypeMask, EV_ABS)) {
- close(fd);
- return -1;
- }
-
- // make sure that we can get the absolute X and Y positions from the device
- char absMask[(ABS_MAX + sizeof(char) - 1) * sizeof(char) + 1];
- memset(absMask, 0, sizeof(absMask));
- if (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absMask)), absMask) < 0) {
- close(fd);
- return -1;
- }
- if (!testBit(absMask, ABS_X) || !testBit(absMask, ABS_Y)) {
- close(fd);
- return -1;
- }
-
- return fd;
-}
-
-void QApplicationPrivate::initializeMultitouch_sys()
-{
- Q_Q(QApplication);
-
- QByteArray deviceName = QByteArray("/dev/input/event");
- int currentDeviceNumber = 0;
- for (;;) {
- int fd = openRX71Device(QByteArray(deviceName + QByteArray::number(currentDeviceNumber++)));
- if (fd == -ENOENT) {
- // no more devices
- break;
- }
- if (fd < 0) {
- // not a touch device
- continue;
- }
-
- struct input_absinfo abs_x, abs_y, abs_z;
- ioctl(fd, EVIOCGABS(ABS_X), &abs_x);
- ioctl(fd, EVIOCGABS(ABS_Y), &abs_y);
- ioctl(fd, EVIOCGABS(ABS_Z), &abs_z);
-
- int deviceNumber = allRX71TouchPoints.count();
-
- QSocketNotifier *socketNotifier = new QSocketNotifier(fd, QSocketNotifier::Read, q);
- QObject::connect(socketNotifier, SIGNAL(activated(int)), q, SLOT(_q_readRX71MultiTouchEvents()));
-
- RX71TouchPointState touchPointState = {
- socketNotifier,
- QTouchEvent::TouchPoint(deviceNumber),
-
- abs_x.minimum, abs_x.maximum, q->desktop()->screenGeometry().width(),
- abs_y.minimum, abs_y.maximum, q->desktop()->screenGeometry().height(),
- abs_z.minimum, abs_z.maximum
- };
- allRX71TouchPoints.append(touchPointState);
- }
-
- hasRX71MultiTouch = allRX71TouchPoints.count() > 1;
- if (!hasRX71MultiTouch) {
- for (int i = 0; i < allRX71TouchPoints.count(); ++i) {
- QSocketNotifier *socketNotifier = allRX71TouchPoints.at(i).socketNotifier;
- close(socketNotifier->socket());
- delete socketNotifier;
- }
- allRX71TouchPoints.clear();
- }
-}
-
-void QApplicationPrivate::cleanupMultitouch_sys()
-{
- hasRX71MultiTouch = false;
- for (int i = 0; i < allRX71TouchPoints.count(); ++i) {
- QSocketNotifier *socketNotifier = allRX71TouchPoints.at(i).socketNotifier;
- close(socketNotifier->socket());
- delete socketNotifier;
- }
- allRX71TouchPoints.clear();
-}
-
-bool QApplicationPrivate::readRX71MultiTouchEvents(int deviceNumber)
-{
- RX71TouchPointState &touchPointState = allRX71TouchPoints[deviceNumber];
- QSocketNotifier *socketNotifier = touchPointState.socketNotifier;
- int fd = socketNotifier->socket();
-
- QTouchEvent::TouchPoint &touchPoint = touchPointState.touchPoint;
-
- bool down = touchPoint.state() != Qt::TouchPointReleased;
- if (down)
- touchPoint.setState(Qt::TouchPointStationary);
-
- bool changed = false;
- for (;;) {
- struct input_event inputEvent;
- int bytesRead = read(fd, &inputEvent, sizeof(inputEvent));
- if (bytesRead <= 0)
- break;
- if (bytesRead != sizeof(inputEvent)) {
- qWarning("Qt: INTERNAL ERROR: short read in readRX71MultiTouchEvents()");
- return false;
- }
-
- switch (inputEvent.type) {
- case EV_SYN:
- changed = true;
- switch (touchPoint.state()) {
- case Qt::TouchPointPressed:
- case Qt::TouchPointReleased:
- // make sure we don't compress pressed and releases with any other events
- return changed;
- default:
- break;
- }
- continue;
- case EV_KEY:
- case EV_ABS:
- break;
- default:
- qWarning("Qt: WARNING: unknown event type %d on multitouch device", inputEvent.type);
- continue;
- }
-
- QPointF screenPos = touchPoint.screenPos();
- switch (inputEvent.code) {
- case BTN_TOUCH:
- if (!down && inputEvent.value != 0)
- touchPoint.setState(Qt::TouchPointPressed);
- else if (down && inputEvent.value == 0)
- touchPoint.setState(Qt::TouchPointReleased);
- break;
- case ABS_TOOL_WIDTH:
- case ABS_VOLUME:
- case ABS_PRESSURE:
- // ignore for now
- break;
- case ABS_X:
- {
- qreal newValue = ((qreal(inputEvent.value - touchPointState.minX)
- / qreal(touchPointState.maxX - touchPointState.minX))
- * touchPointState.scaleX);
- screenPos.rx() = newValue;
- touchPoint.setScreenPos(screenPos);
- break;
- }
- case ABS_Y:
- {
- qreal newValue = ((qreal(inputEvent.value - touchPointState.minY)
- / qreal(touchPointState.maxY - touchPointState.minY))
- * touchPointState.scaleY);
- screenPos.ry() = newValue;
- touchPoint.setScreenPos(screenPos);
- break;
- }
- case ABS_Z:
- {
- // map Z (signal strength) to pressure for now
- qreal newValue = (qreal(inputEvent.value - touchPointState.minZ)
- / qreal(touchPointState.maxZ - touchPointState.minZ));
- touchPoint.setPressure(newValue);
- break;
- }
- default:
- qWarning("Qt: WARNING: unknown event code %d on multitouch device", inputEvent.code);
- continue;
- }
- }
-
- if (down && touchPoint.state() != Qt::TouchPointReleased)
- touchPoint.setState(changed ? Qt::TouchPointMoved : Qt::TouchPointStationary);
-
- return changed;
-}
-
-void QApplicationPrivate::_q_readRX71MultiTouchEvents()
-{
- // read touch events from all devices
- bool changed = false;
- for (int i = 0; i < allRX71TouchPoints.count(); ++i)
- changed = readRX71MultiTouchEvents(i) || changed;
- if (!changed)
- return;
-
- QList<QTouchEvent::TouchPoint> touchPoints;
- for (int i = 0; i < allRX71TouchPoints.count(); ++i)
- touchPoints.append(allRX71TouchPoints.at(i).touchPoint);
-
- translateRawTouchEvent(0, QTouchEvent::TouchScreen, touchPoints);
-}
-
-#else // !QT_RX71_MULTITOUCH
-
-void QApplicationPrivate::initializeMultitouch_sys()
-{ }
-void QApplicationPrivate::cleanupMultitouch_sys()
-{ }
-
-#endif // QT_RX71_MULTITOUCH
-
-QT_END_NAMESPACE
diff --git a/src/gui/kernel/qboxlayout.h b/src/gui/kernel/qboxlayout.h
deleted file mode 100644
index d0de651387..0000000000
--- a/src/gui/kernel/qboxlayout.h
+++ /dev/null
@@ -1,173 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QBOXLAYOUT_H
-#define QBOXLAYOUT_H
-
-#include <QtGui/qlayout.h>
-#ifdef QT_INCLUDE_COMPAT
-#include <QtGui/qwidget.h>
-#endif
-
-#include <limits.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QBoxLayoutPrivate;
-
-class Q_GUI_EXPORT QBoxLayout : public QLayout
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QBoxLayout)
-public:
- enum Direction { LeftToRight, RightToLeft, TopToBottom, BottomToTop,
- Down = TopToBottom, Up = BottomToTop };
-
- explicit QBoxLayout(Direction, QWidget *parent = 0);
-
-#ifdef QT3_SUPPORT
- QT3_SUPPORT_CONSTRUCTOR QBoxLayout(QWidget *parent, Direction, int border = 0, int spacing = -1,
- const char *name = 0);
- QT3_SUPPORT_CONSTRUCTOR QBoxLayout(QLayout *parentLayout, Direction, int spacing = -1,
- const char *name = 0);
- QT3_SUPPORT_CONSTRUCTOR QBoxLayout(Direction, int spacing, const char *name = 0);
-#endif
- ~QBoxLayout();
-
- Direction direction() const;
- void setDirection(Direction);
-
- void addSpacing(int size);
- void addStretch(int stretch = 0);
- void addSpacerItem(QSpacerItem *spacerItem);
- void addWidget(QWidget *, int stretch = 0, Qt::Alignment alignment = 0);
- void addLayout(QLayout *layout, int stretch = 0);
- void addStrut(int);
- void addItem(QLayoutItem *);
-
- void insertSpacing(int index, int size);
- void insertStretch(int index, int stretch = 0);
- void insertSpacerItem(int index, QSpacerItem *spacerItem);
- void insertWidget(int index, QWidget *widget, int stretch = 0, Qt::Alignment alignment = 0);
- void insertLayout(int index, QLayout *layout, int stretch = 0);
-
- int spacing() const;
- void setSpacing(int spacing);
-
- bool setStretchFactor(QWidget *w, int stretch);
- bool setStretchFactor(QLayout *l, int stretch);
- void setStretch(int index, int stretch);
- int stretch(int index) const;
-
- QSize sizeHint() const;
- QSize minimumSize() const;
- QSize maximumSize() const;
-
- bool hasHeightForWidth() const;
- int heightForWidth(int) const;
- int minimumHeightForWidth(int) const;
-
- Qt::Orientations expandingDirections() const;
- void invalidate();
- QLayoutItem *itemAt(int) const;
- QLayoutItem *takeAt(int);
- int count() const;
- void setGeometry(const QRect&);
-#ifdef QT3_SUPPORT
- inline QT3_SUPPORT int findWidget(QWidget* w) {return indexOf(w);}
-#endif
-protected:
- // ### Qt 5: make public
- void insertItem(int index, QLayoutItem *);
-
-private:
- Q_DISABLE_COPY(QBoxLayout)
-};
-
-class Q_GUI_EXPORT QHBoxLayout : public QBoxLayout
-{
- Q_OBJECT
-public:
- QHBoxLayout();
- explicit QHBoxLayout(QWidget *parent);
- ~QHBoxLayout();
-
-#ifdef QT3_SUPPORT
- QT3_SUPPORT_CONSTRUCTOR QHBoxLayout(QWidget *parent, int border,
- int spacing = -1, const char *name = 0);
- QT3_SUPPORT_CONSTRUCTOR QHBoxLayout(QLayout *parentLayout,
- int spacing = -1, const char *name = 0);
- QT3_SUPPORT_CONSTRUCTOR QHBoxLayout(int spacing, const char *name = 0);
-#endif
-
-private:
- Q_DISABLE_COPY(QHBoxLayout)
-};
-
-class Q_GUI_EXPORT QVBoxLayout : public QBoxLayout
-{
- Q_OBJECT
-public:
- QVBoxLayout();
- explicit QVBoxLayout(QWidget *parent);
- ~QVBoxLayout();
-
-#ifdef QT3_SUPPORT
- QT3_SUPPORT_CONSTRUCTOR QVBoxLayout(QWidget *parent, int border,
- int spacing = -1, const char *name = 0);
- QT3_SUPPORT_CONSTRUCTOR QVBoxLayout(QLayout *parentLayout,
- int spacing = -1, const char *name = 0);
- QT3_SUPPORT_CONSTRUCTOR QVBoxLayout(int spacing, const char *name = 0);
-#endif
-
-private:
- Q_DISABLE_COPY(QVBoxLayout)
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QBOXLAYOUT_H
diff --git a/src/gui/kernel/qclipboard.cpp b/src/gui/kernel/qclipboard.cpp
index ef995eb9aa..ec9ac315f5 100644
--- a/src/gui/kernel/qclipboard.cpp
+++ b/src/gui/kernel/qclipboard.cpp
@@ -43,8 +43,6 @@
#ifndef QT_NO_CLIPBOARD
-#include "qapplication.h"
-#include "qapplication_p.h"
#include "qpixmap.h"
#include "qclipboard_p.h"
#include "qvariant.h"
diff --git a/src/gui/kernel/qclipboard.h b/src/gui/kernel/qclipboard.h
index d42f0c7cb9..fd68a998b0 100644
--- a/src/gui/kernel/qclipboard.h
+++ b/src/gui/kernel/qclipboard.h
@@ -109,6 +109,7 @@ protected:
friend class QApplication;
friend class QApplicationPrivate;
+ friend class QGuiApplication;
friend class QBaseApplication;
friend class QDragManager;
friend class QMimeSource;
diff --git a/src/gui/kernel/qclipboard_qpa.cpp b/src/gui/kernel/qclipboard_qpa.cpp
index 6a88129168..737b2131c0 100644
--- a/src/gui/kernel/qclipboard_qpa.cpp
+++ b/src/gui/kernel/qclipboard_qpa.cpp
@@ -44,7 +44,7 @@
#ifndef QT_NO_CLIPBOARD
#include "qmimedata.h"
-#include "private/qapplication_p.h"
+#include "private/qguiapplication_p.h"
#include "qplatformclipboard_qpa.h"
QT_BEGIN_NAMESPACE
@@ -53,7 +53,7 @@ QT_USE_NAMESPACE
void QClipboard::clear(Mode mode)
{
- setMimeData(0,mode);
+ setMimeData(0, mode);
}
@@ -64,14 +64,14 @@ bool QClipboard::event(QEvent *e)
const QMimeData* QClipboard::mimeData(Mode mode) const
{
- QPlatformClipboard *clipboard = QApplicationPrivate::platformIntegration()->clipboard();
+ QPlatformClipboard *clipboard = QGuiApplicationPrivate::platformIntegration()->clipboard();
if (!clipboard->supportsMode(mode)) return 0;
return clipboard->mimeData(mode);
}
void QClipboard::setMimeData(QMimeData* src, Mode mode)
{
- QPlatformClipboard *clipboard = QApplicationPrivate::platformIntegration()->clipboard();
+ QPlatformClipboard *clipboard = QGuiApplicationPrivate::platformIntegration()->clipboard();
if (!clipboard->supportsMode(mode)) return;
clipboard->setMimeData(src,mode);
@@ -81,15 +81,14 @@ void QClipboard::setMimeData(QMimeData* src, Mode mode)
bool QClipboard::supportsMode(Mode mode) const
{
- QPlatformClipboard *clipboard = QApplicationPrivate::platformIntegration()->clipboard();
+ QPlatformClipboard *clipboard = QGuiApplicationPrivate::platformIntegration()->clipboard();
return clipboard->supportsMode(mode);
}
bool QClipboard::ownsMode(Mode mode) const
{
- if (mode == Clipboard)
- qWarning("QClipboard::ownsClipboard: UNIMPLEMENTED!");
- return false;
+ QPlatformClipboard *clipboard = QGuiApplicationPrivate::platformIntegration()->clipboard();
+ return clipboard->ownsMode(mode);
}
void QClipboard::connectNotify( const char * )
diff --git a/src/gui/kernel/qclipboard_qws.cpp b/src/gui/kernel/qclipboard_qws.cpp
deleted file mode 100644
index a85a7f48d3..0000000000
--- a/src/gui/kernel/qclipboard_qws.cpp
+++ /dev/null
@@ -1,304 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qclipboard.h"
-
-#ifndef QT_NO_CLIPBOARD
-
-#include "qapplication.h"
-#include "qbitmap.h"
-#include "qdatetime.h"
-#include "qbuffer.h"
-#include "qwidget.h"
-#include "qevent.h"
-
-#include <qwsdisplay_qws.h>
-#include <qwsproperty_qws.h>
-#include <qwsevent_qws.h>
-
-QT_BEGIN_NAMESPACE
-
-QT_USE_NAMESPACE
-
-
-/*****************************************************************************
- Internal QClipboard functions for Qt for Embedded Linux
- *****************************************************************************/
-
-static const int TextClipboard=424242;
-static bool init = false;
-
-static inline void qwsInitClipboard()
-{
- //### this should go into QWSServer; it only needs to happen once.
- if( !init ) {
- QPaintDevice::qwsDisplay()->addProperty(0, TextClipboard);
- init = true;
- }
-}
-
-static QString qwsClipboardText()
-{
- char * data;
- int len;
- qwsInitClipboard();
- if( !QPaintDevice::qwsDisplay()->getProperty(0, TextClipboard, data, len) ) {
-// qDebug("Property received: %d bytes", len);
- }
-
- QString s((const QChar*)data, len/sizeof(QChar));
- // qDebug("Property received: '%s'", s.toAscii().constData());
- delete[] data;
- return s;
-}
-
-
-static void qwsSetClipboardText(const QString& s)
-{
- qwsInitClipboard();
- // qDebug("qwsSetClipboardText( %s )", s.toAscii().data());
- int len = s.length()*sizeof(QChar);
- QByteArray ba((const char*)s.unicode(), len);
- QPaintDevice::qwsDisplay()->
- setProperty(0, TextClipboard, QWSPropertyManager::PropReplace, ba);
-
-}
-
-class QClipboardData
-{
-public:
- QClipboardData();
- ~QClipboardData();
-
- void setSource(QMimeData* s)
- {
- if (s == src)
- return;
- delete src;
- src = s;
- }
- QMimeData* source()
- { return src; }
-#if 0
- void addTransferredPixmap(QPixmap pm)
- { /* TODO: queue them */
- transferred[tindex] = pm;
- tindex=(tindex+1)%2;
- }
- void clearTransfers()
- {
- transferred[0] = QPixmap();
- transferred[1] = QPixmap();
- }
-#endif
-
- void clear();
-
-private:
- QMimeData* src;
-
-#if 0
- QPixmap transferred[2];
- int tindex;
-#endif
-};
-
-QClipboardData::QClipboardData()
-{
- src = 0;
-#if 0
- tindex=0;
-#endif
-}
-
-QClipboardData::~QClipboardData()
-{
- delete src;
-}
-
-void QClipboardData::clear()
-{
- delete src;
- src = 0;
-}
-
-
-static QClipboardData *internalCbData = 0;
-
-static void cleanupClipboardData()
-{
- delete internalCbData;
- internalCbData = 0;
-}
-
-static QClipboardData *clipboardData()
-{
- if (internalCbData == 0) {
- internalCbData = new QClipboardData;
- qAddPostRoutine(cleanupClipboardData);
- }
- return internalCbData;
-}
-
-
-/*****************************************************************************
- QClipboard member functions for FB.
- *****************************************************************************/
-
-#if 0
-
-QString QClipboard::text() const
-{
- return qwsClipboardText();
-}
-
-void QClipboard::setText(const QString &text)
-{
- qwsSetClipboardText(text);
-}
-
-QString QClipboard::text(QString& subtype) const
-{
- QString r;
- if (subtype == "plain")
- r = text();
- return r;
-}
-
-#endif
-
-void QClipboard::clear(Mode mode)
-{
- setText(QString(), mode);
-}
-
-
-bool QClipboard::event(QEvent *e)
-{
- static bool recursionWatch = false;
- if (e->type() != QEvent::Clipboard || recursionWatch)
- return QObject::event(e);
-
- recursionWatch = true;
- QWSPropertyNotifyEvent *event = (QWSPropertyNotifyEvent *)(((QClipboardEvent *)e)->data());
- if (event && event->simpleData.state == QWSPropertyNotifyEvent::PropertyNewValue) {
- QClipboardData *d = clipboardData();
- QString t = qwsClipboardText();
- if( (d->source() == 0 && !t.isEmpty()) || (d->source() != 0 && d->source()->text() != t) ) {
- if( !d->source() )
- d->setSource(new QMimeData);
- d->source()->setText( t );
- emitChanged(QClipboard::Clipboard);
- }
- }
-
- recursionWatch = false;
- return true;
-}
-
-const QMimeData* QClipboard::mimeData(Mode mode) const
-{
- if (mode != Clipboard) return 0;
-
- QClipboardData *d = clipboardData();
- // Try and get data from QWSProperty if no mime data has been set on us.
- if( !d->source() ) {
- QString t = qwsClipboardText();
- if( !t.isEmpty() ) {
- QMimeData* nd = new QMimeData;
- nd->setText( t );
- d->setSource( nd );
- }
- }
- return d->source();
-}
-
-void QClipboard::setMimeData(QMimeData* src, Mode mode)
-{
- if (mode != Clipboard) return;
-
- QClipboardData *d = clipboardData();
-
- /* Propagate text data to other QWSClients */
-
- QString newText;
- if( src != 0 )
- newText = src->text();
- QString oldText;
- if( d->source() != 0 )
- oldText = d->source()->text();
-
- d->setSource(src);
-
- if( oldText != newText ) {
- if( d->source() == 0 ) {
- qwsSetClipboardText( QString() );
- } else {
- qwsSetClipboardText( d->source()->text() );
- }
- }
-
- emitChanged(QClipboard::Clipboard);
-}
-
-bool QClipboard::supportsMode(Mode mode) const
-{
- return (mode == Clipboard);
-}
-
-bool QClipboard::ownsMode(Mode mode) const
-{
- if (mode == Clipboard)
- qWarning("QClipboard::ownsClipboard: UNIMPLEMENTED!");
- return false;
-}
-
-void QClipboard::connectNotify( const char * )
-{
-}
-
-void QClipboard::ownerDestroyed()
-{
-}
-
-#endif // QT_NO_CLIPBOARD
-
-QT_END_NAMESPACE
diff --git a/src/gui/kernel/qcocoaapplication_mac.mm b/src/gui/kernel/qcocoaapplication_mac.mm
deleted file mode 100644
index 6c47a9e2ec..0000000000
--- a/src/gui/kernel/qcocoaapplication_mac.mm
+++ /dev/null
@@ -1,222 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/****************************************************************************
-**
-** Copyright (c) 2007-2008, Apple, Inc.
-**
-** All rights reserved.
-**
-** Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are met:
-**
-** * Redistributions of source code must retain the above copyright notice,
-** this list of conditions and the following disclaimer.
-**
-** * Redistributions in binary form must reproduce the above copyright notice,
-** this list of conditions and the following disclaimer in the documentation
-** and/or other materials provided with the distribution.
-**
-** * Neither the name of Apple, Inc. nor the names of its contributors
-** may be used to endorse or promote products derived from this software
-** without specific prior written permission.
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-**
-****************************************************************************/
-
-#include <qglobal.h>
-#ifdef QT_MAC_USE_COCOA
-#include <private/qcocoaapplication_mac_p.h>
-#include <private/qcocoaapplicationdelegate_mac_p.h>
-#include <private/qt_cocoa_helpers_mac_p.h>
-#include <private/qcocoaintrospection_p.h>
-
-QT_USE_NAMESPACE
-
-@implementation NSApplication (QT_MANGLE_NAMESPACE(QApplicationIntegration))
-
-- (void)QT_MANGLE_NAMESPACE(qt_setDockMenu):(NSMenu *)newMenu
-{
- [[QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) sharedDelegate] setDockMenu:newMenu];
-}
-
-- (QApplicationPrivate *)QT_MANGLE_NAMESPACE(qt_qappPrivate)
-{
- return [[QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) sharedDelegate] qAppPrivate];
-}
-
-- (QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *)QT_MANGLE_NAMESPACE(qt_qcocoamenuLoader)
-{
- return [[QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) sharedDelegate] menuLoader];
-}
-
-- (int)QT_MANGLE_NAMESPACE(qt_validModesForFontPanel):(NSFontPanel *)fontPanel
-{
- Q_UNUSED(fontPanel);
- // only display those things that QFont can handle
- return NSFontPanelFaceModeMask
- | NSFontPanelSizeModeMask
- | NSFontPanelCollectionModeMask
- | NSFontPanelUnderlineEffectModeMask
- | NSFontPanelStrikethroughEffectModeMask;
-}
-
-- (void)qt_sendPostedMessage:(NSEvent *)event
-{
- // WARNING: data1 and data2 is truncated to from 64-bit to 32-bit on OS 10.5!
- // That is why we need to split the address in two parts:
- quint64 lower = [event data1];
- quint64 upper = [event data2];
- QCocoaPostMessageArgs *args = reinterpret_cast<QCocoaPostMessageArgs *>(lower | (upper << 32));
- // Special case for convenience: if the argument is an NSNumber, we unbox it directly.
- // Use NSValue instead if this behaviour is unwanted.
- id a1 = ([args->arg1 isKindOfClass:[NSNumber class]]) ? (id)[args->arg1 intValue] : args->arg1;
- id a2 = ([args->arg2 isKindOfClass:[NSNumber class]]) ? (id)[args->arg2 intValue] : args->arg2;
- switch (args->argCount) {
- case 0:
- [args->target performSelector:args->selector];
- break;
- case 1:
- [args->target performSelector:args->selector withObject:a1];
- break;
- case 3:
- [args->target performSelector:args->selector withObject:a1 withObject:a2];
- break;
- }
-
- delete args;
-}
-
-- (BOOL)qt_filterEvent:(NSEvent *)event
-{
- if (qApp->macEventFilter(0, reinterpret_cast<EventRef>(event)))
- return true;
-
- if ([event type] == NSApplicationDefined) {
- switch ([event subtype]) {
- case QtCocoaEventSubTypePostMessage:
- [NSApp qt_sendPostedMessage:event];
- return true;
- default:
- break;
- }
- }
- return false;
-}
-
-@end
-
-@implementation QNSApplication
-
-- (void)qt_sendEvent_original:(NSEvent *)event
-{
- Q_UNUSED(event);
- // This method will only be used as a signature
- // template for the method we add into NSApplication
- // containing the original [NSApplication sendEvent:] implementation
-}
-
-- (void)qt_sendEvent_replacement:(NSEvent *)event
-{
- // This method (or its implementation to be precise) will
- // be called instead of sendEvent if redirection occurs.
- // 'self' will then be an instance of NSApplication
- // (and not QNSApplication)
- if (![NSApp qt_filterEvent:event])
- [self qt_sendEvent_original:event];
-}
-
-- (void)sendEvent:(NSEvent *)event
-{
- // This method will be called if
- // no redirection occurs
- if (![NSApp qt_filterEvent:event])
- [super sendEvent:event];
-}
-
-- (void)qtDispatcherToQAction:(id)sender
-{
- // Forward actions sendt from the menu bar (e.g. quit) to the menu loader.
- // Having this method here means that we are the last stop in the responder
- // chain, and that we are able to handle menu actions even when no window is
- // visible on screen. Note: If Qt is used as a plugin, Qt will not use a
- // native menu bar. Hence, we will also not need to do any redirection etc. as
- // we do with sendEvent.
- [[NSApp QT_MANGLE_NAMESPACE(qt_qcocoamenuLoader)] qtDispatcherToQAction:sender];
-}
-
-@end
-
-QT_BEGIN_NAMESPACE
-
-void qt_redirectNSApplicationSendEvent()
-{
- if ([NSApp isMemberOfClass:[QNSApplication class]]) {
- // No need to change implementation since Qt
- // already controls a subclass of NSApplication
- return;
- }
-
- // Change the implementation of [NSApplication sendEvent] to the
- // implementation of qt_sendEvent_replacement found in QNSApplication.
- // And keep the old implementation that gets overwritten inside a new
- // method 'qt_sendEvent_original' that we add to NSApplication
- qt_cocoa_change_implementation(
- [NSApplication class],
- @selector(sendEvent:),
- [QNSApplication class],
- @selector(qt_sendEvent_replacement:),
- @selector(qt_sendEvent_original:));
- }
-
-QT_END_NAMESPACE
-#endif
diff --git a/src/gui/kernel/qcocoaapplication_mac_p.h b/src/gui/kernel/qcocoaapplication_mac_p.h
deleted file mode 100644
index a8a16f3547..0000000000
--- a/src/gui/kernel/qcocoaapplication_mac_p.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/****************************************************************************
-**
-** Copyright (c) 2007-2008, Apple, Inc.
-**
-** All rights reserved.
-**
-** Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are met:
-**
-** * Redistributions of source code must retain the above copyright notice,
-** this list of conditions and the following disclaimer.
-**
-** * Redistributions in binary form must reproduce the above copyright notice,
-** this list of conditions and the following disclaimer in the documentation
-** and/or other materials provided with the distribution.
-**
-** * Neither the name of Apple, Inc. nor the names of its contributors
-** may be used to endorse or promote products derived from this software
-** without specific prior written permission.
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-**
-****************************************************************************/
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of qapplication_*.cpp, qwidget*.cpp, qcolor_x11.cpp, qfiledialog.cpp
-// and many other. This header file may change from version to version
-// without notice, or even be removed.
-//
-// We mean it.
-//
-
-/*
- Cocoa Application Categories
-*/
-#include "qmacdefines_mac.h"
-#ifdef QT_MAC_USE_COCOA
-#import <AppKit/AppKit.h>
-QT_FORWARD_DECLARE_CLASS(QApplicationPrivate)
-@class QT_MANGLE_NAMESPACE(QCocoaMenuLoader);
-
-@interface NSApplication (QT_MANGLE_NAMESPACE(QApplicationIntegration))
-- (void)QT_MANGLE_NAMESPACE(qt_setDockMenu):(NSMenu *)newMenu;
-- (QApplicationPrivate *)QT_MANGLE_NAMESPACE(qt_qappPrivate);
-- (QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *)QT_MANGLE_NAMESPACE(qt_qcocoamenuLoader);
-- (int)QT_MANGLE_NAMESPACE(qt_validModesForFontPanel):(NSFontPanel *)fontPanel;
-
-- (void)qt_sendPostedMessage:(NSEvent *)event;
-- (BOOL)qt_filterEvent:(NSEvent *)event;
-@end
-
-@interface QNSApplication : NSApplication {
-}
-@end
-
-QT_BEGIN_NAMESPACE
-
-void qt_redirectNSApplicationSendEvent();
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/gui/kernel/qcocoaapplicationdelegate_mac.mm b/src/gui/kernel/qcocoaapplicationdelegate_mac.mm
deleted file mode 100644
index cd9ad2262a..0000000000
--- a/src/gui/kernel/qcocoaapplicationdelegate_mac.mm
+++ /dev/null
@@ -1,354 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/****************************************************************************
- **
- ** Copyright (c) 2007-2008, Apple, Inc.
- **
- ** All rights reserved.
- **
- ** Redistribution and use in source and binary forms, with or without
- ** modification, are permitted provided that the following conditions are met:
- **
- ** * Redistributions of source code must retain the above copyright notice,
- ** this list of conditions and the following disclaimer.
- **
- ** * Redistributions in binary form must reproduce the above copyright notice,
- ** this list of conditions and the following disclaimer in the documentation
- ** and/or other materials provided with the distribution.
- **
- ** * Neither the name of Apple, Inc. nor the names of its contributors
- ** may be used to endorse or promote products derived from this software
- ** without specific prior written permission.
- **
- ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- ** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- ** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- ** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- ** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- ** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- ** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- **
- ****************************************************************************/
-
-#include "qmacdefines_mac.h"
-#ifdef QT_MAC_USE_COCOA
-
-#import <private/qcocoaapplicationdelegate_mac_p.h>
-#import <private/qcocoamenuloader_mac_p.h>
-#import <private/qcocoaapplication_mac_p.h>
-#include <private/qapplication_p.h>
-#include <private/qt_mac_p.h>
-#include <private/qt_cocoa_helpers_mac_p.h>
-#include <private/qdesktopwidget_mac_p.h>
-#include <qevent.h>
-#include <qurl.h>
-#include <qapplication.h>
-
-QT_BEGIN_NAMESPACE
-extern void onApplicationChangedActivation(bool); // qapplication_mac.mm
-extern void qt_release_apple_event_handler(); //qapplication_mac.mm
-extern QPointer<QWidget> qt_last_mouse_receiver; // qapplication_mac.cpp
-extern QPointer<QWidget> qt_last_native_mouse_receiver; // qt_cocoa_helpers_mac.mm
-extern QPointer<QWidget> qt_button_down; // qapplication_mac.cpp
-
-QT_END_NAMESPACE
-
-QT_FORWARD_DECLARE_CLASS(QDesktopWidgetImplementation)
-QT_USE_NAMESPACE
-
-static QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) *sharedCocoaApplicationDelegate = nil;
-
-static void cleanupCocoaApplicationDelegate()
-{
- [sharedCocoaApplicationDelegate release];
-}
-
-@implementation QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate)
-
-- (id)init
-{
- self = [super init];
- if (self)
- inLaunch = true;
- return self;
-}
-
-- (void)dealloc
-{
- sharedCocoaApplicationDelegate = nil;
- [dockMenu release];
- [qtMenuLoader release];
- if (reflectionDelegate) {
- [NSApp setDelegate:reflectionDelegate];
- [reflectionDelegate release];
- }
- [super dealloc];
-}
-
-+ (id)allocWithZone:(NSZone *)zone
-{
- @synchronized(self) {
- if (sharedCocoaApplicationDelegate == nil) {
- sharedCocoaApplicationDelegate = [super allocWithZone:zone];
- return sharedCocoaApplicationDelegate;
- qAddPostRoutine(cleanupCocoaApplicationDelegate);
- }
- }
- return nil;
-}
-
-+ (QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate)*)sharedDelegate
-{
- @synchronized(self) {
- if (sharedCocoaApplicationDelegate == nil)
- [[self alloc] init];
- }
- return [[sharedCocoaApplicationDelegate retain] autorelease];
-}
-
-- (void)setDockMenu:(NSMenu*)newMenu
-{
- [newMenu retain];
- [dockMenu release];
- dockMenu = newMenu;
-}
-
-- (NSMenu *)applicationDockMenu
-{
- return [[dockMenu retain] autorelease];
-}
-
-- (QApplicationPrivate *)qAppPrivate
-{
- return qtPrivate;
-}
-
-- (void)setQtPrivate:(QApplicationPrivate *)value
-{
- qtPrivate = value;
-}
-
-- (void)setMenuLoader:(QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *)menuLoader
-{
- [menuLoader retain];
- [qtMenuLoader release];
- qtMenuLoader = menuLoader;
-}
-
-- (QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *)menuLoader
-{
- return [[qtMenuLoader retain] autorelease];
-}
-
-// This function will only be called when NSApp is actually running. Before
-// that, the kAEQuitApplication Apple event will be sent to
-// QApplicationPrivate::globalAppleEventProcessor in qapplication_mac.mm
-- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
-{
- Q_UNUSED(sender);
- // The reflection delegate gets precedence
- if (reflectionDelegate
- && [reflectionDelegate respondsToSelector:@selector(applicationShouldTerminate:)]) {
- return [reflectionDelegate applicationShouldTerminate:sender];
- }
-
- if (qtPrivate->canQuit()) {
- if (!startedQuit) {
- startedQuit = true;
- qAppInstance()->quit();
- startedQuit = false;
- }
- }
-
- if (qtPrivate->threadData->eventLoops.size() == 0) {
- // INVARIANT: No event loop is executing. This probably
- // means that Qt is used as a plugin, or as a part of a native
- // Cocoa application. In any case it should be fine to
- // terminate now:
- return NSTerminateNow;
- }
-
- return NSTerminateCancel;
-}
-
-- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
-{
- Q_UNUSED(aNotification);
- inLaunch = false;
- qt_release_apple_event_handler();
-}
-
-- (void)application:(NSApplication *)sender openFiles:(NSArray *)filenames
-{
- 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 &&
- [reflectionDelegate respondsToSelector:@selector(application:openFiles:)])
- [reflectionDelegate application:sender openFiles:filenames];
-}
-
-- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender
-{
- // If we have a reflection delegate, that will get to call the shots.
- if (reflectionDelegate
- && [reflectionDelegate respondsToSelector:
- @selector(applicationShouldTerminateAfterLastWindowClosed:)])
- return [reflectionDelegate applicationShouldTerminateAfterLastWindowClosed:sender];
- return NO; // Someday qApp->quitOnLastWindowClosed(); when QApp and NSApp work closer together.
-}
-
-
-- (void)applicationDidBecomeActive:(NSNotification *)notification
-{
- if (reflectionDelegate
- && [reflectionDelegate respondsToSelector:@selector(applicationDidBecomeActive:)])
- [reflectionDelegate applicationDidBecomeActive:notification];
-
- onApplicationChangedActivation(true);
-
- if (!QWidget::mouseGrabber()){
- // Update enter/leave immidiatly, don't wait for a move event. But only
- // if no grab exists (even if the grab points to this widget, it seems, ref X11)
- QPoint qlocal, qglobal;
- QWidget *widgetUnderMouse = 0;
- qt_mac_getTargetForMouseEvent(0, QEvent::Enter, qlocal, qglobal, 0, &widgetUnderMouse);
- QApplicationPrivate::dispatchEnterLeave(widgetUnderMouse, 0);
- qt_last_mouse_receiver = widgetUnderMouse;
- qt_last_native_mouse_receiver = widgetUnderMouse ?
- (widgetUnderMouse->internalWinId() ? widgetUnderMouse : widgetUnderMouse->nativeParentWidget()) : 0;
- }
-}
-
-- (void)applicationDidResignActive:(NSNotification *)notification
-{
- if (reflectionDelegate
- && [reflectionDelegate respondsToSelector:@selector(applicationDidResignActive:)])
- [reflectionDelegate applicationDidResignActive:notification];
-
- onApplicationChangedActivation(false);
-
- if (!QWidget::mouseGrabber())
- QApplicationPrivate::dispatchEnterLeave(0, qt_last_mouse_receiver);
- qt_last_mouse_receiver = 0;
- qt_last_native_mouse_receiver = 0;
- qt_button_down = 0;
-}
-
-- (void)applicationDidChangeScreenParameters:(NSNotification *)notification
-{
- Q_UNUSED(notification);
- QDesktopWidgetImplementation::instance()->onResize();
-}
-
-- (void)setReflectionDelegate:(NSObject <NSApplicationDelegate> *)oldDelegate
-{
- [oldDelegate retain];
- [reflectionDelegate release];
- reflectionDelegate = oldDelegate;
-}
-
-- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
-{
- NSMethodSignature *result = [super methodSignatureForSelector:aSelector];
- if (!result && reflectionDelegate) {
- result = [reflectionDelegate methodSignatureForSelector:aSelector];
- }
- return result;
-}
-
-- (BOOL)respondsToSelector:(SEL)aSelector
-{
- BOOL result = [super respondsToSelector:aSelector];
- if (!result && reflectionDelegate)
- result = [reflectionDelegate respondsToSelector:aSelector];
- return result;
-}
-
-- (void)forwardInvocation:(NSInvocation *)invocation
-{
- SEL invocationSelector = [invocation selector];
- if (reflectionDelegate && [reflectionDelegate respondsToSelector:invocationSelector])
- [invocation invokeWithTarget:reflectionDelegate];
- else
- [self doesNotRecognizeSelector:invocationSelector];
-}
-
-- (void)getUrl:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent
-{
- Q_UNUSED(replyEvent);
-
- NSString *urlString = [[event paramDescriptorForKeyword:keyDirectObject] stringValue];
- QUrl url(qt_mac_NSStringToQString(urlString));
- QFileOpenEvent qtEvent(url);
- qt_sendSpontaneousEvent(qAppInstance(), &qtEvent);
-}
-
-- (void)appleEventQuit:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent
-{
- Q_UNUSED(event);
- Q_UNUSED(replyEvent);
- [NSApp terminate:self];
-}
-
-- (void)qtDispatcherToQAction:(id)sender
-{
- [[NSApp QT_MANGLE_NAMESPACE(qt_qcocoamenuLoader)] qtDispatcherToQAction:sender];
-}
-
-@end
-#endif
diff --git a/src/gui/kernel/qcocoaapplicationdelegate_mac_p.h b/src/gui/kernel/qcocoaapplicationdelegate_mac_p.h
deleted file mode 100644
index 275ea0696a..0000000000
--- a/src/gui/kernel/qcocoaapplicationdelegate_mac_p.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-/****************************************************************************
- **
- ** Copyright (c) 2007-2008, Apple, Inc.
- **
- ** All rights reserved.
- **
- ** Redistribution and use in source and binary forms, with or without
- ** modification, are permitted provided that the following conditions are met:
- **
- ** * Redistributions of source code must retain the above copyright notice,
- ** this list of conditions and the following disclaimer.
- **
- ** * Redistributions in binary form must reproduce the above copyright notice,
- ** this list of conditions and the following disclaimer in the documentation
- ** and/or other materials provided with the distribution.
- **
- ** * Neither the name of Apple, Inc. nor the names of its contributors
- ** may be used to endorse or promote products derived from this software
- ** without specific prior written permission.
- **
- ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- ** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- ** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- ** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- ** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- ** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- ** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- **
- ****************************************************************************/
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of qapplication_*.cpp, qwidget*.cpp, qcolor_x11.cpp, qfiledialog.cpp
-// and many other. This header file may change from version to version
-// without notice, or even be removed.
-//
-// We mean it.
-//
-
-
-#include "qmacdefines_mac.h"
-#ifdef QT_MAC_USE_COCOA
-#import <Cocoa/Cocoa.h>
-
-QT_FORWARD_DECLARE_CLASS(QApplicationPrivate);
-
-@class QT_MANGLE_NAMESPACE(QCocoaMenuLoader);
-
-#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5
-
-@protocol NSApplicationDelegate <NSObject>
-- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender;
-- (void)applicationDidFinishLaunching:(NSNotification *)aNotification;
-- (void)application:(NSApplication *)sender openFiles:(NSArray *)filenames;
-- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender;
-- (void)applicationDidBecomeActive:(NSNotification *)notification;
-- (void)applicationDidResignActive:(NSNotification *)notification;
-@end
-
-#endif
-
-@interface QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) : NSObject <NSApplicationDelegate> {
- bool startedQuit;
- QApplicationPrivate *qtPrivate;
- NSMenu *dockMenu;
- QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *qtMenuLoader;
- NSObject <NSApplicationDelegate> *reflectionDelegate;
- bool inLaunch;
-}
-+ (QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate)*)sharedDelegate;
-- (void)setDockMenu:(NSMenu *)newMenu;
-- (void)setQtPrivate:(QApplicationPrivate *)value;
-- (QApplicationPrivate *)qAppPrivate;
-- (void)setMenuLoader:(QT_MANGLE_NAMESPACE(QCocoaMenuLoader)*)menuLoader;
-- (QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *)menuLoader;
-- (void)setReflectionDelegate:(NSObject <NSApplicationDelegate> *)oldDelegate;
-- (void)getUrl:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent;
-@end
-#endif
diff --git a/src/gui/kernel/qcocoamenuloader_mac.mm b/src/gui/kernel/qcocoamenuloader_mac.mm
deleted file mode 100644
index da11c3a1c6..0000000000
--- a/src/gui/kernel/qcocoamenuloader_mac.mm
+++ /dev/null
@@ -1,264 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qmacdefines_mac.h"
-#ifdef QT_MAC_USE_COCOA
-#include <qaction.h>
-#include <qcoreapplication.h>
-#include <private/qcocoamenuloader_mac_p.h>
-#include <private/qapplication_p.h>
-#include <private/qt_mac_p.h>
-#include <private/qmenubar_p.h>
-#include <qmenubar.h>
-#include <private/qt_cocoa_helpers_mac_p.h>
-
-QT_FORWARD_DECLARE_CLASS(QCFString)
-QT_FORWARD_DECLARE_CLASS(QString)
-
-#ifndef QT_NO_TRANSLATION
- QT_BEGIN_NAMESPACE
- extern QString qt_mac_applicationmenu_string(int type);
- QT_END_NAMESPACE
-#endif
-
-QT_USE_NAMESPACE
-
-@implementation QT_MANGLE_NAMESPACE(QCocoaMenuLoader)
-
-- (void)awakeFromNib
-{
- servicesItem = [[appMenu itemWithTitle:@"Services"] retain];
- hideAllOthersItem = [[appMenu itemWithTitle:@"Hide Others"] retain];
- showAllItem = [[appMenu itemWithTitle:@"Show All"] retain];
-
- // Get the names in the nib to match the app name set by Qt.
- const NSString *appName = reinterpret_cast<const NSString*>(QCFString::toCFStringRef(qAppName()));
- [quitItem setTitle:[[quitItem title] stringByReplacingOccurrencesOfString:@"NewApplication"
- withString:const_cast<NSString *>(appName)]];
- [hideItem setTitle:[[hideItem title] stringByReplacingOccurrencesOfString:@"NewApplication"
- withString:const_cast<NSString *>(appName)]];
- [aboutItem setTitle:[[aboutItem title] stringByReplacingOccurrencesOfString:@"NewApplication"
- withString:const_cast<NSString *>(appName)]];
- [appName release];
- // Disable the items that don't do anything. If someone associates a QAction with them
- // They should get synced back in.
- [preferencesItem setEnabled:NO];
- [preferencesItem setHidden:YES];
- [aboutItem setEnabled:NO];
- [aboutItem setHidden:YES];
-}
-
-- (void)ensureAppMenuInMenu:(NSMenu *)menu
-{
- // The application menu is the menu in the menu bar that contains the
- // 'Quit' item. When changing menu bar (e.g when switching between
- // windows with different menu bars), we never recreate this menu, but
- // instead pull it out the current menu bar and place into the new one:
- NSMenu *mainMenu = [NSApp mainMenu];
- if ([NSApp mainMenu] == menu)
- return; // nothing to do (menu is the current menu bar)!
-
-#ifndef QT_NAMESPACE
- Q_ASSERT(mainMenu);
-#endif
- // Grab the app menu out of the current menu.
- int numItems = [mainMenu numberOfItems];
- NSMenuItem *oldAppMenuItem = 0;
- for (int i = 0; i < numItems; ++i) {
- NSMenuItem *item = [mainMenu itemAtIndex:i];
- if ([item submenu] == appMenu) {
- oldAppMenuItem = item;
- [oldAppMenuItem retain];
- [mainMenu removeItemAtIndex:i];
- break;
- }
- }
-
- if (oldAppMenuItem) {
- [oldAppMenuItem setSubmenu:nil];
- [oldAppMenuItem release];
- NSMenuItem *appMenuItem = [[NSMenuItem alloc] initWithTitle:@"Apple"
- action:nil keyEquivalent:@""];
- [appMenuItem setSubmenu:appMenu];
- [menu insertItem:appMenuItem atIndex:0];
- }
-}
-
-- (void)removeActionsFromAppMenu
-{
- for (NSMenuItem *item in [appMenu itemArray])
- [item setTag:nil];
-}
-
-- (void)dealloc
-{
- [servicesItem release];
- [hideAllOthersItem release];
- [showAllItem release];
-
- [lastAppSpecificItem release];
- [theMenu release];
- [appMenu release];
- [super dealloc];
-}
-
-- (NSMenu *)menu
-{
- return [[theMenu retain] autorelease];
-}
-
-- (NSMenu *)applicationMenu
-{
- return [[appMenu retain] autorelease];
-}
-
-- (NSMenuItem *)quitMenuItem
-{
- return [[quitItem retain] autorelease];
-}
-
-- (NSMenuItem *)preferencesMenuItem
-{
- return [[preferencesItem retain] autorelease];
-}
-
-- (NSMenuItem *)aboutMenuItem
-{
- return [[aboutItem retain] autorelease];
-}
-
-- (NSMenuItem *)aboutQtMenuItem
-{
- return [[aboutQtItem retain] autorelease];
-}
-
-- (NSMenuItem *)hideMenuItem
-{
- return [[hideItem retain] autorelease];
-}
-
-- (NSMenuItem *)appSpecificMenuItem
-{
- // Create an App-Specific menu item, insert it into the menu and return
- // it as an autorelease item.
- NSMenuItem *item = [[NSMenuItem alloc] init];
-
- NSInteger location;
- if (lastAppSpecificItem == nil) {
- location = [appMenu indexOfItem:aboutQtItem];
- } else {
- location = [appMenu indexOfItem:lastAppSpecificItem];
- [lastAppSpecificItem release];
- }
- lastAppSpecificItem = item; // Keep track of this for later (i.e., don't release it)
- [appMenu insertItem:item atIndex:location + 1];
-
- return [[item retain] autorelease];
-}
-
-- (BOOL) acceptsFirstResponder
-{
- return YES;
-}
-
-- (void)terminate:(id)sender
-{
- [NSApp terminate:sender];
-}
-
-- (void)orderFrontStandardAboutPanel:(id)sender
-{
- [NSApp orderFrontStandardAboutPanel:sender];
-}
-
-- (void)hideOtherApplications:(id)sender
-{
- [NSApp hideOtherApplications:sender];
-}
-
-- (void)unhideAllApplications:(id)sender
-{
- [NSApp unhideAllApplications:sender];
-}
-
-- (void)hide:(id)sender
-{
- [NSApp hide:sender];
-}
-
-- (void)qtUpdateMenubar
-{
- QMenuBarPrivate::macUpdateMenuBarImmediatly();
-}
-
-- (void)qtTranslateApplicationMenu
-{
-#ifndef QT_NO_TRANSLATION
- [servicesItem setTitle: qt_mac_QStringToNSString(qt_mac_applicationmenu_string(0))];
- [hideItem setTitle: qt_mac_QStringToNSString(qt_mac_applicationmenu_string(1).arg(qAppName()))];
- [hideAllOthersItem setTitle: qt_mac_QStringToNSString(qt_mac_applicationmenu_string(2))];
- [showAllItem setTitle: qt_mac_QStringToNSString(qt_mac_applicationmenu_string(3))];
- [preferencesItem setTitle: qt_mac_QStringToNSString(qt_mac_applicationmenu_string(4))];
- [quitItem setTitle: qt_mac_QStringToNSString(qt_mac_applicationmenu_string(5).arg(qAppName()))];
- [aboutItem setTitle: qt_mac_QStringToNSString(qt_mac_applicationmenu_string(6).arg(qAppName()))];
-#endif
-}
-
-- (IBAction)qtDispatcherToQAction:(id)sender
-{
- QScopedLoopLevelCounter loopLevelCounter(QApplicationPrivate::instance()->threadData);
- NSMenuItem *item = static_cast<NSMenuItem *>(sender);
- if (QAction *action = reinterpret_cast<QAction *>([item tag])) {
- action->trigger();
- } else if (item == quitItem) {
- // We got here because someone was once the quitItem, but it has been
- // abandoned (e.g., the menubar was deleted). In the meantime, just do
- // normal QApplication::quit().
- qApp->quit();
- }
-}
-
- - (void)orderFrontCharacterPalette:(id)sender
- {
- [NSApp orderFrontCharacterPalette:sender];
- }
-@end
-#endif // QT_MAC_USE_COCOA
diff --git a/src/gui/kernel/qcocoamenuloader_mac_p.h b/src/gui/kernel/qcocoamenuloader_mac_p.h
deleted file mode 100644
index 1e637fdc39..0000000000
--- a/src/gui/kernel/qcocoamenuloader_mac_p.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QCOCOAMENULOADER_P_H
-#define QCOCOAMENULOADER_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header
-// file may change from version to version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qmacdefines_mac.h"
-#ifdef QT_MAC_USE_COCOA
-#import <Cocoa/Cocoa.h>
-
-@interface QT_MANGLE_NAMESPACE(QCocoaMenuLoader) : NSResponder
-{
- IBOutlet NSMenu *theMenu;
- IBOutlet NSMenu *appMenu;
- IBOutlet NSMenuItem *quitItem;
- IBOutlet NSMenuItem *preferencesItem;
- IBOutlet NSMenuItem *aboutItem;
- IBOutlet NSMenuItem *aboutQtItem;
- IBOutlet NSMenuItem *hideItem;
- NSMenuItem *lastAppSpecificItem;
- NSMenuItem *servicesItem;
- NSMenuItem *hideAllOthersItem;
- NSMenuItem *showAllItem;
-}
-- (void)ensureAppMenuInMenu:(NSMenu *)menu;
-- (void)removeActionsFromAppMenu;
-- (NSMenu *)applicationMenu;
-- (NSMenu *)menu;
-- (NSMenuItem *)quitMenuItem;
-- (NSMenuItem *)preferencesMenuItem;
-- (NSMenuItem *)aboutMenuItem;
-- (NSMenuItem *)aboutQtMenuItem;
-- (NSMenuItem *)hideMenuItem;
-- (NSMenuItem *)appSpecificMenuItem;
-- (IBAction)terminate:(id)sender;
-- (IBAction)orderFrontStandardAboutPanel:(id)sender;
-- (IBAction)hideOtherApplications:(id)sender;
-- (IBAction)unhideAllApplications:(id)sender;
-- (IBAction)hide:(id)sender;
-- (IBAction)qtDispatcherToQAction:(id)sender;
-- (void)qtUpdateMenubar;
-- (void)orderFrontCharacterPalette:(id)sender;
-@end
-
-#endif // QT_MAC_USE_COCOA
-#endif // QCOCOAMENULOADER_P_H
diff --git a/src/gui/kernel/qcocoaview_mac_p.h b/src/gui/kernel/qcocoaview_mac_p.h
deleted file mode 100644
index e5e977bedd..0000000000
--- a/src/gui/kernel/qcocoaview_mac_p.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <qevent.h>
-#ifdef QT_MAC_USE_COCOA
-#import <Cocoa/Cocoa.h>
-
-@class QT_MANGLE_NAMESPACE(QCocoaView);
-QT_FORWARD_DECLARE_CLASS(QWidgetPrivate);
-QT_FORWARD_DECLARE_CLASS(QWidget);
-QT_FORWARD_DECLARE_CLASS(QEvent);
-QT_FORWARD_DECLARE_CLASS(QString);
-QT_FORWARD_DECLARE_CLASS(QStringList);
-
-Q_GUI_EXPORT
-@interface QT_MANGLE_NAMESPACE(QCocoaView) : NSControl <NSTextInput> {
- QWidget *qwidget;
- QWidgetPrivate *qwidgetprivate;
- NSDragOperation supportedActions;
- bool composing;
- int composingLength;
- bool sendKeyEvents;
- bool fromKeyDownEvent;
- QString *composingText;
- @public int alienTouchCount;
-}
-- (id)initWithQWidget:(QWidget *)widget widgetPrivate:(QWidgetPrivate *)widgetprivate;
-- (void) finishInitWithQWidget:(QWidget *)widget widgetPrivate:(QWidgetPrivate *)widgetprivate;
-- (void)frameDidChange:(NSNotification *)note;
-- (void)setSupportedActions:(NSDragOperation)actions;
-- (NSDragOperation)draggingSourceOperationMaskForLocal:(BOOL)isLocal;
-- (void)draggedImage:(NSImage *)anImage endedAt:(NSPoint)aPoint operation:(NSDragOperation)operation;
-- (BOOL)isComposing;
-- (QWidget *)qt_qwidget;
-- (void) qt_clearQWidget;
-
-@end
-#endif
diff --git a/src/gui/kernel/qcursor.cpp b/src/gui/kernel/qcursor.cpp
index a7868ba1a1..9ca06aaa98 100644
--- a/src/gui/kernel/qcursor.cpp
+++ b/src/gui/kernel/qcursor.cpp
@@ -43,7 +43,7 @@
#ifndef QT_NO_CURSOR
-#include <qapplication.h>
+#include <qcoreapplication.h>
#include <qbitmap.h>
#include <qimage.h>
#include <qdatastream.h>
@@ -71,7 +71,7 @@ QT_BEGIN_NAMESPACE
To associate a cursor with a widget, use QWidget::setCursor(). To
associate a cursor with all widgets (normally for a short period
- of time), use QApplication::setOverrideCursor().
+ of time), use QGuiApplication::setOverrideCursor().
To set a cursor shape use QCursor::setShape() or use the QCursor
constructor which takes the shape as argument, or you can use one
@@ -85,9 +85,9 @@ QT_BEGIN_NAMESPACE
methods QCursor::pos() and QCursor::setPos().
\bold{Note:} It is possible to create a QCursor before
- QApplication, but it is not useful except as a place-holder for a
- real QCursor created after QApplication. Attempting to use a
- QCursor that was created before QApplication will result in a
+ QGuiApplication, but it is not useful except as a place-holder for a
+ real QCursor created after QGuiApplication. Attempting to use a
+ QCursor that was created before QGuiApplication will result in a
crash.
\section1 A Note for X11 Users
@@ -410,7 +410,7 @@ void QCursorData::initialize()
QCursor::QCursor()
{
if (!QCursorData::initialized) {
- if (QApplication::startingUp()) {
+ if (QCoreApplication::startingUp()) {
d = 0;
return;
}
diff --git a/src/gui/kernel/qcursor.h b/src/gui/kernel/qcursor.h
index d857eda1e5..dac74c2c01 100644
--- a/src/gui/kernel/qcursor.h
+++ b/src/gui/kernel/qcursor.h
@@ -152,18 +152,6 @@ private:
#endif
};
-#ifdef QT3_SUPPORT
-// CursorShape is defined in X11/X.h
-#ifdef CursorShape
-#define X_CursorShape CursorShape
-#undef CursorShape
-#endif
-typedef Qt::CursorShape QCursorShape;
-#ifdef X_CursorShape
-#define CursorShape X_CursorShape
-#endif
-#endif
-
/*****************************************************************************
QCursor stream functions
*****************************************************************************/
diff --git a/src/gui/kernel/qcursor_qpa.cpp b/src/gui/kernel/qcursor_qpa.cpp
index d4cf6f4995..40a15317ee 100644
--- a/src/gui/kernel/qcursor_qpa.cpp
+++ b/src/gui/kernel/qcursor_qpa.cpp
@@ -41,6 +41,8 @@
#include <qcursor.h>
#include <private/qcursor_p.h>
+#include <qplatformcursor_qpa.h>
+#include <private/qguiapplication_p.h>
#include <qbitmap.h>
QT_BEGIN_NAMESPACE
@@ -107,21 +109,29 @@ void QCursorData::update()
#endif //QT_NO_CURSOR
-extern qreal qt_last_x,qt_last_y;
-
QPoint QCursor::pos()
{
- return QPointF(qt_last_x, qt_last_y).toPoint();
+ return QGuiApplicationPrivate::lastCursorPosition.toPoint();
}
void QCursor::setPos(int x, int y)
{
+ QPoint target(x, y);
+
// Need to check, since some X servers generate null mouse move
// events, causing looping in applications which call setPos() on
// every mouse move event.
//
- if (pos() == QPoint(x, y))
+ if (pos() == target)
return;
+
+ QList<QWeakPointer<QPlatformCursor> > cursors = QPlatformCursorPrivate::getInstances();
+ int cursorCount = cursors.count();
+ for (int i = 0; i < cursorCount; ++i) {
+ const QWeakPointer<QPlatformCursor> &cursor(cursors.at(i));
+ if (cursor)
+ cursor.data()->setPos(target);
+ }
}
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qcursor_qws.cpp b/src/gui/kernel/qcursor_qws.cpp
deleted file mode 100644
index e47119dc1a..0000000000
--- a/src/gui/kernel/qcursor_qws.cpp
+++ /dev/null
@@ -1,138 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qcursor.h>
-#include <private/qcursor_p.h>
-#include <qbitmap.h>
-#include <qwsdisplay_qws.h>
-
-QT_BEGIN_NAMESPACE
-
-QT_USE_NAMESPACE
-
-#ifndef QT_NO_CURSOR
-
-static int nextCursorId = Qt::BitmapCursor;
-
-/*****************************************************************************
- Internal QCursorData class
- *****************************************************************************/
-
-QCursorData::QCursorData(Qt::CursorShape s)
- : cshape(s), bm(0), bmm(0), hx(0), hy(0), id(s)
-{
- ref = 1;
-}
-
-QCursorData::~QCursorData()
-{
- delete bm;
- delete bmm;
- QT_TRY {
- QPaintDevice::qwsDisplay()->destroyCursor(id);
- } QT_CATCH(const std::bad_alloc &) {
- // do nothing.
- }
-}
-
-
-/*****************************************************************************
- Global cursors
- *****************************************************************************/
-
-int QCursor::handle() const
-{
- return d->id;
-}
-
-
-QCursorData *QCursorData::setBitmap(const QBitmap &bitmap, const QBitmap &mask, int hotX, int hotY)
-{
- if (!QCursorData::initialized)
- QCursorData::initialize();
- if (bitmap.depth() != 1 || mask.depth() != 1 || bitmap.size() != mask.size()) {
- qWarning("QCursor: Cannot create bitmap cursor; invalid bitmap(s)");
- QCursorData *c = qt_cursorTable[0];
- c->ref.ref();
- return c;
- }
- QCursorData *d = new QCursorData;
- d->bm = new QBitmap(bitmap);
- d->bmm = new QBitmap(mask);
- d->cshape = Qt::BitmapCursor;
- d->id = ++nextCursorId;
- d->hx = hotX >= 0 ? hotX : bitmap.width() / 2;
- d->hy = hotY >= 0 ? hotY : bitmap.height() / 2;
-
- QPaintDevice::qwsDisplay()->defineCursor(d->id, *d->bm, *d->bmm, d->hx, d->hy);
- return d;
-}
-
-void QCursorData::update()
-{
-}
-
-#endif //QT_NO_CURSOR
-
-extern int *qt_last_x,*qt_last_y;
-
-QPoint QCursor::pos()
-{
- // This doesn't know about hotspots yet so we disable it
- //qt_accel_update_cursor();
- if (qt_last_x)
- return QPoint(*qt_last_x, *qt_last_y);
- else
- return QPoint();
-}
-
-void QCursor::setPos(int x, int y)
-{
- // Need to check, since some X servers generate null mouse move
- // events, causing looping in applications which call setPos() on
- // every mouse move event.
- //
- if (pos() == QPoint(x, y))
- return;
- QPaintDevice::qwsDisplay()->setCursorPosition(x, y);
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/kernel/qcursor_x11.cpp b/src/gui/kernel/qcursor_x11.cpp
deleted file mode 100644
index 167e8f8517..0000000000
--- a/src/gui/kernel/qcursor_x11.cpp
+++ /dev/null
@@ -1,640 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qdebug.h>
-#include <qdatastream.h>
-#include <private/qcursor_p.h>
-#include <private/qt_x11_p.h>
-#include <private/qapplication_p.h>
-#include <qbitmap.h>
-#include <qcursor.h>
-#include <X11/cursorfont.h>
-
-#include <qlibrary.h>
-
-#ifndef QT_NO_XCURSOR
-# include <X11/Xcursor/Xcursor.h>
-#endif // QT_NO_XCURSOR
-
-#ifndef QT_NO_XFIXES
-#ifndef Status
-#define Status int
-#endif
-# include <X11/extensions/Xfixes.h>
-#endif // QT_NO_XFIXES
-
-#include "qx11info_x11.h"
-#include <private/qpixmap_x11_p.h>
-
-QT_BEGIN_NAMESPACE
-
-// Define QT_USE_APPROXIMATE_CURSORS when compiling if you REALLY want to
-// use the ugly X11 cursors.
-
-/*****************************************************************************
- Internal QCursorData class
- *****************************************************************************/
-
-QCursorData::QCursorData(Qt::CursorShape s)
- : cshape(s), bm(0), bmm(0), hx(0), hy(0), hcurs(0), pm(0), pmm(0)
-{
- ref = 1;
-}
-
-QCursorData::~QCursorData()
-{
- Display *dpy = X11 ? X11->display : (Display*)0;
-
- // Add in checking for the display too as on HP-UX
- // we seem to get a core dump as the cursor data is
- // deleted again from main() on exit...
- if (hcurs && dpy)
- XFreeCursor(dpy, hcurs);
- if (pm && dpy)
- XFreePixmap(dpy, pm);
- if (pmm && dpy)
- XFreePixmap(dpy, pmm);
- delete bm;
- delete bmm;
-}
-
-#ifndef QT_NO_CURSOR
-QCursor::QCursor(Qt::HANDLE cursor)
-{
- if (!QCursorData::initialized)
- QCursorData::initialize();
- d = new QCursorData(Qt::CustomCursor);
- d->hcurs = cursor;
-}
-
-#endif
-
-QCursorData *QCursorData::setBitmap(const QBitmap &bitmap, const QBitmap &mask, int hotX, int hotY)
-{
- if (!QCursorData::initialized)
- QCursorData::initialize();
- if (bitmap.depth() != 1 || mask.depth() != 1 || bitmap.size() != mask.size()) {
- qWarning("QCursor: Cannot create bitmap cursor; invalid bitmap(s)");
- QCursorData *c = qt_cursorTable[0];
- c->ref.ref();
- return c;
- }
- QCursorData *d = new QCursorData;
- d->ref = 1;
-
- extern QPixmap qt_toX11Pixmap(const QPixmap &pixmap); // qpixmap_x11.cpp
- d->bm = new QBitmap(qt_toX11Pixmap(bitmap));
- d->bmm = new QBitmap(qt_toX11Pixmap(mask));
-
- d->hcurs = 0;
- d->cshape = Qt::BitmapCursor;
- d->hx = hotX >= 0 ? hotX : bitmap.width() / 2;
- d->hy = hotY >= 0 ? hotY : bitmap.height() / 2;
- d->fg.red = 0x0000;
- d->fg.green = 0x0000;
- d->fg.blue = 0x0000;
- d->bg.red = 0xffff;
- d->bg.green = 0xffff;
- d->bg.blue = 0xffff;
- return d;
-}
-
-
-
-#ifndef QT_NO_CURSOR
-Qt::HANDLE QCursor::handle() const
-{
- if (!QCursorData::initialized)
- QCursorData::initialize();
- if (!d->hcurs)
- d->update();
- return d->hcurs;
-}
-#endif
-
-QPoint QCursor::pos()
-{
- Window root;
- Window child;
- int root_x, root_y, win_x, win_y;
- uint buttons;
- Display* dpy = X11->display;
- for (int i = 0; i < ScreenCount(dpy); ++i) {
- if (XQueryPointer(dpy, QX11Info::appRootWindow(i), &root, &child, &root_x, &root_y,
- &win_x, &win_y, &buttons))
-
- return QPoint(root_x, root_y);
- }
- return QPoint();
-}
-
-/*! \internal
-*/
-#ifndef QT_NO_CURSOR
-int QCursor::x11Screen()
-{
- Window root;
- Window child;
- int root_x, root_y, win_x, win_y;
- uint buttons;
- Display* dpy = X11->display;
- for (int i = 0; i < ScreenCount(dpy); ++i) {
- if (XQueryPointer(dpy, QX11Info::appRootWindow(i), &root, &child, &root_x, &root_y,
- &win_x, &win_y, &buttons))
- return i;
- }
- return -1;
-}
-#endif
-
-void QCursor::setPos(int x, int y)
-{
- QPoint current, target(x, y);
-
- // this is copied from pos(), since we need the screen number for the correct
- // root window in the XWarpPointer call
- Window root;
- Window child;
- int root_x, root_y, win_x, win_y;
- uint buttons;
- Display* dpy = X11->display;
- int screen;
- for (screen = 0; screen < ScreenCount(dpy); ++screen) {
- if (XQueryPointer(dpy, QX11Info::appRootWindow(screen), &root, &child, &root_x, &root_y,
- &win_x, &win_y, &buttons)) {
- current = QPoint(root_x, root_y);
- break;
- }
- }
-
- if (screen >= ScreenCount(dpy))
- return;
-
- // Need to check, since some X servers generate null mouse move
- // events, causing looping in applications which call setPos() on
- // every mouse move event.
- //
- if (current == target)
- return;
-
- XWarpPointer(X11->display, XNone, QX11Info::appRootWindow(screen), 0, 0, 0, 0, x, y);
-}
-
-
-/*!
- \internal
-
- Creates the cursor.
-*/
-
-void QCursorData::update()
-{
- if (!QCursorData::initialized)
- QCursorData::initialize();
- if (hcurs)
- return;
-
- Display *dpy = X11->display;
- Window rootwin = QX11Info::appRootWindow();
-
- if (cshape == Qt::BitmapCursor) {
- extern QPixmap qt_toX11Pixmap(const QPixmap &pixmap); // qpixmap_x11.cpp
-#ifndef QT_NO_XRENDER
- if (!pixmap.isNull() && X11->use_xrender) {
- pixmap = qt_toX11Pixmap(pixmap);
- hcurs = XRenderCreateCursor (X11->display, pixmap.x11PictureHandle(), hx, hy);
- } else
-#endif
- {
- hcurs = XCreatePixmapCursor(dpy, bm->handle(), bmm->handle(), &fg, &bg, hx, hy);
- }
- return;
- }
-
- static const char *cursorNames[] = {
- "left_ptr",
- "up_arrow",
- "cross",
- "wait",
- "ibeam",
- "size_ver",
- "size_hor",
- "size_bdiag",
- "size_fdiag",
- "size_all",
- "blank",
- "split_v",
- "split_h",
- "pointing_hand",
- "forbidden",
- "whats_this",
- "left_ptr_watch",
- "openhand",
- "closedhand",
- "copy",
- "move",
- "link"
- };
-
-#ifndef QT_NO_XCURSOR
- if (X11->ptrXcursorLibraryLoadCursor) {
- // special case for non-standard dnd-* cursors
- switch (cshape) {
- case Qt::DragCopyCursor:
- hcurs = X11->ptrXcursorLibraryLoadCursor(dpy, "dnd-copy");
- break;
- case Qt::DragMoveCursor:
- hcurs = X11->ptrXcursorLibraryLoadCursor(dpy, "dnd-move");
- break;
- case Qt::DragLinkCursor:
- hcurs = X11->ptrXcursorLibraryLoadCursor(dpy, "dnd-link");
- break;
- default:
- break;
- }
- if (!hcurs)
- hcurs = X11->ptrXcursorLibraryLoadCursor(dpy, cursorNames[cshape]);
- }
- if (hcurs)
- return;
-#endif // QT_NO_XCURSOR
-
- static const uchar cur_blank_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-
- // Non-standard X11 cursors are created from bitmaps
-
-#ifndef QT_USE_APPROXIMATE_CURSORS
- static const uchar cur_ver_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0xf0, 0x0f,
- 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0xf0, 0x0f,
- 0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01, 0x00, 0x00 };
- static const uchar mcur_ver_bits[] = {
- 0x00, 0x00, 0x80, 0x03, 0xc0, 0x07, 0xe0, 0x0f, 0xf0, 0x1f, 0xf8, 0x3f,
- 0xfc, 0x7f, 0xc0, 0x07, 0xc0, 0x07, 0xc0, 0x07, 0xfc, 0x7f, 0xf8, 0x3f,
- 0xf0, 0x1f, 0xe0, 0x0f, 0xc0, 0x07, 0x80, 0x03 };
- static const uchar cur_hor_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x08, 0x30, 0x18,
- 0x38, 0x38, 0xfc, 0x7f, 0xfc, 0x7f, 0x38, 0x38, 0x30, 0x18, 0x20, 0x08,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
- static const uchar mcur_hor_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x40, 0x04, 0x60, 0x0c, 0x70, 0x1c, 0x78, 0x3c,
- 0xfc, 0x7f, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfc, 0x7f, 0x78, 0x3c,
- 0x70, 0x1c, 0x60, 0x0c, 0x40, 0x04, 0x00, 0x00 };
- static const uchar cur_bdiag_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x3e, 0x00, 0x3c, 0x00, 0x3e,
- 0x00, 0x37, 0x88, 0x23, 0xd8, 0x01, 0xf8, 0x00, 0x78, 0x00, 0xf8, 0x00,
- 0xf8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
- static const uchar mcur_bdiag_bits[] = {
- 0x00, 0x00, 0xc0, 0x7f, 0x80, 0x7f, 0x00, 0x7f, 0x00, 0x7e, 0x04, 0x7f,
- 0x8c, 0x7f, 0xdc, 0x77, 0xfc, 0x63, 0xfc, 0x41, 0xfc, 0x00, 0xfc, 0x01,
- 0xfc, 0x03, 0xfc, 0x07, 0x00, 0x00, 0x00, 0x00 };
- static const uchar cur_fdiag_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x01, 0xf8, 0x00, 0x78, 0x00,
- 0xf8, 0x00, 0xd8, 0x01, 0x88, 0x23, 0x00, 0x37, 0x00, 0x3e, 0x00, 0x3c,
- 0x00, 0x3e, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00 };
- static const uchar mcur_fdiag_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0xfc, 0x07, 0xfc, 0x03, 0xfc, 0x01, 0xfc, 0x00,
- 0xfc, 0x41, 0xfc, 0x63, 0xdc, 0x77, 0x8c, 0x7f, 0x04, 0x7f, 0x00, 0x7e,
- 0x00, 0x7f, 0x80, 0x7f, 0xc0, 0x7f, 0x00, 0x00 };
- static const uchar *cursor_bits16[] = {
- cur_ver_bits, mcur_ver_bits, cur_hor_bits, mcur_hor_bits,
- cur_bdiag_bits, mcur_bdiag_bits, cur_fdiag_bits, mcur_fdiag_bits,
- 0, 0, cur_blank_bits, cur_blank_bits };
-
- static const uchar vsplit_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xe0, 0x03, 0x00,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xff, 0x7f, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x7f, 0x00,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00,
- 0x00, 0xc0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
- static const uchar vsplitm_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
- 0x00, 0xc0, 0x01, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x00, 0xf0, 0x07, 0x00,
- 0x00, 0xf8, 0x0f, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00,
- 0x00, 0xc0, 0x01, 0x00, 0x80, 0xff, 0xff, 0x00, 0x80, 0xff, 0xff, 0x00,
- 0x80, 0xff, 0xff, 0x00, 0x80, 0xff, 0xff, 0x00, 0x80, 0xff, 0xff, 0x00,
- 0x80, 0xff, 0xff, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00,
- 0x00, 0xc0, 0x01, 0x00, 0x00, 0xf8, 0x0f, 0x00, 0x00, 0xf0, 0x07, 0x00,
- 0x00, 0xe0, 0x03, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
- static const uchar hsplit_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00,
- 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00,
- 0x00, 0x41, 0x82, 0x00, 0x80, 0x41, 0x82, 0x01, 0xc0, 0x7f, 0xfe, 0x03,
- 0x80, 0x41, 0x82, 0x01, 0x00, 0x41, 0x82, 0x00, 0x00, 0x40, 0x02, 0x00,
- 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00,
- 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
- static const uchar hsplitm_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00,
- 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe2, 0x47, 0x00, 0x00, 0xe3, 0xc7, 0x00,
- 0x80, 0xe3, 0xc7, 0x01, 0xc0, 0xff, 0xff, 0x03, 0xe0, 0xff, 0xff, 0x07,
- 0xc0, 0xff, 0xff, 0x03, 0x80, 0xe3, 0xc7, 0x01, 0x00, 0xe3, 0xc7, 0x00,
- 0x00, 0xe2, 0x47, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00,
- 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
- static const uchar whatsthis_bits[] = {
- 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0xf0, 0x07, 0x00,
- 0x09, 0x18, 0x0e, 0x00, 0x11, 0x1c, 0x0e, 0x00, 0x21, 0x1c, 0x0e, 0x00,
- 0x41, 0x1c, 0x0e, 0x00, 0x81, 0x1c, 0x0e, 0x00, 0x01, 0x01, 0x07, 0x00,
- 0x01, 0x82, 0x03, 0x00, 0xc1, 0xc7, 0x01, 0x00, 0x49, 0xc0, 0x01, 0x00,
- 0x95, 0xc0, 0x01, 0x00, 0x93, 0xc0, 0x01, 0x00, 0x21, 0x01, 0x00, 0x00,
- 0x20, 0xc1, 0x01, 0x00, 0x40, 0xc2, 0x01, 0x00, 0x40, 0x02, 0x00, 0x00,
- 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
- static const uchar whatsthism_bits[] = {
- 0x01, 0x00, 0x00, 0x00, 0x03, 0xf0, 0x07, 0x00, 0x07, 0xf8, 0x0f, 0x00,
- 0x0f, 0xfc, 0x1f, 0x00, 0x1f, 0x3e, 0x1f, 0x00, 0x3f, 0x3e, 0x1f, 0x00,
- 0x7f, 0x3e, 0x1f, 0x00, 0xff, 0x3e, 0x1f, 0x00, 0xff, 0x9d, 0x0f, 0x00,
- 0xff, 0xc3, 0x07, 0x00, 0xff, 0xe7, 0x03, 0x00, 0x7f, 0xe0, 0x03, 0x00,
- 0xf7, 0xe0, 0x03, 0x00, 0xf3, 0xe0, 0x03, 0x00, 0xe1, 0xe1, 0x03, 0x00,
- 0xe0, 0xe1, 0x03, 0x00, 0xc0, 0xe3, 0x03, 0x00, 0xc0, 0xe3, 0x03, 0x00,
- 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
- static const uchar busy_bits[] = {
- 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
- 0x09, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
- 0x41, 0xe0, 0xff, 0x00, 0x81, 0x20, 0x80, 0x00, 0x01, 0xe1, 0xff, 0x00,
- 0x01, 0x42, 0x40, 0x00, 0xc1, 0x47, 0x40, 0x00, 0x49, 0x40, 0x55, 0x00,
- 0x95, 0x80, 0x2a, 0x00, 0x93, 0x00, 0x15, 0x00, 0x21, 0x01, 0x0a, 0x00,
- 0x20, 0x01, 0x11, 0x00, 0x40, 0x82, 0x20, 0x00, 0x40, 0x42, 0x44, 0x00,
- 0x80, 0x41, 0x4a, 0x00, 0x00, 0x40, 0x55, 0x00, 0x00, 0xe0, 0xff, 0x00,
- 0x00, 0x20, 0x80, 0x00, 0x00, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
- static const uchar busym_bits[] = {
- 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
- 0x0f, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00,
- 0x7f, 0xe0, 0xff, 0x00, 0xff, 0xe0, 0xff, 0x00, 0xff, 0xe1, 0xff, 0x00,
- 0xff, 0xc3, 0x7f, 0x00, 0xff, 0xc7, 0x7f, 0x00, 0x7f, 0xc0, 0x7f, 0x00,
- 0xf7, 0x80, 0x3f, 0x00, 0xf3, 0x00, 0x1f, 0x00, 0xe1, 0x01, 0x0e, 0x00,
- 0xe0, 0x01, 0x1f, 0x00, 0xc0, 0x83, 0x3f, 0x00, 0xc0, 0xc3, 0x7f, 0x00,
- 0x80, 0xc1, 0x7f, 0x00, 0x00, 0xc0, 0x7f, 0x00, 0x00, 0xe0, 0xff, 0x00,
- 0x00, 0xe0, 0xff, 0x00, 0x00, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-
- static const uchar * const cursor_bits32[] = {
- vsplit_bits, vsplitm_bits, hsplit_bits, hsplitm_bits,
- 0, 0, 0, 0, whatsthis_bits, whatsthism_bits, busy_bits, busym_bits
- };
-
- static const uchar forbidden_bits[] = {
- 0x00,0x00,0x00,0x80,0x1f,0x00,0xe0,0x7f,0x00,0xf0,0xf0,0x00,0x38,0xc0,0x01,
- 0x7c,0x80,0x03,0xec,0x00,0x03,0xce,0x01,0x07,0x86,0x03,0x06,0x06,0x07,0x06,
- 0x06,0x0e,0x06,0x06,0x1c,0x06,0x0e,0x38,0x07,0x0c,0x70,0x03,0x1c,0xe0,0x03,
- 0x38,0xc0,0x01,0xf0,0xe0,0x00,0xe0,0x7f,0x00,0x80,0x1f,0x00,0x00,0x00,0x00 };
-
- static const uchar forbiddenm_bits[] = {
- 0x80,0x1f,0x00,0xe0,0x7f,0x00,0xf0,0xff,0x00,0xf8,0xff,0x01,0xfc,0xf0,0x03,
- 0xfe,0xc0,0x07,0xfe,0x81,0x07,0xff,0x83,0x0f,0xcf,0x07,0x0f,0x8f,0x0f,0x0f,
- 0x0f,0x1f,0x0f,0x0f,0x3e,0x0f,0x1f,0xfc,0x0f,0x1e,0xf8,0x07,0x3e,0xf0,0x07,
- 0xfc,0xe0,0x03,0xf8,0xff,0x01,0xf0,0xff,0x00,0xe0,0x7f,0x00,0x80,0x1f,0x00};
-
- static const uchar openhand_bits[] = {
- 0x80,0x01,0x58,0x0e,0x64,0x12,0x64,0x52,0x48,0xb2,0x48,0x92,
- 0x16,0x90,0x19,0x80,0x11,0x40,0x02,0x40,0x04,0x40,0x04,0x20,
- 0x08,0x20,0x10,0x10,0x20,0x10,0x00,0x00};
- static const uchar openhandm_bits[] = {
- 0x80,0x01,0xd8,0x0f,0xfc,0x1f,0xfc,0x5f,0xf8,0xff,0xf8,0xff,
- 0xf6,0xff,0xff,0xff,0xff,0x7f,0xfe,0x7f,0xfc,0x7f,0xfc,0x3f,
- 0xf8,0x3f,0xf0,0x1f,0xe0,0x1f,0x00,0x00};
- static const uchar closedhand_bits[] = {
- 0x00,0x00,0x00,0x00,0x00,0x00,0xb0,0x0d,0x48,0x32,0x08,0x50,
- 0x10,0x40,0x18,0x40,0x04,0x40,0x04,0x20,0x08,0x20,0x10,0x10,
- 0x20,0x10,0x20,0x10,0x00,0x00,0x00,0x00};
- static const uchar closedhandm_bits[] = {
- 0x00,0x00,0x00,0x00,0x00,0x00,0xb0,0x0d,0xf8,0x3f,0xf8,0x7f,
- 0xf0,0x7f,0xf8,0x7f,0xfc,0x7f,0xfc,0x3f,0xf8,0x3f,0xf0,0x1f,
- 0xe0,0x1f,0xe0,0x1f,0x00,0x00,0x00,0x00};
-
- static const uchar * const cursor_bits20[] = {
- forbidden_bits, forbiddenm_bits
- };
-
- if ((cshape >= Qt::SizeVerCursor && cshape < Qt::SizeAllCursor)
- || cshape == Qt::BlankCursor) {
- XColor bg, fg;
- bg.red = 255 << 8;
- bg.green = 255 << 8;
- bg.blue = 255 << 8;
- fg.red = 0;
- fg.green = 0;
- fg.blue = 0;
- int i = (cshape - Qt::SizeVerCursor) * 2;
- pm = XCreateBitmapFromData(dpy, rootwin, reinterpret_cast<const char*>(cursor_bits16[i]), 16, 16);
- pmm = XCreateBitmapFromData(dpy, rootwin, reinterpret_cast<const char*>(cursor_bits16[i + 1]), 16, 16);
- hcurs = XCreatePixmapCursor(dpy, pm, pmm, &fg, &bg, 8, 8);
- } else if ((cshape >= Qt::SplitVCursor && cshape <= Qt::SplitHCursor)
- || cshape == Qt::WhatsThisCursor || cshape == Qt::BusyCursor) {
- XColor bg, fg;
- bg.red = 255 << 8;
- bg.green = 255 << 8;
- bg.blue = 255 << 8;
- fg.red = 0;
- fg.green = 0;
- fg.blue = 0;
- int i = (cshape - Qt::SplitVCursor) * 2;
- pm = XCreateBitmapFromData(dpy, rootwin, reinterpret_cast<const char *>(cursor_bits32[i]), 32, 32);
- pmm = XCreateBitmapFromData(dpy, rootwin, reinterpret_cast<const char *>(cursor_bits32[i + 1]), 32, 32);
- int hs = (cshape == Qt::PointingHandCursor || cshape == Qt::WhatsThisCursor
- || cshape == Qt::BusyCursor) ? 0 : 16;
- hcurs = XCreatePixmapCursor(dpy, pm, pmm, &fg, &bg, hs, hs);
- } else if (cshape == Qt::ForbiddenCursor) {
- XColor bg, fg;
- bg.red = 255 << 8;
- bg.green = 255 << 8;
- bg.blue = 255 << 8;
- fg.red = 0;
- fg.green = 0;
- fg.blue = 0;
- int i = (cshape - Qt::ForbiddenCursor) * 2;
- pm = XCreateBitmapFromData(dpy, rootwin, reinterpret_cast<const char *>(cursor_bits20[i]), 20, 20);
- pmm = XCreateBitmapFromData(dpy, rootwin, reinterpret_cast<const char *>(cursor_bits20[i + 1]), 20, 20);
- hcurs = XCreatePixmapCursor(dpy, pm, pmm, &fg, &bg, 10, 10);
- } else if (cshape == Qt::OpenHandCursor || cshape == Qt::ClosedHandCursor) {
- XColor bg, fg;
- bg.red = 255 << 8;
- bg.green = 255 << 8;
- bg.blue = 255 << 8;
- fg.red = 0;
- fg.green = 0;
- fg.blue = 0;
- bool open = cshape == Qt::OpenHandCursor;
- pm = XCreateBitmapFromData(dpy, rootwin, reinterpret_cast<const char *>(open ? openhand_bits : closedhand_bits), 16, 16);
- pmm = XCreateBitmapFromData(dpy, rootwin, reinterpret_cast<const char *>(open ? openhandm_bits : closedhandm_bits), 16, 16);
- hcurs = XCreatePixmapCursor(dpy, pm, pmm, &fg, &bg, 8, 8);
- } else if (cshape == Qt::DragCopyCursor || cshape == Qt::DragMoveCursor
- || cshape == Qt::DragLinkCursor) {
- XColor bg, fg;
- bg.red = 255 << 8;
- bg.green = 255 << 8;
- bg.blue = 255 << 8;
- fg.red = 0;
- fg.green = 0;
- fg.blue = 0;
- QImage image = QApplicationPrivate::instance()->getPixmapCursor(cshape).toImage();
- pm = QX11PixmapData::createBitmapFromImage(image);
- pmm = QX11PixmapData::createBitmapFromImage(image.createAlphaMask().convertToFormat(QImage::Format_MonoLSB));
- hcurs = XCreatePixmapCursor(dpy, pm, pmm, &fg, &bg, 8, 8);
- }
-
- if (hcurs)
- {
-#ifndef QT_NO_XFIXES
- if (X11->use_xfixes && X11->ptrXFixesSetCursorName)
- X11->ptrXFixesSetCursorName(dpy, hcurs, cursorNames[cshape]);
-#endif /* ! QT_NO_XFIXES */
- return;
- }
-
-#endif /* ! QT_USE_APPROXIMATE_CURSORS */
-
- uint sh;
- switch (cshape) { // map Q cursor to X cursor
- case Qt::ArrowCursor:
- sh = XC_left_ptr;
- break;
- case Qt::UpArrowCursor:
- sh = XC_center_ptr;
- break;
- case Qt::CrossCursor:
- sh = XC_crosshair;
- break;
- case Qt::WaitCursor:
- sh = XC_watch;
- break;
- case Qt::IBeamCursor:
- sh = XC_xterm;
- break;
- case Qt::SizeAllCursor:
- sh = XC_fleur;
- break;
- case Qt::PointingHandCursor:
- sh = XC_hand2;
- break;
-#ifdef QT_USE_APPROXIMATE_CURSORS
- case Qt::SizeBDiagCursor:
- sh = XC_top_right_corner;
- break;
- case Qt::SizeFDiagCursor:
- sh = XC_bottom_right_corner;
- break;
- case Qt::BlankCursor:
- XColor bg, fg;
- bg.red = 255 << 8;
- bg.green = 255 << 8;
- bg.blue = 255 << 8;
- fg.red = 0;
- fg.green = 0;
- fg.blue = 0;
- pm = XCreateBitmapFromData(dpy, rootwin, cur_blank_bits, 16, 16);
- pmm = XCreateBitmapFromData(dpy, rootwin, cur_blank_bits, 16, 16);
- hcurs = XCreatePixmapCursor(dpy, pm, pmm, &fg, &bg, 8, 8);
- return;
- break;
- case Qt::SizeVerCursor:
- case Qt::SplitVCursor:
- sh = XC_sb_v_double_arrow;
- break;
- case Qt::SizeHorCursor:
- case Qt::SplitHCursor:
- sh = XC_sb_h_double_arrow;
- break;
- case Qt::WhatsThisCursor:
- sh = XC_question_arrow;
- break;
- case Qt::ForbiddenCursor:
- sh = XC_circle;
- break;
- case Qt::BusyCursor:
- sh = XC_watch;
- break;
- case Qt::DragCopyCursor:
- sh = XC_tcross;
- break;
- case Qt::DragLinkCursor:
- sh = XC_center_ptr;
- break;
- case Qt::DragMoveCursor:
- sh = XC_top_left_arrow;
- break;
-#endif /* QT_USE_APPROXIMATE_CURSORS */
- default:
- qWarning("QCursor::update: Invalid cursor shape %d", cshape);
- return;
- }
- hcurs = XCreateFontCursor(dpy, sh);
-
-#ifndef QT_NO_XFIXES
- if (X11->use_xfixes && X11->ptrXFixesSetCursorName)
- X11->ptrXFixesSetCursorName(dpy, hcurs, cursorNames[cshape]);
-#endif /* ! QT_NO_XFIXES */
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/kernel/qdesktopwidget.h b/src/gui/kernel/qdesktopwidget.h
deleted file mode 100644
index 4cd0d53be6..0000000000
--- a/src/gui/kernel/qdesktopwidget.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDESKTOPWIDGET_H
-#define QDESKTOPWIDGET_H
-
-#include <QtGui/qwidget.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QApplication;
-class QDesktopWidgetPrivate;
-
-class Q_GUI_EXPORT QDesktopWidget : public QWidget
-{
- Q_OBJECT
- Q_PROPERTY(bool virtualDesktop READ isVirtualDesktop)
- Q_PROPERTY(int screenCount READ screenCount NOTIFY screenCountChanged)
- Q_PROPERTY(int primaryScreen READ primaryScreen)
-public:
- QDesktopWidget();
- ~QDesktopWidget();
-
- bool isVirtualDesktop() const;
-
- int numScreens() const;
- int screenCount() const;
- int primaryScreen() const;
-
- int screenNumber(const QWidget *widget = 0) const;
- int screenNumber(const QPoint &) const;
-
- QWidget *screen(int screen = -1);
-
- const QRect screenGeometry(int screen = -1) const;
- const QRect screenGeometry(const QWidget *widget) const;
- const QRect screenGeometry(const QPoint &point) const
- { return screenGeometry(screenNumber(point)); }
-
- const QRect availableGeometry(int screen = -1) const;
- const QRect availableGeometry(const QWidget *widget) const;
- const QRect availableGeometry(const QPoint &point) const
- { return availableGeometry(screenNumber(point)); }
-
-Q_SIGNALS:
- void resized(int);
- void workAreaResized(int);
- void screenCountChanged(int);
-
-protected:
- void resizeEvent(QResizeEvent *e);
-
-private:
- Q_DISABLE_COPY(QDesktopWidget)
- Q_DECLARE_PRIVATE(QDesktopWidget)
-
- friend class QApplication;
- friend class QApplicationPrivate;
-};
-
-inline int QDesktopWidget::screenCount() const
-{ return numScreens(); }
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QDESKTOPWIDGET_H
diff --git a/src/gui/kernel/qdesktopwidget_qpa.cpp b/src/gui/kernel/qdesktopwidget_qpa.cpp
deleted file mode 100644
index b9d257789d..0000000000
--- a/src/gui/kernel/qdesktopwidget_qpa.cpp
+++ /dev/null
@@ -1,176 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qdesktopwidget.h"
-#include "private/qapplication_p.h"
-#include "private/qgraphicssystem_p.h"
-#include <QWidget>
-#include "private/qwidget_p.h"
-#include "private/qdesktopwidget_qpa_p.h"
-QT_BEGIN_NAMESPACE
-
-QT_USE_NAMESPACE
-
-void QDesktopWidgetPrivate::updateScreenList()
-{
- Q_Q(QDesktopWidget);
-
- QList<QPlatformScreen *> screenList = QApplicationPrivate::platformIntegration()->screens();
- int targetLength = screenList.length();
- int currentLength = screens.length();
-
- // Add or remove screen widgets as necessary
- if(currentLength > targetLength) {
- QDesktopScreenWidget *screen;
- while (currentLength-- > targetLength) {
- screen = screens.takeLast();
- delete screen;
- }
- }
- else if (currentLength < targetLength) {
- QDesktopScreenWidget *screen;
- while (currentLength < targetLength) {
- screen = new QDesktopScreenWidget(currentLength++);
- screens.append(screen);
- }
- }
-
- QRegion virtualGeometry;
-
- // update the geometry of each screen widget
- for (int i = 0; i < screens.length(); i++) {
- QRect screenGeometry = screenList.at(i)->geometry();
- screens.at(i)->setGeometry(screenGeometry);
- virtualGeometry += screenGeometry;
- }
-
- q->setGeometry(virtualGeometry.boundingRect());
-}
-
-QDesktopWidget::QDesktopWidget()
- : QWidget(*new QDesktopWidgetPrivate, 0, Qt::Desktop)
-{
- Q_D(QDesktopWidget);
- setObjectName(QLatin1String("desktop"));
- d->updateScreenList();
-}
-
-QDesktopWidget::~QDesktopWidget()
-{
-}
-
-bool QDesktopWidget::isVirtualDesktop() const
-{
- return QApplicationPrivate::platformIntegration()->isVirtualDesktop();
-}
-
-int QDesktopWidget::primaryScreen() const
-{
- return 0;
-}
-
-int QDesktopWidget::numScreens() const
-{
- QPlatformIntegration *pi = QApplicationPrivate::platformIntegration();
- return qMax(pi->screens().size(), 1);
-}
-
-QWidget *QDesktopWidget::screen(int screen)
-{
- Q_D(QDesktopWidget);
- if (screen < 0 || screen >= d->screens.length())
- return d->screens.at(0);
- return d->screens.at(screen);
-}
-
-const QRect QDesktopWidget::availableGeometry(int screenNo) const
-{
- QPlatformIntegration *pi = QApplicationPrivate::platformIntegration();
- QList<QPlatformScreen *> screens = pi->screens();
- if (screenNo == -1)
- screenNo = 0;
- if (screenNo < 0 || screenNo >= screens.size())
- return QRect();
- else
- return screens[screenNo]->availableGeometry();
-}
-
-const QRect QDesktopWidget::screenGeometry(int screenNo) const
-{
- QPlatformIntegration *pi = QApplicationPrivate::platformIntegration();
- QList<QPlatformScreen *> screens = pi->screens();
- if (screenNo == -1)
- screenNo = 0;
- if (screenNo < 0 || screenNo >= screens.size())
- return QRect();
- else
- return screens[screenNo]->geometry();
-}
-
-int QDesktopWidget::screenNumber(const QWidget *w) const
-{
- if (!w)
- return 0;
-
- QRect frame = w->frameGeometry();
- if (!w->isWindow())
- frame.moveTopLeft(w->mapToGlobal(QPoint(0, 0)));
- const QPoint midpoint = (frame.topLeft() + frame.bottomRight()) / 2;
- return screenNumber(midpoint);
-}
-
-int QDesktopWidget::screenNumber(const QPoint &p) const
-{
- QPlatformIntegration *pi = QApplicationPrivate::platformIntegration();
- QList<QPlatformScreen *> screens = pi->screens();
-
- for (int i = 0; i < screens.size(); ++i)
- if (screens[i]->geometry().contains(p))
- return i;
-
- return primaryScreen(); //even better would be closest screen
-}
-
-void QDesktopWidget::resizeEvent(QResizeEvent *)
-{
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/kernel/qdesktopwidget_qws.cpp b/src/gui/kernel/qdesktopwidget_qws.cpp
deleted file mode 100644
index 50ccb9f140..0000000000
--- a/src/gui/kernel/qdesktopwidget_qws.cpp
+++ /dev/null
@@ -1,159 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qdesktopwidget.h"
-#include "qscreen_qws.h"
-#include "private/qapplication_p.h"
-
-QT_BEGIN_NAMESPACE
-
-QT_USE_NAMESPACE
-
-QDesktopWidget::QDesktopWidget()
- : QWidget(0, Qt::Desktop)
-{
- setObjectName(QLatin1String("desktop"));
-}
-
-QDesktopWidget::~QDesktopWidget()
-{
-}
-
-bool QDesktopWidget::isVirtualDesktop() const
-{
- return true;
-}
-
-int QDesktopWidget::primaryScreen() const
-{
- return 0;
-}
-
-int QDesktopWidget::numScreens() const
-{
- QScreen *screen = QScreen::instance();
- if (!screen)
- return 0;
-
- const QList<QScreen*> subScreens = screen->subScreens();
- return qMax(subScreens.size(), 1);
-}
-
-QWidget *QDesktopWidget::screen(int)
-{
- return this;
-}
-
-const QRect QDesktopWidget::availableGeometry(int screenNo) const
-{
- const QScreen *screen = QScreen::instance();
- if (screenNo == -1)
- screenNo = 0;
- if (!screen || screenNo < 0)
- return QRect();
-
- const QList<QScreen*> subScreens = screen->subScreens();
- if (!subScreens.isEmpty()) {
- if (screenNo >= subScreens.size())
- return QRect();
- screen = subScreens.at(screenNo);
- }
-
- QApplicationPrivate *ap = QApplicationPrivate::instance();
- const QRect r = ap->maxWindowRect(screen);
- if (!r.isEmpty())
- return r;
-
- return screen->region().boundingRect();
-}
-
-const QRect QDesktopWidget::screenGeometry(int screenNo) const
-{
- const QScreen *screen = QScreen::instance();
- if (screenNo == -1)
- screenNo = 0;
- if (!screen || screenNo < 0)
- return QRect();
-
- const QList<QScreen*> subScreens = screen->subScreens();
- if (subScreens.size() == 0 && screenNo == 0)
- return screen->region().boundingRect();
-
- if (screenNo >= subScreens.size())
- return QRect();
-
- return subScreens.at(screenNo)->region().boundingRect();
-}
-
-int QDesktopWidget::screenNumber(const QWidget *w) const
-{
- if (!w)
- return 0;
-
- QRect frame = w->frameGeometry();
- if (!w->isWindow())
- frame.moveTopLeft(w->mapToGlobal(QPoint(0, 0)));
- const QPoint midpoint = (frame.topLeft() + frame.bottomRight()) / 2;
- return screenNumber(midpoint);
-}
-
-int QDesktopWidget::screenNumber(const QPoint &p) const
-{
- const QScreen *screen = QScreen::instance();
- if (!screen || !screen->region().contains(p))
- return -1;
-
- const QList<QScreen*> subScreens = screen->subScreens();
- if (subScreens.size() == 0)
- return 0;
-
- for (int i = 0; i < subScreens.size(); ++i)
- if (subScreens.at(i)->region().contains(p))
- return i;
-
- return -1;
-}
-
-void QDesktopWidget::resizeEvent(QResizeEvent *)
-{
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/kernel/qdnd.cpp b/src/gui/kernel/qdnd.cpp
index e880f2ebb1..4ed2515115 100644
--- a/src/gui/kernel/qdnd.cpp
+++ b/src/gui/kernel/qdnd.cpp
@@ -47,9 +47,8 @@
#include "qevent.h"
#include "qfile.h"
#include "qtextcodec.h"
-#include "qapplication.h"
+#include "qguiapplication.h"
#include "qpoint.h"
-#include "qwidget.h"
#include "qbuffer.h"
#include "qimage.h"
#include "qregexp.h"
@@ -59,15 +58,14 @@
#include "qimagewriter.h"
#include "qdebug.h"
#include <ctype.h>
+#include <qplatformdrag_qpa.h>
-#include <private/qapplication_p.h>
+#include <private/qguiapplication_p.h>
#ifndef QT_NO_DRAGANDDROP
QT_BEGIN_NAMESPACE
-#ifndef QT_NO_DRAGANDDROP
-
//#define QDND_DEBUG
#ifdef QDND_DEBUG
@@ -124,7 +122,6 @@ QString KeyboardModifiersToString(Qt::KeyboardModifiers moderfies)
}
#endif
-
// the universe's only drag manager
QDragManager *QDragManager::instance = 0;
@@ -142,11 +139,20 @@ QDragManager::QDragManager()
restoreCursor = false;
willDrop = false;
eventLoop = 0;
- dropData = new QDropData();
currentDropTarget = 0;
#ifdef Q_WS_X11
xdndMimeTransferedPixmapIndex = 0;
#endif
+ shapedPixmapWindow = 0;
+
+ possible_actions = Qt::IgnoreAction;
+
+ QPlatformIntegration *pi = QGuiApplicationPrivate::platformIntegration();
+ platformDrag = pi->drag();
+
+ platformDropData = 0;
+ if (platformDrag)
+ platformDropData = platformDrag->platformDropData();
}
@@ -154,15 +160,14 @@ QDragManager::~QDragManager()
{
#ifndef QT_NO_CURSOR
if (restoreCursor)
- QApplication::restoreOverrideCursor();
+ QGuiApplication::restoreOverrideCursor();
#endif
instance = 0;
- delete dropData;
}
QDragManager *QDragManager::self()
{
- if (!instance && !QApplication::closingDown())
+ if (!instance && !QGuiApplication::closingDown())
instance = new QDragManager;
return instance;
}
@@ -172,23 +177,23 @@ QPixmap QDragManager::dragCursor(Qt::DropAction action) const
QDragPrivate * d = dragPrivate();
if (d && d->customCursors.contains(action))
return d->customCursors[action];
- else if (action == Qt::MoveAction)
- return QApplicationPrivate::instance()->getPixmapCursor(Qt::DragMoveCursor);
- else if (action == Qt::CopyAction)
- return QApplicationPrivate::instance()->getPixmapCursor(Qt::DragCopyCursor);
- else if (action == Qt::LinkAction)
- return QApplicationPrivate::instance()->getPixmapCursor(Qt::DragLinkCursor);
-#ifdef Q_WS_WIN
- else if (action == Qt::IgnoreAction)
- return QApplicationPrivate::instance()->getPixmapCursor(Qt::ForbiddenCursor);
-#endif
- return QPixmap();
-}
-bool QDragManager::hasCustomDragCursors() const
-{
- QDragPrivate * d = dragPrivate();
- return d && !d->customCursors.isEmpty();
+ Qt::CursorShape shape = Qt::ForbiddenCursor;
+ switch (action) {
+ case Qt::MoveAction:
+ shape = Qt::DragMoveCursor;
+ break;
+ case Qt::CopyAction:
+ shape = Qt::DragCopyCursor;
+ break;
+ case Qt::LinkAction:
+ shape = Qt::DragLinkCursor;
+ break;
+ default:
+ shape = Qt::ForbiddenCursor;
+ }
+
+ return QGuiApplicationPrivate::instance()->getPixmapCursor(Qt::DragMoveCursor);
}
Qt::DropAction QDragManager::defaultAction(Qt::DropActions possibleActions,
@@ -230,10 +235,6 @@ Qt::DropAction QDragManager::defaultAction(Qt::DropActions possibleActions,
defaultAction = Qt::LinkAction;
#endif
- // if the object is set take the list of possibles from it
- if (object)
- possibleActions = object->d_func()->possible_actions;
-
#ifdef QDND_DEBUG
qDebug("possible actions : %s", dragActionsToString(possibleActions).latin1());
#endif
@@ -257,7 +258,7 @@ Qt::DropAction QDragManager::defaultAction(Qt::DropActions possibleActions,
return defaultAction;
}
-void QDragManager::setCurrentTarget(QWidget *target, bool dropped)
+void QDragManager::setCurrentTarget(QObject *target, bool dropped)
{
if (currentDropTarget == target)
return;
@@ -270,21 +271,264 @@ void QDragManager::setCurrentTarget(QWidget *target, bool dropped)
}
-QWidget *QDragManager::currentTarget()
+QObject *QDragManager::currentTarget()
{
return currentDropTarget;
}
+
+static QPixmap *defaultPm = 0;
+static const int default_pm_hotx = -2;
+static const int default_pm_hoty = -16;
+static const char *const default_pm[] = {
+"13 9 3 1",
+". c None",
+" c #000000",
+"X c #FFFFFF",
+"X X X X X X X",
+" X X X X X X ",
+"X ......... X",
+" X.........X ",
+"X ......... X",
+" X.........X ",
+"X ......... X",
+" X X X X X X ",
+"X X X X X X X",
+};
+
+
+static Qt::KeyboardModifiers oldstate;
+
+void QDragManager::updatePixmap()
+{
+ if (shapedPixmapWindow) {
+ QPixmap pm;
+ QPoint pm_hot(default_pm_hotx,default_pm_hoty);
+ if (object) {
+ pm = object->pixmap();
+ if (!pm.isNull())
+ pm_hot = object->hotSpot();
+ }
+ if (pm.isNull()) {
+ if (!defaultPm)
+ defaultPm = new QPixmap(default_pm);
+ pm = *defaultPm;
+ }
+ shapedPixmapWindow->setPixmap(pm);
+ shapedPixmapWindow->move(QCursor::pos()-pm_hot);
+ if (willDrop) {
+ shapedPixmapWindow->show();
+ } else {
+ shapedPixmapWindow->hide();
+ }
+ }
+}
+
+void QDragManager::updateCursor()
+{
+#ifndef QT_NO_CURSOR
+ if (willDrop) {
+ if (shapedPixmapWindow)
+ shapedPixmapWindow->show();
+ if (currentActionForOverrideCursor != global_accepted_action) {
+ QGuiApplication::changeOverrideCursor(QCursor(dragCursor(global_accepted_action), 0, 0));
+ currentActionForOverrideCursor = global_accepted_action;
+ }
+ } else {
+ QCursor *overrideCursor = QGuiApplication::overrideCursor();
+ if (!overrideCursor || overrideCursor->shape() != Qt::ForbiddenCursor) {
+ QGuiApplication::changeOverrideCursor(QCursor(Qt::ForbiddenCursor));
+ currentActionForOverrideCursor = Qt::IgnoreAction;
+ }
+ if (shapedPixmapWindow)
+ shapedPixmapWindow->hide();
+ }
+#endif
+}
+
+
+bool QDragManager::eventFilter(QObject *o, QEvent *e)
+{
+ if (beingCancelled) {
+ if (e->type() == QEvent::KeyRelease && static_cast<QKeyEvent*>(e)->key() == Qt::Key_Escape) {
+ qApp->removeEventFilter(this);
+ Q_ASSERT(object == 0);
+ beingCancelled = false;
+ eventLoop->exit();
+ return true; // block the key release
+ }
+ return false;
+ }
+
+ Q_ASSERT(object != 0);
+
+ if (!qobject_cast<QWindow *>(o))
+ return false;
+
+ switch(e->type()) {
+ case QEvent::ShortcutOverride:
+ // prevent accelerators from firing while dragging
+ e->accept();
+ return true;
+
+ case QEvent::KeyPress:
+ case QEvent::KeyRelease:
+ {
+ QKeyEvent *ke = static_cast<QKeyEvent *>(e);
+ if (ke->key() == Qt::Key_Escape && e->type() == QEvent::KeyPress) {
+ cancel();
+ qApp->removeEventFilter(this);
+ beingCancelled = false;
+ eventLoop->exit();
+ } else {
+ // ### x11 forces move!
+ updateCursor();
+ }
+ return true; // Eat all key events
+ }
+
+ case QEvent::MouseMove:
+ move(static_cast<QMouseEvent *>(e));
+ return true; // Eat all mouse events
+
+ case QEvent::MouseButtonRelease:
+ qApp->removeEventFilter(this);
+ if (willDrop)
+ drop(static_cast<QMouseEvent *>(e));
+ else
+ cancel();
+ beingCancelled = false;
+ eventLoop->exit();
+ return true; // Eat all mouse events
+
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonDblClick:
+ case QEvent::Wheel:
+ return true;
+ default:
+ break;
+ }
+ return false;
+}
+
+Qt::DropAction QDragManager::drag(QDrag *o)
+{
+ if (!o || object == o)
+ return Qt::IgnoreAction;
+
+ if (!platformDrag || !o->source()) {
+ o->deleteLater();
+ return Qt::IgnoreAction;
+ }
+
+ if (object) {
+ cancel();
+ qApp->removeEventFilter(this);
+ beingCancelled = false;
+ }
+
+ object = o;
+ if (!shapedPixmapWindow)
+ shapedPixmapWindow = new QShapedPixmapWindow();
+ oldstate = Qt::NoModifier; // #### Should use state that caused the drag
+// drag_mode = mode;
+
+ possible_actions = dragPrivate()->possible_actions;
+
+ willDrop = false;
+ object->d_func()->target = 0;
+ qApp->installEventFilter(this);
+
+ global_accepted_action = Qt::CopyAction;
+#ifndef QT_NO_CURSOR
+ qApp->setOverrideCursor(Qt::ArrowCursor);
+ restoreCursor = true;
+ updateCursor();
+#endif
+ updatePixmap();
+
+ platformDrag->startDrag();
+
+ eventLoop = new QEventLoop;
+ (void) eventLoop->exec();
+ delete eventLoop;
+ eventLoop = 0;
+
+ delete shapedPixmapWindow;
+ shapedPixmapWindow = 0;
+
+ return global_accepted_action;
+}
+
+void QDragManager::move(const QMouseEvent *me)
+{
+ if (!platformDrag)
+ return;
+
+ platformDrag->move(me);
+}
+
+void QDragManager::drop(const QMouseEvent *me)
+{
+ if (!platformDrag)
+ return;
+
+#ifndef QT_NO_CURSOR
+ if (restoreCursor) {
+ QGuiApplication::restoreOverrideCursor();
+ restoreCursor = false;
+ }
+#endif
+ willDrop = false;
+
+ platformDrag->drop(me);
+
+ if (object)
+ object->deleteLater();
+ object = 0;
+}
+
+void QDragManager::cancel(bool deleteSource)
+{
+ if (!platformDrag)
+ return;
+
+#ifndef QT_NO_CURSOR
+ if (restoreCursor) {
+ QGuiApplication::restoreOverrideCursor();
+ restoreCursor = false;
+ }
#endif
-QDropData::QDropData()
- : QInternalMimeData()
+ beingCancelled = true;
+
+ platformDrag->cancel();
+
+ if (object && deleteSource)
+ object->deleteLater();
+ object = 0;
+
+ global_accepted_action = Qt::IgnoreAction;
+}
+
+/*!
+ Called from startDrag() in QPlatformDrag implementations that do not need
+ the desktop-oriented stuff provided by the event filter (e.g. because their
+ drag is not based on mouse events). Instead, they will manage everything on
+ their own, will not rely on move/drop/cancel, and will call stopDrag() to stop
+ the event loop when the drag is over.
+ */
+void QDragManager::unmanageEvents()
{
+ qApp->removeEventFilter(this);
}
-QDropData::~QDropData()
+void QDragManager::stopDrag()
{
+ if (eventLoop)
+ eventLoop->exit();
}
+
#endif // QT_NO_DRAGANDDROP
#if !(defined(QT_NO_DRAGANDDROP) && defined(QT_NO_CLIPBOARD))
diff --git a/src/gui/kernel/qdnd_p.h b/src/gui/kernel/qdnd_p.h
index 74fa9aeb6a..2a81de5c7f 100644
--- a/src/gui/kernel/qdnd_p.h
+++ b/src/gui/kernel/qdnd_p.h
@@ -59,22 +59,17 @@
#include "QtGui/qdrag.h"
#include "QtGui/qpixmap.h"
#include "QtGui/qcursor.h"
+#include "QtGui/qwindow.h"
#include "QtCore/qpoint.h"
#include "private/qobject_p.h"
-#ifdef Q_WS_MAC
-# include "private/qt_mac_p.h"
-#endif
-
-#if defined(Q_WS_WIN)
-# include <qt_windows.h>
-# include <objidl.h>
-#endif
QT_BEGIN_NAMESPACE
class QEventLoop;
+class QMouseEvent;
+class QPlatformDrag;
-#if !(defined(QT_NO_DRAGANDDROP) && defined(QT_NO_CLIPBOARD))
+#ifndef QT_NO_DRAGANDDROP
class Q_GUI_EXPORT QInternalMimeData : public QMimeData
{
@@ -100,82 +95,11 @@ protected:
virtual QVariant retrieveData_sys(const QString &mimeType, QVariant::Type type) const = 0;
};
-#ifdef Q_WS_WIN
-class QOleDataObject : public IDataObject
-{
-public:
- explicit QOleDataObject(QMimeData *mimeData);
- virtual ~QOleDataObject();
-
- void releaseQt();
- const QMimeData *mimeData() const;
- DWORD reportedPerformedEffect() const;
-
- // IUnknown methods
- STDMETHOD(QueryInterface)(REFIID riid, void FAR* FAR* ppvObj);
- STDMETHOD_(ULONG,AddRef)(void);
- STDMETHOD_(ULONG,Release)(void);
-
- // IDataObject methods
- STDMETHOD(GetData)(LPFORMATETC pformatetcIn, LPSTGMEDIUM pmedium);
- STDMETHOD(GetDataHere)(LPFORMATETC pformatetc, LPSTGMEDIUM pmedium);
- STDMETHOD(QueryGetData)(LPFORMATETC pformatetc);
- STDMETHOD(GetCanonicalFormatEtc)(LPFORMATETC pformatetc, LPFORMATETC pformatetcOut);
- STDMETHOD(SetData)(LPFORMATETC pformatetc, STGMEDIUM FAR * pmedium,
- BOOL fRelease);
- STDMETHOD(EnumFormatEtc)(DWORD dwDirection, LPENUMFORMATETC FAR* ppenumFormatEtc);
- STDMETHOD(DAdvise)(FORMATETC FAR* pFormatetc, DWORD advf,
- LPADVISESINK pAdvSink, DWORD FAR* pdwConnection);
- STDMETHOD(DUnadvise)(DWORD dwConnection);
- STDMETHOD(EnumDAdvise)(LPENUMSTATDATA FAR* ppenumAdvise);
-
-private:
- ULONG m_refs;
- QPointer<QMimeData> data;
- int CF_PERFORMEDDROPEFFECT;
- DWORD performedEffect;
-};
-
-class QOleEnumFmtEtc : public IEnumFORMATETC
-{
-public:
- explicit QOleEnumFmtEtc(const QVector<FORMATETC> &fmtetcs);
- explicit QOleEnumFmtEtc(const QVector<LPFORMATETC> &lpfmtetcs);
- virtual ~QOleEnumFmtEtc();
-
- bool isNull() const;
-
- // IUnknown methods
- STDMETHOD(QueryInterface)(REFIID riid, void FAR* FAR* ppvObj);
- STDMETHOD_(ULONG,AddRef)(void);
- STDMETHOD_(ULONG,Release)(void);
-
- // IEnumFORMATETC methods
- STDMETHOD(Next)(ULONG celt, LPFORMATETC rgelt, ULONG FAR* pceltFetched);
- STDMETHOD(Skip)(ULONG celt);
- STDMETHOD(Reset)(void);
- STDMETHOD(Clone)(LPENUMFORMATETC FAR* newEnum);
-
-private:
- bool copyFormatEtc(LPFORMATETC dest, LPFORMATETC src) const;
-
- ULONG m_dwRefs;
- ULONG m_nIndex;
- QVector<LPFORMATETC> m_lpfmtetcs;
- bool m_isNull;
-};
-
-#endif
-
-#endif //QT_NO_DRAGANDDROP && QT_NO_CLIPBOARD
-
-#ifndef QT_NO_DRAGANDDROP
-
class QDragPrivate : public QObjectPrivate
{
public:
- QWidget *source;
- QWidget *target;
+ QObject *source;
+ QObject *target;
QMimeData *data;
QPixmap pixmap;
QPoint hotspot;
@@ -185,148 +109,112 @@ public:
Qt::DropAction defaultDropAction;
};
-class QDropData : public QInternalMimeData
-{
- Q_OBJECT
-public:
- QDropData();
- ~QDropData();
-
-protected:
- bool hasFormat_sys(const QString &mimeType) const;
- QStringList formats_sys() const;
- QVariant retrieveData_sys(const QString &mimeType, QVariant::Type type) const;
-
-#if defined(Q_WS_WIN)
+class QShapedPixmapWindow : public QWindow {
+ QPixmap pixmap;
public:
- LPDATAOBJECT currentDataObject;
-#endif
+ QShapedPixmapWindow() :
+ QWindow()
+ {
+ setWindowFlags(Qt::Tool | Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint);
+ // ### Should we set the surface type to raster?
+ // ### FIXME
+// setAttribute(Qt::WA_TransparentForMouseEvents);
+ }
+
+ void move(const QPoint &p) {
+ QRect g = geometry();
+ g.setTopLeft(p);
+ setGeometry(g);
+ }
+ void setPixmap(QPixmap pm)
+ {
+ pixmap = pm;
+ // ###
+// if (!pixmap.mask().isNull()) {
+// setMask(pixmap.mask());
+// } else {
+// clearMask();
+// }
+ setGeometry(QRect(geometry().topLeft(), pm.size()));
+ }
+
+ // ### Get it painted again!
+// void paintEvent(QPaintEvent*)
+// {
+// QPainter p(this);
+// p.drawPixmap(0,0,pixmap);
+// }
};
-class QDragManager: public QObject {
+
+class Q_GUI_EXPORT QDragManager : public QObject {
Q_OBJECT
- QDragManager();
- ~QDragManager();
// only friend classes can use QDragManager.
friend class QDrag;
friend class QDragMoveEvent;
friend class QDropEvent;
friend class QApplication;
-#ifdef Q_WS_MAC
- friend class QWidgetPrivate; //dnd is implemented here
-#endif
bool eventFilter(QObject *, QEvent *);
- void timerEvent(QTimerEvent*);
public:
- Qt::DropAction drag(QDrag *);
-
- void cancel(bool deleteSource = true);
- void move(const QPoint &);
- void drop();
- void updatePixmap();
- QWidget *source() const { return object ? object->d_func()->source : 0; }
- QDragPrivate *dragPrivate() const { return object ? object->d_func() : 0; }
- static QDragPrivate *dragPrivate(QDrag *drag) { return drag ? drag->d_func() : 0; }
-
+ QDragManager();
+ ~QDragManager();
static QDragManager *self();
- Qt::DropAction defaultAction(Qt::DropActions possibleActions,
- Qt::KeyboardModifiers modifiers) const;
- QDrag *object;
+ virtual Qt::DropAction drag(QDrag *);
+
+ virtual void cancel(bool deleteSource = true);
+ virtual void move(const QMouseEvent *me);
+ virtual void drop(const QMouseEvent *me);
+ void updatePixmap();
void updateCursor();
- bool beingCancelled;
- bool restoreCursor;
- bool willDrop;
- QEventLoop *eventLoop;
+ Qt::DropAction defaultAction(Qt::DropActions possibleActions,
+ Qt::KeyboardModifiers modifiers) const;
QPixmap dragCursor(Qt::DropAction action) const;
- bool hasCustomDragCursors() const;
+ QDragPrivate *dragPrivate() const { return object ? object->d_func() : 0; }
- QDropData *dropData;
+ inline QMimeData *dropData()
+ { return object ? dragPrivate()->data : platformDropData; }
void emitActionChanged(Qt::DropAction newAction) { if (object) emit object->actionChanged(newAction); }
- void setCurrentTarget(QWidget *target, bool dropped = false);
- QWidget *currentTarget();
-
-#ifdef Q_WS_X11
- QPixmap xdndMimeTransferedPixmap[2];
- int xdndMimeTransferedPixmapIndex;
-#endif
-
-private:
-#if defined(Q_WS_QWS) || defined(Q_WS_QPA)
- Qt::DropAction currentActionForOverrideCursor;
-#endif
-#ifdef Q_OS_SYMBIAN
-#ifndef QT_NO_CURSOR
- QCursor overrideCursor;
-#endif
-#endif
- QWidget *currentDropTarget;
-
- static QDragManager *instance;
- Q_DISABLE_COPY(QDragManager)
-};
-
+ void setCurrentTarget(QObject *target, bool dropped = false);
+ QObject *currentTarget();
-#if defined(Q_WS_WIN)
+ QDrag *object;
-class QOleDropTarget : public IDropTarget
-{
-public:
- QOleDropTarget(QWidget* w);
- virtual ~QOleDropTarget() {}
+ bool beingCancelled;
+ bool restoreCursor;
+ bool willDrop;
+ QEventLoop *eventLoop;
- void releaseQt();
+ Qt::DropActions possible_actions;
+ // Shift/Ctrl handling, and final drop status
+ Qt::DropAction global_accepted_action;
- // IUnknown methods
- STDMETHOD(QueryInterface)(REFIID riid, void FAR* FAR* ppvObj);
- STDMETHOD_(ULONG, AddRef)(void);
- STDMETHOD_(ULONG, Release)(void);
+ QShapedPixmapWindow *shapedPixmapWindow;
- // IDropTarget methods
- STDMETHOD(DragEnter)(LPDATAOBJECT pDataObj, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect);
- STDMETHOD(DragOver)(DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect);
- STDMETHOD(DragLeave)();
- STDMETHOD(Drop)(LPDATAOBJECT pDataObj, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect);
+ void unmanageEvents();
+ void stopDrag();
private:
- ULONG m_refs;
- QWidget* widget;
- QPointer<QWidget> currentWidget;
- QRect answerRect;
- QPoint lastPoint;
- DWORD chosenEffect;
- DWORD lastKeyState;
-
- void sendDragEnterEvent(QWidget *to, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect);
-};
+ QMimeData *platformDropData;
-#endif
+ Qt::DropAction currentActionForOverrideCursor;
+ QObject *currentDropTarget;
-#if defined (Q_WS_MAC)
-class QCocoaDropData : public QInternalMimeData
-{
- Q_OBJECT
-public:
- QCocoaDropData(CFStringRef pasteboard);
- ~QCocoaDropData();
+ QPlatformDrag *platformDrag;
-protected:
- bool hasFormat_sys(const QString &mimeType) const;
- QStringList formats_sys() const;
- QVariant retrieveData_sys(const QString &mimeType, QVariant::Type type) const;
-public:
- CFStringRef dropPasteboard;
+ static QDragManager *instance;
+ Q_DISABLE_COPY(QDragManager)
};
-#endif
+
#endif // !QT_NO_DRAGANDDROP
diff --git a/src/gui/kernel/qdnd_qws.cpp b/src/gui/kernel/qdnd_qws.cpp
deleted file mode 100644
index 96bdaed67b..0000000000
--- a/src/gui/kernel/qdnd_qws.cpp
+++ /dev/null
@@ -1,426 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qapplication.h"
-
-#ifndef QT_NO_DRAGANDDROP
-
-#include "qwidget.h"
-#include "qdatetime.h"
-#include "qbitmap.h"
-#include "qcursor.h"
-#include "qevent.h"
-#include "qpainter.h"
-#include "qdnd_p.h"
-
-QT_BEGIN_NAMESPACE
-
-QT_USE_NAMESPACE
-
-static QPixmap *defaultPm = 0;
-static const int default_pm_hotx = -2;
-static const int default_pm_hoty = -16;
-static const char *const default_pm[] = {
-"13 9 3 1",
-". c None",
-" c #000000",
-"X c #FFFFFF",
-"X X X X X X X",
-" X X X X X X ",
-"X ......... X",
-" X.........X ",
-"X ......... X",
-" X.........X ",
-"X ......... X",
-" X X X X X X ",
-"X X X X X X X",
-};
-
-// Shift/Ctrl handling, and final drop status
-static Qt::DropAction global_accepted_action = Qt::CopyAction;
-static Qt::DropActions possible_actions = Qt::IgnoreAction;
-
-
-// static variables in place of a proper cross-process solution
-static QDrag *drag_object;
-static bool qt_qws_dnd_dragging = false;
-
-
-static Qt::KeyboardModifiers oldstate;
-
-class QShapedPixmapWidget : public QWidget {
- QPixmap pixmap;
-public:
- QShapedPixmapWidget() :
- QWidget(0, Qt::Tool | Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint)
- {
- // ### Temporary workaround for 4.2-rc1!!! To prevent flickering when
- // using drag'n drop in a client application. (task 126956)
- // setAttribute() should be done unconditionally!
- if (QApplication::type() == QApplication::GuiServer)
- setAttribute(Qt::WA_TransparentForMouseEvents);
- }
-
- void setPixmap(QPixmap pm)
- {
- pixmap = pm;
- if (!pixmap.mask().isNull()) {
- setMask(pixmap.mask());
- } else {
- clearMask();
- }
- resize(pm.width(),pm.height());
- }
-
- void paintEvent(QPaintEvent*)
- {
- QPainter p(this);
- p.drawPixmap(0,0,pixmap);
- }
-};
-
-
-static QShapedPixmapWidget *qt_qws_dnd_deco = 0;
-
-
-void QDragManager::updatePixmap()
-{
- if (qt_qws_dnd_deco) {
- QPixmap pm;
- QPoint pm_hot(default_pm_hotx,default_pm_hoty);
- if (drag_object) {
- pm = drag_object->pixmap();
- if (!pm.isNull())
- pm_hot = drag_object->hotSpot();
- }
- if (pm.isNull()) {
- if (!defaultPm)
- defaultPm = new QPixmap(default_pm);
- pm = *defaultPm;
- }
- qt_qws_dnd_deco->setPixmap(pm);
- qt_qws_dnd_deco->move(QCursor::pos()-pm_hot);
- if (willDrop) {
- qt_qws_dnd_deco->show();
- } else {
- qt_qws_dnd_deco->hide();
- }
- }
-}
-
-void QDragManager::timerEvent(QTimerEvent *) { }
-
-void QDragManager::move(const QPoint &) { }
-
-void QDragManager::updateCursor()
-{
-#ifndef QT_NO_CURSOR
- if (willDrop) {
- if (qt_qws_dnd_deco)
- qt_qws_dnd_deco->show();
- if (currentActionForOverrideCursor != global_accepted_action) {
- QApplication::changeOverrideCursor(QCursor(dragCursor(global_accepted_action), 0, 0));
- currentActionForOverrideCursor = global_accepted_action;
- }
- } else {
- QCursor *overrideCursor = QApplication::overrideCursor();
- if (!overrideCursor || overrideCursor->shape() != Qt::ForbiddenCursor) {
- QApplication::changeOverrideCursor(QCursor(Qt::ForbiddenCursor));
- currentActionForOverrideCursor = Qt::IgnoreAction;
- }
- if (qt_qws_dnd_deco)
- qt_qws_dnd_deco->hide();
- }
-#endif
-}
-
-
-bool QDragManager::eventFilter(QObject *o, QEvent *e)
-{
- if (beingCancelled) {
- if (e->type() == QEvent::KeyRelease && static_cast<QKeyEvent*>(e)->key() == Qt::Key_Escape) {
- qApp->removeEventFilter(this);
- Q_ASSERT(object == 0);
- beingCancelled = false;
- eventLoop->exit();
- return true; // block the key release
- }
- return false;
- }
-
-
-
- if (!o->isWidgetType())
- return false;
-
- switch(e->type()) {
- case QEvent::ShortcutOverride:
- // prevent accelerators from firing while dragging
- e->accept();
- return true;
-
- case QEvent::KeyPress:
- case QEvent::KeyRelease:
- {
- QKeyEvent *ke = ((QKeyEvent*)e);
- if (ke->key() == Qt::Key_Escape && e->type() == QEvent::KeyPress) {
- cancel();
- qApp->removeEventFilter(this);
- beingCancelled = false;
- eventLoop->exit();
- } else {
- updateCursor();
- }
- return true; // Eat all key events
- }
-
- case QEvent::MouseButtonPress:
- case QEvent::MouseMove:
- {
- if (!object) { //#### this should not happen
- qWarning("QDragManager::eventFilter: No object");
- return true;
- }
-
- QDragManager *manager = QDragManager::self();
- QMimeData *dropData = manager->object ? manager->dragPrivate()->data : manager->dropData;
- if (manager->object)
- possible_actions = manager->dragPrivate()->possible_actions;
- else
- possible_actions = Qt::IgnoreAction;
-
- QMouseEvent *me = (QMouseEvent *)e;
- if (me->buttons()) {
- Qt::DropAction prevAction = global_accepted_action;
- QWidget *cw = QApplication::widgetAt(me->globalPos());
-
- // Fix for when we move mouse on to the deco widget
- if (qt_qws_dnd_deco && cw == qt_qws_dnd_deco)
- cw = object->target();
-
- while (cw && !cw->acceptDrops() && !cw->isWindow())
- cw = cw->parentWidget();
-
- if (object->target() != cw) {
- if (object->target()) {
- QDragLeaveEvent dle;
- QApplication::sendEvent(object->target(), &dle);
- willDrop = false;
- global_accepted_action = Qt::IgnoreAction;
- updateCursor();
- restoreCursor = true;
- object->d_func()->target = 0;
- }
- if (cw && cw->acceptDrops()) {
- object->d_func()->target = cw;
- QDragEnterEvent dee(cw->mapFromGlobal(me->globalPos()), possible_actions, dropData,
- me->buttons(), me->modifiers());
- QApplication::sendEvent(object->target(), &dee);
- willDrop = dee.isAccepted() && dee.dropAction() != Qt::IgnoreAction;
- global_accepted_action = willDrop ? dee.dropAction() : Qt::IgnoreAction;
- updateCursor();
- restoreCursor = true;
- }
- } else if (cw) {
- QDragMoveEvent dme(cw->mapFromGlobal(me->globalPos()), possible_actions, dropData,
- me->buttons(), me->modifiers());
- if (global_accepted_action != Qt::IgnoreAction) {
- dme.setDropAction(global_accepted_action);
- dme.accept();
- }
- QApplication::sendEvent(cw, &dme);
- willDrop = dme.isAccepted();
- global_accepted_action = willDrop ? dme.dropAction() : Qt::IgnoreAction;
- updatePixmap();
- updateCursor();
- }
- if (global_accepted_action != prevAction)
- emitActionChanged(global_accepted_action);
- }
- return true; // Eat all mouse events
- }
-
- case QEvent::MouseButtonRelease:
- {
- qApp->removeEventFilter(this);
- if (restoreCursor) {
- willDrop = false;
-#ifndef QT_NO_CURSOR
- QApplication::restoreOverrideCursor();
-#endif
- restoreCursor = false;
- }
- if (object && object->target()) {
- QMouseEvent *me = (QMouseEvent *)e;
-
- QDragManager *manager = QDragManager::self();
- QMimeData *dropData = manager->object ? manager->dragPrivate()->data : manager->dropData;
-
- QDropEvent de(object->target()->mapFromGlobal(me->globalPos()), possible_actions, dropData,
- me->buttons(), me->modifiers());
- QApplication::sendEvent(object->target(), &de);
- if (de.isAccepted())
- global_accepted_action = de.dropAction();
- else
- global_accepted_action = Qt::IgnoreAction;
-
- if (object)
- object->deleteLater();
- drag_object = object = 0;
- }
- eventLoop->exit();
- return true; // Eat all mouse events
- }
-
- default:
- break;
- }
-
- return false;
-}
-
-Qt::DropAction QDragManager::drag(QDrag *o)
-{
- if (object == o || !o || !o->source())
- return Qt::IgnoreAction;
-
- if (object) {
- cancel();
- qApp->removeEventFilter(this);
- beingCancelled = false;
- }
-
- object = drag_object = o;
- qt_qws_dnd_deco = new QShapedPixmapWidget();
- oldstate = Qt::NoModifier; // #### Should use state that caused the drag
-// drag_mode = mode;
-
- willDrop = false;
- updatePixmap();
- updateCursor();
- restoreCursor = true;
- object->d_func()->target = 0;
- qApp->installEventFilter(this);
-
- global_accepted_action = Qt::CopyAction;
-#ifndef QT_NO_CURSOR
- qApp->setOverrideCursor(Qt::ArrowCursor);
- restoreCursor = true;
- updateCursor();
-#endif
-
- qt_qws_dnd_dragging = true;
-
- eventLoop = new QEventLoop;
- (void) eventLoop->exec();
- delete eventLoop;
- eventLoop = 0;
-
- delete qt_qws_dnd_deco;
- qt_qws_dnd_deco = 0;
- qt_qws_dnd_dragging = false;
-
-
- return global_accepted_action;
-}
-
-
-void QDragManager::cancel(bool deleteSource)
-{
-// qDebug("QDragManager::cancel");
- beingCancelled = true;
-
- if (object->target()) {
- QDragLeaveEvent dle;
- QApplication::sendEvent(object->target(), &dle);
- }
-
-#ifndef QT_NO_CURSOR
- if (restoreCursor) {
- QApplication::restoreOverrideCursor();
- restoreCursor = false;
- }
-#endif
-
- if (drag_object) {
- if (deleteSource)
- object->deleteLater();
- drag_object = object = 0;
- }
-
- delete qt_qws_dnd_deco;
- qt_qws_dnd_deco = 0;
-
- global_accepted_action = Qt::IgnoreAction;
-}
-
-
-void QDragManager::drop()
-{
-}
-
-QVariant QDropData::retrieveData_sys(const QString &mimetype, QVariant::Type type) const
-{
- if (!drag_object)
- return QVariant();
- QByteArray data = drag_object->mimeData()->data(mimetype);
- if (type == QVariant::String)
- return QString::fromUtf8(data);
- return data;
-}
-
-bool QDropData::hasFormat_sys(const QString &format) const
-{
- return formats().contains(format);
-}
-
-QStringList QDropData::formats_sys() const
-{
- if (drag_object)
- return drag_object->mimeData()->formats();
- return QStringList();
-}
-
-
-#endif // QT_NO_DRAGANDDROP
-
-
-QT_END_NAMESPACE
diff --git a/src/gui/kernel/qdnd_x11.cpp b/src/gui/kernel/qdnd_x11.cpp
deleted file mode 100644
index 11e87e96f3..0000000000
--- a/src/gui/kernel/qdnd_x11.cpp
+++ /dev/null
@@ -1,2061 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qplatformdefs.h"
-
-#include "qapplication.h"
-
-#ifndef QT_NO_DRAGANDDROP
-
-#include "qwidget.h"
-#include "qpainter.h"
-#include "qpixmap.h"
-#include "qbitmap.h"
-#include "qdesktopwidget.h"
-#include "qevent.h"
-#include "qiodevice.h"
-#include "qpointer.h"
-#include "qcursor.h"
-#include "qelapsedtimer.h"
-#include "qvariant.h"
-#include "qvector.h"
-#include "qurl.h"
-#include "qdebug.h"
-#include "qimagewriter.h"
-#include "qbuffer.h"
-#include "qtextcodec.h"
-
-#include "qdnd_p.h"
-#include "qapplication_p.h"
-#include "qt_x11_p.h"
-#include "qx11info_x11.h"
-
-#include "qwidget_p.h"
-#include "qcursor_p.h"
-
-QT_BEGIN_NAMESPACE
-
-// #define DND_DEBUG
-#ifdef DND_DEBUG
-#define DEBUG qDebug
-#else
-#define DEBUG if(0) qDebug
-#endif
-
-#ifdef DND_DEBUG
-#define DNDDEBUG qDebug()
-#else
-#define DNDDEBUG if(0) qDebug()
-#endif
-
-static int findXdndDropTransactionByWindow(Window window)
-{
- int at = -1;
- for (int i = 0; i < X11->dndDropTransactions.count(); ++i) {
- const QXdndDropTransaction &t = X11->dndDropTransactions.at(i);
- if (t.target == window || t.proxy_target == window) {
- at = i;
- break;
- }
- }
- return at;
-}
-
-static int findXdndDropTransactionByTime(Time timestamp)
-{
- int at = -1;
- for (int i = 0; i < X11->dndDropTransactions.count(); ++i) {
- const QXdndDropTransaction &t = X11->dndDropTransactions.at(i);
- if (t.timestamp == timestamp) {
- at = i;
- break;
- }
- }
- return at;
-}
-
-// timer used to discard old XdndDrop transactions
-static int transaction_expiry_timer = -1;
-enum { XdndDropTransactionTimeout = 5000 }; // 5 seconds
-
-static void restartXdndDropExpiryTimer()
-{
- if (transaction_expiry_timer != -1)
- QDragManager::self()->killTimer(transaction_expiry_timer);
- transaction_expiry_timer = QDragManager::self()->startTimer(XdndDropTransactionTimeout);
-}
-
-
-// find an ancestor with XdndAware on it
-static Window findXdndAwareParent(Window window)
-{
- Window target = 0;
- forever {
- // check if window has XdndAware
- Atom type = 0;
- int f;
- unsigned long n, a;
- unsigned char *data = 0;
- if (XGetWindowProperty(X11->display, window, ATOM(XdndAware), 0, 0, False,
- AnyPropertyType, &type, &f,&n,&a,&data) == Success) {
- if (data)
- XFree(data);
- if (type) {
- target = window;
- break;
- }
- }
-
- // try window's parent
- Window root;
- Window parent;
- Window *children;
- uint unused;
- if (!XQueryTree(X11->display, window, &root, &parent, &children, &unused))
- break;
- if (children)
- XFree(children);
- if (window == root)
- break;
- window = parent;
- }
- return target;
-}
-
-
-
-
-// and all this stuff is copied -into- qapp_x11.cpp
-
-static void handle_xdnd_position(QWidget *, const XEvent *, bool);
-static void handle_xdnd_status(QWidget * w, const XEvent * xe, bool /*passive*/);
-
-const int xdnd_version = 5;
-
-static Qt::DropAction xdndaction_to_qtaction(Atom atom)
-{
- if (atom == ATOM(XdndActionCopy) || atom == 0)
- return Qt::CopyAction;
- if (atom == ATOM(XdndActionLink))
- return Qt::LinkAction;
- if (atom == ATOM(XdndActionMove))
- return Qt::MoveAction;
- return Qt::CopyAction;
-}
-
-static int qtaction_to_xdndaction(Qt::DropAction a)
-{
- switch (a) {
- case Qt::CopyAction:
- return ATOM(XdndActionCopy);
- case Qt::LinkAction:
- return ATOM(XdndActionLink);
- case Qt::MoveAction:
- case Qt::TargetMoveAction:
- return ATOM(XdndActionMove);
- case Qt::IgnoreAction:
- return XNone;
- default:
- return ATOM(XdndActionCopy);
- }
-}
-
-// clean up the stuff used.
-static void qt_xdnd_cleanup();
-
-static void qt_xdnd_send_leave();
-
-// real variables:
-// xid of current drag source
-static Atom qt_xdnd_dragsource_xid = 0;
-
-// the types in this drop. 100 is no good, but at least it's big.
-const int qt_xdnd_max_type = 100;
-static Atom qt_xdnd_types[qt_xdnd_max_type + 1];
-
-// timer used when target wants "continuous" move messages (eg. scroll)
-static int heartbeat = -1;
-// rectangle in which the answer will be the same
-static QRect qt_xdnd_source_sameanswer;
-// top-level window we sent position to last.
-static Window qt_xdnd_current_target;
-// window to send events to (always valid if qt_xdnd_current_target)
-static Window qt_xdnd_current_proxy_target;
-static Time qt_xdnd_source_current_time;
-
-// widget we forwarded position to last, and local position
-static QPointer<QWidget> qt_xdnd_current_widget;
-static QPoint qt_xdnd_current_position;
-// timestamp from the XdndPosition and XdndDrop
-static Time qt_xdnd_target_current_time;
-// screen number containing the pointer... -1 means default
-static int qt_xdnd_current_screen = -1;
-// state of dragging... true if dragging, false if not
-bool qt_xdnd_dragging = false;
-
-static bool waiting_for_status = false;
-
-// used to preset each new QDragMoveEvent
-static Qt::DropAction last_target_accepted_action = Qt::IgnoreAction;
-
-// Shift/Ctrl handling, and final drop status
-static Qt::DropAction global_accepted_action = Qt::CopyAction;
-static Qt::DropActions possible_actions = Qt::IgnoreAction;
-
-// for embedding only
-static QWidget* current_embedding_widget = 0;
-static XEvent last_enter_event;
-
-// cursors
-static QCursor *noDropCursor = 0;
-static QCursor *moveCursor = 0;
-static QCursor *copyCursor = 0;
-static QCursor *linkCursor = 0;
-
-static QPixmap *defaultPm = 0;
-
-static const int default_pm_hotx = -2;
-static const int default_pm_hoty = -16;
-static const char* const default_pm[] = {
-"13 9 3 1",
-". c None",
-" c #000000",
-"X c #FFFFFF",
-"X X X X X X X",
-" X X X X X X ",
-"X ......... X",
-" X.........X ",
-"X ......... X",
-" X.........X ",
-"X ......... X",
-" X X X X X X ",
-"X X X X X X X"
-};
-
-class QShapedPixmapWidget : public QWidget
-{
- Q_OBJECT
-public:
- QShapedPixmapWidget(QWidget* w) :
- QWidget(w,
- Qt::Tool | Qt::FramelessWindowHint
- | Qt::X11BypassWindowManagerHint
- | Qt::BypassGraphicsProxyWidget)
- {
- setAttribute(Qt::WA_X11NetWmWindowTypeDND);
- }
-
- void setPixmap(const QPixmap &pm)
- {
- QBitmap mask = pm.mask();
- if (!mask.isNull()) {
- setMask(mask);
- } else {
- clearMask();
- }
- resize(pm.width(),pm.height());
- pixmap = pm;
- update();
- }
- QPoint pm_hot;
-
-protected:
- QPixmap pixmap;
- void paintEvent(QPaintEvent*)
- {
- QPainter p(this);
- p.drawPixmap(0, 0, pixmap);
- }
-};
-
-#include "qdnd_x11.moc"
-
-struct XdndData {
- QShapedPixmapWidget *deco;
- QWidget* desktop_proxy;
-};
-
-static XdndData xdnd_data = { 0, 0 };
-
-class QExtraWidget : public QWidget
-{
- Q_DECLARE_PRIVATE(QWidget)
-public:
- inline QWExtra* extraData();
- inline QTLWExtra* topData();
-};
-
-inline QWExtra* QExtraWidget::extraData() { return d_func()->extraData(); }
-inline QTLWExtra* QExtraWidget::topData() { return d_func()->topData(); }
-
-
-static WId xdndProxy(WId w)
-{
- Atom type = XNone;
- int f;
- unsigned long n, a;
- unsigned char *retval = 0;
- XGetWindowProperty(X11->display, w, ATOM(XdndProxy), 0, 1, False,
- XA_WINDOW, &type, &f,&n,&a,&retval);
- WId *proxy_id_ptr = (WId *)retval;
- WId proxy_id = 0;
- if (type == XA_WINDOW && proxy_id_ptr) {
- proxy_id = *proxy_id_ptr;
- XFree(proxy_id_ptr);
- proxy_id_ptr = 0;
- // Already exists. Real?
- X11->ignoreBadwindow();
- XGetWindowProperty(X11->display, proxy_id, ATOM(XdndProxy), 0, 1, False,
- XA_WINDOW, &type, &f,&n,&a,&retval);
- proxy_id_ptr = (WId *)retval;
- if (X11->badwindow() || type != XA_WINDOW || !proxy_id_ptr || *proxy_id_ptr != proxy_id)
- // Bogus - we will overwrite.
- proxy_id = 0;
- }
- if (proxy_id_ptr)
- XFree(proxy_id_ptr);
- return proxy_id;
-}
-
-static bool xdndEnable(QWidget* w, bool on)
-{
- DNDDEBUG << "xdndEnable" << w << on;
- if (on) {
- QWidget * xdnd_widget = 0;
- if ((w->windowType() == Qt::Desktop)) {
- if (xdnd_data.desktop_proxy) // *WE* already have one.
- return false;
-
- // As per Xdnd4, use XdndProxy
- XGrabServer(X11->display);
- Q_ASSERT(w->testAttribute(Qt::WA_WState_Created));
- WId proxy_id = xdndProxy(w->effectiveWinId());
-
- if (!proxy_id) {
- xdnd_widget = xdnd_data.desktop_proxy = new QWidget;
- proxy_id = xdnd_data.desktop_proxy->effectiveWinId();
- XChangeProperty (X11->display, w->effectiveWinId(), ATOM(XdndProxy),
- XA_WINDOW, 32, PropModeReplace, (unsigned char *)&proxy_id, 1);
- XChangeProperty (X11->display, proxy_id, ATOM(XdndProxy),
- XA_WINDOW, 32, PropModeReplace, (unsigned char *)&proxy_id, 1);
- }
-
- XUngrabServer(X11->display);
- } else {
- xdnd_widget = w->window();
- }
- if (xdnd_widget) {
- DNDDEBUG << "setting XdndAware for" << xdnd_widget << xdnd_widget->effectiveWinId();
- Atom atm = (Atom)xdnd_version;
- Q_ASSERT(xdnd_widget->testAttribute(Qt::WA_WState_Created));
- XChangeProperty(X11->display, xdnd_widget->effectiveWinId(), ATOM(XdndAware),
- XA_ATOM, 32, PropModeReplace, (unsigned char *)&atm, 1);
- return true;
- } else {
- return false;
- }
- } else {
- if ((w->windowType() == Qt::Desktop)) {
- XDeleteProperty(X11->display, w->internalWinId(), ATOM(XdndProxy));
- delete xdnd_data.desktop_proxy;
- xdnd_data.desktop_proxy = 0;
- } else {
- DNDDEBUG << "not deleting XDndAware";
- }
- return true;
- }
-}
-
-QByteArray QX11Data::xdndAtomToString(Atom a)
-{
- if (!a) return 0;
-
- if (a == XA_STRING || a == ATOM(UTF8_STRING)) {
- return "text/plain"; // some Xdnd clients are dumb
- }
- char *atom = XGetAtomName(display, a);
- QByteArray result = atom;
- XFree(atom);
- return result;
-}
-
-Atom QX11Data::xdndStringToAtom(const char *mimeType)
-{
- if (!mimeType || !*mimeType)
- return 0;
- return XInternAtom(display, mimeType, False);
-}
-
-//$$$
-QString QX11Data::xdndMimeAtomToString(Atom a)
-{
- QString atomName;
- if (a) {
- char *atom = XGetAtomName(display, a);
- atomName = QString::fromLatin1(atom);
- XFree(atom);
- }
- return atomName;
-}
-
-//$$$
-Atom QX11Data::xdndMimeStringToAtom(const QString &mimeType)
-{
- if (mimeType.isEmpty())
- return 0;
- return XInternAtom(display, mimeType.toLatin1().constData(), False);
-}
-
-//$$$ replace ccxdndAtomToString()
-QStringList QX11Data::xdndMimeFormatsForAtom(Atom a)
-{
- QStringList formats;
- if (a) {
- QString atomName = xdndMimeAtomToString(a);
- formats.append(atomName);
-
- // special cases for string type
- if (a == ATOM(UTF8_STRING) || a == XA_STRING
- || a == ATOM(TEXT) || a == ATOM(COMPOUND_TEXT))
- formats.append(QLatin1String("text/plain"));
-
- // special cases for uris
- if (atomName == QLatin1String("text/x-moz-url"))
- formats.append(QLatin1String("text/uri-list"));
-
- // special case for images
- if (a == XA_PIXMAP)
- formats.append(QLatin1String("image/ppm"));
- }
- return formats;
-}
-
-//$$$
-bool QX11Data::xdndMimeDataForAtom(Atom a, QMimeData *mimeData, QByteArray *data, Atom *atomFormat, int *dataFormat)
-{
- bool ret = false;
- *atomFormat = a;
- *dataFormat = 8;
- QString atomName = xdndMimeAtomToString(a);
- if (QInternalMimeData::hasFormatHelper(atomName, mimeData)) {
- *data = QInternalMimeData::renderDataHelper(atomName, mimeData);
- if (atomName == QLatin1String("application/x-color"))
- *dataFormat = 16;
- ret = true;
- } else {
- if ((a == ATOM(UTF8_STRING) || a == XA_STRING
- || a == ATOM(TEXT) || a == ATOM(COMPOUND_TEXT))
- && QInternalMimeData::hasFormatHelper(QLatin1String("text/plain"), mimeData)) {
- if (a == ATOM(UTF8_STRING)){
- *data = QInternalMimeData::renderDataHelper(QLatin1String("text/plain"), mimeData);
- ret = true;
- } else if (a == XA_STRING) {
- *data = QString::fromUtf8(QInternalMimeData::renderDataHelper(
- QLatin1String("text/plain"), mimeData)).toLocal8Bit();
- ret = true;
- } else if (a == ATOM(TEXT) || a == ATOM(COMPOUND_TEXT)) {
- // the ICCCM states that TEXT and COMPOUND_TEXT are in the
- // encoding of choice, so we choose the encoding of the locale
- QByteArray strData = QString::fromUtf8(QInternalMimeData::renderDataHelper(
- QLatin1String("text/plain"), mimeData)).toLocal8Bit();
- char *list[] = { strData.data(), NULL };
-
- XICCEncodingStyle style = (a == ATOM(COMPOUND_TEXT))
- ? XCompoundTextStyle : XStdICCTextStyle;
- XTextProperty textprop;
- if (list[0] != NULL
- && XmbTextListToTextProperty(X11->display, list, 1, style,
- &textprop) == Success) {
- *atomFormat = textprop.encoding;
- *dataFormat = textprop.format;
- *data = QByteArray((const char *) textprop.value, textprop.nitems * textprop.format / 8);
- ret = true;
-
- DEBUG(" textprop type %lx\n"
- " textprop name '%s'\n"
- " format %d\n"
- " %ld items\n"
- " %d bytes\n",
- textprop.encoding,
- X11->xdndMimeAtomToString(textprop.encoding).toLatin1().data(),
- textprop.format, textprop.nitems, data->size());
-
- XFree(textprop.value);
- }
- }
- } else if (atomName == QLatin1String("text/x-moz-url") &&
- QInternalMimeData::hasFormatHelper(QLatin1String("text/uri-list"), mimeData)) {
- QByteArray uri = QInternalMimeData::renderDataHelper(
- QLatin1String("text/uri-list"), mimeData).split('\n').first();
- QString mozUri = QString::fromLatin1(uri, uri.size());
- mozUri += QLatin1Char('\n');
- *data = QByteArray(reinterpret_cast<const char *>(mozUri.utf16()), mozUri.length() * 2);
- ret = true;
- } else if ((a == XA_PIXMAP || a == XA_BITMAP) && mimeData->hasImage()) {
- QPixmap pm = qvariant_cast<QPixmap>(mimeData->imageData());
- if (a == XA_BITMAP && pm.depth() != 1) {
- QImage img = pm.toImage();
- img = img.convertToFormat(QImage::Format_MonoLSB);
- pm = QPixmap::fromImage(img);
- }
- QDragManager *dm = QDragManager::self();
- if (dm) {
- Pixmap handle = pm.handle();
- *data = QByteArray((const char *) &handle, sizeof(Pixmap));
- dm->xdndMimeTransferedPixmap[dm->xdndMimeTransferedPixmapIndex] = pm;
- dm->xdndMimeTransferedPixmapIndex =
- (dm->xdndMimeTransferedPixmapIndex + 1) % 2;
- ret = true;
- }
- } else {
- DEBUG("QClipboard: xdndMimeDataForAtom(): converting to type '%s' is not supported", qPrintable(atomName));
- }
- }
- return ret && data != 0;
-}
-
-//$$$
-QList<Atom> QX11Data::xdndMimeAtomsForFormat(const QString &format)
-{
- QList<Atom> atoms;
- atoms.append(xdndMimeStringToAtom(format));
-
- // special cases for strings
- if (format == QLatin1String("text/plain")) {
- atoms.append(ATOM(UTF8_STRING));
- atoms.append(XA_STRING);
- atoms.append(ATOM(TEXT));
- atoms.append(ATOM(COMPOUND_TEXT));
- }
-
- // special cases for uris
- if (format == QLatin1String("text/uri-list")) {
- atoms.append(xdndMimeStringToAtom(QLatin1String("text/x-moz-url")));
- }
-
- //special cases for images
- if (format == QLatin1String("image/ppm"))
- atoms.append(XA_PIXMAP);
- if (format == QLatin1String("image/pbm"))
- atoms.append(XA_BITMAP);
-
- return atoms;
-}
-
-//$$$
-QVariant QX11Data::xdndMimeConvertToFormat(Atom a, const QByteArray &data, const QString &format, QVariant::Type requestedType, const QByteArray &encoding)
-{
- QString atomName = xdndMimeAtomToString(a);
- if (atomName == format)
- return data;
-
- if (!encoding.isEmpty()
- && atomName == format + QLatin1String(";charset=") + QString::fromLatin1(encoding)) {
-
- if (requestedType == QVariant::String) {
- QTextCodec *codec = QTextCodec::codecForName(encoding);
- if (codec)
- return codec->toUnicode(data);
- }
-
- return data;
- }
-
- // special cases for string types
- if (format == QLatin1String("text/plain")) {
- if (a == ATOM(UTF8_STRING))
- return QString::fromUtf8(data);
- if (a == XA_STRING)
- return QString::fromLatin1(data);
- if (a == ATOM(TEXT) || a == ATOM(COMPOUND_TEXT))
- // #### might be wrong for COMPUND_TEXT
- return QString::fromLocal8Bit(data, data.size());
- }
-
- // special case for uri types
- if (format == QLatin1String("text/uri-list")) {
- if (atomName == QLatin1String("text/x-moz-url")) {
- // we expect this as utf16 <url><space><title>
- // the first part is a url that should only contain ascci char
- // so it should be safe to check that the second char is 0
- // to verify that it is utf16
- if (data.size() > 1 && data.at(1) == 0)
- return QString::fromRawData((const QChar *)data.constData(),
- data.size() / 2).split(QLatin1Char('\n')).first().toLatin1();
- }
- }
-
- // special cas for images
- if (format == QLatin1String("image/ppm")) {
- if (a == XA_PIXMAP && data.size() == sizeof(Pixmap)) {
- Pixmap xpm = *((Pixmap*)data.data());
- if (!xpm)
- return QByteArray();
- QPixmap qpm = QPixmap::fromX11Pixmap(xpm);
- QImageWriter imageWriter;
- imageWriter.setFormat("PPMRAW");
- QImage imageToWrite = qpm.toImage();
- QBuffer buf;
- buf.open(QIODevice::WriteOnly);
- imageWriter.setDevice(&buf);
- imageWriter.write(imageToWrite);
- return buf.buffer();
- }
- }
- return QVariant();
-}
-
-//$$$ middle of xdndObtainData
-Atom QX11Data::xdndMimeAtomForFormat(const QString &format, QVariant::Type requestedType, const QList<Atom> &atoms, QByteArray *encoding)
-{
- encoding->clear();
-
- // find matches for string types
- if (format == QLatin1String("text/plain")) {
- if (atoms.contains(ATOM(UTF8_STRING)))
- return ATOM(UTF8_STRING);
- if (atoms.contains(ATOM(COMPOUND_TEXT)))
- return ATOM(COMPOUND_TEXT);
- if (atoms.contains(ATOM(TEXT)))
- return ATOM(TEXT);
- if (atoms.contains(XA_STRING))
- return XA_STRING;
- }
-
- // find matches for uri types
- if (format == QLatin1String("text/uri-list")) {
- Atom a = xdndMimeStringToAtom(format);
- if (a && atoms.contains(a))
- return a;
- a = xdndMimeStringToAtom(QLatin1String("text/x-moz-url"));
- if (a && atoms.contains(a))
- return a;
- }
-
- // find match for image
- if (format == QLatin1String("image/ppm")) {
- if (atoms.contains(XA_PIXMAP))
- return XA_PIXMAP;
- }
-
- // for string/text requests try to use a format with a well-defined charset
- // first to avoid encoding problems
- if (requestedType == QVariant::String
- && format.startsWith(QLatin1String("text/"))
- && !format.contains(QLatin1String("charset="))) {
-
- QString formatWithCharset = format;
- formatWithCharset.append(QLatin1String(";charset=utf-8"));
-
- Atom a = xdndMimeStringToAtom(formatWithCharset);
- if (a && atoms.contains(a)) {
- *encoding = "utf-8";
- return a;
- }
- }
-
- Atom a = xdndMimeStringToAtom(format);
- if (a && atoms.contains(a))
- return a;
-
- return 0;
-}
-
-void QX11Data::xdndSetup() {
- QCursorData::initialize();
- qAddPostRoutine(qt_xdnd_cleanup);
-}
-
-
-void qt_xdnd_cleanup()
-{
- delete noDropCursor;
- noDropCursor = 0;
- delete copyCursor;
- copyCursor = 0;
- delete moveCursor;
- moveCursor = 0;
- delete linkCursor;
- linkCursor = 0;
- delete defaultPm;
- defaultPm = 0;
- delete xdnd_data.desktop_proxy;
- xdnd_data.desktop_proxy = 0;
- delete xdnd_data.deco;
- xdnd_data.deco = 0;
-}
-
-
-static QWidget *find_child(QWidget *tlw, QPoint & p)
-{
- QWidget *widget = tlw;
-
- p = widget->mapFromGlobal(p);
- bool done = false;
- while (!done) {
- done = true;
- if (((QExtraWidget*)widget)->extraData() &&
- ((QExtraWidget*)widget)->extraData()->xDndProxy != 0)
- break; // stop searching for widgets under the mouse cursor if found widget is a proxy.
- QObjectList children = widget->children();
- if (!children.isEmpty()) {
- for(int i = children.size(); i > 0;) {
- --i;
- QWidget *w = qobject_cast<QWidget *>(children.at(i));
- if (!w)
- continue;
- if (w->testAttribute(Qt::WA_TransparentForMouseEvents))
- continue;
- if (w->isVisible() &&
- w->geometry().contains(p) &&
- !w->isWindow()) {
- widget = w;
- done = false;
- p = widget->mapFromParent(p);
- break;
- }
- }
- }
- }
- return widget;
-}
-
-
-static bool checkEmbedded(QWidget* w, const XEvent* xe)
-{
- if (!w)
- return false;
-
- if (current_embedding_widget != 0 && current_embedding_widget != w) {
- qt_xdnd_current_target = ((QExtraWidget*)current_embedding_widget)->extraData()->xDndProxy;
- qt_xdnd_current_proxy_target = qt_xdnd_current_target;
- qt_xdnd_send_leave();
- qt_xdnd_current_target = 0;
- qt_xdnd_current_proxy_target = 0;
- current_embedding_widget = 0;
- }
-
- QWExtra* extra = ((QExtraWidget*)w)->extraData();
- if (extra && extra->xDndProxy != 0) {
-
- if (current_embedding_widget != w) {
-
- last_enter_event.xany.window = extra->xDndProxy;
- XSendEvent(X11->display, extra->xDndProxy, False, NoEventMask, &last_enter_event);
- current_embedding_widget = w;
- }
-
- ((XEvent*)xe)->xany.window = extra->xDndProxy;
- XSendEvent(X11->display, extra->xDndProxy, False, NoEventMask, (XEvent*)xe);
- if (qt_xdnd_current_widget != w) {
- qt_xdnd_current_widget = w;
- }
- return true;
- }
- current_embedding_widget = 0;
- return false;
-}
-
-void QX11Data::xdndHandleEnter(QWidget *, const XEvent * xe, bool /*passive*/)
-{
- motifdnd_active = false;
-
- last_enter_event.xclient = xe->xclient;
-
- const long *l = xe->xclient.data.l;
- int version = (int)(((unsigned long)(l[1])) >> 24);
-
- if (version > xdnd_version)
- return;
-
- qt_xdnd_dragsource_xid = l[0];
-
- int j = 0;
- if (l[1] & 1) {
- // get the types from XdndTypeList
- Atom type = XNone;
- int f;
- unsigned long n, a;
- unsigned char *retval = 0;
- XGetWindowProperty(X11->display, qt_xdnd_dragsource_xid, ATOM(XdndTypelist), 0,
- qt_xdnd_max_type, False, XA_ATOM, &type, &f,&n,&a,&retval);
- if (retval) {
- Atom *data = (Atom *)retval;
- for (; j<qt_xdnd_max_type && j < (int)n; j++) {
- qt_xdnd_types[j] = data[j];
- }
- XFree((uchar*)data);
- }
- } else {
- // get the types from the message
- int i;
- for(i=2; i < 5; i++) {
- qt_xdnd_types[j++] = l[i];
- }
- }
- qt_xdnd_types[j] = 0;
-}
-
-static void handle_xdnd_position(QWidget *w, const XEvent * xe, bool passive)
-{
- const unsigned long *l = (const unsigned long *)xe->xclient.data.l;
-
- QPoint p((l[2] & 0xffff0000) >> 16, l[2] & 0x0000ffff);
- QWidget * c = find_child(w, p); // changes p to to c-local coordinates
-
- if (!passive && checkEmbedded(c, xe))
- return;
-
- if (!c || (!c->acceptDrops() && (c->windowType() == Qt::Desktop)))
- return;
-
- if (l[0] != qt_xdnd_dragsource_xid) {
- DEBUG("xdnd drag position from unexpected source (%08lx not %08lx)", l[0], qt_xdnd_dragsource_xid);
- return;
- }
-
- // timestamp from the source
- if (l[3] != 0) {
- // Some X server/client combination swallow the first 32 bit and
- // interpret a set bit 31 as negative sign.
- qt_xdnd_target_current_time = X11->userTime =
- ((sizeof(Time) == 8 && xe->xclient.data.l[3] < 0)
- ? uint(l[3])
- : l[3]);
- }
-
- QDragManager *manager = QDragManager::self();
- QMimeData *dropData = manager->object ? manager->dragPrivate()->data : manager->dropData;
-
- XClientMessageEvent response;
- response.type = ClientMessage;
- response.window = qt_xdnd_dragsource_xid;
- response.format = 32;
- response.message_type = ATOM(XdndStatus);
- response.data.l[0] = w->effectiveWinId();
- response.data.l[1] = 0; // flags
- response.data.l[2] = 0; // x, y
- response.data.l[3] = 0; // w, h
- response.data.l[4] = 0; // action
-
- if (!passive) { // otherwise just reject
- while (c && !c->acceptDrops() && !c->isWindow()) {
- p = c->mapToParent(p);
- c = c->parentWidget();
- }
- QWidget *target_widget = c && c->acceptDrops() ? c : 0;
-
- QRect answerRect(c->mapToGlobal(p), QSize(1,1));
-
- if (manager->object) {
- possible_actions = manager->dragPrivate()->possible_actions;
- } else {
- possible_actions = Qt::DropActions(xdndaction_to_qtaction(l[4]));
-// possible_actions |= Qt::CopyAction;
- }
- QDragMoveEvent me(p, possible_actions, dropData, QApplication::mouseButtons(), QApplication::keyboardModifiers());
-
- Qt::DropAction accepted_action = Qt::IgnoreAction;
-
-
- if (target_widget != qt_xdnd_current_widget) {
- if (qt_xdnd_current_widget) {
- QDragLeaveEvent e;
- QApplication::sendEvent(qt_xdnd_current_widget, &e);
- }
- if (qt_xdnd_current_widget != target_widget) {
- qt_xdnd_current_widget = target_widget;
- }
- if (target_widget) {
- qt_xdnd_current_position = p;
-
- last_target_accepted_action = Qt::IgnoreAction;
- QDragEnterEvent de(p, possible_actions, dropData, QApplication::mouseButtons(), QApplication::keyboardModifiers());
- QApplication::sendEvent(target_widget, &de);
- if (de.isAccepted() && de.dropAction() != Qt::IgnoreAction)
- last_target_accepted_action = de.dropAction();
- }
- }
-
- DEBUG() << "qt_handle_xdnd_position action=" << X11->xdndAtomToString(l[4]);
- if (!target_widget) {
- answerRect = QRect(p, QSize(1, 1));
- } else {
- qt_xdnd_current_widget = c;
- qt_xdnd_current_position = p;
-
- if (last_target_accepted_action != Qt::IgnoreAction) {
- me.setDropAction(last_target_accepted_action);
- me.accept();
- }
- QApplication::sendEvent(c, &me);
- if (me.isAccepted()) {
- response.data.l[1] = 1; // yes
- accepted_action = me.dropAction();
- last_target_accepted_action = accepted_action;
- } else {
- response.data.l[0] = 0;
- last_target_accepted_action = Qt::IgnoreAction;
- }
- answerRect = me.answerRect().intersected(c->rect());
- }
- answerRect = QRect(c->mapToGlobal(answerRect.topLeft()), answerRect.size());
-
- if (answerRect.left() < 0)
- answerRect.setLeft(0);
- if (answerRect.right() > 4096)
- answerRect.setRight(4096);
- if (answerRect.top() < 0)
- answerRect.setTop(0);
- if (answerRect.bottom() > 4096)
- answerRect.setBottom(4096);
- if (answerRect.width() < 0)
- answerRect.setWidth(0);
- if (answerRect.height() < 0)
- answerRect.setHeight(0);
-
- response.data.l[2] = (answerRect.x() << 16) + answerRect.y();
- response.data.l[3] = (answerRect.width() << 16) + answerRect.height();
- response.data.l[4] = qtaction_to_xdndaction(accepted_action);
- }
-
- // reset
- qt_xdnd_target_current_time = CurrentTime;
-
- QWidget * source = QWidget::find(qt_xdnd_dragsource_xid);
- if (source && (source->windowType() == Qt::Desktop) && !source->acceptDrops())
- source = 0;
-
- DEBUG() << "sending XdndStatus";
- if (source)
- handle_xdnd_status(source, (const XEvent *)&response, passive);
- else
- XSendEvent(X11->display, qt_xdnd_dragsource_xid, False, NoEventMask, (XEvent*)&response);
-}
-
-static Bool xdnd_position_scanner(Display *, XEvent *event, XPointer)
-{
- if (event->type != ClientMessage)
- return false;
- XClientMessageEvent *ev = &event->xclient;
-
- if (ev->message_type == ATOM(XdndPosition))
- return true;
-
- return false;
-}
-
-void QX11Data::xdndHandlePosition(QWidget * w, const XEvent * xe, bool passive)
-{
- DEBUG("xdndHandlePosition");
- while (XCheckIfEvent(X11->display, (XEvent *)xe, xdnd_position_scanner, 0))
- ;
-
- handle_xdnd_position(w, xe, passive);
-}
-
-
-static void handle_xdnd_status(QWidget *, const XEvent * xe, bool)
-{
- const unsigned long *l = (const unsigned long *)xe->xclient.data.l;
- // ignore late status messages
- if (l[0] && l[0] != qt_xdnd_current_proxy_target)
- return;
- Qt::DropAction newAction = (l[1] & 0x1) ? xdndaction_to_qtaction(l[4]) : Qt::IgnoreAction;
-
- if ((int)(l[1] & 2) == 0) {
- QPoint p((l[2] & 0xffff0000) >> 16, l[2] & 0x0000ffff);
- QSize s((l[3] & 0xffff0000) >> 16, l[3] & 0x0000ffff);
- qt_xdnd_source_sameanswer = QRect(p, s);
- } else {
- qt_xdnd_source_sameanswer = QRect();
- }
- QDragManager *manager = QDragManager::self();
- manager->willDrop = (l[1] & 0x1);
- if (global_accepted_action != newAction)
- manager->emitActionChanged(newAction);
- global_accepted_action = newAction;
- manager->updateCursor();
- waiting_for_status = false;
-}
-
-static Bool xdnd_status_scanner(Display *, XEvent *event, XPointer)
-{
- if (event->type != ClientMessage)
- return false;
- XClientMessageEvent *ev = &event->xclient;
-
- if (ev->message_type == ATOM(XdndStatus))
- return true;
-
- return false;
-}
-
-void QX11Data::xdndHandleStatus(QWidget * w, const XEvent * xe, bool passive)
-{
- DEBUG("xdndHandleStatus");
- while (XCheckIfEvent(X11->display, (XEvent *)xe, xdnd_status_scanner, 0))
- ;
-
- handle_xdnd_status(w, xe, passive);
- DEBUG("xdndHandleStatus end");
-}
-
-void QX11Data::xdndHandleLeave(QWidget *w, const XEvent * xe, bool /*passive*/)
-{
- DEBUG("xdnd leave");
- if (!qt_xdnd_current_widget ||
- w->window() != qt_xdnd_current_widget->window()) {
- return; // sanity
- }
-
- if (checkEmbedded(current_embedding_widget, xe)) {
- current_embedding_widget = 0;
- qt_xdnd_current_widget = 0;
- return;
- }
-
- const unsigned long *l = (const unsigned long *)xe->xclient.data.l;
-
- QDragLeaveEvent e;
- QApplication::sendEvent(qt_xdnd_current_widget, &e);
-
- if (l[0] != qt_xdnd_dragsource_xid) {
- // This often happens - leave other-process window quickly
- DEBUG("xdnd drag leave from unexpected source (%08lx not %08lx", l[0], qt_xdnd_dragsource_xid);
- qt_xdnd_current_widget = 0;
- return;
- }
-
- qt_xdnd_dragsource_xid = 0;
- qt_xdnd_types[0] = 0;
- qt_xdnd_current_widget = 0;
-}
-
-
-void qt_xdnd_send_leave()
-{
- if (!qt_xdnd_current_target)
- return;
-
- QDragManager *manager = QDragManager::self();
-
- XClientMessageEvent leave;
- leave.type = ClientMessage;
- leave.window = qt_xdnd_current_target;
- leave.format = 32;
- leave.message_type = ATOM(XdndLeave);
- leave.data.l[0] = manager->dragPrivate()->source->effectiveWinId();
- leave.data.l[1] = 0; // flags
- leave.data.l[2] = 0; // x, y
- leave.data.l[3] = 0; // w, h
- leave.data.l[4] = 0; // just null
-
- QWidget * w = QWidget::find(qt_xdnd_current_proxy_target);
-
- if (w && (w->windowType() == Qt::Desktop) && !w->acceptDrops())
- w = 0;
-
- if (w)
- X11->xdndHandleLeave(w, (const XEvent *)&leave, false);
- else
- XSendEvent(X11->display, qt_xdnd_current_proxy_target, False,
- NoEventMask, (XEvent*)&leave);
-
- // reset the drag manager state
- manager->willDrop = false;
- if (global_accepted_action != Qt::IgnoreAction)
- manager->emitActionChanged(Qt::IgnoreAction);
- global_accepted_action = Qt::IgnoreAction;
- manager->updateCursor();
- qt_xdnd_current_target = 0;
- qt_xdnd_current_proxy_target = 0;
- qt_xdnd_source_current_time = 0;
- waiting_for_status = false;
-}
-
-void QX11Data::xdndHandleDrop(QWidget *, const XEvent * xe, bool passive)
-{
- DEBUG("xdndHandleDrop");
- if (!qt_xdnd_current_widget) {
- qt_xdnd_dragsource_xid = 0;
- return; // sanity
- }
-
- if (!passive && checkEmbedded(qt_xdnd_current_widget, xe)){
- current_embedding_widget = 0;
- qt_xdnd_dragsource_xid = 0;
- qt_xdnd_current_widget = 0;
- return;
- }
- const unsigned long *l = (const unsigned long *)xe->xclient.data.l;
-
- QDragManager *manager = QDragManager::self();
- DEBUG("xdnd drop");
-
- if (l[0] != qt_xdnd_dragsource_xid) {
- DEBUG("xdnd drop from unexpected source (%08lx not %08lx", l[0], qt_xdnd_dragsource_xid);
- return;
- }
-
- // update the "user time" from the timestamp in the event.
- if (l[2] != 0) {
- // Some X server/client combination swallow the first 32 bit and
- // interpret a set bit 31 as negative sign.
- qt_xdnd_target_current_time = X11->userTime =
- ((sizeof(Time) == 8 && xe->xclient.data.l[2] < 0)
- ? uint(l[2])
- : l[2]);
- }
-
- if (!passive) {
- // this could be a same-application drop, just proxied due to
- // some XEMBEDding, so try to find the real QMimeData used
- // based on the timestamp for this drop.
- QMimeData *dropData = 0;
- int at = findXdndDropTransactionByTime(qt_xdnd_target_current_time);
- if (at != -1)
- dropData = QDragManager::dragPrivate(X11->dndDropTransactions.at(at).object)->data;
- // if we can't find it, then use the data in the drag manager
- if (!dropData)
- dropData = (manager->object) ? manager->dragPrivate()->data : manager->dropData;
-
- // Drop coming from another app? Update keyboard modifiers.
- if (!qt_xdnd_dragging) {
- QApplicationPrivate::modifier_buttons = QApplication::queryKeyboardModifiers();
- }
-
- QDropEvent de(qt_xdnd_current_position, possible_actions, dropData,
- QApplication::mouseButtons(), QApplication::keyboardModifiers());
- QApplication::sendEvent(qt_xdnd_current_widget, &de);
- if (!de.isAccepted()) {
- // Ignore a failed drag
- global_accepted_action = Qt::IgnoreAction;
- } else {
- global_accepted_action = de.dropAction();
- }
- XClientMessageEvent finished;
- finished.type = ClientMessage;
- finished.window = qt_xdnd_dragsource_xid;
- finished.format = 32;
- finished.message_type = ATOM(XdndFinished);
- DNDDEBUG << "xdndHandleDrop"
- << "qt_xdnd_current_widget" << qt_xdnd_current_widget
- << (qt_xdnd_current_widget ? qt_xdnd_current_widget->effectiveWinId() : 0)
- << "t_xdnd_current_widget->window()"
- << (qt_xdnd_current_widget ? qt_xdnd_current_widget->window() : 0)
- << (qt_xdnd_current_widget ? qt_xdnd_current_widget->window()->internalWinId() : 0);
- finished.data.l[0] = qt_xdnd_current_widget?qt_xdnd_current_widget->window()->internalWinId():0;
- finished.data.l[1] = de.isAccepted() ? 1 : 0; // flags
- finished.data.l[2] = qtaction_to_xdndaction(global_accepted_action);
- XSendEvent(X11->display, qt_xdnd_dragsource_xid, False,
- NoEventMask, (XEvent*)&finished);
- } else {
- QDragLeaveEvent e;
- QApplication::sendEvent(qt_xdnd_current_widget, &e);
- }
- qt_xdnd_dragsource_xid = 0;
- qt_xdnd_current_widget = 0;
- waiting_for_status = false;
-
- // reset
- qt_xdnd_target_current_time = CurrentTime;
-}
-
-
-void QX11Data::xdndHandleFinished(QWidget *, const XEvent * xe, bool passive)
-{
- DEBUG("xdndHandleFinished");
- const unsigned long *l = (const unsigned long *)xe->xclient.data.l;
-
- DNDDEBUG << "xdndHandleFinished, l[0]" << l[0]
- << "qt_xdnd_current_target" << qt_xdnd_current_target
- << "qt_xdnd_current_proxy_targe" << qt_xdnd_current_proxy_target;
-
- if (l[0]) {
- int at = findXdndDropTransactionByWindow(l[0]);
- if (at != -1) {
- restartXdndDropExpiryTimer();
-
- QXdndDropTransaction t = X11->dndDropTransactions.takeAt(at);
- QDragManager *manager = QDragManager::self();
-
- Window target = qt_xdnd_current_target;
- Window proxy_target = qt_xdnd_current_proxy_target;
- QWidget *embedding_widget = current_embedding_widget;
- QDrag *currentObject = manager->object;
-
- qt_xdnd_current_target = t.target;
- qt_xdnd_current_proxy_target = t.proxy_target;
- current_embedding_widget = t.embedding_widget;
- manager->object = t.object;
-
- if (!passive)
- (void) checkEmbedded(qt_xdnd_current_widget, xe);
-
- current_embedding_widget = 0;
- qt_xdnd_current_target = 0;
- qt_xdnd_current_proxy_target = 0;
-
- if (t.object)
- t.object->deleteLater();
-
- qt_xdnd_current_target = target;
- qt_xdnd_current_proxy_target = proxy_target;
- current_embedding_widget = embedding_widget;
- manager->object = currentObject;
- }
- }
- waiting_for_status = false;
-}
-
-
-void QDragManager::timerEvent(QTimerEvent* e)
-{
- if (e->timerId() == heartbeat && qt_xdnd_source_sameanswer.isNull()) {
- move(QCursor::pos());
- } else if (e->timerId() == transaction_expiry_timer) {
- for (int i = 0; i < X11->dndDropTransactions.count(); ++i) {
- const QXdndDropTransaction &t = X11->dndDropTransactions.at(i);
- if (t.targetWidget) {
- // dnd within the same process, don't delete these
- continue;
- }
- t.object->deleteLater();
- X11->dndDropTransactions.removeAt(i--);
- }
-
- killTimer(transaction_expiry_timer);
- transaction_expiry_timer = -1;
- }
-}
-
-bool QDragManager::eventFilter(QObject * o, QEvent * e)
-{
- if (beingCancelled) {
- if (e->type() == QEvent::KeyRelease && ((QKeyEvent*)e)->key() == Qt::Key_Escape) {
- qApp->removeEventFilter(this);
- Q_ASSERT(object == 0);
- beingCancelled = false;
- eventLoop->exit();
- return true; // block the key release
- }
- return false;
- }
-
- Q_ASSERT(object != 0);
-
- if (!o->isWidgetType())
- return false;
-
- if (e->type() == QEvent::MouseMove) {
- QMouseEvent* me = (QMouseEvent *)e;
- move(me->globalPos());
- return true;
- } else if (e->type() == QEvent::MouseButtonRelease) {
- DEBUG("pre drop");
- qApp->removeEventFilter(this);
- if (willDrop)
- drop();
- else
- cancel();
- DEBUG("drop, resetting object");
- beingCancelled = false;
- eventLoop->exit();
- return true;
- }
-
- if (e->type() == QEvent::ShortcutOverride) {
- // prevent accelerators from firing while dragging
- e->accept();
- return true;
- }
-
- if (e->type() == QEvent::KeyPress || e->type() == QEvent::KeyRelease) {
- QKeyEvent *ke = ((QKeyEvent*)e);
- if (ke->key() == Qt::Key_Escape && e->type() == QEvent::KeyPress) {
- cancel();
- qApp->removeEventFilter(this);
- beingCancelled = false;
- eventLoop->exit();
- } else {
- qt_xdnd_source_sameanswer = QRect(); // force move
- move(QCursor::pos());
- }
- return true; // Eat all key events
- }
-
- // ### We bind modality to widgets, so we have to do this
- // ### "manually".
- // DnD is modal - eat all other interactive events
- switch (e->type()) {
- case QEvent::MouseButtonPress:
- case QEvent::MouseButtonRelease:
- case QEvent::MouseButtonDblClick:
- case QEvent::MouseMove:
- case QEvent::KeyPress:
- case QEvent::KeyRelease:
- case QEvent::Wheel:
- case QEvent::ShortcutOverride:
-#ifdef QT3_SUPPORT
- case QEvent::Accel:
- case QEvent::AccelAvailable:
-#endif
- return true;
- default:
- return false;
- }
-}
-
-void QDragManager::updateCursor()
-{
- if (!noDropCursor) {
-#ifndef QT_NO_CURSOR
- noDropCursor = new QCursor(Qt::ForbiddenCursor);
- moveCursor = new QCursor(Qt::DragMoveCursor);
- copyCursor = new QCursor(Qt::DragCopyCursor);
- linkCursor = new QCursor(Qt::DragLinkCursor);
-#endif
- }
-
- QCursor *c;
- if (willDrop) {
- if (global_accepted_action == Qt::CopyAction) {
- c = copyCursor;
- } else if (global_accepted_action == Qt::LinkAction) {
- c = linkCursor;
- } else {
- c = moveCursor;
- }
- if (xdnd_data.deco) {
- xdnd_data.deco->show();
- xdnd_data.deco->raise();
- }
- } else {
- c = noDropCursor;
- //if (qt_xdnd_deco)
- // qt_xdnd_deco->hide();
- }
-#ifndef QT_NO_CURSOR
- if (c)
- qApp->changeOverrideCursor(*c);
-#endif
-}
-
-
-void QDragManager::cancel(bool deleteSource)
-{
- DEBUG("QDragManager::cancel");
- Q_ASSERT(heartbeat != -1);
- killTimer(heartbeat);
- heartbeat = -1;
- beingCancelled = true;
- qt_xdnd_dragging = false;
-
- if (qt_xdnd_current_target)
- qt_xdnd_send_leave();
-
-#ifndef QT_NO_CURSOR
- if (restoreCursor) {
- QApplication::restoreOverrideCursor();
- restoreCursor = false;
- }
-#endif
-
- if (deleteSource && object)
- object->deleteLater();
- object = 0;
- qDeleteInEventHandler(xdnd_data.deco);
- xdnd_data.deco = 0;
-
- global_accepted_action = Qt::IgnoreAction;
-}
-
-static
-Window findRealWindow(const QPoint & pos, Window w, int md)
-{
- if (xdnd_data.deco && w == xdnd_data.deco->effectiveWinId())
- return 0;
-
- if (md) {
- X11->ignoreBadwindow();
- XWindowAttributes attr;
- XGetWindowAttributes(X11->display, w, &attr);
- if (X11->badwindow())
- return 0;
-
- if (attr.map_state == IsViewable
- && QRect(attr.x,attr.y,attr.width,attr.height).contains(pos)) {
- {
- Atom type = XNone;
- int f;
- unsigned long n, a;
- unsigned char *data;
-
- XGetWindowProperty(X11->display, w, ATOM(XdndAware), 0, 0, False,
- AnyPropertyType, &type, &f,&n,&a,&data);
- if (data) XFree(data);
- if (type)
- return w;
- }
-
- Window r, p;
- Window* c;
- uint nc;
- if (XQueryTree(X11->display, w, &r, &p, &c, &nc)) {
- r=0;
- for (uint i=nc; !r && i--;) {
- r = findRealWindow(pos-QPoint(attr.x,attr.y),
- c[i], md-1);
- }
- XFree(c);
- if (r)
- return r;
-
- // We didn't find a client window! Just use the
- // innermost window.
- }
-
- // No children!
- return w;
- }
- }
- return 0;
-}
-
-void QDragManager::move(const QPoint & globalPos)
-{
-#ifdef QT_NO_CURSOR
- Q_UNUSED(globalPos);
- return;
-#else
- DEBUG() << "QDragManager::move enter";
- if (!object) {
- // perhaps the target crashed?
- return;
- }
-
- int screen = QCursor::x11Screen();
- if ((qt_xdnd_current_screen == -1 && screen != X11->defaultScreen) || (screen != qt_xdnd_current_screen)) {
- // recreate the pixmap on the new screen...
- delete xdnd_data.deco;
- QWidget* parent = object->source()->window()->x11Info().screen() == screen
- ? object->source()->window() : QApplication::desktop()->screen(screen);
- xdnd_data.deco = new QShapedPixmapWidget(parent);
- if (!QWidget::mouseGrabber()) {
- updatePixmap();
- xdnd_data.deco->grabMouse();
- }
- }
- xdnd_data.deco->move(QCursor::pos() - xdnd_data.deco->pm_hot);
-
- if (qt_xdnd_source_sameanswer.contains(globalPos) && qt_xdnd_source_sameanswer.isValid())
- return;
-
- qt_xdnd_current_screen = screen;
- Window rootwin = QX11Info::appRootWindow(qt_xdnd_current_screen);
- Window target = 0;
- int lx = 0, ly = 0;
- if (!XTranslateCoordinates(X11->display, rootwin, rootwin, globalPos.x(), globalPos.y(), &lx, &ly, &target))
- // some weird error...
- return;
-
- if (target == rootwin) {
- // Ok.
- } else if (target) {
- //me
- Window src = rootwin;
- while (target != 0) {
- DNDDEBUG << "checking target for XdndAware" << QWidget::find(target) << target;
- int lx2, ly2;
- Window t;
- // translate coordinates
- if (!XTranslateCoordinates(X11->display, src, target, lx, ly, &lx2, &ly2, &t)) {
- target = 0;
- break;
- }
- lx = lx2;
- ly = ly2;
- src = target;
-
- // check if it has XdndAware
- Atom type = 0;
- int f;
- unsigned long n, a;
- unsigned char *data = 0;
- XGetWindowProperty(X11->display, target, ATOM(XdndAware), 0, 0, False,
- AnyPropertyType, &type, &f,&n,&a,&data);
- if (data)
- XFree(data);
- if (type) {
- DNDDEBUG << "Found XdndAware on " << QWidget::find(target) << target;
- break;
- }
-
- // find child at the coordinates
- if (!XTranslateCoordinates(X11->display, src, src, lx, ly, &lx2, &ly2, &target)) {
- target = 0;
- break;
- }
- }
- if (xdnd_data.deco && (!target || target == xdnd_data.deco->effectiveWinId())) {
- DNDDEBUG << "need to find real window";
- target = findRealWindow(globalPos, rootwin, 6);
- DNDDEBUG << "real window found" << QWidget::find(target) << target;
- }
- }
-
- QWidget* w;
- if (target) {
- w = QWidget::find((WId)target);
- if (w && (w->windowType() == Qt::Desktop) && !w->acceptDrops())
- w = 0;
- } else {
- w = 0;
- target = rootwin;
- }
-
- DNDDEBUG << "and the final target is " << QWidget::find(target) << target;
- DNDDEBUG << "the widget w is" << w;
-
- WId proxy_target = xdndProxy(target);
- if (!proxy_target)
- proxy_target = target;
- int target_version = 1;
-
- if (proxy_target) {
- Atom type = XNone;
- int r, f;
- unsigned long n, a;
- unsigned char *retval;
- X11->ignoreBadwindow();
- r = XGetWindowProperty(X11->display, proxy_target, ATOM(XdndAware), 0,
- 1, False, AnyPropertyType, &type, &f,&n,&a,&retval);
- int *tv = (int *)retval;
- if (r != Success || X11->badwindow()) {
- target = 0;
- } else {
- target_version = qMin(xdnd_version,tv ? *tv : 1);
- if (tv)
- XFree(tv);
-// if (!(!X11->badwindow() && type))
-// target = 0;
- }
- }
-
- if (target != qt_xdnd_current_target) {
- if (qt_xdnd_current_target)
- qt_xdnd_send_leave();
-
- qt_xdnd_current_target = target;
- qt_xdnd_current_proxy_target = proxy_target;
- if (target) {
- QVector<Atom> types;
- int flags = target_version << 24;
- QStringList fmts = QInternalMimeData::formatsHelper(dragPrivate()->data);
- for (int i = 0; i < fmts.size(); ++i) {
- QList<Atom> atoms = X11->xdndMimeAtomsForFormat(fmts.at(i));
- for (int j = 0; j < atoms.size(); ++j) {
- if (!types.contains(atoms.at(j)))
- types.append(atoms.at(j));
- }
- }
- if (types.size() > 3) {
- XChangeProperty(X11->display,
- dragPrivate()->source->effectiveWinId(), ATOM(XdndTypelist),
- XA_ATOM, 32, PropModeReplace,
- (unsigned char *)types.data(),
- types.size());
- flags |= 0x0001;
- }
- XClientMessageEvent enter;
- enter.type = ClientMessage;
- enter.window = target;
- enter.format = 32;
- enter.message_type = ATOM(XdndEnter);
- enter.data.l[0] = dragPrivate()->source->effectiveWinId();
- enter.data.l[1] = flags;
- enter.data.l[2] = types.size()>0 ? types.at(0) : 0;
- enter.data.l[3] = types.size()>1 ? types.at(1) : 0;
- enter.data.l[4] = types.size()>2 ? types.at(2) : 0;
- // provisionally set the rectangle to 5x5 pixels...
- qt_xdnd_source_sameanswer = QRect(globalPos.x() - 2,
- globalPos.y() -2 , 5, 5);
-
- DEBUG("sending Xdnd enter");
- if (w)
- X11->xdndHandleEnter(w, (const XEvent *)&enter, false);
- else if (target)
- XSendEvent(X11->display, proxy_target, False, NoEventMask, (XEvent*)&enter);
- waiting_for_status = false;
- }
- }
- if (waiting_for_status)
- return;
-
- if (target) {
- waiting_for_status = true;
-
- XClientMessageEvent move;
- move.type = ClientMessage;
- move.window = target;
- move.format = 32;
- move.message_type = ATOM(XdndPosition);
- move.window = target;
- move.data.l[0] = dragPrivate()->source->effectiveWinId();
- move.data.l[1] = 0; // flags
- move.data.l[2] = (globalPos.x() << 16) + globalPos.y();
- move.data.l[3] = X11->time;
- move.data.l[4] = qtaction_to_xdndaction(defaultAction(dragPrivate()->possible_actions, QApplication::keyboardModifiers()));
- DEBUG("sending Xdnd position");
-
- qt_xdnd_source_current_time = X11->time;
-
- if (w)
- handle_xdnd_position(w, (const XEvent *)&move, false);
- else
- XSendEvent(X11->display, proxy_target, False, NoEventMask,
- (XEvent*)&move);
- } else {
- if (willDrop) {
- willDrop = false;
- updateCursor();
- }
- }
- DEBUG() << "QDragManager::move leave";
-#endif
-}
-
-
-void QDragManager::drop()
-{
- Q_ASSERT(heartbeat != -1);
- killTimer(heartbeat);
- heartbeat = -1;
- qt_xdnd_dragging = false;
-
- if (!qt_xdnd_current_target)
- return;
-
- qDeleteInEventHandler(xdnd_data.deco);
- xdnd_data.deco = 0;
-
- XClientMessageEvent drop;
- drop.type = ClientMessage;
- drop.window = qt_xdnd_current_target;
- drop.format = 32;
- drop.message_type = ATOM(XdndDrop);
- drop.data.l[0] = dragPrivate()->source->effectiveWinId();
- drop.data.l[1] = 0; // flags
- drop.data.l[2] = X11->time;
-
- drop.data.l[3] = 0;
- drop.data.l[4] = 0;
-
- QWidget * w = QWidget::find(qt_xdnd_current_proxy_target);
-
- if (w && (w->windowType() == Qt::Desktop) && !w->acceptDrops())
- w = 0;
-
- QXdndDropTransaction t = {
- X11->time,
- qt_xdnd_current_target,
- qt_xdnd_current_proxy_target,
- w,
- current_embedding_widget,
- object
- };
- X11->dndDropTransactions.append(t);
- restartXdndDropExpiryTimer();
-
- if (w)
- X11->xdndHandleDrop(w, (const XEvent *)&drop, false);
- else
- XSendEvent(X11->display, qt_xdnd_current_proxy_target, False,
- NoEventMask, (XEvent*)&drop);
-
- qt_xdnd_current_target = 0;
- qt_xdnd_current_proxy_target = 0;
- qt_xdnd_source_current_time = 0;
- current_embedding_widget = 0;
- object = 0;
-
-#ifndef QT_NO_CURSOR
- if (restoreCursor) {
- QApplication::restoreOverrideCursor();
- restoreCursor = false;
- }
-#endif
-}
-
-
-
-bool QX11Data::xdndHandleBadwindow()
-{
- if (qt_xdnd_current_target) {
- QDragManager *manager = QDragManager::self();
- if (manager->object) {
- qt_xdnd_current_target = 0;
- qt_xdnd_current_proxy_target = 0;
- manager->object->deleteLater();
- manager->object = 0;
- delete xdnd_data.deco;
- xdnd_data.deco = 0;
- return true;
- }
- }
- if (qt_xdnd_dragsource_xid) {
- qt_xdnd_dragsource_xid = 0;
- if (qt_xdnd_current_widget) {
- QApplication::postEvent(qt_xdnd_current_widget, new QDragLeaveEvent);
- qt_xdnd_current_widget = 0;
- }
- return true;
- }
- return false;
-}
-
-void QX11Data::xdndHandleSelectionRequest(const XSelectionRequestEvent * req)
-{
- if (!req)
- return;
- XEvent evt;
- evt.xselection.type = SelectionNotify;
- evt.xselection.display = req->display;
- evt.xselection.requestor = req->requestor;
- evt.xselection.selection = req->selection;
- evt.xselection.target = XNone;
- evt.xselection.property = XNone;
- evt.xselection.time = req->time;
-
- QDragManager *manager = QDragManager::self();
- QDrag *currentObject = manager->object;
-
- // which transaction do we use? (note: -2 means use current manager->object)
- int at = -1;
-
- // figure out which data the requestor is really interested in
- if (manager->object && req->time == qt_xdnd_source_current_time) {
- // requestor wants the current drag data
- at = -2;
- } else {
- // if someone has requested data in response to XdndDrop, find the corresponding transaction. the
- // spec says to call XConvertSelection() using the timestamp from the XdndDrop
- at = findXdndDropTransactionByTime(req->time);
- if (at == -1) {
- // no dice, perhaps the client was nice enough to use the same window id in XConvertSelection()
- // that we sent the XdndDrop event to.
- at = findXdndDropTransactionByWindow(req->requestor);
- }
- if (at == -1 && req->time == CurrentTime) {
- // previous Qt versions always requested the data on a child of the target window
- // using CurrentTime... but it could be asking for either drop data or the current drag's data
- Window target = findXdndAwareParent(req->requestor);
- if (target) {
- if (qt_xdnd_current_target && qt_xdnd_current_target == target)
- at = -2;
- else
- at = findXdndDropTransactionByWindow(target);
- }
- }
- }
- if (at >= 0) {
- restartXdndDropExpiryTimer();
-
- // use the drag object from an XdndDrop tansaction
- manager->object = X11->dndDropTransactions.at(at).object;
- } else if (at != -2) {
- // no transaction found, we'll have to reject the request
- manager->object = 0;
- }
- if (manager->object) {
- Atom atomFormat = req->target;
- int dataFormat = 0;
- QByteArray data;
- if (X11->xdndMimeDataForAtom(req->target, manager->dragPrivate()->data,
- &data, &atomFormat, &dataFormat)) {
- int dataSize = data.size() / (dataFormat / 8);
- XChangeProperty (X11->display, req->requestor, req->property,
- atomFormat, dataFormat, PropModeReplace,
- (unsigned char *)data.data(), dataSize);
- evt.xselection.property = req->property;
- evt.xselection.target = atomFormat;
- }
- }
-
- // reset manager->object in case we modified it above
- manager->object = currentObject;
-
- // ### this can die if req->requestor crashes at the wrong
- // ### moment
- XSendEvent(X11->display, req->requestor, False, 0, &evt);
-}
-
-static QVariant xdndObtainData(const char *format, QVariant::Type requestedType)
-{
- QByteArray result;
-
- QWidget* w;
- QDragManager *manager = QDragManager::self();
- if (qt_xdnd_dragsource_xid && manager->object &&
- (w=QWidget::find(qt_xdnd_dragsource_xid))
- && (!(w->windowType() == Qt::Desktop) || w->acceptDrops()))
- {
- QDragPrivate * o = QDragManager::self()->dragPrivate();
- if (o->data->hasFormat(QLatin1String(format)))
- result = o->data->data(QLatin1String(format));
- return result;
- }
-
- QList<Atom> atoms;
- int i = 0;
- while ((qt_xdnd_types[i])) {
- atoms.append(qt_xdnd_types[i]);
- ++i;
- }
- QByteArray encoding;
- Atom a = X11->xdndMimeAtomForFormat(QLatin1String(format), requestedType, atoms, &encoding);
- if (!a)
- return result;
-
- if (XGetSelectionOwner(X11->display, ATOM(XdndSelection)) == XNone)
- return result; // should never happen?
-
- QWidget* tw = qt_xdnd_current_widget;
- if (!qt_xdnd_current_widget || (qt_xdnd_current_widget->windowType() == Qt::Desktop))
- tw = new QWidget;
-
- XConvertSelection(X11->display, ATOM(XdndSelection), a, ATOM(XdndSelection), tw->effectiveWinId(),
- qt_xdnd_target_current_time);
- XFlush(X11->display);
-
- XEvent xevent;
- bool got=X11->clipboardWaitForEvent(tw->effectiveWinId(), SelectionNotify, &xevent, 5000);
- if (got) {
- Atom type;
-
- if (X11->clipboardReadProperty(tw->effectiveWinId(), ATOM(XdndSelection), true, &result, 0, &type, 0)) {
- if (type == ATOM(INCR)) {
- int nbytes = result.size() >= 4 ? *((int*)result.data()) : 0;
- result = X11->clipboardReadIncrementalProperty(tw->effectiveWinId(), ATOM(XdndSelection), nbytes, false);
- } else if (type != a && type != XNone) {
- DEBUG("Qt clipboard: unknown atom %ld", type);
- }
- }
- }
- if (!qt_xdnd_current_widget || (qt_xdnd_current_widget->windowType() == Qt::Desktop))
- delete tw;
-
- return X11->xdndMimeConvertToFormat(a, result, QLatin1String(format), requestedType, encoding);
-}
-
-
-/*
- Enable drag and drop for widget w by installing the proper
- properties on w's toplevel widget.
-*/
-bool QX11Data::dndEnable(QWidget* w, bool on)
-{
- w = w->window();
-
- if (bool(((QExtraWidget*)w)->topData()->dnd) == on)
- return true; // been there, done that
- ((QExtraWidget*)w)->topData()->dnd = on ? 1 : 0;
-
- motifdndEnable(w, on);
- return xdndEnable(w, on);
-}
-
-Qt::DropAction QDragManager::drag(QDrag * o)
-{
- if (object == o || !o || !o->d_func()->source)
- return Qt::IgnoreAction;
-
- if (object) {
- cancel();
- qApp->removeEventFilter(this);
- beingCancelled = false;
- }
-
- if (object) {
- // the last drag and drop operation hasn't finished, so we are going to wait
- // for one second to see if it does... if the finish message comes after this,
- // then we could still have problems, but this is highly unlikely
- QApplication::flush();
-
- QElapsedTimer timer;
- timer.start();
- do {
- XEvent event;
- if (XCheckTypedEvent(X11->display, ClientMessage, &event))
- qApp->x11ProcessEvent(&event);
-
- // sleep 50 ms, so we don't use up CPU cycles all the time.
- struct timeval usleep_tv;
- usleep_tv.tv_sec = 0;
- usleep_tv.tv_usec = 50000;
- select(0, 0, 0, 0, &usleep_tv);
- } while (object && timer.hasExpired(1000));
- }
-
- object = o;
- object->d_func()->target = 0;
- xdnd_data.deco = new QShapedPixmapWidget(object->source()->window());
-
- willDrop = false;
-
- updatePixmap();
-
- qApp->installEventFilter(this);
- XSetSelectionOwner(X11->display, ATOM(XdndSelection), dragPrivate()->source->window()->internalWinId(), X11->time);
- global_accepted_action = Qt::CopyAction;
- qt_xdnd_source_sameanswer = QRect();
-#ifndef QT_NO_CURSOR
- // set the override cursor (must be done here, since it is updated
- // in the call to move() below)
- qApp->setOverrideCursor(Qt::ArrowCursor);
- restoreCursor = true;
-#endif
- move(QCursor::pos());
- heartbeat = startTimer(200);
-
- qt_xdnd_dragging = true;
-
- if (!QWidget::mouseGrabber())
- xdnd_data.deco->grabMouse();
-
- eventLoop = new QEventLoop;
- (void) eventLoop->exec();
- delete eventLoop;
- eventLoop = 0;
-
-#ifndef QT_NO_CURSOR
- if (restoreCursor) {
- qApp->restoreOverrideCursor();
- restoreCursor = false;
- }
-#endif
-
- // delete cursors as they may be different next drag.
- delete noDropCursor;
- noDropCursor = 0;
- delete copyCursor;
- copyCursor = 0;
- delete moveCursor;
- moveCursor = 0;
- delete linkCursor;
- linkCursor = 0;
-
- delete xdnd_data.deco;
- xdnd_data.deco = 0;
- if (heartbeat != -1)
- killTimer(heartbeat);
- heartbeat = -1;
- qt_xdnd_current_screen = -1;
- qt_xdnd_dragging = false;
-
- return global_accepted_action;
- // object persists until we get an xdnd_finish message
-}
-
-void QDragManager::updatePixmap()
-{
- if (xdnd_data.deco) {
- QPixmap pm;
- QPoint pm_hot(default_pm_hotx,default_pm_hoty);
- if (object) {
- pm = dragPrivate()->pixmap;
- if (!pm.isNull())
- pm_hot = dragPrivate()->hotspot;
- }
- if (pm.isNull()) {
- if (!defaultPm)
- defaultPm = new QPixmap(default_pm);
- pm = *defaultPm;
- }
- xdnd_data.deco->pm_hot = pm_hot;
- xdnd_data.deco->setPixmap(pm);
- xdnd_data.deco->move(QCursor::pos()-pm_hot);
- xdnd_data.deco->show();
- }
-}
-
-QVariant QDropData::retrieveData_sys(const QString &mimetype, QVariant::Type requestedType) const
-{
- QByteArray mime = mimetype.toLatin1();
- QVariant data = X11->motifdnd_active
- ? X11->motifdndObtainData(mime)
- : xdndObtainData(mime, requestedType);
- return data;
-}
-
-bool QDropData::hasFormat_sys(const QString &format) const
-{
- return formats().contains(format);
-}
-
-QStringList QDropData::formats_sys() const
-{
- QStringList formats;
- if (X11->motifdnd_active) {
- int i = 0;
- QByteArray fmt;
- while (!(fmt = X11->motifdndFormat(i)).isEmpty()) {
- formats.append(QLatin1String(fmt));
- ++i;
- }
- } else {
- int i = 0;
- while ((qt_xdnd_types[i])) {
- QStringList formatsForAtom = X11->xdndMimeFormatsForAtom(qt_xdnd_types[i]);
- for (int j = 0; j < formatsForAtom.size(); ++j) {
- if (!formats.contains(formatsForAtom.at(j)))
- formats.append(formatsForAtom.at(j));
- }
- ++i;
- }
- }
- return formats;
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_DRAGANDDROP
diff --git a/src/gui/kernel/qdrag.cpp b/src/gui/kernel/qdrag.cpp
index fb07ea7315..399c467643 100644
--- a/src/gui/kernel/qdrag.cpp
+++ b/src/gui/kernel/qdrag.cpp
@@ -39,7 +39,6 @@
**
****************************************************************************/
-#include <qwidget.h>
#include <qdrag.h>
#include <qpixmap.h>
#include <qpoint.h>
@@ -66,7 +65,7 @@ QT_BEGIN_NAMESPACE
\snippet doc/src/snippets/dragging/mainwindow.cpp 1
Note that setMimeData() assigns ownership of the QMimeData object to the
- QDrag object. The QDrag must be constructed on the heap with a parent QWidget
+ QDrag object. The QDrag must be constructed on the heap with a parent QObject
to ensure that Qt can clean up after the drag and drop operation has been
completed.
@@ -107,7 +106,7 @@ QT_BEGIN_NAMESPACE
/*!
Constructs a new drag object for the widget specified by \a dragSource.
*/
-QDrag::QDrag(QWidget *dragSource)
+QDrag::QDrag(QObject *dragSource)
: QObject(*new QDragPrivate, dragSource)
{
Q_D(QDrag);
@@ -203,7 +202,7 @@ QPoint QDrag::hotSpot() const
Returns the source of the drag object. This is the widget where the drag
and drop operation originated.
*/
-QWidget *QDrag::source() const
+QObject *QDrag::source() const
{
Q_D(const QDrag);
return d->source;
@@ -213,7 +212,7 @@ QWidget *QDrag::source() const
Returns the target of the drag and drop operation. This is the widget where
the drag object was dropped.
*/
-QWidget *QDrag::target() const
+QObject *QDrag::target() const
{
Q_D(const QDrag);
return d->target;
@@ -346,7 +345,7 @@ void QDrag::setDragCursor(const QPixmap &cursor, Qt::DropAction action)
*/
/*!
- \fn void QDrag::targetChanged(QWidget *newTarget)
+ \fn void QDrag::targetChanged(QObject *newTarget)
This signal is emitted when the target of the drag and drop
operation changes, with \a newTarget the new target.
diff --git a/src/gui/kernel/qdrag.h b/src/gui/kernel/qdrag.h
index d74f5cddf5..b590c4f015 100644
--- a/src/gui/kernel/qdrag.h
+++ b/src/gui/kernel/qdrag.h
@@ -53,7 +53,6 @@ QT_MODULE(Gui)
#ifndef QT_NO_DRAGANDDROP
class QMimeData;
class QDragPrivate;
-class QWidget;
class QPixmap;
class QPoint;
class QDragManager;
@@ -63,7 +62,7 @@ class Q_GUI_EXPORT QDrag : public QObject
Q_OBJECT
Q_DECLARE_PRIVATE(QDrag)
public:
- explicit QDrag(QWidget *dragSource);
+ explicit QDrag(QObject *dragSource);
~QDrag();
void setMimeData(QMimeData *data);
@@ -75,8 +74,8 @@ public:
void setHotSpot(const QPoint &hotspot);
QPoint hotSpot() const;
- QWidget *source() const;
- QWidget *target() const;
+ QObject *source() const;
+ QObject *target() const;
Qt::DropAction start(Qt::DropActions supportedActions = Qt::CopyAction);
Qt::DropAction exec(Qt::DropActions supportedActions = Qt::MoveAction);
@@ -86,12 +85,9 @@ public:
Q_SIGNALS:
void actionChanged(Qt::DropAction action);
- void targetChanged(QWidget *newTarget);
+ void targetChanged(QObject *newTarget);
private:
-#ifdef Q_WS_MAC
- friend class QWidgetPrivate;
-#endif
friend class QDragManager;
Q_DISABLE_COPY(QDrag)
};
diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp
index 5d356292fe..ea19a0548d 100644
--- a/src/gui/kernel/qevent.cpp
+++ b/src/gui/kernel/qevent.cpp
@@ -41,18 +41,13 @@
#include "qevent.h"
#include "qcursor.h"
-#include "qapplication.h"
-#include "private/qapplication_p.h"
+#include "private/qguiapplication_p.h"
#include "private/qevent_p.h"
#include "private/qkeysequence_p.h"
-#include "qwidget.h"
-#include "qgraphicsview.h"
#include "qdebug.h"
#include "qmime.h"
-#include "qdnd_p.h"
+#include "private/qdnd_p.h"
#include "qevent_p.h"
-#include "qgesture.h"
-#include "qgesture_p.h"
#include "qmath.h"
#ifdef Q_OS_SYMBIAN
@@ -73,7 +68,7 @@ QT_BEGIN_NAMESPACE
\internal
*/
QInputEvent::QInputEvent(Type type, Qt::KeyboardModifiers modifiers)
- : QEvent(type), modState(modifiers)
+ : QEvent(type), modState(modifiers), ts(0)
{}
/*!
@@ -154,63 +149,50 @@ QInputEvent::~QInputEvent()
QEvent::MouseButtonRelease, QEvent::MouseButtonDblClick,
or QEvent::MouseMove.
- The \a position is the mouse cursor's position relative to the
- receiving widget.
+ The \a localPos is the mouse cursor's position relative to the
+ receiving widget or item. The window position is set to the same value
+ as \a localPos.
The \a button that caused the event is given as a value from
the Qt::MouseButton enum. If the event \a type is
\l MouseMove, the appropriate button for this event is Qt::NoButton.
The mouse and keyboard states at the time of the event are specified by
\a buttons and \a modifiers.
- The globalPos() is initialized to QCursor::pos(), which may not
+ The screenPos() is initialized to QCursor::pos(), which may not
be appropriate. Use the other constructor to specify the global
position explicitly.
*/
-
-QMouseEvent::QMouseEvent(Type type, const QPointF &position, Qt::MouseButton button,
+QMouseEvent::QMouseEvent(Type type, const QPointF &localPos, Qt::MouseButton button,
Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers)
- : QInputEvent(type, modifiers), p(position), b(button), mouseState(buttons)
+ : QInputEvent(type, modifiers), l(localPos), w(localPos), b(button), mouseState(buttons)
{
- g = QCursor::pos();
+ s = QCursor::pos();
}
-/*!
- \internal
-*/
-QMouseEvent::~QMouseEvent()
-{
-}
-#ifdef QT3_SUPPORT
/*!
- Use QMouseEvent(\a type, \a pos, \a button, \c buttons, \c
- modifiers) instead, where \c buttons is \a state &
- Qt::MouseButtonMask and \c modifiers is \a state &
- Qt::KeyButtonMask.
-*/
-QMouseEvent::QMouseEvent(Type type, const QPoint &pos, Qt::ButtonState button, int state)
- : QInputEvent(type), p(pos), b((Qt::MouseButton)button)
-{
- g = QCursor::pos();
- mouseState = Qt::MouseButtons((state ^ b) & Qt::MouseButtonMask);
- modState = Qt::KeyboardModifiers(state & (int)Qt::KeyButtonMask);
-}
+ Constructs a mouse event object.
-/*!
- Use QMouseEvent(\a type, \a pos, \a globalPos, \a button,
- \c buttons, \c modifiers) instead, where
- \c buttons is \a state & Qt::MouseButtonMask and
- \c modifiers is \a state & Qt::KeyButtonMask.
-*/
-QMouseEvent::QMouseEvent(Type type, const QPoint &pos, const QPoint &globalPos,
- Qt::ButtonState button, int state)
- : QInputEvent(type), p(pos), g(globalPos), b((Qt::MouseButton)button)
-{
- mouseState = Qt::MouseButtons((state ^ b) & Qt::MouseButtonMask);
- modState = Qt::KeyboardModifiers(state & (int)Qt::KeyButtonMask);
-}
-#endif
+ The \a type parameter must be QEvent::MouseButtonPress,
+ QEvent::MouseButtonRelease, QEvent::MouseButtonDblClick,
+ or QEvent::MouseMove.
+ The \a localPos is the mouse cursor's position relative to the
+ receiving widget or item. The cursor's position in screen coordinates is
+ specified by \a screenPos. The window position is set to the same value
+ as \a localPos. The \a button that caused the event is
+ given as a value from the \l Qt::MouseButton enum. If the event \a
+ type is \l MouseMove, the appropriate button for this event is
+ Qt::NoButton. \a buttons is the state of all buttons at the
+ time of the event, \a modifiers the state of all keyboard
+ modifiers.
+
+*/
+QMouseEvent::QMouseEvent(Type type, const QPointF &localPos, const QPointF &screenPos,
+ Qt::MouseButton button, Qt::MouseButtons buttons,
+ Qt::KeyboardModifiers modifiers)
+ : QInputEvent(type, modifiers), l(localPos), w(localPos), s(screenPos), b(button), mouseState(buttons)
+{}
/*!
Constructs a mouse event object.
@@ -229,30 +211,59 @@ QMouseEvent::QMouseEvent(Type type, const QPoint &pos, const QPoint &globalPos,
modifiers.
*/
-QMouseEvent::QMouseEvent(Type type, const QPointF &pos, const QPointF &globalPos,
+QMouseEvent::QMouseEvent(Type type, const QPointF &localPos, const QPointF &windowPos, const QPointF &screenPos,
Qt::MouseButton button, Qt::MouseButtons buttons,
Qt::KeyboardModifiers modifiers)
- : QInputEvent(type, modifiers), p(pos), g(globalPos), b(button), mouseState(buttons)
+ : QInputEvent(type, modifiers), l(localPos), w(windowPos), s(screenPos), b(button), mouseState(buttons)
{}
/*!
- \fn bool QMouseEvent::hasExtendedInfo() const
\internal
*/
+QMouseEvent::~QMouseEvent()
+{
+}
+
/*!
- \fn QPointF QMouseEvent::posF() const
+ \fn QPointF QMouseEvent::localPos() const
- \since 4.4
+ \since 5.0
Returns the position of the mouse cursor as a QPointF, relative to the
- widget that received the event.
+ widget or item that received the event.
+
+ If you move the widget as a result of the mouse event, use the
+ screen position returned by screenPos() to avoid a shaking
+ motion.
+
+ \sa x() y() windowPos() screenPos()
+*/
+
+/*!
+ \fn QPointF QMouseEvent::windowPos() const
+
+ \since 5.0
+
+ Returns the position of the mouse cursor as a QPointF, relative to the
+ window that received the event.
If you move the widget as a result of the mouse event, use the
global position returned by globalPos() to avoid a shaking
motion.
- \sa x() y() pos() globalPos()
+ \sa x() y() pos() localPos() screenPos()
+*/
+
+/*!
+ \fn QPointF QMouseEvent::screenPos() const
+
+ \since 5.0
+
+ Returns the position of the mouse cursor as a QPointF, relative to the
+ screen that received the event.
+
+ \sa x() y() pos() localPos() screenPos()
*/
/*!
@@ -528,19 +539,6 @@ QWheelEvent::~QWheelEvent()
{
}
-#ifdef QT3_SUPPORT
-/*!
- Use one of the other constructors instead.
-*/
-QWheelEvent::QWheelEvent(const QPoint &pos, int delta, int state, Qt::Orientation orient)
- : QInputEvent(Wheel), p(pos), d(delta), o(orient)
-{
- g = QCursor::pos();
- mouseState = Qt::MouseButtons(state & Qt::MouseButtonMask);
- modState = Qt::KeyboardModifiers(state & (int)Qt::KeyButtonMask);
-}
-#endif
-
/*!
Constructs a wheel event object.
@@ -558,18 +556,6 @@ QWheelEvent::QWheelEvent(const QPointF &pos, const QPointF& globalPos, int delta
: QInputEvent(Wheel, modifiers), p(pos), g(globalPos), d(delta), mouseState(buttons), o(orient)
{}
-#ifdef QT3_SUPPORT
-/*!
- Use one of the other constructors instead.
-*/
-QWheelEvent::QWheelEvent(const QPoint &pos, const QPoint& globalPos, int delta, int state,
- Qt::Orientation orient)
- : QInputEvent(Wheel), p(pos), g(globalPos), d(delta), o(orient)
-{
- mouseState = Qt::MouseButtons(state & Qt::MouseButtonMask);
- modState = Qt::KeyboardModifiers(state & (int) Qt::KeyButtonMask);
-}
-#endif
#endif // QT_NO_WHEELEVENT
/*!
@@ -884,7 +870,7 @@ Qt::KeyboardModifiers QKeyEvent::modifiers() const
bool QKeyEvent::matches(QKeySequence::StandardKey matchKey) const
{
uint searchkey = (modifiers() | key()) & ~(Qt::KeypadModifier); //The keypad modifier should not make a difference
- uint platform = QApplicationPrivate::currentPlatform();
+ uint platform = QGuiApplicationPrivate::currentKeyPlatform();
#ifdef Q_WS_MAC
if (qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)) {
@@ -963,34 +949,6 @@ bool QKeyEvent::matches(QKeySequence::StandardKey matchKey) const
\sa Qt::WA_KeyCompression
*/
-#ifdef QT3_SUPPORT
-/*!
- \fn QKeyEvent::QKeyEvent(Type type, int key, int ascii,
- int modifiers, const QString &text,
- bool autorep, ushort count)
-
- Use one of the other constructors instead.
-*/
-
-/*!
- \fn int QKeyEvent::ascii() const
-
- Use text() instead.
-*/
-
-/*!
- \fn Qt::ButtonState QKeyEvent::state() const
-
- Use QInputEvent::modifiers() instead.
-*/
-
-/*!
- \fn Qt::ButtonState QKeyEvent::stateAfter() const
-
- Use modifiers() instead.
-*/
-#endif
-
/*!
\class QFocusEvent
\brief The QFocusEvent class contains event parameters for widget focus
@@ -1061,23 +1019,6 @@ Qt::FocusReason QFocusEvent::reason() const
false.
*/
-#ifdef QT3_SUPPORT
-/*!
- \enum QFocusEvent::Reason
- \compat
-
- Use Qt::FocusReason instead.
-
- \value Mouse Same as Qt::MouseFocusReason.
- \value Tab Same as Qt::TabFocusReason.
- \value Backtab Same as Qt::BacktabFocusReason.
- \value MenuBar Same as Qt::MenuBarFocusReason.
- \value ActiveWindow Same as Qt::ActiveWindowFocusReason
- \value Other Same as Qt::OtherFocusReason
- \value Popup Same as Qt::PopupFocusReason
- \value Shortcut Same as Qt::ShortcutFocusReason
-*/
-#endif
/*!
\class QPaintEvent
@@ -1146,18 +1087,6 @@ QPaintEvent::QPaintEvent(const QRect &paintRect)
{}
-#ifdef QT3_SUPPORT
- /*!
- Constructs a paint event object with both a \a paintRegion and a
- \a paintRect, both of which represent the area of the widget that
- needs to be updated.
-
-*/
-QPaintEvent::QPaintEvent(const QRegion &paintRegion, const QRect &paintRect)
- : QEvent(Paint), m_rect(paintRect), m_region(paintRegion), m_erased(false)
-{}
-#endif
-
/*!
\internal
*/
@@ -1233,6 +1162,29 @@ QMoveEvent::~QMoveEvent()
Returns the old position of the widget.
*/
+/*!
+ \class QExposeEvent
+ \brief The QExposeEvent class contains event parameters for expose events.
+
+ \ingroup events
+
+ Expose events are sent to widgets when an area of the widget is invalidated
+ and needs to be flushed from the backing store.
+
+ The event handler QWindow::exposeEvent() receives expose events.
+*/
+QExposeEvent::QExposeEvent(const QRegion &exposeRegion)
+ : QEvent(Expose)
+ , rgn(exposeRegion)
+{
+}
+
+/*!
+ \internal
+*/
+QExposeEvent::~QExposeEvent()
+{
+}
/*!
\class QResizeEvent
@@ -1424,17 +1376,6 @@ QContextMenuEvent::QContextMenuEvent(Reason reason, const QPoint &pos, const QPo
: QInputEvent(ContextMenu, modifiers), p(pos), gp(globalPos), reas(reason)
{}
-#ifdef QT3_SUPPORT
-/*!
- Constructs a context menu event with the given \a reason for the
- position specified by \a pos in widget coordinates and \a globalPos
- in global screen coordinates. \a dummy is ignored.
-*/
-QContextMenuEvent::QContextMenuEvent(Reason reason, const QPoint &pos, const QPoint &globalPos,
- int /* dummy */)
- : QInputEvent(ContextMenu), p(pos), gp(globalPos), reas(reason)
-{}
-#endif
/*! \internal */
QContextMenuEvent::~QContextMenuEvent()
@@ -1460,24 +1401,6 @@ QContextMenuEvent::QContextMenuEvent(Reason reason, const QPoint &pos)
gp = QCursor::pos();
}
-#ifdef QT3_SUPPORT
-/*!
- Constructs a context menu event with the given \a reason for the
- position specified by \a pos in widget coordinates. \a dummy is
- ignored.
-*/
-QContextMenuEvent::QContextMenuEvent(Reason reason, const QPoint &pos, int /* dummy */)
- : QInputEvent(ContextMenu), p(pos), reas(reason)
-{
- gp = QCursor::pos();
-}
-
-Qt::ButtonState QContextMenuEvent::state() const
-{
- return Qt::ButtonState(int(QApplication::keyboardModifiers())|QApplication::mouseButtons());
-}
-#endif
-
/*!
\fn const QPoint &QContextMenuEvent::pos() const
@@ -1849,6 +1772,74 @@ void QInputMethodEvent::setCommitString(const QString &commitString, int replace
\sa replacementStart(), setCommitString()
*/
+
+/*! \class QInputMethodQueryEvent
+
+ This event is sent by the input context to input objects.
+
+ It is used by the
+ input method to query a set of properties of the object to be
+ able to support complex input method operations as support for
+ surrounding text and reconversions.
+
+ query() specifies which property is queried.
+
+ The object should call setValue() on the event to fill in the requested
+ data before calling accept().
+*/
+QInputMethodQueryEvent::QInputMethodQueryEvent(Qt::InputMethodQueries queries)
+ : QEvent(InputMethodQuery),
+ m_queries(queries)
+{
+}
+
+QInputMethodQueryEvent::~QInputMethodQueryEvent()
+{
+}
+
+
+void QInputMethodQueryEvent::setValue(Qt::InputMethodQuery q, const QVariant &v)
+{
+ for (int i = 0; i < m_values.size(); ++i) {
+ if (m_values.at(i).query == q) {
+ m_values[i].value = v;
+ return;
+ }
+ }
+ QueryPair pair = { q, v };
+ m_values.append(pair);
+}
+
+QVariant QInputMethodQueryEvent::value(Qt::InputMethodQuery q) const
+{
+ for (int i = 0; i < m_values.size(); ++i)
+ if (m_values.at(i).query == q)
+ return m_values.at(i).value;
+ return QVariant();
+}
+
+/*!
+ \fn Qt::InputMethodQuery QInputMethodQueryEvent::query() const
+
+ returns the type of data queried.
+*/
+
+/*!
+ \fn QVariant QInputMethodQueryEvent::value() const
+
+ returns the value set by the receiving object. Mainly used by the input method.
+
+ \sa setValue()
+*/
+
+/*!
+ \fn QVariant QInputMethodQueryEvent::setValue()
+
+ Used by the receiving object to set the value requested by query().
+
+ \sa setValue()
+*/
+
#ifndef QT_NO_TABLETEVENT
/*!
@@ -2303,7 +2294,7 @@ QDropEvent::QDropEvent(const QPoint& pos, Qt::DropActions actions, const QMimeDa
modState(modifiers), act(actions),
mdata(data)
{
- default_action = QDragManager::self()->defaultAction(act, modifiers);
+ default_action = Qt::CopyAction; // ### Qt5: QDragManager::self()->defaultAction(act, modifiers);
drop_action = default_action;
ignore();
}
@@ -2382,10 +2373,10 @@ bool QDropEvent::provides(const char *mimeType) const
\sa QDrag::QDrag()
*/
-QWidget* QDropEvent::source() const
+QObject* QDropEvent::source() const
{
QDragManager *manager = QDragManager::self();
- return manager ? manager->source() : 0;
+ return (manager && manager->object) ? manager->object->source() : 0;
}
@@ -2509,37 +2500,6 @@ void QDropEvent::setDropAction(Qt::DropAction action)
\sa setDropAction(), proposedAction(), {QEvent::accept()}{accept()}
*/
-#ifdef QT3_SUPPORT
-/*!
- Use dropAction() instead.
-
- The table below shows the correspondance between the return type
- of action() and the return type of dropAction().
-
- \table
- \header \i Old enum value \i New enum value
- \row \i QDropEvent::Copy \i Qt::CopyAction
- \row \i QDropEvent::Move \i Qt::MoveAction
- \row \i QDropEvent::Link \i Qt::LinkAction
- \row \i other \i Qt::CopyAction
- \endtable
-*/
-
-QT3_SUPPORT QDropEvent::Action QDropEvent::action() const
-{
- switch(drop_action) {
- case Qt::CopyAction:
- return Copy;
- case Qt::MoveAction:
- return Move;
- case Qt::LinkAction:
- return Link;
- default:
- return Copy;
- }
-}
-#endif
-
/*!
\fn void QDropEvent::setPoint(const QPoint &point)
\compat
@@ -2594,21 +2554,6 @@ QDragEnterEvent::~QDragEnterEvent()
}
/*!
- Constructs a drag response event containing the \a accepted value,
- indicating whether the drag and drop operation was accepted by the
- recipient.
-*/
-QDragResponseEvent::QDragResponseEvent(bool accepted)
- : QEvent(DragResponse), a(accepted)
-{}
-
-/*! \internal
-*/
-QDragResponseEvent::~QDragResponseEvent()
-{
-}
-
-/*!
\class QDragMoveEvent
\brief The QDragMoveEvent class provides an event which is sent while a drag and drop action is in progress.
@@ -3442,12 +3387,6 @@ QDebug operator<<(QDebug dbg, const QEvent *e) {
case QEvent::UngrabKeyboard:
n = "UngrabKeyboard";
break;
-#ifdef QT3_SUPPORT
- case QEvent::ChildInsertedRequest:
- n = "ChildInsertedRequest";
- break;
- case QEvent::ChildInserted: n = "ChildInserted";
-#endif
case QEvent::ChildAdded: n = n ? n : "ChildAdded";
case QEvent::ChildPolished: n = n ? n : "ChildPolished";
case QEvent::ChildRemoved: n = n ? n : "ChildRemoved";
@@ -3599,60 +3538,6 @@ QWindowStateChangeEvent::~QWindowStateChangeEvent()
{
}
-#ifdef QT3_SUPPORT
-
-/*!
- \class QMenubarUpdatedEvent
- \internal
- Event sent by QMenuBar to tell Q3Workspace to update itself.
-*/
-
-/*! \internal
-
-*/
-QMenubarUpdatedEvent::QMenubarUpdatedEvent(QMenuBar * const menuBar)
-:QEvent(QEvent::MenubarUpdated), m_menuBar(menuBar) {}
-
-/*!
- \fn QMenuBar *QMenubarUpdatedEvent::menuBar()
- \internal
-*/
-
-/*!
- \fn bool operator==(QKeyEvent *e, QKeySequence::StandardKey key)
-
- \relates QKeyEvent
-
- Returns true if \a key is currently bound to the key combination
- specified by \a e.
-
- Equivalent to \c {e->matches(key)}.
-*/
-
-/*!
- \fn bool operator==(QKeySequence::StandardKey key, QKeyEvent *e)
-
- \relates QKeyEvent
-
- Returns true if \a key is currently bound to the key combination
- specified by \a e.
-
- Equivalent to \c {e->matches(key)}.
-*/
-
-/*!
- \internal
-
- \class QKeyEventEx
- \ingroup events
-
- \brief The QKeyEventEx class provides more extended information about a keyevent.
-
- This class is for internal use only, and exists to aid the shortcut system on
- various platforms to get all the information it needs.
-*/
-
-#endif
/*!
\class QTouchEvent
@@ -4288,317 +4173,6 @@ QTouchEvent::TouchPoint &QTouchEvent::TouchPoint::operator=(const QTouchEvent::T
return *this;
}
-#ifndef QT_NO_GESTURES
-/*!
- \class QGestureEvent
- \since 4.6
- \ingroup events
- \ingroup gestures
-
- \brief The QGestureEvent class provides the description of triggered gestures.
-
- The QGestureEvent class contains a list of gestures, which can be obtained using the
- gestures() function.
-
- The gestures are either active or canceled. A list of those that are currently being
- executed can be obtained using the activeGestures() function. A list of those which
- were previously active and have been canceled can be accessed using the
- canceledGestures() function. A gesture might be canceled if the current window loses
- focus, for example, or because of a timeout, or for other reasons.
-
- If the event handler does not accept the event by calling the generic
- QEvent::accept() function, all individual QGesture object that were not
- accepted and in the Qt::GestureStarted state will be propagated up the
- parent widget chain until a widget accepts them individually, by calling
- QGestureEvent::accept() for each of them, or an event filter consumes the
- event.
-
- \section1 Further Reading
-
- For an overview of gesture handling in Qt and information on using gestures
- in your applications, see the \l{Gestures Programming} document.
-
- \sa QGesture, QGestureRecognizer,
- QWidget::grabGesture(), QGraphicsObject::grabGesture()
-*/
-
-/*!
- Creates new QGestureEvent containing a list of \a gestures.
-*/
-QGestureEvent::QGestureEvent(const QList<QGesture *> &gestures)
- : QEvent(QEvent::Gesture)
-{
- d = reinterpret_cast<QEventPrivate *>(new QGestureEventPrivate(gestures));
-}
-
-/*!
- Destroys QGestureEvent.
-*/
-QGestureEvent::~QGestureEvent()
-{
- delete reinterpret_cast<QGestureEventPrivate *>(d);
-}
-
-/*!
- Returns all gestures that are delivered in the event.
-*/
-QList<QGesture *> QGestureEvent::gestures() const
-{
- return d_func()->gestures;
-}
-
-/*!
- Returns a gesture object by \a type.
-*/
-QGesture *QGestureEvent::gesture(Qt::GestureType type) const
-{
- const QGestureEventPrivate *d = d_func();
- for(int i = 0; i < d->gestures.size(); ++i)
- if (d->gestures.at(i)->gestureType() == type)
- return d->gestures.at(i);
- return 0;
-}
-
-/*!
- Returns a list of active (not canceled) gestures.
-*/
-QList<QGesture *> QGestureEvent::activeGestures() const
-{
- QList<QGesture *> gestures;
- foreach (QGesture *gesture, d_func()->gestures) {
- if (gesture->state() != Qt::GestureCanceled)
- gestures.append(gesture);
- }
- return gestures;
-}
-
-/*!
- Returns a list of canceled gestures.
-*/
-QList<QGesture *> QGestureEvent::canceledGestures() const
-{
- QList<QGesture *> gestures;
- foreach (QGesture *gesture, d_func()->gestures) {
- if (gesture->state() == Qt::GestureCanceled)
- gestures.append(gesture);
- }
- return gestures;
-}
-
-/*!
- Sets the accept flag of the given \a gesture object to the specified \a value.
-
- Setting the accept flag indicates that the event receiver wants the \a gesture.
- Unwanted gestures may be propagated to the parent widget.
-
- By default, gestures in events of type QEvent::Gesture are accepted, and
- gestures in QEvent::GestureOverride events are ignored.
-
- For convenience, the accept flag can also be set with
- \l{QGestureEvent::accept()}{accept(gesture)}, and cleared with
- \l{QGestureEvent::ignore()}{ignore(gesture)}.
-*/
-void QGestureEvent::setAccepted(QGesture *gesture, bool value)
-{
- if (gesture)
- setAccepted(gesture->gestureType(), value);
-}
-
-/*!
- Sets the accept flag of the given \a gesture object, the equivalent of calling
- \l{QGestureEvent::setAccepted()}{setAccepted(gesture, true)}.
-
- Setting the accept flag indicates that the event receiver wants the
- gesture. Unwanted gestures may be propagated to the parent widget.
-
- \sa QGestureEvent::ignore()
-*/
-void QGestureEvent::accept(QGesture *gesture)
-{
- if (gesture)
- setAccepted(gesture->gestureType(), true);
-}
-
-/*!
- Clears the accept flag parameter of the given \a gesture object, the equivalent
- of calling \l{QGestureEvent::setAccepted()}{setAccepted(gesture, false)}.
-
- Clearing the accept flag indicates that the event receiver does not
- want the gesture. Unwanted gestures may be propagated to the parent widget.
-
- \sa QGestureEvent::accept()
-*/
-void QGestureEvent::ignore(QGesture *gesture)
-{
- if (gesture)
- setAccepted(gesture->gestureType(), false);
-}
-
-/*!
- Returns true if the \a gesture is accepted; otherwise returns false.
-*/
-bool QGestureEvent::isAccepted(QGesture *gesture) const
-{
- return gesture ? isAccepted(gesture->gestureType()) : false;
-}
-
-/*!
- Sets the accept flag of the given \a gestureType object to the specified
- \a value.
-
- Setting the accept flag indicates that the event receiver wants to receive
- gestures of the specified type, \a gestureType. Unwanted gestures may be
- propagated to the parent widget.
-
- By default, gestures in events of type QEvent::Gesture are accepted, and
- gestures in QEvent::GestureOverride events are ignored.
-
- For convenience, the accept flag can also be set with
- \l{QGestureEvent::accept()}{accept(gestureType)}, and cleared with
- \l{QGestureEvent::ignore()}{ignore(gestureType)}.
-*/
-void QGestureEvent::setAccepted(Qt::GestureType gestureType, bool value)
-{
- setAccepted(false);
- d_func()->accepted[gestureType] = value;
-}
-
-/*!
- Sets the accept flag of the given \a gestureType, the equivalent of calling
- \l{QGestureEvent::setAccepted()}{setAccepted(gestureType, true)}.
-
- Setting the accept flag indicates that the event receiver wants the
- gesture. Unwanted gestures may be propagated to the parent widget.
-
- \sa QGestureEvent::ignore()
-*/
-void QGestureEvent::accept(Qt::GestureType gestureType)
-{
- setAccepted(gestureType, true);
-}
-
-/*!
- Clears the accept flag parameter of the given \a gestureType, the equivalent
- of calling \l{QGestureEvent::setAccepted()}{setAccepted(gesture, false)}.
-
- Clearing the accept flag indicates that the event receiver does not
- want the gesture. Unwanted gestures may be propgated to the parent widget.
-
- \sa QGestureEvent::accept()
-*/
-void QGestureEvent::ignore(Qt::GestureType gestureType)
-{
- setAccepted(gestureType, false);
-}
-
-/*!
- Returns true if the gesture of type \a gestureType is accepted; otherwise
- returns false.
-*/
-bool QGestureEvent::isAccepted(Qt::GestureType gestureType) const
-{
- return d_func()->accepted.value(gestureType, true);
-}
-
-/*!
- \internal
-
- Sets the widget for this event to the \a widget specified.
-*/
-void QGestureEvent::setWidget(QWidget *widget)
-{
- d_func()->widget = widget;
-}
-
-/*!
- Returns the widget on which the event occurred.
-*/
-QWidget *QGestureEvent::widget() const
-{
- return d_func()->widget;
-}
-
-#ifndef QT_NO_GRAPHICSVIEW
-/*!
- Returns the scene-local coordinates if the \a gesturePoint is inside a
- graphics view.
-
- This functional might be useful when the gesture event is delivered to a
- QGraphicsObject to translate a point in screen coordinates to scene-local
- coordinates.
-
- \sa QPointF::isNull().
-*/
-QPointF QGestureEvent::mapToGraphicsScene(const QPointF &gesturePoint) const
-{
- QWidget *w = widget();
- if (w) // we get the viewport as widget, not the graphics view
- w = w->parentWidget();
- QGraphicsView *view = qobject_cast<QGraphicsView*>(w);
- if (view) {
- return view->mapToScene(view->mapFromGlobal(gesturePoint.toPoint()));
- }
- return QPointF();
-}
-#endif //QT_NO_GRAPHICSVIEW
-
-/*!
- \internal
-*/
-QGestureEventPrivate *QGestureEvent::d_func()
-{
- return reinterpret_cast<QGestureEventPrivate *>(d);
-}
-
-/*!
- \internal
-*/
-const QGestureEventPrivate *QGestureEvent::d_func() const
-{
- return reinterpret_cast<const QGestureEventPrivate *>(d);
-}
-
-#ifdef Q_NO_USING_KEYWORD
-/*!
- \fn void QGestureEvent::setAccepted(bool accepted)
-
- Sets or clears the event's internal flag that determines whether it should
- be delivered to other objects.
-
- Calling this function with a value of true for \a accepted indicates that the
- caller has accepted the event and that it should not be propagated further.
- Calling this function with a value of false indicates that the caller has
- ignored the event and that it should be delivered to other objects.
-
- For convenience, the accept flag can also be set with accept(), and cleared
- with ignore().
-
- \sa QEvent::accepted
-*/
-/*!
- \fn bool QGestureEvent::isAccepted() const
-
- Returns true is the event has been accepted; otherwise returns false.
-
- \sa QEvent::accepted
-*/
-/*!
- \fn void QGestureEvent::accept()
-
- Accepts the event, the equivalent of calling setAccepted(true).
-
- \sa QEvent::accept()
-*/
-/*!
- \fn void QGestureEvent::ignore()
-
- Ignores the event, the equivalent of calling setAccepted(false).
-
- \sa QEvent::ignore()
-*/
-#endif
-
-#endif // QT_NO_GESTURES
/*!
\class QScrollPrepareEvent
diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h
index a6196346a7..faa80d5c7d 100644
--- a/src/gui/kernel/qevent.h
+++ b/src/gui/kernel/qevent.h
@@ -50,9 +50,9 @@
#include <QtGui/qkeysequence.h>
#include <QtCore/qcoreevent.h>
#include <QtGui/qmime.h>
-#include <QtGui/qdrag.h>
#include <QtCore/qvariant.h>
#include <QtCore/qmap.h>
+#include <QtCore/qvector.h>
#include <QtCore/qset.h>
#include <QtCore/qfile.h>
@@ -78,8 +78,11 @@ public:
~QInputEvent();
inline Qt::KeyboardModifiers modifiers() const { return modState; }
inline void setModifiers(Qt::KeyboardModifiers amodifiers) { modState = amodifiers; }
+ inline ulong timestamp() const { return ts; }
+ inline void setTimestamp(ulong atimestamp) { ts = atimestamp; }
protected:
Qt::KeyboardModifiers modState;
+ ulong ts;
};
class Q_GUI_EXPORT QMouseEvent : public QInputEvent
@@ -90,31 +93,32 @@ public:
QMouseEvent(Type type, const QPointF &pos, const QPointF &globalPos,
Qt::MouseButton button, Qt::MouseButtons buttons,
Qt::KeyboardModifiers modifiers);
+ QMouseEvent(Type type, const QPointF &pos, const QPointF &windowPos, const QPointF &globalPos,
+ Qt::MouseButton button, Qt::MouseButtons buttons,
+ Qt::KeyboardModifiers modifiers);
~QMouseEvent();
- inline QPoint pos() const { return p.toPoint(); }
- inline QPoint globalPos() const { return g.toPoint(); }
- inline int x() const { return qRound(p.x()); }
- inline int y() const { return qRound(p.y()); }
- inline int globalX() const { return qRound(g.x()); }
- inline int globalY() const { return qRound(g.y()); }
+#ifndef QT_NO_INTEGER_EVENT_COORDINATES
+ inline QPoint pos() const { return l.toPoint(); }
+ inline QPoint globalPos() const { return s.toPoint(); }
+ inline int x() const { return qRound(l.x()); }
+ inline int y() const { return qRound(l.y()); }
+ inline int globalX() const { return qRound(s.x()); }
+ inline int globalY() const { return qRound(s.y()); }
+#endif
+ const QPointF &localPos() const { return l; }
+ const QPointF &windowPos() const { return w; }
+ const QPointF &screenPos() const { return s; }
+
inline Qt::MouseButton button() const { return b; }
inline Qt::MouseButtons buttons() const { return mouseState; }
- const QPointF &posF() const { return p; }
- const QPointF &globalPosF() const { return g; }
-
-#ifdef QT3_SUPPORT
- QT3_SUPPORT_CONSTRUCTOR QMouseEvent(Type type, const QPoint &pos, Qt::ButtonState button, int state);
- QT3_SUPPORT_CONSTRUCTOR QMouseEvent(Type type, const QPoint &pos, const QPoint &globalPos,
- Qt::ButtonState button, int state);
- inline QT3_SUPPORT Qt::ButtonState state() const
- { return Qt::ButtonState((mouseState^b)|int(modifiers())); }
- inline QT3_SUPPORT Qt::ButtonState stateAfter() const
- { return Qt::ButtonState(int(mouseState)|int(modifiers())); }
+#if QT_DEPRECATED_SINCE(5, 0)
+ Q_DEPRECATED inline QPointF posF() const { return l; }
#endif
+
protected:
- QPointF p, g;
+ QPointF l, w, s;
Qt::MouseButton b;
Qt::MouseButtons mouseState;
};
@@ -125,8 +129,10 @@ public:
QHoverEvent(Type type, const QPointF &pos, const QPointF &oldPos, Qt::KeyboardModifiers modifiers = Qt::NoModifier);
~QHoverEvent();
+#ifndef QT_NO_INTEGER_EVENT_COORDINATES
inline QPoint pos() const { return p.toPoint(); }
inline QPoint oldPos() const { return op.toPoint(); }
+#endif
inline const QPointF &posF() const { return p; }
inline const QPointF &oldPosF() const { return op; }
@@ -148,27 +154,21 @@ public:
~QWheelEvent();
inline int delta() const { return d; }
+#ifndef QT_NO_INTEGER_EVENT_COORDINATES
inline QPoint pos() const { return p.toPoint(); }
inline QPoint globalPos() const { return g.toPoint(); }
inline int x() const { return p.x(); }
inline int y() const { return p.y(); }
inline int globalX() const { return g.x(); }
inline int globalY() const { return g.y(); }
+#endif
+ inline const QPointF &posF() const { return p; }
+ inline const QPointF &globalPosF() const { return g; }
inline Qt::MouseButtons buttons() const { return mouseState; }
Qt::Orientation orientation() const { return o; }
- inline const QPointF &posF() const { return p; }
- inline const QPointF &globalPosF() const { return g; }
-#ifdef QT3_SUPPORT
- QT3_SUPPORT_CONSTRUCTOR QWheelEvent(const QPoint &pos, int delta, int state,
- Qt::Orientation orient = Qt::Vertical);
- QT3_SUPPORT_CONSTRUCTOR QWheelEvent(const QPoint &pos, const QPoint& globalPos, int delta, int state,
- Qt::Orientation orient = Qt::Vertical);
- inline QT3_SUPPORT Qt::ButtonState state() const
- { return static_cast<Qt::ButtonState>(int(buttons())|int(modifiers())); }
-#endif
protected:
QPointF p;
QPointF g;
@@ -251,22 +251,6 @@ public:
quint32 nativeVirtualKey() const;
quint32 nativeModifiers() const;
-#ifdef QT3_SUPPORT
- inline QT3_SUPPORT_CONSTRUCTOR QKeyEvent(Type type, int key, int /*ascii*/,
- int modifiers, const QString& text = QString(),
- bool autorep = false, ushort count = 1)
- : QInputEvent(type, Qt::KeyboardModifiers(modifiers & (int)Qt::KeyButtonMask)), txt(text), k(key),
- c(count), autor(autorep)
- {
- if (key >= Qt::Key_Back && key <= Qt::Key_MediaLast)
- ignore();
- }
- inline QT3_SUPPORT int ascii() const
- { return (txt.length() ? txt.unicode()->toLatin1() : 0); }
- inline QT3_SUPPORT Qt::ButtonState state() const { return Qt::ButtonState(QInputEvent::modifiers()); }
- inline QT3_SUPPORT Qt::ButtonState stateAfter() const { return Qt::ButtonState(modifiers()); }
-#endif
-
protected:
QString txt;
int k;
@@ -284,12 +268,6 @@ public:
inline bool gotFocus() const { return type() == FocusIn; }
inline bool lostFocus() const { return type() == FocusOut; }
-#ifdef QT3_SUPPORT
- enum Reason { Mouse=Qt::MouseFocusReason, Tab=Qt::TabFocusReason,
- Backtab=Qt::BacktabFocusReason, MenuBar=Qt::MenuBarFocusReason,
- ActiveWindow=Qt::ActiveWindowFocusReason, Other=Qt::OtherFocusReason,
- Popup=Qt::PopupFocusReason, Shortcut=Qt::ShortcutFocusReason };
-#endif
Qt::FocusReason reason();
Qt::FocusReason reason() const;
@@ -308,12 +286,6 @@ public:
inline const QRect &rect() const { return m_rect; }
inline const QRegion &region() const { return m_region; }
-#ifdef QT3_SUPPORT
- QT3_SUPPORT_CONSTRUCTOR QPaintEvent(const QRegion &paintRegion, const QRect &paintRect);
- inline QT3_SUPPORT bool erased() const { return m_erased; }
- inline QT3_SUPPORT void setErased(bool b) { m_erased = b; }
-#endif
-
protected:
friend class QApplication;
friend class QCoreApplication;
@@ -322,7 +294,8 @@ protected:
bool m_erased;
};
-class QUpdateLaterEvent : public QEvent
+// ### Qt5: make internal
+class Q_GUI_EXPORT QUpdateLaterEvent : public QEvent
{
public:
QUpdateLaterEvent(const QRegion& paintRegion);
@@ -348,6 +321,17 @@ protected:
friend class QCoreApplication;
};
+class Q_GUI_EXPORT QExposeEvent : public QEvent
+{
+public:
+ QExposeEvent(const QRegion &rgn);
+ ~QExposeEvent();
+
+ inline const QRegion &region() const { return rgn; }
+
+protected:
+ QRegion rgn;
+};
class Q_GUI_EXPORT QResizeEvent : public QEvent
{
@@ -417,12 +401,6 @@ public:
inline Reason reason() const { return Reason(reas); }
-#ifdef QT3_SUPPORT
- QT3_SUPPORT_CONSTRUCTOR QContextMenuEvent(Reason reason, const QPoint &pos, const QPoint &globalPos, int);
- QT3_SUPPORT_CONSTRUCTOR QContextMenuEvent(Reason reason, const QPoint &pos, int);
-
- QT3_SUPPORT Qt::ButtonState state() const;
-#endif
protected:
QPoint p;
QPoint gp;
@@ -470,6 +448,26 @@ private:
int replace_from;
int replace_length;
};
+
+class Q_GUI_EXPORT QInputMethodQueryEvent : public QEvent
+{
+public:
+ QInputMethodQueryEvent(Qt::InputMethodQueries queries);
+ ~QInputMethodQueryEvent();
+
+ Qt::InputMethodQueries queries() const { return m_queries; }
+
+ void setValue(Qt::InputMethodQuery q, const QVariant &v);
+ QVariant value(Qt::InputMethodQuery q) const;
+private:
+ Qt::InputMethodQueries m_queries;
+ struct QueryPair {
+ Qt::InputMethodQuery query;
+ QVariant value;
+ };
+ QVector<QueryPair> m_values;
+};
+
#endif // QT_NO_INPUTMETHOD
#ifndef QT_NO_DRAGANDDROP
@@ -497,7 +495,7 @@ public:
inline Qt::DropAction dropAction() const { return drop_action; }
void setDropAction(Qt::DropAction action);
- QWidget* source() const;
+ QObject* source() const;
inline const QMimeData *mimeData() const { return mdata; }
// QT3_SUPPORT
@@ -505,16 +503,6 @@ public:
QByteArray encodedData(const char*) const;
bool provides(const char*) const;
// END QT3_SUPPORT
-#ifdef QT3_SUPPORT
- inline void accept() { QEvent::accept(); }
- inline QT3_SUPPORT void accept(bool y) { setAccepted(y); }
- inline QT3_SUPPORT QByteArray data(const char* f) const { return encodedData(f); }
-
- enum Action { Copy, Link, Move, Private, UserAction = Private };
- QT3_SUPPORT Action action() const;
- inline QT3_SUPPORT void acceptAction(bool y = true) { if (y) { drop_action = default_action; accept(); } }
- inline QT3_SUPPORT void setPoint(const QPoint& np) { p = np; }
-#endif
protected:
@@ -545,10 +533,6 @@ public:
inline void accept(const QRect & r) { accept(); rect = r; }
inline void ignore(const QRect & r) { ignore(); rect = r; }
-#ifdef QT3_SUPPORT
- inline QT3_SUPPORT void accept(bool y) { setAccepted(y); }
-#endif
-
protected:
friend class QApplication;
QRect rect;
@@ -564,19 +548,6 @@ public:
};
-/* An internal class */
-class Q_GUI_EXPORT QDragResponseEvent : public QEvent
-{
-public:
- QDragResponseEvent(bool accepted);
- ~QDragResponseEvent();
-
- inline bool dragAccepted() const { return a; }
-protected:
- bool a;
-};
-
-
class Q_GUI_EXPORT QDragLeaveEvent : public QEvent
{
public:
@@ -719,18 +690,6 @@ private:
Qt::WindowStates ostate;
};
-#ifdef QT3_SUPPORT
-class QMenuBar;
-class Q_GUI_EXPORT QMenubarUpdatedEvent: public QEvent
-{
-public:
- QMenubarUpdatedEvent(QMenuBar * const menBar);
- inline QMenuBar *menuBar() { return m_menuBar; }
-private:
- QMenuBar *m_menuBar;
-};
-#endif
-
#ifndef QT_NO_DEBUG_STREAM
Q_GUI_EXPORT QDebug operator<<(QDebug, const QEvent *);
#endif
@@ -801,6 +760,8 @@ public:
private:
QTouchEventTouchPointPrivate *d;
+ friend class QGuiApplication;
+ friend class QGuiApplicationPrivate;
friend class QApplication;
friend class QApplicationPrivate;
};
@@ -834,63 +795,12 @@ protected:
Qt::TouchPointStates _touchPointStates;
QList<QTouchEvent::TouchPoint> _touchPoints;
+ friend class QGuiApplication;
+ friend class QGuiApplicationPrivate;
friend class QApplication;
friend class QApplicationPrivate;
};
-#ifndef QT_NO_GESTURES
-class QGesture;
-class QGestureEventPrivate;
-class Q_GUI_EXPORT QGestureEvent : public QEvent
-{
-public:
- QGestureEvent(const QList<QGesture *> &gestures);
- ~QGestureEvent();
-
- QList<QGesture *> gestures() const;
- QGesture *gesture(Qt::GestureType type) const;
-
- QList<QGesture *> activeGestures() const;
- QList<QGesture *> canceledGestures() const;
-
-#ifdef Q_NO_USING_KEYWORD
- inline void setAccepted(bool accepted) { QEvent::setAccepted(accepted); }
- inline bool isAccepted() const { return QEvent::isAccepted(); }
-
- inline void accept() { QEvent::accept(); }
- inline void ignore() { QEvent::ignore(); }
-#else
- using QEvent::setAccepted;
- using QEvent::isAccepted;
- using QEvent::accept;
- using QEvent::ignore;
-#endif
-
- void setAccepted(QGesture *, bool);
- void accept(QGesture *);
- void ignore(QGesture *);
- bool isAccepted(QGesture *) const;
-
- void setAccepted(Qt::GestureType, bool);
- void accept(Qt::GestureType);
- void ignore(Qt::GestureType);
- bool isAccepted(Qt::GestureType) const;
-
- void setWidget(QWidget *widget);
- QWidget *widget() const;
-
-#ifndef QT_NO_GRAPHICSVIEW
- QPointF mapToGraphicsScene(const QPointF &gesturePoint) const;
-#endif
-
-private:
- QGestureEventPrivate *d_func();
- const QGestureEventPrivate *d_func() const;
-
- friend class QApplication;
- friend class QGestureManager;
-};
-#endif // QT_NO_GESTURES
class QScrollPrepareEventPrivate;
class Q_GUI_EXPORT QScrollPrepareEvent : public QEvent
diff --git a/src/gui/kernel/qevent_p.h b/src/gui/kernel/qevent_p.h
index ffe1dfdefc..59eb270230 100644
--- a/src/gui/kernel/qevent_p.h
+++ b/src/gui/kernel/qevent_p.h
@@ -110,53 +110,6 @@ public:
qreal pressure;
};
-#ifndef QT_NO_GESTURES
-class QNativeGestureEvent : public QEvent
-{
-public:
- enum Type {
- None,
- GestureBegin,
- GestureEnd,
- Pan,
- Zoom,
- Rotate,
- Swipe
- };
-
- QNativeGestureEvent()
- : QEvent(QEvent::NativeGesture), gestureType(None), percentage(0)
-#ifdef Q_WS_WIN
- , sequenceId(0), argument(0)
-#endif
- {
- }
-
- Type gestureType;
- float percentage;
- QPoint position;
- float angle;
-#ifdef Q_WS_WIN
- ulong sequenceId;
- quint64 argument;
-#endif
-};
-
-class QGestureEventPrivate
-{
-public:
- inline QGestureEventPrivate(const QList<QGesture *> &list)
- : gestures(list), widget(0)
- {
- }
-
- QList<QGesture *> gestures;
- QWidget *widget;
- QMap<Qt::GestureType, bool> accepted;
- QMap<Qt::GestureType, QWidget *> targetWidgets;
-};
-#endif // QT_NO_GESTURES
-
class QFileOpenEventPrivate
{
public:
diff --git a/src/gui/kernel/qeventdispatcher_glib_qpa.cpp b/src/gui/kernel/qeventdispatcher_glib_qpa.cpp
deleted file mode 100644
index a9b10182d0..0000000000
--- a/src/gui/kernel/qeventdispatcher_glib_qpa.cpp
+++ /dev/null
@@ -1,147 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qeventdispatcher_glib_qpa_p.h"
-
-#include "qapplication.h"
-
-#include "qplatformdefs.h"
-#include "qapplication.h"
-
-#include <glib.h>
-#include "qapplication_p.h"
-
-#include <qdebug.h>
-
-QT_BEGIN_NAMESPACE
-
-struct GUserEventSource
-{
- GSource source;
- QPAEventDispatcherGlib *q;
-};
-
-static gboolean userEventSourcePrepare(GSource *s, gint *timeout)
-{
- Q_UNUSED(s)
- Q_UNUSED(timeout)
-
- return QWindowSystemInterfacePrivate::windowSystemEventsQueued() > 0;
-}
-
-static gboolean userEventSourceCheck(GSource *source)
-{
- return userEventSourcePrepare(source, 0);
-}
-
-static gboolean userEventSourceDispatch(GSource *s, GSourceFunc, gpointer)
-{
- GUserEventSource * source = reinterpret_cast<GUserEventSource *>(s);
-
- QWindowSystemInterfacePrivate::WindowSystemEvent * event;
- while (QWindowSystemInterfacePrivate::windowSystemEventsQueued()) {
- event = QWindowSystemInterfacePrivate::getWindowSystemEvent();
- if (!event)
- break;
-
- // send through event filter
- if (source->q->filterEvent(event)) {
- delete event;
- continue;
- }
- QApplicationPrivate::processWindowSystemEvent(event);
- delete event;
- }
-
- return true;
-}
-
-
-static GSourceFuncs userEventSourceFuncs = {
- userEventSourcePrepare,
- userEventSourceCheck,
- userEventSourceDispatch,
- NULL,
- NULL,
- NULL
-};
-
-QPAEventDispatcherGlibPrivate::QPAEventDispatcherGlibPrivate(GMainContext *context)
- : QEventDispatcherGlibPrivate(context)
-{
- userEventSource = reinterpret_cast<GUserEventSource *>(g_source_new(&userEventSourceFuncs,
- sizeof(GUserEventSource)));
- userEventSource->q = 0;
- g_source_set_can_recurse(&userEventSource->source, true);
- g_source_attach(&userEventSource->source, mainContext);
-}
-
-
-QPAEventDispatcherGlib::QPAEventDispatcherGlib(QObject *parent)
- : QEventDispatcherGlib(*new QPAEventDispatcherGlibPrivate, parent)
-{
- Q_D(QPAEventDispatcherGlib);
- d->userEventSource->q = this;
-}
-
-QPAEventDispatcherGlib::~QPAEventDispatcherGlib()
-{
- Q_D(QPAEventDispatcherGlib);
-
- g_source_destroy(&d->userEventSource->source);
- g_source_unref(&d->userEventSource->source);
- d->userEventSource = 0;
-}
-
-bool QPAEventDispatcherGlib::processEvents(QEventLoop::ProcessEventsFlags flags)
-{
- static bool init = false;
- if (!init) {
- if (QApplicationPrivate::platformIntegration()->createEventLoopIntegration()) {
- qWarning("Eventloop integration is not supported by the glib event dispatcher");
- qWarning("Use the UNIX event dispatcher by defining environment variable QT_NO_GLIB=1");
- }
- init = true;
- }
- return QEventDispatcherGlib::processEvents(flags);
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/kernel/qeventdispatcher_glib_qpa_p.h b/src/gui/kernel/qeventdispatcher_glib_qpa_p.h
deleted file mode 100644
index 8a8559dfb4..0000000000
--- a/src/gui/kernel/qeventdispatcher_glib_qpa_p.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QEVENTDISPATCHER_GLIB_QPA_P_H
-#define QEVENTDISPATCHER_GLIB_QPA_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of the QLibrary class. This header file may change from
-// version to version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/private/qeventdispatcher_glib_p.h>
-
-typedef struct _GMainContext GMainContext;
-
-QT_BEGIN_NAMESPACE
-class QPAEventDispatcherGlibPrivate;
-
-class QPAEventDispatcherGlib : public QEventDispatcherGlib
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QPAEventDispatcherGlib)
-
-public:
- explicit QPAEventDispatcherGlib(QObject *parent = 0);
- ~QPAEventDispatcherGlib();
-
- bool processEvents(QEventLoop::ProcessEventsFlags flags);
-};
-
-struct GUserEventSource;
-
-class QPAEventDispatcherGlibPrivate : public QEventDispatcherGlibPrivate
-{
- Q_DECLARE_PUBLIC(QPAEventDispatcherGlib)
-public:
- QPAEventDispatcherGlibPrivate(GMainContext *context = 0);
- GUserEventSource *userEventSource;
-};
-
-
-QT_END_NAMESPACE
-
-#endif // QEVENTDISPATCHER_GLIB_QPA_P_H
diff --git a/src/gui/kernel/qeventdispatcher_glib_qws.cpp b/src/gui/kernel/qeventdispatcher_glib_qws.cpp
deleted file mode 100644
index 0c2dd994f7..0000000000
--- a/src/gui/kernel/qeventdispatcher_glib_qws.cpp
+++ /dev/null
@@ -1,195 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qeventdispatcher_glib_qws_p.h"
-
-#include "qapplication.h"
-
-#include "qplatformdefs.h"
-#include "qapplication.h"
-#include "private/qwscommand_qws_p.h"
-#include "qwsdisplay_qws.h"
-#include "qwsevent_qws.h"
-#include "qwindowsystem_qws.h"
-
-#include <glib.h>
-
-QT_BEGIN_NAMESPACE
-
-// from qapplication_qws.cpp
-extern QWSDisplay* qt_fbdpy; // QWS `display'
-
-//from qwindowsystem_qws.cpp
-extern QList<QWSCommand*> *qt_get_server_queue();
-
-struct GQWSEventSource
-{
- GSource source;
- QEventLoop::ProcessEventsFlags flags;
- QWSEventDispatcherGlib *q;
- QWSEventDispatcherGlibPrivate *d;
-};
-
-class QWSEventDispatcherGlibPrivate : public QEventDispatcherGlibPrivate
-{
- Q_DECLARE_PUBLIC(QWSEventDispatcherGlib)
-
-public:
- QWSEventDispatcherGlibPrivate();
- GQWSEventSource *qwsEventSource;
- QList<QWSEvent*> queuedUserInputEvents;
-};
-
-static gboolean qwsEventSourcePrepare(GSource *s, gint *timeout)
-{
- if (timeout)
- *timeout = -1;
- GQWSEventSource *source = reinterpret_cast<GQWSEventSource *>(s);
- return qt_fbdpy->eventPending() || !source->d->queuedUserInputEvents.isEmpty()
- || !qt_get_server_queue()->isEmpty() ;
-}
-
-static gboolean qwsEventSourceCheck(GSource *s)
-{
- GQWSEventSource *source = reinterpret_cast<GQWSEventSource *>(s);
- return qt_fbdpy->eventPending() || !source->d->queuedUserInputEvents.isEmpty()
- || !qt_get_server_queue()->isEmpty() ;
-}
-
-static gboolean qwsEventSourceDispatch(GSource *s, GSourceFunc callback, gpointer user_data)
-{
- GQWSEventSource *source = reinterpret_cast<GQWSEventSource *>(s);
-
- //??? ulong marker = XNextRequest(X11->display);
- do {
- QWSEvent *event;
- if (!(source->flags & QEventLoop::ExcludeUserInputEvents)
- && !source->d->queuedUserInputEvents.isEmpty()) {
- // process a pending user input event
- event = source->d->queuedUserInputEvents.takeFirst();
- } else if (qt_fbdpy->eventPending()) {
- event = qt_fbdpy->getEvent();
-
- if (source->flags & QEventLoop::ExcludeUserInputEvents) {
- // queue user input events
-
- if (event->type == QWSEvent::Mouse || event->type == QWSEvent::Key) {
- source->d->queuedUserInputEvents.append(event);
- continue;
- }
- }
- } else {
- // no event to process
- break;
- }
-
- // send through event filter
- if (source->q->filterEvent(event)) {
- delete event;
- continue;
- }
-
- bool ret = qApp->qwsProcessEvent(event) == 1;
- delete event;
- if (ret) {
- return true;
- }
-
- } while (qt_fbdpy->eventPending());
-
- if (callback)
- callback(user_data);
- return true;
-}
-
-static GSourceFuncs qwsEventSourceFuncs = {
- qwsEventSourcePrepare,
- qwsEventSourceCheck,
- qwsEventSourceDispatch,
- NULL,
- NULL,
- NULL
-};
-
-QWSEventDispatcherGlibPrivate::QWSEventDispatcherGlibPrivate()
-{
- qwsEventSource = reinterpret_cast<GQWSEventSource *>(g_source_new(&qwsEventSourceFuncs,
- sizeof(GQWSEventSource)));
- g_source_set_can_recurse(&qwsEventSource->source, true);
-
- qwsEventSource->flags = QEventLoop::AllEvents;
- qwsEventSource->q = 0;
- qwsEventSource->d = 0;
-
- g_source_attach(&qwsEventSource->source, mainContext);
-}
-
-QWSEventDispatcherGlib::QWSEventDispatcherGlib(QObject *parent)
- : QEventDispatcherGlib(*new QWSEventDispatcherGlibPrivate, parent)
-{
-}
-
-QWSEventDispatcherGlib::~QWSEventDispatcherGlib()
-{
- Q_D(QWSEventDispatcherGlib);
-
- g_source_destroy(&d->qwsEventSource->source);
- d->qwsEventSource = 0;
-}
-
-bool QWSEventDispatcherGlib::processEvents(QEventLoop::ProcessEventsFlags flags)
-{
- Q_D(QWSEventDispatcherGlib);
- QEventLoop::ProcessEventsFlags saved_flags = d->qwsEventSource->flags;
- d->qwsEventSource->flags = flags;
- bool returnValue = QEventDispatcherGlib::processEvents(flags);
- d->qwsEventSource->flags = saved_flags;
- return returnValue;
-}
-
-void QWSEventDispatcherGlib::startingUp()
-{
- Q_D(QWSEventDispatcherGlib);
- d->qwsEventSource->q = this;
- d->qwsEventSource->d = d;
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/kernel/qeventdispatcher_glib_qws_p.h b/src/gui/kernel/qeventdispatcher_glib_qws_p.h
deleted file mode 100644
index ba6e836a4b..0000000000
--- a/src/gui/kernel/qeventdispatcher_glib_qws_p.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWSEVENTDISPATCHER_GLIB_P_H
-#define QWSEVENTDISPATCHER_GLIB_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of the QLibrary class. This header file may change from
-// version to version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/private/qeventdispatcher_glib_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QWSEventDispatcherGlibPrivate;
-
-class QWSEventDispatcherGlib : public QEventDispatcherGlib
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QWSEventDispatcherGlib)
-
-public:
- explicit QWSEventDispatcherGlib(QObject *parent = 0);
- ~QWSEventDispatcherGlib();
-
- bool processEvents(QEventLoop::ProcessEventsFlags flags);
-
- void startingUp();
-};
-
-QT_END_NAMESPACE
-
-#endif // QWSEVENTDISPATCHER_GLIB_P_H
diff --git a/src/gui/kernel/qeventdispatcher_qpa.cpp b/src/gui/kernel/qeventdispatcher_qpa.cpp
deleted file mode 100644
index 200696d104..0000000000
--- a/src/gui/kernel/qeventdispatcher_qpa.cpp
+++ /dev/null
@@ -1,334 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qplatformdefs.h"
-#include "qapplication.h"
-#include "qeventdispatcher_qpa_p.h"
-#include "private/qeventdispatcher_unix_p.h"
-#include "qapplication_p.h"
-#include "qplatformeventloopintegration_qpa.h"
-
-#include <QWindowSystemInterface>
-#include <QtCore/QElapsedTimer>
-#include <QtCore/QAtomicInt>
-#include <QtCore/QSemaphore>
-
-#include <QtCore/QDebug>
-
-#include <errno.h>
-
-QT_BEGIN_NAMESPACE
-
-QT_USE_NAMESPACE
-
-class Rendezvous
-{
-public:
- void checkpoint()
- {
- if (state.testAndSetOrdered(0,1)) {
- semaphore.acquire();
- } else if (state.testAndSetAcquire(1,0)) {
- semaphore.release();
- } else {
- qWarning("Barrier internal error");
- }
- }
-private:
- QSemaphore semaphore;
- QAtomicInt state;
-};
-
-class SelectWorker : public QThread
-{
-public:
- SelectWorker(QEventDispatcherQPAPrivate *eventDispatcherPrivate)
- : QThread(),
- m_edPrivate(eventDispatcherPrivate),
- m_retVal(0)
- {
- }
-
- void setSelectValues(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds)
- {
- m_nfds = nfds;
- m_readfds = readfds;
- m_writefds = writefds;
- m_exceptfds = exceptfds;
-
-
- }
-
- int retVal() const {
- return m_retVal;
- }
-
-protected:
- void run();
-
-private:
- QEventDispatcherQPAPrivate *m_edPrivate;
- int m_retVal;
-
- int m_nfds;
- fd_set *m_readfds, *m_writefds, *m_exceptfds;
-};
-
-class QEventDispatcherQPAPrivate : public QEventDispatcherUNIXPrivate
-{
- Q_DECLARE_PUBLIC(QEventDispatcherQPA)
-public:
- QEventDispatcherQPAPrivate()
- : eventLoopIntegration(0),
- barrierBeforeBlocking(0),
- barrierReturnValue(0),
- selectReturnMutex(0),
- selectWorkerNeedsSync(true),
- selectWorkerHasResult(false),
- m_integrationInitialised(false),
- m_hasIntegration(false),
- m_isEventLoopIntegrationRunning(false)
- {
-
- }
-
- ~QEventDispatcherQPAPrivate()
- {
- delete selectWorker;
- delete eventLoopIntegration;
- delete barrierBeforeBlocking;
- delete barrierReturnValue;
- delete selectReturnMutex;
- }
-
- bool hasIntegration() const
- {
- if (!m_integrationInitialised) {
- QEventDispatcherQPAPrivate *that = const_cast<QEventDispatcherQPAPrivate *>(this);
- if (qApp && (qApp->thread() == QThread::currentThread())) { // guiThread
- if (QApplicationPrivate::platformIntegration()) {
- that->eventLoopIntegration = QApplicationPrivate::platformIntegration()->createEventLoopIntegration();
- if (that->eventLoopIntegration) {
- that->selectWorker = new SelectWorker(that);
- that->barrierBeforeBlocking = new Rendezvous;
- that->barrierReturnValue = new Rendezvous;
- that->selectReturnMutex = new QMutex;
- that->selectWorker->start();
- that->m_hasIntegration = true;
- if (!QElapsedTimer::isMonotonic())
- qWarning("Having eventloop integration without monotonic timers can lead to undefined behaviour");
- }
- }
- }
- that->m_integrationInitialised = true;
- }
- return m_hasIntegration;
- }
-
- bool isEventLoopIntegrationRunning() const
- {
- return m_isEventLoopIntegrationRunning;
- }
-
- void runEventLoopIntegration()
- {
- if (qApp && (qApp->thread() == QThread::currentThread())) {
- m_isEventLoopIntegrationRunning = true;
- eventLoopIntegration->startEventLoop();
- }
- }
-
- QPlatformEventLoopIntegration *eventLoopIntegration;
- Rendezvous *barrierBeforeBlocking;
- Rendezvous *barrierReturnValue;
-
- QMutex *selectReturnMutex;
- bool selectWorkerNeedsSync;
- bool selectWorkerHasResult;
-
- SelectWorker *selectWorker;
-private:
- bool m_integrationInitialised;
- bool m_hasIntegration;
- bool m_isEventLoopIntegrationRunning;
-};
-
-QEventDispatcherQPA::QEventDispatcherQPA(QObject *parent)
- : QEventDispatcherUNIX(*new QEventDispatcherQPAPrivate, parent)
-{ }
-
-QEventDispatcherQPA::~QEventDispatcherQPA()
-{ }
-
-bool QEventDispatcherQPA::processEvents(QEventLoop::ProcessEventsFlags flags)
-{
- Q_D(QEventDispatcherQPA);
-
- if (d->hasIntegration()) {
- if (!d->isEventLoopIntegrationRunning()) {
- d->runEventLoopIntegration();
- }
- if (d->threadData->quitNow) {
- d->eventLoopIntegration->quitEventLoop();
- return false;
- }
- }
-
- int nevents = 0;
-
- // handle gui and posted events
- d->interrupt = false;
- QApplication::sendPostedEvents();
-
- while (!d->interrupt) { // also flushes output buffer ###can be optimized
- QWindowSystemInterfacePrivate::WindowSystemEvent *event;
- if (!(flags & QEventLoop::ExcludeUserInputEvents)
- && QWindowSystemInterfacePrivate::windowSystemEventsQueued() > 0) {
- // process a pending user input event
- event = QWindowSystemInterfacePrivate::getWindowSystemEvent();
- if (!event)
- break;
- } else {
- break;
- }
-
- if (filterEvent(event)) {
- delete event;
- continue;
- }
- nevents++;
-
- QApplicationPrivate::processWindowSystemEvent(event);
- delete event;
- }
-
- if (!d->interrupt) {
- if (QEventDispatcherUNIX::processEvents(flags)) {
- QEventDispatcherUNIX::processEvents(flags);
- return true;
- }
- }
- return (nevents > 0);
-}
-
-bool QEventDispatcherQPA::hasPendingEvents()
-{
- extern uint qGlobalPostedEventsCount(); // from qapplication.cpp
- return qGlobalPostedEventsCount() || QWindowSystemInterfacePrivate::windowSystemEventsQueued();
-}
-
-void QEventDispatcherQPA::registerSocketNotifier(QSocketNotifier *notifier)
-{
- Q_D(QEventDispatcherQPA);
- QEventDispatcherUNIX::registerSocketNotifier(notifier);
- if (d->hasIntegration())
- wakeUp();
-
-}
-
-void QEventDispatcherQPA::unregisterSocketNotifier(QSocketNotifier *notifier)
-{
- Q_D(QEventDispatcherQPA);
- QEventDispatcherUNIX::unregisterSocketNotifier(notifier);
- if (d->hasIntegration())
- wakeUp();
-}
-
-void QEventDispatcherQPA::flush()
-{
- if(qApp)
- qApp->sendPostedEvents();
-}
-
-int QEventDispatcherQPA::select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
- timeval *timeout)
-{
- Q_D(QEventDispatcherQPA);
- int retVal = 0;
- if (d->hasIntegration()) {
- qint64 timeoutmsec = 0;
- if (timeout)
- timeoutmsec = timeout->tv_sec * 1000 + (timeout->tv_usec/1000);
- d->selectReturnMutex->lock();
- if (d->selectWorkerNeedsSync) {
- if (d->selectWorkerHasResult) {
- retVal = d->selectWorker->retVal();
- d->selectWorkerHasResult = false;
-
- d->selectReturnMutex->unlock();
- d->barrierReturnValue->checkpoint();
- d->eventLoopIntegration->setNextTimerEvent(0);
- return retVal;
- } else {
- d->selectWorkerNeedsSync = false;
- d->selectWorker->setSelectValues(nfds,readfds, writefds, exceptfds);
- d->barrierBeforeBlocking->checkpoint();
- }
- }
- d->selectReturnMutex->unlock();
- d->eventLoopIntegration->setNextTimerEvent(timeoutmsec);
- retVal = 0; //is 0 if select has not returned
- } else {
- retVal = QEventDispatcherUNIX::select(nfds, readfds, writefds, exceptfds, timeout);
- }
- return retVal;
-}
-
-
-void SelectWorker::run()
-{
-
- while(true) {
- m_retVal = 0;
- m_edPrivate->barrierBeforeBlocking->checkpoint(); // wait for mainthread
- int tmpRet = qt_safe_select(m_nfds,m_readfds,m_writefds,m_exceptfds,0);
- m_edPrivate->selectReturnMutex->lock();
- m_edPrivate->eventLoopIntegration->qtNeedsToProcessEvents();
-
- m_edPrivate->selectWorkerNeedsSync = true;
- m_edPrivate->selectWorkerHasResult = true;
- m_retVal = tmpRet;
-
- m_edPrivate->selectReturnMutex->unlock();
- m_edPrivate->barrierReturnValue->checkpoint();
- }
-}
-QT_END_NAMESPACE
diff --git a/src/gui/kernel/qeventdispatcher_qpa_p.h b/src/gui/kernel/qeventdispatcher_qpa_p.h
deleted file mode 100644
index c145e389f6..0000000000
--- a/src/gui/kernel/qeventdispatcher_qpa_p.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QEVENTDISPATCHER_QPA_P_H
-#define QEVENTDISPATCHER_QPA_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "private/qeventdispatcher_unix_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class QEventDispatcherQPAPrivate;
-
-class QEventDispatcherQPA : public QEventDispatcherUNIX
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QEventDispatcherQPA)
-
-public:
- explicit QEventDispatcherQPA(QObject *parent = 0);
- ~QEventDispatcherQPA();
-
- bool processEvents(QEventLoop::ProcessEventsFlags flags);
- bool hasPendingEvents();
-
- void registerSocketNotifier(QSocketNotifier *notifier);
- void unregisterSocketNotifier(QSocketNotifier *notifier);
-
- void flush();
-
-protected:
- int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
- timeval *timeout);
-};
-
-QT_END_NAMESPACE
-
-#endif // QEVENTDISPATCHER_QPA_P_H
diff --git a/src/gui/kernel/qeventdispatcher_qws.cpp b/src/gui/kernel/qeventdispatcher_qws.cpp
deleted file mode 100644
index cc39c03773..0000000000
--- a/src/gui/kernel/qeventdispatcher_qws.cpp
+++ /dev/null
@@ -1,168 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qplatformdefs.h"
-#include "qapplication.h"
-#include "private/qwscommand_qws_p.h"
-#include "qwsdisplay_qws.h"
-#include "qwsevent_qws.h"
-#include "qwindowsystem_qws.h"
-#include "qeventdispatcher_qws_p.h"
-#include "private/qeventdispatcher_unix_p.h"
-#ifndef QT_NO_THREAD
-# include "qmutex.h"
-#endif
-
-#include <errno.h>
-
-QT_BEGIN_NAMESPACE
-
-QT_USE_NAMESPACE
-
-class QEventDispatcherQWSPrivate : public QEventDispatcherUNIXPrivate
-{
- Q_DECLARE_PUBLIC(QEventDispatcherQWS)
-public:
- inline QEventDispatcherQWSPrivate()
- { }
- QList<QWSEvent*> queuedUserInputEvents;
-};
-
-
-QEventDispatcherQWS::QEventDispatcherQWS(QObject *parent)
- : QEventDispatcherUNIX(*new QEventDispatcherQWSPrivate, parent)
-{ }
-
-QEventDispatcherQWS::~QEventDispatcherQWS()
-{ }
-
-
-
-// from qapplication_qws.cpp
-extern QWSDisplay* qt_fbdpy; // QWS `display'
-
-//#define ZERO_FOR_THE_MOMENT
-
-bool QEventDispatcherQWS::processEvents(QEventLoop::ProcessEventsFlags flags)
-{
- Q_D(QEventDispatcherQWS);
- // process events from the QWS server
- int nevents = 0;
-
- // handle gui and posted events
- d->interrupt = false;
- QApplication::sendPostedEvents();
-
- while (!d->interrupt) { // also flushes output buffer ###can be optimized
- QWSEvent *event;
- if (!(flags & QEventLoop::ExcludeUserInputEvents)
- && !d->queuedUserInputEvents.isEmpty()) {
- // process a pending user input event
- event = d->queuedUserInputEvents.takeFirst();
- } else if (qt_fbdpy->eventPending()) {
- event = qt_fbdpy->getEvent(); // get next event
- if (flags & QEventLoop::ExcludeUserInputEvents) {
- // queue user input events
- if (event->type == QWSEvent::Mouse || event->type == QWSEvent::Key) {
- d->queuedUserInputEvents.append(event);
- continue;
- }
- }
- } else {
- break;
- }
-
- if (filterEvent(event)) {
- delete event;
- continue;
- }
- nevents++;
-
- bool ret = qApp->qwsProcessEvent(event) == 1;
- delete event;
- if (ret) {
- return true;
- }
- }
-
- if (!d->interrupt) {
- extern QList<QWSCommand*> *qt_get_server_queue();
- if (!qt_get_server_queue()->isEmpty()) {
- QWSServer::processEventQueue();
- }
-
- if (QEventDispatcherUNIX::processEvents(flags))
- return true;
- }
- return (nevents > 0);
-}
-
-bool QEventDispatcherQWS::hasPendingEvents()
-{
- extern uint qGlobalPostedEventsCount(); // from qapplication.cpp
- return qGlobalPostedEventsCount() || qt_fbdpy->eventPending();
-}
-
-void QEventDispatcherQWS::startingUp()
-{
-
-}
-
-void QEventDispatcherQWS::closingDown()
-{
-
-}
-
-void QEventDispatcherQWS::flush()
-{
- if(qApp)
- qApp->sendPostedEvents();
- (void)qt_fbdpy->eventPending(); // flush
-}
-
-
-int QEventDispatcherQWS::select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
- timeval *timeout)
-{
- return QEventDispatcherUNIX::select(nfds, readfds, writefds, exceptfds, timeout);
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/kernel/qeventdispatcher_qws_p.h b/src/gui/kernel/qeventdispatcher_qws_p.h
deleted file mode 100644
index f27d765e51..0000000000
--- a/src/gui/kernel/qeventdispatcher_qws_p.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QEVENTDISPATCHER_QWS_P_H
-#define QEVENTDISPATCHER_QWS_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "private/qeventdispatcher_unix_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class QEventDispatcherQWSPrivate;
-
-class QEventDispatcherQWS : public QEventDispatcherUNIX
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QEventDispatcherQWS)
-
-public:
- explicit QEventDispatcherQWS(QObject *parent = 0);
- ~QEventDispatcherQWS();
-
- bool processEvents(QEventLoop::ProcessEventsFlags flags);
- bool hasPendingEvents();
-
- void flush();
-
- void startingUp();
- void closingDown();
-
-protected:
- int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
- timeval *timeout);
-};
-
-QT_END_NAMESPACE
-
-#endif // QEVENTDISPATCHER_QWS_P_H
diff --git a/src/gui/kernel/qeventdispatcher_s60_p.h b/src/gui/kernel/qeventdispatcher_s60_p.h
deleted file mode 100644
index 49ec568097..0000000000
--- a/src/gui/kernel/qeventdispatcher_s60_p.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QEVENTDISPATCHER_S60_P_H
-#define QEVENTDISPATCHER_S60_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <private/qeventdispatcher_symbian_p.h>
-#include "qt_s60_p.h"
-
-#include <eikenv.h>
-
-QT_BEGIN_NAMESPACE
-
-class QEventDispatcherS60;
-
-class QtEikonEnv : public CEikonEnv
-{
-public:
- QtEikonEnv();
- ~QtEikonEnv();
-
- // from CActive.
- void RunL();
- void DoCancel();
-
- void complete();
-
-private:
- // Workaround for a BC break from S60 3.2 -> 5.0, where the CEikonEnv override was removed.
- // To avoid linking to that when we build against 3.2, define an empty body here.
- // Reserved_*() have been verified to be empty in the S60 code.
- void Reserved_1() {}
- void Reserved_2() {}
-
-private:
- int m_lastIterationCount;
- TInt m_savedStatusCode;
- bool m_hasAlreadyRun;
-};
-
-class Q_GUI_EXPORT QEventDispatcherS60 : public QEventDispatcherSymbian
-{
- Q_OBJECT
-
-public:
- QEventDispatcherS60(QObject *parent = 0);
- ~QEventDispatcherS60();
-
- bool processEvents ( QEventLoop::ProcessEventsFlags flags );
- bool hasPendingEvents();
-
- bool excludeUserInputEvents() { return m_noInputEvents; }
-
- void saveInputEvent(QSymbianControl *control, QWidget *widget, QInputEvent *event);
-
- void reactivateDeferredActiveObjects();
-
-private:
- bool sendDeferredInputEvents();
-
-private Q_SLOTS:
- void removeInputEventsForWidget(QObject *object);
-
-private:
- bool m_noInputEvents;
-
- struct DeferredInputEvent
- {
- QSymbianControl *control;
- QWidget *widget;
- QInputEvent *event;
- };
- QList<DeferredInputEvent> m_deferredInputEvents;
-};
-
-QT_END_NAMESPACE
-
-#endif // QEVENTDISPATCHER_S60_P_H
diff --git a/src/gui/kernel/qformlayout.h b/src/gui/kernel/qformlayout.h
deleted file mode 100644
index bc09666394..0000000000
--- a/src/gui/kernel/qformlayout.h
+++ /dev/null
@@ -1,163 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QFORMLAYOUT_H
-#define QFORMLAYOUT_H
-
-#include <QtGui/QLayout>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QFormLayoutPrivate;
-
-class Q_GUI_EXPORT QFormLayout : public QLayout
-{
- Q_OBJECT
- Q_ENUMS(FormStyle FieldGrowthPolicy RowWrapPolicy ItemRole)
- Q_DECLARE_PRIVATE(QFormLayout)
- Q_PROPERTY(FieldGrowthPolicy fieldGrowthPolicy READ fieldGrowthPolicy WRITE setFieldGrowthPolicy RESET resetFieldGrowthPolicy)
- Q_PROPERTY(RowWrapPolicy rowWrapPolicy READ rowWrapPolicy WRITE setRowWrapPolicy RESET resetRowWrapPolicy)
- Q_PROPERTY(Qt::Alignment labelAlignment READ labelAlignment WRITE setLabelAlignment RESET resetLabelAlignment)
- Q_PROPERTY(Qt::Alignment formAlignment READ formAlignment WRITE setFormAlignment RESET resetFormAlignment)
- Q_PROPERTY(int horizontalSpacing READ horizontalSpacing WRITE setHorizontalSpacing)
- Q_PROPERTY(int verticalSpacing READ verticalSpacing WRITE setVerticalSpacing)
-
-public:
- enum FieldGrowthPolicy {
- FieldsStayAtSizeHint,
- ExpandingFieldsGrow,
- AllNonFixedFieldsGrow
- };
-
- enum RowWrapPolicy {
- DontWrapRows,
- WrapLongRows,
- WrapAllRows
- };
-
- enum ItemRole {
- LabelRole = 0,
- FieldRole = 1,
- SpanningRole = 2
- };
-
- explicit QFormLayout(QWidget *parent = 0);
- ~QFormLayout();
-
- void setFieldGrowthPolicy(FieldGrowthPolicy policy);
- FieldGrowthPolicy fieldGrowthPolicy() const;
- void setRowWrapPolicy(RowWrapPolicy policy);
- RowWrapPolicy rowWrapPolicy() const;
- void setLabelAlignment(Qt::Alignment alignment);
- Qt::Alignment labelAlignment() const;
- void setFormAlignment(Qt::Alignment alignment);
- Qt::Alignment formAlignment() const;
-
- void setHorizontalSpacing(int spacing);
- int horizontalSpacing() const;
- void setVerticalSpacing(int spacing);
- int verticalSpacing() const;
-
- int spacing() const;
- void setSpacing(int);
-
- void addRow(QWidget *label, QWidget *field);
- void addRow(QWidget *label, QLayout *field);
- void addRow(const QString &labelText, QWidget *field);
- void addRow(const QString &labelText, QLayout *field);
- void addRow(QWidget *widget);
- void addRow(QLayout *layout);
-
- void insertRow(int row, QWidget *label, QWidget *field);
- void insertRow(int row, QWidget *label, QLayout *field);
- void insertRow(int row, const QString &labelText, QWidget *field);
- void insertRow(int row, const QString &labelText, QLayout *field);
- void insertRow(int row, QWidget *widget);
- void insertRow(int row, QLayout *layout);
-
- void setItem(int row, ItemRole role, QLayoutItem *item);
- void setWidget(int row, ItemRole role, QWidget *widget);
- void setLayout(int row, ItemRole role, QLayout *layout);
-
- QLayoutItem *itemAt(int row, ItemRole role) const;
- void getItemPosition(int index, int *rowPtr, ItemRole *rolePtr) const;
- void getWidgetPosition(QWidget *widget, int *rowPtr, ItemRole *rolePtr) const;
- void getLayoutPosition(QLayout *layout, int *rowPtr, ItemRole *rolePtr) const;
- QWidget *labelForField(QWidget *field) const;
- QWidget *labelForField(QLayout *field) const;
-
- // reimplemented from QLayout
- void addItem(QLayoutItem *item);
- QLayoutItem *itemAt(int index) const;
- QLayoutItem *takeAt(int index);
-
- void setGeometry(const QRect &rect);
- QSize minimumSize() const;
- QSize sizeHint() const;
- void invalidate();
-
- bool hasHeightForWidth() const;
- int heightForWidth(int width) const;
- Qt::Orientations expandingDirections() const;
- int count() const;
-
- int rowCount() const;
-
-#if 0
- void dump() const;
-#endif
-
-private:
- void resetFieldGrowthPolicy();
- void resetRowWrapPolicy();
- void resetLabelAlignment();
- void resetFormAlignment();
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif
diff --git a/src/gui/kernel/qgenericpluginfactory_qpa.cpp b/src/gui/kernel/qgenericpluginfactory_qpa.cpp
index fb6a0d85fd..7c0975ac1d 100644
--- a/src/gui/kernel/qgenericpluginfactory_qpa.cpp
+++ b/src/gui/kernel/qgenericpluginfactory_qpa.cpp
@@ -41,7 +41,7 @@
#include "qgenericpluginfactory_qpa.h"
-#include "qapplication.h"
+#include "qguiapplication.h"
#include "private/qfactoryloader_p.h"
#include "qgenericplugin_qpa.h"
#include "qdebug.h"
diff --git a/src/gui/kernel/qgesture.cpp b/src/gui/kernel/qgesture.cpp
deleted file mode 100644
index a3ac42e08a..0000000000
--- a/src/gui/kernel/qgesture.cpp
+++ /dev/null
@@ -1,807 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qgesture.h"
-#include "private/qgesture_p.h"
-#include "private/qstandardgestures_p.h"
-
-#ifndef QT_NO_GESTURES
-
-QT_BEGIN_NAMESPACE
-
- /*!
- \class QGesture
- \since 4.6
- \ingroup gestures
-
- \brief The QGesture class represents a gesture, containing properties that
- describe the corresponding user input.
-
- Gesture objects are not constructed directly by developers. They are created by
- the QGestureRecognizer object that is registered with the application; see
- QGestureRecognizer::registerRecognizer().
-
- For an overview of gesture handling in Qt and information on using gestures
- in your applications, see the \l{Gestures Programming} document.
-
- \section1 Gesture Properties
-
- The class has a list of properties that can be queried by the user to get
- some gesture-specific arguments. For example, the pinch gesture has a scale
- factor that is exposed as a property.
-
- Developers of custom gesture recognizers can add additional properties in
- order to provide additional information about a gesture. This can be done
- by adding new dynamic properties to a QGesture object, or by subclassing
- the QGesture class (or one of its subclasses).
-
- \section1 Lifecycle of a Gesture Object
-
- A QGesture instance is implicitly created when needed and is owned by Qt.
- Developers should never destroy them or store them for later use as Qt may
- destroy particular instances of them and create new ones to replace them.
-
- The registered gesture recognizer monitors the input events for the target
- object via its \l{QGestureRecognizer::}{recognize()} function, updating the
- properties of the gesture object as required.
-
- The gesture object may be delivered to the target object in a QGestureEvent if
- the corresponding gesture is active or has just been canceled. Each event that
- is delivered contains a list of gesture objects, since support for more than
- one gesture may be enabled for the target object. Due to the way events are
- handled in Qt, gesture events may be filtered by other objects.
-
- \sa QGestureEvent, QGestureRecognizer
-*/
-
-/*!
- Constructs a new gesture object with the given \a parent.
-
- QGesture objects are created by gesture recognizers in the
- QGestureRecognizer::create() function.
-*/
-QGesture::QGesture(QObject *parent)
- : QObject(*new QGesturePrivate, parent)
-{
- d_func()->gestureType = Qt::CustomGesture;
-}
-
-/*!
- \internal
-*/
-QGesture::QGesture(QGesturePrivate &dd, QObject *parent)
- : QObject(dd, parent)
-{
-}
-
-/*!
- Destroys the gesture object.
-*/
-QGesture::~QGesture()
-{
-}
-
-/*!
- \property QGesture::state
- \brief the current state of the gesture
-*/
-
-/*!
- \property QGesture::gestureType
- \brief the type of the gesture
-*/
-
-/*!
- \property QGesture::hotSpot
-
- \brief The point that is used to find the receiver for the gesture event.
-
- The hot-spot is a point in the global coordinate system, use
- QWidget::mapFromGlobal() or QGestureEvent::mapToGraphicsScene() to get a
- local hot-spot.
-
- The hot-spot should be set by the gesture recognizer to allow gesture event
- delivery to a QGraphicsObject.
-*/
-
-/*!
- \property QGesture::hasHotSpot
- \brief whether the gesture has a hot-spot
-*/
-
-Qt::GestureType QGesture::gestureType() const
-{
- return d_func()->gestureType;
-}
-
-Qt::GestureState QGesture::state() const
-{
- return d_func()->state;
-}
-
-QPointF QGesture::hotSpot() const
-{
- return d_func()->hotSpot;
-}
-
-void QGesture::setHotSpot(const QPointF &value)
-{
- Q_D(QGesture);
- d->hotSpot = value;
- d->isHotSpotSet = true;
-}
-
-bool QGesture::hasHotSpot() const
-{
- return d_func()->isHotSpotSet;
-}
-
-void QGesture::unsetHotSpot()
-{
- d_func()->isHotSpotSet = false;
-}
-
-/*!
- \property QGesture::gestureCancelPolicy
- \brief the policy for deciding what happens on accepting a gesture
-
- On accepting one gesture Qt can automatically cancel other gestures
- that belong to other targets. The policy is normally set to not cancel
- any other gestures and can be set to cancel all active gestures in the
- context. For example for all child widgets.
-*/
-
-/*!
- \enum QGesture::GestureCancelPolicy
-
- This enum describes how accepting a gesture can cancel other gestures
- automatically.
-
- \value CancelNone On accepting this gesture no other gestures will be affected.
-
- \value CancelAllInContext On accepting this gesture all gestures that are
- active in the context (respecting the Qt::GestureFlag that were specified
- when subscribed to the gesture) will be cancelled.
-*/
-
-void QGesture::setGestureCancelPolicy(GestureCancelPolicy policy)
-{
- Q_D(QGesture);
- d->gestureCancelPolicy = static_cast<uint>(policy);
-}
-
-QGesture::GestureCancelPolicy QGesture::gestureCancelPolicy() const
-{
- Q_D(const QGesture);
- return static_cast<GestureCancelPolicy>(d->gestureCancelPolicy);
-}
-
-/*!
- \class QPanGesture
- \since 4.6
- \brief The QPanGesture class describes a panning gesture made by the user.
- \ingroup gestures
-
- \image pangesture.png
-
- For an overview of gesture handling in Qt and information on using gestures
- in your applications, see the \l{Gestures Programming} document.
-
- \sa QPinchGesture, QSwipeGesture
-*/
-
-/*!
- \property QPanGesture::lastOffset
- \brief the last offset recorded for this gesture
-
- The last offset contains the change in position of the user's input as
- reported in the \l offset property when a previous gesture event was
- delivered for this gesture.
-
- If no previous event was delivered with information about this gesture
- (i.e., this gesture object contains information about the first movement
- in the gesture) then this property contains a zero size.
-*/
-
-/*!
- \property QPanGesture::offset
- \brief the total offset from the first input position to the current input
- position
-
- The offset measures the total change in position of the user's input
- covered by the gesture on the input device.
-*/
-
-/*!
- \property QPanGesture::delta
- \brief the offset from the previous input position to the current input
-
- This is essentially the same as the difference between offset() and
- lastOffset().
-*/
-
-/*!
- \property QPanGesture::acceleration
- \brief the acceleration in the motion of the touch point for this gesture
-*/
-
-/*!
- \property QPanGesture::horizontalVelocity
- \brief the horizontal component of the motion of the touch point for this
- gesture
- \since 4.7.1
- \internal
-
- \sa verticalVelocity, acceleration
-*/
-
-/*!
- \property QPanGesture::verticalVelocity
- \brief the vertical component of the motion of the touch point for this
- gesture
- \since 4.7.1
- \internal
-
- \sa horizontalVelocity, acceleration
-*/
-
-/*!
- \internal
-*/
-QPanGesture::QPanGesture(QObject *parent)
- : QGesture(*new QPanGesturePrivate, parent)
-{
- d_func()->gestureType = Qt::PanGesture;
-}
-
-
-QPointF QPanGesture::lastOffset() const
-{
- return d_func()->lastOffset;
-}
-
-QPointF QPanGesture::offset() const
-{
- return d_func()->offset;
-}
-
-QPointF QPanGesture::delta() const
-{
- Q_D(const QPanGesture);
- return d->offset - d->lastOffset;
-}
-
-qreal QPanGesture::acceleration() const
-{
- return d_func()->acceleration;
-}
-
-void QPanGesture::setLastOffset(const QPointF &value)
-{
- d_func()->lastOffset = value;
-}
-
-void QPanGesture::setOffset(const QPointF &value)
-{
- d_func()->offset = value;
-}
-
-void QPanGesture::setAcceleration(qreal value)
-{
- d_func()->acceleration = value;
-}
-
-/*!
- \class QPinchGesture
- \since 4.6
- \brief The QPinchGesture class describes a pinch gesture made by the user.
- \ingroup touch
- \ingroup gestures
-
- A pinch gesture is a form of touch user input in which the user typically
- touches two points on the input device with a thumb and finger, before moving
- them closer together or further apart to change the scale factor, zoom, or level
- of detail of the user interface.
-
- For an overview of gesture handling in Qt and information on using gestures
- in your applications, see the \l{Gestures Programming} document.
-
- \image pinchgesture.png
-
- Instead of repeatedly applying the same pinching gesture, the user may
- continue to touch the input device in one place, and apply a second touch
- to a new point, continuing the gesture. When this occurs, gesture events
- will continue to be delivered to the target object, containing an instance
- of QPinchGesture in the Qt::GestureUpdated state.
-
- \sa QPanGesture, QSwipeGesture
-*/
-
-/*!
- \enum QPinchGesture::ChangeFlag
-
- This enum describes the changes that can occur to the properties of
- the gesture object.
-
- \value ScaleFactorChanged The scale factor held by scaleFactor changed.
- \value RotationAngleChanged The rotation angle held by rotationAngle changed.
- \value CenterPointChanged The center point held by centerPoint changed.
-
- \sa changeFlags, totalChangeFlags
-*/
-
-/*!
- \property QPinchGesture::totalChangeFlags
- \brief the property of the gesture that has change
-
- This property indicates which of the other properties has changed since the
- gesture has started. You can use this information to determine which aspect
- of your user interface needs to be updated.
-
- \sa changeFlags, scaleFactor, rotationAngle, centerPoint
-*/
-
-/*!
- \property QPinchGesture::changeFlags
- \brief the property of the gesture that has changed in the current step
-
- This property indicates which of the other properties has changed since
- the previous gesture event included information about this gesture. You
- can use this information to determine which aspect of your user interface
- needs to be updated.
-
- \sa totalChangeFlags, scaleFactor, rotationAngle, centerPoint
-*/
-
-/*!
- \property QPinchGesture::totalScaleFactor
- \brief the total scale factor
-
- The total scale factor measures the total change in scale factor from the
- original value to the current scale factor.
-
- \sa scaleFactor, lastScaleFactor
-*/
-/*!
- \property QPinchGesture::lastScaleFactor
- \brief the last scale factor recorded for this gesture
-
- The last scale factor contains the scale factor reported in the
- \l scaleFactor property when a previous gesture event included
- information about this gesture.
-
- If no previous event was delivered with information about this gesture
- (i.e., this gesture object contains information about the first movement
- in the gesture) then this property contains zero.
-
- \sa scaleFactor, totalScaleFactor
-*/
-/*!
- \property QPinchGesture::scaleFactor
- \brief the current scale factor
-
- The scale factor measures the scale factor associated with the distance
- between two of the user's inputs on a touch device.
-
- \sa totalScaleFactor, lastScaleFactor
-*/
-
-/*!
- \property QPinchGesture::totalRotationAngle
- \brief the total angle covered by the gesture
-
- This total angle measures the complete angle covered by the gesture. Usually, this
- is equal to the value held by the \l rotationAngle property, except in the case where
- the user performs multiple rotations by removing and repositioning one of the touch
- points, as described above. In this case, the total angle will be the sum of the
- rotation angles for the multiple stages of the gesture.
-
- \sa rotationAngle, lastRotationAngle
-*/
-/*!
- \property QPinchGesture::lastRotationAngle
- \brief the last reported angle covered by the gesture motion
-
- The last rotation angle is the angle as reported in the \l rotationAngle property
- when a previous gesture event was delivered for this gesture.
-
- \sa rotationAngle, totalRotationAngle
-*/
-/*!
- \property QPinchGesture::rotationAngle
- \brief the angle covered by the gesture motion
-
- \sa totalRotationAngle, lastRotationAngle
-*/
-
-/*!
- \property QPinchGesture::startCenterPoint
- \brief the starting position of the center point
-
- \sa centerPoint, lastCenterPoint
-*/
-/*!
- \property QPinchGesture::lastCenterPoint
- \brief the last position of the center point recorded for this gesture
-
- \sa centerPoint, startCenterPoint
-*/
-/*!
- \property QPinchGesture::centerPoint
- \brief the current center point
-
- The center point is the midpoint between the two input points in the gesture.
-
- \sa startCenterPoint, lastCenterPoint
-*/
-
-/*!
- \internal
-*/
-QPinchGesture::QPinchGesture(QObject *parent)
- : QGesture(*new QPinchGesturePrivate, parent)
-{
- d_func()->gestureType = Qt::PinchGesture;
-}
-
-QPinchGesture::ChangeFlags QPinchGesture::totalChangeFlags() const
-{
- return d_func()->totalChangeFlags;
-}
-
-void QPinchGesture::setTotalChangeFlags(QPinchGesture::ChangeFlags value)
-{
- d_func()->totalChangeFlags = value;
-}
-
-QPinchGesture::ChangeFlags QPinchGesture::changeFlags() const
-{
- return d_func()->changeFlags;
-}
-
-void QPinchGesture::setChangeFlags(QPinchGesture::ChangeFlags value)
-{
- d_func()->changeFlags = value;
-}
-
-QPointF QPinchGesture::startCenterPoint() const
-{
- return d_func()->startCenterPoint;
-}
-
-QPointF QPinchGesture::lastCenterPoint() const
-{
- return d_func()->lastCenterPoint;
-}
-
-QPointF QPinchGesture::centerPoint() const
-{
- return d_func()->centerPoint;
-}
-
-void QPinchGesture::setStartCenterPoint(const QPointF &value)
-{
- d_func()->startCenterPoint = value;
-}
-
-void QPinchGesture::setLastCenterPoint(const QPointF &value)
-{
- d_func()->lastCenterPoint = value;
-}
-
-void QPinchGesture::setCenterPoint(const QPointF &value)
-{
- d_func()->centerPoint = value;
-}
-
-
-qreal QPinchGesture::totalScaleFactor() const
-{
- return d_func()->totalScaleFactor;
-}
-
-qreal QPinchGesture::lastScaleFactor() const
-{
- return d_func()->lastScaleFactor;
-}
-
-qreal QPinchGesture::scaleFactor() const
-{
- return d_func()->scaleFactor;
-}
-
-void QPinchGesture::setTotalScaleFactor(qreal value)
-{
- d_func()->totalScaleFactor = value;
-}
-
-void QPinchGesture::setLastScaleFactor(qreal value)
-{
- d_func()->lastScaleFactor = value;
-}
-
-void QPinchGesture::setScaleFactor(qreal value)
-{
- d_func()->scaleFactor = value;
-}
-
-
-qreal QPinchGesture::totalRotationAngle() const
-{
- return d_func()->totalRotationAngle;
-}
-
-qreal QPinchGesture::lastRotationAngle() const
-{
- return d_func()->lastRotationAngle;
-}
-
-qreal QPinchGesture::rotationAngle() const
-{
- return d_func()->rotationAngle;
-}
-
-void QPinchGesture::setTotalRotationAngle(qreal value)
-{
- d_func()->totalRotationAngle = value;
-}
-
-void QPinchGesture::setLastRotationAngle(qreal value)
-{
- d_func()->lastRotationAngle = value;
-}
-
-void QPinchGesture::setRotationAngle(qreal value)
-{
- d_func()->rotationAngle = value;
-}
-
-/*!
- \class QSwipeGesture
- \since 4.6
- \brief The QSwipeGesture class describes a swipe gesture made by the user.
- \ingroup gestures
-
- \image swipegesture.png
-
- For an overview of gesture handling in Qt and information on using gestures
- in your applications, see the \l{Gestures Programming} document.
-
- \sa QPanGesture, QPinchGesture
-*/
-
-/*!
- \enum QSwipeGesture::SwipeDirection
-
- This enum describes the possible directions for the gesture's motion
- along the horizontal and vertical axes.
-
- \value NoDirection The gesture had no motion associated with it on a particular axis.
- \value Left The gesture involved a horizontal motion to the left.
- \value Right The gesture involved a horizontal motion to the right.
- \value Up The gesture involved an upward vertical motion.
- \value Down The gesture involved a downward vertical motion.
-*/
-
-/*!
- \property QSwipeGesture::horizontalDirection
- \brief the horizontal direction of the gesture
-
- If the gesture has a horizontal component, the horizontal direction
- is either Left or Right; otherwise, it is NoDirection.
-
- \sa verticalDirection, swipeAngle
-*/
-
-/*!
- \property QSwipeGesture::verticalDirection
- \brief the vertical direction of the gesture
-
- If the gesture has a vertical component, the vertical direction
- is either Up or Down; otherwise, it is NoDirection.
-
- \sa horizontalDirection, swipeAngle
-*/
-
-/*!
- \property QSwipeGesture::swipeAngle
- \brief the angle of the motion associated with the gesture
-
- If the gesture has either a horizontal or vertical component, the
- swipe angle describes the angle between the direction of motion and the
- x-axis as defined using the standard widget
- \l{Coordinate System}{coordinate system}.
-
- \sa horizontalDirection, verticalDirection
-*/
-
-/*!
- \property QSwipeGesture::velocity
- \since 4.7.1
- \internal
-*/
-
-/*!
- \internal
-*/
-QSwipeGesture::QSwipeGesture(QObject *parent)
- : QGesture(*new QSwipeGesturePrivate, parent)
-{
- d_func()->gestureType = Qt::SwipeGesture;
-}
-
-QSwipeGesture::SwipeDirection QSwipeGesture::horizontalDirection() const
-{
- Q_D(const QSwipeGesture);
- if (d->swipeAngle < 0 || d->swipeAngle == 90 || d->swipeAngle == 270)
- return QSwipeGesture::NoDirection;
- else if (d->swipeAngle < 90 || d->swipeAngle > 270)
- return QSwipeGesture::Right;
- else
- return QSwipeGesture::Left;
-}
-
-QSwipeGesture::SwipeDirection QSwipeGesture::verticalDirection() const
-{
- Q_D(const QSwipeGesture);
- if (d->swipeAngle <= 0 || d->swipeAngle == 180)
- return QSwipeGesture::NoDirection;
- else if (d->swipeAngle < 180)
- return QSwipeGesture::Up;
- else
- return QSwipeGesture::Down;
-}
-
-qreal QSwipeGesture::swipeAngle() const
-{
- return d_func()->swipeAngle;
-}
-
-void QSwipeGesture::setSwipeAngle(qreal value)
-{
- d_func()->swipeAngle = value;
-}
-
-/*!
- \class QTapGesture
- \since 4.6
- \brief The QTapGesture class describes a tap gesture made by the user.
- \ingroup gestures
-
- For an overview of gesture handling in Qt and information on using gestures
- in your applications, see the \l{Gestures Programming} document.
-
- \sa QPanGesture, QPinchGesture
-*/
-
-/*!
- \property QTapGesture::position
- \brief the position of the tap
-*/
-
-/*!
- \internal
-*/
-QTapGesture::QTapGesture(QObject *parent)
- : QGesture(*new QTapGesturePrivate, parent)
-{
- d_func()->gestureType = Qt::TapGesture;
-}
-
-QPointF QTapGesture::position() const
-{
- return d_func()->position;
-}
-
-void QTapGesture::setPosition(const QPointF &value)
-{
- d_func()->position = value;
-}
-/*!
- \class QTapAndHoldGesture
- \since 4.6
- \brief The QTapAndHoldGesture class describes a tap-and-hold (aka LongTap)
- gesture made by the user.
- \ingroup gestures
-
- For an overview of gesture handling in Qt and information on using gestures
- in your applications, see the \l{Gestures Programming} document.
-
- \sa QPanGesture, QPinchGesture
-*/
-
-/*!
- \property QTapAndHoldGesture::position
- \brief the position of the tap
-*/
-
-/*!
- \internal
-*/
-QTapAndHoldGesture::QTapAndHoldGesture(QObject *parent)
- : QGesture(*new QTapAndHoldGesturePrivate, parent)
-{
- d_func()->gestureType = Qt::TapAndHoldGesture;
-}
-
-QPointF QTapAndHoldGesture::position() const
-{
- return d_func()->position;
-}
-
-void QTapAndHoldGesture::setPosition(const QPointF &value)
-{
- d_func()->position = value;
-}
-
-/*!
- Set the timeout, in milliseconds, before the gesture triggers.
-
- The recognizer will detect a touch down and and if \a msecs
- later the touch is still down, it will trigger the QTapAndHoldGesture.
- The default value is 700 milliseconds.
-*/
-// static
-void QTapAndHoldGesture::setTimeout(int msecs)
-{
- QTapAndHoldGesturePrivate::Timeout = msecs;
-}
-
-/*!
- Gets the timeout, in milliseconds, before the gesture triggers.
-
- The recognizer will detect a touch down and and if timeout()
- later the touch is still down, it will trigger the QTapAndHoldGesture.
- The default value is 700 milliseconds.
-*/
-// static
-int QTapAndHoldGesture::timeout()
-{
- return QTapAndHoldGesturePrivate::Timeout;
-}
-
-int QTapAndHoldGesturePrivate::Timeout = 700; // in ms
-
-QT_END_NAMESPACE
-
-#include <moc_qgesture.cpp>
-
-#endif // QT_NO_GESTURES
diff --git a/src/gui/kernel/qgesture.h b/src/gui/kernel/qgesture.h
deleted file mode 100644
index 5e6f026175..0000000000
--- a/src/gui/kernel/qgesture.h
+++ /dev/null
@@ -1,275 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGESTURE_H
-#define QGESTURE_H
-
-#include <QtCore/qobject.h>
-#include <QtCore/qlist.h>
-#include <QtCore/qdatetime.h>
-#include <QtCore/qpoint.h>
-#include <QtCore/qrect.h>
-#include <QtCore/qmetatype.h>
-
-#ifndef QT_NO_GESTURES
-
-QT_BEGIN_HEADER
-
-Q_DECLARE_METATYPE(Qt::GestureState)
-Q_DECLARE_METATYPE(Qt::GestureType)
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QGesturePrivate;
-class Q_GUI_EXPORT QGesture : public QObject
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QGesture)
-
- Q_PROPERTY(Qt::GestureState state READ state)
- Q_PROPERTY(Qt::GestureType gestureType READ gestureType)
- Q_PROPERTY(QGesture::GestureCancelPolicy gestureCancelPolicy READ gestureCancelPolicy WRITE setGestureCancelPolicy)
- Q_PROPERTY(QPointF hotSpot READ hotSpot WRITE setHotSpot RESET unsetHotSpot)
- Q_PROPERTY(bool hasHotSpot READ hasHotSpot)
-
-public:
- explicit QGesture(QObject *parent = 0);
- ~QGesture();
-
- Qt::GestureType gestureType() const;
-
- Qt::GestureState state() const;
-
- QPointF hotSpot() const;
- void setHotSpot(const QPointF &value);
- bool hasHotSpot() const;
- void unsetHotSpot();
-
- enum GestureCancelPolicy {
- CancelNone = 0,
- CancelAllInContext
- };
-
- void setGestureCancelPolicy(GestureCancelPolicy policy);
- GestureCancelPolicy gestureCancelPolicy() const;
-
-protected:
- QGesture(QGesturePrivate &dd, QObject *parent);
-
-private:
- friend class QGestureEvent;
- friend class QGestureRecognizer;
- friend class QGestureManager;
- friend class QGraphicsScenePrivate;
-};
-
-class QPanGesturePrivate;
-class Q_GUI_EXPORT QPanGesture : public QGesture
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QPanGesture)
-
- Q_PROPERTY(QPointF lastOffset READ lastOffset WRITE setLastOffset)
- Q_PROPERTY(QPointF offset READ offset WRITE setOffset)
- Q_PROPERTY(QPointF delta READ delta STORED false)
- Q_PROPERTY(qreal acceleration READ acceleration WRITE setAcceleration)
- Q_PRIVATE_PROPERTY(QPanGesture::d_func(), qreal horizontalVelocity READ horizontalVelocity WRITE setHorizontalVelocity)
- Q_PRIVATE_PROPERTY(QPanGesture::d_func(), qreal verticalVelocity READ verticalVelocity WRITE setVerticalVelocity)
-
-public:
- QPanGesture(QObject *parent = 0);
-
- QPointF lastOffset() const;
- QPointF offset() const;
- QPointF delta() const;
- qreal acceleration() const;
-
- void setLastOffset(const QPointF &value);
- void setOffset(const QPointF &value);
- void setAcceleration(qreal value);
-
- friend class QPanGestureRecognizer;
- friend class QWinNativePanGestureRecognizer;
-};
-
-class QPinchGesturePrivate;
-class Q_GUI_EXPORT QPinchGesture : public QGesture
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QPinchGesture)
- Q_FLAGS(ChangeFlags ChangeFlag)
-
-public:
- enum ChangeFlag {
- ScaleFactorChanged = 0x1,
- RotationAngleChanged = 0x2,
- CenterPointChanged = 0x4
- };
- Q_DECLARE_FLAGS(ChangeFlags, ChangeFlag)
-
- Q_PROPERTY(ChangeFlags totalChangeFlags READ totalChangeFlags WRITE setTotalChangeFlags)
- Q_PROPERTY(ChangeFlags changeFlags READ changeFlags WRITE setChangeFlags)
-
- Q_PROPERTY(qreal totalScaleFactor READ totalScaleFactor WRITE setTotalScaleFactor)
- Q_PROPERTY(qreal lastScaleFactor READ lastScaleFactor WRITE setLastScaleFactor)
- Q_PROPERTY(qreal scaleFactor READ scaleFactor WRITE setScaleFactor)
-
- Q_PROPERTY(qreal totalRotationAngle READ totalRotationAngle WRITE setTotalRotationAngle)
- Q_PROPERTY(qreal lastRotationAngle READ lastRotationAngle WRITE setLastRotationAngle)
- Q_PROPERTY(qreal rotationAngle READ rotationAngle WRITE setRotationAngle)
-
- Q_PROPERTY(QPointF startCenterPoint READ startCenterPoint WRITE setStartCenterPoint)
- Q_PROPERTY(QPointF lastCenterPoint READ lastCenterPoint WRITE setLastCenterPoint)
- Q_PROPERTY(QPointF centerPoint READ centerPoint WRITE setCenterPoint)
-
-public:
- QPinchGesture(QObject *parent = 0);
-
- ChangeFlags totalChangeFlags() const;
- void setTotalChangeFlags(ChangeFlags value);
-
- ChangeFlags changeFlags() const;
- void setChangeFlags(ChangeFlags value);
-
- QPointF startCenterPoint() const;
- QPointF lastCenterPoint() const;
- QPointF centerPoint() const;
- void setStartCenterPoint(const QPointF &value);
- void setLastCenterPoint(const QPointF &value);
- void setCenterPoint(const QPointF &value);
-
- qreal totalScaleFactor() const;
- qreal lastScaleFactor() const;
- qreal scaleFactor() const;
- void setTotalScaleFactor(qreal value);
- void setLastScaleFactor(qreal value);
- void setScaleFactor(qreal value);
-
- qreal totalRotationAngle() const;
- qreal lastRotationAngle() const;
- qreal rotationAngle() const;
- void setTotalRotationAngle(qreal value);
- void setLastRotationAngle(qreal value);
- void setRotationAngle(qreal value);
-
- friend class QPinchGestureRecognizer;
-};
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QPinchGesture::ChangeFlags)
-
-QT_END_NAMESPACE
-
-Q_DECLARE_METATYPE(QPinchGesture::ChangeFlags)
-
-QT_BEGIN_NAMESPACE
-
-class QSwipeGesturePrivate;
-class Q_GUI_EXPORT QSwipeGesture : public QGesture
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QSwipeGesture)
- Q_ENUMS(SwipeDirection)
-
- Q_PROPERTY(SwipeDirection horizontalDirection READ horizontalDirection STORED false)
- Q_PROPERTY(SwipeDirection verticalDirection READ verticalDirection STORED false)
- Q_PROPERTY(qreal swipeAngle READ swipeAngle WRITE setSwipeAngle)
- Q_PRIVATE_PROPERTY(QSwipeGesture::d_func(), qreal velocity READ velocity WRITE setVelocity)
-
-public:
- enum SwipeDirection { NoDirection, Left, Right, Up, Down };
- QSwipeGesture(QObject *parent = 0);
-
- SwipeDirection horizontalDirection() const;
- SwipeDirection verticalDirection() const;
-
- qreal swipeAngle() const;
- void setSwipeAngle(qreal value);
-
- friend class QSwipeGestureRecognizer;
-};
-
-class QTapGesturePrivate;
-class Q_GUI_EXPORT QTapGesture : public QGesture
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QTapGesture)
-
- Q_PROPERTY(QPointF position READ position WRITE setPosition)
-
-public:
- QTapGesture(QObject *parent = 0);
-
- QPointF position() const;
- void setPosition(const QPointF &pos);
-
- friend class QTapGestureRecognizer;
-};
-
-class QTapAndHoldGesturePrivate;
-class Q_GUI_EXPORT QTapAndHoldGesture : public QGesture
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QTapAndHoldGesture)
-
- Q_PROPERTY(QPointF position READ position WRITE setPosition)
-
-public:
- QTapAndHoldGesture(QObject *parent = 0);
-
- QPointF position() const;
- void setPosition(const QPointF &pos);
-
- static void setTimeout(int msecs);
- static int timeout();
-
- friend class QTapAndHoldGestureRecognizer;
-};
-
-QT_END_NAMESPACE
-
-Q_DECLARE_METATYPE(QGesture::GestureCancelPolicy)
-QT_END_HEADER
-
-#endif // QT_NO_GESTURES
-
-#endif // QGESTURE_H
diff --git a/src/gui/kernel/qgesture_p.h b/src/gui/kernel/qgesture_p.h
deleted file mode 100644
index 7a3e0726d7..0000000000
--- a/src/gui/kernel/qgesture_p.h
+++ /dev/null
@@ -1,197 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGESTURE_P_H
-#define QGESTURE_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qrect.h"
-#include "qpoint.h"
-#include "qgesture.h"
-#include "qelapsedtimer.h"
-#include "private/qobject_p.h"
-
-#ifndef QT_NO_GESTURES
-
-QT_BEGIN_NAMESPACE
-
-class QGesturePrivate : public QObjectPrivate
-{
- Q_DECLARE_PUBLIC(QGesture)
-
-public:
- QGesturePrivate()
- : gestureType(Qt::CustomGesture), state(Qt::NoGesture),
- isHotSpotSet(false), gestureCancelPolicy(0)
- {
- }
-
- Qt::GestureType gestureType;
- Qt::GestureState state;
- QPointF hotSpot;
- QPointF sceneHotSpot;
- uint isHotSpotSet : 1;
- uint gestureCancelPolicy : 2;
-};
-
-class QPanGesturePrivate : public QGesturePrivate
-{
- Q_DECLARE_PUBLIC(QPanGesture)
-
-public:
- QPanGesturePrivate()
- : acceleration(0), xVelocity(0), yVelocity(0)
- {
- }
-
- qreal horizontalVelocity() const { return xVelocity; }
- void setHorizontalVelocity(qreal value) { xVelocity = value; }
- qreal verticalVelocity() const { return yVelocity; }
- void setVerticalVelocity(qreal value) { yVelocity = value; }
-
- QPointF lastOffset;
- QPointF offset;
- QPoint startPosition;
- qreal acceleration;
- qreal xVelocity;
- qreal yVelocity;
-};
-
-class QPinchGesturePrivate : public QGesturePrivate
-{
- Q_DECLARE_PUBLIC(QPinchGesture)
-
-public:
- QPinchGesturePrivate()
- : totalChangeFlags(0), changeFlags(0),
- totalScaleFactor(1), lastScaleFactor(1), scaleFactor(1),
- totalRotationAngle(0), lastRotationAngle(0), rotationAngle(0),
- isNewSequence(true)
- {
- }
-
- QPinchGesture::ChangeFlags totalChangeFlags;
- QPinchGesture::ChangeFlags changeFlags;
-
- QPointF startCenterPoint;
- QPointF lastCenterPoint;
- QPointF centerPoint;
-
- qreal totalScaleFactor;
- qreal lastScaleFactor;
- qreal scaleFactor;
-
- qreal totalRotationAngle;
- qreal lastRotationAngle;
- qreal rotationAngle;
-
- bool isNewSequence;
- QPointF startPosition[2];
-};
-
-class QSwipeGesturePrivate : public QGesturePrivate
-{
- Q_DECLARE_PUBLIC(QSwipeGesture)
-
-public:
- QSwipeGesturePrivate()
- : horizontalDirection(QSwipeGesture::NoDirection),
- verticalDirection(QSwipeGesture::NoDirection),
- swipeAngle(0),
- started(false), velocityValue(0)
- {
- }
-
- qreal velocity() const { return velocityValue; }
- void setVelocity(qreal value) { velocityValue = value; }
-
- QSwipeGesture::SwipeDirection horizontalDirection;
- QSwipeGesture::SwipeDirection verticalDirection;
- qreal swipeAngle;
-
- QPoint lastPositions[3];
- bool started;
- qreal velocityValue;
- QElapsedTimer time;
-};
-
-class QTapGesturePrivate : public QGesturePrivate
-{
- Q_DECLARE_PUBLIC(QTapGesture)
-
-public:
- QTapGesturePrivate()
- {
- }
-
- QPointF position;
-};
-
-class QTapAndHoldGesturePrivate : public QGesturePrivate
-{
- Q_DECLARE_PUBLIC(QTapAndHoldGesture)
-
-public:
- QTapAndHoldGesturePrivate()
- : timerId(0)
- {
- }
-
- QPointF position;
- int timerId;
- static int Timeout;
-};
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_GESTURES
-
-#endif // QGESTURE_P_H
diff --git a/src/gui/kernel/qgesturemanager.cpp b/src/gui/kernel/qgesturemanager.cpp
deleted file mode 100644
index 868387d77f..0000000000
--- a/src/gui/kernel/qgesturemanager.cpp
+++ /dev/null
@@ -1,720 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "private/qgesturemanager_p.h"
-#include "private/qstandardgestures_p.h"
-#include "private/qwidget_p.h"
-#include "private/qgesture_p.h"
-#include "private/qgraphicsitem_p.h"
-#include "private/qevent_p.h"
-#include "private/qapplication_p.h"
-#include "qgesture.h"
-#include "qevent.h"
-#include "qgraphicsitem.h"
-
-#ifdef Q_WS_MAC
-#include "qmacgesturerecognizer_mac_p.h"
-#endif
-#if defined(Q_OS_WIN) && !defined(QT_NO_NATIVE_GESTURES)
-#include "qwinnativepangesturerecognizer_win_p.h"
-#endif
-
-#include "qdebug.h"
-
-// #define GESTURE_DEBUG
-#ifndef GESTURE_DEBUG
-# define DEBUG if (0) qDebug
-#else
-# define DEBUG qDebug
-#endif
-
-#ifndef QT_NO_GESTURES
-
-QT_BEGIN_NAMESPACE
-
-QGestureManager::QGestureManager(QObject *parent)
- : QObject(parent), state(NotGesture), m_lastCustomGestureId(Qt::CustomGesture)
-{
- qRegisterMetaType<Qt::GestureState>();
-
-#if defined(Q_WS_MAC)
- registerGestureRecognizer(new QMacSwipeGestureRecognizer);
- registerGestureRecognizer(new QMacPinchGestureRecognizer);
- #if defined(QT_MAC_USE_COCOA)
- registerGestureRecognizer(new QMacPanGestureRecognizer);
- #endif
-#else
- registerGestureRecognizer(new QPanGestureRecognizer);
- registerGestureRecognizer(new QPinchGestureRecognizer);
- registerGestureRecognizer(new QSwipeGestureRecognizer);
- registerGestureRecognizer(new QTapGestureRecognizer);
-#endif
-#if defined(Q_OS_WIN)
- #if !defined(QT_NO_NATIVE_GESTURES)
- if (QApplicationPrivate::HasTouchSupport)
- registerGestureRecognizer(new QWinNativePanGestureRecognizer);
- #endif
-#else
- registerGestureRecognizer(new QTapAndHoldGestureRecognizer);
-#endif
-}
-
-QGestureManager::~QGestureManager()
-{
- qDeleteAll(m_recognizers.values());
- foreach (QGestureRecognizer *recognizer, m_obsoleteGestures.keys()) {
- qDeleteAll(m_obsoleteGestures.value(recognizer));
- delete recognizer;
- }
- m_obsoleteGestures.clear();
-}
-
-Qt::GestureType QGestureManager::registerGestureRecognizer(QGestureRecognizer *recognizer)
-{
- QGesture *dummy = recognizer->create(0);
- if (!dummy) {
- qWarning("QGestureManager::registerGestureRecognizer: "
- "the recognizer fails to create a gesture object, skipping registration.");
- return Qt::GestureType(0);
- }
- Qt::GestureType type = dummy->gestureType();
- if (type == Qt::CustomGesture) {
- // generate a new custom gesture id
- ++m_lastCustomGestureId;
- type = Qt::GestureType(m_lastCustomGestureId);
- }
- m_recognizers.insertMulti(type, recognizer);
- delete dummy;
- return type;
-}
-
-void QGestureManager::unregisterGestureRecognizer(Qt::GestureType type)
-{
- QList<QGestureRecognizer *> list = m_recognizers.values(type);
- while (QGestureRecognizer *recognizer = m_recognizers.take(type)) {
- if (!m_obsoleteGestures.contains(recognizer)) {
- // inserting even an empty QSet will cause the recognizer to be deleted on destruction of the manager
- m_obsoleteGestures.insert(recognizer, QSet<QGesture *>());
- }
- }
- foreach (QGesture *g, m_gestureToRecognizer.keys()) {
- QGestureRecognizer *recognizer = m_gestureToRecognizer.value(g);
- if (list.contains(recognizer)) {
- m_deletedRecognizers.insert(g, recognizer);
- }
- }
-
- QMap<ObjectGesture, QList<QGesture *> >::const_iterator iter = m_objectGestures.begin();
- while (iter != m_objectGestures.end()) {
- ObjectGesture objectGesture = iter.key();
- if (objectGesture.gesture == type) {
- foreach (QGesture *g, iter.value()) {
- if (QGestureRecognizer *recognizer = m_gestureToRecognizer.value(g)) {
- m_gestureToRecognizer.remove(g);
- m_obsoleteGestures[recognizer].insert(g);
- }
- }
- }
- ++iter;
- }
-}
-
-void QGestureManager::cleanupCachedGestures(QObject *target, Qt::GestureType type)
-{
- QMap<ObjectGesture, QList<QGesture *> >::Iterator iter = m_objectGestures.begin();
- while (iter != m_objectGestures.end()) {
- ObjectGesture objectGesture = iter.key();
- if (objectGesture.gesture == type && target == objectGesture.object) {
- QSet<QGesture *> gestures = iter.value().toSet();
- for (QHash<QGestureRecognizer *, QSet<QGesture *> >::iterator
- it = m_obsoleteGestures.begin(), e = m_obsoleteGestures.end(); it != e; ++it) {
- it.value() -= gestures;
- }
- foreach (QGesture *g, gestures) {
- m_deletedRecognizers.remove(g);
- m_gestureToRecognizer.remove(g);
- m_maybeGestures.remove(g);
- m_activeGestures.remove(g);
- m_gestureOwners.remove(g);
- m_gestureTargets.remove(g);
- m_gesturesToDelete.insert(g);
- }
-
- iter = m_objectGestures.erase(iter);
- } else {
- ++iter;
- }
- }
-}
-
-// get or create a QGesture object that will represent the state for a given object, used by the recognizer
-QGesture *QGestureManager::getState(QObject *object, QGestureRecognizer *recognizer, Qt::GestureType type)
-{
- // if the widget is being deleted we should be careful not to
- // create a new state, as it will create QWeakPointer which doesn't work
- // from the destructor.
- if (object->isWidgetType()) {
- if (static_cast<QWidget *>(object)->d_func()->data.in_destructor)
- return 0;
- } else if (QGesture *g = qobject_cast<QGesture *>(object)) {
- return g;
-#ifndef QT_NO_GRAPHICSVIEW
- } else {
- Q_ASSERT(qobject_cast<QGraphicsObject *>(object));
- QGraphicsObject *graphicsObject = static_cast<QGraphicsObject *>(object);
- if (graphicsObject->QGraphicsItem::d_func()->inDestructor)
- return 0;
-#endif
- }
-
- // check if the QGesture for this recognizer has already been created
- foreach (QGesture *state, m_objectGestures.value(QGestureManager::ObjectGesture(object, type))) {
- if (m_gestureToRecognizer.value(state) == recognizer)
- return state;
- }
-
- Q_ASSERT(recognizer);
- QGesture *state = recognizer->create(object);
- if (!state)
- return 0;
- state->setParent(this);
- if (state->gestureType() == Qt::CustomGesture) {
- // if the recognizer didn't fill in the gesture type, then this
- // is a custom gesture with autogenerated id and we fill it.
- state->d_func()->gestureType = type;
-#if defined(GESTURE_DEBUG)
- state->setObjectName(QString::number((int)type));
-#endif
- }
- m_objectGestures[QGestureManager::ObjectGesture(object, type)].append(state);
- m_gestureToRecognizer[state] = recognizer;
- m_gestureOwners[state] = object;
-
- return state;
-}
-
-bool QGestureManager::filterEventThroughContexts(const QMultiMap<QObject *,
- Qt::GestureType> &contexts,
- QEvent *event)
-{
- QSet<QGesture *> triggeredGestures;
- QSet<QGesture *> finishedGestures;
- QSet<QGesture *> newMaybeGestures;
- QSet<QGesture *> notGestures;
-
- // TODO: sort contexts by the gesture type and check if one of the contexts
- // is already active.
-
- bool consumeEventHint = false;
-
- // filter the event through recognizers
- typedef QMultiMap<QObject *, Qt::GestureType>::const_iterator ContextIterator;
- ContextIterator contextEnd = contexts.end();
- for (ContextIterator context = contexts.begin(); context != contextEnd; ++context) {
- Qt::GestureType gestureType = context.value();
- QMap<Qt::GestureType, QGestureRecognizer *>::const_iterator
- typeToRecognizerIterator = m_recognizers.lowerBound(gestureType),
- typeToRecognizerEnd = m_recognizers.upperBound(gestureType);
- for (; typeToRecognizerIterator != typeToRecognizerEnd; ++typeToRecognizerIterator) {
- QGestureRecognizer *recognizer = typeToRecognizerIterator.value();
- QObject *target = context.key();
- QGesture *state = getState(target, recognizer, gestureType);
- if (!state)
- continue;
- QGestureRecognizer::Result recognizerResult = recognizer->recognize(state, target, event);
- QGestureRecognizer::Result recognizerState = recognizerResult & QGestureRecognizer::ResultState_Mask;
- QGestureRecognizer::Result resultHint = recognizerResult & QGestureRecognizer::ResultHint_Mask;
- if (recognizerState == QGestureRecognizer::TriggerGesture) {
- DEBUG() << "QGestureManager:Recognizer: gesture triggered: " << state;
- triggeredGestures << state;
- } else if (recognizerState == QGestureRecognizer::FinishGesture) {
- DEBUG() << "QGestureManager:Recognizer: gesture finished: " << state;
- finishedGestures << state;
- } else if (recognizerState == QGestureRecognizer::MayBeGesture) {
- DEBUG() << "QGestureManager:Recognizer: maybe gesture: " << state;
- newMaybeGestures << state;
- } else if (recognizerState == QGestureRecognizer::CancelGesture) {
- DEBUG() << "QGestureManager:Recognizer: not gesture: " << state;
- notGestures << state;
- } else if (recognizerState == QGestureRecognizer::Ignore) {
- DEBUG() << "QGestureManager:Recognizer: ignored the event: " << state;
- } else {
- DEBUG() << "QGestureManager:Recognizer: hm, lets assume the recognizer"
- << "ignored the event: " << state;
- }
- if (resultHint & QGestureRecognizer::ConsumeEventHint) {
- DEBUG() << "QGestureManager: we were asked to consume the event: "
- << state;
- consumeEventHint = true;
- }
- }
- }
- if (triggeredGestures.isEmpty() && finishedGestures.isEmpty()
- && newMaybeGestures.isEmpty() && notGestures.isEmpty())
- return consumeEventHint;
-
- QSet<QGesture *> startedGestures = triggeredGestures - m_activeGestures;
- triggeredGestures &= m_activeGestures;
-
- // check if a running gesture switched back to maybe state
- QSet<QGesture *> activeToMaybeGestures = m_activeGestures & newMaybeGestures;
-
- // check if a maybe gesture switched to canceled - reset it but don't send an event
- QSet<QGesture *> maybeToCanceledGestures = m_maybeGestures & notGestures;
-
- // check if a running gesture switched back to not gesture state,
- // i.e. were canceled
- QSet<QGesture *> canceledGestures = m_activeGestures & notGestures;
-
- // new gestures in maybe state
- m_maybeGestures += newMaybeGestures;
-
- // gestures that were in maybe state
- QSet<QGesture *> notMaybeGestures = (startedGestures | triggeredGestures
- | finishedGestures | canceledGestures
- | notGestures);
- m_maybeGestures -= notMaybeGestures;
-
- Q_ASSERT((startedGestures & finishedGestures).isEmpty());
- Q_ASSERT((startedGestures & newMaybeGestures).isEmpty());
- Q_ASSERT((startedGestures & canceledGestures).isEmpty());
- Q_ASSERT((finishedGestures & newMaybeGestures).isEmpty());
- Q_ASSERT((finishedGestures & canceledGestures).isEmpty());
- Q_ASSERT((canceledGestures & newMaybeGestures).isEmpty());
-
- QSet<QGesture *> notStarted = finishedGestures - m_activeGestures;
- if (!notStarted.isEmpty()) {
- // there are some gestures that claim to be finished, but never started.
- // probably those are "singleshot" gestures so we'll fake the started state.
- foreach (QGesture *gesture, notStarted)
- gesture->d_func()->state = Qt::GestureStarted;
- QSet<QGesture *> undeliveredGestures;
- deliverEvents(notStarted, &undeliveredGestures);
- finishedGestures -= undeliveredGestures;
- }
-
- m_activeGestures += startedGestures;
- // sanity check: all triggered gestures should already be in active gestures list
- Q_ASSERT((m_activeGestures & triggeredGestures).size() == triggeredGestures.size());
- m_activeGestures -= finishedGestures;
- m_activeGestures -= activeToMaybeGestures;
- m_activeGestures -= canceledGestures;
-
- // set the proper gesture state on each gesture
- foreach (QGesture *gesture, startedGestures)
- gesture->d_func()->state = Qt::GestureStarted;
- foreach (QGesture *gesture, triggeredGestures)
- gesture->d_func()->state = Qt::GestureUpdated;
- foreach (QGesture *gesture, finishedGestures)
- gesture->d_func()->state = Qt::GestureFinished;
- foreach (QGesture *gesture, canceledGestures)
- gesture->d_func()->state = Qt::GestureCanceled;
- foreach (QGesture *gesture, activeToMaybeGestures)
- gesture->d_func()->state = Qt::GestureFinished;
-
- if (!m_activeGestures.isEmpty() || !m_maybeGestures.isEmpty() ||
- !startedGestures.isEmpty() || !triggeredGestures.isEmpty() ||
- !finishedGestures.isEmpty() || !canceledGestures.isEmpty()) {
- DEBUG() << "QGestureManager::filterEventThroughContexts:"
- << "\n\tactiveGestures:" << m_activeGestures
- << "\n\tmaybeGestures:" << m_maybeGestures
- << "\n\tstarted:" << startedGestures
- << "\n\ttriggered:" << triggeredGestures
- << "\n\tfinished:" << finishedGestures
- << "\n\tcanceled:" << canceledGestures
- << "\n\tmaybe-canceled:" << maybeToCanceledGestures;
- }
-
- QSet<QGesture *> undeliveredGestures;
- deliverEvents(startedGestures+triggeredGestures+finishedGestures+canceledGestures,
- &undeliveredGestures);
-
- foreach (QGesture *g, startedGestures) {
- if (undeliveredGestures.contains(g))
- continue;
- if (g->gestureCancelPolicy() == QGesture::CancelAllInContext) {
- DEBUG() << "lets try to cancel some";
- // find gestures in context in Qt::GestureStarted or Qt::GestureUpdated state and cancel them
- cancelGesturesForChildren(g);
- }
- }
-
- m_activeGestures -= undeliveredGestures;
-
- // reset gestures that ended
- QSet<QGesture *> endedGestures =
- finishedGestures + canceledGestures + undeliveredGestures + maybeToCanceledGestures;
- foreach (QGesture *gesture, endedGestures) {
- recycle(gesture);
- m_gestureTargets.remove(gesture);
- }
-
- //Clean up the Gestures
- qDeleteAll(m_gesturesToDelete);
- m_gesturesToDelete.clear();
-
- return consumeEventHint;
-}
-
-// Cancel all gestures of children of the widget that original is associated with
-void QGestureManager::cancelGesturesForChildren(QGesture *original)
-{
- Q_ASSERT(original);
- QWidget *originatingWidget = m_gestureTargets.value(original);
- Q_ASSERT(originatingWidget);
-
- // iterate over all active gestures and all maybe gestures
- // for each find the owner
- // if the owner is part of our sub-hierarchy, cancel it.
-
- QSet<QGesture*> cancelledGestures;
- QSet<QGesture*>::Iterator iter = m_activeGestures.begin();
- while (iter != m_activeGestures.end()) {
- QWidget *widget = m_gestureTargets.value(*iter);
- // note that we don't touch the gestures for our originatingWidget
- if (widget != originatingWidget && originatingWidget->isAncestorOf(widget)) {
- DEBUG() << " found a gesture to cancel" << (*iter);
- (*iter)->d_func()->state = Qt::GestureCanceled;
- cancelledGestures << *iter;
- iter = m_activeGestures.erase(iter);
- } else {
- ++iter;
- }
- }
-
- // TODO handle 'maybe' gestures too
-
- // sort them per target widget by cherry picking from almostCanceledGestures and delivering
- QSet<QGesture *> almostCanceledGestures = cancelledGestures;
- while (!almostCanceledGestures.isEmpty()) {
- QWidget *target = 0;
- QSet<QGesture*> gestures;
- iter = almostCanceledGestures.begin();
- // sort per target widget
- while (iter != almostCanceledGestures.end()) {
- QWidget *widget = m_gestureTargets.value(*iter);
- if (target == 0)
- target = widget;
- if (target == widget) {
- gestures << *iter;
- iter = almostCanceledGestures.erase(iter);
- } else {
- ++iter;
- }
- }
- Q_ASSERT(target);
-
- QSet<QGesture*> undeliveredGestures;
- deliverEvents(gestures, &undeliveredGestures);
- }
-
- for (iter = cancelledGestures.begin(); iter != cancelledGestures.end(); ++iter)
- recycle(*iter);
-}
-
-void QGestureManager::cleanupGesturesForRemovedRecognizer(QGesture *gesture)
-{
- QGestureRecognizer *recognizer = m_deletedRecognizers.value(gesture);
- if(!recognizer) //The Gesture is removed while in the even loop, so the recognizers for this gestures was removed
- return;
- m_deletedRecognizers.remove(gesture);
- if (m_deletedRecognizers.keys(recognizer).isEmpty()) {
- // no more active gestures, cleanup!
- qDeleteAll(m_obsoleteGestures.value(recognizer));
- m_obsoleteGestures.remove(recognizer);
- delete recognizer;
- }
-}
-
-// return true if accepted (consumed)
-bool QGestureManager::filterEvent(QWidget *receiver, QEvent *event)
-{
- QMap<Qt::GestureType, int> types;
- QMultiMap<QObject *, Qt::GestureType> contexts;
- QWidget *w = receiver;
- typedef QMap<Qt::GestureType, Qt::GestureFlags>::const_iterator ContextIterator;
- if (!w->d_func()->gestureContext.isEmpty()) {
- for(ContextIterator it = w->d_func()->gestureContext.begin(),
- e = w->d_func()->gestureContext.end(); it != e; ++it) {
- types.insert(it.key(), 0);
- contexts.insertMulti(w, it.key());
- }
- }
- // find all gesture contexts for the widget tree
- w = w->isWindow() ? 0 : w->parentWidget();
- while (w)
- {
- for (ContextIterator it = w->d_func()->gestureContext.begin(),
- e = w->d_func()->gestureContext.end(); it != e; ++it) {
- if (!(it.value() & Qt::DontStartGestureOnChildren)) {
- if (!types.contains(it.key())) {
- types.insert(it.key(), 0);
- contexts.insertMulti(w, it.key());
- }
- }
- }
- if (w->isWindow())
- break;
- w = w->parentWidget();
- }
- return contexts.isEmpty() ? false : filterEventThroughContexts(contexts, event);
-}
-
-#ifndef QT_NO_GRAPHICSVIEW
-bool QGestureManager::filterEvent(QGraphicsObject *receiver, QEvent *event)
-{
- QMap<Qt::GestureType, int> types;
- QMultiMap<QObject *, Qt::GestureType> contexts;
- QGraphicsObject *item = receiver;
- if (!item->QGraphicsItem::d_func()->gestureContext.isEmpty()) {
- typedef QMap<Qt::GestureType, Qt::GestureFlags>::const_iterator ContextIterator;
- for(ContextIterator it = item->QGraphicsItem::d_func()->gestureContext.begin(),
- e = item->QGraphicsItem::d_func()->gestureContext.end(); it != e; ++it) {
- types.insert(it.key(), 0);
- contexts.insertMulti(item, it.key());
- }
- }
- // find all gesture contexts for the graphics object tree
- item = item->parentObject();
- while (item)
- {
- typedef QMap<Qt::GestureType, Qt::GestureFlags>::const_iterator ContextIterator;
- for (ContextIterator it = item->QGraphicsItem::d_func()->gestureContext.begin(),
- e = item->QGraphicsItem::d_func()->gestureContext.end(); it != e; ++it) {
- if (!(it.value() & Qt::DontStartGestureOnChildren)) {
- if (!types.contains(it.key())) {
- types.insert(it.key(), 0);
- contexts.insertMulti(item, it.key());
- }
- }
- }
- item = item->parentObject();
- }
- return contexts.isEmpty() ? false : filterEventThroughContexts(contexts, event);
-}
-#endif
-
-bool QGestureManager::filterEvent(QObject *receiver, QEvent *event)
-{
- if (!m_gestureToRecognizer.contains(static_cast<QGesture *>(receiver)))
- return false;
- QGesture *state = static_cast<QGesture *>(receiver);
- QMultiMap<QObject *, Qt::GestureType> contexts;
- contexts.insert(state, state->gestureType());
- return filterEventThroughContexts(contexts, event);
-}
-
-void QGestureManager::getGestureTargets(const QSet<QGesture*> &gestures,
- QMap<QWidget *, QList<QGesture *> > *conflicts,
- QMap<QWidget *, QList<QGesture *> > *normal)
-{
- typedef QHash<Qt::GestureType, QHash<QWidget *, QGesture *> > GestureByTypes;
- GestureByTypes gestureByTypes;
-
- // sort gestures by types
- foreach (QGesture *gesture, gestures) {
- QWidget *receiver = m_gestureTargets.value(gesture, 0);
- Q_ASSERT(receiver);
- gestureByTypes[gesture->gestureType()].insert(receiver, gesture);
- }
-
- // for each gesture type
- foreach (Qt::GestureType type, gestureByTypes.keys()) {
- QHash<QWidget *, QGesture *> gestures = gestureByTypes.value(type);
- foreach (QWidget *widget, gestures.keys()) {
- QWidget *w = widget->parentWidget();
- while (w) {
- QMap<Qt::GestureType, Qt::GestureFlags>::const_iterator it
- = w->d_func()->gestureContext.find(type);
- if (it != w->d_func()->gestureContext.end()) {
- // i.e. 'w' listens to gesture 'type'
- if (!(it.value() & Qt::DontStartGestureOnChildren) && w != widget) {
- // conflicting gesture!
- (*conflicts)[widget].append(gestures[widget]);
- break;
- }
- }
- if (w->isWindow()) {
- w = 0;
- break;
- }
- w = w->parentWidget();
- }
- if (!w)
- (*normal)[widget].append(gestures[widget]);
- }
- }
-}
-
-void QGestureManager::deliverEvents(const QSet<QGesture *> &gestures,
- QSet<QGesture *> *undeliveredGestures)
-{
- if (gestures.isEmpty())
- return;
-
- typedef QMap<QWidget *, QList<QGesture *> > GesturesPerWidget;
- GesturesPerWidget conflictedGestures;
- GesturesPerWidget normalStartedGestures;
-
- QSet<QGesture *> startedGestures;
- // first figure out the initial receivers of gestures
- for (QSet<QGesture *>::const_iterator it = gestures.begin(),
- e = gestures.end(); it != e; ++it) {
- QGesture *gesture = *it;
- QWidget *target = m_gestureTargets.value(gesture, 0);
- if (!target) {
- // the gesture has just started and doesn't have a target yet.
- Q_ASSERT(gesture->state() == Qt::GestureStarted);
- if (gesture->hasHotSpot()) {
- // guess the target widget using the hotspot of the gesture
- QPoint pt = gesture->hotSpot().toPoint();
- if (QWidget *topLevel = qApp->topLevelAt(pt)) {
- QWidget *child = topLevel->childAt(topLevel->mapFromGlobal(pt));
- target = child ? child : topLevel;
- }
- } else {
- // or use the context of the gesture
- QObject *context = m_gestureOwners.value(gesture, 0);
- if (context->isWidgetType())
- target = static_cast<QWidget *>(context);
- }
- if (target)
- m_gestureTargets.insert(gesture, target);
- }
-
- Qt::GestureType gestureType = gesture->gestureType();
- Q_ASSERT(gestureType != Qt::CustomGesture);
- Q_UNUSED(gestureType);
-
- if (target) {
- if (gesture->state() == Qt::GestureStarted) {
- startedGestures.insert(gesture);
- } else {
- normalStartedGestures[target].append(gesture);
- }
- } else {
- DEBUG() << "QGestureManager::deliverEvent: could not find the target for gesture"
- << gesture->gestureType();
- qWarning("QGestureManager::deliverEvent: could not find the target for gesture");
- undeliveredGestures->insert(gesture);
- }
- }
-
- getGestureTargets(startedGestures, &conflictedGestures, &normalStartedGestures);
- DEBUG() << "QGestureManager::deliverEvents:"
- << "\nstarted: " << startedGestures
- << "\nconflicted: " << conflictedGestures
- << "\nnormal: " << normalStartedGestures
- << "\n";
-
- // if there are conflicting gestures, send the GestureOverride event
- for (GesturesPerWidget::const_iterator it = conflictedGestures.begin(),
- e = conflictedGestures.end(); it != e; ++it) {
- QWidget *receiver = it.key();
- QList<QGesture *> gestures = it.value();
- DEBUG() << "QGestureManager::deliverEvents: sending GestureOverride to"
- << receiver
- << "gestures:" << gestures;
- QGestureEvent event(gestures);
- event.t = QEvent::GestureOverride;
- // mark event and individual gestures as ignored
- event.ignore();
- foreach(QGesture *g, gestures)
- event.setAccepted(g, false);
-
- QApplication::sendEvent(receiver, &event);
- bool eventAccepted = event.isAccepted();
- foreach(QGesture *gesture, event.gestures()) {
- if (eventAccepted || event.isAccepted(gesture)) {
- QWidget *w = event.d_func()->targetWidgets.value(gesture->gestureType(), 0);
- Q_ASSERT(w);
- DEBUG() << "override event: gesture was accepted:" << gesture << w;
- QList<QGesture *> &gestures = normalStartedGestures[w];
- gestures.append(gesture);
- // override the target
- m_gestureTargets[gesture] = w;
- } else {
- DEBUG() << "override event: gesture wasn't accepted. putting back:" << gesture;
- QList<QGesture *> &gestures = normalStartedGestures[receiver];
- gestures.append(gesture);
- }
- }
- }
-
- // delivering gestures that are not in conflicted state
- for (GesturesPerWidget::const_iterator it = normalStartedGestures.begin(),
- e = normalStartedGestures.end(); it != e; ++it) {
- if (!it.value().isEmpty()) {
- DEBUG() << "QGestureManager::deliverEvents: sending to" << it.key()
- << "gestures:" << it.value();
- QGestureEvent event(it.value());
- QApplication::sendEvent(it.key(), &event);
- bool eventAccepted = event.isAccepted();
- foreach (QGesture *gesture, event.gestures()) {
- if (gesture->state() == Qt::GestureStarted &&
- (eventAccepted || event.isAccepted(gesture))) {
- QWidget *w = event.d_func()->targetWidgets.value(gesture->gestureType(), 0);
- Q_ASSERT(w);
- DEBUG() << "started gesture was delivered and accepted by" << w;
- m_gestureTargets[gesture] = w;
- }
- }
- }
- }
-}
-
-void QGestureManager::recycle(QGesture *gesture)
-{
- QGestureRecognizer *recognizer = m_gestureToRecognizer.value(gesture, 0);
- if (recognizer) {
- gesture->setGestureCancelPolicy(QGesture::CancelNone);
- recognizer->reset(gesture);
- m_activeGestures.remove(gesture);
- } else {
- cleanupGesturesForRemovedRecognizer(gesture);
- }
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_GESTURES
-
-#include "moc_qgesturemanager_p.cpp"
diff --git a/src/gui/kernel/qgesturerecognizer.h b/src/gui/kernel/qgesturerecognizer.h
deleted file mode 100644
index d3574f7ad2..0000000000
--- a/src/gui/kernel/qgesturerecognizer.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGESTURERECOGNIZER_H
-#define QGESTURERECOGNIZER_H
-
-#include <QtCore/qglobal.h>
-#include <QtCore/qnamespace.h>
-
-#ifndef QT_NO_GESTURES
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QObject;
-class QEvent;
-class QGesture;
-class Q_GUI_EXPORT QGestureRecognizer
-{
-public:
- enum ResultFlag
- {
- Ignore = 0x0001,
-
- MayBeGesture = 0x0002,
- TriggerGesture = 0x0004,
- FinishGesture = 0x0008,
- CancelGesture = 0x0010,
-
- ResultState_Mask = 0x00ff,
-
- ConsumeEventHint = 0x0100,
- // StoreEventHint = 0x0200,
- // ReplayStoredEventsHint = 0x0400,
- // DiscardStoredEventsHint = 0x0800,
-
- ResultHint_Mask = 0xff00
- };
- Q_DECLARE_FLAGS(Result, ResultFlag)
-
- QGestureRecognizer();
- virtual ~QGestureRecognizer();
-
- virtual QGesture *create(QObject *target);
- virtual Result recognize(QGesture *state, QObject *watched,
- QEvent *event) = 0;
- virtual void reset(QGesture *state);
-
- static Qt::GestureType registerRecognizer(QGestureRecognizer *recognizer);
- static void unregisterRecognizer(Qt::GestureType type);
-};
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QGestureRecognizer::Result)
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QT_NO_GESTURES
-
-#endif // QGESTURERECOGNIZER_H
diff --git a/src/gui/kernel/qgridlayout.h b/src/gui/kernel/qgridlayout.h
deleted file mode 100644
index 41c9dd6237..0000000000
--- a/src/gui/kernel/qgridlayout.h
+++ /dev/null
@@ -1,176 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGRIDLAYOUT_H
-#define QGRIDLAYOUT_H
-
-#include <QtGui/qlayout.h>
-#ifdef QT_INCLUDE_COMPAT
-#include <QtGui/qwidget.h>
-#endif
-
-#include <limits.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QGridLayoutPrivate;
-
-class Q_GUI_EXPORT QGridLayout : public QLayout
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QGridLayout)
- QDOC_PROPERTY(int horizontalSpacing READ horizontalSpacing WRITE setHorizontalSpacing)
- QDOC_PROPERTY(int verticalSpacing READ verticalSpacing WRITE setVerticalSpacing)
-
-public:
- explicit QGridLayout(QWidget *parent);
- QGridLayout();
-
-#ifdef QT3_SUPPORT
- QT3_SUPPORT_CONSTRUCTOR QGridLayout(QWidget *parent, int nRows , int nCols = 1, int border = 0,
- int spacing = -1, const char *name = 0);
- QT3_SUPPORT_CONSTRUCTOR QGridLayout(int nRows , int nCols = 1, int spacing = -1, const char *name = 0);
- QT3_SUPPORT_CONSTRUCTOR QGridLayout(QLayout *parentLayout, int nRows = 1, int nCols = 1, int spacing = -1,
- const char *name = 0);
-#endif
- ~QGridLayout();
-
- QSize sizeHint() const;
- QSize minimumSize() const;
- QSize maximumSize() const;
-
- void setHorizontalSpacing(int spacing);
- int horizontalSpacing() const;
- void setVerticalSpacing(int spacing);
- int verticalSpacing() const;
- void setSpacing(int spacing);
- int spacing() const;
-
- void setRowStretch(int row, int stretch);
- void setColumnStretch(int column, int stretch);
- int rowStretch(int row) const;
- int columnStretch(int column) const;
-
- void setRowMinimumHeight(int row, int minSize);
- void setColumnMinimumWidth(int column, int minSize);
- int rowMinimumHeight(int row) const;
- int columnMinimumWidth(int column) const;
-
- int columnCount() const;
- int rowCount() const;
-
- QRect cellRect(int row, int column) const;
-#ifdef QT3_SUPPORT
- inline QT3_SUPPORT QRect cellGeometry(int row, int column) const {return cellRect(row, column);}
-#endif
-
- bool hasHeightForWidth() const;
- int heightForWidth(int) const;
- int minimumHeightForWidth(int) const;
-
- Qt::Orientations expandingDirections() const;
- void invalidate();
-
- inline void addWidget(QWidget *w) { QLayout::addWidget(w); }
- void addWidget(QWidget *, int row, int column, Qt::Alignment = 0);
- void addWidget(QWidget *, int row, int column, int rowSpan, int columnSpan, Qt::Alignment = 0);
- void addLayout(QLayout *, int row, int column, Qt::Alignment = 0);
- void addLayout(QLayout *, int row, int column, int rowSpan, int columnSpan, Qt::Alignment = 0);
-
- void setOriginCorner(Qt::Corner);
- Qt::Corner originCorner() const;
-
-#ifdef QT3_SUPPORT
- inline QT3_SUPPORT void setOrigin(Qt::Corner corner) { setOriginCorner(corner); }
- inline QT3_SUPPORT Qt::Corner origin() const { return originCorner(); }
-#endif
- QLayoutItem *itemAt(int index) const;
- QLayoutItem *itemAtPosition(int row, int column) const;
- QLayoutItem *takeAt(int index);
- int count() const;
- void setGeometry(const QRect&);
-
- void addItem(QLayoutItem *item, int row, int column, int rowSpan = 1, int columnSpan = 1, Qt::Alignment = 0);
-
- void setDefaultPositioning(int n, Qt::Orientation orient);
- void getItemPosition(int idx, int *row, int *column, int *rowSpan, int *columnSpan);
-
-protected:
-#ifdef QT3_SUPPORT
- QT3_SUPPORT bool findWidget(QWidget* w, int *r, int *c);
-#endif
- void addItem(QLayoutItem *);
-
-private:
- Q_DISABLE_COPY(QGridLayout)
-
-#ifdef QT3_SUPPORT
-public:
- QT3_SUPPORT void expand(int rows, int cols);
- inline QT3_SUPPORT void addRowSpacing(int row, int minsize) { addItem(new QSpacerItem(0,minsize), row, 0); }
- inline QT3_SUPPORT void addColSpacing(int col, int minsize) { addItem(new QSpacerItem(minsize,0), 0, col); }
- inline QT3_SUPPORT void addMultiCellWidget(QWidget *w, int fromRow, int toRow, int fromCol, int toCol, Qt::Alignment _align = 0)
- { addWidget(w, fromRow, fromCol, (toRow < 0) ? -1 : toRow - fromRow + 1, (toCol < 0) ? -1 : toCol - fromCol + 1, _align); }
- inline QT3_SUPPORT void addMultiCell(QLayoutItem *l, int fromRow, int toRow, int fromCol, int toCol, Qt::Alignment _align = 0)
- { addItem(l, fromRow, fromCol, (toRow < 0) ? -1 : toRow - fromRow + 1, (toCol < 0) ? -1 : toCol - fromCol + 1, _align); }
- inline QT3_SUPPORT void addMultiCellLayout(QLayout *layout, int fromRow, int toRow, int fromCol, int toCol, Qt::Alignment _align = 0)
- { addLayout(layout, fromRow, fromCol, (toRow < 0) ? -1 : toRow - fromRow + 1, (toCol < 0) ? -1 : toCol - fromCol + 1, _align); }
-
- inline QT3_SUPPORT int numRows() const { return rowCount(); }
- inline QT3_SUPPORT int numCols() const { return columnCount(); }
- inline QT3_SUPPORT void setColStretch(int col, int stretch) {setColumnStretch(col, stretch); }
- inline QT3_SUPPORT int colStretch(int col) const {return columnStretch(col); }
- inline QT3_SUPPORT void setColSpacing(int col, int minSize) { setColumnMinimumWidth(col, minSize); }
- inline QT3_SUPPORT int colSpacing(int col) const { return columnMinimumWidth(col); }
- inline QT3_SUPPORT void setRowSpacing(int row, int minSize) {setRowMinimumHeight(row, minSize); }
- inline QT3_SUPPORT int rowSpacing(int row) const {return rowMinimumHeight(row); }
-#endif
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QGRIDLAYOUT_H
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
new file mode 100644
index 0000000000..212afdf8dc
--- /dev/null
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -0,0 +1,1495 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qguiapplication.h"
+
+#include "private/qguiapplication_p.h"
+#include "private/qplatformintegrationfactory_qpa_p.h"
+#include "private/qevent_p.h"
+#include "qfont.h"
+#include "qplatformfontdatabase_qpa.h"
+#include "qplatformwindow_qpa.h"
+
+#include <QtCore/QAbstractEventDispatcher>
+#include <QtCore/private/qcoreapplication_p.h>
+#include <QtCore/private/qabstracteventdispatcher_p.h>
+#include <QtCore/qmutex.h>
+#include <QtCore/private/qthread_p.h>
+#include <QtDebug>
+#include <qpalette.h>
+#include <qscreen.h>
+
+#include <QtGui/QPlatformIntegration>
+#include <QtGui/QGenericPluginFactory>
+#include <QtGui/qstylehints.h>
+#include <QtGui/qinputpanel.h>
+
+#include <QWindowSystemInterface>
+#include "private/qwindowsysteminterface_qpa_p.h"
+#include "private/qwindow_p.h"
+#include "private/qkeymapper_p.h"
+#include "private/qcursor_p.h"
+#include "private/qdnd_p.h"
+#ifndef QT_NO_CURSOR
+#include "qplatformcursor_qpa.h"
+#endif
+
+#include <QtGui/QPixmap>
+
+#ifndef QT_NO_CLIPBOARD
+#include <QtGui/QClipboard>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+Q_GUI_EXPORT bool qt_is_gui_used = true;
+
+Qt::MouseButtons QGuiApplicationPrivate::mouse_buttons = Qt::NoButton;
+Qt::KeyboardModifiers QGuiApplicationPrivate::modifier_buttons = Qt::NoModifier;
+
+QPointF QGuiApplicationPrivate::lastCursorPosition(0.0, 0.0);
+
+QPlatformIntegration *QGuiApplicationPrivate::platform_integration = 0;
+
+bool QGuiApplicationPrivate::app_do_modal = false;
+
+QPalette *QGuiApplicationPrivate::app_pal = 0; // default application palette
+
+Qt::MouseButtons QGuiApplicationPrivate::buttons = Qt::NoButton;
+ulong QGuiApplicationPrivate::mousePressTime = 0;
+Qt::MouseButton QGuiApplicationPrivate::mousePressButton = Qt::NoButton;
+int QGuiApplicationPrivate::mousePressX = 0;
+int QGuiApplicationPrivate::mousePressY = 0;
+int QGuiApplicationPrivate::mouse_double_click_distance = 5;
+
+bool QGuiApplicationPrivate::quitOnLastWindowClosed = true;
+
+static Qt::LayoutDirection layout_direction = Qt::LeftToRight;
+static bool force_reverse = false;
+
+QGuiApplicationPrivate *QGuiApplicationPrivate::self = 0;
+
+#ifndef QT_NO_CLIPBOARD
+QClipboard *QGuiApplicationPrivate::qt_clipboard = 0;
+#endif
+
+QList<QScreen *> QGuiApplicationPrivate::screen_list;
+
+QWindowList QGuiApplicationPrivate::window_list;
+QWindow *QGuiApplicationPrivate::active_window = 0;
+
+Q_GLOBAL_STATIC(QMutex, applicationFontMutex)
+QFont *QGuiApplicationPrivate::app_font = 0;
+
+extern int qRegisterGuiVariant();
+extern int qUnregisterGuiVariant();
+extern void qInitDrawhelperAsm();
+extern void qInitImageConversions();
+
+static bool qt_detectRTLLanguage()
+{
+ return force_reverse ^
+ (QCoreApplication::tr("QT_LAYOUT_DIRECTION",
+ "Translate this string to the string 'LTR' in left-to-right"
+ " languages or to 'RTL' in right-to-left languages (such as Hebrew"
+ " and Arabic) to get proper widget layout.") == QLatin1String("RTL"));
+}
+
+
+QGuiApplication::QGuiApplication(int &argc, char **argv, int flags)
+ : QCoreApplication(*new QGuiApplicationPrivate(argc, argv, flags))
+{
+ d_func()->init();
+
+ QCoreApplicationPrivate::eventDispatcher->startingUp();
+}
+
+QGuiApplication::QGuiApplication(QGuiApplicationPrivate &p)
+ : QCoreApplication(p)
+{
+ d_func()->init();
+}
+
+QGuiApplication::~QGuiApplication()
+{
+ Q_D(QGuiApplication);
+ // flush clipboard contents
+ if (QGuiApplicationPrivate::qt_clipboard) {
+ QEvent event(QEvent::Clipboard);
+ QGuiApplication::sendEvent(QGuiApplicationPrivate::qt_clipboard, &event);
+ }
+
+ d->eventDispatcher->closingDown();
+ d->eventDispatcher = 0;
+
+ delete QGuiApplicationPrivate::qt_clipboard;
+ QGuiApplicationPrivate::qt_clipboard = 0;
+
+ delete QGuiApplicationPrivate::app_pal;
+ QGuiApplicationPrivate::app_pal = 0;
+
+ qUnregisterGuiVariant();
+
+#ifndef QT_NO_CURSOR
+ d->cursor_list.clear();
+#endif
+}
+
+QGuiApplicationPrivate::QGuiApplicationPrivate(int &argc, char **argv, int flags)
+ : QCoreApplicationPrivate(argc, argv, flags),
+ styleHints(0),
+ inputPanel(0)
+{
+ self = this;
+}
+
+QWindow *QGuiApplication::activeWindow()
+{
+ return QGuiApplicationPrivate::active_window;
+}
+
+QWindowList QGuiApplication::topLevelWindows()
+{
+ return QGuiApplicationPrivate::window_list;
+}
+
+QScreen *QGuiApplication::primaryScreen()
+{
+ if (QGuiApplicationPrivate::screen_list.isEmpty())
+ return 0;
+ return QGuiApplicationPrivate::screen_list.at(0);
+}
+
+QList<QScreen *> QGuiApplication::screens()
+{
+ return QGuiApplicationPrivate::screen_list;
+}
+
+QWindow *QGuiApplication::topLevelAt(const QPoint &pos)
+{
+ QList<QScreen *> screens = QGuiApplication::screens();
+ QList<QScreen *>::const_iterator screen = screens.constBegin();
+ QList<QScreen *>::const_iterator end = screens.constEnd();
+
+ while (screen != end) {
+ if ((*screen)->geometry().contains(pos))
+ return (*screen)->handle()->topLevelAt(pos);
+ ++screen;
+ }
+ return 0;
+}
+
+
+static void init_platform(QString name, const QString &platformPluginPath)
+{
+ if (name.isEmpty()) {
+ const QStringList keys = QPlatformIntegrationFactory::keys(platformPluginPath);
+#if defined(Q_OS_MAC)
+ const QString defaultPlatform = QLatin1String("cocoa");
+#elif defined (Q_OS_WIN)
+ const QString defaultPlatform = QLatin1String("windows");
+#else
+ const QString defaultPlatform = QLatin1String("xcb");
+#endif
+ if (keys.contains(defaultPlatform)) {
+ qWarning("No platform plugin argument was specified, defaulting to \"%s\".",
+ qPrintable(defaultPlatform));
+ name = defaultPlatform;
+ } else {
+ qFatal("No platform plugin argument was specified and the default plugin \"%s\" is not available",
+ qPrintable(defaultPlatform));
+ }
+ }
+
+ QGuiApplicationPrivate::platform_integration = QPlatformIntegrationFactory::create(name, platformPluginPath);
+ if (!QGuiApplicationPrivate::platform_integration) {
+ QStringList keys = QPlatformIntegrationFactory::keys(platformPluginPath);
+ QString fatalMessage =
+ QString::fromLatin1("Failed to load platform plugin \"%1\". Available platforms are: \n").arg(name);
+ foreach(const QString &key, keys) {
+ fatalMessage.append(key + QLatin1Char('\n'));
+ }
+ qFatal("%s", fatalMessage.toLocal8Bit().constData());
+ }
+}
+
+static void init_plugins(const QList<QByteArray> &pluginList)
+{
+ for (int i = 0; i < pluginList.count(); ++i) {
+ QByteArray pluginSpec = pluginList.at(i);
+ qDebug() << "init_plugins" << i << pluginSpec;
+ int colonPos = pluginSpec.indexOf(':');
+ QObject *plugin;
+ if (colonPos < 0)
+ plugin = QGenericPluginFactory::create(QLatin1String(pluginSpec), QString());
+ else
+ plugin = QGenericPluginFactory::create(QLatin1String(pluginSpec.mid(0, colonPos)),
+ QLatin1String(pluginSpec.mid(colonPos+1)));
+ qDebug() << " created" << plugin;
+ }
+}
+
+void QGuiApplicationPrivate::createPlatformIntegration()
+{
+ Q_Q(QGuiApplication);
+
+ // Use the Qt menus by default. Platform plugins that
+ // want to enable a native menu implementation can clear
+ // this flag.
+ q->setAttribute(Qt::AA_DontUseNativeMenuBar, true);
+
+ // Load the platform integration
+ QString platformPluginPath = QLatin1String(qgetenv("QT_QPA_PLATFORM_PLUGIN_PATH"));
+ QByteArray platformName;
+#ifdef QT_QPA_DEFAULT_PLATFORM_NAME
+ platformName = QT_QPA_DEFAULT_PLATFORM_NAME;
+#endif
+ QByteArray platformNameEnv = qgetenv("QT_QPA_PLATFORM");
+ if (!platformNameEnv.isEmpty()) {
+ platformName = platformNameEnv;
+ }
+
+ // Get command line params
+
+ int j = argc ? 1 : 0;
+ for (int i=1; i<argc; i++) {
+ if (argv[i] && *argv[i] != '-') {
+ argv[j++] = argv[i];
+ continue;
+ }
+ QByteArray arg = argv[i];
+ if (arg == "-platformpluginpath") {
+ if (++i < argc)
+ platformPluginPath = QLatin1String(argv[i]);
+ } else if (arg == "-platform") {
+ if (++i < argc)
+ platformName = argv[i];
+ } else {
+ argv[j++] = argv[i];
+ }
+ }
+
+ if (j < argc) {
+ argv[j] = 0;
+ argc = j;
+ }
+
+ init_platform(QLatin1String(platformName), platformPluginPath);
+
+}
+
+void QGuiApplicationPrivate::createEventDispatcher()
+{
+ if (platform_integration == 0)
+ createPlatformIntegration();
+
+ if (!eventDispatcher) {
+ QAbstractEventDispatcher *eventDispatcher = platform_integration->guiThreadEventDispatcher();
+ setEventDispatcher(eventDispatcher);
+ }
+}
+
+void QGuiApplicationPrivate::setEventDispatcher(QAbstractEventDispatcher *eventDispatcher)
+{
+ Q_Q(QGuiApplication);
+
+ if (!QCoreApplicationPrivate::eventDispatcher) {
+ QCoreApplicationPrivate::eventDispatcher = eventDispatcher;
+ QCoreApplicationPrivate::eventDispatcher->setParent(q);
+ threadData->eventDispatcher = eventDispatcher;
+ }
+
+}
+
+void QGuiApplicationPrivate::init()
+{
+ QList<QByteArray> pluginList;
+ // Get command line params
+
+ int j = argc ? 1 : 0;
+ for (int i=1; i<argc; i++) {
+ if (argv[i] && *argv[i] != '-') {
+ argv[j++] = argv[i];
+ continue;
+ }
+ QByteArray arg = argv[i];
+ if (arg == "-plugin") {
+ if (++i < argc)
+ pluginList << argv[i];
+ } else if (arg == "-reverse") {
+ force_reverse = true;
+ QGuiApplication::setLayoutDirection(Qt::RightToLeft);
+ } else {
+ argv[j++] = argv[i];
+ }
+ }
+
+ if (j < argc) {
+ argv[j] = 0;
+ argc = j;
+ }
+
+ if (platform_integration == 0)
+ createPlatformIntegration();
+
+ init_plugins(pluginList);
+
+ // Set up which span functions should be used in raster engine...
+ qInitDrawhelperAsm();
+ // and QImage conversion functions
+ qInitImageConversions();
+
+ QFont::initialize();
+
+#ifndef QT_NO_CURSOR
+ QCursorData::initialize();
+#endif
+
+ // trigger registering of QVariant's GUI types
+ qRegisterGuiVariant();
+
+ is_app_running = true;
+}
+
+QGuiApplicationPrivate::~QGuiApplicationPrivate()
+{
+ is_app_closing = true;
+ is_app_running = false;
+
+ QFont::cleanup();
+
+#ifndef QT_NO_CURSOR
+ QCursorData::cleanup();
+#endif
+
+ layout_direction = Qt::LeftToRight;
+
+ cleanupThreadData();
+
+ delete styleHints;
+ delete inputPanel;
+
+ delete platform_integration;
+ platform_integration = 0;
+}
+
+#if 0
+#ifndef QT_NO_CURSOR
+QCursor *overrideCursor();
+void setOverrideCursor(const QCursor &);
+void changeOverrideCursor(const QCursor &);
+void restoreOverrideCursor();
+#endif
+
+static QFont font();
+static QFont font(const QWidget*);
+static QFont font(const char *className);
+static void setFont(const QFont &, const char* className = 0);
+static QFontMetrics fontMetrics();
+
+#ifndef QT_NO_CLIPBOARD
+static QClipboard *clipboard();
+#endif
+#endif
+
+Qt::KeyboardModifiers QGuiApplication::keyboardModifiers()
+{
+ return QGuiApplicationPrivate::modifier_buttons;
+}
+
+Qt::MouseButtons QGuiApplication::mouseButtons()
+{
+ return QGuiApplicationPrivate::mouse_buttons;
+}
+
+QPlatformNativeInterface *QGuiApplication::platformNativeInterface()
+{
+ QPlatformIntegration *pi = QGuiApplicationPrivate::platformIntegration();
+ return pi->nativeInterface();
+}
+
+int QGuiApplication::exec()
+{
+ return QCoreApplication::exec();
+}
+
+bool QGuiApplication::notify(QObject *object, QEvent *event)
+{
+ return QCoreApplication::notify(object, event);
+}
+
+bool QGuiApplication::event(QEvent *e)
+{
+ if(e->type() == QEvent::LanguageChange) {
+ setLayoutDirection(qt_detectRTLLanguage()?Qt::RightToLeft:Qt::LeftToRight);
+ }
+ return QCoreApplication::event(e);
+}
+
+bool QGuiApplication::compressEvent(QEvent *event, QObject *receiver, QPostEventList *postedEvents)
+{
+ return QCoreApplication::compressEvent(event, receiver, postedEvents);
+}
+
+void QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *e)
+{
+ switch(e->type) {
+ case QWindowSystemInterfacePrivate::Mouse:
+ QGuiApplicationPrivate::processMouseEvent(static_cast<QWindowSystemInterfacePrivate::MouseEvent *>(e));
+ break;
+ case QWindowSystemInterfacePrivate::Wheel:
+ QGuiApplicationPrivate::processWheelEvent(static_cast<QWindowSystemInterfacePrivate::WheelEvent *>(e));
+ break;
+ case QWindowSystemInterfacePrivate::Key:
+ QGuiApplicationPrivate::processKeyEvent(static_cast<QWindowSystemInterfacePrivate::KeyEvent *>(e));
+ break;
+ case QWindowSystemInterfacePrivate::Touch:
+ QGuiApplicationPrivate::processTouchEvent(static_cast<QWindowSystemInterfacePrivate::TouchEvent *>(e));
+ break;
+ case QWindowSystemInterfacePrivate::GeometryChange:
+ QGuiApplicationPrivate::processGeometryChangeEvent(static_cast<QWindowSystemInterfacePrivate::GeometryChangeEvent*>(e));
+ break;
+ case QWindowSystemInterfacePrivate::Enter:
+ QGuiApplicationPrivate::processEnterEvent(static_cast<QWindowSystemInterfacePrivate::EnterEvent *>(e));
+ break;
+ case QWindowSystemInterfacePrivate::Leave:
+ QGuiApplicationPrivate::processLeaveEvent(static_cast<QWindowSystemInterfacePrivate::LeaveEvent *>(e));
+ break;
+ case QWindowSystemInterfacePrivate::ActivatedWindow:
+ QGuiApplicationPrivate::processActivatedEvent(static_cast<QWindowSystemInterfacePrivate::ActivatedWindowEvent *>(e));
+ break;
+ case QWindowSystemInterfacePrivate::WindowStateChanged:
+ QGuiApplicationPrivate::processWindowStateChangedEvent(static_cast<QWindowSystemInterfacePrivate::WindowStateChangedEvent *>(e));
+ break;
+ case QWindowSystemInterfacePrivate::Close:
+ QGuiApplicationPrivate::processCloseEvent(
+ static_cast<QWindowSystemInterfacePrivate::CloseEvent *>(e));
+ break;
+ case QWindowSystemInterfacePrivate::ScreenCountChange:
+ QGuiApplicationPrivate::reportScreenCount(
+ static_cast<QWindowSystemInterfacePrivate::ScreenCountEvent *>(e));
+ break;
+ case QWindowSystemInterfacePrivate::ScreenGeometry:
+ QGuiApplicationPrivate::reportGeometryChange(
+ static_cast<QWindowSystemInterfacePrivate::ScreenGeometryEvent *>(e));
+ break;
+ case QWindowSystemInterfacePrivate::ScreenAvailableGeometry:
+ QGuiApplicationPrivate::reportAvailableGeometryChange(
+ static_cast<QWindowSystemInterfacePrivate::ScreenAvailableGeometryEvent *>(e));
+ break;
+ case QWindowSystemInterfacePrivate::Map:
+ QGuiApplicationPrivate::processMapEvent(static_cast<QWindowSystemInterfacePrivate::MapEvent *>(e));
+ break;
+ case QWindowSystemInterfacePrivate::Unmap:
+ QGuiApplicationPrivate::processUnmapEvent(static_cast<QWindowSystemInterfacePrivate::UnmapEvent *>(e));
+ break;
+ case QWindowSystemInterfacePrivate::Expose:
+ QGuiApplicationPrivate::processExposeEvent(static_cast<QWindowSystemInterfacePrivate::ExposeEvent *>(e));
+ break;
+ default:
+ qWarning() << "Unknown user input event type:" << e->type;
+ break;
+ }
+}
+
+void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent *e)
+{
+ QEvent::Type type;
+ // move first
+ Qt::MouseButtons stateChange = e->buttons ^ buttons;
+ if (e->globalPos != QGuiApplicationPrivate::lastCursorPosition && (stateChange != Qt::NoButton)) {
+ QWindowSystemInterfacePrivate::MouseEvent * newMouseEvent =
+ new QWindowSystemInterfacePrivate::MouseEvent(e->window.data(), e->timestamp, e->localPos, e->globalPos, e->buttons);
+ QWindowSystemInterfacePrivate::windowSystemEventQueue.prepend(newMouseEvent); // just in case the move triggers a new event loop
+ stateChange = Qt::NoButton;
+ }
+
+ QWindow *window = e->window.data();
+
+ if (!window)
+ window = QGuiApplication::topLevelAt(e->globalPos.toPoint());
+
+ QPointF localPoint = e->localPos;
+ QPointF globalPoint = e->globalPos;
+
+ Qt::MouseButton button = Qt::NoButton;
+
+ if (QGuiApplicationPrivate::lastCursorPosition != globalPoint) {
+ type = QEvent::MouseMove;
+ QGuiApplicationPrivate::lastCursorPosition = globalPoint;
+ if (qAbs(globalPoint.x() - mousePressX) > mouse_double_click_distance||
+ qAbs(globalPoint.y() - mousePressY) > mouse_double_click_distance)
+ mousePressButton = Qt::NoButton;
+ }
+ else { // check to see if a new button has been pressed/released
+ for (int check = Qt::LeftButton;
+ check <= Qt::XButton2;
+ check = check << 1) {
+ if (check & stateChange) {
+ button = Qt::MouseButton(check);
+ break;
+ }
+ }
+ if (button == Qt::NoButton) {
+ // Ignore mouse events that don't change the current state
+ return;
+ }
+ buttons = e->buttons;
+ if (button & e->buttons) {
+ if ((e->timestamp - mousePressTime) < static_cast<ulong>(qApp->styleHints()->mouseDoubleClickInterval()) &&
+ button == mousePressButton) {
+ type = QEvent::MouseButtonDblClick;
+ mousePressButton = Qt::NoButton;
+ }
+ else {
+ type = QEvent::MouseButtonPress;
+ mousePressTime = e->timestamp;
+ mousePressButton = button;
+ const QPoint point = QGuiApplicationPrivate::lastCursorPosition.toPoint();
+ mousePressX = point.x();
+ mousePressY = point.y();
+ }
+ }
+ else
+ type = QEvent::MouseButtonRelease;
+ }
+
+
+ if (window) {
+ QMouseEvent ev(type, localPoint, localPoint, globalPoint, button, buttons, QGuiApplication::keyboardModifiers());
+ ev.setTimestamp(e->timestamp);
+#ifndef QT_NO_CURSOR
+ QList<QWeakPointer<QPlatformCursor> > cursors = QPlatformCursorPrivate::getInstances();
+ for (int i = 0; i < cursors.count(); ++i)
+ if (cursors.at(i))
+ cursors.at(i).data()->pointerEvent(ev);
+#endif
+ QGuiApplication::sendSpontaneousEvent(window, &ev);
+ return;
+ }
+}
+
+
+//### there's a lot of duplicated logic here -- refactoring required!
+
+void QGuiApplicationPrivate::processWheelEvent(QWindowSystemInterfacePrivate::WheelEvent *e)
+{
+ if (!e->window)
+ return;
+
+ QPointF globalPoint = e->globalPos;
+ QGuiApplicationPrivate::lastCursorPosition = globalPoint;
+
+ QWindow *window = e->window.data();
+
+ if (window) {
+ QWheelEvent ev(e->localPos, e->globalPos, e->delta, buttons, QGuiApplication::keyboardModifiers(),
+ e->orient);
+ ev.setTimestamp(e->timestamp);
+ QGuiApplication::sendSpontaneousEvent(window, &ev);
+ return;
+ }
+}
+
+
+
+// Remember, Qt convention is: keyboard state is state *before*
+
+void QGuiApplicationPrivate::processKeyEvent(QWindowSystemInterfacePrivate::KeyEvent *e)
+{
+ QWindow *window = e->window.data();
+ if (!window)
+ return;
+
+ QObject *target = window;
+
+ if (e->nativeScanCode || e->nativeVirtualKey || e->nativeModifiers) {
+ QKeyEventEx ev(e->keyType, e->key, e->modifiers, e->unicode, e->repeat, e->repeatCount,
+ e->nativeScanCode, e->nativeVirtualKey, e->nativeModifiers);
+ ev.setTimestamp(e->timestamp);
+ QGuiApplication::sendSpontaneousEvent(target, &ev);
+ } else {
+ QKeyEvent ev(e->keyType, e->key, e->modifiers, e->unicode, e->repeat, e->repeatCount);
+ ev.setTimestamp(e->timestamp);
+ QGuiApplication::sendSpontaneousEvent(target, &ev);
+ }
+}
+
+void QGuiApplicationPrivate::processEnterEvent(QWindowSystemInterfacePrivate::EnterEvent *e)
+{
+ if (!e->enter)
+ return;
+
+ QEvent event(QEvent::Enter);
+ QCoreApplication::sendSpontaneousEvent(e->enter.data(), &event);
+}
+
+void QGuiApplicationPrivate::processLeaveEvent(QWindowSystemInterfacePrivate::LeaveEvent *e)
+{
+ if (!e->leave)
+ return;
+
+ QEvent event(QEvent::Leave);
+ QCoreApplication::sendSpontaneousEvent(e->leave.data(), &event);
+}
+
+void QGuiApplicationPrivate::processActivatedEvent(QWindowSystemInterfacePrivate::ActivatedWindowEvent *e)
+{
+ if (!e->activated)
+ return;
+
+ QWindow *previous = QGuiApplicationPrivate::active_window;
+ QGuiApplicationPrivate::active_window = e->activated.data();
+ if (self)
+ self->notifyActiveWindowChange(previous);
+}
+
+void QGuiApplicationPrivate::processWindowStateChangedEvent(QWindowSystemInterfacePrivate::WindowStateChangedEvent *wse)
+{
+ if (QWindow *window = wse->window.data()) {
+ QWindowStateChangeEvent e(window->windowState());
+ window->d_func()->windowState = wse->newState;
+ QGuiApplication::sendSpontaneousEvent(window, &e);
+ }
+}
+
+void QGuiApplicationPrivate::processGeometryChangeEvent(QWindowSystemInterfacePrivate::GeometryChangeEvent *e)
+{
+ if (e->tlw.isNull())
+ return;
+
+ QWindow *window = e->tlw.data();
+ if (!window)
+ return;
+
+ QRect newRect = e->newGeometry;
+ QRect cr = window->geometry();
+
+ bool isResize = cr.size() != newRect.size();
+ bool isMove = cr.topLeft() != newRect.topLeft();
+
+ window->d_func()->geometry = newRect;
+
+ if (isResize) {
+ QResizeEvent e(newRect.size(), cr.size());
+ QGuiApplication::sendSpontaneousEvent(window, &e);
+ }
+
+ if (isMove) {
+ //### frame geometry
+ QMoveEvent e(newRect.topLeft(), cr.topLeft());
+ QGuiApplication::sendSpontaneousEvent(window, &e);
+ }
+}
+
+void QGuiApplicationPrivate::processCloseEvent(QWindowSystemInterfacePrivate::CloseEvent *e)
+{
+ if (e->window.isNull())
+ return;
+
+ QCloseEvent event;
+ QGuiApplication::sendSpontaneousEvent(e->window.data(), &event);
+}
+
+void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::TouchEvent *e)
+{
+ QWindow *window = e->window.data();
+ QGuiApplicationPrivate *d = self;
+ typedef QPair<Qt::TouchPointStates, QList<QTouchEvent::TouchPoint> > StatesAndTouchPoints;
+ QHash<QWindow *, StatesAndTouchPoints> windowsNeedingEvents;
+
+ for (int i = 0; i < e->points.count(); ++i) {
+ QTouchEvent::TouchPoint touchPoint = e->points.at(i);
+ // explicitly detach from the original touch point that we got, so even
+ // if the touchpoint structs are reused, we will make a copy that we'll
+ // deliver to the user (which might want to store the struct for later use).
+ touchPoint.d = touchPoint.d->detach();
+
+ // update state
+ QWeakPointer<QWindow> w;
+ QTouchEvent::TouchPoint previousTouchPoint;
+ switch (touchPoint.state()) {
+ case Qt::TouchPointPressed:
+ if (e->devType == QTouchEvent::TouchPad) {
+ // on touch-pads, send all touch points to the same widget
+ w = d->windowForTouchPointId.isEmpty()
+ ? QWeakPointer<QWindow>()
+ : d->windowForTouchPointId.constBegin().value();
+ }
+
+ if (!w) {
+ // determine which window this event will go to
+ if (!window)
+ window = QGuiApplication::topLevelAt(touchPoint.screenPos().toPoint());
+ if (!window)
+ continue;
+ w = window;
+ }
+
+ d->windowForTouchPointId[touchPoint.id()] = w;
+ touchPoint.d->startScreenPos = touchPoint.screenPos();
+ touchPoint.d->lastScreenPos = touchPoint.screenPos();
+ touchPoint.d->startNormalizedPos = touchPoint.normalizedPos();
+ touchPoint.d->lastNormalizedPos = touchPoint.normalizedPos();
+ if (touchPoint.pressure() < qreal(0.))
+ touchPoint.d->pressure = qreal(1.);
+
+ d->appCurrentTouchPoints.insert(touchPoint.id(), touchPoint);
+ break;
+
+ case Qt::TouchPointReleased:
+ w = d->windowForTouchPointId.take(touchPoint.id());
+ if (!w)
+ continue;
+ previousTouchPoint = d->appCurrentTouchPoints.take(touchPoint.id());
+ touchPoint.d->startScreenPos = previousTouchPoint.startScreenPos();
+ touchPoint.d->lastScreenPos = previousTouchPoint.screenPos();
+ touchPoint.d->startPos = previousTouchPoint.startPos();
+ touchPoint.d->lastPos = previousTouchPoint.pos();
+ touchPoint.d->startNormalizedPos = previousTouchPoint.startNormalizedPos();
+ touchPoint.d->lastNormalizedPos = previousTouchPoint.normalizedPos();
+ if (touchPoint.pressure() < qreal(0.))
+ touchPoint.d->pressure = qreal(0.);
+ break;
+
+ default:
+ w = d->windowForTouchPointId.value(touchPoint.id());
+ if (!w)
+ continue;
+ Q_ASSERT(d->appCurrentTouchPoints.contains(touchPoint.id()));
+ previousTouchPoint = d->appCurrentTouchPoints.value(touchPoint.id());
+ touchPoint.d->startScreenPos = previousTouchPoint.startScreenPos();
+ touchPoint.d->lastScreenPos = previousTouchPoint.screenPos();
+ touchPoint.d->startPos = previousTouchPoint.startPos();
+ touchPoint.d->lastPos = previousTouchPoint.pos();
+ touchPoint.d->startNormalizedPos = previousTouchPoint.startNormalizedPos();
+ touchPoint.d->lastNormalizedPos = previousTouchPoint.normalizedPos();
+ if (touchPoint.pressure() < qreal(0.))
+ touchPoint.d->pressure = qreal(1.);
+ d->appCurrentTouchPoints[touchPoint.id()] = touchPoint;
+ break;
+ }
+
+ Q_ASSERT(w.data() != 0);
+
+ // make the *scene* functions return the same as the *screen* functions
+ touchPoint.d->sceneRect = touchPoint.screenRect();
+ touchPoint.d->startScenePos = touchPoint.startScreenPos();
+ touchPoint.d->lastScenePos = touchPoint.lastScreenPos();
+
+ StatesAndTouchPoints &maskAndPoints = windowsNeedingEvents[w.data()];
+ maskAndPoints.first |= touchPoint.state();
+ if (touchPoint.isPrimary())
+ maskAndPoints.first |= Qt::TouchPointPrimary;
+ maskAndPoints.second.append(touchPoint);
+ }
+
+ if (windowsNeedingEvents.isEmpty())
+ return;
+
+ QHash<QWindow *, StatesAndTouchPoints>::ConstIterator it = windowsNeedingEvents.constBegin();
+ const QHash<QWindow *, StatesAndTouchPoints>::ConstIterator end = windowsNeedingEvents.constEnd();
+ for (; it != end; ++it) {
+ QWindow *w = it.key();
+
+ QEvent::Type eventType;
+ switch (it.value().first & Qt::TouchPointStateMask) {
+ case Qt::TouchPointPressed:
+ eventType = QEvent::TouchBegin;
+ break;
+ case Qt::TouchPointReleased:
+ eventType = QEvent::TouchEnd;
+ break;
+ case Qt::TouchPointStationary:
+ // don't send the event if nothing changed
+ continue;
+ default:
+ eventType = QEvent::TouchUpdate;
+ break;
+ }
+
+ QTouchEvent touchEvent(eventType,
+ e->devType,
+ QGuiApplication::keyboardModifiers(),
+ it.value().first,
+ it.value().second);
+ touchEvent.setTimestamp(e->timestamp);
+
+ for (int i = 0; i < touchEvent.touchPoints().count(); ++i) {
+ QTouchEvent::TouchPoint &touchPoint = touchEvent._touchPoints[i];
+
+ // preserve the sub-pixel resolution
+ QRectF rect = touchPoint.screenRect();
+ const QPointF screenPos = rect.center();
+ const QPointF delta = screenPos - screenPos.toPoint();
+
+ rect.moveCenter(w->mapFromGlobal(screenPos.toPoint()) + delta);
+ touchPoint.d->rect = rect;
+ if (touchPoint.state() == Qt::TouchPointPressed) {
+ touchPoint.d->startPos = w->mapFromGlobal(touchPoint.startScreenPos().toPoint()) + delta;
+ touchPoint.d->lastPos = w->mapFromGlobal(touchPoint.lastScreenPos().toPoint()) + delta;
+ }
+ }
+
+ QGuiApplication::sendSpontaneousEvent(w, &touchEvent);
+ }
+}
+
+void QGuiApplicationPrivate::reportScreenCount(QWindowSystemInterfacePrivate::ScreenCountEvent *)
+{
+ // This operation only makes sense after the QGuiApplication constructor runs
+ if (QCoreApplication::startingUp())
+ return;
+
+ //QGuiApplication::desktop()->d_func()->updateScreenList();
+ // signal anything listening for creation or deletion of screens
+ //QDesktopWidget *desktop = QGuiApplication::desktop();
+ //emit desktop->screenCountChanged(e->count);
+}
+
+void QGuiApplicationPrivate::reportGeometryChange(QWindowSystemInterfacePrivate::ScreenGeometryEvent *)
+{
+ // This operation only makes sense after the QGuiApplication constructor runs
+ if (QCoreApplication::startingUp())
+ return;
+}
+
+void QGuiApplicationPrivate::reportAvailableGeometryChange(
+ QWindowSystemInterfacePrivate::ScreenAvailableGeometryEvent *)
+{
+ // This operation only makes sense after the QGuiApplication constructor runs
+ if (QCoreApplication::startingUp())
+ return;
+}
+
+void QGuiApplicationPrivate::processMapEvent(QWindowSystemInterfacePrivate::MapEvent *e)
+{
+ if (!e->mapped)
+ return;
+
+ QEvent event(QEvent::Map);
+ QCoreApplication::sendSpontaneousEvent(e->mapped.data(), &event);
+}
+
+void QGuiApplicationPrivate::processUnmapEvent(QWindowSystemInterfacePrivate::UnmapEvent *e)
+{
+ if (!e->unmapped)
+ return;
+
+ QEvent event(QEvent::Unmap);
+ QCoreApplication::sendSpontaneousEvent(e->unmapped.data(), &event);
+}
+
+void QGuiApplicationPrivate::processExposeEvent(QWindowSystemInterfacePrivate::ExposeEvent *e)
+{
+ if (!e->exposed)
+ return;
+
+ QWindow *window = e->exposed.data();
+
+ QResizeEvent resizeEvent(window->handle()->geometry().size(), window->size());
+ QGuiApplication::sendSpontaneousEvent(window, &resizeEvent);
+
+ QExposeEvent exposeEvent(e->region);
+ QCoreApplication::sendSpontaneousEvent(window, &exposeEvent);
+}
+
+Qt::DropAction QGuiApplicationPrivate::processDrag(QWindow *w, QMimeData *dropData, const QPoint &p)
+{
+ static QPointer<QWindow> currentDragWindow;
+ QDragManager *manager = QDragManager::self();
+ if (!dropData) {
+ if (currentDragWindow.data() == w)
+ currentDragWindow = 0;
+ QDragLeaveEvent e;
+ QGuiApplication::sendEvent(w, &e);
+ manager->global_accepted_action = Qt::IgnoreAction;
+ return Qt::IgnoreAction;
+ }
+ QDragMoveEvent me(p, manager->possible_actions, dropData,
+ QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers());
+ if (w != currentDragWindow) {
+ if (currentDragWindow) {
+ QDragLeaveEvent e;
+ QGuiApplication::sendEvent(currentDragWindow, &e);
+ manager->global_accepted_action = Qt::IgnoreAction;
+ }
+ currentDragWindow = w;
+ QDragEnterEvent e(p, manager->possible_actions, dropData,
+ QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers());
+ QGuiApplication::sendEvent(w, &e);
+ manager->global_accepted_action = e.isAccepted() ? e.dropAction() : Qt::IgnoreAction;
+ if (manager->global_accepted_action != Qt::IgnoreAction) {
+ me.setDropAction(manager->global_accepted_action);
+ me.accept();
+ }
+ }
+ QGuiApplication::sendEvent(w, &me);
+ manager->global_accepted_action = me.isAccepted() ? me.dropAction() : Qt::IgnoreAction;
+ return manager->global_accepted_action;
+}
+
+Qt::DropAction QGuiApplicationPrivate::processDrop(QWindow *w, QMimeData *dropData, const QPoint &p)
+{
+ QDragManager *manager = QDragManager::self();
+ QDropEvent de(p, manager->possible_actions, dropData,
+ QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers());
+ QGuiApplication::sendEvent(w, &de);
+ manager->global_accepted_action = de.isAccepted() ? de.dropAction() : Qt::IgnoreAction;
+ return manager->global_accepted_action;
+}
+
+#ifndef QT_NO_CLIPBOARD
+QClipboard * QGuiApplication::clipboard()
+{
+ if (QGuiApplicationPrivate::qt_clipboard == 0) {
+ if (!qApp) {
+ qWarning("QGuiApplication: Must construct a QGuiApplication before accessing a QClipboard");
+ return 0;
+ }
+ QGuiApplicationPrivate::qt_clipboard = new QClipboard(0);
+ }
+ return QGuiApplicationPrivate::qt_clipboard;
+}
+#endif
+
+/*!
+ Returns the application palette.
+
+ \sa setPalette(), QWidget::palette()
+*/
+QPalette QGuiApplication::palette()
+{
+ if (!QGuiApplicationPrivate::app_pal)
+ QGuiApplicationPrivate::app_pal = new QPalette(Qt::black);
+ return *QGuiApplicationPrivate::app_pal;
+}
+
+QFont QGuiApplication::font()
+{
+ QMutexLocker locker(applicationFontMutex());
+ if (!QGuiApplicationPrivate::app_font)
+ QGuiApplicationPrivate::app_font =
+ new QFont(QGuiApplicationPrivate::platformIntegration()->fontDatabase()->defaultFont());
+ return *QGuiApplicationPrivate::app_font;
+}
+
+void QGuiApplication::setFont(const QFont &font)
+{
+ QMutexLocker locker(applicationFontMutex());
+ if (!QGuiApplicationPrivate::app_font)
+ QGuiApplicationPrivate::app_font = new QFont(font);
+ else
+ *QGuiApplicationPrivate::app_font = font;
+}
+
+/*!
+ \fn bool QGuiApplication::isRightToLeft()
+
+ Returns true if the application's layout direction is
+ Qt::RightToLeft; otherwise returns false.
+
+ \sa layoutDirection(), isLeftToRight()
+*/
+
+/*!
+ \fn bool QGuiApplication::isLeftToRight()
+
+ Returns true if the application's layout direction is
+ Qt::LeftToRight; otherwise returns false.
+
+ \sa layoutDirection(), isRightToLeft()
+*/
+
+void QGuiApplicationPrivate::notifyLayoutDirectionChange()
+{
+}
+
+void QGuiApplicationPrivate::notifyActiveWindowChange(QWindow *)
+{
+}
+
+
+/*!
+ \property QGuiApplication::quitOnLastWindowClosed
+
+ \brief whether the application implicitly quits when the last window is
+ closed.
+
+ The default is true.
+
+ If this property is true, the applications quits when the last visible
+ primary window (i.e. window with no parent) is closed.
+
+ \sa quit(), QWindow::close()
+ */
+
+void QGuiApplication::setQuitOnLastWindowClosed(bool quit)
+{
+ QGuiApplicationPrivate::quitOnLastWindowClosed = quit;
+}
+
+
+
+bool QGuiApplication::quitOnLastWindowClosed()
+{
+ return QGuiApplicationPrivate::quitOnLastWindowClosed;
+}
+
+
+
+void QGuiApplicationPrivate::emitLastWindowClosed()
+{
+ if (qGuiApp && qGuiApp->d_func()->in_exec) {
+ if (QGuiApplicationPrivate::quitOnLastWindowClosed) {
+ // get ready to quit, this event might be removed if the
+ // event loop is re-entered, however
+ QGuiApplication::postEvent(qApp, new QEvent(QEvent::Quit));
+ }
+ emit qGuiApp->lastWindowClosed();
+ }
+}
+
+
+/*!
+ \property QGuiApplication::layoutDirection
+ \brief the default layout direction for this application
+
+ On system start-up, the default layout direction depends on the
+ application's language.
+
+ \sa QWidget::layoutDirection, isLeftToRight(), isRightToLeft()
+ */
+
+void QGuiApplication::setLayoutDirection(Qt::LayoutDirection direction)
+{
+ if (layout_direction == direction || direction == Qt::LayoutDirectionAuto)
+ return;
+
+ layout_direction = direction;
+
+ QGuiApplicationPrivate::self->notifyLayoutDirectionChange();
+}
+
+Qt::LayoutDirection QGuiApplication::layoutDirection()
+{
+ return layout_direction;
+}
+
+/*!
+ \fn QCursor *QGuiApplication::overrideCursor()
+
+ 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).
+
+ \sa setOverrideCursor(), restoreOverrideCursor()
+*/
+#ifndef QT_NO_CURSOR
+QCursor *QGuiApplication::overrideCursor()
+{
+ return qGuiApp->d_func()->cursor_list.isEmpty() ? 0 : &qGuiApp->d_func()->cursor_list.first();
+}
+
+/*!
+ Changes the currently active application override cursor to \a cursor.
+
+ This function has no effect if setOverrideCursor() was not called.
+
+ \sa setOverrideCursor(), overrideCursor(), restoreOverrideCursor(),
+ QWidget::setCursor()
+ */
+void QGuiApplication::changeOverrideCursor(const QCursor &cursor)
+{
+ if (qGuiApp->d_func()->cursor_list.isEmpty())
+ return;
+ qGuiApp->d_func()->cursor_list.removeFirst();
+ setOverrideCursor(cursor);
+}
+#endif
+
+/*!
+ \fn void QGuiApplication::setOverrideCursor(const QCursor &cursor, bool replace)
+
+ Use changeOverrideCursor(\a cursor) (if \a replace is true) or
+ setOverrideCursor(\a cursor) (if \a replace is false).
+*/
+
+#ifndef QT_NO_CURSOR
+void QGuiApplication::setOverrideCursor(const QCursor &cursor)
+{
+ qGuiApp->d_func()->cursor_list.prepend(cursor);
+}
+
+void QGuiApplication::restoreOverrideCursor()
+{
+ if (qGuiApp->d_func()->cursor_list.isEmpty())
+ return;
+ qGuiApp->d_func()->cursor_list.removeFirst();
+}
+#endif// QT_NO_CURSOR
+
+/*!
+ \since 5.0
+
+ returns the style hints.
+
+ The style hints encapsulate a set of platform dependent properties
+ such as double click intervals, full width selection and others.
+
+ The hints can be used to integrate tighter with the underlying platform.
+
+ \sa QStyleHints
+ */
+QStyleHints *QGuiApplication::styleHints() const
+{
+ Q_D(const QGuiApplication);
+ if (!d->styleHints)
+ const_cast<QGuiApplicationPrivate *>(d)->styleHints = new QStyleHints();
+ return d->styleHints;
+}
+
+
+/*!
+ \since 5.0
+
+ returns the input panel.
+
+ The input panel returns properties about the state and position of
+ the virtual keyboard. It also provides information about the position of the
+ current focused input element.
+
+ \sa QInputPanel
+ */
+QInputPanel *QGuiApplication::inputPanel() const
+{
+ Q_D(const QGuiApplication);
+ if (!d->inputPanel)
+ const_cast<QGuiApplicationPrivate *>(d)->inputPanel = new QInputPanel();
+ return d->inputPanel;
+}
+
+
+// Returns the current platform used by keyBindings
+uint QGuiApplicationPrivate::currentKeyPlatform()
+{
+ uint platform = KB_Win;
+#ifdef Q_OS_MAC
+ platform = KB_Mac;
+#elif defined Q_WS_X11
+ platform = KB_X11;
+ // ## TODO: detect these
+#if 0
+ if (X11->desktopEnvironment == DE_KDE)
+ platform |= KB_KDE;
+ if (X11->desktopEnvironment == DE_GNOME)
+ platform |= KB_Gnome;
+ if (X11->desktopEnvironment == DE_CDE)
+ platform |= KB_CDE;
+#endif
+#endif
+ return platform;
+}
+
+/*!
+ \since 4.2
+
+ Returns the current keyboard input locale.
+*/
+QLocale QGuiApplication::keyboardInputLocale()
+{
+ if (!QGuiApplicationPrivate::checkInstance("keyboardInputLocale"))
+ return QLocale::c();
+ return qt_keymapper_private()->keyboardInputLocale;
+}
+
+/*!
+ \since 4.2
+
+ Returns the current keyboard input direction.
+*/
+Qt::LayoutDirection QGuiApplication::keyboardInputDirection()
+{
+ if (!QGuiApplicationPrivate::checkInstance("keyboardInputDirection"))
+ return Qt::LeftToRight;
+ return qt_keymapper_private()->keyboardInputDirection;
+}
+
+/*!
+ \since 4.5
+ \fn void QGuiApplication::fontDatabaseChanged()
+
+ This signal is emitted when application fonts are loaded or removed.
+
+ \sa QFontDatabase::addApplicationFont(),
+ QFontDatabase::addApplicationFontFromData(),
+ QFontDatabase::removeAllApplicationFonts(),
+ QFontDatabase::removeApplicationFont()
+*/
+
+// These pixmaps approximate the images in the Windows User Interface Guidelines.
+
+// XPM
+
+static const char * const move_xpm[] = {
+"11 20 3 1",
+". c None",
+#if defined(Q_WS_WIN)
+"a c #000000",
+"X c #FFFFFF", // Windows cursor is traditionally white
+#else
+"a c #FFFFFF",
+"X c #000000", // X11 cursor is traditionally black
+#endif
+"aa.........",
+"aXa........",
+"aXXa.......",
+"aXXXa......",
+"aXXXXa.....",
+"aXXXXXa....",
+"aXXXXXXa...",
+"aXXXXXXXa..",
+"aXXXXXXXXa.",
+"aXXXXXXXXXa",
+"aXXXXXXaaaa",
+"aXXXaXXa...",
+"aXXaaXXa...",
+"aXa..aXXa..",
+"aa...aXXa..",
+"a.....aXXa.",
+"......aXXa.",
+".......aXXa",
+".......aXXa",
+"........aa."};
+
+#ifdef Q_WS_WIN
+/* XPM */
+static const char * const ignore_xpm[] = {
+"24 30 3 1",
+". c None",
+"a c #000000",
+"X c #FFFFFF",
+"aa......................",
+"aXa.....................",
+"aXXa....................",
+"aXXXa...................",
+"aXXXXa..................",
+"aXXXXXa.................",
+"aXXXXXXa................",
+"aXXXXXXXa...............",
+"aXXXXXXXXa..............",
+"aXXXXXXXXXa.............",
+"aXXXXXXaaaa.............",
+"aXXXaXXa................",
+"aXXaaXXa................",
+"aXa..aXXa...............",
+"aa...aXXa...............",
+"a.....aXXa..............",
+"......aXXa.....XXXX.....",
+".......aXXa..XXaaaaXX...",
+".......aXXa.XaaaaaaaaX..",
+"........aa.XaaaXXXXaaaX.",
+"...........XaaaaX..XaaX.",
+"..........XaaXaaaX..XaaX",
+"..........XaaXXaaaX.XaaX",
+"..........XaaX.XaaaXXaaX",
+"..........XaaX..XaaaXaaX",
+"...........XaaX..XaaaaX.",
+"...........XaaaXXXXaaaX.",
+"............XaaaaaaaaX..",
+".............XXaaaaXX...",
+"...............XXXX....."};
+#endif
+
+/* XPM */
+static const char * const copy_xpm[] = {
+"24 30 3 1",
+". c None",
+"a c #000000",
+"X c #FFFFFF",
+#if defined(Q_WS_WIN) // Windows cursor is traditionally white
+"aa......................",
+"aXa.....................",
+"aXXa....................",
+"aXXXa...................",
+"aXXXXa..................",
+"aXXXXXa.................",
+"aXXXXXXa................",
+"aXXXXXXXa...............",
+"aXXXXXXXXa..............",
+"aXXXXXXXXXa.............",
+"aXXXXXXaaaa.............",
+"aXXXaXXa................",
+"aXXaaXXa................",
+"aXa..aXXa...............",
+"aa...aXXa...............",
+"a.....aXXa..............",
+"......aXXa..............",
+".......aXXa.............",
+".......aXXa.............",
+"........aa...aaaaaaaaaaa",
+#else
+"XX......................",
+"XaX.....................",
+"XaaX....................",
+"XaaaX...................",
+"XaaaaX..................",
+"XaaaaaX.................",
+"XaaaaaaX................",
+"XaaaaaaaX...............",
+"XaaaaaaaaX..............",
+"XaaaaaaaaaX.............",
+"XaaaaaaXXXX.............",
+"XaaaXaaX................",
+"XaaXXaaX................",
+"XaX..XaaX...............",
+"XX...XaaX...............",
+"X.....XaaX..............",
+"......XaaX..............",
+".......XaaX.............",
+".......XaaX.............",
+"........XX...aaaaaaaaaaa",
+#endif
+".............aXXXXXXXXXa",
+".............aXXXXXXXXXa",
+".............aXXXXaXXXXa",
+".............aXXXXaXXXXa",
+".............aXXaaaaaXXa",
+".............aXXXXaXXXXa",
+".............aXXXXaXXXXa",
+".............aXXXXXXXXXa",
+".............aXXXXXXXXXa",
+".............aaaaaaaaaaa"};
+
+/* XPM */
+static const char * const link_xpm[] = {
+"24 30 3 1",
+". c None",
+"a c #000000",
+"X c #FFFFFF",
+#if defined(Q_WS_WIN) // Windows cursor is traditionally white
+"aa......................",
+"aXa.....................",
+"aXXa....................",
+"aXXXa...................",
+"aXXXXa..................",
+"aXXXXXa.................",
+"aXXXXXXa................",
+"aXXXXXXXa...............",
+"aXXXXXXXXa..............",
+"aXXXXXXXXXa.............",
+"aXXXXXXaaaa.............",
+"aXXXaXXa................",
+"aXXaaXXa................",
+"aXa..aXXa...............",
+"aa...aXXa...............",
+"a.....aXXa..............",
+"......aXXa..............",
+".......aXXa.............",
+".......aXXa.............",
+"........aa...aaaaaaaaaaa",
+#else
+"XX......................",
+"XaX.....................",
+"XaaX....................",
+"XaaaX...................",
+"XaaaaX..................",
+"XaaaaaX.................",
+"XaaaaaaX................",
+"XaaaaaaaX...............",
+"XaaaaaaaaX..............",
+"XaaaaaaaaaX.............",
+"XaaaaaaXXXX.............",
+"XaaaXaaX................",
+"XaaXXaaX................",
+"XaX..XaaX...............",
+"XX...XaaX...............",
+"X.....XaaX..............",
+"......XaaX..............",
+".......XaaX.............",
+".......XaaX.............",
+"........XX...aaaaaaaaaaa",
+#endif
+".............aXXXXXXXXXa",
+".............aXXXaaaaXXa",
+".............aXXXXaaaXXa",
+".............aXXXaaaaXXa",
+".............aXXaaaXaXXa",
+".............aXXaaXXXXXa",
+".............aXXaXXXXXXa",
+".............aXXXaXXXXXa",
+".............aXXXXXXXXXa",
+".............aaaaaaaaaaa"};
+
+QPixmap QGuiApplicationPrivate::getPixmapCursor(Qt::CursorShape cshape)
+{
+#if defined(Q_WS_X11) || defined(Q_WS_WIN)
+ if (!move_cursor) {
+ move_cursor = new QPixmap((const char **)move_xpm);
+ copy_cursor = new QPixmap((const char **)copy_xpm);
+ link_cursor = new QPixmap((const char **)link_xpm);
+#ifdef Q_WS_WIN
+ ignore_cursor = new QPixmap((const char **)ignore_xpm);
+#endif
+ }
+
+ switch (cshape) {
+ case Qt::DragMoveCursor:
+ return *move_cursor;
+ case Qt::DragCopyCursor:
+ return *copy_cursor;
+ case Qt::DragLinkCursor:
+ return *link_cursor;
+#ifdef Q_WS_WIN
+ case Qt::ForbiddenCursor:
+ return *ignore_cursor;
+#endif
+ default:
+ break;
+ }
+#else
+ Q_UNUSED(cshape);
+#endif
+ return QPixmap();
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/kernel/qguiapplication.h b/src/gui/kernel/qguiapplication.h
new file mode 100644
index 0000000000..0649b5de31
--- /dev/null
+++ b/src/gui/kernel/qguiapplication.h
@@ -0,0 +1,158 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGUIAPPLICATION_QPA_H
+#define QGUIAPPLICATION_QPA_H
+
+#include <QtCore/qcoreapplication.h>
+#include <QtGui/qwindowdefs.h>
+#include <QtCore/qlocale.h>
+#include <QtCore/qpoint.h>
+#include <QtCore/qsize.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QGuiApplicationPrivate;
+class QPlatformNativeInterface;
+class QPalette;
+class QScreen;
+class QStyleHints;
+class QInputPanel;
+
+#if defined(qApp)
+#undef qApp
+#endif
+#define qApp (static_cast<QGuiApplication *>(QCoreApplication::instance()))
+
+#if defined(qGuiApp)
+#undef qGuiApp
+#endif
+#define qGuiApp (static_cast<QGuiApplication *>(QCoreApplication::instance()))
+
+class Q_GUI_EXPORT QGuiApplication : public QCoreApplication
+{
+ Q_OBJECT
+ Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection)
+
+ Q_PROPERTY(bool quitOnLastWindowClosed READ quitOnLastWindowClosed WRITE setQuitOnLastWindowClosed)
+
+public:
+ QGuiApplication(int &argc, char **argv, int = ApplicationFlags);
+ virtual ~QGuiApplication();
+
+ static QWindowList topLevelWindows();
+ static QWindow *topLevelAt(const QPoint &pos);
+
+ static QWindow *activeWindow();
+ static QScreen *primaryScreen();
+ static QList<QScreen *> screens();
+
+#ifndef QT_NO_CURSOR
+ static QCursor *overrideCursor();
+ static void setOverrideCursor(const QCursor &);
+ static void changeOverrideCursor(const QCursor &);
+ static void restoreOverrideCursor();
+#endif
+
+ static QFont font();
+ static void setFont(const QFont &);
+
+#ifndef QT_NO_CLIPBOARD
+ static QClipboard *clipboard();
+#endif
+
+ static QPalette palette();
+
+ static Qt::KeyboardModifiers keyboardModifiers();
+ static Qt::MouseButtons mouseButtons();
+
+ static void setLayoutDirection(Qt::LayoutDirection direction);
+ static Qt::LayoutDirection layoutDirection();
+
+ static inline bool isRightToLeft() { return layoutDirection() == Qt::RightToLeft; }
+ static inline bool isLeftToRight() { return layoutDirection() == Qt::LeftToRight; }
+
+ // ### move to QInputPanel
+ static QLocale keyboardInputLocale();
+ static Qt::LayoutDirection keyboardInputDirection();
+
+ QStyleHints *styleHints() const;
+ QInputPanel *inputPanel() const;
+
+ static QPlatformNativeInterface *platformNativeInterface();
+
+ static void setQuitOnLastWindowClosed(bool quit);
+ static bool quitOnLastWindowClosed();
+
+ static int exec();
+ bool notify(QObject *, QEvent *);
+
+Q_SIGNALS:
+ void fontDatabaseChanged();
+ void screenAdded(QScreen *screen);
+ void lastWindowClosed();
+
+protected:
+ bool event(QEvent *);
+ bool compressEvent(QEvent *, QObject *receiver, QPostEventList *);
+
+ QGuiApplication(QGuiApplicationPrivate &p);
+
+private:
+ Q_DISABLE_COPY(QGuiApplication)
+ Q_DECLARE_PRIVATE(QGuiApplication)
+
+#ifndef QT_NO_GESTURES
+ friend class QGestureManager;
+#endif
+ friend class QFontDatabasePrivate;
+ friend class QPlatformIntegration;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QGUIAPPLICATION_QPA_H
diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h
new file mode 100644
index 0000000000..97cf7d371e
--- /dev/null
+++ b/src/gui/kernel/qguiapplication_p.h
@@ -0,0 +1,194 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGUIAPPLICATION_QPA_P_H
+#define QGUIAPPLICATION_QPA_P_H
+
+#include <QtGui/qguiapplication.h>
+
+#include <QtCore/QPointF>
+#include <QtCore/private/qcoreapplication_p.h>
+
+#include <QtCore/private/qthread_p.h>
+
+#include <QWindowSystemInterface>
+#include "private/qwindowsysteminterface_qpa_p.h"
+#include "QtGui/qplatformintegration_qpa.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class Q_GUI_EXPORT QGuiApplicationPrivate : public QCoreApplicationPrivate
+{
+ Q_DECLARE_PUBLIC(QGuiApplication)
+public:
+ QGuiApplicationPrivate(int &argc, char **argv, int flags);
+ ~QGuiApplicationPrivate();
+
+ void createPlatformIntegration();
+ void createEventDispatcher();
+ void setEventDispatcher(QAbstractEventDispatcher *eventDispatcher);
+
+ virtual void notifyLayoutDirectionChange();
+ virtual void notifyActiveWindowChange(QWindow *previous);
+
+ static Qt::KeyboardModifiers modifier_buttons;
+ static Qt::MouseButtons mouse_buttons;
+
+ static QPlatformIntegration *platform_integration;
+
+ static QPlatformIntegration *platformIntegration()
+ { return platform_integration; }
+
+ enum KeyPlatform {
+ KB_Win = 1,
+ KB_Mac = 2,
+ KB_X11 = 4,
+ KB_KDE = 8,
+ KB_Gnome = 16,
+ KB_CDE = 32,
+ KB_S60 = 64,
+ KB_All = 0xffff
+ };
+
+ static uint currentKeyPlatform();
+
+ static QAbstractEventDispatcher *qt_qpa_core_dispatcher()
+ { return QCoreApplication::instance()->d_func()->threadData->eventDispatcher; }
+
+ static void processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent *e);
+ static void processKeyEvent(QWindowSystemInterfacePrivate::KeyEvent *e);
+ static void processWheelEvent(QWindowSystemInterfacePrivate::WheelEvent *e);
+ static void processTouchEvent(QWindowSystemInterfacePrivate::TouchEvent *e);
+
+ static void processCloseEvent(QWindowSystemInterfacePrivate::CloseEvent *e);
+
+ static void processGeometryChangeEvent(QWindowSystemInterfacePrivate::GeometryChangeEvent *e);
+
+ static void processEnterEvent(QWindowSystemInterfacePrivate::EnterEvent *e);
+ static void processLeaveEvent(QWindowSystemInterfacePrivate::LeaveEvent *e);
+
+ static void processActivatedEvent(QWindowSystemInterfacePrivate::ActivatedWindowEvent *e);
+ static void processWindowStateChangedEvent(QWindowSystemInterfacePrivate::WindowStateChangedEvent *e);
+
+ static void processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *e);
+
+ static void reportScreenCount(QWindowSystemInterfacePrivate::ScreenCountEvent *e);
+ static void reportGeometryChange(QWindowSystemInterfacePrivate::ScreenGeometryEvent *e);
+ static void reportAvailableGeometryChange(QWindowSystemInterfacePrivate::ScreenAvailableGeometryEvent *e);
+
+ static void processMapEvent(QWindowSystemInterfacePrivate::MapEvent *e);
+ static void processUnmapEvent(QWindowSystemInterfacePrivate::UnmapEvent *e);
+
+ static void processExposeEvent(QWindowSystemInterfacePrivate::ExposeEvent *e);
+
+ static Qt::DropAction processDrag(QWindow *w, QMimeData *dropData, const QPoint &p);
+ static Qt::DropAction processDrop(QWindow *w, QMimeData *dropData, const QPoint &p);
+
+ static inline Qt::Alignment visualAlignment(Qt::LayoutDirection direction, Qt::Alignment alignment)
+ {
+ if (!(alignment & Qt::AlignHorizontal_Mask))
+ alignment |= Qt::AlignLeft;
+ if ((alignment & Qt::AlignAbsolute) == 0 && (alignment & (Qt::AlignLeft | Qt::AlignRight))) {
+ if (direction == Qt::RightToLeft)
+ alignment ^= (Qt::AlignLeft | Qt::AlignRight);
+ alignment |= Qt::AlignAbsolute;
+ }
+ return alignment;
+ }
+
+ static void emitLastWindowClosed();
+
+ QPixmap getPixmapCursor(Qt::CursorShape cshape);
+
+ static QGuiApplicationPrivate *instance() { return self; }
+
+ static bool app_do_modal;
+
+ static Qt::MouseButtons buttons;
+ static ulong mousePressTime;
+ static Qt::MouseButton mousePressButton;
+ static int mousePressX;
+ static int mousePressY;
+ static int mouse_double_click_distance;
+ static QPointF lastCursorPosition;
+
+#ifndef QT_NO_CLIPBOARD
+ static QClipboard *qt_clipboard;
+#endif
+
+ static QPalette *app_pal;
+
+ static QWindowList window_list;
+ static QWindow *active_window;
+
+#ifndef QT_NO_CURSOR
+ QList<QCursor> cursor_list;
+#endif
+ static QList<QScreen *> screen_list;
+
+ static QFont *app_font;
+
+ QStyleHints *styleHints;
+ QInputPanel *inputPanel;
+
+ static bool quitOnLastWindowClosed;
+
+ QString qmljs_debug_arguments; // a string containing arguments for js/qml debugging.
+ inline QString qmljsDebugArgumentsString() { return qmljs_debug_arguments; }
+
+private:
+ void init();
+
+ static QGuiApplicationPrivate *self;
+
+ QMap<int, QWeakPointer<QWindow> > windowForTouchPointId;
+ QMap<int, QTouchEvent::TouchPoint> appCurrentTouchPoints;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QGUIAPPLICATION_QPA_P_H
diff --git a/src/gui/kernel/qguiplatformplugin_p.h b/src/gui/kernel/qguiplatformplugin_p.h
deleted file mode 100644
index 907b9bd508..0000000000
--- a/src/gui/kernel/qguiplatformplugin_p.h
+++ /dev/null
@@ -1,126 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGUIPLATFORM_P_H
-#define QGUIPLATFORM_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/qplugin.h>
-#include <QtCore/qfactoryinterface.h>
-#include <QtGui/qdialog.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QStyle;
-class QPalette;
-class QIcon;
-class QFileDialog;
-class QColorDialog;
-class QFileInfo;
-
-struct Q_GUI_EXPORT QGuiPlatformPluginInterface : public QFactoryInterface
-{
-};
-
-#define QGuiPlatformPluginInterface_iid "com.nokia.qt.QGuiPlatformPluginInterface"
-
-Q_DECLARE_INTERFACE(QGuiPlatformPluginInterface, QGuiPlatformPluginInterface_iid)
-
-class Q_GUI_EXPORT QGuiPlatformPlugin : public QObject, public QGuiPlatformPluginInterface
-{
- Q_OBJECT
- Q_INTERFACES(QGuiPlatformPluginInterface:QFactoryInterface)
- public:
- explicit QGuiPlatformPlugin(QObject *parent = 0);
- ~QGuiPlatformPlugin();
-
- virtual QStringList keys() const { return QStringList() << QLatin1String("default"); };
-
- virtual QString styleName();
- virtual QPalette palette();
- virtual QString systemIconThemeName();
- virtual QStringList iconThemeSearchPaths();
- virtual QIcon fileSystemIcon(const QFileInfo &);
-
- enum PlatformHint { PH_ToolButtonStyle, PH_ToolBarIconSize, PH_ItemView_ActivateItemOnSingleClick };
- virtual int platformHint(PlatformHint hint);
-
-
- virtual void fileDialogDelete(QFileDialog *) {}
- virtual bool fileDialogSetVisible(QFileDialog *, bool) { return false; }
- virtual QDialog::DialogCode fileDialogResultCode(QFileDialog *) { return QDialog::Rejected; }
- virtual void fileDialogSetDirectory(QFileDialog *, const QString &) {}
- virtual QString fileDialogDirectory(const QFileDialog *) const { return QString(); }
- virtual void fileDialogSelectFile(QFileDialog *, const QString &) {}
- virtual QStringList fileDialogSelectedFiles(const QFileDialog *) const { return QStringList(); }
- virtual void fileDialogSetFilter(QFileDialog *) {}
- virtual void fileDialogSetNameFilters(QFileDialog *, const QStringList &) {}
- virtual void fileDialogSelectNameFilter(QFileDialog *, const QString &) {}
- virtual QString fileDialogSelectedNameFilter(const QFileDialog *) const { return QString(); }
-
- virtual void colorDialogDelete(QColorDialog *) {}
- virtual bool colorDialogSetVisible(QColorDialog *, bool) { return false; }
- virtual void colorDialogSetCurrentColor(QColorDialog *, const QColor &) {}
-};
-
-//internal
-QGuiPlatformPlugin *qt_guiPlatformPlugin();
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-
-#endif // QGUIPLATFORMPLUGIN_H
diff --git a/src/gui/kernel/qguivariant.cpp b/src/gui/kernel/qguivariant.cpp
index bd5036650a..f09b9609e6 100644
--- a/src/gui/kernel/qguivariant.cpp
+++ b/src/gui/kernel/qguivariant.cpp
@@ -48,7 +48,6 @@
#include "qdatastream.h"
#include "qdebug.h"
#include "qfont.h"
-#include "qicon.h"
#include "qimage.h"
#include "qkeysequence.h"
#include "qtransform.h"
@@ -58,7 +57,6 @@
#include "qpixmap.h"
#include "qpolygon.h"
#include "qregion.h"
-#include "qsizepolicy.h"
#include "qtextformat.h"
#include "qmatrix4x4.h"
#include "qvector2d.h"
@@ -70,10 +68,7 @@
QT_BEGIN_NAMESPACE
-#ifdef QT3_SUPPORT
-extern QDataStream &qt_stream_out_qcolorgroup(QDataStream &s, const QColorGroup &g);
-extern QDataStream &qt_stream_in_qcolorgroup(QDataStream &s, QColorGroup &g);
-#endif
+Q_GUI_EXPORT const QVariant::Handler *qt_widgets_variant_handler = 0;
Q_CORE_EXPORT const QVariant::Handler *qcoreVariantHandler();
@@ -107,16 +102,6 @@ static void construct(QVariant::Private *x, const void *copy)
case QVariant::Palette:
v_construct<QPalette>(x, copy);
break;
-#ifdef QT3_SUPPORT
- case QVariant::ColorGroup:
- v_construct<QColorGroup>(x, copy);
- break;
-#endif
-#ifndef QT_NO_ICON
- case QVariant::Icon:
- v_construct<QIcon>(x, copy);
- break;
-#endif
case QVariant::Matrix:
v_construct<QMatrix>(x, copy);
break;
@@ -137,9 +122,6 @@ static void construct(QVariant::Private *x, const void *copy)
case QVariant::Pen:
v_construct<QPen>(x, copy);
break;
- case QVariant::SizePolicy:
- v_construct<QSizePolicy>(x, copy);
- break;
#ifndef QT_NO_CURSOR
case QVariant::Cursor:
v_construct<QCursor>(x, copy);
@@ -178,6 +160,13 @@ static void construct(QVariant::Private *x, const void *copy)
v_construct<QQuaternion>(x, copy);
break;
#endif
+ case QVariant::SizePolicy:
+ case QVariant::Icon:
+ if (qt_widgets_variant_handler) {
+ qt_widgets_variant_handler->construct(x, copy);
+ return;
+ }
+ break;
default:
qcoreVariantHandler()->construct(x, copy);
return;
@@ -218,16 +207,6 @@ static void clear(QVariant::Private *d)
case QVariant::Palette:
v_clear<QPalette>(d);
break;
-#ifdef QT3_SUPPORT
- case QVariant::ColorGroup:
- v_clear<QColorGroup>(d);
- break;
-#endif
-#ifndef QT_NO_ICON
- case QVariant::Icon:
- v_clear<QIcon>(d);
- break;
-#endif
case QVariant::Matrix:
v_clear<QMatrix>(d);
break;
@@ -240,9 +219,6 @@ static void clear(QVariant::Private *d)
case QVariant::TextLength:
v_clear<QTextLength>(d);
break;
- case QVariant::SizePolicy:
- v_clear<QSizePolicy>(d);
- break;
#ifndef QT_NO_SHORTCUT
case QVariant::KeySequence:
v_clear<QKeySequence>(d);
@@ -276,6 +252,13 @@ static void clear(QVariant::Private *d)
v_clear<QVector4D>(d);
break;
#endif
+ case QVariant::SizePolicy:
+ case QVariant::Icon:
+ if (qt_widgets_variant_handler) {
+ qt_widgets_variant_handler->clear(d);
+ return;
+ }
+ break;
default:
qcoreVariantHandler()->clear(d);
return;
@@ -300,10 +283,6 @@ static bool isNull(const QVariant::Private *d)
return v_cast<QPixmap>(d)->isNull();
case QVariant::Image:
return v_cast<QImage>(d)->isNull();
-#ifndef QT_NO_ICON
- case QVariant::Icon:
- return v_cast<QIcon>(d)->isNull();
-#endif
case QVariant::Matrix:
case QVariant::TextFormat:
case QVariant::TextLength:
@@ -313,9 +292,6 @@ static bool isNull(const QVariant::Private *d)
case QVariant::Brush:
case QVariant::Color:
case QVariant::Palette:
-#ifdef QT3_SUPPORT
- case QVariant::ColorGroup:
-#endif
case QVariant::SizePolicy:
#ifndef QT_NO_SHORTCUT
case QVariant::KeySequence:
@@ -341,6 +317,10 @@ static bool isNull(const QVariant::Private *d)
case QVariant::Quaternion:
return v_cast<QQuaternion>(d)->isNull();
#endif
+ case QVariant::Icon:
+ if (qt_widgets_variant_handler)
+ return qt_widgets_variant_handler->isNull(d);
+ break;
default:
return qcoreVariantHandler()->isNull(d);
}
@@ -374,10 +354,6 @@ static bool compare(const QVariant::Private *a, const QVariant::Private *b)
return *v_cast<QColor>(a) == *v_cast<QColor>(b);
case QVariant::Palette:
return *v_cast<QPalette>(a) == *v_cast<QPalette>(b);
-#ifdef QT3_SUPPORT
- case QVariant::ColorGroup:
- return *v_cast<QColorGroup>(a) == *v_cast<QColorGroup>(b);
-#endif
#ifndef QT_NO_ICON
case QVariant::Icon:
/* QIcon::operator==() cannot be reasonably implemented for QIcon,
@@ -392,8 +368,6 @@ static bool compare(const QVariant::Private *a, const QVariant::Private *b)
return *v_cast<QTextFormat>(a) == *v_cast<QTextFormat>(b);
case QVariant::TextLength:
return *v_cast<QTextLength>(a) == *v_cast<QTextLength>(b);
- case QVariant::SizePolicy:
- return *v_cast<QSizePolicy>(a) == *v_cast<QSizePolicy>(b);
#ifndef QT_NO_SHORTCUT
case QVariant::KeySequence:
return *v_cast<QKeySequence>(a) == *v_cast<QKeySequence>(b);
@@ -420,6 +394,10 @@ static bool compare(const QVariant::Private *a, const QVariant::Private *b)
case QVariant::Quaternion:
return *v_cast<QQuaternion>(a) == *v_cast<QQuaternion>(b);
#endif
+ case QVariant::SizePolicy:
+ if (qt_widgets_variant_handler)
+ return qt_widgets_variant_handler->compare(a, b);
+ break;
default:
break;
}
@@ -688,17 +666,11 @@ extern Q_CORE_EXPORT const QMetaTypeGuiHelper *qMetaTypeGuiHelper;
static const QLoad##TYPE qLoad##TYPE = qMetaTypeLoadHelper<TYPE>;
#endif
-#ifdef QT3_SUPPORT
-Q_DECL_METATYPE_HELPER(QColorGroup)
-#endif
Q_DECL_METATYPE_HELPER(QFont)
Q_DECL_METATYPE_HELPER(QPixmap)
Q_DECL_METATYPE_HELPER(QBrush)
Q_DECL_METATYPE_HELPER(QColor)
Q_DECL_METATYPE_HELPER(QPalette)
-#ifndef QT_NO_ICON
-Q_DECL_METATYPE_HELPER(QIcon)
-#endif
Q_DECL_METATYPE_HELPER(QImage)
Q_DECL_METATYPE_HELPER(QPolygon)
Q_DECL_METATYPE_HELPER(QRegion)
@@ -706,7 +678,6 @@ Q_DECL_METATYPE_HELPER(QBitmap)
#ifndef QT_NO_CURSOR
Q_DECL_METATYPE_HELPER(QCursor)
#endif
-Q_DECL_METATYPE_HELPER(QSizePolicy)
#ifndef QT_NO_SHORTCUT
Q_DECL_METATYPE_HELPER(QKeySequence)
#endif
@@ -745,21 +716,11 @@ Q_DECL_METATYPE_HELPER(QQuaternion)
#endif
static const QMetaTypeGuiHelper qVariantGuiHelper[] = {
-#ifdef QT3_SUPPORT
- Q_IMPL_METATYPE_HELPER(QColorGroup),
-#else
- {0, 0, 0, 0},
-#endif
Q_IMPL_METATYPE_HELPER(QFont),
Q_IMPL_METATYPE_HELPER(QPixmap),
Q_IMPL_METATYPE_HELPER(QBrush),
Q_IMPL_METATYPE_HELPER(QColor),
Q_IMPL_METATYPE_HELPER(QPalette),
-#ifdef QT_NO_ICON
- {0, 0, 0, 0},
-#else
- Q_IMPL_METATYPE_HELPER(QIcon),
-#endif
Q_IMPL_METATYPE_HELPER(QImage),
Q_IMPL_METATYPE_HELPER(QPolygon),
Q_IMPL_METATYPE_HELPER(QRegion),
@@ -769,7 +730,6 @@ static const QMetaTypeGuiHelper qVariantGuiHelper[] = {
#else
Q_IMPL_METATYPE_HELPER(QCursor),
#endif
- Q_IMPL_METATYPE_HELPER(QSizePolicy),
#ifdef QT_NO_SHORTCUT
{0, 0, 0, 0},
#else
@@ -825,4 +785,5 @@ int qUnregisterGuiVariant()
}
Q_DESTRUCTOR_FUNCTION(qUnregisterGuiVariant)
+
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qinputpanel.cpp b/src/gui/kernel/qinputpanel.cpp
new file mode 100644
index 0000000000..b6160dc71a
--- /dev/null
+++ b/src/gui/kernel/qinputpanel.cpp
@@ -0,0 +1,190 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qinputpanel.h>
+#include <private/qinputpanel_p.h>
+#include <qplatforminputcontext_qpa.h>
+#include <private/qguiapplication_p.h>
+
+QInputPanel::QInputPanel()
+ : QObject(*new QInputPanelPrivate)
+{
+}
+
+QInputPanel::~QInputPanel()
+{
+}
+
+QObject *QInputPanel::inputItem() const
+{
+ Q_D(const QInputPanel);
+ return d->inputItem.data();
+}
+
+void QInputPanel::setInputItem(QObject *inputItem)
+{
+ Q_D(QInputPanel);
+
+ if (d->inputItem.data() == inputItem)
+ return;
+
+ d->inputItem = inputItem;
+ emit inputItemChanged();
+}
+
+QWindow *QInputPanel::inputWindow() const
+{
+ return qApp->activeWindow();
+}
+
+QTransform QInputPanel::inputItemTransform() const
+{
+ Q_D(const QInputPanel);
+ return d->inputItemTransform;
+}
+
+void QInputPanel::setInputItemTransform(const QTransform &transform)
+{
+ Q_D(QInputPanel);
+ if (d->inputItemTransform == transform)
+ return;
+
+ d->inputItemTransform = transform;
+ emit cursorRectangleChanged();
+}
+
+QRectF QInputPanel::cursorRectangle() const
+{
+ Q_D(const QInputPanel);
+
+ if (!d->inputItem)
+ return QRectF();
+
+ QInputMethodQueryEvent query(Qt::ImCursorRectangle);
+ QGuiApplication::sendEvent(d->inputItem.data(), &query);
+ QRect r = query.value(Qt::ImCursorRectangle).toRect();
+ if (!r.isValid())
+ return QRect();
+
+ return d->inputItemTransform.mapRect(r);
+}
+
+QRectF QInputPanel::keyboardRectangle()
+{
+ QPlatformInputContext *ic = QGuiApplicationPrivate::platformIntegration()->inputContext();
+ if (ic)
+ return ic->keyboardRect();
+ return QRectF();
+}
+
+void QInputPanel::show()
+{
+ setVisible(true);
+}
+
+void QInputPanel::hide()
+{
+ setVisible(false);
+}
+
+bool QInputPanel::visible() const
+{
+ Q_D(const QInputPanel);
+
+ return d->visible;
+}
+
+void QInputPanel::setVisible(bool visible)
+{
+ Q_D(QInputPanel);
+ if (d->visible == visible)
+ return;
+
+ d->visible = visible;
+ emit visibleChanged();
+}
+
+bool QInputPanel::isAnimating() const
+{
+ QPlatformInputContext *ic = QGuiApplicationPrivate::platformIntegration()->inputContext();
+ if (ic)
+ return ic->isAnimating();
+ return false;
+}
+
+
+void QInputPanel::update(Qt::InputMethodQueries queries)
+{
+ Q_D(QInputPanel);
+
+ if (!d->inputItem)
+ return;
+
+ QPlatformInputContext *ic = QGuiApplicationPrivate::platformIntegration()->inputContext();
+ if (ic)
+ ic->update(queries);
+
+ if (queries & Qt::ImCursorRectangle)
+ emit cursorRectangleChanged();
+}
+
+void QInputPanel::reset()
+{
+ QPlatformInputContext *ic = QGuiApplicationPrivate::platformIntegration()->inputContext();
+ if (ic)
+ ic->reset();
+}
+
+void QInputPanel::commit()
+{
+ QPlatformInputContext *ic = QGuiApplicationPrivate::platformIntegration()->inputContext();
+ if (ic)
+ ic->commit();
+}
+
+void QInputPanel::invokeAction(Action a, int cursorPosition)
+{
+ QPlatformInputContext *ic = QGuiApplicationPrivate::platformIntegration()->inputContext();
+ if (ic)
+ ic->invokeAction(a, cursorPosition);
+}
+
+#include "moc_qinputpanel.cpp"
diff --git a/src/gui/kernel/qinputpanel.h b/src/gui/kernel/qinputpanel.h
new file mode 100644
index 0000000000..9db54b6664
--- /dev/null
+++ b/src/gui/kernel/qinputpanel.h
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QINPUTPANEL_H
+#define QINPUTPANEL_H
+
+#include <QtCore/qobject.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QInputPanelPrivate;
+class QWindow;
+class QRectF;
+class QTransform;
+
+class Q_GUI_EXPORT QInputPanel : public QObject
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QInputPanel)
+ Q_PROPERTY(QObject *inputItem READ inputItem WRITE setInputItem NOTIFY inputItemChanged)
+ Q_PROPERTY(QRectF cursorRectangle READ cursorRectangle NOTIFY cursorRectangleChanged)
+ Q_PROPERTY(QRectF keyboardRectangle READ keyboardRectangle NOTIFY keyboardRectangleChanged)
+ Q_PROPERTY(bool visible READ visible WRITE setVisible NOTIFY visibleChanged)
+ Q_PROPERTY(bool animating READ isAnimating NOTIFY animatingChanged)
+
+public:
+ QObject *inputItem() const;
+ void setInputItem(QObject *inputItemChanged);
+
+ // the window containing the editor
+ QWindow *inputWindow() const;
+
+ QTransform inputItemTransform() const;
+ void setInputItemTransform(const QTransform &transform);
+
+ // in window coordinates
+ QRectF cursorRectangle() const; // ### what if we have rotations for the item?
+
+ // keyboard geometry in window coords
+ QRectF keyboardRectangle();
+
+ enum Action {
+ Click,
+ ContextMenu
+ };
+
+ bool visible() const;
+ void setVisible(bool visible);
+
+ bool isAnimating() const;
+
+public Q_SLOTS:
+ void show();
+ void hide();
+
+ void update(Qt::InputMethodQueries queries);
+ void reset();
+ void commit();
+
+ void invokeAction(Action a, int cursorPosition);
+
+Q_SIGNALS:
+ void inputItemChanged();
+ void cursorRectangleChanged();
+ void keyboardRectangleChanged();
+ void visibleChanged();
+ void animatingChanged();
+
+private:
+ friend class QGuiApplication;
+ friend class QGuiApplicationPrivate;
+ friend class QPlatformInputContext;
+ QInputPanel();
+ ~QInputPanel();
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/gui/kernel/qinputpanel_p.h b/src/gui/kernel/qinputpanel_p.h
new file mode 100644
index 0000000000..84cfb06c94
--- /dev/null
+++ b/src/gui/kernel/qinputpanel_p.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QINPUTPANEL_P_H
+#define QINPUTPANEL_P_H
+
+#include <qinputpanel.h>
+#include <private/qobject_p.h>
+#include <QtCore/QWeakPointer>
+#include <QTransform>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QInputPanelPrivate : public QObjectPrivate
+{
+public:
+ inline QInputPanelPrivate()
+ : visible(false)
+ {}
+ QTransform inputItemTransform;
+ QWeakPointer<QObject> inputItem;
+ bool visible;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/gui/kernel/qkde_p.h b/src/gui/kernel/qkde_p.h
deleted file mode 100644
index 23587db360..0000000000
--- a/src/gui/kernel/qkde_p.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QKDE_H
-#define QKDE_H
-
-#include <QtCore/qglobal.h>
-#include <QtGui/QPalette>
-#include <QtGui/QIcon>
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-#if defined(Q_WS_X11)
-
-
-QT_BEGIN_NAMESPACE
-
-/*!\internal
- This namespace contains helper function to help KDE integration
- They are only used if we detect the use of KDE and the KDE platform plugin is not found (old KDE version)
- Or if the detected KDE version is KDE3
-*/
-namespace QKde {
- QString kdeHome();
- QString kdeStyle();
- QPalette kdePalette();
- int kdeToolButtonStyle();
- int kdeToolBarIconSize();
-}
-
-
-QT_END_NAMESPACE
-
-#endif // Q_WS_X11
-#endif // QKDE_H
diff --git a/src/gui/kernel/qkeymapper.cpp b/src/gui/kernel/qkeymapper.cpp
index 46e6c0cde9..4ee7d66dd8 100644
--- a/src/gui/kernel/qkeymapper.cpp
+++ b/src/gui/kernel/qkeymapper.cpp
@@ -40,11 +40,10 @@
****************************************************************************/
-#include "qapplication.h"
+#include "qguiapplication.h"
#include <private/qobject_p.h>
#include "qkeymapper_p.h"
-#include <qwidget.h>
QT_BEGIN_NAMESPACE
@@ -91,6 +90,8 @@ void QKeyMapper::changeKeyboard()
{
instance()->d_func()->clearMappings();
+ // ## TODO: Support KeyboardLayoutChange on QPA
+#if 0
// inform all toplevel widgets of the change
QEvent e(QEvent::KeyboardLayoutChange);
QWidgetList list = QApplication::topLevelWidgets();
@@ -98,6 +99,7 @@ void QKeyMapper::changeKeyboard()
QWidget *w = list.at(i);
qt_sendSpontaneousEvent(w, &e);
}
+#endif
}
Q_GLOBAL_STATIC(QKeyMapper, keymapper)
diff --git a/src/gui/kernel/qkeymapper_mac.cpp b/src/gui/kernel/qkeymapper_mac.cpp
deleted file mode 100644
index b5b3c4b5b9..0000000000
--- a/src/gui/kernel/qkeymapper_mac.cpp
+++ /dev/null
@@ -1,1023 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <private/qt_mac_p.h>
-#include <qdebug.h>
-#include <qevent.h>
-#include <private/qevent_p.h>
-#include <qtextcodec.h>
-#include <qapplication.h>
-#include <qinputcontext.h>
-#include <private/qkeymapper_p.h>
-#include <private/qapplication_p.h>
-#include <private/qmacinputcontext_p.h>
-
-QT_BEGIN_NAMESPACE
-
-QT_USE_NAMESPACE
-
-/*****************************************************************************
- QKeyMapper debug facilities
- *****************************************************************************/
-//#define DEBUG_KEY_BINDINGS
-//#define DEBUG_KEY_BINDINGS_MODIFIERS
-//#define DEBUG_KEY_MAPS
-
-/*****************************************************************************
- Internal variables and functions
- *****************************************************************************/
-bool qt_mac_eat_unicode_key = false;
-extern bool qt_sendSpontaneousEvent(QObject *obj, QEvent *event); //qapplication_mac.cpp
-
-Q_GUI_EXPORT void qt_mac_secure_keyboard(bool b)
-{
- static bool secure = false;
- if (b != secure){
- b ? EnableSecureEventInput() : DisableSecureEventInput();
- secure = b;
- }
-}
-
-/*
- \internal
- A Mac KeyboardLayoutItem has 8 possible states:
- 1. Unmodified
- 2. Shift
- 3. Control
- 4. Control + Shift
- 5. Alt
- 6. Alt + Shift
- 7. Alt + Control
- 8. Alt + Control + Shift
- 9. Meta
- 10. Meta + Shift
- 11. Meta + Control
- 12. Meta + Control + Shift
- 13. Meta + Alt
- 14. Meta + Alt + Shift
- 15. Meta + Alt + Control
- 16. Meta + Alt + Control + Shift
-*/
-struct KeyboardLayoutItem {
- bool dirty;
- quint32 qtKey[16]; // Can by any Qt::Key_<foo>, or unicode character
-};
-
-// Possible modifier states.
-// NOTE: The order of these states match the order in QKeyMapperPrivate::updatePossibleKeyCodes()!
-static const Qt::KeyboardModifiers ModsTbl[] = {
- Qt::NoModifier, // 0
- Qt::ShiftModifier, // 1
- Qt::ControlModifier, // 2
- Qt::ControlModifier | Qt::ShiftModifier, // 3
- Qt::AltModifier, // 4
- Qt::AltModifier | Qt::ShiftModifier, // 5
- Qt::AltModifier | Qt::ControlModifier, // 6
- Qt::AltModifier | Qt::ShiftModifier | Qt::ControlModifier, // 7
- Qt::MetaModifier, // 8
- Qt::MetaModifier | Qt::ShiftModifier, // 9
- Qt::MetaModifier | Qt::ControlModifier, // 10
- Qt::MetaModifier | Qt::ControlModifier | Qt::ShiftModifier,// 11
- Qt::MetaModifier | Qt::AltModifier, // 12
- Qt::MetaModifier | Qt::AltModifier | Qt::ShiftModifier, // 13
- Qt::MetaModifier | Qt::AltModifier | Qt::ControlModifier, // 14
- Qt::MetaModifier | Qt::AltModifier | Qt::ShiftModifier | Qt::ControlModifier, // 15
-};
-
-/* key maps */
-struct qt_mac_enum_mapper
-{
- int mac_code;
- int qt_code;
-#if defined(DEBUG_KEY_BINDINGS)
-# define QT_MAC_MAP_ENUM(x) x, #x
- const char *desc;
-#else
-# define QT_MAC_MAP_ENUM(x) x
-#endif
-};
-
-//modifiers
-static qt_mac_enum_mapper qt_mac_modifier_symbols[] = {
- { shiftKey, QT_MAC_MAP_ENUM(Qt::ShiftModifier) },
- { rightShiftKey, QT_MAC_MAP_ENUM(Qt::ShiftModifier) },
- { controlKey, QT_MAC_MAP_ENUM(Qt::MetaModifier) },
- { rightControlKey, QT_MAC_MAP_ENUM(Qt::MetaModifier) },
- { cmdKey, QT_MAC_MAP_ENUM(Qt::ControlModifier) },
- { optionKey, QT_MAC_MAP_ENUM(Qt::AltModifier) },
- { rightOptionKey, QT_MAC_MAP_ENUM(Qt::AltModifier) },
- { kEventKeyModifierNumLockMask, QT_MAC_MAP_ENUM(Qt::KeypadModifier) },
- { 0, QT_MAC_MAP_ENUM(0) }
-};
-Qt::KeyboardModifiers qt_mac_get_modifiers(int keys)
-{
-#ifdef DEBUG_KEY_BINDINGS_MODIFIERS
- qDebug("Qt: internal: **Mapping modifiers: %d (0x%04x)", keys, keys);
-#endif
- Qt::KeyboardModifiers ret = Qt::NoModifier;
- for (int i = 0; qt_mac_modifier_symbols[i].qt_code; i++) {
- if (keys & qt_mac_modifier_symbols[i].mac_code) {
-#ifdef DEBUG_KEY_BINDINGS_MODIFIERS
- qDebug("Qt: internal: got modifier: %s", qt_mac_modifier_symbols[i].desc);
-#endif
- ret |= Qt::KeyboardModifier(qt_mac_modifier_symbols[i].qt_code);
- }
- }
- if (qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)) {
- Qt::KeyboardModifiers oldModifiers = ret;
- ret &= ~(Qt::MetaModifier | Qt::ControlModifier);
- if (oldModifiers & Qt::ControlModifier)
- ret |= Qt::MetaModifier;
- if (oldModifiers & Qt::MetaModifier)
- ret |= Qt::ControlModifier;
- }
- return ret;
-}
-static int qt_mac_get_mac_modifiers(Qt::KeyboardModifiers keys)
-{
-#ifdef DEBUG_KEY_BINDINGS_MODIFIERS
- qDebug("Qt: internal: **Mapping modifiers: %d (0x%04x)", (int)keys, (int)keys);
-#endif
- int ret = 0;
- for (int i = 0; qt_mac_modifier_symbols[i].qt_code; i++) {
- if (keys & qt_mac_modifier_symbols[i].qt_code) {
-#ifdef DEBUG_KEY_BINDINGS_MODIFIERS
- qDebug("Qt: internal: got modifier: %s", qt_mac_modifier_symbols[i].desc);
-#endif
- ret |= qt_mac_modifier_symbols[i].mac_code;
- }
- }
-
- if (qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)) {
- int oldModifiers = ret;
- ret &= ~(controlKeyBit | cmdKeyBit);
- if (oldModifiers & controlKeyBit)
- ret |= cmdKeyBit;
- if (oldModifiers & cmdKeyBit)
- ret |= controlKeyBit;
- }
- return ret;
-}
-void qt_mac_send_modifiers_changed(quint32 modifiers, QObject *object)
-{
- static quint32 cachedModifiers = 0;
- quint32 lastModifiers = cachedModifiers,
- changedModifiers = lastModifiers ^ modifiers;
- cachedModifiers = modifiers;
-
- //check the bits
- static qt_mac_enum_mapper modifier_key_symbols[] = {
- { shiftKeyBit, QT_MAC_MAP_ENUM(Qt::Key_Shift) },
- { rightShiftKeyBit, QT_MAC_MAP_ENUM(Qt::Key_Shift) }, //???
- { controlKeyBit, QT_MAC_MAP_ENUM(Qt::Key_Meta) },
- { rightControlKeyBit, QT_MAC_MAP_ENUM(Qt::Key_Meta) }, //???
- { cmdKeyBit, QT_MAC_MAP_ENUM(Qt::Key_Control) },
- { optionKeyBit, QT_MAC_MAP_ENUM(Qt::Key_Alt) },
- { rightOptionKeyBit, QT_MAC_MAP_ENUM(Qt::Key_Alt) }, //???
- { alphaLockBit, QT_MAC_MAP_ENUM(Qt::Key_CapsLock) },
- { kEventKeyModifierNumLockBit, QT_MAC_MAP_ENUM(Qt::Key_NumLock) },
- { 0, QT_MAC_MAP_ENUM(0) } };
- for (int i = 0; i <= 32; i++) { //just check each bit
- if (!(changedModifiers & (1 << i)))
- continue;
- QEvent::Type etype = QEvent::KeyPress;
- if (lastModifiers & (1 << i))
- etype = QEvent::KeyRelease;
- int key = 0;
- for (uint x = 0; modifier_key_symbols[x].mac_code; x++) {
- if (modifier_key_symbols[x].mac_code == i) {
-#ifdef DEBUG_KEY_BINDINGS_MODIFIERS
- qDebug("got modifier changed: %s", modifier_key_symbols[x].desc);
-#endif
- key = modifier_key_symbols[x].qt_code;
- break;
- }
- }
- if (!key) {
-#ifdef DEBUG_KEY_BINDINGS_MODIFIERS
- qDebug("could not get modifier changed: %d", i);
-#endif
- continue;
- }
-#ifdef DEBUG_KEY_BINDINGS_MODIFIERS
- qDebug("KeyEvent (modif): Sending %s to %s::%s: %d - 0x%08x",
- etype == QEvent::KeyRelease ? "KeyRelease" : "KeyPress",
- object ? object->metaObject()->className() : "none",
- object ? object->objectName().toLatin1().constData() : "",
- key, (int)modifiers);
-#endif
- QKeyEvent ke(etype, key, qt_mac_get_modifiers(modifiers ^ (1 << i)), QLatin1String(""));
- qt_sendSpontaneousEvent(object, &ke);
- }
-}
-
-//keyboard keys (non-modifiers)
-static qt_mac_enum_mapper qt_mac_keyboard_symbols[] = {
- { kHomeCharCode, QT_MAC_MAP_ENUM(Qt::Key_Home) },
- { kEnterCharCode, QT_MAC_MAP_ENUM(Qt::Key_Enter) },
- { kEndCharCode, QT_MAC_MAP_ENUM(Qt::Key_End) },
- { kBackspaceCharCode, QT_MAC_MAP_ENUM(Qt::Key_Backspace) },
- { kTabCharCode, QT_MAC_MAP_ENUM(Qt::Key_Tab) },
- { kPageUpCharCode, QT_MAC_MAP_ENUM(Qt::Key_PageUp) },
- { kPageDownCharCode, QT_MAC_MAP_ENUM(Qt::Key_PageDown) },
- { kReturnCharCode, QT_MAC_MAP_ENUM(Qt::Key_Return) },
- { kEscapeCharCode, QT_MAC_MAP_ENUM(Qt::Key_Escape) },
- { kLeftArrowCharCode, QT_MAC_MAP_ENUM(Qt::Key_Left) },
- { kRightArrowCharCode, QT_MAC_MAP_ENUM(Qt::Key_Right) },
- { kUpArrowCharCode, QT_MAC_MAP_ENUM(Qt::Key_Up) },
- { kDownArrowCharCode, QT_MAC_MAP_ENUM(Qt::Key_Down) },
- { kHelpCharCode, QT_MAC_MAP_ENUM(Qt::Key_Help) },
- { kDeleteCharCode, QT_MAC_MAP_ENUM(Qt::Key_Delete) },
-//ascii maps, for debug
- { ':', QT_MAC_MAP_ENUM(Qt::Key_Colon) },
- { ';', QT_MAC_MAP_ENUM(Qt::Key_Semicolon) },
- { '<', QT_MAC_MAP_ENUM(Qt::Key_Less) },
- { '=', QT_MAC_MAP_ENUM(Qt::Key_Equal) },
- { '>', QT_MAC_MAP_ENUM(Qt::Key_Greater) },
- { '?', QT_MAC_MAP_ENUM(Qt::Key_Question) },
- { '@', QT_MAC_MAP_ENUM(Qt::Key_At) },
- { ' ', QT_MAC_MAP_ENUM(Qt::Key_Space) },
- { '!', QT_MAC_MAP_ENUM(Qt::Key_Exclam) },
- { '"', QT_MAC_MAP_ENUM(Qt::Key_QuoteDbl) },
- { '#', QT_MAC_MAP_ENUM(Qt::Key_NumberSign) },
- { '$', QT_MAC_MAP_ENUM(Qt::Key_Dollar) },
- { '%', QT_MAC_MAP_ENUM(Qt::Key_Percent) },
- { '&', QT_MAC_MAP_ENUM(Qt::Key_Ampersand) },
- { '\'', QT_MAC_MAP_ENUM(Qt::Key_Apostrophe) },
- { '(', QT_MAC_MAP_ENUM(Qt::Key_ParenLeft) },
- { ')', QT_MAC_MAP_ENUM(Qt::Key_ParenRight) },
- { '*', QT_MAC_MAP_ENUM(Qt::Key_Asterisk) },
- { '+', QT_MAC_MAP_ENUM(Qt::Key_Plus) },
- { ',', QT_MAC_MAP_ENUM(Qt::Key_Comma) },
- { '-', QT_MAC_MAP_ENUM(Qt::Key_Minus) },
- { '.', QT_MAC_MAP_ENUM(Qt::Key_Period) },
- { '/', QT_MAC_MAP_ENUM(Qt::Key_Slash) },
- { '[', QT_MAC_MAP_ENUM(Qt::Key_BracketLeft) },
- { ']', QT_MAC_MAP_ENUM(Qt::Key_BracketRight) },
- { '\\', QT_MAC_MAP_ENUM(Qt::Key_Backslash) },
- { '_', QT_MAC_MAP_ENUM(Qt::Key_Underscore) },
- { '`', QT_MAC_MAP_ENUM(Qt::Key_QuoteLeft) },
- { '{', QT_MAC_MAP_ENUM(Qt::Key_BraceLeft) },
- { '}', QT_MAC_MAP_ENUM(Qt::Key_BraceRight) },
- { '|', QT_MAC_MAP_ENUM(Qt::Key_Bar) },
- { '~', QT_MAC_MAP_ENUM(Qt::Key_AsciiTilde) },
- { '^', QT_MAC_MAP_ENUM(Qt::Key_AsciiCircum) },
- { 0, QT_MAC_MAP_ENUM(0) }
-};
-
-static qt_mac_enum_mapper qt_mac_keyvkey_symbols[] = { //real scan codes
- { 122, QT_MAC_MAP_ENUM(Qt::Key_F1) },
- { 120, QT_MAC_MAP_ENUM(Qt::Key_F2) },
- { 99, QT_MAC_MAP_ENUM(Qt::Key_F3) },
- { 118, QT_MAC_MAP_ENUM(Qt::Key_F4) },
- { 96, QT_MAC_MAP_ENUM(Qt::Key_F5) },
- { 97, QT_MAC_MAP_ENUM(Qt::Key_F6) },
- { 98, QT_MAC_MAP_ENUM(Qt::Key_F7) },
- { 100, QT_MAC_MAP_ENUM(Qt::Key_F8) },
- { 101, QT_MAC_MAP_ENUM(Qt::Key_F9) },
- { 109, QT_MAC_MAP_ENUM(Qt::Key_F10) },
- { 103, QT_MAC_MAP_ENUM(Qt::Key_F11) },
- { 111, QT_MAC_MAP_ENUM(Qt::Key_F12) },
- { 105, QT_MAC_MAP_ENUM(Qt::Key_F13) },
- { 107, QT_MAC_MAP_ENUM(Qt::Key_F14) },
- { 113, QT_MAC_MAP_ENUM(Qt::Key_F15) },
- { 106, QT_MAC_MAP_ENUM(Qt::Key_F16) },
- { 0, QT_MAC_MAP_ENUM(0) }
-};
-
-static qt_mac_enum_mapper qt_mac_private_unicode[] = {
- { 0xF700, QT_MAC_MAP_ENUM(Qt::Key_Up) }, //NSUpArrowFunctionKey
- { 0xF701, QT_MAC_MAP_ENUM(Qt::Key_Down) }, //NSDownArrowFunctionKey
- { 0xF702, QT_MAC_MAP_ENUM(Qt::Key_Left) }, //NSLeftArrowFunctionKey
- { 0xF703, QT_MAC_MAP_ENUM(Qt::Key_Right) }, //NSRightArrowFunctionKey
- { 0xF727, QT_MAC_MAP_ENUM(Qt::Key_Insert) }, //NSInsertFunctionKey
- { 0xF728, QT_MAC_MAP_ENUM(Qt::Key_Delete) }, //NSDeleteFunctionKey
- { 0xF729, QT_MAC_MAP_ENUM(Qt::Key_Home) }, //NSHomeFunctionKey
- { 0xF72B, QT_MAC_MAP_ENUM(Qt::Key_End) }, //NSEndFunctionKey
- { 0xF72C, QT_MAC_MAP_ENUM(Qt::Key_PageUp) }, //NSPageUpFunctionKey
- { 0xF72D, QT_MAC_MAP_ENUM(Qt::Key_PageDown) }, //NSPageDownFunctionKey
- { 0xF72F, QT_MAC_MAP_ENUM(Qt::Key_ScrollLock) }, //NSScrollLockFunctionKey
- { 0xF730, QT_MAC_MAP_ENUM(Qt::Key_Pause) }, //NSPauseFunctionKey
- { 0xF731, QT_MAC_MAP_ENUM(Qt::Key_SysReq) }, //NSSysReqFunctionKey
- { 0xF735, QT_MAC_MAP_ENUM(Qt::Key_Menu) }, //NSMenuFunctionKey
- { 0xF738, QT_MAC_MAP_ENUM(Qt::Key_Print) }, //NSPrintFunctionKey
- { 0xF73A, QT_MAC_MAP_ENUM(Qt::Key_Clear) }, //NSClearDisplayFunctionKey
- { 0xF73D, QT_MAC_MAP_ENUM(Qt::Key_Insert) }, //NSInsertCharFunctionKey
- { 0xF73E, QT_MAC_MAP_ENUM(Qt::Key_Delete) }, //NSDeleteCharFunctionKey
- { 0xF741, QT_MAC_MAP_ENUM(Qt::Key_Select) }, //NSSelectFunctionKey
- { 0xF742, QT_MAC_MAP_ENUM(Qt::Key_Execute) }, //NSExecuteFunctionKey
- { 0xF746, QT_MAC_MAP_ENUM(Qt::Key_Help) }, //NSHelpFunctionKey
- { 0xF747, QT_MAC_MAP_ENUM(Qt::Key_Mode_switch) }, //NSModeSwitchFunctionKey
- { 0, QT_MAC_MAP_ENUM(0) }
-};
-
-static int qt_mac_get_key(int modif, const QChar &key, int virtualKey)
-{
-#ifdef DEBUG_KEY_BINDINGS
- qDebug("**Mapping key: %d (0x%04x) - %d (0x%04x)", key.unicode(), key.unicode(), virtualKey, virtualKey);
-#endif
-
- if (key == kClearCharCode && virtualKey == 0x47)
- return Qt::Key_Clear;
-
- if (key.isDigit()) {
-#ifdef DEBUG_KEY_BINDINGS
- qDebug("%d: got key: %d", __LINE__, key.digitValue());
-#endif
- return key.digitValue() + Qt::Key_0;
- }
-
- if (key.isLetter()) {
-#ifdef DEBUG_KEY_BINDINGS
- qDebug("%d: got key: %d", __LINE__, (key.toUpper().unicode() - 'A'));
-#endif
- return (key.toUpper().unicode() - 'A') + Qt::Key_A;
- }
- if (key.isSymbol()) {
-#ifdef DEBUG_KEY_BINDINGS
- qDebug("%d: got key: %d", __LINE__, (key.unicode()));
-#endif
- return key.unicode();
- }
-
- for (int i = 0; qt_mac_keyboard_symbols[i].qt_code; i++) {
- if (qt_mac_keyboard_symbols[i].mac_code == key) {
- /* To work like Qt for X11 we issue Backtab when Shift + Tab are pressed */
- if (qt_mac_keyboard_symbols[i].qt_code == Qt::Key_Tab && (modif & Qt::ShiftModifier)) {
-#ifdef DEBUG_KEY_BINDINGS
- qDebug("%d: got key: Qt::Key_Backtab", __LINE__);
-#endif
- return Qt::Key_Backtab;
- }
-
-#ifdef DEBUG_KEY_BINDINGS
- qDebug("%d: got key: %s", __LINE__, qt_mac_keyboard_symbols[i].desc);
-#endif
- return qt_mac_keyboard_symbols[i].qt_code;
- }
- }
-
- //last ditch try to match the scan code
- for (int i = 0; qt_mac_keyvkey_symbols[i].qt_code; i++) {
- if (qt_mac_keyvkey_symbols[i].mac_code == virtualKey) {
-#ifdef DEBUG_KEY_BINDINGS
- qDebug("%d: got key: %s", __LINE__, qt_mac_keyvkey_symbols[i].desc);
-#endif
- return qt_mac_keyvkey_symbols[i].qt_code;
- }
- }
-
- // check if they belong to key codes in private unicode range
- if (key >= 0xf700 && key <= 0xf747) {
- if (key >= 0xf704 && key <= 0xf726) {
- return Qt::Key_F1 + (key.unicode() - 0xf704) ;
- }
- for (int i = 0; qt_mac_private_unicode[i].qt_code; i++) {
- if (qt_mac_private_unicode[i].mac_code == key) {
- return qt_mac_private_unicode[i].qt_code;
- }
- }
-
- }
-
- //oh well
-#ifdef DEBUG_KEY_BINDINGS
- qDebug("Unknown case.. %s:%d %d[%d] %d", __FILE__, __LINE__, key.unicode(), key.toLatin1(), virtualKey);
-#endif
- return Qt::Key_unknown;
-}
-
-static Boolean qt_KeyEventComparatorProc(EventRef inEvent, void *data)
-{
- UInt32 ekind = GetEventKind(inEvent),
- eclass = GetEventClass(inEvent);
- return (eclass == kEventClassKeyboard && (void *)ekind == data);
-}
-
-static bool translateKeyEventInternal(EventHandlerCallRef er, EventRef keyEvent, int *qtKey,
- QChar *outChar, Qt::KeyboardModifiers *outModifiers, bool *outHandled)
-{
-#if !defined(QT_MAC_USE_COCOA) || defined(Q_OS_MAC64)
- Q_UNUSED(er);
- Q_UNUSED(outHandled);
-#endif
- const UInt32 ekind = GetEventKind(keyEvent);
- {
- UInt32 mac_modifiers = 0;
- GetEventParameter(keyEvent, kEventParamKeyModifiers, typeUInt32, 0,
- sizeof(mac_modifiers), 0, &mac_modifiers);
-#ifdef DEBUG_KEY_BINDINGS_MODIFIERS
- qDebug("************ Mapping modifiers and key ***********");
-#endif
- *outModifiers = qt_mac_get_modifiers(mac_modifiers);
-#ifdef DEBUG_KEY_BINDINGS_MODIFIERS
- qDebug("------------ Mapping modifiers and key -----------");
-#endif
- }
-
- //get keycode
- UInt32 keyCode = 0;
- GetEventParameter(keyEvent, kEventParamKeyCode, typeUInt32, 0, sizeof(keyCode), 0, &keyCode);
-
- //get mac mapping
- static UInt32 tmp_unused_state = 0L;
- const UCKeyboardLayout *uchrData = 0;
-#if defined(Q_OS_MAC32)
- KeyboardLayoutRef keyLayoutRef = 0;
- KLGetCurrentKeyboardLayout(&keyLayoutRef);
- OSStatus err;
- if (keyLayoutRef != 0) {
- err = KLGetKeyboardLayoutProperty(keyLayoutRef, kKLuchrData,
- (reinterpret_cast<const void **>(&uchrData)));
- if (err != noErr) {
- qWarning("Qt::internal::unable to get keyboardlayout %ld %s:%d",
- long(err), __FILE__, __LINE__);
- }
- }
-#else
- QCFType<TISInputSourceRef> inputSource = TISCopyCurrentKeyboardInputSource();
- Q_ASSERT(inputSource != 0);
- CFDataRef data = static_cast<CFDataRef>(TISGetInputSourceProperty(inputSource,
- kTISPropertyUnicodeKeyLayoutData));
- uchrData = data ? reinterpret_cast<const UCKeyboardLayout *>(CFDataGetBytePtr(data)) : 0;
-#endif
- *qtKey = Qt::Key_unknown;
- if (uchrData) {
- // The easy stuff; use the unicode stuff!
- UniChar string[4];
- UniCharCount actualLength;
- UInt32 currentModifiers = GetCurrentEventKeyModifiers();
- UInt32 currentModifiersWOAltOrControl = currentModifiers & ~(controlKey | optionKey);
- int keyAction;
- switch (ekind) {
- default:
- case kEventRawKeyDown:
- keyAction = kUCKeyActionDown;
- break;
- case kEventRawKeyUp:
- keyAction = kUCKeyActionUp;
- break;
- case kEventRawKeyRepeat:
- keyAction = kUCKeyActionAutoKey;
- break;
- }
- OSStatus err = UCKeyTranslate(uchrData, keyCode, keyAction,
- ((currentModifiersWOAltOrControl >> 8) & 0xff), LMGetKbdType(),
- kUCKeyTranslateNoDeadKeysMask, &tmp_unused_state, 4, &actualLength,
- string);
- if (err == noErr) {
- *outChar = QChar(string[0]);
- *qtKey = qt_mac_get_key(*outModifiers, *outChar, keyCode);
- if (currentModifiersWOAltOrControl != currentModifiers) {
- // Now get the real char.
- err = UCKeyTranslate(uchrData, keyCode, keyAction,
- ((currentModifiers >> 8) & 0xff), LMGetKbdType(),
- kUCKeyTranslateNoDeadKeysMask, &tmp_unused_state, 4, &actualLength,
- string);
- if (err == noErr)
- *outChar = QChar(string[0]);
- }
- } else {
- qWarning("Qt::internal::UCKeyTranslate is returnining %ld %s:%d",
- long(err), __FILE__, __LINE__);
- }
- }
-#ifdef Q_OS_MAC32
- else {
- // The road less travelled; use KeyTranslate
- const void *keyboard_layout;
- KeyboardLayoutRef keyLayoutRef = 0;
- KLGetCurrentKeyboardLayout(&keyLayoutRef);
- err = KLGetKeyboardLayoutProperty(keyLayoutRef, kKLKCHRData,
- reinterpret_cast<const void **>(&keyboard_layout));
-
- int translatedChar = KeyTranslate(keyboard_layout, (GetCurrentEventKeyModifiers() &
- (kEventKeyModifierNumLockMask|shiftKey|cmdKey|
- rightShiftKey|alphaLock)) | keyCode,
- &tmp_unused_state);
- if (!translatedChar) {
-#ifdef QT_MAC_USE_COCOA
- if (outHandled) {
- qt_mac_eat_unicode_key = false;
- if (er)
- CallNextEventHandler(er, keyEvent);
- *outHandled = qt_mac_eat_unicode_key;
- }
-#endif
- return false;
- }
-
- //map it into qt keys
- *qtKey = qt_mac_get_key(*outModifiers, QChar(translatedChar), keyCode);
- if (*outModifiers & (Qt::AltModifier | Qt::ControlModifier)) {
- if (translatedChar & (1 << 7)) //high ascii
- translatedChar = 0;
- } else { //now get the real ascii value
- UInt32 tmp_mod = 0L;
- static UInt32 tmp_state = 0L;
- if (*outModifiers & Qt::ShiftModifier)
- tmp_mod |= shiftKey;
- if (*outModifiers & Qt::MetaModifier)
- tmp_mod |= controlKey;
- if (*outModifiers & Qt::ControlModifier)
- tmp_mod |= cmdKey;
- if (GetCurrentEventKeyModifiers() & alphaLock) //no Qt mapper
- tmp_mod |= alphaLock;
- if (*outModifiers & Qt::AltModifier)
- tmp_mod |= optionKey;
- if (*outModifiers & Qt::KeypadModifier)
- tmp_mod |= kEventKeyModifierNumLockMask;
- translatedChar = KeyTranslate(keyboard_layout, tmp_mod | keyCode, &tmp_state);
- }
- {
- ByteCount unilen = 0;
- if (GetEventParameter(keyEvent, kEventParamKeyUnicodes, typeUnicodeText, 0, 0, &unilen, 0)
- == noErr && unilen == 2) {
- GetEventParameter(keyEvent, kEventParamKeyUnicodes, typeUnicodeText, 0, unilen, 0, outChar);
- } else if (translatedChar) {
- static QTextCodec *c = 0;
- if (!c)
- c = QTextCodec::codecForName("Apple Roman");
- char tmpChar = (char)translatedChar; // **sigh**
- *outChar = c->toUnicode(&tmpChar, 1).at(0);
- } else {
- *qtKey = qt_mac_get_key(*outModifiers, QChar(translatedChar), keyCode);
- }
- }
- }
-#endif
- if (*qtKey == Qt::Key_unknown)
- *qtKey = qt_mac_get_key(*outModifiers, *outChar, keyCode);
- return true;
-}
-
-QKeyMapperPrivate::QKeyMapperPrivate()
-{
- memset(keyLayout, 0, sizeof(keyLayout));
- keyboard_layout_format.unicode = 0;
-#ifdef Q_OS_MAC32
- keyboard_mode = NullMode;
-#else
- currentInputSource = 0;
-#endif
-}
-
-QKeyMapperPrivate::~QKeyMapperPrivate()
-{
- deleteLayouts();
-}
-
-bool
-QKeyMapperPrivate::updateKeyboard()
-{
- const UCKeyboardLayout *uchrData = 0;
-#ifdef Q_OS_MAC32
- KeyboardLayoutRef keyLayoutRef = 0;
- KLGetCurrentKeyboardLayout(&keyLayoutRef);
-
- if (keyboard_mode != NullMode && currentKeyboardLayout == keyLayoutRef)
- return false;
-
- OSStatus err;
- if (keyLayoutRef != 0) {
- err = KLGetKeyboardLayoutProperty(keyLayoutRef, kKLuchrData,
- const_cast<const void **>(reinterpret_cast<const void **>(&uchrData)));
- if (err != noErr) {
- qWarning("Qt::internal::unable to get unicode keyboardlayout %ld %s:%d",
- long(err), __FILE__, __LINE__);
- }
- }
-#else
- QCFType<TISInputSourceRef> source = TISCopyCurrentKeyboardInputSource();
- if (keyboard_mode != NullMode && source == currentInputSource) {
- return false;
- }
- Q_ASSERT(source != 0);
- CFDataRef data = static_cast<CFDataRef>(TISGetInputSourceProperty(source,
- kTISPropertyUnicodeKeyLayoutData));
- uchrData = data ? reinterpret_cast<const UCKeyboardLayout *>(CFDataGetBytePtr(data)) : 0;
-#endif
-
- keyboard_kind = LMGetKbdType();
- if (uchrData) {
- keyboard_layout_format.unicode = uchrData;
- keyboard_mode = UnicodeMode;
- }
-#ifdef Q_OS_MAC32
- else {
- void *happy;
- err = KLGetKeyboardLayoutProperty(keyLayoutRef, kKLKCHRData,
- const_cast<const void **>(reinterpret_cast<void **>(&happy)));
- if (err != noErr) {
- qFatal("Qt::internal::unable to get non-unicode layout, cannot procede %ld %s:%d",
- long(err), __FILE__, __LINE__);
- }
- keyboard_layout_format.other = happy;
- keyboard_mode = OtherMode;
- }
-
- currentKeyboardLayout = keyLayoutRef;
-#else
- currentInputSource = source;
-#endif
- keyboard_dead = 0;
- CFStringRef iso639Code;
-#ifdef Q_OS_MAC32
-# ifndef kKLLanguageCode
-# define kKLLanguageCode 9
-# endif
- KLGetKeyboardLayoutProperty(currentKeyboardLayout, kKLLanguageCode,
- reinterpret_cast<const void **>(&iso639Code));
-#else
- CFArrayRef array = static_cast<CFArrayRef>(TISGetInputSourceProperty(currentInputSource, kTISPropertyInputSourceLanguages));
- iso639Code = static_cast<CFStringRef>(CFArrayGetValueAtIndex(array, 0)); // Actually a RFC3066bis, but it's close enough
-#endif
- if (iso639Code) {
- keyboardInputLocale = QLocale(QCFString::toQString(iso639Code));
- keyboardInputDirection = keyboardInputLocale.textDirection();
- } else {
- keyboardInputLocale = QLocale::c();
- keyboardInputDirection = Qt::LeftToRight;
- }
- return true;
-}
-
-void
-QKeyMapperPrivate::deleteLayouts()
-{
- keyboard_mode = NullMode;
- for (int i = 0; i < 255; ++i) {
- if (keyLayout[i]) {
- delete keyLayout[i];
- keyLayout[i] = 0;
- }
- }
-}
-
-void
-QKeyMapperPrivate::clearMappings()
-{
- deleteLayouts();
- updateKeyboard();
-}
-
-QList<int>
-QKeyMapperPrivate::possibleKeys(QKeyEvent *e)
-{
- QList<int> ret;
-
- KeyboardLayoutItem *kbItem = keyLayout[e->nativeVirtualKey()];
- if (!kbItem) // Key is not in any keyboard layout (e.g. eisu-key on Japanese keyboard)
- return ret;
-
- int baseKey = kbItem->qtKey[0];
- Qt::KeyboardModifiers keyMods = e->modifiers();
- ret << int(baseKey + keyMods); // The base key is _always_ valid, of course
-
- for (int i = 1; i < 8; ++i) {
- Qt::KeyboardModifiers neededMods = ModsTbl[i];
- int key = kbItem->qtKey[i];
- if (key && key != baseKey && ((keyMods & neededMods) == neededMods))
- ret << int(key + (keyMods & ~neededMods));
- }
-
- return ret;
-}
-
-bool QKeyMapperPrivate::translateKeyEvent(QWidget *widget, EventHandlerCallRef er, EventRef event,
- void *info, bool grab)
-{
- Q_ASSERT(GetEventClass(event) == kEventClassKeyboard);
- bool handled_event=true;
- UInt32 ekind = GetEventKind(event);
-
- // unfortunately modifiers changed event looks quite different, so I have a separate
- // code path
- if (ekind == kEventRawKeyModifiersChanged) {
- //figure out changed modifiers, wish Apple would just send a delta
- UInt32 modifiers = 0;
- GetEventParameter(event, kEventParamKeyModifiers, typeUInt32, 0,
- sizeof(modifiers), 0, &modifiers);
- qt_mac_send_modifiers_changed(modifiers, widget);
- return true;
- }
-
- QInputContext *currentContext = qApp->inputContext();
- if (currentContext && currentContext->isComposing()) {
- if (ekind == kEventRawKeyDown) {
- QMacInputContext *context = qobject_cast<QMacInputContext*>(currentContext);
- if (context)
- context->setLastKeydownEvent(event);
- }
- return false;
- }
- // Once we process the key down , we don't need to send the saved event again from
- // kEventTextInputUnicodeForKeyEvent, so clear it.
- if (currentContext && ekind == kEventRawKeyDown) {
- QMacInputContext *context = qobject_cast<QMacInputContext*>(currentContext);
- if (context)
- context->setLastKeydownEvent(0);
- }
-
- //get modifiers
- Qt::KeyboardModifiers modifiers;
- int qtKey;
- QChar ourChar;
- if (translateKeyEventInternal(er, event, &qtKey, &ourChar, &modifiers,
- &handled_event) == false)
- return handled_event;
- QString text(ourChar);
- /* This is actually wrong - but unfortunately it is the best that can be
- done for now because of the Control/Meta mapping problems */
- if (modifiers & (Qt::ControlModifier | Qt::MetaModifier)
- && !qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)) {
- text = QString();
- }
-
-
- if (widget) {
-#ifndef QT_MAC_USE_COCOA
- Q_UNUSED(info);
- // Try not to call "other" event handlers if we have a popup,
- // However, if the key has text
- // then we should pass it along because otherwise then people
- // can use input method stuff.
- if (!qApp->activePopupWidget()
- || (qApp->activePopupWidget() && !text.isEmpty())) {
- //Find out if someone else wants the event, namely
- //is it of use to text services? If so we won't bother
- //with a QKeyEvent.
- qt_mac_eat_unicode_key = false;
- if (er)
- CallNextEventHandler(er, event);
- extern bool qt_mac_menubar_is_open();
- if (qt_mac_eat_unicode_key || qt_mac_menubar_is_open()) {
- return true;
- }
- }
-#endif
- // Try to compress key events.
- if (!text.isEmpty() && widget->testAttribute(Qt::WA_KeyCompression)) {
- EventTime lastTime = GetEventTime(event);
- for (;;) {
- EventRef releaseEvent = FindSpecificEventInQueue(GetMainEventQueue(),
- qt_KeyEventComparatorProc,
- (void*)kEventRawKeyUp);
- if (!releaseEvent)
- break;
- const EventTime releaseTime = GetEventTime(releaseEvent);
- if (releaseTime < lastTime)
- break;
- lastTime = releaseTime;
-
- EventRef pressEvent = FindSpecificEventInQueue(GetMainEventQueue(),
- qt_KeyEventComparatorProc,
- (void*)kEventRawKeyDown);
- if (!pressEvent)
- break;
- const EventTime pressTime = GetEventTime(pressEvent);
- if (pressTime < lastTime)
- break;
- lastTime = pressTime;
-
- Qt::KeyboardModifiers compressMod;
- int compressQtKey = 0;
- QChar compressChar;
- if (translateKeyEventInternal(er, pressEvent,
- &compressQtKey, &compressChar, &compressMod, 0)
- == false) {
- break;
- }
- // Copied from qapplication_x11.cpp (change both).
-
- bool stopCompression =
- // 1) misc keys
- (compressQtKey >= Qt::Key_Escape && compressQtKey <= Qt::Key_SysReq)
- // 2) cursor movement
- || (compressQtKey >= Qt::Key_Home && compressQtKey <= Qt::Key_PageDown)
- // 3) extra keys
- || (compressQtKey >= Qt::Key_Super_L && compressQtKey <= Qt::Key_Direction_R)
- // 4) something that a) doesn't translate to text or b) translates
- // to newline text
- || (compressQtKey == 0)
- || (compressChar == QLatin1Char('\n'))
- || (compressQtKey == Qt::Key_unknown);
-
- if (compressMod == modifiers && !compressChar.isNull() && !stopCompression) {
-#ifdef DEBUG_KEY_BINDINGS
- qDebug("compressing away %c", compressChar.toLatin1());
-#endif
- text += compressChar;
- // Clean up
- RemoveEventFromQueue(GetMainEventQueue(), releaseEvent);
- RemoveEventFromQueue(GetMainEventQueue(), pressEvent);
- } else {
-#ifdef DEBUG_KEY_BINDINGS
- qDebug("stoping compression..");
-#endif
- break;
- }
- }
- }
-
- // There is no way to get the scan code from carbon. But we cannot use the value 0, since
- // it indicates that the event originates from somewhere else than the keyboard
- UInt32 macScanCode = 1;
- UInt32 macVirtualKey = 0;
- GetEventParameter(event, kEventParamKeyCode, typeUInt32, 0, sizeof(macVirtualKey), 0, &macVirtualKey);
- UInt32 macModifiers = 0;
- GetEventParameter(event, kEventParamKeyModifiers, typeUInt32, 0,
- sizeof(macModifiers), 0, &macModifiers);
-#ifdef QT_MAC_USE_COCOA
- // The unicode characters in the range 0xF700-0xF747 are reserved
- // by Mac OS X for transient use as keyboard function keys. We
- // wont send 'text' for such key events. This is done to match
- // behavior on other platforms.
- unsigned int *unicodeKey = (unsigned int*)info;
- if (*unicodeKey >= 0xf700 && *unicodeKey <= 0xf747)
- text = QString();
- bool isAccepted;
-#endif
- handled_event = QKeyMapper::sendKeyEvent(widget, grab,
- (ekind == kEventRawKeyUp) ? QEvent::KeyRelease : QEvent::KeyPress,
- qtKey, modifiers, text, ekind == kEventRawKeyRepeat, 0,
- macScanCode, macVirtualKey, macModifiers
-#ifdef QT_MAC_USE_COCOA
- ,&isAccepted
-#endif
- );
-#ifdef QT_MAC_USE_COCOA
- *unicodeKey = (unsigned int)isAccepted;
-#endif
- }
- return handled_event;
-}
-
-void
-QKeyMapperPrivate::updateKeyMap(EventHandlerCallRef, EventRef event, void *
-#if defined(QT_MAC_USE_COCOA)
- unicodeKey // unicode character from NSEvent (modifiers applied)
-#endif
- )
-{
- UInt32 macVirtualKey = 0;
- GetEventParameter(event, kEventParamKeyCode, typeUInt32, 0, sizeof(macVirtualKey), 0, &macVirtualKey);
- if (updateKeyboard())
- QKeyMapper::changeKeyboard();
- else if (keyLayout[macVirtualKey])
- return;
-
- UniCharCount buffer_size = 10;
- UniChar buffer[buffer_size];
- keyLayout[macVirtualKey] = new KeyboardLayoutItem;
- for (int i = 0; i < 16; ++i) {
- UniCharCount out_buffer_size = 0;
- keyLayout[macVirtualKey]->qtKey[i] = 0;
-#ifdef Q_WS_MAC32
- if (keyboard_mode == UnicodeMode) {
-#endif
- const UInt32 keyModifier = ((qt_mac_get_mac_modifiers(ModsTbl[i]) >> 8) & 0xFF);
- OSStatus err = UCKeyTranslate(keyboard_layout_format.unicode, macVirtualKey, kUCKeyActionDown, keyModifier,
- keyboard_kind, 0, &keyboard_dead, buffer_size, &out_buffer_size, buffer);
- if (err == noErr && out_buffer_size) {
- const QChar unicode(buffer[0]);
- int qtkey = qt_mac_get_key(keyModifier, unicode, macVirtualKey);
- if (qtkey == Qt::Key_unknown)
- qtkey = unicode.unicode();
- keyLayout[macVirtualKey]->qtKey[i] = qtkey;
- }
-#ifndef Q_WS_MAC32
- else {
- const QChar unicode(*((UniChar *)unicodeKey));
- int qtkey = qt_mac_get_key(keyModifier, unicode, macVirtualKey);
- if (qtkey == Qt::Key_unknown)
- qtkey = unicode.unicode();
- keyLayout[macVirtualKey]->qtKey[i] = qtkey;
- }
-#endif
-#ifdef Q_WS_MAC32
- } else {
- const UInt32 keyModifier = (qt_mac_get_mac_modifiers(ModsTbl[i]));
-
- uchar translatedChar = KeyTranslate(keyboard_layout_format.other, keyModifier | macVirtualKey, &keyboard_dead);
- if (translatedChar) {
- static QTextCodec *c = 0;
- if (!c)
- c = QTextCodec::codecForName("Apple Roman");
- const QChar unicode(c->toUnicode((const char *)&translatedChar, 1).at(0));
- int qtkey = qt_mac_get_key(keyModifier, unicode, macVirtualKey);
- if (qtkey == Qt::Key_unknown)
- qtkey = unicode.unicode();
- keyLayout[macVirtualKey]->qtKey[i] = qtkey;
- }
- }
-#endif
- }
-#ifdef DEBUG_KEY_MAPS
- qDebug("updateKeyMap for virtual key = 0x%02x!", (uint)macVirtualKey);
- for (int i = 0; i < 16; ++i) {
- qDebug(" [%d] (%d,0x%02x,'%c')", i,
- keyLayout[macVirtualKey]->qtKey[i],
- keyLayout[macVirtualKey]->qtKey[i],
- keyLayout[macVirtualKey]->qtKey[i]);
- }
-#endif
-}
-
-bool
-QKeyMapper::sendKeyEvent(QWidget *widget, bool grab,
- QEvent::Type type, int code, Qt::KeyboardModifiers modifiers,
- const QString &text, bool autorepeat, int count,
- quint32 nativeScanCode, quint32 nativeVirtualKey,
- quint32 nativeModifiers, bool *isAccepted)
-{
- Q_UNUSED(count);
- if (widget && widget->isEnabled()) {
- bool key_event = true;
-#if defined(QT3_SUPPORT) && !defined(QT_NO_SHORTCUT)
- if (type == QEvent::KeyPress && !grab
- && QApplicationPrivate::instance()->use_compat()) {
- QKeyEventEx accel_ev(type, code, modifiers,
- text, autorepeat, qMax(1, int(text.length())),
- nativeScanCode, nativeVirtualKey, nativeModifiers);
- if (QApplicationPrivate::instance()->qt_tryAccelEvent(widget, &accel_ev)) {
-#if defined(DEBUG_KEY_BINDINGS) || defined(DEBUG_KEY_BINDINGS_MODIFIERS)
- qDebug("KeyEvent: %s::%s consumed Accel: %s",
- widget ? widget->metaObject()->className() : "none",
- widget ? widget->objectName().toLatin1().constData() : "",
- text.toLatin1().constData());
-#endif
- key_event = false;
- } else {
- if (accel_ev.isAccepted()) {
-#if defined(DEBUG_KEY_BINDINGS) || defined(DEBUG_KEY_BINDINGS_MODIFIERS)
- qDebug("KeyEvent: %s::%s overrode Accel: %s",
- widget ? widget->metaObject()->className() : "none",
- widget ? widget->objectName().toLatin1().constData() : "",
- text.toLatin1().constData());
-#endif
- }
- }
- }
-#else
-Q_UNUSED(grab);
-#endif // QT3_SUPPORT && !QT_NO_SHORTCUT
- if (key_event) {
-#if defined(DEBUG_KEY_BINDINGS) || defined(DEBUG_KEY_BINDINGS_MODIFIERS)
- qDebug("KeyEvent: Sending %s to %s::%s: %s 0x%08x%s",
- type == QEvent::KeyRelease ? "KeyRelease" : "KeyPress",
- widget ? widget->metaObject()->className() : "none",
- widget ? widget->objectName().toLatin1().constData() : "",
- text.toLatin1().constData(), int(modifiers),
- autorepeat ? " Repeat" : "");
-#endif
- QKeyEventEx ke(type, code, modifiers, text, autorepeat, qMax(1, text.length()),
- nativeScanCode, nativeVirtualKey, nativeModifiers);
- bool retMe = qt_sendSpontaneousEvent(widget,&ke);
- if (isAccepted)
- *isAccepted = ke.isAccepted();
- return retMe;
- }
- }
- return false;
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/kernel/qkeymapper_p.h b/src/gui/kernel/qkeymapper_p.h
index 2607c2a1a9..35f2a63345 100644
--- a/src/gui/kernel/qkeymapper_p.h
+++ b/src/gui/kernel/qkeymapper_p.h
@@ -67,7 +67,7 @@
QT_BEGIN_NAMESPACE
class QKeyMapperPrivate;
-class QKeyMapper : public QObject
+class Q_GUI_EXPORT QKeyMapper : public QObject
{
Q_OBJECT
public:
@@ -76,11 +76,13 @@ public:
static QKeyMapper *instance();
static void changeKeyboard();
+#ifndef Q_WS_QPA
static bool sendKeyEvent(QWidget *widget, bool grab,
QEvent::Type type, int code, Qt::KeyboardModifiers modifiers,
const QString &text, bool autorepeat, int count,
quint32 nativeScanCode, quint32 nativeVirtualKey, quint32 nativeModifiers,
bool *unusedExceptForCocoa = 0);
+#endif
static QList<int> possibleKeys(QKeyEvent *e);
private:
diff --git a/src/gui/kernel/qkeymapper_qws.cpp b/src/gui/kernel/qkeymapper_qpa.cpp
index 13c6d6c28b..13c6d6c28b 100644
--- a/src/gui/kernel/qkeymapper_qws.cpp
+++ b/src/gui/kernel/qkeymapper_qpa.cpp
diff --git a/src/gui/kernel/qkeymapper_win.cpp b/src/gui/kernel/qkeymapper_win.cpp
deleted file mode 100644
index b981066434..0000000000
--- a/src/gui/kernel/qkeymapper_win.cpp
+++ /dev/null
@@ -1,1207 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qkeymapper_p.h"
-
-#include <qt_windows.h>
-#include <qdebug.h>
-#include <private/qevent_p.h>
-#include <private/qlocale_p.h>
-#include <private/qapplication_p.h>
-#include <qwidget.h>
-#include <qapplication.h>
-#include <ctype.h>
-
-QT_BEGIN_NAMESPACE
-
-// Uncommend, to show debugging information for the keymapper
-//#define DEBUG_KEYMAPPER
-
-// Implemented elsewhere
-extern "C" LRESULT QT_WIN_CALLBACK QtWndProc(HWND, UINT, WPARAM, LPARAM);
-
-extern Q_CORE_EXPORT QLocale qt_localeFromLCID(LCID id);
-#ifndef LANG_PASHTO
-#define LANG_PASHTO 0x63
-#endif
-#ifndef LANG_SYRIAC
-#define LANG_SYRIAC 0x5a
-#endif
-#ifndef LANG_DIVEHI
-#define LANG_DIVEHI 0x65
-#endif
-#ifndef VK_OEM_PLUS
-#define VK_OEM_PLUS 0xBB
-#endif
-#ifndef VK_OEM_3
-#define VK_OEM_3 0xC0
-#endif
-
-#if defined(Q_OS_WINCE)
-bool GetKeyboardState(unsigned char* kbuffer)
-{
- for (int i=0; i< 256; ++i)
- kbuffer[i] = GetAsyncKeyState(i);
- return true;
-}
-#endif
-// Key recorder ------------------------------------------------------------------------[ start ] --
-struct KeyRecord {
- KeyRecord(int c, int a, int s, const QString &t) : code(c), ascii(a), state(s), text(t) {}
- KeyRecord() {}
-
- int code;
- int ascii;
- int state;
- QString text;
-};
-
-static const int QT_MAX_KEY_RECORDINGS = 64; // User has LOTS of fingers...
-struct KeyRecorder
-{
- KeyRecorder() : nrecs(0) {}
-
- inline KeyRecord *findKey(int code, bool remove);
- inline void storeKey(int code, int ascii, int state, const QString& text);
- inline void clearKeys();
-
- int nrecs;
- KeyRecord deleted_record; // A copy of last entry removed from records[]
- KeyRecord records[QT_MAX_KEY_RECORDINGS];
-};
-static KeyRecorder key_recorder;
-
-KeyRecord *KeyRecorder::findKey(int code, bool remove)
-{
- KeyRecord *result = 0;
- for (int i = 0; i < nrecs; ++i) {
- if (records[i].code == code) {
- if (remove) {
- deleted_record = records[i];
- // Move rest down, and decrease count
- while (i + 1 < nrecs) {
- records[i] = records[i + 1];
- ++i;
- }
- --nrecs;
- result = &deleted_record;
- } else {
- result = &records[i];
- }
- break;
- }
- }
- return result;
-}
-
-void KeyRecorder::storeKey(int code, int ascii, int state, const QString& text)
-{
- Q_ASSERT_X(nrecs != QT_MAX_KEY_RECORDINGS,
- "Internal KeyRecorder",
- "Keyboard recorder buffer overflow, consider increasing QT_MAX_KEY_RECORDINGS");
-
- if (nrecs == QT_MAX_KEY_RECORDINGS) {
- qWarning("Qt: Internal keyboard buffer overflow");
- return;
- }
- records[nrecs++] = KeyRecord(code,ascii,state,text);
-}
-
-void KeyRecorder::clearKeys()
-{
- nrecs = 0;
-}
-// Key recorder --------------------------------------------------------------------------[ end ] --
-
-
-// Key translation ---------------------------------------------------------------------[ start ] --
-// Meaning of values:
-// 0 = Character output key, needs keyboard driver mapping
-// Key_unknown = Unknown Virtual Key, no translation possible, ignore
-static const uint KeyTbl[] = { // Keyboard mapping table
- // Dec | Hex | Windows Virtual key
- Qt::Key_unknown, // 0 0x00
- Qt::Key_unknown, // 1 0x01 VK_LBUTTON | Left mouse button
- Qt::Key_unknown, // 2 0x02 VK_RBUTTON | Right mouse button
- Qt::Key_Cancel, // 3 0x03 VK_CANCEL | Control-Break processing
- Qt::Key_unknown, // 4 0x04 VK_MBUTTON | Middle mouse button
- Qt::Key_unknown, // 5 0x05 VK_XBUTTON1 | X1 mouse button
- Qt::Key_unknown, // 6 0x06 VK_XBUTTON2 | X2 mouse button
- Qt::Key_unknown, // 7 0x07 -- unassigned --
- Qt::Key_Backspace, // 8 0x08 VK_BACK | BackSpace key
- Qt::Key_Tab, // 9 0x09 VK_TAB | Tab key
- Qt::Key_unknown, // 10 0x0A -- reserved --
- Qt::Key_unknown, // 11 0x0B -- reserved --
- Qt::Key_Clear, // 12 0x0C VK_CLEAR | Clear key
- Qt::Key_Return, // 13 0x0D VK_RETURN | Enter key
- Qt::Key_unknown, // 14 0x0E -- unassigned --
- Qt::Key_unknown, // 15 0x0F -- unassigned --
- Qt::Key_Shift, // 16 0x10 VK_SHIFT | Shift key
- Qt::Key_Control, // 17 0x11 VK_CONTROL | Ctrl key
- Qt::Key_Alt, // 18 0x12 VK_MENU | Alt key
- Qt::Key_Pause, // 19 0x13 VK_PAUSE | Pause key
- Qt::Key_CapsLock, // 20 0x14 VK_CAPITAL | Caps-Lock
- Qt::Key_unknown, // 21 0x15 VK_KANA / VK_HANGUL | IME Kana or Hangul mode
- Qt::Key_unknown, // 22 0x16 -- unassigned --
- Qt::Key_unknown, // 23 0x17 VK_JUNJA | IME Junja mode
- Qt::Key_unknown, // 24 0x18 VK_FINAL | IME final mode
- Qt::Key_unknown, // 25 0x19 VK_HANJA / VK_KANJI | IME Hanja or Kanji mode
- Qt::Key_unknown, // 26 0x1A -- unassigned --
- Qt::Key_Escape, // 27 0x1B VK_ESCAPE | Esc key
- Qt::Key_unknown, // 28 0x1C VK_CONVERT | IME convert
- Qt::Key_unknown, // 29 0x1D VK_NONCONVERT | IME non-convert
- Qt::Key_unknown, // 30 0x1E VK_ACCEPT | IME accept
- Qt::Key_Mode_switch,// 31 0x1F VK_MODECHANGE | IME mode change request
- Qt::Key_Space, // 32 0x20 VK_SPACE | Spacebar
- Qt::Key_PageUp, // 33 0x21 VK_PRIOR | Page Up key
- Qt::Key_PageDown, // 34 0x22 VK_NEXT | Page Down key
- Qt::Key_End, // 35 0x23 VK_END | End key
- Qt::Key_Home, // 36 0x24 VK_HOME | Home key
- Qt::Key_Left, // 37 0x25 VK_LEFT | Left arrow key
- Qt::Key_Up, // 38 0x26 VK_UP | Up arrow key
- Qt::Key_Right, // 39 0x27 VK_RIGHT | Right arrow key
- Qt::Key_Down, // 40 0x28 VK_DOWN | Down arrow key
- Qt::Key_Select, // 41 0x29 VK_SELECT | Select key
- Qt::Key_Printer, // 42 0x2A VK_PRINT | Print key
- Qt::Key_Execute, // 43 0x2B VK_EXECUTE | Execute key
- Qt::Key_Print, // 44 0x2C VK_SNAPSHOT | Print Screen key
- Qt::Key_Insert, // 45 0x2D VK_INSERT | Ins key
- Qt::Key_Delete, // 46 0x2E VK_DELETE | Del key
- Qt::Key_Help, // 47 0x2F VK_HELP | Help key
- 0, // 48 0x30 (VK_0) | 0 key
- 0, // 49 0x31 (VK_1) | 1 key
- 0, // 50 0x32 (VK_2) | 2 key
- 0, // 51 0x33 (VK_3) | 3 key
- 0, // 52 0x34 (VK_4) | 4 key
- 0, // 53 0x35 (VK_5) | 5 key
- 0, // 54 0x36 (VK_6) | 6 key
- 0, // 55 0x37 (VK_7) | 7 key
- 0, // 56 0x38 (VK_8) | 8 key
- 0, // 57 0x39 (VK_9) | 9 key
- Qt::Key_unknown, // 58 0x3A -- unassigned --
- Qt::Key_unknown, // 59 0x3B -- unassigned --
- Qt::Key_unknown, // 60 0x3C -- unassigned --
- Qt::Key_unknown, // 61 0x3D -- unassigned --
- Qt::Key_unknown, // 62 0x3E -- unassigned --
- Qt::Key_unknown, // 63 0x3F -- unassigned --
- Qt::Key_unknown, // 64 0x40 -- unassigned --
- 0, // 65 0x41 (VK_A) | A key
- 0, // 66 0x42 (VK_B) | B key
- 0, // 67 0x43 (VK_C) | C key
- 0, // 68 0x44 (VK_D) | D key
- 0, // 69 0x45 (VK_E) | E key
- 0, // 70 0x46 (VK_F) | F key
- 0, // 71 0x47 (VK_G) | G key
- 0, // 72 0x48 (VK_H) | H key
- 0, // 73 0x49 (VK_I) | I key
- 0, // 74 0x4A (VK_J) | J key
- 0, // 75 0x4B (VK_K) | K key
- 0, // 76 0x4C (VK_L) | L key
- 0, // 77 0x4D (VK_M) | M key
- 0, // 78 0x4E (VK_N) | N key
- 0, // 79 0x4F (VK_O) | O key
- 0, // 80 0x50 (VK_P) | P key
- 0, // 81 0x51 (VK_Q) | Q key
- 0, // 82 0x52 (VK_R) | R key
- 0, // 83 0x53 (VK_S) | S key
- 0, // 84 0x54 (VK_T) | T key
- 0, // 85 0x55 (VK_U) | U key
- 0, // 86 0x56 (VK_V) | V key
- 0, // 87 0x57 (VK_W) | W key
- 0, // 88 0x58 (VK_X) | X key
- 0, // 89 0x59 (VK_Y) | Y key
- 0, // 90 0x5A (VK_Z) | Z key
- Qt::Key_Meta, // 91 0x5B VK_LWIN | Left Windows - MS Natural kbd
- Qt::Key_Meta, // 92 0x5C VK_RWIN | Right Windows - MS Natural kbd
- Qt::Key_Menu, // 93 0x5D VK_APPS | Application key-MS Natural kbd
- Qt::Key_unknown, // 94 0x5E -- reserved --
- Qt::Key_Sleep, // 95 0x5F VK_SLEEP
- Qt::Key_0, // 96 0x60 VK_NUMPAD0 | Numeric keypad 0 key
- Qt::Key_1, // 97 0x61 VK_NUMPAD1 | Numeric keypad 1 key
- Qt::Key_2, // 98 0x62 VK_NUMPAD2 | Numeric keypad 2 key
- Qt::Key_3, // 99 0x63 VK_NUMPAD3 | Numeric keypad 3 key
- Qt::Key_4, // 100 0x64 VK_NUMPAD4 | Numeric keypad 4 key
- Qt::Key_5, // 101 0x65 VK_NUMPAD5 | Numeric keypad 5 key
- Qt::Key_6, // 102 0x66 VK_NUMPAD6 | Numeric keypad 6 key
- Qt::Key_7, // 103 0x67 VK_NUMPAD7 | Numeric keypad 7 key
- Qt::Key_8, // 104 0x68 VK_NUMPAD8 | Numeric keypad 8 key
- Qt::Key_9, // 105 0x69 VK_NUMPAD9 | Numeric keypad 9 key
- Qt::Key_Asterisk, // 106 0x6A VK_MULTIPLY | Multiply key
- Qt::Key_Plus, // 107 0x6B VK_ADD | Add key
- Qt::Key_Comma, // 108 0x6C VK_SEPARATOR | Separator key
- Qt::Key_Minus, // 109 0x6D VK_SUBTRACT | Subtract key
- Qt::Key_Period, // 110 0x6E VK_DECIMAL | Decimal key
- Qt::Key_Slash, // 111 0x6F VK_DIVIDE | Divide key
- Qt::Key_F1, // 112 0x70 VK_F1 | F1 key
- Qt::Key_F2, // 113 0x71 VK_F2 | F2 key
- Qt::Key_F3, // 114 0x72 VK_F3 | F3 key
- Qt::Key_F4, // 115 0x73 VK_F4 | F4 key
- Qt::Key_F5, // 116 0x74 VK_F5 | F5 key
- Qt::Key_F6, // 117 0x75 VK_F6 | F6 key
- Qt::Key_F7, // 118 0x76 VK_F7 | F7 key
- Qt::Key_F8, // 119 0x77 VK_F8 | F8 key
- Qt::Key_F9, // 120 0x78 VK_F9 | F9 key
- Qt::Key_F10, // 121 0x79 VK_F10 | F10 key
- Qt::Key_F11, // 122 0x7A VK_F11 | F11 key
- Qt::Key_F12, // 123 0x7B VK_F12 | F12 key
- Qt::Key_F13, // 124 0x7C VK_F13 | F13 key
- Qt::Key_F14, // 125 0x7D VK_F14 | F14 key
- Qt::Key_F15, // 126 0x7E VK_F15 | F15 key
- Qt::Key_F16, // 127 0x7F VK_F16 | F16 key
- Qt::Key_F17, // 128 0x80 VK_F17 | F17 key
- Qt::Key_F18, // 129 0x81 VK_F18 | F18 key
- Qt::Key_F19, // 130 0x82 VK_F19 | F19 key
- Qt::Key_F20, // 131 0x83 VK_F20 | F20 key
- Qt::Key_F21, // 132 0x84 VK_F21 | F21 key
- Qt::Key_F22, // 133 0x85 VK_F22 | F22 key
- Qt::Key_F23, // 134 0x86 VK_F23 | F23 key
- Qt::Key_F24, // 135 0x87 VK_F24 | F24 key
- Qt::Key_unknown, // 136 0x88 -- unassigned --
- Qt::Key_unknown, // 137 0x89 -- unassigned --
- Qt::Key_unknown, // 138 0x8A -- unassigned --
- Qt::Key_unknown, // 139 0x8B -- unassigned --
- Qt::Key_unknown, // 140 0x8C -- unassigned --
- Qt::Key_unknown, // 141 0x8D -- unassigned --
- Qt::Key_unknown, // 142 0x8E -- unassigned --
- Qt::Key_unknown, // 143 0x8F -- unassigned --
- Qt::Key_NumLock, // 144 0x90 VK_NUMLOCK | Num Lock key
- Qt::Key_ScrollLock, // 145 0x91 VK_SCROLL | Scroll Lock key
- // Fujitsu/OASYS kbd --------------------
- 0, //Qt::Key_Jisho, // 146 0x92 VK_OEM_FJ_JISHO | 'Dictionary' key /
- // VK_OEM_NEC_EQUAL = key on numpad on NEC PC-9800 kbd
- Qt::Key_Massyo, // 147 0x93 VK_OEM_FJ_MASSHOU | 'Unregister word' key
- Qt::Key_Touroku, // 148 0x94 VK_OEM_FJ_TOUROKU | 'Register word' key
- 0, //Qt::Key_Oyayubi_Left,//149 0x95 VK_OEM_FJ_LOYA | 'Left OYAYUBI' key
- 0, //Qt::Key_Oyayubi_Right,//150 0x96 VK_OEM_FJ_ROYA | 'Right OYAYUBI' key
- Qt::Key_unknown, // 151 0x97 -- unassigned --
- Qt::Key_unknown, // 152 0x98 -- unassigned --
- Qt::Key_unknown, // 153 0x99 -- unassigned --
- Qt::Key_unknown, // 154 0x9A -- unassigned --
- Qt::Key_unknown, // 155 0x9B -- unassigned --
- Qt::Key_unknown, // 156 0x9C -- unassigned --
- Qt::Key_unknown, // 157 0x9D -- unassigned --
- Qt::Key_unknown, // 158 0x9E -- unassigned --
- Qt::Key_unknown, // 159 0x9F -- unassigned --
- Qt::Key_Shift, // 160 0xA0 VK_LSHIFT | Left Shift key
- Qt::Key_Shift, // 161 0xA1 VK_RSHIFT | Right Shift key
- Qt::Key_Control, // 162 0xA2 VK_LCONTROL | Left Ctrl key
- Qt::Key_Control, // 163 0xA3 VK_RCONTROL | Right Ctrl key
- Qt::Key_Alt, // 164 0xA4 VK_LMENU | Left Menu key
- Qt::Key_Alt, // 165 0xA5 VK_RMENU | Right Menu key
- Qt::Key_Back, // 166 0xA6 VK_BROWSER_BACK | Browser Back key
- Qt::Key_Forward, // 167 0xA7 VK_BROWSER_FORWARD | Browser Forward key
- Qt::Key_Refresh, // 168 0xA8 VK_BROWSER_REFRESH | Browser Refresh key
- Qt::Key_Stop, // 169 0xA9 VK_BROWSER_STOP | Browser Stop key
- Qt::Key_Search, // 170 0xAA VK_BROWSER_SEARCH | Browser Search key
- Qt::Key_Favorites, // 171 0xAB VK_BROWSER_FAVORITES| Browser Favorites key
- Qt::Key_HomePage, // 172 0xAC VK_BROWSER_HOME | Browser Start and Home key
- Qt::Key_VolumeMute, // 173 0xAD VK_VOLUME_MUTE | Volume Mute key
- Qt::Key_VolumeDown, // 174 0xAE VK_VOLUME_DOWN | Volume Down key
- Qt::Key_VolumeUp, // 175 0xAF VK_VOLUME_UP | Volume Up key
- Qt::Key_MediaNext, // 176 0xB0 VK_MEDIA_NEXT_TRACK | Next Track key
- Qt::Key_MediaPrevious, //177 0xB1 VK_MEDIA_PREV_TRACK | Previous Track key
- Qt::Key_MediaStop, // 178 0xB2 VK_MEDIA_STOP | Stop Media key
- Qt::Key_MediaPlay, // 179 0xB3 VK_MEDIA_PLAY_PAUSE | Play/Pause Media key
- Qt::Key_LaunchMail, // 180 0xB4 VK_LAUNCH_MAIL | Start Mail key
- Qt::Key_LaunchMedia,// 181 0xB5 VK_LAUNCH_MEDIA_SELECT Select Media key
- Qt::Key_Launch0, // 182 0xB6 VK_LAUNCH_APP1 | Start Application 1 key
- Qt::Key_Launch1, // 183 0xB7 VK_LAUNCH_APP2 | Start Application 2 key
- Qt::Key_unknown, // 184 0xB8 -- reserved --
- Qt::Key_unknown, // 185 0xB9 -- reserved --
- 0, // 186 0xBA VK_OEM_1 | ';:' for US
- 0, // 187 0xBB VK_OEM_PLUS | '+' any country
- 0, // 188 0xBC VK_OEM_COMMA | ',' any country
- 0, // 189 0xBD VK_OEM_MINUS | '-' any country
- 0, // 190 0xBE VK_OEM_PERIOD | '.' any country
- 0, // 191 0xBF VK_OEM_2 | '/?' for US
- 0, // 192 0xC0 VK_OEM_3 | '`~' for US
- Qt::Key_unknown, // 193 0xC1 -- reserved --
- Qt::Key_unknown, // 194 0xC2 -- reserved --
- Qt::Key_unknown, // 195 0xC3 -- reserved --
- Qt::Key_unknown, // 196 0xC4 -- reserved --
- Qt::Key_unknown, // 197 0xC5 -- reserved --
- Qt::Key_unknown, // 198 0xC6 -- reserved --
- Qt::Key_unknown, // 199 0xC7 -- reserved --
- Qt::Key_unknown, // 200 0xC8 -- reserved --
- Qt::Key_unknown, // 201 0xC9 -- reserved --
- Qt::Key_unknown, // 202 0xCA -- reserved --
- Qt::Key_unknown, // 203 0xCB -- reserved --
- Qt::Key_unknown, // 204 0xCC -- reserved --
- Qt::Key_unknown, // 205 0xCD -- reserved --
- Qt::Key_unknown, // 206 0xCE -- reserved --
- Qt::Key_unknown, // 207 0xCF -- reserved --
- Qt::Key_unknown, // 208 0xD0 -- reserved --
- Qt::Key_unknown, // 209 0xD1 -- reserved --
- Qt::Key_unknown, // 210 0xD2 -- reserved --
- Qt::Key_unknown, // 211 0xD3 -- reserved --
- Qt::Key_unknown, // 212 0xD4 -- reserved --
- Qt::Key_unknown, // 213 0xD5 -- reserved --
- Qt::Key_unknown, // 214 0xD6 -- reserved --
- Qt::Key_unknown, // 215 0xD7 -- reserved --
- Qt::Key_unknown, // 216 0xD8 -- unassigned --
- Qt::Key_unknown, // 217 0xD9 -- unassigned --
- Qt::Key_unknown, // 218 0xDA -- unassigned --
- 0, // 219 0xDB VK_OEM_4 | '[{' for US
- 0, // 220 0xDC VK_OEM_5 | '\|' for US
- 0, // 221 0xDD VK_OEM_6 | ']}' for US
- 0, // 222 0xDE VK_OEM_7 | ''"' for US
- 0, // 223 0xDF VK_OEM_8
- Qt::Key_unknown, // 224 0xE0 -- reserved --
- Qt::Key_unknown, // 225 0xE1 VK_OEM_AX | 'AX' key on Japanese AX kbd
- Qt::Key_unknown, // 226 0xE2 VK_OEM_102 | "<>" or "\|" on RT 102-key kbd
- Qt::Key_unknown, // 227 0xE3 VK_ICO_HELP | Help key on ICO
- Qt::Key_unknown, // 228 0xE4 VK_ICO_00 | 00 key on ICO
- Qt::Key_unknown, // 229 0xE5 VK_PROCESSKEY | IME Process key
- Qt::Key_unknown, // 230 0xE6 VK_ICO_CLEAR |
- Qt::Key_unknown, // 231 0xE7 VK_PACKET | Unicode char as keystrokes
- Qt::Key_unknown, // 232 0xE8 -- unassigned --
- // Nokia/Ericsson definitions ---------------
- Qt::Key_unknown, // 233 0xE9 VK_OEM_RESET
- Qt::Key_unknown, // 234 0xEA VK_OEM_JUMP
- Qt::Key_unknown, // 235 0xEB VK_OEM_PA1
- Qt::Key_unknown, // 236 0xEC VK_OEM_PA2
- Qt::Key_unknown, // 237 0xED VK_OEM_PA3
- Qt::Key_unknown, // 238 0xEE VK_OEM_WSCTRL
- Qt::Key_unknown, // 239 0xEF VK_OEM_CUSEL
- Qt::Key_unknown, // 240 0xF0 VK_OEM_ATTN
- Qt::Key_unknown, // 241 0xF1 VK_OEM_FINISH
- Qt::Key_unknown, // 242 0xF2 VK_OEM_COPY
- Qt::Key_unknown, // 243 0xF3 VK_OEM_AUTO
- Qt::Key_unknown, // 244 0xF4 VK_OEM_ENLW
- Qt::Key_unknown, // 245 0xF5 VK_OEM_BACKTAB
- Qt::Key_unknown, // 246 0xF6 VK_ATTN | Attn key
- Qt::Key_unknown, // 247 0xF7 VK_CRSEL | CrSel key
- Qt::Key_unknown, // 248 0xF8 VK_EXSEL | ExSel key
- Qt::Key_unknown, // 249 0xF9 VK_EREOF | Erase EOF key
- Qt::Key_Play, // 250 0xFA VK_PLAY | Play key
- Qt::Key_Zoom, // 251 0xFB VK_ZOOM | Zoom key
- Qt::Key_unknown, // 252 0xFC VK_NONAME | Reserved
- Qt::Key_unknown, // 253 0xFD VK_PA1 | PA1 key
- Qt::Key_Clear, // 254 0xFE VK_OEM_CLEAR | Clear key
- 0
-};
-
-// Possible modifier states.
-// NOTE: The order of these states match the order in QKeyMapperPrivate::updatePossibleKeyCodes()!
-static const Qt::KeyboardModifiers ModsTbl[] = {
- Qt::NoModifier, // 0
- Qt::ShiftModifier, // 1
- Qt::ControlModifier, // 2
- Qt::ControlModifier | Qt::ShiftModifier, // 3
- Qt::AltModifier, // 4
- Qt::AltModifier | Qt::ShiftModifier, // 5
- Qt::AltModifier | Qt::ControlModifier, // 6
- Qt::AltModifier | Qt::ShiftModifier | Qt::ControlModifier, // 7
- Qt::NoModifier, // Fall-back to raw Key_*
-};
-
-/**
- Remap return or action key to select key for windows mobile.
-*/
-inline int winceKeyBend(int keyCode)
-{
-#if defined(Q_OS_WINCE_WM) && defined(QT_KEYPAD_NAVIGATION)
- // remap return or action key to select key for windows mobile.
- // will be changed to a table remapping function in the next version (4.6/7).
- if (keyCode == VK_RETURN && QApplication::keypadNavigationEnabled())
- return Qt::Key_Select;
- else
- return KeyTbl[keyCode];
-#else
- return KeyTbl[keyCode];
-#endif
-}
-
-#if defined(Q_OS_WINCE)
- // Use the KeyTbl to resolve a Qt::Key out of the virtual keys.
- // In case it is not resolvable, continue using the virtual key itself.
-
-QT_BEGIN_INCLUDE_NAMESPACE
-
-int ToUnicode(UINT vk, int /*scancode*/, unsigned char* /*kbdBuffer*/, LPWSTR unicodeBuffer, int, int)
-{
- QT_USE_NAMESPACE
- QChar* buf = reinterpret_cast< QChar*>(unicodeBuffer);
- if (KeyTbl[vk] == 0) {
- buf[0] = vk;
- return 1;
- }
- return 0;
-}
-
-int ToAscii(UINT vk, int scancode, unsigned char *kbdBuffer, LPWORD unicodeBuffer, int flag)
-{
- return ToUnicode(vk, scancode, kbdBuffer, (LPWSTR) unicodeBuffer, 0, flag);
-
-}
-QT_END_INCLUDE_NAMESPACE
-
-#endif
-
-// Translate a VK into a Qt key code, or unicode character
-static inline int toKeyOrUnicode(int vk, int scancode, unsigned char *kbdBuffer, bool *isDeadkey = 0)
-{
- Q_ASSERT(vk > 0 && vk < 256);
- int code = 0;
- QChar unicodeBuffer[5];
- int res = ToUnicode(vk, scancode, kbdBuffer, reinterpret_cast<LPWSTR>(unicodeBuffer), 5, 0);
- if (res)
- code = unicodeBuffer[0].toUpper().unicode();
-
- // Qt::Key_*'s are not encoded below 0x20, so try again, and DEL keys (0x7f) is encoded with a
- // proper Qt::Key_ code
- if (code < 0x20 || code == 0x7f) // Handles res==0 too
- code = winceKeyBend(vk);
-
- if (isDeadkey)
- *isDeadkey = (res == -1);
-
- return code == Qt::Key_unknown ? 0 : code;
-}
-
-Q_GUI_EXPORT int qt_translateKeyCode(int vk)
-{
- int code = winceKeyBend((vk < 0 || vk > 255) ? 0 : vk);
- return code == Qt::Key_unknown ? 0 : code;
-}
-
-static inline int asciiToKeycode(char a, int state)
-{
- if (a >= 'a' && a <= 'z')
- a = toupper(a);
- if ((state & Qt::ControlModifier) != 0) {
- if (a >= 0 && a <= 31) // Ctrl+@..Ctrl+A..CTRL+Z..Ctrl+_
- a += '@'; // to @..A..Z.._
- }
- return a & 0xff;
-}
-
-static inline bool isModifierKey(int code)
-{
- return (code >= Qt::Key_Shift) && (code <= Qt::Key_ScrollLock);
-}
-// Key translation -----------------------------------------------------------------------[ end ]---
-
-
-static void qt_show_system_menu(QWidget* tlw)
-{
- Q_ASSERT(tlw->testAttribute(Qt::WA_WState_Created));
- HMENU menu = GetSystemMenu(tlw->internalWinId(), FALSE);
- if (!menu)
- return; // no menu for this window
-
-#define enabled (MF_BYCOMMAND | MF_ENABLED)
-#define disabled (MF_BYCOMMAND | MF_GRAYED)
-
-#ifndef Q_OS_WINCE
- EnableMenuItem(menu, SC_MINIMIZE, (tlw->windowFlags() & Qt::WindowMinimizeButtonHint)?enabled:disabled);
- bool maximized = IsZoomed(tlw->internalWinId());
-
- EnableMenuItem(menu, SC_MAXIMIZE, ! (tlw->windowFlags() & Qt::WindowMaximizeButtonHint) || maximized?disabled:enabled);
- EnableMenuItem(menu, SC_RESTORE, maximized?enabled:disabled);
-
- // We should _not_ check with the setFixedSize(x,y) case here, since Windows is not able to check
- // this and our menu here would be out-of-sync with the menu produced by mouse-click on the
- // System Menu, or right-click on the title bar.
- EnableMenuItem(menu, SC_SIZE, (tlw->windowFlags() & Qt::MSWindowsFixedSizeDialogHint) || maximized?disabled:enabled);
- EnableMenuItem(menu, SC_MOVE, maximized?disabled:enabled);
- EnableMenuItem(menu, SC_CLOSE, enabled);
- // Set bold on close menu item
- MENUITEMINFO closeItem;
- closeItem.cbSize = sizeof(MENUITEMINFO);
- closeItem.fMask = MIIM_STATE;
- closeItem.fState = MFS_DEFAULT;
- SetMenuItemInfo(menu, SC_CLOSE, FALSE, &closeItem);
-#endif
-
-#undef enabled
-#undef disabled
- int ret = TrackPopupMenuEx(menu,
- TPM_LEFTALIGN | TPM_TOPALIGN | TPM_NONOTIFY | TPM_RETURNCMD,
- tlw->geometry().x(), tlw->geometry().y(),
- tlw->internalWinId(),
- 0);
- if (ret)
- QtWndProc(tlw->internalWinId(), WM_SYSCOMMAND, ret, 0);
-}
-
-
-// QETWidget class is only for accessing the sendSpontaneousEvent function in QApplication
-class QETWidget : public QWidget {
-public:
- static bool sendSpontaneousEvent(QObject *r, QEvent *e)
- { return QApplication::sendSpontaneousEvent(r, e); }
-};
-
-
-// Keyboard map private ----------------------------------------------------------------[ start ]---
-
-/*
- \internal
- A Windows KeyboardLayoutItem has 8 possible states:
- 1. Unmodified
- 2. Shift
- 3. Control
- 4. Control + Shift
- 5. Alt
- 6. Alt + Shift
- 7. Alt + Control
- 8. Alt + Control + Shift
-*/
-struct KeyboardLayoutItem {
- bool dirty;
- quint8 deadkeys;
- quint32 qtKey[9]; // Can by any Qt::Key_<foo>, or unicode character
-};
-
-QKeyMapperPrivate::QKeyMapperPrivate()
-{
- memset(keyLayout, 0, sizeof(keyLayout));
-}
-
-QKeyMapperPrivate::~QKeyMapperPrivate()
-{
- deleteLayouts();
-}
-
-void QKeyMapperPrivate::deleteLayouts()
-{
- for (int i = 0; i < 255; ++i) {
- if (keyLayout[i]) {
- delete keyLayout[i];
- keyLayout[i] = 0;
- }
- }
-}
-
-void QKeyMapperPrivate::clearMappings()
-{
- deleteLayouts();
-
- /* MAKELCID()'s first argument is a WORD, and GetKeyboardLayout()
- * returns a DWORD. */
-
- LCID newLCID = MAKELCID((quintptr)GetKeyboardLayout(0), SORT_DEFAULT);
-// keyboardInputLocale = qt_localeFromLCID(newLCID);
-
- bool bidi = false;
- wchar_t LCIDFontSig[16];
- if (GetLocaleInfo(newLCID, LOCALE_FONTSIGNATURE, LCIDFontSig, sizeof(LCIDFontSig) / sizeof(wchar_t))
- && (LCIDFontSig[7] & (wchar_t)0x0800))
- bidi = true;
-
- keyboardInputDirection = bidi ? Qt::RightToLeft : Qt::LeftToRight;
-}
-
-void QKeyMapperPrivate::clearRecordedKeys()
-{
- key_recorder.clearKeys();
-}
-
-
-inline void setKbdState(unsigned char *kbd, bool shift, bool ctrl, bool alt)
-{
- kbd[VK_LSHIFT ] = (shift ? 0x80 : 0);
- kbd[VK_SHIFT ] = (shift ? 0x80 : 0);
- kbd[VK_LCONTROL] = (ctrl ? 0x80 : 0);
- kbd[VK_CONTROL ] = (ctrl ? 0x80 : 0);
- kbd[VK_RMENU ] = (alt ? 0x80 : 0);
- kbd[VK_MENU ] = (alt ? 0x80 : 0);
-}
-
-void QKeyMapperPrivate::updateKeyMap(const MSG &msg)
-{
- unsigned char kbdBuffer[256]; // Will hold the complete keyboard state
- GetKeyboardState(kbdBuffer);
- quint32 scancode = (msg.lParam >> 16) & 0xfff;
- updatePossibleKeyCodes(kbdBuffer, scancode, msg.wParam);
-}
-
-void QKeyMapperPrivate::updatePossibleKeyCodes(unsigned char *kbdBuffer, quint32 scancode,
- quint32 vk_key)
-{
- if (!vk_key || (keyLayout[vk_key] && !keyLayout[vk_key]->dirty))
- return;
-
- if (!keyLayout[vk_key])
- keyLayout[vk_key] = new KeyboardLayoutItem;
-
- // Copy keyboard state, so we can modify and query output for each possible permutation
- unsigned char buffer[256];
- memcpy(buffer, kbdBuffer, sizeof(buffer));
- // Always 0, as Windows doesn't treat these as modifiers;
- buffer[VK_LWIN ] = 0;
- buffer[VK_RWIN ] = 0;
- buffer[VK_CAPITAL ] = 0;
- buffer[VK_NUMLOCK ] = 0;
- buffer[VK_SCROLL ] = 0;
- // Always 0, since we'll only change the other versions
- buffer[VK_RSHIFT ] = 0;
- buffer[VK_RCONTROL] = 0;
- buffer[VK_LMENU ] = 0; // Use right Alt, since left Ctrl + right Alt is considered AltGraph
-
- bool isDeadKey = false;
- keyLayout[vk_key]->deadkeys = 0;
- keyLayout[vk_key]->dirty = false;
- setKbdState(buffer, false, false, false);
- keyLayout[vk_key]->qtKey[0] = toKeyOrUnicode(vk_key, scancode, buffer, &isDeadKey);
- keyLayout[vk_key]->deadkeys |= isDeadKey ? 0x01 : 0;
- setKbdState(buffer, true, false, false);
- keyLayout[vk_key]->qtKey[1] = toKeyOrUnicode(vk_key, scancode, buffer, &isDeadKey);
- keyLayout[vk_key]->deadkeys |= isDeadKey ? 0x02 : 0;
- setKbdState(buffer, false, true, false);
- keyLayout[vk_key]->qtKey[2] = toKeyOrUnicode(vk_key, scancode, buffer, &isDeadKey);
- keyLayout[vk_key]->deadkeys |= isDeadKey ? 0x04 : 0;
- setKbdState(buffer, true, true, false);
- keyLayout[vk_key]->qtKey[3] = toKeyOrUnicode(vk_key, scancode, buffer, &isDeadKey);
- keyLayout[vk_key]->deadkeys |= isDeadKey ? 0x08 : 0;
- setKbdState(buffer, false, false, true);
- keyLayout[vk_key]->qtKey[4] = toKeyOrUnicode(vk_key, scancode, buffer, &isDeadKey);
- keyLayout[vk_key]->deadkeys |= isDeadKey ? 0x10 : 0;
- setKbdState(buffer, true, false, true);
- keyLayout[vk_key]->qtKey[5] = toKeyOrUnicode(vk_key, scancode, buffer, &isDeadKey);
- keyLayout[vk_key]->deadkeys |= isDeadKey ? 0x20 : 0;
- setKbdState(buffer, false, true, true);
- keyLayout[vk_key]->qtKey[6] = toKeyOrUnicode(vk_key, scancode, buffer, &isDeadKey);
- keyLayout[vk_key]->deadkeys |= isDeadKey ? 0x40 : 0;
- setKbdState(buffer, true, true, true);
- keyLayout[vk_key]->qtKey[7] = toKeyOrUnicode(vk_key, scancode, buffer, &isDeadKey);
- keyLayout[vk_key]->deadkeys |= isDeadKey ? 0x80 : 0;
- // Add a fall back key for layouts which don't do composition and show non-latin1 characters
- int fallbackKey = winceKeyBend(vk_key);
- if (!fallbackKey || fallbackKey == Qt::Key_unknown) {
- fallbackKey = 0;
- if (vk_key != keyLayout[vk_key]->qtKey[0] && vk_key < 0x5B && vk_key > 0x2F)
- fallbackKey = vk_key;
- }
- keyLayout[vk_key]->qtKey[8] = fallbackKey;
-
- // If this vk_key a Dead Key
- if (MapVirtualKey(vk_key, 2) & 0x80000000) {
- // Push a Space, then the original key through the low-level ToAscii functions.
- // We do this because these functions (ToAscii / ToUnicode) will alter the internal state of
- // the keyboard driver By doing the following, we set the keyboard driver state back to what
- // it was before we wrecked it with the code above.
- // We need to push the space with an empty keystate map, since the driver checks the map for
- // transitions in modifiers, so this helps us capture all possible deadkeys.
- unsigned char emptyBuffer[256];
- memset(emptyBuffer, 0, sizeof(emptyBuffer));
- ::ToAscii(VK_SPACE, 0, emptyBuffer, reinterpret_cast<LPWORD>(&buffer), 0);
- ::ToAscii(vk_key, scancode, kbdBuffer, reinterpret_cast<LPWORD>(&buffer), 0);
- }
-
-#ifdef DEBUG_KEYMAPPER
- qDebug("updatePossibleKeyCodes for virtual key = 0x%02x!", vk_key);
- for (int i = 0; i < 9; ++i) {
- qDebug(" [%d] (%d,0x%02x,'%c') %s", i,
- keyLayout[vk_key]->qtKey[i],
- keyLayout[vk_key]->qtKey[i],
- keyLayout[vk_key]->qtKey[i] ? keyLayout[vk_key]->qtKey[i] : 0x03,
- keyLayout[vk_key]->deadkeys & (1<<i) ? "deadkey" : "");
- }
-#endif // DEBUG_KEYMAPPER
-}
-
-bool QKeyMapperPrivate::isADeadKey(unsigned int vk_key, unsigned int modifiers)
-{
- if (keyLayout && (vk_key < 256) && keyLayout[vk_key]) {
- for(register int i = 0; i < 9; ++i) {
- if (uint(ModsTbl[i]) == modifiers)
- return bool(keyLayout[vk_key]->deadkeys & 1<<i);
- }
- }
- return false;
-}
-
-extern bool qt_use_rtl_extensions;
-
-QList<int> QKeyMapperPrivate::possibleKeys(QKeyEvent *e)
-{
- QList<int> result;
-
- KeyboardLayoutItem *kbItem = keyLayout[e->nativeVirtualKey()];
- if(!kbItem)
- return result;
-
- quint32 baseKey = kbItem->qtKey[0];
- Qt::KeyboardModifiers keyMods = e->modifiers();
- if (baseKey == Qt::Key_Return && (e->nativeModifiers() & ExtendedKey)) {
- result << int(Qt::Key_Enter + keyMods);
- return result;
- }
- result << int(baseKey + keyMods); // The base key is _always_ valid, of course
-
- for(int i = 1; i < 9; ++i) {
- Qt::KeyboardModifiers neededMods = ModsTbl[i];
- quint32 key = kbItem->qtKey[i];
- if (key && key != baseKey && ((keyMods & neededMods) == neededMods))
- result << int(key + (keyMods & ~neededMods));
- }
-
- return result;
-}
-
-bool QKeyMapperPrivate::translateKeyEvent(QWidget *widget, const MSG &msg, bool grab)
-{
- Q_Q(QKeyMapper);
- Q_UNUSED(q); // Strange, but the compiler complains on q not being referenced, even if it is..
- bool k0 = false;
- bool k1 = false;
- int msgType = msg.message;
-
- quint32 scancode = (msg.lParam >> 16) & 0xfff;
- quint32 vk_key = MapVirtualKey(scancode, 1);
- bool isNumpad = (msg.wParam >= VK_NUMPAD0 && msg.wParam <= VK_NUMPAD9);
- quint32 nModifiers = 0;
-
-#if defined(Q_OS_WINCE)
- nModifiers |= (GetKeyState(VK_SHIFT ) < 0 ? ShiftAny : 0);
- nModifiers |= (GetKeyState(VK_CONTROL) < 0 ? ControlAny : 0);
- nModifiers |= (GetKeyState(VK_MENU ) < 0 ? AltAny : 0);
- nModifiers |= (GetKeyState(VK_LWIN ) < 0 ? MetaLeft : 0);
- nModifiers |= (GetKeyState(VK_RWIN ) < 0 ? MetaRight : 0);
-#else
- // Map native modifiers to some bit representation
- nModifiers |= (GetKeyState(VK_LSHIFT ) & 0x80 ? ShiftLeft : 0);
- nModifiers |= (GetKeyState(VK_RSHIFT ) & 0x80 ? ShiftRight : 0);
- nModifiers |= (GetKeyState(VK_LCONTROL) & 0x80 ? ControlLeft : 0);
- nModifiers |= (GetKeyState(VK_RCONTROL) & 0x80 ? ControlRight : 0);
- nModifiers |= (GetKeyState(VK_LMENU ) & 0x80 ? AltLeft : 0);
- nModifiers |= (GetKeyState(VK_RMENU ) & 0x80 ? AltRight : 0);
- nModifiers |= (GetKeyState(VK_LWIN ) & 0x80 ? MetaLeft : 0);
- nModifiers |= (GetKeyState(VK_RWIN ) & 0x80 ? MetaRight : 0);
- // Add Lock keys to the same bits
- nModifiers |= (GetKeyState(VK_CAPITAL ) & 0x01 ? CapsLock : 0);
- nModifiers |= (GetKeyState(VK_NUMLOCK ) & 0x01 ? NumLock : 0);
- nModifiers |= (GetKeyState(VK_SCROLL ) & 0x01 ? ScrollLock : 0);
-#endif // Q_OS_WINCE
-
- if (msg.lParam & ExtendedKey)
- nModifiers |= msg.lParam & ExtendedKey;
-
- // Get the modifier states (may be altered later, depending on key code)
- int state = 0;
- state |= (nModifiers & ShiftAny ? Qt::ShiftModifier : 0);
- state |= (nModifiers & ControlAny ? Qt::ControlModifier : 0);
- state |= (nModifiers & AltAny ? Qt::AltModifier : 0);
- state |= (nModifiers & MetaAny ? Qt::MetaModifier : 0);
-
- // Now we know enough to either have MapVirtualKey or our own keymap tell us if it's a deadkey
- bool isDeadKey = isADeadKey(msg.wParam, state)
- || MapVirtualKey(msg.wParam, 2) & 0x80000000;
-
- // A multi-character key not found by our look-ahead
- if (msgType == WM_CHAR) {
- QString s;
- QChar ch = QChar((ushort)msg.wParam);
- if (!ch.isNull())
- s += ch;
-
- k0 = q->sendKeyEvent(widget, grab, QEvent::KeyPress, 0, Qt::KeyboardModifier(state), s, false, 0, scancode, vk_key, nModifiers);
- k1 = q->sendKeyEvent(widget, grab, QEvent::KeyRelease, 0, Qt::KeyboardModifier(state), s, false, 0, scancode, vk_key, nModifiers);
- }
-
- // Input method characters not found by our look-ahead
- else if (msgType == WM_IME_CHAR) {
- QString s;
- QChar ch = QChar((ushort)msg.wParam);
- if (!ch.isNull())
- s += ch;
-
- k0 = q->sendKeyEvent(widget, grab, QEvent::KeyPress, 0, Qt::KeyboardModifier(state), s, false, 0, scancode, vk_key, nModifiers);
- k1 = q->sendKeyEvent(widget, grab, QEvent::KeyRelease, 0, Qt::KeyboardModifier(state), s, false, 0, scancode, vk_key, nModifiers);
- }
-
- else {
- // handle Directionality changes (BiDi) with RTL extensions
- if (qt_use_rtl_extensions) {
- static int dirStatus = 0;
- if (!dirStatus && state == Qt::ControlModifier
- && msg.wParam == VK_CONTROL
- && msgType == WM_KEYDOWN) {
- if (GetKeyState(VK_LCONTROL) < 0)
- dirStatus = VK_LCONTROL;
- else if (GetKeyState(VK_RCONTROL) < 0)
- dirStatus = VK_RCONTROL;
- } else if (dirStatus) {
- if (msgType == WM_KEYDOWN) {
- if (msg.wParam == VK_SHIFT) {
- if (dirStatus == VK_LCONTROL && GetKeyState(VK_LSHIFT) < 0)
- dirStatus = VK_LSHIFT;
- else if (dirStatus == VK_RCONTROL && GetKeyState(VK_RSHIFT) < 0)
- dirStatus = VK_RSHIFT;
- } else {
- dirStatus = 0;
- }
- } else if (msgType == WM_KEYUP) {
- if (dirStatus == VK_LSHIFT
- && ((msg.wParam == VK_SHIFT && GetKeyState(VK_LCONTROL))
- || (msg.wParam == VK_CONTROL && GetKeyState(VK_LSHIFT)))) {
- k0 = q->sendKeyEvent(widget, grab, QEvent::KeyPress, Qt::Key_Direction_L, 0,
- QString(), false, 0,
- scancode, msg.wParam, nModifiers);
- k1 = q->sendKeyEvent(widget, grab, QEvent::KeyRelease, Qt::Key_Direction_L, 0,
- QString(), false, 0,
- scancode, msg.wParam, nModifiers);
- dirStatus = 0;
- } else if (dirStatus == VK_RSHIFT
- && ( (msg.wParam == VK_SHIFT && GetKeyState(VK_RCONTROL))
- || (msg.wParam == VK_CONTROL && GetKeyState(VK_RSHIFT)))) {
- k0 = q->sendKeyEvent(widget, grab, QEvent::KeyPress, Qt::Key_Direction_R,
- 0, QString(), false, 0,
- scancode, msg.wParam, nModifiers);
- k1 = q->sendKeyEvent(widget, grab, QEvent::KeyRelease, Qt::Key_Direction_R,
- 0, QString(), false, 0,
- scancode, msg.wParam, nModifiers);
- dirStatus = 0;
- } else {
- dirStatus = 0;
- }
- } else {
- dirStatus = 0;
- }
- }
- }
-
- // IME will process these keys, so simply return
- if(msg.wParam == VK_PROCESSKEY)
- return true;
-
- // Ignore invalid virtual keycodes (see bugs 127424, QTBUG-3630)
- if (msg.wParam == 0 || msg.wParam == 0xFF)
- return true;
-
- // Translate VK_* (native) -> Key_* (Qt) keys
- // If it's a dead key, we cannot use the toKeyOrUnicode() function, since that will change
- // the internal state of the keyboard driver, resulting in that dead keys no longer works.
- // ..also if we're typing numbers on the keypad, while holding down the Alt modifier.
- int code = 0;
- if (isNumpad && (nModifiers & AltAny)) {
- code = winceKeyBend(msg.wParam);
- } else if (!isDeadKey) {
- unsigned char kbdBuffer[256]; // Will hold the complete keyboard state
- GetKeyboardState(kbdBuffer);
- code = toKeyOrUnicode(msg.wParam, scancode, kbdBuffer);
- }
-
- // Invert state logic:
- // If the key actually pressed is a modifier key, then we remove its modifier key from the
- // state, since a modifier-key can't have itself as a modifier
- if (code == Qt::Key_Control)
- state = state ^ Qt::ControlModifier;
- else if (code == Qt::Key_Shift)
- state = state ^ Qt::ShiftModifier;
- else if (code == Qt::Key_Alt)
- state = state ^ Qt::AltModifier;
-
- // If the bit 24 of lParm is set you received a enter,
- // otherwise a Return. (This is the extended key bit)
- if ((code == Qt::Key_Return) && (msg.lParam & 0x1000000))
- code = Qt::Key_Enter;
-
- // All cursor keys without extended bit
- if (!(msg.lParam & 0x1000000)) {
- switch (code) {
- case Qt::Key_Left:
- case Qt::Key_Right:
- case Qt::Key_Up:
- case Qt::Key_Down:
- case Qt::Key_PageUp:
- case Qt::Key_PageDown:
- case Qt::Key_Home:
- case Qt::Key_End:
- case Qt::Key_Insert:
- case Qt::Key_Delete:
- case Qt::Key_Asterisk:
- case Qt::Key_Plus:
- case Qt::Key_Minus:
- case Qt::Key_Period:
- case Qt::Key_0:
- case Qt::Key_1:
- case Qt::Key_2:
- case Qt::Key_3:
- case Qt::Key_4:
- case Qt::Key_5:
- case Qt::Key_6:
- case Qt::Key_7:
- case Qt::Key_8:
- case Qt::Key_9:
- state |= ((msg.wParam >= '0' && msg.wParam <= '9')
- || (msg.wParam >= VK_OEM_PLUS && msg.wParam <= VK_OEM_3))
- ? 0 : Qt::KeypadModifier;
- default:
- if ((uint)msg.lParam == 0x004c0001 || (uint)msg.lParam == 0xc04c0001)
- state |= Qt::KeypadModifier;
- break;
- }
- }
- // Other keys with with extended bit
- else {
- switch (code) {
- case Qt::Key_Enter:
- case Qt::Key_Slash:
- case Qt::Key_NumLock:
- state |= Qt::KeypadModifier;
- default:
- break;
- }
- }
-
- // KEYDOWN ---------------------------------------------------------------------------------
- if (msgType == WM_KEYDOWN || msgType == WM_IME_KEYDOWN || msgType == WM_SYSKEYDOWN) {
- // Get the last record of this key press, so we can validate the current state
- // The record is not removed from the list
- KeyRecord *rec = key_recorder.findKey(msg.wParam, false);
-
- // If rec's state doesn't match the current state, something has changed behind our back
- // (Consumed by modal widget is one possibility) So, remove the record from the list
- // This will stop the auto-repeat of the key, should a modifier change, for example
- if (rec && rec->state != state) {
- key_recorder.findKey(msg.wParam, true);
- rec = 0;
- }
-
- // Find unicode character from Windows Message Queue
- MSG wm_char;
- UINT charType = (msgType == WM_KEYDOWN
- ? WM_CHAR
- : msgType == WM_IME_KEYDOWN ? WM_IME_CHAR : WM_SYSCHAR);
-
- QChar uch;
- if (PeekMessage(&wm_char, 0, charType, charType, PM_REMOVE)) {
- // Found a ?_CHAR
- uch = QChar((ushort)wm_char.wParam);
- if (msgType == WM_SYSKEYDOWN && uch.isLetter() && (msg.lParam & KF_ALTDOWN))
- uch = uch.toLower(); // (See doc of WM_SYSCHAR) Alt-letter
- if (!code && !uch.row())
- code = asciiToKeycode(uch.cell(), state);
- }
-
- // Special handling for the WM_IME_KEYDOWN message. Microsoft IME (Korean) will not
- // generate a WM_IME_CHAR message corresponding to this message. We might get wrong
- // results, if we map this virtual key-code directly (for eg '?' US layouts). So try
- // to find the correct key using the current message parameters & keyboard state.
- if (uch.isNull() && msgType == WM_IME_KEYDOWN) {
- BYTE keyState[256];
- wchar_t newKey[3] = {0};
- GetKeyboardState(keyState);
- int val = ToUnicode(vk_key, scancode, keyState, newKey, 2, 0);
- if (val == 1) {
- uch = QChar(newKey[0]);
- } else {
- // If we are still not able to find a unicode key, pass the WM_IME_KEYDOWN
- // message to DefWindowProc() for generating a proper WM_KEYDOWN.
- return false;
- }
- }
-
- // If no ?_CHAR was found in the queue; deduct character from the ?_KEYDOWN parameters
- if (uch.isNull()) {
- if (msg.wParam == VK_DELETE) {
- uch = QChar(QLatin1Char(0x7f)); // Windows doesn't know this one.
- } else {
- if (msgType != WM_SYSKEYDOWN || !code) {
- UINT map = MapVirtualKey(msg.wParam, 2);
- // If the high bit of the return value is set, it's a deadkey
- if (!(map & 0x80000000))
- uch = QChar((ushort)map);
- }
- }
- if (!code && !uch.row())
- code = asciiToKeycode(uch.cell(), state);
- }
-
- // Special handling of global Windows hotkeys
- if (state == Qt::AltModifier) {
- switch (code) {
- case Qt::Key_Escape:
- case Qt::Key_Tab:
- case Qt::Key_Enter:
- case Qt::Key_F4:
- return false; // Send the event on to Windows
- case Qt::Key_Space:
- // do not pass this key to windows, we will process it ourselves
- qt_show_system_menu(widget->window());
- return true;
- default:
- break;
- }
- }
-
- // Map SHIFT + Tab to SHIFT + BackTab, QShortcutMap knows about this translation
- if (code == Qt::Key_Tab && (state & Qt::ShiftModifier) == Qt::ShiftModifier)
- code = Qt::Key_Backtab;
-
- // If we have a record, it means that the key is already pressed, the state is the same
- // so, we have an auto-repeating key
- if (rec) {
- if (code < Qt::Key_Shift || code > Qt::Key_ScrollLock) {
- k0 = q->sendKeyEvent(widget, grab, QEvent::KeyRelease, code,
- Qt::KeyboardModifier(state), rec->text, true, 0,
- scancode, msg.wParam, nModifiers);
- k1 = q->sendKeyEvent(widget, grab, QEvent::KeyPress, code,
- Qt::KeyboardModifier(state), rec->text, true, 0,
- scancode, msg.wParam, nModifiers);
- }
- }
- // No record of the key being previous pressed, so we now send a QEvent::KeyPress event,
- // and store the key data into our records.
- else {
- QString text;
- if (!uch.isNull())
- text += uch;
- char a = uch.row() ? 0 : uch.cell();
- key_recorder.storeKey(msg.wParam, a, state, text);
- k0 = q->sendKeyEvent(widget, grab, QEvent::KeyPress, code, Qt::KeyboardModifier(state),
- text, false, 0, scancode, msg.wParam, nModifiers);
-
- bool store = true;
- // Alt+<alphanumerical> go to the Win32 menu system if unhandled by Qt
-#if !defined(Q_OS_WINCE)
- if (msgType == WM_SYSKEYDOWN && !k0 && a) {
- HWND parent = GetParent(widget->internalWinId());
- while (parent) {
- if (GetMenu(parent)) {
- SendMessage(parent, WM_SYSCOMMAND, SC_KEYMENU, a);
- store = false;
- k0 = true;
- break;
- }
- parent = GetParent(parent);
- }
- }
-#endif
- if (!store)
- key_recorder.findKey(msg.wParam, true);
- }
- }
-
- // KEYUP -----------------------------------------------------------------------------------
- else {
- // Try to locate the key in our records, and remove it if it exists.
- // The key may not be in our records if, for example, the down event was handled by
- // win32 natively, or our window gets focus while a key is already press, but now gets
- // the key release event.
- KeyRecord* rec = key_recorder.findKey(msg.wParam, true);
- if (!rec && !(code == Qt::Key_Shift
- || code == Qt::Key_Control
- || code == Qt::Key_Meta
- || code == Qt::Key_Alt)) {
- // Someone ate the key down event
- } else {
- if (!code)
- code = asciiToKeycode(rec->ascii ? rec->ascii : msg.wParam, state);
-
- // Map SHIFT + Tab to SHIFT + BackTab, QShortcutMap knows about this translation
- if (code == Qt::Key_Tab && (state & Qt::ShiftModifier) == Qt::ShiftModifier)
- code = Qt::Key_Backtab;
-
- k0 = q->sendKeyEvent(widget, grab, QEvent::KeyRelease, code, Qt::KeyboardModifier(state),
- (rec ? rec->text : QString()), false, 0, scancode, msg.wParam, nModifiers);
-
- // don't pass Alt to Windows unless we are embedded in a non-Qt window
-#if !defined(Q_OS_WINCE)
- if (code == Qt::Key_Alt) {
- k0 = true;
- HWND parent = GetParent(widget->internalWinId());
- while (parent) {
- if (!QWidget::find(parent) && GetMenu(parent)) {
- k0 = false;
- break;
- }
- parent = GetParent(parent);
- }
- }
-#endif
- }
- }
- }
-
- // Return true, if a QKeyEvent was sent to a widget
- return k0 || k1;
-}
-
-
-// QKeyMapper (Windows) implementation -------------------------------------------------[ start ]---
-
-bool QKeyMapper::sendKeyEvent(QWidget *widget, bool grab,
- QEvent::Type type, int code, Qt::KeyboardModifiers modifiers,
- const QString &text, bool autorepeat, int count,
- quint32 nativeScanCode, quint32 nativeVirtualKey, quint32 nativeModifiers,
- bool *)
-{
-#if defined(Q_OS_WINCE)
- Q_UNUSED(grab);
-#endif
- Q_UNUSED(count);
-#if defined QT3_SUPPORT && !defined(QT_NO_SHORTCUT)
- if (type == QEvent::KeyPress
- && !grab
- && QApplicationPrivate::instance()->use_compat()) {
- // send accel events if the keyboard is not grabbed
- QKeyEventEx a(type, code, modifiers,
- text, autorepeat, qMax(1, int(text.length())),
- nativeScanCode, nativeVirtualKey, nativeModifiers);
- if (QApplicationPrivate::instance()->qt_tryAccelEvent(widget, &a))
- return true;
- }
-#else
- Q_UNUSED(grab);
-#endif
- if (!widget->isEnabled())
- return false;
-
- QKeyEventEx e(type, code, modifiers,
- text, autorepeat, qMax(1, int(text.length())),
- nativeScanCode, nativeVirtualKey, nativeModifiers);
- QETWidget::sendSpontaneousEvent(widget, &e);
-
- if (!isModifierKey(code)
- && modifiers == Qt::AltModifier
- && ((code >= Qt::Key_A && code <= Qt::Key_Z) || (code >= Qt::Key_0 && code <= Qt::Key_9))
- && type == QEvent::KeyPress
- && !e.isAccepted())
- QApplication::beep(); // Emulate windows behavior
-
- return e.isAccepted();
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp
index 2350f166b5..0c7af19d34 100644
--- a/src/gui/kernel/qkeysequence.cpp
+++ b/src/gui/kernel/qkeysequence.cpp
@@ -41,11 +41,10 @@
#include "qkeysequence.h"
#include "qkeysequence_p.h"
-#include "private/qapplication_p.h"
+#include "private/qguiapplication_p.h"
#ifndef QT_NO_SHORTCUT
-#include "qshortcut.h"
#include "qdebug.h"
#ifndef QT_NO_REGEXP
# include "qregexp.h"
@@ -55,14 +54,14 @@
#endif
#include "qvariant.h"
-#ifdef Q_WS_MAC
-# include <private/qt_mac_p.h>
-
+#ifdef Q_OS_MAC
+#include <QtCore/private/qcore_mac_p.h>
+#include <Carbon/Carbon.h>
#endif
QT_BEGIN_NAMESPACE
-#ifdef Q_WS_MAC
+#ifdef Q_OS_MAC
static bool qt_sequence_no_mnemonics = true;
struct MacSpecialKey {
int key;
@@ -643,153 +642,153 @@ static const struct {
const QKeyBinding QKeySequencePrivate::keyBindings[] = {
// StandardKey Priority Key Sequence Platforms
- {QKeySequence::Back, 0, Qt::Key_Backspace, QApplicationPrivate::KB_Win},
- {QKeySequence::InsertParagraphSeparator,0, Qt::Key_Return, QApplicationPrivate::KB_All},
- {QKeySequence::InsertParagraphSeparator,0, Qt::Key_Enter, QApplicationPrivate::KB_All},
- {QKeySequence::Delete, 1, Qt::Key_Delete, QApplicationPrivate::KB_All},
- {QKeySequence::MoveToStartOfLine, 0, Qt::Key_Home, QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11 | QApplicationPrivate::KB_S60},
- {QKeySequence::MoveToStartOfDocument, 0, Qt::Key_Home, QApplicationPrivate::KB_Mac},
- {QKeySequence::MoveToEndOfLine, 0, Qt::Key_End, QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11 | QApplicationPrivate::KB_S60},
- {QKeySequence::MoveToEndOfDocument, 0, Qt::Key_End, QApplicationPrivate::KB_Mac},
- {QKeySequence::MoveToPreviousChar, 0, Qt::Key_Left, QApplicationPrivate::KB_All},
- {QKeySequence::MoveToPreviousLine, 0, Qt::Key_Up, QApplicationPrivate::KB_All},
- {QKeySequence::MoveToNextChar, 0, Qt::Key_Right, QApplicationPrivate::KB_All},
- {QKeySequence::MoveToNextLine, 0, Qt::Key_Down, QApplicationPrivate::KB_All},
- {QKeySequence::MoveToPreviousPage, 1, Qt::Key_PageUp, QApplicationPrivate::KB_All},
- {QKeySequence::MoveToNextPage, 1, Qt::Key_PageDown, QApplicationPrivate::KB_All},
- {QKeySequence::HelpContents, 0, Qt::Key_F1, QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11},
- {QKeySequence::HelpContents, 0, Qt::Key_F2, QApplicationPrivate::KB_S60},
- {QKeySequence::FindNext, 0, Qt::Key_F3, QApplicationPrivate::KB_X11},
- {QKeySequence::FindNext, 1, Qt::Key_F3, QApplicationPrivate::KB_Win},
- {QKeySequence::Refresh, 0, Qt::Key_F5, QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11},
- {QKeySequence::Undo, 0, Qt::Key_F14, QApplicationPrivate::KB_X11}, //Undo on sun keyboards
- {QKeySequence::Copy, 0, Qt::Key_F16, QApplicationPrivate::KB_X11}, //Copy on sun keyboards
- {QKeySequence::Paste, 0, Qt::Key_F18, QApplicationPrivate::KB_X11}, //Paste on sun keyboards
- {QKeySequence::Cut, 0, Qt::Key_F20, QApplicationPrivate::KB_X11}, //Cut on sun keyboards
- {QKeySequence::PreviousChild, 0, Qt::Key_Back, QApplicationPrivate::KB_All},
- {QKeySequence::NextChild, 0, Qt::Key_Forward, QApplicationPrivate::KB_All},
- {QKeySequence::Forward, 0, Qt::SHIFT | Qt::Key_Backspace, QApplicationPrivate::KB_Win},
- {QKeySequence::Delete, 0, Qt::SHIFT | Qt::Key_Backspace, QApplicationPrivate::KB_S60},
- {QKeySequence::InsertLineSeparator, 0, Qt::SHIFT | Qt::Key_Return, QApplicationPrivate::KB_All},
- {QKeySequence::InsertLineSeparator, 0, Qt::SHIFT | Qt::Key_Enter, QApplicationPrivate::KB_All},
- {QKeySequence::Paste, 0, Qt::SHIFT | Qt::Key_Insert, QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11},
- {QKeySequence::Cut, 0, Qt::SHIFT | Qt::Key_Delete, QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11}, //## Check if this should work on mac
- {QKeySequence::SelectStartOfLine, 0, Qt::SHIFT | Qt::Key_Home, QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11 | QApplicationPrivate::KB_S60},
- {QKeySequence::SelectStartOfDocument, 0, Qt::SHIFT | Qt::Key_Home, QApplicationPrivate::KB_Mac},
- {QKeySequence::SelectEndOfLine, 0, Qt::SHIFT | Qt::Key_End, QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11 | QApplicationPrivate::KB_S60},
- {QKeySequence::SelectEndOfDocument, 0, Qt::SHIFT | Qt::Key_End, QApplicationPrivate::KB_Mac},
- {QKeySequence::SelectPreviousChar, 0, Qt::SHIFT | Qt::Key_Left, QApplicationPrivate::KB_All},
- {QKeySequence::SelectPreviousLine, 0, Qt::SHIFT | Qt::Key_Up, QApplicationPrivate::KB_All},
- {QKeySequence::SelectNextChar, 0, Qt::SHIFT | Qt::Key_Right, QApplicationPrivate::KB_All},
- {QKeySequence::SelectNextLine, 0, Qt::SHIFT | Qt::Key_Down, QApplicationPrivate::KB_All},
- {QKeySequence::SelectPreviousPage, 0, Qt::SHIFT | Qt::Key_PageUp, QApplicationPrivate::KB_All},
- {QKeySequence::SelectNextPage, 0, Qt::SHIFT | Qt::Key_PageDown, QApplicationPrivate::KB_All},
- {QKeySequence::WhatsThis, 1, Qt::SHIFT | Qt::Key_F1, QApplicationPrivate::KB_All},
- {QKeySequence::FindPrevious, 0, Qt::SHIFT | Qt::Key_F3, QApplicationPrivate::KB_X11},
- {QKeySequence::FindPrevious, 1, Qt::SHIFT | Qt::Key_F3, QApplicationPrivate::KB_Win},
- {QKeySequence::ZoomIn, 1, Qt::CTRL | Qt::Key_Plus, QApplicationPrivate::KB_All},
- {QKeySequence::NextChild, 0, Qt::CTRL | Qt::Key_Comma, QApplicationPrivate::KB_KDE},
- {QKeySequence::Preferences, 0, Qt::CTRL | Qt::Key_Comma, QApplicationPrivate::KB_Mac},
- {QKeySequence::ZoomOut, 1, Qt::CTRL | Qt::Key_Minus, QApplicationPrivate::KB_All},
- {QKeySequence::PreviousChild, 0, Qt::CTRL | Qt::Key_Period, QApplicationPrivate::KB_KDE},
- {QKeySequence::HelpContents, 1, Qt::CTRL | Qt::Key_Question, QApplicationPrivate::KB_Mac},
- {QKeySequence::SelectAll, 1, Qt::CTRL | Qt::Key_A, QApplicationPrivate::KB_All},
- {QKeySequence::Bold, 1, Qt::CTRL | Qt::Key_B, QApplicationPrivate::KB_All},
- {QKeySequence::Copy, 1, Qt::CTRL | Qt::Key_C, QApplicationPrivate::KB_All},
- {QKeySequence::Delete, 0, Qt::CTRL | Qt::Key_D, QApplicationPrivate::KB_X11}, //emacs (line edit only)
- {QKeySequence::Find, 0, Qt::CTRL | Qt::Key_F, QApplicationPrivate::KB_All},
- {QKeySequence::FindNext, 1, Qt::CTRL | Qt::Key_G, QApplicationPrivate::KB_Gnome | QApplicationPrivate::KB_Mac},
- {QKeySequence::FindNext, 0, Qt::CTRL | Qt::Key_G, QApplicationPrivate::KB_Win},
- {QKeySequence::Replace, 0, Qt::CTRL | Qt::Key_H, QApplicationPrivate::KB_Win},
- {QKeySequence::Replace, 0, Qt::CTRL | Qt::Key_H, QApplicationPrivate::KB_Gnome},
- {QKeySequence::Italic, 0, Qt::CTRL | Qt::Key_I, QApplicationPrivate::KB_All},
- {QKeySequence::DeleteEndOfLine, 0, Qt::CTRL | Qt::Key_K, QApplicationPrivate::KB_X11}, //emacs (line edit only)
- {QKeySequence::New, 1, Qt::CTRL | Qt::Key_N, QApplicationPrivate::KB_All},
- {QKeySequence::Open, 1, Qt::CTRL | Qt::Key_O, QApplicationPrivate::KB_All},
- {QKeySequence::Print, 1, Qt::CTRL | Qt::Key_P, QApplicationPrivate::KB_All},
- {QKeySequence::Quit, 0, Qt::CTRL | Qt::Key_Q, QApplicationPrivate::KB_Gnome | QApplicationPrivate::KB_KDE | QApplicationPrivate::KB_Mac},
- {QKeySequence::Refresh, 1, Qt::CTRL | Qt::Key_R, QApplicationPrivate::KB_Gnome | QApplicationPrivate::KB_Mac},
- {QKeySequence::Replace, 0, Qt::CTRL | Qt::Key_R, QApplicationPrivate::KB_KDE},
- {QKeySequence::Save, 1, Qt::CTRL | Qt::Key_S, QApplicationPrivate::KB_All},
- {QKeySequence::AddTab, 0, Qt::CTRL | Qt::Key_T, QApplicationPrivate::KB_All},
- {QKeySequence::Underline, 1, Qt::CTRL | Qt::Key_U, QApplicationPrivate::KB_All},
- {QKeySequence::Paste, 1, Qt::CTRL | Qt::Key_V, QApplicationPrivate::KB_All},
- {QKeySequence::Close, 0, Qt::CTRL | Qt::Key_W, QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11},
- {QKeySequence::Close, 1, Qt::CTRL | Qt::Key_W, QApplicationPrivate::KB_Mac},
- {QKeySequence::Cut, 1, Qt::CTRL | Qt::Key_X, QApplicationPrivate::KB_All},
- {QKeySequence::Redo, 1, Qt::CTRL | Qt::Key_Y, QApplicationPrivate::KB_Win | QApplicationPrivate::KB_S60},
- {QKeySequence::Undo, 1, Qt::CTRL | Qt::Key_Z, QApplicationPrivate::KB_All},
- {QKeySequence::Back, 1, Qt::CTRL | Qt::Key_BracketLeft, QApplicationPrivate::KB_Mac},
- {QKeySequence::Forward, 1, Qt::CTRL | Qt::Key_BracketRight, QApplicationPrivate::KB_Mac},
- {QKeySequence::PreviousChild, 1, Qt::CTRL | Qt::Key_BraceLeft, QApplicationPrivate::KB_Mac},
- {QKeySequence::NextChild, 1, Qt::CTRL | Qt::Key_BraceRight, QApplicationPrivate::KB_Mac},
- {QKeySequence::NextChild, 1, Qt::CTRL | Qt::Key_Tab, QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11},
- {QKeySequence::NextChild, 0, Qt::CTRL | Qt::Key_Tab, QApplicationPrivate::KB_Mac}, //different priority from above
- {QKeySequence::DeleteStartOfWord, 0, Qt::CTRL | Qt::Key_Backspace, QApplicationPrivate::KB_X11 | QApplicationPrivate::KB_Win},
- {QKeySequence::Copy, 0, Qt::CTRL | Qt::Key_Insert, QApplicationPrivate::KB_X11 | QApplicationPrivate::KB_Win},
- {QKeySequence::DeleteEndOfWord, 0, Qt::CTRL | Qt::Key_Delete, QApplicationPrivate::KB_X11 | QApplicationPrivate::KB_Win},
- {QKeySequence::MoveToStartOfDocument, 0, Qt::CTRL | Qt::Key_Home, QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11 | QApplicationPrivate::KB_S60},
- {QKeySequence::MoveToEndOfDocument, 0, Qt::CTRL | Qt::Key_End, QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11 | QApplicationPrivate::KB_S60},
- {QKeySequence::Back, 0, Qt::CTRL | Qt::Key_Left, QApplicationPrivate::KB_Mac},
- {QKeySequence::MoveToPreviousWord, 0, Qt::CTRL | Qt::Key_Left, QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11 | QApplicationPrivate::KB_S60},
- {QKeySequence::MoveToStartOfLine, 0, Qt::CTRL | Qt::Key_Left, QApplicationPrivate::KB_Mac },
- {QKeySequence::MoveToStartOfDocument, 1, Qt::CTRL | Qt::Key_Up, QApplicationPrivate::KB_Mac},
- {QKeySequence::Forward, 0, Qt::CTRL | Qt::Key_Right, QApplicationPrivate::KB_Mac},
- {QKeySequence::MoveToEndOfLine, 0, Qt::CTRL | Qt::Key_Right, QApplicationPrivate::KB_Mac },
- {QKeySequence::MoveToNextWord, 0, Qt::CTRL | Qt::Key_Right, QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11 | QApplicationPrivate::KB_S60},
- {QKeySequence::MoveToEndOfDocument, 1, Qt::CTRL | Qt::Key_Down, QApplicationPrivate::KB_Mac},
- {QKeySequence::Close, 1, Qt::CTRL | Qt::Key_F4, QApplicationPrivate::KB_Win},
- {QKeySequence::Close, 0, Qt::CTRL | Qt::Key_F4, QApplicationPrivate::KB_Mac},
- {QKeySequence::NextChild, 0, Qt::CTRL | Qt::Key_F6, QApplicationPrivate::KB_Win},
- {QKeySequence::FindPrevious, 1, Qt::CTRL | Qt::SHIFT | Qt::Key_G, QApplicationPrivate::KB_Gnome | QApplicationPrivate::KB_Mac},
- {QKeySequence::FindPrevious, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_G, QApplicationPrivate::KB_Win},
- {QKeySequence::AddTab, 1, Qt::CTRL | Qt::SHIFT | Qt::Key_N, QApplicationPrivate::KB_KDE},
- {QKeySequence::SaveAs, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_S, QApplicationPrivate::KB_Gnome | QApplicationPrivate::KB_Mac},
- {QKeySequence::Redo, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Z, QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11 | QApplicationPrivate::KB_S60},
- {QKeySequence::Redo, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Z, QApplicationPrivate::KB_Mac},
- {QKeySequence::PreviousChild, 1, Qt::CTRL | Qt::SHIFT | Qt::Key_Backtab, QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11},
- {QKeySequence::PreviousChild, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Backtab, QApplicationPrivate::KB_Mac },//different priority from above
- {QKeySequence::Paste, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Insert, QApplicationPrivate::KB_X11},
- {QKeySequence::SelectStartOfDocument, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Home, QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11 | QApplicationPrivate::KB_S60},
- {QKeySequence::SelectEndOfDocument, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_End, QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11 | QApplicationPrivate::KB_S60},
- {QKeySequence::SelectPreviousWord, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Left, QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11 | QApplicationPrivate::KB_S60},
- {QKeySequence::SelectStartOfLine, 1, Qt::CTRL | Qt::SHIFT | Qt::Key_Left, QApplicationPrivate::KB_Mac },
- {QKeySequence::SelectStartOfDocument, 1, Qt::CTRL | Qt::SHIFT | Qt::Key_Up, QApplicationPrivate::KB_Mac},
- {QKeySequence::SelectNextWord, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Right, QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11 | QApplicationPrivate::KB_S60},
- {QKeySequence::SelectEndOfLine, 1, Qt::CTRL | Qt::SHIFT | Qt::Key_Right, QApplicationPrivate::KB_Mac },
- {QKeySequence::SelectEndOfDocument, 1, Qt::CTRL | Qt::SHIFT | Qt::Key_Down, QApplicationPrivate::KB_Mac},
- {QKeySequence::PreviousChild, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_F6, QApplicationPrivate::KB_Win},
- {QKeySequence::Undo, 0, Qt::ALT | Qt::Key_Backspace, QApplicationPrivate::KB_Win},
- {QKeySequence::DeleteStartOfWord, 0, Qt::ALT | Qt::Key_Backspace, QApplicationPrivate::KB_Mac},
- {QKeySequence::DeleteEndOfWord, 0, Qt::ALT | Qt::Key_Delete, QApplicationPrivate::KB_Mac},
- {QKeySequence::Back, 1, Qt::ALT | Qt::Key_Left, QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11},
- {QKeySequence::MoveToPreviousWord, 0, Qt::ALT | Qt::Key_Left, QApplicationPrivate::KB_Mac},
- {QKeySequence::MoveToStartOfBlock, 0, Qt::ALT | Qt::Key_Up, QApplicationPrivate::KB_Mac}, //mac only
- {QKeySequence::MoveToNextWord, 0, Qt::ALT | Qt::Key_Right, QApplicationPrivate::KB_Mac},
- {QKeySequence::Forward, 1, Qt::ALT | Qt::Key_Right, QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11},
- {QKeySequence::MoveToEndOfBlock, 0, Qt::ALT | Qt::Key_Down, QApplicationPrivate::KB_Mac}, //mac only
- {QKeySequence::MoveToPreviousPage, 0, Qt::ALT | Qt::Key_PageUp, QApplicationPrivate::KB_Mac },
- {QKeySequence::MoveToNextPage, 0, Qt::ALT | Qt::Key_PageDown, QApplicationPrivate::KB_Mac },
- {QKeySequence::Redo, 0, Qt::ALT | Qt::SHIFT | Qt::Key_Backspace,QApplicationPrivate::KB_Win},
- {QKeySequence::SelectPreviousWord, 0, Qt::ALT | Qt::SHIFT | Qt::Key_Left, QApplicationPrivate::KB_Mac},
- {QKeySequence::SelectStartOfBlock, 0, Qt::ALT | Qt::SHIFT | Qt::Key_Up, QApplicationPrivate::KB_Mac}, //mac only
- {QKeySequence::SelectNextWord, 0, Qt::ALT | Qt::SHIFT | Qt::Key_Right, QApplicationPrivate::KB_Mac},
- {QKeySequence::SelectEndOfBlock, 0, Qt::ALT | Qt::SHIFT | Qt::Key_Down, QApplicationPrivate::KB_Mac}, //mac only
- {QKeySequence::MoveToStartOfBlock, 0, Qt::META | Qt::Key_A, QApplicationPrivate::KB_Mac},
- {QKeySequence::Delete, 0, Qt::META | Qt::Key_D, QApplicationPrivate::KB_Mac},
- {QKeySequence::MoveToEndOfBlock, 0, Qt::META | Qt::Key_E, QApplicationPrivate::KB_Mac},
- {QKeySequence::InsertLineSeparator, 0, Qt::META | Qt::Key_Return, QApplicationPrivate::KB_Mac},
- {QKeySequence::InsertLineSeparator, 0, Qt::META | Qt::Key_Enter, QApplicationPrivate::KB_Mac},
- {QKeySequence::MoveToStartOfLine, 0, Qt::META | Qt::Key_Left, QApplicationPrivate::KB_Mac},
- {QKeySequence::MoveToPreviousPage, 0, Qt::META | Qt::Key_Up, QApplicationPrivate::KB_Mac},
- {QKeySequence::MoveToEndOfLine, 0, Qt::META | Qt::Key_Right, QApplicationPrivate::KB_Mac},
- {QKeySequence::MoveToNextPage, 0, Qt::META | Qt::Key_Down, QApplicationPrivate::KB_Mac},
- {QKeySequence::MoveToPreviousPage, 0, Qt::META | Qt::Key_PageUp, QApplicationPrivate::KB_Mac},
- {QKeySequence::MoveToNextPage, 0, Qt::META | Qt::Key_PageDown, QApplicationPrivate::KB_Mac},
- {QKeySequence::SelectStartOfBlock, 0, Qt::META | Qt::SHIFT | Qt::Key_A, QApplicationPrivate::KB_Mac},
- {QKeySequence::SelectEndOfBlock, 0, Qt::META | Qt::SHIFT | Qt::Key_E, QApplicationPrivate::KB_Mac},
- {QKeySequence::SelectStartOfLine, 0, Qt::META | Qt::SHIFT | Qt::Key_Left, QApplicationPrivate::KB_Mac},
- {QKeySequence::SelectEndOfLine, 0, Qt::META | Qt::SHIFT | Qt::Key_Right, QApplicationPrivate::KB_Mac}
+ {QKeySequence::Back, 0, Qt::Key_Backspace, QGuiApplicationPrivate::KB_Win},
+ {QKeySequence::InsertParagraphSeparator,0, Qt::Key_Return, QGuiApplicationPrivate::KB_All},
+ {QKeySequence::InsertParagraphSeparator,0, Qt::Key_Enter, QGuiApplicationPrivate::KB_All},
+ {QKeySequence::Delete, 1, Qt::Key_Delete, QGuiApplicationPrivate::KB_All},
+ {QKeySequence::MoveToStartOfLine, 0, Qt::Key_Home, QGuiApplicationPrivate::KB_Win | QGuiApplicationPrivate::KB_X11 | QGuiApplicationPrivate::KB_S60},
+ {QKeySequence::MoveToStartOfDocument, 0, Qt::Key_Home, QGuiApplicationPrivate::KB_Mac},
+ {QKeySequence::MoveToEndOfLine, 0, Qt::Key_End, QGuiApplicationPrivate::KB_Win | QGuiApplicationPrivate::KB_X11 | QGuiApplicationPrivate::KB_S60},
+ {QKeySequence::MoveToEndOfDocument, 0, Qt::Key_End, QGuiApplicationPrivate::KB_Mac},
+ {QKeySequence::MoveToPreviousChar, 0, Qt::Key_Left, QGuiApplicationPrivate::KB_All},
+ {QKeySequence::MoveToPreviousLine, 0, Qt::Key_Up, QGuiApplicationPrivate::KB_All},
+ {QKeySequence::MoveToNextChar, 0, Qt::Key_Right, QGuiApplicationPrivate::KB_All},
+ {QKeySequence::MoveToNextLine, 0, Qt::Key_Down, QGuiApplicationPrivate::KB_All},
+ {QKeySequence::MoveToPreviousPage, 1, Qt::Key_PageUp, QGuiApplicationPrivate::KB_All},
+ {QKeySequence::MoveToNextPage, 1, Qt::Key_PageDown, QGuiApplicationPrivate::KB_All},
+ {QKeySequence::HelpContents, 0, Qt::Key_F1, QGuiApplicationPrivate::KB_Win | QGuiApplicationPrivate::KB_X11},
+ {QKeySequence::HelpContents, 0, Qt::Key_F2, QGuiApplicationPrivate::KB_S60},
+ {QKeySequence::FindNext, 0, Qt::Key_F3, QGuiApplicationPrivate::KB_X11},
+ {QKeySequence::FindNext, 1, Qt::Key_F3, QGuiApplicationPrivate::KB_Win},
+ {QKeySequence::Refresh, 0, Qt::Key_F5, QGuiApplicationPrivate::KB_Win | QGuiApplicationPrivate::KB_X11},
+ {QKeySequence::Undo, 0, Qt::Key_F14, QGuiApplicationPrivate::KB_X11}, //Undo on sun keyboards
+ {QKeySequence::Copy, 0, Qt::Key_F16, QGuiApplicationPrivate::KB_X11}, //Copy on sun keyboards
+ {QKeySequence::Paste, 0, Qt::Key_F18, QGuiApplicationPrivate::KB_X11}, //Paste on sun keyboards
+ {QKeySequence::Cut, 0, Qt::Key_F20, QGuiApplicationPrivate::KB_X11}, //Cut on sun keyboards
+ {QKeySequence::PreviousChild, 0, Qt::Key_Back, QGuiApplicationPrivate::KB_All},
+ {QKeySequence::NextChild, 0, Qt::Key_Forward, QGuiApplicationPrivate::KB_All},
+ {QKeySequence::Forward, 0, Qt::SHIFT | Qt::Key_Backspace, QGuiApplicationPrivate::KB_Win},
+ {QKeySequence::Delete, 0, Qt::SHIFT | Qt::Key_Backspace, QGuiApplicationPrivate::KB_S60},
+ {QKeySequence::InsertLineSeparator, 0, Qt::SHIFT | Qt::Key_Return, QGuiApplicationPrivate::KB_All},
+ {QKeySequence::InsertLineSeparator, 0, Qt::SHIFT | Qt::Key_Enter, QGuiApplicationPrivate::KB_All},
+ {QKeySequence::Paste, 0, Qt::SHIFT | Qt::Key_Insert, QGuiApplicationPrivate::KB_Win | QGuiApplicationPrivate::KB_X11},
+ {QKeySequence::Cut, 0, Qt::SHIFT | Qt::Key_Delete, QGuiApplicationPrivate::KB_Win | QGuiApplicationPrivate::KB_X11}, //## Check if this should work on mac
+ {QKeySequence::SelectStartOfLine, 0, Qt::SHIFT | Qt::Key_Home, QGuiApplicationPrivate::KB_Win | QGuiApplicationPrivate::KB_X11 | QGuiApplicationPrivate::KB_S60},
+ {QKeySequence::SelectStartOfDocument, 0, Qt::SHIFT | Qt::Key_Home, QGuiApplicationPrivate::KB_Mac},
+ {QKeySequence::SelectEndOfLine, 0, Qt::SHIFT | Qt::Key_End, QGuiApplicationPrivate::KB_Win | QGuiApplicationPrivate::KB_X11 | QGuiApplicationPrivate::KB_S60},
+ {QKeySequence::SelectEndOfDocument, 0, Qt::SHIFT | Qt::Key_End, QGuiApplicationPrivate::KB_Mac},
+ {QKeySequence::SelectPreviousChar, 0, Qt::SHIFT | Qt::Key_Left, QGuiApplicationPrivate::KB_All},
+ {QKeySequence::SelectPreviousLine, 0, Qt::SHIFT | Qt::Key_Up, QGuiApplicationPrivate::KB_All},
+ {QKeySequence::SelectNextChar, 0, Qt::SHIFT | Qt::Key_Right, QGuiApplicationPrivate::KB_All},
+ {QKeySequence::SelectNextLine, 0, Qt::SHIFT | Qt::Key_Down, QGuiApplicationPrivate::KB_All},
+ {QKeySequence::SelectPreviousPage, 0, Qt::SHIFT | Qt::Key_PageUp, QGuiApplicationPrivate::KB_All},
+ {QKeySequence::SelectNextPage, 0, Qt::SHIFT | Qt::Key_PageDown, QGuiApplicationPrivate::KB_All},
+ {QKeySequence::WhatsThis, 1, Qt::SHIFT | Qt::Key_F1, QGuiApplicationPrivate::KB_All},
+ {QKeySequence::FindPrevious, 0, Qt::SHIFT | Qt::Key_F3, QGuiApplicationPrivate::KB_X11},
+ {QKeySequence::FindPrevious, 1, Qt::SHIFT | Qt::Key_F3, QGuiApplicationPrivate::KB_Win},
+ {QKeySequence::ZoomIn, 1, Qt::CTRL | Qt::Key_Plus, QGuiApplicationPrivate::KB_All},
+ {QKeySequence::NextChild, 0, Qt::CTRL | Qt::Key_Comma, QGuiApplicationPrivate::KB_KDE},
+ {QKeySequence::Preferences, 0, Qt::CTRL | Qt::Key_Comma, QGuiApplicationPrivate::KB_Mac},
+ {QKeySequence::ZoomOut, 1, Qt::CTRL | Qt::Key_Minus, QGuiApplicationPrivate::KB_All},
+ {QKeySequence::PreviousChild, 0, Qt::CTRL | Qt::Key_Period, QGuiApplicationPrivate::KB_KDE},
+ {QKeySequence::HelpContents, 1, Qt::CTRL | Qt::Key_Question, QGuiApplicationPrivate::KB_Mac},
+ {QKeySequence::SelectAll, 1, Qt::CTRL | Qt::Key_A, QGuiApplicationPrivate::KB_All},
+ {QKeySequence::Bold, 1, Qt::CTRL | Qt::Key_B, QGuiApplicationPrivate::KB_All},
+ {QKeySequence::Copy, 1, Qt::CTRL | Qt::Key_C, QGuiApplicationPrivate::KB_All},
+ {QKeySequence::Delete, 0, Qt::CTRL | Qt::Key_D, QGuiApplicationPrivate::KB_X11}, //emacs (line edit only)
+ {QKeySequence::Find, 0, Qt::CTRL | Qt::Key_F, QGuiApplicationPrivate::KB_All},
+ {QKeySequence::FindNext, 1, Qt::CTRL | Qt::Key_G, QGuiApplicationPrivate::KB_Gnome | QGuiApplicationPrivate::KB_Mac},
+ {QKeySequence::FindNext, 0, Qt::CTRL | Qt::Key_G, QGuiApplicationPrivate::KB_Win},
+ {QKeySequence::Replace, 0, Qt::CTRL | Qt::Key_H, QGuiApplicationPrivate::KB_Win},
+ {QKeySequence::Replace, 0, Qt::CTRL | Qt::Key_H, QGuiApplicationPrivate::KB_Gnome},
+ {QKeySequence::Italic, 0, Qt::CTRL | Qt::Key_I, QGuiApplicationPrivate::KB_All},
+ {QKeySequence::DeleteEndOfLine, 0, Qt::CTRL | Qt::Key_K, QGuiApplicationPrivate::KB_X11}, //emacs (line edit only)
+ {QKeySequence::New, 1, Qt::CTRL | Qt::Key_N, QGuiApplicationPrivate::KB_All},
+ {QKeySequence::Open, 1, Qt::CTRL | Qt::Key_O, QGuiApplicationPrivate::KB_All},
+ {QKeySequence::Print, 1, Qt::CTRL | Qt::Key_P, QGuiApplicationPrivate::KB_All},
+ {QKeySequence::Quit, 0, Qt::CTRL | Qt::Key_Q, QGuiApplicationPrivate::KB_Gnome | QGuiApplicationPrivate::KB_KDE | QGuiApplicationPrivate::KB_Mac},
+ {QKeySequence::Refresh, 1, Qt::CTRL | Qt::Key_R, QGuiApplicationPrivate::KB_Gnome | QGuiApplicationPrivate::KB_Mac},
+ {QKeySequence::Replace, 0, Qt::CTRL | Qt::Key_R, QGuiApplicationPrivate::KB_KDE},
+ {QKeySequence::Save, 1, Qt::CTRL | Qt::Key_S, QGuiApplicationPrivate::KB_All},
+ {QKeySequence::AddTab, 0, Qt::CTRL | Qt::Key_T, QGuiApplicationPrivate::KB_All},
+ {QKeySequence::Underline, 1, Qt::CTRL | Qt::Key_U, QGuiApplicationPrivate::KB_All},
+ {QKeySequence::Paste, 1, Qt::CTRL | Qt::Key_V, QGuiApplicationPrivate::KB_All},
+ {QKeySequence::Close, 0, Qt::CTRL | Qt::Key_W, QGuiApplicationPrivate::KB_Win | QGuiApplicationPrivate::KB_X11},
+ {QKeySequence::Close, 1, Qt::CTRL | Qt::Key_W, QGuiApplicationPrivate::KB_Mac},
+ {QKeySequence::Cut, 1, Qt::CTRL | Qt::Key_X, QGuiApplicationPrivate::KB_All},
+ {QKeySequence::Redo, 1, Qt::CTRL | Qt::Key_Y, QGuiApplicationPrivate::KB_Win | QGuiApplicationPrivate::KB_S60},
+ {QKeySequence::Undo, 1, Qt::CTRL | Qt::Key_Z, QGuiApplicationPrivate::KB_All},
+ {QKeySequence::Back, 1, Qt::CTRL | Qt::Key_BracketLeft, QGuiApplicationPrivate::KB_Mac},
+ {QKeySequence::Forward, 1, Qt::CTRL | Qt::Key_BracketRight, QGuiApplicationPrivate::KB_Mac},
+ {QKeySequence::PreviousChild, 1, Qt::CTRL | Qt::Key_BraceLeft, QGuiApplicationPrivate::KB_Mac},
+ {QKeySequence::NextChild, 1, Qt::CTRL | Qt::Key_BraceRight, QGuiApplicationPrivate::KB_Mac},
+ {QKeySequence::NextChild, 1, Qt::CTRL | Qt::Key_Tab, QGuiApplicationPrivate::KB_Win | QGuiApplicationPrivate::KB_X11},
+ {QKeySequence::NextChild, 0, Qt::CTRL | Qt::Key_Tab, QGuiApplicationPrivate::KB_Mac}, //different priority from above
+ {QKeySequence::DeleteStartOfWord, 0, Qt::CTRL | Qt::Key_Backspace, QGuiApplicationPrivate::KB_X11 | QGuiApplicationPrivate::KB_Win},
+ {QKeySequence::Copy, 0, Qt::CTRL | Qt::Key_Insert, QGuiApplicationPrivate::KB_X11 | QGuiApplicationPrivate::KB_Win},
+ {QKeySequence::DeleteEndOfWord, 0, Qt::CTRL | Qt::Key_Delete, QGuiApplicationPrivate::KB_X11 | QGuiApplicationPrivate::KB_Win},
+ {QKeySequence::MoveToStartOfDocument, 0, Qt::CTRL | Qt::Key_Home, QGuiApplicationPrivate::KB_Win | QGuiApplicationPrivate::KB_X11 | QGuiApplicationPrivate::KB_S60},
+ {QKeySequence::MoveToEndOfDocument, 0, Qt::CTRL | Qt::Key_End, QGuiApplicationPrivate::KB_Win | QGuiApplicationPrivate::KB_X11 | QGuiApplicationPrivate::KB_S60},
+ {QKeySequence::Back, 0, Qt::CTRL | Qt::Key_Left, QGuiApplicationPrivate::KB_Mac},
+ {QKeySequence::MoveToPreviousWord, 0, Qt::CTRL | Qt::Key_Left, QGuiApplicationPrivate::KB_Win | QGuiApplicationPrivate::KB_X11 | QGuiApplicationPrivate::KB_S60},
+ {QKeySequence::MoveToStartOfLine, 0, Qt::CTRL | Qt::Key_Left, QGuiApplicationPrivate::KB_Mac },
+ {QKeySequence::MoveToStartOfDocument, 1, Qt::CTRL | Qt::Key_Up, QGuiApplicationPrivate::KB_Mac},
+ {QKeySequence::Forward, 0, Qt::CTRL | Qt::Key_Right, QGuiApplicationPrivate::KB_Mac},
+ {QKeySequence::MoveToEndOfLine, 0, Qt::CTRL | Qt::Key_Right, QGuiApplicationPrivate::KB_Mac },
+ {QKeySequence::MoveToNextWord, 0, Qt::CTRL | Qt::Key_Right, QGuiApplicationPrivate::KB_Win | QGuiApplicationPrivate::KB_X11 | QGuiApplicationPrivate::KB_S60},
+ {QKeySequence::MoveToEndOfDocument, 1, Qt::CTRL | Qt::Key_Down, QGuiApplicationPrivate::KB_Mac},
+ {QKeySequence::Close, 1, Qt::CTRL | Qt::Key_F4, QGuiApplicationPrivate::KB_Win},
+ {QKeySequence::Close, 0, Qt::CTRL | Qt::Key_F4, QGuiApplicationPrivate::KB_Mac},
+ {QKeySequence::NextChild, 0, Qt::CTRL | Qt::Key_F6, QGuiApplicationPrivate::KB_Win},
+ {QKeySequence::FindPrevious, 1, Qt::CTRL | Qt::SHIFT | Qt::Key_G, QGuiApplicationPrivate::KB_Gnome | QGuiApplicationPrivate::KB_Mac},
+ {QKeySequence::FindPrevious, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_G, QGuiApplicationPrivate::KB_Win},
+ {QKeySequence::AddTab, 1, Qt::CTRL | Qt::SHIFT | Qt::Key_N, QGuiApplicationPrivate::KB_KDE},
+ {QKeySequence::SaveAs, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_S, QGuiApplicationPrivate::KB_Gnome | QGuiApplicationPrivate::KB_Mac},
+ {QKeySequence::Redo, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Z, QGuiApplicationPrivate::KB_Win | QGuiApplicationPrivate::KB_X11 | QGuiApplicationPrivate::KB_S60},
+ {QKeySequence::Redo, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Z, QGuiApplicationPrivate::KB_Mac},
+ {QKeySequence::PreviousChild, 1, Qt::CTRL | Qt::SHIFT | Qt::Key_Backtab, QGuiApplicationPrivate::KB_Win | QGuiApplicationPrivate::KB_X11},
+ {QKeySequence::PreviousChild, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Backtab, QGuiApplicationPrivate::KB_Mac },//different priority from above
+ {QKeySequence::Paste, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Insert, QGuiApplicationPrivate::KB_X11},
+ {QKeySequence::SelectStartOfDocument, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Home, QGuiApplicationPrivate::KB_Win | QGuiApplicationPrivate::KB_X11 | QGuiApplicationPrivate::KB_S60},
+ {QKeySequence::SelectEndOfDocument, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_End, QGuiApplicationPrivate::KB_Win | QGuiApplicationPrivate::KB_X11 | QGuiApplicationPrivate::KB_S60},
+ {QKeySequence::SelectPreviousWord, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Left, QGuiApplicationPrivate::KB_Win | QGuiApplicationPrivate::KB_X11 | QGuiApplicationPrivate::KB_S60},
+ {QKeySequence::SelectStartOfLine, 1, Qt::CTRL | Qt::SHIFT | Qt::Key_Left, QGuiApplicationPrivate::KB_Mac },
+ {QKeySequence::SelectStartOfDocument, 1, Qt::CTRL | Qt::SHIFT | Qt::Key_Up, QGuiApplicationPrivate::KB_Mac},
+ {QKeySequence::SelectNextWord, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Right, QGuiApplicationPrivate::KB_Win | QGuiApplicationPrivate::KB_X11 | QGuiApplicationPrivate::KB_S60},
+ {QKeySequence::SelectEndOfLine, 1, Qt::CTRL | Qt::SHIFT | Qt::Key_Right, QGuiApplicationPrivate::KB_Mac },
+ {QKeySequence::SelectEndOfDocument, 1, Qt::CTRL | Qt::SHIFT | Qt::Key_Down, QGuiApplicationPrivate::KB_Mac},
+ {QKeySequence::PreviousChild, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_F6, QGuiApplicationPrivate::KB_Win},
+ {QKeySequence::Undo, 0, Qt::ALT | Qt::Key_Backspace, QGuiApplicationPrivate::KB_Win},
+ {QKeySequence::DeleteStartOfWord, 0, Qt::ALT | Qt::Key_Backspace, QGuiApplicationPrivate::KB_Mac},
+ {QKeySequence::DeleteEndOfWord, 0, Qt::ALT | Qt::Key_Delete, QGuiApplicationPrivate::KB_Mac},
+ {QKeySequence::Back, 1, Qt::ALT | Qt::Key_Left, QGuiApplicationPrivate::KB_Win | QGuiApplicationPrivate::KB_X11},
+ {QKeySequence::MoveToPreviousWord, 0, Qt::ALT | Qt::Key_Left, QGuiApplicationPrivate::KB_Mac},
+ {QKeySequence::MoveToStartOfBlock, 0, Qt::ALT | Qt::Key_Up, QGuiApplicationPrivate::KB_Mac}, //mac only
+ {QKeySequence::MoveToNextWord, 0, Qt::ALT | Qt::Key_Right, QGuiApplicationPrivate::KB_Mac},
+ {QKeySequence::Forward, 1, Qt::ALT | Qt::Key_Right, QGuiApplicationPrivate::KB_Win | QGuiApplicationPrivate::KB_X11},
+ {QKeySequence::MoveToEndOfBlock, 0, Qt::ALT | Qt::Key_Down, QGuiApplicationPrivate::KB_Mac}, //mac only
+ {QKeySequence::MoveToPreviousPage, 0, Qt::ALT | Qt::Key_PageUp, QGuiApplicationPrivate::KB_Mac },
+ {QKeySequence::MoveToNextPage, 0, Qt::ALT | Qt::Key_PageDown, QGuiApplicationPrivate::KB_Mac },
+ {QKeySequence::Redo, 0, Qt::ALT | Qt::SHIFT | Qt::Key_Backspace,QGuiApplicationPrivate::KB_Win},
+ {QKeySequence::SelectPreviousWord, 0, Qt::ALT | Qt::SHIFT | Qt::Key_Left, QGuiApplicationPrivate::KB_Mac},
+ {QKeySequence::SelectStartOfBlock, 0, Qt::ALT | Qt::SHIFT | Qt::Key_Up, QGuiApplicationPrivate::KB_Mac}, //mac only
+ {QKeySequence::SelectNextWord, 0, Qt::ALT | Qt::SHIFT | Qt::Key_Right, QGuiApplicationPrivate::KB_Mac},
+ {QKeySequence::SelectEndOfBlock, 0, Qt::ALT | Qt::SHIFT | Qt::Key_Down, QGuiApplicationPrivate::KB_Mac}, //mac only
+ {QKeySequence::MoveToStartOfBlock, 0, Qt::META | Qt::Key_A, QGuiApplicationPrivate::KB_Mac},
+ {QKeySequence::Delete, 0, Qt::META | Qt::Key_D, QGuiApplicationPrivate::KB_Mac},
+ {QKeySequence::MoveToEndOfBlock, 0, Qt::META | Qt::Key_E, QGuiApplicationPrivate::KB_Mac},
+ {QKeySequence::InsertLineSeparator, 0, Qt::META | Qt::Key_Return, QGuiApplicationPrivate::KB_Mac},
+ {QKeySequence::InsertLineSeparator, 0, Qt::META | Qt::Key_Enter, QGuiApplicationPrivate::KB_Mac},
+ {QKeySequence::MoveToStartOfLine, 0, Qt::META | Qt::Key_Left, QGuiApplicationPrivate::KB_Mac},
+ {QKeySequence::MoveToPreviousPage, 0, Qt::META | Qt::Key_Up, QGuiApplicationPrivate::KB_Mac},
+ {QKeySequence::MoveToEndOfLine, 0, Qt::META | Qt::Key_Right, QGuiApplicationPrivate::KB_Mac},
+ {QKeySequence::MoveToNextPage, 0, Qt::META | Qt::Key_Down, QGuiApplicationPrivate::KB_Mac},
+ {QKeySequence::MoveToPreviousPage, 0, Qt::META | Qt::Key_PageUp, QGuiApplicationPrivate::KB_Mac},
+ {QKeySequence::MoveToNextPage, 0, Qt::META | Qt::Key_PageDown, QGuiApplicationPrivate::KB_Mac},
+ {QKeySequence::SelectStartOfBlock, 0, Qt::META | Qt::SHIFT | Qt::Key_A, QGuiApplicationPrivate::KB_Mac},
+ {QKeySequence::SelectEndOfBlock, 0, Qt::META | Qt::SHIFT | Qt::Key_E, QGuiApplicationPrivate::KB_Mac},
+ {QKeySequence::SelectStartOfLine, 0, Qt::META | Qt::SHIFT | Qt::Key_Left, QGuiApplicationPrivate::KB_Mac},
+ {QKeySequence::SelectEndOfLine, 0, Qt::META | Qt::SHIFT | Qt::Key_Right, QGuiApplicationPrivate::KB_Mac}
};
const uint QKeySequencePrivate::numberOfKeyBindings = sizeof(QKeySequencePrivate::keyBindings)/(sizeof(QKeyBinding));
@@ -968,7 +967,7 @@ QKeySequence::QKeySequence(const QKeySequence& keysequence)
d->ref.ref();
}
-#ifdef Q_WS_MAC
+#ifdef Q_OS_MAC
static inline int maybeSwapShortcut(int shortcut)
{
if (qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)) {
@@ -994,13 +993,13 @@ static inline int maybeSwapShortcut(int shortcut)
*/
QList<QKeySequence> QKeySequence::keyBindings(StandardKey key)
{
- uint platform = QApplicationPrivate::currentPlatform();
+ uint platform = QGuiApplicationPrivate::currentKeyPlatform();
QList <QKeySequence> list;
for (uint i = 0; i < QKeySequencePrivate::numberOfKeyBindings ; ++i) {
QKeyBinding keyBinding = QKeySequencePrivate::keyBindings[i];
if (keyBinding.standardKey == key && (keyBinding.platform & platform)) {
uint shortcut =
-#ifdef Q_WS_MAC
+#ifdef Q_OS_MAC
maybeSwapShortcut(QKeySequencePrivate::keyBindings[i].shortcut);
#else
QKeySequencePrivate::keyBindings[i].shortcut;
@@ -1202,7 +1201,7 @@ int QKeySequencePrivate::decodeString(const QString &str, QKeySequence::Sequence
if (nativeText) {
gmodifs = globalModifs();
if (gmodifs->isEmpty()) {
-#ifdef Q_WS_MAC
+#ifdef Q_OS_MAC
const bool dontSwap = qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta);
if (dontSwap)
*gmodifs << QModifKeyName(Qt::META, QChar(kCommandUnicode));
@@ -1234,15 +1233,15 @@ int QKeySequencePrivate::decodeString(const QString &str, QKeySequence::Sequence
QList<QModifKeyName> modifs;
if (nativeText) {
- modifs << QModifKeyName(Qt::CTRL, QShortcut::tr("Ctrl").toLower().append(QLatin1Char('+')))
- << QModifKeyName(Qt::SHIFT, QShortcut::tr("Shift").toLower().append(QLatin1Char('+')))
- << QModifKeyName(Qt::ALT, QShortcut::tr("Alt").toLower().append(QLatin1Char('+')))
- << QModifKeyName(Qt::META, QShortcut::tr("Meta").toLower().append(QLatin1Char('+')));
+ modifs << QModifKeyName(Qt::CTRL, QCoreApplication::translate("QShortcut", "Ctrl").toLower().append(QLatin1Char('+')))
+ << QModifKeyName(Qt::SHIFT, QCoreApplication::translate("QShortcut", "Shift").toLower().append(QLatin1Char('+')))
+ << QModifKeyName(Qt::ALT, QCoreApplication::translate("QShortcut", "Alt").toLower().append(QLatin1Char('+')))
+ << QModifKeyName(Qt::META, QCoreApplication::translate("QShortcut", "Meta").toLower().append(QLatin1Char('+')));
}
modifs += *gmodifs; // Test non-translated ones last
QString sl = accel;
-#ifdef Q_WS_MAC
+#ifdef Q_OS_MAC
for (int i = 0; i < modifs.size(); ++i) {
const QModifKeyName &mkf = modifs.at(i);
if (sl.contains(mkf.name)) {
@@ -1278,7 +1277,7 @@ int QKeySequencePrivate::decodeString(const QString &str, QKeySequence::Sequence
int fnum = 0;
if (accel.length() == 1) {
-#ifdef Q_WS_MAC
+#ifdef Q_OS_MAC
int qtKey = qtkeyForMacSymbol(accel[0]);
if (qtKey != -1) {
ret |= qtKey;
@@ -1299,7 +1298,7 @@ int QKeySequencePrivate::decodeString(const QString &str, QKeySequence::Sequence
++tran;
for (int i = 0; keyname[i].name; ++i) {
QString keyName(tran == 0
- ? QShortcut::tr(keyname[i].name)
+ ? QCoreApplication::translate("QShortcut", keyname[i].name)
: QString::fromLatin1(keyname[i].name));
if (accel == keyName.toLower()) {
ret |= keyname[i].key;
@@ -1327,7 +1326,7 @@ QString QKeySequence::encodeString(int key)
static inline void addKey(QString &str, const QString &theKey, QKeySequence::SequenceFormat format)
{
if (!str.isEmpty())
- str += (format == QKeySequence::NativeText) ? QShortcut::tr("+")
+ str += (format == QKeySequence::NativeText) ? QCoreApplication::translate("QShortcut", "+")
: QString::fromLatin1("+");
str += theKey;
}
@@ -1336,7 +1335,7 @@ QString QKeySequencePrivate::encodeString(int key, QKeySequence::SequenceFormat
{
bool nativeText = (format == QKeySequence::NativeText);
QString s;
-#if defined(Q_WS_MAC)
+#if defined(Q_OS_MAC)
if (nativeText) {
// On Mac OS X the order (by default) is Meta, Alt, Shift, Control.
// If the AA_MacDontSwapCtrlAndMeta is enabled, then the order
@@ -1367,13 +1366,13 @@ QString QKeySequencePrivate::encodeString(int key, QKeySequence::SequenceFormat
{
// On other systems the order is Meta, Control, Alt, Shift
if ((key & Qt::META) == Qt::META)
- s = nativeText ? QShortcut::tr("Meta") : QString::fromLatin1("Meta");
+ s = nativeText ? QCoreApplication::translate("QShortcut", "Meta") : QString::fromLatin1("Meta");
if ((key & Qt::CTRL) == Qt::CTRL)
- addKey(s, nativeText ? QShortcut::tr("Ctrl") : QString::fromLatin1("Ctrl"), format);
+ addKey(s, nativeText ? QCoreApplication::translate("QShortcut", "Ctrl") : QString::fromLatin1("Ctrl"), format);
if ((key & Qt::ALT) == Qt::ALT)
- addKey(s, nativeText ? QShortcut::tr("Alt") : QString::fromLatin1("Alt"), format);
+ addKey(s, nativeText ? QCoreApplication::translate("QShortcut", "Alt") : QString::fromLatin1("Alt"), format);
if ((key & Qt::SHIFT) == Qt::SHIFT)
- addKey(s, nativeText ? QShortcut::tr("Shift") : QString::fromLatin1("Shift"), format);
+ addKey(s, nativeText ? QCoreApplication::translate("QShortcut", "Shift") : QString::fromLatin1("Shift"), format);
}
@@ -1388,11 +1387,11 @@ QString QKeySequencePrivate::encodeString(int key, QKeySequence::SequenceFormat
p += QChar(QChar::lowSurrogate(key));
}
} else if (key >= Qt::Key_F1 && key <= Qt::Key_F35) {
- p = nativeText ? QShortcut::tr("F%1").arg(key - Qt::Key_F1 + 1)
+ p = nativeText ? QCoreApplication::translate("QShortcut", "F%1").arg(key - Qt::Key_F1 + 1)
: QString::fromLatin1("F%1").arg(key - Qt::Key_F1 + 1);
} else if (key) {
int i=0;
-#if defined(Q_WS_MAC)
+#if defined(Q_OS_MAC)
if (nativeText) {
QChar ch = qt_macSymbolForQtKey(key);
if (!ch.isNull())
@@ -1402,12 +1401,12 @@ QString QKeySequencePrivate::encodeString(int key, QKeySequence::SequenceFormat
} else
#endif
{
-#ifdef Q_WS_MAC
+#ifdef Q_OS_MAC
NonSymbol:
#endif
while (keyname[i].name) {
if (key == keyname[i].key) {
- p = nativeText ? QShortcut::tr(keyname[i].name)
+ p = nativeText ? QCoreApplication::translate("QShortcut", keyname[i].name)
: QString::fromLatin1(keyname[i].name);
break;
}
@@ -1428,7 +1427,7 @@ NonSymbol:
}
}
-#ifdef Q_WS_MAC
+#ifdef Q_OS_MAC
if (nativeText)
s += p;
else
diff --git a/src/gui/kernel/qkeysequence.h b/src/gui/kernel/qkeysequence.h
index 22bdfc404d..31cec17fb1 100644
--- a/src/gui/kernel/qkeysequence.h
+++ b/src/gui/kernel/qkeysequence.h
@@ -161,9 +161,6 @@ public:
NoMatch,
PartialMatch,
ExactMatch
-#ifdef QT3_SUPPORT
- , Identical = ExactMatch
-#endif
};
QString toString(SequenceFormat format = PortableText) const;
diff --git a/src/gui/kernel/qlayout.h b/src/gui/kernel/qlayout.h
deleted file mode 100644
index 1a98606d35..0000000000
--- a/src/gui/kernel/qlayout.h
+++ /dev/null
@@ -1,245 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QLAYOUT_H
-#define QLAYOUT_H
-
-#include <QtCore/qobject.h>
-#include <QtGui/qlayoutitem.h>
-#include <QtGui/qsizepolicy.h>
-#include <QtCore/qrect.h>
-#include <QtCore/qmargins.h>
-
-#include <limits.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QLayout;
-class QSize;
-
-#ifdef QT3_SUPPORT
-class Q_GUI_EXPORT QLayoutIterator
-{
-public:
- inline QT3_SUPPORT_CONSTRUCTOR QLayoutIterator(QLayout *i) : layout(i), index(0) {}
- inline QLayoutIterator(const QLayoutIterator &i)
- : layout(i.layout), index(i.index) {}
- inline QLayoutIterator &operator=(const QLayoutIterator &i) {
- layout = i.layout;
- index = i.index;
- return *this;
- }
- inline QT3_SUPPORT QLayoutItem *operator++();
- inline QT3_SUPPORT QLayoutItem *current();
- inline QT3_SUPPORT QLayoutItem *takeCurrent();
- inline QT3_SUPPORT void deleteCurrent();
-
-private:
- // hack to avoid deprecated warning
- friend class QLayout;
- inline QLayoutIterator(QLayout *i, bool) : layout(i), index(0) {}
- QLayout *layout;
- int index;
-};
-#endif
-
-class QLayoutPrivate;
-
-class Q_GUI_EXPORT QLayout : public QObject, public QLayoutItem
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QLayout)
-
- Q_ENUMS(SizeConstraint)
- Q_PROPERTY(int margin READ margin WRITE setMargin)
- Q_PROPERTY(int spacing READ spacing WRITE setSpacing)
- Q_PROPERTY(SizeConstraint sizeConstraint READ sizeConstraint WRITE setSizeConstraint)
-public:
- enum SizeConstraint {
- SetDefaultConstraint,
- SetNoConstraint,
- SetMinimumSize,
- SetFixedSize,
- SetMaximumSize,
- SetMinAndMaxSize
-#if defined(QT3_SUPPORT) && !defined(Q_MOC_RUN)
- , Auto = SetDefaultConstraint,
- FreeResize = SetNoConstraint,
- Minimum = SetMinimumSize,
- Fixed = SetFixedSize
-#endif
- };
-
- QLayout(QWidget *parent);
- QLayout();
- ~QLayout();
-
- int margin() const;
- int spacing() const;
-
- void setMargin(int);
- void setSpacing(int);
-
- void setContentsMargins(int left, int top, int right, int bottom);
- void setContentsMargins(const QMargins &margins);
- void getContentsMargins(int *left, int *top, int *right, int *bottom) const;
- QMargins contentsMargins() const;
- QRect contentsRect() const;
-
- bool setAlignment(QWidget *w, Qt::Alignment alignment);
- bool setAlignment(QLayout *l, Qt::Alignment alignment);
-#ifdef Q_NO_USING_KEYWORD
- inline void setAlignment(Qt::Alignment alignment) { QLayoutItem::setAlignment(alignment); }
-#else
- using QLayoutItem::setAlignment;
-#endif
-
- void setSizeConstraint(SizeConstraint);
- SizeConstraint sizeConstraint() const;
-#ifdef QT3_SUPPORT
- inline QT3_SUPPORT void setResizeMode(SizeConstraint s) {setSizeConstraint(s);}
- inline QT3_SUPPORT SizeConstraint resizeMode() const {return sizeConstraint();}
-#endif
- void setMenuBar(QWidget *w);
- QWidget *menuBar() const;
-
- QWidget *parentWidget() const;
-
- void invalidate();
- QRect geometry() const;
- bool activate();
- void update();
-
- void addWidget(QWidget *w);
- virtual void addItem(QLayoutItem *) = 0;
-
- void removeWidget(QWidget *w);
- void removeItem(QLayoutItem *);
-
- Qt::Orientations expandingDirections() const;
- QSize minimumSize() const;
- QSize maximumSize() const;
- virtual void setGeometry(const QRect&);
- virtual QLayoutItem *itemAt(int index) const = 0;
- virtual QLayoutItem *takeAt(int index) = 0;
- virtual int indexOf(QWidget *) const;
- virtual int count() const = 0;
- bool isEmpty() const;
-
- int totalHeightForWidth(int w) const;
- QSize totalMinimumSize() const;
- QSize totalMaximumSize() const;
- QSize totalSizeHint() const;
- QLayout *layout();
-
- void setEnabled(bool);
- bool isEnabled() const;
-
-#ifdef QT3_SUPPORT
- QT3_SUPPORT void freeze(int w=0, int h=0);
- QT3_SUPPORT bool isTopLevel() const;
-#endif
-
- static QSize closestAcceptableSize(const QWidget *w, const QSize &s);
-
-protected:
- void widgetEvent(QEvent *);
- void childEvent(QChildEvent *e);
- void addChildLayout(QLayout *l);
- void addChildWidget(QWidget *w);
-#ifdef QT3_SUPPORT
- QT3_SUPPORT void deleteAllItems();
-#endif
-
- QRect alignmentRect(const QRect&) const;
-protected:
- QLayout(QLayoutPrivate &d, QLayout*, QWidget*);
-
-private:
- Q_DISABLE_COPY(QLayout)
-
- static void activateRecursiveHelper(QLayoutItem *item);
-
- friend class QApplicationPrivate;
- friend class QWidget;
-
-#ifdef QT3_SUPPORT
-public:
- QT3_SUPPORT_CONSTRUCTOR QLayout(QWidget *parent, int margin, int spacing = -1,
- const char *name = 0);
- QT3_SUPPORT_CONSTRUCTOR QLayout(QLayout *parentLayout, int spacing = -1, const char *name = 0);
- QT3_SUPPORT_CONSTRUCTOR QLayout(int spacing, const char *name = 0);
- inline QT3_SUPPORT QWidget *mainWidget() const { return parentWidget(); }
- inline QT3_SUPPORT void remove(QWidget *w) { removeWidget(w); }
- inline QT3_SUPPORT void add(QWidget *w) { addWidget(w); }
-
- QT3_SUPPORT void setAutoAdd(bool a);
- QT3_SUPPORT bool autoAdd() const;
- inline QT3_SUPPORT QLayoutIterator iterator() { return QLayoutIterator(this,true); }
-
- inline QT3_SUPPORT int defaultBorder() const { return spacing(); }
-#endif
-};
-
-#ifdef QT3_SUPPORT
-inline QLayoutItem *QLayoutIterator::operator++() { return layout->itemAt(++index); }
-inline QLayoutItem *QLayoutIterator::current() { return layout->itemAt(index); }
-inline QLayoutItem *QLayoutIterator::takeCurrent() { return layout->takeAt(index); }
-inline void QLayoutIterator::deleteCurrent() { delete layout->takeAt(index); }
-#endif
-
-//### support old includes
-#if 1 //def QT3_SUPPORT
-QT_BEGIN_INCLUDE_NAMESPACE
-#include <QtGui/qboxlayout.h>
-#include <QtGui/qgridlayout.h>
-QT_END_INCLUDE_NAMESPACE
-#endif
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QLAYOUT_H
diff --git a/src/gui/kernel/qlayout_p.h b/src/gui/kernel/qlayout_p.h
deleted file mode 100644
index 9e8d9cd355..0000000000
--- a/src/gui/kernel/qlayout_p.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QLAYOUT_P_H
-#define QLAYOUT_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of qlayout*.cpp, and qabstractlayout.cpp. This header
-// file may change from version to version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "private/qobject_p.h"
-#include "qstyle.h"
-#include "qsizepolicy.h"
-
-QT_BEGIN_NAMESPACE
-
-class QWidgetItem;
-class QSpacerItem;
-
-class Q_GUI_EXPORT QLayoutPrivate : public QObjectPrivate
-{
- Q_DECLARE_PUBLIC(QLayout)
-
-public:
- typedef QWidgetItem * (*QWidgetItemFactoryMethod)(const QLayout *layout, QWidget *widget);
- typedef QSpacerItem * (*QSpacerItemFactoryMethod)(const QLayout *layout, int w, int h, QSizePolicy::Policy hPolicy, QSizePolicy::Policy);
-
- QLayoutPrivate();
-
- void getMargin(int *result, int userMargin, QStyle::PixelMetric pm) const;
- void doResize(const QSize &);
- void reparentChildWidgets(QWidget *mw);
-
- static QWidgetItem *createWidgetItem(const QLayout *layout, QWidget *widget);
- static QSpacerItem *createSpacerItem(const QLayout *layout, int w, int h, QSizePolicy::Policy hPolicy = QSizePolicy::Minimum, QSizePolicy::Policy vPolicy = QSizePolicy::Minimum);
-
- static QWidgetItemFactoryMethod widgetItemFactoryMethod;
- static QSpacerItemFactoryMethod spacerItemFactoryMethod;
-
- int insideSpacing;
- int userLeftMargin;
- int userTopMargin;
- int userRightMargin;
- int userBottomMargin;
- uint topLevel : 1;
- uint enabled : 1;
- uint activated : 1;
- uint autoNewChild : 1;
- QLayout::SizeConstraint constraint;
- QRect rect;
- QWidget *menubar;
-};
-
-QT_END_NAMESPACE
-
-#endif // QLAYOUT_P_H
diff --git a/src/gui/kernel/qlayoutengine.cpp b/src/gui/kernel/qlayoutengine.cpp
deleted file mode 100644
index a93661737d..0000000000
--- a/src/gui/kernel/qlayoutengine.cpp
+++ /dev/null
@@ -1,436 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qlayout.h"
-#include "private/qlayoutengine_p.h"
-
-#include "qvector.h"
-#include "qwidget.h"
-
-#include <qlist.h>
-#include <qalgorithms.h>
-
-#include <qdebug.h>
-
-QT_BEGIN_NAMESPACE
-
-//#define QLAYOUT_EXTRA_DEBUG
-
-typedef qint64 Fixed64;
-static inline Fixed64 toFixed(int i) { return (Fixed64)i * 256; }
-static inline int fRound(Fixed64 i) {
- return (i % 256 < 128) ? i / 256 : 1 + i / 256;
-}
-
-/*
- This is the main workhorse of the QGridLayout. It portions out
- available space to the chain's children.
-
- The calculation is done in fixed point: "fixed" variables are
- scaled by a factor of 256.
-
- If the layout runs "backwards" (i.e. RightToLeft or Up) the layout
- is computed mirror-reversed, and it's the caller's responsibility
- do reverse the values before use.
-
- chain contains input and output parameters describing the geometry.
- count is the count of items in the chain; pos and space give the
- interval (relative to parentWidget topLeft).
-*/
-void qGeomCalc(QVector<QLayoutStruct> &chain, int start, int count,
- int pos, int space, int spacer)
-{
- int cHint = 0;
- int cMin = 0;
- int cMax = 0;
- int sumStretch = 0;
- int sumSpacing = 0;
-
- bool wannaGrow = false; // anyone who really wants to grow?
- // bool canShrink = false; // anyone who could be persuaded to shrink?
-
- bool allEmptyNonstretch = true;
- int pendingSpacing = -1;
- int spacerCount = 0;
- int i;
-
- for (i = start; i < start + count; i++) {
- QLayoutStruct *data = &chain[i];
-
- data->done = false;
- cHint += data->smartSizeHint();
- cMin += data->minimumSize;
- cMax += data->maximumSize;
- sumStretch += data->stretch;
- if (!data->empty) {
- /*
- Using pendingSpacing, we ensure that the spacing for the last
- (non-empty) item is ignored.
- */
- if (pendingSpacing >= 0) {
- sumSpacing += pendingSpacing;
- ++spacerCount;
- }
- pendingSpacing = data->effectiveSpacer(spacer);
- }
- wannaGrow = wannaGrow || data->expansive || data->stretch > 0;
- allEmptyNonstretch = allEmptyNonstretch && !wannaGrow && data->empty;
- }
-
- int extraspace = 0;
-
- if (space < cMin + sumSpacing) {
- /*
- Less space than minimumSize; take from the biggest first
- */
-
- int minSize = cMin + sumSpacing;
-
- // shrink the spacers proportionally
- if (spacer >= 0) {
- spacer = minSize > 0 ? spacer * space / minSize : 0;
- sumSpacing = spacer * spacerCount;
- }
-
- QList<int> list;
-
- for (i = start; i < start + count; i++)
- list << chain.at(i).minimumSize;
-
- qSort(list);
-
- int space_left = space - sumSpacing;
-
- int sum = 0;
- int idx = 0;
- int space_used=0;
- int current = 0;
- while (idx < count && space_used < space_left) {
- current = list.at(idx);
- space_used = sum + current * (count - idx);
- sum += current;
- ++idx;
- }
- --idx;
- int deficit = space_used - space_left;
-
- int items = count - idx;
- /*
- * If we truncate all items to "current", we would get "deficit" too many pixels. Therefore, we have to remove
- * deficit/items from each item bigger than maxval. The actual value to remove is deficitPerItem + remainder/items
- * "rest" is the accumulated error from using integer arithmetic.
- */
- int deficitPerItem = deficit/items;
- int remainder = deficit % items;
- int maxval = current - deficitPerItem;
-
- int rest = 0;
- for (i = start; i < start + count; i++) {
- int maxv = maxval;
- rest += remainder;
- if (rest >= items) {
- maxv--;
- rest-=items;
- }
- QLayoutStruct *data = &chain[i];
- data->size = qMin(data->minimumSize, maxv);
- data->done = true;
- }
- } else if (space < cHint + sumSpacing) {
- /*
- Less space than smartSizeHint(), but more than minimumSize.
- Currently take space equally from each, as in Qt 2.x.
- Commented-out lines will give more space to stretchier
- items.
- */
- int n = count;
- int space_left = space - sumSpacing;
- int overdraft = cHint - space_left;
-
- // first give to the fixed ones:
- for (i = start; i < start + count; i++) {
- QLayoutStruct *data = &chain[i];
- if (!data->done
- && data->minimumSize >= data->smartSizeHint()) {
- data->size = data->smartSizeHint();
- data->done = true;
- space_left -= data->smartSizeHint();
- // sumStretch -= data->stretch;
- n--;
- }
- }
- bool finished = n == 0;
- while (!finished) {
- finished = true;
- Fixed64 fp_over = toFixed(overdraft);
- Fixed64 fp_w = 0;
-
- for (i = start; i < start+count; i++) {
- QLayoutStruct *data = &chain[i];
- if (data->done)
- continue;
- // if (sumStretch <= 0)
- fp_w += fp_over / n;
- // else
- // fp_w += (fp_over * data->stretch) / sumStretch;
- int w = fRound(fp_w);
- data->size = data->smartSizeHint() - w;
- fp_w -= toFixed(w); // give the difference to the next
- if (data->size < data->minimumSize) {
- data->done = true;
- data->size = data->minimumSize;
- finished = false;
- overdraft -= data->smartSizeHint() - data->minimumSize;
- // sumStretch -= data->stretch;
- n--;
- break;
- }
- }
- }
- } else { // extra space
- int n = count;
- int space_left = space - sumSpacing;
- // first give to the fixed ones, and handle non-expansiveness
- for (i = start; i < start + count; i++) {
- QLayoutStruct *data = &chain[i];
- if (!data->done
- && (data->maximumSize <= data->smartSizeHint()
- || (wannaGrow && !data->expansive && data->stretch == 0)
- || (!allEmptyNonstretch && data->empty &&
- !data->expansive && data->stretch == 0))) {
- data->size = data->smartSizeHint();
- data->done = true;
- space_left -= data->size;
- sumStretch -= data->stretch;
- n--;
- }
- }
- extraspace = space_left;
-
- /*
- Do a trial distribution and calculate how much it is off.
- If there are more deficit pixels than surplus pixels, give
- the minimum size items what they need, and repeat.
- Otherwise give to the maximum size items, and repeat.
-
- Paul Olav Tvete has a wonderful mathematical proof of the
- correctness of this principle, but unfortunately this
- comment is too small to contain it.
- */
- int surplus, deficit;
- do {
- surplus = deficit = 0;
- Fixed64 fp_space = toFixed(space_left);
- Fixed64 fp_w = 0;
- for (i = start; i < start + count; i++) {
- QLayoutStruct *data = &chain[i];
- if (data->done)
- continue;
- extraspace = 0;
- if (sumStretch <= 0)
- fp_w += fp_space / n;
- else
- fp_w += (fp_space * data->stretch) / sumStretch;
- int w = fRound(fp_w);
- data->size = w;
- fp_w -= toFixed(w); // give the difference to the next
- if (w < data->smartSizeHint()) {
- deficit += data->smartSizeHint() - w;
- } else if (w > data->maximumSize) {
- surplus += w - data->maximumSize;
- }
- }
- if (deficit > 0 && surplus <= deficit) {
- // give to the ones that have too little
- for (i = start; i < start+count; i++) {
- QLayoutStruct *data = &chain[i];
- if (!data->done && data->size < data->smartSizeHint()) {
- data->size = data->smartSizeHint();
- data->done = true;
- space_left -= data->smartSizeHint();
- sumStretch -= data->stretch;
- n--;
- }
- }
- }
- if (surplus > 0 && surplus >= deficit) {
- // take from the ones that have too much
- for (i = start; i < start + count; i++) {
- QLayoutStruct *data = &chain[i];
- if (!data->done && data->size > data->maximumSize) {
- data->size = data->maximumSize;
- data->done = true;
- space_left -= data->maximumSize;
- sumStretch -= data->stretch;
- n--;
- }
- }
- }
- } while (n > 0 && surplus != deficit);
- if (n == 0)
- extraspace = space_left;
- }
-
- /*
- As a last resort, we distribute the unwanted space equally
- among the spacers (counting the start and end of the chain). We
- could, but don't, attempt a sub-pixel allocation of the extra
- space.
- */
- int extra = extraspace / (spacerCount + 2);
- int p = pos + extra;
- for (i = start; i < start+count; i++) {
- QLayoutStruct *data = &chain[i];
- data->pos = p;
- p += data->size;
- if (!data->empty)
- p += data->effectiveSpacer(spacer) + extra;
- }
-
-#ifdef QLAYOUT_EXTRA_DEBUG
- qDebug() << "qGeomCalc" << "start" << start << "count" << count << "pos" << pos
- << "space" << space << "spacer" << spacer;
- for (i = start; i < start + count; ++i) {
- qDebug() << i << ':' << chain[i].minimumSize << chain[i].smartSizeHint()
- << chain[i].maximumSize << "stretch" << chain[i].stretch
- << "empty" << chain[i].empty << "expansive" << chain[i].expansive
- << "spacing" << chain[i].spacing;
- qDebug() << "result pos" << chain[i].pos << "size" << chain[i].size;
- }
-#endif
-}
-
-Q_GUI_EXPORT QSize qSmartMinSize(const QSize &sizeHint, const QSize &minSizeHint,
- const QSize &minSize, const QSize &maxSize,
- const QSizePolicy &sizePolicy)
-{
- QSize s(0, 0);
-
- if (sizePolicy.horizontalPolicy() != QSizePolicy::Ignored) {
- if (sizePolicy.horizontalPolicy() & QSizePolicy::ShrinkFlag)
- s.setWidth(minSizeHint.width());
- else
- s.setWidth(qMax(sizeHint.width(), minSizeHint.width()));
- }
-
- if (sizePolicy.verticalPolicy() != QSizePolicy::Ignored) {
- if (sizePolicy.verticalPolicy() & QSizePolicy::ShrinkFlag) {
- s.setHeight(minSizeHint.height());
- } else {
- s.setHeight(qMax(sizeHint.height(), minSizeHint.height()));
- }
- }
-
- s = s.boundedTo(maxSize);
- if (minSize.width() > 0)
- s.setWidth(minSize.width());
- if (minSize.height() > 0)
- s.setHeight(minSize.height());
-
- return s.expandedTo(QSize(0,0));
-}
-
-Q_GUI_EXPORT QSize qSmartMinSize(const QWidgetItem *i)
-{
- QWidget *w = ((QWidgetItem *)i)->widget();
- return qSmartMinSize(w->sizeHint(), w->minimumSizeHint(),
- w->minimumSize(), w->maximumSize(),
- w->sizePolicy());
-}
-
-Q_GUI_EXPORT QSize qSmartMinSize(const QWidget *w)
-{
- return qSmartMinSize(w->sizeHint(), w->minimumSizeHint(),
- w->minimumSize(), w->maximumSize(),
- w->sizePolicy());
-}
-
-Q_GUI_EXPORT QSize qSmartMaxSize(const QSize &sizeHint,
- const QSize &minSize, const QSize &maxSize,
- const QSizePolicy &sizePolicy, Qt::Alignment align)
-{
- if (align & Qt::AlignHorizontal_Mask && align & Qt::AlignVertical_Mask)
- return QSize(QLAYOUTSIZE_MAX, QLAYOUTSIZE_MAX);
- QSize s = maxSize;
- QSize hint = sizeHint.expandedTo(minSize);
- if (s.width() == QWIDGETSIZE_MAX && !(align & Qt::AlignHorizontal_Mask))
- if (!(sizePolicy.horizontalPolicy() & QSizePolicy::GrowFlag))
- s.setWidth(hint.width());
-
- if (s.height() == QWIDGETSIZE_MAX && !(align & Qt::AlignVertical_Mask))
- if (!(sizePolicy.verticalPolicy() & QSizePolicy::GrowFlag))
- s.setHeight(hint.height());
-
- if (align & Qt::AlignHorizontal_Mask)
- s.setWidth(QLAYOUTSIZE_MAX);
- if (align & Qt::AlignVertical_Mask)
- s.setHeight(QLAYOUTSIZE_MAX);
- return s;
-}
-
-Q_GUI_EXPORT QSize qSmartMaxSize(const QWidgetItem *i, Qt::Alignment align)
-{
- QWidget *w = ((QWidgetItem*)i)->widget();
-
- return qSmartMaxSize(w->sizeHint().expandedTo(w->minimumSizeHint()), w->minimumSize(), w->maximumSize(),
- w->sizePolicy(), align);
-}
-
-Q_GUI_EXPORT QSize qSmartMaxSize(const QWidget *w, Qt::Alignment align)
-{
- return qSmartMaxSize(w->sizeHint().expandedTo(w->minimumSizeHint()), w->minimumSize(), w->maximumSize(),
- w->sizePolicy(), align);
-}
-
-Q_GUI_EXPORT int qSmartSpacing(const QLayout *layout, QStyle::PixelMetric pm)
-{
- QObject *parent = layout->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();
- }
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/kernel/qlayoutengine_p.h b/src/gui/kernel/qlayoutengine_p.h
deleted file mode 100644
index 8a2ea110e9..0000000000
--- a/src/gui/kernel/qlayoutengine_p.h
+++ /dev/null
@@ -1,140 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QLAYOUTENGINE_P_H
-#define QLAYOUTENGINE_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "QtGui/qlayoutitem.h"
-#include "QtGui/qstyle.h"
-
-QT_BEGIN_NAMESPACE
-
-template <typename T> class QVector;
-
-struct QLayoutStruct
-{
- inline void init(int stretchFactor = 0, int minSize = 0) {
- stretch = stretchFactor;
- minimumSize = sizeHint = minSize;
- maximumSize = QLAYOUTSIZE_MAX;
- expansive = false;
- empty = true;
- spacing = 0;
- }
-
- int smartSizeHint() {
- return (stretch > 0) ? minimumSize : sizeHint;
- }
- int effectiveSpacer(int uniformSpacer) const {
- Q_ASSERT(uniformSpacer >= 0 || spacing >= 0);
- return (uniformSpacer >= 0) ? uniformSpacer : spacing;
- }
-
- // parameters
- int stretch;
- int sizeHint;
- int maximumSize;
- int minimumSize;
- bool expansive;
- bool empty;
- int spacing;
-
- // temporary storage
- bool done;
-
- // result
- int pos;
- int size;
-};
-
-
-Q_GUI_EXPORT void qGeomCalc(QVector<QLayoutStruct> &chain, int start, int count,
- int pos, int space, int spacer = -1);
-Q_GUI_EXPORT QSize qSmartMinSize(const QSize &sizeHint, const QSize &minSizeHint,
- const QSize &minSize, const QSize &maxSize,
- const QSizePolicy &sizePolicy);
-Q_GUI_EXPORT QSize qSmartMinSize(const QWidgetItem *i);
-Q_GUI_EXPORT QSize qSmartMinSize(const QWidget *w);
-Q_GUI_EXPORT QSize qSmartMaxSize(const QSize &sizeHint,
- const QSize &minSize, const QSize &maxSize,
- const QSizePolicy &sizePolicy, Qt::Alignment align = 0);
-Q_GUI_EXPORT QSize qSmartMaxSize(const QWidgetItem *i, Qt::Alignment align = 0);
-Q_GUI_EXPORT QSize qSmartMaxSize(const QWidget *w, Qt::Alignment align = 0);
-
-Q_GUI_EXPORT int qSmartSpacing(const QLayout *layout, QStyle::PixelMetric pm);
-
-/*
- Modify total maximum (max), total expansion (exp), and total empty
- when adding boxmax/boxexp.
-
- Expansive boxes win over non-expansive boxes.
- Non-empty boxes win over empty boxes.
-*/
-static inline void qMaxExpCalc(int & max, bool &exp, bool &empty,
- int boxmax, bool boxexp, bool boxempty)
-{
- if (exp) {
- if (boxexp)
- max = qMax(max, boxmax);
- } else {
- if (boxexp || (empty && (!boxempty || max == 0)))
- max = boxmax;
- else if (empty == boxempty)
- max = qMin(max, boxmax);
- }
- exp = exp || boxexp;
- empty = empty && boxempty;
-}
-
-QT_END_NAMESPACE
-
-#endif // QLAYOUTENGINE_P_H
diff --git a/src/gui/kernel/qlayoutitem.h b/src/gui/kernel/qlayoutitem.h
deleted file mode 100644
index eff87e5004..0000000000
--- a/src/gui/kernel/qlayoutitem.h
+++ /dev/null
@@ -1,182 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QLAYOUTITEM_H
-#define QLAYOUTITEM_H
-
-#include <QtGui/qsizepolicy.h>
-#include <QtCore/qrect.h>
-
-#include <limits.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-static const int QLAYOUTSIZE_MAX = INT_MAX/256/16;
-
-class QLayout;
-class QLayoutItem;
-class QSpacerItem;
-class QWidget;
-class QSize;
-
-class Q_GUI_EXPORT QLayoutItem
-{
-public:
- inline explicit QLayoutItem(Qt::Alignment alignment = 0);
- virtual ~QLayoutItem();
- virtual QSize sizeHint() const = 0;
- virtual QSize minimumSize() const = 0;
- virtual QSize maximumSize() const = 0;
- virtual Qt::Orientations expandingDirections() const = 0;
- virtual void setGeometry(const QRect&) = 0;
- virtual QRect geometry() const = 0;
- virtual bool isEmpty() const = 0;
- virtual bool hasHeightForWidth() const;
- virtual int heightForWidth(int) const;
- virtual int minimumHeightForWidth(int) const;
- virtual void invalidate();
-
- virtual QWidget *widget();
- virtual QLayout *layout();
- virtual QSpacerItem *spacerItem();
-
- Qt::Alignment alignment() const { return align; }
- void setAlignment(Qt::Alignment a);
- QSizePolicy::ControlTypes controlTypes() const;
-
-protected:
- Qt::Alignment align;
-};
-
-inline QLayoutItem::QLayoutItem(Qt::Alignment aalignment)
- : align(aalignment) { }
-
-class Q_GUI_EXPORT QSpacerItem : public QLayoutItem
-{
-public:
- QSpacerItem(int w, int h,
- QSizePolicy::Policy hData = QSizePolicy::Minimum,
- QSizePolicy::Policy vData = QSizePolicy::Minimum)
- : width(w), height(h), sizeP(hData, vData) { }
- void changeSize(int w, int h,
- QSizePolicy::Policy hData = QSizePolicy::Minimum,
- QSizePolicy::Policy vData = QSizePolicy::Minimum);
- QSize sizeHint() const;
- QSize minimumSize() const;
- QSize maximumSize() const;
- Qt::Orientations expandingDirections() const;
- bool isEmpty() const;
- void setGeometry(const QRect&);
- QRect geometry() const;
- QSpacerItem *spacerItem();
-
-private:
- int width;
- int height;
- QSizePolicy sizeP;
- QRect rect;
-};
-
-class Q_GUI_EXPORT QWidgetItem : public QLayoutItem
-{
- Q_DISABLE_COPY(QWidgetItem)
-
-public:
- explicit QWidgetItem(QWidget *w) : wid(w) { }
- QSize sizeHint() const;
- QSize minimumSize() const;
- QSize maximumSize() const;
- Qt::Orientations expandingDirections() const;
- bool isEmpty() const;
- void setGeometry(const QRect&);
- QRect geometry() const;
- virtual QWidget *widget();
-
- bool hasHeightForWidth() const;
- int heightForWidth(int) const;
-
-protected:
- QWidget *wid;
-};
-
-class Q_GUI_EXPORT QWidgetItemV2 : public QWidgetItem
-{
-public:
- explicit QWidgetItemV2(QWidget *widget);
- ~QWidgetItemV2();
-
- QSize sizeHint() const;
- QSize minimumSize() const;
- QSize maximumSize() const;
- int heightForWidth(int width) const;
-
-private:
- enum { Dirty = -123, HfwCacheMaxSize = 3 };
-
- inline bool useSizeCache() const;
- void updateCacheIfNecessary() const;
- inline void invalidateSizeCache() {
- q_cachedMinimumSize.setWidth(Dirty);
- q_hfwCacheSize = 0;
- }
-
- mutable QSize q_cachedMinimumSize;
- mutable QSize q_cachedSizeHint;
- mutable QSize q_cachedMaximumSize;
- mutable QSize q_cachedHfws[HfwCacheMaxSize];
- mutable short q_firstCachedHfw;
- mutable short q_hfwCacheSize;
- void *d;
-
- friend class QWidgetPrivate;
-
- Q_DISABLE_COPY(QWidgetItemV2)
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QLAYOUTITEM_H
diff --git a/src/gui/kernel/qmacdefines_mac.h b/src/gui/kernel/qmacdefines_mac.h
deleted file mode 100644
index 02360873e4..0000000000
--- a/src/gui/kernel/qmacdefines_mac.h
+++ /dev/null
@@ -1,180 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/****************************************************************************
-**
-** Copyright (c) 2007-2008, Apple, Inc.
-**
-** All rights reserved.
-**
-** Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are met:
-**
-** * Redistributions of source code must retain the above copyright notice,
-** this list of conditions and the following disclaimer.
-**
-** * Redistributions in binary form must reproduce the above copyright notice,
-** this list of conditions and the following disclaimer in the documentation
-** and/or other materials provided with the distribution.
-**
-** * Neither the name of Apple, Inc. nor the names of its contributors
-** may be used to endorse or promote products derived from this software
-** without specific prior written permission.
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-**
-****************************************************************************/
-
-/*
- * qmacdefines_mac_p.h
- * All the defines you'll ever need for Qt/Mac :-)
- */
-
-/* This is just many defines. Therefore it doesn't need things like:
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-Yes, it is an informative comment ;-)
-*/
-
-#include <QtCore/qglobal.h>
-
-#ifdef qDebug
-# define old_qDebug qDebug
-# undef qDebug
-#endif
-
-#ifdef __LP64__
-typedef signed int OSStatus;
-#else
-typedef signed long OSStatus;
-#endif
-
-#ifdef __OBJC__
-# ifdef slots
-# define old_slots slots
-# undef slots
-# endif
-#include <Cocoa/Cocoa.h>
-# ifdef old_slots
-# undef slots
-# define slots
-# undef old_slots
-# endif
-#endif
-#ifdef QT_MAC_USE_COCOA
- typedef struct OpaqueEventHandlerCallRef * EventHandlerCallRef;
- typedef struct OpaqueEventRef * EventRef;
- typedef struct OpaqueMenuRef * MenuRef;
- typedef struct OpaquePasteboardRef* PasteboardRef;
- typedef struct OpaqueRgnHandle * RgnHandle;
- typedef const struct __HIShape *HIShapeRef;
- typedef struct __HIShape *HIMutableShapeRef;
- typedef struct CGRect CGRect;
- typedef struct CGImage *CGImageRef;
- typedef struct CGContext *CGContextRef;
- typedef struct GDevice * GDPtr;
- typedef GDPtr * GDHandle;
- typedef struct OpaqueIconRef * IconRef;
-# ifdef __OBJC__
- typedef NSWindow* OSWindowRef;
- typedef NSView *OSViewRef;
- typedef NSMenu *OSMenuRef;
- typedef NSEvent *OSEventRef;
-# else
- typedef void *OSWindowRef;
- typedef void *OSViewRef;
- typedef void *OSMenuRef;
- typedef void *OSEventRef;
-# endif
-#else // Carbon
- typedef struct OpaqueEventHandlerCallRef * EventHandlerCallRef;
- typedef struct OpaqueEventRef * EventRef;
- typedef struct OpaqueMenuRef * MenuRef;
- typedef struct OpaquePasteboardRef* PasteboardRef;
- typedef struct OpaqueRgnHandle * RgnHandle;
- typedef const struct __HIShape *HIShapeRef;
- typedef struct __HIShape *HIMutableShapeRef;
- typedef struct CGRect CGRect;
- typedef struct CGImage *CGImageRef;
- typedef struct CGContext *CGContextRef;
- typedef struct GDevice * GDPtr;
- typedef GDPtr * GDHandle;
- typedef struct OpaqueIconRef * IconRef;
- typedef struct OpaqueWindowPtr * WindowRef;
- typedef struct OpaqueControlRef * HIViewRef;
- typedef WindowRef OSWindowRef;
- typedef HIViewRef OSViewRef;
- typedef MenuRef OSMenuRef;
- typedef EventRef OSEventRef;
-#endif // QT_MAC_USE_COCOA
-
-typedef PasteboardRef OSPasteboardRef;
-typedef struct AEDesc AEDescList;
-typedef AEDescList AERecord;
-typedef AERecord AppleEvent;
-
-#ifdef check
-#undef check
-#endif
-
-#ifdef old_qDebug
-# undef qDebug
-# define qDebug QT_NO_QDEBUG_MACRO
-# undef old_qDebug
-#endif
diff --git a/src/gui/kernel/qmime_mac.cpp b/src/gui/kernel/qmime_mac.cpp
deleted file mode 100644
index a1df34eb1f..0000000000
--- a/src/gui/kernel/qmime_mac.cpp
+++ /dev/null
@@ -1,1310 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qmime.h"
-
-//#define USE_INTERNET_CONFIG
-
-#ifndef USE_INTERNET_CONFIG
-# include "qfile.h"
-# include "qfileinfo.h"
-# include "qtextstream.h"
-# include "qdir.h"
-# include <unistd.h>
-# include <sys/types.h>
-# include <sys/stat.h>
-# include <sys/fcntl.h>
-#endif
-
-#include "qdebug.h"
-#include "qpixmap.h"
-#include "qimagewriter.h"
-#include "qimagereader.h"
-#include "qdatastream.h"
-#include "qbuffer.h"
-#include "qdatetime.h"
-#include "qapplication_p.h"
-#include "qtextcodec.h"
-#include "qregexp.h"
-#include "qurl.h"
-#include "qmap.h"
-#include <private/qt_mac_p.h>
-
-
-#ifdef Q_WS_MAC32
-#include <QuickTime/QuickTime.h>
-#include <qlibrary.h>
-#endif
-
-QT_BEGIN_NAMESPACE
-
-extern CGImageRef qt_mac_createCGImageFromQImage(const QImage &img, const QImage **imagePtr = 0); // qpaintengine_mac.cpp
-
-typedef QList<QMacPasteboardMime*> MimeList;
-Q_GLOBAL_STATIC(MimeList, globalMimeList)
-
-static void cleanup_mimes()
-{
- MimeList *mimes = globalMimeList();
- while (!mimes->isEmpty())
- delete mimes->takeFirst();
-}
-
-Q_GLOBAL_STATIC(QStringList, globalDraggedTypesList)
-
-/*!
- \fn void qRegisterDraggedTypes(const QStringList &types)
- \relates QMacPasteboardMime
-
- Registers the given \a types as custom pasteboard types.
-
- This function should be called to enable the Drag and Drop events
- for custom pasteboard types on Cocoa implementations. This is required
- in addition to a QMacPasteboardMime subclass implementation. By default
- drag and drop is enabled for all standard pasteboard types.
-
- \sa QMacPasteboardMime
-*/
-Q_GUI_EXPORT void qRegisterDraggedTypes(const QStringList &types)
-{
- (*globalDraggedTypesList()) += types;
-}
-
-const QStringList& qEnabledDraggedTypes()
-{
- return (*globalDraggedTypesList());
-}
-
-
-/*****************************************************************************
- QDnD debug facilities
- *****************************************************************************/
-//#define DEBUG_MIME_MAPS
-
-//functions
-extern QString qt_mac_from_pascal_string(const Str255); //qglobal.cpp
-extern void qt_mac_from_pascal_string(QString, Str255, TextEncoding encoding=0, int len=-1); //qglobal.cpp
-
-ScrapFlavorType qt_mac_mime_type = 'CUTE';
-CFStringRef qt_mac_mime_typeUTI = CFSTR("com.pasteboard.trolltech.marker");
-
-/*!
- \class QMacPasteboardMime
- \brief The QMacPasteboardMime class converts between a MIME type and a
- \l{http://developer.apple.com/macosx/uniformtypeidentifiers.html}{Uniform
- Type Identifier (UTI)} format.
- \since 4.2
-
- \ingroup draganddrop
-
- Qt's drag and drop and clipboard facilities use the MIME
- standard. On X11, this maps trivially to the Xdnd protocol. On
- Mac, although some applications use MIME to describe clipboard
- contents, it is more common to use Apple's UTI format.
-
- QMacPasteboardMime's role is to bridge the gap between MIME and UTI;
- By subclasses this class, one can extend Qt's drag and drop
- and clipboard handling to convert to and from unsupported, or proprietary, UTI formats.
-
- A subclass of QMacPasteboardMime will automatically be registered, and active, upon instantiation.
-
- Qt has predefined support for the following UTIs:
- \list
- \i public.utf8-plain-text - converts to "text/plain"
- \i public.utf16-plain-text - converts to "text/plain"
- \i public.html - converts to "text/html"
- \i public.url - converts to "text/uri-list"
- \i public.file-url - converts to "text/uri-list"
- \i public.tiff - converts to "application/x-qt-image"
- \i public.vcard - converts to "text/plain"
- \i com.apple.traditional-mac-plain-text - converts to "text/plain"
- \i com.apple.pict - converts to "application/x-qt-image"
- \endlist
-
- When working with MIME data, Qt will interate through all instances of QMacPasteboardMime to
- find an instance that can convert to, or from, a specific MIME type. It will do this by calling
- canConvert() on each instance, starting with (and choosing) the last created instance first.
- The actual conversions will be done by using convertToMime() and convertFromMime().
-
- \note The API uses the term "flavor" in some cases. This is for backwards
- compatibility reasons, and should now be understood as UTIs.
-*/
-
-/*! \enum QMacPasteboardMime::QMacPasteboardMimeType
- \internal
-*/
-
-/*!
- Constructs a new conversion object of type \a t, adding it to the
- globally accessed list of available convertors.
-*/
-QMacPasteboardMime::QMacPasteboardMime(char t) : type(t)
-{
- globalMimeList()->append(this);
-}
-
-/*!
- Destroys a conversion object, removing it from the global
- list of available convertors.
-*/
-QMacPasteboardMime::~QMacPasteboardMime()
-{
- if(!QApplication::closingDown())
- globalMimeList()->removeAll(this);
-}
-
-class QMacPasteboardMimeAny : public QMacPasteboardMime {
-private:
-
-public:
- QMacPasteboardMimeAny() : QMacPasteboardMime(MIME_QT_CONVERTOR|MIME_ALL) {
- }
- ~QMacPasteboardMimeAny() {
- }
- QString convertorName();
-
- QString flavorFor(const QString &mime);
- QString mimeFor(QString flav);
- bool canConvert(const QString &mime, QString flav);
- QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav);
- QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav);
-};
-
-QString QMacPasteboardMimeAny::convertorName()
-{
- return QLatin1String("Any-Mime");
-}
-
-QString QMacPasteboardMimeAny::flavorFor(const QString &mime)
-{
- // do not handle the mime type name in the drag pasteboard
- if(mime == QLatin1String("application/x-qt-mime-type-name"))
- return QString();
- QString ret = QLatin1String("com.trolltech.anymime.") + mime;
- return ret.replace(QLatin1Char('/'), QLatin1String("--"));
-}
-
-QString QMacPasteboardMimeAny::mimeFor(QString flav)
-{
- const QString any_prefix = QLatin1String("com.trolltech.anymime.");
- if(flav.size() > any_prefix.length() && flav.startsWith(any_prefix))
- return flav.mid(any_prefix.length()).replace(QLatin1String("--"), QLatin1String("/"));
- return QString();
-}
-
-bool QMacPasteboardMimeAny::canConvert(const QString &mime, QString flav)
-{
- return mimeFor(flav) == mime;
-}
-
-QVariant QMacPasteboardMimeAny::convertToMime(const QString &mime, QList<QByteArray> data, QString)
-{
- if(data.count() > 1)
- qWarning("QMacPasteboardMimeAny: Cannot handle multiple member data");
- QVariant ret;
- if (mime == QLatin1String("text/plain"))
- ret = QString::fromUtf8(data.first());
- else
- ret = data.first();
- return ret;
-}
-
-QList<QByteArray> QMacPasteboardMimeAny::convertFromMime(const QString &mime, QVariant data, QString)
-{
- QList<QByteArray> ret;
- if (mime == QLatin1String("text/plain"))
- ret.append(data.toString().toUtf8());
- else
- ret.append(data.toByteArray());
- return ret;
-}
-
-class QMacPasteboardMimeTypeName : public QMacPasteboardMime {
-private:
-
-public:
- QMacPasteboardMimeTypeName() : QMacPasteboardMime(MIME_QT_CONVERTOR|MIME_ALL) {
- }
- ~QMacPasteboardMimeTypeName() {
- }
- QString convertorName();
-
- QString flavorFor(const QString &mime);
- QString mimeFor(QString flav);
- bool canConvert(const QString &mime, QString flav);
- QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav);
- QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav);
-};
-
-QString QMacPasteboardMimeTypeName::convertorName()
-{
- return QLatin1String("Qt-Mime-Type");
-}
-
-QString QMacPasteboardMimeTypeName::flavorFor(const QString &mime)
-{
- if(mime == QLatin1String("application/x-qt-mime-type-name"))
- return QLatin1String("com.trolltech.qt.MimeTypeName");
- return QString();
-}
-
-QString QMacPasteboardMimeTypeName::mimeFor(QString)
-{
- return QString();
-}
-
-bool QMacPasteboardMimeTypeName::canConvert(const QString &, QString)
-{
- return false;
-}
-
-QVariant QMacPasteboardMimeTypeName::convertToMime(const QString &, QList<QByteArray>, QString)
-{
- QVariant ret;
- return ret;
-}
-
-QList<QByteArray> QMacPasteboardMimeTypeName::convertFromMime(const QString &, QVariant, QString)
-{
- QList<QByteArray> ret;
- ret.append(QString("x-qt-mime-type-name").toUtf8());
- return ret;
-}
-
-class QMacPasteboardMimePlainText : public QMacPasteboardMime {
-public:
- QMacPasteboardMimePlainText() : QMacPasteboardMime(MIME_ALL) { }
- QString convertorName();
-
- QString flavorFor(const QString &mime);
- QString mimeFor(QString flav);
- bool canConvert(const QString &mime, QString flav);
- QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav);
- QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav);
-};
-
-QString QMacPasteboardMimePlainText::convertorName()
-{
- return QLatin1String("PlainText");
-}
-
-QString QMacPasteboardMimePlainText::flavorFor(const QString &mime)
-{
- if (mime == QLatin1String("text/plain"))
- return QLatin1String("com.apple.traditional-mac-plain-text");
- return QString();
-}
-
-QString QMacPasteboardMimePlainText::mimeFor(QString flav)
-{
- if (flav == QLatin1String("com.apple.traditional-mac-plain-text"))
- return QLatin1String("text/plain");
- return QString();
-}
-
-bool QMacPasteboardMimePlainText::canConvert(const QString &mime, QString flav)
-{
- return flavorFor(mime) == flav;
-}
-
-QVariant QMacPasteboardMimePlainText::convertToMime(const QString &mimetype, QList<QByteArray> data, QString flavor)
-{
- if(data.count() > 1)
- qWarning("QMacPasteboardMimePlainText: Cannot handle multiple member data");
- const QByteArray &firstData = data.first();
- QVariant ret;
- if(flavor == QCFString(QLatin1String("com.apple.traditional-mac-plain-text"))) {
- QCFString str(CFStringCreateWithBytes(kCFAllocatorDefault,
- reinterpret_cast<const UInt8 *>(firstData.constData()),
- firstData.size(), CFStringGetSystemEncoding(), false));
- ret = QString(str);
- } else {
- qWarning("QMime::convertToMime: unhandled mimetype: %s", qPrintable(mimetype));
- }
- return ret;
-}
-
-QList<QByteArray> QMacPasteboardMimePlainText::convertFromMime(const QString &, QVariant data, QString flavor)
-{
- QList<QByteArray> ret;
- QString string = data.toString();
- if(flavor == QCFString(QLatin1String("com.apple.traditional-mac-plain-text")))
- ret.append(string.toLatin1());
- return ret;
-}
-
-class QMacPasteboardMimeUnicodeText : public QMacPasteboardMime {
-public:
- QMacPasteboardMimeUnicodeText() : QMacPasteboardMime(MIME_ALL) { }
- QString convertorName();
-
- QString flavorFor(const QString &mime);
- QString mimeFor(QString flav);
- bool canConvert(const QString &mime, QString flav);
- QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav);
- QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav);
-};
-
-QString QMacPasteboardMimeUnicodeText::convertorName()
-{
- return QLatin1String("UnicodeText");
-}
-
-QString QMacPasteboardMimeUnicodeText::flavorFor(const QString &mime)
-{
- if (mime == QLatin1String("text/plain"))
- return QLatin1String("public.utf16-plain-text");
- int i = mime.indexOf(QLatin1String("charset="));
- if (i >= 0) {
- QString cs(mime.mid(i+8).toLower());
- i = cs.indexOf(QLatin1Char(';'));
- if (i>=0)
- cs = cs.left(i);
- if (cs == QLatin1String("system"))
- return QLatin1String("public.utf8-plain-text");
- else if (cs == QLatin1String("iso-10646-ucs-2")
- || cs == QLatin1String("utf16"))
- return QLatin1String("public.utf16-plain-text");
- }
- return QString();
-}
-
-QString QMacPasteboardMimeUnicodeText::mimeFor(QString flav)
-{
- if (flav == QLatin1String("public.utf16-plain-text") || flav == QLatin1String("public.utf8-plain-text"))
- return QLatin1String("text/plain");
- return QString();
-}
-
-bool QMacPasteboardMimeUnicodeText::canConvert(const QString &mime, QString flav)
-{
- return flavorFor(mime) == flav;
-}
-
-QVariant QMacPasteboardMimeUnicodeText::convertToMime(const QString &mimetype, QList<QByteArray> data, QString flavor)
-{
- if(data.count() > 1)
- qWarning("QMacPasteboardMimeUnicodeText: Cannot handle multiple member data");
- const QByteArray &firstData = data.first();
- // I can only handle two types (system and unicode) so deal with them that way
- QVariant ret;
- if(flavor == QLatin1String("public.utf8-plain-text")) {
- QCFString str(CFStringCreateWithBytes(kCFAllocatorDefault,
- reinterpret_cast<const UInt8 *>(firstData.constData()),
- firstData.size(), CFStringGetSystemEncoding(), false));
- ret = QString(str);
- } else if (flavor == QLatin1String("public.utf16-plain-text")) {
- ret = QString(reinterpret_cast<const QChar *>(firstData.constData()),
- firstData.size() / sizeof(QChar));
- } else {
- qWarning("QMime::convertToMime: unhandled mimetype: %s", qPrintable(mimetype));
- }
- return ret;
-}
-
-QList<QByteArray> QMacPasteboardMimeUnicodeText::convertFromMime(const QString &, QVariant data, QString flavor)
-{
- QList<QByteArray> ret;
- QString string = data.toString();
- if(flavor == QLatin1String("public.utf8-plain-text"))
- ret.append(string.toUtf8());
- else if (flavor == QLatin1String("public.utf16-plain-text"))
- ret.append(QByteArray((char*)string.utf16(), string.length()*2));
- return ret;
-}
-
-class QMacPasteboardMimeHTMLText : public QMacPasteboardMime {
-public:
- QMacPasteboardMimeHTMLText() : QMacPasteboardMime(MIME_ALL) { }
- QString convertorName();
-
- QString flavorFor(const QString &mime);
- QString mimeFor(QString flav);
- bool canConvert(const QString &mime, QString flav);
- QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav);
- QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav);
-};
-
-QString QMacPasteboardMimeHTMLText::convertorName()
-{
- return QLatin1String("HTML");
-}
-
-QString QMacPasteboardMimeHTMLText::flavorFor(const QString &mime)
-{
- if (mime == QLatin1String("text/html"))
- return QLatin1String("public.html");
- return QString();
-}
-
-QString QMacPasteboardMimeHTMLText::mimeFor(QString flav)
-{
- if (flav == QLatin1String("public.html"))
- return QLatin1String("text/html");
- return QString();
-}
-
-bool QMacPasteboardMimeHTMLText::canConvert(const QString &mime, QString flav)
-{
- return flavorFor(mime) == flav;
-}
-
-QVariant QMacPasteboardMimeHTMLText::convertToMime(const QString &mimeType, QList<QByteArray> data, QString flavor)
-{
- if (!canConvert(mimeType, flavor))
- return QVariant();
- if (data.count() > 1)
- qWarning("QMacPasteboardMimeHTMLText: Cannot handle multiple member data");
- return data.first();
-}
-
-QList<QByteArray> QMacPasteboardMimeHTMLText::convertFromMime(const QString &mime, QVariant data, QString flavor)
-{
- QList<QByteArray> ret;
- if (!canConvert(mime, flavor))
- return ret;
- ret.append(data.toByteArray());
- return ret;
-}
-
-
-#ifdef Q_WS_MAC32
-
-// This can be removed once 10.6 is the minimum (or we have to require 64-bit) whichever comes first.
-
-typedef ComponentResult (*PtrGraphicsImportSetDataHandle)(GraphicsImportComponent, Handle);
-typedef ComponentResult (*PtrGraphicsImportCreateCGImage)(GraphicsImportComponent, CGImageRef*, UInt32);
-typedef ComponentResult (*PtrGraphicsExportSetInputCGImage)(GraphicsExportComponent, CGImageRef);
-typedef ComponentResult (*PtrGraphicsExportSetOutputHandle)(GraphicsExportComponent, Handle);
-typedef ComponentResult (*PtrGraphicsExportDoExport)(GraphicsExportComponent, unsigned long *);
-
-static PtrGraphicsImportSetDataHandle ptrGraphicsImportSetDataHandle = 0;
-static PtrGraphicsImportCreateCGImage ptrGraphicsImportCreateCGImage = 0;
-static PtrGraphicsExportSetInputCGImage ptrGraphicsExportSetInputCGImage = 0;
-static PtrGraphicsExportSetOutputHandle ptrGraphicsExportSetOutputHandle = 0;
-static PtrGraphicsExportDoExport ptrGraphicsExportDoExport = 0;
-
-static bool resolveMimeQuickTimeSymbols()
-{
- if (ptrGraphicsImportSetDataHandle == 0) {
- QLibrary library(QLatin1String("/System/Library/Frameworks/QuickTime.framework/QuickTime"));
- ptrGraphicsImportSetDataHandle = reinterpret_cast<PtrGraphicsImportSetDataHandle>(library.resolve("GraphicsImportSetDataHandle"));
- ptrGraphicsImportCreateCGImage = reinterpret_cast<PtrGraphicsImportCreateCGImage>(library.resolve("GraphicsImportCreateCGImage"));
- ptrGraphicsExportSetInputCGImage = reinterpret_cast<PtrGraphicsExportSetInputCGImage>(library.resolve("GraphicsExportSetInputCGImage"));
- ptrGraphicsExportSetOutputHandle = reinterpret_cast<PtrGraphicsExportSetOutputHandle>(library.resolve("GraphicsExportSetOutputHandle"));
- ptrGraphicsExportDoExport = reinterpret_cast<PtrGraphicsExportDoExport>(library.resolve("GraphicsExportDoExport"));
- }
-
- return ptrGraphicsImportSetDataHandle != 0
- && ptrGraphicsImportCreateCGImage != 0 && ptrGraphicsExportSetInputCGImage != 0
- && ptrGraphicsExportSetOutputHandle != 0 && ptrGraphicsExportDoExport != 0;
-}
-
-class QMacPasteboardMimePict : public QMacPasteboardMime {
-public:
- QMacPasteboardMimePict() : QMacPasteboardMime(MIME_ALL) { }
- QString convertorName();
-
- QString flavorFor(const QString &mime);
- QString mimeFor(QString flav);
- bool canConvert(const QString &mime, QString flav);
- QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav);
- QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav);
-};
-
-QString QMacPasteboardMimePict::convertorName()
-{
- return QLatin1String("Pict");
-}
-
-QString QMacPasteboardMimePict::flavorFor(const QString &mime)
-{
- if(mime.startsWith(QLatin1String("application/x-qt-image")))
- return QLatin1String("com.apple.pict");
- return QString();
-}
-
-QString QMacPasteboardMimePict::mimeFor(QString flav)
-{
- if(flav == QLatin1String("com.apple.pict"))
- return QLatin1String("application/x-qt-image");
- return QString();
-}
-
-bool QMacPasteboardMimePict::canConvert(const QString &mime, QString flav)
-{
- return flav == QLatin1String("com.apple.pict")
- && mime == QLatin1String("application/x-qt-image");
-}
-
-
-QVariant QMacPasteboardMimePict::convertToMime(const QString &mime, QList<QByteArray> data, QString flav)
-{
- if(data.count() > 1)
- qWarning("QMacPasteboardMimePict: Cannot handle multiple member data");
- QVariant ret;
- if (!resolveMimeQuickTimeSymbols())
- return ret;
-
- if(!canConvert(mime, flav))
- return ret;
- const QByteArray &a = data.first();
-
- // This function expects the 512 header (just to skip it, so create the extra space for it).
- Handle pic = NewHandle(a.size() + 512);
- memcpy(*pic + 512, a.constData(), a.size());
-
- GraphicsImportComponent graphicsImporter;
- ComponentResult result = OpenADefaultComponent(GraphicsImporterComponentType,
- kQTFileTypePicture, &graphicsImporter);
- QCFType<CGImageRef> cgImage;
- if (!result)
- result = ptrGraphicsImportSetDataHandle(graphicsImporter, pic);
- if (!result)
- result = ptrGraphicsImportCreateCGImage(graphicsImporter, &cgImage,
- kGraphicsImportCreateCGImageUsingCurrentSettings);
- if (!result)
- ret = QVariant(QPixmap::fromMacCGImageRef(cgImage).toImage());
- CloseComponent(graphicsImporter);
- DisposeHandle(pic);
- return ret;
-}
-
-QList<QByteArray> QMacPasteboardMimePict::convertFromMime(const QString &mime, QVariant variant,
- QString flav)
-{
- QList<QByteArray> ret;
- if (!resolveMimeQuickTimeSymbols())
- return ret;
-
- if (!canConvert(mime, flav))
- return ret;
- QCFType<CGImageRef> cgimage = qt_mac_createCGImageFromQImage(qvariant_cast<QImage>(variant));
- Handle pic = NewHandle(0);
- GraphicsExportComponent graphicsExporter;
- ComponentResult result = OpenADefaultComponent(GraphicsExporterComponentType,
- kQTFileTypePicture, &graphicsExporter);
- if (!result) {
- unsigned long sizeWritten;
- result = ptrGraphicsExportSetInputCGImage(graphicsExporter, cgimage);
- if (!result)
- result = ptrGraphicsExportSetOutputHandle(graphicsExporter, pic);
- if (!result)
- result = ptrGraphicsExportDoExport(graphicsExporter, &sizeWritten);
-
- CloseComponent(graphicsExporter);
- }
-
- int size = GetHandleSize((Handle)pic);
- // Skip the Picture File header (512 bytes) and feed the raw data
- QByteArray ar(reinterpret_cast<char *>(*pic + 512), size - 512);
- ret.append(ar);
- DisposeHandle(pic);
- return ret;
-}
-
-
-#endif //Q_WS_MAC32
-
-class QMacPasteboardMimeTiff : public QMacPasteboardMime {
-public:
- QMacPasteboardMimeTiff() : QMacPasteboardMime(MIME_ALL) { }
- QString convertorName();
-
- QString flavorFor(const QString &mime);
- QString mimeFor(QString flav);
- bool canConvert(const QString &mime, QString flav);
- QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav);
- QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav);
-};
-
-QString QMacPasteboardMimeTiff::convertorName()
-{
- return QLatin1String("Tiff");
-}
-
-QString QMacPasteboardMimeTiff::flavorFor(const QString &mime)
-{
- if(mime.startsWith(QLatin1String("application/x-qt-image")))
- return QLatin1String("public.tiff");
- return QString();
-}
-
-QString QMacPasteboardMimeTiff::mimeFor(QString flav)
-{
- if(flav == QLatin1String("public.tiff"))
- return QLatin1String("application/x-qt-image");
- return QString();
-}
-
-bool QMacPasteboardMimeTiff::canConvert(const QString &mime, QString flav)
-{
- return flav == QLatin1String("public.tiff") && mime == QLatin1String("application/x-qt-image");
-}
-
-QVariant QMacPasteboardMimeTiff::convertToMime(const QString &mime, QList<QByteArray> data, QString flav)
-{
- if(data.count() > 1)
- qWarning("QMacPasteboardMimeTiff: Cannot handle multiple member data");
- QVariant ret;
- if (!canConvert(mime, flav))
- return ret;
- const QByteArray &a = data.first();
- QCFType<CGImageRef> image;
- QCFType<CFDataRef> tiffData = CFDataCreateWithBytesNoCopy(0,
- reinterpret_cast<const UInt8 *>(a.constData()),
- a.size(), kCFAllocatorNull);
- QCFType<CGImageSourceRef> imageSource = CGImageSourceCreateWithData(tiffData, 0);
- image = CGImageSourceCreateImageAtIndex(imageSource, 0, 0);
-
- if (image != 0)
- ret = QVariant(QPixmap::fromMacCGImageRef(image).toImage());
- return ret;
-}
-
-QList<QByteArray> QMacPasteboardMimeTiff::convertFromMime(const QString &mime, QVariant variant, QString flav)
-{
- QList<QByteArray> ret;
- if (!canConvert(mime, flav))
- return ret;
-
- QImage img = qvariant_cast<QImage>(variant);
- QCFType<CGImageRef> cgimage = qt_mac_createCGImageFromQImage(img);
-#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4)
- if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4) {
- QCFType<CFMutableDataRef> data = CFDataCreateMutable(0, 0);
- QCFType<CGImageDestinationRef> imageDestination = CGImageDestinationCreateWithData(data, kUTTypeTIFF, 1, 0);
- if (imageDestination != 0) {
- CFTypeRef keys[2];
- QCFType<CFTypeRef> values[2];
- QCFType<CFDictionaryRef> options;
- keys[0] = kCGImagePropertyPixelWidth;
- keys[1] = kCGImagePropertyPixelHeight;
- int width = img.width();
- int height = img.height();
- values[0] = CFNumberCreate(0, kCFNumberIntType, &width);
- values[1] = CFNumberCreate(0, kCFNumberIntType, &height);
- options = CFDictionaryCreate(0, reinterpret_cast<const void **>(keys),
- reinterpret_cast<const void **>(values), 2,
- &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks);
- CGImageDestinationAddImage(imageDestination, cgimage, options);
- CGImageDestinationFinalize(imageDestination);
- }
- QByteArray ar(CFDataGetLength(data), 0);
- CFDataGetBytes(data,
- CFRangeMake(0, ar.size()),
- reinterpret_cast<UInt8 *>(ar.data()));
- ret.append(ar);
- } else
-#endif
- {
-#ifdef Q_WS_MAC32
- Handle tiff = NewHandle(0);
- if (resolveMimeQuickTimeSymbols()) {
- GraphicsExportComponent graphicsExporter;
- ComponentResult result = OpenADefaultComponent(GraphicsExporterComponentType,
- kQTFileTypeTIFF, &graphicsExporter);
- if (!result) {
- unsigned long sizeWritten;
- result = ptrGraphicsExportSetInputCGImage(graphicsExporter, cgimage);
- if (!result)
- result = ptrGraphicsExportSetOutputHandle(graphicsExporter, tiff);
- if (!result)
- result = ptrGraphicsExportDoExport(graphicsExporter, &sizeWritten);
-
- CloseComponent(graphicsExporter);
- }
- }
- int size = GetHandleSize((Handle)tiff);
- QByteArray ar(reinterpret_cast<char *>(*tiff), size);
- ret.append(ar);
- DisposeHandle(tiff);
-#endif
- }
- return ret;
-}
-
-
-class QMacPasteboardMimeFileUri : public QMacPasteboardMime {
-public:
- QMacPasteboardMimeFileUri() : QMacPasteboardMime(MIME_ALL) { }
- QString convertorName();
-
- QString flavorFor(const QString &mime);
- QString mimeFor(QString flav);
- bool canConvert(const QString &mime, QString flav);
- QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav);
- QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav);
-};
-
-QString QMacPasteboardMimeFileUri::convertorName()
-{
- return QLatin1String("FileURL");
-}
-
-QString QMacPasteboardMimeFileUri::flavorFor(const QString &mime)
-{
- if (mime == QLatin1String("text/uri-list"))
- return QCFString(UTTypeCreatePreferredIdentifierForTag(kUTTagClassOSType, CFSTR("furl"), 0));
- return QString();
-}
-
-QString QMacPasteboardMimeFileUri::mimeFor(QString flav)
-{
- if (flav == QCFString(UTTypeCreatePreferredIdentifierForTag(kUTTagClassOSType, CFSTR("furl"), 0)))
- return QLatin1String("text/uri-list");
- return QString();
-}
-
-bool QMacPasteboardMimeFileUri::canConvert(const QString &mime, QString flav)
-{
- return mime == QLatin1String("text/uri-list")
- && flav == QCFString(UTTypeCreatePreferredIdentifierForTag(kUTTagClassOSType, CFSTR("furl"), 0));
-}
-
-QVariant QMacPasteboardMimeFileUri::convertToMime(const QString &mime, QList<QByteArray> data, QString flav)
-{
- if(!canConvert(mime, flav))
- return QVariant();
- QList<QVariant> ret;
- for(int i = 0; i < data.size(); ++i) {
- QUrl url = QUrl::fromEncoded(data.at(i));
- if (url.host().toLower() == QLatin1String("localhost"))
- url.setHost(QString());
- url.setPath(url.path().normalized(QString::NormalizationForm_C));
- ret.append(url);
- }
- return QVariant(ret);
-}
-
-QList<QByteArray> QMacPasteboardMimeFileUri::convertFromMime(const QString &mime, QVariant data, QString flav)
-{
- QList<QByteArray> ret;
- if (!canConvert(mime, flav))
- return ret;
- QList<QVariant> urls = data.toList();
- for(int i = 0; i < urls.size(); ++i) {
- QUrl url = urls.at(i).toUrl();
- if (url.scheme().isEmpty())
- url.setScheme(QLatin1String("file"));
- if (url.scheme().toLower() == QLatin1String("file")) {
- if (url.host().isEmpty())
- url.setHost(QLatin1String("localhost"));
- url.setPath(url.path().normalized(QString::NormalizationForm_D));
- }
- ret.append(url.toEncoded());
- }
- return ret;
-}
-
-class QMacPasteboardMimeUrl : public QMacPasteboardMime {
-public:
- QMacPasteboardMimeUrl() : QMacPasteboardMime(MIME_ALL) { }
- QString convertorName();
-
- QString flavorFor(const QString &mime);
- QString mimeFor(QString flav);
- bool canConvert(const QString &mime, QString flav);
- QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav);
- QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav);
-};
-
-QString QMacPasteboardMimeUrl::convertorName()
-{
- return QLatin1String("URL");
-}
-
-QString QMacPasteboardMimeUrl::flavorFor(const QString &mime)
-{
- if(mime.startsWith(QLatin1String("text/uri-list")))
- return QLatin1String("public.url");
- return QString();
-}
-
-QString QMacPasteboardMimeUrl::mimeFor(QString flav)
-{
- if(flav == QLatin1String("public.url"))
- return QLatin1String("text/uri-list");
- return QString();
-}
-
-bool QMacPasteboardMimeUrl::canConvert(const QString &mime, QString flav)
-{
- return flav == QLatin1String("public.url")
- && mime == QLatin1String("text/uri-list");
-}
-
-QVariant QMacPasteboardMimeUrl::convertToMime(const QString &mime, QList<QByteArray> data, QString flav)
-{
- if(!canConvert(mime, flav))
- return QVariant();
-
- QList<QVariant> ret;
- for (int i=0; i<data.size(); ++i) {
- QUrl url = QUrl::fromEncoded(data.at(i));
- if (url.host().toLower() == QLatin1String("localhost"))
- url.setHost(QString());
- url.setPath(url.path().normalized(QString::NormalizationForm_C));
- ret.append(url);
- }
- return QVariant(ret);
-}
-
-QList<QByteArray> QMacPasteboardMimeUrl::convertFromMime(const QString &mime, QVariant data, QString flav)
-{
- QList<QByteArray> ret;
- if (!canConvert(mime, flav))
- return ret;
-
- QList<QVariant> urls = data.toList();
- for(int i=0; i<urls.size(); ++i) {
- QUrl url = urls.at(i).toUrl();
- if (url.scheme().isEmpty())
- url.setScheme(QLatin1String("file"));
- if (url.scheme().toLower() == QLatin1String("file")) {
- if (url.host().isEmpty())
- url.setHost(QLatin1String("localhost"));
- url.setPath(url.path().normalized(QString::NormalizationForm_D));
- }
- ret.append(url.toEncoded());
- }
- return ret;
-}
-
-class QMacPasteboardMimeVCard : public QMacPasteboardMime
-{
-public:
- QMacPasteboardMimeVCard() : QMacPasteboardMime(MIME_ALL){ }
- QString convertorName();
-
- QString flavorFor(const QString &mime);
- QString mimeFor(QString flav);
- bool canConvert(const QString &mime, QString flav);
- QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav);
- QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav);
-};
-
-QString QMacPasteboardMimeVCard::convertorName()
-{
- return QString("VCard");
-}
-
-bool QMacPasteboardMimeVCard::canConvert(const QString &mime, QString flav)
-{
- return mimeFor(flav) == mime;
-}
-
-QString QMacPasteboardMimeVCard::flavorFor(const QString &mime)
-{
- if(mime.startsWith(QLatin1String("text/plain")))
- return QLatin1String("public.vcard");
- return QString();
-}
-
-QString QMacPasteboardMimeVCard::mimeFor(QString flav)
-{
- if (flav == QLatin1String("public.vcard"))
- return QLatin1String("text/plain");
- return QString();
-}
-
-QVariant QMacPasteboardMimeVCard::convertToMime(const QString &mime, QList<QByteArray> data, QString)
-{
- QByteArray cards;
- if (mime == QLatin1String("text/plain")) {
- for (int i=0; i<data.size(); ++i)
- cards += data[i];
- }
- return QVariant(cards);
-}
-
-QList<QByteArray> QMacPasteboardMimeVCard::convertFromMime(const QString &mime, QVariant data, QString)
-{
- QList<QByteArray> ret;
- if (mime == QLatin1String("text/plain"))
- ret.append(data.toString().toUtf8());
- return ret;
-}
-
-#ifdef QT3_SUPPORT
-class QMacPasteboardMimeQt3Any : public QMacPasteboardMime {
-private:
- int current_max;
- QFile library_file;
- QDateTime mime_registry_loaded;
- QMap<QString, int> mime_registry;
- int registerMimeType(const QString &mime);
- bool loadMimeRegistry();
-
-public:
- QMacPasteboardMimeQt3Any() : QMacPasteboardMime(MIME_QT3_CONVERTOR) {
- current_max = 'QT00';
- }
- ~QMacPasteboardMimeQt3Any() {
- }
- QString convertorName();
-
- QString flavorFor(const QString &mime);
- QString mimeFor(QString flav);
- bool canConvert(const QString &mime, QString flav);
- QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav);
- QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav);
-};
-
-static bool qt_mac_openMimeRegistry(bool global, QIODevice::OpenMode mode, QFile &file)
-{
- QString dir = QLatin1String("/Library/Qt");
- if(!global)
- dir.prepend(QDir::homePath());
- file.setFileName(dir + QLatin1String("/.mime_types"));
- if(mode != QIODevice::ReadOnly) {
- if(!QFile::exists(dir)) {
- // Do it with a system call as I don't see much worth in
- // doing it with QDir since we have to chmod anyway.
- bool success = ::mkdir(dir.toLocal8Bit().constData(), S_IRUSR | S_IWUSR | S_IXUSR) == 0;
- if (success)
- success = ::chmod(dir.toLocal8Bit().constData(), S_IRUSR | S_IWUSR | S_IXUSR
- | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH) == 0;
- if (!success)
- return false;
- }
- if (!file.exists()) {
- // Create the file and chmod it so that everyone can write to it.
- int fd = ::open(file.fileName().toLocal8Bit().constData(), O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
- bool success = fd != -1;
- if (success)
- success = ::fchmod(fd, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH) == 0;
- if (fd != -1)
- ::close(fd);
- if(!success)
- return false;
- }
- }
- return file.open(mode);
-}
-
-static void qt_mac_loadMimeRegistry(QFile &file, QMap<QString, int> &registry, int &max)
-{
- file.reset();
- QTextStream stream(&file);
- while(!stream.atEnd()) {
- QString mime = stream.readLine();
- int mactype = stream.readLine().toInt();
- if(mactype > max)
- max = mactype;
- registry.insert(mime, mactype);
- }
-}
-
-bool QMacPasteboardMimeQt3Any::loadMimeRegistry()
-{
- if(!library_file.isOpen()) {
- if(!qt_mac_openMimeRegistry(true, QIODevice::ReadWrite, library_file)) {
- QFile global;
- if(qt_mac_openMimeRegistry(true, QIODevice::ReadOnly, global)) {
- qt_mac_loadMimeRegistry(global, mime_registry, current_max);
- global.close();
- }
- if(!qt_mac_openMimeRegistry(false, QIODevice::ReadWrite, library_file)) {
- qWarning("QMacPasteboardMimeAnyQt3Mime: Failure to open mime resources %s -- %s", library_file.fileName().toLatin1().constData(),
- library_file.errorString().toLatin1().constData());
- return false;
- }
- }
- }
-
- QFileInfo fi(library_file);
- if(!mime_registry_loaded.isNull() && mime_registry_loaded == fi.lastModified())
- return true;
- mime_registry_loaded = fi.lastModified();
- qt_mac_loadMimeRegistry(library_file, mime_registry, current_max);
- return true;
-}
-
-int QMacPasteboardMimeQt3Any::registerMimeType(const QString &mime)
-{
- if(!mime_registry.contains(mime)) {
- if(!loadMimeRegistry()) {
- qWarning("QMacPasteboardMimeAnyQt3Mime: Internal error");
- return 0;
- }
- if(!mime_registry.contains(mime)) {
- if(!library_file.isOpen()) {
- if(!library_file.open(QIODevice::WriteOnly)) {
- qWarning("QMacPasteboardMimeAnyQt3Mime: Failure to open %s -- %s", library_file.fileName().toLatin1().constData(),
- library_file.errorString().toLatin1().constData());
- return false;
- }
- }
- int ret = ++current_max;
- mime_registry_loaded = QFileInfo(library_file).lastModified();
- QTextStream stream(&library_file);
- stream << mime << endl;
- stream << ret << endl;
- mime_registry.insert(mime, ret);
- library_file.flush(); //flush and set mtime
- return ret;
- }
- }
- return mime_registry[mime];
-}
-
-QString QMacPasteboardMimeQt3Any::convertorName()
-{
- return QLatin1String("Qt3-Any-Mime");
-}
-
-QString QMacPasteboardMimeQt3Any::flavorFor(const QString &mime)
-{
- const int os_flav = registerMimeType(mime);
- QCFType<CFArrayRef> ids = UTTypeCreateAllIdentifiersForTag(0, kUTTagClassOSType,
- QCFString(UTCreateStringForOSType(os_flav)));
- if(ids) {
- const int type_count = CFArrayGetCount(ids);
- if(type_count) {
- if(type_count > 1)
- qDebug("Can't happen!");
- return QCFString::toQString((CFStringRef)CFArrayGetValueAtIndex(ids, 0));
- }
- }
- return QString();
-}
-
-QString QMacPasteboardMimeQt3Any::mimeFor(QString flav)
-{
- loadMimeRegistry();
- const int os_flav = UTGetOSTypeFromString(UTTypeCopyPreferredTagWithClass(QCFString(flav), kUTTagClassOSType));
- for(QMap<QString, int>::const_iterator it = mime_registry.constBegin();
- it != mime_registry.constEnd(); ++it) {
- if(it.value() == os_flav)
- return QString::fromLatin1(it.key().toLatin1());
- }
- return QString();
-}
-
-bool QMacPasteboardMimeQt3Any::canConvert(const QString &mime, QString flav)
-{
- loadMimeRegistry();
- const int os_flav = UTGetOSTypeFromString(UTTypeCopyPreferredTagWithClass(QCFString(flav), kUTTagClassOSType));
- if(mime_registry.contains(mime) && mime_registry[mime] == os_flav)
- return true;
- return false;
-}
-
-QVariant QMacPasteboardMimeQt3Any::convertToMime(const QString &, QList<QByteArray>, QString)
-{
- qWarning("QMacPasteboardMimeAnyQt3Mime: Cannot write anything!");
- return QVariant();
-}
-
-QList<QByteArray> QMacPasteboardMimeQt3Any::convertFromMime(const QString &mime, QVariant data, QString)
-{
- QList<QByteArray> ret;
- if (mime == QLatin1String("text/plain")) {
- ret.append(data.toString().toUtf8());
- } else {
- ret.append(data.toByteArray());
- }
- return ret;
-}
-#endif
-
-/*!
- \internal
-
- This is an internal function.
-*/
-void QMacPasteboardMime::initialize()
-{
- if(globalMimeList()->isEmpty()) {
- qAddPostRoutine(cleanup_mimes);
-
- //standard types that we wrap
- new QMacPasteboardMimeTiff;
-#ifdef Q_WS_MAC32
- // 10.6 does automatic synthesis to and from PICT to standard image types (like TIFF),
- // so don't bother doing it ourselves, especially since it's not available in 64-bit.
- if (QSysInfo::MacintoshVersion < QSysInfo::MV_10_6)
- new QMacPasteboardMimePict;
-#endif
- new QMacPasteboardMimeUnicodeText;
- new QMacPasteboardMimePlainText;
- new QMacPasteboardMimeHTMLText;
- new QMacPasteboardMimeFileUri;
- new QMacPasteboardMimeUrl;
- new QMacPasteboardMimeTypeName;
- new QMacPasteboardMimeVCard;
- //make sure our "non-standard" types are always last! --Sam
- new QMacPasteboardMimeAny;
-#ifdef QT3_SUPPORT
- new QMacPasteboardMimeQt3Any;
-#endif
- }
-}
-
-/*!
- Returns the most-recently created QMacPasteboardMime of type \a t that can convert
- between the \a mime and \a flav formats. Returns 0 if no such convertor
- exists.
-*/
-QMacPasteboardMime*
-QMacPasteboardMime::convertor(uchar t, const QString &mime, QString flav)
-{
- MimeList *mimes = globalMimeList();
- for(MimeList::const_iterator it = mimes->constBegin(); it != mimes->constEnd(); ++it) {
-#ifdef DEBUG_MIME_MAPS
- qDebug("QMacPasteboardMime::convertor: seeing if %s (%d) can convert %s to %d[%c%c%c%c] [%d]",
- (*it)->convertorName().toLatin1().constData(),
- (*it)->type & t, mime.toLatin1().constData(),
- flav, (flav >> 24) & 0xFF, (flav >> 16) & 0xFF, (flav >> 8) & 0xFF, (flav) & 0xFF,
- (*it)->canConvert(mime,flav));
- for(int i = 0; i < (*it)->countFlavors(); ++i) {
- int f = (*it)->flavor(i);
- qDebug(" %d) %d[%c%c%c%c] [%s]", i, f,
- (f >> 24) & 0xFF, (f >> 16) & 0xFF, (f >> 8) & 0xFF, (f) & 0xFF,
- (*it)->convertorName().toLatin1().constData());
- }
-#endif
- if(((*it)->type & t) && (*it)->canConvert(mime, flav))
- return (*it);
- }
- return 0;
-}
-/*!
- Returns a MIME type of type \a t for \a flav, or 0 if none exists.
-*/
-QString QMacPasteboardMime::flavorToMime(uchar t, QString flav)
-{
- MimeList *mimes = globalMimeList();
- for(MimeList::const_iterator it = mimes->constBegin(); it != mimes->constEnd(); ++it) {
-#ifdef DEBUG_MIME_MAPS
- qDebug("QMacMIme::flavorToMime: attempting %s (%d) for flavor %d[%c%c%c%c] [%s]",
- (*it)->convertorName().toLatin1().constData(),
- (*it)->type & t, flav, (flav >> 24) & 0xFF, (flav >> 16) & 0xFF, (flav >> 8) & 0xFF, (flav) & 0xFF,
- (*it)->mimeFor(flav).toLatin1().constData());
-
-#endif
- if((*it)->type & t) {
- QString mimeType = (*it)->mimeFor(flav);
- if(!mimeType.isNull())
- return mimeType;
- }
- }
- return QString();
-}
-
-/*!
- Returns a list of all currently defined QMacPasteboardMime objects of type \a t.
-*/
-QList<QMacPasteboardMime*> QMacPasteboardMime::all(uchar t)
-{
- MimeList ret;
- MimeList *mimes = globalMimeList();
- for(MimeList::const_iterator it = mimes->constBegin(); it != mimes->constEnd(); ++it) {
- if((*it)->type & t)
- ret.append((*it));
- }
- return ret;
-}
-
-
-/*!
- \fn QString QMacPasteboardMime::convertorName()
-
- Returns a name for the convertor.
-
- All subclasses must reimplement this pure virtual function.
-*/
-
-/*!
- \fn bool QMacPasteboardMime::canConvert(const QString &mime, QString flav)
-
- Returns true if the convertor can convert (both ways) between
- \a mime and \a flav; otherwise returns false.
-
- All subclasses must reimplement this pure virtual function.
-*/
-
-/*!
- \fn QString QMacPasteboardMime::mimeFor(QString flav)
-
- Returns the MIME UTI used for Mac flavor \a flav, or 0 if this
- convertor does not support \a flav.
-
- All subclasses must reimplement this pure virtual function.
-*/
-
-/*!
- \fn QString QMacPasteboardMime::flavorFor(const QString &mime)
-
- Returns the Mac UTI used for MIME type \a mime, or 0 if this
- convertor does not support \a mime.
-
- All subclasses must reimplement this pure virtual function.
-*/
-
-/*!
- \fn QVariant QMacPasteboardMime::convertToMime(const QString &mime, QList<QByteArray> data, QString flav)
-
- Returns \a data converted from Mac UTI \a flav to MIME type \a
- mime.
-
- Note that Mac flavors must all be self-terminating. The input \a
- data may contain trailing data.
-
- All subclasses must reimplement this pure virtual function.
-*/
-
-/*!
- \fn QList<QByteArray> QMacPasteboardMime::convertFromMime(const QString &mime, QVariant data, QString flav)
-
- Returns \a data converted from MIME type \a mime
- to Mac UTI \a flav.
-
- Note that Mac flavors must all be self-terminating. The return
- value may contain trailing data.
-
- All subclasses must reimplement this pure virtual function.
-*/
-
-
-QT_END_NAMESPACE
diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp
new file mode 100644
index 0000000000..22d003d4e9
--- /dev/null
+++ b/src/gui/kernel/qopenglcontext.cpp
@@ -0,0 +1,605 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qplatformopenglcontext_qpa.h"
+#include "qopenglcontext.h"
+#include "qopenglcontext_p.h"
+#include "qwindow.h"
+
+#include <QtCore/QThreadStorage>
+#include <QtCore/QThread>
+
+#include <QtGui/private/qguiapplication_p.h>
+#include <QtGui/QScreen>
+
+#include <private/qopenglextensions_p.h>
+
+#include <QDebug>
+
+class QGuiGLThreadContext
+{
+public:
+ ~QGuiGLThreadContext() {
+ if (context)
+ context->doneCurrent();
+ }
+ QOpenGLContext *context;
+};
+
+static QThreadStorage<QGuiGLThreadContext *> qwindow_context_storage;
+
+void QOpenGLContextPrivate::setCurrentContext(QOpenGLContext *context)
+{
+ QGuiGLThreadContext *threadContext = qwindow_context_storage.localData();
+ if (!threadContext) {
+ if (!QThread::currentThread()) {
+ qWarning("No QTLS available. currentContext wont work");
+ return;
+ }
+ threadContext = new QGuiGLThreadContext;
+ qwindow_context_storage.setLocalData(threadContext);
+ }
+ threadContext->context = context;
+}
+
+/*!
+ Returns the last context which called makeCurrent. This function is thread aware.
+*/
+QOpenGLContext* QOpenGLContext::currentContext()
+{
+ QGuiGLThreadContext *threadContext = qwindow_context_storage.localData();
+ if(threadContext) {
+ return threadContext->context;
+ }
+ return 0;
+}
+
+bool QOpenGLContext::areSharing(QOpenGLContext *first, QOpenGLContext *second)
+{
+ return first->shareGroup() == second->shareGroup();
+}
+
+QPlatformOpenGLContext *QOpenGLContext::handle() const
+{
+ Q_D(const QOpenGLContext);
+ return d->platformGLContext;
+}
+
+QPlatformOpenGLContext *QOpenGLContext::shareHandle() const
+{
+ Q_D(const QOpenGLContext);
+ if (d->shareContext)
+ return d->shareContext->handle();
+ return 0;
+}
+
+/*!
+ Creates a new GL context instance, you need to call create() before it can be used.
+*/
+QOpenGLContext::QOpenGLContext(QObject *parent)
+ : QObject(*new QOpenGLContextPrivate(), parent)
+{
+ Q_D(QOpenGLContext);
+ d->screen = QGuiApplication::primaryScreen();
+}
+
+/*!
+ Sets the format the GL context should be compatible with. You need to call create() before it takes effect.
+*/
+void QOpenGLContext::setFormat(const QSurfaceFormat &format)
+{
+ Q_D(QOpenGLContext);
+ d->requestedFormat = format;
+}
+
+/*!
+ Sets the context to share textures, shaders, and other GL resources with. You need to call create() before it takes effect.
+*/
+void QOpenGLContext::setShareContext(QOpenGLContext *shareContext)
+{
+ Q_D(QOpenGLContext);
+ d->shareContext = shareContext;
+}
+
+/*!
+ Sets the screen the GL context should be valid for. You need to call create() before it takes effect.
+*/
+void QOpenGLContext::setScreen(QScreen *screen)
+{
+ Q_D(QOpenGLContext);
+ d->screen = screen;
+ if (!d->screen)
+ d->screen = QGuiApplication::primaryScreen();
+}
+
+/*!
+ Attempts to create the GL context with the desired parameters.
+
+ Returns true if the native context was successfully created and is ready to be used.
+*/
+bool QOpenGLContext::create()
+{
+ destroy();
+
+ Q_D(QOpenGLContext);
+ d->platformGLContext = QGuiApplicationPrivate::platformIntegration()->createPlatformOpenGLContext(this);
+ d->platformGLContext->setContext(this);
+ d->shareGroup = d->shareContext ? d->shareContext->shareGroup() : new QOpenGLContextGroup;
+ d->shareGroup->d_func()->addContext(this);
+ return d->platformGLContext;
+}
+
+void QOpenGLContext::destroy()
+{
+ Q_D(QOpenGLContext);
+ if (QOpenGLContext::currentContext() == this)
+ doneCurrent();
+ if (d->shareGroup)
+ d->shareGroup->d_func()->removeContext(this);
+ d->shareGroup = 0;
+ delete d->platformGLContext;
+ d->platformGLContext = 0;
+ delete d->functions;
+ d->functions = 0;
+}
+
+/*!
+ If this is the current context for the thread, doneCurrent is called
+*/
+QOpenGLContext::~QOpenGLContext()
+{
+ destroy();
+}
+
+/*!
+ Returns if this context is valid, i.e. has been successfully created.
+*/
+bool QOpenGLContext::isValid() const
+{
+ Q_D(const QOpenGLContext);
+ return d->platformGLContext != 0;
+}
+
+/*!
+ Get the QOpenGLFunctions instance for this context.
+
+ The context or a sharing context must be current.
+*/
+
+QOpenGLFunctions *QOpenGLContext::functions() const
+{
+ Q_D(const QOpenGLContext);
+ if (!d->functions)
+ const_cast<QOpenGLFunctions *&>(d->functions) = new QOpenGLExtensions(QOpenGLContext::currentContext());
+ return d->functions;
+}
+
+/*!
+ If surface is 0 this is equivalent to calling doneCurrent().
+
+ Do not call this function from a different thread than the one the QOpenGLContext instance lives in. If
+ you wish to use QOpenGLContext from a different thread you should first call make sure it's not current
+ in the current thread, by calling doneCurrent() if necessary. Then call moveToThread(otherThread)
+ before using it in the other thread.
+*/
+bool QOpenGLContext::makeCurrent(QSurface *surface)
+{
+ Q_D(QOpenGLContext);
+ if (!d->platformGLContext)
+ return false;
+
+ if (thread() != QThread::currentThread())
+ qFatal("Cannot make QOpenGLContext current in a different thread");
+
+ if (!surface) {
+ doneCurrent();
+ return true;
+ }
+
+ if (!surface->surfaceHandle())
+ return false;
+
+ if (d->platformGLContext->makeCurrent(surface->surfaceHandle())) {
+ QOpenGLContextPrivate::setCurrentContext(this);
+ d->surface = surface;
+
+ d->shareGroup->d_func()->deletePendingResources(this);
+
+ return true;
+ }
+
+ return false;
+}
+
+/*!
+ Convenience function for calling makeCurrent with a 0 surface.
+*/
+void QOpenGLContext::doneCurrent()
+{
+ Q_D(QOpenGLContext);
+ if (!d->platformGLContext)
+ return;
+
+ if (QOpenGLContext::currentContext() == this)
+ d->shareGroup->d_func()->deletePendingResources(this);
+
+ d->platformGLContext->doneCurrent();
+ QOpenGLContextPrivate::setCurrentContext(0);
+
+ d->surface = 0;
+}
+
+/*!
+ Returns the surface the context is current for.
+*/
+QSurface *QOpenGLContext::surface() const
+{
+ Q_D(const QOpenGLContext);
+ return d->surface;
+}
+
+
+void QOpenGLContext::swapBuffers(QSurface *surface)
+{
+ Q_D(QOpenGLContext);
+ if (!d->platformGLContext)
+ return;
+
+ if (!surface) {
+ qWarning() << "QOpenGLContext::swapBuffers() called with null argument";
+ return;
+ }
+
+ d->platformGLContext->swapBuffers(surface->surfaceHandle());
+}
+
+void (*QOpenGLContext::getProcAddress(const QByteArray &procName)) ()
+{
+ Q_D(QOpenGLContext);
+ if (!d->platformGLContext)
+ return 0;
+ return d->platformGLContext->getProcAddress(procName);
+}
+
+QSurfaceFormat QOpenGLContext::format() const
+{
+ Q_D(const QOpenGLContext);
+ if (!d->platformGLContext)
+ return d->requestedFormat;
+ return d->platformGLContext->format();
+}
+
+QOpenGLContextGroup *QOpenGLContext::shareGroup() const
+{
+ Q_D(const QOpenGLContext);
+ return d->shareGroup;
+}
+
+QOpenGLContext *QOpenGLContext::shareContext() const
+{
+ Q_D(const QOpenGLContext);
+ return d->shareContext;
+}
+
+QScreen *QOpenGLContext::screen() const
+{
+ Q_D(const QOpenGLContext);
+ return d->screen;
+}
+
+/*
+ internal: Needs to have a pointer to qGLContext. But since this is in QtGui we cant
+ have any type information.
+*/
+void *QOpenGLContext::qGLContextHandle() const
+{
+ Q_D(const QOpenGLContext);
+ return d->qGLContextHandle;
+}
+
+void QOpenGLContext::setQGLContextHandle(void *handle,void (*qGLContextDeleteFunction)(void *))
+{
+ Q_D(QOpenGLContext);
+ d->qGLContextHandle = handle;
+ d->qGLContextDeleteFunction = qGLContextDeleteFunction;
+}
+
+void QOpenGLContext::deleteQGLContext()
+{
+ Q_D(QOpenGLContext);
+ if (d->qGLContextDeleteFunction && d->qGLContextHandle) {
+ d->qGLContextDeleteFunction(d->qGLContextHandle);
+ d->qGLContextDeleteFunction = 0;
+ d->qGLContextHandle = 0;
+ }
+}
+
+QOpenGLContextGroup::QOpenGLContextGroup()
+ : QObject(*new QOpenGLContextGroupPrivate())
+{
+}
+
+QOpenGLContextGroup::~QOpenGLContextGroup()
+{
+ Q_D(QOpenGLContextGroup);
+ d->cleanup();
+}
+
+QList<QOpenGLContext *> QOpenGLContextGroup::shares() const
+{
+ Q_D(const QOpenGLContextGroup);
+ return d->m_shares;
+}
+
+QOpenGLContextGroup *QOpenGLContextGroup::currentContextGroup()
+{
+ QOpenGLContext *current = QOpenGLContext::currentContext();
+ return current ? current->shareGroup() : 0;
+}
+
+void QOpenGLContextGroupPrivate::addContext(QOpenGLContext *ctx)
+{
+ QMutexLocker locker(&m_mutex);
+ m_refs.ref();
+ m_shares << ctx;
+}
+
+void QOpenGLContextGroupPrivate::removeContext(QOpenGLContext *ctx)
+{
+ Q_Q(QOpenGLContextGroup);
+
+ QMutexLocker locker(&m_mutex);
+ m_shares.removeOne(ctx);
+
+ if (ctx == m_context && !m_shares.isEmpty())
+ m_context = m_shares.first();
+
+ if (!m_refs.deref()) {
+ cleanup();
+ q->deleteLater();
+ }
+}
+
+void QOpenGLContextGroupPrivate::cleanup()
+{
+ QList<QOpenGLSharedResource *>::iterator it = m_sharedResources.begin();
+ QList<QOpenGLSharedResource *>::iterator end = m_sharedResources.end();
+
+ while (it != end) {
+ (*it)->invalidateResource();
+ (*it)->m_group = 0;
+ ++it;
+ }
+
+ m_sharedResources.clear();
+
+ qDeleteAll(m_pendingDeletion.begin(), m_pendingDeletion.end());
+ m_pendingDeletion.clear();
+}
+
+void QOpenGLContextGroupPrivate::deletePendingResources(QOpenGLContext *ctx)
+{
+ QMutexLocker locker(&m_mutex);
+
+ QList<QOpenGLSharedResource *> pending = m_pendingDeletion;
+ m_pendingDeletion.clear();
+
+ QList<QOpenGLSharedResource *>::iterator it = pending.begin();
+ QList<QOpenGLSharedResource *>::iterator end = pending.end();
+ while (it != end) {
+ (*it)->freeResource(ctx);
+ delete *it;
+ ++it;
+ }
+}
+
+/*!
+ \class QOpenGLSharedResource
+ \internal
+ \since 5.0
+ \brief The QOpenGLSharedResource class is used to keep track of resources that
+ are shared between OpenGL contexts (like textures, framebuffer objects, shader
+ programs, etc), and clean them up in a safe way when they're no longer needed.
+
+ The QOpenGLSharedResource instance should never be deleted, instead free()
+ should be called when it's no longer needed. Thus it will be put on a queue
+ and freed at an appropriate time (when a context in the share group becomes
+ current).
+
+ The sub-class needs to implement two pure virtual functions. The first,
+ freeResource() must be implemented to actually do the freeing, for example
+ call glDeleteTextures() on a texture id. Qt makes sure a valid context in
+ the resource's share group is current at the time. The other, invalidateResource(),
+ is called by Qt in the circumstance when the last context in the share group is
+ destroyed before free() has been called. The implementation of invalidateResource()
+ should set any identifiers to 0 or set a flag to prevent them from being used
+ later on.
+*/
+QOpenGLSharedResource::QOpenGLSharedResource(QOpenGLContextGroup *group)
+ : m_group(group)
+{
+ QMutexLocker locker(&m_group->d_func()->m_mutex);
+ m_group->d_func()->m_sharedResources << this;
+}
+
+QOpenGLSharedResource::~QOpenGLSharedResource()
+{
+}
+
+// schedule the resource for deletion at an appropriate time
+void QOpenGLSharedResource::free()
+{
+ if (!m_group) {
+ delete this;
+ return;
+ }
+
+ QMutexLocker locker(&m_group->d_func()->m_mutex);
+ m_group->d_func()->m_sharedResources.removeOne(this);
+ m_group->d_func()->m_pendingDeletion << this;
+
+ // can we delete right away?
+ QOpenGLContext *current = QOpenGLContext::currentContext();
+ if (current && current->shareGroup() == m_group) {
+ m_group->d_func()->deletePendingResources(current);
+ }
+}
+
+/*!
+ \class QOpenGLSharedResourceGuard
+ \internal
+ \since 5.0
+ \brief The QOpenGLSharedResourceGuard class is a convenience sub-class of
+ QOpenGLSharedResource to be used to track a single OpenGL object with a
+ GLuint identifier. The constructor takes a function pointer to a function
+ that will be used to free the resource if and when necessary.
+*/
+void QOpenGLSharedResourceGuard::freeResource(QOpenGLContext *context)
+{
+ if (m_id) {
+ QOpenGLFunctions functions(context);
+ m_func(&functions, m_id);
+ m_id = 0;
+ }
+}
+
+/*!
+ \class QOpenGLMultiGroupSharedResource
+ \internal
+ \since 5.0
+ \brief The QOpenGLMultiGroupSharedResource keeps track of a shared resource
+ that might be needed from multiple contexts, like a glyph cache or gradient
+ cache. One instance of the object is created for each group when
+ necessary. The shared resource instance should have a constructor that
+ takes a QOpenGLContext *. To get an instance for a given context one calls
+ T *QOpenGLMultiGroupSharedResource::value<T>(context), where T is a sub-class
+ of QOpenGLSharedResource.
+
+ You should not call free() on QOpenGLSharedResources owned by a
+ QOpenGLMultiGroupSharedResource instance.
+*/
+QOpenGLMultiGroupSharedResource::QOpenGLMultiGroupSharedResource()
+ : active(0)
+{
+#ifdef QT_GL_CONTEXT_RESOURCE_DEBUG
+ qDebug("Creating context group resource object %p.", this);
+#endif
+}
+
+QOpenGLMultiGroupSharedResource::~QOpenGLMultiGroupSharedResource()
+{
+#ifdef QT_GL_CONTEXT_RESOURCE_DEBUG
+ qDebug("Deleting context group resource %p. Group size: %d.", this, m_groups.size());
+#endif
+ for (int i = 0; i < m_groups.size(); ++i) {
+ if (!m_groups.at(i)->shares().isEmpty()) {
+ QOpenGLContext *context = m_groups.at(i)->shares().first();
+ QOpenGLSharedResource *resource = value(context);
+ if (resource)
+ resource->free();
+ }
+ m_groups.at(i)->d_func()->m_resources.remove(this);
+ active.deref();
+ }
+#ifndef QT_NO_DEBUG
+ if (active != 0) {
+ qWarning("QtGui: Resources are still available at program shutdown.\n"
+ " This is possibly caused by a leaked QOpenGLWidget, \n"
+ " QOpenGLFramebufferObject or QOpenGLPixelBuffer.");
+ }
+#endif
+}
+
+void QOpenGLMultiGroupSharedResource::insert(QOpenGLContext *context, QOpenGLSharedResource *value)
+{
+#ifdef QT_GL_CONTEXT_RESOURCE_DEBUG
+ qDebug("Inserting context group resource %p for context %p, managed by %p.", value, context, this);
+#endif
+ QOpenGLContextGroup *group = context->shareGroup();
+ Q_ASSERT(!group->d_func()->m_resources.contains(this));
+ group->d_func()->m_resources.insert(this, value);
+ m_groups.append(group);
+ active.ref();
+}
+
+QOpenGLSharedResource *QOpenGLMultiGroupSharedResource::value(QOpenGLContext *context)
+{
+ QOpenGLContextGroup *group = context->shareGroup();
+ return group->d_func()->m_resources.value(this, 0);
+}
+
+QList<QOpenGLSharedResource *> QOpenGLMultiGroupSharedResource::resources() const
+{
+ QList<QOpenGLSharedResource *> result;
+ for (QList<QOpenGLContextGroup *>::const_iterator it = m_groups.constBegin(); it != m_groups.constEnd(); ++it) {
+ QOpenGLSharedResource *resource = (*it)->d_func()->m_resources.value(const_cast<QOpenGLMultiGroupSharedResource *>(this), 0);
+ if (resource)
+ result << resource;
+ }
+ return result;
+}
+
+void QOpenGLMultiGroupSharedResource::cleanup(QOpenGLContext *ctx)
+{
+ QOpenGLSharedResource *resource = value(ctx);
+
+ if (resource != 0) {
+ resource->free();
+
+ QOpenGLContextGroup *group = ctx->shareGroup();
+ group->d_func()->m_resources.remove(this);
+ m_groups.removeOne(group);
+ active.deref();
+ }
+}
+
+void QOpenGLMultiGroupSharedResource::cleanup(QOpenGLContext *ctx, QOpenGLSharedResource *value)
+{
+#ifdef QT_GL_CONTEXT_RESOURCE_DEBUG
+ qDebug("Cleaning up context group resource %p, for context %p in thread %p.", this, ctx, QThread::currentThread());
+#endif
+ value->free();
+ active.deref();
+
+ QOpenGLContextGroup *group = ctx->shareGroup();
+ m_groups.removeOne(group);
+}
+
diff --git a/src/gui/kernel/qopenglcontext.h b/src/gui/kernel/qopenglcontext.h
new file mode 100644
index 0000000000..b5a19a0ebc
--- /dev/null
+++ b/src/gui/kernel/qopenglcontext.h
@@ -0,0 +1,146 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QOPENGLCONTEXT_H
+#define QOPENGLCONTEXT_H
+
+#include <QtCore/qnamespace.h>
+#include <QtCore/QObject>
+#include <QtCore/QScopedPointer>
+
+#include <QtGui/QSurfaceFormat>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QOpenGLContextPrivate;
+class QOpenGLContextGroupPrivate;
+class QOpenGLFunctions;
+class QPlatformOpenGLContext;
+
+class QScreen;
+class QSurface;
+
+class Q_GUI_EXPORT QOpenGLContextGroup : public QObject
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QOpenGLContextGroup)
+public:
+ ~QOpenGLContextGroup();
+
+ QList<QOpenGLContext *> shares() const;
+
+ static QOpenGLContextGroup *currentContextGroup();
+
+private:
+ QOpenGLContextGroup();
+
+ friend class QOpenGLContext;
+ friend class QOpenGLContextGroupResourceBase;
+ friend class QOpenGLSharedResource;
+ friend class QOpenGLMultiGroupSharedResource;
+};
+
+class Q_GUI_EXPORT QOpenGLContext : public QObject
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QOpenGLContext)
+public:
+ QOpenGLContext(QObject *parent = 0);
+ ~QOpenGLContext();
+
+ void setFormat(const QSurfaceFormat &format);
+ void setShareContext(QOpenGLContext *shareContext);
+ void setScreen(QScreen *screen);
+
+ bool create();
+ bool isValid() const;
+
+ QSurfaceFormat format() const;
+ QOpenGLContext *shareContext() const;
+ QOpenGLContextGroup *shareGroup() const;
+ QScreen *screen() const;
+
+ bool makeCurrent(QSurface *surface);
+ void doneCurrent();
+
+ void swapBuffers(QSurface *surface);
+ void (*getProcAddress(const QByteArray &procName)) ();
+
+ QSurface *surface() const;
+
+ static QOpenGLContext *currentContext();
+ static bool areSharing(QOpenGLContext *first, QOpenGLContext *second);
+
+ QPlatformOpenGLContext *handle() const;
+ QPlatformOpenGLContext *shareHandle() const;
+
+ QOpenGLFunctions *functions() const;
+
+private:
+ friend class QGLContext;
+ friend class QOpenGLContextResourceBase;
+ friend class QOpenGLPaintDevice;
+ friend class QOpenGLGlyphTexture;
+ friend class QOpenGLTextureGlyphCache;
+ friend class QOpenGLEngineShaderManager;
+ friend class QOpenGLFramebufferObject;
+ friend class QOpenGLFramebufferObjectPrivate;
+ friend class QOpenGL2PaintEngineEx;
+ friend class QOpenGL2PaintEngineExPrivate;
+ friend class QSGDistanceFieldGlyphCache;
+ friend class QWidgetPrivate;
+
+ void *qGLContextHandle() const;
+ void setQGLContextHandle(void *handle,void (*qGLContextDeleteFunction)(void *));
+ void deleteQGLContext();
+
+ void destroy();
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QGUIGLCONTEXT_H
diff --git a/src/gui/kernel/qopenglcontext_p.h b/src/gui/kernel/qopenglcontext_p.h
new file mode 100644
index 0000000000..059872c09f
--- /dev/null
+++ b/src/gui/kernel/qopenglcontext_p.h
@@ -0,0 +1,234 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGUIGLCONTEXT_P_H
+#define QGUIGLCONTEXT_P_H
+
+#include "qopengl.h"
+#include "qopenglcontext.h"
+#include <private/qobject_p.h>
+#include <qmutex.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QOpenGLFunctions;
+class QOpenGLContext;
+class QOpenGLMultiGroupSharedResource;
+
+class Q_GUI_EXPORT QOpenGLSharedResource
+{
+public:
+ QOpenGLSharedResource(QOpenGLContextGroup *group);
+ virtual ~QOpenGLSharedResource() = 0;
+
+ QOpenGLContextGroup *group() const { return m_group; }
+
+ // schedule the resource for deletion at an appropriate time
+ void free();
+
+protected:
+ // the resource's share group no longer exists, invalidate the resource
+ virtual void invalidateResource() = 0;
+
+ // a valid context in the group is current, free the resource
+ virtual void freeResource(QOpenGLContext *context) = 0;
+
+private:
+ QOpenGLContextGroup *m_group;
+
+ friend class QOpenGLContextGroup;
+ friend class QOpenGLContextGroupPrivate;
+
+ Q_DISABLE_COPY(QOpenGLSharedResource);
+};
+
+class Q_GUI_EXPORT QOpenGLSharedResourceGuard : public QOpenGLSharedResource
+{
+public:
+ typedef void (*FreeResourceFunc)(QOpenGLFunctions *functions, GLuint id);
+ QOpenGLSharedResourceGuard(QOpenGLContext *context, GLuint id, FreeResourceFunc func)
+ : QOpenGLSharedResource(context->shareGroup())
+ , m_id(id)
+ , m_func(func)
+ {
+ }
+
+ GLuint id() const { return m_id; }
+
+protected:
+ void invalidateResource()
+ {
+ m_id = 0;
+ }
+
+ void freeResource(QOpenGLContext *context);
+
+private:
+ GLuint m_id;
+ FreeResourceFunc m_func;
+};
+
+class Q_GUI_EXPORT QOpenGLContextGroupPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QOpenGLContextGroup);
+public:
+ QOpenGLContextGroupPrivate()
+ : m_context(0)
+ , m_mutex(QMutex::Recursive)
+ , m_refs(0)
+ {
+ }
+
+ void addContext(QOpenGLContext *ctx);
+ void removeContext(QOpenGLContext *ctx);
+
+ void cleanup();
+
+ void deletePendingResources(QOpenGLContext *ctx);
+
+ QOpenGLContext *m_context;
+
+ QList<QOpenGLContext *> m_shares;
+ QMutex m_mutex;
+
+ QHash<QOpenGLMultiGroupSharedResource *, QOpenGLSharedResource *> m_resources;
+ QAtomicInt m_refs;
+
+ QList<QOpenGLSharedResource *> m_sharedResources;
+ QList<QOpenGLSharedResource *> m_pendingDeletion;
+
+ void cleanupResources(QOpenGLContext *ctx);
+};
+
+class Q_GUI_EXPORT QOpenGLMultiGroupSharedResource
+{
+public:
+ QOpenGLMultiGroupSharedResource();
+ ~QOpenGLMultiGroupSharedResource();
+
+ void insert(QOpenGLContext *context, QOpenGLSharedResource *value);
+ void cleanup(QOpenGLContext *context);
+ void cleanup(QOpenGLContext *context, QOpenGLSharedResource *value);
+
+ QOpenGLSharedResource *value(QOpenGLContext *context);
+
+ QList<QOpenGLSharedResource *> resources() const;
+
+ template <typename T>
+ T *value(QOpenGLContext *context) {
+ QOpenGLContextGroup *group = context->shareGroup();
+ T *resource = static_cast<T *>(group->d_func()->m_resources.value(this, 0));
+ if (!resource) {
+ resource = new T(context);
+ insert(context, resource);
+ }
+ return resource;
+ }
+
+private:
+ QAtomicInt active;
+ QList<QOpenGLContextGroup *> m_groups;
+};
+
+class QPaintEngineEx;
+class QOpenGLFunctions;
+
+class Q_GUI_EXPORT QOpenGLContextPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QOpenGLContext)
+public:
+ QOpenGLContextPrivate()
+ : qGLContextHandle(0)
+ , platformGLContext(0)
+ , shareContext(0)
+ , shareGroup(0)
+ , screen(0)
+ , surface(0)
+ , functions(0)
+ , current_fbo(0)
+ , default_fbo(0)
+ , workaround_brokenFBOReadBack(false)
+ , workaround_brokenTexSubImage(false)
+ , active_engine(0)
+ {
+ }
+
+ virtual ~QOpenGLContextPrivate()
+ {
+ //do not delete the QOpenGLContext handle here as it is deleted in
+ //QWidgetPrivate::deleteTLSysExtra()
+ }
+
+ void *qGLContextHandle;
+ void (*qGLContextDeleteFunction)(void *handle);
+
+ QSurfaceFormat requestedFormat;
+ QPlatformOpenGLContext *platformGLContext;
+ QOpenGLContext *shareContext;
+ QOpenGLContextGroup *shareGroup;
+ QScreen *screen;
+ QSurface *surface;
+ QOpenGLFunctions *functions;
+
+ GLuint current_fbo;
+ GLuint default_fbo;
+
+ bool workaround_brokenFBOReadBack;
+ bool workaround_brokenTexSubImage;
+
+ QPaintEngineEx *active_engine;
+
+ QHash<QOpenGLMultiGroupSharedResource *, void *> m_resources;
+
+ static void setCurrentContext(QOpenGLContext *context);
+
+ int maxTextureSize() const { return 1024; }
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QGUIGLCONTEXT_P_H
diff --git a/src/gui/kernel/qpalette.cpp b/src/gui/kernel/qpalette.cpp
index ed483d95ff..404faea25f 100644
--- a/src/gui/kernel/qpalette.cpp
+++ b/src/gui/kernel/qpalette.cpp
@@ -40,7 +40,7 @@
****************************************************************************/
#include "qpalette.h"
-#include "qapplication.h"
+#include "qguiapplication.h"
#include "qdatastream.h"
#include "qvariant.h"
@@ -63,103 +63,6 @@ static QColor qt_mix_colors(QColor a, QColor b)
(a.blue() + b.blue()) / 2, (a.alpha() + b.alpha()) / 2);
}
-#ifdef QT3_SUPPORT
-
-#ifndef QT_NO_DATASTREAM
-QDataStream &qt_stream_out_qcolorgroup(QDataStream &s, const QColorGroup &g)
-{
- if(s.version() == 1) {
- // Qt 1.x
- s << g.color(QPalette::Foreground) << g.color(QPalette::Background)
- << g.color(QPalette::Light) << g.color(QPalette::Dark)
- << g.color(QPalette::Mid) << g.color(QPalette::Text) << g.color(QPalette::Base);
- } else {
- int max = QPalette::NColorRoles;
- if (s.version() <= QDataStream::Qt_2_1)
- max = QPalette::HighlightedText + 1;
- else if (s.version() <= QDataStream::Qt_4_3)
- max = QPalette::AlternateBase + 1;
- for(int r = 0 ; r < max ; r++)
- s << g.brush((QPalette::ColorRole)r);
- }
- return s;
-}
-
-QDataStream &qt_stream_in_qcolorgroup(QDataStream &s, QColorGroup &g)
-{
- if(s.version() == 1) { // Qt 1.x
- QColor fg, bg, light, dark, mid, text, base;
- s >> fg >> bg >> light >> dark >> mid >> text >> base;
- QPalette p(bg);
- p.setColor(QPalette::Active, QPalette::Foreground, fg);
- p.setColor(QPalette::Active, QPalette::Light, light);
- p.setColor(QPalette::Active, QPalette::Dark, dark);
- p.setColor(QPalette::Active, QPalette::Mid, mid);
- p.setColor(QPalette::Active, QPalette::Text, text);
- p.setColor(QPalette::Active, QPalette::Base, base);
- g = p;
- g.setCurrentColorGroup(QPalette::Active);
- } else {
- int max = QPalette::NColorRoles;
- if (s.version() <= QDataStream::Qt_2_1)
- max = QPalette::HighlightedText + 1;
- else if (s.version() <= QDataStream::Qt_3_0)
- max = QPalette::LinkVisited + 1;
- else if (s.version() <= QDataStream::Qt_4_3)
- max = QPalette::AlternateBase + 1;
- QBrush tmp;
- for(int r = 0 ; r < max; r++) {
- s >> tmp;
- g.setBrush((QPalette::ColorRole)r, tmp);
- }
- }
- return s;
-}
-
-QDataStream &operator<<(QDataStream &s, const QColorGroup &g)
-{
- return qt_stream_out_qcolorgroup(s, g);
-}
-
-QDataStream &operator>>(QDataStream &s, QColorGroup &g)
-{
- return qt_stream_in_qcolorgroup(s, g);
-}
-#endif // QT_NO_DATASTREAM
-
-/*!
- Constructs a palette with the specified \a active, \a disabled and
- \a inactive color groups.
-*/
-QPalette::QPalette(const QColorGroup &active, const QColorGroup &disabled,
- const QColorGroup &inactive)
-{
- Q_ASSERT(QPalette::NColorRoles == QPalette::ToolTipText + 1);
- init();
- setColorGroup(Active, active);
- setColorGroup(Disabled, disabled);
- setColorGroup(Inactive, inactive);
-}
-
-QColorGroup QPalette::createColorGroup(ColorGroup cr) const
-{
- QColorGroup ret(*this);
- ret.setCurrentColorGroup(cr);
- return ret;
-}
-
-void QPalette::setColorGroup(ColorGroup cg, const QColorGroup &g)
-{
- setColorGroup(cg, g.brush(WindowText), g.brush(Button), g.brush(Light),
- g.brush(Dark), g.brush(Mid), g.brush(Text), g.brush(BrightText),
- g.brush(Base), g.brush(AlternateBase), g.brush(Window),
- g.brush(Midlight), g.brush(ButtonText), g.brush(Shadow),
- g.brush(Highlight), g.brush(HighlightedText), g.brush(Link),
- g.brush(LinkVisited), g.brush(ToolTipBase), g.brush(ToolTipText));
-}
-
-#endif // QT3_SUPPORT
-
/*!
\fn const QColor &QPalette::color(ColorRole role) const
@@ -433,7 +336,7 @@ void QPalette::setColorGroup(ColorGroup cg, const QColorGroup &g)
roles are enumerated and defined in the \l ColorRole documentation.
We strongly recommend that you use the default palette of the
- current style (returned by QApplication::palette()) and
+ current style (returned by QGuiApplication::palette()) and
modify that as necessary. This is done by Qt's widgets when they
are drawn.
@@ -584,7 +487,7 @@ void QPalette::setColorGroup(ColorGroup cg, const QColorGroup &g)
\sa QApplication::setPalette(), QApplication::palette()
*/
QPalette::QPalette()
- : d(QApplication::palette().d),
+ : d(QGuiApplication::palette().d),
current_group(Active),
resolve_mask(0)
{
@@ -897,27 +800,6 @@ bool QPalette::operator==(const QPalette &p) const
return true;
}
-#ifdef QT3_SUPPORT
-bool QColorGroup::operator==(const QColorGroup &other) const
-{
- if (isCopyOf(other))
- return true;
- for (int role = 0; role < int(NColorRoles); role++) {
- if(d->br[current_group][role] != other.d->br[other.current_group][role])
- return false;
- }
- return true;
-}
-
-/*!
- Returns the color group as a QVariant
-*/
-QColorGroup::operator QVariant() const
-{
- return QVariant(QVariant::ColorGroup, this);
-}
-#endif
-
/*!
\fn bool QPalette::isEqual(ColorGroup cg1, ColorGroup cg2) const
@@ -1205,75 +1087,5 @@ void QPalette::setColorGroup(ColorGroup cg, const QBrush &foreground, const QBru
Use simple assignment instead.
*/
-/*!
- \fn QColorGroup QPalette::normal() const
- \obsolete
-
- Returns the active color group. Use active() instead.
-
- Use createColorGroup(Active) instead.
-*/
-
-/*!
- \fn void QPalette::setNormal(const QColorGroup &colorGroup)
-
- Sets the normal color group to \a colorGroup.
-
- \sa QColorGroup
-*/
-
-/*!
- \fn QColorGroup QPalette::active() const
-
- Returns the active color group.
- \sa QColorGroup
-*/
-
-/*!
- \fn QColorGroup QPalette::disabled() const
-
- Returns the disabled color group.
- \sa QColorGroup
-*/
-
-/*!
- \fn QColorGroup QPalette::inactive() const
-
- Returns the inactive color group.
- \sa QColorGroup
-*/
-
-/*!
- \fn void QPalette::setActive(const QColorGroup &colorGroup)
-
- Sets the active color group to \a colorGroup.
- \sa QColorGroup
-*/
-
-/*!
- \fn void QPalette::setDisabled(const QColorGroup &colorGroup)
-
- Sets the disabled color group to \a colorGroup.
- \sa QColorGroup
-*/
-
-/*!
- \fn void QPalette::setInactive(const QColorGroup &colorGroup)
-
- Sets the inactive color group.
- \sa QColorGroup
-*/
-
-/*! \fn bool QColorGroup::operator==(const QColorGroup &other) const
-
- Returns true if this color group is equal to \a other; otherwise
- returns false.
-*/
-
-/*! \fn bool QColorGroup::operator!=(const QColorGroup &other) const
-
- Returns true if this color group is not equal to \a other;
- otherwise returns false.
-*/
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qpalette.h b/src/gui/kernel/qpalette.h
index 671a56cd78..dd59d121a0 100644
--- a/src/gui/kernel/qpalette.h
+++ b/src/gui/kernel/qpalette.h
@@ -52,9 +52,6 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Gui)
-#ifdef QT3_SUPPORT
-class QColorGroup;
-#endif
class QPalettePrivate;
class QVariant;
@@ -72,9 +69,6 @@ public:
const QBrush &bright_text, const QBrush &base, const QBrush &window);
QPalette(const QColor &windowText, const QColor &window, const QColor &light,
const QColor &dark, const QColor &mid, const QColor &text, const QColor &base);
-#ifdef QT3_SUPPORT
- QT3_SUPPORT_CONSTRUCTOR QPalette(const QColorGroup &active, const QColorGroup &disabled, const QColorGroup &inactive);
-#endif
QPalette(const QPalette &palette);
~QPalette();
QPalette &operator=(const QPalette &palette);
@@ -142,19 +136,6 @@ public:
inline const QBrush &link() const { return brush(Link); }
inline const QBrush &linkVisited() const { return brush(LinkVisited); }
-#ifdef QT3_SUPPORT
- inline QT3_SUPPORT QPalette copy() const { QPalette p = *this; p.detach(); return p; }
- QT3_SUPPORT QColorGroup normal() const;
- inline QT3_SUPPORT void setNormal(const QColorGroup &cg) { setColorGroup(Active, cg); }
-
- QT3_SUPPORT QColorGroup active() const;
- QT3_SUPPORT QColorGroup disabled() const;
- QT3_SUPPORT QColorGroup inactive() const;
- inline QT3_SUPPORT void setActive(const QColorGroup &cg) { setColorGroup(Active, cg); }
- inline QT3_SUPPORT void setDisabled(const QColorGroup &cg) { setColorGroup(Disabled, cg); }
- inline QT3_SUPPORT void setInactive(const QColorGroup &cg) { setColorGroup(Inactive, cg); }
-#endif
-
bool operator==(const QPalette &p) const;
inline bool operator!=(const QPalette &p) const { return !(operator==(p)); }
bool isCopyOf(const QPalette &p) const;
@@ -184,11 +165,6 @@ private:
const QBrush &highlight, const QBrush &highlighted_text,
const QBrush &link, const QBrush &link_visited,
const QBrush &toolTipBase, const QBrush &toolTipText);
-#ifdef QT3_SUPPORT
- friend class QColorGroup;
- void setColorGroup(ColorGroup, const QColorGroup &);
- QColorGroup createColorGroup(ColorGroup) const;
-#endif
void init();
void detach();
@@ -206,55 +182,6 @@ inline void QPalette::setColor(ColorRole acr, const QColor &acolor)
inline void QPalette::setBrush(ColorRole acr, const QBrush &abrush)
{ setBrush(All, acr, abrush); }
-#ifdef QT3_SUPPORT
-class Q_GUI_EXPORT QColorGroup : public QPalette
-{
-public:
- inline QColorGroup() : QPalette() {}
- inline QColorGroup(const QBrush &foreground, const QBrush &button, const QBrush &light,
- const QBrush &dark, const QBrush &mid, const QBrush &text,
- const QBrush &bright_text, const QBrush &base, const QBrush &background)
- : QPalette(foreground, button, light, dark, mid, text, bright_text, base, background)
- {}
- inline QColorGroup(const QColor &foreground, const QColor &background, const QColor &light,
- const QColor &dark, const QColor &mid, const QColor &text, const QColor &base)
- : QPalette(foreground, background, light, dark, mid, text, base) {}
- inline QColorGroup(const QColorGroup &cg) : QPalette(cg) {}
- inline QColorGroup(const QPalette &pal) : QPalette(pal) {}
- bool operator==(const QColorGroup &other) const;
- inline bool operator!=(const QColorGroup &other) const { return !(operator==(other)); }
- operator QVariant() const;
-
- inline QT3_SUPPORT const QColor &foreground() const { return color(WindowText); }
- inline QT3_SUPPORT const QColor &button() const { return color(Button); }
- inline QT3_SUPPORT const QColor &light() const { return color(Light); }
- inline QT3_SUPPORT const QColor &dark() const { return color(Dark); }
- inline QT3_SUPPORT const QColor &mid() const { return color(Mid); }
- inline QT3_SUPPORT const QColor &text() const { return color(Text); }
- inline QT3_SUPPORT const QColor &base() const { return color(Base); }
- inline QT3_SUPPORT const QColor &background() const { return color(Window); }
- inline QT3_SUPPORT const QColor &midlight() const { return color(Midlight); }
- inline QT3_SUPPORT const QColor &brightText() const { return color(BrightText); }
- inline QT3_SUPPORT const QColor &buttonText() const { return color(ButtonText); }
- inline QT3_SUPPORT const QColor &shadow() const { return color(Shadow); }
- inline QT3_SUPPORT const QColor &highlight() const { return color(Highlight); }
- inline QT3_SUPPORT const QColor &highlightedText() const { return color(HighlightedText); }
- inline QT3_SUPPORT const QColor &link() const { return color(Link); }
- inline QT3_SUPPORT const QColor &linkVisited() const { return color(LinkVisited); }
-};
-
-#ifndef QT_NO_DATASTREAM
-Q_GUI_EXPORT QT3_SUPPORT QDataStream &operator<<(QDataStream &ds, const QColorGroup &cg);
-Q_GUI_EXPORT QT3_SUPPORT QDataStream &operator>>(QDataStream &ds, QColorGroup &cg);
-#endif
-
-inline QColorGroup QPalette::inactive() const { return createColorGroup(Inactive); }
-inline QColorGroup QPalette::disabled() const { return createColorGroup(Disabled); }
-inline QColorGroup QPalette::active() const { return createColorGroup(Active); }
-inline QColorGroup QPalette::normal() const { return createColorGroup(Active); }
-
-#endif
-
/*****************************************************************************
QPalette stream functions
*****************************************************************************/
diff --git a/src/gui/kernel/qplatformclipboard_qpa.cpp b/src/gui/kernel/qplatformclipboard_qpa.cpp
index f8e4b629b6..66693409d1 100644
--- a/src/gui/kernel/qplatformclipboard_qpa.cpp
+++ b/src/gui/kernel/qplatformclipboard_qpa.cpp
@@ -42,7 +42,7 @@
#ifndef QT_NO_CLIPBOARD
-#include <QtGui/private/qapplication_p.h>
+#include <QtGui/private/qguiapplication_p.h>
QT_BEGIN_NAMESPACE
@@ -102,9 +102,15 @@ bool QPlatformClipboard::supportsMode(QClipboard::Mode mode) const
return mode == QClipboard::Clipboard;
}
+bool QPlatformClipboard::ownsMode(QClipboard::Mode mode) const
+{
+ Q_UNUSED(mode);
+ return false;
+}
+
void QPlatformClipboard::emitChanged(QClipboard::Mode mode)
{
- QApplication::clipboard()->emitChanged(mode);
+ QGuiApplication::clipboard()->emitChanged(mode);
}
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qplatformclipboard_qpa.h b/src/gui/kernel/qplatformclipboard_qpa.h
index 6a40fbc86c..fc0505b87e 100644
--- a/src/gui/kernel/qplatformclipboard_qpa.h
+++ b/src/gui/kernel/qplatformclipboard_qpa.h
@@ -62,6 +62,7 @@ public:
virtual QMimeData *mimeData(QClipboard::Mode mode = QClipboard::Clipboard);
virtual void setMimeData(QMimeData *data, QClipboard::Mode mode = QClipboard::Clipboard);
virtual bool supportsMode(QClipboard::Mode mode) const;
+ virtual bool ownsMode(QClipboard::Mode mode) const;
void emitChanged(QClipboard::Mode mode);
};
diff --git a/src/gui/kernel/qplatformcursor_qpa.cpp b/src/gui/kernel/qplatformcursor_qpa.cpp
index 06954864f2..56d2847cfb 100644
--- a/src/gui/kernel/qplatformcursor_qpa.cpp
+++ b/src/gui/kernel/qplatformcursor_qpa.cpp
@@ -40,10 +40,10 @@
****************************************************************************/
#include "qplatformcursor_qpa.h"
-#include <QWidget>
#include <QPainter>
#include <QBitmap>
-#include <QApplication>
+#include <QGuiApplication>
+#include <private/qguiapplication_p.h>
#include <QDebug>
@@ -99,6 +99,18 @@ QPlatformCursor::QPlatformCursor(QPlatformScreen *scr )
QPlatformCursorPrivate::instances.append(this);
}
+QPoint QPlatformCursor::pos() const
+{
+ // As a fallback return the last mouse position seen by QGuiApplication.
+ return QGuiApplicationPrivate::lastCursorPosition.toPoint();
+}
+
+void QPlatformCursor::setPos(const QPoint &pos)
+{
+ Q_UNUSED(pos);
+ qWarning("This plugin does not support QCursor::setPos()");
+}
+
// End of display and pointer event handling code
// Beginning of built-in cursor graphics
// from src/gui/embedded/QGraphicsSystemCursorImage_qws.cpp
@@ -566,7 +578,7 @@ void QPlatformCursorImage::set(const uchar *data, const uchar *mask,
if (!width || !height || !data || !mask || cursorImage.isNull())
return;
- cursorImage.setNumColors(3);
+ cursorImage.setColorCount(3);
cursorImage.setColor(0, 0xff000000);
cursorImage.setColor(1, 0xffffffff);
cursorImage.setColor(2, 0x00000000);
diff --git a/src/gui/kernel/qplatformcursor_qpa.h b/src/gui/kernel/qplatformcursor_qpa.h
index 852a369b36..af40c7d1c0 100644
--- a/src/gui/kernel/qplatformcursor_qpa.h
+++ b/src/gui/kernel/qplatformcursor_qpa.h
@@ -73,7 +73,7 @@ private:
class QPlatformCursor;
-class QPlatformCursorPrivate {
+class Q_GUI_EXPORT QPlatformCursorPrivate {
public:
static QList<QWeakPointer<QPlatformCursor> > getInstances() { return instances; }
static QList<QWeakPointer<QPlatformCursor> > instances;
@@ -85,7 +85,9 @@ public:
// input methods
virtual void pointerEvent(const QMouseEvent & event) { Q_UNUSED(event); }
- virtual void changeCursor(QCursor * widgetCursor, QWidget * widget) = 0;
+ virtual void changeCursor(QCursor * widgetCursor, QWindow * widget) = 0;
+ virtual QPoint pos() const;
+ virtual void setPos(const QPoint &pos);
protected:
QPlatformScreen* screen; // Where to request an update
diff --git a/src/gui/kernel/qplatformdrag_qpa.h b/src/gui/kernel/qplatformdrag_qpa.h
new file mode 100644
index 0000000000..eac17ed2a6
--- /dev/null
+++ b/src/gui/kernel/qplatformdrag_qpa.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPLATFORMDRAG_H
+#define QPLATFORMDRAG_H
+
+#include <qglobal.h>
+
+QT_BEGIN_NAMESPACE
+
+class QMimeData;
+class QMouseEvent;
+
+class QPlatformDrag
+{
+public:
+ virtual ~QPlatformDrag() {}
+
+ virtual QMimeData *platformDropData() = 0;
+
+ virtual void startDrag() {};
+ virtual void move(const QMouseEvent *me) = 0;
+ virtual void drop(const QMouseEvent *me) = 0;
+ virtual void cancel() = 0;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/gui/kernel/qplatformeventloopintegration_qpa.cpp b/src/gui/kernel/qplatformeventloopintegration_qpa.cpp
deleted file mode 100644
index a79b03eee4..0000000000
--- a/src/gui/kernel/qplatformeventloopintegration_qpa.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qplatformeventloopintegration_qpa.h"
-
-#include <QtCore/QCoreApplication>
-
-#include <QtCore/QDebug>
-
-class QPlatformEventLoopIntegrationPrivate
-{
-public:
- QPlatformEventLoopIntegrationPrivate();
- qint64 nextTimerEvent;
-};
-
-QPlatformEventLoopIntegrationPrivate::QPlatformEventLoopIntegrationPrivate()
- : nextTimerEvent(0)
-{
-}
-
-QPlatformEventLoopIntegration::QPlatformEventLoopIntegration()
- : d_ptr(new QPlatformEventLoopIntegrationPrivate)
-
-{
-}
-
-QPlatformEventLoopIntegration::~QPlatformEventLoopIntegration()
-{
-}
-
-qint64 QPlatformEventLoopIntegration::nextTimerEvent() const
-{
- Q_D(const QPlatformEventLoopIntegration);
- return d->nextTimerEvent;
-}
-
-
-void QPlatformEventLoopIntegration::setNextTimerEvent(qint64 nextTimerEvent)
-{
- Q_D(QPlatformEventLoopIntegration);
- d->nextTimerEvent = nextTimerEvent;
-}
-
-void QPlatformEventLoopIntegration::processEvents()
-{
- QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents);
-}
diff --git a/src/gui/kernel/qplatformeventloopintegration_qpa.h b/src/gui/kernel/qplatformeventloopintegration_qpa.h
deleted file mode 100644
index 16a7cfdc6c..0000000000
--- a/src/gui/kernel/qplatformeventloopintegration_qpa.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPLATFORMEVENTLOOPINTEGRATION_QPA_H
-#define QPLATFORMEVENTLOOPINTEGRATION_QPA_H
-
-#include <QtCore/qglobal.h>
-#include <QtCore/QScopedPointer>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QPlatformEventLoopIntegrationPrivate;
-
-class Q_GUI_EXPORT QPlatformEventLoopIntegration
-{
- Q_DECLARE_PRIVATE(QPlatformEventLoopIntegration);
-public:
- QPlatformEventLoopIntegration();
- virtual ~QPlatformEventLoopIntegration();
-
- virtual void startEventLoop() = 0;
- virtual void quitEventLoop() = 0;
- virtual void qtNeedsToProcessEvents() = 0;
-
- qint64 nextTimerEvent() const;
- void setNextTimerEvent(qint64 nextTimerEvent);
-
- static void processEvents();
-protected:
- QScopedPointer<QPlatformEventLoopIntegrationPrivate> d_ptr;
-private:
- Q_DISABLE_COPY(QPlatformEventLoopIntegration);
- friend class QEventDispatcherQPA;
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QPLATFORMEVENTLOOPINTEGRATION_QPA_H
diff --git a/src/gui/kernel/qplatformglcontext_qpa.cpp b/src/gui/kernel/qplatformglcontext_qpa.cpp
deleted file mode 100644
index b0c6aeb27a..0000000000
--- a/src/gui/kernel/qplatformglcontext_qpa.cpp
+++ /dev/null
@@ -1,210 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qplatformglcontext_qpa.h"
-
-#include <QtCore/QThreadStorage>
-#include <QtCore/QThread>
-
-#include <QDebug>
-
-class QPlatformGLThreadContext
-{
-public:
- ~QPlatformGLThreadContext() {
- if (context)
- context->doneCurrent();
- }
- QPlatformGLContext *context;
-};
-
-static QThreadStorage<QPlatformGLThreadContext *> qplatformgl_context_storage;
-
-class QPlatformGLContextPrivate
-{
-public:
- QPlatformGLContextPrivate()
- : qGLContextHandle(0)
- , qGLContextDeleteFunction(0)
- {
- }
-
- virtual ~QPlatformGLContextPrivate()
- {
- //do not delete the QGLContext handle here as it is deleted in
- //QWidgetPrivate::deleteTLSysExtra()
- }
- void *qGLContextHandle;
- void (*qGLContextDeleteFunction)(void *handle);
- static QPlatformGLContext *staticSharedContext;
-
- static void setCurrentContext(QPlatformGLContext *context);
-};
-
-QPlatformGLContext *QPlatformGLContextPrivate::staticSharedContext = 0;
-
-void QPlatformGLContextPrivate::setCurrentContext(QPlatformGLContext *context)
-{
- QPlatformGLThreadContext *threadContext = qplatformgl_context_storage.localData();
- if (!threadContext) {
- if (!QThread::currentThread()) {
- qWarning("No QTLS available. currentContext wont work");
- return;
- }
- threadContext = new QPlatformGLThreadContext;
- qplatformgl_context_storage.setLocalData(threadContext);
- }
- threadContext->context = context;
-}
-
-/*!
- Returns the last context which called makeCurrent. This function is thread aware.
-*/
-const QPlatformGLContext* QPlatformGLContext::currentContext()
-{
- QPlatformGLThreadContext *threadContext = qplatformgl_context_storage.localData();
- if(threadContext) {
- return threadContext->context;
- }
- return 0;
-}
-
-/*!
- All subclasses needs to specify the platformWindow. It can be a null window.
-*/
-QPlatformGLContext::QPlatformGLContext()
- :d_ptr(new QPlatformGLContextPrivate())
-{
-}
-
-/*!
- If this is the current context for the thread, doneCurrent is called
-*/
-QPlatformGLContext::~QPlatformGLContext()
-{
- if (QPlatformGLContext::currentContext() == this) {
- doneCurrent();
- }
-
-}
-
-/*!
- Reimplement in subclass to do makeCurrent on native GL context
-*/
-void QPlatformGLContext::makeCurrent()
-{
- QPlatformGLContextPrivate::setCurrentContext(this);
-}
-
-/*!
- Reimplement in subclass to release current context.
- Typically this is calling makeCurrent with 0 "surface"
-*/
-void QPlatformGLContext::doneCurrent()
-{
- QPlatformGLContextPrivate::setCurrentContext(0);
-}
-
-/*
- internal: Needs to have a pointer to qGLContext. But since this is in QtGui we cant
- have any type information.
-*/
-void *QPlatformGLContext::qGLContextHandle() const
-{
- Q_D(const QPlatformGLContext);
- return d->qGLContextHandle;
-}
-
-void QPlatformGLContext::setQGLContextHandle(void *handle,void (*qGLContextDeleteFunction)(void *))
-{
- Q_D(QPlatformGLContext);
- d->qGLContextHandle = handle;
- d->qGLContextDeleteFunction = qGLContextDeleteFunction;
-}
-
-void QPlatformGLContext::deleteQGLContext()
-{
- Q_D(QPlatformGLContext);
- if (d->qGLContextDeleteFunction && d->qGLContextHandle) {
- d->qGLContextDeleteFunction(d->qGLContextHandle);
- d->qGLContextDeleteFunction = 0;
- d->qGLContextHandle = 0;
- }
-}
-
-/*!
- \class QPlatformGLContext
- \since 4.8
- \internal
- \preliminary
- \ingroup qpa
-
- \brief The QPlatformGLContext class provides an abstraction for native GL contexts.
-
- In QPA the way to support OpenGL or OpenVG or other technologies that requires a native GL
- context is through the QPlatformGLContext wrapper.
-
- There is no factory function for QPlatformGLContexts, but rather only one accessor function.
- The only place to retrieve a QPlatformGLContext from is through a QPlatformWindow.
-
- The context which is current for a specific thread can be collected by the currentContext()
- function. This is how QPlatformGLContext also makes it possible to use the QtOpenGL module
- withhout using QGLWidget. When using QGLContext::currentContext(), it will ask
- QPlatformGLContext for the currentContext. Then a corresponding QGLContext will be returned,
- which maps to the QPlatformGLContext.
-*/
-
-/*! \fn void QPlatformGLContext::swapBuffers()
- Reimplement in subclass to native swap buffers calls
-*/
-
-/*! \fn void *QPlatformGLContext::getProcAddress(const QString &procName)
- Reimplement in subclass to native getProcAddr calls.
-
- Note: its convenient to use qPrintable(const QString &str) to get the const char * pointer
-*/
-
-/*! \fn QPlatformWindowFormat QPlatformGLContext::platformWindowFormat() const
- QWidget has the function qplatformWindowFormat(). That function is for the application
- programmer to request the format of the window and the context that he wants.
-
- Reimplement this function in a subclass to indicate what format the glContext actually has.
-*/
diff --git a/src/gui/kernel/qplatformglcontext_qpa.h b/src/gui/kernel/qplatformglcontext_qpa.h
deleted file mode 100644
index 1e64f4a781..0000000000
--- a/src/gui/kernel/qplatformglcontext_qpa.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPLATFORM_GL_CONTEXT_H
-#define QPLATFORM_GL_CONTEXT_H
-
-#include <QtCore/qnamespace.h>
-#include <QtGui/QPlatformWindowFormat>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QPlatformGLContextPrivate;
-
-class Q_OPENGL_EXPORT QPlatformGLContext
-{
-Q_DECLARE_PRIVATE(QPlatformGLContext);
-
-public:
- explicit QPlatformGLContext();
- virtual ~QPlatformGLContext();
-
- virtual void makeCurrent();
- virtual void doneCurrent();
- virtual void swapBuffers() = 0;
- virtual void* getProcAddress(const QString& procName) = 0;
-
- virtual QPlatformWindowFormat platformWindowFormat() const = 0;
-
- const static QPlatformGLContext *currentContext();
-
-protected:
- QScopedPointer<QPlatformGLContextPrivate> d_ptr;
-
-private:
- //hack to make it work with QGLContext::CurrentContext
- friend class QGLContext;
- friend class QWidgetPrivate;
- void *qGLContextHandle() const;
- void setQGLContextHandle(void *handle,void (*qGLContextDeleteFunction)(void *));
- void deleteQGLContext();
- Q_DISABLE_COPY(QPlatformGLContext);
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-
-#endif // QPLATFORM_GL_INTEGRATION_P_H
diff --git a/src/gui/kernel/qplatforminputcontext_qpa.cpp b/src/gui/kernel/qplatforminputcontext_qpa.cpp
new file mode 100644
index 0000000000..0fdcd9e9ac
--- /dev/null
+++ b/src/gui/kernel/qplatforminputcontext_qpa.cpp
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qplatforminputcontext_qpa.h>
+#include <qguiapplication.h>
+#include <QRect>
+
+QT_BEGIN_NAMESPACE
+
+QPlatformInputContext::QPlatformInputContext()
+{
+}
+
+QPlatformInputContext::~QPlatformInputContext()
+{
+}
+
+bool QPlatformInputContext::isValid() const
+{
+ return false;
+}
+
+void QPlatformInputContext::reset()
+{
+}
+
+void QPlatformInputContext::commit()
+{
+}
+
+void QPlatformInputContext::update(Qt::InputMethodQueries)
+{
+}
+
+void QPlatformInputContext::invokeAction(QInputPanel::Action action, int cursorPosition)
+{
+ // Default behavior for simple ephemeral input contexts. Some
+ // complex input contexts should not be reset here.
+ if (action == QInputPanel::Click)
+ reset();
+}
+
+QRectF QPlatformInputContext::keyboardRect() const
+{
+ return QRectF();
+}
+
+void QPlatformInputContext::emitKeyboardRectChanged() const
+{
+ emit qApp->inputPanel()->keyboardRectangleChanged();
+}
+
+bool QPlatformInputContext::isAnimating()
+{
+ return false;
+}
+
+void QPlatformInputContext::emitAnimatingChanged()
+{
+ emit qApp->inputPanel()->animatingChanged();
+}
+
+
+QT_END_NAMESPACE
diff --git a/src/gui/kernel/qplatforminputcontext_qpa.h b/src/gui/kernel/qplatforminputcontext_qpa.h
new file mode 100644
index 0000000000..35763edf13
--- /dev/null
+++ b/src/gui/kernel/qplatforminputcontext_qpa.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPLATFORMINPUTCONTEXT_H
+#define QPLATFORMINPUTCONTEXT_H
+
+#include <qinputpanel.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QWindow;
+class QMouseEvent;
+
+class Q_GUI_EXPORT QPlatformInputContext : public QObject
+{
+ Q_OBJECT
+public:
+ QPlatformInputContext();
+ virtual ~QPlatformInputContext();
+
+ virtual bool isValid() const;
+
+ virtual void reset();
+ virtual void commit();
+ virtual void update(Qt::InputMethodQueries);
+ virtual void invokeAction(QInputPanel::Action, int cursorPosition);
+
+ virtual QRectF keyboardRect() const;
+ void emitKeyboardRectChanged() const;
+
+ virtual bool isAnimating();
+ void emitAnimatingChanged();
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QPLATFORMINPUTCONTEXT_H
diff --git a/src/gui/kernel/qplatformintegration_qpa.cpp b/src/gui/kernel/qplatformintegration_qpa.cpp
index 29287fe71c..856ceab87c 100644
--- a/src/gui/kernel/qplatformintegration_qpa.cpp
+++ b/src/gui/kernel/qplatformintegration_qpa.cpp
@@ -43,33 +43,14 @@
#include <QtGui/QPlatformFontDatabase>
#include <QtGui/QPlatformClipboard>
+#include <QtGui/private/qguiapplication_p.h>
+#include <QtGui/private/qpixmap_raster_p.h>
+#include <private/qdnd_p.h>
QT_BEGIN_NAMESPACE
-QPixmap QPlatformIntegration::grabWindow(WId window, int x, int y, int width, int height) const
-{
- Q_UNUSED(window);
- Q_UNUSED(x);
- Q_UNUSED(y);
- Q_UNUSED(width);
- Q_UNUSED(height);
- return QPixmap();
-}
-
/*!
- Factory function for the eventloop integration interface.
-
- Default implementation returns 0, which causes the eventloop to run in a single thread mode.
-
- \sa QPlatformEventLoopIntegration
-*/
-QPlatformEventLoopIntegration *QPlatformIntegration::createEventLoopIntegration() const
-{
- return 0;
-}
-
-/*!
- Accessor for the platform integrations fontdatabase.
+ Accessor for the platform integration's fontdatabase.
Default implementation returns a default QPlatformFontDatabase.
@@ -85,7 +66,7 @@ QPlatformFontDatabase *QPlatformIntegration::fontDatabase() const
}
/*!
- Accessor for the platform integrations clipboard.
+ Accessor for the platform integration's clipboard.
Default implementation returns a default QPlatformClipboard.
@@ -106,6 +87,19 @@ QPlatformClipboard *QPlatformIntegration::clipboard() const
#endif
+#ifndef QT_NO_DRAGANDDROP
+/*!
+ Accessor for the platform integration's drag object.
+
+ Default implementation returns 0, implying no drag and drop support.
+
+*/
+QPlatformDrag *QPlatformIntegration::drag() const
+{
+ return 0;
+}
+#endif
+
QPlatformNativeInterface * QPlatformIntegration::nativeInterface() const
{
return 0;
@@ -123,12 +117,12 @@ QPlatformNativeInterface * QPlatformIntegration::nativeInterface() const
using the QPA platform. It has factory functions for creating platform specific pixmaps and
windows. The class also controls the font subsystem.
- QPlatformIntegration is a singelton class which gets instansiated in the QApplication
+ QPlatformIntegration is a singleton class which gets instantiated in the QGuiApplication
constructor. The QPlatformIntegration instance do not have ownership of objects it creates in
functions where the name starts with create. However, functions which don't have a name
- starting with create acts as assessors to member variables.
+ starting with create acts as accessors to member variables.
- It is not trivial to create or build a platform plugin outside of the Qt source tree. Therefor
+ It is not trivial to create or build a platform plugin outside of the Qt source tree. Therefore
the recommended approach for making new platform plugin is to copy an existing plugin inside
the QTSRCTREE/src/plugins/platform and develop the plugin inside the source tree.
@@ -138,88 +132,131 @@ QPlatformNativeInterface * QPlatformIntegration::nativeInterface() const
*/
/*!
- \fn QPixmapData *QPlatformIntegration::createPixmapData(QPixmapData::PixelType type) const
+ \fn QPlatformPixmap *QPlatformIntegration::createPlatformPixmap(QPlatformPixmap::PixelType type) const
- Factory function for QPixmapData. PixelType can be either PixmapType or BitmapType.
- \sa QPixmapData
+ Factory function for QPlatformPixmap. PixelType can be either PixmapType or BitmapType.
+ \sa QPlatformPixmap
*/
/*!
- \fn QPlatformWindow *QPlatformIntegration::createPlatformWindow(QWidget *widget, WId winId = 0) const
+ \fn QPlatformWindow *QPlatformIntegration::createPlatformWindow(QWindow *window) const
+
+ Factory function for QPlatformWindow. The \a window parameter is a pointer to the top level
+ window which the QPlatformWindow is supposed to be created for.
- Factory function for QPlatformWindow. The widget parameter is a pointer to the top level
- widget(tlw) which the QPlatformWindow is suppose to be created for. The WId handle is actually
- never used, but there for future reference. Its purpose is if it is going to be possible to
- create QPlatformWindows on existing WId.
+ All top level windows have to have a QPlatformWindow, and it will be created when the
+ QPlatformWindow is set to be visible for the first time. If the top level window's flags are
+ changed, or if the top level window's QPlatformWindowFormat is changed, then the top level
+ window's QPlatformWindow is deleted and a new one is created.
- All tlw has to have a QPlatformWindow, and it will be created when the QPlatformWindow is set
- to be visible for the first time. If the tlw's window flags are changed, or if the tlw's
- QPlatformWindowFormat is changed, then the tlw's QPlatformWindow is deleted and a new one is
- created.
+ In the constructor, of the QPlatformWindow, the window flags, state, title and geometry
+ of the \a window should be applied to the underlying window. If the resulting flags or state
+ differs, the resulting values should be set on the \a window using QWindow::setWindowFlags()
+ or QWindow::setWindowState(), respectively.
\sa QPlatformWindow, QPlatformWindowFormat
- \sa createWindowSurface(QWidget *widget, WId winId) const
+ \sa createPlatformBackingStore(QWindow *window) const
*/
/*!
- \fn QWindowSurface *QPlatformIntegration::createWindowSurface(QWidget *widget, WId winId) const
+ \fn QPlatformBackingStore *QPlatformIntegration::createPlatformBackingStore(QWindow *window) const
- Factory function for QWindowSurface. The QWidget parameter is a pointer to the
+ Factory function for QPlatformBackingStore. The QWindow parameter is a pointer to the
top level widget(tlw) the window surface is created for. A QPlatformWindow is always created
- before the QWindowSurface for tlw where the widget also requires a WindowSurface. It is
- possible to create top level QWidgets without a QWindowSurface by specifying
- QPlatformWindowFormat::setWindowSurface(false) for the tlw QPlatformWindowFormat.
+ before the QPlatformBackingStore for tlw where the widget also requires a backing store.
- \sa QWindowSurface
- \sa createPlatformWindow(QWidget *widget, WId winId = 0) const
+ \sa QBackingStore
+ \sa createPlatformWindow(QWindow *window, WId winId = 0) const
*/
/*!
- \fn void QPlatformIntegration::moveToScreen(QWidget *window, int screen)
-
- This function is called when a QWidget is displayed on screen, or the QWidget is to be
- displayed on a new screen. The QWidget parameter is a pointer to the top level widget and
- the int parameter is the index to the screen in QList<QPlatformScreen *> screens() const.
- Default implementation does nothing.
+ \fn QAbstractEventDispatcher *guiThreadEventDispatcher() const = 0
- \sa screens() const
+ Accessor function for the event dispatcher. The platform plugin should create
+ an instance of the QAbstractEventDispatcher in its constructor and set it
+ on the application using QGuiApplicationPrivate::instance()->setEventDispatcher().
+ The event dispatcher is owned by QGuiApplication, the accessor should return
+ a flat pointer.
+ \sa QGuiApplicationPrivate
*/
-/*!
- \fn QList<QPlatformScreen *> QPlatformIntegration::screens() const
+bool QPlatformIntegration::hasCapability(Capability cap) const
+{
+ Q_UNUSED(cap);
+ return false;
+}
- Accessor function to a list of all the screens on the current system. The screen with the
- index == 0 is the default/main screen.
-*/
+QPlatformPixmap *QPlatformIntegration::createPlatformPixmap(QPlatformPixmap::PixelType type) const
+{
+ return new QRasterPlatformPixmap(type);
+}
-/*!
- \fn bool QPlatformIntegration::isVirtualDesktop()
+QPlatformOpenGLContext *QPlatformIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
+{
+ Q_UNUSED(context);
+ qWarning("This plugin does not support createPlatformOpenGLContext!");
+ return 0;
+}
- Returns if the current windowing system configuration defines all the screens to be one
- desktop(virtual desktop), or if each screen is a desktop of its own.
+/*!
+ Returns the platforms input context.
- Default implementation returns false.
+ The default implementation returns 0, implying no input method support.
*/
+QPlatformInputContext *QPlatformIntegration::inputContext() const
+{
+ return 0;
+}
-/*!
- \fn QPixmap QPlatformIntegration::grabWindow(WId window, int x, int y, int width, int height) const
-
- This function is called when Qt needs to be able to grab the content of a window.
+QVariant QPlatformIntegration::styleHint(StyleHint hint) const
+{
+ switch (hint) {
+ case CursorFlashTime:
+ return 1000;
+ case KeyboardInputInterval:
+ return 400;
+ case MouseDoubleClickInterval:
+ return 400;
+ case StartDragDistance:
+ return 10;
+ case StartDragTime:
+ return 500;
+ }
- Returnes the content of the window specified with the WId handle within the boundaries of
- QRect(x,y,width,height).
-*/
+ return 0;
+}
+QPlatformMenu *QPlatformIntegration::createPlatformMenu(QMenu *menu) const
+{
+ Q_UNUSED(menu);
+ return 0;
+}
-bool QPlatformIntegration::hasCapability(Capability cap) const
+QPlatformMenuBar *QPlatformIntegration::createPlatformMenuBar(QMenuBar *menuBar) const
{
- Q_UNUSED(cap);
- return false;
+ Q_UNUSED(menuBar);
+ return 0;
}
+/*!
+ Should be called by the implementation whenever a new screen is added.
+ The first screen added will be the primary screen, used for default-created
+ windows, GL contexts, and other resources unless otherwise specified.
+ This adds the screen to QGuiApplication::screens(), and emits the
+ QGuiApplication::screenAdded() signal.
+ The screen is automatically removed when the QPlatformScreen is destroyed.
+*/
+void QPlatformIntegration::screenAdded(QPlatformScreen *ps)
+{
+ QScreen *screen = ps ? ps->screen() : 0;
+ if (screen && !QGuiApplicationPrivate::screen_list.contains(screen)) {
+ QGuiApplicationPrivate::screen_list << screen;
+ emit qGuiApp->screenAdded(screen);
+ }
+}
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qplatformintegration_qpa.h b/src/gui/kernel/qplatformintegration_qpa.h
index 74d2342314..b9e1d02552 100644
--- a/src/gui/kernel/qplatformintegration_qpa.h
+++ b/src/gui/kernel/qplatformintegration_qpa.h
@@ -43,9 +43,8 @@
#define QPLATFORMINTEGRATION_H
#include <QtGui/qwindowdefs.h>
-#include <QtGui/private/qwindowsurface_p.h>
-#include <QtGui/private/qpixmapdata_p.h>
#include <QtGui/qplatformscreen_qpa.h>
+#include <QtGui/qsurfaceformat.h>
QT_BEGIN_HEADER
@@ -54,50 +53,70 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Gui)
class QPlatformWindow;
-class QWindowSurface;
-class QBlittable;
-class QWidget;
-class QPlatformEventLoopIntegration;
+class QWindow;
+class QPlatformBackingStore;
class QPlatformFontDatabase;
class QPlatformClipboard;
class QPlatformNativeInterface;
+class QPlatformDrag;
+class QPlatformOpenGLContext;
+class QGuiGLFormat;
+class QAbstractEventDispatcher;
+class QPlatformInputContext;
+class QMenu;
+class QMenuBar;
+class QPlatformMenu;
+class QPlatformMenuBar;
class Q_GUI_EXPORT QPlatformIntegration
{
public:
enum Capability {
ThreadedPixmaps = 1,
- OpenGL = 2
+ OpenGL = 2,
+ ThreadedOpenGL = 3
};
virtual ~QPlatformIntegration() { }
virtual bool hasCapability(Capability cap) const;
-// GraphicsSystem functions
- virtual QPixmapData *createPixmapData(QPixmapData::PixelType type) const = 0;
- virtual QPlatformWindow *createPlatformWindow(QWidget *widget, WId winId = 0) const = 0;
- virtual QWindowSurface *createWindowSurface(QWidget *widget, WId winId) const = 0;
+ virtual QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const;
+ virtual QPlatformWindow *createPlatformWindow(QWindow *window) const = 0;
+ virtual QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const = 0;
+ virtual QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const;
-// Window System functions
- virtual QList<QPlatformScreen *> screens() const = 0;
- virtual void moveToScreen(QWidget *window, int screen) {Q_UNUSED(window); Q_UNUSED(screen);}
- virtual bool isVirtualDesktop() { return false; }
- virtual QPixmap grabWindow(WId window, int x, int y, int width, int height) const;
+// Event dispatcher:
+ virtual QAbstractEventDispatcher *guiThreadEventDispatcher() const = 0;
//Deeper window system integrations
virtual QPlatformFontDatabase *fontDatabase() const;
#ifndef QT_NO_CLIPBOARD
virtual QPlatformClipboard *clipboard() const;
#endif
+#ifndef QT_NO_DRAGANDDROP
+ virtual QPlatformDrag *drag() const;
+#endif
+ virtual QPlatformInputContext *inputContext() const;
-// Experimental in mainthread eventloop integration
-// This should only be used if it is only possible to do window system event processing in
-// the gui thread. All of the functions in QWindowSystemInterface are thread safe.
- virtual QPlatformEventLoopIntegration *createEventLoopIntegration() const;
+ virtual QPlatformMenu *createPlatformMenu(QMenu *menu = 0) const;
+ virtual QPlatformMenuBar *createPlatformMenuBar(QMenuBar *menuBar = 0) const;
// Access native handles. The window handle is already available from Wid;
virtual QPlatformNativeInterface *nativeInterface() const;
+
+ enum StyleHint {
+ CursorFlashTime,
+ KeyboardInputInterval,
+ MouseDoubleClickInterval,
+ StartDragDistance,
+ StartDragTime
+ };
+
+ virtual QVariant styleHint(StyleHint hint) const;
+
+protected:
+ void screenAdded(QPlatformScreen *screen);
};
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qplatformintegrationfactory_qpa.cpp b/src/gui/kernel/qplatformintegrationfactory_qpa.cpp
index a2d1c36882..c40494c408 100644
--- a/src/gui/kernel/qplatformintegrationfactory_qpa.cpp
+++ b/src/gui/kernel/qplatformintegrationfactory_qpa.cpp
@@ -44,7 +44,7 @@
#include "private/qfactoryloader_p.h"
#include "qmutex.h"
-#include "qapplication.h"
+#include "qguiapplication.h"
#include "qdebug.h"
QT_BEGIN_NAMESPACE
diff --git a/src/gui/kernel/qplatformnativeinterface_qpa.cpp b/src/gui/kernel/qplatformnativeinterface_qpa.cpp
index e3f6689acc..7b9ff4a7a5 100644
--- a/src/gui/kernel/qplatformnativeinterface_qpa.cpp
+++ b/src/gui/kernel/qplatformnativeinterface_qpa.cpp
@@ -43,10 +43,24 @@
QT_BEGIN_NAMESPACE
-void *QPlatformNativeInterface::nativeResourceForWidget(const QByteArray &resource, QWidget *widget)
+void *QPlatformNativeInterface::nativeResourceForWindow(const QByteArray &resource, QWindow *window)
{
Q_UNUSED(resource);
- Q_UNUSED(widget);
+ Q_UNUSED(window);
+ return 0;
+}
+
+void *QPlatformNativeInterface::nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context)
+{
+ Q_UNUSED(resource);
+ Q_UNUSED(context);
+ return 0;
+}
+
+void * QPlatformNativeInterface::nativeResourceForBackingStore(const QByteArray &resource, QBackingStore *backingStore)
+{
+ Q_UNUSED(resource);
+ Q_UNUSED(backingStore);
return 0;
}
diff --git a/src/gui/kernel/qplatformnativeinterface_qpa.h b/src/gui/kernel/qplatformnativeinterface_qpa.h
index dd57f94a88..bfcf78813b 100644
--- a/src/gui/kernel/qplatformnativeinterface_qpa.h
+++ b/src/gui/kernel/qplatformnativeinterface_qpa.h
@@ -52,14 +52,18 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Gui)
-class QWidget;
+class QOpenGLContext;
+class QWindow;
class QPlatformWindow;
+class QBackingStore;
class Q_GUI_EXPORT QPlatformNativeInterface : public QObject
{
Q_OBJECT
public:
- virtual void *nativeResourceForWidget(const QByteArray &resource, QWidget *widget);
+ virtual void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context);
+ virtual void *nativeResourceForWindow(const QByteArray &resource, QWindow *window);
+ virtual void *nativeResourceForBackingStore(const QByteArray &resource, QBackingStore *backingStore);
virtual QVariantMap windowProperties(QPlatformWindow *window) const;
virtual QVariant windowProperty(QPlatformWindow *window, const QString &name) const;
@@ -68,7 +72,6 @@ public:
Q_SIGNALS:
void windowPropertyChanged(QPlatformWindow *window, const QString &propertyName);
-
};
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qplatformopenglcontext_qpa.cpp b/src/gui/kernel/qplatformopenglcontext_qpa.cpp
new file mode 100644
index 0000000000..2957b4db4b
--- /dev/null
+++ b/src/gui/kernel/qplatformopenglcontext_qpa.cpp
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qplatformopenglcontext_qpa.h"
+
+/*!
+ \class QPlatformOpenGLContext
+ \since 4.8
+ \internal
+ \preliminary
+ \ingroup qpa
+
+ \brief The QPlatformOpenGLContext class provides an abstraction for native GL contexts.
+
+ In QPA the way to support OpenGL or OpenVG or other technologies that requires a native GL
+ context is through the QPlatformOpenGLContext wrapper.
+
+ There is no factory function for QPlatformOpenGLContexts, but rather only one accessor function.
+ The only place to retrieve a QPlatformOpenGLContext from is through a QPlatformWindow.
+
+ The context which is current for a specific thread can be collected by the currentContext()
+ function. This is how QPlatformOpenGLContext also makes it possible to use the QtGui module
+ withhout using QOpenGLWidget. When using QOpenGLContext::currentContext(), it will ask
+ QPlatformOpenGLContext for the currentContext. Then a corresponding QOpenGLContext will be returned,
+ which maps to the QPlatformOpenGLContext.
+*/
+
+/*! \fn void QPlatformOpenGLContext::swapBuffers()
+ Reimplement in subclass to native swap buffers calls
+
+ The implementation must support being called in a thread different than the gui-thread.
+*/
+
+/*! \fn void *QPlatformOpenGLContext::getProcAddress(const QString &procName)
+ Reimplement in subclass to native getProcAddr calls.
+
+ Note: its convenient to use qPrintable(const QString &str) to get the const char * pointer
+*/
+
+/*! \fn QPlatformWindowFormat QPlatformOpenGLContext::platformWindowFormat() const
+ QWidget has the function qplatformWindowFormat(). That function is for the application
+ programmer to request the format of the window and the context that he wants.
+
+ Reimplement this function in a subclass to indicate what format the glContext actually has.
+*/
+
+struct QPlatformOpenGLContextPrivate
+{
+ QOpenGLContext *context;
+};
+
+QPlatformOpenGLContext::QPlatformOpenGLContext()
+ : d_ptr(new QPlatformOpenGLContextPrivate)
+{
+ Q_D(QPlatformOpenGLContext);
+ d->context = 0;
+}
+
+QPlatformOpenGLContext::~QPlatformOpenGLContext()
+{
+}
+
+QOpenGLContext *QPlatformOpenGLContext::context() const
+{
+ Q_D(const QPlatformOpenGLContext);
+ return d->context;
+}
+
+void QPlatformOpenGLContext::setContext(QOpenGLContext *context)
+{
+ Q_D(QPlatformOpenGLContext);
+ d->context = context;
+}
diff --git a/src/gui/kernel/qplatformopenglcontext_qpa.h b/src/gui/kernel/qplatformopenglcontext_qpa.h
new file mode 100644
index 0000000000..6fb8da25c1
--- /dev/null
+++ b/src/gui/kernel/qplatformopenglcontext_qpa.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPLATFORMGLCONTEXT_H
+#define QPLATFORMGLCONTEXT_H
+
+#include <QtCore/qnamespace.h>
+#include <QtGui/qsurfaceformat.h>
+#include <QtGui/qwindow.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QPlatformOpenGLContextPrivate;
+
+class Q_GUI_EXPORT QPlatformOpenGLContext
+{
+ Q_DECLARE_PRIVATE(QPlatformOpenGLContext)
+public:
+ QPlatformOpenGLContext();
+ virtual ~QPlatformOpenGLContext();
+
+ virtual QSurfaceFormat format() const = 0;
+
+ virtual void swapBuffers(QPlatformSurface *surface) = 0;
+
+ virtual bool makeCurrent(QPlatformSurface *surface) = 0;
+ virtual void doneCurrent() = 0;
+
+ virtual void (*getProcAddress(const QByteArray &procName)) () = 0;
+
+ QOpenGLContext *context() const;
+
+private:
+ friend class QOpenGLContext;
+
+ QScopedPointer<QPlatformOpenGLContextPrivate> d_ptr;
+
+ void setContext(QOpenGLContext *context);
+
+ Q_DISABLE_COPY(QPlatformOpenGLContext)
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif // QPLATFORMGLCONTEXT_H
diff --git a/src/gui/kernel/qplatformscreen_qpa.cpp b/src/gui/kernel/qplatformscreen_qpa.cpp
index 2a1e7e4b9a..8fb42595b8 100644
--- a/src/gui/kernel/qplatformscreen_qpa.cpp
+++ b/src/gui/kernel/qplatformscreen_qpa.cpp
@@ -40,26 +40,63 @@
****************************************************************************/
#include "qplatformscreen_qpa.h"
-#include <QtGui/qapplication.h>
-#include <QtGui/private/qapplication_p.h>
-#include <QtGui/qdesktopwidget.h>
+#include <QtGui/qguiapplication.h>
+#include <QtGui/private/qguiapplication_p.h>
#include <QtGui/qplatformintegration_qpa.h>
-#include <QtGui/qwidget.h>
-#include <QtGui/private/qwidget_p.h>
+#include <QtGui/qscreen.h>
+#include <QtGui/qwindow.h>
+
+class QPlatformScreenPrivate
+{
+public:
+ QScreen *screen;
+};
+
+QPlatformScreen::QPlatformScreen()
+ : d_ptr(new QPlatformScreenPrivate)
+{
+ Q_D(QPlatformScreen);
+ d->screen = new QScreen(this);
+}
+
+QPlatformScreen::~QPlatformScreen()
+{
+ Q_D(QPlatformScreen);
+
+ QGuiApplicationPrivate::screen_list.removeOne(d->screen);
+ delete d->screen;
+}
/*!
- Return the given top level widget for a given position.
+ \fn QPixmap QPlatformScreen::grabWindow(WId window, int x, int y, int width, int height) const
+
+ This function is called when Qt needs to be able to grab the content of a window.
- Default implementation retrieves a list of all top level widgets and finds the first widget
+ Returnes the content of the window specified with the WId handle within the boundaries of
+ QRect(x,y,width,height).
+*/
+QPixmap QPlatformScreen::grabWindow(WId window, int x, int y, int width, int height) const
+{
+ Q_UNUSED(window);
+ Q_UNUSED(x);
+ Q_UNUSED(y);
+ Q_UNUSED(width);
+ Q_UNUSED(height);
+ return QPixmap();
+}
+
+/*!
+ Return the given top level window for a given position.
+
+ Default implementation retrieves a list of all top level windows and finds the first window
which contains point \a pos
*/
-QWidget *QPlatformScreen::topLevelAt(const QPoint & pos) const
+QWindow *QPlatformScreen::topLevelAt(const QPoint & pos) const
{
- QWidgetList list = QApplication::topLevelWidgets();
+ QWindowList list = QGuiApplication::topLevelWindows();
for (int i = list.size()-1; i >= 0; --i) {
- QWidget *w = list[i];
- //### mask is ignored
- if (w != QApplication::desktop() && w->isVisible() && w->geometry().contains(pos))
+ QWindow *w = list[i];
+ if (w->visible() && w->geometry().contains(pos))
return w;
}
@@ -67,6 +104,26 @@ QWidget *QPlatformScreen::topLevelAt(const QPoint & pos) const
}
/*!
+ Returns a list of all the platform screens that are part of the same
+ virtual desktop.
+
+ Screens part of the same virtual desktop share a common coordinate system,
+ and windows can be freely moved between them.
+*/
+QList<QPlatformScreen *> QPlatformScreen::virtualSiblings() const
+{
+ QList<QPlatformScreen *> list;
+ list << const_cast<QPlatformScreen *>(this);
+ return list;
+}
+
+QScreen *QPlatformScreen::screen() const
+{
+ Q_D(const QPlatformScreen);
+ return d->screen;
+}
+
+/*!
Reimplement this function in subclass to return the physical size of the
screen. This function is used by QFont to convert point sizes to pixel
sizes.
@@ -84,15 +141,9 @@ QSize QPlatformScreen::physicalSize() const
return QSize(width,height);
}
-Q_GUI_EXPORT extern QWidgetPrivate *qt_widget_private(QWidget *widget);
-QPlatformScreen * QPlatformScreen::platformScreenForWidget(const QWidget *widget)
+QPlatformScreen * QPlatformScreen::platformScreenForWindow(const QWindow *window)
{
- QWidget *window = widget->window();
- QWidgetPrivate *windowPrivate = qt_widget_private(window);
- QTLWExtra * topData = windowPrivate->topData();
- QPlatformIntegration *integration =
- QApplicationPrivate::platformIntegration();
- return integration->screens()[topData->screenIndex];
+ return window->screen()->handle();
}
/*!
diff --git a/src/gui/kernel/qplatformscreen_qpa.h b/src/gui/kernel/qplatformscreen_qpa.h
index a9ce7c29e3..3851b1821a 100644
--- a/src/gui/kernel/qplatformscreen_qpa.h
+++ b/src/gui/kernel/qplatformscreen_qpa.h
@@ -51,7 +51,8 @@
#include <QtGui/qcursor.h>
#include <QtGui/qimage.h>
-#include <QtGui/qwidget.h>
+#include <QtGui/qwindowdefs.h>
+#include <QtGui/qplatformpixmap_qpa.h>
QT_BEGIN_HEADER
@@ -59,24 +60,46 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Gui)
-class Q_GUI_EXPORT QPlatformScreen : public QObject
+class QPlatformBackingStore;
+class QPlatformOpenGLContext;
+class QPlatformScreenPrivate;
+class QPlatformWindow;
+class QScreen;
+class QSurfaceFormat;
+
+class Q_GUI_EXPORT QPlatformScreen
{
- Q_OBJECT
+ Q_DECLARE_PRIVATE(QPlatformScreen)
+
public:
- virtual ~QPlatformScreen() { }
+ QPlatformScreen();
+ virtual ~QPlatformScreen();
+
+ virtual QPixmap grabWindow(WId window, int x, int y, int width, int height) const;
virtual QRect geometry() const = 0;
virtual QRect availableGeometry() const {return geometry();}
+
virtual int depth() const = 0;
virtual QImage::Format format() const = 0;
virtual QSize physicalSize() const;
- //jl: should setDirty be removed.
- virtual void setDirty(const QRect &) {}
- virtual QWidget *topLevelAt(const QPoint &point) const;
+
+ virtual QWindow *topLevelAt(const QPoint &point) const;
+ virtual QList<QPlatformScreen *> virtualSiblings() const;
+
+ QScreen *screen() const;
//jl: should this function be in QPlatformIntegration
- //jl: maybe screenForWidget is a better name?
- static QPlatformScreen *platformScreenForWidget(const QWidget *widget);
+ //jl: maybe screenForWindow is a better name?
+ static QPlatformScreen *platformScreenForWindow(const QWindow *window);
+
+ virtual QString name() const { return QString(); }
+
+protected:
+ QScopedPointer<QPlatformScreenPrivate> d_ptr;
+
+private:
+ Q_DISABLE_COPY(QPlatformScreen)
};
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qplatformsurface_qpa.cpp b/src/gui/kernel/qplatformsurface_qpa.cpp
new file mode 100644
index 0000000000..dcfd201ea3
--- /dev/null
+++ b/src/gui/kernel/qplatformsurface_qpa.cpp
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qplatformsurface_qpa.h"
+
+QT_BEGIN_NAMESPACE
+
+QSurface::SurfaceType QPlatformSurface::surfaceType() const
+{
+ return m_type;
+}
+
+QPlatformSurface::QPlatformSurface(QSurface::SurfaceType type) : m_type(type)
+{
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/gui/kernel/qplatformsurface_qpa.h b/src/gui/kernel/qplatformsurface_qpa.h
new file mode 100644
index 0000000000..76b564de25
--- /dev/null
+++ b/src/gui/kernel/qplatformsurface_qpa.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPLATFORMSURFACE_H
+#define QPLATFORMSURFACE_H
+
+#include <QtCore/qnamespace.h>
+#include <QtGui/qsurface.h>
+#include <QtGui/qsurfaceformat.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class Q_GUI_EXPORT QPlatformSurface
+{
+public:
+ virtual QSurfaceFormat format() const = 0;
+
+ QSurface::SurfaceType surfaceType() const;
+
+private:
+ QPlatformSurface(QSurface::SurfaceType type);
+
+ QSurface::SurfaceType m_type;
+
+ friend class QPlatformWindow;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif //QPLATFORMSURFACE_H
diff --git a/src/gui/kernel/qplatformwindow_qpa.cpp b/src/gui/kernel/qplatformwindow_qpa.cpp
index b1c66ea32b..0734fb7a26 100644
--- a/src/gui/kernel/qplatformwindow_qpa.cpp
+++ b/src/gui/kernel/qplatformwindow_qpa.cpp
@@ -42,49 +42,76 @@
#include "qplatformwindow_qpa.h"
#include <QtGui/qwindowsysteminterface_qpa.h>
-#include <QtGui/qwidget.h>
+#include <QtGui/qwindow.h>
+#include <QtGui/qscreen.h>
class QPlatformWindowPrivate
{
- QWidget *tlw;
+ QWindow *window;
QRect rect;
- Qt::WindowFlags flags;
friend class QPlatformWindow;
};
/*!
- Constructs a platform window with the given top level widget.
+ Constructs a platform window with the given top level window.
*/
-QPlatformWindow::QPlatformWindow(QWidget *tlw)
- : d_ptr(new QPlatformWindowPrivate)
+QPlatformWindow::QPlatformWindow(QWindow *window)
+ : QPlatformSurface(QSurface::Window)
+ , d_ptr(new QPlatformWindowPrivate)
{
Q_D(QPlatformWindow);
- d->tlw = tlw;
- tlw->setPlatformWindow(this);
+ d->window = window;
+ d->rect = window->geometry();
}
/*!
- Virtual destructor does not delete its top level widget.
+ Virtual destructor does not delete its top level window.
*/
QPlatformWindow::~QPlatformWindow()
{
}
/*!
- Returnes the widget which belongs to the QPlatformWindow
+ Returns the window which belongs to the QPlatformWindow
*/
-QWidget *QPlatformWindow::widget() const
+QWindow *QPlatformWindow::window() const
{
Q_D(const QPlatformWindow);
- return d->tlw;
+ return d->window;
+}
+
+/*!
+ Returns the parent platform window (or 0 if orphan).
+*/
+QPlatformWindow *QPlatformWindow::parent() const
+{
+ Q_D(const QPlatformWindow);
+ return d->window->parent() ? d->window->parent()->handle() : 0;
+}
+
+/*!
+ Returns the platform screen handle corresponding to this platform window.
+*/
+QPlatformScreen *QPlatformWindow::screen() const
+{
+ Q_D(const QPlatformWindow);
+ return d->window->screen()->handle();
+}
+
+/*!
+ Returns the actual surface format of the window.
+*/
+QSurfaceFormat QPlatformWindow::format() const
+{
+ return QSurfaceFormat();
}
/*!
This function is called by Qt whenever a window is moved or the window is resized. The resize
can happen programatically(from ie. user application) or by the window manager. This means that
there is no need to call this function specifically from the window manager callback, instead
- call QWindowSystemInterface::handleGeometryChange(QWidget *w, const QRect &newRect);
+ call QWindowSystemInterface::handleGeometryChange(QWindow *w, const QRect &newRect);
*/
void QPlatformWindow::setGeometry(const QRect &rect)
{
@@ -101,6 +128,11 @@ QRect QPlatformWindow::geometry() const
return d->rect;
}
+QMargins QPlatformWindow::frameMargins() const
+{
+ return QMargins();
+}
+
/*!
Reimplemented in subclasses to show the surface
if \a visible is \c true, and hide it if \a visible is \c false.
@@ -115,18 +147,18 @@ void QPlatformWindow::setVisible(bool visible)
*/
Qt::WindowFlags QPlatformWindow::setWindowFlags(Qt::WindowFlags flags)
{
- Q_D(QPlatformWindow);
- d->flags = flags;
return flags;
}
/*!
- Returns the effective window flags for this surface.
+ Requests setting the window state of this surface
+ to \a type. Returns the actual state set.
+
+ Qt::WindowActive can be ignored.
*/
-Qt::WindowFlags QPlatformWindow::windowFlags() const
+Qt::WindowState QPlatformWindow::setWindowState(Qt::WindowState)
{
- Q_D(const QPlatformWindow);
- return d->flags;
+ return Qt::WindowNoState;
}
/*!
@@ -135,7 +167,7 @@ Qt::WindowFlags QPlatformWindow::windowFlags() const
WId QPlatformWindow::winId() const { return WId(0); }
/*!
- This function is called to enable native child widgets in QPA. It is common not to support this
+ This function is called to enable native child window in QPA. It is common not to support this
feature in Window systems, but can be faked. When this function is called all geometry of this
platform window will be relative to the parent.
*/
@@ -150,7 +182,7 @@ void QPlatformWindow::setParent(const QPlatformWindow *parent)
/*!
Reimplement to set the window title to \a title
*/
-void QPlatformWindow::setWindowTitle(const QString &) {}
+void QPlatformWindow::setWindowTitle(const QString &title) { Q_UNUSED(title); }
/*!
Reimplement to be able to let Qt rais windows to the top of the desktop
@@ -163,6 +195,14 @@ void QPlatformWindow::raise() { qWarning("This plugin does not support raise()")
void QPlatformWindow::lower() { qWarning("This plugin does not support lower()"); }
/*!
+ Reimplement to propagate the size hints of the QWindow.
+
+ The size hints include QWindow::minimumSize(), QWindow::maximumSize(),
+ QWindow::sizeIncrement(), and QWindow::baseSize().
+*/
+void QPlatformWindow::propagateSizeHints() {qWarning("This plugin does not support propagateSizeHints()"); }
+
+/*!
Reimplement to be able to let Qt set the opacity level of a window
*/
void QPlatformWindow::setOpacity(qreal level)
@@ -175,26 +215,32 @@ void QPlatformWindow::setOpacity(qreal level)
Reimplement to let Qt be able to request activation/focus for a window
Some window systems will probably not have callbacks for this functionality,
- and then calling QWindowSystemInterface::handleWindowActivated(QWidget *w)
+ and then calling QWindowSystemInterface::handleWindowActivated(QWindow *w)
would be sufficient.
If the window system has some event handling/callbacks then call
- QWindowSystemInterface::handleWindowActivated(QWidget *w) when the window system
+ QWindowSystemInterface::handleWindowActivated(QWindow *w) when the window system
gives the notification.
- Default implementation calls QWindowSystem::handleWindowActivated(QWidget *w)
+ Default implementation calls QWindowSystem::handleWindowActivated(QWindow *w)
*/
void QPlatformWindow::requestActivateWindow()
{
- QWindowSystemInterface::handleWindowActivated(widget());
+ QWindowSystemInterface::handleWindowActivated(window());
}
-/*!
- Reimplement to return the glContext associated with the window.
-*/
-QPlatformGLContext *QPlatformWindow::glContext() const
+bool QPlatformWindow::setKeyboardGrabEnabled(bool grab)
+{
+ Q_UNUSED(grab);
+ qWarning("This plugin does not support grabbing the keyboard");
+ return false;
+}
+
+bool QPlatformWindow::setMouseGrabEnabled(bool grab)
{
- return 0;
+ Q_UNUSED(grab);
+ qWarning("This plugin does not support grabbing the mouse");
+ return false;
}
/*!
@@ -206,24 +252,24 @@ QPlatformGLContext *QPlatformWindow::glContext() const
\brief The QPlatformWindow class provides an abstraction for top-level windows.
- The QPlatformWindow abstraction is used by QWidget for all its top level widgets. It is being
+ The QPlatformWindow abstraction is used by QWindow for all its top level windows. It is being
created by calling the createPlatformWindow function in the loaded QPlatformIntegration
instance.
QPlatformWindow is used to signal to the windowing system, how Qt persieves its frame.
However, it is not concerned with how Qt renders into the window it represents.
- Top level QWidgets(tlw) will always have a QPlatformWindow. However, it is not necessary for
- all tlw to have a QWindowSurface. This is the case for QGLWidget. And could be the case for
- widgets where some 3.party renders into it.
+ Visible QWindows will always have a QPlatformWindow. However, it is not necessary for
+ all windows to have a QWindowSurface. This is the case for QOpenGLWidget. And could be the case for
+ windows where some 3.party renders into it.
The platform specific window handle can be retrieved by the winId function.
QPlatformWindow is also the way QPA defines how native child windows should be supported
through the setParent function.
- The only way to retrieve a QPlatformGLContext in QPA is by calling the glContext() function
+ The only way to retrieve a QPlatformOpenGLContext in QPA is by calling the glContext() function
on QPlatformWindow.
- \sa QWindowSurface, QWidget
+ \sa QWindowSurface, QWindow
*/
diff --git a/src/gui/kernel/qplatformwindow_qpa.h b/src/gui/kernel/qplatformwindow_qpa.h
index 78090def0a..ffc3b75c1b 100644
--- a/src/gui/kernel/qplatformwindow_qpa.h
+++ b/src/gui/kernel/qplatformwindow_qpa.h
@@ -41,12 +41,14 @@
#ifndef QPLATFORMWINDOW_H
#define QPLATFORMWINDOW_H
-
#include <QtCore/qscopedpointer.h>
#include <QtCore/qrect.h>
+#include <QtCore/qmargins.h>
#include <QtCore/qstring.h>
#include <QtGui/qwindowdefs.h>
-
+#include <QtGui/qwindow.h>
+#include <QtGui/qplatformopenglcontext_qpa.h>
+#include <QtGui/qplatformsurface_qpa.h>
QT_BEGIN_HEADER
@@ -54,24 +56,33 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Gui)
+class QPlatformScreen;
class QPlatformWindowPrivate;
-class QWidget;
-class QPlatformGLContext;
+class QWindow;
-class Q_GUI_EXPORT QPlatformWindow
+class Q_GUI_EXPORT QPlatformWindow : public QPlatformSurface
{
Q_DECLARE_PRIVATE(QPlatformWindow)
public:
- QPlatformWindow(QWidget *tlw);
+ QPlatformWindow(QWindow *window);
virtual ~QPlatformWindow();
- QWidget *widget() const;
+ QWindow *window() const;
+ QPlatformWindow *parent() const;
+
+ QPlatformScreen *screen() const;
+
+ virtual QSurfaceFormat format() const;
+
virtual void setGeometry(const QRect &rect);
virtual QRect geometry() const;
+ virtual QMargins frameMargins() const;
+
virtual void setVisible(bool visible);
virtual Qt::WindowFlags setWindowFlags(Qt::WindowFlags flags);
- virtual Qt::WindowFlags windowFlags() const;
+ virtual Qt::WindowState setWindowState(Qt::WindowState state);
+
virtual WId winId() const;
virtual void setParent(const QPlatformWindow *window);
@@ -79,10 +90,14 @@ public:
virtual void raise();
virtual void lower();
+ virtual void propagateSizeHints();
+
virtual void setOpacity(qreal level);
virtual void requestActivateWindow();
- virtual QPlatformGLContext *glContext() const;
+ virtual bool setKeyboardGrabEnabled(bool grab);
+ virtual bool setMouseGrabEnabled(bool grab);
+
protected:
QScopedPointer<QPlatformWindowPrivate> d_ptr;
private:
diff --git a/src/gui/kernel/qplatformwindowformat_qpa.cpp b/src/gui/kernel/qplatformwindowformat_qpa.cpp
deleted file mode 100644
index 482ae68a2b..0000000000
--- a/src/gui/kernel/qplatformwindowformat_qpa.cpp
+++ /dev/null
@@ -1,994 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qplatformwindowformat_qpa.h"
-
-#include <QtCore/QDebug>
-
-Q_GLOBAL_STATIC(QPlatformWindowFormat, q_platformwindow_default_format);
-
-class QPlatformWindowFormatPrivate
-{
-public:
- QPlatformWindowFormatPrivate()
- : ref(1)
- , opts(QPlatformWindowFormat::DoubleBuffer | QPlatformWindowFormat::DepthBuffer
- | QPlatformWindowFormat::Rgba | QPlatformWindowFormat::DirectRendering
- | QPlatformWindowFormat::StencilBuffer | QPlatformWindowFormat::DeprecatedFunctions
- | QPlatformWindowFormat::HasWindowSurface)
- , depthSize(-1)
- , accumSize(-1)
- , stencilSize(-1)
- , redSize(-1)
- , greenSize(-1)
- , blueSize(-1)
- , alphaSize(-1)
- , numSamples(-1)
- , swapInterval(-1)
- , windowApi(QPlatformWindowFormat::Raster)
- , sharedContext(0)
- {
- }
-
- QPlatformWindowFormatPrivate(const QPlatformWindowFormatPrivate *other)
- : ref(1),
- opts(other->opts),
- depthSize(other->depthSize),
- accumSize(other->accumSize),
- stencilSize(other->stencilSize),
- redSize(other->redSize),
- greenSize(other->greenSize),
- blueSize(other->blueSize),
- alphaSize(other->alphaSize),
- numSamples(other->numSamples),
- swapInterval(other->swapInterval),
- windowApi(other->windowApi),
- sharedContext(other->sharedContext)
- {
- }
- QAtomicInt ref;
- QPlatformWindowFormat::FormatOptions opts;
- int depthSize;
- int accumSize;
- int stencilSize;
- int redSize;
- int greenSize;
- int blueSize;
- int alphaSize;
- int numSamples;
- int swapInterval;
- QPlatformWindowFormat::WindowApi windowApi;
- QPlatformGLContext *sharedContext;
-};
-
-/*!
- \class QPlatformWindowFormat
- \brief The QPlatformWindowFormat class specifies the display format of an OpenGL
- rendering context and if possible attributes of the corresponding QPlatformWindow.
-
- \ingroup painting
-
- QWidget has a setter and getter function for QPlatformWindowFormat. These functions can be used
- by the application programmer to signal what kind of format he wants to the window and glcontext
- should have. However, it is not always possible to fulfill these requirements. The application
- programmer should therefore check the resulting QPlatformWindowFormat from QPlatformGLContext
- to see the format that was actually created.
-
- A display format has several characteristics:
- \list
- \i \link setDoubleBuffer() Double or single buffering.\endlink
- \i \link setDepth() Depth buffer.\endlink
- \i \link setRgba() RGBA or color index mode.\endlink
- \i \link setAlpha() Alpha channel.\endlink
- \i \link setAccum() Accumulation buffer.\endlink
- \i \link setStencil() Stencil buffer.\endlink
- \i \link setStereo() Stereo buffers.\endlink
- \i \link setDirectRendering() Direct rendering.\endlink
- \i \link setSampleBuffers() Multisample buffers.\endlink
- \endlist
-
- You can also specify preferred bit depths for the color buffer,
- depth buffer, alpha buffer, accumulation buffer and the stencil
- buffer with the functions: setRedBufferSize(), setGreenBufferSize(),
- setBlueBufferSize(), setDepthBufferSize(), setAlphaBufferSize(),
- setAccumBufferSize() and setStencilBufferSize().
-
- Note that even if you specify that you prefer a 32 bit depth
- buffer (e.g. with setDepthBufferSize(32)), the format that is
- chosen may not have a 32 bit depth buffer, even if there is a
- format available with a 32 bit depth buffer. The main reason for
- this is how the system dependant picking algorithms work on the
- different platforms, and some format options may have higher
- precedence than others.
-
- You create and tell a QPlatformWindowFormat object what rendering options you
- want from an OpenGL rendering context.
-
- OpenGL drivers or accelerated hardware may or may not support
- advanced features such as alpha channel or stereographic viewing.
- If you request some features that the driver/hardware does not
- provide when you create a QGLWidget, you will get a rendering
- context with the nearest subset of features.
-
- There are different ways to define the display characteristics of
- a rendering context. One is to create a QPlatformWindowFormat and make it the
- default for the entire application:
- \snippet doc/src/snippets/code/src_opengl_qgl.cpp 0
-
- Or you can specify the desired format when creating an object of
- your QGLWidget subclass:
- \snippet doc/src/snippets/code/src_opengl_qgl.cpp 1
-
- After the widget has been created, you can find out which of the
- requested features the system was able to provide:
- \snippet doc/src/snippets/code/src_opengl_qgl.cpp 2
-
- \legalese
- OpenGL is a trademark of Silicon Graphics, Inc. in the
- United States and other countries.
- \endlegalese
-
- \sa QPlatformGLContext, QWidget
-*/
-
-/*!
- Constructs a QPlatformWindowFormat object with the following default settings:
- \list
- \i \link setDoubleBuffer() Double buffer:\endlink Enabled.
- \i \link setDepth() Depth buffer:\endlink Enabled.
- \i \link setRgba() RGBA:\endlink Enabled (i.e., color index disabled).
- \i \link setAlpha() Alpha channel:\endlink Disabled.
- \i \link setAccum() Accumulator buffer:\endlink Disabled.
- \i \link setStencil() Stencil buffer:\endlink Enabled.
- \i \link setStereo() Stereo:\endlink Disabled.
- \i \link setDirectRendering() Direct rendering:\endlink Enabled.
- \i \link setSampleBuffers() Multisample buffers:\endlink Disabled.
- \endlist
-*/
-
-QPlatformWindowFormat::QPlatformWindowFormat()
-{
- d = new QPlatformWindowFormatPrivate;
-}
-
-
-/*!
- Creates a QPlatformWindowFormat object that is a copy of the current
- defaultFormat().
-
- If \a options is not 0, the default format is modified by the
- specified format options. The \a options parameter should be
- QGL::FormatOption values OR'ed together.
-
- This constructor makes it easy to specify a certain desired format
- in classes derived from QGLWidget, for example:
- \snippet doc/src/snippets/code/src_opengl_qgl.cpp 3
-
- Note that there are QGL::FormatOption values to turn format settings
- both on and off; e.g., QGL::DepthBuffer and QGL::NoDepthBuffer,
- QGL::DirectRendering and QGL::IndirectRendering, etc.
-
- \sa defaultFormat(), setOption()
-*/
-
-QPlatformWindowFormat::QPlatformWindowFormat(QPlatformWindowFormat::FormatOptions options)
-{
- d = new QPlatformWindowFormatPrivate;
- QPlatformWindowFormat::FormatOptions newOpts = options;
- d->opts = defaultFormat().d->opts;
- d->opts |= (newOpts & 0xffff);
- d->opts &= ~(newOpts >> 16);
-}
-
-/*!
- \internal
-*/
-void QPlatformWindowFormat::detach()
-{
- if (d->ref != 1) {
- QPlatformWindowFormatPrivate *newd = new QPlatformWindowFormatPrivate(d);
- if (!d->ref.deref())
- delete d;
- d = newd;
- }
-}
-
-/*!
- Constructs a copy of \a other.
-*/
-
-QPlatformWindowFormat::QPlatformWindowFormat(const QPlatformWindowFormat &other)
-{
- d = other.d;
- d->ref.ref();
-}
-
-/*!
- Assigns \a other to this object.
-*/
-
-QPlatformWindowFormat &QPlatformWindowFormat::operator=(const QPlatformWindowFormat &other)
-{
- if (d != other.d) {
- other.d->ref.ref();
- if (!d->ref.deref())
- delete d;
- d = other.d;
- }
- return *this;
-}
-
-/*!
- Destroys the QPlatformWindowFormat.
-*/
-QPlatformWindowFormat::~QPlatformWindowFormat()
-{
- if (!d->ref.deref())
- delete d;
-}
-
-/*!
- \fn bool QPlatformWindowFormat::doubleBuffer() const
-
- Returns true if double buffering is enabled; otherwise returns
- false. Double buffering is enabled by default.
-
- \sa setDoubleBuffer()
-*/
-
-/*!
- If \a enable is true sets double buffering; otherwise sets single
- buffering.
-
- Double buffering is enabled by default.
-
- Double buffering is a technique where graphics are rendered on an
- off-screen buffer and not directly to the screen. When the drawing
- has been completed, the program calls a swapBuffers() function to
- exchange the screen contents with the buffer. The result is
- flicker-free drawing and often better performance.
-
- \sa doubleBuffer(), QGLContext::swapBuffers(),
- QGLWidget::swapBuffers()
-*/
-
-void QPlatformWindowFormat::setDoubleBuffer(bool enable)
-{
- setOption(enable ? QPlatformWindowFormat::DoubleBuffer : QPlatformWindowFormat::SingleBuffer);
-}
-
-
-/*!
- \fn bool QPlatformWindowFormat::depth() const
-
- Returns true if the depth buffer is enabled; otherwise returns
- false. The depth buffer is enabled by default.
-
- \sa setDepth(), setDepthBufferSize()
-*/
-
-/*!
- If \a enable is true enables the depth buffer; otherwise disables
- the depth buffer.
-
- The depth buffer is enabled by default.
-
- The purpose of a depth buffer (or Z-buffering) is to remove hidden
- surfaces. Pixels are assigned Z values based on the distance to
- the viewer. A pixel with a high Z value is closer to the viewer
- than a pixel with a low Z value. This information is used to
- decide whether to draw a pixel or not.
-
- \sa depth(), setDepthBufferSize()
-*/
-
-void QPlatformWindowFormat::setDepth(bool enable)
-{
- setOption(enable ? QPlatformWindowFormat::DepthBuffer : QPlatformWindowFormat::NoDepthBuffer);
-}
-
-
-/*!
- \fn bool QPlatformWindowFormat::rgba() const
-
- Returns true if RGBA color mode is set. Returns false if color
- index mode is set. The default color mode is RGBA.
-
- \sa setRgba()
-*/
-
-/*!
- If \a enable is true sets RGBA mode. If \a enable is false sets
- color index mode.
-
- The default color mode is RGBA.
-
- RGBA is the preferred mode for most OpenGL applications. In RGBA
- color mode you specify colors as red + green + blue + alpha
- quadruplets.
-
- In color index mode you specify an index into a color lookup
- table.
-
- \sa rgba()
-*/
-
-void QPlatformWindowFormat::setRgba(bool enable)
-{
- setOption(enable ? QPlatformWindowFormat::Rgba : QPlatformWindowFormat::ColorIndex);
-}
-
-
-/*!
- \fn bool QPlatformWindowFormat::alpha() const
-
- Returns true if the alpha buffer in the framebuffer is enabled;
- otherwise returns false. The alpha buffer is disabled by default.
-
- \sa setAlpha(), setAlphaBufferSize()
-*/
-
-/*!
- If \a enable is true enables the alpha buffer; otherwise disables
- the alpha buffer.
-
- The alpha buffer is disabled by default.
-
- The alpha buffer is typically used for implementing transparency
- or translucency. The A in RGBA specifies the transparency of a
- pixel.
-
- \sa alpha(), setAlphaBufferSize()
-*/
-
-void QPlatformWindowFormat::setAlpha(bool enable)
-{
- setOption(enable ? QPlatformWindowFormat::AlphaChannel : QPlatformWindowFormat::NoAlphaChannel);
-}
-
-
-/*!
- \fn bool QPlatformWindowFormat::accum() const
-
- Returns true if the accumulation buffer is enabled; otherwise
- returns false. The accumulation buffer is disabled by default.
-
- \sa setAccum(), setAccumBufferSize()
-*/
-
-/*!
- If \a enable is true enables the accumulation buffer; otherwise
- disables the accumulation buffer.
-
- The accumulation buffer is disabled by default.
-
- The accumulation buffer is used to create blur effects and
- multiple exposures.
-
- \sa accum(), setAccumBufferSize()
-*/
-
-void QPlatformWindowFormat::setAccum(bool enable)
-{
- setOption(enable ? QPlatformWindowFormat::AccumBuffer : QPlatformWindowFormat::NoAccumBuffer);
-}
-
-
-/*!
- \fn bool QPlatformWindowFormat::stencil() const
-
- Returns true if the stencil buffer is enabled; otherwise returns
- false. The stencil buffer is enabled by default.
-
- \sa setStencil(), setStencilBufferSize()
-*/
-
-/*!
- If \a enable is true enables the stencil buffer; otherwise
- disables the stencil buffer.
-
- The stencil buffer is enabled by default.
-
- The stencil buffer masks certain parts of the drawing area so that
- masked parts are not drawn on.
-
- \sa stencil(), setStencilBufferSize()
-*/
-
-void QPlatformWindowFormat::setStencil(bool enable)
-{
- setOption(enable ? QPlatformWindowFormat::StencilBuffer: QPlatformWindowFormat::NoStencilBuffer);
-}
-
-
-/*!
- \fn bool QPlatformWindowFormat::stereo() const
-
- Returns true if stereo buffering is enabled; otherwise returns
- false. Stereo buffering is disabled by default.
-
- \sa setStereo()
-*/
-
-/*!
- If \a enable is true enables stereo buffering; otherwise disables
- stereo buffering.
-
- Stereo buffering is disabled by default.
-
- Stereo buffering provides extra color buffers to generate left-eye
- and right-eye images.
-
- \sa stereo()
-*/
-
-void QPlatformWindowFormat::setStereo(bool enable)
-{
- setOption(enable ? QPlatformWindowFormat::StereoBuffers : QPlatformWindowFormat::NoStereoBuffers);
-}
-
-
-/*!
- \fn bool QPlatformWindowFormat::directRendering() const
-
- Returns true if direct rendering is enabled; otherwise returns
- false.
-
- Direct rendering is enabled by default.
-
- \sa setDirectRendering()
-*/
-
-/*!
- If \a enable is true enables direct rendering; otherwise disables
- direct rendering.
-
- Direct rendering is enabled by default.
-
- Enabling this option will make OpenGL bypass the underlying window
- system and render directly from hardware to the screen, if this is
- supported by the system.
-
- \sa directRendering()
-*/
-
-void QPlatformWindowFormat::setDirectRendering(bool enable)
-{
- setOption(enable ? QPlatformWindowFormat::DirectRendering : QPlatformWindowFormat::IndirectRendering);
-}
-
-/*!
- \fn bool QPlatformWindowFormat::sampleBuffers() const
-
- Returns true if multisample buffer support is enabled; otherwise
- returns false.
-
- The multisample buffer is disabled by default.
-
- \sa setSampleBuffers()
-*/
-
-/*!
- If \a enable is true, a GL context with multisample buffer support
- is picked; otherwise ignored.
-
- \sa sampleBuffers(), setSamples(), samples()
-*/
-void QPlatformWindowFormat::setSampleBuffers(bool enable)
-{
- setOption(enable ? QPlatformWindowFormat::SampleBuffers : QPlatformWindowFormat::NoSampleBuffers);
-}
-
-/*!
- Returns the number of samples per pixel when multisampling is
- enabled. By default, the highest number of samples that is
- available is used.
-
- \sa setSampleBuffers(), sampleBuffers(), setSamples()
-*/
-int QPlatformWindowFormat::samples() const
-{
- return d->numSamples;
-}
-
-/*!
- Set the preferred number of samples per pixel when multisampling
- is enabled to \a numSamples. By default, the highest number of
- samples available is used.
-
- \sa setSampleBuffers(), sampleBuffers(), samples()
-*/
-void QPlatformWindowFormat::setSamples(int numSamples)
-{
- detach();
- if (numSamples < 0) {
- qWarning("QPlatformWindowFormat::setSamples: Cannot have negative number of samples per pixel %d", numSamples);
- return;
- }
- d->numSamples = numSamples;
- setSampleBuffers(numSamples > 0);
-}
-
-/*!
- \since 4.2
-
- Set the preferred swap interval. This can be used to sync the GL
- drawing into a system window to the vertical refresh of the screen.
- Setting an \a interval value of 0 will turn the vertical refresh syncing
- off, any value higher than 0 will turn the vertical syncing on.
-
- Under Windows and under X11, where the \c{WGL_EXT_swap_control}
- and \c{GLX_SGI_video_sync} extensions are used, the \a interval
- parameter can be used to set the minimum number of video frames
- that are displayed before a buffer swap will occur. In effect,
- setting the \a interval to 10, means there will be 10 vertical
- retraces between every buffer swap.
-
- Under Windows the \c{WGL_EXT_swap_control} extension has to be present,
- and under X11 the \c{GLX_SGI_video_sync} extension has to be present.
-*/
-void QPlatformWindowFormat::setSwapInterval(int interval)
-{
- detach();
- d->swapInterval = interval;
-}
-
-/*!
- \since 4.2
-
- Returns the currently set swap interval. -1 is returned if setting
- the swap interval isn't supported in the system GL implementation.
-*/
-int QPlatformWindowFormat::swapInterval() const
-{
- return d->swapInterval;
-}
-
-void QPlatformWindowFormat::setWindowApi(QPlatformWindowFormat::WindowApi api)
-{
- detach();
- d->windowApi = api;
-}
-
-QPlatformWindowFormat::WindowApi QPlatformWindowFormat::windowApi() const
-{
- return d->windowApi;
-}
-
-void QPlatformWindowFormat::setSharedContext(QPlatformGLContext *context)
-{
- d->sharedContext = context;
-}
-
-QPlatformGLContext *QPlatformWindowFormat::sharedGLContext() const
-{
- return d->sharedContext;
-}
-
-/*!
- \fn bool QPlatformWindowFormat::hasWindowSurface() const
-
- Returns true if the corresponding widget has an instance of QWindowSurface.
-
- Otherwise returns false.
-
- WindowSurface is enabled by default.
-*/
-
-/*!
- If \a enable is true a top level QWidget will create a QWindowSurface at creation;
-
- otherwise the QWidget will only have a QPlatformWindow.
-
- This is useful for QGLWidget where the QPlatformGLContext controls the surface.
-*/
-
-void QPlatformWindowFormat::setWindowSurface(bool enable)
-{
- setOption(enable ? QPlatformWindowFormat::HasWindowSurface : QPlatformWindowFormat::NoWindowSurface);
-}
-
-/*!
- Sets the format option to \a opt.
-
- \sa testOption()
-*/
-
-void QPlatformWindowFormat::setOption(QPlatformWindowFormat::FormatOptions opt)
-{
- detach();
- if (opt & 0xffff)
- d->opts |= opt;
- else
- d->opts &= ~(opt >> 16);
-}
-
-
-
-/*!
- Returns true if format option \a opt is set; otherwise returns false.
-
- \sa setOption()
-*/
-
-bool QPlatformWindowFormat::testOption(QPlatformWindowFormat::FormatOptions opt) const
-{
- if (opt & 0xffff)
- return (d->opts & opt) != 0;
- else
- return (d->opts & (opt >> 16)) == 0;
-}
-
-/*!
- Set the minimum depth buffer size to \a size.
-
- \sa depthBufferSize(), setDepth(), depth()
-*/
-void QPlatformWindowFormat::setDepthBufferSize(int size)
-{
- detach();
- if (size < 0) {
- qWarning("QPlatformWindowFormat::setDepthBufferSize: Cannot set negative depth buffer size %d", size);
- return;
- }
- d->depthSize = size;
- setDepth(size > 0);
-}
-
-/*!
- Returns the depth buffer size.
-
- \sa depth(), setDepth(), setDepthBufferSize()
-*/
-int QPlatformWindowFormat::depthBufferSize() const
-{
- return d->depthSize;
-}
-
-/*!
- \since 4.2
-
- Set the preferred red buffer size to \a size.
-
- \sa setGreenBufferSize(), setBlueBufferSize(), setAlphaBufferSize()
-*/
-void QPlatformWindowFormat::setRedBufferSize(int size)
-{
- detach();
- if (size < 0) {
- qWarning("QPlatformWindowFormat::setRedBufferSize: Cannot set negative red buffer size %d", size);
- return;
- }
- d->redSize = size;
-}
-
-/*!
- \since 4.2
-
- Returns the red buffer size.
-
- \sa setRedBufferSize()
-*/
-int QPlatformWindowFormat::redBufferSize() const
-{
- return d->redSize;
-}
-
-/*!
- \since 4.2
-
- Set the preferred green buffer size to \a size.
-
- \sa setRedBufferSize(), setBlueBufferSize(), setAlphaBufferSize()
-*/
-void QPlatformWindowFormat::setGreenBufferSize(int size)
-{
- detach();
- if (size < 0) {
- qWarning("QPlatformWindowFormat::setGreenBufferSize: Cannot set negative green buffer size %d", size);
- return;
- }
- d->greenSize = size;
-}
-
-/*!
- \since 4.2
-
- Returns the green buffer size.
-
- \sa setGreenBufferSize()
-*/
-int QPlatformWindowFormat::greenBufferSize() const
-{
- return d->greenSize;
-}
-
-/*!
- \since 4.2
-
- Set the preferred blue buffer size to \a size.
-
- \sa setRedBufferSize(), setGreenBufferSize(), setAlphaBufferSize()
-*/
-void QPlatformWindowFormat::setBlueBufferSize(int size)
-{
- detach();
- if (size < 0) {
- qWarning("QPlatformWindowFormat::setBlueBufferSize: Cannot set negative blue buffer size %d", size);
- return;
- }
- d->blueSize = size;
-}
-
-/*!
- \since 4.2
-
- Returns the blue buffer size.
-
- \sa setBlueBufferSize()
-*/
-int QPlatformWindowFormat::blueBufferSize() const
-{
- return d->blueSize;
-}
-
-/*!
- Set the preferred alpha buffer size to \a size.
- This function implicitly enables the alpha channel.
-
- \sa setRedBufferSize(), setGreenBufferSize(), alphaBufferSize()
-*/
-void QPlatformWindowFormat::setAlphaBufferSize(int size)
-{
- detach();
- if (size < 0) {
- qWarning("QPlatformWindowFormat::setAlphaBufferSize: Cannot set negative alpha buffer size %d", size);
- return;
- }
- d->alphaSize = size;
- setAlpha(size > 0);
-}
-
-/*!
- Returns the alpha buffer size.
-
- \sa alpha(), setAlpha(), setAlphaBufferSize()
-*/
-int QPlatformWindowFormat::alphaBufferSize() const
-{
- return d->alphaSize;
-}
-
-/*!
- Set the preferred accumulation buffer size, where \a size is the
- bit depth for each RGBA component.
-
- \sa accum(), setAccum(), accumBufferSize()
-*/
-void QPlatformWindowFormat::setAccumBufferSize(int size)
-{
- detach();
- if (size < 0) {
- qWarning("QPlatformWindowFormat::setAccumBufferSize: Cannot set negative accumulate buffer size %d", size);
- return;
- }
- d->accumSize = size;
- setAccum(size > 0);
-}
-
-/*!
- Returns the accumulation buffer size.
-
- \sa setAccumBufferSize(), accum(), setAccum()
-*/
-int QPlatformWindowFormat::accumBufferSize() const
-{
- return d->accumSize;
-}
-
-/*!
- Set the preferred stencil buffer size to \a size.
-
- \sa stencilBufferSize(), setStencil(), stencil()
-*/
-void QPlatformWindowFormat::setStencilBufferSize(int size)
-{
- detach();
- if (size < 0) {
- qWarning("QPlatformWindowFormat::setStencilBufferSize: Cannot set negative stencil buffer size %d", size);
- return;
- }
- d->stencilSize = size;
- setStencil(size > 0);
-}
-
-/*!
- Returns the stencil buffer size.
-
- \sa stencil(), setStencil(), setStencilBufferSize()
-*/
-int QPlatformWindowFormat::stencilBufferSize() const
-{
- return d->stencilSize;
-}
-
-/*!
- Returns the default QPlatformWindowFormat for the application. All QGLWidget
- objects that are created use this format unless another format is
- specified, e.g. when they are constructed.
-
- If no special default format has been set using
- setDefaultFormat(), the default format is the same as that created
- with QPlatformWindowFormat().
-
- \sa setDefaultFormat()
-*/
-
-QPlatformWindowFormat QPlatformWindowFormat::defaultFormat()
-{
- return *q_platformwindow_default_format();
-}
-
-/*!
- Sets a new default QPlatformWindowFormat for the application to \a f. For
- example, to set single buffering as the default instead of double
- buffering, your main() might contain code like this:
- \snippet doc/src/snippets/code/src_opengl_qgl.cpp 4
-
- \sa defaultFormat()
-*/
-
-void QPlatformWindowFormat::setDefaultFormat(const QPlatformWindowFormat &f)
-{
- *q_platformwindow_default_format() = f;
-}
-
-
-/*
- Returns the default QPlatformWindowFormat for overlay contexts.
-
- The default overlay format is:
- \list
- \i \link setDoubleBuffer() Double buffer:\endlink Disabled.
- \i \link setDepth() Depth buffer:\endlink Disabled.
- \i \link setRgba() RGBA:\endlink Disabled (i.e., color index enabled).
- \i \link setAlpha() Alpha channel:\endlink Disabled.
- \i \link setAccum() Accumulator buffer:\endlink Disabled.
- \i \link setStencil() Stencil buffer:\endlink Disabled.
- \i \link setStereo() Stereo:\endlink Disabled.
- \i \link setDirectRendering() Direct rendering:\endlink Enabled.
- \i \link setSampleBuffers() Multisample buffers:\endlink Disabled.
- \endlist
-
- \sa setDefaultFormat()
-*/
-
-//QPlatformWindowFormat QPlatformWindowFormat::defaultOverlayFormat()
-//{
-// return *defaultOverlayFormatInstance();
-//}
-
-///*!
-// Sets a new default QPlatformWindowFormat for overlay contexts to \a f. This
-// format is used whenever a QGLWidget is created with a format that
-// hasOverlay() enabled.
-
-// For example, to get a double buffered overlay context (if
-// available), use code like this:
-
-// \snippet doc/src/snippets/code/src_opengl_qgl.cpp 5
-
-// As usual, you can find out after widget creation whether the
-// underlying OpenGL system was able to provide the requested
-// specification:
-
-// \snippet doc/src/snippets/code/src_opengl_qgl.cpp 6
-
-// \sa defaultOverlayFormat()
-//*/
-
-//void QPlatformWindowFormat::setDefaultOverlayFormat(const QPlatformWindowFormat &f)
-//{
-// QPlatformWindowFormat *defaultFormat = defaultOverlayFormatInstance();
-// *defaultFormat = f;
-// // Make sure the user doesn't request that the overlays themselves
-// // have overlays, since it is unlikely that the system supports
-// // infinitely many planes...
-// defaultFormat->setOverlay(false);
-//}
-
-
-/*!
- Returns true if all the options of the two QPlatformWindowFormat objects
- \a a and \a b are equal; otherwise returns false.
-
- \relates QPlatformWindowFormat
-*/
-
-bool operator==(const QPlatformWindowFormat& a, const QPlatformWindowFormat& b)
-{
- return (a.d == b.d) || ((int) a.d->opts == (int) b.d->opts
- && a.d->alphaSize == b.d->alphaSize
- && a.d->accumSize == b.d->accumSize
- && a.d->stencilSize == b.d->stencilSize
- && a.d->depthSize == b.d->depthSize
- && a.d->redSize == b.d->redSize
- && a.d->greenSize == b.d->greenSize
- && a.d->blueSize == b.d->blueSize
- && a.d->numSamples == b.d->numSamples
- && a.d->swapInterval == b.d->swapInterval
- && a.d->windowApi == b.d->windowApi);
-}
-
-
-/*!
- Returns false if all the options of the two QPlatformWindowFormat objects
- \a a and \a b are equal; otherwise returns true.
-
- \relates QPlatformWindowFormat
-*/
-
-bool operator!=(const QPlatformWindowFormat& a, const QPlatformWindowFormat& b)
-{
- return !(a == b);
-}
-
-#ifndef QT_NO_DEBUG_STREAM
-QDebug operator<<(QDebug dbg, const QPlatformWindowFormat &f)
-{
- const QPlatformWindowFormatPrivate * const d = f.d;
-
- dbg.nospace() << "QGLFormat("
- << "options " << d->opts
- << ", depthBufferSize " << d->depthSize
- << ", accumBufferSize " << d->accumSize
- << ", stencilBufferSize " << d->stencilSize
- << ", redBufferSize " << d->redSize
- << ", greenBufferSize " << d->greenSize
- << ", blueBufferSize " << d->blueSize
- << ", alphaBufferSize " << d->alphaSize
- << ", samples " << d->numSamples
- << ", swapInterval " << d->swapInterval
- << ')';
-
- return dbg.space();
-}
-#endif
diff --git a/src/gui/kernel/qplatformwindowformat_qpa.h b/src/gui/kernel/qplatformwindowformat_qpa.h
deleted file mode 100644
index e7dde79261..0000000000
--- a/src/gui/kernel/qplatformwindowformat_qpa.h
+++ /dev/null
@@ -1,234 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#ifndef QPLATFORMWINDOWFORMAT_QPA_H
-#define QPLATFORMWINDOWFORMAT_QPA_H
-
-#include <QtGui/QPlatformWindow>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QPlatformWindowFormatPrivate;
-
-class Q_GUI_EXPORT QPlatformWindowFormat
-{
-public:
- enum FormatOption {
- DoubleBuffer = 0x0001,
- DepthBuffer = 0x0002,
- Rgba = 0x0004,
- AlphaChannel = 0x0008,
- AccumBuffer = 0x0010,
- StencilBuffer = 0x0020,
- StereoBuffers = 0x0040,
- DirectRendering = 0x0080,
- HasOverlay = 0x0100,
- SampleBuffers = 0x0200,
- DeprecatedFunctions = 0x0400,
- HasWindowSurface = 0x0800,
- SingleBuffer = DoubleBuffer << 16,
- NoDepthBuffer = DepthBuffer << 16,
- ColorIndex = Rgba << 16,
- NoAlphaChannel = AlphaChannel << 16,
- NoAccumBuffer = AccumBuffer << 16,
- NoStencilBuffer = StencilBuffer << 16,
- NoStereoBuffers = StereoBuffers << 16,
- IndirectRendering = DirectRendering << 16,
- NoOverlay = HasOverlay << 16,
- NoSampleBuffers = SampleBuffers << 16,
- NoDeprecatedFunctions = DeprecatedFunctions << 16,
- NoWindowSurface = HasWindowSurface << 16
-
- };
- Q_DECLARE_FLAGS(FormatOptions, FormatOption)
-
- enum WindowApi {
- Raster,
- OpenGL,
- OpenVG
- };
-
- QPlatformWindowFormat();
- QPlatformWindowFormat(FormatOptions options);
- QPlatformWindowFormat(const QPlatformWindowFormat &other);
- QPlatformWindowFormat &operator=(const QPlatformWindowFormat &other);
- ~QPlatformWindowFormat();
-
- void setDepthBufferSize(int size);
- int depthBufferSize() const;
-
- void setAccumBufferSize(int size);
- int accumBufferSize() const;
-
- void setRedBufferSize(int size);
- int redBufferSize() const;
-
- void setGreenBufferSize(int size);
- int greenBufferSize() const;
-
- void setBlueBufferSize(int size);
- int blueBufferSize() const;
-
- void setAlphaBufferSize(int size);
- int alphaBufferSize() const;
-
- void setStencilBufferSize(int size);
- int stencilBufferSize() const;
-
- void setSampleBuffers(bool enable);
- bool sampleBuffers() const;
-
- void setSamples(int numSamples);
- int samples() const;
-
- void setSwapInterval(int interval);
- int swapInterval() const;
-
- void setWindowApi(QPlatformWindowFormat::WindowApi api);
- WindowApi windowApi() const;
-
- void setSharedContext(QPlatformGLContext *context);
- QPlatformGLContext *sharedGLContext() const;
-
- bool doubleBuffer() const;
- void setDoubleBuffer(bool enable);
- bool depth() const;
- void setDepth(bool enable);
- bool rgba() const;
- void setRgba(bool enable);
- bool alpha() const;
- void setAlpha(bool enable);
- bool accum() const;
- void setAccum(bool enable);
- bool stencil() const;
- void setStencil(bool enable);
- bool stereo() const;
- void setStereo(bool enable);
- bool directRendering() const;
- void setDirectRendering(bool enable);
- bool hasWindowSurface() const;
- void setWindowSurface(bool enable);
-
- void setOption(QPlatformWindowFormat::FormatOptions opt);
- bool testOption(QPlatformWindowFormat::FormatOptions opt) const;
-
- static QPlatformWindowFormat defaultFormat();
- static void setDefaultFormat(const QPlatformWindowFormat& f);
-
-private:
- QPlatformWindowFormatPrivate *d;
-
- void detach();
-
- friend Q_GUI_EXPORT bool operator==(const QPlatformWindowFormat&, const QPlatformWindowFormat&);
- friend Q_GUI_EXPORT bool operator!=(const QPlatformWindowFormat&, const QPlatformWindowFormat&);
-#ifndef QT_NO_DEBUG_STREAM
- friend Q_GUI_EXPORT QDebug operator<<(QDebug, const QPlatformWindowFormat &);
-#endif
-};
-
-Q_GUI_EXPORT bool operator==(const QPlatformWindowFormat&, const QPlatformWindowFormat&);
-Q_GUI_EXPORT bool operator!=(const QPlatformWindowFormat&, const QPlatformWindowFormat&);
-
-#ifndef QT_NO_DEBUG_STREAM
-Q_OPENGL_EXPORT QDebug operator<<(QDebug, const QPlatformWindowFormat &);
-#endif
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QPlatformWindowFormat::FormatOptions)
-
-inline bool QPlatformWindowFormat::doubleBuffer() const
-{
- return testOption(QPlatformWindowFormat::DoubleBuffer);
-}
-
-inline bool QPlatformWindowFormat::depth() const
-{
- return testOption(QPlatformWindowFormat::DepthBuffer);
-}
-
-inline bool QPlatformWindowFormat::rgba() const
-{
- return testOption(QPlatformWindowFormat::Rgba);
-}
-
-inline bool QPlatformWindowFormat::alpha() const
-{
- return testOption(QPlatformWindowFormat::AlphaChannel);
-}
-
-inline bool QPlatformWindowFormat::accum() const
-{
- return testOption(QPlatformWindowFormat::AccumBuffer);
-}
-
-inline bool QPlatformWindowFormat::stencil() const
-{
- return testOption(QPlatformWindowFormat::StencilBuffer);
-}
-
-inline bool QPlatformWindowFormat::stereo() const
-{
- return testOption(QPlatformWindowFormat::StereoBuffers);
-}
-
-inline bool QPlatformWindowFormat::directRendering() const
-{
- return testOption(QPlatformWindowFormat::DirectRendering);
-}
-
-inline bool QPlatformWindowFormat::hasWindowSurface() const
-{
- return testOption(QPlatformWindowFormat::HasWindowSurface);
-}
-
-inline bool QPlatformWindowFormat::sampleBuffers() const
-{
- return testOption(QPlatformWindowFormat::SampleBuffers);
-}
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif //QPLATFORMWINDOWFORMAT_QPA_H
diff --git a/src/gui/kernel/qscreen.cpp b/src/gui/kernel/qscreen.cpp
new file mode 100644
index 0000000000..47db5a0264
--- /dev/null
+++ b/src/gui/kernel/qscreen.cpp
@@ -0,0 +1,212 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qscreen.h"
+#include "qplatformscreen_qpa.h"
+
+#include <QtCore/private/qobject_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QScreenPrivate : public QObjectPrivate
+{
+public:
+ QScreenPrivate(QPlatformScreen *screen)
+ : platformScreen(screen)
+ {
+ }
+
+ QPlatformScreen *platformScreen;
+};
+
+QScreen::QScreen(QPlatformScreen *screen)
+ : QObject(*new QScreenPrivate(screen), 0)
+{
+}
+
+/*!
+ Get the platform screen handle.
+*/
+QPlatformScreen *QScreen::handle() const
+{
+ Q_D(const QScreen);
+ return d->platformScreen;
+}
+
+/*!
+ Get the platform dependent screen name.
+
+ For example, on an X11 platform this should typically be
+ the DISPLAY environment variable corresponding to the screen.
+*/
+QString QScreen::name() const
+{
+ Q_D(const QScreen);
+ return d->platformScreen->name();
+}
+
+/*!
+ Get the screen's color depth.
+*/
+int QScreen::depth() const
+{
+ Q_D(const QScreen);
+ return d->platformScreen->depth();
+}
+
+/*!
+ Get the screen's size.
+*/
+QSize QScreen::size() const
+{
+ Q_D(const QScreen);
+ return d->platformScreen->geometry().size();
+}
+
+/*!
+ Get the screen's available size.
+
+ The available size is the size excluding window manager reserved areas
+ such as task bars and system menus.
+*/
+QSize QScreen::availableSize() const
+{
+ Q_D(const QScreen);
+ return d->platformScreen->availableGeometry().size();
+}
+
+/*!
+ Get the screen's geometry.
+*/
+QRect QScreen::geometry() const
+{
+ Q_D(const QScreen);
+ return d->platformScreen->geometry();
+}
+
+/*!
+ Get the screen's available geometry.
+
+ The available geometry is the geometry excluding window manager reserved areas
+ such as task bars and system menus.
+*/
+QRect QScreen::availableGeometry() const
+{
+ Q_D(const QScreen);
+ return d->platformScreen->availableGeometry();
+}
+
+/*!
+ Get the screen's virtual siblings.
+
+ The virtual siblings are the screen instances sharing the same virtual desktop.
+ They share a common coordinate system, and windows can freely be moved or
+ positioned across them without having to be re-created.
+*/
+QList<QScreen *> QScreen::virtualSiblings() const
+{
+ Q_D(const QScreen);
+ QList<QPlatformScreen *> platformScreens = d->platformScreen->virtualSiblings();
+ QList<QScreen *> screens;
+ foreach (QPlatformScreen *platformScreen, platformScreens)
+ screens << platformScreen->screen();
+ return screens;
+}
+
+/*!
+ Get the size of the virtual desktop corresponding to this screen.
+
+ This is the combined size of the virtual siblings' individual geometries.
+
+ \sa virtualSiblings()
+*/
+QSize QScreen::virtualSize() const
+{
+ return virtualGeometry().size();
+}
+
+/*!
+ Get the geometry of the virtual desktop corresponding to this screen.
+
+ This is the union of the virtual siblings' individual geometries.
+
+ \sa virtualSiblings()
+*/
+QRect QScreen::virtualGeometry() const
+{
+ Q_D(const QScreen);
+ QRect result;
+ foreach (QPlatformScreen *platformScreen, d->platformScreen->virtualSiblings())
+ result |= platformScreen->geometry();
+ return result;
+}
+
+/*!
+ Get the available size of the virtual desktop corresponding to this screen.
+
+ This is the combined size of the virtual siblings' individual available geometries.
+
+ \sa availableSize()
+ \sa virtualSiblings()
+*/
+QSize QScreen::availableVirtualSize() const
+{
+ return availableVirtualGeometry().size();
+}
+
+/*!
+ Get the available size of the virtual desktop corresponding to this screen.
+
+ This is the union of the virtual siblings' individual available geometries.
+
+ \sa availableGeometry()
+ \sa virtualSiblings()
+*/
+QRect QScreen::availableVirtualGeometry() const
+{
+ Q_D(const QScreen);
+ QRect result;
+ foreach (QPlatformScreen *platformScreen, d->platformScreen->virtualSiblings())
+ result |= platformScreen->availableGeometry();
+ return result;
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/kernel/qscreen.h b/src/gui/kernel/qscreen.h
new file mode 100644
index 0000000000..7063578f74
--- /dev/null
+++ b/src/gui/kernel/qscreen.h
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSCREEN_H
+#define QSCREEN_H
+
+#include <QtCore/QList>
+#include <QtCore/QObject>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QPlatformScreen;
+class QScreenPrivate;
+class QWindow;
+class QSize;
+class QRect;
+
+class Q_GUI_EXPORT QScreen : public QObject
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QScreen)
+
+public:
+ QPlatformScreen *handle() const;
+
+ QString name() const;
+
+ int depth() const;
+
+ QSize size() const;
+ QRect geometry() const;
+
+ QSize availableSize() const;
+ QRect availableGeometry() const;
+
+ QList<QScreen *> virtualSiblings() const;
+
+ QSize virtualSize() const;
+ QRect virtualGeometry() const;
+
+ QSize availableVirtualSize() const;
+ QRect availableVirtualGeometry() const;
+
+private:
+ QScreen(QPlatformScreen *screen);
+
+ Q_DISABLE_COPY(QScreen)
+ friend class QPlatformScreen;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QSCREEN_H
+
diff --git a/src/gui/kernel/qsessionmanager.h b/src/gui/kernel/qsessionmanager.h
index 6432a888af..3328fa9011 100644
--- a/src/gui/kernel/qsessionmanager.h
+++ b/src/gui/kernel/qsessionmanager.h
@@ -55,13 +55,15 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Gui)
+class QGuiApplication;
+
class QSessionManagerPrivate;
class Q_GUI_EXPORT QSessionManager : public QObject
{
Q_OBJECT
Q_DECLARE_PRIVATE(QSessionManager)
- QSessionManager(QApplication *app, QString &id, QString &key);
+ QSessionManager(QGuiApplication *app, QString &id, QString &key);
~QSessionManager();
public:
QString sessionId() const;
diff --git a/src/gui/kernel/qsessionmanager_qpa.cpp b/src/gui/kernel/qsessionmanager_qpa.cpp
index bea0e12d9e..7ade0df3a8 100644
--- a/src/gui/kernel/qsessionmanager_qpa.cpp
+++ b/src/gui/kernel/qsessionmanager_qpa.cpp
@@ -40,9 +40,9 @@
****************************************************************************/
#include <qsessionmanager.h>
+#include <qguiapplication.h>
#include <private/qobject_p.h>
-#include <qapplication.h>
#ifndef QT_NO_SESSIONMANAGER
@@ -68,7 +68,7 @@ QSessionManagerPrivate::QSessionManagerPrivate(QSessionManager*,
{
}
-QSessionManager::QSessionManager(QApplication *app, QString &id, QString &key)
+QSessionManager::QSessionManager(QGuiApplication *app, QString &id, QString &key)
: QObject(*(new QSessionManagerPrivate(this, id, key)), app)
{
Q_D(QSessionManager);
diff --git a/src/gui/kernel/qsessionmanager_qws.cpp b/src/gui/kernel/qsessionmanager_qws.cpp
deleted file mode 100644
index efe688e0e5..0000000000
--- a/src/gui/kernel/qsessionmanager_qws.cpp
+++ /dev/null
@@ -1,171 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qsessionmanager.h>
-
-#ifndef QT_NO_SESSIONMANAGER
-
-QT_BEGIN_NAMESPACE
-
-class QSessionManagerPrivate : public QObjectPrivate
-{
-public:
- QSessionManagerPrivate(QSessionManager *m, const QString &id,
- const QString &key);
-
- QStringList restartCommand;
- QStringList discardCommand;
- const QString sessionId;
- const QString sessionKey;
- QSessionManager::RestartHint restartHint;
-};
-
-QSessionManagerPrivate::QSessionManagerPrivate(QSessionManager*,
- const QString &id,
- const QString &key)
- : QObjectPrivate(), sessionId(id), sessionKey(key)
-{
-}
-
-QSessionManager::QSessionManager(QApplication *app, QString &id, QString &key)
- : QObject(*new QSessionManagerPrivate(this, id, key), app)
-{
- Q_D(QSessionManager);
- d->restartHint = RestartIfRunning;
-}
-
-QSessionManager::~QSessionManager()
-{
-}
-
-QString QSessionManager::sessionId() const
-{
- Q_D(const QSessionManager);
- return d->sessionId;
-}
-
-QString QSessionManager::sessionKey() const
-{
- Q_D(const QSessionManager);
- return d->sessionKey;
-}
-
-
-bool QSessionManager::allowsInteraction()
-{
- return false;
-}
-
-bool QSessionManager::allowsErrorInteraction()
-{
- return false;
-}
-
-void QSessionManager::release()
-{
-}
-
-void QSessionManager::cancel()
-{
-}
-
-void QSessionManager::setRestartHint(QSessionManager::RestartHint hint)
-{
- Q_D(QSessionManager);
- d->restartHint = hint;
-}
-
-QSessionManager::RestartHint QSessionManager::restartHint() const
-{
- Q_D(const QSessionManager);
- return d->restartHint;
-}
-
-void QSessionManager::setRestartCommand(const QStringList &command)
-{
- Q_D(QSessionManager);
- d->restartCommand = command;
-}
-
-QStringList QSessionManager::restartCommand() const
-{
- Q_D(const QSessionManager);
- return d->restartCommand;
-}
-
-void QSessionManager::setDiscardCommand(const QStringList &command)
-{
- Q_D(QSessionManager);
- d->discardCommand = command;
-}
-
-QStringList QSessionManager::discardCommand() const
-{
- Q_D(const QSessionManager);
- return d->discardCommand;
-}
-
-void QSessionManager::setManagerProperty(const QString &name,
- const QString &value)
-{
- Q_UNUSED(name);
- Q_UNUSED(value);
-}
-
-void QSessionManager::setManagerProperty(const QString &name,
- const QStringList &value)
-{
- Q_UNUSED(name);
- Q_UNUSED(value);
-}
-
-bool QSessionManager::isPhase2() const
-{
- return false;
-}
-
-void QSessionManager::requestPhase2()
-{
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_SESSIONMANAGER
diff --git a/src/gui/kernel/qshortcut.h b/src/gui/kernel/qshortcut.h
deleted file mode 100644
index 5567b50a98..0000000000
--- a/src/gui/kernel/qshortcut.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSHORTCUT_H
-#define QSHORTCUT_H
-
-#include <QtGui/qwidget.h>
-#include <QtGui/qkeysequence.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_SHORTCUT
-
-class QShortcutPrivate;
-class Q_GUI_EXPORT QShortcut : public QObject
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QShortcut)
- Q_PROPERTY(QKeySequence key READ key WRITE setKey)
- Q_PROPERTY(QString whatsThis READ whatsThis WRITE setWhatsThis)
- Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled)
- Q_PROPERTY(bool autoRepeat READ autoRepeat WRITE setAutoRepeat)
- Q_PROPERTY(Qt::ShortcutContext context READ context WRITE setContext)
-public:
- explicit QShortcut(QWidget *parent);
- QShortcut(const QKeySequence& key, QWidget *parent,
- const char *member = 0, const char *ambiguousMember = 0,
- Qt::ShortcutContext context = Qt::WindowShortcut);
- ~QShortcut();
-
- void setKey(const QKeySequence& key);
- QKeySequence key() const;
-
- void setEnabled(bool enable);
- bool isEnabled() const;
-
- void setContext(Qt::ShortcutContext context);
- Qt::ShortcutContext context();
-
- void setWhatsThis(const QString &text);
- QString whatsThis() const;
-
- void setAutoRepeat(bool on);
- bool autoRepeat() const;
-
- int id() const;
-
- inline QWidget *parentWidget() const
- { return static_cast<QWidget *>(QObject::parent()); }
-
-Q_SIGNALS:
- void activated();
- void activatedAmbiguously();
-
-protected:
- bool event(QEvent *e);
-};
-
-#endif // QT_NO_SHORTCUT
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QSHORTCUT_H
diff --git a/src/gui/kernel/qshortcutmap.cpp b/src/gui/kernel/qshortcutmap.cpp
deleted file mode 100644
index b60578d8e3..0000000000
--- a/src/gui/kernel/qshortcutmap.cpp
+++ /dev/null
@@ -1,897 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qshortcutmap_p.h"
-#include "private/qobject_p.h"
-#include "qkeysequence.h"
-#include "qgraphicsscene.h"
-#include "qgraphicsview.h"
-#include "qdebug.h"
-#include "qevent.h"
-#include "qwidget.h"
-#include "qapplication.h"
-#include "qvector.h"
-#include "qmenu.h"
-#include "qmenubar.h"
-#include "qshortcut.h"
-#include "qapplication_p.h"
-#include <private/qaction_p.h>
-#include <private/qkeymapper_p.h>
-#include <private/qwidget_p.h>
-
-#ifndef QT_NO_SHORTCUT
-
-QT_BEGIN_NAMESPACE
-
-// To enable verbose output uncomment below
-//#define DEBUG_QSHORTCUTMAP
-
-/* \internal
- Entry data for QShortcutMap
- Contains:
- Keysequence for entry
- Pointer to parent owning the sequence
-*/
-struct QShortcutEntry
-{
- QShortcutEntry()
- : keyseq(0), context(Qt::WindowShortcut), enabled(false), autorepeat(1), id(0), owner(0)
- {}
-
- QShortcutEntry(const QKeySequence &k)
- : keyseq(k), context(Qt::WindowShortcut), enabled(false), autorepeat(1), id(0), owner(0)
- {}
-
- QShortcutEntry(QObject *o, const QKeySequence &k, Qt::ShortcutContext c, int i)
- : keyseq(k), context(c), enabled(true), autorepeat(1), id(i), owner(o)
- {}
-
- QShortcutEntry(QObject *o, const QKeySequence &k, Qt::ShortcutContext c, int i, bool a)
- : keyseq(k), context(c), enabled(true), autorepeat(a), id(i), owner(o)
- {}
-
- bool operator<(const QShortcutEntry &f) const
- { return keyseq < f.keyseq; }
-
- QKeySequence keyseq;
- Qt::ShortcutContext context;
- bool enabled : 1;
- bool autorepeat : 1;
- signed int id;
- QObject *owner;
-};
-
-#if 0 //ndef QT_NO_DEBUG_STREAM
-/*! \internal
- QDebug operator<< for easy debug output of the shortcut entries.
-*/
-static QDebug &operator<<(QDebug &dbg, const QShortcutEntry *se) {
- if (!se)
- return dbg << "QShortcutEntry(0x0)";
- dbg.nospace()
- << "QShortcutEntry(" << se->keyseq
- << "), id(" << se->id << "), enabled(" << se->enabled << "), autorepeat(" << se->autorepeat
- << "), owner(" << se->owner << ')';
- return dbg.space();
-}
-#endif // QT_NO_DEBUGSTREAM
-
-/* \internal
- Private data for QShortcutMap
-*/
-class QShortcutMapPrivate
-{
- Q_DECLARE_PUBLIC(QShortcutMap)
-
-public:
- QShortcutMapPrivate(QShortcutMap* parent)
- : q_ptr(parent), currentId(0), ambigCount(0), currentState(QKeySequence::NoMatch)
- {
- identicals.reserve(10);
- currentSequences.reserve(10);
- }
- QShortcutMap *q_ptr; // Private's parent
-
- QList<QShortcutEntry> sequences; // All sequences!
-
- int currentId; // Global shortcut ID number
- int ambigCount; // Index of last enabled ambiguous dispatch
- QKeySequence::SequenceMatch currentState;
- QVector<QKeySequence> currentSequences; // Sequence for the current state
- QVector<QKeySequence> newEntries;
- QKeySequence prevSequence; // Sequence for the previous identical match
- QVector<const QShortcutEntry*> identicals; // Last identical matches
-};
-
-
-/*! \internal
- QShortcutMap constructor.
-*/
-QShortcutMap::QShortcutMap()
- : d_ptr(new QShortcutMapPrivate(this))
-{
- resetState();
-}
-
-/*! \internal
- QShortcutMap destructor.
-*/
-QShortcutMap::~QShortcutMap()
-{
-}
-
-/*! \internal
- Adds a shortcut to the global map.
- Returns the id of the newly added shortcut.
-*/
-int QShortcutMap::addShortcut(QObject *owner, const QKeySequence &key, Qt::ShortcutContext context)
-{
- Q_ASSERT_X(owner, "QShortcutMap::addShortcut", "All shortcuts need an owner");
- Q_ASSERT_X(!key.isEmpty(), "QShortcutMap::addShortcut", "Cannot add keyless shortcuts to map");
- Q_D(QShortcutMap);
-
- QShortcutEntry newEntry(owner, key, context, --(d->currentId), true);
- QList<QShortcutEntry>::iterator it = qUpperBound(d->sequences.begin(), d->sequences.end(), newEntry);
- d->sequences.insert(it, newEntry); // Insert sorted
-#if defined(DEBUG_QSHORTCUTMAP)
- qDebug().nospace()
- << "QShortcutMap::addShortcut(" << owner << ", "
- << key << ", " << context << ") = " << d->currentId;
-#endif
- return d->currentId;
-}
-
-/*! \internal
- Removes a shortcut from the global map.
- If \a owner is 0, all entries in the map with the key sequence specified
- is removed. If \a key is null, all sequences for \a owner is removed from
- the map. If \a id is 0, any identical \a key sequences owned by \a owner
- are removed.
- Returns the number of sequences removed from the map.
-*/
-
-int QShortcutMap::removeShortcut(int id, QObject *owner, const QKeySequence &key)
-{
- Q_D(QShortcutMap);
- int itemsRemoved = 0;
- bool allOwners = (owner == 0);
- bool allKeys = key.isEmpty();
- bool allIds = id == 0;
-
- // Special case, remove everything
- if (allOwners && allKeys && id == 0) {
- itemsRemoved = d->sequences.size();
- d->sequences.clear();
- return itemsRemoved;
- }
-
- int i = d->sequences.size()-1;
- while (i>=0)
- {
- const QShortcutEntry &entry = d->sequences.at(i);
- int entryId = entry.id;
- if ((allOwners || entry.owner == owner)
- && (allIds || entry.id == id)
- && (allKeys || entry.keyseq == key)) {
- d->sequences.removeAt(i);
- ++itemsRemoved;
- }
- if (id == entryId)
- return itemsRemoved;
- --i;
- }
-#if defined(DEBUG_QSHORTCUTMAP)
- qDebug().nospace()
- << "QShortcutMap::removeShortcut(" << id << ", " << owner << ", "
- << key << ") = " << itemsRemoved;
-#endif
- return itemsRemoved;
-}
-
-/*! \internal
- Changes the enable state of a shortcut to \a enable.
- If \a owner is 0, all entries in the map with the key sequence specified
- is removed. If \a key is null, all sequences for \a owner is removed from
- the map. If \a id is 0, any identical \a key sequences owned by \a owner
- are changed.
- Returns the number of sequences which are matched in the map.
-*/
-int QShortcutMap::setShortcutEnabled(bool enable, int id, QObject *owner, const QKeySequence &key)
-{
- Q_D(QShortcutMap);
- int itemsChanged = 0;
- bool allOwners = (owner == 0);
- bool allKeys = key.isEmpty();
- bool allIds = id == 0;
-
- int i = d->sequences.size()-1;
- while (i>=0)
- {
- QShortcutEntry entry = d->sequences.at(i);
- if ((allOwners || entry.owner == owner)
- && (allIds || entry.id == id)
- && (allKeys || entry.keyseq == key)) {
- d->sequences[i].enabled = enable;
- ++itemsChanged;
- }
- if (id == entry.id)
- return itemsChanged;
- --i;
- }
-#if defined(DEBUG_QSHORTCUTMAP)
- qDebug().nospace()
- << "QShortcutMap::setShortcutEnabled(" << enable << ", " << id << ", "
- << owner << ", " << key << ") = " << itemsChanged;
-#endif
- return itemsChanged;
-}
-
-/*! \internal
- Changes the auto repeat state of a shortcut to \a enable.
- If \a owner is 0, all entries in the map with the key sequence specified
- is removed. If \a key is null, all sequences for \a owner is removed from
- the map. If \a id is 0, any identical \a key sequences owned by \a owner
- are changed.
- Returns the number of sequences which are matched in the map.
-*/
-int QShortcutMap::setShortcutAutoRepeat(bool on, int id, QObject *owner, const QKeySequence &key)
-{
- Q_D(QShortcutMap);
- int itemsChanged = 0;
- bool allOwners = (owner == 0);
- bool allKeys = key.isEmpty();
- bool allIds = id == 0;
-
- int i = d->sequences.size()-1;
- while (i>=0)
- {
- QShortcutEntry entry = d->sequences.at(i);
- if ((allOwners || entry.owner == owner)
- && (allIds || entry.id == id)
- && (allKeys || entry.keyseq == key)) {
- d->sequences[i].autorepeat = on;
- ++itemsChanged;
- }
- if (id == entry.id)
- return itemsChanged;
- --i;
- }
-#if defined(DEBUG_QSHORTCUTMAP)
- qDebug().nospace()
- << "QShortcutMap::setShortcutAutoRepeat(" << on << ", " << id << ", "
- << owner << ", " << key << ") = " << itemsChanged;
-#endif
- return itemsChanged;
-}
-
-/*! \internal
- Resets the state of the statemachine to NoMatch
-*/
-void QShortcutMap::resetState()
-{
- Q_D(QShortcutMap);
- d->currentState = QKeySequence::NoMatch;
- clearSequence(d->currentSequences);
-}
-
-/*! \internal
- Returns the current state of the statemachine
-*/
-QKeySequence::SequenceMatch QShortcutMap::state()
-{
- Q_D(QShortcutMap);
- return d->currentState;
-}
-
-/*! \internal
- Uses ShortcutOverride event to see if any widgets want to override
- the event. If not, uses nextState(QKeyEvent) to check for a grabbed
- Shortcut, and dispatchEvent() is found an identical.
- \sa nextState dispatchEvent
-*/
-bool QShortcutMap::tryShortcutEvent(QObject *o, QKeyEvent *e)
-{
- Q_D(QShortcutMap);
-
- bool wasAccepted = e->isAccepted();
- bool wasSpontaneous = e->spont;
- if (d->currentState == QKeySequence::NoMatch) {
- ushort orgType = e->t;
- e->t = QEvent::ShortcutOverride;
- e->ignore();
- QApplication::sendEvent(o, e);
- e->t = orgType;
- e->spont = wasSpontaneous;
- if (e->isAccepted()) {
- if (!wasAccepted)
- e->ignore();
- return false;
- }
- }
-
- QKeySequence::SequenceMatch result = nextState(e);
- bool stateWasAccepted = e->isAccepted();
- if (wasAccepted)
- e->accept();
- else
- e->ignore();
-
- int identicalMatches = d->identicals.count();
-
- switch(result) {
- case QKeySequence::NoMatch:
- return stateWasAccepted;
- case QKeySequence::ExactMatch:
- resetState();
- dispatchEvent(e);
- default:
- break;
- }
- // If nextState is QKeySequence::ExactMatch && identicals.count == 0
- // we've only found disabled shortcuts
- return identicalMatches > 0 || result == QKeySequence::PartialMatch;
-}
-
-/*! \internal
- Returns the next state of the statemachine
- If return value is SequenceMatch::ExactMatch, then a call to matches()
- will return a QObjects* list of all matching objects for the last matching
- sequence.
-*/
-QKeySequence::SequenceMatch QShortcutMap::nextState(QKeyEvent *e)
-{
- Q_D(QShortcutMap);
- // Modifiers can NOT be shortcuts...
- if (e->key() >= Qt::Key_Shift &&
- e->key() <= Qt::Key_Alt)
- return d->currentState;
-
- QKeySequence::SequenceMatch result = QKeySequence::NoMatch;
-
- // We start fresh each time..
- d->identicals.resize(0);
-
- result = find(e);
- if (result == QKeySequence::NoMatch && e->modifiers() & Qt::ShiftModifier) {
- // If Shift + Key_Backtab, also try Shift + Qt::Key_Tab
- if (e->key() == Qt::Key_Backtab) {
- QKeyEvent pe = QKeyEvent(e->type(), Qt::Key_Tab, e->modifiers(), e->text());
- result = find(&pe);
- }
- }
-
- // Should we eat this key press?
- if (d->currentState == QKeySequence::PartialMatch
- || (d->currentState == QKeySequence::ExactMatch && d->identicals.count()))
- e->accept();
- // Does the new state require us to clean up?
- if (result == QKeySequence::NoMatch)
- clearSequence(d->currentSequences);
- d->currentState = result;
-
-#if defined(DEBUG_QSHORTCUTMAP)
- qDebug().nospace() << "QShortcutMap::nextState(" << e << ") = " << result;
-#endif
- return result;
-}
-
-
-/*! \internal
- Determines if an enabled shortcut has a matcing key sequence.
-*/
-bool QShortcutMap::hasShortcutForKeySequence(const QKeySequence &seq) const
-{
- Q_D(const QShortcutMap);
- QShortcutEntry entry(seq); // needed for searching
- QList<QShortcutEntry>::ConstIterator itEnd = d->sequences.constEnd();
- QList<QShortcutEntry>::ConstIterator it = qLowerBound(d->sequences.constBegin(), itEnd, entry);
-
- for (;it != itEnd; ++it) {
- if (matches(entry.keyseq, (*it).keyseq) == QKeySequence::ExactMatch && correctContext(*it) && (*it).enabled) {
- return true;
- }
- }
-
- //end of the loop: we didn't find anything
- return false;
-}
-
-/*! \internal
- Returns the next state of the statemachine, based
- on the new key event \a e.
- Matches are appended to the vector of identicals,
- which can be access through matches().
- \sa matches
-*/
-QKeySequence::SequenceMatch QShortcutMap::find(QKeyEvent *e)
-{
- Q_D(QShortcutMap);
- if (!d->sequences.count())
- return QKeySequence::NoMatch;
-
- createNewSequences(e, d->newEntries);
-#if defined(DEBUG_QSHORTCUTMAP)
- qDebug() << "Possible shortcut key sequences:" << d->newEntries;
-#endif
-
- // Should never happen
- if (d->newEntries == d->currentSequences) {
- Q_ASSERT_X(e->key() != Qt::Key_unknown || e->text().length(),
- "QShortcutMap::find", "New sequence to find identical to previous");
- return QKeySequence::NoMatch;
- }
-
- // Looking for new identicals, scrap old
- d->identicals.resize(0);
-
- bool partialFound = false;
- bool identicalDisabledFound = false;
- QVector<QKeySequence> okEntries;
- int result = QKeySequence::NoMatch;
- for (int i = d->newEntries.count()-1; i >= 0 ; --i) {
- QShortcutEntry entry(d->newEntries.at(i)); // needed for searching
- QList<QShortcutEntry>::ConstIterator itEnd = d->sequences.constEnd();
- QList<QShortcutEntry>::ConstIterator it =
- qLowerBound(d->sequences.constBegin(), itEnd, entry);
-
- int oneKSResult = QKeySequence::NoMatch;
- int tempRes = QKeySequence::NoMatch;
- do {
- if (it == itEnd)
- break;
- tempRes = matches(entry.keyseq, (*it).keyseq);
- oneKSResult = qMax(oneKSResult, tempRes);
- if (tempRes != QKeySequence::NoMatch && correctContext(*it)) {
- if (tempRes == QKeySequence::ExactMatch) {
- if ((*it).enabled)
- d->identicals.append(&*it);
- else
- identicalDisabledFound = true;
- } else if (tempRes == QKeySequence::PartialMatch) {
- // We don't need partials, if we have identicals
- if (d->identicals.size())
- break;
- // We only care about enabled partials, so we don't consume
- // key events when all partials are disabled!
- partialFound |= (*it).enabled;
- }
- }
- ++it;
- // If we got a valid match on this run, there might still be more keys to check against,
- // so we'll loop once more. If we get NoMatch, there's guaranteed no more possible
- // matches in the shortcutmap.
- } while (tempRes != QKeySequence::NoMatch);
-
- // If the type of match improves (ergo, NoMatch->Partial, or Partial->Exact), clear the
- // previous list. If this match is equal or better than the last match, append to the list
- if (oneKSResult > result) {
- okEntries.clear();
-#if defined(DEBUG_QSHORTCUTMAP)
- qDebug() << "Found better match (" << d->newEntries << "), clearing key sequence list";
-#endif
- }
- if (oneKSResult && oneKSResult >= result) {
- okEntries << d->newEntries.at(i);
-#if defined(DEBUG_QSHORTCUTMAP)
- qDebug() << "Added ok key sequence" << d->newEntries;
-#endif
- }
- }
-
- if (d->identicals.size()) {
- result = QKeySequence::ExactMatch;
- } else if (partialFound) {
- result = QKeySequence::PartialMatch;
- } else if (identicalDisabledFound) {
- result = QKeySequence::ExactMatch;
- } else {
- clearSequence(d->currentSequences);
- result = QKeySequence::NoMatch;
- }
- if (result != QKeySequence::NoMatch)
- d->currentSequences = okEntries;
-#if defined(DEBUG_QSHORTCUTMAP)
- qDebug() << "Returning shortcut match == " << result;
-#endif
- return QKeySequence::SequenceMatch(result);
-}
-
-/*! \internal
- Clears \a seq to an empty QKeySequence.
- Same as doing (the slower)
- \snippet doc/src/snippets/code/src_gui_kernel_qshortcutmap.cpp 0
-*/
-void QShortcutMap::clearSequence(QVector<QKeySequence> &ksl)
-{
- ksl.clear();
- d_func()->newEntries.clear();
-}
-
-/*! \internal
- Alters \a seq to the new sequence state, based on the
- current sequence state, and the new key event \a e.
-*/
-void QShortcutMap::createNewSequences(QKeyEvent *e, QVector<QKeySequence> &ksl)
-{
- Q_D(QShortcutMap);
- QList<int> possibleKeys = QKeyMapper::possibleKeys(e);
- int pkTotal = possibleKeys.count();
- if (!pkTotal)
- return;
-
- int ssActual = d->currentSequences.count();
- int ssTotal = qMax(1, ssActual);
- // Resize to possible permutations of the current sequence(s).
- ksl.resize(pkTotal * ssTotal);
-
- int index = ssActual ? d->currentSequences.at(0).count() : 0;
- for (int pkNum = 0; pkNum < pkTotal; ++pkNum) {
- for (int ssNum = 0; ssNum < ssTotal; ++ssNum) {
- int i = (pkNum * ssTotal) + ssNum;
- QKeySequence &curKsl = ksl[i];
- if (ssActual) {
- const QKeySequence &curSeq = d->currentSequences.at(ssNum);
- curKsl.setKey(curSeq[0], 0);
- curKsl.setKey(curSeq[1], 1);
- curKsl.setKey(curSeq[2], 2);
- curKsl.setKey(curSeq[3], 3);
- } else {
- curKsl.setKey(0, 0);
- curKsl.setKey(0, 1);
- curKsl.setKey(0, 2);
- curKsl.setKey(0, 3);
- }
- // Filtering keycode here with 0xdfffffff to ignore the Keypad modifier
- curKsl.setKey(possibleKeys.at(pkNum) & 0xdfffffff, index);
- }
- }
-}
-
-/*! \internal
- Basically the same function as QKeySequence::matches(const QKeySequence &seq) const
- only that is specially handles Key_hyphen as Key_Minus, as people mix these up all the time and
- they conceptually the same.
-*/
-QKeySequence::SequenceMatch QShortcutMap::matches(const QKeySequence &seq1,
- const QKeySequence &seq2) const
-{
- uint userN = seq1.count(),
- seqN = seq2.count();
-
- if (userN > seqN)
- return QKeySequence::NoMatch;
-
- // If equal in length, we have a potential ExactMatch sequence,
- // else we already know it can only be partial.
- QKeySequence::SequenceMatch match = (userN == seqN
- ? QKeySequence::ExactMatch
- : QKeySequence::PartialMatch);
-
- for (uint i = 0; i < userN; ++i) {
- int userKey = seq1[i],
- sequenceKey = seq2[i];
- if ((userKey & Qt::Key_unknown) == Qt::Key_hyphen)
- userKey = (userKey & Qt::KeyboardModifierMask) | Qt::Key_Minus;
- if ((sequenceKey & Qt::Key_unknown) == Qt::Key_hyphen)
- sequenceKey = (sequenceKey & Qt::KeyboardModifierMask) | Qt::Key_Minus;
- if (userKey != sequenceKey)
- return QKeySequence::NoMatch;
- }
- return match;
-}
-
-/*! \internal
- Returns true if the widget \a w is a logical sub window of the current
- top-level widget.
-*/
-bool QShortcutMap::correctContext(const QShortcutEntry &item) const {
- Q_ASSERT_X(item.owner, "QShortcutMap", "Shortcut has no owner. Illegal map state!");
-
- QWidget *active_window = QApplication::activeWindow();
-
- // popups do not become the active window,
- // so we fake it here to get the correct context
- // for the shortcut system.
- if (QApplication::activePopupWidget())
- active_window = QApplication::activePopupWidget();
-
- if (!active_window)
- return false;
-#ifndef QT_NO_ACTION
- if (QAction *a = qobject_cast<QAction *>(item.owner))
- return correctContext(item.context, a, active_window);
-#endif
-#ifndef QT_NO_GRAPHICSVIEW
- if (QGraphicsWidget *gw = qobject_cast<QGraphicsWidget *>(item.owner))
- return correctGraphicsWidgetContext(item.context, gw, active_window);
-#endif
- QWidget *w = qobject_cast<QWidget *>(item.owner);
- if (!w) {
- QShortcut *s = qobject_cast<QShortcut *>(item.owner);
- w = s->parentWidget();
- }
- return correctWidgetContext(item.context, w, active_window);
-}
-
-bool QShortcutMap::correctWidgetContext(Qt::ShortcutContext context, QWidget *w, QWidget *active_window) const
-{
- bool visible = w->isVisible();
-#ifdef Q_WS_MAC
- if (!qApp->testAttribute(Qt::AA_DontUseNativeMenuBar) && qobject_cast<QMenuBar *>(w))
- visible = true;
-#endif
-
- if (!visible || !w->isEnabled())
- return false;
-
- if (context == Qt::ApplicationShortcut)
- return QApplicationPrivate::tryModalHelper(w, 0); // true, unless w is shadowed by a modal dialog
-
- if (context == Qt::WidgetShortcut)
- return w == QApplication::focusWidget();
-
- if (context == Qt::WidgetWithChildrenShortcut) {
- const QWidget *tw = QApplication::focusWidget();
- while (tw && tw != w && (tw->windowType() == Qt::Widget || tw->windowType() == Qt::Popup))
- tw = tw->parentWidget();
- return tw == w;
- }
-
- // Below is Qt::WindowShortcut context
- QWidget *tlw = w->window();
-#ifndef QT_NO_GRAPHICSVIEW
- if (QWExtra *topData = tlw->d_func()->extra) {
- if (topData->proxyWidget) {
- bool res = correctGraphicsWidgetContext(context, (QGraphicsWidget *)topData->proxyWidget, active_window);
- return res;
- }
- }
-#endif
-
- /* if a floating tool window is active, keep shortcuts on the
- * parent working */
- if (active_window != tlw && active_window && active_window->windowType() == Qt::Tool && active_window->parentWidget()) {
- active_window = active_window->parentWidget()->window();
- }
-
- if (active_window != tlw)
- return false;
-
- /* if we live in a MDI subwindow, ignore the event if we are
- not the active document window */
- const QWidget* sw = w;
- while (sw && !(sw->windowType() == Qt::SubWindow) && !sw->isWindow())
- sw = sw->parentWidget();
- if (sw && (sw->windowType() == Qt::SubWindow)) {
- QWidget *focus_widget = QApplication::focusWidget();
- while (focus_widget && focus_widget != sw)
- focus_widget = focus_widget->parentWidget();
- return sw == focus_widget;
- }
-
-#if defined(DEBUG_QSHORTCUTMAP)
- qDebug().nospace() << "..true [Pass-through]";
-#endif
- return true;
-}
-
-#ifndef QT_NO_GRAPHICSVIEW
-bool QShortcutMap::correctGraphicsWidgetContext(Qt::ShortcutContext context, QGraphicsWidget *w, QWidget *active_window) const
-{
- bool visible = w->isVisible();
-#ifdef Q_WS_MAC
- if (!qApp->testAttribute(Qt::AA_DontUseNativeMenuBar) && qobject_cast<QMenuBar *>(w))
- visible = true;
-#endif
-
- if (!visible || !w->isEnabled() || !w->scene())
- return false;
-
- if (context == Qt::ApplicationShortcut) {
- // Applicationwide shortcuts are always reachable unless their owner
- // is shadowed by modality. In QGV there's no modality concept, but we
- // must still check if all views are shadowed.
- QList<QGraphicsView *> views = w->scene()->views();
- for (int i = 0; i < views.size(); ++i) {
- if (QApplicationPrivate::tryModalHelper(views.at(i), 0))
- return true;
- }
- return false;
- }
-
- if (context == Qt::WidgetShortcut)
- return static_cast<QGraphicsItem *>(w) == w->scene()->focusItem();
-
- if (context == Qt::WidgetWithChildrenShortcut) {
- const QGraphicsItem *ti = w->scene()->focusItem();
- if (ti && ti->isWidget()) {
- const QGraphicsWidget *tw = static_cast<const QGraphicsWidget *>(ti);
- while (tw && tw != w && (tw->windowType() == Qt::Widget || tw->windowType() == Qt::Popup))
- tw = tw->parentWidget();
- return tw == w;
- }
- return false;
- }
-
- // Below is Qt::WindowShortcut context
-
- // Find the active view (if any).
- QList<QGraphicsView *> views = w->scene()->views();
- QGraphicsView *activeView = 0;
- for (int i = 0; i < views.size(); ++i) {
- QGraphicsView *view = views.at(i);
- if (view->window() == active_window) {
- activeView = view;
- break;
- }
- }
- if (!activeView)
- return false;
-
- // The shortcut is reachable if owned by a windowless widget, or if the
- // widget's window is the same as the focus item's window.
- QGraphicsWidget *a = w->scene()->activeWindow();
- return !w->window() || a == w->window();
-}
-#endif
-
-#ifndef QT_NO_ACTION
-bool QShortcutMap::correctContext(Qt::ShortcutContext context, QAction *a, QWidget *active_window) const
-{
- const QList<QWidget *> &widgets = a->d_func()->widgets;
-#if defined(DEBUG_QSHORTCUTMAP)
- if (widgets.isEmpty())
- qDebug() << a << "not connected to any widgets; won't trigger";
-#endif
- for (int i = 0; i < widgets.size(); ++i) {
- QWidget *w = widgets.at(i);
-#ifndef QT_NO_MENU
- if (QMenu *menu = qobject_cast<QMenu *>(w)) {
- QAction *a = menu->menuAction();
- if (correctContext(context, a, active_window))
- return true;
- } else
-#endif
- if (correctWidgetContext(context, w, active_window))
- return true;
- }
-
-#ifndef QT_NO_GRAPHICSVIEW
- const QList<QGraphicsWidget *> &graphicsWidgets = a->d_func()->graphicsWidgets;
-#if defined(DEBUG_QSHORTCUTMAP)
- if (graphicsWidgets.isEmpty())
- qDebug() << a << "not connected to any widgets; won't trigger";
-#endif
- for (int i = 0; i < graphicsWidgets.size(); ++i) {
- QGraphicsWidget *w = graphicsWidgets.at(i);
- if (correctGraphicsWidgetContext(context, w, active_window))
- return true;
- }
-#endif
- return false;
-}
-#endif // QT_NO_ACTION
-
-/*! \internal
- Converts keyboard button states into modifier states
-*/
-int QShortcutMap::translateModifiers(Qt::KeyboardModifiers modifiers)
-{
- int result = 0;
- if (modifiers & Qt::ShiftModifier)
- result |= Qt::SHIFT;
- if (modifiers & Qt::ControlModifier)
- result |= Qt::CTRL;
- if (modifiers & Qt::MetaModifier)
- result |= Qt::META;
- if (modifiers & Qt::AltModifier)
- result |= Qt::ALT;
- return result;
-}
-
-/*! \internal
- Returns the vector of QShortcutEntry's matching the last Identical state.
-*/
-QVector<const QShortcutEntry*> QShortcutMap::matches() const
-{
- Q_D(const QShortcutMap);
- return d->identicals;
-}
-
-/*! \internal
- Dispatches QShortcutEvents to widgets who grabbed the matched key sequence.
-*/
-void QShortcutMap::dispatchEvent(QKeyEvent *e)
-{
- Q_D(QShortcutMap);
- if (!d->identicals.size())
- return;
-
- const QKeySequence &curKey = d->identicals.at(0)->keyseq;
- if (d->prevSequence != curKey) {
- d->ambigCount = 0;
- d->prevSequence = curKey;
- }
- // Find next
- const QShortcutEntry *current = 0, *next = 0;
- int i = 0, enabledShortcuts = 0;
- while(i < d->identicals.size()) {
- current = d->identicals.at(i);
- if (current->enabled || !next){
- ++enabledShortcuts;
- if (enabledShortcuts > d->ambigCount + 1)
- break;
- next = current;
- }
- ++i;
- }
- d->ambigCount = (d->identicals.size() == i ? 0 : d->ambigCount + 1);
- // Don't trigger shortcut if we're autorepeating and the shortcut is
- // grabbed with not accepting autorepeats.
- if (!next || (e->isAutoRepeat() && !next->autorepeat))
- return;
- // Dispatch next enabled
-#if defined(DEBUG_QSHORTCUTMAP)
- qDebug().nospace()
- << "QShortcutMap::dispatchEvent(): Sending QShortcutEvent(\""
- << (QString)next->keyseq << "\", " << next->id << ", "
- << (bool)(enabledShortcuts>1) << ") to object(" << next->owner << ')';
-#endif
- QShortcutEvent se(next->keyseq, next->id, enabledShortcuts>1);
- QApplication::sendEvent(const_cast<QObject *>(next->owner), &se);
-}
-
-/* \internal
- QShortcutMap dump function, only available when DEBUG_QSHORTCUTMAP is
- defined.
-*/
-#if defined(Dump_QShortcutMap)
-void QShortcutMap::dumpMap() const
-{
- Q_D(const QShortcutMap);
- for (int i = 0; i < d->sequences.size(); ++i)
- qDebug().nospace() << &(d->sequences.at(i));
-}
-#endif
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_SHORTCUT
diff --git a/src/gui/kernel/qsizepolicy.h b/src/gui/kernel/qsizepolicy.h
deleted file mode 100644
index bd92a91d58..0000000000
--- a/src/gui/kernel/qsizepolicy.h
+++ /dev/null
@@ -1,244 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSIZEPOLICY_H
-#define QSIZEPOLICY_H
-
-#include <QtCore/qobject.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QVariant;
-
-class Q_GUI_EXPORT QSizePolicy
-{
- Q_GADGET
- Q_ENUMS(Policy)
-
-private:
- enum SizePolicyMasks {
- HSize = 4,
- HMask = 0x0f,
- VMask = HMask << HSize,
- CTShift = 9,
- CTSize = 5,
- CTMask = ((0x1 << CTSize) - 1) << CTShift,
- WFHShift = CTShift + CTSize,
- UnusedShift = WFHShift + 1,
- UnusedSize = 1
- };
-
-public:
- enum PolicyFlag {
- GrowFlag = 1,
- ExpandFlag = 2,
- ShrinkFlag = 4,
- IgnoreFlag = 8
- };
-
- enum Policy {
- Fixed = 0,
- Minimum = GrowFlag,
- Maximum = ShrinkFlag,
- Preferred = GrowFlag | ShrinkFlag,
- MinimumExpanding = GrowFlag | ExpandFlag,
- Expanding = GrowFlag | ShrinkFlag | ExpandFlag,
- Ignored = ShrinkFlag | GrowFlag | IgnoreFlag
- };
-
- enum ControlType {
- DefaultType = 0x00000001,
- ButtonBox = 0x00000002,
- CheckBox = 0x00000004,
- ComboBox = 0x00000008,
- Frame = 0x00000010,
- GroupBox = 0x00000020,
- Label = 0x00000040,
- Line = 0x00000080,
- LineEdit = 0x00000100,
- PushButton = 0x00000200,
- RadioButton = 0x00000400,
- Slider = 0x00000800,
- SpinBox = 0x00001000,
- TabWidget = 0x00002000,
- ToolButton = 0x00004000
- };
- Q_DECLARE_FLAGS(ControlTypes, ControlType)
-
- QSizePolicy() : data(0) { }
-
- // ### Qt 5: merge these two constructors (with type == DefaultType)
- QSizePolicy(Policy horizontal, Policy vertical)
- : data(horizontal | (vertical << HSize)) { }
- QSizePolicy(Policy horizontal, Policy vertical, ControlType type)
- : data(horizontal | (vertical << HSize)) { setControlType(type); }
-
- Policy horizontalPolicy() const { return static_cast<Policy>(data & HMask); }
- Policy verticalPolicy() const { return static_cast<Policy>((data & VMask) >> HSize); }
- ControlType controlType() const;
-
- void setHorizontalPolicy(Policy d) { data = (data & ~HMask) | d; }
- void setVerticalPolicy(Policy d) { data = (data & ~(HMask << HSize)) | (d << HSize); }
- void setControlType(ControlType type);
-
- Qt::Orientations expandingDirections() const {
- Qt::Orientations result;
- if (verticalPolicy() & ExpandFlag)
- result |= Qt::Vertical;
- if (horizontalPolicy() & ExpandFlag)
- result |= Qt::Horizontal;
- return result;
- }
-
- void setHeightForWidth(bool b) { data = b ? (data | (1 << 2*HSize)) : (data & ~(1 << 2*HSize)); }
- bool hasHeightForWidth() const { return data & (1 << 2*HSize); }
- void setWidthForHeight(bool b) { data = b ? (data | (1 << (WFHShift))) : (data & ~(1 << (WFHShift))); }
- bool hasWidthForHeight() const { return data & (1 << (WFHShift)); }
-
- bool operator==(const QSizePolicy& s) const { return data == s.data; }
- bool operator!=(const QSizePolicy& s) const { return data != s.data; }
- operator QVariant() const; // implemented in qabstractlayout.cpp
-
- int horizontalStretch() const { return data >> 24; }
- int verticalStretch() const { return (data >> 16) & 0xff; }
- void setHorizontalStretch(uchar stretchFactor) { data = (data&0x00ffffff) | (uint(stretchFactor)<<24); }
- void setVerticalStretch(uchar stretchFactor) { data = (data&0xff00ffff) | (uint(stretchFactor)<<16); }
-
- void transpose();
-
-#ifdef QT3_SUPPORT
- typedef Policy SizeType;
-#ifndef qdoc
- typedef Qt::Orientations ExpandData;
- enum {
- NoDirection = 0,
- Horizontally = 1,
- Vertically = 2,
- BothDirections = Horizontally | Vertically
- };
-#else
- enum ExpandData {
- NoDirection = 0x0,
- Horizontally = 0x1,
- Vertically = 0x2,
- BothDirections = 0x3
- };
-#endif // qdoc
-
- inline QT3_SUPPORT bool mayShrinkHorizontally() const
- { return horizontalPolicy() & ShrinkFlag; }
- inline QT3_SUPPORT bool mayShrinkVertically() const { return verticalPolicy() & ShrinkFlag; }
- inline QT3_SUPPORT bool mayGrowHorizontally() const { return horizontalPolicy() & GrowFlag; }
- inline QT3_SUPPORT bool mayGrowVertically() const { return verticalPolicy() & GrowFlag; }
- inline QT3_SUPPORT Qt::Orientations expanding() const { return expandingDirections(); }
-
- QT3_SUPPORT_CONSTRUCTOR QSizePolicy(Policy hor, Policy ver, bool hfw)
- : data(hor | (ver<<HSize) | (hfw ? (1U<<2*HSize) : 0)) { }
-
- QT3_SUPPORT_CONSTRUCTOR QSizePolicy(Policy hor, Policy ver, uchar hors, uchar vers, bool hfw = false)
- : data(hor | (ver<<HSize) | (hfw ? (1U<<2*HSize) : 0)) {
- setHorizontalStretch(hors);
- setVerticalStretch(vers);
- }
-
- inline QT3_SUPPORT Policy horData() const { return static_cast<Policy>(data & HMask); }
- inline QT3_SUPPORT Policy verData() const { return static_cast<Policy>((data & VMask) >> HSize); }
- inline QT3_SUPPORT void setHorData(Policy d) { setHorizontalPolicy(d); }
- inline QT3_SUPPORT void setVerData(Policy d) { setVerticalPolicy(d); }
-
- inline QT3_SUPPORT uint horStretch() const { return horizontalStretch(); }
- inline QT3_SUPPORT uint verStretch() const { return verticalStretch(); }
- inline QT3_SUPPORT void setHorStretch(uchar sf) { setHorizontalStretch(sf); }
- inline QT3_SUPPORT void setVerStretch(uchar sf) { setVerticalStretch(sf); }
-#endif
-
-private:
-#ifndef QT_NO_DATASTREAM
- friend Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QSizePolicy &);
- friend Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QSizePolicy &);
-#endif
- QSizePolicy(int i) : data(i) { }
-
- quint32 data;
-/* Qt5: Use bit flags instead, keep it here for improved readability for now.
- We can maybe change it for Qt4, but we'd have to be careful, since the behaviour
- is implementation defined. It usually varies between little- and big-endian compilers, but
- it might also not vary.
- quint32 horzPolicy : 4;
- quint32 vertPolicy : 4;
- quint32 hfw : 1;
- quint32 ctype : 5;
- quint32 wfh : 1;
- quint32 padding : 1; // we cannot use the highest bit
- quint32 verStretch : 8;
- quint32 horStretch : 8;
-*/
-
-};
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QSizePolicy::ControlTypes)
-
-#ifndef QT_NO_DATASTREAM
-// implemented in qlayout.cpp
-Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QSizePolicy &);
-Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QSizePolicy &);
-#endif
-
-inline void QSizePolicy::transpose() {
- Policy hData = horizontalPolicy();
- Policy vData = verticalPolicy();
- uchar hStretch = uchar(horizontalStretch());
- uchar vStretch = uchar(verticalStretch());
- setHorizontalPolicy(vData);
- setVerticalPolicy(hData);
- setHorizontalStretch(vStretch);
- setVerticalStretch(hStretch);
-}
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QSIZEPOLICY_H
diff --git a/src/gui/kernel/qsoftkeymanager_p.h b/src/gui/kernel/qsoftkeymanager_p.h
deleted file mode 100644
index 15c27e8fc7..0000000000
--- a/src/gui/kernel/qsoftkeymanager_p.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSOFTKEYMANAGER_P_H
-#define QSOFTKEYMANAGER_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/qobject.h>
-#include "QtGui/qaction.h"
-
-QT_BEGIN_HEADER
-
-#ifndef QT_NO_SOFTKEYMANAGER
-QT_BEGIN_NAMESPACE
-
-class QSoftKeyManagerPrivate;
-
-class Q_AUTOTEST_EXPORT QSoftKeyManager : public QObject
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QSoftKeyManager)
-
-public:
-
- enum StandardSoftKey {
- OkSoftKey,
- SelectSoftKey,
- DoneSoftKey,
- MenuSoftKey,
- CancelSoftKey
- };
-
- static void updateSoftKeys();
-#ifdef Q_WS_S60
- static bool handleCommand(int);
-#endif
-
- static QAction *createAction(StandardSoftKey standardKey, QWidget *actionWidget);
- static QAction *createKeyedAction(StandardSoftKey standardKey, Qt::Key key, QWidget *actionWidget);
- static QString standardSoftKeyText(StandardSoftKey standardKey);
- static void setForceEnabledInSoftkeys(QAction *action);
- static bool isForceEnabledInSofkeys(QAction *action);
-
-protected:
- bool event(QEvent *e);
-
-private:
- QSoftKeyManager();
- static QSoftKeyManager *instance();
- bool appendSoftkeys(const QWidget &source, int level);
- QWidget *softkeySource(QWidget *previousSource, bool& recursiveMerging);
- bool handleUpdateSoftKeys();
-
-private Q_SLOTS:
- void cleanupHash(QObject* obj);
- void sendKeyEvent();
-
-private:
- Q_DISABLE_COPY(QSoftKeyManager)
-};
-
-QT_END_NAMESPACE
-#endif //QT_NO_SOFTKEYMANAGER
-
-QT_END_HEADER
-
-#endif //QSOFTKEYMANAGER_P_H
diff --git a/src/gui/kernel/qsound.cpp b/src/gui/kernel/qsound.cpp
deleted file mode 100644
index 7958f68c66..0000000000
--- a/src/gui/kernel/qsound.cpp
+++ /dev/null
@@ -1,390 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qsound.h"
-
-#ifndef QT_NO_SOUND
-
-#include "qlist.h"
-#include <private/qobject_p.h>
-#include "qsound_p.h"
-
-QT_BEGIN_NAMESPACE
-
-static QList<QAuServer*> *servers=0;
-
-QAuServer::QAuServer(QObject* parent)
- : QObject(parent)
-{
- if (!servers)
- servers = new QList<QAuServer*>;
- servers->prepend(this);
-}
-
-QAuServer::~QAuServer()
-{
- servers->removeAll(this);
- if (servers->count() == 0) {
- delete servers;
- servers = 0;
- }
-}
-
-void QAuServer::play(const QString& filename)
-{
- QSound s(filename);
- play(&s);
-}
-
-extern QAuServer* qt_new_audio_server();
-
-static QAuServer& server()
-{
- if (!servers) qt_new_audio_server();
- return *servers->first();
-}
-
-class QSoundPrivate : public QObjectPrivate
-{
-public:
- QSoundPrivate(const QString& fname)
- : filename(fname), bucket(0), looprem(0), looptotal(1)
- {
- }
-
- ~QSoundPrivate()
- {
- delete bucket;
- }
-
- QString filename;
- QAuBucket* bucket;
- int looprem;
- int looptotal;
-};
-
-/*!
- \class QSound
- \brief The QSound class provides access to the platform audio facilities.
-
- \ingroup multimedia
-
-
- Qt provides the most commonly required audio operation in GUI
- applications: asynchronously playing a sound file. This is most
- easily accomplished using the static play() function:
-
- \snippet doc/src/snippets/code/src_gui_kernel_qsound.cpp 0
-
- Alternatively, create a QSound object from the sound file first
- and then call the play() slot:
-
- \snippet doc/src/snippets/code/src_gui_kernel_qsound.cpp 1
-
- Once created a QSound object can be queried for its fileName() and
- total number of loops() (i.e. the number of times the sound will
- play). The number of repetitions can be altered using the
- setLoops() function. While playing the sound, the loopsRemaining()
- function returns the remaining number of repetitions. Use the
- isFinished() function to determine whether the sound has finished
- playing.
-
- Sounds played using a QSound object may use more memory than the
- static play() function, but it may also play more immediately
- (depending on the underlying platform audio facilities). Use the
- static isAvailable() function to determine whether sound
- facilities exist on the platform. Which facilities that are
- actually used varies:
-
- \table
- \header \o Platform \o Audio Facility
- \row
- \o Microsoft Windows
- \o The underlying multimedia system is used; only WAVE format sound files
- are supported.
- \row
- \o X11
- \o The \l{ftp://ftp.x.org/contrib/audio/nas/}{Network Audio System}
- is used if available, otherwise all operations work silently. NAS
- supports WAVE and AU files.
- \row
- \o Mac OS X
- \o NSSound is used. All formats that NSSound supports, including QuickTime formats,
- are supported by Qt for Mac OS X.
- \row
- \o Qt for Embedded Linux
- \o A built-in mixing sound server is used, accessing \c /dev/dsp
- directly. Only the WAVE format is supported.
- \row
- \o Symbian
- \o CMdaAudioPlayerUtility is used. All formats that Symbian OS or devices support
- are supported also by Qt.
- \endtable
-
- Note that QSound does not support \l{resources.html}{resources}.
- This might be fixed in a future Qt version.
-*/
-
-/*!
- Plays the sound stored in the file specified by the given \a filename.
-
- \sa stop(), loopsRemaining(), isFinished()
-*/
-void QSound::play(const QString& filename)
-{
- server().play(filename);
-}
-
-/*!
- Constructs a QSound object from the file specified by the given \a
- filename and with the given \a parent.
-
- This may use more memory than the static play() function, but it
- may also play more immediately (depending on the underlying
- platform audio facilities).
-
- \sa play()
-*/
-QSound::QSound(const QString& filename, QObject* parent)
- : QObject(*new QSoundPrivate(filename), parent)
-{
- server().init(this);
-}
-
-#ifdef QT3_SUPPORT
-/*!
- \obsolete
-
- Constructs a QSound object from the file specified by the given \a
- filename and with the given \a parent and \a name. Use the
- QSound() construcor and QObject::setObjectName() instead.
-
- \oldcode
- QSound *mySound = new QSound(filename, parent, name);
- \newcode
- QSounc *mySound = new QSound(filename, parent);
- mySound->setObjectName(name);
- \endcode
-*/
-QSound::QSound(const QString& filename, QObject* parent, const char* name)
- : QObject(*new QSoundPrivate(filename), parent)
-{
- setObjectName(QString::fromAscii(name));
- server().init(this);
-}
-#endif
-
-/*!
- Destroys this sound object. If the sound is not finished playing,
- the stop() function is called before the sound object is
- destructed.
-
- \sa stop(), isFinished()
-*/
-QSound::~QSound()
-{
- if (!isFinished())
- stop();
-}
-
-/*!
- Returns true if the sound has finished playing; otherwise returns false.
-
- \warning On Windows this function always returns true for unlooped sounds.
-*/
-bool QSound::isFinished() const
-{
- Q_D(const QSound);
- return d->looprem == 0;
-}
-
-/*!
- \overload
-
- Starts playing the sound specified by this QSound object.
-
- The function returns immediately. Depending on the platform audio
- facilities, other sounds may stop or be mixed with the new
- sound. The sound can be played again at any time, possibly mixing
- or replacing previous plays of the sound.
-
- \sa fileName()
-*/
-void QSound::play()
-{
- Q_D(QSound);
- d->looprem = d->looptotal;
- server().play(this);
-}
-
-/*!
- Returns the number of times the sound will play.
-
- \sa loopsRemaining(), setLoops()
-*/
-int QSound::loops() const
-{
- Q_D(const QSound);
- return d->looptotal;
-}
-
-/*!
- Returns the remaining number of times the sound will loop (this
- value decreases each time the sound is played).
-
- \sa loops(), isFinished()
-*/
-int QSound::loopsRemaining() const
-{
- Q_D(const QSound);
- return d->looprem;
-}
-
-/*!
- \fn void QSound::setLoops(int number)
-
- Sets the sound to repeat the given \a number of times when it is
- played.
-
- Note that passing the value -1 will cause the sound to loop
- indefinitely.
-
- \sa loops()
-*/
-void QSound::setLoops(int n)
-{
- Q_D(QSound);
- d->looptotal = n;
-}
-
-/*!
- Returns the filename associated with this QSound object.
-
- \sa QSound()
-*/
-QString QSound::fileName() const
-{
- Q_D(const QSound);
- return d->filename;
-}
-
-/*!
- Stops the sound playing.
-
- Note that on Windows the current loop will finish if a sound is
- played in a loop.
-
- \sa play()
-*/
-void QSound::stop()
-{
- Q_D(QSound);
- server().stop(this);
- d->looprem = 0;
-}
-
-
-/*!
- Returns true if sound facilities exist on the platform; otherwise
- returns false.
-
- If no sound is available, all QSound operations work silently and
- quickly. An application may choose either to notify the user if
- sound is crucial to the application or to operate silently without
- bothering the user.
-
- Note: On Windows this always returns true because some sound card
- drivers do not implement a way to find out whether it is available
- or not.
-*/
-bool QSound::isAvailable()
-{
- return server().okay();
-}
-
-/*!
- Sets the internal bucket record of sound \a s to \a b, deleting
- any previous setting.
-*/
-void QAuServer::setBucket(QSound* s, QAuBucket* b)
-{
- delete s->d_func()->bucket;
- s->d_func()->bucket = b;
-}
-
-/*!
- Returns the internal bucket record of sound \a s.
-*/
-QAuBucket* QAuServer::bucket(QSound* s)
-{
- return s->d_func()->bucket;
-}
-
-/*!
- Decrements the QSound::loopRemaining() value for sound \a s,
- returning the result.
-*/
-int QAuServer::decLoop(QSound* s)
-{
- if (s->d_func()->looprem > 0)
- --s->d_func()->looprem;
- return s->d_func()->looprem;
-}
-
-/*!
- Initializes the sound. The default implementation does nothing.
-*/
-void QAuServer::init(QSound*)
-{
-}
-
-QAuBucket::~QAuBucket()
-{
-}
-/*!
- \fn bool QSound::available()
-
- Use the isAvailable() function instead.
-*/
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_SOUND
diff --git a/src/gui/kernel/qsound.h b/src/gui/kernel/qsound.h
deleted file mode 100644
index 368387c2ae..0000000000
--- a/src/gui/kernel/qsound.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSOUND_H
-#define QSOUND_H
-
-#include <QtCore/qobject.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_SOUND
-
-class QSoundPrivate;
-
-class Q_GUI_EXPORT QSound : public QObject
-{
- Q_OBJECT
-
-public:
- static bool isAvailable();
- static void play(const QString& filename);
-
- explicit QSound(const QString& filename, QObject* parent = 0);
- ~QSound();
-
- int loops() const;
- int loopsRemaining() const;
- void setLoops(int);
- QString fileName() const;
-
- bool isFinished() const;
-
-public Q_SLOTS:
- void play();
- void stop();
-
-public:
-#ifdef QT3_SUPPORT
- QT3_SUPPORT_CONSTRUCTOR QSound(const QString& filename, QObject* parent, const char* name);
- static inline QT3_SUPPORT bool available() { return isAvailable(); }
-#endif
-private:
- Q_DECLARE_PRIVATE(QSound)
- friend class QAuServer;
-};
-
-#endif // QT_NO_SOUND
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QSOUND_H
diff --git a/src/gui/kernel/qsound_qws.cpp b/src/gui/kernel/qsound_qws.cpp
deleted file mode 100644
index 08382389f5..0000000000
--- a/src/gui/kernel/qsound_qws.cpp
+++ /dev/null
@@ -1,350 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qapplication.h"
-
-#ifndef QT_NO_SOUND
-
-#include "qsound.h"
-#include "qpaintdevice.h"
-#include "qwsdisplay_qws.h"
-#include "qsound_p.h"
-
-#include "qsoundqss_qws.h"
-
-#include "qhash.h"
-#include "qfileinfo.h"
-
-#include "qbytearray.h"
-#include "quuid.h"
-#include "qdatastream.h"
-#include "qcopchannel_qws.h"
-#include "qbuffer.h"
-
-
-QT_BEGIN_NAMESPACE
-
-#ifdef MEDIA_SERVER
-
-#define SERVER_CHANNEL "QPE/MediaServer"
-
-class QCopMessage : public QDataStream
-{
-public:
- QCopMessage( const QString& channel, const QString& message )
- : QDataStream( new QBuffer ), m_channel( channel ), m_message( message )
- {
- device()->open( QIODevice::WriteOnly );
- }
-
- ~QCopMessage()
- {
- QCopChannel::send( m_channel, m_message, ((QBuffer*)device())->buffer() );
- delete device();
- }
-
-private:
- QString m_channel;
- QString m_message;
-};
-
-#endif // MEDIA_SERVER
-
-class QAuServerQWS;
-
-class QAuBucketQWS : public QObject, public QAuBucket
-{
- Q_OBJECT
-public:
- QAuBucketQWS( QAuServerQWS*, QSound*, QObject* parent = 0 );
-
- ~QAuBucketQWS();
-
-#ifndef MEDIA_SERVER
- int id() const { return id_; }
-#endif
-
- QSound* sound() const { return sound_; }
-
-#ifdef MEDIA_SERVER
- void play();
-
- void stop();
-#endif
-
-signals:
- // Only for Media Server
- void done( QAuBucketQWS* );
-
-private slots:
- // Only for Media Server
- void processMessage( const QString& msg, const QByteArray& data );
-
-private:
-#ifdef MEDIA_SERVER
- QCopChannel *m_channel;
- QUuid m_id;
-#endif
-
-#ifndef MEDIA_SERVER
- int id_;
-#endif
- QSound *sound_;
- QAuServerQWS *server_;
-
- static int next;
-};
-
-int QAuBucketQWS::next = 0;
-
-class QAuServerQWS : public QAuServer
-{
- Q_OBJECT
-public:
- QAuServerQWS( QObject* parent );
-
- void init( QSound* s )
- {
- QAuBucketQWS *bucket = new QAuBucketQWS( this, s );
-#ifdef MEDIA_SERVER
- connect( bucket, SIGNAL(done(QAuBucketQWS*)),
- this, SLOT(complete(QAuBucketQWS*)) );
-#endif
- setBucket( s, bucket );
- }
-
-#ifndef MEDIA_SERVER
- // Register bucket
- void insert( QAuBucketQWS *bucket )
- {
- buckets.insert( bucket->id(), bucket );
- }
-
- // Remove bucket from register
- void remove( QAuBucketQWS *bucket )
- {
- buckets.remove( bucket->id() );
- }
-#endif
-
- void play( QSound* s )
- {
- QString filepath = QFileInfo( s->fileName() ).absoluteFilePath();
-#if defined(QT_NO_QWS_SOUNDSERVER)
- server->playFile( bucket( s )->id(), filepath );
-#elif defined(MEDIA_SERVER)
- bucket( s )->play();
-#else
- client->play( bucket( s )->id(), filepath );
-#endif
- }
-
- void stop( QSound* s )
- {
-#if defined(QT_NO_QWS_SOUNDSERVER)
- server->stopFile( bucket( s )->id() );
-#elif defined(MEDIA_SERVER)
- bucket( s )->stop();
-#else
- client->stop( bucket( s )->id() );
-#endif
- }
-
- bool okay() { return true; }
-
-private slots:
- // Continue playing sound if loops remain
- void complete( int id )
- {
-#ifndef MEDIA_SERVER
- QAuBucketQWS *bucket = find( id );
- if( bucket ) {
- QSound *sound = bucket->sound();
- if( decLoop( sound ) ) {
- play( sound );
- }
- }
-#else
- Q_UNUSED(id);
-#endif
- }
-
- // Only for Media Server
- void complete( QAuBucketQWS* bucket )
- {
-#ifndef MEDIA_SERVER
- Q_UNUSED(bucket);
-#else
- QSound *sound = bucket->sound();
- if( decLoop( sound ) ) {
- play( sound );
- }
-#endif
- }
-
-protected:
- QAuBucketQWS* bucket( QSound *s )
- {
- return (QAuBucketQWS*)QAuServer::bucket( s );
- }
-
-private:
-#ifndef MEDIA_SERVER
- // Find registered bucket with given id, return null if none found
- QAuBucketQWS* find( int id )
- {
- QHash<int, QAuBucketQWS*>::Iterator it = buckets.find( id );
- if( it != buckets.end() ) {
- return it.value();
- }
-
- return 0;
- }
-
- QHash<int, QAuBucketQWS*> buckets; // ### possible problem with overlapping keys
-
-#ifdef QT_NO_QWS_SOUNDSERVER
- QWSSoundServer *server;
-#else
- QWSSoundClient *client;
-#endif
-
-#endif // MEDIA_SERVER
-};
-
-QAuServerQWS::QAuServerQWS(QObject* parent) :
- QAuServer(parent)
-{
-#ifndef MEDIA_SERVER
- setObjectName(QLatin1String("qauserverqws"));
-
-#ifdef QT_NO_QWS_SOUNDSERVER
- server = new QWSSoundServer( this ); // ### only suitable for single application
-
- connect( server, SIGNAL(soundCompleted(int)),
- this, SLOT(complete(int)) );
-#else
- client = new QWSSoundClient( this ); // ### requires successful connection
-
- connect( client, SIGNAL(soundCompleted(int)),
- this, SLOT(complete(int)) );
-#endif
-
-#endif // MEDIA_SERVER
-}
-
-QAuBucketQWS::QAuBucketQWS( QAuServerQWS *server, QSound *sound, QObject* parent )
- : QObject( parent ), sound_( sound ), server_( server )
-{
-#ifdef MEDIA_SERVER
- m_id = QUuid::createUuid();
-
- sound->setObjectName( m_id.toString() );
-
- m_channel = new QCopChannel(QLatin1String("QPE/QSound/") + m_id, this );
- connect( m_channel, SIGNAL(received(QString,QByteArray)),
- this, SLOT(processMessage(QString,QByteArray)) );
-
- {
- QCopMessage message( QLatin1String(SERVER_CHANNEL), QLatin1String("subscribe(QUuid)") );
- message << m_id;
- }
-
- {
- QString filepath = QFileInfo( sound_->fileName() ).absoluteFilePath();
- QCopMessage message( QLatin1String(SERVER_CHANNEL), QLatin1String("open(QUuid,QString)") );
- message << m_id << filepath;
- }
-#else
- id_ = next++;
- server_->insert( this );
-#endif
-}
-
-#ifdef MEDIA_SERVER
-void QAuBucketQWS::play()
-{
- QString filepath = QFileInfo( sound_->fileName() ).absoluteFilePath();
-
- QCopMessage message( QLatin1String(SERVER_CHANNEL), QLatin1String("play(QUuid)") );
- message << m_id;
-}
-
-void QAuBucketQWS::stop()
-{
- QCopMessage message( QLatin1String(SERVER_CHANNEL), QLatin1String("stop(QUuid)") );
- message << m_id;
-}
-#endif // MEDIA_SERVER
-
-void QAuBucketQWS::processMessage( const QString& msg, const QByteArray& data )
-{
- Q_UNUSED(data);
-#ifndef MEDIA_SERVER
- Q_UNUSED(msg);
-#else
- if( msg == QLatin1String("done()") ) {
- emit done( this );
- }
-#endif
-}
-
-QAuBucketQWS::~QAuBucketQWS()
-{
-#ifdef MEDIA_SERVER
- QCopMessage message( QLatin1String(SERVER_CHANNEL), QLatin1String("revoke(QUuid)") );
- message << m_id;
-#else
- server_->remove( this );
-#endif
-}
-
-
-QAuServer* qt_new_audio_server()
-{
- return new QAuServerQWS(qApp);
-}
-
-#include "qsound_qws.moc"
-
-#endif // QT_NO_SOUND
-
-QT_END_NAMESPACE
diff --git a/src/gui/kernel/qstackedlayout.h b/src/gui/kernel/qstackedlayout.h
deleted file mode 100644
index 89bf26456d..0000000000
--- a/src/gui/kernel/qstackedlayout.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSTACKEDLAYOUT_H
-#define QSTACKEDLAYOUT_H
-
-#include <QtGui/qlayout.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QStackedLayoutPrivate;
-
-class Q_GUI_EXPORT QStackedLayout : public QLayout
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QStackedLayout)
- Q_ENUMS(StackingMode)
- Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentChanged)
- Q_PROPERTY(StackingMode stackingMode READ stackingMode WRITE setStackingMode)
- QDOC_PROPERTY(int count READ count)
-
-public:
- enum StackingMode {
- StackOne,
- StackAll
- };
-
- QStackedLayout();
- explicit QStackedLayout(QWidget *parent);
- explicit QStackedLayout(QLayout *parentLayout);
- ~QStackedLayout();
-
- int addWidget(QWidget *w);
- int insertWidget(int index, QWidget *w);
-
- QWidget *currentWidget() const;
- int currentIndex() const;
-#ifdef Q_NO_USING_KEYWORD
- inline QWidget *widget() { return QLayout::widget(); }
-#else
- using QLayout::widget;
-#endif
- QWidget *widget(int) const;
- int count() const;
-
- StackingMode stackingMode() const;
- void setStackingMode(StackingMode stackingMode);
-
- // abstract virtual functions:
- void addItem(QLayoutItem *item);
- QSize sizeHint() const;
- QSize minimumSize() const;
- QLayoutItem *itemAt(int) const;
- QLayoutItem *takeAt(int);
- void setGeometry(const QRect &rect);
-
-Q_SIGNALS:
- void widgetRemoved(int index);
- void currentChanged(int index);
-
-public Q_SLOTS:
- void setCurrentIndex(int index);
- void setCurrentWidget(QWidget *w);
-
-private:
- Q_DISABLE_COPY(QStackedLayout)
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QSTACKEDLAYOUT_H
diff --git a/src/gui/kernel/qstylehints.cpp b/src/gui/kernel/qstylehints.cpp
new file mode 100644
index 0000000000..8c87c390a3
--- /dev/null
+++ b/src/gui/kernel/qstylehints.cpp
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qstylehints.h>
+#include <qplatformintegration_qpa.h>
+#include <private/qguiapplication_p.h>
+
+static inline QVariant hint(QPlatformIntegration::StyleHint h)
+{
+ return QGuiApplicationPrivate::platformIntegration()->styleHint(h);
+}
+
+QStyleHints::QStyleHints()
+ : QObject()
+{
+}
+
+
+int QStyleHints::mouseDoubleClickInterval() const
+{
+ return hint(QPlatformIntegration::MouseDoubleClickInterval).toInt();
+}
+
+int QStyleHints::startDragDistance() const
+{
+ return hint(QPlatformIntegration::StartDragDistance).toInt();
+}
+
+int QStyleHints::startDragTime() const
+{
+ return hint(QPlatformIntegration::StartDragTime).toInt();
+}
+
+int QStyleHints::keyboardInputInterval() const
+{
+ return hint(QPlatformIntegration::KeyboardInputInterval).toInt();
+}
+
+int QStyleHints::cursorFlashTime() const
+{
+ return hint(QPlatformIntegration::CursorFlashTime).toInt();
+}
diff --git a/src/gui/kernel/qstylehints.h b/src/gui/kernel/qstylehints.h
new file mode 100644
index 0000000000..3cb549daad
--- /dev/null
+++ b/src/gui/kernel/qstylehints.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSTYLEHINTS_H
+#define QSTYLEHINTS_H
+
+#include <QtCore/qobject.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QPlatformIntegration;
+
+class Q_GUI_EXPORT QStyleHints : public QObject
+{
+ Q_OBJECT
+public:
+ int mouseDoubleClickInterval() const;
+ int startDragDistance() const;
+ int startDragTime() const;
+ int keyboardInputInterval() const;
+ int cursorFlashTime() const;
+private:
+ friend class QGuiApplication;
+ QStyleHints();
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/gui/kernel/qsurface.cpp b/src/gui/kernel/qsurface.cpp
new file mode 100644
index 0000000000..e192674f02
--- /dev/null
+++ b/src/gui/kernel/qsurface.cpp
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qsurface.h"
+
+QT_BEGIN_NAMESPACE
+
+QSurface::QSurface(SurfaceType type)
+ : m_type(type)
+{
+}
+
+QSurface::SurfaceType QSurface::surfaceType() const
+{
+ return m_type;
+}
+
+QT_BEGIN_NAMESPACE
+
diff --git a/src/gui/kernel/qsurface.h b/src/gui/kernel/qsurface.h
new file mode 100644
index 0000000000..a6c8745a7a
--- /dev/null
+++ b/src/gui/kernel/qsurface.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSURFACE_H
+#define QSURFACE_H
+
+#include <QtCore/qnamespace.h>
+#include <QtGui/qsurfaceformat.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QPlatformSurface;
+
+class Q_GUI_EXPORT QSurface
+{
+public:
+ enum SurfaceType {
+ Window
+ };
+
+ virtual ~QSurface();
+
+ SurfaceType surfaceType() const;
+
+ virtual QSurfaceFormat format() const = 0;
+ virtual QPlatformSurface *surfaceHandle() const = 0;
+
+private:
+ QSurface(SurfaceType type);
+
+ SurfaceType m_type;
+
+ friend class QWindow;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif //QSURFACE_H
diff --git a/src/gui/kernel/qsurfaceformat.cpp b/src/gui/kernel/qsurfaceformat.cpp
new file mode 100644
index 0000000000..c53c510d8c
--- /dev/null
+++ b/src/gui/kernel/qsurfaceformat.cpp
@@ -0,0 +1,466 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qsurfaceformat.h"
+
+#include <QtCore/qatomic.h>
+#include <QtCore/QDebug>
+
+#ifdef major
+#undef major
+#endif
+
+#ifdef minor
+#undef minor
+#endif
+
+class QSurfaceFormatPrivate
+{
+public:
+ explicit QSurfaceFormatPrivate(QSurfaceFormat::FormatOptions _opts = 0)
+ : ref(1)
+ , opts(_opts)
+ , redBufferSize(-1)
+ , greenBufferSize(-1)
+ , blueBufferSize(-1)
+ , alphaBufferSize(-1)
+ , depthSize(-1)
+ , stencilSize(-1)
+ , swapBehavior(QSurfaceFormat::DefaultSwapBehavior)
+ , numSamples(-1)
+ , profile(QSurfaceFormat::NoProfile)
+ , major(1)
+ , minor(1)
+ {
+ }
+
+ QSurfaceFormatPrivate(const QSurfaceFormatPrivate *other)
+ : ref(1),
+ opts(other->opts),
+ redBufferSize(other->redBufferSize),
+ greenBufferSize(other->greenBufferSize),
+ blueBufferSize(other->blueBufferSize),
+ alphaBufferSize(other->alphaBufferSize),
+ depthSize(other->depthSize),
+ stencilSize(other->stencilSize),
+ swapBehavior(other->swapBehavior),
+ numSamples(other->numSamples),
+ profile(other->profile),
+ major(other->major),
+ minor(other->minor)
+ {
+ }
+
+ QAtomicInt ref;
+ QSurfaceFormat::FormatOptions opts;
+ int redBufferSize;
+ int greenBufferSize;
+ int blueBufferSize;
+ int alphaBufferSize;
+ int depthSize;
+ int stencilSize;
+ QSurfaceFormat::SwapBehavior swapBehavior;
+ int numSamples;
+ QSurfaceFormat::OpenGLContextProfile profile;
+ int major;
+ int minor;
+};
+
+QSurfaceFormat::QSurfaceFormat() : d(new QSurfaceFormatPrivate)
+{
+}
+
+QSurfaceFormat::QSurfaceFormat(QSurfaceFormat::FormatOptions options) :
+ d(new QSurfaceFormatPrivate(options))
+{
+}
+
+/*!
+ \internal
+*/
+void QSurfaceFormat::detach()
+{
+ if (d->ref != 1) {
+ QSurfaceFormatPrivate *newd = new QSurfaceFormatPrivate(d);
+ if (!d->ref.deref())
+ delete d;
+ d = newd;
+ }
+}
+
+/*!
+ Constructs a copy of \a other.
+*/
+
+QSurfaceFormat::QSurfaceFormat(const QSurfaceFormat &other)
+{
+ d = other.d;
+ d->ref.ref();
+}
+
+/*!
+ Assigns \a other to this object.
+*/
+
+QSurfaceFormat &QSurfaceFormat::operator=(const QSurfaceFormat &other)
+{
+ if (d != other.d) {
+ other.d->ref.ref();
+ if (!d->ref.deref())
+ delete d;
+ d = other.d;
+ }
+ return *this;
+}
+
+/*!
+ Destroys the QSurfaceFormat.
+*/
+QSurfaceFormat::~QSurfaceFormat()
+{
+ if (!d->ref.deref())
+ delete d;
+}
+
+/*!
+ \fn bool QSurfaceFormat::stereo() const
+
+ Returns true if stereo buffering is enabled; otherwise returns
+ false. Stereo buffering is disabled by default.
+
+ \sa setStereo()
+*/
+
+/*!
+ If \a enable is true enables stereo buffering; otherwise disables
+ stereo buffering.
+
+ Stereo buffering is disabled by default.
+
+ Stereo buffering provides extra color buffers to generate left-eye
+ and right-eye images.
+
+ \sa stereo()
+*/
+
+void QSurfaceFormat::setStereo(bool enable)
+{
+ QSurfaceFormat::FormatOptions newOptions = d->opts;
+ if (enable) {
+ newOptions |= QSurfaceFormat::StereoBuffers;
+ } else {
+ newOptions &= ~QSurfaceFormat::StereoBuffers;
+ }
+ if (int(newOptions) != int(d->opts)) {
+ detach();
+ d->opts = newOptions;
+ }
+}
+
+/*!
+ Returns the number of samples per pixel when multisampling is
+ enabled. By default, the highest number of samples that is
+ available is used.
+
+ \sa setSampleBuffers(), sampleBuffers(), setSamples()
+*/
+int QSurfaceFormat::samples() const
+{
+ return d->numSamples;
+}
+
+/*!
+ Set the preferred number of samples per pixel when multisampling
+ is enabled to \a numSamples. By default, the highest number of
+ samples available is used.
+
+ \sa setSampleBuffers(), sampleBuffers(), samples()
+*/
+void QSurfaceFormat::setSamples(int numSamples)
+{
+ if (d->numSamples != numSamples) {
+ detach();
+ d->numSamples = numSamples;
+ }
+}
+
+/*!
+ Sets the format option to \a opt.
+
+ \sa testOption()
+*/
+
+void QSurfaceFormat::setOption(QSurfaceFormat::FormatOptions opt)
+{
+ const QSurfaceFormat::FormatOptions newOptions = d->opts | opt;
+ if (int(newOptions) != int(d->opts)) {
+ detach();
+ d->opts = newOptions;
+ }
+}
+
+/*!
+ Returns true if format option \a opt is set; otherwise returns false.
+
+ \sa setOption()
+*/
+
+bool QSurfaceFormat::testOption(QSurfaceFormat::FormatOptions opt) const
+{
+ return d->opts & opt;
+}
+
+/*!
+ Set the minimum depth buffer size to \a size.
+
+ \sa depthBufferSize(), setDepth(), depth()
+*/
+void QSurfaceFormat::setDepthBufferSize(int size)
+{
+ if (d->depthSize != size) {
+ detach();
+ d->depthSize = size;
+ }
+}
+
+/*!
+ Returns the depth buffer size.
+
+ \sa depth(), setDepth(), setDepthBufferSize()
+*/
+int QSurfaceFormat::depthBufferSize() const
+{
+ return d->depthSize;
+}
+
+void QSurfaceFormat::setSwapBehavior(SwapBehavior behavior)
+{
+ if (d->swapBehavior != behavior) {
+ detach();
+ d->swapBehavior = behavior;
+ }
+}
+
+
+QSurfaceFormat::SwapBehavior QSurfaceFormat::swapBehavior() const
+{
+ return d->swapBehavior;
+}
+
+bool QSurfaceFormat::hasAlpha() const
+{
+ return d->alphaBufferSize > 0;
+}
+
+/*!
+ Set the preferred stencil buffer size to \a size.
+
+ \sa stencilBufferSize(), setStencil(), stencil()
+*/
+void QSurfaceFormat::setStencilBufferSize(int size)
+{
+ if (d->stencilSize != size) {
+ detach();
+ d->stencilSize = size;
+ }
+}
+
+/*!
+ Returns the stencil buffer size.
+
+ \sa stencil(), setStencil(), setStencilBufferSize()
+*/
+int QSurfaceFormat::stencilBufferSize() const
+{
+ return d->stencilSize;
+}
+
+int QSurfaceFormat::redBufferSize() const
+{
+ return d->redBufferSize;
+}
+
+int QSurfaceFormat::greenBufferSize() const
+{
+ return d->greenBufferSize;
+}
+
+int QSurfaceFormat::blueBufferSize() const
+{
+ return d->blueBufferSize;
+}
+
+int QSurfaceFormat::alphaBufferSize() const
+{
+ return d->alphaBufferSize;
+}
+
+void QSurfaceFormat::setRedBufferSize(int size)
+{
+ if (d->redBufferSize != size) {
+ detach();
+ d->redBufferSize = size;
+ }
+}
+
+void QSurfaceFormat::setGreenBufferSize(int size)
+{
+ if (d->greenBufferSize != size) {
+ detach();
+ d->greenBufferSize = size;
+ }
+}
+
+void QSurfaceFormat::setBlueBufferSize(int size)
+{
+ if (d->blueBufferSize != size) {
+ detach();
+ d->blueBufferSize = size;
+ }
+}
+
+void QSurfaceFormat::setAlphaBufferSize(int size)
+{
+ if (d->alphaBufferSize != size) {
+ detach();
+ d->alphaBufferSize = size;
+ }
+}
+
+/*!
+ Sets the desired OpenGL context profile.
+
+ This setting is ignored if the requested OpenGL version is
+ less than 3.2.
+*/
+void QSurfaceFormat::setProfile(OpenGLContextProfile profile)
+{
+ if (d->profile != profile) {
+ detach();
+ d->profile = profile;
+ }
+}
+
+QSurfaceFormat::OpenGLContextProfile QSurfaceFormat::profile() const
+{
+ return d->profile;
+}
+
+/*!
+ Sets the desired major OpenGL version.
+*/
+void QSurfaceFormat::setMajorVersion(int major)
+{
+ d->major = major;
+}
+
+/*!
+ Returns the major OpenGL version.
+*/
+int QSurfaceFormat::majorVersion() const
+{
+ return d->major;
+}
+
+/*!
+ Sets the desired minor OpenGL version.
+*/
+void QSurfaceFormat::setMinorVersion(int minor)
+{
+ d->minor = minor;
+}
+
+/*!
+ Returns the minor OpenGL version.
+*/
+int QSurfaceFormat::minorVersion() const
+{
+ return d->minor;
+}
+
+bool operator==(const QSurfaceFormat& a, const QSurfaceFormat& b)
+{
+ return (a.d == b.d) || ((int) a.d->opts == (int) b.d->opts
+ && a.d->stencilSize == b.d->stencilSize
+ && a.d->redBufferSize == b.d->redBufferSize
+ && a.d->greenBufferSize == b.d->greenBufferSize
+ && a.d->blueBufferSize == b.d->blueBufferSize
+ && a.d->alphaBufferSize == b.d->alphaBufferSize
+ && a.d->depthSize == b.d->depthSize
+ && a.d->numSamples == b.d->numSamples
+ && a.d->swapBehavior == b.d->swapBehavior
+ && a.d->profile == b.d->profile);
+}
+
+
+/*!
+ Returns false if all the options of the two QSurfaceFormat objects
+ \a a and \a b are equal; otherwise returns true.
+
+ \relates QSurfaceFormat
+*/
+
+bool operator!=(const QSurfaceFormat& a, const QSurfaceFormat& b)
+{
+ return !(a == b);
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug dbg, const QSurfaceFormat &f)
+{
+ const QSurfaceFormatPrivate * const d = f.d;
+
+ dbg.nospace() << "QSurfaceFormat("
+ << "options " << d->opts
+ << ", depthBufferSize " << d->depthSize
+ << ", redBufferSize " << d->redBufferSize
+ << ", greenBufferSize " << d->greenBufferSize
+ << ", blueBufferSize " << d->blueBufferSize
+ << ", alphaBufferSize " << d->alphaBufferSize
+ << ", stencilBufferSize " << d->stencilSize
+ << ", samples " << d->numSamples
+ << ", swapBehavior " << d->swapBehavior
+ << ", profile " << d->profile
+ << ')';
+
+ return dbg.space();
+}
+#endif
diff --git a/src/gui/kernel/qsurfaceformat.h b/src/gui/kernel/qsurfaceformat.h
new file mode 100644
index 0000000000..f305edbcc9
--- /dev/null
+++ b/src/gui/kernel/qsurfaceformat.h
@@ -0,0 +1,152 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QSURFACEFORMAT_H
+#define QSURFACEFORMAT_H
+
+#include <qglobal.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QOpenGLContext;
+class QSurfaceFormatPrivate;
+
+class Q_GUI_EXPORT QSurfaceFormat
+{
+public:
+ enum FormatOption {
+ StereoBuffers = 0x0001,
+ DebugContext = 0x0002,
+ DeprecatedFunctions = 0x0004
+ };
+ Q_DECLARE_FLAGS(FormatOptions, FormatOption)
+
+ enum SwapBehavior {
+ DefaultSwapBehavior,
+ SingleBuffer,
+ DoubleBuffer,
+ TripleBuffer
+ };
+
+ enum OpenGLContextProfile {
+ NoProfile,
+ CoreProfile,
+ CompatibilityProfile
+ };
+
+ QSurfaceFormat();
+ QSurfaceFormat(FormatOptions options);
+ QSurfaceFormat(const QSurfaceFormat &other);
+ QSurfaceFormat &operator=(const QSurfaceFormat &other);
+ ~QSurfaceFormat();
+
+ void setDepthBufferSize(int size);
+ int depthBufferSize() const;
+
+ void setStencilBufferSize(int size);
+ int stencilBufferSize() const;
+
+ void setRedBufferSize(int size);
+ int redBufferSize() const;
+ void setGreenBufferSize(int size);
+ int greenBufferSize() const;
+ void setBlueBufferSize(int size);
+ int blueBufferSize() const;
+ void setAlphaBufferSize(int size);
+ int alphaBufferSize() const;
+
+ void setSamples(int numSamples);
+ int samples() const;
+
+ void setSwapBehavior(SwapBehavior behavior);
+ SwapBehavior swapBehavior() const;
+
+ bool hasAlpha() const;
+
+ void setProfile(OpenGLContextProfile profile);
+ OpenGLContextProfile profile() const;
+
+ void setMajorVersion(int majorVersion);
+ int majorVersion() const;
+
+ void setMinorVersion(int minorVersion);
+ int minorVersion() const;
+
+ bool stereo() const;
+ void setStereo(bool enable);
+
+ void setOption(QSurfaceFormat::FormatOptions opt);
+ bool testOption(QSurfaceFormat::FormatOptions opt) const;
+
+private:
+ QSurfaceFormatPrivate *d;
+
+ void detach();
+
+ friend Q_GUI_EXPORT bool operator==(const QSurfaceFormat&, const QSurfaceFormat&);
+ friend Q_GUI_EXPORT bool operator!=(const QSurfaceFormat&, const QSurfaceFormat&);
+#ifndef QT_NO_DEBUG_STREAM
+ friend Q_GUI_EXPORT QDebug operator<<(QDebug, const QSurfaceFormat &);
+#endif
+};
+
+Q_GUI_EXPORT bool operator==(const QSurfaceFormat&, const QSurfaceFormat&);
+Q_GUI_EXPORT bool operator!=(const QSurfaceFormat&, const QSurfaceFormat&);
+
+#ifndef QT_NO_DEBUG_STREAM
+Q_GUI_EXPORT QDebug operator<<(QDebug, const QSurfaceFormat &);
+#endif
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QSurfaceFormat::FormatOptions)
+
+inline bool QSurfaceFormat::stereo() const
+{
+ return testOption(QSurfaceFormat::StereoBuffers);
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif //QSURFACEFORMAT_H
diff --git a/src/gui/kernel/qt_cocoa_helpers_mac.mm b/src/gui/kernel/qt_cocoa_helpers_mac.mm
deleted file mode 100644
index 97ed7f7e39..0000000000
--- a/src/gui/kernel/qt_cocoa_helpers_mac.mm
+++ /dev/null
@@ -1,1824 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/****************************************************************************
-**
-** Copyright (c) 2007-2008, Apple, Inc.
-**
-** All rights reserved.
-**
-** Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are met:
-**
-** * Redistributions of source code must retain the above copyright notice,
-** this list of conditions and the following disclaimer.
-**
-** * Redistributions in binary form must reproduce the above copyright notice,
-** this list of conditions and the following disclaimer in the documentation
-** and/or other materials provided with the distribution.
-**
-** * Neither the name of Apple, Inc. nor the names of its contributors
-** may be used to endorse or promote products derived from this software
-** without specific prior written permission.
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-**
-****************************************************************************/
-
-#include <private/qcore_mac_p.h>
-#include <qaction.h>
-#include <qwidget.h>
-#include <qdesktopwidget.h>
-#include <qevent.h>
-#include <qpixmapcache.h>
-#include <qvarlengtharray.h>
-#include <private/qevent_p.h>
-#include <private/qt_cocoa_helpers_mac_p.h>
-#include <private/qt_mac_p.h>
-#include <private/qapplication_p.h>
-#include <private/qcocoaapplication_mac_p.h>
-#include <private/qcocoawindow_mac_p.h>
-#include <private/qcocoaview_mac_p.h>
-#include <private/qkeymapper_p.h>
-#include <private/qwidget_p.h>
-#include <private/qcocoawindow_mac_p.h>
-
-QT_BEGIN_NAMESPACE
-
-#ifdef QT_MAC_USE_COCOA
-// Cmd + left mousebutton should produce a right button
-// press (mainly for mac users with one-button mice):
-static bool qt_leftButtonIsRightButton = false;
-#endif
-
-Q_GLOBAL_STATIC(QMacWindowFader, macwindowFader);
-
-QMacWindowFader::QMacWindowFader()
- : m_duration(0.250)
-{
-}
-
-QMacWindowFader *QMacWindowFader::currentFader()
-{
- return macwindowFader();
-}
-
-void QMacWindowFader::registerWindowToFade(QWidget *window)
-{
- m_windowsToFade.append(window);
-}
-
-void QMacWindowFader::performFade()
-{
- const QWidgetList myWidgetsToFade = m_windowsToFade;
- const int widgetCount = myWidgetsToFade.count();
-#if QT_MAC_USE_COCOA
- QMacCocoaAutoReleasePool pool;
- [NSAnimationContext beginGrouping];
- [[NSAnimationContext currentContext] setDuration:NSTimeInterval(m_duration)];
-#endif
-
- for (int i = 0; i < widgetCount; ++i) {
- QWidget *widget = m_windowsToFade.at(i);
- OSWindowRef window = qt_mac_window_for(widget);
-#if QT_MAC_USE_COCOA
- [[window animator] setAlphaValue:0.0];
- QTimer::singleShot(qRound(m_duration * 1000), widget, SLOT(hide()));
-#else
- TransitionWindowOptions options = {0, m_duration, 0, 0};
- TransitionWindowWithOptions(window, kWindowFadeTransitionEffect, kWindowHideTransitionAction,
- 0, 1, &options);
-#endif
- }
-#if QT_MAC_USE_COCOA
- [NSAnimationContext endGrouping];
-#endif
- m_duration = 0.250;
- m_windowsToFade.clear();
-}
-
-extern bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event); // qapplication.cpp;
-extern QWidget * mac_mouse_grabber;
-extern QWidget *qt_button_down; //qapplication_mac.cpp
-extern QPointer<QWidget> qt_last_mouse_receiver;
-extern OSViewRef qt_mac_effectiveview_for(const QWidget *w);
-extern void qt_mac_updateCursorWithWidgetUnderMouse(QWidget *widgetUnderMouse); // qcursor_mac.mm
-
-void macWindowFade(void * /*OSWindowRef*/ window, float durationSeconds)
-{
-#ifdef QT_MAC_USE_COCOA
- QMacCocoaAutoReleasePool pool;
-#endif
- OSWindowRef wnd = static_cast<OSWindowRef>(window);
- if (wnd) {
- QWidget *widget;
-#if QT_MAC_USE_COCOA
- widget = [wnd QT_MANGLE_NAMESPACE(qt_qwidget)];
-#else
- const UInt32 kWidgetCreatorQt = kEventClassQt;
- enum {
- kWidgetPropertyQWidget = 'QWId' //QWidget *
- };
- if (GetWindowProperty(static_cast<WindowRef>(window), kWidgetCreatorQt, kWidgetPropertyQWidget, sizeof(widget), 0, &widget) != noErr)
- widget = 0;
-#endif
- if (widget) {
- QMacWindowFader::currentFader()->setFadeDuration(durationSeconds);
- QMacWindowFader::currentFader()->registerWindowToFade(widget);
- QMacWindowFader::currentFader()->performFade();
- }
- }
-}
-struct dndenum_mapper
-{
- NSDragOperation mac_code;
- Qt::DropAction qt_code;
- bool Qt2Mac;
-};
-
-#if defined(QT_MAC_USE_COCOA) && defined(__OBJC__)
-
-static dndenum_mapper dnd_enums[] = {
- { NSDragOperationLink, Qt::LinkAction, true },
- { NSDragOperationMove, Qt::MoveAction, true },
- { NSDragOperationCopy, Qt::CopyAction, true },
- { NSDragOperationGeneric, Qt::CopyAction, false },
- { NSDragOperationEvery, Qt::ActionMask, false },
- { NSDragOperationNone, Qt::IgnoreAction, false }
-};
-
-NSDragOperation qt_mac_mapDropAction(Qt::DropAction action)
-{
- for (int i=0; dnd_enums[i].qt_code; i++) {
- if (dnd_enums[i].Qt2Mac && (action & dnd_enums[i].qt_code)) {
- return dnd_enums[i].mac_code;
- }
- }
- return NSDragOperationNone;
-}
-
-NSDragOperation qt_mac_mapDropActions(Qt::DropActions actions)
-{
- NSDragOperation nsActions = NSDragOperationNone;
- for (int i=0; dnd_enums[i].qt_code; i++) {
- if (dnd_enums[i].Qt2Mac && (actions & dnd_enums[i].qt_code))
- nsActions |= dnd_enums[i].mac_code;
- }
- return nsActions;
-}
-
-Qt::DropAction qt_mac_mapNSDragOperation(NSDragOperation nsActions)
-{
- Qt::DropAction action = Qt::IgnoreAction;
- for (int i=0; dnd_enums[i].mac_code; i++) {
- if (nsActions & dnd_enums[i].mac_code)
- return dnd_enums[i].qt_code;
- }
- return action;
-}
-
-Qt::DropActions qt_mac_mapNSDragOperations(NSDragOperation nsActions)
-{
- Qt::DropActions actions = Qt::IgnoreAction;
- for (int i=0; dnd_enums[i].mac_code; i++) {
- if (nsActions & dnd_enums[i].mac_code)
- actions |= dnd_enums[i].qt_code;
- }
- return actions;
-}
-
-Q_GLOBAL_STATIC(DnDParams, currentDnDParameters);
-DnDParams *macCurrentDnDParameters()
-{
- return currentDnDParameters();
-}
-#endif
-
-bool macWindowIsTextured( void * /*OSWindowRef*/ window )
-{
- OSWindowRef wnd = static_cast<OSWindowRef>(window);
-#if QT_MAC_USE_COCOA
- return ( [wnd styleMask] & NSTexturedBackgroundWindowMask ) ? true : false;
-#else
- WindowAttributes currentAttributes;
- GetWindowAttributes(wnd, &currentAttributes);
- return (currentAttributes & kWindowMetalAttribute) ? true : false;
-#endif
-}
-
-void macWindowToolbarShow(const QWidget *widget, bool show )
-{
- OSWindowRef wnd = qt_mac_window_for(widget);
-#if QT_MAC_USE_COCOA
- if (NSToolbar *toolbar = [wnd toolbar]) {
- QMacCocoaAutoReleasePool pool;
- if (show != [toolbar isVisible]) {
- [toolbar setVisible:show];
- } else {
- // The toolbar may be in sync, but we are not, update our framestrut.
- qt_widget_private(const_cast<QWidget *>(widget))->updateFrameStrut();
- }
- }
-#else
- qt_widget_private(const_cast<QWidget *>(widget))->updateFrameStrut();
- ShowHideWindowToolbar(wnd, show, false);
-#endif
-}
-
-
-void macWindowToolbarSet( void * /*OSWindowRef*/ window, void *toolbarRef )
-{
- OSWindowRef wnd = static_cast<OSWindowRef>(window);
-#if QT_MAC_USE_COCOA
- [wnd setToolbar:static_cast<NSToolbar *>(toolbarRef)];
-#else
- SetWindowToolbar(wnd, static_cast<HIToolbarRef>(toolbarRef));
-#endif
-}
-
-bool macWindowToolbarIsVisible( void * /*OSWindowRef*/ window )
-{
- OSWindowRef wnd = static_cast<OSWindowRef>(window);
-#if QT_MAC_USE_COCOA
- if (NSToolbar *toolbar = [wnd toolbar])
- return [toolbar isVisible];
- return false;
-#else
- return IsWindowToolbarVisible(wnd);
-#endif
-}
-
-void macWindowSetHasShadow( void * /*OSWindowRef*/ window, bool hasShadow )
-{
- OSWindowRef wnd = static_cast<OSWindowRef>(window);
-#if QT_MAC_USE_COCOA
- [wnd setHasShadow:BOOL(hasShadow)];
-#else
- if (hasShadow)
- ChangeWindowAttributes(wnd, 0, kWindowNoShadowAttribute);
- else
- ChangeWindowAttributes(wnd, kWindowNoShadowAttribute, 0);
-#endif
-}
-
-void macWindowFlush(void * /*OSWindowRef*/ window)
-{
- OSWindowRef wnd = static_cast<OSWindowRef>(window);
-#if QT_MAC_USE_COCOA
- [wnd flushWindowIfNeeded];
-#else
- HIWindowFlush(wnd);
-#endif
-}
-
-void * /*NSImage */qt_mac_create_nsimage(const QPixmap &pm)
-{
- QMacCocoaAutoReleasePool pool;
- if(QCFType<CGImageRef> image = pm.toMacCGImageRef()) {
- NSImage *newImage = 0;
- NSRect imageRect = NSMakeRect(0.0, 0.0, CGImageGetWidth(image), CGImageGetHeight(image));
- newImage = [[NSImage alloc] initWithSize:imageRect.size];
- [newImage lockFocus];
- {
- CGContextRef imageContext = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
- CGContextDrawImage(imageContext, *(CGRect*)&imageRect, image);
- }
- [newImage unlockFocus];
- return newImage;
- }
- return 0;
-}
-
-void qt_mac_update_mouseTracking(QWidget *widget)
-{
-#ifdef QT_MAC_USE_COCOA
- [qt_mac_nativeview_for(widget) updateTrackingAreas];
-#else
- Q_UNUSED(widget);
-#endif
-}
-
-OSStatus qt_mac_drawCGImage(CGContextRef inContext, const CGRect *inBounds, CGImageRef inImage)
-{
- // Verbatim copy if HIViewDrawCGImage (as shown on Carbon-Dev)
- OSStatus err = noErr;
-
- require_action(inContext != NULL, InvalidContext, err = paramErr);
- require_action(inBounds != NULL, InvalidBounds, err = paramErr);
- require_action(inImage != NULL, InvalidImage, err = paramErr);
-
- CGContextSaveGState( inContext );
- CGContextTranslateCTM (inContext, 0, inBounds->origin.y + CGRectGetMaxY(*inBounds));
- CGContextScaleCTM(inContext, 1, -1);
-
- CGContextDrawImage(inContext, *inBounds, inImage);
-
- CGContextRestoreGState(inContext);
-InvalidImage:
-InvalidBounds:
-InvalidContext:
- return err;
-}
-
-bool qt_mac_checkForNativeSizeGrip(const QWidget *widget)
-{
-#ifndef QT_MAC_USE_COCOA
- OSViewRef nativeSizeGrip = 0;
- HIViewFindByID(HIViewGetRoot(HIViewGetWindow(HIViewRef(widget->winId()))), kHIViewWindowGrowBoxID, &nativeSizeGrip);
- return (nativeSizeGrip != 0);
-#else
- return [[reinterpret_cast<NSView *>(widget->effectiveWinId()) window] showsResizeIndicator];
-#endif
-}
-struct qt_mac_enum_mapper
-{
- int mac_code;
- int qt_code;
-#if defined(DEBUG_MOUSE_MAPS)
-# define QT_MAC_MAP_ENUM(x) x, #x
- const char *desc;
-#else
-# define QT_MAC_MAP_ENUM(x) x
-#endif
-};
-
-//mouse buttons
-static qt_mac_enum_mapper qt_mac_mouse_symbols[] = {
-{ kEventMouseButtonPrimary, QT_MAC_MAP_ENUM(Qt::LeftButton) },
-{ kEventMouseButtonSecondary, QT_MAC_MAP_ENUM(Qt::RightButton) },
-{ kEventMouseButtonTertiary, QT_MAC_MAP_ENUM(Qt::MidButton) },
-{ 4, QT_MAC_MAP_ENUM(Qt::XButton1) },
-{ 5, QT_MAC_MAP_ENUM(Qt::XButton2) },
-{ 0, QT_MAC_MAP_ENUM(0) }
-};
-Qt::MouseButtons qt_mac_get_buttons(int buttons)
-{
-#ifdef DEBUG_MOUSE_MAPS
- qDebug("Qt: internal: **Mapping buttons: %d (0x%04x)", buttons, buttons);
-#endif
- Qt::MouseButtons ret = Qt::NoButton;
- for(int i = 0; qt_mac_mouse_symbols[i].qt_code; i++) {
- if (buttons & (0x01<<(qt_mac_mouse_symbols[i].mac_code-1))) {
-#ifdef DEBUG_MOUSE_MAPS
- qDebug("Qt: internal: got button: %s", qt_mac_mouse_symbols[i].desc);
-#endif
- ret |= Qt::MouseButtons(qt_mac_mouse_symbols[i].qt_code);
- }
- }
- return ret;
-}
-Qt::MouseButton qt_mac_get_button(EventMouseButton button)
-{
-#ifdef DEBUG_MOUSE_MAPS
- qDebug("Qt: internal: **Mapping button: %d (0x%04x)", button, button);
-#endif
- Qt::MouseButtons ret = 0;
- for(int i = 0; qt_mac_mouse_symbols[i].qt_code; i++) {
- if (button == qt_mac_mouse_symbols[i].mac_code) {
-#ifdef DEBUG_MOUSE_MAPS
- qDebug("Qt: internal: got button: %s", qt_mac_mouse_symbols[i].desc);
-#endif
- return Qt::MouseButton(qt_mac_mouse_symbols[i].qt_code);
- }
- }
- return Qt::NoButton;
-}
-
-void macSendToolbarChangeEvent(QWidget *widget)
-{
- QToolBarChangeEvent ev(!(GetCurrentKeyModifiers() & cmdKey));
- qt_sendSpontaneousEvent(widget, &ev);
-}
-
-Q_GLOBAL_STATIC(QMacTabletHash, tablet_hash)
-QMacTabletHash *qt_mac_tablet_hash()
-{
- return tablet_hash();
-}
-
-#ifdef QT_MAC_USE_COCOA
-
-// Clears the QWidget pointer that each QCocoaView holds.
-void qt_mac_clearCocoaViewQWidgetPointers(QWidget *widget)
-{
- QT_MANGLE_NAMESPACE(QCocoaView) *cocoaView = reinterpret_cast<QT_MANGLE_NAMESPACE(QCocoaView) *>(qt_mac_nativeview_for(widget));
- if (cocoaView && [cocoaView respondsToSelector:@selector(qt_qwidget)]) {
- [cocoaView qt_clearQWidget];
- }
-}
-
-void qt_dispatchTabletProximityEvent(void * /*NSEvent * */ tabletEvent)
-{
- NSEvent *proximityEvent = static_cast<NSEvent *>(tabletEvent);
- // simply construct a Carbon proximity record and handle it all in one spot.
- TabletProximityRec carbonProximityRec = { [proximityEvent vendorID],
- [proximityEvent tabletID],
- [proximityEvent pointingDeviceID],
- [proximityEvent deviceID],
- [proximityEvent systemTabletID],
- [proximityEvent vendorPointingDeviceType],
- [proximityEvent pointingDeviceSerialNumber],
- [proximityEvent uniqueID],
- [proximityEvent capabilityMask],
- [proximityEvent pointingDeviceType],
- [proximityEvent isEnteringProximity] };
- qt_dispatchTabletProximityEvent(carbonProximityRec);
-}
-#endif // QT_MAC_USE_COCOA
-
-void qt_dispatchTabletProximityEvent(const ::TabletProximityRec &proxRec)
-{
- QTabletDeviceData proximityDevice;
- proximityDevice.tabletUniqueID = proxRec.uniqueID;
- proximityDevice.capabilityMask = proxRec.capabilityMask;
-
- switch (proxRec.pointerType) {
- case NSUnknownPointingDevice:
- default:
- proximityDevice.tabletPointerType = QTabletEvent::UnknownPointer;
- break;
- case NSPenPointingDevice:
- proximityDevice.tabletPointerType = QTabletEvent::Pen;
- break;
- case NSCursorPointingDevice:
- proximityDevice.tabletPointerType = QTabletEvent::Cursor;
- break;
- case NSEraserPointingDevice:
- proximityDevice.tabletPointerType = QTabletEvent::Eraser;
- break;
- }
- uint bits = proxRec.vendorPointerType;
- if (bits == 0 && proximityDevice.tabletUniqueID != 0) {
- // Fallback. It seems that the driver doesn't always include all the information.
- // High-End Wacom devices store their "type" in the uper bits of the Unique ID.
- // I'm not sure how to handle it for consumer devices, but I'll test that in a bit.
- bits = proximityDevice.tabletUniqueID >> 32;
- }
- // Defined in the "EN0056-NxtGenImpGuideX"
- // on Wacom's Developer Website (www.wacomeng.com)
- if (((bits & 0x0006) == 0x0002) && ((bits & 0x0F06) != 0x0902)) {
- proximityDevice.tabletDeviceType = QTabletEvent::Stylus;
- } else {
- switch (bits & 0x0F06) {
- case 0x0802:
- proximityDevice.tabletDeviceType = QTabletEvent::Stylus;
- break;
- case 0x0902:
- proximityDevice.tabletDeviceType = QTabletEvent::Airbrush;
- break;
- case 0x0004:
- proximityDevice.tabletDeviceType = QTabletEvent::FourDMouse;
- break;
- case 0x0006:
- proximityDevice.tabletDeviceType = QTabletEvent::Puck;
- break;
- case 0x0804:
- proximityDevice.tabletDeviceType = QTabletEvent::RotationStylus;
- break;
- default:
- proximityDevice.tabletDeviceType = QTabletEvent::NoDevice;
- }
- }
- // The deviceID is "unique" while in the proximity, it's a key that we can use for
- // linking up TabletDeviceData to an event (especially if there are two devices in action).
- bool entering = proxRec.enterProximity;
- if (entering) {
- qt_mac_tablet_hash()->insert(proxRec.deviceID, proximityDevice);
- } else {
- qt_mac_tablet_hash()->remove(proxRec.deviceID);
- }
-
- QTabletEvent qtabletProximity(entering ? QEvent::TabletEnterProximity
- : QEvent::TabletLeaveProximity,
- QPoint(), QPoint(), QPointF(), proximityDevice.tabletDeviceType,
- proximityDevice.tabletPointerType, 0., 0, 0, 0., 0., 0, 0,
- proximityDevice.tabletUniqueID);
-
- qt_sendSpontaneousEvent(qApp, &qtabletProximity);
-}
-
-// Use this method to keep all the information in the TextSegment. As long as it is ordered
-// we are in OK shape, and we can influence that ourselves.
-struct KeyPair
-{
- QChar cocoaKey;
- Qt::Key qtKey;
-};
-
-bool operator==(const KeyPair &entry, QChar qchar)
-{
- return entry.cocoaKey == qchar;
-}
-
-bool operator<(const KeyPair &entry, QChar qchar)
-{
- return entry.cocoaKey < qchar;
-}
-
-bool operator<(QChar qchar, const KeyPair &entry)
-{
- return qchar < entry.cocoaKey;
-}
-
-bool operator<(const Qt::Key &key, const KeyPair &entry)
-{
- return key < entry.qtKey;
-}
-
-bool operator<(const KeyPair &entry, const Qt::Key &key)
-{
- return entry.qtKey < key;
-}
-
-static bool qtKey2CocoaKeySortLessThan(const KeyPair &entry1, const KeyPair &entry2)
-{
- return entry1.qtKey < entry2.qtKey;
-}
-
-static const int NumEntries = 59;
-static const KeyPair entries[NumEntries] = {
- { NSEnterCharacter, Qt::Key_Enter },
- { NSBackspaceCharacter, Qt::Key_Backspace },
- { NSTabCharacter, Qt::Key_Tab },
- { NSNewlineCharacter, Qt::Key_Return },
- { NSCarriageReturnCharacter, Qt::Key_Return },
- { NSBackTabCharacter, Qt::Key_Backtab },
- { kEscapeCharCode, Qt::Key_Escape },
- // Cocoa sends us delete when pressing backspace!
- // (NB when we reverse this list in qtKey2CocoaKey, there
- // will be two indices of Qt::Key_Backspace. But is seems to work
- // ok for menu shortcuts (which uses that function):
- { NSDeleteCharacter, Qt::Key_Backspace },
- { NSUpArrowFunctionKey, Qt::Key_Up },
- { NSDownArrowFunctionKey, Qt::Key_Down },
- { NSLeftArrowFunctionKey, Qt::Key_Left },
- { NSRightArrowFunctionKey, Qt::Key_Right },
- { NSF1FunctionKey, Qt::Key_F1 },
- { NSF2FunctionKey, Qt::Key_F2 },
- { NSF3FunctionKey, Qt::Key_F3 },
- { NSF4FunctionKey, Qt::Key_F4 },
- { NSF5FunctionKey, Qt::Key_F5 },
- { NSF6FunctionKey, Qt::Key_F6 },
- { NSF7FunctionKey, Qt::Key_F7 },
- { NSF8FunctionKey, Qt::Key_F8 },
- { NSF9FunctionKey, Qt::Key_F8 },
- { NSF10FunctionKey, Qt::Key_F10 },
- { NSF11FunctionKey, Qt::Key_F11 },
- { NSF12FunctionKey, Qt::Key_F12 },
- { NSF13FunctionKey, Qt::Key_F13 },
- { NSF14FunctionKey, Qt::Key_F14 },
- { NSF15FunctionKey, Qt::Key_F15 },
- { NSF16FunctionKey, Qt::Key_F16 },
- { NSF17FunctionKey, Qt::Key_F17 },
- { NSF18FunctionKey, Qt::Key_F18 },
- { NSF19FunctionKey, Qt::Key_F19 },
- { NSF20FunctionKey, Qt::Key_F20 },
- { NSF21FunctionKey, Qt::Key_F21 },
- { NSF22FunctionKey, Qt::Key_F22 },
- { NSF23FunctionKey, Qt::Key_F23 },
- { NSF24FunctionKey, Qt::Key_F24 },
- { NSF25FunctionKey, Qt::Key_F25 },
- { NSF26FunctionKey, Qt::Key_F26 },
- { NSF27FunctionKey, Qt::Key_F27 },
- { NSF28FunctionKey, Qt::Key_F28 },
- { NSF29FunctionKey, Qt::Key_F29 },
- { NSF30FunctionKey, Qt::Key_F30 },
- { NSF31FunctionKey, Qt::Key_F31 },
- { NSF32FunctionKey, Qt::Key_F32 },
- { NSF33FunctionKey, Qt::Key_F33 },
- { NSF34FunctionKey, Qt::Key_F34 },
- { NSF35FunctionKey, Qt::Key_F35 },
- { NSInsertFunctionKey, Qt::Key_Insert },
- { NSDeleteFunctionKey, Qt::Key_Delete },
- { NSHomeFunctionKey, Qt::Key_Home },
- { NSEndFunctionKey, Qt::Key_End },
- { NSPageUpFunctionKey, Qt::Key_PageUp },
- { NSPageDownFunctionKey, Qt::Key_PageDown },
- { NSPrintScreenFunctionKey, Qt::Key_Print },
- { NSScrollLockFunctionKey, Qt::Key_ScrollLock },
- { NSPauseFunctionKey, Qt::Key_Pause },
- { NSSysReqFunctionKey, Qt::Key_SysReq },
- { NSMenuFunctionKey, Qt::Key_Menu },
- { NSHelpFunctionKey, Qt::Key_Help },
-};
-static const KeyPair * const end = entries + NumEntries;
-
-QChar qtKey2CocoaKey(Qt::Key key)
-{
- // The first time this function is called, create a reverse
- // looup table sorted on Qt Key rather than Cocoa key:
- static QVector<KeyPair> rev_entries(NumEntries);
- static bool mustInit = true;
- if (mustInit){
- mustInit = false;
- for (int i=0; i<NumEntries; ++i)
- rev_entries[i] = entries[i];
- qSort(rev_entries.begin(), rev_entries.end(), qtKey2CocoaKeySortLessThan);
- }
- const QVector<KeyPair>::iterator i
- = qBinaryFind(rev_entries.begin(), rev_entries.end(), key);
- if (i == rev_entries.end())
- return QChar();
- return i->cocoaKey;
-}
-
-#ifdef QT_MAC_USE_COCOA
-static Qt::Key cocoaKey2QtKey(QChar keyCode)
-{
- const KeyPair *i = qBinaryFind(entries, end, keyCode);
- if (i == end)
- return Qt::Key(keyCode.unicode());
- return i->qtKey;
-}
-
-Qt::KeyboardModifiers qt_cocoaModifiers2QtModifiers(ulong modifierFlags)
-{
- Qt::KeyboardModifiers qtMods =Qt::NoModifier;
- if (modifierFlags & NSShiftKeyMask)
- qtMods |= Qt::ShiftModifier;
- if (modifierFlags & NSControlKeyMask)
- qtMods |= Qt::MetaModifier;
- if (modifierFlags & NSAlternateKeyMask)
- qtMods |= Qt::AltModifier;
- if (modifierFlags & NSCommandKeyMask)
- qtMods |= Qt::ControlModifier;
- if (modifierFlags & NSNumericPadKeyMask)
- qtMods |= Qt::KeypadModifier;
- return qtMods;
-}
-
-NSString *qt_mac_removePrivateUnicode(NSString* string)
-{
- int len = [string length];
- if (len) {
- QVarLengthArray <unichar, 10> characters(len);
- bool changed = false;
- for (int i = 0; i<len; i++) {
- characters[i] = [string characterAtIndex:i];
- // check if they belong to key codes in private unicode range
- // currently we need to handle only the NSDeleteFunctionKey
- if (characters[i] == NSDeleteFunctionKey) {
- characters[i] = NSDeleteCharacter;
- changed = true;
- }
- }
- if (changed)
- return [NSString stringWithCharacters:characters.data() length:len];
- }
- return string;
-}
-
-Qt::KeyboardModifiers qt_cocoaDragOperation2QtModifiers(uint dragOperations)
-{
- Qt::KeyboardModifiers qtMods =Qt::NoModifier;
- if (dragOperations & NSDragOperationLink)
- qtMods |= Qt::MetaModifier;
- if (dragOperations & NSDragOperationGeneric)
- qtMods |= Qt::ControlModifier;
- if (dragOperations & NSDragOperationCopy)
- qtMods |= Qt::AltModifier;
- return qtMods;
-}
-
-static inline QEvent::Type cocoaEvent2QtEvent(NSUInteger eventType)
-{
- // Handle the trivial cases that can be determined from the type.
- switch (eventType) {
- case NSKeyDown:
- return QEvent::KeyPress;
- case NSKeyUp:
- return QEvent::KeyRelease;
- case NSLeftMouseDown:
- case NSRightMouseDown:
- case NSOtherMouseDown:
- return QEvent::MouseButtonPress;
- case NSLeftMouseUp:
- case NSRightMouseUp:
- case NSOtherMouseUp:
- return QEvent::MouseButtonRelease;
- case NSMouseMoved:
- case NSLeftMouseDragged:
- case NSRightMouseDragged:
- case NSOtherMouseDragged:
- return QEvent::MouseMove;
- case NSScrollWheel:
- return QEvent::Wheel;
- }
- return QEvent::None;
-}
-
-static bool mustUseCocoaKeyEvent()
-{
- QCFType<TISInputSourceRef> source = TISCopyCurrentKeyboardInputSource();
- return TISGetInputSourceProperty(source, kTISPropertyUnicodeKeyLayoutData) == 0;
-}
-
-bool qt_dispatchKeyEventWithCocoa(void * /*NSEvent * */ keyEvent, QWidget *widgetToGetEvent)
-{
- NSEvent *event = static_cast<NSEvent *>(keyEvent);
- NSString *keyChars = [event charactersIgnoringModifiers];
- 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;
-
- // 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 (!ignoreText && !(keyMods & (Qt::ControlModifier | Qt::MetaModifier)))
- text = QCFString::toQString(reinterpret_cast<CFStringRef>(keyChars));
-
- UInt32 macScanCode = 1;
- QKeyEventEx ke(cocoaEvent2QtEvent([event type]), qtKey, keyMods, text, [event isARepeat], qMax(1, keyLength),
- macScanCode, [event keyCode], [event modifierFlags]);
- return qt_sendSpontaneousEvent(widgetToGetEvent, &ke) && ke.isAccepted();
-}
-#endif
-
-Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum)
-{
- if (buttonNum == 0)
- return Qt::LeftButton;
- if (buttonNum == 1)
- return Qt::RightButton;
- if (buttonNum == 2)
- return Qt::MidButton;
- if (buttonNum == 3)
- return Qt::XButton1;
- if (buttonNum == 4)
- return Qt::XButton2;
- return Qt::NoButton;
-}
-
-bool qt_dispatchKeyEvent(void * /*NSEvent * */ keyEvent, QWidget *widgetToGetEvent)
-{
-#ifndef QT_MAC_USE_COCOA
- Q_UNUSED(keyEvent);
- Q_UNUSED(widgetToGetEvent);
- return false;
-#else
- NSEvent *event = static_cast<NSEvent *>(keyEvent);
- EventRef key_event = static_cast<EventRef>(const_cast<void *>([event eventRef]));
- Q_ASSERT(key_event);
- unsigned int info = 0;
-
- if ([event type] == NSKeyDown) {
- NSString *characters = [event characters];
- if ([characters length]) {
- unichar value = [characters characterAtIndex:0];
- qt_keymapper_private()->updateKeyMap(0, key_event, (void *)&value);
- info = value;
- }
- }
-
- if (qt_mac_sendMacEventToWidget(widgetToGetEvent, key_event))
- return true;
-
- if (mustUseCocoaKeyEvent())
- return qt_dispatchKeyEventWithCocoa(keyEvent, widgetToGetEvent);
-
- bool consumed = qt_keymapper_private()->translateKeyEvent(widgetToGetEvent, 0, key_event, &info, true);
- return consumed && (info != 0);
-#endif
-}
-
-void qt_dispatchModifiersChanged(void * /*NSEvent * */flagsChangedEvent, QWidget *widgetToGetEvent)
-{
-#ifndef QT_MAC_USE_COCOA
- Q_UNUSED(flagsChangedEvent);
- Q_UNUSED(widgetToGetEvent);
-#else
- UInt32 modifiers = 0;
- // Sync modifiers with Qt
- NSEvent *event = static_cast<NSEvent *>(flagsChangedEvent);
- EventRef key_event = static_cast<EventRef>(const_cast<void *>([event eventRef]));
- Q_ASSERT(key_event);
- GetEventParameter(key_event, kEventParamKeyModifiers, typeUInt32, 0,
- sizeof(modifiers), 0, &modifiers);
- extern void qt_mac_send_modifiers_changed(quint32 modifiers, QObject *object);
- qt_mac_send_modifiers_changed(modifiers, widgetToGetEvent);
-#endif
-}
-
-QPointF flipPoint(const NSPoint &p)
-{
- return QPointF(p.x, flipYCoordinate(p.y));
-}
-
-NSPoint flipPoint(const QPoint &p)
-{
- return NSMakePoint(p.x(), flipYCoordinate(p.y()));
-}
-
-NSPoint flipPoint(const QPointF &p)
-{
- return NSMakePoint(p.x(), flipYCoordinate(p.y()));
-}
-
-#if QT_MAC_USE_COCOA && __OBJC__
-
-void qt_mac_handleNonClientAreaMouseEvent(NSWindow *window, NSEvent *event)
-{
- QWidget *widgetToGetEvent = [window QT_MANGLE_NAMESPACE(qt_qwidget)];
- if (widgetToGetEvent == 0)
- return;
-
- NSEventType evtType = [event type];
- QPoint qlocalPoint;
- QPoint qglobalPoint;
- bool processThisEvent = false;
- bool fakeNCEvents = false;
- bool fakeMouseEvents = false;
-
- // Check if this is a mouse event.
- if (evtType == NSLeftMouseDown || evtType == NSLeftMouseUp
- || evtType == NSRightMouseDown || evtType == NSRightMouseUp
- || evtType == NSOtherMouseDown || evtType == NSOtherMouseUp
- || evtType == NSMouseMoved || evtType == NSLeftMouseDragged
- || evtType == NSRightMouseDragged || evtType == NSOtherMouseDragged) {
- // Check if we want to pass this message to another window
- if (mac_mouse_grabber && mac_mouse_grabber != widgetToGetEvent) {
- NSWindow *grabWindow = static_cast<NSWindow *>(qt_mac_window_for(mac_mouse_grabber));
- if (window != grabWindow) {
- window = grabWindow;
- widgetToGetEvent = mac_mouse_grabber;
- fakeNCEvents = true;
- }
- }
- // Dont generate normal NC mouse events for Left Button dragged
- if(evtType != NSLeftMouseDragged || fakeNCEvents) {
- NSPoint windowPoint = [event locationInWindow];
- NSPoint globalPoint = [[event window] convertBaseToScreen:windowPoint];
- NSRect frameRect = [window frame];
- if (fakeNCEvents || NSMouseInRect(globalPoint, frameRect, NO)) {
- NSRect contentRect = [window contentRectForFrameRect:frameRect];
- qglobalPoint = QPoint(flipPoint(globalPoint).toPoint());
- QWidget *w = widgetToGetEvent->childAt(widgetToGetEvent->mapFromGlobal(qglobalPoint));
- // check that the mouse pointer is on the non-client area and
- // there are not widgets in it.
- if (fakeNCEvents || (!NSMouseInRect(globalPoint, contentRect, NO) && !w)) {
- qglobalPoint = QPoint(flipPoint(globalPoint).toPoint());
- qlocalPoint = widgetToGetEvent->mapFromGlobal(qglobalPoint);
- processThisEvent = true;
- }
- }
- }
- }
- // This is not an NC area mouse message.
- if (!processThisEvent)
- return;
-
- // If the window is frame less, generate fake mouse events instead. (floating QToolBar)
- // or if someone already got an explicit or implicit grab
- if (mac_mouse_grabber || qt_button_down ||
- (fakeNCEvents && (widgetToGetEvent->window()->windowFlags() & Qt::FramelessWindowHint)))
- fakeMouseEvents = true;
-
- Qt::MouseButton button;
- QEvent::Type eventType;
- // Convert to Qt::Event type
- switch (evtType) {
- case NSLeftMouseDown:
- button = Qt::LeftButton;
- eventType = (!fakeMouseEvents) ? QEvent::NonClientAreaMouseButtonPress
- : QEvent::MouseButtonPress;
- break;
- case NSLeftMouseUp:
- button = Qt::LeftButton;
- eventType = (!fakeMouseEvents) ? QEvent::NonClientAreaMouseButtonRelease
- : QEvent::MouseButtonRelease;
- break;
- case NSRightMouseDown:
- button = Qt::RightButton;
- eventType = (!fakeMouseEvents) ? QEvent::NonClientAreaMouseButtonPress
- : QEvent::MouseButtonPress;
- break;
- case NSRightMouseUp:
- button = Qt::RightButton;
- eventType = (!fakeMouseEvents) ? QEvent::NonClientAreaMouseButtonRelease
- : QEvent::MouseButtonRelease;
- break;
- case NSOtherMouseDown:
- button = cocoaButton2QtButton([event buttonNumber]);
- eventType = (!fakeMouseEvents) ? QEvent::NonClientAreaMouseButtonPress
- : QEvent::MouseButtonPress;
- break;
- case NSOtherMouseUp:
- button = cocoaButton2QtButton([event buttonNumber]);
- eventType = (!fakeMouseEvents) ? QEvent::NonClientAreaMouseButtonRelease
- : QEvent::MouseButtonRelease;
- break;
- case NSMouseMoved:
- button = Qt::NoButton;
- eventType = (!fakeMouseEvents) ? QEvent::NonClientAreaMouseMove
- : QEvent::MouseMove;
- break;
- case NSLeftMouseDragged:
- button = Qt::LeftButton;
- eventType = (!fakeMouseEvents) ? QEvent::NonClientAreaMouseMove
- : QEvent::MouseMove;
- break;
- case NSRightMouseDragged:
- button = Qt::RightButton;
- eventType = (!fakeMouseEvents) ? QEvent::NonClientAreaMouseMove
- : QEvent::MouseMove;
- break;
- case NSOtherMouseDragged:
- button = cocoaButton2QtButton([event buttonNumber]);
- eventType = (!fakeMouseEvents) ? QEvent::NonClientAreaMouseMove
- : QEvent::MouseMove;
- break;
- default:
- qWarning("not handled! Non client area mouse message");
- return;
- }
-
- Qt::KeyboardModifiers keyMods = qt_cocoaModifiers2QtModifiers([event modifierFlags]);
- if (eventType == QEvent::NonClientAreaMouseButtonPress || eventType == QEvent::MouseButtonPress) {
- NSInteger clickCount = [event clickCount];
- if (clickCount % 2 == 0)
- eventType = (!fakeMouseEvents) ? QEvent::NonClientAreaMouseButtonDblClick
- : QEvent::MouseButtonDblClick;
- if (button == Qt::LeftButton && (keyMods & Qt::MetaModifier)) {
- button = Qt::RightButton;
- qt_leftButtonIsRightButton = true;
- }
- } else if (eventType == QEvent::NonClientAreaMouseButtonRelease || eventType == QEvent::MouseButtonRelease) {
- if (button == Qt::LeftButton && qt_leftButtonIsRightButton) {
- button = Qt::RightButton;
- qt_leftButtonIsRightButton = false;
- }
- }
-
- Qt::MouseButtons buttons = 0;
- {
- UInt32 mac_buttons;
- if (GetEventParameter((EventRef)[event eventRef], kEventParamMouseChord, typeUInt32, 0,
- sizeof(mac_buttons), 0, &mac_buttons) == noErr)
- buttons = qt_mac_get_buttons(mac_buttons);
- }
-
- QMouseEvent qme(eventType, qlocalPoint, qglobalPoint, button, buttons, keyMods);
- qt_sendSpontaneousEvent(widgetToGetEvent, &qme);
-
- // We don't need to set the implicit grab widget here because we won't
- // reach this point if then event type is Press over a Qt widget.
- // However we might need to unset it if the event is Release.
- if (eventType == QEvent::MouseButtonRelease)
- qt_button_down = 0;
-}
-
-QWidget *qt_mac_getTargetForKeyEvent(QWidget *widgetThatReceivedEvent)
-{
- if (QWidget *popup = QApplication::activePopupWidget()) {
- QWidget *focusInPopup = popup->focusWidget();
- return focusInPopup ? focusInPopup : popup;
- }
-
- QWidget *widgetToGetKey = qApp->focusWidget();
- if (!widgetToGetKey)
- widgetToGetKey = widgetThatReceivedEvent;
-
- return widgetToGetKey;
-}
-
-// This function will find the widget that should receive the
-// mouse event. Because of explicit/implicit mouse grabs, popups,
-// etc, this might not end up being the same as the widget under
-// the mouse (which is more interresting when handling enter/leave
-// events
-QWidget *qt_mac_getTargetForMouseEvent(
- // You can call this function without providing an event.
- NSEvent *event,
- QEvent::Type eventType,
- QPoint &returnLocalPoint,
- QPoint &returnGlobalPoint,
- QWidget *nativeWidget,
- QWidget **returnWidgetUnderMouse)
-{
- Q_UNUSED(event);
- NSPoint nsglobalpoint = event ? [[event window] convertBaseToScreen:[event locationInWindow]] : [NSEvent mouseLocation];
- returnGlobalPoint = flipPoint(nsglobalpoint).toPoint();
- QWidget *mouseGrabber = QWidget::mouseGrabber();
- bool buttonDownNotBlockedByModal = qt_button_down && !QApplicationPrivate::isBlockedByModal(qt_button_down);
- QWidget *popup = QApplication::activePopupWidget();
-
- // Resolve the widget under the mouse:
- QWidget *widgetUnderMouse = 0;
- if (popup || qt_button_down || !nativeWidget || !nativeWidget->isVisible()) {
- // Using QApplication::widgetAt for finding the widget under the mouse
- // is most safe, since it ignores cocoas own mouse down redirections (which
- // we need to be prepared for when using nativeWidget as starting point).
- // (the only exception is for QMacNativeWidget, where QApplication::widgetAt fails).
- // But it is also slower (I guess), so we try to avoid it and use nativeWidget if we can:
- widgetUnderMouse = QApplication::widgetAt(returnGlobalPoint);
- }
-
- if (!widgetUnderMouse && nativeWidget) {
- // Entering here should be the common case. We
- // also handle the QMacNativeWidget fallback case.
- QPoint p = nativeWidget->mapFromGlobal(returnGlobalPoint);
- widgetUnderMouse = nativeWidget->childAt(p);
- if (!widgetUnderMouse && nativeWidget->rect().contains(p))
- widgetUnderMouse = nativeWidget;
- }
-
- if (widgetUnderMouse) {
- // Check if widgetUnderMouse is blocked by a modal
- // window, or the mouse if over the frame strut:
- if (widgetUnderMouse == qt_button_down) {
- // Small optimization to avoid an extra call to isBlockedByModal:
- if (buttonDownNotBlockedByModal == false)
- widgetUnderMouse = 0;
- } else if (QApplicationPrivate::isBlockedByModal(widgetUnderMouse)) {
- widgetUnderMouse = 0;
- }
-
- if (widgetUnderMouse && widgetUnderMouse->isWindow()) {
- // Exclude the titlebar (and frame strut) when finding widget under mouse:
- QPoint p = widgetUnderMouse->mapFromGlobal(returnGlobalPoint);
- if (!widgetUnderMouse->rect().contains(p))
- widgetUnderMouse = 0;
- }
- }
- if (returnWidgetUnderMouse)
- *returnWidgetUnderMouse = widgetUnderMouse;
-
- // Resolve the target for the mouse event. Default will be
- // widgetUnderMouse, except if there is a grab (popup/mouse/button-down):
- if (popup && !mouseGrabber) {
- // We special case handling of popups, since they have an implicitt mouse grab.
- QWidget *candidate = buttonDownNotBlockedByModal ? qt_button_down : widgetUnderMouse;
- if (!popup->isAncestorOf(candidate)) {
- // INVARIANT: we have a popup, but the candidate is not
- // in it. But the popup will grab the mouse anyway,
- // except if the user scrolls:
- if (eventType == QEvent::Wheel)
- return 0;
- returnLocalPoint = popup->mapFromGlobal(returnGlobalPoint);
- return popup;
- } else if (popup == candidate) {
- // INVARIANT: The candidate is the popup itself, and not a child:
- returnLocalPoint = popup->mapFromGlobal(returnGlobalPoint);
- return popup;
- } else {
- // INVARIANT: The candidate is a child inside the popup:
- returnLocalPoint = candidate->mapFromGlobal(returnGlobalPoint);
- return candidate;
- }
- }
-
- QWidget *target = mouseGrabber;
- if (!target && buttonDownNotBlockedByModal)
- target = qt_button_down;
- if (!target)
- target = widgetUnderMouse;
- if (!target)
- return 0;
-
- returnLocalPoint = target->mapFromGlobal(returnGlobalPoint);
- return target;
-}
-
-QPointer<QWidget> qt_last_native_mouse_receiver = 0;
-
-static inline void qt_mac_checkEnterLeaveForNativeWidgets(QWidget *maybeEnterWidget)
-{
- // Dispatch enter/leave for the cases where QApplicationPrivate::sendMouseEvent do
- // not. This will in general be the cases when alien widgets are not involved:
- // 1. from a native widget to another native widget or
- // 2. from a native widget to no widget
- // 3. from no widget to a native or alien widget
-
- if (qt_button_down || QWidget::mouseGrabber())
- return;
-
- if ((maybeEnterWidget == qt_last_native_mouse_receiver) && qt_last_native_mouse_receiver)
- return;
- if (maybeEnterWidget) {
- if (!qt_last_native_mouse_receiver) {
- // case 3
- QApplicationPrivate::dispatchEnterLeave(maybeEnterWidget, 0);
- qt_last_native_mouse_receiver = maybeEnterWidget->internalWinId() ? maybeEnterWidget : maybeEnterWidget->nativeParentWidget();
- } else if (maybeEnterWidget->internalWinId()) {
- // case 1
- QApplicationPrivate::dispatchEnterLeave(maybeEnterWidget, qt_last_native_mouse_receiver);
- qt_last_native_mouse_receiver = maybeEnterWidget->internalWinId() ? maybeEnterWidget : maybeEnterWidget->nativeParentWidget();
- } // else at lest one of the widgets are alien, so enter/leave will be handled in QApplicationPrivate
- } else {
- if (qt_last_native_mouse_receiver) {
- // case 2
- QApplicationPrivate::dispatchEnterLeave(0, qt_last_native_mouse_receiver);
- qt_last_mouse_receiver = 0;
- qt_last_native_mouse_receiver = 0;
- }
- }
-}
-
-bool qt_mac_handleMouseEvent(NSEvent *event, QEvent::Type eventType, Qt::MouseButton button, QWidget *nativeWidget)
-{
- // Give the Input Manager a chance to process the mouse events.
- NSInputManager *currentIManager = [NSInputManager currentInputManager];
- if (currentIManager && [currentIManager wantsToHandleMouseEvents]) {
- [currentIManager handleMouseEvent:event];
- }
-
- // Find the widget that should receive the event, and the widget under the mouse. Those
- // can differ if an implicit or explicit mouse grab is active:
- QWidget *widgetUnderMouse = 0;
- QPoint localPoint, globalPoint;
- QWidget *widgetToGetMouse = qt_mac_getTargetForMouseEvent(event, eventType, localPoint, globalPoint, nativeWidget, &widgetUnderMouse);
- if (!widgetToGetMouse)
- return false;
-
- // From here on, we let nativeWidget actually be the native widget under widgetUnderMouse. The reason
- // for this, is that qt_mac_getTargetForMouseEvent will set cocoa's mouse event redirection aside when
- // determining which widget is under the mouse (in other words, it will usually ignore nativeWidget).
- // nativeWidget will be used in QApplicationPrivate::sendMouseEvent to correctly dispatch enter/leave events.
- if (widgetUnderMouse)
- nativeWidget = widgetUnderMouse->internalWinId() ? widgetUnderMouse : widgetUnderMouse->nativeParentWidget();
- if (!nativeWidget)
- return false;
- NSView *view = qt_mac_effectiveview_for(nativeWidget);
-
- // Handle tablet events (if any) first.
- if (qt_mac_handleTabletEvent(view, event)) {
- // Tablet event was handled. In Qt we aren't supposed to send the mouse event.
- return true;
- }
-
- EventRef carbonEvent = static_cast<EventRef>(const_cast<void *>([event eventRef]));
- if (qt_mac_sendMacEventToWidget(widgetToGetMouse, carbonEvent))
- return true;
-
- // Keep previousButton to make sure we don't send double click
- // events when the user double clicks using two different buttons:
- static Qt::MouseButton previousButton = Qt::NoButton;
-
- Qt::KeyboardModifiers keyMods = qt_cocoaModifiers2QtModifiers([event modifierFlags]);
- NSInteger clickCount = [event clickCount];
- Qt::MouseButtons buttons = 0;
- {
- UInt32 mac_buttons;
- if (GetEventParameter(carbonEvent, kEventParamMouseChord, typeUInt32, 0,
- sizeof(mac_buttons), 0, &mac_buttons) == noErr)
- buttons = qt_mac_get_buttons(mac_buttons);
- }
-
- // Send enter/leave events for the cases when QApplicationPrivate::sendMouseEvent do not:
- qt_mac_checkEnterLeaveForNativeWidgets(widgetUnderMouse);
-
- switch (eventType) {
- default:
- qWarning("not handled! %d", eventType);
- break;
- case QEvent::MouseMove:
- if (button == Qt::LeftButton && qt_leftButtonIsRightButton)
- button = Qt::RightButton;
- break;
- case QEvent::MouseButtonPress:
- qt_button_down = widgetUnderMouse;
- if (clickCount % 2 == 0 && (previousButton == Qt::NoButton || previousButton == button))
- eventType = QEvent::MouseButtonDblClick;
- if (button == Qt::LeftButton && (keyMods & Qt::MetaModifier)) {
- button = Qt::RightButton;
- qt_leftButtonIsRightButton = true;
- }
- break;
- case QEvent::MouseButtonRelease:
- if (button == Qt::LeftButton && qt_leftButtonIsRightButton) {
- button = Qt::RightButton;
- qt_leftButtonIsRightButton = false;
- }
- qt_button_down = 0;
- break;
- }
-
- qt_mac_updateCursorWithWidgetUnderMouse(widgetUnderMouse);
-
- DnDParams *dndParams = currentDnDParameters();
- dndParams->view = view;
- dndParams->theEvent = event;
- dndParams->globalPoint = globalPoint;
-
- // Send the mouse event:
- QMouseEvent qme(eventType, localPoint, globalPoint, button, buttons, keyMods);
- QApplicationPrivate::sendMouseEvent(
- widgetToGetMouse, &qme, widgetUnderMouse, nativeWidget,
- &qt_button_down, qt_last_mouse_receiver, true);
-
- if (eventType == QEvent::MouseButtonPress && button == Qt::RightButton) {
- QContextMenuEvent qcme(QContextMenuEvent::Mouse, localPoint, globalPoint, keyMods);
- qt_sendSpontaneousEvent(widgetToGetMouse, &qcme);
- }
-
- if (eventType == QEvent::MouseButtonRelease) {
- // A mouse button was released, which means that the implicit grab was
- // released. We therefore need to re-check if should send (delayed) enter leave events:
- // qt_button_down has now become NULL since the call at the top of the function. Also, since
- // the relase might have closed a window, we dont give the nativeWidget hint
- qt_mac_getTargetForMouseEvent(0, QEvent::None, localPoint, globalPoint, nativeWidget, &widgetUnderMouse);
- qt_mac_checkEnterLeaveForNativeWidgets(widgetUnderMouse);
- }
-
- previousButton = button;
- return true;
-}
-#endif
-
-bool qt_mac_handleTabletEvent(void * /*QCocoaView * */view, void * /*NSEvent * */tabletEvent)
-{
-#ifndef QT_MAC_USE_COCOA
- Q_UNUSED(view);
- Q_UNUSED(tabletEvent);
- return false;
-#else
- QT_MANGLE_NAMESPACE(QCocoaView) *theView = static_cast<QT_MANGLE_NAMESPACE(QCocoaView) *>(view);
- NSView *theNSView = static_cast<NSView *>(view);
- NSEvent *theTabletEvent = static_cast<NSEvent *>(tabletEvent);
-
- NSEventType eventType = [theTabletEvent type];
- if (eventType != NSTabletPoint && [theTabletEvent subtype] != NSTabletPointEventSubtype)
- return false; // Not a tablet event.
-
- NSPoint windowPoint = [theTabletEvent locationInWindow];
- NSPoint globalPoint = [[theTabletEvent window] convertBaseToScreen:windowPoint];
-
- QWidget *qwidget = [theView qt_qwidget];
- QWidget *widgetToGetMouse = qwidget;
- QWidget *popup = qAppInstance()->activePopupWidget();
- if (popup && popup != qwidget->window())
- widgetToGetMouse = popup;
-
- if (qt_mac_sendMacEventToWidget(widgetToGetMouse,
- static_cast<EventRef>(const_cast<void *>([theTabletEvent eventRef]))))
- return true;
- if (widgetToGetMouse != qwidget) {
- theNSView = qt_mac_nativeview_for(widgetToGetMouse);
- windowPoint = [[theNSView window] convertScreenToBase:globalPoint];
- }
- NSPoint localPoint = [theNSView convertPoint:windowPoint fromView:nil];
- // Tablet events do not handle WA_TransparentForMouseEvents ATM
- // In theory, people who set the WA_TransparentForMouseEvents attribute won't handle
- // tablet events either in which case they will fall into the mouse event case and get
- // them passed on. This will NOT handle the raw events, but that might not be a big problem.
-
- const QMacTabletHash *tabletHash = qt_mac_tablet_hash();
- if (!tabletHash->contains([theTabletEvent deviceID])) {
- qWarning("QCocoaView handleTabletEvent: This tablet device is unknown"
- " (received no proximity event for it). Discarding event.");
- return false;
- }
- const QTabletDeviceData &deviceData = tabletHash->value([theTabletEvent deviceID]);
-
-
- QEvent::Type qType;
- switch (eventType) {
- case NSLeftMouseDown:
- case NSRightMouseDown:
- qType = QEvent::TabletPress;
- break;
- case NSLeftMouseUp:
- case NSRightMouseUp:
- qType = QEvent::TabletRelease;
- break;
- case NSMouseMoved:
- case NSTabletPoint:
- case NSLeftMouseDragged:
- case NSRightMouseDragged:
- default:
- qType = QEvent::TabletMove;
- break;
- }
-
- qreal pressure;
- if (eventType != NSMouseMoved) {
- pressure = [theTabletEvent pressure];
- } else {
- pressure = 0.0;
- }
-
- NSPoint tilt = [theTabletEvent tilt];
- int xTilt = qRound(tilt.x * 60.0);
- int yTilt = qRound(tilt.y * -60.0);
- qreal tangentialPressure = 0;
- qreal rotation = 0;
- int z = 0;
- if (deviceData.capabilityMask & 0x0200)
- z = [theTabletEvent absoluteZ];
-
- if (deviceData.capabilityMask & 0x0800)
- tangentialPressure = [theTabletEvent tangentialPressure];
-
- rotation = [theTabletEvent rotation];
- QPointF hiRes = flipPoint(globalPoint);
- QTabletEvent qtabletEvent(qType, QPoint(localPoint.x, localPoint.y),
- hiRes.toPoint(), hiRes,
- deviceData.tabletDeviceType, deviceData.tabletPointerType,
- pressure, xTilt, yTilt, tangentialPressure, rotation, z,
- qt_cocoaModifiers2QtModifiers([theTabletEvent modifierFlags]),
- deviceData.tabletUniqueID);
-
- qt_sendSpontaneousEvent(widgetToGetMouse, &qtabletEvent);
- return qtabletEvent.isAccepted();
-#endif
-}
-
-void qt_mac_updateContentBorderMetricts(void * /*OSWindowRef */window, const ::HIContentBorderMetrics &metrics)
-{
- OSWindowRef theWindow = static_cast<OSWindowRef>(window);
-#if !defined(QT_MAC_USE_COCOA)
-# if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
- if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) {
- ::HIWindowSetContentBorderThickness(theWindow, &metrics);
- }
-# else
- Q_UNUSED(window);
- Q_UNUSED(metrics);
-# endif
-#else
- if ([theWindow styleMask] & NSTexturedBackgroundWindowMask)
- [theWindow setContentBorderThickness:metrics.top forEdge:NSMaxYEdge];
- [theWindow setContentBorderThickness:metrics.bottom forEdge:NSMinYEdge];
-#endif
-}
-
-#if QT_MAC_USE_COCOA
-void qt_mac_replaceDrawRect(void * /*OSWindowRef */window, QWidgetPrivate *widget)
-{
- QMacCocoaAutoReleasePool pool;
- OSWindowRef theWindow = static_cast<OSWindowRef>(window);
- if(!theWindow)
- return;
- id theClass = [[[theWindow contentView] superview] class];
- // What we do here is basically to add a new selector to NSThemeFrame called
- // "drawRectOriginal:" which will contain the original implementation of
- // "drawRect:". After that we get the new implementation from QCocoaWindow
- // and exchange them. The new implementation is called drawRectSpecial.
- // We cannot just add the method because it might have been added before and since
- // we cannot remove a method once it has been added we need to ask QCocoaWindow if
- // we did the swap or not.
- if(!widget->drawRectOriginalAdded) {
- Method m2 = class_getInstanceMethod(theClass, @selector(drawRect:));
- if(!m2) {
- // This case is pretty extreme, no drawRect means no drawing!
- return;
- }
- class_addMethod(theClass, @selector(drawRectOriginal:), method_getImplementation(m2), method_getTypeEncoding(m2));
- widget->drawRectOriginalAdded = true;
- }
- if(widget->originalDrawMethod) {
- Method m0 = class_getInstanceMethod([theWindow class], @selector(drawRectSpecial:));
- if(!m0) {
- // Ok, this means the methods were never swapped. Just ignore
- return;
- }
- Method m1 = class_getInstanceMethod(theClass, @selector(drawRect:));
- if(!m1) {
- // Ok, this means the methods were never swapped. Just ignore
- return;
- }
- // We have the original method here. Proceed and swap the methods.
- method_exchangeImplementations(m1, m0);
- widget->originalDrawMethod = false;
- [theWindow display];
- }
-}
-
-void qt_mac_replaceDrawRectOriginal(void * /*OSWindowRef */window, QWidgetPrivate *widget)
-{
- QMacCocoaAutoReleasePool pool;
- OSWindowRef theWindow = static_cast<OSWindowRef>(window);
- id theClass = [[[theWindow contentView] superview] class];
- // Now we need to revert the methods to their original state.
- // We cannot remove the method, so we just keep track of it in QCocoaWindow.
- Method m0 = class_getInstanceMethod([theWindow class], @selector(drawRectSpecial:));
- if(!m0) {
- // Ok, this means the methods were never swapped. Just ignore
- return;
- }
- Method m1 = class_getInstanceMethod(theClass, @selector(drawRect:));
- if(!m1) {
- // Ok, this means the methods were never swapped. Just ignore
- return;
- }
- method_exchangeImplementations(m1, m0);
- widget->originalDrawMethod = true;
- [theWindow display];
-}
-#endif // QT_MAC_USE_COCOA
-
-#if QT_MAC_USE_COCOA
-void qt_mac_showBaseLineSeparator(void * /*OSWindowRef */window, bool show)
-{
- if(!window)
- return;
- QMacCocoaAutoReleasePool pool;
- OSWindowRef theWindow = static_cast<OSWindowRef>(window);
- NSToolbar *macToolbar = [theWindow toolbar];
- [macToolbar setShowsBaselineSeparator:show];
-}
-#endif // QT_MAC_USE_COCOA
-
-QStringList qt_mac_NSArrayToQStringList(void *nsarray)
-{
- QStringList result;
- NSArray *array = static_cast<NSArray *>(nsarray);
- for (NSUInteger i=0; i<[array count]; ++i)
- result << qt_mac_NSStringToQString([array objectAtIndex:i]);
- return result;
-}
-
-void *qt_mac_QStringListToNSMutableArrayVoid(const QStringList &list)
-{
- NSMutableArray *result = [NSMutableArray arrayWithCapacity:list.size()];
- for (int i=0; i<list.size(); ++i){
- [result addObject:reinterpret_cast<const NSString *>(QCFString::toCFStringRef(list[i]))];
- }
- return result;
-}
-
-#if QT_MAC_USE_COCOA
-void qt_syncCocoaTitleBarButtons(OSWindowRef window, QWidget *widgetForWindow)
-{
- if (!widgetForWindow)
- return;
-
- Qt::WindowFlags flags = widgetForWindow->windowFlags();
- bool customize = flags & Qt::CustomizeWindowHint;
-
- NSButton *btn = [window standardWindowButton:NSWindowZoomButton];
- // BOOL is not an int, so the bitwise AND doesn't work.
- bool go = uint(customize && !(flags & Qt::WindowMaximizeButtonHint)) == 0;
- [btn setEnabled:go];
-
- btn = [window standardWindowButton:NSWindowMiniaturizeButton];
- go = uint(customize && !(flags & Qt::WindowMinimizeButtonHint)) == 0;
- [btn setEnabled:go];
-
- btn = [window standardWindowButton:NSWindowCloseButton];
- go = uint(customize && !(flags & Qt::WindowSystemMenuHint
- || flags & Qt::WindowCloseButtonHint)) == 0;
- [btn setEnabled:go];
-
- [window setShowsToolbarButton:uint(flags & Qt::MacWindowToolBarButtonHint) != 0];
-}
-#endif // QT_MAC_USE_COCOA
-
-// Carbon: Make sure you call QDEndContext on the context when done with it.
-CGContextRef qt_mac_graphicsContextFor(QWidget *widget)
-{
- if (!widget)
- return 0;
-
-#ifndef QT_MAC_USE_COCOA
- CGContextRef context;
- CGrafPtr port = GetWindowPort(qt_mac_window_for(widget));
- QDBeginCGContext(port, &context);
-#else
- CGContextRef context = (CGContextRef)[[NSGraphicsContext graphicsContextWithWindow:qt_mac_window_for(widget)] graphicsPort];
-#endif
- return context;
-}
-
-void qt_mac_dispatchPendingUpdateRequests(QWidget *widget)
-{
- if (!widget)
- return;
-#ifndef QT_MAC_USE_COCOA
- HIViewRender(qt_mac_nativeview_for(widget));
-#else
- [qt_mac_nativeview_for(widget) displayIfNeeded];
-#endif
-}
-
-CGFloat qt_mac_get_scalefactor()
-{
-#ifndef QT_MAC_USE_COCOA
- return HIGetScaleFactor();
-#else
- return [[NSScreen mainScreen] userSpaceScaleFactor];
-#endif
-}
-
-QString qt_mac_get_pasteboardString(OSPasteboardRef paste)
-{
- QMacCocoaAutoReleasePool pool;
- NSPasteboard *pb = nil;
- CFStringRef pbname;
- if (PasteboardCopyName(paste, &pbname) == noErr) {
- pb = [NSPasteboard pasteboardWithName:const_cast<NSString *>(reinterpret_cast<const NSString *>(pbname))];
- CFRelease(pbname);
- } else {
- pb = [NSPasteboard generalPasteboard];
- }
- if (pb) {
- NSString *text = [pb stringForType:NSStringPboardType];
- if (text)
- return qt_mac_NSStringToQString(text);
- }
- return QString();
-}
-
-QPixmap qt_mac_convert_iconref(const IconRef icon, int width, int height)
-{
- QPixmap ret(width, height);
- ret.fill(QColor(0, 0, 0, 0));
-
- CGRect rect = CGRectMake(0, 0, width, height);
-
- CGContextRef ctx = qt_mac_cg_context(&ret);
- CGAffineTransform old_xform = CGContextGetCTM(ctx);
- CGContextConcatCTM(ctx, CGAffineTransformInvert(old_xform));
- CGContextConcatCTM(ctx, CGAffineTransformIdentity);
-
- ::RGBColor b;
- b.blue = b.green = b.red = 255*255;
- PlotIconRefInContext(ctx, &rect, kAlignNone, kTransformNone, &b, kPlotIconRefNormalFlags, icon);
- CGContextRelease(ctx);
- return ret;
-}
-
-void qt_mac_constructQIconFromIconRef(const IconRef icon, const IconRef overlayIcon, QIcon *retIcon, QStyle::StandardPixmap standardIcon)
-{
- int size = 16;
- while (size <= 128) {
-
- const QString cacheKey = QLatin1String("qt_mac_constructQIconFromIconRef") + QString::number(standardIcon) + QString::number(size);
- QPixmap mainIcon;
- if (standardIcon >= QStyle::SP_CustomBase) {
- mainIcon = qt_mac_convert_iconref(icon, size, size);
- } else if (QPixmapCache::find(cacheKey, mainIcon) == false) {
- mainIcon = qt_mac_convert_iconref(icon, size, size);
- QPixmapCache::insert(cacheKey, mainIcon);
- }
-
- if (overlayIcon) {
- int littleSize = size / 2;
- QPixmap overlayPix = qt_mac_convert_iconref(overlayIcon, littleSize, littleSize);
- QPainter painter(&mainIcon);
- painter.drawPixmap(size - littleSize, size - littleSize, overlayPix);
- }
-
- retIcon->addPixmap(mainIcon);
- size += size; // 16 -> 32 -> 64 -> 128
- }
-}
-
-#ifdef QT_MAC_USE_COCOA
-void qt_mac_menu_collapseSeparators(void */*NSMenu **/ theMenu, bool collapse)
-{
- QMacCocoaAutoReleasePool pool;
- OSMenuRef menu = static_cast<OSMenuRef>(theMenu);
- if (collapse) {
- bool previousIsSeparator = true; // setting to true kills all the separators placed at the top.
- NSMenuItem *previousItem = nil;
-
- NSArray *itemArray = [menu itemArray];
- for (unsigned int i = 0; i < [itemArray count]; ++i) {
- NSMenuItem *item = reinterpret_cast<NSMenuItem *>([itemArray objectAtIndex:i]);
- if ([item isSeparatorItem]) {
- [item setHidden:previousIsSeparator];
- }
-
- if (![item isHidden]) {
- previousItem = item;
- previousIsSeparator = ([previousItem isSeparatorItem]);
- }
- }
-
- // We now need to check the final item since we don't want any separators at the end of the list.
- if (previousItem && previousIsSeparator)
- [previousItem setHidden:YES];
- } else {
- NSArray *itemArray = [menu itemArray];
- for (unsigned int i = 0; i < [itemArray count]; ++i) {
- NSMenuItem *item = reinterpret_cast<NSMenuItem *>([itemArray objectAtIndex:i]);
- if (QAction *action = reinterpret_cast<QAction *>([item tag]))
- [item setHidden:!action->isVisible()];
- }
- }
-}
-
-class CocoaPostMessageAfterEventLoopExitHelp : public QObject
-{
- id target;
- SEL selector;
- int argCount;
- id arg1;
- id arg2;
-public:
- CocoaPostMessageAfterEventLoopExitHelp(id target, SEL selector, int argCount, id arg1, id arg2)
- : target(target), selector(selector), argCount(argCount), arg1(arg1), arg2(arg2){
- deleteLater();
- }
-
- ~CocoaPostMessageAfterEventLoopExitHelp()
- {
- qt_cocoaPostMessage(target, selector, argCount, arg1, arg2);
- }
-};
-
-void qt_cocoaPostMessage(id target, SEL selector, int argCount, id arg1, id arg2)
-{
- // WARNING: data1 and data2 is truncated to from 64-bit to 32-bit on OS 10.5!
- // That is why we need to split the address in two parts:
- QCocoaPostMessageArgs *args = new QCocoaPostMessageArgs(target, selector, argCount, arg1, arg2);
- quint32 lower = quintptr(args);
- quint32 upper = quintptr(args) >> 32;
- NSEvent *e = [NSEvent otherEventWithType:NSApplicationDefined
- location:NSZeroPoint modifierFlags:0 timestamp:0 windowNumber:0
- context:nil subtype:QtCocoaEventSubTypePostMessage data1:lower data2:upper];
- [NSApp postEvent:e atStart:NO];
-}
-
-void qt_cocoaPostMessageAfterEventLoopExit(id target, SEL selector, int argCount, id arg1, id arg2)
-{
- if (QApplicationPrivate::instance()->threadData->eventLoops.size() <= 1)
- qt_cocoaPostMessage(target, selector, argCount, arg1, arg2);
- else
- new CocoaPostMessageAfterEventLoopExitHelp(target, selector, argCount, arg1, arg2);
-}
-
-#endif
-
-QMacCocoaAutoReleasePool::QMacCocoaAutoReleasePool()
-{
-#ifndef QT_MAC_USE_COCOA
- NSApplicationLoad();
-#endif
- pool = (void*)[[NSAutoreleasePool alloc] init];
-}
-
-QMacCocoaAutoReleasePool::~QMacCocoaAutoReleasePool()
-{
- [(NSAutoreleasePool*)pool release];
-}
-
-void qt_mac_post_retranslateAppMenu()
-{
-#ifdef QT_MAC_USE_COCOA
- QMacCocoaAutoReleasePool pool;
- qt_cocoaPostMessage([NSApp QT_MANGLE_NAMESPACE(qt_qcocoamenuLoader)], @selector(qtTranslateApplicationMenu));
-#endif
-}
-
-QWidgetPrivate *QMacScrollOptimization::_target = 0;
-bool QMacScrollOptimization::_inWheelEvent = false;
-int QMacScrollOptimization::_dx = 0;
-int QMacScrollOptimization::_dy = 0;
-QRect QMacScrollOptimization::_scrollRect = QRect(0, 0, -1, -1);
-
-#ifdef QT_MAC_USE_COCOA
-// This method implements the magic for the drawRectSpecial method.
-// We draw a line at the upper edge of the content view in order to
-// override the title baseline.
-void macDrawRectOnTop(void * /*OSWindowRef */window)
-{
- OSWindowRef theWindow = static_cast<OSWindowRef>(window);
- NSView *contentView = [theWindow contentView];
- if(!contentView)
- return;
- // Get coordinates of the content view
- NSRect contentRect = [contentView frame];
- // Draw a line on top of the already drawn line.
- // We need to check if we are active or not to use the proper color.
- if([theWindow isKeyWindow] || [theWindow isMainWindow]) {
- [[NSColor colorWithCalibratedRed:1.0 green:1.0 blue:1.0 alpha:1.0] set];
- } else {
- [[NSColor colorWithCalibratedRed:1.0 green:1.0 blue:1.0 alpha:1.0] set];
- }
- NSPoint origin = NSMakePoint(0, contentRect.size.height);
- NSPoint end = NSMakePoint(contentRect.size.width, contentRect.size.height);
- [NSBezierPath strokeLineFromPoint:origin toPoint:end];
-}
-
-// This method will (or at least should) get called only once.
-// Its mission is to find out if we are active or not. If we are active
-// we assume that we were launched via finder, otherwise we assume
-// we were called from the command line. The distinction is important,
-// since in the first case we don't need to trigger a paintEvent, while
-// in the second case we do.
-void macSyncDrawingOnFirstInvocation(void * /*OSWindowRef */window)
-{
- OSWindowRef theWindow = static_cast<OSWindowRef>(window);
- NSApplication *application = [NSApplication sharedApplication];
- NSToolbar *toolbar = [theWindow toolbar];
- if([application isActive]) {
- // Launched from finder
- [toolbar setShowsBaselineSeparator:NO];
- } else {
- // Launched from commandline
- [toolbar setVisible:false];
- [toolbar setShowsBaselineSeparator:NO];
- [toolbar setVisible:true];
- [theWindow display];
- }
-}
-
-void qt_cocoaStackChildWindowOnTopOfOtherChildren(QWidget *childWidget)
-{
- if (!childWidget)
- return;
-
- QWidget *parent = childWidget->parentWidget();
- if (childWidget->isWindow() && parent) {
- if ([[qt_mac_window_for(parent) childWindows] containsObject:qt_mac_window_for(childWidget)]) {
- QWidgetPrivate *d = qt_widget_private(childWidget);
- d->setSubWindowStacking(false);
- d->setSubWindowStacking(true);
- }
- }
-}
-
-void qt_mac_display(QWidget *widget)
-{
- NSView *theNSView = qt_mac_nativeview_for(widget);
- [theNSView display];
-}
-
-void qt_mac_setNeedsDisplay(QWidget *widget)
-{
- NSView *theNSView = qt_mac_nativeview_for(widget);
- [theNSView setNeedsDisplay:YES];
-}
-
-void qt_mac_setNeedsDisplayInRect(QWidget *widget, QRegion region)
-{
- NSView *theNSView = qt_mac_nativeview_for(widget);
- if (region.isEmpty()) {
- [theNSView setNeedsDisplay:YES];
- return;
- }
-
- QVector<QRect> rects = region.rects();
- for (int i = 0; i < rects.count(); ++i) {
- const QRect &rect = rects.at(i);
- NSRect nsrect = NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height());
- [theNSView setNeedsDisplayInRect:nsrect];
- }
-
-}
-
-#endif // QT_MAC_USE_COCOA
-
-QT_END_NAMESPACE
diff --git a/src/gui/kernel/qt_cocoa_helpers_mac_p.h b/src/gui/kernel/qt_cocoa_helpers_mac_p.h
deleted file mode 100644
index 14be29e61c..0000000000
--- a/src/gui/kernel/qt_cocoa_helpers_mac_p.h
+++ /dev/null
@@ -1,340 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/****************************************************************************
-**
-** Copyright (c) 2007-2008, Apple, Inc.
-**
-** All rights reserved.
-**
-** Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are met:
-**
-** * Redistributions of source code must retain the above copyright notice,
-** this list of conditions and the following disclaimer.
-**
-** * Redistributions in binary form must reproduce the above copyright notice,
-** this list of conditions and the following disclaimer in the documentation
-** and/or other materials provided with the distribution.
-**
-** * Neither the name of Apple, Inc. nor the names of its contributors
-** may be used to endorse or promote products derived from this software
-** without specific prior written permission.
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-**
-****************************************************************************/
-
-#ifndef QT_COCOA_HELPERS_MAC_P_H
-#define QT_COCOA_HELPERS_MAC_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of qapplication_*.cpp, qwidget*.cpp, qcolor_x11.cpp, qfiledialog.cpp
-// and many other. This header file may change from version to version
-// without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <private/qt_mac_p.h>
-
-#include <qapplication.h>
-#include <qdesktopwidget.h>
-#include <qwidget.h>
-#include <qevent.h>
-#include <qhash.h>
-#include <qlabel.h>
-#include <qpointer.h>
-#include <qstyle.h>
-#include <qstyleoption.h>
-#include <qstylepainter.h>
-#include <qtimer.h>
-#include <qtooltip.h>
-#include <private/qeffects_p.h>
-#include <private/qwidget_p.h>
-#include <qtextdocument.h>
-#include <qdebug.h>
-#include <qpoint.h>
-#include "private/qt_mac_p.h"
-
-struct HIContentBorderMetrics;
-
-#ifdef Q_WS_MAC32
-typedef struct _NSPoint NSPoint; // Just redefine here so I don't have to pull in all of Cocoa.
-#else
-typedef struct CGPoint NSPoint;
-#endif
-
-QT_BEGIN_NAMESPACE
-
-enum {
- QtCocoaEventSubTypeWakeup = SHRT_MAX,
- QtCocoaEventSubTypePostMessage = SHRT_MAX-1
-};
-
-Qt::MouseButtons qt_mac_get_buttons(int buttons);
-Qt::MouseButton qt_mac_get_button(EventMouseButton button);
-void macWindowFade(void * /*OSWindowRef*/ window, float durationSeconds = 0.15);
-bool macWindowIsTextured(void * /*OSWindowRef*/ window);
-void macWindowToolbarShow(const QWidget *widget, bool show );
-void macWindowToolbarSet( void * /*OSWindowRef*/ window, void* toolbarRef );
-bool macWindowToolbarIsVisible( void * /*OSWindowRef*/ window );
-void macWindowSetHasShadow( void * /*OSWindowRef*/ window, bool hasShadow );
-void macWindowFlush(void * /*OSWindowRef*/ window);
-void macSendToolbarChangeEvent(QWidget *widget);
-void qt_mac_updateContentBorderMetricts(void * /*OSWindowRef */window, const ::HIContentBorderMetrics &metrics);
-void qt_mac_replaceDrawRect(void * /*OSWindowRef */window, QWidgetPrivate *widget);
-void qt_mac_replaceDrawRectOriginal(void * /*OSWindowRef */window, QWidgetPrivate *widget);
-void qt_mac_showBaseLineSeparator(void * /*OSWindowRef */window, bool show);
-void * /*NSImage */qt_mac_create_nsimage(const QPixmap &pm);
-void qt_mac_update_mouseTracking(QWidget *widget);
-OSStatus qt_mac_drawCGImage(CGContextRef cg, const CGRect *inbounds, CGImageRef);
-bool qt_mac_checkForNativeSizeGrip(const QWidget *widget);
-void qt_dispatchTabletProximityEvent(void * /*NSEvent * */ tabletEvent);
-#ifdef QT_MAC_USE_COCOA
-bool qt_dispatchKeyEventWithCocoa(void * /*NSEvent * */ keyEvent, QWidget *widgetToGetEvent);
-// These methods exists only for supporting unified mode.
-void macDrawRectOnTop(void * /*OSWindowRef */ window);
-void macSyncDrawingOnFirstInvocation(void * /*OSWindowRef */window);
-void qt_cocoaStackChildWindowOnTopOfOtherChildren(QWidget *widget);
-void qt_mac_menu_collapseSeparators(void * /*NSMenu */ menu, bool collapse);
-#endif
-bool qt_dispatchKeyEvent(void * /*NSEvent * */ keyEvent, QWidget *widgetToGetEvent);
-void qt_dispatchModifiersChanged(void * /*NSEvent * */flagsChangedEvent, QWidget *widgetToGetEvent);
-bool qt_mac_handleTabletEvent(void * /*QCocoaView * */view, void * /*NSEvent * */event);
-inline QApplication *qAppInstance() { return static_cast<QApplication *>(QCoreApplication::instance()); }
-struct ::TabletProximityRec;
-void qt_dispatchTabletProximityEvent(const ::TabletProximityRec &proxRec);
-Qt::KeyboardModifiers qt_cocoaModifiers2QtModifiers(ulong modifierFlags);
-Qt::KeyboardModifiers qt_cocoaDragOperation2QtModifiers(uint dragOperations);
-QPixmap qt_mac_convert_iconref(const IconRef icon, int width, int height);
-void qt_mac_constructQIconFromIconRef(const IconRef icon, const IconRef overlayIcon, QIcon *retIcon,
- QStyle::StandardPixmap standardIcon = QStyle::SP_CustomBase);
-
-#if QT_MAC_USE_COCOA && __OBJC__
-struct DnDParams
-{
- NSView *view;
- NSEvent *theEvent;
- QPoint globalPoint;
- NSDragOperation performedAction;
-};
-
-DnDParams *macCurrentDnDParameters();
-NSDragOperation qt_mac_mapDropAction(Qt::DropAction action);
-NSDragOperation qt_mac_mapDropActions(Qt::DropActions actions);
-Qt::DropAction qt_mac_mapNSDragOperation(NSDragOperation nsActions);
-Qt::DropActions qt_mac_mapNSDragOperations(NSDragOperation nsActions);
-
-QWidget *qt_mac_getTargetForKeyEvent(QWidget *widgetThatReceivedEvent);
-QWidget *qt_mac_getTargetForMouseEvent(NSEvent *event, QEvent::Type eventType,
- QPoint &returnLocalPoint, QPoint &returnGlobalPoint, QWidget *nativeWidget, QWidget **returnWidgetUnderMouse);
-bool qt_mac_handleMouseEvent(NSEvent *event, QEvent::Type eventType, Qt::MouseButton button, QWidget *nativeWidget);
-void qt_mac_handleNonClientAreaMouseEvent(NSWindow *window, NSEvent *event);
-#endif
-
-inline int flipYCoordinate(int y)
-{
- return QApplication::desktop()->screenGeometry(0).height() - y;
-}
-
-inline qreal flipYCoordinate(qreal y)
-{
- return QApplication::desktop()->screenGeometry(0).height() - y;
-}
-
-QPointF flipPoint(const NSPoint &p);
-NSPoint flipPoint(const QPoint &p);
-NSPoint flipPoint(const QPointF &p);
-
-QStringList qt_mac_NSArrayToQStringList(void *nsarray);
-void *qt_mac_QStringListToNSMutableArrayVoid(const QStringList &list);
-
-void qt_syncCocoaTitleBarButtons(OSWindowRef window, QWidget *widgetForWindow);
-
-CGFloat qt_mac_get_scalefactor();
-QString qt_mac_get_pasteboardString(OSPasteboardRef paste);
-
-#ifdef __OBJC__
-inline NSMutableArray *qt_mac_QStringListToNSMutableArray(const QStringList &qstrlist)
-{ return reinterpret_cast<NSMutableArray *>(qt_mac_QStringListToNSMutableArrayVoid(qstrlist)); }
-
-inline QString qt_mac_NSStringToQString(const NSString *nsstr)
-{ return QCFString::toQString(reinterpret_cast<const CFStringRef>(nsstr)); }
-
-inline NSString *qt_mac_QStringToNSString(const QString &qstr)
-{ return [reinterpret_cast<const NSString *>(QCFString::toCFStringRef(qstr)) autorelease]; }
-
-#ifdef QT_MAC_USE_COCOA
-class QCocoaPostMessageArgs {
-public:
- id target;
- SEL selector;
- int argCount;
- id arg1;
- id arg2;
- QCocoaPostMessageArgs(id target, SEL selector, int argCount=0, id arg1=0, id arg2=0)
- : target(target), selector(selector), argCount(argCount), arg1(arg1), arg2(arg2)
- {
- [target retain];
- [arg1 retain];
- [arg2 retain];
- }
-
- ~QCocoaPostMessageArgs()
- {
- [arg2 release];
- [arg1 release];
- [target release];
- }
-};
-void qt_cocoaPostMessage(id target, SEL selector, int argCount=0, id arg1=0, id arg2=0);
-void qt_cocoaPostMessageAfterEventLoopExit(id target, SEL selector, int argCount=0, id arg1=0, id arg2=0);
-#endif
-
-#endif
-
-class QMacScrollOptimization {
- // This class is made to optimize for the case when the user
- // scrolls both horizontally and vertically at the same
- // time. This will result in two QWheelEvents (one for each
- // direction), which will typically result in two calls to
- // QWidget::_scroll_sys. Rather than copying pixels twize on
- // screen because of this, we add this helper class to try to
- // get away with only one blit.
- static QWidgetPrivate *_target;
- static bool _inWheelEvent;
- static int _dx;
- static int _dy;
- static QRect _scrollRect;
-
-public:
- static void initDelayedScroll()
- {
- _inWheelEvent = true;
- }
-
- static bool delayScroll(QWidgetPrivate *target, int dx, int dy, const QRect &scrollRect)
- {
- if (!_inWheelEvent)
- return false;
- if (_target && _target != target)
- return false;
- if (_scrollRect.width() != -1 && _scrollRect != scrollRect)
- return false;
-
- _target = target;
- _dx += dx;
- _dy += dy;
- _scrollRect = scrollRect;
- return true;
- }
-
- static void performDelayedScroll()
- {
- if (!_inWheelEvent)
- return;
- _inWheelEvent = false;
- if (!_target)
- return;
-
- _target->scroll_sys(_dx, _dy, _scrollRect);
-
- _target = 0;
- _dx = 0;
- _dy = 0;
- _scrollRect = QRect(0, 0, -1, -1);
- }
-};
-
-void qt_mac_post_retranslateAppMenu();
-
-#ifdef QT_MAC_USE_COCOA
-void qt_mac_display(QWidget *widget);
-void qt_mac_setNeedsDisplay(QWidget *widget);
-void qt_mac_setNeedsDisplayInRect(QWidget *widget, QRegion region);
-#endif // QT_MAC_USE_COCOA
-
-
-// Utility functions to ease the use of Core Graphics contexts.
-
-inline void qt_mac_retain_graphics_context(CGContextRef context)
-{
- CGContextRetain(context);
- CGContextSaveGState(context);
-}
-
-inline void qt_mac_release_graphics_context(CGContextRef context)
-{
- CGContextRestoreGState(context);
- CGContextRelease(context);
-}
-
-inline void qt_mac_draw_image(CGContextRef context, CGContextRef imageContext, CGRect area, CGRect drawingArea)
-{
- CGImageRef image = CGBitmapContextCreateImage(imageContext);
- CGImageRef subImage = CGImageCreateWithImageInRect(image, area);
-
- CGContextTranslateCTM (context, 0, drawingArea.origin.y + CGRectGetMaxY(drawingArea));
- CGContextScaleCTM(context, 1, -1);
- CGContextDrawImage(context, drawingArea, subImage);
-
- CGImageRelease(subImage);
- CGImageRelease(image);
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_COCOA_HELPERS_MAC_P_H
diff --git a/src/gui/kernel/qt_gui_pch.h b/src/gui/kernel/qt_gui_pch.h
index 012d92ce8c..3cb527d0b1 100644
--- a/src/gui/kernel/qt_gui_pch.h
+++ b/src/gui/kernel/qt_gui_pch.h
@@ -52,7 +52,7 @@
#include <qglobal.h>
-#ifdef Q_WS_WIN
+#ifdef Q_OS_WIN
# define _POSIX_
# include <limits.h>
# undef _POSIX_
@@ -67,18 +67,14 @@
#include <qstringlist.h>
#include <qtextcodec.h>
-#include <qapplication.h>
+#include <qguiapplication.h>
#include <qbitmap.h>
#include <qcursor.h>
-#include <qdesktopwidget.h>
#include <qevent.h>
#include <qimage.h>
-#include <qlayout.h>
#include <qpainter.h>
#include <qpixmap.h>
-#include <qstyle.h>
#include <qtimer.h>
-#include <qwidget.h>
#include <stdlib.h>
diff --git a/src/gui/kernel/qt_mac_p.h b/src/gui/kernel/qt_mac_p.h
deleted file mode 100644
index 4625982062..0000000000
--- a/src/gui/kernel/qt_mac_p.h
+++ /dev/null
@@ -1,286 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QT_MAC_P_H
-#define QT_MAC_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qmacdefines_mac.h"
-
-#ifdef __OBJC__
-#include <Cocoa/Cocoa.h>
-#ifdef QT_MAC_USE_COCOA
-#include <objc/runtime.h>
-#endif // QT_MAC_USE_COCOA
-#endif
-
-#include <CoreServices/CoreServices.h>
-
-#include "QtCore/qglobal.h"
-#include "QtCore/qvariant.h"
-#include "QtCore/qmimedata.h"
-#include "QtCore/qpointer.h"
-#include "private/qcore_mac_p.h"
-
-
-#include "QtGui/qpainter.h"
-
-#include <Carbon/Carbon.h>
-
-QT_BEGIN_NAMESPACE
-class QWidget;
-class QDragMoveEvent;
-
-/* Event masks */
-// internal Qt types
-
- // Event class for our own Carbon events.
-#if defined(QT_NAMESPACE) && defined(QT_NAMESPACE_MAC_CRC)
-// Take the CRC we generated at configure time. This *may* result in a
-// collision with another value If that is the case, please change the value
-// here to something other than 'Cute'.
-const UInt32 kEventClassQt = QT_NAMESPACE_MAC_CRC;
-#else
-const UInt32 kEventClassQt = 'Cute';
-#endif
-
-enum {
- //AE types
- typeAEClipboardChanged = 1,
- //types
- typeQWidget = 1, /* QWidget * */
- //params
- kEventParamQWidget = 'qwid', /* typeQWidget */
- //events
- kEventQtRequestContext = 13,
- kEventQtRequestMenubarUpdate = 14,
- kEventQtRequestShowSheet = 17,
- kEventQtRequestActivate = 18,
- kEventQtRequestWindowChange = 20
-};
-
-// Simple class to manage short-lived regions
-class QMacSmartQuickDrawRegion
-{
- RgnHandle qdRgn;
- Q_DISABLE_COPY(QMacSmartQuickDrawRegion)
-public:
- explicit QMacSmartQuickDrawRegion(RgnHandle rgn) : qdRgn(rgn) {}
- ~QMacSmartQuickDrawRegion() {
- extern void qt_mac_dispose_rgn(RgnHandle); // qregion_mac.cpp
- qt_mac_dispose_rgn(qdRgn);
- }
- operator RgnHandle() {
- return qdRgn;
- }
-};
-
-// Class for chaining to gether a bunch of fades. It pretty much is only used for qmenu fading.
-class QMacWindowFader
-{
- QWidgetList m_windowsToFade;
- float m_duration;
- Q_DISABLE_COPY(QMacWindowFader)
-public:
- QMacWindowFader(); // PLEASE DON'T CALL THIS.
- static QMacWindowFader *currentFader();
- void registerWindowToFade(QWidget *window);
- void setFadeDuration(float durationInSecs) { m_duration = durationInSecs; }
- float fadeDuration() const { return m_duration; }
- void performFade();
-};
-
-class Q_GUI_EXPORT QMacCocoaAutoReleasePool
-{
-private:
- void *pool;
-public:
- QMacCocoaAutoReleasePool();
- ~QMacCocoaAutoReleasePool();
-
- inline void *handle() const { return pool; }
-};
-
-QString qt_mac_removeMnemonics(const QString &original); //implemented in qmacstyle_mac.cpp
-
-class Q_GUI_EXPORT QMacWindowChangeEvent
-{
-private:
- static QList<QMacWindowChangeEvent*> *change_events;
-public:
- QMacWindowChangeEvent() {
- }
- virtual ~QMacWindowChangeEvent() {
- }
- static inline void exec(bool ) {
- }
-protected:
- virtual void windowChanged() = 0;
- virtual void flushWindowChanged() = 0;
-};
-
-class QMacCGContext
-{
- CGContextRef context;
-public:
- QMacCGContext(QPainter *p); //qpaintengine_mac.cpp
- inline QMacCGContext() { context = 0; }
- inline QMacCGContext(const QPaintDevice *pdev) {
- extern CGContextRef qt_mac_cg_context(const QPaintDevice *);
- context = qt_mac_cg_context(pdev);
- }
- inline QMacCGContext(CGContextRef cg, bool takeOwnership=false) {
- context = cg;
- if(!takeOwnership)
- CGContextRetain(context);
- }
- inline QMacCGContext(const QMacCGContext &copy) : context(0) { *this = copy; }
- inline ~QMacCGContext() {
- if(context)
- CGContextRelease(context);
- }
- inline bool isNull() const { return context; }
- inline operator CGContextRef() { return context; }
- inline QMacCGContext &operator=(const QMacCGContext &copy) {
- if(context)
- CGContextRelease(context);
- context = copy.context;
- CGContextRetain(context);
- return *this;
- }
- inline QMacCGContext &operator=(CGContextRef cg) {
- if(context)
- CGContextRelease(context);
- context = cg;
- CGContextRetain(context); //we do not take ownership
- return *this;
- }
-};
-
-class QMacPasteboardMime;
-class QMimeData;
-
-class QMacPasteboard
-{
- struct Promise {
- Promise() : itemId(0), convertor(0) { }
- Promise(int itemId, QMacPasteboardMime *c, QString m, QVariant d, int o=0) : itemId(itemId), offset(o), convertor(c), mime(m), data(d) { }
- int itemId, offset;
- QMacPasteboardMime *convertor;
- QString mime;
- QVariant data;
- };
- QList<Promise> promises;
-
- OSPasteboardRef paste;
- uchar mime_type;
- mutable QPointer<QMimeData> mime;
- mutable bool mac_mime_source;
- static OSStatus promiseKeeper(OSPasteboardRef, PasteboardItemID, CFStringRef, void *);
- void clear_helper();
-public:
- QMacPasteboard(OSPasteboardRef p, uchar mime_type=0);
- QMacPasteboard(uchar mime_type);
- QMacPasteboard(CFStringRef name=0, uchar mime_type=0);
- ~QMacPasteboard();
-
- bool hasFlavor(QString flavor) const;
- bool hasOSType(int c_flavor) const;
-
- OSPasteboardRef pasteBoard() const;
- QMimeData *mimeData() const;
- void setMimeData(QMimeData *mime);
-
- QStringList formats() const;
- bool hasFormat(const QString &format) const;
- QVariant retrieveData(const QString &format, QVariant::Type) const;
-
- void clear();
- bool sync() const;
-};
-
-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
-#endif
-
-QFont qfontForThemeFont(ThemeFontID themeID);
-
-QColor qcolorForTheme(ThemeBrush brush);
-
-QColor qcolorForThemeTextColor(ThemeTextColor themeColor);
-
-struct QMacDndAnswerRecord {
- QRect rect;
- 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;
-void qt_mac_copy_answer_rect(const QDragMoveEvent &event);
-bool qt_mac_mouse_inside_answer_rect(QPoint mouse);
-
-QT_END_NAMESPACE
-
-#endif // QT_MAC_P_H
diff --git a/src/gui/kernel/qt_x11_p.h b/src/gui/kernel/qt_x11_p.h
deleted file mode 100644
index 1a9830d42b..0000000000
--- a/src/gui/kernel/qt_x11_p.h
+++ /dev/null
@@ -1,757 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QT_X11_P_H
-#define QT_X11_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "QtGui/qwindowdefs.h"
-#include "QtCore/qlist.h"
-#include "QtCore/qvariant.h"
-
-// the following is necessary to work around breakage in many versions
-// of XFree86's Xlib.h still in use
-// ### which versions?
-#if defined(_XLIB_H_) // crude hack, but...
-#error "cannot include <X11/Xlib.h> before this file"
-#endif
-#define XRegisterIMInstantiateCallback qt_XRegisterIMInstantiateCallback
-#define XUnregisterIMInstantiateCallback qt_XUnregisterIMInstantiateCallback
-#define XSetIMValues qt_XSetIMValues
-#include <X11/Xlib.h>
-#undef XRegisterIMInstantiateCallback
-#undef XUnregisterIMInstantiateCallback
-#undef XSetIMValues
-
-#include <X11/Xutil.h>
-#include <X11/Xos.h>
-#ifdef index
-# undef index
-#endif
-#ifdef rindex
-# undef rindex
-#endif
-#ifdef Q_OS_VXWORS
-# ifdef open
-# undef open
-# endif
-# ifdef getpid
-# undef getpid
-# endif
-#endif // Q_OS_VXWORKS
-#include <X11/Xatom.h>
-
-//#define QT_NO_SHAPE
-#ifdef QT_NO_SHAPE
-# define XShapeCombineRegion(a,b,c,d,e,f,g)
-# define XShapeCombineMask(a,b,c,d,e,f,g)
-#else
-# include <X11/extensions/shape.h>
-#endif // QT_NO_SHAPE
-
-
-#if !defined (QT_NO_TABLET)
-# include <X11/extensions/XInput.h>
-#if defined (Q_OS_IRIX)
-# include <X11/extensions/SGIMisc.h>
-# include <wacom.h>
-#endif
-#endif // QT_NO_TABLET
-
-
-// #define QT_NO_XINERAMA
-#ifndef QT_NO_XINERAMA
-# if 0 // ### Xsun, but how to detect it?
-// Xinerama is only supported in Solaris 7 with patches 107648/108376 and
-// Solaris 8 or above which introduce the X11R6.4 Xserver.
-// To switch the Xinerama functionality on, you need to add the "+xinerama"
-// argument to the Xsun start line.
-// At least Solaris 7 and 8 are missing Xinerama system headers and function
-// declarations (bug 4284701).
-// The Xinerama API is not documented. In theory it could change but it
-// probably won't because Sun are using it in at least dtlogin (bug 4221829).
-extern "C" Bool XPanoramiXQueryExtension(
- Display*,
- int*,
- int*
-);
-extern "C" Status XPanoramiXQueryVersion(
- Display*,
- int*,
- int*
-);
-extern "C" Status XPanoramiXGetState(
- Display*,
- Drawable,
- XPanoramiXInfo*
-);
-extern "C" Status XPanoramiXGetScreenCount(
- Display *,
- Drawable,
- XPanoramiXInfo*
-);
-extern "C" Status XPanoramiXGetScreenSize(
- Display*,
- Drawable,
- int,
- XPanoramiXInfo*
-);
-# else // XFree86
-// XFree86 does not C++ify Xinerama (at least up to XFree86 4.0.3).
-extern "C" {
-# include <X11/extensions/Xinerama.h>
-}
-# endif
-#endif // QT_NO_XINERAMA
-
-// #define QT_NO_XRANDR
-#ifndef QT_NO_XRANDR
-# include <X11/extensions/Xrandr.h>
-#endif // QT_NO_XRANDR
-
-// #define QT_NO_XRENDER
-#ifndef QT_NO_XRENDER
-# include <X11/extensions/Xrender.h>
-#endif // QT_NO_XRENDER
-
-#ifndef QT_NO_XSYNC
-extern "C" {
-# include "X11/extensions/sync.h"
-}
-#endif
-
-// #define QT_NO_XKB
-#ifndef QT_NO_XKB
-# include <X11/XKBlib.h>
-#endif // QT_NO_XKB
-
-
-#if !defined(XlibSpecificationRelease)
-# define X11R4
-typedef char *XPointer;
-#else
-# undef X11R4
-#endif
-
-// #define QT_NO_XIM
-#if defined(X11R4)
-// X11R4 does not have XIM
-#define QT_NO_XIM
-#elif defined(Q_OS_OSF) && (XlibSpecificationRelease < 6)
-// broken in Xlib up to OSF/1 3.2
-#define QT_NO_XIM
-#elif defined(Q_OS_AIX)
-// broken in Xlib up to what version of AIX?
-#define QT_NO_XIM
-#elif defined(QT_NO_DEBUG) && defined(Q_OS_IRIX)
-// XmbLookupString broken on IRIX
-// XCreateIC broken when compiling -64 on IRIX 6.5.2
-#define QT_NO_XIM
-#elif defined(Q_OS_HPUX) && defined(__LP64__)
-// XCreateIC broken when compiling 64-bit ELF on HP-UX 11.0
-#define QT_NO_XIM
-#elif defined(Q_OS_SCO)
-// ### suggested by user...
-// ### #define QT_NO_XIM
-#endif // QT_NO_XIM
-
-#ifndef QT_NO_XFIXES
-typedef Bool (*PtrXFixesQueryExtension)(Display *, int *, int *);
-typedef Status (*PtrXFixesQueryVersion)(Display *, int *, int *);
-typedef void (*PtrXFixesSetCursorName)(Display *dpy, Cursor cursor, const char *name);
-typedef void (*PtrXFixesSelectSelectionInput)(Display *dpy, Window win, Atom selection, unsigned long eventMask);
-#endif // QT_NO_XFIXES
-
-#ifndef QT_NO_XCURSOR
-#include <X11/Xcursor/Xcursor.h>
-typedef Cursor (*PtrXcursorLibraryLoadCursor)(Display *, const char *);
-#endif // QT_NO_XCURSOR
-
-#ifndef QT_NO_XINERAMA
-typedef Bool (*PtrXineramaQueryExtension)(Display *dpy, int *event_base, int *error_base);
-typedef Bool (*PtrXineramaIsActive)(Display *dpy);
-typedef XineramaScreenInfo *(*PtrXineramaQueryScreens)(Display *dpy, int *number);
-#endif // QT_NO_XINERAMA
-
-#ifndef QT_NO_XRANDR
-typedef void (*PtrXRRSelectInput)(Display *, Window, int);
-typedef int (*PtrXRRUpdateConfiguration)(XEvent *);
-typedef int (*PtrXRRRootToScreen)(Display *, Window);
-typedef Bool (*PtrXRRQueryExtension)(Display *, int *, int *);
-typedef XRRScreenSize *(*PtrXRRSizes)(Display *, int, int *);
-#endif // QT_NO_XRANDR
-
-#ifndef QT_NO_XINPUT
-typedef int (*PtrXCloseDevice)(Display *, XDevice *);
-typedef XDeviceInfo* (*PtrXListInputDevices)(Display *, int *);
-typedef XDevice* (*PtrXOpenDevice)(Display *, XID);
-typedef void (*PtrXFreeDeviceList)(XDeviceInfo *);
-typedef int (*PtrXSelectExtensionEvent)(Display *, Window, XEventClass *, int);
-#endif // QT_NO_XINPUT
-
-/*
- * Solaris patch 108652-47 and higher fixes crases in
- * XRegisterIMInstantiateCallback, but the function doesn't seem to
- * work.
- *
- * Instead, we disabled R6 input, and open the input method
- * immediately at application start.
- */
-#if !defined(QT_NO_XIM) && (XlibSpecificationRelease >= 6) && \
- !defined(Q_OS_SOLARIS)
-#define USE_X11R6_XIM
-
-//######### XFree86 has wrong declarations for XRegisterIMInstantiateCallback
-//######### and XUnregisterIMInstantiateCallback in at least version 3.3.2.
-//######### Many old X11R6 header files lack XSetIMValues.
-//######### Therefore, we have to declare these functions ourselves.
-
-extern "C" Bool XRegisterIMInstantiateCallback(
- Display*,
- struct _XrmHashBucketRec*,
- char*,
- char*,
- XIMProc, //XFree86 has XIDProc, which has to be wrong
- XPointer
-);
-
-extern "C" Bool XUnregisterIMInstantiateCallback(
- Display*,
- struct _XrmHashBucketRec*,
- char*,
- char*,
- XIMProc, //XFree86 has XIDProc, which has to be wrong
- XPointer
-);
-
-extern "C" char *XSetIMValues(XIM /* im */, ...);
-
-#endif
-
-#ifndef QT_NO_FONTCONFIG
-#include <fontconfig/fontconfig.h>
-#endif
-
-#ifndef QT_NO_XIM
-// some platforms (eg. Solaris 2.51) don't have these defines in Xlib.h
-#ifndef XNResetState
-#define XNResetState "resetState"
-#endif
-#ifndef XIMPreserveState
-#define XIMPreserveState (1L<<1)
-#endif
-#endif
-
-
-#ifndef X11R4
-# include <X11/Xlocale.h>
-#endif // X11R4
-
-
-#ifndef QT_NO_MITSHM
-# include <X11/extensions/XShm.h>
-#endif // QT_NO_MITSHM
-
-QT_BEGIN_NAMESPACE
-
-class QWidget;
-
-struct QX11InfoData {
- uint ref;
- int screen;
- int dpiX;
- int dpiY;
- int depth;
- int cells;
- Colormap colormap;
- Visual *visual;
- bool defaultColormap;
- bool defaultVisual;
- int subpixel;
-};
-
-class QDrag;
-struct QXdndDropTransaction
-{
- Time timestamp;
- Window target;
- Window proxy_target;
- QWidget *targetWidget;
- QWidget *embedding_widget;
- QDrag *object;
-};
-
-class QMimeData;
-
-struct QX11Data;
-extern Q_GUI_EXPORT QX11Data *qt_x11Data;
-
-enum DesktopEnvironment {
- DE_UNKNOWN,
- DE_KDE,
- DE_GNOME,
- DE_CDE,
- DE_MEEGO_COMPOSITOR,
- DE_4DWM
-};
-
-struct QX11Data
-{
- static Qt::KeyboardModifiers translateModifiers(int s);
-
- Window findClientWindow(Window, Atom, bool);
-
- // from qclipboard_x11.cpp
- bool clipboardWaitForEvent(Window win, int type, XEvent *event, int timeout);
- bool clipboardReadProperty(Window win, Atom property, bool deleteProperty,
- QByteArray *buffer, int *size, Atom *type, int *format);
- QByteArray clipboardReadIncrementalProperty(Window win, Atom property, int nbytes, bool nullterm);
-
- // from qdnd_x11.cpp
- bool dndEnable(QWidget* w, bool on);
- static void xdndSetup();
- void xdndHandleEnter(QWidget *, const XEvent *, bool);
- void xdndHandlePosition(QWidget *, const XEvent *, bool);
- void xdndHandleStatus(QWidget *, const XEvent *, bool);
- void xdndHandleLeave(QWidget *, const XEvent *, bool);
- void xdndHandleDrop(QWidget *, const XEvent *, bool);
- void xdndHandleFinished(QWidget *, const XEvent *, bool);
- void xdndHandleSelectionRequest(const XSelectionRequestEvent *);
- static bool xdndHandleBadwindow();
- QByteArray xdndAtomToString(Atom a);
- Atom xdndStringToAtom(const char *);
-
- QString xdndMimeAtomToString(Atom a);
- Atom xdndMimeStringToAtom(const QString &mimeType);
- QStringList xdndMimeFormatsForAtom(Atom a);
- bool xdndMimeDataForAtom(Atom a, QMimeData *mimeData, QByteArray *data, Atom *atomFormat, int *dataFormat);
- QList<Atom> xdndMimeAtomsForFormat(const QString &format);
- QVariant xdndMimeConvertToFormat(Atom a, const QByteArray &data, const QString &format, QVariant::Type requestedType, const QByteArray &encoding);
- Atom xdndMimeAtomForFormat(const QString &format, QVariant::Type requestedType, const QList<Atom> &atoms, QByteArray *requestedEncoding);
-
- QList<QXdndDropTransaction> dndDropTransactions;
-
- // from qmotifdnd_x11.cpp
- void motifdndHandle(QWidget *, const XEvent *, bool);
- void motifdndEnable(QWidget *, bool);
- QVariant motifdndObtainData(const char *format);
- QByteArray motifdndFormat(int n);
- bool motifdnd_active;
-
- Display *display;
- char *displayName;
- bool foreignDisplay;
- // current focus model
- enum {
- FM_Unknown = -1,
- FM_Other = 0,
- FM_PointerRoot = 1
- };
- int focus_model;
-
- // true if Qt is compiled w/ RANDR support and RANDR is supported on the connected Display
- bool use_xrandr;
- int xrandr_major;
- int xrandr_eventbase;
- int xrandr_errorbase;
-
- // true if Qt is compiled w/ RENDER support and RENDER is supported on the connected Display
- bool use_xrender;
- int xrender_major;
- int xrender_version;
-
- // true if Qt is compiled w/ XFIXES support and XFIXES is supported on the connected Display
- bool use_xfixes;
- int xfixes_major;
- int xfixes_eventbase;
- int xfixes_errorbase;
-
-#ifndef QT_NO_XFIXES
- PtrXFixesQueryExtension ptrXFixesQueryExtension;
- PtrXFixesQueryVersion ptrXFixesQueryVersion;
- PtrXFixesSetCursorName ptrXFixesSetCursorName;
- PtrXFixesSelectSelectionInput ptrXFixesSelectSelectionInput;
-#endif
-
-#ifndef QT_NO_XINPUT
- PtrXCloseDevice ptrXCloseDevice;
- PtrXListInputDevices ptrXListInputDevices;
- PtrXOpenDevice ptrXOpenDevice;
- PtrXFreeDeviceList ptrXFreeDeviceList;
- PtrXSelectExtensionEvent ptrXSelectExtensionEvent;
-#endif // QT_NO_XINPUT
-
-
- // true if Qt is compiled w/ MIT-SHM support and MIT-SHM is supported on the connected Display
- bool use_mitshm;
- bool use_mitshm_pixmaps;
- int mitshm_major;
-
- // true if Qt is compiled w/ Tablet support and we have a tablet.
- bool use_xinput;
- int xinput_major;
- int xinput_eventbase;
- int xinput_errorbase;
-
- // for XKEYBOARD support
- bool use_xkb;
- int xkb_major;
- int xkb_eventbase;
- int xkb_errorbase;
-
- QList<QWidget *> deferred_map;
- struct ScrollInProgress {
- long id;
- QWidget* scrolled_widget;
- int dx, dy;
- };
- long sip_serial;
- QList<ScrollInProgress> sip_list;
-
- // window managers list of supported "stuff"
- Atom *net_supported_list;
- // list of virtual root windows
- Window *net_virtual_root_list;
- // client leader window
- Window wm_client_leader;
-
- QX11InfoData *screens;
- Visual **argbVisuals;
- Colormap *argbColormaps;
- int screenCount;
- int defaultScreen;
-
- Time time;
- Time userTime;
-
- QString default_im;
-
- // starts to ignore bad window errors from X
- static inline void ignoreBadwindow() {
- qt_x11Data->ignore_badwindow = true;
- qt_x11Data->seen_badwindow = false;
- }
-
- // ends ignoring bad window errors and returns whether an error had happened.
- static inline bool badwindow() {
- qt_x11Data->ignore_badwindow = false;
- return qt_x11Data->seen_badwindow;
- }
-
- bool ignore_badwindow;
- bool seen_badwindow;
-
- // options
- int visual_class;
- int visual_id;
- int color_count;
- bool custom_cmap;
-
- // outside visual/colormap
- Visual *visual;
- Colormap colormap;
-
-#ifndef QT_NO_XRENDER
- enum { solid_fill_count = 16 };
- struct SolidFills {
- XRenderColor color;
- int screen;
- Picture picture;
- } solid_fills[solid_fill_count];
- enum { pattern_fill_count = 16 };
- struct PatternFills {
- XRenderColor color;
- XRenderColor bg_color;
- int screen;
- int style;
- bool opaque;
- Picture picture;
- } pattern_fills[pattern_fill_count];
- Picture getSolidFill(int screen, const QColor &c);
- XRenderColor preMultiply(const QColor &c);
-#endif
-
- bool has_fontconfig;
- qreal fc_scale;
- bool fc_antialias;
- int fc_hint_style;
-
- char *startupId;
-
- DesktopEnvironment desktopEnvironment : 8;
- uint desktopVersion : 8; /* Used only for KDE */
-
- /* Warning: if you modify this list, modify the names of atoms in qapplication_x11.cpp as well! */
- enum X11Atom {
- // window-manager <-> client protocols
- WM_PROTOCOLS,
- WM_DELETE_WINDOW,
- WM_TAKE_FOCUS,
- _NET_WM_PING,
- _NET_WM_CONTEXT_HELP,
- _NET_WM_SYNC_REQUEST,
- _NET_WM_SYNC_REQUEST_COUNTER,
-
- // ICCCM window state
- WM_STATE,
- WM_CHANGE_STATE,
-
- // Session management
- WM_CLIENT_LEADER,
- WM_WINDOW_ROLE,
- SM_CLIENT_ID,
-
- // Clipboard
- CLIPBOARD,
- INCR,
- TARGETS,
- MULTIPLE,
- TIMESTAMP,
- SAVE_TARGETS,
- CLIP_TEMPORARY,
- _QT_SELECTION,
- _QT_CLIPBOARD_SENTINEL,
- _QT_SELECTION_SENTINEL,
- CLIPBOARD_MANAGER,
-
- RESOURCE_MANAGER,
-
- _XSETROOT_ID,
-
- _QT_SCROLL_DONE,
- _QT_INPUT_ENCODING,
-
- _MOTIF_WM_HINTS,
-
- DTWM_IS_RUNNING,
- ENLIGHTENMENT_DESKTOP,
- _DT_SAVE_MODE,
- _SGI_DESKS_MANAGER,
-
- // EWMH (aka NETWM)
- _NET_SUPPORTED,
- _NET_VIRTUAL_ROOTS,
- _NET_WORKAREA,
-
- _NET_MOVERESIZE_WINDOW,
- _NET_WM_MOVERESIZE,
-
- _NET_WM_NAME,
- _NET_WM_ICON_NAME,
- _NET_WM_ICON,
-
- _NET_WM_PID,
-
- _NET_WM_WINDOW_OPACITY,
-
- _NET_WM_STATE,
- _NET_WM_STATE_ABOVE,
- _NET_WM_STATE_BELOW,
- _NET_WM_STATE_FULLSCREEN,
- _NET_WM_STATE_MAXIMIZED_HORZ,
- _NET_WM_STATE_MAXIMIZED_VERT,
- _NET_WM_STATE_MODAL,
- _NET_WM_STATE_STAYS_ON_TOP,
- _NET_WM_STATE_DEMANDS_ATTENTION,
-
- _NET_WM_USER_TIME,
- _NET_WM_USER_TIME_WINDOW,
- _NET_WM_FULL_PLACEMENT,
-
- _NET_WM_WINDOW_TYPE,
- _NET_WM_WINDOW_TYPE_DESKTOP,
- _NET_WM_WINDOW_TYPE_DOCK,
- _NET_WM_WINDOW_TYPE_TOOLBAR,
- _NET_WM_WINDOW_TYPE_MENU,
- _NET_WM_WINDOW_TYPE_UTILITY,
- _NET_WM_WINDOW_TYPE_SPLASH,
- _NET_WM_WINDOW_TYPE_DIALOG,
- _NET_WM_WINDOW_TYPE_DROPDOWN_MENU,
- _NET_WM_WINDOW_TYPE_POPUP_MENU,
- _NET_WM_WINDOW_TYPE_TOOLTIP,
- _NET_WM_WINDOW_TYPE_NOTIFICATION,
- _NET_WM_WINDOW_TYPE_COMBO,
- _NET_WM_WINDOW_TYPE_DND,
- _NET_WM_WINDOW_TYPE_NORMAL,
- _KDE_NET_WM_WINDOW_TYPE_OVERRIDE,
-
- _KDE_NET_WM_FRAME_STRUT,
-
- _NET_STARTUP_INFO,
- _NET_STARTUP_INFO_BEGIN,
-
- _NET_SUPPORTING_WM_CHECK,
-
- _NET_WM_CM_S0,
-
- _NET_SYSTEM_TRAY_VISUAL,
-
- _NET_ACTIVE_WINDOW,
-
- // Property formats
- COMPOUND_TEXT,
- TEXT,
- UTF8_STRING,
-
- // Xdnd
- XdndEnter,
- XdndPosition,
- XdndStatus,
- XdndLeave,
- XdndDrop,
- XdndFinished,
- XdndTypelist,
- XdndActionList,
-
- XdndSelection,
-
- XdndAware,
- XdndProxy,
-
- XdndActionCopy,
- XdndActionLink,
- XdndActionMove,
- XdndActionPrivate,
-
- // Motif DND
- _MOTIF_DRAG_AND_DROP_MESSAGE,
- _MOTIF_DRAG_INITIATOR_INFO,
- _MOTIF_DRAG_RECEIVER_INFO,
- _MOTIF_DRAG_WINDOW,
- _MOTIF_DRAG_TARGETS,
-
- XmTRANSFER_SUCCESS,
- XmTRANSFER_FAILURE,
-
- // Xkb
- _XKB_RULES_NAMES,
-
- // XEMBED
- _XEMBED,
- _XEMBED_INFO,
-
- XWacomStylus,
- XWacomCursor,
- XWacomEraser,
-
- XTabletStylus,
- XTabletEraser,
-
- NPredefinedAtoms,
-
- _QT_SETTINGS_TIMESTAMP = NPredefinedAtoms,
- NAtoms
- };
- Atom atoms[NAtoms];
-
- bool isSupportedByWM(Atom atom);
-
- bool compositingManagerRunning;
-
-#ifndef QT_NO_XCURSOR
- PtrXcursorLibraryLoadCursor ptrXcursorLibraryLoadCursor;
-#endif // QT_NO_XCURSOR
-
-#ifndef QT_NO_XINERAMA
- PtrXineramaQueryExtension ptrXineramaQueryExtension;
- PtrXineramaIsActive ptrXineramaIsActive;
- PtrXineramaQueryScreens ptrXineramaQueryScreens;
-#endif // QT_NO_XINERAMA
-
-#ifndef QT_NO_XRANDR
- PtrXRRSelectInput ptrXRRSelectInput;
- PtrXRRUpdateConfiguration ptrXRRUpdateConfiguration;
- PtrXRRRootToScreen ptrXRRRootToScreen;
- PtrXRRQueryExtension ptrXRRQueryExtension;
- PtrXRRSizes ptrXRRSizes;
-#endif // QT_NO_XRANDR
-};
-
-extern QX11Data *qt_x11Data;
-#define ATOM(x) qt_x11Data->atoms[QX11Data::x]
-#define X11 qt_x11Data
-
-// rename a couple of X defines to get rid of name clashes
-// resolve the conflict between X11's FocusIn and QEvent::FocusIn
-enum {
- XFocusOut = FocusOut,
- XFocusIn = FocusIn,
- XKeyPress = KeyPress,
- XKeyRelease = KeyRelease,
- XNone = None,
- XRevertToParent = RevertToParent,
- XGrayScale = GrayScale,
- XCursorShape = CursorShape
-};
-#undef FocusOut
-#undef FocusIn
-#undef KeyPress
-#undef KeyRelease
-#undef None
-#undef RevertToParent
-#undef GrayScale
-#undef CursorShape
-
-#ifdef FontChange
-#undef FontChange
-#endif
-
-Q_DECLARE_TYPEINFO(XPoint, Q_PRIMITIVE_TYPE);
-Q_DECLARE_TYPEINFO(XRectangle, Q_PRIMITIVE_TYPE);
-Q_DECLARE_TYPEINFO(XChar2b, Q_PRIMITIVE_TYPE);
-#ifndef QT_NO_XRENDER
-Q_DECLARE_TYPEINFO(XGlyphElt32, Q_PRIMITIVE_TYPE);
-#endif
-
-
-QT_END_NAMESPACE
-
-#endif // QT_X11_P_H
diff --git a/src/gui/kernel/qtooltip.h b/src/gui/kernel/qtooltip.h
deleted file mode 100644
index 7c49711a1c..0000000000
--- a/src/gui/kernel/qtooltip.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QTOOLTIP_H
-#define QTOOLTIP_H
-
-#include <QtGui/qwidget.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_TOOLTIP
-
-class Q_GUI_EXPORT QToolTip
-{
- QToolTip();
-public:
- static void showText(const QPoint &pos, const QString &text, QWidget *w = 0);
- static void showText(const QPoint &pos, const QString &text, QWidget *w, const QRect &rect);
- static inline void hideText() { showText(QPoint(), QString()); }
-
- static bool isVisible();
- static QString text();
-
- static QPalette palette();
- static void setPalette(const QPalette &);
- static QFont font();
- static void setFont(const QFont &);
-#ifdef QT3_SUPPORT
- static inline QT3_SUPPORT void add(QWidget *w, const QString &s) { w->setToolTip(s); }
- static inline QT3_SUPPORT void add(QWidget *w, const QRect &, const QString &s)
- { w->setToolTip(s); }
- static inline QT3_SUPPORT void remove(QWidget *w) { w->setToolTip(QString()); }
-#endif
-};
-
-#endif // QT_NO_TOOLTIP
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QTOOLTIP_H
diff --git a/src/gui/kernel/qwhatsthis.cpp b/src/gui/kernel/qwhatsthis.cpp
deleted file mode 100644
index 5328cb1fd1..0000000000
--- a/src/gui/kernel/qwhatsthis.cpp
+++ /dev/null
@@ -1,777 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qwhatsthis.h"
-#ifndef QT_NO_WHATSTHIS
-#include "qpointer.h"
-#include "qapplication.h"
-#include "qdesktopwidget.h"
-#include "qevent.h"
-#include "qpixmap.h"
-#include "qpainter.h"
-#include "qtimer.h"
-#include "qhash.h"
-#include "qaction.h"
-#include "qcursor.h"
-#include "qbitmap.h"
-#include "qtextdocument.h"
-#include "../text/qtextdocumentlayout_p.h"
-#include "qtoolbutton.h"
-#include "qdebug.h"
-#ifndef QT_NO_ACCESSIBILITY
-#include "qaccessible.h"
-#endif
-#if defined(Q_WS_WIN)
-#include "qt_windows.h"
-#ifndef SPI_GETDROPSHADOW
-#define SPI_GETDROPSHADOW 0x1024
-#endif
-#endif
-#if defined(Q_WS_X11)
-#include "qx11info_x11.h"
-#include <qwidget.h>
-#endif
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \class QWhatsThis
- \brief The QWhatsThis class provides a simple description of any
- widget, i.e. answering the question "What's This?".
-
- \ingroup helpsystem
-
-
- "What's This?" help is part of an application's online help
- system, and provides users with information about the
- functionality and usage of a particular widget. "What's This?"
- help texts are typically longer and more detailed than \link
- QToolTip tooltips\endlink, but generally provide less information
- than that supplied by separate help windows.
-
- QWhatsThis provides a single window with an explanatory text that
- pops up when the user asks "What's This?". The default way for
- users to ask the question is to move the focus to the relevant
- widget and press Shift+F1. The help text appears immediately; it
- goes away as soon as the user does something else.
- (Note that if there is a shortcut for Shift+F1, this mechanism
- will not work.) Some dialogs provide a "?" button that users can
- click to enter "What's This?" mode; they then click the relevant
- widget to pop up the "What's This?" window. It is also possible to
- provide a a menu option or toolbar button to switch into "What's
- This?" mode.
-
- To add "What's This?" text to a widget or an action, you simply
- call QWidget::setWhatsThis() or QAction::setWhatsThis().
-
- The text can be either rich text or plain text. If you specify a
- rich text formatted string, it will be rendered using the default
- stylesheet, making it possible to embed images in the displayed
- text. To be as fast as possible, the default stylesheet uses a
- simple method to determine whether the text can be rendered as
- plain text. See Qt::mightBeRichText() for details.
-
- \snippet doc/src/snippets/whatsthis/whatsthis.cpp 0
-
- An alternative way to enter "What's This?" mode is to call
- createAction(), and add the returned QAction to either a menu or
- a tool bar. By invoking this context help action (in the picture
- below, the button with the arrow and question mark icon) the user
- switches into "What's This?" mode. If they now click on a widget
- the appropriate help text is shown. The mode is left when help is
- given or when the user presses Esc.
-
- \img whatsthis.png
-
- You can enter "What's This?" mode programmatically with
- enterWhatsThisMode(), check the mode with inWhatsThisMode(), and
- return to normal mode with leaveWhatsThisMode().
-
- If you want to control the "What's This?" behavior of a widget
- manually see Qt::WA_CustomWhatsThis.
-
- It is also possible to show different help texts for different
- regions of a widget, by using a QHelpEvent of type
- QEvent::WhatsThis. Intercept the help event in your widget's
- QWidget::event() function and call QWhatsThis::showText() with the
- text you want to display for the position specified in
- QHelpEvent::pos(). If the text is rich text and the user clicks
- on a link, the widget also receives a QWhatsThisClickedEvent with
- the link's reference as QWhatsThisClickedEvent::href(). If a
- QWhatsThisClickedEvent is handled (i.e. QWidget::event() returns
- true), the help window remains visible. Call
- QWhatsThis::hideText() to hide it explicitly.
-
- \sa QToolTip
-*/
-
-Q_CORE_EXPORT void qDeleteInEventHandler(QObject *o);
-
-class QWhatsThat : public QWidget
-{
- Q_OBJECT
-
-public:
- QWhatsThat(const QString& txt, QWidget* parent, QWidget *showTextFor);
- ~QWhatsThat() ;
-
- static QWhatsThat *instance;
-
-protected:
- void showEvent(QShowEvent *e);
- void mousePressEvent(QMouseEvent*);
- void mouseReleaseEvent(QMouseEvent*);
- void mouseMoveEvent(QMouseEvent*);
- void keyPressEvent(QKeyEvent*);
- void paintEvent(QPaintEvent*);
-
-private:
- QPointer<QWidget>widget;
- bool pressed;
- QString text;
- QTextDocument* doc;
- QString anchor;
- QPixmap background;
-};
-
-QWhatsThat *QWhatsThat::instance = 0;
-
-// shadowWidth not const, for XP drop-shadow-fu turns it to 0
-static int shadowWidth = 6; // also used as '5' and '6' and even '8' below
-static const int vMargin = 8;
-static const int hMargin = 12;
-
-QWhatsThat::QWhatsThat(const QString& txt, QWidget* parent, QWidget *showTextFor)
- : QWidget(parent, Qt::Popup),
- widget(showTextFor), pressed(false), text(txt)
-{
- delete instance;
- instance = this;
- setAttribute(Qt::WA_DeleteOnClose, true);
- setAttribute(Qt::WA_NoSystemBackground, true);
- if (parent)
- setPalette(parent->palette());
- setMouseTracking(true);
- setFocusPolicy(Qt::StrongFocus);
-#ifndef QT_NO_CURSOR
- setCursor(Qt::ArrowCursor);
-#endif
- QRect r;
- doc = 0;
- ensurePolished(); // Ensures style sheet font before size calc
- if (Qt::mightBeRichText(text)) {
- doc = new QTextDocument();
- doc->setUndoRedoEnabled(false);
- doc->setDefaultFont(QApplication::font(this));
-#ifdef QT_NO_TEXTHTMLPARSER
- doc->setPlainText(text);
-#else
- doc->setHtml(text);
-#endif
- doc->setUndoRedoEnabled(false);
- doc->adjustSize();
- r.setTop(0);
- r.setLeft(0);
- r.setSize(doc->size().toSize());
- }
- else
- {
- int sw = QApplication::desktop()->width() / 3;
- if (sw < 200)
- sw = 200;
- else if (sw > 300)
- sw = 300;
-
- r = fontMetrics().boundingRect(0, 0, sw, 1000,
- Qt::AlignLeft + Qt::AlignTop
- + Qt::TextWordWrap + Qt::TextExpandTabs,
- text);
- }
-#if defined(Q_WS_WIN)
- if ((QSysInfo::WindowsVersion >= QSysInfo::WV_XP
- && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based))
- {
- BOOL shadow;
- SystemParametersInfo(SPI_GETDROPSHADOW, 0, &shadow, 0);
- shadowWidth = shadow ? 0 : 6;
- }
-#endif
- resize(r.width() + 2*hMargin + shadowWidth, r.height() + 2*vMargin + shadowWidth);
-}
-
-QWhatsThat::~QWhatsThat()
-{
- instance = 0;
- if (doc)
- delete doc;
-}
-
-void QWhatsThat::showEvent(QShowEvent *)
-{
- background = QPixmap::grabWindow(QApplication::desktop()->internalWinId(),
- x(), y(), width(), height());
-}
-
-void QWhatsThat::mousePressEvent(QMouseEvent* e)
-{
- pressed = true;
- if (e->button() == Qt::LeftButton && rect().contains(e->pos())) {
- if (doc)
- anchor = doc->documentLayout()->anchorAt(e->pos() - QPoint(hMargin, vMargin));
- return;
- }
- close();
-}
-
-void QWhatsThat::mouseReleaseEvent(QMouseEvent* e)
-{
- if (!pressed)
- return;
- if (widget && e->button() == Qt::LeftButton && doc && rect().contains(e->pos())) {
- QString a = doc->documentLayout()->anchorAt(e->pos() - QPoint(hMargin, vMargin));
- QString href;
- if (anchor == a)
- href = a;
- anchor.clear();
- if (!href.isEmpty()) {
- QWhatsThisClickedEvent e(href);
- if (QApplication::sendEvent(widget, &e))
- return;
- }
- }
- close();
-}
-
-void QWhatsThat::mouseMoveEvent(QMouseEvent* e)
-{
-#ifdef QT_NO_CURSOR
- Q_UNUSED(e);
-#else
- if (!doc)
- return;
- QString a = doc->documentLayout()->anchorAt(e->pos() - QPoint(hMargin, vMargin));
- if (!a.isEmpty())
- setCursor(Qt::PointingHandCursor);
- else
- setCursor(Qt::ArrowCursor);
-#endif
-}
-
-void QWhatsThat::keyPressEvent(QKeyEvent*)
-{
- close();
-}
-
-void QWhatsThat::paintEvent(QPaintEvent*)
-{
- bool drawShadow = true;
-#if defined(Q_WS_WIN)
- if ((QSysInfo::WindowsVersion >= QSysInfo::WV_XP
- && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based))
- {
- BOOL shadow;
- SystemParametersInfo(SPI_GETDROPSHADOW, 0, &shadow, 0);
- drawShadow = !shadow;
- }
-#elif defined(Q_WS_MAC) || defined(Q_WS_QWS)
- drawShadow = false; // never draw it on OS X or QWS, as we get it for free
-#endif
-
- QRect r = rect();
- r.adjust(0, 0, -1, -1);
- if (drawShadow)
- r.adjust(0, 0, -shadowWidth, -shadowWidth);
- QPainter p(this);
- p.drawPixmap(0, 0, background);
- p.setPen(QPen(palette().toolTipText(), 0));
- p.setBrush(palette().toolTipBase());
- p.drawRect(r);
- int w = r.width();
- int h = r.height();
- p.setPen(palette().brush(QPalette::Dark).color());
- p.drawRect(1, 1, w-2, h-2);
- if (drawShadow) {
- p.setPen(palette().shadow().color());
- p.drawPoint(w + 5, 6);
- p.drawLine(w + 3, 6, w + 5, 8);
- p.drawLine(w + 1, 6, w + 5, 10);
- int i;
- for(i=7; i < h; i += 2)
- p.drawLine(w, i, w + 5, i + 5);
- for(i = w - i + h; i > 6; i -= 2)
- p.drawLine(i, h, i + 5, h + 5);
- for(; i > 0 ; i -= 2)
- p.drawLine(6, h + 6 - i, i + 5, h + 5);
- }
- r.adjust(0, 0, 1, 1);
- p.setPen(palette().toolTipText().color());
- r.adjust(hMargin, vMargin, -hMargin, -vMargin);
-
- if (doc) {
- p.translate(r.x(), r.y());
- QRect rect = r;
- rect.translate(-r.x(), -r.y());
- p.setClipRect(rect);
- QAbstractTextDocumentLayout::PaintContext context;
- context.palette.setBrush(QPalette::Text, context.palette.toolTipText());
- doc->documentLayout()->draw(&p, context);
- }
- else
- {
- p.drawText(r, Qt::AlignLeft + Qt::AlignTop + Qt::TextWordWrap + Qt::TextExpandTabs, text);
- }
-}
-
-static const char * const button_image[] = {
-"16 16 3 1",
-" c None",
-"o c #000000",
-"a c #000080",
-"o aaaaa ",
-"oo aaa aaa ",
-"ooo aaa aaa",
-"oooo aa aa",
-"ooooo aa aa",
-"oooooo a aaa",
-"ooooooo aaa ",
-"oooooooo aaa ",
-"ooooooooo aaa ",
-"ooooo aaa ",
-"oo ooo ",
-"o ooo aaa ",
-" ooo aaa ",
-" ooo ",
-" ooo ",
-" ooo "};
-
-class QWhatsThisPrivate : public QObject
-{
- public:
- QWhatsThisPrivate();
- ~QWhatsThisPrivate();
- static QWhatsThisPrivate *instance;
- bool eventFilter(QObject *, QEvent *);
- QPointer<QAction> action;
-#ifdef QT3_SUPPORT
- QPointer<QToolButton> button;
-#endif
- static void say(QWidget *, const QString &, int x = 0, int y = 0);
- static void notifyToplevels(QEvent *e);
- bool leaveOnMouseRelease;
-};
-
-void QWhatsThisPrivate::notifyToplevels(QEvent *e)
-{
- QWidgetList toplevels = QApplication::topLevelWidgets();
- for (int i = 0; i < toplevels.count(); ++i) {
- register QWidget *w = toplevels.at(i);
- QApplication::sendEvent(w, e);
- }
-}
-
-QWhatsThisPrivate *QWhatsThisPrivate::instance = 0;
-
-QWhatsThisPrivate::QWhatsThisPrivate()
- : leaveOnMouseRelease(false)
-{
- instance = this;
- qApp->installEventFilter(this);
-
- QPoint pos = QCursor::pos();
- if (QWidget *w = QApplication::widgetAt(pos)) {
- QHelpEvent e(QEvent::QueryWhatsThis, w->mapFromGlobal(pos), pos);
- bool sentEvent = QApplication::sendEvent(w, &e);
-#ifdef QT_NO_CURSOR
- Q_UNUSED(sentEvent);
-#else
- QApplication::setOverrideCursor((!sentEvent || !e.isAccepted())?
- Qt::ForbiddenCursor:Qt::WhatsThisCursor);
- } else {
- QApplication::setOverrideCursor(Qt::WhatsThisCursor);
-#endif
- }
-#ifndef QT_NO_ACCESSIBILITY
- QAccessible::updateAccessibility(this, 0, QAccessible::ContextHelpStart);
-#endif
-}
-
-QWhatsThisPrivate::~QWhatsThisPrivate()
-{
- if (action)
- action->setChecked(false);
-#ifdef QT3_SUPPORT
- if (button)
- button->setChecked(false);
-#endif
-#ifndef QT_NO_CURSOR
- QApplication::restoreOverrideCursor();
-#endif
-#ifndef QT_NO_ACCESSIBILITY
- QAccessible::updateAccessibility(this, 0, QAccessible::ContextHelpEnd);
-#endif
- instance = 0;
-}
-
-bool QWhatsThisPrivate::eventFilter(QObject *o, QEvent *e)
-{
- if (!o->isWidgetType())
- return false;
- QWidget * w = static_cast<QWidget *>(o);
- bool customWhatsThis = w->testAttribute(Qt::WA_CustomWhatsThis);
- switch (e->type()) {
- case QEvent::MouseButtonPress:
- {
- QMouseEvent *me = static_cast<QMouseEvent*>(e);
- if (me->button() == Qt::RightButton || customWhatsThis)
- return false;
- QHelpEvent e(QEvent::WhatsThis, me->pos(), me->globalPos());
- if (!QApplication::sendEvent(w, &e) || !e.isAccepted())
- leaveOnMouseRelease = true;
-
- } break;
-
- case QEvent::MouseMove:
- {
- QMouseEvent *me = static_cast<QMouseEvent*>(e);
- QHelpEvent e(QEvent::QueryWhatsThis, me->pos(), me->globalPos());
- bool sentEvent = QApplication::sendEvent(w, &e);
-#ifdef QT_NO_CURSOR
- Q_UNUSED(sentEvent);
-#else
- QApplication::changeOverrideCursor((!sentEvent || !e.isAccepted())?
- Qt::ForbiddenCursor:Qt::WhatsThisCursor);
-#endif
- }
- // fall through
- case QEvent::MouseButtonRelease:
- case QEvent::MouseButtonDblClick:
- if (leaveOnMouseRelease && e->type() == QEvent::MouseButtonRelease)
- QWhatsThis::leaveWhatsThisMode();
- if (static_cast<QMouseEvent*>(e)->button() == Qt::RightButton || customWhatsThis)
- return false; // ignore RMB release
- break;
- case QEvent::KeyPress:
- {
- QKeyEvent* kev = (QKeyEvent*)e;
-
- if (kev->key() == Qt::Key_Escape) {
- QWhatsThis::leaveWhatsThisMode();
- return true;
- } else if (customWhatsThis) {
- return false;
- } else if (kev->key() == Qt::Key_Menu ||
- (kev->key() == Qt::Key_F10 &&
- kev->modifiers() == Qt::ShiftModifier)) {
- // we don't react to these keys, they are used for context menus
- return false;
- } else if (kev->key() != Qt::Key_Shift && kev->key() != Qt::Key_Alt // not a modifier key
- && kev->key() != Qt::Key_Control && kev->key() != Qt::Key_Meta) {
- QWhatsThis::leaveWhatsThisMode();
- }
- } break;
- default:
- return false;
- }
- return true;
-}
-
-class QWhatsThisAction: public QAction
-{
- Q_OBJECT
-
-public:
- explicit QWhatsThisAction(QObject* parent = 0);
-
-private slots:
- void actionTriggered();
-};
-
-QWhatsThisAction::QWhatsThisAction(QObject *parent) : QAction(tr("What's This?"), parent)
-{
-#ifndef QT_NO_IMAGEFORMAT_XPM
- QPixmap p((const char**)button_image);
- setIcon(p);
-#endif
- setCheckable(true);
- connect(this, SIGNAL(triggered()), this, SLOT(actionTriggered()));
-#ifndef QT_NO_SHORTCUT
- setShortcut(Qt::ShiftModifier + Qt::Key_F1);
-#endif
-}
-
-void QWhatsThisAction::actionTriggered()
-{
- if (isChecked()) {
- QWhatsThis::enterWhatsThisMode();
- QWhatsThisPrivate::instance->action = this;
- }
-}
-
-QWhatsThis::QWhatsThis()
-{
-}
-
-#ifdef QT3_SUPPORT
-/*!
- \obsolete
-
- Sets the What's This text \a s for the widget \a w.
-
- Use QWidget::setWhatsThis() or QAction::setWhatsThis() instead.
-*/
-void QWhatsThis::add(QWidget *w, const QString &s)
-{
- w->setWhatsThis(s);
-}
-
-/*!
- \obsolete
-
- Remove's the What's This text for the widget \a w.
-
- Use QWidget::setWhatsThis() or QAction::setWhatsThis() instead.
-*/
-void QWhatsThis::remove(QWidget *w)
-{
- w->setWhatsThis(QString());
-}
-
-class QWhatsThisButton : public QToolButton
-{
- Q_OBJECT
-public:
- QWhatsThisButton(QWidget *p) : QToolButton(p) {
- setCheckable(true);
- QPixmap pix( const_cast<const char**>(button_image) );
- setIcon( pix );
- QObject::connect(this, SIGNAL(toggled(bool)), this, SLOT(whatToggled(bool)));
- setAutoRaise(true);
- setFocusPolicy(Qt::NoFocus);
- }
-
-public slots:
- void whatToggled(bool b) {
- if (b) {
- QWhatsThis::enterWhatsThisMode();
- QWhatsThisPrivate::instance->button = this;
- }
- }
-};
-
-/*!
- Returns a new "What's This?" QToolButton with the given \a
- parent. To do this now, create your own QToolButton and a
- QWhatsThis object and call the QWhatsThis object's showText()
- function when the QToolButton is invoked.
-
- Use createAction() instead.
-*/
-QToolButton * QWhatsThis::whatsThisButton(QWidget * parent)
-{
- return new QWhatsThisButton(parent);
-}
-#endif
-
-/*!
- This function switches the user interface into "What's This?"
- mode. The user interface can be switched back into normal mode by
- the user (e.g. by them clicking or pressing Esc), or
- programmatically by calling leaveWhatsThisMode().
-
- When entering "What's This?" mode, a QEvent of type
- Qt::EnterWhatsThisMode is sent to all toplevel widgets.
-
- \sa inWhatsThisMode() leaveWhatsThisMode()
-*/
-void QWhatsThis::enterWhatsThisMode()
-{
- if (QWhatsThisPrivate::instance)
- return;
- (void) new QWhatsThisPrivate;
- QEvent e(QEvent::EnterWhatsThisMode);
- QWhatsThisPrivate::notifyToplevels(&e);
- }
-
-/*!
- Returns true if the user interface is in "What's This?" mode;
- otherwise returns false.
-
- \sa enterWhatsThisMode()
-*/
-bool QWhatsThis::inWhatsThisMode()
-{
- return (QWhatsThisPrivate::instance != 0);
-}
-
-/*!
- If the user interface is in "What's This?" mode, this function
- switches back to normal mode; otherwise it does nothing.
-
- When leaving "What's This?" mode, a QEvent of type
- Qt::LeaveWhatsThisMode is sent to all toplevel widgets.
-
- \sa enterWhatsThisMode() inWhatsThisMode()
-*/
-void QWhatsThis::leaveWhatsThisMode()
-{
- delete QWhatsThisPrivate::instance;
- QEvent e(QEvent::LeaveWhatsThisMode);
- QWhatsThisPrivate::notifyToplevels(&e);
-}
-
-void QWhatsThisPrivate::say(QWidget * widget, const QString &text, int x, int y)
-{
- if (text.size() == 0)
- return;
- // make a fresh widget, and set it up
- QWhatsThat *whatsThat = new QWhatsThat(
- text,
-#if defined(Q_WS_X11) && !defined(QT_NO_CURSOR)
- QApplication::desktop()->screen(widget ? widget->x11Info().screen() : QCursor::x11Screen()),
-#else
- 0,
-#endif
- widget
- );
-
-
- // okay, now to find a suitable location
-
- int scr = (widget ?
- QApplication::desktop()->screenNumber(widget) :
-#if defined(Q_WS_X11) && !defined(QT_NO_CURSOR)
- QCursor::x11Screen()
-#else
- QApplication::desktop()->screenNumber(QPoint(x,y))
-#endif // Q_WS_X11
- );
- QRect screen = QApplication::desktop()->screenGeometry(scr);
-
- int w = whatsThat->width();
- int h = whatsThat->height();
- int sx = screen.x();
- int sy = screen.y();
-
- // first try locating the widget immediately above/below,
- // with nice alignment if possible.
- QPoint pos;
- if (widget)
- pos = widget->mapToGlobal(QPoint(0,0));
-
- if (widget && w > widget->width() + 16)
- x = pos.x() + widget->width()/2 - w/2;
- else
- x = x - w/2;
-
- // squeeze it in if that would result in part of what's this
- // being only partially visible
- if (x + w + shadowWidth > sx+screen.width())
- x = (widget? (qMin(screen.width(),
- pos.x() + widget->width())
- ) : screen.width())
- - w;
-
- if (x < sx)
- x = sx;
-
- if (widget && h > widget->height() + 16) {
- y = pos.y() + widget->height() + 2; // below, two pixels spacing
- // what's this is above or below, wherever there's most space
- if (y + h + 10 > sy+screen.height())
- y = pos.y() + 2 - shadowWidth - h; // above, overlap
- }
- y = y + 2;
-
- // squeeze it in if that would result in part of what's this
- // being only partially visible
- if (y + h + shadowWidth > sy+screen.height())
- y = (widget ? (qMin(screen.height(),
- pos.y() + widget->height())
- ) : screen.height())
- - h;
- if (y < sy)
- y = sy;
-
- whatsThat->move(x, y);
- whatsThat->show();
- whatsThat->grabKeyboard();
-}
-
-/*!
- Shows \a text as a "What's This?" window, at global position \a
- pos. The optional widget argument, \a w, is used to determine the
- appropriate screen on multi-head systems.
-
- \sa hideText()
-*/
-void QWhatsThis::showText(const QPoint &pos, const QString &text, QWidget *w)
-{
- leaveWhatsThisMode();
- QWhatsThisPrivate::say(w, text, pos.x(), pos.y());
-}
-
-/*!
- If a "What's This?" window is showing, this destroys it.
-
- \sa showText()
-*/
-void QWhatsThis::hideText()
-{
- qDeleteInEventHandler(QWhatsThat::instance);
-}
-
-/*!
- Returns a ready-made QAction, used to invoke "What's This?" context
- help, with the given \a parent.
-
- The returned QAction provides a convenient way to let users enter
- "What's This?" mode.
-*/
-QAction *QWhatsThis::createAction(QObject *parent)
-{
- return new QWhatsThisAction(parent);
-}
-
-QT_END_NAMESPACE
-
-#include "qwhatsthis.moc"
-
-#endif // QT_NO_WHATSTHIS
diff --git a/src/gui/kernel/qwhatsthis.h b/src/gui/kernel/qwhatsthis.h
deleted file mode 100644
index 0028a32545..0000000000
--- a/src/gui/kernel/qwhatsthis.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWHATSTHIS_H
-#define QWHATSTHIS_H
-
-#include <QtCore/qobject.h>
-#include <QtGui/qcursor.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_WHATSTHIS
-
-class QAction;
-#ifdef QT3_SUPPORT
-class QToolButton;
-#endif
-
-class Q_GUI_EXPORT QWhatsThis
-{
- QWhatsThis();
-
-public:
- static void enterWhatsThisMode();
- static bool inWhatsThisMode();
- static void leaveWhatsThisMode();
-
- static void showText(const QPoint &pos, const QString &text, QWidget *w = 0);
- static void hideText();
-
- static QAction *createAction(QObject *parent = 0);
-
-#ifdef QT3_SUPPORT
- static QT3_SUPPORT void add(QWidget *w, const QString &s);
- static QT3_SUPPORT void remove(QWidget *);
- static QT3_SUPPORT QToolButton *whatsThisButton(QWidget *parent);
-#endif
-};
-
-#endif // QT_NO_WHATSTHIS
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QWHATSTHIS_H
diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp
deleted file mode 100644
index 72ff5e9df2..0000000000
--- a/src/gui/kernel/qwidget.cpp
+++ /dev/null
@@ -1,12686 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qapplication.h"
-#include "qapplication_p.h"
-#include "qbrush.h"
-#include "qcursor.h"
-#include "qdesktopwidget.h"
-#include "qevent.h"
-#include "qhash.h"
-#include "qlayout.h"
-#include "qmenu.h"
-#include "qmetaobject.h"
-#include "qpixmap.h"
-#include "qpointer.h"
-#include "qstack.h"
-#include "qstyle.h"
-#include "qstylefactory.h"
-#include "qvariant.h"
-#include "qwidget.h"
-#include "qstyleoption.h"
-#ifndef QT_NO_ACCESSIBILITY
-# include "qaccessible.h"
-#endif
-#if defined(Q_WS_WIN)
-# include "qt_windows.h"
-#endif
-#ifdef Q_WS_MAC
-# include "qt_mac_p.h"
-# include "qt_cocoa_helpers_mac_p.h"
-# include "qmainwindow.h"
-# include "qtoolbar.h"
-# include <private/qmainwindowlayout_p.h>
-#endif
-#if defined(Q_WS_QWS)
-# include "qwsdisplay_qws.h"
-# include "qwsmanager_qws.h"
-# include "qpaintengine.h" // for PorterDuff
-# include "private/qwindowsurface_qws_p.h"
-#endif
-#if defined(Q_WS_QPA)
-#include "qplatformwindow_qpa.h"
-#endif
-#include "qpainter.h"
-#include "qtooltip.h"
-#include "qwhatsthis.h"
-#include "qdebug.h"
-#include "private/qstylesheetstyle_p.h"
-#include "private/qstyle_p.h"
-#include "private/qinputcontext_p.h"
-#include "qfileinfo.h"
-#include "private/qsoftkeymanager_p.h"
-
-#if defined (Q_WS_WIN)
-# include <private/qwininputcontext_p.h>
-#endif
-
-#if defined(Q_WS_X11)
-# include <private/qpaintengine_x11_p.h>
-# include "qx11info_x11.h"
-#endif
-
-#include <private/qgraphicseffect_p.h>
-#include <private/qwindowsurface_p.h>
-#include <private/qbackingstore_p.h>
-#ifdef Q_WS_MAC
-# include <private/qpaintengine_mac_p.h>
-#endif
-#include <private/qpaintengine_raster_p.h>
-
-#if defined(Q_OS_SYMBIAN)
-#include "private/qt_s60_p.h"
-#endif
-
-#include "qwidget_p.h"
-#include "qaction_p.h"
-#include "qlayout_p.h"
-#include "QtGui/qgraphicsproxywidget.h"
-#include "QtGui/qgraphicsscene.h"
-#include "private/qgraphicsproxywidget_p.h"
-#include "QtGui/qabstractscrollarea.h"
-#include "private/qabstractscrollarea_p.h"
-#include "private/qevent_p.h"
-
-#include "private/qgraphicssystem_p.h"
-#include "private/qgesturemanager_p.h"
-
-#ifdef QT_KEYPAD_NAVIGATION
-#include "qtabwidget.h" // Needed in inTabWidget()
-#endif // QT_KEYPAD_NAVIGATION
-
-#ifdef Q_WS_S60
-#include <aknappui.h>
-#endif
-
-// widget/widget data creation count
-//#define QWIDGET_EXTRA_DEBUG
-//#define ALIEN_DEBUG
-
-QT_BEGIN_NAMESPACE
-
-#if !defined(Q_WS_QWS)
-static bool qt_enable_backingstore = true;
-#endif
-#ifdef Q_WS_X11
-// for compatibility with Qt 4.0
-Q_GUI_EXPORT void qt_x11_set_global_double_buffer(bool enable)
-{
- qt_enable_backingstore = enable;
-}
-#endif
-
-#if defined(QT_MAC_USE_COCOA)
-bool qt_mac_clearDirtyOnWidgetInsideDrawWidget = false;
-#endif
-
-static inline bool qRectIntersects(const QRect &r1, const QRect &r2)
-{
- return (qMax(r1.left(), r2.left()) <= qMin(r1.right(), r2.right()) &&
- qMax(r1.top(), r2.top()) <= qMin(r1.bottom(), r2.bottom()));
-}
-
-static inline bool hasBackingStoreSupport()
-{
-#ifdef Q_WS_MAC
- return QApplicationPrivate::graphicsSystem() != 0;
-#else
- return true;
-#endif
-}
-
-#ifdef Q_WS_MAC
-# define QT_NO_PAINT_DEBUG
-#endif
-
-extern bool qt_sendSpontaneousEvent(QObject*, QEvent*); // qapplication.cpp
-extern QDesktopWidget *qt_desktopWidget; // qapplication.cpp
-
-/*!
- \internal
- \class QWidgetBackingStoreTracker
- \brief Class which allows tracking of which widgets are using a given backing store
-
- QWidgetBackingStoreTracker is a thin wrapper around a QWidgetBackingStore pointer,
- which maintains a list of the QWidgets which are currently using the backing
- store. This list is modified via the registerWidget and unregisterWidget functions.
- */
-
-QWidgetBackingStoreTracker::QWidgetBackingStoreTracker()
- : m_ptr(0)
-{
-
-}
-
-QWidgetBackingStoreTracker::~QWidgetBackingStoreTracker()
-{
- delete m_ptr;
-}
-
-/*!
- \internal
- Destroy the contained QWidgetBackingStore, if not null, and clear the list of
- widgets using the backing store, then create a new QWidgetBackingStore, providing
- the QWidget.
- */
-void QWidgetBackingStoreTracker::create(QWidget *widget)
-{
- destroy();
- m_ptr = new QWidgetBackingStore(widget);
-}
-
-/*!
- \internal
- Destroy the contained QWidgetBackingStore, if not null, and clear the list of
- widgets using the backing store.
- */
-void QWidgetBackingStoreTracker::destroy()
-{
- delete m_ptr;
- m_ptr = 0;
- m_widgets.clear();
-}
-
-/*!
- \internal
- Add the widget to the list of widgets currently using the backing store.
- If the widget was already in the list, this function is a no-op.
- */
-void QWidgetBackingStoreTracker::registerWidget(QWidget *w)
-{
- Q_ASSERT(m_ptr);
- Q_ASSERT(w->internalWinId());
- Q_ASSERT(qt_widget_private(w)->maybeBackingStore() == m_ptr);
- m_widgets.insert(w);
-}
-
-/*!
- \internal
- Remove the widget from the list of widgets currently using the backing store.
- If the widget was in the list, and removing it causes the list to be empty,
- the backing store is deleted.
- If the widget was not in the list, this function is a no-op.
- */
-void QWidgetBackingStoreTracker::unregisterWidget(QWidget *w)
-{
- if (m_widgets.remove(w) && m_widgets.isEmpty()) {
- delete m_ptr;
- m_ptr = 0;
- }
-}
-
-/*!
- \internal
- Recursively remove widget and all of its descendents.
- */
-void QWidgetBackingStoreTracker::unregisterWidgetSubtree(QWidget *widget)
-{
- unregisterWidget(widget);
- foreach (QObject *child, widget->children())
- if (QWidget *childWidget = qobject_cast<QWidget *>(child))
- unregisterWidgetSubtree(childWidget);
-}
-
-QWidgetPrivate::QWidgetPrivate(int version)
- : QObjectPrivate(version)
- , extra(0)
- , focus_next(0)
- , focus_prev(0)
- , focus_child(0)
- , layout(0)
- , needsFlush(0)
- , redirectDev(0)
- , widgetItem(0)
- , extraPaintEngine(0)
- , polished(0)
- , graphicsEffect(0)
-#if !defined(QT_NO_IM)
- , imHints(Qt::ImhNone)
-#endif
- , inheritedFontResolveMask(0)
- , inheritedPaletteResolveMask(0)
- , leftmargin(0)
- , topmargin(0)
- , rightmargin(0)
- , bottommargin(0)
- , leftLayoutItemMargin(0)
- , topLayoutItemMargin(0)
- , rightLayoutItemMargin(0)
- , bottomLayoutItemMargin(0)
- , hd(0)
- , size_policy(QSizePolicy::Preferred, QSizePolicy::Preferred)
- , fg_role(QPalette::NoRole)
- , bg_role(QPalette::NoRole)
- , dirtyOpaqueChildren(1)
- , isOpaque(0)
- , inDirtyList(0)
- , isScrolled(0)
- , isMoved(0)
- , isGLWidget(0)
- , usesDoubleBufferedGLContext(0)
-#ifndef QT_NO_IM
- , inheritsInputMethodHints(0)
-#endif
- , inSetParent(0)
-#if defined(Q_WS_X11)
- , picture(0)
-#elif defined(Q_WS_WIN)
- , noPaintOnScreen(0)
- #ifndef QT_NO_GESTURES
- , nativeGesturePanEnabled(0)
- #endif
-#elif defined(Q_WS_MAC)
- , needWindowChange(0)
- , window_event(0)
- , qd_hd(0)
-#elif defined(Q_OS_SYMBIAN)
- , symbianScreenNumber(0)
- , fixNativeOrientationCalled(false)
-#endif
-{
- if (!qApp) {
- qFatal("QWidget: Must construct a QApplication before a QPaintDevice");
- return;
- }
-
- if (version != QObjectPrivateVersion)
- qFatal("Cannot mix incompatible Qt libraries");
-
- isWidget = true;
- memset(high_attributes, 0, sizeof(high_attributes));
-#if QT_MAC_USE_COCOA
- drawRectOriginalAdded = false;
- originalDrawMethod = true;
- changeMethods = false;
- isInUnifiedToolbar = false;
- unifiedSurface = 0;
- toolbar_ancestor = 0;
- flushRequested = false;
- touchEventsEnabled = false;
-#endif // QT_MAC_USE_COCOA
-#ifdef QWIDGET_EXTRA_DEBUG
- static int count = 0;
- qDebug() << "widgets" << ++count;
-#endif
-}
-
-
-QWidgetPrivate::~QWidgetPrivate()
-{
- if (widgetItem)
- widgetItem->wid = 0;
-
- if (extra)
- deleteExtra();
-
-#ifndef QT_NO_GRAPHICSEFFECT
- delete graphicsEffect;
-#endif //QT_NO_GRAPHICSEFFECT
-}
-
-class QDummyWindowSurface : public QWindowSurface
-{
-public:
- QDummyWindowSurface(QWidget *window) : QWindowSurface(window) {}
- QPaintDevice *paintDevice() { return window(); }
- void flush(QWidget *, const QRegion &, const QPoint &) {}
-};
-
-QWindowSurface *QWidgetPrivate::createDefaultWindowSurface()
-{
- Q_Q(QWidget);
-
- QWindowSurface *surface;
-#ifndef QT_NO_PROPERTIES
- if (q->property("_q_DummyWindowSurface").toBool()) {
- surface = new QDummyWindowSurface(q);
- } else
-#endif
- {
- if (QApplicationPrivate::graphicsSystem())
- surface = QApplicationPrivate::graphicsSystem()->createWindowSurface(q);
- else
- surface = createDefaultWindowSurface_sys();
- }
-
- return surface;
-}
-
-/*!
- \internal
-*/
-void QWidgetPrivate::scrollChildren(int dx, int dy)
-{
- Q_Q(QWidget);
- if (q->children().size() > 0) { // scroll children
- QPoint pd(dx, dy);
- QObjectList childObjects = q->children();
- for (int i = 0; i < childObjects.size(); ++i) { // move all children
- QWidget *w = qobject_cast<QWidget*>(childObjects.at(i));
- if (w && !w->isWindow()) {
- QPoint oldp = w->pos();
- QRect r(w->pos() + pd, w->size());
- w->data->crect = r;
-#ifndef Q_WS_QWS
- if (w->testAttribute(Qt::WA_WState_Created))
- w->d_func()->setWSGeometry();
-#endif
- w->d_func()->setDirtyOpaqueRegion();
- QMoveEvent e(r.topLeft(), oldp);
- QApplication::sendEvent(w, &e);
- }
- }
- }
-}
-
-QInputContext *QWidgetPrivate::assignedInputContext() const
-{
-#ifndef QT_NO_IM
- const QWidget *widget = q_func();
- while (widget) {
- if (QInputContext *qic = widget->d_func()->ic)
- return qic;
- widget = widget->parentWidget();
- }
-#endif
- return 0;
-}
-
-QInputContext *QWidgetPrivate::inputContext() const
-{
-#ifndef QT_NO_IM
- if (QInputContext *qic = assignedInputContext())
- return qic;
- return qApp->inputContext();
-#else
- return 0;
-#endif
-}
-
-/*!
- This function returns the QInputContext for this widget. By
- default the input context is inherited from the widgets
- parent. For toplevels it is inherited from QApplication.
-
- You can override this and set a special input context for this
- widget by using the setInputContext() method.
-
- \sa setInputContext()
-*/
-QInputContext *QWidget::inputContext()
-{
- Q_D(QWidget);
- if (!testAttribute(Qt::WA_InputMethodEnabled))
- return 0;
-
- return d->inputContext();
-}
-
-/*!
- This function sets the input context \a context
- on this widget.
-
- Qt takes ownership of the given input \a context.
-
- \sa inputContext()
-*/
-void QWidget::setInputContext(QInputContext *context)
-{
- Q_D(QWidget);
- if (!testAttribute(Qt::WA_InputMethodEnabled))
- return;
-#ifndef QT_NO_IM
- if (context == d->ic)
- return;
- if (d->ic)
- delete d->ic;
- d->ic = context;
- if (d->ic)
- d->ic->setParent(this);
-#endif
-}
-
-
-/*!
- \obsolete
-
- This function can be called on the widget that currently has focus
- to reset the input method operating on it.
-
- 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
- QInputContext *qic = this->inputContext();
- if(qic)
- qic->reset();
-#endif // QT_NO_IM
-}
-
-#ifdef QT_KEYPAD_NAVIGATION
-QPointer<QWidget> QWidgetPrivate::editingWidget;
-
-/*!
- Returns true if this widget currently has edit focus; otherwise false.
-
- This feature is only available in Qt for Embedded Linux.
-
- \sa setEditFocus(), QApplication::keypadNavigationEnabled()
-*/
-bool QWidget::hasEditFocus() const
-{
- const QWidget* w = this;
- while (w->d_func()->extra && w->d_func()->extra->focus_proxy)
- w = w->d_func()->extra->focus_proxy;
- return QWidgetPrivate::editingWidget == w;
-}
-
-/*!
- \fn void QWidget::setEditFocus(bool enable)
-
- If \a enable is true, make this widget have edit focus, in which
- case Qt::Key_Up and Qt::Key_Down will be delivered to the widget
- normally; otherwise, Qt::Key_Up and Qt::Key_Down are used to
- change focus.
-
- This feature is only available in Qt for Embedded Linux and Qt
- for Symbian.
-
- \sa hasEditFocus(), QApplication::keypadNavigationEnabled()
-*/
-void QWidget::setEditFocus(bool on)
-{
- QWidget *f = this;
- while (f->d_func()->extra && f->d_func()->extra->focus_proxy)
- f = f->d_func()->extra->focus_proxy;
-
- if (QWidgetPrivate::editingWidget && QWidgetPrivate::editingWidget != f)
- QWidgetPrivate::editingWidget->setEditFocus(false);
-
- if (on && !f->hasFocus())
- f->setFocus();
-
- if ((!on && !QWidgetPrivate::editingWidget)
- || (on && QWidgetPrivate::editingWidget == f)) {
- return;
- }
-
- if (!on && QWidgetPrivate::editingWidget == f) {
- QWidgetPrivate::editingWidget = 0;
- QEvent event(QEvent::LeaveEditFocus);
- QApplication::sendEvent(f, &event);
- QApplication::sendEvent(f->style(), &event);
- } else if (on) {
- QWidgetPrivate::editingWidget = f;
- QEvent event(QEvent::EnterEditFocus);
- QApplication::sendEvent(f, &event);
- QApplication::sendEvent(f->style(), &event);
- }
-}
-#endif
-
-/*!
- \property QWidget::autoFillBackground
- \brief whether the widget background is filled automatically
- \since 4.1
-
- If enabled, this property will cause Qt to fill the background of the
- widget before invoking the paint event. The color used is defined by the
- QPalette::Window color role from the widget's \l{QPalette}{palette}.
-
- In addition, Windows are always filled with QPalette::Window, unless the
- WA_OpaquePaintEvent or WA_NoSystemBackground attributes are set.
-
- This property cannot be turned off (i.e., set to false) if a widget's
- parent has a static gradient for its background.
-
- \warning Use this property with caution in conjunction with
- \l{Qt Style Sheets}. When a widget has a style sheet with a valid
- background or a border-image, this property is automatically disabled.
-
- By default, this property is false.
-
- \sa Qt::WA_OpaquePaintEvent, Qt::WA_NoSystemBackground,
- {QWidget#Transparency and Double Buffering}{Transparency and Double Buffering}
-*/
-bool QWidget::autoFillBackground() const
-{
- Q_D(const QWidget);
- return d->extra && d->extra->autoFillBackground;
-}
-
-void QWidget::setAutoFillBackground(bool enabled)
-{
- Q_D(QWidget);
- if (!d->extra)
- d->createExtra();
- if (d->extra->autoFillBackground == enabled)
- return;
-
- d->extra->autoFillBackground = enabled;
- d->updateIsOpaque();
- update();
- d->updateIsOpaque();
-}
-
-/*!
- \class QWidget
- \brief The QWidget class is the base class of all user interface objects.
-
- \ingroup basicwidgets
-
- The widget is the atom of the user interface: it receives mouse, keyboard
- and other events from the window system, and paints a representation of
- itself on the screen. Every widget is rectangular, and they are sorted in a
- Z-order. A widget is clipped by its parent and by the widgets in front of
- it.
-
- A widget that is not embedded in a parent widget is called a window.
- Usually, windows have a frame and a title bar, although it is also possible
- to create windows without such decoration using suitable
- \l{Qt::WindowFlags}{window flags}). In Qt, QMainWindow and the various
- subclasses of QDialog are the most common window types.
-
- Every widget's constructor accepts one or two standard arguments:
-
- \list 1
- \i \c{QWidget *parent = 0} is the parent of the new widget. If it is 0
- (the default), the new widget will be a window. If not, it will be
- a child of \e parent, and be constrained by \e parent's geometry
- (unless you specify Qt::Window as window flag).
- \i \c{Qt::WindowFlags f = 0} (where available) sets the window flags;
- the default is suitable for almost all widgets, but to get, for
- example, a window without a window system frame, you must use
- special flags.
- \endlist
-
- QWidget has many member functions, but some of them have little direct
- functionality; for example, QWidget has a font property, but never uses
- this itself. There are many subclasses which provide real functionality,
- such as QLabel, QPushButton, QListWidget, and QTabWidget.
-
-
- \section1 Top-Level and Child Widgets
-
- A widget without a parent widget is always an independent window (top-level
- widget). For these widgets, setWindowTitle() and setWindowIcon() set the
- title bar and icon respectively.
-
- Non-window widgets are child widgets, displayed within their parent
- widgets. Most widgets in Qt are mainly useful as child widgets. For
- example, it is possible to display a button as a top-level window, but most
- people prefer to put their buttons inside other widgets, such as QDialog.
-
- \image parent-child-widgets.png A parent widget containing various child widgets.
-
- The diagram above shows a QGroupBox widget being used to hold various child
- widgets in a layout provided by QGridLayout. The QLabel child widgets have
- been outlined to indicate their full sizes.
-
- If you want to use a QWidget to hold child widgets you will usually want to
- add a layout to the parent QWidget. See \l{Layout Management} for more
- information.
-
-
- \section1 Composite Widgets
-
- When a widget is used as a container to group a number of child widgets, it
- is known as a composite widget. These can be created by constructing a
- widget with the required visual properties - a QFrame, for example - and
- adding child widgets to it, usually managed by a layout. The above diagram
- shows such a composite widget that was created using \l{Qt Designer}.
-
- Composite widgets can also be created by subclassing a standard widget,
- such as QWidget or QFrame, and adding the necessary layout and child
- widgets in the constructor of the subclass. Many of the \l{Qt Examples}
- {examples provided with Qt} use this approach, and it is also covered in
- the Qt \l{Tutorials}.
-
-
- \section1 Custom Widgets and Painting
-
- Since QWidget is a subclass of QPaintDevice, subclasses can be used to
- display custom content that is composed using a series of painting
- operations with an instance of the QPainter class. This approach contrasts
- with the canvas-style approach used by the \l{Graphics View}
- {Graphics View Framework} where items are added to a scene by the
- application and are rendered by the framework itself.
-
- Each widget performs all painting operations from within its paintEvent()
- function. This is called whenever the widget needs to be redrawn, either
- as a result of some external change or when requested by the application.
-
- The \l{widgets/analogclock}{Analog Clock example} shows how a simple widget
- can handle paint events.
-
-
- \section1 Size Hints and Size Policies
-
- When implementing a new widget, it is almost always useful to reimplement
- sizeHint() to provide a reasonable default size for the widget and to set
- the correct size policy with setSizePolicy().
-
- By default, composite widgets which do not provide a size hint will be
- sized according to the space requirements of their child widgets.
-
- The size policy lets you supply good default behavior for the layout
- management system, so that other widgets can contain and manage yours
- easily. The default size policy indicates that the size hint represents
- the preferred size of the widget, and this is often good enough for many
- widgets.
-
- \note The size of top-level widgets are constrained to 2/3 of the desktop's
- height and width. You can resize() the widget manually if these bounds are
- inadequate.
-
-
- \section1 Events
-
- Widgets respond to events that are typically caused by user actions. Qt
- delivers events to widgets by calling specific event handler functions with
- instances of QEvent subclasses containing information about each event.
-
- If your widget only contains child widgets, you probably do not need to
- implement any event handlers. If you want to detect a mouse click in a
- child widget call the child's underMouse() function inside the widget's
- mousePressEvent().
-
- The \l{widgets/scribble}{Scribble example} implements a wider set of
- events to handle mouse movement, button presses, and window resizing.
-
- You will need to supply the behavior and content for your own widgets, but
- here is a brief overview of the events that are relevant to QWidget,
- starting with the most common ones:
-
- \list
- \i paintEvent() is called whenever the widget needs to be repainted.
- Every widget displaying custom content must implement it. Painting
- using a QPainter can only take place in a paintEvent() or a
- function called by a paintEvent().
- \i resizeEvent() is called when the widget has been resized.
- \i mousePressEvent() is called when a mouse button is pressed while
- the mouse cursor is inside the widget, or when the widget has
- grabbed the mouse using grabMouse(). Pressing the mouse without
- releasing it is effectively the same as calling grabMouse().
- \i mouseReleaseEvent() is called when a mouse button is released. A
- widget receives mouse release events when it has received the
- corresponding mouse press event. This means that if the user
- presses the mouse inside \e your widget, then drags the mouse
- somewhere else before releasing the mouse button, \e your widget
- receives the release event. There is one exception: if a popup menu
- appears while the mouse button is held down, this popup immediately
- steals the mouse events.
- \i mouseDoubleClickEvent() is called when the user double-clicks in
- the widget. If the user double-clicks, the widget receives a mouse
- press event, a mouse release event and finally this event instead
- of a second mouse press event. (Some mouse move events may also be
- received if the mouse is not held steady during this operation.) It
- is \e{not possible} to distinguish a click from a double-click
- until the second click arrives. (This is one reason why most GUI
- books recommend that double-clicks be an extension of
- single-clicks, rather than trigger a different action.)
- \endlist
-
- Widgets that accept keyboard input need to reimplement a few more event
- handlers:
-
- \list
- \i keyPressEvent() is called whenever a key is pressed, and again when
- a key has been held down long enough for it to auto-repeat. The
- \key Tab and \key Shift+Tab keys are only passed to the widget if
- they are not used by the focus-change mechanisms. To force those
- keys to be processed by your widget, you must reimplement
- QWidget::event().
- \i focusInEvent() is called when the widget gains keyboard focus
- (assuming you have called setFocusPolicy()). Well-behaved widgets
- indicate that they own the keyboard focus in a clear but discreet
- way.
- \i focusOutEvent() is called when the widget loses keyboard focus.
- \endlist
-
- You may be required to also reimplement some of the less common event
- handlers:
-
- \list
- \i mouseMoveEvent() is called whenever the mouse moves while a mouse
- button is held down. This can be useful during drag and drop
- operations. If you call \l{setMouseTracking()}{setMouseTracking}(true),
- you get mouse move events even when no buttons are held down.
- (See also the \l{Drag and Drop} guide.)
- \i keyReleaseEvent() is called whenever a key is released and while it
- is held down (if the key is auto-repeating). In that case, the
- widget will receive a pair of key release and key press event for
- every repeat. The \key Tab and \key Shift+Tab keys are only passed
- to the widget if they are not used by the focus-change mechanisms.
- To force those keys to be processed by your widget, you must
- reimplement QWidget::event().
- \i wheelEvent() is called whenever the user turns the mouse wheel
- while the widget has the focus.
- \i enterEvent() is called when the mouse enters the widget's screen
- space. (This excludes screen space owned by any of the widget's
- children.)
- \i leaveEvent() is called when the mouse leaves the widget's screen
- space. If the mouse enters a child widget it will not cause a
- leaveEvent().
- \i moveEvent() is called when the widget has been moved relative to
- its parent.
- \i closeEvent() is called when the user closes the widget (or when
- close() is called).
- \endlist
-
- There are also some rather obscure events described in the documentation
- for QEvent::Type. To handle these events, you need to reimplement event()
- directly.
-
- The default implementation of event() handles \key Tab and \key Shift+Tab
- (to move the keyboard focus), and passes on most of the other events to
- one of the more specialized handlers above.
-
- Events and the mechanism used to deliver them are covered in
- \l{The Event System}.
-
- \section1 Groups of Functions and Properties
-
- \table
- \header \i Context \i Functions and Properties
-
- \row \i Window functions \i
- show(),
- hide(),
- raise(),
- lower(),
- close().
-
- \row \i Top-level windows \i
- \l windowModified, \l windowTitle, \l windowIcon, \l windowIconText,
- \l isActiveWindow, activateWindow(), \l minimized, showMinimized(),
- \l maximized, showMaximized(), \l fullScreen, showFullScreen(),
- showNormal().
-
- \row \i Window contents \i
- update(),
- repaint(),
- scroll().
-
- \row \i Geometry \i
- \l pos, x(), y(), \l rect, \l size, width(), height(), move(), resize(),
- \l sizePolicy, sizeHint(), minimumSizeHint(),
- updateGeometry(), layout(),
- \l frameGeometry, \l geometry, \l childrenRect, \l childrenRegion,
- adjustSize(),
- mapFromGlobal(), mapToGlobal(),
- mapFromParent(), mapToParent(),
- \l maximumSize, \l minimumSize, \l sizeIncrement,
- \l baseSize, setFixedSize()
-
- \row \i Mode \i
- \l visible, isVisibleTo(),
- \l enabled, isEnabledTo(),
- \l modal,
- isWindow(),
- \l mouseTracking,
- \l updatesEnabled,
- visibleRegion().
-
- \row \i Look and feel \i
- style(),
- setStyle(),
- \l styleSheet,
- \l cursor,
- \l font,
- \l palette,
- backgroundRole(), setBackgroundRole(),
- fontInfo(), fontMetrics().
-
- \row \i Keyboard focus functions \i
- \l focus, \l focusPolicy,
- setFocus(), clearFocus(), setTabOrder(), setFocusProxy(),
- focusNextChild(), focusPreviousChild().
-
- \row \i Mouse and keyboard grabbing \i
- grabMouse(), releaseMouse(),
- grabKeyboard(), releaseKeyboard(),
- mouseGrabber(), keyboardGrabber().
-
- \row \i Event handlers \i
- event(),
- mousePressEvent(),
- mouseReleaseEvent(),
- mouseDoubleClickEvent(),
- mouseMoveEvent(),
- keyPressEvent(),
- keyReleaseEvent(),
- focusInEvent(),
- focusOutEvent(),
- wheelEvent(),
- enterEvent(),
- leaveEvent(),
- paintEvent(),
- moveEvent(),
- resizeEvent(),
- closeEvent(),
- dragEnterEvent(),
- dragMoveEvent(),
- dragLeaveEvent(),
- dropEvent(),
- childEvent(),
- showEvent(),
- hideEvent(),
- customEvent().
- changeEvent(),
-
- \row \i System functions \i
- parentWidget(), window(), setParent(), winId(),
- find(), metric().
-
- \row \i Interactive help \i
- setToolTip(), setWhatsThis()
-
- \endtable
-
-
- \section1 Widget Style Sheets
-
- In addition to the standard widget styles for each platform, widgets can
- also be styled according to rules specified in a \l{styleSheet}
- {style sheet}. This feature enables you to customize the appearance of
- specific widgets to provide visual cues to users about their purpose. For
- example, a button could be styled in a particular way to indicate that it
- performs a destructive action.
-
- The use of widget style sheets is described in more detail in the
- \l{Qt Style Sheets} document.
-
-
- \section1 Transparency and Double Buffering
-
- Since Qt 4.0, QWidget automatically double-buffers its painting, so there
- is no need to write double-buffering code in paintEvent() to avoid
- flicker.
-
- Since Qt 4.1, the Qt::WA_ContentsPropagated widget attribute has been
- deprecated. Instead, the contents of parent widgets are propagated by
- default to each of their children as long as Qt::WA_PaintOnScreen is not
- set. Custom widgets can be written to take advantage of this feature by
- updating irregular regions (to create non-rectangular child widgets), or
- painting with colors that have less than full alpha component. The
- following diagram shows how attributes and properties of a custom widget
- can be fine-tuned to achieve different effects.
-
- \image propagation-custom.png
-
- In the above diagram, a semi-transparent rectangular child widget with an
- area removed is constructed and added to a parent widget (a QLabel showing
- a pixmap). Then, different properties and widget attributes are set to
- achieve different effects:
-
- \list
- \i The left widget has no additional properties or widget attributes
- set. This default state suits most custom widgets using
- transparency, are irregularly-shaped, or do not paint over their
- entire area with an opaque brush.
- \i The center widget has the \l autoFillBackground property set. This
- property is used with custom widgets that rely on the widget to
- supply a default background, and do not paint over their entire
- area with an opaque brush.
- \i The right widget has the Qt::WA_OpaquePaintEvent widget attribute
- set. This indicates that the widget will paint over its entire area
- with opaque colors. The widget's area will initially be
- \e{uninitialized}, represented in the diagram with a red diagonal
- grid pattern that shines through the overpainted area. The
- Qt::WA_OpaquePaintArea attribute is useful for widgets that need to
- paint their own specialized contents quickly and do not need a
- default filled background.
- \endlist
-
- To rapidly update custom widgets with simple background colors, such as
- real-time plotting or graphing widgets, it is better to define a suitable
- background color (using setBackgroundRole() with the
- QPalette::Window role), set the \l autoFillBackground property, and only
- implement the necessary drawing functionality in the widget's paintEvent().
-
- To rapidly update custom widgets that constantly paint over their entire
- areas with opaque content, e.g., video streaming widgets, it is better to
- set the widget's Qt::WA_OpaquePaintEvent, avoiding any unnecessary overhead
- associated with repainting the widget's background.
-
- If a widget has both the Qt::WA_OpaquePaintEvent widget attribute \e{and}
- the \l autoFillBackground property set, the Qt::WA_OpaquePaintEvent
- attribute takes precedence. Depending on your requirements, you should
- choose either one of them.
-
- Since Qt 4.1, the contents of parent widgets are also propagated to
- standard Qt widgets. This can lead to some unexpected results if the
- parent widget is decorated in a non-standard way, as shown in the diagram
- below.
-
- \image propagation-standard.png
-
- The scope for customizing the painting behavior of standard Qt widgets,
- without resorting to subclassing, is slightly less than that possible for
- custom widgets. Usually, the desired appearance of a standard widget can be
- achieved by setting its \l autoFillBackground property.
-
-
- \section1 Creating Translucent Windows
-
- Since Qt 4.5, it has been possible to create windows with translucent regions
- on window systems that support compositing.
-
- To enable this feature in a top-level widget, set its Qt::WA_TranslucentBackground
- attribute with setAttribute() and ensure that its background is painted with
- non-opaque colors in the regions you want to be partially transparent.
-
- Platform notes:
-
- \list
- \o X11: This feature relies on the use of an X server that supports ARGB visuals
- and a compositing window manager.
- \o Windows: The widget needs to have the Qt::FramelessWindowHint window flag set
- for the translucency to work.
- \endlist
-
-
- \section1 Native Widgets vs Alien Widgets
-
- Introduced in Qt 4.4, alien widgets are widgets unknown to the windowing
- system. They do not have a native window handle associated with them. This
- feature significantly speeds up widget painting, resizing, and removes flicker.
-
- Should you require the old behavior with native windows, you can choose
- one of the following options:
-
- \list 1
- \i Use the \c{QT_USE_NATIVE_WINDOWS=1} in your environment.
- \i Set the Qt::AA_NativeWindows attribute on your application. All
- widgets will be native widgets.
- \i Set the Qt::WA_NativeWindow attribute on widgets: The widget itself
- and all of its ancestors will become native (unless
- Qt::WA_DontCreateNativeAncestors is set).
- \i Call QWidget::winId to enforce a native window (this implies 3).
- \i Set the Qt::WA_PaintOnScreen attribute to enforce a native window
- (this implies 3).
- \endlist
-
- \sa QEvent, QPainter, QGridLayout, QBoxLayout
-
- \section1 Softkeys
-
- Since Qt 4.6, Softkeys are usually physical keys on a device that have a corresponding label or
- other visual representation on the screen that is generally located next to its
- physical counterpart. They are most often found on mobile phone platforms. In
- modern touch based user interfaces it is also possible to have softkeys that do
- not correspond to any physical keys. Softkeys differ from other onscreen labels
- in that they are contextual.
-
- In Qt, contextual softkeys are added to a widget by calling addAction() and
- passing a \c QAction with a softkey role set on it. When the widget
- containing the softkey actions has focus, its softkeys should appear in
- the user interface. Softkeys are discovered by traversing the widget
- hierarchy so it is possible to define a single set of softkeys that are
- present at all times by calling addAction() for a given top level widget.
-
- On some platforms, this concept overlaps with \c QMenuBar such that if no
- other softkeys are found and the top level widget is a QMainWindow containing
- a QMenuBar, the menubar actions may appear on one of the softkeys.
-
- Note: Currently softkeys are only supported on the Symbian Platform.
-
- \sa addAction(), QAction, QMenuBar
-
-*/
-
-QWidgetMapper *QWidgetPrivate::mapper = 0; // widget with wid
-QWidgetSet *QWidgetPrivate::allWidgets = 0; // widgets with no wid
-
-
-/*****************************************************************************
- QWidget utility functions
- *****************************************************************************/
-
-QRegion qt_dirtyRegion(QWidget *widget)
-{
- if (!widget)
- return QRegion();
-
- QWidgetBackingStore *bs = qt_widget_private(widget)->maybeBackingStore();
- if (!bs)
- return QRegion();
-
- return bs->dirtyRegion(widget);
-}
-
-/*****************************************************************************
- QWidget member functions
- *****************************************************************************/
-
-/*
- Widget state flags:
- \list
- \i Qt::WA_WState_Created The widget has a valid winId().
- \i Qt::WA_WState_Visible The widget is currently visible.
- \i Qt::WA_WState_Hidden The widget is hidden, i.e. it won't
- become visible unless you call show() on it. Qt::WA_WState_Hidden
- implies !Qt::WA_WState_Visible.
- \i Qt::WA_WState_CompressKeys Compress keyboard events.
- \i Qt::WA_WState_BlockUpdates Repaints and updates are disabled.
- \i Qt::WA_WState_InPaintEvent Currently processing a paint event.
- \i Qt::WA_WState_Reparented The widget has been reparented.
- \i Qt::WA_WState_ConfigPending A configuration (resize/move) event is pending.
- \i Qt::WA_WState_DND (Deprecated) The widget supports drag and drop, see setAcceptDrops().
- \endlist
-*/
-
-struct QWidgetExceptionCleaner
-{
- /* this cleans up when the constructor throws an exception */
- static inline void cleanup(QWidget *that, QWidgetPrivate *d)
- {
-#ifdef QT_NO_EXCEPTIONS
- Q_UNUSED(that);
- Q_UNUSED(d);
-#else
- QWidgetPrivate::allWidgets->remove(that);
- if (d->focus_next != that) {
- if (d->focus_next)
- d->focus_next->d_func()->focus_prev = d->focus_prev;
- if (d->focus_prev)
- d->focus_prev->d_func()->focus_next = d->focus_next;
- }
-#endif
- }
-};
-
-/*!
- Constructs a widget which is a child of \a parent, with widget
- flags set to \a f.
-
- If \a parent is 0, the new widget becomes a window. If
- \a parent is another widget, this widget becomes a child window
- inside \a parent. The new widget is deleted when its \a parent is
- deleted.
-
- The widget flags argument, \a f, is normally 0, but it can be set
- to customize the frame of a window (i.e. \a
- parent must be 0). To customize the frame, use a value composed
- from the bitwise OR of any of the \l{Qt::WindowFlags}{window flags}.
-
- If you add a child widget to an already visible widget you must
- explicitly show the child to make it visible.
-
- Note that the X11 version of Qt may not be able to deliver all
- combinations of style flags on all systems. This is because on
- X11, Qt can only ask the window manager, and the window manager
- can override the application's settings. On Windows, Qt can set
- whatever flags you want.
-
- \sa windowFlags
-*/
-QWidget::QWidget(QWidget *parent, Qt::WindowFlags f)
- : QObject(*new QWidgetPrivate, 0), QPaintDevice()
-{
- QT_TRY {
- d_func()->init(parent, f);
- } QT_CATCH(...) {
- QWidgetExceptionCleaner::cleanup(this, d_func());
- QT_RETHROW;
- }
-}
-
-#ifdef QT3_SUPPORT
-/*!
- \overload
- \obsolete
- */
-QWidget::QWidget(QWidget *parent, const char *name, Qt::WindowFlags f)
- : QObject(*new QWidgetPrivate, 0), QPaintDevice()
-{
- QT_TRY {
- d_func()->init(parent , f);
- setObjectName(QString::fromAscii(name));
- } QT_CATCH(...) {
- QWidgetExceptionCleaner::cleanup(this, d_func());
- QT_RETHROW;
- }
-}
-#endif
-
-/*! \internal
-*/
-QWidget::QWidget(QWidgetPrivate &dd, QWidget* parent, Qt::WindowFlags f)
- : QObject(dd, 0), QPaintDevice()
-{
- Q_D(QWidget);
- QT_TRY {
- d->init(parent, f);
- } QT_CATCH(...) {
- QWidgetExceptionCleaner::cleanup(this, d_func());
- QT_RETHROW;
- }
-}
-
-/*!
- \internal
-*/
-int QWidget::devType() const
-{
- return QInternal::Widget;
-}
-
-
-//### w is a "this" ptr, passed as a param because QWorkspace needs special logic
-void QWidgetPrivate::adjustFlags(Qt::WindowFlags &flags, QWidget *w)
-{
- bool customize = (flags & (Qt::CustomizeWindowHint
- | Qt::FramelessWindowHint
- | Qt::WindowTitleHint
- | Qt::WindowSystemMenuHint
- | Qt::WindowMinimizeButtonHint
- | Qt::WindowMaximizeButtonHint
- | Qt::WindowCloseButtonHint
- | Qt::WindowContextHelpButtonHint));
-
- uint type = (flags & Qt::WindowType_Mask);
-
- if ((type == Qt::Widget || type == Qt::SubWindow) && w && !w->parent()) {
- type = Qt::Window;
- flags |= Qt::Window;
- }
-
- if (flags & Qt::CustomizeWindowHint) {
- // modify window flags to make them consistent.
- // Only enable this on non-Mac platforms. Since the old way of doing this would
- // interpret WindowSystemMenuHint as a close button and we can't change that behavior
- // we can't just add this in.
-#ifndef Q_WS_MAC
- if (flags & (Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint | Qt::WindowContextHelpButtonHint)) {
- flags |= Qt::WindowSystemMenuHint;
-#else
- if (flags & (Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint
- | Qt::WindowSystemMenuHint)) {
-#endif
- flags |= Qt::WindowTitleHint;
- flags &= ~Qt::FramelessWindowHint;
- }
- } else if (customize && !(flags & Qt::FramelessWindowHint)) {
- // if any of the window hints that affect the titlebar are set
- // and the window is supposed to have frame, we add a titlebar
- // and system menu by default.
- flags |= Qt::WindowSystemMenuHint;
- flags |= Qt::WindowTitleHint;
- }
- if (customize)
- ; // don't modify window flags if the user explicitly set them.
- else if (type == Qt::Dialog || type == Qt::Sheet)
-#ifndef Q_WS_WINCE
- flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowContextHelpButtonHint | Qt::WindowCloseButtonHint;
-#else
- flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint;
-#endif
- else if (type == Qt::Tool)
- flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint;
- else
- flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint;
-
-
-}
-
-void QWidgetPrivate::init(QWidget *parentWidget, Qt::WindowFlags f)
-{
- Q_Q(QWidget);
- if (QApplication::type() == QApplication::Tty)
- qFatal("QWidget: Cannot create a QWidget when no GUI is being used");
-
- Q_ASSERT(allWidgets);
- if (allWidgets)
- allWidgets->insert(q);
-
- QWidget *desktopWidget = 0;
- if (parentWidget && parentWidget->windowType() == Qt::Desktop) {
- desktopWidget = parentWidget;
- parentWidget = 0;
- }
-
- q->data = &data;
-
-#ifndef QT_NO_THREAD
- if (!parent) {
- Q_ASSERT_X(q->thread() == qApp->thread(), "QWidget",
- "Widgets must be created in the GUI thread.");
- }
-#endif
-
-#if defined(Q_WS_X11)
- if (desktopWidget) {
- // make sure the widget is created on the same screen as the
- // programmer specified desktop widget
- xinfo = desktopWidget->d_func()->xinfo;
- }
-#elif defined(Q_OS_SYMBIAN)
- if (desktopWidget) {
- symbianScreenNumber = qt_widget_private(desktopWidget)->symbianScreenNumber;
- }
-#elif defined(Q_WS_QPA)
- if (desktopWidget) {
- int screen = desktopWidget->d_func()->topData()->screenIndex;
- QPlatformIntegration *platform = QApplicationPrivate::platformIntegration();
- platform->moveToScreen(q, screen);
- }
-#else
- Q_UNUSED(desktopWidget);
-#endif
-
- data.fstrut_dirty = true;
-
- data.winid = 0;
- data.widget_attributes = 0;
- data.window_flags = f;
- data.window_state = 0;
- data.focus_policy = 0;
- data.context_menu_policy = Qt::DefaultContextMenu;
- data.window_modality = Qt::NonModal;
-
- data.sizehint_forced = 0;
- data.is_closing = 0;
- data.in_show = 0;
- data.in_set_window_state = 0;
- data.in_destructor = false;
-
- // Widgets with Qt::MSWindowsOwnDC (typically QGLWidget) must have a window handle.
- if (f & Qt::MSWindowsOwnDC)
- q->setAttribute(Qt::WA_NativeWindow);
-
-//#ifdef Q_WS_MAC
-// q->setAttribute(Qt::WA_NativeWindow);
-//#endif
-
- q->setAttribute(Qt::WA_QuitOnClose); // might be cleared in adjustQuitOnCloseAttribute()
- adjustQuitOnCloseAttribute();
-
- q->setAttribute(Qt::WA_WState_Hidden);
-
- //give potential windows a bigger "pre-initial" size; create_sys() will give them a new size later
-#ifdef Q_OS_SYMBIAN
- if (isGLWidget) {
- // Don't waste GPU mem for unnecessary large egl surface until resized by application
- data.crect = QRect(0,0,1,1);
- } else {
- data.crect = parentWidget ? QRect(0,0,100,30) : QRect(0,0,360,640);
- }
-#else
- data.crect = parentWidget ? QRect(0,0,100,30) : QRect(0,0,640,480);
-#endif
-
- focus_next = focus_prev = q;
-
- if ((f & Qt::WindowType_Mask) == Qt::Desktop)
- q->create();
- else if (parentWidget)
- q->setParent(parentWidget, data.window_flags);
- else {
- adjustFlags(data.window_flags, q);
- resolveLayoutDirection();
- // opaque system background?
- const QBrush &background = q->palette().brush(QPalette::Window);
- setOpaque(q->isWindow() && background.style() != Qt::NoBrush && background.isOpaque());
- }
- data.fnt = QFont(data.fnt, q);
-#if defined(Q_WS_X11)
- data.fnt.x11SetScreen(xinfo.screen());
-#endif // Q_WS_X11
-
- q->setAttribute(Qt::WA_PendingMoveEvent);
- q->setAttribute(Qt::WA_PendingResizeEvent);
-
- if (++QWidgetPrivate::instanceCounter > QWidgetPrivate::maxInstances)
- QWidgetPrivate::maxInstances = QWidgetPrivate::instanceCounter;
-
- if (QApplicationPrivate::app_compile_version < 0x040200
- || QApplicationPrivate::testAttribute(Qt::AA_ImmediateWidgetCreation))
- q->create();
-
-
- QEvent e(QEvent::Create);
- QApplication::sendEvent(q, &e);
- QApplication::postEvent(q, new QEvent(QEvent::PolishRequest));
-
- extraPaintEngine = 0;
-
-#ifdef QT_MAC_USE_COCOA
- // If we add a child to the unified toolbar, we have to redirect the painting.
- if (parentWidget && parentWidget->d_func() && parentWidget->d_func()->isInUnifiedToolbar) {
- if (parentWidget->d_func()->unifiedSurface) {
- QWidget *toolbar = parentWidget->d_func()->toolbar_ancestor;
- parentWidget->d_func()->unifiedSurface->recursiveRedirect(toolbar, toolbar, toolbar->d_func()->toolbar_offset);
- }
- }
-#endif // QT_MAC_USE_COCOA
-}
-
-
-
-void QWidgetPrivate::createRecursively()
-{
- Q_Q(QWidget);
- q->create(0, true, true);
- for (int i = 0; i < children.size(); ++i) {
- QWidget *child = qobject_cast<QWidget *>(children.at(i));
- if (child && !child->isHidden() && !child->isWindow() && !child->testAttribute(Qt::WA_WState_Created))
- child->d_func()->createRecursively();
- }
-}
-
-
-
-
-/*!
- Creates a new widget window if \a window is 0, otherwise sets the
- widget's window to \a window.
-
- Initializes the window (sets the geometry etc.) if \a
- initializeWindow is true. If \a initializeWindow is false, no
- initialization is performed. This parameter only makes sense if \a
- window is a valid window.
-
- Destroys the old window if \a destroyOldWindow is true. If \a
- destroyOldWindow is false, you are responsible for destroying the
- window yourself (using platform native code).
-
- The QWidget constructor calls create(0,true,true) to create a
- window for this widget.
-*/
-
-void QWidget::create(WId window, bool initializeWindow, bool destroyOldWindow)
-{
- Q_D(QWidget);
- if (testAttribute(Qt::WA_WState_Created) && window == 0 && internalWinId())
- return;
-
- if (d->data.in_destructor)
- return;
-
- Qt::WindowType type = windowType();
- Qt::WindowFlags &flags = data->window_flags;
-
- if ((type == Qt::Widget || type == Qt::SubWindow) && !parentWidget()) {
- type = Qt::Window;
- flags |= Qt::Window;
- }
-
-#ifndef Q_WS_QPA
- if (QWidget *parent = parentWidget()) {
- if (type & Qt::Window) {
- if (!parent->testAttribute(Qt::WA_WState_Created))
- parent->createWinId();
- } else if (testAttribute(Qt::WA_NativeWindow) && !parent->internalWinId()
- && !testAttribute(Qt::WA_DontCreateNativeAncestors)) {
- // We're about to create a native child widget that doesn't have a native parent;
- // enforce a native handle for the parent unless the Qt::WA_DontCreateNativeAncestors
- // attribute is set.
- d->createWinId(window);
- // Nothing more to do.
- Q_ASSERT(testAttribute(Qt::WA_WState_Created));
- Q_ASSERT(internalWinId());
- return;
- }
- }
-#endif //Q_WS_QPA
-
-#ifdef QT3_SUPPORT
- if (flags & Qt::WStaticContents)
- setAttribute(Qt::WA_StaticContents);
- if (flags & Qt::WDestructiveClose)
- setAttribute(Qt::WA_DeleteOnClose);
- if (flags & Qt::WShowModal)
- setWindowModality(Qt::ApplicationModal);
- if (flags & Qt::WMouseNoMask)
- setAttribute(Qt::WA_MouseNoMask);
- if (flags & Qt::WGroupLeader)
- setAttribute(Qt::WA_GroupLeader);
- if (flags & Qt::WNoMousePropagation)
- setAttribute(Qt::WA_NoMousePropagation);
-#endif
-
- static int paintOnScreenEnv = -1;
- if (paintOnScreenEnv == -1)
- paintOnScreenEnv = qgetenv("QT_ONSCREEN_PAINT").toInt() > 0 ? 1 : 0;
- if (paintOnScreenEnv == 1)
- setAttribute(Qt::WA_PaintOnScreen);
-
- if (QApplicationPrivate::testAttribute(Qt::AA_NativeWindows))
- setAttribute(Qt::WA_NativeWindow);
-
-#ifdef ALIEN_DEBUG
- qDebug() << "QWidget::create:" << this << "parent:" << parentWidget()
- << "Alien?" << !testAttribute(Qt::WA_NativeWindow);
-#endif
-
-#if defined (Q_WS_WIN) && !defined(QT_NO_DRAGANDDROP)
- // Unregister the dropsite (if already registered) before we
- // re-create the widget with a native window.
- if (testAttribute(Qt::WA_WState_Created) && !internalWinId() && testAttribute(Qt::WA_NativeWindow)
- && d->extra && d->extra->dropTarget) {
- d->registerDropSite(false);
- }
-#endif // defined (Q_WS_WIN) && !defined(QT_NO_DRAGANDDROP)
-
- d->updateIsOpaque();
-
- setAttribute(Qt::WA_WState_Created); // set created flag
- d->create_sys(window, initializeWindow, destroyOldWindow);
-
- // a real toplevel window needs a backing store
- if (isWindow() && windowType() != Qt::Desktop) {
- d->topData()->backingStore.destroy();
- if (hasBackingStoreSupport())
- d->topData()->backingStore.create(this);
- }
-
- d->setModal_sys();
-
- if (!isWindow() && parentWidget() && parentWidget()->testAttribute(Qt::WA_DropSiteRegistered))
- setAttribute(Qt::WA_DropSiteRegistered, true);
-
-#ifdef QT_EVAL
- extern void qt_eval_init_widget(QWidget *w);
- qt_eval_init_widget(this);
-#endif
-
- // need to force the resting of the icon after changing parents
- if (testAttribute(Qt::WA_SetWindowIcon))
- d->setWindowIcon_sys(true);
- if (isWindow() && !d->topData()->iconText.isEmpty())
- d->setWindowIconText_helper(d->topData()->iconText);
- if (isWindow() && !d->topData()->caption.isEmpty())
- d->setWindowTitle_helper(d->topData()->caption);
- if (windowType() != Qt::Desktop) {
- d->updateSystemBackground();
-
- if (isWindow() && !testAttribute(Qt::WA_SetWindowIcon))
- d->setWindowIcon_sys();
- }
-}
-
-/*!
- Destroys the widget.
-
- All this widget's children are deleted first. The application
- exits if this widget is the main widget.
-*/
-
-QWidget::~QWidget()
-{
- Q_D(QWidget);
- d->data.in_destructor = true;
-
-#if defined (QT_CHECK_STATE)
- if (paintingActive())
- qWarning("QWidget: %s (%s) deleted while being painted", className(), name());
-#endif
-
-#ifndef QT_NO_GESTURES
- foreach (Qt::GestureType type, d->gestureContext.keys())
- ungrabGesture(type);
-#endif
-
- // force acceptDrops false before winId is destroyed.
- d->registerDropSite(false);
-
-#ifndef QT_NO_ACTION
- // remove all actions from this widget
- for (int i = 0; i < d->actions.size(); ++i) {
- QActionPrivate *apriv = d->actions.at(i)->d_func();
- apriv->widgets.removeAll(this);
- }
- d->actions.clear();
-#endif
-
-#ifndef QT_NO_SHORTCUT
- // Remove all shortcuts grabbed by this
- // widget, unless application is closing
- if (!QApplicationPrivate::is_app_closing && testAttribute(Qt::WA_GrabbedShortcut))
- qApp->d_func()->shortcutMap.removeShortcut(0, this, QKeySequence());
-#endif
-
- // delete layout while we still are a valid widget
- delete d->layout;
- d->layout = 0;
- // Remove myself from focus list
-
- Q_ASSERT(d->focus_next->d_func()->focus_prev == this);
- Q_ASSERT(d->focus_prev->d_func()->focus_next == this);
-
- if (d->focus_next != this) {
- d->focus_next->d_func()->focus_prev = d->focus_prev;
- d->focus_prev->d_func()->focus_next = d->focus_next;
- d->focus_next = d->focus_prev = 0;
- }
-
-#ifdef QT3_SUPPORT
- if (QApplicationPrivate::main_widget == this) { // reset main widget
- QApplicationPrivate::main_widget = 0;
- QApplication::quit();
- }
-#endif
-
- QT_TRY {
- clearFocus();
- } QT_CATCH(...) {
- // swallow this problem because we are in a destructor
- }
-
- d->setDirtyOpaqueRegion();
-
- if (isWindow() && isVisible() && internalWinId()) {
- QT_TRY {
- d->close_helper(QWidgetPrivate::CloseNoEvent);
- } QT_CATCH(...) {
- // if we're out of memory, at least hide the window.
- QT_TRY {
- hide();
- } QT_CATCH(...) {
- // and if that also doesn't work, then give up
- }
- }
- }
-
-#if defined(Q_WS_WIN) || defined(Q_WS_X11)|| defined(Q_WS_MAC)
- else if (!internalWinId() && isVisible()) {
- qApp->d_func()->sendSyntheticEnterLeave(this);
- }
-#elif defined(Q_WS_QWS) || defined(Q_WS_QPA)
- else if (isVisible()) {
- qApp->d_func()->sendSyntheticEnterLeave(this);
- }
-#endif
-
-#ifdef Q_OS_SYMBIAN
- if (d->extra && d->extra->topextra && d->extra->topextra->backingStore) {
- // Okay, we are about to destroy the top-level window that owns
- // the backing store. Make sure we delete the backing store right away
- // before the window handle is invalid. This is important because
- // the backing store will delete its window surface, which may or may
- // not have a reference to this widget that will be used later to
- // notify the window it no longer has a surface.
- d->extra->topextra->backingStore.destroy();
- }
-#endif
- if (QWidgetBackingStore *bs = d->maybeBackingStore()) {
- bs->removeDirtyWidget(this);
- if (testAttribute(Qt::WA_StaticContents))
- bs->removeStaticWidget(this);
- }
-
- delete d->needsFlush;
- d->needsFlush = 0;
-
- // set all QPointers for this object to zero
- if (d->hasGuards)
- QObjectPrivate::clearGuards(this);
-
- if (d->declarativeData) {
- QAbstractDeclarativeData::destroyed(d->declarativeData, this);
- d->declarativeData = 0; // don't activate again in ~QObject
- }
-
-#ifdef QT_MAC_USE_COCOA
- // QCocoaView holds a pointer back to this widget. Clear it now
- // to make sure it's not followed later on. The lifetime of the
- // QCocoaView might exceed the lifetime of this widget in cases
- // where Cocoa itself holds references to it.
- extern void qt_mac_clearCocoaViewQWidgetPointers(QWidget *);
- qt_mac_clearCocoaViewQWidgetPointers(this);
-#endif
-
- if (!d->children.isEmpty())
- d->deleteChildren();
-
-#ifndef QT_NO_ACCESSIBILITY
- QAccessible::updateAccessibility(this, 0, QAccessible::ObjectDestroyed);
-#endif
-
- QApplication::removePostedEvents(this);
-
- QT_TRY {
- destroy(); // platform-dependent cleanup
- } QT_CATCH(...) {
- // if this fails we can't do anything about it but at least we are not allowed to throw.
- }
- --QWidgetPrivate::instanceCounter;
-
- if (QWidgetPrivate::allWidgets) // might have been deleted by ~QApplication
- QWidgetPrivate::allWidgets->remove(this);
-
- QT_TRY {
- QEvent e(QEvent::Destroy);
- QCoreApplication::sendEvent(this, &e);
- } QT_CATCH(const std::exception&) {
- // if this fails we can't do anything about it but at least we are not allowed to throw.
- }
-}
-
-int QWidgetPrivate::instanceCounter = 0; // Current number of widget instances
-int QWidgetPrivate::maxInstances = 0; // Maximum number of widget instances
-
-void QWidgetPrivate::setWinId(WId id) // set widget identifier
-{
- Q_Q(QWidget);
- // 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);
- }
-
- const WId oldWinId = data.winid;
-
- data.winid = id;
-#if defined(Q_WS_X11)
- hd = id; // X11: hd == ident
-#endif
- if (mapper && id && !userDesktopWidget) {
- mapper->insert(data.winid, q);
- }
-
- if(oldWinId != id) {
- QEvent e(QEvent::WinIdChange);
- QCoreApplication::sendEvent(q, &e);
- }
-}
-
-void QWidgetPrivate::createTLExtra()
-{
- if (!extra)
- createExtra();
- if (!extra->topextra) {
- QTLWExtra* x = extra->topextra = new QTLWExtra;
- x->icon = 0;
- x->iconPixmap = 0;
- x->windowSurface = 0;
- x->sharedPainter = 0;
- x->incw = x->inch = 0;
- x->basew = x->baseh = 0;
- x->frameStrut.setCoords(0, 0, 0, 0);
- x->normalGeometry = QRect(0,0,-1,-1);
- x->savedFlags = 0;
- x->opacity = 255;
- x->posFromMove = false;
- x->sizeAdjusted = false;
- x->inTopLevelResize = false;
- x->inRepaint = false;
- x->embedded = 0;
-#ifdef Q_WS_MAC
-#ifdef QT_MAC_USE_COCOA
- x->wasMaximized = false;
-#endif // QT_MAC_USE_COCOA
-#endif // Q_WS_MAC
- createTLSysExtra();
-#ifdef QWIDGET_EXTRA_DEBUG
- static int count = 0;
- qDebug() << "tlextra" << ++count;
-#endif
-#if defined(Q_WS_QPA)
- x->platformWindow = 0;
- x->platformWindowFormat = QPlatformWindowFormat::defaultFormat();
- x->screenIndex = 0;
-#endif
- }
-}
-
-/*!
- \internal
- Creates the widget extra data.
-*/
-
-void QWidgetPrivate::createExtra()
-{
- if (!extra) { // if not exists
- extra = new QWExtra;
- extra->glContext = 0;
- extra->topextra = 0;
-#ifndef QT_NO_GRAPHICSVIEW
- extra->proxyWidget = 0;
-#endif
-#ifndef QT_NO_CURSOR
- extra->curs = 0;
-#endif
- extra->minw = 0;
- extra->minh = 0;
- extra->maxw = QWIDGETSIZE_MAX;
- extra->maxh = QWIDGETSIZE_MAX;
- extra->customDpiX = 0;
- extra->customDpiY = 0;
- extra->explicitMinSize = 0;
- extra->explicitMaxSize = 0;
- extra->autoFillBackground = 0;
- extra->nativeChildrenForced = 0;
- extra->inRenderWithPainter = 0;
- extra->hasMask = 0;
- createSysExtra();
-#ifdef QWIDGET_EXTRA_DEBUG
- static int count = 0;
- qDebug() << "extra" << ++count;
-#endif
- }
-}
-
-
-/*!
- \internal
- Deletes the widget extra data.
-*/
-
-void QWidgetPrivate::deleteExtra()
-{
- if (extra) { // if exists
-#ifndef QT_NO_CURSOR
- delete extra->curs;
-#endif
- deleteSysExtra();
-#ifndef QT_NO_STYLE_STYLESHEET
- // dereference the stylesheet style
- if (QStyleSheetStyle *proxy = qobject_cast<QStyleSheetStyle *>(extra->style))
- proxy->deref();
-#endif
- if (extra->topextra) {
- deleteTLSysExtra();
- extra->topextra->backingStore.destroy();
- delete extra->topextra->icon;
- delete extra->topextra->iconPixmap;
-#if defined(Q_WS_QWS) && !defined(QT_NO_QWS_MANAGER)
- delete extra->topextra->qwsManager;
-#endif
- delete extra->topextra->windowSurface;
- delete extra->topextra;
- }
- delete extra;
- // extra->xic destroyed in QWidget::destroy()
- extra = 0;
- }
-}
-
-/*
- Returns true if there are widgets above this which overlap with
- \a rect, which is in parent's coordinate system (same as crect).
-*/
-
-bool QWidgetPrivate::isOverlapped(const QRect &rect) const
-{
- Q_Q(const QWidget);
-
- const QWidget *w = q;
- QRect r = rect;
- while (w) {
- if (w->isWindow())
- return false;
- QWidgetPrivate *pd = w->parentWidget()->d_func();
- bool above = false;
- for (int i = 0; i < pd->children.size(); ++i) {
- QWidget *sibling = qobject_cast<QWidget *>(pd->children.at(i));
- if (!sibling || !sibling->isVisible() || sibling->isWindow())
- continue;
- if (!above) {
- above = (sibling == w);
- continue;
- }
-
- if (qRectIntersects(sibling->d_func()->effectiveRectFor(sibling->data->crect), r)) {
- const QWExtra *siblingExtra = sibling->d_func()->extra;
- if (siblingExtra && siblingExtra->hasMask && !sibling->d_func()->graphicsEffect
- && !siblingExtra->mask.translated(sibling->data->crect.topLeft()).intersects(r)) {
- continue;
- }
- return true;
- }
- }
- w = w->parentWidget();
- r.translate(pd->data.crect.topLeft());
- }
- return false;
-}
-
-void QWidgetPrivate::syncBackingStore()
-{
- if (paintOnScreen()) {
- repaint_sys(dirty);
- dirty = QRegion();
- } else if (QWidgetBackingStore *bs = maybeBackingStore()) {
- bs->sync();
- }
-}
-
-void QWidgetPrivate::syncBackingStore(const QRegion &region)
-{
- if (paintOnScreen())
- repaint_sys(region);
- else if (QWidgetBackingStore *bs = maybeBackingStore()) {
- bs->sync(q_func(), region);
- }
-}
-
-void QWidgetPrivate::setUpdatesEnabled_helper(bool enable)
-{
- Q_Q(QWidget);
-
- if (enable && !q->isWindow() && q->parentWidget() && !q->parentWidget()->updatesEnabled())
- return; // nothing we can do
-
- if (enable != q->testAttribute(Qt::WA_UpdatesDisabled))
- return; // nothing to do
-
- q->setAttribute(Qt::WA_UpdatesDisabled, !enable);
- if (enable)
- q->update();
-
- Qt::WidgetAttribute attribute = enable ? Qt::WA_ForceUpdatesDisabled : Qt::WA_UpdatesDisabled;
- for (int i = 0; i < children.size(); ++i) {
- QWidget *w = qobject_cast<QWidget *>(children.at(i));
- if (w && !w->isWindow() && !w->testAttribute(attribute))
- w->d_func()->setUpdatesEnabled_helper(enable);
- }
-}
-
-/*!
- \internal
-
- Propagate this widget's palette to all children, except style sheet
- widgets, and windows that don't enable window propagation (palettes don't
- normally propagate to windows).
-*/
-void QWidgetPrivate::propagatePaletteChange()
-{
- Q_Q(QWidget);
- // Propagate a new inherited mask to all children.
-#ifndef QT_NO_GRAPHICSVIEW
- if (!q->parentWidget() && extra && extra->proxyWidget) {
- QGraphicsProxyWidget *p = extra->proxyWidget;
- inheritedPaletteResolveMask = p->d_func()->inheritedPaletteResolveMask | p->palette().resolve();
- } else
-#endif //QT_NO_GRAPHICSVIEW
- if (q->isWindow() && !q->testAttribute(Qt::WA_WindowPropagation)) {
- inheritedPaletteResolveMask = 0;
- }
- int mask = data.pal.resolve() | inheritedPaletteResolveMask;
-
- QEvent pc(QEvent::PaletteChange);
- QApplication::sendEvent(q, &pc);
- for (int i = 0; i < children.size(); ++i) {
- QWidget *w = qobject_cast<QWidget*>(children.at(i));
- if (w && !w->testAttribute(Qt::WA_StyleSheet)
- && (!w->isWindow() || w->testAttribute(Qt::WA_WindowPropagation))) {
- QWidgetPrivate *wd = w->d_func();
- wd->inheritedPaletteResolveMask = mask;
- wd->resolvePalette();
- }
- }
-#if defined(QT3_SUPPORT)
- q->paletteChange(q->palette()); // compatibility
-#endif
-}
-
-/*
- Returns the widget's clipping rectangle.
-*/
-QRect QWidgetPrivate::clipRect() const
-{
- Q_Q(const QWidget);
- const QWidget * w = q;
- if (!w->isVisible())
- return QRect();
- QRect r = effectiveRectFor(q->rect());
- int ox = 0;
- int oy = 0;
- while (w
- && w->isVisible()
- && !w->isWindow()
- && w->parentWidget()) {
- ox -= w->x();
- oy -= w->y();
- w = w->parentWidget();
- r &= QRect(ox, oy, w->width(), w->height());
- }
- return r;
-}
-
-/*
- Returns the widget's clipping region (without siblings).
-*/
-QRegion QWidgetPrivate::clipRegion() const
-{
- Q_Q(const QWidget);
- if (!q->isVisible())
- return QRegion();
- QRegion r(q->rect());
- const QWidget * w = q;
- const QWidget *ignoreUpTo;
- int ox = 0;
- int oy = 0;
- while (w
- && w->isVisible()
- && !w->isWindow()
- && w->parentWidget()) {
- ox -= w->x();
- oy -= w->y();
- ignoreUpTo = w;
- w = w->parentWidget();
- r &= QRegion(ox, oy, w->width(), w->height());
-
- int i = 0;
- while(w->d_func()->children.at(i++) != static_cast<const QObject *>(ignoreUpTo))
- ;
- for ( ; i < w->d_func()->children.size(); ++i) {
- if(QWidget *sibling = qobject_cast<QWidget *>(w->d_func()->children.at(i))) {
- if(sibling->isVisible() && !sibling->isWindow()) {
- QRect siblingRect(ox+sibling->x(), oy+sibling->y(),
- sibling->width(), sibling->height());
- if (qRectIntersects(siblingRect, q->rect()))
- r -= QRegion(siblingRect);
- }
- }
- }
- }
- return r;
-}
-
-#ifndef QT_NO_GRAPHICSEFFECT
-void QWidgetPrivate::invalidateGraphicsEffectsRecursively()
-{
- Q_Q(QWidget);
- QWidget *w = q;
- do {
- if (w->graphicsEffect()) {
- QWidgetEffectSourcePrivate *sourced =
- static_cast<QWidgetEffectSourcePrivate *>(w->graphicsEffect()->source()->d_func());
- if (!sourced->updateDueToGraphicsEffect)
- w->graphicsEffect()->source()->d_func()->invalidateCache();
- }
- w = w->parentWidget();
- } while (w);
-}
-#endif //QT_NO_GRAPHICSEFFECT
-
-void QWidgetPrivate::setDirtyOpaqueRegion()
-{
- Q_Q(QWidget);
-
- dirtyOpaqueChildren = true;
-
-#ifndef QT_NO_GRAPHICSEFFECT
- invalidateGraphicsEffectsRecursively();
-#endif //QT_NO_GRAPHICSEFFECT
-
- if (q->isWindow())
- return;
-
- QWidget *parent = q->parentWidget();
- if (!parent)
- return;
-
- // TODO: instead of setting dirtyflag, manipulate the dirtyregion directly?
- QWidgetPrivate *pd = parent->d_func();
- if (!pd->dirtyOpaqueChildren)
- pd->setDirtyOpaqueRegion();
-}
-
-const QRegion &QWidgetPrivate::getOpaqueChildren() const
-{
- if (!dirtyOpaqueChildren)
- return opaqueChildren;
-
- QWidgetPrivate *that = const_cast<QWidgetPrivate*>(this);
- that->opaqueChildren = QRegion();
-
- for (int i = 0; i < children.size(); ++i) {
- QWidget *child = qobject_cast<QWidget *>(children.at(i));
- if (!child || !child->isVisible() || child->isWindow())
- continue;
-
- const QPoint offset = child->geometry().topLeft();
- QWidgetPrivate *childd = child->d_func();
- QRegion r = childd->isOpaque ? child->rect() : childd->getOpaqueChildren();
- if (childd->extra && childd->extra->hasMask)
- r &= childd->extra->mask;
- if (r.isEmpty())
- continue;
- r.translate(offset);
- that->opaqueChildren += r;
- }
-
- that->opaqueChildren &= q_func()->rect();
- that->dirtyOpaqueChildren = false;
-
- return that->opaqueChildren;
-}
-
-void QWidgetPrivate::subtractOpaqueChildren(QRegion &source, const QRect &clipRect) const
-{
- if (children.isEmpty() || clipRect.isEmpty())
- return;
-
- const QRegion &r = getOpaqueChildren();
- if (!r.isEmpty())
- source -= (r & clipRect);
-}
-
-//subtract any relatives that are higher up than me --- this is too expensive !!!
-void QWidgetPrivate::subtractOpaqueSiblings(QRegion &sourceRegion, bool *hasDirtySiblingsAbove,
- bool alsoNonOpaque) const
-{
- Q_Q(const QWidget);
- static int disableSubtractOpaqueSiblings = qgetenv("QT_NO_SUBTRACTOPAQUESIBLINGS").toInt();
- if (disableSubtractOpaqueSiblings || q->isWindow())
- return;
-
-#ifdef QT_MAC_USE_COCOA
- if (q->d_func()->isInUnifiedToolbar)
- return;
-#endif // QT_MAC_USE_COCOA
-
- QRect clipBoundingRect;
- bool dirtyClipBoundingRect = true;
-
- QRegion parentClip;
- bool dirtyParentClip = true;
-
- QPoint parentOffset = data.crect.topLeft();
-
- const QWidget *w = q;
-
- while (w) {
- if (w->isWindow())
- break;
- QWidgetPrivate *pd = w->parentWidget()->d_func();
- const int myIndex = pd->children.indexOf(const_cast<QWidget *>(w));
- const QRect widgetGeometry = w->d_func()->effectiveRectFor(w->data->crect);
- for (int i = myIndex + 1; i < pd->children.size(); ++i) {
- QWidget *sibling = qobject_cast<QWidget *>(pd->children.at(i));
- if (!sibling || !sibling->isVisible() || sibling->isWindow())
- continue;
-
- const QRect siblingGeometry = sibling->d_func()->effectiveRectFor(sibling->data->crect);
- if (!qRectIntersects(siblingGeometry, widgetGeometry))
- continue;
-
- if (dirtyClipBoundingRect) {
- clipBoundingRect = sourceRegion.boundingRect();
- dirtyClipBoundingRect = false;
- }
-
- if (!qRectIntersects(siblingGeometry, clipBoundingRect.translated(parentOffset)))
- continue;
-
- if (dirtyParentClip) {
- parentClip = sourceRegion.translated(parentOffset);
- dirtyParentClip = false;
- }
-
- const QPoint siblingPos(sibling->data->crect.topLeft());
- const QRect siblingClipRect(sibling->d_func()->clipRect());
- QRegion siblingDirty(parentClip);
- siblingDirty &= (siblingClipRect.translated(siblingPos));
- const bool hasMask = sibling->d_func()->extra && sibling->d_func()->extra->hasMask
- && !sibling->d_func()->graphicsEffect;
- if (hasMask)
- siblingDirty &= sibling->d_func()->extra->mask.translated(siblingPos);
- if (siblingDirty.isEmpty())
- continue;
-
- if (sibling->d_func()->isOpaque || alsoNonOpaque) {
- if (hasMask) {
- siblingDirty.translate(-parentOffset);
- sourceRegion -= siblingDirty;
- } else {
- sourceRegion -= siblingGeometry.translated(-parentOffset);
- }
- } else {
- if (hasDirtySiblingsAbove)
- *hasDirtySiblingsAbove = true;
- if (sibling->d_func()->children.isEmpty())
- continue;
- QRegion opaqueSiblingChildren(sibling->d_func()->getOpaqueChildren());
- opaqueSiblingChildren.translate(-parentOffset + siblingPos);
- sourceRegion -= opaqueSiblingChildren;
- }
- if (sourceRegion.isEmpty())
- return;
-
- dirtyClipBoundingRect = true;
- dirtyParentClip = true;
- }
-
- w = w->parentWidget();
- parentOffset += pd->data.crect.topLeft();
- dirtyParentClip = true;
- }
-}
-
-void QWidgetPrivate::clipToEffectiveMask(QRegion &region) const
-{
- Q_Q(const QWidget);
-
- const QWidget *w = q;
- QPoint offset;
-
-#ifndef QT_NO_GRAPHICSEFFECT
- if (graphicsEffect) {
- w = q->parentWidget();
- offset -= data.crect.topLeft();
- }
-#endif //QT_NO_GRAPHICSEFFECT
-
- while (w) {
- const QWidgetPrivate *wd = w->d_func();
- if (wd->extra && wd->extra->hasMask)
- region &= (w != q) ? wd->extra->mask.translated(offset) : wd->extra->mask;
- if (w->isWindow())
- return;
- offset -= wd->data.crect.topLeft();
- w = w->parentWidget();
- }
-}
-
-bool QWidgetPrivate::paintOnScreen() const
-{
-#if defined(Q_WS_QWS)
- return false;
-#elif defined(QT_NO_BACKINGSTORE)
- return true;
-#else
- Q_Q(const QWidget);
- if (q->testAttribute(Qt::WA_PaintOnScreen)
- || (!q->isWindow() && q->window()->testAttribute(Qt::WA_PaintOnScreen))) {
- return true;
- }
-
- return !qt_enable_backingstore;
-#endif
-}
-
-void QWidgetPrivate::updateIsOpaque()
-{
- // hw: todo: only needed if opacity actually changed
- setDirtyOpaqueRegion();
-
-#ifndef QT_NO_GRAPHICSEFFECT
- if (graphicsEffect) {
- // ### We should probably add QGraphicsEffect::isOpaque at some point.
- setOpaque(false);
- return;
- }
-#endif //QT_NO_GRAPHICSEFFECT
-
- Q_Q(QWidget);
-#ifdef Q_WS_X11
- if (q->testAttribute(Qt::WA_X11OpenGLOverlay)) {
- setOpaque(false);
- return;
- }
-#endif
-
-#ifdef Q_WS_S60
- if (q->windowType() == Qt::Dialog && q->testAttribute(Qt::WA_TranslucentBackground)
- && S60->avkonComponentsSupportTransparency) {
- setOpaque(false);
- return;
- }
-#endif
-
- if (q->testAttribute(Qt::WA_OpaquePaintEvent) || q->testAttribute(Qt::WA_PaintOnScreen)) {
- setOpaque(true);
- return;
- }
-
- const QPalette &pal = q->palette();
-
- if (q->autoFillBackground()) {
- const QBrush &autoFillBrush = pal.brush(q->backgroundRole());
- if (autoFillBrush.style() != Qt::NoBrush && autoFillBrush.isOpaque()) {
- setOpaque(true);
- return;
- }
- }
-
- if (q->isWindow() && !q->testAttribute(Qt::WA_NoSystemBackground)) {
- const QBrush &windowBrush = q->palette().brush(QPalette::Window);
- if (windowBrush.style() != Qt::NoBrush && windowBrush.isOpaque()) {
- setOpaque(true);
- return;
- }
- }
- setOpaque(false);
-}
-
-void QWidgetPrivate::setOpaque(bool opaque)
-{
- if (isOpaque == opaque)
- return;
- isOpaque = opaque;
-#ifdef Q_WS_MAC
- macUpdateIsOpaque();
-#endif
-#ifdef Q_WS_X11
- x11UpdateIsOpaque();
-#endif
-#ifdef Q_WS_WIN
- winUpdateIsOpaque();
-#endif
-#ifdef Q_OS_SYMBIAN
- s60UpdateIsOpaque();
-#endif
-}
-
-void QWidgetPrivate::updateIsTranslucent()
-{
-#ifdef Q_WS_MAC
- macUpdateIsOpaque();
-#endif
-#ifdef Q_WS_X11
- x11UpdateIsOpaque();
-#endif
-#ifdef Q_WS_WIN
- winUpdateIsOpaque();
-#endif
-#ifdef Q_OS_SYMBIAN
- s60UpdateIsOpaque();
-#endif
-}
-
-/*!
- \fn void QPixmap::fill(const QWidget *widget, const QPoint &offset)
-
- Fills the pixmap with the \a widget's background color or pixmap
- according to the given offset.
-
- The QPoint \a offset defines a point in widget coordinates to
- which the pixmap's top-left pixel will be mapped to. This is only
- significant if the widget has a background pixmap; otherwise the
- pixmap will simply be filled with the background color of the
- widget.
-*/
-
-void QPixmap::fill( const QWidget *widget, const QPoint &off )
-{
- QPainter p(this);
- p.translate(-off);
- widget->d_func()->paintBackground(&p, QRect(off, size()));
-}
-
-static inline void fillRegion(QPainter *painter, const QRegion &rgn, const QBrush &brush)
-{
- Q_ASSERT(painter);
-
- if (brush.style() == Qt::TexturePattern) {
-#ifdef Q_WS_MAC
- // Optimize pattern filling on mac by using HITheme directly
- // when filling with the standard widget background.
- // Defined in qmacstyle_mac.cpp
- extern void qt_mac_fill_background(QPainter *painter, const QRegion &rgn, const QBrush &brush);
- qt_mac_fill_background(painter, rgn, brush);
-#else
-#if !defined(QT_NO_STYLE_S60)
- // Defined in qs60style.cpp
- extern bool qt_s60_fill_background(QPainter *painter, const QRegion &rgn, const QBrush &brush);
- if (!qt_s60_fill_background(painter, rgn, brush))
-#endif // !defined(QT_NO_STYLE_S60)
- {
- const QRect rect(rgn.boundingRect());
- painter->setClipRegion(rgn);
- painter->drawTiledPixmap(rect, brush.texture(), rect.topLeft());
- }
-#endif // Q_WS_MAC
-
- } else if (brush.gradient()
- && brush.gradient()->coordinateMode() == QGradient::ObjectBoundingMode) {
- painter->save();
- painter->setClipRegion(rgn);
- painter->fillRect(0, 0, painter->device()->width(), painter->device()->height(), brush);
- painter->restore();
- } else {
- const QVector<QRect> &rects = rgn.rects();
- for (int i = 0; i < rects.size(); ++i)
- painter->fillRect(rects.at(i), brush);
- }
-}
-
-void QWidgetPrivate::paintBackground(QPainter *painter, const QRegion &rgn, int flags) const
-{
- Q_Q(const QWidget);
-
-#ifndef QT_NO_SCROLLAREA
- bool resetBrushOrigin = false;
- QPointF oldBrushOrigin;
- //If we are painting the viewport of a scrollarea, we must apply an offset to the brush in case we are drawing a texture
- QAbstractScrollArea *scrollArea = qobject_cast<QAbstractScrollArea *>(parent);
- if (scrollArea && scrollArea->viewport() == q) {
- QObjectData *scrollPrivate = static_cast<QWidget *>(scrollArea)->d_ptr.data();
- QAbstractScrollAreaPrivate *priv = static_cast<QAbstractScrollAreaPrivate *>(scrollPrivate);
- oldBrushOrigin = painter->brushOrigin();
- resetBrushOrigin = true;
- painter->setBrushOrigin(-priv->contentsOffset());
-
- }
-#endif // QT_NO_SCROLLAREA
-
- const QBrush autoFillBrush = q->palette().brush(q->backgroundRole());
-
- if ((flags & DrawAsRoot) && !(q->autoFillBackground() && autoFillBrush.isOpaque())) {
- const QBrush bg = q->palette().brush(QPalette::Window);
-#ifdef Q_WS_QWS
- if (!(flags & DontSetCompositionMode) && painter->paintEngine()->hasFeature(QPaintEngine::PorterDuff))
- painter->setCompositionMode(QPainter::CompositionMode_Source); //copy alpha straight in
-#endif
- fillRegion(painter, rgn, bg);
- }
-
- if (q->autoFillBackground())
- fillRegion(painter, rgn, autoFillBrush);
-
- if (q->testAttribute(Qt::WA_StyledBackground)) {
- painter->setClipRegion(rgn);
- QStyleOption opt;
- opt.initFrom(q);
- q->style()->drawPrimitive(QStyle::PE_Widget, &opt, painter, q);
- }
-
-#ifndef QT_NO_SCROLLAREA
- if (resetBrushOrigin)
- painter->setBrushOrigin(oldBrushOrigin);
-#endif // QT_NO_SCROLLAREA
-}
-
-/*
- \internal
- This function is called when a widget is hidden or destroyed.
- It resets some application global pointers that should only refer active,
- visible widgets.
-*/
-
-#ifdef Q_WS_MAC
- extern QPointer<QWidget> qt_button_down;
-#else
- extern QWidget *qt_button_down;
-#endif
-
-void QWidgetPrivate::deactivateWidgetCleanup()
-{
- Q_Q(QWidget);
- // If this was the active application window, reset it
- if (QApplication::activeWindow() == q)
- QApplication::setActiveWindow(0);
- // If the is the active mouse press widget, reset it
- if (q == qt_button_down)
- qt_button_down = 0;
-}
-
-
-/*!
- Returns a pointer to the widget with window identifer/handle \a
- id.
-
- The window identifier type depends on the underlying window
- system, see \c qwindowdefs.h for the actual definition. If there
- is no widget with this identifier, 0 is returned.
-*/
-
-QWidget *QWidget::find(WId id)
-{
- return QWidgetPrivate::mapper ? QWidgetPrivate::mapper->value(id, 0) : 0;
-}
-
-
-
-/*!
- \fn WId QWidget::internalWinId() const
- \internal
- Returns the window system identifier of the widget, or 0 if the widget is not created yet.
-
-*/
-
-/*!
- \fn WId QWidget::winId() const
-
- Returns the window system identifier of the widget.
-
- Portable in principle, but if you use it you are probably about to
- do something non-portable. Be careful.
-
- If a widget is non-native (alien) and winId() is invoked on it, that widget
- will be provided a native handle.
-
- On Mac OS X, the type returned depends on which framework Qt was linked
- against. If Qt is using Carbon, the {WId} is actually an HIViewRef. If Qt
- is using Cocoa, {WId} is a pointer to an NSView.
-
- This value may change at run-time. An event with type QEvent::WinIdChange
- will be sent to the widget following a change in window system identifier.
-
- \sa find()
-*/
-WId QWidget::winId() const
-{
- if (!testAttribute(Qt::WA_WState_Created) || !internalWinId()) {
-#ifdef ALIEN_DEBUG
- qDebug() << "QWidget::winId: creating native window for" << this;
-#endif
- QWidget *that = const_cast<QWidget*>(this);
-#ifndef Q_WS_QPA
- that->setAttribute(Qt::WA_NativeWindow);
-#endif
- that->d_func()->createWinId();
- return that->data->winid;
- }
- return data->winid;
-}
-
-
-void QWidgetPrivate::createWinId(WId winid)
-{
- Q_Q(QWidget);
-
-#ifdef ALIEN_DEBUG
- qDebug() << "QWidgetPrivate::createWinId for" << q << winid;
-#endif
- const bool forceNativeWindow = q->testAttribute(Qt::WA_NativeWindow);
- if (!q->testAttribute(Qt::WA_WState_Created) || (forceNativeWindow && !q->internalWinId())) {
-#ifndef Q_WS_QPA
- if (!q->isWindow()) {
- QWidget *parent = q->parentWidget();
- QWidgetPrivate *pd = parent->d_func();
- if (forceNativeWindow && !q->testAttribute(Qt::WA_DontCreateNativeAncestors))
- parent->setAttribute(Qt::WA_NativeWindow);
- if (!parent->internalWinId()) {
- pd->createWinId();
- }
-
- for (int i = 0; i < pd->children.size(); ++i) {
- QWidget *w = qobject_cast<QWidget *>(pd->children.at(i));
- if (w && !w->isWindow() && (!w->testAttribute(Qt::WA_WState_Created)
- || (!w->internalWinId() && w->testAttribute(Qt::WA_NativeWindow)))) {
- if (w!=q) {
- w->create();
- } else {
- w->create(winid);
- // if the window has already been created, we
- // need to raise it to its proper stacking position
- if (winid)
- w->raise();
- }
- }
- }
- } else {
- q->create();
- }
-#else
- Q_UNUSED(winid);
- q->create();
-#endif //Q_WS_QPA
-
- }
-}
-
-
-/*!
-\internal
-Ensures that the widget has a window system identifier, i.e. that it is known to the windowing system.
-
-*/
-
-void QWidget::createWinId()
-{
- Q_D(QWidget);
-#ifdef ALIEN_DEBUG
- qDebug() << "QWidget::createWinId" << this;
-#endif
-// qWarning("QWidget::createWinId is obsolete, please fix your code.");
- d->createWinId();
-}
-
-/*!
- \since 4.4
-
- Returns the effective window system identifier of the widget, i.e. the
- native parent's window system identifier.
-
- If the widget is native, this function returns the native widget ID.
- Otherwise, the window ID of the first native parent widget, i.e., the
- top-level widget that contains this widget, is returned.
-
- \note We recommend that you do not store this value as it is likely to
- change at run-time.
-
- \sa nativeParentWidget()
-*/
-WId QWidget::effectiveWinId() const
-{
- WId id = internalWinId();
- if (id || !testAttribute(Qt::WA_WState_Created))
- return id;
- QWidget *realParent = nativeParentWidget();
- if (!realParent && d_func()->inSetParent) {
- // In transitional state. This is really just a workaround. The real problem
- // is that QWidgetPrivate::setParent_sys (platform specific code) first sets
- // the window id to 0 (setWinId(0)) before it sets the Qt::WA_WState_Created
- // attribute to false. The correct way is to do it the other way around, and
- // in that case the Qt::WA_WState_Created logic above will kick in and
- // return 0 whenever the widget is in a transitional state. However, changing
- // the original logic for all platforms is far more intrusive and might
- // break existing applications.
- // Note: The widget can only be in a transitional state when changing its
- // parent -- everything else is an internal error -- hence explicitly checking
- // against 'inSetParent' rather than doing an unconditional return whenever
- // 'realParent' is 0 (which may cause strange artifacts and headache later).
- return 0;
- }
- // This widget *must* have a native parent widget.
- Q_ASSERT(realParent);
- Q_ASSERT(realParent->internalWinId());
- return realParent->internalWinId();
-}
-
-#ifndef QT_NO_STYLE_STYLESHEET
-
-/*!
- \property QWidget::styleSheet
- \brief the widget's style sheet
- \since 4.2
-
- The style sheet contains a textual description of customizations to the
- widget's style, as described in the \l{Qt Style Sheets} document.
-
- Since Qt 4.5, Qt style sheets fully supports Mac OS X.
-
- \warning Qt style sheets are currently not supported for custom QStyle
- subclasses. We plan to address this in some future release.
-
- \sa setStyle(), QApplication::styleSheet, {Qt Style Sheets}
-*/
-QString QWidget::styleSheet() const
-{
- Q_D(const QWidget);
- if (!d->extra)
- return QString();
- return d->extra->styleSheet;
-}
-
-void QWidget::setStyleSheet(const QString& styleSheet)
-{
- Q_D(QWidget);
- d->createExtra();
-
- QStyleSheetStyle *proxy = qobject_cast<QStyleSheetStyle *>(d->extra->style);
- d->extra->styleSheet = styleSheet;
- if (styleSheet.isEmpty()) { // stylesheet removed
- if (!proxy)
- return;
-
- d->inheritStyle();
- return;
- }
-
- if (proxy) { // style sheet update
- proxy->repolish(this);
- return;
- }
-
- if (testAttribute(Qt::WA_SetStyle)) {
- d->setStyle_helper(new QStyleSheetStyle(d->extra->style), true);
- } else {
- d->setStyle_helper(new QStyleSheetStyle(0), true);
- }
-}
-
-#endif // QT_NO_STYLE_STYLESHEET
-
-/*!
- \sa QWidget::setStyle(), QApplication::setStyle(), QApplication::style()
-*/
-
-QStyle *QWidget::style() const
-{
- Q_D(const QWidget);
-
- if (d->extra && d->extra->style)
- return d->extra->style;
- return QApplication::style();
-}
-
-/*!
- Sets the widget's GUI style to \a style. The ownership of the style
- object is not transferred.
-
- If no style is set, the widget uses the application's style,
- QApplication::style() instead.
-
- Setting a widget's style has no effect on existing or future child
- widgets.
-
- \warning This function is particularly useful for demonstration
- purposes, where you want to show Qt's styling capabilities. Real
- applications should avoid it and use one consistent GUI style
- instead.
-
- \warning Qt style sheets are currently not supported for custom QStyle
- subclasses. We plan to address this in some future release.
-
- \sa style(), QStyle, QApplication::style(), QApplication::setStyle()
-*/
-
-void QWidget::setStyle(QStyle *style)
-{
- Q_D(QWidget);
- setAttribute(Qt::WA_SetStyle, style != 0);
- d->createExtra();
-#ifndef QT_NO_STYLE_STYLESHEET
- if (QStyleSheetStyle *proxy = qobject_cast<QStyleSheetStyle *>(style)) {
- //if for some reason someone try to set a QStyleSheetStyle, ref it
- //(this may happen for exemple in QButtonDialogBox which propagates its style)
- proxy->ref();
- d->setStyle_helper(style, false);
- } else if (qobject_cast<QStyleSheetStyle *>(d->extra->style) || !qApp->styleSheet().isEmpty()) {
- // if we have an application stylesheet or have a proxy already, propagate
- d->setStyle_helper(new QStyleSheetStyle(style), true);
- } else
-#endif
- d->setStyle_helper(style, false);
-}
-
-void QWidgetPrivate::setStyle_helper(QStyle *newStyle, bool propagate, bool
-#ifdef Q_WS_MAC
- metalHack
-#endif
- )
-{
- Q_Q(QWidget);
- QStyle *oldStyle = q->style();
-#ifndef QT_NO_STYLE_STYLESHEET
- QWeakPointer<QStyle> origStyle;
-#endif
-
-#ifdef Q_WS_MAC
- // the metalhack boolean allows Qt/Mac to do a proper re-polish depending
- // on how the Qt::WA_MacBrushedMetal attribute is set. It is only ever
- // set when changing that attribute and passes the widget's CURRENT style.
- // therefore no need to do a reassignment.
- if (!metalHack)
-#endif
- {
- createExtra();
-
-#ifndef QT_NO_STYLE_STYLESHEET
- origStyle = extra->style.data();
-#endif
- extra->style = newStyle;
- }
-
- // repolish
- if (q->windowType() != Qt::Desktop) {
- if (polished) {
- oldStyle->unpolish(q);
-#ifdef Q_WS_MAC
- if (metalHack)
- macUpdateMetalAttribute();
-#endif
- q->style()->polish(q);
-#ifdef Q_WS_MAC
- } else if (metalHack) {
- macUpdateMetalAttribute();
-#endif
- }
- }
-
- if (propagate) {
- for (int i = 0; i < children.size(); ++i) {
- QWidget *c = qobject_cast<QWidget*>(children.at(i));
- if (c)
- c->d_func()->inheritStyle();
- }
- }
-
-#ifndef QT_NO_STYLE_STYLESHEET
- if (!qobject_cast<QStyleSheetStyle*>(newStyle)) {
- if (const QStyleSheetStyle* cssStyle = qobject_cast<QStyleSheetStyle*>(origStyle.data())) {
- cssStyle->clearWidgetFont(q);
- }
- }
-#endif
-
- QEvent e(QEvent::StyleChange);
- QApplication::sendEvent(q, &e);
-#ifdef QT3_SUPPORT
- q->styleChange(*oldStyle);
-#endif
-
-#ifndef QT_NO_STYLE_STYLESHEET
- // dereference the old stylesheet style
- if (QStyleSheetStyle *proxy = qobject_cast<QStyleSheetStyle *>(origStyle.data()))
- proxy->deref();
-#endif
-}
-
-// Inherits style from the current parent and propagates it as necessary
-void QWidgetPrivate::inheritStyle()
-{
-#ifndef QT_NO_STYLE_STYLESHEET
- Q_Q(QWidget);
-
- QStyleSheetStyle *proxy = extra ? qobject_cast<QStyleSheetStyle *>(extra->style) : 0;
-
- if (!q->styleSheet().isEmpty()) {
- Q_ASSERT(proxy);
- proxy->repolish(q);
- return;
- }
-
- QStyle *origStyle = proxy ? proxy->base : (extra ? (QStyle*)extra->style : 0);
- QWidget *parent = q->parentWidget();
- QStyle *parentStyle = (parent && parent->d_func()->extra) ? (QStyle*)parent->d_func()->extra->style : 0;
- // If we have stylesheet on app or parent has stylesheet style, we need
- // to be running a proxy
- if (!qApp->styleSheet().isEmpty() || qobject_cast<QStyleSheetStyle *>(parentStyle)) {
- QStyle *newStyle = parentStyle;
- if (q->testAttribute(Qt::WA_SetStyle))
- newStyle = new QStyleSheetStyle(origStyle);
- else if (QStyleSheetStyle *newProxy = qobject_cast<QStyleSheetStyle *>(parentStyle))
- newProxy->ref();
-
- setStyle_helper(newStyle, true);
- return;
- }
-
- // So, we have no stylesheet on parent/app and we have an empty stylesheet
- // we just need our original style back
- if (origStyle == (extra ? (QStyle*)extra->style : 0)) // is it any different?
- return;
-
- // We could have inherited the proxy from our parent (which has a custom style)
- // In such a case we need to start following the application style (i.e revert
- // the propagation behavior of QStyleSheetStyle)
- if (!q->testAttribute(Qt::WA_SetStyle))
- origStyle = 0;
-
- setStyle_helper(origStyle, true);
-#endif // QT_NO_STYLE_STYLESHEET
-}
-
-#ifdef QT3_SUPPORT
-/*!
- \overload
-
- Sets the widget's GUI style to \a style using the QStyleFactory.
-*/
-QStyle* QWidget::setStyle(const QString &style)
-{
- QStyle *s = QStyleFactory::create(style);
- setStyle(s);
- return s;
-}
-#endif
-
-/*!
- \fn bool QWidget::isWindow() const
-
- Returns true if the widget is an independent window, otherwise
- returns false.
-
- A window is a widget that isn't visually the child of any other
- widget and that usually has a frame and a
- \l{QWidget::setWindowTitle()}{window title}.
-
- A window can have a \l{QWidget::parentWidget()}{parent widget}.
- It will then be grouped with its parent and deleted when the
- parent is deleted, minimized when the parent is minimized etc. If
- supported by the window manager, it will also have a common
- taskbar entry with its parent.
-
- QDialog and QMainWindow widgets are by default windows, even if a
- parent widget is specified in the constructor. This behavior is
- specified by the Qt::Window flag.
-
- \sa window(), isModal(), parentWidget()
-*/
-
-/*!
- \property QWidget::modal
- \brief whether the widget is a modal widget
-
- This property only makes sense for windows. A modal widget
- prevents widgets in all other windows from getting any input.
-
- By default, this property is false.
-
- \sa isWindow(), windowModality, QDialog
-*/
-
-/*!
- \property QWidget::windowModality
- \brief which windows are blocked by the modal widget
- \since 4.1
-
- This property only makes sense for windows. A modal widget
- prevents widgets in other windows from getting input. The value of
- this property controls which windows are blocked when the widget
- is visible. Changing this property while the window is visible has
- no effect; you must hide() the widget first, then show() it again.
-
- By default, this property is Qt::NonModal.
-
- \sa isWindow(), QWidget::modal, QDialog
-*/
-
-Qt::WindowModality QWidget::windowModality() const
-{
- return static_cast<Qt::WindowModality>(data->window_modality);
-}
-
-void QWidget::setWindowModality(Qt::WindowModality windowModality)
-{
- data->window_modality = windowModality;
- // setModal_sys() will be called by setAttribute()
- setAttribute(Qt::WA_ShowModal, (data->window_modality != Qt::NonModal));
- setAttribute(Qt::WA_SetWindowModality, true);
-}
-
-/*!
- \fn bool QWidget::underMouse() const
-
- Returns true if the widget is under the mouse cursor; otherwise
- returns false.
-
- This value is not updated properly during drag and drop
- operations.
-
- \sa enterEvent(), leaveEvent()
-*/
-
-/*!
- \property QWidget::minimized
- \brief whether this widget is minimized (iconified)
-
- This property is only relevant for windows.
-
- By default, this property is false.
-
- \sa showMinimized(), visible, show(), hide(), showNormal(), maximized
-*/
-bool QWidget::isMinimized() const
-{ return data->window_state & Qt::WindowMinimized; }
-
-/*!
- Shows the widget minimized, as an icon.
-
- Calling this function only affects \l{isWindow()}{windows}.
-
- \sa showNormal(), showMaximized(), show(), hide(), isVisible(),
- isMinimized()
-*/
-void QWidget::showMinimized()
-{
- bool isMin = isMinimized();
- if (isMin && isVisible())
- return;
-
- ensurePolished();
-#ifdef QT3_SUPPORT
- if (parent())
- QApplication::sendPostedEvents(parent(), QEvent::ChildInserted);
-#endif
-
- if (!isMin)
- setWindowState((windowState() & ~Qt::WindowActive) | Qt::WindowMinimized);
- show();
-}
-
-/*!
- \property QWidget::maximized
- \brief whether this widget is maximized
-
- This property is only relevant for windows.
-
- \note Due to limitations on some window systems, this does not always
- report the expected results (e.g., if the user on X11 maximizes the
- window via the window manager, Qt has no way of distinguishing this
- from any other resize). This is expected to improve as window manager
- protocols evolve.
-
- By default, this property is false.
-
- \sa windowState(), showMaximized(), visible, show(), hide(), showNormal(), minimized
-*/
-bool QWidget::isMaximized() const
-{ return data->window_state & Qt::WindowMaximized; }
-
-
-
-/*!
- Returns the current window state. The window state is a OR'ed
- combination of Qt::WindowState: Qt::WindowMinimized,
- Qt::WindowMaximized, Qt::WindowFullScreen, and Qt::WindowActive.
-
- \sa Qt::WindowState setWindowState()
- */
-Qt::WindowStates QWidget::windowState() const
-{
- return Qt::WindowStates(data->window_state);
-}
-
-/*!\internal
-
- The function sets the window state on child widgets similar to
- setWindowState(). The difference is that the window state changed
- event has the isOverride() flag set. It exists mainly to keep
- Q3Workspace working.
- */
-void QWidget::overrideWindowState(Qt::WindowStates newstate)
-{
- QWindowStateChangeEvent e(Qt::WindowStates(data->window_state), true);
- data->window_state = newstate;
- QApplication::sendEvent(this, &e);
-}
-
-/*!
- \fn void QWidget::setWindowState(Qt::WindowStates windowState)
-
- Sets the window state to \a windowState. The window state is a OR'ed
- combination of Qt::WindowState: Qt::WindowMinimized,
- Qt::WindowMaximized, Qt::WindowFullScreen, and Qt::WindowActive.
-
- If the window is not visible (i.e. isVisible() returns false), the
- window state will take effect when show() is called. For visible
- windows, the change is immediate. For example, to toggle between
- full-screen and normal mode, use the following code:
-
- \snippet doc/src/snippets/code/src_gui_kernel_qwidget.cpp 0
-
- In order to restore and activate a minimized window (while
- preserving its maximized and/or full-screen state), use the following:
-
- \snippet doc/src/snippets/code/src_gui_kernel_qwidget.cpp 1
-
- Calling this function will hide the widget. You must call show() to make
- the widget visible again.
-
- \note On some window systems Qt::WindowActive is not immediate, and may be
- ignored in certain cases.
-
- When the window state changes, the widget receives a changeEvent()
- of type QEvent::WindowStateChange.
-
- \sa Qt::WindowState windowState()
-*/
-
-/*!
- \property QWidget::fullScreen
- \brief whether the widget is shown in full screen mode
-
- A widget in full screen mode occupies the whole screen area and does not
- display window decorations, such as a title bar.
-
- By default, this property is false.
-
- \sa windowState(), minimized, maximized
-*/
-bool QWidget::isFullScreen() const
-{ return data->window_state & Qt::WindowFullScreen; }
-
-/*!
- Shows the widget in full-screen mode.
-
- Calling this function only affects \l{isWindow()}{windows}.
-
- To return from full-screen mode, call showNormal().
-
- Full-screen mode works fine under Windows, but has certain
- problems under X. These problems are due to limitations of the
- ICCCM protocol that specifies the communication between X11
- clients and the window manager. ICCCM simply does not understand
- the concept of non-decorated full-screen windows. Therefore, the
- best we can do is to request a borderless window and place and
- resize it to fill the entire screen. Depending on the window
- manager, this may or may not work. The borderless window is
- requested using MOTIF hints, which are at least partially
- supported by virtually all modern window managers.
-
- An alternative would be to bypass the window manager entirely and
- create a window with the Qt::X11BypassWindowManagerHint flag. This
- has other severe problems though, like totally broken keyboard focus
- and very strange effects on desktop changes or when the user raises
- other windows.
-
- X11 window managers that follow modern post-ICCCM specifications
- support full-screen mode properly.
-
- \sa showNormal(), showMaximized(), show(), hide(), isVisible()
-*/
-void QWidget::showFullScreen()
-{
-#ifdef Q_WS_MAC
- // If the unified toolbar is enabled, we have to disable it before going fullscreen.
- QMainWindow *mainWindow = qobject_cast<QMainWindow*>(this);
- if (mainWindow && mainWindow->unifiedTitleAndToolBarOnMac()) {
- mainWindow->setUnifiedTitleAndToolBarOnMac(false);
- QMainWindowLayout *mainLayout = qobject_cast<QMainWindowLayout*>(mainWindow->layout());
- mainLayout->activateUnifiedToolbarAfterFullScreen = true;
- }
-#endif // Q_WS_MAC
- ensurePolished();
-#ifdef QT3_SUPPORT
- if (parent())
- QApplication::sendPostedEvents(parent(), QEvent::ChildInserted);
-#endif
-
- setWindowState((windowState() & ~(Qt::WindowMinimized | Qt::WindowMaximized))
- | Qt::WindowFullScreen);
- show();
- activateWindow();
-}
-
-/*!
- Shows the widget maximized.
-
- Calling this function only affects \l{isWindow()}{windows}.
-
- On X11, this function may not work properly with certain window
- managers. See the \l{Window Geometry} documentation for an explanation.
-
- \sa setWindowState(), showNormal(), showMinimized(), show(), hide(), isVisible()
-*/
-void QWidget::showMaximized()
-{
- ensurePolished();
-#ifdef QT3_SUPPORT
- if (parent())
- QApplication::sendPostedEvents(parent(), QEvent::ChildInserted);
-#endif
-
- setWindowState((windowState() & ~(Qt::WindowMinimized | Qt::WindowFullScreen))
- | Qt::WindowMaximized);
-#ifdef Q_WS_MAC
- // If the unified toolbar was enabled before going fullscreen, we have to enable it back.
- QMainWindow *mainWindow = qobject_cast<QMainWindow*>(this);
- if (mainWindow)
- {
- QMainWindowLayout *mainLayout = qobject_cast<QMainWindowLayout*>(mainWindow->layout());
- if (mainLayout->activateUnifiedToolbarAfterFullScreen) {
- mainWindow->setUnifiedTitleAndToolBarOnMac(true);
- mainLayout->activateUnifiedToolbarAfterFullScreen = false;
- }
- }
-#endif // Q_WS_MAC
- show();
-}
-
-/*!
- Restores the widget after it has been maximized or minimized.
-
- Calling this function only affects \l{isWindow()}{windows}.
-
- \sa setWindowState(), showMinimized(), showMaximized(), show(), hide(), isVisible()
-*/
-void QWidget::showNormal()
-{
- ensurePolished();
-#ifdef QT3_SUPPORT
- if (parent())
- QApplication::sendPostedEvents(parent(), QEvent::ChildInserted);
-#endif
-
- setWindowState(windowState() & ~(Qt::WindowMinimized
- | Qt::WindowMaximized
- | Qt::WindowFullScreen));
-#ifdef Q_WS_MAC
- // If the unified toolbar was enabled before going fullscreen, we have to enable it back.
- QMainWindow *mainWindow = qobject_cast<QMainWindow*>(this);
- if (mainWindow)
- {
- QMainWindowLayout *mainLayout = qobject_cast<QMainWindowLayout*>(mainWindow->layout());
- if (mainLayout->activateUnifiedToolbarAfterFullScreen) {
- mainWindow->setUnifiedTitleAndToolBarOnMac(true);
- mainLayout->activateUnifiedToolbarAfterFullScreen = false;
- }
- }
-#endif // Q_WS_MAC
- show();
-}
-
-/*!
- Returns true if this widget would become enabled if \a ancestor is
- enabled; otherwise returns false.
-
-
-
- This is the case if neither the widget itself nor every parent up
- to but excluding \a ancestor has been explicitly disabled.
-
- isEnabledTo(0) is equivalent to isEnabled().
-
- \sa setEnabled() enabled
-*/
-
-bool QWidget::isEnabledTo(QWidget* ancestor) const
-{
- const QWidget * w = this;
- while (!w->testAttribute(Qt::WA_ForceDisabled)
- && !w->isWindow()
- && w->parentWidget()
- && w->parentWidget() != ancestor)
- w = w->parentWidget();
- return !w->testAttribute(Qt::WA_ForceDisabled);
-}
-
-#ifndef QT_NO_ACTION
-/*!
- Appends the action \a action to this widget's list of actions.
-
- All QWidgets have a list of \l{QAction}s, however they can be
- represented graphically in many different ways. The default use of
- the QAction list (as returned by actions()) is to create a context
- QMenu.
-
- A QWidget should only have one of each action and adding an action
- it already has will not cause the same action to be in the widget twice.
-
- The ownership of \a action is not transferred to this QWidget.
-
- \sa removeAction(), insertAction(), actions(), QMenu
-*/
-void QWidget::addAction(QAction *action)
-{
- insertAction(0, action);
-}
-
-/*!
- Appends the actions \a actions to this widget's list of actions.
-
- \sa removeAction(), QMenu, addAction()
-*/
-void QWidget::addActions(QList<QAction*> actions)
-{
- for(int i = 0; i < actions.count(); i++)
- insertAction(0, actions.at(i));
-}
-
-/*!
- Inserts the action \a action to this widget's list of actions,
- before the action \a before. It appends the action if \a before is 0 or
- \a before is not a valid action for this widget.
-
- A QWidget should only have one of each action.
-
- \sa removeAction(), addAction(), QMenu, contextMenuPolicy, actions()
-*/
-void QWidget::insertAction(QAction *before, QAction *action)
-{
- if(!action) {
- qWarning("QWidget::insertAction: Attempt to insert null action");
- return;
- }
-
- Q_D(QWidget);
- if(d->actions.contains(action))
- removeAction(action);
-
- int pos = d->actions.indexOf(before);
- if (pos < 0) {
- before = 0;
- pos = d->actions.size();
- }
- d->actions.insert(pos, action);
-
- QActionPrivate *apriv = action->d_func();
- apriv->widgets.append(this);
-
- QActionEvent e(QEvent::ActionAdded, action, before);
- QApplication::sendEvent(this, &e);
-}
-
-/*!
- Inserts the actions \a actions to this widget's list of actions,
- before the action \a before. It appends the action if \a before is 0 or
- \a before is not a valid action for this widget.
-
- A QWidget can have at most one of each action.
-
- \sa removeAction(), QMenu, insertAction(), contextMenuPolicy
-*/
-void QWidget::insertActions(QAction *before, QList<QAction*> actions)
-{
- for(int i = 0; i < actions.count(); ++i)
- insertAction(before, actions.at(i));
-}
-
-/*!
- Removes the action \a action from this widget's list of actions.
- \sa insertAction(), actions(), insertAction()
-*/
-void QWidget::removeAction(QAction *action)
-{
- if (!action)
- return;
-
- Q_D(QWidget);
-
- QActionPrivate *apriv = action->d_func();
- apriv->widgets.removeAll(this);
-
- if (d->actions.removeAll(action)) {
- QActionEvent e(QEvent::ActionRemoved, action);
- QApplication::sendEvent(this, &e);
- }
-}
-
-/*!
- Returns the (possibly empty) list of this widget's actions.
-
- \sa contextMenuPolicy, insertAction(), removeAction()
-*/
-QList<QAction*> QWidget::actions() const
-{
- Q_D(const QWidget);
- return d->actions;
-}
-#endif // QT_NO_ACTION
-
-/*!
- \fn bool QWidget::isEnabledToTLW() const
- \obsolete
-
- This function is deprecated. It is equivalent to isEnabled()
-*/
-
-/*!
- \property QWidget::enabled
- \brief whether the widget is enabled
-
- An enabled widget handles keyboard and mouse events; a disabled
- widget does not.
-
- Some widgets display themselves differently when they are
- disabled. For example a button might draw its label grayed out. If
- your widget needs to know when it becomes enabled or disabled, you
- can use the changeEvent() with type QEvent::EnabledChange.
-
- Disabling a widget implicitly disables all its children. Enabling
- respectively enables all child widgets unless they have been
- explicitly disabled.
-
- By default, this property is true.
-
- \sa isEnabledTo(), QKeyEvent, QMouseEvent, changeEvent()
-*/
-void QWidget::setEnabled(bool enable)
-{
- Q_D(QWidget);
- setAttribute(Qt::WA_ForceDisabled, !enable);
- d->setEnabled_helper(enable);
-}
-
-void QWidgetPrivate::setEnabled_helper(bool enable)
-{
- Q_Q(QWidget);
-
- if (enable && !q->isWindow() && q->parentWidget() && !q->parentWidget()->isEnabled())
- return; // nothing we can do
-
- if (enable != q->testAttribute(Qt::WA_Disabled))
- return; // nothing to do
-
- q->setAttribute(Qt::WA_Disabled, !enable);
- updateSystemBackground();
-
- if (!enable && q->window()->focusWidget() == q) {
- bool parentIsEnabled = (!q->parentWidget() || q->parentWidget()->isEnabled());
- if (!parentIsEnabled || !q->focusNextChild())
- q->clearFocus();
- }
-
- Qt::WidgetAttribute attribute = enable ? Qt::WA_ForceDisabled : Qt::WA_Disabled;
- for (int i = 0; i < children.size(); ++i) {
- QWidget *w = qobject_cast<QWidget *>(children.at(i));
- if (w && !w->testAttribute(attribute))
- w->d_func()->setEnabled_helper(enable);
- }
-#if defined(Q_WS_X11)
- if (q->testAttribute(Qt::WA_SetCursor) || q->isWindow()) {
- // enforce the windows behavior of clearing the cursor on
- // disabled widgets
- qt_x11_enforce_cursor(q);
- }
-#endif
-#if defined(Q_WS_MAC)
- setEnabled_helper_sys(enable);
-#endif
-#ifndef QT_NO_IM
- if (q->testAttribute(Qt::WA_InputMethodEnabled) && q->hasFocus()) {
- QWidget *focusWidget = effectiveFocusWidget();
- QInputContext *qic = focusWidget->d_func()->inputContext();
- if (enable) {
- if (focusWidget->testAttribute(Qt::WA_InputMethodEnabled))
- qic->setFocusWidget(focusWidget);
- } else {
- qic->reset();
- qic->setFocusWidget(0);
- }
- }
-#endif //QT_NO_IM
- QEvent e(QEvent::EnabledChange);
- QApplication::sendEvent(q, &e);
-#ifdef QT3_SUPPORT
- q->enabledChange(!enable); // compatibility
-#endif
-}
-
-/*!
- \property QWidget::acceptDrops
- \brief whether drop events are enabled for this widget
-
- Setting this property to true announces to the system that this
- widget \e may be able to accept drop events.
-
- If the widget is the desktop (windowType() == Qt::Desktop), this may
- fail if another application is using the desktop; you can call
- acceptDrops() to test if this occurs.
-
- \warning Do not modify this property in a drag and drop event handler.
-
- By default, this property is false.
-
- \sa {Drag and Drop}
-*/
-bool QWidget::acceptDrops() const
-{
- return testAttribute(Qt::WA_AcceptDrops);
-}
-
-void QWidget::setAcceptDrops(bool on)
-{
- setAttribute(Qt::WA_AcceptDrops, on);
-
-}
-
-/*!
- \fn void QWidget::enabledChange(bool)
-
- \internal
- \obsolete
-*/
-
-/*!
- \fn void QWidget::paletteChange(const QPalette &)
-
- \internal
- \obsolete
-*/
-
-/*!
- \fn void QWidget::fontChange(const QFont &)
-
- \internal
- \obsolete
-*/
-
-/*!
- \fn void QWidget::windowActivationChange(bool)
-
- \internal
- \obsolete
-*/
-
-/*!
- \fn void QWidget::languageChange()
-
- \obsolete
-*/
-
-/*!
- \fn void QWidget::styleChange(QStyle& style)
-
- \internal
- \obsolete
-*/
-
-/*!
- Disables widget input events if \a disable is true; otherwise
- enables input events.
-
- See the \l enabled documentation for more information.
-
- \sa isEnabledTo(), QKeyEvent, QMouseEvent, changeEvent()
-*/
-void QWidget::setDisabled(bool disable)
-{
- setEnabled(!disable);
-}
-
-/*!
- \property QWidget::frameGeometry
- \brief geometry of the widget relative to its parent including any
- window frame
-
- See the \l{Window Geometry} documentation for an overview of geometry
- issues with windows.
-
- By default, this property contains a value that depends on the user's
- platform and screen geometry.
-
- \sa geometry() x() y() pos()
-*/
-QRect QWidget::frameGeometry() const
-{
- Q_D(const QWidget);
- if (isWindow() && ! (windowType() == Qt::Popup)) {
- QRect fs = d->frameStrut();
- return QRect(data->crect.x() - fs.left(),
- data->crect.y() - fs.top(),
- data->crect.width() + fs.left() + fs.right(),
- data->crect.height() + fs.top() + fs.bottom());
- }
- return data->crect;
-}
-
-/*!
- \property QWidget::x
-
- \brief the x coordinate of the widget relative to its parent including
- any window frame
-
- See the \l{Window Geometry} documentation for an overview of geometry
- issues with windows.
-
- By default, this property has a value of 0.
-
- \sa frameGeometry, y, pos
-*/
-int QWidget::x() const
-{
- Q_D(const QWidget);
- if (isWindow() && ! (windowType() == Qt::Popup))
- return data->crect.x() - d->frameStrut().left();
- return data->crect.x();
-}
-
-/*!
- \property QWidget::y
- \brief the y coordinate of the widget relative to its parent and
- including any window frame
-
- See the \l{Window Geometry} documentation for an overview of geometry
- issues with windows.
-
- By default, this property has a value of 0.
-
- \sa frameGeometry, x, pos
-*/
-int QWidget::y() const
-{
- Q_D(const QWidget);
- if (isWindow() && ! (windowType() == Qt::Popup))
- return data->crect.y() - d->frameStrut().top();
- return data->crect.y();
-}
-
-/*!
- \property QWidget::pos
- \brief the position of the widget within its parent widget
-
- If the widget is a window, the position is that of the widget on
- the desktop, including its frame.
-
- When changing the position, the widget, if visible, receives a
- move event (moveEvent()) immediately. If the widget is not
- currently visible, it is guaranteed to receive an event before it
- is shown.
-
- By default, this property contains a position that refers to the
- origin.
-
- \warning Calling move() or setGeometry() inside moveEvent() can
- lead to infinite recursion.
-
- See the \l{Window Geometry} documentation for an overview of geometry
- issues with windows.
-
- \sa frameGeometry, size x(), y()
-*/
-QPoint QWidget::pos() const
-{
- Q_D(const QWidget);
- if (isWindow() && ! (windowType() == Qt::Popup)) {
- QRect fs = d->frameStrut();
- return QPoint(data->crect.x() - fs.left(), data->crect.y() - fs.top());
- }
- return data->crect.topLeft();
-}
-
-/*!
- \property QWidget::geometry
- \brief the geometry of the widget relative to its parent and
- excluding the window frame
-
- When changing the geometry, the widget, if visible, receives a
- move event (moveEvent()) and/or a resize event (resizeEvent())
- immediately. If the widget is not currently visible, it is
- guaranteed to receive appropriate events before it is shown.
-
- The size component is adjusted if it lies outside the range
- defined by minimumSize() and maximumSize().
-
- \warning Calling setGeometry() inside resizeEvent() or moveEvent()
- can lead to infinite recursion.
-
- See the \l{Window Geometry} documentation for an overview of geometry
- issues with windows.
-
- By default, this property contains a value that depends on the user's
- platform and screen geometry.
-
- \sa frameGeometry(), rect(), move(), resize(), moveEvent(),
- resizeEvent(), minimumSize(), maximumSize()
-*/
-
-/*!
- \property QWidget::normalGeometry
-
- \brief the geometry of the widget as it will appear when shown as
- a normal (not maximized or full screen) top-level widget
-
- For child widgets this property always holds an empty rectangle.
-
- By default, this property contains an empty rectangle.
-
- \sa QWidget::windowState(), QWidget::geometry
-*/
-
-/*!
- \property QWidget::size
- \brief the size of the widget excluding any window frame
-
- If the widget is visible when it is being resized, it receives a resize event
- (resizeEvent()) immediately. If the widget is not currently
- visible, it is guaranteed to receive an event before it is shown.
-
- The size is adjusted if it lies outside the range defined by
- minimumSize() and maximumSize().
-
- By default, this property contains a value that depends on the user's
- platform and screen geometry.
-
- \warning Calling resize() or setGeometry() inside resizeEvent() can
- lead to infinite recursion.
-
- \note Setting the size to \c{QSize(0, 0)} will cause the widget to not
- appear on screen. This also applies to windows.
-
- \sa pos, geometry, minimumSize, maximumSize, resizeEvent(), adjustSize()
-*/
-
-/*!
- \property QWidget::width
- \brief the width of the widget excluding any window frame
-
- See the \l{Window Geometry} documentation for an overview of geometry
- issues with windows.
-
- \note Do not use this function to find the width of a screen on
- a \l{QDesktopWidget}{multiple screen desktop}. Read
- \l{QDesktopWidget#Screen Geometry}{this note} for details.
-
- By default, this property contains a value that depends on the user's
- platform and screen geometry.
-
- \sa geometry, height, size
-*/
-
-/*!
- \property QWidget::height
- \brief the height of the widget excluding any window frame
-
- See the \l{Window Geometry} documentation for an overview of geometry
- issues with windows.
-
- \note Do not use this function to find the height of a screen
- on a \l{QDesktopWidget}{multiple screen desktop}. Read
- \l{QDesktopWidget#Screen Geometry}{this note} for details.
-
- By default, this property contains a value that depends on the user's
- platform and screen geometry.
-
- \sa geometry, width, size
-*/
-
-/*!
- \property QWidget::rect
- \brief the internal geometry of the widget excluding any window
- frame
-
- The rect property equals QRect(0, 0, width(), height()).
-
- See the \l{Window Geometry} documentation for an overview of geometry
- issues with windows.
-
- By default, this property contains a value that depends on the user's
- platform and screen geometry.
-
- \sa size
-*/
-
-
-QRect QWidget::normalGeometry() const
-{
- Q_D(const QWidget);
- if (!d->extra || !d->extra->topextra)
- return QRect();
-
- if (!isMaximized() && !isFullScreen())
- return geometry();
-
- return d->topData()->normalGeometry;
-}
-
-
-/*!
- \property QWidget::childrenRect
- \brief the bounding rectangle of the widget's children
-
- Hidden children are excluded.
-
- By default, for a widget with no children, this property contains a
- rectangle with zero width and height located at the origin.
-
- \sa childrenRegion() geometry()
-*/
-
-QRect QWidget::childrenRect() const
-{
- Q_D(const QWidget);
- QRect r(0, 0, 0, 0);
- for (int i = 0; i < d->children.size(); ++i) {
- QWidget *w = qobject_cast<QWidget *>(d->children.at(i));
- if (w && !w->isWindow() && !w->isHidden())
- r |= w->geometry();
- }
- return r;
-}
-
-/*!
- \property QWidget::childrenRegion
- \brief the combined region occupied by the widget's children
-
- Hidden children are excluded.
-
- By default, for a widget with no children, this property contains an
- empty region.
-
- \sa childrenRect() geometry() mask()
-*/
-
-QRegion QWidget::childrenRegion() const
-{
- Q_D(const QWidget);
- QRegion r;
- for (int i = 0; i < d->children.size(); ++i) {
- QWidget *w = qobject_cast<QWidget *>(d->children.at(i));
- if (w && !w->isWindow() && !w->isHidden()) {
- QRegion mask = w->mask();
- if (mask.isEmpty())
- r |= w->geometry();
- else
- r |= mask.translated(w->pos());
- }
- }
- return r;
-}
-
-
-/*!
- \property QWidget::minimumSize
- \brief the widget's minimum size
-
- The widget cannot be resized to a smaller size than the minimum
- widget size. The widget's size is forced to the minimum size if
- the current size is smaller.
-
- The minimum size set by this function will override the minimum size
- defined by QLayout. In order to unset the minimum size, use a
- value of \c{QSize(0, 0)}.
-
- By default, this property contains a size with zero width and height.
-
- \sa minimumWidth, minimumHeight, maximumSize, sizeIncrement
-*/
-
-QSize QWidget::minimumSize() const
-{
- Q_D(const QWidget);
- return d->extra ? QSize(d->extra->minw, d->extra->minh) : QSize(0, 0);
-}
-
-/*!
- \property QWidget::maximumSize
- \brief the widget's maximum size in pixels
-
- The widget cannot be resized to a larger size than the maximum
- widget size.
-
- By default, this property contains a size in which both width and height
- have values of 16777215.
-
- \note The definition of the \c QWIDGETSIZE_MAX macro limits the maximum size
- of widgets.
-
- \sa maximumWidth, maximumHeight, minimumSize, sizeIncrement
-*/
-
-QSize QWidget::maximumSize() const
-{
- Q_D(const QWidget);
- return d->extra ? QSize(d->extra->maxw, d->extra->maxh)
- : QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
-}
-
-
-/*!
- \property QWidget::minimumWidth
- \brief the widget's minimum width in pixels
-
- This property corresponds to the width held by the \l minimumSize property.
-
- By default, this property has a value of 0.
-
- \sa minimumSize, minimumHeight
-*/
-
-/*!
- \property QWidget::minimumHeight
- \brief the widget's minimum height in pixels
-
- This property corresponds to the height held by the \l minimumSize property.
-
- By default, this property has a value of 0.
-
- \sa minimumSize, minimumWidth
-*/
-
-/*!
- \property QWidget::maximumWidth
- \brief the widget's maximum width in pixels
-
- This property corresponds to the width held by the \l maximumSize property.
-
- By default, this property contains a value of 16777215.
-
- \note The definition of the \c QWIDGETSIZE_MAX macro limits the maximum size
- of widgets.
-
- \sa maximumSize, maximumHeight
-*/
-
-/*!
- \property QWidget::maximumHeight
- \brief the widget's maximum height in pixels
-
- This property corresponds to the height held by the \l maximumSize property.
-
- By default, this property contains a value of 16777215.
-
- \note The definition of the \c QWIDGETSIZE_MAX macro limits the maximum size
- of widgets.
-
- \sa maximumSize, maximumWidth
-*/
-
-/*!
- \property QWidget::sizeIncrement
- \brief the size increment of the widget
-
- When the user resizes the window, the size will move in steps of
- sizeIncrement().width() pixels horizontally and
- sizeIncrement.height() pixels vertically, with baseSize() as the
- basis. Preferred widget sizes are for non-negative integers \e i
- and \e j:
- \snippet doc/src/snippets/code/src_gui_kernel_qwidget.cpp 2
-
- Note that while you can set the size increment for all widgets, it
- only affects windows.
-
- By default, this property contains a size with zero width and height.
-
- \warning The size increment has no effect under Windows, and may
- be disregarded by the window manager on X11.
-
- \sa size, minimumSize, maximumSize
-*/
-QSize QWidget::sizeIncrement() const
-{
- Q_D(const QWidget);
- return (d->extra && d->extra->topextra)
- ? QSize(d->extra->topextra->incw, d->extra->topextra->inch)
- : QSize(0, 0);
-}
-
-/*!
- \property QWidget::baseSize
- \brief the base size of the widget
-
- The base size is used to calculate a proper widget size if the
- widget defines sizeIncrement().
-
- By default, for a newly-created widget, this property contains a size with
- zero width and height.
-
- \sa setSizeIncrement()
-*/
-
-QSize QWidget::baseSize() const
-{
- Q_D(const QWidget);
- return (d->extra != 0 && d->extra->topextra != 0)
- ? QSize(d->extra->topextra->basew, d->extra->topextra->baseh)
- : QSize(0, 0);
-}
-
-bool QWidgetPrivate::setMinimumSize_helper(int &minw, int &minh)
-{
- Q_Q(QWidget);
-
-#ifdef Q_WS_QWS
- if (q->isWindow()) {
- const QRect maxWindowRect = QApplication::desktop()->availableGeometry(QApplication::desktop()->screenNumber(q));
- if (!maxWindowRect.isEmpty()) {
- // ### This is really just a work-around. Layout shouldn't be
- // asking for minimum sizes bigger than the screen.
- if (minw > maxWindowRect.width())
- minw = maxWindowRect.width();
- if (minh > maxWindowRect.height())
- minh = maxWindowRect.height();
- }
- }
-#endif
- int mw = minw, mh = minh;
- if (mw == QWIDGETSIZE_MAX)
- mw = 0;
- if (mh == QWIDGETSIZE_MAX)
- mh = 0;
- if (minw > QWIDGETSIZE_MAX || minh > QWIDGETSIZE_MAX) {
- qWarning("QWidget::setMinimumSize: (%s/%s) "
- "The largest allowed size is (%d,%d)",
- q->objectName().toLocal8Bit().data(), q->metaObject()->className(), QWIDGETSIZE_MAX,
- QWIDGETSIZE_MAX);
- minw = mw = qMin<int>(minw, QWIDGETSIZE_MAX);
- minh = mh = qMin<int>(minh, QWIDGETSIZE_MAX);
- }
- if (minw < 0 || minh < 0) {
- qWarning("QWidget::setMinimumSize: (%s/%s) Negative sizes (%d,%d) "
- "are not possible",
- q->objectName().toLocal8Bit().data(), q->metaObject()->className(), minw, minh);
- minw = mw = qMax(minw, 0);
- minh = mh = qMax(minh, 0);
- }
- createExtra();
- if (extra->minw == mw && extra->minh == mh)
- return false;
- extra->minw = mw;
- extra->minh = mh;
- extra->explicitMinSize = (mw ? Qt::Horizontal : 0) | (mh ? Qt::Vertical : 0);
- return true;
-}
-
-/*!
- \overload
-
- This function corresponds to setMinimumSize(QSize(minw, minh)).
- Sets the minimum width to \a minw and the minimum height to \a
- minh.
-*/
-
-void QWidget::setMinimumSize(int minw, int minh)
-{
- Q_D(QWidget);
- if (!d->setMinimumSize_helper(minw, minh))
- return;
-
- if (isWindow())
- d->setConstraints_sys();
- if (minw > width() || minh > height()) {
- bool resized = testAttribute(Qt::WA_Resized);
- bool maximized = isMaximized();
- resize(qMax(minw,width()), qMax(minh,height()));
- setAttribute(Qt::WA_Resized, resized); //not a user resize
- if (maximized)
- data->window_state = data->window_state | Qt::WindowMaximized;
- }
-#ifndef QT_NO_GRAPHICSVIEW
- if (d->extra) {
- if (d->extra->proxyWidget)
- d->extra->proxyWidget->setMinimumSize(minw, minh);
- }
-#endif
- d->updateGeometry_helper(d->extra->minw == d->extra->maxw && d->extra->minh == d->extra->maxh);
-}
-
-bool QWidgetPrivate::setMaximumSize_helper(int &maxw, int &maxh)
-{
- Q_Q(QWidget);
- if (maxw > QWIDGETSIZE_MAX || maxh > QWIDGETSIZE_MAX) {
- qWarning("QWidget::setMaximumSize: (%s/%s) "
- "The largest allowed size is (%d,%d)",
- q->objectName().toLocal8Bit().data(), q->metaObject()->className(), QWIDGETSIZE_MAX,
- QWIDGETSIZE_MAX);
- maxw = qMin<int>(maxw, QWIDGETSIZE_MAX);
- maxh = qMin<int>(maxh, QWIDGETSIZE_MAX);
- }
- if (maxw < 0 || maxh < 0) {
- qWarning("QWidget::setMaximumSize: (%s/%s) Negative sizes (%d,%d) "
- "are not possible",
- q->objectName().toLocal8Bit().data(), q->metaObject()->className(), maxw, maxh);
- maxw = qMax(maxw, 0);
- maxh = qMax(maxh, 0);
- }
- createExtra();
- if (extra->maxw == maxw && extra->maxh == maxh)
- return false;
- extra->maxw = maxw;
- extra->maxh = maxh;
- extra->explicitMaxSize = (maxw != QWIDGETSIZE_MAX ? Qt::Horizontal : 0) |
- (maxh != QWIDGETSIZE_MAX ? Qt::Vertical : 0);
- return true;
-}
-
-/*!
- \overload
-
- This function corresponds to setMaximumSize(QSize(\a maxw, \a
- maxh)). Sets the maximum width to \a maxw and the maximum height
- to \a maxh.
-*/
-void QWidget::setMaximumSize(int maxw, int maxh)
-{
- Q_D(QWidget);
- if (!d->setMaximumSize_helper(maxw, maxh))
- return;
-
- if (isWindow())
- d->setConstraints_sys();
- if (maxw < width() || maxh < height()) {
- bool resized = testAttribute(Qt::WA_Resized);
- resize(qMin(maxw,width()), qMin(maxh,height()));
- setAttribute(Qt::WA_Resized, resized); //not a user resize
- }
-
-#ifndef QT_NO_GRAPHICSVIEW
- if (d->extra) {
- if (d->extra->proxyWidget)
- d->extra->proxyWidget->setMaximumSize(maxw, maxh);
- }
-#endif
-
- d->updateGeometry_helper(d->extra->minw == d->extra->maxw && d->extra->minh == d->extra->maxh);
-}
-
-/*!
- \overload
-
- Sets the x (width) size increment to \a w and the y (height) size
- increment to \a h.
-*/
-void QWidget::setSizeIncrement(int w, int h)
-{
- Q_D(QWidget);
- d->createTLExtra();
- QTLWExtra* x = d->topData();
- if (x->incw == w && x->inch == h)
- return;
- x->incw = w;
- x->inch = h;
- if (isWindow())
- d->setConstraints_sys();
-}
-
-/*!
- \overload
-
- This corresponds to setBaseSize(QSize(\a basew, \a baseh)). Sets
- the widgets base size to width \a basew and height \a baseh.
-*/
-void QWidget::setBaseSize(int basew, int baseh)
-{
- Q_D(QWidget);
- d->createTLExtra();
- QTLWExtra* x = d->topData();
- if (x->basew == basew && x->baseh == baseh)
- return;
- x->basew = basew;
- x->baseh = baseh;
- if (isWindow())
- d->setConstraints_sys();
-}
-
-/*!
- Sets both the minimum and maximum sizes of the widget to \a s,
- thereby preventing it from ever growing or shrinking.
-
- This will override the default size constraints set by QLayout.
-
- To remove constraints, set the size to QWIDGETSIZE_MAX.
-
- Alternatively, if you want the widget to have a
- fixed size based on its contents, you can call
- QLayout::setSizeConstraint(QLayout::SetFixedSize);
-
- \sa maximumSize, minimumSize
-*/
-
-void QWidget::setFixedSize(const QSize & s)
-{
- setFixedSize(s.width(), s.height());
-}
-
-
-/*!
- \fn void QWidget::setFixedSize(int w, int h)
- \overload
-
- Sets the width of the widget to \a w and the height to \a h.
-*/
-
-void QWidget::setFixedSize(int w, int h)
-{
- Q_D(QWidget);
-#ifdef Q_WS_QWS
- // temporary fix for 4.3.x.
- // Should move the embedded spesific contraints in setMinimumSize_helper into QLayout
- int tmpW = w;
- int tmpH = h;
- bool minSizeSet = d->setMinimumSize_helper(tmpW, tmpH);
-#else
- bool minSizeSet = d->setMinimumSize_helper(w, h);
-#endif
- bool maxSizeSet = d->setMaximumSize_helper(w, h);
- if (!minSizeSet && !maxSizeSet)
- return;
-
- if (isWindow())
- d->setConstraints_sys();
- else
- d->updateGeometry_helper(true);
-
- if (w != QWIDGETSIZE_MAX || h != QWIDGETSIZE_MAX)
- resize(w, h);
-}
-
-void QWidget::setMinimumWidth(int w)
-{
- Q_D(QWidget);
- d->createExtra();
- uint expl = d->extra->explicitMinSize | (w ? Qt::Horizontal : 0);
- setMinimumSize(w, minimumSize().height());
- d->extra->explicitMinSize = expl;
-}
-
-void QWidget::setMinimumHeight(int h)
-{
- Q_D(QWidget);
- d->createExtra();
- uint expl = d->extra->explicitMinSize | (h ? Qt::Vertical : 0);
- setMinimumSize(minimumSize().width(), h);
- d->extra->explicitMinSize = expl;
-}
-
-void QWidget::setMaximumWidth(int w)
-{
- Q_D(QWidget);
- d->createExtra();
- uint expl = d->extra->explicitMaxSize | (w == QWIDGETSIZE_MAX ? 0 : Qt::Horizontal);
- setMaximumSize(w, maximumSize().height());
- d->extra->explicitMaxSize = expl;
-}
-
-void QWidget::setMaximumHeight(int h)
-{
- Q_D(QWidget);
- d->createExtra();
- uint expl = d->extra->explicitMaxSize | (h == QWIDGETSIZE_MAX ? 0 : Qt::Vertical);
- setMaximumSize(maximumSize().width(), h);
- d->extra->explicitMaxSize = expl;
-}
-
-/*!
- Sets both the minimum and maximum width of the widget to \a w
- without changing the heights. Provided for convenience.
-
- \sa sizeHint() minimumSize() maximumSize() setFixedSize()
-*/
-
-void QWidget::setFixedWidth(int w)
-{
- Q_D(QWidget);
- d->createExtra();
- uint explMin = d->extra->explicitMinSize | Qt::Horizontal;
- uint explMax = d->extra->explicitMaxSize | Qt::Horizontal;
- setMinimumSize(w, minimumSize().height());
- setMaximumSize(w, maximumSize().height());
- d->extra->explicitMinSize = explMin;
- d->extra->explicitMaxSize = explMax;
-}
-
-
-/*!
- Sets both the minimum and maximum heights of the widget to \a h
- without changing the widths. Provided for convenience.
-
- \sa sizeHint() minimumSize() maximumSize() setFixedSize()
-*/
-
-void QWidget::setFixedHeight(int h)
-{
- Q_D(QWidget);
- d->createExtra();
- uint explMin = d->extra->explicitMinSize | Qt::Vertical;
- uint explMax = d->extra->explicitMaxSize | Qt::Vertical;
- setMinimumSize(minimumSize().width(), h);
- setMaximumSize(maximumSize().width(), h);
- d->extra->explicitMinSize = explMin;
- d->extra->explicitMaxSize = explMax;
-}
-
-
-/*!
- Translates the widget coordinate \a pos to the coordinate system
- of \a parent. The \a parent must not be 0 and must be a parent
- of the calling widget.
-
- \sa mapFrom() mapToParent() mapToGlobal() underMouse()
-*/
-
-QPoint QWidget::mapTo(QWidget * parent, const QPoint & pos) const
-{
- QPoint p = pos;
- if (parent) {
- const QWidget * w = this;
- while (w != parent) {
- Q_ASSERT_X(w, "QWidget::mapTo(QWidget *parent, const QPoint &pos)",
- "parent must be in parent hierarchy");
- p = w->mapToParent(p);
- w = w->parentWidget();
- }
- }
- return p;
-}
-
-
-/*!
- Translates the widget coordinate \a pos from the coordinate system
- of \a parent to this widget's coordinate system. The \a parent
- must not be 0 and must be a parent of the calling widget.
-
- \sa mapTo() mapFromParent() mapFromGlobal() underMouse()
-*/
-
-QPoint QWidget::mapFrom(QWidget * parent, const QPoint & pos) const
-{
- QPoint p(pos);
- if (parent) {
- const QWidget * w = this;
- while (w != parent) {
- Q_ASSERT_X(w, "QWidget::mapFrom(QWidget *parent, const QPoint &pos)",
- "parent must be in parent hierarchy");
-
- p = w->mapFromParent(p);
- w = w->parentWidget();
- }
- }
- return p;
-}
-
-
-/*!
- Translates the widget coordinate \a pos to a coordinate in the
- parent widget.
-
- Same as mapToGlobal() if the widget has no parent.
-
- \sa mapFromParent() mapTo() mapToGlobal() underMouse()
-*/
-
-QPoint QWidget::mapToParent(const QPoint &pos) const
-{
- return pos + data->crect.topLeft();
-}
-
-/*!
- Translates the parent widget coordinate \a pos to widget
- coordinates.
-
- Same as mapFromGlobal() if the widget has no parent.
-
- \sa mapToParent() mapFrom() mapFromGlobal() underMouse()
-*/
-
-QPoint QWidget::mapFromParent(const QPoint &pos) const
-{
- return pos - data->crect.topLeft();
-}
-
-
-/*!
- Returns the window for this widget, i.e. the next ancestor widget
- that has (or could have) a window-system frame.
-
- If the widget is a window, the widget itself is returned.
-
- Typical usage is changing the window title:
-
- \snippet doc/src/snippets/code/src_gui_kernel_qwidget.cpp 3
-
- \sa isWindow()
-*/
-
-QWidget *QWidget::window() const
-{
- QWidget *w = (QWidget *)this;
- QWidget *p = w->parentWidget();
- while (!w->isWindow() && p) {
- w = p;
- p = p->parentWidget();
- }
- return w;
-}
-
-/*!
- \since 4.4
-
- Returns the native parent for this widget, i.e. the next ancestor widget
- that has a system identifier, or 0 if it does not have any native parent.
-
- \sa effectiveWinId()
-*/
-QWidget *QWidget::nativeParentWidget() const
-{
- QWidget *parent = parentWidget();
- while (parent && !parent->internalWinId())
- parent = parent->parentWidget();
- return parent;
-}
-
-/*! \fn QWidget *QWidget::topLevelWidget() const
- \obsolete
-
- Use window() instead.
-*/
-
-#ifdef QT3_SUPPORT
-/*!
- Returns the color role used for painting the widget's background.
-
- Use QPalette(backgroundRole(()) instead.
-*/
-Qt::BackgroundMode QWidget::backgroundMode() const
-{
- if (testAttribute(Qt::WA_NoSystemBackground))
- return Qt::NoBackground;
- switch(backgroundRole()) {
- case QPalette::WindowText:
- return Qt::PaletteForeground;
- case QPalette::Button:
- return Qt::PaletteButton;
- case QPalette::Light:
- return Qt::PaletteLight;
- case QPalette::Midlight:
- return Qt::PaletteMidlight;
- case QPalette::Dark:
- return Qt::PaletteDark;
- case QPalette::Mid:
- return Qt::PaletteMid;
- case QPalette::Text:
- return Qt::PaletteText;
- case QPalette::BrightText:
- return Qt::PaletteBrightText;
- case QPalette::Base:
- return Qt::PaletteBase;
- case QPalette::Window:
- return Qt::PaletteBackground;
- case QPalette::Shadow:
- return Qt::PaletteShadow;
- case QPalette::Highlight:
- return Qt::PaletteHighlight;
- case QPalette::HighlightedText:
- return Qt::PaletteHighlightedText;
- case QPalette::ButtonText:
- return Qt::PaletteButtonText;
- case QPalette::Link:
- return Qt::PaletteLink;
- case QPalette::LinkVisited:
- return Qt::PaletteLinkVisited;
- default:
- break;
- }
- return Qt::NoBackground;
-}
-
-/*!
- \fn void QWidget::setBackgroundMode(Qt::BackgroundMode
- widgetBackground, Qt::BackgroundMode paletteBackground)
-
- Sets the color role used for painting the widget's background to
- background mode \a widgetBackground. The \a paletteBackground mode
- parameter is ignored.
-*/
-void QWidget::setBackgroundMode(Qt::BackgroundMode m, Qt::BackgroundMode)
-{
- Q_D(QWidget);
- if(m == Qt::NoBackground) {
- setAttribute(Qt::WA_NoSystemBackground, true);
- return;
- }
- setAttribute(Qt::WA_NoSystemBackground, false);
- d->fg_role = QPalette::NoRole;
- QPalette::ColorRole role = d->bg_role;
- switch(m) {
- case Qt::FixedColor:
- case Qt::FixedPixmap:
- break;
- case Qt::PaletteForeground:
- role = QPalette::WindowText;
- break;
- case Qt::PaletteButton:
- role = QPalette::Button;
- break;
- case Qt::PaletteLight:
- role = QPalette::Light;
- break;
- case Qt::PaletteMidlight:
- role = QPalette::Midlight;
- break;
- case Qt::PaletteDark:
- role = QPalette::Dark;
- break;
- case Qt::PaletteMid:
- role = QPalette::Mid;
- break;
- case Qt::PaletteText:
- role = QPalette::Text;
- break;
- case Qt::PaletteBrightText:
- role = QPalette::BrightText;
- break;
- case Qt::PaletteBase:
- role = QPalette::Base;
- break;
- case Qt::PaletteBackground:
- role = QPalette::Window;
- break;
- case Qt::PaletteShadow:
- role = QPalette::Shadow;
- break;
- case Qt::PaletteHighlight:
- role = QPalette::Highlight;
- break;
- case Qt::PaletteHighlightedText:
- role = QPalette::HighlightedText;
- break;
- case Qt::PaletteButtonText:
- role = QPalette::ButtonText;
- break;
- case Qt::PaletteLink:
- role = QPalette::Link;
- break;
- case Qt::PaletteLinkVisited:
- role = QPalette::LinkVisited;
- break;
- case Qt::X11ParentRelative:
- d->fg_role = role = QPalette::NoRole;
- default:
- break;
- }
- setBackgroundRole(role);
-}
-
-/*!
- The widget mapper is no longer part of the public API.
-*/
-QT3_SUPPORT QWidgetMapper *QWidget::wmapper() { return QWidgetPrivate::mapper; }
-
-#endif
-
-
-/*!
- Returns the background role of the widget.
-
- The background role defines the brush from the widget's \l palette that
- is used to render the background.
-
- If no explicit background role is set, the widget inherts its parent
- widget's background role.
-
- \sa setBackgroundRole(), foregroundRole()
- */
-QPalette::ColorRole QWidget::backgroundRole() const
-{
-
- const QWidget *w = this;
- do {
- QPalette::ColorRole role = w->d_func()->bg_role;
- if (role != QPalette::NoRole)
- return role;
- if (w->isWindow() || w->windowType() == Qt::SubWindow)
- break;
- w = w->parentWidget();
- } while (w);
- return QPalette::Window;
-}
-
-/*!
- Sets the background role of the widget to \a role.
-
- The background role defines the brush from the widget's \l palette that
- is used to render the background.
-
- If \a role is QPalette::NoRole, then the widget inherits its
- parent's background role.
-
- Note that styles are free to choose any color from the palette.
- You can modify the palette or set a style sheet if you don't
- achieve the result you want with setBackgroundRole().
-
- \sa backgroundRole(), foregroundRole()
- */
-
-void QWidget::setBackgroundRole(QPalette::ColorRole role)
-{
- Q_D(QWidget);
- d->bg_role = role;
- d->updateSystemBackground();
- d->propagatePaletteChange();
- d->updateIsOpaque();
-}
-
-/*!
- Returns the foreground role.
-
- The foreground role defines the color from the widget's \l palette that
- is used to draw the foreground.
-
- If no explicit foreground role is set, the function returns a role
- that contrasts with the background role.
-
- \sa setForegroundRole(), backgroundRole()
- */
-QPalette::ColorRole QWidget::foregroundRole() const
-{
- Q_D(const QWidget);
- QPalette::ColorRole rl = QPalette::ColorRole(d->fg_role);
- if (rl != QPalette::NoRole)
- return rl;
- QPalette::ColorRole role = QPalette::WindowText;
- switch (backgroundRole()) {
- case QPalette::Button:
- role = QPalette::ButtonText;
- break;
- case QPalette::Base:
- role = QPalette::Text;
- break;
- case QPalette::Dark:
- case QPalette::Shadow:
- role = QPalette::Light;
- break;
- case QPalette::Highlight:
- role = QPalette::HighlightedText;
- break;
- case QPalette::ToolTipBase:
- role = QPalette::ToolTipText;
- break;
- default:
- ;
- }
- return role;
-}
-
-/*!
- Sets the foreground role of the widget to \a role.
-
- The foreground role defines the color from the widget's \l palette that
- is used to draw the foreground.
-
- If \a role is QPalette::NoRole, the widget uses a foreground role
- that contrasts with the background role.
-
- Note that styles are free to choose any color from the palette.
- You can modify the palette or set a style sheet if you don't
- achieve the result you want with setForegroundRole().
-
- \sa foregroundRole(), backgroundRole()
- */
-void QWidget::setForegroundRole(QPalette::ColorRole role)
-{
- Q_D(QWidget);
- d->fg_role = role;
- d->updateSystemBackground();
- d->propagatePaletteChange();
-}
-
-/*!
- \property QWidget::palette
- \brief the widget's palette
-
- This property describes the widget's palette. The palette is used by the
- widget's style when rendering standard components, and is available as a
- means to ensure that custom widgets can maintain consistency with the
- native platform's look and feel. It's common that different platforms, or
- different styles, have different palettes.
-
- When you assign a new palette to a widget, the color roles from this
- palette are combined with the widget's default palette to form the
- widget's final palette. The palette entry for the widget's background role
- is used to fill the widget's background (see QWidget::autoFillBackground),
- and the foreground role initializes QPainter's pen.
-
- The default depends on the system environment. QApplication maintains a
- system/theme palette which serves as a default for all widgets. There may
- also be special palette defaults for certain types of widgets (e.g., on
- Windows XP and Vista, all classes that derive from QMenuBar have a special
- default palette). You can also define default palettes for widgets
- yourself by passing a custom palette and the name of a widget to
- QApplication::setPalette(). Finally, the style always has the option of
- polishing the palette as it's assigned (see QStyle::polish()).
-
- QWidget propagates explicit palette roles from parent to child. If you
- assign a brush or color to a specific role on a palette and assign that
- palette to a widget, that role will propagate to all the widget's
- children, overriding any system defaults for that role. Note that palettes
- by default don't propagate to windows (see isWindow()) unless the
- Qt::WA_WindowPropagation attribute is enabled.
-
- QWidget's palette propagation is similar to its font propagation.
-
- The current style, which is used to render the content of all standard Qt
- widgets, is free to choose colors and brushes from the widget palette, or
- in some cases, to ignore the palette (partially, or completely). In
- particular, certain styles like GTK style, Mac style, Windows XP, and
- Vista style, depend on third party APIs to render the content of widgets,
- and these styles typically do not follow the palette. Because of this,
- assigning roles to a widget's palette is not guaranteed to change the
- appearance of the widget. Instead, you may choose to apply a \l
- styleSheet. You can refer to our Knowledge Base article
- \l{http://qt.nokia.com/developer/knowledgebase/22}{here} for more
- information.
-
- \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".
-
- \sa QApplication::palette(), QWidget::font()
-*/
-const QPalette &QWidget::palette() const
-{
- if (!isEnabled()) {
- data->pal.setCurrentColorGroup(QPalette::Disabled);
- } else if ((!isVisible() || isActiveWindow())
-#if defined(Q_OS_WIN) && !defined(Q_WS_WINCE)
- && !QApplicationPrivate::isBlockedByModal(const_cast<QWidget *>(this))
-#endif
- ) {
- data->pal.setCurrentColorGroup(QPalette::Active);
- } else {
-#ifdef Q_WS_MAC
- extern bool qt_mac_can_clickThrough(const QWidget *); //qwidget_mac.cpp
- if (qt_mac_can_clickThrough(this))
- data->pal.setCurrentColorGroup(QPalette::Active);
- else
-#endif
- data->pal.setCurrentColorGroup(QPalette::Inactive);
- }
- return data->pal;
-}
-
-void QWidget::setPalette(const QPalette &palette)
-{
- Q_D(QWidget);
- setAttribute(Qt::WA_SetPalette, palette.resolve() != 0);
-
- // Determine which palette is inherited from this widget's ancestors and
- // QApplication::palette, resolve this against \a palette (attributes from
- // the inherited palette are copied over this widget's palette). Then
- // propagate this palette to this widget's children.
- QPalette naturalPalette = d->naturalWidgetPalette(d->inheritedPaletteResolveMask);
- QPalette resolvedPalette = palette.resolve(naturalPalette);
- d->setPalette_helper(resolvedPalette);
-}
-
-/*!
- \internal
-
- Returns the palette that the widget \a w inherits from its ancestors and
- QApplication::palette. \a inheritedMask is the combination of the widget's
- ancestors palette request masks (i.e., which attributes from the parent
- widget's palette are implicitly imposed on this widget by the user). Note
- that this font does not take into account the palette set on \a w itself.
-*/
-QPalette QWidgetPrivate::naturalWidgetPalette(uint inheritedMask) const
-{
- Q_Q(const QWidget);
- QPalette naturalPalette = QApplication::palette(q);
- if (!q->testAttribute(Qt::WA_StyleSheet)
- && (!q->isWindow() || q->testAttribute(Qt::WA_WindowPropagation)
-#ifndef QT_NO_GRAPHICSVIEW
- || (extra && extra->proxyWidget)
-#endif //QT_NO_GRAPHICSVIEW
- )) {
- if (QWidget *p = q->parentWidget()) {
- if (!p->testAttribute(Qt::WA_StyleSheet)) {
- if (!naturalPalette.isCopyOf(QApplication::palette())) {
- QPalette inheritedPalette = p->palette();
- inheritedPalette.resolve(inheritedMask);
- naturalPalette = inheritedPalette.resolve(naturalPalette);
- } else {
- naturalPalette = p->palette();
- }
- }
- }
-#ifndef QT_NO_GRAPHICSVIEW
- else if (extra && extra->proxyWidget) {
- QPalette inheritedPalette = extra->proxyWidget->palette();
- inheritedPalette.resolve(inheritedMask);
- naturalPalette = inheritedPalette.resolve(naturalPalette);
- }
-#endif //QT_NO_GRAPHICSVIEW
- }
- naturalPalette.resolve(0);
- return naturalPalette;
-}
-/*!
- \internal
-
- Determine which palette is inherited from this widget's ancestors and
- QApplication::palette, resolve this against this widget's palette
- (attributes from the inherited palette are copied over this widget's
- palette). Then propagate this palette to this widget's children.
-*/
-void QWidgetPrivate::resolvePalette()
-{
- QPalette naturalPalette = naturalWidgetPalette(inheritedPaletteResolveMask);
- QPalette resolvedPalette = data.pal.resolve(naturalPalette);
- setPalette_helper(resolvedPalette);
-}
-
-void QWidgetPrivate::setPalette_helper(const QPalette &palette)
-{
- Q_Q(QWidget);
- if (data.pal == palette && data.pal.resolve() == palette.resolve())
- return;
- data.pal = palette;
- updateSystemBackground();
- propagatePaletteChange();
- updateIsOpaque();
- q->update();
- updateIsOpaque();
-}
-
-/*!
- \property QWidget::font
- \brief the font currently set for the widget
-
- This property describes the widget's requested font. The font is used by
- the widget's style when rendering standard components, and is available as
- a means to ensure that custom widgets can maintain consistency with the
- native platform's look and feel. It's common that different platforms, or
- different styles, define different fonts for an application.
-
- When you assign a new font to a widget, the properties from this font are
- combined with the widget's default font to form the widget's final
- font. You can call fontInfo() to get a copy of the widget's final
- font. The final font is also used to initialize QPainter's font.
-
- The default depends on the system environment. QApplication maintains a
- system/theme font which serves as a default for all widgets. There may
- also be special font defaults for certain types of widgets. You can also
- define default fonts for widgets yourself by passing a custom font and the
- name of a widget to QApplication::setFont(). Finally, the font is matched
- against Qt's font database to find the best match.
-
- QWidget propagates explicit font properties from parent to child. If you
- change a specific property on a font and assign that font to a widget,
- that property will propagate to all the widget's children, overriding any
- system defaults for that property. Note that fonts by default don't
- propagate to windows (see isWindow()) unless the Qt::WA_WindowPropagation
- attribute is enabled.
-
- QWidget's font propagation is similar to its palette propagation.
-
- The current style, which is used to render the content of all standard Qt
- widgets, is free to choose to use the widget font, or in some cases, to
- ignore it (partially, or completely). In particular, certain styles like
- GTK style, Mac style, Windows XP, and Vista style, apply special
- modifications to the widget font to match the platform's native look and
- feel. Because of this, assigning properties to a widget's font is not
- guaranteed to change the appearance of the widget. Instead, you may choose
- to apply a \l styleSheet.
-
- \note If \l{Qt Style Sheets} are used on the same widget as setFont(),
- style sheets will take precedence if the settings conflict.
-
- \sa fontInfo(), fontMetrics()
-*/
-
-void QWidget::setFont(const QFont &font)
-{
- Q_D(QWidget);
-
-#ifndef QT_NO_STYLE_STYLESHEET
- const QStyleSheetStyle* style;
- if (d->extra && (style = qobject_cast<const QStyleSheetStyle*>(d->extra->style))) {
- style->saveWidgetFont(this, font);
- }
-#endif
-
- setAttribute(Qt::WA_SetFont, font.resolve() != 0);
-
- // Determine which font is inherited from this widget's ancestors and
- // QApplication::font, resolve this against \a font (attributes from the
- // inherited font are copied over). Then propagate this font to this
- // widget's children.
- QFont naturalFont = d->naturalWidgetFont(d->inheritedFontResolveMask);
- QFont resolvedFont = font.resolve(naturalFont);
- d->setFont_helper(resolvedFont);
-}
-
-/*
- \internal
-
- Returns the font that the widget \a w inherits from its ancestors and
- QApplication::font. \a inheritedMask is the combination of the widget's
- ancestors font request masks (i.e., which attributes from the parent
- widget's font are implicitly imposed on this widget by the user). Note
- that this font does not take into account the font set on \a w itself.
-
- ### Stylesheet has a different font propagation mechanism. When a stylesheet
- is applied, fonts are not propagated anymore
-*/
-QFont QWidgetPrivate::naturalWidgetFont(uint inheritedMask) const
-{
- Q_Q(const QWidget);
- QFont naturalFont = QApplication::font(q);
- if (!q->testAttribute(Qt::WA_StyleSheet)
- && (!q->isWindow() || q->testAttribute(Qt::WA_WindowPropagation)
-#ifndef QT_NO_GRAPHICSVIEW
- || (extra && extra->proxyWidget)
-#endif //QT_NO_GRAPHICSVIEW
- )) {
- if (QWidget *p = q->parentWidget()) {
- if (!p->testAttribute(Qt::WA_StyleSheet)) {
- if (!naturalFont.isCopyOf(QApplication::font())) {
- QFont inheritedFont = p->font();
- inheritedFont.resolve(inheritedMask);
- naturalFont = inheritedFont.resolve(naturalFont);
- } else {
- naturalFont = p->font();
- }
- }
- }
-#ifndef QT_NO_GRAPHICSVIEW
- else if (extra && extra->proxyWidget) {
- QFont inheritedFont = extra->proxyWidget->font();
- inheritedFont.resolve(inheritedMask);
- naturalFont = inheritedFont.resolve(naturalFont);
- }
-#endif //QT_NO_GRAPHICSVIEW
- }
- naturalFont.resolve(0);
- return naturalFont;
-}
-
-/*!
- \internal
-
- Determine which font is implicitly imposed on this widget by its ancestors
- and QApplication::font, resolve this against its own font (attributes from
- the implicit font are copied over). Then propagate this font to this
- widget's children.
-*/
-void QWidgetPrivate::resolveFont()
-{
- QFont naturalFont = naturalWidgetFont(inheritedFontResolveMask);
- QFont resolvedFont = data.fnt.resolve(naturalFont);
- setFont_helper(resolvedFont);
-}
-
-/*!
- \internal
-
- Assign \a font to this widget, and propagate it to all children, except
- style sheet widgets (handled differently) and windows that don't enable
- window propagation. \a implicitMask is the union of all ancestor widgets'
- font request masks, and determines which attributes from this widget's
- font should propagate.
-*/
-void QWidgetPrivate::updateFont(const QFont &font)
-{
- Q_Q(QWidget);
-#ifndef QT_NO_STYLE_STYLESHEET
- const QStyleSheetStyle* cssStyle;
- cssStyle = extra ? qobject_cast<const QStyleSheetStyle*>(extra->style) : 0;
-#endif
-
-#ifdef QT3_SUPPORT
- QFont old = data.fnt;
-#endif
- data.fnt = QFont(font, q);
-#if defined(Q_WS_X11)
- // make sure the font set on this widget is associated with the correct screen
- data.fnt.x11SetScreen(xinfo.screen());
-#endif
- // Combine new mask with natural mask and propagate to children.
-#ifndef QT_NO_GRAPHICSVIEW
- if (!q->parentWidget() && extra && extra->proxyWidget) {
- QGraphicsProxyWidget *p = extra->proxyWidget;
- inheritedFontResolveMask = p->d_func()->inheritedFontResolveMask | p->font().resolve();
- } else
-#endif //QT_NO_GRAPHICSVIEW
- if (q->isWindow() && !q->testAttribute(Qt::WA_WindowPropagation)) {
- inheritedFontResolveMask = 0;
- }
- uint newMask = data.fnt.resolve() | inheritedFontResolveMask;
-
- for (int i = 0; i < children.size(); ++i) {
- QWidget *w = qobject_cast<QWidget*>(children.at(i));
- if (w) {
- if (0) {
-#ifndef QT_NO_STYLE_STYLESHEET
- } else if (w->testAttribute(Qt::WA_StyleSheet)) {
- // Style sheets follow a different font propagation scheme.
- if (cssStyle)
- cssStyle->updateStyleSheetFont(w);
-#endif
- } else if ((!w->isWindow() || w->testAttribute(Qt::WA_WindowPropagation))) {
- // Propagate font changes.
- QWidgetPrivate *wd = w->d_func();
- wd->inheritedFontResolveMask = newMask;
- wd->resolveFont();
- }
- }
- }
-
-#ifndef QT_NO_STYLE_STYLESHEET
- if (cssStyle) {
- cssStyle->updateStyleSheetFont(q);
- }
-#endif
-
- QEvent e(QEvent::FontChange);
- QApplication::sendEvent(q, &e);
-#ifdef QT3_SUPPORT
- q->fontChange(old);
-#endif
-}
-
-void QWidgetPrivate::setLayoutDirection_helper(Qt::LayoutDirection direction)
-{
- Q_Q(QWidget);
-
- if ( (direction == Qt::RightToLeft) == q->testAttribute(Qt::WA_RightToLeft))
- return;
- q->setAttribute(Qt::WA_RightToLeft, (direction == Qt::RightToLeft));
- if (!children.isEmpty()) {
- for (int i = 0; i < children.size(); ++i) {
- QWidget *w = qobject_cast<QWidget*>(children.at(i));
- if (w && !w->isWindow() && !w->testAttribute(Qt::WA_SetLayoutDirection))
- w->d_func()->setLayoutDirection_helper(direction);
- }
- }
- QEvent e(QEvent::LayoutDirectionChange);
- QApplication::sendEvent(q, &e);
-}
-
-void QWidgetPrivate::resolveLayoutDirection()
-{
- Q_Q(const QWidget);
- if (!q->testAttribute(Qt::WA_SetLayoutDirection))
- setLayoutDirection_helper(q->isWindow() ? QApplication::layoutDirection() : q->parentWidget()->layoutDirection());
-}
-
-/*!
- \property QWidget::layoutDirection
-
- \brief the layout direction for this widget
-
- By default, this property is set to Qt::LeftToRight.
-
- When the layout direction is set on a widget, it will propagate to
- the widget's children, but not to a child that is a window and not
- to a child for which setLayoutDirection() has been explicitly
- called. Also, child widgets added \e after setLayoutDirection()
- has been called for the parent do not inherit the parent's layout
- direction.
-
- This method no longer affects text layout direction since Qt 4.7.
-
- \sa QApplication::layoutDirection
-*/
-void QWidget::setLayoutDirection(Qt::LayoutDirection direction)
-{
- Q_D(QWidget);
-
- if (direction == Qt::LayoutDirectionAuto) {
- unsetLayoutDirection();
- return;
- }
-
- setAttribute(Qt::WA_SetLayoutDirection);
- d->setLayoutDirection_helper(direction);
-}
-
-Qt::LayoutDirection QWidget::layoutDirection() const
-{
- return testAttribute(Qt::WA_RightToLeft) ? Qt::RightToLeft : Qt::LeftToRight;
-}
-
-void QWidget::unsetLayoutDirection()
-{
- Q_D(QWidget);
- setAttribute(Qt::WA_SetLayoutDirection, false);
- d->resolveLayoutDirection();
-}
-
-/*!
- \fn QFontMetrics QWidget::fontMetrics() const
-
- Returns the font metrics for the widget's current font.
- Equivalent to QFontMetrics(widget->font()).
-
- \sa font(), fontInfo(), setFont()
-*/
-
-/*!
- \fn QFontInfo QWidget::fontInfo() const
-
- Returns the font info for the widget's current font.
- Equivalent to QFontInto(widget->font()).
-
- \sa font(), fontMetrics(), setFont()
-*/
-
-
-/*!
- \property QWidget::cursor
- \brief the cursor shape for this widget
-
- The mouse cursor will assume this shape when it's over this
- widget. See the \link Qt::CursorShape list of predefined cursor
- objects\endlink for a range of useful shapes.
-
- An editor widget might use an I-beam cursor:
- \snippet doc/src/snippets/code/src_gui_kernel_qwidget.cpp 6
-
- If no cursor has been set, or after a call to unsetCursor(), the
- parent's cursor is used.
-
- By default, this property contains a cursor with the Qt::ArrowCursor
- shape.
-
- Some underlying window implementations will reset the cursor if it
- leaves a widget even if the mouse is grabbed. If you want to have
- a cursor set for all widgets, even when outside the window, consider
- QApplication::setOverrideCursor().
-
- \sa QApplication::setOverrideCursor()
-*/
-
-#ifndef QT_NO_CURSOR
-QCursor QWidget::cursor() const
-{
- Q_D(const QWidget);
- if (testAttribute(Qt::WA_SetCursor))
- return (d->extra && d->extra->curs)
- ? *d->extra->curs
- : QCursor(Qt::ArrowCursor);
- if (isWindow() || !parentWidget())
- return QCursor(Qt::ArrowCursor);
- return parentWidget()->cursor();
-}
-
-void QWidget::setCursor(const QCursor &cursor)
-{
- Q_D(QWidget);
-// On Mac we must set the cursor even if it is the ArrowCursor.
-#if !defined(Q_WS_MAC) && !defined(Q_WS_QWS)
- if (cursor.shape() != Qt::ArrowCursor
- || (d->extra && d->extra->curs))
-#endif
- {
- d->createExtra();
- QCursor *newCursor = new QCursor(cursor);
- delete d->extra->curs;
- d->extra->curs = newCursor;
- }
- setAttribute(Qt::WA_SetCursor);
- d->setCursor_sys(cursor);
-
- QEvent event(QEvent::CursorChange);
- QApplication::sendEvent(this, &event);
-}
-
-void QWidget::unsetCursor()
-{
- Q_D(QWidget);
- if (d->extra) {
- delete d->extra->curs;
- d->extra->curs = 0;
- }
- if (!isWindow())
- setAttribute(Qt::WA_SetCursor, false);
- d->unsetCursor_sys();
-
- QEvent event(QEvent::CursorChange);
- QApplication::sendEvent(this, &event);
-}
-
-#endif
-
-/*!
- \enum QWidget::RenderFlag
-
- This enum describes how to render the widget when calling QWidget::render().
-
- \value DrawWindowBackground If you enable this option, the widget's background
- is rendered into the target even if autoFillBackground is not set. By default,
- this option is enabled.
-
- \value DrawChildren If you enable this option, the widget's children
- are rendered recursively into the target. By default, this option is enabled.
-
- \value IgnoreMask If you enable this option, the widget's QWidget::mask()
- is ignored when rendering into the target. By default, this option is disabled.
-
- \since 4.3
-*/
-
-/*!
- \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:
-
- \snippet doc/src/snippets/code/src_gui_kernel_qwidget.cpp 7
-
- If \a sourceRegion is a null region, this function will use QWidget::rect() as
- the region, i.e. the entire widget.
-
- 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
-
- \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)
-{
- d_func()->render(target, targetOffset, sourceRegion, renderFlags, false);
-}
-
-/*!
- \overload
-
- Renders the widget into the \a painter's QPainter::device().
-
- Transformations and settings applied to the \a painter will be used
- when rendering.
-
- \note The \a painter must be active. On Mac OS X the widget will be
- rendered into a QPixmap and then drawn by the \a painter.
-
- \sa QPainter::device()
-*/
-void QWidget::render(QPainter *painter, const QPoint &targetOffset,
- const QRegion &sourceRegion, RenderFlags renderFlags)
-{
- if (!painter) {
- qWarning("QWidget::render: Null pointer to painter");
- return;
- }
-
- if (!painter->isActive()) {
- qWarning("QWidget::render: Cannot render with an inactive painter");
- return;
- }
-
- const qreal opacity = painter->opacity();
- if (qFuzzyIsNull(opacity))
- return; // Fully transparent.
-
- Q_D(QWidget);
- const bool inRenderWithPainter = d->extra && d->extra->inRenderWithPainter;
- const QRegion toBePainted = !inRenderWithPainter ? d->prepareToRender(sourceRegion, renderFlags)
- : sourceRegion;
- if (toBePainted.isEmpty())
- return;
-
- if (!d->extra)
- d->createExtra();
- d->extra->inRenderWithPainter = true;
-
-#ifdef Q_WS_MAC
- d->render_helper(painter, targetOffset, toBePainted, renderFlags);
-#else
- QPaintEngine *engine = painter->paintEngine();
- Q_ASSERT(engine);
- QPaintEnginePrivate *enginePriv = engine->d_func();
- Q_ASSERT(enginePriv);
- QPaintDevice *target = engine->paintDevice();
- Q_ASSERT(target);
-
- // Render via a pixmap when dealing with non-opaque painters or printers.
- if (!inRenderWithPainter && (opacity < 1.0 || (target->devType() == QInternal::Printer))) {
- d->render_helper(painter, targetOffset, toBePainted, renderFlags);
- d->extra->inRenderWithPainter = false;
- return;
- }
-
- // Set new shared painter.
- QPainter *oldPainter = d->sharedPainter();
- d->setSharedPainter(painter);
-
- // Save current system clip, viewport and transform,
- const QTransform oldTransform = enginePriv->systemTransform;
- const QRegion oldSystemClip = enginePriv->systemClip;
- const QRegion oldSystemViewport = enginePriv->systemViewport;
-
- // This ensures that all painting triggered by render() is clipped to the current engine clip.
- if (painter->hasClipping()) {
- const QRegion painterClip = painter->deviceTransform().map(painter->clipRegion());
- enginePriv->setSystemViewport(oldSystemClip.isEmpty() ? painterClip : oldSystemClip & painterClip);
- } else {
- enginePriv->setSystemViewport(oldSystemClip);
- }
-
- render(target, targetOffset, toBePainted, renderFlags);
-
- // Restore system clip, viewport and transform.
- enginePriv->systemClip = oldSystemClip;
- enginePriv->setSystemViewport(oldSystemViewport);
- enginePriv->setSystemTransform(oldTransform);
-
- // Restore shared painter.
- d->setSharedPainter(oldPainter);
-#endif
-
- d->extra->inRenderWithPainter = false;
-}
-
-/*!
- \brief The graphicsEffect function returns a pointer to the
- widget's graphics effect.
-
- If the widget has no graphics effect, 0 is returned.
-
- \since 4.6
-
- \sa setGraphicsEffect()
-*/
-#ifndef QT_NO_GRAPHICSEFFECT
-QGraphicsEffect *QWidget::graphicsEffect() const
-{
- Q_D(const QWidget);
- return d->graphicsEffect;
-}
-#endif //QT_NO_GRAPHICSEFFECT
-
-/*!
-
- \brief The setGraphicsEffect function is for setting the widget's graphics effect.
-
- Sets \a effect as the widget's effect. If there already is an effect installed
- on this widget, QWidget will delete the existing effect before installing
- the new \a effect.
-
- If \a effect is the installed on a different widget, setGraphicsEffect() will remove
- the effect from the widget and install it on this widget.
-
- QWidget takes ownership of \a effect.
-
- \note This function will apply the effect on itself and all its children.
-
- \since 4.6
-
- \sa graphicsEffect()
-*/
-#ifndef QT_NO_GRAPHICSEFFECT
-void QWidget::setGraphicsEffect(QGraphicsEffect *effect)
-{
- Q_D(QWidget);
- if (d->graphicsEffect == effect)
- return;
-
- if (d->graphicsEffect) {
- d->invalidateBuffer(rect());
- delete d->graphicsEffect;
- d->graphicsEffect = 0;
- }
-
- if (effect) {
- // Set new effect.
- QGraphicsEffectSourcePrivate *sourced = new QWidgetEffectSourcePrivate(this);
- QGraphicsEffectSource *source = new QGraphicsEffectSource(*sourced);
- d->graphicsEffect = effect;
- effect->d_func()->setGraphicsEffectSource(source);
- update();
- }
-
- d->updateIsOpaque();
-}
-#endif //QT_NO_GRAPHICSEFFECT
-
-bool QWidgetPrivate::isAboutToShow() const
-{
- if (data.in_show)
- return true;
-
- Q_Q(const QWidget);
- if (q->isHidden())
- return false;
-
- // The widget will be shown if any of its ancestors are about to show.
- QWidget *parent = q->parentWidget();
- return parent ? parent->d_func()->isAboutToShow() : false;
-}
-
-QRegion QWidgetPrivate::prepareToRender(const QRegion &region, QWidget::RenderFlags renderFlags)
-{
- Q_Q(QWidget);
- const bool isVisible = q->isVisible();
-
- // Make sure the widget is laid out correctly.
- if (!isVisible && !isAboutToShow()) {
- QWidget *topLevel = q->window();
- (void)topLevel->d_func()->topData(); // Make sure we at least have top-data.
- topLevel->ensurePolished();
-
- // Invalidate the layout of hidden ancestors (incl. myself) and pretend
- // they're not explicitly hidden.
- QWidget *widget = q;
- QWidgetList hiddenWidgets;
- while (widget) {
- if (widget->isHidden()) {
- widget->setAttribute(Qt::WA_WState_Hidden, false);
- hiddenWidgets.append(widget);
- if (!widget->isWindow() && widget->parentWidget()->d_func()->layout)
- widget->d_func()->updateGeometry_helper(true);
- }
- widget = widget->parentWidget();
- }
-
- // Activate top-level layout.
- if (topLevel->d_func()->layout)
- topLevel->d_func()->layout->activate();
-
- // Adjust size if necessary.
- QTLWExtra *topLevelExtra = topLevel->d_func()->maybeTopData();
- if (topLevelExtra && !topLevelExtra->sizeAdjusted
- && !topLevel->testAttribute(Qt::WA_Resized)) {
- topLevel->adjustSize();
- topLevel->setAttribute(Qt::WA_Resized, false);
- }
-
- // Activate child layouts.
- topLevel->d_func()->activateChildLayoutsRecursively();
-
- // We're not cheating with WA_WState_Hidden anymore.
- for (int i = 0; i < hiddenWidgets.size(); ++i) {
- QWidget *widget = hiddenWidgets.at(i);
- widget->setAttribute(Qt::WA_WState_Hidden);
- if (!widget->isWindow() && widget->parentWidget()->d_func()->layout)
- widget->parentWidget()->d_func()->layout->invalidate();
- }
- } else if (isVisible) {
- q->window()->d_func()->sendPendingMoveAndResizeEvents(true, true);
- }
-
- // Calculate the region to be painted.
- QRegion toBePainted = !region.isEmpty() ? region : QRegion(q->rect());
- if (!(renderFlags & QWidget::IgnoreMask) && extra && extra->hasMask)
- toBePainted &= extra->mask;
- return toBePainted;
-}
-
-void QWidgetPrivate::render_helper(QPainter *painter, const QPoint &targetOffset, const QRegion &toBePainted,
- QWidget::RenderFlags renderFlags)
-{
- Q_ASSERT(painter);
- Q_ASSERT(!toBePainted.isEmpty());
-
- Q_Q(QWidget);
-#ifndef Q_WS_MAC
- const QTransform originalTransform = painter->worldTransform();
- const bool useDeviceCoordinates = originalTransform.isScaling();
- if (!useDeviceCoordinates) {
-#endif
- // Render via a pixmap.
- const QRect rect = toBePainted.boundingRect();
- const QSize size = rect.size();
- if (size.isNull())
- return;
-
- QPixmap pixmap(size);
- if (!(renderFlags & QWidget::DrawWindowBackground) || !isOpaque)
- pixmap.fill(Qt::transparent);
- q->render(&pixmap, QPoint(), toBePainted, renderFlags);
-
- const bool restore = !(painter->renderHints() & QPainter::SmoothPixmapTransform);
- painter->setRenderHints(QPainter::SmoothPixmapTransform, true);
-
- painter->drawPixmap(targetOffset, pixmap);
-
- if (restore)
- painter->setRenderHints(QPainter::SmoothPixmapTransform, false);
-
-#ifndef Q_WS_MAC
- } else {
- // Render via a pixmap in device coordinates (to avoid pixmap scaling).
- QTransform transform = originalTransform;
- transform.translate(targetOffset.x(), targetOffset.y());
-
- QPaintDevice *device = painter->device();
- Q_ASSERT(device);
-
- // Calculate device rect.
- const QRectF rect(toBePainted.boundingRect());
- QRect deviceRect = transform.mapRect(QRectF(0, 0, rect.width(), rect.height())).toAlignedRect();
- deviceRect &= QRect(0, 0, device->width(), device->height());
-
- QPixmap pixmap(deviceRect.size());
- pixmap.fill(Qt::transparent);
-
- // Create a pixmap device coordinate painter.
- QPainter pixmapPainter(&pixmap);
- pixmapPainter.setRenderHints(painter->renderHints());
- transform *= QTransform::fromTranslate(-deviceRect.x(), -deviceRect.y());
- pixmapPainter.setTransform(transform);
-
- q->render(&pixmapPainter, QPoint(), toBePainted, renderFlags);
- pixmapPainter.end();
-
- // And then draw the pixmap.
- painter->setTransform(QTransform());
- painter->drawPixmap(deviceRect.topLeft(), pixmap);
- painter->setTransform(originalTransform);
- }
-#endif
-}
-
-void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QPoint &offset, int flags,
- QPainter *sharedPainter, QWidgetBackingStore *backingStore)
-{
- if (rgn.isEmpty())
- return;
-
-#if defined(Q_WS_MAC) && defined(QT_MAC_USE_COCOA)
- if (qt_mac_clearDirtyOnWidgetInsideDrawWidget)
- dirtyOnWidget = QRegion();
-
- // We disable the rendering of QToolBar in the backingStore if
- // it's supposed to be in the unified toolbar on Mac OS X.
- if (backingStore && isInUnifiedToolbar)
- return;
-#endif // Q_WS_MAC && QT_MAC_USE_COCOA
-
-
- Q_Q(QWidget);
-#ifndef QT_NO_GRAPHICSEFFECT
- if (graphicsEffect && graphicsEffect->isEnabled()) {
- QGraphicsEffectSource *source = graphicsEffect->d_func()->source;
- QWidgetEffectSourcePrivate *sourced = static_cast<QWidgetEffectSourcePrivate *>
- (source->d_func());
- if (!sourced->context) {
- QWidgetPaintContext context(pdev, rgn, offset, flags, sharedPainter, backingStore);
- sourced->context = &context;
- if (!sharedPainter) {
- QPaintEngine *paintEngine = pdev->paintEngine();
- paintEngine->d_func()->systemClip = rgn.translated(offset);
- QPainter p(pdev);
- p.translate(offset);
- context.painter = &p;
- graphicsEffect->draw(&p);
- paintEngine->d_func()->systemClip = QRegion();
- } else {
- context.painter = sharedPainter;
- if (sharedPainter->worldTransform() != sourced->lastEffectTransform) {
- sourced->invalidateCache();
- sourced->lastEffectTransform = sharedPainter->worldTransform();
- }
- sharedPainter->save();
- sharedPainter->translate(offset);
- graphicsEffect->draw(sharedPainter);
- sharedPainter->restore();
- }
- sourced->context = 0;
- return;
- }
- }
-#endif //QT_NO_GRAFFICSEFFECT
-
- const bool asRoot = flags & DrawAsRoot;
- const bool alsoOnScreen = flags & DrawPaintOnScreen;
- const bool recursive = flags & DrawRecursive;
- const bool alsoInvisible = flags & DrawInvisible;
-
- Q_ASSERT(sharedPainter ? sharedPainter->isActive() : true);
-
- QRegion toBePainted(rgn);
- if (asRoot && !alsoInvisible)
- toBePainted &= clipRect(); //(rgn & visibleRegion());
- if (!(flags & DontSubtractOpaqueChildren))
- subtractOpaqueChildren(toBePainted, q->rect());
-
- if (!toBePainted.isEmpty()) {
- bool onScreen = paintOnScreen();
- if (!onScreen || alsoOnScreen) {
- //update the "in paint event" flag
- if (q->testAttribute(Qt::WA_WState_InPaintEvent))
- qWarning("QWidget::repaint: Recursive repaint detected");
- q->setAttribute(Qt::WA_WState_InPaintEvent);
-
- //clip away the new area
-#ifndef QT_NO_PAINT_DEBUG
- bool flushed = QWidgetBackingStore::flushPaint(q, toBePainted);
-#endif
- QPaintEngine *paintEngine = pdev->paintEngine();
- if (paintEngine) {
- setRedirected(pdev, -offset);
-
-#ifdef Q_WS_MAC
- // (Alien support) Special case for Mac when redirecting: If the paint device
- // is of the Widget type we need to set WA_WState_InPaintEvent since painting
- // outside the paint event is not supported on QWidgets. The attributeis
- // restored further down.
- if (pdev->devType() == QInternal::Widget)
- static_cast<QWidget *>(pdev)->setAttribute(Qt::WA_WState_InPaintEvent);
-
-#endif
- if (sharedPainter)
- paintEngine->d_func()->systemClip = toBePainted;
- else
- paintEngine->d_func()->systemRect = q->data->crect;
-
- //paint the background
- if ((asRoot || q->autoFillBackground() || onScreen || q->testAttribute(Qt::WA_StyledBackground))
- && !q->testAttribute(Qt::WA_OpaquePaintEvent) && !q->testAttribute(Qt::WA_NoSystemBackground)) {
- QPainter p(q);
- paintBackground(&p, toBePainted, (asRoot || onScreen) ? flags | DrawAsRoot : 0);
- }
-
- if (!sharedPainter)
- paintEngine->d_func()->systemClip = toBePainted.translated(offset);
-
- if (!onScreen && !asRoot && !isOpaque && q->testAttribute(Qt::WA_TintedBackground)) {
- QPainter p(q);
- QColor tint = q->palette().window().color();
- tint.setAlphaF(qreal(.6));
- p.fillRect(toBePainted.boundingRect(), tint);
- }
- }
-
-#if 0
- qDebug() << "painting" << q << "opaque ==" << isOpaque();
- qDebug() << "clipping to" << toBePainted << "location == " << offset
- << "geometry ==" << QRect(q->mapTo(q->window(), QPoint(0, 0)), q->size());
-#endif
-
- //actually send the paint event
- QPaintEvent e(toBePainted);
- QCoreApplication::sendSpontaneousEvent(q, &e);
-#if !defined(Q_WS_QWS) && !defined(Q_WS_QPA)
- if (backingStore && !onScreen && !asRoot && (q->internalWinId() || !q->nativeParentWidget()->isWindow()))
- backingStore->markDirtyOnScreen(toBePainted, q, offset);
-#endif
-
- //restore
- if (paintEngine) {
-#ifdef Q_WS_MAC
- if (pdev->devType() == QInternal::Widget)
- static_cast<QWidget *>(pdev)->setAttribute(Qt::WA_WState_InPaintEvent, false);
-#endif
- restoreRedirected();
- if (!sharedPainter)
- paintEngine->d_func()->systemRect = QRect();
- else
- paintEngine->d_func()->currentClipWidget = 0;
- paintEngine->d_func()->systemClip = QRegion();
- }
- q->setAttribute(Qt::WA_WState_InPaintEvent, false);
- if (q->paintingActive() && !q->testAttribute(Qt::WA_PaintOutsidePaintEvent))
- qWarning("QWidget::repaint: It is dangerous to leave painters active on a widget outside of the PaintEvent");
-
- if (paintEngine && paintEngine->autoDestruct()) {
- delete paintEngine;
- }
-
-#ifndef QT_NO_PAINT_DEBUG
- if (flushed)
- QWidgetBackingStore::unflushPaint(q, toBePainted);
-#endif
- } else if (q->isWindow()) {
- QPaintEngine *engine = pdev->paintEngine();
- if (engine) {
- QPainter p(pdev);
- p.setClipRegion(toBePainted);
- const QBrush bg = q->palette().brush(QPalette::Window);
- if (bg.style() == Qt::TexturePattern)
- p.drawTiledPixmap(q->rect(), bg.texture());
- else
- p.fillRect(q->rect(), bg);
-
- if (engine->autoDestruct())
- delete engine;
- }
- }
- }
-
- if (recursive && !children.isEmpty()) {
- paintSiblingsRecursive(pdev, children, children.size() - 1, rgn, offset, flags & ~DrawAsRoot
-#ifdef Q_BACKINGSTORE_SUBSURFACES
- , q->windowSurface()
-#endif
- , sharedPainter, backingStore);
- }
-}
-
-void QWidgetPrivate::render(QPaintDevice *target, const QPoint &targetOffset,
- const QRegion &sourceRegion, QWidget::RenderFlags renderFlags,
- bool readyToRender)
-{
- if (!target) {
- qWarning("QWidget::render: null pointer to paint device");
- return;
- }
-
- const bool inRenderWithPainter = extra && extra->inRenderWithPainter;
- QRegion paintRegion = !inRenderWithPainter && !readyToRender
- ? prepareToRender(sourceRegion, renderFlags)
- : sourceRegion;
- if (paintRegion.isEmpty())
- return;
-
-#ifndef Q_WS_MAC
- QPainter *oldSharedPainter = inRenderWithPainter ? sharedPainter() : 0;
-
- // Use the target's shared painter if set (typically set when doing
- // "other->render(widget);" in the widget's paintEvent.
- if (target->devType() == QInternal::Widget) {
- QWidgetPrivate *targetPrivate = static_cast<QWidget *>(target)->d_func();
- if (targetPrivate->extra && targetPrivate->extra->inRenderWithPainter) {
- QPainter *targetPainter = targetPrivate->sharedPainter();
- if (targetPainter && targetPainter->isActive())
- setSharedPainter(targetPainter);
- }
- }
-#endif
-
- // Use the target's redirected device if set and adjust offset and paint
- // region accordingly. This is typically the case when people call render
- // from the paintEvent.
- QPoint offset = targetOffset;
- offset -= paintRegion.boundingRect().topLeft();
- QPoint redirectionOffset;
- QPaintDevice *redirected = 0;
-
- if (target->devType() == QInternal::Widget)
- redirected = static_cast<QWidget *>(target)->d_func()->redirected(&redirectionOffset);
- if (!redirected)
- redirected = QPainter::redirected(target, &redirectionOffset);
-
- if (redirected) {
- target = redirected;
- offset -= redirectionOffset;
- }
-
- if (!inRenderWithPainter) { // Clip handled by shared painter (in qpainter.cpp).
- if (QPaintEngine *targetEngine = target->paintEngine()) {
- const QRegion targetSystemClip = targetEngine->systemClip();
- if (!targetSystemClip.isEmpty())
- paintRegion &= targetSystemClip.translated(-offset);
- }
- }
-
- // Set backingstore flags.
- int flags = DrawPaintOnScreen | DrawInvisible;
- if (renderFlags & QWidget::DrawWindowBackground)
- flags |= DrawAsRoot;
-
- if (renderFlags & QWidget::DrawChildren)
- flags |= DrawRecursive;
- else
- flags |= DontSubtractOpaqueChildren;
-
-#ifdef Q_WS_QWS
- flags |= DontSetCompositionMode;
-#endif
-
- if (target->devType() == QInternal::Printer) {
- QPainter p(target);
- render_helper(&p, targetOffset, paintRegion, renderFlags);
- return;
- }
-
-#ifndef Q_WS_MAC
- // Render via backingstore.
- drawWidget(target, paintRegion, offset, flags, sharedPainter());
-
- // Restore shared painter.
- if (oldSharedPainter)
- setSharedPainter(oldSharedPainter);
-#else
- // Render via backingstore (no shared painter).
- drawWidget(target, paintRegion, offset, flags, 0);
-#endif
-}
-
-void QWidgetPrivate::paintSiblingsRecursive(QPaintDevice *pdev, const QObjectList& siblings, int index, const QRegion &rgn,
- const QPoint &offset, int flags
-#ifdef Q_BACKINGSTORE_SUBSURFACES
- , const QWindowSurface *currentSurface
-#endif
- , QPainter *sharedPainter, QWidgetBackingStore *backingStore)
-{
- QWidget *w = 0;
- QRect boundingRect;
- bool dirtyBoundingRect = true;
- const bool exludeOpaqueChildren = (flags & DontDrawOpaqueChildren);
- const bool excludeNativeChildren = (flags & DontDrawNativeChildren);
-
- do {
- QWidget *x = qobject_cast<QWidget*>(siblings.at(index));
- if (x && !(exludeOpaqueChildren && x->d_func()->isOpaque) && !x->isHidden() && !x->isWindow()
- && !(excludeNativeChildren && x->internalWinId())) {
- if (dirtyBoundingRect) {
- boundingRect = rgn.boundingRect();
- dirtyBoundingRect = false;
- }
-
- if (qRectIntersects(boundingRect, x->d_func()->effectiveRectFor(x->data->crect))) {
-#ifdef Q_BACKINGSTORE_SUBSURFACES
- if (x->windowSurface() == currentSurface)
-#endif
- {
- w = x;
- break;
- }
- }
- }
- --index;
- } while (index >= 0);
-
- if (!w)
- return;
-
- QWidgetPrivate *wd = w->d_func();
- const QPoint widgetPos(w->data->crect.topLeft());
- const bool hasMask = wd->extra && wd->extra->hasMask && !wd->graphicsEffect;
- if (index > 0) {
- QRegion wr(rgn);
- if (wd->isOpaque)
- wr -= hasMask ? wd->extra->mask.translated(widgetPos) : w->data->crect;
- paintSiblingsRecursive(pdev, siblings, --index, wr, offset, flags
-#ifdef Q_BACKINGSTORE_SUBSURFACES
- , currentSurface
-#endif
- , sharedPainter, backingStore);
- }
-
- if (w->updatesEnabled()
-#ifndef QT_NO_GRAPHICSVIEW
- && (!w->d_func()->extra || !w->d_func()->extra->proxyWidget)
-#endif //QT_NO_GRAPHICSVIEW
- ) {
- QRegion wRegion(rgn);
- wRegion &= wd->effectiveRectFor(w->data->crect);
- wRegion.translate(-widgetPos);
- if (hasMask)
- wRegion &= wd->extra->mask;
- wd->drawWidget(pdev, wRegion, offset + widgetPos, flags, sharedPainter, backingStore);
- }
-}
-
-#ifndef QT_NO_GRAPHICSEFFECT
-QRectF QWidgetEffectSourcePrivate::boundingRect(Qt::CoordinateSystem system) const
-{
- if (system != Qt::DeviceCoordinates)
- return m_widget->rect();
-
- if (!context) {
- // Device coordinates without context not yet supported.
- qWarning("QGraphicsEffectSource::boundingRect: Not yet implemented, lacking device context");
- return QRectF();
- }
-
- return context->painter->worldTransform().mapRect(m_widget->rect());
-}
-
-void QWidgetEffectSourcePrivate::draw(QPainter *painter)
-{
- if (!context || context->painter != painter) {
- m_widget->render(painter);
- return;
- }
-
- // The region saved in the context is neither clipped to the rect
- // nor the mask, so we have to clip it here before calling drawWidget.
- QRegion toBePainted = context->rgn;
- toBePainted &= m_widget->rect();
- QWidgetPrivate *wd = qt_widget_private(m_widget);
- if (wd->extra && wd->extra->hasMask)
- toBePainted &= wd->extra->mask;
-
- wd->drawWidget(context->pdev, toBePainted, context->offset, context->flags,
- context->sharedPainter, context->backingStore);
-}
-
-QPixmap QWidgetEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QPoint *offset,
- QGraphicsEffect::PixmapPadMode mode) const
-{
- const bool deviceCoordinates = (system == Qt::DeviceCoordinates);
- if (!context && deviceCoordinates) {
- // Device coordinates without context not yet supported.
- qWarning("QGraphicsEffectSource::pixmap: Not yet implemented, lacking device context");
- return QPixmap();
- }
-
- QPoint pixmapOffset;
- QRectF sourceRect = m_widget->rect();
-
- if (deviceCoordinates) {
- const QTransform &painterTransform = context->painter->worldTransform();
- sourceRect = painterTransform.mapRect(sourceRect);
- pixmapOffset = painterTransform.map(pixmapOffset);
- }
-
- QRect effectRect;
-
- if (mode == QGraphicsEffect::PadToEffectiveBoundingRect)
- effectRect = m_widget->graphicsEffect()->boundingRectFor(sourceRect).toAlignedRect();
- else if (mode == QGraphicsEffect::PadToTransparentBorder)
- effectRect = sourceRect.adjusted(-1, -1, 1, 1).toAlignedRect();
- else
- effectRect = sourceRect.toAlignedRect();
-
- if (offset)
- *offset = effectRect.topLeft();
-
- pixmapOffset -= effectRect.topLeft();
-
- QPixmap pixmap(effectRect.size());
- pixmap.fill(Qt::transparent);
- m_widget->render(&pixmap, pixmapOffset, QRegion(), QWidget::DrawChildren);
- return pixmap;
-}
-#endif //QT_NO_GRAPHICSEFFECT
-
-#ifndef QT_NO_GRAPHICSVIEW
-/*!
- \internal
-
- Finds the nearest widget embedded in a graphics proxy widget along the chain formed by this
- widget and its ancestors. The search starts at \a origin (inclusive).
- If successful, the function returns the proxy that embeds the widget, or 0 if no embedded
- widget was found.
-*/
-QGraphicsProxyWidget * QWidgetPrivate::nearestGraphicsProxyWidget(const QWidget *origin)
-{
- if (origin) {
- QWExtra *extra = origin->d_func()->extra;
- if (extra && extra->proxyWidget)
- return extra->proxyWidget;
- return nearestGraphicsProxyWidget(origin->parentWidget());
- }
- return 0;
-}
-#endif
-
-/*!
- \property QWidget::locale
- \brief the widget's locale
- \since 4.3
-
- As long as no special locale has been set, this is either
- the parent's locale or (if this widget is a top level widget),
- the default locale.
-
- If the widget displays dates or numbers, these should be formatted
- using the widget's locale.
-
- \sa QLocale QLocale::setDefault()
-*/
-
-void QWidgetPrivate::setLocale_helper(const QLocale &loc, bool forceUpdate)
-{
- Q_Q(QWidget);
- if (locale == loc && !forceUpdate)
- return;
-
- locale = loc;
-
- if (!children.isEmpty()) {
- for (int i = 0; i < children.size(); ++i) {
- QWidget *w = qobject_cast<QWidget*>(children.at(i));
- if (!w)
- continue;
- if (w->testAttribute(Qt::WA_SetLocale))
- continue;
- if (w->isWindow() && !w->testAttribute(Qt::WA_WindowPropagation))
- continue;
- w->d_func()->setLocale_helper(loc, forceUpdate);
- }
- }
- QEvent e(QEvent::LocaleChange);
- QApplication::sendEvent(q, &e);
-}
-
-void QWidget::setLocale(const QLocale &locale)
-{
- Q_D(QWidget);
-
- setAttribute(Qt::WA_SetLocale);
- d->setLocale_helper(locale);
-}
-
-QLocale QWidget::locale() const
-{
- Q_D(const QWidget);
-
- return d->locale;
-}
-
-void QWidgetPrivate::resolveLocale()
-{
- Q_Q(const QWidget);
-
- if (!q->testAttribute(Qt::WA_SetLocale)) {
- setLocale_helper(q->isWindow()
- ? QLocale()
- : q->parentWidget()->locale());
- }
-}
-
-void QWidget::unsetLocale()
-{
- Q_D(QWidget);
- setAttribute(Qt::WA_SetLocale, false);
- d->resolveLocale();
-}
-
-static QString constructWindowTitleFromFilePath(const QString &filePath)
-{
- QFileInfo fi(filePath);
- QString windowTitle = fi.fileName() + QLatin1String("[*]");
-#ifndef Q_WS_MAC
- QString appName = QApplication::applicationName();
- if (!appName.isEmpty())
- windowTitle += QLatin1Char(' ') + QChar(0x2014) + QLatin1Char(' ') + appName;
-#endif
- return windowTitle;
-}
-
-/*!
- \property QWidget::windowTitle
- \brief the window title (caption)
-
- This property only makes sense for top-level widgets, such as
- windows and dialogs. If no caption has been set, the title is based of the
- \l windowFilePath. If neither of these is set, then the title is
- an empty string.
-
- If you use the \l windowModified mechanism, the window title must
- contain a "[*]" placeholder, which indicates where the '*' should
- appear. Normally, it should appear right after the file name
- (e.g., "document1.txt[*] - Text Editor"). If the \l
- windowModified property is false (the default), the placeholder
- is simply removed.
-
- \sa windowIcon, windowIconText, windowModified, windowFilePath
-*/
-QString QWidget::windowTitle() const
-{
- Q_D(const QWidget);
- if (d->extra && d->extra->topextra) {
- if (!d->extra->topextra->caption.isEmpty())
- return d->extra->topextra->caption;
- if (!d->extra->topextra->filePath.isEmpty())
- return constructWindowTitleFromFilePath(d->extra->topextra->filePath);
- }
- return QString();
-}
-
-/*!
- Returns a modified window title with the [*] place holder
- replaced according to the rules described in QWidget::setWindowTitle
-
- This function assumes that "[*]" can be quoted by another
- "[*]", so it will replace two place holders by one and
- a single last one by either "*" or nothing depending on
- the modified flag.
-
- \internal
-*/
-QString qt_setWindowTitle_helperHelper(const QString &title, const QWidget *widget)
-{
- Q_ASSERT(widget);
-
-#ifdef QT_EVAL
- extern QString qt_eval_adapt_window_title(const QString &title);
- QString cap = qt_eval_adapt_window_title(title);
-#else
- QString cap = title;
-#endif
-
- if (cap.isEmpty())
- return cap;
-
- QLatin1String placeHolder("[*]");
- int placeHolderLength = 3; // QLatin1String doesn't have length()
-
- int index = cap.indexOf(placeHolder);
-
- // here the magic begins
- while (index != -1) {
- index += placeHolderLength;
- int count = 1;
- while (cap.indexOf(placeHolder, index) == index) {
- ++count;
- index += placeHolderLength;
- }
-
- if (count%2) { // odd number of [*] -> replace last one
- int lastIndex = cap.lastIndexOf(placeHolder, index - 1);
- if (widget->isWindowModified()
- && widget->style()->styleHint(QStyle::SH_TitleBar_ModifyNotification, 0, widget))
- cap.replace(lastIndex, 3, QWidget::tr("*"));
- else
- cap.remove(lastIndex, 3);
- }
-
- index = cap.indexOf(placeHolder, index);
- }
-
- cap.replace(QLatin1String("[*][*]"), placeHolder);
-
- return cap;
-}
-
-void QWidgetPrivate::setWindowTitle_helper(const QString &title)
-{
- Q_Q(QWidget);
- if (q->testAttribute(Qt::WA_WState_Created))
- setWindowTitle_sys(qt_setWindowTitle_helperHelper(title, q));
-}
-
-void QWidgetPrivate::setWindowIconText_helper(const QString &title)
-{
- Q_Q(QWidget);
- if (q->testAttribute(Qt::WA_WState_Created))
- setWindowIconText_sys(qt_setWindowTitle_helperHelper(title, q));
-}
-
-void QWidget::setWindowIconText(const QString &iconText)
-{
- if (QWidget::windowIconText() == iconText)
- return;
-
- Q_D(QWidget);
- d->topData()->iconText = iconText;
- d->setWindowIconText_helper(iconText);
-
- QEvent e(QEvent::IconTextChange);
- QApplication::sendEvent(this, &e);
-}
-
-void QWidget::setWindowTitle(const QString &title)
-{
- if (QWidget::windowTitle() == title && !title.isEmpty() && !title.isNull())
- return;
-
- Q_D(QWidget);
- d->topData()->caption = title;
- d->setWindowTitle_helper(title);
-
- QEvent e(QEvent::WindowTitleChange);
- QApplication::sendEvent(this, &e);
-}
-
-
-/*!
- \property QWidget::windowIcon
- \brief the widget's icon
-
- This property only makes sense for windows. If no icon
- has been set, windowIcon() returns the application icon
- (QApplication::windowIcon()).
-
- \sa windowIconText, windowTitle
-*/
-QIcon QWidget::windowIcon() const
-{
- const QWidget *w = this;
- while (w) {
- const QWidgetPrivate *d = w->d_func();
- if (d->extra && d->extra->topextra && d->extra->topextra->icon)
- return *d->extra->topextra->icon;
- w = w->parentWidget();
- }
- return QApplication::windowIcon();
-}
-
-void QWidgetPrivate::setWindowIcon_helper()
-{
- QEvent e(QEvent::WindowIconChange);
- QApplication::sendEvent(q_func(), &e);
- for (int i = 0; i < children.size(); ++i) {
- QWidget *w = qobject_cast<QWidget *>(children.at(i));
- if (w && !w->isWindow())
- QApplication::sendEvent(w, &e);
- }
-}
-
-void QWidget::setWindowIcon(const QIcon &icon)
-{
- Q_D(QWidget);
-
- setAttribute(Qt::WA_SetWindowIcon, !icon.isNull());
- d->createTLExtra();
-
- if (!d->extra->topextra->icon)
- d->extra->topextra->icon = new QIcon();
- *d->extra->topextra->icon = icon;
-
- delete d->extra->topextra->iconPixmap;
- d->extra->topextra->iconPixmap = 0;
-
- d->setWindowIcon_sys();
- d->setWindowIcon_helper();
-}
-
-
-/*!
- \property QWidget::windowIconText
- \brief the widget's icon text
-
- This property only makes sense for windows. If no icon
- text has been set, this functions returns an empty string.
-
- \sa windowIcon, windowTitle
-*/
-
-QString QWidget::windowIconText() const
-{
- Q_D(const QWidget);
- return (d->extra && d->extra->topextra) ? d->extra->topextra->iconText : QString();
-}
-
-/*!
- \property QWidget::windowFilePath
- \since 4.4
- \brief the file path associated with a widget
-
- This property only makes sense for windows. It associates a file path with
- a window. If you set the file path, but have not set the window title, Qt
- sets the window title to contain a string created using the following
- components.
-
- On Mac OS X:
-
- \list
- \o The file name of the specified path, obtained using QFileInfo::fileName().
- \endlist
-
- On Windows and X11:
-
- \list
- \o The file name of the specified path, obtained using QFileInfo::fileName().
- \o An optional \c{*} character, if the \l windowModified property is set.
- \o The \c{0x2014} unicode character, padded either side by spaces.
- \o The application name, obtained from the application's
- \l{QCoreApplication::}{applicationName} property.
- \endlist
-
- If the window title is set at any point, then the window title takes precedence and
- will be shown instead of the file path string.
-
- Additionally, on Mac OS X, this has an added benefit that it sets the
- \l{http://developer.apple.com/documentation/UserExperience/Conceptual/OSXHIGuidelines/XHIGWindows/chapter_17_section_3.html}{proxy icon}
- for the window, assuming that the file path exists.
-
- If no file path is set, this property contains an empty string.
-
- By default, this property contains an empty string.
-
- \sa windowTitle, windowIcon
-*/
-
-QString QWidget::windowFilePath() const
-{
- Q_D(const QWidget);
- return (d->extra && d->extra->topextra) ? d->extra->topextra->filePath : QString();
-}
-
-void QWidget::setWindowFilePath(const QString &filePath)
-{
- if (filePath == windowFilePath())
- return;
-
- Q_D(QWidget);
-
- d->createTLExtra();
- d->extra->topextra->filePath = filePath;
- d->setWindowFilePath_helper(filePath);
-}
-
-void QWidgetPrivate::setWindowFilePath_helper(const QString &filePath)
-{
- if (extra->topextra && extra->topextra->caption.isEmpty()) {
-#ifdef Q_WS_MAC
- setWindowTitle_helper(QFileInfo(filePath).fileName());
-#else
- Q_Q(QWidget);
- Q_UNUSED(filePath);
- setWindowTitle_helper(q->windowTitle());
-#endif
- }
-#ifdef Q_WS_MAC
- setWindowFilePath_sys(filePath);
-#endif
-}
-
-/*!
- Returns the window's role, or an empty string.
-
- \sa windowIcon, windowTitle
-*/
-
-QString QWidget::windowRole() const
-{
- Q_D(const QWidget);
- return (d->extra && d->extra->topextra) ? d->extra->topextra->role : QString();
-}
-
-/*!
- Sets the window's role to \a role. This only makes sense for
- windows on X11.
-*/
-void QWidget::setWindowRole(const QString &role)
-{
-#if defined(Q_WS_X11)
- Q_D(QWidget);
- d->topData()->role = role;
- d->setWindowRole();
-#else
- Q_UNUSED(role)
-#endif
-}
-
-/*!
- \property QWidget::mouseTracking
- \brief whether mouse tracking is enabled for the widget
-
- If mouse tracking is disabled (the default), the widget only
- receives mouse move events when at least one mouse button is
- pressed while the mouse is being moved.
-
- If mouse tracking is enabled, the widget receives mouse move
- events even if no buttons are pressed.
-
- \sa mouseMoveEvent()
-*/
-
-
-/*!
- Sets the widget's focus proxy to widget \a w. If \a w is 0, the
- function resets this widget to have no focus proxy.
-
- Some widgets can "have focus", but create a child widget, such as
- QLineEdit, to actually handle the focus. In this case, the widget
- can set the line edit to be its focus proxy.
-
- setFocusProxy() sets the widget which will actually get focus when
- "this widget" gets it. If there is a focus proxy, setFocus() and
- hasFocus() operate on the focus proxy.
-
- \sa focusProxy()
-*/
-
-void QWidget::setFocusProxy(QWidget * w)
-{
- Q_D(QWidget);
- if (!w && !d->extra)
- return;
-
- for (QWidget* fp = w; fp; fp = fp->focusProxy()) {
- if (fp == this) {
- qWarning("QWidget: %s (%s) already in focus proxy chain", metaObject()->className(), objectName().toLocal8Bit().constData());
- return;
- }
- }
-
- d->createExtra();
- d->extra->focus_proxy = w;
-}
-
-
-/*!
- Returns the focus proxy, or 0 if there is no focus proxy.
-
- \sa setFocusProxy()
-*/
-
-QWidget * QWidget::focusProxy() const
-{
- Q_D(const QWidget);
- return d->extra ? (QWidget *)d->extra->focus_proxy : 0;
-}
-
-
-/*!
- \property QWidget::focus
- \brief whether this widget (or its focus proxy) has the keyboard
- input focus
-
- By default, this property is false.
-
- \note Obtaining the value of this property for a widget is effectively equivalent
- to checking whether QApplication::focusWidget() refers to the widget.
-
- \sa setFocus(), clearFocus(), setFocusPolicy(), QApplication::focusWidget()
-*/
-bool QWidget::hasFocus() const
-{
- const QWidget* w = this;
- while (w->d_func()->extra && w->d_func()->extra->focus_proxy)
- w = w->d_func()->extra->focus_proxy;
- if (QWidget *window = w->window()) {
-#ifndef QT_NO_GRAPHICSVIEW
- QWExtra *e = window->d_func()->extra;
- if (e && e->proxyWidget && e->proxyWidget->hasFocus() && window->focusWidget() == w)
- return true;
-#endif
- }
- return (QApplication::focusWidget() == w);
-}
-
-/*!
- Gives the keyboard input focus to this widget (or its focus
- proxy) if this widget or one of its parents is the \link
- isActiveWindow() active window\endlink. The \a reason argument will
- be passed into any focus event sent from this function, it is used
- to give an explanation of what caused the widget to get focus.
- If the window is not active, the widget will be given the focus when
- the window becomes active.
-
- First, a focus out event is sent to the focus widget (if any) to
- tell it that it is about to lose the focus. Then a focus in event
- is sent to this widget to tell it that it just received the focus.
- (Nothing happens if the focus in and focus out widgets are the
- same.)
-
- \note On embedded platforms, setFocus() will not cause an input panel
- to be opened by the input method. If you want this to happen, you
- have to send a QEvent::RequestSoftwareInputPanel event to the
- widget yourself.
-
- setFocus() gives focus to a widget regardless of its focus policy,
- but does not clear any keyboard grab (see grabKeyboard()).
-
- Be aware that if the widget is hidden, it will not accept focus
- until it is shown.
-
- \warning If you call setFocus() in a function which may itself be
- called from focusOutEvent() or focusInEvent(), you may get an
- infinite recursion.
-
- \sa hasFocus(), clearFocus(), focusInEvent(), focusOutEvent(),
- setFocusPolicy(), focusWidget(), QApplication::focusWidget(), grabKeyboard(),
- grabMouse(), {Keyboard Focus}, QEvent::RequestSoftwareInputPanel
-*/
-
-void QWidget::setFocus(Qt::FocusReason reason)
-{
- if (!isEnabled())
- return;
-
- QWidget *f = this;
- while (f->d_func()->extra && f->d_func()->extra->focus_proxy)
- f = f->d_func()->extra->focus_proxy;
-
- if (QApplication::focusWidget() == f
-#if defined(Q_WS_WIN)
- && GetFocus() == f->internalWinId()
-#endif
- )
- return;
-
-#ifndef QT_NO_GRAPHICSVIEW
- QWidget *previousProxyFocus = 0;
- if (QWExtra *topData = window()->d_func()->extra) {
- if (topData->proxyWidget && topData->proxyWidget->hasFocus()) {
- previousProxyFocus = topData->proxyWidget->widget()->focusWidget();
- if (previousProxyFocus && previousProxyFocus->focusProxy())
- previousProxyFocus = previousProxyFocus->focusProxy();
- if (previousProxyFocus == this && !topData->proxyWidget->d_func()->proxyIsGivingFocus)
- return;
- }
- }
-#endif
-
- QWidget *w = f;
- if (isHidden()) {
- while (w && w->isHidden()) {
- w->d_func()->focus_child = f;
- w = w->isWindow() ? 0 : w->parentWidget();
- }
- } else {
- while (w) {
- w->d_func()->focus_child = f;
- w = w->isWindow() ? 0 : w->parentWidget();
- }
- }
-
-#ifndef QT_NO_GRAPHICSVIEW
- // Update proxy state
- if (QWExtra *topData = window()->d_func()->extra) {
- if (topData->proxyWidget && !topData->proxyWidget->hasFocus()) {
- topData->proxyWidget->d_func()->focusFromWidgetToProxy = 1;
- topData->proxyWidget->setFocus(reason);
- topData->proxyWidget->d_func()->focusFromWidgetToProxy = 0;
- }
- }
-#endif
-
- if (f->isActiveWindow()) {
- QApplicationPrivate::setFocusWidget(f, reason);
-#ifndef QT_NO_ACCESSIBILITY
-# ifdef Q_OS_WIN
- // The negation of the condition in setFocus_sys
- if (!(testAttribute(Qt::WA_WState_Created) && window()->windowType() != Qt::Popup && internalWinId()))
- //setFocusWidget will already post a focus event for us (that the AT client receives) on Windows
-# endif
-# ifdef Q_OS_UNIX
- // menus update the focus manually and this would create bogus events
- if (!(f->inherits("QMenuBar") || f->inherits("QMenu") || f->inherits("QMenuItem")))
-# endif
- QAccessible::updateAccessibility(f, 0, QAccessible::Focus);
-#endif
-#ifndef QT_NO_GRAPHICSVIEW
- if (QWExtra *topData = window()->d_func()->extra) {
- if (topData->proxyWidget) {
- if (previousProxyFocus && previousProxyFocus != f) {
- // Send event to self
- QFocusEvent event(QEvent::FocusOut, reason);
- QPointer<QWidget> that = previousProxyFocus;
- QApplication::sendEvent(previousProxyFocus, &event);
- if (that)
- QApplication::sendEvent(that->style(), &event);
- }
- if (!isHidden()) {
-#ifndef QT_NO_GRAPHICSVIEW
- // Update proxy state
- if (QWExtra *topData = window()->d_func()->extra)
- if (topData->proxyWidget && topData->proxyWidget->hasFocus())
- topData->proxyWidget->d_func()->updateProxyInputMethodAcceptanceFromWidget();
-#endif
- // Send event to self
- QFocusEvent event(QEvent::FocusIn, reason);
- QPointer<QWidget> that = f;
- QApplication::sendEvent(f, &event);
- if (that)
- QApplication::sendEvent(that->style(), &event);
- }
- }
- }
-#endif
- }
-}
-
-/*!
- \fn void QWidget::setFocus()
- \overload
-
- Gives the keyboard input focus to this widget (or its focus
- proxy) if this widget or one of its parents is the
- \l{isActiveWindow()}{active window}.
-*/
-
-/*!
- Takes keyboard input focus from the widget.
-
- If the widget has active focus, a \link focusOutEvent() focus out
- event\endlink is sent to this widget to tell it that it is about
- to lose the focus.
-
- This widget must enable focus setting in order to get the keyboard
- input focus, i.e. it must call setFocusPolicy().
-
- \sa hasFocus(), setFocus(), focusInEvent(), focusOutEvent(),
- setFocusPolicy(), QApplication::focusWidget()
-*/
-
-void QWidget::clearFocus()
-{
- QWidget *w = this;
- while (w) {
- if (w->d_func()->focus_child == this)
- w->d_func()->focus_child = 0;
- w = w->parentWidget();
- }
-#ifndef QT_NO_GRAPHICSVIEW
- QWExtra *topData = d_func()->extra;
- if (topData && topData->proxyWidget)
- topData->proxyWidget->clearFocus();
-#endif
-
- if (hasFocus()) {
- // Update proxy state
- QApplicationPrivate::setFocusWidget(0, Qt::OtherFocusReason);
-#if defined(Q_WS_WIN)
- if (!(windowType() == Qt::Popup) && GetFocus() == internalWinId())
- SetFocus(0);
- else
-#endif
- {
-#ifndef QT_NO_ACCESSIBILITY
- QAccessible::updateAccessibility(this, 0, QAccessible::Focus);
-#endif
- }
- }
-}
-
-
-/*!
- \fn bool QWidget::focusNextChild()
-
- Finds a new widget to give the keyboard focus to, as appropriate
- for \key Tab, and returns true if it can find a new widget, or
- false if it can't.
-
- \sa focusPreviousChild()
-*/
-
-/*!
- \fn bool QWidget::focusPreviousChild()
-
- Finds a new widget to give the keyboard focus to, as appropriate
- for \key Shift+Tab, and returns true if it can find a new widget,
- or false if it can't.
-
- \sa focusNextChild()
-*/
-
-/*!
- Finds a new widget to give the keyboard focus to, as appropriate
- for Tab and Shift+Tab, and returns true if it can find a new
- widget, or false if it can't.
-
- If \a next is true, this function searches forward, if \a next
- is false, it searches backward.
-
- Sometimes, you will want to reimplement this function. For
- example, a web browser might reimplement it to move its "current
- active link" forward or backward, and call
- focusNextPrevChild() only when it reaches the last or
- first link on the "page".
-
- Child widgets call focusNextPrevChild() on their parent widgets,
- but only the window that contains the child widgets decides where
- to redirect focus. By reimplementing this function for an object,
- you thus gain control of focus traversal for all child widgets.
-
- \sa focusNextChild(), focusPreviousChild()
-*/
-
-bool QWidget::focusNextPrevChild(bool next)
-{
- Q_D(QWidget);
- QWidget* p = parentWidget();
- bool isSubWindow = (windowType() == Qt::SubWindow);
- if (!isWindow() && !isSubWindow && p)
- return p->focusNextPrevChild(next);
-#ifndef QT_NO_GRAPHICSVIEW
- if (d->extra && d->extra->proxyWidget)
- return d->extra->proxyWidget->focusNextPrevChild(next);
-#endif
- QWidget *w = QApplicationPrivate::focusNextPrevChild_helper(this, next);
- if (!w) return false;
-
- w->setFocus(next ? Qt::TabFocusReason : Qt::BacktabFocusReason);
- return true;
-}
-
-/*!
- Returns the last child of this widget that setFocus had been
- called on. For top level widgets this is the widget that will get
- focus in case this window gets activated
-
- This is not the same as QApplication::focusWidget(), which returns
- the focus widget in the currently active window.
-*/
-
-QWidget *QWidget::focusWidget() const
-{
- return const_cast<QWidget *>(d_func()->focus_child);
-}
-
-/*!
- Returns the next widget in this widget's focus chain.
-
- \sa previousInFocusChain()
-*/
-QWidget *QWidget::nextInFocusChain() const
-{
- return const_cast<QWidget *>(d_func()->focus_next);
-}
-
-/*!
- \brief The previousInFocusChain function returns the previous
- widget in this widget's focus chain.
-
- \sa nextInFocusChain()
-
- \since 4.6
-*/
-QWidget *QWidget::previousInFocusChain() const
-{
- return const_cast<QWidget *>(d_func()->focus_prev);
-}
-
-/*!
- \property QWidget::isActiveWindow
- \brief whether this widget's window is the active window
-
- The active window is the window that contains the widget that has
- keyboard focus (The window may still have focus if it has no
- widgets or none of its widgets accepts keyboard focus).
-
- When popup windows are visible, this property is true for both the
- active window \e and for the popup.
-
- By default, this property is false.
-
- \sa activateWindow(), QApplication::activeWindow()
-*/
-bool QWidget::isActiveWindow() const
-{
- QWidget *tlw = window();
- if(tlw == QApplication::activeWindow() || (isVisible() && (tlw->windowType() == Qt::Popup)))
- return true;
-
-#ifndef QT_NO_GRAPHICSVIEW
- if (QWExtra *tlwExtra = tlw->d_func()->extra) {
- if (isVisible() && tlwExtra->proxyWidget)
- return tlwExtra->proxyWidget->isActiveWindow();
- }
-#endif
-
-#ifdef Q_WS_MAC
- extern bool qt_mac_is_macdrawer(const QWidget *); //qwidget_mac.cpp
- if(qt_mac_is_macdrawer(tlw) &&
- tlw->parentWidget() && tlw->parentWidget()->isActiveWindow())
- return true;
-
- extern bool qt_mac_insideKeyWindow(const QWidget *); //qwidget_mac.cpp
- if (QApplication::testAttribute(Qt::AA_MacPluginApplication) && qt_mac_insideKeyWindow(tlw))
- return true;
-#endif
- if(style()->styleHint(QStyle::SH_Widget_ShareActivation, 0, this)) {
- if(tlw->windowType() == Qt::Tool &&
- !tlw->isModal() &&
- (!tlw->parentWidget() || tlw->parentWidget()->isActiveWindow()))
- return true;
- QWidget *w = QApplication::activeWindow();
- while(w && tlw->windowType() == Qt::Tool &&
- !w->isModal() && w->parentWidget()) {
- w = w->parentWidget()->window();
- if(w == tlw)
- return true;
- }
- }
-#if defined(Q_WS_WIN32)
- HWND active = GetActiveWindow();
- if (!tlw->testAttribute(Qt::WA_WState_Created))
- return false;
- return active == tlw->internalWinId() || ::IsChild(active, tlw->internalWinId());
-#else
- return false;
-#endif
-}
-
-/*!
- Puts the \a second widget after the \a first widget in the focus order.
-
- Note that since the tab order of the \a second widget is changed, you
- should order a chain like this:
-
- \snippet doc/src/snippets/code/src_gui_kernel_qwidget.cpp 9
-
- \e not like this:
-
- \snippet doc/src/snippets/code/src_gui_kernel_qwidget.cpp 10
-
- If \a first or \a second has a focus proxy, setTabOrder()
- correctly substitutes the proxy.
-
- \sa setFocusPolicy(), setFocusProxy(), {Keyboard Focus}
-*/
-void QWidget::setTabOrder(QWidget* first, QWidget *second)
-{
- if (!first || !second || first->focusPolicy() == Qt::NoFocus || second->focusPolicy() == Qt::NoFocus)
- return;
-
- if (first->window() != second->window()) {
- qWarning("QWidget::setTabOrder: 'first' and 'second' must be in the same window");
- return;
- }
-
- QWidget *fp = first->focusProxy();
- if (fp) {
- // If first is redirected, set first to the last child of first
- // that can take keyboard focus so that second is inserted after
- // that last child, and the focus order within first is (more
- // likely to be) preserved.
- QList<QWidget *> l = first->findChildren<QWidget *>();
- for (int i = l.size()-1; i >= 0; --i) {
- QWidget * next = l.at(i);
- if (next->window() == fp->window()) {
- fp = next;
- if (fp->focusPolicy() != Qt::NoFocus)
- break;
- }
- }
- first = fp;
- }
-
- if (fp == second)
- return;
-
- if (QWidget *sp = second->focusProxy())
- second = sp;
-
-// QWidget *fp = first->d_func()->focus_prev;
- QWidget *fn = first->d_func()->focus_next;
-
- if (fn == second || first == second)
- return;
-
- QWidget *sp = second->d_func()->focus_prev;
- QWidget *sn = second->d_func()->focus_next;
-
- fn->d_func()->focus_prev = second;
- first->d_func()->focus_next = second;
-
- second->d_func()->focus_next = fn;
- second->d_func()->focus_prev = first;
-
- sp->d_func()->focus_next = sn;
- sn->d_func()->focus_prev = sp;
-
-
- Q_ASSERT(first->d_func()->focus_next->d_func()->focus_prev == first);
- Q_ASSERT(first->d_func()->focus_prev->d_func()->focus_next == first);
-
- Q_ASSERT(second->d_func()->focus_next->d_func()->focus_prev == second);
- Q_ASSERT(second->d_func()->focus_prev->d_func()->focus_next == second);
-}
-
-/*!\internal
-
- Moves the relevant subwidgets of this widget from the \a oldtlw's
- tab chain to that of the new parent, if there's anything to move and
- we're really moving
-
- This function is called from QWidget::reparent() *after* the widget
- has been reparented.
-
- \sa reparent()
-*/
-
-void QWidgetPrivate::reparentFocusWidgets(QWidget * oldtlw)
-{
- Q_Q(QWidget);
- if (oldtlw == q->window())
- return; // nothing to do
-
- if(focus_child)
- focus_child->clearFocus();
-
- // separate the focus chain into new (children of myself) and old (the rest)
- QWidget *firstOld = 0;
- //QWidget *firstNew = q; //invariant
- QWidget *o = 0; // last in the old list
- QWidget *n = q; // last in the new list
-
- bool prevWasNew = true;
- QWidget *w = focus_next;
-
- //Note: for efficiency, we do not maintain the list invariant inside the loop
- //we append items to the relevant list, and we optimize by not changing pointers
- //when subsequent items are going into the same list.
- while (w != q) {
- bool currentIsNew = q->isAncestorOf(w);
- if (currentIsNew) {
- if (!prevWasNew) {
- //prev was old -- append to new list
- n->d_func()->focus_next = w;
- w->d_func()->focus_prev = n;
- }
- n = w;
- } else {
- if (prevWasNew) {
- //prev was new -- append to old list, if there is one
- if (o) {
- o->d_func()->focus_next = w;
- w->d_func()->focus_prev = o;
- } else {
- // "create" the old list
- firstOld = w;
- }
- }
- o = w;
- }
- w = w->d_func()->focus_next;
- prevWasNew = currentIsNew;
- }
-
- //repair the old list:
- if (firstOld) {
- o->d_func()->focus_next = firstOld;
- firstOld->d_func()->focus_prev = o;
- }
-
- if (!q->isWindow()) {
- QWidget *topLevel = q->window();
- //insert new chain into toplevel's chain
-
- QWidget *prev = topLevel->d_func()->focus_prev;
-
- topLevel->d_func()->focus_prev = n;
- prev->d_func()->focus_next = q;
-
- focus_prev = prev;
- n->d_func()->focus_next = topLevel;
- } else {
- //repair the new list
- n->d_func()->focus_next = q;
- focus_prev = n;
- }
-
-}
-
-/*!\internal
-
- Measures the shortest distance from a point to a rect.
-
- This function is called from QDesktopwidget::screen(QPoint) to find the
- closest screen for a point.
- In directional KeypadNavigation, it is called to find the closest
- widget to the current focus widget center.
-*/
-int QWidgetPrivate::pointToRect(const QPoint &p, const QRect &r)
-{
- int dx = 0;
- int dy = 0;
- if (p.x() < r.left())
- dx = r.left() - p.x();
- else if (p.x() > r.right())
- dx = p.x() - r.right();
- if (p.y() < r.top())
- dy = r.top() - p.y();
- else if (p.y() > r.bottom())
- dy = p.y() - r.bottom();
- return dx + dy;
-}
-
-/*!
- \property QWidget::frameSize
- \brief the size of the widget including any window frame
-
- By default, this property contains a value that depends on the user's
- platform and screen geometry.
-*/
-QSize QWidget::frameSize() const
-{
- Q_D(const QWidget);
- if (isWindow() && !(windowType() == Qt::Popup)) {
- QRect fs = d->frameStrut();
- return QSize(data->crect.width() + fs.left() + fs.right(),
- data->crect.height() + fs.top() + fs.bottom());
- }
- return data->crect.size();
-}
-
-/*! \fn void QWidget::move(int x, int y)
-
- \overload
-
- This corresponds to move(QPoint(\a x, \a y)).
-*/
-
-void QWidget::move(const QPoint &p)
-{
- Q_D(QWidget);
- setAttribute(Qt::WA_Moved);
- if (isWindow())
- d->topData()->posFromMove = true;
- if (testAttribute(Qt::WA_WState_Created)) {
- d->setGeometry_sys(p.x() + geometry().x() - QWidget::x(),
- p.y() + geometry().y() - QWidget::y(),
- width(), height(), true);
- d->setDirtyOpaqueRegion();
- } else {
- data->crect.moveTopLeft(p); // no frame yet
- setAttribute(Qt::WA_PendingMoveEvent);
- }
-}
-
-/*! \fn void QWidget::resize(int w, int h)
- \overload
-
- This corresponds to resize(QSize(\a w, \a h)).
-*/
-
-void QWidget::resize(const QSize &s)
-{
- Q_D(QWidget);
- setAttribute(Qt::WA_Resized);
- if (testAttribute(Qt::WA_WState_Created)) {
- d->setGeometry_sys(geometry().x(), geometry().y(), s.width(), s.height(), false);
- d->setDirtyOpaqueRegion();
- } else {
- data->crect.setSize(s.boundedTo(maximumSize()).expandedTo(minimumSize()));
- setAttribute(Qt::WA_PendingResizeEvent);
- }
-}
-
-void QWidget::setGeometry(const QRect &r)
-{
- Q_D(QWidget);
- setAttribute(Qt::WA_Resized);
- setAttribute(Qt::WA_Moved);
- if (isWindow())
- d->topData()->posFromMove = false;
- if (testAttribute(Qt::WA_WState_Created)) {
- d->setGeometry_sys(r.x(), r.y(), r.width(), r.height(), true);
- d->setDirtyOpaqueRegion();
- } else {
- data->crect.setTopLeft(r.topLeft());
- data->crect.setSize(r.size().boundedTo(maximumSize()).expandedTo(minimumSize()));
- setAttribute(Qt::WA_PendingMoveEvent);
- setAttribute(Qt::WA_PendingResizeEvent);
- }
-}
-
-/*!
- \since 4.2
- Saves the current geometry and state for top-level widgets.
-
- To save the geometry when the window closes, you can
- implement a close event like this:
-
- \snippet doc/src/snippets/code/src_gui_kernel_qwidget.cpp 11
-
- See the \l{Window Geometry} documentation for an overview of geometry
- issues with windows.
-
- Use QMainWindow::saveState() to save the geometry and the state of
- toolbars and dock widgets.
-
- \sa restoreGeometry(), QMainWindow::saveState(), QMainWindow::restoreState()
-*/
-QByteArray QWidget::saveGeometry() const
-{
-#ifdef QT_MAC_USE_COCOA
- // We check if the window was maximized during this invocation. If so, we need to record the
- // starting position as 0,0.
- Q_D(const QWidget);
- QRect newFramePosition = frameGeometry();
- QRect newNormalPosition = normalGeometry();
- if(d->topData()->wasMaximized && !(windowState() & Qt::WindowMaximized)) {
- // Change the starting position
- newFramePosition.moveTo(0, 0);
- newNormalPosition.moveTo(0, 0);
- }
-#endif // QT_MAC_USE_COCOA
- QByteArray array;
- QDataStream stream(&array, QIODevice::WriteOnly);
- stream.setVersion(QDataStream::Qt_4_0);
- const quint32 magicNumber = 0x1D9D0CB;
- quint16 majorVersion = 1;
- quint16 minorVersion = 0;
- stream << magicNumber
- << majorVersion
- << minorVersion
-#ifdef QT_MAC_USE_COCOA
- << newFramePosition
- << newNormalPosition
-#else
- << frameGeometry()
- << normalGeometry()
-#endif // QT_MAC_USE_COCOA
- << qint32(QApplication::desktop()->screenNumber(this))
- << quint8(windowState() & Qt::WindowMaximized)
- << quint8(windowState() & Qt::WindowFullScreen);
- return array;
-}
-
-/*!
- \since 4.2
-
- Restores the geometry and state top-level widgets stored in the
- byte array \a geometry. Returns true on success; otherwise
- returns false.
-
- If the restored geometry is off-screen, it will be modified to be
- inside the available screen geometry.
-
- To restore geometry saved using QSettings, you can use code like
- this:
-
- \snippet doc/src/snippets/code/src_gui_kernel_qwidget.cpp 12
-
- See the \l{Window Geometry} documentation for an overview of geometry
- issues with windows.
-
- Use QMainWindow::restoreState() to restore the geometry and the
- state of toolbars and dock widgets.
-
- \sa saveGeometry(), QSettings, QMainWindow::saveState(), QMainWindow::restoreState()
-*/
-bool QWidget::restoreGeometry(const QByteArray &geometry)
-{
- if (geometry.size() < 4)
- return false;
- QDataStream stream(geometry);
- stream.setVersion(QDataStream::Qt_4_0);
-
- const quint32 magicNumber = 0x1D9D0CB;
- quint32 storedMagicNumber;
- stream >> storedMagicNumber;
- if (storedMagicNumber != magicNumber)
- return false;
-
- const quint16 currentMajorVersion = 1;
- quint16 majorVersion = 0;
- quint16 minorVersion = 0;
-
- stream >> majorVersion >> minorVersion;
-
- if (majorVersion != currentMajorVersion)
- return false;
- // (Allow all minor versions.)
-
- QRect restoredFrameGeometry;
- QRect restoredNormalGeometry;
- qint32 restoredScreenNumber;
- quint8 maximized;
- quint8 fullScreen;
-
- stream >> restoredFrameGeometry
- >> restoredNormalGeometry
- >> restoredScreenNumber
- >> maximized
- >> fullScreen;
-
- const int frameHeight = 20;
- if (!restoredFrameGeometry.isValid())
- restoredFrameGeometry = QRect(QPoint(0,0), sizeHint());
-
- if (!restoredNormalGeometry.isValid())
- restoredNormalGeometry = QRect(QPoint(0, frameHeight), sizeHint());
- if (!restoredNormalGeometry.isValid()) {
- // use the widget's adjustedSize if the sizeHint() doesn't help
- restoredNormalGeometry.setSize(restoredNormalGeometry
- .size()
- .expandedTo(d_func()->adjustedSize()));
- }
-
- const QDesktopWidget * const desktop = QApplication::desktop();
- if (restoredScreenNumber >= desktop->numScreens())
- restoredScreenNumber = desktop->primaryScreen();
-
- const QRect availableGeometry = desktop->availableGeometry(restoredScreenNumber);
-
- // Modify the restored geometry if we are about to restore to coordinates
- // that would make the window "lost". This happens if:
- // - The restored geometry is completely oustside the available geometry
- // - The title bar is outside the available geometry.
- // - (Mac only) The window is higher than the available geometry. It must
- // be possible to bring the size grip on screen by moving the window.
-#ifdef Q_WS_MAC
- restoredFrameGeometry.setHeight(qMin(restoredFrameGeometry.height(), availableGeometry.height()));
- restoredNormalGeometry.setHeight(qMin(restoredNormalGeometry.height(), availableGeometry.height() - frameHeight));
-#endif
-
- if (!restoredFrameGeometry.intersects(availableGeometry)) {
- restoredFrameGeometry.moveBottom(qMin(restoredFrameGeometry.bottom(), availableGeometry.bottom()));
- restoredFrameGeometry.moveLeft(qMax(restoredFrameGeometry.left(), availableGeometry.left()));
- restoredFrameGeometry.moveRight(qMin(restoredFrameGeometry.right(), availableGeometry.right()));
- }
- restoredFrameGeometry.moveTop(qMax(restoredFrameGeometry.top(), availableGeometry.top()));
-
- if (!restoredNormalGeometry.intersects(availableGeometry)) {
- restoredNormalGeometry.moveBottom(qMin(restoredNormalGeometry.bottom(), availableGeometry.bottom()));
- restoredNormalGeometry.moveLeft(qMax(restoredNormalGeometry.left(), availableGeometry.left()));
- restoredNormalGeometry.moveRight(qMin(restoredNormalGeometry.right(), availableGeometry.right()));
- }
- restoredNormalGeometry.moveTop(qMax(restoredNormalGeometry.top(), availableGeometry.top() + frameHeight));
-
- if (maximized || fullScreen) {
- // set geomerty before setting the window state to make
- // sure the window is maximized to the right screen.
- // Skip on windows: the window is restored into a broken
- // half-maximized state.
-#ifndef Q_WS_WIN
- setGeometry(restoredNormalGeometry);
-#endif
- Qt::WindowStates ws = windowState();
- if (maximized)
- ws |= Qt::WindowMaximized;
- if (fullScreen)
- ws |= Qt::WindowFullScreen;
- setWindowState(ws);
- d_func()->topData()->normalGeometry = restoredNormalGeometry;
- } else {
- QPoint offset;
-#ifdef Q_WS_X11
- if (isFullScreen())
- offset = d_func()->topData()->fullScreenOffset;
-#endif
- setWindowState(windowState() & ~(Qt::WindowMaximized | Qt::WindowFullScreen));
- move(restoredFrameGeometry.topLeft() + offset);
- resize(restoredNormalGeometry.size());
- }
- return true;
-}
-
-/*!\fn void QWidget::setGeometry(int x, int y, int w, int h)
- \overload
-
- This corresponds to setGeometry(QRect(\a x, \a y, \a w, \a h)).
-*/
-
-/*!
- Sets the margins around the contents of the widget to have the sizes
- \a left, \a top, \a right, and \a bottom. The margins are used by
- the layout system, and may be used by subclasses to specify the area
- to draw in (e.g. excluding the frame).
-
- Changing the margins will trigger a resizeEvent().
-
- \sa contentsRect(), getContentsMargins()
-*/
-void QWidget::setContentsMargins(int left, int top, int right, int bottom)
-{
- Q_D(QWidget);
- if (left == d->leftmargin && top == d->topmargin
- && right == d->rightmargin && bottom == d->bottommargin)
- return;
- d->leftmargin = left;
- d->topmargin = top;
- d->rightmargin = right;
- d->bottommargin = bottom;
-
- if (QLayout *l=d->layout)
- l->update(); //force activate; will do updateGeometry
- else
- updateGeometry();
-
- // ### Qt 5: compat, remove
- if (isVisible()) {
- update();
- QResizeEvent e(data->crect.size(), data->crect.size());
- QApplication::sendEvent(this, &e);
- } else {
- setAttribute(Qt::WA_PendingResizeEvent, true);
- }
-
- QEvent e(QEvent::ContentsRectChange);
- QApplication::sendEvent(this, &e);
-}
-
-/*!
- \overload
- \since 4.6
-
- \brief The setContentsMargins function sets the margins around the
- widget's contents.
-
- Sets the margins around the contents of the widget to have the
- sizes determined by \a margins. The margins are
- used by the layout system, and may be used by subclasses to
- specify the area to draw in (e.g. excluding the frame).
-
- Changing the margins will trigger a resizeEvent().
-
- \sa contentsRect(), getContentsMargins()
-*/
-void QWidget::setContentsMargins(const QMargins &margins)
-{
- setContentsMargins(margins.left(), margins.top(),
- margins.right(), margins.bottom());
-}
-
-/*!
- Returns the widget's contents margins for \a left, \a top, \a
- right, and \a bottom.
-
- \sa setContentsMargins(), contentsRect()
- */
-void QWidget::getContentsMargins(int *left, int *top, int *right, int *bottom) const
-{
- Q_D(const QWidget);
- if (left)
- *left = d->leftmargin;
- if (top)
- *top = d->topmargin;
- if (right)
- *right = d->rightmargin;
- if (bottom)
- *bottom = d->bottommargin;
-}
-
-/*!
- \since 4.6
-
- \brief The contentsMargins function returns the widget's contents margins.
-
- \sa getContentsMargins(), setContentsMargins(), contentsRect()
- */
-QMargins QWidget::contentsMargins() const
-{
- Q_D(const QWidget);
- return QMargins(d->leftmargin, d->topmargin, d->rightmargin, d->bottommargin);
-}
-
-
-/*!
- Returns the area inside the widget's margins.
-
- \sa setContentsMargins(), getContentsMargins()
-*/
-QRect QWidget::contentsRect() const
-{
- Q_D(const QWidget);
- return QRect(QPoint(d->leftmargin, d->topmargin),
- QPoint(data->crect.width() - 1 - d->rightmargin,
- data->crect.height() - 1 - d->bottommargin));
-
-}
-
-
-
-/*!
- \fn void QWidget::customContextMenuRequested(const QPoint &pos)
-
- This signal is emitted when the widget's \l contextMenuPolicy is
- Qt::CustomContextMenu, and the user has requested a context menu on
- the widget. The position \a pos is the position of the context menu
- event that the widget receives. Normally this is in widget
- coordinates. The exception to this rule is QAbstractScrollArea and
- its subclasses that map the context menu event to coordinates of the
- \link QAbstractScrollArea::viewport() viewport() \endlink .
-
-
- \sa mapToGlobal() QMenu contextMenuPolicy
-*/
-
-
-/*!
- \property QWidget::contextMenuPolicy
- \brief how the widget shows a context menu
-
- The default value of this property is Qt::DefaultContextMenu,
- which means the contextMenuEvent() handler is called. Other values
- are Qt::NoContextMenu, Qt::PreventContextMenu,
- Qt::ActionsContextMenu, and Qt::CustomContextMenu. With
- Qt::CustomContextMenu, the signal customContextMenuRequested() is
- emitted.
-
- \sa contextMenuEvent(), customContextMenuRequested(), actions()
-*/
-
-Qt::ContextMenuPolicy QWidget::contextMenuPolicy() const
-{
- return (Qt::ContextMenuPolicy)data->context_menu_policy;
-}
-
-void QWidget::setContextMenuPolicy(Qt::ContextMenuPolicy policy)
-{
- data->context_menu_policy = (uint) policy;
-}
-
-/*!
- \property QWidget::focusPolicy
- \brief the way the widget accepts keyboard focus
-
- The policy is Qt::TabFocus if the widget accepts keyboard
- focus by tabbing, Qt::ClickFocus if the widget accepts
- focus by clicking, Qt::StrongFocus if it accepts both, and
- Qt::NoFocus (the default) if it does not accept focus at
- all.
-
- You must enable keyboard focus for a widget if it processes
- keyboard events. This is normally done from the widget's
- constructor. For instance, the QLineEdit constructor calls
- setFocusPolicy(Qt::StrongFocus).
-
- If the widget has a focus proxy, then the focus policy will
- be propagated to it.
-
- \sa focusInEvent(), focusOutEvent(), keyPressEvent(), keyReleaseEvent(), enabled
-*/
-
-
-Qt::FocusPolicy QWidget::focusPolicy() const
-{
- return (Qt::FocusPolicy)data->focus_policy;
-}
-
-void QWidget::setFocusPolicy(Qt::FocusPolicy policy)
-{
- data->focus_policy = (uint) policy;
- Q_D(QWidget);
- if (d->extra && d->extra->focus_proxy)
- d->extra->focus_proxy->setFocusPolicy(policy);
-}
-
-/*!
- \property QWidget::updatesEnabled
- \brief whether updates are enabled
-
- An updates enabled widget receives paint events and has a system
- background; a disabled widget does not. This also implies that
- calling update() and repaint() has no effect if updates are
- disabled.
-
- By default, this property is true.
-
- setUpdatesEnabled() is normally used to disable updates for a
- short period of time, for instance to avoid screen flicker during
- large changes. In Qt, widgets normally do not generate screen
- flicker, but on X11 the server might erase regions on the screen
- when widgets get hidden before they can be replaced by other
- widgets. Disabling updates solves this.
-
- Example:
- \snippet doc/src/snippets/code/src_gui_kernel_qwidget.cpp 13
-
- Disabling a widget implicitly disables all its children. Enabling a widget
- enables all child widgets \e except top-level widgets or those that
- have been explicitly disabled. Re-enabling updates implicitly calls
- update() on the widget.
-
- \sa paintEvent()
-*/
-void QWidget::setUpdatesEnabled(bool enable)
-{
- Q_D(QWidget);
- setAttribute(Qt::WA_ForceUpdatesDisabled, !enable);
- d->setUpdatesEnabled_helper(enable);
-}
-
-/*! \fn void QWidget::show()
-
- Shows the widget and its child widgets. This function is
- equivalent to setVisible(true).
-
- \sa raise(), showEvent(), hide(), setVisible(), showMinimized(), showMaximized(),
- showNormal(), isVisible()
-*/
-
-
-/*! \internal
-
- Makes the widget visible in the isVisible() meaning of the word.
- It is only called for toplevels or widgets with visible parents.
- */
-void QWidgetPrivate::show_recursive()
-{
- Q_Q(QWidget);
- // polish if necessary
-
- if (!q->testAttribute(Qt::WA_WState_Created))
- createRecursively();
- q->ensurePolished();
-
-#ifdef QT3_SUPPORT
- if(sendChildEvents)
- QApplication::sendPostedEvents(q, QEvent::ChildInserted);
-#endif
- if (!q->isWindow() && q->parentWidget()->d_func()->layout && !q->parentWidget()->data->in_show)
- q->parentWidget()->d_func()->layout->activate();
- // activate our layout before we and our children become visible
- if (layout)
- layout->activate();
-
- show_helper();
-}
-
-void QWidgetPrivate::sendPendingMoveAndResizeEvents(bool recursive, bool disableUpdates)
-{
- Q_Q(QWidget);
-
- disableUpdates = disableUpdates && q->updatesEnabled();
- if (disableUpdates)
- q->setAttribute(Qt::WA_UpdatesDisabled);
-
- if (q->testAttribute(Qt::WA_PendingMoveEvent)) {
- QMoveEvent e(data.crect.topLeft(), data.crect.topLeft());
- QApplication::sendEvent(q, &e);
- q->setAttribute(Qt::WA_PendingMoveEvent, false);
- }
-
- if (q->testAttribute(Qt::WA_PendingResizeEvent)) {
- QResizeEvent e(data.crect.size(), QSize());
- QApplication::sendEvent(q, &e);
- q->setAttribute(Qt::WA_PendingResizeEvent, false);
- }
-
- if (disableUpdates)
- q->setAttribute(Qt::WA_UpdatesDisabled, false);
-
- if (!recursive)
- return;
-
- for (int i = 0; i < children.size(); ++i) {
- if (QWidget *child = qobject_cast<QWidget *>(children.at(i)))
- child->d_func()->sendPendingMoveAndResizeEvents(recursive, disableUpdates);
- }
-}
-
-void QWidgetPrivate::activateChildLayoutsRecursively()
-{
- sendPendingMoveAndResizeEvents(false, true);
-
- for (int i = 0; i < children.size(); ++i) {
- QWidget *child = qobject_cast<QWidget *>(children.at(i));
- if (!child || child->isHidden() || child->isWindow())
- continue;
-
- child->ensurePolished();
-
- // Activate child's layout
- QWidgetPrivate *childPrivate = child->d_func();
- if (childPrivate->layout)
- childPrivate->layout->activate();
-
- // Pretend we're visible.
- const bool wasVisible = child->isVisible();
- if (!wasVisible)
- child->setAttribute(Qt::WA_WState_Visible);
-
- // Do the same for all my children.
- childPrivate->activateChildLayoutsRecursively();
-
- // We're not cheating anymore.
- if (!wasVisible)
- child->setAttribute(Qt::WA_WState_Visible, false);
- }
-}
-
-void QWidgetPrivate::show_helper()
-{
- Q_Q(QWidget);
- data.in_show = true; // qws optimization
- // make sure we receive pending move and resize events
- sendPendingMoveAndResizeEvents();
-
- // become visible before showing all children
- q->setAttribute(Qt::WA_WState_Visible);
-
- // finally show all children recursively
- showChildren(false);
-
-#ifdef QT3_SUPPORT
- if (q->parentWidget() && sendChildEvents)
- QApplication::sendPostedEvents(q->parentWidget(),
- QEvent::ChildInserted);
-#endif
-
-
- // popup handling: new popups and tools need to be raised, and
- // existing popups must be closed. Also propagate the current
- // windows's KeyboardFocusChange status.
- if (q->isWindow()) {
- if ((q->windowType() == Qt::Tool) || (q->windowType() == Qt::Popup) || q->windowType() == Qt::ToolTip) {
- q->raise();
- if (q->parentWidget() && q->parentWidget()->window()->testAttribute(Qt::WA_KeyboardFocusChange))
- q->setAttribute(Qt::WA_KeyboardFocusChange);
- } else {
- while (QApplication::activePopupWidget()) {
- if (!QApplication::activePopupWidget()->close())
- break;
- }
- }
- }
-
- // Automatic embedding of child windows of widgets already embedded into
- // QGraphicsProxyWidget when they are shown the first time.
- bool isEmbedded = false;
-#ifndef QT_NO_GRAPHICSVIEW
- if (q->isWindow()) {
- isEmbedded = q->graphicsProxyWidget() ? true : false;
- if (!isEmbedded && !bypassGraphicsProxyWidget(q)) {
- QGraphicsProxyWidget *ancestorProxy = nearestGraphicsProxyWidget(q->parentWidget());
- if (ancestorProxy) {
- isEmbedded = true;
- ancestorProxy->d_func()->embedSubWindow(q);
- }
- }
- }
-#else
- Q_UNUSED(isEmbedded);
-#endif
-
- // On Windows, show the popup now so that our own focus handling
- // stores the correct old focus widget even if it's stolen in the
- // showevent
-#if defined(Q_WS_WIN) || defined(Q_WS_MAC) || defined(Q_OS_SYMBIAN)
- if (!isEmbedded && q->windowType() == Qt::Popup)
- qApp->d_func()->openPopup(q);
-#endif
-
- // send the show event before showing the window
- QShowEvent showEvent;
- QApplication::sendEvent(q, &showEvent);
-
- if (!isEmbedded && q->isModal() && q->isWindow())
- // QApplicationPrivate::enterModal *before* show, otherwise the initial
- // stacking might be wrong
- QApplicationPrivate::enterModal(q);
-
-
- show_sys();
-
-#if !defined(Q_WS_WIN) && !defined(Q_WS_MAC) && !defined(Q_OS_SYMBIAN)
- if (!isEmbedded && q->windowType() == Qt::Popup)
- qApp->d_func()->openPopup(q);
-#endif
-
-#ifndef QT_NO_ACCESSIBILITY
- if (q->windowType() != Qt::ToolTip) // Tooltips are read aloud twice in MS narrator.
- QAccessible::updateAccessibility(q, 0, QAccessible::ObjectShow);
-#endif
-
- if (QApplicationPrivate::hidden_focus_widget == q) {
- QApplicationPrivate::hidden_focus_widget = 0;
- q->setFocus(Qt::OtherFocusReason);
- }
-
- // Process events when showing a Qt::SplashScreen widget before the event loop
- // is spinnning; otherwise it might not show up on particular platforms.
- // This makes QSplashScreen behave the same on all platforms.
- if (!qApp->d_func()->in_exec && q->windowType() == Qt::SplashScreen)
- QApplication::processEvents();
-
- data.in_show = false; // reset qws optimization
-}
-
-/*! \fn void QWidget::hide()
-
- Hides the widget. This function is equivalent to
- setVisible(false).
-
-
- \note If you are working with QDialog or its subclasses and you invoke
- the show() function after this function, the dialog will be displayed in
- its original position.
-
- \sa hideEvent(), isHidden(), show(), setVisible(), isVisible(), close()
-*/
-
-/*!\internal
- */
-void QWidgetPrivate::hide_helper()
-{
- Q_Q(QWidget);
-
- bool isEmbedded = false;
-#if !defined QT_NO_GRAPHICSVIEW
- isEmbedded = q->isWindow() && !bypassGraphicsProxyWidget(q) && nearestGraphicsProxyWidget(q->parentWidget()) != 0;
-#else
- Q_UNUSED(isEmbedded);
-#endif
-
- if (!isEmbedded && (q->windowType() == Qt::Popup))
- qApp->d_func()->closePopup(q);
-
- // Move test modal here. Otherwise, a modal dialog could get
- // destroyed and we lose all access to its parent because we haven't
- // left modality. (Eg. modal Progress Dialog)
- if (!isEmbedded && q->isModal() && q->isWindow())
- QApplicationPrivate::leaveModal(q);
-
-#if defined(Q_WS_WIN)
- if (q->isWindow() && !(q->windowType() == Qt::Popup) && q->parentWidget()
- && !q->parentWidget()->isHidden() && q->isActiveWindow())
- q->parentWidget()->activateWindow(); // Activate parent
-#endif
-
- q->setAttribute(Qt::WA_Mapped, false);
- hide_sys();
-
- bool wasVisible = q->testAttribute(Qt::WA_WState_Visible);
-
- if (wasVisible) {
- q->setAttribute(Qt::WA_WState_Visible, false);
-
- }
-
- QHideEvent hideEvent;
- QApplication::sendEvent(q, &hideEvent);
- hideChildren(false);
-
- // next bit tries to move the focus if the focus widget is now
- // hidden.
- if (wasVisible) {
-#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) || defined(Q_WS_MAC) || defined(Q_WS_QPA)
- qApp->d_func()->sendSyntheticEnterLeave(q);
-#endif
-
- QWidget *fw = QApplication::focusWidget();
- while (fw && !fw->isWindow()) {
- if (fw == q) {
- q->focusNextPrevChild(true);
- break;
- }
- fw = fw->parentWidget();
- }
- }
-
- if (QWidgetBackingStore *bs = maybeBackingStore())
- bs->removeDirtyWidget(q);
-
-#ifndef QT_NO_ACCESSIBILITY
- if (wasVisible)
- QAccessible::updateAccessibility(q, 0, QAccessible::ObjectHide);
-#endif
-}
-
-/*!
- \fn bool QWidget::isHidden() const
-
- Returns true if the widget is hidden, otherwise returns false.
-
- A hidden widget will only become visible when show() is called on
- it. It will not be automatically shown when the parent is shown.
-
- To check visibility, use !isVisible() instead (notice the exclamation mark).
-
- isHidden() implies !isVisible(), but a widget can be not visible
- and not hidden at the same time. This is the case for widgets that are children of
- widgets that are not visible.
-
-
- Widgets are hidden if:
- \list
- \o they were created as independent windows,
- \o they were created as children of visible widgets,
- \o hide() or setVisible(false) was called.
- \endlist
-*/
-
-
-void QWidget::setVisible(bool visible)
-{
- if (visible) { // show
- if (testAttribute(Qt::WA_WState_ExplicitShowHide) && !testAttribute(Qt::WA_WState_Hidden))
- return;
-
- Q_D(QWidget);
-
- // Designer uses a trick to make grabWidget work without showing
- if (!isWindow() && parentWidget() && parentWidget()->isVisible()
- && !parentWidget()->testAttribute(Qt::WA_WState_Created))
- parentWidget()->window()->d_func()->createRecursively();
-
- //we have to at least create toplevels before applyX11SpecificCommandLineArguments
- //but not children of non-visible parents
- QWidget *pw = parentWidget();
- if (!testAttribute(Qt::WA_WState_Created)
- && (isWindow() || pw->testAttribute(Qt::WA_WState_Created))) {
- create();
- }
-
-#if defined(Q_WS_X11)
- if (windowType() == Qt::Window)
- QApplicationPrivate::applyX11SpecificCommandLineArguments(this);
-#elif defined(Q_WS_QWS)
- if (windowType() == Qt::Window)
- QApplicationPrivate::applyQWSSpecificCommandLineArguments(this);
-#endif
-
- bool wasResized = testAttribute(Qt::WA_Resized);
- Qt::WindowStates initialWindowState = windowState();
-
- // polish if necessary
- ensurePolished();
-
- // remember that show was called explicitly
- setAttribute(Qt::WA_WState_ExplicitShowHide);
- // whether we need to inform the parent widget immediately
- bool needUpdateGeometry = !isWindow() && testAttribute(Qt::WA_WState_Hidden);
- // we are no longer hidden
- setAttribute(Qt::WA_WState_Hidden, false);
-
- if (needUpdateGeometry)
- d->updateGeometry_helper(true);
-
-#ifdef QT3_SUPPORT
- QApplication::sendPostedEvents(this, QEvent::ChildInserted);
-#endif
- // activate our layout before we and our children become visible
- if (d->layout)
- d->layout->activate();
-
- if (!isWindow()) {
- QWidget *parent = parentWidget();
- while (parent && parent->isVisible() && parent->d_func()->layout && !parent->data->in_show) {
- parent->d_func()->layout->activate();
- if (parent->isWindow())
- break;
- parent = parent->parentWidget();
- }
- if (parent)
- parent->d_func()->setDirtyOpaqueRegion();
- }
-
- // adjust size if necessary
- if (!wasResized
- && (isWindow() || !parentWidget()->d_func()->layout)) {
- if (isWindow()) {
- adjustSize();
- if (windowState() != initialWindowState)
- setWindowState(initialWindowState);
- } else {
- adjustSize();
- }
- setAttribute(Qt::WA_Resized, false);
- }
-
- setAttribute(Qt::WA_KeyboardFocusChange, false);
-
- if (isWindow() || parentWidget()->isVisible()) {
- // remove posted quit events when showing a new window
- QCoreApplication::removePostedEvents(qApp, QEvent::Quit);
-
- d->show_helper();
-
-#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) || defined(Q_WS_MAC) || defined(Q_WS_QPA)
- qApp->d_func()->sendSyntheticEnterLeave(this);
-#endif
- }
-
- QEvent showToParentEvent(QEvent::ShowToParent);
- QApplication::sendEvent(this, &showToParentEvent);
- } else { // hide
- if (testAttribute(Qt::WA_WState_ExplicitShowHide) && testAttribute(Qt::WA_WState_Hidden))
- return;
-#if defined(Q_WS_WIN)
- // reset WS_DISABLED style in a Blocked window
- if(isWindow() && testAttribute(Qt::WA_WState_Created)
- && QApplicationPrivate::isBlockedByModal(this))
- {
- LONG dwStyle = GetWindowLong(winId(), GWL_STYLE);
- dwStyle &= ~WS_DISABLED;
- SetWindowLong(winId(), GWL_STYLE, dwStyle);
- }
-#endif
- if (QApplicationPrivate::hidden_focus_widget == this)
- QApplicationPrivate::hidden_focus_widget = 0;
-
- Q_D(QWidget);
-
- // hw: The test on getOpaqueRegion() needs to be more intelligent
- // currently it doesn't work if the widget is hidden (the region will
- // be clipped). The real check should be testing the cached region
- // (and dirty flag) directly.
- if (!isWindow() && parentWidget()) // && !d->getOpaqueRegion().isEmpty())
- parentWidget()->d_func()->setDirtyOpaqueRegion();
-
- setAttribute(Qt::WA_WState_Hidden);
- setAttribute(Qt::WA_WState_ExplicitShowHide);
- if (testAttribute(Qt::WA_WState_Created))
- d->hide_helper();
-
- // invalidate layout similar to updateGeometry()
- if (!isWindow() && parentWidget()) {
- if (parentWidget()->d_func()->layout)
- parentWidget()->d_func()->layout->invalidate();
- else if (parentWidget()->isVisible())
- QApplication::postEvent(parentWidget(), new QEvent(QEvent::LayoutRequest));
- }
-
- QEvent hideToParentEvent(QEvent::HideToParent);
- QApplication::sendEvent(this, &hideToParentEvent);
- }
-}
-
-/*!\fn void QWidget::setHidden(bool hidden)
-
- Convenience function, equivalent to setVisible(!\a hidden).
-*/
-
-/*!\fn void QWidget::setShown(bool shown)
-
- Use setVisible(\a shown) instead.
-*/
-
-
-void QWidgetPrivate::_q_showIfNotHidden()
-{
- Q_Q(QWidget);
- if ( !(q->isHidden() && q->testAttribute(Qt::WA_WState_ExplicitShowHide)) )
- q->setVisible(true);
-}
-
-void QWidgetPrivate::showChildren(bool spontaneous)
-{
- QList<QObject*> childList = children;
- for (int i = 0; i < childList.size(); ++i) {
- QWidget *widget = qobject_cast<QWidget*>(childList.at(i));
- if (!widget
- || widget->isWindow()
- || widget->testAttribute(Qt::WA_WState_Hidden))
- continue;
- if (spontaneous) {
- widget->setAttribute(Qt::WA_Mapped);
- widget->d_func()->showChildren(true);
- QShowEvent e;
- QApplication::sendSpontaneousEvent(widget, &e);
- } else {
- if (widget->testAttribute(Qt::WA_WState_ExplicitShowHide))
- widget->d_func()->show_recursive();
- else
- widget->show();
- }
- }
-}
-
-void QWidgetPrivate::hideChildren(bool spontaneous)
-{
- QList<QObject*> childList = children;
- for (int i = 0; i < childList.size(); ++i) {
- QWidget *widget = qobject_cast<QWidget*>(childList.at(i));
- if (!widget || widget->isWindow() || widget->testAttribute(Qt::WA_WState_Hidden))
- continue;
-#ifdef QT_MAC_USE_COCOA
- // Before doing anything we need to make sure that we don't leave anything in a non-consistent state.
- // When hiding a widget we need to make sure that no mouse_down events are active, because
- // the mouse_up event will never be received by a hidden widget or one of its descendants.
- // The solution is simple, before going through with this we check if there are any mouse_down events in
- // progress, if so we check if it is related to this widget or not. If so, we just reset the mouse_down and
- // then we continue.
- // In X11 and Windows we send a mouse_release event, however we don't do that here because we were already
- // ignoring that from before. I.e. Carbon did not send the mouse release event, so we will not send the
- // mouse release event. There are two ways to interpret this:
- // 1. If we don't send the mouse release event, the widget might get into an inconsistent state, i.e. it
- // might be waiting for a release event that will never arrive.
- // 2. If we send the mouse release event, then the widget might decide to trigger an action that is not
- // supposed to trigger because it is not visible.
- if(widget == qt_button_down)
- qt_button_down = 0;
-#endif // QT_MAC_USE_COCOA
- if (spontaneous)
- widget->setAttribute(Qt::WA_Mapped, false);
- else
- widget->setAttribute(Qt::WA_WState_Visible, false);
- widget->d_func()->hideChildren(spontaneous);
- QHideEvent e;
- if (spontaneous) {
- QApplication::sendSpontaneousEvent(widget, &e);
- } else {
- QApplication::sendEvent(widget, &e);
- if (widget->internalWinId()
- && widget->testAttribute(Qt::WA_DontCreateNativeAncestors)) {
- // hide_sys() on an ancestor won't have any affect on this
- // widget, so it needs an explicit hide_sys() of its own
- widget->d_func()->hide_sys();
- }
- }
-#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) || defined(Q_WS_MAC) || defined(Q_WS_QPA)
- qApp->d_func()->sendSyntheticEnterLeave(widget);
-#endif
-#ifndef QT_NO_ACCESSIBILITY
- if (!spontaneous)
- QAccessible::updateAccessibility(widget, 0, QAccessible::ObjectHide);
-#endif
- }
-}
-
-bool QWidgetPrivate::close_helper(CloseMode mode)
-{
- if (data.is_closing)
- return true;
-
- Q_Q(QWidget);
- data.is_closing = 1;
-
- QPointer<QWidget> that = q;
- QPointer<QWidget> parentWidget = q->parentWidget();
-
-#ifdef QT3_SUPPORT
- bool isMain = (QApplicationPrivate::main_widget == q);
-#endif
- bool quitOnClose = q->testAttribute(Qt::WA_QuitOnClose);
- if (mode != CloseNoEvent) {
- QCloseEvent e;
- if (mode == CloseWithSpontaneousEvent)
- QApplication::sendSpontaneousEvent(q, &e);
- else
- QApplication::sendEvent(q, &e);
- if (!that.isNull() && !e.isAccepted()) {
- data.is_closing = 0;
- return false;
- }
- }
-
- if (!that.isNull() && !q->isHidden())
- q->hide();
-
-#ifdef QT3_SUPPORT
- if (isMain)
- QApplication::quit();
-#endif
- // Attempt to close the application only if this has WA_QuitOnClose set and a non-visible parent
- quitOnClose = quitOnClose && (parentWidget.isNull() || !parentWidget->isVisible());
-
- if (quitOnClose) {
- /* if there is no non-withdrawn primary window left (except
- the ones without QuitOnClose), we emit the lastWindowClosed
- signal */
- QWidgetList list = QApplication::topLevelWidgets();
- bool lastWindowClosed = true;
- for (int i = 0; i < list.size(); ++i) {
- QWidget *w = list.at(i);
- if (!w->isVisible() || w->parentWidget() || !w->testAttribute(Qt::WA_QuitOnClose))
- continue;
- lastWindowClosed = false;
- break;
- }
- if (lastWindowClosed)
- QApplicationPrivate::emitLastWindowClosed();
- }
-
- if (!that.isNull()) {
- data.is_closing = 0;
- if (q->testAttribute(Qt::WA_DeleteOnClose)) {
- q->setAttribute(Qt::WA_DeleteOnClose, false);
- q->deleteLater();
- }
- }
- return true;
-}
-
-
-/*!
- Closes this widget. Returns true if the widget was closed;
- otherwise returns false.
-
- First it sends the widget a QCloseEvent. The widget is \link
- hide() hidden\endlink if it \link QCloseEvent::accept()
- accepts\endlink the close event. If it \link QCloseEvent::ignore()
- ignores\endlink the event, nothing happens. The default
- implementation of QWidget::closeEvent() accepts the close event.
-
- If the widget has the Qt::WA_DeleteOnClose flag, the widget
- is also deleted. A close events is delivered to the widget no
- matter if the widget is visible or not.
-
- The \l QApplication::lastWindowClosed() signal is emitted when the
- last visible primary window (i.e. window with no parent) with the
- Qt::WA_QuitOnClose attribute set is closed. By default this
- attribute is set for all widgets except transient windows such as
- splash screens, tool windows, and popup menus.
-
-*/
-
-bool QWidget::close()
-{
- return d_func()->close_helper(QWidgetPrivate::CloseWithEvent);
-}
-
-/*!
- \property QWidget::visible
- \brief whether the widget is visible
-
- Calling setVisible(true) or show() sets the widget to visible
- status if all its parent widgets up to the window are visible. If
- an ancestor is not visible, the widget won't become visible until
- all its ancestors are shown. If its size or position has changed,
- Qt guarantees that a widget gets move and resize events just
- before it is shown. If the widget has not been resized yet, Qt
- will adjust the widget's size to a useful default using
- adjustSize().
-
- Calling setVisible(false) or hide() hides a widget explicitly. An
- explicitly hidden widget will never become visible, even if all
- its ancestors become visible, unless you show it.
-
- A widget receives show and hide events when its visibility status
- changes. Between a hide and a show event, there is no need to
- waste CPU cycles preparing or displaying information to the user.
- A video application, for example, might simply stop generating new
- frames.
-
- A widget that happens to be obscured by other windows on the
- screen is considered to be visible. The same applies to iconified
- windows and windows that exist on another virtual
- desktop (on platforms that support this concept). A widget
- receives spontaneous show and hide events when its mapping status
- is changed by the window system, e.g. a spontaneous hide event
- when the user minimizes the window, and a spontaneous show event
- when the window is restored again.
-
- You almost never have to reimplement the setVisible() function. If
- you need to change some settings before a widget is shown, use
- showEvent() instead. If you need to do some delayed initialization
- use the Polish event delivered to the event() function.
-
- \sa show(), hide(), isHidden(), isVisibleTo(), isMinimized(),
- showEvent(), hideEvent()
-*/
-
-
-/*!
- Returns true if this widget would become visible if \a ancestor is
- shown; otherwise returns false.
-
- The true case occurs if neither the widget itself nor any parent
- up to but excluding \a ancestor has been explicitly hidden.
-
- This function will still return true if the widget is obscured by
- other windows on the screen, but could be physically visible if it
- or they were to be moved.
-
- isVisibleTo(0) is identical to isVisible().
-
- \sa show() hide() isVisible()
-*/
-
-bool QWidget::isVisibleTo(QWidget* ancestor) const
-{
- if (!ancestor)
- return isVisible();
- const QWidget * w = this;
- while (!w->isHidden()
- && !w->isWindow()
- && w->parentWidget()
- && w->parentWidget() != ancestor)
- w = w->parentWidget();
- return !w->isHidden();
-}
-
-#ifdef QT3_SUPPORT
-/*!
- Use visibleRegion() instead.
-*/
-QRect QWidget::visibleRect() const
-{
- return d_func()->clipRect();
-}
-#endif
-
-/*!
- Returns the unobscured region where paint events can occur.
-
- For visible widgets, this is an approximation of the area not
- covered by other widgets; otherwise, this is an empty region.
-
- The repaint() function calls this function if necessary, so in
- general you do not need to call it.
-
-*/
-QRegion QWidget::visibleRegion() const
-{
- Q_D(const QWidget);
-
- QRect clipRect = d->clipRect();
- if (clipRect.isEmpty())
- return QRegion();
- QRegion r(clipRect);
- d->subtractOpaqueChildren(r, clipRect);
- d->subtractOpaqueSiblings(r);
-#ifdef Q_WS_QWS
- const QWSWindowSurface *surface = static_cast<const QWSWindowSurface*>(windowSurface());
- if (surface) {
- const QPoint offset = mapTo(surface->window(), QPoint());
- r &= surface->clipRegion().translated(-offset);
- }
-#endif
- return r;
-}
-
-
-QSize QWidgetPrivate::adjustedSize() const
-{
- Q_Q(const QWidget);
-
- QSize s = q->sizeHint();
-
- if (q->isWindow()) {
- Qt::Orientations exp;
- if (layout) {
- if (layout->hasHeightForWidth())
- s.setHeight(layout->totalHeightForWidth(s.width()));
- exp = layout->expandingDirections();
- } else
- {
- if (q->sizePolicy().hasHeightForWidth())
- s.setHeight(q->heightForWidth(s.width()));
- exp = q->sizePolicy().expandingDirections();
- }
- if (exp & Qt::Horizontal)
- s.setWidth(qMax(s.width(), 200));
- if (exp & Qt::Vertical)
- s.setHeight(qMax(s.height(), 100));
-#if defined(Q_WS_X11)
- QRect screen = QApplication::desktop()->screenGeometry(q->x11Info().screen());
-#else // all others
- QRect screen = QApplication::desktop()->screenGeometry(q->pos());
-#endif
-#if defined (Q_WS_WINCE) || defined (Q_OS_SYMBIAN)
- s.setWidth(qMin(s.width(), screen.width()));
- s.setHeight(qMin(s.height(), screen.height()));
-#else
- s.setWidth(qMin(s.width(), screen.width()*2/3));
- s.setHeight(qMin(s.height(), screen.height()*2/3));
-#endif
- if (QTLWExtra *extra = maybeTopData())
- extra->sizeAdjusted = true;
- }
-
- if (!s.isValid()) {
- QRect r = q->childrenRect(); // get children rectangle
- if (r.isNull())
- return s;
- s = r.size() + QSize(2 * r.x(), 2 * r.y());
- }
-
- return s;
-}
-
-/*!
- Adjusts the size of the widget to fit its contents.
-
- This function uses sizeHint() if it is valid, i.e., the size hint's width
- and height are \>= 0. Otherwise, it sets the size to the children
- rectangle that covers all child widgets (the union of all child widget
- rectangles).
-
- For windows, the screen size is also taken into account. If the sizeHint()
- is less than (200, 100) and the size policy is \l{QSizePolicy::Expanding}
- {expanding}, the window will be at least (200, 100). The maximum size of
- a window is 2/3 of the screen's width and height.
-
- \sa sizeHint(), childrenRect()
-*/
-
-void QWidget::adjustSize()
-{
- Q_D(QWidget);
- ensurePolished();
- QSize s = d->adjustedSize();
-
- if (d->layout)
- d->layout->activate();
-
- if (s.isValid())
- resize(s);
-}
-
-
-/*!
- \property QWidget::sizeHint
- \brief the recommended size for the widget
-
- If the value of this property is an invalid size, no size is
- recommended.
-
- The default implementation of sizeHint() returns an invalid size
- if there is no layout for this widget, and returns the layout's
- preferred size otherwise.
-
- \sa QSize::isValid(), minimumSizeHint(), sizePolicy(),
- setMinimumSize(), updateGeometry()
-*/
-
-QSize QWidget::sizeHint() const
-{
- Q_D(const QWidget);
- if (d->layout)
- return d->layout->totalSizeHint();
- return QSize(-1, -1);
-}
-
-/*!
- \property QWidget::minimumSizeHint
- \brief the recommended minimum size for the widget
-
- If the value of this property is an invalid size, no minimum size
- is recommended.
-
- The default implementation of minimumSizeHint() returns an invalid
- size if there is no layout for this widget, and returns the
- layout's minimum size otherwise. Most built-in widgets reimplement
- minimumSizeHint().
-
- \l QLayout will never resize a widget to a size smaller than the
- minimum size hint unless minimumSize() is set or the size policy is
- set to QSizePolicy::Ignore. If minimumSize() is set, the minimum
- size hint will be ignored.
-
- \sa QSize::isValid(), resize(), setMinimumSize(), sizePolicy()
-*/
-QSize QWidget::minimumSizeHint() const
-{
- Q_D(const QWidget);
- if (d->layout)
- return d->layout->totalMinimumSize();
- return QSize(-1, -1);
-}
-
-
-/*!
- \fn QWidget *QWidget::parentWidget() const
-
- Returns the parent of this widget, or 0 if it does not have any
- parent widget.
-*/
-
-
-/*!
- Returns true if this widget is a parent, (or grandparent and so on
- to any level), of the given \a child, and both widgets are within
- the same window; otherwise returns false.
-*/
-
-bool QWidget::isAncestorOf(const QWidget *child) const
-{
- while (child) {
- if (child == this)
- return true;
- if (child->isWindow())
- return false;
- child = child->parentWidget();
- }
- return false;
-}
-
-#if defined(Q_WS_WIN)
-inline void setDisabledStyle(QWidget *w, bool setStyle)
-{
- // set/reset WS_DISABLED style.
- if(w && w->isWindow() && w->isVisible() && w->isEnabled()) {
- LONG dwStyle = GetWindowLong(w->winId(), GWL_STYLE);
- LONG newStyle = dwStyle;
- if (setStyle)
- newStyle |= WS_DISABLED;
- else
- newStyle &= ~WS_DISABLED;
- if (newStyle != dwStyle) {
- SetWindowLong(w->winId(), GWL_STYLE, newStyle);
- // we might need to repaint in some situations (eg. menu)
- w->repaint();
- }
- }
-}
-#endif
-
-/*****************************************************************************
- QWidget event handling
- *****************************************************************************/
-
-/*!
- This is the main event handler; it handles event \a event. You can
- reimplement this function in a subclass, but we recommend using
- one of the specialized event handlers instead.
-
- Key press and release events are treated differently from other
- events. event() checks for Tab and Shift+Tab and tries to move the
- focus appropriately. If there is no widget to move the focus to
- (or the key press is not Tab or Shift+Tab), event() calls
- keyPressEvent().
-
- Mouse and tablet event handling is also slightly special: only
- when the widget is \l enabled, event() will call the specialized
- handlers such as mousePressEvent(); otherwise it will discard the
- event.
-
- This function returns true if the event was recognized, otherwise
- it returns false. If the recognized event was accepted (see \l
- QEvent::accepted), any further processing such as event
- propagation to the parent widget stops.
-
- \sa closeEvent(), focusInEvent(), focusOutEvent(), enterEvent(),
- keyPressEvent(), keyReleaseEvent(), leaveEvent(),
- mouseDoubleClickEvent(), mouseMoveEvent(), mousePressEvent(),
- mouseReleaseEvent(), moveEvent(), paintEvent(), resizeEvent(),
- QObject::event(), QObject::timerEvent()
-*/
-
-bool QWidget::event(QEvent *event)
-{
- Q_D(QWidget);
-
- // ignore mouse events when disabled
- if (!isEnabled()) {
- switch(event->type()) {
- case QEvent::TabletPress:
- case QEvent::TabletRelease:
- case QEvent::TabletMove:
- case QEvent::MouseButtonPress:
- case QEvent::MouseButtonRelease:
- case QEvent::MouseButtonDblClick:
- case QEvent::MouseMove:
- case QEvent::TouchBegin:
- case QEvent::TouchUpdate:
- case QEvent::TouchEnd:
- case QEvent::ContextMenu:
-#ifndef QT_NO_WHEELEVENT
- case QEvent::Wheel:
-#endif
- return false;
- default:
- break;
- }
- }
- switch (event->type()) {
- case QEvent::MouseMove:
- mouseMoveEvent((QMouseEvent*)event);
- break;
-
- case QEvent::MouseButtonPress:
- // Don't reset input context here. Whether reset or not is
- // a responsibility of input method. reset() will be
- // called by mouseHandler() of input method if necessary
- // via mousePressEvent() of text widgets.
-#if 0
- resetInputContext();
-#endif
- mousePressEvent((QMouseEvent*)event);
- break;
-
- case QEvent::MouseButtonRelease:
- mouseReleaseEvent((QMouseEvent*)event);
- break;
-
- case QEvent::MouseButtonDblClick:
- mouseDoubleClickEvent((QMouseEvent*)event);
- break;
-#ifndef QT_NO_WHEELEVENT
- case QEvent::Wheel:
- wheelEvent((QWheelEvent*)event);
- break;
-#endif
-#ifndef QT_NO_TABLETEVENT
- case QEvent::TabletMove:
- case QEvent::TabletPress:
- case QEvent::TabletRelease:
- tabletEvent((QTabletEvent*)event);
- break;
-#endif
-#ifdef QT3_SUPPORT
- case QEvent::Accel:
- event->ignore();
- return false;
-#endif
- case QEvent::KeyPress: {
- QKeyEvent *k = (QKeyEvent *)event;
- bool res = false;
- if (!(k->modifiers() & (Qt::ControlModifier | Qt::AltModifier))) { //### Add MetaModifier?
- if (k->key() == Qt::Key_Backtab
- || (k->key() == Qt::Key_Tab && (k->modifiers() & Qt::ShiftModifier)))
- res = focusNextPrevChild(false);
- else if (k->key() == Qt::Key_Tab)
- res = focusNextPrevChild(true);
- if (res)
- break;
- }
- keyPressEvent(k);
-#ifdef QT_KEYPAD_NAVIGATION
- if (!k->isAccepted() && QApplication::keypadNavigationEnabled()
- && !(k->modifiers() & (Qt::ControlModifier | Qt::AltModifier | Qt::ShiftModifier))) {
- if (QApplication::navigationMode() == Qt::NavigationModeKeypadTabOrder) {
- if (k->key() == Qt::Key_Up)
- res = focusNextPrevChild(false);
- else if (k->key() == Qt::Key_Down)
- res = focusNextPrevChild(true);
- } else if (QApplication::navigationMode() == Qt::NavigationModeKeypadDirectional) {
- if (k->key() == Qt::Key_Up)
- res = QWidgetPrivate::navigateToDirection(QWidgetPrivate::DirectionNorth);
- else if (k->key() == Qt::Key_Right)
- res = QWidgetPrivate::navigateToDirection(QWidgetPrivate::DirectionEast);
- else if (k->key() == Qt::Key_Down)
- res = QWidgetPrivate::navigateToDirection(QWidgetPrivate::DirectionSouth);
- else if (k->key() == Qt::Key_Left)
- res = QWidgetPrivate::navigateToDirection(QWidgetPrivate::DirectionWest);
- }
- if (res) {
- k->accept();
- break;
- }
- }
-#endif
-#ifndef QT_NO_WHATSTHIS
- if (!k->isAccepted()
- && k->modifiers() & Qt::ShiftModifier && k->key() == Qt::Key_F1
- && d->whatsThis.size()) {
- QWhatsThis::showText(mapToGlobal(inputMethodQuery(Qt::ImMicroFocus).toRect().center()), d->whatsThis, this);
- k->accept();
- }
-#endif
- }
- break;
-
- case QEvent::KeyRelease:
- keyReleaseEvent((QKeyEvent*)event);
- // fall through
- case QEvent::ShortcutOverride:
- break;
-
- case QEvent::InputMethod:
- inputMethodEvent((QInputMethodEvent *) event);
- break;
-
- case QEvent::PolishRequest:
- ensurePolished();
- break;
-
- case QEvent::Polish: {
- style()->polish(this);
- setAttribute(Qt::WA_WState_Polished);
- if (!QApplication::font(this).isCopyOf(QApplication::font()))
- d->resolveFont();
- if (!QApplication::palette(this).isCopyOf(QApplication::palette()))
- d->resolvePalette();
-#ifdef QT3_SUPPORT
- if(d->sendChildEvents)
- QApplication::sendPostedEvents(this, QEvent::ChildInserted);
-#endif
- }
- break;
-
- case QEvent::ApplicationWindowIconChange:
- if (isWindow() && !testAttribute(Qt::WA_SetWindowIcon)) {
- d->setWindowIcon_sys();
- d->setWindowIcon_helper();
- }
- break;
- case QEvent::FocusIn:
-#ifdef QT_SOFTKEYS_ENABLED
- QSoftKeyManager::updateSoftKeys();
-#endif
- focusInEvent((QFocusEvent*)event);
- break;
-
- case QEvent::FocusOut:
- focusOutEvent((QFocusEvent*)event);
- break;
-
- case QEvent::Enter:
-#ifndef QT_NO_STATUSTIP
- if (d->statusTip.size()) {
- QStatusTipEvent tip(d->statusTip);
- QApplication::sendEvent(const_cast<QWidget *>(this), &tip);
- }
-#endif
- enterEvent(event);
- break;
-
- case QEvent::Leave:
-#ifndef QT_NO_STATUSTIP
- if (d->statusTip.size()) {
- QString empty;
- QStatusTipEvent tip(empty);
- QApplication::sendEvent(const_cast<QWidget *>(this), &tip);
- }
-#endif
- leaveEvent(event);
- break;
-
- case QEvent::HoverEnter:
- case QEvent::HoverLeave:
- update();
- break;
-
- case QEvent::Paint:
- // At this point the event has to be delivered, regardless
- // whether the widget isVisible() or not because it
- // already went through the filters
- paintEvent((QPaintEvent*)event);
- break;
-
- case QEvent::Move:
- moveEvent((QMoveEvent*)event);
- break;
-
- case QEvent::Resize:
- resizeEvent((QResizeEvent*)event);
- break;
-
- case QEvent::Close:
- closeEvent((QCloseEvent *)event);
- break;
-
-#ifndef QT_NO_CONTEXTMENU
- case QEvent::ContextMenu:
- switch (data->context_menu_policy) {
- case Qt::PreventContextMenu:
- break;
- case Qt::DefaultContextMenu:
- contextMenuEvent(static_cast<QContextMenuEvent *>(event));
- break;
- case Qt::CustomContextMenu:
- emit customContextMenuRequested(static_cast<QContextMenuEvent *>(event)->pos());
- break;
-#ifndef QT_NO_MENU
- case Qt::ActionsContextMenu:
- if (d->actions.count()) {
- QMenu::exec(d->actions, static_cast<QContextMenuEvent *>(event)->globalPos(),
- 0, this);
- break;
- }
- // fall through
-#endif
- default:
- event->ignore();
- break;
- }
- break;
-#endif // QT_NO_CONTEXTMENU
-
-#ifndef QT_NO_DRAGANDDROP
- case QEvent::Drop:
- dropEvent((QDropEvent*) event);
- break;
-
- case QEvent::DragEnter:
- dragEnterEvent((QDragEnterEvent*) event);
- break;
-
- case QEvent::DragMove:
- dragMoveEvent((QDragMoveEvent*) event);
- break;
-
- case QEvent::DragLeave:
- dragLeaveEvent((QDragLeaveEvent*) event);
- break;
-#endif
-
- case QEvent::Show:
- showEvent((QShowEvent*) event);
- break;
-
- case QEvent::Hide:
- hideEvent((QHideEvent*) event);
- break;
-
- case QEvent::ShowWindowRequest:
- if (!isHidden())
- d->show_sys();
- break;
-
- case QEvent::ApplicationFontChange:
- d->resolveFont();
- break;
- case QEvent::ApplicationPaletteChange:
- if (!(windowType() == Qt::Desktop))
- d->resolvePalette();
- break;
-
- case QEvent::ToolBarChange:
- case QEvent::ActivationChange:
- case QEvent::EnabledChange:
- case QEvent::FontChange:
- case QEvent::StyleChange:
- case QEvent::PaletteChange:
- case QEvent::WindowTitleChange:
- case QEvent::IconTextChange:
- case QEvent::ModifiedChange:
- case QEvent::MouseTrackingChange:
- case QEvent::ParentChange:
- case QEvent::WindowStateChange:
- case QEvent::LocaleChange:
- case QEvent::MacSizeChange:
- case QEvent::ContentsRectChange:
- changeEvent(event);
- break;
-
- case QEvent::WindowActivate:
- case QEvent::WindowDeactivate: {
-#ifdef QT3_SUPPORT
- windowActivationChange(event->type() != QEvent::WindowActivate);
-#endif
- if (isVisible() && !palette().isEqual(QPalette::Active, QPalette::Inactive))
- update();
- QList<QObject*> childList = d->children;
- for (int i = 0; i < childList.size(); ++i) {
- QWidget *w = qobject_cast<QWidget *>(childList.at(i));
- if (w && w->isVisible() && !w->isWindow())
- QApplication::sendEvent(w, event);
- }
-
-#ifdef QT_SOFTKEYS_ENABLED
- if (isWindow())
- QSoftKeyManager::updateSoftKeys();
-#endif
-
- break; }
-
- case QEvent::LanguageChange:
-#ifdef QT3_SUPPORT
- languageChange();
-#endif
- changeEvent(event);
- {
- QList<QObject*> childList = d->children;
- for (int i = 0; i < childList.size(); ++i) {
- QObject *o = childList.at(i);
- if (o)
- QApplication::sendEvent(o, event);
- }
- }
- update();
- break;
-
- case QEvent::ApplicationLayoutDirectionChange:
- d->resolveLayoutDirection();
- break;
-
- case QEvent::LayoutDirectionChange:
- if (d->layout)
- d->layout->invalidate();
- update();
- changeEvent(event);
- break;
- case QEvent::UpdateRequest:
- d->syncBackingStore();
- break;
- case QEvent::UpdateLater:
- update(static_cast<QUpdateLaterEvent*>(event)->region());
- break;
-
- case QEvent::WindowBlocked:
- case QEvent::WindowUnblocked:
- {
- QList<QObject*> childList = d->children;
- for (int i = 0; i < childList.size(); ++i) {
- QObject *o = childList.at(i);
- if (o && o != QApplication::activeModalWidget()) {
- if (qobject_cast<QWidget *>(o) && static_cast<QWidget *>(o)->isWindow()) {
- // do not forward the event to child windows,
- // QApplication does this for us
- continue;
- }
- QApplication::sendEvent(o, event);
- }
- }
-#if defined(Q_WS_WIN)
- setDisabledStyle(this, (event->type() == QEvent::WindowBlocked));
-#endif
- }
- break;
-#ifndef QT_NO_TOOLTIP
- case QEvent::ToolTip:
- if (!d->toolTip.isEmpty())
- QToolTip::showText(static_cast<QHelpEvent*>(event)->globalPos(), d->toolTip, this);
- else
- event->ignore();
- break;
-#endif
-#ifndef QT_NO_WHATSTHIS
- case QEvent::WhatsThis:
- if (d->whatsThis.size())
- QWhatsThis::showText(static_cast<QHelpEvent *>(event)->globalPos(), d->whatsThis, this);
- else
- event->ignore();
- break;
- case QEvent::QueryWhatsThis:
- if (d->whatsThis.isEmpty())
- event->ignore();
- break;
-#endif
-#ifndef QT_NO_ACCESSIBILITY
- case QEvent::AccessibilityDescription:
- case QEvent::AccessibilityHelp: {
- QAccessibleEvent *ev = static_cast<QAccessibleEvent *>(event);
- if (ev->child())
- return false;
- switch (ev->type()) {
-#ifndef QT_NO_TOOLTIP
- case QEvent::AccessibilityDescription:
- ev->setValue(d->toolTip);
- break;
-#endif
-#ifndef QT_NO_WHATSTHIS
- case QEvent::AccessibilityHelp:
- ev->setValue(d->whatsThis);
- break;
-#endif
- default:
- return false;
- }
- break; }
-#endif
- case QEvent::EmbeddingControl:
- d->topData()->frameStrut.setCoords(0 ,0, 0, 0);
- data->fstrut_dirty = false;
-#if defined(Q_WS_WIN) || defined(Q_WS_X11)
- d->topData()->embedded = 1;
-#endif
- break;
-#ifndef QT_NO_ACTION
- case QEvent::ActionAdded:
- case QEvent::ActionRemoved:
- case QEvent::ActionChanged:
-#ifdef QT_SOFTKEYS_ENABLED
- QSoftKeyManager::updateSoftKeys();
-#endif
- actionEvent((QActionEvent*)event);
- break;
-#endif
-
- case QEvent::KeyboardLayoutChange:
- {
- changeEvent(event);
-
- // inform children of the change
- QList<QObject*> childList = d->children;
- for (int i = 0; i < childList.size(); ++i) {
- QWidget *w = qobject_cast<QWidget *>(childList.at(i));
- if (w && w->isVisible() && !w->isWindow())
- QApplication::sendEvent(w, event);
- }
- break;
- }
-#ifdef Q_WS_MAC
- case QEvent::MacGLWindowChange:
- d->needWindowChange = false;
- break;
-#endif
- case QEvent::TouchBegin:
- case QEvent::TouchUpdate:
- case QEvent::TouchEnd:
- {
-#ifndef Q_WS_MAC
- QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event);
- const QTouchEvent::TouchPoint &touchPoint = touchEvent->touchPoints().first();
- if (touchPoint.isPrimary() || touchEvent->deviceType() == QTouchEvent::TouchPad)
- break;
-
- // fake a mouse event!
- QEvent::Type eventType = QEvent::None;
- switch (touchEvent->type()) {
- case QEvent::TouchBegin:
- eventType = QEvent::MouseButtonPress;
- break;
- case QEvent::TouchUpdate:
- eventType = QEvent::MouseMove;
- break;
- case QEvent::TouchEnd:
- eventType = QEvent::MouseButtonRelease;
- break;
- default:
- Q_ASSERT(!true);
- break;
- }
- if (eventType == QEvent::None)
- break;
-
- QMouseEvent mouseEvent(eventType,
- touchPoint.pos().toPoint(),
- touchPoint.screenPos().toPoint(),
- Qt::LeftButton,
- Qt::LeftButton,
- touchEvent->modifiers());
- (void) QApplication::sendEvent(this, &mouseEvent);
-#endif // Q_WS_MAC
- break;
- }
-#ifndef QT_NO_GESTURES
- case QEvent::Gesture:
- event->ignore();
- break;
-#endif
-#ifndef QT_NO_PROPERTIES
- case QEvent::DynamicPropertyChange: {
- const QByteArray &propName = static_cast<QDynamicPropertyChangeEvent *>(event)->propertyName();
- if (!qstrncmp(propName, "_q_customDpi", 12) && propName.length() == 13) {
- uint value = property(propName.constData()).toUInt();
- if (!d->extra)
- d->createExtra();
- const char axis = propName.at(12);
- if (axis == 'X')
- d->extra->customDpiX = value;
- else if (axis == 'Y')
- d->extra->customDpiY = value;
- d->updateFont(d->data.fnt);
- }
- // fall through
- }
-#endif
- default:
- return QObject::event(event);
- }
- return true;
-}
-
-/*!
- This event handler can be reimplemented to handle state changes.
-
- The state being changed in this event can be retrieved through the \a event
- supplied.
-
- Change events include: QEvent::ToolBarChange,
- QEvent::ActivationChange, QEvent::EnabledChange, QEvent::FontChange,
- QEvent::StyleChange, QEvent::PaletteChange,
- QEvent::WindowTitleChange, QEvent::IconTextChange,
- QEvent::ModifiedChange, QEvent::MouseTrackingChange,
- QEvent::ParentChange, QEvent::WindowStateChange,
- QEvent::LanguageChange, QEvent::LocaleChange,
- QEvent::LayoutDirectionChange.
-
-*/
-void QWidget::changeEvent(QEvent * event)
-{
- switch(event->type()) {
- case QEvent::EnabledChange:
- update();
-#ifndef QT_NO_ACCESSIBILITY
- QAccessible::updateAccessibility(this, 0, QAccessible::StateChanged);
-#endif
- break;
-
- case QEvent::FontChange:
- case QEvent::StyleChange: {
- Q_D(QWidget);
- update();
- updateGeometry();
- if (d->layout)
- d->layout->invalidate();
-#ifdef Q_WS_QWS
- if (isWindow())
- d->data.fstrut_dirty = true;
-#endif
- break;
- }
-
- case QEvent::PaletteChange:
- update();
- break;
-
-#ifdef Q_WS_MAC
- case QEvent::MacSizeChange:
- updateGeometry();
- break;
- case QEvent::ToolTipChange:
- case QEvent::MouseTrackingChange:
- qt_mac_update_mouseTracking(this);
- break;
-#endif
-
- default:
- break;
- }
-}
-
-/*!
- This event handler, for event \a event, can be reimplemented in a
- subclass to receive mouse move events for the widget.
-
- If mouse tracking is switched off, mouse move events only occur if
- a mouse button is pressed while the mouse is being moved. If mouse
- tracking is switched on, mouse move events occur even if no mouse
- button is pressed.
-
- QMouseEvent::pos() reports the position of the mouse cursor,
- relative to this widget. For press and release events, the
- position is usually the same as the position of the last mouse
- move event, but it might be different if the user's hand shakes.
- This is a feature of the underlying window system, not Qt.
-
- If you want to show a tooltip immediately, while the mouse is
- moving (e.g., to get the mouse coordinates with QMouseEvent::pos()
- and show them as a tooltip), you must first enable mouse tracking
- as described above. Then, to ensure that the tooltip is updated
- immediately, you must call QToolTip::showText() instead of
- setToolTip() in your implementation of mouseMoveEvent().
-
- \sa setMouseTracking(), mousePressEvent(), mouseReleaseEvent(),
- mouseDoubleClickEvent(), event(), QMouseEvent, {Scribble Example}
-*/
-
-void QWidget::mouseMoveEvent(QMouseEvent *event)
-{
- event->ignore();
-}
-
-/*!
- This event handler, for event \a event, can be reimplemented in a
- subclass to receive mouse press events for the widget.
-
- If you create new widgets in the mousePressEvent() the
- mouseReleaseEvent() may not end up where you expect, depending on
- the underlying window system (or X11 window manager), the widgets'
- location and maybe more.
-
- The default implementation implements the closing of popup widgets
- when you click outside the window. For other widget types it does
- nothing.
-
- \sa mouseReleaseEvent(), mouseDoubleClickEvent(),
- mouseMoveEvent(), event(), QMouseEvent, {Scribble Example}
-*/
-
-void QWidget::mousePressEvent(QMouseEvent *event)
-{
- event->ignore();
- if ((windowType() == Qt::Popup)) {
- event->accept();
- QWidget* w;
- while ((w = QApplication::activePopupWidget()) && w != this){
- w->close();
- if (QApplication::activePopupWidget() == w) // widget does not want to disappear
- w->hide(); // hide at least
- }
- if (!rect().contains(event->pos())){
- close();
- }
- }
-}
-
-/*!
- This event handler, for event \a event, can be reimplemented in a
- subclass to receive mouse release events for the widget.
-
- \sa mousePressEvent(), mouseDoubleClickEvent(),
- mouseMoveEvent(), event(), QMouseEvent, {Scribble Example}
-*/
-
-void QWidget::mouseReleaseEvent(QMouseEvent *event)
-{
- event->ignore();
-}
-
-/*!
- This event handler, for event \a event, can be reimplemented in a
- subclass to receive mouse double click events for the widget.
-
- The default implementation generates a normal mouse press event.
-
- \note The widget will also receive mouse press and mouse release
- events in addition to the double click event. It is up to the
- developer to ensure that the application interprets these events
- correctly.
-
- \sa mousePressEvent(), mouseReleaseEvent() mouseMoveEvent(),
- event(), QMouseEvent
-*/
-
-void QWidget::mouseDoubleClickEvent(QMouseEvent *event)
-{
- mousePressEvent(event); // try mouse press event
-}
-
-#ifndef QT_NO_WHEELEVENT
-/*!
- This event handler, for event \a event, can be reimplemented in a
- subclass to receive wheel events for the widget.
-
- If you reimplement this handler, it is very important that you
- \link QWheelEvent ignore()\endlink the event if you do not handle
- it, so that the widget's parent can interpret it.
-
- The default implementation ignores the event.
-
- \sa QWheelEvent::ignore(), QWheelEvent::accept(), event(),
- QWheelEvent
-*/
-
-void QWidget::wheelEvent(QWheelEvent *event)
-{
- event->ignore();
-}
-#endif // QT_NO_WHEELEVENT
-
-#ifndef QT_NO_TABLETEVENT
-/*!
- This event handler, for event \a event, can be reimplemented in a
- subclass to receive tablet events for the widget.
-
- If you reimplement this handler, it is very important that you
- \link QTabletEvent ignore()\endlink the event if you do not handle
- it, so that the widget's parent can interpret it.
-
- The default implementation ignores the event.
-
- \sa QTabletEvent::ignore(), QTabletEvent::accept(), event(),
- QTabletEvent
-*/
-
-void QWidget::tabletEvent(QTabletEvent *event)
-{
- event->ignore();
-}
-#endif // QT_NO_TABLETEVENT
-
-/*!
- This event handler, for event \a event, can be reimplemented in a
- subclass to receive key press events for the widget.
-
- A widget must call setFocusPolicy() to accept focus initially and
- have focus in order to receive a key press event.
-
- If you reimplement this handler, it is very important that you
- call the base class implementation if you do not act upon the key.
-
- The default implementation closes popup widgets if the user
- presses Esc. Otherwise the event is ignored, so that the widget's
- parent can interpret it.
-
- Note that QKeyEvent starts with isAccepted() == true, so you do not
- need to call QKeyEvent::accept() - just do not call the base class
- implementation if you act upon the key.
-
- \sa keyReleaseEvent(), setFocusPolicy(),
- focusInEvent(), focusOutEvent(), event(), QKeyEvent, {Tetrix Example}
-*/
-
-void QWidget::keyPressEvent(QKeyEvent *event)
-{
- if ((windowType() == Qt::Popup) && event->key() == Qt::Key_Escape) {
- event->accept();
- close();
- } else {
- event->ignore();
- }
-}
-
-/*!
- This event handler, for event \a event, can be reimplemented in a
- subclass to receive key release events for the widget.
-
- A widget must \link setFocusPolicy() accept focus\endlink
- initially and \link hasFocus() have focus\endlink in order to
- receive a key release event.
-
- If you reimplement this handler, it is very important that you
- call the base class implementation if you do not act upon the key.
-
- The default implementation ignores the event, so that the widget's
- parent can interpret it.
-
- Note that QKeyEvent starts with isAccepted() == true, so you do not
- need to call QKeyEvent::accept() - just do not call the base class
- implementation if you act upon the key.
-
- \sa keyPressEvent(), QKeyEvent::ignore(), setFocusPolicy(),
- focusInEvent(), focusOutEvent(), event(), QKeyEvent
-*/
-
-void QWidget::keyReleaseEvent(QKeyEvent *event)
-{
- event->ignore();
-}
-
-/*!
- \fn void QWidget::focusInEvent(QFocusEvent *event)
-
- This event handler can be reimplemented in a subclass to receive
- keyboard focus events (focus received) for the widget. The event
- is passed in the \a event parameter
-
- A widget normally must setFocusPolicy() to something other than
- Qt::NoFocus in order to receive focus events. (Note that the
- application programmer can call setFocus() on any widget, even
- those that do not normally accept focus.)
-
- The default implementation updates the widget (except for windows
- that do not specify a focusPolicy()).
-
- \sa focusOutEvent(), setFocusPolicy(), keyPressEvent(),
- keyReleaseEvent(), event(), QFocusEvent
-*/
-
-void QWidget::focusInEvent(QFocusEvent *)
-{
- if (focusPolicy() != Qt::NoFocus || !isWindow()) {
- update();
- }
-}
-
-/*!
- \fn void QWidget::focusOutEvent(QFocusEvent *event)
-
- This event handler can be reimplemented in a subclass to receive
- keyboard focus events (focus lost) for the widget. The events is
- passed in the \a event parameter.
-
- A widget normally must setFocusPolicy() to something other than
- Qt::NoFocus in order to receive focus events. (Note that the
- application programmer can call setFocus() on any widget, even
- those that do not normally accept focus.)
-
- The default implementation updates the widget (except for windows
- that do not specify a focusPolicy()).
-
- \sa focusInEvent(), setFocusPolicy(), keyPressEvent(),
- keyReleaseEvent(), event(), QFocusEvent
-*/
-
-void QWidget::focusOutEvent(QFocusEvent *)
-{
- if (focusPolicy() != Qt::NoFocus || !isWindow())
- update();
-}
-
-/*!
- \fn void QWidget::enterEvent(QEvent *event)
-
- This event handler can be reimplemented in a subclass to receive
- widget enter events which are passed in the \a event parameter.
-
- An event is sent to the widget when the mouse cursor enters the
- widget.
-
- \sa leaveEvent(), mouseMoveEvent(), event()
-*/
-
-void QWidget::enterEvent(QEvent *)
-{
-}
-
-/*!
- \fn void QWidget::leaveEvent(QEvent *event)
-
- This event handler can be reimplemented in a subclass to receive
- widget leave events which are passed in the \a event parameter.
-
- A leave event is sent to the widget when the mouse cursor leaves
- the widget.
-
- \sa enterEvent(), mouseMoveEvent(), event()
-*/
-
-void QWidget::leaveEvent(QEvent *)
-{
-}
-
-/*!
- \fn void QWidget::paintEvent(QPaintEvent *event)
-
- This event handler can be reimplemented in a subclass to receive paint
- events passed in \a event.
-
- A paint event is a request to repaint all or part of a widget. It can
- happen for one of the following reasons:
-
- \list
- \o repaint() or update() was invoked,
- \o the widget was obscured and has now been uncovered, or
- \o many other reasons.
- \endlist
-
- Many widgets can simply repaint their entire surface when asked to, but
- some slow widgets need to optimize by painting only the requested region:
- QPaintEvent::region(). This speed optimization does not change the result,
- as painting is clipped to that region during event processing. QListView
- and QTableView do this, for example.
-
- Qt also tries to speed up painting by merging multiple paint events into
- one. When update() is called several times or the window system sends
- several paint events, Qt merges these events into one event with a larger
- region (see QRegion::united()). The repaint() function does not permit this
- optimization, so we suggest using update() whenever possible.
-
- When the paint event occurs, the update region has normally been erased, so
- you are painting on the widget's background.
-
- The background can be set using setBackgroundRole() and setPalette().
-
- Since Qt 4.0, QWidget automatically double-buffers its painting, so there
- is no need to write double-buffering code in paintEvent() to avoid flicker.
-
- \bold{Note for the X11 platform}: It is possible to toggle global double
- buffering by calling \c qt_x11_set_global_double_buffer(). For example,
-
- \snippet doc/src/snippets/code/src_gui_kernel_qwidget.cpp 14
-
- \note Generally, you should refrain from calling update() or repaint()
- \bold{inside} a paintEvent(). For example, calling update() or repaint() on
- children inside a paintevent() results in undefined behavior; the child may
- or may not get a paint event.
-
- \warning If you are using a custom paint engine without Qt's backingstore,
- Qt::WA_PaintOnScreen must be set. Otherwise, QWidget::paintEngine() will
- never be called; the backingstore will be used instead.
-
- \sa event(), repaint(), update(), QPainter, QPixmap, QPaintEvent,
- {Analog Clock Example}
-*/
-
-void QWidget::paintEvent(QPaintEvent *)
-{
-}
-
-
-/*!
- \fn void QWidget::moveEvent(QMoveEvent *event)
-
- This event handler can be reimplemented in a subclass to receive
- widget move events which are passed in the \a event parameter.
- When the widget receives this event, it is already at the new
- position.
-
- The old position is accessible through QMoveEvent::oldPos().
-
- \sa resizeEvent(), event(), move(), QMoveEvent
-*/
-
-void QWidget::moveEvent(QMoveEvent *)
-{
-}
-
-
-/*!
- This event handler can be reimplemented in a subclass to receive
- widget resize events which are passed in the \a event parameter.
- When resizeEvent() is called, the widget already has its new
- geometry. The old size is accessible through
- QResizeEvent::oldSize().
-
- The widget will be erased and receive a paint event immediately
- after processing the resize event. No drawing need be (or should
- be) done inside this handler.
-
-
- \sa moveEvent(), event(), resize(), QResizeEvent, paintEvent(),
- {Scribble Example}
-*/
-
-void QWidget::resizeEvent(QResizeEvent * /* event */)
-{
-}
-
-#ifndef QT_NO_ACTION
-/*!
- \fn void QWidget::actionEvent(QActionEvent *event)
-
- This event handler is called with the given \a event whenever the
- widget's actions are changed.
-
- \sa addAction(), insertAction(), removeAction(), actions(), QActionEvent
-*/
-void QWidget::actionEvent(QActionEvent *)
-{
-
-}
-#endif
-
-/*!
- This event handler is called with the given \a event when Qt receives a window
- close request for a top-level widget from the window system.
-
- By default, the event is accepted and the widget is closed. You can reimplement
- this function to change the way the widget responds to window close requests.
- For example, you can prevent the window from closing by calling \l{QEvent::}{ignore()}
- on all events.
-
- Main window applications typically use reimplementations of this function to check
- whether the user's work has been saved and ask for permission before closing.
- For example, the \l{Application Example} uses a helper function to determine whether
- or not to close the window:
-
- \snippet mainwindows/application/mainwindow.cpp 3
- \snippet mainwindows/application/mainwindow.cpp 4
-
- \sa event(), hide(), close(), QCloseEvent, {Application Example}
-*/
-
-void QWidget::closeEvent(QCloseEvent *event)
-{
- event->accept();
-}
-
-#ifndef QT_NO_CONTEXTMENU
-/*!
- This event handler, for event \a event, can be reimplemented in a
- subclass to receive widget context menu events.
-
- The handler is called when the widget's \l contextMenuPolicy is
- Qt::DefaultContextMenu.
-
- The default implementation ignores the context event.
- See the \l QContextMenuEvent documentation for more details.
-
- \sa event(), QContextMenuEvent customContextMenuRequested()
-*/
-
-void QWidget::contextMenuEvent(QContextMenuEvent *event)
-{
- event->ignore();
-}
-#endif // QT_NO_CONTEXTMENU
-
-
-/*!
- This event handler, for event \a event, can be reimplemented in a
- subclass to receive Input Method composition events. This handler
- is called when the state of the input method changes.
-
- Note that when creating custom text editing widgets, the
- Qt::WA_InputMethodEnabled window attribute must be set explicitly
- (using the setAttribute() function) in order to receive input
- method events.
-
- The default implementation calls event->ignore(), which rejects the
- Input Method event. See the \l QInputMethodEvent documentation for more
- details.
-
- \sa event(), QInputMethodEvent
-*/
-void QWidget::inputMethodEvent(QInputMethodEvent *event)
-{
- event->ignore();
-}
-
-/*!
- This method is only relevant for input widgets. It is used by the
- input method to query a set of properties of the widget to be
- able to support complex input method operations as support for
- surrounding text and reconversions.
-
- \a query specifies which property is queried.
-
- \sa inputMethodEvent(), QInputMethodEvent, QInputContext, inputMethodHints
-*/
-QVariant QWidget::inputMethodQuery(Qt::InputMethodQuery query) const
-{
- switch(query) {
- case Qt::ImMicroFocus:
- return QRect(width()/2, 0, 1, height());
- case Qt::ImFont:
- return font();
- case Qt::ImAnchorPosition:
- // Fallback.
- return inputMethodQuery(Qt::ImCursorPosition);
- default:
- return QVariant();
- }
-}
-
-/*!
- \property QWidget::inputMethodHints
- \brief What input method specific hints the widget has.
-
- This is only relevant for input widgets. It is used by
- the input method to retrieve hints as to how the input method
- should operate. For example, if the Qt::ImhFormattedNumbersOnly flag
- is set, the input method may change its visual components to reflect
- that only numbers can be entered.
-
- \note The flags are only hints, so the particular input method
- implementation is free to ignore them. If you want to be
- sure that a certain type of characters are entered,
- you should also set a QValidator on the widget.
-
- The default value is Qt::ImhNone.
-
- \since 4.6
-
- \sa inputMethodQuery(), QInputContext
-*/
-Qt::InputMethodHints QWidget::inputMethodHints() const
-{
-#ifndef QT_NO_IM
- const QWidgetPrivate *priv = d_func();
- while (priv->inheritsInputMethodHints) {
- priv = priv->q_func()->parentWidget()->d_func();
- Q_ASSERT(priv);
- }
- return priv->imHints;
-#else //QT_NO_IM
- return 0;
-#endif //QT_NO_IM
-}
-
-void QWidget::setInputMethodHints(Qt::InputMethodHints hints)
-{
-#ifndef QT_NO_IM
- Q_D(QWidget);
- d->imHints = hints;
- // Optimization to update input context only it has already been created.
- if (d->ic || qApp->d_func()->inputContext) {
- QInputContext *ic = inputContext();
- if (ic)
- ic->update();
- }
-#endif //QT_NO_IM
-}
-
-
-#ifndef QT_NO_DRAGANDDROP
-
-/*!
- \fn void QWidget::dragEnterEvent(QDragEnterEvent *event)
-
- This event handler is called when a drag is in progress and the
- mouse enters this widget. The event is passed in the \a event parameter.
-
- If the event is ignored, the widget won't receive any \l{dragMoveEvent()}{drag
- move events}.
-
- See the \link dnd.html Drag-and-drop documentation\endlink for an
- overview of how to provide drag-and-drop in your application.
-
- \sa QDrag, QDragEnterEvent
-*/
-void QWidget::dragEnterEvent(QDragEnterEvent *)
-{
-}
-
-/*!
- \fn void QWidget::dragMoveEvent(QDragMoveEvent *event)
-
- This event handler is called if a drag is in progress, and when
- any of the following conditions occur: the cursor enters this widget,
- the cursor moves within this widget, or a modifier key is pressed on
- the keyboard while this widget has the focus. The event is passed
- in the \a event parameter.
-
- See the \link dnd.html Drag-and-drop documentation\endlink for an
- overview of how to provide drag-and-drop in your application.
-
- \sa QDrag, QDragMoveEvent
-*/
-void QWidget::dragMoveEvent(QDragMoveEvent *)
-{
-}
-
-/*!
- \fn void QWidget::dragLeaveEvent(QDragLeaveEvent *event)
-
- This event handler is called when a drag is in progress and the
- mouse leaves this widget. The event is passed in the \a event
- parameter.
-
- See the \link dnd.html Drag-and-drop documentation\endlink for an
- overview of how to provide drag-and-drop in your application.
-
- \sa QDrag, QDragLeaveEvent
-*/
-void QWidget::dragLeaveEvent(QDragLeaveEvent *)
-{
-}
-
-/*!
- \fn void QWidget::dropEvent(QDropEvent *event)
-
- This event handler is called when the drag is dropped on this
- widget. The event is passed in the \a event parameter.
-
- See the \link dnd.html Drag-and-drop documentation\endlink for an
- overview of how to provide drag-and-drop in your application.
-
- \sa QDrag, QDropEvent
-*/
-void QWidget::dropEvent(QDropEvent *)
-{
-}
-
-#endif // QT_NO_DRAGANDDROP
-
-/*!
- \fn void QWidget::showEvent(QShowEvent *event)
-
- This event handler can be reimplemented in a subclass to receive
- widget show events which are passed in the \a event parameter.
-
- Non-spontaneous show events are sent to widgets immediately
- before they are shown. The spontaneous show events of windows are
- delivered afterwards.
-
- Note: A widget receives spontaneous show and hide events when its
- mapping status is changed by the window system, e.g. a spontaneous
- hide event when the user minimizes the window, and a spontaneous
- show event when the window is restored again. After receiving a
- spontaneous hide event, a widget is still considered visible in
- the sense of isVisible().
-
- \sa visible, event(), QShowEvent
-*/
-void QWidget::showEvent(QShowEvent *)
-{
-}
-
-/*!
- \fn void QWidget::hideEvent(QHideEvent *event)
-
- This event handler can be reimplemented in a subclass to receive
- widget hide events. The event is passed in the \a event parameter.
-
- Hide events are sent to widgets immediately after they have been
- hidden.
-
- Note: A widget receives spontaneous show and hide events when its
- mapping status is changed by the window system, e.g. a spontaneous
- hide event when the user minimizes the window, and a spontaneous
- show event when the window is restored again. After receiving a
- spontaneous hide event, a widget is still considered visible in
- the sense of isVisible().
-
- \sa visible, event(), QHideEvent
-*/
-void QWidget::hideEvent(QHideEvent *)
-{
-}
-
-/*
- \fn QWidget::x11Event(MSG *)
-
- This special event handler can be reimplemented in a subclass to receive
- native X11 events.
-
- In your reimplementation of this function, if you want to stop Qt from
- handling the event, return true. If you return false, this native event
- is passed back to Qt, which translates it into a Qt event and sends it to
- the widget.
-
- \note Events are only delivered to this event handler if the widget is
- native.
-
- \warning This function is not portable.
-
- \sa QApplication::x11EventFilter(), QWidget::winId()
-*/
-
-
-#if defined(Q_WS_MAC)
-
-/*!
- \fn bool QWidget::macEvent(EventHandlerCallRef caller, EventRef event)
-
- This special event handler can be reimplemented in a subclass to
- receive native Macintosh events.
-
- The parameters are a bit different depending if Qt is build against Carbon
- or Cocoa. In Carbon, \a caller and \a event are the corresponding
- EventHandlerCallRef and EventRef that correspond to the Carbon event
- handlers that are installed. In Cocoa, \a caller is always 0 and the
- EventRef is the EventRef generated from the NSEvent.
-
- In your reimplementation of this function, if you want to stop the
- event being handled by Qt, return true. If you return false, this
- native event is passed back to Qt, which translates the event into
- a Qt event and sends it to the widget.
-
- \warning This function is not portable.
-
- \warning This function was not called inside of Qt until Qt 4.4.
- If you need compatibility with earlier versions of Qt, consider QApplication::macEventFilter() instead.
-
- \sa QApplication::macEventFilter()
-*/
-
-bool QWidget::macEvent(EventHandlerCallRef, EventRef)
-{
- return false;
-}
-
-#endif
-#if defined(Q_WS_WIN)
-
-/*!
- This special event handler can be reimplemented in a subclass to
- receive native Windows events which are passed in the \a message
- parameter.
-
- In your reimplementation of this function, if you want to stop the
- event being handled by Qt, return true and set \a result to the value
- that the window procedure should return. If you return false, this
- native event is passed back to Qt, which translates the event into
- a Qt event and sends it to the widget.
-
- \warning This function is not portable.
-
- \sa QApplication::winEventFilter()
-*/
-bool QWidget::winEvent(MSG *message, long *result)
-{
- Q_UNUSED(message);
- Q_UNUSED(result);
- return false;
-}
-
-#endif
-#if defined(Q_WS_X11)
-
-/*!
- \fn bool QWidget::x11Event(XEvent *event)
-
- This special event handler can be reimplemented in a subclass to receive
- native X11 events passed in the \a event parameter.
-
- In your reimplementation of this function, if you want to stop Qt from
- handling the event, return true. If you return false, this native event
- is passed back to Qt, which translates it into a Qt event and sends it to
- the widget.
-
- \note Events are only delivered to this event handler if the widget is
- native.
-
- \warning This function is not portable.
-
- \sa QApplication::x11EventFilter(), QWidget::winId()
-*/
-bool QWidget::x11Event(XEvent *)
-{
- return false;
-}
-
-#endif
-#if defined(Q_WS_QWS)
-
-/*!
- \fn bool QWidget::qwsEvent(QWSEvent *event)
-
- This special event handler can be reimplemented in a subclass to
- receive native Qt for Embedded Linux events which are passed in the
- \a event parameter.
-
- In your reimplementation of this function, if you want to stop the
- event being handled by Qt, return true. If you return false, this
- native event is passed back to Qt, which translates the event into
- a Qt event and sends it to the widget.
-
- \warning This function is not portable.
-
- \sa QApplication::qwsEventFilter()
-*/
-bool QWidget::qwsEvent(QWSEvent *)
-{
- return false;
-}
-
-#endif
-
-
-/*!
- Ensures that the widget has been polished by QStyle (i.e., has a
- proper font and palette).
-
- QWidget calls this function after it has been fully constructed
- but before it is shown the very first time. You can call this
- function if you want to ensure that the widget is polished before
- doing an operation, e.g., the correct font size might be needed in
- the widget's sizeHint() reimplementation. Note that this function
- \e is called from the default implementation of sizeHint().
-
- Polishing is useful for final initialization that must happen after
- all constructors (from base classes as well as from subclasses)
- have been called.
-
- If you need to change some settings when a widget is polished,
- reimplement event() and handle the QEvent::Polish event type.
-
- \bold{Note:} The function is declared const so that it can be called from
- other const functions (e.g., sizeHint()).
-
- \sa event()
-*/
-void QWidget::ensurePolished() const
-{
- Q_D(const QWidget);
-
- const QMetaObject *m = metaObject();
- if (m == d->polished)
- return;
- d->polished = m;
-
- QEvent e(QEvent::Polish);
- QCoreApplication::sendEvent(const_cast<QWidget *>(this), &e);
-
- // polish children after 'this'
- QList<QObject*> children = d->children;
- for (int i = 0; i < children.size(); ++i) {
- QObject *o = children.at(i);
- if(!o->isWidgetType())
- continue;
- if (QWidget *w = qobject_cast<QWidget *>(o))
- w->ensurePolished();
- }
-
- if (d->parent && d->sendChildEvents) {
- QChildEvent e(QEvent::ChildPolished, const_cast<QWidget *>(this));
- QCoreApplication::sendEvent(d->parent, &e);
- }
-}
-
-/*!
- Returns the mask currently set on a widget. If no mask is set the
- return value will be an empty region.
-
- \sa setMask(), clearMask(), QRegion::isEmpty(), {Shaped Clock Example}
-*/
-QRegion QWidget::mask() const
-{
- Q_D(const QWidget);
- return d->extra ? d->extra->mask : QRegion();
-}
-
-/*!
- Returns the layout manager that is installed on this widget, or 0
- if no layout manager is installed.
-
- The layout manager sets the geometry of the widget's children
- that have been added to the layout.
-
- \sa setLayout(), sizePolicy(), {Layout Management}
-*/
-QLayout *QWidget::layout() const
-{
- return d_func()->layout;
-}
-
-
-/*!
- \fn void QWidget::setLayout(QLayout *layout)
-
- Sets the layout manager for this widget to \a layout.
-
- If there already is a layout manager installed on this widget,
- QWidget won't let you install another. You must first delete the
- existing layout manager (returned by layout()) before you can
- call setLayout() with the new layout.
-
- If \a layout is the layout manger on a different widget, setLayout()
- will reparent the layout and make it the layout manager for this widget.
-
- Example:
-
- \snippet examples/uitools/textfinder/textfinder.cpp 3b
-
- An alternative to calling this function is to pass this widget to
- the layout's constructor.
-
- The QWidget will take ownership of \a layout.
-
- \sa layout(), {Layout Management}
-*/
-
-void QWidget::setLayout(QLayout *l)
-{
- if (!l) {
- qWarning("QWidget::setLayout: Cannot set layout to 0");
- return;
- }
- if (layout()) {
- if (layout() != l)
- qWarning("QWidget::setLayout: Attempting to set QLayout \"%s\" on %s \"%s\", which already has a"
- " layout", l->objectName().toLocal8Bit().data(), metaObject()->className(),
- objectName().toLocal8Bit().data());
- return;
- }
-
- QObject *oldParent = l->parent();
- if (oldParent && oldParent != this) {
- if (oldParent->isWidgetType()) {
- // Steal the layout off a widget parent. Takes effect when
- // morphing laid-out container widgets in Designer.
- QWidget *oldParentWidget = static_cast<QWidget *>(oldParent);
- oldParentWidget->takeLayout();
- } else {
- qWarning("QWidget::setLayout: Attempting to set QLayout \"%s\" on %s \"%s\", when the QLayout already has a parent",
- l->objectName().toLocal8Bit().data(), metaObject()->className(),
- objectName().toLocal8Bit().data());
- return;
- }
- }
-
- Q_D(QWidget);
- l->d_func()->topLevel = true;
- d->layout = l;
- if (oldParent != this) {
- l->setParent(this);
- l->d_func()->reparentChildWidgets(this);
- l->invalidate();
- }
-
- if (isWindow() && d->maybeTopData())
- d->topData()->sizeAdjusted = false;
-}
-
-/*!
- \fn QLayout *QWidget::takeLayout()
-
- Remove the layout from the widget.
- \since 4.5
-*/
-
-QLayout *QWidget::takeLayout()
-{
- Q_D(QWidget);
- QLayout *l = layout();
- if (!l)
- return 0;
- d->layout = 0;
- l->setParent(0);
- return l;
-}
-
-/*!
- \property QWidget::sizePolicy
- \brief the default layout behavior of the widget
-
- If there is a QLayout that manages this widget's children, the
- size policy specified by that layout is used. If there is no such
- QLayout, the result of this function is used.
-
- The default policy is Preferred/Preferred, which means that the
- widget can be freely resized, but prefers to be the size
- sizeHint() returns. Button-like widgets set the size policy to
- specify that they may stretch horizontally, but are fixed
- vertically. The same applies to lineedit controls (such as
- QLineEdit, QSpinBox or an editable QComboBox) and other
- horizontally orientated widgets (such as QProgressBar).
- QToolButton's are normally square, so they allow growth in both
- directions. Widgets that support different directions (such as
- QSlider, QScrollBar or QHeader) specify stretching in the
- respective direction only. Widgets that can provide scroll bars
- (usually subclasses of QScrollArea) tend to specify that they can
- use additional space, and that they can make do with less than
- sizeHint().
-
- \sa sizeHint() QLayout QSizePolicy updateGeometry()
-*/
-QSizePolicy QWidget::sizePolicy() const
-{
- Q_D(const QWidget);
- return d->size_policy;
-}
-
-void QWidget::setSizePolicy(QSizePolicy policy)
-{
- Q_D(QWidget);
- setAttribute(Qt::WA_WState_OwnSizePolicy);
- if (policy == d->size_policy)
- return;
- d->size_policy = policy;
-
-#ifndef QT_NO_GRAPHICSVIEW
- if (QWExtra *extra = d->extra) {
- if (extra->proxyWidget)
- extra->proxyWidget->setSizePolicy(policy);
- }
-#endif
-
- updateGeometry();
-
- if (isWindow() && d->maybeTopData())
- d->topData()->sizeAdjusted = false;
-}
-
-/*!
- \fn void QWidget::setSizePolicy(QSizePolicy::Policy horizontal, QSizePolicy::Policy vertical)
- \overload
-
- Sets the size policy of the widget to \a horizontal and \a
- vertical, with standard stretch and no height-for-width.
-
- \sa QSizePolicy::QSizePolicy()
-*/
-
-/*!
- Returns the preferred height for this widget, given the width \a w.
-
- If this widget has a layout, the default implementation returns
- the layout's preferred height. if there is no layout, the default
- implementation returns -1 indicating that the preferred height
- does not depend on the width.
-*/
-
-int QWidget::heightForWidth(int w) const
-{
- if (layout() && layout()->hasHeightForWidth())
- return layout()->totalHeightForWidth(w);
- return -1;
-}
-
-
-/*!
- \internal
-
- *virtual private*
-
- This is a bit hackish, but ideally we would have created a virtual function
- in the public API (however, too late...) so that subclasses could reimplement
- their own function.
- Instead we add a virtual function to QWidgetPrivate.
- ### Qt5: move to public class and make virtual
-*/
-bool QWidgetPrivate::hasHeightForWidth() const
-{
- return layout ? layout->hasHeightForWidth() : size_policy.hasHeightForWidth();
-}
-
-/*!
- \fn QWidget *QWidget::childAt(int x, int y) const
-
- Returns the visible child widget at the position (\a{x}, \a{y})
- in the widget's coordinate system. If there is no visible child
- widget at the specified position, the function returns 0.
-*/
-
-/*!
- \overload
-
- Returns the visible child widget at point \a p in the widget's own
- coordinate system.
-*/
-
-QWidget *QWidget::childAt(const QPoint &p) const
-{
- return d_func()->childAt_helper(p, false);
-}
-
-QWidget *QWidgetPrivate::childAt_helper(const QPoint &p, bool ignoreChildrenInDestructor) const
-{
- if (children.isEmpty())
- return 0;
-
-#ifdef Q_WS_MAC
- Q_Q(const QWidget);
- // Unified tool bars on the Mac require special handling since they live outside
- // QMainWindow's geometry(). See commit: 35667fd45ada49269a5987c235fdedfc43e92bb8
- bool includeFrame = q->isWindow() && qobject_cast<const QMainWindow *>(q)
- && static_cast<const QMainWindow *>(q)->unifiedTitleAndToolBarOnMac();
- if (includeFrame)
- return childAtRecursiveHelper(p, ignoreChildrenInDestructor, includeFrame);
-#endif
-
- if (!pointInsideRectAndMask(p))
- return 0;
- return childAtRecursiveHelper(p, ignoreChildrenInDestructor);
-}
-
-QWidget *QWidgetPrivate::childAtRecursiveHelper(const QPoint &p, bool ignoreChildrenInDestructor, bool includeFrame) const
-{
-#ifndef Q_WS_MAC
- Q_UNUSED(includeFrame);
-#endif
- for (int i = children.size() - 1; i >= 0; --i) {
- QWidget *child = qobject_cast<QWidget *>(children.at(i));
- if (!child || child->isWindow() || child->isHidden() || child->testAttribute(Qt::WA_TransparentForMouseEvents)
- || (ignoreChildrenInDestructor && child->data->in_destructor)) {
- continue;
- }
-
- // Map the point 'p' from parent coordinates to child coordinates.
- QPoint childPoint = p;
-#ifdef Q_WS_MAC
- // 'includeFrame' is true if the child's parent is a top-level QMainWindow with an unified tool bar.
- // An unified tool bar on the Mac lives outside QMainWindow's geometry(), so a normal
- // QWidget::mapFromParent won't do the trick.
- if (includeFrame && qobject_cast<QToolBar *>(child))
- childPoint = qt_mac_nativeMapFromParent(child, p);
- else
-#endif
- childPoint -= child->data->crect.topLeft();
-
- // Check if the point hits the child.
- if (!child->d_func()->pointInsideRectAndMask(childPoint))
- continue;
-
- // Do the same for the child's descendants.
- if (QWidget *w = child->d_func()->childAtRecursiveHelper(childPoint, ignoreChildrenInDestructor))
- return w;
-
- // We have found our target; namely the child at position 'p'.
- return child;
- }
- return 0;
-}
-
-void QWidgetPrivate::updateGeometry_helper(bool forceUpdate)
-{
- Q_Q(QWidget);
- if (widgetItem)
- widgetItem->invalidateSizeCache();
- QWidget *parent;
- if (forceUpdate || !extra || extra->minw != extra->maxw || extra->minh != extra->maxh) {
- if (!q->isWindow() && !q->isHidden() && (parent = q->parentWidget())) {
- if (parent->d_func()->layout)
- parent->d_func()->layout->invalidate();
- else if (parent->isVisible())
- QApplication::postEvent(parent, new QEvent(QEvent::LayoutRequest));
- }
- }
-}
-
-/*!
- Notifies the layout system that this widget has changed and may
- need to change geometry.
-
- Call this function if the sizeHint() or sizePolicy() have changed.
-
- For explicitly hidden widgets, updateGeometry() is a no-op. The
- layout system will be notified as soon as the widget is shown.
-*/
-
-void QWidget::updateGeometry()
-{
- Q_D(QWidget);
- d->updateGeometry_helper(false);
-}
-
-/*! \property QWidget::windowFlags
-
- Window flags are a combination of a type (e.g. Qt::Dialog) and
- zero or more hints to the window system (e.g.
- Qt::FramelessWindowHint).
-
- If the widget had type Qt::Widget or Qt::SubWindow and becomes a
- window (Qt::Window, Qt::Dialog, etc.), it is put at position (0,
- 0) on the desktop. If the widget is a window and becomes a
- Qt::Widget or Qt::SubWindow, it is put at position (0, 0)
- relative to its parent widget.
-
- \note This function calls setParent() when changing the flags for
- a window, causing the widget to be hidden. You must call show() to make
- the widget visible again..
-
- \sa windowType(), {Window Flags Example}
-*/
-void QWidget::setWindowFlags(Qt::WindowFlags flags)
-{
- if (data->window_flags == flags)
- return;
-
- Q_D(QWidget);
-
- if ((data->window_flags | flags) & Qt::Window) {
- // the old type was a window and/or the new type is a window
- QPoint oldPos = pos();
- bool visible = isVisible();
- setParent(parentWidget(), flags);
-
- // if both types are windows or neither of them are, we restore
- // the old position
- if (!((data->window_flags ^ flags) & Qt::Window)
- && (visible || testAttribute(Qt::WA_Moved))) {
- move(oldPos);
- }
- // for backward-compatibility we change Qt::WA_QuitOnClose attribute value only when the window was recreated.
- d->adjustQuitOnCloseAttribute();
- } else {
- data->window_flags = flags;
- }
-}
-
-/*!
- Sets the window flags for the widget to \a flags,
- \e without telling the window system.
-
- \warning Do not call this function unless you really know what
- you're doing.
-
- \sa setWindowFlags()
-*/
-void QWidget::overrideWindowFlags(Qt::WindowFlags flags)
-{
- data->window_flags = flags;
-}
-
-/*!
- \fn Qt::WindowType QWidget::windowType() const
-
- Returns the window type of this widget. This is identical to
- windowFlags() & Qt::WindowType_Mask.
-
- \sa windowFlags
-*/
-
-/*!
- Sets the parent of the widget to \a parent, and resets the window
- flags. The widget is moved to position (0, 0) in its new parent.
-
- If the new parent widget is in a different window, the
- reparented widget and its children are appended to the end of the
- \l{setFocusPolicy()}{tab chain} of the new parent
- widget, in the same internal order as before. If one of the moved
- widgets had keyboard focus, setParent() calls clearFocus() for that
- widget.
-
- If the new parent widget is in the same window as the
- old parent, setting the parent doesn't change the tab order or
- keyboard focus.
-
- If the "new" parent widget is the old parent widget, this function
- does nothing.
-
- \note The widget becomes invisible as part of changing its parent,
- even if it was previously visible. You must call show() to make the
- widget visible again.
-
- \warning It is very unlikely that you will ever need this
- function. If you have a widget that changes its content
- dynamically, it is far easier to use \l QStackedWidget.
-
- \sa setWindowFlags()
-*/
-void QWidget::setParent(QWidget *parent)
-{
- if (parent == parentWidget())
- return;
- setParent((QWidget*)parent, windowFlags() & ~Qt::WindowType_Mask);
-}
-
-/*!
- \overload
-
- This function also takes widget flags, \a f as an argument.
-*/
-
-void QWidget::setParent(QWidget *parent, Qt::WindowFlags f)
-{
- Q_D(QWidget);
- d->inSetParent = true;
- bool resized = testAttribute(Qt::WA_Resized);
- bool wasCreated = testAttribute(Qt::WA_WState_Created);
- QWidget *oldtlw = window();
-
- QWidget *desktopWidget = 0;
- if (parent && parent->windowType() == Qt::Desktop)
- desktopWidget = parent;
- bool newParent = (parent != parentWidget()) || !wasCreated || desktopWidget;
-
-#if defined(Q_WS_X11) || defined(Q_WS_WIN) || defined(Q_WS_MAC) || defined(Q_OS_SYMBIAN)
- if (newParent && parent && !desktopWidget) {
- if (testAttribute(Qt::WA_NativeWindow) && !qApp->testAttribute(Qt::AA_DontCreateNativeWidgetSiblings)
-#if defined(Q_WS_MAC) && defined(QT_MAC_USE_COCOA)
- // On Mac, toolbars inside the unified title bar will never overlap with
- // siblings in the content view. So we skip enforce native siblings in that case
- && !d->isInUnifiedToolbar && parentWidget() && parentWidget()->isWindow()
-#endif // Q_WS_MAC && QT_MAC_USE_COCOA
- )
- parent->d_func()->enforceNativeChildren();
- else if (parent->d_func()->nativeChildrenForced() || parent->testAttribute(Qt::WA_PaintOnScreen))
- setAttribute(Qt::WA_NativeWindow);
- }
-#endif
-
- if (wasCreated) {
- if (!testAttribute(Qt::WA_WState_Hidden)) {
- hide();
- setAttribute(Qt::WA_WState_ExplicitShowHide, false);
- }
- if (newParent) {
- QEvent e(QEvent::ParentAboutToChange);
- QApplication::sendEvent(this, &e);
- }
- }
- if (newParent && isAncestorOf(focusWidget()))
- focusWidget()->clearFocus();
-
- QTLWExtra *oldTopExtra = window()->d_func()->maybeTopData();
- QWidgetBackingStoreTracker *oldBsTracker = oldTopExtra ? &oldTopExtra->backingStore : 0;
-
- d->setParent_sys(parent, f);
-
- QTLWExtra *topExtra = window()->d_func()->maybeTopData();
- QWidgetBackingStoreTracker *bsTracker = topExtra ? &topExtra->backingStore : 0;
- if (oldBsTracker && oldBsTracker != bsTracker)
- oldBsTracker->unregisterWidgetSubtree(this);
-
- if (desktopWidget)
- parent = 0;
-
-#ifdef Q_BACKINGSTORE_SUBSURFACES
- QTLWExtra *extra = d->maybeTopData();
- QWindowSurface *windowSurface = (extra ? extra->windowSurface : 0);
- if (newParent && windowSurface) {
- QWidgetBackingStore *oldBs = oldtlw->d_func()->maybeBackingStore();
- if (oldBs)
- oldBs->subSurfaces.removeAll(windowSurface);
-
- if (parent) {
- QWidgetBackingStore *newBs = parent->d_func()->maybeBackingStore();
- if (newBs)
- newBs->subSurfaces.append(windowSurface);
- }
- }
-#endif
-
- if (QWidgetBackingStore *oldBs = oldtlw->d_func()->maybeBackingStore()) {
- if (newParent)
- oldBs->removeDirtyWidget(this);
- // Move the widget and all its static children from
- // the old backing store to the new one.
- oldBs->moveStaticWidgets(this);
- }
-
- if ((QApplicationPrivate::app_compile_version < 0x040200
- || QApplicationPrivate::testAttribute(Qt::AA_ImmediateWidgetCreation))
- && !testAttribute(Qt::WA_WState_Created))
- create();
-
- d->reparentFocusWidgets(oldtlw);
- setAttribute(Qt::WA_Resized, resized);
- if (!testAttribute(Qt::WA_StyleSheet)
- && (!parent || !parent->testAttribute(Qt::WA_StyleSheet))) {
- d->resolveFont();
- d->resolvePalette();
- }
- d->resolveLayoutDirection();
- d->resolveLocale();
-
- // Note: GL widgets under WGL or EGL will always need a ParentChange
- // event to handle recreation/rebinding of the GL context, hence the
- // (f & Qt::MSWindowsOwnDC) clause (which is set on QGLWidgets on all
- // platforms).
- if (newParent
-#if defined(Q_WS_WIN) || defined(QT_OPENGL_ES)
- || (f & Qt::MSWindowsOwnDC)
-#endif
- ) {
- // propagate enabled updates enabled state to non-windows
- if (!isWindow()) {
- if (!testAttribute(Qt::WA_ForceDisabled))
- d->setEnabled_helper(parent ? parent->isEnabled() : true);
- if (!testAttribute(Qt::WA_ForceUpdatesDisabled))
- d->setUpdatesEnabled_helper(parent ? parent->updatesEnabled() : true);
- }
- d->inheritStyle();
-
- // send and post remaining QObject events
- if (parent && d->sendChildEvents) {
- QChildEvent e(QEvent::ChildAdded, this);
- QApplication::sendEvent(parent, &e);
-#ifdef QT3_SUPPORT
- if (parent->d_func()->pendingChildInsertedEvents.isEmpty()) {
- QApplication::postEvent(parent,
- new QEvent(QEvent::ChildInsertedRequest),
- Qt::HighEventPriority);
- }
- parent->d_func()->pendingChildInsertedEvents.append(this);
-#endif
- }
-
-//### already hidden above ---> must probably do something smart on the mac
-// #ifdef Q_WS_MAC
-// extern bool qt_mac_is_macdrawer(const QWidget *); //qwidget_mac.cpp
-// if(!qt_mac_is_macdrawer(q)) //special case
-// q->setAttribute(Qt::WA_WState_Hidden);
-// #else
-// q->setAttribute(Qt::WA_WState_Hidden);
-//#endif
-
- if (parent && d->sendChildEvents && d->polished) {
- QChildEvent e(QEvent::ChildPolished, this);
- QCoreApplication::sendEvent(parent, &e);
- }
-
- QEvent e(QEvent::ParentChange);
- QApplication::sendEvent(this, &e);
- }
-
- if (!wasCreated) {
- if (isWindow() || parentWidget()->isVisible())
- setAttribute(Qt::WA_WState_Hidden, true);
- else if (!testAttribute(Qt::WA_WState_ExplicitShowHide))
- setAttribute(Qt::WA_WState_Hidden, false);
- }
-
- d->updateIsOpaque();
-
-#ifndef QT_NO_GRAPHICSVIEW
- // Embed the widget into a proxy if the parent is embedded.
- // ### Doesn't handle reparenting out of an embedded widget.
- if (oldtlw->graphicsProxyWidget()) {
- if (QGraphicsProxyWidget *ancestorProxy = d->nearestGraphicsProxyWidget(oldtlw))
- ancestorProxy->d_func()->unembedSubWindow(this);
- }
- if (isWindow() && parent && !graphicsProxyWidget() && !bypassGraphicsProxyWidget(this)) {
- if (QGraphicsProxyWidget *ancestorProxy = d->nearestGraphicsProxyWidget(parent))
- ancestorProxy->d_func()->embedSubWindow(this);
- }
-#endif
-
- d->inSetParent = false;
-}
-
-/*!
- Scrolls the widget including its children \a dx pixels to the
- right and \a dy downward. Both \a dx and \a dy may be negative.
-
- After scrolling, the widgets will receive paint events for
- the areas that need to be repainted. For widgets that Qt knows to
- be opaque, this is only the newly exposed parts.
- For example, if an opaque widget is scrolled 8 pixels to the left,
- only an 8-pixel wide stripe at the right edge needs updating.
-
- Since widgets propagate the contents of their parents by default,
- you need to set the \l autoFillBackground property, or use
- setAttribute() to set the Qt::WA_OpaquePaintEvent attribute, to make
- a widget opaque.
-
- For widgets that use contents propagation, a scroll will cause an
- update of the entire scroll area.
-
- \sa {Transparency and Double Buffering}
-*/
-
-void QWidget::scroll(int dx, int dy)
-{
- if ((!updatesEnabled() && children().size() == 0) || !isVisible())
- return;
- if (dx == 0 && dy == 0)
- return;
- Q_D(QWidget);
-#ifndef QT_NO_GRAPHICSVIEW
- if (QGraphicsProxyWidget *proxy = QWidgetPrivate::nearestGraphicsProxyWidget(this)) {
- // Graphics View maintains its own dirty region as a list of rects;
- // until we can connect item updates directly to the view, we must
- // separately add a translated dirty region.
- if (!d->dirty.isEmpty()) {
- foreach (const QRect &rect, (d->dirty.translated(dx, dy)).rects())
- proxy->update(rect);
- }
- proxy->scroll(dx, dy, proxy->subWidgetRect(this));
- return;
- }
-#endif
- d->setDirtyOpaqueRegion();
- d->scroll_sys(dx, dy);
-}
-
-/*!
- \overload
-
- This version only scrolls \a r and does not move the children of
- the widget.
-
- If \a r is empty or invalid, the result is undefined.
-
- \sa QScrollArea
-*/
-void QWidget::scroll(int dx, int dy, const QRect &r)
-{
-
- if ((!updatesEnabled() && children().size() == 0) || !isVisible())
- return;
- if (dx == 0 && dy == 0)
- return;
- Q_D(QWidget);
-#ifndef QT_NO_GRAPHICSVIEW
- if (QGraphicsProxyWidget *proxy = QWidgetPrivate::nearestGraphicsProxyWidget(this)) {
- // Graphics View maintains its own dirty region as a list of rects;
- // until we can connect item updates directly to the view, we must
- // separately add a translated dirty region.
- if (!d->dirty.isEmpty()) {
- foreach (const QRect &rect, (d->dirty.translated(dx, dy) & r).rects())
- proxy->update(rect);
- }
- proxy->scroll(dx, dy, r.translated(proxy->subWidgetRect(this).topLeft().toPoint()));
- return;
- }
-#endif
- d->scroll_sys(dx, dy, r);
-}
-
-/*!
- Repaints the widget directly by calling paintEvent() immediately,
- unless updates are disabled or the widget is hidden.
-
- We suggest only using repaint() if you need an immediate repaint,
- for example during animation. In almost all circumstances update()
- is better, as it permits Qt to optimize for speed and minimize
- flicker.
-
- \warning If you call repaint() in a function which may itself be
- called from paintEvent(), you may get infinite recursion. The
- update() function never causes recursion.
-
- \sa update(), paintEvent(), setUpdatesEnabled()
-*/
-
-void QWidget::repaint()
-{
- repaint(rect());
-}
-
-/*! \overload
-
- This version repaints a rectangle (\a x, \a y, \a w, \a h) inside
- the widget.
-
- If \a w is negative, it is replaced with \c{width() - x}, and if
- \a h is negative, it is replaced width \c{height() - y}.
-*/
-void QWidget::repaint(int x, int y, int w, int h)
-{
- if (x > data->crect.width() || y > data->crect.height())
- return;
-
- if (w < 0)
- w = data->crect.width() - x;
- if (h < 0)
- h = data->crect.height() - y;
-
- repaint(QRect(x, y, w, h));
-}
-
-/*! \overload
-
- This version repaints a rectangle \a rect inside the widget.
-*/
-void QWidget::repaint(const QRect &rect)
-{
- Q_D(QWidget);
-
- if (testAttribute(Qt::WA_WState_ConfigPending)) {
- update(rect);
- return;
- }
-
- if (!isVisible() || !updatesEnabled() || rect.isEmpty())
- return;
-
- if (hasBackingStoreSupport()) {
-#ifdef QT_MAC_USE_COCOA
- if (qt_widget_private(this)->isInUnifiedToolbar) {
- qt_widget_private(this)->unifiedSurface->renderToolbar(this, true);
- return;
- }
-#endif // QT_MAC_USE_COCOA
- 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);
- }
-}
-
-/*!
- \overload
-
- This version repaints a region \a rgn inside the widget.
-*/
-void QWidget::repaint(const QRegion &rgn)
-{
- Q_D(QWidget);
-
- if (testAttribute(Qt::WA_WState_ConfigPending)) {
- update(rgn);
- return;
- }
-
- if (!isVisible() || !updatesEnabled() || rgn.isEmpty())
- return;
-
- if (hasBackingStoreSupport()) {
-#ifdef QT_MAC_USE_COCOA
- if (qt_widget_private(this)->isInUnifiedToolbar) {
- qt_widget_private(this)->unifiedSurface->renderToolbar(this, true);
- return;
- }
-#endif // QT_MAC_USE_COCOA
- 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);
- }
-}
-
-/*!
- Updates the widget unless updates are disabled or the widget is
- hidden.
-
- This function does not cause an immediate repaint; instead it
- schedules a paint event for processing when Qt returns to the main
- event loop. This permits Qt to optimize for more speed and less
- flicker than a call to repaint() does.
-
- Calling update() several times normally results in just one
- paintEvent() call.
-
- Qt normally erases the widget's area before the paintEvent() call.
- If the Qt::WA_OpaquePaintEvent widget attribute is set, the widget is
- responsible for painting all its pixels with an opaque color.
-
- \sa repaint() paintEvent(), setUpdatesEnabled(), {Analog Clock Example}
-*/
-void QWidget::update()
-{
- update(rect());
-}
-
-/*! \fn void QWidget::update(int x, int y, int w, int h)
- \overload
-
- This version updates a rectangle (\a x, \a y, \a w, \a h) inside
- the widget.
-*/
-
-/*!
- \overload
-
- This version updates a rectangle \a rect inside the widget.
-*/
-void QWidget::update(const QRect &rect)
-{
- if (!isVisible() || !updatesEnabled() || rect.isEmpty())
- return;
-
- if (testAttribute(Qt::WA_WState_InPaintEvent)) {
- QApplication::postEvent(this, new QUpdateLaterEvent(rect));
- return;
- }
-
- if (hasBackingStoreSupport()) {
-#ifdef QT_MAC_USE_COCOA
- if (qt_widget_private(this)->isInUnifiedToolbar) {
- qt_widget_private(this)->unifiedSurface->renderToolbar(this, true);
- return;
- }
-#endif // QT_MAC_USE_COCOA
- QTLWExtra *tlwExtra = window()->d_func()->maybeTopData();
- if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore)
- tlwExtra->backingStore->markDirty(rect, this);
- } else {
- d_func()->repaint_sys(rect);
- }
-}
-
-/*!
- \overload
-
- This version repaints a region \a rgn inside the widget.
-*/
-void QWidget::update(const QRegion &rgn)
-{
- if (!isVisible() || !updatesEnabled() || rgn.isEmpty())
- return;
-
- if (testAttribute(Qt::WA_WState_InPaintEvent)) {
- QApplication::postEvent(this, new QUpdateLaterEvent(rgn));
- return;
- }
-
- if (hasBackingStoreSupport()) {
-#ifdef QT_MAC_USE_COCOA
- if (qt_widget_private(this)->isInUnifiedToolbar) {
- qt_widget_private(this)->unifiedSurface->renderToolbar(this, true);
- return;
- }
-#endif // QT_MAC_USE_COCOA
- QTLWExtra *tlwExtra = window()->d_func()->maybeTopData();
- if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore)
- tlwExtra->backingStore->markDirty(rgn, this);
- } else {
- d_func()->repaint_sys(rgn);
- }
-}
-
-#ifdef QT3_SUPPORT
-/*!
- Clear the rectangle at point (\a x, \a y) of width \a w and height
- \a h.
-
- \warning This is best done in a paintEvent().
-*/
-void QWidget::erase_helper(int x, int y, int w, int h)
-{
- if (testAttribute(Qt::WA_NoSystemBackground) || testAttribute(Qt::WA_UpdatesDisabled) || !testAttribute(Qt::WA_WState_Visible))
- return;
- if (w < 0)
- w = data->crect.width() - x;
- if (h < 0)
- h = data->crect.height() - y;
- if (w != 0 && h != 0) {
- QPainter p(this);
- p.eraseRect(QRect(x, y, w, h));
- }
-}
-
-/*!
- \overload
-
- Clear the given region, \a rgn.
-
- Drawing may only take place in a QPaintEvent. Overload
- paintEvent() to do your erasing and call update() to schedule a
- replaint whenever necessary. See also QPainter.
-*/
-void QWidget::erase(const QRegion& rgn)
-{
- if (testAttribute(Qt::WA_NoSystemBackground) || testAttribute(Qt::WA_UpdatesDisabled) || !testAttribute(Qt::WA_WState_Visible))
- return;
-
- QPainter p(this);
- p.setClipRegion(rgn);
- p.eraseRect(rgn.boundingRect());
-}
-
-void QWidget::drawText_helper(int x, int y, const QString &str)
-{
- if(!testAttribute(Qt::WA_WState_Visible))
- return;
- QPainter paint(this);
- paint.drawText(x, y, str);
-}
-
-
-/*!
- Closes the widget.
-
- Use the no-argument overload instead.
-*/
-bool QWidget::close(bool alsoDelete)
-{
- QPointer<QWidget> that = this;
- bool accepted = close();
- if (alsoDelete && accepted && that)
- deleteLater();
- return accepted;
-}
-
-void QWidget::setIcon(const QPixmap &i)
-{
- setWindowIcon(i);
-}
-
-/*!
- Return's the widget's icon.
-
- Use windowIcon() instead.
-*/
-const QPixmap *QWidget::icon() const
-{
- Q_D(const QWidget);
- return (d->extra && d->extra->topextra) ? d->extra->topextra->iconPixmap : 0;
-}
-
-#endif // QT3_SUPPORT
-
- /*!
- \internal
-
- This just sets the corresponding attribute bit to 1 or 0
- */
-static void setAttribute_internal(Qt::WidgetAttribute attribute, bool on, QWidgetData *data,
- QWidgetPrivate *d)
-{
- if (attribute < int(8*sizeof(uint))) {
- if (on)
- data->widget_attributes |= (1<<attribute);
- else
- data->widget_attributes &= ~(1<<attribute);
- } else {
- const int x = attribute - 8*sizeof(uint);
- const int int_off = x / (8*sizeof(uint));
- if (on)
- d->high_attributes[int_off] |= (1<<(x-(int_off*8*sizeof(uint))));
- else
- d->high_attributes[int_off] &= ~(1<<(x-(int_off*8*sizeof(uint))));
- }
-}
-
-/*!
- Sets the attribute \a attribute on this widget if \a on is true;
- otherwise clears the attribute.
-
- \sa testAttribute()
-*/
-void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on)
-{
- if (testAttribute(attribute) == on)
- return;
-
- Q_D(QWidget);
- Q_ASSERT_X(sizeof(d->high_attributes)*8 >= (Qt::WA_AttributeCount - sizeof(uint)*8),
- "QWidget::setAttribute(WidgetAttribute, bool)",
- "QWidgetPrivate::high_attributes[] too small to contain all attributes in WidgetAttribute");
-#ifdef Q_WS_WIN
- // ### Don't use PaintOnScreen+paintEngine() to do native painting in 5.0
- if (attribute == Qt::WA_PaintOnScreen && on && !inherits("QGLWidget")) {
- // see qwidget_win.cpp, ::paintEngine for details
- paintEngine();
- if (d->noPaintOnScreen)
- return;
- }
-#endif
-
- setAttribute_internal(attribute, on, data, d);
-
- switch (attribute) {
-
-#ifndef QT_NO_DRAGANDDROP
- case Qt::WA_AcceptDrops: {
- if (on && !testAttribute(Qt::WA_DropSiteRegistered))
- setAttribute(Qt::WA_DropSiteRegistered, true);
- else if (!on && (isWindow() || !parentWidget() || !parentWidget()->testAttribute(Qt::WA_DropSiteRegistered)))
- setAttribute(Qt::WA_DropSiteRegistered, false);
- QEvent e(QEvent::AcceptDropsChange);
- QApplication::sendEvent(this, &e);
- break;
- }
- case Qt::WA_DropSiteRegistered: {
- d->registerDropSite(on);
- for (int i = 0; i < d->children.size(); ++i) {
- QWidget *w = qobject_cast<QWidget *>(d->children.at(i));
- if (w && !w->isWindow() && !w->testAttribute(Qt::WA_AcceptDrops) && w->testAttribute(Qt::WA_DropSiteRegistered) != on)
- w->setAttribute(Qt::WA_DropSiteRegistered, on);
- }
- break;
- }
-#endif
-
- case Qt::WA_NoChildEventsForParent:
- d->sendChildEvents = !on;
- break;
- case Qt::WA_NoChildEventsFromChildren:
- d->receiveChildEvents = !on;
- break;
- case Qt::WA_MacBrushedMetal:
-#ifdef Q_WS_MAC
- d->setStyle_helper(style(), false, true); // Make sure things get unpolished/polished correctly.
- // fall through since changing the metal attribute affects the opaque size grip.
- case Qt::WA_MacOpaqueSizeGrip:
- d->macUpdateOpaqueSizeGrip();
- break;
- case Qt::WA_MacShowFocusRect:
- if (hasFocus()) {
- clearFocus();
- setFocus();
- }
- break;
- case Qt::WA_Hover:
- qt_mac_update_mouseTracking(this);
- break;
-#endif
- case Qt::WA_MacAlwaysShowToolWindow:
-#ifdef Q_WS_MAC
- d->macUpdateHideOnSuspend();
-#endif
- break;
- case Qt::WA_MacNormalSize:
- case Qt::WA_MacSmallSize:
- case Qt::WA_MacMiniSize:
-#ifdef Q_WS_MAC
- {
- // We can only have one of these set at a time
- const Qt::WidgetAttribute MacSizes[] = { Qt::WA_MacNormalSize, Qt::WA_MacSmallSize,
- Qt::WA_MacMiniSize };
- for (int i = 0; i < 3; ++i) {
- if (MacSizes[i] != attribute)
- setAttribute_internal(MacSizes[i], false, data, d);
- }
- d->macUpdateSizeAttribute();
- }
-#endif
- break;
- case Qt::WA_ShowModal:
- if (!on) {
- if (isVisible())
- QApplicationPrivate::leaveModal(this);
- // reset modality type to Modeless when clearing WA_ShowModal
- data->window_modality = Qt::NonModal;
- } else if (data->window_modality == Qt::NonModal) {
- // determine the modality type if it hasn't been set prior
- // to setting WA_ShowModal. set the default to WindowModal
- // if we are the child of a group leader; otherwise use
- // ApplicationModal.
- QWidget *w = parentWidget();
- if (w)
- w = w->window();
- while (w && !w->testAttribute(Qt::WA_GroupLeader)) {
- w = w->parentWidget();
- if (w)
- w = w->window();
- }
- data->window_modality = (w && w->testAttribute(Qt::WA_GroupLeader))
- ? Qt::WindowModal
- : Qt::ApplicationModal;
- // Some window managers does not allow us to enter modal after the
- // window is showing. Therefore, to be consistent, we cannot call
- // QApplicationPrivate::enterModal(this) here. The window must be
- // hidden before changing modality.
- }
- if (testAttribute(Qt::WA_WState_Created)) {
- // don't call setModal_sys() before create_sys()
- d->setModal_sys();
- }
- break;
- case Qt::WA_MouseTracking: {
- QEvent e(QEvent::MouseTrackingChange);
- QApplication::sendEvent(this, &e);
- break; }
- case Qt::WA_NativeWindow: {
-#ifndef QT_NO_IM
- QWidget *focusWidget = d->effectiveFocusWidget();
- QInputContext *ic = 0;
- if (on && !internalWinId() && hasFocus()
- && focusWidget->testAttribute(Qt::WA_InputMethodEnabled)) {
- ic = focusWidget->d_func()->inputContext();
- if (ic) {
- ic->reset();
- ic->setFocusWidget(0);
- }
- }
- if (!qApp->testAttribute(Qt::AA_DontCreateNativeWidgetSiblings) && parentWidget()
-#if defined(Q_WS_MAC) && defined(QT_MAC_USE_COCOA)
- // On Mac, toolbars inside the unified title bar will never overlap with
- // siblings in the content view. So we skip enforce native siblings in that case
- && !d->isInUnifiedToolbar && parentWidget()->isWindow()
-#endif // Q_WS_MAC && QT_MAC_USE_COCOA
- )
- parentWidget()->d_func()->enforceNativeChildren();
- if (on && !internalWinId() && testAttribute(Qt::WA_WState_Created))
- d->createWinId();
- if (ic && isEnabled() && focusWidget->isEnabled()
- && focusWidget->testAttribute(Qt::WA_InputMethodEnabled)) {
- ic->setFocusWidget(focusWidget);
- }
-#endif //QT_NO_IM
- break;
- }
- case Qt::WA_PaintOnScreen:
- d->updateIsOpaque();
-#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_OS_SYMBIAN)
- // Recreate the widget if it's already created as an alien widget and
- // WA_PaintOnScreen is enabled. Paint on screen widgets must have win id.
- // So must their children.
- if (on) {
- setAttribute(Qt::WA_NativeWindow);
- d->enforceNativeChildren();
- }
-#endif
- // fall through
- case Qt::WA_OpaquePaintEvent:
- d->updateIsOpaque();
- break;
- case Qt::WA_NoSystemBackground:
- d->updateIsOpaque();
- // fall through...
- case Qt::WA_UpdatesDisabled:
- d->updateSystemBackground();
- break;
- case Qt::WA_TransparentForMouseEvents:
-#ifdef Q_WS_MAC
- d->macUpdateIgnoreMouseEvents();
-#endif
- break;
- case Qt::WA_InputMethodEnabled: {
-#ifndef QT_NO_IM
- QWidget *focusWidget = d->effectiveFocusWidget();
- QInputContext *ic = focusWidget->d_func()->assignedInputContext();
- if (!ic && (!on || hasFocus()))
- ic = focusWidget->d_func()->inputContext();
- if (ic) {
- if (on && hasFocus() && ic->focusWidget() != focusWidget && isEnabled()
- && focusWidget->testAttribute(Qt::WA_InputMethodEnabled)) {
- ic->setFocusWidget(focusWidget);
- } else if (!on && ic->focusWidget() == focusWidget) {
- ic->reset();
- ic->setFocusWidget(0);
- }
- }
-#endif //QT_NO_IM
- break;
- }
- case Qt::WA_WindowPropagation:
- d->resolvePalette();
- d->resolveFont();
- d->resolveLocale();
- break;
-#ifdef Q_WS_X11
- case Qt::WA_NoX11EventCompression:
- if (!d->extra)
- d->createExtra();
- d->extra->compress_events = on;
- break;
- case Qt::WA_X11OpenGLOverlay:
- d->updateIsOpaque();
- break;
- case Qt::WA_X11DoNotAcceptFocus:
- if (testAttribute(Qt::WA_WState_Created))
- d->updateX11AcceptFocus();
- break;
-#endif
- case Qt::WA_DontShowOnScreen: {
- if (on && isVisible()) {
- // Make sure we keep the current state and only hide the widget
- // from the desktop. show_sys will only update platform specific
- // attributes at this point.
- d->hide_sys();
-#ifdef Q_WS_QWS
- // Release the region for this window from qws if the widget has
- // been shown before the attribute was set.
- if (QWSWindowSurface *surface = static_cast<QWSWindowSurface *>(windowSurface())) {
- QWidget::qwsDisplay()->requestRegion(surface->winId(), surface->key(),
- surface->permanentState(), QRegion());
- }
-#endif
- d->show_sys();
- }
- break;
- }
-
-#ifdef Q_WS_X11
- case Qt::WA_X11NetWmWindowTypeDesktop:
- case Qt::WA_X11NetWmWindowTypeDock:
- case Qt::WA_X11NetWmWindowTypeToolBar:
- case Qt::WA_X11NetWmWindowTypeMenu:
- case Qt::WA_X11NetWmWindowTypeUtility:
- case Qt::WA_X11NetWmWindowTypeSplash:
- case Qt::WA_X11NetWmWindowTypeDialog:
- case Qt::WA_X11NetWmWindowTypeDropDownMenu:
- case Qt::WA_X11NetWmWindowTypePopupMenu:
- case Qt::WA_X11NetWmWindowTypeToolTip:
- case Qt::WA_X11NetWmWindowTypeNotification:
- case Qt::WA_X11NetWmWindowTypeCombo:
- case Qt::WA_X11NetWmWindowTypeDND:
- if (testAttribute(Qt::WA_WState_Created))
- d->setNetWmWindowTypes();
- break;
-#endif
-
- case Qt::WA_StaticContents:
- if (QWidgetBackingStore *bs = d->maybeBackingStore()) {
- if (on)
- bs->addStaticWidget(this);
- else
- bs->removeStaticWidget(this);
- }
- break;
- case Qt::WA_TranslucentBackground:
- if (on) {
- setAttribute(Qt::WA_NoSystemBackground);
- d->updateIsTranslucent();
- }
-
- break;
- case Qt::WA_AcceptTouchEvents:
-#if defined(Q_WS_WIN) || defined(Q_WS_MAC) || defined(Q_OS_SYMBIAN)
- if (on)
- d->registerTouchWindow();
-#endif
- break;
- case Qt::WA_LockPortraitOrientation:
- case Qt::WA_LockLandscapeOrientation:
- case Qt::WA_AutoOrientation: {
- const Qt::WidgetAttribute orientations[3] = {
- Qt::WA_LockPortraitOrientation,
- Qt::WA_LockLandscapeOrientation,
- Qt::WA_AutoOrientation
- };
-
- if (on) {
- // We can only have one of these set at a time
- for (int i = 0; i < 3; ++i) {
- if (orientations[i] != attribute)
- setAttribute_internal(orientations[i], false, data, d);
- }
- }
-
-#ifdef Q_WS_S60
- CAknAppUiBase* appUi = static_cast<CAknAppUiBase*>(CEikonEnv::Static()->EikAppUi());
- const CAknAppUiBase::TAppUiOrientation s60orientations[] = {
- CAknAppUiBase::EAppUiOrientationPortrait,
- CAknAppUiBase::EAppUiOrientationLandscape,
- CAknAppUiBase::EAppUiOrientationAutomatic
- };
- CAknAppUiBase::TAppUiOrientation s60orientation = CAknAppUiBase::EAppUiOrientationUnspecified;
- for (int i = 0; i < 3; ++i) {
- if (testAttribute(orientations[i])) {
- s60orientation = s60orientations[i];
- break;
- }
- }
- QT_TRAP_THROWING(appUi->SetOrientationL(s60orientation));
- S60->orientationSet = true;
- QSymbianControl *window = static_cast<QSymbianControl *>(internalWinId());
- if (window)
- window->ensureFixNativeOrientation();
-#endif
- break;
- }
- default:
- break;
- }
-}
-
-/*! \fn bool QWidget::testAttribute(Qt::WidgetAttribute attribute) const
-
- Returns true if attribute \a attribute is set on this widget;
- otherwise returns false.
-
- \sa setAttribute()
- */
-bool QWidget::testAttribute_helper(Qt::WidgetAttribute attribute) const
-{
- Q_D(const QWidget);
- const int x = attribute - 8*sizeof(uint);
- const int int_off = x / (8*sizeof(uint));
- return (d->high_attributes[int_off] & (1<<(x-(int_off*8*sizeof(uint)))));
-}
-
-/*!
- \property QWidget::windowOpacity
-
- \brief The level of opacity for the window.
-
- The valid range of opacity is from 1.0 (completely opaque) to
- 0.0 (completely transparent).
-
- By default the value of this property is 1.0.
-
- This feature is available on Embedded Linux, Mac OS X, Windows,
- and X11 platforms that support the Composite extension.
-
- This feature is not available on Windows CE.
-
- Note that under X11 you need to have a composite manager running,
- and the X11 specific _NET_WM_WINDOW_OPACITY atom needs to be
- supported by the window manager you are using.
-
- \warning Changing this property from opaque to transparent might issue a
- paint event that needs to be processed before the window is displayed
- correctly. This affects mainly the use of QPixmap::grabWindow(). Also note
- that semi-transparent windows update and resize significantly slower than
- opaque windows.
-
- \sa setMask()
-*/
-qreal QWidget::windowOpacity() const
-{
- Q_D(const QWidget);
- return (isWindow() && d->maybeTopData()) ? d->maybeTopData()->opacity / 255. : 1.0;
-}
-
-void QWidget::setWindowOpacity(qreal opacity)
-{
- Q_D(QWidget);
- if (!isWindow())
- return;
-
- opacity = qBound(qreal(0.0), opacity, qreal(1.0));
- QTLWExtra *extra = d->topData();
- extra->opacity = uint(opacity * 255);
- setAttribute(Qt::WA_WState_WindowOpacitySet);
-
-#ifndef Q_WS_QWS
- if (!testAttribute(Qt::WA_WState_Created))
- return;
-#endif
-
-#ifndef QT_NO_GRAPHICSVIEW
- if (QGraphicsProxyWidget *proxy = graphicsProxyWidget()) {
- // Avoid invalidating the cache if set.
- if (proxy->cacheMode() == QGraphicsItem::NoCache)
- proxy->update();
- else if (QGraphicsScene *scene = proxy->scene())
- scene->update(proxy->sceneBoundingRect());
- return;
- }
-#endif
-
- d->setWindowOpacity_sys(opacity);
-}
-
-/*!
- \property QWidget::windowModified
- \brief whether the document shown in the window has unsaved changes
-
- A modified window is a window whose content has changed but has
- not been saved to disk. This flag will have different effects
- varied by the platform. On Mac OS X the close button will have a
- modified look; on other platforms, the window title will have an
- '*' (asterisk).
-
- The window title must contain a "[*]" placeholder, which
- indicates where the '*' should appear. Normally, it should appear
- right after the file name (e.g., "document1.txt[*] - Text
- Editor"). If the window isn't modified, the placeholder is simply
- removed.
-
- Note that if a widget is set as modified, all its ancestors will
- also be set as modified. However, if you call \c
- {setWindowModified(false)} on a widget, this will not propagate to
- its parent because other children of the parent might have been
- modified.
-
- \sa windowTitle, {Application Example}, {SDI Example}, {MDI Example}
-*/
-bool QWidget::isWindowModified() const
-{
- return testAttribute(Qt::WA_WindowModified);
-}
-
-void QWidget::setWindowModified(bool mod)
-{
- Q_D(QWidget);
- setAttribute(Qt::WA_WindowModified, mod);
-
-#ifndef Q_WS_MAC
- if (!windowTitle().contains(QLatin1String("[*]")) && mod)
- qWarning("QWidget::setWindowModified: The window title does not contain a '[*]' placeholder");
-#endif
- d->setWindowTitle_helper(windowTitle());
- d->setWindowIconText_helper(windowIconText());
-#ifdef Q_WS_MAC
- d->setWindowModified_sys(mod);
-#endif
-
- QEvent e(QEvent::ModifiedChange);
- QApplication::sendEvent(this, &e);
-}
-
-#ifndef QT_NO_TOOLTIP
-/*!
- \property QWidget::toolTip
-
- \brief the widget's tooltip
-
- Note that by default tooltips are only shown for widgets that are
- children of the active window. You can change this behavior by
- setting the attribute Qt::WA_AlwaysShowToolTips on the \e window,
- not on the widget with the tooltip.
-
- If you want to control a tooltip's behavior, you can intercept the
- event() function and catch the QEvent::ToolTip event (e.g., if you
- want to customize the area for which the tooltip should be shown).
-
- By default, this property contains an empty string.
-
- \sa QToolTip statusTip whatsThis
-*/
-void QWidget::setToolTip(const QString &s)
-{
- Q_D(QWidget);
- d->toolTip = s;
-
- QEvent event(QEvent::ToolTipChange);
- QApplication::sendEvent(this, &event);
-}
-
-QString QWidget::toolTip() const
-{
- Q_D(const QWidget);
- return d->toolTip;
-}
-#endif // QT_NO_TOOLTIP
-
-
-#ifndef QT_NO_STATUSTIP
-/*!
- \property QWidget::statusTip
- \brief the widget's status tip
-
- By default, this property contains an empty string.
-
- \sa toolTip whatsThis
-*/
-void QWidget::setStatusTip(const QString &s)
-{
- Q_D(QWidget);
- d->statusTip = s;
-}
-
-QString QWidget::statusTip() const
-{
- Q_D(const QWidget);
- return d->statusTip;
-}
-#endif // QT_NO_STATUSTIP
-
-#ifndef QT_NO_WHATSTHIS
-/*!
- \property QWidget::whatsThis
-
- \brief the widget's What's This help text.
-
- By default, this property contains an empty string.
-
- \sa QWhatsThis QWidget::toolTip QWidget::statusTip
-*/
-void QWidget::setWhatsThis(const QString &s)
-{
- Q_D(QWidget);
- d->whatsThis = s;
-}
-
-QString QWidget::whatsThis() const
-{
- Q_D(const QWidget);
- return d->whatsThis;
-}
-#endif // QT_NO_WHATSTHIS
-
-#ifndef QT_NO_ACCESSIBILITY
-/*!
- \property QWidget::accessibleName
-
- \brief the widget's name as seen by assistive technologies
-
- This property is used by accessible clients to identify, find, or announce
- the widget for accessible clients.
-
- By default, this property contains an empty string.
-
- \sa QAccessibleInterface::text()
-*/
-void QWidget::setAccessibleName(const QString &name)
-{
- Q_D(QWidget);
- d->accessibleName = name;
- QAccessible::updateAccessibility(this, 0, QAccessible::NameChanged);
-}
-
-QString QWidget::accessibleName() const
-{
- Q_D(const QWidget);
- return d->accessibleName;
-}
-
-/*!
- \property QWidget::accessibleDescription
-
- \brief the widget's description as seen by assistive technologies
-
- By default, this property contains an empty string.
-
- \sa QAccessibleInterface::text()
-*/
-void QWidget::setAccessibleDescription(const QString &description)
-{
- Q_D(QWidget);
- d->accessibleDescription = description;
- QAccessible::updateAccessibility(this, 0, QAccessible::DescriptionChanged);
-}
-
-QString QWidget::accessibleDescription() const
-{
- Q_D(const QWidget);
- return d->accessibleDescription;
-}
-#endif // QT_NO_ACCESSIBILITY
-
-#ifndef QT_NO_SHORTCUT
-/*!
- Adds a shortcut to Qt's shortcut system that watches for the given
- \a key sequence in the given \a context. If the \a context is
- Qt::ApplicationShortcut, the shortcut applies to the application as a
- whole. Otherwise, it is either local to this widget, Qt::WidgetShortcut,
- or to the window itself, Qt::WindowShortcut.
-
- If the same \a key sequence has been grabbed by several widgets,
- when the \a key sequence occurs a QEvent::Shortcut event is sent
- to all the widgets to which it applies in a non-deterministic
- order, but with the ``ambiguous'' flag set to true.
-
- \warning You should not normally need to use this function;
- instead create \l{QAction}s with the shortcut key sequences you
- require (if you also want equivalent menu options and toolbar
- buttons), or create \l{QShortcut}s if you just need key sequences.
- Both QAction and QShortcut handle all the event filtering for you,
- and provide signals which are triggered when the user triggers the
- key sequence, so are much easier to use than this low-level
- function.
-
- \sa releaseShortcut() setShortcutEnabled()
-*/
-int QWidget::grabShortcut(const QKeySequence &key, Qt::ShortcutContext context)
-{
- Q_ASSERT(qApp);
- if (key.isEmpty())
- return 0;
- setAttribute(Qt::WA_GrabbedShortcut);
- return qApp->d_func()->shortcutMap.addShortcut(this, key, context);
-}
-
-/*!
- Removes the shortcut with the given \a id from Qt's shortcut
- system. The widget will no longer receive QEvent::Shortcut events
- for the shortcut's key sequence (unless it has other shortcuts
- with the same key sequence).
-
- \warning You should not normally need to use this function since
- Qt's shortcut system removes shortcuts automatically when their
- parent widget is destroyed. It is best to use QAction or
- QShortcut to handle shortcuts, since they are easier to use than
- this low-level function. Note also that this is an expensive
- operation.
-
- \sa grabShortcut() setShortcutEnabled()
-*/
-void QWidget::releaseShortcut(int id)
-{
- Q_ASSERT(qApp);
- if (id)
- qApp->d_func()->shortcutMap.removeShortcut(id, this, 0);
-}
-
-/*!
- If \a enable is true, the shortcut with the given \a id is
- enabled; otherwise the shortcut is disabled.
-
- \warning You should not normally need to use this function since
- Qt's shortcut system enables/disables shortcuts automatically as
- widgets become hidden/visible and gain or lose focus. It is best
- to use QAction or QShortcut to handle shortcuts, since they are
- easier to use than this low-level function.
-
- \sa grabShortcut() releaseShortcut()
-*/
-void QWidget::setShortcutEnabled(int id, bool enable)
-{
- Q_ASSERT(qApp);
- if (id)
- qApp->d_func()->shortcutMap.setShortcutEnabled(enable, id, this, 0);
-}
-
-/*!
- \since 4.2
-
- If \a enable is true, auto repeat of the shortcut with the
- given \a id is enabled; otherwise it is disabled.
-
- \sa grabShortcut() releaseShortcut()
-*/
-void QWidget::setShortcutAutoRepeat(int id, bool enable)
-{
- Q_ASSERT(qApp);
- if (id)
- qApp->d_func()->shortcutMap.setShortcutAutoRepeat(enable, id, this, 0);
-}
-#endif // QT_NO_SHORTCUT
-/*!
- Updates the widget's micro focus.
-
- \sa QInputContext
-*/
-void QWidget::updateMicroFocus()
-{
-#if !defined(QT_NO_IM) && (defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN))
- Q_D(QWidget);
- // and optimization to update input context only it has already been created.
- if (d->assignedInputContext() || qApp->d_func()->inputContext) {
- QInputContext *ic = inputContext();
- if (ic)
- ic->update();
- }
-#endif
-#ifndef QT_NO_ACCESSIBILITY
- if (isVisible()) {
- // ##### is this correct
- QAccessible::updateAccessibility(this, 0, QAccessible::StateChanged);
- }
-#endif
-}
-
-
-#if defined (Q_WS_WIN)
-/*!
- Returns the window system handle of the widget, for low-level
- access. Using this function is not portable.
-
- An HDC acquired with getDC() has to be released with releaseDC().
-
- \warning Using this function is not portable.
-*/
-HDC QWidget::getDC() const
-{
- Q_D(const QWidget);
- if (d->hd)
- return (HDC) d->hd;
- return GetDC(winId());
-}
-
-/*!
- Releases the HDC \a hdc acquired by a previous call to getDC().
-
- \warning Using this function is not portable.
-*/
-void QWidget::releaseDC(HDC hdc) const
-{
- Q_D(const QWidget);
- // If its the widgets own dc, it will be released elsewhere. If
- // its a different HDC we release it and issue a warning if it
- // fails.
- if (hdc != d->hd && !ReleaseDC(winId(), hdc))
- qErrnoWarning("QWidget::releaseDC(): failed to release HDC");
-}
-#else
-/*!
- Returns the window system handle of the widget, for low-level
- access. Using this function is not portable.
-
- The HANDLE type varies with platform; see \c qwindowdefs.h for
- details.
-*/
-Qt::HANDLE QWidget::handle() const
-{
- Q_D(const QWidget);
- if (!internalWinId() && testAttribute(Qt::WA_WState_Created))
- (void)winId(); // enforce native window
- return d->hd;
-}
-#endif
-
-
-/*!
- Raises this widget to the top of the parent widget's stack.
-
- After this call the widget will be visually in front of any
- overlapping sibling widgets.
-
- \note When using activateWindow(), you can call this function to
- ensure that the window is stacked on top.
-
- \sa lower(), stackUnder()
-*/
-
-void QWidget::raise()
-{
- Q_D(QWidget);
- if (!isWindow()) {
- QWidget *p = parentWidget();
- const int parentChildCount = p->d_func()->children.size();
- if (parentChildCount < 2)
- return;
- const int from = p->d_func()->children.indexOf(this);
- Q_ASSERT(from >= 0);
- // Do nothing if the widget is already in correct stacking order _and_ created.
- if (from != parentChildCount -1)
- p->d_func()->children.move(from, parentChildCount - 1);
- if (!testAttribute(Qt::WA_WState_Created) && p->testAttribute(Qt::WA_WState_Created))
- create();
- else if (from == parentChildCount - 1)
- return;
-
- QRegion region(rect());
- d->subtractOpaqueSiblings(region);
- d->invalidateBuffer(region);
- }
- if (testAttribute(Qt::WA_WState_Created))
- d->raise_sys();
-
- QEvent e(QEvent::ZOrderChange);
- QApplication::sendEvent(this, &e);
-}
-
-/*!
- Lowers the widget to the bottom of the parent widget's stack.
-
- After this call the widget will be visually behind (and therefore
- obscured by) any overlapping sibling widgets.
-
- \sa raise(), stackUnder()
-*/
-
-void QWidget::lower()
-{
- Q_D(QWidget);
- if (!isWindow()) {
- QWidget *p = parentWidget();
- const int parentChildCount = p->d_func()->children.size();
- if (parentChildCount < 2)
- return;
- const int from = p->d_func()->children.indexOf(this);
- Q_ASSERT(from >= 0);
- // Do nothing if the widget is already in correct stacking order _and_ created.
- if (from != 0)
- p->d_func()->children.move(from, 0);
- if (!testAttribute(Qt::WA_WState_Created) && p->testAttribute(Qt::WA_WState_Created))
- create();
- else if (from == 0)
- return;
- }
- if (testAttribute(Qt::WA_WState_Created))
- d->lower_sys();
-
- QEvent e(QEvent::ZOrderChange);
- QApplication::sendEvent(this, &e);
-}
-
-
-/*!
- Places the widget under \a w in the parent widget's stack.
-
- To make this work, the widget itself and \a w must be siblings.
-
- \sa raise(), lower()
-*/
-void QWidget::stackUnder(QWidget* w)
-{
- Q_D(QWidget);
- QWidget *p = parentWidget();
- if (!w || isWindow() || p != w->parentWidget() || this == w)
- return;
- if (p) {
- int from = p->d_func()->children.indexOf(this);
- int to = p->d_func()->children.indexOf(w);
- Q_ASSERT(from >= 0);
- Q_ASSERT(to >= 0);
- if (from < to)
- --to;
- // Do nothing if the widget is already in correct stacking order _and_ created.
- if (from != to)
- p->d_func()->children.move(from, to);
- if (!testAttribute(Qt::WA_WState_Created) && p->testAttribute(Qt::WA_WState_Created))
- create();
- else if (from == to)
- return;
- }
- if (testAttribute(Qt::WA_WState_Created))
- d->stackUnder_sys(w);
-
- QEvent e(QEvent::ZOrderChange);
- QApplication::sendEvent(this, &e);
-}
-
-void QWidget::styleChange(QStyle&) { }
-void QWidget::enabledChange(bool) { } // compat
-void QWidget::paletteChange(const QPalette &) { } // compat
-void QWidget::fontChange(const QFont &) { } // compat
-void QWidget::windowActivationChange(bool) { } // compat
-void QWidget::languageChange() { } // compat
-
-
-/*!
- \fn bool QWidget::isVisibleToTLW() const
-
- Use isVisible() instead.
-*/
-
-/*!
- \fn void QWidget::iconify()
-
- Use showMinimized() instead.
-*/
-
-/*!
- \fn void QWidget::constPolish() const
-
- Use ensurePolished() instead.
-*/
-
-/*!
- \fn void QWidget::reparent(QWidget *parent, Qt::WindowFlags f, const QPoint &p, bool showIt)
-
- Use setParent() to change the parent or the widget's widget flags;
- use move() to move the widget, and use show() to show the widget.
-*/
-
-/*!
- \fn void QWidget::reparent(QWidget *parent, const QPoint &p, bool showIt)
-
- Use setParent() to change the parent; use move() to move the
- widget, and use show() to show the widget.
-*/
-
-/*!
- \fn void QWidget::recreate(QWidget *parent, Qt::WindowFlags f, const QPoint & p, bool showIt)
-
- Use setParent() to change the parent or the widget's widget flags;
- use move() to move the widget, and use show() to show the widget.
-*/
-
-/*!
- \fn bool QWidget::hasMouse() const
-
- Use testAttribute(Qt::WA_UnderMouse) instead.
-*/
-
-/*!
- \fn bool QWidget::ownCursor() const
-
- Use testAttribute(Qt::WA_SetCursor) instead.
-*/
-
-/*!
- \fn bool QWidget::ownFont() const
-
- Use testAttribute(Qt::WA_SetFont) instead.
-*/
-
-/*!
- \fn void QWidget::unsetFont()
-
- Use setFont(QFont()) instead.
-*/
-
-/*!
- \fn bool QWidget::ownPalette() const
-
- Use testAttribute(Qt::WA_SetPalette) instead.
-*/
-
-/*!
- \fn void QWidget::unsetPalette()
-
- Use setPalette(QPalette()) instead.
-*/
-
-/*!
- \fn void QWidget::setEraseColor(const QColor &color)
-
- Use the palette instead.
-
- \oldcode
- widget->setEraseColor(color);
- \newcode
- QPalette palette;
- palette.setColor(widget->backgroundRole(), color);
- widget->setPalette(palette);
- \endcode
-*/
-
-/*!
- \fn void QWidget::setErasePixmap(const QPixmap &pixmap)
-
- Use the palette instead.
-
- \oldcode
- widget->setErasePixmap(pixmap);
- \newcode
- QPalette palette;
- palette.setBrush(widget->backgroundRole(), QBrush(pixmap));
- widget->setPalette(palette);
- \endcode
-*/
-
-/*!
- \fn void QWidget::setPaletteForegroundColor(const QColor &color)
-
- Use the palette directly.
-
- \oldcode
- widget->setPaletteForegroundColor(color);
- \newcode
- QPalette palette;
- palette.setColor(widget->foregroundRole(), color);
- widget->setPalette(palette);
- \endcode
-*/
-
-/*!
- \fn void QWidget::setPaletteBackgroundColor(const QColor &color)
-
- Use the palette directly.
-
- \oldcode
- widget->setPaletteBackgroundColor(color);
- \newcode
- QPalette palette;
- palette.setColor(widget->backgroundRole(), color);
- widget->setPalette(palette);
- \endcode
-*/
-
-/*!
- \fn void QWidget::setPaletteBackgroundPixmap(const QPixmap &pixmap)
-
- Use the palette directly.
-
- \oldcode
- widget->setPaletteBackgroundPixmap(pixmap);
- \newcode
- QPalette palette;
- palette.setBrush(widget->backgroundRole(), QBrush(pixmap));
- widget->setPalette(palette);
- \endcode
-*/
-
-/*!
- \fn void QWidget::setBackgroundPixmap(const QPixmap &pixmap)
-
- Use the palette instead.
-
- \oldcode
- widget->setBackgroundPixmap(pixmap);
- \newcode
- QPalette palette;
- palette.setBrush(widget->backgroundRole(), QBrush(pixmap));
- widget->setPalette(palette);
- \endcode
-*/
-
-/*!
- \fn void QWidget::setBackgroundColor(const QColor &color)
-
- Use the palette instead.
-
- \oldcode
- widget->setBackgroundColor(color);
- \newcode
- QPalette palette;
- palette.setColor(widget->backgroundRole(), color);
- widget->setPalette(palette);
- \endcode
-*/
-
-/*!
- \fn QColorGroup QWidget::colorGroup() const
-
- Use QColorGroup(palette()) instead.
-*/
-
-/*!
- \fn QWidget *QWidget::parentWidget(bool sameWindow) const
-
- Use the no-argument overload instead.
-*/
-
-/*!
- \fn void QWidget::setKeyCompression(bool b)
-
- Use setAttribute(Qt::WA_KeyCompression, b) instead.
-*/
-
-/*!
- \fn void QWidget::setFont(const QFont &f, bool b)
-
- Use the single-argument overload instead.
-*/
-
-/*!
- \fn void QWidget::setPalette(const QPalette &p, bool b)
-
- Use the single-argument overload instead.
-*/
-
-/*!
- \fn void QWidget::setBackgroundOrigin(BackgroundOrigin background)
-
- \obsolete
-*/
-
-/*!
- \fn BackgroundOrigin QWidget::backgroundOrigin() const
-
- \obsolete
-
- Always returns \c WindowOrigin.
-*/
-
-/*!
- \fn QPoint QWidget::backgroundOffset() const
-
- \obsolete
-
- Always returns QPoint().
-*/
-
-/*!
- \fn void QWidget::repaint(bool b)
-
- The boolean parameter \a b is ignored. Use the no-argument overload instead.
-*/
-
-/*!
- \fn void QWidget::repaint(int x, int y, int w, int h, bool b)
-
- The boolean parameter \a b is ignored. Use the four-argument overload instead.
-*/
-
-/*!
- \fn void QWidget::repaint(const QRect &r, bool b)
-
- The boolean parameter \a b is ignored. Use the single rect-argument overload instead.
-*/
-
-/*!
- \fn void QWidget::repaint(const QRegion &rgn, bool b)
-
- The boolean parameter \a b is ignored. Use the single region-argument overload instead.
-*/
-
-/*!
- \fn void QWidget::erase()
-
- Drawing may only take place in a QPaintEvent. Overload
- paintEvent() to do your erasing and call update() to schedule a
- replaint whenever necessary. See also QPainter.
-*/
-
-/*!
- \fn void QWidget::erase(int x, int y, int w, int h)
-
- Drawing may only take place in a QPaintEvent. Overload
- paintEvent() to do your erasing and call update() to schedule a
- replaint whenever necessary. See also QPainter.
-*/
-
-/*!
- \fn void QWidget::erase(const QRect &rect)
-
- Drawing may only take place in a QPaintEvent. Overload
- paintEvent() to do your erasing and call update() to schedule a
- replaint whenever necessary. See also QPainter.
-*/
-
-/*!
- \fn void QWidget::drawText(const QPoint &p, const QString &s)
-
- Drawing may only take place in a QPaintEvent. Overload
- paintEvent() to do your drawing and call update() to schedule a
- replaint whenever necessary. See also QPainter.
-*/
-
-/*!
- \fn void QWidget::drawText(int x, int y, const QString &s)
-
- Drawing may only take place in a QPaintEvent. Overload
- paintEvent() to do your drawing and call update() to schedule a
- replaint whenever necessary. See also QPainter.
-*/
-
-/*!
- \fn QWidget *QWidget::childAt(const QPoint &p, bool includeThis) const
-
- Use the single point argument overload instead.
-*/
-
-/*!
- \fn void QWidget::setCaption(const QString &c)
-
- Use setWindowTitle() instead.
-*/
-
-/*!
- \fn void QWidget::setIcon(const QPixmap &i)
-
- Use setWindowIcon() instead.
-*/
-
-/*!
- \fn void QWidget::setIconText(const QString &it)
-
- Use setWindowIconText() instead.
-*/
-
-/*!
- \fn QString QWidget::caption() const
-
- Use windowTitle() instead.
-*/
-
-/*!
- \fn QString QWidget::iconText() const
-
- Use windowIconText() instead.
-*/
-
-/*!
- \fn bool QWidget::isTopLevel() const
- \obsolete
-
- Use isWindow() instead.
-*/
-
-/*!
- \fn bool QWidget::isRightToLeft() const
- \internal
-*/
-
-/*!
- \fn bool QWidget::isLeftToRight() const
- \internal
-*/
-
-/*!
- \fn void QWidget::setInputMethodEnabled(bool enabled)
-
- Use setAttribute(Qt::WA_InputMethodEnabled, \a enabled) instead.
-*/
-
-/*!
- \fn bool QWidget::isInputMethodEnabled() const
-
- Use testAttribute(Qt::WA_InputMethodEnabled) instead.
-*/
-
-/*!
- \fn void QWidget::setActiveWindow()
-
- Use activateWindow() instead.
-*/
-
-/*!
- \fn bool QWidget::isShown() const
-
- Use !isHidden() instead (notice the exclamation mark), or use isVisible() to check whether the widget is visible.
-*/
-
-/*!
- \fn bool QWidget::isDialog() const
-
- Use windowType() == Qt::Dialog instead.
-*/
-
-/*!
- \fn bool QWidget::isPopup() const
-
- Use windowType() == Qt::Popup instead.
-*/
-
-/*!
- \fn bool QWidget::isDesktop() const
-
- Use windowType() == Qt::Desktop instead.
-*/
-
-/*!
- \fn void QWidget::polish()
-
- Use ensurePolished() instead.
-*/
-
-/*!
- \fn QWidget *QWidget::childAt(int x, int y, bool includeThis) const
-
- Use the childAt() overload that doesn't have an \a includeThis parameter.
-
- \oldcode
- return widget->childAt(x, y, true);
- \newcode
- QWidget *child = widget->childAt(x, y, true);
- if (child)
- return child;
- if (widget->rect().contains(x, y))
- return widget;
- \endcode
-*/
-
-/*!
- \macro QWIDGETSIZE_MAX
- \relates QWidget
-
- Defines the maximum size for a QWidget object.
-
- The largest allowed size for a widget is QSize(QWIDGETSIZE_MAX,
- QWIDGETSIZE_MAX), i.e. QSize (16777215,16777215).
-
- \sa QWidget::setMaximumSize()
-*/
-
-/*!
- \fn QWidget::setupUi(QWidget *widget)
-
- Sets up the user interface for the specified \a widget.
-
- \note This function is available with widgets that derive from user
- interface descriptions created using \l{uic}.
-
- \sa {Using a Designer UI File in Your Application}
-*/
-
-QRect QWidgetPrivate::frameStrut() const
-{
- Q_Q(const QWidget);
- if (!q->isWindow() || (q->windowType() == Qt::Desktop) || q->testAttribute(Qt::WA_DontShowOnScreen)) {
- // x2 = x1 + w - 1, so w/h = 1
- return QRect(0, 0, 1, 1);
- }
-
- if (data.fstrut_dirty
-#ifndef Q_WS_WIN
- // ### Fix properly for 4.3
- && q->isVisible()
-#endif
- && q->testAttribute(Qt::WA_WState_Created))
- const_cast<QWidgetPrivate *>(this)->updateFrameStrut();
-
- return maybeTopData() ? maybeTopData()->frameStrut : QRect();
-}
-
-#ifdef QT_KEYPAD_NAVIGATION
-/*!
- \internal
-
- Changes the focus from the current focusWidget to a widget in
- the \a direction.
-
- Returns true, if there was a widget in that direction
-*/
-bool QWidgetPrivate::navigateToDirection(Direction direction)
-{
- QWidget *targetWidget = widgetInNavigationDirection(direction);
- if (targetWidget)
- targetWidget->setFocus();
- return (targetWidget != 0);
-}
-
-/*!
- \internal
-
- Searches for a widget that is positioned in the \a direction, starting
- from the current focusWidget.
-
- Returns the pointer to a found widget or 0, if there was no widget in
- that direction.
-*/
-QWidget *QWidgetPrivate::widgetInNavigationDirection(Direction direction)
-{
- const QWidget *sourceWidget = QApplication::focusWidget();
- if (!sourceWidget)
- return 0;
- const QRect sourceRect = sourceWidget->rect().translated(sourceWidget->mapToGlobal(QPoint()));
- const int sourceX =
- (direction == DirectionNorth || direction == DirectionSouth) ?
- (sourceRect.left() + (sourceRect.right() - sourceRect.left()) / 2)
- :(direction == DirectionEast ? sourceRect.right() : sourceRect.left());
- const int sourceY =
- (direction == DirectionEast || direction == DirectionWest) ?
- (sourceRect.top() + (sourceRect.bottom() - sourceRect.top()) / 2)
- :(direction == DirectionSouth ? sourceRect.bottom() : sourceRect.top());
- const QPoint sourcePoint(sourceX, sourceY);
- const QPoint sourceCenter = sourceRect.center();
- const QWidget *sourceWindow = sourceWidget->window();
-
- QWidget *targetWidget = 0;
- int shortestDistance = INT_MAX;
- foreach(QWidget *targetCandidate, QApplication::allWidgets()) {
-
- const QRect targetCandidateRect = targetCandidate->rect().translated(targetCandidate->mapToGlobal(QPoint()));
-
- // For focus proxies, the child widget handling the focus can have keypad navigation focus,
- // but the owner of the proxy cannot.
- // Additionally, empty widgets should be ignored.
- if (targetCandidate->focusProxy() || targetCandidateRect.isEmpty())
- continue;
-
- // Only navigate to a target widget that...
- if ( targetCandidate != sourceWidget
- // ...takes the focus,
- && targetCandidate->focusPolicy() & Qt::TabFocus
- // ...is above if DirectionNorth,
- && !(direction == DirectionNorth && targetCandidateRect.bottom() > sourceRect.top())
- // ...is on the right if DirectionEast,
- && !(direction == DirectionEast && targetCandidateRect.left() < sourceRect.right())
- // ...is below if DirectionSouth,
- && !(direction == DirectionSouth && targetCandidateRect.top() < sourceRect.bottom())
- // ...is on the left if DirectionWest,
- && !(direction == DirectionWest && targetCandidateRect.right() > sourceRect.left())
- // ...is enabled,
- && targetCandidate->isEnabled()
- // ...is visible,
- && targetCandidate->isVisible()
- // ...is in the same window,
- && targetCandidate->window() == sourceWindow) {
- const int targetCandidateDistance = pointToRect(sourcePoint, targetCandidateRect);
- if (targetCandidateDistance < shortestDistance) {
- shortestDistance = targetCandidateDistance;
- targetWidget = targetCandidate;
- }
- }
- }
- return targetWidget;
-}
-
-/*!
- \internal
-
- Tells us if it there is currently a reachable widget by keypad navigation in
- a certain \a orientation.
- If no navigation is possible, occurring key events in that \a orientation may
- be used to interact with the value in the focused widget, even though it
- currently has not the editFocus.
-
- \sa QWidgetPrivate::widgetInNavigationDirection(), QWidget::hasEditFocus()
-*/
-bool QWidgetPrivate::canKeypadNavigate(Qt::Orientation orientation)
-{
- return orientation == Qt::Horizontal?
- (QWidgetPrivate::widgetInNavigationDirection(QWidgetPrivate::DirectionEast)
- || QWidgetPrivate::widgetInNavigationDirection(QWidgetPrivate::DirectionWest))
- :(QWidgetPrivate::widgetInNavigationDirection(QWidgetPrivate::DirectionNorth)
- || QWidgetPrivate::widgetInNavigationDirection(QWidgetPrivate::DirectionSouth));
-}
-/*!
- \internal
-
- Checks, if the \a widget is inside a QTabWidget. If is is inside
- one, left/right key events will be used to switch between tabs in keypad
- navigation. If there is no QTabWidget, the horizontal key events can be used
-to
- interact with the value in the focused widget, even though it currently has
- not the editFocus.
-
- \sa QWidget::hasEditFocus()
-*/
-bool QWidgetPrivate::inTabWidget(QWidget *widget)
-{
- for (QWidget *tabWidget = widget; tabWidget; tabWidget = tabWidget->parentWidget())
- if (qobject_cast<const QTabWidget*>(tabWidget))
- return true;
- return false;
-}
-#endif
-
-/*!
- \preliminary
- \since 4.2
- \obsolete
-
- Sets the window surface to be the \a surface specified.
- The QWidget takes will ownership of the \a surface.
- widget itself is deleted.
-*/
-void QWidget::setWindowSurface(QWindowSurface *surface)
-{
- // ### createWinId() ??
-
-#ifndef Q_BACKINGSTORE_SUBSURFACES
- if (!isTopLevel())
- return;
-#endif
-
- Q_D(QWidget);
-
- QTLWExtra *topData = d->topData();
- if (topData->windowSurface == surface)
- return;
-
- QWindowSurface *oldSurface = topData->windowSurface;
- delete topData->windowSurface;
- topData->windowSurface = surface;
-
- QWidgetBackingStore *bs = d->maybeBackingStore();
- if (!bs)
- return;
-
- if (isTopLevel()) {
- if (bs->windowSurface != oldSurface && bs->windowSurface != surface)
- delete bs->windowSurface;
- bs->windowSurface = surface;
- }
-#ifdef Q_BACKINGSTORE_SUBSURFACES
- else {
- bs->subSurfaces.append(surface);
- }
- bs->subSurfaces.removeOne(oldSurface);
-#endif
-}
-
-/*!
- \preliminary
- \since 4.2
-
- Returns the QWindowSurface this widget will be drawn into.
-*/
-QWindowSurface *QWidget::windowSurface() const
-{
- Q_D(const QWidget);
- QTLWExtra *extra = d->maybeTopData();
- if (extra && extra->windowSurface)
- return extra->windowSurface;
-
- QWidgetBackingStore *bs = d->maybeBackingStore();
-
-#ifdef Q_BACKINGSTORE_SUBSURFACES
- if (bs && bs->subSurfaces.isEmpty())
- return bs->windowSurface;
-
- if (!isTopLevel()) {
- const QWidget *w = parentWidget();
- while (w) {
- QTLWExtra *extra = w->d_func()->maybeTopData();
- if (extra && extra->windowSurface)
- return extra->windowSurface;
- if (w->isTopLevel())
- break;
- w = w->parentWidget();
- }
- }
-#endif // Q_BACKINGSTORE_SUBSURFACES
-
- return bs ? bs->windowSurface : 0;
-}
-
-void QWidgetPrivate::getLayoutItemMargins(int *left, int *top, int *right, int *bottom) const
-{
- if (left)
- *left = (int)leftLayoutItemMargin;
- if (top)
- *top = (int)topLayoutItemMargin;
- if (right)
- *right = (int)rightLayoutItemMargin;
- if (bottom)
- *bottom = (int)bottomLayoutItemMargin;
-}
-
-void QWidgetPrivate::setLayoutItemMargins(int left, int top, int right, int bottom)
-{
- if (leftLayoutItemMargin == left
- && topLayoutItemMargin == top
- && rightLayoutItemMargin == right
- && bottomLayoutItemMargin == bottom)
- return;
-
- Q_Q(QWidget);
- leftLayoutItemMargin = (signed char)left;
- topLayoutItemMargin = (signed char)top;
- rightLayoutItemMargin = (signed char)right;
- bottomLayoutItemMargin = (signed char)bottom;
- q->updateGeometry();
-}
-
-void QWidgetPrivate::setLayoutItemMargins(QStyle::SubElement element, const QStyleOption *opt)
-{
- Q_Q(QWidget);
- QStyleOption myOpt;
- if (!opt) {
- myOpt.initFrom(q);
- myOpt.rect.setRect(0, 0, 32768, 32768); // arbitrary
- opt = &myOpt;
- }
-
- QRect liRect = q->style()->subElementRect(element, opt, q);
- if (liRect.isValid()) {
- leftLayoutItemMargin = (signed char)(opt->rect.left() - liRect.left());
- topLayoutItemMargin = (signed char)(opt->rect.top() - liRect.top());
- rightLayoutItemMargin = (signed char)(liRect.right() - opt->rect.right());
- bottomLayoutItemMargin = (signed char)(liRect.bottom() - opt->rect.bottom());
- } else {
- leftLayoutItemMargin = 0;
- topLayoutItemMargin = 0;
- rightLayoutItemMargin = 0;
- bottomLayoutItemMargin = 0;
- }
-}
-// resets the Qt::WA_QuitOnClose attribute to the default value for transient widgets.
-void QWidgetPrivate::adjustQuitOnCloseAttribute()
-{
- Q_Q(QWidget);
-
- if (!q->parentWidget()) {
- Qt::WindowType type = q->windowType();
- if (type == Qt::Widget || type == Qt::SubWindow)
- type = Qt::Window;
- if (type != Qt::Widget && type != Qt::Window && type != Qt::Dialog)
- q->setAttribute(Qt::WA_QuitOnClose, false);
- }
-}
-
-
-
-Q_GUI_EXPORT QWidgetData *qt_qwidget_data(QWidget *widget)
-{
- return widget->data;
-}
-
-Q_GUI_EXPORT QWidgetPrivate *qt_widget_private(QWidget *widget)
-{
- return widget->d_func();
-}
-
-
-#ifndef QT_NO_GRAPHICSVIEW
-/*!
- \since 4.5
-
- Returns the proxy widget for the corresponding embedded widget in a graphics
- view; otherwise returns 0.
-
- \sa QGraphicsProxyWidget::createProxyForChildWidget(),
- QGraphicsScene::addWidget()
- */
-QGraphicsProxyWidget *QWidget::graphicsProxyWidget() const
-{
- Q_D(const QWidget);
- if (d->extra) {
- return d->extra->proxyWidget;
- }
- return 0;
-}
-#endif
-
-
-/*!
- \typedef QWidgetList
- \relates QWidget
-
- Synonym for QList<QWidget *>.
-*/
-
-#ifndef QT_NO_GESTURES
-/*!
- Subscribes the widget to a given \a gesture with specific \a flags.
-
- \sa ungrabGesture(), QGestureEvent
- \since 4.6
-*/
-void QWidget::grabGesture(Qt::GestureType gesture, Qt::GestureFlags flags)
-{
- Q_D(QWidget);
- d->gestureContext.insert(gesture, flags);
- (void)QGestureManager::instance(); // create a gesture manager
-}
-
-/*!
- Unsubscribes the widget from a given \a gesture type
-
- \sa grabGesture(), QGestureEvent
- \since 4.6
-*/
-void QWidget::ungrabGesture(Qt::GestureType gesture)
-{
- Q_D(QWidget);
- if (d->gestureContext.remove(gesture)) {
- if (QGestureManager *manager = QGestureManager::instance())
- manager->cleanupCachedGestures(this, gesture);
- }
-}
-#endif // QT_NO_GESTURES
-
-/*!
- \typedef WId
- \relates QWidget
-
- Platform dependent window identifier.
-*/
-
-/*!
- \fn void QWidget::destroy(bool destroyWindow, bool destroySubWindows)
-
- Frees up window system resources. Destroys the widget window if \a
- destroyWindow is true.
-
- destroy() calls itself recursively for all the child widgets,
- passing \a destroySubWindows for the \a destroyWindow parameter.
- To have more control over destruction of subwidgets, destroy
- subwidgets selectively first.
-
- This function is usually called from the QWidget destructor.
-*/
-
-/*!
- \fn QPaintEngine *QWidget::paintEngine() const
-
- Returns the widget's paint engine.
-
- Note that this function should not be called explicitly by the
- user, since it's meant for reimplementation purposes only. The
- function is called by Qt internally, and the default
- implementation may not always return a valid pointer.
-*/
-
-/*!
- \fn QPoint QWidget::mapToGlobal(const QPoint &pos) const
-
- Translates the widget coordinate \a pos to global screen
- coordinates. For example, \c{mapToGlobal(QPoint(0,0))} would give
- the global coordinates of the top-left pixel of the widget.
-
- \sa mapFromGlobal() mapTo() mapToParent()
-*/
-
-/*!
- \fn QPoint QWidget::mapFromGlobal(const QPoint &pos) const
-
- Translates the global screen coordinate \a pos to widget
- coordinates.
-
- \sa mapToGlobal() mapFrom() mapFromParent()
-*/
-
-/*!
- \fn void QWidget::grabMouse()
-
- Grabs the mouse input.
-
- This widget receives all mouse events until releaseMouse() is
- called; other widgets get no mouse events at all. Keyboard
- events are not affected. Use grabKeyboard() if you want to grab
- that.
-
- \warning Bugs in mouse-grabbing applications very often lock the
- terminal. Use this function with extreme caution, and consider
- using the \c -nograb command line option while debugging.
-
- It is almost never necessary to grab the mouse when using Qt, as
- Qt grabs and releases it sensibly. In particular, Qt grabs the
- mouse when a mouse button is pressed and keeps it until the last
- button is released.
-
- \note Only visible widgets can grab mouse input. If isVisible()
- returns false for a widget, that widget cannot call grabMouse().
-
- \note \bold{(Mac OS X developers)} For \e Cocoa, calling
- grabMouse() on a widget only works when the mouse is inside the
- frame of that widget. For \e Carbon, it works outside the widget's
- frame as well, like for Windows and X11.
-
- \sa releaseMouse() grabKeyboard() releaseKeyboard()
-*/
-
-/*!
- \fn void QWidget::grabMouse(const QCursor &cursor)
- \overload grabMouse()
-
- Grabs the mouse input and changes the cursor shape.
-
- The cursor will assume shape \a cursor (for as long as the mouse
- focus is grabbed) and this widget will be the only one to receive
- mouse events until releaseMouse() is called().
-
- \warning Grabbing the mouse might lock the terminal.
-
- \note \bold{(Mac OS X developers)} See the note in QWidget::grabMouse().
-
- \sa releaseMouse(), grabKeyboard(), releaseKeyboard(), setCursor()
-*/
-
-/*!
- \fn void QWidget::releaseMouse()
-
- Releases the mouse grab.
-
- \sa grabMouse(), grabKeyboard(), releaseKeyboard()
-*/
-
-/*!
- \fn void QWidget::grabKeyboard()
-
- Grabs the keyboard input.
-
- This widget receives all keyboard events until releaseKeyboard()
- is called; other widgets get no keyboard events at all. Mouse
- events are not affected. Use grabMouse() if you want to grab that.
-
- The focus widget is not affected, except that it doesn't receive
- any keyboard events. setFocus() moves the focus as usual, but the
- new focus widget receives keyboard events only after
- releaseKeyboard() is called.
-
- If a different widget is currently grabbing keyboard input, that
- widget's grab is released first.
-
- \sa releaseKeyboard() grabMouse() releaseMouse() focusWidget()
-*/
-
-/*!
- \fn void QWidget::releaseKeyboard()
-
- Releases the keyboard grab.
-
- \sa grabKeyboard(), grabMouse(), releaseMouse()
-*/
-
-/*!
- \fn QWidget *QWidget::mouseGrabber()
-
- Returns the widget that is currently grabbing the mouse input.
-
- If no widget in this application is currently grabbing the mouse,
- 0 is returned.
-
- \sa grabMouse(), keyboardGrabber()
-*/
-
-/*!
- \fn QWidget *QWidget::keyboardGrabber()
-
- Returns the widget that is currently grabbing the keyboard input.
-
- If no widget in this application is currently grabbing the
- keyboard, 0 is returned.
-
- \sa grabMouse(), mouseGrabber()
-*/
-
-/*!
- \fn void QWidget::activateWindow()
-
- Sets the top-level widget containing this widget to be the active
- window.
-
- An active window is a visible top-level window that has the
- keyboard input focus.
-
- This function performs the same operation as clicking the mouse on
- the title bar of a top-level window. On X11, the result depends on
- the Window Manager. If you want to ensure that the window is
- stacked on top as well you should also call raise(). Note that the
- window must be visible, otherwise activateWindow() has no effect.
-
- On Windows, if you are calling this when the application is not
- 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
- does not allow an application to interrupt what the user is currently
- doing in another application.
-
- \sa isActiveWindow(), window(), show()
-*/
-
-/*!
- \fn int QWidget::metric(PaintDeviceMetric m) const
-
- Internal implementation of the virtual QPaintDevice::metric()
- function.
-
- \a m is the metric to get.
-*/
-
-/*!
- \fn void QWidget::setMask(const QRegion &region)
- \overload
-
- Causes only the parts of the widget which overlap \a region to be
- visible. If the region includes pixels outside the rect() of the
- widget, window system controls in that area may or may not be
- visible, depending on the platform.
-
- Note that this effect can be slow if the region is particularly
- complex.
-
- \sa windowOpacity
-*/
-void QWidget::setMask(const QRegion &newMask)
-{
- Q_D(QWidget);
-
- d->createExtra();
- if (newMask == d->extra->mask)
- return;
-
-#ifndef QT_NO_BACKINGSTORE
- const QRegion oldMask(d->extra->mask);
-#endif
-
- d->extra->mask = newMask;
- d->extra->hasMask = !newMask.isEmpty();
-
-#ifndef QT_MAC_USE_COCOA
- if (!testAttribute(Qt::WA_WState_Created))
- return;
-#endif
-
- d->setMask_sys(newMask);
-
-#ifndef QT_NO_BACKINGSTORE
- if (!isVisible())
- return;
-
- if (!d->extra->hasMask) {
- // Mask was cleared; update newly exposed area.
- QRegion expose(rect());
- expose -= oldMask;
- if (!expose.isEmpty()) {
- d->setDirtyOpaqueRegion();
- update(expose);
- }
- return;
- }
-
- if (!isWindow()) {
- // Update newly exposed area on the parent widget.
- QRegion parentExpose(rect());
- parentExpose -= newMask;
- if (!parentExpose.isEmpty()) {
- d->setDirtyOpaqueRegion();
- parentExpose.translate(data->crect.topLeft());
- parentWidget()->update(parentExpose);
- }
-
- // Update newly exposed area on this widget
- if (!oldMask.isEmpty())
- update(newMask - oldMask);
- }
-#endif
-}
-
-/*!
- \fn void QWidget::setMask(const QBitmap &bitmap)
-
- Causes only the pixels of the widget for which \a bitmap has a
- corresponding 1 bit to be visible. If the region includes pixels
- outside the rect() of the widget, window system controls in that
- area may or may not be visible, depending on the platform.
-
- Note that this effect can be slow if the region is particularly
- complex.
-
- The following code shows how an image with an alpha channel can be
- used to generate a mask for a widget:
-
- \snippet doc/src/snippets/widget-mask/main.cpp 0
-
- The label shown by this code is masked using the image it contains,
- giving the appearance that an irregularly-shaped image is being drawn
- directly onto the screen.
-
- Masked widgets receive mouse events only on their visible
- portions.
-
- \sa clearMask(), windowOpacity(), {Shaped Clock Example}
-*/
-void QWidget::setMask(const QBitmap &bitmap)
-{
- setMask(QRegion(bitmap));
-}
-
-/*!
- \fn void QWidget::clearMask()
-
- Removes any mask set by setMask().
-
- \sa setMask()
-*/
-void QWidget::clearMask()
-{
- setMask(QRegion());
-}
-
-/*! \fn const QX11Info &QWidget::x11Info() const
- Returns information about the configuration of the X display used to display
- the widget.
-
- \warning This function is only available on X11.
-*/
-
-/*! \fn Qt::HANDLE QWidget::x11PictureHandle() const
- Returns the X11 Picture handle of the widget for XRender
- support. Use of this function is not portable. This function will
- return 0 if XRender support is not compiled into Qt, if the
- XRender extension is not supported on the X11 display, or if the
- handle could not be created.
-*/
-
-#ifdef Q_OS_SYMBIAN
-void QWidgetPrivate::_q_delayedDestroy(WId winId)
-{
- delete winId;
-}
-#endif
-
-#if QT_MAC_USE_COCOA
-void QWidgetPrivate::syncUnifiedMode() {
- // The whole purpose of this method is to keep the unifiedToolbar in sync.
- // That means making sure we either exchange the drawing methods or we let
- // the toolbar know that it does not require to draw the baseline.
- Q_Q(QWidget);
- // This function makes sense only if this is a top level
- if(!q->isWindow())
- return;
- OSWindowRef window = qt_mac_window_for(q);
- if(changeMethods) {
- // Ok, we are in documentMode.
- if(originalDrawMethod)
- qt_mac_replaceDrawRect(window, this);
- } else {
- if(!originalDrawMethod)
- qt_mac_replaceDrawRectOriginal(window, this);
- }
-}
-
-#endif // QT_MAC_USE_COCOA
-
-QT_END_NAMESPACE
-
-#include "moc_qwidget.cpp"
-
diff --git a/src/gui/kernel/qwidget.h b/src/gui/kernel/qwidget.h
deleted file mode 100644
index 1a9987d171..0000000000
--- a/src/gui/kernel/qwidget.h
+++ /dev/null
@@ -1,1090 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWIDGET_H
-#define QWIDGET_H
-
-#include <QtGui/qwindowdefs.h>
-#include <QtCore/qobject.h>
-#include <QtCore/qmargins.h>
-#include <QtGui/qpaintdevice.h>
-#include <QtGui/qpalette.h>
-#include <QtGui/qfont.h>
-#include <QtGui/qfontmetrics.h>
-#include <QtGui/qfontinfo.h>
-#include <QtGui/qsizepolicy.h>
-#include <QtGui/qregion.h>
-#include <QtGui/qbrush.h>
-#include <QtGui/qcursor.h>
-#include <QtGui/qkeysequence.h>
-
-#ifdef Q_WS_QPA //should this go somewhere else?
-#include <QtGui/qplatformwindowformat_qpa.h>
-#endif
-
-#ifdef QT_INCLUDE_COMPAT
-#include <QtGui/qevent.h>
-#endif
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QLayout;
-class QWSRegionManager;
-class QStyle;
-class QAction;
-class QVariant;
-
-class QActionEvent;
-class QMouseEvent;
-class QWheelEvent;
-class QHoverEvent;
-class QKeyEvent;
-class QFocusEvent;
-class QPaintEvent;
-class QMoveEvent;
-class QResizeEvent;
-class QCloseEvent;
-class QContextMenuEvent;
-class QInputMethodEvent;
-class QTabletEvent;
-class QDragEnterEvent;
-class QDragMoveEvent;
-class QDragLeaveEvent;
-class QDropEvent;
-class QShowEvent;
-class QHideEvent;
-class QInputContext;
-class QIcon;
-class QWindowSurface;
-class QPlatformWindow;
-class QLocale;
-class QGraphicsProxyWidget;
-class QGraphicsEffect;
-class QRasterWindowSurface;
-class QUnifiedToolbarSurface;
-#if defined(Q_WS_X11)
-class QX11Info;
-#endif
-
-class QWidgetData
-{
-public:
- WId winid;
- uint widget_attributes;
- Qt::WindowFlags window_flags;
- uint window_state : 4;
- uint focus_policy : 4;
- uint sizehint_forced :1;
- uint is_closing :1;
- uint in_show : 1;
- uint in_set_window_state : 1;
- mutable uint fstrut_dirty : 1;
- uint context_menu_policy : 3;
- uint window_modality : 2;
- uint in_destructor : 1;
- uint unused : 13;
- QRect crect;
- mutable QPalette pal;
- QFont fnt;
-#if defined(Q_WS_QWS)
-// QRegion req_region; // Requested region
-// mutable QRegion paintable_region; // Paintable region
-// mutable bool paintable_region_dirty;// needs to be recalculated
-// mutable QRegion alloc_region; // Allocated region
-// mutable bool alloc_region_dirty; // needs to be recalculated
-// mutable int overlapping_children; // Handle overlapping children
-
- int alloc_region_index;
-// int alloc_region_revision;
-#endif
- QRect wrect;
-};
-
-class QWidgetPrivate;
-
-class Q_GUI_EXPORT QWidget : public QObject, public QPaintDevice
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QWidget)
-
- Q_PROPERTY(bool modal READ isModal)
- Q_PROPERTY(Qt::WindowModality windowModality READ windowModality WRITE setWindowModality)
- Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled)
- Q_PROPERTY(QRect geometry READ geometry WRITE setGeometry)
- Q_PROPERTY(QRect frameGeometry READ frameGeometry)
- Q_PROPERTY(QRect normalGeometry READ normalGeometry)
- Q_PROPERTY(int x READ x)
- Q_PROPERTY(int y READ y)
- Q_PROPERTY(QPoint pos READ pos WRITE move DESIGNABLE false STORED false)
- Q_PROPERTY(QSize frameSize READ frameSize)
- Q_PROPERTY(QSize size READ size WRITE resize DESIGNABLE false STORED false)
- Q_PROPERTY(int width READ width)
- Q_PROPERTY(int height READ height)
- Q_PROPERTY(QRect rect READ rect)
- Q_PROPERTY(QRect childrenRect READ childrenRect)
- Q_PROPERTY(QRegion childrenRegion READ childrenRegion)
- Q_PROPERTY(QSizePolicy sizePolicy READ sizePolicy WRITE setSizePolicy)
- Q_PROPERTY(QSize minimumSize READ minimumSize WRITE setMinimumSize)
- Q_PROPERTY(QSize maximumSize READ maximumSize WRITE setMaximumSize)
- Q_PROPERTY(int minimumWidth READ minimumWidth WRITE setMinimumWidth STORED false DESIGNABLE false)
- Q_PROPERTY(int minimumHeight READ minimumHeight WRITE setMinimumHeight STORED false DESIGNABLE false)
- Q_PROPERTY(int maximumWidth READ maximumWidth WRITE setMaximumWidth STORED false DESIGNABLE false)
- Q_PROPERTY(int maximumHeight READ maximumHeight WRITE setMaximumHeight STORED false DESIGNABLE false)
- Q_PROPERTY(QSize sizeIncrement READ sizeIncrement WRITE setSizeIncrement)
- Q_PROPERTY(QSize baseSize READ baseSize WRITE setBaseSize)
- Q_PROPERTY(QPalette palette READ palette WRITE setPalette)
- Q_PROPERTY(QFont font READ font WRITE setFont)
-#ifndef QT_NO_CURSOR
- Q_PROPERTY(QCursor cursor READ cursor WRITE setCursor RESET unsetCursor)
-#endif
- Q_PROPERTY(bool mouseTracking READ hasMouseTracking WRITE setMouseTracking)
- Q_PROPERTY(bool isActiveWindow READ isActiveWindow)
- Q_PROPERTY(Qt::FocusPolicy focusPolicy READ focusPolicy WRITE setFocusPolicy)
- Q_PROPERTY(bool focus READ hasFocus)
- Q_PROPERTY(Qt::ContextMenuPolicy contextMenuPolicy READ contextMenuPolicy WRITE setContextMenuPolicy)
- Q_PROPERTY(bool updatesEnabled READ updatesEnabled WRITE setUpdatesEnabled DESIGNABLE false)
- Q_PROPERTY(bool visible READ isVisible WRITE setVisible DESIGNABLE false)
- Q_PROPERTY(bool minimized READ isMinimized)
- Q_PROPERTY(bool maximized READ isMaximized)
- Q_PROPERTY(bool fullScreen READ isFullScreen)
- Q_PROPERTY(QSize sizeHint READ sizeHint)
- Q_PROPERTY(QSize minimumSizeHint READ minimumSizeHint)
- Q_PROPERTY(bool acceptDrops READ acceptDrops WRITE setAcceptDrops)
- Q_PROPERTY(QString windowTitle READ windowTitle WRITE setWindowTitle DESIGNABLE isWindow)
- Q_PROPERTY(QIcon windowIcon READ windowIcon WRITE setWindowIcon DESIGNABLE isWindow)
- Q_PROPERTY(QString windowIconText READ windowIconText WRITE setWindowIconText DESIGNABLE isWindow)
- Q_PROPERTY(double windowOpacity READ windowOpacity WRITE setWindowOpacity DESIGNABLE isWindow)
- Q_PROPERTY(bool windowModified READ isWindowModified WRITE setWindowModified DESIGNABLE isWindow)
-#ifndef QT_NO_TOOLTIP
- Q_PROPERTY(QString toolTip READ toolTip WRITE setToolTip)
-#endif
-#ifndef QT_NO_STATUSTIP
- Q_PROPERTY(QString statusTip READ statusTip WRITE setStatusTip)
-#endif
-#ifndef QT_NO_WHATSTHIS
- Q_PROPERTY(QString whatsThis READ whatsThis WRITE setWhatsThis)
-#endif
-#ifndef QT_NO_ACCESSIBILITY
- Q_PROPERTY(QString accessibleName READ accessibleName WRITE setAccessibleName)
- Q_PROPERTY(QString accessibleDescription READ accessibleDescription WRITE setAccessibleDescription)
-#endif
- Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection RESET unsetLayoutDirection)
- QDOC_PROPERTY(Qt::WindowFlags windowFlags READ windowFlags WRITE setWindowFlags)
- Q_PROPERTY(bool autoFillBackground READ autoFillBackground WRITE setAutoFillBackground)
-#ifndef QT_NO_STYLE_STYLESHEET
- Q_PROPERTY(QString styleSheet READ styleSheet WRITE setStyleSheet)
-#endif
- Q_PROPERTY(QLocale locale READ locale WRITE setLocale RESET unsetLocale)
- Q_PROPERTY(QString windowFilePath READ windowFilePath WRITE setWindowFilePath DESIGNABLE isWindow)
- Q_PROPERTY(Qt::InputMethodHints inputMethodHints READ inputMethodHints WRITE setInputMethodHints)
-
-public:
- enum RenderFlag {
- DrawWindowBackground = 0x1,
- DrawChildren = 0x2,
- IgnoreMask = 0x4
- };
- Q_DECLARE_FLAGS(RenderFlags, RenderFlag)
-
- explicit QWidget(QWidget* parent = 0, Qt::WindowFlags f = 0);
-#ifdef QT3_SUPPORT
- QT3_SUPPORT_CONSTRUCTOR QWidget(QWidget* parent, const char *name, Qt::WindowFlags f = 0);
-#endif
- ~QWidget();
-
- int devType() const;
-
- WId winId() const;
- void createWinId(); // internal, going away
- inline WId internalWinId() const { return data->winid; }
- WId effectiveWinId() const;
-
- // GUI style setting
- QStyle *style() const;
- void setStyle(QStyle *);
- // Widget types and states
-
- bool isTopLevel() const;
- bool isWindow() const;
-
- bool isModal() const;
- Qt::WindowModality windowModality() const;
- void setWindowModality(Qt::WindowModality windowModality);
-
- bool isEnabled() const;
- bool isEnabledTo(QWidget*) const;
- bool isEnabledToTLW() const;
-
-public Q_SLOTS:
- void setEnabled(bool);
- void setDisabled(bool);
- void setWindowModified(bool);
-
- // Widget coordinates
-
-public:
- QRect frameGeometry() const;
- const QRect &geometry() const;
- QRect normalGeometry() const;
-
- int x() const;
- int y() const;
- QPoint pos() const;
- QSize frameSize() const;
- QSize size() const;
- inline int width() const;
- inline int height() const;
- inline QRect rect() const;
- QRect childrenRect() const;
- QRegion childrenRegion() const;
-
- QSize minimumSize() const;
- QSize maximumSize() const;
- int minimumWidth() const;
- int minimumHeight() const;
- int maximumWidth() const;
- int maximumHeight() const;
- void setMinimumSize(const QSize &);
- void setMinimumSize(int minw, int minh);
- void setMaximumSize(const QSize &);
- void setMaximumSize(int maxw, int maxh);
- void setMinimumWidth(int minw);
- void setMinimumHeight(int minh);
- void setMaximumWidth(int maxw);
- void setMaximumHeight(int maxh);
-
-#ifdef Q_QDOC
- void setupUi(QWidget *widget);
-#endif
-
- QSize sizeIncrement() const;
- void setSizeIncrement(const QSize &);
- void setSizeIncrement(int w, int h);
- QSize baseSize() const;
- void setBaseSize(const QSize &);
- void setBaseSize(int basew, int baseh);
-
- void setFixedSize(const QSize &);
- void setFixedSize(int w, int h);
- void setFixedWidth(int w);
- void setFixedHeight(int h);
-
- // Widget coordinate mapping
-
- QPoint mapToGlobal(const QPoint &) const;
- QPoint mapFromGlobal(const QPoint &) const;
- QPoint mapToParent(const QPoint &) const;
- QPoint mapFromParent(const QPoint &) const;
- QPoint mapTo(QWidget *, const QPoint &) const;
- QPoint mapFrom(QWidget *, const QPoint &) const;
-
- QWidget *window() const;
- QWidget *nativeParentWidget() const;
- inline QWidget *topLevelWidget() const { return window(); }
-
- // Widget appearance functions
- const QPalette &palette() const;
- void setPalette(const QPalette &);
-
- void setBackgroundRole(QPalette::ColorRole);
- QPalette::ColorRole backgroundRole() const;
-
- void setForegroundRole(QPalette::ColorRole);
- QPalette::ColorRole foregroundRole() const;
-
- const QFont &font() const;
- void setFont(const QFont &);
- QFontMetrics fontMetrics() const;
- QFontInfo fontInfo() const;
-
-#ifndef QT_NO_CURSOR
- QCursor cursor() const;
- void setCursor(const QCursor &);
- void unsetCursor();
-#endif
-
- void setMouseTracking(bool enable);
- bool hasMouseTracking() const;
- bool underMouse() const;
-
- void setMask(const QBitmap &);
- void setMask(const QRegion &);
- QRegion mask() const;
- void clearMask();
-
- void render(QPaintDevice *target, const QPoint &targetOffset = QPoint(),
- const QRegion &sourceRegion = QRegion(),
- RenderFlags renderFlags = RenderFlags(DrawWindowBackground | DrawChildren));
-
- void render(QPainter *painter, const QPoint &targetOffset = QPoint(),
- const QRegion &sourceRegion = QRegion(),
- RenderFlags renderFlags = RenderFlags(DrawWindowBackground | DrawChildren));
-
-#ifndef QT_NO_GRAPHICSEFFECT
- QGraphicsEffect *graphicsEffect() const;
- void setGraphicsEffect(QGraphicsEffect *effect);
-#endif //QT_NO_GRAPHICSEFFECT
-
-#ifndef QT_NO_GESTURES
- void grabGesture(Qt::GestureType type, Qt::GestureFlags flags = Qt::GestureFlags());
- void ungrabGesture(Qt::GestureType type);
-#endif
-
-public Q_SLOTS:
- void setWindowTitle(const QString &);
-#ifndef QT_NO_STYLE_STYLESHEET
- void setStyleSheet(const QString& styleSheet);
-#endif
-public:
-#ifndef QT_NO_STYLE_STYLESHEET
- QString styleSheet() const;
-#endif
- QString windowTitle() const;
- void setWindowIcon(const QIcon &icon);
- QIcon windowIcon() const;
- void setWindowIconText(const QString &);
- QString windowIconText() const;
- void setWindowRole(const QString &);
- QString windowRole() const;
- void setWindowFilePath(const QString &filePath);
- QString windowFilePath() const;
-
- void setWindowOpacity(qreal level);
- qreal windowOpacity() const;
-
- bool isWindowModified() const;
-#ifndef QT_NO_TOOLTIP
- void setToolTip(const QString &);
- QString toolTip() const;
-#endif
-#ifndef QT_NO_STATUSTIP
- void setStatusTip(const QString &);
- QString statusTip() const;
-#endif
-#ifndef QT_NO_WHATSTHIS
- void setWhatsThis(const QString &);
- QString whatsThis() const;
-#endif
-#ifndef QT_NO_ACCESSIBILITY
- QString accessibleName() const;
- void setAccessibleName(const QString &name);
- QString accessibleDescription() const;
- void setAccessibleDescription(const QString &description);
-#endif
-
- void setLayoutDirection(Qt::LayoutDirection direction);
- Qt::LayoutDirection layoutDirection() const;
- void unsetLayoutDirection();
-
- void setLocale(const QLocale &locale);
- QLocale locale() const;
- void unsetLocale();
-
- inline bool isRightToLeft() const { return layoutDirection() == Qt::RightToLeft; }
- inline bool isLeftToRight() const { return layoutDirection() == Qt::LeftToRight; }
-
-public Q_SLOTS:
- inline void setFocus() { setFocus(Qt::OtherFocusReason); }
-
-public:
- bool isActiveWindow() const;
- void activateWindow();
- void clearFocus();
-
- void setFocus(Qt::FocusReason reason);
- Qt::FocusPolicy focusPolicy() const;
- void setFocusPolicy(Qt::FocusPolicy policy);
- bool hasFocus() const;
- static void setTabOrder(QWidget *, QWidget *);
- void setFocusProxy(QWidget *);
- QWidget *focusProxy() const;
- Qt::ContextMenuPolicy contextMenuPolicy() const;
- void setContextMenuPolicy(Qt::ContextMenuPolicy policy);
-
- // Grab functions
- void grabMouse();
-#ifndef QT_NO_CURSOR
- void grabMouse(const QCursor &);
-#endif
- void releaseMouse();
- void grabKeyboard();
- void releaseKeyboard();
-#ifndef QT_NO_SHORTCUT
- int grabShortcut(const QKeySequence &key, Qt::ShortcutContext context = Qt::WindowShortcut);
- void releaseShortcut(int id);
- void setShortcutEnabled(int id, bool enable = true);
- void setShortcutAutoRepeat(int id, bool enable = true);
-#endif
- static QWidget *mouseGrabber();
- static QWidget *keyboardGrabber();
-
- // Update/refresh functions
- inline bool updatesEnabled() const;
- void setUpdatesEnabled(bool enable);
-
-#if 0 //def Q_WS_QWS
- void repaintUnclipped(const QRegion &, bool erase = true);
-#endif
-
-#ifndef QT_NO_GRAPHICSVIEW
- QGraphicsProxyWidget *graphicsProxyWidget() const;
-#endif
-
-public Q_SLOTS:
- void update();
- void repaint();
-
-public:
- inline void update(int x, int y, int w, int h);
- void update(const QRect&);
- void update(const QRegion&);
-
- void repaint(int x, int y, int w, int h);
- void repaint(const QRect &);
- void repaint(const QRegion &);
-
-public Q_SLOTS:
- // Widget management functions
-
- virtual void setVisible(bool visible);
- inline void setHidden(bool hidden) { setVisible(!hidden); }
-#ifndef Q_WS_WINCE
- inline void show() { setVisible(true); }
-#else
- void show();
-#endif
- inline void hide() { setVisible(false); }
- inline QT_MOC_COMPAT void setShown(bool shown) { setVisible(shown); }
-
- void showMinimized();
- void showMaximized();
- void showFullScreen();
- void showNormal();
-
- bool close();
- void raise();
- void lower();
-
-public:
- void stackUnder(QWidget*);
- void move(int x, int y);
- void move(const QPoint &);
- void resize(int w, int h);
- void resize(const QSize &);
- inline void setGeometry(int x, int y, int w, int h);
- void setGeometry(const QRect &);
- QByteArray saveGeometry() const;
- bool restoreGeometry(const QByteArray &geometry);
- void adjustSize();
- bool isVisible() const;
- bool isVisibleTo(QWidget*) const;
- // ### Qt 5: bool isVisibleTo(_const_ QWidget *) const
- inline bool isHidden() const;
-
- bool isMinimized() const;
- bool isMaximized() const;
- bool isFullScreen() const;
-
- Qt::WindowStates windowState() const;
- void setWindowState(Qt::WindowStates state);
- void overrideWindowState(Qt::WindowStates state);
-
- virtual QSize sizeHint() const;
- virtual QSize minimumSizeHint() const;
-
- QSizePolicy sizePolicy() const;
- void setSizePolicy(QSizePolicy);
- inline void setSizePolicy(QSizePolicy::Policy horizontal, QSizePolicy::Policy vertical);
- virtual int heightForWidth(int) const;
-
- QRegion visibleRegion() const;
-
- void setContentsMargins(int left, int top, int right, int bottom);
- void setContentsMargins(const QMargins &margins);
- void getContentsMargins(int *left, int *top, int *right, int *bottom) const;
- QMargins contentsMargins() const;
-
- QRect contentsRect() const;
-
-public:
- QLayout *layout() const;
- void setLayout(QLayout *);
- void updateGeometry();
-
- void setParent(QWidget *parent);
- void setParent(QWidget *parent, Qt::WindowFlags f);
-
- void scroll(int dx, int dy);
- void scroll(int dx, int dy, const QRect&);
-
- // Misc. functions
-
- QWidget *focusWidget() const;
- QWidget *nextInFocusChain() const;
- QWidget *previousInFocusChain() const;
-
- // drag and drop
- bool acceptDrops() const;
- void setAcceptDrops(bool on);
-
-#ifndef QT_NO_ACTION
- //actions
- void addAction(QAction *action);
- void addActions(QList<QAction*> actions);
- void insertAction(QAction *before, QAction *action);
- void insertActions(QAction *before, QList<QAction*> actions);
- void removeAction(QAction *action);
- QList<QAction*> actions() const;
-#endif
-
- QWidget *parentWidget() const;
-
- void setWindowFlags(Qt::WindowFlags type);
- inline Qt::WindowFlags windowFlags() const;
- void overrideWindowFlags(Qt::WindowFlags type);
-
- inline Qt::WindowType windowType() const;
-
- static QWidget *find(WId);
-#ifdef QT3_SUPPORT
- static QT3_SUPPORT QWidgetMapper *wmapper();
-#endif
- inline QWidget *childAt(int x, int y) const;
- QWidget *childAt(const QPoint &p) const;
-
-#if defined(Q_WS_X11)
- const QX11Info &x11Info() const;
- Qt::HANDLE x11PictureHandle() const;
-#endif
-
-#if defined(Q_WS_MAC)
- Qt::HANDLE macQDHandle() const;
- Qt::HANDLE macCGHandle() const;
-#endif
-
-#if defined(Q_WS_WIN)
- HDC getDC() const;
- void releaseDC(HDC) const;
-#else
- Qt::HANDLE handle() const;
-#endif
-
- void setAttribute(Qt::WidgetAttribute, bool on = true);
- inline bool testAttribute(Qt::WidgetAttribute) const;
-
- QPaintEngine *paintEngine() const;
-
- void ensurePolished() const;
-
- QInputContext *inputContext();
- void setInputContext(QInputContext *);
-
- bool isAncestorOf(const QWidget *child) const;
-
-#ifdef QT_KEYPAD_NAVIGATION
- bool hasEditFocus() const;
- void setEditFocus(bool on);
-#endif
-
- bool autoFillBackground() const;
- void setAutoFillBackground(bool enabled);
-
- void setWindowSurface(QWindowSurface *surface);
- QWindowSurface *windowSurface() const;
-
-#if defined(Q_WS_QPA)
- void setPlatformWindow(QPlatformWindow *window);
- QPlatformWindow *platformWindow() const;
-
- void setPlatformWindowFormat(const QPlatformWindowFormat &format);
- QPlatformWindowFormat platformWindowFormat() const;
-
- friend class QDesktopScreenWidget;
-#endif
-
-Q_SIGNALS:
- void customContextMenuRequested(const QPoint &pos);
-
-protected:
- // Event handlers
- bool event(QEvent *);
- virtual void mousePressEvent(QMouseEvent *);
- virtual void mouseReleaseEvent(QMouseEvent *);
- virtual void mouseDoubleClickEvent(QMouseEvent *);
- virtual void mouseMoveEvent(QMouseEvent *);
-#ifndef QT_NO_WHEELEVENT
- virtual void wheelEvent(QWheelEvent *);
-#endif
- virtual void keyPressEvent(QKeyEvent *);
- virtual void keyReleaseEvent(QKeyEvent *);
- virtual void focusInEvent(QFocusEvent *);
- virtual void focusOutEvent(QFocusEvent *);
- virtual void enterEvent(QEvent *);
- virtual void leaveEvent(QEvent *);
- virtual void paintEvent(QPaintEvent *);
- virtual void moveEvent(QMoveEvent *);
- virtual void resizeEvent(QResizeEvent *);
- virtual void closeEvent(QCloseEvent *);
-#ifndef QT_NO_CONTEXTMENU
- virtual void contextMenuEvent(QContextMenuEvent *);
-#endif
-#ifndef QT_NO_TABLETEVENT
- virtual void tabletEvent(QTabletEvent *);
-#endif
-#ifndef QT_NO_ACTION
- virtual void actionEvent(QActionEvent *);
-#endif
-
-#ifndef QT_NO_DRAGANDDROP
- virtual void dragEnterEvent(QDragEnterEvent *);
- virtual void dragMoveEvent(QDragMoveEvent *);
- virtual void dragLeaveEvent(QDragLeaveEvent *);
- virtual void dropEvent(QDropEvent *);
-#endif
-
- virtual void showEvent(QShowEvent *);
- virtual void hideEvent(QHideEvent *);
-
-#if defined(Q_WS_MAC)
- virtual bool macEvent(EventHandlerCallRef, EventRef);
-#endif
-#if defined(Q_WS_WIN)
- virtual bool winEvent(MSG *message, long *result);
-#endif
-#if defined(Q_WS_X11)
- virtual bool x11Event(XEvent *);
-#endif
-#if defined(Q_WS_QWS)
- virtual bool qwsEvent(QWSEvent *);
-#endif
-
- // Misc. protected functions
- virtual void changeEvent(QEvent *);
-
- int metric(PaintDeviceMetric) const;
-
- virtual void inputMethodEvent(QInputMethodEvent *);
-public:
- virtual QVariant inputMethodQuery(Qt::InputMethodQuery) const;
-
- Qt::InputMethodHints inputMethodHints() const;
- void setInputMethodHints(Qt::InputMethodHints hints);
-
-protected:
- void resetInputContext();
-protected Q_SLOTS:
- void updateMicroFocus();
-protected:
-
- void create(WId = 0, bool initializeWindow = true,
- bool destroyOldWindow = true);
- void destroy(bool destroyWindow = true,
- bool destroySubWindows = true);
-
- virtual bool focusNextPrevChild(bool next);
- inline bool focusNextChild() { return focusNextPrevChild(true); }
- inline bool focusPreviousChild() { return focusNextPrevChild(false); }
-
-protected:
- QWidget(QWidgetPrivate &d, QWidget* parent, Qt::WindowFlags f);
-private:
-
- bool testAttribute_helper(Qt::WidgetAttribute) const;
-
- QLayout *takeLayout();
-
- friend class QBackingStoreDevice;
- friend class QWidgetBackingStore;
- friend class QApplication;
- friend class QApplicationPrivate;
- friend class QBaseApplication;
- friend class QPainter;
- friend class QPainterPrivate;
- friend class QPixmap; // for QPixmap::fill()
- friend class QFontMetrics;
- friend class QFontInfo;
- friend class QETWidget;
- friend class QLayout;
- friend class QWidgetItem;
- friend class QWidgetItemV2;
- friend class QGLContext;
- friend class QGLWidget;
- friend class QGLWindowSurface;
- friend class QX11PaintEngine;
- friend class QWin32PaintEngine;
- friend class QShortcutPrivate;
- friend class QShortcutMap;
- friend class QWindowSurface;
- friend class QGraphicsProxyWidget;
- friend class QGraphicsProxyWidgetPrivate;
- friend class QStyleSheetStyle;
- friend struct QWidgetExceptionCleaner;
-#ifndef QT_NO_GESTURES
- friend class QGestureManager;
- friend class QWinNativePanGestureRecognizer;
-#endif // QT_NO_GESTURES
- friend class QWidgetEffectSourcePrivate;
-
-#ifdef Q_WS_MAC
- friend class QCoreGraphicsPaintEnginePrivate;
- friend QPoint qt_mac_posInWindow(const QWidget *w);
- friend OSWindowRef qt_mac_window_for(const QWidget *w);
- friend bool qt_mac_is_metal(const QWidget *w);
- friend OSViewRef qt_mac_nativeview_for(const QWidget *w);
- friend void qt_event_request_window_change(QWidget *widget);
- friend bool qt_mac_sendMacEventToWidget(QWidget *widget, EventRef ref);
- friend class QRasterWindowSurface;
- friend class QUnifiedToolbarSurface;
-#endif
-#ifdef Q_WS_QWS
- friend class QWSBackingStore;
- friend class QWSManager;
- friend class QWSManagerPrivate;
- friend class QDecoration;
- friend class QWSWindowSurface;
- friend class QScreen;
- friend class QVNCScreen;
- friend bool isWidgetOpaque(const QWidget *);
- friend class QGLWidgetPrivate;
-#endif
-#ifdef Q_OS_SYMBIAN
- friend class QSymbianControl;
- friend class QS60WindowSurface;
-#endif
-#ifdef Q_WS_X11
- friend void qt_net_update_user_time(QWidget *tlw, unsigned long timestamp);
- friend void qt_net_remove_user_time(QWidget *tlw);
- friend void qt_set_winid_on_widget(QWidget*, Qt::HANDLE);
-#endif
-
- friend Q_GUI_EXPORT QWidgetData *qt_qwidget_data(QWidget *widget);
- friend Q_GUI_EXPORT QWidgetPrivate *qt_widget_private(QWidget *widget);
-
-private:
- Q_DISABLE_COPY(QWidget)
- Q_PRIVATE_SLOT(d_func(), void _q_showIfNotHidden())
-#ifdef Q_OS_SYMBIAN
- Q_PRIVATE_SLOT(d_func(), void _q_delayedDestroy(WId winId))
-#endif
-
- QWidgetData *data;
-
-#ifdef QT3_SUPPORT
-public:
- inline QT3_SUPPORT bool isUpdatesEnabled() const { return updatesEnabled(); }
- QT3_SUPPORT QStyle *setStyle(const QString&);
- inline QT3_SUPPORT bool isVisibleToTLW() const;
- QT3_SUPPORT QRect visibleRect() const;
- inline QT3_SUPPORT void iconify() { showMinimized(); }
- inline QT3_SUPPORT void constPolish() const { ensurePolished(); }
- inline QT3_SUPPORT void polish() { ensurePolished(); }
- inline QT3_SUPPORT void reparent(QWidget *parent, Qt::WindowFlags f, const QPoint &p, bool showIt=false)
- { setParent(parent, f); setGeometry(p.x(),p.y(),width(),height()); if (showIt) show(); }
- inline QT3_SUPPORT void reparent(QWidget *parent, const QPoint &p, bool showIt=false)
- { setParent(parent, windowFlags() & ~Qt::WindowType_Mask); setGeometry(p.x(),p.y(),width(),height()); if (showIt) show(); }
- inline QT3_SUPPORT void recreate(QWidget *parent, Qt::WindowFlags f, const QPoint & p, bool showIt=false)
- { setParent(parent, f); setGeometry(p.x(),p.y(),width(),height()); if (showIt) show(); }
- inline QT3_SUPPORT void setSizePolicy(QSizePolicy::Policy hor, QSizePolicy::Policy ver, bool hfw)
- { QSizePolicy sp(hor, ver); sp.setHeightForWidth(hfw); setSizePolicy(sp);}
- inline QT3_SUPPORT bool hasMouse() const { return testAttribute(Qt::WA_UnderMouse); }
-#ifndef QT_NO_CURSOR
- inline QT3_SUPPORT bool ownCursor() const { return testAttribute(Qt::WA_SetCursor); }
-#endif
- inline QT3_SUPPORT bool ownFont() const { return testAttribute(Qt::WA_SetFont); }
- inline QT3_SUPPORT void unsetFont() { setFont(QFont()); }
- inline QT3_SUPPORT bool ownPalette() const { return testAttribute(Qt::WA_SetPalette); }
- inline QT3_SUPPORT void unsetPalette() { setPalette(QPalette()); }
- Qt::BackgroundMode QT3_SUPPORT backgroundMode() const;
- void QT3_SUPPORT setBackgroundMode(Qt::BackgroundMode, Qt::BackgroundMode = Qt::PaletteBackground);
- const QT3_SUPPORT QColor &eraseColor() const;
- void QT3_SUPPORT setEraseColor(const QColor &);
- const QT3_SUPPORT QColor &foregroundColor() const;
- const QT3_SUPPORT QPixmap *erasePixmap() const;
- void QT3_SUPPORT setErasePixmap(const QPixmap &);
- const QT3_SUPPORT QColor &paletteForegroundColor() const;
- void QT3_SUPPORT setPaletteForegroundColor(const QColor &);
- const QT3_SUPPORT QColor &paletteBackgroundColor() const;
- void QT3_SUPPORT setPaletteBackgroundColor(const QColor &);
- const QT3_SUPPORT QPixmap *paletteBackgroundPixmap() const;
- void QT3_SUPPORT setPaletteBackgroundPixmap(const QPixmap &);
- const QT3_SUPPORT QBrush& backgroundBrush() const;
- const QT3_SUPPORT QColor &backgroundColor() const;
- const QT3_SUPPORT QPixmap *backgroundPixmap() const;
- void QT3_SUPPORT setBackgroundPixmap(const QPixmap &);
- QT3_SUPPORT void setBackgroundColor(const QColor &);
- QT3_SUPPORT QColorGroup colorGroup() const;
- QT3_SUPPORT QWidget *parentWidget(bool sameWindow) const;
- inline QT3_SUPPORT void setKeyCompression(bool b) { setAttribute(Qt::WA_KeyCompression, b); }
- inline QT3_SUPPORT void setFont(const QFont &f, bool) { setFont(f); }
- inline QT3_SUPPORT void setPalette(const QPalette &p, bool) { setPalette(p); }
- enum BackgroundOrigin { WidgetOrigin, ParentOrigin, WindowOrigin, AncestorOrigin };
- inline QT3_SUPPORT void setBackgroundOrigin(BackgroundOrigin) {}
- inline QT3_SUPPORT BackgroundOrigin backgroundOrigin() const { return WindowOrigin; }
- inline QT3_SUPPORT QPoint backgroundOffset() const { return QPoint(); }
- inline QT3_SUPPORT void repaint(bool) { repaint(); }
- inline QT3_SUPPORT void repaint(int x, int y, int w, int h, bool) { repaint(x,y,w,h); }
- inline QT3_SUPPORT void repaint(const QRect &r, bool) { repaint(r); }
- inline QT3_SUPPORT void repaint(const QRegion &rgn, bool) { repaint(rgn); }
- QT3_SUPPORT void erase();
- inline QT3_SUPPORT void erase(int x, int y, int w, int h) { erase_helper(x, y, w, h); }
- QT3_SUPPORT void erase(const QRect &);
- QT3_SUPPORT void erase(const QRegion &);
- QT3_SUPPORT void drawText(const QPoint &p, const QString &s)
- { drawText_helper(p.x(), p.y(), s); }
- inline QT3_SUPPORT void drawText(int x, int y, const QString &s)
- { drawText_helper(x, y, s); }
- QT3_SUPPORT bool close(bool);
- inline QT3_SUPPORT QWidget *childAt(int x, int y, bool includeThis) const
- {
- QWidget *w = childAt(x, y);
- return w ? w : ((includeThis && rect().contains(x,y))?const_cast<QWidget*>(this):0);
- }
- inline QT3_SUPPORT QWidget *childAt(const QPoint &p, bool includeThis) const
- {
- QWidget *w = childAt(p);
- return w ? w : ((includeThis && rect().contains(p))?const_cast<QWidget*>(this):0);
- }
- inline QT3_SUPPORT void setCaption(const QString &c) { setWindowTitle(c); }
- QT3_SUPPORT void setIcon(const QPixmap &i);
- inline QT3_SUPPORT void setIconText(const QString &it) { setWindowIconText(it); }
- inline QT3_SUPPORT QString caption() const { return windowTitle(); }
- QT3_SUPPORT const QPixmap *icon() const;
- inline QT3_SUPPORT QString iconText() const { return windowIconText(); }
- inline QT3_SUPPORT void setInputMethodEnabled(bool b) { setAttribute(Qt::WA_InputMethodEnabled, b); }
- inline QT3_SUPPORT bool isInputMethodEnabled() const { return testAttribute(Qt::WA_InputMethodEnabled); }
- inline QT3_SUPPORT void setActiveWindow() { activateWindow(); }
- inline QT3_SUPPORT bool isShown() const { return !isHidden(); }
- inline QT3_SUPPORT bool isDialog() const { return windowType() == Qt::Dialog; }
- inline QT3_SUPPORT bool isPopup() const { return windowType() == Qt::Popup; }
- inline QT3_SUPPORT bool isDesktop() const { return windowType() == Qt::Desktop; }
-
-
-private:
- void drawText_helper(int x, int y, const QString &);
- void erase_helper(int x, int y, int w, int h);
-#endif // QT3_SUPPORT
-
-protected:
- virtual void styleChange(QStyle&); // compat
- virtual void enabledChange(bool); // compat
- virtual void paletteChange(const QPalette &); // compat
- virtual void fontChange(const QFont &); // compat
- virtual void windowActivationChange(bool); // compat
- virtual void languageChange(); // compat
-};
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QWidget::RenderFlags)
-
-template <> inline QWidget *qobject_cast<QWidget*>(QObject *o)
-{
- if (!o || !o->isWidgetType()) return 0;
- return static_cast<QWidget*>(o);
-}
-template <> inline const QWidget *qobject_cast<const QWidget*>(const QObject *o)
-{
- if (!o || !o->isWidgetType()) return 0;
- return static_cast<const QWidget*>(o);
-}
-
-inline QWidget *QWidget::childAt(int ax, int ay) const
-{ return childAt(QPoint(ax, ay)); }
-
-inline Qt::WindowType QWidget::windowType() const
-{ return static_cast<Qt::WindowType>(int(data->window_flags & Qt::WindowType_Mask)); }
-inline Qt::WindowFlags QWidget::windowFlags() const
-{ return data->window_flags; }
-
-inline bool QWidget::isTopLevel() const
-{ return (windowType() & Qt::Window); }
-
-inline bool QWidget::isWindow() const
-{ return (windowType() & Qt::Window); }
-
-inline bool QWidget::isEnabled() const
-{ return !testAttribute(Qt::WA_Disabled); }
-
-inline bool QWidget::isModal() const
-{ return data->window_modality != Qt::NonModal; }
-
-inline bool QWidget::isEnabledToTLW() const
-{ return isEnabled(); }
-
-inline int QWidget::minimumWidth() const
-{ return minimumSize().width(); }
-
-inline int QWidget::minimumHeight() const
-{ return minimumSize().height(); }
-
-inline int QWidget::maximumWidth() const
-{ return maximumSize().width(); }
-
-inline int QWidget::maximumHeight() const
-{ return maximumSize().height(); }
-
-inline void QWidget::setMinimumSize(const QSize &s)
-{ setMinimumSize(s.width(),s.height()); }
-
-inline void QWidget::setMaximumSize(const QSize &s)
-{ setMaximumSize(s.width(),s.height()); }
-
-inline void QWidget::setSizeIncrement(const QSize &s)
-{ setSizeIncrement(s.width(),s.height()); }
-
-inline void QWidget::setBaseSize(const QSize &s)
-{ setBaseSize(s.width(),s.height()); }
-
-inline const QFont &QWidget::font() const
-{ return data->fnt; }
-
-inline QFontMetrics QWidget::fontMetrics() const
-{ return QFontMetrics(data->fnt); }
-
-inline QFontInfo QWidget::fontInfo() const
-{ return QFontInfo(data->fnt); }
-
-inline void QWidget::setMouseTracking(bool enable)
-{ setAttribute(Qt::WA_MouseTracking, enable); }
-
-inline bool QWidget::hasMouseTracking() const
-{ return testAttribute(Qt::WA_MouseTracking); }
-
-inline bool QWidget::underMouse() const
-{ return testAttribute(Qt::WA_UnderMouse); }
-
-inline bool QWidget::updatesEnabled() const
-{ return !testAttribute(Qt::WA_UpdatesDisabled); }
-
-inline void QWidget::update(int ax, int ay, int aw, int ah)
-{ update(QRect(ax, ay, aw, ah)); }
-
-inline bool QWidget::isVisible() const
-{ return testAttribute(Qt::WA_WState_Visible); }
-
-inline bool QWidget::isHidden() const
-{ return testAttribute(Qt::WA_WState_Hidden); }
-
-inline void QWidget::move(int ax, int ay)
-{ move(QPoint(ax, ay)); }
-
-inline void QWidget::resize(int w, int h)
-{ resize(QSize(w, h)); }
-
-inline void QWidget::setGeometry(int ax, int ay, int aw, int ah)
-{ setGeometry(QRect(ax, ay, aw, ah)); }
-
-inline QRect QWidget::rect() const
-{ return QRect(0,0,data->crect.width(),data->crect.height()); }
-
-inline const QRect &QWidget::geometry() const
-{ return data->crect; }
-
-inline QSize QWidget::size() const
-{ return data->crect.size(); }
-
-inline int QWidget::width() const
-{ return data->crect.width(); }
-
-inline int QWidget::height() const
-{ return data->crect.height(); }
-
-inline QWidget *QWidget::parentWidget() const
-{ return static_cast<QWidget *>(QObject::parent()); }
-
-inline void QWidget::setSizePolicy(QSizePolicy::Policy hor, QSizePolicy::Policy ver)
-{ setSizePolicy(QSizePolicy(hor, ver)); }
-
-inline bool QWidget::testAttribute(Qt::WidgetAttribute attribute) const
-{
- if (attribute < int(8*sizeof(uint)))
- return data->widget_attributes & (1<<attribute);
- return testAttribute_helper(attribute);
-}
-
-#ifdef QT3_SUPPORT
-inline bool QWidget::isVisibleToTLW() const
-{ return isVisible(); }
-inline QWidget *QWidget::parentWidget(bool sameWindow) const
-{
- if (sameWindow && isWindow())
- return 0;
- return static_cast<QWidget *>(QObject::parent());
-}
-inline QColorGroup QWidget::colorGroup() const
-{ return QColorGroup(palette()); }
-inline void QWidget::setPaletteForegroundColor(const QColor &c)
-{ QPalette p = palette(); p.setColor(foregroundRole(), c); setPalette(p); }
-inline const QBrush& QWidget::backgroundBrush() const { return palette().brush(backgroundRole()); }
-inline void QWidget::setBackgroundPixmap(const QPixmap &pm)
-{ QPalette p = palette(); p.setBrush(backgroundRole(), QBrush(pm)); setPalette(p); }
-inline const QPixmap *QWidget::backgroundPixmap() const { return 0; }
-inline void QWidget::setBackgroundColor(const QColor &c)
-{ QPalette p = palette(); p.setColor(backgroundRole(), c); setPalette(p); }
-inline const QColor & QWidget::backgroundColor() const { return palette().color(backgroundRole()); }
-inline const QColor &QWidget::foregroundColor() const { return palette().color(foregroundRole());}
-inline const QColor &QWidget::eraseColor() const { return palette().color(backgroundRole()); }
-inline void QWidget::setEraseColor(const QColor &c)
-{ QPalette p = palette(); p.setColor(backgroundRole(), c); setPalette(p); }
-inline const QPixmap *QWidget::erasePixmap() const { return 0; }
-inline void QWidget::setErasePixmap(const QPixmap &pm)
-{ QPalette p = palette(); p.setBrush(backgroundRole(), QBrush(pm)); setPalette(p); }
-inline const QColor &QWidget::paletteForegroundColor() const { return palette().color(foregroundRole());}
-inline const QColor &QWidget::paletteBackgroundColor() const { return palette().color(backgroundRole()); }
-inline void QWidget::setPaletteBackgroundColor(const QColor &c)
-{ QPalette p = palette(); p.setColor(backgroundRole(), c); setPalette(p); }
-inline const QPixmap *QWidget::paletteBackgroundPixmap() const
-{ return 0; }
-inline void QWidget::setPaletteBackgroundPixmap(const QPixmap &pm)
-{ QPalette p = palette(); p.setBrush(backgroundRole(), QBrush(pm)); setPalette(p); }
-inline QT3_SUPPORT void QWidget::erase() { erase_helper(0, 0, data->crect.width(), data->crect.height()); }
-inline QT3_SUPPORT void QWidget::erase(const QRect &r) { erase_helper(r.x(), r.y(), r.width(), r.height()); }
-#endif
-
-#define QWIDGETSIZE_MAX ((1<<24)-1)
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QWIDGET_H
diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h
deleted file mode 100644
index 5252397f61..0000000000
--- a/src/gui/kernel/qwidget_p.h
+++ /dev/null
@@ -1,1036 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWIDGET_P_H
-#define QWIDGET_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header
-// file may change from version to version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "QtGui/qwidget.h"
-#include "private/qobject_p.h"
-#include "QtCore/qrect.h"
-#include "QtCore/qlocale.h"
-#include "QtCore/qset.h"
-#include "QtGui/qregion.h"
-#include "QtGui/qsizepolicy.h"
-#include "QtGui/qstyle.h"
-#include "QtGui/qapplication.h"
-#include <private/qgraphicseffect_p.h>
-#include "QtGui/qgraphicsproxywidget.h"
-#include "QtGui/qgraphicsscene.h"
-#include "QtGui/qgraphicsview.h"
-#include <private/qgesture_p.h>
-
-#ifdef Q_WS_WIN
-#include "QtCore/qt_windows.h"
-#include <private/qdnd_p.h>
-#endif // Q_WS_WIN
-
-#ifdef Q_WS_X11
-#include "QtGui/qx11info_x11.h"
-#endif
-
-#ifdef Q_WS_MAC
-#include <private/qt_mac_p.h>
-#endif
-
-#if defined(Q_WS_QWS)
-#include "QtGui/qinputcontext.h"
-#include "QtGui/qscreen_qws.h"
-#endif
-
-#if defined(Q_OS_SYMBIAN)
-class RDrawableWindow;
-class CCoeControl;
-#endif
-
-QT_BEGIN_NAMESPACE
-
-// Extra QWidget data
-// - to minimize memory usage for members that are seldom used.
-// - top-level widgets have extra extra data to reduce cost further
-#if defined(Q_WS_QWS)
-class QWSManager;
-#endif
-#if defined(Q_WS_MAC)
-class QCoreGraphicsPaintEnginePrivate;
-#endif
-#if defined(Q_WS_QPA)
-class QPlatformWindow;
-#endif
-class QPaintEngine;
-class QPixmap;
-class QWidgetBackingStore;
-class QGraphicsProxyWidget;
-class QWidgetItemV2;
-
-class QStyle;
-
-class QUnifiedToolbarSurface;
-
-class Q_AUTOTEST_EXPORT QWidgetBackingStoreTracker
-{
-
-public:
- QWidgetBackingStoreTracker();
- ~QWidgetBackingStoreTracker();
-
- void create(QWidget *tlw);
- void destroy();
-
- void registerWidget(QWidget *w);
- void unregisterWidget(QWidget *w);
- void unregisterWidgetSubtree(QWidget *w);
-
- inline QWidgetBackingStore* data()
- {
- return m_ptr;
- }
-
- inline QWidgetBackingStore* operator->()
- {
- return m_ptr;
- }
-
- inline QWidgetBackingStore& operator*()
- {
- return *m_ptr;
- }
-
- inline operator bool() const
- {
- return (0 != m_ptr);
- }
-
-private:
- Q_DISABLE_COPY(QWidgetBackingStoreTracker)
-
-private:
- QWidgetBackingStore* m_ptr;
- QSet<QWidget *> m_widgets;
-};
-
-struct QTLWExtra {
- // *************************** Cross-platform variables *****************************
-
- // Regular pointers (keep them together to avoid gaps on 64 bits architectures).
- QIcon *icon; // widget icon
- QPixmap *iconPixmap;
- QWidgetBackingStoreTracker backingStore;
- QWindowSurface *windowSurface;
- QPainter *sharedPainter;
-
- // Implicit pointers (shared_null).
- QString caption; // widget caption
- QString iconText; // widget icon text
- QString role; // widget role
- QString filePath; // widget file path
-
- // Other variables.
- short incw, inch; // size increments
- short basew, baseh; // base sizes
- // frame strut, don't use these directly, use QWidgetPrivate::frameStrut() instead.
- QRect frameStrut;
- QRect normalGeometry; // used by showMin/maximized/FullScreen
- Qt::WindowFlags savedFlags; // Save widget flags while showing fullscreen
-
- // *************************** Cross-platform bit fields ****************************
- uint opacity : 8;
- uint posFromMove : 1;
- uint sizeAdjusted : 1;
- uint inTopLevelResize : 1;
- uint inRepaint : 1;
- uint embedded : 1;
-
- // *************************** Platform specific values (bit fields first) **********
-#if defined(Q_WS_X11) // <----------------------------------------------------------- X11
- uint spont_unmapped: 1; // window was spontaneously unmapped
- uint dnd : 1; // DND properties installed
- uint validWMState : 1; // is WM_STATE valid?
- uint waitingForMapNotify : 1; // show() has been called, haven't got the MapNotify yet
- WId parentWinId; // parent window Id (valid after reparenting)
- WId userTimeWindow; // window id that contains user-time timestamp when WM supports a _NET_WM_USER_TIME_WINDOW atom
- QPoint fullScreenOffset;
-#ifndef QT_NO_XSYNC
- WId syncUpdateCounter;
- ulong syncRequestTimestamp;
- qint32 newCounterValueHi;
- quint32 newCounterValueLo;
-#endif
-#elif defined(Q_WS_WIN) // <--------------------------------------------------------- WIN
- uint hotkeyRegistered: 1; // Hot key from the STARTUPINFO has been registered.
- HICON winIconBig; // internal big Windows icon
- HICON winIconSmall; // internal small Windows icon
-#elif defined(Q_WS_MAC) // <--------------------------------------------------------- MAC
- uint resizer : 4;
- uint isSetGeometry : 1;
- uint isMove : 1;
- quint32 wattr;
- quint32 wclass;
- WindowGroupRef group;
- IconRef windowIcon; // the current window icon, if set with setWindowIcon_sys.
- quint32 savedWindowAttributesFromMaximized; // Saved attributes from when the calling updateMaximizeButton_sys()
-#ifdef QT_MAC_USE_COCOA
- // This value is just to make sure we maximize and restore to the right location, yet we allow apps to be maximized and
- // manually resized.
- // The name is misleading, since this is set when maximizing the window. It is a hint to saveGeometry(..) to record the
- // starting position as 0,0 instead of the normal starting position.
- bool wasMaximized;
-#endif // QT_MAC_USE_COCOA
-
-#elif defined(Q_WS_QWS) // <--------------------------------------------------------- QWS
-#ifndef QT_NO_QWS_MANAGER
- QWSManager *qwsManager;
-#endif
-#elif defined(Q_OS_SYMBIAN)
- uint inExpose : 1; // Prevents drawing recursion
- uint nativeWindowTransparencyEnabled : 1; // Tracks native window transparency
-#elif defined(Q_WS_QPA)
- QPlatformWindow *platformWindow;
- QPlatformWindowFormat platformWindowFormat;
- quint32 screenIndex; // index in qplatformscreenlist
-#endif
-};
-
-struct QWExtra {
- // *************************** Cross-platform variables *****************************
-
- // Regular pointers (keep them together to avoid gaps on 64 bits architectures).
- void *glContext; // if the widget is hijacked by QGLWindowSurface
- QTLWExtra *topextra; // only useful for TLWs
-#ifndef QT_NO_GRAPHICSVIEW
- QGraphicsProxyWidget *proxyWidget; // if the widget is embedded
-#endif
-#ifndef QT_NO_CURSOR
- QCursor *curs;
-#endif
- QPointer<QStyle> style;
- QPointer<QWidget> focus_proxy;
-
- // Implicit pointers (shared_empty/shared_null).
- QRegion mask; // widget mask
- QString styleSheet;
-
- // Other variables.
- qint32 minw;
- qint32 minh; // minimum size
- qint32 maxw;
- qint32 maxh; // maximum size
- quint16 customDpiX;
- quint16 customDpiY;
- QSize staticContentsSize;
-
- // *************************** Cross-platform bit fields ****************************
- uint explicitMinSize : 2;
- uint explicitMaxSize : 2;
- uint autoFillBackground : 1;
- uint nativeChildrenForced : 1;
- uint inRenderWithPainter : 1;
- uint hasMask : 1;
-
- // *************************** Platform specific values (bit fields first) **********
-#if defined(Q_WS_WIN) // <----------------------------------------------------------- WIN
-#ifndef QT_NO_DRAGANDDROP
- QOleDropTarget *dropTarget; // drop target
- QList<QPointer<QWidget> > oleDropWidgets;
-#endif
-#elif defined(Q_WS_X11) // <--------------------------------------------------------- X11
- uint compress_events : 1;
- WId xDndProxy; // XDND forwarding to embedded windows
-#elif defined(Q_WS_MAC) // <------------------------------------------------------ MAC
-#ifdef QT_MAC_USE_COCOA
- // Cocoa Mask stuff
- QImage maskBits;
- CGImageRef imageMask;
-#endif
-#elif defined(Q_OS_SYMBIAN) // <----------------------------------------------------- Symbian
- uint activated : 1; // RWindowBase::Activated has been called
-
- /**
- * If this bit is set, each native widget receives the signals from the
- * Symbian control immediately before and immediately after draw ops are
- * sent to the window server for this control:
- * void beginNativePaintEvent(const QRect &paintRect);
- * void endNativePaintEvent(const QRect &paintRect);
- */
- uint receiveNativePaintEvents : 1;
-
- /**
- * Defines the behaviour of QSymbianControl::Draw.
- */
- enum NativePaintMode {
- /**
- * Normal drawing mode: blits the required region of the backing store
- * via WSERV.
- */
- Blit,
-
- /**
- * Disable drawing for this widget.
- */
- Disable,
-
- /**
- * Paint zeros into the WSERV framebuffer, using BitGDI APIs. For windows
- * with an EColor16MU display mode, zero is written only into the R, G and B
- * channels of the pixel.
- */
- ZeroFill,
-
- /**
- * Blit backing store, propagating alpha channel into the framebuffer.
- */
- BlitWriteAlpha,
-
- Default = Blit
- };
-
- NativePaintMode nativePaintMode;
-
-#endif
-};
-
-/*!
- \internal
-
- Returns true if \a p or any of its parents enable the
- Qt::BypassGraphicsProxyWidget window flag. Used in QWidget::show() and
- QWidget::setParent() to determine whether it's necessary to embed the
- widget into a QGraphicsProxyWidget or not.
-*/
-static inline bool bypassGraphicsProxyWidget(const QWidget *p)
-{
- while (p) {
- if (p->windowFlags() & Qt::BypassGraphicsProxyWidget)
- return true;
- p = p->parentWidget();
- }
- return false;
-}
-
-class Q_GUI_EXPORT QWidgetPrivate : public QObjectPrivate
-{
- Q_DECLARE_PUBLIC(QWidget)
-
-public:
- // *************************** Cross-platform ***************************************
- enum DrawWidgetFlags {
- DrawAsRoot = 0x01,
- DrawPaintOnScreen = 0x02,
- DrawRecursive = 0x04,
- DrawInvisible = 0x08,
- DontSubtractOpaqueChildren = 0x10,
- DontSetCompositionMode = 0x20,
- DontDrawOpaqueChildren = 0x40,
- DontDrawNativeChildren = 0x80
- };
-
- enum CloseMode {
- CloseNoEvent,
- CloseWithEvent,
- CloseWithSpontaneousEvent
- };
-
- enum Direction {
- DirectionNorth = 0x01,
- DirectionEast = 0x10,
- DirectionSouth = 0x02,
- DirectionWest = 0x20
- };
-
- // Functions.
- explicit QWidgetPrivate(int version = QObjectPrivateVersion);
- ~QWidgetPrivate();
-
- QWExtra *extraData() const;
- QTLWExtra *topData() const;
- QTLWExtra *maybeTopData() const;
- QPainter *sharedPainter() const;
- void setSharedPainter(QPainter *painter);
- QWidgetBackingStore *maybeBackingStore() const;
- void init(QWidget *desktopWidget, Qt::WindowFlags f);
- void create_sys(WId window, bool initializeWindow, bool destroyOldWindow);
- void createRecursively();
- void createWinId(WId id = 0);
-
- void createTLExtra();
- void createExtra();
- void deleteExtra();
- void createSysExtra();
- void deleteSysExtra();
- void createTLSysExtra();
- void deleteTLSysExtra();
- void updateSystemBackground();
- void propagatePaletteChange();
-
- void setPalette_helper(const QPalette &);
- void resolvePalette();
- QPalette naturalWidgetPalette(uint inheritedMask) const;
-
- void setMask_sys(const QRegion &);
-#ifdef Q_OS_SYMBIAN
- void setSoftKeys_sys(const QList<QAction*> &softkeys);
- void activateSymbianWindow(WId wid = 0);
- void _q_delayedDestroy(WId winId);
-#endif
-
- void raise_sys();
- void lower_sys();
- void stackUnder_sys(QWidget *);
-
- void setFocus_sys();
-
- void updateFont(const QFont &);
- inline void setFont_helper(const QFont &font) {
- if (data.fnt == font && data.fnt.resolve() == font.resolve())
- return;
- updateFont(font);
- }
- void resolveFont();
- QFont naturalWidgetFont(uint inheritedMask) const;
-
- void setLayoutDirection_helper(Qt::LayoutDirection);
- void resolveLayoutDirection();
-
- void setLocale_helper(const QLocale &l, bool forceUpdate = false);
- void resolveLocale();
-
- void setStyle_helper(QStyle *newStyle, bool propagate, bool metalHack = false);
- void inheritStyle();
-
- void setUpdatesEnabled_helper(bool );
-
- void paintBackground(QPainter *, const QRegion &, int flags = DrawAsRoot) const;
- bool isAboutToShow() const;
- QRegion prepareToRender(const QRegion &region, QWidget::RenderFlags renderFlags);
- void render_helper(QPainter *painter, const QPoint &targetOffset, const QRegion &sourceRegion,
- QWidget::RenderFlags renderFlags);
- void render(QPaintDevice *target, const QPoint &targetOffset, const QRegion &sourceRegion,
- QWidget::RenderFlags renderFlags, bool readyToRender);
- void drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QPoint &offset, int flags,
- QPainter *sharedPainter = 0, QWidgetBackingStore *backingStore = 0);
-
-
- void paintSiblingsRecursive(QPaintDevice *pdev, const QObjectList& children, int index,
- const QRegion &rgn, const QPoint &offset, int flags
-#ifdef Q_BACKINGSTORE_SUBSURFACES
- , const QWindowSurface *currentSurface
-#endif
- , QPainter *sharedPainter, QWidgetBackingStore *backingStore);
-
-
- QPainter *beginSharedPainter();
- bool endSharedPainter();
-#ifndef QT_NO_GRAPHICSVIEW
- static QGraphicsProxyWidget * nearestGraphicsProxyWidget(const QWidget *origin);
-#endif
- QWindowSurface *createDefaultWindowSurface();
- QWindowSurface *createDefaultWindowSurface_sys();
- void repaint_sys(const QRegion &rgn);
-
- QRect clipRect() const;
- QRegion clipRegion() const;
- void subtractOpaqueChildren(QRegion &rgn, const QRect &clipRect) const;
- void subtractOpaqueSiblings(QRegion &source, bool *hasDirtySiblingsAbove = 0,
- bool alsoNonOpaque = false) const;
- void clipToEffectiveMask(QRegion &region) const;
- void updateIsOpaque();
- void setOpaque(bool opaque);
- void updateIsTranslucent();
- bool paintOnScreen() const;
-#ifndef QT_NO_GRAPHICSEFFECT
- void invalidateGraphicsEffectsRecursively();
-#endif //QT_NO_GRAPHICSEFFECT
-
- const QRegion &getOpaqueChildren() const;
- void setDirtyOpaqueRegion();
-
- bool close_helper(CloseMode mode);
-
- void setWindowIcon_helper();
- void setWindowIcon_sys(bool forceReset = false);
- void setWindowOpacity_sys(qreal opacity);
- void adjustQuitOnCloseAttribute();
-
- void scrollChildren(int dx, int dy);
- void moveRect(const QRect &, int dx, int dy);
- void scrollRect(const QRect &, int dx, int dy);
- void invalidateBuffer_resizeHelper(const QPoint &oldPos, const QSize &oldSize);
- // ### Qt 4.6: Merge into a template function (after MSVC isn't supported anymore).
- void invalidateBuffer(const QRegion &);
- void invalidateBuffer(const QRect &);
- bool isOverlapped(const QRect&) const;
- void syncBackingStore();
- void syncBackingStore(const QRegion &region);
-
- void reparentFocusWidgets(QWidget *oldtlw);
-
- static int pointToRect(const QPoint &p, const QRect &r);
-
- void setWinId(WId);
- void showChildren(bool spontaneous);
- void hideChildren(bool spontaneous);
- void setParent_sys(QWidget *parent, Qt::WindowFlags);
- void scroll_sys(int dx, int dy);
- void scroll_sys(int dx, int dy, const QRect &r);
- void deactivateWidgetCleanup();
- void setGeometry_sys(int, int, int, int, bool);
- void sendPendingMoveAndResizeEvents(bool recursive = false, bool disableUpdates = false);
- void activateChildLayoutsRecursively();
- void show_recursive();
- void show_helper();
- void show_sys();
- void hide_sys();
- void hide_helper();
- void _q_showIfNotHidden();
-
- void setEnabled_helper(bool);
- void registerDropSite(bool);
- static void adjustFlags(Qt::WindowFlags &flags, QWidget *w = 0);
-
- void updateFrameStrut();
- QRect frameStrut() const;
-
-#ifdef QT_KEYPAD_NAVIGATION
- static bool navigateToDirection(Direction direction);
- static QWidget *widgetInNavigationDirection(Direction direction);
- static bool canKeypadNavigate(Qt::Orientation orientation);
- static bool inTabWidget(QWidget *widget);
-#endif
-
- void setWindowIconText_sys(const QString &cap);
- void setWindowIconText_helper(const QString &cap);
- void setWindowTitle_sys(const QString &cap);
-
-#ifndef QT_NO_CURSOR
- void setCursor_sys(const QCursor &cursor);
- void unsetCursor_sys();
-#endif
-
- void setWindowTitle_helper(const QString &cap);
- void setWindowFilePath_helper(const QString &filePath);
-
- bool setMinimumSize_helper(int &minw, int &minh);
- bool setMaximumSize_helper(int &maxw, int &maxh);
- virtual bool hasHeightForWidth() const;
- void setConstraints_sys();
- bool pointInsideRectAndMask(const QPoint &) const;
- QWidget *childAt_helper(const QPoint &, bool) const;
- QWidget *childAtRecursiveHelper(const QPoint &p, bool, bool includeFrame = false) const;
- void updateGeometry_helper(bool forceUpdate);
-
- void getLayoutItemMargins(int *left, int *top, int *right, int *bottom) const;
- void setLayoutItemMargins(int left, int top, int right, int bottom);
- void setLayoutItemMargins(QStyle::SubElement element, const QStyleOption *opt = 0);
-
- // aboutToDestroy() is called just before the contents of
- // QWidget::destroy() is executed. It's used to signal QWidget
- // sub-classes that their internals are about to be released.
- virtual void aboutToDestroy() {}
-
- QInputContext *assignedInputContext() const;
- QInputContext *inputContext() const;
- inline QWidget *effectiveFocusWidget() {
- QWidget *w = q_func();
- while (w->focusProxy())
- w = w->focusProxy();
- return w;
- }
-
- void setModal_sys();
-
- // This is an helper function that return the available geometry for
- // a widget and takes care is this one is in QGraphicsView.
- // If the widget is not embed in a scene then the geometry available is
- // null, we let QDesktopWidget decide for us.
- static QRect screenGeometry(const QWidget *widget)
- {
- QRect screen;
-#ifndef QT_NO_GRAPHICSVIEW
- QGraphicsProxyWidget *ancestorProxy = widget->d_func()->nearestGraphicsProxyWidget(widget);
- //It's embedded if it has an ancestor
- if (ancestorProxy) {
- if (!bypassGraphicsProxyWidget(widget) && ancestorProxy->scene() != 0) {
- // One view, let be smart and return the viewport rect then the popup is aligned
- if (ancestorProxy->scene()->views().size() == 1) {
- QGraphicsView *view = ancestorProxy->scene()->views().at(0);
- screen = view->mapToScene(view->viewport()->rect()).boundingRect().toRect();
- } else {
- screen = ancestorProxy->scene()->sceneRect().toRect();
- }
- }
- }
-#endif
- return screen;
- }
-
- inline void setRedirected(QPaintDevice *replacement, const QPoint &offset)
- {
- Q_ASSERT(q_func()->testAttribute(Qt::WA_WState_InPaintEvent));
- redirectDev = replacement;
- redirectOffset = offset;
- }
-
- inline QPaintDevice *redirected(QPoint *offset) const
- {
- if (offset)
- *offset = redirectDev ? redirectOffset : QPoint();
- return redirectDev;
- }
-
- inline void restoreRedirected()
- { redirectDev = 0; }
-
- inline void enforceNativeChildren()
- {
- if (!extra)
- createExtra();
-
- if (extra->nativeChildrenForced)
- return;
- extra->nativeChildrenForced = 1;
-
- for (int i = 0; i < children.size(); ++i) {
- if (QWidget *child = qobject_cast<QWidget *>(children.at(i)))
- child->setAttribute(Qt::WA_NativeWindow);
- }
- }
-
- inline bool nativeChildrenForced() const
- {
- return extra ? extra->nativeChildrenForced : false;
- }
-
- inline QRect effectiveRectFor(const QRect &rect) const
- {
-#ifndef QT_NO_GRAPHICSEFFECT
- if (graphicsEffect && graphicsEffect->isEnabled())
- return graphicsEffect->boundingRectFor(rect).toAlignedRect();
-#endif //QT_NO_GRAPHICSEFFECT
- return rect;
- }
-
- QSize adjustedSize() const;
-
- inline void handleSoftwareInputPanel(Qt::MouseButton button, bool clickCausedFocus)
- {
- Q_Q(QWidget);
- if (button == Qt::LeftButton && qApp->autoSipEnabled()) {
- QStyle::RequestSoftwareInputPanel behavior = QStyle::RequestSoftwareInputPanel(
- q->style()->styleHint(QStyle::SH_RequestSoftwareInputPanel));
- if (!clickCausedFocus || behavior == QStyle::RSIP_OnMouseClick) {
- QEvent event(QEvent::RequestSoftwareInputPanel);
- QApplication::sendEvent(q, &event);
- }
- }
- }
-
-#ifndef Q_WS_QWS // Almost cross-platform :-)
- void setWSGeometry(bool dontShow=false, const QRect &oldRect = QRect());
-
- inline QPoint mapToWS(const QPoint &p) const
- { return p - data.wrect.topLeft(); }
-
- inline QPoint mapFromWS(const QPoint &p) const
- { return p + data.wrect.topLeft(); }
-
- inline QRect mapToWS(const QRect &r) const
- { QRect rr(r); rr.translate(-data.wrect.topLeft()); return rr; }
-
- inline QRect mapFromWS(const QRect &r) const
- { QRect rr(r); rr.translate(data.wrect.topLeft()); return rr; }
-#endif
-
- // Variables.
- // Regular pointers (keep them together to avoid gaps on 64 bit architectures).
- QWExtra *extra;
- QWidget *focus_next;
- QWidget *focus_prev;
- QWidget *focus_child;
- QLayout *layout;
- QRegion *needsFlush;
- QPaintDevice *redirectDev;
- QWidgetItemV2 *widgetItem;
- QPaintEngine *extraPaintEngine;
- mutable const QMetaObject *polished;
- QGraphicsEffect *graphicsEffect;
- // All widgets are added into the allWidgets set. Once
- // they receive a window id they are also added to the mapper.
- // This should just ensure that all widgets are deleted by QApplication
- static QWidgetMapper *mapper;
- static QWidgetSet *allWidgets;
-#if !defined(QT_NO_IM)
- QPointer<QInputContext> ic;
- Qt::InputMethodHints imHints;
-#endif
-#ifdef QT_KEYPAD_NAVIGATION
- static QPointer<QWidget> editingWidget;
-#endif
-
- // Implicit pointers (shared_null/shared_empty).
- QRegion opaqueChildren;
- QRegion dirty;
-#ifndef QT_NO_TOOLTIP
- QString toolTip;
-#endif
-#ifndef QT_NO_STATUSTIP
- QString statusTip;
-#endif
-#ifndef QT_NO_WHATSTHIS
- QString whatsThis;
-#endif
-#ifndef QT_NO_ACCESSIBILITY
- QString accessibleName;
- QString accessibleDescription;
-#endif
-
- // Other variables.
- uint inheritedFontResolveMask;
- uint inheritedPaletteResolveMask;
- short leftmargin;
- short topmargin;
- short rightmargin;
- short bottommargin;
- signed char leftLayoutItemMargin;
- signed char topLayoutItemMargin;
- signed char rightLayoutItemMargin;
- signed char bottomLayoutItemMargin;
- static int instanceCounter; // Current number of widget instances
- static int maxInstances; // Maximum number of widget instances
- Qt::HANDLE hd;
- QWidgetData data;
- QSizePolicy size_policy;
- QLocale locale;
- QPoint redirectOffset;
-#ifndef QT_NO_ACTION
- QList<QAction*> actions;
-#endif
-#ifndef QT_NO_GESTURES
- QMap<Qt::GestureType, Qt::GestureFlags> gestureContext;
-#endif
-
- // Bit fields.
- uint high_attributes[4]; // the low ones are in QWidget::widget_attributes
- QPalette::ColorRole fg_role : 8;
- QPalette::ColorRole bg_role : 8;
- uint dirtyOpaqueChildren : 1;
- uint isOpaque : 1;
- uint inDirtyList : 1;
- uint isScrolled : 1;
- uint isMoved : 1;
- uint isGLWidget : 1;
- uint usesDoubleBufferedGLContext : 1;
-#ifndef QT_NO_IM
- uint inheritsInputMethodHints : 1;
-#endif
- uint inSetParent : 1;
-
- // *************************** Platform specific ************************************
-#if defined(Q_WS_X11) // <----------------------------------------------------------- X11
- QX11Info xinfo;
- Qt::HANDLE picture;
- static QWidget *mouseGrabber;
- static QWidget *keyboardGrabber;
-
- void setWindowRole();
- void sendStartupMessage(const char *message) const;
- void setNetWmWindowTypes();
- void x11UpdateIsOpaque();
- bool isBackgroundInherited() const;
- void updateX11AcceptFocus();
- QPoint mapToGlobal(const QPoint &pos) const;
- QPoint mapFromGlobal(const QPoint &pos) const;
-#elif defined(Q_WS_WIN) // <--------------------------------------------------------- WIN
- uint noPaintOnScreen : 1; // see qwidget_win.cpp ::paintEngine()
-#ifndef QT_NO_GESTURES
- uint nativeGesturePanEnabled : 1;
-#endif
- bool shouldShowMaximizeButton();
- void winUpdateIsOpaque();
- void reparentChildren();
-#ifndef QT_NO_DRAGANDDROP
- QOleDropTarget *registerOleDnd(QWidget *widget);
- void unregisterOleDnd(QWidget *widget, QOleDropTarget *target);
-#endif
- void grabMouseWhileInWindow();
- void registerTouchWindow();
- void winSetupGestures();
-#elif defined(Q_WS_MAC) // <--------------------------------------------------------- MAC
- // This is new stuff
- uint needWindowChange : 1;
-
- // Each wiget keeps a list of all its child and grandchild OpenGL widgets.
- // This list is used to update the gl context whenever a parent and a granparent
- // moves, and also to check for intersections with gl widgets within the window
- // when a widget moves.
- struct GlWidgetInfo
- {
- GlWidgetInfo(QWidget *widget) : widget(widget), lastUpdateWidget(0) { }
- bool operator==(const GlWidgetInfo &other) const { return (widget == other.widget); }
- QWidget * widget;
- QWidget * lastUpdateWidget;
- };
-
- // dirtyOnWidget contains the areas in the widget that needs to be repained,
- // in the same way as dirtyOnScreen does for the window. Areas are added in
- // dirtyWidget_sys and cleared in the paint event. In scroll_sys we then use
- // this information repaint invalid areas when widgets are scrolled.
- QRegion dirtyOnWidget;
- EventHandlerRef window_event;
- QList<GlWidgetInfo> glWidgets;
-
- //these are here just for code compat (HIViews)
- Qt::HANDLE qd_hd;
-
- void macUpdateSizeAttribute();
- void macUpdateHideOnSuspend();
- void macUpdateOpaqueSizeGrip();
- void macUpdateIgnoreMouseEvents();
- void macUpdateMetalAttribute();
- void macUpdateIsOpaque();
- void macSetNeedsDisplay(QRegion region);
- void setEnabled_helper_sys(bool enable);
- bool isRealWindow() const;
- void adjustWithinMaxAndMinSize(int &w, int &h);
- void applyMaxAndMinSizeOnWindow();
- void update_sys(const QRect &rect);
- void update_sys(const QRegion &rgn);
- void setGeometry_sys_helper(int, int, int, int, bool);
- void setWindowModified_sys(bool b);
- void updateMaximizeButton_sys();
- void setWindowFilePath_sys(const QString &filePath);
- void createWindow_sys();
- void recreateMacWindow();
-#ifndef QT_MAC_USE_COCOA
- void initWindowPtr();
- void finishCreateWindow_sys_Carbon(OSWindowRef windowRef);
-#else
- void setSubWindowStacking(bool set);
- void setWindowLevel();
- void finishCreateWindow_sys_Cocoa(void * /*NSWindow * */ windowRef);
- void syncCocoaMask();
- void finishCocoaMaskSetup();
- void syncUnifiedMode();
- // Did we add the drawRectOriginal method?
- bool drawRectOriginalAdded;
- // Is the original drawRect method available?
- bool originalDrawMethod;
- // Do we need to change the methods?
- bool changeMethods;
-
- // Unified toolbar variables
- bool isInUnifiedToolbar;
- QUnifiedToolbarSurface *unifiedSurface;
- QPoint toolbar_offset;
- QWidget *toolbar_ancestor;
- bool flushRequested;
- bool touchEventsEnabled;
-#endif // QT_MAC_USE_COCOA
- void determineWindowClass();
- void transferChildren();
- bool qt_mac_dnd_event(uint, DragRef);
- void toggleDrawers(bool);
- //mac event functions
- static bool qt_create_root_win();
- static void qt_clean_root_win();
- static bool qt_mac_update_sizer(QWidget *, int up = 0);
- static OSStatus qt_window_event(EventHandlerCallRef er, EventRef event, void *);
- static OSStatus qt_widget_event(EventHandlerCallRef er, EventRef event, void *);
- static bool qt_widget_rgn(QWidget *, short, RgnHandle, bool);
- void registerTouchWindow(bool enable = true);
-#elif defined(Q_WS_QWS) // <--------------------------------------------------------- QWS
- void setMaxWindowState_helper();
- void setFullScreenSize_helper();
- void moveSurface(QWindowSurface *surface, const QPoint &offset);
- QRegion localRequestedRegion() const;
- QRegion localAllocatedRegion() const;
-
- friend class QWSManager;
- friend class QWSManagerPrivate;
- friend class QDecoration;
-#ifndef QT_NO_CURSOR
- void updateCursor() const;
-#endif
- QScreen* getScreen() const;
-#elif defined(Q_WS_QPA) // <--------------------------------------------------------- QPA
- void setMaxWindowState_helper();
- void setFullScreenSize_helper();
-#ifndef QT_NO_CURSOR
- void updateCursor() const;
-#endif
-#elif defined(Q_OS_SYMBIAN) // <--------------------------------------------------------- SYMBIAN
- static QWidget *mouseGrabber;
- static QWidget *keyboardGrabber;
- int symbianScreenNumber; // only valid for desktop widget and top-levels
- bool fixNativeOrientationCalled;
- void s60UpdateIsOpaque();
- void reparentChildren();
- void registerTouchWindow();
-#endif
-
-};
-
-struct QWidgetPaintContext
-{
- inline QWidgetPaintContext(QPaintDevice *d, const QRegion &r, const QPoint &o, int f,
- QPainter *p, QWidgetBackingStore *b)
- : pdev(d), rgn(r), offset(o), flags(f), sharedPainter(p), backingStore(b), painter(0) {}
-
- QPaintDevice *pdev;
- QRegion rgn;
- QPoint offset;
- int flags;
- QPainter *sharedPainter;
- QWidgetBackingStore *backingStore;
- QPainter *painter;
-};
-
-#ifndef QT_NO_GRAPHICSEFFECT
-class QWidgetEffectSourcePrivate : public QGraphicsEffectSourcePrivate
-{
-public:
- QWidgetEffectSourcePrivate(QWidget *widget)
- : QGraphicsEffectSourcePrivate(), m_widget(widget), context(0), updateDueToGraphicsEffect(false)
- {}
-
- inline void detach()
- { m_widget->d_func()->graphicsEffect = 0; }
-
- inline const QGraphicsItem *graphicsItem() const
- { return 0; }
-
- inline const QWidget *widget() const
- { return m_widget; }
-
- inline void update()
- {
- updateDueToGraphicsEffect = true;
- m_widget->update();
- updateDueToGraphicsEffect = false;
- }
-
- inline bool isPixmap() const
- { return false; }
-
- inline void effectBoundingRectChanged()
- {
- // ### This function should take a rect parameter; then we can avoid
- // updating too much on the parent widget.
- if (QWidget *parent = m_widget->parentWidget())
- parent->update();
- else
- update();
- }
-
- inline const QStyleOption *styleOption() const
- { return 0; }
-
- inline QRect deviceRect() const
- { return m_widget->window()->rect(); }
-
- QRectF boundingRect(Qt::CoordinateSystem system) const;
- void draw(QPainter *p);
- QPixmap pixmap(Qt::CoordinateSystem system, QPoint *offset,
- QGraphicsEffect::PixmapPadMode mode) const;
-
- QWidget *m_widget;
- QWidgetPaintContext *context;
- QTransform lastEffectTransform;
- bool updateDueToGraphicsEffect;
-};
-#endif //QT_NO_GRAPHICSEFFECT
-
-inline QWExtra *QWidgetPrivate::extraData() const
-{
- return extra;
-}
-
-inline QTLWExtra *QWidgetPrivate::topData() const
-{
- const_cast<QWidgetPrivate *>(this)->createTLExtra();
- return extra->topextra;
-}
-
-inline QTLWExtra *QWidgetPrivate::maybeTopData() const
-{
- return extra ? extra->topextra : 0;
-}
-
-inline QPainter *QWidgetPrivate::sharedPainter() const
-{
- Q_Q(const QWidget);
- QTLWExtra *x = q->window()->d_func()->maybeTopData();
- return x ? x->sharedPainter : 0;
-}
-
-inline void QWidgetPrivate::setSharedPainter(QPainter *painter)
-{
- Q_Q(QWidget);
- QTLWExtra *x = q->window()->d_func()->topData();
- x->sharedPainter = painter;
-}
-
-inline bool QWidgetPrivate::pointInsideRectAndMask(const QPoint &p) const
-{
- Q_Q(const QWidget);
- return q->rect().contains(p) && (!extra || !extra->hasMask || q->testAttribute(Qt::WA_MouseNoMask)
- || extra->mask.contains(p));
-}
-
-inline QWidgetBackingStore *QWidgetPrivate::maybeBackingStore() const
-{
- Q_Q(const QWidget);
- QTLWExtra *x = q->window()->d_func()->maybeTopData();
- return x ? x->backingStore.data() : 0;
-}
-
-QT_END_NAMESPACE
-
-#endif // QWIDGET_P_H
diff --git a/src/gui/kernel/qwidget_qpa.cpp b/src/gui/kernel/qwidget_qpa.cpp
deleted file mode 100644
index 661120c8b2..0000000000
--- a/src/gui/kernel/qwidget_qpa.cpp
+++ /dev/null
@@ -1,890 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "QtGui/qwidget.h"
-#include "QtGui/qevent.h"
-#include "QtGui/qapplication.h"
-#include "QtGui/private/qbackingstore_p.h"
-#include "QtGui/private/qwidget_p.h"
-#include "QtGui/private/qgraphicssystem_p.h"
-#include "QtGui/private/qapplication_p.h"
-#include "QtGui/qdesktopwidget.h"
-#include "QtGui/qplatformwindow_qpa.h"
-#include "QtGui/qplatformglcontext_qpa.h"
-
-#include <QtGui/QPlatformCursor>
-
-QT_BEGIN_NAMESPACE
-
-void q_createNativeChildrenAndSetParent(QPlatformWindow *parentWindow, const QWidget *parentWidget)
-{
- QObjectList children = parentWidget->children();
- for (int i = 0; i < children.size(); i++) {
- if (children.at(i)->isWidgetType()) {
- const QWidget *childWidget = qobject_cast<const QWidget *>(children.at(i));
- if (childWidget) { // should not be necessary
- if (childWidget->testAttribute(Qt::WA_NativeWindow)) {
- if (!childWidget->platformWindow())
- childWidget->winId();
- }
- if (childWidget->platformWindow()) {
- childWidget->platformWindow()->setParent(parentWindow);
- } else {
- q_createNativeChildrenAndSetParent(parentWindow,childWidget);
- }
- }
- }
- }
-
-}
-
-void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyOldWindow)
-{
- Q_Q(QWidget);
-
- Q_UNUSED(window);
- Q_UNUSED(initializeWindow);
- Q_UNUSED(destroyOldWindow);
-
- Qt::WindowFlags flags = data.window_flags;
-
- if ((!q->testAttribute(Qt::WA_NativeWindow) && !q->isWindow()) || q->windowType() == Qt::Desktop )
- return; // we only care about real toplevels
-
- QWindowSurface *surface = q->windowSurface();
- QPlatformWindow *platformWindow = q->platformWindow();
-
- if (!platformWindow) {
- platformWindow = QApplicationPrivate::platformIntegration()->createPlatformWindow(q);
- }
- Q_ASSERT(platformWindow);
-
- if (!surface ) {
- if (platformWindow && q->platformWindowFormat().hasWindowSurface()) {
- surface = QApplicationPrivate::platformIntegration()->createWindowSurface(q,platformWindow->winId());
- } else {
- q->setAttribute(Qt::WA_PaintOnScreen,true);
- }
- }
-
- data.window_flags = q->platformWindow()->setWindowFlags(data.window_flags);
-
- setWinId(q->platformWindow()->winId());
-
- //first check children. and create them if necessary
- q_createNativeChildrenAndSetParent(q->platformWindow(),q);
-
- //if we we have a parent, then set correct parent;
- if (!q->isWindow()) {
- if (QWidget *nativeParent = q->nativeParentWidget()) {
- if (nativeParent->platformWindow()) {
- platformWindow->setParent(nativeParent->platformWindow());
- }
- }
- }
-
- QApplicationPrivate::platformIntegration()->moveToScreen(q, topData()->screenIndex);
-// qDebug() << "create_sys" << q << q->internalWinId();
-}
-
-void QWidget::destroy(bool destroyWindow, bool destroySubWindows)
-{
- Q_D(QWidget);
-
- if ((windowType() == Qt::Popup))
- qApp->d_func()->closePopup(this);
-
- //### we don't have proper focus event handling yet
- if (this == QApplicationPrivate::active_window)
- QApplication::setActiveWindow(0);
-
- if (windowType() != Qt::Desktop) {
- if (destroySubWindows) {
- QObjectList childList(children());
- for (int i = 0; i < childList.size(); i++) {
- QWidget *widget = qobject_cast<QWidget *>(childList.at(i));
- if (widget && widget->testAttribute(Qt::WA_NativeWindow)) {
- if (widget->platformWindow()) {
- widget->destroy();
- }
- }
- }
- }
- if (destroyWindow) {
- d->deleteTLSysExtra();
- } else {
- if (parentWidget() && parentWidget()->testAttribute(Qt::WA_WState_Created)) {
- d->hide_sys();
- }
- }
- }
-}
-
-void QWidgetPrivate::setParent_sys(QWidget *newparent, Qt::WindowFlags f)
-{
- Q_Q(QWidget);
-
- Qt::WindowFlags oldFlags = data.window_flags;
-
- int targetScreen = -1;
- // Handle a request to move the widget to a particular screen
- if (newparent && newparent->windowType() == Qt::Desktop) {
- // make sure the widget is created on the same screen as the
- // programmer specified desktop widget
-
- // get the desktop's screen number
- targetScreen = newparent->window()->d_func()->topData()->screenIndex;
- newparent = 0;
- }
-
- if (parent != newparent) {
- QObjectPrivate::setParent_helper(newparent); //### why does this have to be done in the _sys function???
- if (q->platformWindow() && newparent) {
- QWidget * parentWithWindow = newparent->platformWindow()? newparent : newparent->nativeParentWidget();
- if (parentWithWindow && parentWithWindow->platformWindow()) {
- q->platformWindow()->setParent(parentWithWindow->platformWindow());
- }
- }
-
- }
-
- if (!newparent) {
- f |= Qt::Window;
- if (targetScreen == -1) {
- if (parent)
- targetScreen = q->parentWidget()->window()->d_func()->topData()->screenIndex;
- }
- }
-
- bool explicitlyHidden = q->testAttribute(Qt::WA_WState_Hidden) && q->testAttribute(Qt::WA_WState_ExplicitShowHide);
-
- // Reparenting toplevel to child
- if (!(f&Qt::Window) && (oldFlags&Qt::Window) && !q->testAttribute(Qt::WA_NativeWindow)) {
- //qDebug() << "setParent_sys() change from toplevel";
- q->destroy();
- }
-
- data.window_flags = f;
- q->setAttribute(Qt::WA_WState_Created, false);
- q->setAttribute(Qt::WA_WState_Visible, false);
- q->setAttribute(Qt::WA_WState_Hidden, false);
-
- if (f & Qt::Window) {
- //qDebug() << "setParent_sys" << q << newparent << hex << f;
- if (QPlatformWindow *window = q->platformWindow())
- data.window_flags = window->setWindowFlags(data.window_flags);
- }
-
- if (q->isWindow() || (!newparent || newparent->isVisible()) || explicitlyHidden)
- q->setAttribute(Qt::WA_WState_Hidden);
- q->setAttribute(Qt::WA_WState_ExplicitShowHide, explicitlyHidden);
-
- // move the window to the selected screen
- if (!newparent && targetScreen != -1) {
- if (maybeTopData())
- maybeTopData()->screenIndex = targetScreen;
- // only if it is already created
- if (q->testAttribute(Qt::WA_WState_Created)) {
- QPlatformIntegration *platform = QApplicationPrivate::platformIntegration();
- platform->moveToScreen(q, targetScreen);
- }
- }
-}
-
-QPoint QWidget::mapToGlobal(const QPoint &pos) const
-{
- int x=pos.x(), y=pos.y();
- const QWidget* w = this;
- while (w) {
- x += w->data->crect.x();
- y += w->data->crect.y();
- w = w->isWindow() ? 0 : w->parentWidget();
- }
- return QPoint(x, y);
-}
-
-QPoint QWidget::mapFromGlobal(const QPoint &pos) const
-{
- int x=pos.x(), y=pos.y();
- const QWidget* w = this;
- while (w) {
- x -= w->data->crect.x();
- y -= w->data->crect.y();
- w = w->isWindow() ? 0 : w->parentWidget();
- }
- return QPoint(x, y);
-}
-
-void QWidgetPrivate::updateSystemBackground() {}
-
-#ifndef QT_NO_CURSOR
-void QWidgetPrivate::setCursor_sys(const QCursor &cursor)
-{
- Q_UNUSED(cursor);
- Q_Q(QWidget);
- if (q->isVisible())
- qt_qpa_set_cursor(q, false);
-}
-
-void QWidgetPrivate::unsetCursor_sys()
-{
- Q_Q(QWidget);
- if (q->isVisible())
- qt_qpa_set_cursor(q, false);
-}
-
-void QWidgetPrivate::updateCursor() const
-{
- // XXX
-}
-
-#endif //QT_NO_CURSOR
-
-void QWidgetPrivate::setWindowTitle_sys(const QString &caption)
-{
- Q_Q(QWidget);
- if (!q->isWindow())
- return;
-
- if (QPlatformWindow *window = q->platformWindow())
- window->setWindowTitle(caption);
-
-}
-
-void QWidgetPrivate::setWindowIcon_sys(bool /*forceReset*/)
-{
-}
-
-void QWidgetPrivate::setWindowIconText_sys(const QString &iconText)
-{
- Q_UNUSED(iconText);
-}
-
-QWidget *qt_pressGrab = 0;
-QWidget *qt_mouseGrb = 0;
-static QWidget *keyboardGrb = 0;
-
-void QWidget::grabMouse()
-{
- if (qt_mouseGrb)
- qt_mouseGrb->releaseMouse();
-
- // XXX
- //qwsDisplay()->grabMouse(this,true);
-
- qt_mouseGrb = this;
- qt_pressGrab = 0;
-}
-
-#ifndef QT_NO_CURSOR
-void QWidget::grabMouse(const QCursor &cursor)
-{
- Q_UNUSED(cursor);
-
- if (qt_mouseGrb)
- qt_mouseGrb->releaseMouse();
-
- // XXX
- //qwsDisplay()->grabMouse(this,true);
- //qwsDisplay()->selectCursor(this, cursor.handle());
- qt_mouseGrb = this;
- qt_pressGrab = 0;
-}
-#endif
-
-void QWidget::releaseMouse()
-{
- if (qt_mouseGrb == this) {
- // XXX
- //qwsDisplay()->grabMouse(this,false);
- qt_mouseGrb = 0;
- }
-}
-
-void QWidget::grabKeyboard()
-{
- if (keyboardGrb)
- keyboardGrb->releaseKeyboard();
- // XXX
- //qwsDisplay()->grabKeyboard(this, true);
- keyboardGrb = this;
-}
-
-void QWidget::releaseKeyboard()
-{
- if (keyboardGrb == this) {
- // XXX
- //qwsDisplay()->grabKeyboard(this, false);
- keyboardGrb = 0;
- }
-}
-
-QWidget *QWidget::mouseGrabber()
-{
- if (qt_mouseGrb)
- return qt_mouseGrb;
- return qt_pressGrab;
-}
-
-QWidget *QWidget::keyboardGrabber()
-{
- return keyboardGrb;
-}
-
-void QWidget::activateWindow()
-{
- if (platformWindow())
- platformWindow()->requestActivateWindow();
-}
-
-void QWidgetPrivate::show_sys()
-{
- Q_Q(QWidget);
- q->setAttribute(Qt::WA_Mapped);
- if (q->testAttribute(Qt::WA_DontShowOnScreen)) {
- invalidateBuffer(q->rect());
- return;
- }
-
- QApplication::postEvent(q, new QUpdateLaterEvent(q->rect()));
-
- QPlatformWindow *window = q->platformWindow();
- if (window) {
- QRect geomRect = q->geometry();
- if (!q->isWindow()) {
- QPoint topLeftOfWindow = q->mapTo(q->nativeParentWidget(),QPoint());
- geomRect.moveTopLeft(topLeftOfWindow);
- }
- const QRect windowRect = window->geometry();
- if (windowRect != geomRect) {
- window->setGeometry(geomRect);
- }
- if (QWindowSurface *surface = q->windowSurface()) {
- if (windowRect.size() != geomRect.size()) {
- surface->resize(geomRect.size());
- }
- }
- if (window)
- window->setVisible(true);
- }
-}
-
-
-void QWidgetPrivate::hide_sys()
-{
- Q_Q(QWidget);
- q->setAttribute(Qt::WA_Mapped, false);
- if (!q->isWindow()) {
- QWidget *p = q->parentWidget();
- if (p &&p->isVisible()) {
- invalidateBuffer(q->rect());
- }
- return;
- }
- if (QPlatformWindow *window = q->platformWindow()) {
- window->setVisible(false);
- }
-
- //### we don't yet have proper focus event handling
- if (q == QApplicationPrivate::active_window)
- QApplication::setActiveWindow(0);
-
-}
-
-void QWidgetPrivate::setMaxWindowState_helper()
-{
- setFullScreenSize_helper(); //### decoration size
-}
-
-void QWidgetPrivate::setFullScreenSize_helper()
-{
- Q_Q(QWidget);
-
- const uint old_state = data.in_set_window_state;
- data.in_set_window_state = 1;
-
- const QRect screen = qApp->desktop()->screenGeometry(qApp->desktop()->screenNumber(q));
- q->move(screen.topLeft());
- q->resize(screen.size());
-
- data.in_set_window_state = old_state;
-}
-
-static Qt::WindowStates effectiveState(Qt::WindowStates state)
- {
- if (state & Qt::WindowMinimized)
- return Qt::WindowMinimized;
- else if (state & Qt::WindowFullScreen)
- return Qt::WindowFullScreen;
- else if (state & Qt::WindowMaximized)
- return Qt::WindowMaximized;
- return Qt::WindowNoState;
- }
-
-void QWidget::setWindowState(Qt::WindowStates newstate)
-{
- Q_D(QWidget);
- Qt::WindowStates oldstate = windowState();
- if (oldstate == newstate)
- return;
- if (isWindow() && !testAttribute(Qt::WA_WState_Created))
- create();
-
- data->window_state = newstate;
- data->in_set_window_state = 1;
- bool needShow = false;
- Qt::WindowStates newEffectiveState = effectiveState(newstate);
- Qt::WindowStates oldEffectiveState = effectiveState(oldstate);
- if (isWindow() && newEffectiveState != oldEffectiveState) {
- d->createTLExtra();
- if (oldEffectiveState == Qt::WindowNoState) { //normal
- d->topData()->normalGeometry = geometry();
- } else if (oldEffectiveState == Qt::WindowFullScreen) {
- setParent(0, d->topData()->savedFlags);
- needShow = true;
- } else if (oldEffectiveState == Qt::WindowMinimized) {
- needShow = true;
- }
-
- if (newEffectiveState == Qt::WindowMinimized) {
- //### not ideal...
- hide();
- needShow = false;
- } else if (newEffectiveState == Qt::WindowFullScreen) {
- d->topData()->savedFlags = windowFlags();
- setParent(0, Qt::FramelessWindowHint | (windowFlags() & Qt::WindowStaysOnTopHint));
- d->setFullScreenSize_helper();
- raise();
- needShow = true;
- } else if (newEffectiveState == Qt::WindowMaximized) {
- createWinId();
- d->setMaxWindowState_helper();
- } else { //normal
- QRect r = d->topData()->normalGeometry;
- if (r.width() >= 0) {
- d->topData()->normalGeometry = QRect(0,0,-1,-1);
- setGeometry(r);
- }
- }
- }
- data->in_set_window_state = 0;
-
- if (needShow)
- show();
-
- if (newstate & Qt::WindowActive)
- activateWindow();
-
- QWindowStateChangeEvent e(oldstate);
- QApplication::sendEvent(this, &e);
-}
-
-void QWidgetPrivate::setFocus_sys()
-{
-
-}
-
-void QWidgetPrivate::raise_sys()
-{
- Q_Q(QWidget);
- if (q->isWindow()) {
- q->platformWindow()->raise();
- }
-}
-
-void QWidgetPrivate::lower_sys()
-{
- Q_Q(QWidget);
- if (q->isWindow()) {
- Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
- q->platformWindow()->lower();
- } else if (QWidget *p = q->parentWidget()) {
- setDirtyOpaqueRegion();
- p->d_func()->invalidateBuffer(effectiveRectFor(q->geometry()));
- }
-}
-
-void QWidgetPrivate::stackUnder_sys(QWidget*)
-{
- Q_Q(QWidget);
- if (QWidget *p = q->parentWidget()) {
- setDirtyOpaqueRegion();
- p->d_func()->invalidateBuffer(effectiveRectFor(q->geometry()));
- }
-}
-
-void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove)
-{
- Q_Q(QWidget);
- if (extra) { // any size restrictions?
- w = qMin(w,extra->maxw);
- h = qMin(h,extra->maxh);
- w = qMax(w,extra->minw);
- h = qMax(h,extra->minh);
- }
-
- QPoint oldp = q->geometry().topLeft();
- QSize olds = q->size();
- QRect r(x, y, w, h);
-
- bool isResize = olds != r.size();
- isMove = oldp != r.topLeft(); //### why do we have isMove as a parameter?
-
-
- // We only care about stuff that changes the geometry, or may
- // cause the window manager to change its state
- if (r.size() == olds && oldp == r.topLeft())
- return;
-
- if (!data.in_set_window_state) {
- q->data->window_state &= ~Qt::WindowMaximized;
- q->data->window_state &= ~Qt::WindowFullScreen;
- if (q->isWindow())
- topData()->normalGeometry = QRect(0, 0, -1, -1);
- }
-
- QPoint oldPos = q->pos();
- data.crect = r;
-
- if (q->isVisible()) {
- if (q->platformWindow()) {
- if (q->isWindow()) {
- q->platformWindow()->setGeometry(q->geometry());
- } else {
- QPoint posInNativeParent = q->mapTo(q->nativeParentWidget(),QPoint());
- q->platformWindow()->setGeometry(QRect(posInNativeParent,r.size()));
- }
- const QWidgetBackingStore *bs = maybeBackingStore();
- if (bs->windowSurface) {
- if (isResize)
- bs->windowSurface->resize(r.size());
- }
- } else {
- if (isMove && !isResize)
- moveRect(QRect(oldPos, olds), x - oldPos.x(), y - oldPos.y());
- else
- invalidateBuffer_resizeHelper(oldPos, olds);
- }
-
- if (isMove) {
- QMoveEvent e(q->pos(), oldPos);
- QApplication::sendEvent(q, &e);
- }
- if (isResize) {
- QResizeEvent e(r.size(), olds);
- QApplication::sendEvent(q, &e);
- if (q->platformWindow())
- q->update();
- }
- } else { // not visible
- if (isMove && q->pos() != oldPos)
- q->setAttribute(Qt::WA_PendingMoveEvent, true);
- if (isResize)
- q->setAttribute(Qt::WA_PendingResizeEvent, true);
- }
-
-}
-
-void QWidgetPrivate::setConstraints_sys()
-{
-}
-
-void QWidgetPrivate::scroll_sys(int dx, int dy)
-{
- Q_Q(QWidget);
- scrollChildren(dx, dy);
- scrollRect(q->rect(), dx, dy);
-}
-
-void QWidgetPrivate::scroll_sys(int dx, int dy, const QRect &r)
-{
- scrollRect(r, dx, dy);
-}
-
-int QWidget::metric(PaintDeviceMetric m) const
-{
- Q_D(const QWidget);
-
- QPlatformScreen *screen = QPlatformScreen::platformScreenForWidget(this);
- if (!screen) {
- if (m == PdmDpiX || m == PdmDpiY)
- return 72;
- return QPaintDevice::metric(m);
- }
- int val;
- if (m == PdmWidth) {
- val = data->crect.width();
- } else if (m == PdmWidthMM) {
- val = data->crect.width() * screen->physicalSize().width() / screen->geometry().width();
- } else if (m == PdmHeight) {
- val = data->crect.height();
- } else if (m == PdmHeightMM) {
- val = data->crect.height() * screen->physicalSize().height() / screen->geometry().height();
- } else if (m == PdmDepth) {
- return screen->depth();
- } else if (m == PdmDpiX || m == PdmPhysicalDpiX) {
- if (d->extra && d->extra->customDpiX)
- return d->extra->customDpiX;
- else if (d->parent)
- return static_cast<QWidget *>(d->parent)->metric(m);
- return qRound(screen->geometry().width() / double(screen->physicalSize().width() / 25.4));
- } else if (m == PdmDpiY || m == PdmPhysicalDpiY) {
- if (d->extra && d->extra->customDpiY)
- return d->extra->customDpiY;
- else if (d->parent)
- return static_cast<QWidget *>(d->parent)->metric(m);
- return qRound(screen->geometry().height() / double(screen->physicalSize().height() / 25.4));
- } else {
- val = QPaintDevice::metric(m);// XXX
- }
- return val;
-}
-
-/*!
- \preliminary
-
- Sets the window to be the platform \a window specified.
-
- The widget takes ownership of the \a window. Any platform window
- previously set on the widget will be destroyed.
-*/
-void QWidget::setPlatformWindow(QPlatformWindow *window)
-{
- Q_D(QWidget);
-
- QTLWExtra *topData = d->topData();
- if (topData->platformWindow == window)
- return;
-
- delete topData->platformWindow;
- topData->platformWindow = window;
-}
-
-/*!
- \preliminary
-
- Returns the QPlatformWindow this widget will be drawn into.
-*/
-QPlatformWindow *QWidget::platformWindow() const
-{
- Q_D(const QWidget);
- QTLWExtra *extra = d->maybeTopData();
- if (extra && extra->platformWindow)
- return extra->platformWindow;
-
- return 0;
-}
-
-/*!
- Sets the platform window format for the widget to the \a format specified.
-*/
-void QWidget::setPlatformWindowFormat(const QPlatformWindowFormat &format)
-{
- if (isWindow() || testAttribute(Qt::WA_NativeWindow)) {
- Q_D(QWidget);
- QTLWExtra *topData = d->topData();
- topData->platformWindowFormat = format;
- if (testAttribute(Qt::WA_WState_Created)) {
- bool wasVisible = testAttribute(Qt::WA_WState_Visible);
- destroy();
- d->create_sys(0,true,true);
- if (wasVisible)
- topData->platformWindow->setVisible(true);
- }
- }
-}
-
-/*!
- Returns the platform window format for the widget.
-*/
-QPlatformWindowFormat QWidget::platformWindowFormat() const
-{
- Q_D(const QWidget);
-
- QPlatformWindowFormat format;
-
- QTLWExtra *extra = d->maybeTopData();
- if (extra){
- format = extra->platformWindowFormat;
- } else {
- format = QPlatformWindowFormat::defaultFormat();
- }
-
- if (testAttribute(Qt::WA_TranslucentBackground))
- format.setAlpha(true);
-
- return format;
-}
-
-void QWidgetPrivate::createSysExtra()
-{
-}
-
-void QWidgetPrivate::deleteSysExtra()
-{
-
-}
-
-void QWidgetPrivate::createTLSysExtra()
-{
-}
-
-void QWidgetPrivate::deleteTLSysExtra()
-{
- if (extra && extra->topextra) {
- //the toplevel might have a context with a "qglcontext associated with it. We need to
- //delete the qglcontext before we delete the qplatformglcontext.
- //One unfortunate thing about this is that we potentially create a glContext just to
- //delete it straight afterwards.
- if (extra->topextra->platformWindow) {
- if (QPlatformGLContext *context = extra->topextra->platformWindow->glContext()) {
- context->deleteQGLContext();
- }
- }
- setWinId(0);
- delete extra->topextra->platformWindow;
- extra->topextra->platformWindow = 0;
- }
-}
-
-void QWidgetPrivate::registerDropSite(bool on)
-{
- Q_UNUSED(on);
-}
-
-void QWidgetPrivate::setMask_sys(const QRegion &region)
-{
- Q_UNUSED(region);
- // XXX
-}
-
-void QWidgetPrivate::updateFrameStrut()
-{
- // XXX
-}
-
-void QWidgetPrivate::setWindowOpacity_sys(qreal level)
-{
- Q_Q(QWidget);
- q->platformWindow()->setOpacity(level);
-}
-
-void QWidgetPrivate::setWSGeometry(bool dontShow, const QRect &oldRect)
-{
- Q_UNUSED(dontShow);
- Q_UNUSED(oldRect);
- // XXX
-}
-
-QPaintEngine *QWidget::paintEngine() const
-{
- qWarning("QWidget::paintEngine: Should no longer be called");
- return 0; //##### @@@
-}
-
-QWindowSurface *QWidgetPrivate::createDefaultWindowSurface_sys()
-{
- Q_Q(QWidget);
- if (q->platformWindowFormat().hasWindowSurface())
- return QApplicationPrivate::platformIntegration()->createWindowSurface(q,0);
- else
- return 0;
-}
-
-void QWidgetPrivate::setModal_sys()
-{
-}
-
-#ifndef QT_NO_CURSOR
-void qt_qpa_set_cursor(QWidget * w, bool force)
-{
- static QCursor arrowCursor(Qt::ArrowCursor);
- static QPointer<QWidget> lastUnderMouse = 0;
-
- QCursor * override = QApplication::overrideCursor();
-
- if (override && w != 0)
- return;
-
- QWidget *cursorWidget;
- QCursor cursorCursor;
-
- do {
- if (w == 0) {
- if (override) {
- cursorCursor = *override;
- cursorWidget = QApplication::topLevelAt(QCursor::pos());
- break;
- }
- w = QApplication::widgetAt(QCursor::pos());
- if (w == 0) // clear the override cursor while over empty space
- w = QApplication::desktop();
- } else if (force) {
- lastUnderMouse = w;
- } else if (w->testAttribute(Qt::WA_WState_Created) && lastUnderMouse
- && lastUnderMouse->effectiveWinId() == w->effectiveWinId()) {
- w = lastUnderMouse;
- }
- if (w == QApplication::desktop() && !override) {
- cursorCursor = arrowCursor;
- cursorWidget = w;
- break;
- }
-
- QWidget * curWin = QApplication::activeWindow();
- if (!curWin && w && w->internalWinId())
- return;
- QWidget* cW = w && !w->internalWinId() ? w : curWin;
-
- if (!cW || cW->window() != w->window() ||
- !cW->isVisible() || !cW->underMouse() || override)
- return;
-
- cursorCursor = w->cursor();
- cursorWidget = w;
- } while (0);
- foreach (QWeakPointer<QPlatformCursor> cursor, QPlatformCursorPrivate::getInstances())
- if (cursor)
- cursor.data()->changeCursor(&cursorCursor, cursorWidget);
-}
-#endif //QT_NO_CURSOR
-
-QT_END_NAMESPACE
diff --git a/src/gui/kernel/qwidget_qws.cpp b/src/gui/kernel/qwidget_qws.cpp
deleted file mode 100644
index aa90410f3e..0000000000
--- a/src/gui/kernel/qwidget_qws.cpp
+++ /dev/null
@@ -1,1221 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qcursor.h"
-#include "qapplication.h"
-#include "qapplication_p.h"
-#include "qpainter.h"
-#include "qbitmap.h"
-#include "qimage.h"
-#include "qhash.h"
-#include "qstack.h"
-#include "qlayout.h"
-#include "qtextcodec.h"
-#include "qinputcontext.h"
-#include "qdesktopwidget.h"
-
-#include "qwsdisplay_qws.h"
-#include "private/qwsdisplay_qws_p.h"
-#include "qscreen_qws.h"
-#include "qwsmanager_qws.h"
-#include <private/qwsmanager_p.h>
-#include <private/qbackingstore_p.h>
-#include <private/qwindowsurface_qws_p.h>
-#include <private/qwslock_p.h>
-#include "qpaintengine.h"
-
-#include "qdebug.h"
-
-#include "qwidget_p.h"
-
-QT_BEGIN_NAMESPACE
-
-QT_USE_NAMESPACE
-
-extern int *qt_last_x;
-extern int *qt_last_y;
-extern WId qt_last_cursor;
-extern bool qws_overrideCursor;
-extern QWidget *qt_pressGrab;
-extern QWidget *qt_mouseGrb;
-
-static QWidget *keyboardGrb = 0;
-
-static int takeLocalId()
-{
- static int n=-1000;
- return --n;
-}
-
-class QWSServer;
-extern QWSServer *qwsServer;
-
-static inline bool isServerProcess()
-{
- return (qwsServer != 0);
-}
-
-/*****************************************************************************
- QWidget member functions
- *****************************************************************************/
-
-void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool /*destroyOldWindow*/)
-{
- Q_Q(QWidget);
- Qt::WindowType type = q->windowType();
-
- // Make sure the WindowTitleHint is on if any of the title bar hints are set
- // Note: This might be moved to cross-platform QWidgetPrivate::adjustFlags()
- if ( !(data.window_flags & Qt::CustomizeWindowHint) && (
- (data.window_flags & Qt::WindowSystemMenuHint) ||
- (data.window_flags & Qt::WindowContextHelpButtonHint) ||
- (data.window_flags & Qt::WindowMinimizeButtonHint) ||
- (data.window_flags & Qt::WindowMaximizeButtonHint) ||
- (data.window_flags & Qt::WindowCloseButtonHint) ) ) {
- data.window_flags |= Qt::WindowTitleHint;
- }
-
- // Decoration plugins on QWS don't support switching on the close button on its own
- if (data.window_flags & Qt::WindowCloseButtonHint)
- data.window_flags |= Qt::WindowSystemMenuHint;
-
- Qt::WindowFlags flags = data.window_flags;
-
- data.alloc_region_index = -1;
-
- // we don't have a "Drawer" window type
- if (type == Qt::Drawer) {
- type = Qt::Widget;
- flags &= ~Qt::WindowType_Mask;
- }
-
-
- bool topLevel = (flags & Qt::Window);
- bool popup = (type == Qt::Popup);
- bool dialog = (type == Qt::Dialog
- || type == Qt::Sheet
- || (flags & Qt::MSWindowsFixedSizeDialogHint));
- bool desktop = (type == Qt::Desktop);
- bool tool = (type == Qt::Tool || type == Qt::SplashScreen || type == Qt::ToolTip);
-
-
-#ifndef QT_NO_WARNING_OUTPUT
- static bool toolWarningShown = false;
- if (!toolWarningShown && type == Qt::Tool && !(flags & Qt::FramelessWindowHint)) {
- qWarning("Qt for Embedded Linux " QT_VERSION_STR " does not support tool windows with frames.\n"
- "This behavior will change in a later release. To ensure compatibility with\n"
- "future versions, use (Qt::Tool | Qt::FramelessWindowHint).");
- toolWarningShown = true;
- }
-#endif
-
- WId id;
- QWSDisplay* dpy = QWidget::qwsDisplay();
-
- if (!window) // always initialize
- initializeWindow = true;
-
- // use the size of the primary screen to determine the default window size
- QList<QScreen *> screens = qt_screen->subScreens();
- if (screens.isEmpty())
- screens.append(qt_screen);
- int sw = screens[0]->width();
- int sh = screens[0]->height();
-
- if (desktop) { // desktop widget
- dialog = popup = false; // force these flags off
- data.crect.setRect(0, 0, sw, sh);
- } else if (topLevel && !q->testAttribute(Qt::WA_Resized)) {
- int width = sw / 2;
- int height = 4 * sh / 10;
- if (extra) {
- width = qMax(qMin(width, extra->maxw), extra->minw);
- height = qMax(qMin(height, extra->maxh), extra->minh);
- }
- data.crect.setSize(QSize(width, height));
- }
-
- if (window) { // override the old window
- id = window;
- setWinId(window);
- } else if (desktop) { // desktop widget
- id = (WId)-2; // id = root window
-#if 0
- QWidget *otherDesktop = q->find(id); // is there another desktop?
- if (otherDesktop && otherDesktop->testWFlags(Qt::WPaintDesktop)) {
- otherDesktop->d_func()->setWinId(0); // remove id from widget mapper
- setWinId(id); // make sure otherDesktop is
- otherDesktop->d_func()->setWinId(id); // found first
- } else
-#endif
- {
- setWinId(id);
- }
- } else {
- id = topLevel ? dpy->takeId() : takeLocalId();
- setWinId(id); // set widget id/handle + hd
- }
-
-
- bool hasFrame = true;
- if (topLevel) {
- if (desktop || popup || tool || q->testAttribute(Qt::WA_DontShowOnScreen))
- hasFrame = false;
- else
- hasFrame = !(flags & Qt::FramelessWindowHint);
- }
- if (desktop) {
- q->setAttribute(Qt::WA_WState_Visible);
- } else if (topLevel) { // set X cursor
- //QCursor *oc = QApplication::overrideCursor();
- if (initializeWindow) {
- //XXX XDefineCursor(dpy, winid, oc ? oc->handle() : cursor().handle());
- }
- QWidget::qwsDisplay()->nameRegion(q->internalWinId(), q->objectName(), q->windowTitle());
- }
-
- if (topLevel) {
- createTLExtra();
- QTLWExtra *topextra = extra->topextra;
-#ifndef QT_NO_QWS_MANAGER
- if (hasFrame) {
- // get size of wm decoration and make the old crect the new frect
- QRect cr = data.crect;
- QRegion r = QApplication::qwsDecoration().region(q, cr) | cr;
- QRect br(r.boundingRect());
- topextra->frameStrut.setCoords(cr.x() - br.x(),
- cr.y() - br.y(),
- br.right() - cr.right(),
- br.bottom() - cr.bottom());
- if (!q->testAttribute(Qt::WA_Moved) || topextra->posFromMove)
- data.crect.translate(topextra->frameStrut.left(), topextra->frameStrut.top());
- if (!topData()->qwsManager) {
- topData()->qwsManager = new QWSManager(q);
- if((q->data->window_state & ~Qt::WindowActive) == Qt::WindowMaximized)
- topData()->qwsManager->maximize();
- }
-
- } else if (topData()->qwsManager) {
- delete topData()->qwsManager;
- topData()->qwsManager = 0;
- data.crect.translate(-topextra->frameStrut.left(), -topextra->frameStrut.top());
- topextra->frameStrut.setCoords(0, 0, 0, 0);
- }
-#endif
- if (!topextra->caption.isEmpty())
- setWindowTitle_helper(topextra->caption);
-
- //XXX If we are session managed, inform the window manager about it
- } else {
- if (extra && extra->topextra) { // already allocated due to reparent?
- extra->topextra->frameStrut.setCoords(0, 0, 0, 0);
- }
- //updateRequestedRegion(mapToGlobal(QPoint(0,0)));
- }
-}
-
-
-void QWidget::destroy(bool destroyWindow, bool destroySubWindows)
-{
- Q_D(QWidget);
- d->aboutToDestroy();
- if (!isWindow() && parentWidget())
- parentWidget()->d_func()->invalidateBuffer(d->effectiveRectFor(geometry()));
-
- d->deactivateWidgetCleanup();
- if (testAttribute(Qt::WA_WState_Created)) {
- setAttribute(Qt::WA_WState_Created, false);
- QObjectList childObjects = children();
- for (int i = 0; i < childObjects.size(); ++i) {
- QObject *obj = childObjects.at(i);
- if (obj->isWidgetType())
- static_cast<QWidget*>(obj)->destroy(destroySubWindows,
- destroySubWindows);
- }
- releaseMouse();
- if (qt_pressGrab == this)
- qt_pressGrab = 0;
-
- if (keyboardGrb == this)
- releaseKeyboard();
- if (testAttribute(Qt::WA_ShowModal)) // just be sure we leave modal
- QApplicationPrivate::leaveModal(this);
- else if ((windowType() == Qt::Popup))
- qApp->d_func()->closePopup(this);
-#ifndef QT_NO_IM
- if (d->ic) {
- delete d->ic;
- d->ic =0;
- } else {
- // release previous focus information participating with
- // preedit preservation of qic -- while we still have a winId
- QInputContext *qic = QApplicationPrivate::inputContext;
- if (qic)
- qic->widgetDestroyed(this);
- }
-#endif //QT_NO_IM
-
- if ((windowType() == Qt::Desktop)) {
- } else {
- if (parentWidget() && parentWidget()->testAttribute(Qt::WA_WState_Created)) {
- d->hide_sys();
- }
- if (destroyWindow && isWindow()) {
- if (d->extra && d->extra->topextra && d->extra->topextra->backingStore)
- d->extra->topextra->backingStore->windowSurface->setGeometry(QRect());
- qwsDisplay()->destroyRegion(internalWinId());
- }
- }
- QT_TRY {
- d->setWinId(0);
- } QT_CATCH (const std::bad_alloc &) {
- // swallow - destructors must not throw
- }
- }
-}
-
-
-void QWidgetPrivate::setParent_sys(QWidget *newparent, Qt::WindowFlags f)
-{
- Q_Q(QWidget);
- bool wasCreated = q->testAttribute(Qt::WA_WState_Created);
- if (q->isVisible() && q->parentWidget() && parent != q->parentWidget())
- q->parentWidget()->d_func()->invalidateBuffer(effectiveRectFor(q->geometry()));
-#ifndef QT_NO_CURSOR
- QCursor oldcurs;
- bool setcurs=q->testAttribute(Qt::WA_SetCursor);
- if (setcurs) {
- oldcurs = q->cursor();
- q->unsetCursor();
- }
-#endif
-
- WId old_winid = data.winid;
- if ((q->windowType() == Qt::Desktop))
- old_winid = 0;
-
- if (!q->isWindow() && q->parentWidget() && q->parentWidget()->testAttribute(Qt::WA_WState_Created))
- hide_sys();
-
- setWinId(0);
-
- if (parent != newparent) {
- QWidget *oldparent = q->parentWidget();
- QObjectPrivate::setParent_helper(newparent);
- if (oldparent) {
-// oldparent->d_func()->setChildrenAllocatedDirty();
-// oldparent->data->paintable_region_dirty = true;
- }
- if (newparent) {
-// newparent->d_func()->setChildrenAllocatedDirty();
-// newparent->data->paintable_region_dirty = true;
- //@@@@@@@
- }
- }
- Qt::FocusPolicy fp = q->focusPolicy();
- QSize s = q->size();
- //QBrush bgc = background(); // save colors
- bool explicitlyHidden = q->testAttribute(Qt::WA_WState_Hidden) && q->testAttribute(Qt::WA_WState_ExplicitShowHide);
-
- data.window_flags = f;
- q->setAttribute(Qt::WA_WState_Created, false);
- q->setAttribute(Qt::WA_WState_Visible, false);
- q->setAttribute(Qt::WA_WState_Hidden, false);
- adjustFlags(data.window_flags, q);
- // keep compatibility with previous versions, we need to preserve the created state
- // (but we recreate the winId for the widget being reparented, again for compatibility)
- if (wasCreated || (!q->isWindow() && newparent->testAttribute(Qt::WA_WState_Created)))
- createWinId();
- if (q->isWindow() || (!newparent || newparent->isVisible()) || explicitlyHidden)
- q->setAttribute(Qt::WA_WState_Hidden);
- q->setAttribute(Qt::WA_WState_ExplicitShowHide, explicitlyHidden);
-
- if (q->isWindow()) {
- QRect fs = frameStrut();
- data.crect = QRect(fs.left(), fs.top(), s.width(), s.height());
- if ((data.window_flags & Qt::FramelessWindowHint) && extra && extra->topextra)
- extra->topextra->frameStrut.setCoords(0, 0, 0, 0);
- } else {
- data.crect = QRect(0, 0, s.width(), s.height());
- }
-
- q->setFocusPolicy(fp);
- if (extra && !extra->mask.isEmpty()) {
- QRegion r = extra->mask;
- extra->mask = QRegion();
- q->setMask(r);
- }
- if ((int)old_winid > 0) {
- QWidget::qwsDisplay()->destroyRegion(old_winid);
- extra->topextra->backingStore->windowSurface->setGeometry(QRect());
- }
-#ifndef QT_NO_CURSOR
- if (setcurs) {
- q->setCursor(oldcurs);
- }
-#endif
-}
-
-
-QPoint QWidget::mapToGlobal(const QPoint &pos) const
-{
- int x=pos.x(), y=pos.y();
- const QWidget* w = this;
- while (w) {
- x += w->data->crect.x();
- y += w->data->crect.y();
- w = w->isWindow() ? 0 : w->parentWidget();
- }
- return QPoint(x, y);
-}
-
-QPoint QWidget::mapFromGlobal(const QPoint &pos) const
-{
- int x=pos.x(), y=pos.y();
- const QWidget* w = this;
- while (w) {
- x -= w->data->crect.x();
- y -= w->data->crect.y();
- w = w->isWindow() ? 0 : w->parentWidget();
- }
- return QPoint(x, y);
-}
-
-#if 0 // #####
-void QWidget::setMicroFocusHint(int x, int y, int width, int height,
- bool text, QFont *)
-{
- if (QRect(x, y, width, height) != microFocusHint()) {
- d->createExtra();
- d->extra->micro_focus_hint.setRect(x, y, width, height);
- }
-#ifndef QT_NO_QWS_INPUTMETHODS
- if (text) {
- QWidget *tlw = window();
- int winid = tlw->internalWinId();
- QPoint p(x, y + height);
- QPoint gp = mapToGlobal(p);
-
- QRect r = QRect(mapToGlobal(QPoint(0,0)),
- size());
-
- r.setBottom(tlw->geometry().bottom());
-
- //qDebug("QWidget::setMicroFocusHint %d %d %d %d", r.x(),
- // r.y(), r.width(), r.height());
- QInputContext::setMicroFocusWidget(this);
-
- qwsDisplay()->setIMInfo(winid, gp.x(), gp.y(), r);
-
- //send font info, ###if necessary
- qwsDisplay()->setInputFont(winid, font());
- }
-#endif
-}
-#endif
-
-void QWidgetPrivate::updateSystemBackground() {}
-
-#ifndef QT_NO_CURSOR
-void QWidgetPrivate::setCursor_sys(const QCursor &cursor)
-{
- Q_UNUSED(cursor);
- Q_Q(QWidget);
- if (q->isVisible())
- updateCursor();
-}
-
-void QWidgetPrivate::unsetCursor_sys()
-{
- Q_Q(QWidget);
- if (q->isVisible())
- updateCursor();
-}
-#endif //QT_NO_CURSOR
-
-void QWidgetPrivate::setWindowTitle_sys(const QString &caption)
-{
- Q_Q(QWidget);
- QWidget::qwsDisplay()->setWindowCaption(q, caption);
-}
-
-void QWidgetPrivate::setWindowIcon_sys(bool /*forceReset*/)
-{
-#if 0
- QTLWExtra* x = d->topData();
- delete x->icon;
- x->icon = 0;
- QBitmap mask;
- if (unscaledPixmap.isNull()) {
- } else {
- QImage unscaledIcon = unscaledPixmap.toImage();
- QPixmap pixmap =
- QPixmap::fromImage(unscaledIcon.scale(16, 16, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
- x->icon = new QPixmap(pixmap);
- mask = pixmap.mask() ? *pixmap.mask() : pixmap.createHeuristicMask();
- }
-#endif
-}
-
-void QWidgetPrivate::setWindowIconText_sys(const QString &iconText)
-{
- Q_UNUSED(iconText);
-}
-
-void QWidget::grabMouse()
-{
- if (qt_mouseGrb)
- qt_mouseGrb->releaseMouse();
-
- qwsDisplay()->grabMouse(this,true);
-
- qt_mouseGrb = this;
- qt_pressGrab = 0;
-}
-
-#ifndef QT_NO_CURSOR
-void QWidget::grabMouse(const QCursor &cursor)
-{
- if (qt_mouseGrb)
- qt_mouseGrb->releaseMouse();
-
- qwsDisplay()->grabMouse(this,true);
- qwsDisplay()->selectCursor(this, cursor.handle());
- qt_mouseGrb = this;
- qt_pressGrab = 0;
-}
-#endif
-
-void QWidget::releaseMouse()
-{
- if (qt_mouseGrb == this) {
- qwsDisplay()->grabMouse(this,false);
- qt_mouseGrb = 0;
- }
-}
-
-void QWidget::grabKeyboard()
-{
- if (keyboardGrb)
- keyboardGrb->releaseKeyboard();
- qwsDisplay()->grabKeyboard(this, true);
- keyboardGrb = this;
-}
-
-void QWidget::releaseKeyboard()
-{
- if (keyboardGrb == this) {
- qwsDisplay()->grabKeyboard(this, false);
- keyboardGrb = 0;
- }
-}
-
-
-QWidget *QWidget::mouseGrabber()
-{
- if (qt_mouseGrb)
- return qt_mouseGrb;
- return qt_pressGrab;
-}
-
-
-QWidget *QWidget::keyboardGrabber()
-{
- return keyboardGrb;
-}
-
-void QWidget::activateWindow()
-{
- QWidget *tlw = window();
- if (tlw->isVisible()) {
- Q_ASSERT(tlw->testAttribute(Qt::WA_WState_Created));
- qwsDisplay()->requestFocus(tlw->internalWinId(), true);
- }
-}
-
-void QWidgetPrivate::show_sys()
-{
- Q_Q(QWidget);
- q->setAttribute(Qt::WA_Mapped);
- if (q->testAttribute(Qt::WA_DontShowOnScreen)) {
- invalidateBuffer(q->rect());
- return;
- }
-
- if (q->isWindow()) {
-
-
- if (!q->testAttribute(Qt::WA_ShowWithoutActivating)
- && q->windowType() != Qt::Popup
- && q->windowType() != Qt::Tool
- && q->windowType() != Qt::ToolTip) {
- QWidget::qwsDisplay()->requestFocus(data.winid,true);
- }
-
-
- if (QWindowSurface *surface = q->windowSurface()) {
- const QRect frameRect = q->frameGeometry();
- if (surface->geometry() != frameRect)
- surface->setGeometry(frameRect);
- }
-
- QRegion r = localRequestedRegion();
-#ifndef QT_NO_QWS_MANAGER
- if (extra && extra->topextra && extra->topextra->qwsManager) {
- r.translate(data.crect.topLeft());
- r += extra->topextra->qwsManager->region();
- r.translate(-data.crect.topLeft());
- }
-#endif
- data.fstrut_dirty = true;
- invalidateBuffer(r);
- bool staysontop =
- (q->windowFlags() & Qt::WindowStaysOnTopHint)
- || q->windowType() == Qt::Popup;
- if (!staysontop && q->parentWidget()) { // if our parent stays on top, so must we
- QWidget *ptl = q->parentWidget()->window();
- if (ptl && (ptl->windowFlags() & Qt::WindowStaysOnTopHint))
- staysontop = true;
- }
-
- QWSChangeAltitudeCommand::Altitude altitude;
- altitude = staysontop ? QWSChangeAltitudeCommand::StaysOnTop : QWSChangeAltitudeCommand::Raise;
- QWidget::qwsDisplay()->setAltitude(data.winid, altitude, true);
- if (!q->objectName().isEmpty()) {
- QWidget::qwsDisplay()->setWindowCaption(q, q->windowTitle());
- }
- }
-#ifdef Q_BACKINGSTORE_SUBSURFACES
- else if ( extra && extra->topextra && extra->topextra->windowSurface) {
- QWSWindowSurface *surface;
- surface = static_cast<QWSWindowSurface*>(q->windowSurface());
- const QPoint p = q->mapToGlobal(QPoint());
- surface->setGeometry(QRect(p, q->size()));
- }
-#endif
-
- if (!q->window()->data->in_show) {
- invalidateBuffer(q->rect());
- }
-}
-
-
-void QWidgetPrivate::hide_sys()
-{
- Q_Q(QWidget);
- deactivateWidgetCleanup();
-
- if (q->isWindow()) {
- q->releaseMouse();
-// requestWindowRegion(QRegion());
-
- if (extra->topextra->backingStore)
- extra->topextra->backingStore->releaseBuffer();
-
-
- QWidget::qwsDisplay()->requestFocus(data.winid,false);
- } else {
- QWidget *p = q->parentWidget();
- if (p &&p->isVisible()) {
- invalidateBuffer(q->rect());
- }
- }
-}
-
-
-
-static Qt::WindowStates effectiveState(Qt::WindowStates state)
- {
- if (state & Qt::WindowMinimized)
- return Qt::WindowMinimized;
- else if (state & Qt::WindowFullScreen)
- return Qt::WindowFullScreen;
- else if (state & Qt::WindowMaximized)
- return Qt::WindowMaximized;
- return Qt::WindowNoState;
- }
-
-void QWidgetPrivate::setMaxWindowState_helper()
-{
- // in_set_window_state is usually set in setWindowState(), but this
- // function is used in other functions as well
- // (e.g QApplicationPrivate::setMaxWindowRect())
- const uint old_state = data.in_set_window_state;
- data.in_set_window_state = 1;
-
-#ifndef QT_NO_QWS_MANAGER
- if (extra && extra->topextra && extra->topextra->qwsManager)
- extra->topextra->qwsManager->maximize();
- else
-#endif
- {
- Q_Q(QWidget);
- const QDesktopWidget *desktop = QApplication::desktop();
- const int screen = desktop->screenNumber(q);
- const QRect maxWindowRect = desktop->availableGeometry(screen);
- q->setGeometry(maxWindowRect);
- }
- data.in_set_window_state = old_state;
-}
-
-void QWidgetPrivate::setFullScreenSize_helper()
-{
- Q_Q(QWidget);
-
- const uint old_state = data.in_set_window_state;
- data.in_set_window_state = 1;
-
- const QRect screen = qApp->desktop()->screenGeometry(qApp->desktop()->screenNumber(q));
- q->move(screen.topLeft());
- q->resize(screen.size());
-
- data.in_set_window_state = old_state;
-}
-
-void QWidget::setWindowState(Qt::WindowStates newstate)
-{
- Q_D(QWidget);
- Qt::WindowStates oldstate = windowState();
- if (oldstate == newstate)
- return;
- if (isWindow() && !testAttribute(Qt::WA_WState_Created))
- create();
-
- data->window_state = newstate;
- data->in_set_window_state = 1;
- bool needShow = false;
- Qt::WindowStates newEffectiveState = effectiveState(newstate);
- Qt::WindowStates oldEffectiveState = effectiveState(oldstate);
- if (isWindow() && newEffectiveState != oldEffectiveState) {
- d->createTLExtra();
- if (oldEffectiveState == Qt::WindowNoState) { //normal
- d->topData()->normalGeometry = geometry();
- } else if (oldEffectiveState == Qt::WindowFullScreen) {
- setParent(0, d->topData()->savedFlags);
- needShow = true;
- } else if (oldEffectiveState == Qt::WindowMinimized) {
- needShow = true;
- }
-
- if (newEffectiveState == Qt::WindowMinimized) {
- //### not ideal...
- hide();
- needShow = false;
- } else if (newEffectiveState == Qt::WindowFullScreen) {
- d->topData()->savedFlags = windowFlags();
- setParent(0, Qt::FramelessWindowHint | (windowFlags() & Qt::WindowStaysOnTopHint));
- d->setFullScreenSize_helper();
- raise();
- needShow = true;
- } else if (newEffectiveState == Qt::WindowMaximized) {
- createWinId();
- d->setMaxWindowState_helper();
- } else { //normal
- QRect r = d->topData()->normalGeometry;
- if (r.width() >= 0) {
- d->topData()->normalGeometry = QRect(0,0,-1,-1);
- setGeometry(r);
- }
- }
- }
- data->in_set_window_state = 0;
-
- if (needShow)
- show();
-
- if (newstate & Qt::WindowActive)
- activateWindow();
-
- QWindowStateChangeEvent e(oldstate);
- QApplication::sendEvent(this, &e);
-}
-
-void QWidgetPrivate::setFocus_sys()
-{
-
-}
-
-void QWidgetPrivate::raise_sys()
-{
- Q_Q(QWidget);
- //@@@ transaction
- if (q->isWindow()) {
- Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
- QWidget::qwsDisplay()->setAltitude(q->internalWinId(),
- QWSChangeAltitudeCommand::Raise);
- // XXX: subsurfaces?
-#ifdef QT_NO_WINDOWGROUPHINT
-#else
- QObjectList childObjects = q->children();
- if (!childObjects.isEmpty()) {
- QWidgetList toraise;
- for (int i = 0; i < childObjects.size(); ++i) {
- QObject *obj = childObjects.at(i);
- if (obj->isWidgetType()) {
- QWidget* w = static_cast<QWidget*>(obj);
- if (w->isWindow())
- toraise.append(w);
- }
- }
-
- for (int i = 0; i < toraise.size(); ++i) {
- QWidget *w = toraise.at(i);
- if (w->isVisible())
- w->raise();
- }
- }
-#endif // QT_NO_WINDOWGROUPHINT
- }
-}
-
-void QWidgetPrivate::lower_sys()
-{
- Q_Q(QWidget);
- if (q->isWindow()) {
- Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
- QWidget::qwsDisplay()->setAltitude(data.winid,
- QWSChangeAltitudeCommand::Lower);
- } else if (QWidget *p = q->parentWidget()) {
- setDirtyOpaqueRegion();
- p->d_func()->invalidateBuffer(effectiveRectFor(q->geometry()));
- }
-}
-
-void QWidgetPrivate::stackUnder_sys(QWidget*)
-{
- Q_Q(QWidget);
- if (QWidget *p = q->parentWidget()) {
- setDirtyOpaqueRegion();
- p->d_func()->invalidateBuffer(effectiveRectFor(q->geometry()));
- }
-}
-
-void QWidgetPrivate::moveSurface(QWindowSurface *surface, const QPoint &offset)
-{
- QWSWindowSurface *s = static_cast<QWSWindowSurface*>(surface);
- if (!s->move(offset))
- s->invalidateBuffer();
-
- QWSDisplay::instance()->moveRegion(s->winId(), offset.x(), offset.y());
-}
-
-void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove)
-{
- Q_Q(QWidget);
- if (extra) { // any size restrictions?
- w = qMin(w,extra->maxw);
- h = qMin(h,extra->maxh);
- w = qMax(w,extra->minw);
- h = qMax(h,extra->minh);
- }
-
- QPoint oldp = q->geometry().topLeft();
- QSize olds = q->size();
- QRect r(x, y, w, h);
-
- bool isResize = olds != r.size();
- isMove = oldp != r.topLeft(); //### why do we have isMove as a parameter?
-
- // We only care about stuff that changes the geometry, or may
- // cause the window manager to change its state
- if (r.size() == olds && oldp == r.topLeft())
- return;
-
- if (!data.in_set_window_state) {
- q->data->window_state &= ~Qt::WindowMaximized;
- q->data->window_state &= ~Qt::WindowFullScreen;
- if (q->isWindow())
- topData()->normalGeometry = QRect(0, 0, -1, -1);
- }
- QPoint oldPos = q->pos();
- data.crect = r;
-
- if ((q->windowType() == Qt::Desktop))
- return;
-
- if (q->isVisible()) {
-
- bool toplevelMove = false;
- QWSWindowSurface *surface = 0;
-
- if (q->isWindow()) {
- //### ConfigPending not implemented, do we need it?
- //setAttribute(Qt::WA_WState_ConfigPending);
- const QWidgetBackingStore *bs = maybeBackingStore();
- if (bs)
- surface = static_cast<QWSWindowSurface*>(bs->windowSurface);
- if (isMove && !isResize && surface) {
- const QPoint offset(x - oldp.x(), y - oldp.y());
- moveSurface(surface, offset);
- toplevelMove = true; //server moves window, but we must send moveEvent, which might trigger painting
-
-#ifdef Q_BACKINGSTORE_SUBSURFACES
- QList<QWindowSurface*> surfaces = bs->subSurfaces;
- for (int i = 0; i < surfaces.size(); ++i)
- moveSurface(surfaces.at(i), offset);
-#endif
- } else {
- updateFrameStrut();
- }
- }
-
- if (!toplevelMove) {
- if (q->isWindow()) {
- if (surface)
- surface->setGeometry(q->frameGeometry());
- else
- invalidateBuffer(q->rect()); //###
-
-#ifdef Q_BACKINGSTORE_SUBSURFACES
- // XXX: should not resize subsurfaces. Children within a layout
- // will be resized automatically while children with a static
- // geometry should get a new clip region instead.
- const QRect clipRect = q->geometry();
- QWidgetBackingStore *bs = maybeBackingStore();
- QList<QWindowSurface*> surfaces = bs->subSurfaces;
- for (int i = 0; i < surfaces.size(); ++i) {
- QWSWindowSurface *s = static_cast<QWSWindowSurface*>(surfaces.at(i));
- QRect srect = s->geometry();
- s->setGeometry(clipRect & srect);
- }
-#endif
- }
-#ifdef Q_BACKINGSTORE_SUBSURFACES
- // XXX: merge this case with the isWindow() case
- else if (maybeTopData() && maybeTopData()->windowSurface) {
- QWSWindowSurface *surface;
- surface = static_cast<QWSWindowSurface*>(q->windowSurface());
- if (isMove && !isResize) {
- moveSurface(surface, QPoint(x - oldp.x(), y - oldp.y()));
- } else {
- const QPoint p = q->mapToGlobal(QPoint());
- surface->setGeometry(QRect(p, QSize(w, h)));
- }
- }
-#endif
- else {
- if (isMove && !isResize)
- moveRect(QRect(oldPos, olds), x - oldPos.x(), y - oldPos.y());
- else
- invalidateBuffer_resizeHelper(oldPos, olds);
- }
- }
-
- //### must have frame geometry correct before sending move/resize events
- if (isMove) {
- QMoveEvent e(q->pos(), oldPos);
- QApplication::sendEvent(q, &e);
- }
- if (isResize) {
- QResizeEvent e(r.size(), olds);
- QApplication::sendEvent(q, &e);
- }
-
- } else { // not visible
- if (isMove && q->pos() != oldPos)
- q->setAttribute(Qt::WA_PendingMoveEvent, true);
- if (isResize)
- q->setAttribute(Qt::WA_PendingResizeEvent, true);
- }
-}
-
-void QWidgetPrivate::setConstraints_sys()
-{
-}
-
-QScreen* QWidgetPrivate::getScreen() const
-{
- Q_Q(const QWidget);
-
- const QList<QScreen*> subScreens = qt_screen->subScreens();
- if (subScreens.isEmpty() || q->windowType() == Qt::Desktop)
- return qt_screen;
-
- const int screen = QApplication::desktop()->screenNumber(q);
-
- return qt_screen->subScreens().at(screen < 0 ? 0 : screen);
-}
-
-void QWidgetPrivate::scroll_sys(int dx, int dy)
-{
- Q_Q(QWidget);
- scrollChildren(dx, dy);
- scrollRect(q->rect(), dx, dy);
-}
-
-void QWidgetPrivate::scroll_sys(int dx, int dy, const QRect &r)
-{
- scrollRect(r, dx, dy);
-}
-
-int QWidget::metric(PaintDeviceMetric m) const
-{
- Q_D(const QWidget);
-
- int val;
- if (m == PdmWidth) {
- val = data->crect.width();
- } else if (m == PdmWidthMM) {
- const QScreen *screen = d->getScreen();
- val = data->crect.width() * screen->physicalWidth() / screen->width();
- } else if (m == PdmHeight) {
- val = data->crect.height();
- } else if (m == PdmHeightMM) {
- const QScreen *screen = d->getScreen();
- val = data->crect.height() * screen->physicalHeight() / screen->height();
- } else if (m == PdmDepth) {
- return qwsDisplay()->depth();
- } else if (m == PdmDpiX || m == PdmPhysicalDpiX) {
- if (d->extra && d->extra->customDpiX)
- return d->extra->customDpiX;
- else if (d->parent)
- return static_cast<QWidget *>(d->parent)->metric(m);
- const QScreen *screen = d->getScreen();
- return qRound(screen->width() / double(screen->physicalWidth() / 25.4));
- } else if (m == PdmDpiY || m == PdmPhysicalDpiY) {
- if (d->extra && d->extra->customDpiY)
- return d->extra->customDpiY;
- else if (d->parent)
- return static_cast<QWidget *>(d->parent)->metric(m);
- const QScreen *screen = d->getScreen();
- return qRound(screen->height() / double(screen->physicalHeight() / 25.4));
- } else if (m == PdmNumColors) {
- QScreen *screen = d->getScreen();
- int ret = screen->colorCount();
- if (!ret) {
- const int depth = qwsDisplay()->depth();
- switch (depth) {
- case 1:
- ret = 2;
- break;
- case 8:
- ret = 256;
- break;
- case 16:
- ret = 65536;
- break;
- case 24:
- ret = 16777216;
- break;
- case 32:
- ret = 2147483647;
- break;
- }
- }
- return ret;
- } else {
- val = QPaintDevice::metric(m);// XXX
- }
- return val;
-}
-
-void QWidgetPrivate::createSysExtra()
-{
-}
-
-void QWidgetPrivate::deleteSysExtra()
-{
-}
-
-void QWidgetPrivate::createTLSysExtra()
-{
-#ifndef QT_NO_QWS_MANAGER
- extra->topextra->qwsManager = 0;
-#endif
-}
-
-void QWidgetPrivate::deleteTLSysExtra()
-{
-}
-
-void QWidgetPrivate::registerDropSite(bool on)
-{
- Q_UNUSED(on);
-}
-
-QRegion QWidgetPrivate::localRequestedRegion() const
-{
- Q_Q(const QWidget);
- QRegion r(q->rect());
- if (extra && !extra->mask.isEmpty())
- r &= extra->mask;
-
- return r;
-}
-
-QRegion QWidgetPrivate::localAllocatedRegion() const
-{
- Q_Q(const QWidget);
-
- QWidgetBackingStore *wbs = q->window()->d_func()->maybeBackingStore();
-
- QWindowSurface *ws = wbs ? wbs->windowSurface : 0;
- if (!ws)
- return QRegion();
- QRegion r = static_cast<QWSWindowSurface*>(ws)->clipRegion();
- if (!q->isWindow()) {
- QPoint off = q->mapTo(q->window(), QPoint());
- r &= localRequestedRegion().translated(off);
- r.translate(-off);
- }
- return r;
-}
-
-inline bool QRect::intersects(const QRect &r) const
-{
- return (qMax(x1, r.x1) <= qMin(x2, r.x2) &&
- qMax(y1, r.y1) <= qMin(y2, r.y2));
-}
-
-void QWidgetPrivate::setMask_sys(const QRegion &region)
-{
- Q_UNUSED(region);
- Q_Q(QWidget);
-
- if (!q->isVisible() || !q->isWindow())
- return;
-
- data.fstrut_dirty = true;
- invalidateBuffer(q->rect());
- QWindowSurface *surface = extra->topextra->backingStore->windowSurface;
- if (surface) {
- // QWSWindowSurface::setGeometry() returns without doing anything
- // if old geom == new geom. Therefore, we need to reset the old value.
- surface->QWindowSurface::setGeometry(QRect());
- surface->setGeometry(q->frameGeometry());
- }
-}
-
-void QWidgetPrivate::updateFrameStrut()
-{
- Q_Q(QWidget);
-
- if(!q->isVisible() || (q->windowType() == Qt::Desktop)) {
- data.fstrut_dirty = q->isVisible();
- return;
- }
-
-#ifndef QT_NO_QWS_MANAGER
- if (extra && extra->topextra && extra->topextra->qwsManager) {
- QTLWExtra *topextra = extra->topextra;
- const QRect oldFrameStrut = topextra->frameStrut;
- const QRect contents = data.crect;
- QRegion r = localRequestedRegion().translated(contents.topLeft());
- r += extra->topextra->qwsManager->region();
- const QRect frame = r.boundingRect();
-
- topextra->frameStrut.setCoords(contents.left() - frame.left(),
- contents.top() - frame.top(),
- frame.right() - contents.right(),
- frame.bottom() - contents.bottom());
- topextra->qwsManager->repaintRegion(QDecoration::All, QDecoration::Normal);
- }
-#endif
- data.fstrut_dirty = false;
-}
-
-#ifndef QT_NO_CURSOR
-void QWidgetPrivate::updateCursor() const
-{
- Q_Q(const QWidget);
-
- if (QApplication::overrideCursor())
- return;
-
- if (qt_last_x
- && (!QWidget::mouseGrabber() || QWidget::mouseGrabber() == q)
- && qt_last_cursor != (WId)q->cursor().handle())
- {
- const QPoint pos(*qt_last_x, *qt_last_y);
- const QPoint offset = q->mapToGlobal(QPoint());
- if (!localAllocatedRegion().contains(pos - offset))
- return;
-
- const QWidget *w = q->childAt(q->mapFromGlobal(pos));
- if (!w || w->cursor().handle() == q->cursor().handle())
- QWidget::qwsDisplay()->selectCursor(const_cast<QWidget*>(q),
- q->cursor().handle());
- }
-}
-#endif
-
-void QWidgetPrivate::setWindowOpacity_sys(qreal level)
-{
- Q_Q(QWidget);
- Q_UNUSED(level);
- createWinId();
- QWidget::qwsDisplay()->setOpacity(q->data->winid, topData()->opacity);
-}
-
-//static QSingleCleanupHandler<QWSPaintEngine> qt_paintengine_cleanup_handler;
-//static QWSPaintEngine *qt_widget_paintengine = 0;
-QPaintEngine *QWidget::paintEngine() const
-{
- qWarning("QWidget::paintEngine: Should no longer be called");
- return 0; //##### @@@
-// if (!qt_widget_paintengine) {
-// qt_widget_paintengine = new QRasterPaintEngine();
-// qt_paintengine_cleanup_handler.set(&qt_widget_paintengine);
-// }
-// if (qt_widget_paintengine->isActive()) {
-// if (d->extraPaintEngine)
-// return d->extraPaintEngine;
-// const_cast<QWidget *>(this)->d_func()->extraPaintEngine = new QRasterPaintEngine();
-// return d->extraPaintEngine;
-// }
-// return qt_widget_paintengine;
-}
-
-QWindowSurface *QWidgetPrivate::createDefaultWindowSurface_sys()
-{
- Q_Q(QWidget);
- if (q->windowType() == Qt::Desktop)
- return 0;
- q->ensurePolished();
- return qt_screen->createSurface(q);
-}
-
-void QWidgetPrivate::setModal_sys()
-{
-}
-
-
-QT_END_NAMESPACE
diff --git a/src/gui/kernel/qwidget_x11.cpp b/src/gui/kernel/qwidget_x11.cpp
deleted file mode 100644
index eaa9405c36..0000000000
--- a/src/gui/kernel/qwidget_x11.cpp
+++ /dev/null
@@ -1,3149 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qevent.h"
-#include "qwidget.h"
-#include "qdesktopwidget.h"
-#include "qapplication.h"
-#include "qapplication_p.h"
-#include "qnamespace.h"
-#include "qpainter.h"
-#include "qbitmap.h"
-#include "qlayout.h"
-#include "qtextcodec.h"
-#include "qelapsedtimer.h"
-#include "qcursor.h"
-#include "qstack.h"
-#include "qcolormap.h"
-#include "qdebug.h"
-#include "qmenu.h"
-#include "private/qmenu_p.h"
-#include "private/qbackingstore_p.h"
-#include "private/qwindowsurface_x11_p.h"
-
-//extern bool qt_sendSpontaneousEvent(QObject *, QEvent *); //qapplication_x11.cpp
-
-#include <private/qpixmap_x11_p.h>
-#include <private/qpaintengine_x11_p.h>
-#include "qt_x11_p.h"
-#include "qx11info_x11.h"
-
-#include <stdlib.h>
-
-//#define ALIEN_DEBUG
-
-// defined in qapplication_x11.cpp
-//bool qt_wstate_iconified(WId);
-//void qt_updated_rootinfo();
-
-
-#if !defined(QT_NO_IM)
-#include "qinputcontext.h"
-#include "qinputcontextfactory.h"
-#endif
-
-#include "qwidget_p.h"
-
-#define XCOORD_MAX 16383
-#define WRECT_MAX 8191
-
-QT_BEGIN_NAMESPACE
-
-extern bool qt_nograb();
-
-QWidget *QWidgetPrivate::mouseGrabber = 0;
-QWidget *QWidgetPrivate::keyboardGrabber = 0;
-
-void qt_net_remove_user_time(QWidget *tlw);
-void qt_net_update_user_time(QWidget *tlw, unsigned long timestamp);
-
-int qt_x11_create_desktop_on_screen = -1;
-
-extern void qt_net_update_user_time(QWidget *tlw, unsigned long timestamp);
-
-// MWM support
-struct QtMWMHints {
- ulong flags, functions, decorations;
- long input_mode;
- ulong status;
-};
-
-enum {
- MWM_HINTS_FUNCTIONS = (1L << 0),
-
- MWM_FUNC_ALL = (1L << 0),
- MWM_FUNC_RESIZE = (1L << 1),
- MWM_FUNC_MOVE = (1L << 2),
- MWM_FUNC_MINIMIZE = (1L << 3),
- MWM_FUNC_MAXIMIZE = (1L << 4),
- MWM_FUNC_CLOSE = (1L << 5),
-
- MWM_HINTS_DECORATIONS = (1L << 1),
-
- MWM_DECOR_ALL = (1L << 0),
- MWM_DECOR_BORDER = (1L << 1),
- MWM_DECOR_RESIZEH = (1L << 2),
- MWM_DECOR_TITLE = (1L << 3),
- MWM_DECOR_MENU = (1L << 4),
- MWM_DECOR_MINIMIZE = (1L << 5),
- MWM_DECOR_MAXIMIZE = (1L << 6),
-
- MWM_HINTS_INPUT_MODE = (1L << 2),
-
- MWM_INPUT_MODELESS = 0L,
- MWM_INPUT_PRIMARY_APPLICATION_MODAL = 1L,
- MWM_INPUT_FULL_APPLICATION_MODAL = 3L
-};
-
-
-static QtMWMHints GetMWMHints(Display *display, Window window)
-{
- QtMWMHints mwmhints;
-
- Atom type;
- int format;
- ulong nitems, bytesLeft;
- uchar *data = 0;
- if ((XGetWindowProperty(display, window, ATOM(_MOTIF_WM_HINTS), 0, 5, false,
- ATOM(_MOTIF_WM_HINTS), &type, &format, &nitems, &bytesLeft,
- &data) == Success)
- && (type == ATOM(_MOTIF_WM_HINTS)
- && format == 32
- && nitems >= 5)) {
- mwmhints = *(reinterpret_cast<QtMWMHints *>(data));
- } else {
- mwmhints.flags = 0L;
- mwmhints.functions = MWM_FUNC_ALL;
- mwmhints.decorations = MWM_DECOR_ALL;
- mwmhints.input_mode = 0L;
- mwmhints.status = 0L;
- }
-
- if (data)
- XFree(data);
-
- return mwmhints;
-}
-
-static void SetMWMHints(Display *display, Window window, const QtMWMHints &mwmhints)
-{
- if (mwmhints.flags != 0l) {
- XChangeProperty(display, window, ATOM(_MOTIF_WM_HINTS), ATOM(_MOTIF_WM_HINTS), 32,
- PropModeReplace, (unsigned char *) &mwmhints, 5);
- } else {
- XDeleteProperty(display, window, ATOM(_MOTIF_WM_HINTS));
- }
-}
-
-// Returns true if we should set WM_TRANSIENT_FOR on \a w
-static inline bool isTransient(const QWidget *w)
-{
- return ((w->windowType() == Qt::Dialog
- || w->windowType() == Qt::Sheet
- || w->windowType() == Qt::Tool
- || w->windowType() == Qt::SplashScreen
- || w->windowType() == Qt::ToolTip
- || w->windowType() == Qt::Drawer
- || w->windowType() == Qt::Popup)
- && !w->testAttribute(Qt::WA_X11BypassTransientForHint));
-}
-
-static void do_size_hints(QWidget* widget, QWExtra *x);
-
-/*****************************************************************************
- QWidget member functions
- *****************************************************************************/
-
-const uint stdWidgetEventMask = // X event mask
- (uint)(
- KeyPressMask | KeyReleaseMask |
- ButtonPressMask | ButtonReleaseMask |
- KeymapStateMask |
- ButtonMotionMask | PointerMotionMask |
- EnterWindowMask | LeaveWindowMask |
- FocusChangeMask |
- ExposureMask |
- PropertyChangeMask |
- StructureNotifyMask
- );
-
-const uint stdDesktopEventMask = // X event mask
- (uint)(
- KeymapStateMask |
- EnterWindowMask | LeaveWindowMask |
- PropertyChangeMask
- );
-
-
-/*
- The qt_ functions below are implemented in qwidgetcreate_x11.cpp.
-*/
-
-Window qt_XCreateWindow(const QWidget *creator,
- Display *display, Window parent,
- int x, int y, uint w, uint h,
- int borderwidth, int depth,
- uint windowclass, Visual *visual,
- ulong valuemask, XSetWindowAttributes *attributes);
-Window qt_XCreateSimpleWindow(const QWidget *creator,
- Display *display, Window parent,
- int x, int y, uint w, uint h, int borderwidth,
- ulong border, ulong background);
-void qt_XDestroyWindow(const QWidget *destroyer,
- Display *display, Window window);
-
-
-static void qt_insert_sip(QWidget* scrolled_widget, int dx, int dy)
-{
- if (!scrolled_widget->isWindow() && !scrolled_widget->internalWinId())
- return;
- QX11Data::ScrollInProgress sip = { X11->sip_serial++, scrolled_widget, dx, dy };
- X11->sip_list.append(sip);
-
- XClientMessageEvent client_message;
- client_message.type = ClientMessage;
- client_message.window = scrolled_widget->internalWinId();
- client_message.format = 32;
- client_message.message_type = ATOM(_QT_SCROLL_DONE);
- client_message.data.l[0] = sip.id;
-
- XSendEvent(X11->display, scrolled_widget->internalWinId(), False, NoEventMask,
- (XEvent*)&client_message);
-}
-
-static int qt_sip_count(QWidget* scrolled_widget)
-{
- int sips=0;
-
- for (int i = 0; i < X11->sip_list.size(); ++i) {
- const QX11Data::ScrollInProgress &sip = X11->sip_list.at(i);
- if (sip.scrolled_widget == scrolled_widget)
- sips++;
- }
-
- return sips;
-}
-
-static void create_wm_client_leader()
-{
- if (X11->wm_client_leader) return;
-
- X11->wm_client_leader =
- XCreateSimpleWindow(X11->display,
- QX11Info::appRootWindow(),
- 0, 0, 1, 1, 0, 0, 0);
-
- // set client leader property to itself
- XChangeProperty(X11->display,
- X11->wm_client_leader, ATOM(WM_CLIENT_LEADER),
- XA_WINDOW, 32, PropModeReplace,
- (unsigned char *)&X11->wm_client_leader, 1);
-
-#ifndef QT_NO_SESSIONMANAGER
- // If we are session managed, inform the window manager about it
- QByteArray session = qApp->sessionId().toLatin1();
- if (!session.isEmpty()) {
- XChangeProperty(X11->display,
- X11->wm_client_leader, ATOM(SM_CLIENT_ID),
- XA_STRING, 8, PropModeReplace,
- (unsigned char *)session.data(), session.size());
- }
-#endif
-}
-
-/*!
- \internal
- Update the X11 cursor of the widget w.
- \a force is true if this function is called from dispatchEnterLeave, it means that the
- mouse is actually directly under this widget.
- */
-void qt_x11_enforce_cursor(QWidget * w, bool force)
-{
- if (!w->testAttribute(Qt::WA_WState_Created))
- return;
-
- static QPointer<QWidget> lastUnderMouse = 0;
- if (force) {
- lastUnderMouse = w;
- } else if (lastUnderMouse && lastUnderMouse->effectiveWinId() == w->effectiveWinId()) {
- w = lastUnderMouse;
- } else if (!w->internalWinId()) {
- return; //the mouse is not under this widget, and it's not native, so don't change it
- }
-
- while (!w->internalWinId() && w->parentWidget() && !w->isWindow() && !w->testAttribute(Qt::WA_SetCursor))
- w = w->parentWidget();
-
- QWidget *nativeParent = w;
- if (!w->internalWinId())
- nativeParent = w->nativeParentWidget();
- // This does the same as effectiveWinId(), but since it is possible
- // to not have a native parent widget due to a special hack in
- // qwidget for reparenting widgets to a different X11 screen,
- // added additional check to make sure native parent widget exists.
- if (!nativeParent || !nativeParent->internalWinId())
- return;
- WId winid = nativeParent->internalWinId();
-
- if (w->isWindow() || w->testAttribute(Qt::WA_SetCursor)) {
-#ifndef QT_NO_CURSOR
- QCursor *oc = QApplication::overrideCursor();
- if (oc) {
- XDefineCursor(X11->display, winid, oc->handle());
- } else if (w->isEnabled()) {
- XDefineCursor(X11->display, winid, w->cursor().handle());
- } else {
- // enforce the windows behavior of clearing the cursor on
- // disabled widgets
- XDefineCursor(X11->display, winid, XNone);
- }
-#endif
- } else {
- XDefineCursor(X11->display, winid, XNone);
- }
-}
-
-Q_GUI_EXPORT void qt_x11_enforce_cursor(QWidget * w)
-{
- qt_x11_enforce_cursor(w, false);
-}
-
-void qt_x11_wait_for_window_manager(QWidget *w, bool sendPostedEvents)
-{
- if (!w || (!w->isWindow() && !w->internalWinId()))
- return;
- QApplication::flush();
- XEvent ev;
- QElapsedTimer t;
- t.start();
- static const int maximumWaitTime = 2000;
- if (!w->testAttribute(Qt::WA_WState_Created))
- return;
-
- WId winid = w->internalWinId();
-
- // first deliver events that are already in the local queue
- if (sendPostedEvents)
- QApplication::sendPostedEvents();
-
- // the normal sequence is:
- // ... ConfigureNotify ... ReparentNotify ... MapNotify ... Expose
- // with X11BypassWindowManagerHint:
- // ConfigureNotify ... MapNotify ... Expose
-
- enum State {
- Initial, Mapped
- } state = Initial;
-
- do {
- if (XEventsQueued(X11->display, QueuedAlready)) {
- XNextEvent(X11->display, &ev);
- qApp->x11ProcessEvent(&ev);
-
- switch (state) {
- case Initial:
- if (ev.type == MapNotify && ev.xany.window == winid)
- state = Mapped;
- break;
- case Mapped:
- if (ev.type == Expose && ev.xany.window == winid)
- return;
- break;
- }
- } else {
- if (!XEventsQueued(X11->display, QueuedAfterFlush))
- qApp->syncX(); // non-busy wait
- }
- if (t.elapsed() > maximumWaitTime)
- return;
- } while(1);
-}
-
-Q_GUI_EXPORT void qt_x11_wait_for_window_manager(QWidget *w)
-{
- qt_x11_wait_for_window_manager(w, true);
-}
-
-void qt_change_net_wm_state(const QWidget* w, bool set, Atom one, Atom two = 0)
-{
- if (!w->isVisible()) // not managed by the window manager
- return;
-
- XEvent e;
- e.xclient.type = ClientMessage;
- e.xclient.message_type = ATOM(_NET_WM_STATE);
- e.xclient.display = X11->display;
- e.xclient.window = w->internalWinId();
- e.xclient.format = 32;
- e.xclient.data.l[0] = set ? 1 : 0;
- e.xclient.data.l[1] = one;
- e.xclient.data.l[2] = two;
- e.xclient.data.l[3] = 0;
- e.xclient.data.l[4] = 0;
- XSendEvent(X11->display, RootWindow(X11->display, w->x11Info().screen()),
- false, (SubstructureNotifyMask | SubstructureRedirectMask), &e);
-}
-
-struct QX11WindowAttributes {
- const XWindowAttributes *att;
-};
-
-void qt_x11_getX11InfoForWindow(QX11Info * xinfo, const XWindowAttributes &a)
-{
- QX11WindowAttributes att;
- att.att = &a;
- qt_x11_getX11InfoForWindow(xinfo,att);
-}
-
-
-static QVector<Atom> getNetWmState(QWidget *w)
-{
- QVector<Atom> returnValue;
-
- // Don't read anything, just get the size of the property data
- Atom actualType;
- int actualFormat;
- ulong propertyLength;
- ulong bytesLeft;
- uchar *propertyData = 0;
- if (XGetWindowProperty(X11->display, w->internalWinId(), ATOM(_NET_WM_STATE), 0, 0,
- False, XA_ATOM, &actualType, &actualFormat,
- &propertyLength, &bytesLeft, &propertyData) == Success
- && actualType == XA_ATOM && actualFormat == 32) {
- returnValue.resize(bytesLeft / 4);
- XFree((char*) propertyData);
- propertyData = 0;
-
- // fetch all data
- if (XGetWindowProperty(X11->display, w->internalWinId(), ATOM(_NET_WM_STATE), 0,
- returnValue.size(), False, XA_ATOM, &actualType, &actualFormat,
- &propertyLength, &bytesLeft, &propertyData) != Success) {
- returnValue.clear();
- } else if (propertyLength != (ulong)returnValue.size()) {
- returnValue.resize(propertyLength);
- }
-
- // put it into netWmState
- if (!returnValue.isEmpty()) {
- memcpy(returnValue.data(), propertyData, returnValue.size() * sizeof(Atom));
- }
- if (propertyData)
- XFree((char*) propertyData);
- }
-
- return returnValue;
-}
-
-void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyOldWindow)
-{
- Q_Q(QWidget);
- Qt::WindowType type = q->windowType();
- Qt::WindowFlags &flags = data.window_flags;
- QWidget *parentWidget = q->parentWidget();
-
- if (type == Qt::ToolTip)
- flags |= Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint;
- if (type == Qt::Popup)
- flags |= Qt::X11BypassWindowManagerHint;
-
- bool topLevel = (flags & Qt::Window);
- bool popup = (type == Qt::Popup);
- bool desktop = (type == Qt::Desktop);
- bool tool = (type == Qt::Tool || type == Qt::SplashScreen
- || type == Qt::ToolTip || type == Qt::Drawer);
-
-#ifdef ALIEN_DEBUG
- qDebug() << "QWidgetPrivate::create_sys START:" << q << "topLevel?" << topLevel << "WId:"
- << window << "initializeWindow:" << initializeWindow << "destroyOldWindow" << destroyOldWindow;
-#endif
- if (topLevel) {
- if (parentWidget) { // if our parent stays on top, so must we
- QWidget *ptl = parentWidget->window();
- if(ptl && (ptl->windowFlags() & Qt::WindowStaysOnTopHint))
- flags |= Qt::WindowStaysOnTopHint;
- }
-
- if (type == Qt::SplashScreen) {
- if (X11->isSupportedByWM(ATOM(_NET_WM_WINDOW_TYPE_SPLASH))) {
- flags &= ~Qt::X11BypassWindowManagerHint;
- } else {
- flags |= Qt::X11BypassWindowManagerHint | Qt::FramelessWindowHint;
- }
- }
- // All these buttons depend on the system menu, so we enable it
- if (flags & (Qt::WindowMinimizeButtonHint
- | Qt::WindowMaximizeButtonHint
- | Qt::WindowContextHelpButtonHint))
- flags |= Qt::WindowSystemMenuHint;
- }
-
-
- Window parentw, destroyw = 0;
- WId id = 0;
-
- // always initialize
- if (!window)
- initializeWindow = true;
-
- QX11Info *parentXinfo = parentWidget ? &parentWidget->d_func()->xinfo : 0;
-
- if (desktop &&
- qt_x11_create_desktop_on_screen >= 0 &&
- qt_x11_create_desktop_on_screen != xinfo.screen()) {
- // desktop on a certain screen other than the default requested
- QX11InfoData *xd = &X11->screens[qt_x11_create_desktop_on_screen];
- xinfo.setX11Data(xd);
- } else if (parentXinfo && (parentXinfo->screen() != xinfo.screen()
- || (parentXinfo->visual() != xinfo.visual()
- && !q->inherits("QGLWidget"))))
- {
- // QGLWidgets have to be excluded here as they have a
- // specially crafted QX11Info structure which can't be swapped
- // out with the parent widgets QX11Info. The parent visual,
- // for instance, might not even be GL capable.
- xinfo = *parentXinfo;
- }
-
- //get display, screen number, root window and desktop geometry for
- //the current screen
- Display *dpy = X11->display;
- int scr = xinfo.screen();
- Window root_win = RootWindow(dpy, scr);
- int sw = DisplayWidth(dpy,scr);
- int sh = DisplayHeight(dpy,scr);
-
- if (desktop) { // desktop widget
- popup = false; // force these flags off
- data.crect.setRect(0, 0, sw, sh);
- } else if (topLevel && !q->testAttribute(Qt::WA_Resized)) {
- QDesktopWidget *desktopWidget = qApp->desktop();
- if (desktopWidget->isVirtualDesktop()) {
- QRect r = desktopWidget->screenGeometry();
- sw = r.width();
- sh = r.height();
- }
-
- int width = sw / 2;
- int height = 4 * sh / 10;
- if (extra) {
- width = qMax(qMin(width, extra->maxw), extra->minw);
- height = qMax(qMin(height, extra->maxh), extra->minh);
- }
- data.crect.setSize(QSize(width, height));
- }
-
- parentw = topLevel ? root_win : parentWidget->effectiveWinId();
-
- XSetWindowAttributes wsa;
-
- if (window) { // override the old window
- if (destroyOldWindow) {
- if (topLevel)
- X11->dndEnable(q, false);
- destroyw = data.winid;
- }
- id = window;
- setWinId(window);
- XWindowAttributes a;
- XGetWindowAttributes(dpy, window, &a);
- data.crect.setRect(a.x, a.y, a.width, a.height);
-
- if (a.map_state == IsUnmapped)
- q->setAttribute(Qt::WA_WState_Visible, false);
- else
- q->setAttribute(Qt::WA_WState_Visible);
-
- qt_x11_getX11InfoForWindow(&xinfo,a);
-
- } else if (desktop) { // desktop widget
-#ifdef QWIDGET_EXTRA_DEBUG
- qDebug() << "create desktop";
-#endif
- id = (WId)parentw; // id = root window
-// QWidget *otherDesktop = find(id); // is there another desktop?
-// if (otherDesktop && otherDesktop->testWFlags(Qt::WPaintDesktop)) {
-// otherDesktop->d->setWinId(0); // remove id from widget mapper
-// d->setWinId(id); // make sure otherDesktop is
-// otherDesktop->d->setWinId(id); // found first
-// } else {
- setWinId(id);
-// }
- } else if (topLevel || q->testAttribute(Qt::WA_NativeWindow) || paintOnScreen()) {
-#ifdef QWIDGET_EXTRA_DEBUG
- static int topLevels = 0;
- static int children = 0;
- if (parentw == root_win)
- qDebug() << "create toplevel" << ++topLevels;
- else
- qDebug() << "create child" << ++children;
-#endif
- QRect safeRect = data.crect; //##### must handle huge sizes as well.... i.e. wrect
- if (safeRect.width() < 1|| safeRect.height() < 1) {
- if (topLevel) {
- // top-levels must be at least 1x1
- safeRect.setSize(safeRect.size().expandedTo(QSize(1, 1)));
- } else {
- // create it way off screen, and rely on
- // setWSGeometry() to do the right thing with it later
- safeRect = QRect(-1000,-1000,1,1);
- }
- }
-#ifndef QT_NO_XRENDER
- int screen = xinfo.screen();
- if (topLevel && X11->use_xrender
- && xinfo.depth() != 32 && X11->argbVisuals[screen]
- && q->testAttribute(Qt::WA_TranslucentBackground))
- {
- QX11InfoData *xd = xinfo.getX11Data(true);
-
- xd->screen = screen;
- xd->visual = X11->argbVisuals[screen];
- xd->colormap = X11->argbColormaps[screen];
- xd->depth = 32;
- xd->defaultVisual = false;
- xd->defaultColormap = false;
- xd->cells = xd->visual->map_entries;
- xinfo.setX11Data(xd);
- }
-#endif
- if (xinfo.defaultVisual() && xinfo.defaultColormap()) {
- id = (WId)qt_XCreateSimpleWindow(q, dpy, parentw,
- safeRect.left(), safeRect.top(),
- safeRect.width(), safeRect.height(),
- 0,
- BlackPixel(dpy, xinfo.screen()),
- WhitePixel(dpy, xinfo.screen()));
- } else {
- wsa.background_pixel = WhitePixel(dpy, xinfo.screen());
- wsa.border_pixel = BlackPixel(dpy, xinfo.screen());
- wsa.colormap = xinfo.colormap();
- id = (WId)qt_XCreateWindow(q, dpy, parentw,
- safeRect.left(), safeRect.top(),
- safeRect.width(), safeRect.height(),
- 0, xinfo.depth(), InputOutput,
- (Visual *) xinfo.visual(),
- CWBackPixel|CWBorderPixel|CWColormap,
- &wsa);
- }
-
- setWinId(id); // set widget id/handle + hd
- }
-
-#ifndef QT_NO_XRENDER
- if (picture) {
- XRenderFreePicture(X11->display, picture);
- picture = 0;
- }
-
- if (X11->use_xrender && !desktop && q->internalWinId()) {
- XRenderPictFormat *format = XRenderFindVisualFormat(dpy, (Visual *) xinfo.visual());
- if (format)
- picture = XRenderCreatePicture(dpy, id, format, 0, 0);
- }
-#endif // QT_NO_XRENDER
-
- QtMWMHints mwmhints;
- mwmhints.flags = 0L;
- mwmhints.functions = 0L;
- mwmhints.decorations = 0;
- mwmhints.input_mode = 0L;
- mwmhints.status = 0L;
-
- if (topLevel) {
- ulong wsa_mask = 0;
- if (type != Qt::SplashScreen) { // && customize) {
- mwmhints.flags |= MWM_HINTS_DECORATIONS;
-
- bool customize = flags & Qt::CustomizeWindowHint;
- if (!(flags & Qt::FramelessWindowHint) && !(customize && !(flags & Qt::WindowTitleHint))) {
- mwmhints.decorations |= MWM_DECOR_BORDER;
- mwmhints.decorations |= MWM_DECOR_RESIZEH;
-
- if (flags & Qt::WindowTitleHint)
- mwmhints.decorations |= MWM_DECOR_TITLE;
-
- if (flags & Qt::WindowSystemMenuHint)
- mwmhints.decorations |= MWM_DECOR_MENU;
-
- if (flags & Qt::WindowMinimizeButtonHint) {
- mwmhints.decorations |= MWM_DECOR_MINIMIZE;
- mwmhints.functions |= MWM_FUNC_MINIMIZE;
- }
-
- if (flags & Qt::WindowMaximizeButtonHint) {
- mwmhints.decorations |= MWM_DECOR_MAXIMIZE;
- mwmhints.functions |= MWM_FUNC_MAXIMIZE;
- }
-
- if (flags & Qt::WindowCloseButtonHint)
- mwmhints.functions |= MWM_FUNC_CLOSE;
- }
- } else {
- // if type == Qt::SplashScreen
- mwmhints.decorations = MWM_DECOR_ALL;
- }
-
- if (tool) {
- wsa.save_under = True;
- wsa_mask |= CWSaveUnder;
- }
-
- if (flags & Qt::X11BypassWindowManagerHint) {
- wsa.override_redirect = True;
- wsa_mask |= CWOverrideRedirect;
- }
-
- if (wsa_mask && initializeWindow) {
- Q_ASSERT(id);
- XChangeWindowAttributes(dpy, id, wsa_mask, &wsa);
- }
-
- if (mwmhints.functions != 0) {
- mwmhints.flags |= MWM_HINTS_FUNCTIONS;
- mwmhints.functions |= MWM_FUNC_MOVE | MWM_FUNC_RESIZE;
- } else {
- mwmhints.functions = MWM_FUNC_ALL;
- }
-
- if (!(flags & Qt::FramelessWindowHint)
- && flags & Qt::CustomizeWindowHint
- && flags & Qt::WindowTitleHint
- && !(flags &
- (Qt::WindowMinimizeButtonHint
- | Qt::WindowMaximizeButtonHint
- | Qt::WindowCloseButtonHint))) {
- // a special case - only the titlebar without any button
- mwmhints.flags = MWM_HINTS_FUNCTIONS;
- mwmhints.functions = MWM_FUNC_MOVE | MWM_FUNC_RESIZE;
- mwmhints.decorations = 0;
- }
- }
-
- if (!initializeWindow) {
- // do no initialization
- } else if (popup) { // popup widget
- // set EWMH window types
- setNetWmWindowTypes();
-
- wsa.override_redirect = True;
- wsa.save_under = True;
- Q_ASSERT(id);
- XChangeWindowAttributes(dpy, id, CWOverrideRedirect | CWSaveUnder,
- &wsa);
- } else if (topLevel && !desktop) { // top-level widget
- if (!X11->wm_client_leader)
- create_wm_client_leader();
-
- // note: WM_TRANSIENT_FOR is set in QWidgetPrivate::show_sys()
-
- XSizeHints size_hints;
- size_hints.flags = USSize | PSize | PWinGravity;
- size_hints.x = data.crect.left();
- size_hints.y = data.crect.top();
- size_hints.width = data.crect.width();
- size_hints.height = data.crect.height();
- size_hints.win_gravity =
- QApplication::isRightToLeft() ? NorthEastGravity : NorthWestGravity;
-
- XWMHints wm_hints; // window manager hints
- memset(&wm_hints, 0, sizeof(wm_hints)); // make valgrind happy
- wm_hints.flags = InputHint | StateHint | WindowGroupHint;
- wm_hints.input = q->testAttribute(Qt::WA_X11DoNotAcceptFocus) ? False : True;
- wm_hints.initial_state = NormalState;
- wm_hints.window_group = X11->wm_client_leader;
-
- XClassHint class_hint;
- QByteArray appName = qAppName().toLatin1();
- class_hint.res_name = appName.data(); // application name
- class_hint.res_class = const_cast<char *>(QX11Info::appClass()); // application class
-
- XSetWMProperties(dpy, id, 0, 0,
- qApp->d_func()->argv, qApp->d_func()->argc,
- &size_hints, &wm_hints, &class_hint);
-
- XResizeWindow(dpy, id,
- qBound(1, data.crect.width(), XCOORD_MAX),
- qBound(1, data.crect.height(), XCOORD_MAX));
- XStoreName(dpy, id, appName.data());
- Atom protocols[5];
- int n = 0;
- protocols[n++] = ATOM(WM_DELETE_WINDOW); // support del window protocol
- protocols[n++] = ATOM(WM_TAKE_FOCUS); // support take focus window protocol
- protocols[n++] = ATOM(_NET_WM_PING); // support _NET_WM_PING protocol
-#ifndef QT_NO_XSYNC
- protocols[n++] = ATOM(_NET_WM_SYNC_REQUEST); // support _NET_WM_SYNC_REQUEST protocol
-#endif // QT_NO_XSYNC
- if (flags & Qt::WindowContextHelpButtonHint)
- protocols[n++] = ATOM(_NET_WM_CONTEXT_HELP);
- XSetWMProtocols(dpy, id, protocols, n);
-
- // set mwm hints
- SetMWMHints(dpy, id, mwmhints);
-
- // set EWMH window types
- setNetWmWindowTypes();
-
- // set _NET_WM_PID
- long curr_pid = getpid();
- XChangeProperty(dpy, id, ATOM(_NET_WM_PID), XA_CARDINAL, 32, PropModeReplace,
- (unsigned char *) &curr_pid, 1);
-
- // when we create a toplevel widget, the frame strut should be dirty
- data.fstrut_dirty = 1;
-
- // declare the widget's window role
- if (QTLWExtra *topData = maybeTopData()) {
- if (!topData->role.isEmpty()) {
- QByteArray windowRole = topData->role.toUtf8();
- XChangeProperty(dpy, id,
- ATOM(WM_WINDOW_ROLE), XA_STRING, 8, PropModeReplace,
- (unsigned char *)windowRole.constData(), windowRole.length());
- }
- }
-
- // set client leader property
- XChangeProperty(dpy, id, ATOM(WM_CLIENT_LEADER),
- XA_WINDOW, 32, PropModeReplace,
- (unsigned char *)&X11->wm_client_leader, 1);
- } else {
- // non-toplevel widgets don't have a frame, so no need to
- // update the strut
- data.fstrut_dirty = 0;
- }
-
- if (initializeWindow && q->internalWinId()) {
- // don't erase when resizing
- wsa.bit_gravity = QApplication::isRightToLeft() ? NorthEastGravity : NorthWestGravity;
- Q_ASSERT(id);
- XChangeWindowAttributes(dpy, id, CWBitGravity, &wsa);
- }
-
- // set X11 event mask
- if (desktop) {
-// QWidget* main_desktop = find(id);
-// if (main_desktop->testWFlags(Qt::WPaintDesktop))
-// XSelectInput(dpy, id, stdDesktopEventMask | ExposureMask);
-// else
- XSelectInput(dpy, id, stdDesktopEventMask);
- } else if (q->internalWinId()) {
- XSelectInput(dpy, id, stdWidgetEventMask);
-#if !defined (QT_NO_TABLET)
- QTabletDeviceDataList *tablet_list = qt_tablet_devices();
- if (X11->ptrXSelectExtensionEvent) {
- for (int i = 0; i < tablet_list->size(); ++i) {
- QTabletDeviceData tablet = tablet_list->at(i);
- X11->ptrXSelectExtensionEvent(dpy, id, reinterpret_cast<XEventClass*>(tablet.eventList),
- tablet.eventCount);
- }
- }
-#endif
- }
-
- if (desktop) {
- q->setAttribute(Qt::WA_WState_Visible);
- } else if (topLevel) { // set X cursor
- if (initializeWindow) {
- qt_x11_enforce_cursor(q);
-
- if (QTLWExtra *topData = maybeTopData())
- if (!topData->caption.isEmpty())
- setWindowTitle_helper(topData->caption);
-
- //always enable dnd: it's not worth the effort to maintain the state
- // NOTE: this always creates topData()
- X11->dndEnable(q, true);
-
- if (maybeTopData() && maybeTopData()->opacity != 255)
- q->setWindowOpacity(maybeTopData()->opacity/255.);
-
- }
- } else if (q->internalWinId()) {
- qt_x11_enforce_cursor(q);
- if (QWidget *p = q->parentWidget()) // reset the cursor on the native parent
- qt_x11_enforce_cursor(p);
- }
-
- if (extra && !extra->mask.isEmpty() && q->internalWinId())
- XShapeCombineRegion(X11->display, q->internalWinId(), ShapeBounding, 0, 0,
- extra->mask.handle(), ShapeSet);
-
- if (q->hasFocus() && q->testAttribute(Qt::WA_InputMethodEnabled)) {
- QInputContext *inputContext = q->inputContext();
- if (inputContext)
- inputContext->setFocusWidget(q);
- }
-
- if (destroyw) {
- qt_XDestroyWindow(q, dpy, destroyw);
- if (QTLWExtra *topData = maybeTopData()) {
-#ifndef QT_NO_XSYNC
- if (topData->syncUpdateCounter)
- XSyncDestroyCounter(dpy, topData->syncUpdateCounter);
-#endif
- // we destroyed our old window - reset the top-level state
- createTLSysExtra();
- }
- }
-
- // newly created windows are positioned at the window system's
- // (0,0) position. If the parent uses wrect mapping to expand the
- // coordinate system, we must also adjust this widget's window
- // system position
- if (!topLevel && !parentWidget->data->wrect.topLeft().isNull())
- setWSGeometry();
- else if (topLevel && (data.crect.width() == 0 || data.crect.height() == 0))
- q->setAttribute(Qt::WA_OutsideWSRange, true);
-
- if (!topLevel && q->testAttribute(Qt::WA_NativeWindow) && q->testAttribute(Qt::WA_Mapped)) {
- Q_ASSERT(q->internalWinId());
- XMapWindow(X11->display, q->internalWinId());
- // Ensure that mapped alien widgets are flushed immediately when re-created as native widgets.
- if (QWindowSurface *surface = q->windowSurface())
- surface->flush(q, q->rect(), q->mapTo(surface->window(), QPoint()));
- }
-
-#ifdef ALIEN_DEBUG
- qDebug() << "QWidgetPrivate::create_sys END:" << q;
-#endif
-}
-
-static void qt_x11_recreateWidget(QWidget *widget)
-{
- if (widget->inherits("QGLWidget")) {
- // We send QGLWidgets a ParentChange event which causes them to
- // recreate their GL context, which in turn causes them to choose
- // their visual again. Now that WA_TranslucentBackground is set,
- // QGLContext::chooseVisual will select an ARGB visual.
-
- // QGLWidget expects a ParentAboutToChange to be sent first
- QEvent aboutToChangeEvent(QEvent::ParentAboutToChange);
- QApplication::sendEvent(widget, &aboutToChangeEvent);
-
- QEvent parentChangeEvent(QEvent::ParentChange);
- QApplication::sendEvent(widget, &parentChangeEvent);
- } else {
- // For regular widgets, reparent them with their parent which
- // also triggers a recreation of the native window
- QPoint pos = widget->pos();
- bool visible = widget->isVisible();
- if (visible)
- widget->hide();
-
- widget->setParent(widget->parentWidget(), widget->windowFlags());
- widget->move(pos);
- if (visible)
- widget->show();
- }
-}
-
-static void qt_x11_recreateNativeWidgetsRecursive(QWidget *widget)
-{
- if (widget->internalWinId())
- qt_x11_recreateWidget(widget);
-
- const QObjectList &children = widget->children();
- for (int i = 0; i < children.size(); ++i) {
- QWidget *child = qobject_cast<QWidget*>(children.at(i));
- if (child)
- qt_x11_recreateNativeWidgetsRecursive(child);
- }
-}
-
-void QWidgetPrivate::x11UpdateIsOpaque()
-{
-#ifndef QT_NO_XRENDER
- Q_Q(QWidget);
- if (!q->testAttribute(Qt::WA_WState_Created) || !q->testAttribute(Qt::WA_TranslucentBackground))
- return;
-
- bool topLevel = (data.window_flags & Qt::Window);
- int screen = xinfo.screen();
- if (topLevel && X11->use_xrender
- && X11->argbVisuals[screen] && xinfo.depth() != 32)
- {
- qt_x11_recreateNativeWidgetsRecursive(q);
- }
-#endif
-}
-
-/*
- Returns true if the background is inherited; otherwise returns
- false.
-
- Mainly used in the paintOnScreen case.
-*/
-bool QWidgetPrivate::isBackgroundInherited() const
-{
- Q_Q(const QWidget);
-
- // windows do not inherit their background
- if (q->isWindow() || q->windowType() == Qt::SubWindow)
- return false;
-
- if (q->testAttribute(Qt::WA_NoSystemBackground) || q->testAttribute(Qt::WA_OpaquePaintEvent))
- return false;
-
- const QPalette &pal = q->palette();
- QPalette::ColorRole bg = q->backgroundRole();
- QBrush brush = pal.brush(bg);
-
- // non opaque brushes leaves us no choice, we must inherit
- if (!q->autoFillBackground() || !brush.isOpaque())
- return true;
-
- if (brush.style() == Qt::SolidPattern) {
- // the background is just a solid color. If there is no
- // propagated contents, then we claim as performance
- // optimization that it was not inheritet. This is the normal
- // case in standard Windows or Motif style.
- const QWidget *w = q->parentWidget();
- if (!w->d_func()->isBackgroundInherited())
- return false;
- }
-
- return true;
-}
-
-void QWidget::destroy(bool destroyWindow, bool destroySubWindows)
-{
- Q_D(QWidget);
- d->aboutToDestroy();
- if (!isWindow() && parentWidget())
- parentWidget()->d_func()->invalidateBuffer(d->effectiveRectFor(geometry()));
- d->deactivateWidgetCleanup();
- if (testAttribute(Qt::WA_WState_Created)) {
- setAttribute(Qt::WA_WState_Created, false);
- QObjectList childList = children();
- for (int i = 0; i < childList.size(); ++i) { // destroy all widget children
- register QObject *obj = childList.at(i);
- if (obj->isWidgetType())
- static_cast<QWidget*>(obj)->destroy(destroySubWindows,
- destroySubWindows);
- }
- if (QWidgetPrivate::mouseGrabber == this)
- releaseMouse();
- if (QWidgetPrivate::keyboardGrabber == this)
- releaseKeyboard();
- if (isWindow())
- X11->deferred_map.removeAll(this);
- if (isModal()) {
- // just be sure we leave modal
- QApplicationPrivate::leaveModal(this);
- }
- else if ((windowType() == Qt::Popup))
- qApp->d_func()->closePopup(this);
-
-#ifndef QT_NO_XRENDER
- if (d->picture) {
- if (destroyWindow)
- XRenderFreePicture(X11->display, d->picture);
- d->picture = 0;
- }
-#endif // QT_NO_XRENDER
-
- // delete the _NET_WM_USER_TIME_WINDOW
- qt_net_remove_user_time(this);
-
- if ((windowType() == Qt::Desktop)) {
- if (acceptDrops())
- X11->dndEnable(this, false);
- } else {
- if (isWindow())
- X11->dndEnable(this, false);
- if (destroyWindow)
- qt_XDestroyWindow(this, X11->display, data->winid);
- }
- QT_TRY {
- d->setWinId(0);
- } QT_CATCH (const std::bad_alloc &) {
- // swallow - destructors must not throw
- }
-
- extern void qPRCleanup(QWidget *widget); // from qapplication_x11.cpp
- if (testAttribute(Qt::WA_WState_Reparented))
- qPRCleanup(this);
-
- if(d->ic) {
- delete d->ic;
- } else {
- // release previous focus information participating with
- // preedit preservation of qic
- QInputContext *qic = QApplicationPrivate::inputContext;
- if (qic)
- qic->widgetDestroyed(this);
- }
- }
-}
-
-void QWidgetPrivate::setParent_sys(QWidget *parent, Qt::WindowFlags f)
-{
- Q_Q(QWidget);
-#ifdef ALIEN_DEBUG
- qDebug() << "QWidgetPrivate::setParent_sys START" << q << "parent:" << parent;
-#endif
- QX11Info old_xinfo = xinfo;
- if (parent && parent->windowType() == Qt::Desktop) {
- // make sure the widget is created on the same screen as the
- // programmer specified desktop widget
- xinfo = parent->d_func()->xinfo;
- parent = 0;
- }
-
- QTLWExtra *topData = maybeTopData();
- bool wasCreated = q->testAttribute(Qt::WA_WState_Created);
- if (q->isVisible() && q->parentWidget() && parent != q->parentWidget())
- q->parentWidget()->d_func()->invalidateBuffer(effectiveRectFor(q->geometry()));
- extern void qPRCreate(const QWidget *, Window);
-#ifndef QT_NO_CURSOR
- QCursor oldcurs;
-#endif
-
- // dnd unregister (we will register again below)
- if (q->testAttribute(Qt::WA_DropSiteRegistered))
- q->setAttribute(Qt::WA_DropSiteRegistered, false);
-
- // if we are a top then remove our dnd prop for now
- // it will get rest later
- if (q->isWindow() && wasCreated)
- X11->dndEnable(q, false);
-
- if (topData)
- qt_net_remove_user_time(q);
-
-// QWidget *oldparent = q->parentWidget();
- WId old_winid = wasCreated ? data.winid : 0;
- if ((q->windowType() == Qt::Desktop))
- old_winid = 0;
- setWinId(0);
-
-#ifndef QT_NO_XRENDER
- if (picture) {
- XRenderFreePicture(X11->display, picture);
- picture = 0;
- }
-#endif
-
- // hide and reparent our own window away. Otherwise we might get
- // destroyed when emitting the child remove event below. See QWorkspace.
- if (wasCreated && old_winid) {
- XUnmapWindow(X11->display, old_winid);
- if (!old_xinfo.screen() != xinfo.screen())
- XReparentWindow(X11->display, old_winid, RootWindow(X11->display, xinfo.screen()), 0, 0);
- }
- if (topData) {
- topData->parentWinId = 0;
- // zero the frame strut and mark it dirty
- topData->frameStrut.setCoords(0, 0, 0, 0);
-
- // reparenting from top-level, make sure show() works again
- topData->waitingForMapNotify = 0;
- topData->validWMState = 0;
- }
- data.fstrut_dirty = (!parent || (f & Qt::Window)); // toplevels get a dirty framestrut
-
- QObjectPrivate::setParent_helper(parent);
- bool explicitlyHidden = q->testAttribute(Qt::WA_WState_Hidden) && q->testAttribute(Qt::WA_WState_ExplicitShowHide);
-
- data.window_flags = f;
- q->setAttribute(Qt::WA_WState_Created, false);
- q->setAttribute(Qt::WA_WState_Visible, false);
- q->setAttribute(Qt::WA_WState_Hidden, false);
- adjustFlags(data.window_flags, q);
- // keep compatibility with previous versions, we need to preserve the created state
- // (but we recreate the winId for the widget being reparented, again for compatibility)
- if (wasCreated)
- createWinId();
- if (q->isWindow() || (!parent || parent->isVisible()) || explicitlyHidden)
- q->setAttribute(Qt::WA_WState_Hidden);
- q->setAttribute(Qt::WA_WState_ExplicitShowHide, explicitlyHidden);
-
- if (wasCreated) {
- QObjectList chlist = q->children();
- for (int i = 0; i < chlist.size(); ++i) { // reparent children
- QObject *obj = chlist.at(i);
- if (obj->isWidgetType()) {
- QWidget *w = (QWidget *)obj;
- if (!w->testAttribute(Qt::WA_WState_Created))
- continue;
- if (xinfo.screen() != w->d_func()->xinfo.screen()) {
- // ### force setParent() to not shortcut out (because
- // ### we're setting the parent to the current parent)
- // ### setParent will add child back to the list
- // ### of children so we need to make sure the
- // ### widget won't be added twice.
- w->d_func()->parent = 0;
- this->children.removeOne(w);
- w->setParent(q);
- } else if (!w->isWindow()) {
- w->d_func()->invalidateBuffer(w->rect());
- if (w->internalWinId()) {
- if (w->testAttribute(Qt::WA_NativeWindow)) {
- QWidget *nativeParentWidget = w->nativeParentWidget();
- // Qt::WA_NativeWindow ensures that we always have a nativeParentWidget
- Q_ASSERT(nativeParentWidget != 0);
- QPoint p = w->mapTo(nativeParentWidget, QPoint());
- XReparentWindow(X11->display,
- w->internalWinId(),
- nativeParentWidget->internalWinId(),
- p.x(), p.y());
- } else {
- w->d_func()->setParent_sys(q, w->data->window_flags);
- }
- }
- } else if (isTransient(w)) {
- /*
- when reparenting toplevel windows with toplevel-transient children,
- we need to make sure that the window manager gets the updated
- WM_TRANSIENT_FOR information... unfortunately, some window managers
- don't handle changing WM_TRANSIENT_FOR before the toplevel window is
- visible, so we unmap and remap all toplevel-transient children *after*
- the toplevel parent has been mapped. thankfully, this is easy in Qt :)
-
- note that the WM_TRANSIENT_FOR hint is actually updated in
- QWidgetPrivate::show_sys()
- */
- if (w->internalWinId())
- XUnmapWindow(X11->display, w->internalWinId());
- QApplication::postEvent(w, new QEvent(QEvent::ShowWindowRequest));
- }
- }
- }
- qPRCreate(q, old_winid);
- updateSystemBackground();
-
- if (old_winid) {
- Window *cmwret;
- int count;
- if (XGetWMColormapWindows(X11->display, old_winid, &cmwret, &count)) {
- Window *cmw;
- int cmw_size = sizeof(Window)*count;
- cmw = new Window[count];
- memcpy((char *)cmw, (char *)cmwret, cmw_size);
- XFree((char *)cmwret);
- int i;
- for (i=0; i<count; i++) {
- if (cmw[i] == old_winid) {
- cmw[i] = q->internalWinId();
- break;
- }
- }
- int top_count;
- if (XGetWMColormapWindows(X11->display, q->window()->internalWinId(),
- &cmwret, &top_count))
- {
- Window *merged_cmw = new Window[count + top_count];
- memcpy((char *)merged_cmw, (char *)cmw, cmw_size);
- memcpy((char *)merged_cmw + cmw_size, (char *)cmwret, sizeof(Window)*top_count);
- delete [] cmw;
- XFree((char *)cmwret);
- cmw = merged_cmw;
- count += top_count;
- }
-
- XSetWMColormapWindows(X11->display, q->window()->internalWinId(), cmw, count);
- delete [] cmw;
- }
-
- qt_XDestroyWindow(q, X11->display, old_winid);
- }
- }
-
- // check if we need to register our dropsite
- if (q->testAttribute(Qt::WA_AcceptDrops)
- || (!q->isWindow() && q->parentWidget() && q->parentWidget()->testAttribute(Qt::WA_DropSiteRegistered))) {
- q->setAttribute(Qt::WA_DropSiteRegistered, true);
- }
-#if !defined(QT_NO_IM)
- ic = 0;
-#endif
- invalidateBuffer(q->rect());
-#ifdef ALIEN_DEBUG
- qDebug() << "QWidgetPrivate::setParent_sys END" << q;
-#endif
-}
-
-QPoint QWidgetPrivate::mapToGlobal(const QPoint &pos) const
-{
- Q_Q(const QWidget);
- if (!q->testAttribute(Qt::WA_WState_Created) || !q->internalWinId()) {
- QPoint p = pos + q->data->crect.topLeft();
- //cannot trust that !isWindow() implies parentWidget() before create
- return (q->isWindow() || !q->parentWidget()) ? p : q->parentWidget()->d_func()->mapToGlobal(p);
- }
- int x, y;
- Window child;
- QPoint p = mapToWS(pos);
- XTranslateCoordinates(X11->display, q->internalWinId(),
- QApplication::desktop()->screen(xinfo.screen())->internalWinId(),
- p.x(), p.y(), &x, &y, &child);
- return QPoint(x, y);
-}
-
-QPoint QWidgetPrivate::mapFromGlobal(const QPoint &pos) const
-{
- Q_Q(const QWidget);
- if (!q->testAttribute(Qt::WA_WState_Created) || !q->internalWinId()) {
- //cannot trust that !isWindow() implies parentWidget() before create
- QPoint p = (q->isWindow() || !q->parentWidget()) ? pos : q->parentWidget()->d_func()->mapFromGlobal(pos);
- return p - q->data->crect.topLeft();
- }
- int x, y;
- Window child;
- XTranslateCoordinates(X11->display,
- QApplication::desktop()->screen(xinfo.screen())->internalWinId(),
- q->internalWinId(), pos.x(), pos.y(), &x, &y, &child);
- return mapFromWS(QPoint(x, y));
-}
-
-QPoint QWidget::mapToGlobal(const QPoint &pos) const
-{
- Q_D(const QWidget);
- QPoint offset = data->crect.topLeft();
- const QWidget *w = this;
- const QWidget *p = w->parentWidget();
- while (!w->isWindow() && p) {
- w = p;
- p = p->parentWidget();
- offset += w->data->crect.topLeft();
- }
-
- const QWidgetPrivate *wd = w->d_func();
- QTLWExtra *tlw = wd->topData();
- if (!tlw->embedded)
- return pos + offset;
-
- return d->mapToGlobal(pos);
-}
-
-QPoint QWidget::mapFromGlobal(const QPoint &pos) const
-{
- Q_D(const QWidget);
- QPoint offset = data->crect.topLeft();
- const QWidget *w = this;
- const QWidget *p = w->parentWidget();
- while (!w->isWindow() && p) {
- w = p;
- p = p->parentWidget();
- offset += w->data->crect.topLeft();
- }
-
- const QWidgetPrivate *wd = w->d_func();
- QTLWExtra *tlw = wd->topData();
- if (!tlw->embedded)
- return pos - offset;
-
- return d->mapFromGlobal(pos);
-}
-
-void QWidgetPrivate::updateSystemBackground()
-{
- Q_Q(QWidget);
- if (!q->testAttribute(Qt::WA_WState_Created) || !q->internalWinId())
- return;
- QBrush brush = q->palette().brush(QPalette::Active, q->backgroundRole());
- Qt::WindowType type = q->windowType();
- if (brush.style() == Qt::NoBrush
- || q->testAttribute(Qt::WA_NoSystemBackground)
- || q->testAttribute(Qt::WA_UpdatesDisabled)
- || type == Qt::Popup || type == Qt::ToolTip) {
- if (QX11Info::isCompositingManagerRunning()
- && q->testAttribute(Qt::WA_TranslucentBackground)
- && !(q->parent()))
- XSetWindowBackground(X11->display, q->internalWinId(),
- QColormap::instance(xinfo.screen()).pixel(Qt::transparent));
- else
- XSetWindowBackgroundPixmap(X11->display, q->internalWinId(), XNone);
- }
- else if (brush.style() == Qt::SolidPattern && brush.isOpaque())
- XSetWindowBackground(X11->display, q->internalWinId(),
- QColormap::instance(xinfo.screen()).pixel(brush.color()));
- else if (isBackgroundInherited())
- XSetWindowBackgroundPixmap(X11->display, q->internalWinId(), ParentRelative);
- else if (brush.style() == Qt::TexturePattern) {
- extern QPixmap qt_toX11Pixmap(const QPixmap &pixmap); // qpixmap_x11.cpp
- XSetWindowBackgroundPixmap(X11->display, q->internalWinId(),
- static_cast<QX11PixmapData*>(qt_toX11Pixmap(brush.texture()).data.data())->x11ConvertToDefaultDepth());
- } else
- XSetWindowBackground(X11->display, q->internalWinId(),
- QColormap::instance(xinfo.screen()).pixel(brush.color()));
-}
-
-#ifndef QT_NO_CURSOR
-void QWidgetPrivate::setCursor_sys(const QCursor &)
-{
- Q_Q(QWidget);
- qt_x11_enforce_cursor(q);
- XFlush(X11->display);
-}
-
-void QWidgetPrivate::unsetCursor_sys()
-{
- Q_Q(QWidget);
- qt_x11_enforce_cursor(q);
- XFlush(X11->display);
-}
-#endif
-
-static XTextProperty*
-qstring_to_xtp(const QString& s)
-{
- static XTextProperty tp = { 0, 0, 0, 0 };
- static bool free_prop = true; // we can't free tp.value in case it references
- // the data of the static QCString below.
- if (tp.value) {
- if (free_prop)
- XFree(tp.value);
- tp.value = 0;
- free_prop = true;
- }
-
- static const QTextCodec* mapper = QTextCodec::codecForLocale();
- int errCode = 0;
- if (mapper) {
- QByteArray mapped = mapper->fromUnicode(s);
- char* tl[2];
- tl[0] = mapped.data();
- tl[1] = 0;
- errCode = XmbTextListToTextProperty(X11->display, tl, 1, XStdICCTextStyle, &tp);
-#if defined(QT_DEBUG)
- if (errCode < 0)
- qDebug("qstring_to_xtp result code %d", errCode);
-#endif
- }
- if (!mapper || errCode < 0) {
- static QByteArray qcs;
- qcs = s.toAscii();
- tp.value = (uchar*)qcs.data();
- tp.encoding = XA_STRING;
- tp.format = 8;
- tp.nitems = qcs.length();
- free_prop = false;
- }
-
- // ### If we knew WM could understand unicode, we could use
- // ### a much simpler, cheaper encoding...
- /*
- tp.value = (XChar2b*)s.unicode();
- tp.encoding = XA_UNICODE; // wish
- tp.format = 16;
- tp.nitems = s.length();
- */
-
- return &tp;
-}
-
-void QWidgetPrivate::setWindowTitle_sys(const QString &caption)
-{
- Q_Q(QWidget);
- Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
- if (!q->internalWinId())
- return;
- XSetWMName(X11->display, q->internalWinId(), qstring_to_xtp(caption));
-
- QByteArray net_wm_name = caption.toUtf8();
- XChangeProperty(X11->display, q->internalWinId(), ATOM(_NET_WM_NAME), ATOM(UTF8_STRING), 8,
- PropModeReplace, (unsigned char *)net_wm_name.data(), net_wm_name.size());
-}
-
-void QWidgetPrivate::setWindowIcon_sys(bool forceReset)
-{
- Q_Q(QWidget);
- if (!q->testAttribute(Qt::WA_WState_Created))
- return;
- QTLWExtra *topData = this->topData();
- if (topData->iconPixmap && !forceReset)
- // already been set
- return;
-
- // preparing images to set the _NET_WM_ICON property
- QIcon icon = q->windowIcon();
- QVector<long> icon_data;
- Qt::HANDLE pixmap_handle = 0;
- if (!icon.isNull()) {
- QList<QSize> availableSizes = icon.availableSizes();
- if(availableSizes.isEmpty()) {
- // try to use default sizes since the icon can be a scalable image like svg.
- availableSizes.push_back(QSize(16,16));
- availableSizes.push_back(QSize(32,32));
- availableSizes.push_back(QSize(64,64));
- availableSizes.push_back(QSize(128,128));
- }
- for(int i = 0; i < availableSizes.size(); ++i) {
- QSize size = availableSizes.at(i);
- QPixmap pixmap = icon.pixmap(size);
- if (!pixmap.isNull()) {
- QImage image = pixmap.toImage().convertToFormat(QImage::Format_ARGB32);
- int pos = icon_data.size();
- icon_data.resize(pos + 2 + image.width()*image.height());
- icon_data[pos++] = image.width();
- icon_data[pos++] = image.height();
- if (sizeof(long) == sizeof(quint32)) {
- memcpy(icon_data.data() + pos, image.scanLine(0), image.byteCount());
- } else {
- for (int y = 0; y < image.height(); ++y) {
- uint *scanLine = reinterpret_cast<uint *>(image.scanLine(y));
- for (int x = 0; x < image.width(); ++x)
- icon_data[pos + y*image.width() + x] = scanLine[x];
- }
- }
- }
- }
- if (!icon_data.isEmpty()) {
- extern QPixmap qt_toX11Pixmap(const QPixmap &pixmap);
- /*
- if the app is running on an unknown desktop, or it is not
- using the default visual, convert the icon to 1bpp as stated
- in the ICCCM section 4.1.2.4; otherwise, create the icon pixmap
- in the default depth (even though this violates the ICCCM)
- */
- if (X11->desktopEnvironment == DE_UNKNOWN
- || !QX11Info::appDefaultVisual(xinfo.screen())
- || !QX11Info::appDefaultColormap(xinfo.screen())) {
- // unknown DE or non-default visual/colormap, use 1bpp bitmap
- if (!forceReset || !topData->iconPixmap)
- topData->iconPixmap = new QPixmap(qt_toX11Pixmap(QBitmap(icon.pixmap(QSize(64,64)))));
- pixmap_handle = topData->iconPixmap->handle();
- } else {
- // default depth, use a normal pixmap (even though this
- // violates the ICCCM), since this works on all DEs known to Qt
- if (!forceReset || !topData->iconPixmap)
- topData->iconPixmap = new QPixmap(qt_toX11Pixmap(icon.pixmap(QSize(64,64))));
- pixmap_handle = static_cast<QX11PixmapData*>(topData->iconPixmap->data.data())->x11ConvertToDefaultDepth();
- }
- }
- }
-
- if (!q->internalWinId())
- return;
-
- if (!icon_data.isEmpty()) {
- XChangeProperty(X11->display, q->internalWinId(), ATOM(_NET_WM_ICON), XA_CARDINAL, 32,
- PropModeReplace, (unsigned char *) icon_data.data(),
- icon_data.size());
- } else {
- XDeleteProperty(X11->display, q->internalWinId(), ATOM(_NET_WM_ICON));
- }
-
- XWMHints *h = XGetWMHints(X11->display, q->internalWinId());
- XWMHints wm_hints;
- if (!h) {
- memset(&wm_hints, 0, sizeof(wm_hints)); // make valgrind happy
- h = &wm_hints;
- }
-
- if (pixmap_handle) {
- h->icon_pixmap = pixmap_handle;
- h->flags |= IconPixmapHint;
- } else {
- h->icon_pixmap = 0;
- h->flags &= ~(IconPixmapHint | IconMaskHint);
- }
-
- XSetWMHints(X11->display, q->internalWinId(), h);
- if (h != &wm_hints)
- XFree((char *)h);
-}
-
-void QWidgetPrivate::setWindowIconText_sys(const QString &iconText)
-{
- Q_Q(QWidget);
- if (!q->internalWinId())
- return;
- Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
- XSetWMIconName(X11->display, q->internalWinId(), qstring_to_xtp(iconText));
-
- QByteArray icon_name = iconText.toUtf8();
- XChangeProperty(X11->display, q->internalWinId(), ATOM(_NET_WM_ICON_NAME), ATOM(UTF8_STRING), 8,
- PropModeReplace, (unsigned char *) icon_name.constData(), icon_name.size());
-}
-
-
-void QWidget::grabMouse()
-{
- if (isVisible() && !qt_nograb()) {
- if (QWidgetPrivate::mouseGrabber && QWidgetPrivate::mouseGrabber != this)
- QWidgetPrivate::mouseGrabber->releaseMouse();
- Q_ASSERT(testAttribute(Qt::WA_WState_Created));
-#ifndef QT_NO_DEBUG
- int status =
-#endif
- XGrabPointer(X11->display, effectiveWinId(), False,
- (uint)(ButtonPressMask | ButtonReleaseMask |
- PointerMotionMask | EnterWindowMask |
- LeaveWindowMask),
- GrabModeAsync, GrabModeAsync,
- XNone, XNone, X11->time);
-#ifndef QT_NO_DEBUG
- if (status) {
- const char *s =
- status == GrabNotViewable ? "\"GrabNotViewable\"" :
- status == AlreadyGrabbed ? "\"AlreadyGrabbed\"" :
- status == GrabFrozen ? "\"GrabFrozen\"" :
- status == GrabInvalidTime ? "\"GrabInvalidTime\"" :
- "<?>";
- qWarning("QWidget::grabMouse: Failed with %s", s);
- }
-#endif
- QWidgetPrivate::mouseGrabber = this;
- }
-}
-
-
-#ifndef QT_NO_CURSOR
-void QWidget::grabMouse(const QCursor &cursor)
-{
- if (!qt_nograb()) {
- if (QWidgetPrivate::mouseGrabber && QWidgetPrivate::mouseGrabber != this)
- QWidgetPrivate::mouseGrabber->releaseMouse();
- Q_ASSERT(testAttribute(Qt::WA_WState_Created));
-#ifndef QT_NO_DEBUG
- int status =
-#endif
- XGrabPointer(X11->display, effectiveWinId(), False,
- (uint)(ButtonPressMask | ButtonReleaseMask |
- PointerMotionMask | EnterWindowMask | LeaveWindowMask),
- GrabModeAsync, GrabModeAsync,
- XNone, cursor.handle(), X11->time);
-#ifndef QT_NO_DEBUG
- if (status) {
- const char *s =
- status == GrabNotViewable ? "\"GrabNotViewable\"" :
- status == AlreadyGrabbed ? "\"AlreadyGrabbed\"" :
- status == GrabFrozen ? "\"GrabFrozen\"" :
- status == GrabInvalidTime ? "\"GrabInvalidTime\"" :
- "<?>";
- qWarning("QWidget::grabMouse: Failed with %s", s);
- }
-#endif
- QWidgetPrivate::mouseGrabber = this;
- }
-}
-#endif
-
-
-void QWidget::releaseMouse()
-{
- if (!qt_nograb() && QWidgetPrivate::mouseGrabber == this) {
- XUngrabPointer(X11->display, X11->time);
- XFlush(X11->display);
- QWidgetPrivate::mouseGrabber = 0;
- }
-}
-
-
-void QWidget::grabKeyboard()
-{
- if (!qt_nograb()) {
- if (QWidgetPrivate::keyboardGrabber && QWidgetPrivate::keyboardGrabber != this)
- QWidgetPrivate::keyboardGrabber->releaseKeyboard();
- XGrabKeyboard(X11->display, effectiveWinId(), False, GrabModeAsync, GrabModeAsync,
- X11->time);
- QWidgetPrivate::keyboardGrabber = this;
- }
-}
-
-
-void QWidget::releaseKeyboard()
-{
- if (!qt_nograb() && QWidgetPrivate::keyboardGrabber == this) {
- XUngrabKeyboard(X11->display, X11->time);
- QWidgetPrivate::keyboardGrabber = 0;
- }
-}
-
-
-QWidget *QWidget::mouseGrabber()
-{
- return QWidgetPrivate::mouseGrabber;
-}
-
-
-QWidget *QWidget::keyboardGrabber()
-{
- return QWidgetPrivate::keyboardGrabber;
-}
-
-void QWidget::activateWindow()
-{
- QWidget *tlw = window();
- if (tlw->isVisible() && !tlw->d_func()->topData()->embedded && !X11->deferred_map.contains(tlw)) {
- if (X11->userTime == 0)
- X11->userTime = X11->time;
- qt_net_update_user_time(tlw, X11->userTime);
-
- if (X11->isSupportedByWM(ATOM(_NET_ACTIVE_WINDOW))
- && !(tlw->windowFlags() & Qt::X11BypassWindowManagerHint)) {
- XEvent e;
- e.xclient.type = ClientMessage;
- e.xclient.message_type = ATOM(_NET_ACTIVE_WINDOW);
- e.xclient.display = X11->display;
- e.xclient.window = tlw->internalWinId();
- e.xclient.format = 32;
- e.xclient.data.l[0] = 1; // 1 == application
- e.xclient.data.l[1] = X11->userTime;
- if (QWidget *aw = QApplication::activeWindow())
- e.xclient.data.l[2] = aw->internalWinId();
- else
- e.xclient.data.l[2] = XNone;
- e.xclient.data.l[3] = 0;
- e.xclient.data.l[4] = 0;
- XSendEvent(X11->display, RootWindow(X11->display, tlw->x11Info().screen()),
- false, SubstructureNotifyMask | SubstructureRedirectMask, &e);
- } else {
- if (!qt_widget_private(tlw)->topData()->waitingForMapNotify)
- XSetInputFocus(X11->display, tlw->internalWinId(), XRevertToParent, X11->time);
- }
- }
-}
-
-void QWidget::setWindowState(Qt::WindowStates newstate)
-{
- Q_D(QWidget);
- bool needShow = false;
- Qt::WindowStates oldstate = windowState();
- if (oldstate == newstate)
- return;
- if (isWindow()) {
- // Ensure the initial size is valid, since we store it as normalGeometry below.
- if (!testAttribute(Qt::WA_Resized) && !isVisible())
- adjustSize();
-
- QTLWExtra *top = d->topData();
-
- if ((oldstate & Qt::WindowMaximized) != (newstate & Qt::WindowMaximized)) {
- if (X11->isSupportedByWM(ATOM(_NET_WM_STATE_MAXIMIZED_HORZ))
- && X11->isSupportedByWM(ATOM(_NET_WM_STATE_MAXIMIZED_VERT))) {
- if ((newstate & Qt::WindowMaximized) && !(oldstate & Qt::WindowFullScreen))
- top->normalGeometry = geometry();
- qt_change_net_wm_state(this, (newstate & Qt::WindowMaximized),
- ATOM(_NET_WM_STATE_MAXIMIZED_HORZ),
- ATOM(_NET_WM_STATE_MAXIMIZED_VERT));
- } else if (! (newstate & Qt::WindowFullScreen)) {
- if (newstate & Qt::WindowMaximized) {
- // save original geometry
- const QRect normalGeometry = geometry();
-
- if (isVisible()) {
- data->fstrut_dirty = true;
- const QRect maxRect = QApplication::desktop()->availableGeometry(this);
- const QRect r = top->normalGeometry;
- const QRect fs = d->frameStrut();
- setGeometry(maxRect.x() + fs.left(),
- maxRect.y() + fs.top(),
- maxRect.width() - fs.left() - fs.right(),
- maxRect.height() - fs.top() - fs.bottom());
- top->normalGeometry = r;
- }
-
- if (top->normalGeometry.width() < 0)
- top->normalGeometry = normalGeometry;
- } else {
- // restore original geometry
- setGeometry(top->normalGeometry);
- }
- }
- }
-
- if ((oldstate & Qt::WindowFullScreen) != (newstate & Qt::WindowFullScreen)) {
- if (X11->isSupportedByWM(ATOM(_NET_WM_STATE_FULLSCREEN))) {
- if (newstate & Qt::WindowFullScreen) {
- top->normalGeometry = geometry();
- top->fullScreenOffset = d->frameStrut().topLeft();
- }
- qt_change_net_wm_state(this, (newstate & Qt::WindowFullScreen),
- ATOM(_NET_WM_STATE_FULLSCREEN));
- } else {
- needShow = isVisible();
-
- if (newstate & Qt::WindowFullScreen) {
- data->fstrut_dirty = true;
- const QRect normalGeometry = geometry();
- const QPoint fullScreenOffset = d->frameStrut().topLeft();
-
- top->savedFlags = windowFlags();
- setParent(0, Qt::Window | Qt::FramelessWindowHint);
- const QRect r = top->normalGeometry;
- setGeometry(qApp->desktop()->screenGeometry(this));
- top->normalGeometry = r;
-
- if (top->normalGeometry.width() < 0) {
- top->normalGeometry = normalGeometry;
- top->fullScreenOffset = fullScreenOffset;
- }
- } else {
- setParent(0, top->savedFlags);
-
- if (newstate & Qt::WindowMaximized) {
- // from fullscreen to maximized
- data->fstrut_dirty = true;
- const QRect maxRect = QApplication::desktop()->availableGeometry(this);
- const QRect r = top->normalGeometry;
- const QRect fs = d->frameStrut();
- setGeometry(maxRect.x() + fs.left(),
- maxRect.y() + fs.top(),
- maxRect.width() - fs.left() - fs.right(),
- maxRect.height() - fs.top() - fs.bottom());
- top->normalGeometry = r;
- } else {
- // restore original geometry
- setGeometry(top->normalGeometry.adjusted(-top->fullScreenOffset.x(),
- -top->fullScreenOffset.y(),
- -top->fullScreenOffset.x(),
- -top->fullScreenOffset.y()));
- }
- }
- }
- }
-
- createWinId();
- Q_ASSERT(testAttribute(Qt::WA_WState_Created));
- if ((oldstate & Qt::WindowMinimized) != (newstate & Qt::WindowMinimized)) {
- if (isVisible()) {
- if (newstate & Qt::WindowMinimized) {
- XEvent e;
- e.xclient.type = ClientMessage;
- e.xclient.message_type = ATOM(WM_CHANGE_STATE);
- e.xclient.display = X11->display;
- e.xclient.window = data->winid;
- e.xclient.format = 32;
- e.xclient.data.l[0] = IconicState;
- e.xclient.data.l[1] = 0;
- e.xclient.data.l[2] = 0;
- e.xclient.data.l[3] = 0;
- e.xclient.data.l[4] = 0;
- XSendEvent(X11->display,
- RootWindow(X11->display,d->xinfo.screen()),
- False, (SubstructureNotifyMask|SubstructureRedirectMask), &e);
- } else {
- setAttribute(Qt::WA_Mapped);
- XMapWindow(X11->display, effectiveWinId());
- }
- }
-
- needShow = false;
- }
- }
-
- data->window_state = newstate;
-
- if (needShow)
- show();
-
- if (newstate & Qt::WindowActive)
- activateWindow();
-
- QWindowStateChangeEvent e(oldstate);
- QApplication::sendEvent(this, &e);
-}
-
-/*!
- \internal
- Platform-specific part of QWidget::show().
-*/
-
-void QWidgetPrivate::show_sys()
-{
- Q_Q(QWidget);
- Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
-
- if (q->testAttribute(Qt::WA_DontShowOnScreen)) {
- invalidateBuffer(q->rect());
- q->setAttribute(Qt::WA_Mapped);
- if (QTLWExtra *tlwExtra = maybeTopData())
- tlwExtra->waitingForMapNotify = 0;
- return;
- }
-
- if (q->isWindow()) {
- XWMHints *h = XGetWMHints(X11->display, q->internalWinId());
- XWMHints wm_hints;
- bool got_hints = h != 0;
- if (!got_hints) {
- memset(&wm_hints, 0, sizeof(wm_hints)); // make valgrind happy
- h = &wm_hints;
- }
- h->initial_state = q->isMinimized() ? IconicState : NormalState;
- h->flags |= StateHint;
- XSetWMHints(X11->display, q->internalWinId(), h);
- if (got_hints)
- XFree((char *)h);
-
- // update WM_NORMAL_HINTS
- do_size_hints(q, extra);
-
- // udpate WM_TRANSIENT_FOR
- if (isTransient(q)) {
- QWidget *p = q->parentWidget();
-
-#ifndef QT_NO_MENU
- // hackish ... try to find the main window related to this QMenu
- if (qobject_cast<QMenu *>(q)) {
- p = static_cast<QMenuPrivate*>(this)->causedPopup.widget;
- if (!p)
- p = q->parentWidget();
- if (!p)
- p = QApplication::widgetAt(q->pos());
- if (!p)
- p = qApp->activeWindow();
- }
-#endif
- if (p)
- p = p->window();
- if (p) {
- // transient for window
- XSetTransientForHint(X11->display, q->internalWinId(), p->internalWinId());
- } else {
- // transient for group
- XSetTransientForHint(X11->display, q->internalWinId(), X11->wm_client_leader);
- }
- }
-
- // update _MOTIF_WM_HINTS
- QtMWMHints mwmhints = GetMWMHints(X11->display, q->internalWinId());
-
- if (data.window_modality != Qt::NonModal) {
- switch (data.window_modality) {
- case Qt::WindowModal:
- mwmhints.input_mode = MWM_INPUT_PRIMARY_APPLICATION_MODAL;
- break;
- case Qt::ApplicationModal:
- default:
- mwmhints.input_mode = MWM_INPUT_FULL_APPLICATION_MODAL;
- break;
- }
- mwmhints.flags |= MWM_HINTS_INPUT_MODE;
- } else {
- mwmhints.input_mode = MWM_INPUT_MODELESS;
- mwmhints.flags &= ~MWM_HINTS_INPUT_MODE;
- }
-
- if (q->minimumSize() == q->maximumSize()) {
- // fixed size, remove the resize handle (since mwm/dtwm
- // isn't smart enough to do it itself)
- mwmhints.flags |= MWM_HINTS_FUNCTIONS;
- if (mwmhints.functions == MWM_FUNC_ALL) {
- mwmhints.functions = MWM_FUNC_MOVE;
- } else {
- mwmhints.functions &= ~MWM_FUNC_RESIZE;
- }
-
- if (mwmhints.decorations == MWM_DECOR_ALL) {
- mwmhints.flags |= MWM_HINTS_DECORATIONS;
- mwmhints.decorations = (MWM_DECOR_BORDER
- | MWM_DECOR_TITLE
- | MWM_DECOR_MENU);
- } else {
- mwmhints.decorations &= ~MWM_DECOR_RESIZEH;
- }
-
- 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;
- }
- if (q->windowFlags() & Qt::WindowCloseButtonHint)
- mwmhints.functions |= MWM_FUNC_CLOSE;
- }
-
- SetMWMHints(X11->display, q->internalWinId(), mwmhints);
-
- // update _NET_WM_STATE
- QVector<Atom> netWmState = getNetWmState(q);
-
- Qt::WindowFlags flags = q->windowFlags();
- if (flags & Qt::WindowStaysOnTopHint) {
- if (flags & Qt::WindowStaysOnBottomHint)
- qWarning() << "QWidget: Incompatible window flags: the window can't be on top and on bottom at the same time";
- if (!netWmState.contains(ATOM(_NET_WM_STATE_ABOVE)))
- netWmState.append(ATOM(_NET_WM_STATE_ABOVE));
- if (!netWmState.contains(ATOM(_NET_WM_STATE_STAYS_ON_TOP)))
- netWmState.append(ATOM(_NET_WM_STATE_STAYS_ON_TOP));
- } else if (flags & Qt::WindowStaysOnBottomHint) {
- if (!netWmState.contains(ATOM(_NET_WM_STATE_BELOW)))
- netWmState.append(ATOM(_NET_WM_STATE_BELOW));
- }
- if (q->isFullScreen()) {
- if (!netWmState.contains(ATOM(_NET_WM_STATE_FULLSCREEN)))
- netWmState.append(ATOM(_NET_WM_STATE_FULLSCREEN));
- }
- if (q->isMaximized()) {
- if (!netWmState.contains(ATOM(_NET_WM_STATE_MAXIMIZED_HORZ)))
- netWmState.append(ATOM(_NET_WM_STATE_MAXIMIZED_HORZ));
- if (!netWmState.contains(ATOM(_NET_WM_STATE_MAXIMIZED_VERT)))
- netWmState.append(ATOM(_NET_WM_STATE_MAXIMIZED_VERT));
- }
- if (data.window_modality != Qt::NonModal) {
- if (!netWmState.contains(ATOM(_NET_WM_STATE_MODAL)))
- netWmState.append(ATOM(_NET_WM_STATE_MODAL));
- }
-
- if (!netWmState.isEmpty()) {
- XChangeProperty(X11->display, q->internalWinId(),
- ATOM(_NET_WM_STATE), XA_ATOM, 32, PropModeReplace,
- (unsigned char *) netWmState.data(), netWmState.size());
- } else {
- XDeleteProperty(X11->display, q->internalWinId(), ATOM(_NET_WM_STATE));
- }
-
- // set _NET_WM_USER_TIME
- Time userTime = X11->userTime;
- bool setUserTime = false;
- if (q->testAttribute(Qt::WA_ShowWithoutActivating)) {
- userTime = 0;
- setUserTime = true;
- } else if (userTime != CurrentTime) {
- setUserTime = true;
- }
- if (setUserTime)
- qt_net_update_user_time(q, userTime);
-
-#ifndef QT_NO_XSYNC
- if (!topData()->syncUpdateCounter) {
- XSyncValue value;
- XSyncIntToValue(&value, 0);
- topData()->syncUpdateCounter = XSyncCreateCounter(X11->display, value);
-
- XChangeProperty(X11->display, q->internalWinId(),
- ATOM(_NET_WM_SYNC_REQUEST_COUNTER),
- XA_CARDINAL,
- 32, PropModeReplace,
- (uchar *) &topData()->syncUpdateCounter, 1);
-
- topData()->newCounterValueHi = 0;
- topData()->newCounterValueLo = 0;
- }
-#endif
-
- if (!topData()->embedded
- && (topData()->validWMState || topData()->waitingForMapNotify)
- && !q->isMinimized()) {
- X11->deferred_map.append(q);
- return;
- }
-
- if (q->isMaximized() && !q->isFullScreen()
- && !(X11->isSupportedByWM(ATOM(_NET_WM_STATE_MAXIMIZED_HORZ))
- && X11->isSupportedByWM(ATOM(_NET_WM_STATE_MAXIMIZED_VERT)))) {
- XMapWindow(X11->display, q->internalWinId());
- data.fstrut_dirty = true;
- qt_x11_wait_for_window_manager(q);
-
- // if the wm was not smart enough to adjust our size, do that manually
- QRect maxRect = QApplication::desktop()->availableGeometry(q);
-
- QTLWExtra *top = topData();
- QRect normalRect = top->normalGeometry;
- const QRect fs = frameStrut();
-
- q->setGeometry(maxRect.x() + fs.left(),
- maxRect.y() + fs.top(),
- maxRect.width() - fs.left() - fs.right(),
- maxRect.height() - fs.top() - fs.bottom());
-
- // restore the original normalGeometry
- top->normalGeometry = normalRect;
- // internalSetGeometry() clears the maximized flag... make sure we set it back
- data.window_state = data.window_state | Qt::WindowMaximized;
- q->setAttribute(Qt::WA_Mapped);
- return;
- }
-
- if (q->isFullScreen() && !X11->isSupportedByWM(ATOM(_NET_WM_STATE_FULLSCREEN))) {
- XMapWindow(X11->display, q->internalWinId());
- qt_x11_wait_for_window_manager(q);
- q->setAttribute(Qt::WA_Mapped);
- return;
- }
- }
-
- invalidateBuffer(q->rect());
-
- if (q->testAttribute(Qt::WA_OutsideWSRange))
- return;
- q->setAttribute(Qt::WA_Mapped);
- if (q->isWindow())
- topData()->waitingForMapNotify = 1;
-
- if (!q->isWindow()
- && (!q->autoFillBackground()
- || q->palette().brush(q->backgroundRole()).style() == Qt::LinearGradientPattern)) {
- if (q->internalWinId()) {
- XSetWindowBackgroundPixmap(X11->display, q->internalWinId(), XNone);
- XMapWindow(X11->display, q->internalWinId());
- updateSystemBackground();
- }
- return;
- }
-
- if (q->internalWinId())
- XMapWindow(X11->display, q->internalWinId());
-
- // Freedesktop.org Startup Notification
- if (X11->startupId && q->isWindow()) {
- QByteArray message("remove: ID=");
- message.append(X11->startupId);
- sendStartupMessage(message.constData());
- X11->startupId = 0;
- }
-}
-
-/*!
- \internal
- Platform-specific part of QWidget::show().
-*/
-
-void QWidgetPrivate::sendStartupMessage(const char *message) const
-{
- Q_Q(const QWidget);
-
- if (!message)
- return;
-
- XEvent xevent;
- xevent.xclient.type = ClientMessage;
- xevent.xclient.message_type = ATOM(_NET_STARTUP_INFO_BEGIN);
- xevent.xclient.display = X11->display;
- xevent.xclient.window = q->internalWinId();
- xevent.xclient.format = 8;
-
- Window rootWindow = RootWindow(X11->display, DefaultScreen(X11->display));
- uint sent = 0;
- uint length = strlen(message) + 1;
- do {
- if (sent == 20)
- xevent.xclient.message_type = ATOM(_NET_STARTUP_INFO);
-
- for (uint i = 0; i < 20 && i + sent <= length; i++)
- xevent.xclient.data.b[i] = message[i + sent++];
-
- XSendEvent(X11->display, rootWindow, false, PropertyChangeMask, &xevent);
- } while (sent <= length);
-}
-
-void QWidgetPrivate::setNetWmWindowTypes()
-{
- Q_Q(QWidget);
- Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
-
- if (!q->isWindow()) {
- if (q->internalWinId())
- XDeleteProperty(X11->display, q->internalWinId(), ATOM(_NET_WM_WINDOW_TYPE));
- return;
- }
-
- QVector<long> windowTypes;
-
- // manual selection 1 (these are never set by Qt and take precedence)
- if (q->testAttribute(Qt::WA_X11NetWmWindowTypeDesktop))
- windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_DESKTOP));
- if (q->testAttribute(Qt::WA_X11NetWmWindowTypeDock))
- windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_DOCK));
- if (q->testAttribute(Qt::WA_X11NetWmWindowTypeNotification))
- windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_NOTIFICATION));
-
- // manual selection 2 (Qt uses these during auto selection);
- if (q->testAttribute(Qt::WA_X11NetWmWindowTypeUtility))
- windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_UTILITY));
- if (q->testAttribute(Qt::WA_X11NetWmWindowTypeSplash))
- windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_SPLASH));
- if (q->testAttribute(Qt::WA_X11NetWmWindowTypeDialog))
- windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_DIALOG));
- if (q->testAttribute(Qt::WA_X11NetWmWindowTypeToolTip))
- windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_TOOLTIP));
-
- // manual selection 3 (these can be set by Qt, but don't have a
- // corresponding Qt::WindowType). note that order of the *MENU
- // atoms is important
- if (q->testAttribute(Qt::WA_X11NetWmWindowTypeMenu))
- windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_MENU));
- if (q->testAttribute(Qt::WA_X11NetWmWindowTypeDropDownMenu))
- windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_DROPDOWN_MENU));
- if (q->testAttribute(Qt::WA_X11NetWmWindowTypePopupMenu))
- windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_POPUP_MENU));
- if (q->testAttribute(Qt::WA_X11NetWmWindowTypeToolBar))
- windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_TOOLBAR));
- if (q->testAttribute(Qt::WA_X11NetWmWindowTypeCombo))
- windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_COMBO));
- if (q->testAttribute(Qt::WA_X11NetWmWindowTypeDND))
- windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_DND));
-
- // automatic selection
- switch (q->windowType()) {
- case Qt::Dialog:
- case Qt::Sheet:
- // dialog netwm type
- windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_DIALOG));
- break;
-
- case Qt::Tool:
- case Qt::Drawer:
- // utility netwm type
- windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_UTILITY));
- break;
-
- case Qt::ToolTip:
- // tooltip netwm type
- windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_TOOLTIP));
- break;
-
- case Qt::SplashScreen:
- // splash netwm type
- windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_SPLASH));
- break;
-
- default:
- break;
- }
-
- if (q->windowFlags() & Qt::FramelessWindowHint) {
- // override netwm type - quick and easy for KDE noborder
- windowTypes.append(ATOM(_KDE_NET_WM_WINDOW_TYPE_OVERRIDE));
- }
-
- // normal netwm type - default
- windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_NORMAL));
-
- if (!windowTypes.isEmpty()) {
- XChangeProperty(X11->display, q->winId(), ATOM(_NET_WM_WINDOW_TYPE), XA_ATOM, 32,
- PropModeReplace, (unsigned char *) windowTypes.constData(),
- windowTypes.count());
- } else {
- XDeleteProperty(X11->display, q->winId(), ATOM(_NET_WM_WINDOW_TYPE));
- }
-}
-
-/*!
- \internal
- Platform-specific part of QWidget::hide().
-*/
-
-void QWidgetPrivate::hide_sys()
-{
- Q_Q(QWidget);
- Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
- deactivateWidgetCleanup();
- if (q->isWindow()) {
- X11->deferred_map.removeAll(q);
- if (q->internalWinId()) // in nsplugin, may be 0
- XWithdrawWindow(X11->display, q->internalWinId(), xinfo.screen());
- XFlush(X11->display);
- } else {
- invalidateBuffer(q->rect());
- if (q->internalWinId()) // in nsplugin, may be 0
- XUnmapWindow(X11->display, q->internalWinId());
- }
- q->setAttribute(Qt::WA_Mapped, false);
-}
-
-void QWidgetPrivate::setFocus_sys()
-{
-
-}
-
-
-void QWidgetPrivate::raise_sys()
-{
- Q_Q(QWidget);
- Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
- if (q->internalWinId())
- XRaiseWindow(X11->display, q->internalWinId());
-}
-
-void QWidgetPrivate::lower_sys()
-{
- Q_Q(QWidget);
- Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
- if (q->internalWinId())
- XLowerWindow(X11->display, q->internalWinId());
- if(!q->isWindow())
- invalidateBuffer(q->rect());
-}
-
-void QWidgetPrivate::stackUnder_sys(QWidget* w)
-{
- Q_Q(QWidget);
- Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
- if (q->internalWinId() && w->internalWinId()) {
- Window stack[2];
- stack[0] = w->internalWinId();;
- stack[1] = q->internalWinId();
- XRestackWindows(X11->display, stack, 2);
- }
- if(!q->isWindow() || !w->internalWinId())
- invalidateBuffer(q->rect());
-}
-
-
-static void do_size_hints(QWidget* widget, QWExtra *x)
-{
- Q_ASSERT(widget->testAttribute(Qt::WA_WState_Created));
- XSizeHints s;
- s.flags = 0;
- if (x) {
- QRect g = widget->geometry();
- s.x = g.x();
- s.y = g.y();
- s.width = g.width();
- s.height = g.height();
- if (x->minw > 0 || x->minh > 0) {
- // add minimum size hints
- s.flags |= PMinSize;
- s.min_width = qMin(XCOORD_MAX, x->minw);
- s.min_height = qMin(XCOORD_MAX, x->minh);
- }
- if (x->maxw < QWIDGETSIZE_MAX || x->maxh < QWIDGETSIZE_MAX) {
- // add maximum size hints
- s.flags |= PMaxSize;
- s.max_width = qMin(XCOORD_MAX, x->maxw);
- s.max_height = qMin(XCOORD_MAX, x->maxh);
- }
- if (x->topextra &&
- (x->topextra->incw > 0 || x->topextra->inch > 0)) {
- // add resize increment hints
- s.flags |= PResizeInc | PBaseSize;
- s.width_inc = x->topextra->incw;
- s.height_inc = x->topextra->inch;
- s.base_width = x->topextra->basew;
- s.base_height = x->topextra->baseh;
- }
- }
- if (widget->testAttribute(Qt::WA_Moved)) {
- // user (i.e. command-line) specified position
- s.flags |= USPosition;
- s.flags |= PPosition;
- }
- if (widget->testAttribute(Qt::WA_Resized)) {
- // user (i.e. command-line) specified size
- s.flags |= USSize;
- s.flags |= PSize;
- }
- s.flags |= PWinGravity;
- if (widget->testAttribute(Qt::WA_Moved) && x && x->topextra && !x->topextra->posFromMove) {
- // position came from setGeometry(), tell the WM that we don't
- // want our window gravity-shifted
- s.win_gravity = StaticGravity;
- } else {
- // position came from move()
- s.x = widget->x();
- s.y = widget->y();
- s.win_gravity = QApplication::isRightToLeft() ? NorthEastGravity : NorthWestGravity;
- }
- if (widget->internalWinId())
- XSetWMNormalHints(X11->display, widget->internalWinId(), &s);
-}
-
-
-/*
- Helper function for non-toplevel widgets. Helps to map Qt's 32bit
- coordinate system to X11's 16bit coordinate system.
-
- Sets the geometry of the widget to data.crect, but clipped to sizes
- that X can handle. Unmaps widgets that are completely outside the
- valid range.
-
- Maintains data.wrect, which is the geometry of the X widget,
- measured in this widget's coordinate system.
-
- if the parent is not clipped, parentWRect is empty, otherwise
- parentWRect is the geometry of the parent's X rect, measured in
- parent's coord sys
- */
-void QWidgetPrivate::setWSGeometry(bool dontShow, const QRect &)
-{
- Q_Q(QWidget);
- Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
-
- /*
- There are up to four different coordinate systems here:
- Qt coordinate system for this widget.
- X coordinate system for this widget (relative to wrect).
- Qt coordinate system for parent
- X coordinate system for parent (relative to parent's wrect).
- */
- Display *dpy = xinfo.display();
- QRect validRange(-XCOORD_MAX,-XCOORD_MAX, 2*XCOORD_MAX, 2*XCOORD_MAX);
- QRect wrectRange(-WRECT_MAX,-WRECT_MAX, 2*WRECT_MAX, 2*WRECT_MAX);
- QRect wrect;
- //xrect is the X geometry of my X widget. (starts out in parent's Qt coord sys, and ends up in parent's X coord sys)
- QRect xrect = data.crect;
-
- const QWidget *const parent = q->parentWidget();
- QRect parentWRect = parent->data->wrect;
-
- if (parentWRect.isValid()) {
- // parent is clipped, and we have to clip to the same limit as parent
- if (!parentWRect.contains(xrect)) {
- xrect &= parentWRect;
- wrect = xrect;
- //translate from parent's to my Qt coord sys
- wrect.translate(-data.crect.topLeft());
- }
- //translate from parent's Qt coords to parent's X coords
- xrect.translate(-parentWRect.topLeft());
-
- } else {
- // parent is not clipped, we may or may not have to clip
-
- if (data.wrect.isValid() && QRect(QPoint(),data.crect.size()).contains(data.wrect)) {
- // This is where the main optimization is: we are already
- // clipped, and if our clip is still valid, we can just
- // move our window, and do not need to move or clip
- // children
-
- QRect vrect = xrect & parent->rect();
- vrect.translate(-data.crect.topLeft()); //the part of me that's visible through parent, in my Qt coords
- if (data.wrect.contains(vrect)) {
- xrect = data.wrect;
- xrect.translate(data.crect.topLeft());
- if (data.winid)
- XMoveWindow(dpy, data.winid, xrect.x(), xrect.y());
- return;
- }
- }
-
- if (!validRange.contains(xrect)) {
- // we are too big, and must clip
- xrect &=wrectRange;
- wrect = xrect;
- wrect.translate(-data.crect.topLeft());
- //parent's X coord system is equal to parent's Qt coord
- //sys, so we don't need to map xrect.
- }
-
- }
-
- // unmap if we are outside the valid window system coord system
- bool outsideRange = !xrect.isValid();
- bool mapWindow = false;
- if (q->testAttribute(Qt::WA_OutsideWSRange) != outsideRange) {
- q->setAttribute(Qt::WA_OutsideWSRange, outsideRange);
- if (outsideRange) {
- if (data.winid)
- XUnmapWindow(dpy, data.winid);
- q->setAttribute(Qt::WA_Mapped, false);
- } else if (!q->isHidden()) {
- mapWindow = true;
- }
- }
-
- if (outsideRange)
- return;
-
- bool jump = (data.wrect != wrect);
- data.wrect = wrect;
-
-
- // and now recursively for all children...
- // ### can be optimized
- for (int i = 0; i < children.size(); ++i) {
- QObject *object = children.at(i);
- if (object->isWidgetType()) {
- QWidget *w = static_cast<QWidget *>(object);
- if (!w->isWindow() && w->testAttribute(Qt::WA_WState_Created))
- w->d_func()->setWSGeometry(jump);
- }
- }
-
- if (data.winid) {
- // move ourselves to the new position and map (if necessary) after
- // the movement. Rationale: moving unmapped windows is much faster
- // than moving mapped windows
- if (jump) //avoid flicker when jumping
- XSetWindowBackgroundPixmap(dpy, data.winid, XNone);
- if (!parent->internalWinId())
- xrect.translate(parent->mapTo(q->nativeParentWidget(), QPoint(0, 0)));
- XMoveResizeWindow(dpy, data.winid, xrect.x(), xrect.y(), xrect.width(), xrect.height());
- }
-
- //to avoid flicker, we have to show children after the helper widget has moved
- if (jump) {
- for (int i = 0; i < children.size(); ++i) {
- QObject *object = children.at(i);
- if (object->isWidgetType()) {
- QWidget *w = static_cast<QWidget *>(object);
- if (!w->testAttribute(Qt::WA_OutsideWSRange) && !w->testAttribute(Qt::WA_Mapped) && !w->isHidden()) {
- w->setAttribute(Qt::WA_Mapped);
- if (w->internalWinId())
- XMapWindow(dpy, w->data->winid);
- }
- }
- }
- }
-
-
- if (jump && data.winid)
- XClearArea(dpy, data.winid, 0, 0, wrect.width(), wrect.height(), True);
-
- if (mapWindow && !dontShow) {
- q->setAttribute(Qt::WA_Mapped);
- if (data.winid)
- XMapWindow(dpy, data.winid);
- }
-}
-
-void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove)
-{
- Q_Q(QWidget);
- Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
- Display *dpy = X11->display;
-
- if ((q->windowType() == Qt::Desktop))
- return;
- if (q->isWindow()) {
- if (!X11->isSupportedByWM(ATOM(_NET_WM_STATE_MAXIMIZED_VERT))
- && !X11->isSupportedByWM(ATOM(_NET_WM_STATE_MAXIMIZED_HORZ)))
- data.window_state &= ~Qt::WindowMaximized;
- if (!X11->isSupportedByWM(ATOM(_NET_WM_STATE_FULLSCREEN)))
- data.window_state &= ~Qt::WindowFullScreen;
- if (QTLWExtra *topData = maybeTopData())
- topData->normalGeometry = QRect(0,0,-1,-1);
- } else {
- uint s = data.window_state;
- s &= ~(Qt::WindowMaximized | Qt::WindowFullScreen);
- data.window_state = s;
- }
- if (extra) { // any size restrictions?
- w = qMin(w,extra->maxw);
- h = qMin(h,extra->maxh);
- w = qMax(w,extra->minw);
- h = qMax(h,extra->minh);
- }
- QPoint oldPos(q->pos());
- QSize oldSize(q->size());
- QRect oldGeom(data.crect);
- QRect r(x, y, w, h);
-
- // We only care about stuff that changes the geometry, or may
- // cause the window manager to change its state
- if (!q->isWindow() && oldGeom == r)
- return;
-
- data.crect = r;
- bool isResize = q->size() != oldSize;
-
- if (q->isWindow()) {
- if (w == 0 || h == 0) {
- q->setAttribute(Qt::WA_OutsideWSRange, true);
- if (q->isVisible() && q->testAttribute(Qt::WA_Mapped))
- hide_sys();
- } else if (q->isVisible() && q->testAttribute(Qt::WA_OutsideWSRange)) {
- q->setAttribute(Qt::WA_OutsideWSRange, false);
-
- // put the window in its place and show it
- if (data.winid)
- XMoveResizeWindow(dpy, data.winid, x, y, w, h);
- topData()->posFromMove = false; // force StaticGravity
- do_size_hints(q, extra);
- show_sys();
- } else {
- q->setAttribute(Qt::WA_OutsideWSRange, false);
- if (!q->isVisible())
- do_size_hints(q, extra);
- if (isMove) {
- if ((data.window_flags & Qt::X11BypassWindowManagerHint) == Qt::X11BypassWindowManagerHint
- // work around 4Dwm's incompliance with ICCCM 4.1.5
- || X11->desktopEnvironment == DE_4DWM) {
- if (data.winid)
- XMoveResizeWindow(dpy, data.winid, x, y, w, h);
- } else if (q->isVisible()
- && topData()->validWMState
- && X11->isSupportedByWM(ATOM(_NET_MOVERESIZE_WINDOW))) {
- XEvent e;
- e.xclient.type = ClientMessage;
- e.xclient.message_type = ATOM(_NET_MOVERESIZE_WINDOW);
- e.xclient.display = X11->display;
- e.xclient.window = q->internalWinId();
- e.xclient.format = 32;
- e.xclient.data.l[0] = StaticGravity | 1<<8 | 1<<9 | 1<<10 | 1<<11 | 1<<12;
- e.xclient.data.l[1] = x;
- e.xclient.data.l[2] = y;
- e.xclient.data.l[3] = w;
- e.xclient.data.l[4] = h;
- XSendEvent(X11->display, RootWindow(X11->display, q->x11Info().screen()),
- false, (SubstructureNotifyMask | SubstructureRedirectMask), &e);
- } else if (data.winid) {
- // pos() is right according to ICCCM 4.1.5
- XMoveResizeWindow(dpy, data.winid, q->pos().x(), q->pos().y(), w, h);
- }
- } else if (isResize && data.winid) {
- if (!q->isVisible()
- && topData()->validWMState
- && !q->testAttribute(Qt::WA_PendingMoveEvent)) {
- /*
- even though we've not visible, we could be in a
- race w/ the window manager, and it may ignore
- our ConfigureRequest. setting posFromMove to
- false makes sure that doDeferredMap() in
- qapplication_x11.cpp keeps the window in the
- right place
- */
- topData()->posFromMove = false;
- }
- XResizeWindow(dpy, data.winid, w, h);
- }
- }
- if (isResize && !q->testAttribute(Qt::WA_DontShowOnScreen)) // set config pending only on resize, see qapplication_x11.cpp, translateConfigEvent()
- q->setAttribute(Qt::WA_WState_ConfigPending);
-
- } else {
- QTLWExtra *tlwExtra = q->window()->d_func()->maybeTopData();
- const bool inTopLevelResize = tlwExtra ? tlwExtra->inTopLevelResize : false;
- const bool disableInTopLevelResize = inTopLevelResize && q->internalWinId();
- if (disableInTopLevelResize) {
- // Top-level resize optimization does not work for native child widgets;
- // disable it for this particular widget.
- tlwExtra->inTopLevelResize = false;
- }
-
- if (!isResize && (!inTopLevelResize || disableInTopLevelResize) && q->isVisible()) {
- moveRect(QRect(oldPos, oldSize), x - oldPos.x(), y - oldPos.y());
- }
- if (q->testAttribute(Qt::WA_WState_Created))
- setWSGeometry();
-
- if (isResize && (!inTopLevelResize || disableInTopLevelResize) && q->isVisible())
- invalidateBuffer_resizeHelper(oldPos, oldSize);
-
- if (disableInTopLevelResize)
- tlwExtra->inTopLevelResize = true;
- }
-
- if (q->isVisible()) {
- if (isMove && q->pos() != oldPos) {
- if (X11->desktopEnvironment != DE_4DWM) {
- // pos() is right according to ICCCM 4.1.5
- QMoveEvent e(q->pos(), oldPos);
- QApplication::sendEvent(q, &e);
- } else {
- // work around 4Dwm's incompliance with ICCCM 4.1.5
- QMoveEvent e(data.crect.topLeft(), oldGeom.topLeft());
- QApplication::sendEvent(q, &e);
- }
- }
- if (isResize) {
- static bool slowResize = qgetenv("QT_SLOW_TOPLEVEL_RESIZE").toInt();
- // If we have a backing store with static contents, we have to disable the top-level
- // resize optimization in order to get invalidated regions for resized widgets.
- // The optimization discards all invalidateBuffer() calls since we're going to
- // repaint everything anyways, but that's not the case with static contents.
- const bool setTopLevelResize = !slowResize && q->isWindow() && extra && extra->topextra
- && !extra->topextra->inTopLevelResize
- && (!extra->topextra->backingStore
- || !extra->topextra->backingStore->hasStaticContents());
- if (setTopLevelResize)
- extra->topextra->inTopLevelResize = true;
- QResizeEvent e(q->size(), oldSize);
- QApplication::sendEvent(q, &e);
- if (setTopLevelResize)
- extra->topextra->inTopLevelResize = false;
- }
- } else {
- if (isMove && q->pos() != oldPos)
- q->setAttribute(Qt::WA_PendingMoveEvent, true);
- if (isResize)
- q->setAttribute(Qt::WA_PendingResizeEvent, true);
- }
-}
-
-void QWidgetPrivate::setConstraints_sys()
-{
- Q_Q(QWidget);
-#ifdef ALIEN_DEBUG
- qDebug() << "QWidgetPrivate::setConstraints_sys START" << q;
-#endif
- if (q->testAttribute(Qt::WA_WState_Created))
- do_size_hints(q, extra);
-#ifdef ALIEN_DEBUG
- qDebug() << "QWidgetPrivate::setConstraints_sys END" << q;
-#endif
-}
-
-void QWidgetPrivate::scroll_sys(int dx, int dy)
-{
- Q_Q(QWidget);
-
- scrollChildren(dx, dy);
- if (!paintOnScreen()) {
- scrollRect(q->rect(), dx, dy);
- } else {
- scroll_sys(dx, dy, QRect());
- }
-}
-
-void QWidgetPrivate::scroll_sys(int dx, int dy, const QRect &r)
-{
- Q_Q(QWidget);
-
- if (!paintOnScreen()) {
- scrollRect(r, dx, dy);
- return;
- }
- bool valid_rect = r.isValid();
- bool just_update = qAbs(dx) > q->width() || qAbs(dy) > q->height();
- QRect sr = valid_rect ? r : clipRect();
- if (just_update)
- q->update();
- else if (!valid_rect)
- dirty.translate(dx, dy);
-
- int x1, y1, x2, y2, w = sr.width(), h = sr.height();
- if (dx > 0) {
- x1 = sr.x();
- x2 = x1+dx;
- w -= dx;
- } else {
- x2 = sr.x();
- x1 = x2-dx;
- w += dx;
- }
- if (dy > 0) {
- y1 = sr.y();
- y2 = y1+dy;
- h -= dy;
- } else {
- y2 = sr.y();
- y1 = y2-dy;
- h += dy;
- }
-
- if (dx == 0 && dy == 0)
- return;
-
- Display *dpy = X11->display;
- // Want expose events
- if (w > 0 && h > 0 && !just_update && q->internalWinId()) {
- GC gc = XCreateGC(dpy, q->internalWinId(), 0, 0);
- XSetGraphicsExposures(dpy, gc, True);
- XCopyArea(dpy, q->internalWinId(), q->internalWinId(), gc, x1, y1, w, h, x2, y2);
- XFreeGC(dpy, gc);
- }
-
- if (!valid_rect && !children.isEmpty()) { // scroll children
- QPoint pd(dx, dy);
- for (int i = 0; i < children.size(); ++i) { // move all children
- register QObject *object = children.at(i);
- if (object->isWidgetType()) {
- QWidget *w = static_cast<QWidget *>(object);
- if (!w->isWindow())
- w->move(w->pos() + pd);
- }
- }
- }
-
- if (just_update)
- return;
-
- // Don't let the server be bogged-down with repaint events
- bool repaint_immediately = (qt_sip_count(q) < 3 && !q->testAttribute(Qt::WA_WState_InPaintEvent));
-
- if (dx) {
- int x = x2 == sr.x() ? sr.x()+w : sr.x();
- if (repaint_immediately)
- q->repaint(x, sr.y(), qAbs(dx), sr.height());
- else if (q->internalWinId())
- XClearArea(dpy, data.winid, x, sr.y(), qAbs(dx), sr.height(), True);
- }
- if (dy) {
- int y = y2 == sr.y() ? sr.y()+h : sr.y();
- if (repaint_immediately)
- q->repaint(sr.x(), y, sr.width(), qAbs(dy));
- else if (q->internalWinId())
- XClearArea(dpy, data.winid, sr.x(), y, sr.width(), qAbs(dy), True);
- }
-
- qt_insert_sip(q, dx, dy); // #### ignores r
-}
-
-int QWidget::metric(PaintDeviceMetric m) const
-{
- Q_D(const QWidget);
- int val;
- if (m == PdmWidth) {
- val = data->crect.width();
- } else if (m == PdmHeight) {
- val = data->crect.height();
- } else {
- Display *dpy = X11->display;
- int scr = d->xinfo.screen();
- switch (m) {
- case PdmDpiX:
- case PdmPhysicalDpiX:
- if (d->extra && d->extra->customDpiX)
- val = d->extra->customDpiX;
- else if (d->parent)
- val = static_cast<QWidget *>(d->parent)->metric(m);
- else
- val = QX11Info::appDpiX(scr);
- break;
- case PdmDpiY:
- case PdmPhysicalDpiY:
- if (d->extra && d->extra->customDpiY)
- val = d->extra->customDpiY;
- else if (d->parent)
- val = static_cast<QWidget *>(d->parent)->metric(m);
- else
- val = QX11Info::appDpiY(scr);
- break;
- case PdmWidthMM:
- val = (DisplayWidthMM(dpy,scr)*data->crect.width())/
- DisplayWidth(dpy,scr);
- break;
- case PdmHeightMM:
- val = (DisplayHeightMM(dpy,scr)*data->crect.height())/
- DisplayHeight(dpy,scr);
- break;
- case PdmNumColors:
- val = d->xinfo.cells();
- break;
- case PdmDepth:
- val = d->xinfo.depth();
- break;
- default:
- val = 0;
- qWarning("QWidget::metric: Invalid metric command");
- }
- }
- return val;
-}
-
-void QWidgetPrivate::createSysExtra()
-{
- extra->compress_events = true;
- extra->xDndProxy = 0;
-}
-
-void QWidgetPrivate::deleteSysExtra()
-{
-}
-
-void QWidgetPrivate::createTLSysExtra()
-{
- extra->topextra->spont_unmapped = 0;
- extra->topextra->dnd = 0;
- extra->topextra->validWMState = 0;
- extra->topextra->waitingForMapNotify = 0;
- extra->topextra->parentWinId = 0;
- extra->topextra->userTimeWindow = 0;
-#ifndef QT_NO_XSYNC
- extra->topextra->syncUpdateCounter = 0;
- extra->topextra->syncRequestTimestamp = 0;
- extra->topextra->newCounterValueHi = 0;
- extra->topextra->newCounterValueLo = 0;
-#endif
-}
-
-void QWidgetPrivate::deleteTLSysExtra()
-{
- // don't destroy input context here. it will be destroyed in
- // QWidget::destroy() destroyInputContext();
-}
-
-void QWidgetPrivate::registerDropSite(bool on)
-{
- Q_UNUSED(on);
-}
-
-void QWidgetPrivate::setMask_sys(const QRegion &region)
-{
- Q_Q(QWidget);
- if (!q->internalWinId())
- return;
-
- if (region.isEmpty()) {
- XShapeCombineMask(X11->display, q->internalWinId(), ShapeBounding, 0, 0,
- XNone, ShapeSet);
- } else {
- XShapeCombineRegion(X11->display, q->internalWinId(), ShapeBounding, 0, 0,
- region.handle(), ShapeSet);
- }
-}
-
-/*!
- \internal
-
- Computes the frame rectangle when needed. This is an internal function, you
- should never call this.
-*/
-
-void QWidgetPrivate::updateFrameStrut()
-{
- Q_Q(QWidget);
-
- QTLWExtra *top = topData();
- if (!top->validWMState) {
- return;
- }
- if (!q->isWindow() && !q->internalWinId()) {
- data.fstrut_dirty = false;
- return;
- }
-
- Atom type_ret;
- Window l = q->effectiveWinId(), w = l, p, r; // target window, its parent, root
- Window *c;
- int i_unused;
- unsigned int nc;
- unsigned char *data_ret;
- unsigned long l_unused;
-
- while (XQueryTree(X11->display, w, &r, &p, &c, &nc)) {
- if (c && nc > 0)
- XFree(c);
-
- if (! p) {
- qWarning("QWidget::updateFrameStrut: No parent");
- return;
- }
-
- // if the parent window is the root window, an Enlightenment virtual root or
- // a NET WM virtual root window, stop here
- data_ret = 0;
- if (p == r ||
- (XGetWindowProperty(X11->display, p,
- ATOM(ENLIGHTENMENT_DESKTOP), 0, 1, False, XA_CARDINAL,
- &type_ret, &i_unused, &l_unused, &l_unused,
- &data_ret) == Success &&
- type_ret == XA_CARDINAL)) {
- if (data_ret)
- XFree(data_ret);
-
- break;
- } else if (X11->isSupportedByWM(ATOM(_NET_VIRTUAL_ROOTS)) && X11->net_virtual_root_list) {
- int i = 0;
- while (X11->net_virtual_root_list[i] != 0) {
- if (X11->net_virtual_root_list[i++] == p)
- break;
- }
- }
-
- l = w;
- w = p;
- }
-
- // we have our window
- int transx, transy;
- XWindowAttributes wattr;
- if (XTranslateCoordinates(X11->display, l, w,
- 0, 0, &transx, &transy, &p) &&
- XGetWindowAttributes(X11->display, w, &wattr)) {
- top->frameStrut.setCoords(transx,
- transy,
- wattr.width - data.crect.width() - transx,
- wattr.height - data.crect.height() - transy);
-
- // add the border_width for the window managers frame... some window managers
- // do not use a border_width of zero for their frames, and if we the left and
- // top strut, we ensure that pos() is absolutely correct. frameGeometry()
- // will still be incorrect though... perhaps i should have foffset as well, to
- // indicate the frame offset (equal to the border_width on X).
- // - Brad
- top->frameStrut.adjust(wattr.border_width,
- wattr.border_width,
- wattr.border_width,
- wattr.border_width);
- }
-
- data.fstrut_dirty = false;
-}
-
-void QWidgetPrivate::setWindowOpacity_sys(qreal opacity)
-{
- Q_Q(QWidget);
- ulong value = ulong(opacity * 0xffffffff);
- XChangeProperty(QX11Info::display(), q->internalWinId(), ATOM(_NET_WM_WINDOW_OPACITY), XA_CARDINAL,
- 32, PropModeReplace, (uchar*)&value, 1);
-}
-
-const QX11Info &QWidget::x11Info() const
-{
- Q_D(const QWidget);
- return d->xinfo;
-}
-
-void QWidgetPrivate::setWindowRole()
-{
- Q_Q(QWidget);
- if (!q->internalWinId())
- return;
- QByteArray windowRole = topData()->role.toUtf8();
- XChangeProperty(X11->display, q->internalWinId(),
- ATOM(WM_WINDOW_ROLE), XA_STRING, 8, PropModeReplace,
- (unsigned char *)windowRole.constData(), windowRole.length());
-}
-
-Q_GLOBAL_STATIC(QX11PaintEngine, qt_widget_paintengine)
-QPaintEngine *QWidget::paintEngine() const
-{
- Q_D(const QWidget);
- if (qt_widget_paintengine()->isActive()) {
- if (d->extraPaintEngine)
- return d->extraPaintEngine;
- QWidget *self = const_cast<QWidget *>(this);
- self->d_func()->extraPaintEngine = new QX11PaintEngine();
- return d->extraPaintEngine;
- }
- return qt_widget_paintengine();
-}
-
-QWindowSurface *QWidgetPrivate::createDefaultWindowSurface_sys()
-{
- return new QX11WindowSurface(q_func());
-}
-
-Qt::HANDLE QWidget::x11PictureHandle() const
-{
-#ifndef QT_NO_XRENDER
- Q_D(const QWidget);
- if (!internalWinId() && testAttribute(Qt::WA_WState_Created))
- (void)winId(); // enforce native window
- return d->picture;
-#else
- return 0;
-#endif // QT_NO_XRENDER
-}
-
-#ifndef QT_NO_XRENDER
-XRenderColor QX11Data::preMultiply(const QColor &c)
-{
- XRenderColor color;
- const uint A = c.alpha(),
- R = c.red(),
- G = c.green(),
- B = c.blue();
- color.alpha = (A | A << 8);
- color.red = (R | R << 8) * color.alpha / 0x10000;
- color.green = (G | G << 8) * color.alpha / 0x10000;
- color.blue = (B | B << 8) * color.alpha / 0x10000;
- return color;
-}
-Picture QX11Data::getSolidFill(int screen, const QColor &c)
-{
- if (!X11->use_xrender)
- return XNone;
-
- XRenderColor color = preMultiply(c);
- for (int i = 0; i < X11->solid_fill_count; ++i) {
- if (X11->solid_fills[i].screen == screen
- && X11->solid_fills[i].color.alpha == color.alpha
- && X11->solid_fills[i].color.red == color.red
- && X11->solid_fills[i].color.green == color.green
- && X11->solid_fills[i].color.blue == color.blue)
- return X11->solid_fills[i].picture;
- }
- // none found, replace one
- int i = qrand() % 16;
-
- if (X11->solid_fills[i].screen != screen && X11->solid_fills[i].picture) {
- XRenderFreePicture (X11->display, X11->solid_fills[i].picture);
- X11->solid_fills[i].picture = 0;
- }
-
- if (!X11->solid_fills[i].picture) {
- Pixmap pixmap = XCreatePixmap (X11->display, RootWindow (X11->display, screen), 1, 1, 32);
- XRenderPictureAttributes attrs;
- attrs.repeat = True;
- X11->solid_fills[i].picture = XRenderCreatePicture (X11->display, pixmap,
- XRenderFindStandardFormat(X11->display, PictStandardARGB32),
- CPRepeat, &attrs);
- XFreePixmap (X11->display, pixmap);
- }
-
- X11->solid_fills[i].color = color;
- X11->solid_fills[i].screen = screen;
- XRenderFillRectangle (X11->display, PictOpSrc, X11->solid_fills[i].picture, &color, 0, 0, 1, 1);
- return X11->solid_fills[i].picture;
-}
-#endif
-
-void QWidgetPrivate::setModal_sys()
-{
-}
-
-void qt_x11_getX11InfoForWindow(QX11Info * xinfo, const QX11WindowAttributes &att)
-{
- QX11InfoData* xd = xinfo->getX11Data(true);
- const XWindowAttributes &a = *(att.att);
- // find which screen the window is on...
- xd->screen = QX11Info::appScreen(); // by default, use the default :)
- int i;
- for (i = 0; i < ScreenCount(X11->display); i++) {
- if (RootWindow(X11->display, i) == a.root) {
- xd->screen = i;
- break;
- }
- }
-
- xd->depth = a.depth;
- xd->cells = DisplayCells(X11->display, xd->screen);
- xd->visual = a.visual;
- xd->defaultVisual = (XVisualIDFromVisual((Visual *) a.visual) ==
- XVisualIDFromVisual((Visual *) QX11Info::appVisual(xinfo->screen())));
- xd->colormap = a.colormap;
- xd->defaultColormap = (a.colormap == QX11Info::appColormap(xinfo->screen()));
- xinfo->setX11Data(xd);
-}
-
-void QWidgetPrivate::updateX11AcceptFocus()
-{
- Q_Q(QWidget);
- if (!q->isWindow() || !q->internalWinId())
- return;
-
- XWMHints *h = XGetWMHints(X11->display, q->internalWinId());
- XWMHints wm_hints;
- if (!h) {
- memset(&wm_hints, 0, sizeof(wm_hints)); // make valgrind happy
- h = &wm_hints;
- }
- h->flags |= InputHint;
- h->input = q->testAttribute(Qt::WA_X11DoNotAcceptFocus) ? False : True;
-
- XSetWMHints(X11->display, q->internalWinId(), h);
- if (h != &wm_hints)
- XFree((char *)h);
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/kernel/qwidgetaction.h b/src/gui/kernel/qwidgetaction.h
deleted file mode 100644
index 94a681791b..0000000000
--- a/src/gui/kernel/qwidgetaction.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWIDGETACTION_H
-#define QWIDGETACTION_H
-
-#include <QtGui/qaction.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_ACTION
-
-class QWidgetActionPrivate;
-
-class Q_GUI_EXPORT QWidgetAction : public QAction
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QWidgetAction)
-
-public:
- explicit QWidgetAction(QObject *parent);
- virtual ~QWidgetAction();
-
- void setDefaultWidget(QWidget *w);
- QWidget *defaultWidget() const;
-
- QWidget *requestWidget(QWidget *parent);
- void releaseWidget(QWidget *widget);
-
-protected:
- virtual bool event(QEvent *);
- virtual bool eventFilter(QObject *, QEvent *);
- virtual QWidget *createWidget(QWidget *parent);
- virtual void deleteWidget(QWidget *widget);
- QList<QWidget *> createdWidgets() const;
-
-private:
- Q_DISABLE_COPY(QWidgetAction)
- Q_PRIVATE_SLOT(d_func(), void _q_widgetDestroyed(QObject *))
- friend class QToolBar;
-};
-
-#endif // QT_NO_ACTION
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QWIDGETACTION_H
diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp
new file mode 100644
index 0000000000..9bf58e1656
--- /dev/null
+++ b/src/gui/kernel/qwindow.cpp
@@ -0,0 +1,701 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindow.h"
+
+#include "qplatformwindow_qpa.h"
+#include "qsurfaceformat.h"
+#include "qplatformopenglcontext_qpa.h"
+#include "qopenglcontext.h"
+#include "qscreen.h"
+
+#include "qwindow_p.h"
+#include "qguiapplication_p.h"
+
+#include <private/qevent_p.h>
+
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+QWindow::QWindow(QScreen *targetScreen)
+ : QObject(*new QWindowPrivate(), 0)
+ , QSurface(QSurface::Window)
+{
+ Q_D(QWindow);
+ d->screen = targetScreen;
+ if (!d->screen)
+ d->screen = QGuiApplication::primaryScreen();
+ QGuiApplicationPrivate::window_list.prepend(this);
+}
+
+QWindow::QWindow(QWindow *parent)
+ : QObject(*new QWindowPrivate(), parent)
+ , QSurface(QSurface::Window)
+{
+ Q_D(QWindow);
+ d->parentWindow = parent;
+ if (parent)
+ d->screen = parent->screen();
+ if (!d->screen)
+ d->screen = QGuiApplication::primaryScreen();
+ QGuiApplicationPrivate::window_list.prepend(this);
+}
+
+QWindow::QWindow(QWindowPrivate &dd, QWindow *parent)
+ : QObject(dd, parent)
+ , QSurface(QSurface::Window)
+{
+ Q_D(QWindow);
+ d->parentWindow = parent;
+ if (parent)
+ d->screen = parent->screen();
+ if (!d->screen)
+ d->screen = QGuiApplication::primaryScreen();
+ QGuiApplicationPrivate::window_list.prepend(this);
+}
+
+QWindow::~QWindow()
+{
+ if (QGuiApplicationPrivate::active_window == this)
+ QGuiApplicationPrivate::active_window = 0;
+ QGuiApplicationPrivate::window_list.removeAll(this);
+ destroy();
+}
+
+QSurface::~QSurface()
+{
+}
+
+void QWindow::setSurfaceType(SurfaceType surfaceType)
+{
+ Q_D(QWindow);
+ d->surfaceType = surfaceType;
+}
+
+QWindow::SurfaceType QWindow::surfaceType() const
+{
+ Q_D(const QWindow);
+ return d->surfaceType;
+}
+
+void QWindow::setVisible(bool visible)
+{
+ Q_D(QWindow);
+
+ if (d->visible == visible)
+ return;
+ d->visible = visible;
+
+ if (!d->platformWindow)
+ create();
+
+ if (visible) {
+ QShowEvent showEvent;
+ QGuiApplication::sendEvent(this, &showEvent);
+ }
+
+ d->platformWindow->setVisible(visible);
+
+ if (!visible) {
+ QHideEvent hideEvent;
+ QGuiApplication::sendEvent(this, &hideEvent);
+ }
+}
+
+bool QWindow::visible() const
+{
+ Q_D(const QWindow);
+
+ return d->visible;
+}
+
+void QWindow::create()
+{
+ Q_D(QWindow);
+ if (!d->platformWindow) {
+ d->platformWindow = QGuiApplicationPrivate::platformIntegration()->createPlatformWindow(this);
+ QObjectList childObjects = children();
+ for (int i = 0; i < childObjects.size(); i ++) {
+ QObject *object = childObjects.at(i);
+ if(object->isWindowType()) {
+ QWindow *window = static_cast<QWindow *>(object);
+ if (window->d_func()->platformWindow)
+ window->d_func()->platformWindow->setParent(d->platformWindow);
+ }
+ }
+ }
+}
+
+WId QWindow::winId() const
+{
+ Q_D(const QWindow);
+ if(!d->platformWindow)
+ const_cast<QWindow *>(this)->create();
+ return d->platformWindow->winId();
+}
+
+QWindow *QWindow::parent() const
+{
+ Q_D(const QWindow);
+ return d->parentWindow;
+}
+
+/**
+ Sets the parent Window. This will lead to the windowing system managing the clip of the window, so it will be clipped to the parent window.
+ Setting parent to be 0(NULL) means map it as a top level window. If the parent window has grabbed its window system resources, then the current window will also grab its window system resources.
+ **/
+
+void QWindow::setParent(QWindow *parent)
+{
+ Q_D(QWindow);
+
+ QObject::setParent(parent);
+
+ if (d->platformWindow) {
+ if (parent && parent->d_func()->platformWindow) {
+ d->platformWindow->setParent(parent->d_func()->platformWindow);
+ } else {
+ d->platformWindow->setParent(0);
+ }
+ }
+
+ d->parentWindow = parent;
+}
+
+/*!
+ Returns whether the window is top level, i.e. has no parent window.
+ */
+bool QWindow::isTopLevel() const
+{
+ Q_D(const QWindow);
+ return d->parentWindow == 0;
+}
+
+bool QWindow::isModal() const
+{
+ Q_D(const QWindow);
+ return d->modality != Qt::NonModal;
+}
+
+Qt::WindowModality QWindow::windowModality() const
+{
+ Q_D(const QWindow);
+ return d->modality;
+}
+
+void QWindow::setWindowModality(Qt::WindowModality windowModality)
+{
+ Q_D(QWindow);
+ d->modality = windowModality;
+}
+
+void QWindow::setFormat(const QSurfaceFormat &format)
+{
+ Q_D(QWindow);
+ d->requestedFormat = format;
+}
+
+QSurfaceFormat QWindow::format() const
+{
+ Q_D(const QWindow);
+ if (d->platformWindow)
+ return d->platformWindow->format();
+ return d->requestedFormat;
+}
+
+void QWindow::setWindowFlags(Qt::WindowFlags flags)
+{
+ Q_D(QWindow);
+ if (d->platformWindow)
+ d->windowFlags = d->platformWindow->setWindowFlags(flags);
+ else
+ d->windowFlags = flags;
+}
+
+Qt::WindowFlags QWindow::windowFlags() const
+{
+ Q_D(const QWindow);
+ return d->windowFlags;
+}
+
+Qt::WindowType QWindow::windowType() const
+{
+ Q_D(const QWindow);
+ return static_cast<Qt::WindowType>(int(d->windowFlags & Qt::WindowType_Mask));
+}
+
+void QWindow::setWindowTitle(const QString &title)
+{
+ Q_D(QWindow);
+ d->windowTitle = title;
+ if (d->platformWindow) {
+ d->platformWindow->setWindowTitle(title);
+ }
+}
+
+QString QWindow::windowTitle() const
+{
+ Q_D(const QWindow);
+ return d->windowTitle;
+}
+
+void QWindow::raise()
+{
+ Q_D(QWindow);
+ if (d->platformWindow) {
+ d->platformWindow->raise();
+ }
+}
+
+void QWindow::lower()
+{
+ Q_D(QWindow);
+ if (d->platformWindow) {
+ d->platformWindow->lower();
+ }
+}
+
+void QWindow::setOpacity(qreal level)
+{
+ Q_D(QWindow);
+ if (d->platformWindow) {
+ d->platformWindow->setOpacity(level);
+ }
+}
+
+void QWindow::requestActivateWindow()
+{
+ Q_D(QWindow);
+ QGuiApplicationPrivate::active_window = this;
+ if (d->platformWindow) {
+ d->platformWindow->requestActivateWindow();
+ }
+}
+
+Qt::WindowState QWindow::windowState() const
+{
+ Q_D(const QWindow);
+ return d->windowState;
+}
+
+void QWindow::setWindowState(Qt::WindowState state)
+{
+ if (state == Qt::WindowActive) {
+ requestActivateWindow();
+ return;
+ }
+
+ Q_D(QWindow);
+ if (d->platformWindow)
+ d->windowState = d->platformWindow->setWindowState(state);
+ else
+ d->windowState = state;
+}
+
+/*!
+ Sets the transient parent, which is a hint to the window manager that this window is a dialog or pop-up on behalf of the given window.
+*/
+void QWindow::setTransientParent(QWindow *parent)
+{
+ Q_D(QWindow);
+ d->transientParent = parent;
+}
+
+QWindow *QWindow::transientParent() const
+{
+ Q_D(const QWindow);
+ return d->transientParent.data();
+}
+
+QSize QWindow::minimumSize() const
+{
+ Q_D(const QWindow);
+ return d->minimumSize;
+}
+
+QSize QWindow::maximumSize() const
+{
+ Q_D(const QWindow);
+ return d->maximumSize;
+}
+
+QSize QWindow::baseSize() const
+{
+ Q_D(const QWindow);
+ return d->baseSize;
+}
+
+QSize QWindow::sizeIncrement() const
+{
+ Q_D(const QWindow);
+ return d->sizeIncrement;
+}
+
+void QWindow::setMinimumSize(const QSize &size)
+{
+ Q_D(QWindow);
+ QSize adjustedSize = QSize(qBound(0, size.width(), QWINDOWSIZE_MAX), qBound(0, size.height(), QWINDOWSIZE_MAX));
+ if (d->minimumSize == adjustedSize)
+ return;
+ d->minimumSize = adjustedSize;
+ if (d->platformWindow && isTopLevel())
+ d->platformWindow->propagateSizeHints();
+}
+
+void QWindow::setMaximumSize(const QSize &size)
+{
+ Q_D(QWindow);
+ QSize adjustedSize = QSize(qBound(0, size.width(), QWINDOWSIZE_MAX), qBound(0, size.height(), QWINDOWSIZE_MAX));
+ if (d->maximumSize == adjustedSize)
+ return;
+ d->maximumSize = adjustedSize;
+ if (d->platformWindow && isTopLevel())
+ d->platformWindow->propagateSizeHints();
+}
+
+void QWindow::setBaseSize(const QSize &size)
+{
+ Q_D(QWindow);
+ if (d->baseSize == size)
+ return;
+ d->baseSize = size;
+ if (d->platformWindow && isTopLevel())
+ d->platformWindow->propagateSizeHints();
+}
+
+void QWindow::setSizeIncrement(const QSize &size)
+{
+ Q_D(QWindow);
+ if (d->sizeIncrement == size)
+ return;
+ d->sizeIncrement = size;
+ if (d->platformWindow && isTopLevel())
+ d->platformWindow->propagateSizeHints();
+}
+
+void QWindow::setGeometry(const QRect &rect)
+{
+ Q_D(QWindow);
+ if (d->platformWindow) {
+ d->platformWindow->setGeometry(rect);
+ } else {
+ d->geometry = rect;
+ }
+}
+
+QRect QWindow::geometry() const
+{
+ Q_D(const QWindow);
+ return d->geometry;
+}
+
+QMargins QWindow::frameMargins() const
+{
+ Q_D(const QWindow);
+ if (d->platformWindow)
+ return d->platformWindow->frameMargins();
+ return QMargins();
+}
+
+void QWindow::setWindowIcon(const QImage &icon) const
+{
+ Q_UNUSED(icon);
+ qDebug() << "unimplemented:" << __FILE__ << __LINE__;
+}
+
+void QWindow::destroy()
+{
+ Q_D(QWindow);
+ setVisible(false);
+ delete d->platformWindow;
+ d->platformWindow = 0;
+}
+
+QPlatformWindow *QWindow::handle() const
+{
+ Q_D(const QWindow);
+ return d->platformWindow;
+}
+
+QPlatformSurface *QWindow::surfaceHandle() const
+{
+ Q_D(const QWindow);
+ return d->platformWindow;
+}
+
+bool QWindow::setKeyboardGrabEnabled(bool grab)
+{
+ Q_D(QWindow);
+ if (d->platformWindow)
+ return d->platformWindow->setKeyboardGrabEnabled(grab);
+ return false;
+}
+
+bool QWindow::setMouseGrabEnabled(bool grab)
+{
+ Q_D(QWindow);
+ if (d->platformWindow)
+ return d->platformWindow->setMouseGrabEnabled(grab);
+ return false;
+}
+
+QScreen *QWindow::screen() const
+{
+ Q_D(const QWindow);
+ return d->screen;
+}
+
+void QWindow::setScreen(QScreen *newScreen)
+{
+ Q_D(QWindow);
+ bool wasCreated = d->platformWindow != 0;
+ if (wasCreated)
+ destroy();
+ d->screen = newScreen ? newScreen : QGuiApplication::primaryScreen();
+ if (wasCreated)
+ create();
+}
+
+void QWindow::showMinimized()
+{
+ qDebug() << "unimplemented:" << __FILE__ << __LINE__;
+}
+
+void QWindow::showMaximized()
+{
+ qDebug() << "unimplemented:" << __FILE__ << __LINE__;
+}
+
+void QWindow::showFullScreen()
+{
+ qDebug() << "unimplemented:" << __FILE__ << __LINE__;
+}
+
+void QWindow::showNormal()
+{
+ qDebug() << "unimplemented:" << __FILE__ << __LINE__;
+}
+
+bool QWindow::close()
+{
+ //should we have close?
+ qDebug() << "unimplemented:" << __FILE__ << __LINE__;
+ return true;
+}
+
+void QWindow::exposeEvent(QExposeEvent *)
+{
+}
+
+void QWindow::resizeEvent(QResizeEvent *)
+{
+}
+
+void QWindow::showEvent(QShowEvent *)
+{
+}
+
+void QWindow::hideEvent(QHideEvent *)
+{
+}
+
+bool QWindow::event(QEvent *event)
+{
+ switch (event->type()) {
+ case QEvent::MouseMove:
+ mouseMoveEvent(static_cast<QMouseEvent*>(event));
+ break;
+
+ case QEvent::MouseButtonPress:
+ mousePressEvent(static_cast<QMouseEvent*>(event));
+ break;
+
+ case QEvent::MouseButtonRelease:
+ mouseReleaseEvent(static_cast<QMouseEvent*>(event));
+ break;
+
+ case QEvent::MouseButtonDblClick:
+ mouseDoubleClickEvent(static_cast<QMouseEvent*>(event));
+ break;
+
+ case QEvent::Resize:
+ resizeEvent(static_cast<QResizeEvent*>(event));
+ break;
+
+ case QEvent::KeyPress:
+ keyPressEvent(static_cast<QKeyEvent *>(event));
+ break;
+
+ case QEvent::KeyRelease:
+ keyReleaseEvent(static_cast<QKeyEvent *>(event));
+ break;
+
+#ifndef QT_NO_WHEELEVENT
+ case QEvent::Wheel:
+ wheelEvent(static_cast<QWheelEvent*>(event));
+ break;
+#endif
+
+ case QEvent::Close: {
+ Q_D(QWindow);
+ bool wasVisible = visible();
+ destroy();
+ if (wasVisible)
+ d->maybeQuitOnLastWindowClosed();
+ break; }
+
+ case QEvent::Expose:
+ exposeEvent(static_cast<QExposeEvent *>(event));
+ break;
+
+ case QEvent::Show:
+ showEvent(static_cast<QShowEvent *>(event));
+ break;
+
+ case QEvent::Hide:
+ hideEvent(static_cast<QHideEvent *>(event));
+ break;
+
+ default:
+ return QObject::event(event);
+ }
+ return true;
+}
+
+void QWindow::keyPressEvent(QKeyEvent *)
+{
+}
+
+void QWindow::keyReleaseEvent(QKeyEvent *)
+{
+}
+
+void QWindow::inputMethodEvent(QInputMethodEvent *)
+{
+}
+
+void QWindow::mousePressEvent(QMouseEvent *)
+{
+}
+
+void QWindow::mouseReleaseEvent(QMouseEvent *)
+{
+}
+
+void QWindow::mouseDoubleClickEvent(QMouseEvent *)
+{
+}
+
+void QWindow::mouseMoveEvent(QMouseEvent *)
+{
+}
+
+#ifndef QT_NO_WHEELEVENT
+void QWindow::wheelEvent(QWheelEvent *)
+{
+}
+#endif //QT_NO_WHEELEVENT
+
+
+
+/*!
+ \fn QPoint QWindow::mapToGlobal(const QPoint &pos) const
+
+ Translates the window coordinate \a pos to global screen
+ coordinates. For example, \c{mapToGlobal(QPoint(0,0))} would give
+ the global coordinates of the top-left pixel of the window.
+
+ \sa mapFromGlobal()
+*/
+
+QPoint QWindow::mapToGlobal(const QPoint &pos) const
+{
+ return pos + d_func()->globalPosition();
+}
+
+
+
+/*!
+ \fn QPoint QWindow::mapFromGlobal(const QPoint &pos) const
+
+ Translates the global screen coordinate \a pos to window
+ coordinates.
+
+ \sa mapToGlobal()
+*/
+
+QPoint QWindow::mapFromGlobal(const QPoint &pos) const
+{
+ return pos - d_func()->globalPosition();
+}
+
+
+
+Q_GUI_EXPORT QWindowPrivate *qt_window_private(QWindow *window)
+{
+ return window->d_func();
+}
+
+void QWindowPrivate::maybeQuitOnLastWindowClosed()
+{
+ Q_Q(QWindow);
+
+ // Attempt to close the application only if this has WA_QuitOnClose set and a non-visible parent
+ bool quitOnClose = QGuiApplication::quitOnLastWindowClosed() && !q->parent();
+
+ if (quitOnClose) {
+ QWindowList list = QGuiApplication::topLevelWindows();
+ bool lastWindowClosed = true;
+ for (int i = 0; i < list.size(); ++i) {
+ QWindow *w = list.at(i);
+ if (!w->visible() || w->parent())
+ continue;
+ lastWindowClosed = false;
+ break;
+ }
+ if (lastWindowClosed)
+ QGuiApplicationPrivate::emitLastWindowClosed();
+ }
+
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/kernel/qwindow.h b/src/gui/kernel/qwindow.h
new file mode 100644
index 0000000000..a6604aa951
--- /dev/null
+++ b/src/gui/kernel/qwindow.h
@@ -0,0 +1,227 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOW_QPA_H
+#define QWINDOW_QPA_H
+
+#include <QtCore/QObject>
+#include <QtCore/QEvent>
+#include <QtCore/QMargins>
+#include <QtCore/QRect>
+
+#include <QtGui/qsurface.h>
+#include <QtGui/qsurfaceformat.h>
+#include <QtGui/qwindowdefs.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QWindowPrivate;
+
+class QExposeEvent;
+class QResizeEvent;
+class QShowEvent;
+class QHideEvent;
+class QKeyEvent;
+class QInputMethodEvent;
+class QMouseEvent;
+#ifndef QT_NO_WHEELEVENT
+class QWheelEvent;
+#endif
+
+class QPlatformSurface;
+class QPlatformWindow;
+class QBackingStore;
+class QScreen;
+
+class Q_GUI_EXPORT QWindow : public QObject, public QSurface
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QWindow)
+
+ Q_PROPERTY(QString windowTitle READ windowTitle WRITE setWindowTitle)
+
+public:
+ enum SurfaceType { RasterSurface, OpenGLSurface };
+
+ QWindow(QScreen *screen = 0);
+ QWindow(QWindow *parent);
+ virtual ~QWindow();
+
+ void setSurfaceType(SurfaceType surfaceType);
+ SurfaceType surfaceType() const;
+
+ void setVisible(bool visible);
+ bool visible() const;
+
+ void create();
+
+ WId winId() const;
+
+ QWindow *parent() const;
+ void setParent(QWindow *parent);
+
+ bool isTopLevel() const;
+
+ bool isModal() const;
+ Qt::WindowModality windowModality() const;
+ void setWindowModality(Qt::WindowModality windowModality);
+
+ void setFormat(const QSurfaceFormat &format);
+ QSurfaceFormat format() const;
+
+ void setWindowFlags(Qt::WindowFlags flags);
+ Qt::WindowFlags windowFlags() const;
+ Qt::WindowType windowType() const;
+
+ QString windowTitle() const;
+
+ void setOpacity(qreal level);
+ void requestActivateWindow();
+
+ Qt::WindowState windowState() const;
+ void setWindowState(Qt::WindowState state);
+
+ void setTransientParent(QWindow *parent);
+ QWindow *transientParent() const;
+
+ QSize minimumSize() const;
+ QSize maximumSize() const;
+ QSize baseSize() const;
+ QSize sizeIncrement() const;
+
+ void setMinimumSize(const QSize &size);
+ void setMaximumSize(const QSize &size);
+ void setBaseSize(const QSize &size);
+ void setSizeIncrement(const QSize &size);
+
+ void setGeometry(int x, int y, int w, int h) { setGeometry(QRect(x, y, w, h)); }
+ void setGeometry(const QRect &rect);
+ QRect geometry() const;
+
+ inline int width() const { return geometry().width(); }
+ inline int height() const { return geometry().height(); }
+ inline int x() const { return geometry().x(); }
+ inline int y() const { return geometry().y(); }
+
+ inline QSize size() const { return geometry().size(); }
+ inline QPoint pos() const { return geometry().topLeft(); }
+
+ inline void move(const QPoint &pt) { setGeometry(QRect(pt, size())); }
+ inline void move(int x, int y) { move(QPoint(x, y)); }
+
+ inline void resize(const QSize &size) { setGeometry(QRect(pos(), size)); }
+ inline void resize(int w, int h) { setGeometry(QRect(x(), y(), w, h)); }
+
+ QMargins frameMargins() const;
+
+ void setWindowIcon(const QImage &icon) const;
+
+ void destroy();
+
+ QPlatformWindow *handle() const;
+
+ bool setKeyboardGrabEnabled(bool grab);
+ bool setMouseGrabEnabled(bool grab);
+
+ QScreen *screen() const;
+ void setScreen(QScreen *screen);
+
+ QPoint mapToGlobal(const QPoint &pos) const;
+ QPoint mapFromGlobal(const QPoint &pos) const;
+
+public Q_SLOTS:
+ inline void show() { setVisible(true); }
+ inline void hide() { setVisible(false); }
+
+ void showMinimized();
+ void showMaximized();
+ void showFullScreen();
+ void showNormal();
+
+ bool close();
+ void raise();
+ void lower();
+
+ void setWindowTitle(const QString &);
+
+Q_SIGNALS:
+ void backBufferReady();
+
+protected:
+ virtual void exposeEvent(QExposeEvent *);
+ virtual void resizeEvent(QResizeEvent *);
+
+ virtual void showEvent(QShowEvent *);
+ virtual void hideEvent(QHideEvent *);
+
+ virtual bool event(QEvent *);
+ virtual void keyPressEvent(QKeyEvent *);
+ virtual void keyReleaseEvent(QKeyEvent *);
+ virtual void inputMethodEvent(QInputMethodEvent *);
+ virtual void mousePressEvent(QMouseEvent *);
+ virtual void mouseReleaseEvent(QMouseEvent *);
+ virtual void mouseDoubleClickEvent(QMouseEvent *);
+ virtual void mouseMoveEvent(QMouseEvent *);
+#ifndef QT_NO_WHEELEVENT
+ virtual void wheelEvent(QWheelEvent *);
+#endif
+
+ QWindow(QWindowPrivate &dd, QWindow *parent);
+
+private:
+ QPlatformSurface *surfaceHandle() const;
+
+ Q_DISABLE_COPY(QWindow)
+
+ friend class QGuiApplication;
+ friend class QGuiApplicationPrivate;
+ friend Q_GUI_EXPORT QWindowPrivate *qt_window_private(QWindow *window);
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QWINDOW_QPA_H
diff --git a/src/gui/kernel/qwindow_p.h b/src/gui/kernel/qwindow_p.h
new file mode 100644
index 0000000000..38b90fdd73
--- /dev/null
+++ b/src/gui/kernel/qwindow_p.h
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOW_QPA_P_H
+#define QWINDOW_QPA_P_H
+
+#include <QtGui/qwindow.h>
+
+#include <QtCore/private/qobject_p.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#define QWINDOWSIZE_MAX ((1<<24)-1)
+
+class Q_GUI_EXPORT QWindowPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QWindow)
+
+public:
+ QWindowPrivate()
+ : QObjectPrivate()
+ , surfaceType(QWindow::RasterSurface)
+ , windowFlags(Qt::Window)
+ , parentWindow(0)
+ , platformWindow(0)
+ , visible(false)
+ , windowState(Qt::WindowNoState)
+ , maximumSize(QWINDOWSIZE_MAX, QWINDOWSIZE_MAX)
+ , modality(Qt::NonModal)
+ , transientParent(0)
+ , screen(0)
+ {
+ isWindow = true;
+ }
+
+ ~QWindowPrivate()
+ {
+ }
+
+ void maybeQuitOnLastWindowClosed();
+
+ QPoint globalPosition() const {
+ Q_Q(const QWindow);
+ QPoint offset = q->pos();
+ for (const QWindow *p = q->parent(); p; p = p->parent())
+ offset += p->pos();
+ return offset;
+ }
+
+
+ QWindow::SurfaceType surfaceType;
+ Qt::WindowFlags windowFlags;
+ QWindow *parentWindow;
+ QPlatformWindow *platformWindow;
+ bool visible;
+ QSurfaceFormat requestedFormat;
+ QString windowTitle;
+ QRect geometry;
+ Qt::WindowState windowState;
+
+ QSize minimumSize;
+ QSize maximumSize;
+ QSize baseSize;
+ QSize sizeIncrement;
+
+ Qt::WindowModality modality;
+ QPointer<QWindow> transientParent;
+ QScreen *screen;
+};
+
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QWINDOW_QPA_P_H
diff --git a/src/gui/kernel/qwindowdefs.h b/src/gui/kernel/qwindowdefs.h
index 6b24ddeb1a..165b62da8f 100644
--- a/src/gui/kernel/qwindowdefs.h
+++ b/src/gui/kernel/qwindowdefs.h
@@ -54,12 +54,10 @@ QT_MODULE(Gui)
class QPaintDevice;
class QWidget;
+class QWindow;
class QDialog;
class QColor;
class QPalette;
-#ifdef QT3_SUPPORT
-class QColorGroup;
-#endif
class QCursor;
class QPoint;
class QSize;
@@ -78,7 +76,6 @@ class QBitmap;
class QMovie;
class QImage;
class QPicture;
-class QPrinter;
class QTimer;
class QTime;
class QClipboard;
@@ -88,6 +85,7 @@ class QApplication;
template<typename T> class QList;
typedef QList<QWidget *> QWidgetList;
+typedef QList<QWindow *> QWindowList;
QT_END_NAMESPACE
QT_END_HEADER
@@ -106,9 +104,9 @@ typedef long WId;
#endif // Q_WS_MAC
-#if defined(Q_WS_WIN)
-#include <QtGui/qwindowdefs_win.h>
-#endif // Q_WS_WIN
+#if defined(Q_OS_WIN)
+# include <QtGui/qwindowdefs_win.h>
+#endif // Q_OS_WIN
#if defined(Q_WS_X11)
diff --git a/src/gui/kernel/qwindowdefs_win.h b/src/gui/kernel/qwindowdefs_win.h
index 396853e609..2bf9c8e672 100644
--- a/src/gui/kernel/qwindowdefs_win.h
+++ b/src/gui/kernel/qwindowdefs_win.h
@@ -115,15 +115,13 @@ typedef long HRESULT;
#endif
typedef struct tagMSG MSG;
-typedef HWND WId;
-
QT_BEGIN_NAMESPACE
Q_CORE_EXPORT HINSTANCE qWinAppInst();
Q_CORE_EXPORT HINSTANCE qWinAppPrevInst();
Q_CORE_EXPORT int qWinAppCmdShow();
-Q_GUI_EXPORT HDC qt_win_display_dc();
+Q_WIDGETS_EXPORT HDC qt_win_display_dc();
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qwindowsysteminterface_qpa.cpp b/src/gui/kernel/qwindowsysteminterface_qpa.cpp
index 5ae30148d3..d862d05baa 100644
--- a/src/gui/kernel/qwindowsysteminterface_qpa.cpp
+++ b/src/gui/kernel/qwindowsysteminterface_qpa.cpp
@@ -40,8 +40,9 @@
****************************************************************************/
#include "qwindowsysteminterface_qpa.h"
#include "qwindowsysteminterface_qpa_p.h"
-#include "qapplication_p.h"
+#include "private/qguiapplication_p.h"
#include <QAbstractEventDispatcher>
+#include <qdebug.h>
QT_BEGIN_NAMESPACE
@@ -56,51 +57,49 @@ QTime QWindowSystemInterfacePrivate::eventTime;
QList<QWindowSystemInterfacePrivate::WindowSystemEvent *> QWindowSystemInterfacePrivate::windowSystemEventQueue;
QMutex QWindowSystemInterfacePrivate::queueMutex;
-extern QPointer<QWidget> qt_last_mouse_receiver;
+extern QPointer<QWindow> qt_last_mouse_receiver;
-void QWindowSystemInterface::handleEnterEvent(QWidget *tlw)
+void QWindowSystemInterface::handleEnterEvent(QWindow *tlw)
{
if (tlw) {
- QWidgetData *data = qt_qwidget_data(tlw);
- if (data->in_destructor)
- return;
-
QWindowSystemInterfacePrivate::EnterEvent *e = new QWindowSystemInterfacePrivate::EnterEvent(tlw);
QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
}
}
-void QWindowSystemInterface::handleLeaveEvent(QWidget *tlw)
+void QWindowSystemInterface::handleLeaveEvent(QWindow *tlw)
{
- if (tlw) {
- QWidgetData *data = qt_qwidget_data(tlw);
- if (data->in_destructor)
- return;
- }
QWindowSystemInterfacePrivate::LeaveEvent *e = new QWindowSystemInterfacePrivate::LeaveEvent(tlw);
QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
}
-void QWindowSystemInterface::handleWindowActivated(QWidget *tlw)
+void QWindowSystemInterface::handleWindowActivated(QWindow *tlw)
{
QWindowSystemInterfacePrivate::ActivatedWindowEvent *e = new QWindowSystemInterfacePrivate::ActivatedWindowEvent(tlw);
QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
}
-void QWindowSystemInterface::handleGeometryChange(QWidget *tlw, const QRect &newRect)
+void QWindowSystemInterface::handleWindowStateChanged(QWindow *tlw, Qt::WindowState newState)
+{
+ QWindowSystemInterfacePrivate::WindowStateChangedEvent *e =
+ new QWindowSystemInterfacePrivate::WindowStateChangedEvent(tlw, newState);
+ QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
+}
+
+void QWindowSystemInterface::handleGeometryChange(QWindow *tlw, const QRect &newRect)
{
- if (tlw) {
- QWidgetData *data = qt_qwidget_data(tlw);
- if (data->in_destructor)
- return;
- }
QWindowSystemInterfacePrivate::GeometryChangeEvent *e = new QWindowSystemInterfacePrivate::GeometryChangeEvent(tlw,newRect);
QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
}
+void QWindowSystemInterface::handleSynchronousGeometryChange(QWindow *tlw, const QRect &newRect)
+{
+ QWindowSystemInterfacePrivate::GeometryChangeEvent *e = new QWindowSystemInterfacePrivate::GeometryChangeEvent(tlw,newRect);
+ QGuiApplicationPrivate::processWindowSystemEvent(e); // send event immediately.
+}
-void QWindowSystemInterface::handleCloseEvent(QWidget *tlw)
+void QWindowSystemInterface::handleCloseEvent(QWindow *tlw)
{
if (tlw) {
QWindowSystemInterfacePrivate::CloseEvent *e =
@@ -115,42 +114,31 @@ void QWindowSystemInterface::handleCloseEvent(QWidget *tlw)
*/
-void QWindowSystemInterface::handleMouseEvent(QWidget *w, const QPointF & local, const QPointF & global, Qt::MouseButtons b) {
+void QWindowSystemInterface::handleMouseEvent(QWindow *w, const QPointF & local, const QPointF & global, Qt::MouseButtons b) {
unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed();
handleMouseEvent(w, time, local, global, b);
}
-void QWindowSystemInterface::handleMouseEvent(QWidget *tlw, ulong timestamp, const QPointF & local, const QPointF & global, Qt::MouseButtons b)
+void QWindowSystemInterface::handleMouseEvent(QWindow *tlw, ulong timestamp, const QPointF & local, const QPointF & global, Qt::MouseButtons b)
{
- if (tlw) {
- QWidgetData *data = qt_qwidget_data(tlw);
- if (data->in_destructor)
- tlw = 0;
- }
QWindowSystemInterfacePrivate::MouseEvent * e =
new QWindowSystemInterfacePrivate::MouseEvent(tlw, timestamp, local, global, b);
QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
}
-void QWindowSystemInterface::handleKeyEvent(QWidget *w, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text, bool autorep, ushort count) {
+void QWindowSystemInterface::handleKeyEvent(QWindow *w, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text, bool autorep, ushort count) {
unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed();
handleKeyEvent(w, time, t, k, mods, text, autorep, count);
}
-void QWindowSystemInterface::handleKeyEvent(QWidget *tlw, ulong timestamp, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text, bool autorep, ushort count)
+void QWindowSystemInterface::handleKeyEvent(QWindow *tlw, ulong timestamp, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text, bool autorep, ushort count)
{
- if (tlw) {
- QWidgetData *data = qt_qwidget_data(tlw);
- if (data->in_destructor)
- tlw = 0;
- }
-
QWindowSystemInterfacePrivate::KeyEvent * e =
new QWindowSystemInterfacePrivate::KeyEvent(tlw, timestamp, t, k, mods, text, autorep, count);
QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
}
-void QWindowSystemInterface::handleExtendedKeyEvent(QWidget *w, QEvent::Type type, int key, Qt::KeyboardModifiers modifiers,
+void QWindowSystemInterface::handleExtendedKeyEvent(QWindow *w, QEvent::Type type, int key, Qt::KeyboardModifiers modifiers,
quint32 nativeScanCode, quint32 nativeVirtualKey,
quint32 nativeModifiers,
const QString& text, bool autorep,
@@ -161,38 +149,26 @@ void QWindowSystemInterface::handleExtendedKeyEvent(QWidget *w, QEvent::Type typ
text, autorep, count);
}
-void QWindowSystemInterface::handleExtendedKeyEvent(QWidget *tlw, ulong timestamp, QEvent::Type type, int key,
+void QWindowSystemInterface::handleExtendedKeyEvent(QWindow *tlw, ulong timestamp, QEvent::Type type, int key,
Qt::KeyboardModifiers modifiers,
quint32 nativeScanCode, quint32 nativeVirtualKey,
quint32 nativeModifiers,
const QString& text, bool autorep,
ushort count)
{
- if (tlw) {
- QWidgetData *data = qt_qwidget_data(tlw);
- if (data->in_destructor)
- tlw = 0;
- }
-
QWindowSystemInterfacePrivate::KeyEvent * e =
new QWindowSystemInterfacePrivate::KeyEvent(tlw, timestamp, type, key, modifiers,
nativeScanCode, nativeVirtualKey, nativeModifiers, text, autorep, count);
QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
}
-void QWindowSystemInterface::handleWheelEvent(QWidget *w, const QPointF & local, const QPointF & global, int d, Qt::Orientation o) {
+void QWindowSystemInterface::handleWheelEvent(QWindow *w, const QPointF & local, const QPointF & global, int d, Qt::Orientation o) {
unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed();
handleWheelEvent(w, time, local, global, d, o);
}
-void QWindowSystemInterface::handleWheelEvent(QWidget *tlw, ulong timestamp, const QPointF & local, const QPointF & global, int d, Qt::Orientation o)
+void QWindowSystemInterface::handleWheelEvent(QWindow *tlw, ulong timestamp, const QPointF & local, const QPointF & global, int d, Qt::Orientation o)
{
- if (tlw) {
- QWidgetData *data = qt_qwidget_data(tlw);
- if (data->in_destructor)
- tlw = 0;
- }
-
QWindowSystemInterfacePrivate::WheelEvent *e =
new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, local, global, d, o);
QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
@@ -224,17 +200,17 @@ void QWindowSystemInterfacePrivate::queueWindowSystemEvent(QWindowSystemInterfac
windowSystemEventQueue.append(ev);
queueMutex.unlock();
- QAbstractEventDispatcher *dispatcher = QApplicationPrivate::qt_qpa_core_dispatcher();
+ QAbstractEventDispatcher *dispatcher = QGuiApplicationPrivate::qt_qpa_core_dispatcher();
if (dispatcher)
dispatcher->wakeUp();
}
-void QWindowSystemInterface::handleTouchEvent(QWidget *w, QEvent::Type type, QTouchEvent::DeviceType devType, const QList<struct TouchPoint> &points) {
+void QWindowSystemInterface::handleTouchEvent(QWindow *w, QEvent::Type type, QTouchEvent::DeviceType devType, const QList<struct TouchPoint> &points) {
unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed();
handleTouchEvent(w, time, type, devType, points);
}
-void QWindowSystemInterface::handleTouchEvent(QWidget *tlw, ulong timestamp, QEvent::Type type, QTouchEvent::DeviceType devType, const QList<struct TouchPoint> &points)
+void QWindowSystemInterface::handleTouchEvent(QWindow *tlw, ulong timestamp, QEvent::Type type, QTouchEvent::DeviceType devType, const QList<struct TouchPoint> &points)
{
if (!points.size()) // Touch events must have at least one point
return;
@@ -288,4 +264,70 @@ void QWindowSystemInterface::handleScreenCountChange(int count)
QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
}
+void QWindowSystemInterface::handleMapEvent(QWindow *tlw)
+{
+ QWindowSystemInterfacePrivate::MapEvent *e = new QWindowSystemInterfacePrivate::MapEvent(tlw);
+ QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
+}
+
+void QWindowSystemInterface::handleUnmapEvent(QWindow *tlw)
+{
+ QWindowSystemInterfacePrivate::UnmapEvent *e = new QWindowSystemInterfacePrivate::UnmapEvent(tlw);
+ QWindowSystemInterfacePrivate::queueWindowSystemEvent(e);
+}
+
+void QWindowSystemInterface::handleSynchronousExposeEvent(QWindow *tlw, const QRegion &region)
+{
+ QWindowSystemInterfacePrivate::ExposeEvent *e = new QWindowSystemInterfacePrivate::ExposeEvent(tlw, region);
+ QGuiApplicationPrivate::processWindowSystemEvent(e); // send event immediately.
+}
+
+bool QWindowSystemInterface::sendWindowSystemEvents(QAbstractEventDispatcher *eventDispatcher, QEventLoop::ProcessEventsFlags flags)
+{
+ int nevents = 0;
+
+ // handle gui and posted events
+ QCoreApplication::sendPostedEvents();
+
+ while (true) {
+ QWindowSystemInterfacePrivate::WindowSystemEvent *event;
+ if (!(flags & QEventLoop::ExcludeUserInputEvents)
+ && QWindowSystemInterfacePrivate::windowSystemEventsQueued() > 0) {
+ // process a pending user input event
+ event = QWindowSystemInterfacePrivate::getWindowSystemEvent();
+ if (!event)
+ break;
+ } else {
+ break;
+ }
+
+ if (eventDispatcher->filterEvent(event)) {
+ delete event;
+ continue;
+ }
+
+ nevents++;
+
+ QGuiApplicationPrivate::processWindowSystemEvent(event);
+ delete event;
+ }
+
+ return (nevents > 0);
+}
+
+int QWindowSystemInterface::windowSystemEventsQueued()
+{
+ return QWindowSystemInterfacePrivate::windowSystemEventsQueued();
+}
+
+Qt::DropAction QWindowSystemInterface::handleDrag(QWindow *w, QMimeData *dropData, const QPoint &p)
+{
+ return QGuiApplicationPrivate::processDrag(w, dropData, p);
+}
+
+Qt::DropAction QWindowSystemInterface::handleDrop(QWindow *w, QMimeData *dropData, const QPoint &p)
+{
+ return QGuiApplicationPrivate::processDrop(w, dropData, p);
+}
+
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qwindowsysteminterface_qpa.h b/src/gui/kernel/qwindowsysteminterface_qpa.h
index 5a811b90c1..99db5f2b17 100644
--- a/src/gui/kernel/qwindowsysteminterface_qpa.h
+++ b/src/gui/kernel/qwindowsysteminterface_qpa.h
@@ -44,39 +44,43 @@
#include <QtCore/QTime>
#include <QtGui/qwindowdefs.h>
#include <QtCore/QEvent>
-#include <QtGui/QWidget>
+#include <QtCore/QAbstractEventDispatcher>
+#include <QtGui/QWindow>
#include <QtCore/QWeakPointer>
#include <QtCore/QMutex>
#include <QtGui/QTouchEvent>
+#include <QtCore/QEventLoop>
QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
+class QMimeData;
+
QT_MODULE(Gui)
class Q_GUI_EXPORT QWindowSystemInterface
{
public:
- static void handleMouseEvent(QWidget *w, const QPointF & local, const QPointF & global, Qt::MouseButtons b);
- static void handleMouseEvent(QWidget *w, ulong timestamp, const QPointF & local, const QPointF & global, Qt::MouseButtons b);
+ static void handleMouseEvent(QWindow *w, const QPointF & local, const QPointF & global, Qt::MouseButtons b);
+ static void handleMouseEvent(QWindow *w, ulong timestamp, const QPointF & local, const QPointF & global, Qt::MouseButtons b);
- static void handleKeyEvent(QWidget *w, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text = QString(), bool autorep = false, ushort count = 1);
- static void handleKeyEvent(QWidget *w, ulong timestamp, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text = QString(), bool autorep = false, ushort count = 1);
+ static void handleKeyEvent(QWindow *w, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text = QString(), bool autorep = false, ushort count = 1);
+ static void handleKeyEvent(QWindow *w, ulong timestamp, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text = QString(), bool autorep = false, ushort count = 1);
- static void handleExtendedKeyEvent(QWidget *w, QEvent::Type type, int key, Qt::KeyboardModifiers modifiers,
+ static void handleExtendedKeyEvent(QWindow *w, QEvent::Type type, int key, Qt::KeyboardModifiers modifiers,
quint32 nativeScanCode, quint32 nativeVirtualKey,
quint32 nativeModifiers,
const QString& text = QString(), bool autorep = false,
ushort count = 1);
- static void handleExtendedKeyEvent(QWidget *w, ulong timestamp, QEvent::Type type, int key, Qt::KeyboardModifiers modifiers,
+ static void handleExtendedKeyEvent(QWindow *w, ulong timestamp, QEvent::Type type, int key, Qt::KeyboardModifiers modifiers,
quint32 nativeScanCode, quint32 nativeVirtualKey,
quint32 nativeModifiers,
const QString& text = QString(), bool autorep = false,
ushort count = 1);
- static void handleWheelEvent(QWidget *w, const QPointF & local, const QPointF & global, int d, Qt::Orientation o);
- static void handleWheelEvent(QWidget *w, ulong timestamp, const QPointF & local, const QPointF & global, int d, Qt::Orientation o);
+ static void handleWheelEvent(QWindow *w, const QPointF & local, const QPointF & global, int d, Qt::Orientation o);
+ static void handleWheelEvent(QWindow *w, ulong timestamp, const QPointF & local, const QPointF & global, int d, Qt::Orientation o);
struct TouchPoint {
int id; // for application use
@@ -87,19 +91,34 @@ public:
Qt::TouchPointState state; //Qt::TouchPoint{Pressed|Moved|Stationary|Released}
};
- static void handleTouchEvent(QWidget *w, QEvent::Type type, QTouchEvent::DeviceType devType, const QList<struct TouchPoint> &points);
- static void handleTouchEvent(QWidget *w, ulong timestamp, QEvent::Type type, QTouchEvent::DeviceType devType, const QList<struct TouchPoint> &points);
+ static void handleTouchEvent(QWindow *w, QEvent::Type type, QTouchEvent::DeviceType devType, const QList<struct TouchPoint> &points);
+ static void handleTouchEvent(QWindow *w, ulong timestamp, QEvent::Type type, QTouchEvent::DeviceType devType, const QList<struct TouchPoint> &points);
+
+ static void handleGeometryChange(QWindow *w, const QRect &newRect);
+ static void handleSynchronousGeometryChange(QWindow *w, const QRect &newRect);
+ static void handleCloseEvent(QWindow *w);
+ static void handleEnterEvent(QWindow *w);
+ static void handleLeaveEvent(QWindow *w);
+ static void handleWindowActivated(QWindow *w);
+ static void handleWindowStateChanged(QWindow *w, Qt::WindowState newState);
+
+ static void handleMapEvent(QWindow *w);
+ static void handleUnmapEvent(QWindow *w);
- static void handleGeometryChange(QWidget *w, const QRect &newRect);
- static void handleCloseEvent(QWidget *w);
- static void handleEnterEvent(QWidget *w);
- static void handleLeaveEvent(QWidget *w);
- static void handleWindowActivated(QWidget *w);
+ static void handleSynchronousExposeEvent(QWindow *tlw, const QRegion &region);
+
+ // Drag and drop. These events are sent immediately.
+ static Qt::DropAction handleDrag(QWindow *w, QMimeData *dropData, const QPoint &p);
+ static Qt::DropAction handleDrop(QWindow *w, QMimeData *dropData, const QPoint &p);
// Changes to the screen
static void handleScreenGeometryChange(int screenIndex);
static void handleScreenAvailableGeometryChange(int screenIndex);
static void handleScreenCountChange(int count);
+
+ // For event dispatcher implementations
+ static bool sendWindowSystemEvents(QAbstractEventDispatcher *eventDispatcher, QEventLoop::ProcessEventsFlags flags);
+ static int windowSystemEventsQueued();
};
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qwindowsysteminterface_qpa_p.h b/src/gui/kernel/qwindowsysteminterface_qpa_p.h
index 385175cc60..352092d066 100644
--- a/src/gui/kernel/qwindowsysteminterface_qpa_p.h
+++ b/src/gui/kernel/qwindowsysteminterface_qpa_p.h
@@ -55,73 +55,87 @@ public:
Enter,
Leave,
ActivatedWindow,
+ WindowStateChanged,
Mouse,
Wheel,
Key,
Touch,
ScreenGeometry,
ScreenAvailableGeometry,
- ScreenCountChange
+ ScreenCountChange,
+ Map,
+ Unmap,
+ Expose
};
class WindowSystemEvent {
public:
- WindowSystemEvent(EventType t)
+ explicit WindowSystemEvent(EventType t)
: type(t) { }
EventType type;
};
class CloseEvent : public WindowSystemEvent {
public:
- CloseEvent(QWidget *tlw)
- : WindowSystemEvent(Close), topLevel(tlw) { }
- QWeakPointer<QWidget> topLevel;
+ explicit CloseEvent(QWindow *w)
+ : WindowSystemEvent(Close), window(w) { }
+ QWeakPointer<QWindow> window;
};
class GeometryChangeEvent : public WindowSystemEvent {
public:
- GeometryChangeEvent(QWidget *tlw, const QRect &newGeometry)
+ GeometryChangeEvent(QWindow *tlw, const QRect &newGeometry)
: WindowSystemEvent(GeometryChange), tlw(tlw), newGeometry(newGeometry)
{ }
- QWeakPointer<QWidget> tlw;
+ QWeakPointer<QWindow> tlw;
QRect newGeometry;
};
class EnterEvent : public WindowSystemEvent {
public:
- EnterEvent(QWidget *enter)
+ explicit EnterEvent(QWindow *enter)
: WindowSystemEvent(Enter), enter(enter)
{ }
- QWeakPointer<QWidget> enter;
+ QWeakPointer<QWindow> enter;
};
class LeaveEvent : public WindowSystemEvent {
public:
- LeaveEvent(QWidget *leave)
+ explicit LeaveEvent(QWindow *leave)
: WindowSystemEvent(Leave), leave(leave)
{ }
- QWeakPointer<QWidget> leave;
+ QWeakPointer<QWindow> leave;
};
class ActivatedWindowEvent : public WindowSystemEvent {
public:
- ActivatedWindowEvent(QWidget *activatedWindow)
+ explicit ActivatedWindowEvent(QWindow *activatedWindow)
: WindowSystemEvent(ActivatedWindow), activated(activatedWindow)
{ }
- QWeakPointer<QWidget> activated;
+ QWeakPointer<QWindow> activated;
+ };
+
+ class WindowStateChangedEvent : public WindowSystemEvent {
+ public:
+ WindowStateChangedEvent(QWindow *_window, Qt::WindowState _newState)
+ : WindowSystemEvent(WindowStateChanged), window(_window), newState(_newState)
+ { }
+
+ QWeakPointer<QWindow> window;
+ Qt::WindowState newState;
};
class UserEvent : public WindowSystemEvent {
public:
- UserEvent(QWidget * w, ulong time, EventType t)
- : WindowSystemEvent(t), widget(w), timestamp(time) { }
- QWeakPointer<QWidget> widget;
+ UserEvent(QWindow * w, ulong time, EventType t)
+ : WindowSystemEvent(t), window(w), timestamp(time) { }
+ QWeakPointer<QWindow> window;
unsigned long timestamp;
};
class MouseEvent : public UserEvent {
public:
- MouseEvent(QWidget * w, ulong time, const QPointF & local, const QPointF & global, Qt::MouseButtons b)
+ MouseEvent(QWindow * w, ulong time, const QPointF & local, const QPointF & global, Qt::MouseButtons b)
: UserEvent(w, time, Mouse), localPos(local), globalPos(global), buttons(b) { }
QPointF localPos;
QPointF globalPos;
@@ -130,7 +144,7 @@ public:
class WheelEvent : public UserEvent {
public:
- WheelEvent(QWidget *w, ulong time, const QPointF & local, const QPointF & global, int d, Qt::Orientation o)
+ WheelEvent(QWindow *w, ulong time, const QPointF & local, const QPointF & global, int d, Qt::Orientation o)
: UserEvent(w, time, Wheel), delta(d), localPos(local), globalPos(global), orient(o) { }
int delta;
QPointF localPos;
@@ -140,11 +154,11 @@ public:
class KeyEvent : public UserEvent {
public:
- KeyEvent(QWidget *w, ulong time, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text = QString(), bool autorep = false, ushort count = 1)
+ KeyEvent(QWindow *w, ulong time, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text = QString(), bool autorep = false, ushort count = 1)
:UserEvent(w, time, Key), key(k), unicode(text), repeat(autorep),
repeatCount(count), modifiers(mods), keyType(t),
nativeScanCode(0), nativeVirtualKey(0), nativeModifiers(0) { }
- KeyEvent(QWidget *w, ulong time, QEvent::Type t, int k, Qt::KeyboardModifiers mods,
+ KeyEvent(QWindow *w, ulong time, QEvent::Type t, int k, Qt::KeyboardModifiers mods,
quint32 nativeSC, quint32 nativeVK, quint32 nativeMods,
const QString & text = QString(), bool autorep = false, ushort count = 1)
:UserEvent(w, time, Key), key(k), unicode(text), repeat(autorep),
@@ -163,7 +177,7 @@ public:
class TouchEvent : public UserEvent {
public:
- TouchEvent(QWidget *w, ulong time, QEvent::Type t, QTouchEvent::DeviceType d, const QList<QTouchEvent::TouchPoint> &p)
+ TouchEvent(QWindow *w, ulong time, QEvent::Type t, QTouchEvent::DeviceType d, const QList<QTouchEvent::TouchPoint> &p)
:UserEvent(w, time, Touch), devType(d), points(p), touchType(t) { }
QTouchEvent::DeviceType devType;
QList<QTouchEvent::TouchPoint> points;
@@ -192,6 +206,31 @@ public:
int index;
};
+ class MapEvent : public WindowSystemEvent {
+ public:
+ MapEvent(QWindow *mapped)
+ : WindowSystemEvent(Map), mapped(mapped)
+ { }
+ QWeakPointer<QWindow> mapped;
+ };
+
+ class UnmapEvent : public WindowSystemEvent {
+ public:
+ UnmapEvent(QWindow *unmapped)
+ : WindowSystemEvent(Unmap), unmapped(unmapped)
+ { }
+ QWeakPointer<QWindow> unmapped;
+ };
+
+ class ExposeEvent : public WindowSystemEvent {
+ public:
+ ExposeEvent(QWindow *exposed, const QRegion &region)
+ : WindowSystemEvent(Expose), exposed(exposed), region(region)
+ { }
+ QWeakPointer<QWindow> exposed;
+ QRegion region;
+ };
+
static QList<WindowSystemEvent *> windowSystemEventQueue;
static QMutex queueMutex;
diff --git a/src/gui/kernel/qx11embed_x11.h b/src/gui/kernel/qx11embed_x11.h
deleted file mode 100644
index ada7a29ed3..0000000000
--- a/src/gui/kernel/qx11embed_x11.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QX11EMBED_X11_H
-#define QX11EMBED_X11_H
-
-#include <QtGui/qwidget.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QX11EmbedWidgetPrivate;
-class Q_GUI_EXPORT QX11EmbedWidget : public QWidget
-{
- Q_OBJECT
-public:
- QX11EmbedWidget(QWidget *parent = 0);
- ~QX11EmbedWidget();
-
- void embedInto(WId id);
- WId containerWinId() const;
-
- enum Error {
- Unknown,
- Internal,
- InvalidWindowID
- };
- Error error() const;
-
-Q_SIGNALS:
- void embedded();
- void containerClosed();
- void error(QX11EmbedWidget::Error error);
-
-protected:
- bool x11Event(XEvent *);
- bool eventFilter(QObject *, QEvent *);
- bool event(QEvent *);
- void resizeEvent(QResizeEvent *);
-
-private:
- Q_DECLARE_PRIVATE(QX11EmbedWidget)
- Q_DISABLE_COPY(QX11EmbedWidget)
-};
-
-class QX11EmbedContainerPrivate;
-class Q_GUI_EXPORT QX11EmbedContainer : public QWidget
-{
- Q_OBJECT
-public:
- QX11EmbedContainer(QWidget *parent = 0);
- ~QX11EmbedContainer();
-
- void embedClient(WId id);
- void discardClient();
-
- WId clientWinId() const;
-
- QSize minimumSizeHint() const;
-
- enum Error {
- Unknown,
- Internal,
- InvalidWindowID
- };
- Error error() const;
-
-Q_SIGNALS:
- void clientIsEmbedded();
- void clientClosed();
- void error(QX11EmbedContainer::Error);
-
-protected:
- bool x11Event(XEvent *);
- bool eventFilter(QObject *, QEvent *);
- void paintEvent(QPaintEvent *e);
- void resizeEvent(QResizeEvent *);
- void showEvent(QShowEvent *);
- void hideEvent(QHideEvent *);
- bool event(QEvent *);
-
-private:
- Q_DECLARE_PRIVATE(QX11EmbedContainer)
- Q_DISABLE_COPY(QX11EmbedContainer)
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QX11EMBED_X11_H
diff --git a/src/gui/kernel/qx11info_x11.h b/src/gui/kernel/qx11info_x11.h
deleted file mode 100644
index 2d81c6be76..0000000000
--- a/src/gui/kernel/qx11info_x11.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QX11INFO_X11_H
-#define QX11INFO_X11_H
-
-#include <QtCore/qnamespace.h>
-
-typedef struct _XDisplay Display;
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-struct QX11InfoData;
-class QX11Info;
-class QPaintDevice;
-class QApplicationPrivate;
-class QX11InfoPrivate;
-struct QX11WindowAttributes;
-
-void qt_x11_getX11InfoForWindow(QX11Info * xinfo, const QX11WindowAttributes &a);
-class Q_GUI_EXPORT QX11Info
-{
-public:
- QX11Info();
- ~QX11Info();
- QX11Info(const QX11Info &other);
- QX11Info &operator=(const QX11Info &other);
-
- static Display *display();
- static const char *appClass();
- int screen() const;
- int depth() const;
- int cells() const;
- Qt::HANDLE colormap() const;
- bool defaultColormap() const;
- void *visual() const;
- bool defaultVisual() const;
-
- static int appScreen();
- static int appDepth(int screen = -1);
- static int appCells(int screen = -1);
- static Qt::HANDLE appColormap(int screen = -1);
- static void *appVisual(int screen = -1);
- static Qt::HANDLE appRootWindow(int screen = -1);
- static bool appDefaultColormap(int screen = -1);
- static bool appDefaultVisual(int screen = -1);
- static int appDpiX(int screen = -1);
- static int appDpiY(int screen = -1);
- static void setAppDpiX(int screen, int dpi);
- static void setAppDpiY(int screen, int dpi);
- static unsigned long appTime();
- static unsigned long appUserTime();
- static void setAppTime(unsigned long time);
- static void setAppUserTime(unsigned long time);
- static bool isCompositingManagerRunning();
-
-protected:
- void copyX11Data(const QPaintDevice *);
- void cloneX11Data(const QPaintDevice *);
- void setX11Data(const QX11InfoData *);
- QX11InfoData* getX11Data(bool def = false) const;
-
- QX11InfoData *x11data;
-
- friend class QX11PaintEngine;
- friend class QPixmap;
- friend class QX11PixmapData;
- friend class QWidget;
- friend class QWidgetPrivate;
- friend class QGLWidget;
- friend void qt_init(QApplicationPrivate *priv, int, Display *display, Qt::HANDLE visual,
- Qt::HANDLE colormap);
- friend void qt_cleanup();
- friend void qt_x11_getX11InfoForWindow(QX11Info * xinfo, const QX11WindowAttributes &a);
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QX11INFO_X11_H
diff --git a/src/gui/mac/macresources.qrc b/src/gui/mac/macresources.qrc
deleted file mode 100644
index 9696002205..0000000000
--- a/src/gui/mac/macresources.qrc
+++ /dev/null
@@ -1,12 +0,0 @@
-<!DOCTYPE RCC><RCC version="1.0">
-<qresource prefix="/trolltech/mac/cursors">
-<file>images/copyarrowcursor.png</file>
-<file>images/forbiddencursor.png</file>
-<file>images/spincursor.png</file>
-<file>images/waitcursor.png</file>
-<file>images/pluscursor.png</file>
-</qresource>
-<qresource prefix="/trolltech/mac/style">
-<file>images/leopard-unified-toolbar-on.png</file>
-</qresource>
-</RCC>
diff --git a/src/gui/opengl/opengl.pri b/src/gui/opengl/opengl.pri
new file mode 100644
index 0000000000..4ee7af4569
--- /dev/null
+++ b/src/gui/opengl/opengl.pri
@@ -0,0 +1,48 @@
+# Qt gui library, opengl module
+
+contains(QT_CONFIG, opengl):CONFIG += opengl
+contains(QT_CONFIG, opengles2):CONFIG += opengles2
+contains(QT_CONFIG, egl):CONFIG += egl
+
+HEADERS += opengl/qopengl.h \
+ opengl/qopengl_p.h \
+ opengl/qopenglfunctions.h \
+ opengl/qopenglframebufferobject.h \
+ opengl/qopenglframebufferobject_p.h \
+ opengl/qopenglpaintdevice.h \
+ opengl/qopenglbuffer.h \
+ opengl/qopenglshaderprogram.h \
+ opengl/qopenglextensions_p.h \
+ opengl/qopenglgradientcache_p.h \
+ opengl/qopengltexturecache_p.h \
+ opengl/qopenglengineshadermanager_p.h \
+ opengl/qopengl2pexvertexarray_p.h \
+ opengl/qopenglpaintengine_p.h \
+ opengl/qopenglengineshadersource_p.h \
+ opengl/qopenglcustomshaderstage_p.h \
+ opengl/qopengltriangulatingstroker_p.h \
+ opengl/qopengltextureglyphcache_p.h \
+ opengl/qopenglshadercache_p.h \
+ opengl/qopenglshadercache_meego_p.h \
+ opengl/qopenglcolormap.h \
+ opengl/qtriangulator_p.h \
+ opengl/qrbtree_p.h
+
+SOURCES += opengl/qopengl.cpp \
+ opengl/qopenglfunctions.cpp \
+ opengl/qopenglframebufferobject.cpp \
+ opengl/qopenglpaintdevice.cpp \
+ opengl/qopenglbuffer.cpp \
+ opengl/qopenglshaderprogram.cpp \
+ opengl/qopenglgradientcache.cpp \
+ opengl/qopengltexturecache.cpp \
+ opengl/qopenglengineshadermanager.cpp \
+ opengl/qopengl2pexvertexarray.cpp \
+ opengl/qopenglpaintengine.cpp \
+ opengl/qopenglcustomshaderstage.cpp \
+ opengl/qopengltriangulatingstroker.cpp \
+ opengl/qopengltextureglyphcache.cpp \
+ opengl/qopenglcolormap.cpp \
+ opengl/qtriangulator.cpp
+
+#INCLUDEPATH += ../3rdparty/harfbuzz/src
diff --git a/src/gui/opengl/qopengl.cpp b/src/gui/opengl/qopengl.cpp
new file mode 100644
index 0000000000..3233fcfa5b
--- /dev/null
+++ b/src/gui/opengl/qopengl.cpp
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qopengl_p.h"
+
+#include "qopenglcontext.h"
+
+QT_BEGIN_NAMESPACE
+
+QOpenGLExtensionMatcher::QOpenGLExtensionMatcher(const char *str)
+{
+ init(str);
+}
+
+typedef GLubyte * (*qt_glGetStringi)(GLenum, GLuint);
+
+#ifndef GL_NUM_EXTENSIONS
+#define GL_NUM_EXTENSIONS 0x821D
+#endif
+
+QOpenGLExtensionMatcher::QOpenGLExtensionMatcher()
+{
+ const char *extensionStr = reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS));
+
+ if (extensionStr) {
+ init(extensionStr);
+ } else {
+ // clear error state
+ while (glGetError()) {}
+
+ QOpenGLContext *ctx = QOpenGLContext::currentContext();
+ if (ctx) {
+ qt_glGetStringi glGetStringi = (qt_glGetStringi)ctx->getProcAddress("glGetStringi");
+
+ if (!glGetStringi)
+ return;
+
+ GLint numExtensions;
+ glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions);
+
+ for (int i = 0; i < numExtensions; ++i) {
+ const char *str = reinterpret_cast<const char *>(glGetStringi(GL_EXTENSIONS, i));
+
+ m_offsets << m_extensions.size();
+
+ while (*str != 0)
+ m_extensions.append(*str++);
+ m_extensions.append(' ');
+ }
+ }
+ }
+}
+
+void QOpenGLExtensionMatcher::init(const char *str)
+{
+ m_extensions = str;
+
+ // make sure extension string ends with a space
+ if (!m_extensions.endsWith(' '))
+ m_extensions.append(' ');
+
+ int index = 0;
+ int next = 0;
+ while ((next = m_extensions.indexOf(' ', index)) >= 0) {
+ m_offsets << index;
+ index = next + 1;
+ }
+}
+
+
+QT_END_NAMESPACE
diff --git a/src/gui/opengl/qopengl.h b/src/gui/opengl/qopengl.h
new file mode 100644
index 0000000000..cef4277d6b
--- /dev/null
+++ b/src/gui/opengl/qopengl.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QOPENGL_H
+#define QOPENGL_H
+
+#include <qglobal.h>
+
+QT_BEGIN_HEADER
+
+#if 1
+#if defined(QT_OPENGL_ES_2)
+# if defined(Q_OS_MAC)
+# include <OpenGLES/ES2/gl.h>
+# else
+# include <GLES2/gl2.h>
+# endif
+# ifndef GL_DOUBLE
+# define GL_DOUBLE GL_FLOAT
+# endif
+# ifndef GLdouble
+typedef GLfloat GLdouble;
+# endif
+#else
+# if defined(Q_OS_MAC)
+# include <OpenGL/gl.h>
+# else
+# if defined(Q_OS_WIN)
+# include <QtCore/qt_windows.h>
+# endif
+# include <GL/gl.h>
+# endif
+#endif
+#endif
+
+QT_END_HEADER
+
+#endif // QOPENGL_H
diff --git a/src/gui/opengl/qopengl2pexvertexarray.cpp b/src/gui/opengl/qopengl2pexvertexarray.cpp
new file mode 100644
index 0000000000..ec26fdbf5b
--- /dev/null
+++ b/src/gui/opengl/qopengl2pexvertexarray.cpp
@@ -0,0 +1,175 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qopengl2pexvertexarray_p.h"
+
+#include <private/qbezier_p.h>
+
+QT_BEGIN_NAMESPACE
+
+void QOpenGL2PEXVertexArray::clear()
+{
+ vertexArray.reset();
+ vertexArrayStops.reset();
+ boundingRectDirty = true;
+}
+
+
+QOpenGLRect QOpenGL2PEXVertexArray::boundingRect() const
+{
+ if (boundingRectDirty)
+ return QOpenGLRect(0.0, 0.0, 0.0, 0.0);
+ else
+ return QOpenGLRect(minX, minY, maxX, maxY);
+}
+
+void QOpenGL2PEXVertexArray::addClosingLine(int index)
+{
+ QPointF point(vertexArray.at(index));
+ if (point != QPointF(vertexArray.last()))
+ vertexArray.add(point);
+}
+
+void QOpenGL2PEXVertexArray::addCentroid(const QVectorPath &path, int subPathIndex)
+{
+ const QPointF *const points = reinterpret_cast<const QPointF *>(path.points());
+ const QPainterPath::ElementType *const elements = path.elements();
+
+ QPointF sum = points[subPathIndex];
+ int count = 1;
+
+ for (int i = subPathIndex + 1; i < path.elementCount() && (!elements || elements[i] != QPainterPath::MoveToElement); ++i) {
+ sum += points[i];
+ ++count;
+ }
+
+ const QPointF centroid = sum / qreal(count);
+ vertexArray.add(centroid);
+}
+
+void QOpenGL2PEXVertexArray::addPath(const QVectorPath &path, GLfloat curveInverseScale, bool outline)
+{
+ const QPointF* const points = reinterpret_cast<const QPointF*>(path.points());
+ const QPainterPath::ElementType* const elements = path.elements();
+
+ if (boundingRectDirty) {
+ minX = maxX = points[0].x();
+ minY = maxY = points[0].y();
+ boundingRectDirty = false;
+ }
+
+ if (!outline && !path.isConvex())
+ addCentroid(path, 0);
+
+ int lastMoveTo = vertexArray.size();
+ vertexArray.add(points[0]); // The first element is always a moveTo
+
+ do {
+ if (!elements) {
+// qDebug("QVectorPath has no elements");
+ // If the path has a null elements pointer, the elements implicitly
+ // start with a moveTo (already added) and continue with lineTos:
+ for (int i=1; i<path.elementCount(); ++i)
+ lineToArray(points[i].x(), points[i].y());
+
+ break;
+ }
+// qDebug("QVectorPath has element types");
+
+ for (int i=1; i<path.elementCount(); ++i) {
+ switch (elements[i]) {
+ case QPainterPath::MoveToElement:
+ if (!outline)
+ addClosingLine(lastMoveTo);
+// qDebug("element[%d] is a MoveToElement", i);
+ vertexArrayStops.add(vertexArray.size());
+ if (!outline) {
+ if (!path.isConvex()) addCentroid(path, i);
+ lastMoveTo = vertexArray.size();
+ }
+ lineToArray(points[i].x(), points[i].y()); // Add the moveTo as a new vertex
+ break;
+ case QPainterPath::LineToElement:
+// qDebug("element[%d] is a LineToElement", i);
+ lineToArray(points[i].x(), points[i].y());
+ break;
+ case QPainterPath::CurveToElement: {
+ QBezier b = QBezier::fromPoints(*(((const QPointF *) points) + i - 1),
+ points[i],
+ points[i+1],
+ points[i+2]);
+ QRectF bounds = b.bounds();
+ // threshold based on same algorithm as in qtriangulatingstroker.cpp
+ int threshold = qMin<float>(64, qMax(bounds.width(), bounds.height()) * 3.14f / (curveInverseScale * 6));
+ if (threshold < 3) threshold = 3;
+ qreal one_over_threshold_minus_1 = qreal(1) / (threshold - 1);
+ for (int t=0; t<threshold; ++t) {
+ QPointF pt = b.pointAt(t * one_over_threshold_minus_1);
+ lineToArray(pt.x(), pt.y());
+ }
+ i += 2;
+ break; }
+ default:
+ break;
+ }
+ }
+ } while (0);
+
+ if (!outline)
+ addClosingLine(lastMoveTo);
+ vertexArrayStops.add(vertexArray.size());
+}
+
+void QOpenGL2PEXVertexArray::lineToArray(const GLfloat x, const GLfloat y)
+{
+ vertexArray.add(QOpenGLPoint(x, y));
+
+ if (x > maxX)
+ maxX = x;
+ else if (x < minX)
+ minX = x;
+ if (y > maxY)
+ maxY = y;
+ else if (y < minY)
+ minY = y;
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/opengl/qopengl2pexvertexarray_p.h b/src/gui/opengl/qopengl2pexvertexarray_p.h
new file mode 100644
index 0000000000..5ad4f7a237
--- /dev/null
+++ b/src/gui/opengl/qopengl2pexvertexarray_p.h
@@ -0,0 +1,169 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QOPENGL2PEXVERTEXARRAY_P_H
+#define QOPENGL2PEXVERTEXARRAY_P_H
+
+#include <QRectF>
+
+#include <private/qdatabuffer_p.h>
+#include <private/qvectorpath_p.h>
+#include <private/qopenglcontext_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QOpenGLPoint
+{
+public:
+ QOpenGLPoint(GLfloat new_x, GLfloat new_y) :
+ x(new_x), y(new_y) {};
+
+ QOpenGLPoint(const QPointF &p) :
+ x(p.x()), y(p.y()) {};
+
+ QOpenGLPoint(const QPointF* p) :
+ x(p->x()), y(p->y()) {};
+
+ GLfloat x;
+ GLfloat y;
+
+ operator QPointF() {return QPointF(x,y);}
+ operator QPointF() const {return QPointF(x,y);}
+};
+
+struct QOpenGLRect
+{
+ QOpenGLRect(const QRectF &r)
+ : left(r.left()), top(r.top()), right(r.right()), bottom(r.bottom()) {}
+
+ QOpenGLRect(GLfloat l, GLfloat t, GLfloat r, GLfloat b)
+ : left(l), top(t), right(r), bottom(b) {}
+
+ GLfloat left;
+ GLfloat top;
+ GLfloat right;
+ GLfloat bottom;
+
+ operator QRectF() const {return QRectF(left, top, right-left, bottom-top);}
+};
+
+class QOpenGL2PEXVertexArray
+{
+public:
+ QOpenGL2PEXVertexArray() :
+ vertexArray(0), vertexArrayStops(0),
+ maxX(-2e10), maxY(-2e10), minX(2e10), minY(2e10),
+ boundingRectDirty(true)
+ { }
+
+ inline void addRect(const QRectF &rect)
+ {
+ qreal top = rect.top();
+ qreal left = rect.left();
+ qreal bottom = rect.bottom();
+ qreal right = rect.right();
+
+ vertexArray << QOpenGLPoint(left, top)
+ << QOpenGLPoint(right, top)
+ << QOpenGLPoint(right, bottom)
+ << QOpenGLPoint(right, bottom)
+ << QOpenGLPoint(left, bottom)
+ << QOpenGLPoint(left, top);
+ }
+
+ inline void addQuad(const QRectF &rect)
+ {
+ qreal top = rect.top();
+ qreal left = rect.left();
+ qreal bottom = rect.bottom();
+ qreal right = rect.right();
+
+ vertexArray << QOpenGLPoint(left, top)
+ << QOpenGLPoint(right, top)
+ << QOpenGLPoint(left, bottom)
+ << QOpenGLPoint(right, bottom);
+
+ }
+
+ inline void addVertex(const GLfloat x, const GLfloat y)
+ {
+ vertexArray.add(QOpenGLPoint(x, y));
+ }
+
+ void addPath(const QVectorPath &path, GLfloat curveInverseScale, bool outline = true);
+ void clear();
+
+ QOpenGLPoint* data() {return vertexArray.data();}
+ int *stops() const { return vertexArrayStops.data(); }
+ int stopCount() const { return vertexArrayStops.size(); }
+ QOpenGLRect boundingRect() const;
+
+ int vertexCount() const { return vertexArray.size(); }
+
+ void lineToArray(const GLfloat x, const GLfloat y);
+
+private:
+ QDataBuffer<QOpenGLPoint> vertexArray;
+ QDataBuffer<int> vertexArrayStops;
+
+ GLfloat maxX;
+ GLfloat maxY;
+ GLfloat minX;
+ GLfloat minY;
+ bool boundingRectDirty;
+ void addClosingLine(int index);
+ void addCentroid(const QVectorPath &path, int subPathIndex);
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/gui/opengl/qopengl_p.h b/src/gui/opengl/qopengl_p.h
new file mode 100644
index 0000000000..b09f9447db
--- /dev/null
+++ b/src/gui/opengl/qopengl_p.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QOPENGL_P_H
+#define QOPENGL_P_H
+
+#include <qopengl.h>
+#include <private/qopenglcontext_p.h>
+
+#include <qthreadstorage.h>
+#include <qcache.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QOpenGLExtensionMatcher
+{
+public:
+ QOpenGLExtensionMatcher(const char *str);
+ QOpenGLExtensionMatcher();
+
+ bool match(const char *str) const {
+ int str_length = qstrlen(str);
+
+ Q_ASSERT(str);
+ Q_ASSERT(str_length > 0);
+ Q_ASSERT(str[str_length-1] != ' ');
+
+ for (int i = 0; i < m_offsets.size(); ++i) {
+ const char *extension = m_extensions.constData() + m_offsets.at(i);
+ if (qstrncmp(extension, str, str_length) == 0 && extension[str_length] == ' ')
+ return true;
+ }
+ return false;
+ }
+
+private:
+ void init(const char *str);
+
+ QByteArray m_extensions;
+ QVector<int> m_offsets;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QOPENGL_H
diff --git a/src/gui/opengl/qopenglbuffer.cpp b/src/gui/opengl/qopenglbuffer.cpp
new file mode 100644
index 0000000000..bdd38018fa
--- /dev/null
+++ b/src/gui/opengl/qopenglbuffer.cpp
@@ -0,0 +1,567 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/qopengl.h>
+#include <QtGui/private/qopenglcontext_p.h>
+#include <QtCore/qatomic.h>
+#include "qopenglbuffer.h"
+#include <private/qopenglextensions_p.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QOpenGLBuffer
+ \brief The QOpenGLBuffer class provides functions for creating and managing GL buffer objects.
+ \since 5.0
+ \ingroup painting-3D
+
+ Buffer objects are created in the GL server so that the
+ client application can avoid uploading vertices, indices,
+ texture image data, etc every time they are needed.
+
+ QOpenGLBuffer objects can be copied around as a reference to the
+ underlying GL buffer object:
+
+ \code
+ QOpenGLBuffer buffer1(QOpenGLBuffer::IndexBuffer);
+ buffer1.create();
+
+ QOpenGLBuffer buffer2 = buffer1;
+ \endcode
+
+ QOpenGLBuffer performs a shallow copy when objects are copied in this
+ manner, but does not implement copy-on-write semantics. The original
+ object will be affected whenever the copy is modified.
+*/
+
+/*!
+ \enum QOpenGLBuffer::Type
+ This enum defines the type of GL buffer object to create with QOpenGLBuffer.
+
+ \value VertexBuffer Vertex buffer object for use when specifying
+ vertex arrays.
+ \value IndexBuffer Index buffer object for use with \c{glDrawElements()}.
+ \value PixelPackBuffer Pixel pack buffer object for reading pixel
+ data from the GL server (for example, with \c{glReadPixels()}).
+ Not supported under OpenGL/ES.
+ \value PixelUnpackBuffer Pixel unpack buffer object for writing pixel
+ data to the GL server (for example, with \c{glTexImage2D()}).
+ Not supported under OpenGL/ES.
+*/
+
+/*!
+ \enum QOpenGLBuffer::UsagePattern
+ This enum defines the usage pattern of a QOpenGLBuffer object.
+
+ \value StreamDraw The data will be set once and used a few times
+ for drawing operations. Under OpenGL/ES 1.1 this is identical
+ to StaticDraw.
+ \value StreamRead The data will be set once and used a few times
+ for reading data back from the GL server. Not supported
+ under OpenGL/ES.
+ \value StreamCopy The data will be set once and used a few times
+ for reading data back from the GL server for use in further
+ drawing operations. Not supported under OpenGL/ES.
+ \value StaticDraw The data will be set once and used many times
+ for drawing operations.
+ \value StaticRead The data will be set once and used many times
+ for reading data back from the GL server. Not supported
+ under OpenGL/ES.
+ \value StaticCopy The data will be set once and used many times
+ for reading data back from the GL server for use in further
+ drawing operations. Not supported under OpenGL/ES.
+ \value DynamicDraw The data will be modified repeatedly and used
+ many times for drawing operations.
+ \value DynamicRead The data will be modified repeatedly and used
+ many times for reading data back from the GL server.
+ Not supported under OpenGL/ES.
+ \value DynamicCopy The data will be modified repeatedly and used
+ many times for reading data back from the GL server for
+ use in further drawing operations. Not supported under OpenGL/ES.
+*/
+
+/*!
+ \enum QOpenGLBuffer::Access
+ This enum defines the access mode for QOpenGLBuffer::map().
+
+ \value ReadOnly The buffer will be mapped for reading only.
+ \value WriteOnly The buffer will be mapped for writing only.
+ \value ReadWrite The buffer will be mapped for reading and writing.
+*/
+
+class QOpenGLBufferPrivate
+{
+public:
+ QOpenGLBufferPrivate(QOpenGLBuffer::Type t)
+ : ref(1),
+ type(t),
+ guard(0),
+ usagePattern(QOpenGLBuffer::StaticDraw),
+ actualUsagePattern(QOpenGLBuffer::StaticDraw),
+ funcs(0)
+ {
+ }
+
+ QAtomicInt ref;
+ QOpenGLBuffer::Type type;
+ QOpenGLSharedResourceGuard *guard;
+ QOpenGLBuffer::UsagePattern usagePattern;
+ QOpenGLBuffer::UsagePattern actualUsagePattern;
+ QOpenGLExtensions *funcs;
+};
+
+/*!
+ Constructs a new buffer object of type QOpenGLBuffer::VertexBuffer.
+
+ Note: this constructor just creates the QOpenGLBuffer instance. The actual
+ buffer object in the GL server is not created until create() is called.
+
+ \sa create()
+*/
+QOpenGLBuffer::QOpenGLBuffer()
+ : d_ptr(new QOpenGLBufferPrivate(QOpenGLBuffer::VertexBuffer))
+{
+}
+
+/*!
+ Constructs a new buffer object of \a type.
+
+ Note: this constructor just creates the QOpenGLBuffer instance. The actual
+ buffer object in the GL server is not created until create() is called.
+
+ \sa create()
+*/
+QOpenGLBuffer::QOpenGLBuffer(QOpenGLBuffer::Type type)
+ : d_ptr(new QOpenGLBufferPrivate(type))
+{
+}
+
+/*!
+ Constructs a shallow copy of \a other.
+
+ Note: QOpenGLBuffer does not implement copy-on-write semantics,
+ so \a other will be affected whenever the copy is modified.
+*/
+QOpenGLBuffer::QOpenGLBuffer(const QOpenGLBuffer &other)
+ : d_ptr(other.d_ptr)
+{
+ d_ptr->ref.ref();
+}
+
+/*!
+ Destroys this buffer object, including the storage being
+ used in the GL server.
+*/
+QOpenGLBuffer::~QOpenGLBuffer()
+{
+ if (!d_ptr->ref.deref()) {
+ destroy();
+ delete d_ptr;
+ }
+}
+
+/*!
+ Assigns a shallow copy of \a other to this object.
+
+ Note: QOpenGLBuffer does not implement copy-on-write semantics,
+ so \a other will be affected whenever the copy is modified.
+*/
+QOpenGLBuffer &QOpenGLBuffer::operator=(const QOpenGLBuffer &other)
+{
+ if (d_ptr != other.d_ptr) {
+ other.d_ptr->ref.ref();
+ if (!d_ptr->ref.deref())
+ destroy();
+ d_ptr = other.d_ptr;
+ }
+ return *this;
+}
+
+/*!
+ Returns the type of buffer represented by this object.
+*/
+QOpenGLBuffer::Type QOpenGLBuffer::type() const
+{
+ Q_D(const QOpenGLBuffer);
+ return d->type;
+}
+
+/*!
+ Returns the usage pattern for this buffer object.
+ The default value is StaticDraw.
+
+ \sa setUsagePattern()
+*/
+QOpenGLBuffer::UsagePattern QOpenGLBuffer::usagePattern() const
+{
+ Q_D(const QOpenGLBuffer);
+ return d->usagePattern;
+}
+
+/*!
+ Sets the usage pattern for this buffer object to \a value.
+ This function must be called before allocate() or write().
+
+ \sa usagePattern(), allocate(), write()
+*/
+void QOpenGLBuffer::setUsagePattern(QOpenGLBuffer::UsagePattern value)
+{
+ Q_D(QOpenGLBuffer);
+ d->usagePattern = d->actualUsagePattern = value;
+}
+
+namespace {
+ void freeBufferFunc(QOpenGLFunctions *funcs, GLuint id)
+ {
+ funcs->glDeleteBuffers(1, &id);
+ }
+}
+
+/*!
+ Creates the buffer object in the GL server. Returns true if
+ the object was created; false otherwise.
+
+ This function must be called with a current QOpenGLContext.
+ The buffer will be bound to and can only be used in
+ that context (or any other context that is shared with it).
+
+ This function will return false if the GL implementation
+ does not support buffers, or there is no current QOpenGLContext.
+
+ \sa isCreated(), allocate(), write(), destroy()
+*/
+bool QOpenGLBuffer::create()
+{
+ Q_D(QOpenGLBuffer);
+ if (d->guard && d->guard->id())
+ return true;
+ QOpenGLContext *ctx = QOpenGLContext::currentContext();
+ if (ctx) {
+ delete d->funcs;
+ d->funcs = new QOpenGLExtensions(ctx);
+ GLuint bufferId = 0;
+ d->funcs->glGenBuffers(1, &bufferId);
+ if (bufferId) {
+ if (d->guard)
+ d->guard->free();
+
+ d->guard = new QOpenGLSharedResourceGuard(ctx, bufferId, freeBufferFunc);
+ return true;
+ }
+ }
+ return false;
+}
+
+/*!
+ Returns true if this buffer has been created; false otherwise.
+
+ \sa create(), destroy()
+*/
+bool QOpenGLBuffer::isCreated() const
+{
+ Q_D(const QOpenGLBuffer);
+ return d->guard && d->guard->id();
+}
+
+/*!
+ Destroys this buffer object, including the storage being
+ used in the GL server. All references to the buffer will
+ become invalid.
+*/
+void QOpenGLBuffer::destroy()
+{
+ Q_D(QOpenGLBuffer);
+ if (d->guard) {
+ d->guard->free();
+ d->guard = 0;
+ }
+}
+
+/*!
+ Reads the \a count bytes in this buffer starting at \a offset
+ into \a data. Returns true on success; false if reading from
+ the buffer is not supported. Buffer reading is not supported
+ under OpenGL/ES.
+
+ It is assumed that this buffer has been bound to the current context.
+
+ \sa write(), bind()
+*/
+bool QOpenGLBuffer::read(int offset, void *data, int count)
+{
+#if !defined(QT_OPENGL_ES)
+ Q_D(QOpenGLBuffer);
+ if (!d->funcs->hasOpenGLFeature(QOpenGLFunctions::Buffers) || !d->guard->id())
+ return false;
+ while (glGetError() != GL_NO_ERROR) ; // Clear error state.
+ d->funcs->glGetBufferSubData(d->type, offset, count, data);
+ return glGetError() == GL_NO_ERROR;
+#else
+ Q_UNUSED(offset);
+ Q_UNUSED(data);
+ Q_UNUSED(count);
+ return false;
+#endif
+}
+
+/*!
+ Replaces the \a count bytes of this buffer starting at \a offset
+ with the contents of \a data. Any other bytes in the buffer
+ will be left unmodified.
+
+ It is assumed that create() has been called on this buffer and that
+ it has been bound to the current context.
+
+ \sa create(), read(), allocate()
+*/
+void QOpenGLBuffer::write(int offset, const void *data, int count)
+{
+#ifndef QT_NO_DEBUG
+ if (!isCreated())
+ qWarning("QOpenGLBuffer::allocate(): buffer not created");
+#endif
+ Q_D(QOpenGLBuffer);
+ if (d->guard && d->guard->id())
+ d->funcs->glBufferSubData(d->type, offset, count, data);
+}
+
+/*!
+ Allocates \a count bytes of space to the buffer, initialized to
+ the contents of \a data. Any previous contents will be removed.
+
+ It is assumed that create() has been called on this buffer and that
+ it has been bound to the current context.
+
+ \sa create(), read(), write()
+*/
+void QOpenGLBuffer::allocate(const void *data, int count)
+{
+#ifndef QT_NO_DEBUG
+ if (!isCreated())
+ qWarning("QOpenGLBuffer::allocate(): buffer not created");
+#endif
+ Q_D(QOpenGLBuffer);
+ if (d->guard && d->guard->id())
+ d->funcs->glBufferData(d->type, count, data, d->actualUsagePattern);
+}
+
+/*!
+ \fn void QOpenGLBuffer::allocate(int count)
+ \overload
+
+ Allocates \a count bytes of space to the buffer. Any previous
+ contents will be removed.
+
+ It is assumed that create() has been called on this buffer and that
+ it has been bound to the current context.
+
+ \sa create(), write()
+*/
+
+/*!
+ Binds the buffer associated with this object to the current
+ GL context. Returns false if binding was not possible, usually because
+ type() is not supported on this GL implementation.
+
+ The buffer must be bound to the same QOpenGLContext current when create()
+ was called, or to another QOpenGLContext that is sharing with it.
+ Otherwise, false will be returned from this function.
+
+ \sa release(), create()
+*/
+bool QOpenGLBuffer::bind()
+{
+#ifndef QT_NO_DEBUG
+ if (!isCreated())
+ qWarning("QOpenGLBuffer::bind(): buffer not created");
+#endif
+ Q_D(const QOpenGLBuffer);
+ GLuint bufferId = d->guard ? d->guard->id() : 0;
+ if (bufferId) {
+ if (d->guard->group() != QOpenGLContextGroup::currentContextGroup()) {
+#ifndef QT_NO_DEBUG
+ qWarning("QOpenGLBuffer::bind: buffer is not valid in the current context");
+#endif
+ return false;
+ }
+ d->funcs->glBindBuffer(d->type, bufferId);
+ return true;
+ } else {
+ return false;
+ }
+}
+
+/*!
+ Releases the buffer associated with this object from the
+ current GL context.
+
+ This function must be called with the same QOpenGLContext current
+ as when bind() was called on the buffer.
+
+ \sa bind()
+*/
+void QOpenGLBuffer::release()
+{
+#ifndef QT_NO_DEBUG
+ if (!isCreated())
+ qWarning("QOpenGLBuffer::release(): buffer not created");
+#endif
+ Q_D(const QOpenGLBuffer);
+ if (d->guard && d->guard->id())
+ d->funcs->glBindBuffer(d->type, 0);
+}
+
+/*!
+ Releases the buffer associated with \a type in the current
+ QOpenGLContext.
+
+ This function is a direct call to \c{glBindBuffer(type, 0)}
+ for use when the caller does not know which QOpenGLBuffer has
+ been bound to the context but wants to make sure that it
+ is released.
+
+ \code
+ QOpenGLBuffer::release(QOpenGLBuffer::VertexBuffer);
+ \endcode
+*/
+void QOpenGLBuffer::release(QOpenGLBuffer::Type type)
+{
+ QOpenGLContext *ctx = QOpenGLContext::currentContext();
+ if (ctx)
+ ctx->functions()->glBindBuffer(GLenum(type), 0);
+}
+
+/*!
+ Returns the GL identifier associated with this buffer; zero if
+ the buffer has not been created.
+
+ \sa isCreated()
+*/
+GLuint QOpenGLBuffer::bufferId() const
+{
+ Q_D(const QOpenGLBuffer);
+ return d->guard ? d->guard->id() : 0;
+}
+
+/*!
+ Returns the size of the data in this buffer, for reading operations.
+ Returns -1 if fetching the buffer size is not supported, or the
+ buffer has not been created.
+
+ It is assumed that this buffer has been bound to the current context.
+
+ \sa isCreated(), bind()
+*/
+int QOpenGLBuffer::size() const
+{
+ Q_D(const QOpenGLBuffer);
+ if (!d->guard || !d->guard->id())
+ return -1;
+ GLint value = -1;
+ d->funcs->glGetBufferParameteriv(d->type, GL_BUFFER_SIZE, &value);
+ return value;
+}
+
+/*!
+ Maps the contents of this buffer into the application's memory
+ space and returns a pointer to it. Returns null if memory
+ mapping is not possible. The \a access parameter indicates the
+ type of access to be performed.
+
+ It is assumed that create() has been called on this buffer and that
+ it has been bound to the current context.
+
+ This function is only supported under OpenGL/ES if the
+ \c{GL_OES_mapbuffer} extension is present.
+
+ \sa unmap(), create(), bind()
+*/
+void *QOpenGLBuffer::map(QOpenGLBuffer::Access access)
+{
+ Q_D(QOpenGLBuffer);
+#ifndef QT_NO_DEBUG
+ if (!isCreated())
+ qWarning("QOpenGLBuffer::map(): buffer not created");
+#endif
+ if (!d->guard || !d->guard->id())
+ return 0;
+#if 0
+ if (!glMapBufferARB)
+ return 0;
+ return glMapBufferARB(d->type, access);
+#endif
+ Q_UNUSED(access);
+ qWarning("QOpenGLBuffer::map(): pending implementation");
+ return 0;
+}
+
+/*!
+ Unmaps the buffer after it was mapped into the application's
+ memory space with a previous call to map(). Returns true if
+ the unmap succeeded; false otherwise.
+
+ It is assumed that this buffer has been bound to the current context,
+ and that it was previously mapped with map().
+
+ This function is only supported under OpenGL/ES if the
+ \c{GL_OES_mapbuffer} extension is present.
+
+ \sa map()
+*/
+bool QOpenGLBuffer::unmap()
+{
+ Q_D(QOpenGLBuffer);
+#ifndef QT_NO_DEBUG
+ if (!isCreated())
+ qWarning("QOpenGLBuffer::unmap(): buffer not created");
+#endif
+ if (!d->guard || !d->guard->id())
+ return false;
+#if 0
+ if (!glUnmapBufferARB)
+ return false;
+ return glUnmapBufferARB(d->type) == GL_TRUE;
+#endif
+ qWarning("QOpenGLBuffer::map(): pending implementation");
+ return 0;
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/opengl/qopenglbuffer.h b/src/gui/opengl/qopenglbuffer.h
new file mode 100644
index 0000000000..52a2c4d640
--- /dev/null
+++ b/src/gui/opengl/qopenglbuffer.h
@@ -0,0 +1,132 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QOPENGLBUFFER_H
+#define QOPENGLBUFFER_H
+
+#include <QtCore/qscopedpointer.h>
+#include <QtGui/qopengl.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QOpenGLBufferPrivate;
+
+class Q_GUI_EXPORT QOpenGLBuffer
+{
+public:
+ enum Type
+ {
+ VertexBuffer = 0x8892, // GL_ARRAY_BUFFER
+ IndexBuffer = 0x8893, // GL_ELEMENT_ARRAY_BUFFER
+ PixelPackBuffer = 0x88EB, // GL_PIXEL_PACK_BUFFER
+ PixelUnpackBuffer = 0x88EC // GL_PIXEL_UNPACK_BUFFER
+ };
+
+ QOpenGLBuffer();
+ explicit QOpenGLBuffer(QOpenGLBuffer::Type type);
+ QOpenGLBuffer(const QOpenGLBuffer &other);
+ ~QOpenGLBuffer();
+
+ QOpenGLBuffer &operator=(const QOpenGLBuffer &other);
+
+ enum UsagePattern
+ {
+ StreamDraw = 0x88E0, // GL_STREAM_DRAW
+ StreamRead = 0x88E1, // GL_STREAM_READ
+ StreamCopy = 0x88E2, // GL_STREAM_COPY
+ StaticDraw = 0x88E4, // GL_STATIC_DRAW
+ StaticRead = 0x88E5, // GL_STATIC_READ
+ StaticCopy = 0x88E6, // GL_STATIC_COPY
+ DynamicDraw = 0x88E8, // GL_DYNAMIC_DRAW
+ DynamicRead = 0x88E9, // GL_DYNAMIC_READ
+ DynamicCopy = 0x88EA // GL_DYNAMIC_COPY
+ };
+
+ enum Access
+ {
+ ReadOnly = 0x88B8, // GL_READ_ONLY
+ WriteOnly = 0x88B9, // GL_WRITE_ONLY
+ ReadWrite = 0x88BA // GL_READ_WRITE
+ };
+
+ QOpenGLBuffer::Type type() const;
+
+ QOpenGLBuffer::UsagePattern usagePattern() const;
+ void setUsagePattern(QOpenGLBuffer::UsagePattern value);
+
+ bool create();
+ bool isCreated() const;
+
+ void destroy();
+
+ bool bind();
+ void release();
+
+ static void release(QOpenGLBuffer::Type type);
+
+ GLuint bufferId() const;
+
+ int size() const;
+
+ bool read(int offset, void *data, int count);
+ void write(int offset, const void *data, int count);
+
+ void allocate(const void *data, int count);
+ inline void allocate(int count) { allocate(0, count); }
+
+ void *map(QOpenGLBuffer::Access access);
+ bool unmap();
+
+private:
+ QOpenGLBufferPrivate *d_ptr;
+
+ Q_DECLARE_PRIVATE(QOpenGLBuffer)
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/gui/opengl/qopenglcolormap.cpp b/src/gui/opengl/qopenglcolormap.cpp
new file mode 100644
index 0000000000..386358ac23
--- /dev/null
+++ b/src/gui/opengl/qopenglcolormap.cpp
@@ -0,0 +1,297 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \class QOpenGLColormap
+ \brief The QOpenGLColormap class is used for installing custom colormaps into
+ a QOpenGLWidget.
+
+ \module OpenGL
+ \ingroup painting-3D
+ \ingroup shared
+
+ QOpenGLColormap provides a platform independent way of specifying and
+ installing indexed colormaps for a QOpenGLWidget. QOpenGLColormap is
+ especially useful when using the OpenGL color-index mode.
+
+ Under X11 you must use an X server that supports either a \c
+ PseudoColor or \c DirectColor visual class. If your X server
+ currently only provides a \c GrayScale, \c TrueColor, \c
+ StaticColor or \c StaticGray visual, you will not be able to
+ allocate colorcells for writing. If this is the case, try setting
+ your X server to 8 bit mode. It should then provide you with at
+ least a \c PseudoColor visual. Note that you may experience
+ colormap flashing if your X server is running in 8 bit mode.
+
+ The size() of the colormap is always set to 256
+ colors. Note that under Windows you can also install colormaps
+ in child widgets.
+
+ This class uses \l{implicit sharing} as a memory and speed
+ optimization.
+
+ Example of use:
+ \snippet doc/src/snippets/code/src_opengl_qopenglcolormap.cpp 0
+
+ \sa QOpenGLWidget::setColormap(), QOpenGLWidget::colormap()
+*/
+
+/*!
+ \fn Qt::HANDLE QOpenGLColormap::handle()
+
+ \internal
+
+ Returns the handle for this color map.
+*/
+
+/*!
+ \fn void QOpenGLColormap::setHandle(Qt::HANDLE handle)
+
+ \internal
+
+ Sets the handle for this color map to \a handle.
+*/
+
+#include "qopenglcolormap.h"
+
+QT_BEGIN_NAMESPACE
+
+QOpenGLColormap::QOpenGLColormapData QOpenGLColormap::shared_null = { Q_BASIC_ATOMIC_INITIALIZER(1), 0, 0 };
+
+/*!
+ Construct a QOpenGLColormap.
+*/
+QOpenGLColormap::QOpenGLColormap()
+ : d(&shared_null)
+{
+ d->ref.ref();
+}
+
+
+/*!
+ Construct a shallow copy of \a map.
+*/
+QOpenGLColormap::QOpenGLColormap(const QOpenGLColormap &map)
+ : d(map.d)
+{
+ d->ref.ref();
+}
+
+/*!
+ Dereferences the QOpenGLColormap and deletes it if this was the last
+ reference to it.
+*/
+QOpenGLColormap::~QOpenGLColormap()
+{
+ if (!d->ref.deref())
+ cleanup(d);
+}
+
+void QOpenGLColormap::cleanup(QOpenGLColormap::QOpenGLColormapData *x)
+{
+ delete x->cells;
+ x->cells = 0;
+ delete x;
+}
+
+/*!
+ Assign a shallow copy of \a map to this QOpenGLColormap.
+*/
+QOpenGLColormap & QOpenGLColormap::operator=(const QOpenGLColormap &map)
+{
+ map.d->ref.ref();
+ if (!d->ref.deref())
+ cleanup(d);
+ d = map.d;
+ return *this;
+}
+
+/*!
+ \fn void QOpenGLColormap::detach()
+ \internal
+
+ Detaches this QOpenGLColormap from the shared block.
+*/
+
+void QOpenGLColormap::detach_helper()
+{
+ QOpenGLColormapData *x = new QOpenGLColormapData;
+ x->ref = 1;
+ x->cmapHandle = 0;
+ x->cells = 0;
+ if (d->cells) {
+ x->cells = new QVector<QRgb>(256);
+ *x->cells = *d->cells;
+ }
+ if (!d->ref.deref())
+ cleanup(d);
+ d = x;
+}
+
+/*!
+ Set cell at index \a idx in the colormap to color \a color.
+*/
+void QOpenGLColormap::setEntry(int idx, QRgb color)
+{
+ detach();
+ if (!d->cells)
+ d->cells = new QVector<QRgb>(256);
+ d->cells->replace(idx, color);
+}
+
+/*!
+ Set an array of cells in this colormap. \a count is the number of
+ colors that should be set, \a colors is the array of colors, and
+ \a base is the starting index. The first element in \a colors
+ is set at \a base in the colormap.
+*/
+void QOpenGLColormap::setEntries(int count, const QRgb *colors, int base)
+{
+ detach();
+ if (!d->cells)
+ d->cells = new QVector<QRgb>(256);
+
+ Q_ASSERT_X(colors && base >= 0 && (base + count) <= d->cells->size(), "QOpenGLColormap::setEntries",
+ "preconditions not met");
+ for (int i = 0; i < count; ++i)
+ setEntry(base + i, colors[i]);
+}
+
+/*!
+ Returns the QRgb value in the colorcell with index \a idx.
+*/
+QRgb QOpenGLColormap::entryRgb(int idx) const
+{
+ if (d == &shared_null || !d->cells)
+ return 0;
+ else
+ return d->cells->at(idx);
+}
+
+/*!
+ \overload
+
+ Set the cell with index \a idx in the colormap to color \a color.
+*/
+void QOpenGLColormap::setEntry(int idx, const QColor &color)
+{
+ setEntry(idx, color.rgb());
+}
+
+/*!
+ Returns the QRgb value in the colorcell with index \a idx.
+*/
+QColor QOpenGLColormap::entryColor(int idx) const
+{
+ if (d == &shared_null || !d->cells)
+ return QColor();
+ else
+ return QColor(d->cells->at(idx));
+}
+
+/*!
+ Returns true if the colormap is empty or it is not in use
+ by a QOpenGLWidget; otherwise returns false.
+
+ A colormap with no color values set is considered to be empty.
+ For historical reasons, a colormap that has color values set
+ but which is not in use by a QOpenGLWidget is also considered empty.
+
+ Compare size() with zero to determine if the colormap is empty
+ regardless of whether it is in use by a QOpenGLWidget or not.
+
+ \sa size()
+*/
+bool QOpenGLColormap::isEmpty() const
+{
+ return d == &shared_null || d->cells == 0 || d->cells->size() == 0 || d->cmapHandle == 0;
+}
+
+
+/*!
+ Returns the number of colorcells in the colormap.
+*/
+int QOpenGLColormap::size() const
+{
+ return d->cells ? d->cells->size() : 0;
+}
+
+/*!
+ Returns the index of the color \a color. If \a color is not in the
+ map, -1 is returned.
+*/
+int QOpenGLColormap::find(QRgb color) const
+{
+ if (d->cells)
+ return d->cells->indexOf(color);
+ return -1;
+}
+
+/*!
+ Returns the index of the color that is the closest match to color
+ \a color.
+*/
+int QOpenGLColormap::findNearest(QRgb color) const
+{
+ int idx = find(color);
+ if (idx >= 0)
+ return idx;
+ int mapSize = size();
+ int mindist = 200000;
+ int r = qRed(color);
+ int g = qGreen(color);
+ int b = qBlue(color);
+ int rx, gx, bx, dist;
+ for (int i = 0; i < mapSize; ++i) {
+ QRgb ci = d->cells->at(i);
+ rx = r - qRed(ci);
+ gx = g - qGreen(ci);
+ bx = b - qBlue(ci);
+ dist = rx * rx + gx * gx + bx * bx; // calculate distance
+ if (dist < mindist) { // minimal?
+ mindist = dist;
+ idx = i;
+ }
+ }
+ return idx;
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/opengl/qopenglcolormap.h b/src/gui/opengl/qopenglcolormap.h
new file mode 100644
index 0000000000..b05e3f331d
--- /dev/null
+++ b/src/gui/opengl/qopenglcolormap.h
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QOPENGLCOLORMAP_H
+#define QOPENGLCOLORMAP_H
+
+#include <QtGui/qcolor.h>
+#include <QtCore/qvector.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class Q_GUI_EXPORT QOpenGLColormap
+{
+public:
+ QOpenGLColormap();
+ QOpenGLColormap(const QOpenGLColormap &);
+ ~QOpenGLColormap();
+
+ QOpenGLColormap &operator=(const QOpenGLColormap &);
+
+ bool isEmpty() const;
+ int size() const;
+ void detach();
+
+ void setEntries(int count, const QRgb * colors, int base = 0);
+ void setEntry(int idx, QRgb color);
+ void setEntry(int idx, const QColor & color);
+ QRgb entryRgb(int idx) const;
+ QColor entryColor(int idx) const;
+ int find(QRgb color) const;
+ int findNearest(QRgb color) const;
+
+protected:
+ Qt::HANDLE handle() { return d ? d->cmapHandle : 0; }
+ void setHandle(Qt::HANDLE ahandle) { d->cmapHandle = ahandle; }
+
+private:
+ struct QOpenGLColormapData {
+ QBasicAtomicInt ref;
+ QVector<QRgb> *cells;
+ Qt::HANDLE cmapHandle;
+ };
+
+ QOpenGLColormapData *d;
+ static struct QOpenGLColormapData shared_null;
+ static void cleanup(QOpenGLColormapData *x);
+ void detach_helper();
+
+ friend class QOpenGLWidget;
+ friend class QOpenGLWidgetPrivate;
+};
+
+inline void QOpenGLColormap::detach()
+{
+ if (d->ref != 1)
+ detach_helper();
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QOPENGLCOLORMAP_H
diff --git a/src/gui/opengl/qopenglcustomshaderstage.cpp b/src/gui/opengl/qopenglcustomshaderstage.cpp
new file mode 100644
index 0000000000..6cedf66df1
--- /dev/null
+++ b/src/gui/opengl/qopenglcustomshaderstage.cpp
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qopenglcustomshaderstage_p.h"
+#include "qopenglengineshadermanager_p.h"
+#include "qopenglpaintengine_p.h"
+#include <private/qpainter_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QOpenGLCustomShaderStagePrivate
+{
+public:
+ QOpenGLCustomShaderStagePrivate() :
+ m_manager(0) {}
+
+ QPointer<QOpenGLEngineShaderManager> m_manager;
+ QByteArray m_source;
+};
+
+
+
+
+QOpenGLCustomShaderStage::QOpenGLCustomShaderStage()
+ : d_ptr(new QOpenGLCustomShaderStagePrivate)
+{
+}
+
+QOpenGLCustomShaderStage::~QOpenGLCustomShaderStage()
+{
+ Q_D(QOpenGLCustomShaderStage);
+ if (d->m_manager) {
+ d->m_manager->removeCustomStage();
+ d->m_manager->sharedShaders->cleanupCustomStage(this);
+ }
+}
+
+void QOpenGLCustomShaderStage::setUniformsDirty()
+{
+ Q_D(QOpenGLCustomShaderStage);
+ if (d->m_manager)
+ d->m_manager->setDirty(); // ### Probably a bit overkill!
+}
+
+bool QOpenGLCustomShaderStage::setOnPainter(QPainter* p)
+{
+ Q_D(QOpenGLCustomShaderStage);
+ if (p->paintEngine()->type() != QPaintEngine::OpenGL2) {
+ qWarning("QOpenGLCustomShaderStage::setOnPainter() - paint engine not OpenGL2");
+ return false;
+ }
+ if (d->m_manager)
+ qWarning("Custom shader is already set on a painter");
+
+ QOpenGL2PaintEngineEx *engine = static_cast<QOpenGL2PaintEngineEx*>(p->paintEngine());
+ d->m_manager = QOpenGL2PaintEngineExPrivate::shaderManagerForEngine(engine);
+ Q_ASSERT(d->m_manager);
+
+ d->m_manager->setCustomStage(this);
+ return true;
+}
+
+void QOpenGLCustomShaderStage::removeFromPainter(QPainter* p)
+{
+ Q_D(QOpenGLCustomShaderStage);
+ if (p->paintEngine()->type() != QPaintEngine::OpenGL2)
+ return;
+
+ QOpenGL2PaintEngineEx *engine = static_cast<QOpenGL2PaintEngineEx*>(p->paintEngine());
+ d->m_manager = QOpenGL2PaintEngineExPrivate::shaderManagerForEngine(engine);
+ Q_ASSERT(d->m_manager);
+
+ // Just set the stage to null, don't call removeCustomStage().
+ // This should leave the program in a compiled/linked state
+ // if the next custom shader stage is this one again.
+ d->m_manager->setCustomStage(0);
+ d->m_manager = 0;
+}
+
+QByteArray QOpenGLCustomShaderStage::source() const
+{
+ Q_D(const QOpenGLCustomShaderStage);
+ return d->m_source;
+}
+
+// Called by the shader manager if another custom shader is attached or
+// the manager is deleted
+void QOpenGLCustomShaderStage::setInactive()
+{
+ Q_D(QOpenGLCustomShaderStage);
+ d->m_manager = 0;
+}
+
+void QOpenGLCustomShaderStage::setSource(const QByteArray& s)
+{
+ Q_D(QOpenGLCustomShaderStage);
+ d->m_source = s;
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/opengl/qopenglcustomshaderstage_p.h b/src/gui/opengl/qopenglcustomshaderstage_p.h
new file mode 100644
index 0000000000..de459c0050
--- /dev/null
+++ b/src/gui/opengl/qopenglcustomshaderstage_p.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QOPENGL_CUSTOM_SHADER_STAGE_H
+#define QOPENGL_CUSTOM_SHADER_STAGE_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QOpenGLShaderProgram>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QPainter;
+class QOpenGLCustomShaderStagePrivate;
+class Q_GUI_EXPORT QOpenGLCustomShaderStage
+{
+ Q_DECLARE_PRIVATE(QOpenGLCustomShaderStage)
+public:
+ QOpenGLCustomShaderStage();
+ virtual ~QOpenGLCustomShaderStage();
+ virtual void setUniforms(QOpenGLShaderProgram*) {}
+
+ void setUniformsDirty();
+
+ bool setOnPainter(QPainter*);
+ void removeFromPainter(QPainter*);
+ QByteArray source() const;
+
+ void setInactive();
+protected:
+ void setSource(const QByteArray&);
+
+private:
+ QOpenGLCustomShaderStagePrivate* d_ptr;
+};
+
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif
diff --git a/src/gui/opengl/qopenglengineshadermanager.cpp b/src/gui/opengl/qopenglengineshadermanager.cpp
new file mode 100644
index 0000000000..aaca6ad89c
--- /dev/null
+++ b/src/gui/opengl/qopenglengineshadermanager.cpp
@@ -0,0 +1,881 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qopenglengineshadermanager_p.h"
+#include "qopenglengineshadersource_p.h"
+#include "qopenglpaintengine_p.h"
+#include "qopenglshadercache_p.h"
+
+#include <QtGui/private/qopenglcontext_p.h>
+#include <QtCore/qthreadstorage.h>
+
+#if defined(QT_DEBUG)
+#include <QMetaEnum>
+#endif
+
+// #define QT_GL_SHARED_SHADER_DEBUG
+
+QT_BEGIN_NAMESPACE
+
+class QOpenGLEngineSharedShadersResource : public QOpenGLSharedResource
+{
+public:
+ QOpenGLEngineSharedShadersResource(QOpenGLContext *ctx)
+ : QOpenGLSharedResource(ctx->shareGroup())
+ , m_shaders(new QOpenGLEngineSharedShaders(ctx))
+ {
+ }
+
+ ~QOpenGLEngineSharedShadersResource()
+ {
+ delete m_shaders;
+ }
+
+ void invalidateResource()
+ {
+ delete m_shaders;
+ m_shaders = 0;
+ }
+
+ void freeResource(QOpenGLContext *)
+ {
+ }
+
+ QOpenGLEngineSharedShaders *shaders() const { return m_shaders; }
+
+private:
+ QOpenGLEngineSharedShaders *m_shaders;
+};
+
+class QOpenGLShaderStorage
+{
+public:
+ QOpenGLEngineSharedShaders *shadersForThread(QOpenGLContext *context) {
+ QOpenGLMultiGroupSharedResource *&shaders = m_storage.localData();
+ if (!shaders)
+ shaders = new QOpenGLMultiGroupSharedResource;
+ QOpenGLEngineSharedShadersResource *resource =
+ shaders->value<QOpenGLEngineSharedShadersResource>(context);
+ return resource ? resource->shaders() : 0;
+ }
+
+private:
+ QThreadStorage<QOpenGLMultiGroupSharedResource *> m_storage;
+};
+
+Q_GLOBAL_STATIC(QOpenGLShaderStorage, qt_shader_storage);
+
+QOpenGLEngineSharedShaders *QOpenGLEngineSharedShaders::shadersForContext(QOpenGLContext *context)
+{
+ return qt_shader_storage()->shadersForThread(context);
+}
+
+const char* QOpenGLEngineSharedShaders::qShaderSnippets[] = {
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0
+};
+
+QOpenGLEngineSharedShaders::QOpenGLEngineSharedShaders(QOpenGLContext* context)
+ : blitShaderProg(0)
+ , simpleShaderProg(0)
+{
+
+/*
+ Rather than having the shader source array statically initialised, it is initialised
+ here instead. This is to allow new shader names to be inserted or existing names moved
+ around without having to change the order of the glsl strings. It is hoped this will
+ make future hard-to-find runtime bugs more obvious and generally give more solid code.
+*/
+ static bool snippetsPopulated = false;
+ if (!snippetsPopulated) {
+
+ const char** code = qShaderSnippets; // shortcut
+
+ code[MainVertexShader] = qopenglslMainVertexShader;
+ code[MainWithTexCoordsVertexShader] = qopenglslMainWithTexCoordsVertexShader;
+ code[MainWithTexCoordsAndOpacityVertexShader] = qopenglslMainWithTexCoordsAndOpacityVertexShader;
+
+ code[UntransformedPositionVertexShader] = qopenglslUntransformedPositionVertexShader;
+ code[PositionOnlyVertexShader] = qopenglslPositionOnlyVertexShader;
+ code[ComplexGeometryPositionOnlyVertexShader] = qopenglslComplexGeometryPositionOnlyVertexShader;
+ code[PositionWithPatternBrushVertexShader] = qopenglslPositionWithPatternBrushVertexShader;
+ code[PositionWithLinearGradientBrushVertexShader] = qopenglslPositionWithLinearGradientBrushVertexShader;
+ code[PositionWithConicalGradientBrushVertexShader] = qopenglslPositionWithConicalGradientBrushVertexShader;
+ code[PositionWithRadialGradientBrushVertexShader] = qopenglslPositionWithRadialGradientBrushVertexShader;
+ code[PositionWithTextureBrushVertexShader] = qopenglslPositionWithTextureBrushVertexShader;
+ code[AffinePositionWithPatternBrushVertexShader] = qopenglslAffinePositionWithPatternBrushVertexShader;
+ code[AffinePositionWithLinearGradientBrushVertexShader] = qopenglslAffinePositionWithLinearGradientBrushVertexShader;
+ code[AffinePositionWithConicalGradientBrushVertexShader] = qopenglslAffinePositionWithConicalGradientBrushVertexShader;
+ code[AffinePositionWithRadialGradientBrushVertexShader] = qopenglslAffinePositionWithRadialGradientBrushVertexShader;
+ code[AffinePositionWithTextureBrushVertexShader] = qopenglslAffinePositionWithTextureBrushVertexShader;
+
+ code[MainFragmentShader_CMO] = qopenglslMainFragmentShader_CMO;
+ code[MainFragmentShader_CM] = qopenglslMainFragmentShader_CM;
+ code[MainFragmentShader_MO] = qopenglslMainFragmentShader_MO;
+ code[MainFragmentShader_M] = qopenglslMainFragmentShader_M;
+ code[MainFragmentShader_CO] = qopenglslMainFragmentShader_CO;
+ code[MainFragmentShader_C] = qopenglslMainFragmentShader_C;
+ code[MainFragmentShader_O] = qopenglslMainFragmentShader_O;
+ code[MainFragmentShader] = qopenglslMainFragmentShader;
+ code[MainFragmentShader_ImageArrays] = qopenglslMainFragmentShader_ImageArrays;
+
+ code[ImageSrcFragmentShader] = qopenglslImageSrcFragmentShader;
+ code[ImageSrcWithPatternFragmentShader] = qopenglslImageSrcWithPatternFragmentShader;
+ code[NonPremultipliedImageSrcFragmentShader] = qopenglslNonPremultipliedImageSrcFragmentShader;
+ code[CustomImageSrcFragmentShader] = qopenglslCustomSrcFragmentShader; // Calls "customShader", which must be appended
+ code[SolidBrushSrcFragmentShader] = qopenglslSolidBrushSrcFragmentShader;
+ code[TextureBrushSrcFragmentShader] = qopenglslTextureBrushSrcFragmentShader;
+ code[TextureBrushSrcWithPatternFragmentShader] = qopenglslTextureBrushSrcWithPatternFragmentShader;
+ code[PatternBrushSrcFragmentShader] = qopenglslPatternBrushSrcFragmentShader;
+ code[LinearGradientBrushSrcFragmentShader] = qopenglslLinearGradientBrushSrcFragmentShader;
+ code[RadialGradientBrushSrcFragmentShader] = qopenglslRadialGradientBrushSrcFragmentShader;
+ code[ConicalGradientBrushSrcFragmentShader] = qopenglslConicalGradientBrushSrcFragmentShader;
+ code[ShockingPinkSrcFragmentShader] = qopenglslShockingPinkSrcFragmentShader;
+
+ code[NoMaskFragmentShader] = "";
+ code[MaskFragmentShader] = qopenglslMaskFragmentShader;
+ code[RgbMaskFragmentShaderPass1] = qopenglslRgbMaskFragmentShaderPass1;
+ code[RgbMaskFragmentShaderPass2] = qopenglslRgbMaskFragmentShaderPass2;
+ code[RgbMaskWithGammaFragmentShader] = ""; //###
+
+ code[NoCompositionModeFragmentShader] = "";
+ code[MultiplyCompositionModeFragmentShader] = ""; //###
+ code[ScreenCompositionModeFragmentShader] = ""; //###
+ code[OverlayCompositionModeFragmentShader] = ""; //###
+ code[DarkenCompositionModeFragmentShader] = ""; //###
+ code[LightenCompositionModeFragmentShader] = ""; //###
+ code[ColorDodgeCompositionModeFragmentShader] = ""; //###
+ code[ColorBurnCompositionModeFragmentShader] = ""; //###
+ code[HardLightCompositionModeFragmentShader] = ""; //###
+ code[SoftLightCompositionModeFragmentShader] = ""; //###
+ code[DifferenceCompositionModeFragmentShader] = ""; //###
+ code[ExclusionCompositionModeFragmentShader] = ""; //###
+
+#if defined(QT_DEBUG)
+ // Check that all the elements have been filled:
+ for (int i = 0; i < TotalSnippetCount; ++i) {
+ if (qShaderSnippets[i] == 0) {
+ qFatal("Shader snippet for %s (#%d) is missing!",
+ snippetNameStr(SnippetName(i)).constData(), i);
+ }
+ }
+#endif
+ snippetsPopulated = true;
+ }
+
+ QOpenGLShader* fragShader;
+ QOpenGLShader* vertexShader;
+ QByteArray vertexSource;
+ QByteArray fragSource;
+
+ // Compile up the simple shader:
+ vertexSource.append(qShaderSnippets[MainVertexShader]);
+ vertexSource.append(qShaderSnippets[PositionOnlyVertexShader]);
+
+ fragSource.append(qShaderSnippets[MainFragmentShader]);
+ fragSource.append(qShaderSnippets[ShockingPinkSrcFragmentShader]);
+
+ simpleShaderProg = new QOpenGLShaderProgram;
+
+ CachedShader simpleShaderCache(fragSource, vertexSource);
+
+ bool inCache = simpleShaderCache.load(simpleShaderProg, context);
+
+ if (!inCache) {
+ vertexShader = new QOpenGLShader(QOpenGLShader::Vertex);
+ shaders.append(vertexShader);
+ if (!vertexShader->compileSourceCode(vertexSource))
+ qWarning("Vertex shader for simpleShaderProg (MainVertexShader & PositionOnlyVertexShader) failed to compile");
+
+ fragShader = new QOpenGLShader(QOpenGLShader::Fragment);
+ shaders.append(fragShader);
+ if (!fragShader->compileSourceCode(fragSource))
+ qWarning("Fragment shader for simpleShaderProg (MainFragmentShader & ShockingPinkSrcFragmentShader) failed to compile");
+
+ simpleShaderProg->addShader(vertexShader);
+ simpleShaderProg->addShader(fragShader);
+
+ simpleShaderProg->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR);
+ simpleShaderProg->bindAttributeLocation("pmvMatrix1", QT_PMV_MATRIX_1_ATTR);
+ simpleShaderProg->bindAttributeLocation("pmvMatrix2", QT_PMV_MATRIX_2_ATTR);
+ simpleShaderProg->bindAttributeLocation("pmvMatrix3", QT_PMV_MATRIX_3_ATTR);
+ }
+
+ simpleShaderProg->link();
+
+ if (simpleShaderProg->isLinked()) {
+ if (!inCache)
+ simpleShaderCache.store(simpleShaderProg, context);
+ } else {
+ qCritical() << "Errors linking simple shader:"
+ << simpleShaderProg->log();
+ }
+
+ // Compile the blit shader:
+ vertexSource.clear();
+ vertexSource.append(qShaderSnippets[MainWithTexCoordsVertexShader]);
+ vertexSource.append(qShaderSnippets[UntransformedPositionVertexShader]);
+
+ fragSource.clear();
+ fragSource.append(qShaderSnippets[MainFragmentShader]);
+ fragSource.append(qShaderSnippets[ImageSrcFragmentShader]);
+
+ blitShaderProg = new QOpenGLShaderProgram;
+
+ CachedShader blitShaderCache(fragSource, vertexSource);
+
+ inCache = blitShaderCache.load(blitShaderProg, context);
+
+ if (!inCache) {
+ vertexShader = new QOpenGLShader(QOpenGLShader::Vertex);
+ shaders.append(vertexShader);
+ if (!vertexShader->compileSourceCode(vertexSource))
+ qWarning("Vertex shader for blitShaderProg (MainWithTexCoordsVertexShader & UntransformedPositionVertexShader) failed to compile");
+
+ fragShader = new QOpenGLShader(QOpenGLShader::Fragment);
+ shaders.append(fragShader);
+ if (!fragShader->compileSourceCode(fragSource))
+ qWarning("Fragment shader for blitShaderProg (MainFragmentShader & ImageSrcFragmentShader) failed to compile");
+
+ blitShaderProg->addShader(vertexShader);
+ blitShaderProg->addShader(fragShader);
+
+ blitShaderProg->bindAttributeLocation("textureCoordArray", QT_TEXTURE_COORDS_ATTR);
+ blitShaderProg->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR);
+ }
+
+ blitShaderProg->link();
+ if (blitShaderProg->isLinked()) {
+ if (!inCache)
+ blitShaderCache.store(blitShaderProg, context);
+ } else {
+ qCritical() << "Errors linking blit shader:"
+ << blitShaderProg->log();
+ }
+
+#ifdef QT_GL_SHARED_SHADER_DEBUG
+ qDebug(" -> QOpenGLEngineSharedShaders() %p for thread %p.", this, QThread::currentThread());
+#endif
+}
+
+QOpenGLEngineSharedShaders::~QOpenGLEngineSharedShaders()
+{
+#ifdef QT_GL_SHARED_SHADER_DEBUG
+ qDebug(" -> ~QOpenGLEngineSharedShaders() %p for thread %p.", this, QThread::currentThread());
+#endif
+ qDeleteAll(shaders);
+ shaders.clear();
+
+ qDeleteAll(cachedPrograms);
+ cachedPrograms.clear();
+
+ if (blitShaderProg) {
+ delete blitShaderProg;
+ blitShaderProg = 0;
+ }
+
+ if (simpleShaderProg) {
+ delete simpleShaderProg;
+ simpleShaderProg = 0;
+ }
+}
+
+#if defined (QT_DEBUG)
+QByteArray QOpenGLEngineSharedShaders::snippetNameStr(SnippetName name)
+{
+ QMetaEnum m = staticMetaObject.enumerator(staticMetaObject.indexOfEnumerator("SnippetName"));
+ return QByteArray(m.valueToKey(name));
+}
+#endif
+
+// The address returned here will only be valid until next time this function is called.
+// The program is return bound.
+QOpenGLEngineShaderProg *QOpenGLEngineSharedShaders::findProgramInCache(const QOpenGLEngineShaderProg &prog)
+{
+ for (int i = 0; i < cachedPrograms.size(); ++i) {
+ QOpenGLEngineShaderProg *cachedProg = cachedPrograms[i];
+ if (*cachedProg == prog) {
+ // Move the program to the top of the list as a poor-man's cache algo
+ cachedPrograms.move(i, 0);
+ cachedProg->program->bind();
+ return cachedProg;
+ }
+ }
+
+ QScopedPointer<QOpenGLEngineShaderProg> newProg;
+
+ do {
+ QByteArray fragSource;
+ // Insert the custom stage before the srcPixel shader to work around an ATI driver bug
+ // where you cannot forward declare a function that takes a sampler as argument.
+ if (prog.srcPixelFragShader == CustomImageSrcFragmentShader)
+ fragSource.append(prog.customStageSource);
+ fragSource.append(qShaderSnippets[prog.mainFragShader]);
+ fragSource.append(qShaderSnippets[prog.srcPixelFragShader]);
+ if (prog.compositionFragShader)
+ fragSource.append(qShaderSnippets[prog.compositionFragShader]);
+ if (prog.maskFragShader)
+ fragSource.append(qShaderSnippets[prog.maskFragShader]);
+
+ QByteArray vertexSource;
+ vertexSource.append(qShaderSnippets[prog.mainVertexShader]);
+ vertexSource.append(qShaderSnippets[prog.positionVertexShader]);
+
+ QScopedPointer<QOpenGLShaderProgram> shaderProgram(new QOpenGLShaderProgram);
+
+ CachedShader shaderCache(fragSource, vertexSource);
+ bool inCache = shaderCache.load(shaderProgram.data(), QOpenGLContext::currentContext());
+
+ if (!inCache) {
+
+ QScopedPointer<QOpenGLShader> fragShader(new QOpenGLShader(QOpenGLShader::Fragment));
+ QByteArray description;
+#if defined(QT_DEBUG)
+ // Name the shader for easier debugging
+ description.append("Fragment shader: main=");
+ description.append(snippetNameStr(prog.mainFragShader));
+ description.append(", srcPixel=");
+ description.append(snippetNameStr(prog.srcPixelFragShader));
+ if (prog.compositionFragShader) {
+ description.append(", composition=");
+ description.append(snippetNameStr(prog.compositionFragShader));
+ }
+ if (prog.maskFragShader) {
+ description.append(", mask=");
+ description.append(snippetNameStr(prog.maskFragShader));
+ }
+ fragShader->setObjectName(QString::fromLatin1(description));
+#endif
+ if (!fragShader->compileSourceCode(fragSource)) {
+ qWarning() << "Warning:" << description << "failed to compile!";
+ break;
+ }
+
+ QScopedPointer<QOpenGLShader> vertexShader(new QOpenGLShader(QOpenGLShader::Vertex));
+#if defined(QT_DEBUG)
+ // Name the shader for easier debugging
+ description.clear();
+ description.append("Vertex shader: main=");
+ description.append(snippetNameStr(prog.mainVertexShader));
+ description.append(", position=");
+ description.append(snippetNameStr(prog.positionVertexShader));
+ vertexShader->setObjectName(QString::fromLatin1(description));
+#endif
+ if (!vertexShader->compileSourceCode(vertexSource)) {
+ qWarning() << "Warning:" << description << "failed to compile!";
+ break;
+ }
+
+ shaders.append(vertexShader.data());
+ shaders.append(fragShader.data());
+ shaderProgram->addShader(vertexShader.take());
+ shaderProgram->addShader(fragShader.take());
+
+ // We have to bind the vertex attribute names before the program is linked:
+ shaderProgram->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR);
+ if (prog.useTextureCoords)
+ shaderProgram->bindAttributeLocation("textureCoordArray", QT_TEXTURE_COORDS_ATTR);
+ if (prog.useOpacityAttribute)
+ shaderProgram->bindAttributeLocation("opacityArray", QT_OPACITY_ATTR);
+ if (prog.usePmvMatrixAttribute) {
+ shaderProgram->bindAttributeLocation("pmvMatrix1", QT_PMV_MATRIX_1_ATTR);
+ shaderProgram->bindAttributeLocation("pmvMatrix2", QT_PMV_MATRIX_2_ATTR);
+ shaderProgram->bindAttributeLocation("pmvMatrix3", QT_PMV_MATRIX_3_ATTR);
+ }
+ }
+
+ newProg.reset(new QOpenGLEngineShaderProg(prog));
+ newProg->program = shaderProgram.take();
+
+ newProg->program->link();
+ if (newProg->program->isLinked()) {
+ if (!inCache)
+ shaderCache.store(newProg->program, QOpenGLContext::currentContext());
+ } else {
+ QLatin1String none("none");
+ QLatin1String br("\n");
+ QString error;
+ error = QLatin1String("Shader program failed to link,");
+#if defined(QT_DEBUG)
+ error += QLatin1String("\n Shaders Used:\n");
+ for (int i = 0; i < newProg->program->shaders().count(); ++i) {
+ QOpenGLShader *shader = newProg->program->shaders().at(i);
+ error += QLatin1String(" ") + shader->objectName() + QLatin1String(": \n")
+ + QLatin1String(shader->sourceCode()) + br;
+ }
+#endif
+ error += QLatin1String(" Error Log:\n")
+ + QLatin1String(" ") + newProg->program->log();
+ qWarning() << error;
+ break;
+ }
+
+ newProg->program->bind();
+
+ if (newProg->maskFragShader != QOpenGLEngineSharedShaders::NoMaskFragmentShader) {
+ GLuint location = newProg->program->uniformLocation("maskTexture");
+ newProg->program->setUniformValue(location, QT_MASK_TEXTURE_UNIT);
+ }
+
+ if (cachedPrograms.count() > 30) {
+ // The cache is full, so delete the last 5 programs in the list.
+ // These programs will be least used, as a program us bumped to
+ // the top of the list when it's used.
+ for (int i = 0; i < 5; ++i) {
+ delete cachedPrograms.last();
+ cachedPrograms.removeLast();
+ }
+ }
+
+ cachedPrograms.insert(0, newProg.data());
+ } while (false);
+
+ return newProg.take();
+}
+
+void QOpenGLEngineSharedShaders::cleanupCustomStage(QOpenGLCustomShaderStage* stage)
+{
+ // Remove any shader programs which has this as the custom shader src:
+ for (int i = 0; i < cachedPrograms.size(); ++i) {
+ QOpenGLEngineShaderProg *cachedProg = cachedPrograms[i];
+ if (cachedProg->customStageSource == stage->source()) {
+ delete cachedProg;
+ cachedPrograms.removeAt(i);
+ i--;
+ }
+ }
+}
+
+
+QOpenGLEngineShaderManager::QOpenGLEngineShaderManager(QOpenGLContext* context)
+ : ctx(context),
+ shaderProgNeedsChanging(true),
+ complexGeometry(false),
+ srcPixelType(Qt::NoBrush),
+ opacityMode(NoOpacity),
+ maskType(NoMask),
+ compositionMode(QPainter::CompositionMode_SourceOver),
+ customSrcStage(0),
+ currentShaderProg(0)
+{
+ sharedShaders = QOpenGLEngineSharedShaders::shadersForContext(context);
+}
+
+QOpenGLEngineShaderManager::~QOpenGLEngineShaderManager()
+{
+ //###
+ removeCustomStage();
+}
+
+GLuint QOpenGLEngineShaderManager::getUniformLocation(Uniform id)
+{
+ if (!currentShaderProg)
+ return 0;
+
+ QVector<uint> &uniformLocations = currentShaderProg->uniformLocations;
+ if (uniformLocations.isEmpty())
+ uniformLocations.fill(GLuint(-1), NumUniforms);
+
+ static const char *uniformNames[] = {
+ "imageTexture",
+ "patternColor",
+ "globalOpacity",
+ "depth",
+ "maskTexture",
+ "fragmentColor",
+ "linearData",
+ "angle",
+ "halfViewportSize",
+ "fmp",
+ "fmp2_m_radius2",
+ "inverse_2_fmp2_m_radius2",
+ "sqrfr",
+ "bradius",
+ "invertedTextureSize",
+ "brushTransform",
+ "brushTexture",
+ "matrix"
+ };
+
+ if (uniformLocations.at(id) == GLuint(-1))
+ uniformLocations[id] = currentShaderProg->program->uniformLocation(uniformNames[id]);
+
+ return uniformLocations.at(id);
+}
+
+
+void QOpenGLEngineShaderManager::optimiseForBrushTransform(QTransform::TransformationType transformType)
+{
+ Q_UNUSED(transformType); // Currently ignored
+}
+
+void QOpenGLEngineShaderManager::setDirty()
+{
+ shaderProgNeedsChanging = true;
+}
+
+void QOpenGLEngineShaderManager::setSrcPixelType(Qt::BrushStyle style)
+{
+ Q_ASSERT(style != Qt::NoBrush);
+ if (srcPixelType == PixelSrcType(style))
+ return;
+
+ srcPixelType = style;
+ shaderProgNeedsChanging = true; //###
+}
+
+void QOpenGLEngineShaderManager::setSrcPixelType(PixelSrcType type)
+{
+ if (srcPixelType == type)
+ return;
+
+ srcPixelType = type;
+ shaderProgNeedsChanging = true; //###
+}
+
+void QOpenGLEngineShaderManager::setOpacityMode(OpacityMode mode)
+{
+ if (opacityMode == mode)
+ return;
+
+ opacityMode = mode;
+ shaderProgNeedsChanging = true; //###
+}
+
+void QOpenGLEngineShaderManager::setMaskType(MaskType type)
+{
+ if (maskType == type)
+ return;
+
+ maskType = type;
+ shaderProgNeedsChanging = true; //###
+}
+
+void QOpenGLEngineShaderManager::setCompositionMode(QPainter::CompositionMode mode)
+{
+ if (compositionMode == mode)
+ return;
+
+ compositionMode = mode;
+ shaderProgNeedsChanging = true; //###
+}
+
+void QOpenGLEngineShaderManager::setCustomStage(QOpenGLCustomShaderStage* stage)
+{
+ if (customSrcStage)
+ removeCustomStage();
+ customSrcStage = stage;
+ shaderProgNeedsChanging = true;
+}
+
+void QOpenGLEngineShaderManager::removeCustomStage()
+{
+ if (customSrcStage)
+ customSrcStage->setInactive();
+ customSrcStage = 0;
+ shaderProgNeedsChanging = true;
+}
+
+QOpenGLShaderProgram* QOpenGLEngineShaderManager::currentProgram()
+{
+ if (currentShaderProg)
+ return currentShaderProg->program;
+ else
+ return sharedShaders->simpleProgram();
+}
+
+void QOpenGLEngineShaderManager::useSimpleProgram()
+{
+ sharedShaders->simpleProgram()->bind();
+ QOpenGLContextPrivate* ctx_d = ctx->d_func();
+ Q_UNUSED(ctx_d);
+
+ QOpenGL2PaintEngineEx *active_engine = static_cast<QOpenGL2PaintEngineEx *>(ctx_d->active_engine);
+
+ active_engine->d_func()->setVertexAttribArrayEnabled(QT_VERTEX_COORDS_ATTR, true);
+ active_engine->d_func()->setVertexAttribArrayEnabled(QT_TEXTURE_COORDS_ATTR, false);
+ active_engine->d_func()->setVertexAttribArrayEnabled(QT_OPACITY_ATTR, false);
+
+ shaderProgNeedsChanging = true;
+}
+
+void QOpenGLEngineShaderManager::useBlitProgram()
+{
+ sharedShaders->blitProgram()->bind();
+ QOpenGLContextPrivate* ctx_d = ctx->d_func();
+ QOpenGL2PaintEngineEx *active_engine = static_cast<QOpenGL2PaintEngineEx *>(ctx_d->active_engine);
+ active_engine->d_func()->setVertexAttribArrayEnabled(QT_VERTEX_COORDS_ATTR, true);
+ active_engine->d_func()->setVertexAttribArrayEnabled(QT_TEXTURE_COORDS_ATTR, true);
+ active_engine->d_func()->setVertexAttribArrayEnabled(QT_OPACITY_ATTR, false);
+ shaderProgNeedsChanging = true;
+}
+
+QOpenGLShaderProgram* QOpenGLEngineShaderManager::simpleProgram()
+{
+ return sharedShaders->simpleProgram();
+}
+
+QOpenGLShaderProgram* QOpenGLEngineShaderManager::blitProgram()
+{
+ return sharedShaders->blitProgram();
+}
+
+
+
+// Select & use the correct shader program using the current state.
+// Returns true if program needed changing.
+bool QOpenGLEngineShaderManager::useCorrectShaderProg()
+{
+ if (!shaderProgNeedsChanging)
+ return false;
+
+ bool useCustomSrc = customSrcStage != 0;
+ if (useCustomSrc && srcPixelType != QOpenGLEngineShaderManager::ImageSrc && srcPixelType != Qt::TexturePattern) {
+ useCustomSrc = false;
+ qWarning("QOpenGLEngineShaderManager - Ignoring custom shader stage for non image src");
+ }
+
+ QOpenGLEngineShaderProg requiredProgram;
+
+ bool texCoords = false;
+
+ // Choose vertex shader shader position function (which typically also sets
+ // varyings) and the source pixel (srcPixel) fragment shader function:
+ requiredProgram.positionVertexShader = QOpenGLEngineSharedShaders::InvalidSnippetName;
+ requiredProgram.srcPixelFragShader = QOpenGLEngineSharedShaders::InvalidSnippetName;
+ bool isAffine = brushTransform.isAffine();
+ if ( (srcPixelType >= Qt::Dense1Pattern) && (srcPixelType <= Qt::DiagCrossPattern) ) {
+ if (isAffine)
+ requiredProgram.positionVertexShader = QOpenGLEngineSharedShaders::AffinePositionWithPatternBrushVertexShader;
+ else
+ requiredProgram.positionVertexShader = QOpenGLEngineSharedShaders::PositionWithPatternBrushVertexShader;
+
+ requiredProgram.srcPixelFragShader = QOpenGLEngineSharedShaders::PatternBrushSrcFragmentShader;
+ }
+ else switch (srcPixelType) {
+ default:
+ case Qt::NoBrush:
+ qFatal("QOpenGLEngineShaderManager::useCorrectShaderProg() - Qt::NoBrush style is set");
+ break;
+ case QOpenGLEngineShaderManager::ImageSrc:
+ requiredProgram.srcPixelFragShader = QOpenGLEngineSharedShaders::ImageSrcFragmentShader;
+ requiredProgram.positionVertexShader = QOpenGLEngineSharedShaders::PositionOnlyVertexShader;
+ texCoords = true;
+ break;
+ case QOpenGLEngineShaderManager::NonPremultipliedImageSrc:
+ requiredProgram.srcPixelFragShader = QOpenGLEngineSharedShaders::NonPremultipliedImageSrcFragmentShader;
+ requiredProgram.positionVertexShader = QOpenGLEngineSharedShaders::PositionOnlyVertexShader;
+ texCoords = true;
+ break;
+ case QOpenGLEngineShaderManager::PatternSrc:
+ requiredProgram.srcPixelFragShader = QOpenGLEngineSharedShaders::ImageSrcWithPatternFragmentShader;
+ requiredProgram.positionVertexShader = QOpenGLEngineSharedShaders::PositionOnlyVertexShader;
+ texCoords = true;
+ break;
+ case QOpenGLEngineShaderManager::TextureSrcWithPattern:
+ requiredProgram.srcPixelFragShader = QOpenGLEngineSharedShaders::TextureBrushSrcWithPatternFragmentShader;
+ requiredProgram.positionVertexShader = isAffine ? QOpenGLEngineSharedShaders::AffinePositionWithTextureBrushVertexShader
+ : QOpenGLEngineSharedShaders::PositionWithTextureBrushVertexShader;
+ break;
+ case Qt::SolidPattern:
+ requiredProgram.srcPixelFragShader = QOpenGLEngineSharedShaders::SolidBrushSrcFragmentShader;
+ requiredProgram.positionVertexShader = QOpenGLEngineSharedShaders::PositionOnlyVertexShader;
+ break;
+ case Qt::LinearGradientPattern:
+ requiredProgram.srcPixelFragShader = QOpenGLEngineSharedShaders::LinearGradientBrushSrcFragmentShader;
+ requiredProgram.positionVertexShader = isAffine ? QOpenGLEngineSharedShaders::AffinePositionWithLinearGradientBrushVertexShader
+ : QOpenGLEngineSharedShaders::PositionWithLinearGradientBrushVertexShader;
+ break;
+ case Qt::ConicalGradientPattern:
+ requiredProgram.srcPixelFragShader = QOpenGLEngineSharedShaders::ConicalGradientBrushSrcFragmentShader;
+ requiredProgram.positionVertexShader = isAffine ? QOpenGLEngineSharedShaders::AffinePositionWithConicalGradientBrushVertexShader
+ : QOpenGLEngineSharedShaders::PositionWithConicalGradientBrushVertexShader;
+ break;
+ case Qt::RadialGradientPattern:
+ requiredProgram.srcPixelFragShader = QOpenGLEngineSharedShaders::RadialGradientBrushSrcFragmentShader;
+ requiredProgram.positionVertexShader = isAffine ? QOpenGLEngineSharedShaders::AffinePositionWithRadialGradientBrushVertexShader
+ : QOpenGLEngineSharedShaders::PositionWithRadialGradientBrushVertexShader;
+ break;
+ case Qt::TexturePattern:
+ requiredProgram.srcPixelFragShader = QOpenGLEngineSharedShaders::TextureBrushSrcFragmentShader;
+ requiredProgram.positionVertexShader = isAffine ? QOpenGLEngineSharedShaders::AffinePositionWithTextureBrushVertexShader
+ : QOpenGLEngineSharedShaders::PositionWithTextureBrushVertexShader;
+ break;
+ };
+
+ if (useCustomSrc) {
+ requiredProgram.srcPixelFragShader = QOpenGLEngineSharedShaders::CustomImageSrcFragmentShader;
+ requiredProgram.customStageSource = customSrcStage->source();
+ }
+
+ const bool hasCompose = compositionMode > QPainter::CompositionMode_Plus;
+ const bool hasMask = maskType != QOpenGLEngineShaderManager::NoMask;
+
+ // Choose fragment shader main function:
+ if (opacityMode == AttributeOpacity) {
+ Q_ASSERT(!hasCompose && !hasMask);
+ requiredProgram.mainFragShader = QOpenGLEngineSharedShaders::MainFragmentShader_ImageArrays;
+ } else {
+ bool useGlobalOpacity = (opacityMode == UniformOpacity);
+ if (hasCompose && hasMask && useGlobalOpacity)
+ requiredProgram.mainFragShader = QOpenGLEngineSharedShaders::MainFragmentShader_CMO;
+ if (hasCompose && hasMask && !useGlobalOpacity)
+ requiredProgram.mainFragShader = QOpenGLEngineSharedShaders::MainFragmentShader_CM;
+ if (!hasCompose && hasMask && useGlobalOpacity)
+ requiredProgram.mainFragShader = QOpenGLEngineSharedShaders::MainFragmentShader_MO;
+ if (!hasCompose && hasMask && !useGlobalOpacity)
+ requiredProgram.mainFragShader = QOpenGLEngineSharedShaders::MainFragmentShader_M;
+ if (hasCompose && !hasMask && useGlobalOpacity)
+ requiredProgram.mainFragShader = QOpenGLEngineSharedShaders::MainFragmentShader_CO;
+ if (hasCompose && !hasMask && !useGlobalOpacity)
+ requiredProgram.mainFragShader = QOpenGLEngineSharedShaders::MainFragmentShader_C;
+ if (!hasCompose && !hasMask && useGlobalOpacity)
+ requiredProgram.mainFragShader = QOpenGLEngineSharedShaders::MainFragmentShader_O;
+ if (!hasCompose && !hasMask && !useGlobalOpacity)
+ requiredProgram.mainFragShader = QOpenGLEngineSharedShaders::MainFragmentShader;
+ }
+
+ if (hasMask) {
+ if (maskType == PixelMask) {
+ requiredProgram.maskFragShader = QOpenGLEngineSharedShaders::MaskFragmentShader;
+ texCoords = true;
+ } else if (maskType == SubPixelMaskPass1) {
+ requiredProgram.maskFragShader = QOpenGLEngineSharedShaders::RgbMaskFragmentShaderPass1;
+ texCoords = true;
+ } else if (maskType == SubPixelMaskPass2) {
+ requiredProgram.maskFragShader = QOpenGLEngineSharedShaders::RgbMaskFragmentShaderPass2;
+ texCoords = true;
+ } else if (maskType == SubPixelWithGammaMask) {
+ requiredProgram.maskFragShader = QOpenGLEngineSharedShaders::RgbMaskWithGammaFragmentShader;
+ texCoords = true;
+ } else {
+ qCritical("QOpenGLEngineShaderManager::useCorrectShaderProg() - Unknown mask type");
+ }
+ } else {
+ requiredProgram.maskFragShader = QOpenGLEngineSharedShaders::NoMaskFragmentShader;
+ }
+
+ if (hasCompose) {
+ switch (compositionMode) {
+ case QPainter::CompositionMode_Multiply:
+ requiredProgram.compositionFragShader = QOpenGLEngineSharedShaders::MultiplyCompositionModeFragmentShader;
+ break;
+ case QPainter::CompositionMode_Screen:
+ requiredProgram.compositionFragShader = QOpenGLEngineSharedShaders::ScreenCompositionModeFragmentShader;
+ break;
+ case QPainter::CompositionMode_Overlay:
+ requiredProgram.compositionFragShader = QOpenGLEngineSharedShaders::OverlayCompositionModeFragmentShader;
+ break;
+ case QPainter::CompositionMode_Darken:
+ requiredProgram.compositionFragShader = QOpenGLEngineSharedShaders::DarkenCompositionModeFragmentShader;
+ break;
+ case QPainter::CompositionMode_Lighten:
+ requiredProgram.compositionFragShader = QOpenGLEngineSharedShaders::LightenCompositionModeFragmentShader;
+ break;
+ case QPainter::CompositionMode_ColorDodge:
+ requiredProgram.compositionFragShader = QOpenGLEngineSharedShaders::ColorDodgeCompositionModeFragmentShader;
+ break;
+ case QPainter::CompositionMode_ColorBurn:
+ requiredProgram.compositionFragShader = QOpenGLEngineSharedShaders::ColorBurnCompositionModeFragmentShader;
+ break;
+ case QPainter::CompositionMode_HardLight:
+ requiredProgram.compositionFragShader = QOpenGLEngineSharedShaders::HardLightCompositionModeFragmentShader;
+ break;
+ case QPainter::CompositionMode_SoftLight:
+ requiredProgram.compositionFragShader = QOpenGLEngineSharedShaders::SoftLightCompositionModeFragmentShader;
+ break;
+ case QPainter::CompositionMode_Difference:
+ requiredProgram.compositionFragShader = QOpenGLEngineSharedShaders::DifferenceCompositionModeFragmentShader;
+ break;
+ case QPainter::CompositionMode_Exclusion:
+ requiredProgram.compositionFragShader = QOpenGLEngineSharedShaders::ExclusionCompositionModeFragmentShader;
+ break;
+ default:
+ qWarning("QOpenGLEngineShaderManager::useCorrectShaderProg() - Unsupported composition mode");
+ }
+ } else {
+ requiredProgram.compositionFragShader = QOpenGLEngineSharedShaders::NoCompositionModeFragmentShader;
+ }
+
+ // Choose vertex shader main function
+ if (opacityMode == AttributeOpacity) {
+ Q_ASSERT(texCoords);
+ requiredProgram.mainVertexShader = QOpenGLEngineSharedShaders::MainWithTexCoordsAndOpacityVertexShader;
+ } else if (texCoords) {
+ requiredProgram.mainVertexShader = QOpenGLEngineSharedShaders::MainWithTexCoordsVertexShader;
+ } else {
+ requiredProgram.mainVertexShader = QOpenGLEngineSharedShaders::MainVertexShader;
+ }
+ requiredProgram.useTextureCoords = texCoords;
+ requiredProgram.useOpacityAttribute = (opacityMode == AttributeOpacity);
+ if (complexGeometry && srcPixelType == Qt::SolidPattern) {
+ requiredProgram.positionVertexShader = QOpenGLEngineSharedShaders::ComplexGeometryPositionOnlyVertexShader;
+ requiredProgram.usePmvMatrixAttribute = false;
+ } else {
+ requiredProgram.usePmvMatrixAttribute = true;
+
+ // Force complexGeometry off, since we currently don't support that mode for
+ // non-solid brushes
+ complexGeometry = false;
+ }
+
+ // At this point, requiredProgram is fully populated so try to find the program in the cache
+ currentShaderProg = sharedShaders->findProgramInCache(requiredProgram);
+
+ if (currentShaderProg && useCustomSrc) {
+ customSrcStage->setUniforms(currentShaderProg->program);
+ }
+
+ // Make sure all the vertex attribute arrays the program uses are enabled (and the ones it
+ // doesn't use are disabled)
+ QOpenGLContextPrivate* ctx_d = ctx->d_func();
+ QOpenGL2PaintEngineEx *active_engine = static_cast<QOpenGL2PaintEngineEx *>(ctx_d->active_engine);
+ active_engine->d_func()->setVertexAttribArrayEnabled(QT_VERTEX_COORDS_ATTR, true);
+ active_engine->d_func()->setVertexAttribArrayEnabled(QT_TEXTURE_COORDS_ATTR, currentShaderProg && currentShaderProg->useTextureCoords);
+ active_engine->d_func()->setVertexAttribArrayEnabled(QT_OPACITY_ATTR, currentShaderProg && currentShaderProg->useOpacityAttribute);
+
+ shaderProgNeedsChanging = false;
+ return true;
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/opengl/qopenglengineshadermanager_p.h b/src/gui/opengl/qopenglengineshadermanager_p.h
new file mode 100644
index 0000000000..1dcc4fe7a7
--- /dev/null
+++ b/src/gui/opengl/qopenglengineshadermanager_p.h
@@ -0,0 +1,514 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+/*
+ VERTEX SHADERS
+ ==============
+
+ Vertex shaders are specified as multiple (partial) shaders. On desktop,
+ this works fine. On ES, QOpenGLShader & QOpenGLShaderProgram will make partial
+ shaders work by concatenating the source in each QOpenGLShader and compiling
+ it as a single shader. This is abstracted nicely by QOpenGLShaderProgram and
+ the GL2 engine doesn't need to worry about it.
+
+ Generally, there's two vertex shader objects. The position shaders are
+ the ones which set gl_Position. There's also two "main" vertex shaders,
+ one which just calls the position shader and another which also passes
+ through some texture coordinates from a vertex attribute array to a
+ varying. These texture coordinates are used for mask position in text
+ rendering and for the source coordinates in drawImage/drawPixmap. There's
+ also a "Simple" vertex shader for rendering a solid colour (used to render
+ into the stencil buffer where the actual colour value is discarded).
+
+ The position shaders for brushes look scary. This is because many of the
+ calculations which logically belong in the fragment shader have been moved
+ into the vertex shader to improve performance. This is why the position
+ calculation is in a separate shader. Not only does it calculate the
+ position, but it also calculates some data to be passed to the fragment
+ shader as a varying. It is optimal to move as much of the calculation as
+ possible into the vertex shader as this is executed less often.
+
+ The varyings passed to the fragment shaders are interpolated (which is
+ cheap). Unfortunately, GL will apply perspective correction to the
+ interpolation calusing errors. To get around this, the vertex shader must
+ apply perspective correction itself and set the w-value of gl_Position to
+ zero. That way, GL will be tricked into thinking it doesn't need to apply a
+ perspective correction and use linear interpolation instead (which is what
+ we want). Of course, if the brush transform is affeine, no perspective
+ correction is needed and a simpler vertex shader can be used instead.
+
+ So there are the following "main" vertex shaders:
+ qopenglslMainVertexShader
+ qopenglslMainWithTexCoordsVertexShader
+
+ And the the following position vertex shaders:
+ qopenglslPositionOnlyVertexShader
+ qopenglslPositionWithTextureBrushVertexShader
+ qopenglslPositionWithPatternBrushVertexShader
+ qopenglslPositionWithLinearGradientBrushVertexShader
+ qopenglslPositionWithRadialGradientBrushVertexShader
+ qopenglslPositionWithConicalGradientBrushVertexShader
+ qopenglslAffinePositionWithTextureBrushVertexShader
+ qopenglslAffinePositionWithPatternBrushVertexShader
+ qopenglslAffinePositionWithLinearGradientBrushVertexShader
+ qopenglslAffinePositionWithRadialGradientBrushVertexShader
+ qopenglslAffinePositionWithConicalGradientBrushVertexShader
+
+ Leading to 23 possible vertex shaders
+
+
+ FRAGMENT SHADERS
+ ================
+
+ Fragment shaders are also specified as multiple (partial) shaders. The
+ different fragment shaders represent the different stages in Qt's fragment
+ pipeline. There are 1-3 stages in this pipeline: First stage is to get the
+ fragment's colour value. The next stage is to get the fragment's mask value
+ (coverage value for anti-aliasing) and the final stage is to blend the
+ incoming fragment with the background (for composition modes not supported
+ by GL).
+
+ Of these, the first stage will always be present. If Qt doesn't need to
+ apply anti-aliasing (because it's off or handled by multisampling) then
+ the coverage value doesn't need to be applied. (Note: There are two types
+ of mask, one for regular anti-aliasing and one for sub-pixel anti-
+ aliasing.) If the composition mode is one which GL supports natively then
+ the blending stage doesn't need to be applied.
+
+ As eash stage can have multiple implementations, they are abstracted as
+ GLSL function calls with the following signatures:
+
+ Brushes & image drawing are implementations of "qcolorp vec4 srcPixel()":
+ qopenglslImageSrcFragShader
+ qopenglslImageSrcWithPatternFragShader
+ qopenglslNonPremultipliedImageSrcFragShader
+ qopenglslSolidBrushSrcFragShader
+ qopenglslTextureBrushSrcFragShader
+ qopenglslTextureBrushWithPatternFragShader
+ qopenglslPatternBrushSrcFragShader
+ qopenglslLinearGradientBrushSrcFragShader
+ qopenglslRadialGradientBrushSrcFragShader
+ qopenglslConicalGradientBrushSrcFragShader
+ NOTE: It is assumed the colour returned by srcPixel() is pre-multiplied
+
+ Masks are implementations of "qcolorp vec4 applyMask(qcolorp vec4 src)":
+ qopenglslMaskFragmentShader
+ qopenglslRgbMaskFragmentShaderPass1
+ qopenglslRgbMaskFragmentShaderPass2
+ qopenglslRgbMaskWithGammaFragmentShader
+
+ Composition modes are "qcolorp vec4 compose(qcolorp vec4 src)":
+ qopenglslColorBurnCompositionModeFragmentShader
+ qopenglslColorDodgeCompositionModeFragmentShader
+ qopenglslDarkenCompositionModeFragmentShader
+ qopenglslDifferenceCompositionModeFragmentShader
+ qopenglslExclusionCompositionModeFragmentShader
+ qopenglslHardLightCompositionModeFragmentShader
+ qopenglslLightenCompositionModeFragmentShader
+ qopenglslMultiplyCompositionModeFragmentShader
+ qopenglslOverlayCompositionModeFragmentShader
+ qopenglslScreenCompositionModeFragmentShader
+ qopenglslSoftLightCompositionModeFragmentShader
+
+
+ Note: In the future, some GLSL compilers will support an extension allowing
+ a new 'color' precision specifier. To support this, qcolorp is used for
+ all color components so it can be defined to colorp or lowp depending upon
+ the implementation.
+
+ So there are differnt frament shader main functions, depending on the
+ number & type of pipelines the fragment needs to go through.
+
+ The choice of which main() fragment shader string to use depends on:
+ - Use of global opacity
+ - Brush style (some brushes apply opacity themselves)
+ - Use & type of mask (TODO: Need to support high quality anti-aliasing & text)
+ - Use of non-GL Composition mode
+
+ Leading to the following fragment shader main functions:
+ gl_FragColor = compose(applyMask(srcPixel()*globalOpacity));
+ gl_FragColor = compose(applyMask(srcPixel()));
+ gl_FragColor = applyMask(srcPixel()*globalOpacity);
+ gl_FragColor = applyMask(srcPixel());
+ gl_FragColor = compose(srcPixel()*globalOpacity);
+ gl_FragColor = compose(srcPixel());
+ gl_FragColor = srcPixel()*globalOpacity;
+ gl_FragColor = srcPixel();
+
+ Called:
+ qopenglslMainFragmentShader_CMO
+ qopenglslMainFragmentShader_CM
+ qopenglslMainFragmentShader_MO
+ qopenglslMainFragmentShader_M
+ qopenglslMainFragmentShader_CO
+ qopenglslMainFragmentShader_C
+ qopenglslMainFragmentShader_O
+ qopenglslMainFragmentShader
+
+ Where:
+ M = Mask
+ C = Composition
+ O = Global Opacity
+
+
+ CUSTOM SHADER CODE
+ ==================
+
+ The use of custom shader code is supported by the engine for drawImage and
+ drawPixmap calls. This is implemented via hooks in the fragment pipeline.
+
+ The custom shader is passed to the engine as a partial fragment shader
+ (QOpenGLCustomShaderStage). The shader will implement a pre-defined method name
+ which Qt's fragment pipeline will call:
+
+ lowp vec4 customShader(lowp sampler2d imageTexture, highp vec2 textureCoords)
+
+ The provided src and srcCoords parameters can be used to sample from the
+ source image.
+
+ Transformations, clipping, opacity, and composition modes set using QPainter
+ will be respected when using the custom shader hook.
+*/
+
+#ifndef QOPENGLENGINE_SHADER_MANAGER_H
+#define QOPENGLENGINE_SHADER_MANAGER_H
+
+#include <QOpenGLShader>
+#include <QOpenGLShaderProgram>
+#include <QPainter>
+#include <private/qopenglcontext_p.h>
+#include <private/qopenglcustomshaderstage_p.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+
+/*
+struct QOpenGLEngineCachedShaderProg
+{
+ QOpenGLEngineCachedShaderProg(QOpenGLEngineShaderManager::ShaderName vertexMain,
+ QOpenGLEngineShaderManager::ShaderName vertexPosition,
+ QOpenGLEngineShaderManager::ShaderName fragMain,
+ QOpenGLEngineShaderManager::ShaderName pixelSrc,
+ QOpenGLEngineShaderManager::ShaderName mask,
+ QOpenGLEngineShaderManager::ShaderName composition);
+
+ int cacheKey;
+ QOpenGLShaderProgram* program;
+}
+*/
+
+static const GLuint QT_VERTEX_COORDS_ATTR = 0;
+static const GLuint QT_TEXTURE_COORDS_ATTR = 1;
+static const GLuint QT_OPACITY_ATTR = 2;
+static const GLuint QT_PMV_MATRIX_1_ATTR = 3;
+static const GLuint QT_PMV_MATRIX_2_ATTR = 4;
+static const GLuint QT_PMV_MATRIX_3_ATTR = 5;
+
+class QOpenGLEngineShaderProg;
+
+class Q_GUI_EXPORT QOpenGLEngineSharedShaders
+{
+ Q_GADGET
+public:
+
+ enum SnippetName {
+ MainVertexShader,
+ MainWithTexCoordsVertexShader,
+ MainWithTexCoordsAndOpacityVertexShader,
+
+ // UntransformedPositionVertexShader must be first in the list:
+ UntransformedPositionVertexShader,
+ PositionOnlyVertexShader,
+ ComplexGeometryPositionOnlyVertexShader,
+ PositionWithPatternBrushVertexShader,
+ PositionWithLinearGradientBrushVertexShader,
+ PositionWithConicalGradientBrushVertexShader,
+ PositionWithRadialGradientBrushVertexShader,
+ PositionWithTextureBrushVertexShader,
+ AffinePositionWithPatternBrushVertexShader,
+ AffinePositionWithLinearGradientBrushVertexShader,
+ AffinePositionWithConicalGradientBrushVertexShader,
+ AffinePositionWithRadialGradientBrushVertexShader,
+ AffinePositionWithTextureBrushVertexShader,
+
+ // MainFragmentShader_CMO must be first in the list:
+ MainFragmentShader_CMO,
+ MainFragmentShader_CM,
+ MainFragmentShader_MO,
+ MainFragmentShader_M,
+ MainFragmentShader_CO,
+ MainFragmentShader_C,
+ MainFragmentShader_O,
+ MainFragmentShader,
+ MainFragmentShader_ImageArrays,
+
+ // ImageSrcFragmentShader must be first in the list::
+ ImageSrcFragmentShader,
+ ImageSrcWithPatternFragmentShader,
+ NonPremultipliedImageSrcFragmentShader,
+ CustomImageSrcFragmentShader,
+ SolidBrushSrcFragmentShader,
+ TextureBrushSrcFragmentShader,
+ TextureBrushSrcWithPatternFragmentShader,
+ PatternBrushSrcFragmentShader,
+ LinearGradientBrushSrcFragmentShader,
+ RadialGradientBrushSrcFragmentShader,
+ ConicalGradientBrushSrcFragmentShader,
+ ShockingPinkSrcFragmentShader,
+
+ // NoMaskFragmentShader must be first in the list:
+ NoMaskFragmentShader,
+ MaskFragmentShader,
+ RgbMaskFragmentShaderPass1,
+ RgbMaskFragmentShaderPass2,
+ RgbMaskWithGammaFragmentShader,
+
+ // NoCompositionModeFragmentShader must be first in the list:
+ NoCompositionModeFragmentShader,
+ MultiplyCompositionModeFragmentShader,
+ ScreenCompositionModeFragmentShader,
+ OverlayCompositionModeFragmentShader,
+ DarkenCompositionModeFragmentShader,
+ LightenCompositionModeFragmentShader,
+ ColorDodgeCompositionModeFragmentShader,
+ ColorBurnCompositionModeFragmentShader,
+ HardLightCompositionModeFragmentShader,
+ SoftLightCompositionModeFragmentShader,
+ DifferenceCompositionModeFragmentShader,
+ ExclusionCompositionModeFragmentShader,
+
+ TotalSnippetCount, InvalidSnippetName
+ };
+#if defined (QT_DEBUG)
+ Q_ENUMS(SnippetName)
+ static QByteArray snippetNameStr(SnippetName snippetName);
+#endif
+
+/*
+ // These allow the ShaderName enum to be used as a cache key
+ const int mainVertexOffset = 0;
+ const int positionVertexOffset = (1<<2) - PositionOnlyVertexShader;
+ const int mainFragOffset = (1<<6) - MainFragmentShader_CMO;
+ const int srcPixelOffset = (1<<10) - ImageSrcFragmentShader;
+ const int maskOffset = (1<<14) - NoMaskShader;
+ const int compositionOffset = (1 << 16) - MultiplyCompositionModeFragmentShader;
+*/
+
+ QOpenGLEngineSharedShaders(QOpenGLContext *context);
+ ~QOpenGLEngineSharedShaders();
+
+ QOpenGLShaderProgram *simpleProgram() { return simpleShaderProg; }
+ QOpenGLShaderProgram *blitProgram() { return blitShaderProg; }
+ // Compile the program if it's not already in the cache, return the item in the cache.
+ QOpenGLEngineShaderProg *findProgramInCache(const QOpenGLEngineShaderProg &prog);
+ // Compile the custom shader if it's not already in the cache, return the item in the cache.
+
+ static QOpenGLEngineSharedShaders *shadersForContext(QOpenGLContext *context);
+
+ // Ideally, this would be static and cleanup all programs in all contexts which
+ // contain the custom code. Currently it is just a hint and we rely on deleted
+ // custom shaders being cleaned up by being kicked out of the cache when it's
+ // full.
+ void cleanupCustomStage(QOpenGLCustomShaderStage* stage);
+
+private:
+ QOpenGLShaderProgram *blitShaderProg;
+ QOpenGLShaderProgram *simpleShaderProg;
+ QList<QOpenGLEngineShaderProg*> cachedPrograms;
+ QList<QOpenGLShader *> shaders;
+
+ static const char* qShaderSnippets[TotalSnippetCount];
+};
+
+
+class QOpenGLEngineShaderProg
+{
+public:
+ QOpenGLEngineShaderProg() : program(0) {}
+
+ ~QOpenGLEngineShaderProg() {
+ if (program)
+ delete program;
+ }
+
+ QOpenGLEngineSharedShaders::SnippetName mainVertexShader;
+ QOpenGLEngineSharedShaders::SnippetName positionVertexShader;
+ QOpenGLEngineSharedShaders::SnippetName mainFragShader;
+ QOpenGLEngineSharedShaders::SnippetName srcPixelFragShader;
+ QOpenGLEngineSharedShaders::SnippetName maskFragShader;
+ QOpenGLEngineSharedShaders::SnippetName compositionFragShader;
+
+ QByteArray customStageSource; //TODO: Decent cache key for custom stages
+ QOpenGLShaderProgram* program;
+
+ QVector<uint> uniformLocations;
+
+ bool useTextureCoords;
+ bool useOpacityAttribute;
+ bool usePmvMatrixAttribute;
+
+ bool operator==(const QOpenGLEngineShaderProg& other) {
+ // We don't care about the program
+ return ( mainVertexShader == other.mainVertexShader &&
+ positionVertexShader == other.positionVertexShader &&
+ mainFragShader == other.mainFragShader &&
+ srcPixelFragShader == other.srcPixelFragShader &&
+ maskFragShader == other.maskFragShader &&
+ compositionFragShader == other.compositionFragShader &&
+ customStageSource == other.customStageSource
+ );
+ }
+};
+
+class Q_GUI_EXPORT QOpenGLEngineShaderManager : public QObject
+{
+ Q_OBJECT
+public:
+ QOpenGLEngineShaderManager(QOpenGLContext* context);
+ ~QOpenGLEngineShaderManager();
+
+ enum MaskType {NoMask, PixelMask, SubPixelMaskPass1, SubPixelMaskPass2, SubPixelWithGammaMask};
+ enum PixelSrcType {
+ ImageSrc = Qt::TexturePattern+1,
+ NonPremultipliedImageSrc = Qt::TexturePattern+2,
+ PatternSrc = Qt::TexturePattern+3,
+ TextureSrcWithPattern = Qt::TexturePattern+4
+ };
+
+ enum Uniform {
+ ImageTexture,
+ PatternColor,
+ GlobalOpacity,
+ Depth,
+ MaskTexture,
+ FragmentColor,
+ LinearData,
+ Angle,
+ HalfViewportSize,
+ Fmp,
+ Fmp2MRadius2,
+ Inverse2Fmp2MRadius2,
+ SqrFr,
+ BRadius,
+ InvertedTextureSize,
+ BrushTransform,
+ BrushTexture,
+ Matrix,
+ NumUniforms
+ };
+
+ enum OpacityMode {
+ NoOpacity,
+ UniformOpacity,
+ AttributeOpacity
+ };
+
+ // There are optimizations we can do, depending on the brush transform:
+ // 1) May not have to apply perspective-correction
+ // 2) Can use lower precision for matrix
+ void optimiseForBrushTransform(QTransform::TransformationType transformType);
+ void setSrcPixelType(Qt::BrushStyle);
+ void setSrcPixelType(PixelSrcType); // For non-brush sources, like pixmaps & images
+ void setOpacityMode(OpacityMode);
+ void setMaskType(MaskType);
+ void setCompositionMode(QPainter::CompositionMode);
+ void setCustomStage(QOpenGLCustomShaderStage* stage);
+ void removeCustomStage();
+
+ GLuint getUniformLocation(Uniform id);
+
+ void setDirty(); // someone has manually changed the current shader program
+ bool useCorrectShaderProg(); // returns true if the shader program needed to be changed
+
+ void useSimpleProgram();
+ void useBlitProgram();
+ void setHasComplexGeometry(bool hasComplexGeometry)
+ {
+ complexGeometry = hasComplexGeometry;
+ shaderProgNeedsChanging = true;
+ }
+ bool hasComplexGeometry() const
+ {
+ return complexGeometry;
+ }
+
+ QOpenGLShaderProgram* currentProgram(); // Returns pointer to the shader the manager has chosen
+ QOpenGLShaderProgram* simpleProgram(); // Used to draw into e.g. stencil buffers
+ QOpenGLShaderProgram* blitProgram(); // Used to blit a texture into the framebuffer
+
+ QOpenGLEngineSharedShaders* sharedShaders;
+
+private:
+ QOpenGLContext* ctx;
+ bool shaderProgNeedsChanging;
+ bool complexGeometry;
+
+ // Current state variables which influence the choice of shader:
+ QTransform brushTransform;
+ int srcPixelType;
+ OpacityMode opacityMode;
+ MaskType maskType;
+ QPainter::CompositionMode compositionMode;
+ QOpenGLCustomShaderStage* customSrcStage;
+
+ QOpenGLEngineShaderProg* currentShaderProg;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif //QOPENGLENGINE_SHADER_MANAGER_H
diff --git a/src/gui/opengl/qopenglengineshadersource_p.h b/src/gui/opengl/qopenglengineshadersource_p.h
new file mode 100644
index 0000000000..cb85212308
--- /dev/null
+++ b/src/gui/opengl/qopenglengineshadersource_p.h
@@ -0,0 +1,529 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+
+#ifndef QOPENGL_ENGINE_SHADER_SOURCE_H
+#define QOPENGL_ENGINE_SHADER_SOURCE_H
+
+#include "qopenglengineshadermanager_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+
+static const char* const qopenglslMainVertexShader = "\n\
+ void setPosition(); \n\
+ void main(void) \n\
+ { \n\
+ setPosition(); \n\
+ }\n";
+
+static const char* const qopenglslMainWithTexCoordsVertexShader = "\n\
+ attribute highp vec2 textureCoordArray; \n\
+ varying highp vec2 textureCoords; \n\
+ void setPosition(); \n\
+ void main(void) \n\
+ { \n\
+ setPosition(); \n\
+ textureCoords = textureCoordArray; \n\
+ }\n";
+
+static const char* const qopenglslMainWithTexCoordsAndOpacityVertexShader = "\n\
+ attribute highp vec2 textureCoordArray; \n\
+ attribute lowp float opacityArray; \n\
+ varying highp vec2 textureCoords; \n\
+ varying lowp float opacity; \n\
+ void setPosition(); \n\
+ void main(void) \n\
+ { \n\
+ setPosition(); \n\
+ textureCoords = textureCoordArray; \n\
+ opacity = opacityArray; \n\
+ }\n";
+
+// NOTE: We let GL do the perspective correction so texture lookups in the fragment
+// shader are also perspective corrected.
+static const char* const qopenglslPositionOnlyVertexShader = "\n\
+ attribute highp vec2 vertexCoordsArray; \n\
+ attribute highp vec3 pmvMatrix1; \n\
+ attribute highp vec3 pmvMatrix2; \n\
+ attribute highp vec3 pmvMatrix3; \n\
+ void setPosition(void) \n\
+ { \n\
+ highp mat3 pmvMatrix = mat3(pmvMatrix1, pmvMatrix2, pmvMatrix3); \n\
+ vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \n\
+ gl_Position = vec4(transformedPos.xy, 0.0, transformedPos.z); \n\
+ }\n";
+
+static const char* const qopenglslComplexGeometryPositionOnlyVertexShader = "\n\
+ uniform highp mat3 matrix; \n\
+ attribute highp vec2 vertexCoordsArray; \n\
+ void setPosition(void) \n\
+ { \n\
+ gl_Position = vec4(matrix * vec3(vertexCoordsArray, 1), 1);\n\
+ } \n";
+
+static const char* const qopenglslUntransformedPositionVertexShader = "\n\
+ attribute highp vec4 vertexCoordsArray; \n\
+ void setPosition(void) \n\
+ { \n\
+ gl_Position = vertexCoordsArray; \n\
+ }\n";
+
+// Pattern Brush - This assumes the texture size is 8x8 and thus, the inverted size is 0.125
+static const char* const qopenglslPositionWithPatternBrushVertexShader = "\n\
+ attribute highp vec2 vertexCoordsArray; \n\
+ attribute highp vec3 pmvMatrix1; \n\
+ attribute highp vec3 pmvMatrix2; \n\
+ attribute highp vec3 pmvMatrix3; \n\
+ uniform mediump vec2 halfViewportSize; \n\
+ uniform highp vec2 invertedTextureSize; \n\
+ uniform highp mat3 brushTransform; \n\
+ varying highp vec2 patternTexCoords; \n\
+ void setPosition(void) \n\
+ { \n\
+ highp mat3 pmvMatrix = mat3(pmvMatrix1, pmvMatrix2, pmvMatrix3); \n\
+ vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \n\
+ gl_Position.xy = transformedPos.xy / transformedPos.z; \n\
+ mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \n\
+ mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1.0); \n\
+ mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \n\
+ gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \n\
+ patternTexCoords.xy = (hTexCoords.xy * 0.125) * invertedHTexCoordsZ; \n\
+ }\n";
+
+static const char* const qopenglslAffinePositionWithPatternBrushVertexShader
+ = qopenglslPositionWithPatternBrushVertexShader;
+
+static const char* const qopenglslPatternBrushSrcFragmentShader = "\n\
+ uniform sampler2D brushTexture; \n\
+ uniform lowp vec4 patternColor; \n\
+ varying highp vec2 patternTexCoords;\n\
+ lowp vec4 srcPixel() \n\
+ { \n\
+ return patternColor * (1.0 - texture2D(brushTexture, patternTexCoords).r); \n\
+ }\n";
+
+
+// Linear Gradient Brush
+static const char* const qopenglslPositionWithLinearGradientBrushVertexShader = "\n\
+ attribute highp vec2 vertexCoordsArray; \n\
+ attribute highp vec3 pmvMatrix1; \n\
+ attribute highp vec3 pmvMatrix2; \n\
+ attribute highp vec3 pmvMatrix3; \n\
+ uniform mediump vec2 halfViewportSize; \n\
+ uniform highp vec3 linearData; \n\
+ uniform highp mat3 brushTransform; \n\
+ varying mediump float index; \n\
+ void setPosition() \n\
+ { \n\
+ highp mat3 pmvMatrix = mat3(pmvMatrix1, pmvMatrix2, pmvMatrix3); \n\
+ vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \n\
+ gl_Position.xy = transformedPos.xy / transformedPos.z; \n\
+ mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \n\
+ mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \n\
+ mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \n\
+ gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \n\
+ index = (dot(linearData.xy, hTexCoords.xy) * linearData.z) * invertedHTexCoordsZ; \n\
+ }\n";
+
+static const char* const qopenglslAffinePositionWithLinearGradientBrushVertexShader
+ = qopenglslPositionWithLinearGradientBrushVertexShader;
+
+static const char* const qopenglslLinearGradientBrushSrcFragmentShader = "\n\
+ uniform sampler2D brushTexture; \n\
+ varying mediump float index; \n\
+ lowp vec4 srcPixel() \n\
+ { \n\
+ mediump vec2 val = vec2(index, 0.5); \n\
+ return texture2D(brushTexture, val); \n\
+ }\n";
+
+
+// Conical Gradient Brush
+static const char* const qopenglslPositionWithConicalGradientBrushVertexShader = "\n\
+ attribute highp vec2 vertexCoordsArray; \n\
+ attribute highp vec3 pmvMatrix1; \n\
+ attribute highp vec3 pmvMatrix2; \n\
+ attribute highp vec3 pmvMatrix3; \n\
+ uniform mediump vec2 halfViewportSize; \n\
+ uniform highp mat3 brushTransform; \n\
+ varying highp vec2 A; \n\
+ void setPosition(void) \n\
+ { \n\
+ highp mat3 pmvMatrix = mat3(pmvMatrix1, pmvMatrix2, pmvMatrix3); \n\
+ vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \n\
+ gl_Position.xy = transformedPos.xy / transformedPos.z; \n\
+ mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \n\
+ mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \n\
+ mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \n\
+ gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \n\
+ A = hTexCoords.xy * invertedHTexCoordsZ; \n\
+ }\n";
+
+static const char* const qopenglslAffinePositionWithConicalGradientBrushVertexShader
+ = qopenglslPositionWithConicalGradientBrushVertexShader;
+
+static const char* const qopenglslConicalGradientBrushSrcFragmentShader = "\n\
+ #define INVERSE_2PI 0.1591549430918953358 \n\
+ uniform sampler2D brushTexture; \n\
+ uniform mediump float angle; \n\
+ varying highp vec2 A; \n\
+ lowp vec4 srcPixel() \n\
+ { \n\
+ highp float t; \n\
+ if (abs(A.y) == abs(A.x)) \n\
+ t = (atan(-A.y + 0.002, A.x) + angle) * INVERSE_2PI; \n\
+ else \n\
+ t = (atan(-A.y, A.x) + angle) * INVERSE_2PI; \n\
+ return texture2D(brushTexture, vec2(t - floor(t), 0.5)); \n\
+ }\n";
+
+
+// Radial Gradient Brush
+static const char* const qopenglslPositionWithRadialGradientBrushVertexShader = "\n\
+ attribute highp vec2 vertexCoordsArray;\n\
+ attribute highp vec3 pmvMatrix1; \n\
+ attribute highp vec3 pmvMatrix2; \n\
+ attribute highp vec3 pmvMatrix3; \n\
+ uniform mediump vec2 halfViewportSize; \n\
+ uniform highp mat3 brushTransform; \n\
+ uniform highp vec2 fmp; \n\
+ uniform highp vec3 bradius; \n\
+ varying highp float b; \n\
+ varying highp vec2 A; \n\
+ void setPosition(void) \n\
+ {\n\
+ highp mat3 pmvMatrix = mat3(pmvMatrix1, pmvMatrix2, pmvMatrix3); \n\
+ vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \n\
+ gl_Position.xy = transformedPos.xy / transformedPos.z; \n\
+ mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \n\
+ mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \n\
+ mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \n\
+ gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \n\
+ A = hTexCoords.xy * invertedHTexCoordsZ; \n\
+ b = bradius.x + 2.0 * dot(A, fmp); \n\
+ }\n";
+
+static const char* const qopenglslAffinePositionWithRadialGradientBrushVertexShader
+ = qopenglslPositionWithRadialGradientBrushVertexShader;
+
+static const char* const qopenglslRadialGradientBrushSrcFragmentShader = "\n\
+ uniform sampler2D brushTexture; \n\
+ uniform highp float fmp2_m_radius2; \n\
+ uniform highp float inverse_2_fmp2_m_radius2; \n\
+ uniform highp float sqrfr; \n\
+ varying highp float b; \n\
+ varying highp vec2 A; \n\
+ uniform highp vec3 bradius; \n\
+ lowp vec4 srcPixel() \n\
+ { \n\
+ highp float c = sqrfr-dot(A, A); \n\
+ highp float det = b*b - 4.0*fmp2_m_radius2*c; \n\
+ lowp vec4 result = vec4(0.0); \n\
+ if (det >= 0.0) { \n\
+ highp float detSqrt = sqrt(det); \n\
+ highp float w = max((-b - detSqrt) * inverse_2_fmp2_m_radius2, (-b + detSqrt) * inverse_2_fmp2_m_radius2); \n\
+ if (bradius.y + w * bradius.z >= 0.0) \n\
+ result = texture2D(brushTexture, vec2(w, 0.5)); \n\
+ } \n\
+ return result; \n\
+ }\n";
+
+
+// Texture Brush
+static const char* const qopenglslPositionWithTextureBrushVertexShader = "\n\
+ attribute highp vec2 vertexCoordsArray; \n\
+ attribute highp vec3 pmvMatrix1; \n\
+ attribute highp vec3 pmvMatrix2; \n\
+ attribute highp vec3 pmvMatrix3; \n\
+ uniform mediump vec2 halfViewportSize; \n\
+ uniform highp vec2 invertedTextureSize; \n\
+ uniform highp mat3 brushTransform; \n\
+ varying highp vec2 brushTextureCoords; \n\
+ void setPosition(void) \n\
+ { \n\
+ highp mat3 pmvMatrix = mat3(pmvMatrix1, pmvMatrix2, pmvMatrix3); \n\
+ vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \n\
+ gl_Position.xy = transformedPos.xy / transformedPos.z; \n\
+ mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \n\
+ mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \n\
+ mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \n\
+ gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \n\
+ brushTextureCoords.xy = (hTexCoords.xy * invertedTextureSize) * gl_Position.w; \n\
+ }\n";
+
+static const char* const qopenglslAffinePositionWithTextureBrushVertexShader
+ = qopenglslPositionWithTextureBrushVertexShader;
+
+#if defined(QT_OPENGL_ES_2)
+// OpenGL ES does not support GL_REPEAT wrap modes for NPOT textures. So instead,
+// we emulate GL_REPEAT by only taking the fractional part of the texture coords.
+// TODO: Special case POT textures which don't need this emulation
+static const char* const qopenglslTextureBrushSrcFragmentShader = "\n\
+ varying highp vec2 brushTextureCoords; \n\
+ uniform sampler2D brushTexture; \n\
+ lowp vec4 srcPixel() { \n\
+ return texture2D(brushTexture, fract(brushTextureCoords)); \n\
+ }\n";
+#else
+static const char* const qopenglslTextureBrushSrcFragmentShader = "\n\
+ varying highp vec2 brushTextureCoords; \n\
+ uniform sampler2D brushTexture; \n\
+ lowp vec4 srcPixel() \n\
+ { \n\
+ return texture2D(brushTexture, brushTextureCoords); \n\
+ }\n";
+#endif
+
+static const char* const qopenglslTextureBrushSrcWithPatternFragmentShader = "\n\
+ varying highp vec2 brushTextureCoords; \n\
+ uniform lowp vec4 patternColor; \n\
+ uniform sampler2D brushTexture; \n\
+ lowp vec4 srcPixel() \n\
+ { \n\
+ return patternColor * (1.0 - texture2D(brushTexture, brushTextureCoords).r); \n\
+ }\n";
+
+// Solid Fill Brush
+static const char* const qopenglslSolidBrushSrcFragmentShader = "\n\
+ uniform lowp vec4 fragmentColor; \n\
+ lowp vec4 srcPixel() \n\
+ { \n\
+ return fragmentColor; \n\
+ }\n";
+
+static const char* const qopenglslImageSrcFragmentShader = "\n\
+ varying highp vec2 textureCoords; \n\
+ uniform sampler2D imageTexture; \n\
+ lowp vec4 srcPixel() \n\
+ { \n"
+ "return texture2D(imageTexture, textureCoords); \n"
+ "}\n";
+
+static const char* const qopenglslCustomSrcFragmentShader = "\n\
+ varying highp vec2 textureCoords; \n\
+ uniform sampler2D imageTexture; \n\
+ lowp vec4 srcPixel() \n\
+ { \n\
+ return customShader(imageTexture, textureCoords); \n\
+ }\n";
+
+static const char* const qopenglslImageSrcWithPatternFragmentShader = "\n\
+ varying highp vec2 textureCoords; \n\
+ uniform lowp vec4 patternColor; \n\
+ uniform sampler2D imageTexture; \n\
+ lowp vec4 srcPixel() \n\
+ { \n\
+ return patternColor * (1.0 - texture2D(imageTexture, textureCoords).r); \n\
+ }\n";
+
+static const char* const qopenglslNonPremultipliedImageSrcFragmentShader = "\n\
+ varying highp vec2 textureCoords; \n\
+ uniform sampler2D imageTexture; \n\
+ lowp vec4 srcPixel() \n\
+ { \n\
+ lowp vec4 sample = texture2D(imageTexture, textureCoords); \n\
+ sample.rgb = sample.rgb * sample.a; \n\
+ return sample; \n\
+ }\n";
+
+static const char* const qopenglslShockingPinkSrcFragmentShader = "\n\
+ lowp vec4 srcPixel() \n\
+ { \n\
+ return vec4(0.98, 0.06, 0.75, 1.0); \n\
+ }\n";
+
+static const char* const qopenglslMainFragmentShader_ImageArrays = "\n\
+ varying lowp float opacity; \n\
+ lowp vec4 srcPixel(); \n\
+ void main() \n\
+ { \n\
+ gl_FragColor = srcPixel() * opacity; \n\
+ }\n";
+
+static const char* const qopenglslMainFragmentShader_CMO = "\n\
+ uniform lowp float globalOpacity; \n\
+ lowp vec4 srcPixel(); \n\
+ lowp vec4 applyMask(lowp vec4); \n\
+ lowp vec4 compose(lowp vec4); \n\
+ void main() \n\
+ { \n\
+ gl_FragColor = applyMask(compose(srcPixel()*globalOpacity))); \n\
+ }\n";
+
+static const char* const qopenglslMainFragmentShader_CM = "\n\
+ lowp vec4 srcPixel(); \n\
+ lowp vec4 applyMask(lowp vec4); \n\
+ lowp vec4 compose(lowp vec4); \n\
+ void main() \n\
+ { \n\
+ gl_FragColor = applyMask(compose(srcPixel())); \n\
+ }\n";
+
+static const char* const qopenglslMainFragmentShader_MO = "\n\
+ uniform lowp float globalOpacity; \n\
+ lowp vec4 srcPixel(); \n\
+ lowp vec4 applyMask(lowp vec4); \n\
+ void main() \n\
+ { \n\
+ gl_FragColor = applyMask(srcPixel()*globalOpacity); \n\
+ }\n";
+
+static const char* const qopenglslMainFragmentShader_M = "\n\
+ lowp vec4 srcPixel(); \n\
+ lowp vec4 applyMask(lowp vec4); \n\
+ void main() \n\
+ { \n\
+ gl_FragColor = applyMask(srcPixel()); \n\
+ }\n";
+
+static const char* const qopenglslMainFragmentShader_CO = "\n\
+ uniform lowp float globalOpacity; \n\
+ lowp vec4 srcPixel(); \n\
+ lowp vec4 compose(lowp vec4); \n\
+ void main() \n\
+ { \n\
+ gl_FragColor = compose(srcPixel()*globalOpacity); \n\
+ }\n";
+
+static const char* const qopenglslMainFragmentShader_C = "\n\
+ lowp vec4 srcPixel(); \n\
+ lowp vec4 compose(lowp vec4); \n\
+ void main() \n\
+ { \n\
+ gl_FragColor = compose(srcPixel()); \n\
+ }\n";
+
+static const char* const qopenglslMainFragmentShader_O = "\n\
+ uniform lowp float globalOpacity; \n\
+ lowp vec4 srcPixel(); \n\
+ void main() \n\
+ { \n\
+ gl_FragColor = srcPixel()*globalOpacity; \n\
+ }\n";
+
+static const char* const qopenglslMainFragmentShader = "\n\
+ lowp vec4 srcPixel(); \n\
+ void main() \n\
+ { \n\
+ gl_FragColor = srcPixel(); \n\
+ }\n";
+
+static const char* const qopenglslMaskFragmentShader = "\n\
+ varying highp vec2 textureCoords;\n\
+ uniform sampler2D maskTexture;\n\
+ lowp vec4 applyMask(lowp vec4 src) \n\
+ {\n\
+ lowp vec4 mask = texture2D(maskTexture, textureCoords); \n\
+ return src * mask.a; \n\
+ }\n";
+
+// For source over with subpixel antialiasing, the final color is calculated per component as follows
+// (.a is alpha component, .c is red, green or blue component):
+// alpha = src.a * mask.c * opacity
+// dest.c = dest.c * (1 - alpha) + src.c * alpha
+//
+// In the first pass, calculate: dest.c = dest.c * (1 - alpha) with blend funcs: zero, 1 - source color
+// In the second pass, calculate: dest.c = dest.c + src.c * alpha with blend funcs: one, one
+//
+// If source is a solid color (src is constant), only the first pass is needed, with blend funcs: constant, 1 - source color
+
+// For source composition with subpixel antialiasing, the final color is calculated per component as follows:
+// alpha = src.a * mask.c * opacity
+// dest.c = dest.c * (1 - mask.c) + src.c * alpha
+//
+
+static const char* const qopenglslRgbMaskFragmentShaderPass1 = "\n\
+ varying highp vec2 textureCoords;\n\
+ uniform sampler2D maskTexture;\n\
+ lowp vec4 applyMask(lowp vec4 src) \n\
+ { \n\
+ lowp vec4 mask = texture2D(maskTexture, textureCoords); \n\
+ return src.a * mask; \n\
+ }\n";
+
+static const char* const qopenglslRgbMaskFragmentShaderPass2 = "\n\
+ varying highp vec2 textureCoords;\n\
+ uniform sampler2D maskTexture;\n\
+ lowp vec4 applyMask(lowp vec4 src) \n\
+ { \n\
+ lowp vec4 mask = texture2D(maskTexture, textureCoords); \n\
+ return src * mask; \n\
+ }\n";
+
+/*
+ Left to implement:
+ RgbMaskFragmentShader,
+ RgbMaskWithGammaFragmentShader,
+
+ MultiplyCompositionModeFragmentShader,
+ ScreenCompositionModeFragmentShader,
+ OverlayCompositionModeFragmentShader,
+ DarkenCompositionModeFragmentShader,
+ LightenCompositionModeFragmentShader,
+ ColorDodgeCompositionModeFragmentShader,
+ ColorBurnCompositionModeFragmentShader,
+ HardLightCompositionModeFragmentShader,
+ SoftLightCompositionModeFragmentShader,
+ DifferenceCompositionModeFragmentShader,
+ ExclusionCompositionModeFragmentShader,
+*/
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // GLGC_SHADER_SOURCE_H
diff --git a/src/gui/opengl/qopenglextensions_p.h b/src/gui/opengl/qopenglextensions_p.h
new file mode 100644
index 0000000000..65d92e3a65
--- /dev/null
+++ b/src/gui/opengl/qopenglextensions_p.h
@@ -0,0 +1,677 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QOPENGL_EXTENSIONS_P_H
+#define QOPENGL_EXTENSIONS_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the Qt OpenGL classes. This header file may change from
+// version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qopenglfunctions.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#if 0
+#ifndef GL_ARB_vertex_buffer_object
+typedef ptrdiff_t GLintptrARB;
+typedef ptrdiff_t GLsizeiptrARB;
+#endif
+#endif
+
+#ifndef GL_VERSION_2_0
+typedef char GLchar;
+#endif
+
+class QOpenGLExtensionsPrivate;
+
+class Q_GUI_EXPORT QOpenGLExtensions : public QOpenGLFunctions
+{
+ Q_DECLARE_PRIVATE(QOpenGLExtensions)
+public:
+ QOpenGLExtensions();
+ QOpenGLExtensions(QOpenGLContext *context);
+ ~QOpenGLExtensions() {}
+
+ enum OpenGLExtension {
+ TextureRectangle = 0x00000001,
+ GenerateMipmap = 0x00000002,
+ TextureCompression = 0x00000004,
+ MirroredRepeat = 0x00000008,
+ FramebufferMultisample = 0x00000010,
+ StencilTwoSide = 0x00000020,
+ StencilWrap = 0x00000040,
+ PackedDepthStencil = 0x00000080,
+ NVFloatBuffer = 0x00000100,
+ PixelBufferObject = 0x00000200,
+ FramebufferBlit = 0x00000400,
+ BGRATextureFormat = 0x00000800,
+ DDSTextureCompression = 0x00001000,
+ ETC1TextureCompression = 0x00002000,
+ PVRTCTextureCompression = 0x00004000,
+ ElementIndexUint = 0x00008000,
+ Depth24 = 0x00010000,
+ SRGBFrameBuffer = 0x00020000,
+ MapBuffer = 0x00040000,
+ GeometryShaders = 0x00080000
+ };
+ Q_DECLARE_FLAGS(OpenGLExtensions, OpenGLExtension)
+
+ OpenGLExtensions openGLExtensions();
+ bool hasOpenGLExtension(QOpenGLExtensions::OpenGLExtension extension) const;
+
+ void initializeGLExtensions();
+
+ GLvoid *glMapBuffer(GLenum target, GLenum access);
+ GLboolean glUnmapBuffer(GLenum target);
+
+ void glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+ GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+ GLbitfield mask, GLenum filter);
+
+ void glRenderbufferStorageMultisample(GLenum target, GLsizei samples,
+ GLenum internalFormat,
+ GLsizei width, GLsizei height);
+
+ void glGetBufferSubData(GLenum target, qopengl_GLintptr offset, qopengl_GLsizeiptr size, GLvoid *data);
+
+private:
+ static bool isInitialized(const QOpenGLFunctionsPrivate *d) { return d != 0; }
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QOpenGLExtensions::OpenGLExtensions)
+
+class QOpenGLExtensionsPrivate : public QOpenGLFunctionsPrivate
+{
+public:
+ explicit QOpenGLExtensionsPrivate(QOpenGLContext *ctx);
+
+ GLvoid* (QOPENGLF_APIENTRYP MapBuffer)(GLenum target, GLenum access);
+ GLboolean (QOPENGLF_APIENTRYP UnmapBuffer)(GLenum target);
+ void (QOPENGLF_APIENTRYP BlitFramebuffer)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+ GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+ GLbitfield mask, GLenum filter);
+ void (QOPENGLF_APIENTRYP RenderbufferStorageMultisample)(GLenum target, GLsizei samples,
+ GLenum internalFormat,
+ GLsizei width, GLsizei height);
+ void (QOPENGLF_APIENTRYP GetBufferSubData)(GLenum target, qopengl_GLintptr offset, qopengl_GLsizeiptr size, GLvoid *data);
+};
+
+inline GLvoid *QOpenGLExtensions::glMapBuffer(GLenum target, GLenum access)
+{
+ Q_D(QOpenGLExtensions);
+ Q_ASSERT(QOpenGLExtensions::isInitialized(d));
+ GLvoid *result = d->MapBuffer(target, access);
+ Q_OPENGL_FUNCTIONS_DEBUG
+ return result;
+}
+
+inline GLboolean QOpenGLExtensions::glUnmapBuffer(GLenum target)
+{
+ Q_D(QOpenGLExtensions);
+ Q_ASSERT(QOpenGLExtensions::isInitialized(d));
+ GLboolean result = d->UnmapBuffer(target);
+ Q_OPENGL_FUNCTIONS_DEBUG
+ return result;
+}
+
+inline void QOpenGLExtensions::glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+ GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+ GLbitfield mask, GLenum filter)
+{
+ Q_D(QOpenGLExtensions);
+ Q_ASSERT(QOpenGLExtensions::isInitialized(d));
+ d->BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtensions::glRenderbufferStorageMultisample(GLenum target, GLsizei samples,
+ GLenum internalFormat,
+ GLsizei width, GLsizei height)
+{
+ Q_D(QOpenGLExtensions);
+ Q_ASSERT(QOpenGLExtensions::isInitialized(d));
+ d->RenderbufferStorageMultisample(target, samples, internalFormat, width, height);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLExtensions::glGetBufferSubData(GLenum target, qopengl_GLintptr offset, qopengl_GLsizeiptr size, GLvoid *data)
+{
+ Q_D(QOpenGLExtensions);
+ Q_ASSERT(QOpenGLExtensions::isInitialized(d));
+ d->GetBufferSubData(target, offset, size, data);
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+#ifndef GL_FRAMEBUFFER_SRGB_CAPABLE
+#define GL_FRAMEBUFFER_SRGB_CAPABLE 0x8DBA
+#endif
+#ifndef GL_FRAMEBUFFER_SRGB
+#define GL_FRAMEBUFFER_SRGB 0x8DB9
+#endif
+#ifndef GL_ARRAY_BUFFER
+#define GL_ARRAY_BUFFER 0x8892
+#endif
+#ifndef GL_STATIC_DRAW
+#define GL_STATIC_DRAW 0x88E4
+#endif
+#ifndef GL_TEXTURE_RECTANGLE
+#define GL_TEXTURE_RECTANGLE 0x84F5
+#endif
+#ifndef GL_TEXTURE_BINDING_RECTANGLE
+#define GL_TEXTURE_BINDING_RECTANGLE 0x84F6
+#endif
+#ifndef GL_PROXY_TEXTURE_RECTANGLE
+#define GL_PROXY_TEXTURE_RECTANGLE 0x84F7
+#endif
+#ifndef GL_MAX_RECTANGLE_TEXTURE_SIZE
+#define GL_MAX_RECTANGLE_TEXTURE_SIZE 0x84F8
+#endif
+#ifndef GL_BGRA
+#define GL_BGRA 0x80E1
+#endif
+#ifndef GL_RGB16
+#define GL_RGB16 0x8054
+#endif
+#ifndef GL_UNSIGNED_SHORT_5_6_5
+#define GL_UNSIGNED_SHORT_5_6_5 0x8363
+#endif
+#ifndef GL_UNSIGNED_INT_8_8_8_8_REV
+#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367
+#endif
+#ifndef GL_MULTISAMPLE
+#define GL_MULTISAMPLE 0x809D
+#endif
+#ifndef GL_CLAMP_TO_EDGE
+#define GL_CLAMP_TO_EDGE 0x812F
+#endif
+#ifndef GL_MIRRORED_REPEAT
+#define GL_MIRRORED_REPEAT 0x8370
+#endif
+#ifndef GL_GENERATE_MIPMAP
+#define GL_GENERATE_MIPMAP 0x8191
+#endif
+#ifndef GL_GENERATE_MIPMAP_HINT
+#define GL_GENERATE_MIPMAP_HINT 0x8192
+#endif
+#ifndef GL_FRAGMENT_PROGRAM
+#define GL_FRAGMENT_PROGRAM 0x8804
+#endif
+#ifndef GL_PROGRAM_FORMAT_ASCII
+#define GL_PROGRAM_FORMAT_ASCII 0x8875
+#endif
+#ifndef GL_PIXEL_UNPACK_BUFFER
+#define GL_PIXEL_UNPACK_BUFFER 0x88EC
+#endif
+#ifndef GL_WRITE_ONLY
+#define GL_WRITE_ONLY 0x88B9
+#endif
+#ifndef GL_STREAM_DRAW
+#define GL_STREAM_DRAW 0x88E0
+#endif
+#ifndef GL_STENCIL_TEST_TWO_SIDE
+#define GL_STENCIL_TEST_TWO_SIDE 0x8910
+#endif
+#ifndef GL_INCR_WRAP
+#define GL_INCR_WRAP 0x8507
+#endif
+#ifndef GL_DECR_WRAP
+#define GL_DECR_WRAP 0x8508
+#endif
+#ifndef GL_TEXTURE0
+#define GL_TEXTURE0 0x84C0
+#endif
+#ifndef GL_TEXTURE1
+#define GL_TEXTURE1 0x84C1
+#endif
+#ifndef GL_DEPTH_COMPONENT16
+#define GL_DEPTH_COMPONENT16 0x81A5
+#endif
+#ifndef GL_DEPTH_COMPONENT24
+#define GL_DEPTH_COMPONENT24 0x81A6
+#endif
+#ifndef GL_INVALID_FRAMEBUFFER_OPERATION
+#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506
+#endif
+#ifndef GL_MAX_RENDERBUFFER_SIZE
+#define GL_MAX_RENDERBUFFER_SIZE 0x84E8
+#endif
+#ifndef GL_FRAMEBUFFER_BINDING
+#define GL_FRAMEBUFFER_BINDING 0x8CA6
+#endif
+#ifndef GL_RENDERBUFFER_BINDING
+#define GL_RENDERBUFFER_BINDING 0x8CA7
+#endif
+#ifndef GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0
+#endif
+#ifndef GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1
+#endif
+#ifndef GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2
+#endif
+#ifndef GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3
+#endif
+#ifndef GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET 0x8CD4
+#endif
+#ifndef GL_FRAMEBUFFER_COMPLETE
+#define GL_FRAMEBUFFER_COMPLETE 0x8CD5
+#endif
+#ifndef GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT
+#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6
+#endif
+#ifndef GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT
+#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7
+#endif
+#ifndef GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT
+#define GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT 0x8CD8
+#endif
+#ifndef GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS
+#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9
+#endif
+#ifndef GL_FRAMEBUFFER_INCOMPLETE_FORMATS
+#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS 0x8CDA
+#endif
+#ifndef GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER
+#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB
+#endif
+#ifndef GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER
+#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC
+#endif
+#ifndef GL_FRAMEBUFFER_UNSUPPORTED
+#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD
+#endif
+#ifndef GL_MAX_COLOR_ATTACHMENTS
+#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF
+#endif
+#ifndef GL_COLOR_ATTACHMENT0
+#define GL_COLOR_ATTACHMENT0 0x8CE0
+#endif
+#ifndef GL_COLOR_ATTACHMENT1
+#define GL_COLOR_ATTACHMENT1 0x8CE1
+#endif
+#ifndef GL_COLOR_ATTACHMENT2
+#define GL_COLOR_ATTACHMENT2 0x8CE2
+#endif
+#ifndef GL_COLOR_ATTACHMENT3
+#define GL_COLOR_ATTACHMENT3 0x8CE3
+#endif
+#ifndef GL_COLOR_ATTACHMENT4
+#define GL_COLOR_ATTACHMENT4 0x8CE4
+#endif
+#ifndef GL_COLOR_ATTACHMENT5
+#define GL_COLOR_ATTACHMENT5 0x8CE5
+#endif
+#ifndef GL_COLOR_ATTACHMENT6
+#define GL_COLOR_ATTACHMENT6 0x8CE6
+#endif
+#ifndef GL_COLOR_ATTACHMENT7
+#define GL_COLOR_ATTACHMENT7 0x8CE7
+#endif
+#ifndef GL_COLOR_ATTACHMENT8
+#define GL_COLOR_ATTACHMENT8 0x8CE8
+#endif
+#ifndef GL_COLOR_ATTACHMENT9
+#define GL_COLOR_ATTACHMENT9 0x8CE9
+#endif
+#ifndef GL_COLOR_ATTACHMENT10
+#define GL_COLOR_ATTACHMENT10 0x8CEA
+#endif
+#ifndef GL_COLOR_ATTACHMENT11
+#define GL_COLOR_ATTACHMENT11 0x8CEB
+#endif
+#ifndef GL_COLOR_ATTACHMENT12
+#define GL_COLOR_ATTACHMENT12 0x8CEC
+#endif
+#ifndef GL_COLOR_ATTACHMENT13
+#define GL_COLOR_ATTACHMENT13 0x8CED
+#endif
+#ifndef GL_COLOR_ATTACHMENT14
+#define GL_COLOR_ATTACHMENT14 0x8CEE
+#endif
+#ifndef GL_COLOR_ATTACHMENT15
+#define GL_COLOR_ATTACHMENT15 0x8CEF
+#endif
+#ifndef GL_DEPTH_ATTACHMENT
+#define GL_DEPTH_ATTACHMENT 0x8D00
+#endif
+#ifndef GL_STENCIL_ATTACHMENT
+#define GL_STENCIL_ATTACHMENT 0x8D20
+#endif
+#ifndef GL_FRAMEBUFFER
+#define GL_FRAMEBUFFER 0x8D40
+#endif
+#ifndef GL_RENDERBUFFER
+#define GL_RENDERBUFFER 0x8D41
+#endif
+#ifndef GL_RENDERBUFFER_WIDTH
+#define GL_RENDERBUFFER_WIDTH 0x8D42
+#endif
+#ifndef GL_RENDERBUFFER_HEIGHT
+#define GL_RENDERBUFFER_HEIGHT 0x8D43
+#endif
+#ifndef GL_RENDERBUFFER_INTERNAL_FORMAT
+#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44
+#endif
+#ifndef GL_STENCIL_INDEX
+#define GL_STENCIL_INDEX 0x8D45
+#endif
+#ifndef GL_STENCIL_INDEX1
+#define GL_STENCIL_INDEX1 0x8D46
+#endif
+#ifndef GL_STENCIL_INDEX4
+#define GL_STENCIL_INDEX4 0x8D47
+#endif
+#ifndef GL_STENCIL_INDEX8
+#define GL_STENCIL_INDEX8 0x8D48
+#endif
+#ifndef GL_STENCIL_INDEX16
+#define GL_STENCIL_INDEX16 0x8D49
+#endif
+#ifndef GL_RENDERBUFFER_RED_SIZE
+#define GL_RENDERBUFFER_RED_SIZE 0x8D50
+#endif
+#ifndef GL_RENDERBUFFER_GREEN_SIZE
+#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51
+#endif
+#ifndef GL_RENDERBUFFER_BLUE_SIZE
+#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52
+#endif
+#ifndef GL_RENDERBUFFER_ALPHA_SIZE
+#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53
+#endif
+#ifndef GL_RENDERBUFFER_DEPTH_SIZE
+#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54
+#endif
+#ifndef GL_RENDERBUFFER_STENCIL_SIZE
+#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55
+#endif
+#ifndef GL_READ_FRAMEBUFFER
+#define GL_READ_FRAMEBUFFER 0x8CA8
+#endif
+#ifndef GL_RENDERBUFFER_SAMPLES
+#define GL_RENDERBUFFER_SAMPLES 0x8CAB
+#endif
+#ifndef GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56
+#endif
+#ifndef GL_MAX_SAMPLES
+#define GL_MAX_SAMPLES 0x8D57
+#endif
+#ifndef GL_DRAW_FRAMEBUFFER
+#define GL_DRAW_FRAMEBUFFER 0x8CA9
+#endif
+#ifndef GL_DEPTH_STENCIL
+#define GL_DEPTH_STENCIL 0x84F9
+#endif
+#ifndef GL_UNSIGNED_INT_24_8
+#define GL_UNSIGNED_INT_24_8 0x84FA
+#endif
+#ifndef GL_DEPTH24_STENCIL8
+#define GL_DEPTH24_STENCIL8 0x88F0
+#endif
+#ifndef GL_TEXTURE_STENCIL_SIZE
+#define GL_TEXTURE_STENCIL_SIZE 0x88F1
+#endif
+#ifndef GL_CLAMP_TO_EDGE
+#define GL_CLAMP_TO_EDGE 0x812F
+#endif
+#ifndef GL_PACK_SKIP_IMAGES
+#define GL_PACK_SKIP_IMAGES 0x806B
+#endif
+#ifndef GL_PACK_IMAGE_HEIGHT
+#define GL_PACK_IMAGE_HEIGHT 0x806C
+#endif
+#ifndef GL_UNPACK_SKIP_IMAGES
+#define GL_UNPACK_SKIP_IMAGES 0x806D
+#endif
+#ifndef GL_UNPACK_IMAGE_HEIGHT
+#define GL_UNPACK_IMAGE_HEIGHT 0x806E
+#endif
+#ifndef GL_CONSTANT_COLOR
+#define GL_CONSTANT_COLOR 0x8001
+#endif
+#ifndef GL_ONE_MINUS_CONSTANT_COLOR
+#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002
+#endif
+#ifndef GL_CONSTANT_ALPHA
+#define GL_CONSTANT_ALPHA 0x8003
+#endif
+#ifndef GL_ONE_MINUS_CONSTANT_ALPHA
+#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004
+#endif
+#ifndef GL_INCR_WRAP
+#define GL_INCR_WRAP 0x8507
+#endif
+#ifndef GL_DECR_WRAP
+#define GL_DECR_WRAP 0x8508
+#endif
+#ifndef GL_ARRAY_BUFFER
+#define GL_ARRAY_BUFFER 0x8892
+#endif
+#ifndef GL_ELEMENT_ARRAY_BUFFER
+#define GL_ELEMENT_ARRAY_BUFFER 0x8893
+#endif
+#ifndef GL_STREAM_DRAW
+#define GL_STREAM_DRAW 0x88E0
+#endif
+#ifndef GL_STREAM_READ
+#define GL_STREAM_READ 0x88E1
+#endif
+#ifndef GL_STREAM_COPY
+#define GL_STREAM_COPY 0x88E2
+#endif
+#ifndef GL_STATIC_DRAW
+#define GL_STATIC_DRAW 0x88E4
+#endif
+#ifndef GL_STATIC_READ
+#define GL_STATIC_READ 0x88E5
+#endif
+#ifndef GL_STATIC_COPY
+#define GL_STATIC_COPY 0x88E6
+#endif
+#ifndef GL_DYNAMIC_DRAW
+#define GL_DYNAMIC_DRAW 0x88E8
+#endif
+#ifndef GL_DYNAMIC_READ
+#define GL_DYNAMIC_READ 0x88E9
+#endif
+#ifndef GL_DYNAMIC_COPY
+#define GL_DYNAMIC_COPY 0x88EA
+#endif
+#ifndef GL_FRAGMENT_SHADER
+#define GL_FRAGMENT_SHADER 0x8B30
+#endif
+#ifndef GL_VERTEX_SHADER
+#define GL_VERTEX_SHADER 0x8B31
+#endif
+#ifndef GL_FLOAT_VEC2
+#define GL_FLOAT_VEC2 0x8B50
+#endif
+#ifndef GL_FLOAT_VEC3
+#define GL_FLOAT_VEC3 0x8B51
+#endif
+#ifndef GL_FLOAT_VEC4
+#define GL_FLOAT_VEC4 0x8B52
+#endif
+#ifndef GL_INT_VEC2
+#define GL_INT_VEC2 0x8B53
+#endif
+#ifndef GL_INT_VEC3
+#define GL_INT_VEC3 0x8B54
+#endif
+#ifndef GL_INT_VEC4
+#define GL_INT_VEC4 0x8B55
+#endif
+#ifndef GL_BOOL
+#define GL_BOOL 0x8B56
+#endif
+#ifndef GL_BOOL_VEC2
+#define GL_BOOL_VEC2 0x8B57
+#endif
+#ifndef GL_BOOL_VEC3
+#define GL_BOOL_VEC3 0x8B58
+#endif
+#ifndef GL_BOOL_VEC4
+#define GL_BOOL_VEC4 0x8B59
+#endif
+#ifndef GL_FLOAT_MAT2
+#define GL_FLOAT_MAT2 0x8B5A
+#endif
+#ifndef GL_FLOAT_MAT3
+#define GL_FLOAT_MAT3 0x8B5B
+#endif
+#ifndef GL_FLOAT_MAT4
+#define GL_FLOAT_MAT4 0x8B5C
+#endif
+#ifndef GL_SAMPLER_1D
+#define GL_SAMPLER_1D 0x8B5D
+#endif
+#ifndef GL_SAMPLER_2D
+#define GL_SAMPLER_2D 0x8B5E
+#endif
+#ifndef GL_SAMPLER_3D
+#define GL_SAMPLER_3D 0x8B5F
+#endif
+#ifndef GL_SAMPLER_CUBE
+#define GL_SAMPLER_CUBE 0x8B60
+#endif
+#ifndef GL_COMPILE_STATUS
+#define GL_COMPILE_STATUS 0x8B81
+#endif
+#ifndef GL_LINK_STATUS
+#define GL_LINK_STATUS 0x8B82
+#endif
+#ifndef GL_INFO_LOG_LENGTH
+#define GL_INFO_LOG_LENGTH 0x8B84
+#endif
+#ifndef GL_ACTIVE_UNIFORMS
+#define GL_ACTIVE_UNIFORMS 0x8B86
+#endif
+#ifndef GL_ACTIVE_UNIFORM_MAX_LENGTH
+#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87
+#endif
+#ifndef GL_ACTIVE_ATTRIBUTES
+#define GL_ACTIVE_ATTRIBUTES 0x8B89
+#endif
+#ifndef GL_ACTIVE_ATTRIBUTE_MAX_LENGTH
+#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A
+#endif
+#ifndef GL_GEOMETRY_SHADER
+#define GL_GEOMETRY_SHADER 0x8DD9
+#endif
+#ifndef GL_GEOMETRY_VERTICES_OUT
+#define GL_GEOMETRY_VERTICES_OUT 0x8DDA
+#endif
+#ifndef GL_GEOMETRY_INPUT_TYPE
+#define GL_GEOMETRY_INPUT_TYPE 0x8DDB
+#endif
+#ifndef GL_GEOMETRY_OUTPUT_TYPE
+#define GL_GEOMETRY_OUTPUT_TYPE 0x8DDC
+#endif
+#ifndef GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS
+#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS 0x8C29
+#endif
+#ifndef GL_MAX_GEOMETRY_VARYING_COMPONENTS
+#define GL_MAX_GEOMETRY_VARYING_COMPONENTS 0x8DDD
+#endif
+#ifndef GL_MAX_VERTEX_VARYING_COMPONENTS
+#define GL_MAX_VERTEX_VARYING_COMPONENTS 0x8DDE
+#endif
+#ifndef GL_MAX_VARYING_COMPONENTS
+#define GL_MAX_VARYING_COMPONENTS 0x8B4B
+#endif
+#ifndef GL_MAX_GEOMETRY_UNIFORM_COMPONENTS
+#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS 0x8DDF
+#endif
+#ifndef GL_MAX_GEOMETRY_OUTPUT_VERTICES
+#define GL_MAX_GEOMETRY_OUTPUT_VERTICES 0x8DE0
+#endif
+#ifndef GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS
+#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS 0x8DE1
+#endif
+#ifndef GL_LINES_ADJACENCY
+#define GL_LINES_ADJACENCY 0xA
+#endif
+#ifndef GL_LINE_STRIP_ADJACENCY
+#define GL_LINE_STRIP_ADJACENCY 0xB
+#endif
+#ifndef GL_TRIANGLES_ADJACENCY
+#define GL_TRIANGLES_ADJACENCY 0xC
+#endif
+#ifndef GL_TRIANGLE_STRIP_ADJACENCY
+#define GL_TRIANGLE_STRIP_ADJACENCY 0xD
+#endif
+#ifndef GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS
+#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8
+#endif
+#ifndef GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT
+#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT 0x8DA9
+#endif
+#ifndef GL_FRAMEBUFFER_ATTACHMENT_LAYERED
+#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED 0x8DA7
+#endif
+#ifndef GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4
+#endif
+#ifndef GL_PROGRAM_POINT_SIZE
+#define GL_PROGRAM_POINT_SIZE 0x8642
+#endif
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QOPENGL_EXTENSIONS_P_H
diff --git a/src/gui/opengl/qopenglframebufferobject.cpp b/src/gui/opengl/qopenglframebufferobject.cpp
new file mode 100644
index 0000000000..8c5eb0d877
--- /dev/null
+++ b/src/gui/opengl/qopenglframebufferobject.cpp
@@ -0,0 +1,1229 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qopenglframebufferobject.h"
+#include "qopenglframebufferobject_p.h"
+
+#include <qdebug.h>
+#include <private/qopengl_p.h>
+#include <private/qopenglcontext_p.h>
+#include <private/qopenglextensions_p.h>
+#include <private/qfont_p.h>
+
+#include <qwindow.h>
+#include <qlibrary.h>
+#include <qimage.h>
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_DEBUG
+#define QT_RESET_GLERROR() \
+{ \
+ while (glGetError() != GL_NO_ERROR) {} \
+}
+#define QT_CHECK_GLERROR() \
+{ \
+ GLenum err = glGetError(); \
+ if (err != GL_NO_ERROR) { \
+ qDebug("[%s line %d] GL Error: %d", \
+ __FILE__, __LINE__, (int)err); \
+ } \
+}
+#else
+#define QT_RESET_GLERROR() {}
+#define QT_CHECK_GLERROR() {}
+#endif
+
+/*!
+ \class QOpenGLFramebufferObjectFormat
+ \brief The QOpenGLFramebufferObjectFormat class specifies the format of an OpenGL
+ framebuffer object.
+
+ \since 5.0
+
+ \ingroup painting-3D
+
+ A framebuffer object has several characteristics:
+ \list
+ \i \link setSamples() Number of samples per pixels.\endlink
+ \i \link setAttachment() Depth and/or stencil attachments.\endlink
+ \i \link setTextureTarget() Texture target.\endlink
+ \i \link setInternalTextureFormat() Internal texture format.\endlink
+ \endlist
+
+ Note that the desired attachments or number of samples per pixels might not
+ be supported by the hardware driver. Call QOpenGLFramebufferObject::format()
+ after creating a QOpenGLFramebufferObject to find the exact format that was
+ used to create the frame buffer object.
+
+ \sa QOpenGLFramebufferObject
+*/
+
+/*!
+ \internal
+*/
+void QOpenGLFramebufferObjectFormat::detach()
+{
+ if (d->ref != 1) {
+ QOpenGLFramebufferObjectFormatPrivate *newd
+ = new QOpenGLFramebufferObjectFormatPrivate(d);
+ if (!d->ref.deref())
+ delete d;
+ d = newd;
+ }
+}
+
+/*!
+ Creates a QOpenGLFramebufferObjectFormat object for specifying
+ the format of an OpenGL framebuffer object.
+
+ By default the format specifies a non-multisample framebuffer object with no
+ attachments, texture target \c GL_TEXTURE_2D, and internal format \c GL_RGBA8.
+ On OpenGL/ES systems, the default internal format is \c GL_RGBA.
+
+ \sa samples(), attachment(), internalTextureFormat()
+*/
+
+QOpenGLFramebufferObjectFormat::QOpenGLFramebufferObjectFormat()
+{
+ d = new QOpenGLFramebufferObjectFormatPrivate;
+}
+
+/*!
+ Constructs a copy of \a other.
+*/
+
+QOpenGLFramebufferObjectFormat::QOpenGLFramebufferObjectFormat(const QOpenGLFramebufferObjectFormat &other)
+{
+ d = other.d;
+ d->ref.ref();
+}
+
+/*!
+ Assigns \a other to this object.
+*/
+
+QOpenGLFramebufferObjectFormat &QOpenGLFramebufferObjectFormat::operator=(const QOpenGLFramebufferObjectFormat &other)
+{
+ if (d != other.d) {
+ other.d->ref.ref();
+ if (!d->ref.deref())
+ delete d;
+ d = other.d;
+ }
+ return *this;
+}
+
+/*!
+ Destroys the QOpenGLFramebufferObjectFormat.
+*/
+QOpenGLFramebufferObjectFormat::~QOpenGLFramebufferObjectFormat()
+{
+ if (!d->ref.deref())
+ delete d;
+}
+
+/*!
+ Sets the number of samples per pixel for a multisample framebuffer object
+ to \a samples. The default sample count of 0 represents a regular
+ non-multisample framebuffer object.
+
+ If the desired amount of samples per pixel is not supported by the hardware
+ then the maximum number of samples per pixel will be used. Note that
+ multisample framebuffer objects can not be bound as textures. Also, the
+ \c{GL_EXT_framebuffer_multisample} extension is required to create a
+ framebuffer with more than one sample per pixel.
+
+ \sa samples()
+*/
+void QOpenGLFramebufferObjectFormat::setSamples(int samples)
+{
+ detach();
+ d->samples = samples;
+}
+
+/*!
+ Returns the number of samples per pixel if a framebuffer object
+ is a multisample framebuffer object. Otherwise, returns 0.
+ The default value is 0.
+
+ \sa setSamples()
+*/
+int QOpenGLFramebufferObjectFormat::samples() const
+{
+ return d->samples;
+}
+
+/*!
+ Enables mipmapping if \a enabled is true; otherwise disables it.
+
+ Mipmapping is disabled by default.
+
+ If mipmapping is enabled, additional memory will be allocated for
+ the mipmap levels. The mipmap levels can be updated by binding the
+ texture and calling glGenerateMipmap(). Mipmapping cannot be enabled
+ for multisampled framebuffer objects.
+
+ \sa mipmap(), QOpenGLFramebufferObject::texture()
+*/
+void QOpenGLFramebufferObjectFormat::setMipmap(bool enabled)
+{
+ detach();
+ d->mipmap = enabled;
+}
+
+/*!
+ Returns true if mipmapping is enabled.
+
+ \sa setMipmap()
+*/
+bool QOpenGLFramebufferObjectFormat::mipmap() const
+{
+ return d->mipmap;
+}
+
+/*!
+ Sets the attachment configuration of a framebuffer object to \a attachment.
+
+ \sa attachment()
+*/
+void QOpenGLFramebufferObjectFormat::setAttachment(QOpenGLFramebufferObject::Attachment attachment)
+{
+ detach();
+ d->attachment = attachment;
+}
+
+/*!
+ Returns the configuration of the depth and stencil buffers attached to
+ a framebuffer object. The default is QOpenGLFramebufferObject::NoAttachment.
+
+ \sa setAttachment()
+*/
+QOpenGLFramebufferObject::Attachment QOpenGLFramebufferObjectFormat::attachment() const
+{
+ return d->attachment;
+}
+
+/*!
+ Sets the texture target of the texture attached to a framebuffer object to
+ \a target. Ignored for multisample framebuffer objects.
+
+ \sa textureTarget(), samples()
+*/
+void QOpenGLFramebufferObjectFormat::setTextureTarget(GLenum target)
+{
+ detach();
+ d->target = target;
+}
+
+/*!
+ Returns the texture target of the texture attached to a framebuffer object.
+ Ignored for multisample framebuffer objects. The default is
+ \c GL_TEXTURE_2D.
+
+ \sa setTextureTarget(), samples()
+*/
+GLenum QOpenGLFramebufferObjectFormat::textureTarget() const
+{
+ return d->target;
+}
+
+/*!
+ Sets the internal format of a framebuffer object's texture or
+ multisample framebuffer object's color buffer to
+ \a internalTextureFormat.
+
+ \sa internalTextureFormat()
+*/
+void QOpenGLFramebufferObjectFormat::setInternalTextureFormat(GLenum internalTextureFormat)
+{
+ detach();
+ d->internal_format = internalTextureFormat;
+}
+
+/*!
+ Returns the internal format of a framebuffer object's texture or
+ multisample framebuffer object's color buffer. The default is
+ \c GL_RGBA8 on desktop OpenGL systems, and \c GL_RGBA on
+ OpenGL/ES systems.
+
+ \sa setInternalTextureFormat()
+*/
+GLenum QOpenGLFramebufferObjectFormat::internalTextureFormat() const
+{
+ return d->internal_format;
+}
+
+/*!
+ Returns true if all the options of this framebuffer object format
+ are the same as \a other; otherwise returns false.
+*/
+bool QOpenGLFramebufferObjectFormat::operator==(const QOpenGLFramebufferObjectFormat& other) const
+{
+ if (d == other.d)
+ return true;
+ else
+ return d->equals(other.d);
+}
+
+/*!
+ Returns false if all the options of this framebuffer object format
+ are the same as \a other; otherwise returns true.
+*/
+bool QOpenGLFramebufferObjectFormat::operator!=(const QOpenGLFramebufferObjectFormat& other) const
+{
+ return !(*this == other);
+}
+
+bool QOpenGLFramebufferObjectPrivate::checkFramebufferStatus() const
+{
+ QOpenGLContext *ctx = QOpenGLContext::currentContext();
+ if (!ctx)
+ return false; // Context no longer exists.
+ GLenum status = ctx->functions()->glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ switch(status) {
+ case GL_NO_ERROR:
+ case GL_FRAMEBUFFER_COMPLETE:
+ return true;
+ break;
+ case GL_FRAMEBUFFER_UNSUPPORTED:
+ qDebug("QOpenGLFramebufferObject: Unsupported framebuffer format.");
+ break;
+ case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
+ qDebug("QOpenGLFramebufferObject: Framebuffer incomplete attachment.");
+ break;
+ case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
+ qDebug("QOpenGLFramebufferObject: Framebuffer incomplete, missing attachment.");
+ break;
+#ifdef GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT
+ case GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT:
+ qDebug("QOpenGLFramebufferObject: Framebuffer incomplete, duplicate attachment.");
+ break;
+#endif
+ case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
+ qDebug("QOpenGLFramebufferObject: Framebuffer incomplete, attached images must have same dimensions.");
+ break;
+ case GL_FRAMEBUFFER_INCOMPLETE_FORMATS:
+ qDebug("QOpenGLFramebufferObject: Framebuffer incomplete, attached images must have same format.");
+ break;
+ case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
+ qDebug("QOpenGLFramebufferObject: Framebuffer incomplete, missing draw buffer.");
+ break;
+ case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
+ qDebug("QOpenGLFramebufferObject: Framebuffer incomplete, missing read buffer.");
+ break;
+ case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
+ qDebug("QOpenGLFramebufferObject: Framebuffer incomplete, attachments must have same number of samples per pixel.");
+ break;
+ default:
+ qDebug() <<"QOpenGLFramebufferObject: An undefined error has occurred: "<< status;
+ break;
+ }
+ return false;
+}
+
+namespace
+{
+ void freeFramebufferFunc(QOpenGLFunctions *funcs, GLuint id)
+ {
+ funcs->glDeleteFramebuffers(1, &id);
+ }
+
+ void freeRenderbufferFunc(QOpenGLFunctions *funcs, GLuint id)
+ {
+ funcs->glDeleteRenderbuffers(1, &id);
+ }
+
+ void freeTextureFunc(QOpenGLFunctions *, GLuint id)
+ {
+ glDeleteTextures(1, &id);
+ }
+}
+
+void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *, const QSize &sz,
+ QOpenGLFramebufferObject::Attachment attachment,
+ GLenum texture_target, GLenum internal_format,
+ GLint samples, bool mipmap)
+{
+ QOpenGLContext *ctx = QOpenGLContext::currentContext();
+
+ funcs.initializeGLFunctions();
+
+ if (!funcs.hasOpenGLFeature(QOpenGLFunctions::Framebuffers))
+ return;
+
+ size = sz;
+ target = texture_target;
+ // texture dimensions
+
+ QT_RESET_GLERROR(); // reset error state
+ GLuint fbo = 0;
+
+ funcs.glGenFramebuffers(1, &fbo);
+ funcs.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+
+ GLuint texture = 0;
+ GLuint color_buffer = 0;
+ GLuint depth_buffer = 0;
+ GLuint stencil_buffer = 0;
+
+ QT_CHECK_GLERROR();
+ // init texture
+ if (samples == 0) {
+ glGenTextures(1, &texture);
+ glBindTexture(target, texture);
+ glTexImage2D(target, 0, internal_format, size.width(), size.height(), 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ if (mipmap)
+ funcs.glGenerateMipmap(GL_TEXTURE_2D);
+#ifndef QT_OPENGL_ES
+ glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+#else
+ glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameterf(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterf(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+#endif
+ funcs.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ target, texture, 0);
+
+ QT_CHECK_GLERROR();
+ valid = checkFramebufferStatus();
+ glBindTexture(target, 0);
+
+ color_buffer = 0;
+ } else {
+ mipmap = false;
+ GLint maxSamples;
+ glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
+
+ samples = qBound(0, int(samples), int(maxSamples));
+
+ funcs.glGenRenderbuffers(1, &color_buffer);
+ funcs.glBindRenderbuffer(GL_RENDERBUFFER, color_buffer);
+ if (funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample) && samples > 0) {
+ funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
+ internal_format, size.width(), size.height());
+ } else {
+ samples = 0;
+ funcs.glRenderbufferStorage(GL_RENDERBUFFER, internal_format,
+ size.width(), size.height());
+ }
+
+ funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ GL_RENDERBUFFER, color_buffer);
+
+ QT_CHECK_GLERROR();
+ valid = checkFramebufferStatus();
+
+ if (valid)
+ funcs.glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &samples);
+ }
+
+ // In practice, a combined depth-stencil buffer is supported by all desktop platforms, while a
+ // separate stencil buffer is not. On embedded devices however, a combined depth-stencil buffer
+ // might not be supported while separate buffers are, according to QTBUG-12861.
+
+ if (attachment == QOpenGLFramebufferObject::CombinedDepthStencil
+ && funcs.hasOpenGLExtension(QOpenGLExtensions::PackedDepthStencil))
+ {
+ // depth and stencil buffer needs another extension
+ funcs.glGenRenderbuffers(1, &depth_buffer);
+ Q_ASSERT(!funcs.glIsRenderbuffer(depth_buffer));
+ funcs.glBindRenderbuffer(GL_RENDERBUFFER, depth_buffer);
+ Q_ASSERT(funcs.glIsRenderbuffer(depth_buffer));
+ if (samples != 0 && funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample))
+ funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
+ GL_DEPTH24_STENCIL8, size.width(), size.height());
+ else
+ funcs.glRenderbufferStorage(GL_RENDERBUFFER,
+ GL_DEPTH24_STENCIL8, size.width(), size.height());
+
+ stencil_buffer = depth_buffer;
+ funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+ GL_RENDERBUFFER, depth_buffer);
+ funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
+ GL_RENDERBUFFER, stencil_buffer);
+
+ valid = checkFramebufferStatus();
+ if (!valid) {
+ funcs.glDeleteRenderbuffers(1, &depth_buffer);
+ stencil_buffer = depth_buffer = 0;
+ }
+ }
+
+ if (depth_buffer == 0 && (attachment == QOpenGLFramebufferObject::CombinedDepthStencil
+ || (attachment == QOpenGLFramebufferObject::Depth)))
+ {
+ funcs.glGenRenderbuffers(1, &depth_buffer);
+ Q_ASSERT(!funcs.glIsRenderbuffer(depth_buffer));
+ funcs.glBindRenderbuffer(GL_RENDERBUFFER, depth_buffer);
+ Q_ASSERT(funcs.glIsRenderbuffer(depth_buffer));
+ if (samples != 0 && funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample)) {
+#ifdef QT_OPENGL_ES
+ if (funcs.hasOpenGLExtension(QOpenGLExtensions::Depth24)) {
+ funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
+ GL_DEPTH_COMPONENT24, size.width(), size.height());
+ } else {
+ funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
+ GL_DEPTH_COMPONENT16, size.width(), size.height());
+ }
+#else
+ funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
+ GL_DEPTH_COMPONENT, size.width(), size.height());
+#endif
+ } else {
+#ifdef QT_OPENGL_ES
+ if (funcs.hasOpenGLExtension(QOpenGLExtensions::Depth24)) {
+ funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24,
+ size.width(), size.height());
+ } else {
+ funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16,
+ size.width(), size.height());
+ }
+#else
+ funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, size.width(), size.height());
+#endif
+ }
+ funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+ GL_RENDERBUFFER, depth_buffer);
+ valid = checkFramebufferStatus();
+ if (!valid) {
+ funcs.glDeleteRenderbuffers(1, &depth_buffer);
+ depth_buffer = 0;
+ }
+ }
+
+ if (stencil_buffer == 0 && (attachment == QOpenGLFramebufferObject::CombinedDepthStencil)) {
+ funcs.glGenRenderbuffers(1, &stencil_buffer);
+ Q_ASSERT(!funcs.glIsRenderbuffer(stencil_buffer));
+ funcs.glBindRenderbuffer(GL_RENDERBUFFER, stencil_buffer);
+ Q_ASSERT(funcs.glIsRenderbuffer(stencil_buffer));
+ if (samples != 0 && funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample)) {
+#ifdef QT_OPENGL_ES
+ funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
+ GL_STENCIL_INDEX8, size.width(), size.height());
+#else
+ funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
+ GL_STENCIL_INDEX, size.width(), size.height());
+#endif
+ } else {
+#ifdef QT_OPENGL_ES
+ funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8,
+ size.width(), size.height());
+#else
+ funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX,
+ size.width(), size.height());
+#endif
+ }
+ funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
+ GL_RENDERBUFFER, stencil_buffer);
+ valid = checkFramebufferStatus();
+ if (!valid) {
+ funcs.glDeleteRenderbuffers(1, &stencil_buffer);
+ stencil_buffer = 0;
+ }
+ }
+
+ // The FBO might have become valid after removing the depth or stencil buffer.
+ valid = checkFramebufferStatus();
+
+ if (depth_buffer && stencil_buffer) {
+ fbo_attachment = QOpenGLFramebufferObject::CombinedDepthStencil;
+ } else if (depth_buffer) {
+ fbo_attachment = QOpenGLFramebufferObject::Depth;
+ } else {
+ fbo_attachment = QOpenGLFramebufferObject::NoAttachment;
+ }
+
+ funcs.glBindFramebuffer(GL_FRAMEBUFFER, ctx->d_func()->current_fbo);
+ if (valid) {
+ fbo_guard = new QOpenGLSharedResourceGuard(ctx, fbo, freeFramebufferFunc);
+ if (color_buffer)
+ color_buffer_guard = new QOpenGLSharedResourceGuard(ctx, color_buffer, freeRenderbufferFunc);
+ else
+ texture_guard = new QOpenGLSharedResourceGuard(ctx, texture, freeTextureFunc);
+ if (depth_buffer)
+ depth_buffer_guard = new QOpenGLSharedResourceGuard(ctx, depth_buffer, freeRenderbufferFunc);
+ if (stencil_buffer) {
+ if (stencil_buffer == depth_buffer)
+ stencil_buffer_guard = depth_buffer_guard;
+ else
+ stencil_buffer_guard = new QOpenGLSharedResourceGuard(ctx, stencil_buffer, freeRenderbufferFunc);
+ }
+ } else {
+ if (color_buffer)
+ funcs.glDeleteRenderbuffers(1, &color_buffer);
+ else
+ glDeleteTextures(1, &texture);
+ if (depth_buffer)
+ funcs.glDeleteRenderbuffers(1, &depth_buffer);
+ if (stencil_buffer && depth_buffer != stencil_buffer)
+ funcs.glDeleteRenderbuffers(1, &stencil_buffer);
+ funcs.glDeleteFramebuffers(1, &fbo);
+ }
+ QT_CHECK_GLERROR();
+
+ format.setTextureTarget(target);
+ format.setSamples(int(samples));
+ format.setAttachment(fbo_attachment);
+ format.setInternalTextureFormat(internal_format);
+ format.setMipmap(mipmap);
+}
+
+/*!
+ \class QOpenGLFramebufferObject
+ \brief The QOpenGLFramebufferObject class encapsulates an OpenGL framebuffer object.
+ \since 5.0
+
+ \ingroup painting-3D
+
+ The QOpenGLFramebufferObject class encapsulates an OpenGL framebuffer
+ object, defined by the \c{GL_EXT_framebuffer_object} extension. In
+ addition it provides a rendering surface that can be painted on
+ with a QPainter, rendered to using native GL calls, or both. This
+ surface can be bound and used as a regular texture in your own GL
+ drawing code. By default, the QOpenGLFramebufferObject class
+ generates a 2D GL texture (using the \c{GL_TEXTURE_2D} target),
+ which is used as the internal rendering target.
+
+ \bold{It is important to have a current GL context when creating a
+ QOpenGLFramebufferObject, otherwise initialization will fail.}
+
+ OpenGL framebuffer objects and pbuffers (see
+ \l{QOpenGLPixelBuffer}{QOpenGLPixelBuffer}) can both be used to render to
+ offscreen surfaces, but there are a number of advantages with
+ using framebuffer objects instead of pbuffers:
+
+ \list 1
+ \o A framebuffer object does not require a separate rendering
+ context, so no context switching will occur when switching
+ rendering targets. There is an overhead involved in switching
+ targets, but in general it is cheaper than a context switch to a
+ pbuffer.
+
+ \o Rendering to dynamic textures (i.e. render-to-texture
+ functionality) works on all platforms. No need to do explicit copy
+ calls from a render buffer into a texture, as was necessary on
+ systems that did not support the \c{render_texture} extension.
+
+ \o It is possible to attach several rendering buffers (or texture
+ objects) to the same framebuffer object, and render to all of them
+ without doing a context switch.
+
+ \o The OpenGL framebuffer extension is a pure GL extension with no
+ system dependant WGL, CGL, or GLX parts. This makes using
+ framebuffer objects more portable.
+ \endlist
+
+ When using a QPainter to paint to a QOpenGLFramebufferObject you should take
+ care that the QOpenGLFramebufferObject is created with the CombinedDepthStencil
+ attachment for QPainter to be able to render correctly.
+ Note that you need to create a QOpenGLFramebufferObject with more than one
+ sample per pixel for primitives to be antialiased when drawing using a
+ QPainter. To create a multisample framebuffer object you should use one of
+ the constructors that take a QOpenGLFramebufferObject parameter, and set the
+ QOpenGLFramebufferObject::samples() property to a non-zero value.
+
+ For multisample framebuffer objects a color render buffer is created,
+ otherwise a texture with the specified texture target is created.
+ The color render buffer or texture will have the specified internal
+ format, and will be bound to the \c GL_COLOR_ATTACHMENT0
+ attachment in the framebuffer object.
+
+ If you want to use a framebuffer object with multisampling enabled
+ as a texture, you first need to copy from it to a regular framebuffer
+ object using QOpenGLContext::blitFramebuffer().
+
+ \section1 Threading
+
+ As of Qt 4.8, it's possible to draw into a QOpenGLFramebufferObject
+ using a QPainter in a separate thread. Note that OpenGL 2.0 or
+ OpenGL ES 2.0 is required for this to work.
+
+ \sa {Framebuffer Object Example}
+*/
+
+
+/*!
+ \enum QOpenGLFramebufferObject::Attachment
+
+ This enum type is used to configure the depth and stencil buffers
+ attached to the framebuffer object when it is created.
+
+ \value NoAttachment No attachment is added to the framebuffer object. Note that the
+ OpenGL depth and stencil tests won't work when rendering to a
+ framebuffer object without any depth or stencil buffers.
+ This is the default value.
+
+ \value CombinedDepthStencil If the \c GL_EXT_packed_depth_stencil extension is present,
+ a combined depth and stencil buffer is attached.
+ If the extension is not present, only a depth buffer is attached.
+
+ \value Depth A depth buffer is attached to the framebuffer object.
+
+ \sa attachment()
+*/
+
+
+/*! \fn QOpenGLFramebufferObject::QOpenGLFramebufferObject(const QSize &size, GLenum target)
+
+ Constructs an OpenGL framebuffer object and binds a 2D GL texture
+ to the buffer of the size \a size. The texture is bound to the
+ \c GL_COLOR_ATTACHMENT0 target in the framebuffer object.
+
+ The \a target parameter is used to specify the GL texture
+ target. The default target is \c GL_TEXTURE_2D. Keep in mind that
+ \c GL_TEXTURE_2D textures must have a power of 2 width and height
+ (e.g. 256x512), unless you are using OpenGL 2.0 or higher.
+
+ By default, no depth and stencil buffers are attached. This behavior
+ can be toggled using one of the overloaded constructors.
+
+ The default internal texture format is \c GL_RGBA8 for desktop
+ OpenGL, and \c GL_RGBA for OpenGL/ES.
+
+ It is important that you have a current GL context set when
+ creating the QOpenGLFramebufferObject, otherwise the initialization
+ will fail.
+
+ \sa size(), texture(), attachment()
+*/
+
+QOpenGLFramebufferObject::QOpenGLFramebufferObject(const QSize &size, GLenum target)
+ : d_ptr(new QOpenGLFramebufferObjectPrivate)
+{
+ Q_D(QOpenGLFramebufferObject);
+ d->init(this, size, NoAttachment, target, DEFAULT_FORMAT);
+}
+
+/*! \overload
+
+ Constructs an OpenGL framebuffer object and binds a 2D GL texture
+ to the buffer of the given \a width and \a height.
+
+ \sa size(), texture()
+*/
+QOpenGLFramebufferObject::QOpenGLFramebufferObject(int width, int height, GLenum target)
+ : d_ptr(new QOpenGLFramebufferObjectPrivate)
+{
+ Q_D(QOpenGLFramebufferObject);
+ d->init(this, QSize(width, height), NoAttachment, target, DEFAULT_FORMAT);
+}
+
+/*! \overload
+
+ Constructs an OpenGL framebuffer object of the given \a size based on the
+ supplied \a format.
+*/
+
+QOpenGLFramebufferObject::QOpenGLFramebufferObject(const QSize &size, const QOpenGLFramebufferObjectFormat &format)
+ : d_ptr(new QOpenGLFramebufferObjectPrivate)
+{
+ Q_D(QOpenGLFramebufferObject);
+ d->init(this, size, format.attachment(), format.textureTarget(), format.internalTextureFormat(),
+ format.samples(), format.mipmap());
+}
+
+/*! \overload
+
+ Constructs an OpenGL framebuffer object of the given \a width and \a height
+ based on the supplied \a format.
+*/
+
+QOpenGLFramebufferObject::QOpenGLFramebufferObject(int width, int height, const QOpenGLFramebufferObjectFormat &format)
+ : d_ptr(new QOpenGLFramebufferObjectPrivate)
+{
+ Q_D(QOpenGLFramebufferObject);
+ d->init(this, QSize(width, height), format.attachment(), format.textureTarget(),
+ format.internalTextureFormat(), format.samples(), format.mipmap());
+}
+
+/*! \overload
+
+ Constructs an OpenGL framebuffer object and binds a texture to the
+ buffer of the given \a width and \a height.
+
+ The \a attachment parameter describes the depth/stencil buffer
+ configuration, \a target the texture target and \a internal_format
+ the internal texture format. The default texture target is \c
+ GL_TEXTURE_2D, while the default internal format is \c GL_RGBA8
+ for desktop OpenGL and \c GL_RGBA for OpenGL/ES.
+
+ \sa size(), texture(), attachment()
+*/
+QOpenGLFramebufferObject::QOpenGLFramebufferObject(int width, int height, Attachment attachment,
+ GLenum target, GLenum internal_format)
+ : d_ptr(new QOpenGLFramebufferObjectPrivate)
+{
+ Q_D(QOpenGLFramebufferObject);
+ d->init(this, QSize(width, height), attachment, target, internal_format);
+}
+
+/*! \overload
+
+ Constructs an OpenGL framebuffer object and binds a texture to the
+ buffer of the given \a size.
+
+ The \a attachment parameter describes the depth/stencil buffer
+ configuration, \a target the texture target and \a internal_format
+ the internal texture format. The default texture target is \c
+ GL_TEXTURE_2D, while the default internal format is \c GL_RGBA8
+ for desktop OpenGL and \c GL_RGBA for OpenGL/ES.
+
+ \sa size(), texture(), attachment()
+*/
+QOpenGLFramebufferObject::QOpenGLFramebufferObject(const QSize &size, Attachment attachment,
+ GLenum target, GLenum internal_format)
+ : d_ptr(new QOpenGLFramebufferObjectPrivate)
+{
+ Q_D(QOpenGLFramebufferObject);
+ d->init(this, size, attachment, target, internal_format);
+}
+
+/*!
+ \fn QOpenGLFramebufferObject::~QOpenGLFramebufferObject()
+
+ Destroys the framebuffer object and frees any allocated resources.
+*/
+QOpenGLFramebufferObject::~QOpenGLFramebufferObject()
+{
+ Q_D(QOpenGLFramebufferObject);
+
+ if (d->texture_guard)
+ d->texture_guard->free();
+ if (d->color_buffer_guard)
+ d->color_buffer_guard->free();
+ if (d->depth_buffer_guard)
+ d->depth_buffer_guard->free();
+ if (d->stencil_buffer_guard && d->stencil_buffer_guard != d->depth_buffer_guard)
+ d->stencil_buffer_guard->free();
+ if (d->fbo_guard)
+ d->fbo_guard->free();
+}
+
+/*!
+ \fn bool QOpenGLFramebufferObject::isValid() const
+
+ Returns true if the framebuffer object is valid.
+
+ The framebuffer can become invalid if the initialization process
+ fails, the user attaches an invalid buffer to the framebuffer
+ object, or a non-power of two width/height is specified as the
+ texture size if the texture target is \c{GL_TEXTURE_2D}.
+ The non-power of two limitation does not apply if the OpenGL version
+ is 2.0 or higher, or if the GL_ARB_texture_non_power_of_two extension
+ is present.
+
+ The framebuffer can also become invalid if the QOpenGLContext that
+ the framebuffer was created within is destroyed and there are
+ no other shared contexts that can take over ownership of the
+ framebuffer.
+*/
+bool QOpenGLFramebufferObject::isValid() const
+{
+ Q_D(const QOpenGLFramebufferObject);
+ return d->valid && d->fbo_guard && d->fbo_guard->id();
+}
+
+/*!
+ \fn bool QOpenGLFramebufferObject::bind()
+
+ Switches rendering from the default, windowing system provided
+ framebuffer to this framebuffer object.
+ Returns true upon success, false otherwise.
+
+ \sa release()
+*/
+bool QOpenGLFramebufferObject::bind()
+{
+ if (!isValid())
+ return false;
+ Q_D(QOpenGLFramebufferObject);
+ QOpenGLContext *current = QOpenGLContext::currentContext();
+ if (!current)
+ return false;
+#ifdef QT_DEBUG
+ if (current->shareGroup() != d->fbo_guard->group())
+ qWarning("QOpenGLFramebufferObject::bind() called from incompatible context");
+#endif
+ d->funcs.glBindFramebuffer(GL_FRAMEBUFFER, d->fbo());
+ d->valid = d->checkFramebufferStatus();
+ if (d->valid && current)
+ current->d_func()->current_fbo = d->fbo();
+ return d->valid;
+}
+
+/*!
+ \fn bool QOpenGLFramebufferObject::release()
+
+ Switches rendering back to the default, windowing system provided
+ framebuffer.
+ Returns true upon success, false otherwise.
+
+ \sa bind()
+*/
+bool QOpenGLFramebufferObject::release()
+{
+ if (!isValid())
+ return false;
+
+ QOpenGLContext *current = QOpenGLContext::currentContext();
+ if (!current)
+ return false;
+
+ Q_D(QOpenGLFramebufferObject);
+#ifdef QT_DEBUG
+ if (current->shareGroup() != d->fbo_guard->group())
+ qWarning("QOpenGLFramebufferObject::release() called from incompatible context");
+#endif
+
+ if (current) {
+ current->d_func()->current_fbo = current->d_func()->default_fbo;
+ d->funcs.glBindFramebuffer(GL_FRAMEBUFFER, current->d_func()->default_fbo);
+ }
+
+ return true;
+}
+
+/*!
+ \fn GLuint QOpenGLFramebufferObject::texture() const
+
+ Returns the texture id for the texture attached as the default
+ rendering target in this framebuffer object. This texture id can
+ be bound as a normal texture in your own GL code.
+
+ If a multisample framebuffer object is used then the value returned
+ from this function will be invalid.
+*/
+GLuint QOpenGLFramebufferObject::texture() const
+{
+ Q_D(const QOpenGLFramebufferObject);
+ return d->texture_guard ? d->texture_guard->id() : 0;
+}
+
+/*!
+ \fn QSize QOpenGLFramebufferObject::size() const
+
+ Returns the size of the texture attached to this framebuffer
+ object.
+*/
+QSize QOpenGLFramebufferObject::size() const
+{
+ Q_D(const QOpenGLFramebufferObject);
+ return d->size;
+}
+
+/*!
+ Returns the format of this framebuffer object.
+*/
+QOpenGLFramebufferObjectFormat QOpenGLFramebufferObject::format() const
+{
+ Q_D(const QOpenGLFramebufferObject);
+ return d->format;
+}
+
+namespace {
+/*
+ Read back the contents of the currently bound framebuffer, used in
+ QGLWidget::grabFrameBuffer(), QGLPixelbuffer::toImage() and
+ QGLFramebufferObject::toImage()
+*/
+
+void convertFromGLImage(QImage &img, int w, int h, bool alpha_format, bool include_alpha)
+{
+ if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
+ // OpenGL gives RGBA; Qt wants ARGB
+ uint *p = (uint*)img.bits();
+ uint *end = p + w*h;
+ if (alpha_format && include_alpha) {
+ while (p < end) {
+ uint a = *p << 24;
+ *p = (*p >> 8) | a;
+ p++;
+ }
+ } else {
+ // This is an old legacy fix for PowerPC based Macs, which
+ // we shouldn't remove
+ while (p < end) {
+ *p = 0xff000000 | (*p>>8);
+ ++p;
+ }
+ }
+ } else {
+ // OpenGL gives ABGR (i.e. RGBA backwards); Qt wants ARGB
+ for (int y = 0; y < h; y++) {
+ uint *q = (uint*)img.scanLine(y);
+ for (int x=0; x < w; ++x) {
+ const uint pixel = *q;
+ if (alpha_format && include_alpha) {
+ *q = ((pixel << 16) & 0xff0000) | ((pixel >> 16) & 0xff)
+ | (pixel & 0xff00ff00);
+ } else {
+ *q = 0xff000000 | ((pixel << 16) & 0xff0000)
+ | ((pixel >> 16) & 0xff) | (pixel & 0x00ff00);
+ }
+
+ q++;
+ }
+ }
+
+ }
+ img = img.mirrored();
+}
+
+}
+
+Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include_alpha)
+{
+ QImage img(size, (alpha_format && include_alpha) ? QImage::Format_ARGB32_Premultiplied
+ : QImage::Format_RGB32);
+ int w = size.width();
+ int h = size.height();
+ glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, img.bits());
+ convertFromGLImage(img, w, h, alpha_format, include_alpha);
+ return img;
+}
+
+/*!
+ \fn QImage QOpenGLFramebufferObject::toImage() const
+
+ Returns the contents of this framebuffer object as a QImage.
+*/
+QImage QOpenGLFramebufferObject::toImage() const
+{
+ Q_D(const QOpenGLFramebufferObject);
+ if (!d->valid)
+ return QImage();
+
+ // qt_gl_read_framebuffer doesn't work on a multisample FBO
+ if (format().samples() != 0) {
+ QOpenGLFramebufferObject temp(size(), QOpenGLFramebufferObjectFormat());
+
+ QRect rect(QPoint(0, 0), size());
+ blitFramebuffer(&temp, rect, const_cast<QOpenGLFramebufferObject *>(this), rect);
+
+ return temp.toImage();
+ }
+
+ bool wasBound = isBound();
+ if (!wasBound)
+ const_cast<QOpenGLFramebufferObject *>(this)->bind();
+ QImage image = qt_gl_read_framebuffer(d->size, format().internalTextureFormat() != GL_RGB, true);
+ if (!wasBound)
+ const_cast<QOpenGLFramebufferObject *>(this)->release();
+
+ return image;
+}
+
+/*!
+ \fn bool QOpenGLFramebufferObject::bindDefault()
+ \internal
+
+ Switches rendering back to the default, windowing system provided
+ framebuffer.
+ Returns true upon success, false otherwise.
+
+ \sa bind(), release()
+*/
+bool QOpenGLFramebufferObject::bindDefault()
+{
+ QOpenGLContext *ctx = const_cast<QOpenGLContext *>(QOpenGLContext::currentContext());
+ QOpenGLFunctions functions(ctx);
+
+ if (ctx) {
+ ctx->d_func()->current_fbo = ctx->d_func()->default_fbo;
+ functions.glBindFramebuffer(GL_FRAMEBUFFER, ctx->d_func()->default_fbo);
+#ifdef QT_DEBUG
+ } else {
+ qWarning("QOpenGLFramebufferObject::bindDefault() called without current context.");
+#endif
+ }
+
+ return ctx != 0;
+}
+
+/*!
+ \fn bool QOpenGLFramebufferObject::hasOpenGLFramebufferObjects()
+
+ Returns true if the OpenGL \c{GL_EXT_framebuffer_object} extension
+ is present on this system; otherwise returns false.
+*/
+bool QOpenGLFramebufferObject::hasOpenGLFramebufferObjects()
+{
+ return QOpenGLFunctions(QOpenGLContext::currentContext()).hasOpenGLFeature(QOpenGLFunctions::Framebuffers);
+}
+
+/*!
+ \fn GLuint QOpenGLFramebufferObject::handle() const
+
+ Returns the GL framebuffer object handle for this framebuffer
+ object (returned by the \c{glGenFrameBuffersEXT()} function). This
+ handle can be used to attach new images or buffers to the
+ framebuffer. The user is responsible for cleaning up and
+ destroying these objects.
+*/
+GLuint QOpenGLFramebufferObject::handle() const
+{
+ Q_D(const QOpenGLFramebufferObject);
+ return d->fbo();
+}
+
+/*!
+ Returns the status of the depth and stencil buffers attached to
+ this framebuffer object.
+*/
+
+QOpenGLFramebufferObject::Attachment QOpenGLFramebufferObject::attachment() const
+{
+ Q_D(const QOpenGLFramebufferObject);
+ if (d->valid)
+ return d->fbo_attachment;
+ return NoAttachment;
+}
+
+/*!
+ Returns true if the framebuffer object is currently bound to a context,
+ otherwise false is returned.
+*/
+
+bool QOpenGLFramebufferObject::isBound() const
+{
+ Q_D(const QOpenGLFramebufferObject);
+ QOpenGLContext *current = QOpenGLContext::currentContext();
+ return current ? current->d_func()->current_fbo == d->fbo() : false;
+}
+
+/*!
+ \fn bool QOpenGLFramebufferObject::hasOpenGLFramebufferBlit()
+
+ Returns true if the OpenGL \c{GL_EXT_framebuffer_blit} extension
+ is present on this system; otherwise returns false.
+
+ \sa blitFramebuffer()
+*/
+bool QOpenGLFramebufferObject::hasOpenGLFramebufferBlit()
+{
+ return QOpenGLExtensions(QOpenGLContext::currentContext()).hasOpenGLExtension(QOpenGLExtensions::FramebufferBlit);
+}
+
+
+/*!
+ \overload
+ \sa blitFramebuffer
+*/
+
+void QOpenGLFramebufferObject::blitFramebuffer(QOpenGLFramebufferObject *target,
+ QOpenGLFramebufferObject *source,
+ GLbitfield buffers, GLenum filter)
+{
+ blitFramebuffer(target, QRect(QPoint(0, 0), target->size()),
+ source, QRect(QPoint(0, 0), source->size()),
+ buffers, filter);
+}
+
+/*!
+ Blits from the \a sourceRect rectangle in the \a source framebuffer
+ object to the \a targetRect rectangle in the \a target framebuffer object.
+
+ If \a source or \a target is 0, the default framebuffer will be used
+ instead of a framebuffer object as source or target respectively.
+
+ The \a buffers parameter should be a mask consisting of any combination of
+ \c GL_COLOR_BUFFER_BIT, \c GL_DEPTH_BUFFER_BIT, and
+ \c GL_STENCIL_BUFFER_BIT. Any buffer type that is not present both
+ in the source and target buffers is ignored.
+
+ The \a sourceRect and \a targetRect rectangles may have different sizes;
+ in this case \a buffers should not contain \c GL_DEPTH_BUFFER_BIT or
+ \c GL_STENCIL_BUFFER_BIT. The \a filter parameter should be set to
+ \c GL_LINEAR or \c GL_NEAREST, and specifies whether linear or nearest
+ interpolation should be used when scaling is performed.
+
+ If \a source equals \a target a copy is performed within the same buffer.
+ Results are undefined if the source and target rectangles overlap and
+ have different sizes. The sizes must also be the same if any of the
+ framebuffer objects are multisample framebuffers.
+
+ Note that the scissor test will restrict the blit area if enabled.
+
+ This function will have no effect unless hasOpenGLFramebufferBlit() returns
+ true.
+
+ \sa hasOpenGLFramebufferBlit()
+*/
+void QOpenGLFramebufferObject::blitFramebuffer(QOpenGLFramebufferObject *target, const QRect &targetRect,
+ QOpenGLFramebufferObject *source, const QRect &sourceRect,
+ GLbitfield buffers,
+ GLenum filter)
+{
+ QOpenGLContext *ctx = QOpenGLContext::currentContext();
+ if (!ctx)
+ return;
+
+ QOpenGLExtensions extensions(ctx);
+ if (!extensions.hasOpenGLExtension(QOpenGLExtensions::FramebufferBlit))
+ return;
+
+ const int sx0 = sourceRect.left();
+ const int sx1 = sourceRect.left() + sourceRect.width();
+ const int sy0 = sourceRect.top();
+ const int sy1 = sourceRect.top() + sourceRect.height();
+
+ const int tx0 = targetRect.left();
+ const int tx1 = targetRect.left() + targetRect.width();
+ const int ty0 = targetRect.top();
+ const int ty1 = targetRect.top() + targetRect.height();
+
+ extensions.glBindFramebuffer(GL_READ_FRAMEBUFFER, source ? source->handle() : 0);
+ extensions.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, target ? target->handle() : 0);
+
+ extensions.glBlitFramebuffer(sx0, sy0, sx1, sy1,
+ tx0, ty0, tx1, ty1,
+ buffers, filter);
+
+ extensions.glBindFramebuffer(GL_FRAMEBUFFER, ctx->d_func()->current_fbo);
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/opengl/qopenglframebufferobject.h b/src/gui/opengl/qopenglframebufferobject.h
new file mode 100644
index 0000000000..17ee74aa94
--- /dev/null
+++ b/src/gui/opengl/qopenglframebufferobject.h
@@ -0,0 +1,163 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QOPENGLFRAMEBUFFEROBJECT_H
+#define QOPENGLFRAMEBUFFEROBJECT_H
+
+#include <QtGui/qopengl.h>
+#include <QtGui/qpaintdevice.h>
+
+#include <QtCore/qscopedpointer.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QOpenGLFramebufferObjectPrivate;
+class QOpenGLFramebufferObjectFormat;
+
+class Q_GUI_EXPORT QOpenGLFramebufferObject
+{
+ Q_DECLARE_PRIVATE(QOpenGLFramebufferObject)
+public:
+ enum Attachment {
+ NoAttachment,
+ CombinedDepthStencil,
+ Depth
+ };
+
+ QOpenGLFramebufferObject(const QSize &size, GLenum target = GL_TEXTURE_2D);
+ QOpenGLFramebufferObject(int width, int height, GLenum target = GL_TEXTURE_2D);
+#if !defined(QT_OPENGL_ES) || defined(Q_QDOC)
+ QOpenGLFramebufferObject(const QSize &size, Attachment attachment,
+ GLenum target = GL_TEXTURE_2D, GLenum internal_format = GL_RGBA8);
+ QOpenGLFramebufferObject(int width, int height, Attachment attachment,
+ GLenum target = GL_TEXTURE_2D, GLenum internal_format = GL_RGBA8);
+#else
+ QOpenGLFramebufferObject(const QSize &size, Attachment attachment,
+ GLenum target = GL_TEXTURE_2D, GLenum internal_format = GL_RGBA);
+ QOpenGLFramebufferObject(int width, int height, Attachment attachment,
+ GLenum target = GL_TEXTURE_2D, GLenum internal_format = GL_RGBA);
+#endif
+
+ QOpenGLFramebufferObject(const QSize &size, const QOpenGLFramebufferObjectFormat &format);
+ QOpenGLFramebufferObject(int width, int height, const QOpenGLFramebufferObjectFormat &format);
+
+ virtual ~QOpenGLFramebufferObject();
+
+ QOpenGLFramebufferObjectFormat format() const;
+
+ bool isValid() const;
+ bool isBound() const;
+ bool bind();
+ bool release();
+
+ int width() const { return size().width(); }
+ int height() const { return size().height(); }
+
+ GLuint texture() const;
+ QSize size() const;
+ QImage toImage() const;
+ Attachment attachment() const;
+
+ QPaintEngine *paintEngine() const;
+ GLuint handle() const;
+
+ static bool bindDefault();
+
+ static bool hasOpenGLFramebufferObjects();
+
+ static bool hasOpenGLFramebufferBlit();
+ static void blitFramebuffer(QOpenGLFramebufferObject *target, const QRect &targetRect,
+ QOpenGLFramebufferObject *source, const QRect &sourceRect,
+ GLbitfield buffers = GL_COLOR_BUFFER_BIT,
+ GLenum filter = GL_NEAREST);
+ static void blitFramebuffer(QOpenGLFramebufferObject *target,
+ QOpenGLFramebufferObject *source,
+ GLbitfield buffers = GL_COLOR_BUFFER_BIT,
+ GLenum filter = GL_NEAREST);
+
+private:
+ Q_DISABLE_COPY(QOpenGLFramebufferObject)
+ QScopedPointer<QOpenGLFramebufferObjectPrivate> d_ptr;
+ friend class QOpenGLPaintDevice;
+ friend class QOpenGLFBOGLPaintDevice;
+};
+
+class QOpenGLFramebufferObjectFormatPrivate;
+class Q_GUI_EXPORT QOpenGLFramebufferObjectFormat
+{
+public:
+ QOpenGLFramebufferObjectFormat();
+ QOpenGLFramebufferObjectFormat(const QOpenGLFramebufferObjectFormat &other);
+ QOpenGLFramebufferObjectFormat &operator=(const QOpenGLFramebufferObjectFormat &other);
+ ~QOpenGLFramebufferObjectFormat();
+
+ void setSamples(int samples);
+ int samples() const;
+
+ void setMipmap(bool enabled);
+ bool mipmap() const;
+
+ void setAttachment(QOpenGLFramebufferObject::Attachment attachment);
+ QOpenGLFramebufferObject::Attachment attachment() const;
+
+ void setTextureTarget(GLenum target);
+ GLenum textureTarget() const;
+
+ void setInternalTextureFormat(GLenum internalTextureFormat);
+ GLenum internalTextureFormat() const;
+
+ bool operator==(const QOpenGLFramebufferObjectFormat& other) const;
+ bool operator!=(const QOpenGLFramebufferObjectFormat& other) const;
+
+private:
+ QOpenGLFramebufferObjectFormatPrivate *d;
+
+ void detach();
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+#endif // QOPENGLFRAMEBUFFEROBJECT_H
diff --git a/src/gui/opengl/qopenglframebufferobject_p.h b/src/gui/opengl/qopenglframebufferobject_p.h
new file mode 100644
index 0000000000..93a8bbf32f
--- /dev/null
+++ b/src/gui/opengl/qopenglframebufferobject_p.h
@@ -0,0 +1,142 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QOPENGLFRAMEBUFFEROBJECT_P_H
+#define QOPENGLFRAMEBUFFEROBJECT_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the QLibrary class. This header file may change from
+// version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+QT_BEGIN_NAMESPACE
+
+QT_BEGIN_INCLUDE_NAMESPACE
+
+#include <qopenglframebufferobject.h>
+#include <private/qopenglcontext_p.h>
+#include <private/qopenglextensions_p.h>
+
+QT_END_INCLUDE_NAMESPACE
+
+#ifndef QT_OPENGL_ES
+#define DEFAULT_FORMAT GL_RGBA8
+#else
+#define DEFAULT_FORMAT GL_RGBA
+#endif
+
+class QOpenGLFramebufferObjectFormatPrivate
+{
+public:
+ QOpenGLFramebufferObjectFormatPrivate()
+ : ref(1),
+ samples(0),
+ attachment(QOpenGLFramebufferObject::NoAttachment),
+ target(GL_TEXTURE_2D),
+ internal_format(DEFAULT_FORMAT),
+ mipmap(false)
+ {
+ }
+ QOpenGLFramebufferObjectFormatPrivate
+ (const QOpenGLFramebufferObjectFormatPrivate *other)
+ : ref(1),
+ samples(other->samples),
+ attachment(other->attachment),
+ target(other->target),
+ internal_format(other->internal_format),
+ mipmap(other->mipmap)
+ {
+ }
+ bool equals(const QOpenGLFramebufferObjectFormatPrivate *other)
+ {
+ return samples == other->samples &&
+ attachment == other->attachment &&
+ target == other->target &&
+ internal_format == other->internal_format &&
+ mipmap == other->mipmap;
+ }
+
+ QAtomicInt ref;
+ int samples;
+ QOpenGLFramebufferObject::Attachment attachment;
+ GLenum target;
+ GLenum internal_format;
+ uint mipmap : 1;
+};
+
+class QOpenGLFramebufferObjectPrivate
+{
+public:
+ QOpenGLFramebufferObjectPrivate() : fbo_guard(0), texture_guard(0), depth_buffer_guard(0)
+ , stencil_buffer_guard(0), color_buffer_guard(0)
+ , valid(false) {}
+ ~QOpenGLFramebufferObjectPrivate() {}
+
+ void init(QOpenGLFramebufferObject *q, const QSize& sz,
+ QOpenGLFramebufferObject::Attachment attachment,
+ GLenum internal_format, GLenum texture_target,
+ GLint samples = 0, bool mipmap = false);
+ bool checkFramebufferStatus() const;
+ QOpenGLSharedResourceGuard *fbo_guard;
+ QOpenGLSharedResourceGuard *texture_guard;
+ QOpenGLSharedResourceGuard *depth_buffer_guard;
+ QOpenGLSharedResourceGuard *stencil_buffer_guard;
+ QOpenGLSharedResourceGuard *color_buffer_guard;
+ GLenum target;
+ QSize size;
+ QOpenGLFramebufferObjectFormat format;
+ uint valid : 1;
+ QOpenGLFramebufferObject::Attachment fbo_attachment;
+ QOpenGLExtensions funcs;
+
+ inline GLuint fbo() const { return fbo_guard ? fbo_guard->id() : 0; }
+};
+
+
+QT_END_NAMESPACE
+
+#endif // QOPENGLFRAMEBUFFEROBJECT_P_H
diff --git a/src/gui/opengl/qopenglfunctions.cpp b/src/gui/opengl/qopenglfunctions.cpp
new file mode 100644
index 0000000000..4024a3896d
--- /dev/null
+++ b/src/gui/opengl/qopenglfunctions.cpp
@@ -0,0 +1,2452 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qopenglfunctions.h"
+#include "qopenglextensions_p.h"
+#include "qdebug.h"
+#include "QtGui/private/qopenglcontext_p.h"
+#include "QtGui/private/qopengl_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QOpenGLFunctions
+ \brief The QOpenGLFunctions class provides cross-platform access to the OpenGL/ES 2.0 API.
+ \since 5.0
+ \ingroup painting-3D
+
+ OpenGL/ES 2.0 defines a subset of the OpenGL specification that is
+ common across many desktop and embedded OpenGL implementations.
+ However, it can be difficult to use the functions from that subset
+ because they need to be resolved manually on desktop systems.
+
+ QOpenGLFunctions provides a guaranteed API that is available on all
+ OpenGL systems and takes care of function resolution on systems
+ that need it. The recommended way to use QOpenGLFunctions is by
+ direct inheritance:
+
+ \code
+ class MyGLWidget : public QOpenGLWidget, protected QOpenGLFunctions
+ {
+ Q_OBJECT
+ public:
+ MyGLWidget(QWidget *parent = 0) : QOpenGLWidget(parent) {}
+
+ protected:
+ void initializeGL();
+ void paintGL();
+ };
+
+ void MyGLWidget::initializeGL()
+ {
+ initializeGLFunctions();
+ }
+ \endcode
+
+ The \c{paintGL()} function can then use any of the OpenGL/ES 2.0
+ functions without explicit resolution, such as glActiveTexture()
+ in the following example:
+
+ \code
+ void MyGLWidget::paintGL()
+ {
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_2D, textureId);
+ ...
+ }
+ \endcode
+
+ QOpenGLFunctions can also be used directly for ad-hoc invocation
+ of OpenGL/ES 2.0 functions on all platforms:
+
+ \code
+ QOpenGLFunctions glFuncs(QOpenGLContext::currentContext());
+ glFuncs.glActiveTexture(GL_TEXTURE1);
+ \endcode
+
+ QOpenGLFunctions provides wrappers for all OpenGL/ES 2.0 functions,
+ except those like \c{glDrawArrays()}, \c{glViewport()}, and
+ \c{glBindTexture()} that don't have portability issues.
+
+ Including the header for QOpenGLFunctions will also define all of
+ the OpenGL/ES 2.0 macro constants that are not already defined by
+ the system's OpenGL headers, such as \c{GL_TEXTURE1} above.
+
+ The hasOpenGLFeature() and openGLFeatures() functions can be used
+ to determine if the OpenGL implementation has a major OpenGL/ES 2.0
+ feature. For example, the following checks if non power of two
+ textures are available:
+
+ \code
+ QOpenGLFunctions funcs(QOpenGLContext::currentContext());
+ bool npot = funcs.hasOpenGLFeature(QOpenGLFunctions::NPOTTextures);
+ \endcode
+*/
+
+/*!
+ \enum QOpenGLFunctions::OpenGLFeature
+ This enum defines OpenGL/ES 2.0 features that may be optional
+ on other platforms.
+
+ \value Multitexture glActiveTexture() function is available.
+ \value Shaders Shader functions are available.
+ \value Buffers Vertex and index buffer functions are available.
+ \value Framebuffers Framebuffer object functions are available.
+ \value BlendColor glBlendColor() is available.
+ \value BlendEquation glBlendEquation() is available.
+ \value BlendEquationSeparate glBlendEquationSeparate() is available.
+ \value BlendFuncSeparate glBlendFuncSeparate() is available.
+ \value BlendSubtract Blend subtract mode is available.
+ \value CompressedTextures Compressed texture functions are available.
+ \value Multisample glSampleCoverage() function is available.
+ \value StencilSeparate Separate stencil functions are available.
+ \value NPOTTextures Non power of two textures are available.
+*/
+
+// Hidden private fields for additional extension data.
+struct QOpenGLFunctionsPrivateEx : public QOpenGLExtensionsPrivate, public QOpenGLSharedResource
+{
+ QOpenGLFunctionsPrivateEx(QOpenGLContext *context)
+ : QOpenGLExtensionsPrivate(context)
+ , QOpenGLSharedResource(context->shareGroup())
+ , m_features(-1)
+ , m_extensions(-1)
+ {}
+
+ void invalidateResource()
+ {
+ m_features = -1;
+ m_extensions = -1;
+ }
+
+ void freeResource(QOpenGLContext *)
+ {
+ // no gl resources to free
+ }
+
+ int m_features;
+ int m_extensions;
+};
+
+Q_GLOBAL_STATIC(QOpenGLMultiGroupSharedResource, qt_gl_functions_resource)
+
+static QOpenGLFunctionsPrivateEx *qt_gl_functions(QOpenGLContext *context = 0)
+{
+ if (!context)
+ context = QOpenGLContext::currentContext();
+ Q_ASSERT(context);
+ QOpenGLFunctionsPrivateEx *funcs =
+ qt_gl_functions_resource()->value<QOpenGLFunctionsPrivateEx>(context);
+ return funcs;
+}
+
+/*!
+ Constructs a default function resolver. The resolver cannot
+ be used until initializeGLFunctions() is called to specify
+ the context.
+
+ \sa initializeGLFunctions()
+*/
+QOpenGLFunctions::QOpenGLFunctions()
+ : d_ptr(0)
+{
+}
+
+/*!
+ Constructs a function resolver for \a context. If \a context
+ is null, then the resolver will be created for the current QOpenGLContext.
+
+ The context or another context in the group must be current.
+
+ An object constructed in this way can only be used with \a context
+ and other contexts that share with it. Use initializeGLFunctions()
+ to change the object's context association.
+
+ \sa initializeGLFunctions()
+*/
+QOpenGLFunctions::QOpenGLFunctions(QOpenGLContext *context)
+ : d_ptr(0)
+{
+ if (context && QOpenGLContextGroup::currentContextGroup() == context->shareGroup())
+ d_ptr = qt_gl_functions(context);
+ else
+ qWarning() << "QOpenGLFunctions created with non-current context";
+}
+
+QOpenGLExtensions::QOpenGLExtensions()
+ : QOpenGLFunctions()
+{
+}
+
+QOpenGLExtensions::QOpenGLExtensions(QOpenGLContext *context)
+ : QOpenGLFunctions(context)
+{
+}
+
+/*!
+ \fn QOpenGLFunctions::~QOpenGLFunctions()
+
+ Destroys this function resolver.
+*/
+
+static int qt_gl_resolve_features()
+{
+#if defined(QT_OPENGL_ES_2)
+ int features = QOpenGLFunctions::Multitexture |
+ QOpenGLFunctions::Shaders |
+ QOpenGLFunctions::Buffers |
+ QOpenGLFunctions::Framebuffers |
+ QOpenGLFunctions::BlendColor |
+ QOpenGLFunctions::BlendEquation |
+ QOpenGLFunctions::BlendEquationSeparate |
+ QOpenGLFunctions::BlendFuncSeparate |
+ QOpenGLFunctions::BlendSubtract |
+ QOpenGLFunctions::CompressedTextures |
+ QOpenGLFunctions::Multisample |
+ QOpenGLFunctions::StencilSeparate;
+ QOpenGLExtensionMatcher extensions;
+ if (extensions.match("GL_OES_texture_npot"))
+ features |= QOpenGLFunctions::NPOTTextures;
+ if (extensions.match("GL_IMG_texture_npot"))
+ features |= QOpenGLFunctions::NPOTTextures;
+ return features;
+#elif defined(QT_OPENGL_ES)
+ int features = QOpenGLFunctions::Multitexture |
+ QOpenGLFunctions::Buffers |
+ QOpenGLFunctions::CompressedTextures |
+ QOpenGLFunctions::Multisample;
+ QOpenGLExtensionMatcher extensions;
+ if (extensions.match("GL_OES_framebuffer_object"))
+ features |= QOpenGLFunctions::Framebuffers;
+ if (extensions.match("GL_OES_blend_equation_separate"))
+ features |= QOpenGLFunctions::BlendEquationSeparate;
+ if (extensions.match("GL_OES_blend_func_separate"))
+ features |= QOpenGLFunctions::BlendFuncSeparate;
+ if (extensions.match("GL_OES_blend_subtract"))
+ features |= QOpenGLFunctions::BlendSubtract;
+ if (extensions.match("GL_OES_texture_npot"))
+ features |= QOpenGLFunctions::NPOTTextures;
+ if (extensions.match("GL_IMG_texture_npot"))
+ features |= QOpenGLFunctions::NPOTTextures;
+ return features;
+#else
+ int features = 0;
+ //QOpenGLFormat::OpenGLVersionFlags versions = QOpenGLFormat::openGLVersionFlags();
+ QOpenGLExtensionMatcher extensions;
+
+ // Recognize features by extension name.
+ if (extensions.match("GL_ARB_multitexture"))
+ features |= QOpenGLFunctions::Multitexture;
+ if (extensions.match("GL_ARB_shader_objects"))
+ features |= QOpenGLFunctions::Shaders;
+ if (extensions.match("GL_EXT_framebuffer_object") ||
+ extensions.match("GL_ARB_framebuffer_object"))
+ features |= QOpenGLFunctions::Framebuffers;
+ if (extensions.match("GL_EXT_blend_color"))
+ features |= QOpenGLFunctions::BlendColor;
+ if (extensions.match("GL_EXT_blend_equation_separate"))
+ features |= QOpenGLFunctions::BlendEquationSeparate;
+ if (extensions.match("GL_EXT_blend_func_separate"))
+ features |= QOpenGLFunctions::BlendFuncSeparate;
+ if (extensions.match("GL_EXT_blend_subtract"))
+ features |= QOpenGLFunctions::BlendSubtract;
+ if (extensions.match("GL_ARB_texture_compression"))
+ features |= QOpenGLFunctions::CompressedTextures;
+ if (extensions.match("GL_ARB_multisample"))
+ features |= QOpenGLFunctions::Multisample;
+ if (extensions.match("GL_ARB_texture_non_power_of_two"))
+ features |= QOpenGLFunctions::NPOTTextures;
+
+ // assume version 2.0 or higher
+ features |= QOpenGLFunctions::BlendColor |
+ QOpenGLFunctions::BlendEquation |
+ QOpenGLFunctions::Multitexture |
+ QOpenGLFunctions::CompressedTextures |
+ QOpenGLFunctions::Multisample |
+ QOpenGLFunctions::BlendFuncSeparate |
+ QOpenGLFunctions::Buffers |
+ QOpenGLFunctions::Shaders |
+ QOpenGLFunctions::StencilSeparate |
+ QOpenGLFunctions::BlendEquationSeparate |
+ QOpenGLFunctions::NPOTTextures;
+ return features;
+#endif
+}
+
+static int qt_gl_resolve_extensions()
+{
+ int extensions = 0;
+ QOpenGLExtensionMatcher extensionMatcher;
+#if defined(QT_OPENGL_ES)
+ if (extensionMatcher.match("GL_OES_mapbuffer"))
+ extensions |= QOpenGLExtensions::MapBuffer;
+ if (extensionMatcher.match("GL_OES_packed_depth_stencil"))
+ extensions |= QOpenGLExtensions::PackedDepthStencil;
+ if (extensionMatcher.match("GL_OES_element_index_uint"))
+ extensions |= QOpenGLExtensions::ElementIndexUint;
+ if (extensionMatcher.match("GL_OES_depth24"))
+ extensions |= QOpenGLExtensions::Depth24;
+#else
+ extensions |= QOpenGLExtensions::ElementIndexUint | QOpenGLExtensions::MapBuffer;
+
+ // Recognize features by extension name.
+ if (extensionMatcher.match("GL_ARB_framebuffer_object")) {
+ extensions |= QOpenGLExtensions::FramebufferMultisample |
+ QOpenGLExtensions::FramebufferBlit |
+ QOpenGLExtensions::PackedDepthStencil;
+ } else {
+ if (extensionMatcher.match("GL_EXT_framebuffer_multisample"))
+ extensions |= QOpenGLExtensions::FramebufferMultisample;
+ if (extensionMatcher.match("GL_EXT_framebuffer_blit"))
+ extensions |= QOpenGLExtensions::FramebufferBlit;
+ if (extensionMatcher.match("GL_EXT_pakced_depth_stencil"))
+ extensions |= QOpenGLExtensions::PackedDepthStencil;
+ }
+#endif
+ return extensions;
+}
+
+/*!
+ Returns the set of features that are present on this system's
+ OpenGL implementation.
+
+ It is assumed that the QOpenGLContext associated with this function
+ resolver is current.
+
+ \sa hasOpenGLFeature()
+*/
+QOpenGLFunctions::OpenGLFeatures QOpenGLFunctions::openGLFeatures() const
+{
+ QOpenGLFunctionsPrivateEx *d = static_cast<QOpenGLFunctionsPrivateEx *>(d_ptr);
+ if (!d)
+ return 0;
+ if (d->m_features == -1)
+ d->m_features = qt_gl_resolve_features();
+ return QOpenGLFunctions::OpenGLFeatures(d->m_features);
+}
+
+/*!
+ Returns true if \a feature is present on this system's OpenGL
+ implementation; false otherwise.
+
+ It is assumed that the QOpenGLContext associated with this function
+ resolver is current.
+
+ \sa openGLFeatures()
+*/
+bool QOpenGLFunctions::hasOpenGLFeature(QOpenGLFunctions::OpenGLFeature feature) const
+{
+ QOpenGLFunctionsPrivateEx *d = static_cast<QOpenGLFunctionsPrivateEx *>(d_ptr);
+ if (!d)
+ return false;
+ if (d->m_features == -1)
+ d->m_features = qt_gl_resolve_features();
+ return (d->m_features & int(feature)) != 0;
+}
+
+/*!
+ Returns the set of extensions that are present on this system's
+ OpenGL implementation.
+
+ It is assumed that the QOpenGLContext associated with this extension
+ resolver is current.
+
+ \sa hasOpenGLExtensions()
+*/
+QOpenGLExtensions::OpenGLExtensions QOpenGLExtensions::openGLExtensions()
+{
+ QOpenGLFunctionsPrivateEx *d = static_cast<QOpenGLFunctionsPrivateEx *>(d_ptr);
+ if (!d)
+ return 0;
+ if (d->m_extensions == -1)
+ d->m_extensions = qt_gl_resolve_extensions();
+ return QOpenGLExtensions::OpenGLExtensions(d->m_extensions);
+}
+
+/*!
+ Returns true if \a extension is present on this system's OpenGL
+ implementation; false otherwise.
+
+ It is assumed that the QOpenGLContext associated with this extension
+ resolver is current.
+
+ \sa openGLFeatures()
+*/
+bool QOpenGLExtensions::hasOpenGLExtension(QOpenGLExtensions::OpenGLExtension extension) const
+{
+ QOpenGLFunctionsPrivateEx *d = static_cast<QOpenGLFunctionsPrivateEx *>(d_ptr);
+ if (!d)
+ return false;
+ if (d->m_extensions == -1)
+ d->m_extensions = qt_gl_resolve_extensions();
+ return (d->m_extensions & int(extension)) != 0;
+}
+
+/*!
+ Initializes GL function resolution for the current context.
+
+ After calling this function, the QOpenGLFunctions object can only be
+ used with the current context and other contexts that share with it.
+ Call initializeGLFunctions() again to change the object's context
+ association.
+*/
+void QOpenGLFunctions::initializeGLFunctions()
+{
+ d_ptr = qt_gl_functions();
+}
+
+/*!
+ \fn void QOpenGLFunctions::glActiveTexture(GLenum texture)
+
+ Convenience function that calls glActiveTexture(\a texture).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glActiveTexture.xml}{glActiveTexture()}.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glAttachShader(GLuint program, GLuint shader)
+
+ Convenience function that calls glAttachShader(\a program, \a shader).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glAttachShader.xml}{glAttachShader()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glBindAttribLocation(GLuint program, GLuint index, const char* name)
+
+ Convenience function that calls glBindAttribLocation(\a program, \a index, \a name).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glBindAttribLocation.xml}{glBindAttribLocation()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glBindBuffer(GLenum target, GLuint buffer)
+
+ Convenience function that calls glBindBuffer(\a target, \a buffer).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glBindBuffer.xml}{glBindBuffer()}.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glBindFramebuffer(GLenum target, GLuint framebuffer)
+
+ Convenience function that calls glBindFramebuffer(\a target, \a framebuffer).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glBindFramebuffer.xml}{glBindFramebuffer()}.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glBindRenderbuffer(GLenum target, GLuint renderbuffer)
+
+ Convenience function that calls glBindRenderbuffer(\a target, \a renderbuffer).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glBindRenderbuffer.xml}{glBindRenderbuffer()}.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+
+ Convenience function that calls glBlendColor(\a red, \a green, \a blue, \a alpha).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glBlendColor.xml}{glBlendColor()}.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glBlendEquation(GLenum mode)
+
+ Convenience function that calls glBlendEquation(\a mode).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glBlendEquation.xml}{glBlendEquation()}.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
+
+ Convenience function that calls glBlendEquationSeparate(\a modeRGB, \a modeAlpha).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glBlendEquationSeparate.xml}{glBlendEquationSeparate()}.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
+
+ Convenience function that calls glBlendFuncSeparate(\a srcRGB, \a dstRGB, \a srcAlpha, \a dstAlpha).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glBlendFuncSeparate.xml}{glBlendFuncSeparate()}.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glBufferData(GLenum target, qopengl_GLsizeiptr size, const void* data, GLenum usage)
+
+ Convenience function that calls glBufferData(\a target, \a size, \a data, \a usage).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glBufferData.xml}{glBufferData()}.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glBufferSubData(GLenum target, qopengl_GLintptr offset, qopengl_GLsizeiptr size, const void* data)
+
+ Convenience function that calls glBufferSubData(\a target, \a offset, \a size, \a data).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glBufferSubData.xml}{glBufferSubData()}.
+*/
+
+/*!
+ \fn GLenum QOpenGLFunctions::glCheckFramebufferStatus(GLenum target)
+
+ Convenience function that calls glCheckFramebufferStatus(\a target).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glCheckFramebufferStatus.xml}{glCheckFramebufferStatus()}.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glClearDepthf(GLclampf depth)
+
+ Convenience function that calls glClearDepth(\a depth) on
+ desktop OpenGL systems and glClearDepthf(\a depth) on
+ embedded OpenGL/ES systems.
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glClearDepthf.xml}{glClearDepthf()}.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glCompileShader(GLuint shader)
+
+ Convenience function that calls glCompileShader(\a shader).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glCompileShader.xml}{glCompileShader()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data)
+
+ Convenience function that calls glCompressedTexImage2D(\a target, \a level, \a internalformat, \a width, \a height, \a border, \a imageSize, \a data).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glCompressedTexImage2D.xml}{glCompressedTexImage2D()}.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data)
+
+ Convenience function that calls glCompressedTexSubImage2D(\a target, \a level, \a xoffset, \a yoffset, \a width, \a height, \a format, \a imageSize, \a data).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glCompressedTexSubImage2D.xml}{glCompressedTexSubImage2D()}.
+*/
+
+/*!
+ \fn GLuint QOpenGLFunctions::glCreateProgram()
+
+ Convenience function that calls glCreateProgram().
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glCreateProgram.xml}{glCreateProgram()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn GLuint QOpenGLFunctions::glCreateShader(GLenum type)
+
+ Convenience function that calls glCreateShader(\a type).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glCreateShader.xml}{glCreateShader()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glDeleteBuffers(GLsizei n, const GLuint* buffers)
+
+ Convenience function that calls glDeleteBuffers(\a n, \a buffers).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glDeleteBuffers.xml}{glDeleteBuffers()}.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
+
+ Convenience function that calls glDeleteFramebuffers(\a n, \a framebuffers).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glDeleteFramebuffers.xml}{glDeleteFramebuffers()}.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glDeleteProgram(GLuint program)
+
+ Convenience function that calls glDeleteProgram(\a program).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glDeleteProgram.xml}{glDeleteProgram()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
+
+ Convenience function that calls glDeleteRenderbuffers(\a n, \a renderbuffers).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glDeleteRenderbuffers.xml}{glDeleteRenderbuffers()}.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glDeleteShader(GLuint shader)
+
+ Convenience function that calls glDeleteShader(\a shader).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glDeleteShader.xml}{glDeleteShader()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glDepthRangef(GLclampf zNear, GLclampf zFar)
+
+ Convenience function that calls glDepthRange(\a zNear, \a zFar) on
+ desktop OpenGL systems and glDepthRangef(\a zNear, \a zFar) on
+ embedded OpenGL/ES systems.
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glDepthRangef.xml}{glDepthRangef()}.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glDetachShader(GLuint program, GLuint shader)
+
+ Convenience function that calls glDetachShader(\a program, \a shader).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glDetachShader.xml}{glDetachShader()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glDisableVertexAttribArray(GLuint index)
+
+ Convenience function that calls glDisableVertexAttribArray(\a index).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glDisableVertexAttribArray.xml}{glDisableVertexAttribArray()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glEnableVertexAttribArray(GLuint index)
+
+ Convenience function that calls glEnableVertexAttribArray(\a index).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glEnableVertexAttribArray.xml}{glEnableVertexAttribArray()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
+
+ Convenience function that calls glFramebufferRenderbuffer(\a target, \a attachment, \a renderbuffertarget, \a renderbuffer).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glFramebufferRenderbuffer.xml}{glFramebufferRenderbuffer()}.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
+
+ Convenience function that calls glFramebufferTexture2D(\a target, \a attachment, \a textarget, \a texture, \a level).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glFramebufferTexture2D.xml}{glFramebufferTexture2D()}.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glGenBuffers(GLsizei n, GLuint* buffers)
+
+ Convenience function that calls glGenBuffers(\a n, \a buffers).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glGenBuffers.xml}{glGenBuffers()}.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glGenerateMipmap(GLenum target)
+
+ Convenience function that calls glGenerateMipmap(\a target).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glGenerateMipmap.xml}{glGenerateMipmap()}.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glGenFramebuffers(GLsizei n, GLuint* framebuffers)
+
+ Convenience function that calls glGenFramebuffers(\a n, \a framebuffers).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glGenFramebuffers.xml}{glGenFramebuffers()}.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
+
+ Convenience function that calls glGenRenderbuffers(\a n, \a renderbuffers).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glGenRenderbuffers.xml}{glGenRenderbuffers()}.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name)
+
+ Convenience function that calls glGetActiveAttrib(\a program, \a index, \a bufsize, \a length, \a size, \a type, \a name).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glGetActiveAttrib.xml}{glGetActiveAttrib()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name)
+
+ Convenience function that calls glGetActiveUniform(\a program, \a index, \a bufsize, \a length, \a size, \a type, \a name).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glGetActiveUniform.xml}{glGetActiveUniform()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
+
+ Convenience function that calls glGetAttachedShaders(\a program, \a maxcount, \a count, \a shaders).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glGetAttachedShaders.xml}{glGetAttachedShaders()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn GLint QOpenGLFunctions::glGetAttribLocation(GLuint program, const char* name)
+
+ Convenience function that calls glGetAttribLocation(\a program, \a name).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glGetAttribLocation.xml}{glGetAttribLocation()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
+
+ Convenience function that calls glGetBufferParameteriv(\a target, \a pname, \a params).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glGetBufferParameteriv.xml}{glGetBufferParameteriv()}.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
+
+ Convenience function that calls glGetFramebufferAttachmentParameteriv(\a target, \a attachment, \a pname, \a params).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glGetFramebufferAttachmentParameteriv.xml}{glGetFramebufferAttachmentParameteriv()}.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glGetProgramiv(GLuint program, GLenum pname, GLint* params)
+
+ Convenience function that calls glGetProgramiv(\a program, \a pname, \a params).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glGetProgramiv.xml}{glGetProgramiv()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, char* infolog)
+
+ Convenience function that calls glGetProgramInfoLog(\a program, \a bufsize, \a length, \a infolog).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glGetProgramInfoLog.xml}{glGetProgramInfoLog()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
+
+ Convenience function that calls glGetRenderbufferParameteriv(\a target, \a pname, \a params).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glGetRenderbufferParameteriv.xml}{glGetRenderbufferParameteriv()}.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
+
+ Convenience function that calls glGetShaderiv(\a shader, \a pname, \a params).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glGetShaderiv.xml}{glGetShaderiv()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog)
+
+ Convenience function that calls glGetShaderInfoLog(\a shader, \a bufsize, \a length, \a infolog).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glGetShaderInfoLog.xml}{glGetShaderInfoLog()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
+
+ Convenience function that calls glGetShaderPrecisionFormat(\a shadertype, \a precisiontype, \a range, \a precision).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glGetShaderPrecisionFormat.xml}{glGetShaderPrecisionFormat()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, char* source)
+
+ Convenience function that calls glGetShaderSource(\a shader, \a bufsize, \a length, \a source).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glGetShaderSource.xml}{glGetShaderSource()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glGetUniformfv(GLuint program, GLint location, GLfloat* params)
+
+ Convenience function that calls glGetUniformfv(\a program, \a location, \a params).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glGetUniformfv.xml}{glGetUniformfv()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glGetUniformiv(GLuint program, GLint location, GLint* params)
+
+ Convenience function that calls glGetUniformiv(\a program, \a location, \a params).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glGetUniformiv.xml}{glGetUniformiv()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn GLint QOpenGLFunctions::glGetUniformLocation(GLuint program, const char* name)
+
+ Convenience function that calls glGetUniformLocation(\a program, \a name).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glGetUniformLocation.xml}{glGetUniformLocation()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
+
+ Convenience function that calls glGetVertexAttribfv(\a index, \a pname, \a params).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glGetVertexAttribfv.xml}{glGetVertexAttribfv()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
+
+ Convenience function that calls glGetVertexAttribiv(\a index, \a pname, \a params).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glGetVertexAttribiv.xml}{glGetVertexAttribiv()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glGetVertexAttribPointerv(GLuint index, GLenum pname, void** pointer)
+
+ Convenience function that calls glGetVertexAttribPointerv(\a index, \a pname, \a pointer).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glGetVertexAttribPointerv.xml}{glGetVertexAttribPointerv()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn GLboolean QOpenGLFunctions::glIsBuffer(GLuint buffer)
+
+ Convenience function that calls glIsBuffer(\a buffer).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glIsBuffer.xml}{glIsBuffer()}.
+*/
+
+/*!
+ \fn GLboolean QOpenGLFunctions::glIsFramebuffer(GLuint framebuffer)
+
+ Convenience function that calls glIsFramebuffer(\a framebuffer).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glIsFramebuffer.xml}{glIsFramebuffer()}.
+*/
+
+/*!
+ \fn GLboolean QOpenGLFunctions::glIsProgram(GLuint program)
+
+ Convenience function that calls glIsProgram(\a program).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glIsProgram.xml}{glIsProgram()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn GLboolean QOpenGLFunctions::glIsRenderbuffer(GLuint renderbuffer)
+
+ Convenience function that calls glIsRenderbuffer(\a renderbuffer).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glIsRenderbuffer.xml}{glIsRenderbuffer()}.
+*/
+
+/*!
+ \fn GLboolean QOpenGLFunctions::glIsShader(GLuint shader)
+
+ Convenience function that calls glIsShader(\a shader).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glIsShader.xml}{glIsShader()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glLinkProgram(GLuint program)
+
+ Convenience function that calls glLinkProgram(\a program).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glLinkProgram.xml}{glLinkProgram()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glReleaseShaderCompiler()
+
+ Convenience function that calls glReleaseShaderCompiler().
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glReleaseShaderCompiler.xml}{glReleaseShaderCompiler()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
+
+ Convenience function that calls glRenderbufferStorage(\a target, \a internalformat, \a width, \a height).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glRenderbufferStorage.xml}{glRenderbufferStorage()}.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glSampleCoverage(GLclampf value, GLboolean invert)
+
+ Convenience function that calls glSampleCoverage(\a value, \a invert).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glSampleCoverage.xml}{glSampleCoverage()}.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glShaderBinary(GLint n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLint length)
+
+ Convenience function that calls glShaderBinary(\a n, \a shaders, \a binaryformat, \a binary, \a length).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glShaderBinary.xml}{glShaderBinary()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glShaderSource(GLuint shader, GLsizei count, const char** string, const GLint* length)
+
+ Convenience function that calls glShaderSource(\a shader, \a count, \a string, \a length).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glShaderSource.xml}{glShaderSource()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
+
+ Convenience function that calls glStencilFuncSeparate(\a face, \a func, \a ref, \a mask).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glStencilFuncSeparate.xml}{glStencilFuncSeparate()}.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glStencilMaskSeparate(GLenum face, GLuint mask)
+
+ Convenience function that calls glStencilMaskSeparate(\a face, \a mask).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glStencilMaskSeparate.xml}{glStencilMaskSeparate()}.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
+
+ Convenience function that calls glStencilOpSeparate(\a face, \a fail, \a zfail, \a zpass).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glStencilOpSeparate.xml}{glStencilOpSeparate()}.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glUniform1f(GLint location, GLfloat x)
+
+ Convenience function that calls glUniform1f(\a location, \a x).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glUniform1f.xml}{glUniform1f()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
+
+ Convenience function that calls glUniform1fv(\a location, \a count, \a v).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glUniform1fv.xml}{glUniform1fv()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glUniform1i(GLint location, GLint x)
+
+ Convenience function that calls glUniform1i(\a location, \a x).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glUniform1i.xml}{glUniform1i()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glUniform1iv(GLint location, GLsizei count, const GLint* v)
+
+ Convenience function that calls glUniform1iv(\a location, \a count, \a v).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glUniform1iv.xml}{glUniform1iv()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glUniform2f(GLint location, GLfloat x, GLfloat y)
+
+ Convenience function that calls glUniform2f(\a location, \a x, \a y).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glUniform2f.xml}{glUniform2f()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
+
+ Convenience function that calls glUniform2fv(\a location, \a count, \a v).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glUniform2fv.xml}{glUniform2fv()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glUniform2i(GLint location, GLint x, GLint y)
+
+ Convenience function that calls glUniform2i(\a location, \a x, \a y).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glUniform2i.xml}{glUniform2i()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glUniform2iv(GLint location, GLsizei count, const GLint* v)
+
+ Convenience function that calls glUniform2iv(\a location, \a count, \a v).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glUniform2iv.xml}{glUniform2iv()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
+
+ Convenience function that calls glUniform3f(\a location, \a x, \a y, \a z).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glUniform3f.xml}{glUniform3f()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
+
+ Convenience function that calls glUniform3fv(\a location, \a count, \a v).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glUniform3fv.xml}{glUniform3fv()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glUniform3i(GLint location, GLint x, GLint y, GLint z)
+
+ Convenience function that calls glUniform3i(\a location, \a x, \a y, \a z).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glUniform3i.xml}{glUniform3i()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glUniform3iv(GLint location, GLsizei count, const GLint* v)
+
+ Convenience function that calls glUniform3iv(\a location, \a count, \a v).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glUniform3iv.xml}{glUniform3iv()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+
+ Convenience function that calls glUniform4f(\a location, \a x, \a y, \a z, \a w).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glUniform4f.xml}{glUniform4f()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
+
+ Convenience function that calls glUniform4fv(\a location, \a count, \a v).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glUniform4fv.xml}{glUniform4fv()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
+
+ Convenience function that calls glUniform4i(\a location, \a x, \a y, \a z, \a w).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glUniform4i.xml}{glUniform4i()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glUniform4iv(GLint location, GLsizei count, const GLint* v)
+
+ Convenience function that calls glUniform4iv(\a location, \a count, \a v).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glUniform4iv.xml}{glUniform4iv()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+
+ Convenience function that calls glUniformMatrix2fv(\a location, \a count, \a transpose, \a value).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glUniformMatrix2fv.xml}{glUniformMatrix2fv()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+
+ Convenience function that calls glUniformMatrix3fv(\a location, \a count, \a transpose, \a value).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glUniformMatrix3fv.xml}{glUniformMatrix3fv()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+
+ Convenience function that calls glUniformMatrix4fv(\a location, \a count, \a transpose, \a value).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glUniformMatrix4fv.xml}{glUniformMatrix4fv()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glUseProgram(GLuint program)
+
+ Convenience function that calls glUseProgram(\a program).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glUseProgram.xml}{glUseProgram()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glValidateProgram(GLuint program)
+
+ Convenience function that calls glValidateProgram(\a program).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glValidateProgram.xml}{glValidateProgram()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glVertexAttrib1f(GLuint indx, GLfloat x)
+
+ Convenience function that calls glVertexAttrib1f(\a indx, \a x).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glVertexAttrib1f.xml}{glVertexAttrib1f()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glVertexAttrib1fv(GLuint indx, const GLfloat* values)
+
+ Convenience function that calls glVertexAttrib1fv(\a indx, \a values).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glVertexAttrib1fv.xml}{glVertexAttrib1fv()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glVertexAttrib2f(GLuint indx, GLfloat x, GLfloat y)
+
+ Convenience function that calls glVertexAttrib2f(\a indx, \a x, \a y).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glVertexAttrib2f.xml}{glVertexAttrib2f()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glVertexAttrib2fv(GLuint indx, const GLfloat* values)
+
+ Convenience function that calls glVertexAttrib2fv(\a indx, \a values).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glVertexAttrib2fv.xml}{glVertexAttrib2fv()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glVertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z)
+
+ Convenience function that calls glVertexAttrib3f(\a indx, \a x, \a y, \a z).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glVertexAttrib3f.xml}{glVertexAttrib3f()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glVertexAttrib3fv(GLuint indx, const GLfloat* values)
+
+ Convenience function that calls glVertexAttrib3fv(\a indx, \a values).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glVertexAttrib3fv.xml}{glVertexAttrib3fv()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glVertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+
+ Convenience function that calls glVertexAttrib4f(\a indx, \a x, \a y, \a z, \a w).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glVertexAttrib4f.xml}{glVertexAttrib4f()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glVertexAttrib4fv(GLuint indx, const GLfloat* values)
+
+ Convenience function that calls glVertexAttrib4fv(\a indx, \a values).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glVertexAttrib4fv.xml}{glVertexAttrib4fv()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+/*!
+ \fn void QOpenGLFunctions::glVertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr)
+
+ Convenience function that calls glVertexAttribPointer(\a indx, \a size, \a type, \a normalized, \a stride, \a ptr).
+
+ For more information, see the OpenGL/ES 2.0 documentation for
+ \l{http://www.khronos.org/opengles/sdk/docs/man/glVertexAttribPointer.xml}{glVertexAttribPointer()}.
+
+ This convenience function will do nothing on OpenGL/ES 1.x systems.
+*/
+
+namespace {
+
+enum ResolvePolicy
+{
+ ResolveOES = 0x1,
+ ResolveEXT = 0x2
+};
+
+template <typename Base, typename FuncType, int Policy, typename ReturnType>
+class Resolver
+{
+public:
+ Resolver(FuncType Base::*func, FuncType fallback, const char *name, const char *alternateName = 0)
+ : funcPointerName(func)
+ , fallbackFuncPointer(fallback)
+ , funcName(name)
+ , alternateFuncName(alternateName)
+ {
+ }
+
+ ReturnType operator()();
+
+ template <typename P1>
+ ReturnType operator()(P1 p1);
+
+ template <typename P1, typename P2>
+ ReturnType operator()(P1 p1, P2 p2);
+
+ template <typename P1, typename P2, typename P3>
+ ReturnType operator()(P1 p1, P2 p2, P3 p3);
+
+ template <typename P1, typename P2, typename P3, typename P4>
+ ReturnType operator()(P1 p1, P2 p2, P3 p3, P4 p4);
+
+ template <typename P1, typename P2, typename P3, typename P4, typename P5>
+ ReturnType operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5);
+
+ template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
+ ReturnType operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6);
+
+ template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>
+ ReturnType operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7);
+
+ template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8>
+ ReturnType operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8);
+
+ template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9>
+ ReturnType operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9);
+
+ template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10>
+ ReturnType operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10);
+
+private:
+ FuncType Base::*funcPointerName;
+ FuncType fallbackFuncPointer;
+ QByteArray funcName;
+ QByteArray alternateFuncName;
+};
+
+template <typename Base, typename FuncType, int Policy>
+class Resolver<Base, FuncType, Policy, void>
+{
+public:
+ Resolver(FuncType Base::*func, FuncType fallback, const char *name, const char *alternateName = 0)
+ : funcPointerName(func)
+ , fallbackFuncPointer(fallback)
+ , funcName(name)
+ , alternateFuncName(alternateName)
+ {
+ }
+
+ void operator()();
+
+ template <typename P1>
+ void operator()(P1 p1);
+
+ template <typename P1, typename P2>
+ void operator()(P1 p1, P2 p2);
+
+ template <typename P1, typename P2, typename P3>
+ void operator()(P1 p1, P2 p2, P3 p3);
+
+ template <typename P1, typename P2, typename P3, typename P4>
+ void operator()(P1 p1, P2 p2, P3 p3, P4 p4);
+
+ template <typename P1, typename P2, typename P3, typename P4, typename P5>
+ void operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5);
+
+ template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
+ void operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6);
+
+ template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>
+ void operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7);
+
+ template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8>
+ void operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8);
+
+ template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9>
+ void operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9);
+
+ template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10>
+ void operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10);
+
+private:
+ FuncType Base::*funcPointerName;
+ FuncType fallbackFuncPointer;
+ QByteArray funcName;
+ QByteArray alternateFuncName;
+};
+
+#define RESOLVER_COMMON \
+ QOpenGLContext *context = QOpenGLContext::currentContext(); \
+ Base *funcs = qt_gl_functions(context); \
+ \
+ FuncType old = funcs->*funcPointerName; \
+ \
+ funcs->*funcPointerName = (FuncType)context->getProcAddress(funcName); \
+ \
+ if ((Policy & ResolveOES) && !(funcs->*funcPointerName)) \
+ funcs->*funcPointerName = (FuncType)context->getProcAddress(funcName + "OES"); \
+ \
+ if (!(funcs->*funcPointerName)) \
+ funcs->*funcPointerName = (FuncType)context->getProcAddress(funcName + "ARB"); \
+ \
+ if ((Policy & ResolveEXT) && !(funcs->*funcPointerName)) \
+ funcs->*funcPointerName = (FuncType)context->getProcAddress(funcName + "EXT"); \
+ \
+ if (!alternateFuncName.isEmpty() && !(funcs->*funcPointerName)) { \
+ funcs->*funcPointerName = (FuncType)context->getProcAddress(alternateFuncName); \
+ \
+ if ((Policy & ResolveOES) && !(funcs->*funcPointerName)) \
+ funcs->*funcPointerName = (FuncType)context->getProcAddress(alternateFuncName + "OES"); \
+ \
+ if (!(funcs->*funcPointerName)) \
+ funcs->*funcPointerName = (FuncType)context->getProcAddress(alternateFuncName + "ARB"); \
+ \
+ if ((Policy & ResolveEXT) && !(funcs->*funcPointerName)) \
+ funcs->*funcPointerName = (FuncType)context->getProcAddress(alternateFuncName + "EXT"); \
+ }
+
+#define RESOLVER_COMMON_NON_VOID \
+ RESOLVER_COMMON \
+ \
+ if (!(funcs->*funcPointerName)) { \
+ if (fallbackFuncPointer) { \
+ funcs->*funcPointerName = fallbackFuncPointer; \
+ } else { \
+ funcs->*funcPointerName = old; \
+ return ReturnType(); \
+ } \
+ }
+
+#define RESOLVER_COMMON_VOID \
+ RESOLVER_COMMON \
+ \
+ if (!(funcs->*funcPointerName)) { \
+ if (fallbackFuncPointer) { \
+ funcs->*funcPointerName = fallbackFuncPointer; \
+ } else { \
+ funcs->*funcPointerName = old; \
+ return; \
+ } \
+ }
+
+template <typename Base, typename FuncType, int Policy, typename ReturnType>
+ReturnType Resolver<Base, FuncType, Policy, ReturnType>::operator()()
+{
+ RESOLVER_COMMON_NON_VOID
+
+ return (funcs->*funcPointerName)();
+}
+
+template <typename Base, typename FuncType, int Policy, typename ReturnType> template <typename P1>
+ReturnType Resolver<Base, FuncType, Policy, ReturnType>::operator()(P1 p1)
+{
+ RESOLVER_COMMON_NON_VOID
+
+ return (funcs->*funcPointerName)(p1);
+}
+
+template <typename Base, typename FuncType, int Policy, typename ReturnType> template <typename P1, typename P2>
+ReturnType Resolver<Base, FuncType, Policy, ReturnType>::operator()(P1 p1, P2 p2)
+{
+ RESOLVER_COMMON_NON_VOID
+
+ return (funcs->*funcPointerName)(p1, p2);
+}
+
+template <typename Base, typename FuncType, int Policy, typename ReturnType> template <typename P1, typename P2, typename P3>
+ReturnType Resolver<Base, FuncType, Policy, ReturnType>::operator()(P1 p1, P2 p2, P3 p3)
+{
+ RESOLVER_COMMON_NON_VOID
+
+ return (funcs->*funcPointerName)(p1, p2, p3);
+}
+
+template <typename Base, typename FuncType, int Policy, typename ReturnType> template <typename P1, typename P2, typename P3, typename P4>
+ReturnType Resolver<Base, FuncType, Policy, ReturnType>::operator()(P1 p1, P2 p2, P3 p3, P4 p4)
+{
+ RESOLVER_COMMON_NON_VOID
+
+ return (funcs->*funcPointerName)(p1, p2, p3, p4);
+}
+
+template <typename Base, typename FuncType, int Policy, typename ReturnType> template <typename P1, typename P2, typename P3, typename P4, typename P5>
+ReturnType Resolver<Base, FuncType, Policy, ReturnType>::operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5)
+{
+ RESOLVER_COMMON_NON_VOID
+
+ return (funcs->*funcPointerName)(p1, p2, p3, p4, p5);
+}
+
+template <typename Base, typename FuncType, int Policy, typename ReturnType> template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
+ReturnType Resolver<Base, FuncType, Policy, ReturnType>::operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6)
+{
+ RESOLVER_COMMON_NON_VOID
+
+ return (funcs->*funcPointerName)(p1, p2, p3, p4, p5, p6);
+}
+
+template <typename Base, typename FuncType, int Policy, typename ReturnType> template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>
+ReturnType Resolver<Base, FuncType, Policy, ReturnType>::operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7)
+{
+ RESOLVER_COMMON_NON_VOID
+
+ return (funcs->*funcPointerName)(p1, p2, p3, p4, p5, p6, p7);
+}
+
+template <typename Base, typename FuncType, int Policy, typename ReturnType> template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8>
+ReturnType Resolver<Base, FuncType, Policy, ReturnType>::operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8)
+{
+ RESOLVER_COMMON_NON_VOID
+
+ return (funcs->*funcPointerName)(p1, p2, p3, p4, p5, p6, p7, p8);
+}
+
+template <typename Base, typename FuncType, int Policy, typename ReturnType> template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9>
+ReturnType Resolver<Base, FuncType, Policy, ReturnType>::operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9)
+{
+ RESOLVER_COMMON_NON_VOID
+
+ return (funcs->*funcPointerName)(p1, p2, p3, p4, p5, p6, p7, p8, p9);
+}
+
+template <typename Base, typename FuncType, int Policy, typename ReturnType> template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10>
+ReturnType Resolver<Base, FuncType, Policy, ReturnType>::operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10)
+{
+ RESOLVER_COMMON_NON_VOID
+
+ return (funcs->*funcPointerName)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
+}
+
+template <typename Base, typename FuncType, int Policy>
+void Resolver<Base, FuncType, Policy, void>::operator()()
+{
+ RESOLVER_COMMON_VOID
+
+ (funcs->*funcPointerName)();
+}
+
+template <typename Base, typename FuncType, int Policy> template <typename P1>
+void Resolver<Base, FuncType, Policy, void>::operator()(P1 p1)
+{
+ RESOLVER_COMMON_VOID
+
+ (funcs->*funcPointerName)(p1);
+}
+
+template <typename Base, typename FuncType, int Policy> template <typename P1, typename P2>
+void Resolver<Base, FuncType, Policy, void>::operator()(P1 p1, P2 p2)
+{
+ RESOLVER_COMMON_VOID
+
+ (funcs->*funcPointerName)(p1, p2);
+}
+
+template <typename Base, typename FuncType, int Policy> template <typename P1, typename P2, typename P3>
+void Resolver<Base, FuncType, Policy, void>::operator()(P1 p1, P2 p2, P3 p3)
+{
+ RESOLVER_COMMON_VOID
+
+ (funcs->*funcPointerName)(p1, p2, p3);
+}
+
+template <typename Base, typename FuncType, int Policy> template <typename P1, typename P2, typename P3, typename P4>
+void Resolver<Base, FuncType, Policy, void>::operator()(P1 p1, P2 p2, P3 p3, P4 p4)
+{
+ RESOLVER_COMMON_VOID
+
+ (funcs->*funcPointerName)(p1, p2, p3, p4);
+}
+
+template <typename Base, typename FuncType, int Policy> template <typename P1, typename P2, typename P3, typename P4, typename P5>
+void Resolver<Base, FuncType, Policy, void>::operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5)
+{
+ RESOLVER_COMMON_VOID
+
+ (funcs->*funcPointerName)(p1, p2, p3, p4, p5);
+}
+
+template <typename Base, typename FuncType, int Policy> template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
+void Resolver<Base, FuncType, Policy, void>::operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6)
+{
+ RESOLVER_COMMON_VOID
+
+ (funcs->*funcPointerName)(p1, p2, p3, p4, p5, p6);
+}
+
+template <typename Base, typename FuncType, int Policy> template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>
+void Resolver<Base, FuncType, Policy, void>::operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7)
+{
+ RESOLVER_COMMON_VOID
+
+ (funcs->*funcPointerName)(p1, p2, p3, p4, p5, p6, p7);
+}
+
+template <typename Base, typename FuncType, int Policy> template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8>
+void Resolver<Base, FuncType, Policy, void>::operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8)
+{
+ RESOLVER_COMMON_VOID
+
+ (funcs->*funcPointerName)(p1, p2, p3, p4, p5, p6, p7, p8);
+}
+
+template <typename Base, typename FuncType, int Policy> template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9>
+void Resolver<Base, FuncType, Policy, void>::operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9)
+{
+ RESOLVER_COMMON_VOID
+
+ (funcs->*funcPointerName)(p1, p2, p3, p4, p5, p6, p7, p8, p9);
+}
+
+template <typename Base, typename FuncType, int Policy> template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10>
+void Resolver<Base, FuncType, Policy, void>::operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10)
+{
+ RESOLVER_COMMON_VOID
+
+ (funcs->*funcPointerName)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
+}
+
+template <typename ReturnType, int Policy, typename Base, typename FuncType>
+Resolver<Base, FuncType, Policy, ReturnType> functionResolverWithFallback(FuncType Base::*func, FuncType fallback, const char *name, const char *alternate = 0)
+{
+ return Resolver<Base, FuncType, Policy, ReturnType>(func, fallback, name, alternate);
+}
+
+template <typename ReturnType, int Policy, typename Base, typename FuncType>
+Resolver<Base, FuncType, Policy, ReturnType> functionResolver(FuncType Base::*func, const char *name, const char *alternate = 0)
+{
+ return Resolver<Base, FuncType, Policy, ReturnType>(func, 0, name, alternate);
+}
+
+}
+
+#define RESOLVE_FUNC(RETURN_TYPE, POLICY, NAME) \
+ return functionResolver<RETURN_TYPE, POLICY>(&QOpenGLExtensionsPrivate::NAME, "gl" #NAME)
+
+#define RESOLVE_FUNC_VOID(POLICY, NAME) \
+ functionResolver<void, POLICY>(&QOpenGLExtensionsPrivate::NAME, "gl" #NAME)
+
+#define RESOLVE_FUNC_SPECIAL(RETURN_TYPE, POLICY, NAME) \
+ return functionResolverWithFallback<RETURN_TYPE, POLICY>(&QOpenGLExtensionsPrivate::NAME, qopenglfSpecial##NAME, "gl" #NAME)
+
+#define RESOLVE_FUNC_SPECIAL_VOID(POLICY, NAME) \
+ functionResolverWithFallback<void, POLICY>(&QOpenGLExtensionsPrivate::NAME, qopenglfSpecial##NAME, "gl" #NAME)
+
+#define RESOLVE_FUNC_WITH_ALTERNATE(RETURN_TYPE, POLICY, NAME, ALTERNATE) \
+ return functionResolver<RETURN_TYPE, POLICY>(&QOpenGLExtensionsPrivate::NAME, "gl" #NAME, "gl" #ALTERNATE)
+
+#define RESOLVE_FUNC_VOID_WITH_ALTERNATE(POLICY, NAME, ALTERNATE) \
+ functionResolver<void, POLICY>(&QOpenGLExtensionsPrivate::NAME, "gl" #NAME, "gl" #ALTERNATE)
+
+#ifndef QT_OPENGL_ES_2
+
+static void QOPENGLF_APIENTRY qopenglfResolveActiveTexture(GLenum texture)
+{
+ RESOLVE_FUNC_VOID(0, ActiveTexture)(texture);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveAttachShader(GLuint program, GLuint shader)
+{
+ RESOLVE_FUNC_VOID_WITH_ALTERNATE(0, AttachShader, AttachObject)(program, shader);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveBindAttribLocation(GLuint program, GLuint index, const char* name)
+{
+ RESOLVE_FUNC_VOID(0, BindAttribLocation)(program, index, name);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveBindBuffer(GLenum target, GLuint buffer)
+{
+ RESOLVE_FUNC_VOID(ResolveOES | ResolveEXT, BindBuffer)(target, buffer);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveBindFramebuffer(GLenum target, GLuint framebuffer)
+{
+ RESOLVE_FUNC_VOID(ResolveOES | ResolveEXT, BindFramebuffer)(target, framebuffer);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveBindRenderbuffer(GLenum target, GLuint renderbuffer)
+{
+ RESOLVE_FUNC_VOID(ResolveOES | ResolveEXT, BindRenderbuffer)(target, renderbuffer);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+{
+ RESOLVE_FUNC_VOID(ResolveOES | ResolveEXT, BlendColor)(red, green, blue, alpha);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveBlendEquation(GLenum mode)
+{
+ RESOLVE_FUNC_VOID(ResolveOES | ResolveEXT, BlendEquation)(mode);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
+{
+ RESOLVE_FUNC_VOID(ResolveOES | ResolveEXT, BlendEquationSeparate)(modeRGB, modeAlpha);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
+{
+ RESOLVE_FUNC_VOID(ResolveOES | ResolveEXT, BlendFuncSeparate)(srcRGB, dstRGB, srcAlpha, dstAlpha);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveBufferData(GLenum target, qopengl_GLsizeiptr size, const void* data, GLenum usage)
+{
+ RESOLVE_FUNC_VOID(ResolveOES | ResolveEXT, BufferData)(target, size, data, usage);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveBufferSubData(GLenum target, qopengl_GLintptr offset, qopengl_GLsizeiptr size, const void* data)
+{
+ RESOLVE_FUNC_VOID(ResolveOES | ResolveEXT, BufferSubData)(target, offset, size, data);
+}
+
+static GLenum QOPENGLF_APIENTRY qopenglfResolveCheckFramebufferStatus(GLenum target)
+{
+ RESOLVE_FUNC(GLenum, ResolveOES | ResolveEXT, CheckFramebufferStatus)(target);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveCompileShader(GLuint shader)
+{
+ RESOLVE_FUNC_VOID(0, CompileShader)(shader);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data)
+{
+ RESOLVE_FUNC_VOID(ResolveOES | ResolveEXT, CompressedTexImage2D)(target, level, internalformat, width, height, border, imageSize, data);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data)
+{
+ RESOLVE_FUNC_VOID(ResolveOES | ResolveEXT, CompressedTexSubImage2D)(target, level, xoffset, yoffset, width, height, format, imageSize, data);
+}
+
+static GLuint QOPENGLF_APIENTRY qopenglfResolveCreateProgram()
+{
+ RESOLVE_FUNC_WITH_ALTERNATE(GLuint, 0, CreateProgram, CreateProgramObject)();
+}
+
+static GLuint QOPENGLF_APIENTRY qopenglfResolveCreateShader(GLenum type)
+{
+ RESOLVE_FUNC_WITH_ALTERNATE(GLuint, 0, CreateShader, CreateShaderObject)(type);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveDeleteBuffers(GLsizei n, const GLuint* buffers)
+{
+ RESOLVE_FUNC_VOID(ResolveOES | ResolveEXT, DeleteBuffers)(n, buffers);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
+{
+ RESOLVE_FUNC_VOID(ResolveOES | ResolveEXT, DeleteFramebuffers)(n, framebuffers);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveDeleteProgram(GLuint program)
+{
+ RESOLVE_FUNC_VOID(0, DeleteProgram)(program);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
+{
+ RESOLVE_FUNC_VOID(ResolveOES | ResolveEXT, DeleteRenderbuffers)(n, renderbuffers);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveDeleteShader(GLuint shader)
+{
+ RESOLVE_FUNC_VOID_WITH_ALTERNATE(0, DeleteShader, DeleteObject)(shader);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveDetachShader(GLuint program, GLuint shader)
+{
+ RESOLVE_FUNC_VOID_WITH_ALTERNATE(0, DetachShader, DetachObject)(program, shader);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveDisableVertexAttribArray(GLuint index)
+{
+ RESOLVE_FUNC_VOID(0, DisableVertexAttribArray)(index);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveEnableVertexAttribArray(GLuint index)
+{
+ RESOLVE_FUNC_VOID(0, EnableVertexAttribArray)(index);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
+{
+ RESOLVE_FUNC_VOID(ResolveOES | ResolveEXT, FramebufferRenderbuffer)(target, attachment, renderbuffertarget, renderbuffer);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
+{
+ RESOLVE_FUNC_VOID(ResolveOES | ResolveEXT, FramebufferTexture2D)(target, attachment, textarget, texture, level);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGenBuffers(GLsizei n, GLuint* buffers)
+{
+ RESOLVE_FUNC_VOID(ResolveOES | ResolveEXT, GenBuffers)(n, buffers);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGenerateMipmap(GLenum target)
+{
+ RESOLVE_FUNC_VOID(ResolveOES | ResolveEXT, GenerateMipmap)(target);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGenFramebuffers(GLsizei n, GLuint* framebuffers)
+{
+ RESOLVE_FUNC_VOID(ResolveOES | ResolveEXT, GenFramebuffers)(n, framebuffers);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
+{
+ RESOLVE_FUNC_VOID(ResolveOES | ResolveEXT, GenRenderbuffers)(n, renderbuffers);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name)
+{
+ RESOLVE_FUNC_VOID(0, GetActiveAttrib)(program, index, bufsize, length, size, type, name);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name)
+{
+ RESOLVE_FUNC_VOID(0, GetActiveUniform)(program, index, bufsize, length, size, type, name);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
+{
+ RESOLVE_FUNC_VOID_WITH_ALTERNATE(0, GetAttachedShaders, GetAttachedObjects)(program, maxcount, count, shaders);
+}
+
+static GLint QOPENGLF_APIENTRY qopenglfResolveGetAttribLocation(GLuint program, const char* name)
+{
+ RESOLVE_FUNC(GLint, 0, GetAttribLocation)(program, name);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
+{
+ RESOLVE_FUNC_VOID(ResolveOES | ResolveEXT, GetBufferParameteriv)(target, pname, params);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
+{
+ RESOLVE_FUNC_VOID(ResolveOES | ResolveEXT, GetFramebufferAttachmentParameteriv)(target, attachment, pname, params);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGetProgramiv(GLuint program, GLenum pname, GLint* params)
+{
+ RESOLVE_FUNC_VOID_WITH_ALTERNATE(0, GetProgramiv, GetObjectParameteriv)(program, pname, params);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, char* infolog)
+{
+ RESOLVE_FUNC_VOID_WITH_ALTERNATE(0, GetProgramInfoLog, GetInfoLog)(program, bufsize, length, infolog);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
+{
+ RESOLVE_FUNC_VOID(ResolveOES | ResolveEXT, GetRenderbufferParameteriv)(target, pname, params);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGetShaderiv(GLuint shader, GLenum pname, GLint* params)
+{
+ RESOLVE_FUNC_VOID_WITH_ALTERNATE(0, GetShaderiv, GetObjectParameteriv)(shader, pname, params);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog)
+{
+ RESOLVE_FUNC_VOID_WITH_ALTERNATE(0, GetShaderInfoLog, GetInfoLog)(shader, bufsize, length, infolog);
+}
+
+static void QOPENGLF_APIENTRY qopenglfSpecialGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
+{
+ Q_UNUSED(shadertype);
+ Q_UNUSED(precisiontype);
+ range[0] = range[1] = precision[0] = 0;
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
+{
+ RESOLVE_FUNC_SPECIAL_VOID(ResolveOES | ResolveEXT, GetShaderPrecisionFormat)(shadertype, precisiontype, range, precision);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, char* source)
+{
+ RESOLVE_FUNC_VOID(0, GetShaderSource)(shader, bufsize, length, source);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGetUniformfv(GLuint program, GLint location, GLfloat* params)
+{
+ RESOLVE_FUNC_VOID(0, GetUniformfv)(program, location, params);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGetUniformiv(GLuint program, GLint location, GLint* params)
+{
+ RESOLVE_FUNC_VOID(0, GetUniformiv)(program, location, params);
+}
+
+static GLint QOPENGLF_APIENTRY qopenglfResolveGetUniformLocation(GLuint program, const char* name)
+{
+ RESOLVE_FUNC(GLint, 0, GetUniformLocation)(program, name);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
+{
+ RESOLVE_FUNC_VOID(0, GetVertexAttribfv)(index, pname, params);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
+{
+ RESOLVE_FUNC_VOID(0, GetVertexAttribiv)(index, pname, params);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGetVertexAttribPointerv(GLuint index, GLenum pname, void** pointer)
+{
+ RESOLVE_FUNC_VOID(0, GetVertexAttribPointerv)(index, pname, pointer);
+}
+
+static GLboolean QOPENGLF_APIENTRY qopenglfResolveIsBuffer(GLuint buffer)
+{
+ RESOLVE_FUNC(GLboolean, ResolveOES | ResolveEXT, IsBuffer)(buffer);
+}
+
+static GLboolean QOPENGLF_APIENTRY qopenglfResolveIsFramebuffer(GLuint framebuffer)
+{
+ RESOLVE_FUNC(GLboolean, ResolveOES | ResolveEXT, IsFramebuffer)(framebuffer);
+}
+
+static GLboolean QOPENGLF_APIENTRY qopenglfSpecialIsProgram(GLuint program)
+{
+ return program != 0;
+}
+
+static GLboolean QOPENGLF_APIENTRY qopenglfResolveIsProgram(GLuint program)
+{
+ RESOLVE_FUNC_SPECIAL(GLboolean, 0, IsProgram)(program);
+}
+
+static GLboolean QOPENGLF_APIENTRY qopenglfResolveIsRenderbuffer(GLuint renderbuffer)
+{
+ RESOLVE_FUNC(GLboolean, ResolveOES | ResolveEXT, IsRenderbuffer)(renderbuffer);
+}
+
+static GLboolean QOPENGLF_APIENTRY qopenglfSpecialIsShader(GLuint shader)
+{
+ return shader != 0;
+}
+
+static GLboolean QOPENGLF_APIENTRY qopenglfResolveIsShader(GLuint shader)
+{
+ RESOLVE_FUNC_SPECIAL(GLboolean, 0, IsShader)(shader);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveLinkProgram(GLuint program)
+{
+ RESOLVE_FUNC_VOID(0, LinkProgram)(program);
+}
+
+static void QOPENGLF_APIENTRY qopenglfSpecialReleaseShaderCompiler()
+{
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveReleaseShaderCompiler()
+{
+ RESOLVE_FUNC_SPECIAL_VOID(0, ReleaseShaderCompiler)();
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
+{
+ RESOLVE_FUNC_VOID(ResolveOES | ResolveEXT, RenderbufferStorage)(target, internalformat, width, height);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveSampleCoverage(GLclampf value, GLboolean invert)
+{
+ RESOLVE_FUNC_VOID(ResolveOES | ResolveEXT, SampleCoverage)(value, invert);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveShaderBinary(GLint n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLint length)
+{
+ RESOLVE_FUNC_VOID(0, ShaderBinary)(n, shaders, binaryformat, binary, length);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveShaderSource(GLuint shader, GLsizei count, const char** string, const GLint* length)
+{
+ RESOLVE_FUNC_VOID(0, ShaderSource)(shader, count, string, length);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
+{
+ RESOLVE_FUNC_VOID(ResolveEXT, StencilFuncSeparate)(face, func, ref, mask);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveStencilMaskSeparate(GLenum face, GLuint mask)
+{
+ RESOLVE_FUNC_VOID(ResolveEXT, StencilMaskSeparate)(face, mask);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
+{
+ RESOLVE_FUNC_VOID(ResolveEXT, StencilOpSeparate)(face, fail, zfail, zpass);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveUniform1f(GLint location, GLfloat x)
+{
+ RESOLVE_FUNC_VOID(0, Uniform1f)(location, x);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveUniform1fv(GLint location, GLsizei count, const GLfloat* v)
+{
+ RESOLVE_FUNC_VOID(0, Uniform1fv)(location, count, v);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveUniform1i(GLint location, GLint x)
+{
+ RESOLVE_FUNC_VOID(0, Uniform1i)(location, x);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveUniform1iv(GLint location, GLsizei count, const GLint* v)
+{
+ RESOLVE_FUNC_VOID(0, Uniform1iv)(location, count, v);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveUniform2f(GLint location, GLfloat x, GLfloat y)
+{
+ RESOLVE_FUNC_VOID(0, Uniform2f)(location, x, y);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveUniform2fv(GLint location, GLsizei count, const GLfloat* v)
+{
+ RESOLVE_FUNC_VOID(0, Uniform2fv)(location, count, v);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveUniform2i(GLint location, GLint x, GLint y)
+{
+ RESOLVE_FUNC_VOID(0, Uniform2i)(location, x, y);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveUniform2iv(GLint location, GLsizei count, const GLint* v)
+{
+ RESOLVE_FUNC_VOID(0, Uniform2iv)(location, count, v);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
+{
+ RESOLVE_FUNC_VOID(0, Uniform3f)(location, x, y, z);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveUniform3fv(GLint location, GLsizei count, const GLfloat* v)
+{
+ RESOLVE_FUNC_VOID(0, Uniform3fv)(location, count, v);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveUniform3i(GLint location, GLint x, GLint y, GLint z)
+{
+ RESOLVE_FUNC_VOID(0, Uniform3i)(location, x, y, z);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveUniform3iv(GLint location, GLsizei count, const GLint* v)
+{
+ RESOLVE_FUNC_VOID(0, Uniform3iv)(location, count, v);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ RESOLVE_FUNC_VOID(0, Uniform4f)(location, x, y, z, w);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveUniform4fv(GLint location, GLsizei count, const GLfloat* v)
+{
+ RESOLVE_FUNC_VOID(0, Uniform4fv)(location, count, v);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
+{
+ RESOLVE_FUNC_VOID(0, Uniform4i)(location, x, y, z, w);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveUniform4iv(GLint location, GLsizei count, const GLint* v)
+{
+ RESOLVE_FUNC_VOID(0, Uniform4iv)(location, count, v);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+ RESOLVE_FUNC_VOID(0, UniformMatrix2fv)(location, count, transpose, value);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+ RESOLVE_FUNC_VOID(0, UniformMatrix3fv)(location, count, transpose, value);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+ RESOLVE_FUNC_VOID(0, UniformMatrix4fv)(location, count, transpose, value);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveUseProgram(GLuint program)
+{
+ RESOLVE_FUNC_VOID(0, UseProgram)(program);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveValidateProgram(GLuint program)
+{
+ RESOLVE_FUNC_VOID(0, ValidateProgram)(program);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveVertexAttrib1f(GLuint indx, GLfloat x)
+{
+ RESOLVE_FUNC_VOID(0, VertexAttrib1f)(indx, x);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveVertexAttrib1fv(GLuint indx, const GLfloat* values)
+{
+ RESOLVE_FUNC_VOID(0, VertexAttrib1fv)(indx, values);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveVertexAttrib2f(GLuint indx, GLfloat x, GLfloat y)
+{
+ RESOLVE_FUNC_VOID(0, VertexAttrib2f)(indx, x, y);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveVertexAttrib2fv(GLuint indx, const GLfloat* values)
+{
+ RESOLVE_FUNC_VOID(0, VertexAttrib2fv)(indx, values);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveVertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z)
+{
+ RESOLVE_FUNC_VOID(0, VertexAttrib3f)(indx, x, y, z);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveVertexAttrib3fv(GLuint indx, const GLfloat* values)
+{
+ RESOLVE_FUNC_VOID(0, VertexAttrib3fv)(indx, values);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveVertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ RESOLVE_FUNC_VOID(0, VertexAttrib4f)(indx, x, y, z, w);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveVertexAttrib4fv(GLuint indx, const GLfloat* values)
+{
+ RESOLVE_FUNC_VOID(0, VertexAttrib4fv)(indx, values);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveVertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr)
+{
+ RESOLVE_FUNC_VOID(0, VertexAttribPointer)(indx, size, type, normalized, stride, ptr);
+}
+
+#endif // !QT_OPENGL_ES_2
+
+static GLvoid *QOPENGLF_APIENTRY qopenglfResolveMapBuffer(GLenum target, GLenum access)
+{
+ RESOLVE_FUNC(GLvoid *, ResolveOES, MapBuffer)(target, access);
+}
+
+static GLboolean QOPENGLF_APIENTRY qopenglfResolveUnmapBuffer(GLenum target)
+{
+ RESOLVE_FUNC(GLboolean, ResolveOES, UnmapBuffer)(target);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+ GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+ GLbitfield mask, GLenum filter)
+{
+ RESOLVE_FUNC_VOID(ResolveEXT, BlitFramebuffer)
+ (srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveRenderbufferStorageMultisample(GLenum target, GLsizei samples,
+ GLenum internalFormat,
+ GLsizei width, GLsizei height)
+{
+ RESOLVE_FUNC_VOID(ResolveEXT, RenderbufferStorageMultisample)
+ (target, samples, internalFormat, width, height);
+}
+
+static void QOPENGLF_APIENTRY qopenglfResolveGetBufferSubData(GLenum target, qopengl_GLintptr offset, qopengl_GLsizeiptr size, GLvoid *data)
+{
+ RESOLVE_FUNC_VOID(ResolveEXT, GetBufferSubData)
+ (target, offset, size, data);
+}
+
+QOpenGLFunctionsPrivate::QOpenGLFunctionsPrivate(QOpenGLContext *)
+{
+#ifndef QT_OPENGL_ES_2
+ ActiveTexture = qopenglfResolveActiveTexture;
+ AttachShader = qopenglfResolveAttachShader;
+ BindAttribLocation = qopenglfResolveBindAttribLocation;
+ BindBuffer = qopenglfResolveBindBuffer;
+ BindFramebuffer = qopenglfResolveBindFramebuffer;
+ BindRenderbuffer = qopenglfResolveBindRenderbuffer;
+ BlendColor = qopenglfResolveBlendColor;
+ BlendEquation = qopenglfResolveBlendEquation;
+ BlendEquationSeparate = qopenglfResolveBlendEquationSeparate;
+ BlendFuncSeparate = qopenglfResolveBlendFuncSeparate;
+ BufferData = qopenglfResolveBufferData;
+ BufferSubData = qopenglfResolveBufferSubData;
+ CheckFramebufferStatus = qopenglfResolveCheckFramebufferStatus;
+ CompileShader = qopenglfResolveCompileShader;
+ CompressedTexImage2D = qopenglfResolveCompressedTexImage2D;
+ CompressedTexSubImage2D = qopenglfResolveCompressedTexSubImage2D;
+ CreateProgram = qopenglfResolveCreateProgram;
+ CreateShader = qopenglfResolveCreateShader;
+ DeleteBuffers = qopenglfResolveDeleteBuffers;
+ DeleteFramebuffers = qopenglfResolveDeleteFramebuffers;
+ DeleteProgram = qopenglfResolveDeleteProgram;
+ DeleteRenderbuffers = qopenglfResolveDeleteRenderbuffers;
+ DeleteShader = qopenglfResolveDeleteShader;
+ DetachShader = qopenglfResolveDetachShader;
+ DisableVertexAttribArray = qopenglfResolveDisableVertexAttribArray;
+ EnableVertexAttribArray = qopenglfResolveEnableVertexAttribArray;
+ FramebufferRenderbuffer = qopenglfResolveFramebufferRenderbuffer;
+ FramebufferTexture2D = qopenglfResolveFramebufferTexture2D;
+ GenBuffers = qopenglfResolveGenBuffers;
+ GenerateMipmap = qopenglfResolveGenerateMipmap;
+ GenFramebuffers = qopenglfResolveGenFramebuffers;
+ GenRenderbuffers = qopenglfResolveGenRenderbuffers;
+ GetActiveAttrib = qopenglfResolveGetActiveAttrib;
+ GetActiveUniform = qopenglfResolveGetActiveUniform;
+ GetAttachedShaders = qopenglfResolveGetAttachedShaders;
+ GetAttribLocation = qopenglfResolveGetAttribLocation;
+ GetBufferParameteriv = qopenglfResolveGetBufferParameteriv;
+ GetFramebufferAttachmentParameteriv = qopenglfResolveGetFramebufferAttachmentParameteriv;
+ GetProgramiv = qopenglfResolveGetProgramiv;
+ GetProgramInfoLog = qopenglfResolveGetProgramInfoLog;
+ GetRenderbufferParameteriv = qopenglfResolveGetRenderbufferParameteriv;
+ GetShaderiv = qopenglfResolveGetShaderiv;
+ GetShaderInfoLog = qopenglfResolveGetShaderInfoLog;
+ GetShaderPrecisionFormat = qopenglfResolveGetShaderPrecisionFormat;
+ GetShaderSource = qopenglfResolveGetShaderSource;
+ GetUniformfv = qopenglfResolveGetUniformfv;
+ GetUniformiv = qopenglfResolveGetUniformiv;
+ GetUniformLocation = qopenglfResolveGetUniformLocation;
+ GetVertexAttribfv = qopenglfResolveGetVertexAttribfv;
+ GetVertexAttribiv = qopenglfResolveGetVertexAttribiv;
+ GetVertexAttribPointerv = qopenglfResolveGetVertexAttribPointerv;
+ IsBuffer = qopenglfResolveIsBuffer;
+ IsFramebuffer = qopenglfResolveIsFramebuffer;
+ IsProgram = qopenglfResolveIsProgram;
+ IsRenderbuffer = qopenglfResolveIsRenderbuffer;
+ IsShader = qopenglfResolveIsShader;
+ LinkProgram = qopenglfResolveLinkProgram;
+ ReleaseShaderCompiler = qopenglfResolveReleaseShaderCompiler;
+ RenderbufferStorage = qopenglfResolveRenderbufferStorage;
+ SampleCoverage = qopenglfResolveSampleCoverage;
+ ShaderBinary = qopenglfResolveShaderBinary;
+ ShaderSource = qopenglfResolveShaderSource;
+ StencilFuncSeparate = qopenglfResolveStencilFuncSeparate;
+ StencilMaskSeparate = qopenglfResolveStencilMaskSeparate;
+ StencilOpSeparate = qopenglfResolveStencilOpSeparate;
+ Uniform1f = qopenglfResolveUniform1f;
+ Uniform1fv = qopenglfResolveUniform1fv;
+ Uniform1i = qopenglfResolveUniform1i;
+ Uniform1iv = qopenglfResolveUniform1iv;
+ Uniform2f = qopenglfResolveUniform2f;
+ Uniform2fv = qopenglfResolveUniform2fv;
+ Uniform2i = qopenglfResolveUniform2i;
+ Uniform2iv = qopenglfResolveUniform2iv;
+ Uniform3f = qopenglfResolveUniform3f;
+ Uniform3fv = qopenglfResolveUniform3fv;
+ Uniform3i = qopenglfResolveUniform3i;
+ Uniform3iv = qopenglfResolveUniform3iv;
+ Uniform4f = qopenglfResolveUniform4f;
+ Uniform4fv = qopenglfResolveUniform4fv;
+ Uniform4i = qopenglfResolveUniform4i;
+ Uniform4iv = qopenglfResolveUniform4iv;
+ UniformMatrix2fv = qopenglfResolveUniformMatrix2fv;
+ UniformMatrix3fv = qopenglfResolveUniformMatrix3fv;
+ UniformMatrix4fv = qopenglfResolveUniformMatrix4fv;
+ UseProgram = qopenglfResolveUseProgram;
+ ValidateProgram = qopenglfResolveValidateProgram;
+ VertexAttrib1f = qopenglfResolveVertexAttrib1f;
+ VertexAttrib1fv = qopenglfResolveVertexAttrib1fv;
+ VertexAttrib2f = qopenglfResolveVertexAttrib2f;
+ VertexAttrib2fv = qopenglfResolveVertexAttrib2fv;
+ VertexAttrib3f = qopenglfResolveVertexAttrib3f;
+ VertexAttrib3fv = qopenglfResolveVertexAttrib3fv;
+ VertexAttrib4f = qopenglfResolveVertexAttrib4f;
+ VertexAttrib4fv = qopenglfResolveVertexAttrib4fv;
+ VertexAttribPointer = qopenglfResolveVertexAttribPointer;
+#endif // !QT_OPENGL_ES_2
+}
+
+QOpenGLExtensionsPrivate::QOpenGLExtensionsPrivate(QOpenGLContext *ctx)
+ : QOpenGLFunctionsPrivate(ctx)
+{
+ MapBuffer = qopenglfResolveMapBuffer;
+ UnmapBuffer = qopenglfResolveUnmapBuffer;
+ BlitFramebuffer = qopenglfResolveBlitFramebuffer;
+ RenderbufferStorageMultisample = qopenglfResolveRenderbufferStorageMultisample;
+ GetBufferSubData = qopenglfResolveGetBufferSubData;
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/opengl/qopenglfunctions.h b/src/gui/opengl/qopenglfunctions.h
new file mode 100644
index 0000000000..d3bd580fc7
--- /dev/null
+++ b/src/gui/opengl/qopenglfunctions.h
@@ -0,0 +1,2427 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QOPENGLFUNCTIONS_H
+#define QOPENGLFUNCTIONS_H
+
+#ifdef __GLEW_H__
+#warning qopenglfunctions.h is not compatible with GLEW, GLEW defines will be undefined
+#warning To use GLEW with Qt, do not include <qopengl.h> or <QOpenGLFunctions> after glew.h
+#endif
+
+#include <QtGui/qopengl.h>
+#include <QtGui/qopenglcontext.h>
+
+//#define Q_ENABLE_OPENGL_FUNCTIONS_DEBUG
+
+#ifdef Q_ENABLE_OPENGL_FUNCTIONS_DEBUG
+#include <stdio.h>
+#define Q_OPENGL_FUNCTIONS_DEBUG \
+ GLenum error = glGetError(); \
+ if (error != GL_NO_ERROR) { \
+ unsigned clamped = qMin(unsigned(error - GL_INVALID_ENUM), 4U); \
+ const char *errors[] = { "GL_INVALID_ENUM", "GL_INVALID_VALUE", "GL_INVALID_OPERATION", "Unknown" }; \
+ printf("GL error at %s:%d: %s\n", __FILE__, __LINE__, errors[clamped]); \
+ int *value = 0; \
+ *value = 0; \
+ }
+#else
+#define Q_OPENGL_FUNCTIONS_DEBUG
+#endif
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+// Types that aren't defined in all system's gl.h files.
+typedef ptrdiff_t qopengl_GLintptr;
+typedef ptrdiff_t qopengl_GLsizeiptr;
+
+#ifdef Q_WS_WIN
+# define QOPENGLF_APIENTRY APIENTRY
+#endif
+
+#ifndef Q_WS_MAC
+# ifndef QOPENGLF_APIENTRYP
+# ifdef QOPENGLF_APIENTRY
+# define QOPENGLF_APIENTRYP QOPENGLF_APIENTRY *
+# else
+# define QOPENGLF_APIENTRY
+# define QOPENGLF_APIENTRYP *
+# endif
+# endif
+#else
+# define QOPENGLF_APIENTRY
+# define QOPENGLF_APIENTRYP *
+#endif
+
+struct QOpenGLFunctionsPrivate;
+
+// Undefine any macros from GLEW, qopenglextensions_p.h, etc that
+// may interfere with the definition of QOpenGLFunctions.
+#undef glActiveTexture
+#undef glAttachShader
+#undef glBindAttribLocation
+#undef glBindBuffer
+#undef glBindFramebuffer
+#undef glBindRenderbuffer
+#undef glBlendColor
+#undef glBlendEquation
+#undef glBlendEquationSeparate
+#undef glBlendFuncSeparate
+#undef glBufferData
+#undef glBufferSubData
+#undef glCheckFramebufferStatus
+#undef glClearDepthf
+#undef glCompileShader
+#undef glCompressedTexImage2D
+#undef glCompressedTexSubImage2D
+#undef glCreateProgram
+#undef glCreateShader
+#undef glDeleteBuffers
+#undef glDeleteFramebuffers
+#undef glDeleteProgram
+#undef glDeleteRenderbuffers
+#undef glDeleteShader
+#undef glDepthRangef
+#undef glDetachShader
+#undef glDisableVertexAttribArray
+#undef glEnableVertexAttribArray
+#undef glFramebufferRenderbuffer
+#undef glFramebufferTexture2D
+#undef glGenBuffers
+#undef glGenerateMipmap
+#undef glGenFramebuffers
+#undef glGenRenderbuffers
+#undef glGetActiveAttrib
+#undef glGetActiveUniform
+#undef glGetAttachedShaders
+#undef glGetAttribLocation
+#undef glGetBufferParameteriv
+#undef glGetFramebufferAttachmentParameteriv
+#undef glGetProgramiv
+#undef glGetProgramInfoLog
+#undef glGetRenderbufferParameteriv
+#undef glGetShaderiv
+#undef glGetShaderInfoLog
+#undef glGetShaderPrecisionFormat
+#undef glGetShaderSource
+#undef glGetUniformfv
+#undef glGetUniformiv
+#undef glGetUniformLocation
+#undef glGetVertexAttribfv
+#undef glGetVertexAttribiv
+#undef glGetVertexAttribPointerv
+#undef glIsBuffer
+#undef glIsFramebuffer
+#undef glIsProgram
+#undef glIsRenderbuffer
+#undef glIsShader
+#undef glLinkProgram
+#undef glReleaseShaderCompiler
+#undef glRenderbufferStorage
+#undef glSampleCoverage
+#undef glShaderBinary
+#undef glShaderSource
+#undef glStencilFuncSeparate
+#undef glStencilMaskSeparate
+#undef glStencilOpSeparate
+#undef glUniform1f
+#undef glUniform1fv
+#undef glUniform1i
+#undef glUniform1iv
+#undef glUniform2f
+#undef glUniform2fv
+#undef glUniform2i
+#undef glUniform2iv
+#undef glUniform3f
+#undef glUniform3fv
+#undef glUniform3i
+#undef glUniform3iv
+#undef glUniform4f
+#undef glUniform4fv
+#undef glUniform4i
+#undef glUniform4iv
+#undef glUniformMatrix2fv
+#undef glUniformMatrix3fv
+#undef glUniformMatrix4fv
+#undef glUseProgram
+#undef glValidateProgram
+#undef glVertexAttrib1f
+#undef glVertexAttrib1fv
+#undef glVertexAttrib2f
+#undef glVertexAttrib2fv
+#undef glVertexAttrib3f
+#undef glVertexAttrib3fv
+#undef glVertexAttrib4f
+#undef glVertexAttrib4fv
+#undef glVertexAttribPointer
+
+class Q_GUI_EXPORT QOpenGLFunctions
+{
+public:
+ QOpenGLFunctions();
+ QOpenGLFunctions(QOpenGLContext *context);
+ ~QOpenGLFunctions() {}
+
+ enum OpenGLFeature
+ {
+ Multitexture = 0x0001,
+ Shaders = 0x0002,
+ Buffers = 0x0004,
+ Framebuffers = 0x0008,
+ BlendColor = 0x0010,
+ BlendEquation = 0x0020,
+ BlendEquationSeparate = 0x0040,
+ BlendFuncSeparate = 0x0080,
+ BlendSubtract = 0x0100,
+ CompressedTextures = 0x0200,
+ Multisample = 0x0400,
+ StencilSeparate = 0x0800,
+ NPOTTextures = 0x1000
+ };
+ Q_DECLARE_FLAGS(OpenGLFeatures, OpenGLFeature)
+
+ QOpenGLFunctions::OpenGLFeatures openGLFeatures() const;
+ bool hasOpenGLFeature(QOpenGLFunctions::OpenGLFeature feature) const;
+
+ void initializeGLFunctions();
+
+ void glActiveTexture(GLenum texture);
+ void glAttachShader(GLuint program, GLuint shader);
+ void glBindAttribLocation(GLuint program, GLuint index, const char* name);
+ void glBindBuffer(GLenum target, GLuint buffer);
+ void glBindFramebuffer(GLenum target, GLuint framebuffer);
+ void glBindRenderbuffer(GLenum target, GLuint renderbuffer);
+ void glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+ void glBlendEquation(GLenum mode);
+ void glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha);
+ void glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+ void glBufferData(GLenum target, qopengl_GLsizeiptr size, const void* data, GLenum usage);
+ void glBufferSubData(GLenum target, qopengl_GLintptr offset, qopengl_GLsizeiptr size, const void* data);
+ GLenum glCheckFramebufferStatus(GLenum target);
+ void glClearDepthf(GLclampf depth);
+ void glCompileShader(GLuint shader);
+ void glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data);
+ void glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data);
+ GLuint glCreateProgram();
+ GLuint glCreateShader(GLenum type);
+ void glDeleteBuffers(GLsizei n, const GLuint* buffers);
+ void glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers);
+ void glDeleteProgram(GLuint program);
+ void glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers);
+ void glDeleteShader(GLuint shader);
+ void glDepthRangef(GLclampf zNear, GLclampf zFar);
+ void glDetachShader(GLuint program, GLuint shader);
+ void glDisableVertexAttribArray(GLuint index);
+ void glEnableVertexAttribArray(GLuint index);
+ void glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+ void glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+ void glGenBuffers(GLsizei n, GLuint* buffers);
+ void glGenerateMipmap(GLenum target);
+ void glGenFramebuffers(GLsizei n, GLuint* framebuffers);
+ void glGenRenderbuffers(GLsizei n, GLuint* renderbuffers);
+ void glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name);
+ void glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name);
+ void glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders);
+ GLint glGetAttribLocation(GLuint program, const char* name);
+ void glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params);
+ void glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params);
+ void glGetProgramiv(GLuint program, GLenum pname, GLint* params);
+ void glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, char* infolog);
+ void glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params);
+ void glGetShaderiv(GLuint shader, GLenum pname, GLint* params);
+ void glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog);
+ void glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision);
+ void glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, char* source);
+ void glGetUniformfv(GLuint program, GLint location, GLfloat* params);
+ void glGetUniformiv(GLuint program, GLint location, GLint* params);
+ GLint glGetUniformLocation(GLuint program, const char* name);
+ void glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params);
+ void glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params);
+ void glGetVertexAttribPointerv(GLuint index, GLenum pname, void** pointer);
+ GLboolean glIsBuffer(GLuint buffer);
+ GLboolean glIsFramebuffer(GLuint framebuffer);
+ GLboolean glIsProgram(GLuint program);
+ GLboolean glIsRenderbuffer(GLuint renderbuffer);
+ GLboolean glIsShader(GLuint shader);
+ void glLinkProgram(GLuint program);
+ void glReleaseShaderCompiler();
+ void glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+ void glSampleCoverage(GLclampf value, GLboolean invert);
+ void glShaderBinary(GLint n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLint length);
+ void glShaderSource(GLuint shader, GLsizei count, const char** string, const GLint* length);
+ void glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask);
+ void glStencilMaskSeparate(GLenum face, GLuint mask);
+ void glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass);
+ void glUniform1f(GLint location, GLfloat x);
+ void glUniform1fv(GLint location, GLsizei count, const GLfloat* v);
+ void glUniform1i(GLint location, GLint x);
+ void glUniform1iv(GLint location, GLsizei count, const GLint* v);
+ void glUniform2f(GLint location, GLfloat x, GLfloat y);
+ void glUniform2fv(GLint location, GLsizei count, const GLfloat* v);
+ void glUniform2i(GLint location, GLint x, GLint y);
+ void glUniform2iv(GLint location, GLsizei count, const GLint* v);
+ void glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z);
+ void glUniform3fv(GLint location, GLsizei count, const GLfloat* v);
+ void glUniform3i(GLint location, GLint x, GLint y, GLint z);
+ void glUniform3iv(GLint location, GLsizei count, const GLint* v);
+ void glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+ void glUniform4fv(GLint location, GLsizei count, const GLfloat* v);
+ void glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w);
+ void glUniform4iv(GLint location, GLsizei count, const GLint* v);
+ void glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+ void glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+ void glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+ void glUseProgram(GLuint program);
+ void glValidateProgram(GLuint program);
+ void glVertexAttrib1f(GLuint indx, GLfloat x);
+ void glVertexAttrib1fv(GLuint indx, const GLfloat* values);
+ void glVertexAttrib2f(GLuint indx, GLfloat x, GLfloat y);
+ void glVertexAttrib2fv(GLuint indx, const GLfloat* values);
+ void glVertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z);
+ void glVertexAttrib3fv(GLuint indx, const GLfloat* values);
+ void glVertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+ void glVertexAttrib4fv(GLuint indx, const GLfloat* values);
+ void glVertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr);
+
+protected:
+ QOpenGLFunctionsPrivate *d_ptr;
+ static bool isInitialized(const QOpenGLFunctionsPrivate *d) { return d != 0; }
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QOpenGLFunctions::OpenGLFeatures)
+
+struct QOpenGLFunctionsPrivate
+{
+ QOpenGLFunctionsPrivate(QOpenGLContext *ctx);
+
+#ifndef QT_OPENGL_ES_2
+ void (QOPENGLF_APIENTRYP ActiveTexture)(GLenum texture);
+ void (QOPENGLF_APIENTRYP AttachShader)(GLuint program, GLuint shader);
+ void (QOPENGLF_APIENTRYP BindAttribLocation)(GLuint program, GLuint index, const char* name);
+ void (QOPENGLF_APIENTRYP BindBuffer)(GLenum target, GLuint buffer);
+ void (QOPENGLF_APIENTRYP BindFramebuffer)(GLenum target, GLuint framebuffer);
+ void (QOPENGLF_APIENTRYP BindRenderbuffer)(GLenum target, GLuint renderbuffer);
+ void (QOPENGLF_APIENTRYP BlendColor)(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+ void (QOPENGLF_APIENTRYP BlendEquation)(GLenum mode);
+ void (QOPENGLF_APIENTRYP BlendEquationSeparate)(GLenum modeRGB, GLenum modeAlpha);
+ void (QOPENGLF_APIENTRYP BlendFuncSeparate)(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+ void (QOPENGLF_APIENTRYP BufferData)(GLenum target, qopengl_GLsizeiptr size, const void* data, GLenum usage);
+ void (QOPENGLF_APIENTRYP BufferSubData)(GLenum target, qopengl_GLintptr offset, qopengl_GLsizeiptr size, const void* data);
+ GLenum (QOPENGLF_APIENTRYP CheckFramebufferStatus)(GLenum target);
+ void (QOPENGLF_APIENTRYP CompileShader)(GLuint shader);
+ void (QOPENGLF_APIENTRYP CompressedTexImage2D)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data);
+ void (QOPENGLF_APIENTRYP CompressedTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data);
+ GLuint (QOPENGLF_APIENTRYP CreateProgram)();
+ GLuint (QOPENGLF_APIENTRYP CreateShader)(GLenum type);
+ void (QOPENGLF_APIENTRYP DeleteBuffers)(GLsizei n, const GLuint* buffers);
+ void (QOPENGLF_APIENTRYP DeleteFramebuffers)(GLsizei n, const GLuint* framebuffers);
+ void (QOPENGLF_APIENTRYP DeleteProgram)(GLuint program);
+ void (QOPENGLF_APIENTRYP DeleteRenderbuffers)(GLsizei n, const GLuint* renderbuffers);
+ void (QOPENGLF_APIENTRYP DeleteShader)(GLuint shader);
+ void (QOPENGLF_APIENTRYP DetachShader)(GLuint program, GLuint shader);
+ void (QOPENGLF_APIENTRYP DisableVertexAttribArray)(GLuint index);
+ void (QOPENGLF_APIENTRYP EnableVertexAttribArray)(GLuint index);
+ void (QOPENGLF_APIENTRYP FramebufferRenderbuffer)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+ void (QOPENGLF_APIENTRYP FramebufferTexture2D)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+ void (QOPENGLF_APIENTRYP GenBuffers)(GLsizei n, GLuint* buffers);
+ void (QOPENGLF_APIENTRYP GenerateMipmap)(GLenum target);
+ void (QOPENGLF_APIENTRYP GenFramebuffers)(GLsizei n, GLuint* framebuffers);
+ void (QOPENGLF_APIENTRYP GenRenderbuffers)(GLsizei n, GLuint* renderbuffers);
+ void (QOPENGLF_APIENTRYP GetActiveAttrib)(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name);
+ void (QOPENGLF_APIENTRYP GetActiveUniform)(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name);
+ void (QOPENGLF_APIENTRYP GetAttachedShaders)(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders);
+ GLint (QOPENGLF_APIENTRYP GetAttribLocation)(GLuint program, const char* name);
+ void (QOPENGLF_APIENTRYP GetBufferParameteriv)(GLenum target, GLenum pname, GLint* params);
+ void (QOPENGLF_APIENTRYP GetFramebufferAttachmentParameteriv)(GLenum target, GLenum attachment, GLenum pname, GLint* params);
+ void (QOPENGLF_APIENTRYP GetProgramiv)(GLuint program, GLenum pname, GLint* params);
+ void (QOPENGLF_APIENTRYP GetProgramInfoLog)(GLuint program, GLsizei bufsize, GLsizei* length, char* infolog);
+ void (QOPENGLF_APIENTRYP GetRenderbufferParameteriv)(GLenum target, GLenum pname, GLint* params);
+ void (QOPENGLF_APIENTRYP GetShaderiv)(GLuint shader, GLenum pname, GLint* params);
+ void (QOPENGLF_APIENTRYP GetShaderInfoLog)(GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog);
+ void (QOPENGLF_APIENTRYP GetShaderPrecisionFormat)(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision);
+ void (QOPENGLF_APIENTRYP GetShaderSource)(GLuint shader, GLsizei bufsize, GLsizei* length, char* source);
+ void (QOPENGLF_APIENTRYP GetUniformfv)(GLuint program, GLint location, GLfloat* params);
+ void (QOPENGLF_APIENTRYP GetUniformiv)(GLuint program, GLint location, GLint* params);
+ GLint (QOPENGLF_APIENTRYP GetUniformLocation)(GLuint program, const char* name);
+ void (QOPENGLF_APIENTRYP GetVertexAttribfv)(GLuint index, GLenum pname, GLfloat* params);
+ void (QOPENGLF_APIENTRYP GetVertexAttribiv)(GLuint index, GLenum pname, GLint* params);
+ void (QOPENGLF_APIENTRYP GetVertexAttribPointerv)(GLuint index, GLenum pname, void** pointer);
+ GLboolean (QOPENGLF_APIENTRYP IsBuffer)(GLuint buffer);
+ GLboolean (QOPENGLF_APIENTRYP IsFramebuffer)(GLuint framebuffer);
+ GLboolean (QOPENGLF_APIENTRYP IsProgram)(GLuint program);
+ GLboolean (QOPENGLF_APIENTRYP IsRenderbuffer)(GLuint renderbuffer);
+ GLboolean (QOPENGLF_APIENTRYP IsShader)(GLuint shader);
+ void (QOPENGLF_APIENTRYP LinkProgram)(GLuint program);
+ void (QOPENGLF_APIENTRYP ReleaseShaderCompiler)();
+ void (QOPENGLF_APIENTRYP RenderbufferStorage)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+ void (QOPENGLF_APIENTRYP SampleCoverage)(GLclampf value, GLboolean invert);
+ void (QOPENGLF_APIENTRYP ShaderBinary)(GLint n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLint length);
+ void (QOPENGLF_APIENTRYP ShaderSource)(GLuint shader, GLsizei count, const char** string, const GLint* length);
+ void (QOPENGLF_APIENTRYP StencilFuncSeparate)(GLenum face, GLenum func, GLint ref, GLuint mask);
+ void (QOPENGLF_APIENTRYP StencilMaskSeparate)(GLenum face, GLuint mask);
+ void (QOPENGLF_APIENTRYP StencilOpSeparate)(GLenum face, GLenum fail, GLenum zfail, GLenum zpass);
+ void (QOPENGLF_APIENTRYP Uniform1f)(GLint location, GLfloat x);
+ void (QOPENGLF_APIENTRYP Uniform1fv)(GLint location, GLsizei count, const GLfloat* v);
+ void (QOPENGLF_APIENTRYP Uniform1i)(GLint location, GLint x);
+ void (QOPENGLF_APIENTRYP Uniform1iv)(GLint location, GLsizei count, const GLint* v);
+ void (QOPENGLF_APIENTRYP Uniform2f)(GLint location, GLfloat x, GLfloat y);
+ void (QOPENGLF_APIENTRYP Uniform2fv)(GLint location, GLsizei count, const GLfloat* v);
+ void (QOPENGLF_APIENTRYP Uniform2i)(GLint location, GLint x, GLint y);
+ void (QOPENGLF_APIENTRYP Uniform2iv)(GLint location, GLsizei count, const GLint* v);
+ void (QOPENGLF_APIENTRYP Uniform3f)(GLint location, GLfloat x, GLfloat y, GLfloat z);
+ void (QOPENGLF_APIENTRYP Uniform3fv)(GLint location, GLsizei count, const GLfloat* v);
+ void (QOPENGLF_APIENTRYP Uniform3i)(GLint location, GLint x, GLint y, GLint z);
+ void (QOPENGLF_APIENTRYP Uniform3iv)(GLint location, GLsizei count, const GLint* v);
+ void (QOPENGLF_APIENTRYP Uniform4f)(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+ void (QOPENGLF_APIENTRYP Uniform4fv)(GLint location, GLsizei count, const GLfloat* v);
+ void (QOPENGLF_APIENTRYP Uniform4i)(GLint location, GLint x, GLint y, GLint z, GLint w);
+ void (QOPENGLF_APIENTRYP Uniform4iv)(GLint location, GLsizei count, const GLint* v);
+ void (QOPENGLF_APIENTRYP UniformMatrix2fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+ void (QOPENGLF_APIENTRYP UniformMatrix3fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+ void (QOPENGLF_APIENTRYP UniformMatrix4fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+ void (QOPENGLF_APIENTRYP UseProgram)(GLuint program);
+ void (QOPENGLF_APIENTRYP ValidateProgram)(GLuint program);
+ void (QOPENGLF_APIENTRYP VertexAttrib1f)(GLuint indx, GLfloat x);
+ void (QOPENGLF_APIENTRYP VertexAttrib1fv)(GLuint indx, const GLfloat* values);
+ void (QOPENGLF_APIENTRYP VertexAttrib2f)(GLuint indx, GLfloat x, GLfloat y);
+ void (QOPENGLF_APIENTRYP VertexAttrib2fv)(GLuint indx, const GLfloat* values);
+ void (QOPENGLF_APIENTRYP VertexAttrib3f)(GLuint indx, GLfloat x, GLfloat y, GLfloat z);
+ void (QOPENGLF_APIENTRYP VertexAttrib3fv)(GLuint indx, const GLfloat* values);
+ void (QOPENGLF_APIENTRYP VertexAttrib4f)(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+ void (QOPENGLF_APIENTRYP VertexAttrib4fv)(GLuint indx, const GLfloat* values);
+ void (QOPENGLF_APIENTRYP VertexAttribPointer)(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr);
+#endif
+};
+
+inline void QOpenGLFunctions::glActiveTexture(GLenum texture)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glActiveTexture(texture);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->ActiveTexture(texture);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glAttachShader(GLuint program, GLuint shader)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glAttachShader(program, shader);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->AttachShader(program, shader);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glBindAttribLocation(GLuint program, GLuint index, const char* name)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glBindAttribLocation(program, index, name);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->BindAttribLocation(program, index, name);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glBindBuffer(GLenum target, GLuint buffer)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glBindBuffer(target, buffer);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->BindBuffer(target, buffer);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glBindFramebuffer(GLenum target, GLuint framebuffer)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glBindFramebuffer(target, framebuffer);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->BindFramebuffer(target, framebuffer);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glBindRenderbuffer(GLenum target, GLuint renderbuffer)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glBindRenderbuffer(target, renderbuffer);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->BindRenderbuffer(target, renderbuffer);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glBlendColor(red, green, blue, alpha);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->BlendColor(red, green, blue, alpha);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glBlendEquation(GLenum mode)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glBlendEquation(mode);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->BlendEquation(mode);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glBlendEquationSeparate(modeRGB, modeAlpha);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->BlendEquationSeparate(modeRGB, modeAlpha);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->BlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glBufferData(GLenum target, qopengl_GLsizeiptr size, const void* data, GLenum usage)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glBufferData(target, size, data, usage);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->BufferData(target, size, data, usage);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glBufferSubData(GLenum target, qopengl_GLintptr offset, qopengl_GLsizeiptr size, const void* data)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glBufferSubData(target, offset, size, data);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->BufferSubData(target, offset, size, data);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline GLenum QOpenGLFunctions::glCheckFramebufferStatus(GLenum target)
+{
+#if defined(QT_OPENGL_ES_2)
+ GLenum result = ::glCheckFramebufferStatus(target);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ GLenum result = d_ptr->CheckFramebufferStatus(target);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+ return result;
+}
+
+inline void QOpenGLFunctions::glClearDepthf(GLclampf depth)
+{
+#ifndef QT_OPENGL_ES
+ ::glClearDepth(depth);
+#else
+ ::glClearDepthf(depth);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glCompileShader(GLuint shader)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glCompileShader(shader);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->CompileShader(shader);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->CompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->CompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline GLuint QOpenGLFunctions::glCreateProgram()
+{
+#if defined(QT_OPENGL_ES_2)
+ GLuint result = ::glCreateProgram();
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ GLuint result = d_ptr->CreateProgram();
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+ return result;
+}
+
+inline GLuint QOpenGLFunctions::glCreateShader(GLenum type)
+{
+#if defined(QT_OPENGL_ES_2)
+ GLuint result = ::glCreateShader(type);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ GLuint result = d_ptr->CreateShader(type);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+ return result;
+}
+
+inline void QOpenGLFunctions::glDeleteBuffers(GLsizei n, const GLuint* buffers)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glDeleteBuffers(n, buffers);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->DeleteBuffers(n, buffers);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glDeleteFramebuffers(n, framebuffers);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->DeleteFramebuffers(n, framebuffers);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glDeleteProgram(GLuint program)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glDeleteProgram(program);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->DeleteProgram(program);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glDeleteRenderbuffers(n, renderbuffers);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->DeleteRenderbuffers(n, renderbuffers);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glDeleteShader(GLuint shader)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glDeleteShader(shader);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->DeleteShader(shader);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glDepthRangef(GLclampf zNear, GLclampf zFar)
+{
+#ifndef QT_OPENGL_ES
+ ::glDepthRange(zNear, zFar);
+#else
+ ::glDepthRangef(zNear, zFar);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glDetachShader(GLuint program, GLuint shader)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glDetachShader(program, shader);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->DetachShader(program, shader);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glDisableVertexAttribArray(GLuint index)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glDisableVertexAttribArray(index);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->DisableVertexAttribArray(index);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glEnableVertexAttribArray(GLuint index)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glEnableVertexAttribArray(index);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->EnableVertexAttribArray(index);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glFramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->FramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glFramebufferTexture2D(target, attachment, textarget, texture, level);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->FramebufferTexture2D(target, attachment, textarget, texture, level);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glGenBuffers(GLsizei n, GLuint* buffers)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glGenBuffers(n, buffers);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->GenBuffers(n, buffers);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glGenerateMipmap(GLenum target)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glGenerateMipmap(target);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->GenerateMipmap(target);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glGenFramebuffers(GLsizei n, GLuint* framebuffers)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glGenFramebuffers(n, framebuffers);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->GenFramebuffers(n, framebuffers);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glGenRenderbuffers(n, renderbuffers);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->GenRenderbuffers(n, renderbuffers);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glGetActiveAttrib(program, index, bufsize, length, size, type, name);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->GetActiveAttrib(program, index, bufsize, length, size, type, name);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glGetActiveUniform(program, index, bufsize, length, size, type, name);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->GetActiveUniform(program, index, bufsize, length, size, type, name);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glGetAttachedShaders(program, maxcount, count, shaders);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->GetAttachedShaders(program, maxcount, count, shaders);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline GLint QOpenGLFunctions::glGetAttribLocation(GLuint program, const char* name)
+{
+#if defined(QT_OPENGL_ES_2)
+ GLint result = ::glGetAttribLocation(program, name);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ GLint result = d_ptr->GetAttribLocation(program, name);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+ return result;
+}
+
+inline void QOpenGLFunctions::glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glGetBufferParameteriv(target, pname, params);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->GetBufferParameteriv(target, pname, params);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glGetFramebufferAttachmentParameteriv(target, attachment, pname, params);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->GetFramebufferAttachmentParameteriv(target, attachment, pname, params);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glGetProgramiv(GLuint program, GLenum pname, GLint* params)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glGetProgramiv(program, pname, params);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->GetProgramiv(program, pname, params);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, char* infolog)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glGetProgramInfoLog(program, bufsize, length, infolog);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->GetProgramInfoLog(program, bufsize, length, infolog);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glGetRenderbufferParameteriv(target, pname, params);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->GetRenderbufferParameteriv(target, pname, params);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glGetShaderiv(shader, pname, params);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->GetShaderiv(shader, pname, params);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glGetShaderInfoLog(shader, bufsize, length, infolog);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->GetShaderInfoLog(shader, bufsize, length, infolog);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glGetShaderPrecisionFormat(shadertype, precisiontype, range, precision);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->GetShaderPrecisionFormat(shadertype, precisiontype, range, precision);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, char* source)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glGetShaderSource(shader, bufsize, length, source);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->GetShaderSource(shader, bufsize, length, source);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glGetUniformfv(GLuint program, GLint location, GLfloat* params)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glGetUniformfv(program, location, params);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->GetUniformfv(program, location, params);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glGetUniformiv(GLuint program, GLint location, GLint* params)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glGetUniformiv(program, location, params);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->GetUniformiv(program, location, params);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline GLint QOpenGLFunctions::glGetUniformLocation(GLuint program, const char* name)
+{
+#if defined(QT_OPENGL_ES_2)
+ GLint result = ::glGetUniformLocation(program, name);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ GLint result = d_ptr->GetUniformLocation(program, name);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+ return result;
+}
+
+inline void QOpenGLFunctions::glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glGetVertexAttribfv(index, pname, params);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->GetVertexAttribfv(index, pname, params);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glGetVertexAttribiv(index, pname, params);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->GetVertexAttribiv(index, pname, params);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glGetVertexAttribPointerv(GLuint index, GLenum pname, void** pointer)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glGetVertexAttribPointerv(index, pname, pointer);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->GetVertexAttribPointerv(index, pname, pointer);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline GLboolean QOpenGLFunctions::glIsBuffer(GLuint buffer)
+{
+#if defined(QT_OPENGL_ES_2)
+ GLboolean result = ::glIsBuffer(buffer);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ GLboolean result = d_ptr->IsBuffer(buffer);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+ return result;
+}
+
+inline GLboolean QOpenGLFunctions::glIsFramebuffer(GLuint framebuffer)
+{
+#if defined(QT_OPENGL_ES_2)
+ GLboolean result = ::glIsFramebuffer(framebuffer);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ GLboolean result = d_ptr->IsFramebuffer(framebuffer);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+ return result;
+}
+
+inline GLboolean QOpenGLFunctions::glIsProgram(GLuint program)
+{
+#if defined(QT_OPENGL_ES_2)
+ GLboolean result = ::glIsProgram(program);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ GLboolean result = d_ptr->IsProgram(program);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+ return result;
+}
+
+inline GLboolean QOpenGLFunctions::glIsRenderbuffer(GLuint renderbuffer)
+{
+#if defined(QT_OPENGL_ES_2)
+ GLboolean result = ::glIsRenderbuffer(renderbuffer);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ GLboolean result = d_ptr->IsRenderbuffer(renderbuffer);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+ return result;
+}
+
+inline GLboolean QOpenGLFunctions::glIsShader(GLuint shader)
+{
+#if defined(QT_OPENGL_ES_2)
+ GLboolean result = ::glIsShader(shader);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ GLboolean result = d_ptr->IsShader(shader);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+ return result;
+}
+
+inline void QOpenGLFunctions::glLinkProgram(GLuint program)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glLinkProgram(program);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->LinkProgram(program);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glReleaseShaderCompiler()
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glReleaseShaderCompiler();
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->ReleaseShaderCompiler();
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glRenderbufferStorage(target, internalformat, width, height);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->RenderbufferStorage(target, internalformat, width, height);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glSampleCoverage(GLclampf value, GLboolean invert)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glSampleCoverage(value, invert);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->SampleCoverage(value, invert);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glShaderBinary(GLint n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLint length)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glShaderBinary(n, shaders, binaryformat, binary, length);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->ShaderBinary(n, shaders, binaryformat, binary, length);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glShaderSource(GLuint shader, GLsizei count, const char** string, const GLint* length)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glShaderSource(shader, count, string, length);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->ShaderSource(shader, count, string, length);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glStencilFuncSeparate(face, func, ref, mask);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->StencilFuncSeparate(face, func, ref, mask);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glStencilMaskSeparate(GLenum face, GLuint mask)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glStencilMaskSeparate(face, mask);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->StencilMaskSeparate(face, mask);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glStencilOpSeparate(face, fail, zfail, zpass);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->StencilOpSeparate(face, fail, zfail, zpass);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glUniform1f(GLint location, GLfloat x)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glUniform1f(location, x);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->Uniform1f(location, x);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glUniform1fv(location, count, v);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->Uniform1fv(location, count, v);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glUniform1i(GLint location, GLint x)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glUniform1i(location, x);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->Uniform1i(location, x);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glUniform1iv(GLint location, GLsizei count, const GLint* v)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glUniform1iv(location, count, v);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->Uniform1iv(location, count, v);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glUniform2f(GLint location, GLfloat x, GLfloat y)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glUniform2f(location, x, y);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->Uniform2f(location, x, y);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glUniform2fv(location, count, v);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->Uniform2fv(location, count, v);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glUniform2i(GLint location, GLint x, GLint y)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glUniform2i(location, x, y);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->Uniform2i(location, x, y);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glUniform2iv(GLint location, GLsizei count, const GLint* v)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glUniform2iv(location, count, v);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->Uniform2iv(location, count, v);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glUniform3f(location, x, y, z);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->Uniform3f(location, x, y, z);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glUniform3fv(location, count, v);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->Uniform3fv(location, count, v);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glUniform3i(GLint location, GLint x, GLint y, GLint z)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glUniform3i(location, x, y, z);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->Uniform3i(location, x, y, z);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glUniform3iv(GLint location, GLsizei count, const GLint* v)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glUniform3iv(location, count, v);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->Uniform3iv(location, count, v);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glUniform4f(location, x, y, z, w);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->Uniform4f(location, x, y, z, w);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glUniform4fv(location, count, v);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->Uniform4fv(location, count, v);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glUniform4i(location, x, y, z, w);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->Uniform4i(location, x, y, z, w);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glUniform4iv(GLint location, GLsizei count, const GLint* v)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glUniform4iv(location, count, v);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->Uniform4iv(location, count, v);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glUniformMatrix2fv(location, count, transpose, value);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->UniformMatrix2fv(location, count, transpose, value);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glUniformMatrix3fv(location, count, transpose, value);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->UniformMatrix3fv(location, count, transpose, value);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glUniformMatrix4fv(location, count, transpose, value);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->UniformMatrix4fv(location, count, transpose, value);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glUseProgram(GLuint program)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glUseProgram(program);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->UseProgram(program);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glValidateProgram(GLuint program)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glValidateProgram(program);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->ValidateProgram(program);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glVertexAttrib1f(GLuint indx, GLfloat x)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glVertexAttrib1f(indx, x);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->VertexAttrib1f(indx, x);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glVertexAttrib1fv(GLuint indx, const GLfloat* values)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glVertexAttrib1fv(indx, values);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->VertexAttrib1fv(indx, values);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glVertexAttrib2f(GLuint indx, GLfloat x, GLfloat y)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glVertexAttrib2f(indx, x, y);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->VertexAttrib2f(indx, x, y);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glVertexAttrib2fv(GLuint indx, const GLfloat* values)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glVertexAttrib2fv(indx, values);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->VertexAttrib2fv(indx, values);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glVertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glVertexAttrib3f(indx, x, y, z);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->VertexAttrib3f(indx, x, y, z);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glVertexAttrib3fv(GLuint indx, const GLfloat* values)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glVertexAttrib3fv(indx, values);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->VertexAttrib3fv(indx, values);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glVertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glVertexAttrib4f(indx, x, y, z, w);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->VertexAttrib4f(indx, x, y, z, w);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glVertexAttrib4fv(GLuint indx, const GLfloat* values)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glVertexAttrib4fv(indx, values);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->VertexAttrib4fv(indx, values);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+inline void QOpenGLFunctions::glVertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr)
+{
+#if defined(QT_OPENGL_ES_2)
+ ::glVertexAttribPointer(indx, size, type, normalized, stride, ptr);
+#else
+ Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr));
+ d_ptr->VertexAttribPointer(indx, size, type, normalized, stride, ptr);
+#endif
+ Q_OPENGL_FUNCTIONS_DEBUG
+}
+
+#ifndef GL_ACTIVE_ATTRIBUTE_MAX_LENGTH
+#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A
+#endif
+#ifndef GL_ACTIVE_ATTRIBUTES
+#define GL_ACTIVE_ATTRIBUTES 0x8B89
+#endif
+#ifndef GL_ACTIVE_TEXTURE
+#define GL_ACTIVE_TEXTURE 0x84E0
+#endif
+#ifndef GL_ACTIVE_UNIFORM_MAX_LENGTH
+#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87
+#endif
+#ifndef GL_ACTIVE_UNIFORMS
+#define GL_ACTIVE_UNIFORMS 0x8B86
+#endif
+#ifndef GL_ALIASED_LINE_WIDTH_RANGE
+#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E
+#endif
+#ifndef GL_ALIASED_POINT_SIZE_RANGE
+#define GL_ALIASED_POINT_SIZE_RANGE 0x846D
+#endif
+#ifndef GL_ALPHA
+#define GL_ALPHA 0x1906
+#endif
+#ifndef GL_ALPHA_BITS
+#define GL_ALPHA_BITS 0x0D55
+#endif
+#ifndef GL_ALWAYS
+#define GL_ALWAYS 0x0207
+#endif
+#ifndef GL_ARRAY_BUFFER
+#define GL_ARRAY_BUFFER 0x8892
+#endif
+#ifndef GL_ARRAY_BUFFER_BINDING
+#define GL_ARRAY_BUFFER_BINDING 0x8894
+#endif
+#ifndef GL_ATTACHED_SHADERS
+#define GL_ATTACHED_SHADERS 0x8B85
+#endif
+#ifndef GL_BACK
+#define GL_BACK 0x0405
+#endif
+#ifndef GL_BLEND
+#define GL_BLEND 0x0BE2
+#endif
+#ifndef GL_BLEND_COLOR
+#define GL_BLEND_COLOR 0x8005
+#endif
+#ifndef GL_BLEND_DST_ALPHA
+#define GL_BLEND_DST_ALPHA 0x80CA
+#endif
+#ifndef GL_BLEND_DST_RGB
+#define GL_BLEND_DST_RGB 0x80C8
+#endif
+#ifndef GL_BLEND_EQUATION
+#define GL_BLEND_EQUATION 0x8009
+#endif
+#ifndef GL_BLEND_EQUATION_ALPHA
+#define GL_BLEND_EQUATION_ALPHA 0x883D
+#endif
+#ifndef GL_BLEND_EQUATION_RGB
+#define GL_BLEND_EQUATION_RGB 0x8009
+#endif
+#ifndef GL_BLEND_SRC_ALPHA
+#define GL_BLEND_SRC_ALPHA 0x80CB
+#endif
+#ifndef GL_BLEND_SRC_RGB
+#define GL_BLEND_SRC_RGB 0x80C9
+#endif
+#ifndef GL_BLUE_BITS
+#define GL_BLUE_BITS 0x0D54
+#endif
+#ifndef GL_BOOL
+#define GL_BOOL 0x8B56
+#endif
+#ifndef GL_BOOL_VEC2
+#define GL_BOOL_VEC2 0x8B57
+#endif
+#ifndef GL_BOOL_VEC3
+#define GL_BOOL_VEC3 0x8B58
+#endif
+#ifndef GL_BOOL_VEC4
+#define GL_BOOL_VEC4 0x8B59
+#endif
+#ifndef GL_BUFFER_SIZE
+#define GL_BUFFER_SIZE 0x8764
+#endif
+#ifndef GL_BUFFER_USAGE
+#define GL_BUFFER_USAGE 0x8765
+#endif
+#ifndef GL_BYTE
+#define GL_BYTE 0x1400
+#endif
+#ifndef GL_CCW
+#define GL_CCW 0x0901
+#endif
+#ifndef GL_CLAMP_TO_EDGE
+#define GL_CLAMP_TO_EDGE 0x812F
+#endif
+#ifndef GL_COLOR_ATTACHMENT0
+#define GL_COLOR_ATTACHMENT0 0x8CE0
+#endif
+#ifndef GL_COLOR_BUFFER_BIT
+#define GL_COLOR_BUFFER_BIT 0x00004000
+#endif
+#ifndef GL_COLOR_CLEAR_VALUE
+#define GL_COLOR_CLEAR_VALUE 0x0C22
+#endif
+#ifndef GL_COLOR_WRITEMASK
+#define GL_COLOR_WRITEMASK 0x0C23
+#endif
+#ifndef GL_COMPILE_STATUS
+#define GL_COMPILE_STATUS 0x8B81
+#endif
+#ifndef GL_COMPRESSED_TEXTURE_FORMATS
+#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3
+#endif
+#ifndef GL_CONSTANT_ALPHA
+#define GL_CONSTANT_ALPHA 0x8003
+#endif
+#ifndef GL_CONSTANT_COLOR
+#define GL_CONSTANT_COLOR 0x8001
+#endif
+#ifndef GL_CULL_FACE
+#define GL_CULL_FACE 0x0B44
+#endif
+#ifndef GL_CULL_FACE_MODE
+#define GL_CULL_FACE_MODE 0x0B45
+#endif
+#ifndef GL_CURRENT_PROGRAM
+#define GL_CURRENT_PROGRAM 0x8B8D
+#endif
+#ifndef GL_CURRENT_VERTEX_ATTRIB
+#define GL_CURRENT_VERTEX_ATTRIB 0x8626
+#endif
+#ifndef GL_CW
+#define GL_CW 0x0900
+#endif
+#ifndef GL_DECR
+#define GL_DECR 0x1E03
+#endif
+#ifndef GL_DECR_WRAP
+#define GL_DECR_WRAP 0x8508
+#endif
+#ifndef GL_DELETE_STATUS
+#define GL_DELETE_STATUS 0x8B80
+#endif
+#ifndef GL_DEPTH_ATTACHMENT
+#define GL_DEPTH_ATTACHMENT 0x8D00
+#endif
+#ifndef GL_DEPTH_BITS
+#define GL_DEPTH_BITS 0x0D56
+#endif
+#ifndef GL_DEPTH_BUFFER_BIT
+#define GL_DEPTH_BUFFER_BIT 0x00000100
+#endif
+#ifndef GL_DEPTH_CLEAR_VALUE
+#define GL_DEPTH_CLEAR_VALUE 0x0B73
+#endif
+#ifndef GL_DEPTH_COMPONENT
+#define GL_DEPTH_COMPONENT 0x1902
+#endif
+#ifndef GL_DEPTH_COMPONENT16
+#define GL_DEPTH_COMPONENT16 0x81A5
+#endif
+#ifndef GL_DEPTH_FUNC
+#define GL_DEPTH_FUNC 0x0B74
+#endif
+#ifndef GL_DEPTH_RANGE
+#define GL_DEPTH_RANGE 0x0B70
+#endif
+#ifndef GL_DEPTH_TEST
+#define GL_DEPTH_TEST 0x0B71
+#endif
+#ifndef GL_DEPTH_WRITEMASK
+#define GL_DEPTH_WRITEMASK 0x0B72
+#endif
+#ifndef GL_DITHER
+#define GL_DITHER 0x0BD0
+#endif
+#ifndef GL_DONT_CARE
+#define GL_DONT_CARE 0x1100
+#endif
+#ifndef GL_DST_ALPHA
+#define GL_DST_ALPHA 0x0304
+#endif
+#ifndef GL_DST_COLOR
+#define GL_DST_COLOR 0x0306
+#endif
+#ifndef GL_DYNAMIC_DRAW
+#define GL_DYNAMIC_DRAW 0x88E8
+#endif
+#ifndef GL_ELEMENT_ARRAY_BUFFER
+#define GL_ELEMENT_ARRAY_BUFFER 0x8893
+#endif
+#ifndef GL_ELEMENT_ARRAY_BUFFER_BINDING
+#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895
+#endif
+#ifndef GL_EQUAL
+#define GL_EQUAL 0x0202
+#endif
+#ifndef GL_EXTENSIONS
+#define GL_EXTENSIONS 0x1F03
+#endif
+#ifndef GL_FALSE
+#define GL_FALSE 0
+#endif
+#ifndef GL_FASTEST
+#define GL_FASTEST 0x1101
+#endif
+#ifndef GL_FIXED
+#define GL_FIXED 0x140C
+#endif
+#ifndef GL_FLOAT
+#define GL_FLOAT 0x1406
+#endif
+#ifndef GL_FLOAT_MAT2
+#define GL_FLOAT_MAT2 0x8B5A
+#endif
+#ifndef GL_FLOAT_MAT3
+#define GL_FLOAT_MAT3 0x8B5B
+#endif
+#ifndef GL_FLOAT_MAT4
+#define GL_FLOAT_MAT4 0x8B5C
+#endif
+#ifndef GL_FLOAT_VEC2
+#define GL_FLOAT_VEC2 0x8B50
+#endif
+#ifndef GL_FLOAT_VEC3
+#define GL_FLOAT_VEC3 0x8B51
+#endif
+#ifndef GL_FLOAT_VEC4
+#define GL_FLOAT_VEC4 0x8B52
+#endif
+#ifndef GL_FRAGMENT_SHADER
+#define GL_FRAGMENT_SHADER 0x8B30
+#endif
+#ifndef GL_FRAMEBUFFER
+#define GL_FRAMEBUFFER 0x8D40
+#endif
+#ifndef GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1
+#endif
+#ifndef GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0
+#endif
+#ifndef GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3
+#endif
+#ifndef GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2
+#endif
+#ifndef GL_FRAMEBUFFER_BINDING
+#define GL_FRAMEBUFFER_BINDING 0x8CA6
+#endif
+#ifndef GL_FRAMEBUFFER_COMPLETE
+#define GL_FRAMEBUFFER_COMPLETE 0x8CD5
+#endif
+#ifndef GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT
+#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6
+#endif
+#ifndef GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS
+#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9
+#endif
+#ifndef GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT
+#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7
+#endif
+#ifndef GL_FRAMEBUFFER_UNSUPPORTED
+#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD
+#endif
+#ifndef GL_FRONT
+#define GL_FRONT 0x0404
+#endif
+#ifndef GL_FRONT_AND_BACK
+#define GL_FRONT_AND_BACK 0x0408
+#endif
+#ifndef GL_FRONT_FACE
+#define GL_FRONT_FACE 0x0B46
+#endif
+#ifndef GL_FUNC_ADD
+#define GL_FUNC_ADD 0x8006
+#endif
+#ifndef GL_FUNC_REVERSE_SUBTRACT
+#define GL_FUNC_REVERSE_SUBTRACT 0x800B
+#endif
+#ifndef GL_FUNC_SUBTRACT
+#define GL_FUNC_SUBTRACT 0x800A
+#endif
+#ifndef GL_GENERATE_MIPMAP_HINT
+#define GL_GENERATE_MIPMAP_HINT 0x8192
+#endif
+#ifndef GL_GEQUAL
+#define GL_GEQUAL 0x0206
+#endif
+#ifndef GL_GREATER
+#define GL_GREATER 0x0204
+#endif
+#ifndef GL_GREEN_BITS
+#define GL_GREEN_BITS 0x0D53
+#endif
+#ifndef GL_HIGH_FLOAT
+#define GL_HIGH_FLOAT 0x8DF2
+#endif
+#ifndef GL_HIGH_INT
+#define GL_HIGH_INT 0x8DF5
+#endif
+#ifndef GL_IMPLEMENTATION_COLOR_READ_FORMAT
+#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B
+#endif
+#ifndef GL_IMPLEMENTATION_COLOR_READ_TYPE
+#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A
+#endif
+#ifndef GL_INCR
+#define GL_INCR 0x1E02
+#endif
+#ifndef GL_INCR_WRAP
+#define GL_INCR_WRAP 0x8507
+#endif
+#ifndef GL_INFO_LOG_LENGTH
+#define GL_INFO_LOG_LENGTH 0x8B84
+#endif
+#ifndef GL_INT
+#define GL_INT 0x1404
+#endif
+#ifndef GL_INT_VEC2
+#define GL_INT_VEC2 0x8B53
+#endif
+#ifndef GL_INT_VEC3
+#define GL_INT_VEC3 0x8B54
+#endif
+#ifndef GL_INT_VEC4
+#define GL_INT_VEC4 0x8B55
+#endif
+#ifndef GL_INVALID_ENUM
+#define GL_INVALID_ENUM 0x0500
+#endif
+#ifndef GL_INVALID_FRAMEBUFFER_OPERATION
+#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506
+#endif
+#ifndef GL_INVALID_OPERATION
+#define GL_INVALID_OPERATION 0x0502
+#endif
+#ifndef GL_INVALID_VALUE
+#define GL_INVALID_VALUE 0x0501
+#endif
+#ifndef GL_INVERT
+#define GL_INVERT 0x150A
+#endif
+#ifndef GL_KEEP
+#define GL_KEEP 0x1E00
+#endif
+#ifndef GL_LEQUAL
+#define GL_LEQUAL 0x0203
+#endif
+#ifndef GL_LESS
+#define GL_LESS 0x0201
+#endif
+#ifndef GL_LINEAR
+#define GL_LINEAR 0x2601
+#endif
+#ifndef GL_LINEAR_MIPMAP_LINEAR
+#define GL_LINEAR_MIPMAP_LINEAR 0x2703
+#endif
+#ifndef GL_LINEAR_MIPMAP_NEAREST
+#define GL_LINEAR_MIPMAP_NEAREST 0x2701
+#endif
+#ifndef GL_LINE_LOOP
+#define GL_LINE_LOOP 0x0002
+#endif
+#ifndef GL_LINES
+#define GL_LINES 0x0001
+#endif
+#ifndef GL_LINE_STRIP
+#define GL_LINE_STRIP 0x0003
+#endif
+#ifndef GL_LINE_WIDTH
+#define GL_LINE_WIDTH 0x0B21
+#endif
+#ifndef GL_LINK_STATUS
+#define GL_LINK_STATUS 0x8B82
+#endif
+#ifndef GL_LOW_FLOAT
+#define GL_LOW_FLOAT 0x8DF0
+#endif
+#ifndef GL_LOW_INT
+#define GL_LOW_INT 0x8DF3
+#endif
+#ifndef GL_LUMINANCE
+#define GL_LUMINANCE 0x1909
+#endif
+#ifndef GL_LUMINANCE_ALPHA
+#define GL_LUMINANCE_ALPHA 0x190A
+#endif
+#ifndef GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS
+#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D
+#endif
+#ifndef GL_MAX_CUBE_MAP_TEXTURE_SIZE
+#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C
+#endif
+#ifndef GL_MAX_FRAGMENT_UNIFORM_VECTORS
+#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD
+#endif
+#ifndef GL_MAX_RENDERBUFFER_SIZE
+#define GL_MAX_RENDERBUFFER_SIZE 0x84E8
+#endif
+#ifndef GL_MAX_TEXTURE_IMAGE_UNITS
+#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872
+#endif
+#ifndef GL_MAX_TEXTURE_SIZE
+#define GL_MAX_TEXTURE_SIZE 0x0D33
+#endif
+#ifndef GL_MAX_VARYING_VECTORS
+#define GL_MAX_VARYING_VECTORS 0x8DFC
+#endif
+#ifndef GL_MAX_VERTEX_ATTRIBS
+#define GL_MAX_VERTEX_ATTRIBS 0x8869
+#endif
+#ifndef GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS
+#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C
+#endif
+#ifndef GL_MAX_VERTEX_UNIFORM_VECTORS
+#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB
+#endif
+#ifndef GL_MAX_VIEWPORT_DIMS
+#define GL_MAX_VIEWPORT_DIMS 0x0D3A
+#endif
+#ifndef GL_MEDIUM_FLOAT
+#define GL_MEDIUM_FLOAT 0x8DF1
+#endif
+#ifndef GL_MEDIUM_INT
+#define GL_MEDIUM_INT 0x8DF4
+#endif
+#ifndef GL_MIRRORED_REPEAT
+#define GL_MIRRORED_REPEAT 0x8370
+#endif
+#ifndef GL_NEAREST
+#define GL_NEAREST 0x2600
+#endif
+#ifndef GL_NEAREST_MIPMAP_LINEAR
+#define GL_NEAREST_MIPMAP_LINEAR 0x2702
+#endif
+#ifndef GL_NEAREST_MIPMAP_NEAREST
+#define GL_NEAREST_MIPMAP_NEAREST 0x2700
+#endif
+#ifndef GL_NEVER
+#define GL_NEVER 0x0200
+#endif
+#ifndef GL_NICEST
+#define GL_NICEST 0x1102
+#endif
+#ifndef GL_NO_ERROR
+#define GL_NO_ERROR 0
+#endif
+#ifndef GL_NONE
+#define GL_NONE 0
+#endif
+#ifndef GL_NOTEQUAL
+#define GL_NOTEQUAL 0x0205
+#endif
+#ifndef GL_NUM_COMPRESSED_TEXTURE_FORMATS
+#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2
+#endif
+#ifndef GL_NUM_SHADER_BINARY_FORMATS
+#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9
+#endif
+#ifndef GL_ONE
+#define GL_ONE 1
+#endif
+#ifndef GL_ONE_MINUS_CONSTANT_ALPHA
+#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004
+#endif
+#ifndef GL_ONE_MINUS_CONSTANT_COLOR
+#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002
+#endif
+#ifndef GL_ONE_MINUS_DST_ALPHA
+#define GL_ONE_MINUS_DST_ALPHA 0x0305
+#endif
+#ifndef GL_ONE_MINUS_DST_COLOR
+#define GL_ONE_MINUS_DST_COLOR 0x0307
+#endif
+#ifndef GL_ONE_MINUS_SRC_ALPHA
+#define GL_ONE_MINUS_SRC_ALPHA 0x0303
+#endif
+#ifndef GL_ONE_MINUS_SRC_COLOR
+#define GL_ONE_MINUS_SRC_COLOR 0x0301
+#endif
+#ifndef GL_OUT_OF_MEMORY
+#define GL_OUT_OF_MEMORY 0x0505
+#endif
+#ifndef GL_PACK_ALIGNMENT
+#define GL_PACK_ALIGNMENT 0x0D05
+#endif
+#ifndef GL_POINTS
+#define GL_POINTS 0x0000
+#endif
+#ifndef GL_POLYGON_OFFSET_FACTOR
+#define GL_POLYGON_OFFSET_FACTOR 0x8038
+#endif
+#ifndef GL_POLYGON_OFFSET_FILL
+#define GL_POLYGON_OFFSET_FILL 0x8037
+#endif
+#ifndef GL_POLYGON_OFFSET_UNITS
+#define GL_POLYGON_OFFSET_UNITS 0x2A00
+#endif
+#ifndef GL_RED_BITS
+#define GL_RED_BITS 0x0D52
+#endif
+#ifndef GL_RENDERBUFFER
+#define GL_RENDERBUFFER 0x8D41
+#endif
+#ifndef GL_RENDERBUFFER_ALPHA_SIZE
+#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53
+#endif
+#ifndef GL_RENDERBUFFER_BINDING
+#define GL_RENDERBUFFER_BINDING 0x8CA7
+#endif
+#ifndef GL_RENDERBUFFER_BLUE_SIZE
+#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52
+#endif
+#ifndef GL_RENDERBUFFER_DEPTH_SIZE
+#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54
+#endif
+#ifndef GL_RENDERBUFFER_GREEN_SIZE
+#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51
+#endif
+#ifndef GL_RENDERBUFFER_HEIGHT
+#define GL_RENDERBUFFER_HEIGHT 0x8D43
+#endif
+#ifndef GL_RENDERBUFFER_INTERNAL_FORMAT
+#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44
+#endif
+#ifndef GL_RENDERBUFFER_RED_SIZE
+#define GL_RENDERBUFFER_RED_SIZE 0x8D50
+#endif
+#ifndef GL_RENDERBUFFER_STENCIL_SIZE
+#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55
+#endif
+#ifndef GL_RENDERBUFFER_WIDTH
+#define GL_RENDERBUFFER_WIDTH 0x8D42
+#endif
+#ifndef GL_RENDERER
+#define GL_RENDERER 0x1F01
+#endif
+#ifndef GL_REPEAT
+#define GL_REPEAT 0x2901
+#endif
+#ifndef GL_REPLACE
+#define GL_REPLACE 0x1E01
+#endif
+#ifndef GL_RGB
+#define GL_RGB 0x1907
+#endif
+#ifndef GL_RGB565
+#define GL_RGB565 0x8D62
+#endif
+#ifndef GL_RGB5_A1
+#define GL_RGB5_A1 0x8057
+#endif
+#ifndef GL_RGBA
+#define GL_RGBA 0x1908
+#endif
+#ifndef GL_RGBA4
+#define GL_RGBA4 0x8056
+#endif
+#ifndef GL_BGRA
+#define GL_BGRA 0x80E1
+#endif
+#ifndef GL_SAMPLE_ALPHA_TO_COVERAGE
+#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E
+#endif
+#ifndef GL_SAMPLE_BUFFERS
+#define GL_SAMPLE_BUFFERS 0x80A8
+#endif
+#ifndef GL_SAMPLE_COVERAGE
+#define GL_SAMPLE_COVERAGE 0x80A0
+#endif
+#ifndef GL_SAMPLE_COVERAGE_INVERT
+#define GL_SAMPLE_COVERAGE_INVERT 0x80AB
+#endif
+#ifndef GL_SAMPLE_COVERAGE_VALUE
+#define GL_SAMPLE_COVERAGE_VALUE 0x80AA
+#endif
+#ifndef GL_SAMPLER_2D
+#define GL_SAMPLER_2D 0x8B5E
+#endif
+#ifndef GL_SAMPLER_CUBE
+#define GL_SAMPLER_CUBE 0x8B60
+#endif
+#ifndef GL_SAMPLES
+#define GL_SAMPLES 0x80A9
+#endif
+#ifndef GL_SCISSOR_BOX
+#define GL_SCISSOR_BOX 0x0C10
+#endif
+#ifndef GL_SCISSOR_TEST
+#define GL_SCISSOR_TEST 0x0C11
+#endif
+#ifndef GL_SHADER_BINARY_FORMATS
+#define GL_SHADER_BINARY_FORMATS 0x8DF8
+#endif
+#ifndef GL_SHADER_COMPILER
+#define GL_SHADER_COMPILER 0x8DFA
+#endif
+#ifndef GL_SHADER_SOURCE_LENGTH
+#define GL_SHADER_SOURCE_LENGTH 0x8B88
+#endif
+#ifndef GL_SHADER_TYPE
+#define GL_SHADER_TYPE 0x8B4F
+#endif
+#ifndef GL_SHADING_LANGUAGE_VERSION
+#define GL_SHADING_LANGUAGE_VERSION 0x8B8C
+#endif
+#ifndef GL_SHORT
+#define GL_SHORT 0x1402
+#endif
+#ifndef GL_SRC_ALPHA
+#define GL_SRC_ALPHA 0x0302
+#endif
+#ifndef GL_SRC_ALPHA_SATURATE
+#define GL_SRC_ALPHA_SATURATE 0x0308
+#endif
+#ifndef GL_SRC_COLOR
+#define GL_SRC_COLOR 0x0300
+#endif
+#ifndef GL_STATIC_DRAW
+#define GL_STATIC_DRAW 0x88E4
+#endif
+#ifndef GL_STENCIL_ATTACHMENT
+#define GL_STENCIL_ATTACHMENT 0x8D20
+#endif
+#ifndef GL_STENCIL_BACK_FAIL
+#define GL_STENCIL_BACK_FAIL 0x8801
+#endif
+#ifndef GL_STENCIL_BACK_FUNC
+#define GL_STENCIL_BACK_FUNC 0x8800
+#endif
+#ifndef GL_STENCIL_BACK_PASS_DEPTH_FAIL
+#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802
+#endif
+#ifndef GL_STENCIL_BACK_PASS_DEPTH_PASS
+#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803
+#endif
+#ifndef GL_STENCIL_BACK_REF
+#define GL_STENCIL_BACK_REF 0x8CA3
+#endif
+#ifndef GL_STENCIL_BACK_VALUE_MASK
+#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4
+#endif
+#ifndef GL_STENCIL_BACK_WRITEMASK
+#define GL_STENCIL_BACK_WRITEMASK 0x8CA5
+#endif
+#ifndef GL_STENCIL_BITS
+#define GL_STENCIL_BITS 0x0D57
+#endif
+#ifndef GL_STENCIL_BUFFER_BIT
+#define GL_STENCIL_BUFFER_BIT 0x00000400
+#endif
+#ifndef GL_STENCIL_CLEAR_VALUE
+#define GL_STENCIL_CLEAR_VALUE 0x0B91
+#endif
+#ifndef GL_STENCIL_FAIL
+#define GL_STENCIL_FAIL 0x0B94
+#endif
+#ifndef GL_STENCIL_FUNC
+#define GL_STENCIL_FUNC 0x0B92
+#endif
+#ifndef GL_STENCIL_INDEX
+#define GL_STENCIL_INDEX 0x1901
+#endif
+#ifndef GL_STENCIL_INDEX8
+#define GL_STENCIL_INDEX8 0x8D48
+#endif
+#ifndef GL_STENCIL_PASS_DEPTH_FAIL
+#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95
+#endif
+#ifndef GL_STENCIL_PASS_DEPTH_PASS
+#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96
+#endif
+#ifndef GL_STENCIL_REF
+#define GL_STENCIL_REF 0x0B97
+#endif
+#ifndef GL_STENCIL_TEST
+#define GL_STENCIL_TEST 0x0B90
+#endif
+#ifndef GL_STENCIL_VALUE_MASK
+#define GL_STENCIL_VALUE_MASK 0x0B93
+#endif
+#ifndef GL_STENCIL_WRITEMASK
+#define GL_STENCIL_WRITEMASK 0x0B98
+#endif
+#ifndef GL_STREAM_DRAW
+#define GL_STREAM_DRAW 0x88E0
+#endif
+#ifndef GL_SUBPIXEL_BITS
+#define GL_SUBPIXEL_BITS 0x0D50
+#endif
+#ifndef GL_TEXTURE0
+#define GL_TEXTURE0 0x84C0
+#endif
+#ifndef GL_TEXTURE
+#define GL_TEXTURE 0x1702
+#endif
+#ifndef GL_TEXTURE10
+#define GL_TEXTURE10 0x84CA
+#endif
+#ifndef GL_TEXTURE1
+#define GL_TEXTURE1 0x84C1
+#endif
+#ifndef GL_TEXTURE11
+#define GL_TEXTURE11 0x84CB
+#endif
+#ifndef GL_TEXTURE12
+#define GL_TEXTURE12 0x84CC
+#endif
+#ifndef GL_TEXTURE13
+#define GL_TEXTURE13 0x84CD
+#endif
+#ifndef GL_TEXTURE14
+#define GL_TEXTURE14 0x84CE
+#endif
+#ifndef GL_TEXTURE15
+#define GL_TEXTURE15 0x84CF
+#endif
+#ifndef GL_TEXTURE16
+#define GL_TEXTURE16 0x84D0
+#endif
+#ifndef GL_TEXTURE17
+#define GL_TEXTURE17 0x84D1
+#endif
+#ifndef GL_TEXTURE18
+#define GL_TEXTURE18 0x84D2
+#endif
+#ifndef GL_TEXTURE19
+#define GL_TEXTURE19 0x84D3
+#endif
+#ifndef GL_TEXTURE20
+#define GL_TEXTURE20 0x84D4
+#endif
+#ifndef GL_TEXTURE2
+#define GL_TEXTURE2 0x84C2
+#endif
+#ifndef GL_TEXTURE21
+#define GL_TEXTURE21 0x84D5
+#endif
+#ifndef GL_TEXTURE22
+#define GL_TEXTURE22 0x84D6
+#endif
+#ifndef GL_TEXTURE23
+#define GL_TEXTURE23 0x84D7
+#endif
+#ifndef GL_TEXTURE24
+#define GL_TEXTURE24 0x84D8
+#endif
+#ifndef GL_TEXTURE25
+#define GL_TEXTURE25 0x84D9
+#endif
+#ifndef GL_TEXTURE26
+#define GL_TEXTURE26 0x84DA
+#endif
+#ifndef GL_TEXTURE27
+#define GL_TEXTURE27 0x84DB
+#endif
+#ifndef GL_TEXTURE28
+#define GL_TEXTURE28 0x84DC
+#endif
+#ifndef GL_TEXTURE29
+#define GL_TEXTURE29 0x84DD
+#endif
+#ifndef GL_TEXTURE_2D
+#define GL_TEXTURE_2D 0x0DE1
+#endif
+#ifndef GL_TEXTURE30
+#define GL_TEXTURE30 0x84DE
+#endif
+#ifndef GL_TEXTURE3
+#define GL_TEXTURE3 0x84C3
+#endif
+#ifndef GL_TEXTURE31
+#define GL_TEXTURE31 0x84DF
+#endif
+#ifndef GL_TEXTURE4
+#define GL_TEXTURE4 0x84C4
+#endif
+#ifndef GL_TEXTURE5
+#define GL_TEXTURE5 0x84C5
+#endif
+#ifndef GL_TEXTURE6
+#define GL_TEXTURE6 0x84C6
+#endif
+#ifndef GL_TEXTURE7
+#define GL_TEXTURE7 0x84C7
+#endif
+#ifndef GL_TEXTURE8
+#define GL_TEXTURE8 0x84C8
+#endif
+#ifndef GL_TEXTURE9
+#define GL_TEXTURE9 0x84C9
+#endif
+#ifndef GL_TEXTURE_BINDING_2D
+#define GL_TEXTURE_BINDING_2D 0x8069
+#endif
+#ifndef GL_TEXTURE_BINDING_CUBE_MAP
+#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514
+#endif
+#ifndef GL_TEXTURE_CUBE_MAP
+#define GL_TEXTURE_CUBE_MAP 0x8513
+#endif
+#ifndef GL_TEXTURE_CUBE_MAP_NEGATIVE_X
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516
+#endif
+#ifndef GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518
+#endif
+#ifndef GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A
+#endif
+#ifndef GL_TEXTURE_CUBE_MAP_POSITIVE_X
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515
+#endif
+#ifndef GL_TEXTURE_CUBE_MAP_POSITIVE_Y
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517
+#endif
+#ifndef GL_TEXTURE_CUBE_MAP_POSITIVE_Z
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519
+#endif
+#ifndef GL_TEXTURE_MAG_FILTER
+#define GL_TEXTURE_MAG_FILTER 0x2800
+#endif
+#ifndef GL_TEXTURE_MIN_FILTER
+#define GL_TEXTURE_MIN_FILTER 0x2801
+#endif
+#ifndef GL_TEXTURE_WRAP_S
+#define GL_TEXTURE_WRAP_S 0x2802
+#endif
+#ifndef GL_TEXTURE_WRAP_T
+#define GL_TEXTURE_WRAP_T 0x2803
+#endif
+#ifndef GL_TRIANGLE_FAN
+#define GL_TRIANGLE_FAN 0x0006
+#endif
+#ifndef GL_TRIANGLES
+#define GL_TRIANGLES 0x0004
+#endif
+#ifndef GL_TRIANGLE_STRIP
+#define GL_TRIANGLE_STRIP 0x0005
+#endif
+#ifndef GL_TRUE
+#define GL_TRUE 1
+#endif
+#ifndef GL_UNPACK_ALIGNMENT
+#define GL_UNPACK_ALIGNMENT 0x0CF5
+#endif
+#ifndef GL_UNSIGNED_BYTE
+#define GL_UNSIGNED_BYTE 0x1401
+#endif
+#ifndef GL_UNSIGNED_INT
+#define GL_UNSIGNED_INT 0x1405
+#endif
+#ifndef GL_UNSIGNED_SHORT
+#define GL_UNSIGNED_SHORT 0x1403
+#endif
+#ifndef GL_UNSIGNED_SHORT_4_4_4_4
+#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033
+#endif
+#ifndef GL_UNSIGNED_SHORT_5_5_5_1
+#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034
+#endif
+#ifndef GL_UNSIGNED_SHORT_5_6_5
+#define GL_UNSIGNED_SHORT_5_6_5 0x8363
+#endif
+#ifndef GL_VALIDATE_STATUS
+#define GL_VALIDATE_STATUS 0x8B83
+#endif
+#ifndef GL_VENDOR
+#define GL_VENDOR 0x1F00
+#endif
+#ifndef GL_VERSION
+#define GL_VERSION 0x1F02
+#endif
+#ifndef GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING
+#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F
+#endif
+#ifndef GL_VERTEX_ATTRIB_ARRAY_ENABLED
+#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622
+#endif
+#ifndef GL_VERTEX_ATTRIB_ARRAY_NORMALIZED
+#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A
+#endif
+#ifndef GL_VERTEX_ATTRIB_ARRAY_POINTER
+#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645
+#endif
+#ifndef GL_VERTEX_ATTRIB_ARRAY_SIZE
+#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623
+#endif
+#ifndef GL_VERTEX_ATTRIB_ARRAY_STRIDE
+#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624
+#endif
+#ifndef GL_VERTEX_ATTRIB_ARRAY_TYPE
+#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625
+#endif
+#ifndef GL_VERTEX_SHADER
+#define GL_VERTEX_SHADER 0x8B31
+#endif
+#ifndef GL_VIEWPORT
+#define GL_VIEWPORT 0x0BA2
+#endif
+#ifndef GL_ZERO
+#define GL_ZERO 0
+#endif
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/gui/opengl/qopenglgradientcache.cpp b/src/gui/opengl/qopenglgradientcache.cpp
new file mode 100644
index 0000000000..f8d61cd620
--- /dev/null
+++ b/src/gui/opengl/qopenglgradientcache.cpp
@@ -0,0 +1,227 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qopenglgradientcache_p.h"
+#include <private/qdrawhelper_p.h>
+#include <private/qopenglcontext_p.h>
+#include <QtCore/qmutex.h>
+
+QT_BEGIN_NAMESPACE
+
+class QOpenGL2GradientCacheWrapper
+{
+public:
+ QOpenGL2GradientCache *cacheForContext(QOpenGLContext *context) {
+ QMutexLocker lock(&m_mutex);
+ return m_resource.value<QOpenGL2GradientCache>(context);
+ }
+
+private:
+ QOpenGLMultiGroupSharedResource m_resource;
+ QMutex m_mutex;
+};
+
+Q_GLOBAL_STATIC(QOpenGL2GradientCacheWrapper, qt_gradient_caches)
+
+QOpenGL2GradientCache::QOpenGL2GradientCache(QOpenGLContext *ctx)
+ : QOpenGLSharedResource(ctx->shareGroup())
+{
+}
+
+QOpenGL2GradientCache::~QOpenGL2GradientCache()
+{
+ cache.clear();
+}
+
+QOpenGL2GradientCache *QOpenGL2GradientCache::cacheForContext(QOpenGLContext *context)
+{
+ return qt_gradient_caches()->cacheForContext(context);
+}
+
+void QOpenGL2GradientCache::invalidateResource()
+{
+ QMutexLocker lock(&m_mutex);
+ cache.clear();
+}
+
+void QOpenGL2GradientCache::freeResource(QOpenGLContext *)
+{
+ cleanCache();
+}
+
+void QOpenGL2GradientCache::cleanCache()
+{
+ QMutexLocker lock(&m_mutex);
+ QOpenGLGradientColorTableHash::const_iterator it = cache.constBegin();
+ for (; it != cache.constEnd(); ++it) {
+ const CacheInfo &cache_info = it.value();
+ glDeleteTextures(1, &cache_info.texId);
+ }
+ cache.clear();
+}
+
+GLuint QOpenGL2GradientCache::getBuffer(const QGradient &gradient, qreal opacity)
+{
+ QMutexLocker lock(&m_mutex);
+ quint64 hash_val = 0;
+
+ QGradientStops stops = gradient.stops();
+ for (int i = 0; i < stops.size() && i <= 2; i++)
+ hash_val += stops[i].second.rgba();
+
+ QOpenGLGradientColorTableHash::const_iterator it = cache.constFind(hash_val);
+
+ if (it == cache.constEnd())
+ return addCacheElement(hash_val, gradient, opacity);
+ else {
+ do {
+ const CacheInfo &cache_info = it.value();
+ if (cache_info.stops == stops && cache_info.opacity == opacity
+ && cache_info.interpolationMode == gradient.interpolationMode())
+ {
+ return cache_info.texId;
+ }
+ ++it;
+ } while (it != cache.constEnd() && it.key() == hash_val);
+ // an exact match for these stops and opacity was not found, create new cache
+ return addCacheElement(hash_val, gradient, opacity);
+ }
+}
+
+
+GLuint QOpenGL2GradientCache::addCacheElement(quint64 hash_val, const QGradient &gradient, qreal opacity)
+{
+ if (cache.size() == maxCacheSize()) {
+ int elem_to_remove = qrand() % maxCacheSize();
+ quint64 key = cache.keys()[elem_to_remove];
+
+ // need to call glDeleteTextures on each removed cache entry:
+ QOpenGLGradientColorTableHash::const_iterator it = cache.constFind(key);
+ do {
+ glDeleteTextures(1, &it.value().texId);
+ } while (++it != cache.constEnd() && it.key() == key);
+ cache.remove(key); // may remove more than 1, but OK
+ }
+
+ CacheInfo cache_entry(gradient.stops(), opacity, gradient.interpolationMode());
+ uint buffer[1024];
+ generateGradientColorTable(gradient, buffer, paletteSize(), opacity);
+ glGenTextures(1, &cache_entry.texId);
+ glBindTexture(GL_TEXTURE_2D, cache_entry.texId);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, paletteSize(), 1,
+ 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
+ return cache.insert(hash_val, cache_entry).value().texId;
+}
+
+
+// GL's expects pixels in RGBA (when using GL_RGBA), bin-endian (ABGR on x86).
+// Qt always stores in ARGB reguardless of the byte-order the mancine uses.
+static inline uint qtToGlColor(uint c)
+{
+ uint o;
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ o = (c & 0xff00ff00) // alpha & green already in the right place
+ | ((c >> 16) & 0x000000ff) // red
+ | ((c << 16) & 0x00ff0000); // blue
+#else //Q_BIG_ENDIAN
+ o = (c << 8)
+ | ((c >> 24) & 0x000000ff);
+#endif // Q_BYTE_ORDER
+ return o;
+}
+
+//TODO: Let GL generate the texture using an FBO
+void QOpenGL2GradientCache::generateGradientColorTable(const QGradient& gradient, uint *colorTable, int size, qreal opacity) const
+{
+ int pos = 0;
+ QGradientStops s = gradient.stops();
+ QVector<uint> colors(s.size());
+
+ for (int i = 0; i < s.size(); ++i)
+ colors[i] = s[i].second.rgba(); // Qt LIES! It returns ARGB (on little-endian AND on big-endian)
+
+ bool colorInterpolation = (gradient.interpolationMode() == QGradient::ColorInterpolation);
+
+ uint alpha = qRound(opacity * 256);
+ uint current_color = ARGB_COMBINE_ALPHA(colors[0], alpha);
+ qreal incr = 1.0 / qreal(size);
+ qreal fpos = 1.5 * incr;
+ colorTable[pos++] = qtToGlColor(PREMUL(current_color));
+
+ while (fpos <= s.first().first) {
+ colorTable[pos] = colorTable[pos - 1];
+ pos++;
+ fpos += incr;
+ }
+
+ if (colorInterpolation)
+ current_color = PREMUL(current_color);
+
+ for (int i = 0; i < s.size() - 1; ++i) {
+ qreal delta = 1/(s[i+1].first - s[i].first);
+ uint next_color = ARGB_COMBINE_ALPHA(colors[i+1], alpha);
+ if (colorInterpolation)
+ next_color = PREMUL(next_color);
+
+ while (fpos < s[i+1].first && pos < size) {
+ int dist = int(256 * ((fpos - s[i].first) * delta));
+ int idist = 256 - dist;
+ if (colorInterpolation)
+ colorTable[pos] = qtToGlColor(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist));
+ else
+ colorTable[pos] = qtToGlColor(PREMUL(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist)));
+ ++pos;
+ fpos += incr;
+ }
+ current_color = next_color;
+ }
+
+ Q_ASSERT(s.size() > 0);
+
+ uint last_color = qtToGlColor(PREMUL(ARGB_COMBINE_ALPHA(colors[s.size() - 1], alpha)));
+ for (;pos < size; ++pos)
+ colorTable[pos] = last_color;
+
+ // Make sure the last color stop is represented at the end of the table
+ colorTable[size-1] = last_color;
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/opengl/qopenglgradientcache_p.h b/src/gui/opengl/qopenglgradientcache_p.h
new file mode 100644
index 0000000000..53abf221d2
--- /dev/null
+++ b/src/gui/opengl/qopenglgradientcache_p.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QMultiHash>
+#include <QObject>
+#include <QtGui/QtGui>
+#include <private/qopenglcontext_p.h>
+#include <QtCore/qmutex.h>
+
+QT_BEGIN_NAMESPACE
+
+class QOpenGL2GradientCache : public QOpenGLSharedResource
+{
+ struct CacheInfo
+ {
+ inline CacheInfo(QGradientStops s, qreal op, QGradient::InterpolationMode mode) :
+ stops(s), opacity(op), interpolationMode(mode) {}
+
+ GLuint texId;
+ QGradientStops stops;
+ qreal opacity;
+ QGradient::InterpolationMode interpolationMode;
+ };
+
+ typedef QMultiHash<quint64, CacheInfo> QOpenGLGradientColorTableHash;
+
+public:
+ static QOpenGL2GradientCache *cacheForContext(QOpenGLContext *context);
+
+ QOpenGL2GradientCache(QOpenGLContext *);
+ ~QOpenGL2GradientCache();
+
+ GLuint getBuffer(const QGradient &gradient, qreal opacity);
+ inline int paletteSize() const { return 1024; }
+
+ void invalidateResource();
+ void freeResource(QOpenGLContext *ctx);
+
+private:
+ inline int maxCacheSize() const { return 60; }
+ inline void generateGradientColorTable(const QGradient& gradient,
+ uint *colorTable,
+ int size, qreal opacity) const;
+ GLuint addCacheElement(quint64 hash_val, const QGradient &gradient, qreal opacity);
+ void cleanCache();
+
+ QOpenGLGradientColorTableHash cache;
+ QMutex m_mutex;
+};
+
+QT_END_NAMESPACE
+
diff --git a/src/gui/opengl/qopenglpaintdevice.cpp b/src/gui/opengl/qopenglpaintdevice.cpp
new file mode 100644
index 0000000000..4e5c2703dc
--- /dev/null
+++ b/src/gui/opengl/qopenglpaintdevice.cpp
@@ -0,0 +1,231 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qopenglpaintdevice.h>
+#include <qpaintengine.h>
+#include <qthreadstorage.h>
+
+#include <private/qobject_p.h>
+#include <private/qopenglcontext_p.h>
+#include <private/qopenglframebufferobject_p.h>
+#include <private/qopenglpaintengine_p.h>
+
+// for qt_defaultDpiX/Y
+#include <private/qfont_p.h>
+
+#include <qopenglfunctions.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QOpenGLPaintDevice
+ \brief The QOpenGLPaintDevice class enables painting to an OpenGL context using QPainter.
+ \since 5.0
+
+ \ingroup painting-3D
+
+ When painting to a QOpenGLPaintDevice using QPainter, the state of
+ the current GL context will be altered by the paint engine to reflect
+ its needs. Applications should not rely upon the GL state being reset
+ to its original conditions, particularly the current shader program,
+ GL viewport, texture units, and drawing modes.
+*/
+
+class QOpenGLPaintDevicePrivate
+{
+public:
+ QOpenGLPaintDevicePrivate(const QSize &size);
+
+ QSize size;
+ QOpenGLContext *ctx;
+
+ qreal dpmx;
+ qreal dpmy;
+
+ bool flipped;
+
+ QPaintEngine *engine;
+
+ void init(const QSize &size, QOpenGLContext *ctx);
+};
+
+/*!
+ Constructs a QOpenGLPaintDevice with the given \a size.
+
+ The QOpenGLPaintDevice is only valid for the current context.
+
+ \sa QOpenGLContext::currentContext()
+*/
+QOpenGLPaintDevice::QOpenGLPaintDevice(const QSize &size)
+ : d_ptr(new QOpenGLPaintDevicePrivate(size))
+{
+}
+
+/*!
+ Constructs a QOpenGLPaintDevice with the given \a size and \a ctx.
+
+ The QOpenGLPaintDevice is only valid for the current context.
+
+ \sa QOpenGLContext::currentContext()
+*/
+QOpenGLPaintDevice::QOpenGLPaintDevice(int width, int height)
+ : d_ptr(new QOpenGLPaintDevicePrivate(QSize(width, height)))
+{
+}
+
+QOpenGLPaintDevice::~QOpenGLPaintDevice()
+{
+ delete d_ptr->engine;
+}
+
+QOpenGLPaintDevicePrivate::QOpenGLPaintDevicePrivate(const QSize &sz)
+ : size(sz)
+ , ctx(QOpenGLContext::currentContext())
+ , dpmx(qt_defaultDpiX() * 100. / 2.54)
+ , dpmy(qt_defaultDpiY() * 100. / 2.54)
+ , flipped(false)
+ , engine(0)
+{
+}
+
+class QOpenGLEngineThreadStorage
+{
+public:
+ QPaintEngine *engine() {
+ QPaintEngine *&localEngine = storage.localData();
+ if (!localEngine)
+ localEngine = new QOpenGL2PaintEngineEx;
+ return localEngine;
+ }
+
+private:
+ QThreadStorage<QPaintEngine *> storage;
+};
+
+Q_GLOBAL_STATIC(QOpenGLEngineThreadStorage, qt_opengl_engine)
+
+QPaintEngine *QOpenGLPaintDevice::paintEngine() const
+{
+ if (d_ptr->engine)
+ return d_ptr->engine;
+
+ QPaintEngine *engine = qt_opengl_engine()->engine();
+ if (engine->isActive() && engine->paintDevice() != this) {
+ d_ptr->engine = new QOpenGL2PaintEngineEx;
+ return d_ptr->engine;
+ }
+
+ return engine;
+}
+
+QOpenGLContext *QOpenGLPaintDevice::context() const
+{
+ return d_ptr->ctx;
+}
+
+QSize QOpenGLPaintDevice::size() const
+{
+ return d_ptr->size;
+}
+
+int QOpenGLPaintDevice::metric(QPaintDevice::PaintDeviceMetric metric) const
+{
+ switch (metric) {
+ case PdmWidth:
+ return d_ptr->size.width();
+ case PdmHeight:
+ return d_ptr->size.height();
+ case PdmDepth:
+ return 32;
+ case PdmWidthMM:
+ return qRound(d_ptr->size.width() * 1000 / d_ptr->dpmx);
+ case PdmHeightMM:
+ return qRound(d_ptr->size.height() * 1000 / d_ptr->dpmy);
+ case PdmNumColors:
+ return 0;
+ case PdmDpiX:
+ return qRound(d_ptr->dpmx * 0.0254);
+ case PdmDpiY:
+ return qRound(d_ptr->dpmy * 0.0254);
+ case PdmPhysicalDpiX:
+ return qRound(d_ptr->dpmx * 0.0254);
+ case PdmPhysicalDpiY:
+ return qRound(d_ptr->dpmy * 0.0254);
+ default:
+ qWarning("QOpenGLPaintDevice::metric() - metric %d not known", metric);
+ return 0;
+ }
+}
+
+qreal QOpenGLPaintDevice::dotsPerMeterX() const
+{
+ return d_ptr->dpmx;
+}
+
+qreal QOpenGLPaintDevice::dotsPerMeterY() const
+{
+ return d_ptr->dpmy;
+}
+
+void QOpenGLPaintDevice::setDotsPerMeterX(qreal dpmx)
+{
+ d_ptr->dpmx = dpmx;
+}
+
+void QOpenGLPaintDevice::setDotsPerMeterY(qreal dpmy)
+{
+ d_ptr->dpmx = dpmy;
+}
+
+/*!
+ Specifies whether painting should be flipped around the Y-axis or not.
+*/
+void QOpenGLPaintDevice::setPaintFlipped(bool flipped)
+{
+ d_ptr->flipped = flipped;
+}
+
+bool QOpenGLPaintDevice::paintFlipped() const
+{
+ return d_ptr->flipped;
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/opengl/qopenglpaintdevice.h b/src/gui/opengl/qopenglpaintdevice.h
new file mode 100644
index 0000000000..9edc347b32
--- /dev/null
+++ b/src/gui/opengl/qopenglpaintdevice.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QOPENGLPAINTDEVICE_H
+#define QOPENGLPAINTDEVICE_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the QtGui module. This header file may change from
+// version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+
+#include <QtGui/qpaintdevice.h>
+#include <QtGui/qopengl.h>
+#include <QtGui/qopenglcontext.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QOpenGLPaintDevicePrivate;
+
+class Q_GUI_EXPORT QOpenGLPaintDevice : public QPaintDevice
+{
+ Q_DECLARE_PRIVATE(QOpenGLPaintDevice)
+public:
+ QOpenGLPaintDevice(const QSize &size);
+ QOpenGLPaintDevice(int width, int height);
+ virtual ~QOpenGLPaintDevice();
+
+ int devType() const { return QInternal::OpenGL; }
+ QPaintEngine *paintEngine() const;
+
+ QOpenGLContext *context() const;
+ QSize size() const;
+
+ qreal dotsPerMeterX() const;
+ qreal dotsPerMeterY() const;
+
+ void setDotsPerMeterX(qreal);
+ void setDotsPerMeterY(qreal);
+
+ void setPaintFlipped(bool flipped);
+ bool paintFlipped() const;
+
+protected:
+ int metric(QPaintDevice::PaintDeviceMetric metric) const;
+
+ Q_DISABLE_COPY(QOpenGLPaintDevice)
+ QScopedPointer<QOpenGLPaintDevicePrivate> d_ptr;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QOPENGLPAINTDEVICE_H
diff --git a/src/gui/opengl/qopenglpaintengine.cpp b/src/gui/opengl/qopenglpaintengine.cpp
new file mode 100644
index 0000000000..b29cedcdf9
--- /dev/null
+++ b/src/gui/opengl/qopenglpaintengine.cpp
@@ -0,0 +1,2432 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*
+ When the active program changes, we need to update it's uniforms.
+ We could track state for each program and only update stale uniforms
+ - Could lead to lots of overhead if there's a lot of programs
+ We could update all the uniforms when the program changes
+ - Could end up updating lots of uniforms which don't need updating
+
+ Updating uniforms should be cheap, so the overhead of updating up-to-date
+ uniforms should be minimal. It's also less complex.
+
+ Things which _may_ cause a different program to be used:
+ - Change in brush/pen style
+ - Change in painter opacity
+ - Change in composition mode
+
+ Whenever we set a mode on the shader manager - it needs to tell us if it had
+ to switch to a different program.
+
+ The shader manager should only switch when we tell it to. E.g. if we set a new
+ brush style and then switch to transparent painter, we only want it to compile
+ and use the correct program when we really need it.
+*/
+
+// #define QT_OPENGL_CACHE_AS_VBOS
+
+#include "qopenglgradientcache_p.h"
+#include "qopengltexturecache_p.h"
+#include "qopenglpaintengine_p.h"
+
+#include <string.h> //for memcpy
+#include <qmath.h>
+
+#include <private/qopengl_p.h>
+#include <private/qopenglcontext_p.h>
+#include <private/qopenglextensions_p.h>
+#include <private/qmath_p.h>
+#include <private/qpaintengineex_p.h>
+#include <QPaintEngine>
+#include <private/qpainter_p.h>
+#include <private/qfontengine_p.h>
+#include <private/qdatabuffer_p.h>
+#include <private/qstatictext_p.h>
+#include <private/qtriangulator_p.h>
+
+#include "qopenglengineshadermanager_p.h"
+#include "qopengl2pexvertexarray_p.h"
+#include "qopengltriangulatingstroker_p.h"
+#include "qopengltextureglyphcache_p.h"
+
+#include <QDebug>
+
+QT_BEGIN_NAMESPACE
+
+#if defined(Q_WS_WIN)
+extern Q_GUI_EXPORT bool qt_cleartype_enabled;
+#endif
+
+#ifdef Q_WS_MAC
+extern bool qt_applefontsmoothing_enabled;
+#endif
+
+Q_GUI_EXPORT QImage qt_imageForBrush(int brushStyle, bool invert);
+
+////////////////////////////////// Private Methods //////////////////////////////////////////
+
+QOpenGL2PaintEngineExPrivate::~QOpenGL2PaintEngineExPrivate()
+{
+ delete shaderManager;
+
+ while (pathCaches.size()) {
+ QVectorPath::CacheEntry *e = *(pathCaches.constBegin());
+ e->cleanup(e->engine, e->data);
+ e->data = 0;
+ e->engine = 0;
+ }
+
+ if (elementIndicesVBOId != 0) {
+ funcs.glDeleteBuffers(1, &elementIndicesVBOId);
+ elementIndicesVBOId = 0;
+ }
+}
+
+void QOpenGL2PaintEngineExPrivate::updateTextureFilter(GLenum target, GLenum wrapMode, bool smoothPixmapTransform, GLuint id)
+{
+// funcs.glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT); //### Is it always this texture unit?
+ if (id != GLuint(-1) && id == lastTextureUsed)
+ return;
+
+ lastTextureUsed = id;
+
+ if (smoothPixmapTransform) {
+ glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ } else {
+ glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ }
+ glTexParameterf(target, GL_TEXTURE_WRAP_S, wrapMode);
+ glTexParameterf(target, GL_TEXTURE_WRAP_T, wrapMode);
+}
+
+
+inline QColor qt_premultiplyColor(QColor c, GLfloat opacity)
+{
+ qreal alpha = c.alphaF() * opacity;
+ c.setAlphaF(alpha);
+ c.setRedF(c.redF() * alpha);
+ c.setGreenF(c.greenF() * alpha);
+ c.setBlueF(c.blueF() * alpha);
+ return c;
+}
+
+
+void QOpenGL2PaintEngineExPrivate::setBrush(const QBrush& brush)
+{
+ if (qbrush_fast_equals(currentBrush, brush))
+ return;
+
+ const Qt::BrushStyle newStyle = qbrush_style(brush);
+ Q_ASSERT(newStyle != Qt::NoBrush);
+
+ currentBrush = brush;
+ if (!currentBrushPixmap.isNull())
+ currentBrushPixmap = QPixmap();
+ brushUniformsDirty = true; // All brushes have at least one uniform
+
+ if (newStyle > Qt::SolidPattern)
+ brushTextureDirty = true;
+
+ if (currentBrush.style() == Qt::TexturePattern
+ && qHasPixmapTexture(brush) && brush.texture().isQBitmap())
+ {
+ shaderManager->setSrcPixelType(QOpenGLEngineShaderManager::TextureSrcWithPattern);
+ } else {
+ shaderManager->setSrcPixelType(newStyle);
+ }
+ shaderManager->optimiseForBrushTransform(currentBrush.transform().type());
+}
+
+
+void QOpenGL2PaintEngineExPrivate::useSimpleShader()
+{
+ shaderManager->useSimpleProgram();
+
+ if (matrixDirty)
+ updateMatrix();
+}
+
+void QOpenGL2PaintEngineExPrivate::updateBrushTexture()
+{
+ Q_Q(QOpenGL2PaintEngineEx);
+// qDebug("QOpenGL2PaintEngineExPrivate::updateBrushTexture()");
+ Qt::BrushStyle style = currentBrush.style();
+
+ if ( (style >= Qt::Dense1Pattern) && (style <= Qt::DiagCrossPattern) ) {
+ // Get the image data for the pattern
+ QImage texImage = qt_imageForBrush(style, false);
+
+ funcs.glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT);
+ QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, texImage);
+ updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, q->state()->renderHints & QPainter::SmoothPixmapTransform);
+ }
+ else if (style >= Qt::LinearGradientPattern && style <= Qt::ConicalGradientPattern) {
+ // Gradiant brush: All the gradiants use the same texture
+
+ const QGradient* g = currentBrush.gradient();
+
+ // We apply global opacity in the fragment shaders, so we always pass 1.0
+ // for opacity to the cache.
+ GLuint texId = QOpenGL2GradientCache::cacheForContext(ctx)->getBuffer(*g, 1.0);
+
+ funcs.glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT);
+ glBindTexture(GL_TEXTURE_2D, texId);
+
+ if (g->spread() == QGradient::RepeatSpread || g->type() == QGradient::ConicalGradient)
+ updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, q->state()->renderHints & QPainter::SmoothPixmapTransform);
+ else if (g->spread() == QGradient::ReflectSpread)
+ updateTextureFilter(GL_TEXTURE_2D, GL_MIRRORED_REPEAT, q->state()->renderHints & QPainter::SmoothPixmapTransform);
+ else
+ updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE, q->state()->renderHints & QPainter::SmoothPixmapTransform);
+ }
+ else if (style == Qt::TexturePattern) {
+ currentBrushPixmap = currentBrush.texture();
+
+ int max_texture_size = ctx->d_func()->maxTextureSize();
+ if (currentBrushPixmap.width() > max_texture_size || currentBrushPixmap.height() > max_texture_size)
+ currentBrushPixmap = currentBrushPixmap.scaled(max_texture_size, max_texture_size, Qt::KeepAspectRatio);
+
+ funcs.glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT);
+ QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, currentBrushPixmap);
+ updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, q->state()->renderHints & QPainter::SmoothPixmapTransform);
+ textureInvertedY = false;
+ }
+ brushTextureDirty = false;
+}
+
+
+void QOpenGL2PaintEngineExPrivate::updateBrushUniforms()
+{
+// qDebug("QOpenGL2PaintEngineExPrivate::updateBrushUniforms()");
+ Qt::BrushStyle style = currentBrush.style();
+
+ if (style == Qt::NoBrush)
+ return;
+
+ QTransform brushQTransform = currentBrush.transform();
+
+ if (style == Qt::SolidPattern) {
+ QColor col = qt_premultiplyColor(currentBrush.color(), (GLfloat)q->state()->opacity);
+ shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::FragmentColor), col);
+ }
+ else {
+ // All other brushes have a transform and thus need the translation point:
+ QPointF translationPoint;
+
+ if (style <= Qt::DiagCrossPattern) {
+ QColor col = qt_premultiplyColor(currentBrush.color(), (GLfloat)q->state()->opacity);
+
+ shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::PatternColor), col);
+
+ QVector2D halfViewportSize(width*0.5, height*0.5);
+ shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::HalfViewportSize), halfViewportSize);
+ }
+ else if (style == Qt::LinearGradientPattern) {
+ const QLinearGradient *g = static_cast<const QLinearGradient *>(currentBrush.gradient());
+
+ QPointF realStart = g->start();
+ QPointF realFinal = g->finalStop();
+ translationPoint = realStart;
+
+ QPointF l = realFinal - realStart;
+
+ QVector3D linearData(
+ l.x(),
+ l.y(),
+ 1.0f / (l.x() * l.x() + l.y() * l.y())
+ );
+
+ shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::LinearData), linearData);
+
+ QVector2D halfViewportSize(width*0.5, height*0.5);
+ shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::HalfViewportSize), halfViewportSize);
+ }
+ else if (style == Qt::ConicalGradientPattern) {
+ const QConicalGradient *g = static_cast<const QConicalGradient *>(currentBrush.gradient());
+ translationPoint = g->center();
+
+ GLfloat angle = -(g->angle() * 2 * Q_PI) / 360.0;
+
+ shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::Angle), angle);
+
+ QVector2D halfViewportSize(width*0.5, height*0.5);
+ shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::HalfViewportSize), halfViewportSize);
+ }
+ else if (style == Qt::RadialGradientPattern) {
+ const QRadialGradient *g = static_cast<const QRadialGradient *>(currentBrush.gradient());
+ QPointF realCenter = g->center();
+ QPointF realFocal = g->focalPoint();
+ qreal realRadius = g->centerRadius() - g->focalRadius();
+ translationPoint = realFocal;
+
+ QPointF fmp = realCenter - realFocal;
+ shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::Fmp), fmp);
+
+ GLfloat fmp2_m_radius2 = -fmp.x() * fmp.x() - fmp.y() * fmp.y() + realRadius*realRadius;
+ shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::Fmp2MRadius2), fmp2_m_radius2);
+ shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::Inverse2Fmp2MRadius2),
+ GLfloat(1.0 / (2.0*fmp2_m_radius2)));
+ shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::SqrFr),
+ GLfloat(g->focalRadius() * g->focalRadius()));
+ shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::BRadius),
+ GLfloat(2 * (g->centerRadius() - g->focalRadius()) * g->focalRadius()),
+ g->focalRadius(),
+ g->centerRadius() - g->focalRadius());
+
+ QVector2D halfViewportSize(width*0.5, height*0.5);
+ shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::HalfViewportSize), halfViewportSize);
+ }
+ else if (style == Qt::TexturePattern) {
+ const QPixmap& texPixmap = currentBrush.texture();
+
+ if (qHasPixmapTexture(currentBrush) && currentBrush.texture().isQBitmap()) {
+ QColor col = qt_premultiplyColor(currentBrush.color(), (GLfloat)q->state()->opacity);
+ shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::PatternColor), col);
+ }
+
+ QSizeF invertedTextureSize(1.0 / texPixmap.width(), 1.0 / texPixmap.height());
+ shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::InvertedTextureSize), invertedTextureSize);
+
+ QVector2D halfViewportSize(width*0.5, height*0.5);
+ shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::HalfViewportSize), halfViewportSize);
+ }
+ else
+ qWarning("QOpenGL2PaintEngineEx: Unimplemented fill style");
+
+ const QPointF &brushOrigin = q->state()->brushOrigin;
+ QTransform matrix = q->state()->matrix;
+ matrix.translate(brushOrigin.x(), brushOrigin.y());
+
+ QTransform translate(1, 0, 0, 1, -translationPoint.x(), -translationPoint.y());
+ qreal m22 = -1;
+ qreal dy = height;
+ if (device->paintFlipped()) {
+ m22 = 1;
+ dy = 0;
+ }
+ QTransform gl_to_qt(1, 0, 0, m22, 0, dy);
+ QTransform inv_matrix;
+ if (style == Qt::TexturePattern && textureInvertedY == -1)
+ inv_matrix = gl_to_qt * (QTransform(1, 0, 0, -1, 0, currentBrush.texture().height()) * brushQTransform * matrix).inverted() * translate;
+ else
+ inv_matrix = gl_to_qt * (brushQTransform * matrix).inverted() * translate;
+
+ shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::BrushTransform), inv_matrix);
+ shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::BrushTexture), QT_BRUSH_TEXTURE_UNIT);
+ }
+ brushUniformsDirty = false;
+}
+
+
+// This assumes the shader manager has already setup the correct shader program
+void QOpenGL2PaintEngineExPrivate::updateMatrix()
+{
+// qDebug("QOpenGL2PaintEngineExPrivate::updateMatrix()");
+
+ const QTransform& transform = q->state()->matrix;
+
+ // The projection matrix converts from Qt's coordinate system to GL's coordinate system
+ // * GL's viewport is 2x2, Qt's is width x height
+ // * GL has +y -> -y going from bottom -> top, Qt is the other way round
+ // * GL has [0,0] in the center, Qt has it in the top-left
+ //
+ // This results in the Projection matrix below, which is multiplied by the painter's
+ // transformation matrix, as shown below:
+ //
+ // Projection Matrix Painter Transform
+ // ------------------------------------------------ ------------------------
+ // | 2.0 / width | 0.0 | -1.0 | | m11 | m21 | dx |
+ // | 0.0 | -2.0 / height | 1.0 | * | m12 | m22 | dy |
+ // | 0.0 | 0.0 | 1.0 | | m13 | m23 | m33 |
+ // ------------------------------------------------ ------------------------
+ //
+ // NOTE: The resultant matrix is also transposed, as GL expects column-major matracies
+
+ const GLfloat wfactor = 2.0f / width;
+ GLfloat hfactor = -2.0f / height;
+
+ GLfloat dx = transform.dx();
+ GLfloat dy = transform.dy();
+
+ if (device->paintFlipped()) {
+ hfactor *= -1;
+ dy -= height;
+ }
+
+ // Non-integer translates can have strange effects for some rendering operations such as
+ // anti-aliased text rendering. In such cases, we snap the translate to the pixel grid.
+ if (snapToPixelGrid && transform.type() == QTransform::TxTranslate) {
+ // 0.50 needs to rounded down to 0.0 for consistency with raster engine:
+ dx = ceilf(dx - 0.5f);
+ dy = ceilf(dy - 0.5f);
+ }
+ pmvMatrix[0][0] = (wfactor * transform.m11()) - transform.m13();
+ pmvMatrix[1][0] = (wfactor * transform.m21()) - transform.m23();
+ pmvMatrix[2][0] = (wfactor * dx) - transform.m33();
+ pmvMatrix[0][1] = (hfactor * transform.m12()) + transform.m13();
+ pmvMatrix[1][1] = (hfactor * transform.m22()) + transform.m23();
+ pmvMatrix[2][1] = (hfactor * dy) + transform.m33();
+ pmvMatrix[0][2] = transform.m13();
+ pmvMatrix[1][2] = transform.m23();
+ pmvMatrix[2][2] = transform.m33();
+
+ // 1/10000 == 0.0001, so we have good enough res to cover curves
+ // that span the entire widget...
+ inverseScale = qMax(1 / qMax( qMax(qAbs(transform.m11()), qAbs(transform.m22())),
+ qMax(qAbs(transform.m12()), qAbs(transform.m21())) ),
+ qreal(0.0001));
+
+ matrixDirty = false;
+ matrixUniformDirty = true;
+
+ // Set the PMV matrix attribute. As we use an attributes rather than uniforms, we only
+ // need to do this once for every matrix change and persists across all shader programs.
+ funcs.glVertexAttrib3fv(QT_PMV_MATRIX_1_ATTR, pmvMatrix[0]);
+ funcs.glVertexAttrib3fv(QT_PMV_MATRIX_2_ATTR, pmvMatrix[1]);
+ funcs.glVertexAttrib3fv(QT_PMV_MATRIX_3_ATTR, pmvMatrix[2]);
+
+ dasher.setInvScale(inverseScale);
+ stroker.setInvScale(inverseScale);
+}
+
+
+void QOpenGL2PaintEngineExPrivate::updateCompositionMode()
+{
+ // NOTE: The entire paint engine works on pre-multiplied data - which is why some of these
+ // composition modes look odd.
+// qDebug() << "QOpenGL2PaintEngineExPrivate::updateCompositionMode() - Setting GL composition mode for " << q->state()->composition_mode;
+ switch(q->state()->composition_mode) {
+ case QPainter::CompositionMode_SourceOver:
+ glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+ break;
+ case QPainter::CompositionMode_DestinationOver:
+ glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ONE);
+ break;
+ case QPainter::CompositionMode_Clear:
+ glBlendFunc(GL_ZERO, GL_ZERO);
+ break;
+ case QPainter::CompositionMode_Source:
+ glBlendFunc(GL_ONE, GL_ZERO);
+ break;
+ case QPainter::CompositionMode_Destination:
+ glBlendFunc(GL_ZERO, GL_ONE);
+ break;
+ case QPainter::CompositionMode_SourceIn:
+ glBlendFunc(GL_DST_ALPHA, GL_ZERO);
+ break;
+ case QPainter::CompositionMode_DestinationIn:
+ glBlendFunc(GL_ZERO, GL_SRC_ALPHA);
+ break;
+ case QPainter::CompositionMode_SourceOut:
+ glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ZERO);
+ break;
+ case QPainter::CompositionMode_DestinationOut:
+ glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_ALPHA);
+ break;
+ case QPainter::CompositionMode_SourceAtop:
+ glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ break;
+ case QPainter::CompositionMode_DestinationAtop:
+ glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_SRC_ALPHA);
+ break;
+ case QPainter::CompositionMode_Xor:
+ glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ break;
+ case QPainter::CompositionMode_Plus:
+ glBlendFunc(GL_ONE, GL_ONE);
+ break;
+ default:
+ qWarning("Unsupported composition mode");
+ break;
+ }
+
+ compositionModeDirty = false;
+}
+
+static inline void setCoords(GLfloat *coords, const QOpenGLRect &rect)
+{
+ coords[0] = rect.left;
+ coords[1] = rect.top;
+ coords[2] = rect.right;
+ coords[3] = rect.top;
+ coords[4] = rect.right;
+ coords[5] = rect.bottom;
+ coords[6] = rect.left;
+ coords[7] = rect.bottom;
+}
+
+void QOpenGL2PaintEngineExPrivate::drawTexture(const QOpenGLRect& dest, const QOpenGLRect& src, const QSize &textureSize, bool opaque, bool pattern)
+{
+ // Setup for texture drawing
+ currentBrush = noBrush;
+ shaderManager->setSrcPixelType(pattern ? QOpenGLEngineShaderManager::PatternSrc : QOpenGLEngineShaderManager::ImageSrc);
+
+ if (snapToPixelGrid) {
+ snapToPixelGrid = false;
+ matrixDirty = true;
+ }
+
+ if (prepareForDraw(opaque))
+ shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::ImageTexture), QT_IMAGE_TEXTURE_UNIT);
+
+ if (pattern) {
+ QColor col = qt_premultiplyColor(q->state()->pen.color(), (GLfloat)q->state()->opacity);
+ shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::PatternColor), col);
+ }
+
+ GLfloat dx = 1.0 / textureSize.width();
+ GLfloat dy = 1.0 / textureSize.height();
+
+ QOpenGLRect srcTextureRect(src.left*dx, src.top*dy, src.right*dx, src.bottom*dy);
+
+ setCoords(staticVertexCoordinateArray, dest);
+ setCoords(staticTextureCoordinateArray, srcTextureRect);
+
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+}
+
+void QOpenGL2PaintEngineEx::beginNativePainting()
+{
+ Q_D(QOpenGL2PaintEngineEx);
+ ensureActive();
+ d->transferMode(BrushDrawingMode);
+
+ d->nativePaintingActive = true;
+
+ d->funcs.glUseProgram(0);
+
+ // Disable all the vertex attribute arrays:
+ for (int i = 0; i < QT_GL_VERTEX_ARRAY_TRACKED_COUNT; ++i)
+ d->funcs.glDisableVertexAttribArray(i);
+
+#ifndef QT_OPENGL_ES_2
+ Q_ASSERT(QOpenGLContext::currentContext());
+ const QSurfaceFormat &fmt = d->device->context()->format();
+ if (fmt.majorVersion() < 3 || (fmt.majorVersion() == 3 && fmt.minorVersion() < 1)
+ || fmt.profile() == QSurfaceFormat::CompatibilityProfile)
+ {
+ // be nice to people who mix OpenGL 1.x code with QPainter commands
+ // by setting modelview and projection matrices to mirror the GL 1
+ // paint engine
+ const QTransform& mtx = state()->matrix;
+
+ float mv_matrix[4][4] =
+ {
+ { float(mtx.m11()), float(mtx.m12()), 0, float(mtx.m13()) },
+ { float(mtx.m21()), float(mtx.m22()), 0, float(mtx.m23()) },
+ { 0, 0, 1, 0 },
+ { float(mtx.dx()), float(mtx.dy()), 0, float(mtx.m33()) }
+ };
+
+ const QSize sz = d->device->size();
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0, sz.width(), sz.height(), 0, -999999, 999999);
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadMatrixf(&mv_matrix[0][0]);
+ }
+#endif
+
+ d->lastTextureUsed = GLuint(-1);
+ d->dirtyStencilRegion = QRect(0, 0, d->width, d->height);
+ d->resetGLState();
+
+ d->shaderManager->setDirty();
+
+ d->needsSync = true;
+}
+
+void QOpenGL2PaintEngineExPrivate::resetGLState()
+{
+ glDisable(GL_BLEND);
+ funcs.glActiveTexture(GL_TEXTURE0);
+ glDisable(GL_STENCIL_TEST);
+ glDisable(GL_DEPTH_TEST);
+ glDisable(GL_SCISSOR_TEST);
+ glDepthMask(true);
+ glDepthFunc(GL_LESS);
+ funcs.glClearDepthf(1);
+ glStencilMask(0xff);
+ glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
+ glStencilFunc(GL_ALWAYS, 0, 0xff);
+ setVertexAttribArrayEnabled(QT_TEXTURE_COORDS_ATTR, false);
+ setVertexAttribArrayEnabled(QT_VERTEX_COORDS_ATTR, false);
+ setVertexAttribArrayEnabled(QT_OPACITY_ATTR, false);
+#ifndef QT_OPENGL_ES_2
+ // gl_Color, corresponding to vertex attribute 3, may have been changed
+ float color[] = { 1.0f, 1.0f, 1.0f, 1.0f };
+ funcs.glVertexAttrib4fv(3, color);
+#endif
+}
+
+void QOpenGL2PaintEngineEx::endNativePainting()
+{
+ Q_D(QOpenGL2PaintEngineEx);
+ d->needsSync = true;
+ d->nativePaintingActive = false;
+}
+
+void QOpenGL2PaintEngineEx::invalidateState()
+{
+ Q_D(QOpenGL2PaintEngineEx);
+ d->needsSync = true;
+}
+
+bool QOpenGL2PaintEngineEx::isNativePaintingActive() const {
+ Q_D(const QOpenGL2PaintEngineEx);
+ return d->nativePaintingActive;
+}
+
+void QOpenGL2PaintEngineExPrivate::transferMode(EngineMode newMode)
+{
+ if (newMode == mode)
+ return;
+
+ if (mode == TextDrawingMode || mode == ImageDrawingMode || mode == ImageArrayDrawingMode) {
+ lastTextureUsed = GLuint(-1);
+ }
+
+ if (newMode == TextDrawingMode) {
+ shaderManager->setHasComplexGeometry(true);
+ } else {
+ shaderManager->setHasComplexGeometry(false);
+ }
+
+ if (newMode == ImageDrawingMode) {
+ setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, staticVertexCoordinateArray);
+ setVertexAttributePointer(QT_TEXTURE_COORDS_ATTR, staticTextureCoordinateArray);
+ }
+
+ if (newMode == ImageArrayDrawingMode) {
+ setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, (GLfloat*)vertexCoordinateArray.data());
+ setVertexAttributePointer(QT_TEXTURE_COORDS_ATTR, (GLfloat*)textureCoordinateArray.data());
+ setVertexAttributePointer(QT_OPACITY_ATTR, (GLfloat*)opacityArray.data());
+ }
+
+ // This needs to change when we implement high-quality anti-aliasing...
+ if (newMode != TextDrawingMode)
+ shaderManager->setMaskType(QOpenGLEngineShaderManager::NoMask);
+
+ mode = newMode;
+}
+
+struct QOpenGL2PEVectorPathCache
+{
+#ifdef QT_OPENGL_CACHE_AS_VBOS
+ GLuint vbo;
+ GLuint ibo;
+#else
+ float *vertices;
+ void *indices;
+#endif
+ int vertexCount;
+ int indexCount;
+ GLenum primitiveType;
+ qreal iscale;
+ QVertexIndexVector::Type indexType;
+};
+
+void QOpenGL2PaintEngineExPrivate::cleanupVectorPath(QPaintEngineEx *engine, void *data)
+{
+ QOpenGL2PEVectorPathCache *c = (QOpenGL2PEVectorPathCache *) data;
+#ifdef QT_OPENGL_CACHE_AS_VBOS
+ Q_ASSERT(engine->type() == QPaintEngine::OpenGL2);
+ static_cast<QOpenGL2PaintEngineEx *>(engine)->d_func()->unusedVBOSToClean << c->vbo;
+ if (c->ibo)
+ d->unusedIBOSToClean << c->ibo;
+#else
+ Q_UNUSED(engine);
+ qFree(c->vertices);
+ qFree(c->indices);
+#endif
+ delete c;
+}
+
+// Assumes everything is configured for the brush you want to use
+void QOpenGL2PaintEngineExPrivate::fill(const QVectorPath& path)
+{
+ transferMode(BrushDrawingMode);
+
+ if (snapToPixelGrid) {
+ snapToPixelGrid = false;
+ matrixDirty = true;
+ }
+
+ // Might need to call updateMatrix to re-calculate inverseScale
+ if (matrixDirty)
+ updateMatrix();
+
+ const QPointF* const points = reinterpret_cast<const QPointF*>(path.points());
+
+ // Check to see if there's any hints
+ if (path.shape() == QVectorPath::RectangleHint) {
+ QOpenGLRect rect(points[0].x(), points[0].y(), points[2].x(), points[2].y());
+ prepareForDraw(currentBrush.isOpaque());
+ composite(rect);
+ } else if (path.isConvex()) {
+
+ if (path.isCacheable()) {
+ QVectorPath::CacheEntry *data = path.lookupCacheData(q);
+ QOpenGL2PEVectorPathCache *cache;
+
+ bool updateCache = false;
+
+ if (data) {
+ cache = (QOpenGL2PEVectorPathCache *) data->data;
+ // Check if scale factor is exceeded for curved paths and generate curves if so...
+ if (path.isCurved()) {
+ qreal scaleFactor = cache->iscale / inverseScale;
+ if (scaleFactor < 0.5 || scaleFactor > 2.0) {
+#ifdef QT_OPENGL_CACHE_AS_VBOS
+ glDeleteBuffers(1, &cache->vbo);
+ cache->vbo = 0;
+ Q_ASSERT(cache->ibo == 0);
+#else
+ qFree(cache->vertices);
+ Q_ASSERT(cache->indices == 0);
+#endif
+ updateCache = true;
+ }
+ }
+ } else {
+ cache = new QOpenGL2PEVectorPathCache;
+ data = const_cast<QVectorPath &>(path).addCacheData(q, cache, cleanupVectorPath);
+ updateCache = true;
+ }
+
+ // Flatten the path at the current scale factor and fill it into the cache struct.
+ if (updateCache) {
+ vertexCoordinateArray.clear();
+ vertexCoordinateArray.addPath(path, inverseScale, false);
+ int vertexCount = vertexCoordinateArray.vertexCount();
+ int floatSizeInBytes = vertexCount * 2 * sizeof(float);
+ cache->vertexCount = vertexCount;
+ cache->indexCount = 0;
+ cache->primitiveType = GL_TRIANGLE_FAN;
+ cache->iscale = inverseScale;
+#ifdef QT_OPENGL_CACHE_AS_VBOS
+ glGenBuffers(1, &cache->vbo);
+ glBindBuffer(GL_ARRAY_BUFFER, cache->vbo);
+ glBufferData(GL_ARRAY_BUFFER, floatSizeInBytes, vertexCoordinateArray.data(), GL_STATIC_DRAW);
+ cache->ibo = 0;
+#else
+ cache->vertices = (float *) qMalloc(floatSizeInBytes);
+ memcpy(cache->vertices, vertexCoordinateArray.data(), floatSizeInBytes);
+ cache->indices = 0;
+#endif
+ }
+
+ prepareForDraw(currentBrush.isOpaque());
+#ifdef QT_OPENGL_CACHE_AS_VBOS
+ glBindBuffer(GL_ARRAY_BUFFER, cache->vbo);
+ setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, 0);
+#else
+ setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, cache->vertices);
+#endif
+ glDrawArrays(cache->primitiveType, 0, cache->vertexCount);
+
+ } else {
+ // printf(" - Marking path as cachable...\n");
+ // Tag it for later so that if the same path is drawn twice, it is assumed to be static and thus cachable
+ path.makeCacheable();
+ vertexCoordinateArray.clear();
+ vertexCoordinateArray.addPath(path, inverseScale, false);
+ prepareForDraw(currentBrush.isOpaque());
+ drawVertexArrays(vertexCoordinateArray, GL_TRIANGLE_FAN);
+ }
+
+ } else {
+ bool useCache = path.isCacheable();
+ if (useCache) {
+ QRectF bbox = path.controlPointRect();
+ // If the path doesn't fit within these limits, it is possible that the triangulation will fail.
+ useCache &= (bbox.left() > -0x8000 * inverseScale)
+ && (bbox.right() < 0x8000 * inverseScale)
+ && (bbox.top() > -0x8000 * inverseScale)
+ && (bbox.bottom() < 0x8000 * inverseScale);
+ }
+
+ if (useCache) {
+ QVectorPath::CacheEntry *data = path.lookupCacheData(q);
+ QOpenGL2PEVectorPathCache *cache;
+
+ bool updateCache = false;
+
+ if (data) {
+ cache = (QOpenGL2PEVectorPathCache *) data->data;
+ // Check if scale factor is exceeded for curved paths and generate curves if so...
+ if (path.isCurved()) {
+ qreal scaleFactor = cache->iscale / inverseScale;
+ if (scaleFactor < 0.5 || scaleFactor > 2.0) {
+#ifdef QT_OPENGL_CACHE_AS_VBOS
+ glDeleteBuffers(1, &cache->vbo);
+ glDeleteBuffers(1, &cache->ibo);
+#else
+ qFree(cache->vertices);
+ qFree(cache->indices);
+#endif
+ updateCache = true;
+ }
+ }
+ } else {
+ cache = new QOpenGL2PEVectorPathCache;
+ data = const_cast<QVectorPath &>(path).addCacheData(q, cache, cleanupVectorPath);
+ updateCache = true;
+ }
+
+ // Flatten the path at the current scale factor and fill it into the cache struct.
+ if (updateCache) {
+ QTriangleSet polys = qTriangulate(path, QTransform().scale(1 / inverseScale, 1 / inverseScale));
+ cache->vertexCount = polys.vertices.size() / 2;
+ cache->indexCount = polys.indices.size();
+ cache->primitiveType = GL_TRIANGLES;
+ cache->iscale = inverseScale;
+ cache->indexType = polys.indices.type();
+#ifdef QT_OPENGL_CACHE_AS_VBOS
+ glGenBuffers(1, &cache->vbo);
+ glGenBuffers(1, &cache->ibo);
+ glBindBuffer(GL_ARRAY_BUFFER, cache->vbo);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cache->ibo);
+
+ if (polys.indices.type() == QVertexIndexVector::UnsignedInt)
+ funcs.glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(quint32) * polys.indices.size(), polys.indices.data(), GL_STATIC_DRAW);
+ else
+ funcs.glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(quint16) * polys.indices.size(), polys.indices.data(), GL_STATIC_DRAW);
+
+ QVarLengthArray<float> vertices(polys.vertices.size());
+ for (int i = 0; i < polys.vertices.size(); ++i)
+ vertices[i] = float(inverseScale * polys.vertices.at(i));
+ funcs.glBufferData(GL_ARRAY_BUFFER, sizeof(float) * vertices.size(), vertices.data(), GL_STATIC_DRAW);
+#else
+ cache->vertices = (float *) qMalloc(sizeof(float) * polys.vertices.size());
+ if (polys.indices.type() == QVertexIndexVector::UnsignedInt) {
+ cache->indices = (quint32 *) qMalloc(sizeof(quint32) * polys.indices.size());
+ memcpy(cache->indices, polys.indices.data(), sizeof(quint32) * polys.indices.size());
+ } else {
+ cache->indices = (quint16 *) qMalloc(sizeof(quint16) * polys.indices.size());
+ memcpy(cache->indices, polys.indices.data(), sizeof(quint16) * polys.indices.size());
+ }
+ for (int i = 0; i < polys.vertices.size(); ++i)
+ cache->vertices[i] = float(inverseScale * polys.vertices.at(i));
+#endif
+ }
+
+ prepareForDraw(currentBrush.isOpaque());
+#ifdef QT_OPENGL_CACHE_AS_VBOS
+ glBindBuffer(GL_ARRAY_BUFFER, cache->vbo);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cache->ibo);
+ setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, 0);
+ if (cache->indexType == QVertexIndexVector::UnsignedInt)
+ glDrawElements(cache->primitiveType, cache->indexCount, GL_UNSIGNED_INT, 0);
+ else
+ glDrawElements(cache->primitiveType, cache->indexCount, GL_UNSIGNED_SHORT, 0);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+#else
+ setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, cache->vertices);
+ if (cache->indexType == QVertexIndexVector::UnsignedInt)
+ glDrawElements(cache->primitiveType, cache->indexCount, GL_UNSIGNED_INT, (qint32 *)cache->indices);
+ else
+ glDrawElements(cache->primitiveType, cache->indexCount, GL_UNSIGNED_SHORT, (qint16 *)cache->indices);
+#endif
+
+ } else {
+ // printf(" - Marking path as cachable...\n");
+ // Tag it for later so that if the same path is drawn twice, it is assumed to be static and thus cachable
+ path.makeCacheable();
+
+ if (device->context()->format().stencilBufferSize() == 0) {
+ // If there is no stencil buffer, triangulate the path instead.
+
+ QRectF bbox = path.controlPointRect();
+ // If the path doesn't fit within these limits, it is possible that the triangulation will fail.
+ bool withinLimits = (bbox.left() > -0x8000 * inverseScale)
+ && (bbox.right() < 0x8000 * inverseScale)
+ && (bbox.top() > -0x8000 * inverseScale)
+ && (bbox.bottom() < 0x8000 * inverseScale);
+ if (withinLimits) {
+ QTriangleSet polys = qTriangulate(path, QTransform().scale(1 / inverseScale, 1 / inverseScale));
+
+ QVarLengthArray<float> vertices(polys.vertices.size());
+ for (int i = 0; i < polys.vertices.size(); ++i)
+ vertices[i] = float(inverseScale * polys.vertices.at(i));
+
+ prepareForDraw(currentBrush.isOpaque());
+ setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, vertices.constData());
+ if (funcs.hasOpenGLExtension(QOpenGLExtensions::ElementIndexUint))
+ glDrawElements(GL_TRIANGLES, polys.indices.size(), GL_UNSIGNED_INT, polys.indices.data());
+ else
+ glDrawElements(GL_TRIANGLES, polys.indices.size(), GL_UNSIGNED_SHORT, polys.indices.data());
+ } else {
+ // We can't handle big, concave painter paths with OpenGL without stencil buffer.
+ qWarning("Painter path exceeds +/-32767 pixels.");
+ }
+ return;
+ }
+
+ // The path is too complicated & needs the stencil technique
+ vertexCoordinateArray.clear();
+ vertexCoordinateArray.addPath(path, inverseScale, false);
+
+ fillStencilWithVertexArray(vertexCoordinateArray, path.hasWindingFill());
+
+ glStencilMask(0xff);
+ glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE);
+
+ if (q->state()->clipTestEnabled) {
+ // Pass when high bit is set, replace stencil value with current clip
+ glStencilFunc(GL_NOTEQUAL, q->state()->currentClip, GL_STENCIL_HIGH_BIT);
+ } else if (path.hasWindingFill()) {
+ // Pass when any bit is set, replace stencil value with 0
+ glStencilFunc(GL_NOTEQUAL, 0, 0xff);
+ } else {
+ // Pass when high bit is set, replace stencil value with 0
+ glStencilFunc(GL_NOTEQUAL, 0, GL_STENCIL_HIGH_BIT);
+ }
+ prepareForDraw(currentBrush.isOpaque());
+
+ // Stencil the brush onto the dest buffer
+ composite(vertexCoordinateArray.boundingRect());
+ glStencilMask(0);
+ updateClipScissorTest();
+ }
+ }
+}
+
+
+void QOpenGL2PaintEngineExPrivate::fillStencilWithVertexArray(const float *data,
+ int count,
+ int *stops,
+ int stopCount,
+ const QOpenGLRect &bounds,
+ StencilFillMode mode)
+{
+ Q_ASSERT(count || stops);
+
+// qDebug("QOpenGL2PaintEngineExPrivate::fillStencilWithVertexArray()");
+ glStencilMask(0xff); // Enable stencil writes
+
+ if (dirtyStencilRegion.intersects(currentScissorBounds)) {
+ QVector<QRect> clearRegion = dirtyStencilRegion.intersected(currentScissorBounds).rects();
+ glClearStencil(0); // Clear to zero
+ for (int i = 0; i < clearRegion.size(); ++i) {
+#ifndef QT_GL_NO_SCISSOR_TEST
+ setScissor(clearRegion.at(i));
+#endif
+ glClear(GL_STENCIL_BUFFER_BIT);
+ }
+
+ dirtyStencilRegion -= currentScissorBounds;
+
+#ifndef QT_GL_NO_SCISSOR_TEST
+ updateClipScissorTest();
+#endif
+ }
+
+ glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); // Disable color writes
+ useSimpleShader();
+ glEnable(GL_STENCIL_TEST); // For some reason, this has to happen _after_ the simple shader is use()'d
+
+ if (mode == WindingFillMode) {
+ Q_ASSERT(stops && !count);
+ if (q->state()->clipTestEnabled) {
+ // Flatten clip values higher than current clip, and set high bit to match current clip
+ glStencilFunc(GL_LEQUAL, GL_STENCIL_HIGH_BIT | q->state()->currentClip, ~GL_STENCIL_HIGH_BIT);
+ glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE);
+ composite(bounds);
+
+ glStencilFunc(GL_EQUAL, GL_STENCIL_HIGH_BIT, GL_STENCIL_HIGH_BIT);
+ } else if (!stencilClean) {
+ // Clear stencil buffer within bounding rect
+ glStencilFunc(GL_ALWAYS, 0, 0xff);
+ glStencilOp(GL_ZERO, GL_ZERO, GL_ZERO);
+ composite(bounds);
+ }
+
+ // Inc. for front-facing triangle
+ funcs.glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_INCR_WRAP, GL_INCR_WRAP);
+ // Dec. for back-facing "holes"
+ funcs.glStencilOpSeparate(GL_BACK, GL_KEEP, GL_DECR_WRAP, GL_DECR_WRAP);
+ glStencilMask(~GL_STENCIL_HIGH_BIT);
+ drawVertexArrays(data, stops, stopCount, GL_TRIANGLE_FAN);
+
+ if (q->state()->clipTestEnabled) {
+ // Clear high bit of stencil outside of path
+ glStencilFunc(GL_EQUAL, q->state()->currentClip, ~GL_STENCIL_HIGH_BIT);
+ glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE);
+ glStencilMask(GL_STENCIL_HIGH_BIT);
+ composite(bounds);
+ }
+ } else if (mode == OddEvenFillMode) {
+ glStencilMask(GL_STENCIL_HIGH_BIT);
+ glStencilOp(GL_KEEP, GL_KEEP, GL_INVERT); // Simply invert the stencil bit
+ drawVertexArrays(data, stops, stopCount, GL_TRIANGLE_FAN);
+
+ } else { // TriStripStrokeFillMode
+ Q_ASSERT(count && !stops); // tristrips generated directly, so no vertexArray or stops
+ glStencilMask(GL_STENCIL_HIGH_BIT);
+#if 0
+ glStencilOp(GL_KEEP, GL_KEEP, GL_INVERT); // Simply invert the stencil bit
+ setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, data);
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, count);
+#else
+
+ glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
+ if (q->state()->clipTestEnabled) {
+ glStencilFunc(GL_LEQUAL, q->state()->currentClip | GL_STENCIL_HIGH_BIT,
+ ~GL_STENCIL_HIGH_BIT);
+ } else {
+ glStencilFunc(GL_ALWAYS, GL_STENCIL_HIGH_BIT, 0xff);
+ }
+ setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, data);
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, count);
+#endif
+ }
+
+ // Enable color writes & disable stencil writes
+ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+}
+
+/*
+ If the maximum value in the stencil buffer is GL_STENCIL_HIGH_BIT - 1,
+ restore the stencil buffer to a pristine state. The current clip region
+ is set to 1, and the rest to 0.
+*/
+void QOpenGL2PaintEngineExPrivate::resetClipIfNeeded()
+{
+ if (maxClip != (GL_STENCIL_HIGH_BIT - 1))
+ return;
+
+ Q_Q(QOpenGL2PaintEngineEx);
+
+ useSimpleShader();
+ glEnable(GL_STENCIL_TEST);
+ glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
+
+ QRectF bounds = q->state()->matrix.inverted().mapRect(QRectF(0, 0, width, height));
+ QOpenGLRect rect(bounds.left(), bounds.top(), bounds.right(), bounds.bottom());
+
+ // Set high bit on clip region
+ glStencilFunc(GL_LEQUAL, q->state()->currentClip, 0xff);
+ glStencilOp(GL_KEEP, GL_INVERT, GL_INVERT);
+ glStencilMask(GL_STENCIL_HIGH_BIT);
+ composite(rect);
+
+ // Reset clipping to 1 and everything else to zero
+ glStencilFunc(GL_NOTEQUAL, 0x01, GL_STENCIL_HIGH_BIT);
+ glStencilOp(GL_ZERO, GL_REPLACE, GL_REPLACE);
+ glStencilMask(0xff);
+ composite(rect);
+
+ q->state()->currentClip = 1;
+ q->state()->canRestoreClip = false;
+
+ maxClip = 1;
+
+ glStencilMask(0x0);
+ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+}
+
+bool QOpenGL2PaintEngineExPrivate::prepareForDraw(bool srcPixelsAreOpaque)
+{
+ if (brushTextureDirty && mode != ImageDrawingMode && mode != ImageArrayDrawingMode)
+ updateBrushTexture();
+
+ if (compositionModeDirty)
+ updateCompositionMode();
+
+ if (matrixDirty)
+ updateMatrix();
+
+ const bool stateHasOpacity = q->state()->opacity < 0.99f;
+ if (q->state()->composition_mode == QPainter::CompositionMode_Source
+ || (q->state()->composition_mode == QPainter::CompositionMode_SourceOver
+ && srcPixelsAreOpaque && !stateHasOpacity))
+ {
+ glDisable(GL_BLEND);
+ } else {
+ glEnable(GL_BLEND);
+ }
+
+ QOpenGLEngineShaderManager::OpacityMode opacityMode;
+ if (mode == ImageArrayDrawingMode) {
+ opacityMode = QOpenGLEngineShaderManager::AttributeOpacity;
+ } else {
+ opacityMode = stateHasOpacity ? QOpenGLEngineShaderManager::UniformOpacity
+ : QOpenGLEngineShaderManager::NoOpacity;
+ if (stateHasOpacity && (mode != ImageDrawingMode)) {
+ // Using a brush
+ bool brushIsPattern = (currentBrush.style() >= Qt::Dense1Pattern) &&
+ (currentBrush.style() <= Qt::DiagCrossPattern);
+
+ if ((currentBrush.style() == Qt::SolidPattern) || brushIsPattern)
+ opacityMode = QOpenGLEngineShaderManager::NoOpacity; // Global opacity handled by srcPixel shader
+ }
+ }
+ shaderManager->setOpacityMode(opacityMode);
+
+ bool changed = shaderManager->useCorrectShaderProg();
+ // If the shader program needs changing, we change it and mark all uniforms as dirty
+ if (changed) {
+ // The shader program has changed so mark all uniforms as dirty:
+ brushUniformsDirty = true;
+ opacityUniformDirty = true;
+ matrixUniformDirty = true;
+ }
+
+ if (brushUniformsDirty && mode != ImageDrawingMode && mode != ImageArrayDrawingMode)
+ updateBrushUniforms();
+
+ if (opacityMode == QOpenGLEngineShaderManager::UniformOpacity && opacityUniformDirty) {
+ shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::GlobalOpacity), (GLfloat)q->state()->opacity);
+ opacityUniformDirty = false;
+ }
+
+ if (matrixUniformDirty && shaderManager->hasComplexGeometry()) {
+ shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::Matrix),
+ pmvMatrix);
+ matrixUniformDirty = false;
+ }
+
+ return changed;
+}
+
+void QOpenGL2PaintEngineExPrivate::composite(const QOpenGLRect& boundingRect)
+{
+ setCoords(staticVertexCoordinateArray, boundingRect);
+ setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, staticVertexCoordinateArray);
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+}
+
+// Draws the vertex array as a set of <vertexArrayStops.size()> triangle fans.
+void QOpenGL2PaintEngineExPrivate::drawVertexArrays(const float *data, int *stops, int stopCount,
+ GLenum primitive)
+{
+ // Now setup the pointer to the vertex array:
+ setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, (GLfloat*)data);
+
+ int previousStop = 0;
+ for (int i=0; i<stopCount; ++i) {
+ int stop = stops[i];
+/*
+ qDebug("Drawing triangle fan for vertecies %d -> %d:", previousStop, stop-1);
+ for (int i=previousStop; i<stop; ++i)
+ qDebug(" %02d: [%.2f, %.2f]", i, vertexArray.data()[i].x, vertexArray.data()[i].y);
+*/
+ glDrawArrays(primitive, previousStop, stop - previousStop);
+ previousStop = stop;
+ }
+}
+
+/////////////////////////////////// Public Methods //////////////////////////////////////////
+
+QOpenGL2PaintEngineEx::QOpenGL2PaintEngineEx()
+ : QPaintEngineEx(*(new QOpenGL2PaintEngineExPrivate(this)))
+{
+}
+
+QOpenGL2PaintEngineEx::~QOpenGL2PaintEngineEx()
+{
+}
+
+void QOpenGL2PaintEngineEx::fill(const QVectorPath &path, const QBrush &brush)
+{
+ Q_D(QOpenGL2PaintEngineEx);
+
+ if (qbrush_style(brush) == Qt::NoBrush)
+ return;
+ ensureActive();
+ d->setBrush(brush);
+ d->fill(path);
+}
+
+Q_GUI_EXPORT bool qt_scaleForTransform(const QTransform &transform, qreal *scale); // qtransform.cpp
+
+
+void QOpenGL2PaintEngineEx::stroke(const QVectorPath &path, const QPen &pen)
+{
+ Q_D(QOpenGL2PaintEngineEx);
+
+ const QBrush &penBrush = qpen_brush(pen);
+ if (qpen_style(pen) == Qt::NoPen || qbrush_style(penBrush) == Qt::NoBrush)
+ return;
+
+ QOpenGL2PaintEngineState *s = state();
+ if (pen.isCosmetic() && !qt_scaleForTransform(s->transform(), 0)) {
+ // QTriangulatingStroker class is not meant to support cosmetically sheared strokes.
+ QPaintEngineEx::stroke(path, pen);
+ return;
+ }
+
+ ensureActive();
+ d->setBrush(penBrush);
+ d->stroke(path, pen);
+}
+
+void QOpenGL2PaintEngineExPrivate::stroke(const QVectorPath &path, const QPen &pen)
+{
+ const QOpenGL2PaintEngineState *s = q->state();
+ if (snapToPixelGrid) {
+ snapToPixelGrid = false;
+ matrixDirty = true;
+ }
+
+ const Qt::PenStyle penStyle = qpen_style(pen);
+ const QBrush &penBrush = qpen_brush(pen);
+ const bool opaque = penBrush.isOpaque() && s->opacity > 0.99;
+
+ transferMode(BrushDrawingMode);
+
+ // updateMatrix() is responsible for setting the inverse scale on
+ // the strokers, so we need to call it here and not wait for
+ // prepareForDraw() down below.
+ updateMatrix();
+
+ QRectF clip = q->state()->matrix.inverted().mapRect(q->state()->clipEnabled
+ ? q->state()->rectangleClip
+ : QRectF(0, 0, width, height));
+
+ if (penStyle == Qt::SolidLine) {
+ stroker.process(path, pen, clip);
+
+ } else { // Some sort of dash
+ dasher.process(path, pen, clip);
+
+ QVectorPath dashStroke(dasher.points(),
+ dasher.elementCount(),
+ dasher.elementTypes());
+ stroker.process(dashStroke, pen, clip);
+ }
+
+ if (!stroker.vertexCount())
+ return;
+
+ if (opaque) {
+ prepareForDraw(opaque);
+ setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, stroker.vertices());
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, stroker.vertexCount() / 2);
+
+// QBrush b(Qt::green);
+// d->setBrush(&b);
+// d->prepareForDraw(true);
+// glDrawArrays(GL_LINE_STRIP, 0, d->stroker.vertexCount() / 2);
+
+ } else {
+ qreal width = qpen_widthf(pen) / 2;
+ if (width == 0)
+ width = 0.5;
+ qreal extra = pen.joinStyle() == Qt::MiterJoin
+ ? qMax(pen.miterLimit() * width, width)
+ : width;
+
+ if (pen.isCosmetic())
+ extra = extra * inverseScale;
+
+ QRectF bounds = path.controlPointRect().adjusted(-extra, -extra, extra, extra);
+
+ fillStencilWithVertexArray(stroker.vertices(), stroker.vertexCount() / 2,
+ 0, 0, bounds, QOpenGL2PaintEngineExPrivate::TriStripStrokeFillMode);
+
+ glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE);
+
+ // Pass when any bit is set, replace stencil value with 0
+ glStencilFunc(GL_NOTEQUAL, 0, GL_STENCIL_HIGH_BIT);
+ prepareForDraw(false);
+
+ // Stencil the brush onto the dest buffer
+ composite(bounds);
+
+ glStencilMask(0);
+
+ updateClipScissorTest();
+ }
+}
+
+void QOpenGL2PaintEngineEx::penChanged() { }
+void QOpenGL2PaintEngineEx::brushChanged() { }
+void QOpenGL2PaintEngineEx::brushOriginChanged() { }
+
+void QOpenGL2PaintEngineEx::opacityChanged()
+{
+// qDebug("QOpenGL2PaintEngineEx::opacityChanged()");
+ Q_D(QOpenGL2PaintEngineEx);
+ state()->opacityChanged = true;
+
+ Q_ASSERT(d->shaderManager);
+ d->brushUniformsDirty = true;
+ d->opacityUniformDirty = true;
+}
+
+void QOpenGL2PaintEngineEx::compositionModeChanged()
+{
+// qDebug("QOpenGL2PaintEngineEx::compositionModeChanged()");
+ Q_D(QOpenGL2PaintEngineEx);
+ state()->compositionModeChanged = true;
+ d->compositionModeDirty = true;
+}
+
+void QOpenGL2PaintEngineEx::renderHintsChanged()
+{
+ state()->renderHintsChanged = true;
+
+#if !defined(QT_OPENGL_ES_2)
+ if ((state()->renderHints & QPainter::Antialiasing)
+ || (state()->renderHints & QPainter::HighQualityAntialiasing))
+ glEnable(GL_MULTISAMPLE);
+ else
+ glDisable(GL_MULTISAMPLE);
+#endif
+
+ Q_D(QOpenGL2PaintEngineEx);
+ d->lastTextureUsed = GLuint(-1);
+ d->brushTextureDirty = true;
+// qDebug("QOpenGL2PaintEngineEx::renderHintsChanged() not implemented!");
+}
+
+void QOpenGL2PaintEngineEx::transformChanged()
+{
+ Q_D(QOpenGL2PaintEngineEx);
+ d->matrixDirty = true;
+ state()->matrixChanged = true;
+}
+
+
+static const QRectF scaleRect(const QRectF &r, qreal sx, qreal sy)
+{
+ return QRectF(r.x() * sx, r.y() * sy, r.width() * sx, r.height() * sy);
+}
+
+void QOpenGL2PaintEngineEx::drawPixmap(const QRectF& dest, const QPixmap & pixmap, const QRectF & src)
+{
+ Q_D(QOpenGL2PaintEngineEx);
+ QOpenGLContext *ctx = d->ctx;
+
+ int max_texture_size = ctx->d_func()->maxTextureSize();
+ if (pixmap.width() > max_texture_size || pixmap.height() > max_texture_size) {
+ QPixmap scaled = pixmap.scaled(max_texture_size, max_texture_size, Qt::KeepAspectRatio);
+
+ const qreal sx = scaled.width() / qreal(pixmap.width());
+ const qreal sy = scaled.height() / qreal(pixmap.height());
+
+ drawPixmap(dest, scaled, scaleRect(src, sx, sy));
+ return;
+ }
+
+ ensureActive();
+ d->transferMode(ImageDrawingMode);
+
+ d->funcs.glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT);
+ GLuint id = QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, pixmap);
+
+ QOpenGLRect srcRect(src.left(), src.top(), src.right(), src.bottom());
+
+ bool isBitmap = pixmap.isQBitmap();
+ bool isOpaque = !isBitmap && !pixmap.hasAlpha();
+
+ d->updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE,
+ state()->renderHints & QPainter::SmoothPixmapTransform, id);
+ d->drawTexture(dest, srcRect, pixmap.size(), isOpaque, isBitmap);
+}
+
+void QOpenGL2PaintEngineEx::drawImage(const QRectF& dest, const QImage& image, const QRectF& src,
+ Qt::ImageConversionFlags)
+{
+ Q_D(QOpenGL2PaintEngineEx);
+ QOpenGLContext *ctx = d->ctx;
+
+ int max_texture_size = ctx->d_func()->maxTextureSize();
+ if (image.width() > max_texture_size || image.height() > max_texture_size) {
+ QImage scaled = image.scaled(max_texture_size, max_texture_size, Qt::KeepAspectRatio);
+
+ const qreal sx = scaled.width() / qreal(image.width());
+ const qreal sy = scaled.height() / qreal(image.height());
+
+ drawImage(dest, scaled, scaleRect(src, sx, sy));
+ return;
+ }
+
+ ensureActive();
+ d->transferMode(ImageDrawingMode);
+
+ d->funcs.glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT);
+
+ GLuint id = QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, image);
+
+ d->updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE,
+ state()->renderHints & QPainter::SmoothPixmapTransform, id);
+ d->drawTexture(dest, src, image.size(), !image.hasAlphaChannel());
+}
+
+void QOpenGL2PaintEngineEx::drawStaticTextItem(QStaticTextItem *textItem)
+{
+ Q_D(QOpenGL2PaintEngineEx);
+
+ ensureActive();
+
+ QPainterState *s = state();
+ float det = s->matrix.determinant();
+
+ // don't try to cache huge fonts or vastly transformed fonts
+ QFontEngine *fontEngine = textItem->fontEngine();
+ const qreal pixelSize = fontEngine->fontDef.pixelSize;
+ if (shouldDrawCachedGlyphs(pixelSize, s->matrix) || det < 0.25f || det > 4.f) {
+ QFontEngineGlyphCache::Type glyphType = fontEngine->glyphFormat >= 0
+ ? QFontEngineGlyphCache::Type(textItem->fontEngine()->glyphFormat)
+ : d->glyphCacheType;
+ if (glyphType == QFontEngineGlyphCache::Raster_RGBMask) {
+ if (d->device->context()->format().alphaBufferSize() > 0 || s->matrix.type() > QTransform::TxTranslate
+ || (s->composition_mode != QPainter::CompositionMode_Source
+ && s->composition_mode != QPainter::CompositionMode_SourceOver))
+ {
+ glyphType = QFontEngineGlyphCache::Raster_A8;
+ }
+ }
+
+ d->drawCachedGlyphs(glyphType, textItem);
+ } else {
+ QPaintEngineEx::drawStaticTextItem(textItem);
+ }
+}
+
+bool QOpenGL2PaintEngineEx::drawTexture(const QRectF &dest, GLuint textureId, const QSize &size, const QRectF &src)
+{
+ Q_D(QOpenGL2PaintEngineEx);
+ if (!d->shaderManager)
+ return false;
+
+ ensureActive();
+ d->transferMode(ImageDrawingMode);
+
+ d->funcs.glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT);
+ glBindTexture(GL_TEXTURE_2D, textureId);
+
+ QOpenGLRect srcRect(src.left(), src.bottom(), src.right(), src.top());
+
+ d->updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE,
+ state()->renderHints & QPainter::SmoothPixmapTransform, textureId);
+ d->drawTexture(dest, srcRect, size, false);
+ return true;
+}
+
+void QOpenGL2PaintEngineEx::drawTextItem(const QPointF &p, const QTextItem &textItem)
+{
+ Q_D(QOpenGL2PaintEngineEx);
+
+ ensureActive();
+ QOpenGL2PaintEngineState *s = state();
+
+ const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem);
+
+ QTransform::TransformationType txtype = s->matrix.type();
+
+ float det = s->matrix.determinant();
+ bool drawCached = txtype < QTransform::TxProject;
+
+ // don't try to cache huge fonts or vastly transformed fonts
+ const qreal pixelSize = ti.fontEngine->fontDef.pixelSize;
+ if (shouldDrawCachedGlyphs(pixelSize, s->matrix) || det < 0.25f || det > 4.f)
+ drawCached = false;
+
+ QFontEngineGlyphCache::Type glyphType = ti.fontEngine->glyphFormat >= 0
+ ? QFontEngineGlyphCache::Type(ti.fontEngine->glyphFormat)
+ : d->glyphCacheType;
+
+
+ if (glyphType == QFontEngineGlyphCache::Raster_RGBMask) {
+ if (d->device->context()->format().alphaBufferSize() > 0 || txtype > QTransform::TxTranslate
+ || (state()->composition_mode != QPainter::CompositionMode_Source
+ && state()->composition_mode != QPainter::CompositionMode_SourceOver))
+ {
+ glyphType = QFontEngineGlyphCache::Raster_A8;
+ }
+ }
+
+ if (drawCached) {
+ QVarLengthArray<QFixedPoint> positions;
+ QVarLengthArray<glyph_t> glyphs;
+ QTransform matrix = QTransform::fromTranslate(p.x(), p.y());
+ ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions);
+
+ {
+ QStaticTextItem staticTextItem;
+ staticTextItem.chars = const_cast<QChar *>(ti.chars);
+ staticTextItem.setFontEngine(ti.fontEngine);
+ staticTextItem.glyphs = glyphs.data();
+ staticTextItem.numChars = ti.num_chars;
+ staticTextItem.numGlyphs = glyphs.size();
+ staticTextItem.glyphPositions = positions.data();
+
+ d->drawCachedGlyphs(glyphType, &staticTextItem);
+ }
+ return;
+ }
+
+ QPaintEngineEx::drawTextItem(p, ti);
+}
+
+namespace {
+
+ class QOpenGLStaticTextUserData: public QStaticTextUserData
+ {
+ public:
+ QOpenGLStaticTextUserData()
+ : QStaticTextUserData(OpenGLUserData), cacheSize(0, 0), cacheSerialNumber(0)
+ {
+ }
+
+ ~QOpenGLStaticTextUserData()
+ {
+ }
+
+ QSize cacheSize;
+ QOpenGL2PEXVertexArray vertexCoordinateArray;
+ QOpenGL2PEXVertexArray textureCoordinateArray;
+ QFontEngineGlyphCache::Type glyphType;
+ int cacheSerialNumber;
+ };
+
+}
+
+#if defined(Q_WS_WIN)
+static bool fontSmoothingApproximately(qreal target)
+{
+ extern Q_GUI_EXPORT qreal qt_fontsmoothing_gamma; // qapplication_win.cpp
+ return (qAbs(qt_fontsmoothing_gamma - target) < 0.2);
+}
+#endif
+
+// #define QT_OPENGL_DRAWCACHEDGLYPHS_INDEX_ARRAY_VBO
+
+void QOpenGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyphType,
+ QStaticTextItem *staticTextItem)
+{
+ Q_Q(QOpenGL2PaintEngineEx);
+
+ QOpenGL2PaintEngineState *s = q->state();
+
+ void *cacheKey = ctx->shareGroup();
+ bool recreateVertexArrays = false;
+
+ QOpenGLTextureGlyphCache *cache =
+ (QOpenGLTextureGlyphCache *) staticTextItem->fontEngine()->glyphCache(cacheKey, glyphType, QTransform());
+ if (!cache || cache->cacheType() != glyphType || cache->contextGroup() == 0) {
+ cache = new QOpenGLTextureGlyphCache(glyphType, QTransform());
+ staticTextItem->fontEngine()->setGlyphCache(cacheKey, cache);
+ recreateVertexArrays = true;
+ }
+
+ if (staticTextItem->userDataNeedsUpdate) {
+ recreateVertexArrays = true;
+ } else if (staticTextItem->userData() == 0) {
+ recreateVertexArrays = true;
+ } else if (staticTextItem->userData()->type != QStaticTextUserData::OpenGLUserData) {
+ recreateVertexArrays = true;
+ } else {
+ QOpenGLStaticTextUserData *userData = static_cast<QOpenGLStaticTextUserData *>(staticTextItem->userData());
+ if (userData->glyphType != glyphType) {
+ recreateVertexArrays = true;
+ } else if (userData->cacheSerialNumber != cache->serialNumber()) {
+ recreateVertexArrays = true;
+ }
+ }
+
+ // We only need to update the cache with new glyphs if we are actually going to recreate the vertex arrays.
+ // If the cache size has changed, we do need to regenerate the vertices, but we don't need to repopulate the
+ // cache so this text is performed before we test if the cache size has changed.
+ if (recreateVertexArrays) {
+ cache->setPaintEnginePrivate(this);
+ if (!cache->populate(staticTextItem->fontEngine(), staticTextItem->numGlyphs,
+ staticTextItem->glyphs, staticTextItem->glyphPositions)) {
+ // No space for glyphs in cache. We need to reset it and try again.
+ cache->clear();
+ cache->populate(staticTextItem->fontEngine(), staticTextItem->numGlyphs,
+ staticTextItem->glyphs, staticTextItem->glyphPositions);
+ }
+ cache->fillInPendingGlyphs();
+ }
+
+ if (cache->width() == 0 || cache->height() == 0)
+ return;
+
+ transferMode(TextDrawingMode);
+
+ int margin = cache->glyphMargin();
+
+ GLfloat dx = 1.0 / cache->width();
+ GLfloat dy = 1.0 / cache->height();
+
+ // Use global arrays by default
+ QOpenGL2PEXVertexArray *vertexCoordinates = &vertexCoordinateArray;
+ QOpenGL2PEXVertexArray *textureCoordinates = &textureCoordinateArray;
+
+ if (staticTextItem->useBackendOptimizations) {
+ QOpenGLStaticTextUserData *userData = 0;
+
+ if (staticTextItem->userData() == 0
+ || staticTextItem->userData()->type != QStaticTextUserData::OpenGLUserData) {
+
+ userData = new QOpenGLStaticTextUserData();
+ staticTextItem->setUserData(userData);
+
+ } else {
+ userData = static_cast<QOpenGLStaticTextUserData*>(staticTextItem->userData());
+ }
+
+ userData->glyphType = glyphType;
+ userData->cacheSerialNumber = cache->serialNumber();
+
+ // Use cache if backend optimizations is turned on
+ vertexCoordinates = &userData->vertexCoordinateArray;
+ textureCoordinates = &userData->textureCoordinateArray;
+
+ QSize size(cache->width(), cache->height());
+ if (userData->cacheSize != size) {
+ recreateVertexArrays = true;
+ userData->cacheSize = size;
+ }
+ }
+
+ if (recreateVertexArrays) {
+ vertexCoordinates->clear();
+ textureCoordinates->clear();
+
+ bool supportsSubPixelPositions = staticTextItem->fontEngine()->supportsSubPixelPositions();
+ for (int i=0; i<staticTextItem->numGlyphs; ++i) {
+ QFixed subPixelPosition;
+ if (supportsSubPixelPositions)
+ subPixelPosition = cache->subPixelPositionForX(staticTextItem->glyphPositions[i].x);
+
+ QTextureGlyphCache::GlyphAndSubPixelPosition glyph(staticTextItem->glyphs[i], subPixelPosition);
+
+ const QTextureGlyphCache::Coord &c = cache->coords[glyph];
+ if (c.isNull())
+ continue;
+
+ int x = qFloor(staticTextItem->glyphPositions[i].x) + c.baseLineX - margin;
+ int y = qFloor(staticTextItem->glyphPositions[i].y) - c.baseLineY - margin;
+
+ vertexCoordinates->addQuad(QRectF(x, y, c.w, c.h));
+ textureCoordinates->addQuad(QRectF(c.x*dx, c.y*dy, c.w * dx, c.h * dy));
+ }
+
+ staticTextItem->userDataNeedsUpdate = false;
+ }
+
+ int numGlyphs = vertexCoordinates->vertexCount() / 4;
+ if (numGlyphs == 0)
+ return;
+
+ if (elementIndices.size() < numGlyphs*6) {
+ Q_ASSERT(elementIndices.size() % 6 == 0);
+ int j = elementIndices.size() / 6 * 4;
+ while (j < numGlyphs*4) {
+ elementIndices.append(j + 0);
+ elementIndices.append(j + 0);
+ elementIndices.append(j + 1);
+ elementIndices.append(j + 2);
+ elementIndices.append(j + 3);
+ elementIndices.append(j + 3);
+
+ j += 4;
+ }
+
+#if defined(QT_OPENGL_DRAWCACHEDGLYPHS_INDEX_ARRAY_VBO)
+ if (elementIndicesVBOId == 0)
+ glGenBuffers(1, &elementIndicesVBOId);
+
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementIndicesVBOId);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, elementIndices.size() * sizeof(GLushort),
+ elementIndices.constData(), GL_STATIC_DRAW);
+#endif
+ } else {
+#if defined(QT_OPENGL_DRAWCACHEDGLYPHS_INDEX_ARRAY_VBO)
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementIndicesVBOId);
+#endif
+ }
+
+ setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, (GLfloat*)vertexCoordinates->data());
+ setVertexAttributePointer(QT_TEXTURE_COORDS_ATTR, (GLfloat*)textureCoordinates->data());
+
+ if (!snapToPixelGrid) {
+ snapToPixelGrid = true;
+ matrixDirty = true;
+ }
+
+ QBrush pensBrush = q->state()->pen.brush();
+ setBrush(pensBrush);
+
+ if (glyphType == QFontEngineGlyphCache::Raster_RGBMask) {
+
+ // Subpixel antialiasing without gamma correction
+
+ QPainter::CompositionMode compMode = q->state()->composition_mode;
+ Q_ASSERT(compMode == QPainter::CompositionMode_Source
+ || compMode == QPainter::CompositionMode_SourceOver);
+
+ shaderManager->setMaskType(QOpenGLEngineShaderManager::SubPixelMaskPass1);
+
+ if (pensBrush.style() == Qt::SolidPattern) {
+ // Solid patterns can get away with only one pass.
+ QColor c = pensBrush.color();
+ qreal oldOpacity = q->state()->opacity;
+ if (compMode == QPainter::CompositionMode_Source) {
+ c = qt_premultiplyColor(c, q->state()->opacity);
+ q->state()->opacity = 1;
+ opacityUniformDirty = true;
+ }
+
+ compositionModeDirty = false; // I can handle this myself, thank you very much
+ prepareForDraw(false); // Text always causes src pixels to be transparent
+
+ // prepareForDraw() have set the opacity on the current shader, so the opacity state can now be reset.
+ if (compMode == QPainter::CompositionMode_Source) {
+ q->state()->opacity = oldOpacity;
+ opacityUniformDirty = true;
+ }
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_CONSTANT_COLOR, GL_ONE_MINUS_SRC_COLOR);
+ funcs.glBlendColor(c.redF(), c.greenF(), c.blueF(), c.alphaF());
+ } else {
+ // Other brush styles need two passes.
+
+ qreal oldOpacity = q->state()->opacity;
+ if (compMode == QPainter::CompositionMode_Source) {
+ q->state()->opacity = 1;
+ opacityUniformDirty = true;
+ pensBrush = Qt::white;
+ setBrush(pensBrush);
+ }
+
+ compositionModeDirty = false; // I can handle this myself, thank you very much
+ prepareForDraw(false); // Text always causes src pixels to be transparent
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR);
+
+ funcs.glActiveTexture(GL_TEXTURE0 + QT_MASK_TEXTURE_UNIT);
+ glBindTexture(GL_TEXTURE_2D, cache->texture());
+ updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, false);
+
+#if defined(QT_OPENGL_DRAWCACHEDGLYPHS_INDEX_ARRAY_VBO)
+ glDrawElements(GL_TRIANGLE_STRIP, 6 * numGlyphs, GL_UNSIGNED_SHORT, 0);
+#else
+ glDrawElements(GL_TRIANGLE_STRIP, 6 * numGlyphs, GL_UNSIGNED_SHORT, elementIndices.data());
+#endif
+
+ shaderManager->setMaskType(QOpenGLEngineShaderManager::SubPixelMaskPass2);
+
+ if (compMode == QPainter::CompositionMode_Source) {
+ q->state()->opacity = oldOpacity;
+ opacityUniformDirty = true;
+ pensBrush = q->state()->pen.brush();
+ setBrush(pensBrush);
+ }
+
+ compositionModeDirty = false;
+ prepareForDraw(false); // Text always causes src pixels to be transparent
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_ONE, GL_ONE);
+ }
+ compositionModeDirty = true;
+ } else {
+ // Greyscale/mono glyphs
+
+ shaderManager->setMaskType(QOpenGLEngineShaderManager::PixelMask);
+ prepareForDraw(false); // Text always causes src pixels to be transparent
+ }
+
+ QOpenGLTextureGlyphCache::FilterMode filterMode = (s->matrix.type() > QTransform::TxTranslate)?QOpenGLTextureGlyphCache::Linear:QOpenGLTextureGlyphCache::Nearest;
+ if (lastMaskTextureUsed != cache->texture() || cache->filterMode() != filterMode) {
+
+ funcs.glActiveTexture(GL_TEXTURE0 + QT_MASK_TEXTURE_UNIT);
+ if (lastMaskTextureUsed != cache->texture()) {
+ glBindTexture(GL_TEXTURE_2D, cache->texture());
+ lastMaskTextureUsed = cache->texture();
+ }
+
+ if (cache->filterMode() != filterMode) {
+ if (filterMode == QOpenGLTextureGlyphCache::Linear) {
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ } else {
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ }
+ cache->setFilterMode(filterMode);
+ }
+ }
+
+ bool srgbFrameBufferEnabled = false;
+ if (funcs.hasOpenGLExtension(QOpenGLExtensions::SRGBFrameBuffer)) {
+#if defined(Q_WS_MAC)
+ if (glyphType == QFontEngineGlyphCache::Raster_RGBMask)
+#elif defined(Q_WS_WIN)
+ if (glyphType != QFontEngineGlyphCache::Raster_RGBMask || fontSmoothingApproximately(2.1))
+#else
+ if (false)
+#endif
+ {
+ glEnable(GL_FRAMEBUFFER_SRGB);
+ srgbFrameBufferEnabled = true;
+ }
+ }
+
+#if defined(QT_OPENGL_DRAWCACHEDGLYPHS_INDEX_ARRAY_VBO)
+ glDrawElements(GL_TRIANGLE_STRIP, 6 * numGlyphs, GL_UNSIGNED_SHORT, 0);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+#else
+ glDrawElements(GL_TRIANGLE_STRIP, 6 * numGlyphs, GL_UNSIGNED_SHORT, elementIndices.data());
+#endif
+
+ if (srgbFrameBufferEnabled)
+ glDisable(GL_FRAMEBUFFER_SRGB);
+
+}
+
+void QOpenGL2PaintEngineEx::drawPixmapFragments(const QPainter::PixmapFragment *fragments, int fragmentCount, const QPixmap &pixmap,
+ QPainter::PixmapFragmentHints hints)
+{
+ Q_D(QOpenGL2PaintEngineEx);
+ // Use fallback for extended composition modes.
+ if (state()->composition_mode > QPainter::CompositionMode_Plus) {
+ QPaintEngineEx::drawPixmapFragments(fragments, fragmentCount, pixmap, hints);
+ return;
+ }
+
+ ensureActive();
+ int max_texture_size = d->ctx->d_func()->maxTextureSize();
+ if (pixmap.width() > max_texture_size || pixmap.height() > max_texture_size) {
+ QPixmap scaled = pixmap.scaled(max_texture_size, max_texture_size, Qt::KeepAspectRatio);
+ d->drawPixmapFragments(fragments, fragmentCount, scaled, hints);
+ } else {
+ d->drawPixmapFragments(fragments, fragmentCount, pixmap, hints);
+ }
+}
+
+
+void QOpenGL2PaintEngineExPrivate::drawPixmapFragments(const QPainter::PixmapFragment *fragments,
+ int fragmentCount, const QPixmap &pixmap,
+ QPainter::PixmapFragmentHints hints)
+{
+ GLfloat dx = 1.0f / pixmap.size().width();
+ GLfloat dy = 1.0f / pixmap.size().height();
+
+ vertexCoordinateArray.clear();
+ textureCoordinateArray.clear();
+ opacityArray.reset();
+
+ if (snapToPixelGrid) {
+ snapToPixelGrid = false;
+ matrixDirty = true;
+ }
+
+ bool allOpaque = true;
+
+ for (int i = 0; i < fragmentCount; ++i) {
+ qreal s = 0;
+ qreal c = 1;
+ if (fragments[i].rotation != 0) {
+ s = qFastSin(fragments[i].rotation * Q_PI / 180);
+ c = qFastCos(fragments[i].rotation * Q_PI / 180);
+ }
+
+ qreal right = 0.5 * fragments[i].scaleX * fragments[i].width;
+ qreal bottom = 0.5 * fragments[i].scaleY * fragments[i].height;
+ QOpenGLPoint bottomRight(right * c - bottom * s, right * s + bottom * c);
+ QOpenGLPoint bottomLeft(-right * c - bottom * s, -right * s + bottom * c);
+
+ vertexCoordinateArray.addVertex(bottomRight.x + fragments[i].x, bottomRight.y + fragments[i].y);
+ vertexCoordinateArray.addVertex(-bottomLeft.x + fragments[i].x, -bottomLeft.y + fragments[i].y);
+ vertexCoordinateArray.addVertex(-bottomRight.x + fragments[i].x, -bottomRight.y + fragments[i].y);
+ vertexCoordinateArray.addVertex(-bottomRight.x + fragments[i].x, -bottomRight.y + fragments[i].y);
+ vertexCoordinateArray.addVertex(bottomLeft.x + fragments[i].x, bottomLeft.y + fragments[i].y);
+ vertexCoordinateArray.addVertex(bottomRight.x + fragments[i].x, bottomRight.y + fragments[i].y);
+
+ QOpenGLRect src(fragments[i].sourceLeft * dx, fragments[i].sourceTop * dy,
+ (fragments[i].sourceLeft + fragments[i].width) * dx,
+ (fragments[i].sourceTop + fragments[i].height) * dy);
+
+ textureCoordinateArray.addVertex(src.right, src.bottom);
+ textureCoordinateArray.addVertex(src.right, src.top);
+ textureCoordinateArray.addVertex(src.left, src.top);
+ textureCoordinateArray.addVertex(src.left, src.top);
+ textureCoordinateArray.addVertex(src.left, src.bottom);
+ textureCoordinateArray.addVertex(src.right, src.bottom);
+
+ qreal opacity = fragments[i].opacity * q->state()->opacity;
+ opacityArray << opacity << opacity << opacity << opacity << opacity << opacity;
+ allOpaque &= (opacity >= 0.99f);
+ }
+
+ funcs.glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT);
+ GLuint id = QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, pixmap);
+ transferMode(ImageArrayDrawingMode);
+
+ bool isBitmap = pixmap.isQBitmap();
+ bool isOpaque = !isBitmap && (!pixmap.hasAlpha() || (hints & QPainter::OpaqueHint)) && allOpaque;
+
+ updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE,
+ q->state()->renderHints & QPainter::SmoothPixmapTransform, id);
+
+ // Setup for texture drawing
+ currentBrush = noBrush;
+ shaderManager->setSrcPixelType(isBitmap ? QOpenGLEngineShaderManager::PatternSrc
+ : QOpenGLEngineShaderManager::ImageSrc);
+ if (prepareForDraw(isOpaque))
+ shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::ImageTexture), QT_IMAGE_TEXTURE_UNIT);
+
+ if (isBitmap) {
+ QColor col = qt_premultiplyColor(q->state()->pen.color(), (GLfloat)q->state()->opacity);
+ shaderManager->currentProgram()->setUniformValue(location(QOpenGLEngineShaderManager::PatternColor), col);
+ }
+
+ glDrawArrays(GL_TRIANGLES, 0, 6 * fragmentCount);
+}
+
+bool QOpenGL2PaintEngineEx::begin(QPaintDevice *pdev)
+{
+ Q_D(QOpenGL2PaintEngineEx);
+
+ Q_ASSERT(pdev->devType() == QInternal::OpenGL);
+ d->device = static_cast<QOpenGLPaintDevice*>(pdev);
+
+ if (!d->device)
+ return false;
+
+ if (d->device->context() != QOpenGLContext::currentContext()) {
+ qWarning("QPainter::begin(): QOpenGLPaintDevice's context needs to be current");
+ return false;
+ }
+
+ d->ctx = QOpenGLContext::currentContext();
+ d->ctx->d_func()->active_engine = this;
+
+ d->funcs.initializeGLFunctions();
+
+ for (int i = 0; i < QT_GL_VERTEX_ARRAY_TRACKED_COUNT; ++i)
+ d->vertexAttributeArraysEnabledState[i] = false;
+
+ const QSize sz = d->device->size();
+ d->width = sz.width();
+ d->height = sz.height();
+ d->mode = BrushDrawingMode;
+ d->brushTextureDirty = true;
+ d->brushUniformsDirty = true;
+ d->matrixUniformDirty = true;
+ d->matrixDirty = true;
+ d->compositionModeDirty = true;
+ d->opacityUniformDirty = true;
+ d->needsSync = true;
+ d->useSystemClip = !systemClip().isEmpty();
+ d->currentBrush = QBrush();
+
+ d->dirtyStencilRegion = QRect(0, 0, d->width, d->height);
+ d->stencilClean = true;
+
+ d->shaderManager = new QOpenGLEngineShaderManager(d->ctx);
+
+ glDisable(GL_STENCIL_TEST);
+ glDisable(GL_DEPTH_TEST);
+ glDisable(GL_SCISSOR_TEST);
+
+#if !defined(QT_OPENGL_ES_2)
+ glDisable(GL_MULTISAMPLE);
+#endif
+
+ d->glyphCacheType = QFontEngineGlyphCache::Raster_A8;
+
+#if !defined(QT_OPENGL_ES_2)
+#if defined(Q_WS_WIN)
+ if (qt_cleartype_enabled
+ && (fontSmoothingApproximately(1.0) || fontSmoothingApproximately(2.1)))
+#endif
+#if defined(Q_WS_MAC)
+ if (qt_applefontsmoothing_enabled)
+#endif
+ d->glyphCacheType = QFontEngineGlyphCache::Raster_RGBMask;
+#endif
+
+#if defined(QT_OPENGL_ES_2)
+ // OpenGL ES can't switch MSAA off, so if the gl paint device is
+ // multisampled, it's always multisampled.
+ d->multisamplingAlwaysEnabled = d->device->context()->format().samples() > 1;
+#else
+ d->multisamplingAlwaysEnabled = false;
+#endif
+
+ return true;
+}
+
+bool QOpenGL2PaintEngineEx::end()
+{
+ Q_D(QOpenGL2PaintEngineEx);
+
+ QOpenGLContext *ctx = d->ctx;
+ d->funcs.glUseProgram(0);
+ d->transferMode(BrushDrawingMode);
+
+ ctx->d_func()->active_engine = 0;
+
+ d->resetGLState();
+
+ delete d->shaderManager;
+ d->shaderManager = 0;
+ d->currentBrush = QBrush();
+
+#ifdef QT_OPENGL_CACHE_AS_VBOS
+ if (!d->unusedVBOSToClean.isEmpty()) {
+ glDeleteBuffers(d->unusedVBOSToClean.size(), d->unusedVBOSToClean.constData());
+ d->unusedVBOSToClean.clear();
+ }
+ if (!d->unusedIBOSToClean.isEmpty()) {
+ glDeleteBuffers(d->unusedIBOSToClean.size(), d->unusedIBOSToClean.constData());
+ d->unusedIBOSToClean.clear();
+ }
+#endif
+
+ return false;
+}
+
+void QOpenGL2PaintEngineEx::ensureActive()
+{
+ Q_D(QOpenGL2PaintEngineEx);
+ QOpenGLContext *ctx = d->ctx;
+
+ if (isActive() && ctx->d_func()->active_engine != this) {
+ ctx->d_func()->active_engine = this;
+ d->needsSync = true;
+ }
+
+ if (d->needsSync) {
+ d->transferMode(BrushDrawingMode);
+ glViewport(0, 0, d->width, d->height);
+ d->needsSync = false;
+ d->lastMaskTextureUsed = 0;
+ d->shaderManager->setDirty();
+ d->syncGlState();
+ for (int i = 0; i < 3; ++i)
+ d->vertexAttribPointers[i] = (GLfloat*)-1; // Assume the pointers are clobbered
+ setState(state());
+ }
+}
+
+void QOpenGL2PaintEngineExPrivate::updateClipScissorTest()
+{
+ Q_Q(QOpenGL2PaintEngineEx);
+ if (q->state()->clipTestEnabled) {
+ glEnable(GL_STENCIL_TEST);
+ glStencilFunc(GL_LEQUAL, q->state()->currentClip, ~GL_STENCIL_HIGH_BIT);
+ } else {
+ glDisable(GL_STENCIL_TEST);
+ glStencilFunc(GL_ALWAYS, 0, 0xff);
+ }
+
+#ifdef QT_GL_NO_SCISSOR_TEST
+ currentScissorBounds = QRect(0, 0, width, height);
+#else
+ QRect bounds = q->state()->rectangleClip;
+ if (!q->state()->clipEnabled) {
+ if (useSystemClip)
+ bounds = systemClip.boundingRect();
+ else
+ bounds = QRect(0, 0, width, height);
+ } else {
+ if (useSystemClip)
+ bounds = bounds.intersected(systemClip.boundingRect());
+ else
+ bounds = bounds.intersected(QRect(0, 0, width, height));
+ }
+
+ currentScissorBounds = bounds;
+
+ if (bounds == QRect(0, 0, width, height)) {
+ glDisable(GL_SCISSOR_TEST);
+ } else {
+ glEnable(GL_SCISSOR_TEST);
+ setScissor(bounds);
+ }
+#endif
+}
+
+void QOpenGL2PaintEngineExPrivate::setScissor(const QRect &rect)
+{
+ const int left = rect.left();
+ const int width = rect.width();
+ int bottom = height - (rect.top() + rect.height());
+ if (device->paintFlipped()) {
+ bottom = rect.top();
+ }
+ const int height = rect.height();
+
+ glScissor(left, bottom, width, height);
+}
+
+void QOpenGL2PaintEngineEx::clipEnabledChanged()
+{
+ Q_D(QOpenGL2PaintEngineEx);
+
+ state()->clipChanged = true;
+
+ if (painter()->hasClipping())
+ d->regenerateClip();
+ else
+ d->systemStateChanged();
+}
+
+void QOpenGL2PaintEngineExPrivate::clearClip(uint value)
+{
+ dirtyStencilRegion -= currentScissorBounds;
+
+ glStencilMask(0xff);
+ glClearStencil(value);
+ glClear(GL_STENCIL_BUFFER_BIT);
+ glStencilMask(0x0);
+
+ q->state()->needsClipBufferClear = false;
+}
+
+void QOpenGL2PaintEngineExPrivate::writeClip(const QVectorPath &path, uint value)
+{
+ transferMode(BrushDrawingMode);
+
+ if (snapToPixelGrid) {
+ snapToPixelGrid = false;
+ matrixDirty = true;
+ }
+
+ if (matrixDirty)
+ updateMatrix();
+
+ stencilClean = false;
+
+ const bool singlePass = !path.hasWindingFill()
+ && (((q->state()->currentClip == maxClip - 1) && q->state()->clipTestEnabled)
+ || q->state()->needsClipBufferClear);
+ const uint referenceClipValue = q->state()->needsClipBufferClear ? 1 : q->state()->currentClip;
+
+ if (q->state()->needsClipBufferClear)
+ clearClip(1);
+
+ if (path.isEmpty()) {
+ glEnable(GL_STENCIL_TEST);
+ glStencilFunc(GL_LEQUAL, value, ~GL_STENCIL_HIGH_BIT);
+ return;
+ }
+
+ if (q->state()->clipTestEnabled)
+ glStencilFunc(GL_LEQUAL, q->state()->currentClip, ~GL_STENCIL_HIGH_BIT);
+ else
+ glStencilFunc(GL_ALWAYS, 0, 0xff);
+
+ vertexCoordinateArray.clear();
+ vertexCoordinateArray.addPath(path, inverseScale, false);
+
+ if (!singlePass)
+ fillStencilWithVertexArray(vertexCoordinateArray, path.hasWindingFill());
+
+ glColorMask(false, false, false, false);
+ glEnable(GL_STENCIL_TEST);
+ useSimpleShader();
+
+ if (singlePass) {
+ // Under these conditions we can set the new stencil value in a single
+ // pass, by using the current value and the "new value" as the toggles
+
+ glStencilFunc(GL_LEQUAL, referenceClipValue, ~GL_STENCIL_HIGH_BIT);
+ glStencilOp(GL_KEEP, GL_INVERT, GL_INVERT);
+ glStencilMask(value ^ referenceClipValue);
+
+ drawVertexArrays(vertexCoordinateArray, GL_TRIANGLE_FAN);
+ } else {
+ glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE);
+ glStencilMask(0xff);
+
+ if (!q->state()->clipTestEnabled && path.hasWindingFill()) {
+ // Pass when any clip bit is set, set high bit
+ glStencilFunc(GL_NOTEQUAL, GL_STENCIL_HIGH_BIT, ~GL_STENCIL_HIGH_BIT);
+ composite(vertexCoordinateArray.boundingRect());
+ }
+
+ // Pass when high bit is set, replace stencil value with new clip value
+ glStencilFunc(GL_NOTEQUAL, value, GL_STENCIL_HIGH_BIT);
+
+ composite(vertexCoordinateArray.boundingRect());
+ }
+
+ glStencilFunc(GL_LEQUAL, value, ~GL_STENCIL_HIGH_BIT);
+ glStencilMask(0);
+
+ glColorMask(true, true, true, true);
+}
+
+void QOpenGL2PaintEngineEx::clip(const QVectorPath &path, Qt::ClipOperation op)
+{
+// qDebug("QOpenGL2PaintEngineEx::clip()");
+ Q_D(QOpenGL2PaintEngineEx);
+
+ state()->clipChanged = true;
+
+ ensureActive();
+
+ if (op == Qt::ReplaceClip) {
+ op = Qt::IntersectClip;
+ if (d->hasClipOperations()) {
+ d->systemStateChanged();
+ state()->canRestoreClip = false;
+ }
+ }
+
+#ifndef QT_GL_NO_SCISSOR_TEST
+ if (!path.isEmpty() && op == Qt::IntersectClip && (path.shape() == QVectorPath::RectangleHint)) {
+ const QPointF* const points = reinterpret_cast<const QPointF*>(path.points());
+ QRectF rect(points[0], points[2]);
+
+ if (state()->matrix.type() <= QTransform::TxScale
+ || (state()->matrix.type() == QTransform::TxRotate
+ && qFuzzyIsNull(state()->matrix.m11())
+ && qFuzzyIsNull(state()->matrix.m22())))
+ {
+ state()->rectangleClip = state()->rectangleClip.intersected(state()->matrix.mapRect(rect).toRect());
+ d->updateClipScissorTest();
+ return;
+ }
+ }
+#endif
+
+ const QRect pathRect = state()->matrix.mapRect(path.controlPointRect()).toAlignedRect();
+
+ switch (op) {
+ case Qt::NoClip:
+ if (d->useSystemClip) {
+ state()->clipTestEnabled = true;
+ state()->currentClip = 1;
+ } else {
+ state()->clipTestEnabled = false;
+ }
+ state()->rectangleClip = QRect(0, 0, d->width, d->height);
+ state()->canRestoreClip = false;
+ d->updateClipScissorTest();
+ break;
+ case Qt::IntersectClip:
+ state()->rectangleClip = state()->rectangleClip.intersected(pathRect);
+ d->updateClipScissorTest();
+ d->resetClipIfNeeded();
+ ++d->maxClip;
+ d->writeClip(path, d->maxClip);
+ state()->currentClip = d->maxClip;
+ state()->clipTestEnabled = true;
+ break;
+ default:
+ break;
+ }
+}
+
+void QOpenGL2PaintEngineExPrivate::regenerateClip()
+{
+ systemStateChanged();
+ replayClipOperations();
+}
+
+void QOpenGL2PaintEngineExPrivate::systemStateChanged()
+{
+ Q_Q(QOpenGL2PaintEngineEx);
+
+ q->state()->clipChanged = true;
+
+ if (systemClip.isEmpty()) {
+ useSystemClip = false;
+ } else {
+ if (q->paintDevice()->devType() == QInternal::Widget && currentClipDevice) {
+ //QWidgetPrivate *widgetPrivate = qt_widget_private(static_cast<QWidget *>(currentClipDevice)->window());
+ //useSystemClip = widgetPrivate->extra && widgetPrivate->extra->inRenderWithPainter;
+ useSystemClip = true;
+ } else {
+ useSystemClip = true;
+ }
+ }
+
+ q->state()->clipTestEnabled = false;
+ q->state()->needsClipBufferClear = true;
+
+ q->state()->currentClip = 1;
+ maxClip = 1;
+
+ q->state()->rectangleClip = useSystemClip ? systemClip.boundingRect() : QRect(0, 0, width, height);
+ updateClipScissorTest();
+
+ if (systemClip.rectCount() == 1) {
+ if (systemClip.boundingRect() == QRect(0, 0, width, height))
+ useSystemClip = false;
+#ifndef QT_GL_NO_SCISSOR_TEST
+ // scissoring takes care of the system clip
+ return;
+#endif
+ }
+
+ if (useSystemClip) {
+ clearClip(0);
+
+ QPainterPath path;
+ path.addRegion(systemClip);
+
+ q->state()->currentClip = 0;
+ writeClip(qtVectorPathForPath(q->state()->matrix.inverted().map(path)), 1);
+ q->state()->currentClip = 1;
+ q->state()->clipTestEnabled = true;
+ }
+}
+
+void QOpenGL2PaintEngineEx::setState(QPainterState *new_state)
+{
+ // qDebug("QOpenGL2PaintEngineEx::setState()");
+
+ Q_D(QOpenGL2PaintEngineEx);
+
+ QOpenGL2PaintEngineState *s = static_cast<QOpenGL2PaintEngineState *>(new_state);
+ QOpenGL2PaintEngineState *old_state = state();
+
+ QPaintEngineEx::setState(s);
+
+ if (s->isNew) {
+ // Newly created state object. The call to setState()
+ // will either be followed by a call to begin(), or we are
+ // setting the state as part of a save().
+ s->isNew = false;
+ return;
+ }
+
+ // Setting the state as part of a restore().
+
+ if (old_state == s || old_state->renderHintsChanged)
+ renderHintsChanged();
+
+ if (old_state == s || old_state->matrixChanged)
+ d->matrixDirty = true;
+
+ if (old_state == s || old_state->compositionModeChanged)
+ d->compositionModeDirty = true;
+
+ if (old_state == s || old_state->opacityChanged)
+ d->opacityUniformDirty = true;
+
+ if (old_state == s || old_state->clipChanged) {
+ if (old_state && old_state != s && old_state->canRestoreClip) {
+ d->updateClipScissorTest();
+ glDepthFunc(GL_LEQUAL);
+ } else {
+ d->regenerateClip();
+ }
+ }
+}
+
+QPainterState *QOpenGL2PaintEngineEx::createState(QPainterState *orig) const
+{
+ if (orig)
+ const_cast<QOpenGL2PaintEngineEx *>(this)->ensureActive();
+
+ QOpenGL2PaintEngineState *s;
+ if (!orig)
+ s = new QOpenGL2PaintEngineState();
+ else
+ s = new QOpenGL2PaintEngineState(*static_cast<QOpenGL2PaintEngineState *>(orig));
+
+ s->matrixChanged = false;
+ s->compositionModeChanged = false;
+ s->opacityChanged = false;
+ s->renderHintsChanged = false;
+ s->clipChanged = false;
+
+ return s;
+}
+
+QOpenGL2PaintEngineState::QOpenGL2PaintEngineState(QOpenGL2PaintEngineState &other)
+ : QPainterState(other)
+{
+ isNew = true;
+ needsClipBufferClear = other.needsClipBufferClear;
+ clipTestEnabled = other.clipTestEnabled;
+ currentClip = other.currentClip;
+ canRestoreClip = other.canRestoreClip;
+ rectangleClip = other.rectangleClip;
+}
+
+QOpenGL2PaintEngineState::QOpenGL2PaintEngineState()
+{
+ isNew = true;
+ needsClipBufferClear = true;
+ clipTestEnabled = false;
+ canRestoreClip = true;
+}
+
+QOpenGL2PaintEngineState::~QOpenGL2PaintEngineState()
+{
+}
+
+void QOpenGL2PaintEngineExPrivate::setVertexAttribArrayEnabled(int arrayIndex, bool enabled)
+{
+ Q_ASSERT(arrayIndex < QT_GL_VERTEX_ARRAY_TRACKED_COUNT);
+
+ if (vertexAttributeArraysEnabledState[arrayIndex] && !enabled)
+ funcs.glDisableVertexAttribArray(arrayIndex);
+
+ if (!vertexAttributeArraysEnabledState[arrayIndex] && enabled)
+ funcs.glEnableVertexAttribArray(arrayIndex);
+
+ vertexAttributeArraysEnabledState[arrayIndex] = enabled;
+}
+
+void QOpenGL2PaintEngineExPrivate::syncGlState()
+{
+ for (int i = 0; i < QT_GL_VERTEX_ARRAY_TRACKED_COUNT; ++i) {
+ if (vertexAttributeArraysEnabledState[i])
+ funcs.glEnableVertexAttribArray(i);
+ else
+ funcs.glDisableVertexAttribArray(i);
+ }
+}
+
+
+QT_END_NAMESPACE
diff --git a/src/gui/opengl/qopenglpaintengine_p.h b/src/gui/opengl/qopenglpaintengine_p.h
new file mode 100644
index 0000000000..1ce04eb5a7
--- /dev/null
+++ b/src/gui/opengl/qopenglpaintengine_p.h
@@ -0,0 +1,339 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QOPENGLPAINTENGINE_P_H
+#define QOPENGLPAINTENGINE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QDebug>
+
+#include <qopenglpaintdevice.h>
+
+#include <private/qpaintengineex_p.h>
+#include <private/qopenglengineshadermanager_p.h>
+#include <private/qopengl2pexvertexarray_p.h>
+#include <private/qfontengine_p.h>
+#include <private/qdatabuffer_p.h>
+#include <private/qopengltriangulatingstroker_p.h>
+
+#include <private/qopenglextensions_p.h>
+
+enum EngineMode {
+ ImageDrawingMode,
+ TextDrawingMode,
+ BrushDrawingMode,
+ ImageArrayDrawingMode
+};
+
+QT_BEGIN_NAMESPACE
+
+#define GL_STENCIL_HIGH_BIT GLuint(0x80)
+#define QT_BRUSH_TEXTURE_UNIT GLuint(0)
+#define QT_IMAGE_TEXTURE_UNIT GLuint(0) //Can be the same as brush texture unit
+#define QT_MASK_TEXTURE_UNIT GLuint(1)
+#define QT_BACKGROUND_TEXTURE_UNIT GLuint(2)
+
+class QOpenGL2PaintEngineExPrivate;
+
+class QOpenGL2PaintEngineState : public QPainterState
+{
+public:
+ QOpenGL2PaintEngineState(QOpenGL2PaintEngineState &other);
+ QOpenGL2PaintEngineState();
+ ~QOpenGL2PaintEngineState();
+
+ uint isNew : 1;
+ uint needsClipBufferClear : 1;
+ uint clipTestEnabled : 1;
+ uint canRestoreClip : 1;
+ uint matrixChanged : 1;
+ uint compositionModeChanged : 1;
+ uint opacityChanged : 1;
+ uint renderHintsChanged : 1;
+ uint clipChanged : 1;
+ uint currentClip : 8;
+
+ QRect rectangleClip;
+};
+
+class Q_GUI_EXPORT QOpenGL2PaintEngineEx : public QPaintEngineEx
+{
+ Q_DECLARE_PRIVATE(QOpenGL2PaintEngineEx)
+public:
+ QOpenGL2PaintEngineEx();
+ ~QOpenGL2PaintEngineEx();
+
+ bool begin(QPaintDevice *device);
+ void ensureActive();
+ bool end();
+
+ virtual void clipEnabledChanged();
+ virtual void penChanged();
+ virtual void brushChanged();
+ virtual void brushOriginChanged();
+ virtual void opacityChanged();
+ virtual void compositionModeChanged();
+ virtual void renderHintsChanged();
+ virtual void transformChanged();
+
+ virtual void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr);
+ virtual void drawPixmapFragments(const QPainter::PixmapFragment *fragments, int fragmentCount, const QPixmap &pixmap,
+ QPainter::PixmapFragmentHints hints);
+ virtual void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr,
+ Qt::ImageConversionFlags flags = Qt::AutoColor);
+ virtual void drawTextItem(const QPointF &p, const QTextItem &textItem);
+ virtual void fill(const QVectorPath &path, const QBrush &brush);
+ virtual void stroke(const QVectorPath &path, const QPen &pen);
+ virtual void clip(const QVectorPath &path, Qt::ClipOperation op);
+
+ virtual void drawStaticTextItem(QStaticTextItem *textItem);
+
+ bool drawTexture(const QRectF &r, GLuint textureId, const QSize &size, const QRectF &sr);
+
+ Type type() const { return OpenGL2; }
+
+ virtual void setState(QPainterState *s);
+ virtual QPainterState *createState(QPainterState *orig) const;
+ inline QOpenGL2PaintEngineState *state() {
+ return static_cast<QOpenGL2PaintEngineState *>(QPaintEngineEx::state());
+ }
+ inline const QOpenGL2PaintEngineState *state() const {
+ return static_cast<const QOpenGL2PaintEngineState *>(QPaintEngineEx::state());
+ }
+
+ void beginNativePainting();
+ void endNativePainting();
+
+ void invalidateState();
+
+ void setRenderTextActive(bool);
+
+ bool isNativePaintingActive() const;
+ bool supportsTransformations(qreal, const QTransform &) const { return true; }
+
+private:
+ Q_DISABLE_COPY(QOpenGL2PaintEngineEx)
+
+ friend class QOpenGLEngineShaderManager;
+};
+
+// This probably needs to grow to GL_MAX_VERTEX_ATTRIBS, but 3 is ok for now as that's
+// all the GL2 engine uses:
+#define QT_GL_VERTEX_ARRAY_TRACKED_COUNT 3
+
+class QOpenGL2PaintEngineExPrivate : public QPaintEngineExPrivate
+{
+ Q_DECLARE_PUBLIC(QOpenGL2PaintEngineEx)
+public:
+ enum StencilFillMode {
+ OddEvenFillMode,
+ WindingFillMode,
+ TriStripStrokeFillMode
+ };
+
+ QOpenGL2PaintEngineExPrivate(QOpenGL2PaintEngineEx *q_ptr) :
+ q(q_ptr),
+ shaderManager(0),
+ width(0), height(0),
+ ctx(0),
+ useSystemClip(true),
+ elementIndicesVBOId(0),
+ opacityArray(0),
+ snapToPixelGrid(false),
+ nativePaintingActive(false),
+ inverseScale(1),
+ lastMaskTextureUsed(0)
+ { }
+
+ ~QOpenGL2PaintEngineExPrivate();
+
+ void updateBrushTexture();
+ void updateBrushUniforms();
+ void updateMatrix();
+ void updateCompositionMode();
+ void updateTextureFilter(GLenum target, GLenum wrapMode, bool smoothPixmapTransform, GLuint id = -1);
+
+ void resetGLState();
+
+ // fill, stroke, drawTexture, drawPixmaps & drawCachedGlyphs are the main rendering entry-points,
+ // however writeClip can also be thought of as en entry point as it does similar things.
+ void fill(const QVectorPath &path);
+ void stroke(const QVectorPath &path, const QPen &pen);
+ void drawTexture(const QOpenGLRect& dest, const QOpenGLRect& src, const QSize &textureSize, bool opaque, bool pattern = false);
+ void drawPixmapFragments(const QPainter::PixmapFragment *fragments, int fragmentCount, const QPixmap &pixmap,
+ QPainter::PixmapFragmentHints hints);
+ void drawCachedGlyphs(QFontEngineGlyphCache::Type glyphType, QStaticTextItem *staticTextItem);
+
+ // Calls glVertexAttributePointer if the pointer has changed
+ inline void setVertexAttributePointer(unsigned int arrayIndex, const GLfloat *pointer);
+
+ // draws whatever is in the vertex array:
+ void drawVertexArrays(const float *data, int *stops, int stopCount, GLenum primitive);
+ void drawVertexArrays(QOpenGL2PEXVertexArray &vertexArray, GLenum primitive) {
+ drawVertexArrays((const float *) vertexArray.data(), vertexArray.stops(), vertexArray.stopCount(), primitive);
+ }
+
+ // Composites the bounding rect onto dest buffer:
+ void composite(const QOpenGLRect& boundingRect);
+
+ // Calls drawVertexArrays to render into stencil buffer:
+ void fillStencilWithVertexArray(const float *data, int count, int *stops, int stopCount, const QOpenGLRect &bounds, StencilFillMode mode);
+ void fillStencilWithVertexArray(QOpenGL2PEXVertexArray& vertexArray, bool useWindingFill) {
+ fillStencilWithVertexArray((const float *) vertexArray.data(), 0, vertexArray.stops(), vertexArray.stopCount(),
+ vertexArray.boundingRect(),
+ useWindingFill ? WindingFillMode : OddEvenFillMode);
+ }
+
+ void setBrush(const QBrush& brush);
+ void transferMode(EngineMode newMode);
+ bool prepareForDraw(bool srcPixelsAreOpaque); // returns true if the program has changed
+ inline void useSimpleShader();
+ inline GLuint location(const QOpenGLEngineShaderManager::Uniform uniform) {
+ return shaderManager->getUniformLocation(uniform);
+ }
+
+ void clearClip(uint value);
+ void writeClip(const QVectorPath &path, uint value);
+ void resetClipIfNeeded();
+
+ void updateClipScissorTest();
+ void setScissor(const QRect &rect);
+ void regenerateClip();
+ void systemStateChanged();
+
+ void setVertexAttribArrayEnabled(int arrayIndex, bool enabled = true);
+ void syncGlState();
+
+ static QOpenGLEngineShaderManager* shaderManagerForEngine(QOpenGL2PaintEngineEx *engine) { return engine->d_func()->shaderManager; }
+ static QOpenGL2PaintEngineExPrivate *getData(QOpenGL2PaintEngineEx *engine) { return engine->d_func(); }
+ static void cleanupVectorPath(QPaintEngineEx *engine, void *data);
+
+ QOpenGLExtensions funcs;
+
+ QOpenGL2PaintEngineEx* q;
+ QOpenGLEngineShaderManager* shaderManager;
+ QOpenGLPaintDevice* device;
+ int width, height;
+ QOpenGLContext *ctx;
+ EngineMode mode;
+ QFontEngineGlyphCache::Type glyphCacheType;
+
+ bool vertexAttributeArraysEnabledState[QT_GL_VERTEX_ARRAY_TRACKED_COUNT];
+
+ // Dirty flags
+ bool matrixDirty; // Implies matrix uniforms are also dirty
+ bool compositionModeDirty;
+ bool brushTextureDirty;
+ bool brushUniformsDirty;
+ bool opacityUniformDirty;
+ bool matrixUniformDirty;
+
+ bool stencilClean; // Has the stencil not been used for clipping so far?
+ bool useSystemClip;
+ QRegion dirtyStencilRegion;
+ QRect currentScissorBounds;
+ uint maxClip;
+
+ QBrush currentBrush; // May not be the state's brush!
+ const QBrush noBrush;
+
+ QPixmap currentBrushPixmap;
+
+ QOpenGL2PEXVertexArray vertexCoordinateArray;
+ QOpenGL2PEXVertexArray textureCoordinateArray;
+ QVector<GLushort> elementIndices;
+ GLuint elementIndicesVBOId;
+ QDataBuffer<GLfloat> opacityArray;
+ GLfloat staticVertexCoordinateArray[8];
+ GLfloat staticTextureCoordinateArray[8];
+
+ bool snapToPixelGrid;
+ bool nativePaintingActive;
+ GLfloat pmvMatrix[3][3];
+ GLfloat inverseScale;
+
+ GLuint lastTextureUsed;
+ GLuint lastMaskTextureUsed;
+
+ bool needsSync;
+ bool multisamplingAlwaysEnabled;
+
+ GLfloat depthRange[2];
+
+ float textureInvertedY;
+
+ QTriangulatingStroker stroker;
+ QDashedStrokeProcessor dasher;
+
+ QSet<QVectorPath::CacheEntry *> pathCaches;
+ QVector<GLuint> unusedVBOSToClean;
+ QVector<GLuint> unusedIBOSToClean;
+
+ const GLfloat *vertexAttribPointers[3];
+};
+
+
+void QOpenGL2PaintEngineExPrivate::setVertexAttributePointer(unsigned int arrayIndex, const GLfloat *pointer)
+{
+ Q_ASSERT(arrayIndex < 3);
+ if (pointer == vertexAttribPointers[arrayIndex])
+ return;
+
+ vertexAttribPointers[arrayIndex] = pointer;
+ if (arrayIndex == QT_OPACITY_ATTR)
+ funcs.glVertexAttribPointer(arrayIndex, 1, GL_FLOAT, GL_FALSE, 0, pointer);
+ else
+ funcs.glVertexAttribPointer(arrayIndex, 2, GL_FLOAT, GL_FALSE, 0, pointer);
+}
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/gui/opengl/qopenglshadercache_meego_p.h b/src/gui/opengl/qopenglshadercache_meego_p.h
new file mode 100644
index 0000000000..86a8a861da
--- /dev/null
+++ b/src/gui/opengl/qopenglshadercache_meego_p.h
@@ -0,0 +1,457 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QOPENGLSHADERCACHE_MEEGO_P_H
+#define QOPENGLSHADERCACHE_MEEGO_P_H
+
+#include <QtCore/qopenglobal.h>
+
+#if defined(QT_MEEGO_EXPERIMENTAL_SHADERCACHE) && defined(QT_OPENGL_ES_2)
+
+#include <QtCore/qcryptographichash.h>
+#include <QtCore/qsharedmemory.h>
+#include <QtCore/qsystemsemaphore.h>
+
+#ifndef QT_BOOTSTRAPPED
+# include <GLES2/gl2ext.h>
+#endif
+#if defined(QT_DEBUG) || defined(QT_MEEGO_EXPERIMENTAL_SHADERCACHE_TRACE)
+# include <syslog.h>
+#endif
+
+QT_BEGIN_HEADER
+
+/*
+ This cache stores internal Qt shader programs in shared memory.
+
+ This header file is ugly on purpose and can only be included once. It is only to be used
+ for the internal shader cache, not as a generic cache for anyone's shaders.
+
+ The cache stores either ShaderCacheMaxEntries shader programs or ShaderCacheDataSize kilobytes
+ of shader programs, whatever limit is reached first.
+
+ The layout of the cache is as outlined in the CachedShaders struct. After some
+ integers, an array of headers is reserved, then comes the space for the actual binaries.
+
+ Shader Programs are identified by the md5sum of their frag and vertex shader source code.
+
+ Shader Programs are never removed. The cache never shrinks or re-shuffles. This is done
+ on purpose to ensure minimum amount of locking, no alignment problems and very few write
+ operations.
+
+ Note: Locking the shader cache could be expensive, because the entire system might hang.
+ That's why the cache is immutable to minimize the time we need to keep it locked.
+
+ Why is it Meego specific?
+
+ First, the size is chosen so that it fits to generic meego usage. Second, on Meego, there's
+ always at least one Qt application active (the launcher), so the cache will never be destroyed.
+ Only when the last Qt app exits, the cache dies, which should only be when someone kills the
+ X11 server. And last but not least it was only tested with Meego's SGX driver.
+
+ There's a small tool in src/opengl/util/meego that dumps the contents of the cache.
+ */
+
+// anonymous namespace, prevent exporting of the private symbols
+namespace
+{
+
+struct CachedShaderHeader
+{
+ /* the index in the data[] member of CachedShaders */
+ int index;
+ /* the size of the binary shader */
+ GLsizei size;
+ /* the format of the binary shader */
+ GLenum format;
+ /* the md5sum of the frag+vertex shaders */
+ char md5Sum[16];
+};
+
+enum
+{
+ /* The maximum amount of shader programs the cache can hold */
+ ShaderCacheMaxEntries = 20
+};
+
+typedef CachedShaderHeader CachedShaderHeaders[ShaderCacheMaxEntries];
+
+enum
+{
+ // ShaderCacheDataSize is 20k minus the other data members of CachedShaders
+ ShaderCacheDataSize = 1024 * ShaderCacheMaxEntries - sizeof(CachedShaderHeaders) - 2 * sizeof(int)
+};
+
+struct CachedShaders
+{
+ /* How much space is still available in the cache */
+ inline int availableSize() const { return ShaderCacheDataSize - dataSize; }
+
+ /* The current amount of cached shaders */
+ int shaderCount;
+
+ /* The current amount (in bytes) of cached data */
+ int dataSize;
+
+ /* The headers describing the shaders */
+ CachedShaderHeaders headers;
+
+ /* The actual binary data of the shader programs */
+ char data[ShaderCacheDataSize];
+};
+
+//#define QT_DEBUG_SHADER_CACHE
+#ifdef QT_DEBUG_SHADER_CACHE
+static QDebug shaderCacheDebug()
+{
+ return QDebug(QtDebugMsg);
+}
+#else
+static inline QNoDebug shaderCacheDebug() { return QNoDebug(); }
+#endif
+
+class ShaderCacheSharedMemory
+{
+public:
+ ShaderCacheSharedMemory()
+ : shm(QLatin1String("qt_gles2_shadercache_" QT_VERSION_STR))
+ {
+ // we need a system semaphore here, since cache creation and initialization must be atomic
+ QSystemSemaphore attachSemaphore(QLatin1String("qt_gles2_shadercache_mutex_" QT_VERSION_STR), 1);
+
+ if (!attachSemaphore.acquire()) {
+ shaderCacheDebug() << "Unable to require shader cache semaphore:" << attachSemaphore.errorString();
+ return;
+ }
+
+ if (shm.attach()) {
+ // success!
+ shaderCacheDebug() << "Attached to shader cache";
+ } else {
+
+ // no cache exists - create and initialize it
+ if (shm.create(sizeof(CachedShaders))) {
+ shaderCacheDebug() << "Created new shader cache";
+ initializeCache();
+ } else {
+ shaderCacheDebug() << "Unable to create shader cache:" << shm.errorString();
+ }
+ }
+
+ attachSemaphore.release();
+ }
+
+ inline bool isAttached() const { return shm.isAttached(); }
+
+ inline bool lock() { return shm.lock(); }
+ inline bool unlock() { return shm.unlock(); }
+ inline void *data() { return shm.data(); }
+ inline QString errorString() { return shm.errorString(); }
+
+ ~ShaderCacheSharedMemory()
+ {
+ if (!shm.detach())
+ shaderCacheDebug() << "Unable to detach shader cache" << shm.errorString();
+ }
+
+private:
+ void initializeCache()
+ {
+ // no need to lock the shared memory since we're already protected by the
+ // attach system semaphore.
+
+ void *data = shm.data();
+ Q_ASSERT(data);
+
+ memset(data, 0, sizeof(CachedShaders));
+ }
+
+ QSharedMemory shm;
+};
+
+class ShaderCacheLocker
+{
+public:
+ inline ShaderCacheLocker(ShaderCacheSharedMemory *cache)
+ : shm(cache->lock() ? cache : (ShaderCacheSharedMemory *)0)
+ {
+ if (!shm)
+ shaderCacheDebug() << "Unable to lock shader cache" << cache->errorString();
+ }
+
+ inline bool isLocked() const { return shm; }
+
+ inline ~ShaderCacheLocker()
+ {
+ if (!shm)
+ return;
+ if (!shm->unlock())
+ shaderCacheDebug() << "Unable to unlock shader cache" << shm->errorString();
+ }
+
+private:
+ ShaderCacheSharedMemory *shm;
+};
+
+#ifdef QT_BOOTSTRAPPED
+} // end namespace
+#else
+
+static void traceCacheOverflow(const char *message)
+{
+#if defined(QT_DEBUG) || defined (QT_MEEGO_EXPERIMENTAL_SHADERCACHE_TRACE)
+ openlog(qPrintable(QCoreApplication::applicationName()), LOG_PID | LOG_ODELAY, LOG_USER);
+ syslog(LOG_DEBUG, message);
+ closelog();
+#endif
+ shaderCacheDebug() << message;
+}
+
+Q_GLOBAL_STATIC(ShaderCacheSharedMemory, shaderCacheSharedMemory)
+
+/*
+ Finds the index of the shader program identified by md5Sum in the cache.
+ Note: Does NOT lock the cache for reading, the cache must already be locked!
+
+ Returns -1 when no shader was found.
+ */
+static int qt_cache_index_unlocked(const QByteArray &md5Sum, CachedShaders *cache)
+{
+ for (int i = 0; i < cache->shaderCount; ++i) {
+ if (qstrncmp(md5Sum.constData(), cache->headers[i].md5Sum, 16) == 0) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+/* Returns the index of the shader identified by md5Sum */
+static int qt_cache_index(const QByteArray &md5Sum)
+{
+ ShaderCacheSharedMemory *shm = shaderCacheSharedMemory();
+ if (!shm || !shm->isAttached())
+ return false;
+
+ Q_ASSERT(md5Sum.length() == 16);
+
+ ShaderCacheLocker locker(shm);
+ if (!locker.isLocked())
+ return false;
+
+ void *data = shm->data();
+ Q_ASSERT(data);
+
+ CachedShaders *cache = reinterpret_cast<CachedShaders *>(data);
+
+ return qt_cache_index_unlocked(md5Sum, cache);
+}
+
+/* Loads the cached shader at index \a shaderIndex into \a program
+ * Note: Since the cache is immutable, this operation doesn't lock the shared memory.
+ */
+static bool qt_cached_shader(QOpenGLShaderProgram *program, QOpenGLContext *ctx, int shaderIndex)
+{
+ Q_ASSERT(shaderIndex >= 0 && shaderIndex <= ShaderCacheMaxEntries);
+ Q_ASSERT(program);
+
+ ShaderCacheSharedMemory *shm = shaderCacheSharedMemory();
+ if (!shm || !shm->isAttached())
+ return false;
+
+ void *data = shm->data();
+ Q_ASSERT(data);
+
+ CachedShaders *cache = reinterpret_cast<CachedShaders *>(data);
+
+ shaderCacheDebug() << "fetching cached shader at index" << shaderIndex
+ << "dataIndex" << cache->headers[shaderIndex].index
+ << "size" << cache->headers[shaderIndex].size
+ << "format" << cache->headers[shaderIndex].format;
+
+ // call program->programId first, since that resolves the glProgramBinaryOES symbol
+ GLuint programId = program->programId();
+ glProgramBinaryOES(programId, cache->headers[shaderIndex].format,
+ cache->data + cache->headers[shaderIndex].index,
+ cache->headers[shaderIndex].size);
+
+ return true;
+}
+
+/* Stores the shader program in the cache. Returns false if there's an error with the cache, or
+ if the cache is too small to hold the shader. */
+static bool qt_cache_shader(const QOpenGLShaderProgram *shader, QOpenGLContext *ctx, const QByteArray &md5Sum)
+{
+ ShaderCacheSharedMemory *shm = shaderCacheSharedMemory();
+ if (!shm || !shm->isAttached())
+ return false;
+
+ void *data = shm->data();
+ Q_ASSERT(data);
+
+ CachedShaders *cache = reinterpret_cast<CachedShaders *>(data);
+
+ ShaderCacheLocker locker(shm);
+ if (!locker.isLocked())
+ return false;
+
+ int cacheIdx = cache->shaderCount;
+ if (cacheIdx >= ShaderCacheMaxEntries) {
+ traceCacheOverflow("Qt OpenGL shader cache index overflow!");
+ return false;
+ }
+
+ // now that we have the lock on the shared memory, make sure no one
+ // inserted the shader already while we were unlocked
+ if (qt_cache_index_unlocked(md5Sum, cache) != -1)
+ return true; // already cached
+
+ shaderCacheDebug() << "Caching shader at index" << cacheIdx;
+
+ GLint binaryLength = 0;
+ glGetProgramiv(shader->programId(), GL_PROGRAM_BINARY_LENGTH_OES, &binaryLength);
+
+ if (!binaryLength) {
+ shaderCacheDebug() << "Unable to determine binary shader size!";
+ return false;
+ }
+
+ if (binaryLength > cache->availableSize()) {
+ traceCacheOverflow("Qt OpenGL shader cache data overflow!");
+ return false;
+ }
+
+ GLsizei size = 0;
+ GLenum format = 0;
+ glGetProgramBinaryOES(shader->programId(), binaryLength, &size, &format,
+ cache->data + cache->dataSize);
+
+ if (!size) {
+ shaderCacheDebug() << "Unable to get binary shader!";
+ return false;
+ }
+
+ cache->headers[cacheIdx].index = cache->dataSize;
+ cache->dataSize += binaryLength;
+ ++cache->shaderCount;
+ cache->headers[cacheIdx].size = binaryLength;
+ cache->headers[cacheIdx].format = format;
+
+ memcpy(cache->headers[cacheIdx].md5Sum, md5Sum.constData(), 16);
+
+ shaderCacheDebug() << "cached shader size" << size
+ << "format" << format
+ << "binarySize" << binaryLength
+ << "cache index" << cacheIdx
+ << "data index" << cache->headers[cacheIdx].index;
+
+ return true;
+}
+
+} // namespace
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class CachedShader
+{
+public:
+ CachedShader(const QByteArray &fragSource, const QByteArray &vertexSource)
+ : cacheIdx(-1)
+ {
+ QCryptographicHash md5Hash(QCryptographicHash::Md5);
+
+ md5Hash.addData(fragSource);
+ md5Hash.addData(vertexSource);
+
+ md5Sum = md5Hash.result();
+ }
+
+ bool isCached()
+ {
+ return cacheIndex() != -1;
+ }
+
+ int cacheIndex()
+ {
+ if (cacheIdx != -1)
+ return cacheIdx;
+ cacheIdx = qt_cache_index(md5Sum);
+ return cacheIdx;
+ }
+
+ bool load(QOpenGLShaderProgram *program, QOpenGLContext *ctx)
+ {
+ if (cacheIndex() == -1)
+ return false;
+ return qt_cached_shader(program, ctx, cacheIdx);
+ }
+
+ bool store(QOpenGLShaderProgram *program, QOpenGLContext *ctx)
+ {
+ return qt_cache_shader(program, ctx, md5Sum);
+ }
+
+private:
+ QByteArray md5Sum;
+ int cacheIdx;
+};
+
+
+QT_END_NAMESPACE
+
+#endif
+
+QT_END_HEADER
+
+#endif
+#endif
diff --git a/src/gui/opengl/qopenglshadercache_p.h b/src/gui/opengl/qopenglshadercache_p.h
new file mode 100644
index 0000000000..05a058050c
--- /dev/null
+++ b/src/gui/opengl/qopenglshadercache_p.h
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QOPENGLSHADERCACHE_P_H
+#define QOPENGLSHADERCACHE_P_H
+
+#include <QtCore/qglobal.h>
+
+#if defined(QT_MEEGO_EXPERIMENTAL_SHADERCACHE) && defined(QT_OPENGL_ES_2)
+# include "qopenglshadercache_meego_p.h"
+#else
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QOpenGLShaderProgram;
+class QOpenGLContext;
+
+class CachedShader
+{
+public:
+ inline CachedShader(const QByteArray &, const QByteArray &)
+ {}
+
+ inline bool isCached()
+ {
+ return false;
+ }
+
+ inline bool load(QOpenGLShaderProgram *, QOpenGLContext *)
+ {
+ return false;
+ }
+
+ inline bool store(QOpenGLShaderProgram *, QOpenGLContext *)
+ {
+ return false;
+ }
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
+#endif
diff --git a/src/gui/opengl/qopenglshaderprogram.cpp b/src/gui/opengl/qopenglshaderprogram.cpp
new file mode 100644
index 0000000000..aa7767a7eb
--- /dev/null
+++ b/src/gui/opengl/qopenglshaderprogram.cpp
@@ -0,0 +1,3105 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qopenglshaderprogram.h"
+#include "qopenglfunctions.h"
+#include "private/qopenglcontext_p.h"
+#include <QtCore/private/qobject_p.h>
+#include <QtCore/qdebug.h>
+#include <QtCore/qfile.h>
+#include <QtCore/qvarlengtharray.h>
+#include <QtCore/qvector.h>
+#include <QtGui/qtransform.h>
+#include <QtGui/QColor>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QOpenGLShaderProgram
+ \brief The QOpenGLShaderProgram class allows OpenGL shader programs to be linked and used.
+ \since 5.0
+ \ingroup painting-3D
+
+ \section1 Introduction
+
+ This class supports shader programs written in the OpenGL Shading
+ Language (GLSL) and in the OpenGL/ES Shading Language (GLSL/ES).
+
+ QOpenGLShader and QOpenGLShaderProgram shelter the programmer from the details of
+ compiling and linking vertex and fragment shaders.
+
+ The following example creates a vertex shader program using the
+ supplied source \c{code}. Once compiled and linked, the shader
+ program is activated in the current QOpenGLContext by calling
+ QOpenGLShaderProgram::bind():
+
+ \snippet doc/src/snippets/code/src_opengl_qopenglshaderprogram.cpp 0
+
+ \section1 Writing portable shaders
+
+ Shader programs can be difficult to reuse across OpenGL implementations
+ because of varying levels of support for standard vertex attributes and
+ uniform variables. In particular, GLSL/ES lacks all of the
+ standard variables that are present on desktop OpenGL systems:
+ \c{gl_Vertex}, \c{gl_Normal}, \c{gl_Color}, and so on. Desktop OpenGL
+ lacks the variable qualifiers \c{highp}, \c{mediump}, and \c{lowp}.
+
+ The QOpenGLShaderProgram class makes the process of writing portable shaders
+ easier by prefixing all shader programs with the following lines on
+ desktop OpenGL:
+
+ \code
+ #define highp
+ #define mediump
+ #define lowp
+ \endcode
+
+ This makes it possible to run most GLSL/ES shader programs
+ on desktop systems. The programmer should restrict themselves
+ to just features that are present in GLSL/ES, and avoid
+ standard variable names that only work on the desktop.
+
+ \section1 Simple shader example
+
+ \snippet doc/src/snippets/code/src_opengl_qopenglshaderprogram.cpp 1
+
+ With the above shader program active, we can draw a green triangle
+ as follows:
+
+ \snippet doc/src/snippets/code/src_opengl_qopenglshaderprogram.cpp 2
+
+ \section1 Binary shaders and programs
+
+ Binary shaders may be specified using \c{glShaderBinary()} on
+ the return value from QOpenGLShader::shaderId(). The QOpenGLShader instance
+ containing the binary can then be added to the shader program with
+ addShader() and linked in the usual fashion with link().
+
+ Binary programs may be specified using \c{glProgramBinaryOES()}
+ on the return value from programId(). Then the application should
+ call link(), which will notice that the program has already been
+ specified and linked, allowing other operations to be performed
+ on the shader program.
+
+ \sa QOpenGLShader
+*/
+
+/*!
+ \class QOpenGLShader
+ \brief The QOpenGLShader class allows OpenGL shaders to be compiled.
+ \since 5.0
+ \ingroup painting-3D
+
+ This class supports shaders written in the OpenGL Shading Language (GLSL)
+ and in the OpenGL/ES Shading Language (GLSL/ES).
+
+ QOpenGLShader and QOpenGLShaderProgram shelter the programmer from the details of
+ compiling and linking vertex and fragment shaders.
+
+ \sa QOpenGLShaderProgram
+*/
+
+/*!
+ \enum QOpenGLShader::ShaderTypeBit
+ This enum specifies the type of QOpenGLShader that is being created.
+
+ \value Vertex Vertex shader written in the OpenGL Shading Language (GLSL).
+ \value Fragment Fragment shader written in the OpenGL Shading Language (GLSL).
+ \value Geometry Geometry shaders written in the OpenGL Shading
+ Language (GLSL), based on the GL_EXT_geometry_shader4 extension.
+*/
+
+class QOpenGLShaderPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QOpenGLShader)
+public:
+ QOpenGLShaderPrivate(QOpenGLContext *ctx, QOpenGLShader::ShaderType type)
+ : shaderGuard(0)
+ , shaderType(type)
+ , compiled(false)
+ , glfuncs(new QOpenGLFunctions(ctx))
+ {
+ }
+ ~QOpenGLShaderPrivate();
+
+ QOpenGLSharedResourceGuard *shaderGuard;
+ QOpenGLShader::ShaderType shaderType;
+ bool compiled;
+ QString log;
+
+ QOpenGLFunctions *glfuncs;
+
+ bool create();
+ bool compile(QOpenGLShader *q);
+ void deleteShader();
+};
+
+namespace {
+ void freeShaderFunc(QOpenGLFunctions *funcs, GLuint id)
+ {
+ funcs->glDeleteShader(id);
+ }
+}
+
+QOpenGLShaderPrivate::~QOpenGLShaderPrivate()
+{
+ delete glfuncs;
+ if (shaderGuard)
+ shaderGuard->free();
+}
+
+bool QOpenGLShaderPrivate::create()
+{
+ QOpenGLContext *context = const_cast<QOpenGLContext *>(QOpenGLContext::currentContext());
+ if (!context)
+ return false;
+ GLuint shader;
+ if (shaderType == QOpenGLShader::Vertex)
+ shader = glfuncs->glCreateShader(GL_VERTEX_SHADER);
+#if 0
+ else if (shaderType == QOpenGLShader::Geometry)
+ shader = glfuncs->glCreateShader(GL_GEOMETRY_SHADER_EXT);
+#endif
+ else
+ shader = glfuncs->glCreateShader(GL_FRAGMENT_SHADER);
+ if (!shader) {
+ qWarning() << "QOpenGLShader: could not create shader";
+ return false;
+ }
+ shaderGuard = new QOpenGLSharedResourceGuard(context, shader, freeShaderFunc);
+ return true;
+}
+
+bool QOpenGLShaderPrivate::compile(QOpenGLShader *q)
+{
+ GLuint shader = shaderGuard ? shaderGuard->id() : 0;
+ if (!shader)
+ return false;
+ glfuncs->glCompileShader(shader);
+ GLint value = 0;
+ glfuncs->glGetShaderiv(shader, GL_COMPILE_STATUS, &value);
+ compiled = (value != 0);
+ value = 0;
+ glfuncs->glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &value);
+ if (!compiled && value > 1) {
+ char *logbuf = new char [value];
+ GLint len;
+ glfuncs->glGetShaderInfoLog(shader, value, &len, logbuf);
+ log = QString::fromLatin1(logbuf);
+ QString name = q->objectName();
+
+ const char *types[] = {
+ "Fragment",
+ "Vertex",
+ "Geometry",
+ ""
+ };
+
+ const char *type = types[3];
+ if (shaderType == QOpenGLShader::Fragment)
+ type = types[0];
+ else if (shaderType == QOpenGLShader::Vertex)
+ type = types[1];
+ else if (shaderType == QOpenGLShader::Geometry)
+ type = types[2];
+
+ if (name.isEmpty())
+ qWarning("QOpenGLShader::compile(%s): %s", type, qPrintable(log));
+ else
+ qWarning("QOpenGLShader::compile(%s)[%s]: %s", type, qPrintable(name), qPrintable(log));
+
+ delete [] logbuf;
+ }
+ return compiled;
+}
+
+void QOpenGLShaderPrivate::deleteShader()
+{
+ if (shaderGuard) {
+ shaderGuard->free();
+ shaderGuard = 0;
+ }
+}
+
+/*!
+ Constructs a new QOpenGLShader object of the specified \a type
+ and attaches it to \a parent. If shader programs are not supported,
+ QOpenGLShaderProgram::hasOpenGLShaderPrograms() will return false.
+
+ This constructor is normally followed by a call to compileSourceCode()
+ or compileSourceFile().
+
+ The shader will be associated with the current QOpenGLContext.
+
+ \sa compileSourceCode(), compileSourceFile()
+*/
+QOpenGLShader::QOpenGLShader(QOpenGLShader::ShaderType type, QObject *parent)
+ : QObject(*new QOpenGLShaderPrivate(QOpenGLContext::currentContext(), type), parent)
+{
+ Q_D(QOpenGLShader);
+ d->create();
+}
+
+/*!
+ Deletes this shader. If the shader has been attached to a
+ QOpenGLShaderProgram object, then the actual shader will stay around
+ until the QOpenGLShaderProgram is destroyed.
+*/
+QOpenGLShader::~QOpenGLShader()
+{
+}
+
+/*!
+ Returns the type of this shader.
+*/
+QOpenGLShader::ShaderType QOpenGLShader::shaderType() const
+{
+ Q_D(const QOpenGLShader);
+ return d->shaderType;
+}
+
+// The precision qualifiers are useful on OpenGL/ES systems,
+// but usually not present on desktop systems. Define the
+// keywords to empty strings on desktop systems.
+#if !defined(QT_OPENGL_ES) || defined(QT_OPENGL_FORCE_SHADER_DEFINES)
+#define QOpenGL_DEFINE_QUALIFIERS 1
+static const char qualifierDefines[] =
+ "#define lowp\n"
+ "#define mediump\n"
+ "#define highp\n";
+
+#else
+
+// The "highp" qualifier doesn't exist in fragment shaders
+// on all ES platforms. When it doesn't exist, use "mediump".
+#define QOpenGL_REDEFINE_HIGHP 1
+static const char redefineHighp[] =
+ "#ifndef GL_FRAGMENT_PRECISION_HIGH\n"
+ "#define highp mediump\n"
+ "#endif\n";
+#endif
+
+/*!
+ Sets the \a source code for this shader and compiles it.
+ Returns true if the source was successfully compiled, false otherwise.
+
+ \sa compileSourceFile()
+*/
+bool QOpenGLShader::compileSourceCode(const char *source)
+{
+ Q_D(QOpenGLShader);
+ if (d->shaderGuard && d->shaderGuard->id()) {
+ QVarLengthArray<const char *, 4> src;
+ QVarLengthArray<GLint, 4> srclen;
+ int headerLen = 0;
+ while (source && source[headerLen] == '#') {
+ // Skip #version and #extension directives at the start of
+ // the shader code. We need to insert the qualifierDefines
+ // and redefineHighp just after them.
+ if (qstrncmp(source + headerLen, "#version", 8) != 0 &&
+ qstrncmp(source + headerLen, "#extension", 10) != 0) {
+ break;
+ }
+ while (source[headerLen] != '\0' && source[headerLen] != '\n')
+ ++headerLen;
+ if (source[headerLen] == '\n')
+ ++headerLen;
+ }
+ if (headerLen > 0) {
+ src.append(source);
+ srclen.append(GLint(headerLen));
+ }
+#ifdef QOpenGL_DEFINE_QUALIFIERS
+ src.append(qualifierDefines);
+ srclen.append(GLint(sizeof(qualifierDefines) - 1));
+#endif
+#ifdef QOpenGL_REDEFINE_HIGHP
+ if (d->shaderType == Fragment) {
+ src.append(redefineHighp);
+ srclen.append(GLint(sizeof(redefineHighp) - 1));
+ }
+#endif
+ src.append(source + headerLen);
+ srclen.append(GLint(qstrlen(source + headerLen)));
+ d->glfuncs->glShaderSource(d->shaderGuard->id(), src.size(), src.data(), srclen.data());
+ return d->compile(this);
+ } else {
+ return false;
+ }
+}
+
+/*!
+ \overload
+
+ Sets the \a source code for this shader and compiles it.
+ Returns true if the source was successfully compiled, false otherwise.
+
+ \sa compileSourceFile()
+*/
+bool QOpenGLShader::compileSourceCode(const QByteArray& source)
+{
+ return compileSourceCode(source.constData());
+}
+
+/*!
+ \overload
+
+ Sets the \a source code for this shader and compiles it.
+ Returns true if the source was successfully compiled, false otherwise.
+
+ \sa compileSourceFile()
+*/
+bool QOpenGLShader::compileSourceCode(const QString& source)
+{
+ return compileSourceCode(source.toLatin1().constData());
+}
+
+/*!
+ Sets the source code for this shader to the contents of \a fileName
+ and compiles it. Returns true if the file could be opened and the
+ source compiled, false otherwise.
+
+ \sa compileSourceCode()
+*/
+bool QOpenGLShader::compileSourceFile(const QString& fileName)
+{
+ QFile file(fileName);
+ if (!file.open(QFile::ReadOnly)) {
+ qWarning() << "QOpenGLShader: Unable to open file" << fileName;
+ return false;
+ }
+
+ QByteArray contents = file.readAll();
+ return compileSourceCode(contents.constData());
+}
+
+/*!
+ Returns the source code for this shader.
+
+ \sa compileSourceCode()
+*/
+QByteArray QOpenGLShader::sourceCode() const
+{
+ Q_D(const QOpenGLShader);
+ GLuint shader = d->shaderGuard ? d->shaderGuard->id() : 0;
+ if (!shader)
+ return QByteArray();
+ GLint size = 0;
+ d->glfuncs->glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &size);
+ if (size <= 0)
+ return QByteArray();
+ GLint len = 0;
+ char *source = new char [size];
+ d->glfuncs->glGetShaderSource(shader, size, &len, source);
+ QByteArray src(source);
+ delete [] source;
+ return src;
+}
+
+/*!
+ Returns true if this shader has been compiled; false otherwise.
+
+ \sa compileSourceCode(), compileSourceFile()
+*/
+bool QOpenGLShader::isCompiled() const
+{
+ Q_D(const QOpenGLShader);
+ return d->compiled;
+}
+
+/*!
+ Returns the errors and warnings that occurred during the last compile.
+
+ \sa compileSourceCode(), compileSourceFile()
+*/
+QString QOpenGLShader::log() const
+{
+ Q_D(const QOpenGLShader);
+ return d->log;
+}
+
+/*!
+ Returns the OpenGL identifier associated with this shader.
+
+ \sa QOpenGLShaderProgram::programId()
+*/
+GLuint QOpenGLShader::shaderId() const
+{
+ Q_D(const QOpenGLShader);
+ return d->shaderGuard ? d->shaderGuard->id() : 0;
+}
+
+class QOpenGLShaderProgramPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QOpenGLShaderProgram)
+public:
+ QOpenGLShaderProgramPrivate(QOpenGLContext *ctx)
+ : programGuard(0)
+ , linked(false)
+ , inited(false)
+ , removingShaders(false)
+ , geometryVertexCount(64)
+ , geometryInputType(0)
+ , geometryOutputType(0)
+ , glfuncs(new QOpenGLFunctions(ctx))
+ {
+ }
+ ~QOpenGLShaderProgramPrivate();
+
+ QOpenGLSharedResourceGuard *programGuard;
+ bool linked;
+ bool inited;
+ bool removingShaders;
+
+ int geometryVertexCount;
+ GLenum geometryInputType;
+ GLenum geometryOutputType;
+
+ QString log;
+ QList<QOpenGLShader *> shaders;
+ QList<QOpenGLShader *> anonShaders;
+
+ QOpenGLFunctions *glfuncs;
+
+ bool hasShader(QOpenGLShader::ShaderType type) const;
+};
+
+namespace {
+ void freeProgramFunc(QOpenGLFunctions *funcs, GLuint id)
+ {
+ funcs->glDeleteProgram(id);
+ }
+}
+
+
+QOpenGLShaderProgramPrivate::~QOpenGLShaderProgramPrivate()
+{
+ delete glfuncs;
+ if (programGuard)
+ programGuard->free();
+}
+
+bool QOpenGLShaderProgramPrivate::hasShader(QOpenGLShader::ShaderType type) const
+{
+ foreach (QOpenGLShader *shader, shaders) {
+ if (shader->shaderType() == type)
+ return true;
+ }
+ return false;
+}
+
+/*!
+ Constructs a new shader program and attaches it to \a parent.
+ The program will be invalid until addShader() is called.
+
+ The shader program will be associated with the current QOpenGLContext.
+
+ \sa addShader()
+*/
+QOpenGLShaderProgram::QOpenGLShaderProgram(QObject *parent)
+ : QObject(*new QOpenGLShaderProgramPrivate(QOpenGLContext::currentContext()), parent)
+{
+}
+
+/*!
+ Deletes this shader program.
+*/
+QOpenGLShaderProgram::~QOpenGLShaderProgram()
+{
+}
+
+bool QOpenGLShaderProgram::init()
+{
+ Q_D(QOpenGLShaderProgram);
+ if ((d->programGuard && d->programGuard->id()) || d->inited)
+ return true;
+ d->inited = true;
+ QOpenGLContext *context = const_cast<QOpenGLContext *>(QOpenGLContext::currentContext());
+ if (!context)
+ return false;
+ GLuint program = d->glfuncs->glCreateProgram();
+ if (!program) {
+ qWarning() << "QOpenGLShaderProgram: could not create shader program";
+ return false;
+ }
+ if (d->programGuard)
+ delete d->programGuard;
+ d->programGuard = new QOpenGLSharedResourceGuard(context, program, freeProgramFunc);
+ return true;
+}
+
+/*!
+ Adds a compiled \a shader to this shader program. Returns true
+ if the shader could be added, or false otherwise.
+
+ Ownership of the \a shader object remains with the caller.
+ It will not be deleted when this QOpenGLShaderProgram instance
+ is deleted. This allows the caller to add the same shader
+ to multiple shader programs.
+
+ \sa addShaderFromSourceCode(), addShaderFromSourceFile()
+ \sa removeShader(), link(), removeAllShaders()
+*/
+bool QOpenGLShaderProgram::addShader(QOpenGLShader *shader)
+{
+ Q_D(QOpenGLShaderProgram);
+ if (!init())
+ return false;
+ if (d->shaders.contains(shader))
+ return true; // Already added to this shader program.
+ if (d->programGuard && d->programGuard->id() && shader) {
+ if (!shader->d_func()->shaderGuard || !shader->d_func()->shaderGuard->id())
+ return false;
+ if (d->programGuard->group() != shader->d_func()->shaderGuard->group()) {
+ qWarning("QOpenGLShaderProgram::addShader: Program and shader are not associated with same context.");
+ return false;
+ }
+ d->glfuncs->glAttachShader(d->programGuard->id(), shader->d_func()->shaderGuard->id());
+ d->linked = false; // Program needs to be relinked.
+ d->shaders.append(shader);
+ connect(shader, SIGNAL(destroyed()), this, SLOT(shaderDestroyed()));
+ return true;
+ } else {
+ return false;
+ }
+}
+
+/*!
+ Compiles \a source as a shader of the specified \a type and
+ adds it to this shader program. Returns true if compilation
+ was successful, false otherwise. The compilation errors
+ and warnings will be made available via log().
+
+ This function is intended to be a short-cut for quickly
+ adding vertex and fragment shaders to a shader program without
+ creating an instance of QOpenGLShader first.
+
+ \sa addShader(), addShaderFromSourceFile()
+ \sa removeShader(), link(), log(), removeAllShaders()
+*/
+bool QOpenGLShaderProgram::addShaderFromSourceCode(QOpenGLShader::ShaderType type, const char *source)
+{
+ Q_D(QOpenGLShaderProgram);
+ if (!init())
+ return false;
+ QOpenGLShader *shader = new QOpenGLShader(type, this);
+ if (!shader->compileSourceCode(source)) {
+ d->log = shader->log();
+ delete shader;
+ return false;
+ }
+ d->anonShaders.append(shader);
+ return addShader(shader);
+}
+
+/*!
+ \overload
+
+ Compiles \a source as a shader of the specified \a type and
+ adds it to this shader program. Returns true if compilation
+ was successful, false otherwise. The compilation errors
+ and warnings will be made available via log().
+
+ This function is intended to be a short-cut for quickly
+ adding vertex and fragment shaders to a shader program without
+ creating an instance of QOpenGLShader first.
+
+ \sa addShader(), addShaderFromSourceFile()
+ \sa removeShader(), link(), log(), removeAllShaders()
+*/
+bool QOpenGLShaderProgram::addShaderFromSourceCode(QOpenGLShader::ShaderType type, const QByteArray& source)
+{
+ return addShaderFromSourceCode(type, source.constData());
+}
+
+/*!
+ \overload
+
+ Compiles \a source as a shader of the specified \a type and
+ adds it to this shader program. Returns true if compilation
+ was successful, false otherwise. The compilation errors
+ and warnings will be made available via log().
+
+ This function is intended to be a short-cut for quickly
+ adding vertex and fragment shaders to a shader program without
+ creating an instance of QOpenGLShader first.
+
+ \sa addShader(), addShaderFromSourceFile()
+ \sa removeShader(), link(), log(), removeAllShaders()
+*/
+bool QOpenGLShaderProgram::addShaderFromSourceCode(QOpenGLShader::ShaderType type, const QString& source)
+{
+ return addShaderFromSourceCode(type, source.toLatin1().constData());
+}
+
+/*!
+ Compiles the contents of \a fileName as a shader of the specified
+ \a type and adds it to this shader program. Returns true if
+ compilation was successful, false otherwise. The compilation errors
+ and warnings will be made available via log().
+
+ This function is intended to be a short-cut for quickly
+ adding vertex and fragment shaders to a shader program without
+ creating an instance of QOpenGLShader first.
+
+ \sa addShader(), addShaderFromSourceCode()
+*/
+bool QOpenGLShaderProgram::addShaderFromSourceFile
+ (QOpenGLShader::ShaderType type, const QString& fileName)
+{
+ Q_D(QOpenGLShaderProgram);
+ if (!init())
+ return false;
+ QOpenGLShader *shader = new QOpenGLShader(type, this);
+ if (!shader->compileSourceFile(fileName)) {
+ d->log = shader->log();
+ delete shader;
+ return false;
+ }
+ d->anonShaders.append(shader);
+ return addShader(shader);
+}
+
+/*!
+ Removes \a shader from this shader program. The object is not deleted.
+
+ The shader program must be valid in the current QOpenGLContext.
+
+ \sa addShader(), link(), removeAllShaders()
+*/
+void QOpenGLShaderProgram::removeShader(QOpenGLShader *shader)
+{
+ Q_D(QOpenGLShaderProgram);
+ if (d->programGuard && d->programGuard->id()
+ && shader && shader->d_func()->shaderGuard)
+ {
+ d->glfuncs->glDetachShader(d->programGuard->id(), shader->d_func()->shaderGuard->id());
+ }
+ d->linked = false; // Program needs to be relinked.
+ if (shader) {
+ d->shaders.removeAll(shader);
+ d->anonShaders.removeAll(shader);
+ disconnect(shader, SIGNAL(destroyed()), this, SLOT(shaderDestroyed()));
+ }
+}
+
+/*!
+ Returns a list of all shaders that have been added to this shader
+ program using addShader().
+
+ \sa addShader(), removeShader()
+*/
+QList<QOpenGLShader *> QOpenGLShaderProgram::shaders() const
+{
+ Q_D(const QOpenGLShaderProgram);
+ return d->shaders;
+}
+
+/*!
+ Removes all of the shaders that were added to this program previously.
+ The QOpenGLShader objects for the shaders will not be deleted if they
+ were constructed externally. QOpenGLShader objects that are constructed
+ internally by QOpenGLShaderProgram will be deleted.
+
+ \sa addShader(), removeShader()
+*/
+void QOpenGLShaderProgram::removeAllShaders()
+{
+ Q_D(QOpenGLShaderProgram);
+ d->removingShaders = true;
+ foreach (QOpenGLShader *shader, d->shaders) {
+ if (d->programGuard && d->programGuard->id()
+ && shader && shader->d_func()->shaderGuard)
+ {
+ d->glfuncs->glDetachShader(d->programGuard->id(), shader->d_func()->shaderGuard->id());
+ }
+ }
+ foreach (QOpenGLShader *shader, d->anonShaders) {
+ // Delete shader objects that were created anonymously.
+ delete shader;
+ }
+ d->shaders.clear();
+ d->anonShaders.clear();
+ d->linked = false; // Program needs to be relinked.
+ d->removingShaders = false;
+}
+
+/*!
+ Links together the shaders that were added to this program with
+ addShader(). Returns true if the link was successful or
+ false otherwise. If the link failed, the error messages can
+ be retrieved with log().
+
+ Subclasses can override this function to initialize attributes
+ and uniform variables for use in specific shader programs.
+
+ If the shader program was already linked, calling this
+ function again will force it to be re-linked.
+
+ \sa addShader(), log()
+*/
+bool QOpenGLShaderProgram::link()
+{
+ Q_D(QOpenGLShaderProgram);
+ GLuint program = d->programGuard ? d->programGuard->id() : 0;
+ if (!program)
+ return false;
+
+ GLint value;
+ if (d->shaders.isEmpty()) {
+ // If there are no explicit shaders, then it is possible that the
+ // application added a program binary with glProgramBinaryOES(),
+ // or otherwise populated the shaders itself. Check to see if the
+ // program is already linked and bail out if so.
+ value = 0;
+ d->glfuncs->glGetProgramiv(program, GL_LINK_STATUS, &value);
+ d->linked = (value != 0);
+ if (d->linked)
+ return true;
+ }
+
+ // Set up the geometry shader parameters
+#if 0
+ if (glProgramParameteriEXT) {
+ foreach (QOpenGLShader *shader, d->shaders) {
+ if (shader->shaderType() & QOpenGLShader::Geometry) {
+ glProgramParameteriEXT(program, GL_GEOMETRY_INPUT_TYPE_EXT,
+ d->geometryInputType);
+ glProgramParameteriEXT(program, GL_GEOMETRY_OUTPUT_TYPE_EXT,
+ d->geometryOutputType);
+ glProgramParameteriEXT(program, GL_GEOMETRY_VERTICES_OUT_EXT,
+ d->geometryVertexCount);
+ break;
+ }
+ }
+ }
+#endif
+
+ d->glfuncs->glLinkProgram(program);
+ value = 0;
+ d->glfuncs->glGetProgramiv(program, GL_LINK_STATUS, &value);
+ d->linked = (value != 0);
+ value = 0;
+ d->glfuncs->glGetProgramiv(program, GL_INFO_LOG_LENGTH, &value);
+ d->log = QString();
+ if (value > 1) {
+ char *logbuf = new char [value];
+ GLint len;
+ d->glfuncs->glGetProgramInfoLog(program, value, &len, logbuf);
+ d->log = QString::fromLatin1(logbuf);
+ QString name = objectName();
+ if (name.isEmpty())
+ qWarning() << "QOpenGLShader::link:" << d->log;
+ else
+ qWarning() << "QOpenGLShader::link[" << name << "]:" << d->log;
+ delete [] logbuf;
+ }
+ return d->linked;
+}
+
+/*!
+ Returns true if this shader program has been linked; false otherwise.
+
+ \sa link()
+*/
+bool QOpenGLShaderProgram::isLinked() const
+{
+ Q_D(const QOpenGLShaderProgram);
+ return d->linked;
+}
+
+/*!
+ Returns the errors and warnings that occurred during the last link()
+ or addShader() with explicitly specified source code.
+
+ \sa link()
+*/
+QString QOpenGLShaderProgram::log() const
+{
+ Q_D(const QOpenGLShaderProgram);
+ return d->log;
+}
+
+/*!
+ Binds this shader program to the active QOpenGLContext and makes
+ it the current shader program. Any previously bound shader program
+ is released. This is equivalent to calling \c{glUseProgram()} on
+ programId(). Returns true if the program was successfully bound;
+ false otherwise. If the shader program has not yet been linked,
+ or it needs to be re-linked, this function will call link().
+
+ \sa link(), release()
+*/
+bool QOpenGLShaderProgram::bind()
+{
+ Q_D(QOpenGLShaderProgram);
+ GLuint program = d->programGuard ? d->programGuard->id() : 0;
+ if (!program)
+ return false;
+ if (!d->linked && !link())
+ return false;
+#ifndef QT_NO_DEBUG
+ if (d->programGuard->group() != QOpenGLContextGroup::currentContextGroup()) {
+ qWarning("QOpenGLShaderProgram::bind: program is not valid in the current context.");
+ return false;
+ }
+#endif
+ d->glfuncs->glUseProgram(program);
+ return true;
+}
+
+/*!
+ Releases the active shader program from the current QOpenGLContext.
+ This is equivalent to calling \c{glUseProgram(0)}.
+
+ \sa bind()
+*/
+void QOpenGLShaderProgram::release()
+{
+ Q_D(QOpenGLShaderProgram);
+#ifndef QT_NO_DEBUG
+ if (d->programGuard->group() != QOpenGLContextGroup::currentContextGroup())
+ qWarning("QOpenGLShaderProgram::release: program is not valid in the current context.");
+#endif
+ d->glfuncs->glUseProgram(0);
+}
+
+/*!
+ Returns the OpenGL identifier associated with this shader program.
+
+ \sa QOpenGLShader::shaderId()
+*/
+GLuint QOpenGLShaderProgram::programId() const
+{
+ Q_D(const QOpenGLShaderProgram);
+ GLuint id = d->programGuard ? d->programGuard->id() : 0;
+ if (id)
+ return id;
+
+ // Create the identifier if we don't have one yet. This is for
+ // applications that want to create the attached shader configuration
+ // themselves, particularly those using program binaries.
+ if (!const_cast<QOpenGLShaderProgram *>(this)->init())
+ return 0;
+ return d->programGuard ? d->programGuard->id() : 0;
+}
+
+/*!
+ Binds the attribute \a name to the specified \a location. This
+ function can be called before or after the program has been linked.
+ Any attributes that have not been explicitly bound when the program
+ is linked will be assigned locations automatically.
+
+ When this function is called after the program has been linked,
+ the program will need to be relinked for the change to take effect.
+
+ \sa attributeLocation()
+*/
+void QOpenGLShaderProgram::bindAttributeLocation(const char *name, int location)
+{
+ Q_D(QOpenGLShaderProgram);
+ if (!init() || !d->programGuard || !d->programGuard->id())
+ return;
+ d->glfuncs->glBindAttribLocation(d->programGuard->id(), location, name);
+ d->linked = false; // Program needs to be relinked.
+}
+
+/*!
+ \overload
+
+ Binds the attribute \a name to the specified \a location. This
+ function can be called before or after the program has been linked.
+ Any attributes that have not been explicitly bound when the program
+ is linked will be assigned locations automatically.
+
+ When this function is called after the program has been linked,
+ the program will need to be relinked for the change to take effect.
+
+ \sa attributeLocation()
+*/
+void QOpenGLShaderProgram::bindAttributeLocation(const QByteArray& name, int location)
+{
+ bindAttributeLocation(name.constData(), location);
+}
+
+/*!
+ \overload
+
+ Binds the attribute \a name to the specified \a location. This
+ function can be called before or after the program has been linked.
+ Any attributes that have not been explicitly bound when the program
+ is linked will be assigned locations automatically.
+
+ When this function is called after the program has been linked,
+ the program will need to be relinked for the change to take effect.
+
+ \sa attributeLocation()
+*/
+void QOpenGLShaderProgram::bindAttributeLocation(const QString& name, int location)
+{
+ bindAttributeLocation(name.toLatin1().constData(), location);
+}
+
+/*!
+ Returns the location of the attribute \a name within this shader
+ program's parameter list. Returns -1 if \a name is not a valid
+ attribute for this shader program.
+
+ \sa uniformLocation(), bindAttributeLocation()
+*/
+int QOpenGLShaderProgram::attributeLocation(const char *name) const
+{
+ Q_D(const QOpenGLShaderProgram);
+ if (d->linked && d->programGuard && d->programGuard->id()) {
+ return d->glfuncs->glGetAttribLocation(d->programGuard->id(), name);
+ } else {
+ qWarning() << "QOpenGLShaderProgram::attributeLocation(" << name
+ << "): shader program is not linked";
+ return -1;
+ }
+}
+
+/*!
+ \overload
+
+ Returns the location of the attribute \a name within this shader
+ program's parameter list. Returns -1 if \a name is not a valid
+ attribute for this shader program.
+
+ \sa uniformLocation(), bindAttributeLocation()
+*/
+int QOpenGLShaderProgram::attributeLocation(const QByteArray& name) const
+{
+ return attributeLocation(name.constData());
+}
+
+/*!
+ \overload
+
+ Returns the location of the attribute \a name within this shader
+ program's parameter list. Returns -1 if \a name is not a valid
+ attribute for this shader program.
+
+ \sa uniformLocation(), bindAttributeLocation()
+*/
+int QOpenGLShaderProgram::attributeLocation(const QString& name) const
+{
+ return attributeLocation(name.toLatin1().constData());
+}
+
+/*!
+ Sets the attribute at \a location in the current context to \a value.
+
+ \sa setUniformValue()
+*/
+void QOpenGLShaderProgram::setAttributeValue(int location, GLfloat value)
+{
+ Q_D(QOpenGLShaderProgram);
+ if (location != -1)
+ d->glfuncs->glVertexAttrib1fv(location, &value);
+}
+
+/*!
+ \overload
+
+ Sets the attribute called \a name in the current context to \a value.
+
+ \sa setUniformValue()
+*/
+void QOpenGLShaderProgram::setAttributeValue(const char *name, GLfloat value)
+{
+ setAttributeValue(attributeLocation(name), value);
+}
+
+/*!
+ Sets the attribute at \a location in the current context to
+ the 2D vector (\a x, \a y).
+
+ \sa setUniformValue()
+*/
+void QOpenGLShaderProgram::setAttributeValue(int location, GLfloat x, GLfloat y)
+{
+ Q_D(QOpenGLShaderProgram);
+ if (location != -1) {
+ GLfloat values[2] = {x, y};
+ d->glfuncs->glVertexAttrib2fv(location, values);
+ }
+}
+
+/*!
+ \overload
+
+ Sets the attribute called \a name in the current context to
+ the 2D vector (\a x, \a y).
+
+ \sa setUniformValue()
+*/
+void QOpenGLShaderProgram::setAttributeValue(const char *name, GLfloat x, GLfloat y)
+{
+ setAttributeValue(attributeLocation(name), x, y);
+}
+
+/*!
+ Sets the attribute at \a location in the current context to
+ the 3D vector (\a x, \a y, \a z).
+
+ \sa setUniformValue()
+*/
+void QOpenGLShaderProgram::setAttributeValue
+ (int location, GLfloat x, GLfloat y, GLfloat z)
+{
+ Q_D(QOpenGLShaderProgram);
+ Q_UNUSED(d);
+ if (location != -1) {
+ GLfloat values[3] = {x, y, z};
+ d->glfuncs->glVertexAttrib3fv(location, values);
+ }
+}
+
+/*!
+ \overload
+
+ Sets the attribute called \a name in the current context to
+ the 3D vector (\a x, \a y, \a z).
+
+ \sa setUniformValue()
+*/
+void QOpenGLShaderProgram::setAttributeValue
+ (const char *name, GLfloat x, GLfloat y, GLfloat z)
+{
+ setAttributeValue(attributeLocation(name), x, y, z);
+}
+
+/*!
+ Sets the attribute at \a location in the current context to
+ the 4D vector (\a x, \a y, \a z, \a w).
+
+ \sa setUniformValue()
+*/
+void QOpenGLShaderProgram::setAttributeValue
+ (int location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ Q_D(QOpenGLShaderProgram);
+ if (location != -1) {
+ GLfloat values[4] = {x, y, z, w};
+ d->glfuncs->glVertexAttrib4fv(location, values);
+ }
+}
+
+/*!
+ \overload
+
+ Sets the attribute called \a name in the current context to
+ the 4D vector (\a x, \a y, \a z, \a w).
+
+ \sa setUniformValue()
+*/
+void QOpenGLShaderProgram::setAttributeValue
+ (const char *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ setAttributeValue(attributeLocation(name), x, y, z, w);
+}
+
+/*!
+ Sets the attribute at \a location in the current context to \a value.
+
+ \sa setUniformValue()
+*/
+void QOpenGLShaderProgram::setAttributeValue(int location, const QVector2D& value)
+{
+ Q_D(QOpenGLShaderProgram);
+ if (location != -1)
+ d->glfuncs->glVertexAttrib2fv(location, reinterpret_cast<const GLfloat *>(&value));
+}
+
+/*!
+ \overload
+
+ Sets the attribute called \a name in the current context to \a value.
+
+ \sa setUniformValue()
+*/
+void QOpenGLShaderProgram::setAttributeValue(const char *name, const QVector2D& value)
+{
+ setAttributeValue(attributeLocation(name), value);
+}
+
+/*!
+ Sets the attribute at \a location in the current context to \a value.
+
+ \sa setUniformValue()
+*/
+void QOpenGLShaderProgram::setAttributeValue(int location, const QVector3D& value)
+{
+ Q_D(QOpenGLShaderProgram);
+ Q_UNUSED(d);
+ if (location != -1)
+ d->glfuncs->glVertexAttrib3fv(location, reinterpret_cast<const GLfloat *>(&value));
+}
+
+/*!
+ \overload
+
+ Sets the attribute called \a name in the current context to \a value.
+
+ \sa setUniformValue()
+*/
+void QOpenGLShaderProgram::setAttributeValue(const char *name, const QVector3D& value)
+{
+ setAttributeValue(attributeLocation(name), value);
+}
+
+/*!
+ Sets the attribute at \a location in the current context to \a value.
+
+ \sa setUniformValue()
+*/
+void QOpenGLShaderProgram::setAttributeValue(int location, const QVector4D& value)
+{
+ Q_D(QOpenGLShaderProgram);
+ Q_UNUSED(d);
+ if (location != -1)
+ d->glfuncs->glVertexAttrib4fv(location, reinterpret_cast<const GLfloat *>(&value));
+}
+
+/*!
+ \overload
+
+ Sets the attribute called \a name in the current context to \a value.
+
+ \sa setUniformValue()
+*/
+void QOpenGLShaderProgram::setAttributeValue(const char *name, const QVector4D& value)
+{
+ setAttributeValue(attributeLocation(name), value);
+}
+
+/*!
+ Sets the attribute at \a location in the current context to \a value.
+
+ \sa setUniformValue()
+*/
+void QOpenGLShaderProgram::setAttributeValue(int location, const QColor& value)
+{
+ Q_D(QOpenGLShaderProgram);
+ Q_UNUSED(d);
+ if (location != -1) {
+ GLfloat values[4] = {GLfloat(value.redF()), GLfloat(value.greenF()),
+ GLfloat(value.blueF()), GLfloat(value.alphaF())};
+ d->glfuncs->glVertexAttrib4fv(location, values);
+ }
+}
+
+/*!
+ \overload
+
+ Sets the attribute called \a name in the current context to \a value.
+
+ \sa setUniformValue()
+*/
+void QOpenGLShaderProgram::setAttributeValue(const char *name, const QColor& value)
+{
+ setAttributeValue(attributeLocation(name), value);
+}
+
+/*!
+ Sets the attribute at \a location in the current context to the
+ contents of \a values, which contains \a columns elements, each
+ consisting of \a rows elements. The \a rows value should be
+ 1, 2, 3, or 4. This function is typically used to set matrix
+ values and column vectors.
+
+ \sa setUniformValue()
+*/
+void QOpenGLShaderProgram::setAttributeValue
+ (int location, const GLfloat *values, int columns, int rows)
+{
+ Q_D(QOpenGLShaderProgram);
+ Q_UNUSED(d);
+ if (rows < 1 || rows > 4) {
+ qWarning() << "QOpenGLShaderProgram::setAttributeValue: rows" << rows << "not supported";
+ return;
+ }
+ if (location != -1) {
+ while (columns-- > 0) {
+ if (rows == 1)
+ d->glfuncs->glVertexAttrib1fv(location, values);
+ else if (rows == 2)
+ d->glfuncs->glVertexAttrib2fv(location, values);
+ else if (rows == 3)
+ d->glfuncs->glVertexAttrib3fv(location, values);
+ else
+ d->glfuncs->glVertexAttrib4fv(location, values);
+ values += rows;
+ ++location;
+ }
+ }
+}
+
+/*!
+ \overload
+
+ Sets the attribute called \a name in the current context to the
+ contents of \a values, which contains \a columns elements, each
+ consisting of \a rows elements. The \a rows value should be
+ 1, 2, 3, or 4. This function is typically used to set matrix
+ values and column vectors.
+
+ \sa setUniformValue()
+*/
+void QOpenGLShaderProgram::setAttributeValue
+ (const char *name, const GLfloat *values, int columns, int rows)
+{
+ setAttributeValue(attributeLocation(name), values, columns, rows);
+}
+
+/*!
+ Sets an array of vertex \a values on the attribute at \a location
+ in this shader program. The \a tupleSize indicates the number of
+ components per vertex (1, 2, 3, or 4), and the \a stride indicates
+ the number of bytes between vertices. A default \a stride value
+ of zero indicates that the vertices are densely packed in \a values.
+
+ The array will become active when enableAttributeArray() is called
+ on the \a location. Otherwise the value specified with
+ setAttributeValue() for \a location will be used.
+
+ \sa setAttributeValue(), setUniformValue(), enableAttributeArray()
+ \sa disableAttributeArray()
+*/
+void QOpenGLShaderProgram::setAttributeArray
+ (int location, const GLfloat *values, int tupleSize, int stride)
+{
+ Q_D(QOpenGLShaderProgram);
+ Q_UNUSED(d);
+ if (location != -1) {
+ d->glfuncs->glVertexAttribPointer(location, tupleSize, GL_FLOAT, GL_FALSE,
+ stride, values);
+ }
+}
+
+/*!
+ Sets an array of 2D vertex \a values on the attribute at \a location
+ in this shader program. The \a stride indicates the number of bytes
+ between vertices. A default \a stride value of zero indicates that
+ the vertices are densely packed in \a values.
+
+ The array will become active when enableAttributeArray() is called
+ on the \a location. Otherwise the value specified with
+ setAttributeValue() for \a location will be used.
+
+ \sa setAttributeValue(), setUniformValue(), enableAttributeArray()
+ \sa disableAttributeArray()
+*/
+void QOpenGLShaderProgram::setAttributeArray
+ (int location, const QVector2D *values, int stride)
+{
+ Q_D(QOpenGLShaderProgram);
+ Q_UNUSED(d);
+ if (location != -1) {
+ d->glfuncs->glVertexAttribPointer(location, 2, GL_FLOAT, GL_FALSE,
+ stride, values);
+ }
+}
+
+/*!
+ Sets an array of 3D vertex \a values on the attribute at \a location
+ in this shader program. The \a stride indicates the number of bytes
+ between vertices. A default \a stride value of zero indicates that
+ the vertices are densely packed in \a values.
+
+ The array will become active when enableAttributeArray() is called
+ on the \a location. Otherwise the value specified with
+ setAttributeValue() for \a location will be used.
+
+ \sa setAttributeValue(), setUniformValue(), enableAttributeArray()
+ \sa disableAttributeArray()
+*/
+void QOpenGLShaderProgram::setAttributeArray
+ (int location, const QVector3D *values, int stride)
+{
+ Q_D(QOpenGLShaderProgram);
+ Q_UNUSED(d);
+ if (location != -1) {
+ d->glfuncs->glVertexAttribPointer(location, 3, GL_FLOAT, GL_FALSE,
+ stride, values);
+ }
+}
+
+/*!
+ Sets an array of 4D vertex \a values on the attribute at \a location
+ in this shader program. The \a stride indicates the number of bytes
+ between vertices. A default \a stride value of zero indicates that
+ the vertices are densely packed in \a values.
+
+ The array will become active when enableAttributeArray() is called
+ on the \a location. Otherwise the value specified with
+ setAttributeValue() for \a location will be used.
+
+ \sa setAttributeValue(), setUniformValue(), enableAttributeArray()
+ \sa disableAttributeArray()
+*/
+void QOpenGLShaderProgram::setAttributeArray
+ (int location, const QVector4D *values, int stride)
+{
+ Q_D(QOpenGLShaderProgram);
+ Q_UNUSED(d);
+ if (location != -1) {
+ d->glfuncs->glVertexAttribPointer(location, 4, GL_FLOAT, GL_FALSE,
+ stride, values);
+ }
+}
+
+/*!
+ Sets an array of vertex \a values on the attribute at \a location
+ in this shader program. The \a stride indicates the number of bytes
+ between vertices. A default \a stride value of zero indicates that
+ the vertices are densely packed in \a values.
+
+ The \a type indicates the type of elements in the \a values array,
+ usually \c{GL_FLOAT}, \c{GL_UNSIGNED_BYTE}, etc. The \a tupleSize
+ indicates the number of components per vertex: 1, 2, 3, or 4.
+
+ The array will become active when enableAttributeArray() is called
+ on the \a location. Otherwise the value specified with
+ setAttributeValue() for \a location will be used.
+
+ The setAttributeBuffer() function can be used to set the attribute
+ array to an offset within a vertex buffer.
+
+ \sa setAttributeValue(), setUniformValue(), enableAttributeArray()
+ \sa disableAttributeArray(), setAttributeBuffer()
+*/
+void QOpenGLShaderProgram::setAttributeArray
+ (int location, GLenum type, const void *values, int tupleSize, int stride)
+{
+ Q_D(QOpenGLShaderProgram);
+ Q_UNUSED(d);
+ if (location != -1) {
+ d->glfuncs->glVertexAttribPointer(location, tupleSize, type, GL_TRUE,
+ stride, values);
+ }
+}
+
+/*!
+ \overload
+
+ Sets an array of vertex \a values on the attribute called \a name
+ in this shader program. The \a tupleSize indicates the number of
+ components per vertex (1, 2, 3, or 4), and the \a stride indicates
+ the number of bytes between vertices. A default \a stride value
+ of zero indicates that the vertices are densely packed in \a values.
+
+ The array will become active when enableAttributeArray() is called
+ on \a name. Otherwise the value specified with setAttributeValue()
+ for \a name will be used.
+
+ \sa setAttributeValue(), setUniformValue(), enableAttributeArray()
+ \sa disableAttributeArray()
+*/
+void QOpenGLShaderProgram::setAttributeArray
+ (const char *name, const GLfloat *values, int tupleSize, int stride)
+{
+ setAttributeArray(attributeLocation(name), values, tupleSize, stride);
+}
+
+/*!
+ \overload
+
+ Sets an array of 2D vertex \a values on the attribute called \a name
+ in this shader program. The \a stride indicates the number of bytes
+ between vertices. A default \a stride value of zero indicates that
+ the vertices are densely packed in \a values.
+
+ The array will become active when enableAttributeArray() is called
+ on \a name. Otherwise the value specified with setAttributeValue()
+ for \a name will be used.
+
+ \sa setAttributeValue(), setUniformValue(), enableAttributeArray()
+ \sa disableAttributeArray()
+*/
+void QOpenGLShaderProgram::setAttributeArray
+ (const char *name, const QVector2D *values, int stride)
+{
+ setAttributeArray(attributeLocation(name), values, stride);
+}
+
+/*!
+ \overload
+
+ Sets an array of 3D vertex \a values on the attribute called \a name
+ in this shader program. The \a stride indicates the number of bytes
+ between vertices. A default \a stride value of zero indicates that
+ the vertices are densely packed in \a values.
+
+ The array will become active when enableAttributeArray() is called
+ on \a name. Otherwise the value specified with setAttributeValue()
+ for \a name will be used.
+
+ \sa setAttributeValue(), setUniformValue(), enableAttributeArray()
+ \sa disableAttributeArray()
+*/
+void QOpenGLShaderProgram::setAttributeArray
+ (const char *name, const QVector3D *values, int stride)
+{
+ setAttributeArray(attributeLocation(name), values, stride);
+}
+
+/*!
+ \overload
+
+ Sets an array of 4D vertex \a values on the attribute called \a name
+ in this shader program. The \a stride indicates the number of bytes
+ between vertices. A default \a stride value of zero indicates that
+ the vertices are densely packed in \a values.
+
+ The array will become active when enableAttributeArray() is called
+ on \a name. Otherwise the value specified with setAttributeValue()
+ for \a name will be used.
+
+ \sa setAttributeValue(), setUniformValue(), enableAttributeArray()
+ \sa disableAttributeArray()
+*/
+void QOpenGLShaderProgram::setAttributeArray
+ (const char *name, const QVector4D *values, int stride)
+{
+ setAttributeArray(attributeLocation(name), values, stride);
+}
+
+/*!
+ \overload
+
+ Sets an array of vertex \a values on the attribute called \a name
+ in this shader program. The \a stride indicates the number of bytes
+ between vertices. A default \a stride value of zero indicates that
+ the vertices are densely packed in \a values.
+
+ The \a type indicates the type of elements in the \a values array,
+ usually \c{GL_FLOAT}, \c{GL_UNSIGNED_BYTE}, etc. The \a tupleSize
+ indicates the number of components per vertex: 1, 2, 3, or 4.
+
+ The array will become active when enableAttributeArray() is called
+ on the \a name. Otherwise the value specified with
+ setAttributeValue() for \a name will be used.
+
+ The setAttributeBuffer() function can be used to set the attribute
+ array to an offset within a vertex buffer.
+
+ \sa setAttributeValue(), setUniformValue(), enableAttributeArray()
+ \sa disableAttributeArray(), setAttributeBuffer()
+*/
+void QOpenGLShaderProgram::setAttributeArray
+ (const char *name, GLenum type, const void *values, int tupleSize, int stride)
+{
+ setAttributeArray(attributeLocation(name), type, values, tupleSize, stride);
+}
+
+/*!
+ Sets an array of vertex values on the attribute at \a location in
+ this shader program, starting at a specific \a offset in the
+ currently bound vertex buffer. The \a stride indicates the number
+ of bytes between vertices. A default \a stride value of zero
+ indicates that the vertices are densely packed in the value array.
+
+ The \a type indicates the type of elements in the vertex value
+ array, usually \c{GL_FLOAT}, \c{GL_UNSIGNED_BYTE}, etc. The \a
+ tupleSize indicates the number of components per vertex: 1, 2, 3,
+ or 4.
+
+ The array will become active when enableAttributeArray() is called
+ on the \a location. Otherwise the value specified with
+ setAttributeValue() for \a location will be used.
+
+ \sa setAttributeArray()
+*/
+void QOpenGLShaderProgram::setAttributeBuffer
+ (int location, GLenum type, int offset, int tupleSize, int stride)
+{
+ Q_D(QOpenGLShaderProgram);
+ Q_UNUSED(d);
+ if (location != -1) {
+ d->glfuncs->glVertexAttribPointer(location, tupleSize, type, GL_TRUE, stride,
+ reinterpret_cast<const void *>(offset));
+ }
+}
+
+/*!
+ \overload
+
+ Sets an array of vertex values on the attribute called \a name
+ in this shader program, starting at a specific \a offset in the
+ currently bound vertex buffer. The \a stride indicates the number
+ of bytes between vertices. A default \a stride value of zero
+ indicates that the vertices are densely packed in the value array.
+
+ The \a type indicates the type of elements in the vertex value
+ array, usually \c{GL_FLOAT}, \c{GL_UNSIGNED_BYTE}, etc. The \a
+ tupleSize indicates the number of components per vertex: 1, 2, 3,
+ or 4.
+
+ The array will become active when enableAttributeArray() is called
+ on the \a name. Otherwise the value specified with
+ setAttributeValue() for \a name will be used.
+
+ \sa setAttributeArray()
+*/
+void QOpenGLShaderProgram::setAttributeBuffer
+ (const char *name, GLenum type, int offset, int tupleSize, int stride)
+{
+ setAttributeBuffer(attributeLocation(name), type, offset, tupleSize, stride);
+}
+
+/*!
+ Enables the vertex array at \a location in this shader program
+ so that the value set by setAttributeArray() on \a location
+ will be used by the shader program.
+
+ \sa disableAttributeArray(), setAttributeArray(), setAttributeValue()
+ \sa setUniformValue()
+*/
+void QOpenGLShaderProgram::enableAttributeArray(int location)
+{
+ Q_D(QOpenGLShaderProgram);
+ Q_UNUSED(d);
+ if (location != -1)
+ d->glfuncs->glEnableVertexAttribArray(location);
+}
+
+/*!
+ \overload
+
+ Enables the vertex array called \a name in this shader program
+ so that the value set by setAttributeArray() on \a name
+ will be used by the shader program.
+
+ \sa disableAttributeArray(), setAttributeArray(), setAttributeValue()
+ \sa setUniformValue()
+*/
+void QOpenGLShaderProgram::enableAttributeArray(const char *name)
+{
+ enableAttributeArray(attributeLocation(name));
+}
+
+/*!
+ Disables the vertex array at \a location in this shader program
+ that was enabled by a previous call to enableAttributeArray().
+
+ \sa enableAttributeArray(), setAttributeArray(), setAttributeValue()
+ \sa setUniformValue()
+*/
+void QOpenGLShaderProgram::disableAttributeArray(int location)
+{
+ Q_D(QOpenGLShaderProgram);
+ Q_UNUSED(d);
+ if (location != -1)
+ d->glfuncs->glDisableVertexAttribArray(location);
+}
+
+/*!
+ \overload
+
+ Disables the vertex array called \a name in this shader program
+ that was enabled by a previous call to enableAttributeArray().
+
+ \sa enableAttributeArray(), setAttributeArray(), setAttributeValue()
+ \sa setUniformValue()
+*/
+void QOpenGLShaderProgram::disableAttributeArray(const char *name)
+{
+ disableAttributeArray(attributeLocation(name));
+}
+
+/*!
+ Returns the location of the uniform variable \a name within this shader
+ program's parameter list. Returns -1 if \a name is not a valid
+ uniform variable for this shader program.
+
+ \sa attributeLocation()
+*/
+int QOpenGLShaderProgram::uniformLocation(const char *name) const
+{
+ Q_D(const QOpenGLShaderProgram);
+ Q_UNUSED(d);
+ if (d->linked && d->programGuard && d->programGuard->id()) {
+ return d->glfuncs->glGetUniformLocation(d->programGuard->id(), name);
+ } else {
+ qWarning() << "QOpenGLShaderProgram::uniformLocation(" << name
+ << "): shader program is not linked";
+ return -1;
+ }
+}
+
+/*!
+ \overload
+
+ Returns the location of the uniform variable \a name within this shader
+ program's parameter list. Returns -1 if \a name is not a valid
+ uniform variable for this shader program.
+
+ \sa attributeLocation()
+*/
+int QOpenGLShaderProgram::uniformLocation(const QByteArray& name) const
+{
+ return uniformLocation(name.constData());
+}
+
+/*!
+ \overload
+
+ Returns the location of the uniform variable \a name within this shader
+ program's parameter list. Returns -1 if \a name is not a valid
+ uniform variable for this shader program.
+
+ \sa attributeLocation()
+*/
+int QOpenGLShaderProgram::uniformLocation(const QString& name) const
+{
+ return uniformLocation(name.toLatin1().constData());
+}
+
+/*!
+ Sets the uniform variable at \a location in the current context to \a value.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValue(int location, GLfloat value)
+{
+ Q_D(QOpenGLShaderProgram);
+ Q_UNUSED(d);
+ if (location != -1)
+ d->glfuncs->glUniform1fv(location, 1, &value);
+}
+
+/*!
+ \overload
+
+ Sets the uniform variable called \a name in the current context
+ to \a value.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValue(const char *name, GLfloat value)
+{
+ setUniformValue(uniformLocation(name), value);
+}
+
+/*!
+ Sets the uniform variable at \a location in the current context to \a value.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValue(int location, GLint value)
+{
+ Q_D(QOpenGLShaderProgram);
+ Q_UNUSED(d);
+ if (location != -1)
+ d->glfuncs->glUniform1i(location, value);
+}
+
+/*!
+ \overload
+
+ Sets the uniform variable called \a name in the current context
+ to \a value.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValue(const char *name, GLint value)
+{
+ setUniformValue(uniformLocation(name), value);
+}
+
+/*!
+ Sets the uniform variable at \a location in the current context to \a value.
+ This function should be used when setting sampler values.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValue(int location, GLuint value)
+{
+ Q_D(QOpenGLShaderProgram);
+ Q_UNUSED(d);
+ if (location != -1)
+ d->glfuncs->glUniform1i(location, value);
+}
+
+/*!
+ \overload
+
+ Sets the uniform variable called \a name in the current context
+ to \a value. This function should be used when setting sampler values.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValue(const char *name, GLuint value)
+{
+ setUniformValue(uniformLocation(name), value);
+}
+
+/*!
+ Sets the uniform variable at \a location in the current context to
+ the 2D vector (\a x, \a y).
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValue(int location, GLfloat x, GLfloat y)
+{
+ Q_D(QOpenGLShaderProgram);
+ Q_UNUSED(d);
+ if (location != -1) {
+ GLfloat values[2] = {x, y};
+ d->glfuncs->glUniform2fv(location, 1, values);
+ }
+}
+
+/*!
+ \overload
+
+ Sets the uniform variable called \a name in the current context to
+ the 2D vector (\a x, \a y).
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValue(const char *name, GLfloat x, GLfloat y)
+{
+ setUniformValue(uniformLocation(name), x, y);
+}
+
+/*!
+ Sets the uniform variable at \a location in the current context to
+ the 3D vector (\a x, \a y, \a z).
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValue
+ (int location, GLfloat x, GLfloat y, GLfloat z)
+{
+ Q_D(QOpenGLShaderProgram);
+ Q_UNUSED(d);
+ if (location != -1) {
+ GLfloat values[3] = {x, y, z};
+ d->glfuncs->glUniform3fv(location, 1, values);
+ }
+}
+
+/*!
+ \overload
+
+ Sets the uniform variable called \a name in the current context to
+ the 3D vector (\a x, \a y, \a z).
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValue
+ (const char *name, GLfloat x, GLfloat y, GLfloat z)
+{
+ setUniformValue(uniformLocation(name), x, y, z);
+}
+
+/*!
+ Sets the uniform variable at \a location in the current context to
+ the 4D vector (\a x, \a y, \a z, \a w).
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValue
+ (int location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ Q_D(QOpenGLShaderProgram);
+ Q_UNUSED(d);
+ if (location != -1) {
+ GLfloat values[4] = {x, y, z, w};
+ d->glfuncs->glUniform4fv(location, 1, values);
+ }
+}
+
+/*!
+ \overload
+
+ Sets the uniform variable called \a name in the current context to
+ the 4D vector (\a x, \a y, \a z, \a w).
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValue
+ (const char *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ setUniformValue(uniformLocation(name), x, y, z, w);
+}
+
+/*!
+ Sets the uniform variable at \a location in the current context to \a value.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValue(int location, const QVector2D& value)
+{
+ Q_D(QOpenGLShaderProgram);
+ Q_UNUSED(d);
+ if (location != -1)
+ d->glfuncs->glUniform2fv(location, 1, reinterpret_cast<const GLfloat *>(&value));
+}
+
+/*!
+ \overload
+
+ Sets the uniform variable called \a name in the current context
+ to \a value.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValue(const char *name, const QVector2D& value)
+{
+ setUniformValue(uniformLocation(name), value);
+}
+
+/*!
+ Sets the uniform variable at \a location in the current context to \a value.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValue(int location, const QVector3D& value)
+{
+ Q_D(QOpenGLShaderProgram);
+ Q_UNUSED(d);
+ if (location != -1)
+ d->glfuncs->glUniform3fv(location, 1, reinterpret_cast<const GLfloat *>(&value));
+}
+
+/*!
+ \overload
+
+ Sets the uniform variable called \a name in the current context
+ to \a value.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValue(const char *name, const QVector3D& value)
+{
+ setUniformValue(uniformLocation(name), value);
+}
+
+/*!
+ Sets the uniform variable at \a location in the current context to \a value.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValue(int location, const QVector4D& value)
+{
+ Q_D(QOpenGLShaderProgram);
+ Q_UNUSED(d);
+ if (location != -1)
+ d->glfuncs->glUniform4fv(location, 1, reinterpret_cast<const GLfloat *>(&value));
+}
+
+/*!
+ \overload
+
+ Sets the uniform variable called \a name in the current context
+ to \a value.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValue(const char *name, const QVector4D& value)
+{
+ setUniformValue(uniformLocation(name), value);
+}
+
+/*!
+ Sets the uniform variable at \a location in the current context to
+ the red, green, blue, and alpha components of \a color.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValue(int location, const QColor& color)
+{
+ Q_D(QOpenGLShaderProgram);
+ Q_UNUSED(d);
+ if (location != -1) {
+ GLfloat values[4] = {GLfloat(color.redF()), GLfloat(color.greenF()),
+ GLfloat(color.blueF()), GLfloat(color.alphaF())};
+ d->glfuncs->glUniform4fv(location, 1, values);
+ }
+}
+
+/*!
+ \overload
+
+ Sets the uniform variable called \a name in the current context to
+ the red, green, blue, and alpha components of \a color.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValue(const char *name, const QColor& color)
+{
+ setUniformValue(uniformLocation(name), color);
+}
+
+/*!
+ Sets the uniform variable at \a location in the current context to
+ the x and y coordinates of \a point.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValue(int location, const QPoint& point)
+{
+ Q_D(QOpenGLShaderProgram);
+ Q_UNUSED(d);
+ if (location != -1) {
+ GLfloat values[4] = {GLfloat(point.x()), GLfloat(point.y())};
+ d->glfuncs->glUniform2fv(location, 1, values);
+ }
+}
+
+/*!
+ \overload
+
+ Sets the uniform variable associated with \a name in the current
+ context to the x and y coordinates of \a point.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValue(const char *name, const QPoint& point)
+{
+ setUniformValue(uniformLocation(name), point);
+}
+
+/*!
+ Sets the uniform variable at \a location in the current context to
+ the x and y coordinates of \a point.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValue(int location, const QPointF& point)
+{
+ Q_D(QOpenGLShaderProgram);
+ Q_UNUSED(d);
+ if (location != -1) {
+ GLfloat values[4] = {GLfloat(point.x()), GLfloat(point.y())};
+ d->glfuncs->glUniform2fv(location, 1, values);
+ }
+}
+
+/*!
+ \overload
+
+ Sets the uniform variable associated with \a name in the current
+ context to the x and y coordinates of \a point.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValue(const char *name, const QPointF& point)
+{
+ setUniformValue(uniformLocation(name), point);
+}
+
+/*!
+ Sets the uniform variable at \a location in the current context to
+ the width and height of the given \a size.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValue(int location, const QSize& size)
+{
+ Q_D(QOpenGLShaderProgram);
+ Q_UNUSED(d);
+ if (location != -1) {
+ GLfloat values[4] = {GLfloat(size.width()), GLfloat(size.height())};
+ d->glfuncs->glUniform2fv(location, 1, values);
+ }
+}
+
+/*!
+ \overload
+
+ Sets the uniform variable associated with \a name in the current
+ context to the width and height of the given \a size.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValue(const char *name, const QSize& size)
+{
+ setUniformValue(uniformLocation(name), size);
+}
+
+/*!
+ Sets the uniform variable at \a location in the current context to
+ the width and height of the given \a size.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValue(int location, const QSizeF& size)
+{
+ Q_D(QOpenGLShaderProgram);
+ Q_UNUSED(d);
+ if (location != -1) {
+ GLfloat values[4] = {GLfloat(size.width()), GLfloat(size.height())};
+ d->glfuncs->glUniform2fv(location, 1, values);
+ }
+}
+
+/*!
+ \overload
+
+ Sets the uniform variable associated with \a name in the current
+ context to the width and height of the given \a size.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValue(const char *name, const QSizeF& size)
+{
+ setUniformValue(uniformLocation(name), size);
+}
+
+// We have to repack matrices from qreal to GLfloat.
+#define setUniformMatrix(func,location,value,cols,rows) \
+ if (location == -1) \
+ return; \
+ if (sizeof(qreal) == sizeof(GLfloat)) { \
+ func(location, 1, GL_FALSE, \
+ reinterpret_cast<const GLfloat *>(value.constData())); \
+ } else { \
+ GLfloat mat[cols * rows]; \
+ const qreal *data = value.constData(); \
+ for (int i = 0; i < cols * rows; ++i) \
+ mat[i] = data[i]; \
+ func(location, 1, GL_FALSE, mat); \
+ }
+#define setUniformGenericMatrix(colfunc,location,value,cols,rows) \
+ if (location == -1) \
+ return; \
+ if (sizeof(qreal) == sizeof(GLfloat)) { \
+ const GLfloat *data = reinterpret_cast<const GLfloat *> \
+ (value.constData()); \
+ colfunc(location, cols, data); \
+ } else { \
+ GLfloat mat[cols * rows]; \
+ const qreal *data = value.constData(); \
+ for (int i = 0; i < cols * rows; ++i) \
+ mat[i] = data[i]; \
+ colfunc(location, cols, mat); \
+ }
+
+/*!
+ Sets the uniform variable at \a location in the current context
+ to a 2x2 matrix \a value.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix2x2& value)
+{
+ Q_D(QOpenGLShaderProgram);
+ Q_UNUSED(d);
+ setUniformMatrix(d->glfuncs->glUniformMatrix2fv, location, value, 2, 2);
+}
+
+/*!
+ \overload
+
+ Sets the uniform variable called \a name in the current context
+ to a 2x2 matrix \a value.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValue(const char *name, const QMatrix2x2& value)
+{
+ setUniformValue(uniformLocation(name), value);
+}
+
+/*!
+ Sets the uniform variable at \a location in the current context
+ to a 2x3 matrix \a value.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix2x3& value)
+{
+ Q_D(QOpenGLShaderProgram);
+ Q_UNUSED(d);
+ setUniformGenericMatrix
+ (d->glfuncs->glUniform3fv, location, value, 2, 3);
+}
+
+/*!
+ \overload
+
+ Sets the uniform variable called \a name in the current context
+ to a 2x3 matrix \a value.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValue(const char *name, const QMatrix2x3& value)
+{
+ setUniformValue(uniformLocation(name), value);
+}
+
+/*!
+ Sets the uniform variable at \a location in the current context
+ to a 2x4 matrix \a value.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix2x4& value)
+{
+ Q_D(QOpenGLShaderProgram);
+ Q_UNUSED(d);
+ setUniformGenericMatrix
+ (d->glfuncs->glUniform4fv, location, value, 2, 4);
+}
+
+/*!
+ \overload
+
+ Sets the uniform variable called \a name in the current context
+ to a 2x4 matrix \a value.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValue(const char *name, const QMatrix2x4& value)
+{
+ setUniformValue(uniformLocation(name), value);
+}
+
+/*!
+ Sets the uniform variable at \a location in the current context
+ to a 3x2 matrix \a value.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix3x2& value)
+{
+ Q_D(QOpenGLShaderProgram);
+ Q_UNUSED(d);
+ setUniformGenericMatrix
+ (d->glfuncs->glUniform2fv, location, value, 3, 2);
+}
+
+/*!
+ \overload
+
+ Sets the uniform variable called \a name in the current context
+ to a 3x2 matrix \a value.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValue(const char *name, const QMatrix3x2& value)
+{
+ setUniformValue(uniformLocation(name), value);
+}
+
+/*!
+ Sets the uniform variable at \a location in the current context
+ to a 3x3 matrix \a value.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix3x3& value)
+{
+ Q_D(QOpenGLShaderProgram);
+ Q_UNUSED(d);
+ setUniformMatrix(d->glfuncs->glUniformMatrix3fv, location, value, 3, 3);
+}
+
+/*!
+ \overload
+
+ Sets the uniform variable called \a name in the current context
+ to a 3x3 matrix \a value.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValue(const char *name, const QMatrix3x3& value)
+{
+ setUniformValue(uniformLocation(name), value);
+}
+
+/*!
+ Sets the uniform variable at \a location in the current context
+ to a 3x4 matrix \a value.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix3x4& value)
+{
+ Q_D(QOpenGLShaderProgram);
+ Q_UNUSED(d);
+ setUniformGenericMatrix
+ (d->glfuncs->glUniform4fv, location, value, 3, 4);
+}
+
+/*!
+ \overload
+
+ Sets the uniform variable called \a name in the current context
+ to a 3x4 matrix \a value.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValue(const char *name, const QMatrix3x4& value)
+{
+ setUniformValue(uniformLocation(name), value);
+}
+
+/*!
+ Sets the uniform variable at \a location in the current context
+ to a 4x2 matrix \a value.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix4x2& value)
+{
+ Q_D(QOpenGLShaderProgram);
+ Q_UNUSED(d);
+ setUniformGenericMatrix
+ (d->glfuncs->glUniform2fv, location, value, 4, 2);
+}
+
+/*!
+ \overload
+
+ Sets the uniform variable called \a name in the current context
+ to a 4x2 matrix \a value.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValue(const char *name, const QMatrix4x2& value)
+{
+ setUniformValue(uniformLocation(name), value);
+}
+
+/*!
+ Sets the uniform variable at \a location in the current context
+ to a 4x3 matrix \a value.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix4x3& value)
+{
+ Q_D(QOpenGLShaderProgram);
+ Q_UNUSED(d);
+ setUniformGenericMatrix
+ (d->glfuncs->glUniform3fv, location, value, 4, 3);
+}
+
+/*!
+ \overload
+
+ Sets the uniform variable called \a name in the current context
+ to a 4x3 matrix \a value.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValue(const char *name, const QMatrix4x3& value)
+{
+ setUniformValue(uniformLocation(name), value);
+}
+
+/*!
+ Sets the uniform variable at \a location in the current context
+ to a 4x4 matrix \a value.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix4x4& value)
+{
+ Q_D(QOpenGLShaderProgram);
+ Q_UNUSED(d);
+ setUniformMatrix(d->glfuncs->glUniformMatrix4fv, location, value, 4, 4);
+}
+
+/*!
+ \overload
+
+ Sets the uniform variable called \a name in the current context
+ to a 4x4 matrix \a value.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValue(const char *name, const QMatrix4x4& value)
+{
+ setUniformValue(uniformLocation(name), value);
+}
+
+/*!
+ \overload
+
+ Sets the uniform variable at \a location in the current context
+ to a 2x2 matrix \a value. The matrix elements must be specified
+ in column-major order.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValue(int location, const GLfloat value[2][2])
+{
+ Q_D(QOpenGLShaderProgram);
+ Q_UNUSED(d);
+ if (location != -1)
+ d->glfuncs->glUniformMatrix2fv(location, 1, GL_FALSE, value[0]);
+}
+
+/*!
+ \overload
+
+ Sets the uniform variable at \a location in the current context
+ to a 3x3 matrix \a value. The matrix elements must be specified
+ in column-major order.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValue(int location, const GLfloat value[3][3])
+{
+ Q_D(QOpenGLShaderProgram);
+ Q_UNUSED(d);
+ if (location != -1)
+ d->glfuncs->glUniformMatrix3fv(location, 1, GL_FALSE, value[0]);
+}
+
+/*!
+ \overload
+
+ Sets the uniform variable at \a location in the current context
+ to a 4x4 matrix \a value. The matrix elements must be specified
+ in column-major order.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValue(int location, const GLfloat value[4][4])
+{
+ Q_D(QOpenGLShaderProgram);
+ Q_UNUSED(d);
+ if (location != -1)
+ d->glfuncs->glUniformMatrix4fv(location, 1, GL_FALSE, value[0]);
+}
+
+
+/*!
+ \overload
+
+ Sets the uniform variable called \a name in the current context
+ to a 2x2 matrix \a value. The matrix elements must be specified
+ in column-major order.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValue(const char *name, const GLfloat value[2][2])
+{
+ setUniformValue(uniformLocation(name), value);
+}
+
+/*!
+ \overload
+
+ Sets the uniform variable called \a name in the current context
+ to a 3x3 matrix \a value. The matrix elements must be specified
+ in column-major order.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValue(const char *name, const GLfloat value[3][3])
+{
+ setUniformValue(uniformLocation(name), value);
+}
+
+/*!
+ \overload
+
+ Sets the uniform variable called \a name in the current context
+ to a 4x4 matrix \a value. The matrix elements must be specified
+ in column-major order.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValue(const char *name, const GLfloat value[4][4])
+{
+ setUniformValue(uniformLocation(name), value);
+}
+
+/*!
+ Sets the uniform variable at \a location in the current context to a
+ 3x3 transformation matrix \a value that is specified as a QTransform value.
+
+ To set a QTransform value as a 4x4 matrix in a shader, use
+ \c{setUniformValue(location, QMatrix4x4(value))}.
+*/
+void QOpenGLShaderProgram::setUniformValue(int location, const QTransform& value)
+{
+ Q_D(QOpenGLShaderProgram);
+ Q_UNUSED(d);
+ if (location != -1) {
+ GLfloat mat[3][3] = {
+ {GLfloat(value.m11()), GLfloat(value.m12()), GLfloat(value.m13())},
+ {GLfloat(value.m21()), GLfloat(value.m22()), GLfloat(value.m23())},
+ {GLfloat(value.m31()), GLfloat(value.m32()), GLfloat(value.m33())}
+ };
+ d->glfuncs->glUniformMatrix3fv(location, 1, GL_FALSE, mat[0]);
+ }
+}
+
+/*!
+ \overload
+
+ Sets the uniform variable called \a name in the current context to a
+ 3x3 transformation matrix \a value that is specified as a QTransform value.
+
+ To set a QTransform value as a 4x4 matrix in a shader, use
+ \c{setUniformValue(name, QMatrix4x4(value))}.
+*/
+void QOpenGLShaderProgram::setUniformValue
+ (const char *name, const QTransform& value)
+{
+ setUniformValue(uniformLocation(name), value);
+}
+
+/*!
+ Sets the uniform variable array at \a location in the current
+ context to the \a count elements of \a values.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValueArray(int location, const GLint *values, int count)
+{
+ Q_D(QOpenGLShaderProgram);
+ Q_UNUSED(d);
+ if (location != -1)
+ d->glfuncs->glUniform1iv(location, count, values);
+}
+
+/*!
+ \overload
+
+ Sets the uniform variable array called \a name in the current
+ context to the \a count elements of \a values.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValueArray
+ (const char *name, const GLint *values, int count)
+{
+ setUniformValueArray(uniformLocation(name), values, count);
+}
+
+/*!
+ Sets the uniform variable array at \a location in the current
+ context to the \a count elements of \a values. This overload
+ should be used when setting an array of sampler values.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValueArray(int location, const GLuint *values, int count)
+{
+ Q_D(QOpenGLShaderProgram);
+ Q_UNUSED(d);
+ if (location != -1)
+ d->glfuncs->glUniform1iv(location, count, reinterpret_cast<const GLint *>(values));
+}
+
+/*!
+ \overload
+
+ Sets the uniform variable array called \a name in the current
+ context to the \a count elements of \a values. This overload
+ should be used when setting an array of sampler values.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValueArray
+ (const char *name, const GLuint *values, int count)
+{
+ setUniformValueArray(uniformLocation(name), values, count);
+}
+
+/*!
+ Sets the uniform variable array at \a location in the current
+ context to the \a count elements of \a values. Each element
+ has \a tupleSize components. The \a tupleSize must be 1, 2, 3, or 4.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValueArray(int location, const GLfloat *values, int count, int tupleSize)
+{
+ Q_D(QOpenGLShaderProgram);
+ Q_UNUSED(d);
+ if (location != -1) {
+ if (tupleSize == 1)
+ d->glfuncs->glUniform1fv(location, count, values);
+ else if (tupleSize == 2)
+ d->glfuncs->glUniform2fv(location, count, values);
+ else if (tupleSize == 3)
+ d->glfuncs->glUniform3fv(location, count, values);
+ else if (tupleSize == 4)
+ d->glfuncs->glUniform4fv(location, count, values);
+ else
+ qWarning() << "QOpenGLShaderProgram::setUniformValue: size" << tupleSize << "not supported";
+ }
+}
+
+/*!
+ \overload
+
+ Sets the uniform variable array called \a name in the current
+ context to the \a count elements of \a values. Each element
+ has \a tupleSize components. The \a tupleSize must be 1, 2, 3, or 4.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValueArray
+ (const char *name, const GLfloat *values, int count, int tupleSize)
+{
+ setUniformValueArray(uniformLocation(name), values, count, tupleSize);
+}
+
+/*!
+ Sets the uniform variable array at \a location in the current
+ context to the \a count 2D vector elements of \a values.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValueArray(int location, const QVector2D *values, int count)
+{
+ Q_D(QOpenGLShaderProgram);
+ Q_UNUSED(d);
+ if (location != -1)
+ d->glfuncs->glUniform2fv(location, count, reinterpret_cast<const GLfloat *>(values));
+}
+
+/*!
+ \overload
+
+ Sets the uniform variable array called \a name in the current
+ context to the \a count 2D vector elements of \a values.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValueArray(const char *name, const QVector2D *values, int count)
+{
+ setUniformValueArray(uniformLocation(name), values, count);
+}
+
+/*!
+ Sets the uniform variable array at \a location in the current
+ context to the \a count 3D vector elements of \a values.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValueArray(int location, const QVector3D *values, int count)
+{
+ Q_D(QOpenGLShaderProgram);
+ Q_UNUSED(d);
+ if (location != -1)
+ d->glfuncs->glUniform3fv(location, count, reinterpret_cast<const GLfloat *>(values));
+}
+
+/*!
+ \overload
+
+ Sets the uniform variable array called \a name in the current
+ context to the \a count 3D vector elements of \a values.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValueArray(const char *name, const QVector3D *values, int count)
+{
+ setUniformValueArray(uniformLocation(name), values, count);
+}
+
+/*!
+ Sets the uniform variable array at \a location in the current
+ context to the \a count 4D vector elements of \a values.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValueArray(int location, const QVector4D *values, int count)
+{
+ Q_D(QOpenGLShaderProgram);
+ Q_UNUSED(d);
+ if (location != -1)
+ d->glfuncs->glUniform4fv(location, count, reinterpret_cast<const GLfloat *>(values));
+}
+
+/*!
+ \overload
+
+ Sets the uniform variable array called \a name in the current
+ context to the \a count 4D vector elements of \a values.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValueArray(const char *name, const QVector4D *values, int count)
+{
+ setUniformValueArray(uniformLocation(name), values, count);
+}
+
+// We have to repack matrix arrays from qreal to GLfloat.
+#define setUniformMatrixArray(func,location,values,count,type,cols,rows) \
+ if (location == -1 || count <= 0) \
+ return; \
+ if (sizeof(type) == sizeof(GLfloat) * cols * rows) { \
+ func(location, count, GL_FALSE, \
+ reinterpret_cast<const GLfloat *>(values[0].constData())); \
+ } else { \
+ QVarLengthArray<GLfloat> temp(cols * rows * count); \
+ for (int index = 0; index < count; ++index) { \
+ for (int index2 = 0; index2 < (cols * rows); ++index2) { \
+ temp.data()[cols * rows * index + index2] = \
+ values[index].constData()[index2]; \
+ } \
+ } \
+ func(location, count, GL_FALSE, temp.constData()); \
+ }
+#define setUniformGenericMatrixArray(colfunc,location,values,count,type,cols,rows) \
+ if (location == -1 || count <= 0) \
+ return; \
+ if (sizeof(type) == sizeof(GLfloat) * cols * rows) { \
+ const GLfloat *data = reinterpret_cast<const GLfloat *> \
+ (values[0].constData()); \
+ colfunc(location, count * cols, data); \
+ } else { \
+ QVarLengthArray<GLfloat> temp(cols * rows * count); \
+ for (int index = 0; index < count; ++index) { \
+ for (int index2 = 0; index2 < (cols * rows); ++index2) { \
+ temp.data()[cols * rows * index + index2] = \
+ values[index].constData()[index2]; \
+ } \
+ } \
+ colfunc(location, count * cols, temp.constData()); \
+ }
+
+/*!
+ Sets the uniform variable array at \a location in the current
+ context to the \a count 2x2 matrix elements of \a values.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValueArray(int location, const QMatrix2x2 *values, int count)
+{
+ Q_D(QOpenGLShaderProgram);
+ Q_UNUSED(d);
+ setUniformMatrixArray
+ (d->glfuncs->glUniformMatrix2fv, location, values, count, QMatrix2x2, 2, 2);
+}
+
+/*!
+ \overload
+
+ Sets the uniform variable array called \a name in the current
+ context to the \a count 2x2 matrix elements of \a values.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValueArray(const char *name, const QMatrix2x2 *values, int count)
+{
+ setUniformValueArray(uniformLocation(name), values, count);
+}
+
+/*!
+ Sets the uniform variable array at \a location in the current
+ context to the \a count 2x3 matrix elements of \a values.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValueArray(int location, const QMatrix2x3 *values, int count)
+{
+ Q_D(QOpenGLShaderProgram);
+ Q_UNUSED(d);
+ setUniformGenericMatrixArray
+ (d->glfuncs->glUniform3fv, location, values, count,
+ QMatrix2x3, 2, 3);
+}
+
+/*!
+ \overload
+
+ Sets the uniform variable array called \a name in the current
+ context to the \a count 2x3 matrix elements of \a values.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValueArray(const char *name, const QMatrix2x3 *values, int count)
+{
+ setUniformValueArray(uniformLocation(name), values, count);
+}
+
+/*!
+ Sets the uniform variable array at \a location in the current
+ context to the \a count 2x4 matrix elements of \a values.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValueArray(int location, const QMatrix2x4 *values, int count)
+{
+ Q_D(QOpenGLShaderProgram);
+ Q_UNUSED(d);
+ setUniformGenericMatrixArray
+ (d->glfuncs->glUniform4fv, location, values, count,
+ QMatrix2x4, 2, 4);
+}
+
+/*!
+ \overload
+
+ Sets the uniform variable array called \a name in the current
+ context to the \a count 2x4 matrix elements of \a values.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValueArray(const char *name, const QMatrix2x4 *values, int count)
+{
+ setUniformValueArray(uniformLocation(name), values, count);
+}
+
+/*!
+ Sets the uniform variable array at \a location in the current
+ context to the \a count 3x2 matrix elements of \a values.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValueArray(int location, const QMatrix3x2 *values, int count)
+{
+ Q_D(QOpenGLShaderProgram);
+ Q_UNUSED(d);
+ setUniformGenericMatrixArray
+ (d->glfuncs->glUniform2fv, location, values, count,
+ QMatrix3x2, 3, 2);
+}
+
+/*!
+ \overload
+
+ Sets the uniform variable array called \a name in the current
+ context to the \a count 3x2 matrix elements of \a values.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValueArray(const char *name, const QMatrix3x2 *values, int count)
+{
+ setUniformValueArray(uniformLocation(name), values, count);
+}
+
+/*!
+ Sets the uniform variable array at \a location in the current
+ context to the \a count 3x3 matrix elements of \a values.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValueArray(int location, const QMatrix3x3 *values, int count)
+{
+ Q_D(QOpenGLShaderProgram);
+ Q_UNUSED(d);
+ setUniformMatrixArray
+ (d->glfuncs->glUniformMatrix3fv, location, values, count, QMatrix3x3, 3, 3);
+}
+
+/*!
+ \overload
+
+ Sets the uniform variable array called \a name in the current
+ context to the \a count 3x3 matrix elements of \a values.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValueArray(const char *name, const QMatrix3x3 *values, int count)
+{
+ setUniformValueArray(uniformLocation(name), values, count);
+}
+
+/*!
+ Sets the uniform variable array at \a location in the current
+ context to the \a count 3x4 matrix elements of \a values.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValueArray(int location, const QMatrix3x4 *values, int count)
+{
+ Q_D(QOpenGLShaderProgram);
+ Q_UNUSED(d);
+ setUniformGenericMatrixArray
+ (d->glfuncs->glUniform4fv, location, values, count,
+ QMatrix3x4, 3, 4);
+}
+
+/*!
+ \overload
+
+ Sets the uniform variable array called \a name in the current
+ context to the \a count 3x4 matrix elements of \a values.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValueArray(const char *name, const QMatrix3x4 *values, int count)
+{
+ setUniformValueArray(uniformLocation(name), values, count);
+}
+
+/*!
+ Sets the uniform variable array at \a location in the current
+ context to the \a count 4x2 matrix elements of \a values.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValueArray(int location, const QMatrix4x2 *values, int count)
+{
+ Q_D(QOpenGLShaderProgram);
+ Q_UNUSED(d);
+ setUniformGenericMatrixArray
+ (d->glfuncs->glUniform2fv, location, values, count,
+ QMatrix4x2, 4, 2);
+}
+
+/*!
+ \overload
+
+ Sets the uniform variable array called \a name in the current
+ context to the \a count 4x2 matrix elements of \a values.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValueArray(const char *name, const QMatrix4x2 *values, int count)
+{
+ setUniformValueArray(uniformLocation(name), values, count);
+}
+
+/*!
+ Sets the uniform variable array at \a location in the current
+ context to the \a count 4x3 matrix elements of \a values.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValueArray(int location, const QMatrix4x3 *values, int count)
+{
+ Q_D(QOpenGLShaderProgram);
+ Q_UNUSED(d);
+ setUniformGenericMatrixArray
+ (d->glfuncs->glUniform3fv, location, values, count,
+ QMatrix4x3, 4, 3);
+}
+
+/*!
+ \overload
+
+ Sets the uniform variable array called \a name in the current
+ context to the \a count 4x3 matrix elements of \a values.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValueArray(const char *name, const QMatrix4x3 *values, int count)
+{
+ setUniformValueArray(uniformLocation(name), values, count);
+}
+
+/*!
+ Sets the uniform variable array at \a location in the current
+ context to the \a count 4x4 matrix elements of \a values.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValueArray(int location, const QMatrix4x4 *values, int count)
+{
+ Q_D(QOpenGLShaderProgram);
+ Q_UNUSED(d);
+ setUniformMatrixArray
+ (d->glfuncs->glUniformMatrix4fv, location, values, count, QMatrix4x4, 4, 4);
+}
+
+/*!
+ \overload
+
+ Sets the uniform variable array called \a name in the current
+ context to the \a count 4x4 matrix elements of \a values.
+
+ \sa setAttributeValue()
+*/
+void QOpenGLShaderProgram::setUniformValueArray(const char *name, const QMatrix4x4 *values, int count)
+{
+ setUniformValueArray(uniformLocation(name), values, count);
+}
+
+/*!
+ Returns the hardware limit for how many vertices a geometry shader
+ can output.
+
+ \sa setGeometryOutputVertexCount()
+*/
+int QOpenGLShaderProgram::maxGeometryOutputVertices() const
+{
+ GLint n = 0;
+// glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT, &n);
+ return n;
+}
+
+/*!
+ Sets the maximum number of vertices the current geometry shader
+ program will produce, if active, to \a count.
+
+ This parameter takes effect the next time the program is linked.
+*/
+void QOpenGLShaderProgram::setGeometryOutputVertexCount(int count)
+{
+#ifndef QT_NO_DEBUG
+ int max = maxGeometryOutputVertices();
+ if (count > max) {
+ qWarning("QOpenGLShaderProgram::setGeometryOutputVertexCount: count: %d higher than maximum: %d",
+ count, max);
+ }
+#endif
+ d_func()->geometryVertexCount = count;
+}
+
+
+/*!
+ Returns the maximum number of vertices the current geometry shader
+ program will produce, if active.
+
+ This parameter takes effect the ntext time the program is linked.
+*/
+int QOpenGLShaderProgram::geometryOutputVertexCount() const
+{
+ return d_func()->geometryVertexCount;
+}
+
+
+/*!
+ Sets the input type from \a inputType.
+
+ This parameter takes effect the next time the program is linked.
+*/
+void QOpenGLShaderProgram::setGeometryInputType(GLenum inputType)
+{
+ d_func()->geometryInputType = inputType;
+}
+
+
+/*!
+ Returns the geometry shader input type, if active.
+
+ This parameter takes effect the next time the program is linked.
+ */
+
+GLenum QOpenGLShaderProgram::geometryInputType() const
+{
+ return d_func()->geometryInputType;
+}
+
+
+/*!
+ Sets the output type from the geometry shader, if active, to
+ \a outputType.
+
+ This parameter takes effect the next time the program is linked.
+*/
+void QOpenGLShaderProgram::setGeometryOutputType(GLenum outputType)
+{
+ d_func()->geometryOutputType = outputType;
+}
+
+
+/*!
+ Returns the geometry shader output type, if active.
+
+ This parameter takes effect the next time the program is linked.
+ */
+GLenum QOpenGLShaderProgram::geometryOutputType() const
+{
+ return d_func()->geometryOutputType;
+}
+
+
+/*!
+ Returns true if shader programs written in the OpenGL Shading
+ Language (GLSL) are supported on this system; false otherwise.
+
+ The \a context is used to resolve the GLSL extensions.
+ If \a context is null, then QOpenGLContext::currentContext() is used.
+*/
+bool QOpenGLShaderProgram::hasOpenGLShaderPrograms(QOpenGLContext *context)
+{
+#if !defined(QT_OPENGL_ES_2)
+ if (!context)
+ context = QOpenGLContext::currentContext();
+ if (!context)
+ return false;
+ return QOpenGLFunctions(context).hasOpenGLFeature(QOpenGLFunctions::Shaders);
+#else
+ Q_UNUSED(context);
+ return true;
+#endif
+}
+
+/*!
+ \internal
+*/
+void QOpenGLShaderProgram::shaderDestroyed()
+{
+ Q_D(QOpenGLShaderProgram);
+ QOpenGLShader *shader = qobject_cast<QOpenGLShader *>(sender());
+ if (shader && !d->removingShaders)
+ removeShader(shader);
+}
+
+/*!
+ Returns true if shader programs of type \a type are supported on
+ this system; false otherwise.
+
+ The \a context is used to resolve the GLSL extensions.
+ If \a context is null, then QOpenGLContext::currentContext() is used.
+*/
+bool QOpenGLShader::hasOpenGLShaders(ShaderType type, QOpenGLContext *context)
+{
+ if (!context)
+ context = QOpenGLContext::currentContext();
+ if (!context)
+ return false;
+
+ if ((type & ~(Geometry | Vertex | Fragment)) || type == 0)
+ return false;
+
+#if 0
+ bool resolved = qt_resolve_glsl_extensions(const_cast<QOpenGLContext *>(context));
+ if (!resolved)
+ return false;
+
+ if ((type & Geometry) && !QByteArray((const char *) glGetString(GL_EXTENSIONS)).contains("GL_EXT_geometry_shader4"))
+ return false;
+#endif
+
+ return true;
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/opengl/qopenglshaderprogram.h b/src/gui/opengl/qopenglshaderprogram.h
new file mode 100644
index 0000000000..4c123749a2
--- /dev/null
+++ b/src/gui/opengl/qopenglshaderprogram.h
@@ -0,0 +1,317 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QOPENGLSHADERPROGRAM_H
+#define QOPENGLSHADERPROGRAM_H
+
+#include <QtGui/qopengl.h>
+#include <QtGui/qvector2d.h>
+#include <QtGui/qvector3d.h>
+#include <QtGui/qvector4d.h>
+#include <QtGui/qmatrix4x4.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QOpenGLContext;
+class QOpenGLShaderProgram;
+class QOpenGLShaderPrivate;
+
+class Q_GUI_EXPORT QOpenGLShader : public QObject
+{
+ Q_OBJECT
+public:
+ enum ShaderTypeBit
+ {
+ Vertex = 0x0001,
+ Fragment = 0x0002,
+ Geometry = 0x0004
+ };
+ Q_DECLARE_FLAGS(ShaderType, ShaderTypeBit)
+
+ explicit QOpenGLShader(QOpenGLShader::ShaderType type, QObject *parent = 0);
+ virtual ~QOpenGLShader();
+
+ QOpenGLShader::ShaderType shaderType() const;
+
+ bool compileSourceCode(const char *source);
+ bool compileSourceCode(const QByteArray& source);
+ bool compileSourceCode(const QString& source);
+ bool compileSourceFile(const QString& fileName);
+
+ QByteArray sourceCode() const;
+
+ bool isCompiled() const;
+ QString log() const;
+
+ GLuint shaderId() const;
+
+ static bool hasOpenGLShaders(ShaderType type, QOpenGLContext *context = 0);
+
+private:
+ friend class QOpenGLShaderProgram;
+
+ Q_DISABLE_COPY(QOpenGLShader)
+ Q_DECLARE_PRIVATE(QOpenGLShader)
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QOpenGLShader::ShaderType)
+
+
+class QOpenGLShaderProgramPrivate;
+
+#ifndef GL_EXT_geometry_shader4
+# define GL_LINES_ADJACENCY_EXT 0xA
+# define GL_LINE_STRIP_ADJACENCY_EXT 0xB
+# define GL_TRIANGLES_ADJACENCY_EXT 0xC
+# define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0xD
+#endif
+
+
+class Q_GUI_EXPORT QOpenGLShaderProgram : public QObject
+{
+ Q_OBJECT
+public:
+ explicit QOpenGLShaderProgram(QObject *parent = 0);
+ virtual ~QOpenGLShaderProgram();
+
+ bool addShader(QOpenGLShader *shader);
+ void removeShader(QOpenGLShader *shader);
+ QList<QOpenGLShader *> shaders() const;
+
+ bool addShaderFromSourceCode(QOpenGLShader::ShaderType type, const char *source);
+ bool addShaderFromSourceCode(QOpenGLShader::ShaderType type, const QByteArray& source);
+ bool addShaderFromSourceCode(QOpenGLShader::ShaderType type, const QString& source);
+ bool addShaderFromSourceFile(QOpenGLShader::ShaderType type, const QString& fileName);
+
+ void removeAllShaders();
+
+ virtual bool link();
+ bool isLinked() const;
+ QString log() const;
+
+ bool bind();
+ void release();
+
+ GLuint programId() const;
+
+ int maxGeometryOutputVertices() const;
+
+ void setGeometryOutputVertexCount(int count);
+ int geometryOutputVertexCount() const;
+
+ void setGeometryInputType(GLenum inputType);
+ GLenum geometryInputType() const;
+
+ void setGeometryOutputType(GLenum outputType);
+ GLenum geometryOutputType() const;
+
+ void bindAttributeLocation(const char *name, int location);
+ void bindAttributeLocation(const QByteArray& name, int location);
+ void bindAttributeLocation(const QString& name, int location);
+
+ int attributeLocation(const char *name) const;
+ int attributeLocation(const QByteArray& name) const;
+ int attributeLocation(const QString& name) const;
+
+ void setAttributeValue(int location, GLfloat value);
+ void setAttributeValue(int location, GLfloat x, GLfloat y);
+ void setAttributeValue(int location, GLfloat x, GLfloat y, GLfloat z);
+ void setAttributeValue(int location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+ void setAttributeValue(int location, const QVector2D& value);
+ void setAttributeValue(int location, const QVector3D& value);
+ void setAttributeValue(int location, const QVector4D& value);
+ void setAttributeValue(int location, const QColor& value);
+ void setAttributeValue(int location, const GLfloat *values, int columns, int rows);
+
+ void setAttributeValue(const char *name, GLfloat value);
+ void setAttributeValue(const char *name, GLfloat x, GLfloat y);
+ void setAttributeValue(const char *name, GLfloat x, GLfloat y, GLfloat z);
+ void setAttributeValue(const char *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+ void setAttributeValue(const char *name, const QVector2D& value);
+ void setAttributeValue(const char *name, const QVector3D& value);
+ void setAttributeValue(const char *name, const QVector4D& value);
+ void setAttributeValue(const char *name, const QColor& value);
+ void setAttributeValue(const char *name, const GLfloat *values, int columns, int rows);
+
+ void setAttributeArray
+ (int location, const GLfloat *values, int tupleSize, int stride = 0);
+ void setAttributeArray
+ (int location, const QVector2D *values, int stride = 0);
+ void setAttributeArray
+ (int location, const QVector3D *values, int stride = 0);
+ void setAttributeArray
+ (int location, const QVector4D *values, int stride = 0);
+ void setAttributeArray
+ (int location, GLenum type, const void *values, int tupleSize, int stride = 0);
+ void setAttributeArray
+ (const char *name, const GLfloat *values, int tupleSize, int stride = 0);
+ void setAttributeArray
+ (const char *name, const QVector2D *values, int stride = 0);
+ void setAttributeArray
+ (const char *name, const QVector3D *values, int stride = 0);
+ void setAttributeArray
+ (const char *name, const QVector4D *values, int stride = 0);
+ void setAttributeArray
+ (const char *name, GLenum type, const void *values, int tupleSize, int stride = 0);
+
+ void setAttributeBuffer
+ (int location, GLenum type, int offset, int tupleSize, int stride = 0);
+ void setAttributeBuffer
+ (const char *name, GLenum type, int offset, int tupleSize, int stride = 0);
+
+ void enableAttributeArray(int location);
+ void enableAttributeArray(const char *name);
+ void disableAttributeArray(int location);
+ void disableAttributeArray(const char *name);
+
+ int uniformLocation(const char *name) const;
+ int uniformLocation(const QByteArray& name) const;
+ int uniformLocation(const QString& name) const;
+
+ void setUniformValue(int location, GLfloat value);
+ void setUniformValue(int location, GLint value);
+ void setUniformValue(int location, GLuint value);
+ void setUniformValue(int location, GLfloat x, GLfloat y);
+ void setUniformValue(int location, GLfloat x, GLfloat y, GLfloat z);
+ void setUniformValue(int location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+ void setUniformValue(int location, const QVector2D& value);
+ void setUniformValue(int location, const QVector3D& value);
+ void setUniformValue(int location, const QVector4D& value);
+ void setUniformValue(int location, const QColor& color);
+ void setUniformValue(int location, const QPoint& point);
+ void setUniformValue(int location, const QPointF& point);
+ void setUniformValue(int location, const QSize& size);
+ void setUniformValue(int location, const QSizeF& size);
+ void setUniformValue(int location, const QMatrix2x2& value);
+ void setUniformValue(int location, const QMatrix2x3& value);
+ void setUniformValue(int location, const QMatrix2x4& value);
+ void setUniformValue(int location, const QMatrix3x2& value);
+ void setUniformValue(int location, const QMatrix3x3& value);
+ void setUniformValue(int location, const QMatrix3x4& value);
+ void setUniformValue(int location, const QMatrix4x2& value);
+ void setUniformValue(int location, const QMatrix4x3& value);
+ void setUniformValue(int location, const QMatrix4x4& value);
+ void setUniformValue(int location, const GLfloat value[2][2]);
+ void setUniformValue(int location, const GLfloat value[3][3]);
+ void setUniformValue(int location, const GLfloat value[4][4]);
+ void setUniformValue(int location, const QTransform& value);
+
+ void setUniformValue(const char *name, GLfloat value);
+ void setUniformValue(const char *name, GLint value);
+ void setUniformValue(const char *name, GLuint value);
+ void setUniformValue(const char *name, GLfloat x, GLfloat y);
+ void setUniformValue(const char *name, GLfloat x, GLfloat y, GLfloat z);
+ void setUniformValue(const char *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+ void setUniformValue(const char *name, const QVector2D& value);
+ void setUniformValue(const char *name, const QVector3D& value);
+ void setUniformValue(const char *name, const QVector4D& value);
+ void setUniformValue(const char *name, const QColor& color);
+ void setUniformValue(const char *name, const QPoint& point);
+ void setUniformValue(const char *name, const QPointF& point);
+ void setUniformValue(const char *name, const QSize& size);
+ void setUniformValue(const char *name, const QSizeF& size);
+ void setUniformValue(const char *name, const QMatrix2x2& value);
+ void setUniformValue(const char *name, const QMatrix2x3& value);
+ void setUniformValue(const char *name, const QMatrix2x4& value);
+ void setUniformValue(const char *name, const QMatrix3x2& value);
+ void setUniformValue(const char *name, const QMatrix3x3& value);
+ void setUniformValue(const char *name, const QMatrix3x4& value);
+ void setUniformValue(const char *name, const QMatrix4x2& value);
+ void setUniformValue(const char *name, const QMatrix4x3& value);
+ void setUniformValue(const char *name, const QMatrix4x4& value);
+ void setUniformValue(const char *name, const GLfloat value[2][2]);
+ void setUniformValue(const char *name, const GLfloat value[3][3]);
+ void setUniformValue(const char *name, const GLfloat value[4][4]);
+ void setUniformValue(const char *name, const QTransform& value);
+
+ void setUniformValueArray(int location, const GLfloat *values, int count, int tupleSize);
+ void setUniformValueArray(int location, const GLint *values, int count);
+ void setUniformValueArray(int location, const GLuint *values, int count);
+ void setUniformValueArray(int location, const QVector2D *values, int count);
+ void setUniformValueArray(int location, const QVector3D *values, int count);
+ void setUniformValueArray(int location, const QVector4D *values, int count);
+ void setUniformValueArray(int location, const QMatrix2x2 *values, int count);
+ void setUniformValueArray(int location, const QMatrix2x3 *values, int count);
+ void setUniformValueArray(int location, const QMatrix2x4 *values, int count);
+ void setUniformValueArray(int location, const QMatrix3x2 *values, int count);
+ void setUniformValueArray(int location, const QMatrix3x3 *values, int count);
+ void setUniformValueArray(int location, const QMatrix3x4 *values, int count);
+ void setUniformValueArray(int location, const QMatrix4x2 *values, int count);
+ void setUniformValueArray(int location, const QMatrix4x3 *values, int count);
+ void setUniformValueArray(int location, const QMatrix4x4 *values, int count);
+
+ void setUniformValueArray(const char *name, const GLfloat *values, int count, int tupleSize);
+ void setUniformValueArray(const char *name, const GLint *values, int count);
+ void setUniformValueArray(const char *name, const GLuint *values, int count);
+ void setUniformValueArray(const char *name, const QVector2D *values, int count);
+ void setUniformValueArray(const char *name, const QVector3D *values, int count);
+ void setUniformValueArray(const char *name, const QVector4D *values, int count);
+ void setUniformValueArray(const char *name, const QMatrix2x2 *values, int count);
+ void setUniformValueArray(const char *name, const QMatrix2x3 *values, int count);
+ void setUniformValueArray(const char *name, const QMatrix2x4 *values, int count);
+ void setUniformValueArray(const char *name, const QMatrix3x2 *values, int count);
+ void setUniformValueArray(const char *name, const QMatrix3x3 *values, int count);
+ void setUniformValueArray(const char *name, const QMatrix3x4 *values, int count);
+ void setUniformValueArray(const char *name, const QMatrix4x2 *values, int count);
+ void setUniformValueArray(const char *name, const QMatrix4x3 *values, int count);
+ void setUniformValueArray(const char *name, const QMatrix4x4 *values, int count);
+
+ static bool hasOpenGLShaderPrograms(QOpenGLContext *context = 0);
+
+private Q_SLOTS:
+ void shaderDestroyed();
+
+private:
+ Q_DISABLE_COPY(QOpenGLShaderProgram)
+ Q_DECLARE_PRIVATE(QOpenGLShaderProgram)
+
+ bool init();
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/gui/opengl/qopengltexturecache.cpp b/src/gui/opengl/qopengltexturecache.cpp
new file mode 100644
index 0000000000..067b7a9e20
--- /dev/null
+++ b/src/gui/opengl/qopengltexturecache.cpp
@@ -0,0 +1,215 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qopengltexturecache_p.h"
+#include <private/qopenglcontext_p.h>
+#include <private/qimagepixmapcleanuphooks_p.h>
+#include <qplatformpixmap_qpa.h>
+
+QT_BEGIN_NAMESPACE
+
+class QOpenGLTextureCacheWrapper
+{
+public:
+ QOpenGLTextureCacheWrapper()
+ {
+ QImagePixmapCleanupHooks::instance()->addPlatformPixmapModificationHook(cleanupTexturesForPixmapData);
+ QImagePixmapCleanupHooks::instance()->addPlatformPixmapDestructionHook(cleanupTexturesForPixmapData);
+ QImagePixmapCleanupHooks::instance()->addImageHook(cleanupTexturesForCacheKey);
+ }
+
+ ~QOpenGLTextureCacheWrapper()
+ {
+ QImagePixmapCleanupHooks::instance()->removePlatformPixmapModificationHook(cleanupTexturesForPixmapData);
+ QImagePixmapCleanupHooks::instance()->removePlatformPixmapDestructionHook(cleanupTexturesForPixmapData);
+ QImagePixmapCleanupHooks::instance()->removeImageHook(cleanupTexturesForCacheKey);
+ }
+
+ QOpenGLTextureCache *cacheForContext(QOpenGLContext *context) {
+ QMutexLocker lock(&m_mutex);
+ return m_resource.value<QOpenGLTextureCache>(context);
+ }
+
+ static void cleanupTexturesForCacheKey(qint64 key);
+ static void cleanupTexturesForPixmapData(QPlatformPixmap *pmd);
+
+private:
+ QOpenGLMultiGroupSharedResource m_resource;
+ QMutex m_mutex;
+};
+
+Q_GLOBAL_STATIC(QOpenGLTextureCacheWrapper, qt_texture_caches)
+
+QOpenGLTextureCache *QOpenGLTextureCache::cacheForContext(QOpenGLContext *context)
+{
+ return qt_texture_caches()->cacheForContext(context);
+}
+
+void QOpenGLTextureCacheWrapper::cleanupTexturesForCacheKey(qint64 key)
+{
+ QList<QOpenGLSharedResource *> resources = qt_texture_caches()->m_resource.resources();
+ for (QList<QOpenGLSharedResource *>::iterator it = resources.begin(); it != resources.end(); ++it)
+ static_cast<QOpenGLTextureCache *>(*it)->invalidate(key);
+}
+
+void QOpenGLTextureCacheWrapper::cleanupTexturesForPixmapData(QPlatformPixmap *pmd)
+{
+ cleanupTexturesForCacheKey(pmd->cacheKey());
+}
+
+QOpenGLTextureCache::QOpenGLTextureCache(QOpenGLContext *ctx)
+ : QOpenGLSharedResource(ctx->shareGroup())
+ , m_cache(64 * 1024) // 64 MB cache
+{
+}
+
+QOpenGLTextureCache::~QOpenGLTextureCache()
+{
+}
+
+GLuint QOpenGLTextureCache::bindTexture(QOpenGLContext *context, const QPixmap &pixmap)
+{
+ QMutexLocker locker(&m_mutex);
+ qint64 key = pixmap.cacheKey();
+
+ // A QPainter is active on the image - take the safe route and replace the texture.
+ if (!pixmap.paintingActive()) {
+ QOpenGLCachedTexture *entry = m_cache.object(key);
+ if (entry) {
+ glBindTexture(GL_TEXTURE_2D, entry->id());
+ return entry->id();
+ }
+ }
+
+ GLuint id = bindTexture(context, key, pixmap.toImage());
+ if (id > 0)
+ QImagePixmapCleanupHooks::enableCleanupHooks(pixmap);
+
+ return id;
+}
+
+GLuint QOpenGLTextureCache::bindTexture(QOpenGLContext *context, const QImage &image)
+{
+ QMutexLocker locker(&m_mutex);
+ qint64 key = image.cacheKey();
+
+ // A QPainter is active on the image - take the safe route and replace the texture.
+ if (!image.paintingActive()) {
+ QOpenGLCachedTexture *entry = m_cache.object(key);
+ if (entry) {
+ glBindTexture(GL_TEXTURE_2D, entry->id());
+ return entry->id();
+ }
+ }
+
+ GLuint id = bindTexture(context, key, image);
+ if (id > 0)
+ QImagePixmapCleanupHooks::enableCleanupHooks(image);
+
+ return id;
+}
+
+static inline void qgl_byteSwapImage(QImage &img)
+{
+ const int width = img.width();
+ const int height = img.height();
+
+ if (QSysInfo::ByteOrder == QSysInfo::LittleEndian)
+ {
+ for (int i = 0; i < height; ++i) {
+ uint *p = (uint *) img.scanLine(i);
+ for (int x = 0; x < width; ++x)
+ p[x] = ((p[x] << 16) & 0xff0000) | ((p[x] >> 16) & 0xff) | (p[x] & 0xff00ff00);
+ }
+ } else {
+ for (int i = 0; i < height; ++i) {
+ uint *p = (uint *) img.scanLine(i);
+ for (int x = 0; x < width; ++x)
+ p[x] = (p[x] << 8) | (p[x] >> 24);
+ }
+ }
+}
+
+GLuint QOpenGLTextureCache::bindTexture(QOpenGLContext *context, qint64 key, const QImage &image)
+{
+ GLuint id;
+ glGenTextures(1, &id);
+ glBindTexture(GL_TEXTURE_2D, id);
+
+ QImage tx = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
+
+ qgl_byteSwapImage(tx);
+
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tx.width(), tx.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, const_cast<const QImage &>(tx).bits());
+
+ int cost = tx.width() * tx.height() * 4 / 1024;
+ m_cache.insert(key, new QOpenGLCachedTexture(id, context), cost);
+
+ return id;
+}
+
+void QOpenGLTextureCache::invalidate(qint64 key)
+{
+ QMutexLocker locker(&m_mutex);
+ m_cache.remove(key);
+}
+
+void QOpenGLTextureCache::invalidateResource()
+{
+ m_cache.clear();
+}
+
+void QOpenGLTextureCache::freeResource(QOpenGLContext *)
+{
+ Q_ASSERT(false); // the texture cache lives until the context group disappears
+}
+
+static void freeTexture(QOpenGLFunctions *, GLuint id)
+{
+ glDeleteTextures(1, &id);
+}
+
+QOpenGLCachedTexture::QOpenGLCachedTexture(GLuint id, QOpenGLContext *context)
+{
+ m_resource = new QOpenGLSharedResourceGuard(context, id, freeTexture);
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/opengl/qopengltexturecache_p.h b/src/gui/opengl/qopengltexturecache_p.h
new file mode 100644
index 0000000000..bdee9f4e83
--- /dev/null
+++ b/src/gui/opengl/qopengltexturecache_p.h
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QOPENGLTEXTURECACHE_P_H
+#define QOPENGLTEXTURECACHE_P_H
+
+#include <QHash>
+#include <QObject>
+#include <QtGui/QtGui>
+#include <private/qopenglcontext_p.h>
+#include <QtCore/qmutex.h>
+
+QT_BEGIN_NAMESPACE
+
+class QOpenGLCachedTexture
+{
+public:
+ QOpenGLCachedTexture(GLuint id, QOpenGLContext *context);
+ ~QOpenGLCachedTexture() { m_resource->free(); }
+
+ GLuint id() const { return m_resource->id(); }
+
+private:
+ QOpenGLSharedResourceGuard *m_resource;
+};
+
+class QOpenGLTextureCache : public QOpenGLSharedResource
+{
+public:
+ static QOpenGLTextureCache *cacheForContext(QOpenGLContext *context);
+
+ QOpenGLTextureCache(QOpenGLContext *);
+ ~QOpenGLTextureCache();
+
+ GLuint bindTexture(QOpenGLContext *context, const QPixmap &pixmap);
+ GLuint bindTexture(QOpenGLContext *context, const QImage &image);
+
+ void invalidate(qint64 key);
+
+ void invalidateResource();
+ void freeResource(QOpenGLContext *ctx);
+
+private:
+ GLuint bindTexture(QOpenGLContext *context, qint64 key, const QImage &image);
+
+ QMutex m_mutex;
+ QCache<quint64, QOpenGLCachedTexture> m_cache;
+};
+
+QT_END_NAMESPACE
+
+#endif
+
diff --git a/src/gui/opengl/qopengltextureglyphcache.cpp b/src/gui/opengl/qopengltextureglyphcache.cpp
new file mode 100644
index 0000000000..ffce6f55bb
--- /dev/null
+++ b/src/gui/opengl/qopengltextureglyphcache.cpp
@@ -0,0 +1,396 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qopengltextureglyphcache_p.h"
+#include "qopenglpaintengine_p.h"
+#include "private/qopenglengineshadersource_p.h"
+
+QT_BEGIN_NAMESPACE
+
+#ifdef Q_WS_WIN
+extern Q_GUI_EXPORT bool qt_cleartype_enabled;
+#endif
+
+QBasicAtomicInt qopengltextureglyphcache_serial_number = Q_BASIC_ATOMIC_INITIALIZER(1);
+
+QOpenGLTextureGlyphCache::QOpenGLTextureGlyphCache(QFontEngineGlyphCache::Type type, const QTransform &matrix)
+ : QImageTextureGlyphCache(type, matrix)
+ , pex(0)
+ , m_blitProgram(0)
+ , m_filterMode(Nearest)
+ , m_serialNumber(qopengltextureglyphcache_serial_number.fetchAndAddRelaxed(1))
+{
+#ifdef QT_GL_TEXTURE_GLYPH_CACHE_DEBUG
+ qDebug(" -> QOpenGLTextureGlyphCache() %p for context %p.", this, QOpenGLContext::currentContext());
+#endif
+ m_vertexCoordinateArray[0] = -1.0f;
+ m_vertexCoordinateArray[1] = -1.0f;
+ m_vertexCoordinateArray[2] = 1.0f;
+ m_vertexCoordinateArray[3] = -1.0f;
+ m_vertexCoordinateArray[4] = 1.0f;
+ m_vertexCoordinateArray[5] = 1.0f;
+ m_vertexCoordinateArray[6] = -1.0f;
+ m_vertexCoordinateArray[7] = 1.0f;
+
+ m_textureCoordinateArray[0] = 0.0f;
+ m_textureCoordinateArray[1] = 0.0f;
+ m_textureCoordinateArray[2] = 1.0f;
+ m_textureCoordinateArray[3] = 0.0f;
+ m_textureCoordinateArray[4] = 1.0f;
+ m_textureCoordinateArray[5] = 1.0f;
+ m_textureCoordinateArray[6] = 0.0f;
+ m_textureCoordinateArray[7] = 1.0f;
+}
+
+QOpenGLTextureGlyphCache::~QOpenGLTextureGlyphCache()
+{
+#ifdef QT_GL_TEXTURE_GLYPH_CACHE_DEBUG
+ qDebug(" -> ~QOpenGLTextureGlyphCache() %p.", this);
+#endif
+ delete m_blitProgram;
+}
+
+void QOpenGLTextureGlyphCache::createTextureData(int width, int height)
+{
+ QOpenGLContext *ctx = const_cast<QOpenGLContext *>(QOpenGLContext::currentContext());
+ if (ctx == 0) {
+ qWarning("QOpenGLTextureGlyphCache::createTextureData: Called with no context");
+ return;
+ }
+
+ // create in QImageTextureGlyphCache baseclass is meant to be called
+ // only to create the initial image and does not preserve the content,
+ // so we don't call when this function is called from resize.
+ if (ctx->d_func()->workaround_brokenFBOReadBack && image().isNull())
+ QImageTextureGlyphCache::createTextureData(width, height);
+
+ // Make the lower glyph texture size 16 x 16.
+ if (width < 16)
+ width = 16;
+ if (height < 16)
+ height = 16;
+
+ if (m_textureResource && !m_textureResource->m_texture)
+ delete m_textureResource;
+
+ if (!m_textureResource)
+ m_textureResource = new QOpenGLGlyphTexture(ctx);
+
+ glGenTextures(1, &m_textureResource->m_texture);
+ glBindTexture(GL_TEXTURE_2D, m_textureResource->m_texture);
+
+ m_textureResource->m_width = width;
+ m_textureResource->m_height = height;
+
+ if (m_type == QFontEngineGlyphCache::Raster_RGBMask) {
+ QVarLengthArray<uchar> data(width * height * 4);
+ for (int i = 0; i < data.size(); ++i)
+ data[i] = 0;
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
+ } else {
+ QVarLengthArray<uchar> data(width * height);
+ for (int i = 0; i < data.size(); ++i)
+ data[i] = 0;
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, &data[0]);
+ }
+
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ m_filterMode = Nearest;
+}
+
+void QOpenGLTextureGlyphCache::resizeTextureData(int width, int height)
+{
+ QOpenGLContext *ctx = QOpenGLContext::currentContext();
+ if (ctx == 0) {
+ qWarning("QOpenGLTextureGlyphCache::resizeTextureData: Called with no context");
+ return;
+ }
+
+ int oldWidth = m_textureResource->m_width;
+ int oldHeight = m_textureResource->m_height;
+
+ // Make the lower glyph texture size 16 x 16.
+ if (width < 16)
+ width = 16;
+ if (height < 16)
+ height = 16;
+
+ GLuint oldTexture = m_textureResource->m_texture;
+ createTextureData(width, height);
+
+ if (ctx->d_func()->workaround_brokenFBOReadBack) {
+ QImageTextureGlyphCache::resizeTextureData(width, height);
+ Q_ASSERT(image().depth() == 8);
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, oldHeight, GL_ALPHA, GL_UNSIGNED_BYTE, image().constBits());
+ glDeleteTextures(1, &oldTexture);
+ return;
+ }
+
+ // ### the QTextureGlyphCache API needs to be reworked to allow
+ // ### resizeTextureData to fail
+
+ QOpenGLFunctions funcs(ctx);
+
+ funcs.glBindFramebuffer(GL_FRAMEBUFFER, m_textureResource->m_fbo);
+
+ GLuint tmp_texture;
+ glGenTextures(1, &tmp_texture);
+ glBindTexture(GL_TEXTURE_2D, tmp_texture);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, oldWidth, oldHeight, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ m_filterMode = Nearest;
+ glBindTexture(GL_TEXTURE_2D, 0);
+ funcs.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ GL_TEXTURE_2D, tmp_texture, 0);
+
+ funcs.glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT);
+ glBindTexture(GL_TEXTURE_2D, oldTexture);
+
+ if (pex != 0)
+ pex->transferMode(BrushDrawingMode);
+
+ glDisable(GL_STENCIL_TEST);
+ glDisable(GL_DEPTH_TEST);
+ glDisable(GL_SCISSOR_TEST);
+ glDisable(GL_BLEND);
+
+ glViewport(0, 0, oldWidth, oldHeight);
+
+ QOpenGLShaderProgram *blitProgram = 0;
+ if (pex == 0) {
+ if (m_blitProgram == 0) {
+ m_blitProgram = new QOpenGLShaderProgram(ctx);
+
+ {
+ QString source;
+ source.append(QLatin1String(qopenglslMainWithTexCoordsVertexShader));
+ source.append(QLatin1String(qopenglslUntransformedPositionVertexShader));
+
+ QOpenGLShader *vertexShader = new QOpenGLShader(QOpenGLShader::Vertex, m_blitProgram);
+ vertexShader->compileSourceCode(source);
+
+ m_blitProgram->addShader(vertexShader);
+ }
+
+ {
+ QString source;
+ source.append(QLatin1String(qopenglslMainFragmentShader));
+ source.append(QLatin1String(qopenglslImageSrcFragmentShader));
+
+ QOpenGLShader *fragmentShader = new QOpenGLShader(QOpenGLShader::Fragment, m_blitProgram);
+ fragmentShader->compileSourceCode(source);
+
+ m_blitProgram->addShader(fragmentShader);
+ }
+
+ m_blitProgram->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR);
+ m_blitProgram->bindAttributeLocation("textureCoordArray", QT_TEXTURE_COORDS_ATTR);
+
+ m_blitProgram->link();
+ }
+
+ funcs.glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, m_vertexCoordinateArray);
+ funcs.glVertexAttribPointer(QT_TEXTURE_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, m_textureCoordinateArray);
+
+ m_blitProgram->bind();
+ m_blitProgram->enableAttributeArray(int(QT_VERTEX_COORDS_ATTR));
+ m_blitProgram->enableAttributeArray(int(QT_TEXTURE_COORDS_ATTR));
+ m_blitProgram->disableAttributeArray(int(QT_OPACITY_ATTR));
+
+ blitProgram = m_blitProgram;
+
+ } else {
+ pex->setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, m_vertexCoordinateArray);
+ pex->setVertexAttributePointer(QT_TEXTURE_COORDS_ATTR, m_textureCoordinateArray);
+
+ pex->shaderManager->useBlitProgram();
+ blitProgram = pex->shaderManager->blitProgram();
+ }
+
+ blitProgram->setUniformValue("imageTexture", QT_IMAGE_TEXTURE_UNIT);
+
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+ glBindTexture(GL_TEXTURE_2D, m_textureResource->m_texture);
+
+ glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, oldWidth, oldHeight);
+
+ funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ GL_RENDERBUFFER, 0);
+ glDeleteTextures(1, &tmp_texture);
+ glDeleteTextures(1, &oldTexture);
+
+ funcs.glBindFramebuffer(GL_FRAMEBUFFER, ctx->d_func()->current_fbo);
+
+ if (pex != 0) {
+ glViewport(0, 0, pex->width, pex->height);
+ pex->updateClipScissorTest();
+ }
+}
+
+void QOpenGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed subPixelPosition)
+{
+ QOpenGLContext *ctx = QOpenGLContext::currentContext();
+ if (ctx == 0) {
+ qWarning("QOpenGLTextureGlyphCache::fillTexture: Called with no context");
+ return;
+ }
+
+ if (ctx->d_func()->workaround_brokenFBOReadBack) {
+ QImageTextureGlyphCache::fillTexture(c, glyph, subPixelPosition);
+
+ glBindTexture(GL_TEXTURE_2D, m_textureResource->m_texture);
+ const QImage &texture = image();
+ const uchar *bits = texture.constBits();
+ bits += c.y * texture.bytesPerLine() + c.x;
+ for (int i=0; i<c.h; ++i) {
+ glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y + i, c.w, 1, GL_ALPHA, GL_UNSIGNED_BYTE, bits);
+ bits += texture.bytesPerLine();
+ }
+ return;
+ }
+
+ QImage mask = textureMapForGlyph(glyph, subPixelPosition);
+ const int maskWidth = mask.width();
+ const int maskHeight = mask.height();
+
+ if (mask.format() == QImage::Format_Mono) {
+ mask = mask.convertToFormat(QImage::Format_Indexed8);
+ for (int y = 0; y < maskHeight; ++y) {
+ uchar *src = (uchar *) mask.scanLine(y);
+ for (int x = 0; x < maskWidth; ++x)
+ src[x] = -src[x]; // convert 0 and 1 into 0 and 255
+ }
+ } else if (mask.format() == QImage::Format_RGB32) {
+ // Make the alpha component equal to the average of the RGB values.
+ // This is needed when drawing sub-pixel antialiased text on translucent targets.
+ for (int y = 0; y < maskHeight; ++y) {
+ quint32 *src = (quint32 *) mask.scanLine(y);
+ for (int x = 0; x < maskWidth; ++x) {
+ uchar r = src[x] >> 16;
+ uchar g = src[x] >> 8;
+ uchar b = src[x];
+ quint32 avg = (quint32(r) + quint32(g) + quint32(b) + 1) / 3; // "+1" for rounding.
+ src[x] = (src[x] & 0x00ffffff) | (avg << 24);
+ }
+ }
+ }
+
+ glBindTexture(GL_TEXTURE_2D, m_textureResource->m_texture);
+ if (mask.format() == QImage::Format_RGB32) {
+ glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, GL_BGRA, GL_UNSIGNED_BYTE, mask.bits());
+ } else {
+ // glTexSubImage2D() might cause some garbage to appear in the texture if the mask width is
+ // not a multiple of four bytes. The bug appeared on a computer with 32-bit Windows Vista
+ // and nVidia GeForce 8500GT. GL_UNPACK_ALIGNMENT is set to four bytes, 'mask' has a
+ // multiple of four bytes per line, and most of the glyph shows up correctly in the
+ // texture, which makes me think that this is a driver bug.
+ // One workaround is to make sure the mask width is a multiple of four bytes, for instance
+ // by converting it to a format with four bytes per pixel. Another is to copy one line at a
+ // time.
+
+#if 0
+ if (!ctx->d_func()->workaround_brokenAlphaTexSubImage_init) {
+ // don't know which driver versions exhibit this bug, so be conservative for now
+ const QByteArray versionString(reinterpret_cast<const char*>(glGetString(GL_VERSION)));
+ glctx->d_func()->workaround_brokenAlphaTexSubImage = versionString.indexOf("NVIDIA") >= 0;
+ glctx->d_func()->workaround_brokenAlphaTexSubImage_init = true;
+ }
+#endif
+
+#if 0
+ if (ctx->d_func()->workaround_brokenAlphaTexSubImage) {
+ for (int i = 0; i < maskHeight; ++i)
+ glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y + i, maskWidth, 1, GL_ALPHA, GL_UNSIGNED_BYTE, mask.scanLine(i));
+ } else {
+#endif
+ glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, GL_ALPHA, GL_UNSIGNED_BYTE, mask.bits());
+// }
+ }
+}
+
+int QOpenGLTextureGlyphCache::glyphPadding() const
+{
+ return 1;
+}
+
+int QOpenGLTextureGlyphCache::maxTextureWidth() const
+{
+ QOpenGLContext *ctx = const_cast<QOpenGLContext *>(QOpenGLContext::currentContext());
+ if (ctx == 0)
+ return QImageTextureGlyphCache::maxTextureWidth();
+ else
+ return ctx->d_func()->maxTextureSize();
+}
+
+int QOpenGLTextureGlyphCache::maxTextureHeight() const
+{
+ QOpenGLContext *ctx = const_cast<QOpenGLContext *>(QOpenGLContext::currentContext());
+ if (ctx == 0)
+ return QImageTextureGlyphCache::maxTextureHeight();
+
+ if (ctx->d_func()->workaround_brokenTexSubImage)
+ return qMin(1024, ctx->d_func()->maxTextureSize());
+ else
+ return ctx->d_func()->maxTextureSize();
+}
+
+void QOpenGLTextureGlyphCache::clear()
+{
+ m_textureResource->free();
+ m_textureResource = 0;
+
+ m_w = 0;
+ m_h = 0;
+ m_cx = 0;
+ m_cy = 0;
+ m_currentRowHeight = 0;
+ coords.clear();
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/opengl/qopengltextureglyphcache_p.h b/src/gui/opengl/qopengltextureglyphcache_p.h
new file mode 100644
index 0000000000..97f9ac3c64
--- /dev/null
+++ b/src/gui/opengl/qopengltextureglyphcache_p.h
@@ -0,0 +1,170 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QOPENTEXTUREGLYPHCACHE_P_H
+#define QOPENTEXTUREGLYPHCACHE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the QLibrary class. This header file may change from
+// version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <private/qtextureglyphcache_p.h>
+#include <private/qopenglcontext_p.h>
+#include <qopenglshaderprogram.h>
+#include <qopenglfunctions.h>
+
+// #define QT_GL_TEXTURE_GLYPH_CACHE_DEBUG
+
+QT_BEGIN_NAMESPACE
+
+class QOpenGL2PaintEngineExPrivate;
+
+class QOpenGLGlyphTexture : public QOpenGLSharedResource
+{
+public:
+ explicit QOpenGLGlyphTexture(QOpenGLContext *ctx)
+ : QOpenGLSharedResource(ctx->shareGroup())
+ , m_width(0)
+ , m_height(0)
+ {
+ if (ctx && !ctx->d_func()->workaround_brokenFBOReadBack)
+ QOpenGLFunctions(ctx).glGenFramebuffers(1, &m_fbo);
+
+#ifdef QT_GL_TEXTURE_GLYPH_CACHE_DEBUG
+ qDebug(" -> QOpenGLGlyphTexture() %p for context %p.", this, ctx);
+#endif
+ }
+
+ void freeResource(QOpenGLContext *context)
+ {
+ QOpenGLContext *ctx = context;
+#ifdef QT_GL_TEXTURE_GLYPH_CACHE_DEBUG
+ qDebug("~QOpenGLGlyphTexture() %p for context %p.", this, ctx);
+#endif
+ if (!ctx->d_func()->workaround_brokenFBOReadBack)
+ QOpenGLFunctions(ctx).glDeleteFramebuffers(1, &m_fbo);
+ if (m_width || m_height)
+ glDeleteTextures(1, &m_texture);
+ }
+
+ void invalidateResource()
+ {
+ m_texture = 0;
+ m_fbo = 0;
+ m_width = 0;
+ m_height = 0;
+ }
+
+ GLuint m_texture;
+ GLuint m_fbo;
+ int m_width;
+ int m_height;
+};
+
+class Q_GUI_EXPORT QOpenGLTextureGlyphCache : public QImageTextureGlyphCache
+{
+public:
+ QOpenGLTextureGlyphCache(QFontEngineGlyphCache::Type type, const QTransform &matrix);
+ ~QOpenGLTextureGlyphCache();
+
+ virtual void createTextureData(int width, int height);
+ virtual void resizeTextureData(int width, int height);
+ virtual void fillTexture(const Coord &c, glyph_t glyph, QFixed subPixelPosition);
+ virtual int glyphPadding() const;
+ virtual int maxTextureWidth() const;
+ virtual int maxTextureHeight() const;
+
+ inline GLuint texture() const {
+ QOpenGLTextureGlyphCache *that = const_cast<QOpenGLTextureGlyphCache *>(this);
+ QOpenGLGlyphTexture *glyphTexture = that->m_textureResource;
+ return glyphTexture ? glyphTexture->m_texture : 0;
+ }
+
+ inline int width() const {
+ QOpenGLTextureGlyphCache *that = const_cast<QOpenGLTextureGlyphCache *>(this);
+ QOpenGLGlyphTexture *glyphTexture = that->m_textureResource;
+ return glyphTexture ? glyphTexture->m_width : 0;
+ }
+ inline int height() const {
+ QOpenGLTextureGlyphCache *that = const_cast<QOpenGLTextureGlyphCache *>(this);
+ QOpenGLGlyphTexture *glyphTexture = that->m_textureResource;
+ return glyphTexture ? glyphTexture->m_height : 0;
+ }
+
+ inline void setPaintEnginePrivate(QOpenGL2PaintEngineExPrivate *p) { pex = p; }
+
+ inline const QOpenGLContextGroup *contextGroup() const { return m_textureResource ? m_textureResource->group() : 0; }
+
+ inline int serialNumber() const { return m_serialNumber; }
+
+ enum FilterMode {
+ Nearest,
+ Linear
+ };
+ FilterMode filterMode() const { return m_filterMode; }
+ void setFilterMode(FilterMode m) { m_filterMode = m; }
+
+ void clear();
+
+private:
+ QOpenGLGlyphTexture *m_textureResource;
+
+ QOpenGL2PaintEngineExPrivate *pex;
+ QOpenGLShaderProgram *m_blitProgram;
+ FilterMode m_filterMode;
+
+ GLfloat m_vertexCoordinateArray[8];
+ GLfloat m_textureCoordinateArray[8];
+
+ int m_serialNumber;
+};
+
+QT_END_NAMESPACE
+
+#endif
+
diff --git a/src/gui/opengl/qopengltriangulatingstroker.cpp b/src/gui/opengl/qopengltriangulatingstroker.cpp
new file mode 100644
index 0000000000..3dc3452b60
--- /dev/null
+++ b/src/gui/opengl/qopengltriangulatingstroker.cpp
@@ -0,0 +1,588 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qopengltriangulatingstroker_p.h"
+#include <qmath.h>
+
+QT_BEGIN_NAMESPACE
+
+#define CURVE_FLATNESS Q_PI / 8
+
+
+
+
+void QTriangulatingStroker::endCapOrJoinClosed(const qreal *start, const qreal *cur,
+ bool implicitClose, bool endsAtStart)
+{
+ if (endsAtStart) {
+ join(start + 2);
+ } else if (implicitClose) {
+ join(start);
+ lineTo(start);
+ join(start+2);
+ } else {
+ endCap(cur);
+ }
+ int count = m_vertices.size();
+
+ // Copy the (x, y) values because QDataBuffer::add(const float& t)
+ // may resize the buffer, which will leave t pointing at the
+ // previous buffer's memory region if we don't copy first.
+ float x = m_vertices.at(count-2);
+ float y = m_vertices.at(count-1);
+ m_vertices.add(x);
+ m_vertices.add(y);
+}
+
+
+void QTriangulatingStroker::process(const QVectorPath &path, const QPen &pen, const QRectF &)
+{
+ const qreal *pts = path.points();
+ const QPainterPath::ElementType *types = path.elements();
+ int count = path.elementCount();
+ if (count < 2)
+ return;
+
+ float realWidth = qpen_widthf(pen);
+ if (realWidth == 0)
+ realWidth = 1;
+
+ m_width = realWidth / 2;
+
+ bool cosmetic = pen.isCosmetic();
+ if (cosmetic) {
+ m_width = m_width * m_inv_scale;
+ }
+
+ m_join_style = qpen_joinStyle(pen);
+ m_cap_style = qpen_capStyle(pen);
+ m_vertices.reset();
+ m_miter_limit = pen.miterLimit() * qpen_widthf(pen);
+
+ // The curvyness is based on the notion that I originally wanted
+ // roughly one line segment pr 4 pixels. This may seem little, but
+ // because we sample at constantly incrementing B(t) E [0<t<1], we
+ // will get longer segments where the curvature is small and smaller
+ // segments when the curvature is high.
+ //
+ // To get a rough idea of the length of each curve, I pretend that
+ // the curve is a 90 degree arc, whose radius is
+ // qMax(curveBounds.width, curveBounds.height). Based on this
+ // logic we can estimate the length of the outline edges based on
+ // the radius + a pen width and adjusting for scale factors
+ // depending on if the pen is cosmetic or not.
+ //
+ // The curvyness value of PI/14 was based on,
+ // arcLength = 2*PI*r/4 = PI*r/2 and splitting length into somewhere
+ // between 3 and 8 where 5 seemed to be give pretty good results
+ // hence: Q_PI/14. Lower divisors will give more detail at the
+ // direct cost of performance.
+
+ // simplfy pens that are thin in device size (2px wide or less)
+ if (realWidth < 2.5 && (cosmetic || m_inv_scale == 1)) {
+ if (m_cap_style == Qt::RoundCap)
+ m_cap_style = Qt::SquareCap;
+ if (m_join_style == Qt::RoundJoin)
+ m_join_style = Qt::MiterJoin;
+ m_curvyness_add = 0.5;
+ m_curvyness_mul = CURVE_FLATNESS / m_inv_scale;
+ m_roundness = 1;
+ } else if (cosmetic) {
+ m_curvyness_add = realWidth / 2;
+ m_curvyness_mul = CURVE_FLATNESS;
+ m_roundness = qMax<int>(4, realWidth * CURVE_FLATNESS);
+ } else {
+ m_curvyness_add = m_width;
+ m_curvyness_mul = CURVE_FLATNESS / m_inv_scale;
+ m_roundness = qMax<int>(4, realWidth * m_curvyness_mul);
+ }
+
+ // Over this level of segmentation, there doesn't seem to be any
+ // benefit, even for huge penWidth
+ if (m_roundness > 24)
+ m_roundness = 24;
+
+ m_sin_theta = qFastSin(Q_PI / m_roundness);
+ m_cos_theta = qFastCos(Q_PI / m_roundness);
+
+ const qreal *endPts = pts + (count<<1);
+ const qreal *startPts = 0;
+
+ Qt::PenCapStyle cap = m_cap_style;
+
+ if (!types) {
+ // skip duplicate points
+ while((pts + 2) < endPts && pts[0] == pts[2] && pts[1] == pts[3])
+ pts += 2;
+ if ((pts + 2) == endPts)
+ return;
+
+ startPts = pts;
+
+ bool endsAtStart = startPts[0] == *(endPts-2) && startPts[1] == *(endPts-1);
+
+ if (endsAtStart || path.hasImplicitClose())
+ m_cap_style = Qt::FlatCap;
+ moveTo(pts);
+ m_cap_style = cap;
+ pts += 2;
+ lineTo(pts);
+ pts += 2;
+ while (pts < endPts) {
+ if (m_cx != pts[0] || m_cy != pts[1]) {
+ join(pts);
+ lineTo(pts);
+ }
+ pts += 2;
+ }
+
+ endCapOrJoinClosed(startPts, pts-2, path.hasImplicitClose(), endsAtStart);
+
+ } else {
+ bool endsAtStart = false;
+ while (pts < endPts) {
+ switch (*types) {
+ case QPainterPath::MoveToElement: {
+ if (pts != path.points())
+ endCapOrJoinClosed(startPts, pts-2, path.hasImplicitClose(), endsAtStart);
+
+ startPts = pts;
+ int end = (endPts - pts) / 2;
+ int i = 2; // Start looking to ahead since we never have two moveto's in a row
+ while (i<end && types[i] != QPainterPath::MoveToElement) {
+ ++i;
+ }
+ endsAtStart = startPts[0] == pts[i*2 - 2] && startPts[1] == pts[i*2 - 1];
+ if (endsAtStart || path.hasImplicitClose())
+ m_cap_style = Qt::FlatCap;
+
+ moveTo(pts);
+ m_cap_style = cap;
+ pts+=2;
+ ++types;
+ break; }
+ case QPainterPath::LineToElement:
+ if (*(types - 1) != QPainterPath::MoveToElement)
+ join(pts);
+ lineTo(pts);
+ pts+=2;
+ ++types;
+ break;
+ case QPainterPath::CurveToElement:
+ if (*(types - 1) != QPainterPath::MoveToElement)
+ join(pts);
+ cubicTo(pts);
+ pts+=6;
+ types+=3;
+ break;
+ default:
+ Q_ASSERT(false);
+ break;
+ }
+ }
+
+ endCapOrJoinClosed(startPts, pts-2, path.hasImplicitClose(), endsAtStart);
+ }
+}
+
+void QTriangulatingStroker::moveTo(const qreal *pts)
+{
+ m_cx = pts[0];
+ m_cy = pts[1];
+
+ float x2 = pts[2];
+ float y2 = pts[3];
+ normalVector(m_cx, m_cy, x2, y2, &m_nvx, &m_nvy);
+
+
+ // To acheive jumps we insert zero-area tringles. This is done by
+ // adding two identical points in both the end of previous strip
+ // and beginning of next strip
+ bool invisibleJump = m_vertices.size();
+
+ switch (m_cap_style) {
+ case Qt::FlatCap:
+ if (invisibleJump) {
+ m_vertices.add(m_cx + m_nvx);
+ m_vertices.add(m_cy + m_nvy);
+ }
+ break;
+ case Qt::SquareCap: {
+ float sx = m_cx - m_nvy;
+ float sy = m_cy + m_nvx;
+ if (invisibleJump) {
+ m_vertices.add(sx + m_nvx);
+ m_vertices.add(sy + m_nvy);
+ }
+ emitLineSegment(sx, sy, m_nvx, m_nvy);
+ break; }
+ case Qt::RoundCap: {
+ QVarLengthArray<float> points;
+ arcPoints(m_cx, m_cy, m_cx + m_nvx, m_cy + m_nvy, m_cx - m_nvx, m_cy - m_nvy, points);
+ m_vertices.resize(m_vertices.size() + points.size() + 2 * int(invisibleJump));
+ int count = m_vertices.size();
+ int front = 0;
+ int end = points.size() / 2;
+ while (front != end) {
+ m_vertices.at(--count) = points[2 * end - 1];
+ m_vertices.at(--count) = points[2 * end - 2];
+ --end;
+ if (front == end)
+ break;
+ m_vertices.at(--count) = points[2 * front + 1];
+ m_vertices.at(--count) = points[2 * front + 0];
+ ++front;
+ }
+
+ if (invisibleJump) {
+ m_vertices.at(count - 1) = m_vertices.at(count + 1);
+ m_vertices.at(count - 2) = m_vertices.at(count + 0);
+ }
+ break; }
+ default: break; // ssssh gcc...
+ }
+ emitLineSegment(m_cx, m_cy, m_nvx, m_nvy);
+}
+
+void QTriangulatingStroker::cubicTo(const qreal *pts)
+{
+ const QPointF *p = (const QPointF *) pts;
+ QBezier bezier = QBezier::fromPoints(*(p - 1), p[0], p[1], p[2]);
+
+ QRectF bounds = bezier.bounds();
+ float rad = qMax(bounds.width(), bounds.height());
+ int threshold = qMin<float>(64, (rad + m_curvyness_add) * m_curvyness_mul);
+ if (threshold < 4)
+ threshold = 4;
+ qreal threshold_minus_1 = threshold - 1;
+ float vx, vy;
+
+ float cx = m_cx, cy = m_cy;
+ float x, y;
+
+ for (int i=1; i<threshold; ++i) {
+ qreal t = qreal(i) / threshold_minus_1;
+ QPointF p = bezier.pointAt(t);
+ x = p.x();
+ y = p.y();
+
+ normalVector(cx, cy, x, y, &vx, &vy);
+
+ emitLineSegment(x, y, vx, vy);
+
+ cx = x;
+ cy = y;
+ }
+
+ m_cx = cx;
+ m_cy = cy;
+
+ m_nvx = vx;
+ m_nvy = vy;
+}
+
+void QTriangulatingStroker::join(const qreal *pts)
+{
+ // Creates a join to the next segment (m_cx, m_cy) -> (pts[0], pts[1])
+ normalVector(m_cx, m_cy, pts[0], pts[1], &m_nvx, &m_nvy);
+
+ switch (m_join_style) {
+ case Qt::BevelJoin:
+ break;
+ case Qt::SvgMiterJoin:
+ case Qt::MiterJoin: {
+ // Find out on which side the join should be.
+ int count = m_vertices.size();
+ float prevNvx = m_vertices.at(count - 2) - m_cx;
+ float prevNvy = m_vertices.at(count - 1) - m_cy;
+ float xprod = prevNvx * m_nvy - prevNvy * m_nvx;
+ float px, py, qx, qy;
+
+ // If the segments are parallel, use bevel join.
+ if (qFuzzyIsNull(xprod))
+ break;
+
+ // Find the corners of the previous and next segment to join.
+ if (xprod < 0) {
+ px = m_vertices.at(count - 2);
+ py = m_vertices.at(count - 1);
+ qx = m_cx - m_nvx;
+ qy = m_cy - m_nvy;
+ } else {
+ px = m_vertices.at(count - 4);
+ py = m_vertices.at(count - 3);
+ qx = m_cx + m_nvx;
+ qy = m_cy + m_nvy;
+ }
+
+ // Find intersection point.
+ float pu = px * prevNvx + py * prevNvy;
+ float qv = qx * m_nvx + qy * m_nvy;
+ float ix = (m_nvy * pu - prevNvy * qv) / xprod;
+ float iy = (prevNvx * qv - m_nvx * pu) / xprod;
+
+ // Check that the distance to the intersection point is less than the miter limit.
+ if ((ix - px) * (ix - px) + (iy - py) * (iy - py) <= m_miter_limit * m_miter_limit) {
+ m_vertices.add(ix);
+ m_vertices.add(iy);
+ m_vertices.add(ix);
+ m_vertices.add(iy);
+ }
+ // else
+ // Do a plain bevel join if the miter limit is exceeded or if
+ // the lines are parallel. This is not what the raster
+ // engine's stroker does, but it is both faster and similar to
+ // what some other graphics API's do.
+
+ break; }
+ case Qt::RoundJoin: {
+ QVarLengthArray<float> points;
+ int count = m_vertices.size();
+ float prevNvx = m_vertices.at(count - 2) - m_cx;
+ float prevNvy = m_vertices.at(count - 1) - m_cy;
+ if (m_nvx * prevNvy - m_nvy * prevNvx < 0) {
+ arcPoints(0, 0, m_nvx, m_nvy, -prevNvx, -prevNvy, points);
+ for (int i = points.size() / 2; i > 0; --i)
+ emitLineSegment(m_cx, m_cy, points[2 * i - 2], points[2 * i - 1]);
+ } else {
+ arcPoints(0, 0, -prevNvx, -prevNvy, m_nvx, m_nvy, points);
+ for (int i = 0; i < points.size() / 2; ++i)
+ emitLineSegment(m_cx, m_cy, points[2 * i + 0], points[2 * i + 1]);
+ }
+ break; }
+ default: break; // gcc warn--
+ }
+
+ emitLineSegment(m_cx, m_cy, m_nvx, m_nvy);
+}
+
+void QTriangulatingStroker::endCap(const qreal *)
+{
+ switch (m_cap_style) {
+ case Qt::FlatCap:
+ break;
+ case Qt::SquareCap:
+ emitLineSegment(m_cx + m_nvy, m_cy - m_nvx, m_nvx, m_nvy);
+ break;
+ case Qt::RoundCap: {
+ QVarLengthArray<float> points;
+ int count = m_vertices.size();
+ arcPoints(m_cx, m_cy, m_vertices.at(count - 2), m_vertices.at(count - 1), m_vertices.at(count - 4), m_vertices.at(count - 3), points);
+ int front = 0;
+ int end = points.size() / 2;
+ while (front != end) {
+ m_vertices.add(points[2 * end - 2]);
+ m_vertices.add(points[2 * end - 1]);
+ --end;
+ if (front == end)
+ break;
+ m_vertices.add(points[2 * front + 0]);
+ m_vertices.add(points[2 * front + 1]);
+ ++front;
+ }
+ break; }
+ default: break; // to shut gcc up...
+ }
+}
+
+void QTriangulatingStroker::arcPoints(float cx, float cy, float fromX, float fromY, float toX, float toY, QVarLengthArray<float> &points)
+{
+ float dx1 = fromX - cx;
+ float dy1 = fromY - cy;
+ float dx2 = toX - cx;
+ float dy2 = toY - cy;
+
+ // while more than 180 degrees left:
+ while (dx1 * dy2 - dx2 * dy1 < 0) {
+ float tmpx = dx1 * m_cos_theta - dy1 * m_sin_theta;
+ float tmpy = dx1 * m_sin_theta + dy1 * m_cos_theta;
+ dx1 = tmpx;
+ dy1 = tmpy;
+ points.append(cx + dx1);
+ points.append(cy + dy1);
+ }
+
+ // while more than 90 degrees left:
+ while (dx1 * dx2 + dy1 * dy2 < 0) {
+ float tmpx = dx1 * m_cos_theta - dy1 * m_sin_theta;
+ float tmpy = dx1 * m_sin_theta + dy1 * m_cos_theta;
+ dx1 = tmpx;
+ dy1 = tmpy;
+ points.append(cx + dx1);
+ points.append(cy + dy1);
+ }
+
+ // while more than 0 degrees left:
+ while (dx1 * dy2 - dx2 * dy1 > 0) {
+ float tmpx = dx1 * m_cos_theta - dy1 * m_sin_theta;
+ float tmpy = dx1 * m_sin_theta + dy1 * m_cos_theta;
+ dx1 = tmpx;
+ dy1 = tmpy;
+ points.append(cx + dx1);
+ points.append(cy + dy1);
+ }
+
+ // remove last point which was rotated beyond [toX, toY].
+ if (!points.isEmpty())
+ points.resize(points.size() - 2);
+}
+
+static void qdashprocessor_moveTo(qreal x, qreal y, void *data)
+{
+ ((QDashedStrokeProcessor *) data)->addElement(QPainterPath::MoveToElement, x, y);
+}
+
+static void qdashprocessor_lineTo(qreal x, qreal y, void *data)
+{
+ ((QDashedStrokeProcessor *) data)->addElement(QPainterPath::LineToElement, x, y);
+}
+
+static void qdashprocessor_cubicTo(qreal, qreal, qreal, qreal, qreal, qreal, void *)
+{
+ Q_ASSERT(0); // The dasher should not produce curves...
+}
+
+QDashedStrokeProcessor::QDashedStrokeProcessor()
+ : m_points(0), m_types(0),
+ m_dash_stroker(0), m_inv_scale(1)
+{
+ m_dash_stroker.setMoveToHook(qdashprocessor_moveTo);
+ m_dash_stroker.setLineToHook(qdashprocessor_lineTo);
+ m_dash_stroker.setCubicToHook(qdashprocessor_cubicTo);
+}
+
+void QDashedStrokeProcessor::process(const QVectorPath &path, const QPen &pen, const QRectF &clip)
+{
+
+ const qreal *pts = path.points();
+ const QPainterPath::ElementType *types = path.elements();
+ int count = path.elementCount();
+
+ bool cosmetic = pen.isCosmetic();
+
+ m_points.reset();
+ m_types.reset();
+ m_points.reserve(path.elementCount());
+ m_types.reserve(path.elementCount());
+
+ qreal width = qpen_widthf(pen);
+ if (width == 0)
+ width = 1;
+
+ m_dash_stroker.setDashPattern(pen.dashPattern());
+ m_dash_stroker.setStrokeWidth(cosmetic ? width * m_inv_scale : width);
+ m_dash_stroker.setDashOffset(pen.dashOffset());
+ m_dash_stroker.setMiterLimit(pen.miterLimit());
+ m_dash_stroker.setClipRect(clip);
+
+ float curvynessAdd, curvynessMul, roundness = 0;
+
+ // simplfy pens that are thin in device size (2px wide or less)
+ if (width < 2.5 && (cosmetic || m_inv_scale == 1)) {
+ curvynessAdd = 0.5;
+ curvynessMul = CURVE_FLATNESS / m_inv_scale;
+ roundness = 1;
+ } else if (cosmetic) {
+ curvynessAdd= width / 2;
+ curvynessMul= CURVE_FLATNESS;
+ roundness = qMax<int>(4, width * CURVE_FLATNESS);
+ } else {
+ curvynessAdd = width * m_inv_scale;
+ curvynessMul = CURVE_FLATNESS / m_inv_scale;
+ roundness = qMax<int>(4, width * curvynessMul);
+ }
+
+ if (count < 2)
+ return;
+
+ const qreal *endPts = pts + (count<<1);
+
+ m_dash_stroker.begin(this);
+
+ if (!types) {
+ m_dash_stroker.moveTo(pts[0], pts[1]);
+ pts += 2;
+ while (pts < endPts) {
+ m_dash_stroker.lineTo(pts[0], pts[1]);
+ pts += 2;
+ }
+ } else {
+ while (pts < endPts) {
+ switch (*types) {
+ case QPainterPath::MoveToElement:
+ m_dash_stroker.moveTo(pts[0], pts[1]);
+ pts += 2;
+ ++types;
+ break;
+ case QPainterPath::LineToElement:
+ m_dash_stroker.lineTo(pts[0], pts[1]);
+ pts += 2;
+ ++types;
+ break;
+ case QPainterPath::CurveToElement: {
+ QBezier b = QBezier::fromPoints(*(((const QPointF *) pts) - 1),
+ *(((const QPointF *) pts)),
+ *(((const QPointF *) pts) + 1),
+ *(((const QPointF *) pts) + 2));
+ QRectF bounds = b.bounds();
+ float rad = qMax(bounds.width(), bounds.height());
+ int threshold = qMin<float>(64, (rad + curvynessAdd) * curvynessMul);
+ if (threshold < 4)
+ threshold = 4;
+
+ qreal threshold_minus_1 = threshold - 1;
+ for (int i=0; i<threshold; ++i) {
+ QPointF pt = b.pointAt(i / threshold_minus_1);
+ m_dash_stroker.lineTo(pt.x(), pt.y());
+ }
+ pts += 6;
+ types += 3;
+ break; }
+ default: break;
+ }
+ }
+ }
+
+ m_dash_stroker.end();
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/gui/opengl/qopengltriangulatingstroker_p.h b/src/gui/opengl/qopengltriangulatingstroker_p.h
new file mode 100644
index 0000000000..abb10957c0
--- /dev/null
+++ b/src/gui/opengl/qopengltriangulatingstroker_p.h
@@ -0,0 +1,157 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QOPENGLTRIANGULATINGSTROKER_P_H
+#define QOPENGLTRIANGULATINGSTROKER_P_H
+
+#include <private/qdatabuffer_p.h>
+#include <qvarlengtharray.h>
+#include <private/qvectorpath_p.h>
+#include <private/qbezier_p.h>
+#include <private/qnumeric_p.h>
+#include <private/qmath_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QTriangulatingStroker
+{
+public:
+ QTriangulatingStroker() : m_vertices(0) {}
+ void process(const QVectorPath &path, const QPen &pen, const QRectF &clip);
+
+ inline int vertexCount() const { return m_vertices.size(); }
+ inline const float *vertices() const { return m_vertices.data(); }
+
+ inline void setInvScale(qreal invScale) { m_inv_scale = invScale; }
+
+private:
+ inline void emitLineSegment(float x, float y, float nx, float ny);
+ void moveTo(const qreal *pts);
+ inline void lineTo(const qreal *pts);
+ void cubicTo(const qreal *pts);
+ void join(const qreal *pts);
+ inline void normalVector(float x1, float y1, float x2, float y2, float *nx, float *ny);
+ void endCap(const qreal *pts);
+ void arcPoints(float cx, float cy, float fromX, float fromY, float toX, float toY, QVarLengthArray<float> &points);
+ void endCapOrJoinClosed(const qreal *start, const qreal *cur, bool implicitClose, bool endsAtStart);
+
+
+ QDataBuffer<float> m_vertices;
+
+ float m_cx, m_cy; // current points
+ float m_nvx, m_nvy; // normal vector...
+ float m_width;
+ qreal m_miter_limit;
+
+ int m_roundness; // Number of line segments in a round join
+ qreal m_sin_theta; // sin(m_roundness / 360);
+ qreal m_cos_theta; // cos(m_roundness / 360);
+ qreal m_inv_scale;
+ float m_curvyness_mul;
+ float m_curvyness_add;
+
+ Qt::PenJoinStyle m_join_style;
+ Qt::PenCapStyle m_cap_style;
+};
+
+class QDashedStrokeProcessor
+{
+public:
+ QDashedStrokeProcessor();
+
+ void process(const QVectorPath &path, const QPen &pen, const QRectF &clip);
+
+ inline void addElement(QPainterPath::ElementType type, qreal x, qreal y) {
+ m_points.add(x);
+ m_points.add(y);
+ m_types.add(type);
+ }
+
+ inline int elementCount() const { return m_types.size(); }
+ inline qreal *points() const { return m_points.data(); }
+ inline QPainterPath::ElementType *elementTypes() const { return m_types.data(); }
+
+ inline void setInvScale(qreal invScale) { m_inv_scale = invScale; }
+
+private:
+ QDataBuffer<qreal> m_points;
+ QDataBuffer<QPainterPath::ElementType> m_types;
+ QDashStroker m_dash_stroker;
+ qreal m_inv_scale;
+};
+
+inline void QTriangulatingStroker::normalVector(float x1, float y1, float x2, float y2,
+ float *nx, float *ny)
+{
+ float dx = x2 - x1;
+ float dy = y2 - y1;
+
+ float pw;
+
+ if (dx == 0)
+ pw = m_width / qAbs(dy);
+ else if (dy == 0)
+ pw = m_width / qAbs(dx);
+ else
+ pw = m_width / sqrt(dx*dx + dy*dy);
+
+ *nx = -dy * pw;
+ *ny = dx * pw;
+}
+
+inline void QTriangulatingStroker::emitLineSegment(float x, float y, float vx, float vy)
+{
+ m_vertices.add(x + vx);
+ m_vertices.add(y + vy);
+ m_vertices.add(x - vx);
+ m_vertices.add(y - vy);
+}
+
+void QTriangulatingStroker::lineTo(const qreal *pts)
+{
+ emitLineSegment(pts[0], pts[1], m_nvx, m_nvy);
+ m_cx = pts[0];
+ m_cy = pts[1];
+}
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/gui/opengl/qrbtree_p.h b/src/gui/opengl/qrbtree_p.h
new file mode 100644
index 0000000000..ac464a3fbe
--- /dev/null
+++ b/src/gui/opengl/qrbtree_p.h
@@ -0,0 +1,573 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QRBTREE_P_H
+#define QRBTREE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qglobal.h>
+
+QT_BEGIN_NAMESPACE
+
+template <class T>
+struct QRBTree
+{
+ struct Node
+ {
+ inline Node() : parent(0), left(0), right(0), red(true) { }
+ inline ~Node() {if (left) delete left; if (right) delete right;}
+ T data;
+ Node *parent;
+ Node *left;
+ Node *right;
+ bool red;
+ };
+
+ inline QRBTree() : root(0), freeList(0) { }
+ inline ~QRBTree();
+
+ inline void clear();
+
+ void attachBefore(Node *parent, Node *child);
+ void attachAfter(Node *parent, Node *child);
+
+ inline Node *front(Node *node) const;
+ inline Node *back(Node *node) const;
+ Node *next(Node *node) const;
+ Node *previous(Node *node) const;
+
+ inline void deleteNode(Node *&node);
+ inline Node *newNode();
+
+ // Return 1 if 'left' comes after 'right', 0 if equal, and -1 otherwise.
+ // 'left' and 'right' cannot be null.
+ int order(Node *left, Node *right);
+ inline bool validate() const;
+
+private:
+ void rotateLeft(Node *node);
+ void rotateRight(Node *node);
+ void update(Node *node);
+
+ inline void attachLeft(Node *parent, Node *child);
+ inline void attachRight(Node *parent, Node *child);
+
+ int blackDepth(Node *top) const;
+ bool checkRedBlackProperty(Node *top) const;
+
+ void swapNodes(Node *n1, Node *n2);
+ void detach(Node *node);
+
+ // 'node' must be black. rebalance will reduce the depth of black nodes by one in the sibling tree.
+ void rebalance(Node *node);
+
+public:
+ Node *root;
+private:
+ Node *freeList;
+};
+
+template <class T>
+inline QRBTree<T>::~QRBTree()
+{
+ clear();
+ while (freeList) {
+ // Avoid recursively calling the destructor, as this list may become large.
+ Node *next = freeList->right;
+ freeList->right = 0;
+ delete freeList;
+ freeList = next;
+ }
+}
+
+template <class T>
+inline void QRBTree<T>::clear()
+{
+ if (root)
+ delete root;
+ root = 0;
+}
+
+template <class T>
+void QRBTree<T>::rotateLeft(Node *node)
+{
+ // | | //
+ // N B //
+ // / \ / \ //
+ // A B ---> N D //
+ // / \ / \ //
+ // C D A C //
+
+ Node *&ref = (node->parent ? (node == node->parent->left ? node->parent->left : node->parent->right) : root);
+ ref = node->right;
+ node->right->parent = node->parent;
+
+ // : //
+ // N //
+ // / :| //
+ // A B //
+ // / \ //
+ // C D //
+
+ node->right = ref->left;
+ if (ref->left)
+ ref->left->parent = node;
+
+ // : | //
+ // N B //
+ // / \ : \ //
+ // A C D //
+
+ ref->left = node;
+ node->parent = ref;
+
+ // | //
+ // B //
+ // / \ //
+ // N D //
+ // / \ //
+ // A C //
+}
+
+template <class T>
+void QRBTree<T>::rotateRight(Node *node)
+{
+ // | | //
+ // N A //
+ // / \ / \ //
+ // A B ---> C N //
+ // / \ / \ //
+ // C D D B //
+
+ Node *&ref = (node->parent ? (node == node->parent->left ? node->parent->left : node->parent->right) : root);
+ ref = node->left;
+ node->left->parent = node->parent;
+
+ node->left = ref->right;
+ if (ref->right)
+ ref->right->parent = node;
+
+ ref->right = node;
+ node->parent = ref;
+}
+
+template <class T>
+void QRBTree<T>::update(Node *node) // call this after inserting a node
+{
+ for (;;) {
+ Node *parent = node->parent;
+
+ // if the node is the root, color it black
+ if (!parent) {
+ node->red = false;
+ return;
+ }
+
+ // if the parent is black, the node can be left red
+ if (!parent->red)
+ return;
+
+ // at this point, the parent is red and cannot be the root
+ Node *grandpa = parent->parent;
+ Q_ASSERT(grandpa);
+
+ Node *uncle = (parent == grandpa->left ? grandpa->right : grandpa->left);
+ if (uncle && uncle->red) {
+ // grandpa's black, parent and uncle are red.
+ // let parent and uncle be black, grandpa red and recursively update grandpa.
+ Q_ASSERT(!grandpa->red);
+ parent->red = false;
+ uncle->red = false;
+ grandpa->red = true;
+ node = grandpa;
+ continue;
+ }
+
+ // at this point, uncle is black
+ if (node == parent->right && parent == grandpa->left)
+ rotateLeft(node = parent);
+ else if (node == parent->left && parent == grandpa->right)
+ rotateRight(node = parent);
+ parent = node->parent;
+
+ if (parent == grandpa->left) {
+ rotateRight(grandpa);
+ parent->red = false;
+ grandpa->red = true;
+ } else {
+ rotateLeft(grandpa);
+ parent->red = false;
+ grandpa->red = true;
+ }
+ return;
+ }
+}
+
+template <class T>
+inline void QRBTree<T>::attachLeft(Node *parent, Node *child)
+{
+ Q_ASSERT(!parent->left);
+ parent->left = child;
+ child->parent = parent;
+ update(child);
+}
+
+template <class T>
+inline void QRBTree<T>::attachRight(Node *parent, Node *child)
+{
+ Q_ASSERT(!parent->right);
+ parent->right = child;
+ child->parent = parent;
+ update(child);
+}
+
+template <class T>
+void QRBTree<T>::attachBefore(Node *parent, Node *child)
+{
+ if (!root)
+ update(root = child);
+ else if (!parent)
+ attachRight(back(root), child);
+ else if (parent->left)
+ attachRight(back(parent->left), child);
+ else
+ attachLeft(parent, child);
+}
+
+template <class T>
+void QRBTree<T>::attachAfter(Node *parent, Node *child)
+{
+ if (!root)
+ update(root = child);
+ else if (!parent)
+ attachLeft(front(root), child);
+ else if (parent->right)
+ attachLeft(front(parent->right), child);
+ else
+ attachRight(parent, child);
+}
+
+template <class T>
+void QRBTree<T>::swapNodes(Node *n1, Node *n2)
+{
+ // Since iterators must not be invalidated, it is not sufficient to only swap the data.
+ if (n1->parent == n2) {
+ n1->parent = n2->parent;
+ n2->parent = n1;
+ } else if (n2->parent == n1) {
+ n2->parent = n1->parent;
+ n1->parent = n2;
+ } else {
+ qSwap(n1->parent, n2->parent);
+ }
+
+ qSwap(n1->left, n2->left);
+ qSwap(n1->right, n2->right);
+ qSwap(n1->red, n2->red);
+
+ if (n1->parent) {
+ if (n1->parent->left == n2)
+ n1->parent->left = n1;
+ else
+ n1->parent->right = n1;
+ } else {
+ root = n1;
+ }
+
+ if (n2->parent) {
+ if (n2->parent->left == n1)
+ n2->parent->left = n2;
+ else
+ n2->parent->right = n2;
+ } else {
+ root = n2;
+ }
+
+ if (n1->left)
+ n1->left->parent = n1;
+ if (n1->right)
+ n1->right->parent = n1;
+
+ if (n2->left)
+ n2->left->parent = n2;
+ if (n2->right)
+ n2->right->parent = n2;
+}
+
+template <class T>
+void QRBTree<T>::detach(Node *node) // call this before removing a node.
+{
+ if (node->right)
+ swapNodes(node, front(node->right));
+
+ Node *child = (node->left ? node->left : node->right);
+
+ if (!node->red) {
+ if (child && child->red)
+ child->red = false;
+ else
+ rebalance(node);
+ }
+
+ Node *&ref = (node->parent ? (node == node->parent->left ? node->parent->left : node->parent->right) : root);
+ ref = child;
+ if (child)
+ child->parent = node->parent;
+ node->left = node->right = node->parent = 0;
+}
+
+// 'node' must be black. rebalance will reduce the depth of black nodes by one in the sibling tree.
+template <class T>
+void QRBTree<T>::rebalance(Node *node)
+{
+ Q_ASSERT(!node->red);
+ for (;;) {
+ if (!node->parent)
+ return;
+
+ // at this point, node is not a parent, it is black, thus it must have a sibling.
+ Node *sibling = (node == node->parent->left ? node->parent->right : node->parent->left);
+ Q_ASSERT(sibling);
+
+ if (sibling->red) {
+ sibling->red = false;
+ node->parent->red = true;
+ if (node == node->parent->left)
+ rotateLeft(node->parent);
+ else
+ rotateRight(node->parent);
+ sibling = (node == node->parent->left ? node->parent->right : node->parent->left);
+ Q_ASSERT(sibling);
+ }
+
+ // at this point, the sibling is black.
+ Q_ASSERT(!sibling->red);
+
+ if ((!sibling->left || !sibling->left->red) && (!sibling->right || !sibling->right->red)) {
+ bool parentWasRed = node->parent->red;
+ sibling->red = true;
+ node->parent->red = false;
+ if (parentWasRed)
+ return;
+ node = node->parent;
+ continue;
+ }
+
+ // at this point, at least one of the sibling's children is red.
+
+ if (node == node->parent->left) {
+ if (!sibling->right || !sibling->right->red) {
+ Q_ASSERT(sibling->left);
+ sibling->red = true;
+ sibling->left->red = false;
+ rotateRight(sibling);
+
+ sibling = sibling->parent;
+ Q_ASSERT(sibling);
+ }
+ sibling->red = node->parent->red;
+ node->parent->red = false;
+
+ Q_ASSERT(sibling->right->red);
+ sibling->right->red = false;
+ rotateLeft(node->parent);
+ } else {
+ if (!sibling->left || !sibling->left->red) {
+ Q_ASSERT(sibling->right);
+ sibling->red = true;
+ sibling->right->red = false;
+ rotateLeft(sibling);
+
+ sibling = sibling->parent;
+ Q_ASSERT(sibling);
+ }
+ sibling->red = node->parent->red;
+ node->parent->red = false;
+
+ Q_ASSERT(sibling->left->red);
+ sibling->left->red = false;
+ rotateRight(node->parent);
+ }
+ return;
+ }
+}
+
+template <class T>
+inline typename QRBTree<T>::Node *QRBTree<T>::front(Node *node) const
+{
+ while (node->left)
+ node = node->left;
+ return node;
+}
+
+template <class T>
+inline typename QRBTree<T>::Node *QRBTree<T>::back(Node *node) const
+{
+ while (node->right)
+ node = node->right;
+ return node;
+}
+
+template <class T>
+typename QRBTree<T>::Node *QRBTree<T>::next(Node *node) const
+{
+ if (node->right)
+ return front(node->right);
+ while (node->parent && node == node->parent->right)
+ node = node->parent;
+ return node->parent;
+}
+
+template <class T>
+typename QRBTree<T>::Node *QRBTree<T>::previous(Node *node) const
+{
+ if (node->left)
+ return back(node->left);
+ while (node->parent && node == node->parent->left)
+ node = node->parent;
+ return node->parent;
+}
+
+template <class T>
+int QRBTree<T>::blackDepth(Node *top) const
+{
+ if (!top)
+ return 0;
+ int leftDepth = blackDepth(top->left);
+ int rightDepth = blackDepth(top->right);
+ if (leftDepth != rightDepth)
+ return -1;
+ if (!top->red)
+ ++leftDepth;
+ return leftDepth;
+}
+
+template <class T>
+bool QRBTree<T>::checkRedBlackProperty(Node *top) const
+{
+ if (!top)
+ return true;
+ if (top->left && !checkRedBlackProperty(top->left))
+ return false;
+ if (top->right && !checkRedBlackProperty(top->right))
+ return false;
+ return !(top->red && ((top->left && top->left->red) || (top->right && top->right->red)));
+}
+
+template <class T>
+inline bool QRBTree<T>::validate() const
+{
+ return checkRedBlackProperty(root) && blackDepth(root) != -1;
+}
+
+template <class T>
+inline void QRBTree<T>::deleteNode(Node *&node)
+{
+ Q_ASSERT(node);
+ detach(node);
+ node->right = freeList;
+ freeList = node;
+ node = 0;
+}
+
+template <class T>
+inline typename QRBTree<T>::Node *QRBTree<T>::newNode()
+{
+ if (freeList) {
+ Node *node = freeList;
+ freeList = freeList->right;
+ node->parent = node->left = node->right = 0;
+ node->red = true;
+ return node;
+ }
+ return new Node;
+}
+
+// Return 1 if 'left' comes after 'right', 0 if equal, and -1 otherwise.
+// 'left' and 'right' cannot be null.
+template <class T>
+int QRBTree<T>::order(Node *left, Node *right)
+{
+ Q_ASSERT(left && right);
+ if (left == right)
+ return 0;
+
+ QVector<Node *> leftAncestors;
+ QVector<Node *> rightAncestors;
+ while (left) {
+ leftAncestors.push_back(left);
+ left = left->parent;
+ }
+ while (right) {
+ rightAncestors.push_back(right);
+ right = right->parent;
+ }
+ Q_ASSERT(leftAncestors.back() == root && rightAncestors.back() == root);
+
+ while (!leftAncestors.empty() && !rightAncestors.empty() && leftAncestors.back() == rightAncestors.back()) {
+ leftAncestors.pop_back();
+ rightAncestors.pop_back();
+ }
+
+ if (!leftAncestors.empty())
+ return (leftAncestors.back() == leftAncestors.back()->parent->left ? -1 : 1);
+
+ if (!rightAncestors.empty())
+ return (rightAncestors.back() == rightAncestors.back()->parent->right ? -1 : 1);
+
+ // The code should never reach this point.
+ Q_ASSERT(!leftAncestors.empty() || !rightAncestors.empty());
+ return 0;
+}
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/gui/opengl/qtriangulator.cpp b/src/gui/opengl/qtriangulator.cpp
new file mode 100644
index 0000000000..67c2a6494e
--- /dev/null
+++ b/src/gui/opengl/qtriangulator.cpp
@@ -0,0 +1,2621 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtriangulator_p.h"
+
+#include <QtWidgets/qdialog.h>
+#include <QtGui/qevent.h>
+#include <QtGui/qpainter.h>
+#include <QtGui/qpainterpath.h>
+#include <QtGui/private/qbezier_p.h>
+#include <QtGui/private/qdatabuffer_p.h>
+#include <QtCore/qbitarray.h>
+#include <QtCore/qvarlengtharray.h>
+#include <QtCore/qqueue.h>
+#include <QtCore/qglobal.h>
+#include <QtCore/qpoint.h>
+#include <QtCore/qalgorithms.h>
+
+#include <private/qopenglcontext_p.h>
+#include <private/qopenglextensions_p.h>
+#include <private/qrbtree_p.h>
+
+#include <math.h>
+
+QT_BEGIN_NAMESPACE
+
+//#define Q_TRIANGULATOR_DEBUG
+
+#define Q_FIXED_POINT_SCALE 32
+
+// Quick sort.
+template <class T, class LessThan>
+#ifdef Q_CC_RVCT // RVCT 2.2 doesn't see recursive _static_ template function
+void sort(T *array, int count, LessThan lessThan)
+#else
+static void sort(T *array, int count, LessThan lessThan)
+#endif
+{
+ // If the number of elements fall below some threshold, use insertion sort.
+ const int INSERTION_SORT_LIMIT = 7; // About 7 is fastest on my computer...
+ if (count <= INSERTION_SORT_LIMIT) {
+ for (int i = 1; i < count; ++i) {
+ T temp = array[i];
+ int j = i;
+ while (j > 0 && lessThan(temp, array[j - 1])) {
+ array[j] = array[j - 1];
+ --j;
+ }
+ array[j] = temp;
+ }
+ return;
+ }
+
+ int high = count - 1;
+ int low = 0;
+ int mid = high / 2;
+ if (lessThan(array[mid], array[low]))
+ qSwap(array[mid], array[low]);
+ if (lessThan(array[high], array[mid]))
+ qSwap(array[high], array[mid]);
+ if (lessThan(array[mid], array[low]))
+ qSwap(array[mid], array[low]);
+
+ --high;
+ ++low;
+ qSwap(array[mid], array[high]);
+ int pivot = high;
+ --high;
+
+ while (low <= high) {
+ while (!lessThan(array[pivot], array[low])) {
+ ++low;
+ if (low > high)
+ goto sort_loop_end;
+ }
+ while (!lessThan(array[high], array[pivot])) {
+ --high;
+ if (low > high)
+ goto sort_loop_end;
+ }
+ qSwap(array[low], array[high]);
+ ++low;
+ --high;
+ }
+sort_loop_end:
+ if (low != pivot)
+ qSwap(array[pivot], array[low]);
+ sort(array, low, lessThan);
+ sort(array + low + 1, count - low - 1, lessThan);
+}
+
+// Quick sort.
+template <class T>
+#ifdef Q_CC_RVCT
+void sort(T *array, int count) // RVCT 2.2 doesn't see recursive _static_ template function
+#else
+static void sort(T *array, int count)
+#endif
+{
+ // If the number of elements fall below some threshold, use insertion sort.
+ const int INSERTION_SORT_LIMIT = 25; // About 25 is fastest on my computer...
+ if (count <= INSERTION_SORT_LIMIT) {
+ for (int i = 1; i < count; ++i) {
+ T temp = array[i];
+ int j = i;
+ while (j > 0 && (temp < array[j - 1])) {
+ array[j] = array[j - 1];
+ --j;
+ }
+ array[j] = temp;
+ }
+ return;
+ }
+
+ int high = count - 1;
+ int low = 0;
+ int mid = high / 2;
+ if ((array[mid] < array[low]))
+ qSwap(array[mid], array[low]);
+ if ((array[high] < array[mid]))
+ qSwap(array[high], array[mid]);
+ if ((array[mid] < array[low]))
+ qSwap(array[mid], array[low]);
+
+ --high;
+ ++low;
+ qSwap(array[mid], array[high]);
+ int pivot = high;
+ --high;
+
+ while (low <= high) {
+ while (!(array[pivot] < array[low])) {
+ ++low;
+ if (low > high)
+ goto sort_loop_end;
+ }
+ while (!(array[high] < array[pivot])) {
+ --high;
+ if (low > high)
+ goto sort_loop_end;
+ }
+ qSwap(array[low], array[high]);
+ ++low;
+ --high;
+ }
+sort_loop_end:
+ if (low != pivot)
+ qSwap(array[pivot], array[low]);
+ sort(array, low);
+ sort(array + low + 1, count - low - 1);
+}
+
+template<typename T>
+struct QVertexSet
+{
+ inline QVertexSet() { }
+ inline QVertexSet(const QVertexSet<T> &other) : vertices(other.vertices), indices(other.indices) { }
+ QVertexSet<T> &operator = (const QVertexSet<T> &other) {vertices = other.vertices; indices = other.indices; return *this;}
+
+ // The vertices of a triangle are given by: (x[i[n]], y[i[n]]), (x[j[n]], y[j[n]]), (x[k[n]], y[k[n]]), n = 0, 1, ...
+ QVector<qreal> vertices; // [x[0], y[0], x[1], y[1], x[2], ...]
+ QVector<T> indices; // [i[0], j[0], k[0], i[1], j[1], k[1], i[2], ...]
+};
+
+//============================================================================//
+// QFraction //
+//============================================================================//
+
+// Fraction must be in the range [0, 1)
+struct QFraction
+{
+ // Comparison operators must not be called on invalid fractions.
+ inline bool operator < (const QFraction &other) const;
+ inline bool operator == (const QFraction &other) const;
+ inline bool operator != (const QFraction &other) const {return !(*this == other);}
+ inline bool operator > (const QFraction &other) const {return other < *this;}
+ inline bool operator >= (const QFraction &other) const {return !(*this < other);}
+ inline bool operator <= (const QFraction &other) const {return !(*this > other);}
+
+ inline bool isValid() const {return denominator != 0;}
+
+ // numerator and denominator must not have common denominators.
+ quint64 numerator, denominator;
+};
+
+static inline quint64 gcd(quint64 x, quint64 y)
+{
+ while (y != 0) {
+ quint64 z = y;
+ y = x % y;
+ x = z;
+ }
+ return x;
+}
+
+static inline int compare(quint64 a, quint64 b)
+{
+ return (a > b) - (a < b);
+}
+
+// Compare a/b with c/d.
+// Return negative if less, 0 if equal, positive if greater.
+// a < b, c < d
+static int qCompareFractions(quint64 a, quint64 b, quint64 c, quint64 d)
+{
+ const quint64 LIMIT = Q_UINT64_C(0x100000000);
+ for (;;) {
+ // If the products 'ad' and 'bc' fit into 64 bits, they can be directly compared.
+ if (b < LIMIT && d < LIMIT)
+ return compare(a * d, b * c);
+
+ if (a == 0 || c == 0)
+ return compare(a, c);
+
+ // a/b < c/d <=> d/c < b/a
+ quint64 b_div_a = b / a;
+ quint64 d_div_c = d / c;
+ if (b_div_a != d_div_c)
+ return compare(d_div_c, b_div_a);
+
+ // floor(d/c) == floor(b/a)
+ // frac(d/c) < frac(b/a) ?
+ // frac(x/y) = (x%y)/y
+ d -= d_div_c * c; //d %= c;
+ b -= b_div_a * a; //b %= a;
+ qSwap(a, d);
+ qSwap(b, c);
+ }
+}
+
+// Fraction must be in the range [0, 1)
+// Assume input is valid.
+static QFraction qFraction(quint64 n, quint64 d) {
+ QFraction result;
+ if (n == 0) {
+ result.numerator = 0;
+ result.denominator = 1;
+ } else {
+ quint64 g = gcd(n, d);
+ result.numerator = n / g;
+ result.denominator = d / g;
+ }
+ return result;
+}
+
+inline bool QFraction::operator < (const QFraction &other) const
+{
+ return qCompareFractions(numerator, denominator, other.numerator, other.denominator) < 0;
+}
+
+inline bool QFraction::operator == (const QFraction &other) const
+{
+ return numerator == other.numerator && denominator == other.denominator;
+}
+
+//============================================================================//
+// QPodPoint //
+//============================================================================//
+
+struct QPodPoint
+{
+ inline bool operator < (const QPodPoint &other) const
+ {
+ if (y != other.y)
+ return y < other.y;
+ return x < other.x;
+ }
+
+ inline bool operator > (const QPodPoint &other) const {return other < *this;}
+ inline bool operator <= (const QPodPoint &other) const {return !(*this > other);}
+ inline bool operator >= (const QPodPoint &other) const {return !(*this < other);}
+ inline bool operator == (const QPodPoint &other) const {return x == other.x && y == other.y;}
+ inline bool operator != (const QPodPoint &other) const {return x != other.x || y != other.y;}
+
+ inline QPodPoint &operator += (const QPodPoint &other) {x += other.x; y += other.y; return *this;}
+ inline QPodPoint &operator -= (const QPodPoint &other) {x -= other.x; y -= other.y; return *this;}
+ inline QPodPoint operator + (const QPodPoint &other) const {QPodPoint result = {x + other.x, y + other.y}; return result;}
+ inline QPodPoint operator - (const QPodPoint &other) const {QPodPoint result = {x - other.x, y - other.y}; return result;}
+
+ int x;
+ int y;
+};
+
+static inline qint64 qCross(const QPodPoint &u, const QPodPoint &v)
+{
+ return qint64(u.x) * qint64(v.y) - qint64(u.y) * qint64(v.x);
+}
+
+static inline qint64 qDot(const QPodPoint &u, const QPodPoint &v)
+{
+ return qint64(u.x) * qint64(v.x) + qint64(u.y) * qint64(v.y);
+}
+
+// Return positive value if 'p' is to the right of the line 'v1'->'v2', negative if left of the
+// line and zero if exactly on the line.
+// The returned value is the z-component of the qCross product between 'v2-v1' and 'p-v1',
+// which is twice the signed area of the triangle 'p'->'v1'->'v2' (positive for CW order).
+static inline qint64 qPointDistanceFromLine(const QPodPoint &p, const QPodPoint &v1, const QPodPoint &v2)
+{
+ return qCross(v2 - v1, p - v1);
+}
+
+static inline bool qPointIsLeftOfLine(const QPodPoint &p, const QPodPoint &v1, const QPodPoint &v2)
+{
+ return QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(p, v1, v2) < 0;
+}
+
+// Return:
+// -1 if u < v
+// 0 if u == v
+// 1 if u > v
+static int comparePoints(const QPodPoint &u, const QPodPoint &v)
+{
+ if (u.y < v.y)
+ return -1;
+ if (u.y > v.y)
+ return 1;
+ if (u.x < v.x)
+ return -1;
+ if (u.x > v.x)
+ return 1;
+ return 0;
+}
+
+//============================================================================//
+// QIntersectionPoint //
+//============================================================================//
+
+struct QIntersectionPoint
+{
+ inline bool isValid() const {return xOffset.isValid() && yOffset.isValid();}
+ QPodPoint round() const;
+ inline bool isAccurate() const {return xOffset.numerator == 0 && yOffset.numerator == 0;}
+ bool operator < (const QIntersectionPoint &other) const;
+ bool operator == (const QIntersectionPoint &other) const;
+ inline bool operator != (const QIntersectionPoint &other) const {return !(*this == other);}
+ inline bool operator > (const QIntersectionPoint &other) const {return other < *this;}
+ inline bool operator >= (const QIntersectionPoint &other) const {return !(*this < other);}
+ inline bool operator <= (const QIntersectionPoint &other) const {return !(*this > other);}
+ bool isOnLine(const QPodPoint &u, const QPodPoint &v) const;
+
+ QPodPoint upperLeft;
+ QFraction xOffset;
+ QFraction yOffset;
+};
+
+static inline QIntersectionPoint qIntersectionPoint(const QPodPoint &point)
+{
+ // upperLeft = point, xOffset = 0/1, yOffset = 0/1.
+ QIntersectionPoint p = {{point.x, point.y}, {0, 1}, {0, 1}};
+ return p;
+}
+
+static inline QIntersectionPoint qIntersectionPoint(int x, int y)
+{
+ // upperLeft = (x, y), xOffset = 0/1, yOffset = 0/1.
+ QIntersectionPoint p = {{x, y}, {0, 1}, {0, 1}};
+ return p;
+}
+
+static QIntersectionPoint qIntersectionPoint(const QPodPoint &u1, const QPodPoint &u2, const QPodPoint &v1, const QPodPoint &v2)
+{
+ QIntersectionPoint result = {{0, 0}, {0, 0}, {0, 0}};
+
+ QPodPoint u = u2 - u1;
+ QPodPoint v = v2 - v1;
+ qint64 d1 = qCross(u, v1 - u1);
+ qint64 d2 = qCross(u, v2 - u1);
+ qint64 det = d2 - d1;
+ qint64 d3 = qCross(v, u1 - v1);
+ qint64 d4 = d3 - det; //qCross(v, u2 - v1);
+
+ // Check that the math is correct.
+ Q_ASSERT(d4 == qCross(v, u2 - v1));
+
+ // The intersection point can be expressed as:
+ // v1 - v * d1/det
+ // v2 - v * d2/det
+ // u1 + u * d3/det
+ // u2 + u * d4/det
+
+ // I'm only interested in lines that are crossing, so ignore parallel lines even if they overlap.
+ if (det == 0)
+ return result;
+
+ if (det < 0) {
+ det = -det;
+ d1 = -d1;
+ d2 = -d2;
+ d3 = -d3;
+ d4 = -d4;
+ }
+
+ // I'm only interested in lines intersecting at their interior, not at their end points.
+ // The lines intersect at their interior if and only if 'd1 < 0', 'd2 > 0', 'd3 < 0' and 'd4 > 0'.
+ if (d1 >= 0 || d2 <= 0 || d3 <= 0 || d4 >= 0)
+ return result;
+
+ // Calculate the intersection point as follows:
+ // v1 - v * d1/det | v1 <= v2 (component-wise)
+ // v2 - v * d2/det | v2 < v1 (component-wise)
+
+ // Assuming 21 bits per vector component.
+ // TODO: Make code path for 31 bits per vector component.
+ if (v.x >= 0) {
+ result.upperLeft.x = v1.x + (-v.x * d1) / det;
+ result.xOffset = qFraction(quint64(-v.x * d1) % quint64(det), quint64(det));
+ } else {
+ result.upperLeft.x = v2.x + (-v.x * d2) / det;
+ result.xOffset = qFraction(quint64(-v.x * d2) % quint64(det), quint64(det));
+ }
+
+ if (v.y >= 0) {
+ result.upperLeft.y = v1.y + (-v.y * d1) / det;
+ result.yOffset = qFraction(quint64(-v.y * d1) % quint64(det), quint64(det));
+ } else {
+ result.upperLeft.y = v2.y + (-v.y * d2) / det;
+ result.yOffset = qFraction(quint64(-v.y * d2) % quint64(det), quint64(det));
+ }
+
+ Q_ASSERT(result.xOffset.isValid());
+ Q_ASSERT(result.yOffset.isValid());
+ return result;
+}
+
+QPodPoint QIntersectionPoint::round() const
+{
+ QPodPoint result = upperLeft;
+ if (2 * xOffset.numerator >= xOffset.denominator)
+ ++result.x;
+ if (2 * yOffset.numerator >= yOffset.denominator)
+ ++result.y;
+ return result;
+}
+
+bool QIntersectionPoint::operator < (const QIntersectionPoint &other) const
+{
+ if (upperLeft.y != other.upperLeft.y)
+ return upperLeft.y < other.upperLeft.y;
+ if (yOffset != other.yOffset)
+ return yOffset < other.yOffset;
+ if (upperLeft.x != other.upperLeft.x)
+ return upperLeft.x < other.upperLeft.x;
+ return xOffset < other.xOffset;
+}
+
+bool QIntersectionPoint::operator == (const QIntersectionPoint &other) const
+{
+ return upperLeft == other.upperLeft && xOffset == other.xOffset && yOffset == other.yOffset;
+}
+
+// Returns true if this point is on the infinite line passing through 'u' and 'v'.
+bool QIntersectionPoint::isOnLine(const QPodPoint &u, const QPodPoint &v) const
+{
+ // TODO: Make code path for coordinates with more than 21 bits.
+ const QPodPoint p = upperLeft - u;
+ const QPodPoint q = v - u;
+ bool isHorizontal = p.y == 0 && yOffset.numerator == 0;
+ bool isVertical = p.x == 0 && xOffset.numerator == 0;
+ if (isHorizontal && isVertical)
+ return true;
+ if (isHorizontal)
+ return q.y == 0;
+ if (q.y == 0)
+ return false;
+ if (isVertical)
+ return q.x == 0;
+ if (q.x == 0)
+ return false;
+
+ // At this point, 'p+offset' and 'q' cannot lie on the x or y axis.
+
+ if (((q.x < 0) == (q.y < 0)) != ((p.x < 0) == (p.y < 0)))
+ return false; // 'p + offset' and 'q' pass through different quadrants.
+
+ // Move all coordinates into the first quadrant.
+ quint64 nx, ny;
+ if (p.x < 0)
+ nx = quint64(-p.x) * xOffset.denominator - xOffset.numerator;
+ else
+ nx = quint64(p.x) * xOffset.denominator + xOffset.numerator;
+ if (p.y < 0)
+ ny = quint64(-p.y) * yOffset.denominator - yOffset.numerator;
+ else
+ ny = quint64(p.y) * yOffset.denominator + yOffset.numerator;
+
+ return qFraction(quint64(qAbs(q.x)) * xOffset.denominator, quint64(qAbs(q.y)) * yOffset.denominator) == qFraction(nx, ny);
+}
+
+//============================================================================//
+// QMaxHeap //
+//============================================================================//
+
+template <class T>
+class QMaxHeap
+{
+public:
+ QMaxHeap() : m_data(0) {}
+ inline int size() const {return m_data.size();}
+ inline bool empty() const {return m_data.isEmpty();}
+ inline bool isEmpty() const {return m_data.isEmpty();}
+ void push(const T &x);
+ T pop();
+ inline const T &top() const {return m_data.first();}
+private:
+ static inline int parent(int i) {return (i - 1) / 2;}
+ static inline int left(int i) {return 2 * i + 1;}
+ static inline int right(int i) {return 2 * i + 2;}
+
+ QDataBuffer<T> m_data;
+};
+
+template <class T>
+void QMaxHeap<T>::push(const T &x)
+{
+ int current = m_data.size();
+ int parent = QMaxHeap::parent(current);
+ m_data.add(x);
+ while (current != 0 && m_data.at(parent) < x) {
+ m_data.at(current) = m_data.at(parent);
+ current = parent;
+ parent = QMaxHeap::parent(current);
+ }
+ m_data.at(current) = x;
+}
+
+template <class T>
+T QMaxHeap<T>::pop()
+{
+ T result = m_data.first();
+ T back = m_data.last();
+ m_data.pop_back();
+ if (!m_data.isEmpty()) {
+ int current = 0;
+ for (;;) {
+ int left = QMaxHeap::left(current);
+ int right = QMaxHeap::right(current);
+ if (left >= m_data.size())
+ break;
+ int greater = left;
+ if (right < m_data.size() && m_data.at(left) < m_data.at(right))
+ greater = right;
+ if (m_data.at(greater) < back)
+ break;
+ m_data.at(current) = m_data.at(greater);
+ current = greater;
+ }
+ m_data.at(current) = back;
+ }
+ return result;
+}
+
+//============================================================================//
+// QInt64Hash //
+//============================================================================//
+
+// Copied from qhash.cpp
+static const uchar prime_deltas[] = {
+ 0, 0, 1, 3, 1, 5, 3, 3, 1, 9, 7, 5, 3, 9, 25, 3,
+ 1, 21, 3, 21, 7, 15, 9, 5, 3, 29, 15, 0, 0, 0, 0, 0
+};
+
+// Copied from qhash.cpp
+static inline int primeForNumBits(int numBits)
+{
+ return (1 << numBits) + prime_deltas[numBits];
+}
+
+static inline int primeForCount(int count)
+{
+ int low = 0;
+ int high = 32;
+ for (int i = 0; i < 5; ++i) {
+ int mid = (high + low) / 2;
+ if (count >= 1 << mid)
+ low = mid;
+ else
+ high = mid;
+ }
+ return primeForNumBits(high);
+}
+
+// Hash set of quint64s. Elements cannot be removed without clearing the
+// entire set. A value of -1 is used to mark unused entries.
+class QInt64Set
+{
+public:
+ inline QInt64Set(int capacity = 64);
+ inline ~QInt64Set() {if (m_array) delete[] m_array;}
+ inline bool isValid() const {return m_array;}
+ void insert(quint64 key);
+ bool contains(quint64 key) const;
+ inline void clear();
+private:
+ bool rehash(int capacity);
+
+ static const quint64 UNUSED;
+
+ quint64 *m_array;
+ int m_capacity;
+ int m_count;
+};
+
+const quint64 QInt64Set::UNUSED = quint64(-1);
+
+inline QInt64Set::QInt64Set(int capacity)
+{
+ m_capacity = primeForCount(capacity);
+ m_array = new quint64[m_capacity];
+ if (m_array)
+ clear();
+ else
+ m_capacity = 0;
+}
+
+bool QInt64Set::rehash(int capacity)
+{
+ quint64 *oldArray = m_array;
+ int oldCapacity = m_capacity;
+
+ m_capacity = capacity;
+ m_array = new quint64[m_capacity];
+ if (m_array) {
+ clear();
+ if (oldArray) {
+ for (int i = 0; i < oldCapacity; ++i) {
+ if (oldArray[i] != UNUSED)
+ insert(oldArray[i]);
+ }
+ delete[] oldArray;
+ }
+ return true;
+ } else {
+ m_capacity = oldCapacity;
+ m_array = oldArray;
+ return false;
+ }
+}
+
+void QInt64Set::insert(quint64 key)
+{
+ if (m_count > 3 * m_capacity / 4)
+ rehash(primeForCount(2 * m_capacity));
+ Q_ASSERT_X(m_array, "QInt64Hash<T>::insert", "Hash set not allocated.");
+ int index = int(key % m_capacity);
+ for (int i = 0; i < m_capacity; ++i) {
+ index += i;
+ if (index >= m_capacity)
+ index -= m_capacity;
+ if (m_array[index] == key)
+ return;
+ if (m_array[index] == UNUSED) {
+ ++m_count;
+ m_array[index] = key;
+ return;
+ }
+ }
+ Q_ASSERT_X(0, "QInt64Hash<T>::insert", "Hash set full.");
+}
+
+bool QInt64Set::contains(quint64 key) const
+{
+ Q_ASSERT_X(m_array, "QInt64Hash<T>::contains", "Hash set not allocated.");
+ int index = int(key % m_capacity);
+ for (int i = 0; i < m_capacity; ++i) {
+ index += i;
+ if (index >= m_capacity)
+ index -= m_capacity;
+ if (m_array[index] == key)
+ return true;
+ if (m_array[index] == UNUSED)
+ return false;
+ }
+ return false;
+}
+
+inline void QInt64Set::clear()
+{
+ Q_ASSERT_X(m_array, "QInt64Hash<T>::clear", "Hash set not allocated.");
+ for (int i = 0; i < m_capacity; ++i)
+ m_array[i] = UNUSED;
+ m_count = 0;
+}
+
+//============================================================================//
+// QRingBuffer //
+//============================================================================//
+
+// T must be POD.
+template <class T>
+class QRingBuffer
+{
+public:
+ inline QRingBuffer() : m_array(0), m_head(0), m_size(0), m_capacity(0) { }
+ inline ~QRingBuffer() {if (m_array) delete[] m_array;}
+ bool reallocate(int capacity);
+ inline const T &head() const {Q_ASSERT(m_size > 0); return m_array[m_head];}
+ inline const T &dequeue();
+ inline void enqueue(const T &x);
+ inline bool isEmpty() const {return m_size == 0;}
+private:
+ T *m_array;
+ int m_head;
+ int m_size;
+ int m_capacity;
+};
+
+template <class T>
+bool QRingBuffer<T>::reallocate(int capacity)
+{
+ T *oldArray = m_array;
+ m_array = new T[capacity];
+ if (m_array) {
+ if (oldArray) {
+ if (m_head + m_size > m_capacity) {
+ memcpy(m_array, oldArray + m_head, (m_capacity - m_head) * sizeof(T));
+ memcpy(m_array + (m_capacity - m_head), oldArray, (m_head + m_size - m_capacity) * sizeof(T));
+ } else {
+ memcpy(m_array, oldArray + m_head, m_size * sizeof(T));
+ }
+ delete[] oldArray;
+ }
+ m_capacity = capacity;
+ m_head = 0;
+ return true;
+ } else {
+ m_array = oldArray;
+ return false;
+ }
+}
+
+template <class T>
+inline const T &QRingBuffer<T>::dequeue()
+{
+ Q_ASSERT(m_size > 0);
+ Q_ASSERT(m_array);
+ Q_ASSERT(m_capacity >= m_size);
+ int index = m_head;
+ if (++m_head >= m_capacity)
+ m_head -= m_capacity;
+ --m_size;
+ return m_array[index];
+}
+
+template <class T>
+inline void QRingBuffer<T>::enqueue(const T &x)
+{
+ if (m_size == m_capacity)
+ reallocate(qMax(2 * m_capacity, 64));
+ int index = m_head + m_size;
+ if (index >= m_capacity)
+ index -= m_capacity;
+ m_array[index] = x;
+ ++m_size;
+}
+
+//============================================================================//
+// QTriangulator //
+//============================================================================//
+template<typename T>
+class QTriangulator
+{
+public:
+ typedef QVarLengthArray<int, 6> ShortArray;
+
+ //================================//
+ // QTriangulator::ComplexToSimple //
+ //================================//
+ friend class ComplexToSimple;
+ class ComplexToSimple
+ {
+ public:
+ inline ComplexToSimple(QTriangulator<T> *parent) : m_parent(parent),
+ m_edges(0), m_events(0), m_splits(0) { }
+ void decompose();
+ private:
+ struct Edge
+ {
+ inline int &upper() {return pointingUp ? to : from;}
+ inline int &lower() {return pointingUp ? from : to;}
+ inline int upper() const {return pointingUp ? to : from;}
+ inline int lower() const {return pointingUp ? from : to;}
+
+ QRBTree<int>::Node *node;
+ int from, to; // vertex
+ int next, previous; // edge
+ int winding;
+ bool mayIntersect;
+ bool pointingUp, originallyPointingUp;
+ };
+
+ friend class CompareEdges;
+ class CompareEdges
+ {
+ public:
+ inline CompareEdges(ComplexToSimple *parent) : m_parent(parent) { }
+ bool operator () (int i, int j) const;
+ private:
+ ComplexToSimple *m_parent;
+ };
+
+ struct Intersection
+ {
+ bool operator < (const Intersection &other) const {return other.intersectionPoint < intersectionPoint;}
+
+ QIntersectionPoint intersectionPoint;
+ int vertex;
+ int leftEdge;
+ int rightEdge;
+ };
+
+ struct Split
+ {
+ int vertex;
+ int edge;
+ bool accurate;
+ };
+
+ struct Event
+ {
+ enum Type {Upper, Lower};
+ inline bool operator < (const Event &other) const;
+
+ QPodPoint point;
+ Type type;
+ int edge;
+ };
+
+#ifdef Q_TRIANGULATOR_DEBUG
+ friend class DebugDialog;
+ friend class QTriangulator;
+ class DebugDialog : public QDialog
+ {
+ public:
+ DebugDialog(ComplexToSimple *parent, int currentVertex);
+ protected:
+ void paintEvent(QPaintEvent *);
+ void wheelEvent(QWheelEvent *);
+ void mouseMoveEvent(QMouseEvent *);
+ void mousePressEvent(QMouseEvent *);
+ private:
+ ComplexToSimple *m_parent;
+ QRectF m_window;
+ QPoint m_lastMousePos;
+ int m_vertex;
+ };
+#endif
+
+ void initEdges();
+ bool calculateIntersection(int left, int right);
+ bool edgeIsLeftOfEdge(int leftEdgeIndex, int rightEdgeIndex) const;
+ QRBTree<int>::Node *searchEdgeLeftOf(int edgeIndex) const;
+ QRBTree<int>::Node *searchEdgeLeftOf(int edgeIndex, QRBTree<int>::Node *after) const;
+ QPair<QRBTree<int>::Node *, QRBTree<int>::Node *> bounds(const QPodPoint &point) const;
+ QPair<QRBTree<int>::Node *, QRBTree<int>::Node *> outerBounds(const QPodPoint &point) const;
+ void splitEdgeListRange(QRBTree<int>::Node *leftmost, QRBTree<int>::Node *rightmost, int vertex, const QIntersectionPoint &intersectionPoint);
+ void reorderEdgeListRange(QRBTree<int>::Node *leftmost, QRBTree<int>::Node *rightmost);
+ void sortEdgeList(const QPodPoint eventPoint);
+ void fillPriorityQueue();
+ void calculateIntersections();
+ int splitEdge(int splitIndex);
+ bool splitEdgesAtIntersections();
+ void insertEdgeIntoVectorIfWanted(ShortArray &orderedEdges, int i);
+ void removeUnwantedEdgesAndConnect();
+ void removeUnusedPoints();
+
+ QTriangulator *m_parent;
+ QDataBuffer<Edge> m_edges;
+ QRBTree<int> m_edgeList;
+ QDataBuffer<Event> m_events;
+ QDataBuffer<Split> m_splits;
+ QMaxHeap<Intersection> m_topIntersection;
+ QInt64Set m_processedEdgePairs;
+ int m_initialPointCount;
+ };
+#ifdef Q_TRIANGULATOR_DEBUG
+ friend class ComplexToSimple::DebugDialog;
+#endif
+
+ //=================================//
+ // QTriangulator::SimpleToMonotone //
+ //=================================//
+ friend class SimpleToMonotone;
+ class SimpleToMonotone
+ {
+ public:
+ inline SimpleToMonotone(QTriangulator<T> *parent) : m_parent(parent), m_edges(0), m_upperVertex(0) { }
+ void decompose();
+ private:
+ enum VertexType {MergeVertex, EndVertex, RegularVertex, StartVertex, SplitVertex};
+
+ struct Edge
+ {
+ QRBTree<int>::Node *node;
+ int helper, twin, next, previous;
+ T from, to;
+ VertexType type;
+ bool pointingUp;
+ int upper() const {return (pointingUp ? to : from);}
+ int lower() const {return (pointingUp ? from : to);}
+ };
+
+ friend class CompareVertices;
+ class CompareVertices
+ {
+ public:
+ CompareVertices(SimpleToMonotone *parent) : m_parent(parent) { }
+ bool operator () (int i, int j) const;
+ private:
+ SimpleToMonotone *m_parent;
+ };
+
+ void setupDataStructures();
+ void removeZeroLengthEdges();
+ void fillPriorityQueue();
+ bool edgeIsLeftOfEdge(int leftEdgeIndex, int rightEdgeIndex) const;
+ // Returns the rightmost edge not to the right of the given edge.
+ QRBTree<int>::Node *searchEdgeLeftOfEdge(int edgeIndex) const;
+ // Returns the rightmost edge left of the given point.
+ QRBTree<int>::Node *searchEdgeLeftOfPoint(int pointIndex) const;
+ void classifyVertex(int i);
+ void classifyVertices();
+ bool pointIsInSector(const QPodPoint &p, const QPodPoint &v1, const QPodPoint &v2, const QPodPoint &v3);
+ bool pointIsInSector(int vertex, int sector);
+ int findSector(int edge, int vertex);
+ void createDiagonal(int lower, int upper);
+ void monotoneDecomposition();
+
+ QTriangulator *m_parent;
+ QRBTree<int> m_edgeList;
+ QDataBuffer<Edge> m_edges;
+ QDataBuffer<int> m_upperVertex;
+ bool m_clockwiseOrder;
+ };
+
+ //====================================//
+ // QTriangulator::MonotoneToTriangles //
+ //====================================//
+ friend class MonotoneToTriangles;
+ class MonotoneToTriangles
+ {
+ public:
+ inline MonotoneToTriangles(QTriangulator<T> *parent) : m_parent(parent) { }
+ void decompose();
+ private:
+ inline T indices(int index) const {return m_parent->m_indices.at(index + m_first);}
+ inline int next(int index) const {return (index + 1) % m_length;}
+ inline int previous(int index) const {return (index + m_length - 1) % m_length;}
+ inline bool less(int i, int j) const {return m_parent->m_vertices.at((qint32)indices(i)) < m_parent->m_vertices.at(indices(j));}
+ inline bool leftOfEdge(int i, int j, int k) const
+ {
+ return qPointIsLeftOfLine(m_parent->m_vertices.at((qint32)indices(i)),
+ m_parent->m_vertices.at((qint32)indices(j)), m_parent->m_vertices.at((qint32)indices(k)));
+ }
+
+ QTriangulator<T> *m_parent;
+ int m_first;
+ int m_length;
+ };
+
+ inline QTriangulator() : m_vertices(0) { }
+
+ // Call this only once.
+ void initialize(const qreal *polygon, int count, uint hint, const QTransform &matrix);
+ // Call this only once.
+ void initialize(const QVectorPath &path, const QTransform &matrix, qreal lod);
+ // Call this only once.
+ void initialize(const QPainterPath &path, const QTransform &matrix, qreal lod);
+ // Call either triangulate() or polyline() only once.
+ QVertexSet<T> triangulate();
+ QVertexSet<T> polyline();
+private:
+ QDataBuffer<QPodPoint> m_vertices;
+ QVector<T> m_indices;
+ uint m_hint;
+};
+
+//============================================================================//
+// QTriangulator //
+//============================================================================//
+
+template <typename T>
+QVertexSet<T> QTriangulator<T>::triangulate()
+{
+ for (int i = 0; i < m_vertices.size(); ++i) {
+ Q_ASSERT(qAbs(m_vertices.at(i).x) < (1 << 21));
+ Q_ASSERT(qAbs(m_vertices.at(i).y) < (1 << 21));
+ }
+
+ if (!(m_hint & (QVectorPath::OddEvenFill | QVectorPath::WindingFill)))
+ m_hint |= QVectorPath::OddEvenFill;
+
+ if (m_hint & QVectorPath::NonConvexShapeMask) {
+ ComplexToSimple c2s(this);
+ c2s.decompose();
+ SimpleToMonotone s2m(this);
+ s2m.decompose();
+ }
+ MonotoneToTriangles m2t(this);
+ m2t.decompose();
+
+ QVertexSet<T> result;
+ result.indices = m_indices;
+ result.vertices.resize(2 * m_vertices.size());
+ for (int i = 0; i < m_vertices.size(); ++i) {
+ result.vertices[2 * i + 0] = qreal(m_vertices.at(i).x) / Q_FIXED_POINT_SCALE;
+ result.vertices[2 * i + 1] = qreal(m_vertices.at(i).y) / Q_FIXED_POINT_SCALE;
+ }
+ return result;
+}
+
+template <typename T>
+QVertexSet<T> QTriangulator<T>::polyline()
+{
+ for (int i = 0; i < m_vertices.size(); ++i) {
+ Q_ASSERT(qAbs(m_vertices.at(i).x) < (1 << 21));
+ Q_ASSERT(qAbs(m_vertices.at(i).y) < (1 << 21));
+ }
+
+ if (!(m_hint & (QVectorPath::OddEvenFill | QVectorPath::WindingFill)))
+ m_hint |= QVectorPath::OddEvenFill;
+
+ if (m_hint & QVectorPath::NonConvexShapeMask) {
+ ComplexToSimple c2s(this);
+ c2s.decompose();
+ }
+
+ QVertexSet<T> result;
+ result.indices = m_indices;
+ result.vertices.resize(2 * m_vertices.size());
+ for (int i = 0; i < m_vertices.size(); ++i) {
+ result.vertices[2 * i + 0] = qreal(m_vertices.at(i).x) / Q_FIXED_POINT_SCALE;
+ result.vertices[2 * i + 1] = qreal(m_vertices.at(i).y) / Q_FIXED_POINT_SCALE;
+ }
+ return result;
+}
+
+template <typename T>
+void QTriangulator<T>::initialize(const qreal *polygon, int count, uint hint, const QTransform &matrix)
+{
+ m_hint = hint;
+ m_vertices.resize(count);
+ m_indices.resize(count + 1);
+ for (int i = 0; i < count; ++i) {
+ qreal x, y;
+ matrix.map(polygon[2 * i + 0], polygon[2 * i + 1], &x, &y);
+ m_vertices.at(i).x = qRound(x * Q_FIXED_POINT_SCALE);
+ m_vertices.at(i).y = qRound(y * Q_FIXED_POINT_SCALE);
+ m_indices[i] = i;
+ }
+ m_indices[count] = T(-1); //Q_TRIANGULATE_END_OF_POLYGON
+}
+
+template <typename T>
+void QTriangulator<T>::initialize(const QVectorPath &path, const QTransform &matrix, qreal lod)
+{
+ m_hint = path.hints();
+ // Curved paths will be converted to complex polygons.
+ m_hint &= ~QVectorPath::CurvedShapeMask;
+
+ const qreal *p = path.points();
+ const QPainterPath::ElementType *e = path.elements();
+ if (e) {
+ for (int i = 0; i < path.elementCount(); ++i, ++e, p += 2) {
+ switch (*e) {
+ case QPainterPath::MoveToElement:
+ if (!m_indices.isEmpty())
+ m_indices.push_back(T(-1)); // Q_TRIANGULATE_END_OF_POLYGON
+ // Fall through.
+ case QPainterPath::LineToElement:
+ m_indices.push_back(T(m_vertices.size()));
+ m_vertices.resize(m_vertices.size() + 1);
+ qreal x, y;
+ matrix.map(p[0], p[1], &x, &y);
+ m_vertices.last().x = qRound(x * Q_FIXED_POINT_SCALE);
+ m_vertices.last().y = qRound(y * Q_FIXED_POINT_SCALE);
+ break;
+ case QPainterPath::CurveToElement:
+ {
+ qreal pts[8];
+ for (int i = 0; i < 4; ++i)
+ matrix.map(p[2 * i - 2], p[2 * i - 1], &pts[2 * i + 0], &pts[2 * i + 1]);
+ for (int i = 0; i < 8; ++i)
+ pts[i] *= lod;
+ QBezier bezier = QBezier::fromPoints(QPointF(pts[0], pts[1]), QPointF(pts[2], pts[3]), QPointF(pts[4], pts[5]), QPointF(pts[6], pts[7]));
+ QPolygonF poly = bezier.toPolygon();
+ // Skip first point, it already exists in 'm_vertices'.
+ for (int j = 1; j < poly.size(); ++j) {
+ m_indices.push_back(T(m_vertices.size()));
+ m_vertices.resize(m_vertices.size() + 1);
+ m_vertices.last().x = qRound(poly.at(j).x() * Q_FIXED_POINT_SCALE / lod);
+ m_vertices.last().y = qRound(poly.at(j).y() * Q_FIXED_POINT_SCALE / lod);
+ }
+ }
+ i += 2;
+ e += 2;
+ p += 4;
+ break;
+ default:
+ Q_ASSERT_X(0, "QTriangulator::triangulate", "Unexpected element type.");
+ break;
+ }
+ }
+ } else {
+ for (int i = 0; i < path.elementCount(); ++i, p += 2) {
+ m_indices.push_back(T(m_vertices.size()));
+ m_vertices.resize(m_vertices.size() + 1);
+ qreal x, y;
+ matrix.map(p[0], p[1], &x, &y);
+ m_vertices.last().x = qRound(x * Q_FIXED_POINT_SCALE);
+ m_vertices.last().y = qRound(y * Q_FIXED_POINT_SCALE);
+ }
+ }
+ m_indices.push_back(T(-1)); // Q_TRIANGULATE_END_OF_POLYGON
+}
+
+template <typename T>
+void QTriangulator<T>::initialize(const QPainterPath &path, const QTransform &matrix, qreal lod)
+{
+ initialize(qtVectorPathForPath(path), matrix, lod);
+}
+
+//============================================================================//
+// QTriangulator::ComplexToSimple //
+//============================================================================//
+template <typename T>
+void QTriangulator<T>::ComplexToSimple::decompose()
+{
+ m_initialPointCount = m_parent->m_vertices.size();
+ initEdges();
+ do {
+ calculateIntersections();
+ } while (splitEdgesAtIntersections());
+
+ removeUnwantedEdgesAndConnect();
+ removeUnusedPoints();
+
+ m_parent->m_indices.clear();
+ QBitArray processed(m_edges.size(), false);
+ for (int first = 0; first < m_edges.size(); ++first) {
+ // If already processed, or if unused path, skip.
+ if (processed.at(first) || m_edges.at(first).next == -1)
+ continue;
+
+ int i = first;
+ do {
+ Q_ASSERT(!processed.at(i));
+ Q_ASSERT(m_edges.at(m_edges.at(i).next).previous == i);
+ m_parent->m_indices.push_back(m_edges.at(i).from);
+ processed.setBit(i);
+ i = m_edges.at(i).next; // CCW order
+ } while (i != first);
+ m_parent->m_indices.push_back(T(-1)); // Q_TRIANGULATE_END_OF_POLYGON
+ }
+}
+
+template <typename T>
+void QTriangulator<T>::ComplexToSimple::initEdges()
+{
+ // Initialize edge structure.
+ // 'next' and 'previous' are not being initialized at this point.
+ int first = 0;
+ for (int i = 0; i < m_parent->m_indices.size(); ++i) {
+ if (m_parent->m_indices.at(i) == T(-1)) { // Q_TRIANGULATE_END_OF_POLYGON
+ if (m_edges.size() != first)
+ m_edges.last().to = m_edges.at(first).from;
+ first = m_edges.size();
+ } else {
+ Q_ASSERT(i + 1 < m_parent->m_indices.size());
+ // {node, from, to, next, previous, winding, mayIntersect, pointingUp, originallyPointingUp}
+ Edge edge = {0, m_parent->m_indices.at(i), m_parent->m_indices.at(i + 1), -1, -1, 0, true, false, false};
+ m_edges.add(edge);
+ }
+ }
+ if (first != m_edges.size())
+ m_edges.last().to = m_edges.at(first).from;
+ for (int i = 0; i < m_edges.size(); ++i) {
+ m_edges.at(i).originallyPointingUp = m_edges.at(i).pointingUp =
+ m_parent->m_vertices.at(m_edges.at(i).to) < m_parent->m_vertices.at(m_edges.at(i).from);
+ }
+}
+
+// Return true if new intersection was found
+template <typename T>
+bool QTriangulator<T>::ComplexToSimple::calculateIntersection(int left, int right)
+{
+ const Edge &e1 = m_edges.at(left);
+ const Edge &e2 = m_edges.at(right);
+
+ const QPodPoint &u1 = m_parent->m_vertices.at((qint32)e1.from);
+ const QPodPoint &u2 = m_parent->m_vertices.at((qint32)e1.to);
+ const QPodPoint &v1 = m_parent->m_vertices.at((qint32)e2.from);
+ const QPodPoint &v2 = m_parent->m_vertices.at((qint32)e2.to);
+ if (qMax(u1.x, u2.x) <= qMin(v1.x, v2.x))
+ return false;
+
+ quint64 key = (left > right ? (quint64(right) << 32) | quint64(left) : (quint64(left) << 32) | quint64(right));
+ if (m_processedEdgePairs.contains(key))
+ return false;
+ m_processedEdgePairs.insert(key);
+
+ Intersection intersection;
+ intersection.leftEdge = left;
+ intersection.rightEdge = right;
+ intersection.intersectionPoint = QT_PREPEND_NAMESPACE(qIntersectionPoint)(u1, u2, v1, v2);
+
+ if (!intersection.intersectionPoint.isValid())
+ return false;
+
+ Q_ASSERT(intersection.intersectionPoint.isOnLine(u1, u2));
+ Q_ASSERT(intersection.intersectionPoint.isOnLine(v1, v2));
+
+ intersection.vertex = m_parent->m_vertices.size();
+ m_topIntersection.push(intersection);
+ m_parent->m_vertices.add(intersection.intersectionPoint.round());
+ return true;
+}
+
+template <typename T>
+bool QTriangulator<T>::ComplexToSimple::edgeIsLeftOfEdge(int leftEdgeIndex, int rightEdgeIndex) const
+{
+ const Edge &leftEdge = m_edges.at(leftEdgeIndex);
+ const Edge &rightEdge = m_edges.at(rightEdgeIndex);
+ const QPodPoint &u = m_parent->m_vertices.at(rightEdge.upper());
+ const QPodPoint &l = m_parent->m_vertices.at(rightEdge.lower());
+ const QPodPoint &upper = m_parent->m_vertices.at(leftEdge.upper());
+ if (upper.x < qMin(l.x, u.x))
+ return true;
+ if (upper.x > qMax(l.x, u.x))
+ return false;
+ qint64 d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(upper, l, u);
+ // d < 0: left, d > 0: right, d == 0: on top
+ if (d == 0)
+ d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(m_parent->m_vertices.at(leftEdge.lower()), l, u);
+ return d < 0;
+}
+
+template <typename T>
+QRBTree<int>::Node *QTriangulator<T>::ComplexToSimple::searchEdgeLeftOf(int edgeIndex) const
+{
+ QRBTree<int>::Node *current = m_edgeList.root;
+ QRBTree<int>::Node *result = 0;
+ while (current) {
+ if (edgeIsLeftOfEdge(edgeIndex, current->data)) {
+ current = current->left;
+ } else {
+ result = current;
+ current = current->right;
+ }
+ }
+ return result;
+}
+
+template <typename T>
+QRBTree<int>::Node *QTriangulator<T>::ComplexToSimple::searchEdgeLeftOf(int edgeIndex, QRBTree<int>::Node *after) const
+{
+ if (!m_edgeList.root)
+ return after;
+ QRBTree<int>::Node *result = after;
+ QRBTree<int>::Node *current = (after ? m_edgeList.next(after) : m_edgeList.front(m_edgeList.root));
+ while (current) {
+ if (edgeIsLeftOfEdge(edgeIndex, current->data))
+ return result;
+ result = current;
+ current = m_edgeList.next(current);
+ }
+ return result;
+}
+
+template <typename T>
+QPair<QRBTree<int>::Node *, QRBTree<int>::Node *> QTriangulator<T>::ComplexToSimple::bounds(const QPodPoint &point) const
+{
+ QRBTree<int>::Node *current = m_edgeList.root;
+ QPair<QRBTree<int>::Node *, QRBTree<int>::Node *> result(0, 0);
+ while (current) {
+ const QPodPoint &v1 = m_parent->m_vertices.at(m_edges.at(current->data).lower());
+ const QPodPoint &v2 = m_parent->m_vertices.at(m_edges.at(current->data).upper());
+ qint64 d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(point, v1, v2);
+ if (d == 0) {
+ result.first = result.second = current;
+ break;
+ }
+ current = (d < 0 ? current->left : current->right);
+ }
+ if (current == 0)
+ return result;
+
+ current = result.first->left;
+ while (current) {
+ const QPodPoint &v1 = m_parent->m_vertices.at(m_edges.at(current->data).lower());
+ const QPodPoint &v2 = m_parent->m_vertices.at(m_edges.at(current->data).upper());
+ qint64 d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(point, v1, v2);
+ Q_ASSERT(d >= 0);
+ if (d == 0) {
+ result.first = current;
+ current = current->left;
+ } else {
+ current = current->right;
+ }
+ }
+
+ current = result.second->right;
+ while (current) {
+ const QPodPoint &v1 = m_parent->m_vertices.at(m_edges.at(current->data).lower());
+ const QPodPoint &v2 = m_parent->m_vertices.at(m_edges.at(current->data).upper());
+ qint64 d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(point, v1, v2);
+ Q_ASSERT(d <= 0);
+ if (d == 0) {
+ result.second = current;
+ current = current->right;
+ } else {
+ current = current->left;
+ }
+ }
+
+ return result;
+}
+
+template <typename T>
+QPair<QRBTree<int>::Node *, QRBTree<int>::Node *> QTriangulator<T>::ComplexToSimple::outerBounds(const QPodPoint &point) const
+{
+ QRBTree<int>::Node *current = m_edgeList.root;
+ QPair<QRBTree<int>::Node *, QRBTree<int>::Node *> result(0, 0);
+
+ while (current) {
+ const QPodPoint &v1 = m_parent->m_vertices.at(m_edges.at(current->data).lower());
+ const QPodPoint &v2 = m_parent->m_vertices.at(m_edges.at(current->data).upper());
+ qint64 d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(point, v1, v2);
+ if (d == 0)
+ break;
+ if (d < 0) {
+ result.second = current;
+ current = current->left;
+ } else {
+ result.first = current;
+ current = current->right;
+ }
+ }
+
+ if (!current)
+ return result;
+
+ QRBTree<int>::Node *mid = current;
+
+ current = mid->left;
+ while (current) {
+ const QPodPoint &v1 = m_parent->m_vertices.at(m_edges.at(current->data).lower());
+ const QPodPoint &v2 = m_parent->m_vertices.at(m_edges.at(current->data).upper());
+ qint64 d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(point, v1, v2);
+ Q_ASSERT(d >= 0);
+ if (d == 0) {
+ current = current->left;
+ } else {
+ result.first = current;
+ current = current->right;
+ }
+ }
+
+ current = mid->right;
+ while (current) {
+ const QPodPoint &v1 = m_parent->m_vertices.at(m_edges.at(current->data).lower());
+ const QPodPoint &v2 = m_parent->m_vertices.at(m_edges.at(current->data).upper());
+ qint64 d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(point, v1, v2);
+ Q_ASSERT(d <= 0);
+ if (d == 0) {
+ current = current->right;
+ } else {
+ result.second = current;
+ current = current->left;
+ }
+ }
+
+ return result;
+}
+
+template <typename T>
+void QTriangulator<T>::ComplexToSimple::splitEdgeListRange(QRBTree<int>::Node *leftmost, QRBTree<int>::Node *rightmost, int vertex, const QIntersectionPoint &intersectionPoint)
+{
+ Q_ASSERT(leftmost && rightmost);
+
+ // Split.
+ for (;;) {
+ const QPodPoint &u = m_parent->m_vertices.at(m_edges.at(leftmost->data).from);
+ const QPodPoint &v = m_parent->m_vertices.at(m_edges.at(leftmost->data).to);
+ Q_ASSERT(intersectionPoint.isOnLine(u, v));
+ const Split split = {vertex, leftmost->data, intersectionPoint.isAccurate()};
+ if (intersectionPoint.xOffset.numerator != 0 || intersectionPoint.yOffset.numerator != 0 || (intersectionPoint.upperLeft != u && intersectionPoint.upperLeft != v))
+ m_splits.add(split);
+ if (leftmost == rightmost)
+ break;
+ leftmost = m_edgeList.next(leftmost);
+ }
+}
+
+template <typename T>
+void QTriangulator<T>::ComplexToSimple::reorderEdgeListRange(QRBTree<int>::Node *leftmost, QRBTree<int>::Node *rightmost)
+{
+ Q_ASSERT(leftmost && rightmost);
+
+ QRBTree<int>::Node *storeLeftmost = leftmost;
+ QRBTree<int>::Node *storeRightmost = rightmost;
+
+ // Reorder.
+ while (leftmost != rightmost) {
+ Edge &left = m_edges.at(leftmost->data);
+ Edge &right = m_edges.at(rightmost->data);
+ qSwap(left.node, right.node);
+ qSwap(leftmost->data, rightmost->data);
+ leftmost = m_edgeList.next(leftmost);
+ if (leftmost == rightmost)
+ break;
+ rightmost = m_edgeList.previous(rightmost);
+ }
+
+ rightmost = m_edgeList.next(storeRightmost);
+ leftmost = m_edgeList.previous(storeLeftmost);
+ if (leftmost)
+ calculateIntersection(leftmost->data, storeLeftmost->data);
+ if (rightmost)
+ calculateIntersection(storeRightmost->data, rightmost->data);
+}
+
+template <typename T>
+void QTriangulator<T>::ComplexToSimple::sortEdgeList(const QPodPoint eventPoint)
+{
+ QIntersectionPoint eventPoint2 = QT_PREPEND_NAMESPACE(qIntersectionPoint)(eventPoint);
+ while (!m_topIntersection.isEmpty() && m_topIntersection.top().intersectionPoint < eventPoint2) {
+ Intersection intersection = m_topIntersection.pop();
+
+ QIntersectionPoint currentIntersectionPoint = intersection.intersectionPoint;
+ int currentVertex = intersection.vertex;
+
+ QRBTree<int>::Node *leftmost = m_edges.at(intersection.leftEdge).node;
+ QRBTree<int>::Node *rightmost = m_edges.at(intersection.rightEdge).node;
+
+ for (;;) {
+ QRBTree<int>::Node *previous = m_edgeList.previous(leftmost);
+ if (!previous)
+ break;
+ const Edge &edge = m_edges.at(previous->data);
+ const QPodPoint &u = m_parent->m_vertices.at((qint32)edge.from);
+ const QPodPoint &v = m_parent->m_vertices.at((qint32)edge.to);
+ if (!currentIntersectionPoint.isOnLine(u, v)) {
+ Q_ASSERT(!currentIntersectionPoint.isAccurate() || qCross(currentIntersectionPoint.upperLeft - u, v - u) != 0);
+ break;
+ }
+ leftmost = previous;
+ }
+
+ for (;;) {
+ QRBTree<int>::Node *next = m_edgeList.next(rightmost);
+ if (!next)
+ break;
+ const Edge &edge = m_edges.at(next->data);
+ const QPodPoint &u = m_parent->m_vertices.at((qint32)edge.from);
+ const QPodPoint &v = m_parent->m_vertices.at((qint32)edge.to);
+ if (!currentIntersectionPoint.isOnLine(u, v)) {
+ Q_ASSERT(!currentIntersectionPoint.isAccurate() || qCross(currentIntersectionPoint.upperLeft - u, v - u) != 0);
+ break;
+ }
+ rightmost = next;
+ }
+
+ Q_ASSERT(leftmost && rightmost);
+ splitEdgeListRange(leftmost, rightmost, currentVertex, currentIntersectionPoint);
+ reorderEdgeListRange(leftmost, rightmost);
+
+ while (!m_topIntersection.isEmpty() && m_topIntersection.top().intersectionPoint <= currentIntersectionPoint)
+ m_topIntersection.pop();
+
+#ifdef Q_TRIANGULATOR_DEBUG
+ DebugDialog dialog(this, intersection.vertex);
+ dialog.exec();
+#endif
+
+ }
+}
+
+template <typename T>
+void QTriangulator<T>::ComplexToSimple::fillPriorityQueue()
+{
+ m_events.reset();
+ m_events.reserve(m_edges.size() * 2);
+ for (int i = 0; i < m_edges.size(); ++i) {
+ Q_ASSERT(m_edges.at(i).previous == -1 && m_edges.at(i).next == -1);
+ Q_ASSERT(m_edges.at(i).node == 0);
+ Q_ASSERT(m_edges.at(i).pointingUp == m_edges.at(i).originallyPointingUp);
+ Q_ASSERT(m_edges.at(i).pointingUp == (m_parent->m_vertices.at(m_edges.at(i).to) < m_parent->m_vertices.at(m_edges.at(i).from)));
+ // Ignore zero-length edges.
+ if (m_parent->m_vertices.at(m_edges.at(i).to) != m_parent->m_vertices.at(m_edges.at(i).from)) {
+ QPodPoint upper = m_parent->m_vertices.at(m_edges.at(i).upper());
+ QPodPoint lower = m_parent->m_vertices.at(m_edges.at(i).lower());
+ Event upperEvent = {{upper.x, upper.y}, Event::Upper, i};
+ Event lowerEvent = {{lower.x, lower.y}, Event::Lower, i};
+ m_events.add(upperEvent);
+ m_events.add(lowerEvent);
+ }
+ }
+ //qSort(m_events.data(), m_events.data() + m_events.size());
+ sort(m_events.data(), m_events.size());
+}
+
+template <typename T>
+void QTriangulator<T>::ComplexToSimple::calculateIntersections()
+{
+ fillPriorityQueue();
+
+ Q_ASSERT(m_topIntersection.empty());
+ Q_ASSERT(m_edgeList.root == 0);
+
+ // Find all intersection points.
+ while (!m_events.isEmpty()) {
+ Event event = m_events.last();
+ sortEdgeList(event.point);
+
+ // Find all edges in the edge list that contain the current vertex and mark them to be split later.
+ QPair<QRBTree<int>::Node *, QRBTree<int>::Node *> range = bounds(event.point);
+ QRBTree<int>::Node *leftNode = range.first ? m_edgeList.previous(range.first) : 0;
+ int vertex = (event.type == Event::Upper ? m_edges.at(event.edge).upper() : m_edges.at(event.edge).lower());
+ QIntersectionPoint eventPoint = QT_PREPEND_NAMESPACE(qIntersectionPoint)(event.point);
+
+ if (range.first != 0) {
+ splitEdgeListRange(range.first, range.second, vertex, eventPoint);
+ reorderEdgeListRange(range.first, range.second);
+ }
+
+ // Handle the edges with start or end point in the current vertex.
+ while (!m_events.isEmpty() && m_events.last().point == event.point) {
+ event = m_events.last();
+ m_events.pop_back();
+ int i = event.edge;
+
+ if (m_edges.at(i).node) {
+ // Remove edge from edge list.
+ Q_ASSERT(event.type == Event::Lower);
+ QRBTree<int>::Node *left = m_edgeList.previous(m_edges.at(i).node);
+ QRBTree<int>::Node *right = m_edgeList.next(m_edges.at(i).node);
+ m_edgeList.deleteNode(m_edges.at(i).node);
+ if (!left || !right)
+ continue;
+ calculateIntersection(left->data, right->data);
+ } else {
+ // Insert edge into edge list.
+ Q_ASSERT(event.type == Event::Upper);
+ QRBTree<int>::Node *left = searchEdgeLeftOf(i, leftNode);
+ m_edgeList.attachAfter(left, m_edges.at(i).node = m_edgeList.newNode());
+ m_edges.at(i).node->data = i;
+ QRBTree<int>::Node *right = m_edgeList.next(m_edges.at(i).node);
+ if (left)
+ calculateIntersection(left->data, i);
+ if (right)
+ calculateIntersection(i, right->data);
+ }
+ }
+ while (!m_topIntersection.isEmpty() && m_topIntersection.top().intersectionPoint <= eventPoint)
+ m_topIntersection.pop();
+#ifdef Q_TRIANGULATOR_DEBUG
+ DebugDialog dialog(this, vertex);
+ dialog.exec();
+#endif
+ }
+ m_processedEdgePairs.clear();
+}
+
+// Split an edge into two pieces at the given point.
+// The upper piece is pushed to the end of the 'm_edges' vector.
+// The lower piece replaces the old edge.
+// Return the edge whose 'from' is 'pointIndex'.
+template <typename T>
+int QTriangulator<T>::ComplexToSimple::splitEdge(int splitIndex)
+{
+ const Split &split = m_splits.at(splitIndex);
+ Edge &lowerEdge = m_edges.at(split.edge);
+ Q_ASSERT(lowerEdge.node == 0);
+ Q_ASSERT(lowerEdge.previous == -1 && lowerEdge.next == -1);
+
+ if (lowerEdge.from == split.vertex)
+ return split.edge;
+ if (lowerEdge.to == split.vertex)
+ return lowerEdge.next;
+
+ // Check that angle >= 90 degrees.
+ //Q_ASSERT(qDot(m_points.at(m_edges.at(edgeIndex).from) - m_points.at(pointIndex),
+ // m_points.at(m_edges.at(edgeIndex).to) - m_points.at(pointIndex)) <= 0);
+
+ Edge upperEdge = lowerEdge;
+ upperEdge.mayIntersect |= !split.accurate; // The edge may have been split before at an inaccurate split point.
+ lowerEdge.mayIntersect = !split.accurate;
+ if (lowerEdge.pointingUp) {
+ lowerEdge.to = upperEdge.from = split.vertex;
+ m_edges.add(upperEdge);
+ return m_edges.size() - 1;
+ } else {
+ lowerEdge.from = upperEdge.to = split.vertex;
+ m_edges.add(upperEdge);
+ return split.edge;
+ }
+}
+
+template <typename T>
+bool QTriangulator<T>::ComplexToSimple::splitEdgesAtIntersections()
+{
+ for (int i = 0; i < m_edges.size(); ++i)
+ m_edges.at(i).mayIntersect = false;
+ bool checkForNewIntersections = false;
+ for (int i = 0; i < m_splits.size(); ++i) {
+ splitEdge(i);
+ checkForNewIntersections |= !m_splits.at(i).accurate;
+ }
+ for (int i = 0; i < m_edges.size(); ++i) {
+ m_edges.at(i).originallyPointingUp = m_edges.at(i).pointingUp =
+ m_parent->m_vertices.at(m_edges.at(i).to) < m_parent->m_vertices.at(m_edges.at(i).from);
+ }
+ m_splits.reset();
+ return checkForNewIntersections;
+}
+
+template <typename T>
+void QTriangulator<T>::ComplexToSimple::insertEdgeIntoVectorIfWanted(ShortArray &orderedEdges, int i)
+{
+ // Edges with zero length should not reach this part.
+ Q_ASSERT(m_parent->m_vertices.at(m_edges.at(i).from) != m_parent->m_vertices.at(m_edges.at(i).to));
+
+ // Skip edges with unwanted winding number.
+ int windingNumber = m_edges.at(i).winding;
+ if (m_edges.at(i).originallyPointingUp)
+ ++windingNumber;
+
+ // Make sure exactly one fill rule is specified.
+ Q_ASSERT(((m_parent->m_hint & QVectorPath::WindingFill) != 0) != ((m_parent->m_hint & QVectorPath::OddEvenFill) != 0));
+
+ if ((m_parent->m_hint & QVectorPath::WindingFill) && windingNumber != 0 && windingNumber != 1)
+ return;
+
+ // Skip cancelling edges.
+ if (!orderedEdges.isEmpty()) {
+ int j = orderedEdges[orderedEdges.size() - 1];
+ // If the last edge is already connected in one end, it should not be cancelled.
+ if (m_edges.at(j).next == -1 && m_edges.at(j).previous == -1
+ && (m_parent->m_vertices.at(m_edges.at(i).from) == m_parent->m_vertices.at(m_edges.at(j).to))
+ && (m_parent->m_vertices.at(m_edges.at(i).to) == m_parent->m_vertices.at(m_edges.at(j).from))) {
+ orderedEdges.removeLast();
+ return;
+ }
+ }
+ orderedEdges.append(i);
+}
+
+template <typename T>
+void QTriangulator<T>::ComplexToSimple::removeUnwantedEdgesAndConnect()
+{
+ Q_ASSERT(m_edgeList.root == 0);
+ // Initialize priority queue.
+ fillPriorityQueue();
+
+ ShortArray orderedEdges;
+
+ while (!m_events.isEmpty()) {
+ Event event = m_events.last();
+ int edgeIndex = event.edge;
+
+ // Check that all the edges in the list crosses the current scanline
+ //if (m_edgeList.root) {
+ // for (QRBTree<int>::Node *node = m_edgeList.front(m_edgeList.root); node; node = m_edgeList.next(node)) {
+ // Q_ASSERT(event.point <= m_points.at(m_edges.at(node->data).lower()));
+ // }
+ //}
+
+ orderedEdges.clear();
+ QPair<QRBTree<int>::Node *, QRBTree<int>::Node *> b = outerBounds(event.point);
+ if (m_edgeList.root) {
+ QRBTree<int>::Node *current = (b.first ? m_edgeList.next(b.first) : m_edgeList.front(m_edgeList.root));
+ // Process edges that are going to be removed from the edge list at the current event point.
+ while (current != b.second) {
+ Q_ASSERT(current);
+ Q_ASSERT(m_edges.at(current->data).node == current);
+ Q_ASSERT(QT_PREPEND_NAMESPACE(qIntersectionPoint)(event.point).isOnLine(m_parent->m_vertices.at(m_edges.at(current->data).from), m_parent->m_vertices.at(m_edges.at(current->data).to)));
+ Q_ASSERT(m_parent->m_vertices.at(m_edges.at(current->data).from) == event.point || m_parent->m_vertices.at(m_edges.at(current->data).to) == event.point);
+ insertEdgeIntoVectorIfWanted(orderedEdges, current->data);
+ current = m_edgeList.next(current);
+ }
+ }
+
+ // Remove edges above the event point, insert edges below the event point.
+ do {
+ event = m_events.last();
+ m_events.pop_back();
+ edgeIndex = event.edge;
+
+ // Edges with zero length should not reach this part.
+ Q_ASSERT(m_parent->m_vertices.at(m_edges.at(edgeIndex).from) != m_parent->m_vertices.at(m_edges.at(edgeIndex).to));
+
+ if (m_edges.at(edgeIndex).node) {
+ Q_ASSERT(event.type == Event::Lower);
+ Q_ASSERT(event.point == m_parent->m_vertices.at(m_edges.at(event.edge).lower()));
+ m_edgeList.deleteNode(m_edges.at(edgeIndex).node);
+ } else {
+ Q_ASSERT(event.type == Event::Upper);
+ Q_ASSERT(event.point == m_parent->m_vertices.at(m_edges.at(event.edge).upper()));
+ QRBTree<int>::Node *left = searchEdgeLeftOf(edgeIndex, b.first);
+ m_edgeList.attachAfter(left, m_edges.at(edgeIndex).node = m_edgeList.newNode());
+ m_edges.at(edgeIndex).node->data = edgeIndex;
+ }
+ } while (!m_events.isEmpty() && m_events.last().point == event.point);
+
+ if (m_edgeList.root) {
+ QRBTree<int>::Node *current = (b.first ? m_edgeList.next(b.first) : m_edgeList.front(m_edgeList.root));
+
+ // Calculate winding number and turn counter-clockwise.
+ int currentWindingNumber = (b.first ? m_edges.at(b.first->data).winding : 0);
+ while (current != b.second) {
+ Q_ASSERT(current);
+ //Q_ASSERT(b.second == 0 || m_edgeList.order(current, b.second) < 0);
+ int i = current->data;
+ Q_ASSERT(m_edges.at(i).node == current);
+
+ // Winding number.
+ int ccwWindingNumber = m_edges.at(i).winding = currentWindingNumber;
+ if (m_edges.at(i).originallyPointingUp) {
+ --m_edges.at(i).winding;
+ } else {
+ ++m_edges.at(i).winding;
+ ++ccwWindingNumber;
+ }
+ currentWindingNumber = m_edges.at(i).winding;
+
+ // Turn counter-clockwise.
+ if ((ccwWindingNumber & 1) == 0) {
+ Q_ASSERT(m_edges.at(i).previous == -1 && m_edges.at(i).next == -1);
+ qSwap(m_edges.at(i).from, m_edges.at(i).to);
+ m_edges.at(i).pointingUp = !m_edges.at(i).pointingUp;
+ }
+
+ current = m_edgeList.next(current);
+ }
+
+ // Process edges that were inserted into the edge list at the current event point.
+ current = (b.second ? m_edgeList.previous(b.second) : m_edgeList.back(m_edgeList.root));
+ while (current != b.first) {
+ Q_ASSERT(current);
+ Q_ASSERT(m_edges.at(current->data).node == current);
+ insertEdgeIntoVectorIfWanted(orderedEdges, current->data);
+ current = m_edgeList.previous(current);
+ }
+ }
+ if (orderedEdges.isEmpty())
+ continue;
+
+ Q_ASSERT((orderedEdges.size() & 1) == 0);
+
+ // Connect edges.
+ // First make sure the first edge point towards the current point.
+ int i;
+ if (m_parent->m_vertices.at(m_edges.at(orderedEdges[0]).from) == event.point) {
+ i = 1;
+ int copy = orderedEdges[0]; // Make copy in case the append() will cause a reallocation.
+ orderedEdges.append(copy);
+ } else {
+ Q_ASSERT(m_parent->m_vertices.at(m_edges.at(orderedEdges[0]).to) == event.point);
+ i = 0;
+ }
+
+ // Remove references to duplicate points. First find the point with lowest index.
+ int pointIndex = INT_MAX;
+ for (int j = i; j < orderedEdges.size(); j += 2) {
+ Q_ASSERT(j + 1 < orderedEdges.size());
+ Q_ASSERT(m_parent->m_vertices.at(m_edges.at(orderedEdges[j]).to) == event.point);
+ Q_ASSERT(m_parent->m_vertices.at(m_edges.at(orderedEdges[j + 1]).from) == event.point);
+ if (m_edges.at(orderedEdges[j]).to < pointIndex)
+ pointIndex = m_edges.at(orderedEdges[j]).to;
+ if (m_edges.at(orderedEdges[j + 1]).from < pointIndex)
+ pointIndex = m_edges.at(orderedEdges[j + 1]).from;
+ }
+
+ for (; i < orderedEdges.size(); i += 2) {
+ // Remove references to duplicate points by making all edges reference one common point.
+ m_edges.at(orderedEdges[i]).to = m_edges.at(orderedEdges[i + 1]).from = pointIndex;
+
+ Q_ASSERT(m_edges.at(orderedEdges[i]).pointingUp || m_edges.at(orderedEdges[i]).previous != -1);
+ Q_ASSERT(!m_edges.at(orderedEdges[i + 1]).pointingUp || m_edges.at(orderedEdges[i + 1]).next != -1);
+
+ m_edges.at(orderedEdges[i]).next = orderedEdges[i + 1];
+ m_edges.at(orderedEdges[i + 1]).previous = orderedEdges[i];
+ }
+ } // end while
+}
+
+template <typename T>
+void QTriangulator<T>::ComplexToSimple::removeUnusedPoints() {
+ QBitArray used(m_parent->m_vertices.size(), false);
+ for (int i = 0; i < m_edges.size(); ++i) {
+ Q_ASSERT((m_edges.at(i).previous == -1) == (m_edges.at(i).next == -1));
+ if (m_edges.at(i).next != -1)
+ used.setBit(m_edges.at(i).from);
+ }
+ QDataBuffer<quint32> newMapping(m_parent->m_vertices.size());
+ newMapping.resize(m_parent->m_vertices.size());
+ int count = 0;
+ for (int i = 0; i < m_parent->m_vertices.size(); ++i) {
+ if (used.at(i)) {
+ m_parent->m_vertices.at(count) = m_parent->m_vertices.at(i);
+ newMapping.at(i) = count;
+ ++count;
+ }
+ }
+ m_parent->m_vertices.resize(count);
+ for (int i = 0; i < m_edges.size(); ++i) {
+ m_edges.at(i).from = newMapping.at(m_edges.at(i).from);
+ m_edges.at(i).to = newMapping.at(m_edges.at(i).to);
+ }
+}
+
+template <typename T>
+bool QTriangulator<T>::ComplexToSimple::CompareEdges::operator () (int i, int j) const
+{
+ int cmp = comparePoints(m_parent->m_parent->m_vertices.at(m_parent->m_edges.at(i).from),
+ m_parent->m_parent->m_vertices.at(m_parent->m_edges.at(j).from));
+ if (cmp == 0) {
+ cmp = comparePoints(m_parent->m_parent->m_vertices.at(m_parent->m_edges.at(i).to),
+ m_parent->m_parent->m_vertices.at(m_parent->m_edges.at(j).to));
+ }
+ return cmp > 0;
+}
+
+template <typename T>
+inline bool QTriangulator<T>::ComplexToSimple::Event::operator < (const Event &other) const
+{
+ if (point == other.point)
+ return type < other.type; // 'Lower' has higher priority than 'Upper'.
+ return other.point < point;
+}
+
+//============================================================================//
+// QTriangulator::ComplexToSimple::DebugDialog //
+//============================================================================//
+
+#ifdef Q_TRIANGULATOR_DEBUG
+template <typename T>
+QTriangulator<T>::ComplexToSimple::DebugDialog::DebugDialog(ComplexToSimple *parent, int currentVertex)
+ : m_parent(parent), m_vertex(currentVertex)
+{
+ QDataBuffer<QPodPoint> &vertices = m_parent->m_parent->m_vertices;
+ if (vertices.isEmpty())
+ return;
+
+ int minX, maxX, minY, maxY;
+ minX = maxX = vertices.at(0).x;
+ minY = maxY = vertices.at(0).y;
+ for (int i = 1; i < vertices.size(); ++i) {
+ minX = qMin(minX, vertices.at(i).x);
+ maxX = qMax(maxX, vertices.at(i).x);
+ minY = qMin(minY, vertices.at(i).y);
+ maxY = qMax(maxY, vertices.at(i).y);
+ }
+ int w = maxX - minX;
+ int h = maxY - minY;
+ qreal border = qMin(w, h) / 10.0;
+ m_window = QRectF(minX - border, minY - border, (maxX - minX + 2 * border), (maxY - minY + 2 * border));
+}
+
+template <typename T>
+void QTriangulator<T>::ComplexToSimple::DebugDialog::paintEvent(QPaintEvent *)
+{
+ QPainter p(this);
+ p.setRenderHint(QPainter::Antialiasing, true);
+ p.fillRect(rect(), Qt::black);
+ QDataBuffer<QPodPoint> &vertices = m_parent->m_parent->m_vertices;
+ if (vertices.isEmpty())
+ return;
+
+ qreal halfPointSize = qMin(m_window.width(), m_window.height()) / 300.0;
+ p.setWindow(m_window.toRect());
+
+ p.setPen(Qt::white);
+
+ QDataBuffer<Edge> &edges = m_parent->m_edges;
+ for (int i = 0; i < edges.size(); ++i) {
+ QPodPoint u = vertices.at(edges.at(i).from);
+ QPodPoint v = vertices.at(edges.at(i).to);
+ p.drawLine(u.x, u.y, v.x, v.y);
+ }
+
+ for (int i = 0; i < vertices.size(); ++i) {
+ QPodPoint q = vertices.at(i);
+ p.fillRect(QRectF(q.x - halfPointSize, q.y - halfPointSize, 2 * halfPointSize, 2 * halfPointSize), Qt::red);
+ }
+
+ Qt::GlobalColor colors[6] = {Qt::red, Qt::green, Qt::blue, Qt::cyan, Qt::magenta, Qt::yellow};
+ p.setOpacity(0.5);
+ int count = 0;
+ if (m_parent->m_edgeList.root) {
+ QRBTree<int>::Node *current = m_parent->m_edgeList.front(m_parent->m_edgeList.root);
+ while (current) {
+ p.setPen(colors[count++ % 6]);
+ QPodPoint u = vertices.at(edges.at(current->data).from);
+ QPodPoint v = vertices.at(edges.at(current->data).to);
+ p.drawLine(u.x, u.y, v.x, v.y);
+ current = m_parent->m_edgeList.next(current);
+ }
+ }
+
+ p.setOpacity(1.0);
+ QPodPoint q = vertices.at(m_vertex);
+ p.fillRect(QRectF(q.x - halfPointSize, q.y - halfPointSize, 2 * halfPointSize, 2 * halfPointSize), Qt::green);
+
+ p.setPen(Qt::gray);
+ QDataBuffer<Split> &splits = m_parent->m_splits;
+ for (int i = 0; i < splits.size(); ++i) {
+ QPodPoint q = vertices.at(splits.at(i).vertex);
+ QPodPoint u = vertices.at(edges.at(splits.at(i).edge).from) - q;
+ QPodPoint v = vertices.at(edges.at(splits.at(i).edge).to) - q;
+ qreal uLen = sqrt(qreal(qDot(u, u)));
+ qreal vLen = sqrt(qreal(qDot(v, v)));
+ if (uLen) {
+ u.x *= 2 * halfPointSize / uLen;
+ u.y *= 2 * halfPointSize / uLen;
+ }
+ if (vLen) {
+ v.x *= 2 * halfPointSize / vLen;
+ v.y *= 2 * halfPointSize / vLen;
+ }
+ u += q;
+ v += q;
+ p.drawLine(u.x, u.y, v.x, v.y);
+ }
+}
+
+template <typename T>
+void QTriangulator<T>::ComplexToSimple::DebugDialog::wheelEvent(QWheelEvent *event)
+{
+ qreal scale = exp(-0.001 * event->delta());
+ QPointF center = m_window.center();
+ QPointF delta = scale * (m_window.bottomRight() - center);
+ m_window = QRectF(center - delta, center + delta);
+ event->accept();
+ update();
+}
+
+template <typename T>
+void QTriangulator<T>::ComplexToSimple::DebugDialog::mouseMoveEvent(QMouseEvent *event)
+{
+ if (event->buttons() & Qt::LeftButton) {
+ QPointF delta = event->pos() - m_lastMousePos;
+ delta.setX(delta.x() * m_window.width() / width());
+ delta.setY(delta.y() * m_window.height() / height());
+ m_window.translate(-delta.x(), -delta.y());
+ m_lastMousePos = event->pos();
+ event->accept();
+ update();
+ }
+}
+
+template <typename T>
+void QTriangulator<T>::ComplexToSimple::DebugDialog::mousePressEvent(QMouseEvent *event)
+{
+ if (event->button() == Qt::LeftButton)
+ m_lastMousePos = event->pos();
+ event->accept();
+}
+
+
+#endif
+
+//============================================================================//
+// QTriangulator::SimpleToMonotone //
+//============================================================================//
+template <typename T>
+void QTriangulator<T>::SimpleToMonotone::decompose()
+{
+ setupDataStructures();
+ removeZeroLengthEdges();
+ monotoneDecomposition();
+
+ m_parent->m_indices.clear();
+ QBitArray processed(m_edges.size(), false);
+ for (int first = 0; first < m_edges.size(); ++first) {
+ if (processed.at(first))
+ continue;
+ int i = first;
+ do {
+ Q_ASSERT(!processed.at(i));
+ Q_ASSERT(m_edges.at(m_edges.at(i).next).previous == i);
+ m_parent->m_indices.push_back(m_edges.at(i).from);
+ processed.setBit(i);
+ i = m_edges.at(i).next;
+ } while (i != first);
+ if (m_parent->m_indices.size() > 0 && m_parent->m_indices.back() != T(-1)) // Q_TRIANGULATE_END_OF_POLYGON
+ m_parent->m_indices.push_back(T(-1)); // Q_TRIANGULATE_END_OF_POLYGON
+ }
+}
+
+template <typename T>
+void QTriangulator<T>::SimpleToMonotone::setupDataStructures()
+{
+ int i = 0;
+ Edge e;
+ e.node = 0;
+ e.twin = -1;
+
+ while (i + 3 <= m_parent->m_indices.size()) {
+ int start = m_edges.size();
+
+ do {
+ e.from = m_parent->m_indices.at(i);
+ e.type = RegularVertex;
+ e.next = m_edges.size() + 1;
+ e.previous = m_edges.size() - 1;
+ m_edges.add(e);
+ ++i;
+ Q_ASSERT(i < m_parent->m_indices.size());
+ } while (m_parent->m_indices.at(i) != T(-1)); // Q_TRIANGULATE_END_OF_POLYGON
+
+ m_edges.last().next = start;
+ m_edges.at(start).previous = m_edges.size() - 1;
+ ++i; // Skip Q_TRIANGULATE_END_OF_POLYGON.
+ }
+
+ for (i = 0; i < m_edges.size(); ++i) {
+ m_edges.at(i).to = m_edges.at(m_edges.at(i).next).from;
+ m_edges.at(i).pointingUp = m_parent->m_vertices.at(m_edges.at(i).to) < m_parent->m_vertices.at(m_edges.at(i).from);
+ m_edges.at(i).helper = -1; // Not initialized here.
+ }
+}
+
+template <typename T>
+void QTriangulator<T>::SimpleToMonotone::removeZeroLengthEdges()
+{
+ for (int i = 0; i < m_edges.size(); ++i) {
+ if (m_parent->m_vertices.at(m_edges.at(i).from) == m_parent->m_vertices.at(m_edges.at(i).to)) {
+ m_edges.at(m_edges.at(i).previous).next = m_edges.at(i).next;
+ m_edges.at(m_edges.at(i).next).previous = m_edges.at(i).previous;
+ m_edges.at(m_edges.at(i).next).from = m_edges.at(i).from;
+ m_edges.at(i).next = -1; // Mark as removed.
+ }
+ }
+
+ QDataBuffer<int> newMapping(m_edges.size());
+ newMapping.resize(m_edges.size());
+ int count = 0;
+ for (int i = 0; i < m_edges.size(); ++i) {
+ if (m_edges.at(i).next != -1) {
+ m_edges.at(count) = m_edges.at(i);
+ newMapping.at(i) = count;
+ ++count;
+ }
+ }
+ m_edges.resize(count);
+ for (int i = 0; i < m_edges.size(); ++i) {
+ m_edges.at(i).next = newMapping.at(m_edges.at(i).next);
+ m_edges.at(i).previous = newMapping.at(m_edges.at(i).previous);
+ }
+}
+
+template <typename T>
+void QTriangulator<T>::SimpleToMonotone::fillPriorityQueue()
+{
+ m_upperVertex.reset();
+ m_upperVertex.reserve(m_edges.size());
+ for (int i = 0; i < m_edges.size(); ++i)
+ m_upperVertex.add(i);
+ CompareVertices cmp(this);
+ //qSort(m_upperVertex.data(), m_upperVertex.data() + m_upperVertex.size(), cmp);
+ sort(m_upperVertex.data(), m_upperVertex.size(), cmp);
+ //for (int i = 1; i < m_upperVertex.size(); ++i) {
+ // Q_ASSERT(!cmp(m_upperVertex.at(i), m_upperVertex.at(i - 1)));
+ //}
+}
+
+template <typename T>
+bool QTriangulator<T>::SimpleToMonotone::edgeIsLeftOfEdge(int leftEdgeIndex, int rightEdgeIndex) const
+{
+ const Edge &leftEdge = m_edges.at(leftEdgeIndex);
+ const Edge &rightEdge = m_edges.at(rightEdgeIndex);
+ const QPodPoint &u = m_parent->m_vertices.at(rightEdge.upper());
+ const QPodPoint &l = m_parent->m_vertices.at(rightEdge.lower());
+ qint64 d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(m_parent->m_vertices.at(leftEdge.upper()), l, u);
+ // d < 0: left, d > 0: right, d == 0: on top
+ if (d == 0)
+ d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(m_parent->m_vertices.at(leftEdge.lower()), l, u);
+ return d < 0;
+}
+
+// Returns the rightmost edge not to the right of the given edge.
+template <typename T>
+QRBTree<int>::Node *QTriangulator<T>::SimpleToMonotone::searchEdgeLeftOfEdge(int edgeIndex) const
+{
+ QRBTree<int>::Node *current = m_edgeList.root;
+ QRBTree<int>::Node *result = 0;
+ while (current) {
+ if (edgeIsLeftOfEdge(edgeIndex, current->data)) {
+ current = current->left;
+ } else {
+ result = current;
+ current = current->right;
+ }
+ }
+ return result;
+}
+
+// Returns the rightmost edge left of the given point.
+template <typename T>
+QRBTree<int>::Node *QTriangulator<T>::SimpleToMonotone::searchEdgeLeftOfPoint(int pointIndex) const
+{
+ QRBTree<int>::Node *current = m_edgeList.root;
+ QRBTree<int>::Node *result = 0;
+ while (current) {
+ const QPodPoint &p1 = m_parent->m_vertices.at(m_edges.at(current->data).lower());
+ const QPodPoint &p2 = m_parent->m_vertices.at(m_edges.at(current->data).upper());
+ qint64 d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(m_parent->m_vertices.at(pointIndex), p1, p2);
+ if (d <= 0) {
+ current = current->left;
+ } else {
+ result = current;
+ current = current->right;
+ }
+ }
+ return result;
+}
+
+template <typename T>
+void QTriangulator<T>::SimpleToMonotone::classifyVertex(int i)
+{
+ Edge &e2 = m_edges.at(i);
+ const Edge &e1 = m_edges.at(e2.previous);
+
+ bool startOrSplit = (e1.pointingUp && !e2.pointingUp);
+ bool endOrMerge = (!e1.pointingUp && e2.pointingUp);
+
+ const QPodPoint &p1 = m_parent->m_vertices.at(e1.from);
+ const QPodPoint &p2 = m_parent->m_vertices.at(e2.from);
+ const QPodPoint &p3 = m_parent->m_vertices.at(e2.to);
+ qint64 d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(p1, p2, p3);
+ Q_ASSERT(d != 0 || (!startOrSplit && !endOrMerge));
+
+ e2.type = RegularVertex;
+
+ if (m_clockwiseOrder) {
+ if (startOrSplit)
+ e2.type = (d < 0 ? SplitVertex : StartVertex);
+ else if (endOrMerge)
+ e2.type = (d < 0 ? MergeVertex : EndVertex);
+ } else {
+ if (startOrSplit)
+ e2.type = (d > 0 ? SplitVertex : StartVertex);
+ else if (endOrMerge)
+ e2.type = (d > 0 ? MergeVertex : EndVertex);
+ }
+}
+
+template <typename T>
+void QTriangulator<T>::SimpleToMonotone::classifyVertices()
+{
+ for (int i = 0; i < m_edges.size(); ++i)
+ classifyVertex(i);
+}
+
+template <typename T>
+bool QTriangulator<T>::SimpleToMonotone::pointIsInSector(const QPodPoint &p, const QPodPoint &v1, const QPodPoint &v2, const QPodPoint &v3)
+{
+ bool leftOfPreviousEdge = !qPointIsLeftOfLine(p, v2, v1);
+ bool leftOfNextEdge = !qPointIsLeftOfLine(p, v3, v2);
+
+ if (qPointIsLeftOfLine(v1, v2, v3))
+ return leftOfPreviousEdge && leftOfNextEdge;
+ else
+ return leftOfPreviousEdge || leftOfNextEdge;
+}
+
+template <typename T>
+bool QTriangulator<T>::SimpleToMonotone::pointIsInSector(int vertex, int sector)
+{
+ const QPodPoint &center = m_parent->m_vertices.at(m_edges.at(sector).from);
+ // Handle degenerate edges.
+ while (m_parent->m_vertices.at(m_edges.at(vertex).from) == center)
+ vertex = m_edges.at(vertex).next;
+ int next = m_edges.at(sector).next;
+ while (m_parent->m_vertices.at(m_edges.at(next).from) == center)
+ next = m_edges.at(next).next;
+ int previous = m_edges.at(sector).previous;
+ while (m_parent->m_vertices.at(m_edges.at(previous).from) == center)
+ previous = m_edges.at(previous).previous;
+
+ const QPodPoint &p = m_parent->m_vertices.at(m_edges.at(vertex).from);
+ const QPodPoint &v1 = m_parent->m_vertices.at(m_edges.at(previous).from);
+ const QPodPoint &v3 = m_parent->m_vertices.at(m_edges.at(next).from);
+ if (m_clockwiseOrder)
+ return pointIsInSector(p, v3, center, v1);
+ else
+ return pointIsInSector(p, v1, center, v3);
+}
+
+template <typename T>
+int QTriangulator<T>::SimpleToMonotone::findSector(int edge, int vertex)
+{
+ while (!pointIsInSector(vertex, edge)) {
+ edge = m_edges.at(m_edges.at(edge).previous).twin;
+ Q_ASSERT(edge != -1);
+ }
+ return edge;
+}
+
+template <typename T>
+void QTriangulator<T>::SimpleToMonotone::createDiagonal(int lower, int upper)
+{
+ lower = findSector(lower, upper);
+ upper = findSector(upper, lower);
+
+ int prevLower = m_edges.at(lower).previous;
+ int prevUpper = m_edges.at(upper).previous;
+
+ Edge e;
+
+ e.twin = m_edges.size() + 1;
+ e.next = upper;
+ e.previous = prevLower;
+ e.from = m_edges.at(lower).from;
+ e.to = m_edges.at(upper).from;
+ m_edges.at(upper).previous = m_edges.at(prevLower).next = int(m_edges.size());
+ m_edges.add(e);
+
+ e.twin = m_edges.size() - 1;
+ e.next = lower;
+ e.previous = prevUpper;
+ e.from = m_edges.at(upper).from;
+ e.to = m_edges.at(lower).from;
+ m_edges.at(lower).previous = m_edges.at(prevUpper).next = int(m_edges.size());
+ m_edges.add(e);
+}
+
+template <typename T>
+void QTriangulator<T>::SimpleToMonotone::monotoneDecomposition()
+{
+ if (m_edges.isEmpty())
+ return;
+
+ Q_ASSERT(!m_edgeList.root);
+ QDataBuffer<QPair<int, int> > diagonals(m_upperVertex.size());
+
+ int i = 0;
+ for (int index = 1; index < m_edges.size(); ++index) {
+ if (m_parent->m_vertices.at(m_edges.at(index).from) < m_parent->m_vertices.at(m_edges.at(i).from))
+ i = index;
+ }
+ Q_ASSERT(i < m_edges.size());
+ int j = m_edges.at(i).previous;
+ Q_ASSERT(j < m_edges.size());
+ m_clockwiseOrder = qPointIsLeftOfLine(m_parent->m_vertices.at((quint32)m_edges.at(i).from),
+ m_parent->m_vertices.at((quint32)m_edges.at(j).from), m_parent->m_vertices.at((quint32)m_edges.at(i).to));
+
+ classifyVertices();
+ fillPriorityQueue();
+
+ // debug: set helpers explicitly (shouldn't be necessary)
+ //for (int i = 0; i < m_edges.size(); ++i)
+ // m_edges.at(i).helper = m_edges.at(i).upper();
+
+ while (!m_upperVertex.isEmpty()) {
+ i = m_upperVertex.last();
+ Q_ASSERT(i < m_edges.size());
+ m_upperVertex.pop_back();
+ j = m_edges.at(i).previous;
+ Q_ASSERT(j < m_edges.size());
+
+ QRBTree<int>::Node *leftEdgeNode = 0;
+
+ switch (m_edges.at(i).type) {
+ case RegularVertex:
+ // If polygon interior is to the right of the vertex...
+ if (m_edges.at(i).pointingUp == m_clockwiseOrder) {
+ if (m_edges.at(i).node) {
+ Q_ASSERT(!m_edges.at(j).node);
+ if (m_edges.at(m_edges.at(i).helper).type == MergeVertex)
+ diagonals.add(QPair<int, int>(i, m_edges.at(i).helper));
+ m_edges.at(j).node = m_edges.at(i).node;
+ m_edges.at(i).node = 0;
+ m_edges.at(j).node->data = j;
+ m_edges.at(j).helper = i;
+ } else if (m_edges.at(j).node) {
+ Q_ASSERT(!m_edges.at(i).node);
+ if (m_edges.at(m_edges.at(j).helper).type == MergeVertex)
+ diagonals.add(QPair<int, int>(i, m_edges.at(j).helper));
+ m_edges.at(i).node = m_edges.at(j).node;
+ m_edges.at(j).node = 0;
+ m_edges.at(i).node->data = i;
+ m_edges.at(i).helper = i;
+ } else {
+ qWarning("Inconsistent polygon. (#1)");
+ }
+ } else {
+ leftEdgeNode = searchEdgeLeftOfPoint(m_edges.at(i).from);
+ if (leftEdgeNode) {
+ if (m_edges.at(m_edges.at(leftEdgeNode->data).helper).type == MergeVertex)
+ diagonals.add(QPair<int, int>(i, m_edges.at(leftEdgeNode->data).helper));
+ m_edges.at(leftEdgeNode->data).helper = i;
+ } else {
+ qWarning("Inconsistent polygon. (#2)");
+ }
+ }
+ break;
+ case SplitVertex:
+ leftEdgeNode = searchEdgeLeftOfPoint(m_edges.at(i).from);
+ if (leftEdgeNode) {
+ diagonals.add(QPair<int, int>(i, m_edges.at(leftEdgeNode->data).helper));
+ m_edges.at(leftEdgeNode->data).helper = i;
+ } else {
+ qWarning("Inconsistent polygon. (#3)");
+ }
+ // Fall through.
+ case StartVertex:
+ if (m_clockwiseOrder) {
+ leftEdgeNode = searchEdgeLeftOfEdge(j);
+ QRBTree<int>::Node *node = m_edgeList.newNode();
+ node->data = j;
+ m_edges.at(j).node = node;
+ m_edges.at(j).helper = i;
+ m_edgeList.attachAfter(leftEdgeNode, node);
+ Q_ASSERT(m_edgeList.validate());
+ } else {
+ leftEdgeNode = searchEdgeLeftOfEdge(i);
+ QRBTree<int>::Node *node = m_edgeList.newNode();
+ node->data = i;
+ m_edges.at(i).node = node;
+ m_edges.at(i).helper = i;
+ m_edgeList.attachAfter(leftEdgeNode, node);
+ Q_ASSERT(m_edgeList.validate());
+ }
+ break;
+ case MergeVertex:
+ leftEdgeNode = searchEdgeLeftOfPoint(m_edges.at(i).from);
+ if (leftEdgeNode) {
+ if (m_edges.at(m_edges.at(leftEdgeNode->data).helper).type == MergeVertex)
+ diagonals.add(QPair<int, int>(i, m_edges.at(leftEdgeNode->data).helper));
+ m_edges.at(leftEdgeNode->data).helper = i;
+ } else {
+ qWarning("Inconsistent polygon. (#4)");
+ }
+ // Fall through.
+ case EndVertex:
+ if (m_clockwiseOrder) {
+ if (m_edges.at(m_edges.at(i).helper).type == MergeVertex)
+ diagonals.add(QPair<int, int>(i, m_edges.at(i).helper));
+ if (m_edges.at(i).node) {
+ m_edgeList.deleteNode(m_edges.at(i).node);
+ Q_ASSERT(m_edgeList.validate());
+ } else {
+ qWarning("Inconsistent polygon. (#5)");
+ }
+ } else {
+ if (m_edges.at(m_edges.at(j).helper).type == MergeVertex)
+ diagonals.add(QPair<int, int>(i, m_edges.at(j).helper));
+ if (m_edges.at(j).node) {
+ m_edgeList.deleteNode(m_edges.at(j).node);
+ Q_ASSERT(m_edgeList.validate());
+ } else {
+ qWarning("Inconsistent polygon. (#6)");
+ }
+ }
+ break;
+ }
+ }
+
+ for (int i = 0; i < diagonals.size(); ++i)
+ createDiagonal(diagonals.at(i).first, diagonals.at(i).second);
+}
+
+template <typename T>
+bool QTriangulator<T>::SimpleToMonotone::CompareVertices::operator () (int i, int j) const
+{
+ if (m_parent->m_edges.at(i).from == m_parent->m_edges.at(j).from)
+ return m_parent->m_edges.at(i).type > m_parent->m_edges.at(j).type;
+ return m_parent->m_parent->m_vertices.at(m_parent->m_edges.at(i).from) >
+ m_parent->m_parent->m_vertices.at(m_parent->m_edges.at(j).from);
+}
+
+//============================================================================//
+// QTriangulator::MonotoneToTriangles //
+//============================================================================//
+template <typename T>
+void QTriangulator<T>::MonotoneToTriangles::decompose()
+{
+ QVector<T> result;
+ QDataBuffer<int> stack(m_parent->m_indices.size());
+ m_first = 0;
+ // Require at least three more indices.
+ while (m_first + 3 <= m_parent->m_indices.size()) {
+ m_length = 0;
+ while (m_parent->m_indices.at(m_first + m_length) != T(-1)) { // Q_TRIANGULATE_END_OF_POLYGON
+ ++m_length;
+ Q_ASSERT(m_first + m_length < m_parent->m_indices.size());
+ }
+ if (m_length < 3) {
+ m_first += m_length + 1;
+ continue;
+ }
+
+ int minimum = 0;
+ while (less(next(minimum), minimum))
+ minimum = next(minimum);
+ while (less(previous(minimum), minimum))
+ minimum = previous(minimum);
+
+ stack.reset();
+ stack.add(minimum);
+ int left = previous(minimum);
+ int right = next(minimum);
+ bool stackIsOnLeftSide;
+ bool clockwiseOrder = leftOfEdge(minimum, left, right);
+
+ if (less(left, right)) {
+ stack.add(left);
+ left = previous(left);
+ stackIsOnLeftSide = true;
+ } else {
+ stack.add(right);
+ right = next(right);
+ stackIsOnLeftSide = false;
+ }
+
+ for (int count = 0; count + 2 < m_length; ++count)
+ {
+ Q_ASSERT(stack.size() >= 2);
+ if (less(left, right)) {
+ if (stackIsOnLeftSide == false) {
+ for (int i = 0; i + 1 < stack.size(); ++i) {
+ result.push_back(indices(stack.at(i + 1)));
+ result.push_back(indices(left));
+ result.push_back(indices(stack.at(i)));
+ }
+ stack.first() = stack.last();
+ stack.resize(1);
+ } else {
+ while (stack.size() >= 2 && (clockwiseOrder ^ !leftOfEdge(left, stack.at(stack.size() - 2), stack.last()))) {
+ result.push_back(indices(stack.at(stack.size() - 2)));
+ result.push_back(indices(left));
+ result.push_back(indices(stack.last()));
+ stack.pop_back();
+ }
+ }
+ stack.add(left);
+ left = previous(left);
+ stackIsOnLeftSide = true;
+ } else {
+ if (stackIsOnLeftSide == true) {
+ for (int i = 0; i + 1 < stack.size(); ++i) {
+ result.push_back(indices(stack.at(i)));
+ result.push_back(indices(right));
+ result.push_back(indices(stack.at(i + 1)));
+ }
+ stack.first() = stack.last();
+ stack.resize(1);
+ } else {
+ while (stack.size() >= 2 && (clockwiseOrder ^ !leftOfEdge(right, stack.last(), stack.at(stack.size() - 2)))) {
+ result.push_back(indices(stack.last()));
+ result.push_back(indices(right));
+ result.push_back(indices(stack.at(stack.size() - 2)));
+ stack.pop_back();
+ }
+ }
+ stack.add(right);
+ right = next(right);
+ stackIsOnLeftSide = false;
+ }
+ }
+
+ m_first += m_length + 1;
+ }
+ m_parent->m_indices = result;
+}
+
+//============================================================================//
+// qTriangulate //
+//============================================================================//
+
+static bool hasElementIndexUint()
+{
+ QOpenGLContext *context = QOpenGLContext::currentContext();
+ if (!context)
+ return false;
+ return static_cast<QOpenGLExtensions *>(context->functions())->hasOpenGLExtension(QOpenGLExtensions::ElementIndexUint);
+}
+
+Q_GUI_EXPORT QTriangleSet qTriangulate(const qreal *polygon,
+ int count, uint hint, const QTransform &matrix)
+{
+ QTriangleSet triangleSet;
+ if (hasElementIndexUint()) {
+ QTriangulator<quint32> triangulator;
+ triangulator.initialize(polygon, count, hint, matrix);
+ QVertexSet<quint32> vertexSet = triangulator.triangulate();
+ triangleSet.vertices = vertexSet.vertices;
+ triangleSet.indices.setDataUint(vertexSet.indices);
+
+ } else {
+ QTriangulator<quint16> triangulator;
+ triangulator.initialize(polygon, count, hint, matrix);
+ QVertexSet<quint16> vertexSet = triangulator.triangulate();
+ triangleSet.vertices = vertexSet.vertices;
+ triangleSet.indices.setDataUshort(vertexSet.indices);
+ }
+ return triangleSet;
+}
+
+Q_GUI_EXPORT QTriangleSet qTriangulate(const QVectorPath &path,
+ const QTransform &matrix, qreal lod)
+{
+ QTriangleSet triangleSet;
+ if (hasElementIndexUint()) {
+ QTriangulator<quint32> triangulator;
+ triangulator.initialize(path, matrix, lod);
+ QVertexSet<quint32> vertexSet = triangulator.triangulate();
+ triangleSet.vertices = vertexSet.vertices;
+ triangleSet.indices.setDataUint(vertexSet.indices);
+ } else {
+ QTriangulator<quint16> triangulator;
+ triangulator.initialize(path, matrix, lod);
+ QVertexSet<quint16> vertexSet = triangulator.triangulate();
+ triangleSet.vertices = vertexSet.vertices;
+ triangleSet.indices.setDataUshort(vertexSet.indices);
+ }
+ return triangleSet;
+}
+
+QTriangleSet qTriangulate(const QPainterPath &path,
+ const QTransform &matrix, qreal lod)
+{
+ QTriangleSet triangleSet;
+ if (hasElementIndexUint()) {
+ QTriangulator<quint32> triangulator;
+ triangulator.initialize(path, matrix, lod);
+ QVertexSet<quint32> vertexSet = triangulator.triangulate();
+ triangleSet.vertices = vertexSet.vertices;
+ triangleSet.indices.setDataUint(vertexSet.indices);
+ } else {
+ QTriangulator<quint16> triangulator;
+ triangulator.initialize(path, matrix, lod);
+ QVertexSet<quint16> vertexSet = triangulator.triangulate();
+ triangleSet.vertices = vertexSet.vertices;
+ triangleSet.indices.setDataUshort(vertexSet.indices);
+ }
+ return triangleSet;
+}
+
+QPolylineSet qPolyline(const QVectorPath &path,
+ const QTransform &matrix, qreal lod)
+{
+ QPolylineSet polyLineSet;
+ if (hasElementIndexUint()) {
+ QTriangulator<quint32> triangulator;
+ triangulator.initialize(path, matrix, lod);
+ QVertexSet<quint32> vertexSet = triangulator.polyline();
+ polyLineSet.vertices = vertexSet.vertices;
+ polyLineSet.indices.setDataUint(vertexSet.indices);
+ } else {
+ QTriangulator<quint16> triangulator;
+ triangulator.initialize(path, matrix, lod);
+ QVertexSet<quint16> vertexSet = triangulator.polyline();
+ polyLineSet.vertices = vertexSet.vertices;
+ polyLineSet.indices.setDataUshort(vertexSet.indices);
+ }
+ return polyLineSet;
+}
+
+QPolylineSet qPolyline(const QPainterPath &path,
+ const QTransform &matrix, qreal lod)
+{
+ QPolylineSet polyLineSet;
+ if (hasElementIndexUint()) {
+ QTriangulator<quint32> triangulator;
+ triangulator.initialize(path, matrix, lod);
+ QVertexSet<quint32> vertexSet = triangulator.polyline();
+ polyLineSet.vertices = vertexSet.vertices;
+ polyLineSet.indices.setDataUint(vertexSet.indices);
+ } else {
+ QTriangulator<quint16> triangulator;
+ triangulator.initialize(path, matrix, lod);
+ QVertexSet<quint16> vertexSet = triangulator.polyline();
+ polyLineSet.vertices = vertexSet.vertices;
+ polyLineSet.indices.setDataUshort(vertexSet.indices);
+ }
+ return polyLineSet;
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/opengl/qtriangulator_p.h b/src/gui/opengl/qtriangulator_p.h
new file mode 100644
index 0000000000..8f95d58e23
--- /dev/null
+++ b/src/gui/opengl/qtriangulator_p.h
@@ -0,0 +1,148 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTRIANGULATOR_P_H
+#define QTRIANGULATOR_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qvector.h>
+#include <QtGui/private/qvectorpath_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class Q_GUI_EXPORT QVertexIndexVector
+{
+public:
+ enum Type {
+ UnsignedInt,
+ UnsignedShort
+ };
+
+ inline Type type() const { return t; }
+
+ inline void setDataUint(const QVector<quint32> &data)
+ {
+ t = UnsignedInt;
+ indices32 = data;
+ }
+
+ inline void setDataUshort(const QVector<quint16> &data)
+ {
+ t = UnsignedShort;
+ indices16 = data;
+ }
+
+ inline const void* data() const
+ {
+ if (t == UnsignedInt)
+ return indices32.data();
+ return indices16.data();
+ }
+
+ inline int size() const
+ {
+ if (t == UnsignedInt)
+ return indices32.size();
+ return indices16.size();
+ }
+
+ inline QVertexIndexVector &operator = (const QVertexIndexVector &other)
+ {
+ if (t == UnsignedInt)
+ indices32 = other.indices32;
+ else
+ indices16 = other.indices16;
+
+ return *this;
+ }
+
+private:
+
+ Type t;
+ QVector<quint32> indices32;
+ QVector<quint16> indices16;
+};
+
+struct Q_GUI_EXPORT QTriangleSet
+{
+ inline QTriangleSet() { }
+ inline QTriangleSet(const QTriangleSet &other) : vertices(other.vertices), indices(other.indices) { }
+ QTriangleSet &operator = (const QTriangleSet &other) {vertices = other.vertices; indices = other.indices; return *this;}
+
+ // The vertices of a triangle are given by: (x[i[n]], y[i[n]]), (x[j[n]], y[j[n]]), (x[k[n]], y[k[n]]), n = 0, 1, ...
+ QVector<qreal> vertices; // [x[0], y[0], x[1], y[1], x[2], ...]
+ QVertexIndexVector indices; // [i[0], j[0], k[0], i[1], j[1], k[1], i[2], ...]
+};
+
+struct Q_GUI_EXPORT QPolylineSet
+{
+ inline QPolylineSet() { }
+ inline QPolylineSet(const QPolylineSet &other) : vertices(other.vertices), indices(other.indices) { }
+ QPolylineSet &operator = (const QPolylineSet &other) {vertices = other.vertices; indices = other.indices; return *this;}
+
+ QVector<qreal> vertices; // [x[0], y[0], x[1], y[1], x[2], ...]
+ QVertexIndexVector indices; // End of polyline is marked with -1.
+};
+
+// The vertex coordinates of the returned triangle set will be rounded to a grid with a mesh size
+// of 1/32. The polygon is first transformed, then scaled by 32, the coordinates are rounded to
+// integers, the polygon is triangulated, and then scaled back by 1/32.
+// 'hint' should be a combination of QVectorPath::Hints.
+// 'lod' is the level of detail. Default is 1. Curves are split into more lines when 'lod' is higher.
+QTriangleSet Q_GUI_EXPORT qTriangulate(const qreal *polygon, int count, uint hint = QVectorPath::PolygonHint | QVectorPath::OddEvenFill, const QTransform &matrix = QTransform());
+QTriangleSet Q_GUI_EXPORT qTriangulate(const QVectorPath &path, const QTransform &matrix = QTransform(), qreal lod = 1);
+QTriangleSet Q_GUI_EXPORT qTriangulate(const QPainterPath &path, const QTransform &matrix = QTransform(), qreal lod = 1);
+QPolylineSet qPolyline(const QVectorPath &path, const QTransform &matrix = QTransform(), qreal lod = 1);
+QPolylineSet Q_GUI_EXPORT qPolyline(const QPainterPath &path, const QTransform &matrix = QTransform(), qreal lod = 1);
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/gui/painting/makepsheader.pl b/src/gui/painting/makepsheader.pl
deleted file mode 100755
index 267c183606..0000000000
--- a/src/gui/painting/makepsheader.pl
+++ /dev/null
@@ -1,195 +0,0 @@
-#!/usr/bin/perl
-#############################################################################
-##
-## Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-## All rights reserved.
-## Contact: Nokia Corporation (qt-info@nokia.com)
-##
-## This file is part of the QtGui module of the Qt Toolkit.
-##
-## $QT_BEGIN_LICENSE:LGPL$
-## GNU Lesser General Public License Usage
-## This file may be used under the terms of the GNU Lesser General Public
-## License version 2.1 as published by the Free Software Foundation and
-## appearing in the file LICENSE.LGPL included in the packaging of this
-## file. Please review the following information to ensure the GNU Lesser
-## General Public License version 2.1 requirements will be met:
-## http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-##
-## In addition, as a special exception, Nokia gives you certain additional
-## rights. These rights are described in the Nokia Qt LGPL Exception
-## version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-##
-## 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.
-##
-## Other Usage
-## Alternatively, this file may be used in accordance with the terms and
-## conditions contained in a signed written agreement between you and Nokia.
-##
-##
-##
-##
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
-
-open(INPUT, 'qpsprinter.ps')
- or die "Can't open qpsprinter.ps";
-
-$dontcompress = 1;
-while(<INPUT>) {
- $line = $_;
- chomp $line;
- if ( /ENDUNCOMPRESS/ ) {
- $dontcompress = 0;
- }
- $line =~ s/%.*$//;
- $line = $line;
- if ( $dontcompress eq 1 ) {
- push(@uncompressed, $line);
- } else {
- push(@lines, $line);
- }
-# print "$line\n";
-}
-
-$uc = join(" ", @uncompressed);
-$uc =~ s,\t+, ,g;
-$uc=~ s, +, ,g;
-
-$h = join(" ", @lines);
-$h =~ s,\t+, ,g;
-$h =~ s, +, ,g;
-$h = $h.' ';
-
-# now compress as much as possible
-$h =~ s/ bind def / BD /g;
-$h =~ s/ dup dup / d2 /g;
-$h =~ s/ exch def / ED /g;
-$h =~ s/ setfont / F /g;
-$h =~ s/ rlineto / RL /g;
-$h =~ s/ newpath / n /g;
-$h =~ s/ currentmatrix / CM /g;
-$h =~ s/ setmatrix / SM /g;
-$h =~ s/ translate / TR /g;
-$h =~ s/ setdash / SD /g;
-$h =~ s/ aload pop setrgbcolor / SC /g;
-$h =~ s/ currentfile read pop / CR /g;
-$h =~ s/ index / i /g;
-$h =~ s/ bitshift / bs /g;
-$h =~ s/ setcolorspace / scs /g;
-$h =~ s/ dict dup begin / DB /g;
-$h =~ s/ end def / DE /g;
-$h =~ s/ ifelse / ie /g;
-
-# PDF compatible naming
-$h =~ s/ setlinewidth / w /g;
-$h =~ s/ setdash / d /g;
-
-$h =~ s/ lineto / l /g;
-$h =~ s/ moveto / m /g;
-$h =~ s/ curveto / c /g;
-$h =~ s/ closepath / h /g;
-$h =~ s/ clip / W /g;
-$h =~ s/ eoclip / W* /g;
-
-$h =~ s/ gsave / gs /g;
-$h =~ s/ grestore / gr /g;
-
-# add the uncompressed part of the header before
-$h = $uc.' '.$h;
-
-
-
-#print $h;
-
-# wordwrap at col 76
-@head = split(' ', $h);
-$line = shift @head;
-while( @head ) {
- $token = shift @head;
- chomp $token;
-# print "\nl=$l, len=$len, token=$token.";
- $newline = $line.' '.$token;
- $newline =~ s, /,/,g;
- $newline =~ s, \{,\{,g;
- $newline =~ s, \},\},g;
- $newline =~ s, \[,\[,g;
- $newline =~ s, \],\],g;
- $newline =~ s,\{ ,\{,g;
- $newline =~ s,\} ,\},g;
- $newline =~ s,\[ ,\[,g;
- $newline =~ s,\] ,\],g;
- if ( length( $newline ) > 76 ) {
-# print "\nline=$line\n";
- $header = $header."\n\"".$line."\\n\"";
- $newline = $token;
- }
- $line = $newline;
-}
-$header = $header."\n\"".$line."\\n\"";
-
-
-print "static const char *const ps_header =";
-print $header.";\n\n";
-
-close(INPUT);
-exit;
-
-open(INPUT, 'qpsprinter.agl')
- or die "Can't open qpsprinter.ps";
-
-print "static const char * const agl =\n";
-
-$str = "\"";
-$string ="";
-$i = 0;
-while(<INPUT>) {
- $line = $_;
- chomp $line;
- $line =~ s/#.*//;
- if(length($line) ne 0) {
- $num = $line;
- $name = $line;
- $num =~ s/,.*//;
- $name =~ s/.*, \"//;
- $name =~ s/\".*//;
- push(@qchar, $num);
- push(@index, $i);
- if(length($str.$name) > 76) {
- $str = $str."\"\n";
- $string = $string.$str;
- $str = "\"";
- }
- $str = $str.$name."\\0";
- $i += length($name)+1;
- }
-}
-
-print $string.";\n\n";
-
-print "static const struct { quint16 u; quint16 index; } unicodetoglyph[] = {\n ";
-
-$loop = 0;
-while( @qchar ) {
- $loop = $loop + 1;
- $ch = shift @qchar;
- $i = shift @index;
- print "{".$ch.", ".$i."}";
- if($ch ne "0xFFFF") {
- print ", ";
- }
- if(!($loop % 4)) {
- print "\n ";
- }
-};
-
-print "\n};\n\n";
-
diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri
index 13a9ba1c73..1481cb8520 100644
--- a/src/gui/painting/painting.pri
+++ b/src/gui/painting/painting.pri
@@ -1,23 +1,21 @@
# Qt gui library, paint module
HEADERS += \
+ painting/qbackingstore.h \
painting/qbezier_p.h \
painting/qbrush.h \
painting/qcolor.h \
painting/qcolor_p.h \
- painting/qcolormap.h \
painting/qcosmeticstroker_p.h \
- painting/qdrawutil.h \
painting/qemulationpaintengine_p.h \
- painting/qgraphicssystem_p.h \
painting/qmatrix.h \
painting/qmemrotate_p.h \
painting/qoutlinemapper_p.h \
+ painting/qpagedpaintdevice.h \
+ painting/qpagedpaintdevice_p.h \
painting/qpaintdevice.h \
painting/qpaintengine.h \
painting/qpaintengine_p.h \
- painting/qpaintengine_alpha_p.h \
- painting/qpaintengine_preview_p.h \
painting/qpaintengineex_p.h \
painting/qpainter.h \
painting/qpainter_p.h \
@@ -26,29 +24,21 @@ HEADERS += \
painting/qvectorpath_p.h \
painting/qpathclipper_p.h \
painting/qpdf_p.h \
+ painting/qpdfwriter.h \
painting/qpen.h \
painting/qpolygon.h \
painting/qpolygonclipper_p.h \
- painting/qprintengine.h \
- painting/qprintengine_pdf_p.h \
- painting/qprintengine_ps_p.h \
- painting/qprinter.h \
- painting/qprinter_p.h \
- painting/qprinterinfo.h \
- painting/qprinterinfo_p.h \
painting/qrasterizer_p.h \
painting/qregion.h \
painting/qstroker_p.h \
- painting/qstylepainter.h \
- painting/qtessellator_p.h \
painting/qtextureglyphcache_p.h \
painting/qtransform.h \
- painting/qwindowsurface_p.h \
- painting/qwmatrix.h \
+ painting/qplatformbackingstore_qpa.h \
painting/qpaintbuffer_p.h
SOURCES += \
+ painting/qbackingstore.cpp \
painting/qbezier.cpp \
painting/qblendfunctions.cpp \
painting/qbrush.cpp \
@@ -56,35 +46,28 @@ SOURCES += \
painting/qcolor_p.cpp \
painting/qcosmeticstroker.cpp \
painting/qcssutil.cpp \
- painting/qdrawutil.cpp \
painting/qemulationpaintengine.cpp \
- painting/qgraphicssystem.cpp \
painting/qmatrix.cpp \
painting/qmemrotate.cpp \
painting/qoutlinemapper.cpp \
+ painting/qpagedpaintdevice.cpp \
painting/qpaintdevice.cpp \
+ painting/qpaintdevice_qpa.cpp \
painting/qpaintengine.cpp \
- painting/qpaintengine_alpha.cpp \
- painting/qpaintengine_preview.cpp \
painting/qpaintengineex.cpp \
painting/qpainter.cpp \
painting/qpainterpath.cpp \
painting/qpathclipper.cpp \
painting/qpdf.cpp \
+ painting/qpdfwriter.cpp \
painting/qpen.cpp \
painting/qpolygon.cpp \
- painting/qprintengine_pdf.cpp \
- painting/qprintengine_ps.cpp \
- painting/qprinter.cpp \
- painting/qprinterinfo.cpp \
painting/qrasterizer.cpp \
painting/qregion.cpp \
painting/qstroker.cpp \
- painting/qstylepainter.cpp \
- painting/qtessellator.cpp \
painting/qtextureglyphcache.cpp \
painting/qtransform.cpp \
- painting/qwindowsurface.cpp \
+ painting/qplatformbackingstore_qpa.cpp \
painting/qpaintbuffer.cpp
SOURCES += \
@@ -104,117 +87,7 @@ SOURCES += \
painting/qpaintengine_blitter_p.h \
painting/qblittable_p.h \
-win32 {
- HEADERS += painting/qprintengine_win_p.h
- SOURCES += \
- painting/qcolormap_win.cpp \
- painting/qpaintdevice_win.cpp \
- painting/qprintengine_win.cpp \
- painting/qprinterinfo_win.cpp
-
- !win32-borland:!wince*:LIBS += -lmsimg32
-}
-
-embedded {
- HEADERS += \
- painting/qgraphicssystem_qws_p.h \
-
- SOURCES += \
- painting/qgraphicssystem_qws.cpp \
-
-} else: if(!qpa) {
- HEADERS += \
- painting/qgraphicssystem_raster_p.h \
- painting/qgraphicssystem_runtime_p.h \
- painting/qgraphicssystemfactory_p.h \
- painting/qgraphicssystemplugin_p.h \
- painting/qwindowsurface_raster_p.h
-
- SOURCES += \
- painting/qgraphicssystem_raster.cpp \
- painting/qgraphicssystem_runtime.cpp \
- painting/qgraphicssystemfactory.cpp \
- painting/qgraphicssystemplugin.cpp \
- painting/qwindowsurface_raster.cpp
-}
-
-unix:x11 {
- HEADERS += \
- painting/qpaintengine_x11_p.h
-
- SOURCES += \
- painting/qcolormap_x11.cpp \
- painting/qpaintdevice_x11.cpp \
- painting/qpaintengine_x11.cpp
-}
-
-!embedded:!qpa:!x11:mac {
- HEADERS += \
- painting/qpaintengine_mac_p.h \
- painting/qgraphicssystem_mac_p.h \
- painting/qprintengine_mac_p.h
-
- SOURCES += \
- painting/qcolormap_mac.cpp \
- painting/qpaintdevice_mac.cpp \
- painting/qpaintengine_mac.cpp \
- painting/qgraphicssystem_mac.cpp \
- painting/qprinterinfo_mac.cpp
- OBJECTIVE_SOURCES += \
- painting/qprintengine_mac.mm \
-}
-
-unix:!mac:!symbian|qpa {
- HEADERS += \
- painting/qprinterinfo_unix_p.h
- SOURCES += \
- painting/qprinterinfo_unix.cpp
-}
-
-win32|x11|mac|embedded|qpa|symbian {
- SOURCES += painting/qbackingstore.cpp
- HEADERS += painting/qbackingstore_p.h
-}
-
-embedded {
- contains(QT_CONFIG,qtopia) {
- DEFINES += QTOPIA_PRINTENGINE
- HEADERS += painting/qprintengine_qws_p.h
- SOURCES += painting/qprintengine_qws.cpp
- }
-
- SOURCES += \
- painting/qcolormap_qws.cpp \
- painting/qpaintdevice_qws.cpp
-}
-
-qpa {
- SOURCES += \
- painting/qcolormap_qpa.cpp \
- painting/qpaintdevice_qpa.cpp
-}
-
-symbian {
- SOURCES += \
- painting/qpaintengine_s60.cpp \
- painting/qregion_s60.cpp \
- painting/qcolormap_s60.cpp
-
- HEADERS += \
- painting/qpaintengine_s60_p.h
-}
-
-x11|embedded|qpa {
- contains(QT_CONFIG,qtopia) {
- DEFINES += QT_NO_CUPS QT_NO_LPR
- } else {
- SOURCES += painting/qcups.cpp
- HEADERS += painting/qcups_p.h
- }
-} else {
- DEFINES += QT_NO_CUPS QT_NO_LPR
-}
if(mmx|3dnow|sse|sse2|iwmmxt) {
HEADERS += painting/qdrawhelper_x86_p.h \
@@ -230,29 +103,8 @@ if(mmx|3dnow|sse|sse2|iwmmxt) {
IWMMXT_SOURCES += painting/qdrawhelper_iwmmxt.cpp
}
-x11 {
- HEADERS += painting/qwindowsurface_x11_p.h
- SOURCES += painting/qwindowsurface_x11.cpp
-}
-
-!embedded:!qpa:mac {
- HEADERS += painting/qwindowsurface_mac_p.h \
- painting/qunifiedtoolbarsurface_mac_p.h
- SOURCES += painting/qwindowsurface_mac.cpp \
- painting/qunifiedtoolbarsurface_mac.cpp
-}
-
-embedded {
- HEADERS += painting/qwindowsurface_qws_p.h
- SOURCES += painting/qwindowsurface_qws.cpp
-}
-
-
-
symbian {
- HEADERS += painting/qwindowsurface_s60_p.h \
- painting/qdrawhelper_arm_simd_p.h
- SOURCES += painting/qwindowsurface_s60.cpp
+ HEADERS += painting/qdrawhelper_arm_simd_p.h
armccIfdefBlock = \
"$${LITERAL_HASH}if defined(ARMV6)" \
"MACRO QT_HAVE_ARM_SIMD" \
diff --git a/src/gui/painting/qbackingstore.cpp b/src/gui/painting/qbackingstore.cpp
index 6fbb59fc89..f69a2e4ff6 100644
--- a/src/gui/painting/qbackingstore.cpp
+++ b/src/gui/painting/qbackingstore.cpp
@@ -39,1630 +39,218 @@
**
****************************************************************************/
+#include <qbackingstore.h>
+#include <qwindow.h>
+#include <qpixmap.h>
+#include <qplatformbackingstore_qpa.h>
+#include <qscreen.h>
-#include "qplatformdefs.h"
-
-#include "qbackingstore_p.h"
-
-#include <QtCore/qglobal.h>
-#include <QtCore/qdebug.h>
-#include <QtCore/qvarlengtharray.h>
-#include <QtGui/qevent.h>
-#include <QtGui/qapplication.h>
-#include <QtGui/qpaintengine.h>
-#include <QtGui/qgraphicsproxywidget.h>
-
-#include <private/qwidget_p.h>
-#include <private/qwindowsurface_raster_p.h>
-#include <private/qapplication_p.h>
-#include <private/qpaintengine_raster_p.h>
-#include <private/qgraphicseffect_p.h>
-
-#include "qgraphicssystem_p.h"
-
-#ifdef Q_WS_QWS
-#include <QtGui/qwsmanager_qws.h>
-#include <private/qwsmanager_p.h>
-#endif
+#include <private/qguiapplication_p.h>
+#include <private/qwindow_p.h>
QT_BEGIN_NAMESPACE
-extern QRegion qt_dirtyRegion(QWidget *);
-
-/*
- A version of QRect::intersects() that does not normalize the rects.
-*/
-static inline bool qRectIntersects(const QRect &r1, const QRect &r2)
-{
- return (qMax(r1.left(), r2.left()) <= qMin(r1.right(), r2.right())
- && qMax(r1.top(), r2.top()) <= qMin(r1.bottom(), r2.bottom()));
-}
-
-/**
- * Flushes the contents of the \a windowSurface into the screen area of \a widget.
- * \a tlwOffset is the position of the top level widget relative to the window surface.
- * \a region is the region to be updated in \a widget coordinates.
- */
-static inline void qt_flush(QWidget *widget, const QRegion &region, QWindowSurface *windowSurface,
- QWidget *tlw, const QPoint &tlwOffset)
-{
- Q_ASSERT(widget);
- Q_ASSERT(!region.isEmpty());
- Q_ASSERT(windowSurface);
- Q_ASSERT(tlw);
-
-#if !defined(QT_NO_PAINT_DEBUG) && !defined(Q_WS_QWS)
- // QWS does flush update in QWindowSurface::flush (because it needs to lock the surface etc).
- static int flushUpdate = qgetenv("QT_FLUSH_UPDATE").toInt();
- if (flushUpdate > 0)
- QWidgetBackingStore::showYellowThing(widget, region, flushUpdate * 10, false);
-#endif
-
- //The performance hit by doing this should be negligible. However, be aware that
- //using this FPS when you have > 1 windowsurface can give you inaccurate FPS
- static bool fpsDebug = qgetenv("QT_DEBUG_FPS").toInt();
- if (fpsDebug) {
- static QTime time = QTime::currentTime();
- static int frames = 0;
-
- frames++;
-
- if(time.elapsed() > 5000) {
- double fps = double(frames * 1000) /time.restart();
- fprintf(stderr,"FPS: %.1f\n",fps);
- frames = 0;
- }
- }
- if (widget != tlw)
- windowSurface->flush(widget, region, tlwOffset + widget->mapTo(tlw, QPoint()));
- else
- windowSurface->flush(widget, region, tlwOffset);
-}
-
-#ifndef QT_NO_PAINT_DEBUG
-#ifdef Q_WS_WIN
-static void showYellowThing_win(QWidget *widget, const QRegion &region, int msec)
-{
- HBRUSH brush;
- static int i = 0;
- switch (i) {
- case 0:
- brush = CreateSolidBrush(RGB(255, 255, 0));
- break;
- case 1:
- brush = CreateSolidBrush(RGB(255, 200, 55));
- break;
- case 2:
- brush = CreateSolidBrush(RGB(200, 255, 55));
- break;
- case 3:
- brush = CreateSolidBrush(RGB(200, 200, 0));
- break;
- }
- i = (i + 1) & 3;
-
- HDC hdc = widget->getDC();
-
- const QVector<QRect> &rects = region.rects();
- foreach (QRect rect, rects) {
- RECT winRect;
- SetRect(&winRect, rect.left(), rect.top(), rect.right(), rect.bottom());
- FillRect(hdc, &winRect, brush);
- }
-
- widget->releaseDC(hdc);
- ::Sleep(msec);
-}
-#endif
-
-void QWidgetBackingStore::showYellowThing(QWidget *widget, const QRegion &toBePainted, int msec, bool unclipped)
+class QBackingStorePrivate
{
-#ifdef Q_WS_QWS
- Q_UNUSED(widget);
- Q_UNUSED(unclipped);
- static QWSYellowSurface surface(true);
- surface.setDelay(msec);
- surface.flush(widget, toBePainted, QPoint());
-#else
- QRegion paintRegion = toBePainted;
- QRect widgetRect = widget->rect();
-
- if (!widget->internalWinId()) {
- QWidget *nativeParent = widget->nativeParentWidget();
- const QPoint offset = widget->mapTo(nativeParent, QPoint(0, 0));
- paintRegion.translate(offset);
- widgetRect.translate(offset);
- widget = nativeParent;
+public:
+ QBackingStorePrivate(QWindow *w)
+ : window(w)
+ {
}
-#ifdef Q_WS_WIN
- Q_UNUSED(unclipped);
- showYellowThing_win(widget, paintRegion, msec);
-#else
- //flags to fool painter
- bool paintUnclipped = widget->testAttribute(Qt::WA_PaintUnclipped);
- if (unclipped && !widget->d_func()->paintOnScreen())
- widget->setAttribute(Qt::WA_PaintUnclipped);
-
- const bool setFlag = !widget->testAttribute(Qt::WA_WState_InPaintEvent);
- if (setFlag)
- widget->setAttribute(Qt::WA_WState_InPaintEvent);
-
- //setup the engine
- QPaintEngine *pe = widget->paintEngine();
- if (pe) {
- pe->setSystemClip(paintRegion);
- {
- QPainter p(widget);
- p.setClipRegion(paintRegion);
- static int i = 0;
- switch (i) {
- case 0:
- p.fillRect(widgetRect, QColor(255,255,0));
- break;
- case 1:
- p.fillRect(widgetRect, QColor(255,200,55));
- break;
- case 2:
- p.fillRect(widgetRect, QColor(200,255,55));
- break;
- case 3:
- p.fillRect(widgetRect, QColor(200,200,0));
- break;
- }
- i = (i+1) & 3;
- p.end();
- }
- }
+ QWindow *window;
+ QPlatformBackingStore *platformBackingStore;
+ QRegion staticContents;
+ QSize size;
+};
- if (setFlag)
- widget->setAttribute(Qt::WA_WState_InPaintEvent, false);
+/*!
+ \class QBackingStore
+ \since 5.0
- //restore
- widget->setAttribute(Qt::WA_PaintUnclipped, paintUnclipped);
+ \brief The QBackingStore class provides the drawing area for top-level windows.
+*/
- if (pe)
- pe->setSystemClip(QRegion());
- QApplication::syncX();
+/*!
+ \fn void QBackingStore::beginPaint(const QRegion &region)
-#if defined(Q_OS_UNIX)
- ::usleep(1000 * msec);
-#endif
-#endif // Q_WS_WIN
-#endif // Q_WS_QWS
-}
+ This function is called before painting onto the surface begins,
+ with the \a region in which the painting will occur.
-bool QWidgetBackingStore::flushPaint(QWidget *widget, const QRegion &rgn)
-{
- if (!widget)
- return false;
+ \sa endPaint(), paintDevice()
+*/
- int delay = 0;
- if (widget->testAttribute(Qt::WA_WState_InPaintEvent)) {
- static int flushPaintEvent = qgetenv("QT_FLUSH_PAINT_EVENT").toInt();
- if (!flushPaintEvent)
- return false;
- delay = flushPaintEvent;
- } else {
- static int flushPaint = qgetenv("QT_FLUSH_PAINT").toInt();
- if (!flushPaint)
- return false;
- delay = flushPaint;
- }
+/*!
+ \fn void QBackingStore::endPaint(const QRegion &region)
- QWidgetBackingStore::showYellowThing(widget, rgn, delay * 10, true);
- return true;
-}
+ This function is called after painting onto the surface has ended,
+ with the \a region in which the painting was performed.
-void QWidgetBackingStore::unflushPaint(QWidget *widget, const QRegion &rgn)
-{
- if (widget->d_func()->paintOnScreen() || rgn.isEmpty())
- return;
+ \sa beginPaint(), paintDevice()
+*/
- QWidget *tlw = widget->window();
- QTLWExtra *tlwExtra = tlw->d_func()->maybeTopData();
- if (!tlwExtra)
- return;
+/*!
+ \fn void QBackingStore::flush(QWindow *window, const QRegion &region,
+ const QPoint &offset)
- const QPoint offset = widget->mapTo(tlw, QPoint());
- qt_flush(widget, rgn, tlwExtra->backingStore->windowSurface, tlw, offset);
-}
-#endif // QT_NO_PAINT_DEBUG
+ Flushes the given \a region from the specified \a window onto the
+ screen.
-/*
- Moves the whole rect by (dx, dy) in widget's coordinate system.
- Doesn't generate any updates.
+ Note that the \a offset parameter is currently unused.
*/
-bool QWidgetBackingStore::bltRect(const QRect &rect, int dx, int dy, QWidget *widget)
+void QBackingStore::flush(const QRegion &region, QWindow *win, const QPoint &offset)
{
- const QPoint pos(tlwOffset + widget->mapTo(tlw, rect.topLeft()));
- const QRect tlwRect(QRect(pos, rect.size()));
- if (fullUpdatePending || dirty.intersects(tlwRect))
- return false; // We don't want to scroll junk.
- return windowSurface->scroll(tlwRect, dx, dy);
-}
-
-void QWidgetBackingStore::releaseBuffer()
-{
- if (windowSurface)
-#if defined(Q_WS_QPA)
- windowSurface->resize(QSize());
-#else
- windowSurface->setGeometry(QRect());
-#endif
-#ifdef Q_BACKINGSTORE_SUBSURFACES
- for (int i = 0; i < subSurfaces.size(); ++i)
- subSurfaces.at(i)->setGeometry(QRect());
-#endif
+ if (!win)
+ win = window();
+ d_ptr->platformBackingStore->flush(win, region, offset);
}
/*!
- Prepares the window surface to paint a\ toClean region of the \a widget and
- updates the BeginPaintInfo struct accordingly.
+ \fn QPaintDevice* QBackingStore::paintDevice()
- The \a toClean region might be clipped by the window surface.
+ Implement this function to return the appropriate paint device.
*/
-void QWidgetBackingStore::beginPaint(QRegion &toClean, QWidget *widget, QWindowSurface *windowSurface,
- BeginPaintInfo *returnInfo, bool toCleanIsInTopLevelCoordinates)
+QPaintDevice *QBackingStore::paintDevice()
{
-#ifdef Q_WS_QWS
- QWSWindowSurface *surface = static_cast<QWSWindowSurface *>(windowSurface);
- QWidget *surfaceWidget = surface->window();
-
- if (!surface->isValid()) {
- // this looks strange but it really just releases the surface
- surface->releaseSurface();
- // the old window surface is deleted in setWindowSurface, which is
- // called from QWindowSurface constructor.
- windowSurface = tlw->d_func()->createDefaultWindowSurface();
- surface = static_cast<QWSWindowSurface *>(windowSurface);
- // createDefaultWindowSurface() will set topdata->windowSurface on the
- // widget to zero. However, if this is a sub-surface, it should point
- // to the widget's sub windowSurface, so we set that here:
- if (!surfaceWidget->isWindow())
- surfaceWidget->d_func()->topData()->windowSurface = windowSurface;
- surface->setGeometry(topLevelRect());
- returnInfo->windowSurfaceRecreated = true;
- }
-
- const QRegion toCleanUnclipped(toClean);
-
- if (surfaceWidget->isWindow())
- tlwOffset = surface->painterOffset();
-#ifdef Q_BACKINGSTORE_SUBSURFACES
- else if (toCleanIsInTopLevelCoordinates)
- toClean &= surface->clipRegion().translated(surfaceWidget->mapTo(tlw, QPoint()));
- if (!toCleanIsInTopLevelCoordinates && windowSurface == this->windowSurface)
- toClean &= surface->clipRegion().translated(-widget->mapTo(surfaceWidget, QPoint()));
-#else
- toClean &= surface->clipRegion();
-#endif
-
- if (toClean.isEmpty()) {
- if (surfaceWidget->isWindow()) {
- dirtyFromPreviousSync += toCleanUnclipped;
- hasDirtyFromPreviousSync = true;
- }
-
- returnInfo->nothingToPaint = true;
- // Nothing to repaint. However, we might have newly exposed areas on the
- // screen, so we have to make sure those are flushed.
- flush();
- return;
- }
-
- if (surfaceWidget->isWindow()) {
- if (toCleanUnclipped != toClean) {
- dirtyFromPreviousSync += (toCleanUnclipped - surface->clipRegion());
- hasDirtyFromPreviousSync = true;
- }
- if (hasDirtyFromPreviousSync) {
- dirtyFromPreviousSync -= toClean;
- hasDirtyFromPreviousSync = !dirtyFromPreviousSync.isEmpty();
- }
- }
-
-#endif // Q_WS_QWS
-
- Q_UNUSED(widget);
- Q_UNUSED(toCleanIsInTopLevelCoordinates);
-
- // Always flush repainted areas.
- dirtyOnScreen += toClean;
-
-#if defined(Q_WS_QWS) && !defined(Q_BACKINGSTORE_SUBSURFACES)
- toClean.translate(tlwOffset);
-#endif
-
-#ifdef QT_NO_PAINT_DEBUG
- windowSurface->beginPaint(toClean);
-#else
- returnInfo->wasFlushed = QWidgetBackingStore::flushPaint(tlw, toClean);
- // Avoid deadlock with QT_FLUSH_PAINT: the server will wait for
- // the BackingStore lock, so if we hold that, the server will
- // never release the Communication lock that we are waiting for in
- // sendSynchronousCommand
- if (!returnInfo->wasFlushed)
- windowSurface->beginPaint(toClean);
-#endif
-
- Q_UNUSED(returnInfo);
+ return d_ptr->platformBackingStore->paintDevice();
}
-void QWidgetBackingStore::endPaint(const QRegion &cleaned, QWindowSurface *windowSurface,
- BeginPaintInfo *beginPaintInfo)
+/*!
+ Constructs an empty surface for the given top-level \a window.
+*/
+QBackingStore::QBackingStore(QWindow *window)
+ : d_ptr(new QBackingStorePrivate(window))
{
-#ifndef QT_NO_PAINT_DEBUG
- if (!beginPaintInfo->wasFlushed)
- windowSurface->endPaint(cleaned);
- else
- QWidgetBackingStore::unflushPaint(tlw, cleaned);
-#else
- Q_UNUSED(beginPaintInfo);
- windowSurface->endPaint(cleaned);
-#endif
-
-#ifdef Q_BACKINGSTORE_SUBSURFACES
- flush(static_cast<QWSWindowSurface *>(windowSurface)->window(), windowSurface);
-#else
- flush();
-#endif
+ d_ptr->platformBackingStore = QGuiApplicationPrivate::platformIntegration()->createPlatformBackingStore(window);
}
/*!
- Returns the region (in top-level coordinates) that needs repaint and/or flush.
-
- If the widget is non-zero, only the dirty region for the widget is returned
- and the region will be in widget coordinates.
+ Destroys this surface.
*/
-QRegion QWidgetBackingStore::dirtyRegion(QWidget *widget) const
+QBackingStore::~QBackingStore()
{
- const bool widgetDirty = widget && widget != tlw;
- const QRect tlwRect(topLevelRect());
-#if defined(Q_WS_QPA)
- const QRect surfaceGeometry(tlwRect.topLeft(), windowSurface->size());
-#else
- const QRect surfaceGeometry(windowSurface->geometry());
-#endif
- if (fullUpdatePending || (surfaceGeometry != tlwRect && surfaceGeometry.size() != tlwRect.size())) {
- if (widgetDirty) {
- const QRect dirtyTlwRect = QRect(QPoint(), tlwRect.size());
- const QPoint offset(widget->mapTo(tlw, QPoint()));
- const QRect dirtyWidgetRect(dirtyTlwRect & widget->rect().translated(offset));
- return dirtyWidgetRect.translated(-offset);
- }
- return QRect(QPoint(), tlwRect.size());
- }
-
- // Calculate the region that needs repaint.
- QRegion r(dirty);
- for (int i = 0; i < dirtyWidgets.size(); ++i) {
- QWidget *w = dirtyWidgets.at(i);
- if (widgetDirty && w != widget && !widget->isAncestorOf(w))
- continue;
- r += w->d_func()->dirty.translated(w->mapTo(tlw, QPoint()));
- }
-
- // Append the region that needs flush.
- r += dirtyOnScreen;
-
- if (dirtyOnScreenWidgets) { // Only in use with native child widgets.
- for (int i = 0; i < dirtyOnScreenWidgets->size(); ++i) {
- QWidget *w = dirtyOnScreenWidgets->at(i);
- if (widgetDirty && w != widget && !widget->isAncestorOf(w))
- continue;
- QWidgetPrivate *wd = w->d_func();
- Q_ASSERT(wd->needsFlush);
- r += wd->needsFlush->translated(w->mapTo(tlw, QPoint()));
- }
- }
-
- if (widgetDirty) {
- // Intersect with the widget geometry and translate to its coordinates.
- const QPoint offset(widget->mapTo(tlw, QPoint()));
- r &= widget->rect().translated(offset);
- r.translate(-offset);
- }
- return r;
+ delete d_ptr->platformBackingStore;
}
/*!
- Returns the static content inside the \a parent if non-zero; otherwise the static content
- for the entire backing store is returned. The content will be clipped to \a withinClipRect
- if non-empty.
+ Returns a pointer to the top-level window associated with this
+ surface.
*/
-QRegion QWidgetBackingStore::staticContents(QWidget *parent, const QRect &withinClipRect) const
+QWindow* QBackingStore::window() const
{
- if (!parent && tlw->testAttribute(Qt::WA_StaticContents)) {
-#if defined(Q_WS_QPA)
- const QSize surfaceGeometry(windowSurface->size());
-#else
- const QRect surfaceGeometry(windowSurface->geometry());
-#endif
- QRect surfaceRect(0, 0, surfaceGeometry.width(), surfaceGeometry.height());
- if (!withinClipRect.isEmpty())
- surfaceRect &= withinClipRect;
- return QRegion(surfaceRect);
- }
-
- QRegion region;
- if (parent && parent->d_func()->children.isEmpty())
- return region;
-
- const bool clipToRect = !withinClipRect.isEmpty();
- const int count = staticWidgets.count();
- for (int i = 0; i < count; ++i) {
- QWidget *w = staticWidgets.at(i);
- QWidgetPrivate *wd = w->d_func();
- if (!wd->isOpaque || !wd->extra || wd->extra->staticContentsSize.isEmpty()
- || !w->isVisible() || (parent && !parent->isAncestorOf(w))) {
- continue;
- }
-
- QRect rect(0, 0, wd->extra->staticContentsSize.width(), wd->extra->staticContentsSize.height());
- const QPoint offset = w->mapTo(parent ? parent : tlw, QPoint());
- if (clipToRect)
- rect &= withinClipRect.translated(-offset);
- if (rect.isEmpty())
- continue;
-
- rect &= wd->clipRect();
- if (rect.isEmpty())
- continue;
-
- QRegion visible(rect);
- wd->clipToEffectiveMask(visible);
- if (visible.isEmpty())
- continue;
- wd->subtractOpaqueSiblings(visible, 0, /*alsoNonOpaque=*/true);
-
- visible.translate(offset);
- region += visible;
- }
-
- return region;
+ return d_ptr->window;
}
-static inline void sendUpdateRequest(QWidget *widget, bool updateImmediately)
+void QBackingStore::beginPaint(const QRegion &region)
{
- if (!widget)
- return;
-
- if (updateImmediately) {
- QEvent event(QEvent::UpdateRequest);
- QApplication::sendEvent(widget, &event);
- } else {
- QApplication::postEvent(widget, new QEvent(QEvent::UpdateRequest), Qt::LowEventPriority);
- }
+ d_ptr->platformBackingStore->beginPaint(region);
}
-/*!
- Marks the region of the widget as dirty (if not already marked as dirty) and
- posts an UpdateRequest event to the top-level widget (if not already posted).
-
- If updateImmediately is true, the event is sent immediately instead of posted.
-
- If invalidateBuffer is true, all widgets intersecting with the region will be dirty.
-
- If the widget paints directly on screen, the event is sent to the widget
- instead of the top-level widget, and invalidateBuffer is completely ignored.
-
- ### Qt 4.6: Merge into a template function (after MSVC isn't supported anymore).
-*/
-void QWidgetBackingStore::markDirty(const QRegion &rgn, QWidget *widget, bool updateImmediately,
- bool invalidateBuffer)
+void QBackingStore::endPaint()
{
- Q_ASSERT(tlw->d_func()->extra);
- Q_ASSERT(tlw->d_func()->extra->topextra);
- Q_ASSERT(!tlw->d_func()->extra->topextra->inTopLevelResize);
- Q_ASSERT(widget->isVisible() && widget->updatesEnabled());
- Q_ASSERT(widget->window() == tlw);
- Q_ASSERT(!rgn.isEmpty());
-
-#ifndef QT_NO_GRAPHICSEFFECT
- widget->d_func()->invalidateGraphicsEffectsRecursively();
-#endif //QT_NO_GRAPHICSEFFECT
-
- if (widget->d_func()->paintOnScreen()) {
- if (widget->d_func()->dirty.isEmpty()) {
- widget->d_func()->dirty = rgn;
- sendUpdateRequest(widget, updateImmediately);
- return;
- } else if (qt_region_strictContains(widget->d_func()->dirty, widget->rect())) {
- if (updateImmediately)
- sendUpdateRequest(widget, updateImmediately);
- return; // Already dirty.
- }
-
- const bool eventAlreadyPosted = !widget->d_func()->dirty.isEmpty();
- widget->d_func()->dirty += rgn;
- if (!eventAlreadyPosted || updateImmediately)
- sendUpdateRequest(widget, updateImmediately);
- return;
- }
-
- if (fullUpdatePending) {
- if (updateImmediately)
- sendUpdateRequest(tlw, updateImmediately);
- return;
- }
-
- if (!windowSurface->hasFeature(QWindowSurface::PartialUpdates)) {
- fullUpdatePending = true;
- sendUpdateRequest(tlw, updateImmediately);
- return;
- }
-
- const QPoint offset = widget->mapTo(tlw, QPoint());
- const QRect widgetRect = widget->d_func()->effectiveRectFor(widget->rect());
- if (qt_region_strictContains(dirty, widgetRect.translated(offset))) {
- if (updateImmediately)
- sendUpdateRequest(tlw, updateImmediately);
- return; // Already dirty.
- }
-
- if (invalidateBuffer) {
- const bool eventAlreadyPosted = !dirty.isEmpty();
-#ifndef QT_NO_GRAPHICSEFFECT
- if (widget->d_func()->graphicsEffect)
- dirty += widget->d_func()->effectiveRectFor(rgn.boundingRect()).translated(offset);
- else
-#endif //QT_NO_GRAPHICSEFFECT
- dirty += rgn.translated(offset);
- if (!eventAlreadyPosted || updateImmediately)
- sendUpdateRequest(tlw, updateImmediately);
- return;
- }
-
- if (dirtyWidgets.isEmpty()) {
- addDirtyWidget(widget, rgn);
- sendUpdateRequest(tlw, updateImmediately);
- return;
- }
-
- if (widget->d_func()->inDirtyList) {
- if (!qt_region_strictContains(widget->d_func()->dirty, widgetRect)) {
-#ifndef QT_NO_GRAPHICSEFFECT
- if (widget->d_func()->graphicsEffect)
- widget->d_func()->dirty += widget->d_func()->effectiveRectFor(rgn.boundingRect());
- else
-#endif //QT_NO_GRAPHICSEFFECT
- widget->d_func()->dirty += rgn;
- }
- } else {
- addDirtyWidget(widget, rgn);
- }
-
- if (updateImmediately)
- sendUpdateRequest(tlw, updateImmediately);
+ d_ptr->platformBackingStore->endPaint();
}
/*!
- This function is equivalent to calling markDirty(QRegion(rect), ...), but
- is more efficient as it eliminates QRegion operations/allocations and can
- use the rect more precisely for additional cut-offs.
+ Sets the size of the windowsurface to be \a size.
- ### Qt 4.6: Merge into a template function (after MSVC isn't supported anymore).
+ \sa size()
*/
-void QWidgetBackingStore::markDirty(const QRect &rect, QWidget *widget, bool updateImmediately,
- bool invalidateBuffer)
+void QBackingStore::resize(const QSize &size)
{
- Q_ASSERT(tlw->d_func()->extra);
- Q_ASSERT(tlw->d_func()->extra->topextra);
- Q_ASSERT(!tlw->d_func()->extra->topextra->inTopLevelResize);
- Q_ASSERT(widget->isVisible() && widget->updatesEnabled());
- Q_ASSERT(widget->window() == tlw);
- Q_ASSERT(!rect.isEmpty());
-
-#ifndef QT_NO_GRAPHICSEFFECT
- widget->d_func()->invalidateGraphicsEffectsRecursively();
-#endif //QT_NO_GRAPHICSEFFECT
-
- if (widget->d_func()->paintOnScreen()) {
- if (widget->d_func()->dirty.isEmpty()) {
- widget->d_func()->dirty = QRegion(rect);
- sendUpdateRequest(widget, updateImmediately);
- return;
- } else if (qt_region_strictContains(widget->d_func()->dirty, rect)) {
- if (updateImmediately)
- sendUpdateRequest(widget, updateImmediately);
- return; // Already dirty.
- }
-
- const bool eventAlreadyPosted = !widget->d_func()->dirty.isEmpty();
- widget->d_func()->dirty += rect;
- if (!eventAlreadyPosted || updateImmediately)
- sendUpdateRequest(widget, updateImmediately);
- return;
- }
-
- if (fullUpdatePending) {
- if (updateImmediately)
- sendUpdateRequest(tlw, updateImmediately);
- return;
- }
-
- if (!windowSurface->hasFeature(QWindowSurface::PartialUpdates)) {
- fullUpdatePending = true;
- sendUpdateRequest(tlw, updateImmediately);
- return;
- }
-
- const QRect widgetRect = widget->d_func()->effectiveRectFor(rect);
- const QRect translatedRect(widgetRect.translated(widget->mapTo(tlw, QPoint())));
- if (qt_region_strictContains(dirty, translatedRect)) {
- if (updateImmediately)
- sendUpdateRequest(tlw, updateImmediately);
- return; // Already dirty
- }
-
- if (invalidateBuffer) {
- const bool eventAlreadyPosted = !dirty.isEmpty();
- dirty += translatedRect;
- if (!eventAlreadyPosted || updateImmediately)
- sendUpdateRequest(tlw, updateImmediately);
- return;
- }
-
- if (dirtyWidgets.isEmpty()) {
- addDirtyWidget(widget, rect);
- sendUpdateRequest(tlw, updateImmediately);
- return;
- }
-
- if (widget->d_func()->inDirtyList) {
- if (!qt_region_strictContains(widget->d_func()->dirty, widgetRect))
- widget->d_func()->dirty += widgetRect;
- } else {
- addDirtyWidget(widget, rect);
- }
-
- if (updateImmediately)
- sendUpdateRequest(tlw, updateImmediately);
+ d_ptr->size = size;
+ d_ptr->platformBackingStore->resize(size, d_ptr->staticContents);
}
/*!
- Marks the \a region of the \a widget as dirty on screen. The \a region will be copied from
- the backing store to the \a widget's native parent next time flush() is called.
-
- Paint on screen widgets are ignored.
+ Returns the current size of the windowsurface.
*/
-void QWidgetBackingStore::markDirtyOnScreen(const QRegion &region, QWidget *widget, const QPoint &topLevelOffset)
+QSize QBackingStore::size() const
{
- if (!widget || widget->d_func()->paintOnScreen() || region.isEmpty())
- return;
-
-#if defined(Q_WS_QWS) || defined(Q_WS_MAC)
- if (!widget->testAttribute(Qt::WA_WState_InPaintEvent))
- dirtyOnScreen += region.translated(topLevelOffset);
- return;
-#endif
-
- // Top-level.
- if (widget == tlw) {
- if (!widget->testAttribute(Qt::WA_WState_InPaintEvent))
- dirtyOnScreen += region;
- return;
- }
-
- // Alien widgets.
- if (!widget->internalWinId() && !widget->isWindow()) {
- QWidget *nativeParent = widget->nativeParentWidget(); // Alien widgets with the top-level as the native parent (common case).
- if (nativeParent == tlw) {
- if (!widget->testAttribute(Qt::WA_WState_InPaintEvent))
- dirtyOnScreen += region.translated(topLevelOffset);
- return;
- }
-
- // Alien widgets with native parent != tlw.
- QWidgetPrivate *nativeParentPrivate = nativeParent->d_func();
- if (!nativeParentPrivate->needsFlush)
- nativeParentPrivate->needsFlush = new QRegion;
- const QPoint nativeParentOffset = widget->mapTo(nativeParent, QPoint());
- *nativeParentPrivate->needsFlush += region.translated(nativeParentOffset);
- appendDirtyOnScreenWidget(nativeParent);
- return;
- }
-
- // Native child widgets.
- QWidgetPrivate *widgetPrivate = widget->d_func();
- if (!widgetPrivate->needsFlush)
- widgetPrivate->needsFlush = new QRegion;
- *widgetPrivate->needsFlush += region;
- appendDirtyOnScreenWidget(widget);
-}
-
-void QWidgetBackingStore::removeDirtyWidget(QWidget *w)
-{
- if (!w)
- return;
-
- dirtyWidgetsRemoveAll(w);
- dirtyOnScreenWidgetsRemoveAll(w);
- resetWidget(w);
-
- QWidgetPrivate *wd = w->d_func();
- const int n = wd->children.count();
- for (int i = 0; i < n; ++i) {
- if (QWidget *child = qobject_cast<QWidget*>(wd->children.at(i)))
- removeDirtyWidget(child);
- }
-}
-
-#if defined(Q_WS_QWS) && !defined(QT_NO_QWS_MANAGER)
-bool QWidgetBackingStore::hasDirtyWindowDecoration() const
-{
- QTLWExtra *tlwExtra = tlw->d_func()->maybeTopData();
- if (tlwExtra && tlwExtra->qwsManager)
- return !tlwExtra->qwsManager->d_func()->dirtyRegions.isEmpty();
- return false;
-}
-
-void QWidgetBackingStore::paintWindowDecoration()
-{
- if (!hasDirtyWindowDecoration())
- return;
-
- QDecoration &decoration = QApplication::qwsDecoration();
- const QRect decorationRect = tlw->rect();
- QRegion decorationRegion = decoration.region(tlw, decorationRect);
-
- QWSManagerPrivate *managerPrivate = tlw->d_func()->topData()->qwsManager->d_func();
- const bool doClipping = !managerPrivate->entireDecorationNeedsRepaint
- && !managerPrivate->dirtyClip.isEmpty();
-
- if (doClipping) {
- decorationRegion &= static_cast<QWSWindowSurface *>(windowSurface)->clipRegion();
- decorationRegion &= managerPrivate->dirtyClip;
- }
-
- if (decorationRegion.isEmpty())
- return;
-
- //### The QWS decorations do not always paint the pixels they promise to paint.
- // This causes painting problems with QWSMemorySurface. Since none of the other
- // window surfaces actually use the region, passing an empty region is a safe
- // workaround.
-
- windowSurface->beginPaint(QRegion());
-
- QPaintEngine *engine = windowSurface->paintDevice()->paintEngine();
- Q_ASSERT(engine);
- const QRegion oldSystemClip(engine->systemClip());
- engine->setSystemClip(decorationRegion.translated(tlwOffset));
-
- QPainter painter(windowSurface->paintDevice());
- painter.setFont(QApplication::font());
- painter.translate(tlwOffset);
-
- const int numDirty = managerPrivate->dirtyRegions.size();
- for (int i = 0; i < numDirty; ++i) {
- const int area = managerPrivate->dirtyRegions.at(i);
-
- QRegion clipRegion = decoration.region(tlw, decorationRect, area);
- if (!clipRegion.isEmpty()) {
- // Decoration styles changes the clip and assumes the old clip is non-empty,
- // so we have to set it, but in theory it shouldn't be required.
- painter.setClipRegion(clipRegion);
- decoration.paint(&painter, tlw, area, managerPrivate->dirtyStates.at(i));
- }
- }
- markDirtyOnScreen(decorationRegion, tlw, QPoint());
-
- painter.end();
- windowSurface->endPaint(decorationRegion);
- managerPrivate->clearDirtyRegions();
- engine->setSystemClip(oldSystemClip);
-}
-#endif
-
-void QWidgetBackingStore::updateLists(QWidget *cur)
-{
- if (!cur)
- return;
-
- QList<QObject*> children = cur->children();
- for (int i = 0; i < children.size(); ++i) {
- QWidget *child = qobject_cast<QWidget*>(children.at(i));
- if (!child)
- continue;
-
- updateLists(child);
- }
-
- if (cur->testAttribute(Qt::WA_StaticContents))
- addStaticWidget(cur);
-
-#ifdef Q_BACKINGSTORE_SUBSURFACES
- QTLWExtra *extra = cur->d_func()->maybeTopData();
- if (extra && extra->windowSurface && cur != tlw)
- subSurfaces.append(extra->windowSurface);
-#endif
-}
-
-QWidgetBackingStore::QWidgetBackingStore(QWidget *topLevel)
- : tlw(topLevel), dirtyOnScreenWidgets(0), hasDirtyFromPreviousSync(false)
- , fullUpdatePending(0)
-{
- windowSurface = tlw->windowSurface();
- if (!windowSurface)
- windowSurface = topLevel->d_func()->createDefaultWindowSurface();
-
- // The QWindowSurface constructor will call QWidget::setWindowSurface(),
- // but automatically created surfaces should not be added to the topdata.
-#ifdef Q_BACKINGSTORE_SUBSURFACES
- Q_ASSERT(topLevel->d_func()->topData()->windowSurface == windowSurface);
-#endif
- topLevel->d_func()->topData()->windowSurface = 0;
-
- // Ensure all existing subsurfaces and static widgets are added to their respective lists.
- updateLists(topLevel);
-}
-
-QWidgetBackingStore::~QWidgetBackingStore()
-{
- for (int c = 0; c < dirtyWidgets.size(); ++c) {
- resetWidget(dirtyWidgets.at(c));
- }
-
- delete windowSurface;
- windowSurface = 0;
- delete dirtyOnScreenWidgets;
- dirtyOnScreenWidgets = 0;
-}
-
-//parent's coordinates; move whole rect; update parent and widget
-//assume the screen blt has already been done, so we don't need to refresh that part
-void QWidgetPrivate::moveRect(const QRect &rect, int dx, int dy)
-{
- Q_Q(QWidget);
- if (!q->isVisible() || (dx == 0 && dy == 0))
- return;
-
- QWidget *tlw = q->window();
- QTLWExtra* x = tlw->d_func()->topData();
- if (x->inTopLevelResize)
- return;
-
- static int accelEnv = -1;
- if (accelEnv == -1) {
- accelEnv = qgetenv("QT_NO_FAST_MOVE").toInt() == 0;
- }
-
- QWidget *pw = q->parentWidget();
- QPoint toplevelOffset = pw->mapTo(tlw, QPoint());
- QWidgetPrivate *pd = pw->d_func();
- QRect clipR(pd->clipRect());
-#ifdef Q_WS_QWS
- QWidgetBackingStore *wbs = x->backingStore.data();
- QWSWindowSurface *surface = static_cast<QWSWindowSurface*>(wbs->windowSurface);
- clipR = clipR.intersected(surface->clipRegion().translated(-toplevelOffset).boundingRect());
-#endif
- const QRect newRect(rect.translated(dx, dy));
- QRect destRect = rect.intersected(clipR);
- if (destRect.isValid())
- destRect = destRect.translated(dx, dy).intersected(clipR);
- const QRect sourceRect(destRect.translated(-dx, -dy));
- const QRect parentRect(rect & clipR);
-
- bool accelerateMove = accelEnv && isOpaque
-#ifndef QT_NO_GRAPHICSVIEW
- // No accelerate move for proxy widgets.
- && !tlw->d_func()->extra->proxyWidget
-#endif
- && !isOverlapped(sourceRect) && !isOverlapped(destRect);
-
- if (!accelerateMove) {
- QRegion parentR(effectiveRectFor(parentRect));
- if (!extra || !extra->hasMask) {
- parentR -= newRect;
- } else {
- // invalidateBuffer() excludes anything outside the mask
- parentR += newRect & clipR;
- }
- pd->invalidateBuffer(parentR);
- invalidateBuffer((newRect & clipR).translated(-data.crect.topLeft()));
- } else {
-
- QWidgetBackingStore *wbs = x->backingStore.data();
- QRegion childExpose(newRect & clipR);
-
- if (sourceRect.isValid() && wbs->bltRect(sourceRect, dx, dy, pw))
- childExpose -= destRect;
-
- if (!pw->updatesEnabled())
- return;
-
- const bool childUpdatesEnabled = q->updatesEnabled();
- if (childUpdatesEnabled && !childExpose.isEmpty()) {
- childExpose.translate(-data.crect.topLeft());
- wbs->markDirty(childExpose, q);
- isMoved = true;
- }
-
- QRegion parentExpose(parentRect);
- parentExpose -= newRect;
- if (extra && extra->hasMask)
- parentExpose += QRegion(newRect) - extra->mask.translated(data.crect.topLeft());
-
- if (!parentExpose.isEmpty()) {
- wbs->markDirty(parentExpose, pw);
- pd->isMoved = true;
- }
-
- if (childUpdatesEnabled) {
- QRegion needsFlush(sourceRect);
- needsFlush += destRect;
- wbs->markDirtyOnScreen(needsFlush, pw, toplevelOffset);
- }
- }
-}
-
-//widget's coordinates; scroll within rect; only update widget
-void QWidgetPrivate::scrollRect(const QRect &rect, int dx, int dy)
-{
- Q_Q(QWidget);
- QWidget *tlw = q->window();
- QTLWExtra* x = tlw->d_func()->topData();
- if (x->inTopLevelResize)
- return;
-
- QWidgetBackingStore *wbs = x->backingStore.data();
- if (!wbs)
- return;
-
- static int accelEnv = -1;
- if (accelEnv == -1) {
- accelEnv = qgetenv("QT_NO_FAST_SCROLL").toInt() == 0;
- }
-
- QRect scrollRect = rect & clipRect();
- bool overlapped = false;
- bool accelerateScroll = accelEnv && isOpaque
- && !(overlapped = isOverlapped(scrollRect.translated(data.crect.topLeft())));
-
-#if defined(Q_WS_QWS)
- QWSWindowSurface *surface;
- surface = static_cast<QWSWindowSurface*>(wbs->windowSurface);
-
- if (accelerateScroll && !surface->isBuffered()) {
- const QRegion surfaceClip = surface->clipRegion();
- const QRegion outsideClip = QRegion(rect) - surfaceClip;
- if (!outsideClip.isEmpty()) {
- const QVector<QRect> clipped = (surfaceClip & rect).rects();
- if (clipped.size() < 8) {
- for (int i = 0; i < clipped.size(); ++i)
- this->scrollRect(clipped.at(i), dx, dy);
- return;
- } else {
- accelerateScroll = false;
- }
- }
- }
-#endif // Q_WS_QWS
-
- if (!accelerateScroll) {
- if (overlapped) {
- QRegion region(scrollRect);
- subtractOpaqueSiblings(region);
- invalidateBuffer(region);
- }else {
- invalidateBuffer(scrollRect);
- }
- } else {
- const QPoint toplevelOffset = q->mapTo(tlw, QPoint());
-#ifdef Q_WS_QWS
- QWSWindowSurface *surface = static_cast<QWSWindowSurface*>(wbs->windowSurface);
- const QRegion clip = surface->clipRegion().translated(-toplevelOffset) & scrollRect;
- const QRect clipBoundingRect = clip.boundingRect();
- scrollRect &= clipBoundingRect;
-#endif
- const QRect destRect = scrollRect.translated(dx, dy) & scrollRect;
- const QRect sourceRect = destRect.translated(-dx, -dy);
-
- QRegion childExpose(scrollRect);
- if (sourceRect.isValid()) {
- if (wbs->bltRect(sourceRect, dx, dy, q))
- childExpose -= destRect;
- }
-
- if (inDirtyList) {
- if (rect == q->rect()) {
- dirty.translate(dx, dy);
- } else {
- QRegion dirtyScrollRegion = dirty.intersected(scrollRect);
- if (!dirtyScrollRegion.isEmpty()) {
- dirty -= dirtyScrollRegion;
- dirtyScrollRegion.translate(dx, dy);
- dirty += dirtyScrollRegion;
- }
- }
- }
-
- if (!q->updatesEnabled())
- return;
-
- if (!childExpose.isEmpty()) {
- wbs->markDirty(childExpose, q);
- isScrolled = true;
- }
-
- // Instead of using native scroll-on-screen, we copy from
- // backingstore, giving only one screen update for each
- // scroll, and a solid appearance
- wbs->markDirtyOnScreen(destRect, q, toplevelOffset);
- }
-}
-
-static inline bool discardSyncRequest(QWidget *tlw, QTLWExtra *tlwExtra)
-{
- if (!tlw || !tlwExtra)
- return true;
-
-#ifdef Q_WS_X11
- // Delay the sync until we get an Expose event from X11 (initial show).
- // Qt::WA_Mapped is set to true, but the actual mapping has not yet occurred.
- // However, we must repaint immediately regardless of the state if someone calls repaint().
- if (tlwExtra->waitingForMapNotify && !tlwExtra->inRepaint)
- return true;
-#endif
-
- if (!tlw->testAttribute(Qt::WA_Mapped))
- return true;
-
- if (!tlw->isVisible()
-#ifndef Q_WS_X11
- // If we're minimized on X11, WA_Mapped will be false and we
- // will return in the case above. Some window managers on X11
- // sends us the PropertyNotify to change the minimized state
- // *AFTER* we've received the expose event, which is baaad.
- || tlw->isMinimized()
-#endif
- )
- return true;
-
- return false;
+ return d_ptr->size;
}
/*!
- Synchronizes the \a exposedRegion of the \a exposedWidget with the backing store.
+ Scrolls the given \a area \a dx pixels to the right and \a dy
+ downward; both \a dx and \a dy may be negative.
- If there's nothing to repaint, the area is flushed and painting does not occur;
- otherwise the area is marked as dirty on screen and will be flushed right after
- we are done with all painting.
+ Returns true if the area was scrolled successfully; false otherwise.
*/
-void QWidgetBackingStore::sync(QWidget *exposedWidget, const QRegion &exposedRegion)
+bool QBackingStore::scroll(const QRegion &area, int dx, int dy)
{
- QTLWExtra *tlwExtra = tlw->d_func()->maybeTopData();
- if (discardSyncRequest(tlw, tlwExtra) || tlwExtra->inTopLevelResize)
- return;
-
- if (!exposedWidget || !exposedWidget->internalWinId() || !exposedWidget->isVisible()
- || !exposedWidget->updatesEnabled() || exposedRegion.isEmpty()) {
- return;
- }
-
- // If there's no preserved contents support we always need
- // to do a full repaint before flushing
- if (!windowSurface->hasFeature(QWindowSurface::PreservedContents))
- fullUpdatePending = true;
+ Q_UNUSED(area);
+ Q_UNUSED(dx);
+ Q_UNUSED(dy);
- // Nothing to repaint.
- if (!isDirty()) {
- qt_flush(exposedWidget, exposedRegion, windowSurface, tlw, tlwOffset);
- return;
- }
-
- if (exposedWidget != tlw)
- markDirtyOnScreen(exposedRegion, exposedWidget, exposedWidget->mapTo(tlw, QPoint()));
- else
- markDirtyOnScreen(exposedRegion, exposedWidget, QPoint());
- sync();
+ return d_ptr->platformBackingStore->scroll(area, dx, dy);
}
-/*!
- Synchronizes the backing store, i.e. dirty areas are repainted and flushed.
-*/
-void QWidgetBackingStore::sync()
+void QBackingStore::setStaticContents(const QRegion &region)
{
- QTLWExtra *tlwExtra = tlw->d_func()->maybeTopData();
- if (discardSyncRequest(tlw, tlwExtra)) {
- // If the top-level is minimized, it's not visible on the screen so we can delay the
- // update until it's shown again. In order to do that we must keep the dirty states.
- // These will be cleared when we receive the first expose after showNormal().
- // However, if the widget is not visible (isVisible() returns false), everything will
- // be invalidated once the widget is shown again, so clear all dirty states.
- if (!tlw->isVisible()) {
- dirty = QRegion();
- for (int i = 0; i < dirtyWidgets.size(); ++i)
- resetWidget(dirtyWidgets.at(i));
- dirtyWidgets.clear();
- fullUpdatePending = false;
- }
- return;
- }
-
- const bool updatesDisabled = !tlw->updatesEnabled();
- bool repaintAllWidgets = false;
-
- const bool inTopLevelResize = tlwExtra->inTopLevelResize;
- const QRect tlwRect(topLevelRect());
-#ifdef Q_WS_QPA
- const QRect surfaceGeometry(tlwRect.topLeft(), windowSurface->size());
-#else
- const QRect surfaceGeometry(windowSurface->geometry());
-#endif
- if ((fullUpdatePending || inTopLevelResize || surfaceGeometry.size() != tlwRect.size()) && !updatesDisabled) {
- if (hasStaticContents()) {
- // Repaint existing dirty area and newly visible area.
- const QRect clipRect(0, 0, surfaceGeometry.width(), surfaceGeometry.height());
- const QRegion staticRegion(staticContents(0, clipRect));
- QRegion newVisible(0, 0, tlwRect.width(), tlwRect.height());
- newVisible -= staticRegion;
- dirty += newVisible;
- windowSurface->setStaticContents(staticRegion);
- } else {
- // Repaint everything.
- dirty = QRegion(0, 0, tlwRect.width(), tlwRect.height());
- for (int i = 0; i < dirtyWidgets.size(); ++i)
- resetWidget(dirtyWidgets.at(i));
- dirtyWidgets.clear();
- repaintAllWidgets = true;
- }
- }
-
-#ifdef Q_WS_QPA
- if (inTopLevelResize || surfaceGeometry.size() != tlwRect.size())
- windowSurface->resize(tlwRect.size());
-#else
- if (inTopLevelResize || surfaceGeometry != tlwRect)
- windowSurface->setGeometry(tlwRect);
-#endif
-
- if (updatesDisabled)
- return;
-
- if (hasDirtyFromPreviousSync)
- dirty += dirtyFromPreviousSync;
-
- // Contains everything that needs repaint.
- QRegion toClean(dirty);
-
- // Loop through all update() widgets and remove them from the list before they are
- // painted (in case someone calls update() in paintEvent). If the widget is opaque
- // and does not have transparent overlapping siblings, append it to the
- // opaqueNonOverlappedWidgets list and paint it directly without composition.
- QVarLengthArray<QWidget *, 32> opaqueNonOverlappedWidgets;
- for (int i = 0; i < dirtyWidgets.size(); ++i) {
- QWidget *w = dirtyWidgets.at(i);
- QWidgetPrivate *wd = w->d_func();
- if (wd->data.in_destructor)
- continue;
-
- // Clip with mask() and clipRect().
- wd->dirty &= wd->clipRect();
- wd->clipToEffectiveMask(wd->dirty);
-
- // Subtract opaque siblings and children.
- bool hasDirtySiblingsAbove = false;
- // We know for sure that the widget isn't overlapped if 'isMoved' is true.
- if (!wd->isMoved)
- wd->subtractOpaqueSiblings(wd->dirty, &hasDirtySiblingsAbove);
- // Scrolled and moved widgets must draw all children.
- if (!wd->isScrolled && !wd->isMoved)
- wd->subtractOpaqueChildren(wd->dirty, w->rect());
-
- if (wd->dirty.isEmpty()) {
- resetWidget(w);
- continue;
- }
-
- const QRegion widgetDirty(w != tlw ? wd->dirty.translated(w->mapTo(tlw, QPoint()))
- : wd->dirty);
- toClean += widgetDirty;
-
-#ifndef QT_NO_GRAPHICSVIEW
- if (tlw->d_func()->extra->proxyWidget) {
- resetWidget(w);
- continue;
- }
-#endif
-
- if (!hasDirtySiblingsAbove && wd->isOpaque && !dirty.intersects(widgetDirty.boundingRect())) {
- opaqueNonOverlappedWidgets.append(w);
- } else {
- resetWidget(w);
- dirty += widgetDirty;
- }
- }
- dirtyWidgets.clear();
-
- fullUpdatePending = false;
-
- if (toClean.isEmpty()) {
- // Nothing to repaint. However, we might have newly exposed areas on the
- // screen if this function was called from sync(QWidget *, QRegion)), so
- // we have to make sure those are flushed.
- flush();
- return;
- }
-
-#ifndef QT_NO_GRAPHICSVIEW
- if (tlw->d_func()->extra->proxyWidget) {
- updateStaticContentsSize();
- dirty = QRegion();
- const QVector<QRect> rects(toClean.rects());
- for (int i = 0; i < rects.size(); ++i)
- tlw->d_func()->extra->proxyWidget->update(rects.at(i));
- return;
- }
-#endif
-
-#ifndef Q_BACKINGSTORE_SUBSURFACES
- BeginPaintInfo beginPaintInfo;
- beginPaint(toClean, tlw, windowSurface, &beginPaintInfo);
- if (beginPaintInfo.nothingToPaint) {
- for (int i = 0; i < opaqueNonOverlappedWidgets.size(); ++i)
- resetWidget(opaqueNonOverlappedWidgets[i]);
- dirty = QRegion();
- return;
- }
-#endif
-
- // Must do this before sending any paint events because
- // the size may change in the paint event.
- updateStaticContentsSize();
- const QRegion dirtyCopy(dirty);
- dirty = QRegion();
-
- // Paint opaque non overlapped widgets.
- for (int i = 0; i < opaqueNonOverlappedWidgets.size(); ++i) {
- QWidget *w = opaqueNonOverlappedWidgets[i];
- QWidgetPrivate *wd = w->d_func();
-
- int flags = QWidgetPrivate::DrawRecursive;
- // Scrolled and moved widgets must draw all children.
- if (!wd->isScrolled && !wd->isMoved)
- flags |= QWidgetPrivate::DontDrawOpaqueChildren;
- if (w == tlw)
- flags |= QWidgetPrivate::DrawAsRoot;
-
- QRegion toBePainted(wd->dirty);
- resetWidget(w);
-
-#ifdef Q_BACKINGSTORE_SUBSURFACES
- QWindowSurface *subSurface = w->windowSurface();
- BeginPaintInfo beginPaintInfo;
-
- QPoint off = w->mapTo(tlw, QPoint());
- toBePainted.translate(off);
- beginPaint(toBePainted, w, subSurface, &beginPaintInfo, true);
- toBePainted.translate(-off);
-
- if (beginPaintInfo.nothingToPaint)
- continue;
-
- if (beginPaintInfo.windowSurfaceRecreated) {
- // Eep the window surface has changed. The old one may have been
- // deleted, in which case we will segfault on the call to
- // painterOffset() below. Use the new window surface instead.
- subSurface = w->windowSurface();
- }
-
- QPoint offset(tlwOffset);
- if (subSurface == windowSurface)
- offset += w->mapTo(tlw, QPoint());
- else
- offset = static_cast<QWSWindowSurface*>(subSurface)->painterOffset();
- wd->drawWidget(subSurface->paintDevice(), toBePainted, offset, flags, 0, this);
-
- endPaint(toBePainted, subSurface, &beginPaintInfo);
-#else
- QPoint offset(tlwOffset);
- if (w != tlw)
- offset += w->mapTo(tlw, QPoint());
- wd->drawWidget(windowSurface->paintDevice(), toBePainted, offset, flags, 0, this);
-#endif
- }
-
- // Paint the rest with composition.
-#ifndef Q_BACKINGSTORE_SUBSURFACES
- if (repaintAllWidgets || !dirtyCopy.isEmpty()) {
- const int flags = QWidgetPrivate::DrawAsRoot | QWidgetPrivate::DrawRecursive;
- tlw->d_func()->drawWidget(windowSurface->paintDevice(), dirtyCopy, tlwOffset, flags, 0, this);
- }
-
- endPaint(toClean, windowSurface, &beginPaintInfo);
-#else
- if (!repaintAllWidgets && dirtyCopy.isEmpty())
- return; // Nothing more to paint.
-
- QList<QWindowSurface *> surfaceList(subSurfaces);
- surfaceList.prepend(windowSurface);
- const QRect dirtyBoundingRect(dirtyCopy.boundingRect());
-
- // Loop through all window surfaces (incl. the top-level surface) and
- // repaint those intersecting with the bounding rect of the dirty region.
- for (int i = 0; i < surfaceList.size(); ++i) {
- QWindowSurface *subSurface = surfaceList.at(i);
- QWidget *w = subSurface->window();
- QWidgetPrivate *wd = w->d_func();
-
- const QRect clipRect = wd->clipRect().translated(w->mapTo(tlw, QPoint()));
- if (!qRectIntersects(dirtyBoundingRect, clipRect))
- continue;
-
- toClean = dirtyCopy;
- BeginPaintInfo beginPaintInfo;
- beginPaint(toClean, w, subSurface, &beginPaintInfo);
- if (beginPaintInfo.nothingToPaint)
- continue;
-
- if (beginPaintInfo.windowSurfaceRecreated) {
- // Eep the window surface has changed. The old one may have been
- // deleted, in which case we will segfault on the call to
- // painterOffset() below. Use the new window surface instead.
- subSurface = w->windowSurface();
- }
-
- int flags = QWidgetPrivate::DrawRecursive;
- if (w == tlw)
- flags |= QWidgetPrivate::DrawAsRoot;
- const QPoint painterOffset = static_cast<QWSWindowSurface*>(subSurface)->painterOffset();
- wd->drawWidget(subSurface->paintDevice(), toClean, painterOffset, flags, 0, this);
-
- endPaint(toClean, subSurface, &beginPaintInfo);
- }
-#endif
+ d_ptr->staticContents = region;
}
-/*!
- Flushes the contents of the backing store into the top-level widget.
- If the \a widget is non-zero, the content is flushed to the \a widget.
- If the \a surface is non-zero, the content of the \a surface is flushed.
-*/
-void QWidgetBackingStore::flush(QWidget *widget, QWindowSurface *surface)
+QRegion QBackingStore::staticContents() const
{
-#if defined(Q_WS_QWS) && !defined(QT_NO_QWS_MANAGER)
- paintWindowDecoration();
-#endif
-
- if (!dirtyOnScreen.isEmpty()) {
- QWidget *target = widget ? widget : tlw;
- QWindowSurface *source = surface ? surface : windowSurface;
- qt_flush(target, dirtyOnScreen, source, tlw, tlwOffset);
- dirtyOnScreen = QRegion();
- }
-
- if (!dirtyOnScreenWidgets || dirtyOnScreenWidgets->isEmpty())
- return;
-
- for (int i = 0; i < dirtyOnScreenWidgets->size(); ++i) {
- QWidget *w = dirtyOnScreenWidgets->at(i);
- QWidgetPrivate *wd = w->d_func();
- Q_ASSERT(wd->needsFlush);
- qt_flush(w, *wd->needsFlush, windowSurface, tlw, tlwOffset);
- *wd->needsFlush = QRegion();
- }
- dirtyOnScreenWidgets->clear();
+ return d_ptr->staticContents;
}
-static inline bool discardInvalidateBufferRequest(QWidget *widget, QTLWExtra *tlwExtra)
+bool QBackingStore::hasStaticContents() const
{
- Q_ASSERT(widget);
- if (QApplication::closingDown())
- return true;
-
- if (!tlwExtra || tlwExtra->inTopLevelResize || !tlwExtra->backingStore)
- return true;
-
- if (!widget->isVisible() || !widget->updatesEnabled())
- return true;
-
- return false;
+ return !d_ptr->staticContents.isEmpty();
}
-/*!
- Invalidates the buffer when the widget is resized.
- Static areas are never invalidated unless absolutely needed.
-*/
-void QWidgetPrivate::invalidateBuffer_resizeHelper(const QPoint &oldPos, const QSize &oldSize)
+void Q_GUI_EXPORT qt_scrollRectInImage(QImage &img, const QRect &rect, const QPoint &offset)
{
- Q_Q(QWidget);
- Q_ASSERT(!q->isWindow());
- Q_ASSERT(q->parentWidget());
+ // make sure we don't detach
+ uchar *mem = const_cast<uchar*>(const_cast<const QImage &>(img).bits());
- const bool staticContents = q->testAttribute(Qt::WA_StaticContents);
- const bool sizeDecreased = (data.crect.width() < oldSize.width())
- || (data.crect.height() < oldSize.height());
+ int lineskip = img.bytesPerLine();
+ int depth = img.depth() >> 3;
- const QPoint offset(data.crect.x() - oldPos.x(), data.crect.y() - oldPos.y());
- const bool parentAreaExposed = !offset.isNull() || sizeDecreased;
- const QRect newWidgetRect(q->rect());
- const QRect oldWidgetRect(0, 0, oldSize.width(), oldSize.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 (!staticContents || graphicsEffect) {
- QRegion staticChildren;
- QWidgetBackingStore *bs = 0;
- if (offset.isNull() && (bs = maybeBackingStore()))
- staticChildren = bs->staticContents(q, oldWidgetRect);
- const bool hasStaticChildren = !staticChildren.isEmpty();
-
- if (hasStaticChildren) {
- QRegion dirty(newWidgetRect);
- dirty -= staticChildren;
- invalidateBuffer(dirty);
- } else {
- // Entire widget needs repaint.
- invalidateBuffer(newWidgetRect);
- }
-
- if (!parentAreaExposed)
- return;
-
- // Invalidate newly exposed area of the parent.
- if (!graphicsEffect && extra && extra->hasMask) {
- QRegion parentExpose(extra->mask.translated(oldPos));
- parentExpose &= QRect(oldPos, oldSize);
- if (hasStaticChildren)
- parentExpose -= data.crect; // Offset is unchanged, safe to do this.
- q->parentWidget()->d_func()->invalidateBuffer(parentExpose);
- } else {
- if (hasStaticChildren && !graphicsEffect) {
- QRegion parentExpose(QRect(oldPos, oldSize));
- parentExpose -= data.crect; // Offset is unchanged, safe to do this.
- q->parentWidget()->d_func()->invalidateBuffer(parentExpose);
- } else {
- q->parentWidget()->d_func()->invalidateBuffer(effectiveRectFor(QRect(oldPos, oldSize)));
- }
- }
+ if (r.isEmpty())
return;
- }
-
- // Move static content to its new position.
- if (!offset.isNull()) {
- if (sizeDecreased) {
- const QSize minSize(qMin(oldSize.width(), data.crect.width()),
- qMin(oldSize.height(), data.crect.height()));
- moveRect(QRect(oldPos, minSize), offset.x(), offset.y());
- } else {
- moveRect(QRect(oldPos, oldSize), offset.x(), offset.y());
- }
- }
- // Invalidate newly visible area of the widget.
- if (!sizeDecreased || !oldWidgetRect.contains(newWidgetRect)) {
- QRegion newVisible(newWidgetRect);
- newVisible -= oldWidgetRect;
- invalidateBuffer(newVisible);
- }
-
- if (!parentAreaExposed)
- return;
+ const uchar *src;
+ uchar *dest;
- // Invalidate newly exposed area of the parent.
- const QRect oldRect(oldPos, oldSize);
- if (extra && extra->hasMask) {
- QRegion parentExpose(oldRect);
- parentExpose &= extra->mask.translated(oldPos);
- parentExpose -= (extra->mask.translated(data.crect.topLeft()) & data.crect);
- q->parentWidget()->d_func()->invalidateBuffer(parentExpose);
+ if (r.top() < p.y()) {
+ src = mem + r.bottom() * lineskip + r.left() * depth;
+ dest = mem + (p.y() + r.height() - 1) * lineskip + p.x() * depth;
+ lineskip = -lineskip;
} else {
- QRegion parentExpose(oldRect);
- parentExpose -= data.crect;
- q->parentWidget()->d_func()->invalidateBuffer(parentExpose);
+ src = mem + r.top() * lineskip + r.left() * depth;
+ dest = mem + p.y() * lineskip + p.x() * depth;
}
-}
-/*!
- Invalidates the \a rgn (in widget's coordinates) of the backing store, i.e.
- all widgets intersecting with the region will be repainted when the backing store
- is synced.
+ const int w = r.width();
+ int h = r.height();
+ const int bytes = w * depth;
- ### Qt 4.6: Merge into a template function (after MSVC isn't supported anymore).
-*/
-void QWidgetPrivate::invalidateBuffer(const QRegion &rgn)
-{
- Q_Q(QWidget);
-
- QTLWExtra *tlwExtra = q->window()->d_func()->maybeTopData();
- if (discardInvalidateBufferRequest(q, tlwExtra) || rgn.isEmpty())
- return;
-
- QRegion wrgn(rgn);
- wrgn &= clipRect();
- if (!graphicsEffect && extra && extra->hasMask)
- wrgn &= extra->mask;
- if (wrgn.isEmpty())
- return;
-
- tlwExtra->backingStore->markDirty(wrgn, q, false, true);
-}
-
-/*!
- This function is equivalent to calling invalidateBuffer(QRegion(rect), ...), but
- is more efficient as it eliminates QRegion operations/allocations and can
- use the rect more precisely for additional cut-offs.
-
- ### Qt 4.6: Merge into a template function (after MSVC isn't supported anymore).
-*/
-void QWidgetPrivate::invalidateBuffer(const QRect &rect)
-{
- Q_Q(QWidget);
-
- QTLWExtra *tlwExtra = q->window()->d_func()->maybeTopData();
- if (discardInvalidateBufferRequest(q, tlwExtra) || rect.isEmpty())
- return;
-
- QRect wRect(rect);
- wRect &= clipRect();
- if (wRect.isEmpty())
- return;
-
- if (graphicsEffect || !extra || !extra->hasMask) {
- tlwExtra->backingStore->markDirty(wRect, q, false, true);
- return;
+ // overlapping segments?
+ if (offset.y() == 0 && qAbs(offset.x()) < w) {
+ do {
+ ::memmove(dest, src, bytes);
+ dest += lineskip;
+ src += lineskip;
+ } while (--h);
+ } else {
+ do {
+ ::memcpy(dest, src, bytes);
+ dest += lineskip;
+ src += lineskip;
+ } while (--h);
}
-
- QRegion wRgn(extra->mask);
- wRgn &= wRect;
- if (wRgn.isEmpty())
- return;
-
- tlwExtra->backingStore->markDirty(wRgn, q, false, true);
}
-void QWidgetPrivate::repaint_sys(const QRegion &rgn)
+QPlatformBackingStore *QBackingStore::handle() const
{
- if (data.in_destructor)
- return;
-
- Q_Q(QWidget);
- if (q->testAttribute(Qt::WA_StaticContents)) {
- if (!extra)
- createExtra();
- extra->staticContentsSize = data.crect.size();
- }
-
-#ifdef Q_WS_QPA //Dont even call q->p
- QPaintEngine *engine = 0;
-#else
- QPaintEngine *engine = q->paintEngine();
-#endif
- // QGLWidget does not support partial updates if:
- // 1) The context is double buffered
- // 2) The context is single buffered and auto-fill background is enabled.
- const bool noPartialUpdateSupport = (engine && (engine->type() == QPaintEngine::OpenGL
- || engine->type() == QPaintEngine::OpenGL2))
- && (usesDoubleBufferedGLContext || q->autoFillBackground());
- QRegion toBePainted(noPartialUpdateSupport ? q->rect() : rgn);
-
-#ifdef Q_WS_MAC
- // No difference between update() and repaint() on the Mac.
- update_sys(toBePainted);
- return;
-#endif
-
- toBePainted &= clipRect();
- clipToEffectiveMask(toBePainted);
- if (toBePainted.isEmpty())
- return; // Nothing to repaint.
-
-#ifndef QT_NO_PAINT_DEBUG
- bool flushed = QWidgetBackingStore::flushPaint(q, toBePainted);
-#endif
-
- drawWidget(q, toBePainted, QPoint(), QWidgetPrivate::DrawAsRoot | QWidgetPrivate::DrawPaintOnScreen, 0);
-
-#ifndef QT_NO_PAINT_DEBUG
- if (flushed)
- QWidgetBackingStore::unflushPaint(q, toBePainted);
-#endif
-
- if (!q->testAttribute(Qt::WA_PaintOutsidePaintEvent) && q->paintingActive())
- qWarning("QWidget::repaint: It is dangerous to leave painters active on a widget outside of the PaintEvent");
+ return d_ptr->platformBackingStore;
}
-
QT_END_NAMESPACE
diff --git a/src/gui/painting/qbackingstore.h b/src/gui/painting/qbackingstore.h
new file mode 100644
index 0000000000..9f646f89ac
--- /dev/null
+++ b/src/gui/painting/qbackingstore.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QBACKINGSTORE_H
+#define QBACKINGSTORE_H
+
+#include <QtCore/qrect.h>
+
+#include <QtGui/qwindow.h>
+#include <QtGui/qregion.h>
+
+QT_BEGIN_NAMESPACE
+
+class QRegion;
+class QRect;
+class QPoint;
+class QImage;
+class QBackingStorePrivate;
+class QPlatformBackingStore;
+
+class Q_GUI_EXPORT QBackingStore
+{
+public:
+ QBackingStore(QWindow *window);
+ ~QBackingStore();
+
+ QWindow *window() const;
+
+ QPaintDevice *paintDevice();
+
+ // 'window' can be a child window, in which case 'region' is in child window coordinates and
+ // offset is the (child) window's offset in relation to the window surface.
+ void flush(const QRegion &region, QWindow *window = 0, const QPoint &offset = QPoint());
+
+ void resize(const QSize &size);
+ QSize size() const;
+
+ bool scroll(const QRegion &area, int dx, int dy);
+
+ void beginPaint(const QRegion &);
+ void endPaint();
+
+ void setStaticContents(const QRegion &region);
+ QRegion staticContents() const;
+ bool hasStaticContents() const;
+
+ QPlatformBackingStore *handle() const;
+
+private:
+ QScopedPointer<QBackingStorePrivate> d_ptr;
+};
+
+QT_END_NAMESPACE
+
+#endif // QBACKINGSTORE_H
diff --git a/src/gui/painting/qbackingstore_p.h b/src/gui/painting/qbackingstore_p.h
deleted file mode 100644
index 1ef2e4e1b0..0000000000
--- a/src/gui/painting/qbackingstore_p.h
+++ /dev/null
@@ -1,278 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QBACKINGSTORE_P_H
-#define QBACKINGSTORE_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QDebug>
-#include <QtGui/qwidget.h>
-#include <private/qwidget_p.h>
-#include <private/qwindowsurface_p.h>
-#ifdef Q_WS_QWS
-#include <private/qwindowsurface_qws_p.h>
-#endif
-
-QT_BEGIN_NAMESPACE
-
-class QWindowSurface;
-
-struct BeginPaintInfo {
- inline BeginPaintInfo() : wasFlushed(0), nothingToPaint(0), windowSurfaceRecreated(0) {}
- uint wasFlushed : 1;
- uint nothingToPaint : 1;
- uint windowSurfaceRecreated : 1;
-};
-
-class Q_AUTOTEST_EXPORT QWidgetBackingStore
-{
-public:
- QWidgetBackingStore(QWidget *t);
- ~QWidgetBackingStore();
-
- static void showYellowThing(QWidget *widget, const QRegion &rgn, int msec, bool);
-
- void sync(QWidget *exposedWidget, const QRegion &exposedRegion);
- void sync();
- void flush(QWidget *widget = 0, QWindowSurface *surface = 0);
-
- inline QPoint topLevelOffset() const { return tlwOffset; }
-
- QWindowSurface *surface() const { return windowSurface; }
-
- inline bool isDirty() const
- {
- return !(dirtyWidgets.isEmpty() && dirty.isEmpty() && !hasDirtyFromPreviousSync
- && !fullUpdatePending
-#if defined(Q_WS_QWS) && !defined(QT_NO_QWS_MANAGER)
- && !hasDirtyWindowDecoration()
-#endif
- );
- }
-
- // ### Qt 4.6: Merge into a template function (after MSVC isn't supported anymore).
- void markDirty(const QRegion &rgn, QWidget *widget, bool updateImmediately = false,
- bool invalidateBuffer = false);
- void markDirty(const QRect &rect, QWidget *widget, bool updateImmediately = false,
- bool invalidateBuffer = false);
-
-private:
- QWidget *tlw;
- QRegion dirtyOnScreen; // needsFlush
- QRegion dirty; // needsRepaint
- QRegion dirtyFromPreviousSync;
- QVector<QWidget *> dirtyWidgets;
- QVector<QWidget *> *dirtyOnScreenWidgets;
- QList<QWidget *> staticWidgets;
- QWindowSurface *windowSurface;
-#ifdef Q_BACKINGSTORE_SUBSURFACES
- QList<QWindowSurface*> subSurfaces;
-#endif
- uint hasDirtyFromPreviousSync : 1;
- uint fullUpdatePending : 1;
-
- QPoint tlwOffset;
-
- static bool flushPaint(QWidget *widget, const QRegion &rgn);
- static void unflushPaint(QWidget *widget, const QRegion &rgn);
-
- bool bltRect(const QRect &rect, int dx, int dy, QWidget *widget);
- void releaseBuffer();
-
- void beginPaint(QRegion &toClean, QWidget *widget, QWindowSurface *windowSurface,
- BeginPaintInfo *returnInfo, bool toCleanIsInTopLevelCoordinates = true);
- void endPaint(const QRegion &cleaned, QWindowSurface *windowSurface, BeginPaintInfo *beginPaintInfo);
-
- QRegion dirtyRegion(QWidget *widget = 0) const;
- QRegion staticContents(QWidget *widget = 0, const QRect &withinClipRect = QRect()) const;
-
- void markDirtyOnScreen(const QRegion &dirtyOnScreen, QWidget *widget, const QPoint &topLevelOffset);
-
- void removeDirtyWidget(QWidget *w);
-
-#if defined(Q_WS_QWS) && !defined(QT_NO_QWS_MANAGER)
- bool hasDirtyWindowDecoration() const;
- void paintWindowDecoration();
-#endif
- void updateLists(QWidget *widget);
-
- inline void addDirtyWidget(QWidget *widget, const QRegion &rgn)
- {
- if (widget && !widget->d_func()->inDirtyList && !widget->data->in_destructor) {
- QWidgetPrivate *widgetPrivate = widget->d_func();
-#ifndef QT_NO_GRAPHICSEFFECT
- if (widgetPrivate->graphicsEffect)
- widgetPrivate->dirty = widgetPrivate->effectiveRectFor(rgn.boundingRect());
- else
-#endif //QT_NO_GRAPHICSEFFECT
- widgetPrivate->dirty = rgn;
- dirtyWidgets.append(widget);
- widgetPrivate->inDirtyList = true;
- }
- }
-
- inline void dirtyWidgetsRemoveAll(QWidget *widget)
- {
- int i = 0;
- while (i < dirtyWidgets.size()) {
- if (dirtyWidgets.at(i) == widget)
- dirtyWidgets.remove(i);
- else
- ++i;
- }
- }
-
- inline void addStaticWidget(QWidget *widget)
- {
- if (!widget)
- return;
-
- Q_ASSERT(widget->testAttribute(Qt::WA_StaticContents));
- if (!staticWidgets.contains(widget))
- staticWidgets.append(widget);
- }
-
- inline void removeStaticWidget(QWidget *widget)
- { staticWidgets.removeAll(widget); }
-
- // Move the reparented widget and all its static children from this backing store
- // to the new backing store if reparented into another top-level / backing store.
- inline void moveStaticWidgets(QWidget *reparented)
- {
- Q_ASSERT(reparented);
- QWidgetBackingStore *newBs = reparented->d_func()->maybeBackingStore();
- if (newBs == this)
- return;
-
- int i = 0;
- while (i < staticWidgets.size()) {
- QWidget *w = staticWidgets.at(i);
- if (reparented == w || reparented->isAncestorOf(w)) {
- staticWidgets.removeAt(i);
- if (newBs)
- newBs->addStaticWidget(w);
- } else {
- ++i;
- }
- }
- }
-
- inline QRect topLevelRect() const
- {
-#ifdef Q_WS_QWS
- return tlw->frameGeometry();
-#else
- return tlw->data->crect;
-#endif
- }
-
- inline void appendDirtyOnScreenWidget(QWidget *widget)
- {
- if (!widget)
- return;
-
- if (!dirtyOnScreenWidgets) {
- dirtyOnScreenWidgets = new QVector<QWidget *>;
- dirtyOnScreenWidgets->append(widget);
- } else if (!dirtyOnScreenWidgets->contains(widget)) {
- dirtyOnScreenWidgets->append(widget);
- }
- }
-
- inline void dirtyOnScreenWidgetsRemoveAll(QWidget *widget)
- {
- if (!widget || !dirtyOnScreenWidgets)
- return;
-
- int i = 0;
- while (i < dirtyOnScreenWidgets->size()) {
- if (dirtyOnScreenWidgets->at(i) == widget)
- dirtyOnScreenWidgets->remove(i);
- else
- ++i;
- }
- }
-
- inline void resetWidget(QWidget *widget)
- {
- if (widget) {
- widget->d_func()->inDirtyList = false;
- widget->d_func()->isScrolled = false;
- widget->d_func()->isMoved = false;
- widget->d_func()->dirty = QRegion();
- }
- }
-
- inline void updateStaticContentsSize()
- {
- for (int i = 0; i < staticWidgets.size(); ++i) {
- QWidgetPrivate *wd = staticWidgets.at(i)->d_func();
- if (!wd->extra)
- wd->createExtra();
- wd->extra->staticContentsSize = wd->data.crect.size();
- }
- }
-
- inline bool hasStaticContents() const
- { return !staticWidgets.isEmpty() && windowSurface->hasFeature(QWindowSurface::StaticContents); }
-
- friend QRegion qt_dirtyRegion(QWidget *);
- friend class QWidgetPrivate;
- friend class QWidget;
- friend class QWSManagerPrivate;
- friend class QETWidget;
- friend class QWindowSurface;
- friend class QWSWindowSurface;
-};
-
-QT_END_NAMESPACE
-
-#endif // QBACKINGSTORE_P_H
diff --git a/src/gui/painting/qbrush.cpp b/src/gui/painting/qbrush.cpp
index 742a4ea071..05f191dac6 100644
--- a/src/gui/painting/qbrush.cpp
+++ b/src/gui/painting/qbrush.cpp
@@ -48,7 +48,7 @@
#include "qline.h"
#include "qdebug.h"
#include <QtCore/qcoreapplication.h>
-#include "private/qstylehelper_p.h"
+#include "private/qhexstring_p.h"
#include <QtCore/qnumeric.h>
QT_BEGIN_NAMESPACE
@@ -706,36 +706,6 @@ void QBrush::setColor(const QColor &c)
Sets the brush color to the given \a color.
*/
-
-#ifdef QT3_SUPPORT
-
-/*!
- \fn void QBrush::setPixmap(const QPixmap &pixmap)
-
- \compat
-
- Sets a custom pattern for this brush.
-
- Use setTexture() instead.
-*/
-
-/*!
- \fn QPixmap *QBrush::pixmap() const
-
- Returns a pointer to the custom brush pattern.
-
- Use texture() instead.
-*/
-QPixmap *QBrush::pixmap() const
-{
- if (d->style != Qt::TexturePattern)
- return 0;
- QTexturedBrushData *data = static_cast<QTexturedBrushData*>(d.data());
- QPixmap &pixmap = data->pixmap();
- return pixmap.isNull() ? 0 : &pixmap;
-}
-#endif
-
/*!
\fn QPixmap QBrush::texture() const
diff --git a/src/gui/painting/qbrush.h b/src/gui/painting/qbrush.h
index edf99924a3..edb092c035 100644
--- a/src/gui/painting/qbrush.h
+++ b/src/gui/painting/qbrush.h
@@ -126,12 +126,6 @@ public:
bool operator==(const QBrush &b) const;
inline bool operator!=(const QBrush &b) const { return !(operator==(b)); }
-#ifdef QT3_SUPPORT
- inline QT3_SUPPORT operator const QColor&() const;
- QT3_SUPPORT QPixmap *pixmap() const;
- inline QT3_SUPPORT void setPixmap(const QPixmap &pixmap) { setTexture(pixmap); }
-#endif
-
private:
#if defined(Q_WS_X11)
friend class QX11PaintEngine;
@@ -185,10 +179,6 @@ inline const QMatrix &QBrush::matrix() const { return d->transform.toAffine(); }
inline QTransform QBrush::transform() const { return d->transform; }
inline bool QBrush::isDetached() const { return d->ref == 1; }
-#ifdef QT3_SUPPORT
-inline QBrush::operator const QColor&() const { return d->color; }
-#endif
-
/*******************************************************************************
* QGradients
diff --git a/src/gui/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp
index 3d895b7753..8234fa19f6 100644
--- a/src/gui/painting/qcolor.cpp
+++ b/src/gui/painting/qcolor.cpp
@@ -42,20 +42,10 @@
#include "qcolor.h"
#include "qcolor_p.h"
#include "qnamespace.h"
-#include "qcolormap.h"
#include "qdatastream.h"
#include "qvariant.h"
#include "qdebug.h"
-#ifdef Q_WS_X11
-# include "qapplication.h"
-# include "qx11info_x11.h"
-# include "private/qt_x11_p.h"
-
-static bool allowX11ColorNames = false;
-
-#endif
-
#include <math.h>
#include <stdio.h>
#include <limits.h>
@@ -164,9 +154,6 @@ QT_BEGIN_NAMESPACE
\img alphafill.png
- Alpha-blended drawing is supported on Windows, Mac OS X, and on
- X11 systems that have the X Render extension installed.
-
The alpha channel of a color can be retrieved and set using the
alpha() and setAlpha() functions if its value is an integer, and
alphaF() and setAlphaF() if its value is qreal (double). By
@@ -521,13 +508,11 @@ QString QColor::name() const
same as defined by the Qt::GlobalColor enums, e.g. "green" and Qt::green does not
refer to the same color.
\i \c transparent - representing the absence of a color.
- \i \e{X11 only}: If allowX11ColorNames() returns true, any valid X11 color name. See
- the documentation for \c XParseColor() for information about valid X11 color names.
\endlist
The color is invalid if \a name cannot be parsed.
- \sa QColor(), name(), isValid(), allowX11ColorNames()
+ \sa QColor(), name(), isValid()
*/
void QColor::setNamedColor(const QString &name)
@@ -577,20 +562,8 @@ bool QColor::setColorFromString(const QString &name)
} else
#endif
{
-#ifdef Q_WS_X11
- XColor result;
- if (allowX11ColorNames()
- && QApplication::instance()
- && QX11Info::display()
- && XParseColor(QX11Info::display(), QX11Info::appColormap(), name.toLatin1().constData(), &result)) {
- setRgb(result.red >> 8, result.green >> 8, result.blue >> 8);
- return true;
- } else
-#endif
- {
- invalidate();
- return false;
- }
+ invalidate();
+ return false;
}
}
@@ -2418,35 +2391,6 @@ QColor::operator QVariant() const
return QVariant(QVariant::Color, this);
}
-#ifdef Q_WS_X11
-/*!
- Returns true if setNamedColor() is allowed to look up colors in the X11
- color database. By default, this function returns false.
-
- \note This function is only available on the X11 platform.
-
- \sa setAllowX11ColorNames()
-*/
-bool QColor::allowX11ColorNames()
-{
- return ::allowX11ColorNames;
-}
-
-/*!
- Allow setNamedColor() to look up colors in the X11 color database if
- \a enabled. By default, setNamedColor() does \e not look up colors in the
- X11 color database.
-
- \note This function is only available on the X11 platform.
-
- \sa setNamedColor(), allowX11ColorNames()
-*/
-void QColor::setAllowX11ColorNames(bool enabled)
-{
- ::allowX11ColorNames = enabled;
-}
-#endif
-
/*! \internal
Marks the color as invalid and sets all components to zero (alpha is set
@@ -2462,30 +2406,6 @@ void QColor::invalidate()
ct.argb.pad = 0;
}
-#ifdef QT3_SUPPORT
-
-/*!
- Returns the pixel value used by the underlying window system to refer to a
- color.
-
- Use QColormap::pixel() instead.
-
- \oldcode
- QColor myColor;
- uint pixel = myColor.pixel(screen);
- \newcode
- QColormap cmap = QColormap::instance(screen);
- uint pixel = cmap.pixel(*this);
- \endcode
-*/
-uint QColor::pixel(int screen) const
-{
- QColormap cmap = QColormap::instance(screen);
- return cmap.pixel(*this);
-}
-
-#endif // QT3_SUPPORT
-
/*****************************************************************************
QColor stream functions
*****************************************************************************/
diff --git a/src/gui/painting/qcolor.h b/src/gui/painting/qcolor.h
index 533f6fe315..460a43183f 100644
--- a/src/gui/painting/qcolor.h
+++ b/src/gui/painting/qcolor.h
@@ -203,35 +203,9 @@ public:
operator QVariant() const;
-#ifdef Q_WS_X11
- static bool allowX11ColorNames();
- static void setAllowX11ColorNames(bool enabled);
-#endif
-
-#ifdef QT3_SUPPORT
- inline QT3_SUPPORT_CONSTRUCTOR QColor(int x, int y, int z, Spec colorSpec)
- { if (colorSpec == Hsv) setHsv(x, y, z); else setRgb(x, y, z); }
-
- inline QT3_SUPPORT void rgb(int *r, int *g, int *b) const
- { getRgb(r, g, b); }
- inline QT3_SUPPORT void hsv(int *h, int *s, int *v) const
- { getHsv(h, s, v); }
-
- inline QT3_SUPPORT void setRgba(int r, int g, int b, int a)
- { setRgb(r, g, b, a); }
- inline QT3_SUPPORT void getRgba(int *r, int *g, int *b, int *a) const
- { getRgb(r, g, b, a); }
-
- QT3_SUPPORT uint pixel(int screen = -1) const;
-#endif
-
static bool isValidColor(const QString &name);
private:
-#ifndef QT3_SUPPORT
- // do not allow a spec to be used as an alpha value
- QColor(int, int, int, Spec);
-#endif
void invalidate();
bool setColorFromString(const QString &name);
diff --git a/src/gui/painting/qcolormap.h b/src/gui/painting/qcolormap.h
deleted file mode 100644
index 7ac818fc2e..0000000000
--- a/src/gui/painting/qcolormap.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QCOLORMAP_H
-#define QCOLORMAP_H
-
-#include <QtCore/qatomic.h>
-#include <QtGui/qrgb.h>
-#include <QtCore/qvector.h>
-#include <QtGui/qwindowdefs.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QColor;
-class QColormapPrivate;
-
-class Q_GUI_EXPORT QColormap
-{
-public:
- enum Mode { Direct, Indexed, Gray };
-
- static void initialize();
- static void cleanup();
-
- static QColormap instance(int screen = -1);
-
- QColormap(const QColormap &colormap);
- ~QColormap();
-
- QColormap &operator=(const QColormap &colormap);
-
- Mode mode() const;
-
- int depth() const;
- int size() const;
-
- uint pixel(const QColor &color) const;
- const QColor colorAt(uint pixel) const;
-
- const QVector<QColor> colormap() const;
-
-#ifdef Q_WS_WIN
- static HPALETTE hPal();
-#endif
-
-private:
- QColormap();
- QColormapPrivate *d;
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QCOLORMAP_H
diff --git a/src/gui/painting/qcolormap_qpa.cpp b/src/gui/painting/qcolormap_qpa.cpp
deleted file mode 100644
index 40bf364c5a..0000000000
--- a/src/gui/painting/qcolormap_qpa.cpp
+++ /dev/null
@@ -1,231 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qcolormap.h"
-#include "qcolor.h"
-#include "qpaintdevice.h"
-#include "private/qapplication_p.h"
-#include "private/qgraphicssystem_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class QColormapPrivate
-{
-public:
- inline QColormapPrivate()
- : ref(1), mode(QColormap::Direct), depth(0), numcolors(0)
- { }
-
- QAtomicInt ref;
-
- QColormap::Mode mode;
- int depth;
- int numcolors;
-};
-
-static QColormapPrivate *screenMap = 0;
-
-void QColormap::initialize()
-{
- screenMap = new QColormapPrivate;
-
- QPlatformIntegration *pi = QApplicationPrivate::platformIntegration();
- QList<QPlatformScreen*> screens = pi->screens();
-
- screenMap->depth = screens.at(0)->depth();
- if (screenMap->depth < 8) {
- screenMap->mode = QColormap::Indexed;
- screenMap->numcolors = 256;
- } else {
- screenMap->mode = QColormap::Direct;
- screenMap->numcolors = -1;
- }
-}
-
-void QColormap::cleanup()
-{
- delete screenMap;
- screenMap = 0;
-}
-
-QColormap QColormap::instance(int /*screen*/)
-{
- return QColormap();
-}
-
-QColormap::QColormap()
- : d(screenMap)
-{ d->ref.ref(); }
-
-QColormap::QColormap(const QColormap &colormap)
- :d (colormap.d)
-{ d->ref.ref(); }
-
-QColormap::~QColormap()
-{
- if (!d->ref.deref())
- delete d;
-}
-
-QColormap::Mode QColormap::mode() const
-{ return d->mode; }
-
-
-int QColormap::depth() const
-{ return d->depth; }
-
-
-int QColormap::size() const
-{
- return d->numcolors;
-}
-
-#ifndef QT_QWS_DEPTH16_RGB
-#define QT_QWS_DEPTH16_RGB 565
-#endif
-static const int qt_rbits = (QT_QWS_DEPTH16_RGB/100);
-static const int qt_gbits = (QT_QWS_DEPTH16_RGB/10%10);
-static const int qt_bbits = (QT_QWS_DEPTH16_RGB%10);
-static const int qt_red_shift = qt_bbits+qt_gbits-(8-qt_rbits);
-static const int qt_green_shift = qt_bbits-(8-qt_gbits);
-static const int qt_neg_blue_shift = 8-qt_bbits;
-static const int qt_blue_mask = (1<<qt_bbits)-1;
-static const int qt_green_mask = (1<<(qt_gbits+qt_bbits))-(1<<qt_bbits);
-static const int qt_red_mask = (1<<(qt_rbits+qt_gbits+qt_bbits))-(1<<(qt_gbits+qt_bbits));
-
-static const int qt_red_rounding_shift = qt_red_shift + qt_rbits;
-static const int qt_green_rounding_shift = qt_green_shift + qt_gbits;
-static const int qt_blue_rounding_shift = qt_bbits - qt_neg_blue_shift;
-
-inline ushort qt_convRgbTo16(QRgb c)
-{
- const int tr = qRed(c) << qt_red_shift;
- const int tg = qGreen(c) << qt_green_shift;
- const int tb = qBlue(c) >> qt_neg_blue_shift;
-
- return (tb & qt_blue_mask) | (tg & qt_green_mask) | (tr & qt_red_mask);
-}
-
-inline QRgb qt_conv16ToRgb(ushort c)
-{
- const int r=(c & qt_red_mask);
- const int g=(c & qt_green_mask);
- const int b=(c & qt_blue_mask);
- const int tr = r >> qt_red_shift | r >> qt_red_rounding_shift;
- const int tg = g >> qt_green_shift | g >> qt_green_rounding_shift;
- const int tb = b << qt_neg_blue_shift | b >> qt_blue_rounding_shift;
-
- return qRgb(tr,tg,tb);
-}
-
-uint QColormap::pixel(const QColor &color) const
-{
- QRgb rgb = color.rgba();
- if (d->mode == QColormap::Direct) {
- switch(d->depth) {
- case 16:
- return qt_convRgbTo16(rgb);
- case 24:
- case 32:
- {
- const int r = qRed(rgb);
- const int g = qGreen(rgb);
- const int b = qBlue(rgb);
- const int red_shift = 16;
- const int green_shift = 8;
- const int red_mask = 0xff0000;
- const int green_mask = 0x00ff00;
- const int blue_mask = 0x0000ff;
- const int tg = g << green_shift;
-#ifdef QT_QWS_DEPTH_32_BGR
- if (qt_screen->pixelType() == QScreen::BGRPixel) {
- const int tb = b << red_shift;
- return 0xff000000 | (r & blue_mask) | (tg & green_mask) | (tb & red_mask);
- }
-#endif
- const int tr = r << red_shift;
- return 0xff000000 | (b & blue_mask) | (tg & green_mask) | (tr & red_mask);
- }
- }
- }
- //XXX
- //return qt_screen->alloc(qRed(rgb), qGreen(rgb), qBlue(rgb));
- return 0;
-}
-
-const QColor QColormap::colorAt(uint pixel) const
-{
- if (d->mode == Direct) {
- if (d->depth == 16) {
- pixel = qt_conv16ToRgb(pixel);
- }
- const int red_shift = 16;
- const int green_shift = 8;
- const int red_mask = 0xff0000;
- const int green_mask = 0x00ff00;
- const int blue_mask = 0x0000ff;
-#ifdef QT_QWS_DEPTH_32_BGR
- if (qt_screen->pixelType() == QScreen::BGRPixel) {
- return QColor((pixel & blue_mask),
- (pixel & green_mask) >> green_shift,
- (pixel & red_mask) >> red_shift);
- }
-#endif
- return QColor((pixel & red_mask) >> red_shift,
- (pixel & green_mask) >> green_shift,
- (pixel & blue_mask));
- }
-#if 0 // XXX
- Q_ASSERT_X(int(pixel) < qt_screen->numCols(), "QColormap::colorAt", "pixel out of bounds of palette");
- return QColor(qt_screen->clut()[pixel]);
-#endif
- return QColor();
-}
-
-const QVector<QColor> QColormap::colormap() const
-{
- return QVector<QColor>();
-}
-
-QColormap &QColormap::operator=(const QColormap &colormap)
-{ qAtomicAssign(d, colormap.d); return *this; }
-
-QT_END_NAMESPACE
diff --git a/src/gui/painting/qcolormap_qws.cpp b/src/gui/painting/qcolormap_qws.cpp
deleted file mode 100644
index 00d3a43e4f..0000000000
--- a/src/gui/painting/qcolormap_qws.cpp
+++ /dev/null
@@ -1,185 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qcolormap.h"
-#include "qcolor.h"
-#include "qpaintdevice.h"
-#include "qscreen_qws.h"
-#include "qwsdisplay_qws.h"
-
-QT_BEGIN_NAMESPACE
-
-class QColormapPrivate
-{
-public:
- inline QColormapPrivate()
- : ref(1), mode(QColormap::Direct), depth(0), numcolors(0)
- { }
-
- QAtomicInt ref;
-
- QColormap::Mode mode;
- int depth;
- int numcolors;
-};
-
-static QColormapPrivate *screenMap = 0;
-
-void QColormap::initialize()
-{
- screenMap = new QColormapPrivate;
-
- screenMap->depth = QPaintDevice::qwsDisplay()->depth();
- if (screenMap->depth < 8) {
- screenMap->mode = QColormap::Indexed;
- screenMap->numcolors = 256;
- } else {
- screenMap->mode = QColormap::Direct;
- screenMap->numcolors = -1;
- }
-}
-
-void QColormap::cleanup()
-{
- delete screenMap;
- screenMap = 0;
-}
-
-QColormap QColormap::instance(int /*screen*/)
-{
- return QColormap();
-}
-
-QColormap::QColormap()
- : d(screenMap)
-{ d->ref.ref(); }
-
-QColormap::QColormap(const QColormap &colormap)
- :d (colormap.d)
-{ d->ref.ref(); }
-
-QColormap::~QColormap()
-{
- if (!d->ref.deref())
- delete d;
-}
-
-QColormap::Mode QColormap::mode() const
-{ return d->mode; }
-
-
-int QColormap::depth() const
-{ return d->depth; }
-
-
-int QColormap::size() const
-{
- return d->numcolors;
-}
-
-uint QColormap::pixel(const QColor &color) const
-{
- QRgb rgb = color.rgba();
- if (d->mode == QColormap::Direct) {
- switch(d->depth) {
- case 16:
- return qt_convRgbTo16(rgb);
- case 24:
- case 32:
- {
- const int r = qRed(rgb);
- const int g = qGreen(rgb);
- const int b = qBlue(rgb);
- const int red_shift = 16;
- const int green_shift = 8;
- const int red_mask = 0xff0000;
- const int green_mask = 0x00ff00;
- const int blue_mask = 0x0000ff;
- const int tg = g << green_shift;
-#ifdef QT_QWS_DEPTH_32_BGR
- if (qt_screen->pixelType() == QScreen::BGRPixel) {
- const int tb = b << red_shift;
- return 0xff000000 | (r & blue_mask) | (tg & green_mask) | (tb & red_mask);
- }
-#endif
- const int tr = r << red_shift;
- return 0xff000000 | (b & blue_mask) | (tg & green_mask) | (tr & red_mask);
- }
- }
- }
- return qt_screen->alloc(qRed(rgb), qGreen(rgb), qBlue(rgb));
-}
-
-const QColor QColormap::colorAt(uint pixel) const
-{
- if (d->mode == Direct) {
- if (d->depth == 16) {
- pixel = qt_conv16ToRgb(pixel);
- }
- const int red_shift = 16;
- const int green_shift = 8;
- const int red_mask = 0xff0000;
- const int green_mask = 0x00ff00;
- const int blue_mask = 0x0000ff;
-#ifdef QT_QWS_DEPTH_32_BGR
- if (qt_screen->pixelType() == QScreen::BGRPixel) {
- return QColor((pixel & blue_mask),
- (pixel & green_mask) >> green_shift,
- (pixel & red_mask) >> red_shift);
- }
-#endif
- return QColor((pixel & red_mask) >> red_shift,
- (pixel & green_mask) >> green_shift,
- (pixel & blue_mask));
- }
- Q_ASSERT_X(int(pixel) < qt_screen->colorCount(), "QColormap::colorAt", "pixel out of bounds of palette");
- return QColor(qt_screen->clut()[pixel]);
-}
-
-const QVector<QColor> QColormap::colormap() const
-{
- return QVector<QColor>();
-}
-
-QColormap &QColormap::operator=(const QColormap &colormap)
-{ qAtomicAssign(d, colormap.d); return *this; }
-
-QT_END_NAMESPACE
diff --git a/src/gui/painting/qcssutil_p.h b/src/gui/painting/qcssutil_p.h
index be206f35b8..fe5b7057b9 100644
--- a/src/gui/painting/qcssutil_p.h
+++ b/src/gui/painting/qcssutil_p.h
@@ -71,10 +71,10 @@ extern void qDrawRoundedCorners(QPainter *p, qreal x1, qreal y1, qreal x2, qreal
const QSizeF& r1, const QSizeF& r2,
QCss::Edge edge, QCss::BorderStyle s, QBrush c);
-extern void qDrawBorder(QPainter *p, const QRect &rect, const QCss::BorderStyle *styles,
+extern void Q_GUI_EXPORT qDrawBorder(QPainter *p, const QRect &rect, const QCss::BorderStyle *styles,
const int *borders, const QBrush *colors, const QSize *radii);
-extern void qNormalizeRadii(const QRect &br, const QSize *radii,
+extern void Q_GUI_EXPORT qNormalizeRadii(const QRect &br, const QSize *radii,
QSize *tlr, QSize *trr, QSize *blr, QSize *brr);
QT_END_NAMESPACE
diff --git a/src/gui/painting/qcups.cpp b/src/gui/painting/qcups.cpp
deleted file mode 100644
index 3ec5f72395..0000000000
--- a/src/gui/painting/qcups.cpp
+++ /dev/null
@@ -1,401 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#include <qdebug.h>
-#include "qcups_p.h"
-
-#ifndef QT_NO_CUPS
-
-#ifndef QT_LINUXBASE // LSB merges everything into cups.h
-# include <cups/language.h>
-#endif
-#include <qtextcodec.h>
-
-QT_BEGIN_NAMESPACE
-
-typedef int (*CupsGetDests)(cups_dest_t **dests);
-typedef void (*CupsFreeDests)(int num_dests, cups_dest_t *dests);
-typedef const char* (*CupsGetPPD)(const char *printer);
-typedef int (*CupsMarkOptions)(ppd_file_t *ppd, int num_options, cups_option_t *options);
-typedef ppd_file_t* (*PPDOpenFile)(const char *filename);
-typedef void (*PPDMarkDefaults)(ppd_file_t *ppd);
-typedef int (*PPDMarkOption)(ppd_file_t *ppd, const char *keyword, const char *option);
-typedef void (*PPDClose)(ppd_file_t *ppd);
-typedef int (*PPDMarkOption)(ppd_file_t *ppd, const char *keyword, const char *option);
-typedef void (*CupsFreeOptions)(int num_options, cups_option_t *options);
-typedef void (*CupsSetDests)(int num_dests, cups_dest_t *dests);
-typedef cups_lang_t* (*CupsLangGet)(const char *language);
-typedef const char* (*CupsLangEncoding)(cups_lang_t *language);
-typedef int (*CupsAddOption)(const char *name, const char *value, int num_options, cups_option_t **options);
-typedef int (*CupsTempFd)(char *name, int len);
-typedef int (*CupsPrintFile)(const char * name, const char * filename, const char * title, int num_options, cups_option_t * options);
-
-static bool cupsLoaded = false;
-static int qt_cups_num_printers = 0;
-static CupsGetDests _cupsGetDests = 0;
-static CupsFreeDests _cupsFreeDests = 0;
-static CupsGetPPD _cupsGetPPD = 0;
-static PPDOpenFile _ppdOpenFile = 0;
-static PPDMarkDefaults _ppdMarkDefaults = 0;
-static PPDClose _ppdClose = 0;
-static CupsMarkOptions _cupsMarkOptions = 0;
-static PPDMarkOption _ppdMarkOption = 0;
-static CupsFreeOptions _cupsFreeOptions = 0;
-static CupsSetDests _cupsSetDests = 0;
-static CupsLangGet _cupsLangGet = 0;
-static CupsLangEncoding _cupsLangEncoding = 0;
-static CupsAddOption _cupsAddOption = 0;
-static CupsTempFd _cupsTempFd = 0;
-static CupsPrintFile _cupsPrintFile = 0;
-
-static void resolveCups()
-{
- QLibrary cupsLib(QLatin1String("cups"), 2);
- if(cupsLib.load()) {
- _cupsGetDests = (CupsGetDests) cupsLib.resolve("cupsGetDests");
- _cupsFreeDests = (CupsFreeDests) cupsLib.resolve("cupsFreeDests");
- _cupsGetPPD = (CupsGetPPD) cupsLib.resolve("cupsGetPPD");
- _cupsLangGet = (CupsLangGet) cupsLib.resolve("cupsLangGet");
- _cupsLangEncoding = (CupsLangEncoding) cupsLib.resolve("cupsLangEncoding");
- _ppdOpenFile = (PPDOpenFile) cupsLib.resolve("ppdOpenFile");
- _ppdMarkDefaults = (PPDMarkDefaults) cupsLib.resolve("ppdMarkDefaults");
- _ppdClose = (PPDClose) cupsLib.resolve("ppdClose");
- _cupsMarkOptions = (CupsMarkOptions) cupsLib.resolve("cupsMarkOptions");
- _ppdMarkOption = (PPDMarkOption) cupsLib.resolve("ppdMarkOption");
- _cupsFreeOptions = (CupsFreeOptions) cupsLib.resolve("cupsFreeOptions");
- _cupsSetDests = (CupsSetDests) cupsLib.resolve("cupsSetDests");
- _cupsAddOption = (CupsAddOption) cupsLib.resolve("cupsAddOption");
- _cupsTempFd = (CupsTempFd) cupsLib.resolve("cupsTempFd");
- _cupsPrintFile = (CupsPrintFile) cupsLib.resolve("cupsPrintFile");
-
- if (_cupsGetDests && _cupsFreeDests) {
- cups_dest_t *printers;
- int num_printers = _cupsGetDests(&printers);
- if (num_printers)
- _cupsFreeDests(num_printers, printers);
- qt_cups_num_printers = num_printers;
- }
- }
- cupsLoaded = true;
-}
-
-// ================ CUPS Support class ========================
-
-QCUPSSupport::QCUPSSupport()
- :
- prnCount(0),
- printers(0),
- page_sizes(0),
- currPrinterIndex(0),
- currPPD(0)
-{
- if (!cupsLoaded)
- resolveCups();
-
- // getting all available printers
- if (!isAvailable())
- return;
-
- prnCount = _cupsGetDests(&printers);
-
- for (int i = 0; i < prnCount; ++i) {
- if (printers[i].is_default) {
- currPrinterIndex = i;
- setCurrentPrinter(i);
- break;
- }
- }
-
-#ifndef QT_NO_TEXTCODEC
- cups_lang_t *cupsLang = _cupsLangGet(0);
- codec = QTextCodec::codecForName(_cupsLangEncoding(cupsLang));
- if (!codec)
- codec = QTextCodec::codecForLocale();
-#endif
-}
-
-QCUPSSupport::~QCUPSSupport()
-{
- if (currPPD)
- _ppdClose(currPPD);
- if (prnCount)
- _cupsFreeDests(prnCount, printers);
-}
-
-int QCUPSSupport::availablePrintersCount() const
-{
- return prnCount;
-}
-
-const cups_dest_t* QCUPSSupport::availablePrinters() const
-{
- return printers;
-}
-
-const ppd_file_t* QCUPSSupport::currentPPD() const
-{
- return currPPD;
-}
-
-const ppd_file_t* QCUPSSupport::setCurrentPrinter(int index)
-{
- Q_ASSERT(index >= 0 && index <= prnCount);
- if (index == prnCount)
- return 0;
-
- currPrinterIndex = index;
-
- if (currPPD)
- _ppdClose(currPPD);
- currPPD = 0;
- page_sizes = 0;
-
- const char *ppdFile = _cupsGetPPD(printers[index].name);
-
- if (!ppdFile)
- return 0;
-
- currPPD = _ppdOpenFile(ppdFile);
- unlink(ppdFile);
-
- // marking default options
- _ppdMarkDefaults(currPPD);
-
- // marking options explicitly set
- _cupsMarkOptions(currPPD, printers[currPrinterIndex].num_options, printers[currPrinterIndex].options);
-
- // getting pointer to page sizes
- page_sizes = ppdOption("PageSize");
-
- return currPPD;
-}
-
-int QCUPSSupport::currentPrinterIndex() const
-{
- return currPrinterIndex;
-}
-
-bool QCUPSSupport::isAvailable()
-{
- if(!cupsLoaded)
- resolveCups();
-
- return _cupsGetDests &&
- _cupsFreeDests &&
- _cupsGetPPD &&
- _ppdOpenFile &&
- _ppdMarkDefaults &&
- _ppdClose &&
- _cupsMarkOptions &&
- _ppdMarkOption &&
- _cupsFreeOptions &&
- _cupsSetDests &&
- _cupsLangGet &&
- _cupsLangEncoding &&
- _cupsAddOption &&
- (qt_cups_num_printers > 0);
-}
-
-const ppd_option_t* QCUPSSupport::ppdOption(const char *key) const
-{
- if (currPPD) {
- for (int gr = 0; gr < currPPD->num_groups; ++gr) {
- for (int opt = 0; opt < currPPD->groups[gr].num_options; ++opt) {
- if (qstrcmp(currPPD->groups[gr].options[opt].keyword, key) == 0)
- return &currPPD->groups[gr].options[opt];
- }
- }
- }
- return 0;
-}
-
-const cups_option_t* QCUPSSupport::printerOption(const QString &key) const
-{
- for (int i = 0; i < printers[currPrinterIndex].num_options; ++i) {
- if (QLatin1String(printers[currPrinterIndex].options[i].name) == key)
- return &printers[currPrinterIndex].options[i];
- }
- return 0;
-}
-
-const ppd_option_t* QCUPSSupport::pageSizes() const
-{
- return page_sizes;
-}
-
-int QCUPSSupport::markOption(const char* name, const char* value)
-{
- return _ppdMarkOption(currPPD, name, value);
-}
-
-void QCUPSSupport::saveOptions(QList<const ppd_option_t*> options, QList<const char*> markedOptions)
-{
- int oldOptionCount = printers[currPrinterIndex].num_options;
- cups_option_t* oldOptions = printers[currPrinterIndex].options;
-
- int newOptionCount = 0;
- cups_option_t* newOptions = 0;
-
- // copying old options that are not on the new list
- for (int i = 0; i < oldOptionCount; ++i) {
- bool contains = false;
- for (int j = 0; j < options.count(); ++j) {
- if (qstrcmp(options.at(j)->keyword, oldOptions[i].name) == 0) {
- contains = true;
- break;
- }
- }
-
- if (!contains) {
- newOptionCount = _cupsAddOption(oldOptions[i].name, oldOptions[i].value, newOptionCount, &newOptions);
- }
- }
-
- // we can release old option list
- _cupsFreeOptions(oldOptionCount, oldOptions);
-
- // adding marked options
- for (int i = 0; i < markedOptions.count(); ++i) {
- const char* name = markedOptions.at(i);
- ++i;
- newOptionCount = _cupsAddOption(name, markedOptions.at(i), newOptionCount, &newOptions);
- }
-
- // placing the new option list
- printers[currPrinterIndex].num_options = newOptionCount;
- printers[currPrinterIndex].options = newOptions;
-
- // saving new default values
- _cupsSetDests(prnCount, printers);
-}
-
-QRect QCUPSSupport::paperRect(const char *choice) const
-{
- if (!currPPD)
- return QRect();
- for (int i = 0; i < currPPD->num_sizes; ++i) {
- if (qstrcmp(currPPD->sizes[i].name, choice) == 0)
- return QRect(0, 0, qRound(currPPD->sizes[i].width), qRound(currPPD->sizes[i].length));
- }
- return QRect();
-}
-
-QRect QCUPSSupport::pageRect(const char *choice) const
-{
- if (!currPPD)
- return QRect();
- for (int i = 0; i < currPPD->num_sizes; ++i) {
- if (qstrcmp(currPPD->sizes[i].name, choice) == 0)
- return QRect(qRound(currPPD->sizes[i].left),
- qRound(currPPD->sizes[i].length - currPPD->sizes[i].top),
- qRound(currPPD->sizes[i].right - currPPD->sizes[i].left),
- qRound(currPPD->sizes[i].top - currPPD->sizes[i].bottom));
- }
- return QRect();
-}
-
-QStringList QCUPSSupport::options() const
-{
- QStringList list;
- collectMarkedOptions(list);
- return list;
-}
-
-bool QCUPSSupport::printerHasPPD(const char *printerName)
-{
- if (!isAvailable())
- return false;
- const char *ppdFile = _cupsGetPPD(printerName);
- if (ppdFile)
- unlink(ppdFile);
- return (ppdFile != 0);
-}
-
-QString QCUPSSupport::unicodeString(const char *s)
-{
-#ifndef QT_NO_TEXTCODEC
- return codec->toUnicode(s);
-#else
- return QLatin1String(s);
-#endif
-}
-
-void QCUPSSupport::collectMarkedOptions(QStringList& list, const ppd_group_t* group) const
-{
- if (group == 0) {
- if (!currPPD)
- return;
- for (int i = 0; i < currPPD->num_groups; ++i) {
- collectMarkedOptions(list, &currPPD->groups[i]);
- collectMarkedOptionsHelper(list, &currPPD->groups[i]);
- }
- } else {
- for (int i = 0; i < group->num_subgroups; ++i)
- collectMarkedOptionsHelper(list, &group->subgroups[i]);
- }
-}
-
-void QCUPSSupport::collectMarkedOptionsHelper(QStringList& list, const ppd_group_t* group) const
-{
- for (int i = 0; i < group->num_options; ++i) {
- for (int j = 0; j < group->options[i].num_choices; ++j) {
- if (group->options[i].choices[j].marked == 1 && qstrcmp(group->options[i].choices[j].choice, group->options[i].defchoice) != 0)
- list << QString::fromLocal8Bit(group->options[i].keyword) << QString::fromLocal8Bit(group->options[i].choices[j].choice);
- }
- }
-}
-
-QPair<int, QString> QCUPSSupport::tempFd()
-{
- char filename[512];
- int fd = _cupsTempFd(filename, 512);
- return QPair<int, QString>(fd, QString::fromLocal8Bit(filename));
-}
-
-// Prints the given file and returns a job id.
-int QCUPSSupport::printFile(const char * printerName, const char * filename, const char * title,
- int num_options, cups_option_t * options)
-{
- return _cupsPrintFile(printerName, filename, title, num_options, options);
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_CUPS
diff --git a/src/gui/painting/qcups_p.h b/src/gui/painting/qcups_p.h
deleted file mode 100644
index 47ed7e14ef..0000000000
--- a/src/gui/painting/qcups_p.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QCUPS_P_H
-#define QCUPS_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-#include "QtCore/qstring.h"
-#include "QtCore/qstringlist.h"
-#include "QtGui/qprinter.h"
-
-#ifndef QT_NO_CUPS
-#include <QtCore/qlibrary.h>
-#include <cups/cups.h>
-#include <cups/ppd.h>
-
-QT_BEGIN_NAMESPACE
-
-Q_DECLARE_TYPEINFO(cups_option_t, Q_MOVABLE_TYPE | Q_PRIMITIVE_TYPE);
-
-class QCUPSSupport
-{
-public:
- QCUPSSupport();
- ~QCUPSSupport();
-
- static bool isAvailable();
- static int cupsVersion() { return isAvailable() ? CUPS_VERSION_MAJOR*10000+CUPS_VERSION_MINOR*100+CUPS_VERSION_PATCH : 0; }
- int availablePrintersCount() const;
- const cups_dest_t* availablePrinters() const;
- int currentPrinterIndex() const;
- const ppd_file_t* setCurrentPrinter(int index);
-
- const ppd_file_t* currentPPD() const;
- const ppd_option_t* ppdOption(const char *key) const;
-
- const cups_option_t* printerOption(const QString &key) const;
- const ppd_option_t* pageSizes() const;
-
- int markOption(const char* name, const char* value);
- void saveOptions(QList<const ppd_option_t*> options, QList<const char*> markedOptions);
-
- QRect paperRect(const char *choice) const;
- QRect pageRect(const char *choice) const;
-
- QStringList options() const;
-
- static bool printerHasPPD(const char *printerName);
-
- QString unicodeString(const char *s);
-
- QPair<int, QString> tempFd();
- int printFile(const char * printerName, const char * filename, const char * title,
- int num_options, cups_option_t * options);
-
-private:
- void collectMarkedOptions(QStringList& list, const ppd_group_t* group = 0) const;
- void collectMarkedOptionsHelper(QStringList& list, const ppd_group_t* group) const;
-
- int prnCount;
- cups_dest_t *printers;
- const ppd_option_t* page_sizes;
- int currPrinterIndex;
- ppd_file_t *currPPD;
-#ifndef QT_NO_TEXTCODEC
- QTextCodec *codec;
-#endif
-};
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_CUPS
-
-#endif
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index c97ef24622..cfd9934e9b 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -3285,9 +3285,6 @@ static
void drawBufferSpan(QSpanData *data, const uint *buffer, int bufsize,
int x, int y, int length, uint const_alpha)
{
-#if defined (Q_WS_QWS) && !defined(QT_NO_RASTERCALLBACKS)
- data->rasterEngine->drawBufferSpan(buffer, bufsize, x, y, length, const_alpha);
-#else
Q_UNUSED(data);
Q_UNUSED(buffer);
Q_UNUSED(bufsize);
@@ -3295,7 +3292,6 @@ void drawBufferSpan(QSpanData *data, const uint *buffer, int bufsize,
Q_UNUSED(y);
Q_UNUSED(length);
Q_UNUSED(const_alpha);
-#endif
}
#if !defined(Q_CC_SUN)
@@ -3323,18 +3319,6 @@ void blend_color_generic(int count, const QSpan *spans, void *userData)
}
}
-#if defined (Q_WS_QWS) && !defined(QT_NO_RASTERCALLBACKS)
-static void blend_color_generic_callback(int count, const QSpan *spans, void *userData)
-{
- // ### Falcon
- Q_UNUSED(count);
- Q_UNUSED(spans);
- Q_UNUSED(userData);
-// QSpanData *data = reinterpret_cast<QSpanData*>(userData);
-// data->rasterEngine->drawColorSpans(spans, count, data->solid.color);
-}
-#endif // QT_NO_RASTERCALLBACKS
-
static void blend_color_argb(int count, const QSpan *spans, void *userData)
{
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
@@ -4957,65 +4941,30 @@ void QT_FASTCALL blendUntransformed(int count, const QSpan *spans, void *userDat
static void blend_untransformed_rgb888(int count, const QSpan *spans,
void *userData)
{
-#if defined(QT_QWS_DEPTH_24)
- QSpanData *data = reinterpret_cast<QSpanData *>(userData);
-
- if (data->texture.format == QImage::Format_RGB888)
- blendUntransformed<qrgb888, qrgb888>(count, spans, userData);
- else
-#endif
- blend_untransformed_generic<RegularSpans>(count, spans, userData);
+ blend_untransformed_generic<RegularSpans>(count, spans, userData);
}
static void blend_untransformed_argb6666(int count, const QSpan *spans,
void *userData)
{
-#if defined(QT_QWS_DEPTH_18)
- QSpanData *data = reinterpret_cast<QSpanData *>(userData);
-
- if (data->texture.format == QImage::Format_ARGB6666_Premultiplied)
- blendUntransformed<qargb6666, qargb6666>(count, spans, userData);
- else if (data->texture.format == QImage::Format_RGB666)
- blendUntransformed<qargb6666, qrgb666>(count, spans, userData);
- else
-#endif
- blend_untransformed_generic<RegularSpans>(count, spans, userData);
+ blend_untransformed_generic<RegularSpans>(count, spans, userData);
}
static void blend_untransformed_rgb666(int count, const QSpan *spans,
void *userData)
{
-#if defined(QT_QWS_DEPTH_18)
- QSpanData *data = reinterpret_cast<QSpanData *>(userData);
-
- if (data->texture.format == QImage::Format_ARGB6666_Premultiplied)
- blendUntransformed<qrgb666, qargb6666>(count, spans, userData);
- else if (data->texture.format == QImage::Format_RGB666)
- blendUntransformed<qrgb666, qrgb666>(count, spans, userData);
- else
-#endif
- blend_untransformed_generic<RegularSpans>(count, spans, userData);
+ blend_untransformed_generic<RegularSpans>(count, spans, userData);
}
static void blend_untransformed_argb8565(int count, const QSpan *spans,
void *userData)
{
-#if defined(QT_QWS_DEPTH_16)
- QSpanData *data = reinterpret_cast<QSpanData *>(userData);
-
- if (data->texture.format == QImage::Format_ARGB8565_Premultiplied)
- blendUntransformed<qargb8565, qargb8565>(count, spans, userData);
- else if (data->texture.format == QImage::Format_RGB16)
- blendUntransformed<qargb8565, qrgb565>(count, spans, userData);
- else
-#endif
- blend_untransformed_generic<RegularSpans>(count, spans, userData);
+ blend_untransformed_generic<RegularSpans>(count, spans, userData);
}
static void blend_untransformed_rgb565(int count, const QSpan *spans,
void *userData)
{
-#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_16)
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format == QImage::Format_ARGB8565_Premultiplied)
@@ -5023,68 +4972,31 @@ static void blend_untransformed_rgb565(int count, const QSpan *spans,
else if (data->texture.format == QImage::Format_RGB16)
blendUntransformed<qrgb565, qrgb565>(count, spans, userData);
else
-#endif
blend_untransformed_generic<RegularSpans>(count, spans, userData);
}
static void blend_untransformed_argb8555(int count, const QSpan *spans,
void *userData)
{
-#if defined(QT_QWS_DEPTH_15)
- QSpanData *data = reinterpret_cast<QSpanData *>(userData);
-
- if (data->texture.format == QImage::Format_ARGB8555_Premultiplied)
- blendUntransformed<qargb8555, qargb8555>(count, spans, userData);
- else if (data->texture.format == QImage::Format_RGB555)
- blendUntransformed<qargb8555, qrgb555>(count, spans, userData);
- else
-#endif
- blend_untransformed_generic<RegularSpans>(count, spans, userData);
+ blend_untransformed_generic<RegularSpans>(count, spans, userData);
}
static void blend_untransformed_rgb555(int count, const QSpan *spans,
void *userData)
{
-#if defined(QT_QWS_DEPTH_15)
- QSpanData *data = reinterpret_cast<QSpanData *>(userData);
-
- if (data->texture.format == QImage::Format_ARGB8555_Premultiplied)
- blendUntransformed<qrgb555, qargb8555>(count, spans, userData);
- else if (data->texture.format == QImage::Format_RGB555)
- blendUntransformed<qrgb555, qrgb555>(count, spans, userData);
- else
-#endif
- blend_untransformed_generic<RegularSpans>(count, spans, userData);
+ blend_untransformed_generic<RegularSpans>(count, spans, userData);
}
static void blend_untransformed_argb4444(int count, const QSpan *spans,
void *userData)
{
-#if defined(QT_QWS_DEPTH_12)
- QSpanData *data = reinterpret_cast<QSpanData *>(userData);
-
- if (data->texture.format == QImage::Format_ARGB4444_Premultiplied)
- blendUntransformed<qargb4444, qargb4444>(count, spans, userData);
- else if (data->texture.format == QImage::Format_RGB444)
- blendUntransformed<qargb4444, qrgb444>(count, spans, userData);
- else
-#endif
- blend_untransformed_generic<RegularSpans>(count, spans, userData);
+ blend_untransformed_generic<RegularSpans>(count, spans, userData);
}
static void blend_untransformed_rgb444(int count, const QSpan *spans,
void *userData)
{
-#if defined(QT_QWS_DEPTH_12)
- QSpanData *data = reinterpret_cast<QSpanData *>(userData);
-
- if (data->texture.format == QImage::Format_ARGB4444_Premultiplied)
- blendUntransformed<qrgb444, qargb4444>(count, spans, userData);
- else if (data->texture.format == QImage::Format_RGB444)
- blendUntransformed<qrgb444, qrgb444>(count, spans, userData);
- else
-#endif
- blend_untransformed_generic<RegularSpans>(count, spans, userData);
+ blend_untransformed_generic<RegularSpans>(count, spans, userData);
}
template <SpanMethod spanMethod>
@@ -5300,61 +5212,26 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTiled(int count, const QSpan *spans, void *
static void blend_tiled_rgb888(int count, const QSpan *spans, void *userData)
{
-#if defined(QT_QWS_DEPTH_24)
- QSpanData *data = reinterpret_cast<QSpanData *>(userData);
-
- if (data->texture.format == QImage::Format_RGB888)
- blendTiled<qrgb888, qrgb888>(count, spans, userData);
- else
-#endif
- blend_tiled_generic<RegularSpans>(count, spans, userData);
+ blend_tiled_generic<RegularSpans>(count, spans, userData);
}
static void blend_tiled_argb6666(int count, const QSpan *spans, void *userData)
{
-#if defined(QT_QWS_DEPTH_18)
- QSpanData *data = reinterpret_cast<QSpanData *>(userData);
-
- if (data->texture.format == QImage::Format_ARGB6666_Premultiplied)
- blendTiled<qargb6666, qargb6666>(count, spans, userData);
- else if (data->texture.format == QImage::Format_RGB666)
- blendTiled<qargb6666, qrgb666>(count, spans, userData);
- else
-#endif
- blend_tiled_generic<RegularSpans>(count, spans, userData);
+ blend_tiled_generic<RegularSpans>(count, spans, userData);
}
static void blend_tiled_rgb666(int count, const QSpan *spans, void *userData)
{
-#if defined(QT_QWS_DEPTH_18)
- QSpanData *data = reinterpret_cast<QSpanData *>(userData);
-
- if (data->texture.format == QImage::Format_ARGB6666_Premultiplied)
- blendTiled<qrgb666, qargb6666>(count, spans, userData);
- else if (data->texture.format == QImage::Format_RGB666)
- blendTiled<qrgb666, qrgb666>(count, spans, userData);
- else
-#endif
- blend_tiled_generic<RegularSpans>(count, spans, userData);
+ blend_tiled_generic<RegularSpans>(count, spans, userData);
}
static void blend_tiled_argb8565(int count, const QSpan *spans, void *userData)
{
-#if defined(QT_QWS_DEPTH_16)
- QSpanData *data = reinterpret_cast<QSpanData *>(userData);
-
- if (data->texture.format == QImage::Format_ARGB8565_Premultiplied)
- blendTiled<qargb8565, qargb8565>(count, spans, userData);
- else if (data->texture.format == QImage::Format_RGB16)
- blendTiled<qargb8565, qrgb565>(count, spans, userData);
- else
-#endif
- blend_tiled_generic<RegularSpans>(count, spans, userData);
+ blend_tiled_generic<RegularSpans>(count, spans, userData);
}
static void blend_tiled_rgb565(int count, const QSpan *spans, void *userData)
{
-#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_16)
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format == QImage::Format_ARGB8565_Premultiplied)
@@ -5362,64 +5239,27 @@ static void blend_tiled_rgb565(int count, const QSpan *spans, void *userData)
else if (data->texture.format == QImage::Format_RGB16)
blendTiled<qrgb565, qrgb565>(count, spans, userData);
else
-#endif
blend_tiled_generic<RegularSpans>(count, spans, userData);
}
static void blend_tiled_argb8555(int count, const QSpan *spans, void *userData)
{
-#if defined(QT_QWS_DEPTH_15)
- QSpanData *data = reinterpret_cast<QSpanData *>(userData);
-
- if (data->texture.format == QImage::Format_ARGB8555_Premultiplied)
- blendTiled<qargb8555, qargb8555>(count, spans, userData);
- else if (data->texture.format == QImage::Format_RGB555)
- blendTiled<qargb8555, qrgb555>(count, spans, userData);
- else
-#endif
- blend_tiled_generic<RegularSpans>(count, spans, userData);
+ blend_tiled_generic<RegularSpans>(count, spans, userData);
}
static void blend_tiled_rgb555(int count, const QSpan *spans, void *userData)
{
-#if defined(QT_QWS_DEPTH_15)
- QSpanData *data = reinterpret_cast<QSpanData *>(userData);
-
- if (data->texture.format == QImage::Format_ARGB8555_Premultiplied)
- blendTiled<qrgb555, qargb8555>(count, spans, userData);
- else if (data->texture.format == QImage::Format_RGB555)
- blendTiled<qrgb555, qrgb555>(count, spans, userData);
- else
-#endif
- blend_tiled_generic<RegularSpans>(count, spans, userData);
+ blend_tiled_generic<RegularSpans>(count, spans, userData);
}
static void blend_tiled_argb4444(int count, const QSpan *spans, void *userData)
{
-#if defined(QT_QWS_DEPTH_12)
- QSpanData *data = reinterpret_cast<QSpanData *>(userData);
-
- if (data->texture.format == QImage::Format_ARGB4444_Premultiplied)
- blendTiled<qargb4444, qargb4444>(count, spans, userData);
- else if (data->texture.format == QImage::Format_RGB444)
- blendTiled<qargb4444, qrgb444>(count, spans, userData);
- else
-#endif
- blend_tiled_generic<RegularSpans>(count, spans, userData);
+ blend_tiled_generic<RegularSpans>(count, spans, userData);
}
static void blend_tiled_rgb444(int count, const QSpan *spans, void *userData)
{
-#if defined(QT_QWS_DEPTH_12)
- QSpanData *data = reinterpret_cast<QSpanData *>(userData);
-
- if (data->texture.format == QImage::Format_ARGB4444_Premultiplied)
- blendTiled<qrgb444, qargb4444>(count, spans, userData);
- else if (data->texture.format == QImage::Format_RGB444)
- blendTiled<qrgb444, qrgb444>(count, spans, userData);
- else
-#endif
- blend_tiled_generic<RegularSpans>(count, spans, userData);
+ blend_tiled_generic<RegularSpans>(count, spans, userData);
}
template <class DST, class SRC>
@@ -5647,62 +5487,27 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTransformedBilinear(int count, const QSpan
static void blend_transformed_bilinear_rgb888(int count, const QSpan *spans, void *userData)
{
-#if defined(QT_QWS_DEPTH_24)
- QSpanData *data = reinterpret_cast<QSpanData *>(userData);
-
- if (data->texture.format == QImage::Format_RGB888)
- blendTransformedBilinear<qrgb888, qrgb888>(count, spans, userData);
- else
-#endif
- blend_src_generic<RegularSpans>(count, spans, userData);
+ blend_src_generic<RegularSpans>(count, spans, userData);
}
static void blend_transformed_bilinear_argb6666(int count, const QSpan *spans, void *userData)
{
-#if defined(QT_QWS_DEPTH_18)
- QSpanData *data = reinterpret_cast<QSpanData *>(userData);
-
- if (data->texture.format == QImage::Format_ARGB6666_Premultiplied)
- blendTransformedBilinear<qargb6666, qargb6666>(count, spans, userData);
- else if (data->texture.format == QImage::Format_RGB666)
- blendTransformedBilinear<qargb6666, qrgb666>(count, spans, userData);
- else
-#endif
- blend_src_generic<RegularSpans>(count, spans, userData);
+ blend_src_generic<RegularSpans>(count, spans, userData);
}
static void blend_transformed_bilinear_rgb666(int count, const QSpan *spans, void *userData)
{
-#if defined(QT_QWS_DEPTH_18)
- QSpanData *data = reinterpret_cast<QSpanData *>(userData);
-
- if (data->texture.format == QImage::Format_ARGB6666_Premultiplied)
- blendTransformedBilinear<qrgb666, qargb6666>(count, spans, userData);
- else if (data->texture.format == QImage::Format_RGB666)
- blendTransformedBilinear<qrgb666, qrgb666>(count, spans, userData);
- else
-#endif
- blend_src_generic<RegularSpans>(count, spans, userData);
+ blend_src_generic<RegularSpans>(count, spans, userData);
}
static void blend_transformed_bilinear_argb8565(int count, const QSpan *spans, void *userData)
{
-#if defined(QT_QWS_DEPTH_16)
- QSpanData *data = reinterpret_cast<QSpanData *>(userData);
-
- if (data->texture.format == QImage::Format_ARGB8565_Premultiplied)
- blendTransformedBilinear<qargb8565, qargb8565>(count, spans, userData);
- else if (data->texture.format == QImage::Format_RGB16)
- blendTransformedBilinear<qargb8565, qrgb565>(count, spans, userData);
- else
-#endif
- blend_src_generic<RegularSpans>(count, spans, userData);
+ blend_src_generic<RegularSpans>(count, spans, userData);
}
static void blend_transformed_bilinear_rgb565(int count, const QSpan *spans,
void *userData)
{
-#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_16)
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format == QImage::Format_RGB16)
@@ -5710,64 +5515,27 @@ static void blend_transformed_bilinear_rgb565(int count, const QSpan *spans,
else if (data->texture.format == QImage::Format_ARGB8565_Premultiplied)
blendTransformedBilinear<qrgb565, qargb8565>(count, spans, userData);
else
-#endif
blend_src_generic<RegularSpans>(count, spans, userData);
}
static void blend_transformed_bilinear_argb8555(int count, const QSpan *spans, void *userData)
{
-#if defined(QT_QWS_DEPTH_15)
- QSpanData *data = reinterpret_cast<QSpanData *>(userData);
-
- if (data->texture.format == QImage::Format_ARGB8555_Premultiplied)
- blendTransformedBilinear<qargb8555, qargb8555>(count, spans, userData);
- else if (data->texture.format == QImage::Format_RGB555)
- blendTransformedBilinear<qargb8555, qrgb555>(count, spans, userData);
- else
-#endif
- blend_src_generic<RegularSpans>(count, spans, userData);
+ blend_src_generic<RegularSpans>(count, spans, userData);
}
static void blend_transformed_bilinear_rgb555(int count, const QSpan *spans, void *userData)
{
-#if defined(QT_QWS_DEPTH_15)
- QSpanData *data = reinterpret_cast<QSpanData *>(userData);
-
- if (data->texture.format == QImage::Format_ARGB8555_Premultiplied)
- blendTransformedBilinear<qrgb555, qargb8555>(count, spans, userData);
- else if (data->texture.format == QImage::Format_RGB555)
- blendTransformedBilinear<qrgb555, qrgb555>(count, spans, userData);
- else
-#endif
- blend_src_generic<RegularSpans>(count, spans, userData);
+ blend_src_generic<RegularSpans>(count, spans, userData);
}
static void blend_transformed_bilinear_argb4444(int count, const QSpan *spans, void *userData)
{
-#if defined(QT_QWS_DEPTH_12)
- QSpanData *data = reinterpret_cast<QSpanData *>(userData);
-
- if (data->texture.format == QImage::Format_ARGB4444_Premultiplied)
- blendTransformedBilinear<qargb4444, qargb4444>(count, spans, userData);
- else if (data->texture.format == QImage::Format_RGB444)
- blendTransformedBilinear<qargb4444, qrgb444>(count, spans, userData);
- else
-#endif
- blend_src_generic<RegularSpans>(count, spans, userData);
+ blend_src_generic<RegularSpans>(count, spans, userData);
}
static void blend_transformed_bilinear_rgb444(int count, const QSpan *spans, void *userData)
{
-#if defined(QT_QWS_DEPTH_12)
- QSpanData *data = reinterpret_cast<QSpanData *>(userData);
-
- if (data->texture.format == QImage::Format_ARGB4444_Premultiplied)
- blendTransformedBilinear<qrgb444, qargb4444>(count, spans, userData);
- else if (data->texture.format == QImage::Format_RGB444)
- blendTransformedBilinear<qrgb444, qrgb444>(count, spans, userData);
- else
-#endif
- blend_src_generic<RegularSpans>(count, spans, userData);
+ blend_src_generic<RegularSpans>(count, spans, userData);
}
template <SpanMethod spanMethod>
@@ -6040,65 +5808,30 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTransformed(int count, const QSpan *spans,
static void blend_transformed_rgb888(int count, const QSpan *spans,
void *userData)
{
-#if defined(QT_QWS_DEPTH_24)
- QSpanData *data = reinterpret_cast<QSpanData *>(userData);
-
- if (data->texture.format == QImage::Format_RGB888)
- blendTransformed<qrgb888, qrgb888>(count, spans, userData);
- else
-#endif
- blend_src_generic<RegularSpans>(count, spans, userData);
+ blend_src_generic<RegularSpans>(count, spans, userData);
}
static void blend_transformed_argb6666(int count, const QSpan *spans,
void *userData)
{
-#if defined(QT_QWS_DEPTH_18)
- QSpanData *data = reinterpret_cast<QSpanData *>(userData);
-
- if (data->texture.format == QImage::Format_ARGB6666_Premultiplied)
- blendTransformed<qargb6666, qargb6666>(count, spans, userData);
- else if (data->texture.format == QImage::Format_RGB666)
- blendTransformed<qargb6666, qrgb666>(count, spans, userData);
- else
-#endif
- blend_src_generic<RegularSpans>(count, spans, userData);
+ blend_src_generic<RegularSpans>(count, spans, userData);
}
static void blend_transformed_rgb666(int count, const QSpan *spans,
void *userData)
{
-#if defined(QT_QWS_DEPTH_18)
- QSpanData *data = reinterpret_cast<QSpanData *>(userData);
-
- if (data->texture.format == QImage::Format_ARGB6666_Premultiplied)
- blendTransformed<qrgb666, qargb6666>(count, spans, userData);
- else if (data->texture.format == QImage::Format_RGB666)
- blendTransformed<qrgb666, qrgb666>(count, spans, userData);
- else
-#endif
- blend_src_generic<RegularSpans>(count, spans, userData);
+ blend_src_generic<RegularSpans>(count, spans, userData);
}
static void blend_transformed_argb8565(int count, const QSpan *spans,
void *userData)
{
-#if defined(QT_QWS_DEPTH_16)
- QSpanData *data = reinterpret_cast<QSpanData *>(userData);
-
- if (data->texture.format == QImage::Format_ARGB8565_Premultiplied)
- blendTransformed<qargb8565, qargb8565>(count, spans, userData);
- else if (data->texture.format == QImage::Format_RGB16)
- blendTransformed<qargb8565, qrgb565>(count, spans, userData);
- else
-#endif
- blend_src_generic<RegularSpans>(count, spans, userData);
+ blend_src_generic<RegularSpans>(count, spans, userData);
}
static void blend_transformed_rgb565(int count, const QSpan *spans,
void *userData)
{
-#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_16)
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format == QImage::Format_ARGB8565_Premultiplied)
@@ -6106,68 +5839,31 @@ static void blend_transformed_rgb565(int count, const QSpan *spans,
else if (data->texture.format == QImage::Format_RGB16)
blendTransformed<qrgb565, qrgb565>(count, spans, userData);
else
-#endif
blend_src_generic<RegularSpans>(count, spans, userData);
}
static void blend_transformed_argb8555(int count, const QSpan *spans,
void *userData)
{
-#if defined(QT_QWS_DEPTH_15)
- QSpanData *data = reinterpret_cast<QSpanData *>(userData);
-
- if (data->texture.format == QImage::Format_ARGB8555_Premultiplied)
- blendTransformed<qargb8555, qargb8555>(count, spans, userData);
- else if (data->texture.format == QImage::Format_RGB555)
- blendTransformed<qargb8555, qrgb555>(count, spans, userData);
- else
-#endif
- blend_src_generic<RegularSpans>(count, spans, userData);
+ blend_src_generic<RegularSpans>(count, spans, userData);
}
static void blend_transformed_rgb555(int count, const QSpan *spans,
void *userData)
{
-#if defined(QT_QWS_DEPTH_15)
- QSpanData *data = reinterpret_cast<QSpanData *>(userData);
-
- if (data->texture.format == QImage::Format_ARGB8555_Premultiplied)
- blendTransformed<qrgb555, qargb8555>(count, spans, userData);
- else if (data->texture.format == QImage::Format_RGB555)
- blendTransformed<qrgb555, qrgb555>(count, spans, userData);
- else
-#endif
- blend_src_generic<RegularSpans>(count, spans, userData);
+ blend_src_generic<RegularSpans>(count, spans, userData);
}
static void blend_transformed_argb4444(int count, const QSpan *spans,
void *userData)
{
-#if defined(QT_QWS_DEPTH_12)
- QSpanData *data = reinterpret_cast<QSpanData *>(userData);
-
- if (data->texture.format == QImage::Format_ARGB4444_Premultiplied)
- blendTransformed<qargb4444, qargb4444>(count, spans, userData);
- else if (data->texture.format == QImage::Format_RGB444)
- blendTransformed<qargb4444, qrgb444>(count, spans, userData);
- else
-#endif
- blend_src_generic<RegularSpans>(count, spans, userData);
+ blend_src_generic<RegularSpans>(count, spans, userData);
}
static void blend_transformed_rgb444(int count, const QSpan *spans,
void *userData)
{
-#if defined(QT_QWS_DEPTH_12)
- QSpanData *data = reinterpret_cast<QSpanData *>(userData);
-
- if (data->texture.format == QImage::Format_ARGB4444_Premultiplied)
- blendTransformed<qrgb444, qargb4444>(count, spans, userData);
- else if (data->texture.format == QImage::Format_RGB444)
- blendTransformed<qrgb444, qrgb444>(count, spans, userData);
- else
-#endif
- blend_src_generic<RegularSpans>(count, spans, userData);
+ blend_src_generic<RegularSpans>(count, spans, userData);
}
template <SpanMethod spanMethod>
@@ -6455,65 +6151,30 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTransformedTiled(int count, const QSpan *sp
static void blend_transformed_tiled_rgb888(int count, const QSpan *spans,
void *userData)
{
-#if defined(QT_QWS_DEPTH_24)
- QSpanData *data = reinterpret_cast<QSpanData *>(userData);
-
- if (data->texture.format == QImage::Format_RGB888)
- blendTransformedTiled<qrgb888, qrgb888>(count, spans, userData);
- else
-#endif
- blend_src_generic<RegularSpans>(count, spans, userData);
+ blend_src_generic<RegularSpans>(count, spans, userData);
}
static void blend_transformed_tiled_argb6666(int count, const QSpan *spans,
void *userData)
{
-#if defined(QT_QWS_DEPTH_18)
- QSpanData *data = reinterpret_cast<QSpanData *>(userData);
-
- if (data->texture.format == QImage::Format_ARGB6666_Premultiplied)
- blendTransformedTiled<qargb6666, qargb6666>(count, spans, userData);
- else if (data->texture.format == QImage::Format_RGB666)
- blendTransformedTiled<qargb6666, qrgb666>(count, spans, userData);
- else
-#endif
- blend_src_generic<RegularSpans>(count, spans, userData);
+ blend_src_generic<RegularSpans>(count, spans, userData);
}
static void blend_transformed_tiled_rgb666(int count, const QSpan *spans,
void *userData)
{
-#if defined(QT_QWS_DEPTH_18)
- QSpanData *data = reinterpret_cast<QSpanData *>(userData);
-
- if (data->texture.format == QImage::Format_ARGB6666_Premultiplied)
- blendTransformedTiled<qrgb666, qargb6666>(count, spans, userData);
- else if (data->texture.format == QImage::Format_RGB666)
- blendTransformedTiled<qrgb666, qrgb666>(count, spans, userData);
- else
-#endif
- blend_src_generic<RegularSpans>(count, spans, userData);
+ blend_src_generic<RegularSpans>(count, spans, userData);
}
static void blend_transformed_tiled_argb8565(int count, const QSpan *spans,
void *userData)
{
-#if defined(QT_QWS_DEPTH_16)
- QSpanData *data = reinterpret_cast<QSpanData *>(userData);
-
- if (data->texture.format == QImage::Format_ARGB8565_Premultiplied)
- blendTransformedTiled<qargb8565, qargb8565>(count, spans, userData);
- else if (data->texture.format == QImage::Format_RGB16)
- blendTransformedTiled<qargb8565, qrgb565>(count, spans, userData);
- else
-#endif
- blend_src_generic<RegularSpans>(count, spans, userData);
+ blend_src_generic<RegularSpans>(count, spans, userData);
}
static void blend_transformed_tiled_rgb565(int count, const QSpan *spans,
void *userData)
{
-#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_16)
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format == QImage::Format_ARGB8565_Premultiplied)
@@ -6521,68 +6182,31 @@ static void blend_transformed_tiled_rgb565(int count, const QSpan *spans,
else if (data->texture.format == QImage::Format_RGB16)
blendTransformedTiled<qrgb565, qrgb565>(count, spans, userData);
else
-#endif
blend_src_generic<RegularSpans>(count, spans, userData);
}
static void blend_transformed_tiled_argb8555(int count, const QSpan *spans,
void *userData)
{
-#if defined(QT_QWS_DEPTH_15)
- QSpanData *data = reinterpret_cast<QSpanData *>(userData);
-
- if (data->texture.format == QImage::Format_ARGB8555_Premultiplied)
- blendTransformedTiled<qargb8555, qargb8555>(count, spans, userData);
- else if (data->texture.format == QImage::Format_RGB555)
- blendTransformedTiled<qargb8555, qrgb555>(count, spans, userData);
- else
-#endif
- blend_src_generic<RegularSpans>(count, spans, userData);
+ blend_src_generic<RegularSpans>(count, spans, userData);
}
static void blend_transformed_tiled_rgb555(int count, const QSpan *spans,
void *userData)
{
-#if defined(QT_QWS_DEPTH_15)
- QSpanData *data = reinterpret_cast<QSpanData *>(userData);
-
- if (data->texture.format == QImage::Format_ARGB8555_Premultiplied)
- blendTransformedTiled<qrgb555, qargb8555>(count, spans, userData);
- else if (data->texture.format == QImage::Format_RGB555)
- blendTransformedTiled<qrgb555, qrgb555>(count, spans, userData);
- else
-#endif
- blend_src_generic<RegularSpans>(count, spans, userData);
+ blend_src_generic<RegularSpans>(count, spans, userData);
}
static void blend_transformed_tiled_argb4444(int count, const QSpan *spans,
void *userData)
{
-#if defined(QT_QWS_DEPTH_12)
- QSpanData *data = reinterpret_cast<QSpanData *>(userData);
-
- if (data->texture.format == QImage::Format_ARGB4444_Premultiplied)
- blendTransformedTiled<qargb4444, qargb4444>(count, spans, userData);
- else if (data->texture.format == QImage::Format_RGB444)
- blendTransformedTiled<qargb4444, qrgb444>(count, spans, userData);
- else
-#endif
- blend_src_generic<RegularSpans>(count, spans, userData);
+ blend_src_generic<RegularSpans>(count, spans, userData);
}
static void blend_transformed_tiled_rgb444(int count, const QSpan *spans,
void *userData)
{
-#if defined(QT_QWS_DEPTH_12)
- QSpanData *data = reinterpret_cast<QSpanData *>(userData);
-
- if (data->texture.format == QImage::Format_ARGB4444_Premultiplied)
- blendTransformedTiled<qrgb444, qargb4444>(count, spans, userData);
- else if (data->texture.format == QImage::Format_RGB444)
- blendTransformedTiled<qrgb444, qrgb444>(count, spans, userData);
- else
-#endif
- blend_src_generic<RegularSpans>(count, spans, userData);
+ blend_src_generic<RegularSpans>(count, spans, userData);
}
# define SPANFUNC_POINTER(Name, Arg) Name<Arg>
@@ -6706,125 +6330,6 @@ static const ProcessSpans processTextureSpans[NBlendTypes][QImage::NImageFormats
}
};
-#if defined (Q_WS_QWS) && !defined(QT_NO_RASTERCALLBACKS)
-static const ProcessSpans processTextureSpansCallback[NBlendTypes][QImage::NImageFormats] = {
- // Untransformed
- {
- 0, // Invalid
- blend_untransformed_generic<CallbackSpans>, // Mono
- blend_untransformed_generic<CallbackSpans>, // MonoLsb
- blend_untransformed_generic<CallbackSpans>, // Indexed8
- blend_untransformed_generic<CallbackSpans>, // RGB32
- blend_untransformed_generic<CallbackSpans>, // ARGB32
- blend_untransformed_argb<CallbackSpans>, // ARGB32_Premultiplied
- blend_untransformed_generic<CallbackSpans>, // RGB16
- blend_untransformed_generic<CallbackSpans>, // ARGB8565_Premultiplied
- blend_untransformed_generic<CallbackSpans>, // RGB666
- blend_untransformed_generic<CallbackSpans>, // ARGB6666_Premultiplied
- blend_untransformed_generic<CallbackSpans>, // RGB555
- blend_untransformed_generic<CallbackSpans>, // ARGB8555_Premultiplied
- blend_untransformed_generic<CallbackSpans>, // RGB888
- blend_untransformed_generic<CallbackSpans>, // RGB444
- blend_untransformed_generic<CallbackSpans> // ARGB4444_Premultiplied
- },
- // Tiled
- {
- 0, // Invalid
- blend_tiled_generic<CallbackSpans>, // Mono
- blend_tiled_generic<CallbackSpans>, // MonoLsb
- blend_tiled_generic<CallbackSpans>, // Indexed8
- blend_tiled_generic<CallbackSpans>, // RGB32
- blend_tiled_generic<CallbackSpans>, // ARGB32
- blend_tiled_argb<CallbackSpans>, // ARGB32_Premultiplied
- blend_tiled_generic<CallbackSpans>, // RGB16
- blend_tiled_generic<CallbackSpans>, // ARGB8565_Premultiplied
- blend_tiled_generic<CallbackSpans>, // RGB666
- blend_tiled_generic<CallbackSpans>, // ARGB6666_Premultiplied
- blend_tiled_generic<CallbackSpans>, // RGB555
- blend_tiled_generic<CallbackSpans>, // ARGB8555_Premultiplied
- blend_tiled_generic<CallbackSpans>, // RGB888
- blend_tiled_generic<CallbackSpans>, // RGB444
- blend_tiled_generic<CallbackSpans> // ARGB4444_Premultiplied
- },
- // Transformed
- {
- 0, // Invalid
- blend_src_generic<CallbackSpans>, // Mono
- blend_src_generic<CallbackSpans>, // MonoLsb
- blend_src_generic<CallbackSpans>, // Indexed8
- blend_src_generic<CallbackSpans>, // RGB32
- blend_src_generic<CallbackSpans>, // ARGB32
- blend_transformed_argb<CallbackSpans>, // ARGB32_Premultiplied
- blend_src_generic<CallbackSpans>, // RGB16
- blend_src_generic<CallbackSpans>, // ARGB8565_Premultiplied
- blend_src_generic<CallbackSpans>, // RGB666
- blend_src_generic<CallbackSpans>, // ARGB6666_Premultiplied
- blend_src_generic<CallbackSpans>, // RGB555
- blend_src_generic<CallbackSpans>, // ARGB8555_Premultiplied
- blend_src_generic<CallbackSpans>, // RGB888
- blend_src_generic<CallbackSpans>, // RGB444
- blend_src_generic<CallbackSpans>, // ARGB4444_Premultiplied
- },
- // TransformedTiled
- {
- 0,
- blend_src_generic<CallbackSpans>, // Mono
- blend_src_generic<CallbackSpans>, // MonoLsb
- blend_src_generic<CallbackSpans>, // Indexed8
- blend_src_generic<CallbackSpans>, // RGB32
- blend_src_generic<CallbackSpans>, // ARGB32
- blend_transformed_tiled_argb<CallbackSpans>, // ARGB32_Premultiplied
- blend_src_generic<CallbackSpans>, // RGB16
- blend_src_generic<CallbackSpans>, // ARGB8565_Premultiplied
- blend_src_generic<CallbackSpans>, // RGB666
- blend_src_generic<CallbackSpans>, // ARGB6666_Premultiplied
- blend_src_generic<CallbackSpans>, // RGB555
- blend_src_generic<CallbackSpans>, // ARGB8555_Premultiplied
- blend_src_generic<CallbackSpans>, // RGB888
- blend_src_generic<CallbackSpans>, // RGB444
- blend_src_generic<CallbackSpans> // ARGB4444_Premultiplied
- },
- // Bilinear
- {
- 0,
- blend_src_generic<CallbackSpans>, // Mono
- blend_src_generic<CallbackSpans>, // MonoLsb
- blend_src_generic<CallbackSpans>, // Indexed8
- blend_src_generic<CallbackSpans>, // RGB32
- blend_src_generic<CallbackSpans>, // ARGB32
- blend_src_generic<CallbackSpans>, // ARGB32_Premultiplied
- blend_src_generic<CallbackSpans>, // RGB16
- blend_src_generic<CallbackSpans>, // ARGB8565_Premultiplied
- blend_src_generic<CallbackSpans>, // RGB666
- blend_src_generic<CallbackSpans>, // ARGB6666_Premultiplied
- blend_src_generic<CallbackSpans>, // RGB555
- blend_src_generic<CallbackSpans>, // ARGB8555_Premultiplied
- blend_src_generic<CallbackSpans>, // RGB888
- blend_src_generic<CallbackSpans>, // RGB444
- blend_src_generic<CallbackSpans> // ARGB4444_Premultiplied
- },
- // BilinearTiled
- {
- 0,
- blend_src_generic<CallbackSpans>, // Mono
- blend_src_generic<CallbackSpans>, // MonoLsb
- blend_src_generic<CallbackSpans>, // Indexed8
- blend_src_generic<CallbackSpans>, // RGB32
- blend_src_generic<CallbackSpans>, // ARGB32
- blend_src_generic<CallbackSpans>, // ARGB32_Premultiplied
- blend_src_generic<CallbackSpans>, // RGB16
- blend_src_generic<CallbackSpans>, // ARGB8565_Premultiplied
- blend_src_generic<CallbackSpans>, // RGB666
- blend_src_generic<CallbackSpans>, // ARGB6666_Premultiplied
- blend_src_generic<CallbackSpans>, // RGB555
- blend_src_generic<CallbackSpans>, // ARGB8555_Premultiplied
- blend_src_generic<CallbackSpans>, // RGB888
- blend_src_generic<CallbackSpans>, // RGB444
- blend_src_generic<CallbackSpans> // ARGB4444_Premultiplied
- }
-};
-#endif // QT_NO_RASTERCALLBACKS
-
void qBlendTexture(int count, const QSpan *spans, void *userData)
{
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
@@ -6832,15 +6337,6 @@ void qBlendTexture(int count, const QSpan *spans, void *userData)
proc(count, spans, userData);
}
-#if defined (Q_WS_QWS) && !defined(QT_NO_RASTERCALLBACKS)
-void qBlendTextureCallback(int count, const QSpan *spans, void *userData)
-{
- QSpanData *data = reinterpret_cast<QSpanData *>(userData);
- ProcessSpans proc = processTextureSpansCallback[getBlendType(data)][data->rasterBuffer->format];
- proc(count, spans, userData);
-}
-#endif // QT_NO_RASTERCALLBACKS
-
template <class DST>
inline void qt_bitmapblit_template(QRasterBuffer *rasterBuffer,
int x, int y, quint32 color,
@@ -7490,106 +6986,6 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
}
};
-#if defined (Q_WS_QWS) && !defined(QT_NO_RASTERCALLBACKS)
-DrawHelper qDrawHelperCallback[QImage::NImageFormats] =
-{
- // Format_Invalid,
- { 0, 0, 0, 0, 0, 0 },
- // Format_Mono,
- {
- blend_color_generic_callback,
- blend_src_generic<CallbackSpans>,
- 0, 0, 0, 0
- },
- // Format_MonoLSB,
- {
- blend_color_generic_callback,
- blend_src_generic<CallbackSpans>,
- 0, 0, 0, 0
- },
- // Format_Indexed8,
- {
- blend_color_generic_callback,
- blend_src_generic<CallbackSpans>,
- 0, 0, 0, 0
- },
- // Format_RGB32,
- {
- blend_color_generic_callback,
- blend_src_generic<CallbackSpans>,
- 0, 0, 0, 0
- },
- // Format_ARGB32,
- {
- blend_color_generic_callback,
- blend_src_generic<CallbackSpans>,
- 0, 0, 0, 0
- },
- // Format_ARGB32_Premultiplied
- {
- blend_color_generic_callback,
- blend_src_generic<CallbackSpans>,
- 0, 0, 0, 0
- },
- // Format_RGB16
- {
- blend_color_generic_callback,
- blend_src_generic<CallbackSpans>,
- 0, 0, 0, 0
- },
- // Format_ARGB8565_Premultiplied
- {
- blend_color_generic_callback,
- blend_src_generic<CallbackSpans>,
- 0, 0, 0, 0
- },
- // Format_RGB666
- {
- blend_color_generic_callback,
- blend_src_generic<CallbackSpans>,
- 0, 0, 0, 0
- },
- // Format_ARGB6666_Premultiplied
- {
- blend_color_generic_callback,
- blend_src_generic<CallbackSpans>,
- 0, 0, 0, 0
- },
- // Format_RGB555
- {
- blend_color_generic_callback,
- blend_src_generic<CallbackSpans>,
- 0, 0, 0, 0
- },
- // Format_ARGB8555_Premultiplied
- {
- blend_color_generic_callback,
- blend_src_generic<CallbackSpans>,
- 0, 0, 0, 0
- },
- // Format_RGB888
- {
- blend_color_generic_callback,
- blend_src_generic<CallbackSpans>,
- 0, 0, 0, 0
- },
- // Format_RGB444
- {
- blend_color_generic_callback,
- blend_src_generic<CallbackSpans>,
- 0, 0, 0, 0
- },
- // Format_ARGB4444_Premultiplied
- {
- blend_color_generic_callback,
- blend_src_generic<CallbackSpans>,
- 0, 0, 0, 0
- }
-};
-#endif
-
-
-
#if defined(Q_CC_MSVC) && !defined(_MIPS_)
template <class DST, class SRC>
inline void qt_memfill_template(DST *dest, SRC color, int count)
@@ -7889,64 +7285,4 @@ static void qt_memfill16_setup(quint16 *dest, quint16 value, int count)
qt_memfill16(dest, value, count);
}
-#ifdef QT_QWS_DEPTH_GENERIC
-
-int qrgb::bpp = 0;
-int qrgb::len_red = 0;
-int qrgb::len_green = 0;
-int qrgb::len_blue = 0;
-int qrgb::len_alpha = 0;
-int qrgb::off_red = 0;
-int qrgb::off_green = 0;
-int qrgb::off_blue = 0;
-int qrgb::off_alpha = 0;
-
-template <typename SRC>
-Q_STATIC_TEMPLATE_FUNCTION inline void qt_rectconvert_rgb(qrgb *dest, const SRC *src,
- int x, int y, int width, int height,
- int dstStride, int srcStride)
-{
- quint8 *dest8 = reinterpret_cast<quint8*>(dest)
- + y * dstStride + x * qrgb::bpp;
-
- srcStride = srcStride / sizeof(SRC) - width;
- dstStride -= (width * qrgb::bpp);
-
- for (int j = 0; j < height; ++j) {
- for (int i = 0; i < width; ++i) {
- const quint32 v = qt_convertToRgb<SRC>(*src++);
-#if Q_BYTE_ORDER == Q_BIG_ENDIAN
- for (int j = qrgb::bpp - 1; j >= 0; --j)
- *dest8++ = (v >> (8 * j)) & 0xff;
-#else
- for (int j = 0; j < qrgb::bpp; ++j)
- *dest8++ = (v >> (8 * j)) & 0xff;
-#endif
- }
-
- dest8 += dstStride;
- src += srcStride;
- }
-}
-
-template <>
-void qt_rectconvert(qrgb *dest, const quint32 *src,
- int x, int y, int width, int height,
- int dstStride, int srcStride)
-{
- qt_rectconvert_rgb<quint32>(dest, src, x, y, width, height,
- dstStride, srcStride);
-}
-
-template <>
-void qt_rectconvert(qrgb *dest, const quint16 *src,
- int x, int y, int width, int height,
- int dstStride, int srcStride)
-{
- qt_rectconvert_rgb<quint16>(dest, src, x, y, width, height,
- dstStride, srcStride);
-}
-
-#endif // QT_QWS_DEPTH_GENERIC
-
QT_END_NAMESPACE
diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h
index 0766f2e96b..3d83ba8587 100644
--- a/src/gui/painting/qdrawhelper_p.h
+++ b/src/gui/painting/qdrawhelper_p.h
@@ -65,10 +65,6 @@
#include <private/qsimd_p.h>
#include <private/qmath_p.h>
-#ifdef Q_WS_QWS
-#include "QtGui/qscreen_qws.h"
-#endif
-
QT_BEGIN_NAMESPACE
#if defined(Q_CC_MSVC) && _MSCVER <= 1300 && !defined(Q_CC_INTEL)
@@ -171,10 +167,6 @@ extern MemRotateFunc qMemRotateFunctions[QImage::NImageFormats][3];
extern DrawHelper qDrawHelper[QImage::NImageFormats];
void qBlendTexture(int count, const QSpan *spans, void *userData);
-#if defined(Q_WS_QWS) && !defined(QT_NO_RASTERCALLBACKS)
-extern DrawHelper qDrawHelperCallback[QImage::NImageFormats];
-void qBlendTextureCallback(int count, const QSpan *spans, void *userData);
-#endif
typedef void (QT_FASTCALL *CompositionFunction)(uint *dest, const uint *src, int length, uint const_alpha);
typedef void (QT_FASTCALL *CompositionFunctionSolid)(uint *dest, int length, uint color, uint const_alpha);
@@ -271,13 +263,8 @@ struct QGradientData
QConicalGradientData conical;
};
-#ifdef Q_WS_QWS
-#define GRADIENT_STOPTABLE_SIZE 256
-#define GRADIENT_STOPTABLE_SIZE_SHIFT 8
-#else
#define GRADIENT_STOPTABLE_SIZE 1024
#define GRADIENT_STOPTABLE_SIZE_SHIFT 10
-#endif
uint* colorTable; //[GRADIENT_STOPTABLE_SIZE];
@@ -314,9 +301,6 @@ struct QSpanData
~QSpanData() { delete tempImage; }
QRasterBuffer *rasterBuffer;
-#ifdef Q_WS_QWS
- QRasterPaintEngine *rasterEngine;
-#endif
ProcessSpans blend;
ProcessSpans unclipped_blend;
BitmapBlitFunc bitmapBlit;
@@ -1492,37 +1476,6 @@ inline quint32 qt_colorConvert(qrgb888 color, quint32 dummy)
return quint32(color);
}
-#ifdef QT_QWS_DEPTH_8
-template <>
-inline quint8 qt_colorConvert(quint32 color, quint8 dummy)
-{
- Q_UNUSED(dummy);
-
- uchar r = ((qRed(color) & 0xf8) + 0x19) / 0x33;
- uchar g = ((qGreen(color) &0xf8) + 0x19) / 0x33;
- uchar b = ((qBlue(color) &0xf8) + 0x19) / 0x33;
-
- return r*6*6 + g*6 + b;
-}
-
-template <>
-inline quint8 qt_colorConvert(quint16 color, quint8 dummy)
-{
- Q_UNUSED(dummy);
-
- uchar r = (color & 0xf800) >> (11-3);
- uchar g = (color & 0x07c0) >> (6-3);
- uchar b = (color & 0x001f) << 3;
-
- uchar tr = (r + 0x19) / 0x33;
- uchar tg = (g + 0x19) / 0x33;
- uchar tb = (b + 0x19) / 0x33;
-
- return tr*6*6 + tg*6 + tb;
-}
-
-#endif // QT_QWS_DEPTH_8
-
// hw: endianess??
class quint24
{
@@ -1759,84 +1712,6 @@ qrgb444 qrgb444::byte_mul(quint8 a) const
return result;
}
-#ifdef QT_QWS_DEPTH_GENERIC
-
-struct qrgb
-{
-public:
- static int bpp;
- static int len_red;
- static int len_green;
- static int len_blue;
- static int len_alpha;
- static int off_red;
- static int off_green;
- static int off_blue;
- static int off_alpha;
-} Q_PACKED;
-
-template <typename SRC>
-Q_STATIC_TEMPLATE_FUNCTION inline quint32 qt_convertToRgb(SRC color);
-
-template <>
-inline quint32 qt_convertToRgb(quint32 color)
-{
- const int r = qRed(color) >> (8 - qrgb::len_red);
- const int g = qGreen(color) >> (8 - qrgb::len_green);
- const int b = qBlue(color) >> (8 - qrgb::len_blue);
- const int a = qAlpha(color) >> (8 - qrgb::len_alpha);
- const quint32 v = (r << qrgb::off_red)
- | (g << qrgb::off_green)
- | (b << qrgb::off_blue)
- | (a << qrgb::off_alpha);
-
- return v;
-}
-
-template <>
-inline quint32 qt_convertToRgb(quint16 color)
-{
- return qt_convertToRgb(qt_colorConvert<quint32, quint16>(color, 0));
-}
-
-class qrgb_generic16
-{
-public:
- inline qrgb_generic16(quint32 color)
- {
- const int r = qRed(color) >> (8 - qrgb::len_red);
- const int g = qGreen(color) >> (8 - qrgb::len_green);
- const int b = qBlue(color) >> (8 - qrgb::len_blue);
- const int a = qAlpha(color) >> (8 - qrgb::len_alpha);
- data = (r << qrgb::off_red)
- | (g << qrgb::off_green)
- | (b << qrgb::off_blue)
- | (a << qrgb::off_alpha);
- }
-
- inline operator quint16 () { return data; }
- inline quint32 operator<<(int shift) const { return data << shift; }
-
-private:
- quint16 data;
-} Q_PACKED;
-
-template <>
-inline qrgb_generic16 qt_colorConvert(quint32 color, qrgb_generic16 dummy)
-{
- Q_UNUSED(dummy);
- return qrgb_generic16(color);
-}
-
-template <>
-inline qrgb_generic16 qt_colorConvert(quint16 color, qrgb_generic16 dummy)
-{
- Q_UNUSED(dummy);
- return qrgb_generic16(qt_colorConvert<quint32, quint16>(color, 0));
-}
-
-#endif // QT_QWS_DEPTH_GENERIC
-
template <class T>
void qt_memfill(T *dest, T value, int count);
@@ -2044,16 +1919,6 @@ QT_RECTCONVERT_TRIVIAL_IMPL(qargb4444)
QT_RECTCONVERT_TRIVIAL_IMPL(qrgb444)
#undef QT_RECTCONVERT_TRIVIAL_IMPL
-#ifdef QT_QWS_DEPTH_GENERIC
-template <> void qt_rectconvert(qrgb *dest, const quint32 *src,
- int x, int y, int width, int height,
- int dstStride, int srcStride);
-
-template <> void qt_rectconvert(qrgb *dest, const quint16 *src,
- int x, int y, int width, int height,
- int dstStride, int srcStride);
-#endif // QT_QWS_DEPTH_GENERIC
-
#define QT_MEMFILL_UINT(dest, length, color) \
qt_memfill<quint32>(dest, color, length);
@@ -2116,16 +1981,6 @@ inline ushort qConvertRgb32To16(uint c)
| (((c) >> 8) & 0xf800);
}
-#if defined(Q_WS_QWS) || (QT_VERSION >= 0x040400)
-inline quint32 qConvertRgb32To16x2(quint64 c)
-{
- c = (((c) >> 3) & Q_UINT64_C(0x001f0000001f))
- | (((c) >> 5) & Q_UINT64_C(0x07e0000007e0))
- | (((c) >> 8) & Q_UINT64_C(0xf8000000f800));
- return c | (c >> 16);
-}
-#endif
-
inline QRgb qConvertRgb16To32(uint c)
{
return 0xff000000
diff --git a/src/gui/painting/qdrawutil.cpp b/src/gui/painting/qdrawutil.cpp
deleted file mode 100644
index 98294cb62d..0000000000
--- a/src/gui/painting/qdrawutil.cpp
+++ /dev/null
@@ -1,1360 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qdrawutil.h"
-#include "qbitmap.h"
-#include "qpixmapcache.h"
-#include "qapplication.h"
-#include "qpainter.h"
-#include "qpalette.h"
-#include <private/qpaintengineex_p.h>
-#include <qvarlengtharray.h>
-#include <qmath.h>
-#include <private/qstylehelper_p.h>
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \headerfile <qdrawutil.h>
- \title Drawing Utility Functions
-
- \sa QPainter
-*/
-
-/*!
- \fn void qDrawShadeLine(QPainter *painter, int x1, int y1, int x2, int y2,
- const QPalette &palette, bool sunken,
- int lineWidth, int midLineWidth)
- \relates <qdrawutil.h>
-
- Draws a horizontal (\a y1 == \a y2) or vertical (\a x1 == \a x2)
- shaded line using the given \a painter. Note that nothing is
- drawn if \a y1 != \a y2 and \a x1 != \a x2 (i.e. the line is
- neither horizontal nor vertical).
-
- The provided \a palette specifies the shading colors (\l
- {QPalette::light()}{light}, \l {QPalette::dark()}{dark} and \l
- {QPalette::mid()}{middle} colors). The given \a lineWidth
- specifies the line width for each of the lines; it is not the
- total line width. The given \a midLineWidth specifies the width of
- a middle line drawn in the QPalette::mid() color.
-
- The line appears sunken if \a sunken is true, otherwise raised.
-
- \warning This function does not look at QWidget::style() or
- QApplication::style(). Use the drawing functions in QStyle to
- make widgets that follow the current GUI style.
-
-
- Alternatively you can use a QFrame widget and apply the
- QFrame::setFrameStyle() function to display a shaded line:
-
- \snippet doc/src/snippets/code/src_gui_painting_qdrawutil.cpp 0
-
- \sa qDrawShadeRect(), qDrawShadePanel(), QStyle
-*/
-
-void qDrawShadeLine(QPainter *p, int x1, int y1, int x2, int y2,
- const QPalette &pal, bool sunken,
- int lineWidth, int midLineWidth)
-{
- if (!(p && lineWidth >= 0 && midLineWidth >= 0)) {
- qWarning("qDrawShadeLine: Invalid parameters");
- return;
- }
- int tlw = lineWidth*2 + midLineWidth; // total line width
- QPen oldPen = p->pen(); // save pen
- if (sunken)
- p->setPen(pal.color(QPalette::Dark));
- else
- p->setPen(pal.light().color());
- QPolygon a;
- int i;
- if (y1 == y2) { // horizontal line
- int y = y1 - tlw/2;
- if (x1 > x2) { // swap x1 and x2
- int t = x1;
- x1 = x2;
- x2 = t;
- }
- x2--;
- for (i=0; i<lineWidth; i++) { // draw top shadow
- a.setPoints(3, x1+i, y+tlw-1-i,
- x1+i, y+i,
- x2-i, y+i);
- p->drawPolyline(a);
- }
- if (midLineWidth > 0) {
- p->setPen(pal.mid().color());
- for (i=0; i<midLineWidth; i++) // draw lines in the middle
- p->drawLine(x1+lineWidth, y+lineWidth+i,
- x2-lineWidth, y+lineWidth+i);
- }
- if (sunken)
- p->setPen(pal.light().color());
- else
- p->setPen(pal.dark().color());
- for (i=0; i<lineWidth; i++) { // draw bottom shadow
- a.setPoints(3, x1+i, y+tlw-i-1,
- x2-i, y+tlw-i-1,
- x2-i, y+i+1);
- p->drawPolyline(a);
- }
- }
- else if (x1 == x2) { // vertical line
- int x = x1 - tlw/2;
- if (y1 > y2) { // swap y1 and y2
- int t = y1;
- y1 = y2;
- y2 = t;
- }
- y2--;
- for (i=0; i<lineWidth; i++) { // draw left shadow
- a.setPoints(3, x+i, y2,
- x+i, y1+i,
- x+tlw-1, y1+i);
- p->drawPolyline(a);
- }
- if (midLineWidth > 0) {
- p->setPen(pal.mid().color());
- for (i=0; i<midLineWidth; i++) // draw lines in the middle
- p->drawLine(x+lineWidth+i, y1+lineWidth, x+lineWidth+i, y2);
- }
- if (sunken)
- p->setPen(pal.light().color());
- else
- p->setPen(pal.dark().color());
- for (i=0; i<lineWidth; i++) { // draw right shadow
- a.setPoints(3, x+lineWidth, y2-i,
- x+tlw-i-1, y2-i,
- x+tlw-i-1, y1+lineWidth);
- p->drawPolyline(a);
- }
- }
- p->setPen(oldPen);
-}
-
-/*!
- \fn void qDrawShadeRect(QPainter *painter, int x, int y, int width, int height,
- const QPalette &palette, bool sunken,
- int lineWidth, int midLineWidth,
- const QBrush *fill)
- \relates <qdrawutil.h>
-
- Draws the shaded rectangle beginning at (\a x, \a y) with the
- given \a width and \a height using the provided \a painter.
-
- The provide \a palette specifies the shading colors (\l
- {QPalette::light()}{light}, \l {QPalette::dark()}{dark} and \l
- {QPalette::mid()}{middle} colors. The given \a lineWidth
- specifies the line width for each of the lines; it is not the
- total line width. The \a midLineWidth specifies the width of a
- middle line drawn in the QPalette::mid() color. The rectangle's
- interior is filled with the \a fill brush unless \a fill is 0.
-
- The rectangle appears sunken if \a sunken is true, otherwise
- raised.
-
- \warning This function does not look at QWidget::style() or
- QApplication::style(). Use the drawing functions in QStyle to make
- widgets that follow the current GUI style.
-
- Alternatively you can use a QFrame widget and apply the
- QFrame::setFrameStyle() function to display a shaded rectangle:
-
- \snippet doc/src/snippets/code/src_gui_painting_qdrawutil.cpp 1
-
- \sa qDrawShadeLine(), qDrawShadePanel(), qDrawPlainRect(), QStyle
-*/
-
-void qDrawShadeRect(QPainter *p, int x, int y, int w, int h,
- const QPalette &pal, bool sunken,
- int lineWidth, int midLineWidth,
- const QBrush *fill)
-{
- if (w == 0 || h == 0)
- return;
- if (! (w > 0 && h > 0 && lineWidth >= 0 && midLineWidth >= 0)) {
- qWarning("qDrawShadeRect: Invalid parameters");
- return;
- }
- QPen oldPen = p->pen();
- if (sunken)
- p->setPen(pal.dark().color());
- else
- p->setPen(pal.light().color());
- int x1=x, y1=y, x2=x+w-1, y2=y+h-1;
-
- if (lineWidth == 1 && midLineWidth == 0) {// standard shade rectangle
- p->drawRect(x1, y1, w-2, h-2);
- if (sunken)
- p->setPen(pal.light().color());
- else
- p->setPen(pal.dark().color());
- QLineF lines[4] = { QLineF(x1+1, y1+1, x2-2, y1+1),
- QLineF(x1+1, y1+2, x1+1, y2-2),
- QLineF(x1, y2, x2, y2),
- QLineF(x2,y1, x2,y2-1) };
- p->drawLines(lines, 4); // draw bottom/right lines
- } else { // more complicated
- int m = lineWidth+midLineWidth;
- int i, j=0, k=m;
- for (i=0; i<lineWidth; i++) { // draw top shadow
- QLineF lines[4] = { QLineF(x1+i, y2-i, x1+i, y1+i),
- QLineF(x1+i, y1+i, x2-i, y1+i),
- QLineF(x1+k, y2-k, x2-k, y2-k),
- QLineF(x2-k, y2-k, x2-k, y1+k) };
- p->drawLines(lines, 4);
- k++;
- }
- p->setPen(pal.mid().color());
- j = lineWidth*2;
- for (i=0; i<midLineWidth; i++) { // draw lines in the middle
- p->drawRect(x1+lineWidth+i, y1+lineWidth+i, w-j-1, h-j-1);
- j += 2;
- }
- if (sunken)
- p->setPen(pal.light().color());
- else
- p->setPen(pal.dark().color());
- k = m;
- for (i=0; i<lineWidth; i++) { // draw bottom shadow
- QLineF lines[4] = { QLineF(x1+1+i, y2-i, x2-i, y2-i),
- QLineF(x2-i, y2-i, x2-i, y1+i+1),
- QLineF(x1+k, y2-k, x1+k, y1+k),
- QLineF(x1+k, y1+k, x2-k, y1+k) };
- p->drawLines(lines, 4);
- k++;
- }
- }
- if (fill) {
- QBrush oldBrush = p->brush();
- int tlw = lineWidth + midLineWidth;
- p->setPen(Qt::NoPen);
- p->setBrush(*fill);
- p->drawRect(x+tlw, y+tlw, w-2*tlw, h-2*tlw);
- p->setBrush(oldBrush);
- }
- p->setPen(oldPen); // restore pen
-}
-
-
-/*!
- \fn void qDrawShadePanel(QPainter *painter, int x, int y, int width, int height,
- const QPalette &palette, bool sunken,
- int lineWidth, const QBrush *fill)
- \relates <qdrawutil.h>
-
- Draws the shaded panel beginning at (\a x, \a y) with the given \a
- width and \a height using the provided \a painter and the given \a
- lineWidth.
-
- The given \a palette specifies the shading colors (\l
- {QPalette::light()}{light}, \l {QPalette::dark()}{dark} and \l
- {QPalette::mid()}{middle} colors). The panel's interior is filled
- with the \a fill brush unless \a fill is 0.
-
- The panel appears sunken if \a sunken is true, otherwise raised.
-
- \warning This function does not look at QWidget::style() or
- QApplication::style(). Use the drawing functions in QStyle to make
- widgets that follow the current GUI style.
-
- Alternatively you can use a QFrame widget and apply the
- QFrame::setFrameStyle() function to display a shaded panel:
-
- \snippet doc/src/snippets/code/src_gui_painting_qdrawutil.cpp 2
-
- \sa qDrawWinPanel(), qDrawShadeLine(), qDrawShadeRect(), QStyle
-*/
-
-void qDrawShadePanel(QPainter *p, int x, int y, int w, int h,
- const QPalette &pal, bool sunken,
- int lineWidth, const QBrush *fill)
-{
- if (w == 0 || h == 0)
- return;
- if (!(w > 0 && h > 0 && lineWidth >= 0)) {
- qWarning("qDrawShadePanel: Invalid parameters");
- }
- QColor shade = pal.dark().color();
- QColor light = pal.light().color();
- if (fill) {
- if (fill->color() == shade)
- shade = pal.shadow().color();
- if (fill->color() == light)
- light = pal.midlight().color();
- }
- QPen oldPen = p->pen(); // save pen
- QVector<QLineF> lines;
- lines.reserve(2*lineWidth);
-
- if (sunken)
- p->setPen(shade);
- else
- p->setPen(light);
- int x1, y1, x2, y2;
- int i;
- x1 = x;
- y1 = y2 = y;
- x2 = x+w-2;
- for (i=0; i<lineWidth; i++) { // top shadow
- lines << QLineF(x1, y1++, x2--, y2++);
- }
- x2 = x1;
- y1 = y+h-2;
- for (i=0; i<lineWidth; i++) { // left shado
- lines << QLineF(x1++, y1, x2++, y2--);
- }
- p->drawLines(lines);
- lines.clear();
- if (sunken)
- p->setPen(light);
- else
- p->setPen(shade);
- x1 = x;
- y1 = y2 = y+h-1;
- x2 = x+w-1;
- for (i=0; i<lineWidth; i++) { // bottom shadow
- lines << QLineF(x1++, y1--, x2, y2--);
- }
- x1 = x2;
- y1 = y;
- y2 = y+h-lineWidth-1;
- for (i=0; i<lineWidth; i++) { // right shadow
- lines << QLineF(x1--, y1++, x2--, y2);
- }
- p->drawLines(lines);
- if (fill) // fill with fill color
- p->fillRect(x+lineWidth, y+lineWidth, w-lineWidth*2, h-lineWidth*2, *fill);
- p->setPen(oldPen); // restore pen
-}
-
-
-/*!
- \internal
- This function draws a rectangle with two pixel line width.
- It is called from qDrawWinButton() and qDrawWinPanel().
-
- c1..c4 and fill are used:
-
- 1 1 1 1 1 2
- 1 3 3 3 4 2
- 1 3 F F 4 2
- 1 3 F F 4 2
- 1 4 4 4 4 2
- 2 2 2 2 2 2
-*/
-
-static void qDrawWinShades(QPainter *p,
- int x, int y, int w, int h,
- const QColor &c1, const QColor &c2,
- const QColor &c3, const QColor &c4,
- const QBrush *fill)
-{
- if (w < 2 || h < 2) // can't do anything with that
- return;
- QPen oldPen = p->pen();
- QPoint a[3] = { QPoint(x, y+h-2), QPoint(x, y), QPoint(x+w-2, y) };
- p->setPen(c1);
- p->drawPolyline(a, 3);
- QPoint b[3] = { QPoint(x, y+h-1), QPoint(x+w-1, y+h-1), QPoint(x+w-1, y) };
- p->setPen(c2);
- p->drawPolyline(b, 3);
- if (w > 4 && h > 4) {
- QPoint c[3] = { QPoint(x+1, y+h-3), QPoint(x+1, y+1), QPoint(x+w-3, y+1) };
- p->setPen(c3);
- p->drawPolyline(c, 3);
- QPoint d[3] = { QPoint(x+1, y+h-2), QPoint(x+w-2, y+h-2), QPoint(x+w-2, y+1) };
- p->setPen(c4);
- p->drawPolyline(d, 3);
- if (fill)
- p->fillRect(QRect(x+2, y+2, w-4, h-4), *fill);
- }
- p->setPen(oldPen);
-}
-
-
-/*!
- \fn void qDrawWinButton(QPainter *painter, int x, int y, int width, int height,
- const QPalette &palette, bool sunken,
- const QBrush *fill)
- \relates <qdrawutil.h>
-
- Draws the Windows-style button specified by the given point (\a x,
- \a y}, \a width and \a height using the provided \a painter with a
- line width of 2 pixels. The button's interior is filled with the
- \a{fill} brush unless \a fill is 0.
-
- The given \a palette specifies the shading colors (\l
- {QPalette::light()}{light}, \l {QPalette::dark()}{dark} and \l
- {QPalette::mid()}{middle} colors).
-
- The button appears sunken if \a sunken is true, otherwise raised.
-
- \warning This function does not look at QWidget::style() or
- QApplication::style()-> Use the drawing functions in QStyle to make
- widgets that follow the current GUI style.
-
- \sa qDrawWinPanel(), QStyle
-*/
-
-void qDrawWinButton(QPainter *p, int x, int y, int w, int h,
- const QPalette &pal, bool sunken,
- const QBrush *fill)
-{
- if (sunken)
- qDrawWinShades(p, x, y, w, h,
- pal.shadow().color(), pal.light().color(), pal.dark().color(),
- pal.button().color(), fill);
- else
- qDrawWinShades(p, x, y, w, h,
- pal.light().color(), pal.shadow().color(), pal.button().color(),
- pal.dark().color(), fill);
-}
-
-/*!
- \fn void qDrawWinPanel(QPainter *painter, int x, int y, int width, int height,
- const QPalette &palette, bool sunken,
- const QBrush *fill)
- \relates <qdrawutil.h>
-
- Draws the Windows-style panel specified by the given point(\a x,
- \a y), \a width and \a height using the provided \a painter with a
- line width of 2 pixels. The button's interior is filled with the
- \a fill brush unless \a fill is 0.
-
- The given \a palette specifies the shading colors. The panel
- appears sunken if \a sunken is true, otherwise raised.
-
- \warning This function does not look at QWidget::style() or
- QApplication::style(). Use the drawing functions in QStyle to make
- widgets that follow the current GUI style.
-
- Alternatively you can use a QFrame widget and apply the
- QFrame::setFrameStyle() function to display a shaded panel:
-
- \snippet doc/src/snippets/code/src_gui_painting_qdrawutil.cpp 3
-
- \sa qDrawShadePanel(), qDrawWinButton(), QStyle
-*/
-
-void qDrawWinPanel(QPainter *p, int x, int y, int w, int h,
- const QPalette &pal, bool sunken,
- const QBrush *fill)
-{
- if (sunken)
- qDrawWinShades(p, x, y, w, h,
- pal.dark().color(), pal.light().color(), pal.shadow().color(),
- pal.midlight().color(), fill);
- else
- qDrawWinShades(p, x, y, w, h,
- pal.light().color(), pal.shadow().color(), pal.midlight().color(),
- pal.dark().color(), fill);
-}
-
-/*!
- \fn void qDrawPlainRect(QPainter *painter, int x, int y, int width, int height, const QColor &lineColor,
- int lineWidth, const QBrush *fill)
- \relates <qdrawutil.h>
-
- Draws the plain rectangle beginning at (\a x, \a y) with the given
- \a width and \a height, using the specified \a painter, \a lineColor
- and \a lineWidth. The rectangle's interior is filled with the \a
- fill brush unless \a fill is 0.
-
- \warning This function does not look at QWidget::style() or
- QApplication::style(). Use the drawing functions in QStyle to make
- widgets that follow the current GUI style.
-
- Alternatively you can use a QFrame widget and apply the
- QFrame::setFrameStyle() function to display a plain rectangle:
-
- \snippet doc/src/snippets/code/src_gui_painting_qdrawutil.cpp 4
-
- \sa qDrawShadeRect(), QStyle
-*/
-
-void qDrawPlainRect(QPainter *p, int x, int y, int w, int h, const QColor &c,
- int lineWidth, const QBrush *fill)
-{
- if (w == 0 || h == 0)
- return;
- if (!(w > 0 && h > 0 && lineWidth >= 0)) {
- qWarning("qDrawPlainRect: Invalid parameters");
- }
- QPen oldPen = p->pen();
- QBrush oldBrush = p->brush();
- p->setPen(c);
- p->setBrush(Qt::NoBrush);
- for (int i=0; i<lineWidth; i++)
- p->drawRect(x+i, y+i, w-i*2 - 1, h-i*2 - 1);
- if (fill) { // fill with fill color
- p->setPen(Qt::NoPen);
- p->setBrush(*fill);
- p->drawRect(x+lineWidth, y+lineWidth, w-lineWidth*2, h-lineWidth*2);
- }
- p->setPen(oldPen);
- p->setBrush(oldBrush);
-}
-
-/*****************************************************************************
- Overloaded functions.
- *****************************************************************************/
-
-/*!
- \fn void qDrawShadeLine(QPainter *painter, const QPoint &p1, const QPoint &p2,
- const QPalette &palette, bool sunken, int lineWidth, int midLineWidth)
- \relates <qdrawutil.h>
- \overload
-
- Draws a horizontal or vertical shaded line between \a p1 and \a p2
- using the given \a painter. Note that nothing is drawn if the line
- between the points would be neither horizontal nor vertical.
-
- The provided \a palette specifies the shading colors (\l
- {QPalette::light()}{light}, \l {QPalette::dark()}{dark} and \l
- {QPalette::mid()}{middle} colors). The given \a lineWidth
- specifies the line width for each of the lines; it is not the
- total line width. The given \a midLineWidth specifies the width of
- a middle line drawn in the QPalette::mid() color.
-
- The line appears sunken if \a sunken is true, otherwise raised.
-
- \warning This function does not look at QWidget::style() or
- QApplication::style(). Use the drawing functions in QStyle to
- make widgets that follow the current GUI style.
-
-
- Alternatively you can use a QFrame widget and apply the
- QFrame::setFrameStyle() function to display a shaded line:
-
- \snippet doc/src/snippets/code/src_gui_painting_qdrawutil.cpp 5
-
- \sa qDrawShadeRect(), qDrawShadePanel(), QStyle
-*/
-
-void qDrawShadeLine(QPainter *p, const QPoint &p1, const QPoint &p2,
- const QPalette &pal, bool sunken,
- int lineWidth, int midLineWidth)
-{
- qDrawShadeLine(p, p1.x(), p1.y(), p2.x(), p2.y(), pal, sunken,
- lineWidth, midLineWidth);
-}
-
-/*!
- \fn void qDrawShadeRect(QPainter *painter, const QRect &rect, const QPalette &palette,
- bool sunken, int lineWidth, int midLineWidth, const QBrush *fill)
- \relates <qdrawutil.h>
- \overload
-
- Draws the shaded rectangle specified by \a rect using the given \a painter.
-
- The provide \a palette specifies the shading colors (\l
- {QPalette::light()}{light}, \l {QPalette::dark()}{dark} and \l
- {QPalette::mid()}{middle} colors. The given \a lineWidth
- specifies the line width for each of the lines; it is not the
- total line width. The \a midLineWidth specifies the width of a
- middle line drawn in the QPalette::mid() color. The rectangle's
- interior is filled with the \a fill brush unless \a fill is 0.
-
- The rectangle appears sunken if \a sunken is true, otherwise
- raised.
-
- \warning This function does not look at QWidget::style() or
- QApplication::style(). Use the drawing functions in QStyle to make
- widgets that follow the current GUI style.
-
- Alternatively you can use a QFrame widget and apply the
- QFrame::setFrameStyle() function to display a shaded rectangle:
-
- \snippet doc/src/snippets/code/src_gui_painting_qdrawutil.cpp 6
-
- \sa qDrawShadeLine(), qDrawShadePanel(), qDrawPlainRect(), QStyle
-*/
-
-void qDrawShadeRect(QPainter *p, const QRect &r,
- const QPalette &pal, bool sunken,
- int lineWidth, int midLineWidth,
- const QBrush *fill)
-{
- qDrawShadeRect(p, r.x(), r.y(), r.width(), r.height(), pal, sunken,
- lineWidth, midLineWidth, fill);
-}
-
-/*!
- \fn void qDrawShadePanel(QPainter *painter, const QRect &rect, const QPalette &palette,
- bool sunken, int lineWidth, const QBrush *fill)
- \relates <qdrawutil.h>
- \overload
-
- Draws the shaded panel at the rectangle specified by \a rect using the
- given \a painter and the given \a lineWidth.
-
- The given \a palette specifies the shading colors (\l
- {QPalette::light()}{light}, \l {QPalette::dark()}{dark} and \l
- {QPalette::mid()}{middle} colors). The panel's interior is filled
- with the \a fill brush unless \a fill is 0.
-
- The panel appears sunken if \a sunken is true, otherwise raised.
-
- \warning This function does not look at QWidget::style() or
- QApplication::style(). Use the drawing functions in QStyle to make
- widgets that follow the current GUI style.
-
- Alternatively you can use a QFrame widget and apply the
- QFrame::setFrameStyle() function to display a shaded panel:
-
- \snippet doc/src/snippets/code/src_gui_painting_qdrawutil.cpp 7
-
- \sa qDrawWinPanel(), qDrawShadeLine(), qDrawShadeRect(), QStyle
-*/
-
-void qDrawShadePanel(QPainter *p, const QRect &r,
- const QPalette &pal, bool sunken,
- int lineWidth, const QBrush *fill)
-{
- qDrawShadePanel(p, r.x(), r.y(), r.width(), r.height(), pal, sunken,
- lineWidth, fill);
-}
-
-/*!
- \fn void qDrawWinButton(QPainter *painter, const QRect &rect, const QPalette &palette,
- bool sunken, const QBrush *fill)
- \relates <qdrawutil.h>
- \overload
-
- Draws the Windows-style button at the rectangle specified by \a rect using
- the given \a painter with a line width of 2 pixels. The button's interior
- is filled with the \a{fill} brush unless \a fill is 0.
-
- The given \a palette specifies the shading colors (\l
- {QPalette::light()}{light}, \l {QPalette::dark()}{dark} and \l
- {QPalette::mid()}{middle} colors).
-
- The button appears sunken if \a sunken is true, otherwise raised.
-
- \warning This function does not look at QWidget::style() or
- QApplication::style()-> Use the drawing functions in QStyle to make
- widgets that follow the current GUI style.
-
- \sa qDrawWinPanel(), QStyle
-*/
-
-void qDrawWinButton(QPainter *p, const QRect &r,
- const QPalette &pal, bool sunken, const QBrush *fill)
-{
- qDrawWinButton(p, r.x(), r.y(), r.width(), r.height(), pal, sunken, fill);
-}
-
-/*!
- \fn void qDrawWinPanel(QPainter *painter, const QRect &rect, const QPalette &palette,
- bool sunken, const QBrush *fill)
- \overload
-
- Draws the Windows-style panel at the rectangle specified by \a rect using
- the given \a painter with a line width of 2 pixels. The button's interior
- is filled with the \a fill brush unless \a fill is 0.
-
- The given \a palette specifies the shading colors. The panel
- appears sunken if \a sunken is true, otherwise raised.
-
- \warning This function does not look at QWidget::style() or
- QApplication::style(). Use the drawing functions in QStyle to make
- widgets that follow the current GUI style.
-
- Alternatively you can use a QFrame widget and apply the
- QFrame::setFrameStyle() function to display a shaded panel:
-
- \snippet doc/src/snippets/code/src_gui_painting_qdrawutil.cpp 8
-
- \sa qDrawShadePanel(), qDrawWinButton(), QStyle
-*/
-
-void qDrawWinPanel(QPainter *p, const QRect &r,
- const QPalette &pal, bool sunken, const QBrush *fill)
-{
- qDrawWinPanel(p, r.x(), r.y(), r.width(), r.height(), pal, sunken, fill);
-}
-
-/*!
- \fn void qDrawPlainRect(QPainter *painter, const QRect &rect, const QColor &lineColor, int lineWidth, const QBrush *fill)
- \relates <qdrawutil.h>
- \overload
-
- Draws the plain rectangle specified by \a rect using the given \a painter,
- \a lineColor and \a lineWidth. The rectangle's interior is filled with the
- \a fill brush unless \a fill is 0.
-
- \warning This function does not look at QWidget::style() or
- QApplication::style(). Use the drawing functions in QStyle to make
- widgets that follow the current GUI style.
-
- Alternatively you can use a QFrame widget and apply the
- QFrame::setFrameStyle() function to display a plain rectangle:
-
- \snippet doc/src/snippets/code/src_gui_painting_qdrawutil.cpp 9
-
- \sa qDrawShadeRect(), QStyle
-*/
-
-void qDrawPlainRect(QPainter *p, const QRect &r, const QColor &c,
- int lineWidth, const QBrush *fill)
-{
- qDrawPlainRect(p, r.x(), r.y(), r.width(), r.height(), c,
- lineWidth, fill);
-}
-
-#ifdef QT3_SUPPORT
-static void qDrawWinArrow(QPainter *p, Qt::ArrowType type, bool down,
- int x, int y, int w, int h,
- const QPalette &pal, bool enabled)
-{
- QPolygon a; // arrow polygon
- switch (type) {
- case Qt::UpArrow:
- a.setPoints(7, -3,1, 3,1, -2,0, 2,0, -1,-1, 1,-1, 0,-2);
- break;
- case Qt::DownArrow:
- a.setPoints(7, -3,-1, 3,-1, -2,0, 2,0, -1,1, 1,1, 0,2);
- break;
- case Qt::LeftArrow:
- a.setPoints(7, 1,-3, 1,3, 0,-2, 0,2, -1,-1, -1,1, -2,0);
- break;
- case Qt::RightArrow:
- a.setPoints(7, -1,-3, -1,3, 0,-2, 0,2, 1,-1, 1,1, 2,0);
- break;
- default:
- break;
- }
- if (a.isEmpty())
- return;
-
- if (down) {
- x++;
- y++;
- }
-
- QPen savePen = p->pen(); // save current pen
- if (down)
- p->setBrushOrigin(p->brushOrigin() + QPoint(1,1));
- p->fillRect(x, y, w, h, pal.brush(QPalette::Button));
- if (down)
- p->setBrushOrigin(p->brushOrigin() - QPoint(1,1));
- if (enabled) {
- a.translate(x+w/2, y+h/2);
- p->setPen(pal.foreground().color());
- p->drawLine(a.at(0), a.at(1));
- p->drawLine(a.at(2), a.at(2));
- p->drawPoint(a[6]);
- } else {
- a.translate(x+w/2+1, y+h/2+1);
- p->setPen(pal.light().color());
- p->drawLine(a.at(0), a.at(1));
- p->drawLine(a.at(2), a.at(2));
- p->drawPoint(a[6]);
- a.translate(-1, -1);
- p->setPen(pal.mid().color());
- p->drawLine(a.at(0), a.at(1));
- p->drawLine(a.at(2), a.at(2));
- p->drawPoint(a[6]);
- }
- p->setPen(savePen); // restore pen
-}
-#endif // QT3_SUPPORT
-
-#if defined(Q_CC_MSVC)
-#pragma warning(disable: 4244)
-#endif
-
-#ifdef QT3_SUPPORT
-#ifndef QT_NO_STYLE_MOTIF
-// motif arrows look the same whether they are used or not
-// is this correct?
-static void qDrawMotifArrow(QPainter *p, Qt::ArrowType type, bool down,
- int x, int y, int w, int h,
- const QPalette &pal, bool)
-{
- QPolygon bFill; // fill polygon
- QPolygon bTop; // top shadow.
- QPolygon bBot; // bottom shadow.
- QPolygon bLeft; // left shadow.
- QTransform matrix; // xform matrix
- bool vertical = type == Qt::UpArrow || type == Qt::DownArrow;
- bool horizontal = !vertical;
- int dim = w < h ? w : h;
- int colspec = 0x0000; // color specification array
-
- if (dim < 2) // too small arrow
- return;
-
- if (dim > 3) {
- if (dim > 6)
- bFill.resize(dim & 1 ? 3 : 4);
- bTop.resize((dim/2)*2);
- bBot.resize(dim & 1 ? dim + 1 : dim);
- bLeft.resize(dim > 4 ? 4 : 2);
- bLeft.putPoints(0, 2, 0,0, 0,dim-1);
- if (dim > 4)
- bLeft.putPoints(2, 2, 1,2, 1,dim-3);
- bTop.putPoints(0, 4, 1,0, 1,1, 2,1, 3,1);
- bBot.putPoints(0, 4, 1,dim-1, 1,dim-2, 2,dim-2, 3,dim-2);
-
- for(int i=0; i<dim/2-2 ; i++) {
- bTop.putPoints(i*2+4, 2, 2+i*2,2+i, 5+i*2, 2+i);
- bBot.putPoints(i*2+4, 2, 2+i*2,dim-3-i, 5+i*2,dim-3-i);
- }
- if (dim & 1) // odd number size: extra line
- bBot.putPoints(dim-1, 2, dim-3,dim/2, dim-1,dim/2);
- if (dim > 6) { // dim>6: must fill interior
- bFill.putPoints(0, 2, 1,dim-3, 1,2);
- if (dim & 1) // if size is an odd number
- bFill.setPoint(2, dim - 3, dim / 2);
- else
- bFill.putPoints(2, 2, dim-4,dim/2-1, dim-4,dim/2);
- }
- }
- else {
- if (dim == 3) { // 3x3 arrow pattern
- bLeft.setPoints(4, 0,0, 0,2, 1,1, 1,1);
- bTop .setPoints(2, 1,0, 1,0);
- bBot .setPoints(2, 1,2, 2,1);
- }
- else { // 2x2 arrow pattern
- bLeft.setPoints(2, 0,0, 0,1);
- bTop .setPoints(2, 1,0, 1,0);
- bBot .setPoints(2, 1,1, 1,1);
- }
- }
-
- if (type == Qt::UpArrow || type == Qt::LeftArrow) {
- matrix.translate(x, y);
- if (vertical) {
- matrix.translate(0, h - 1);
- matrix.rotate(-90);
- } else {
- matrix.translate(w - 1, h - 1);
- matrix.rotate(180);
- }
- if (down)
- colspec = horizontal ? 0x2334 : 0x2343;
- else
- colspec = horizontal ? 0x1443 : 0x1434;
- }
- else if (type == Qt::DownArrow || type == Qt::RightArrow) {
- matrix.translate(x, y);
- if (vertical) {
- matrix.translate(w-1, 0);
- matrix.rotate(90);
- }
- if (down)
- colspec = horizontal ? 0x2443 : 0x2434;
- else
- colspec = horizontal ? 0x1334 : 0x1343;
- }
-
- const QColor *cols[5];
- cols[0] = 0;
- cols[1] = &pal.button().color();
- cols[2] = &pal.mid().color();
- cols[3] = &pal.light().color();
- cols[4] = &pal.dark().color();
-#define CMID *cols[(colspec>>12) & 0xf]
-#define CLEFT *cols[(colspec>>8) & 0xf]
-#define CTOP *cols[(colspec>>4) & 0xf]
-#define CBOT *cols[colspec & 0xf]
-
- QPen savePen = p->pen(); // save current pen
- QBrush saveBrush = p->brush(); // save current brush
- QTransform wxm = p->transform();
- QPen pen(Qt::NoPen);
- const QBrush &brush = pal.brush(QPalette::Button);
-
- p->setPen(pen);
- p->setBrush(brush);
- p->setTransform(matrix, true); // set transformation matrix
- p->drawPolygon(bFill); // fill arrow
- p->setBrush(Qt::NoBrush); // don't fill
-
- p->setPen(CLEFT);
- p->drawLines(bLeft);
- p->setPen(CTOP);
- p->drawLines(bTop);
- p->setPen(CBOT);
- p->drawLines(bBot);
-
- p->setTransform(wxm);
- p->setBrush(saveBrush); // restore brush
- p->setPen(savePen); // restore pen
-
-#undef CMID
-#undef CLEFT
-#undef CTOP
-#undef CBOT
-}
-#endif // QT_NO_STYLE_MOTIF
-
-QRect qItemRect(QPainter *p, Qt::GUIStyle gs,
- int x, int y, int w, int h,
- int flags,
- bool enabled,
- const QPixmap *pixmap,
- const QString& text, int len)
-{
- QRect result;
-
- if (pixmap) {
- if ((flags & Qt::AlignVCenter) == Qt::AlignVCenter)
- y += h/2 - pixmap->height()/2;
- else if ((flags & Qt::AlignBottom) == Qt::AlignBottom)
- y += h - pixmap->height();
- if ((flags & Qt::AlignRight) == Qt::AlignRight)
- x += w - pixmap->width();
- else if ((flags & Qt::AlignHCenter) == Qt::AlignHCenter)
- x += w/2 - pixmap->width()/2;
- else if ((flags & Qt::AlignLeft) != Qt::AlignLeft && QApplication::isRightToLeft())
- x += w - pixmap->width();
- result = QRect(x, y, pixmap->width(), pixmap->height());
- } else if (!text.isNull() && p) {
- result = p->boundingRect(QRect(x, y, w, h), flags, text.left(len));
- if (gs == Qt::WindowsStyle && !enabled) {
- result.setWidth(result.width()+1);
- result.setHeight(result.height()+1);
- }
- } else {
- result = QRect(x, y, w, h);
- }
-
- return result;
-}
-
-void qDrawArrow(QPainter *p, Qt::ArrowType type, Qt::GUIStyle style, bool down,
- int x, int y, int w, int h,
- const QPalette &pal, bool enabled)
-{
- switch (style) {
- case Qt::WindowsStyle:
- qDrawWinArrow(p, type, down, x, y, w, h, pal, enabled);
- break;
-#ifndef QT_NO_STYLE_MOTIF
- case Qt::MotifStyle:
- qDrawMotifArrow(p, type, down, x, y, w, h, pal, enabled);
- break;
-#endif
- default:
- qWarning("qDrawArrow: Requested unsupported GUI style");
- }
-}
-
-void qDrawItem(QPainter *p, Qt::GUIStyle gs,
- int x, int y, int w, int h,
- int flags,
- const QPalette &pal, bool enabled,
- const QPixmap *pixmap,
- const QString& text, int len , const QColor* penColor)
-{
- p->setPen(penColor?*penColor:pal.foreground().color());
- if (pixmap) {
- QPixmap pm(*pixmap);
- bool clip = (flags & Qt::TextDontClip) == 0;
- if (clip) {
- if (pm.width() < w && pm.height() < h)
- clip = false;
- else
- p->setClipRect(x, y, w, h);
- }
- if ((flags & Qt::AlignVCenter) == Qt::AlignVCenter)
- y += h/2 - pm.height()/2;
- else if ((flags & Qt::AlignBottom) == Qt::AlignBottom)
- y += h - pm.height();
- if ((flags & Qt::AlignRight) == Qt::AlignRight)
- x += w - pm.width();
- else if ((flags & Qt::AlignHCenter) == Qt::AlignHCenter)
- x += w/2 - pm.width()/2;
- else if (((flags & Qt::AlignLeft) != Qt::AlignLeft) && QApplication::isRightToLeft()) // Qt::AlignAuto && rightToLeft
- x += w - pm.width();
-
- if (!enabled) {
- if (pm.hasAlphaChannel()) { // pixmap with a mask
- pm = pm.mask();
- } else if (pm.depth() == 1) { // monochrome pixmap, no mask
- ;
-#ifndef QT_NO_IMAGE_HEURISTIC_MASK
- } else { // color pixmap, no mask
- QString k = QLatin1Literal("$qt-drawitem")
- % HexString<qint64>(pm.cacheKey());
-
- if (!QPixmapCache::find(k, pm)) {
- pm = pm.createHeuristicMask();
- pm.setMask((QBitmap&)pm);
- QPixmapCache::insert(k, pm);
- }
-#endif
- }
- if (gs == Qt::WindowsStyle) {
- p->setPen(pal.light().color());
- p->drawPixmap(x+1, y+1, pm);
- p->setPen(pal.text().color());
- }
- }
- p->drawPixmap(x, y, pm);
- if (clip)
- p->setClipping(false);
- } else if (!text.isNull()) {
- if (gs == Qt::WindowsStyle && !enabled) {
- p->setPen(pal.light().color());
- p->drawText(x+1, y+1, w, h, flags, text.left(len));
- p->setPen(pal.text().color());
- }
- p->drawText(x, y, w, h, flags, text.left(len));
- }
-}
-
-#endif
-
-/*!
- \class QTileRules
- \since 4.6
-
- Holds the rules used to draw a pixmap or image split into nine segments,
- similar to \l{http://www.w3.org/TR/css3-background/}{CSS3 border-images}.
-
- \sa Qt::TileRule, QMargins
-*/
-
-/*! \fn QTileRules::QTileRules(Qt::TileRule horizontalRule, Qt::TileRule verticalRule)
- Constructs a QTileRules with the given \a horizontalRule and
- \a verticalRule.
- */
-
-/*! \fn QTileRules::QTileRules(Qt::TileRule rule)
- Constructs a QTileRules with the given \a rule used for both
- the horizontal rule and the vertical rule.
- */
-
-/*!
- \fn void qDrawBorderPixmap(QPainter *painter, const QRect &target, const QMargins &margins, const QPixmap &pixmap)
- \relates <qdrawutil.h>
- \since 4.6
- \overload
-
- \brief The qDrawBorderPixmap function is for drawing a pixmap into
- the margins of a rectangle.
-
- Draws the given \a pixmap into the given \a target rectangle, using the
- given \a painter. The pixmap will be split into nine segments and drawn
- according to the \a margins structure.
-*/
-
-typedef QVarLengthArray<QPainter::PixmapFragment, 16> QPixmapFragmentsArray;
-
-/*!
- \since 4.6
-
- Draws the indicated \a sourceRect rectangle from the given \a pixmap into
- the given \a targetRect rectangle, using the given \a painter. The pixmap
- will be split into nine segments according to the given \a targetMargins
- and \a sourceMargins structures. Finally, the pixmap will be drawn
- according to the given \a rules.
-
- This function is used to draw a scaled pixmap, similar to
- \l{http://www.w3.org/TR/css3-background/}{CSS3 border-images}
-
- \sa Qt::TileRule, QTileRules, QMargins
-*/
-
-void qDrawBorderPixmap(QPainter *painter, const QRect &targetRect, const QMargins &targetMargins,
- const QPixmap &pixmap, const QRect &sourceRect,const QMargins &sourceMargins,
- const QTileRules &rules, QDrawBorderPixmap::DrawingHints hints)
-{
- QPainter::PixmapFragment d;
- d.opacity = 1.0;
- d.rotation = 0.0;
-
- QPixmapFragmentsArray opaqueData;
- QPixmapFragmentsArray translucentData;
-
- // source center
- const int sourceCenterTop = sourceRect.top() + sourceMargins.top();
- const int sourceCenterLeft = sourceRect.left() + sourceMargins.left();
- const int sourceCenterBottom = sourceRect.bottom() - sourceMargins.bottom() + 1;
- const int sourceCenterRight = sourceRect.right() - sourceMargins.right() + 1;
- const int sourceCenterWidth = sourceCenterRight - sourceCenterLeft;
- const int sourceCenterHeight = sourceCenterBottom - sourceCenterTop;
- // target center
- const int targetCenterTop = targetRect.top() + targetMargins.top();
- const int targetCenterLeft = targetRect.left() + targetMargins.left();
- const int targetCenterBottom = targetRect.bottom() - targetMargins.bottom() + 1;
- const int targetCenterRight = targetRect.right() - targetMargins.right() + 1;
- const int targetCenterWidth = targetCenterRight - targetCenterLeft;
- const int targetCenterHeight = targetCenterBottom - targetCenterTop;
-
- QVarLengthArray<qreal, 16> xTarget; // x-coordinates of target rectangles
- QVarLengthArray<qreal, 16> yTarget; // y-coordinates of target rectangles
-
- int columns = 3;
- int rows = 3;
- if (rules.horizontal != Qt::StretchTile && sourceCenterWidth != 0)
- columns = qMax(3, 2 + qCeil(targetCenterWidth / qreal(sourceCenterWidth)));
- if (rules.vertical != Qt::StretchTile && sourceCenterHeight != 0)
- rows = qMax(3, 2 + qCeil(targetCenterHeight / qreal(sourceCenterHeight)));
-
- xTarget.resize(columns + 1);
- yTarget.resize(rows + 1);
-
- bool oldAA = painter->testRenderHint(QPainter::Antialiasing);
- if (painter->paintEngine()->type() != QPaintEngine::OpenGL
- && painter->paintEngine()->type() != QPaintEngine::OpenGL2
- && oldAA && painter->combinedTransform().type() != QTransform::TxNone) {
- painter->setRenderHint(QPainter::Antialiasing, false);
- }
-
- xTarget[0] = targetRect.left();
- xTarget[1] = targetCenterLeft;
- xTarget[columns - 1] = targetCenterRight;
- xTarget[columns] = targetRect.left() + targetRect.width();
-
- yTarget[0] = targetRect.top();
- yTarget[1] = targetCenterTop;
- yTarget[rows - 1] = targetCenterBottom;
- yTarget[rows] = targetRect.top() + targetRect.height();
-
- qreal dx = targetCenterWidth;
- qreal dy = targetCenterHeight;
-
- switch (rules.horizontal) {
- case Qt::StretchTile:
- dx = targetCenterWidth;
- break;
- case Qt::RepeatTile:
- dx = sourceCenterWidth;
- break;
- case Qt::RoundTile:
- dx = targetCenterWidth / qreal(columns - 2);
- break;
- }
-
- for (int i = 2; i < columns - 1; ++i)
- xTarget[i] = xTarget[i - 1] + dx;
-
- switch (rules.vertical) {
- case Qt::StretchTile:
- dy = targetCenterHeight;
- break;
- case Qt::RepeatTile:
- dy = sourceCenterHeight;
- break;
- case Qt::RoundTile:
- dy = targetCenterHeight / qreal(rows - 2);
- break;
- }
-
- for (int i = 2; i < rows - 1; ++i)
- yTarget[i] = yTarget[i - 1] + dy;
-
- // corners
- if (targetMargins.top() > 0 && targetMargins.left() > 0 && sourceMargins.top() > 0 && sourceMargins.left() > 0) { // top left
- d.x = (0.5 * (xTarget[1] + xTarget[0]));
- d.y = (0.5 * (yTarget[1] + yTarget[0]));
- d.sourceLeft = sourceRect.left();
- d.sourceTop = sourceRect.top();
- d.width = sourceMargins.left();
- d.height = sourceMargins.top();
- d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.width;
- d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.height;
- if (hints & QDrawBorderPixmap::OpaqueTopLeft)
- opaqueData.append(d);
- else
- translucentData.append(d);
- }
- if (targetMargins.top() > 0 && targetMargins.right() > 0 && sourceMargins.top() > 0 && sourceMargins.right() > 0) { // top right
- d.x = (0.5 * (xTarget[columns] + xTarget[columns - 1]));
- d.y = (0.5 * (yTarget[1] + yTarget[0]));
- d.sourceLeft = sourceCenterRight;
- d.sourceTop = sourceRect.top();
- d.width = sourceMargins.right();
- d.height = sourceMargins.top();
- d.scaleX = qreal(xTarget[columns] - xTarget[columns - 1]) / d.width;
- d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.height;
- if (hints & QDrawBorderPixmap::OpaqueTopRight)
- opaqueData.append(d);
- else
- translucentData.append(d);
- }
- if (targetMargins.bottom() > 0 && targetMargins.left() > 0 && sourceMargins.bottom() > 0 && sourceMargins.left() > 0) { // bottom left
- d.x = (0.5 * (xTarget[1] + xTarget[0]));
- d.y =(0.5 * (yTarget[rows] + yTarget[rows - 1]));
- d.sourceLeft = sourceRect.left();
- d.sourceTop = sourceCenterBottom;
- d.width = sourceMargins.left();
- d.height = sourceMargins.bottom();
- d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.width;
- d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.height;
- if (hints & QDrawBorderPixmap::OpaqueBottomLeft)
- opaqueData.append(d);
- else
- translucentData.append(d);
- }
- if (targetMargins.bottom() > 0 && targetMargins.right() > 0 && sourceMargins.bottom() > 0 && sourceMargins.right() > 0) { // bottom right
- d.x = (0.5 * (xTarget[columns] + xTarget[columns - 1]));
- d.y = (0.5 * (yTarget[rows] + yTarget[rows - 1]));
- d.sourceLeft = sourceCenterRight;
- d.sourceTop = sourceCenterBottom;
- d.width = sourceMargins.right();
- d.height = sourceMargins.bottom();
- d.scaleX = qreal(xTarget[columns] - xTarget[columns - 1]) / d.width;
- d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.height;
- if (hints & QDrawBorderPixmap::OpaqueBottomRight)
- opaqueData.append(d);
- else
- translucentData.append(d);
- }
-
- // horizontal edges
- if (targetCenterWidth > 0 && sourceCenterWidth > 0) {
- if (targetMargins.top() > 0 && sourceMargins.top() > 0) { // top
- QPixmapFragmentsArray &data = hints & QDrawBorderPixmap::OpaqueTop ? opaqueData : translucentData;
- d.sourceLeft = sourceCenterLeft;
- d.sourceTop = sourceRect.top();
- d.width = sourceCenterWidth;
- d.height = sourceMargins.top();
- d.y = (0.5 * (yTarget[1] + yTarget[0]));
- d.scaleX = dx / d.width;
- d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.height;
- for (int i = 1; i < columns - 1; ++i) {
- d.x = (0.5 * (xTarget[i + 1] + xTarget[i]));
- data.append(d);
- }
- if (rules.horizontal == Qt::RepeatTile)
- data[data.size() - 1].width = ((xTarget[columns - 1] - xTarget[columns - 2]) / d.scaleX);
- }
- if (targetMargins.bottom() > 0 && sourceMargins.bottom() > 0) { // bottom
- QPixmapFragmentsArray &data = hints & QDrawBorderPixmap::OpaqueBottom ? opaqueData : translucentData;
- d.sourceLeft = sourceCenterLeft;
- d.sourceTop = sourceCenterBottom;
- d.width = sourceCenterWidth;
- d.height = sourceMargins.bottom();
- d.y = (0.5 * (yTarget[rows] + yTarget[rows - 1]));
- d.scaleX = dx / d.width;
- d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.height;
- for (int i = 1; i < columns - 1; ++i) {
- d.x = (0.5 * (xTarget[i + 1] + xTarget[i]));
- data.append(d);
- }
- if (rules.horizontal == Qt::RepeatTile)
- data[data.size() - 1].width = ((xTarget[columns - 1] - xTarget[columns - 2]) / d.scaleX);
- }
- }
-
- // vertical edges
- if (targetCenterHeight > 0 && sourceCenterHeight > 0) {
- if (targetMargins.left() > 0 && sourceMargins.left() > 0) { // left
- QPixmapFragmentsArray &data = hints & QDrawBorderPixmap::OpaqueLeft ? opaqueData : translucentData;
- d.sourceLeft = sourceRect.left();
- d.sourceTop = sourceCenterTop;
- d.width = sourceMargins.left();
- d.height = sourceCenterHeight;
- d.x = (0.5 * (xTarget[1] + xTarget[0]));
- d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.width;
- d.scaleY = dy / d.height;
- for (int i = 1; i < rows - 1; ++i) {
- d.y = (0.5 * (yTarget[i + 1] + yTarget[i]));
- data.append(d);
- }
- if (rules.vertical == Qt::RepeatTile)
- data[data.size() - 1].height = ((yTarget[rows - 1] - yTarget[rows - 2]) / d.scaleY);
- }
- if (targetMargins.right() > 0 && sourceMargins.right() > 0) { // right
- QPixmapFragmentsArray &data = hints & QDrawBorderPixmap::OpaqueRight ? opaqueData : translucentData;
- d.sourceLeft = sourceCenterRight;
- d.sourceTop = sourceCenterTop;
- d.width = sourceMargins.right();
- d.height = sourceCenterHeight;
- d.x = (0.5 * (xTarget[columns] + xTarget[columns - 1]));
- d.scaleX = qreal(xTarget[columns] - xTarget[columns - 1]) / d.width;
- d.scaleY = dy / d.height;
- for (int i = 1; i < rows - 1; ++i) {
- d.y = (0.5 * (yTarget[i + 1] + yTarget[i]));
- data.append(d);
- }
- if (rules.vertical == Qt::RepeatTile)
- data[data.size() - 1].height = ((yTarget[rows - 1] - yTarget[rows - 2]) / d.scaleY);
- }
- }
-
- // center
- if (targetCenterWidth > 0 && targetCenterHeight > 0 && sourceCenterWidth > 0 && sourceCenterHeight > 0) {
- QPixmapFragmentsArray &data = hints & QDrawBorderPixmap::OpaqueCenter ? opaqueData : translucentData;
- d.sourceLeft = sourceCenterLeft;
- d.sourceTop = sourceCenterTop;
- d.width = sourceCenterWidth;
- d.height = sourceCenterHeight;
- d.scaleX = dx / d.width;
- d.scaleY = dy / d.height;
-
- qreal repeatWidth = (xTarget[columns - 1] - xTarget[columns - 2]) / d.scaleX;
- qreal repeatHeight = (yTarget[rows - 1] - yTarget[rows - 2]) / d.scaleY;
-
- for (int j = 1; j < rows - 1; ++j) {
- d.y = (0.5 * (yTarget[j + 1] + yTarget[j]));
- for (int i = 1; i < columns - 1; ++i) {
- d.x = (0.5 * (xTarget[i + 1] + xTarget[i]));
- data.append(d);
- }
- if (rules.horizontal == Qt::RepeatTile)
- data[data.size() - 1].width = repeatWidth;
- }
- if (rules.vertical == Qt::RepeatTile) {
- for (int i = 1; i < columns - 1; ++i)
- data[data.size() - i].height = repeatHeight;
- }
- }
-
- if (opaqueData.size())
- painter->drawPixmapFragments(opaqueData.data(), opaqueData.size(), pixmap, QPainter::OpaqueHint);
- if (translucentData.size())
- painter->drawPixmapFragments(translucentData.data(), translucentData.size(), pixmap);
-
- if (oldAA)
- painter->setRenderHint(QPainter::Antialiasing, true);
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/painting/qdrawutil.h b/src/gui/painting/qdrawutil.h
deleted file mode 100644
index 0f38357841..0000000000
--- a/src/gui/painting/qdrawutil.h
+++ /dev/null
@@ -1,195 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDRAWUTIL_H
-#define QDRAWUTIL_H
-
-#include <QtCore/qnamespace.h>
-#include <QtCore/qstring.h> // char*->QString conversion
-#include <QtCore/qmargins.h>
-#include <QtGui/qpixmap.h>
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QPainter;
-#ifndef QT3_SUPPORT
-class QColorGroup;
-#endif
-class QPalette;
-class QPoint;
-class QColor;
-class QBrush;
-class QRect;
-
-//
-// Standard shade drawing
-//
-
-Q_GUI_EXPORT void qDrawShadeLine(QPainter *p, int x1, int y1, int x2, int y2,
- const QPalette &pal, bool sunken = true,
- int lineWidth = 1, int midLineWidth = 0);
-
-Q_GUI_EXPORT void qDrawShadeLine(QPainter *p, const QPoint &p1, const QPoint &p2,
- const QPalette &pal, bool sunken = true,
- int lineWidth = 1, int midLineWidth = 0);
-
-Q_GUI_EXPORT void qDrawShadeRect(QPainter *p, int x, int y, int w, int h,
- const QPalette &pal, bool sunken = false,
- int lineWidth = 1, int midLineWidth = 0,
- const QBrush *fill = 0);
-
-Q_GUI_EXPORT void qDrawShadeRect(QPainter *p, const QRect &r,
- const QPalette &pal, bool sunken = false,
- int lineWidth = 1, int midLineWidth = 0,
- const QBrush *fill = 0);
-
-Q_GUI_EXPORT void qDrawShadePanel(QPainter *p, int x, int y, int w, int h,
- const QPalette &pal, bool sunken = false,
- int lineWidth = 1, const QBrush *fill = 0);
-
-Q_GUI_EXPORT void qDrawShadePanel(QPainter *p, const QRect &r,
- const QPalette &pal, bool sunken = false,
- int lineWidth = 1, const QBrush *fill = 0);
-
-Q_GUI_EXPORT void qDrawWinButton(QPainter *p, int x, int y, int w, int h,
- const QPalette &pal, bool sunken = false,
- const QBrush *fill = 0);
-
-Q_GUI_EXPORT void qDrawWinButton(QPainter *p, const QRect &r,
- const QPalette &pal, bool sunken = false,
- const QBrush *fill = 0);
-
-Q_GUI_EXPORT void qDrawWinPanel(QPainter *p, int x, int y, int w, int h,
- const QPalette &pal, bool sunken = false,
- const QBrush *fill = 0);
-
-Q_GUI_EXPORT void qDrawWinPanel(QPainter *p, const QRect &r,
- const QPalette &pal, bool sunken = false,
- const QBrush *fill = 0);
-
-Q_GUI_EXPORT void qDrawPlainRect(QPainter *p, int x, int y, int w, int h, const QColor &,
- int lineWidth = 1, const QBrush *fill = 0);
-
-Q_GUI_EXPORT void qDrawPlainRect(QPainter *p, const QRect &r, const QColor &,
- int lineWidth = 1, const QBrush *fill = 0);
-
-
-#ifdef QT3_SUPPORT
-//
-// Use QStyle::itemRect(), QStyle::drawItem() and QStyle::drawArrow() instead.
-//
-Q_GUI_EXPORT QT3_SUPPORT QRect qItemRect(QPainter *p, Qt::GUIStyle gs, int x, int y, int w, int h,
- int flags, bool enabled,
- const QPixmap *pixmap, const QString& text, int len=-1);
-
-Q_GUI_EXPORT QT3_SUPPORT void qDrawItem(QPainter *p, Qt::GUIStyle gs, int x, int y, int w, int h,
- int flags, const QPalette &pal, bool enabled,
- const QPixmap *pixmap, const QString& text,
- int len=-1, const QColor* penColor = 0);
-
-Q_GUI_EXPORT QT3_SUPPORT void qDrawArrow(QPainter *p, Qt::ArrowType type, Qt::GUIStyle style, bool down,
- int x, int y, int w, int h,
- const QPalette &pal, bool enabled);
-#endif
-
-struct QTileRules
-{
- inline QTileRules(Qt::TileRule horizontalRule, Qt::TileRule verticalRule)
- : horizontal(horizontalRule), vertical(verticalRule) {}
- inline QTileRules(Qt::TileRule rule = Qt::StretchTile)
- : horizontal(rule), vertical(rule) {}
- Qt::TileRule horizontal;
- Qt::TileRule vertical;
-};
-
-#ifndef Q_QDOC
-// For internal use only.
-namespace QDrawBorderPixmap
-{
- enum DrawingHint
- {
- OpaqueTopLeft = 0x0001,
- OpaqueTop = 0x0002,
- OpaqueTopRight = 0x0004,
- OpaqueLeft = 0x0008,
- OpaqueCenter = 0x0010,
- OpaqueRight = 0x0020,
- OpaqueBottomLeft = 0x0040,
- OpaqueBottom = 0x0080,
- OpaqueBottomRight = 0x0100,
- OpaqueCorners = OpaqueTopLeft | OpaqueTopRight | OpaqueBottomLeft | OpaqueBottomRight,
- OpaqueEdges = OpaqueTop | OpaqueLeft | OpaqueRight | OpaqueBottom,
- OpaqueFrame = OpaqueCorners | OpaqueEdges,
- OpaqueAll = OpaqueCenter | OpaqueFrame
- };
-
- Q_DECLARE_FLAGS(DrawingHints, DrawingHint)
-}
-#endif
-
-Q_GUI_EXPORT void qDrawBorderPixmap(QPainter *painter,
- const QRect &targetRect,
- const QMargins &targetMargins,
- const QPixmap &pixmap,
- const QRect &sourceRect,
- const QMargins &sourceMargins,
- const QTileRules &rules = QTileRules()
-#ifndef Q_QDOC
- , QDrawBorderPixmap::DrawingHints hints = 0
-#endif
- );
-
-inline void qDrawBorderPixmap(QPainter *painter,
- const QRect &target,
- const QMargins &margins,
- const QPixmap &pixmap)
-{
- qDrawBorderPixmap(painter, target, margins, pixmap, pixmap.rect(), margins);
-}
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QDRAWUTIL_H
diff --git a/src/gui/painting/qgraphicssystem.cpp b/src/gui/painting/qgraphicssystem.cpp
deleted file mode 100644
index de0b516e79..0000000000
--- a/src/gui/painting/qgraphicssystem.cpp
+++ /dev/null
@@ -1,97 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qgraphicssystem_p.h"
-
-#ifdef Q_WS_X11
-# include <private/qpixmap_x11_p.h>
-#endif
-#if defined(Q_WS_WIN)
-# include <private/qpixmap_raster_p.h>
-#endif
-#ifdef Q_WS_MAC
-# include <private/qpixmap_mac_p.h>
-#endif
-#ifdef Q_WS_QPA
-# include <QtGui/private/qapplication_p.h>
-#endif
-#ifdef Q_OS_SYMBIAN
-# include <private/qpixmap_s60_p.h>
-#endif
-
-QT_BEGIN_NAMESPACE
-
-QGraphicsSystem::~QGraphicsSystem()
-{
-}
-
-QPixmapData *QGraphicsSystem::createDefaultPixmapData(QPixmapData::PixelType type)
-{
-#ifdef Q_WS_QWS
- Q_UNUSED(type);
-#endif
-#if defined(Q_WS_X11)
- return new QX11PixmapData(type);
-#elif defined(Q_WS_WIN)
- return new QRasterPixmapData(type);
-#elif defined(Q_WS_MAC)
- return new QMacPixmapData(type);
-#elif defined(Q_WS_QPA)
- return QApplicationPrivate::platformIntegration()->createPixmapData(type);
-#elif defined(Q_OS_SYMBIAN)
- return new QS60PixmapData(type);
-#elif !defined(Q_WS_QWS)
-#error QGraphicsSystem::createDefaultPixmapData() not implemented
-#endif
- return 0;
-}
-
-QPixmapData *QGraphicsSystem::createPixmapData(QPixmapData *origin)
-{
- return createPixmapData(origin->pixelType());
-}
-
-void QGraphicsSystem::releaseCachedResources()
-{
- // Do nothing here
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/painting/qgraphicssystem_mac.cpp b/src/gui/painting/qgraphicssystem_mac.cpp
deleted file mode 100644
index bbff88b6b5..0000000000
--- a/src/gui/painting/qgraphicssystem_mac.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qgraphicssystem_mac_p.h"
-
-#include <private/qpixmap_mac_p.h>
-#include <private/qwindowsurface_mac_p.h>
-
-QT_BEGIN_NAMESPACE
-
-QPixmapData *QCoreGraphicsSystem::createPixmapData(QPixmapData::PixelType type) const
-{
- return new QMacPixmapData(type);
-}
-
-QWindowSurface *QCoreGraphicsSystem::createWindowSurface(QWidget *widget) const
-{
- return new QMacWindowSurface(widget);
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/painting/qgraphicssystem_mac_p.h b/src/gui/painting/qgraphicssystem_mac_p.h
deleted file mode 100644
index 8e15d8b236..0000000000
--- a/src/gui/painting/qgraphicssystem_mac_p.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGRAPHICSSYSTEM_MAC_P_H
-#define QGRAPHICSSYSTEM_MAC_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "private/qgraphicssystem_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class Q_GUI_EXPORT QCoreGraphicsSystem : public QGraphicsSystem
-{
-public:
- QPixmapData *createPixmapData(QPixmapData::PixelType type) const;
- QWindowSurface *createWindowSurface(QWidget *widget) const;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/gui/painting/qgraphicssystem_p.h b/src/gui/painting/qgraphicssystem_p.h
deleted file mode 100644
index 53c05515fa..0000000000
--- a/src/gui/painting/qgraphicssystem_p.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGRAPHICSSYSTEM_P_H
-#define QGRAPHICSSYSTEM_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "private/qpixmapdata_p.h"
-#include "private/qwindowsurface_p.h"
-#include "private/qpaintengine_blitter_p.h"
-
-#include <qdebug.h>
-
-QT_BEGIN_NAMESPACE
-
-class QPixmapFilter;
-class QBlittable;
-
-class Q_GUI_EXPORT QGraphicsSystem
-{
-public:
- virtual QPixmapData *createPixmapData(QPixmapData::PixelType type) const = 0;
- virtual QPixmapData *createPixmapData(QPixmapData *origin);
- virtual QWindowSurface *createWindowSurface(QWidget *widget) const = 0;
-
- virtual ~QGraphicsSystem();
-
- //### Remove this & change qpixmap.cpp & qbitmap.cpp once every platform is gaurenteed
- // to have a graphics system.
- static QPixmapData *createDefaultPixmapData(QPixmapData::PixelType type);
-
- virtual void releaseCachedResources();
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/gui/painting/qgraphicssystem_qws.cpp b/src/gui/painting/qgraphicssystem_qws.cpp
deleted file mode 100644
index 2c2b776f5d..0000000000
--- a/src/gui/painting/qgraphicssystem_qws.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qscreen_qws.h>
-#include "qgraphicssystem_qws_p.h"
-#include <private/qpixmap_raster_p.h>
-#include <private/qwindowsurface_qws_p.h>
-
-QT_BEGIN_NAMESPACE
-
-QPixmapData *QWSGraphicsSystem::createPixmapData(QPixmapData::PixelType type) const
-{
- if (screen->pixmapDataFactory())
- return screen->pixmapDataFactory()->create(type); //### For 4.4 compatibility
- else
- return new QRasterPixmapData(type);
-}
-
-QWindowSurface *QWSGraphicsSystem::createWindowSurface(QWidget *widget) const
-{
- return screen->createSurface(widget);
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/painting/qgraphicssystem_qws_p.h b/src/gui/painting/qgraphicssystem_qws_p.h
deleted file mode 100644
index b54aad90f9..0000000000
--- a/src/gui/painting/qgraphicssystem_qws_p.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGRAPHICSSYSTEM_QWS_P_H
-#define QGRAPHICSSYSTEM_QWS_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qgraphicssystem_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class Q_GUI_EXPORT QWSGraphicsSystem : public QGraphicsSystem
-{
-public:
-
- QWSGraphicsSystem()
- : screen(QScreen::instance()) {}
-
- QWSGraphicsSystem(QScreen* s)
- : screen(s) {}
-
- virtual QPixmapData *createPixmapData(QPixmapData::PixelType type) const;
- QWindowSurface *createWindowSurface(QWidget *widget) const;
-
-private:
- QScreen* screen;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/gui/painting/qgraphicssystem_raster.cpp b/src/gui/painting/qgraphicssystem_raster.cpp
deleted file mode 100644
index 0edbe9f5a3..0000000000
--- a/src/gui/painting/qgraphicssystem_raster.cpp
+++ /dev/null
@@ -1,72 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qgraphicssystem_raster_p.h"
-
-#ifdef Q_OS_SYMBIAN
-#include "private/qpixmap_s60_p.h"
-#include "private/qwindowsurface_s60_p.h"
-#else
-#include "private/qpixmap_raster_p.h"
-#include "private/qwindowsurface_raster_p.h"
-#endif
-
-QT_BEGIN_NAMESPACE
-
-QPixmapData *QRasterGraphicsSystem::createPixmapData(QPixmapData::PixelType type) const
-{
-#ifdef Q_OS_SYMBIAN
- return new QS60PixmapData(type);
-#else
- return new QRasterPixmapData(type);
-#endif
-}
-
-QWindowSurface *QRasterGraphicsSystem::createWindowSurface(QWidget *widget) const
-{
-#ifdef Q_OS_SYMBIAN
- return new QS60WindowSurface(widget);
-#else
- return new QRasterWindowSurface(widget);
-#endif
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/painting/qgraphicssystem_raster_p.h b/src/gui/painting/qgraphicssystem_raster_p.h
deleted file mode 100644
index e9737ce78f..0000000000
--- a/src/gui/painting/qgraphicssystem_raster_p.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGRAPHICSSYSTEM_RASTER_P_H
-#define QGRAPHICSSYSTEM_RASTER_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qgraphicssystem_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class QRasterGraphicsSystem : public QGraphicsSystem
-{
-public:
- QPixmapData *createPixmapData(QPixmapData::PixelType type) const;
- QWindowSurface *createWindowSurface(QWidget *widget) const;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/gui/painting/qgraphicssystem_runtime.cpp b/src/gui/painting/qgraphicssystem_runtime.cpp
deleted file mode 100644
index 19b29a13b3..0000000000
--- a/src/gui/painting/qgraphicssystem_runtime.cpp
+++ /dev/null
@@ -1,426 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <private/qgraphicssystem_runtime_p.h>
-#include <private/qgraphicssystem_raster_p.h>
-#include <private/qgraphicssystemfactory_p.h>
-#include <private/qapplication_p.h>
-#include <private/qwidget_p.h>
-#include <QtCore/QDebug>
-#include <QtCore/QTimer>
-#include <QtGui/QBitmap>
-
-QT_BEGIN_NAMESPACE
-
-static int qt_pixmap_serial = 0;
-
-#define READBACK(f) \
- f \
- readBackInfo();
-
-
-class QDeferredGraphicsSystemChange : public QObject
-{
- Q_OBJECT
-
-public:
- QDeferredGraphicsSystemChange(QRuntimeGraphicsSystem *gs, const QString& graphicsSystemName)
- : m_graphicsSystem(gs), m_graphicsSystemName(graphicsSystemName)
- {
- }
-
- void launch()
- {
- QTimer::singleShot(0, this, SLOT(doChange()));
- }
-
-private slots:
-
- void doChange()
- {
- m_graphicsSystem->setGraphicsSystem(m_graphicsSystemName);
- deleteLater();
- }
-
-private:
-
- QRuntimeGraphicsSystem *m_graphicsSystem;
- QString m_graphicsSystemName;
-};
-
-QRuntimePixmapData::QRuntimePixmapData(const QRuntimeGraphicsSystem *gs, PixelType type)
- : QPixmapData(type, RuntimeClass), m_graphicsSystem(gs)
-{
- setSerialNumber(++qt_pixmap_serial);
-}
-
-QRuntimePixmapData::~QRuntimePixmapData()
-{
- if (QApplicationPrivate::graphics_system)
- m_graphicsSystem->removePixmapData(this);
- delete m_data;
-}
-
-void QRuntimePixmapData::readBackInfo()
-{
- w = m_data->width();
- h = m_data->height();
- d = m_data->depth();
- is_null = m_data->isNull();
-}
-
-
-QPixmapData *QRuntimePixmapData::createCompatiblePixmapData() const
-{
- QRuntimePixmapData *rtData = new QRuntimePixmapData(m_graphicsSystem, pixelType());
- rtData->m_data = m_data->createCompatiblePixmapData();
- return rtData;
-}
-
-
-void QRuntimePixmapData::resize(int width, int height)
-{
- READBACK(
- m_data->resize(width, height);
- )
-}
-
-
-void QRuntimePixmapData::fromImage(const QImage &image,
- Qt::ImageConversionFlags flags)
-{
- READBACK(
- m_data->fromImage(image, flags);
- )
-}
-
-
-bool QRuntimePixmapData::fromFile(const QString &filename, const char *format,
- Qt::ImageConversionFlags flags)
-{
- bool success(false);
- READBACK(
- success = m_data->fromFile(filename, format, flags);
- )
- return success;
-}
-
-bool QRuntimePixmapData::fromData(const uchar *buffer, uint len, const char *format,
- Qt::ImageConversionFlags flags)
-{
- bool success(false);
- READBACK(
- success = m_data->fromData(buffer, len, format, flags);
- )
- return success;
-}
-
-
-void QRuntimePixmapData::copy(const QPixmapData *data, const QRect &rect)
-{
- if (data->runtimeData()) {
- READBACK(
- m_data->copy(data->runtimeData(), rect);
- )
- } else {
- READBACK(
- m_data->copy(data, rect);
- )
- }
-}
-
-bool QRuntimePixmapData::scroll(int dx, int dy, const QRect &rect)
-{
- return m_data->scroll(dx, dy, rect);
-}
-
-
-int QRuntimePixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const
-{
- return m_data->metric(metric);
-}
-
-void QRuntimePixmapData::fill(const QColor &color)
-{
- return m_data->fill(color);
-}
-
-QBitmap QRuntimePixmapData::mask() const
-{
- return m_data->mask();
-}
-
-void QRuntimePixmapData::setMask(const QBitmap &mask)
-{
- READBACK(
- m_data->setMask(mask);
- )
-}
-
-bool QRuntimePixmapData::hasAlphaChannel() const
-{
- return m_data->hasAlphaChannel();
-}
-
-QPixmap QRuntimePixmapData::transformed(const QTransform &matrix,
- Qt::TransformationMode mode) const
-{
- return m_data->transformed(matrix, mode);
-}
-
-void QRuntimePixmapData::setAlphaChannel(const QPixmap &alphaChannel)
-{
- READBACK(
- m_data->setAlphaChannel(alphaChannel);
- )
-}
-
-QPixmap QRuntimePixmapData::alphaChannel() const
-{
- return m_data->alphaChannel();
-}
-
-QImage QRuntimePixmapData::toImage() const
-{
- return m_data->toImage();
-}
-
-QPaintEngine* QRuntimePixmapData::paintEngine() const
-{
- return m_data->paintEngine();
-}
-
-QImage* QRuntimePixmapData::buffer()
-{
- return m_data->buffer();
-}
-
-#if defined(Q_OS_SYMBIAN)
-void* QRuntimePixmapData::toNativeType(NativeType type)
-{
- return m_data->toNativeType(type);
-}
-
-void QRuntimePixmapData::fromNativeType(void *pixmap, NativeType type)
-{
- m_data->fromNativeType(pixmap, type);
- readBackInfo();
-}
-#endif
-
-QPixmapData* QRuntimePixmapData::runtimeData() const
-{
- return m_data;
-}
-
-QRuntimeWindowSurface::QRuntimeWindowSurface(const QRuntimeGraphicsSystem *gs, QWidget *window)
- : QWindowSurface(window), m_graphicsSystem(gs)
-{
-
-}
-
-QRuntimeWindowSurface::~QRuntimeWindowSurface()
-{
- if (QApplicationPrivate::graphics_system)
- m_graphicsSystem->removeWindowSurface(this);
-}
-
-QPaintDevice *QRuntimeWindowSurface::paintDevice()
-{
- return m_windowSurface->paintDevice();
-}
-
-void QRuntimeWindowSurface::flush(QWidget *widget, const QRegion &region,
- const QPoint &offset)
-{
- m_windowSurface->flush(widget, region, offset);
-
- int destroyPolicy = m_graphicsSystem->windowSurfaceDestroyPolicy();
- if(m_pendingWindowSurface &&
- destroyPolicy == QRuntimeGraphicsSystem::DestroyAfterFirstFlush) {
-#ifdef QT_DEBUG
- qDebug() << "QRuntimeWindowSurface::flush() - destroy pending window surface";
-#endif
- m_pendingWindowSurface.reset();
- }
-}
-
-void QRuntimeWindowSurface::setGeometry(const QRect &rect)
-{
- QWindowSurface::setGeometry(rect);
- m_windowSurface->setGeometry(rect);
-}
-
-bool QRuntimeWindowSurface::scroll(const QRegion &area, int dx, int dy)
-{
- return m_windowSurface->scroll(area, dx, dy);
-}
-
-void QRuntimeWindowSurface::beginPaint(const QRegion &rgn)
-{
- m_windowSurface->beginPaint(rgn);
-}
-
-void QRuntimeWindowSurface::endPaint(const QRegion &rgn)
-{
- m_windowSurface->endPaint(rgn);
-}
-
-QImage* QRuntimeWindowSurface::buffer(const QWidget *widget)
-{
- return m_windowSurface->buffer(widget);
-}
-
-QPixmap QRuntimeWindowSurface::grabWidget(const QWidget *widget, const QRect& rectangle) const
-{
- return m_windowSurface->grabWidget(widget, rectangle);
-}
-
-QPoint QRuntimeWindowSurface::offset(const QWidget *widget) const
-{
- return m_windowSurface->offset(widget);
-}
-
-QWindowSurface::WindowSurfaceFeatures QRuntimeWindowSurface::features() const
-{
- return m_windowSurface->features();
-}
-
-QRuntimeGraphicsSystem::QRuntimeGraphicsSystem()
- : m_windowSurfaceDestroyPolicy(DestroyImmediately),
- m_graphicsSystem(0)
-{
- QApplicationPrivate::runtime_graphics_system = true;
-
-#ifdef QT_DEFAULT_RUNTIME_SYSTEM
- m_graphicsSystemName = QLatin1String(QT_DEFAULT_RUNTIME_SYSTEM);
- if (m_graphicsSystemName.isNull())
-#endif
- m_graphicsSystemName = QLatin1String("raster");
-
-#ifdef Q_OS_SYMBIAN
- m_windowSurfaceDestroyPolicy = DestroyAfterFirstFlush;
-#endif
-
- m_graphicsSystem = QGraphicsSystemFactory::create(m_graphicsSystemName);
-
- QApplicationPrivate::graphics_system_name = QLatin1String("runtime");
-}
-
-
-QPixmapData *QRuntimeGraphicsSystem::createPixmapData(QPixmapData::PixelType type) const
-{
- Q_ASSERT(m_graphicsSystem);
- QPixmapData *data = m_graphicsSystem->createPixmapData(type);
-
- QRuntimePixmapData *rtData = new QRuntimePixmapData(this, type);
- rtData->m_data = data;
- m_pixmapDatas << rtData;
-
- return rtData;
-}
-
-QWindowSurface *QRuntimeGraphicsSystem::createWindowSurface(QWidget *widget) const
-{
- Q_ASSERT(m_graphicsSystem);
- QRuntimeWindowSurface *rtSurface = new QRuntimeWindowSurface(this, widget);
- rtSurface->m_windowSurface.reset(m_graphicsSystem->createWindowSurface(widget));
- widget->setWindowSurface(rtSurface);
- m_windowSurfaces << rtSurface;
- return rtSurface;
-}
-
-void QRuntimeGraphicsSystem::setGraphicsSystem(const QString &name)
-{
- if (m_graphicsSystemName == name)
- return;
-#ifdef QT_DEBUG
- qDebug() << "QRuntimeGraphicsSystem::setGraphicsSystem( " << name << " )";
-#endif
- QGraphicsSystem *oldSystem = m_graphicsSystem;
- m_graphicsSystem = QGraphicsSystemFactory::create(name);
- m_graphicsSystemName = name;
-
- Q_ASSERT(m_graphicsSystem);
-
- m_pendingGraphicsSystemName = QString();
-
- for (int i = 0; i < m_pixmapDatas.size(); ++i) {
- QRuntimePixmapData *proxy = m_pixmapDatas.at(i);
- QPixmapData *newData = m_graphicsSystem->createPixmapData(proxy->m_data);
- newData->fromImage(proxy->m_data->toImage(), Qt::NoOpaqueDetection);
- delete proxy->m_data;
- proxy->m_data = newData;
- proxy->readBackInfo();
- }
-
- for (int i = 0; i < m_windowSurfaces.size(); ++i) {
- QRuntimeWindowSurface *proxy = m_windowSurfaces.at(i);
- QWidget *widget = proxy->m_windowSurface->window();
-
- if(m_windowSurfaceDestroyPolicy == DestroyAfterFirstFlush)
- proxy->m_pendingWindowSurface.reset(proxy->m_windowSurface.take());
-
- QWindowSurface *newWindowSurface = m_graphicsSystem->createWindowSurface(widget);
- newWindowSurface->setGeometry(proxy->geometry());
-
- proxy->m_windowSurface.reset(newWindowSurface);
- qt_widget_private(widget)->invalidateBuffer(widget->rect());
- }
-
- delete oldSystem;
-}
-
-void QRuntimeGraphicsSystem::removePixmapData(QRuntimePixmapData *pixmapData) const
-{
- int index = m_pixmapDatas.lastIndexOf(pixmapData);
- m_pixmapDatas.removeAt(index);
-}
-
-void QRuntimeGraphicsSystem::removeWindowSurface(QRuntimeWindowSurface *windowSurface) const
-{
- int index = m_windowSurfaces.lastIndexOf(windowSurface);
- m_windowSurfaces.removeAt(index);
-}
-
-#include "qgraphicssystem_runtime.moc"
-
-QT_END_NAMESPACE
diff --git a/src/gui/painting/qgraphicssystem_runtime_p.h b/src/gui/painting/qgraphicssystem_runtime_p.h
deleted file mode 100644
index a3828d44c0..0000000000
--- a/src/gui/painting/qgraphicssystem_runtime_p.h
+++ /dev/null
@@ -1,187 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGRAPHICSSYSTEM_RUNTIME_P_H
-#define QGRAPHICSSYSTEM_RUNTIME_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qgraphicssystem_p.h"
-
-#include <private/qpixmapdata_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QRuntimeGraphicsSystem;
-
-class Q_GUI_EXPORT QRuntimePixmapData : public QPixmapData {
-public:
- QRuntimePixmapData(const QRuntimeGraphicsSystem *gs, PixelType type);
- ~QRuntimePixmapData();
-
- virtual QPixmapData *createCompatiblePixmapData() const;
- virtual void resize(int width, int height);
- virtual void fromImage(const QImage &image,
- Qt::ImageConversionFlags flags);
-
- virtual bool fromFile(const QString &filename, const char *format,
- Qt::ImageConversionFlags flags);
- virtual bool fromData(const uchar *buffer, uint len, const char *format,
- Qt::ImageConversionFlags flags);
-
- virtual void copy(const QPixmapData *data, const QRect &rect);
- virtual bool scroll(int dx, int dy, const QRect &rect);
-
- virtual int metric(QPaintDevice::PaintDeviceMetric metric) const;
- virtual void fill(const QColor &color);
- virtual QBitmap mask() const;
- virtual void setMask(const QBitmap &mask);
- virtual bool hasAlphaChannel() const;
- virtual QPixmap transformed(const QTransform &matrix,
- Qt::TransformationMode mode) const;
- virtual void setAlphaChannel(const QPixmap &alphaChannel);
- virtual QPixmap alphaChannel() const;
- virtual QImage toImage() const;
- virtual QPaintEngine *paintEngine() const;
-
- virtual QImage *buffer();
-
- void readBackInfo();
-
- QPixmapData *m_data;
-
-#if defined(Q_OS_SYMBIAN)
- void* toNativeType(NativeType type);
- void fromNativeType(void* pixmap, NativeType type);
-#endif
-
- virtual QPixmapData *runtimeData() const;
-
-private:
- const QRuntimeGraphicsSystem *m_graphicsSystem;
-
-};
-
-class QRuntimeWindowSurface : public QWindowSurface {
-public:
- QRuntimeWindowSurface(const QRuntimeGraphicsSystem *gs, QWidget *window);
- ~QRuntimeWindowSurface();
-
- virtual QPaintDevice *paintDevice();
- virtual void flush(QWidget *widget, const QRegion &region,
- const QPoint &offset);
- virtual void setGeometry(const QRect &rect);
-
- virtual bool scroll(const QRegion &area, int dx, int dy);
-
- virtual void beginPaint(const QRegion &);
- virtual void endPaint(const QRegion &);
-
- virtual QImage* buffer(const QWidget *widget);
- virtual QPixmap grabWidget(const QWidget *widget, const QRect& rectangle = QRect()) const;
-
- virtual QPoint offset(const QWidget *widget) const;
-
- virtual WindowSurfaceFeatures features() const;
-
- QScopedPointer<QWindowSurface> m_windowSurface;
- QScopedPointer<QWindowSurface> m_pendingWindowSurface;
-
-private:
- const QRuntimeGraphicsSystem *m_graphicsSystem;
-};
-
-class QRuntimeGraphicsSystem : public QGraphicsSystem
-{
-public:
-
- enum WindowSurfaceDestroyPolicy
- {
- DestroyImmediately,
- DestroyAfterFirstFlush
- };
-
-public:
- QRuntimeGraphicsSystem();
-
- QPixmapData *createPixmapData(QPixmapData::PixelType type) const;
- QWindowSurface *createWindowSurface(QWidget *widget) const;
-
- void removePixmapData(QRuntimePixmapData *pixmapData) const;
- void removeWindowSurface(QRuntimeWindowSurface *windowSurface) const;
-
- void setGraphicsSystem(const QString &name);
- QString graphicsSystemName() const { return m_graphicsSystemName; }
-
- void setWindowSurfaceDestroyPolicy(WindowSurfaceDestroyPolicy policy)
- {
- m_windowSurfaceDestroyPolicy = policy;
- }
-
- int windowSurfaceDestroyPolicy() const { return m_windowSurfaceDestroyPolicy; }
-
-
-private:
- int m_windowSurfaceDestroyPolicy;
- QGraphicsSystem *m_graphicsSystem;
- mutable QList<QRuntimePixmapData *> m_pixmapDatas;
- mutable QList<QRuntimeWindowSurface *> m_windowSurfaces;
- QString m_graphicsSystemName;
-
- QString m_pendingGraphicsSystemName;
-
- friend class QRuntimePixmapData;
- friend class QRuntimeWindowSurface;
- friend class QMeeGoGraphicsSystem;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/gui/painting/qgraphicssystemfactory.cpp b/src/gui/painting/qgraphicssystemfactory.cpp
deleted file mode 100644
index 4309140cc4..0000000000
--- a/src/gui/painting/qgraphicssystemfactory.cpp
+++ /dev/null
@@ -1,123 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qgraphicssystemfactory_p.h"
-#include "qgraphicssystemplugin_p.h"
-#include "private/qfactoryloader_p.h"
-#include "qmutex.h"
-
-#include "qapplication.h"
-#include <private/qapplication_p.h>
-#include "qgraphicssystem_raster_p.h"
-#include "qgraphicssystem_runtime_p.h"
-#include "qdebug.h"
-
-QT_BEGIN_NAMESPACE
-
-#ifndef QT_NO_LIBRARY
-Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
- (QGraphicsSystemFactoryInterface_iid, QLatin1String("/graphicssystems"), Qt::CaseInsensitive))
-#endif
-
-QGraphicsSystem *QGraphicsSystemFactory::create(const QString& key)
-{
- QGraphicsSystem *ret = 0;
- QString system = key.toLower();
-
-#if defined (QT_GRAPHICSSYSTEM_OPENGL)
- if (system.isEmpty()) {
- system = QLatin1String("opengl");
- }
-#elif defined (QT_GRAPHICSSYSTEM_OPENVG)
- if (system.isEmpty()) {
- system = QLatin1String("openvg");
- }
-#elif defined (QT_GRAPHICSSYSTEM_RUNTIME)
- if (system.isEmpty()) {
- system = QLatin1String("runtime");
- }
-#elif defined (QT_GRAPHICSSYSTEM_RASTER) && !defined(Q_WS_WIN) && !defined(Q_OS_SYMBIAN) || defined(Q_WS_X11) || (defined (Q_WS_MAC) && defined(QT_MAC_USE_COCOA))
- if (system.isEmpty()) {
- system = QLatin1String("raster");
- }
-#endif
-
- QApplicationPrivate::graphics_system_name = system;
- if (system == QLatin1String("raster"))
- return new QRasterGraphicsSystem;
- else if (system == QLatin1String("runtime"))
- return new QRuntimeGraphicsSystem;
- else if (system.isEmpty() || system == QLatin1String("native"))
- return 0;
-
-#ifndef QT_NO_LIBRARY
- if (!ret) {
- if (QGraphicsSystemFactoryInterface *factory = qobject_cast<QGraphicsSystemFactoryInterface*>(loader()->instance(system)))
- ret = factory->create(system);
- }
-#endif
-
- if (!ret)
- qWarning() << "Unable to load graphicssystem" << system;
-
- return ret;
-}
-
-/*!
- Returns the list of valid keys, i.e. the keys this factory can
- create styles for.
-
- \sa create()
-*/
-QStringList QGraphicsSystemFactory::keys()
-{
-#ifndef QT_NO_LIBRARY
- QStringList list = loader()->keys();
-#else
- QStringList list;
-#endif
- if (!list.contains(QLatin1String("Raster")))
- list << QLatin1String("raster");
- return list;
-}
-
-QT_END_NAMESPACE
-
diff --git a/src/gui/painting/qgraphicssystemfactory_p.h b/src/gui/painting/qgraphicssystemfactory_p.h
deleted file mode 100644
index c8e55e049d..0000000000
--- a/src/gui/painting/qgraphicssystemfactory_p.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGRAPHICSSYSTEMFACTORY_H
-#define QGRAPHICSSYSTEMFACTORY_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/qstringlist.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QGraphicsSystem;
-
-class QGraphicsSystemFactory
-{
-public:
- static QStringList keys();
- static QGraphicsSystem *create(const QString&);
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QGRAPHICSSYSTEMFACTORY_H
-
diff --git a/src/gui/painting/qgraphicssystemplugin.cpp b/src/gui/painting/qgraphicssystemplugin.cpp
deleted file mode 100644
index 8153b8aa05..0000000000
--- a/src/gui/painting/qgraphicssystemplugin.cpp
+++ /dev/null
@@ -1,56 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qgraphicssystemplugin_p.h"
-#include "qgraphicssystem_p.h"
-
-QT_BEGIN_NAMESPACE
-
-QGraphicsSystemPlugin::QGraphicsSystemPlugin(QObject *parent)
- : QObject(parent)
-{
-}
-
-QGraphicsSystemPlugin::~QGraphicsSystemPlugin()
-{
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/painting/qgraphicssystemplugin_p.h b/src/gui/painting/qgraphicssystemplugin_p.h
deleted file mode 100644
index 3d353abe79..0000000000
--- a/src/gui/painting/qgraphicssystemplugin_p.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGRAPHICSSYSTEMPLUGIN_H
-#define QGRAPHICSSYSTEMPLUGIN_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/qplugin.h>
-#include <QtCore/qfactoryinterface.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QGraphicsSystem;
-
-struct QGraphicsSystemFactoryInterface : public QFactoryInterface
-{
- virtual QGraphicsSystem *create(const QString &key) = 0;
-};
-
-#define QGraphicsSystemFactoryInterface_iid "com.trolltech.Qt.QGraphicsSystemFactoryInterface"
-
-Q_DECLARE_INTERFACE(QGraphicsSystemFactoryInterface, QGraphicsSystemFactoryInterface_iid)
-
-class Q_GUI_EXPORT QGraphicsSystemPlugin : public QObject, public QGraphicsSystemFactoryInterface
-{
- Q_OBJECT
- Q_INTERFACES(QGraphicsSystemFactoryInterface:QFactoryInterface)
-public:
- explicit QGraphicsSystemPlugin(QObject *parent = 0);
- ~QGraphicsSystemPlugin();
-
- virtual QStringList keys() const = 0;
- virtual QGraphicsSystem *create(const QString &key) = 0;
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QGRAPHICSSYSTEMEPLUGIN_H
diff --git a/src/gui/painting/qmatrix.cpp b/src/gui/painting/qmatrix.cpp
index 7bb2324a2f..767706a5bc 100644
--- a/src/gui/painting/qmatrix.cpp
+++ b/src/gui/painting/qmatrix.cpp
@@ -731,42 +731,6 @@ QPainterPath QMatrix::map(const QPainterPath &path) const
}
/*!
- \fn QRegion QMatrix::mapToRegion(const QRect &rectangle) const
-
- Returns the transformed rectangle \a rectangle as a QRegion
- object. A rectangle which has been rotated or sheared may result
- in a non-rectangular region being returned.
-
- Use the mapToPolygon() or map() function instead.
-*/
-#ifdef QT3_SUPPORT
-QRegion QMatrix::mapToRegion(const QRect &rect) const
-{
- QRegion result;
- if (isIdentity()) {
- result = rect;
- } else if (m12() == 0.0F && m21() == 0.0F) {
- int x = qRound(m11()*rect.x() + dx());
- int y = qRound(m22()*rect.y() + dy());
- int w = qRound(m11()*rect.width());
- int h = qRound(m22()*rect.height());
- if (w < 0) {
- w = -w;
- x -= w - 1;
- }
- if (h < 0) {
- h = -h;
- y -= h - 1;
- }
- result = QRect(x, y, w, h);
- } else {
- result = QRegion(mapToPolygon(rect));
- }
- return result;
-
-}
-#endif
-/*!
\fn QPolygon QMatrix::mapToPolygon(const QRect &rectangle) const
Creates and returns a QPolygon representation of the given \a
diff --git a/src/gui/painting/qmatrix.h b/src/gui/painting/qmatrix.h
index ff80704387..830a0a734f 100644
--- a/src/gui/painting/qmatrix.h
+++ b/src/gui/painting/qmatrix.h
@@ -118,12 +118,6 @@ public:
operator QVariant() const;
-#ifdef QT3_SUPPORT
- inline QT3_SUPPORT QMatrix invert(bool *invertible=0) const { return inverted(invertible); }
- inline QT3_SUPPORT QRect map(const QRect &r) const { return mapRect(r); }
- QT3_SUPPORT QRegion mapToRegion(const QRect &r) const;
-#endif
-
private:
inline QMatrix(bool)
: _m11(1.)
@@ -193,12 +187,6 @@ Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QMatrix &);
Q_GUI_EXPORT QDebug operator<<(QDebug, const QMatrix &);
#endif
-#ifdef QT3_SUPPORT
-QT_BEGIN_INCLUDE_NAMESPACE
-#include <QtGui/qwmatrix.h>
-QT_END_INCLUDE_NAMESPACE
-#endif
-
QT_END_NAMESPACE
QT_END_HEADER
diff --git a/src/gui/painting/qmemrotate.cpp b/src/gui/painting/qmemrotate.cpp
index 0ab6674913..857621df6e 100644
--- a/src/gui/painting/qmemrotate.cpp
+++ b/src/gui/painting/qmemrotate.cpp
@@ -512,34 +512,34 @@ inline void qt_memrotate90_template<quint18, quint32>(const quint32 *src,
}
#define QT_IMPL_MEMROTATE(srctype, desttype) \
-void qt_memrotate90(const srctype *src, int w, int h, int sstride, \
+Q_GUI_EXPORT void qt_memrotate90(const srctype *src, int w, int h, int sstride, \
desttype *dest, int dstride) \
{ \
qt_memrotate90_template(src, w, h, sstride, dest, dstride); \
} \
-void qt_memrotate180(const srctype *src, int w, int h, int sstride, \
+Q_GUI_EXPORT void qt_memrotate180(const srctype *src, int w, int h, int sstride, \
desttype *dest, int dstride) \
{ \
qt_memrotate180_template(src, w, h, sstride, dest, dstride); \
} \
-void qt_memrotate270(const srctype *src, int w, int h, int sstride, \
+Q_GUI_EXPORT void qt_memrotate270(const srctype *src, int w, int h, int sstride, \
desttype *dest, int dstride) \
{ \
qt_memrotate270_template(src, w, h, sstride, dest, dstride); \
}
#define QT_IMPL_SIMPLE_MEMROTATE(srctype, desttype) \
-void qt_memrotate90(const srctype *src, int w, int h, int sstride, \
+Q_GUI_EXPORT void qt_memrotate90(const srctype *src, int w, int h, int sstride, \
desttype *dest, int dstride) \
{ \
qt_memrotate90_tiled_unpacked<desttype,srctype>(src, w, h, sstride, dest, dstride); \
} \
-void qt_memrotate180(const srctype *src, int w, int h, int sstride, \
+Q_GUI_EXPORT void qt_memrotate180(const srctype *src, int w, int h, int sstride, \
desttype *dest, int dstride) \
{ \
qt_memrotate180_template(src, w, h, sstride, dest, dstride); \
} \
-void qt_memrotate270(const srctype *src, int w, int h, int sstride, \
+Q_GUI_EXPORT void qt_memrotate270(const srctype *src, int w, int h, int sstride, \
desttype *dest, int dstride) \
{ \
qt_memrotate270_tiled_unpacked<desttype,srctype>(src, w, h, sstride, dest, dstride); \
diff --git a/src/gui/painting/qmemrotate_p.h b/src/gui/painting/qmemrotate_p.h
index 019576a446..84b0b01846 100644
--- a/src/gui/painting/qmemrotate_p.h
+++ b/src/gui/painting/qmemrotate_p.h
@@ -70,7 +70,7 @@ QT_BEGIN_NAMESPACE
#endif
#endif
-#ifdef Q_WS_QWS
+#if defined(Q_WS_QWS) || defined(Q_WS_QPA) && defined(Q_OS_WIN)
#define Q_GUI_QWS_EXPORT Q_GUI_EXPORT
#else
#define Q_GUI_QWS_EXPORT
diff --git a/src/gui/painting/qpagedpaintdevice.cpp b/src/gui/painting/qpagedpaintdevice.cpp
new file mode 100644
index 0000000000..e5b2c0716e
--- /dev/null
+++ b/src/gui/painting/qpagedpaintdevice.cpp
@@ -0,0 +1,227 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qpagedpaintdevice.h>
+
+class QPagedPaintDevicePrivate
+{
+public:
+ QPagedPaintDevice::PageSize pageSize;
+ QSizeF pageSizeMM;
+ QPagedPaintDevice::Margins margins;
+};
+
+static const struct {
+ float width;
+ float height;
+} pageSizes[] = {
+ {210, 297}, // A4
+ {176, 250}, // B5
+ {215.9f, 279.4f}, // Letter
+ {215.9f, 355.6f}, // Legal
+ {190.5f, 254}, // Executive
+ {841, 1189}, // A0
+ {594, 841}, // A1
+ {420, 594}, // A2
+ {297, 420}, // A3
+ {148, 210}, // A5
+ {105, 148}, // A6
+ {74, 105}, // A7
+ {52, 74}, // A8
+ {37, 52}, // A8
+ {1000, 1414}, // B0
+ {707, 1000}, // B1
+ {31, 44}, // B10
+ {500, 707}, // B2
+ {353, 500}, // B3
+ {250, 353}, // B4
+ {125, 176}, // B6
+ {88, 125}, // B7
+ {62, 88}, // B8
+ {33, 62}, // B9
+ {163, 229}, // C5E
+ {105, 241}, // US Common
+ {110, 220}, // DLE
+ {210, 330}, // Folio
+ {431.8f, 279.4f}, // Ledger
+ {279.4f, 431.8f} // Tabloid
+};
+
+/*!
+ \class QPagedPaintDevice
+
+ \brief The QPagedPaintDevice class is a represents a paintdevice that supports
+ multiple pages.
+
+ \ingroup painting
+
+ Paged paint devices are used to generate output for printing or for formats like PDF.
+ QPdfWriter and QPrinter inherit from it.
+ */
+
+/*!
+ Constructs a new paged paint device.
+ */
+QPagedPaintDevice::QPagedPaintDevice()
+ : d(new QPagedPaintDevicePrivate)
+{
+}
+
+/*!
+ Destroys the object.
+ */
+QPagedPaintDevice::~QPagedPaintDevice()
+{
+ delete d;
+}
+
+/*!
+ \enum QPagedPaintDevice::PageSize
+
+ This enum type specifies the page size of the paint device.
+
+ \value A0 841 x 1189 mm
+ \value A1 594 x 841 mm
+ \value A2 420 x 594 mm
+ \value A3 297 x 420 mm
+ \value A4 210 x 297 mm, 8.26 x 11.69 inches
+ \value A5 148 x 210 mm
+ \value A6 105 x 148 mm
+ \value A7 74 x 105 mm
+ \value A8 52 x 74 mm
+ \value A9 37 x 52 mm
+ \value B0 1000 x 1414 mm
+ \value B1 707 x 1000 mm
+ \value B2 500 x 707 mm
+ \value B3 353 x 500 mm
+ \value B4 250 x 353 mm
+ \value B5 176 x 250 mm, 6.93 x 9.84 inches
+ \value B6 125 x 176 mm
+ \value B7 88 x 125 mm
+ \value B8 62 x 88 mm
+ \value B9 33 x 62 mm
+ \value B10 31 x 44 mm
+ \value C5E 163 x 229 mm
+ \value Comm10E 105 x 241 mm, U.S. Common 10 Envelope
+ \value DLE 110 x 220 mm
+ \value Executive 7.5 x 10 inches, 190.5 x 254 mm
+ \value Folio 210 x 330 mm
+ \value Ledger 431.8 x 279.4 mm
+ \value Legal 8.5 x 14 inches, 215.9 x 355.6 mm
+ \value Letter 8.5 x 11 inches, 215.9 x 279.4 mm
+ \value Tabloid 279.4 x 431.8 mm
+ \value Custom Unknown, or a user defined size.
+
+ \omitvalue NPageSize
+
+ The page size can also be specified in millimeters using setPageSizeMM(). In this case the
+ page size enum is set to Custom.
+*/
+
+/*!
+ \fn bool QPagedPaintDevice::newPage()
+
+ Starts a new page.
+*/
+
+
+/*!
+ Sets the size of the a page to \a size.
+
+ \sa setPageSizeMM
+ */
+void QPagedPaintDevice::setPageSize(PageSize size)
+{
+ if (size >= Custom)
+ return;
+ d->pageSize = size;
+ d->pageSizeMM = QSizeF(pageSizes[A4].width, pageSizes[A4].height);
+}
+
+/*!
+ Returns the currently used page size.
+ */
+QPagedPaintDevice::PageSize QPagedPaintDevice::pageSize() const
+{
+ return d->pageSize;
+}
+
+/*!
+ Sets the page size to \a size. \a size is specified in millimeters.
+ */
+void QPagedPaintDevice::setPageSizeMM(const QSizeF &size)
+{
+ d->pageSize = Custom;
+ d->pageSizeMM = size;
+}
+
+/*!
+ Returns the page size in millimeters.
+ */
+QSizeF QPagedPaintDevice::pageSizeMM() const
+{
+ return d->pageSizeMM;
+}
+
+/*!
+ Sets the margins to be used to \a margins.
+
+ Margins are specified in millimeters.
+
+ The margins are purely a hint to the drawing method. They don't affect the
+ coordinate system or clipping.
+
+ \sa margins
+ */
+void QPagedPaintDevice::setMargins(const Margins &margins)
+{
+ d->margins = margins;
+}
+
+/*!
+ returns the current margins of the paint device. The default is 0.
+
+ /sa setMargins
+ */
+QPagedPaintDevice::Margins QPagedPaintDevice::margins() const
+{
+ return d->margins;
+}
diff --git a/src/gui/painting/qpagedpaintdevice.h b/src/gui/painting/qpagedpaintdevice.h
new file mode 100644
index 0000000000..f3a133a8d9
--- /dev/null
+++ b/src/gui/painting/qpagedpaintdevice.h
@@ -0,0 +1,53 @@
+
+#ifndef QPAGEDPAINTDEVICE_H
+#define QPAGEDPAINTDEVICE_H
+
+#include <QtGui/qpaintdevice.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QPagedPaintDevicePrivate;
+
+class Q_GUI_EXPORT QPagedPaintDevice : public QPaintDevice
+{
+public:
+ QPagedPaintDevice();
+ ~QPagedPaintDevice();
+
+ virtual bool newPage() = 0;
+
+ enum PageSize { A4, B5, Letter, Legal, Executive,
+ A0, A1, A2, A3, A5, A6, A7, A8, A9, B0, B1,
+ B10, B2, B3, B4, B6, B7, B8, B9, C5E, Comm10E,
+ DLE, Folio, Ledger, Tabloid, Custom, NPageSize = Custom };
+
+ virtual void setPageSize(PageSize size);
+ PageSize pageSize() const;
+
+ virtual void setPageSizeMM(const QSizeF &size);
+ QSizeF pageSizeMM() const;
+
+ struct Margins {
+ qreal left;
+ qreal right;
+ qreal top;
+ qreal bottom;
+ };
+
+ virtual void setMargins(const Margins &margins);
+ Margins margins() const;
+
+protected:
+ friend class QPagedPaintDevicePrivate;
+ QPagedPaintDevicePrivate *d;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/gui/painting/qpagedpaintdevice_p.h b/src/gui/painting/qpagedpaintdevice_p.h
new file mode 100644
index 0000000000..55f78d54c5
--- /dev/null
+++ b/src/gui/painting/qpagedpaintdevice_p.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPAGEDPAINTDEVICE_P_H
+#define QPAGEDPAINTDEVICE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <qpagedpaintdevice.h>
+
+QT_BEGIN_NAMESPACE
+
+class Q_GUI_EXPORT QPagedPaintDevicePrivate
+{
+public:
+ QPagedPaintDevicePrivate()
+ : pageSize(QPagedPaintDevice::A4),
+ pageSizeMM(210, 297),
+ fromPage(0),
+ toPage(0),
+ pageOrderAscending(true),
+ printSelectionOnly(false)
+ {
+ margins.left = margins.right = margins.top = margins.bottom = 0;
+ }
+
+ static inline QPagedPaintDevicePrivate *get(QPagedPaintDevice *pd) { return pd->d; }
+
+ QPagedPaintDevice::PageSize pageSize;
+ QSizeF pageSizeMM;
+ QPagedPaintDevice::Margins margins;
+
+ // These are currently required to keep QPrinter functionality working in QTextDocument::print()
+ int fromPage;
+ int toPage;
+ bool pageOrderAscending;
+ bool printSelectionOnly;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/gui/painting/qpaintdevice.cpp b/src/gui/painting/qpaintdevice.cpp
index 7b3d4add49..fc5cdcdaa5 100644
--- a/src/gui/painting/qpaintdevice.cpp
+++ b/src/gui/painting/qpaintdevice.cpp
@@ -43,8 +43,6 @@
QT_BEGIN_NAMESPACE
-extern void qt_painter_removePaintDevice(QPaintDevice *); //qpainter.cpp
-
QPaintDevice::QPaintDevice()
{
painters = 0;
@@ -55,7 +53,6 @@ QPaintDevice::~QPaintDevice()
if (paintingActive())
qWarning("QPaintDevice: Cannot destroy paint device that is being "
"painted");
- qt_painter_removePaintDevice(this);
}
@@ -67,6 +64,20 @@ int QPaintDevice::metric(PaintDeviceMetric) const
}
#endif
+void QPaintDevice::init(QPainter *) const
+{
+}
+
+QPaintDevice *QPaintDevice::redirected(QPoint *) const
+{
+ return 0;
+}
+
+QPainter *QPaintDevice::sharedPainter() const
+{
+ return 0;
+}
+
Q_GUI_EXPORT int qt_paint_device_metric(const QPaintDevice *device, QPaintDevice::PaintDeviceMetric metric)
{
return device->metric(metric);
diff --git a/src/gui/painting/qpaintdevice.h b/src/gui/painting/qpaintdevice.h
index 3ebc24ee14..95509a9daa 100644
--- a/src/gui/painting/qpaintdevice.h
+++ b/src/gui/painting/qpaintdevice.h
@@ -79,15 +79,6 @@ public:
bool paintingActive() const;
virtual QPaintEngine *paintEngine() const = 0;
-#if defined(Q_WS_QWS)
- static QWSDisplay *qwsDisplay();
-#endif
-
-#ifdef Q_WS_WIN
- virtual HDC getDC() const;
- virtual void releaseDC(HDC hdc) const;
-#endif
-
int width() const { return metric(PdmWidth); }
int height() const { return metric(PdmHeight); }
int widthMM() const { return metric(PdmWidthMM); }
@@ -96,70 +87,28 @@ public:
int logicalDpiY() const { return metric(PdmDpiY); }
int physicalDpiX() const { return metric(PdmPhysicalDpiX); }
int physicalDpiY() const { return metric(PdmPhysicalDpiY); }
-#ifdef QT_DEPRECATED
- QT_DEPRECATED int numColors() const { return metric(PdmNumColors); }
-#endif
int colorCount() const { return metric(PdmNumColors); }
int depth() const { return metric(PdmDepth); }
protected:
QPaintDevice();
virtual int metric(PaintDeviceMetric metric) const;
+ virtual void init(QPainter *painter) const;
+ virtual QPaintDevice *redirected(QPoint *offset) const;
+ virtual QPainter *sharedPainter() const;
ushort painters; // refcount
private:
Q_DISABLE_COPY(QPaintDevice)
-#if defined(Q_WS_X11) && defined(QT3_SUPPORT)
-public:
- QT3_SUPPORT Display *x11Display() const;
- QT3_SUPPORT int x11Screen() const;
- QT3_SUPPORT int x11Depth() const;
- QT3_SUPPORT int x11Cells() const;
- QT3_SUPPORT Qt::HANDLE x11Colormap() const;
- QT3_SUPPORT bool x11DefaultColormap() const;
- QT3_SUPPORT void *x11Visual() const;
- QT3_SUPPORT bool x11DefaultVisual() const;
-
- static QT3_SUPPORT Display *x11AppDisplay();
- static QT3_SUPPORT int x11AppScreen();
- static QT3_SUPPORT int x11AppDepth(int screen = -1);
- static QT3_SUPPORT int x11AppCells(int screen = -1);
- static QT3_SUPPORT Qt::HANDLE x11AppRootWindow(int screen = -1);
- static QT3_SUPPORT Qt::HANDLE x11AppColormap(int screen = -1);
- static QT3_SUPPORT void *x11AppVisual(int screen = -1);
- static QT3_SUPPORT bool x11AppDefaultColormap(int screen =-1);
- static QT3_SUPPORT bool x11AppDefaultVisual(int screen =-1);
- static QT3_SUPPORT int x11AppDpiX(int screen = -1);
- static QT3_SUPPORT int x11AppDpiY(int screen = -1);
- static QT3_SUPPORT void x11SetAppDpiX(int, int);
- static QT3_SUPPORT void x11SetAppDpiY(int, int);
-#endif
-
friend class QPainter;
+ friend class QPainterPrivate;
friend class QFontEngineMac;
friend class QX11PaintEngine;
friend Q_GUI_EXPORT int qt_paint_device_metric(const QPaintDevice *device, PaintDeviceMetric metric);
};
-#ifdef QT3_SUPPORT
-QT3_SUPPORT Q_GUI_EXPORT
-void bitBlt(QPaintDevice *dst, int dx, int dy,
- const QPaintDevice *src, int sx=0, int sy=0, int sw=-1, int sh=-1,
- bool ignoreMask=false);
-
-QT3_SUPPORT Q_GUI_EXPORT
-void bitBlt(QPaintDevice *dst, int dx, int dy,
- const QImage *src, int sx=0, int sy=0, int sw=-1, int sh=-1,
- int conversion_flags=0);
-
-QT3_SUPPORT Q_GUI_EXPORT
-void bitBlt(QPaintDevice *dst, const QPoint &dp,
- const QPaintDevice *src, const QRect &sr=QRect(0,0,-1,-1),
- bool ignoreMask=false);
-#endif
-
/*****************************************************************************
Inline functions
*****************************************************************************/
diff --git a/src/gui/painting/qpaintdevice_mac.cpp b/src/gui/painting/qpaintdevice_mac.cpp
deleted file mode 100644
index 56cf8dc5a8..0000000000
--- a/src/gui/painting/qpaintdevice_mac.cpp
+++ /dev/null
@@ -1,152 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qpaintdevice.h"
-#include "qpainter.h"
-#include "qwidget.h"
-#include "qbitmap.h"
-#include "qapplication.h"
-#include "qprinter.h"
-#include <qdebug.h>
-#include <private/qt_mac_p.h>
-#include <private/qprintengine_mac_p.h>
-#include <private/qpixmap_mac_p.h>
-#include <private/qpixmap_raster_p.h>
-
-QT_BEGIN_NAMESPACE
-
-/*****************************************************************************
- Internal variables and functions
- *****************************************************************************/
-
-/*! \internal */
-float qt_mac_defaultDpi_x()
-{
- // Mac OS X currently assumes things to be 72 dpi.
- // (see http://developer.apple.com/releasenotes/GraphicsImaging/RN-ResolutionIndependentUI/)
- // This may need to be re-worked as we go further in the resolution-independence stuff.
- return 72;
-}
-
-/*! \internal */
-float qt_mac_defaultDpi_y()
-{
- // Mac OS X currently assumes things to be 72 dpi.
- // (see http://developer.apple.com/releasenotes/GraphicsImaging/RN-ResolutionIndependentUI/)
- // This may need to be re-worked as we go further in the resolution-independence stuff.
- return 72;
-}
-
-
-/*! \internal
-
- Returns the QuickDraw CGrafPtr of the paint device. 0 is returned
- if it can't be obtained. Do not hold the pointer around for long
- as it can be relocated.
-
- \warning This function is only available on Mac OS X.
-*/
-
-Q_GUI_EXPORT GrafPtr qt_mac_qd_context(const QPaintDevice *device)
-{
- if (device->devType() == QInternal::Pixmap) {
- return static_cast<GrafPtr>(static_cast<const QPixmap *>(device)->macQDHandle());
- } else if(device->devType() == QInternal::Widget) {
- return static_cast<GrafPtr>(static_cast<const QWidget *>(device)->macQDHandle());
- } else if(device->devType() == QInternal::Printer) {
- QPaintEngine *engine = static_cast<const QPrinter *>(device)->paintEngine();
- return static_cast<GrafPtr>(static_cast<const QMacPrintEngine *>(engine)->handle());
- }
- return 0;
-}
-
-extern CGColorSpaceRef qt_mac_colorSpaceForDeviceType(const QPaintDevice *pdev);
-
-/*! \internal
-
- Returns the CoreGraphics CGContextRef of the paint device. 0 is
- returned if it can't be obtained. It is the caller's responsiblity to
- CGContextRelease the context when finished using it.
-
- \warning This function is only available on Mac OS X.
-*/
-
-Q_GUI_EXPORT CGContextRef qt_mac_cg_context(const QPaintDevice *pdev)
-{
- if (pdev->devType() == QInternal::Pixmap) {
- const QPixmap *pm = static_cast<const QPixmap*>(pdev);
- CGColorSpaceRef colorspace = qt_mac_colorSpaceForDeviceType(pdev);
- uint flags = kCGImageAlphaPremultipliedFirst;
-#ifdef kCGBitmapByteOrder32Host //only needed because CGImage.h added symbols in the minor version
- flags |= kCGBitmapByteOrder32Host;
-#endif
- CGContextRef ret = 0;
-
- // It would make sense to put this into a mac #ifdef'ed
- // virtual function in the QPixmapData at some point
- if (pm->data->classId() == QPixmapData::MacClass) {
- const QMacPixmapData *pmData = static_cast<const QMacPixmapData*>(pm->data.data());
- ret = CGBitmapContextCreate(pmData->pixels, pmData->w, pmData->h,
- 8, pmData->bytesPerRow, colorspace,
- flags);
- if(!ret)
- qWarning("QPaintDevice: Unable to create context for pixmap (%d/%d/%d)",
- pmData->w, pmData->h, (pmData->bytesPerRow * pmData->h));
- } else if (pm->data->classId() == QPixmapData::RasterClass) {
- QImage *image = pm->data->buffer();
- ret = CGBitmapContextCreate(image->bits(), image->width(), image->height(),
- 8, image->bytesPerLine(), colorspace, flags);
- }
-
- CGContextTranslateCTM(ret, 0, pm->height());
- CGContextScaleCTM(ret, 1, -1);
- return ret;
- } else if (pdev->devType() == QInternal::Widget) {
- CGContextRef ret = static_cast<CGContextRef>(static_cast<const QWidget *>(pdev)->macCGHandle());
- CGContextRetain(ret);
- return ret;
- } else if (pdev->devType() == QInternal::MacQuartz) {
- return static_cast<const QMacQuartzPaintDevice *>(pdev)->cgContext();
- }
- return 0;
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/painting/qpaintdevice_qpa.cpp b/src/gui/painting/qpaintdevice_qpa.cpp
index 813965feb1..65eeaaa7e8 100644
--- a/src/gui/painting/qpaintdevice_qpa.cpp
+++ b/src/gui/painting/qpaintdevice_qpa.cpp
@@ -41,14 +41,11 @@
#include "qpaintdevice.h"
#include "qpainter.h"
-#include "qwidget.h"
#include "qbitmap.h"
-#include "qapplication.h"
+#include "qguiapplication.h"
QT_BEGIN_NAMESPACE
-extern void qt_painter_removePaintDevice(QPaintDevice *); //qpainter.cpp
-
int QPaintDevice::metric(PaintDeviceMetric m) const
{
qWarning("QPaintDevice::metrics: Device has no metric information");
diff --git a/src/gui/painting/qpaintdevice_qws.cpp b/src/gui/painting/qpaintdevice_qws.cpp
deleted file mode 100644
index 9d5ba6e850..0000000000
--- a/src/gui/painting/qpaintdevice_qws.cpp
+++ /dev/null
@@ -1,56 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qpaintdevice.h"
-#include "qpainter.h"
-#include "qwidget.h"
-#include "qbitmap.h"
-#include "qapplication.h"
-#include "qwsdisplay_qws.h"
-
-QT_BEGIN_NAMESPACE
-
-QWSDisplay *QPaintDevice::qwsDisplay()
-{
- return qt_fbdpy;
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/painting/qpaintdevice_x11.cpp b/src/gui/painting/qpaintdevice_x11.cpp
deleted file mode 100644
index 42e61e855b..0000000000
--- a/src/gui/painting/qpaintdevice_x11.cpp
+++ /dev/null
@@ -1,198 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qpaintdevice.h"
-#include "qpainter.h"
-#include "qwidget.h"
-#include "qbitmap.h"
-#include "qapplication.h"
-#include <private/qt_x11_p.h>
-#include "qx11info_x11.h"
-
-QT_BEGIN_NAMESPACE
-
-/*! \internal
-
- Returns the X11 Drawable of the paint device. 0 is returned if it
- can't be obtained.
-*/
-
-Drawable Q_GUI_EXPORT qt_x11Handle(const QPaintDevice *pd)
-{
- if (!pd) return 0;
- if (pd->devType() == QInternal::Widget)
- return static_cast<const QWidget *>(pd)->handle();
- else if (pd->devType() == QInternal::Pixmap)
- return static_cast<const QPixmap *>(pd)->handle();
- return 0;
-}
-
-/*!
- \relates QPaintDevice
-
- Returns the QX11Info structure for the \a pd paint device. 0 is
- returned if it can't be obtained.
-*/
-const Q_GUI_EXPORT QX11Info *qt_x11Info(const QPaintDevice *pd)
-{
- if (!pd) return 0;
- if (pd->devType() == QInternal::Widget)
- return &static_cast<const QWidget *>(pd)->x11Info();
- else if (pd->devType() == QInternal::Pixmap)
- return &static_cast<const QPixmap *>(pd)->x11Info();
- return 0;
-}
-
-
-
-#ifdef QT3_SUPPORT
-
-Display *QPaintDevice::x11Display() const
-{
- return X11->display;
-}
-
-int QPaintDevice::x11Screen() const
-{
- const QX11Info *info = qt_x11Info(this);
- if (info)
- return info->screen();
- return QX11Info::appScreen();
-}
-
-void *QPaintDevice::x11Visual() const
-{
- const QX11Info *info = qt_x11Info(this);
- if (info)
- return info->visual();
- return QX11Info::appVisual();
-}
-
-int QPaintDevice::x11Depth() const
-{
- const QX11Info *info = qt_x11Info(this);
- if (info)
- return info->depth();
- return QX11Info::appDepth();
-}
-
-int QPaintDevice::x11Cells() const
-{
- const QX11Info *info = qt_x11Info(this);
- if (info)
- return info->cells();
- return QX11Info::appCells();
-}
-
-Qt::HANDLE QPaintDevice::x11Colormap() const
-{
- const QX11Info *info = qt_x11Info(this);
- if (info)
- return info->colormap();
- return QX11Info::appColormap();
-}
-
-bool QPaintDevice::x11DefaultColormap() const
-{
- const QX11Info *info = qt_x11Info(this);
- if (info)
- return info->defaultColormap();
- return QX11Info::appDefaultColormap();
-}
-
-bool QPaintDevice::x11DefaultVisual() const
-{
- const QX11Info *info = qt_x11Info(this);
- if (info)
- return info->defaultVisual();
- return QX11Info::appDefaultVisual();
-}
-
-void *QPaintDevice::x11AppVisual(int screen)
-{ return QX11Info::appVisual(screen); }
-
-Qt::HANDLE QPaintDevice::x11AppColormap(int screen)
-{ return QX11Info::appColormap(screen); }
-
-Display *QPaintDevice::x11AppDisplay()
-{ return QX11Info::display(); }
-
-int QPaintDevice::x11AppScreen()
-{ return QX11Info::appScreen(); }
-
-int QPaintDevice::x11AppDepth(int screen)
-{ return QX11Info::appDepth(screen); }
-
-int QPaintDevice::x11AppCells(int screen)
-{ return QX11Info::appCells(screen); }
-
-Qt::HANDLE QPaintDevice::x11AppRootWindow(int screen)
-{ return QX11Info::appRootWindow(screen); }
-
-bool QPaintDevice::x11AppDefaultColormap(int screen)
-{ return QX11Info::appDefaultColormap(screen); }
-
-bool QPaintDevice::x11AppDefaultVisual(int screen)
-{ return QX11Info::appDefaultVisual(screen); }
-
-void QPaintDevice::x11SetAppDpiX(int dpi, int screen)
-{
- QX11Info::setAppDpiX(dpi, screen);
-}
-
-void QPaintDevice::x11SetAppDpiY(int dpi, int screen)
-{
- QX11Info::setAppDpiY(dpi, screen);
-}
-
-int QPaintDevice::x11AppDpiX(int screen)
-{
- return QX11Info::appDpiX(screen);
-}
-
-int QPaintDevice::x11AppDpiY(int screen)
-{
- return QX11Info::appDpiY(screen);
-}
-#endif
-
-
-QT_END_NAMESPACE
diff --git a/src/gui/painting/qpaintengine.cpp b/src/gui/painting/qpaintengine.cpp
index c46513a07c..f64bd52ec2 100644
--- a/src/gui/painting/qpaintengine.cpp
+++ b/src/gui/painting/qpaintengine.cpp
@@ -43,9 +43,9 @@
#include "qpainter_p.h"
#include "qpolygon.h"
#include "qbitmap.h"
-#include "qapplication.h"
#include <qdebug.h>
#include <qmath.h>
+#include <qguiapplication.h>
#include <private/qtextengine_p.h>
#include <qvarlengtharray.h>
#include <private/qfontengine_p.h>
@@ -139,7 +139,7 @@ QString QTextItem::text() const
QFont QTextItem::font() const
{
const QTextItemInt *ti = static_cast<const QTextItemInt *>(this);
- return ti->f ? *ti->f : QApplication::font();
+ return ti->f ? *ti->f : QGuiApplication::font();
}
@@ -154,7 +154,7 @@ QFont QTextItem::font() const
different painter backends we support. We provide one paint engine for each
window system and painting framework we support. This includes X11 on
Unix/Linux and CoreGraphics on Mac OS X. In addition we provide QPaintEngine
- implementations for OpenGL (accessible through QGLWidget) and PostScript
+ implementations for OpenGL (accessible through QOpenGLWidget) and PostScript
(accessible through QPSPrinter on X11). Additionally there is a raster-based
paint engine that is a fallback for when an engine does not support a certain
capability.
diff --git a/src/gui/painting/qpaintengine.h b/src/gui/painting/qpaintengine.h
index 6befdd8ac7..49ceb2a8b3 100644
--- a/src/gui/painting/qpaintengine.h
+++ b/src/gui/painting/qpaintengine.h
@@ -282,7 +282,7 @@ private:
friend class QWin32PaintEnginePrivate;
friend class QMacCGContext;
friend class QPreviewPaintEngine;
- friend class QX11GLPixmapData;
+ friend class QX11GLPlatformPixmap;
};
diff --git a/src/gui/painting/qpaintengine_blitter.cpp b/src/gui/painting/qpaintengine_blitter.cpp
index 75efa20804..0e9a17a183 100644
--- a/src/gui/painting/qpaintengine_blitter.cpp
+++ b/src/gui/painting/qpaintengine_blitter.cpp
@@ -44,7 +44,6 @@
#include "private/qblittable_p.h"
#include "private/qpaintengine_raster_p.h"
#include "private/qpainter_p.h"
-#include "private/qapplication_p.h"
#include "private/qpixmap_blitter_p.h"
#ifndef QT_NO_BLITTABLE
@@ -112,7 +111,7 @@ public:
bool canBlitterDrawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) const
{
- if (pm.pixmapData()->classId() != QPixmapData::BlitterClass)
+ if (pm.handle()->classId() != QPlatformPixmap::BlitterClass)
return false;
if (checkStateAgainstMask(capabillitiesState,drawPixmapMask)) {
if (m_capabilities & (QBlittable::SourceOverPixmapCapability
@@ -191,7 +190,7 @@ class QBlitterPaintEnginePrivate : public QPaintEngineExPrivate
{
Q_DECLARE_PUBLIC(QBlitterPaintEngine);
public:
- QBlitterPaintEnginePrivate(QBlittablePixmapData *p)
+ QBlitterPaintEnginePrivate(QBlittablePlatformPixmap *p)
: QPaintEngineExPrivate(),
pmData(p),
isBlitterLocked(false),
@@ -281,7 +280,7 @@ public:
QRasterPaintEngine *raster;
- QBlittablePixmapData *pmData;
+ QBlittablePlatformPixmap *pmData;
bool isBlitterLocked;
CapabilitiesToStateMask *capabillities;
@@ -289,7 +288,7 @@ public:
uint hasXForm;
};
-QBlitterPaintEngine::QBlitterPaintEngine(QBlittablePixmapData *p)
+QBlitterPaintEngine::QBlitterPaintEngine(QBlittablePlatformPixmap *p)
: QPaintEngineEx(*(new QBlitterPaintEnginePrivate(p)))
{
}
diff --git a/src/gui/painting/qpaintengine_blitter_p.h b/src/gui/painting/qpaintengine_blitter_p.h
index afd7486dc2..1acc647fbe 100644
--- a/src/gui/painting/qpaintengine_blitter_p.h
+++ b/src/gui/painting/qpaintengine_blitter_p.h
@@ -49,14 +49,14 @@
QT_BEGIN_NAMESPACE
class QBlitterPaintEnginePrivate;
-class QBlittablePixmapData;
+class QBlittablePlatformPixmap;
class QBlittable;
class Q_GUI_EXPORT QBlitterPaintEngine : public QPaintEngineEx
{
Q_DECLARE_PRIVATE(QBlitterPaintEngine);
public:
- QBlitterPaintEngine(QBlittablePixmapData *p);
+ QBlitterPaintEngine(QBlittablePlatformPixmap *p);
~QBlitterPaintEngine();
virtual QPainterState *createState(QPainterState *orig) const;
diff --git a/src/gui/painting/qpaintengine_mac.cpp b/src/gui/painting/qpaintengine_mac.cpp
deleted file mode 100644
index 0d459a5d89..0000000000
--- a/src/gui/painting/qpaintengine_mac.cpp
+++ /dev/null
@@ -1,1747 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qbitmap.h>
-#include <qpaintdevice.h>
-#include <private/qpaintengine_mac_p.h>
-#include <qpainterpath.h>
-#include <qpixmapcache.h>
-#include <private/qpaintengine_raster_p.h>
-#include <private/qprintengine_mac_p.h>
-#include <qprinter.h>
-#include <qstack.h>
-#include <qtextcodec.h>
-#include <qwidget.h>
-#include <qvarlengtharray.h>
-#include <qdebug.h>
-#include <qcoreapplication.h>
-#include <qmath.h>
-
-#include <private/qfont_p.h>
-#include <private/qfontengine_p.h>
-#include <private/qfontengine_coretext_p.h>
-#include <private/qfontengine_mac_p.h>
-#include <private/qnumeric_p.h>
-#include <private/qpainter_p.h>
-#include <private/qpainterpath_p.h>
-#include <private/qpixmap_mac_p.h>
-#include <private/qt_mac_p.h>
-#include <private/qtextengine_p.h>
-#include <private/qwidget_p.h>
-#include <private/qt_cocoa_helpers_mac_p.h>
-
-#include <string.h>
-
-QT_BEGIN_NAMESPACE
-
-extern int qt_antialiasing_threshold; // QApplication.cpp
-
-/*****************************************************************************
- External functions
- *****************************************************************************/
-extern CGImageRef qt_mac_create_imagemask(const QPixmap &px, const QRectF &sr); //qpixmap_mac.cpp
-extern QPoint qt_mac_posInWindow(const QWidget *w); //qwidget_mac.cpp
-extern OSWindowRef qt_mac_window_for(const QWidget *); //qwidget_mac.cpp
-extern CGContextRef qt_mac_cg_context(const QPaintDevice *); //qpaintdevice_mac.cpp
-extern void qt_mac_dispose_rgn(RgnHandle r); //qregion_mac.cpp
-extern QPixmap qt_pixmapForBrush(int, bool); //qbrush.cpp
-
-void qt_mac_clip_cg(CGContextRef hd, const QRegion &rgn, CGAffineTransform *orig_xform);
-
-
-//Implemented for qt_mac_p.h
-QMacCGContext::QMacCGContext(QPainter *p)
-{
- QPaintEngine *pe = p->paintEngine();
- if (pe->type() == QPaintEngine::MacPrinter)
- pe = static_cast<QMacPrintEngine*>(pe)->paintEngine();
- pe->syncState();
- context = 0;
- if(pe->type() == QPaintEngine::CoreGraphics)
- context = static_cast<QCoreGraphicsPaintEngine*>(pe)->handle();
-
- int devType = p->device()->devType();
- if (pe->type() == QPaintEngine::Raster
- && (devType == QInternal::Widget ||
- devType == QInternal::Pixmap ||
- devType == QInternal::Image)) {
-
- extern CGColorSpaceRef qt_mac_colorSpaceForDeviceType(const QPaintDevice *paintDevice);
- CGColorSpaceRef colorspace = qt_mac_colorSpaceForDeviceType(pe->paintDevice());
- uint flags = kCGImageAlphaPremultipliedFirst;
-#ifdef kCGBitmapByteOrder32Host //only needed because CGImage.h added symbols in the minor version
- flags |= kCGBitmapByteOrder32Host;
-#endif
- const QImage *image = (const QImage *) pe->paintDevice();
-
- context = CGBitmapContextCreate((void *) image->bits(), image->width(), image->height(),
- 8, image->bytesPerLine(), colorspace, flags);
-
- CGContextTranslateCTM(context, 0, image->height());
- CGContextScaleCTM(context, 1, -1);
-
- if (devType == QInternal::Widget) {
- QRegion clip = p->paintEngine()->systemClip();
- QTransform native = p->deviceTransform();
- QTransform logical = p->combinedTransform();
-
- if (p->hasClipping()) {
- QRegion r = p->clipRegion();
- r.translate(native.dx(), native.dy());
- if (clip.isEmpty())
- clip = r;
- else
- clip &= r;
- }
- qt_mac_clip_cg(context, clip, 0);
-
- CGContextTranslateCTM(context, native.dx(), native.dy());
- }
- } else {
- CGContextRetain(context);
- }
-}
-
-
-/*****************************************************************************
- QCoreGraphicsPaintEngine utility functions
- *****************************************************************************/
-
-//conversion
-inline static float qt_mac_convert_color_to_cg(int c) { return ((float)c * 1000 / 255) / 1000; }
-inline static int qt_mac_convert_color_from_cg(float c) { return qRound(c * 255); }
-CGAffineTransform qt_mac_convert_transform_to_cg(const QTransform &t) {
- return CGAffineTransformMake(t.m11(), t.m12(), t.m21(), t.m22(), t.dx(), t.dy());
-}
-
-CGColorSpaceRef qt_mac_colorSpaceForDeviceType(const QPaintDevice *paintDevice)
-{
- bool isWidget = (paintDevice->devType() == QInternal::Widget);
- return QCoreGraphicsPaintEngine::macDisplayColorSpace(isWidget ? static_cast<const QWidget *>(paintDevice)
- : 0);
-}
-
-inline static QCFType<CGColorRef> cgColorForQColor(const QColor &col, QPaintDevice *pdev)
-{
- CGFloat components[] = {
- qt_mac_convert_color_to_cg(col.red()),
- qt_mac_convert_color_to_cg(col.green()),
- qt_mac_convert_color_to_cg(col.blue()),
- qt_mac_convert_color_to_cg(col.alpha())
- };
- return CGColorCreate(qt_mac_colorSpaceForDeviceType(pdev), components);
-}
-
-// There's architectural problems with using native gradients
-// on the Mac at the moment, so disable them.
-// #define QT_MAC_USE_NATIVE_GRADIENTS
-
-#ifdef QT_MAC_USE_NATIVE_GRADIENTS
-static bool drawGradientNatively(const QGradient *gradient)
-{
- return gradient->spread() == QGradient::PadSpread;
-}
-
-// gradiant callback
-static void qt_mac_color_gradient_function(void *info, const CGFloat *in, CGFloat *out)
-{
- QBrush *brush = static_cast<QBrush *>(info);
- Q_ASSERT(brush && brush->gradient());
-
- const QGradientStops stops = brush->gradient()->stops();
- const int n = stops.count();
- Q_ASSERT(n >= 1);
- const QGradientStop *begin = stops.constBegin();
- const QGradientStop *end = begin + n;
-
- qreal p = in[0];
- const QGradientStop *i = begin;
- while (i != end && i->first < p)
- ++i;
-
- QRgb c;
- if (i == begin) {
- c = begin->second.rgba();
- } else if (i == end) {
- c = (end - 1)->second.rgba();
- } else {
- const QGradientStop &s1 = *(i - 1);
- const QGradientStop &s2 = *i;
- qreal p1 = s1.first;
- qreal p2 = s2.first;
- QRgb c1 = s1.second.rgba();
- QRgb c2 = s2.second.rgba();
- int idist = 256 * (p - p1) / (p2 - p1);
- int dist = 256 - idist;
- c = qRgba(INTERPOLATE_PIXEL_256(qRed(c1), dist, qRed(c2), idist),
- INTERPOLATE_PIXEL_256(qGreen(c1), dist, qGreen(c2), idist),
- INTERPOLATE_PIXEL_256(qBlue(c1), dist, qBlue(c2), idist),
- INTERPOLATE_PIXEL_256(qAlpha(c1), dist, qAlpha(c2), idist));
- }
-
- out[0] = qt_mac_convert_color_to_cg(qRed(c));
- out[1] = qt_mac_convert_color_to_cg(qGreen(c));
- out[2] = qt_mac_convert_color_to_cg(qBlue(c));
- out[3] = qt_mac_convert_color_to_cg(qAlpha(c));
-}
-#endif
-
-//clipping handling
-void QCoreGraphicsPaintEnginePrivate::resetClip()
-{
- static bool inReset = false;
- if (inReset)
- return;
- inReset = true;
-
- CGAffineTransform old_xform = CGContextGetCTM(hd);
-
- //setup xforms
- CGContextConcatCTM(hd, CGAffineTransformInvert(old_xform));
- while (stackCount > 0) {
- restoreGraphicsState();
- }
- saveGraphicsState();
- inReset = false;
- //reset xforms
- CGContextConcatCTM(hd, CGAffineTransformInvert(CGContextGetCTM(hd)));
- CGContextConcatCTM(hd, old_xform);
-}
-
-static CGRect qt_mac_compose_rect(const QRectF &r, float off=0)
-{
- return CGRectMake(r.x()+off, r.y()+off, r.width(), r.height());
-}
-
-static CGMutablePathRef qt_mac_compose_path(const QPainterPath &p, float off=0)
-{
- CGMutablePathRef ret = CGPathCreateMutable();
- QPointF startPt;
- for (int i=0; i<p.elementCount(); ++i) {
- const QPainterPath::Element &elm = p.elementAt(i);
- switch (elm.type) {
- case QPainterPath::MoveToElement:
- if(i > 0
- && p.elementAt(i - 1).x == startPt.x()
- && p.elementAt(i - 1).y == startPt.y())
- CGPathCloseSubpath(ret);
- startPt = QPointF(elm.x, elm.y);
- CGPathMoveToPoint(ret, 0, elm.x+off, elm.y+off);
- break;
- case QPainterPath::LineToElement:
- CGPathAddLineToPoint(ret, 0, elm.x+off, elm.y+off);
- break;
- case QPainterPath::CurveToElement:
- Q_ASSERT(p.elementAt(i+1).type == QPainterPath::CurveToDataElement);
- Q_ASSERT(p.elementAt(i+2).type == QPainterPath::CurveToDataElement);
- CGPathAddCurveToPoint(ret, 0,
- elm.x+off, elm.y+off,
- p.elementAt(i+1).x+off, p.elementAt(i+1).y+off,
- p.elementAt(i+2).x+off, p.elementAt(i+2).y+off);
- i+=2;
- break;
- default:
- qFatal("QCoreGraphicsPaintEngine::drawPath(), unhandled type: %d", elm.type);
- break;
- }
- }
- if(!p.isEmpty()
- && p.elementAt(p.elementCount() - 1).x == startPt.x()
- && p.elementAt(p.elementCount() - 1).y == startPt.y())
- CGPathCloseSubpath(ret);
- return ret;
-}
-
-CGColorSpaceRef QCoreGraphicsPaintEngine::m_genericColorSpace = 0;
-QHash<CGDirectDisplayID, CGColorSpaceRef> QCoreGraphicsPaintEngine::m_displayColorSpaceHash;
-bool QCoreGraphicsPaintEngine::m_postRoutineRegistered = false;
-
-CGColorSpaceRef QCoreGraphicsPaintEngine::macGenericColorSpace()
-{
-#if 0
- if (!m_genericColorSpace) {
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
- if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4) {
- m_genericColorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
- } else
-#endif
- {
- m_genericColorSpace = CGColorSpaceCreateDeviceRGB();
- }
- if (!m_postRoutineRegistered) {
- m_postRoutineRegistered = true;
- qAddPostRoutine(QCoreGraphicsPaintEngine::cleanUpMacColorSpaces);
- }
- }
- return m_genericColorSpace;
-#else
- // Just return the main display colorspace for the moment.
- return macDisplayColorSpace();
-#endif
-}
-
-/*
- Ideally, we should pass the widget in here, and use CGGetDisplaysWithRect() etc.
- to support multiple displays correctly.
-*/
-CGColorSpaceRef QCoreGraphicsPaintEngine::macDisplayColorSpace(const QWidget *widget)
-{
- CGColorSpaceRef colorSpace;
-
- CGDirectDisplayID displayID;
- CMProfileRef displayProfile = 0;
- if (widget == 0) {
- displayID = CGMainDisplayID();
- } else {
- const QRect &qrect = widget->window()->geometry();
- CGRect rect = CGRectMake(qrect.x(), qrect.y(), qrect.width(), qrect.height());
- CGDisplayCount throwAway;
- CGDisplayErr dErr = CGGetDisplaysWithRect(rect, 1, &displayID, &throwAway);
- if (dErr != kCGErrorSuccess)
- return macDisplayColorSpace(0); // fall back on main display
- }
- if ((colorSpace = m_displayColorSpaceHash.value(displayID)))
- return colorSpace;
-
- CMError err = CMGetProfileByAVID((CMDisplayIDType)displayID, &displayProfile);
- if (err == noErr) {
- colorSpace = CGColorSpaceCreateWithPlatformColorSpace(displayProfile);
- } else if (widget) {
- return macDisplayColorSpace(0); // fall back on main display
- }
-
- if (colorSpace == 0)
- colorSpace = CGColorSpaceCreateDeviceRGB();
-
- m_displayColorSpaceHash.insert(displayID, colorSpace);
- CMCloseProfile(displayProfile);
- if (!m_postRoutineRegistered) {
- m_postRoutineRegistered = true;
- qAddPostRoutine(QCoreGraphicsPaintEngine::cleanUpMacColorSpaces);
- }
- return colorSpace;
-}
-
-void QCoreGraphicsPaintEngine::cleanUpMacColorSpaces()
-{
- if (m_genericColorSpace) {
- CFRelease(m_genericColorSpace);
- m_genericColorSpace = 0;
- }
- QHash<CGDirectDisplayID, CGColorSpaceRef>::const_iterator it = m_displayColorSpaceHash.constBegin();
- while (it != m_displayColorSpaceHash.constEnd()) {
- if (it.value())
- CFRelease(it.value());
- ++it;
- }
- m_displayColorSpaceHash.clear();
-}
-
-void qt_mac_clip_cg(CGContextRef hd, const QRegion &rgn, CGAffineTransform *orig_xform)
-{
- CGAffineTransform old_xform = CGAffineTransformIdentity;
- if(orig_xform) { //setup xforms
- old_xform = CGContextGetCTM(hd);
- CGContextConcatCTM(hd, CGAffineTransformInvert(old_xform));
- CGContextConcatCTM(hd, *orig_xform);
- }
-
- //do the clipping
- CGContextBeginPath(hd);
- if(rgn.isEmpty()) {
- CGContextAddRect(hd, CGRectMake(0, 0, 0, 0));
- } else {
-#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
- if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) {
- QCFType<HIMutableShapeRef> shape = rgn.toHIMutableShape();
- Q_ASSERT(!HIShapeIsEmpty(shape));
- HIShapeReplacePathInCGContext(shape, hd);
- } else
-#endif
- {
- QVector<QRect> rects = rgn.rects();
- const int count = rects.size();
- for(int i = 0; i < count; i++) {
- const QRect &r = rects[i];
- CGRect mac_r = CGRectMake(r.x(), r.y(), r.width(), r.height());
- CGContextAddRect(hd, mac_r);
- }
- }
-
- }
- CGContextClip(hd);
-
- if(orig_xform) {//reset xforms
- CGContextConcatCTM(hd, CGAffineTransformInvert(CGContextGetCTM(hd)));
- CGContextConcatCTM(hd, old_xform);
- }
-}
-
-
-//pattern handling (tiling)
-#if 1
-# define QMACPATTERN_MASK_MULTIPLIER 32
-#else
-# define QMACPATTERN_MASK_MULTIPLIER 1
-#endif
-class QMacPattern
-{
-public:
- QMacPattern() : as_mask(false), pdev(0), image(0) { data.bytes = 0; }
- ~QMacPattern() { CGImageRelease(image); }
- int width() {
- if(image)
- return CGImageGetWidth(image);
- if(data.bytes)
- return 8*QMACPATTERN_MASK_MULTIPLIER;
- return data.pixmap.width();
- }
- int height() {
- if(image)
- return CGImageGetHeight(image);
- if(data.bytes)
- return 8*QMACPATTERN_MASK_MULTIPLIER;
- return data.pixmap.height();
- }
-
- //input
- QColor foreground;
- bool as_mask;
- struct {
- QPixmap pixmap;
- const uchar *bytes;
- } data;
- QPaintDevice *pdev;
- //output
- CGImageRef image;
-};
-static void qt_mac_draw_pattern(void *info, CGContextRef c)
-{
- QMacPattern *pat = (QMacPattern*)info;
- int w = 0, h = 0;
- bool isBitmap = (pat->data.pixmap.depth() == 1);
- if(!pat->image) { //lazy cache
- if(pat->as_mask) {
- Q_ASSERT(pat->data.bytes);
- w = h = 8;
-#if (QMACPATTERN_MASK_MULTIPLIER == 1)
- CGDataProviderRef provider = CGDataProviderCreateWithData(0, pat->data.bytes, w*h, 0);
- pat->image = CGImageMaskCreate(w, h, 1, 1, 1, provider, 0, false);
- CGDataProviderRelease(provider);
-#else
- const int numBytes = (w*h)/sizeof(uchar);
- uchar xor_bytes[numBytes];
- for(int i = 0; i < numBytes; ++i)
- xor_bytes[i] = pat->data.bytes[i] ^ 0xFF;
- CGDataProviderRef provider = CGDataProviderCreateWithData(0, xor_bytes, w*h, 0);
- CGImageRef swatch = CGImageMaskCreate(w, h, 1, 1, 1, provider, 0, false);
- CGDataProviderRelease(provider);
-
- const QColor c0(0, 0, 0, 0), c1(255, 255, 255, 255);
- QPixmap pm(w*QMACPATTERN_MASK_MULTIPLIER, h*QMACPATTERN_MASK_MULTIPLIER);
- pm.fill(c0);
- CGContextRef pm_ctx = qt_mac_cg_context(&pm);
- CGContextSetFillColorWithColor(c, cgColorForQColor(c1, pat->pdev));
- CGRect rect = CGRectMake(0, 0, w, h);
- for(int x = 0; x < QMACPATTERN_MASK_MULTIPLIER; ++x) {
- rect.origin.x = x * w;
- for(int y = 0; y < QMACPATTERN_MASK_MULTIPLIER; ++y) {
- rect.origin.y = y * h;
- qt_mac_drawCGImage(pm_ctx, &rect, swatch);
- }
- }
- pat->image = qt_mac_create_imagemask(pm, pm.rect());
- CGImageRelease(swatch);
- CGContextRelease(pm_ctx);
- w *= QMACPATTERN_MASK_MULTIPLIER;
- h *= QMACPATTERN_MASK_MULTIPLIER;
-#endif
- } else {
- w = pat->data.pixmap.width();
- h = pat->data.pixmap.height();
- if (isBitmap)
- pat->image = qt_mac_create_imagemask(pat->data.pixmap, pat->data.pixmap.rect());
- else
- pat->image = (CGImageRef)pat->data.pixmap.macCGHandle();
- }
- } else {
- w = CGImageGetWidth(pat->image);
- h = CGImageGetHeight(pat->image);
- }
-
- //draw
- bool needRestore = false;
- if (CGImageIsMask(pat->image)) {
- CGContextSaveGState(c);
- CGContextSetFillColorWithColor(c, cgColorForQColor(pat->foreground, pat->pdev));
- }
- CGRect rect = CGRectMake(0, 0, w, h);
- qt_mac_drawCGImage(c, &rect, pat->image);
- if(needRestore)
- CGContextRestoreGState(c);
-}
-static void qt_mac_dispose_pattern(void *info)
-{
- QMacPattern *pat = (QMacPattern*)info;
- delete pat;
-}
-
-/*****************************************************************************
- QCoreGraphicsPaintEngine member functions
- *****************************************************************************/
-
-inline static QPaintEngine::PaintEngineFeatures qt_mac_cg_features()
-{
- return QPaintEngine::PaintEngineFeatures(QPaintEngine::AllFeatures & ~QPaintEngine::PaintOutsidePaintEvent
- & ~QPaintEngine::PerspectiveTransform
- & ~QPaintEngine::ConicalGradientFill
- & ~QPaintEngine::LinearGradientFill
- & ~QPaintEngine::RadialGradientFill
- & ~QPaintEngine::BrushStroke);
-}
-
-QCoreGraphicsPaintEngine::QCoreGraphicsPaintEngine()
-: QPaintEngine(*(new QCoreGraphicsPaintEnginePrivate), qt_mac_cg_features())
-{
-}
-
-QCoreGraphicsPaintEngine::QCoreGraphicsPaintEngine(QPaintEnginePrivate &dptr)
-: QPaintEngine(dptr, qt_mac_cg_features())
-{
-}
-
-QCoreGraphicsPaintEngine::~QCoreGraphicsPaintEngine()
-{
-}
-
-bool
-QCoreGraphicsPaintEngine::begin(QPaintDevice *pdev)
-{
- Q_D(QCoreGraphicsPaintEngine);
- if(isActive()) { // already active painting
- qWarning("QCoreGraphicsPaintEngine::begin: Painter already active");
- return false;
- }
-
- //initialization
- d->pdev = pdev;
- d->complexXForm = false;
- d->cosmeticPen = QCoreGraphicsPaintEnginePrivate::CosmeticSetPenWidth;
- d->cosmeticPenSize = 1;
- d->current.clipEnabled = false;
- d->pixelSize = QPoint(1,1);
- d->hd = qt_mac_cg_context(pdev);
- if(d->hd) {
- d->saveGraphicsState();
- d->orig_xform = CGContextGetCTM(d->hd);
- if (d->shading) {
- CGShadingRelease(d->shading);
- d->shading = 0;
- }
- d->setClip(0); //clear the context's clipping
- }
-
- setActive(true);
-
- if(d->pdev->devType() == QInternal::Widget) { // device is a widget
- QWidget *w = (QWidget*)d->pdev;
- bool unclipped = w->testAttribute(Qt::WA_PaintUnclipped);
-
- if((w->windowType() == Qt::Desktop)) {
- if(!unclipped)
- qWarning("QCoreGraphicsPaintEngine::begin: Does not support clipped desktop on Mac OS X");
- // ## need to do [qt_mac_window_for(w) makeKeyAndOrderFront]; (need to rename the file)
- } else if(unclipped) {
- qWarning("QCoreGraphicsPaintEngine::begin: Does not support unclipped painting");
- }
- } else if(d->pdev->devType() == QInternal::Pixmap) { // device is a pixmap
- QPixmap *pm = (QPixmap*)d->pdev;
- if(pm->isNull()) {
- qWarning("QCoreGraphicsPaintEngine::begin: Cannot paint null pixmap");
- end();
- return false;
- }
- }
-
- setDirty(QPaintEngine::DirtyPen);
- setDirty(QPaintEngine::DirtyBrush);
- setDirty(QPaintEngine::DirtyBackground);
- setDirty(QPaintEngine::DirtyHints);
- return true;
-}
-
-bool
-QCoreGraphicsPaintEngine::end()
-{
- Q_D(QCoreGraphicsPaintEngine);
- setActive(false);
- if(d->pdev->devType() == QInternal::Widget && static_cast<QWidget*>(d->pdev)->windowType() == Qt::Desktop) {
-#ifndef QT_MAC_USE_COCOA
- HideWindow(qt_mac_window_for(static_cast<QWidget*>(d->pdev)));
-#else
-// // ### need to do [qt_mac_window_for(static_cast<QWidget *>(d->pdev)) orderOut]; (need to rename)
-#endif
-
- }
- if(d->shading) {
- CGShadingRelease(d->shading);
- d->shading = 0;
- }
- d->pdev = 0;
- if(d->hd) {
- d->restoreGraphicsState();
- CGContextSynchronize(d->hd);
- CGContextRelease(d->hd);
- d->hd = 0;
- }
- return true;
-}
-
-void
-QCoreGraphicsPaintEngine::updateState(const QPaintEngineState &state)
-{
- Q_D(QCoreGraphicsPaintEngine);
- QPaintEngine::DirtyFlags flags = state.state();
-
- if (flags & DirtyTransform)
- updateMatrix(state.transform());
-
- if (flags & DirtyClipEnabled) {
- if (state.isClipEnabled())
- updateClipPath(painter()->clipPath(), Qt::ReplaceClip);
- else
- updateClipPath(QPainterPath(), Qt::NoClip);
- }
-
- if (flags & DirtyClipPath) {
- updateClipPath(state.clipPath(), state.clipOperation());
- } else if (flags & DirtyClipRegion) {
- updateClipRegion(state.clipRegion(), state.clipOperation());
- }
-
- // If the clip has changed we need to update all other states
- // too, since they are included in the system context on OSX,
- // and changing the clip resets that context back to scratch.
- if (flags & (DirtyClipPath | DirtyClipRegion | DirtyClipEnabled))
- flags |= AllDirty;
-
- if (flags & DirtyPen)
- updatePen(state.pen());
- if (flags & (DirtyBrush|DirtyBrushOrigin))
- updateBrush(state.brush(), state.brushOrigin());
- if (flags & DirtyFont)
- updateFont(state.font());
- if (flags & DirtyOpacity)
- updateOpacity(state.opacity());
- if (flags & DirtyHints)
- updateRenderHints(state.renderHints());
- if (flags & DirtyCompositionMode)
- updateCompositionMode(state.compositionMode());
-
- if (flags & (DirtyPen | DirtyTransform)) {
- if (!d->current.pen.isCosmetic()) {
- d->cosmeticPen = QCoreGraphicsPaintEnginePrivate::CosmeticNone;
- } else if (d->current.transform.m11() < d->current.transform.m22()-1.0 ||
- d->current.transform.m11() > d->current.transform.m22()+1.0) {
- d->cosmeticPen = QCoreGraphicsPaintEnginePrivate::CosmeticTransformPath;
- d->cosmeticPenSize = d->adjustPenWidth(d->current.pen.widthF());
- if (!d->cosmeticPenSize)
- d->cosmeticPenSize = 1.0;
- } else {
- d->cosmeticPen = QCoreGraphicsPaintEnginePrivate::CosmeticSetPenWidth;
- static const float sqrt2 = sqrt(2);
- qreal width = d->current.pen.widthF();
- if (!width)
- width = 1;
- d->cosmeticPenSize = sqrt(pow(d->pixelSize.y(), 2) + pow(d->pixelSize.x(), 2)) / sqrt2 * width;
- }
- }
-}
-
-void
-QCoreGraphicsPaintEngine::updatePen(const QPen &pen)
-{
- Q_D(QCoreGraphicsPaintEngine);
- Q_ASSERT(isActive());
- d->current.pen = pen;
- d->setStrokePen(pen);
-}
-
-void
-QCoreGraphicsPaintEngine::updateBrush(const QBrush &brush, const QPointF &brushOrigin)
-{
- Q_D(QCoreGraphicsPaintEngine);
- Q_ASSERT(isActive());
- d->current.brush = brush;
-
-#ifdef QT_MAC_USE_NATIVE_GRADIENTS
- // Quartz supports only pad spread
- if (const QGradient *gradient = brush.gradient()) {
- if (drawGradientNatively(gradient)) {
- gccaps |= QPaintEngine::LinearGradientFill | QPaintEngine::RadialGradientFill;
- } else {
- gccaps &= ~(QPaintEngine::LinearGradientFill | QPaintEngine::RadialGradientFill);
- }
- }
-#endif
-
- if (d->shading) {
- CGShadingRelease(d->shading);
- d->shading = 0;
- }
- d->setFillBrush(brushOrigin);
-}
-
-void
-QCoreGraphicsPaintEngine::updateOpacity(qreal opacity)
-{
- Q_D(QCoreGraphicsPaintEngine);
- CGContextSetAlpha(d->hd, opacity);
-}
-
-void
-QCoreGraphicsPaintEngine::updateFont(const QFont &)
-{
- Q_D(QCoreGraphicsPaintEngine);
- Q_ASSERT(isActive());
- updatePen(d->current.pen);
-}
-
-void
-QCoreGraphicsPaintEngine::updateMatrix(const QTransform &transform)
-{
- Q_D(QCoreGraphicsPaintEngine);
- Q_ASSERT(isActive());
-
- if (qt_is_nan(transform.m11()) || qt_is_nan(transform.m12()) || qt_is_nan(transform.m13())
- || qt_is_nan(transform.m21()) || qt_is_nan(transform.m22()) || qt_is_nan(transform.m23())
- || qt_is_nan(transform.m31()) || qt_is_nan(transform.m32()) || qt_is_nan(transform.m33()))
- return;
-
- d->current.transform = transform;
- d->setTransform(transform.isIdentity() ? 0 : &transform);
- d->complexXForm = (transform.m11() != 1 || transform.m22() != 1
- || transform.m12() != 0 || transform.m21() != 0);
- d->pixelSize = d->devicePixelSize(d->hd);
-}
-
-void
-QCoreGraphicsPaintEngine::updateClipPath(const QPainterPath &p, Qt::ClipOperation op)
-{
- Q_D(QCoreGraphicsPaintEngine);
- Q_ASSERT(isActive());
- if(op == Qt::NoClip) {
- if(d->current.clipEnabled) {
- d->current.clipEnabled = false;
- d->current.clip = QRegion();
- d->setClip(0);
- }
- } else {
- if(!d->current.clipEnabled)
- op = Qt::ReplaceClip;
- d->current.clipEnabled = true;
- QRegion clipRegion(p.toFillPolygon().toPolygon(), p.fillRule());
- if(op == Qt::ReplaceClip) {
- d->current.clip = clipRegion;
- d->setClip(0);
- if(p.isEmpty()) {
- CGRect rect = CGRectMake(0, 0, 0, 0);
- CGContextClipToRect(d->hd, rect);
- } else {
- CGMutablePathRef path = qt_mac_compose_path(p);
- CGContextBeginPath(d->hd);
- CGContextAddPath(d->hd, path);
- if(p.fillRule() == Qt::WindingFill)
- CGContextClip(d->hd);
- else
- CGContextEOClip(d->hd);
- CGPathRelease(path);
- }
- } else if(op == Qt::IntersectClip) {
- d->current.clip = d->current.clip.intersected(clipRegion);
- d->setClip(&d->current.clip);
- }
- }
-}
-
-void
-QCoreGraphicsPaintEngine::updateClipRegion(const QRegion &clipRegion, Qt::ClipOperation op)
-{
- Q_D(QCoreGraphicsPaintEngine);
- Q_ASSERT(isActive());
- if(op == Qt::NoClip) {
- d->current.clipEnabled = false;
- d->current.clip = QRegion();
- d->setClip(0);
- } else {
- if(!d->current.clipEnabled)
- op = Qt::ReplaceClip;
- d->current.clipEnabled = true;
- if(op == Qt::IntersectClip)
- d->current.clip = d->current.clip.intersected(clipRegion);
- else if(op == Qt::ReplaceClip)
- d->current.clip = clipRegion;
- d->setClip(&d->current.clip);
- }
-}
-
-void
-QCoreGraphicsPaintEngine::drawPath(const QPainterPath &p)
-{
- Q_D(QCoreGraphicsPaintEngine);
- Q_ASSERT(isActive());
-
- if (state->compositionMode() == QPainter::CompositionMode_Destination)
- return;
-
- CGMutablePathRef path = qt_mac_compose_path(p);
- uchar ops = QCoreGraphicsPaintEnginePrivate::CGStroke;
- if(p.fillRule() == Qt::WindingFill)
- ops |= QCoreGraphicsPaintEnginePrivate::CGFill;
- else
- ops |= QCoreGraphicsPaintEnginePrivate::CGEOFill;
- CGContextBeginPath(d->hd);
- d->drawPath(ops, path);
- CGPathRelease(path);
-}
-
-void
-QCoreGraphicsPaintEngine::drawRects(const QRectF *rects, int rectCount)
-{
- Q_D(QCoreGraphicsPaintEngine);
- Q_ASSERT(isActive());
-
- if (state->compositionMode() == QPainter::CompositionMode_Destination)
- return;
-
- for (int i=0; i<rectCount; ++i) {
- QRectF r = rects[i];
-
- CGMutablePathRef path = CGPathCreateMutable();
- CGPathAddRect(path, 0, qt_mac_compose_rect(r));
- d->drawPath(QCoreGraphicsPaintEnginePrivate::CGFill|QCoreGraphicsPaintEnginePrivate::CGStroke,
- path);
- CGPathRelease(path);
- }
-}
-
-void
-QCoreGraphicsPaintEngine::drawPoints(const QPointF *points, int pointCount)
-{
- Q_D(QCoreGraphicsPaintEngine);
- Q_ASSERT(isActive());
-
- if (state->compositionMode() == QPainter::CompositionMode_Destination)
- return;
-
- if (d->current.pen.capStyle() == Qt::FlatCap)
- CGContextSetLineCap(d->hd, kCGLineCapSquare);
-
- CGMutablePathRef path = CGPathCreateMutable();
- for(int i=0; i < pointCount; i++) {
- float x = points[i].x(), y = points[i].y();
- CGPathMoveToPoint(path, 0, x, y);
- CGPathAddLineToPoint(path, 0, x+0.001, y);
- }
-
- bool doRestore = false;
- if(d->cosmeticPen == QCoreGraphicsPaintEnginePrivate::CosmeticNone && !(state->renderHints() & QPainter::Antialiasing)) {
- //we don't want adjusted pens for point rendering
- doRestore = true;
- d->saveGraphicsState();
- CGContextSetLineWidth(d->hd, d->current.pen.widthF());
- }
- d->drawPath(QCoreGraphicsPaintEnginePrivate::CGStroke, path);
- if (doRestore)
- d->restoreGraphicsState();
- CGPathRelease(path);
- if (d->current.pen.capStyle() == Qt::FlatCap)
- CGContextSetLineCap(d->hd, kCGLineCapButt);
-}
-
-void
-QCoreGraphicsPaintEngine::drawEllipse(const QRectF &r)
-{
- Q_D(QCoreGraphicsPaintEngine);
- Q_ASSERT(isActive());
-
- if (state->compositionMode() == QPainter::CompositionMode_Destination)
- return;
-
- CGMutablePathRef path = CGPathCreateMutable();
- CGAffineTransform transform = CGAffineTransformMakeScale(r.width() / r.height(), 1);
- CGPathAddArc(path, &transform,(r.x() + (r.width() / 2)) / (r.width() / r.height()),
- r.y() + (r.height() / 2), r.height() / 2, 0, (2 * M_PI), false);
- d->drawPath(QCoreGraphicsPaintEnginePrivate::CGFill | QCoreGraphicsPaintEnginePrivate::CGStroke,
- path);
- CGPathRelease(path);
-}
-
-void
-QCoreGraphicsPaintEngine::drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode)
-{
- Q_D(QCoreGraphicsPaintEngine);
- Q_ASSERT(isActive());
-
- if (state->compositionMode() == QPainter::CompositionMode_Destination)
- return;
-
- CGMutablePathRef path = CGPathCreateMutable();
- CGPathMoveToPoint(path, 0, points[0].x(), points[0].y());
- for(int x = 1; x < pointCount; ++x)
- CGPathAddLineToPoint(path, 0, points[x].x(), points[x].y());
- if(mode != PolylineMode && points[0] != points[pointCount-1])
- CGPathAddLineToPoint(path, 0, points[0].x(), points[0].y());
- uint op = QCoreGraphicsPaintEnginePrivate::CGStroke;
- if (mode != PolylineMode)
- op |= mode == OddEvenMode ? QCoreGraphicsPaintEnginePrivate::CGEOFill
- : QCoreGraphicsPaintEnginePrivate::CGFill;
- d->drawPath(op, path);
- CGPathRelease(path);
-}
-
-void
-QCoreGraphicsPaintEngine::drawLines(const QLineF *lines, int lineCount)
-{
- Q_D(QCoreGraphicsPaintEngine);
- Q_ASSERT(isActive());
-
- if (state->compositionMode() == QPainter::CompositionMode_Destination)
- return;
-
- CGMutablePathRef path = CGPathCreateMutable();
- for(int i = 0; i < lineCount; i++) {
- const QPointF start = lines[i].p1(), end = lines[i].p2();
- CGPathMoveToPoint(path, 0, start.x(), start.y());
- CGPathAddLineToPoint(path, 0, end.x(), end.y());
- }
- d->drawPath(QCoreGraphicsPaintEnginePrivate::CGStroke, path);
- CGPathRelease(path);
-}
-
-void QCoreGraphicsPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr)
-{
- Q_D(QCoreGraphicsPaintEngine);
- Q_ASSERT(isActive());
-
- if (state->compositionMode() == QPainter::CompositionMode_Destination)
- return;
-
- if(pm.isNull())
- return;
-
- bool differentSize = (QRectF(0, 0, pm.width(), pm.height()) != sr), doRestore = false;
- CGRect rect = CGRectMake(r.x(), r.y(), r.width(), r.height());
- QCFType<CGImageRef> image;
- bool isBitmap = (pm.depth() == 1);
- if (isBitmap) {
- doRestore = true;
- d->saveGraphicsState();
-
- const QColor &col = d->current.pen.color();
- CGContextSetFillColorWithColor(d->hd, cgColorForQColor(col, d->pdev));
- image = qt_mac_create_imagemask(pm, sr);
- } else if (differentSize) {
- QCFType<CGImageRef> img = pm.toMacCGImageRef();
- image = CGImageCreateWithImageInRect(img, CGRectMake(qRound(sr.x()), qRound(sr.y()), qRound(sr.width()), qRound(sr.height())));
- } else {
- image = (CGImageRef)pm.macCGHandle();
- }
- qt_mac_drawCGImage(d->hd, &rect, image);
- if (doRestore)
- d->restoreGraphicsState();
-}
-
-static void drawImageReleaseData (void *info, const void *, size_t)
-{
- delete static_cast<QImage *>(info);
-}
-
-CGImageRef qt_mac_createCGImageFromQImage(const QImage &img, const QImage **imagePtr = 0)
-{
- QImage *image;
- if (img.depth() != 32)
- image = new QImage(img.convertToFormat(QImage::Format_ARGB32_Premultiplied));
- else
- image = new QImage(img);
-
- uint cgflags = kCGImageAlphaNone;
- switch (image->format()) {
- case QImage::Format_ARGB32_Premultiplied:
- cgflags = kCGImageAlphaPremultipliedFirst;
- break;
- case QImage::Format_ARGB32:
- cgflags = kCGImageAlphaFirst;
- break;
- case QImage::Format_RGB32:
- cgflags = kCGImageAlphaNoneSkipFirst;
- default:
- break;
- }
-#if defined(kCGBitmapByteOrder32Host) //only needed because CGImage.h added symbols in the minor version
- cgflags |= kCGBitmapByteOrder32Host;
-#endif
- QCFType<CGDataProviderRef> dataProvider = CGDataProviderCreateWithData(image,
- static_cast<const QImage *>(image)->bits(),
- image->byteCount(),
- drawImageReleaseData);
- if (imagePtr)
- *imagePtr = image;
- return CGImageCreate(image->width(), image->height(), 8, 32,
- image->bytesPerLine(),
- QCoreGraphicsPaintEngine::macGenericColorSpace(),
- cgflags, dataProvider, 0, false, kCGRenderingIntentDefault);
-
-}
-
-void QCoreGraphicsPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRectF &sr,
- Qt::ImageConversionFlags flags)
-{
- Q_D(QCoreGraphicsPaintEngine);
- Q_UNUSED(flags);
- Q_ASSERT(isActive());
-
- if (img.isNull() || state->compositionMode() == QPainter::CompositionMode_Destination)
- return;
-
- const QImage *image;
- QCFType<CGImageRef> cgimage = qt_mac_createCGImageFromQImage(img, &image);
- CGRect rect = CGRectMake(r.x(), r.y(), r.width(), r.height());
- if (QRectF(0, 0, img.width(), img.height()) != sr)
- cgimage = CGImageCreateWithImageInRect(cgimage, CGRectMake(sr.x(), sr.y(),
- sr.width(), sr.height()));
- qt_mac_drawCGImage(d->hd, &rect, cgimage);
-}
-
-void QCoreGraphicsPaintEngine::initialize()
-{
-}
-
-void QCoreGraphicsPaintEngine::cleanup()
-{
-}
-
-CGContextRef
-QCoreGraphicsPaintEngine::handle() const
-{
- return d_func()->hd;
-}
-
-void
-QCoreGraphicsPaintEngine::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap,
- const QPointF &p)
-{
- Q_D(QCoreGraphicsPaintEngine);
- Q_ASSERT(isActive());
-
- if (state->compositionMode() == QPainter::CompositionMode_Destination)
- return;
-
- //save the old state
- d->saveGraphicsState();
-
- //setup the pattern
- QMacPattern *qpattern = new QMacPattern;
- qpattern->data.pixmap = pixmap;
- qpattern->foreground = d->current.pen.color();
- qpattern->pdev = d->pdev;
- CGPatternCallbacks callbks;
- callbks.version = 0;
- callbks.drawPattern = qt_mac_draw_pattern;
- callbks.releaseInfo = qt_mac_dispose_pattern;
- const int width = qpattern->width(), height = qpattern->height();
- CGAffineTransform trans = CGContextGetCTM(d->hd);
- CGPatternRef pat = CGPatternCreate(qpattern, CGRectMake(0, 0, width, height),
- trans, width, height,
- kCGPatternTilingNoDistortion, true, &callbks);
- CGColorSpaceRef cs = CGColorSpaceCreatePattern(0);
- CGContextSetFillColorSpace(d->hd, cs);
- CGFloat component = 1.0; //just one
- CGContextSetFillPattern(d->hd, pat, &component);
- CGSize phase = CGSizeApplyAffineTransform(CGSizeMake(-(p.x()-r.x()), -(p.y()-r.y())), trans);
- CGContextSetPatternPhase(d->hd, phase);
-
- //fill the rectangle
- CGRect mac_rect = CGRectMake(r.x(), r.y(), r.width(), r.height());
- CGContextFillRect(d->hd, mac_rect);
-
- //restore the state
- d->restoreGraphicsState();
- //cleanup
- CGColorSpaceRelease(cs);
- CGPatternRelease(pat);
-}
-
-void QCoreGraphicsPaintEngine::drawTextItem(const QPointF &pos, const QTextItem &item)
-{
- Q_D(QCoreGraphicsPaintEngine);
- if (d->current.transform.type() == QTransform::TxProject
-#ifndef QMAC_NATIVE_GRADIENTS
- || painter()->pen().brush().gradient() //Just let the base engine "emulate" the gradient
-#endif
- ) {
- QPaintEngine::drawTextItem(pos, item);
- return;
- }
-
- if (state->compositionMode() == QPainter::CompositionMode_Destination)
- return;
-
- const QTextItemInt &ti = static_cast<const QTextItemInt &>(item);
-
- QPen oldPen = painter()->pen();
- QBrush oldBrush = painter()->brush();
- QPointF oldBrushOrigin = painter()->brushOrigin();
- updatePen(Qt::NoPen);
- updateBrush(oldPen.brush(), QPointF(0, 0));
-
- Q_ASSERT(type() == QPaintEngine::CoreGraphics);
-
- QFontEngine *fe = ti.fontEngine;
-
- const bool textAA = state->renderHints() & QPainter::TextAntialiasing && fe->fontDef.pointSize > qt_antialiasing_threshold && !(fe->fontDef.styleStrategy & QFont::NoAntialias);
- const bool lineAA = state->renderHints() & QPainter::Antialiasing;
- if(textAA != lineAA)
- CGContextSetShouldAntialias(d->hd, textAA);
-
- if (ti.glyphs.numGlyphs) {
- switch (fe->type()) {
- case QFontEngine::Mac:
-#ifdef QT_MAC_USE_COCOA
- static_cast<QCoreTextFontEngine *>(fe)->draw(d->hd, pos.x(), pos.y(), ti, paintDevice()->height());
-#else
- static_cast<QFontEngineMac *>(fe)->draw(d->hd, pos.x(), pos.y(), ti, paintDevice()->height());
-#endif
- break;
- case QFontEngine::Box:
- d->drawBoxTextItem(pos, ti);
- break;
- default:
- break;
- }
- }
-
- if(textAA != lineAA)
- CGContextSetShouldAntialias(d->hd, !textAA);
-
- updatePen(oldPen);
- updateBrush(oldBrush, oldBrushOrigin);
-}
-
-QPainter::RenderHints
-QCoreGraphicsPaintEngine::supportedRenderHints() const
-{
- return QPainter::RenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
-}
-enum CGCompositeMode {
- kCGCompositeModeClear = 0,
- kCGCompositeModeCopy = 1,
- kCGCompositeModeSourceOver = 2,
- kCGCompositeModeSourceIn = 3,
- kCGCompositeModeSourceOut = 4,
- kCGCompositeModeSourceAtop = 5,
- kCGCompositeModeDestinationOver = 6,
- kCGCompositeModeDestinationIn = 7,
- kCGCompositeModeDestinationOut = 8,
- kCGCompositeModeDestinationAtop = 9,
- kCGCompositeModeXOR = 10,
- kCGCompositeModePlusDarker = 11, // (max (0, (1-d) + (1-s)))
- kCGCompositeModePlusLighter = 12, // (min (1, s + d))
- };
-extern "C" {
- extern void CGContextSetCompositeOperation(CGContextRef, int);
-} // private function, but is in all versions of OS X.
-void
-QCoreGraphicsPaintEngine::updateCompositionMode(QPainter::CompositionMode mode)
-{
-#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
- if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) {
- int cg_mode = kCGBlendModeNormal;
- switch(mode) {
- case QPainter::CompositionMode_Multiply:
- cg_mode = kCGBlendModeMultiply;
- break;
- case QPainter::CompositionMode_Screen:
- cg_mode = kCGBlendModeScreen;
- break;
- case QPainter::CompositionMode_Overlay:
- cg_mode = kCGBlendModeOverlay;
- break;
- case QPainter::CompositionMode_Darken:
- cg_mode = kCGBlendModeDarken;
- break;
- case QPainter::CompositionMode_Lighten:
- cg_mode = kCGBlendModeLighten;
- break;
- case QPainter::CompositionMode_ColorDodge:
- cg_mode = kCGBlendModeColorDodge;
- break;
- case QPainter::CompositionMode_ColorBurn:
- cg_mode = kCGBlendModeColorBurn;
- break;
- case QPainter::CompositionMode_HardLight:
- cg_mode = kCGBlendModeHardLight;
- break;
- case QPainter::CompositionMode_SoftLight:
- cg_mode = kCGBlendModeSoftLight;
- break;
- case QPainter::CompositionMode_Difference:
- cg_mode = kCGBlendModeDifference;
- break;
- case QPainter::CompositionMode_Exclusion:
- cg_mode = kCGBlendModeExclusion;
- break;
- case QPainter::CompositionMode_Plus:
- cg_mode = kCGBlendModePlusLighter;
- break;
- case QPainter::CompositionMode_SourceOver:
- cg_mode = kCGBlendModeNormal;
- break;
- case QPainter::CompositionMode_DestinationOver:
- cg_mode = kCGBlendModeDestinationOver;
- break;
- case QPainter::CompositionMode_Clear:
- cg_mode = kCGBlendModeClear;
- break;
- case QPainter::CompositionMode_Source:
- cg_mode = kCGBlendModeCopy;
- break;
- case QPainter::CompositionMode_Destination:
- cg_mode = -1;
- break;
- case QPainter::CompositionMode_SourceIn:
- cg_mode = kCGBlendModeSourceIn;
- break;
- case QPainter::CompositionMode_DestinationIn:
- cg_mode = kCGCompositeModeDestinationIn;
- break;
- case QPainter::CompositionMode_SourceOut:
- cg_mode = kCGBlendModeSourceOut;
- break;
- case QPainter::CompositionMode_DestinationOut:
- cg_mode = kCGBlendModeDestinationOver;
- break;
- case QPainter::CompositionMode_SourceAtop:
- cg_mode = kCGBlendModeSourceAtop;
- break;
- case QPainter::CompositionMode_DestinationAtop:
- cg_mode = kCGBlendModeDestinationAtop;
- break;
- case QPainter::CompositionMode_Xor:
- cg_mode = kCGBlendModeXOR;
- break;
- default:
- break;
- }
- if (cg_mode > -1) {
- CGContextSetBlendMode(d_func()->hd, CGBlendMode(cg_mode));
- }
- } else
-#endif
- // The standard porter duff ops.
- if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_3
- && mode <= QPainter::CompositionMode_Xor) {
- int cg_mode = kCGCompositeModeCopy;
- switch (mode) {
- case QPainter::CompositionMode_SourceOver:
- cg_mode = kCGCompositeModeSourceOver;
- break;
- case QPainter::CompositionMode_DestinationOver:
- cg_mode = kCGCompositeModeDestinationOver;
- break;
- case QPainter::CompositionMode_Clear:
- cg_mode = kCGCompositeModeClear;
- break;
- default:
- qWarning("QCoreGraphicsPaintEngine: Unhandled composition mode %d", (int)mode);
- break;
- case QPainter::CompositionMode_Source:
- cg_mode = kCGCompositeModeCopy;
- break;
- case QPainter::CompositionMode_Destination:
- cg_mode = CGCompositeMode(-1);
- break;
- case QPainter::CompositionMode_SourceIn:
- cg_mode = kCGCompositeModeSourceIn;
- break;
- case QPainter::CompositionMode_DestinationIn:
- cg_mode = kCGCompositeModeDestinationIn;
- break;
- case QPainter::CompositionMode_SourceOut:
- cg_mode = kCGCompositeModeSourceOut;
- break;
- case QPainter::CompositionMode_DestinationOut:
- cg_mode = kCGCompositeModeDestinationOut;
- break;
- case QPainter::CompositionMode_SourceAtop:
- cg_mode = kCGCompositeModeSourceAtop;
- break;
- case QPainter::CompositionMode_DestinationAtop:
- cg_mode = kCGCompositeModeDestinationAtop;
- break;
- case QPainter::CompositionMode_Xor:
- cg_mode = kCGCompositeModeXOR;
- break;
- }
- if (cg_mode > -1)
- CGContextSetCompositeOperation(d_func()->hd, CGCompositeMode(cg_mode));
- } else {
-#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4)
- bool needPrivateAPI = false;
- if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4) {
- int cg_mode = kCGBlendModeNormal;
- switch (mode) {
- case QPainter::CompositionMode_Multiply:
- cg_mode = kCGBlendModeMultiply;
- break;
- case QPainter::CompositionMode_Screen:
- cg_mode = kCGBlendModeScreen;
- break;
- case QPainter::CompositionMode_Overlay:
- cg_mode = kCGBlendModeOverlay;
- break;
- case QPainter::CompositionMode_Darken:
- cg_mode = kCGBlendModeDarken;
- break;
- case QPainter::CompositionMode_Lighten:
- cg_mode = kCGBlendModeLighten;
- break;
- case QPainter::CompositionMode_ColorDodge:
- cg_mode = kCGBlendModeColorDodge;
- break;
- case QPainter::CompositionMode_ColorBurn:
- cg_mode = kCGBlendModeColorBurn;
- break;
- case QPainter::CompositionMode_HardLight:
- cg_mode = kCGBlendModeHardLight;
- break;
- case QPainter::CompositionMode_SoftLight:
- cg_mode = kCGBlendModeSoftLight;
- break;
- case QPainter::CompositionMode_Difference:
- cg_mode = kCGBlendModeDifference;
- break;
- case QPainter::CompositionMode_Exclusion:
- cg_mode = kCGBlendModeExclusion;
- break;
- case QPainter::CompositionMode_Plus:
- needPrivateAPI = true;
- cg_mode = kCGCompositeModePlusLighter;
- break;
- default:
- break;
- }
- if (!needPrivateAPI)
- CGContextSetBlendMode(d_func()->hd, CGBlendMode(cg_mode));
- else
- CGContextSetCompositeOperation(d_func()->hd, CGCompositeMode(cg_mode));
- }
-#endif
- }
-}
-
-void
-QCoreGraphicsPaintEngine::updateRenderHints(QPainter::RenderHints hints)
-{
- Q_D(QCoreGraphicsPaintEngine);
- CGContextSetShouldAntialias(d->hd, hints & QPainter::Antialiasing);
- static const CGFloat ScaleFactor = qt_mac_get_scalefactor();
- if (ScaleFactor > 1.) {
- CGContextSetInterpolationQuality(d->hd, kCGInterpolationHigh);
- } else {
- CGContextSetInterpolationQuality(d->hd, (hints & QPainter::SmoothPixmapTransform) ?
- kCGInterpolationHigh : kCGInterpolationNone);
- }
- bool textAntialiasing = (hints & QPainter::TextAntialiasing) == QPainter::TextAntialiasing;
- if (!textAntialiasing || d->disabledSmoothFonts) {
- d->disabledSmoothFonts = !textAntialiasing;
- CGContextSetShouldSmoothFonts(d->hd, textAntialiasing);
- }
-}
-
-/*
- Returns the size of one device pixel in user-space coordinates.
-*/
-QPointF QCoreGraphicsPaintEnginePrivate::devicePixelSize(CGContextRef)
-{
- QPointF p1 = current.transform.inverted().map(QPointF(0, 0));
- QPointF p2 = current.transform.inverted().map(QPointF(1, 1));
- return QPointF(qAbs(p2.x() - p1.x()), qAbs(p2.y() - p1.y()));
-}
-
-/*
- Adjusts the pen width so we get correct line widths in the
- non-transformed, aliased case.
-*/
-float QCoreGraphicsPaintEnginePrivate::adjustPenWidth(float penWidth)
-{
- Q_Q(QCoreGraphicsPaintEngine);
- float ret = penWidth;
- if (!complexXForm && !(q->state->renderHints() & QPainter::Antialiasing)) {
- if (penWidth < 2)
- ret = 1;
- else if (penWidth < 3)
- ret = 1.5;
- else
- ret = penWidth -1;
- }
- return ret;
-}
-
-void
-QCoreGraphicsPaintEnginePrivate::setStrokePen(const QPen &pen)
-{
- //pencap
- CGLineCap cglinecap = kCGLineCapButt;
- if(pen.capStyle() == Qt::SquareCap)
- cglinecap = kCGLineCapSquare;
- else if(pen.capStyle() == Qt::RoundCap)
- cglinecap = kCGLineCapRound;
- CGContextSetLineCap(hd, cglinecap);
- CGContextSetLineWidth(hd, adjustPenWidth(pen.widthF()));
-
- //join
- CGLineJoin cglinejoin = kCGLineJoinMiter;
- if(pen.joinStyle() == Qt::BevelJoin)
- cglinejoin = kCGLineJoinBevel;
- else if(pen.joinStyle() == Qt::RoundJoin)
- cglinejoin = kCGLineJoinRound;
- CGContextSetLineJoin(hd, cglinejoin);
-// CGContextSetMiterLimit(hd, pen.miterLimit());
-
- //pen style
- QVector<CGFloat> linedashes;
- if(pen.style() == Qt::CustomDashLine) {
- QVector<qreal> customs = pen.dashPattern();
- for(int i = 0; i < customs.size(); ++i)
- linedashes.append(customs.at(i));
- } else if(pen.style() == Qt::DashLine) {
- linedashes.append(4);
- linedashes.append(2);
- } else if(pen.style() == Qt::DotLine) {
- linedashes.append(1);
- linedashes.append(2);
- } else if(pen.style() == Qt::DashDotLine) {
- linedashes.append(4);
- linedashes.append(2);
- linedashes.append(1);
- linedashes.append(2);
- } else if(pen.style() == Qt::DashDotDotLine) {
- linedashes.append(4);
- linedashes.append(2);
- linedashes.append(1);
- linedashes.append(2);
- linedashes.append(1);
- linedashes.append(2);
- }
- const CGFloat cglinewidth = pen.widthF() <= 0.0f ? 1.0f : float(pen.widthF());
- for(int i = 0; i < linedashes.size(); ++i) {
- linedashes[i] *= cglinewidth;
- if(cglinewidth < 3 && (cglinecap == kCGLineCapSquare || cglinecap == kCGLineCapRound)) {
- if((i%2))
- linedashes[i] += cglinewidth/2;
- else
- linedashes[i] -= cglinewidth/2;
- }
- }
- CGContextSetLineDash(hd, pen.dashOffset() * cglinewidth, linedashes.data(), linedashes.size());
-
- // color
- CGContextSetStrokeColorWithColor(hd, cgColorForQColor(pen.color(), pdev));
-}
-
-// Add our own patterns here to deal with the fact that the coordinate system
-// is flipped vertically with Quartz2D.
-static const uchar *qt_mac_patternForBrush(int brushStyle)
-{
- Q_ASSERT(brushStyle > Qt::SolidPattern && brushStyle < Qt::LinearGradientPattern);
- static const uchar dense1_pat[] = { 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x44, 0x00 };
- static const uchar dense2_pat[] = { 0x00, 0x22, 0x00, 0x88, 0x00, 0x22, 0x00, 0x88 };
- static const uchar dense3_pat[] = { 0x11, 0xaa, 0x44, 0xaa, 0x11, 0xaa, 0x44, 0xaa };
- static const uchar dense4_pat[] = { 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55 };
- static const uchar dense5_pat[] = { 0xee, 0x55, 0xbb, 0x55, 0xee, 0x55, 0xbb, 0x55 };
- static const uchar dense6_pat[] = { 0xff, 0xdd, 0xff, 0x77, 0xff, 0xdd, 0xff, 0x77 };
- static const uchar dense7_pat[] = { 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb, 0xff };
- static const uchar hor_pat[] = { 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff };
- static const uchar ver_pat[] = { 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef };
- static const uchar cross_pat[] = { 0xef, 0xef, 0xef, 0xef, 0x00, 0xef, 0xef, 0xef };
- static const uchar fdiag_pat[] = { 0x7f, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0xfe };
- static const uchar bdiag_pat[] = { 0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f };
- static const uchar dcross_pat[] = { 0x7e, 0xbd, 0xdb, 0xe7, 0xe7, 0xdb, 0xbd, 0x7e };
- static const uchar *const pat_tbl[] = {
- dense1_pat, dense2_pat, dense3_pat, dense4_pat, dense5_pat,
- dense6_pat, dense7_pat,
- hor_pat, ver_pat, cross_pat, bdiag_pat, fdiag_pat, dcross_pat };
- return pat_tbl[brushStyle - Qt::Dense1Pattern];
-}
-
-void QCoreGraphicsPaintEnginePrivate::setFillBrush(const QPointF &offset)
-{
- // pattern
- Qt::BrushStyle bs = current.brush.style();
-#ifdef QT_MAC_USE_NATIVE_GRADIENTS
- if (bs == Qt::LinearGradientPattern || bs == Qt::RadialGradientPattern) {
- const QGradient *grad = static_cast<const QGradient*>(current.brush.gradient());
- if (drawGradientNatively(grad)) {
- Q_ASSERT(grad->spread() == QGradient::PadSpread);
-
- static const CGFloat domain[] = { 0.0f, +1.0f };
- static const CGFunctionCallbacks callbacks = { 0, qt_mac_color_gradient_function, 0 };
- CGFunctionRef fill_func = CGFunctionCreate(reinterpret_cast<void *>(&current.brush),
- 1, domain, 4, 0, &callbacks);
-
- CGColorSpaceRef colorspace = qt_mac_colorSpaceForDeviceType(pdev);
- if (bs == Qt::LinearGradientPattern) {
- const QLinearGradient *linearGrad = static_cast<const QLinearGradient *>(grad);
- const QPointF start(linearGrad->start());
- const QPointF stop(linearGrad->finalStop());
- shading = CGShadingCreateAxial(colorspace, CGPointMake(start.x(), start.y()),
- CGPointMake(stop.x(), stop.y()), fill_func, true, true);
- } else {
- Q_ASSERT(bs == Qt::RadialGradientPattern);
- const QRadialGradient *radialGrad = static_cast<const QRadialGradient *>(grad);
- QPointF center(radialGrad->center());
- QPointF focal(radialGrad->focalPoint());
- qreal radius = radialGrad->radius();
- qreal focalRadius = radialGrad->focalRadius();
- shading = CGShadingCreateRadial(colorspace, CGPointMake(focal.x(), focal.y()),
- focalRadius, CGPointMake(center.x(), center.y()), radius, fill_func, false, true);
- }
-
- CGFunctionRelease(fill_func);
- }
- } else
-#endif
- if(bs != Qt::SolidPattern && bs != Qt::NoBrush
-#ifndef QT_MAC_USE_NATIVE_GRADIENTS
- && (bs < Qt::LinearGradientPattern || bs > Qt::ConicalGradientPattern)
-#endif
- )
- {
- QMacPattern *qpattern = new QMacPattern;
- qpattern->pdev = pdev;
- CGFloat components[4] = { 1.0, 1.0, 1.0, 1.0 };
- CGColorSpaceRef base_colorspace = 0;
- if(bs == Qt::TexturePattern) {
- qpattern->data.pixmap = current.brush.texture();
- if(qpattern->data.pixmap.isQBitmap()) {
- const QColor &col = current.brush.color();
- components[0] = qt_mac_convert_color_to_cg(col.red());
- components[1] = qt_mac_convert_color_to_cg(col.green());
- components[2] = qt_mac_convert_color_to_cg(col.blue());
- base_colorspace = QCoreGraphicsPaintEngine::macGenericColorSpace();
- }
- } else {
- qpattern->as_mask = true;
-
- qpattern->data.bytes = qt_mac_patternForBrush(bs);
- const QColor &col = current.brush.color();
- components[0] = qt_mac_convert_color_to_cg(col.red());
- components[1] = qt_mac_convert_color_to_cg(col.green());
- components[2] = qt_mac_convert_color_to_cg(col.blue());
- base_colorspace = QCoreGraphicsPaintEngine::macGenericColorSpace();
- }
- int width = qpattern->width(), height = qpattern->height();
- qpattern->foreground = current.brush.color();
-
- CGColorSpaceRef fill_colorspace = CGColorSpaceCreatePattern(base_colorspace);
- CGContextSetFillColorSpace(hd, fill_colorspace);
-
- CGAffineTransform xform = CGContextGetCTM(hd);
- xform = CGAffineTransformConcat(qt_mac_convert_transform_to_cg(current.brush.transform()), xform);
- xform = CGAffineTransformTranslate(xform, offset.x(), offset.y());
-
- CGPatternCallbacks callbks;
- callbks.version = 0;
- callbks.drawPattern = qt_mac_draw_pattern;
- callbks.releaseInfo = qt_mac_dispose_pattern;
- CGPatternRef fill_pattern = CGPatternCreate(qpattern, CGRectMake(0, 0, width, height),
- xform, width, height, kCGPatternTilingNoDistortion,
- !base_colorspace, &callbks);
- CGContextSetFillPattern(hd, fill_pattern, components);
-
- CGPatternRelease(fill_pattern);
- CGColorSpaceRelease(fill_colorspace);
- } else if(bs != Qt::NoBrush) {
- CGContextSetFillColorWithColor(hd, cgColorForQColor(current.brush.color(), pdev));
- }
-}
-
-void
-QCoreGraphicsPaintEnginePrivate::setClip(const QRegion *rgn)
-{
- Q_Q(QCoreGraphicsPaintEngine);
- if(hd) {
- resetClip();
- QRegion sysClip = q->systemClip();
- if(!sysClip.isEmpty())
- qt_mac_clip_cg(hd, sysClip, &orig_xform);
- if(rgn)
- qt_mac_clip_cg(hd, *rgn, 0);
- }
-}
-
-struct qt_mac_cg_transform_path {
- CGMutablePathRef path;
- CGAffineTransform transform;
-};
-
-void qt_mac_cg_transform_path_apply(void *info, const CGPathElement *element)
-{
- Q_ASSERT(info && element);
- qt_mac_cg_transform_path *t = (qt_mac_cg_transform_path*)info;
- switch(element->type) {
- case kCGPathElementMoveToPoint:
- CGPathMoveToPoint(t->path, &t->transform, element->points[0].x, element->points[0].y);
- break;
- case kCGPathElementAddLineToPoint:
- CGPathAddLineToPoint(t->path, &t->transform, element->points[0].x, element->points[0].y);
- break;
- case kCGPathElementAddQuadCurveToPoint:
- CGPathAddQuadCurveToPoint(t->path, &t->transform, element->points[0].x, element->points[0].y,
- element->points[1].x, element->points[1].y);
- break;
- case kCGPathElementAddCurveToPoint:
- CGPathAddCurveToPoint(t->path, &t->transform, element->points[0].x, element->points[0].y,
- element->points[1].x, element->points[1].y,
- element->points[2].x, element->points[2].y);
- break;
- case kCGPathElementCloseSubpath:
- CGPathCloseSubpath(t->path);
- break;
- default:
- qDebug() << "Unhandled path transform type: " << element->type;
- }
-}
-
-void QCoreGraphicsPaintEnginePrivate::drawPath(uchar ops, CGMutablePathRef path)
-{
- Q_Q(QCoreGraphicsPaintEngine);
- Q_ASSERT((ops & (CGFill | CGEOFill)) != (CGFill | CGEOFill)); //can't really happen
- if((ops & (CGFill | CGEOFill))) {
- if (shading) {
- Q_ASSERT(path);
- CGContextBeginPath(hd);
- CGContextAddPath(hd, path);
- saveGraphicsState();
- if (ops & CGFill)
- CGContextClip(hd);
- else if (ops & CGEOFill)
- CGContextEOClip(hd);
- if (current.brush.gradient()->coordinateMode() == QGradient::ObjectBoundingMode) {
- CGRect boundingBox = CGPathGetBoundingBox(path);
- CGContextConcatCTM(hd,
- CGAffineTransformMake(boundingBox.size.width, 0,
- 0, boundingBox.size.height,
- boundingBox.origin.x, boundingBox.origin.y));
- }
- CGContextDrawShading(hd, shading);
- restoreGraphicsState();
- ops &= ~CGFill;
- ops &= ~CGEOFill;
- } else if (current.brush.style() == Qt::NoBrush) {
- ops &= ~CGFill;
- ops &= ~CGEOFill;
- }
- }
- if((ops & CGStroke) && current.pen.style() == Qt::NoPen)
- ops &= ~CGStroke;
-
- if(ops & (CGEOFill | CGFill)) {
- CGContextBeginPath(hd);
- CGContextAddPath(hd, path);
- if (ops & CGEOFill) {
- CGContextEOFillPath(hd);
- } else {
- CGContextFillPath(hd);
- }
- }
-
- // Avoid saving and restoring the context if we can.
- const bool needContextSave = (cosmeticPen != QCoreGraphicsPaintEnginePrivate::CosmeticNone ||
- !(q->state->renderHints() & QPainter::Antialiasing));
- if(ops & CGStroke) {
- if (needContextSave)
- saveGraphicsState();
- CGContextBeginPath(hd);
-
- // Translate a fraction of a pixel size in the y direction
- // to make sure that primitives painted at pixel borders
- // fills the right pixel. This is needed since the y xais
- // in the Quartz coordinate system is inverted compared to Qt.
- if (!(q->state->renderHints() & QPainter::Antialiasing)) {
- if (current.pen.style() == Qt::SolidLine || current.pen.width() >= 3)
- CGContextTranslateCTM(hd, double(pixelSize.x()) * 0.25, double(pixelSize.y()) * 0.25);
- else if (current.pen.style() == Qt::DotLine && QSysInfo::MacintoshVersion == QSysInfo::MV_10_3)
- ; // Do nothing.
- else
- CGContextTranslateCTM(hd, 0, double(pixelSize.y()) * 0.1);
- }
-
- if (cosmeticPen != QCoreGraphicsPaintEnginePrivate::CosmeticNone) {
- // If antialiazing is enabled, use the cosmetic pen size directly.
- if (q->state->renderHints() & QPainter::Antialiasing)
- CGContextSetLineWidth(hd, cosmeticPenSize);
- else if (current.pen.widthF() <= 1)
- CGContextSetLineWidth(hd, cosmeticPenSize * 0.9f);
- else
- CGContextSetLineWidth(hd, cosmeticPenSize);
- }
- if(cosmeticPen == QCoreGraphicsPaintEnginePrivate::CosmeticTransformPath) {
- qt_mac_cg_transform_path t;
- t.transform = qt_mac_convert_transform_to_cg(current.transform);
- t.path = CGPathCreateMutable();
- CGPathApply(path, &t, qt_mac_cg_transform_path_apply); //transform the path
- setTransform(0); //unset the context transform
- CGContextSetLineWidth(hd, cosmeticPenSize);
- CGContextAddPath(hd, t.path);
- CGPathRelease(t.path);
- } else {
- CGContextAddPath(hd, path);
- }
-
- CGContextStrokePath(hd);
- if (needContextSave)
- restoreGraphicsState();
- }
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/painting/qpaintengine_p.h b/src/gui/painting/qpaintengine_p.h
index 2b54e82c39..5d540bd11b 100644
--- a/src/gui/painting/qpaintengine_p.h
+++ b/src/gui/painting/qpaintengine_p.h
@@ -66,7 +66,7 @@ class QPaintEnginePrivate
{
Q_DECLARE_PUBLIC(QPaintEngine)
public:
- QPaintEnginePrivate() : pdev(0), q_ptr(0), currentClipWidget(0), hasSystemTransform(0),
+ QPaintEnginePrivate() : pdev(0), q_ptr(0), currentClipDevice(0), hasSystemTransform(0),
hasSystemViewport(0) {}
virtual ~QPaintEnginePrivate() { }
QPaintDevice *pdev;
@@ -75,7 +75,7 @@ public:
QRect systemRect;
QRegion systemViewport;
QTransform systemTransform;
- QWidget *currentClipWidget;
+ QPaintDevice *currentClipDevice;
uint hasSystemTransform : 1;
uint hasSystemViewport : 1;
diff --git a/src/gui/painting/qpaintengine_preview.cpp b/src/gui/painting/qpaintengine_preview.cpp
deleted file mode 100644
index d3b7756516..0000000000
--- a/src/gui/painting/qpaintengine_preview.cpp
+++ /dev/null
@@ -1,223 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <private/qpaintengine_preview_p.h>
-#include <private/qpainter_p.h>
-#include <private/qpaintengine_p.h>
-#include <private/qpicture_p.h>
-
-#include <QtGui/qprintengine.h>
-#include <QtGui/qpainter.h>
-#include <QtGui/qpicture.h>
-
-#ifndef QT_NO_PRINTPREVIEWWIDGET
-QT_BEGIN_NAMESPACE
-
-class QPreviewPaintEnginePrivate : public QPaintEnginePrivate
-{
- Q_DECLARE_PUBLIC(QPreviewPaintEngine)
-public:
- QPreviewPaintEnginePrivate() : state(QPrinter::Idle) {}
- ~QPreviewPaintEnginePrivate() {}
-
- QList<const QPicture *> pages;
- QPaintEngine *engine;
- QPainter *painter;
- QPrinter::PrinterState state;
-
- QPaintEngine *proxy_paint_engine;
- QPrintEngine *proxy_print_engine;
-};
-
-
-QPreviewPaintEngine::QPreviewPaintEngine()
- : QPaintEngine(*(new QPreviewPaintEnginePrivate), PaintEngineFeatures(AllFeatures & ~ObjectBoundingModeGradients))
-{
- Q_D(QPreviewPaintEngine);
- d->proxy_print_engine = 0;
- d->proxy_paint_engine = 0;
-}
-
-QPreviewPaintEngine::~QPreviewPaintEngine()
-{
- Q_D(QPreviewPaintEngine);
-
- qDeleteAll(d->pages);
-}
-
-bool QPreviewPaintEngine::begin(QPaintDevice *)
-{
- Q_D(QPreviewPaintEngine);
-
- qDeleteAll(d->pages);
- d->pages.clear();
-
- QPicture *page = new QPicture;
- page->d_func()->in_memory_only = true;
- d->painter = new QPainter(page);
- d->engine = d->painter->paintEngine();
- d->pages.append(page);
- d->state = QPrinter::Active;
- return true;
-}
-
-bool QPreviewPaintEngine::end()
-{
- Q_D(QPreviewPaintEngine);
-
- delete d->painter;
- d->painter = 0;
- d->engine = 0;
- d->state = QPrinter::Idle;
- return true;
-}
-
-void QPreviewPaintEngine::updateState(const QPaintEngineState &state)
-{
- Q_D(QPreviewPaintEngine);
- d->engine->updateState(state);
-}
-
-void QPreviewPaintEngine::drawPath(const QPainterPath &path)
-{
- Q_D(QPreviewPaintEngine);
- d->engine->drawPath(path);
-}
-
-void QPreviewPaintEngine::drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode)
-{
- Q_D(QPreviewPaintEngine);
- d->engine->drawPolygon(points, pointCount, mode);
-}
-
-void QPreviewPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem)
-{
- Q_D(QPreviewPaintEngine);
- d->engine->drawTextItem(p, textItem);
-}
-
-void QPreviewPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr)
-{
- Q_D(QPreviewPaintEngine);
- d->engine->drawPixmap(r, pm, sr);
-}
-
-void QPreviewPaintEngine::drawTiledPixmap(const QRectF &r, const QPixmap &pm, const QPointF &p)
-{
- Q_D(QPreviewPaintEngine);
- d->engine->drawTiledPixmap(r, pm, p);
-}
-
-bool QPreviewPaintEngine::newPage()
-{
- Q_D(QPreviewPaintEngine);
-
- QPicture *page = new QPicture;
- page->d_func()->in_memory_only = true;
- QPainter *tmp_painter = new QPainter(page);
- QPaintEngine *tmp_engine = tmp_painter->paintEngine();
-
- // copy the painter state from the original painter
- Q_ASSERT(painter()->d_func()->state && tmp_painter->d_func()->state);
- *tmp_painter->d_func()->state = *painter()->d_func()->state;
-
- // composition modes aren't supported on a QPrinter and yields a
- // warning, so ignore it for now
- tmp_engine->setDirty(DirtyFlags(AllDirty & ~DirtyCompositionMode));
- tmp_engine->syncState();
-
- delete d->painter;
- d->painter = tmp_painter;
- d->pages.append(page);
- d->engine = tmp_engine;
- return true;
-}
-
-bool QPreviewPaintEngine::abort()
-{
- Q_D(QPreviewPaintEngine);
- end();
- qDeleteAll(d->pages);
- d->state = QPrinter::Aborted;
-
- return true;
-}
-
-QList<const QPicture *> QPreviewPaintEngine::pages()
-{
- Q_D(QPreviewPaintEngine);
- return d->pages;
-}
-
-void QPreviewPaintEngine::setProxyEngines(QPrintEngine *printEngine, QPaintEngine *paintEngine)
-{
- Q_D(QPreviewPaintEngine);
- d->proxy_print_engine = printEngine;
- d->proxy_paint_engine = paintEngine;
-}
-
-void QPreviewPaintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &value)
-{
- Q_D(QPreviewPaintEngine);
- d->proxy_print_engine->setProperty(key, value);
-}
-
-QVariant QPreviewPaintEngine::property(PrintEnginePropertyKey key) const
-{
- Q_D(const QPreviewPaintEngine);
- return d->proxy_print_engine->property(key);
-}
-
-int QPreviewPaintEngine::metric(QPaintDevice::PaintDeviceMetric id) const
-{
- Q_D(const QPreviewPaintEngine);
- return d->proxy_print_engine->metric(id);
-}
-
-QPrinter::PrinterState QPreviewPaintEngine::printerState() const
-{
- Q_D(const QPreviewPaintEngine);
- return d->state;
-}
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/gui/painting/qpaintengine_preview_p.h b/src/gui/painting/qpaintengine_preview_p.h
deleted file mode 100644
index 902a03bd8f..0000000000
--- a/src/gui/painting/qpaintengine_preview_p.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPREVIEWPAINTENGINE_P_H
-#define QPREVIEWPAINTENGINE_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of QPreviewPrinter and friends. This header file may change from
-// version to version without notice, or even be removed.
-//
-// We mean it.
-//
-//
-
-#include <QtGui/qpaintengine.h>
-#include <QtGui/qprintengine.h>
-
-#ifndef QT_NO_PRINTPREVIEWWIDGET
-
-QT_BEGIN_NAMESPACE
-
-class QPreviewPaintEnginePrivate;
-
-class QPreviewPaintEngine : public QPaintEngine, public QPrintEngine
-{
- Q_DECLARE_PRIVATE(QPreviewPaintEngine)
-public:
- QPreviewPaintEngine();
- ~QPreviewPaintEngine();
-
- bool begin(QPaintDevice *dev);
- bool end();
-
- void updateState(const QPaintEngineState &state);
-
- void drawPath(const QPainterPath &path);
- void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode);
- void drawTextItem(const QPointF &p, const QTextItem &textItem);
-
- void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr);
- void drawTiledPixmap(const QRectF &r, const QPixmap &pm, const QPointF &p);
-
- QList<const QPicture *> pages();
-
- QPaintEngine::Type type() const { return Picture; }
-
- void setProxyEngines(QPrintEngine *printEngine, QPaintEngine *paintEngine);
-
- void setProperty(PrintEnginePropertyKey key, const QVariant &value);
- QVariant property(PrintEnginePropertyKey key) const;
-
- bool newPage();
- bool abort();
-
- int metric(QPaintDevice::PaintDeviceMetric) const;
-
- QPrinter::PrinterState printerState() const;
-};
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_PRINTPREVIEWWIDGET
-
-#endif
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index 45099f92d3..4d4b88b229 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -51,7 +51,6 @@
#include <qpainterpath.h>
#include <qdebug.h>
#include <qhash.h>
-#include <qlabel.h>
#include <qbitmap.h>
#include <qmath.h>
@@ -76,7 +75,7 @@
// #include "qbezier_p.h"
#include "qoutlinemapper_p.h"
-#if defined(Q_WS_WIN)
+#if defined(Q_OS_WIN)
# include <qt_windows.h>
# include <qvarlengtharray.h>
# include <private/qfontengine_p.h>
@@ -87,21 +86,13 @@
# include <private/qt_mac_p.h>
# include <private/qpixmap_mac_p.h>
# include <private/qpaintengine_mac_p.h>
-#elif defined(Q_WS_QWS)
-# if !defined(QT_NO_FREETYPE)
-# include <private/qfontengine_ft_p.h>
-# endif
-# if !defined(QT_NO_QWS_QPF2)
-# include <private/qfontengine_qpf_p.h>
-# endif
-# include <private/qabstractfontengine_p.h>
#elif defined(Q_OS_SYMBIAN) && defined(QT_NO_FREETYPE)
# include <private/qfontengine_s60_p.h>
#elif defined(Q_WS_QPA)
# include <private/qfontengine_ft_p.h>
#endif
-#if defined(Q_WS_WIN64)
+#if defined(Q_OS_WIN64)
# include <malloc.h>
#endif
#include <limits.h>
@@ -127,12 +118,28 @@ void dumpClip(int width, int height, const QClipData *clip);
// 4 pixels.
#define int_dim(pos, dim) (int(pos+dim) - int(pos))
-// use the same rounding as in qrasterizer.cpp (6 bit fixed point)
static const qreal aliasedCoordinateDelta = 0.5 - 0.015625;
-#ifdef Q_WS_WIN
-extern bool qt_cleartype_enabled;
+#ifdef Q_OS_WIN
+
+static inline bool winClearTypeFontsEnabled()
+{
+ UINT result = 0;
+#if !defined(SPI_GETFONTSMOOTHINGTYPE) // MinGW
+# define SPI_GETFONTSMOOTHINGTYPE 0x200A
+# define FE_FONTSMOOTHINGCLEARTYPE 0x002
#endif
+ SystemParametersInfo(SPI_GETFONTSMOOTHINGTYPE, 0, &result, 0);
+ return result == FE_FONTSMOOTHINGCLEARTYPE;
+}
+
+bool QRasterPaintEngine::clearTypeFontsEnabled()
+{
+ static const bool result = winClearTypeFontsEnabled();
+ return result;
+}
+
+#endif // Q_OS_WIN
#ifdef Q_WS_MAC
extern bool qt_applefontsmoothing_enabled;
@@ -145,7 +152,6 @@ extern bool qt_applefontsmoothing_enabled;
static void qt_span_fill_clipRect(int count, const QSpan *spans, void *userData);
static void qt_span_fill_clipped(int count, const QSpan *spans, void *userData);
static void qt_span_clip(int count, const QSpan *spans, void *userData);
-static void qt_merge_clip(const QClipData *c1, const QClipData *c2, QClipData *result);
struct ClipData
{
@@ -332,7 +338,7 @@ void QRasterPaintEngine::init()
Q_D(QRasterPaintEngine);
-#ifdef Q_WS_WIN
+#ifdef Q_OS_WIN
d->hdc = 0;
#endif
@@ -378,11 +384,6 @@ void QRasterPaintEngine::init()
case QInternal::Image:
format = d->rasterBuffer->prepare(static_cast<QImage *>(d->device));
break;
-#ifdef Q_WS_QWS
- case QInternal::CustomRaster:
- d->rasterBuffer->prepare(static_cast<QCustomRasterPaintDevice*>(d->device));
- break;
-#endif
default:
qWarning("QRasterPaintEngine: unsupported target device %d\n", d->device->devType());
d->device = 0;
@@ -436,8 +437,8 @@ bool QRasterPaintEngine::begin(QPaintDevice *device)
if (device->devType() == QInternal::Pixmap) {
QPixmap *pixmap = static_cast<QPixmap *>(device);
- QPixmapData *pd = pixmap->pixmapData();
- if (pd->classId() == QPixmapData::RasterClass || pd->classId() == QPixmapData::BlitterClass)
+ QPlatformPixmap *pd = pixmap->handle();
+ if (pd->classId() == QPlatformPixmap::RasterClass || pd->classId() == QPlatformPixmap::BlitterClass)
d->device = pd->buffer();
} else {
d->device = device;
@@ -485,8 +486,8 @@ bool QRasterPaintEngine::begin(QPaintDevice *device)
if (d->mono_surface)
d->glyphCacheType = QFontEngineGlyphCache::Raster_Mono;
-#if defined(Q_WS_WIN)
- else if (qt_cleartype_enabled)
+#if defined(Q_OS_WIN)
+ else if (clearTypeFontsEnabled())
#elif defined (Q_WS_MAC)
else if (qt_applefontsmoothing_enabled)
#else
@@ -947,13 +948,6 @@ void QRasterPaintEngine::clipEnabledChanged()
}
}
-#ifdef Q_WS_QWS
-void QRasterPaintEnginePrivate::prepare(QCustomRasterPaintDevice *device)
-{
- rasterBuffer->prepare(device);
-}
-#endif
-
void QRasterPaintEnginePrivate::drawImage(const QPointF &pt,
const QImage &img,
SrcOverBlendFunc func,
@@ -1994,9 +1988,9 @@ void QRasterPaintEngine::drawPixmap(const QPointF &pos, const QPixmap &pixmap)
qDebug() << " - QRasterPaintEngine::drawPixmap(), pos=" << pos << " pixmap=" << pixmap.size() << "depth=" << pixmap.depth();
#endif
- QPixmapData *pd = pixmap.pixmapData();
- if (pd->classId() == QPixmapData::RasterClass) {
- const QImage &image = static_cast<QRasterPixmapData *>(pd)->image;
+ QPlatformPixmap *pd = pixmap.handle();
+ if (pd->classId() == QPlatformPixmap::RasterClass) {
+ const QImage &image = static_cast<QRasterPlatformPixmap *>(pd)->image;
if (image.depth() == 1) {
Q_D(QRasterPaintEngine);
QRasterPaintEngineState *s = state();
@@ -2035,9 +2029,9 @@ void QRasterPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pixmap, cons
qDebug() << " - QRasterPaintEngine::drawPixmap(), r=" << r << " sr=" << sr << " pixmap=" << pixmap.size() << "depth=" << pixmap.depth();
#endif
- QPixmapData* pd = pixmap.pixmapData();
- if (pd->classId() == QPixmapData::RasterClass) {
- const QImage &image = static_cast<QRasterPixmapData *>(pd)->image;
+ QPlatformPixmap* pd = pixmap.handle();
+ if (pd->classId() == QPlatformPixmap::RasterClass) {
+ const QImage &image = static_cast<QRasterPlatformPixmap *>(pd)->image;
if (image.depth() == 1) {
Q_D(QRasterPaintEngine);
QRasterPaintEngineState *s = state();
@@ -2430,9 +2424,9 @@ void QRasterPaintEngine::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap,
QImage image;
- QPixmapData *pd = pixmap.pixmapData();
- if (pd->classId() == QPixmapData::RasterClass) {
- image = static_cast<QRasterPixmapData *>(pd)->image;
+ QPlatformPixmap *pd = pixmap.handle();
+ if (pd->classId() == QPlatformPixmap::RasterClass) {
+ image = static_cast<QRasterPlatformPixmap *>(pd)->image;
} else {
image = pixmap.toImage();
}
@@ -3052,33 +3046,17 @@ void QRasterPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textIte
return;
}
-#elif defined (Q_OS_SYMBIAN) && defined(QT_NO_FREETYPE) // Q_WS_WIN || Q_WS_MAC
+#elif defined (Q_OS_SYMBIAN) && defined(QT_NO_FREETYPE) // Q_OS_WIN || Q_WS_MAC
if (s->matrix.type() <= QTransform::TxTranslate
|| (s->matrix.type() == QTransform::TxScale
&& (qFuzzyCompare(s->matrix.m11(), s->matrix.m22())))) {
drawGlyphsS60(p, ti);
return;
}
-#else // Q_WS_WIN || Q_WS_MAC
+#else // Q_OS_WIN || Q_WS_MAC
QFontEngine *fontEngine = ti.fontEngine;
-#if defined(Q_WS_QWS)
- if (fontEngine->type() == QFontEngine::Box) {
- fontEngine->draw(this, qFloor(p.x()), qFloor(p.y()), ti);
- return;
- }
-
- if (s->matrix.type() < QTransform::TxScale
- && (fontEngine->type() == QFontEngine::QPF1 || fontEngine->type() == QFontEngine::QPF2
- || (fontEngine->type() == QFontEngine::Proxy
- && !(static_cast<QProxyFontEngine *>(fontEngine)->drawAsOutline()))
- )) {
- fontEngine->draw(this, qFloor(p.x() + aliasedCoordinateDelta), qFloor(p.y() + aliasedCoordinateDelta), ti);
- return;
- }
-#endif // Q_WS_QWS
-
#ifdef Q_WS_QPA
if (s->matrix.type() < QTransform::TxScale) {
@@ -3109,14 +3087,6 @@ void QRasterPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textIte
#if (defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)) && !defined(QT_NO_FREETYPE)
-#if defined(Q_WS_QWS) && !defined(QT_NO_QWS_QPF2)
- if (fontEngine->type() == QFontEngine::QPF2) {
- QFontEngine *renderingEngine = static_cast<QFontEngineQPF *>(fontEngine)->renderingEngine();
- if (renderingEngine)
- fontEngine = renderingEngine;
- }
-#endif
-
if (fontEngine->type() != QFontEngine::Freetype) {
QPaintEngineEx::drawTextItem(p, ti);
return;
@@ -3333,7 +3303,7 @@ CGContextRef QRasterPaintEngine::getCGContext() const
}
#endif
-#ifdef Q_WS_WIN
+#ifdef Q_OS_WIN
/*!
\internal
*/
@@ -3396,59 +3366,6 @@ QPoint QRasterPaintEngine::coordinateOffset() const
return QPoint(0, 0);
}
-/*!
- Draws the given color \a spans with the specified \a color. The \a
- count parameter specifies the number of spans.
-
- The default implementation does nothing; reimplement this function
- to draw the given color \a spans with the specified \a color. Note
- that this function \e must be reimplemented if the framebuffer is
- not memory-mapped.
-
- \sa drawBufferSpan()
-*/
-#if defined(Q_WS_QWS) && !defined(QT_NO_RASTERCALLBACKS)
-void QRasterPaintEngine::drawColorSpans(const QSpan *spans, int count, uint color)
-{
- Q_UNUSED(spans);
- Q_UNUSED(count);
- Q_UNUSED(color);
- qFatal("QRasterPaintEngine::drawColorSpans must be reimplemented on "
- "a non memory-mapped device");
-}
-
-/*!
- \fn void QRasterPaintEngine::drawBufferSpan(const uint *buffer, int size, int x, int y, int length, uint alpha)
-
- Draws the given \a buffer.
-
- The default implementation does nothing; reimplement this function
- to draw a buffer that contains more than one color. Note that this
- function \e must be reimplemented if the framebuffer is not
- memory-mapped.
-
- The \a size parameter specifies the total size of the given \a
- buffer, while the \a length parameter specifies the number of
- pixels to draw. The buffer's position is given by (\a x, \a
- y). The provided \a alpha value is added to each pixel in the
- buffer when drawing.
-
- \sa drawColorSpans()
-*/
-void QRasterPaintEngine::drawBufferSpan(const uint *buffer, int bufsize,
- int x, int y, int length, uint const_alpha)
-{
- Q_UNUSED(buffer);
- Q_UNUSED(bufsize);
- Q_UNUSED(x);
- Q_UNUSED(y);
- Q_UNUSED(length);
- Q_UNUSED(const_alpha);
- qFatal("QRasterPaintEngine::drawBufferSpan must be reimplemented on "
- "a non memory-mapped device");
-}
-#endif // Q_WS_QWS
-
void QRasterPaintEngine::drawBitmap(const QPointF &pos, const QImage &image, QSpanData *fg)
{
Q_ASSERT(fg);
@@ -3577,76 +3494,6 @@ QRect QRasterPaintEngine::clipBoundingRect() const
return QRect(clip->xmin, clip->ymin, clip->xmax - clip->xmin, clip->ymax - clip->ymin);
}
-static void qt_merge_clip(const QClipData *c1, const QClipData *c2, QClipData *result)
-{
- Q_ASSERT(c1->clipSpanHeight == c2->clipSpanHeight && c1->clipSpanHeight == result->clipSpanHeight);
-
- QVarLengthArray<short, 4096> buffer;
-
- QClipData::ClipLine *c1ClipLines = const_cast<QClipData *>(c1)->clipLines();
- QClipData::ClipLine *c2ClipLines = const_cast<QClipData *>(c2)->clipLines();
- result->initialize();
-
- for (int y = 0; y < c1->clipSpanHeight; ++y) {
- const QSpan *c1_spans = c1ClipLines[y].spans;
- int c1_count = c1ClipLines[y].count;
- const QSpan *c2_spans = c2ClipLines[y].spans;
- int c2_count = c2ClipLines[y].count;
-
- if (c1_count == 0 && c2_count == 0)
- continue;
- if (c1_count == 0) {
- result->appendSpans(c2_spans, c2_count);
- continue;
- } else if (c2_count == 0) {
- result->appendSpans(c1_spans, c1_count);
- continue;
- }
-
- // we need to merge the two
-
- // find required length
- int max = qMax(c1_spans[c1_count - 1].x + c1_spans[c1_count - 1].len,
- c2_spans[c2_count - 1].x + c2_spans[c2_count - 1].len);
- buffer.resize(max);
- memset(buffer.data(), 0, buffer.size() * sizeof(short));
-
- // Fill with old spans.
- for (int i = 0; i < c1_count; ++i) {
- const QSpan *cs = c1_spans + i;
- for (int j=cs->x; j<cs->x + cs->len; ++j)
- buffer[j] = cs->coverage;
- }
-
- // Fill with new spans
- for (int i = 0; i < c2_count; ++i) {
- const QSpan *cs = c2_spans + i;
- for (int j = cs->x; j < cs->x + cs->len; ++j) {
- buffer[j] += cs->coverage;
- if (buffer[j] > 255)
- buffer[j] = 255;
- }
- }
-
- int x = 0;
- while (x<max) {
-
- // Skip to next span
- while (x < max && buffer[x] == 0) ++x;
- if (x >= max) break;
-
- int sx = x;
- int coverage = buffer[x];
-
- // Find length of span
- while (x < max && buffer[x] == coverage)
- ++x;
-
- result->appendSpan(sx, x - sx, y, coverage);
- }
- }
-}
-
void QRasterPaintEnginePrivate::initializeRasterizer(QSpanData *data)
{
Q_Q(QRasterPaintEngine);
@@ -3730,7 +3577,7 @@ void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline,
const int rasterPoolInitialSize = MINIMUM_POOL_SIZE;
int rasterPoolSize = rasterPoolInitialSize;
unsigned char *rasterPoolBase;
-#if defined(Q_WS_WIN64)
+#if defined(Q_OS_WIN64)
rasterPoolBase =
// We make use of setjmp and longjmp in qgrayraster.c which requires
// 16-byte alignment, hence we hardcode this requirement here..
@@ -3783,7 +3630,7 @@ void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline,
rendered_spans += q_gray_rendered_spans(*grayRaster.data());
-#if defined(Q_WS_WIN64)
+#if defined(Q_OS_WIN64)
_aligned_free(rasterPoolBase);
#else
if (rasterPoolBase != rasterPoolOnStack) // initially on the stack
@@ -3792,7 +3639,7 @@ void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline,
rasterPoolSize = new_size;
rasterPoolBase =
-#if defined(Q_WS_WIN64)
+#if defined(Q_OS_WIN64)
// We make use of setjmp and longjmp in qgrayraster.c which requires
// 16-byte alignment, hence we hardcode this requirement here..
(unsigned char *) _aligned_malloc(rasterPoolSize, sizeof(void*) * 2);
@@ -3809,7 +3656,7 @@ void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline,
}
}
-#if defined(Q_WS_WIN64)
+#if defined(Q_OS_WIN64)
_aligned_free(rasterPoolBase);
#else
if (rasterPoolBase != rasterPoolOnStack) // initially on the stack
@@ -3896,127 +3743,6 @@ void QRasterBuffer::resetBuffer(int val)
memset(m_buffer, val, m_height*bytes_per_line);
}
-
-#if defined(Q_WS_QWS)
-void QRasterBuffer::prepare(QCustomRasterPaintDevice *device)
-{
- m_buffer = reinterpret_cast<uchar*>(device->memory());
- m_width = qMin(QT_RASTER_COORD_LIMIT, device->width());
- m_height = qMin(QT_RASTER_COORD_LIMIT, device->height());
- bytes_per_pixel = device->depth() / 8;
- bytes_per_line = device->bytesPerLine();
- format = device->format();
-#ifndef QT_NO_RASTERCALLBACKS
- if (!m_buffer)
- drawHelper = qDrawHelperCallback + format;
- else
-#endif
- drawHelper = qDrawHelper + format;
-}
-
-int QCustomRasterPaintDevice::metric(PaintDeviceMetric m) const
-{
- switch (m) {
- case PdmWidth:
- return widget->frameGeometry().width();
- case PdmHeight:
- return widget->frameGeometry().height();
- default:
- break;
- }
-
- return qt_paint_device_metric(widget, m);
-}
-
-int QCustomRasterPaintDevice::bytesPerLine() const
-{
- return (width() * depth() + 7) / 8;
-}
-
-#elif defined(Q_OS_SYMBIAN)
-
-void QRasterBuffer::prepareBuffer(int /* width */, int /* height */)
-{
-}
-
-#endif // Q_OS_SYMBIAN
-
-/*!
- \class QCustomRasterPaintDevice
- \preliminary
- \ingroup qws
- \since 4.2
-
- \brief The QCustomRasterPaintDevice class is provided to activate
- hardware accelerated paint engines in Qt for Embedded Linux.
-
- Note that this class is only available in \l{Qt for Embedded Linux}.
-
- In \l{Qt for Embedded Linux}, painting is a pure software
- implementation. But starting with Qt 4.2, it is
- possible to add an accelerated graphics driver to take advantage
- of available hardware resources.
-
- Hardware acceleration is accomplished by creating a custom screen
- driver, accelerating the copying from memory to the screen, and
- implementing a custom paint engine accelerating the various
- painting operations. Then a custom paint device (derived from the
- QCustomRasterPaintDevice class) and a custom window surface
- (derived from QWSWindowSurface) must be implemented to make
- \l{Qt for Embedded Linux} aware of the accelerated driver.
-
- See the \l {Adding an Accelerated Graphics Driver to Qt for Embedded Linux}
- documentation for details.
-
- \sa QRasterPaintEngine, QPaintDevice
-*/
-
-/*!
- \fn QCustomRasterPaintDevice::QCustomRasterPaintDevice(QWidget *widget)
-
- Constructs a custom raster based paint device for the given
- top-level \a widget.
-*/
-
-/*!
- \fn int QCustomRasterPaintDevice::bytesPerLine() const
-
- Returns the number of bytes per line in the framebuffer. Note that
- this number might be larger than the framebuffer width.
-*/
-
-/*!
- \fn int QCustomRasterPaintDevice::devType() const
- \internal
-*/
-
-/*!
- \fn QImage::Format QCustomRasterPaintDevice::format() const
-
- Returns the format of the device's memory buffet.
-
- The default format is QImage::Format_ARGB32_Premultiplied. The
- only other valid format is QImage::Format_RGB16.
-*/
-
-/*!
- \fn void * QCustomRasterPaintDevice::memory () const
-
- Returns a pointer to the paint device's memory buffer, or 0 if no
- such buffer exists.
-*/
-
-/*!
- \fn int QCustomRasterPaintDevice::metric ( PaintDeviceMetric m ) const
- \reimp
-*/
-
-/*!
- \fn QSize QCustomRasterPaintDevice::size () const
- \internal
-*/
-
-
QClipData::QClipData(int height)
{
clipSpanHeight = height;
@@ -4740,9 +4466,6 @@ Q_GLOBAL_STATIC(QGradientCache, qt_gradient_cache)
void QSpanData::init(QRasterBuffer *rb, const QRasterPaintEngine *pe)
{
rasterBuffer = rb;
-#ifdef Q_WS_QWS
- rasterEngine = const_cast<QRasterPaintEngine *>(pe);
-#endif
type = None;
txop = 0;
bilinear = false;
@@ -4888,16 +4611,7 @@ void QSpanData::adjustSpanMethods()
unclipped_blend = rasterBuffer->drawHelper->blendGradient;
break;
case Texture:
-#ifdef Q_WS_QWS
-#ifndef QT_NO_RASTERCALLBACKS
- if (!rasterBuffer->buffer())
- unclipped_blend = qBlendTextureCallback;
- else
-#endif
- unclipped_blend = qBlendTexture;
-#else
unclipped_blend = qBlendTexture;
-#endif
if (!texture.imageData)
unclipped_blend = 0;
diff --git a/src/gui/painting/qpaintengine_raster_p.h b/src/gui/painting/qpaintengine_raster_p.h
index f9d388d14e..d387e1312a 100644
--- a/src/gui/painting/qpaintengine_raster_p.h
+++ b/src/gui/painting/qpaintengine_raster_p.h
@@ -72,7 +72,6 @@ class QOutlineMapper;
class QRasterPaintEnginePrivate;
class QRasterBuffer;
class QClipData;
-class QCustomRasterPaintDevice;
class QRasterPaintEngineState : public QPainterState
{
@@ -129,11 +128,7 @@ public:
/*******************************************************************************
* QRasterPaintEngine
*/
-class
-#ifdef Q_WS_QWS
-Q_GUI_EXPORT
-#endif
-QRasterPaintEngine : public QPaintEngineEx
+class Q_GUI_EXPORT QRasterPaintEngine : public QPaintEngineEx
{
Q_DECLARE_PRIVATE(QRasterPaintEngine)
public:
@@ -229,10 +224,11 @@ public:
CGContextRef getCGContext() const;
#endif
-#ifdef Q_WS_WIN
+#ifdef Q_OS_WIN
void setDC(HDC hdc);
HDC getDC() const;
void releaseDC(HDC hdc) const;
+ static bool clearTypeFontsEnabled();
#endif
void alphaPenBlt(const void* src, int bpl, int depth, int rx,int ry,int w,int h);
@@ -241,11 +237,6 @@ public:
QPoint coordinateOffset() const;
-#if defined(Q_WS_QWS) && !defined(QT_NO_RASTERCALLBACKS)
- virtual void drawColorSpans(const QSpan *spans, int count, uint color);
- virtual void drawBufferSpan(const uint *buffer, int bufsize,
- int x, int y, int length, uint const_alpha);
-#endif
bool supportsTransformations(const QFontEngine *fontEngine) const;
bool supportsTransformations(qreal pixelSize, const QTransform &m) const;
@@ -295,11 +286,7 @@ private:
/*******************************************************************************
* QRasterPaintEnginePrivate
*/
-class
-#ifdef Q_WS_QWS
-Q_GUI_EXPORT
-#endif
-QRasterPaintEnginePrivate : public QPaintEngineExPrivate
+class QRasterPaintEnginePrivate : public QPaintEngineExPrivate
{
Q_DECLARE_PUBLIC(QRasterPaintEngine)
public:
@@ -331,10 +318,6 @@ public:
ProcessSpans getBrushFunc(const QRect &rect, const QSpanData *data) const;
ProcessSpans getBrushFunc(const QRectF &rect, const QSpanData *data) const;
-#ifdef Q_WS_QWS
- void prepare(QCustomRasterPaintDevice *);
-#endif
-
inline const QClipData *clip() const;
void initializeRasterizer(QSpanData *data);
@@ -346,7 +329,7 @@ public:
QScopedPointer<QOutlineMapper> outlineMapper;
QScopedPointer<QRasterBuffer> rasterBuffer;
-#if defined (Q_WS_WIN)
+#if defined (Q_OS_WIN)
HDC hdc;
#elif defined(Q_WS_MAC)
CGContextRef cgContext;
@@ -378,11 +361,7 @@ public:
};
-class
-#ifdef Q_WS_QWS
-Q_GUI_EXPORT
-#endif
-QClipData {
+class QClipData {
public:
QClipData(int height);
~QClipData();
@@ -459,41 +438,10 @@ inline void QClipData::appendSpans(const QSpan *s, int num)
count += num;
}
-#ifdef Q_WS_QWS
-class Q_GUI_EXPORT QCustomRasterPaintDevice : public QPaintDevice
-{
-public:
- QCustomRasterPaintDevice(QWidget *w) : widget(w) {}
-
- int devType() const { return QInternal::CustomRaster; }
-
- virtual int metric(PaintDeviceMetric m) const;
-
- virtual void* memory() const { return 0; }
-
- virtual QImage::Format format() const {
- return QImage::Format_ARGB32_Premultiplied;
- }
-
- virtual int bytesPerLine() const;
-
- virtual QSize size() const {
- return static_cast<QRasterPaintEngine*>(paintEngine())->size();
- }
-
-private:
- QWidget *widget;
-};
-#endif // Q_WS_QWS
-
/*******************************************************************************
* QRasterBuffer
*/
-class
-#ifdef Q_WS_QWS
-Q_GUI_EXPORT
-#endif
-QRasterBuffer
+class QRasterBuffer
{
public:
QRasterBuffer() : m_width(0), m_height(0), m_buffer(0) { init(); }
@@ -504,9 +452,6 @@ public:
QImage::Format prepare(QImage *image);
QImage::Format prepare(QPixmap *pix);
-#ifdef Q_WS_QWS
- void prepare(QCustomRasterPaintDevice *device);
-#endif
void prepare(int w, int h);
void prepareBuffer(int w, int h);
diff --git a/src/gui/painting/qpaintengine_s60.cpp b/src/gui/painting/qpaintengine_s60.cpp
deleted file mode 100644
index 091e2e65a4..0000000000
--- a/src/gui/painting/qpaintengine_s60.cpp
+++ /dev/null
@@ -1,145 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#include <private/qpaintengine_s60_p.h>
-#include <private/qpixmap_s60_p.h>
-#include <private/qt_s60_p.h>
-#include <private/qvolatileimage_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QS60PaintEnginePrivate : public QRasterPaintEnginePrivate
-{
-public:
- QS60PaintEnginePrivate() {}
-};
-
-QS60PaintEngine::QS60PaintEngine(QPaintDevice *device, QS60PixmapData *data)
- : QRasterPaintEngine(*(new QS60PaintEnginePrivate), device), pixmapData(data)
-{
-}
-
-bool QS60PaintEngine::begin(QPaintDevice *device)
-{
- Q_D(QS60PaintEngine);
-
- if (pixmapData->classId() == QPixmapData::RasterClass) {
- pixmapData->beginDataAccess();
- bool ret = QRasterPaintEngine::begin(device);
- // Make sure QPaintEngine::paintDevice() returns the proper device.
- // QRasterPaintEngine changes pdev to QImage in case of RasterClass QPixmapData
- // which is incorrect in Symbian.
- d->pdev = device;
- return ret;
- }
-
- return QRasterPaintEngine::begin(device);
-}
-
-bool QS60PaintEngine::end()
-{
- if (pixmapData->classId() == QPixmapData::RasterClass) {
- bool ret = QRasterPaintEngine::end();
- pixmapData->endDataAccess();
- return ret;
- }
- return QRasterPaintEngine::end();
-}
-
-void QS60PaintEngine::drawPixmap(const QPointF &p, const QPixmap &pm)
-{
- if (pm.pixmapData()->classId() == QPixmapData::RasterClass) {
- QS60PixmapData *srcData = static_cast<QS60PixmapData *>(pm.pixmapData());
- srcData->beginDataAccess();
- QRasterPaintEngine::drawPixmap(p, pm);
- srcData->endDataAccess();
- } else {
- void *nativeData = pm.pixmapData()->toNativeType(QPixmapData::VolatileImage);
- if (nativeData) {
- QVolatileImage *img = static_cast<QVolatileImage *>(nativeData);
- img->beginDataAccess();
- QRasterPaintEngine::drawImage(p, img->imageRef());
- img->endDataAccess(true);
- } else {
- QRasterPaintEngine::drawPixmap(p, pm);
- }
- }
-}
-
-void QS60PaintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr)
-{
- if (pm.pixmapData()->classId() == QPixmapData::RasterClass) {
- QS60PixmapData *srcData = static_cast<QS60PixmapData *>(pm.pixmapData());
- srcData->beginDataAccess();
- QRasterPaintEngine::drawPixmap(r, pm, sr);
- srcData->endDataAccess();
- } else {
- void *nativeData = pm.pixmapData()->toNativeType(QPixmapData::VolatileImage);
- if (nativeData) {
- QVolatileImage *img = static_cast<QVolatileImage *>(nativeData);
- img->beginDataAccess();
- QRasterPaintEngine::drawImage(r, img->imageRef(), sr);
- img->endDataAccess(true);
- } else {
- QRasterPaintEngine::drawPixmap(r, pm, sr);
- }
- }
-}
-
-void QS60PaintEngine::drawTiledPixmap(const QRectF &r, const QPixmap &pm, const QPointF &sr)
-{
- if (pm.pixmapData()->classId() == QPixmapData::RasterClass) {
- QS60PixmapData *srcData = static_cast<QS60PixmapData *>(pm.pixmapData());
- srcData->beginDataAccess();
- QRasterPaintEngine::drawTiledPixmap(r, pm, sr);
- srcData->endDataAccess();
- } else {
- QRasterPaintEngine::drawTiledPixmap(r, pm, sr);
- }
-}
-
-void QS60PaintEngine::prepare(QImage *image)
-{
- QRasterBuffer *buffer = d_func()->rasterBuffer.data();
- if (buffer)
- buffer->prepare(image);
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/painting/qpaintengine_s60_p.h b/src/gui/painting/qpaintengine_s60_p.h
deleted file mode 100644
index 2a3b443db3..0000000000
--- a/src/gui/painting/qpaintengine_s60_p.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPAINTENGINE_S60_P_H
-#define QPAINTENGINE_S60_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "private/qpaintengine_raster_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class QS60PaintEnginePrivate;
-class QS60PixmapData;
-
-class QS60PaintEngine : public QRasterPaintEngine
-{
- Q_DECLARE_PRIVATE(QS60PaintEngine)
-
-public:
- QS60PaintEngine(QPaintDevice *device, QS60PixmapData* data);
- bool begin(QPaintDevice *device);
- bool end();
-
- void drawPixmap(const QPointF &p, const QPixmap &pm);
- void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr);
- void drawTiledPixmap(const QRectF &r, const QPixmap &pm, const QPointF &sr);
-
- void prepare(QImage* image);
-
-private:
- QS60PixmapData *pixmapData;
-};
-
-QT_END_NAMESPACE
-
-#endif // QPAINTENGINE_S60_P_H
diff --git a/src/gui/painting/qpaintengine_x11.cpp b/src/gui/painting/qpaintengine_x11.cpp
deleted file mode 100644
index 62c1dacf05..0000000000
--- a/src/gui/painting/qpaintengine_x11.cpp
+++ /dev/null
@@ -1,2499 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qplatformdefs.h"
-
-#include "private/qpixmap_x11_p.h"
-
-#include "qapplication.h"
-#include "qdebug.h"
-#include "qfont.h"
-#include "qwidget.h"
-#include "qbitmap.h"
-#include "qpixmapcache.h"
-#include "qtextcodec.h"
-#include "qcoreevent.h"
-#include "qiodevice.h"
-#include <qmath.h>
-
-#include "qpainter_p.h"
-#include <qtextlayout.h>
-#include <qvarlengtharray.h>
-#include <private/qfont_p.h>
-#include <private/qtextengine_p.h>
-#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"
-#include "qcolormap.h"
-
-#include <private/qpaintengine_p.h>
-#include "qpaintengine_x11_p.h"
-
-#include <private/qt_x11_p.h>
-#include <private/qnumeric_p.h>
-#include <limits.h>
-
-#ifndef QT_NO_XRENDER
-#include <private/qtessellator_p.h>
-#endif
-
-#include <private/qstylehelper_p.h>
-
-QT_BEGIN_NAMESPACE
-
-extern Drawable qt_x11Handle(const QPaintDevice *pd);
-extern const QX11Info *qt_x11Info(const QPaintDevice *pd);
-extern QPixmap qt_pixmapForBrush(int brushStyle, bool invert); //in qbrush.cpp
-extern QPixmap qt_toX11Pixmap(const QPixmap &pixmap);
-
-// use the same rounding as in qrasterizer.cpp (6 bit fixed point)
-static const qreal aliasedCoordinateDelta = 0.5 - 0.015625;
-
-#undef X11 // defined in qt_x11_p.h
-/*!
- Returns the X11 specific pen GC for the painter \a p. Note that
- QPainter::begin() must be called before this function returns a
- valid GC.
-*/
-Q_GUI_EXPORT GC qt_x11_get_pen_gc(QPainter *p)
-{
- if (p && p->paintEngine()
- && p->paintEngine()->isActive()
- && p->paintEngine()->type() == QPaintEngine::X11) {
- return static_cast<QX11PaintEngine *>(p->paintEngine())->d_func()->gc;
- }
- return 0;
-}
-
-/*!
- Returns the X11 specific brush GC for the painter \a p. Note that
- QPainter::begin() must be called before this function returns a
- valid GC.
-*/
-Q_GUI_EXPORT GC qt_x11_get_brush_gc(QPainter *p)
-{
- if (p && p->paintEngine()
- && p->paintEngine()->isActive()
- && p->paintEngine()->type() == QPaintEngine::X11) {
- return static_cast<QX11PaintEngine *>(p->paintEngine())->d_func()->gc_brush;
- }
- return 0;
-}
-#define X11 qt_x11Data
-
-#ifndef QT_NO_XRENDER
-static const int compositionModeToRenderOp[QPainter::CompositionMode_Xor + 1] = {
- PictOpOver, //CompositionMode_SourceOver,
- PictOpOverReverse, //CompositionMode_DestinationOver,
- PictOpClear, //CompositionMode_Clear,
- PictOpSrc, //CompositionMode_Source,
- PictOpDst, //CompositionMode_Destination,
- PictOpIn, //CompositionMode_SourceIn,
- PictOpInReverse, //CompositionMode_DestinationIn,
- PictOpOut, //CompositionMode_SourceOut,
- PictOpOutReverse, //CompositionMode_DestinationOut,
- PictOpAtop, //CompositionMode_SourceAtop,
- PictOpAtopReverse, //CompositionMode_DestinationAtop,
- PictOpXor //CompositionMode_Xor
-};
-
-static inline int qpainterOpToXrender(QPainter::CompositionMode mode)
-{
- Q_ASSERT(mode <= QPainter::CompositionMode_Xor);
- return compositionModeToRenderOp[mode];
-}
-#endif
-
-// hack, so we don't have to make QRegion::clipRectangles() public or include
-// X11 headers in qregion.h
-Q_GUI_EXPORT void *qt_getClipRects(const QRegion &r, int &num)
-{
- return r.clipRectangles(num);
-}
-
-static inline void x11SetClipRegion(Display *dpy, GC gc, GC gc2,
-#ifndef QT_NO_XRENDER
- Picture picture,
-#else
- Qt::HANDLE picture,
-#endif
- const QRegion &r)
-{
- int num;
- XRectangle *rects = (XRectangle *)qt_getClipRects(r, num);
-
- if (gc)
- XSetClipRectangles( dpy, gc, 0, 0, rects, num, YXBanded );
- if (gc2)
- XSetClipRectangles( dpy, gc2, 0, 0, rects, num, YXBanded );
-
-#ifndef QT_NO_XRENDER
- if (picture)
- XRenderSetPictureClipRectangles(dpy, picture, 0, 0, rects, num);
-#else
- Q_UNUSED(picture);
-#endif // QT_NO_XRENDER
-}
-
-
-static inline void x11ClearClipRegion(Display *dpy, GC gc, GC gc2,
-#ifndef QT_NO_XRENDER
- Picture picture
-#else
- Qt::HANDLE picture
-#endif
- )
-{
- if (gc)
- XSetClipMask(dpy, gc, XNone);
- if (gc2)
- XSetClipMask(dpy, gc2, XNone);
-
-#ifndef QT_NO_XRENDER
- if (picture) {
- XRenderPictureAttributes attrs;
- attrs.clip_mask = XNone;
- XRenderChangePicture (dpy, picture, CPClipMask, &attrs);
- }
-#else
- Q_UNUSED(picture);
-#endif // QT_NO_XRENDER
-}
-
-
-#define DITHER_SIZE 16
-static const uchar base_dither_matrix[DITHER_SIZE][DITHER_SIZE] = {
- { 0,192, 48,240, 12,204, 60,252, 3,195, 51,243, 15,207, 63,255 },
- { 128, 64,176,112,140, 76,188,124,131, 67,179,115,143, 79,191,127 },
- { 32,224, 16,208, 44,236, 28,220, 35,227, 19,211, 47,239, 31,223 },
- { 160, 96,144, 80,172,108,156, 92,163, 99,147, 83,175,111,159, 95 },
- { 8,200, 56,248, 4,196, 52,244, 11,203, 59,251, 7,199, 55,247 },
- { 136, 72,184,120,132, 68,180,116,139, 75,187,123,135, 71,183,119 },
- { 40,232, 24,216, 36,228, 20,212, 43,235, 27,219, 39,231, 23,215 },
- { 168,104,152, 88,164,100,148, 84,171,107,155, 91,167,103,151, 87 },
- { 2,194, 50,242, 14,206, 62,254, 1,193, 49,241, 13,205, 61,253 },
- { 130, 66,178,114,142, 78,190,126,129, 65,177,113,141, 77,189,125 },
- { 34,226, 18,210, 46,238, 30,222, 33,225, 17,209, 45,237, 29,221 },
- { 162, 98,146, 82,174,110,158, 94,161, 97,145, 81,173,109,157, 93 },
- { 10,202, 58,250, 6,198, 54,246, 9,201, 57,249, 5,197, 53,245 },
- { 138, 74,186,122,134, 70,182,118,137, 73,185,121,133, 69,181,117 },
- { 42,234, 26,218, 38,230, 22,214, 41,233, 25,217, 37,229, 21,213 },
- { 170,106,154, 90,166,102,150, 86,169,105,153, 89,165,101,149, 85 }
-};
-
-static QPixmap qt_patternForAlpha(uchar alpha, int screen)
-{
- QPixmap pm;
- QString key = QLatin1Literal("$qt-alpha-brush$")
- % HexString<uchar>(alpha)
- % HexString<int>(screen);
-
- if (!QPixmapCache::find(key, pm)) {
- // #### why not use a mono image here????
- QImage pattern(DITHER_SIZE, DITHER_SIZE, QImage::Format_ARGB32);
- pattern.fill(0xffffffff);
- for (int y = 0; y < DITHER_SIZE; ++y) {
- for (int x = 0; x < DITHER_SIZE; ++x) {
- if (base_dither_matrix[x][y] <= alpha)
- pattern.setPixel(x, y, 0x00000000);
- }
- }
- pm = QBitmap::fromImage(pattern);
- pm.x11SetScreen(screen);
- QPixmapCache::insert(key, pm);
- }
- return pm;
-}
-
-#if !defined(QT_NO_XRENDER)
-
-class QXRenderTessellator : public QTessellator
-{
-public:
- QXRenderTessellator() : traps(0), allocated(0), size(0) {}
- ~QXRenderTessellator() { free(traps); }
- XTrapezoid *traps;
- int allocated;
- int size;
- void addTrap(const Trapezoid &trap);
- QRect tessellate(const QPointF *points, int nPoints, bool winding) {
- size = 0;
- setWinding(winding);
- return QTessellator::tessellate(points, nPoints).toRect();
- }
- void done() {
- if (allocated > 64) {
- free(traps);
- traps = 0;
- allocated = 0;
- }
- }
-};
-
-void QXRenderTessellator::addTrap(const Trapezoid &trap)
-{
- if (size == allocated) {
- allocated = qMax(2*allocated, 64);
- traps = q_check_ptr((XTrapezoid *)realloc(traps, allocated * sizeof(XTrapezoid)));
- }
- traps[size].top = Q27Dot5ToXFixed(trap.top);
- traps[size].bottom = Q27Dot5ToXFixed(trap.bottom);
- traps[size].left.p1.x = Q27Dot5ToXFixed(trap.topLeft->x);
- traps[size].left.p1.y = Q27Dot5ToXFixed(trap.topLeft->y);
- traps[size].left.p2.x = Q27Dot5ToXFixed(trap.bottomLeft->x);
- traps[size].left.p2.y = Q27Dot5ToXFixed(trap.bottomLeft->y);
- traps[size].right.p1.x = Q27Dot5ToXFixed(trap.topRight->x);
- traps[size].right.p1.y = Q27Dot5ToXFixed(trap.topRight->y);
- traps[size].right.p2.x = Q27Dot5ToXFixed(trap.bottomRight->x);
- traps[size].right.p2.y = Q27Dot5ToXFixed(trap.bottomRight->y);
- ++size;
-}
-
-#endif // !defined(QT_NO_XRENDER)
-
-
-#ifndef QT_NO_XRENDER
-static Picture getPatternFill(int screen, const QBrush &b)
-{
- if (!X11->use_xrender)
- return XNone;
-
- XRenderColor color = X11->preMultiply(b.color());
- XRenderColor bg_color;
-
- bg_color = X11->preMultiply(QColor(0, 0, 0, 0));
-
- for (int i = 0; i < X11->pattern_fill_count; ++i) {
- if (X11->pattern_fills[i].screen == screen
- && X11->pattern_fills[i].opaque == false
- && X11->pattern_fills[i].style == b.style()
- && X11->pattern_fills[i].color.alpha == color.alpha
- && X11->pattern_fills[i].color.red == color.red
- && X11->pattern_fills[i].color.green == color.green
- && X11->pattern_fills[i].color.blue == color.blue
- && X11->pattern_fills[i].bg_color.alpha == bg_color.alpha
- && X11->pattern_fills[i].bg_color.red == bg_color.red
- && X11->pattern_fills[i].bg_color.green == bg_color.green
- && X11->pattern_fills[i].bg_color.blue == bg_color.blue)
- return X11->pattern_fills[i].picture;
- }
- // none found, replace one
- int i = qrand() % 16;
-
- if (X11->pattern_fills[i].screen != screen && X11->pattern_fills[i].picture) {
- XRenderFreePicture (X11->display, X11->pattern_fills[i].picture);
- X11->pattern_fills[i].picture = 0;
- }
-
- if (!X11->pattern_fills[i].picture) {
- Pixmap pixmap = XCreatePixmap (X11->display, RootWindow (X11->display, screen), 8, 8, 32);
- XRenderPictureAttributes attrs;
- attrs.repeat = True;
- X11->pattern_fills[i].picture = XRenderCreatePicture (X11->display, pixmap,
- XRenderFindStandardFormat(X11->display, PictStandardARGB32),
- CPRepeat, &attrs);
- XFreePixmap (X11->display, pixmap);
- }
-
- X11->pattern_fills[i].screen = screen;
- X11->pattern_fills[i].color = color;
- X11->pattern_fills[i].bg_color = bg_color;
- X11->pattern_fills[i].opaque = false;
- X11->pattern_fills[i].style = b.style();
-
- XRenderFillRectangle(X11->display, PictOpSrc, X11->pattern_fills[i].picture, &bg_color, 0, 0, 8, 8);
-
- QPixmap pattern(qt_pixmapForBrush(b.style(), true));
- XRenderPictureAttributes attrs;
- attrs.repeat = true;
- XRenderChangePicture(X11->display, pattern.x11PictureHandle(), CPRepeat, &attrs);
-
- Picture fill_fg = X11->getSolidFill(screen, b.color());
- XRenderComposite(X11->display, PictOpOver, fill_fg, pattern.x11PictureHandle(),
- X11->pattern_fills[i].picture,
- 0, 0, 0, 0, 0, 0, 8, 8);
-
- return X11->pattern_fills[i].picture;
-}
-
-static void qt_render_bitmap(Display *dpy, int scrn, Picture src, Picture dst,
- int sx, int sy, int x, int y, int sw, int sh,
- const QPen &pen)
-{
- Picture fill_fg = X11->getSolidFill(scrn, pen.color());
- XRenderComposite(dpy, PictOpOver,
- fill_fg, src, dst, sx, sy, sx, sy, x, y, sw, sh);
-}
-#endif
-
-void QX11PaintEnginePrivate::init()
-{
- dpy = 0;
- scrn = 0;
- hd = 0;
- picture = 0;
- xinfo = 0;
-#ifndef QT_NO_XRENDER
- current_brush = 0;
- composition_mode = PictOpOver;
- tessellator = new QXRenderTessellator;
-#endif
-}
-
-void QX11PaintEnginePrivate::setupAdaptedOrigin(const QPoint &p)
-{
- if (adapted_pen_origin)
- XSetTSOrigin(dpy, gc, p.x(), p.y());
- if (adapted_brush_origin)
- XSetTSOrigin(dpy, gc_brush, p.x(), p.y());
-}
-
-void QX11PaintEnginePrivate::resetAdaptedOrigin()
-{
- if (adapted_pen_origin)
- XSetTSOrigin(dpy, gc, 0, 0);
- if (adapted_brush_origin)
- XSetTSOrigin(dpy, gc_brush, 0, 0);
-}
-
-void QX11PaintEnginePrivate::clipPolygon_dev(const QPolygonF &poly, QPolygonF *clipped_poly)
-{
- int clipped_count = 0;
- qt_float_point *clipped_points = 0;
- polygonClipper.clipPolygon((qt_float_point *) poly.data(), poly.size(),
- &clipped_points, &clipped_count);
- clipped_poly->resize(clipped_count);
- for (int i=0; i<clipped_count; ++i)
- (*clipped_poly)[i] = *((QPointF *)(&clipped_points[i]));
-}
-
-void QX11PaintEnginePrivate::systemStateChanged()
-{
- Q_Q(QX11PaintEngine);
- QPainter *painter = q->state ? static_cast<QPainterState *>(q->state)->painter : 0;
- if (painter && painter->hasClipping()) {
- if (q->testDirty(QPaintEngine::DirtyTransform))
- q->updateMatrix(q->state->transform());
- QPolygonF clip_poly_dev(matrix.map(painter->clipPath().toFillPolygon()));
- QPolygonF clipped_poly_dev;
- clipPolygon_dev(clip_poly_dev, &clipped_poly_dev);
- q->updateClipRegion_dev(QRegion(clipped_poly_dev.toPolygon()), Qt::ReplaceClip);
- } else {
- q->updateClipRegion_dev(QRegion(), Qt::NoClip);
- }
-}
-
-static QPaintEngine::PaintEngineFeatures qt_decide_features()
-{
- QPaintEngine::PaintEngineFeatures features =
- QPaintEngine::PrimitiveTransform
- | QPaintEngine::PatternBrush
- | QPaintEngine::AlphaBlend
- | QPaintEngine::PainterPaths
- | QPaintEngine::RasterOpModes;
-
- if (X11->use_xrender) {
- features |= QPaintEngine::Antialiasing;
- features |= QPaintEngine::PorterDuff;
- features |= QPaintEngine::MaskedBrush;
-#if 0
- if (X11->xrender_version > 10) {
- features |= QPaintEngine::LinearGradientFill;
- // ###
- }
-#endif
- }
-
- return features;
-}
-
-/*
- * QX11PaintEngine members
- */
-
-QX11PaintEngine::QX11PaintEngine()
- : QPaintEngine(*(new QX11PaintEnginePrivate), qt_decide_features())
-{
- d_func()->init();
-}
-
-QX11PaintEngine::QX11PaintEngine(QX11PaintEnginePrivate &dptr)
- : QPaintEngine(dptr, qt_decide_features())
-{
- d_func()->init();
-}
-
-QX11PaintEngine::~QX11PaintEngine()
-{
-#ifndef QT_NO_XRENDER
- Q_D(QX11PaintEngine);
- delete d->tessellator;
-#endif
-}
-
-bool QX11PaintEngine::begin(QPaintDevice *pdev)
-{
- Q_D(QX11PaintEngine);
- d->xinfo = qt_x11Info(pdev);
- QWidget *w = d->pdev->devType() == QInternal::Widget ? static_cast<QWidget *>(d->pdev) : 0;
- const bool isAlienWidget = w && !w->internalWinId() && w->testAttribute(Qt::WA_WState_Created);
-#ifndef QT_NO_XRENDER
- if (w) {
- if (isAlienWidget)
- d->picture = (::Picture)w->nativeParentWidget()->x11PictureHandle();
- else
- d->picture = (::Picture)w->x11PictureHandle();
- } else if (pdev->devType() == QInternal::Pixmap) {
- const QPixmap *pm = static_cast<const QPixmap *>(pdev);
- QX11PixmapData *data = static_cast<QX11PixmapData*>(pm->data.data());
- if (X11->use_xrender && data->depth() != 32 && data->x11_mask)
- data->convertToARGB32();
- d->picture = (::Picture)static_cast<const QPixmap *>(pdev)->x11PictureHandle();
- }
-#else
- d->picture = 0;
-#endif
- d->hd = !isAlienWidget ? qt_x11Handle(pdev) : qt_x11Handle(w->nativeParentWidget());
-
- Q_ASSERT(d->xinfo != 0);
- d->dpy = d->xinfo->display(); // get display variable
- d->scrn = d->xinfo->screen(); // get screen variable
-
- d->crgn = QRegion();
- d->gc = XCreateGC(d->dpy, d->hd, 0, 0);
- d->gc_brush = XCreateGC(d->dpy, d->hd, 0, 0);
- d->has_alpha_brush = false;
- d->has_alpha_pen = false;
- d->has_clipping = false;
- d->has_complex_xform = false;
- d->has_scaling_xform = false;
- d->has_non_scaling_xform = true;
- d->xform_scale = 1;
- d->has_custom_pen = false;
- d->matrix = QTransform();
- d->pdev_depth = d->pdev->depth();
- d->render_hints = 0;
- d->txop = QTransform::TxNone;
- d->use_path_fallback = false;
-#if !defined(QT_NO_XRENDER)
- d->composition_mode = PictOpOver;
-#endif
- d->xlibMaxLinePoints = 32762; // a safe number used to avoid, call to XMaxRequestSize(d->dpy) - 3;
- d->opacity = 1;
-
- // Set up the polygon clipper. Note: This will only work in
- // polyline mode as long as we have a buffer zone, since a
- // polyline may be clipped into several non-connected polylines.
- const int BUFFERZONE = 1000;
- QRect devClipRect(-BUFFERZONE, -BUFFERZONE,
- pdev->width() + 2*BUFFERZONE, pdev->height() + 2*BUFFERZONE);
- d->polygonClipper.setBoundingRect(devClipRect);
-
- if (isAlienWidget) {
- // Set system clip for alien widgets painting outside the paint event.
- // This is not a problem with native windows since the windowing system
- // will handle the clip.
- QWidgetPrivate *wd = w->d_func();
- QRegion widgetClip(wd->clipRect());
- wd->clipToEffectiveMask(widgetClip);
- wd->subtractOpaqueSiblings(widgetClip);
- widgetClip.translate(w->mapTo(w->nativeParentWidget(), QPoint()));
- setSystemClip(widgetClip);
- }
-
- QPixmap::x11SetDefaultScreen(d->xinfo->screen());
-
- if (w && w->testAttribute(Qt::WA_PaintUnclipped)) { // paint direct on device
- updatePen(QPen(Qt::black));
- updateBrush(QBrush(Qt::white), QPoint());
- XSetSubwindowMode(d->dpy, d->gc, IncludeInferiors);
- XSetSubwindowMode(d->dpy, d->gc_brush, IncludeInferiors);
-#ifndef QT_NO_XRENDER
- XRenderPictureAttributes attrs;
- attrs.subwindow_mode = IncludeInferiors;
- XRenderChangePicture(d->dpy, d->picture, CPSubwindowMode, &attrs);
-#endif
- }
-
- setDirty(QPaintEngine::DirtyClipRegion);
- setDirty(QPaintEngine::DirtyPen);
- setDirty(QPaintEngine::DirtyBrush);
- setDirty(QPaintEngine::DirtyBackground);
-
- return true;
-}
-
-bool QX11PaintEngine::end()
-{
- Q_D(QX11PaintEngine);
-
-#if !defined(QT_NO_XRENDER)
- if (d->picture) {
- // reset clipping/subwindow mode on our render picture
- XRenderPictureAttributes attrs;
- attrs.subwindow_mode = ClipByChildren;
- attrs.clip_mask = XNone;
- XRenderChangePicture(d->dpy, d->picture, CPClipMask|CPSubwindowMode, &attrs);
- }
-#endif
-
- if (d->gc_brush && d->pdev->painters < 2) {
- XFreeGC(d->dpy, d->gc_brush);
- d->gc_brush = 0;
- }
-
- if (d->gc && d->pdev->painters < 2) {
- XFreeGC(d->dpy, d->gc);
- d->gc = 0;
- }
-
- // Restore system clip for alien widgets painting outside the paint event.
- if (d->pdev->devType() == QInternal::Widget && !static_cast<QWidget *>(d->pdev)->internalWinId())
- setSystemClip(QRegion());
-
- return true;
-}
-
-static bool clipLine(QLineF *line, const QRect &rect)
-{
- qreal x1 = line->x1();
- qreal x2 = line->x2();
- qreal y1 = line->y1();
- qreal y2 = line->y2();
-
- qreal left = rect.x();
- qreal right = rect.x() + rect.width() - 1;
- qreal top = rect.y();
- qreal bottom = rect.y() + rect.height() - 1;
-
- enum { Left, Right, Top, Bottom };
- // clip the lines, after cohen-sutherland, see e.g. http://www.nondot.org/~sabre/graphpro/line6.html
- int p1 = ((x1 < left) << Left)
- | ((x1 > right) << Right)
- | ((y1 < top) << Top)
- | ((y1 > bottom) << Bottom);
- int p2 = ((x2 < left) << Left)
- | ((x2 > right) << Right)
- | ((y2 < top) << Top)
- | ((y2 > bottom) << Bottom);
-
- if (p1 & p2)
- // completely outside
- return false;
-
- if (p1 | p2) {
- qreal dx = x2 - x1;
- qreal dy = y2 - y1;
-
- // clip x coordinates
- if (x1 < left) {
- y1 += dy/dx * (left - x1);
- x1 = left;
- } else if (x1 > right) {
- y1 -= dy/dx * (x1 - right);
- x1 = right;
- }
- if (x2 < left) {
- y2 += dy/dx * (left - x2);
- x2 = left;
- } else if (x2 > right) {
- y2 -= dy/dx * (x2 - right);
- x2 = right;
- }
- p1 = ((y1 < top) << Top)
- | ((y1 > bottom) << Bottom);
- p2 = ((y2 < top) << Top)
- | ((y2 > bottom) << Bottom);
- if (p1 & p2)
- return false;
- // clip y coordinates
- if (y1 < top) {
- x1 += dx/dy * (top - y1);
- y1 = top;
- } else if (y1 > bottom) {
- x1 -= dx/dy * (y1 - bottom);
- y1 = bottom;
- }
- if (y2 < top) {
- x2 += dx/dy * (top - y2);
- y2 = top;
- } else if (y2 > bottom) {
- x2 -= dx/dy * (y2 - bottom);
- y2 = bottom;
- }
- *line = QLineF(QPointF(x1, y1), QPointF(x2, y2));
- }
- return true;
-}
-
-void QX11PaintEngine::drawLines(const QLine *lines, int lineCount)
-{
- Q_ASSERT(lines);
- Q_ASSERT(lineCount);
- Q_D(QX11PaintEngine);
- if (d->has_alpha_brush
- || d->has_alpha_pen
- || d->has_custom_pen
- || (d->cpen.widthF() > 0 && d->has_complex_xform
- && !d->has_non_scaling_xform)
- || (d->render_hints & QPainter::Antialiasing)) {
- for (int i = 0; i < lineCount; ++i) {
- QPainterPath path(lines[i].p1());
- path.lineTo(lines[i].p2());
- drawPath(path);
- }
- return;
- }
-
- if (d->has_pen) {
- for (int i = 0; i < lineCount; ++i) {
- QLineF linef;
- if (d->txop == QTransform::TxNone) {
- linef = lines[i];
- } else {
- linef = d->matrix.map(QLineF(lines[i]));
- }
- if (clipLine(&linef, d->polygonClipper.boundingRect())) {
- int x1 = qRound(linef.x1() + aliasedCoordinateDelta);
- int y1 = qRound(linef.y1() + aliasedCoordinateDelta);
- int x2 = qRound(linef.x2() + aliasedCoordinateDelta);
- int y2 = qRound(linef.y2() + aliasedCoordinateDelta);
-
- XDrawLine(d->dpy, d->hd, d->gc, x1, y1, x2, y2);
- }
- }
- }
-}
-
-void QX11PaintEngine::drawLines(const QLineF *lines, int lineCount)
-{
- Q_ASSERT(lines);
- Q_ASSERT(lineCount);
- Q_D(QX11PaintEngine);
- if (d->has_alpha_brush
- || d->has_alpha_pen
- || d->has_custom_pen
- || (d->cpen.widthF() > 0 && d->has_complex_xform
- && !d->has_non_scaling_xform)
- || (d->render_hints & QPainter::Antialiasing)) {
- for (int i = 0; i < lineCount; ++i) {
- QPainterPath path(lines[i].p1());
- path.lineTo(lines[i].p2());
- drawPath(path);
- }
- return;
- }
-
- if (d->has_pen) {
- for (int i = 0; i < lineCount; ++i) {
- QLineF linef = d->matrix.map(lines[i]);
- if (clipLine(&linef, d->polygonClipper.boundingRect())) {
- int x1 = qRound(linef.x1() + aliasedCoordinateDelta);
- int y1 = qRound(linef.y1() + aliasedCoordinateDelta);
- int x2 = qRound(linef.x2() + aliasedCoordinateDelta);
- int y2 = qRound(linef.y2() + aliasedCoordinateDelta);
-
- XDrawLine(d->dpy, d->hd, d->gc, x1, y1, x2, y2);
- }
- }
- }
-}
-
-static inline QLine clipStraightLine(const QRect &clip, const QLine &l)
-{
- if (l.p1().x() == l.p2().x()) {
- int x = qBound(clip.left(), l.p1().x(), clip.right());
- int y1 = qBound(clip.top(), l.p1().y(), clip.bottom());
- int y2 = qBound(clip.top(), l.p2().y(), clip.bottom());
-
- return QLine(x, y1, x, y2);
- } else {
- Q_ASSERT(l.p1().y() == l.p2().y());
-
- int x1 = qBound(clip.left(), l.p1().x(), clip.right());
- int x2 = qBound(clip.left(), l.p2().x(), clip.right());
- int y = qBound(clip.top(), l.p1().y(), clip.bottom());
-
- return QLine(x1, y, x2, y);
- }
-}
-
-void QX11PaintEngine::drawRects(const QRectF *rects, int rectCount)
-{
- Q_D(QX11PaintEngine);
- Q_ASSERT(rects);
- Q_ASSERT(rectCount);
-
- if (rectCount != 1
- || d->has_pen
- || d->has_alpha_brush
- || d->has_complex_xform
- || d->has_custom_pen
- || d->cbrush.style() != Qt::SolidPattern)
- {
- QPaintEngine::drawRects(rects, rectCount);
- return;
- }
-
- QPoint alignedOffset;
- if (d->txop == QTransform::TxTranslate) {
- QPointF offset(d->matrix.dx(), d->matrix.dy());
- alignedOffset = offset.toPoint();
- if (offset != QPointF(alignedOffset)) {
- QPaintEngine::drawRects(rects, rectCount);
- return;
- }
- }
-
- const QRectF& r = rects[0];
- QRect alignedRect = r.toAlignedRect();
- if (r != QRectF(alignedRect)) {
- QPaintEngine::drawRects(rects, rectCount);
- return;
- }
- alignedRect.translate(alignedOffset);
-
- QRect clip(d->polygonClipper.boundingRect());
- alignedRect = alignedRect.intersected(clip);
- if (alignedRect.isEmpty())
- return;
-
- // simple-case:
- // the rectangle is pixel-aligned
- // the fill brush is just a solid non-alpha color
- // the painter transform is only integer translation
- // ignore: antialiasing and just XFillRectangles directly
- XRectangle xrect;
- xrect.x = short(alignedRect.x());
- xrect.y = short(alignedRect.y());
- xrect.width = ushort(alignedRect.width());
- xrect.height = ushort(alignedRect.height());
- XFillRectangles(d->dpy, d->hd, d->gc_brush, &xrect, 1);
-}
-
-void QX11PaintEngine::drawRects(const QRect *rects, int rectCount)
-{
- Q_D(QX11PaintEngine);
- Q_ASSERT(rects);
- Q_ASSERT(rectCount);
-
- if (d->has_alpha_pen
- || d->has_complex_xform
- || d->has_custom_pen
- || (d->render_hints & QPainter::Antialiasing))
- {
- for (int i = 0; i < rectCount; ++i) {
- QPainterPath path;
- path.addRect(rects[i]);
- drawPath(path);
- }
- return;
- }
-
- QRect clip(d->polygonClipper.boundingRect());
- QPoint offset(qRound(d->matrix.dx()), qRound(d->matrix.dy()));
-#if !defined(QT_NO_XRENDER)
- ::Picture pict = d->picture;
-
- if (X11->use_xrender && pict && d->has_brush && d->pdev_depth != 1
- && (d->has_texture || d->has_alpha_brush))
- {
- XRenderColor xc;
- if (!d->has_texture && !d->has_pattern)
- xc = X11->preMultiply(d->cbrush.color());
-
- for (int i = 0; i < rectCount; ++i) {
- QRect r(rects[i]);
- if (d->txop == QTransform::TxTranslate)
- r.translate(offset);
-
- if (r.width() == 0 || r.height() == 0) {
- if (d->has_pen) {
- const QLine l = clipStraightLine(clip, QLine(r.left(), r.top(), r.left() + r.width(), r.top() + r.height()));
- XDrawLine(d->dpy, d->hd, d->gc, l.p1().x(), l.p1().y(), l.p2().x(), l.p2().y());
- }
- continue;
- }
-
- r = r.intersected(clip);
- if (r.isEmpty())
- continue;
- if (d->has_texture || d->has_pattern) {
- XRenderComposite(d->dpy, d->composition_mode, d->current_brush, 0, pict,
- qRound(r.x() - d->bg_origin.x()), qRound(r.y() - d->bg_origin.y()),
- 0, 0, r.x(), r.y(), r.width(), r.height());
- } else {
- XRenderFillRectangle(d->dpy, d->composition_mode, pict, &xc, r.x(), r.y(), r.width(), r.height());
- }
- if (d->has_pen)
- XDrawRectangle(d->dpy, d->hd, d->gc, r.x(), r.y(), r.width(), r.height());
- }
- } else
-#endif // !QT_NO_XRENDER
- {
- if (d->has_brush && d->has_pen) {
- for (int i = 0; i < rectCount; ++i) {
- QRect r(rects[i]);
- if (d->txop == QTransform::TxTranslate)
- r.translate(offset);
-
- if (r.width() == 0 || r.height() == 0) {
- const QLine l = clipStraightLine(clip, QLine(r.left(), r.top(), r.left() + r.width(), r.top() + r.height()));
- XDrawLine(d->dpy, d->hd, d->gc, l.p1().x(), l.p1().y(), l.p2().x(), l.p2().y());
- continue;
- }
-
- r = r.intersected(clip);
- if (r.isEmpty())
- continue;
- d->setupAdaptedOrigin(r.topLeft());
- XFillRectangle(d->dpy, d->hd, d->gc_brush, r.x(), r.y(), r.width(), r.height());
- XDrawRectangle(d->dpy, d->hd, d->gc, r.x(), r.y(), r.width(), r.height());
- }
- d->resetAdaptedOrigin();
- } else {
- QVarLengthArray<XRectangle> xrects(rectCount);
- int numClipped = rectCount;
- for (int i = 0; i < rectCount; ++i) {
- QRect r(rects[i]);
- if (d->txop == QTransform::TxTranslate)
- r.translate(offset);
-
- if (r.width() == 0 || r.height() == 0) {
- --numClipped;
- if (d->has_pen) {
- const QLine l = clipStraightLine(clip, QLine(r.left(), r.top(), r.left() + r.width(), r.top() + r.height()));
- XDrawLine(d->dpy, d->hd, d->gc, l.p1().x(), l.p1().y(), l.p2().x(), l.p2().y());
- }
- continue;
- }
-
- r = r.intersected(clip);
- if (r.isEmpty()) {
- --numClipped;
- continue;
- }
- xrects[i].x = short(r.x());
- xrects[i].y = short(r.y());
- xrects[i].width = ushort(r.width());
- xrects[i].height = ushort(r.height());
- }
- if (numClipped) {
- d->setupAdaptedOrigin(rects[0].topLeft());
- if (d->has_brush)
- XFillRectangles(d->dpy, d->hd, d->gc_brush, xrects.data(), numClipped);
- else if (d->has_pen)
- XDrawRectangles(d->dpy, d->hd, d->gc, xrects.data(), numClipped);
- d->resetAdaptedOrigin();
- }
- }
- }
-}
-
-static inline void setCapStyle(int cap_style, GC gc)
-{
- ulong mask = GCCapStyle;
- XGCValues vals;
- vals.cap_style = cap_style;
- XChangeGC(X11->display, gc, mask, &vals);
-}
-
-void QX11PaintEngine::drawPoints(const QPoint *points, int pointCount)
-{
- Q_ASSERT(points);
- Q_ASSERT(pointCount);
- Q_D(QX11PaintEngine);
-
- if (!d->has_pen)
- return;
-
- // use the same test here as in drawPath to ensure that we don't use the path fallback
- // and end up in XDrawLines for pens with width <= 1
- if (d->cpen.widthF() > 1.0f
- || (X11->use_xrender && (d->has_alpha_pen || (d->render_hints & QPainter::Antialiasing)))
- || (!d->cpen.isCosmetic() && d->txop > QTransform::TxTranslate))
- {
- Qt::PenCapStyle capStyle = d->cpen.capStyle();
- if (capStyle == Qt::FlatCap) {
- setCapStyle(CapProjecting, d->gc);
- d->cpen.setCapStyle(Qt::SquareCap);
- }
- const QPoint *end = points + pointCount;
- while (points < end) {
- QPainterPath path;
- path.moveTo(*points);
- path.lineTo(points->x()+.005, points->y());
- drawPath(path);
- ++points;
- }
-
- if (capStyle == Qt::FlatCap) {
- setCapStyle(CapButt, d->gc);
- d->cpen.setCapStyle(capStyle);
- }
- return;
- }
-
- static const int BUF_SIZE = 1024;
- XPoint xPoints[BUF_SIZE];
- int i = 0, j = 0;
- while (i < pointCount) {
- while (i < pointCount && j < BUF_SIZE) {
- const QPoint &xformed = d->matrix.map(points[i]);
- int x = xformed.x();
- int y = xformed.y();
- if (x >= SHRT_MIN && y >= SHRT_MIN && x < SHRT_MAX && y < SHRT_MAX) {
- xPoints[j].x = x;
- xPoints[j].y = y;
- ++j;
- }
- ++i;
- }
- if (j)
- XDrawPoints(d->dpy, d->hd, d->gc, xPoints, j, CoordModeOrigin);
-
- j = 0;
- }
-}
-
-void QX11PaintEngine::drawPoints(const QPointF *points, int pointCount)
-{
- Q_ASSERT(points);
- Q_ASSERT(pointCount);
- Q_D(QX11PaintEngine);
-
- if (!d->has_pen)
- return;
-
- // use the same test here as in drawPath to ensure that we don't use the path fallback
- // and end up in XDrawLines for pens with width <= 1
- if (d->cpen.widthF() > 1.0f
- || (X11->use_xrender && (d->has_alpha_pen || (d->render_hints & QPainter::Antialiasing)))
- || (!d->cpen.isCosmetic() && d->txop > QTransform::TxTranslate))
- {
- Qt::PenCapStyle capStyle = d->cpen.capStyle();
- if (capStyle == Qt::FlatCap) {
- setCapStyle(CapProjecting, d->gc);
- d->cpen.setCapStyle(Qt::SquareCap);
- }
-
- const QPointF *end = points + pointCount;
- while (points < end) {
- QPainterPath path;
- path.moveTo(*points);
- path.lineTo(points->x() + 0.005, points->y());
- drawPath(path);
- ++points;
- }
- if (capStyle == Qt::FlatCap) {
- setCapStyle(CapButt, d->gc);
- d->cpen.setCapStyle(capStyle);
- }
- return;
- }
-
- static const int BUF_SIZE = 1024;
- XPoint xPoints[BUF_SIZE];
- int i = 0, j = 0;
- while (i < pointCount) {
- while (i < pointCount && j < BUF_SIZE) {
- const QPointF &xformed = d->matrix.map(points[i]);
- int x = qFloor(xformed.x());
- int y = qFloor(xformed.y());
-
- if (x >= SHRT_MIN && y >= SHRT_MIN && x < SHRT_MAX && y < SHRT_MAX) {
- xPoints[j].x = x;
- xPoints[j].y = y;
- ++j;
- }
- ++i;
- }
- if (j)
- XDrawPoints(d->dpy, d->hd, d->gc, xPoints, j, CoordModeOrigin);
-
- j = 0;
- }
-}
-
-QPainter::RenderHints QX11PaintEngine::supportedRenderHints() const
-{
-#if !defined(QT_NO_XRENDER)
- if (X11->use_xrender)
- return QPainter::Antialiasing;
-#endif
- return QFlag(0);
-}
-
-void QX11PaintEngine::updateState(const QPaintEngineState &state)
-{
- Q_D(QX11PaintEngine);
- QPaintEngine::DirtyFlags flags = state.state();
-
-
- if (flags & DirtyOpacity) {
- d->opacity = state.opacity();
- // Force update pen/brush as to get proper alpha colors propagated
- flags |= DirtyPen;
- flags |= DirtyBrush;
- }
-
- if (flags & DirtyTransform) updateMatrix(state.transform());
- if (flags & DirtyPen) updatePen(state.pen());
- if (flags & (DirtyBrush | DirtyBrushOrigin)) updateBrush(state.brush(), state.brushOrigin());
- if (flags & DirtyFont) updateFont(state.font());
-
- if (state.state() & DirtyClipEnabled) {
- if (state.isClipEnabled()) {
- QPolygonF clip_poly_dev(d->matrix.map(painter()->clipPath().toFillPolygon()));
- QPolygonF clipped_poly_dev;
- d->clipPolygon_dev(clip_poly_dev, &clipped_poly_dev);
- updateClipRegion_dev(QRegion(clipped_poly_dev.toPolygon()), Qt::ReplaceClip);
- } else {
- updateClipRegion_dev(QRegion(), Qt::NoClip);
- }
- }
-
- if (flags & DirtyClipPath) {
- QPolygonF clip_poly_dev(d->matrix.map(state.clipPath().toFillPolygon()));
- QPolygonF clipped_poly_dev;
- d->clipPolygon_dev(clip_poly_dev, &clipped_poly_dev);
- updateClipRegion_dev(QRegion(clipped_poly_dev.toPolygon(), state.clipPath().fillRule()),
- state.clipOperation());
- } else if (flags & DirtyClipRegion) {
- extern QPainterPath qt_regionToPath(const QRegion &region);
- QPainterPath clip_path = qt_regionToPath(state.clipRegion());
- QPolygonF clip_poly_dev(d->matrix.map(clip_path.toFillPolygon()));
- QPolygonF clipped_poly_dev;
- d->clipPolygon_dev(clip_poly_dev, &clipped_poly_dev);
- updateClipRegion_dev(QRegion(clipped_poly_dev.toPolygon()), state.clipOperation());
- }
- if (flags & DirtyHints) updateRenderHints(state.renderHints());
- if (flags & DirtyCompositionMode) {
- int function = GXcopy;
- if (state.compositionMode() >= QPainter::RasterOp_SourceOrDestination) {
- switch (state.compositionMode()) {
- case QPainter::RasterOp_SourceOrDestination:
- function = GXor;
- break;
- case QPainter::RasterOp_SourceAndDestination:
- function = GXand;
- break;
- case QPainter::RasterOp_SourceXorDestination:
- function = GXxor;
- break;
- case QPainter::RasterOp_NotSourceAndNotDestination:
- function = GXnor;
- break;
- case QPainter::RasterOp_NotSourceOrNotDestination:
- function = GXnand;
- break;
- case QPainter::RasterOp_NotSourceXorDestination:
- function = GXequiv;
- break;
- case QPainter::RasterOp_NotSource:
- function = GXcopyInverted;
- break;
- case QPainter::RasterOp_SourceAndNotDestination:
- function = GXandReverse;
- break;
- case QPainter::RasterOp_NotSourceAndDestination:
- function = GXandInverted;
- break;
- default:
- function = GXcopy;
- }
- }
-#if !defined(QT_NO_XRENDER)
- else {
- d->composition_mode =
- qpainterOpToXrender(state.compositionMode());
- }
-#endif
- XSetFunction(X11->display, d->gc, function);
- XSetFunction(X11->display, d->gc_brush, function);
- }
- d->decidePathFallback();
- d->decideCoordAdjust();
-}
-
-void QX11PaintEngine::updateRenderHints(QPainter::RenderHints hints)
-{
- Q_D(QX11PaintEngine);
- d->render_hints = hints;
-
-#if !defined(QT_NO_XRENDER)
- if (X11->use_xrender && d->picture) {
- XRenderPictureAttributes attrs;
- attrs.poly_edge = (hints & QPainter::Antialiasing) ? PolyEdgeSmooth : PolyEdgeSharp;
- XRenderChangePicture(d->dpy, d->picture, CPPolyEdge, &attrs);
- }
-#endif
-}
-
-void QX11PaintEngine::updatePen(const QPen &pen)
-{
- Q_D(QX11PaintEngine);
- d->cpen = pen;
- int cp = CapButt;
- int jn = JoinMiter;
- int ps = pen.style();
-
- if (d->opacity < 1.0) {
- QColor c = d->cpen.color();
- c.setAlpha(qRound(c.alpha()*d->opacity));
- d->cpen.setColor(c);
- }
-
- d->has_pen = (ps != Qt::NoPen);
- d->has_alpha_pen = (pen.color().alpha() != 255);
-
- switch (pen.capStyle()) {
- case Qt::SquareCap:
- cp = CapProjecting;
- break;
- case Qt::RoundCap:
- cp = CapRound;
- break;
- case Qt::FlatCap:
- default:
- cp = CapButt;
- break;
- }
- switch (pen.joinStyle()) {
- case Qt::BevelJoin:
- jn = JoinBevel;
- break;
- case Qt::RoundJoin:
- jn = JoinRound;
- break;
- case Qt::MiterJoin:
- default:
- jn = JoinMiter;
- break;
- }
-
- d->adapted_pen_origin = false;
-
- char dashes[10]; // custom pen dashes
- int dash_len = 0; // length of dash list
- int xStyle = LineSolid;
-
- /*
- We are emulating Windows here. Windows treats cpen.width() == 1
- (or 0) as a very special case. The fudge variable unifies this
- case with the general case.
- */
- qreal pen_width = pen.widthF();
- int scale = qRound(pen_width < 1 ? 1 : pen_width);
- int space = (pen_width < 1 && pen_width > 0 ? 1 : (2 * scale));
- int dot = 1 * scale;
- int dash = 4 * scale;
-
- d->has_custom_pen = false;
-
- switch (ps) {
- case Qt::NoPen:
- case Qt::SolidLine:
- xStyle = LineSolid;
- break;
- case Qt::DashLine:
- dashes[0] = dash;
- dashes[1] = space;
- dash_len = 2;
- xStyle = LineOnOffDash;
- break;
- case Qt::DotLine:
- dashes[0] = dot;
- dashes[1] = space;
- dash_len = 2;
- xStyle = LineOnOffDash;
- break;
- case Qt::DashDotLine:
- dashes[0] = dash;
- dashes[1] = space;
- dashes[2] = dot;
- dashes[3] = space;
- dash_len = 4;
- xStyle = LineOnOffDash;
- break;
- case Qt::DashDotDotLine:
- dashes[0] = dash;
- dashes[1] = space;
- dashes[2] = dot;
- dashes[3] = space;
- dashes[4] = dot;
- dashes[5] = space;
- dash_len = 6;
- xStyle = LineOnOffDash;
- break;
- case Qt::CustomDashLine:
- d->has_custom_pen = true;
- break;
- }
-
- ulong mask = GCForeground | GCBackground | GCGraphicsExposures | GCLineWidth
- | GCCapStyle | GCJoinStyle | GCLineStyle;
- XGCValues vals;
- vals.graphics_exposures = false;
- if (d->pdev_depth == 1) {
- vals.foreground = qGray(pen.color().rgb()) > 127 ? 0 : 1;
- vals.background = qGray(QColor(Qt::transparent).rgb()) > 127 ? 0 : 1;
- } else if (d->pdev->devType() == QInternal::Pixmap && d->pdev_depth == 32
- && X11->use_xrender) {
- vals.foreground = pen.color().rgba();
- vals.background = QColor(Qt::transparent).rgba();
- } else {
- QColormap cmap = QColormap::instance(d->scrn);
- vals.foreground = cmap.pixel(pen.color());
- vals.background = cmap.pixel(QColor(Qt::transparent));
- }
-
-
- vals.line_width = qRound(pen.widthF());
- vals.cap_style = cp;
- vals.join_style = jn;
- vals.line_style = xStyle;
-
- XChangeGC(d->dpy, d->gc, mask, &vals);
-
- if (dash_len) { // make dash list
- XSetDashes(d->dpy, d->gc, 0, dashes, dash_len);
- }
-
- if (!d->has_clipping) { // if clipping is set the paintevent clip region is merged with the clip region
- QRegion sysClip = systemClip();
- if (!sysClip.isEmpty())
- x11SetClipRegion(d->dpy, d->gc, 0, d->picture, sysClip);
- else
- x11ClearClipRegion(d->dpy, d->gc, 0, d->picture);
- }
-}
-
-void QX11PaintEngine::updateBrush(const QBrush &brush, const QPointF &origin)
-{
- Q_D(QX11PaintEngine);
- d->cbrush = brush;
- d->bg_origin = origin;
- d->adapted_brush_origin = false;
-#if !defined(QT_NO_XRENDER)
- d->current_brush = 0;
-#endif
- if (d->opacity < 1.0) {
- QColor c = d->cbrush.color();
- c.setAlpha(qRound(c.alpha()*d->opacity));
- d->cbrush.setColor(c);
- }
-
- int s = FillSolid;
- int bs = d->cbrush.style();
- d->has_brush = (bs != Qt::NoBrush);
- d->has_pattern = bs >= Qt::Dense1Pattern && bs <= Qt::DiagCrossPattern;
- d->has_texture = bs == Qt::TexturePattern;
- d->has_alpha_brush = brush.color().alpha() != 255;
- d->has_alpha_texture = d->has_texture && d->cbrush.texture().hasAlphaChannel();
-
- ulong mask = GCForeground | GCBackground | GCGraphicsExposures
- | GCLineStyle | GCCapStyle | GCJoinStyle | GCFillStyle;
- XGCValues vals;
- vals.graphics_exposures = false;
- if (d->pdev_depth == 1) {
- vals.foreground = qGray(d->cbrush.color().rgb()) > 127 ? 0 : 1;
- vals.background = qGray(QColor(Qt::transparent).rgb()) > 127 ? 0 : 1;
- } else if (X11->use_xrender && d->pdev->devType() == QInternal::Pixmap
- && d->pdev_depth == 32) {
- vals.foreground = d->cbrush.color().rgba();
- vals.background = QColor(Qt::transparent).rgba();
- } else {
- QColormap cmap = QColormap::instance(d->scrn);
- vals.foreground = cmap.pixel(d->cbrush.color());
- vals.background = cmap.pixel(QColor(Qt::transparent));
-
- if (!X11->use_xrender && d->has_brush && !d->has_pattern && !brush.isOpaque()) {
- QPixmap pattern = qt_patternForAlpha(brush.color().alpha(), d->scrn);
- mask |= GCStipple;
- vals.stipple = pattern.handle();
- s = FillStippled;
- d->adapted_brush_origin = true;
- }
- }
- vals.cap_style = CapButt;
- vals.join_style = JoinMiter;
- vals.line_style = LineSolid;
-
- if (d->has_pattern || d->has_texture) {
- if (bs == Qt::TexturePattern) {
- d->brush_pm = qt_toX11Pixmap(d->cbrush.texture());
-#if !defined(QT_NO_XRENDER)
- if (X11->use_xrender) {
- XRenderPictureAttributes attrs;
- attrs.repeat = true;
- XRenderChangePicture(d->dpy, d->brush_pm.x11PictureHandle(), CPRepeat, &attrs);
- QX11PixmapData *data = static_cast<QX11PixmapData*>(d->brush_pm.data.data());
- if (data->mask_picture)
- XRenderChangePicture(d->dpy, data->mask_picture, CPRepeat, &attrs);
- }
-#endif
- } else {
- d->brush_pm = qt_toX11Pixmap(qt_pixmapForBrush(bs, true));
- }
- d->brush_pm.x11SetScreen(d->scrn);
- if (d->brush_pm.depth() == 1) {
- mask |= GCStipple;
- vals.stipple = d->brush_pm.handle();
- s = FillStippled;
-#if !defined(QT_NO_XRENDER)
- if (X11->use_xrender) {
- d->bitmap_texture = QPixmap(d->brush_pm.size());
- d->bitmap_texture.fill(Qt::transparent);
- d->bitmap_texture = qt_toX11Pixmap(d->bitmap_texture);
- d->bitmap_texture.x11SetScreen(d->scrn);
-
- ::Picture src = X11->getSolidFill(d->scrn, d->cbrush.color());
- XRenderComposite(d->dpy, PictOpSrc, src, d->brush_pm.x11PictureHandle(),
- d->bitmap_texture.x11PictureHandle(),
- 0, 0, d->brush_pm.width(), d->brush_pm.height(),
- 0, 0, d->brush_pm.width(), d->brush_pm.height());
-
- XRenderPictureAttributes attrs;
- attrs.repeat = true;
- XRenderChangePicture(d->dpy, d->bitmap_texture.x11PictureHandle(), CPRepeat, &attrs);
-
- d->current_brush = d->bitmap_texture.x11PictureHandle();
- }
-#endif
- } else {
- mask |= GCTile;
-#ifndef QT_NO_XRENDER
- if (d->pdev_depth == 32 && d->brush_pm.depth() != 32) {
- d->brush_pm.detach();
- QX11PixmapData *brushData = static_cast<QX11PixmapData*>(d->brush_pm.data.data());
- brushData->convertToARGB32();
- }
-#endif
- vals.tile = (d->brush_pm.depth() == d->pdev_depth
- ? d->brush_pm.handle()
- : static_cast<QX11PixmapData*>(d->brush_pm.data.data())->x11ConvertToDefaultDepth());
- s = FillTiled;
-#if !defined(QT_NO_XRENDER)
- d->current_brush = d->cbrush.texture().x11PictureHandle();
-#endif
- }
-
- mask |= GCTileStipXOrigin | GCTileStipYOrigin;
- vals.ts_x_origin = qRound(origin.x());
- vals.ts_y_origin = qRound(origin.y());
- }
-#if !defined(QT_NO_XRENDER)
- else if (d->has_alpha_brush) {
- d->current_brush = X11->getSolidFill(d->scrn, d->cbrush.color());
- }
-#endif
-
- vals.fill_style = s;
- XChangeGC(d->dpy, d->gc_brush, mask, &vals);
- if (!d->has_clipping) {
- QRegion sysClip = systemClip();
- if (!sysClip.isEmpty())
- x11SetClipRegion(d->dpy, d->gc_brush, 0, d->picture, sysClip);
- else
- x11ClearClipRegion(d->dpy, d->gc_brush, 0, d->picture);
- }
-}
-
-void QX11PaintEngine::drawEllipse(const QRectF &rect)
-{
- QRect aligned = rect.toAlignedRect();
- if (aligned == rect)
- drawEllipse(aligned);
- else
- QPaintEngine::drawEllipse(rect);
-}
-
-void QX11PaintEngine::drawEllipse(const QRect &rect)
-{
- if (rect.isEmpty()) {
- drawRects(&rect, 1);
- return;
- }
-
- Q_D(QX11PaintEngine);
- QRect devclip(SHRT_MIN, SHRT_MIN, SHRT_MAX*2 - 1, SHRT_MAX*2 - 1);
- QRect r(rect);
- if (d->txop < QTransform::TxRotate) {
- r = d->matrix.mapRect(rect);
- } else if (d->txop == QTransform::TxRotate && rect.width() == rect.height()) {
- QPainterPath path;
- path.addEllipse(rect);
- r = d->matrix.map(path).boundingRect().toRect();
- }
-
- if (d->has_alpha_brush || d->has_alpha_pen || d->has_custom_pen || (d->render_hints & QPainter::Antialiasing)
- || d->has_alpha_texture || devclip.intersected(r) != r
- || (d->has_complex_xform
- && !(d->has_non_scaling_xform && rect.width() == rect.height())))
- {
- QPainterPath path;
- path.addEllipse(rect);
- drawPath(path);
- return;
- }
-
- int x = r.x();
- int y = r.y();
- int w = r.width();
- int h = r.height();
- if (w < 1 || h < 1)
- return;
- if (w == 1 && h == 1) {
- XDrawPoint(d->dpy, d->hd, d->has_pen ? d->gc : d->gc_brush, x, y);
- return;
- }
- d->setupAdaptedOrigin(rect.topLeft());
- 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);
- }
- if (d->has_pen) // draw outline
- XDrawArc(d->dpy, d->hd, d->gc, x, y, w, h, 0, 360*64);
- d->resetAdaptedOrigin();
-}
-
-
-
-void QX11PaintEnginePrivate::fillPolygon_translated(const QPointF *polygonPoints, int pointCount,
- QX11PaintEnginePrivate::GCMode gcMode,
- QPaintEngine::PolygonDrawMode mode)
-{
-
- QVarLengthArray<QPointF> translated_points(pointCount);
- QPointF offset(matrix.dx(), matrix.dy());
-
- qreal offs = adjust_coords ? aliasedCoordinateDelta : 0.0;
- if (!X11->use_xrender || !(render_hints & QPainter::Antialiasing))
- offset += QPointF(aliasedCoordinateDelta, aliasedCoordinateDelta);
-
- for (int i = 0; i < pointCount; ++i) {
- translated_points[i] = polygonPoints[i] + offset;
-
- translated_points[i].rx() = qRound(translated_points[i].x()) + offs;
- translated_points[i].ry() = qRound(translated_points[i].y()) + offs;
- }
-
- fillPolygon_dev(translated_points.data(), pointCount, gcMode, mode);
-}
-
-#ifndef QT_NO_XRENDER
-static void qt_XRenderCompositeTrapezoids(Display *dpy,
- int op,
- Picture src,
- Picture dst,
- _Xconst XRenderPictFormat *maskFormat,
- int xSrc,
- int ySrc,
- const XTrapezoid *traps, int size)
-{
- const int MAX_TRAPS = 50000;
- while (size) {
- int to_draw = size;
- if (to_draw > MAX_TRAPS)
- to_draw = MAX_TRAPS;
- XRenderCompositeTrapezoids(dpy, op, src, dst,
- maskFormat,
- xSrc, ySrc,
- traps, to_draw);
- size -= to_draw;
- traps += to_draw;
- }
-}
-#endif
-
-void QX11PaintEnginePrivate::fillPolygon_dev(const QPointF *polygonPoints, int pointCount,
- QX11PaintEnginePrivate::GCMode gcMode,
- QPaintEngine::PolygonDrawMode mode)
-{
- Q_Q(QX11PaintEngine);
-
- int clippedCount = 0;
- qt_float_point *clippedPoints = 0;
-
-#ifndef QT_NO_XRENDER
- //can change if we switch to pen if gcMode != BrushGC
- bool has_fill_texture = has_texture;
- bool has_fill_pattern = has_pattern;
- ::Picture src;
-#endif
- QBrush fill;
- GC fill_gc;
- if (gcMode == BrushGC) {
- fill = cbrush;
- fill_gc = gc_brush;
-#ifndef QT_NO_XRENDER
- if (current_brush)
- src = current_brush;
- else
- src = X11->getSolidFill(scrn, fill.color());
-#endif
- } else {
- fill = QBrush(cpen.brush());
- fill_gc = gc;
-#ifndef QT_NO_XRENDER
- //we use the pens brush
- has_fill_texture = (fill.style() == Qt::TexturePattern);
- has_fill_pattern = (fill.style() >= Qt::Dense1Pattern && fill.style() <= Qt::DiagCrossPattern);
- if (has_fill_texture)
- src = fill.texture().x11PictureHandle();
- else if (has_fill_pattern)
- src = getPatternFill(scrn, fill);
- else
- src = X11->getSolidFill(scrn, fill.color());
-#endif
- }
-
- polygonClipper.clipPolygon((qt_float_point *) polygonPoints, pointCount,
- &clippedPoints, &clippedCount);
-
-#ifndef QT_NO_XRENDER
- bool solid_fill = fill.color().alpha() == 255;
- if (has_fill_texture && fill.texture().depth() == 1 && solid_fill) {
- has_fill_texture = false;
- has_fill_pattern = true;
- }
-
- bool antialias = render_hints & QPainter::Antialiasing;
-
- if (X11->use_xrender
- && picture
- && !has_fill_pattern
- && (clippedCount > 0)
- && (fill.style() != Qt::NoBrush)
- && ((has_fill_texture && fill.texture().hasAlpha()) || antialias || !solid_fill || has_alpha_pen != has_alpha_brush))
- {
- if (tessellator->size > 0) {
- XRenderPictureAttributes attrs;
- attrs.poly_edge = antialias ? PolyEdgeSmooth : PolyEdgeSharp;
- XRenderChangePicture(dpy, picture, CPPolyEdge, &attrs);
- int x_offset = int(XFixedToDouble(tessellator->traps[0].left.p1.x) - bg_origin.x());
- int y_offset = int(XFixedToDouble(tessellator->traps[0].left.p1.y) - bg_origin.y());
- qt_XRenderCompositeTrapezoids(dpy, composition_mode, src, picture,
- antialias
- ? XRenderFindStandardFormat(dpy, PictStandardA8)
- : XRenderFindStandardFormat(dpy, PictStandardA1),
- x_offset, y_offset,
- tessellator->traps, tessellator->size);
- tessellator->done();
- }
- } else
-#endif
- if (fill.style() != Qt::NoBrush) {
- if (clippedCount > 200000) {
- QPolygon poly;
- for (int i = 0; i < clippedCount; ++i)
- poly << QPoint(qFloor(clippedPoints[i].x), qFloor(clippedPoints[i].y));
-
- const QRect bounds = poly.boundingRect();
- const QRect aligned = bounds
- & QRect(QPoint(), QSize(pdev->width(), pdev->height()));
-
- QImage img(aligned.size(), QImage::Format_ARGB32_Premultiplied);
- img.fill(0);
-
- QPainter painter(&img);
- painter.translate(-aligned.x(), -aligned.y());
- painter.setPen(Qt::NoPen);
- painter.setBrush(fill);
- if (gcMode == BrushGC)
- painter.setBrushOrigin(q->painter()->brushOrigin());
- painter.drawPolygon(poly);
- painter.end();
-
- q->drawImage(aligned, img, img.rect(), Qt::AutoColor);
- } else if (clippedCount > 0) {
- QVarLengthArray<XPoint> xpoints(clippedCount);
- for (int i = 0; i < clippedCount; ++i) {
- xpoints[i].x = qFloor(clippedPoints[i].x);
- xpoints[i].y = qFloor(clippedPoints[i].y);
- }
- if (mode == QPaintEngine::WindingMode)
- XSetFillRule(dpy, fill_gc, WindingRule);
- setupAdaptedOrigin(QPoint(xpoints[0].x, xpoints[0].y));
- XFillPolygon(dpy, hd, fill_gc,
- xpoints.data(), clippedCount,
- mode == QPaintEngine::ConvexMode ? Convex : Complex, CoordModeOrigin);
- resetAdaptedOrigin();
- if (mode == QPaintEngine::WindingMode)
- XSetFillRule(dpy, fill_gc, EvenOddRule);
- }
- }
-}
-
-void QX11PaintEnginePrivate::strokePolygon_translated(const QPointF *polygonPoints, int pointCount, bool close)
-{
- QVarLengthArray<QPointF> translated_points(pointCount);
- QPointF offset(matrix.dx(), matrix.dy());
- for (int i = 0; i < pointCount; ++i)
- translated_points[i] = polygonPoints[i] + offset;
- strokePolygon_dev(translated_points.data(), pointCount, close);
-}
-
-void QX11PaintEnginePrivate::strokePolygon_dev(const QPointF *polygonPoints, int pointCount, bool close)
-{
- int clippedCount = 0;
- qt_float_point *clippedPoints = 0;
- polygonClipper.clipPolygon((qt_float_point *) polygonPoints, pointCount,
- &clippedPoints, &clippedCount, close);
-
- if (clippedCount > 0) {
- QVarLengthArray<XPoint> xpoints(clippedCount);
- for (int i = 0; i < clippedCount; ++i) {
- xpoints[i].x = qRound(clippedPoints[i].x + aliasedCoordinateDelta);
- xpoints[i].y = qRound(clippedPoints[i].y + aliasedCoordinateDelta);
- }
- uint numberPoints = qMin(clippedCount, xlibMaxLinePoints);
- XPoint *pts = xpoints.data();
- XDrawLines(dpy, hd, gc, pts, numberPoints, CoordModeOrigin);
- pts += numberPoints;
- clippedCount -= numberPoints;
- numberPoints = qMin(clippedCount, xlibMaxLinePoints-1);
- while (clippedCount) {
- XDrawLines(dpy, hd, gc, pts-1, numberPoints+1, CoordModeOrigin);
- pts += numberPoints;
- clippedCount -= numberPoints;
- numberPoints = qMin(clippedCount, xlibMaxLinePoints-1);
- }
- }
-}
-
-void QX11PaintEngine::drawPolygon(const QPointF *polygonPoints, int pointCount, PolygonDrawMode mode)
-{
- Q_D(QX11PaintEngine);
- if (d->use_path_fallback) {
- QPainterPath path(polygonPoints[0]);
- for (int i = 1; i < pointCount; ++i)
- path.lineTo(polygonPoints[i]);
- if (mode == PolylineMode) {
- QBrush oldBrush = d->cbrush;
- d->cbrush = QBrush(Qt::NoBrush);
- path.setFillRule(Qt::WindingFill);
- drawPath(path);
- d->cbrush = oldBrush;
- } else {
- path.setFillRule(mode == OddEvenMode ? Qt::OddEvenFill : Qt::WindingFill);
- path.closeSubpath();
- drawPath(path);
- }
- return;
- }
- if (mode != PolylineMode && d->has_brush)
- d->fillPolygon_translated(polygonPoints, pointCount, QX11PaintEnginePrivate::BrushGC, mode);
-
- if (d->has_pen)
- d->strokePolygon_translated(polygonPoints, pointCount, mode != PolylineMode);
-}
-
-
-void QX11PaintEnginePrivate::fillPath(const QPainterPath &path, QX11PaintEnginePrivate::GCMode gc_mode, bool transform)
-{
- qreal offs = adjust_coords ? aliasedCoordinateDelta : 0.0;
-
- QPainterPath clippedPath;
- QPainterPath clipPath;
- clipPath.addRect(polygonClipper.boundingRect());
-
- if (transform)
- clippedPath = (path*matrix).intersected(clipPath);
- else
- clippedPath = path.intersected(clipPath);
-
- QList<QPolygonF> polys = clippedPath.toFillPolygons();
- for (int i = 0; i < polys.size(); ++i) {
- QVarLengthArray<QPointF> translated_points(polys.at(i).size());
-
- for (int j = 0; j < polys.at(i).size(); ++j) {
- translated_points[j] = polys.at(i).at(j);
- if (!X11->use_xrender || !(render_hints & QPainter::Antialiasing)) {
- translated_points[j].rx() = qRound(translated_points[j].rx() + aliasedCoordinateDelta) + offs;
- translated_points[j].ry() = qRound(translated_points[j].ry() + aliasedCoordinateDelta) + offs;
- }
- }
-
- fillPolygon_dev(translated_points.data(), polys.at(i).size(), gc_mode,
- path.fillRule() == Qt::OddEvenFill ? QPaintEngine::OddEvenMode : QPaintEngine::WindingMode);
- }
-}
-
-void QX11PaintEngine::drawPath(const QPainterPath &path)
-{
- Q_D(QX11PaintEngine);
- if (path.isEmpty())
- return;
-
- if (d->has_brush)
- d->fillPath(path, QX11PaintEnginePrivate::BrushGC, true);
- if (d->has_pen
- && ((X11->use_xrender && (d->has_alpha_pen || (d->render_hints & QPainter::Antialiasing)))
- || (!d->cpen.isCosmetic() && d->txop > QTransform::TxTranslate
- && !d->has_non_scaling_xform)
- || (d->cpen.style() == Qt::CustomDashLine))) {
- QPainterPathStroker stroker;
- if (d->cpen.style() == Qt::CustomDashLine) {
- stroker.setDashPattern(d->cpen.dashPattern());
- stroker.setDashOffset(d->cpen.dashOffset());
- } else {
- stroker.setDashPattern(d->cpen.style());
- }
- stroker.setCapStyle(d->cpen.capStyle());
- stroker.setJoinStyle(d->cpen.joinStyle());
- 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) {
- 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;
- stroke.setFillRule(Qt::WindingFill);
- 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;
- stroke.setFillRule(Qt::WindingFill);
- d->fillPath(stroke, QX11PaintEnginePrivate::PenGC, true);
- }
- } else if (d->has_pen) {
- // if we have a cosmetic pen - use XDrawLine() for speed
- QList<QPolygonF> polys = path.toSubpathPolygons(d->matrix);
- for (int i = 0; i < polys.size(); ++i)
- d->strokePolygon_dev(polys.at(i).data(), polys.at(i).size(), false);
- }
-}
-
-Q_GUI_EXPORT void qt_x11_drawImage(const QRect &rect, const QPoint &pos, const QImage &image,
- Drawable hd, GC gc, Display *dpy, Visual *visual, int depth)
-{
- Q_ASSERT(image.format() == QImage::Format_RGB32);
- Q_ASSERT(image.depth() == 32);
-
- XImage *xi;
- // Note: this code assumes either RGB or BGR, 8 bpc server layouts
- const uint red_mask = (uint) visual->red_mask;
- bool bgr_layout = (red_mask == 0xff);
-
- const int w = rect.width();
- const int h = rect.height();
-
- QImage im;
- int image_byte_order = ImageByteOrder(X11->display);
- if ((QSysInfo::ByteOrder == QSysInfo::BigEndian && ((image_byte_order == LSBFirst) || bgr_layout))
- || (image_byte_order == MSBFirst && QSysInfo::ByteOrder == QSysInfo::LittleEndian)
- || (image_byte_order == LSBFirst && bgr_layout))
- {
- im = image.copy(rect);
- const int iw = im.bytesPerLine() / 4;
- uint *data = (uint *)im.bits();
- for (int i=0; i < h; i++) {
- uint *p = data;
- uint *end = p + w;
- if (bgr_layout && image_byte_order == MSBFirst && QSysInfo::ByteOrder == QSysInfo::LittleEndian) {
- while (p < end) {
- *p = ((*p << 8) & 0xffffff00) | ((*p >> 24) & 0x000000ff);
- p++;
- }
- } else if ((image_byte_order == LSBFirst && QSysInfo::ByteOrder == QSysInfo::BigEndian)
- || (image_byte_order == MSBFirst && QSysInfo::ByteOrder == QSysInfo::LittleEndian)) {
- while (p < end) {
- *p = ((*p << 24) & 0xff000000) | ((*p << 8) & 0x00ff0000)
- | ((*p >> 8) & 0x0000ff00) | ((*p >> 24) & 0x000000ff);
- p++;
- }
- } else if ((image_byte_order == MSBFirst && QSysInfo::ByteOrder == QSysInfo::BigEndian)
- || (image_byte_order == LSBFirst && bgr_layout))
- {
- while (p < end) {
- *p = ((*p << 16) & 0x00ff0000) | ((*p >> 16) & 0x000000ff)
- | ((*p ) & 0xff00ff00);
- p++;
- }
- }
- data += iw;
- }
- xi = XCreateImage(dpy, visual, depth, ZPixmap,
- 0, (char *) im.bits(), w, h, 32, im.bytesPerLine());
- } else {
- xi = XCreateImage(dpy, visual, depth, ZPixmap,
- 0, (char *) image.scanLine(rect.y())+rect.x()*sizeof(uint), w, h, 32, image.bytesPerLine());
- }
- XPutImage(dpy, hd, gc, xi, 0, 0, pos.x(), pos.y(), w, h);
- xi->data = 0; // QImage owns these bits
- XDestroyImage(xi);
-}
-
-void QX11PaintEngine::drawImage(const QRectF &r, const QImage &image, const QRectF &sr, Qt::ImageConversionFlags flags)
-{
- Q_D(QX11PaintEngine);
-
- if (image.format() == QImage::Format_RGB32
- && d->pdev_depth >= 24 && image.depth() == 32
- && r.size() == sr.size())
- {
- int sx = qRound(sr.x());
- int sy = qRound(sr.y());
- int x = qRound(r.x());
- int y = qRound(r.y());
- int w = qRound(r.width());
- int h = qRound(r.height());
-
- qt_x11_drawImage(QRect(sx, sy, w, h), QPoint(x, y), image, d->hd, d->gc, d->dpy,
- (Visual *)d->xinfo->visual(), d->pdev_depth);
- } else {
- QPaintEngine::drawImage(r, image, sr, flags);
- }
-}
-
-void QX11PaintEngine::drawPixmap(const QRectF &r, const QPixmap &px, const QRectF &_sr)
-{
- Q_D(QX11PaintEngine);
- QRectF sr = _sr;
- int x = qRound(r.x());
- int y = qRound(r.y());
- int sx = qRound(sr.x());
- int sy = qRound(sr.y());
- int sw = qRound(sr.width());
- int sh = qRound(sr.height());
-
- QPixmap pixmap = qt_toX11Pixmap(px);
- if(pixmap.isNull())
- return;
-
- if ((d->xinfo && d->xinfo->screen() != pixmap.x11Info().screen())
- || (pixmap.x11Info().screen() != DefaultScreen(X11->display))) {
- QPixmap* p = const_cast<QPixmap *>(&pixmap);
- p->x11SetScreen(d->xinfo ? d->xinfo->screen() : DefaultScreen(X11->display));
- }
-
- QPixmap::x11SetDefaultScreen(pixmap.x11Info().screen());
-
-#ifndef QT_NO_XRENDER
- ::Picture src_pict = static_cast<QX11PixmapData*>(pixmap.data.data())->picture;
- if (src_pict && d->picture) {
- const int pDepth = pixmap.depth();
- if (pDepth == 1 && (d->has_alpha_pen)) {
- qt_render_bitmap(d->dpy, d->scrn, src_pict, d->picture,
- sx, sy, x, y, sw, sh, d->cpen);
- return;
- } else if (pDepth != 1 && (pDepth == 32 || pDepth != d->pdev_depth)) {
- XRenderComposite(d->dpy, d->composition_mode,
- src_pict, 0, d->picture, sx, sy, 0, 0, x, y, sw, sh);
- return;
- }
- }
-#endif
-
- bool mono_src = pixmap.depth() == 1;
- bool mono_dst = d->pdev_depth == 1;
- bool restore_clip = false;
-
- if (static_cast<QX11PixmapData*>(pixmap.data.data())->x11_mask) { // pixmap has a mask
- QBitmap comb(sw, sh);
- GC cgc = XCreateGC(d->dpy, comb.handle(), 0, 0);
- XSetForeground(d->dpy, cgc, 0);
- XFillRectangle(d->dpy, comb.handle(), cgc, 0, 0, sw, sh);
- XSetBackground(d->dpy, cgc, 0);
- XSetForeground(d->dpy, cgc, 1);
- if (!d->crgn.isEmpty()) {
- int num;
- XRectangle *rects = (XRectangle *)qt_getClipRects(d->crgn, num);
- XSetClipRectangles(d->dpy, cgc, -x, -y, rects, num, Unsorted);
- } else if (d->has_clipping) {
- XSetClipRectangles(d->dpy, cgc, 0, 0, 0, 0, Unsorted);
- }
- XSetFillStyle(d->dpy, cgc, FillOpaqueStippled);
- XSetTSOrigin(d->dpy, cgc, -sx, -sy);
- XSetStipple(d->dpy, cgc,
- static_cast<QX11PixmapData*>(pixmap.data.data())->x11_mask);
- XFillRectangle(d->dpy, comb.handle(), cgc, 0, 0, sw, sh);
- XFreeGC(d->dpy, cgc);
-
- XSetClipOrigin(d->dpy, d->gc, x, y);
- XSetClipMask(d->dpy, d->gc, comb.handle());
- restore_clip = true;
- }
-
- if (mono_src) {
- if (!d->crgn.isEmpty()) {
- Pixmap comb = XCreatePixmap(d->dpy, d->hd, sw, sh, 1);
- GC cgc = XCreateGC(d->dpy, comb, 0, 0);
- XSetForeground(d->dpy, cgc, 0);
- XFillRectangle(d->dpy, comb, cgc, 0, 0, sw, sh);
- int num;
- XRectangle *rects = (XRectangle *)qt_getClipRects(d->crgn, num);
- XSetClipRectangles(d->dpy, cgc, -x, -y, rects, num, Unsorted);
- XCopyArea(d->dpy, pixmap.handle(), comb, cgc, sx, sy, sw, sh, 0, 0);
- XFreeGC(d->dpy, cgc);
-
- XSetClipMask(d->dpy, d->gc, comb);
- XSetClipOrigin(d->dpy, d->gc, x, y);
- XFreePixmap(d->dpy, comb);
- } else {
- XSetClipMask(d->dpy, d->gc, pixmap.handle());
- XSetClipOrigin(d->dpy, d->gc, x - sx, y - sy);
- }
-
- if (mono_dst) {
- XSetForeground(d->dpy, d->gc, qGray(d->cpen.color().rgb()) > 127 ? 0 : 1);
- } else {
- QColormap cmap = QColormap::instance(d->scrn);
- XSetForeground(d->dpy, d->gc, cmap.pixel(d->cpen.color()));
- }
- XFillRectangle(d->dpy, d->hd, d->gc, x, y, sw, sh);
- restore_clip = true;
- } else if (mono_dst && !mono_src) {
- QBitmap bitmap(pixmap);
- XCopyArea(d->dpy, bitmap.handle(), d->hd, d->gc, sx, sy, sw, sh, x, y);
- } else {
- XCopyArea(d->dpy, pixmap.handle(), d->hd, d->gc, sx, sy, sw, sh, x, y);
- }
-
- if (d->pdev->devType() == QInternal::Pixmap) {
- const QPixmap *px = static_cast<const QPixmap*>(d->pdev);
- Pixmap src_mask = static_cast<QX11PixmapData*>(pixmap.data.data())->x11_mask;
- Pixmap dst_mask = static_cast<QX11PixmapData*>(px->data.data())->x11_mask;
- if (dst_mask) {
- GC cgc = XCreateGC(d->dpy, dst_mask, 0, 0);
- if (src_mask) { // copy src mask into dst mask
- XCopyArea(d->dpy, src_mask, dst_mask, cgc, sx, sy, sw, sh, x, y);
- } else { // no src mask, but make sure the area copied is opaque in dest
- XSetBackground(d->dpy, cgc, 0);
- XSetForeground(d->dpy, cgc, 1);
- XFillRectangle(d->dpy, dst_mask, cgc, x, y, sw, sh);
- }
- XFreeGC(d->dpy, cgc);
- }
- }
-
- if (restore_clip) {
- XSetClipOrigin(d->dpy, d->gc, 0, 0);
- int num;
- XRectangle *rects = (XRectangle *)qt_getClipRects(d->crgn, num);
- if (num == 0)
- XSetClipMask(d->dpy, d->gc, XNone);
- else
- XSetClipRectangles(d->dpy, d->gc, 0, 0, rects, num, Unsorted);
- }
-}
-
-void QX11PaintEngine::updateMatrix(const QTransform &mtx)
-{
- Q_D(QX11PaintEngine);
- d->txop = mtx.type();
- d->matrix = mtx;
-
- d->has_complex_xform = (d->txop > QTransform::TxTranslate);
-
- extern bool qt_scaleForTransform(const QTransform &transform, qreal *scale);
- bool scaling = qt_scaleForTransform(d->matrix, &d->xform_scale);
- d->has_scaling_xform = scaling && d->xform_scale != 1.0;
- d->has_non_scaling_xform = scaling && d->xform_scale == 1.0;
-}
-
-/*
- NB! the clip region is expected to be in dev coordinates
-*/
-void QX11PaintEngine::updateClipRegion_dev(const QRegion &clipRegion, Qt::ClipOperation op)
-{
- Q_D(QX11PaintEngine);
- QRegion sysClip = systemClip();
- if (op == Qt::NoClip) {
- d->has_clipping = false;
- d->crgn = sysClip;
- if (!sysClip.isEmpty()) {
- x11SetClipRegion(d->dpy, d->gc, d->gc_brush, d->picture, sysClip);
- } else {
- x11ClearClipRegion(d->dpy, d->gc, d->gc_brush, d->picture);
- }
- return;
- }
-
- switch (op) {
- case Qt::IntersectClip:
- if (d->has_clipping) {
- d->crgn &= clipRegion;
- break;
- }
- // fall through
- case Qt::ReplaceClip:
- if (!sysClip.isEmpty())
- d->crgn = clipRegion.intersected(sysClip);
- else
- d->crgn = clipRegion;
- break;
- default:
- break;
- }
- d->has_clipping = true;
- x11SetClipRegion(d->dpy, d->gc, d->gc_brush, d->picture, d->crgn);
-}
-
-void QX11PaintEngine::updateFont(const QFont &)
-{
-}
-
-Qt::HANDLE QX11PaintEngine::handle() const
-{
- Q_D(const QX11PaintEngine);
- Q_ASSERT(isActive());
- Q_ASSERT(d->hd);
- return d->hd;
-}
-
-extern void qt_draw_tile(QPaintEngine *, qreal, qreal, qreal, qreal, const QPixmap &,
- qreal, qreal);
-
-void QX11PaintEngine::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &p)
-{
- int x = qRound(r.x());
- int y = qRound(r.y());
- int w = qRound(r.width());
- int h = qRound(r.height());
- int sx = qRound(p.x());
- int sy = qRound(p.y());
-
- bool mono_src = pixmap.depth() == 1;
- Q_D(QX11PaintEngine);
-
- if ((d->xinfo && d->xinfo->screen() != pixmap.x11Info().screen())
- || (pixmap.x11Info().screen() != DefaultScreen(X11->display))) {
- QPixmap* p = const_cast<QPixmap *>(&pixmap);
- p->x11SetScreen(d->xinfo ? d->xinfo->screen() : DefaultScreen(X11->display));
- }
-
- QPixmap::x11SetDefaultScreen(pixmap.x11Info().screen());
-
-#ifndef QT_NO_XRENDER
- if (X11->use_xrender && d->picture && pixmap.x11PictureHandle()) {
-#if 0
- // ### Qt 5: enable this
- XRenderPictureAttributes attrs;
- attrs.repeat = true;
- XRenderChangePicture(d->dpy, pixmap.x11PictureHandle(), CPRepeat, &attrs);
-
- if (mono_src) {
- qt_render_bitmap(d->dpy, d->scrn, pixmap.x11PictureHandle(), d->picture,
- sx, sy, x, y, w, h, d->cpen);
- } else {
- XRenderComposite(d->dpy, d->composition_mode,
- pixmap.x11PictureHandle(), XNone, d->picture,
- sx, sy, 0, 0, x, y, w, h);
- }
-#else
- const int numTiles = (w / pixmap.width()) * (h / pixmap.height());
- if (numTiles < 100) {
- // this is essentially qt_draw_tile(), inlined for
- // the XRenderComposite call
- int yPos, xPos, drawH, drawW, yOff, xOff;
- yPos = y;
- yOff = sy;
- while(yPos < y + h) {
- drawH = pixmap.height() - yOff; // Cropping first row
- if (yPos + drawH > y + h) // Cropping last row
- drawH = y + h - yPos;
- xPos = x;
- xOff = sx;
- while(xPos < x + w) {
- drawW = pixmap.width() - xOff; // Cropping first column
- if (xPos + drawW > x + w) // Cropping last column
- drawW = x + w - xPos;
- if (mono_src) {
- qt_render_bitmap(d->dpy, d->scrn, pixmap.x11PictureHandle(), d->picture,
- xOff, yOff, xPos, yPos, drawW, drawH, d->cpen);
- } else {
- XRenderComposite(d->dpy, d->composition_mode,
- pixmap.x11PictureHandle(), XNone, d->picture,
- xOff, yOff, 0, 0, xPos, yPos, drawW, drawH);
- }
- xPos += drawW;
- xOff = 0;
- }
- yPos += drawH;
- yOff = 0;
- }
- } else {
- w = qMin(w, d->pdev->width() - x);
- h = qMin(h, d->pdev->height() - y);
- if (w <= 0 || h <= 0)
- return;
-
- const int pw = w + sx;
- const int ph = h + sy;
- QPixmap pm(pw, ph);
- if (pixmap.hasAlpha() || mono_src)
- pm.fill(Qt::transparent);
-
- const int mode = pixmap.hasAlpha() ? PictOpOver : PictOpSrc;
- const ::Picture pmPicture = pm.x11PictureHandle();
-
- // first tile
- XRenderComposite(d->dpy, mode,
- pixmap.x11PictureHandle(), XNone, pmPicture,
- 0, 0, 0, 0, 0, 0, qMin(pw, pixmap.width()), qMin(ph, pixmap.height()));
-
- // first row of tiles
- int xPos = pixmap.width();
- const int sh = qMin(ph, pixmap.height());
- while (xPos < pw) {
- const int sw = qMin(xPos, pw - xPos);
- XRenderComposite(d->dpy, mode,
- pmPicture, XNone, pmPicture,
- 0, 0, 0, 0, xPos, 0, sw, sh);
- xPos *= 2;
- }
-
- // remaining rows
- int yPos = pixmap.height();
- const int sw = pw;
- while (yPos < ph) {
- const int sh = qMin(yPos, ph - yPos);
- XRenderComposite(d->dpy, mode,
- pmPicture, XNone, pmPicture,
- 0, 0, 0, 0, 0, yPos, sw, sh);
- yPos *= 2;
- }
-
- // composite
- if (mono_src)
- qt_render_bitmap(d->dpy, d->scrn, pmPicture, d->picture,
- sx, sy, x, y, w, h, d->cpen);
- else
- XRenderComposite(d->dpy, d->composition_mode,
- pmPicture, XNone, d->picture,
- sx, sy, 0, 0, x, y, w, h);
- }
-#endif
- } else
-#endif // !QT_NO_XRENDER
- if (pixmap.depth() > 1 && !static_cast<QX11PixmapData*>(pixmap.data.data())->x11_mask) {
- XSetTile(d->dpy, d->gc, pixmap.handle());
- XSetFillStyle(d->dpy, d->gc, FillTiled);
- XSetTSOrigin(d->dpy, d->gc, x-sx, y-sy);
- XFillRectangle(d->dpy, d->hd, d->gc, x, y, w, h);
- XSetTSOrigin(d->dpy, d->gc, 0, 0);
- XSetFillStyle(d->dpy, d->gc, FillSolid);
- } else {
- qt_draw_tile(this, x, y, w, h, pixmap, sx, sy);
- }
-}
-
-void QX11PaintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem)
-{
- const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem);
-
- switch(ti.fontEngine->type()) {
- case QFontEngine::TestFontEngine:
- case QFontEngine::Box:
- d_func()->drawBoxTextItem(p, ti);
- break;
- case QFontEngine::XLFD:
- drawXLFD(p, ti);
- break;
-#ifndef QT_NO_FONTCONFIG
- case QFontEngine::Freetype:
- drawFreetype(p, ti);
- break;
-#endif
- default:
- Q_ASSERT(false);
- }
-}
-
-void QX11PaintEngine::drawXLFD(const QPointF &p, const QTextItemInt &ti)
-{
- Q_D(QX11PaintEngine);
-
- if (d->txop > QTransform::TxTranslate) {
- // XServer or font don't support server side transformations, need to do it by hand
- QPaintEngine::drawTextItem(p, ti);
- return;
- }
-
- if (!ti.glyphs.numGlyphs)
- return;
-
- QVarLengthArray<QFixedPoint> positions;
- QVarLengthArray<glyph_t> glyphs;
- QTransform matrix = d->matrix;
- matrix.translate(p.x(), p.y());
- ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions);
- if (glyphs.size() == 0)
- return;
-
- QFontEngineXLFD *xlfd = static_cast<QFontEngineXLFD *>(ti.fontEngine);
- Qt::HANDLE font_id = xlfd->fontStruct()->fid;
-
- XSetFont(d->dpy, d->gc, font_id);
-
- const QFixed offs = QFixed::fromReal(aliasedCoordinateDelta);
- for (int i = 0; i < glyphs.size(); i++) {
- int xp = qRound(positions[i].x + offs);
- int yp = qRound(positions[i].y + offs);
- if (xp < SHRT_MAX && xp > SHRT_MIN && yp > SHRT_MIN && yp < SHRT_MAX) {
- XChar2b ch;
- ch.byte1 = glyphs[i] >> 8;
- ch.byte2 = glyphs[i] & 0xff;
- XDrawString16(d->dpy, d->hd, d->gc, xp, yp, &ch, 1);
- }
- }
-}
-
-#ifndef QT_NO_FONTCONFIG
-static QPainterPath path_for_glyphs(const QVarLengthArray<glyph_t> &glyphs,
- const QVarLengthArray<QFixedPoint> &positions,
- const QFontEngineFT *ft)
-{
- QPainterPath path;
- path.setFillRule(Qt::WindingFill);
- ft->lockFace();
- int i = 0;
- while (i < glyphs.size()) {
- QFontEngineFT::Glyph *glyph = ft->loadGlyph(glyphs[i], QFontEngineFT::Format_Mono);
- // #### fix case where we don't get a glyph
- if (!glyph)
- break;
-
- Q_ASSERT(glyph->format == QFontEngineFT::Format_Mono);
- int n = 0;
- int h = glyph->height;
- int xp = qRound(positions[i].x);
- int yp = qRound(positions[i].y);
-
- xp += glyph->x;
- yp += -glyph->y + glyph->height;
- int pitch = ((glyph->width + 31) & ~31) >> 3;
-
- uchar *src = glyph->data;
- while (h--) {
- for (int x = 0; x < glyph->width; ++x) {
- bool set = src[x >> 3] & (0x80 >> (x & 7));
- if (set) {
- QRect r(xp + x, yp - h, 1, 1);
- while (x+1 < glyph->width && src[(x+1) >> 3] & (0x80 >> ((x+1) & 7))) {
- ++x;
- r.setRight(r.right()+1);
- }
-
- path.addRect(r);
- ++n;
- }
- }
- src += pitch;
- }
- ++i;
- }
- ft->unlockFace();
- return path;
-}
-
-void QX11PaintEngine::drawFreetype(const QPointF &p, const QTextItemInt &ti)
-{
- Q_D(QX11PaintEngine);
- if (!ti.glyphs.numGlyphs)
- return;
-
- QFontEngineX11FT *ft = static_cast<QFontEngineX11FT *>(ti.fontEngine);
-
- if (!d->cpen.isSolid()) {
- QPaintEngine::drawTextItem(p, ti);
- return;
- }
-
- const bool xrenderPath = (X11->use_xrender
- && !(d->pdev->devType() == QInternal::Pixmap
- && static_cast<const QPixmap *>(d->pdev)->data->pixelType() == QPixmapData::BitmapType));
-
- QVarLengthArray<QFixedPoint> positions;
- QVarLengthArray<glyph_t> glyphs;
- QTransform matrix;
-
- if (xrenderPath)
- matrix = d->matrix;
- matrix.translate(p.x(), p.y());
- ft->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions);
- if (glyphs.count() == 0)
- return;
-
-#ifndef QT_NO_XRENDER
- QFontEngineFT::QGlyphSet *set = ft->defaultGlyphs();
- if (d->txop >= QTransform::TxScale && xrenderPath)
- set = ft->loadTransformedGlyphSet(d->matrix);
-
- if (!set || set->outline_drawing
- || !ft->loadGlyphs(set, glyphs.constData(), glyphs.size(), positions.constData(), QFontEngineFT::Format_Render))
- {
- QPaintEngine::drawTextItem(p, ti);
- return;
- }
-
- if (xrenderPath) {
- GlyphSet glyphSet = set->id;
- const QColor &pen = d->cpen.color();
- ::Picture src = X11->getSolidFill(d->scrn, pen);
- XRenderPictFormat *maskFormat = 0;
- if (ft->xglyph_format != PictStandardA1)
- maskFormat = XRenderFindStandardFormat(X11->display, ft->xglyph_format);
-
- enum { t_min = SHRT_MIN, t_max = SHRT_MAX };
-
- int i = 0;
- for (; i < glyphs.size()
- && (positions[i].x < t_min || positions[i].x > t_max
- || positions[i].y < t_min || positions[i].y > t_max);
- ++i)
- ;
-
- if (i >= glyphs.size())
- return;
- ++i;
-
- QFixed xp = positions[i - 1].x;
- QFixed yp = positions[i - 1].y;
- QFixed offs = QFixed::fromReal(aliasedCoordinateDelta);
-
- XGlyphElt32 elt;
- elt.glyphset = glyphSet;
- elt.chars = &glyphs[i - 1];
- elt.nchars = 1;
- elt.xOff = qRound(xp + offs);
- elt.yOff = qRound(yp + offs);
- for (; i < glyphs.size(); ++i) {
- if (positions[i].x < t_min || positions[i].x > t_max
- || positions[i].y < t_min || positions[i].y > t_max) {
- break;
- }
- QFontEngineFT::Glyph *g = ft->cachedGlyph(glyphs[i - 1]);
- if (g
- && positions[i].x == xp + g->advance
- && positions[i].y == yp
- && elt.nchars < 253 // don't draw more than 253 characters as some X servers
- // hang with it
- ) {
- elt.nchars++;
- xp += g->advance;
- } else {
- xp = positions[i].x;
- yp = positions[i].y;
-
- XRenderCompositeText32(X11->display, PictOpOver, src, d->picture,
- maskFormat, 0, 0, 0, 0,
- &elt, 1);
- elt.chars = &glyphs[i];
- elt.nchars = 1;
- elt.xOff = qRound(xp + offs);
- elt.yOff = qRound(yp + offs);
- }
- }
- XRenderCompositeText32(X11->display, PictOpOver, src, d->picture,
- maskFormat, 0, 0, 0, 0,
- &elt, 1);
-
- return;
-
- }
-#endif
-
- QPainterPath path = path_for_glyphs(glyphs, positions, ft);
- if (path.elementCount() <= 1)
- return;
- Q_ASSERT((path.elementCount() % 5) == 0);
- if (d->txop >= QTransform::TxScale) {
- painter()->save();
- painter()->setBrush(d->cpen.brush());
- painter()->setPen(Qt::NoPen);
- painter()->drawPath(path);
- painter()->restore();
- return;
- }
-
- const int rectcount = 256;
- XRectangle rects[rectcount];
- int num_rects = 0;
-
- QPoint delta(qRound(d->matrix.dx()), qRound(d->matrix.dy()));
- QRect clip(d->polygonClipper.boundingRect());
- for (int i=0; i < path.elementCount(); i+=5) {
- int x = qRound(path.elementAt(i).x);
- int y = qRound(path.elementAt(i).y);
- int w = qRound(path.elementAt(i+1).x) - x;
- int h = qRound(path.elementAt(i+2).y) - y;
-
- QRect rect = QRect(x + delta.x(), y + delta.y(), w, h);
- rect = rect.intersected(clip);
- if (rect.isEmpty())
- continue;
-
- rects[num_rects].x = short(rect.x());
- rects[num_rects].y = short(rect.y());
- rects[num_rects].width = ushort(rect.width());
- rects[num_rects].height = ushort(rect.height());
- ++num_rects;
- if (num_rects == rectcount) {
- XFillRectangles(d->dpy, d->hd, d->gc, rects, num_rects);
- num_rects = 0;
- }
- }
- if (num_rects > 0)
- XFillRectangles(d->dpy, d->hd, d->gc, rects, num_rects);
-
-}
-#endif // !QT_NO_XRENDER
-
-QT_END_NAMESPACE
diff --git a/src/gui/painting/qpaintengine_x11_p.h b/src/gui/painting/qpaintengine_x11_p.h
deleted file mode 100644
index d8d8817993..0000000000
--- a/src/gui/painting/qpaintengine_x11_p.h
+++ /dev/null
@@ -1,246 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPAINTENGINE_X11_P_H
-#define QPAINTENGINE_X11_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "QtGui/qpaintengine.h"
-#include "QtGui/qregion.h"
-#include "QtGui/qpen.h"
-#include "QtCore/qpoint.h"
-#include "private/qpaintengine_p.h"
-#include "private/qpainter_p.h"
-#include "private/qpolygonclipper_p.h"
-
-typedef unsigned long Picture;
-
-QT_BEGIN_NAMESPACE
-
-class QX11PaintEnginePrivate;
-class QFontEngineFT;
-class QXRenderTessellator;
-
-struct qt_float_point
-{
- qreal x, y;
-};
-
-class QX11PaintEngine : public QPaintEngine
-{
- Q_DECLARE_PRIVATE(QX11PaintEngine)
-public:
- QX11PaintEngine();
- ~QX11PaintEngine();
-
- bool begin(QPaintDevice *pdev);
- bool end();
-
- void updateState(const QPaintEngineState &state);
-
- void updatePen(const QPen &pen);
- void updateBrush(const QBrush &brush, const QPointF &pt);
- void updateRenderHints(QPainter::RenderHints hints);
- void updateFont(const QFont &font);
- void updateMatrix(const QTransform &matrix);
- void updateClipRegion_dev(const QRegion &region, Qt::ClipOperation op);
-
- void drawLines(const QLine *lines, int lineCount);
- void drawLines(const QLineF *lines, int lineCount);
-
- void drawRects(const QRect *rects, int rectCount);
- void drawRects(const QRectF *rects, int rectCount);
-
- void drawPoints(const QPoint *points, int pointCount);
- void drawPoints(const QPointF *points, int pointCount);
-
- void drawEllipse(const QRect &r);
- void drawEllipse(const QRectF &r);
-
- virtual void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode);
- inline void drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode)
- { QPaintEngine::drawPolygon(points, pointCount, mode); }
-
- void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr);
- void drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s);
- void drawPath(const QPainterPath &path);
- void drawTextItem(const QPointF &p, const QTextItem &textItem);
- void drawImage(const QRectF &r, const QImage &img, const QRectF &sr,
- Qt::ImageConversionFlags flags = Qt::AutoColor);
-
- virtual Qt::HANDLE handle() const;
- inline Type type() const { return QPaintEngine::X11; }
-
- QPainter::RenderHints supportedRenderHints() const;
-
-protected:
- QX11PaintEngine(QX11PaintEnginePrivate &dptr);
-
- void drawXLFD(const QPointF &p, const QTextItemInt &si);
-#ifndef QT_NO_FONTCONFIG
- void drawFreetype(const QPointF &p, const QTextItemInt &si);
-#endif
-
- friend class QPixmap;
- friend class QFontEngineBox;
- friend Q_GUI_EXPORT GC qt_x11_get_pen_gc(QPainter *);
- friend Q_GUI_EXPORT GC qt_x11_get_brush_gc(QPainter *);
-
-private:
- Q_DISABLE_COPY(QX11PaintEngine)
-};
-
-class QX11PaintEnginePrivate : public QPaintEnginePrivate
-{
- Q_DECLARE_PUBLIC(QX11PaintEngine)
-public:
- QX11PaintEnginePrivate()
- {
- scrn = -1;
- hd = 0;
- picture = 0;
- gc = gc_brush = 0;
- dpy = 0;
- xinfo = 0;
- txop = QTransform::TxNone;
- has_clipping = false;
- render_hints = 0;
- xform_scale = 1;
-#ifndef QT_NO_XRENDER
- tessellator = 0;
-#endif
- }
- enum GCMode {
- PenGC,
- BrushGC
- };
-
- void init();
- void fillPolygon_translated(const QPointF *points, int pointCount, GCMode gcMode,
- QPaintEngine::PolygonDrawMode mode);
- void fillPolygon_dev(const QPointF *points, int pointCount, GCMode gcMode,
- QPaintEngine::PolygonDrawMode mode);
- void fillPath(const QPainterPath &path, GCMode gcmode, bool transform);
- void strokePolygon_dev(const QPointF *points, int pointCount, bool close);
- void strokePolygon_translated(const QPointF *points, int pointCount, bool close);
- void setupAdaptedOrigin(const QPoint &p);
- void resetAdaptedOrigin();
- void decidePathFallback() {
- use_path_fallback = has_alpha_brush
- || has_alpha_pen
- || has_custom_pen
- || has_complex_xform
- || (render_hints & QPainter::Antialiasing);
- }
- void decideCoordAdjust() {
- adjust_coords = !(render_hints & QPainter::Antialiasing)
- && (has_alpha_pen
- || (has_alpha_brush && has_pen && !has_alpha_pen)
- || (cpen.style() > Qt::SolidLine));
- }
- void clipPolygon_dev(const QPolygonF &poly, QPolygonF *clipped_poly);
- void systemStateChanged();
-
- Display *dpy;
- int scrn;
- int pdev_depth;
- Qt::HANDLE hd;
- QPixmap brush_pm;
-#if !defined (QT_NO_XRENDER)
- Qt::HANDLE picture;
- Qt::HANDLE current_brush;
- QPixmap bitmap_texture;
- int composition_mode;
-#else
- Qt::HANDLE picture;
-#endif
- GC gc;
- GC gc_brush;
-
- QPen cpen;
- QBrush cbrush;
- QRegion crgn;
- QTransform matrix;
- qreal opacity;
-
- uint has_complex_xform : 1;
- uint has_scaling_xform : 1;
- uint has_non_scaling_xform : 1;
- uint has_custom_pen : 1;
- uint use_path_fallback : 1;
- uint adjust_coords : 1;
- uint has_clipping : 1;
- uint adapted_brush_origin : 1;
- uint adapted_pen_origin : 1;
- uint has_pen : 1;
- uint has_brush : 1;
- uint has_texture : 1;
- uint has_alpha_texture : 1;
- uint has_pattern : 1;
- uint has_alpha_pen : 1;
- uint has_alpha_brush : 1;
- uint render_hints;
-
- const QX11Info *xinfo;
- QPointF bg_origin;
- QTransform::TransformationType txop;
- qreal xform_scale;
- QPolygonClipper<qt_float_point, qt_float_point, float> polygonClipper;
-
- int xlibMaxLinePoints;
-#ifndef QT_NO_XRENDER
- QXRenderTessellator *tessellator;
-#endif
-};
-
-QT_END_NAMESPACE
-
-#endif // QPAINTENGINE_X11_P_H
diff --git a/src/gui/painting/qpaintengineex_p.h b/src/gui/painting/qpaintengineex_p.h
index e90d40be4d..9674f04ba1 100644
--- a/src/gui/painting/qpaintengineex_p.h
+++ b/src/gui/painting/qpaintengineex_p.h
@@ -54,7 +54,6 @@
//
#include <QtGui/qpaintengine.h>
-#include <QtGui/qdrawutil.h>
#include <private/qpaintengine_p.h>
#include <private/qstroker_p.h>
@@ -213,6 +212,7 @@ public:
virtual void beginNativePainting() {}
virtual void endNativePainting() {}
+ // ### Qt5: remove, once QtGui is merged into QtGui and QtWidgets
// Return a pixmap filter of "type" that can render the parameters
// in "prototype". The returned filter is owned by the engine and
// will be destroyed when the engine is destroyed. The "prototype"
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index f7b6ab6fee..fe9914bd8f 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -56,9 +56,6 @@
#include "qpixmapcache.h"
#include "qpolygon.h"
#include "qtextlayout.h"
-#include "qwidget.h"
-#include "qapplication.h"
-#include "qstyle.h"
#include "qthread.h"
#include "qvarlengtharray.h"
#include "qstatictext.h"
@@ -69,12 +66,12 @@
#include <private/qemulationpaintengine_p.h>
#include <private/qpainterpath_p.h>
#include <private/qtextengine_p.h>
-#include <private/qwidget_p.h>
#include <private/qpaintengine_raster_p.h>
#include <private/qmath_p.h>
#include <private/qstatictext_p.h>
#include <private/qglyphrun_p.h>
-#include <private/qstylehelper_p.h>
+#include <private/qhexstring_p.h>
+#include <private/qguiapplication_p.h>
#include <private/qrawfont_p.h>
QT_BEGIN_NAMESPACE
@@ -242,34 +239,10 @@ bool QPainterPrivate::attachPainterPrivate(QPainter *q, QPaintDevice *pdev)
Q_ASSERT(q);
Q_ASSERT(pdev);
- if (pdev->devType() != QInternal::Widget)
+ QPainter *sp = pdev->sharedPainter();
+ if (!sp)
return false;
- QWidget *widget = static_cast<QWidget *>(pdev);
- Q_ASSERT(widget);
-
- // Someone either called QPainter::setRedirected in the widget's paint event
- // right before this painter was created (or begin was called) or
- // sent a paint event directly to the widget.
- if (!widget->d_func()->redirectDev)
- return false;
-
- QPainter *sp = widget->d_func()->sharedPainter();
- if (!sp || !sp->isActive())
- return false;
-
- if (sp->paintEngine()->paintDevice() != widget->d_func()->redirectDev)
- return false;
-
- // Check if we're attempting to paint outside a paint event.
- if (!sp->d_ptr->engine->hasFeature(QPaintEngine::PaintOutsidePaintEvent)
- && !widget->testAttribute(Qt::WA_PaintOutsidePaintEvent)
- && !widget->testAttribute(Qt::WA_WState_InPaintEvent)) {
-
- qWarning("QPainter::begin: Widget painting can only begin as a result of a paintEvent");
- return false;
- }
-
// Save the current state of the shared painter and assign
// the current d_ptr to the shared painter's d_ptr.
sp->save();
@@ -293,14 +266,14 @@ bool QPainterPrivate::attachPainterPrivate(QPainter *q, QPaintDevice *pdev)
Q_ASSERT(q->d_ptr->state);
// Now initialize the painter with correct widget properties.
- q->initFrom(widget);
+ q->initFrom(pdev);
QPoint offset;
- widget->d_func()->redirected(&offset);
+ pdev->redirected(&offset);
offset += q->d_ptr->engine->coordinateOffset();
// Update system rect.
- q->d_ptr->state->ww = q->d_ptr->state->vw = widget->width();
- q->d_ptr->state->wh = q->d_ptr->state->vh = widget->height();
+ q->d_ptr->state->ww = q->d_ptr->state->vw = pdev->width();
+ q->d_ptr->state->wh = q->d_ptr->state->vh = pdev->height();
// Update matrix.
if (q->d_ptr->state->WxF) {
@@ -314,13 +287,13 @@ bool QPainterPrivate::attachPainterPrivate(QPainter *q, QPaintDevice *pdev)
q->d_ptr->updateMatrix();
QPaintEnginePrivate *enginePrivate = q->d_ptr->engine->d_func();
- if (enginePrivate->currentClipWidget == widget) {
+ if (enginePrivate->currentClipDevice == pdev) {
enginePrivate->systemStateChanged();
return true;
}
// Update system transform and clip.
- enginePrivate->currentClipWidget = widget;
+ enginePrivate->currentClipDevice = pdev;
enginePrivate->setSystemTransform(q->d_ptr->state->matrix);
return true;
}
@@ -1371,17 +1344,14 @@ void QPainterPrivate::updateState(QPainterState *newState)
only use the format types QImage::Format_ARGB32_Premultiplied,
QImage::Format_RGB32 or QImage::Format_RGB16. Any other format,
including QImage::Format_ARGB32, has significantly worse
- performance. This engine is also used by default on Windows and on
- QWS. It can be used as default graphics system on any
- OS/hardware/software combination by passing \c {-graphicssystem
- raster} on the command line
+ performance. This engine is used by default for QWidget and QPixmap.
\o OpenGL 2.0 (ES) - This backend is the primary backend for
hardware accelerated graphics. It can be run on desktop machines
and embedded devices supporting the OpenGL 2.0 or OpenGL/ES 2.0
specification. This includes most graphics chips produced in the
last couple of years. The engine can be enabled by using QPainter
- onto a QGLWidget or by passing \c {-graphicssystem opengl} on the
+ onto a QOpenGLWidget or by passing \c {-graphicssystem opengl} on the
command line when the underlying system supports it.
\o OpenVG - This backend implements the Khronos standard for 2D
@@ -1542,8 +1512,8 @@ QPainter::~QPainter()
QPaintDevice *QPainter::device() const
{
Q_D(const QPainter);
- if (isActive() && d->engine->d_func()->currentClipWidget)
- return d->engine->d_func()->currentClipWidget;
+ if (isActive() && d->engine->d_func()->currentClipDevice)
+ return d->engine->d_func()->currentClipDevice;
return d->original_device;
}
@@ -1562,25 +1532,23 @@ bool QPainter::isActive() const
/*!
Initializes the painters pen, background and font to the same as
- the given \a widget. This function is called automatically when the
- painter is opened on a QWidget.
+ the given \a paint device.
+
+ \obsolete
\sa begin(), {QPainter#Settings}{Settings}
*/
-void QPainter::initFrom(const QWidget *widget)
+void QPainter::initFrom(const QPaintDevice *device)
{
- Q_ASSERT_X(widget, "QPainter::initFrom(const QWidget *widget)", "Widget cannot be 0");
+ Q_ASSERT_X(device, "QPainter::initFrom(const QPaintDevice *device)", "QPaintDevice cannot be 0");
Q_D(QPainter);
if (!d->engine) {
qWarning("QPainter::initFrom: Painter not active, aborted");
return;
}
- const QPalette &pal = widget->palette();
- d->state->pen = QPen(pal.brush(widget->foregroundRole()), 0);
- d->state->bgBrush = pal.brush(widget->backgroundRole());
- d->state->deviceFont = QFont(widget->font(), const_cast<QWidget*> (widget));
- d->state->font = d->state->deviceFont;
+ device->init(this);
+
if (d->extended) {
d->extended->penChanged();
} else if (d->engine) {
@@ -1753,22 +1721,9 @@ bool QPainter::begin(QPaintDevice *pd)
d->helper_device = pd;
d->original_device = pd;
- QPaintDevice *rpd = 0;
QPoint redirectionOffset;
- // We know for sure that redirection is broken when the widget is inside
- // its paint event, so it's safe to use our hard-coded redirection. However,
- // there IS one particular case we still need to support, and that's
- // when people call QPainter::setRedirected in the widget's paint event right
- // before any painter is created (or QPainter::begin is called). In that
- // particular case our hard-coded redirection is restored and the redirection
- // is retrieved from QPainter::redirected (as before).
- if (pd->devType() == QInternal::Widget)
- rpd = static_cast<QWidget *>(pd)->d_func()->redirected(&redirectionOffset);
-
- if (!rpd)
- rpd = redirected(pd, &redirectionOffset);
-
+ QPaintDevice *rpd = pd->redirected(&redirectionOffset);
if (rpd)
pd = rpd;
@@ -1811,6 +1766,8 @@ bool QPainter::begin(QPaintDevice *pd)
d->engine->state = d->state;
switch (pd->devType()) {
+#if 0
+ // is this needed any more??
case QInternal::Widget:
{
const QWidget *widget = static_cast<const QWidget *>(pd);
@@ -1818,13 +1775,6 @@ bool QPainter::begin(QPaintDevice *pd)
const bool paintOutsidePaintEvent = widget->testAttribute(Qt::WA_PaintOutsidePaintEvent);
const bool inPaintEvent = widget->testAttribute(Qt::WA_WState_InPaintEvent);
- if(!d->engine->hasFeature(QPaintEngine::PaintOutsidePaintEvent)
- && !paintOutsidePaintEvent && !inPaintEvent) {
- qWarning("QPainter::begin: Widget painting can only begin as a "
- "result of a paintEvent");
- qt_cleanup_painter_state(d);
- return false;
- }
// Adjust offset for alien widgets painting outside the paint event.
if (!inPaintEvent && paintOutsidePaintEvent && !widget->internalWinId()
@@ -1834,6 +1784,7 @@ bool QPainter::begin(QPaintDevice *pd)
}
break;
}
+#endif
case QInternal::Pixmap:
{
QPixmap *pm = static_cast<QPixmap *>(pd);
@@ -1894,8 +1845,7 @@ bool QPainter::begin(QPaintDevice *pd)
// Copy painter properties from original paint device,
// required for QPixmap::grabWidget()
if (d->original_device->devType() == QInternal::Widget) {
- QWidget *widget = static_cast<QWidget *>(d->original_device);
- initFrom(widget);
+ initFrom(d->original_device);
} else {
d->state->layoutDirection = Qt::LayoutDirectionAuto;
// make sure we have a font compatible with the paintdevice
@@ -4606,82 +4556,6 @@ void QPainter::drawChord(const QRectF &r, int a, int alen)
startAngle and \a spanAngle.
*/
-#ifdef QT3_SUPPORT
-/*!
- \fn void QPainter::drawLineSegments(const QPolygon &polygon, int
- index, int count)
-
- Draws \a count separate lines from points defined by the \a
- polygon, starting at \a{polygon}\e{[index]} (\a index defaults to
- 0). If \a count is -1 (the default) all points until the end of
- the array are used.
-
- Use drawLines() combined with QPolygon::constData() instead.
-
- \oldcode
- QPainter painter(this);
- painter.drawLineSegments(polygon, index, count);
- \newcode
- int lineCount = (count == -1) ? (polygon.size() - index) / 2 : count;
-
- QPainter painter(this);
- painter.drawLines(polygon.constData() + index * 2, lineCount);
- \endcode
-*/
-
-void QPainter::drawLineSegments(const QPolygon &a, int index, int nlines)
-{
-#ifdef QT_DEBUG_DRAW
- if (qt_show_painter_debug_output)
- printf("QPainter::drawLineSegments(), count=%d\n", a.size()/2);
-#endif
- Q_D(QPainter);
-
- if (!d->engine)
- return;
-
- if (nlines < 0)
- nlines = a.size()/2 - index/2;
- if (index + nlines*2 > (int)a.size())
- nlines = (a.size() - index)/2;
- if (nlines < 1 || index < 0)
- return;
-
- if (d->extended) {
- // FALCON: Use QVectorPath
- QVector<QLineF> lines;
- for (int i=index; i<index + nlines*2; i+=2)
- lines << QLineF(a.at(i), a.at(i+1));
- d->extended->drawLines(lines.data(), lines.size());
- return;
- }
-
- d->updateState(d->state);
-
- QVector<QLineF> lines;
- if (d->state->emulationSpecifier) {
- if (d->state->emulationSpecifier == QPaintEngine::PrimitiveTransform
- && d->state->matrix.type() == QTransform::TxTranslate) {
- QPointF offset(d->state->matrix.dx(), d->state->matrix.dy());
- for (int i=index; i<index + nlines*2; i+=2)
- lines << QLineF(a.at(i) + offset, a.at(i+1) + offset);
- } else {
- QPainterPath linesPath;
- for (int i=index; i<index + nlines*2; i+=2) {
- linesPath.moveTo(a.at(i));
- linesPath.lineTo(a.at(i+1));
- }
- d->draw_helper(linesPath, QPainterPrivate::StrokeDraw);
- return;
- }
- } else {
- for (int i=index; i<index + nlines*2; i+=2)
- lines << QLineF(a.at(i), a.at(i+1));
- }
-
- d->engine->drawLines(lines.data(), lines.size());
-}
-#endif // QT3_SUPPORT
/*!
Draws the first \a lineCount lines in the array \a lines
@@ -6467,7 +6341,7 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const
const qreal underlinePos = pos.y() + qCeil(underlineOffset) - aliasedCoordinateDelta;
if (underlineStyle == QTextCharFormat::SpellCheckUnderline) {
- underlineStyle = QTextCharFormat::UnderlineStyle(QApplication::style()->styleHint(QStyle::SH_SpellCheckUnderlineStyle));
+ underlineStyle = QTextCharFormat::SpellCheckUnderline; // ### Qt5 QTextCharFormat::UnderlineStyle(QApplication::style()->styleHint(QStyle::SH_SpellCheckUnderlineStyle));
}
if (underlineStyle == QTextCharFormat::WaveUnderline) {
@@ -7518,328 +7392,6 @@ void QPainter::setViewTransformEnabled(bool enable)
d->updateMatrix();
}
-#ifdef QT3_SUPPORT
-
-/*!
- \obsolete
-
- Use the worldTransform() combined with QTransform::dx() instead.
-
- \oldcode
- QPainter painter(this);
- qreal x = painter.translationX();
- \newcode
- QPainter painter(this);
- qreal x = painter.worldTransform().dx();
- \endcode
-*/
-qreal QPainter::translationX() const
-{
- Q_D(const QPainter);
- if (!d->engine) {
- qWarning("QPainter::translationX: Painter not active");
- return 0.0;
- }
- return d->state->worldMatrix.dx();
-}
-
-/*!
- \obsolete
-
- Use the worldTransform() combined with QTransform::dy() instead.
-
- \oldcode
- QPainter painter(this);
- qreal y = painter.translationY();
- \newcode
- QPainter painter(this);
- qreal y = painter.worldTransform().dy();
- \endcode
-*/
-qreal QPainter::translationY() const
-{
- Q_D(const QPainter);
- if (!d->engine) {
- qWarning("QPainter::translationY: Painter not active");
- return 0.0;
- }
- return d->state->worldMatrix.dy();
-}
-
-/*!
- \fn void QPainter::map(int x, int y, int *rx, int *ry) const
-
- \internal
-
- Sets (\a{rx}, \a{ry}) to the point that results from applying the
- painter's current transformation on the point (\a{x}, \a{y}).
-*/
-void QPainter::map(int x, int y, int *rx, int *ry) const
-{
- QPoint p(x, y);
- p = p * combinedMatrix();
- *rx = p.x();
- *ry = p.y();
-}
-
-/*!
- \fn QPoint QPainter::xForm(const QPoint &point) const
-
- Use combinedTransform() instead.
-*/
-
-QPoint QPainter::xForm(const QPoint &p) const
-{
- Q_D(const QPainter);
- if (!d->engine) {
- qWarning("QPainter::xForm: Painter not active");
- return QPoint();
- }
- if (d->state->matrix.type() == QTransform::TxNone)
- return p;
- return p * combinedMatrix();
-}
-
-
-/*!
- \fn QRect QPainter::xForm(const QRect &rectangle) const
- \overload
-
- Use combinedTransform() instead of this function and call
- mapRect() on the result to obtain a QRect.
-*/
-
-QRect QPainter::xForm(const QRect &r) const
-{
- Q_D(const QPainter);
- if (!d->engine) {
- qWarning("QPainter::xForm: Painter not active");
- return QRect();
- }
- if (d->state->matrix.type() == QTransform::TxNone)
- return r;
- return combinedMatrix().mapRect(r);
-}
-
-/*!
- \fn QPolygon QPainter::xForm(const QPolygon &polygon) const
- \overload
-
- Use combinedTransform() instead.
-*/
-
-QPolygon QPainter::xForm(const QPolygon &a) const
-{
- Q_D(const QPainter);
- if (!d->engine) {
- qWarning("QPainter::xForm: Painter not active");
- return QPolygon();
- }
- if (d->state->matrix.type() == QTransform::TxNone)
- return a;
- return a * combinedMatrix();
-}
-
-/*!
- \fn QPolygon QPainter::xForm(const QPolygon &polygon, int index, int count) const
- \overload
-
- Use combinedTransform() combined with QPolygon::mid() instead.
-
- \oldcode
- QPainter painter(this);
- QPolygon transformed = painter.xForm(polygon, index, count)
- \newcode
- QPainter painter(this);
- QPolygon transformed = polygon.mid(index, count) * painter.combinedTransform();
- \endcode
-*/
-
-QPolygon QPainter::xForm(const QPolygon &av, int index, int npoints) const
-{
- int lastPoint = npoints < 0 ? av.size() : index+npoints;
- QPolygon a(lastPoint-index);
- memcpy(a.data(), av.data()+index, (lastPoint-index)*sizeof(QPoint));
- return a * combinedMatrix();
-}
-
-/*!
- \fn QPoint QPainter::xFormDev(const QPoint &point) const
- \overload
- \obsolete
-
- Use combinedTransform() combined with QTransform::inverted() instead.
-
- \oldcode
- QPainter painter(this);
- QPoint transformed = painter.xFormDev(point);
- \newcode
- QPainter painter(this);
- QPoint transformed = point * painter.combinedTransform().inverted();
- \endcode
-*/
-
-QPoint QPainter::xFormDev(const QPoint &p) const
-{
- Q_D(const QPainter);
- if (!d->engine) {
- qWarning("QPainter::xFormDev: Painter not active");
- return QPoint();
- }
- if(d->state->matrix.type() == QTransform::TxNone)
- return p;
- return p * combinedMatrix().inverted();
-}
-
-/*!
- \fn QRect QPainter::xFormDev(const QRect &rectangle) const
- \overload
- \obsolete
-
- Use combinedTransform() combined with QTransform::inverted() instead.
-
- \oldcode
- QPainter painter(this);
- QRect transformed = painter.xFormDev(rectangle);
- \newcode
- QPainter painter(this);
- QRegion region = QRegion(rectangle) * painter.combinedTransform().inverted();
- QRect transformed = region.boundingRect();
- \endcode
-*/
-
-QRect QPainter::xFormDev(const QRect &r) const
-{
- Q_D(const QPainter);
- if (!d->engine) {
- qWarning("QPainter::xFormDev: Painter not active");
- return QRect();
- }
- if (d->state->matrix.type() == QTransform::TxNone)
- return r;
- return combinedMatrix().inverted().mapRect(r);
-}
-
-/*!
- \overload
-
- \fn QPoint QPainter::xFormDev(const QPolygon &polygon) const
- \obsolete
-
- Use combinedTransform() combined with QTransform::inverted() instead.
-
- \oldcode
- QPainter painter(this);
- QPolygon transformed = painter.xFormDev(rectangle);
- \newcode
- QPainter painter(this);
- QPolygon transformed = polygon * painter.combinedTransform().inverted();
- \endcode
-*/
-
-QPolygon QPainter::xFormDev(const QPolygon &a) const
-{
- Q_D(const QPainter);
- if (!d->engine) {
- qWarning("QPainter::xFormDev: Painter not active");
- return QPolygon();
- }
- if (d->state->matrix.type() == QTransform::TxNone)
- return a;
- return a * combinedMatrix().inverted();
-}
-
-/*!
- \fn QPolygon QPainter::xFormDev(const QPolygon &polygon, int index, int count) const
- \overload
- \obsolete
-
- Use combinedTransform() combined with QPolygon::mid() and QTransform::inverted() instead.
-
- \oldcode
- QPainter painter(this);
- QPolygon transformed = painter.xFormDev(polygon, index, count);
- \newcode
- QPainter painter(this);
- QPolygon transformed = polygon.mid(index, count) * painter.combinedTransform().inverted();
- \endcode
-*/
-
-QPolygon QPainter::xFormDev(const QPolygon &ad, int index, int npoints) const
-{
- Q_D(const QPainter);
- int lastPoint = npoints < 0 ? ad.size() : index+npoints;
- QPolygon a(lastPoint-index);
- memcpy(a.data(), ad.data()+index, (lastPoint-index)*sizeof(QPoint));
- if (d->state->matrix.type() == QTransform::TxNone)
- return a;
- return a * combinedMatrix().inverted();
-}
-
-/*!
- \fn void QPainter::drawCubicBezier(const QPolygon &controlPoints, int index)
-
- Draws a cubic Bezier curve defined by the \a controlPoints,
- starting at \a{controlPoints}\e{[index]} (\a index defaults to 0).
- Points after \a{controlPoints}\e{[index + 3]} are ignored. Nothing
- happens if there aren't enough control points.
-
- Use strokePath() instead.
-
- \oldcode
- QPainter painter(this);
- painter.drawCubicBezier(controlPoints, index)
- \newcode
- QPainterPath path;
- path.moveTo(controlPoints.at(index));
- path.cubicTo(controlPoints.at(index+1),
- controlPoints.at(index+2),
- controlPoints.at(index+3));
-
- QPainter painter(this);
- painter.strokePath(path, painter.pen());
- \endcode
-*/
-void QPainter::drawCubicBezier(const QPolygon &a, int index)
-{
- Q_D(QPainter);
-
- if (!d->engine)
- return;
-
- if ((int)a.size() - index < 4) {
- qWarning("QPainter::drawCubicBezier: Cubic Bezier needs 4 control "
- "points");
- return;
- }
-
- QPainterPath path;
- path.moveTo(a.at(index));
- path.cubicTo(a.at(index+1), a.at(index+2), a.at(index+3));
- strokePath(path, d->state->pen);
-}
-#endif
-
-struct QPaintDeviceRedirection
-{
- QPaintDeviceRedirection() : device(0), replacement(0), internalWidgetRedirectionIndex(-1) {}
- QPaintDeviceRedirection(const QPaintDevice *device, QPaintDevice *replacement,
- const QPoint& offset, int internalWidgetRedirectionIndex)
- : device(device), replacement(replacement), offset(offset),
- internalWidgetRedirectionIndex(internalWidgetRedirectionIndex) { }
- const QPaintDevice *device;
- QPaintDevice *replacement;
- QPoint offset;
- int internalWidgetRedirectionIndex;
- bool operator==(const QPaintDevice *pdev) const { return device == pdev; }
- Q_DUMMY_COMPARISON_OPERATOR(QPaintDeviceRedirection)
-};
-
-typedef QList<QPaintDeviceRedirection> QPaintDeviceRedirectionList;
-Q_GLOBAL_STATIC(QPaintDeviceRedirectionList, globalRedirections)
-Q_GLOBAL_STATIC(QMutex, globalRedirectionsMutex)
-Q_GLOBAL_STATIC(QAtomicInt, globalRedirectionAtomic)
-
/*!
\threadsafe
@@ -7868,30 +7420,9 @@ void QPainter::setRedirected(const QPaintDevice *device,
const QPoint &offset)
{
Q_ASSERT(device != 0);
-
- bool hadInternalWidgetRedirection = false;
- if (device->devType() == QInternal::Widget) {
- const QWidgetPrivate *widgetPrivate = static_cast<const QWidget *>(device)->d_func();
- // This is the case when the widget is in a paint event.
- if (widgetPrivate->redirectDev) {
- // Remove internal redirection and put it back into the global redirection list.
- QPoint oldOffset;
- QPaintDevice *oldReplacement = widgetPrivate->redirected(&oldOffset);
- const_cast<QWidgetPrivate *>(widgetPrivate)->restoreRedirected();
- setRedirected(device, oldReplacement, oldOffset);
- hadInternalWidgetRedirection = true;
- }
- }
-
- QPoint roffset;
- QPaintDevice *rdev = redirected(replacement, &roffset);
-
- QMutexLocker locker(globalRedirectionsMutex());
- QPaintDeviceRedirectionList *redirections = globalRedirections();
- Q_ASSERT(redirections != 0);
- *redirections += QPaintDeviceRedirection(device, rdev ? rdev : replacement, offset + roffset,
- hadInternalWidgetRedirection ? redirections->size() - 1 : -1);
- globalRedirectionAtomic()->ref();
+ Q_UNUSED(replacement)
+ Q_UNUSED(offset)
+ qWarning("QPainter::setRedirected(): ignoring call to deprecated function, use QWidget::render() instead");
}
/*!
@@ -7913,29 +7444,8 @@ void QPainter::setRedirected(const QPaintDevice *device,
*/
void QPainter::restoreRedirected(const QPaintDevice *device)
{
- Q_ASSERT(device != 0);
- QMutexLocker locker(globalRedirectionsMutex());
- QPaintDeviceRedirectionList *redirections = globalRedirections();
- Q_ASSERT(redirections != 0);
- for (int i = redirections->size()-1; i >= 0; --i) {
- if (redirections->at(i) == device) {
- globalRedirectionAtomic()->deref();
- const int internalWidgetRedirectionIndex = redirections->at(i).internalWidgetRedirectionIndex;
- redirections->removeAt(i);
- // Restore the internal widget redirection, i.e. remove it from the global
- // redirection list and put it back into QWidgetPrivate. The index is only set when
- // someone call QPainter::setRedirected in a widget's paint event and we internally
- // have a redirection set (typically set in QWidgetPrivate::drawWidget).
- if (internalWidgetRedirectionIndex >= 0) {
- Q_ASSERT(internalWidgetRedirectionIndex < redirections->size());
- const QPaintDeviceRedirection &redirectionDevice = redirections->at(internalWidgetRedirectionIndex);
- QWidget *widget = static_cast<QWidget *>(const_cast<QPaintDevice *>(device));
- widget->d_func()->setRedirected(redirectionDevice.replacement, redirectionDevice.offset);
- redirections->removeAt(internalWidgetRedirectionIndex);
- }
- return;
- }
- }
+ Q_UNUSED(device)
+ qWarning("QPainter::restoreRedirected(): ignoring call to deprecated function, use QWidget::render() instead");
}
/*!
@@ -7957,61 +7467,11 @@ void QPainter::restoreRedirected(const QPaintDevice *device)
*/
QPaintDevice *QPainter::redirected(const QPaintDevice *device, QPoint *offset)
{
- Q_ASSERT(device != 0);
-
- if (device->devType() == QInternal::Widget) {
- const QWidgetPrivate *widgetPrivate = static_cast<const QWidget *>(device)->d_func();
- if (widgetPrivate->redirectDev)
- return widgetPrivate->redirected(offset);
- }
-
- if (!globalRedirectionAtomic() || *globalRedirectionAtomic() == 0)
- return 0;
-
- QMutexLocker locker(globalRedirectionsMutex());
- QPaintDeviceRedirectionList *redirections = globalRedirections();
- Q_ASSERT(redirections != 0);
- for (int i = redirections->size()-1; i >= 0; --i)
- if (redirections->at(i) == device) {
- if (offset)
- *offset = redirections->at(i).offset;
- return redirections->at(i).replacement;
- }
- if (offset)
- *offset = QPoint(0, 0);
+ Q_UNUSED(device)
+ Q_UNUSED(offset)
return 0;
}
-
-void qt_painter_removePaintDevice(QPaintDevice *dev)
-{
- if (!globalRedirectionAtomic() || *globalRedirectionAtomic() == 0)
- return;
-
- QMutex *mutex = 0;
- QT_TRY {
- mutex = globalRedirectionsMutex();
- } QT_CATCH(...) {
- // ignore the missing mutex, since we could be called from
- // a destructor, and destructors shall not throw
- }
- QMutexLocker locker(mutex);
- QPaintDeviceRedirectionList *redirections = 0;
- QT_TRY {
- redirections = globalRedirections();
- } QT_CATCH(...) {
- // do nothing - code below is safe with redirections being 0.
- }
- if (redirections) {
- for (int i = 0; i < redirections->size(); ) {
- if(redirections->at(i) == dev || redirections->at(i).replacement == dev)
- redirections->removeAt(i);
- else
- ++i;
- }
- }
-}
-
void qt_format_text(const QFont &fnt, const QRectF &_r,
int tf, const QString& str, QRectF *brect,
int tabstops, int *ta, int tabarraylen,
@@ -8063,7 +7523,7 @@ void qt_format_text(const QFont &fnt, const QRectF &_r,
else
layout_direction = Qt::LeftToRight;
- tf = QStyle::visualAlignment(layout_direction, QFlag(tf));
+ tf = QGuiApplicationPrivate::visualAlignment(layout_direction, QFlag(tf));
bool isRightToLeft = layout_direction == Qt::RightToLeft;
bool expandtabs = ((tf & Qt::TextExpandTabs) &&
@@ -8323,7 +7783,7 @@ QPainterState::QPainterState()
wx(0), wy(0), ww(0), wh(0), vx(0), vy(0), vw(0), vh(0),
opacity(1), WxF(false), VxF(false), clipEnabled(true),
bgMode(Qt::TransparentMode), painter(0),
- layoutDirection(QApplication::layoutDirection()),
+ layoutDirection(QGuiApplication::layoutDirection()),
composition_mode(QPainter::CompositionMode_SourceOver),
emulationSpecifier(0), changeFlags(0)
{
@@ -8353,7 +7813,7 @@ void QPainterState::init(QPainter *p) {
clipInfo.clear();
worldMatrix.reset();
matrix.reset();
- layoutDirection = QApplication::layoutDirection();
+ layoutDirection = QGuiApplication::layoutDirection();
composition_mode = QPainter::CompositionMode_SourceOver;
emulationSpecifier = 0;
dirtyFlags = 0;
@@ -8362,45 +7822,6 @@ void QPainterState::init(QPainter *p) {
opacity = 1;
}
-#ifdef QT3_SUPPORT
-static void bitBlt_helper(QPaintDevice *dst, const QPoint &dp,
- const QPaintDevice *src, const QRect &sr, bool)
-{
- Q_ASSERT(dst);
- Q_ASSERT(src);
-
- if (src->devType() == QInternal::Pixmap) {
- const QPixmap *pixmap = static_cast<const QPixmap *>(src);
- QPainter pt(dst);
- pt.drawPixmap(dp, *pixmap, sr);
-
- } else {
- qWarning("QPainter: bitBlt only works when source is of type pixmap");
- }
-}
-
-void bitBlt(QPaintDevice *dst, int dx, int dy,
- const QPaintDevice *src, int sx, int sy, int sw, int sh,
- bool ignoreMask )
-{
- bitBlt_helper(dst, QPoint(dx, dy), src, QRect(sx, sy, sw, sh), ignoreMask);
-}
-
-void bitBlt(QPaintDevice *dst, const QPoint &dp, const QPaintDevice *src, const QRect &sr, bool ignoreMask)
-{
- bitBlt_helper(dst, dp, src, sr, ignoreMask);
-}
-
-void bitBlt(QPaintDevice *dst, int dx, int dy,
- const QImage *src, int sx, int sy, int sw, int sh, int fl)
-{
- Qt::ImageConversionFlags flags(fl);
- QPixmap srcPixmap = QPixmap::fromImage(*src, flags);
- bitBlt_helper(dst, QPoint(dx, dy), &srcPixmap, QRect(sx, sy, sw, sh), false);
-}
-
-#endif // QT3_SUPPORT
-
/*!
\fn void QPainter::setBackgroundColor(const QColor &color)
diff --git a/src/gui/painting/qpainter.h b/src/gui/painting/qpainter.h
index 30f8da0928..fd40111368 100644
--- a/src/gui/painting/qpainter.h
+++ b/src/gui/painting/qpainter.h
@@ -49,7 +49,6 @@
#include <QtGui/qpixmap.h>
#include <QtGui/qimage.h>
#include <QtGui/qtextoption.h>
-#include <QtGui/qdrawutil.h>
#ifndef QT_INCLUDE_COMPAT
#include <QtGui/qpolygon.h>
@@ -133,7 +132,7 @@ public:
bool end();
bool isActive() const;
- void initFrom(const QWidget *widget);
+ void initFrom(const QPaintDevice *device);
enum CompositionMode {
CompositionMode_SourceOver,
@@ -464,85 +463,13 @@ public:
void beginNativePainting();
void endNativePainting();
-#ifdef QT3_SUPPORT
-
- inline QT3_SUPPORT void setBackgroundColor(const QColor &color) { setBackground(color); }
- inline QT3_SUPPORT const QColor &backgroundColor() const { return background().color(); }
-
- inline QT3_SUPPORT void drawText(int x, int y, const QString &s, int pos, int len)
- { drawText(x, y, s.mid(pos, len)); }
- inline QT3_SUPPORT void drawText(const QPoint &p, const QString &s, int pos, int len)
- { drawText(p, s.mid(pos, len)); }
- inline QT3_SUPPORT void drawText(int x, int y, const QString &s, int len)
- { drawText(x, y, s.left(len)); }
- inline QT3_SUPPORT void drawText(const QPoint &p, const QString &s, int len)
- { drawText(p, s.left(len)); }
- inline QT3_SUPPORT void drawText(const QRect &r, int flags, const QString &str, int len, QRect *br=0)
- { drawText(r, flags, str.left(len), br); }
- inline QT3_SUPPORT void drawText(int x, int y, int w, int h, int flags, const QString &text, int len, QRect *br=0)
- { drawText(QRect(x, y, w, h), flags, text.left(len), br); }
- inline QT3_SUPPORT QRect boundingRect(const QRect &rect, int flags, const QString &text, int len)
- { return boundingRect(rect, flags, text.left(len)); }
- inline QT3_SUPPORT QRect boundingRect(int x, int y, int w, int h, int flags, const QString &text, int len)
- { return boundingRect(QRect(x, y, w, h), flags, text.left(len)); }
-
- inline QT3_SUPPORT bool begin(QPaintDevice *pdev, const QWidget *init)
- { bool ret = begin(pdev); initFrom(init); return ret; }
- QT3_SUPPORT void drawPoints(const QPolygon &pa, int index, int npoints = -1)
- { drawPoints(pa.constData() + index, npoints == -1 ? pa.size() - index : npoints); }
-
- QT3_SUPPORT void drawCubicBezier(const QPolygon &pa, int index = 0);
-
- QT3_SUPPORT void drawLineSegments(const QPolygon &points, int index = 0, int nlines = -1);
-
- inline QT3_SUPPORT void drawPolyline(const QPolygon &pa, int index, int npoints = -1)
- { drawPolyline(pa.constData() + index, npoints == -1 ? pa.size() - index : npoints); }
-
- inline QT3_SUPPORT void drawPolygon(const QPolygon &pa, bool winding, int index = 0, int npoints = -1)
- { drawPolygon(pa.constData() + index, npoints == -1 ? pa.size() - index : npoints,
- winding ? Qt::WindingFill : Qt::OddEvenFill); }
-
- inline QT3_SUPPORT void drawPolygon(const QPolygonF &polygon, bool winding, int index = 0,
- int npoints = -1)
- { drawPolygon(polygon.constData() + index, npoints == -1 ? polygon.size() - index : npoints,
- winding ? Qt::WindingFill : Qt::OddEvenFill); }
-
- inline QT3_SUPPORT void drawConvexPolygon(const QPolygonF &polygon, int index, int npoints = -1)
- { drawConvexPolygon(polygon.constData() + index, npoints == -1 ? polygon.size() - index : npoints); }
- inline QT3_SUPPORT void drawConvexPolygon(const QPolygon &pa, int index, int npoints = -1)
- { drawConvexPolygon(pa.constData() + index, npoints == -1 ? pa.size() - index : npoints); }
-
- static inline QT3_SUPPORT void redirect(QPaintDevice *pdev, QPaintDevice *replacement)
- { setRedirected(pdev, replacement); }
- static inline QT3_SUPPORT QPaintDevice *redirect(QPaintDevice *pdev)
- { return const_cast<QPaintDevice*>(redirected(pdev)); }
-
- inline QT3_SUPPORT void setWorldXForm(bool enabled) { setMatrixEnabled(enabled); }
- inline QT3_SUPPORT bool hasWorldXForm() const { return matrixEnabled(); }
- inline QT3_SUPPORT void resetXForm() { resetTransform(); }
-
- inline QT3_SUPPORT void setViewXForm(bool enabled) { setViewTransformEnabled(enabled); }
- inline QT3_SUPPORT bool hasViewXForm() const { return viewTransformEnabled(); }
-
- QT3_SUPPORT void map(int x, int y, int *rx, int *ry) const;
- QT3_SUPPORT QPoint xForm(const QPoint &) const; // map virtual -> deviceb
- QT3_SUPPORT QRect xForm(const QRect &) const;
- QT3_SUPPORT QPolygon xForm(const QPolygon &) const;
- QT3_SUPPORT QPolygon xForm(const QPolygon &, int index, int npoints) const;
- QT3_SUPPORT QPoint xFormDev(const QPoint &) const; // map device -> virtual
- QT3_SUPPORT QRect xFormDev(const QRect &) const;
- QT3_SUPPORT QPolygon xFormDev(const QPolygon &) const;
- QT3_SUPPORT QPolygon xFormDev(const QPolygon &, int index, int npoints) const;
- QT3_SUPPORT qreal translationX() const;
- QT3_SUPPORT qreal translationY() const;
-#endif
-
private:
Q_DISABLE_COPY(QPainter)
friend class Q3Painter;
QScopedPointer<QPainterPrivate> d_ptr;
+ friend class QWidget;
friend class QFontEngine;
friend class QFontEngineBox;
friend class QFontEngineFT;
diff --git a/src/gui/painting/qpathclipper_p.h b/src/gui/painting/qpathclipper_p.h
index 742cabda81..fe4a97ad4c 100644
--- a/src/gui/painting/qpathclipper_p.h
+++ b/src/gui/painting/qpathclipper_p.h
@@ -68,7 +68,7 @@ QT_MODULE(Gui)
class QWingedEdge;
-class Q_AUTOTEST_EXPORT QPathClipper
+class Q_GUI_EXPORT QPathClipper
{
public:
enum Operation {
diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp
index 958e49907b..47687e4a53 100644
--- a/src/gui/painting/qpdf.cpp
+++ b/src/gui/painting/qpdf.cpp
@@ -44,20 +44,42 @@
#include <qfile.h>
#include <qtemporaryfile.h>
#include <private/qmath_p.h>
-#include "private/qcups_p.h"
-#include "qprinterinfo.h"
#include <qnumeric.h>
#include "private/qfont_p.h"
+#include <qimagewriter.h>
+#include "qbuffer.h"
+#include "QtCore/qdatetime.h"
-#ifdef Q_OS_UNIX
-#include "private/qcore_unix_p.h" // overrides QT_OPEN
+#ifndef QT_NO_COMPRESS
+#include <zlib.h>
#endif
+#ifdef QT_NO_COMPRESS
+static const bool do_compress = false;
+#else
+static const bool do_compress = true;
+#endif
+
+// might be helpful for smooth transforms of images
+// Can't use it though, as gs generates completely wrong images if this is true.
+static const bool interpolateImages = false;
+
QT_BEGIN_NAMESPACE
-#ifndef QT_NO_PRINTER
+inline QPaintEngine::PaintEngineFeatures qt_pdf_decide_features()
+{
+ QPaintEngine::PaintEngineFeatures f = QPaintEngine::AllFeatures;
+ f &= ~(QPaintEngine::PorterDuff | QPaintEngine::PerspectiveTransform
+ | QPaintEngine::ObjectBoundingModeGradients
+#ifndef USE_NATIVE_GRADIENTS
+ | QPaintEngine::LinearGradientFill
+#endif
+ | QPaintEngine::RadialGradientFill
+ | QPaintEngine::ConicalGradientFill);
+ return f;
+}
+
-extern QSizeF qt_paperSizeToQSizeF(QPrinter::PaperSize size);
/* also adds a space at the end of the number */
const char *qt_real_to_string(qreal val, char *buf) {
@@ -891,67 +913,43 @@ const char *QPdf::toHex(uchar u, char *buffer)
return buffer;
}
-#define Q_MM(n) int((n * 720 + 127) / 254)
-#define Q_IN(n) int(n * 72)
-static const char * const psToStr[QPrinter::NPaperSize+1] =
+QPdfPage::QPdfPage()
+ : QPdf::ByteStream(true) // Enable file backing
{
- "A4", "B5", "Letter", "Legal", "Executive",
- "A0", "A1", "A2", "A3", "A5", "A6", "A7", "A8", "A9", "B0", "B1",
- "B10", "B2", "B3", "B4", "B6", "B7", "B8", "B9", "C5E", "Comm10E",
- "DLE", "Folio", "Ledger", "Tabloid", 0
-};
+}
-QPdf::PaperSize QPdf::paperSize(QPrinter::PaperSize paperSize)
+void QPdfPage::streamImage(int w, int h, int object)
{
- QSizeF s = qt_paperSizeToQSizeF(paperSize);
- PaperSize p = { Q_MM(s.width()), Q_MM(s.height()) };
- return p;
+ *this << w << "0 0 " << -h << "0 " << h << "cm /Im" << object << " Do\n";
+ if (!images.contains(object))
+ images.append(object);
}
-const char *QPdf::paperSizeToString(QPrinter::PaperSize paperSize)
+
+QPdfEngine::QPdfEngine(QPdfEnginePrivate &dd)
+ : QPaintEngine(dd, qt_pdf_decide_features())
{
- return psToStr[paperSize];
}
-// -------------------------- base engine, shared code between PS and PDF -----------------------
-
-QPdfBaseEngine::QPdfBaseEngine(QPdfBaseEnginePrivate &dd, PaintEngineFeatures f)
- : QAlphaPaintEngine(dd, f)
+QPdfEngine::QPdfEngine()
+ : QPaintEngine(*new QPdfEnginePrivate(), qt_pdf_decide_features())
{
- Q_D(QPdfBaseEngine);
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
- if (QCUPSSupport::isAvailable()) {
- QCUPSSupport cups;
- const cups_dest_t* printers = cups.availablePrinters();
- int prnCount = cups.availablePrintersCount();
-
- for (int i = 0; i < prnCount; ++i) {
- if (printers[i].is_default) {
- d->printerName = QString::fromLocal8Bit(printers[i].name);
- break;
- }
- }
+}
- } else
-#endif
- {
- d->printerName = QString::fromLocal8Bit(qgetenv("PRINTER"));
- if (d->printerName.isEmpty())
- d->printerName = QString::fromLocal8Bit(qgetenv("LPDEST"));
- if (d->printerName.isEmpty())
- d->printerName = QString::fromLocal8Bit(qgetenv("NPRINTER"));
- if (d->printerName.isEmpty())
- d->printerName = QString::fromLocal8Bit(qgetenv("NGPRINTER"));
- }
+void QPdfEngine::setOutputFilename(const QString &filename)
+{
+ Q_D(QPdfEngine);
+ d->outputFileName = filename;
}
-void QPdfBaseEngine::drawPoints (const QPointF *points, int pointCount)
+
+void QPdfEngine::drawPoints (const QPointF *points, int pointCount)
{
if (!points)
return;
- Q_D(QPdfBaseEngine);
+ Q_D(QPdfEngine);
QPainterPath p;
for (int i=0; i!=pointCount;++i) {
p.moveTo(points[i]);
@@ -964,12 +962,12 @@ void QPdfBaseEngine::drawPoints (const QPointF *points, int pointCount)
d->hasBrush = hadBrush;
}
-void QPdfBaseEngine::drawLines (const QLineF *lines, int lineCount)
+void QPdfEngine::drawLines (const QLineF *lines, int lineCount)
{
if (!lines)
return;
- Q_D(QPdfBaseEngine);
+ Q_D(QPdfEngine);
QPainterPath p;
for (int i=0; i!=lineCount;++i) {
p.moveTo(lines[i].p1());
@@ -981,17 +979,12 @@ void QPdfBaseEngine::drawLines (const QLineF *lines, int lineCount)
d->hasBrush = hadBrush;
}
-void QPdfBaseEngine::drawRects (const QRectF *rects, int rectCount)
+void QPdfEngine::drawRects (const QRectF *rects, int rectCount)
{
if (!rects)
return;
- Q_D(QPdfBaseEngine);
- if (d->useAlphaEngine) {
- QAlphaPaintEngine::drawRects(rects, rectCount);
- if (!continueCall())
- return;
- }
+ Q_D(QPdfEngine);
if (d->clipEnabled && d->allClipped)
return;
@@ -1016,15 +1009,9 @@ void QPdfBaseEngine::drawRects (const QRectF *rects, int rectCount)
}
}
-void QPdfBaseEngine::drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode)
+void QPdfEngine::drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode)
{
- Q_D(QPdfBaseEngine);
-
- if (d->useAlphaEngine) {
- QAlphaPaintEngine::drawPolygon(points, pointCount, mode);
- if (!continueCall())
- return;
- }
+ Q_D(QPdfEngine);
if (!points || !pointCount)
return;
@@ -1058,15 +1045,9 @@ void QPdfBaseEngine::drawPolygon(const QPointF *points, int pointCount, PolygonD
d->hasBrush = hb;
}
-void QPdfBaseEngine::drawPath (const QPainterPath &p)
+void QPdfEngine::drawPath (const QPainterPath &p)
{
- Q_D(QPdfBaseEngine);
-
- if (d->useAlphaEngine) {
- QAlphaPaintEngine::drawPath(p);
- if (!continueCall())
- return;
- }
+ Q_D(QPdfEngine);
if (d->clipEnabled && d->allClipped)
return;
@@ -1091,15 +1072,92 @@ void QPdfBaseEngine::drawPath (const QPainterPath &p)
}
}
-void QPdfBaseEngine::drawTextItem(const QPointF &p, const QTextItem &textItem)
+void QPdfEngine::drawPixmap (const QRectF &rectangle, const QPixmap &pixmap, const QRectF &sr)
{
- Q_D(QPdfBaseEngine);
+ if (sr.isEmpty() || rectangle.isEmpty() || pixmap.isNull())
+ return;
+ Q_D(QPdfEngine);
- if (d->useAlphaEngine) {
- QAlphaPaintEngine::drawTextItem(p, textItem);
- if (!continueCall())
- return;
+ QBrush b = d->brush;
+
+ QRect sourceRect = sr.toRect();
+ QPixmap pm = sourceRect != pixmap.rect() ? pixmap.copy(sourceRect) : pixmap;
+ QImage image = pm.toImage();
+ bool bitmap = true;
+ const int object = d->addImage(image, &bitmap, pm.cacheKey());
+ if (object < 0)
+ return;
+
+ *d->currentPage << "q\n/GSa gs\n";
+ *d->currentPage
+ << QPdf::generateMatrix(QTransform(rectangle.width() / sr.width(), 0, 0, rectangle.height() / sr.height(),
+ rectangle.x(), rectangle.y()) * (d->simplePen ? QTransform() : d->stroker.matrix));
+ if (bitmap) {
+ // set current pen as d->brush
+ d->brush = d->pen.brush();
}
+ setBrush();
+ d->currentPage->streamImage(image.width(), image.height(), object);
+ *d->currentPage << "Q\n";
+
+ d->brush = b;
+}
+
+void QPdfEngine::drawImage(const QRectF &rectangle, const QImage &image, const QRectF &sr, Qt::ImageConversionFlags)
+{
+ if (sr.isEmpty() || rectangle.isEmpty() || image.isNull())
+ return;
+ Q_D(QPdfEngine);
+
+ QRect sourceRect = sr.toRect();
+ QImage im = sourceRect != image.rect() ? image.copy(sourceRect) : image;
+ bool bitmap = true;
+ const int object = d->addImage(im, &bitmap, im.cacheKey());
+ if (object < 0)
+ return;
+
+ *d->currentPage << "q\n/GSa gs\n";
+ *d->currentPage
+ << QPdf::generateMatrix(QTransform(rectangle.width() / sr.width(), 0, 0, rectangle.height() / sr.height(),
+ rectangle.x(), rectangle.y()) * (d->simplePen ? QTransform() : d->stroker.matrix));
+ setBrush();
+ d->currentPage->streamImage(im.width(), im.height(), object);
+ *d->currentPage << "Q\n";
+}
+
+void QPdfEngine::drawTiledPixmap (const QRectF &rectangle, const QPixmap &pixmap, const QPointF &point)
+{
+ Q_D(QPdfEngine);
+
+ bool bitmap = (pixmap.depth() == 1);
+ QBrush b = d->brush;
+ QPointF bo = d->brushOrigin;
+ bool hp = d->hasPen;
+ d->hasPen = false;
+ bool hb = d->hasBrush;
+ d->hasBrush = true;
+
+ d->brush = QBrush(pixmap);
+ if (bitmap)
+ // #### fix bitmap case where we have a brush pen
+ d->brush.setColor(d->pen.color());
+
+ d->brushOrigin = -point;
+ *d->currentPage << "q\n";
+ setBrush();
+
+ drawRects(&rectangle, 1);
+ *d->currentPage << "Q\n";
+
+ d->hasPen = hp;
+ d->hasBrush = hb;
+ d->brush = b;
+ d->brushOrigin = bo;
+}
+
+void QPdfEngine::drawTextItem(const QPointF &p, const QTextItem &textItem)
+{
+ Q_D(QPdfEngine);
if (!d->hasPen || (d->clipEnabled && d->allClipped))
return;
@@ -1128,15 +1186,9 @@ void QPdfBaseEngine::drawTextItem(const QPointF &p, const QTextItem &textItem)
}
-void QPdfBaseEngine::updateState(const QPaintEngineState &state)
+void QPdfEngine::updateState(const QPaintEngineState &state)
{
- Q_D(QPdfBaseEngine);
-
- if (d->useAlphaEngine) {
- QAlphaPaintEngine::updateState(state);
- if (!continueCall())
- return;
- }
+ Q_D(QPdfEngine);
QPaintEngine::DirtyFlags flags = state.state();
@@ -1190,9 +1242,9 @@ void QPdfBaseEngine::updateState(const QPaintEngineState &state)
setupGraphicsState(flags);
}
-void QPdfBaseEngine::setupGraphicsState(QPaintEngine::DirtyFlags flags)
+void QPdfEngine::setupGraphicsState(QPaintEngine::DirtyFlags flags)
{
- Q_D(QPdfBaseEngine);
+ Q_D(QPdfEngine);
if (flags & DirtyClipPath)
flags |= DirtyTransform|DirtyPen|DirtyBrush;
@@ -1233,9 +1285,9 @@ void QPdfBaseEngine::setupGraphicsState(QPaintEngine::DirtyFlags flags)
extern QPainterPath qt_regionToPath(const QRegion &region);
-void QPdfBaseEngine::updateClipPath(const QPainterPath &p, Qt::ClipOperation op)
+void QPdfEngine::updateClipPath(const QPainterPath &p, Qt::ClipOperation op)
{
- Q_D(QPdfBaseEngine);
+ Q_D(QPdfEngine);
QPainterPath path = d->stroker.matrix.map(p);
//qDebug() << "updateClipPath: " << d->stroker.matrix << p.boundingRect() << path.boundingRect() << op;
@@ -1254,43 +1306,18 @@ void QPdfBaseEngine::updateClipPath(const QPainterPath &p, Qt::ClipOperation op)
d->clips.clear();
d->clips.append(path);
}
-
- if (d->useAlphaEngine) {
- // 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
- QPainterPath alphaClip = qt_regionToPath(alphaClipping());
- if (!alphaClip.isEmpty()) {
- if (!d->clipEnabled) {
- QRect r = d->fullPage ? d->paperRect() : d->pageRect();
- QPainterPath dev;
- dev.addRect(QRect(0, 0, r.width(), r.height()));
- if (path.isEmpty())
- path = dev;
- else
- path = path.intersected(dev);
- d->clipEnabled = true;
- } else {
- path = painter()->clipPath();
- path = d->stroker.matrix.map(path);
- }
- path = path.subtracted(alphaClip);
- d->clips.clear();
- d->clips.append(path);
- }
- }
}
-void QPdfBaseEngine::setPen()
+void QPdfEngine::setPen()
{
- Q_D(QPdfBaseEngine);
+ Q_D(QPdfEngine);
if (d->pen.style() == Qt::NoPen)
return;
QBrush b = d->pen.brush();
Q_ASSERT(b.style() == Qt::SolidPattern && b.isOpaque());
QColor rgba = b.color();
- if (d->colorMode == QPrinter::GrayScale) {
+ if (d->grayscale) {
qreal gray = qGray(rgba.rgba())/255.;
*d->currentPage << gray << gray << gray;
} else {
@@ -1337,9 +1364,48 @@ void QPdfBaseEngine::setPen()
*d->currentPage << QPdf::generateDashes(d->pen) << " 0 d\n";
}
-bool QPdfBaseEngine::newPage()
+
+void QPdfEngine::setBrush()
+{
+ Q_D(QPdfEngine);
+ Qt::BrushStyle style = d->brush.style();
+ if (style == Qt::NoBrush)
+ return;
+
+ bool specifyColor;
+ int gStateObject = 0;
+ int patternObject = d->addBrushPattern(d->stroker.matrix, &specifyColor, &gStateObject);
+
+ *d->currentPage << (patternObject ? "/PCSp cs " : "/CSp cs ");
+ if (specifyColor) {
+ QColor rgba = d->brush.color();
+ if (d->grayscale) {
+ qreal gray = qGray(rgba.rgba())/255.;
+ *d->currentPage << gray << gray << gray;
+ } else {
+ *d->currentPage << rgba.redF()
+ << rgba.greenF()
+ << rgba.blueF();
+ }
+ }
+ if (patternObject)
+ *d->currentPage << "/Pat" << patternObject;
+ *d->currentPage << "scn\n";
+
+ if (gStateObject)
+ *d->currentPage << "/GState" << gStateObject << "gs\n";
+ else
+ *d->currentPage << "/GSa gs\n";
+}
+
+
+bool QPdfEngine::newPage()
{
- Q_D(QPdfBaseEngine);
+ Q_D(QPdfEngine);
+ if (!isActive())
+ return false;
+ d->newPage();
+
setupGraphicsState(DirtyBrush|DirtyPen|DirtyClipPath);
QFile *outfile = qobject_cast<QFile*> (d->outDevice);
if (outfile && outfile->error() != QFile::NoError)
@@ -1347,12 +1413,18 @@ bool QPdfBaseEngine::newPage()
return true;
}
+QPaintEngine::Type QPdfEngine::type() const
+{
+ return QPaintEngine::Pdf;
+}
-int QPdfBaseEngine::metric(QPaintDevice::PaintDeviceMetric metricType) const
+
+
+int QPdfEngine::metric(QPaintDevice::PaintDeviceMetric metricType) const
{
- Q_D(const QPdfBaseEngine);
+ Q_D(const QPdfEngine);
int val;
- QRect r = d->fullPage ? d->paperRect() : d->pageRect();
+ QRect r = d->pageRect();
switch (metricType) {
case QPaintDevice::PdmWidth:
val = r.width();
@@ -1381,244 +1453,53 @@ int QPdfBaseEngine::metric(QPaintDevice::PaintDeviceMetric metricType) const
val = 32;
break;
default:
- qWarning("QPrinter::metric: Invalid metric command");
+ qWarning("QPdfWriter::metric: Invalid metric command");
return 0;
}
return val;
}
-void QPdfBaseEngine::setProperty(PrintEnginePropertyKey key, const QVariant &value)
-{
- Q_D(QPdfBaseEngine);
- switch (int(key)) {
- case PPK_CollateCopies:
- d->collate = value.toBool();
- break;
- case PPK_ColorMode:
- d->colorMode = QPrinter::ColorMode(value.toInt());
- break;
- case PPK_Creator:
- d->creator = value.toString();
- break;
- case PPK_DocumentName:
- d->title = value.toString();
- break;
- case PPK_FullPage:
- d->fullPage = value.toBool();
- break;
- case PPK_CopyCount: // fallthrough
- case PPK_NumberOfCopies:
- d->copies = value.toInt();
- break;
- case PPK_Orientation:
- d->orientation = QPrinter::Orientation(value.toInt());
- break;
- case PPK_OutputFileName:
- d->outputFileName = value.toString();
- break;
- case PPK_PageOrder:
- d->pageOrder = QPrinter::PageOrder(value.toInt());
- break;
- case PPK_PaperSize:
- d->paperSize = QPrinter::PaperSize(value.toInt());
- break;
- case PPK_PaperSource:
- d->paperSource = QPrinter::PaperSource(value.toInt());
- break;
- case PPK_PrinterName:
- d->printerName = value.toString();
- break;
- case PPK_PrinterProgram:
- d->printProgram = value.toString();
- break;
- case PPK_Resolution:
- d->resolution = value.toInt();
- break;
- case PPK_SelectionOption:
- d->selectionOption = value.toString();
- break;
- case PPK_FontEmbedding:
- d->embedFonts = value.toBool();
- break;
- case PPK_Duplex:
- d->duplex = static_cast<QPrinter::DuplexMode> (value.toInt());
- break;
- case PPK_CupsPageRect:
- d->cupsPageRect = value.toRect();
- break;
- case PPK_CupsPaperRect:
- d->cupsPaperRect = value.toRect();
- break;
- case PPK_CupsOptions:
- d->cupsOptions = value.toStringList();
- break;
- case PPK_CupsStringPageSize:
- d->cupsStringPageSize = value.toString();
- break;
- case PPK_CustomPaperSize:
- d->paperSize = QPrinter::Custom;
- d->customPaperSize = value.toSizeF();
- break;
- case PPK_PageMargins:
- {
- QList<QVariant> margins(value.toList());
- Q_ASSERT(margins.size() == 4);
- d->leftMargin = margins.at(0).toReal();
- d->topMargin = margins.at(1).toReal();
- d->rightMargin = margins.at(2).toReal();
- d->bottomMargin = margins.at(3).toReal();
- d->hasCustomPageMargins = true;
- break;
- }
- default:
- break;
- }
-}
-
-QVariant QPdfBaseEngine::property(PrintEnginePropertyKey key) const
-{
- Q_D(const QPdfBaseEngine);
-
- QVariant ret;
- switch (int(key)) {
- case PPK_CollateCopies:
- ret = d->collate;
- break;
- case PPK_ColorMode:
- ret = d->colorMode;
- break;
- case PPK_Creator:
- ret = d->creator;
- break;
- case PPK_DocumentName:
- ret = d->title;
- break;
- case PPK_FullPage:
- ret = d->fullPage;
- break;
- case PPK_CopyCount:
- ret = d->copies;
- break;
- case PPK_SupportsMultipleCopies:
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
- if (QCUPSSupport::isAvailable())
- ret = true;
- else
-#endif
- ret = false;
- break;
- case PPK_NumberOfCopies:
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
- if (QCUPSSupport::isAvailable())
- ret = 1;
- else
-#endif
- ret = d->copies;
- break;
- case PPK_Orientation:
- ret = d->orientation;
- break;
- case PPK_OutputFileName:
- ret = d->outputFileName;
- break;
- case PPK_PageOrder:
- ret = d->pageOrder;
- break;
- case PPK_PaperSize:
- ret = d->paperSize;
- break;
- case PPK_PaperSource:
- ret = d->paperSource;
- break;
- case PPK_PrinterName:
- ret = d->printerName;
- break;
- case PPK_PrinterProgram:
- ret = d->printProgram;
- break;
- case PPK_Resolution:
- ret = d->resolution;
- break;
- case PPK_SupportedResolutions:
- ret = QList<QVariant>() << 72;
- break;
- case PPK_PaperRect:
- ret = d->paperRect();
- break;
- case PPK_PageRect:
- ret = d->pageRect();
- break;
- case PPK_SelectionOption:
- ret = d->selectionOption;
- break;
- case PPK_FontEmbedding:
- ret = d->embedFonts;
- break;
- case PPK_Duplex:
- ret = d->duplex;
- break;
- case PPK_CupsPageRect:
- ret = d->cupsPageRect;
- break;
- case PPK_CupsPaperRect:
- ret = d->cupsPaperRect;
- break;
- case PPK_CupsOptions:
- ret = d->cupsOptions;
- break;
- case PPK_CupsStringPageSize:
- ret = d->cupsStringPageSize;
- break;
- case PPK_CustomPaperSize:
- ret = d->customPaperSize;
- break;
- case PPK_PageMargins:
- {
- QList<QVariant> margins;
- if (d->hasCustomPageMargins) {
- margins << d->leftMargin << d->topMargin
- << d->rightMargin << d->bottomMargin;
- } else {
- const qreal defaultMargin = 10; // ~3.5 mm
- margins << defaultMargin << defaultMargin
- << defaultMargin << defaultMargin;
- }
- ret = margins;
- break;
- }
- default:
- break;
- }
- return ret;
-}
+#define Q_MM(n) int((n * 720 + 127) / 254)
-QPdfBaseEnginePrivate::QPdfBaseEnginePrivate(QPrinter::PrinterMode m)
+QPdfEnginePrivate::QPdfEnginePrivate()
: clipEnabled(false), allClipped(false), hasPen(true), hasBrush(false), simplePen(false),
- useAlphaEngine(false),
- outDevice(0), fd(-1),
- duplex(QPrinter::DuplexNone), collate(false), fullPage(false), embedFonts(true), copies(1),
- pageOrder(QPrinter::FirstPageFirst), orientation(QPrinter::Portrait),
- paperSize(QPrinter::A4), colorMode(QPrinter::Color), paperSource(QPrinter::Auto),
- hasCustomPageMargins(false),
- leftMargin(0), topMargin(0), rightMargin(0), bottomMargin(0)
+ outDevice(0), ownsDevice(false),
+ fullPage(false), embedFonts(true),
+ landscape(false),
+ grayscale(false),
+ paperSize(Q_MM(210), Q_MM(297)), // A4
+ leftMargin(10), topMargin(10), rightMargin(10), bottomMargin(10) // ~3.5 mm
{
- resolution = 72;
- if (m == QPrinter::HighResolution)
- resolution = 1200;
- else if (m == QPrinter::ScreenResolution)
- resolution = qt_defaultDpi();
-
+ resolution = 1200;
postscript = false;
currentObject = 1;
currentPage = 0;
stroker.stream = 0;
+
+ streampos = 0;
+
+ stream = new QDataStream;
}
-bool QPdfBaseEngine::begin(QPaintDevice *pdev)
+bool QPdfEngine::begin(QPaintDevice *pdev)
{
- Q_D(QPdfBaseEngine);
+ Q_D(QPdfEngine);
d->pdev = pdev;
+ if (!d->outDevice) {
+ if (!d->outputFileName.isEmpty()) {
+ QFile *file = new QFile(d->outputFileName);
+ if (!file->open(QFile::WriteOnly|QFile::Truncate)) {
+ delete file;
+ return false;
+ }
+ d->outDevice = file;
+ } else {
+ return false;
+ }
+ d->ownsDevice = true;
+ }
+
d->postscript = false;
d->currentObject = 1;
@@ -1626,288 +1507,979 @@ bool QPdfBaseEngine::begin(QPaintDevice *pdev)
d->stroker.stream = d->currentPage;
d->opacity = 1.0;
- return d->openPrintDevice();
+ d->stream->setDevice(d->outDevice);
+
+ d->streampos = 0;
+ d->hasPen = true;
+ d->hasBrush = false;
+ d->clipEnabled = false;
+ d->allClipped = false;
+
+ d->xrefPositions.clear();
+ d->pageRoot = 0;
+ d->catalog = 0;
+ d->info = 0;
+ d->graphicsState = 0;
+ d->patternColorSpace = 0;
+
+ d->pages.clear();
+ d->imageCache.clear();
+
+ setActive(true);
+ d->writeHeader();
+ newPage();
+
+ return true;
}
-bool QPdfBaseEngine::end()
+bool QPdfEngine::end()
{
- Q_D(QPdfBaseEngine);
+ Q_D(QPdfEngine);
+ d->writeTail();
+
+ d->stream->unsetDevice();
+
qDeleteAll(d->fonts);
d->fonts.clear();
delete d->currentPage;
d->currentPage = 0;
- d->closePrintDevice();
+ if (d->outDevice && d->ownsDevice) {
+ d->outDevice->close();
+ delete d->outDevice;
+ d->outDevice = 0;
+ }
+
+ setActive(false);
return true;
}
-#ifndef QT_NO_LPR
-static void closeAllOpenFds()
+QPdfEnginePrivate::~QPdfEnginePrivate()
{
- // hack time... getting the maximum number of open
- // files, if possible. if not we assume it's the
- // larger of 256 and the fd we got
- int i;
-#if defined(_SC_OPEN_MAX)
- i = (int)sysconf(_SC_OPEN_MAX);
-#elif defined(_POSIX_OPEN_MAX)
- i = (int)_POSIX_OPEN_MAX;
-#elif defined(OPEN_MAX)
- i = (int)OPEN_MAX;
-#else
- i = 256;
-#endif
- // leave stdin/out/err untouched
- while(--i > 2)
- QT_CLOSE(i);
+ qDeleteAll(fonts);
+ delete currentPage;
+ delete stream;
}
-#endif
-bool QPdfBaseEnginePrivate::openPrintDevice()
+QRect QPdfEnginePrivate::paperRect() const
{
- if(outDevice)
- return false;
+ int w = qRound(paperSize.width()*resolution/72.);
+ int h = qRound(paperSize.height()*resolution/72.);
- if (!outputFileName.isEmpty()) {
- QFile *file = new QFile(outputFileName);
- if (! file->open(QFile::WriteOnly|QFile::Truncate)) {
- delete file;
- return false;
- }
- outDevice = file;
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
- } else if (QCUPSSupport::isAvailable()) {
- QCUPSSupport cups;
- QPair<int, QString> ret = cups.tempFd();
- if (ret.first < 0) {
- qWarning("QPdfPrinter: Could not open temporary file to print");
- return false;
- }
- cupsTempFile = ret.second;
- outDevice = new QFile();
- static_cast<QFile *>(outDevice)->open(ret.first, QIODevice::WriteOnly);
-#endif
-#ifndef QT_NO_LPR
- } else {
- QString pr;
- if (!printerName.isEmpty())
- pr = printerName;
- int fds[2];
- if (qt_safe_pipe(fds) != 0) {
- qWarning("QPdfPrinter: Could not open pipe to print");
- return false;
- }
+ if (!landscape)
+ return QRect(0, 0, w, h);
+ else
+ return QRect(0, 0, h, w);
+}
- pid_t pid = fork();
- if (pid == 0) { // child process
- // if possible, exit quickly, so the actual lp/lpr
- // becomes a child of init, and ::waitpid() is
- // guaranteed not to wait.
- if (fork() > 0) {
- closeAllOpenFds();
-
- // try to replace this process with "true" - this prevents
- // global destructors from being called (that could possibly
- // do wrong things to the parent process)
- (void)execlp("true", "true", (char *)0);
- (void)execl("/bin/true", "true", (char *)0);
- (void)execl("/usr/bin/true", "true", (char *)0);
- ::_exit(0);
- }
- qt_safe_dup2(fds[0], 0, 0);
-
- closeAllOpenFds();
-
- if (!printProgram.isEmpty()) {
- if (!selectionOption.isEmpty())
- pr.prepend(selectionOption);
- else
- pr.prepend(QLatin1String("-P"));
- (void)execlp(printProgram.toLocal8Bit().data(), printProgram.toLocal8Bit().data(),
- pr.toLocal8Bit().data(), (char *)0);
- } else {
- // if no print program has been specified, be smart
- // about the option string too.
- QList<QByteArray> lprhack;
- QList<QByteArray> lphack;
- QByteArray media;
- if (!pr.isEmpty() || !selectionOption.isEmpty()) {
- if (!selectionOption.isEmpty()) {
- QStringList list = selectionOption.split(QLatin1Char(' '));
- for (int i = 0; i < list.size(); ++i)
- lprhack.append(list.at(i).toLocal8Bit());
- lphack = lprhack;
- } else {
- lprhack.append("-P");
- lphack.append("-d");
- }
- lprhack.append(pr.toLocal8Bit());
- lphack.append(pr.toLocal8Bit());
- }
- lphack.append("-s");
-
- char ** lpargs = new char *[lphack.size()+6];
- char lp[] = "lp";
- lpargs[0] = lp;
- int i;
- for (i = 0; i < lphack.size(); ++i)
- lpargs[i+1] = (char *)lphack.at(i).constData();
-#ifndef Q_OS_OSF
- if (QPdf::paperSizeToString(paperSize)) {
- char dash_o[] = "-o";
- lpargs[++i] = dash_o;
- lpargs[++i] = const_cast<char *>(QPdf::paperSizeToString(paperSize));
- lpargs[++i] = dash_o;
- media = "media=";
- media += QPdf::paperSizeToString(paperSize);
- lpargs[++i] = media.data();
- }
+QRect QPdfEnginePrivate::pageRect() const
+{
+ QRect r = paperRect();
+
+ if(!fullPage)
+ r.adjust(qRound(leftMargin*(resolution/72.)),
+ qRound(topMargin*(resolution/72.)),
+ -qRound(rightMargin*(resolution/72.)),
+ -qRound(bottomMargin*(resolution/72.)));
+
+ return r;
+}
+
+
+void QPdfEnginePrivate::writeHeader()
+{
+ addXrefEntry(0,false);
+
+ xprintf("%%PDF-1.4\n");
+
+ writeInfo();
+
+ catalog = addXrefEntry(-1);
+ pageRoot = requestObject();
+ xprintf("<<\n"
+ "/Type /Catalog\n"
+ "/Pages %d 0 R\n"
+ ">>\n"
+ "endobj\n", pageRoot);
+
+ // graphics state
+ graphicsState = addXrefEntry(-1);
+ xprintf("<<\n"
+ "/Type /ExtGState\n"
+ "/SA true\n"
+ "/SM 0.02\n"
+ "/ca 1.0\n"
+ "/CA 1.0\n"
+ "/AIS false\n"
+ "/SMask /None"
+ ">>\n"
+ "endobj\n");
+
+ // color space for pattern
+ patternColorSpace = addXrefEntry(-1);
+ xprintf("[/Pattern /DeviceRGB]\n"
+ "endobj\n");
+}
+
+void QPdfEnginePrivate::writeInfo()
+{
+ info = addXrefEntry(-1);
+ xprintf("<<\n/Title ");
+ printString(title);
+ xprintf("\n/Creator ");
+ printString(creator);
+ xprintf("\n/Producer ");
+ printString(QString::fromLatin1("Qt " QT_VERSION_STR " (C) 2011 Nokia Corporation and/or its subsidiary(-ies)"));
+ QDateTime now = QDateTime::currentDateTime().toUTC();
+ QTime t = now.time();
+ QDate d = now.date();
+ xprintf("\n/CreationDate (D:%d%02d%02d%02d%02d%02d)\n",
+ d.year(),
+ d.month(),
+ d.day(),
+ t.hour(),
+ t.minute(),
+ t.second());
+ xprintf(">>\n"
+ "endobj\n");
+}
+
+void QPdfEnginePrivate::writePageRoot()
+{
+ addXrefEntry(pageRoot);
+
+ xprintf("<<\n"
+ "/Type /Pages\n"
+ "/Kids \n"
+ "[\n");
+ int size = pages.size();
+ for (int i = 0; i < size; ++i)
+ xprintf("%d 0 R\n", pages[i]);
+ xprintf("]\n");
+
+ //xprintf("/Group <</S /Transparency /I true /K false>>\n");
+ xprintf("/Count %d\n", pages.size());
+
+ xprintf("/ProcSet [/PDF /Text /ImageB /ImageC]\n"
+ ">>\n"
+ "endobj\n");
+}
+
+
+void QPdfEnginePrivate::embedFont(QFontSubset *font)
+{
+ //qDebug() << "embedFont" << font->object_id;
+ int fontObject = font->object_id;
+ QByteArray fontData = font->toTruetype();
+#ifdef FONT_DUMP
+ static int i = 0;
+ QString fileName("font%1.ttf");
+ fileName = fileName.arg(i++);
+ QFile ff(fileName);
+ ff.open(QFile::WriteOnly);
+ ff.write(fontData);
+ ff.close();
#endif
- lpargs[++i] = 0;
- char **lprargs = new char *[lprhack.size()+2];
- char lpr[] = "lpr";
- lprargs[0] = lpr;
- for (int i = 0; i < lprhack.size(); ++i)
- lprargs[i+1] = (char *)lprhack[i].constData();
- lprargs[lprhack.size() + 1] = 0;
- (void)execvp("lp", lpargs);
- (void)execvp("lpr", lprargs);
- (void)execv("/bin/lp", lpargs);
- (void)execv("/bin/lpr", lprargs);
- (void)execv("/usr/bin/lp", lpargs);
- (void)execv("/usr/bin/lpr", lprargs);
-
- delete []lpargs;
- delete []lprargs;
- }
- // if we couldn't exec anything, close the fd,
- // wait for a second so the parent process (the
- // child of the GUI process) has exited. then
- // exit.
- QT_CLOSE(0);
- (void)::sleep(1);
- ::_exit(0);
+
+ int fontDescriptor = requestObject();
+ int fontstream = requestObject();
+ int cidfont = requestObject();
+ int toUnicode = requestObject();
+
+ QFontEngine::Properties properties = font->fontEngine->properties();
+
+ {
+ qreal scale = 1000/properties.emSquare.toReal();
+ addXrefEntry(fontDescriptor);
+ QByteArray descriptor;
+ QPdf::ByteStream s(&descriptor);
+ s << "<< /Type /FontDescriptor\n"
+ "/FontName /Q";
+ int tag = fontDescriptor;
+ for (int i = 0; i < 5; ++i) {
+ s << (char)('A' + (tag % 26));
+ tag /= 26;
}
- // parent process
- QT_CLOSE(fds[0]);
- fd = fds[1];
- (void)qt_safe_waitpid(pid, 0, 0);
+ s << '+' << properties.postscriptName << "\n"
+ "/Flags " << 4 << "\n"
+ "/FontBBox ["
+ << properties.boundingBox.x()*scale
+ << -(properties.boundingBox.y() + properties.boundingBox.height())*scale
+ << (properties.boundingBox.x() + properties.boundingBox.width())*scale
+ << -properties.boundingBox.y()*scale << "]\n"
+ "/ItalicAngle " << properties.italicAngle.toReal() << "\n"
+ "/Ascent " << properties.ascent.toReal()*scale << "\n"
+ "/Descent " << -properties.descent.toReal()*scale << "\n"
+ "/CapHeight " << properties.capHeight.toReal()*scale << "\n"
+ "/StemV " << properties.lineWidth.toReal()*scale << "\n"
+ "/FontFile2 " << fontstream << "0 R\n"
+ ">> endobj\n";
+ write(descriptor);
+ }
+ {
+ addXrefEntry(fontstream);
+ QByteArray header;
+ QPdf::ByteStream s(&header);
+
+ int length_object = requestObject();
+ s << "<<\n"
+ "/Length1 " << fontData.size() << "\n"
+ "/Length " << length_object << "0 R\n";
+ if (do_compress)
+ s << "/Filter /FlateDecode\n";
+ s << ">>\n"
+ "stream\n";
+ write(header);
+ int len = writeCompressed(fontData);
+ write("endstream\n"
+ "endobj\n");
+ addXrefEntry(length_object);
+ xprintf("%d\n"
+ "endobj\n", len);
+ }
+ {
+ addXrefEntry(cidfont);
+ QByteArray cid;
+ QPdf::ByteStream s(&cid);
+ s << "<< /Type /Font\n"
+ "/Subtype /CIDFontType2\n"
+ "/BaseFont /" << properties.postscriptName << "\n"
+ "/CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >>\n"
+ "/FontDescriptor " << fontDescriptor << "0 R\n"
+ "/CIDToGIDMap /Identity\n"
+ << font->widthArray() <<
+ ">>\n"
+ "endobj\n";
+ write(cid);
+ }
+ {
+ addXrefEntry(toUnicode);
+ QByteArray touc = font->createToUnicodeMap();
+ xprintf("<< /Length %d >>\n"
+ "stream\n", touc.length());
+ write(touc);
+ write("endstream\n"
+ "endobj\n");
+ }
+ {
+ addXrefEntry(fontObject);
+ QByteArray font;
+ QPdf::ByteStream s(&font);
+ s << "<< /Type /Font\n"
+ "/Subtype /Type0\n"
+ "/BaseFont /" << properties.postscriptName << "\n"
+ "/Encoding /Identity-H\n"
+ "/DescendantFonts [" << cidfont << "0 R]\n"
+ "/ToUnicode " << toUnicode << "0 R"
+ ">>\n"
+ "endobj\n";
+ write(font);
+ }
+}
- if (fd < 0)
- return false;
- outDevice = new QFile();
- static_cast<QFile *>(outDevice)->open(fd, QIODevice::WriteOnly);
-#endif
+void QPdfEnginePrivate::writeFonts()
+{
+ for (QHash<QFontEngine::FaceId, QFontSubset *>::iterator it = fonts.begin(); it != fonts.end(); ++it) {
+ embedFont(*it);
+ delete *it;
}
+ fonts.clear();
+}
- return true;
+void QPdfEnginePrivate::writePage()
+{
+ if (pages.empty())
+ return;
+
+ *currentPage << "Q Q\n";
+
+ uint pageStream = requestObject();
+ uint pageStreamLength = requestObject();
+ uint resources = requestObject();
+ uint annots = requestObject();
+
+ addXrefEntry(pages.last());
+ xprintf("<<\n"
+ "/Type /Page\n"
+ "/Parent %d 0 R\n"
+ "/Contents %d 0 R\n"
+ "/Resources %d 0 R\n"
+ "/Annots %d 0 R\n"
+ "/MediaBox [0 0 %d %d]\n"
+ ">>\n"
+ "endobj\n",
+ pageRoot, pageStream, resources, annots,
+ // make sure we use the pagesize from when we started the page, since the user may have changed it
+ currentPage->pageSize.width(), currentPage->pageSize.height());
+
+ addXrefEntry(resources);
+ xprintf("<<\n"
+ "/ColorSpace <<\n"
+ "/PCSp %d 0 R\n"
+ "/CSp /DeviceRGB\n"
+ "/CSpg /DeviceGray\n"
+ ">>\n"
+ "/ExtGState <<\n"
+ "/GSa %d 0 R\n",
+ patternColorSpace, graphicsState);
+
+ for (int i = 0; i < currentPage->graphicStates.size(); ++i)
+ xprintf("/GState%d %d 0 R\n", currentPage->graphicStates.at(i), currentPage->graphicStates.at(i));
+ xprintf(">>\n");
+
+ xprintf("/Pattern <<\n");
+ for (int i = 0; i < currentPage->patterns.size(); ++i)
+ xprintf("/Pat%d %d 0 R\n", currentPage->patterns.at(i), currentPage->patterns.at(i));
+ xprintf(">>\n");
+
+ xprintf("/Font <<\n");
+ for (int i = 0; i < currentPage->fonts.size();++i)
+ xprintf("/F%d %d 0 R\n", currentPage->fonts[i], currentPage->fonts[i]);
+ xprintf(">>\n");
+
+ xprintf("/XObject <<\n");
+ for (int i = 0; i<currentPage->images.size(); ++i) {
+ xprintf("/Im%d %d 0 R\n", currentPage->images.at(i), currentPage->images.at(i));
+ }
+ xprintf(">>\n");
+
+ xprintf(">>\n"
+ "endobj\n");
+
+ addXrefEntry(annots);
+ xprintf("[ ");
+ for (int i = 0; i<currentPage->annotations.size(); ++i) {
+ xprintf("%d 0 R ", currentPage->annotations.at(i));
+ }
+ xprintf("]\nendobj\n");
+
+ addXrefEntry(pageStream);
+ xprintf("<<\n"
+ "/Length %d 0 R\n", pageStreamLength); // object number for stream length object
+ if (do_compress)
+ xprintf("/Filter /FlateDecode\n");
+
+ xprintf(">>\n");
+ xprintf("stream\n");
+ QIODevice *content = currentPage->stream();
+ int len = writeCompressed(content);
+ xprintf("endstream\n"
+ "endobj\n");
+
+ addXrefEntry(pageStreamLength);
+ xprintf("%d\nendobj\n",len);
+}
+
+void QPdfEnginePrivate::writeTail()
+{
+ writePage();
+ writeFonts();
+ writePageRoot();
+ addXrefEntry(xrefPositions.size(),false);
+ xprintf("xref\n"
+ "0 %d\n"
+ "%010d 65535 f \n", xrefPositions.size()-1, xrefPositions[0]);
+
+ for (int i = 1; i < xrefPositions.size()-1; ++i)
+ xprintf("%010d 00000 n \n", xrefPositions[i]);
+
+ xprintf("trailer\n"
+ "<<\n"
+ "/Size %d\n"
+ "/Info %d 0 R\n"
+ "/Root %d 0 R\n"
+ ">>\n"
+ "startxref\n%d\n"
+ "%%%%EOF\n",
+ xrefPositions.size()-1, info, catalog, xrefPositions.last());
}
-void QPdfBaseEnginePrivate::closePrintDevice()
+int QPdfEnginePrivate::addXrefEntry(int object, bool printostr)
+{
+ if (object < 0)
+ object = requestObject();
+
+ if (object>=xrefPositions.size())
+ xrefPositions.resize(object+1);
+
+ xrefPositions[object] = streampos;
+ if (printostr)
+ xprintf("%d 0 obj\n",object);
+
+ return object;
+}
+
+void QPdfEnginePrivate::printString(const QString &string) {
+ // The 'text string' type in PDF is encoded either as PDFDocEncoding, or
+ // Unicode UTF-16 with a Unicode byte order mark as the first character
+ // (0xfeff), with the high-order byte first.
+ QByteArray array("(\xfe\xff");
+ const ushort *utf16 = string.utf16();
+
+ for (int i=0; i < string.size(); ++i) {
+ char part[2] = {char((*(utf16 + i)) >> 8), char((*(utf16 + i)) & 0xff)};
+ for(int j=0; j < 2; ++j) {
+ if (part[j] == '(' || part[j] == ')' || part[j] == '\\')
+ array.append('\\');
+ array.append(part[j]);
+ }
+ }
+ array.append(")");
+ write(array);
+}
+
+
+// For strings up to 10000 bytes only !
+void QPdfEnginePrivate::xprintf(const char* fmt, ...)
{
- if (!outDevice)
+ if (!stream)
return;
- outDevice->close();
- if (fd >= 0)
-#if defined(Q_OS_WIN) && defined(_MSC_VER) && _MSC_VER >= 1400
- ::_close(fd);
-#else
- ::close(fd);
-#endif
- fd = -1;
- delete outDevice;
- outDevice = 0;
-
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
- if (!cupsTempFile.isEmpty()) {
- QString tempFile = cupsTempFile;
- cupsTempFile.clear();
- QCUPSSupport cups;
-
- // Set up print options.
- QByteArray prnName;
- QList<QPair<QByteArray, QByteArray> > options;
- QVector<cups_option_t> cupsOptStruct;
-
- if (!printerName.isEmpty()) {
- prnName = printerName.toLocal8Bit();
- } else {
- QPrinterInfo def = QPrinterInfo::defaultPrinter();
- if (def.isNull()) {
- qWarning("Could not determine printer to print to");
- QFile::remove(tempFile);
- return;
+
+ const int msize = 10000;
+ char buf[msize];
+
+ va_list args;
+ va_start(args, fmt);
+ int bufsize = qvsnprintf(buf, msize, fmt, args);
+
+ Q_ASSERT(bufsize<msize);
+
+ va_end(args);
+
+ stream->writeRawData(buf, bufsize);
+ streampos += bufsize;
+}
+
+int QPdfEnginePrivate::writeCompressed(QIODevice *dev)
+{
+#ifndef QT_NO_COMPRESS
+ if (do_compress) {
+ int size = QPdfPage::chunkSize();
+ int sum = 0;
+ ::z_stream zStruct;
+ zStruct.zalloc = Z_NULL;
+ zStruct.zfree = Z_NULL;
+ zStruct.opaque = Z_NULL;
+ if (::deflateInit(&zStruct, Z_DEFAULT_COMPRESSION) != Z_OK) {
+ qWarning("QPdfStream::writeCompressed: Error in deflateInit()");
+ return sum;
+ }
+ zStruct.avail_in = 0;
+ QByteArray in, out;
+ out.resize(size);
+ while (!dev->atEnd() || zStruct.avail_in != 0) {
+ if (zStruct.avail_in == 0) {
+ in = dev->read(size);
+ zStruct.avail_in = in.size();
+ zStruct.next_in = reinterpret_cast<unsigned char*>(in.data());
+ if (in.size() <= 0) {
+ qWarning("QPdfStream::writeCompressed: Error in read()");
+ ::deflateEnd(&zStruct);
+ return sum;
+ }
}
- prnName = def.printerName().toLocal8Bit();
+ zStruct.next_out = reinterpret_cast<unsigned char*>(out.data());
+ zStruct.avail_out = out.size();
+ if (::deflate(&zStruct, 0) != Z_OK) {
+ qWarning("QPdfStream::writeCompressed: Error in deflate()");
+ ::deflateEnd(&zStruct);
+ return sum;
+ }
+ int written = out.size() - zStruct.avail_out;
+ stream->writeRawData(out.constData(), written);
+ streampos += written;
+ sum += written;
}
+ int ret;
+ do {
+ zStruct.next_out = reinterpret_cast<unsigned char*>(out.data());
+ zStruct.avail_out = out.size();
+ ret = ::deflate(&zStruct, Z_FINISH);
+ if (ret != Z_OK && ret != Z_STREAM_END) {
+ qWarning("QPdfStream::writeCompressed: Error in deflate()");
+ ::deflateEnd(&zStruct);
+ return sum;
+ }
+ int written = out.size() - zStruct.avail_out;
+ stream->writeRawData(out.constData(), written);
+ streampos += written;
+ sum += written;
+ } while (ret == Z_OK);
- if (!cupsStringPageSize.isEmpty()) {
- options.append(QPair<QByteArray, QByteArray>("media", cupsStringPageSize.toLocal8Bit()));
- }
+ ::deflateEnd(&zStruct);
- if (copies > 1) {
- options.append(QPair<QByteArray, QByteArray>("copies", QString::number(copies).toLocal8Bit()));
+ return sum;
+ } else
+#endif
+ {
+ QByteArray arr;
+ int sum = 0;
+ while (!dev->atEnd()) {
+ arr = dev->read(QPdfPage::chunkSize());
+ stream->writeRawData(arr.constData(), arr.size());
+ streampos += arr.size();
+ sum += arr.size();
}
+ return sum;
+ }
+}
- if (collate) {
- options.append(QPair<QByteArray, QByteArray>("Collate", "True"));
+int QPdfEnginePrivate::writeCompressed(const char *src, int len)
+{
+#ifndef QT_NO_COMPRESS
+ if(do_compress) {
+ uLongf destLen = len + len/100 + 13; // zlib requirement
+ Bytef* dest = new Bytef[destLen];
+ if (Z_OK == ::compress(dest, &destLen, (const Bytef*) src, (uLongf)len)) {
+ stream->writeRawData((const char*)dest, destLen);
+ } else {
+ qWarning("QPdfStream::writeCompressed: Error in compress()");
+ destLen = 0;
}
+ delete [] dest;
+ len = destLen;
+ } else
+#endif
+ {
+ stream->writeRawData(src,len);
+ }
+ streampos += len;
+ return len;
+}
- if (duplex != QPrinter::DuplexNone) {
- switch(duplex) {
- case QPrinter::DuplexNone: break;
- case QPrinter::DuplexAuto:
- if (orientation == QPrinter::Portrait)
- options.append(QPair<QByteArray, QByteArray>("sides", "two-sided-long-edge"));
- else
- options.append(QPair<QByteArray, QByteArray>("sides", "two-sided-short-edge"));
- break;
- case QPrinter::DuplexLongSide:
- options.append(QPair<QByteArray, QByteArray>("sides", "two-sided-long-edge"));
- break;
- case QPrinter::DuplexShortSide:
- options.append(QPair<QByteArray, QByteArray>("sides", "two-sided-short-edge"));
+int QPdfEnginePrivate::writeImage(const QByteArray &data, int width, int height, int depth,
+ int maskObject, int softMaskObject, bool dct)
+{
+ int image = addXrefEntry(-1);
+ xprintf("<<\n"
+ "/Type /XObject\n"
+ "/Subtype /Image\n"
+ "/Width %d\n"
+ "/Height %d\n", width, height);
+
+ if (depth == 1) {
+ xprintf("/ImageMask true\n"
+ "/Decode [1 0]\n");
+ } else {
+ xprintf("/BitsPerComponent 8\n"
+ "/ColorSpace %s\n", (depth == 32) ? "/DeviceRGB" : "/DeviceGray");
+ }
+ if (maskObject > 0)
+ xprintf("/Mask %d 0 R\n", maskObject);
+ if (softMaskObject > 0)
+ xprintf("/SMask %d 0 R\n", softMaskObject);
+
+ int lenobj = requestObject();
+ xprintf("/Length %d 0 R\n", lenobj);
+ if (interpolateImages)
+ xprintf("/Interpolate true\n");
+ int len = 0;
+ if (dct) {
+ //qDebug() << "DCT";
+ xprintf("/Filter /DCTDecode\n>>\nstream\n");
+ write(data);
+ len = data.length();
+ } else {
+ if (do_compress)
+ xprintf("/Filter /FlateDecode\n>>\nstream\n");
+ else
+ xprintf(">>\nstream\n");
+ len = writeCompressed(data);
+ }
+ xprintf("endstream\n"
+ "endobj\n");
+ addXrefEntry(lenobj);
+ xprintf("%d\n"
+ "endobj\n", len);
+ return image;
+}
+
+#ifdef USE_NATIVE_GRADIENTS
+int QPdfEnginePrivate::gradientBrush(const QBrush &b, const QMatrix &matrix, int *gStateObject)
+{
+ const QGradient *gradient = b.gradient();
+ if (!gradient)
+ return 0;
+
+ QTransform inv = matrix.inverted();
+ QPointF page_rect[4] = { inv.map(QPointF(0, 0)),
+ inv.map(QPointF(width_, 0)),
+ inv.map(QPointF(0, height_)),
+ inv.map(QPointF(width_, height_)) };
+
+ bool opaque = b.isOpaque();
+
+ QByteArray shader;
+ QByteArray alphaShader;
+ if (gradient->type() == QGradient::LinearGradient) {
+ const QLinearGradient *lg = static_cast<const QLinearGradient *>(gradient);
+ shader = QPdf::generateLinearGradientShader(lg, page_rect);
+ if (!opaque)
+ alphaShader = QPdf::generateLinearGradientShader(lg, page_rect, true);
+ } else {
+ // #############
+ return 0;
+ }
+ int shaderObject = addXrefEntry(-1);
+ write(shader);
+
+ QByteArray str;
+ QPdf::ByteStream s(&str);
+ s << "<<\n"
+ "/Type /Pattern\n"
+ "/PatternType 2\n"
+ "/Shading " << shaderObject << "0 R\n"
+ "/Matrix ["
+ << matrix.m11()
+ << matrix.m12()
+ << matrix.m21()
+ << matrix.m22()
+ << matrix.dx()
+ << matrix.dy() << "]\n";
+ s << ">>\n"
+ "endobj\n";
+
+ int patternObj = addXrefEntry(-1);
+ write(str);
+ currentPage->patterns.append(patternObj);
+
+ if (!opaque) {
+ bool ca = true;
+ QGradientStops stops = gradient->stops();
+ int a = stops.at(0).second.alpha();
+ for (int i = 1; i < stops.size(); ++i) {
+ if (stops.at(i).second.alpha() != a) {
+ ca = false;
break;
}
}
-
- if (QCUPSSupport::cupsVersion() >= 10300 && orientation == QPrinter::Landscape) {
- options.append(QPair<QByteArray, QByteArray>("landscape", ""));
+ if (ca) {
+ *gStateObject = addConstantAlphaObject(stops.at(0).second.alpha());
+ } else {
+ int alphaShaderObject = addXrefEntry(-1);
+ write(alphaShader);
+
+ QByteArray content;
+ QPdf::ByteStream c(&content);
+ c << "/Shader" << alphaShaderObject << "sh\n";
+
+ QByteArray form;
+ QPdf::ByteStream f(&form);
+ f << "<<\n"
+ "/Type /XObject\n"
+ "/Subtype /Form\n"
+ "/BBox [0 0 " << width_ << height_ << "]\n"
+ "/Group <</S /Transparency >>\n"
+ "/Resources <<\n"
+ "/Shading << /Shader" << alphaShaderObject << alphaShaderObject << "0 R >>\n"
+ ">>\n";
+
+ f << "/Length " << content.length() << "\n"
+ ">>\n"
+ "stream\n"
+ << content
+ << "endstream\n"
+ "endobj\n";
+
+ int softMaskFormObject = addXrefEntry(-1);
+ write(form);
+ *gStateObject = addXrefEntry(-1);
+ xprintf("<< /SMask << /S /Alpha /G %d 0 R >> >>\n"
+ "endobj\n", softMaskFormObject);
+ currentPage->graphicStates.append(*gStateObject);
}
+ }
- QStringList::const_iterator it = cupsOptions.constBegin();
- while (it != cupsOptions.constEnd()) {
- options.append(QPair<QByteArray, QByteArray>((*it).toLocal8Bit(), (*(it+1)).toLocal8Bit()));
- it += 2;
- }
+ return patternObj;
+}
+#endif
- for (int c = 0; c < options.size(); ++c) {
- cups_option_t opt;
- opt.name = options[c].first.data();
- opt.value = options[c].second.data();
- cupsOptStruct.append(opt);
- }
+int QPdfEnginePrivate::addConstantAlphaObject(int brushAlpha, int penAlpha)
+{
+ if (brushAlpha == 255 && penAlpha == 255)
+ return 0;
+ int object = alphaCache.value(QPair<uint, uint>(brushAlpha, penAlpha), 0);
+ if (!object) {
+ object = addXrefEntry(-1);
+ QByteArray alphaDef;
+ QPdf::ByteStream s(&alphaDef);
+ s << "<<\n/ca " << (brushAlpha/qreal(255.)) << '\n';
+ s << "/CA " << (penAlpha/qreal(255.)) << "\n>>";
+ xprintf("%s\nendobj\n", alphaDef.constData());
+ alphaCache.insert(QPair<uint, uint>(brushAlpha, penAlpha), object);
+ }
+ if (currentPage->graphicStates.indexOf(object) < 0)
+ currentPage->graphicStates.append(object);
+
+ return object;
+}
+
+int QPdfEnginePrivate::addBrushPattern(const QTransform &m, bool *specifyColor, int *gStateObject)
+{
+ int paintType = 2; // Uncolored tiling
+ int w = 8;
+ int h = 8;
- // Print the file.
- cups_option_t* optPtr = cupsOptStruct.size() ? &cupsOptStruct.first() : 0;
- cups.printFile(prnName.constData(), tempFile.toLocal8Bit().constData(),
- title.toLocal8Bit().constData(), cupsOptStruct.size(), optPtr);
+ *specifyColor = true;
+ *gStateObject = 0;
- QFile::remove(tempFile);
- }
+ QTransform matrix = m;
+ matrix.translate(brushOrigin.x(), brushOrigin.y());
+ matrix = matrix * pageMatrix();
+ //qDebug() << brushOrigin << matrix;
+
+ Qt::BrushStyle style = brush.style();
+ if (style == Qt::LinearGradientPattern) {// && style <= Qt::ConicalGradientPattern) {
+#ifdef USE_NATIVE_GRADIENTS
+ *specifyColor = false;
+ return gradientBrush(b, matrix, gStateObject);
+#else
+ return 0;
#endif
+ }
+
+ if ((!brush.isOpaque() && brush.style() < Qt::LinearGradientPattern) || opacity != 1.0)
+ *gStateObject = addConstantAlphaObject(qRound(brush.color().alpha() * opacity),
+ qRound(pen.color().alpha() * opacity));
+
+ int imageObject = -1;
+ QByteArray pattern = QPdf::patternForBrush(brush);
+ if (pattern.isEmpty()) {
+ if (brush.style() != Qt::TexturePattern)
+ return 0;
+ QImage image = brush.texture().toImage();
+ bool bitmap = true;
+ imageObject = addImage(image, &bitmap, brush.texture().cacheKey());
+ if (imageObject != -1) {
+ QImage::Format f = image.format();
+ if (f != QImage::Format_MonoLSB && f != QImage::Format_Mono) {
+ paintType = 1; // Colored tiling
+ *specifyColor = false;
+ }
+ w = image.width();
+ h = image.height();
+ QTransform m(w, 0, 0, -h, 0, h);
+ QPdf::ByteStream s(&pattern);
+ s << QPdf::generateMatrix(m);
+ s << "/Im" << imageObject << " Do\n";
+ }
+ }
+
+ QByteArray str;
+ QPdf::ByteStream s(&str);
+ s << "<<\n"
+ "/Type /Pattern\n"
+ "/PatternType 1\n"
+ "/PaintType " << paintType << "\n"
+ "/TilingType 1\n"
+ "/BBox [0 0 " << w << h << "]\n"
+ "/XStep " << w << "\n"
+ "/YStep " << h << "\n"
+ "/Matrix ["
+ << matrix.m11()
+ << matrix.m12()
+ << matrix.m21()
+ << matrix.m22()
+ << matrix.dx()
+ << matrix.dy() << "]\n"
+ "/Resources \n<< "; // open resource tree
+ if (imageObject > 0) {
+ s << "/XObject << /Im" << imageObject << ' ' << imageObject << "0 R >> ";
+ }
+ s << ">>\n"
+ "/Length " << pattern.length() << "\n"
+ ">>\n"
+ "stream\n"
+ << pattern
+ << "endstream\n"
+ "endobj\n";
+
+ int patternObj = addXrefEntry(-1);
+ write(str);
+ currentPage->patterns.append(patternObj);
+ return patternObj;
}
-QPdfBaseEnginePrivate::~QPdfBaseEnginePrivate()
+/*!
+ * Adds an image to the pdf and return the pdf-object id. Returns -1 if adding the image failed.
+ */
+int QPdfEnginePrivate::addImage(const QImage &img, bool *bitmap, qint64 serial_no)
{
- qDeleteAll(fonts);
- delete currentPage;
+ if (img.isNull())
+ return -1;
+
+ int object = imageCache.value(serial_no);
+ if(object)
+ return object;
+
+ QImage image = img;
+ QImage::Format format = image.format();
+ if (image.depth() == 1 && *bitmap && img.colorTable().size() == 2
+ && img.colorTable().at(0) == QColor(Qt::black).rgba()
+ && img.colorTable().at(1) == QColor(Qt::white).rgba())
+ {
+ if (format == QImage::Format_MonoLSB)
+ image = image.convertToFormat(QImage::Format_Mono);
+ format = QImage::Format_Mono;
+ } else {
+ *bitmap = false;
+ if (format != QImage::Format_RGB32 && format != QImage::Format_ARGB32) {
+ image = image.convertToFormat(QImage::Format_ARGB32);
+ format = QImage::Format_ARGB32;
+ }
+ }
+
+ int w = image.width();
+ int h = image.height();
+ int d = image.depth();
+
+ if (format == QImage::Format_Mono) {
+ int bytesPerLine = (w + 7) >> 3;
+ QByteArray data;
+ data.resize(bytesPerLine * h);
+ char *rawdata = data.data();
+ for (int y = 0; y < h; ++y) {
+ memcpy(rawdata, image.scanLine(y), bytesPerLine);
+ rawdata += bytesPerLine;
+ }
+ object = writeImage(data, w, h, d, 0, 0);
+ } else {
+ QByteArray softMaskData;
+ bool dct = false;
+ QByteArray imageData;
+ bool hasAlpha = false;
+ bool hasMask = false;
+
+ if (QImageWriter::supportedImageFormats().contains("jpeg") && !grayscale) {
+ QBuffer buffer(&imageData);
+ QImageWriter writer(&buffer, "jpeg");
+ writer.setQuality(94);
+ writer.write(image);
+ dct = true;
+
+ if (format != QImage::Format_RGB32) {
+ softMaskData.resize(w * h);
+ uchar *sdata = (uchar *)softMaskData.data();
+ for (int y = 0; y < h; ++y) {
+ const QRgb *rgb = (const QRgb *)image.scanLine(y);
+ for (int x = 0; x < w; ++x) {
+ uchar alpha = qAlpha(*rgb);
+ *sdata++ = alpha;
+ hasMask |= (alpha < 255);
+ hasAlpha |= (alpha != 0 && alpha != 255);
+ ++rgb;
+ }
+ }
+ }
+ } else {
+ imageData.resize(grayscale ? w * h : 3 * w * h);
+ uchar *data = (uchar *)imageData.data();
+ softMaskData.resize(w * h);
+ uchar *sdata = (uchar *)softMaskData.data();
+ for (int y = 0; y < h; ++y) {
+ const QRgb *rgb = (const QRgb *)image.scanLine(y);
+ if (grayscale) {
+ for (int x = 0; x < w; ++x) {
+ *(data++) = qGray(*rgb);
+ uchar alpha = qAlpha(*rgb);
+ *sdata++ = alpha;
+ hasMask |= (alpha < 255);
+ hasAlpha |= (alpha != 0 && alpha != 255);
+ ++rgb;
+ }
+ } else {
+ for (int x = 0; x < w; ++x) {
+ *(data++) = qRed(*rgb);
+ *(data++) = qGreen(*rgb);
+ *(data++) = qBlue(*rgb);
+ uchar alpha = qAlpha(*rgb);
+ *sdata++ = alpha;
+ hasMask |= (alpha < 255);
+ hasAlpha |= (alpha != 0 && alpha != 255);
+ ++rgb;
+ }
+ }
+ }
+ if (format == QImage::Format_RGB32)
+ hasAlpha = hasMask = false;
+ }
+ int maskObject = 0;
+ int softMaskObject = 0;
+ if (hasAlpha) {
+ softMaskObject = writeImage(softMaskData, w, h, 8, 0, 0);
+ } else if (hasMask) {
+ // dither the soft mask to 1bit and add it. This also helps PDF viewers
+ // without transparency support
+ int bytesPerLine = (w + 7) >> 3;
+ QByteArray mask(bytesPerLine * h, 0);
+ uchar *mdata = (uchar *)mask.data();
+ const uchar *sdata = (const uchar *)softMaskData.constData();
+ for (int y = 0; y < h; ++y) {
+ for (int x = 0; x < w; ++x) {
+ if (*sdata)
+ mdata[x>>3] |= (0x80 >> (x&7));
+ ++sdata;
+ }
+ mdata += bytesPerLine;
+ }
+ maskObject = writeImage(mask, w, h, 1, 0, 0);
+ }
+ object = writeImage(imageData, w, h, grayscale ? 8 : 32,
+ maskObject, softMaskObject, dct);
+ }
+ imageCache.insert(serial_no, object);
+ return object;
}
-void QPdfBaseEnginePrivate::drawTextItem(const QPointF &p, const QTextItemInt &ti)
+void QPdfEnginePrivate::drawTextItem(const QPointF &p, const QTextItemInt &ti)
{
- Q_Q(QPdfBaseEngine);
+ Q_Q(QPdfEngine);
+
+ if (ti.charFormat.isAnchor()) {
+ qreal size = ti.fontEngine->fontDef.pixelSize;
+#ifdef Q_WS_WIN
+ if (ti.fontEngine->type() == QFontEngine::Win) {
+ QFontEngineWin *fe = static_cast<QFontEngineWin *>(ti.fontEngine);
+ size = fe->tm.tmHeight;
+ }
+#endif
+ int synthesized = ti.fontEngine->synthesized();
+ qreal stretch = synthesized & QFontEngine::SynthesizedStretch ? ti.fontEngine->fontDef.stretch/100. : 1.;
+
+ QTransform trans;
+ // Build text rendering matrix (Trm). We need it to map the text area to user
+ // space units on the PDF page.
+ trans = QTransform(size*stretch, 0, 0, size, 0, 0);
+ // Apply text matrix (Tm).
+ trans *= QTransform(1,0,0,-1,p.x(),p.y());
+ // Apply page displacement (Identity for first page).
+ trans *= stroker.matrix;
+ // Apply Current Transformation Matrix (CTM)
+ trans *= pageMatrix();
+ qreal x1, y1, x2, y2;
+ trans.map(0, 0, &x1, &y1);
+ trans.map(ti.width.toReal()/size, (ti.ascent.toReal()-ti.descent.toReal())/size, &x2, &y2);
+
+ uint annot = addXrefEntry(-1);
+#ifdef Q_DEBUG_PDF_LINKS
+ xprintf("<<\n/Type /Annot\n/Subtype /Link\n/Rect [%f %f %f %f]\n/Border [16 16 1]\n/A <<\n",
+#else
+ xprintf("<<\n/Type /Annot\n/Subtype /Link\n/Rect [%f %f %f %f]\n/Border [0 0 0]\n/A <<\n",
+#endif
+ static_cast<double>(x1),
+ static_cast<double>(y1),
+ static_cast<double>(x2),
+ static_cast<double>(y2));
+ xprintf("/Type /Action\n/S /URI\n/URI (%s)\n",
+ ti.charFormat.anchorHref().toLatin1().constData());
+ xprintf(">>\n>>\n");
+ xprintf("endobj\n");
+
+ if (!currentPage->annotations.contains(annot)) {
+ currentPage->annotations.append(annot);
+ }
+ }
QFontEngine *fe = ti.fontEngine;
@@ -2024,83 +2596,33 @@ void QPdfBaseEnginePrivate::drawTextItem(const QPointF &p, const QTextItemInt &t
*currentPage << "ET\n";
}
-QRect QPdfBaseEnginePrivate::paperRect() const
+QTransform QPdfEnginePrivate::pageMatrix() const
{
- int w;
- int h;
- if (paperSize == QPrinter::Custom) {
- w = qRound(customPaperSize.width()*resolution/72.);
- h = qRound(customPaperSize.height()*resolution/72.);
- } else {
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
- if (QCUPSSupport::isAvailable() && !cupsPaperRect.isNull()) {
- QRect r = cupsPaperRect;
- w = r.width();
- h = r.height();
- } else
-#endif
- {
- QPdf::PaperSize s = QPdf::paperSize(paperSize);
- w = s.width;
- h = s.height;
- }
- w = qRound(w*resolution/72.);
- h = qRound(h*resolution/72.);
+ qreal scale = 72./resolution;
+ QTransform tmp(scale, 0.0, 0.0, -scale, 0.0, height());
+ if (!fullPage) {
+ QRect r = pageRect();
+ tmp.translate(r.left(), r.top());
}
- if (orientation == QPrinter::Portrait)
- return QRect(0, 0, w, h);
- else
- return QRect(0, 0, h, w);
+ return tmp;
}
-QRect QPdfBaseEnginePrivate::pageRect() const
+void QPdfEnginePrivate::newPage()
{
- if(fullPage)
- return paperRect();
-
- QRect r;
-
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
- if (!hasCustomPageMargins && QCUPSSupport::isAvailable() && !cupsPageRect.isNull()) {
- r = cupsPageRect;
- if (r == cupsPaperRect) {
- // if cups doesn't define any margins, give it at least approx 3.5 mm
- r = QRect(10, 10, r.width() - 20, r.height() - 20);
- }
- } else
-#endif
- {
- QPdf::PaperSize s;
- if (paperSize == QPrinter::Custom) {
- s.width = qRound(customPaperSize.width());
- s.height = qRound(customPaperSize.height());
- } else {
- s = QPdf::paperSize(paperSize);
- }
- if (hasCustomPageMargins)
- r = QRect(0, 0, s.width, s.height);
- else
- r = QRect(72/3, 72/3, s.width - 2*72/3, s.height - 2*72/3);
- }
+ if (currentPage && currentPage->pageSize.isEmpty())
+ currentPage->pageSize = QSize(width(), height());
+ writePage();
- int x = qRound(r.left()*resolution/72.);
- int y = qRound(r.top()*resolution/72.);
- int w = qRound(r.width()*resolution/72.);
- int h = qRound(r.height()*resolution/72.);
- if (orientation == QPrinter::Portrait)
- r = QRect(x, y, w, h);
- else
- r = QRect(y, x, h, w);
-
- if (hasCustomPageMargins) {
- r.adjust(qRound(leftMargin*(resolution/72.)),
- qRound(topMargin*(resolution/72.)),
- -qRound(rightMargin*(resolution/72.)),
- -qRound(bottomMargin*(resolution/72.)));
- }
- return r;
+ delete currentPage;
+ currentPage = new QPdfPage;
+ currentPage->pageSize = QSize(width(), height());
+ stroker.stream = currentPage;
+ pages.append(requestObject());
+
+ *currentPage << "/GSa gs /CSp cs /CSp CS\n"
+ << QPdf::generateMatrix(pageMatrix())
+ << "q q\n";
}
-#endif
QT_END_NAMESPACE
diff --git a/src/gui/painting/qpdf_p.h b/src/gui/painting/qpdf_p.h
index 8cc56befe1..6df5052c06 100644
--- a/src/gui/painting/qpdf_p.h
+++ b/src/gui/painting/qpdf_p.h
@@ -56,22 +56,14 @@
#include "QtCore/qstring.h"
#include "QtCore/qvector.h"
#include "private/qstroker_p.h"
+#include "private/qpaintengine_p.h"
#include "private/qfontengine_p.h"
-#include "QtGui/qprinter.h"
#include "private/qfontsubset_p.h"
-#include "private/qpaintengine_alpha_p.h"
-#include "qprintengine.h"
-#include "qbuffer.h"
-#ifndef QT_NO_PRINTER
+// #define USE_NATIVE_GRADIENTS
QT_BEGIN_NAMESPACE
-#define PPK_CupsOptions QPrintEngine::PrintEnginePropertyKey(0xfe00)
-#define PPK_CupsPageRect QPrintEngine::PrintEnginePropertyKey(0xfe01)
-#define PPK_CupsPaperRect QPrintEngine::PrintEnginePropertyKey(0xfe02)
-#define PPK_CupsStringPageSize QPrintEngine::PrintEnginePropertyKey(0xfe03)
-
const char *qt_real_to_string(qreal val, char *buf);
const char *qt_int_to_string(int val, char *buf);
@@ -149,13 +141,6 @@ namespace QPdf {
const char *toHex(ushort u, char *buffer);
const char *toHex(uchar u, char *buffer);
-
- struct PaperSize {
- int width, height; // in postscript points
- };
- PaperSize paperSize(QPrinter::PaperSize paperSize);
- const char *paperSizeToString(QPrinter::PaperSize paperSize);
-
}
@@ -176,15 +161,20 @@ public:
private:
};
+class QPdfWriter;
+class QPdfEnginePrivate;
-class QPdfBaseEnginePrivate;
-
-class QPdfBaseEngine : public QAlphaPaintEngine, public QPrintEngine
+class Q_GUI_EXPORT QPdfEngine : public QPaintEngine
{
- Q_DECLARE_PRIVATE(QPdfBaseEngine)
+ Q_DECLARE_PRIVATE(QPdfEngine)
+ friend class QPdfWriter;
public:
- QPdfBaseEngine(QPdfBaseEnginePrivate &d, PaintEngineFeatures f);
- ~QPdfBaseEngine() {}
+ QPdfEngine();
+ QPdfEngine(QPdfEnginePrivate &d);
+ ~QPdfEngine() {}
+
+ void setOutputFilename(const QString &filename);
+ inline void setResolution(int resolution);
// reimplementations QPaintEngine
bool begin(QPaintDevice *pdev);
@@ -198,41 +188,62 @@ public:
void drawTextItem(const QPointF &p, const QTextItem &textItem);
+ void drawPixmap (const QRectF & rectangle, const QPixmap & pixmap, const QRectF & sr);
+ void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr,
+ Qt::ImageConversionFlags flags = Qt::AutoColor);
+ void drawTiledPixmap (const QRectF & rectangle, const QPixmap & pixmap, const QPointF & point);
+
void updateState(const QPaintEngineState &state);
int metric(QPaintDevice::PaintDeviceMetric metricType) const;
+ Type type() const;
// end reimplementations QPaintEngine
// Printer stuff...
bool newPage();
- void setProperty(PrintEnginePropertyKey key, const QVariant &value);
- QVariant property(PrintEnginePropertyKey key) const;
void setPen();
- virtual void setBrush() = 0;
+ void setBrush();
void setupGraphicsState(QPaintEngine::DirtyFlags flags);
private:
void updateClipPath(const QPainterPath & path, Qt::ClipOperation op);
};
-class QPdfBaseEnginePrivate : public QAlphaPaintEnginePrivate
+class Q_GUI_EXPORT QPdfEnginePrivate : public QPaintEnginePrivate
{
- Q_DECLARE_PUBLIC(QPdfBaseEngine)
+ Q_DECLARE_PUBLIC(QPdfEngine)
public:
- QPdfBaseEnginePrivate(QPrinter::PrinterMode m);
- ~QPdfBaseEnginePrivate();
+ QPdfEnginePrivate();
+ ~QPdfEnginePrivate();
- bool openPrintDevice();
- void closePrintDevice();
-
-
- virtual void drawTextItem(const QPointF &p, const QTextItemInt &ti);
inline uint requestObject() { return currentObject++; }
QRect paperRect() const;
QRect pageRect() const;
+ int width() const {
+ QRect r = paperRect();
+ return qRound(r.width()*72./resolution);
+ }
+ int height() const {
+ QRect r = paperRect();
+ return qRound(r.height()*72./resolution);
+ }
+
+ void writeHeader();
+ void writeTail();
+
+ int addImage(const QImage &image, bool *bitmap, qint64 serial_no);
+ int addConstantAlphaObject(int brushAlpha, int penAlpha = 255);
+ int addBrushPattern(const QTransform &matrix, bool *specifyColor, int *gStateObject);
+
+ void drawTextItem(const QPointF &p, const QTextItemInt &ti);
+
+ QTransform pageMatrix() const;
+
+ void newPage();
+
bool postscript;
int currentObject;
@@ -249,7 +260,6 @@ public:
bool hasBrush;
bool simplePen;
qreal opacity;
- bool useAlphaEngine;
QHash<QFontEngine::FaceId, QFontSubset *> fonts;
@@ -257,43 +267,70 @@ public:
// the device the output is in the end streamed to.
QIODevice *outDevice;
- int fd;
+ bool ownsDevice;
// printer options
QString outputFileName;
- QString printerName;
- QString printProgram;
- QString selectionOption;
QString title;
QString creator;
- QPrinter::DuplexMode duplex;
- bool collate;
bool fullPage;
bool embedFonts;
- int copies;
int resolution;
- QPrinter::PageOrder pageOrder;
- QPrinter::Orientation orientation;
- QPrinter::PaperSize paperSize;
- QPrinter::ColorMode colorMode;
- QPrinter::PaperSource paperSource;
-
- QStringList cupsOptions;
- QRect cupsPaperRect;
- QRect cupsPageRect;
- QString cupsStringPageSize;
- QSizeF customPaperSize; // in postscript points
- bool hasCustomPageMargins;
+ bool landscape;
+ bool grayscale;
+
+ // in postscript points
+ QSizeF paperSize;
qreal leftMargin, topMargin, rightMargin, bottomMargin;
#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
QString cupsTempFile;
#endif
+
+private:
+#ifdef USE_NATIVE_GRADIENTS
+ int gradientBrush(const QBrush &b, const QMatrix &matrix, int *gStateObject);
+#endif
+
+ void writeInfo();
+ void writePageRoot();
+ void writeFonts();
+ void embedFont(QFontSubset *font);
+
+ QVector<int> xrefPositions;
+ QDataStream* stream;
+ int streampos;
+
+ int writeImage(const QByteArray &data, int width, int height, int depth,
+ int maskObject, int softMaskObject, bool dct = false);
+ void writePage();
+
+ int addXrefEntry(int object, bool printostr = true);
+ void printString(const QString &string);
+ void xprintf(const char* fmt, ...);
+ inline void write(const QByteArray &data) {
+ stream->writeRawData(data.constData(), data.size());
+ streampos += data.size();
+ }
+
+ int writeCompressed(const char *src, int len);
+ inline int writeCompressed(const QByteArray &data) { return writeCompressed(data.constData(), data.length()); }
+ int writeCompressed(QIODevice *dev);
+
+ // various PDF objects
+ int pageRoot, catalog, info, graphicsState, patternColorSpace;
+ QVector<uint> pages;
+ QHash<qint64, uint> imageCache;
+ QHash<QPair<uint, uint>, uint > alphaCache;
};
-QT_END_NAMESPACE
+void QPdfEngine::setResolution(int resolution)
+{
+ Q_D(QPdfEngine);
+ d->resolution = resolution;
+}
-#endif // QT_NO_PRINTER
+QT_END_NAMESPACE
#endif // QPDF_P_H
diff --git a/src/gui/painting/qpdfwriter.cpp b/src/gui/painting/qpdfwriter.cpp
new file mode 100644
index 0000000000..9da5491d19
--- /dev/null
+++ b/src/gui/painting/qpdfwriter.cpp
@@ -0,0 +1,212 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qpdfwriter.h>
+#include <QtCore/private/qobject_p.h>
+#include "private/qpdf_p.h"
+#include <QtCore/qfile.h>
+
+
+class QPdfWriterPrivate : public QObjectPrivate
+{
+public:
+ QPdfWriterPrivate()
+ : QObjectPrivate()
+ {
+ engine = new QPdfEngine();
+ output = 0;
+ }
+ ~QPdfWriterPrivate()
+ {
+ delete engine;
+ delete output;
+ }
+
+ QPdfEngine *engine;
+ QFile *output;
+};
+
+
+/*! \class QPdfWriter
+
+ \brief The QPdfWriter class is a class to generate PDFs
+ that can be used as a paint device.
+
+ \ingroup painting
+
+ QPdfWriter generates PDF out of a series of drawing commands using QPainter.
+ The newPage() method can be used to create several pages.
+ */
+
+/*!
+ Constructs a PDF writer that will write the pdf to \a filename.
+ */
+QPdfWriter::QPdfWriter(const QString &filename)
+ : QObject(*new QPdfWriterPrivate)
+{
+ Q_D(QPdfWriter);
+
+ d->engine->setOutputFilename(filename);
+}
+
+/*!
+ Constructs a PDF writer that will write the pdf to \a device.
+ */
+QPdfWriter::QPdfWriter(QIODevice *device)
+ : QObject(*new QPdfWriterPrivate)
+{
+ Q_D(QPdfWriter);
+
+ d->engine->d_func()->outDevice = device;
+}
+
+/*!
+ Destroys the pdf writer.
+ */
+QPdfWriter::~QPdfWriter()
+{
+
+}
+
+/*!
+ Returns the title of the document.
+ */
+QString QPdfWriter::title() const
+{
+ Q_D(const QPdfWriter);
+ return d->engine->d_func()->title;
+}
+
+/*!
+ Sets the title of the document being created.
+ */
+void QPdfWriter::setTitle(const QString &title)
+{
+ Q_D(QPdfWriter);
+ d->engine->d_func()->title = title;
+}
+
+/*!
+ Returns the creator of the document.
+ */
+QString QPdfWriter::creator() const
+{
+ Q_D(const QPdfWriter);
+ return d->engine->d_func()->creator;
+}
+
+/*!
+ Sets the creator of the document.
+ */
+void QPdfWriter::setCreator(const QString &creator)
+{
+ Q_D(QPdfWriter);
+ d->engine->d_func()->creator = creator;
+}
+
+
+/*!
+ \reimp
+ */
+QPaintEngine *QPdfWriter::paintEngine() const
+{
+ Q_D(const QPdfWriter);
+
+ return d->engine;
+}
+
+/*!
+ \reimp
+ */
+void QPdfWriter::setPageSize(PageSize size)
+{
+ Q_D(const QPdfWriter);
+
+ QPagedPaintDevice::setPageSize(size);
+ d->engine->d_func()->paperSize = pageSizeMM() * 25.4/72.;
+}
+
+/*!
+ \reimp
+ */
+void QPdfWriter::setPageSizeMM(const QSizeF &size)
+{
+ Q_D(const QPdfWriter);
+
+ QPagedPaintDevice::setPageSizeMM(size);
+ d->engine->d_func()->paperSize = pageSizeMM() * 25.4/72.;
+}
+
+/*!
+ \internal
+
+ Returns the metric for the given \a id.
+*/
+int QPdfWriter::metric(PaintDeviceMetric id) const
+{
+ Q_D(const QPdfWriter);
+ return d->engine->metric(id);
+}
+
+/*!
+ \reimp
+*/
+bool QPdfWriter::newPage()
+{
+ Q_D(QPdfWriter);
+
+ return d->engine->newPage();
+}
+
+
+/*!
+ \reimp
+ */
+void QPdfWriter::setMargins(const Margins &m)
+{
+ Q_D(QPdfWriter);
+
+ const qreal multiplier = 72./25.4;
+ d->engine->d_func()->leftMargin = m.left*multiplier;
+ d->engine->d_func()->rightMargin = m.right*multiplier;
+ d->engine->d_func()->topMargin = m.top*multiplier;
+ d->engine->d_func()->bottomMargin = m.bottom*multiplier;
+}
diff --git a/src/gui/painting/qpdfwriter.h b/src/gui/painting/qpdfwriter.h
new file mode 100644
index 0000000000..005d8e640b
--- /dev/null
+++ b/src/gui/painting/qpdfwriter.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPDFWRITER_H
+#define QPDFWRITER_H
+
+#include <QtCore/qobject.h>
+#include <QtGui/qpagedpaintdevice.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QIODevice;
+class QPdfWriterPrivate;
+
+class Q_GUI_EXPORT QPdfWriter : public QObject, public QPagedPaintDevice
+{
+ Q_OBJECT
+public:
+ QPdfWriter(const QString &filename);
+ QPdfWriter(QIODevice *device);
+ ~QPdfWriter();
+
+ QString title() const;
+ void setTitle(const QString &title);
+
+ QString creator() const;
+ void setCreator(const QString &creator);
+
+ bool newPage();
+
+ void setPageSize(PageSize size);
+ void setPageSizeMM(const QSizeF &size);
+
+ void setMargins(const Margins &m);
+
+protected:
+ QPaintEngine *paintEngine() const;
+ int metric(PaintDeviceMetric id) const;
+
+private:
+ Q_DISABLE_COPY(QPdfWriter)
+ Q_DECLARE_PRIVATE(QPdfWriter)
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/gui/painting/qplatformbackingstore_qpa.cpp b/src/gui/painting/qplatformbackingstore_qpa.cpp
new file mode 100644
index 0000000000..fa85661f31
--- /dev/null
+++ b/src/gui/painting/qplatformbackingstore_qpa.cpp
@@ -0,0 +1,155 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qplatformbackingstore_qpa.h>
+#include <qwindow.h>
+#include <qpixmap.h>
+#include <private/qwindow_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QPlatformBackingStorePrivate
+{
+public:
+ QPlatformBackingStorePrivate(QWindow *w)
+ : window(w)
+ {
+ }
+
+ QWindow *window;
+ QSize size;
+};
+
+/*!
+ \class QPlatformBackingStore
+ \since 5.0
+ \internal
+ \preliminary
+ \ingroup qpa
+
+ \brief The QPlatformBackingStore class provides the drawing area for top-level
+ windows.
+*/
+
+
+/*!
+ \fn void QPlatformBackingStore::beginPaint(const QRegion &region)
+
+ This function is called before painting onto the surface begins,
+ with the \a region in which the painting will occur.
+
+ \sa endPaint(), paintDevice()
+*/
+
+/*!
+ \fn void QPlatformBackingStore::endPaint(const QRegion &region)
+
+ This function is called after painting onto the surface has ended,
+ with the \a region in which the painting was performed.
+
+ \sa beginPaint(), paintDevice()
+*/
+
+/*!
+ \fn void QPlatformBackingStore::flush(QWindow *window, const QRegion &region,
+ const QPoint &offset)
+
+ Flushes the given \a region from the specified \a window onto the
+ screen.
+
+ Note that the \a offset parameter is currently unused.
+*/
+
+/*!
+ \fn QPaintDevice* QPlatformBackingStore::paintDevice()
+
+ Implement this function to return the appropriate paint device.
+*/
+
+/*!
+ Constructs an empty surface for the given top-level \a window.
+*/
+QPlatformBackingStore::QPlatformBackingStore(QWindow *window)
+ : d_ptr(new QPlatformBackingStorePrivate(window))
+{
+}
+
+/*!
+ Destroys this surface.
+*/
+QPlatformBackingStore::~QPlatformBackingStore()
+{
+ delete d_ptr;
+}
+
+/*!
+ Returns a pointer to the top-level window associated with this
+ surface.
+*/
+QWindow* QPlatformBackingStore::window() const
+{
+ return d_ptr->window;
+}
+
+void QPlatformBackingStore::beginPaint(const QRegion &)
+{
+}
+
+void QPlatformBackingStore::endPaint()
+{
+}
+
+/*!
+ Scrolls the given \a area \a dx pixels to the right and \a dy
+ downward; both \a dx and \a dy may be negative.
+
+ Returns true if the area was scrolled successfully; false otherwise.
+*/
+bool QPlatformBackingStore::scroll(const QRegion &area, int dx, int dy)
+{
+ Q_UNUSED(area);
+ Q_UNUSED(dx);
+ Q_UNUSED(dy);
+
+ return false;
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/painting/qplatformbackingstore_qpa.h b/src/gui/painting/qplatformbackingstore_qpa.h
new file mode 100644
index 0000000000..29730167b4
--- /dev/null
+++ b/src/gui/painting/qplatformbackingstore_qpa.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPLATFORMBACKINGSTORE_QPA_H
+#define QPLATFORMBACKINGSTORE_QPA_H
+
+#include <QtCore/qrect.h>
+
+#include <QtGui/qwindow.h>
+#include <QtGui/qregion.h>
+
+QT_BEGIN_NAMESPACE
+
+class QRegion;
+class QRect;
+class QPoint;
+class QImage;
+class QPlatformBackingStorePrivate;
+class QPlatformWindow;
+
+class Q_GUI_EXPORT QPlatformBackingStore
+{
+public:
+ QPlatformBackingStore(QWindow *window);
+ virtual ~QPlatformBackingStore();
+
+ QWindow *window() const;
+
+ virtual QPaintDevice *paintDevice() = 0;
+
+ // 'window' can be a child window, in which case 'region' is in child window coordinates and
+ // offset is the (child) window's offset in relation to the window surface.
+ virtual void flush(QWindow *window, const QRegion &region, const QPoint &offset) = 0;
+
+ virtual void resize(const QSize &size, const QRegion &staticContents) = 0;
+
+ virtual bool scroll(const QRegion &area, int dx, int dy);
+
+ virtual void beginPaint(const QRegion &);
+ virtual void endPaint();
+
+private:
+ QPlatformBackingStorePrivate *d_ptr;
+};
+
+QT_END_NAMESPACE
+
+#endif // QPLATFORMBACKINGSTORE_QPA_H
diff --git a/src/gui/painting/qprintengine.h b/src/gui/painting/qprintengine.h
deleted file mode 100644
index da4fe2ac68..0000000000
--- a/src/gui/painting/qprintengine.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPRINTENGINE_H
-#define QPRINTENGINE_H
-
-#include <QtCore/qvariant.h>
-#include <QtGui/qprinter.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_PRINTER
-
-class Q_GUI_EXPORT QPrintEngine
-{
-public:
- virtual ~QPrintEngine() {}
- enum PrintEnginePropertyKey {
- PPK_CollateCopies,
- PPK_ColorMode,
- PPK_Creator,
- PPK_DocumentName,
- PPK_FullPage,
- PPK_NumberOfCopies,
- PPK_Orientation,
- PPK_OutputFileName,
- PPK_PageOrder,
- PPK_PageRect,
- PPK_PageSize,
- PPK_PaperRect,
- PPK_PaperSource,
- PPK_PrinterName,
- PPK_PrinterProgram,
- PPK_Resolution,
- PPK_SelectionOption,
- PPK_SupportedResolutions,
-
- PPK_WindowsPageSize,
- PPK_FontEmbedding,
- PPK_SuppressSystemPrintStatus,
-
- PPK_Duplex,
-
- PPK_PaperSources,
- PPK_CustomPaperSize,
- PPK_PageMargins,
- PPK_CopyCount,
- PPK_SupportsMultipleCopies,
- PPK_PaperSize = PPK_PageSize,
-
- PPK_CustomBase = 0xff00
- };
-
- virtual void setProperty(PrintEnginePropertyKey key, const QVariant &value) = 0;
- virtual QVariant property(PrintEnginePropertyKey key) const = 0;
-
- virtual bool newPage() = 0;
- virtual bool abort() = 0;
-
- virtual int metric(QPaintDevice::PaintDeviceMetric) const = 0;
-
- virtual QPrinter::PrinterState printerState() const = 0;
-
-#ifdef Q_WS_WIN
- virtual HDC getPrinterDC() const { return 0; }
- virtual void releasePrinterDC(HDC) const { }
-#endif
-
-};
-
-#endif // QT_NO_PRINTER
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QPRINTENGINE_H
diff --git a/src/gui/painting/qprintengine_pdf.cpp b/src/gui/painting/qprintengine_pdf.cpp
deleted file mode 100644
index 2b0bca8024..0000000000
--- a/src/gui/painting/qprintengine_pdf.cpp
+++ /dev/null
@@ -1,1244 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtGui/qprintengine.h>
-
-#include <qiodevice.h>
-#include <qpainter.h>
-#include <qbitmap.h>
-#include <qpainterpath.h>
-#include <qpaintdevice.h>
-#include <qfile.h>
-#include <qdebug.h>
-#include <qimagewriter.h>
-#include <qbuffer.h>
-#include <qdatetime.h>
-
-#ifndef QT_NO_PRINTER
-#include <limits.h>
-#include <math.h>
-#ifndef QT_NO_COMPRESS
-#include <zlib.h>
-#endif
-
-#if defined(Q_OS_WINCE)
-#include "qwinfunctions_wince.h"
-#endif
-
-#include "qprintengine_pdf_p.h"
-#include "private/qdrawhelper_p.h"
-
-QT_BEGIN_NAMESPACE
-
-extern qint64 qt_pixmap_id(const QPixmap &pixmap);
-extern qint64 qt_image_id(const QImage &image);
-
-//#define FONT_DUMP
-
-// might be helpful for smooth transforms of images
-// Can't use it though, as gs generates completely wrong images if this is true.
-static const bool interpolateImages = false;
-
-#ifdef QT_NO_COMPRESS
-static const bool do_compress = false;
-#else
-static const bool do_compress = true;
-#endif
-
-QPdfPage::QPdfPage()
- : QPdf::ByteStream(true) // Enable file backing
-{
-}
-
-void QPdfPage::streamImage(int w, int h, int object)
-{
- *this << w << "0 0 " << -h << "0 " << h << "cm /Im" << object << " Do\n";
- if (!images.contains(object))
- images.append(object);
-}
-
-
-inline QPaintEngine::PaintEngineFeatures qt_pdf_decide_features()
-{
- QPaintEngine::PaintEngineFeatures f = QPaintEngine::AllFeatures;
- f &= ~(QPaintEngine::PorterDuff | QPaintEngine::PerspectiveTransform
- | QPaintEngine::ObjectBoundingModeGradients
-#ifndef USE_NATIVE_GRADIENTS
- | QPaintEngine::LinearGradientFill
-#endif
- | QPaintEngine::RadialGradientFill
- | QPaintEngine::ConicalGradientFill);
- return f;
-}
-
-QPdfEngine::QPdfEngine(QPrinter::PrinterMode m)
- : QPdfBaseEngine(*new QPdfEnginePrivate(m), qt_pdf_decide_features())
-{
- state = QPrinter::Idle;
-}
-
-QPdfEngine::~QPdfEngine()
-{
-}
-
-bool QPdfEngine::begin(QPaintDevice *pdev)
-{
- Q_D(QPdfEngine);
-
- if(!QPdfBaseEngine::begin(pdev)) {
- state = QPrinter::Error;
- return false;
- }
- d->stream->setDevice(d->outDevice);
-
- d->streampos = 0;
- d->hasPen = true;
- d->hasBrush = false;
- d->clipEnabled = false;
- d->allClipped = false;
-
- d->xrefPositions.clear();
- d->pageRoot = 0;
- d->catalog = 0;
- d->info = 0;
- d->graphicsState = 0;
- d->patternColorSpace = 0;
-
- d->pages.clear();
- d->imageCache.clear();
-
- setActive(true);
- state = QPrinter::Active;
- d->writeHeader();
- newPage();
-
- return true;
-}
-
-bool QPdfEngine::end()
-{
- Q_D(QPdfEngine);
- d->writeTail();
-
- d->stream->unsetDevice();
- QPdfBaseEngine::end();
- setActive(false);
- state = QPrinter::Idle;
- return true;
-}
-
-
-void QPdfEngine::drawPixmap (const QRectF &rectangle, const QPixmap &pixmap, const QRectF &sr)
-{
- if (sr.isEmpty() || rectangle.isEmpty() || pixmap.isNull())
- return;
- Q_D(QPdfEngine);
-
- QBrush b = d->brush;
-
- QRect sourceRect = sr.toRect();
- QPixmap pm = sourceRect != pixmap.rect() ? pixmap.copy(sourceRect) : pixmap;
- QImage image = pm.toImage();
- bool bitmap = true;
- const int object = d->addImage(image, &bitmap, pm.cacheKey());
- if (object < 0)
- return;
-
- *d->currentPage << "q\n/GSa gs\n";
- *d->currentPage
- << QPdf::generateMatrix(QTransform(rectangle.width() / sr.width(), 0, 0, rectangle.height() / sr.height(),
- rectangle.x(), rectangle.y()) * (d->simplePen ? QTransform() : d->stroker.matrix));
- if (bitmap) {
- // set current pen as d->brush
- d->brush = d->pen.brush();
- }
- setBrush();
- d->currentPage->streamImage(image.width(), image.height(), object);
- *d->currentPage << "Q\n";
-
- d->brush = b;
-}
-
-void QPdfEngine::drawImage(const QRectF &rectangle, const QImage &image, const QRectF &sr, Qt::ImageConversionFlags)
-{
- if (sr.isEmpty() || rectangle.isEmpty() || image.isNull())
- return;
- Q_D(QPdfEngine);
-
- QRect sourceRect = sr.toRect();
- QImage im = sourceRect != image.rect() ? image.copy(sourceRect) : image;
- bool bitmap = true;
- const int object = d->addImage(im, &bitmap, im.cacheKey());
- if (object < 0)
- return;
-
- *d->currentPage << "q\n/GSa gs\n";
- *d->currentPage
- << QPdf::generateMatrix(QTransform(rectangle.width() / sr.width(), 0, 0, rectangle.height() / sr.height(),
- rectangle.x(), rectangle.y()) * (d->simplePen ? QTransform() : d->stroker.matrix));
- setBrush();
- d->currentPage->streamImage(im.width(), im.height(), object);
- *d->currentPage << "Q\n";
-}
-
-void QPdfEngine::drawTiledPixmap (const QRectF &rectangle, const QPixmap &pixmap, const QPointF &point)
-{
- Q_D(QPdfEngine);
-
- bool bitmap = (pixmap.depth() == 1);
- QBrush b = d->brush;
- QPointF bo = d->brushOrigin;
- bool hp = d->hasPen;
- d->hasPen = false;
- bool hb = d->hasBrush;
- d->hasBrush = true;
-
- d->brush = QBrush(pixmap);
- if (bitmap)
- // #### fix bitmap case where we have a brush pen
- d->brush.setColor(d->pen.color());
-
- d->brushOrigin = -point;
- *d->currentPage << "q\n";
- setBrush();
-
- drawRects(&rectangle, 1);
- *d->currentPage << "Q\n";
-
- d->hasPen = hp;
- d->hasBrush = hb;
- d->brush = b;
- d->brushOrigin = bo;
-}
-
-
-void QPdfEngine::setBrush()
-{
- Q_D(QPdfEngine);
- Qt::BrushStyle style = d->brush.style();
- if (style == Qt::NoBrush)
- return;
-
- bool specifyColor;
- int gStateObject = 0;
- int patternObject = d->addBrushPattern(d->stroker.matrix, &specifyColor, &gStateObject);
-
- *d->currentPage << (patternObject ? "/PCSp cs " : "/CSp cs ");
- if (specifyColor) {
- QColor rgba = d->brush.color();
- if (d->colorMode == QPrinter::GrayScale) {
- qreal gray = qGray(rgba.rgba())/255.;
- *d->currentPage << gray << gray << gray;
- } else {
- *d->currentPage << rgba.redF()
- << rgba.greenF()
- << rgba.blueF();
- }
- }
- if (patternObject)
- *d->currentPage << "/Pat" << patternObject;
- *d->currentPage << "scn\n";
-
- if (gStateObject)
- *d->currentPage << "/GState" << gStateObject << "gs\n";
- else
- *d->currentPage << "/GSa gs\n";
-}
-
-QPaintEngine::Type QPdfEngine::type() const
-{
- return QPaintEngine::Pdf;
-}
-
-bool QPdfEngine::newPage()
-{
- Q_D(QPdfEngine);
- if (!isActive())
- return false;
- d->newPage();
- return QPdfBaseEngine::newPage();
-}
-
-QPdfEnginePrivate::QPdfEnginePrivate(QPrinter::PrinterMode m)
- : QPdfBaseEnginePrivate(m)
-{
- streampos = 0;
-
- stream = new QDataStream;
- pageOrder = QPrinter::FirstPageFirst;
- orientation = QPrinter::Portrait;
- fullPage = false;
-}
-
-QPdfEnginePrivate::~QPdfEnginePrivate()
-{
- delete stream;
-}
-
-
-#ifdef USE_NATIVE_GRADIENTS
-int QPdfEnginePrivate::gradientBrush(const QBrush &b, const QMatrix &matrix, int *gStateObject)
-{
- const QGradient *gradient = b.gradient();
- if (!gradient)
- return 0;
-
- QTransform inv = matrix.inverted();
- QPointF page_rect[4] = { inv.map(QPointF(0, 0)),
- inv.map(QPointF(width_, 0)),
- inv.map(QPointF(0, height_)),
- inv.map(QPointF(width_, height_)) };
-
- bool opaque = b.isOpaque();
-
- QByteArray shader;
- QByteArray alphaShader;
- if (gradient->type() == QGradient::LinearGradient) {
- const QLinearGradient *lg = static_cast<const QLinearGradient *>(gradient);
- shader = QPdf::generateLinearGradientShader(lg, page_rect);
- if (!opaque)
- alphaShader = QPdf::generateLinearGradientShader(lg, page_rect, true);
- } else {
- // #############
- return 0;
- }
- int shaderObject = addXrefEntry(-1);
- write(shader);
-
- QByteArray str;
- QPdf::ByteStream s(&str);
- s << "<<\n"
- "/Type /Pattern\n"
- "/PatternType 2\n"
- "/Shading " << shaderObject << "0 R\n"
- "/Matrix ["
- << matrix.m11()
- << matrix.m12()
- << matrix.m21()
- << matrix.m22()
- << matrix.dx()
- << matrix.dy() << "]\n";
- s << ">>\n"
- "endobj\n";
-
- int patternObj = addXrefEntry(-1);
- write(str);
- currentPage->patterns.append(patternObj);
-
- if (!opaque) {
- bool ca = true;
- QGradientStops stops = gradient->stops();
- int a = stops.at(0).second.alpha();
- for (int i = 1; i < stops.size(); ++i) {
- if (stops.at(i).second.alpha() != a) {
- ca = false;
- break;
- }
- }
- if (ca) {
- *gStateObject = addConstantAlphaObject(stops.at(0).second.alpha());
- } else {
- int alphaShaderObject = addXrefEntry(-1);
- write(alphaShader);
-
- QByteArray content;
- QPdf::ByteStream c(&content);
- c << "/Shader" << alphaShaderObject << "sh\n";
-
- QByteArray form;
- QPdf::ByteStream f(&form);
- f << "<<\n"
- "/Type /XObject\n"
- "/Subtype /Form\n"
- "/BBox [0 0 " << width_ << height_ << "]\n"
- "/Group <</S /Transparency >>\n"
- "/Resources <<\n"
- "/Shading << /Shader" << alphaShaderObject << alphaShaderObject << "0 R >>\n"
- ">>\n";
-
- f << "/Length " << content.length() << "\n"
- ">>\n"
- "stream\n"
- << content
- << "endstream\n"
- "endobj\n";
-
- int softMaskFormObject = addXrefEntry(-1);
- write(form);
- *gStateObject = addXrefEntry(-1);
- xprintf("<< /SMask << /S /Alpha /G %d 0 R >> >>\n"
- "endobj\n", softMaskFormObject);
- currentPage->graphicStates.append(*gStateObject);
- }
- }
-
- return patternObj;
-}
-#endif
-
-int QPdfEnginePrivate::addConstantAlphaObject(int brushAlpha, int penAlpha)
-{
- if (brushAlpha == 255 && penAlpha == 255)
- return 0;
- int object = alphaCache.value(QPair<uint, uint>(brushAlpha, penAlpha), 0);
- if (!object) {
- object = addXrefEntry(-1);
- QByteArray alphaDef;
- QPdf::ByteStream s(&alphaDef);
- s << "<<\n/ca " << (brushAlpha/qreal(255.)) << '\n';
- s << "/CA " << (penAlpha/qreal(255.)) << "\n>>";
- xprintf("%s\nendobj\n", alphaDef.constData());
- alphaCache.insert(QPair<uint, uint>(brushAlpha, penAlpha), object);
- }
- if (currentPage->graphicStates.indexOf(object) < 0)
- currentPage->graphicStates.append(object);
-
- return object;
-}
-
-int QPdfEnginePrivate::addBrushPattern(const QTransform &m, bool *specifyColor, int *gStateObject)
-{
- int paintType = 2; // Uncolored tiling
- int w = 8;
- int h = 8;
-
- *specifyColor = true;
- *gStateObject = 0;
-
- QTransform matrix = m;
- matrix.translate(brushOrigin.x(), brushOrigin.y());
- matrix = matrix * pageMatrix();
- //qDebug() << brushOrigin << matrix;
-
- Qt::BrushStyle style = brush.style();
- if (style == Qt::LinearGradientPattern) {// && style <= Qt::ConicalGradientPattern) {
-#ifdef USE_NATIVE_GRADIENTS
- *specifyColor = false;
- return gradientBrush(b, matrix, gStateObject);
-#else
- return 0;
-#endif
- }
-
- if ((!brush.isOpaque() && brush.style() < Qt::LinearGradientPattern) || opacity != 1.0)
- *gStateObject = addConstantAlphaObject(qRound(brush.color().alpha() * opacity),
- qRound(pen.color().alpha() * opacity));
-
- int imageObject = -1;
- QByteArray pattern = QPdf::patternForBrush(brush);
- if (pattern.isEmpty()) {
- if (brush.style() != Qt::TexturePattern)
- return 0;
- QImage image = brush.texture().toImage();
- bool bitmap = true;
- imageObject = addImage(image, &bitmap, qt_pixmap_id(brush.texture()));
- if (imageObject != -1) {
- QImage::Format f = image.format();
- if (f != QImage::Format_MonoLSB && f != QImage::Format_Mono) {
- paintType = 1; // Colored tiling
- *specifyColor = false;
- }
- w = image.width();
- h = image.height();
- QTransform m(w, 0, 0, -h, 0, h);
- QPdf::ByteStream s(&pattern);
- s << QPdf::generateMatrix(m);
- s << "/Im" << imageObject << " Do\n";
- }
- }
-
- QByteArray str;
- QPdf::ByteStream s(&str);
- s << "<<\n"
- "/Type /Pattern\n"
- "/PatternType 1\n"
- "/PaintType " << paintType << "\n"
- "/TilingType 1\n"
- "/BBox [0 0 " << w << h << "]\n"
- "/XStep " << w << "\n"
- "/YStep " << h << "\n"
- "/Matrix ["
- << matrix.m11()
- << matrix.m12()
- << matrix.m21()
- << matrix.m22()
- << matrix.dx()
- << matrix.dy() << "]\n"
- "/Resources \n<< "; // open resource tree
- if (imageObject > 0) {
- s << "/XObject << /Im" << imageObject << ' ' << imageObject << "0 R >> ";
- }
- s << ">>\n"
- "/Length " << pattern.length() << "\n"
- ">>\n"
- "stream\n"
- << pattern
- << "endstream\n"
- "endobj\n";
-
- int patternObj = addXrefEntry(-1);
- write(str);
- currentPage->patterns.append(patternObj);
- return patternObj;
-}
-
-/*!
- * Adds an image to the pdf and return the pdf-object id. Returns -1 if adding the image failed.
- */
-int QPdfEnginePrivate::addImage(const QImage &img, bool *bitmap, qint64 serial_no)
-{
- if (img.isNull())
- return -1;
-
- int object = imageCache.value(serial_no);
- if(object)
- return object;
-
- QImage image = img;
- QImage::Format format = image.format();
- if (image.depth() == 1 && *bitmap && img.colorTable().size() == 2
- && img.colorTable().at(0) == QColor(Qt::black).rgba()
- && img.colorTable().at(1) == QColor(Qt::white).rgba())
- {
- if (format == QImage::Format_MonoLSB)
- image = image.convertToFormat(QImage::Format_Mono);
- format = QImage::Format_Mono;
- } else {
- *bitmap = false;
- if (format != QImage::Format_RGB32 && format != QImage::Format_ARGB32) {
- image = image.convertToFormat(QImage::Format_ARGB32);
- format = QImage::Format_ARGB32;
- }
- }
-
- int w = image.width();
- int h = image.height();
- int d = image.depth();
-
- if (format == QImage::Format_Mono) {
- int bytesPerLine = (w + 7) >> 3;
- QByteArray data;
- data.resize(bytesPerLine * h);
- char *rawdata = data.data();
- for (int y = 0; y < h; ++y) {
- memcpy(rawdata, image.scanLine(y), bytesPerLine);
- rawdata += bytesPerLine;
- }
- object = writeImage(data, w, h, d, 0, 0);
- } else {
- QByteArray softMaskData;
- bool dct = false;
- QByteArray imageData;
- bool hasAlpha = false;
- bool hasMask = false;
-
- if (QImageWriter::supportedImageFormats().contains("jpeg") && colorMode != QPrinter::GrayScale) {
- QBuffer buffer(&imageData);
- QImageWriter writer(&buffer, "jpeg");
- writer.setQuality(94);
- writer.write(image);
- dct = true;
-
- if (format != QImage::Format_RGB32) {
- softMaskData.resize(w * h);
- uchar *sdata = (uchar *)softMaskData.data();
- for (int y = 0; y < h; ++y) {
- const QRgb *rgb = (const QRgb *)image.scanLine(y);
- for (int x = 0; x < w; ++x) {
- uchar alpha = qAlpha(*rgb);
- *sdata++ = alpha;
- hasMask |= (alpha < 255);
- hasAlpha |= (alpha != 0 && alpha != 255);
- ++rgb;
- }
- }
- }
- } else {
- imageData.resize(colorMode == QPrinter::GrayScale ? w * h : 3 * w * h);
- uchar *data = (uchar *)imageData.data();
- softMaskData.resize(w * h);
- uchar *sdata = (uchar *)softMaskData.data();
- for (int y = 0; y < h; ++y) {
- const QRgb *rgb = (const QRgb *)image.scanLine(y);
- if (colorMode == QPrinter::GrayScale) {
- for (int x = 0; x < w; ++x) {
- *(data++) = qGray(*rgb);
- uchar alpha = qAlpha(*rgb);
- *sdata++ = alpha;
- hasMask |= (alpha < 255);
- hasAlpha |= (alpha != 0 && alpha != 255);
- ++rgb;
- }
- } else {
- for (int x = 0; x < w; ++x) {
- *(data++) = qRed(*rgb);
- *(data++) = qGreen(*rgb);
- *(data++) = qBlue(*rgb);
- uchar alpha = qAlpha(*rgb);
- *sdata++ = alpha;
- hasMask |= (alpha < 255);
- hasAlpha |= (alpha != 0 && alpha != 255);
- ++rgb;
- }
- }
- }
- if (format == QImage::Format_RGB32)
- hasAlpha = hasMask = false;
- }
- int maskObject = 0;
- int softMaskObject = 0;
- if (hasAlpha) {
- softMaskObject = writeImage(softMaskData, w, h, 8, 0, 0);
- } else if (hasMask) {
- // dither the soft mask to 1bit and add it. This also helps PDF viewers
- // without transparency support
- int bytesPerLine = (w + 7) >> 3;
- QByteArray mask(bytesPerLine * h, 0);
- uchar *mdata = (uchar *)mask.data();
- const uchar *sdata = (const uchar *)softMaskData.constData();
- for (int y = 0; y < h; ++y) {
- for (int x = 0; x < w; ++x) {
- if (*sdata)
- mdata[x>>3] |= (0x80 >> (x&7));
- ++sdata;
- }
- mdata += bytesPerLine;
- }
- maskObject = writeImage(mask, w, h, 1, 0, 0);
- }
- object = writeImage(imageData, w, h, colorMode == QPrinter::GrayScale ? 8 : 32,
- maskObject, softMaskObject, dct);
- }
- imageCache.insert(serial_no, object);
- return object;
-}
-
-void QPdfEnginePrivate::drawTextItem(const QPointF &p, const QTextItemInt &ti)
-{
- if (ti.charFormat.isAnchor()) {
- qreal size = ti.fontEngine->fontDef.pixelSize;
-#ifdef Q_WS_WIN
- if (ti.fontEngine->type() == QFontEngine::Win) {
- QFontEngineWin *fe = static_cast<QFontEngineWin *>(ti.fontEngine);
- size = fe->tm.tmHeight;
- }
-#endif
- int synthesized = ti.fontEngine->synthesized();
- qreal stretch = synthesized & QFontEngine::SynthesizedStretch ? ti.fontEngine->fontDef.stretch/100. : 1.;
-
- QTransform trans;
- // Build text rendering matrix (Trm). We need it to map the text area to user
- // space units on the PDF page.
- trans = QTransform(size*stretch, 0, 0, size, 0, 0);
- // Apply text matrix (Tm).
- trans *= QTransform(1,0,0,-1,p.x(),p.y());
- // Apply page displacement (Identity for first page).
- trans *= stroker.matrix;
- // Apply Current Transformation Matrix (CTM)
- trans *= pageMatrix();
- qreal x1, y1, x2, y2;
- trans.map(0, 0, &x1, &y1);
- trans.map(ti.width.toReal()/size, (ti.ascent.toReal()-ti.descent.toReal())/size, &x2, &y2);
-
- uint annot = addXrefEntry(-1);
-#ifdef Q_DEBUG_PDF_LINKS
- xprintf("<<\n/Type /Annot\n/Subtype /Link\n/Rect [%f %f %f %f]\n/Border [16 16 1]\n/A <<\n",
-#else
- xprintf("<<\n/Type /Annot\n/Subtype /Link\n/Rect [%f %f %f %f]\n/Border [0 0 0]\n/A <<\n",
-#endif
- static_cast<double>(x1),
- static_cast<double>(y1),
- static_cast<double>(x2),
- static_cast<double>(y2));
- xprintf("/Type /Action\n/S /URI\n/URI (%s)\n",
- ti.charFormat.anchorHref().toLatin1().constData());
- xprintf(">>\n>>\n");
- xprintf("endobj\n");
-
- if (!currentPage->annotations.contains(annot)) {
- currentPage->annotations.append(annot);
- }
- }
-
- QPdfBaseEnginePrivate::drawTextItem(p, ti);
-}
-
-QTransform QPdfEnginePrivate::pageMatrix() const
-{
- qreal scale = 72./resolution;
- QTransform tmp(scale, 0.0, 0.0, -scale, 0.0, height());
- if (!fullPage) {
- QRect r = pageRect();
- tmp.translate(r.left(), r.top());
- }
- return tmp;
-}
-
-void QPdfEnginePrivate::newPage()
-{
- if (currentPage && currentPage->pageSize.isEmpty())
- currentPage->pageSize = QSize(width(), height());
- writePage();
-
- delete currentPage;
- currentPage = new QPdfPage;
- currentPage->pageSize = QSize(width(), height());
- stroker.stream = currentPage;
- pages.append(requestObject());
-
- *currentPage << "/GSa gs /CSp cs /CSp CS\n"
- << QPdf::generateMatrix(pageMatrix())
- << "q q\n";
-}
-
-
-// For strings up to 10000 bytes only !
-void QPdfEnginePrivate::xprintf(const char* fmt, ...)
-{
- if (!stream)
- return;
-
- const int msize = 10000;
- char buf[msize];
-
- va_list args;
- va_start(args, fmt);
- int bufsize = qvsnprintf(buf, msize, fmt, args);
-
- Q_ASSERT(bufsize<msize);
-
- va_end(args);
-
- stream->writeRawData(buf, bufsize);
- streampos += bufsize;
-}
-
-int QPdfEnginePrivate::writeCompressed(QIODevice *dev)
-{
-#ifndef QT_NO_COMPRESS
- if (do_compress) {
- int size = QPdfPage::chunkSize();
- int sum = 0;
- ::z_stream zStruct;
- zStruct.zalloc = Z_NULL;
- zStruct.zfree = Z_NULL;
- zStruct.opaque = Z_NULL;
- if (::deflateInit(&zStruct, Z_DEFAULT_COMPRESSION) != Z_OK) {
- qWarning("QPdfStream::writeCompressed: Error in deflateInit()");
- return sum;
- }
- zStruct.avail_in = 0;
- QByteArray in, out;
- out.resize(size);
- while (!dev->atEnd() || zStruct.avail_in != 0) {
- if (zStruct.avail_in == 0) {
- in = dev->read(size);
- zStruct.avail_in = in.size();
- zStruct.next_in = reinterpret_cast<unsigned char*>(in.data());
- if (in.size() <= 0) {
- qWarning("QPdfStream::writeCompressed: Error in read()");
- ::deflateEnd(&zStruct);
- return sum;
- }
- }
- zStruct.next_out = reinterpret_cast<unsigned char*>(out.data());
- zStruct.avail_out = out.size();
- if (::deflate(&zStruct, 0) != Z_OK) {
- qWarning("QPdfStream::writeCompressed: Error in deflate()");
- ::deflateEnd(&zStruct);
- return sum;
- }
- int written = out.size() - zStruct.avail_out;
- stream->writeRawData(out.constData(), written);
- streampos += written;
- sum += written;
- }
- int ret;
- do {
- zStruct.next_out = reinterpret_cast<unsigned char*>(out.data());
- zStruct.avail_out = out.size();
- ret = ::deflate(&zStruct, Z_FINISH);
- if (ret != Z_OK && ret != Z_STREAM_END) {
- qWarning("QPdfStream::writeCompressed: Error in deflate()");
- ::deflateEnd(&zStruct);
- return sum;
- }
- int written = out.size() - zStruct.avail_out;
- stream->writeRawData(out.constData(), written);
- streampos += written;
- sum += written;
- } while (ret == Z_OK);
-
- ::deflateEnd(&zStruct);
-
- return sum;
- } else
-#endif
- {
- QByteArray arr;
- int sum = 0;
- while (!dev->atEnd()) {
- arr = dev->read(QPdfPage::chunkSize());
- stream->writeRawData(arr.constData(), arr.size());
- streampos += arr.size();
- sum += arr.size();
- }
- return sum;
- }
-}
-
-int QPdfEnginePrivate::writeCompressed(const char *src, int len)
-{
-#ifndef QT_NO_COMPRESS
- if(do_compress) {
- uLongf destLen = len + len/100 + 13; // zlib requirement
- Bytef* dest = new Bytef[destLen];
- if (Z_OK == ::compress(dest, &destLen, (const Bytef*) src, (uLongf)len)) {
- stream->writeRawData((const char*)dest, destLen);
- } else {
- qWarning("QPdfStream::writeCompressed: Error in compress()");
- destLen = 0;
- }
- delete [] dest;
- len = destLen;
- } else
-#endif
- {
- stream->writeRawData(src,len);
- }
- streampos += len;
- return len;
-}
-
-int QPdfEnginePrivate::writeImage(const QByteArray &data, int width, int height, int depth,
- int maskObject, int softMaskObject, bool dct)
-{
- int image = addXrefEntry(-1);
- xprintf("<<\n"
- "/Type /XObject\n"
- "/Subtype /Image\n"
- "/Width %d\n"
- "/Height %d\n", width, height);
-
- if (depth == 1) {
- xprintf("/ImageMask true\n"
- "/Decode [1 0]\n");
- } else {
- xprintf("/BitsPerComponent 8\n"
- "/ColorSpace %s\n", (depth == 32) ? "/DeviceRGB" : "/DeviceGray");
- }
- if (maskObject > 0)
- xprintf("/Mask %d 0 R\n", maskObject);
- if (softMaskObject > 0)
- xprintf("/SMask %d 0 R\n", softMaskObject);
-
- int lenobj = requestObject();
- xprintf("/Length %d 0 R\n", lenobj);
- if (interpolateImages)
- xprintf("/Interpolate true\n");
- int len = 0;
- if (dct) {
- //qDebug() << "DCT";
- xprintf("/Filter /DCTDecode\n>>\nstream\n");
- write(data);
- len = data.length();
- } else {
- if (do_compress)
- xprintf("/Filter /FlateDecode\n>>\nstream\n");
- else
- xprintf(">>\nstream\n");
- len = writeCompressed(data);
- }
- xprintf("endstream\n"
- "endobj\n");
- addXrefEntry(lenobj);
- xprintf("%d\n"
- "endobj\n", len);
- return image;
-}
-
-
-void QPdfEnginePrivate::writeHeader()
-{
- addXrefEntry(0,false);
-
- xprintf("%%PDF-1.4\n");
-
- writeInfo();
-
- catalog = addXrefEntry(-1);
- pageRoot = requestObject();
- xprintf("<<\n"
- "/Type /Catalog\n"
- "/Pages %d 0 R\n"
- ">>\n"
- "endobj\n", pageRoot);
-
- // graphics state
- graphicsState = addXrefEntry(-1);
- xprintf("<<\n"
- "/Type /ExtGState\n"
- "/SA true\n"
- "/SM 0.02\n"
- "/ca 1.0\n"
- "/CA 1.0\n"
- "/AIS false\n"
- "/SMask /None"
- ">>\n"
- "endobj\n");
-
- // color space for pattern
- patternColorSpace = addXrefEntry(-1);
- xprintf("[/Pattern /DeviceRGB]\n"
- "endobj\n");
-}
-
-void QPdfEnginePrivate::writeInfo()
-{
- info = addXrefEntry(-1);
- xprintf("<<\n/Title ");
- printString(title);
- xprintf("\n/Creator ");
- printString(creator);
- xprintf("\n/Producer ");
- printString(QString::fromLatin1("Qt " QT_VERSION_STR " (C) 2011 Nokia Corporation and/or its subsidiary(-ies)"));
- QDateTime now = QDateTime::currentDateTime().toUTC();
- QTime t = now.time();
- QDate d = now.date();
- xprintf("\n/CreationDate (D:%d%02d%02d%02d%02d%02d)\n",
- d.year(),
- d.month(),
- d.day(),
- t.hour(),
- t.minute(),
- t.second());
- xprintf(">>\n"
- "endobj\n");
-}
-
-void QPdfEnginePrivate::writePageRoot()
-{
- addXrefEntry(pageRoot);
-
- xprintf("<<\n"
- "/Type /Pages\n"
- "/Kids \n"
- "[\n");
- int size = pages.size();
- for (int i = 0; i < size; ++i)
- xprintf("%d 0 R\n", pages[i]);
- xprintf("]\n");
-
- //xprintf("/Group <</S /Transparency /I true /K false>>\n");
- xprintf("/Count %d\n", pages.size());
-
- xprintf("/ProcSet [/PDF /Text /ImageB /ImageC]\n"
- ">>\n"
- "endobj\n");
-}
-
-
-void QPdfEnginePrivate::embedFont(QFontSubset *font)
-{
- //qDebug() << "embedFont" << font->object_id;
- int fontObject = font->object_id;
- QByteArray fontData = font->toTruetype();
-#ifdef FONT_DUMP
- static int i = 0;
- QString fileName("font%1.ttf");
- fileName = fileName.arg(i++);
- QFile ff(fileName);
- ff.open(QFile::WriteOnly);
- ff.write(fontData);
- ff.close();
-#endif
-
- int fontDescriptor = requestObject();
- int fontstream = requestObject();
- int cidfont = requestObject();
- int toUnicode = requestObject();
-
- QFontEngine::Properties properties = font->fontEngine->properties();
-
- {
- qreal scale = 1000/properties.emSquare.toReal();
- addXrefEntry(fontDescriptor);
- QByteArray descriptor;
- QPdf::ByteStream s(&descriptor);
- s << "<< /Type /FontDescriptor\n"
- "/FontName /Q";
- int tag = fontDescriptor;
- for (int i = 0; i < 5; ++i) {
- s << (char)('A' + (tag % 26));
- tag /= 26;
- }
- s << '+' << properties.postscriptName << "\n"
- "/Flags " << 4 << "\n"
- "/FontBBox ["
- << properties.boundingBox.x()*scale
- << -(properties.boundingBox.y() + properties.boundingBox.height())*scale
- << (properties.boundingBox.x() + properties.boundingBox.width())*scale
- << -properties.boundingBox.y()*scale << "]\n"
- "/ItalicAngle " << properties.italicAngle.toReal() << "\n"
- "/Ascent " << properties.ascent.toReal()*scale << "\n"
- "/Descent " << -properties.descent.toReal()*scale << "\n"
- "/CapHeight " << properties.capHeight.toReal()*scale << "\n"
- "/StemV " << properties.lineWidth.toReal()*scale << "\n"
- "/FontFile2 " << fontstream << "0 R\n"
- ">> endobj\n";
- write(descriptor);
- }
- {
- addXrefEntry(fontstream);
- QByteArray header;
- QPdf::ByteStream s(&header);
-
- int length_object = requestObject();
- s << "<<\n"
- "/Length1 " << fontData.size() << "\n"
- "/Length " << length_object << "0 R\n";
- if (do_compress)
- s << "/Filter /FlateDecode\n";
- s << ">>\n"
- "stream\n";
- write(header);
- int len = writeCompressed(fontData);
- write("endstream\n"
- "endobj\n");
- addXrefEntry(length_object);
- xprintf("%d\n"
- "endobj\n", len);
- }
- {
- addXrefEntry(cidfont);
- QByteArray cid;
- QPdf::ByteStream s(&cid);
- s << "<< /Type /Font\n"
- "/Subtype /CIDFontType2\n"
- "/BaseFont /" << properties.postscriptName << "\n"
- "/CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >>\n"
- "/FontDescriptor " << fontDescriptor << "0 R\n"
- "/CIDToGIDMap /Identity\n"
- << font->widthArray() <<
- ">>\n"
- "endobj\n";
- write(cid);
- }
- {
- addXrefEntry(toUnicode);
- QByteArray touc = font->createToUnicodeMap();
- xprintf("<< /Length %d >>\n"
- "stream\n", touc.length());
- write(touc);
- write("endstream\n"
- "endobj\n");
- }
- {
- addXrefEntry(fontObject);
- QByteArray font;
- QPdf::ByteStream s(&font);
- s << "<< /Type /Font\n"
- "/Subtype /Type0\n"
- "/BaseFont /" << properties.postscriptName << "\n"
- "/Encoding /Identity-H\n"
- "/DescendantFonts [" << cidfont << "0 R]\n"
- "/ToUnicode " << toUnicode << "0 R"
- ">>\n"
- "endobj\n";
- write(font);
- }
-}
-
-
-void QPdfEnginePrivate::writeFonts()
-{
- for (QHash<QFontEngine::FaceId, QFontSubset *>::iterator it = fonts.begin(); it != fonts.end(); ++it) {
- embedFont(*it);
- delete *it;
- }
- fonts.clear();
-}
-
-void QPdfEnginePrivate::writePage()
-{
- if (pages.empty())
- return;
-
- *currentPage << "Q Q\n";
-
- uint pageStream = requestObject();
- uint pageStreamLength = requestObject();
- uint resources = requestObject();
- uint annots = requestObject();
-
- addXrefEntry(pages.last());
- xprintf("<<\n"
- "/Type /Page\n"
- "/Parent %d 0 R\n"
- "/Contents %d 0 R\n"
- "/Resources %d 0 R\n"
- "/Annots %d 0 R\n"
- "/MediaBox [0 0 %d %d]\n"
- ">>\n"
- "endobj\n",
- pageRoot, pageStream, resources, annots,
- // make sure we use the pagesize from when we started the page, since the user may have changed it
- currentPage->pageSize.width(), currentPage->pageSize.height());
-
- addXrefEntry(resources);
- xprintf("<<\n"
- "/ColorSpace <<\n"
- "/PCSp %d 0 R\n"
- "/CSp /DeviceRGB\n"
- "/CSpg /DeviceGray\n"
- ">>\n"
- "/ExtGState <<\n"
- "/GSa %d 0 R\n",
- patternColorSpace, graphicsState);
-
- for (int i = 0; i < currentPage->graphicStates.size(); ++i)
- xprintf("/GState%d %d 0 R\n", currentPage->graphicStates.at(i), currentPage->graphicStates.at(i));
- xprintf(">>\n");
-
- xprintf("/Pattern <<\n");
- for (int i = 0; i < currentPage->patterns.size(); ++i)
- xprintf("/Pat%d %d 0 R\n", currentPage->patterns.at(i), currentPage->patterns.at(i));
- xprintf(">>\n");
-
- xprintf("/Font <<\n");
- for (int i = 0; i < currentPage->fonts.size();++i)
- xprintf("/F%d %d 0 R\n", currentPage->fonts[i], currentPage->fonts[i]);
- xprintf(">>\n");
-
- xprintf("/XObject <<\n");
- for (int i = 0; i<currentPage->images.size(); ++i) {
- xprintf("/Im%d %d 0 R\n", currentPage->images.at(i), currentPage->images.at(i));
- }
- xprintf(">>\n");
-
- xprintf(">>\n"
- "endobj\n");
-
- addXrefEntry(annots);
- xprintf("[ ");
- for (int i = 0; i<currentPage->annotations.size(); ++i) {
- xprintf("%d 0 R ", currentPage->annotations.at(i));
- }
- xprintf("]\nendobj\n");
-
- addXrefEntry(pageStream);
- xprintf("<<\n"
- "/Length %d 0 R\n", pageStreamLength); // object number for stream length object
- if (do_compress)
- xprintf("/Filter /FlateDecode\n");
-
- xprintf(">>\n");
- xprintf("stream\n");
- QIODevice *content = currentPage->stream();
- int len = writeCompressed(content);
- xprintf("endstream\n"
- "endobj\n");
-
- addXrefEntry(pageStreamLength);
- xprintf("%d\nendobj\n",len);
-}
-
-void QPdfEnginePrivate::writeTail()
-{
- writePage();
- writeFonts();
- writePageRoot();
- addXrefEntry(xrefPositions.size(),false);
- xprintf("xref\n"
- "0 %d\n"
- "%010d 65535 f \n", xrefPositions.size()-1, xrefPositions[0]);
-
- for (int i = 1; i < xrefPositions.size()-1; ++i)
- xprintf("%010d 00000 n \n", xrefPositions[i]);
-
- xprintf("trailer\n"
- "<<\n"
- "/Size %d\n"
- "/Info %d 0 R\n"
- "/Root %d 0 R\n"
- ">>\n"
- "startxref\n%d\n"
- "%%%%EOF\n",
- xrefPositions.size()-1, info, catalog, xrefPositions.last());
-}
-
-int QPdfEnginePrivate::addXrefEntry(int object, bool printostr)
-{
- if (object < 0)
- object = requestObject();
-
- if (object>=xrefPositions.size())
- xrefPositions.resize(object+1);
-
- xrefPositions[object] = streampos;
- if (printostr)
- xprintf("%d 0 obj\n",object);
-
- return object;
-}
-
-void QPdfEnginePrivate::printString(const QString &string) {
- // The 'text string' type in PDF is encoded either as PDFDocEncoding, or
- // Unicode UTF-16 with a Unicode byte order mark as the first character
- // (0xfeff), with the high-order byte first.
- QByteArray array("(\xfe\xff");
- const ushort *utf16 = string.utf16();
-
- for (int i=0; i < string.size(); ++i) {
- char part[2] = {char((*(utf16 + i)) >> 8), char((*(utf16 + i)) & 0xff)};
- for(int j=0; j < 2; ++j) {
- if (part[j] == '(' || part[j] == ')' || part[j] == '\\')
- array.append('\\');
- array.append(part[j]);
- }
- }
- array.append(")");
- write(array);
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_PRINTER
diff --git a/src/gui/painting/qprintengine_pdf_p.h b/src/gui/painting/qprintengine_pdf_p.h
deleted file mode 100644
index ee77e1599c..0000000000
--- a/src/gui/painting/qprintengine_pdf_p.h
+++ /dev/null
@@ -1,195 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPRINTENGINE_PDF_P_H
-#define QPRINTENGINE_PDF_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "QtGui/qprintengine.h"
-
-#ifndef QT_NO_PRINTER
-#include "QtCore/qmap.h"
-#include "QtGui/qmatrix.h"
-#include "QtCore/qstring.h"
-#include "QtCore/qvector.h"
-#include "QtGui/qpaintengine.h"
-#include "QtGui/qpainterpath.h"
-#include "QtCore/qdatastream.h"
-
-#include "private/qfontengine_p.h"
-#include "private/qpdf_p.h"
-#include "private/qpaintengine_p.h"
-
-QT_BEGIN_NAMESPACE
-
-// #define USE_NATIVE_GRADIENTS
-
-class QImage;
-class QDataStream;
-class QPen;
-class QPointF;
-class QRegion;
-class QFile;
-class QPdfEngine;
-
-class QPdfEnginePrivate;
-
-class QPdfEngine : public QPdfBaseEngine
-{
- Q_DECLARE_PRIVATE(QPdfEngine)
-public:
- QPdfEngine(QPrinter::PrinterMode m);
- virtual ~QPdfEngine();
-
- // reimplementations QPaintEngine
- bool begin(QPaintDevice *pdev);
- bool end();
- void drawPixmap (const QRectF & rectangle, const QPixmap & pixmap, const QRectF & sr);
- void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr,
- Qt::ImageConversionFlags flags = Qt::AutoColor);
- void drawTiledPixmap (const QRectF & rectangle, const QPixmap & pixmap, const QPointF & point);
-
- Type type() const;
- // end reimplementations QPaintEngine
-
- // reimplementations QPrintEngine
- bool abort() {return false;}
- bool newPage();
- QPrinter::PrinterState printerState() const {return state;}
- // end reimplementations QPrintEngine
-
- void setBrush();
-
- // ### unused, should have something for this in QPrintEngine
- void setAuthor(const QString &author);
- QString author() const;
-
- void setDevice(QIODevice* dev);
-
-private:
- Q_DISABLE_COPY(QPdfEngine)
-
- QPrinter::PrinterState state;
-};
-
-class QPdfEnginePrivate : public QPdfBaseEnginePrivate
-{
- Q_DECLARE_PUBLIC(QPdfEngine)
-public:
- QPdfEnginePrivate(QPrinter::PrinterMode m);
- ~QPdfEnginePrivate();
-
- void newPage();
-
- int width() const {
- QRect r = paperRect();
- return qRound(r.width()*72./resolution);
- }
- int height() const {
- QRect r = paperRect();
- return qRound(r.height()*72./resolution);
- }
-
- void writeHeader();
- void writeTail();
-
- int addImage(const QImage &image, bool *bitmap, qint64 serial_no);
- int addConstantAlphaObject(int brushAlpha, int penAlpha = 255);
- int addBrushPattern(const QTransform &matrix, bool *specifyColor, int *gStateObject);
-
- void drawTextItem(const QPointF &p, const QTextItemInt &ti);
-
- QTransform pageMatrix() const;
-
-private:
- Q_DISABLE_COPY(QPdfEnginePrivate)
-
-#ifdef USE_NATIVE_GRADIENTS
- int gradientBrush(const QBrush &b, const QMatrix &matrix, int *gStateObject);
-#endif
-
- void writeInfo();
- void writePageRoot();
- void writeFonts();
- void embedFont(QFontSubset *font);
-
- QVector<int> xrefPositions;
- QDataStream* stream;
- int streampos;
-
- int writeImage(const QByteArray &data, int width, int height, int depth,
- int maskObject, int softMaskObject, bool dct = false);
- void writePage();
-
- int addXrefEntry(int object, bool printostr = true);
- void printString(const QString &string);
- void xprintf(const char* fmt, ...);
- inline void write(const QByteArray &data) {
- stream->writeRawData(data.constData(), data.size());
- streampos += data.size();
- }
-
- int writeCompressed(const char *src, int len);
- inline int writeCompressed(const QByteArray &data) { return writeCompressed(data.constData(), data.length()); }
- int writeCompressed(QIODevice *dev);
-
- // various PDF objects
- int pageRoot, catalog, info, graphicsState, patternColorSpace;
- QVector<uint> pages;
- QHash<qint64, uint> imageCache;
- QHash<QPair<uint, uint>, uint > alphaCache;
-};
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_PRINTER
-
-#endif // QPRINTENGINE_PDF_P_H
diff --git a/src/gui/painting/qprintengine_ps.cpp b/src/gui/painting/qprintengine_ps.cpp
deleted file mode 100644
index 89bec21f38..0000000000
--- a/src/gui/painting/qprintengine_ps.cpp
+++ /dev/null
@@ -1,972 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qplatformdefs.h"
-
-#include <private/qprintengine_ps_p.h>
-#include <private/qpainter_p.h>
-#include <private/qfontengine_p.h>
-#include <private/qpaintengine_p.h>
-#include <private/qpdf_p.h>
-
-#ifndef QT_NO_PRINTER
-
-#include "qprinter.h"
-#include "qpainter.h"
-#include "qapplication.h"
-#include "qpixmap.h"
-#include "qimage.h"
-#include "qdatetime.h"
-#include "qstring.h"
-#include "qbytearray.h"
-#include "qhash.h"
-#include "qbuffer.h"
-#include "qsettings.h"
-#include "qmap.h"
-#include "qbitmap.h"
-#include "qregion.h"
-#include "qimagewriter.h"
-#include <private/qpainterpath_p.h>
-#include <qdebug.h>
-#include <private/qdrawhelper_p.h>
-#include <private/qmutexpool_p.h>
-
-#ifndef Q_OS_WIN
-#include <unistd.h>
-#endif
-#include <stdlib.h>
-#include <limits.h>
-
-QT_BEGIN_NAMESPACE
-
-static bool qt_gen_epsf = false;
-
-void qt_generate_epsf(bool b)
-{
- qt_gen_epsf = b;
-}
-
-static const char *const ps_header =
-"/BD{bind def}bind def/d2{dup dup}BD/ED{exch def}BD/D0{0 ED}BD/F{setfont}BD\n"
-"/RL{rlineto}BD/CM{currentmatrix}BD/SM{setmatrix}BD/TR{translate}BD/SD\n"
-"{setdash}BD/SC{aload pop setrgbcolor}BD/CR{currentfile read pop}BD/i{index}\n"
-"BD/scs{setcolorspace}BD/DB{dict dup begin}BD/DE{end def}BD/ie{ifelse}BD/gs\n"
-"{gsave}BD/gr{grestore}BD/w{setlinewidth}BD/d{setdash}BD/J{setlinecap}BD/j\n"
-"{setlinejoin}BD/scn{3 array astore/BCol exch def}BD/SCN{3 array astore/PCol\n"
-"exch def}BD/cm{6 array astore concat}BD/m{moveto}BD/l{lineto}BD/c{curveto}BD\n"
-"/h{closepath}BD/W{clip}BD/W*{eoclip}BD/n{newpath}BD/q{gsave 10 dict begin}BD\n"
-"/Q{end grestore}BD/re{4 2 roll m dup 0 exch RL exch 0 RL 0 exch neg RL h}BD\n"
-"/S{gs PCol SC stroke gr n}BD/BT{gsave 10 dict begin/_m matrix CM def BCol\n"
-"SC}BD/ET{end grestore}BD/Tf{/_fs ED findfont[_fs 0 0 _fs 0 0]makefont F}BD\n"
-"/Tm{6 array astore concat}BD/Td{translate}BD/Tj{0 0 m show}BD/BDC{pop pop}BD\n"
-"/EMC{}BD/BSt 0 def/WFi false def/BCol[1 1 1]def/PCol[0 0 0]def/BDArr[0.94\n"
-"0.88 0.63 0.50 0.37 0.12 0.06]def/level3{/languagelevel where{pop\n"
-"languagelevel 3 ge}{false}ie}BD/QCIgray D0/QCIcolor D0/QCIindex D0/QCI{\n"
-"/colorimage where{pop false 3 colorimage}{exec/QCIcolor ED/QCIgray QCIcolor\n"
-"length 3 idiv string def 0 1 QCIcolor length 3 idiv 1 sub{/QCIindex ED/_x\n"
-"QCIindex 3 mul def QCIgray QCIindex QCIcolor _x get 0.30 mul QCIcolor _x 1\n"
-"add get 0.59 mul QCIcolor _x 2 add get 0.11 mul add add cvi put}for QCIgray\n"
-"image}ie}BD/di{gs TR 1 i 1 eq{pop pop false 3 1 roll BCol SC imagemask}{dup\n"
-"false ne{level3}{false}ie{/_ma ED 8 eq{/_dc[0 1]def/DeviceGray}{/_dc[0 1 0 1\n"
-"0 1]def/DeviceRGB}ie scs/_im ED/_mt ED/_h ED/_w ED <</ImageType 3/DataDict\n"
-"<</ImageType 1/Width _w/Height _h/ImageMatrix _mt/DataSource _im\n"
-"/BitsPerComponent 8/Decode _dc >>/MaskDict <</ImageType 1/Width _w/Height _h\n"
-"/ImageMatrix _mt/DataSource _ma/BitsPerComponent 1/Decode[0 1]>>\n"
-"/InterleaveType 3 >> image}{pop 8 4 1 roll 8 eq{image}{QCI}ie}ie}ie gr}BD/BF\n"
-"{gs BSt 1 eq{BCol SC WFi{fill}{eofill}ie}if BSt 2 ge BSt 8 le and{BDArr BSt\n"
-"2 sub get/_sc ED BCol{1. exch sub _sc mul 1. exch sub}forall 3 array astore\n"
-"SC WFi{fill}{eofill}ie}if BSt 9 ge BSt 14 le and{WFi{W}{W*}ie pathbbox 3 i 3\n"
-"i TR 4 2 roll 3 2 roll exch sub/_h ED sub/_w ED BCol SC 0.3 w n BSt 9 eq BSt\n"
-"11 eq or{0 4 _h{dup 0 exch m _w exch l}for}if BSt 10 eq BSt 11 eq or{0 4 _w{\n"
-"dup 0 m _h l}for}if BSt 12 eq BSt 14 eq or{_w _h gt{0 6 _w _h add{dup 0 m _h\n"
-"sub _h l}for}{0 6 _w _h add{dup 0 exch m _w sub _w exch l}for}ie}if BSt 13\n"
-"eq BSt 14 eq or{_w _h gt{0 6 _w _h add{dup _h m _h sub 0 l}for}{0 6 _w _h\n"
-"add{dup _w exch m _w sub 0 exch l}for}ie}if stroke}if BSt 15 eq{}if BSt 24\n"
-"eq{}if gr}BD/f{/WFi true def BF n}BD/f*{/WFi false def BF n}BD/B{/WFi true\n"
-"def BF S n}BD/B*{/WFi false def BF S n}BD/QI{/C save def pageinit q n}BD/QP{\n"
-"Q C restore showpage}BD/SPD{/setpagedevice where{<< 3 1 roll >>\n"
-"setpagedevice}{pop pop}ie}BD/T1AddMapping{10 dict begin/glyphs ED/fnt ED\n"
-"/current fnt/NumGlyphs get def/CMap fnt/CMap get def 0 1 glyphs length 1 sub\n"
-"{glyphs exch get/gn ED current dup 256 mod/min ED 256 idiv/maj ED CMap dup\n"
-"maj get dup null eq{pop 256 array 0 1 255{1 i exch/.notdef put}for}if dup\n"
-"min gn put maj exch put/current current 1 add def}for fnt/CMap CMap put fnt\n"
-"/NumGlyphs current put end}def/T1AddGlyphs{10 dict begin/glyphs ED/fnt ED\n"
-"/current fnt/NumGlyphs get def/CMap fnt/CMap get def/CharStrings fnt\n"
-"/CharStrings get def 0 1 glyphs length 2 idiv 1 sub{2 mul dup glyphs exch\n"
-"get/gn ED 1 add glyphs exch get/cs ED current dup 256 mod/min ED 256 idiv\n"
-"/maj ED CMap dup maj get dup null eq{pop 256 array 0 1 255{1 i exch/.notdef\n"
-"put}for}if dup min gn put maj exch put CharStrings gn cs put/current current\n"
-"1 add def}for fnt/CharStrings CharStrings put fnt/CMap CMap put fnt\n"
-"/NumGlyphs current put end}def/StringAdd{1 i length 1 i length add string 3\n"
-"1 roll 2 i 0 3 i putinterval 2 i 2 i length 2 i putinterval pop pop}def\n"
-"/T1Setup{10 dict begin dup/FontName ED (-Base) StringAdd cvx cvn/Font ED\n"
-"/MaxPage Font/NumGlyphs get 1 sub 256 idiv def/FDepVector MaxPage 1 add\n"
-"array def/Encoding MaxPage 1 add array def 0 1 MaxPage{dup Encoding exch dup\n"
-"put dup/Page ED FontName (-) StringAdd exch 20 string cvs StringAdd cvn Font\n"
-"0 dict copy d2/CMap get Page get/Encoding exch put definefont FDepVector\n"
-"exch Page exch put}for FontName cvn <</FontType 0/FMapType 2/FontMatrix[1 0\n"
-"0 1 0 0]/Encoding Encoding/FDepVector FDepVector >> definefont pop end}def\n";
-
-
-
-// ------------------------------End of static data ----------------------------------
-
-// make sure DSC comments are not longer than 255 chars per line.
-static QByteArray wrapDSC(const QByteArray &str)
-{
- QByteArray dsc = str.simplified();
- const int wrapAt = 254;
- QByteArray wrapped;
- if (dsc.length() < wrapAt)
- wrapped = dsc;
- else {
- wrapped = dsc.left(wrapAt);
- QByteArray tmp = dsc.mid(wrapAt);
- while (tmp.length() > wrapAt-3) {
- wrapped += "\n%%+" + tmp.left(wrapAt-3);
- tmp = tmp.mid(wrapAt-3);
- }
- wrapped += "\n%%+" + tmp;
- }
- return wrapped + '\n';
-}
-
-// ----------------------------- Internal class declarations -----------------------------
-
-QPSPrintEnginePrivate::QPSPrintEnginePrivate(QPrinter::PrinterMode m)
- : QPdfBaseEnginePrivate(m),
- printerState(QPrinter::Idle), hugeDocument(false), headerDone(false)
-{
- useAlphaEngine = true;
- postscript = true;
-
- firstPage = true;
-
-#ifndef QT_NO_SETTINGS
- QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
- settings.beginGroup(QLatin1String("Qt"));
- embedFonts = settings.value(QLatin1String("embedFonts"), true).toBool();
-#else
- embedFonts = true;
-#endif
-}
-
-QPSPrintEnginePrivate::~QPSPrintEnginePrivate()
-{
-}
-
-QT_BEGIN_INCLUDE_NAMESPACE
-#include <qdebug.h>
-QT_END_INCLUDE_NAMESPACE
-
-static void ps_r7(QPdf::ByteStream& stream, const char * s, int l)
-{
- int i = 0;
- uchar line[84];
- int col = 0;
-
- while(i < l) {
- line[col++] = s[i++];
- if (i < l - 1 && col >= 76) {
- line[col++] = '\n';
- line[col++] = '\0';
- stream << (const char *)line;
- col = 0;
- }
- }
- if (col > 0) {
- while((col&3) != 0)
- line[col++] = '%'; // use a comment as padding
- line[col++] = '\n';
- line[col++] = '\0';
- stream << (const char *)line;
- }
-}
-
-static QByteArray runlengthEncode(const QByteArray &input)
-{
- if (!input.length())
- return input;
-
- const char *data = input.constData();
-
- QByteArray out;
- int start = 0;
- char last = *data;
-
- enum State {
- Undef,
- Equal,
- Diff
- };
- State state = Undef;
-
- int i = 1;
- int written = 0;
- while (1) {
- bool flush = (i == input.size());
- if (!flush) {
- switch(state) {
- case Undef:
- state = (last == data[i]) ? Equal : Diff;
- break;
- case Equal:
- if (data[i] != last)
- flush = true;
- break;
- case Diff:
- if (data[i] == last) {
- --i;
- flush = true;
- }
- }
- }
- if (flush || i - start == 128) {
- int size = i - start;
- if (state == Equal) {
- out.append((char)(uchar)(257-size));
- out.append(last);
- written += size;
- } else {
- out.append((char)(uchar)size-1);
- while (start < i)
- out.append(data[start++]);
- written += size;
- }
- state = Undef;
- start = i;
- if (i == input.size())
- break;
- }
- last = data[i];
- ++i;
- };
- out.append((char)(uchar)128);
- return out;
-}
-
-enum format {
- Raw,
- Runlength,
- DCT
-};
-static const char *const filters[3] = {
- " ",
- "/RunLengthDecode filter ",
- "/DCTDecode filter "
-};
-
-static QByteArray compressHelper(const QImage &image, bool gray, int *format)
-{
- // we can't use premultiplied here
- QByteArray pixelData;
- int depth = image.depth();
-
- Q_ASSERT(image.format() != QImage::Format_ARGB32_Premultiplied);
-
- if (depth != 1 && !gray && QImageWriter::supportedImageFormats().contains("jpeg")) {
- QBuffer buffer(&pixelData);
- QImageWriter writer(&buffer, "jpeg");
- writer.setQuality(94);
- writer.write(image);
- *format = DCT;
- } else {
- int width = image.width();
- int height = image.height();
- int size = width*height;
-
- if (depth == 1)
- size = (width+7)/8*height;
- else if (!gray)
- size = size*3;
-
- pixelData.resize(size);
- uchar *pixel = (uchar *)pixelData.data();
- int i = 0;
- if (depth == 1) {
- QImage::Format format = image.format();
- memset(pixel, 0xff, size);
- for(int y=0; y < height; y++) {
- const uchar * s = image.scanLine(y);
- for(int x=0; x < width; x++) {
- // need to copy bit for bit...
- bool b = (format == QImage::Format_MonoLSB) ?
- (*(s + (x >> 3)) >> (x & 7)) & 1 :
- (*(s + (x >> 3)) << (x & 7)) & 0x80 ;
- if (b)
- pixel[i >> 3] ^= (0x80 >> (i & 7));
- i++;
- }
- // we need to align to 8 bit here
- i = (i+7) & 0xffffff8;
- }
- } else if (depth == 8) {
- for(int y=0; y < height; y++) {
- const uchar * s = image.scanLine(y);
- for(int x=0; x < width; x++) {
- QRgb rgb = image.color(s[x]);
- if (gray) {
- pixel[i] = (unsigned char) qGray(rgb);
- i++;
- } else {
- pixel[i] = (unsigned char) qRed(rgb);
- pixel[i+1] = (unsigned char) qGreen(rgb);
- pixel[i+2] = (unsigned char) qBlue(rgb);
- i += 3;
- }
- }
- }
- } else {
- for(int y=0; y < height; y++) {
- QRgb * s = (QRgb*)(image.scanLine(y));
- for(int x=0; x < width; x++) {
- QRgb rgb = (*s++);
- if (gray) {
- pixel[i] = (unsigned char) qGray(rgb);
- i++;
- } else {
- pixel[i] = (unsigned char) qRed(rgb);
- pixel[i+1] = (unsigned char) qGreen(rgb);
- pixel[i+2] = (unsigned char) qBlue(rgb);
- i += 3;
- }
- }
- }
- }
- *format = Raw;
- if (depth == 1) {
- pixelData = runlengthEncode(pixelData);
- *format = Runlength;
- }
- }
- QByteArray outarr = QPdf::ascii85Encode(pixelData);
- return outarr;
-}
-
-void QPSPrintEnginePrivate::drawImageHelper(qreal x, qreal y, qreal w, qreal h, const QImage &img,
- const QImage &mask, bool gray, qreal scaleX, qreal scaleY)
-{
- Q_UNUSED(h);
- Q_UNUSED(w);
- int width = img.width();
- int height = img.height();
-
- QByteArray out;
- int size = 0;
- const char *bits;
-
- if (!mask.isNull()) {
- int format;
- out = compressHelper(mask, true, &format);
- size = (width+7)/8*height;
- *currentPage << "/mask currentfile/ASCII85Decode filter"
- << filters[format]
- << size << " string readstring\n";
- ps_r7(*currentPage, out, out.size());
- *currentPage << " pop def\n";
- }
- if (img.depth() == 1) {
- size = (width+7)/8*height;
- bits = "1 ";
- } else if (gray) {
- size = width*height;
- bits = "8 ";
- } else {
- size = width*height*3;
- bits = "24 ";
- }
-
- int format;
- out = compressHelper(img, gray, &format);
- *currentPage << "/sl currentfile/ASCII85Decode filter"
- << filters[format]
- << size << " string readstring\n";
- ps_r7(*currentPage, out, out.size());
- *currentPage << " pop def\n";
- *currentPage << width << ' ' << height << '[' << scaleX << " 0 0 " << scaleY << " 0 0]sl "
- << bits << (!mask.isNull() ? "mask " : "false ")
- << x << ' ' << y << " di\n";
-}
-
-
-void QPSPrintEnginePrivate::drawImage(qreal x, qreal y, qreal w, qreal h,
- const QImage &image, const QImage &msk)
-{
- if (!w || !h || image.isNull()) return;
-
- QImage img(image);
- QImage mask(msk);
-
- if (image.format() == QImage::Format_ARGB32_Premultiplied)
- img = image.convertToFormat(QImage::Format_ARGB32);
-
- if (!msk.isNull() && msk.format() == QImage::Format_ARGB32_Premultiplied)
- mask = msk.convertToFormat(QImage::Format_ARGB32);
-
- int width = img.width();
- int height = img.height();
- qreal scaleX = width/w;
- qreal scaleY = height/h;
-
- bool gray = (colorMode == QPrinter::GrayScale) || img.allGray();
- int splitSize = 21830 * (gray ? 3 : 1);
- if (width * height > splitSize) { // 65535/3, tolerance for broken printers
- int images, subheight;
- images = (width * height + splitSize - 1) / splitSize;
- subheight = (height + images-1) / images;
- while (subheight * width > splitSize) {
- images++;
- subheight = (height + images-1) / images;
- }
- int suby = 0;
- const QImage constImg(img);
- const QImage constMask(mask);
- while(suby < height) {
- qreal subImageHeight = qMin(subheight, height-suby);
- const QImage subImage(constImg.scanLine(suby), width, subImageHeight,
- constImg.bytesPerLine(), constImg.format());
- const QImage subMask = mask.isNull() ? mask : QImage(constMask.scanLine(suby), width, subImageHeight,
- constMask.bytesPerLine(), constMask.format());
- drawImageHelper(x, y + suby/scaleY, w, subImageHeight/scaleY,
- subImage, subMask, gray, scaleX, scaleY);
- suby += subheight;
- }
- } else {
- drawImageHelper(x, y, width, height, img, mask, gray, scaleX, scaleY);
- }
-}
-
-void QPSPrintEnginePrivate::emitHeader(bool finished)
-{
- QPSPrintEngine *q = static_cast<QPSPrintEngine *>(q_ptr);
- QPrinter *printer = static_cast<QPrinter*>(pdev);
-
- if (creator.isEmpty())
- creator = QLatin1String("Qt " QT_VERSION_STR);
-
- QByteArray header;
- QPdf::ByteStream s(&header);
-
- qreal scale = 72. / ((qreal) q->metric(QPaintDevice::PdmDpiY));
- QRect pageRect = this->pageRect();
- QRect paperRect = this->paperRect();
- int mtop = pageRect.top() - paperRect.top();
- int mleft = pageRect.left() - paperRect.left();
- int mbottom = paperRect.bottom() - pageRect.bottom();
- int mright = paperRect.right() - pageRect.right();
- int width = pageRect.width();
- int height = pageRect.height();
- if (finished && pageCount == 1 && copies == 1 &&
- ((fullPage && qt_gen_epsf) || (outputFileName.endsWith(QLatin1String(".eps")))))
- {
- // According to the EPSF 3.0 spec it is required that the PS
- // version is PS-Adobe-3.0
- s << "%!PS-Adobe-3.0";
- if (!boundingBox.isValid())
- boundingBox.setRect(0, 0, width, height);
- if (orientation == QPrinter::Landscape) {
- if (!fullPage)
- boundingBox.translate(-mleft, -mtop);
- s << " EPSF-3.0\n%%BoundingBox: "
- << int((printer->height() - boundingBox.bottom())*scale) // llx
- << int((printer->width() - boundingBox.right())*scale - 1) // lly
- << int((printer->height() - boundingBox.top())*scale + 1) // urx
- << int((printer->width() - boundingBox.left())*scale); // ury
- } else {
- if (!fullPage)
- boundingBox.translate(mleft, -mtop);
- s << " EPSF-3.0\n%%BoundingBox: "
- << int((boundingBox.left())*scale)
- << int((printer->height() - boundingBox.bottom())*scale - 1)
- << int((boundingBox.right())*scale + 1)
- << int((printer->height() - boundingBox.top())*scale);
- }
- } else {
- s << "%!PS-Adobe-1.0";
- int w = width + (fullPage ? 0 : mleft + mright);
- int h = height + (fullPage ? 0 : mtop + mbottom);
- w = (int)(w*scale);
- h = (int)(h*scale);
- // set a bounding box according to the DSC
- if (orientation == QPrinter::Landscape)
- s << "\n%%BoundingBox: 0 0 " << h << w;
- else
- s << "\n%%BoundingBox: 0 0 " << w << h;
- }
- s << '\n' << wrapDSC("%%Creator: " + creator.toUtf8());
- if (!title.isEmpty())
- s << wrapDSC("%%Title: " + title.toUtf8());
-#ifndef QT_NO_DATESTRING
- s << "%%CreationDate: " << QDateTime::currentDateTime().toString().toUtf8();
-#endif
- s << "\n%%Orientation: ";
- if (orientation == QPrinter::Landscape)
- s << "Landscape";
- else
- s << "Portrait";
-
- s << "\n%%Pages: (atend)"
- "\n%%DocumentFonts: (atend)"
- "\n%%EndComments\n"
-
- "%%BeginProlog\n"
- "% Prolog copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).\n"
- "% You may copy this prolog in any way that is directly related to this document.\n"
- "% For other use of this prolog, see your licensing agreement for Qt.\n"
- << ps_header << '\n';
-
-
- s << "/pageinit {\n";
- if (!fullPage) {
- if (orientation == QPrinter::Portrait)
- s << mleft*scale << mbottom*scale << "translate\n";
- else
- s << mtop*scale << mleft*scale << "translate\n";
- }
- if (orientation == QPrinter::Portrait) {
- s << "% " << printer->widthMM() << '*' << printer->heightMM()
- << "mm (portrait)\n0 " << height*scale
- << "translate " << scale << '-' << scale << "scale } def\n";
- } else {
- s << "% " << printer->heightMM() << '*' << printer->widthMM()
- << " mm (landscape)\n 90 rotate " << scale << '-' << scale << "scale } def\n";
- }
- s << "%%EndProlog\n";
-
- outDevice->write(header);
- headerDone = true;
-}
-
-
-void QPSPrintEnginePrivate::emitPages()
-{
- if (!hugeDocument) {
- for (QHash<QFontEngine::FaceId, QFontSubset *>::const_iterator it = fonts.constBegin();
- it != fonts.constEnd(); ++it)
- outDevice->write((*it)->toType1());
- }
-
- QIODevice *content = buffer.stream();
- // Write the page contents in chunks.
- while (!content->atEnd()) {
- QByteArray buf = content->read(currentPage->chunkSize());
- if (!buf.isEmpty())
- outDevice->write(buf);
- }
- content = currentPage->stream();
- // Write the page contents in chunks.
- while (!content->atEnd()) {
- QByteArray buf = content->read(currentPage->chunkSize());
- if (!buf.isEmpty())
- outDevice->write(buf);
- }
- outDevice->write(trailer);
-
- buffer.clear();
- currentPage->clear();
- trailer = QByteArray();
- hugeDocument = true;
-}
-
-
-#ifdef Q_WS_QWS
-static const int max_in_memory_size = 2000000;
-#else
-static const int max_in_memory_size = 32000000;
-#endif
-
-void QPSPrintEnginePrivate::flushPage(bool last)
-{
- if (!last && currentPage->stream()->size() == 0)
- return;
-
- QPdf::ByteStream e(&trailer);
- buffer << "%%Page: "
- << pageCount << pageCount << "\n"
- "%%BeginPageSetup\n"
- "QI\n";
- if (hugeDocument) {
- for (QHash<QFontEngine::FaceId, QFontSubset *>::const_iterator it = fonts.constBegin();
- it != fonts.constEnd(); ++it) {
- if (currentPage->fonts.contains((*it)->object_id)) {
- if ((*it)->downloaded_glyphs == 0) {
- buffer << (*it)->toType1();
- (*it)->downloaded_glyphs = 0;
- } else {
- buffer << (*it)->type1AddedGlyphs();
- }
- }
- }
- }
- for (int i = 0; i < currentPage->fonts.size(); ++i)
- buffer << "(F" << QByteArray::number(currentPage->fonts.at(i)) << ") T1Setup\n";
-
- buffer << "%%EndPageSetup\nq\n";
- e << "\nQ QP\n";
- if (last || hugeDocument
- || buffer.stream()->size() + currentPage->stream()->size() > max_in_memory_size) {
-// qDebug("emiting header at page %d", pageCount);
- if (!headerDone)
- emitHeader(last);
- emitPages();
- } else {
- buffer << *currentPage << e;
- currentPage->clear();
- trailer.clear();
- }
- pageCount++;
-}
-
-// ================ PSPrinter class ========================
-
-QPSPrintEngine::QPSPrintEngine(QPrinter::PrinterMode m)
- : QPdfBaseEngine(*(new QPSPrintEnginePrivate(m)),
- PrimitiveTransform
- | PatternTransform
- | PixmapTransform
- | PainterPaths
- | PatternBrush
- )
-{
-}
-
-static void ignoreSigPipe(bool b)
-{
-#ifndef QT_NO_LPR
- static struct sigaction *users_sigpipe_handler = 0;
- static int lockCount = 0;
-
-#ifndef QT_NO_THREAD
- QMutexLocker locker(QMutexPool::globalInstanceGet(&users_sigpipe_handler));
-#endif
-
- if (b) {
- if (lockCount++ > 0)
- return;
-
- if (users_sigpipe_handler != 0)
- return; // already ignoring sigpipe
-
- users_sigpipe_handler = new struct sigaction;
- struct sigaction tmp_sigpipe_handler;
- tmp_sigpipe_handler.sa_handler = SIG_IGN;
- sigemptyset(&tmp_sigpipe_handler.sa_mask);
- tmp_sigpipe_handler.sa_flags = 0;
-
- if (sigaction(SIGPIPE, &tmp_sigpipe_handler, users_sigpipe_handler) == -1) {
- delete users_sigpipe_handler;
- users_sigpipe_handler = 0;
- }
- }
- else {
- if (--lockCount > 0)
- return;
-
- if (users_sigpipe_handler == 0)
- return; // not ignoring sigpipe
-
- if (sigaction(SIGPIPE, users_sigpipe_handler, 0) == -1)
- qWarning("QPSPrintEngine: Could not restore SIGPIPE handler");
-
- delete users_sigpipe_handler;
- users_sigpipe_handler = 0;
- }
-#else
- Q_UNUSED(b);
-#endif
-}
-QPSPrintEngine::~QPSPrintEngine()
-{
- Q_D(QPSPrintEngine);
- if (d->fd >= 0)
-#if defined(Q_OS_WIN) && defined(_MSC_VER) && _MSC_VER >= 1400
- ::_close(d->fd);
-#else
- ::close(d->fd);
-#endif
-}
-
-bool QPSPrintEngine::begin(QPaintDevice *pdev)
-{
- Q_D(QPSPrintEngine);
-
- if (d->fd >= 0)
- return true;
-
- if (d->useAlphaEngine) {
- QAlphaPaintEngine::begin(pdev);
- if (!continueCall())
- return true;
- }
-
- if(!QPdfBaseEngine::begin(pdev)) {
- d->printerState = QPrinter::Error;
- return false;
- }
-
- d->pageCount = 1; // initialize state
-
- d->pen = QPen(Qt::black);
- d->brush = Qt::NoBrush;
- d->hasPen = true;
- d->hasBrush = false;
- d->clipEnabled = false;
- d->allClipped = false;
- d->boundingBox = QRect();
- d->fontsUsed = "";
- d->hugeDocument = false;
- d->simplePen = false;
-
- setActive(true);
- d->printerState = QPrinter::Active;
-
- newPage();
-
- return true;
-}
-
-bool QPSPrintEngine::end()
-{
- Q_D(QPSPrintEngine);
-
- if (d->useAlphaEngine) {
- QAlphaPaintEngine::end();
- if (!continueCall())
- return true;
- }
-
- // we're writing to lp/lpr through a pipe, we don't want to crash with SIGPIPE
- // if lp/lpr dies
- ignoreSigPipe(true);
- d->flushPage(true);
- QByteArray trailer;
- QPdf::ByteStream s(&trailer);
- s << "%%Trailer\n"
- "%%Pages: " << d->pageCount - 1 << '\n' <<
- wrapDSC("%%DocumentFonts: " + d->fontsUsed);
- s << "%%EOF\n";
- d->outDevice->write(trailer);
-
- QPdfBaseEngine::end();
- ignoreSigPipe(false);
-
- d->firstPage = true;
- d->headerDone = false;
-
- setActive(false);
- d->printerState = QPrinter::Idle;
- d->pdev = 0;
-
- return true;
-}
-
-void QPSPrintEngine::setBrush()
-{
- Q_D(QPSPrintEngine);
-#if 0
- bool specifyColor;
- int gStateObject = 0;
- int patternObject = d->addBrushPattern(brush, d->stroker.matrix, brushOrigin, &specifyColor, &gStateObject);
-
- *d->currentPage << (patternObject ? "/PCSp cs " : "/CSp cs ");
- if (specifyColor) {
- QColor rgba = brush.color();
- *d->currentPage << rgba.redF()
- << rgba.greenF()
- << rgba.blueF();
- }
- if (patternObject)
- *d->currentPage << "/Pat" << patternObject;
- *d->currentPage << "scn\n";
-#endif
- QColor rgba = d->brush.color();
- if (d->colorMode == QPrinter::GrayScale) {
- qreal gray = qGray(rgba.rgba())/255.;
- *d->currentPage << gray << gray << gray;
- } else {
- *d->currentPage << rgba.redF()
- << rgba.greenF()
- << rgba.blueF();
- }
- *d->currentPage << "scn\n"
- << "/BSt " << d->brush.style() << "def\n";
-}
-
-void QPSPrintEngine::drawImageInternal(const QRectF &r, QImage image, bool bitmap)
-{
- Q_D(QPSPrintEngine);
- if (d->clipEnabled && d->allClipped)
- return;
- if (bitmap && image.depth() != 1)
- bitmap = false;
- QImage mask;
- // the below is not necessary since it's handled by the alpha
- // engine
- if (!d->useAlphaEngine && !bitmap) {
- if (image.format() == QImage::Format_Mono || image.format() == QImage::Format_MonoLSB)
- image = image.convertToFormat(QImage::Format_Indexed8);
- if (image.hasAlphaChannel()) {
- // get better alpha dithering
- int xscale = image.width();
- xscale *= xscale <= 800 ? 4 : (xscale <= 1600 ? 2 : 1);
- int yscale = image.height();
- yscale *= yscale <= 800 ? 4 : (yscale <= 1600 ? 2 : 1);
- image = image.scaled(xscale, yscale);
- mask = image.createAlphaMask(Qt::OrderedAlphaDither);
- }
- }
- *d->currentPage << "q\n";
- if(!d->simplePen)
- *d->currentPage << QPdf::generateMatrix(d->stroker.matrix);
- QBrush b = d->brush;
- if (image.depth() == 1) {
- // set current pen as brush
- d->brush = d->pen.brush();
- setBrush();
- }
- d->drawImage(r.x(), r.y(), r.width(), r.height(), image, mask);
- *d->currentPage << "Q\n";
- d->brush = b;
-}
-
-
-void QPSPrintEngine::drawImage(const QRectF &r, const QImage &img, const QRectF &sr,
- Qt::ImageConversionFlags)
-{
- Q_D(QPSPrintEngine);
-
- if (d->useAlphaEngine) {
- QAlphaPaintEngine::drawImage(r, img, sr);
- if (!continueCall())
- return;
- }
- QImage image = img.copy(sr.toRect());
- drawImageInternal(r, image, false);
-}
-
-void QPSPrintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr)
-{
- Q_D(QPSPrintEngine);
-
- if (d->useAlphaEngine) {
- QAlphaPaintEngine::drawPixmap(r, pm, sr);
- if (!continueCall())
- return;
- }
-
- QImage img = pm.copy(sr.toRect()).toImage();
- drawImageInternal(r, img, true);
-}
-
-void QPSPrintEngine::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &p)
-{
- Q_D(QPSPrintEngine);
-
- if (d->useAlphaEngine) {
- QAlphaPaintEngine::drawTiledPixmap(r, pixmap, p);
- if (!continueCall())
- return;
- }
-
- if (d->clipEnabled && d->allClipped)
- return;
- // ### Optimize implementation!
- qreal yPos = r.y();
- qreal yOff = p.y();
- while(yPos < r.y() + r.height()) {
- qreal drawH = pixmap.height() - yOff; // Cropping first row
- if (yPos + drawH > r.y() + r.height()) // Cropping last row
- drawH = r.y() + r.height() - yPos;
- qreal xPos = r.x();
- qreal xOff = p.x();
- while(xPos < r.x() + r.width()) {
- qreal drawW = pixmap.width() - xOff; // Cropping first column
- if (xPos + drawW > r.x() + r.width()) // Cropping last column
- drawW = r.x() + r.width() - xPos;
- // ########
- painter()->drawPixmap(QPointF(xPos, yPos).toPoint(), pixmap,
- QRectF(xOff, yOff, drawW, drawH).toRect());
- xPos += drawW;
- xOff = 0;
- }
- yPos += drawH;
- yOff = 0;
- }
-
-}
-
-bool QPSPrintEngine::newPage()
-{
- Q_D(QPSPrintEngine);
-
- if (!d->firstPage && d->useAlphaEngine)
- flushAndInit();
-
- // we're writing to lp/lpr through a pipe, we don't want to crash with SIGPIPE
- // if lp/lpr dies
- ignoreSigPipe(true);
- if (!d->firstPage)
- d->flushPage();
- d->firstPage = false;
- ignoreSigPipe(false);
-
- delete d->currentPage;
- d->currentPage = new QPdfPage;
- d->stroker.stream = d->currentPage;
-
- return QPdfBaseEngine::newPage();
-}
-
-bool QPSPrintEngine::abort()
-{
- // ### abort!?!
- return false;
-}
-
-QPrinter::PrinterState QPSPrintEngine::printerState() const
-{
- Q_D(const QPSPrintEngine);
- return d->printerState;
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_PRINTER
diff --git a/src/gui/painting/qprintengine_ps_p.h b/src/gui/painting/qprintengine_ps_p.h
deleted file mode 100644
index e5203c1041..0000000000
--- a/src/gui/painting/qprintengine_ps_p.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPRINTENGINE_PS_P_H
-#define QPRINTENGINE_PS_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of qpsprinter.cpp and qprinter_x11.cpp.
-// This header file may change from version to version without notice,
-// or even be removed.
-//
-// We mean it.
-//
-
-#ifndef QT_NO_PRINTER
-
-#include "private/qpdf_p.h"
-#include "qplatformdefs.h"
-#include "QtCore/qlibrary.h"
-#include "QtCore/qstringlist.h"
-#include "QtCore/qhash.h"
-#include "QtCore/qabstractitemmodel.h"
-
-QT_BEGIN_NAMESPACE
-
-class QPrinter;
-class QPSPrintEnginePrivate;
-
-class QPSPrintEngine : public QPdfBaseEngine
-{
- Q_DECLARE_PRIVATE(QPSPrintEngine)
-public:
- // QPrinter uses these
- explicit QPSPrintEngine(QPrinter::PrinterMode m);
- ~QPSPrintEngine();
-
-
- virtual bool begin(QPaintDevice *pdev);
- virtual bool end();
-
- void setBrush();
-
- virtual void drawImage(const QRectF &r, const QImage &img, const QRectF &sr, Qt::ImageConversionFlags);
- virtual void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr);
- virtual void drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s);
-
- virtual void drawImageInternal(const QRectF &r, QImage img, bool bitmap);
-
- virtual QPaintEngine::Type type() const { return QPaintEngine::PostScript; }
-
- virtual bool newPage();
- virtual bool abort();
-
- virtual QPrinter::PrinterState printerState() const;
-
- virtual Qt::HANDLE handle() const { return 0; }
-
-private:
- Q_DISABLE_COPY(QPSPrintEngine)
-};
-
-class QPSPrintEnginePrivate : public QPdfBaseEnginePrivate {
-public:
- QPSPrintEnginePrivate(QPrinter::PrinterMode m);
- ~QPSPrintEnginePrivate();
-
- void emitHeader(bool finished);
- void emitPages();
- void drawImage(qreal x, qreal y, qreal w, qreal h, const QImage &img, const QImage &mask);
- void flushPage(bool last = false);
- void drawImageHelper(qreal x, qreal y, qreal w, qreal h, const QImage &img, const QImage &mask,
- bool gray, qreal scaleX, qreal scaleY);
-
- int pageCount;
- bool epsf;
- QByteArray fontsUsed;
-
- // stores the descriptions of the n first pages.
- QPdf::ByteStream buffer;
- QByteArray trailer;
-
- bool firstPage;
-
- QRect boundingBox;
-
- QPrinter::PrinterState printerState;
- bool hugeDocument;
- bool headerDone;
-};
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_PRINTER
-
-#endif // QPRINTENGINE_PS_P_H
diff --git a/src/gui/painting/qprintengine_qws.cpp b/src/gui/painting/qprintengine_qws.cpp
deleted file mode 100644
index 7b759c83c2..0000000000
--- a/src/gui/painting/qprintengine_qws.cpp
+++ /dev/null
@@ -1,886 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <private/qprintengine_qws_p.h>
-
-#ifndef QT_NO_PRINTER
-
-#include <private/qpaintengine_raster_p.h>
-#include <qimage.h>
-#include <qfile.h>
-#include <qdebug.h>
-#include <QCopChannel>
-
-QT_BEGIN_NAMESPACE
-
-#define MM(n) int((n * 720 + 127) / 254)
-#define IN(n) int(n * 72)
-
-extern QSizeF qt_paperSizeToQSizeF(QPrinter::PaperSize size);
-
-QtopiaPrintEngine::QtopiaPrintEngine(QPrinter::PrinterMode mode)
- : QPaintEngine(*(new QtopiaPrintEnginePrivate( mode )))
-{
- d_func()->initialize();
-}
-
-bool QtopiaPrintEngine::begin(QPaintDevice *)
-{
- Q_D(QtopiaPrintEngine);
- Q_ASSERT_X(d->printerState == QPrinter::Idle, "QtopiaPrintEngine", "printer already active");
-
- // Create a new off-screen monochrome image to handle the drawing process.
- QSize size = paperRect().size();
- if ( d->pageImage )
- delete d->pageImage;
- d->pageImage = new QImage( size, QImage::Format_RGB32 );
- if ( !(d->pageImage) )
- return false;
-
- // Recreate the paint engine on the new image.
- delete d->_paintEngine;
- d->_paintEngine = 0;
- d->paintEngine()->state = state;
-
- // Begin the paint process on the image.
- if (!d->paintEngine()->begin(d->pageImage))
- return false;
-
- // Clear the first page to all-white.
- clearPage();
-
- // Clear the print buffer and output the image header.
- d->buffer.clear();
- d->writeG3FaxHeader();
-
- // The print engine is currently active.
- d->printerState = QPrinter::Active;
- return true;
-}
-
-bool QtopiaPrintEngine::end()
-{
- Q_D(QtopiaPrintEngine);
-
- d->paintEngine()->end();
-
- // Flush the last page.
- flushPage();
-
- // Output the fax data to a file (TODO: send to the print queuing daemon).
- QString filename;
- if ( !d->outputFileName.isEmpty() )
- filename = QString::fromLocal8Bit(qgetenv("HOME").constData()) + QLatin1String("/Documents/") + d->outputFileName;
- else
- filename = QString::fromLocal8Bit(qgetenv("HOME").constData()) + QLatin1String("/tmp/qwsfax.tiff");
-
- setProperty(QPrintEngine::PPK_OutputFileName, filename);
- QFile file( filename );
- if ( !file.open( QIODevice::WriteOnly | QIODevice::Truncate ) ) {
- qDebug( "Failed to open %s for printer output",
- filename.toLatin1().constData() );
- } else {
- file.write( d->buffer.data() );
- file.close();
- }
-
- // Free up the memory for the image buffer.
- d->buffer.clear();
-
- // Finalize the print job.
- d->printerState = QPrinter::Idle;
-
- // call qcop service
- QMap<QString, QVariant> map;
- for ( int x = 0; x <= QPrintEngine::PPK_Duplex; x++ )
- map.insert( QString::number(x), property((QPrintEngine::PrintEnginePropertyKey)(x)));
- QVariant variant(map);
-
- QByteArray data;
- QDataStream out(&data, QIODevice::WriteOnly);
- out << variant;
- QCopChannel::send(QLatin1String("QPE/Service/Print"), QLatin1String("print(QVariant)"), data);
-
- return true;
-}
-
-QPaintEngine *QtopiaPrintEngine::paintEngine() const
-{
- return const_cast<QtopiaPrintEnginePrivate *>(d_func())->paintEngine();
-}
-
-void QtopiaPrintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr)
-{
- Q_D(QtopiaPrintEngine);
- Q_ASSERT(d->printerState == QPrinter::Active);
- d->paintEngine()->drawPixmap(r, pm, sr);
-}
-
-void QtopiaPrintEngine::drawTextItem(const QPointF &p, const QTextItem &ti)
-{
- Q_D(QtopiaPrintEngine);
- Q_ASSERT(d->printerState == QPrinter::Active);
- d->paintEngine()->drawTextItem(p, ti);
-}
-
-void QtopiaPrintEngine::updateState(const QPaintEngineState &state)
-{
- Q_D(QtopiaPrintEngine);
- d->paintEngine()->updateState(state);
-}
-
-QRect QtopiaPrintEngine::paperRect() const
-{
- QSizeF s = qt_paperSizeToQSizeF(d_func()->paperSize);
- s.rwidth() = MM(s.width());
- s.rheight() = MM(s.height());
- int w = qRound(s.width()*d_func()->resolution/72.);
- int h = qRound(s.height()*d_func()->resolution/72.);
- if (d_func()->orientation == QPrinter::Portrait)
- return QRect(0, 0, w, h);
- else
- return QRect(0, 0, h, w);
-}
-
-QRect QtopiaPrintEngine::pageRect() const
-{
- QRect r = paperRect();
- if (d_func()->fullPage)
- return r;
- // would be nice to get better margins than this.
- return QRect(d_func()->resolution/3, d_func()->resolution/3, r.width()-2*d_func()->resolution/3, r.height()-2*d_func()->resolution/3);
-}
-
-bool QtopiaPrintEngine::newPage()
-{
- flushPage();
- clearPage();
- ++(d_func()->pageNumber);
- return true;
-}
-
-bool QtopiaPrintEngine::abort()
-{
- return false;
-}
-
-QPrinter::PrinterState QtopiaPrintEngine::printerState() const
-{
- return d_func()->printerState;
-}
-
-int QtopiaPrintEngine::metric(QPaintDevice::PaintDeviceMetric metricType) const
-{
- int val;
- QRect r = d_func()->fullPage ? paperRect() : pageRect();
- switch (metricType) {
- case QPaintDevice::PdmWidth:
- val = r.width();
- break;
- case QPaintDevice::PdmHeight:
- val = r.height();
- break;
- case QPaintDevice::PdmDpiX:
- val = d_func()->resolution;
- break;
- case QPaintDevice::PdmDpiY:
- val = d_func()->resolution;
- break;
- case QPaintDevice::PdmPhysicalDpiX:
- case QPaintDevice::PdmPhysicalDpiY:
- val = QT_QWS_PRINTER_DEFAULT_DPI;
- break;
- case QPaintDevice::PdmWidthMM:
- val = qRound(r.width()*25.4/d_func()->resolution);
- break;
- case QPaintDevice::PdmHeightMM:
- val = qRound(r.height()*25.4/d_func()->resolution);
- break;
- case QPaintDevice::PdmNumColors:
- val = 2;
- break;
- case QPaintDevice::PdmDepth:
- val = 1;
- break;
- default:
- qWarning("QtopiaPrintEngine::metric: Invalid metric command");
- return 0;
- }
- return val;
-}
-
-QVariant QtopiaPrintEngine::property(PrintEnginePropertyKey key) const
-{
- Q_D(const QtopiaPrintEngine);
- QVariant ret;
-
- switch (key) {
- case PPK_CollateCopies:
- ret = d->collateCopies;
- break;
- case PPK_ColorMode:
- ret = d->colorMode;
- break;
- case PPK_Creator:
- ret = d->creator;
- break;
- case PPK_DocumentName:
- ret = d->docName;
- break;
- case PPK_FullPage:
- ret = d->fullPage;
- break;
- case PPK_CopyCount: // fallthrough
- case PPK_NumberOfCopies:
- ret = d->numCopies;
- break;
- case PPK_SupportsMultipleCopies:
- ret = false;
- break;
- case PPK_Orientation:
- ret = d->orientation;
- break;
- case PPK_OutputFileName:
- ret = d->outputFileName;
- break;
- case PPK_PageOrder:
- ret = d->pageOrder;
- break;
- case PPK_PageRect:
- ret = pageRect();
- break;
- case PPK_PaperSize:
- ret = d->paperSize;
- break;
- case PPK_PaperRect:
- ret = paperRect();
- break;
- case PPK_PaperSource:
- ret = d->paperSource;
- break;
- case PPK_PrinterName:
- ret = d->printerName;
- break;
- case PPK_PrinterProgram:
- ret = d->printProgram;
- break;
- case PPK_Resolution:
- ret = d->resolution;
- break;
- case PPK_SupportedResolutions:
- ret = QList<QVariant>() << QT_QWS_PRINTER_DEFAULT_DPI;
- break;
- default:
- break;
- }
- return ret;
-}
-
-void QtopiaPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &value)
-{
- Q_D(QtopiaPrintEngine);
- switch (key) {
- case PPK_CollateCopies:
- d->collateCopies = value.toBool();
- break;
- case PPK_ColorMode:
- d->colorMode = QPrinter::ColorMode(value.toInt());
- break;
- case PPK_Creator:
- d->creator = value.toString();
- break;
- case PPK_DocumentName:
- d->docName = value.toString();
- break;
- case PPK_FullPage:
- d->fullPage = value.toBool();
- break;
- case PPK_CopyCount: // fallthrough
- case PPK_NumberOfCopies:
- d->numCopies = value.toInt();
- break;
- case PPK_Orientation:
- d->orientation = QPrinter::Orientation(value.toInt());
- break;
- case PPK_OutputFileName:
- d->outputFileName = value.toString();
- break;
- case PPK_PageOrder:
- d->pageOrder = QPrinter::PageOrder(value.toInt());
- break;
- case PPK_PaperSize:
- d->paperSize = QPrinter::PaperSize(value.toInt());
- break;
- case PPK_PaperSource:
- d->paperSource = QPrinter::PaperSource(value.toInt());
- case PPK_PrinterName:
- d->printerName = value.toString();
- break;
- case PPK_PrinterProgram:
- d->printProgram = value.toString();
- break;
- case PPK_Resolution:
- d->resolution = value.toInt();
- break;
- default:
- break;
- }
-}
-
-void QtopiaPrintEngine::clearPage()
-{
- d_func()->pageImage->fill(QColor(255, 255, 255).rgb());
-}
-
-void QtopiaPrintEngine::flushPage()
-{
- d_func()->writeG3FaxPage();
-}
-
-QtopiaPrintEnginePrivate::~QtopiaPrintEnginePrivate()
-{
- if ( pageImage )
- delete pageImage;
-}
-
-void QtopiaPrintEnginePrivate::initialize()
-{
- _paintEngine = 0;
-}
-
-QPaintEngine *QtopiaPrintEnginePrivate::paintEngine()
-{
- if (!_paintEngine)
- _paintEngine = new QRasterPaintEngine(pageImage);
- return _paintEngine;
-}
-
-void QtopiaPrintEnginePrivate::writeG3FaxHeader()
-{
- // Write the TIFF file magic number (little-endian TIFF).
- buffer.append( (char)'I' );
- buffer.append( (char)'I' );
- buffer.append( (char)42 );
- buffer.append( (char)0 );
-
- // Leave a place-holder for the IFD offset of the first page.
- ifdPatch = buffer.size();
- buffer.append( (int)0 );
-}
-
-// Tag values, from RFC 2301.
-#define TIFF_IFD_NEW_SUB_FILE_TYPE 254
-#define TIFF_IFD_IMAGE_WIDTH 256
-#define TIFF_IFD_IMAGE_LENGTH 257
-#define TIFF_IFD_BITS_PER_SAMPLE 258
-#define TIFF_IFD_COMPRESSION 259
-#define TIFF_IFD_PHOTOMETRIC_INTERP 262
-#define TIFF_IFD_FILL_ORDER 266
-#define TIFF_IFD_STRIP_OFFSETS 273
-#define TIFF_IFD_ORIENTATION 274
-#define TIFF_IFD_SAMPLES_PER_PIXEL 277
-#define TIFF_IFD_ROWS_PER_STRIP 278
-#define TIFF_IFD_STRIP_BYTE_COUNTS 279
-#define TIFF_IFD_X_RESOLUTION 282
-#define TIFF_IFD_Y_RESOLUTION 283
-#define TIFF_IFD_PLANAR_CONFIG 284
-#define TIFF_IFD_T4_OPTIONS 292
-#define TIFF_IFD_RESOLUTION_UNIT 296
-#define TIFF_IFD_PAGE_NUMBER 297
-#define TIFF_IFD_CLEAN_FAX_DATA 327
-
-// IFD type values.
-#define TIFF_TYPE_SHORT 3
-#define TIFF_TYPE_LONG 4
-#define TIFF_TYPE_RATIONAL 5
-
-// Construct a SHORT pair from two values.
-#define TIFF_SHORT_PAIR(a,b) (((a) & 0xFFFF) | ((b) << 16))
-
-// Width of a FAX page in pixels, in the baseline specification from RFC 2301.
-// This must be hard-wired, as per the RFC. We truncate any pixels that
-// are beyond this limit, or pad lines to reach this limit.
-#define TIFF_FAX_WIDTH 1728
-
-void QtopiaPrintEnginePrivate::writeG3FaxPage()
-{
- // Pad the image file to a word boundary, just in case.
- buffer.pad();
-
- // Back-patch the IFD link for the previous page.
- buffer.patch( ifdPatch, buffer.size() );
-
- // Output the contents of the IFD for this page (these must be
- // in ascending order of tag value).
- buffer.append( (short)19 ); // Number of IFD entries.
- writeG3IFDEntry( TIFF_IFD_NEW_SUB_FILE_TYPE, TIFF_TYPE_LONG, 1, 2 );
- writeG3IFDEntry( TIFF_IFD_IMAGE_WIDTH, TIFF_TYPE_LONG, 1, TIFF_FAX_WIDTH );
- writeG3IFDEntry
- ( TIFF_IFD_IMAGE_LENGTH, TIFF_TYPE_LONG, 1, pageImage->height() );
- writeG3IFDEntry( TIFF_IFD_BITS_PER_SAMPLE, TIFF_TYPE_SHORT, 1, 1 );
- writeG3IFDEntry( TIFF_IFD_COMPRESSION, TIFF_TYPE_SHORT, 1, 3 );
- writeG3IFDEntry( TIFF_IFD_PHOTOMETRIC_INTERP, TIFF_TYPE_SHORT, 1, 0 );
- writeG3IFDEntry( TIFF_IFD_FILL_ORDER, TIFF_TYPE_SHORT, 1, 1 );
- int stripOffsets =
- writeG3IFDEntry( TIFF_IFD_STRIP_OFFSETS, TIFF_TYPE_LONG, 1, 0 );
- writeG3IFDEntry( TIFF_IFD_ORIENTATION, TIFF_TYPE_SHORT, 1, 1 );
- writeG3IFDEntry( TIFF_IFD_SAMPLES_PER_PIXEL, TIFF_TYPE_SHORT, 1, 1 );
- writeG3IFDEntry
- ( TIFF_IFD_ROWS_PER_STRIP, TIFF_TYPE_LONG, 1, pageImage->height() );
- int stripBytes = writeG3IFDEntry
- ( TIFF_IFD_STRIP_BYTE_COUNTS, TIFF_TYPE_LONG, 1, 0 );
- int xres =
- writeG3IFDEntry( TIFF_IFD_X_RESOLUTION, TIFF_TYPE_RATIONAL, 1, 0 );
- int yres =
- writeG3IFDEntry( TIFF_IFD_Y_RESOLUTION, TIFF_TYPE_RATIONAL, 1, 0 );
- writeG3IFDEntry( TIFF_IFD_PLANAR_CONFIG, TIFF_TYPE_SHORT, 1, 1 );
- writeG3IFDEntry( TIFF_IFD_T4_OPTIONS, TIFF_TYPE_LONG, 1, 2 );
- writeG3IFDEntry( TIFF_IFD_RESOLUTION_UNIT, TIFF_TYPE_SHORT, 1, 2 );
- writeG3IFDEntry( TIFF_IFD_PAGE_NUMBER, TIFF_TYPE_SHORT, 2,
- TIFF_SHORT_PAIR( pageNumber, 0 ) );
- writeG3IFDEntry( TIFF_IFD_CLEAN_FAX_DATA, TIFF_TYPE_SHORT, 1, 0 );
-
- // Leave a place-holder for the IFD offset of the next page.
- ifdPatch = buffer.size();
- buffer.append( (int)0 );
-
- // Output the X and Y resolutions, as rational values (usually 200/1).
- buffer.patch( xres, buffer.size() );
- buffer.append( (int)resolution );
- buffer.append( (int)1 );
- buffer.patch( yres, buffer.size() );
- buffer.append( (int)resolution );
- buffer.append( (int)1 );
-
- // We are now at the start of the image data - set the strip offset.
- int start = buffer.size();
- buffer.patch( stripOffsets, start );
-
- // Output the image data.
- int width = pageImage->width();
- QImage::Format imageFormat = pageImage->format();
- for ( int y = 0; y < pageImage->height(); ++y ) {
- unsigned char *scan = pageImage->scanLine(y);
- int prev, pixel, len;
- writeG3EOL();
- prev = 0;
- len = 0;
-
- uint currentColor = qRgb(255, 255, 255); // start with white
-
- for ( int x = 0; x < width && x < TIFF_FAX_WIDTH; ++x ) {
- if ( imageFormat == QImage::Format_RGB32 ) {
- // read color of the current pixel
- uint *p = (uint *)scan + x;
-
- if ( *p == currentColor ) { // if it is the same color
- len++; // imcrement length
- } else { // otherwise write color into the buffer
- if ( len > 0 ) {
- if ( currentColor == qRgb(0, 0, 0) )
- writeG3BlackRun( len );
- else
- writeG3WhiteRun( len );
- }
- // initialise length and color;
- len = 1;
- currentColor = *p;
- }
- } else if ( imageFormat == QImage::Format_Mono ) {
- pixel = ((scan[x >> 3] & (1 << (x & 7))) != 0);
- if ( pixel != prev ) {
- if ( prev ) {
- writeG3BlackRun( len );
- } else {
- writeG3WhiteRun( len );
- }
- prev = pixel;
- len = 1;
- } else {
- ++len;
- }
- }
- }
-
- if ( imageFormat == QImage::Format_RGB32 ) {
- // Output the last run on the line, and pad to TIFF_FAX_WIDTH.
- if ( len != 0 ) {
- if ( currentColor == qRgb(0, 0, 0) )
- writeG3BlackRun( len );
- else
- writeG3WhiteRun( len );
- }
- if ( width < TIFF_FAX_WIDTH )
- writeG3WhiteRun( TIFF_FAX_WIDTH - width );
- } else if ( imageFormat == QImage::Format_Mono ) {
- if ( len != 0 ) {
- if ( prev ) {
- writeG3BlackRun( len );
- if ( width < TIFF_FAX_WIDTH ) {
- writeG3WhiteRun( TIFF_FAX_WIDTH - width );
- }
- } else {
- if ( width < TIFF_FAX_WIDTH ) {
- writeG3WhiteRun( len + ( TIFF_FAX_WIDTH - width ) );
- } else {
- writeG3WhiteRun( len );
- }
- }
- }
- }
- }
-
- // Flush the last partial byte, which is padded with zero fill bits.
- if ( partialBits > 0 ) {
- buffer.append( (char)( partialByte << ( 8 - partialBits ) ) );
- partialByte = 0;
- partialBits = 0;
- }
-
- // end of page add six EOLs
- for ( int i = 0; i < 6; i++ )
- writeG3EOL();
-
- // Update the byte count for the image data strip.
- buffer.patch( stripBytes, buffer.size() - start );
-}
-
-int QtopiaPrintEnginePrivate::writeG3IFDEntry
- ( int tag, int type, int count, int value )
-{
- buffer.append( (short)tag );
- buffer.append( (short)type );
- buffer.append( count );
- buffer.append( value );
- return buffer.size() - 4; // Offset of the value for back-patching.
-}
-
-void QtopiaPrintEnginePrivate::writeG3Code( int code, int bits )
-{
- partialByte = ( ( partialByte << bits ) | code );
- partialBits += bits;
- while ( partialBits >= 8 ) {
- partialBits -= 8;
- buffer.append( (char)( partialByte >> partialBits ) );
- }
-}
-
-void QtopiaPrintEnginePrivate::writeG3WhiteRun( int len )
-{
- static struct {
- unsigned short code;
- unsigned short bits;
- } whiteCodes[64 + 27] = {
- {0x0035, 8}, // 0
- {0x0007, 6},
- {0x0007, 4},
- {0x0008, 4},
- {0x000B, 4},
- {0x000C, 4},
- {0x000E, 4},
- {0x000F, 4},
- {0x0013, 5}, // 8
- {0x0014, 5},
- {0x0007, 5},
- {0x0008, 5},
- {0x0008, 6},
- {0x0003, 6},
- {0x0034, 6},
- {0x0035, 6},
- {0x002A, 6}, // 16
- {0x002B, 6},
- {0x0027, 7},
- {0x000C, 7},
- {0x0008, 7},
- {0x0017, 7},
- {0x0003, 7},
- {0x0004, 7},
- {0x0028, 7}, // 24
- {0x002B, 7},
- {0x0013, 7},
- {0x0024, 7},
- {0x0018, 7},
- {0x0002, 8},
- {0x0003, 8},
- {0x001A, 8},
- {0x001B, 8}, // 32
- {0x0012, 8},
- {0x0013, 8},
- {0x0014, 8},
- {0x0015, 8},
- {0x0016, 8},
- {0x0017, 8},
- {0x0028, 8},
- {0x0029, 8}, // 40
- {0x002A, 8},
- {0x002B, 8},
- {0x002C, 8},
- {0x002D, 8},
- {0x0004, 8},
- {0x0005, 8},
- {0x000A, 8},
- {0x000B, 8}, // 48
- {0x0052, 8},
- {0x0053, 8},
- {0x0054, 8},
- {0x0055, 8},
- {0x0024, 8},
- {0x0025, 8},
- {0x0058, 8},
- {0x0059, 8}, // 56
- {0x005A, 8},
- {0x005B, 8},
- {0x004A, 8},
- {0x004B, 8},
- {0x0032, 8},
- {0x0033, 8},
- {0x0034, 8},
- {0x001B, 5}, // Make up codes: 64
- {0x0012, 5}, // 128
- {0x0017, 6}, // 192
- {0x0037, 7}, // 256
- {0x0036, 8}, // 320
- {0x0037, 8}, // 384
- {0x0064, 8}, // 448
- {0x0065, 8}, // 512
- {0x0068, 8}, // 576
- {0x0067, 8}, // 640
- {0x00CC, 9}, // 704
- {0x00CD, 9}, // 768
- {0x00D2, 9}, // 832
- {0x00D3, 9}, // 896
- {0x00D4, 9}, // 960
- {0x00D5, 9}, // 1024
- {0x00D6, 9}, // 1088
- {0x00D7, 9}, // 1152
- {0x00D8, 9}, // 1216
- {0x00D9, 9}, // 1280
- {0x00DA, 9}, // 1344
- {0x00DB, 9}, // 1408
- {0x0098, 9}, // 1472
- {0x0099, 9}, // 1536
- {0x009A, 9}, // 1600
- {0x0018, 6}, // 1664
- {0x009B, 9}, // 1728
- };
- if ( len >= 64 ) {
- int index = 63 + (len >> 6);
- writeG3Code( whiteCodes[index].code, whiteCodes[index].bits );
- len &= 63;
- }
- writeG3Code( whiteCodes[len].code, whiteCodes[len].bits );
-}
-
-void QtopiaPrintEnginePrivate::writeG3BlackRun( int len )
-{
- static struct {
- unsigned short code;
- unsigned short bits;
- } blackCodes[64 + 27] = {
- {0x0037, 10}, // 0
- {0x0002, 3},
- {0x0003, 2},
- {0x0002, 2},
- {0x0003, 3},
- {0x0003, 4},
- {0x0002, 4},
- {0x0003, 5},
- {0x0005, 6}, // 8
- {0x0004, 6},
- {0x0004, 7},
- {0x0005, 7},
- {0x0007, 7},
- {0x0004, 8},
- {0x0007, 8},
- {0x0018, 9},
- {0x0017, 10}, // 16
- {0x0018, 10},
- {0x0008, 10},
- {0x0067, 11},
- {0x0068, 11},
- {0x006C, 11},
- {0x0037, 11},
- {0x0028, 11},
- {0x0017, 11}, // 24
- {0x0018, 11},
- {0x00CA, 12},
- {0x00CB, 12},
- {0x00CC, 12},
- {0x00CD, 12},
- {0x0068, 12},
- {0x0069, 12},
- {0x006A, 12}, // 32
- {0x006B, 12},
- {0x00D2, 12},
- {0x00D3, 12},
- {0x00D4, 12},
- {0x00D5, 12},
- {0x00D6, 12},
- {0x00D7, 12},
- {0x006C, 12}, // 40
- {0x006D, 12},
- {0x00DA, 12},
- {0x00DB, 12},
- {0x0054, 12},
- {0x0055, 12},
- {0x0056, 12},
- {0x0057, 12},
- {0x0064, 12}, // 48
- {0x0065, 12},
- {0x0052, 12},
- {0x0053, 12},
- {0x0024, 12},
- {0x0037, 12},
- {0x0038, 12},
- {0x0027, 12},
- {0x0028, 12}, // 56
- {0x0058, 12},
- {0x0059, 12},
- {0x002B, 12},
- {0x002C, 12},
- {0x005A, 12},
- {0x0066, 12},
- {0x0067, 12},
- {0x000F, 10}, // Make up codes: 64
- {0x00C8, 12}, // 128
- {0x00C9, 12}, // 192
- {0x005B, 12}, // 256
- {0x0033, 12}, // 320
- {0x0034, 12}, // 384
- {0x0035, 12}, // 448
- {0x006C, 13}, // 512
- {0x006D, 13}, // 576
- {0x004A, 13}, // 640
- {0x004B, 13}, // 704
- {0x004C, 13}, // 768
- {0x004D, 13}, // 832
- {0x0072, 13}, // 896
- {0x0073, 13}, // 960
- {0x0074, 13}, // 1024
- {0x0075, 13}, // 1088
- {0x0076, 13}, // 1152
- {0x0077, 13}, // 1216
- {0x0052, 13}, // 1280
- {0x0053, 13}, // 1344
- {0x0054, 13}, // 1408
- {0x0055, 13}, // 1472
- {0x005A, 13}, // 1536
- {0x005B, 13}, // 1600
- {0x0064, 13}, // 1664
- {0x0065, 13}, // 1728
- };
- if ( len >= 64 ) {
- int index = 63 + (len >> 6);
- writeG3Code( blackCodes[index].code, blackCodes[index].bits );
- len &= 63;
- }
- writeG3Code( blackCodes[len].code, blackCodes[len].bits );
-}
-
-void QtopiaPrintEnginePrivate::writeG3EOL()
-{
- int bitToPad;
- if ( partialBits <= 4 ) {
- bitToPad = 4 - partialBits;
- } else {
- bitToPad = 8 - partialBits + 4;
- }
-
- partialByte = ((partialByte << (bitToPad + 12)) | 0x0001);
- partialBits += bitToPad + 12;
-
- while ( partialBits >= 8 ) {
- partialBits -= 8;
- buffer.append( (char)(partialByte >> partialBits ) );
- }
-// writeG3Code( 0x0001, 12 );
-}
-
-void QtopiaPrintBuffer::append( short value )
-{
- if ( _bigEndian ) {
- _data.append( (char)(value >> 8) );
- _data.append( (char)value );
- } else {
- _data.append( (char)value );
- _data.append( (char)(value >> 8) );
- }
-}
-
-void QtopiaPrintBuffer::append( int value )
-{
- if ( _bigEndian ) {
- _data.append( (char)(value >> 24) );
- _data.append( (char)(value >> 16) );
- _data.append( (char)(value >> 8) );
- _data.append( (char)value );
- } else {
- _data.append( (char)value );
- _data.append( (char)(value >> 8) );
- _data.append( (char)(value >> 16) );
- _data.append( (char)(value >> 24) );
- }
-}
-
-void QtopiaPrintBuffer::patch( int posn, int value )
-{
- if ( _bigEndian ) {
- _data[posn] = (char)(value >> 24);
- _data[posn + 1] = (char)(value >> 16);
- _data[posn + 2] = (char)(value >> 8);
- _data[posn + 3] = (char)value;
- } else {
- _data[posn] = (char)value;
- _data[posn + 1] = (char)(value >> 8);
- _data[posn + 2] = (char)(value >> 16);
- _data[posn + 3] = (char)(value >> 24);
- }
-}
-
-void QtopiaPrintBuffer::pad()
-{
- while ( ( _data.size() % 4 ) != 0 )
- _data.append( (char)0 );
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_PRINTER
diff --git a/src/gui/painting/qprintengine_qws_p.h b/src/gui/painting/qprintengine_qws_p.h
deleted file mode 100644
index e797914180..0000000000
--- a/src/gui/painting/qprintengine_qws_p.h
+++ /dev/null
@@ -1,213 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPRINTENGINE_QWS_P_H
-#define QPRINTENGINE_QWS_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "QtGui/qprinter.h"
-
-#ifndef QT_NO_PRINTER
-
-#include "QtGui/qprintengine.h"
-#include "QtCore/qbytearray.h"
-#include "private/qpaintengine_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class QtopiaPrintEnginePrivate;
-class QRasterPaintEngine;
-class QPrinterPrivate;
-class QImage;
-
-class QtopiaPrintEngine : public QPaintEngine, public QPrintEngine
-{
- Q_DECLARE_PRIVATE(QtopiaPrintEngine)
-public:
- QtopiaPrintEngine(QPrinter::PrinterMode mode);
-
- // override QWSPaintEngine
- bool begin(QPaintDevice *dev);
- bool end();
- void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr);
- void drawTextItem(const QPointF &p, const QTextItem &ti);
- QPaintEngine::Type type() const { return QPaintEngine::X11; }
-
- QPaintEngine *paintEngine() const;
-
- void updateState(const QPaintEngineState &state);
-
- QRect paperRect() const;
- QRect pageRect() const;
-
- bool newPage();
- bool abort();
-
- QPrinter::PrinterState printerState() const;
-
- int metric(QPaintDevice::PaintDeviceMetric metricType) const;
-
- QVariant property(PrintEnginePropertyKey key) const;
- void setProperty(PrintEnginePropertyKey key, const QVariant &value);
-
-private:
- friend class QPrintDialog;
- friend class QPageSetupDialog;
-
- void clearPage();
- void flushPage();
-};
-
-class QtopiaPrintBuffer
-{
-public:
- QtopiaPrintBuffer( bool bigEndian=FALSE ) { _bigEndian = bigEndian; }
- ~QtopiaPrintBuffer() {}
-
- const QByteArray& data() const { return _data; }
-
- int size() const { return _data.size(); }
-
- void clear() { _data.clear(); }
-
- void append( char value ) { _data.append( value ); }
- void append( short value );
- void append( int value );
- void append( const QByteArray& array ) { _data.append( array ); }
-
- void patch( int posn, int value );
-
- void pad();
-
-private:
- QByteArray _data;
- bool _bigEndian;
-};
-
-#define QT_QWS_PRINTER_DEFAULT_DPI 200
-
-class QtopiaPrintEnginePrivate : public QPaintEnginePrivate
-{
- Q_DECLARE_PUBLIC(QtopiaPrintEngine)
-public:
- QtopiaPrintEnginePrivate(QPrinter::PrinterMode m) :
- mode(m),
- printerState(QPrinter::Idle),
- orientation(QPrinter::Portrait),
- paperSize(QPrinter::A4),
- pageOrder(QPrinter::FirstPageFirst),
- colorMode(QPrinter::GrayScale),
- paperSource(QPrinter::OnlyOne),
- resolution(QT_QWS_PRINTER_DEFAULT_DPI),
- _paintEngine(0),
- numCopies(1),
- outputToFile(false),
- fullPage(false),
- collateCopies(false),
- pageNumber(0),
- pageImage(0),
- partialByte(0),
- partialBits(0)
- {
- }
- ~QtopiaPrintEnginePrivate();
-
- void initialize();
- QPaintEngine *paintEngine();
-
- QPrinter::PrinterMode mode;
-
- QString printerName;
- QString outputFileName;
- QString printProgram;
- QString docName;
- QString creator;
-
- QPrinter::PrinterState printerState;
-
- QPrinter::Orientation orientation;
- QPrinter::PaperSize paperSize;
- QPrinter::PageOrder pageOrder;
- QPrinter::ColorMode colorMode;
- QPrinter::PaperSource paperSource;
-
- int resolution;
- QPaintEngine *_paintEngine;
- int numCopies;
-
- bool outputToFile;
- bool fullPage;
- bool collateCopies;
-
- int pageNumber;
-
- QImage *pageImage;
-
- QtopiaPrintBuffer buffer;
-
- // Definitions that are only relevant to G3FAX output.
- int ifdPatch;
- int partialByte;
- int partialBits;
- void writeG3FaxHeader();
- void writeG3FaxPage();
- int writeG3IFDEntry( int tag, int type, int count, int value );
- void writeG3Code( int code, int bits );
- void writeG3WhiteRun( int len );
- void writeG3BlackRun( int len );
- void writeG3EOL();
-};
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_PRINTER
-
-#endif // QPRINTENGINE_QWS_P_H
diff --git a/src/gui/painting/qprinter.cpp b/src/gui/painting/qprinter.cpp
deleted file mode 100644
index 74a8f6a9d8..0000000000
--- a/src/gui/painting/qprinter.cpp
+++ /dev/null
@@ -1,2453 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qprinter_p.h"
-#include "qprinter.h"
-#include "qprintengine.h"
-#include "qprinterinfo.h"
-#include "qlist.h"
-#include <qpagesetupdialog.h>
-#include <qapplication.h>
-#include <qfileinfo.h>
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
-#include "private/qcups_p.h"
-#endif
-
-#ifndef QT_NO_PRINTER
-
-#if defined (Q_WS_WIN)
-#include <private/qprintengine_win_p.h>
-#elif defined (Q_WS_MAC)
-#include <private/qprintengine_mac_p.h>
-#elif defined (QTOPIA_PRINTENGINE)
-#include <private/qprintengine_qws_p.h>
-#endif
-#include <private/qprintengine_ps_p.h>
-
-#if defined(Q_WS_X11)
-#include <private/qt_x11_p.h>
-#endif
-
-#ifndef QT_NO_PDF
-#include "qprintengine_pdf_p.h"
-#endif
-
-#include <qpicture.h>
-#include <private/qpaintengine_preview_p.h>
-
-#if defined(QT3_SUPPORT)
-# include "qprintdialog.h"
-#endif // QT3_SUPPORT
-
-QT_BEGIN_NAMESPACE
-
-#define ABORT_IF_ACTIVE(location) \
- if (d->printEngine->printerState() == QPrinter::Active) { \
- qWarning("%s: Cannot be changed while printer is active", location); \
- return; \
- }
-
-// NB! This table needs to be in sync with QPrinter::PaperSize
-static const float qt_paperSizes[][2] = {
- {210, 297}, // A4
- {176, 250}, // B5
- {215.9f, 279.4f}, // Letter
- {215.9f, 355.6f}, // Legal
- {190.5f, 254}, // Executive
- {841, 1189}, // A0
- {594, 841}, // A1
- {420, 594}, // A2
- {297, 420}, // A3
- {148, 210}, // A5
- {105, 148}, // A6
- {74, 105}, // A7
- {52, 74}, // A8
- {37, 52}, // A8
- {1000, 1414}, // B0
- {707, 1000}, // B1
- {31, 44}, // B10
- {500, 707}, // B2
- {353, 500}, // B3
- {250, 353}, // B4
- {125, 176}, // B6
- {88, 125}, // B7
- {62, 88}, // B8
- {33, 62}, // B9
- {163, 229}, // C5E
- {105, 241}, // US Common
- {110, 220}, // DLE
- {210, 330}, // Folio
- {431.8f, 279.4f}, // Ledger
- {279.4f, 431.8f} // Tabloid
-};
-
-/// return the multiplier of converting from the unit value to postscript-points.
-double qt_multiplierForUnit(QPrinter::Unit unit, int resolution)
-{
- switch(unit) {
- case QPrinter::Millimeter:
- return 2.83464566929;
- case QPrinter::Point:
- return 1.0;
- case QPrinter::Inch:
- return 72.0;
- case QPrinter::Pica:
- return 12;
- case QPrinter::Didot:
- return 1.065826771;
- case QPrinter::Cicero:
- return 12.789921252;
- case QPrinter::DevicePixel:
- return 72.0/resolution;
- }
- return 1.0;
-}
-
-// not static: it's needed in qpagesetupdialog_unix.cpp
-QSizeF qt_printerPaperSize(QPrinter::Orientation orientation,
- QPrinter::PaperSize paperSize,
- QPrinter::Unit unit,
- int resolution)
-{
- int width_index = 0;
- int height_index = 1;
- if (orientation == QPrinter::Landscape) {
- width_index = 1;
- height_index = 0;
- }
- const qreal multiplier = qt_multiplierForUnit(unit, resolution);
- return QSizeF((qt_paperSizes[paperSize][width_index] * 72 / 25.4) / multiplier,
- (qt_paperSizes[paperSize][height_index] * 72 / 25.4) / multiplier);
-}
-
-void QPrinterPrivate::createDefaultEngines()
-{
- QPrinter::OutputFormat realOutputFormat = outputFormat;
-#if !defined (QTOPIA_PRINTENGINE)
-#if defined (Q_OS_UNIX) && ! defined (Q_WS_MAC)
- if(outputFormat == QPrinter::NativeFormat) {
- realOutputFormat = QPrinter::PostScriptFormat;
- }
-#endif
-#endif
-
- switch (realOutputFormat) {
- case QPrinter::NativeFormat: {
-#if defined (Q_WS_WIN)
- QWin32PrintEngine *winEngine = new QWin32PrintEngine(printerMode);
- paintEngine = winEngine;
- printEngine = winEngine;
-#elif defined (Q_WS_MAC)
- QMacPrintEngine *macEngine = new QMacPrintEngine(printerMode);
- paintEngine = macEngine;
- printEngine = macEngine;
-#elif defined (QTOPIA_PRINTENGINE)
- QtopiaPrintEngine *qwsEngine = new QtopiaPrintEngine(printerMode);
- paintEngine = qwsEngine;
- printEngine = qwsEngine;
-#elif defined (Q_OS_UNIX)
- Q_ASSERT(false);
-#endif
- }
- break;
- case QPrinter::PdfFormat: {
- QPdfEngine *pdfEngine = new QPdfEngine(printerMode);
- paintEngine = pdfEngine;
- printEngine = pdfEngine;
- }
- break;
- case QPrinter::PostScriptFormat: {
- QPSPrintEngine *psEngine = new QPSPrintEngine(printerMode);
- paintEngine = psEngine;
- printEngine = psEngine;
- }
- break;
- }
- use_default_engine = true;
- had_default_engines = true;
-}
-
-#ifndef QT_NO_PRINTPREVIEWWIDGET
-QList<const QPicture *> QPrinterPrivate::previewPages() const
-{
- if (previewEngine)
- return previewEngine->pages();
- return QList<const QPicture *>();
-}
-
-void QPrinterPrivate::setPreviewMode(bool enable)
-{
- Q_Q(QPrinter);
- if (enable) {
- if (!previewEngine)
- previewEngine = new QPreviewPaintEngine;
- had_default_engines = use_default_engine;
- use_default_engine = false;
- realPrintEngine = printEngine;
- realPaintEngine = paintEngine;
- q->setEngines(previewEngine, previewEngine);
- previewEngine->setProxyEngines(realPrintEngine, realPaintEngine);
- } else {
- q->setEngines(realPrintEngine, realPaintEngine);
- use_default_engine = had_default_engines;
- }
-}
-#endif // QT_NO_PRINTPREVIEWWIDGET
-
-void QPrinterPrivate::addToManualSetList(QPrintEngine::PrintEnginePropertyKey key)
-{
- for (int c = 0; c < manualSetList.size(); ++c) {
- if (manualSetList[c] == key) return;
- }
- manualSetList.append(key);
-}
-
-
-/*!
- \class QPrinter
- \reentrant
-
- \brief The QPrinter class is a paint device that paints on a printer.
-
- \ingroup printing
-
-
- This device represents a series of pages of printed output, and is
- used in almost exactly the same way as other paint devices such as
- QWidget and QPixmap.
- A set of additional functions are provided to manage device-specific
- features, such as orientation and resolution, and to step through
- the pages in a document as it is generated.
-
- When printing directly to a printer on Windows or Mac OS X, QPrinter uses
- the built-in printer drivers. On X11, QPrinter uses the
- \l{Common Unix Printing System (CUPS)} or the standard Unix \l lpr utility
- 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
- general, QPrinter passes these functions onto the underlying QPrintEngine.
-
- The most important parameters are:
- \list
- \i setOrientation() tells QPrinter which page orientation to use.
- \i setPaperSize() tells QPrinter what paper size to expect from the
- printer.
- \i setResolution() tells QPrinter what resolution you wish the
- printer to provide, in dots per inch (DPI).
- \i setFullPage() tells QPrinter whether you want to deal with the
- full page or just with the part the printer can draw on.
- \i setCopyCount() tells QPrinter how many copies of the document
- it should print.
- \endlist
-
- Many of these functions can only be called before the actual printing
- begins (i.e., before QPainter::begin() is called). This usually makes
- sense because, for example, it's not possible to change the number of
- copies when you are halfway through printing. There are also some
- settings that the user sets (through the printer dialog) and that
- applications are expected to obey. See QAbstractPrintDialog's
- documentation for more details.
-
- When QPainter::begin() is called, the QPrinter it operates on is prepared for
- a new page, enabling the QPainter to be used immediately to paint the first
- page in a document. Once the first page has been painted, newPage() can be
- called to request a new blank page to paint on, or QPainter::end() can be
- called to finish printing. The second page and all following pages are
- prepared using a call to newPage() before they are painted.
-
- The first page in a document does not need to be preceded by a call to
- newPage(). You only need to calling newPage() after QPainter::begin() if you
- need to insert a blank page at the beginning of a printed document.
- Similarly, calling newPage() after the last page in a document is painted will
- result in a trailing blank page appended to the end of the printed document.
-
- If you want to abort the print job, abort() will try its best to
- stop printing. It may cancel the entire job or just part of it.
-
- Since QPrinter can print to any QPrintEngine subclass, it is possible to
- extend printing support to cover new types of printing subsystem by
- subclassing QPrintEngine and reimplementing its interface.
-
- \sa QPrintDialog, {Printing with Qt}
-*/
-
-/*!
- \enum QPrinter::PrinterState
-
- \value Idle
- \value Active
- \value Aborted
- \value Error
-*/
-
-/*!
- \enum QPrinter::PrinterMode
-
- This enum describes the mode the printer should work in. It
- basically presets a certain resolution and working mode.
-
- \value ScreenResolution Sets the resolution of the print device to
- the screen resolution. This has the big advantage that the results
- obtained when painting on the printer will match more or less
- exactly the visible output on the screen. It is the easiest to
- use, as font metrics on the screen and on the printer are the
- same. This is the default value. ScreenResolution will produce a
- lower quality output than HighResolution and should only be used
- for drafts.
-
- \value PrinterResolution This value is deprecated. Is is
- equivalent to ScreenResolution on Unix and HighResolution on
- Windows and Mac. Due do the difference between ScreenResolution
- and HighResolution, use of this value may lead to non-portable
- printer code.
-
- \value HighResolution On Windows, sets the printer resolution to that
- defined for the printer in use. For PostScript printing, sets the
- resolution of the PostScript driver to 1200 dpi.
-
- \note When rendering text on a QPrinter device, it is important
- to realize that the size of text, when specified in points, is
- independent of the resolution specified for the device itself.
- Therefore, it may be useful to specify the font size in pixels
- when combining text with graphics to ensure that their relative
- sizes are what you expect.
-*/
-
-/*!
- \enum QPrinter::Orientation
-
- This enum type (not to be confused with \c Orientation) is used
- to specify each page's orientation.
-
- \value Portrait the page's height is greater than its width.
-
- \value Landscape the page's width is greater than its height.
-
- This type interacts with \l QPrinter::PaperSize and
- QPrinter::setFullPage() to determine the final size of the page
- available to the application.
-*/
-
-
-/*!
- \enum QPrinter::PrintRange
-
- Used to specify the print range selection option.
-
- \value AllPages All pages should be printed.
- \value Selection Only the selection should be printed.
- \value PageRange The specified page range should be printed.
- \value CurrentPage Only the current page should be printed.
-
- \sa QAbstractPrintDialog::PrintRange
-*/
-
-/*!
- \enum QPrinter::PrinterOption
- \compat
-
- Use QAbstractPrintDialog::PrintDialogOption instead.
-
- \value PrintToFile
- \value PrintSelection
- \value PrintPageRange
-*/
-
-/*!
- \enum QPrinter::PageSize
-
- \obsolete
- Use QPrinter::PaperSize instead.
-
- \value A0 841 x 1189 mm
- \value A1 594 x 841 mm
- \value A2 420 x 594 mm
- \value A3 297 x 420 mm
- \value A4 210 x 297 mm, 8.26 x 11.69 inches
- \value A5 148 x 210 mm
- \value A6 105 x 148 mm
- \value A7 74 x 105 mm
- \value A8 52 x 74 mm
- \value A9 37 x 52 mm
- \value B0 1030 x 1456 mm
- \value B1 728 x 1030 mm
- \value B10 32 x 45 mm
- \value B2 515 x 728 mm
- \value B3 364 x 515 mm
- \value B4 257 x 364 mm
- \value B5 182 x 257 mm, 7.17 x 10.13 inches
- \value B6 128 x 182 mm
- \value B7 91 x 128 mm
- \value B8 64 x 91 mm
- \value B9 45 x 64 mm
- \value C5E 163 x 229 mm
- \value Comm10E 105 x 241 mm, U.S. Common 10 Envelope
- \value DLE 110 x 220 mm
- \value Executive 7.5 x 10 inches, 191 x 254 mm
- \value Folio 210 x 330 mm
- \value Ledger 432 x 279 mm
- \value Legal 8.5 x 14 inches, 216 x 356 mm
- \value Letter 8.5 x 11 inches, 216 x 279 mm
- \value Tabloid 279 x 432 mm
- \value Custom Unknown, or a user defined size.
-
- \omitvalue NPageSize
- */
-
-/*!
- \enum QPrinter::PaperSize
- \since 4.4
-
- This enum type specifies what paper size QPrinter should use.
- QPrinter does not check that the paper size is available; it just
- uses this information, together with QPrinter::Orientation and
- QPrinter::setFullPage(), to determine the printable area.
-
- The defined sizes (with setFullPage(true)) are:
-
- \value A0 841 x 1189 mm
- \value A1 594 x 841 mm
- \value A2 420 x 594 mm
- \value A3 297 x 420 mm
- \value A4 210 x 297 mm, 8.26 x 11.69 inches
- \value A5 148 x 210 mm
- \value A6 105 x 148 mm
- \value A7 74 x 105 mm
- \value A8 52 x 74 mm
- \value A9 37 x 52 mm
- \value B0 1000 x 1414 mm
- \value B1 707 x 1000 mm
- \value B2 500 x 707 mm
- \value B3 353 x 500 mm
- \value B4 250 x 353 mm
- \value B5 176 x 250 mm, 6.93 x 9.84 inches
- \value B6 125 x 176 mm
- \value B7 88 x 125 mm
- \value B8 62 x 88 mm
- \value B9 33 x 62 mm
- \value B10 31 x 44 mm
- \value C5E 163 x 229 mm
- \value Comm10E 105 x 241 mm, U.S. Common 10 Envelope
- \value DLE 110 x 220 mm
- \value Executive 7.5 x 10 inches, 190.5 x 254 mm
- \value Folio 210 x 330 mm
- \value Ledger 431.8 x 279.4 mm
- \value Legal 8.5 x 14 inches, 215.9 x 355.6 mm
- \value Letter 8.5 x 11 inches, 215.9 x 279.4 mm
- \value Tabloid 279.4 x 431.8 mm
- \value Custom Unknown, or a user defined size.
-
- With setFullPage(false) (the default), the metrics will be a bit
- smaller; how much depends on the printer in use.
-
- \omitvalue NPageSize
- \omitvalue NPaperSize
-*/
-
-
-/*!
- \enum QPrinter::PageOrder
-
- This enum type is used by QPrinter to tell the application program
- how to print.
-
- \value FirstPageFirst the lowest-numbered page should be printed
- first.
-
- \value LastPageFirst the highest-numbered page should be printed
- first.
-*/
-
-/*!
- \enum QPrinter::ColorMode
-
- This enum type is used to indicate whether QPrinter should print
- in color or not.
-
- \value Color print in color if available, otherwise in grayscale.
-
- \value GrayScale print in grayscale, even on color printers.
-*/
-
-/*!
- \enum QPrinter::PaperSource
-
- This enum type specifies what paper source QPrinter is to use.
- QPrinter does not check that the paper source is available; it
- just uses this information to try and set the paper source.
- Whether it will set the paper source depends on whether the
- printer has that particular source.
-
- \warning This is currently only implemented for Windows.
-
- \value Auto
- \value Cassette
- \value Envelope
- \value EnvelopeManual
- \value FormSource
- \value LargeCapacity
- \value LargeFormat
- \value Lower
- \value MaxPageSource
- \value Middle
- \value Manual
- \value OnlyOne
- \value Tractor
- \value SmallFormat
-*/
-
-/*!
- \enum QPrinter::Unit
- \since 4.4
-
- This enum type is used to specify the measurement unit for page and
- paper sizes.
-
- \value Millimeter
- \value Point
- \value Inch
- \value Pica
- \value Didot
- \value Cicero
- \value DevicePixel
-
- Note the difference between Point and DevicePixel. The Point unit is
- defined to be 1/72th of an inch, while the DevicePixel unit is
- resolution dependant and is based on the actual pixels, or dots, on
- the printer.
-*/
-
-
-/*
- \enum QPrinter::PrintRange
-
- This enum is used to specify which print range the application
- should use to print.
-
- \value AllPages All the pages should be printed.
- \value Selection Only the selection should be printed.
- \value PageRange Print according to the from page and to page options.
- \value CurrentPage Only the current page should be printed.
-
- \sa setPrintRange(), printRange()
-*/
-
-/*
- \enum QPrinter::PrinterOption
-
- This enum describes various printer options that appear in the
- printer setup dialog. It is used to enable and disable these
- options in the setup dialog.
-
- \value PrintToFile Describes if print to file should be enabled.
- \value PrintSelection Describes if printing selections should be enabled.
- \value PrintPageRange Describes if printing page ranges (from, to) should
- be enabled
- \value PrintCurrentPage if Print Current Page option should be enabled
-
- \sa setOptionEnabled(), isOptionEnabled()
-*/
-
-/*!
- Creates a new printer object with the given \a mode.
-*/
-QPrinter::QPrinter(PrinterMode mode)
- : QPaintDevice(),
- d_ptr(new QPrinterPrivate(this))
-{
- init(mode);
- QPrinterInfo defPrn(QPrinterInfo::defaultPrinter());
- if (!defPrn.isNull()) {
- setPrinterName(defPrn.printerName());
- } else if (QPrinterInfo::availablePrinters().isEmpty()
- && d_ptr->paintEngine->type() != QPaintEngine::Windows
- && d_ptr->paintEngine->type() != QPaintEngine::MacPrinter) {
- setOutputFormat(QPrinter::PdfFormat);
- }
-}
-
-/*!
- \since 4.4
-
- Creates a new printer object with the given \a printer and \a mode.
-*/
-QPrinter::QPrinter(const QPrinterInfo& printer, PrinterMode mode)
- : QPaintDevice(),
- d_ptr(new QPrinterPrivate(this))
-{
- init(mode);
- setPrinterName(printer.printerName());
-}
-
-void QPrinter::init(PrinterMode mode)
-{
-#if !defined(Q_WS_X11)
- if (!qApp) {
-#else
- if (!qApp || !X11) {
-#endif
- qFatal("QPrinter: Must construct a QApplication before a QPaintDevice");
- return;
- }
- Q_D(QPrinter);
-
- d->printerMode = mode;
- d->outputFormat = QPrinter::NativeFormat;
- d->createDefaultEngines();
-
-#ifndef QT_NO_PRINTPREVIEWWIDGET
- d->previewEngine = 0;
-#endif
- d->realPrintEngine = 0;
- d->realPaintEngine = 0;
-
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
- if (QCUPSSupport::cupsVersion() >= 10200 && QCUPSSupport().currentPPD()) {
- setOutputFormat(QPrinter::PdfFormat);
- d->outputFormat = QPrinter::NativeFormat;
- }
-#endif
-}
-
-/*!
- This function is used by subclasses of QPrinter to specify custom
- print and paint engines (\a printEngine and \a paintEngine,
- respectively).
-
- QPrinter does not take ownership of the engines, so you need to
- manage these engine instances yourself.
-
- Note that changing the engines will reset the printer state and
- all its properties.
-
- \sa printEngine() paintEngine() setOutputFormat()
-
- \since 4.1
-*/
-void QPrinter::setEngines(QPrintEngine *printEngine, QPaintEngine *paintEngine)
-{
- Q_D(QPrinter);
-
- if (d->use_default_engine)
- delete d->printEngine;
-
- d->printEngine = printEngine;
- d->paintEngine = paintEngine;
- d->use_default_engine = false;
-}
-
-/*!
- Destroys the printer object and frees any allocated resources. If
- the printer is destroyed while a print job is in progress this may
- or may not affect the print job.
-*/
-QPrinter::~QPrinter()
-{
- Q_D(QPrinter);
- if (d->use_default_engine)
- delete d->printEngine;
-#ifndef QT_NO_PRINTPREVIEWWIDGET
- delete d->previewEngine;
-#endif
-}
-
-/*!
- \enum QPrinter::OutputFormat
-
- The OutputFormat enum is used to describe the format QPrinter should
- use for printing.
-
- \value NativeFormat QPrinter will print output using a method defined
- by the platform it is running on. This mode is the default when printing
- directly to a printer.
-
- \value PdfFormat QPrinter will generate its output as a searchable PDF file.
- This mode is the default when printing to a file.
-
- \value PostScriptFormat QPrinter will generate its output as in the PostScript format.
- (This feature was introduced in Qt 4.2.)
-
- \sa outputFormat(), setOutputFormat(), setOutputFileName()
-*/
-
-/*!
- \since 4.1
-
- Sets the output format for this printer to \a format.
-*/
-void QPrinter::setOutputFormat(OutputFormat format)
-{
-
-#ifndef QT_NO_PDF
- Q_D(QPrinter);
- if (d->validPrinter && d->outputFormat == format)
- return;
- d->outputFormat = format;
-
- QPrintEngine *oldPrintEngine = d->printEngine;
- const bool def_engine = d->use_default_engine;
- d->printEngine = 0;
-
- d->createDefaultEngines();
-
- if (oldPrintEngine) {
- for (int i = 0; i < d->manualSetList.size(); ++i) {
- QPrintEngine::PrintEnginePropertyKey key = d->manualSetList[i];
- QVariant prop;
- // PPK_NumberOfCopies need special treatmeant since it in most cases
- // will return 1, disregarding the actual value that was set
- if (key == QPrintEngine::PPK_NumberOfCopies)
- prop = QVariant(copyCount());
- else
- prop = oldPrintEngine->property(key);
- if (prop.isValid())
- d->printEngine->setProperty(key, prop);
- }
- }
-
- if (def_engine)
- delete oldPrintEngine;
-
- if (d->outputFormat == QPrinter::PdfFormat || d->outputFormat == QPrinter::PostScriptFormat)
- d->validPrinter = true;
-#else
- Q_UNUSED(format);
-#endif
-}
-
-/*!
- \since 4.1
-
- Returns the output format for this printer.
-*/
-QPrinter::OutputFormat QPrinter::outputFormat() const
-{
- Q_D(const QPrinter);
- return d->outputFormat;
-}
-
-
-
-/*! \internal
-*/
-int QPrinter::devType() const
-{
- return QInternal::Printer;
-}
-
-/*!
- Returns the printer name. This value is initially set to the name
- of the default printer.
-
- \sa setPrinterName()
-*/
-QString QPrinter::printerName() const
-{
- Q_D(const QPrinter);
- return d->printEngine->property(QPrintEngine::PPK_PrinterName).toString();
-}
-
-/*!
- Sets the printer name to \a name.
-
- \sa printerName(), isValid()
-*/
-void QPrinter::setPrinterName(const QString &name)
-{
- Q_D(QPrinter);
- ABORT_IF_ACTIVE("QPrinter::setPrinterName");
-
-#if defined(Q_OS_UNIX) && !defined(QT_NO_CUPS)
- if(d->use_default_engine
- && d->outputFormat == QPrinter::NativeFormat) {
- if (QCUPSSupport::cupsVersion() >= 10200
- && QCUPSSupport::printerHasPPD(name.toLocal8Bit().constData()))
- setOutputFormat(QPrinter::PdfFormat);
- else
- setOutputFormat(QPrinter::PostScriptFormat);
- d->outputFormat = QPrinter::NativeFormat;
- }
-#endif
-
- QList<QPrinterInfo> prnList = QPrinterInfo::availablePrinters();
- if (name.isEmpty()) {
- d->validPrinter = d->outputFormat == QPrinter::PdfFormat || d->outputFormat == QPrinter::PostScriptFormat;
- } else {
- d->validPrinter = false;
- for (int i = 0; i < prnList.size(); ++i) {
- if (prnList[i].printerName() == name) {
- d->validPrinter = true;
- break;
- }
- }
- }
-
- d->printEngine->setProperty(QPrintEngine::PPK_PrinterName, name);
- d->addToManualSetList(QPrintEngine::PPK_PrinterName);
-}
-
-
-/*!
- \since 4.4
-
- 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 QPrinter::newPage().
-
- \snippet doc/src/snippets/printing-qprinter/errors.cpp 0
-
- \sa setPrinterName()
-*/
-bool QPrinter::isValid() const
-{
- Q_D(const QPrinter);
-#if defined(Q_WS_X11)
- if (!qApp || !X11) {
- return false;
- }
-#endif
- return d->validPrinter;
-}
-
-
-/*!
- \fn bool QPrinter::outputToFile() const
-
- Returns true if the output should be written to a file, or false
- if the output should be sent directly to the printer. The default
- setting is false.
-
- \sa setOutputToFile(), setOutputFileName()
-*/
-
-
-/*!
- \fn void QPrinter::setOutputToFile(bool enable)
-
- Specifies whether the output should be written to a file or sent
- directly to the printer.
-
- Will output to a file if \a enable is true, or will output
- directly to the printer if \a enable is false.
-
- \sa outputToFile(), setOutputFileName()
-*/
-
-
-/*!
- \fn QString QPrinter::outputFileName() const
-
- Returns the name of the output file. By default, this is an empty string
- (indicating that the printer shouldn't print to file).
-
- \sa QPrintEngine::PrintEnginePropertyKey
-
-*/
-
-QString QPrinter::outputFileName() const
-{
- Q_D(const QPrinter);
- return d->printEngine->property(QPrintEngine::PPK_OutputFileName).toString();
-}
-
-/*!
- Sets the name of the output file to \a fileName.
-
- Setting a null or empty name (0 or "") disables printing to a file.
- Setting a non-empty name enables printing to a file.
-
- This can change the value of outputFormat(). If the file name has the
- suffix ".ps" then PostScript is automatically selected as output format.
- If the file name has the ".pdf" suffix PDF is generated. If the file name
- has a suffix other than ".ps" and ".pdf", the output format used is the
- one set with setOutputFormat().
-
- QPrinter uses Qt's cross-platform PostScript or PDF print engines
- respectively. If you can produce this format natively, for example
- Mac OS X can generate PDF's from its print engine, set the output format
- back to NativeFormat.
-
- \sa outputFileName() setOutputToFile() setOutputFormat()
-*/
-
-void QPrinter::setOutputFileName(const QString &fileName)
-{
- Q_D(QPrinter);
- ABORT_IF_ACTIVE("QPrinter::setOutputFileName");
-
- QFileInfo fi(fileName);
- if (!fi.suffix().compare(QLatin1String("ps"), Qt::CaseInsensitive))
- setOutputFormat(QPrinter::PostScriptFormat);
- else if (!fi.suffix().compare(QLatin1String("pdf"), Qt::CaseInsensitive))
- setOutputFormat(QPrinter::PdfFormat);
- else if (fileName.isEmpty())
- setOutputFormat(QPrinter::NativeFormat);
-
- d->printEngine->setProperty(QPrintEngine::PPK_OutputFileName, fileName);
- d->addToManualSetList(QPrintEngine::PPK_OutputFileName);
-}
-
-
-/*!
- Returns the name of the program that sends the print output to the
- printer.
-
- The default is to return an empty string; meaning that QPrinter will try to
- be smart in a system-dependent way. On X11 only, you can set it to something
- different to use a specific print program. On the other platforms, this
- returns an empty string.
-
- \sa setPrintProgram(), setPrinterSelectionOption()
-*/
-QString QPrinter::printProgram() const
-{
- Q_D(const QPrinter);
- return d->printEngine->property(QPrintEngine::PPK_PrinterProgram).toString();
-}
-
-
-/*!
- Sets the name of the program that should do the print job to \a
- printProg.
-
- On X11, this function sets the program to call with the PostScript
- output. On other platforms, it has no effect.
-
- \sa printProgram()
-*/
-void QPrinter::setPrintProgram(const QString &printProg)
-{
- Q_D(QPrinter);
- ABORT_IF_ACTIVE("QPrinter::setPrintProgram");
- d->printEngine->setProperty(QPrintEngine::PPK_PrinterProgram, printProg);
- d->addToManualSetList(QPrintEngine::PPK_PrinterProgram);
-}
-
-
-/*!
- Returns the document name.
-
- \sa setDocName(), QPrintEngine::PrintEnginePropertyKey
-*/
-QString QPrinter::docName() const
-{
- Q_D(const QPrinter);
- return d->printEngine->property(QPrintEngine::PPK_DocumentName).toString();
-}
-
-
-/*!
- Sets the document name to \a name.
-
- On X11, the document name is for example used as the default
- output filename in QPrintDialog. Note that the document name does
- not affect the file name if the printer is printing to a file.
- Use the setOutputFile() function for this.
-
- \sa docName(), QPrintEngine::PrintEnginePropertyKey
-*/
-void QPrinter::setDocName(const QString &name)
-{
- Q_D(QPrinter);
- ABORT_IF_ACTIVE("QPrinter::setDocName");
- d->printEngine->setProperty(QPrintEngine::PPK_DocumentName, name);
- d->addToManualSetList(QPrintEngine::PPK_DocumentName);
-}
-
-
-/*!
- Returns the name of the application that created the document.
-
- \sa setCreator()
-*/
-QString QPrinter::creator() const
-{
- Q_D(const QPrinter);
- return d->printEngine->property(QPrintEngine::PPK_Creator).toString();
-}
-
-
-/*!
- Sets the name of the application that created the document to \a
- creator.
-
- This function is only applicable to the X11 version of Qt. If no
- creator name is specified, the creator will be set to "Qt"
- followed by some version number.
-
- \sa creator()
-*/
-void QPrinter::setCreator(const QString &creator)
-{
- Q_D(QPrinter);
- ABORT_IF_ACTIVE("QPrinter::setCreator");
- d->printEngine->setProperty(QPrintEngine::PPK_Creator, creator);
- d->addToManualSetList(QPrintEngine::PPK_Creator);
-}
-
-
-/*!
- Returns the orientation setting. This is driver-dependent, but is usually
- QPrinter::Portrait.
-
- \sa setOrientation()
-*/
-QPrinter::Orientation QPrinter::orientation() const
-{
- Q_D(const QPrinter);
- return QPrinter::Orientation(d->printEngine->property(QPrintEngine::PPK_Orientation).toInt());
-}
-
-
-/*!
- Sets the print orientation to \a orientation.
-
- The orientation can be either QPrinter::Portrait or
- QPrinter::Landscape.
-
- The printer driver reads this setting and prints using the
- specified orientation.
-
- On Windows, this option can be changed while printing and will
- take effect from the next call to newPage().
-
- On Mac OS X, changing the orientation during a print job has no effect.
-
- \sa orientation()
-*/
-
-void QPrinter::setOrientation(Orientation orientation)
-{
- Q_D(QPrinter);
- d->printEngine->setProperty(QPrintEngine::PPK_Orientation, orientation);
- d->addToManualSetList(QPrintEngine::PPK_Orientation);
-}
-
-
-/*!
- \since 4.4
- Returns the printer paper size. The default value is driver-dependent.
-
- \sa setPaperSize() pageRect() paperRect()
-*/
-
-QPrinter::PaperSize QPrinter::paperSize() const
-{
- Q_D(const QPrinter);
- return QPrinter::PaperSize(d->printEngine->property(QPrintEngine::PPK_PaperSize).toInt());
-}
-
-/*!
- \since 4.4
-
- Sets the printer paper size to \a newPaperSize if that size is
- supported. The result is undefined if \a newPaperSize is not
- supported.
-
- The default paper size is driver-dependent.
-
- This function is useful mostly for setting a default value that
- the user can override in the print dialog.
-
- \sa paperSize() PaperSize setFullPage() setResolution() pageRect() paperRect()
-*/
-void QPrinter::setPaperSize(PaperSize newPaperSize)
-{
- Q_D(QPrinter);
- if (d->paintEngine->type() != QPaintEngine::Pdf)
- ABORT_IF_ACTIVE("QPrinter::setPaperSize");
- if (newPaperSize < 0 || newPaperSize >= NPaperSize) {
- qWarning("QPrinter::setPaperSize: Illegal paper size %d", newPaperSize);
- return;
- }
- d->printEngine->setProperty(QPrintEngine::PPK_PaperSize, newPaperSize);
- d->addToManualSetList(QPrintEngine::PPK_PaperSize);
- d->hasUserSetPageSize = true;
-}
-
-/*!
- \obsolete
-
- Returns the printer page size. The default value is driver-dependent.
-
- Use paperSize() instead.
-*/
-QPrinter::PageSize QPrinter::pageSize() const
-{
- return paperSize();
-}
-
-
-/*!
- \obsolete
-
- Sets the printer page size based on \a newPageSize.
-
- Use setPaperSize() instead.
-*/
-
-void QPrinter::setPageSize(PageSize newPageSize)
-{
- setPaperSize(newPageSize);
-}
-
-/*!
- \since 4.4
-
- Sets the paper size based on \a paperSize in \a unit.
-
- \sa paperSize()
-*/
-
-void QPrinter::setPaperSize(const QSizeF &paperSize, QPrinter::Unit unit)
-{
- Q_D(QPrinter);
- if (d->paintEngine->type() != QPaintEngine::Pdf)
- ABORT_IF_ACTIVE("QPrinter::setPaperSize");
- const qreal multiplier = qt_multiplierForUnit(unit, resolution());
- QSizeF size(paperSize.width() * multiplier, paperSize.height() * multiplier);
- d->printEngine->setProperty(QPrintEngine::PPK_CustomPaperSize, size);
- d->addToManualSetList(QPrintEngine::PPK_CustomPaperSize);
- d->hasUserSetPageSize = true;
-}
-
-/*!
- \since 4.4
-
- Returns the paper size in \a unit.
-
- \sa setPaperSize()
-*/
-
-QSizeF QPrinter::paperSize(Unit unit) const
-{
- Q_D(const QPrinter);
- int res = resolution();
- const qreal multiplier = qt_multiplierForUnit(unit, res);
- PaperSize paperType = paperSize();
- if (paperType == Custom) {
- QSizeF size = d->printEngine->property(QPrintEngine::PPK_CustomPaperSize).toSizeF();
- return QSizeF(size.width() / multiplier, size.height() / multiplier);
- }
- else {
- return qt_printerPaperSize(orientation(), paperType, unit, res);
- }
-}
-
-/*!
- Sets the page order to \a pageOrder.
-
- The page order can be QPrinter::FirstPageFirst or
- QPrinter::LastPageFirst. The application is responsible for
- reading the page order and printing accordingly.
-
- This function is mostly useful for setting a default value that
- the user can override in the print dialog.
-
- This function is only supported under X11.
-*/
-
-void QPrinter::setPageOrder(PageOrder pageOrder)
-{
- Q_D(QPrinter);
- ABORT_IF_ACTIVE("QPrinter::setPageOrder");
- d->printEngine->setProperty(QPrintEngine::PPK_PageOrder, pageOrder);
- d->addToManualSetList(QPrintEngine::PPK_PageOrder);
-}
-
-
-/*!
- Returns the current page order.
-
- The default page order is \c FirstPageFirst.
-*/
-
-QPrinter::PageOrder QPrinter::pageOrder() const
-{
- Q_D(const QPrinter);
- return QPrinter::PageOrder(d->printEngine->property(QPrintEngine::PPK_PageOrder).toInt());
-}
-
-
-/*!
- Sets the printer's color mode to \a newColorMode, which can be
- either \c Color or \c GrayScale.
-
- \sa colorMode()
-*/
-
-void QPrinter::setColorMode(ColorMode newColorMode)
-{
- Q_D(QPrinter);
- ABORT_IF_ACTIVE("QPrinter::setColorMode");
- d->printEngine->setProperty(QPrintEngine::PPK_ColorMode, newColorMode);
- d->addToManualSetList(QPrintEngine::PPK_ColorMode);
-}
-
-
-/*!
- Returns the current color mode.
-
- \sa setColorMode()
-*/
-QPrinter::ColorMode QPrinter::colorMode() const
-{
- Q_D(const QPrinter);
- return QPrinter::ColorMode(d->printEngine->property(QPrintEngine::PPK_ColorMode).toInt());
-}
-
-
-/*!
- \obsolete
- Returns the number of copies to be printed. The default value is 1.
-
- On Windows, Mac OS X and X11 systems that support CUPS, this will always
- return 1 as these operating systems can internally handle the number
- of copies.
-
- On X11, this value will return the number of times the application is
- required to print in order to match the number specified in the printer setup
- dialog. This has been done since some printer drivers are not capable of
- buffering up the copies and in those cases the application must make an
- explicit call to the print code for each copy.
-
- Use copyCount() in conjunction with supportsMultipleCopies() instead.
-
- \sa setNumCopies(), actualNumCopies()
-*/
-
-int QPrinter::numCopies() const
-{
- Q_D(const QPrinter);
- return d->printEngine->property(QPrintEngine::PPK_NumberOfCopies).toInt();
-}
-
-
-/*!
- \obsolete
- \since 4.6
-
- Returns the number of copies that will be printed. The default
- value is 1.
-
- This function always returns the actual value specified in the print
- dialog or using setNumCopies().
-
- Use copyCount() instead.
-
- \sa setNumCopies(), numCopies()
-*/
-int QPrinter::actualNumCopies() const
-{
- return copyCount();
-}
-
-
-
-/*!
- \obsolete
- Sets the number of copies to be printed to \a numCopies.
-
- The printer driver reads this setting and prints the specified
- number of copies.
-
- Use setCopyCount() instead.
-
- \sa numCopies()
-*/
-
-void QPrinter::setNumCopies(int numCopies)
-{
- Q_D(QPrinter);
- ABORT_IF_ACTIVE("QPrinter::setNumCopies");
- d->printEngine->setProperty(QPrintEngine::PPK_NumberOfCopies, numCopies);
- d->addToManualSetList(QPrintEngine::PPK_NumberOfCopies);
-}
-
-/*!
- \since 4.7
-
- Sets the number of copies to be printed to \a count.
-
- The printer driver reads this setting and prints the specified number of
- copies.
-
- \sa copyCount(), supportsMultipleCopies()
-*/
-
-void QPrinter::setCopyCount(int count)
-{
- Q_D(QPrinter);
- ABORT_IF_ACTIVE("QPrinter::setCopyCount;");
- d->printEngine->setProperty(QPrintEngine::PPK_CopyCount, count);
- d->addToManualSetList(QPrintEngine::PPK_CopyCount);
-}
-
-/*!
- \since 4.7
-
- Returns the number of copies that will be printed. The default value is 1.
-
- \sa setCopyCount(), supportsMultipleCopies()
-*/
-
-int QPrinter::copyCount() const
-{
- Q_D(const QPrinter);
- return d->printEngine->property(QPrintEngine::PPK_CopyCount).toInt();
-}
-
-/*!
- \since 4.7
-
- Returns true if the printer supports printing multiple copies of the same
- document in one job; otherwise false is returned.
-
- On most systems this function will return true. However, on X11 systems
- that do not support CUPS, this function will return false. That means the
- application has to handle the number of copies by printing the same
- document the required number of times.
-
- \sa setCopyCount(), copyCount()
-*/
-
-bool QPrinter::supportsMultipleCopies() const
-{
- Q_D(const QPrinter);
- return d->printEngine->property(QPrintEngine::PPK_SupportsMultipleCopies).toBool();
-}
-
-/*!
- \since 4.1
-
- Returns true if collation is turned on when multiple copies is selected.
- Returns false if it is turned off when multiple copies is selected.
- When collating is turned off the printing of each individual page will be repeated
- the numCopies() amount before the next page is started. With collating turned on
- all pages are printed before the next copy of those pages is started.
-
- \sa setCollateCopies()
-*/
-bool QPrinter::collateCopies() const
-{
- Q_D(const QPrinter);
- return d->printEngine->property(QPrintEngine::PPK_CollateCopies).toBool();
-}
-
-
-/*!
- \since 4.1
-
- Sets the default value for collation checkbox when the print
- dialog appears. If \a collate is true, it will enable
- setCollateCopiesEnabled(). The default value is false. This value
- will be changed by what the user presses in the print dialog.
-
- \sa collateCopies()
-*/
-void QPrinter::setCollateCopies(bool collate)
-{
- Q_D(QPrinter);
- ABORT_IF_ACTIVE("QPrinter::setCollateCopies");
- d->printEngine->setProperty(QPrintEngine::PPK_CollateCopies, collate);
- d->addToManualSetList(QPrintEngine::PPK_CollateCopies);
-}
-
-
-
-/*!
- If \a fp is true, enables support for painting over the entire page;
- otherwise restricts painting to the printable area reported by the
- device.
-
- By default, full page printing is disabled. In this case, the origin
- of the QPrinter's coordinate system coincides with the top-left
- corner of the printable area.
-
- If full page printing is enabled, the origin of the QPrinter's
- coordinate system coincides with the top-left corner of the paper
- itself. In this case, the
- \l{QPaintDevice::PaintDeviceMetric}{device metrics} will report
- the exact same dimensions as indicated by \l{PaperSize}. It may not
- be possible to print on the entire physical page because of the
- printer's margins, so the application must account for the margins
- itself.
-
- \sa fullPage(), setPaperSize(), width(), height(), {Printing with Qt}
-*/
-
-void QPrinter::setFullPage(bool fp)
-{
- Q_D(QPrinter);
- d->printEngine->setProperty(QPrintEngine::PPK_FullPage, fp);
- d->addToManualSetList(QPrintEngine::PPK_FullPage);
-}
-
-
-/*!
- Returns true if the origin of the printer's coordinate system is
- at the corner of the page and false if it is at the edge of the
- printable area.
-
- See setFullPage() for details and caveats.
-
- \sa setFullPage() PaperSize
-*/
-
-bool QPrinter::fullPage() const
-{
- Q_D(const QPrinter);
- return d->printEngine->property(QPrintEngine::PPK_FullPage).toBool();
-}
-
-
-/*!
- Requests that the printer prints at \a dpi or as near to \a dpi as
- possible.
-
- This setting affects the coordinate system as returned by, for
- example QPainter::viewport().
-
- This function must be called before QPainter::begin() to have an effect on
- all platforms.
-
- \sa resolution() setPaperSize()
-*/
-
-void QPrinter::setResolution(int dpi)
-{
- Q_D(QPrinter);
- ABORT_IF_ACTIVE("QPrinter::setResolution");
- d->printEngine->setProperty(QPrintEngine::PPK_Resolution, dpi);
- d->addToManualSetList(QPrintEngine::PPK_Resolution);
-}
-
-
-/*!
- Returns the current assumed resolution of the printer, as set by
- setResolution() or by the printer driver.
-
- \sa setResolution()
-*/
-
-int QPrinter::resolution() const
-{
- Q_D(const QPrinter);
- return d->printEngine->property(QPrintEngine::PPK_Resolution).toInt();
-}
-
-/*!
- Sets the paper source setting to \a source.
-
- Windows only: This option can be changed while printing and will
- take effect from the next call to newPage()
-
- \sa paperSource()
-*/
-
-void QPrinter::setPaperSource(PaperSource source)
-{
- Q_D(QPrinter);
- d->printEngine->setProperty(QPrintEngine::PPK_PaperSource, source);
- d->addToManualSetList(QPrintEngine::PPK_PaperSource);
-}
-
-/*!
- Returns the printer's paper source. This is \c Manual or a printer
- tray or paper cassette.
-*/
-QPrinter::PaperSource QPrinter::paperSource() const
-{
- Q_D(const QPrinter);
- return QPrinter::PaperSource(d->printEngine->property(QPrintEngine::PPK_PaperSource).toInt());
-}
-
-
-/*!
- \since 4.1
-
- Enabled or disables font embedding depending on \a enable.
-
- Currently this option is only supported on X11.
-
- \sa fontEmbeddingEnabled()
-*/
-void QPrinter::setFontEmbeddingEnabled(bool enable)
-{
- Q_D(QPrinter);
- d->printEngine->setProperty(QPrintEngine::PPK_FontEmbedding, enable);
- d->addToManualSetList(QPrintEngine::PPK_FontEmbedding);
-}
-
-/*!
- \since 4.1
-
- Returns true if font embedding is enabled.
-
- Currently this option is only supported on X11.
-
- \sa setFontEmbeddingEnabled()
-*/
-bool QPrinter::fontEmbeddingEnabled() const
-{
- Q_D(const QPrinter);
- return d->printEngine->property(QPrintEngine::PPK_FontEmbedding).toBool();
-}
-
-/*!
- \enum QPrinter::DuplexMode
- \since 4.4
-
- This enum is used to indicate whether printing will occur on one or both sides
- of each sheet of paper (simplex or duplex printing).
-
- \value DuplexNone Single sided (simplex) printing only.
- \value DuplexAuto The printer's default setting is used to determine whether
- duplex printing is used.
- \value DuplexLongSide Both sides of each sheet of paper are used for printing.
- The paper is turned over its longest edge before the second
- side is printed
- \value DuplexShortSide Both sides of each sheet of paper are used for printing.
- The paper is turned over its shortest edge before the second
- side is printed
-*/
-
-/*!
- \since 4.2
-
- Enables double sided printing if \a doubleSided is true; otherwise disables it.
-
- Currently this option is only supported on X11.
-*/
-void QPrinter::setDoubleSidedPrinting(bool doubleSided)
-{
- setDuplex(doubleSided ? DuplexAuto : DuplexNone);
-}
-
-
-/*!
- \since 4.2
-
- Returns true if double side printing is enabled.
-
- Currently this option is only supported on X11.
-*/
-bool QPrinter::doubleSidedPrinting() const
-{
- return duplex() != DuplexNone;
-}
-
-/*!
- \since 4.4
-
- Enables double sided printing based on the \a duplex mode.
-
- Currently this option is only supported on X11.
-*/
-void QPrinter::setDuplex(DuplexMode duplex)
-{
- Q_D(QPrinter);
- d->printEngine->setProperty(QPrintEngine::PPK_Duplex, duplex);
- d->addToManualSetList(QPrintEngine::PPK_Duplex);
-}
-
-/*!
- \since 4.4
-
- Returns the current duplex mode.
-
- Currently this option is only supported on X11.
-*/
-QPrinter::DuplexMode QPrinter::duplex() const
-{
- Q_D(const QPrinter);
- return static_cast <DuplexMode> (d->printEngine->property(QPrintEngine::PPK_Duplex).toInt());
-}
-
-/*!
- \since 4.4
-
- Returns the page's rectangle in \a unit; this is usually smaller
- than the paperRect() since the page normally has margins between
- its borders and the paper.
-
- \sa paperSize()
-*/
-QRectF QPrinter::pageRect(Unit unit) const
-{
- Q_D(const QPrinter);
- int res = resolution();
- const qreal multiplier = qt_multiplierForUnit(unit, res);
- // the page rect is in device pixels
- QRect devRect(d->printEngine->property(QPrintEngine::PPK_PageRect).toRect());
- if (unit == DevicePixel)
- return devRect;
- QRectF diRect(devRect.x()*72.0/res,
- devRect.y()*72.0/res,
- devRect.width()*72.0/res,
- devRect.height()*72.0/res);
- return QRectF(diRect.x()/multiplier, diRect.y()/multiplier,
- diRect.width()/multiplier, diRect.height()/multiplier);
-}
-
-
-/*!
- \since 4.4
-
- Returns the paper's rectangle in \a unit; this is usually larger
- than the pageRect().
-
- \sa pageRect()
-*/
-QRectF QPrinter::paperRect(Unit unit) const
-{
- Q_D(const QPrinter);
- int res = resolution();
- const qreal multiplier = qt_multiplierForUnit(unit, resolution());
- // the page rect is in device pixels
- QRect devRect(d->printEngine->property(QPrintEngine::PPK_PaperRect).toRect());
- if (unit == DevicePixel)
- return devRect;
- QRectF diRect(devRect.x()*72.0/res,
- devRect.y()*72.0/res,
- devRect.width()*72.0/res,
- devRect.height()*72.0/res);
- return QRectF(diRect.x()/multiplier, diRect.y()/multiplier,
- diRect.width()/multiplier, diRect.height()/multiplier);
-}
-
-/*!
- Returns the page's rectangle; this is usually smaller than the
- paperRect() since the page normally has margins between its
- borders and the paper.
-
- The unit of the returned rectangle is DevicePixel.
-
- \sa paperSize()
-*/
-QRect QPrinter::pageRect() const
-{
- Q_D(const QPrinter);
- return d->printEngine->property(QPrintEngine::PPK_PageRect).toRect();
-}
-
-/*!
- Returns the paper's rectangle; this is usually larger than the
- pageRect().
-
- The unit of the returned rectangle is DevicePixel.
-
- \sa pageRect()
-*/
-QRect QPrinter::paperRect() const
-{
- Q_D(const QPrinter);
- return d->printEngine->property(QPrintEngine::PPK_PaperRect).toRect();
-}
-
-
-/*!
- \since 4.4
-
- This function sets the \a left, \a top, \a right and \a bottom
- page margins for this printer. The unit of the margins are
- specified with the \a unit parameter.
-*/
-void QPrinter::setPageMargins(qreal left, qreal top, qreal right, qreal bottom, QPrinter::Unit unit)
-{
- Q_D(QPrinter);
- const qreal multiplier = qt_multiplierForUnit(unit, resolution());
- QList<QVariant> margins;
- margins << (left * multiplier) << (top * multiplier)
- << (right * multiplier) << (bottom * multiplier);
- d->printEngine->setProperty(QPrintEngine::PPK_PageMargins, margins);
- d->addToManualSetList(QPrintEngine::PPK_PageMargins);
- d->hasCustomPageMargins = true;
-}
-
-/*!
- \since 4.4
-
- Returns the page margins for this printer in \a left, \a top, \a
- right, \a bottom. The unit of the returned margins are specified
- with the \a unit parameter.
-*/
-void QPrinter::getPageMargins(qreal *left, qreal *top, qreal *right, qreal *bottom, QPrinter::Unit unit) const
-{
- Q_D(const QPrinter);
- Q_ASSERT(left && top && right && bottom);
- const qreal multiplier = qt_multiplierForUnit(unit, resolution());
- QList<QVariant> margins(d->printEngine->property(QPrintEngine::PPK_PageMargins).toList());
- *left = margins.at(0).toReal() / multiplier;
- *top = margins.at(1).toReal() / multiplier;
- *right = margins.at(2).toReal() / multiplier;
- *bottom = margins.at(3).toReal() / multiplier;
-}
-
-/*!
- \internal
-
- Returns the metric for the given \a id.
-*/
-int QPrinter::metric(PaintDeviceMetric id) const
-{
- Q_D(const QPrinter);
- return d->printEngine->metric(id);
-}
-
-/*!
- Returns the paint engine used by the printer.
-*/
-QPaintEngine *QPrinter::paintEngine() const
-{
- Q_D(const QPrinter);
- return d->paintEngine;
-}
-
-/*!
- \since 4.1
-
- Returns the print engine used by the printer.
-*/
-QPrintEngine *QPrinter::printEngine() const
-{
- Q_D(const QPrinter);
- return d->printEngine;
-}
-
-#if defined (Q_WS_WIN)
-/*!
- Sets the page size to be used by the printer under Windows to \a
- pageSize.
-
- \warning This function is not portable so you may prefer to use
- setPaperSize() instead.
-
- \sa winPageSize()
-*/
-void QPrinter::setWinPageSize(int pageSize)
-{
- Q_D(QPrinter);
- ABORT_IF_ACTIVE("QPrinter::setWinPageSize");
- d->printEngine->setProperty(QPrintEngine::PPK_WindowsPageSize, pageSize);
- d->addToManualSetList(QPrintEngine::PPK_WindowsPageSize);
-}
-
-/*!
- Returns the page size used by the printer under Windows.
-
- \warning This function is not portable so you may prefer to use
- paperSize() instead.
-
- \sa setWinPageSize()
-*/
-int QPrinter::winPageSize() const
-{
- Q_D(const QPrinter);
- return d->printEngine->property(QPrintEngine::PPK_WindowsPageSize).toInt();
-}
-#endif // Q_WS_WIN
-
-/*!
- Returns a list of the resolutions (a list of dots-per-inch
- integers) that the printer says it supports.
-
- For X11 where all printing is directly to postscript, this
- function will always return a one item list containing only the
- postscript resolution, i.e., 72 (72 dpi -- but see PrinterMode).
-*/
-QList<int> QPrinter::supportedResolutions() const
-{
- Q_D(const QPrinter);
- QList<QVariant> varlist
- = d->printEngine->property(QPrintEngine::PPK_SupportedResolutions).toList();
- QList<int> intlist;
- for (int i=0; i<varlist.size(); ++i)
- intlist << varlist.at(i).toInt();
- return intlist;
-}
-
-/*!
- Tells the printer to eject the current page and to continue
- printing on a new page. Returns true if this was successful;
- otherwise returns false.
-
- Calling newPage() on an inactive QPrinter object will always
- fail.
-*/
-bool QPrinter::newPage()
-{
- Q_D(QPrinter);
- if (d->printEngine->printerState() != QPrinter::Active)
- return false;
- return d->printEngine->newPage();
-}
-
-/*!
- Aborts the current print run. Returns true if the print run was
- successfully aborted and printerState() will return QPrinter::Aborted; otherwise
- returns false.
-
- It is not always possible to abort a print job. For example,
- all the data has gone to the printer but the printer cannot or
- will not cancel the job when asked to.
-*/
-bool QPrinter::abort()
-{
- Q_D(QPrinter);
- return d->printEngine->abort();
-}
-
-/*!
- Returns the current state of the printer. This may not always be
- accurate (for example if the printer doesn't have the capability
- of reporting its state to the operating system).
-*/
-QPrinter::PrinterState QPrinter::printerState() const
-{
- Q_D(const QPrinter);
- return d->printEngine->printerState();
-}
-
-
-/*! \fn void QPrinter::margins(uint *top, uint *left, uint *bottom, uint *right) const
-
- Sets *\a top, *\a left, *\a bottom, *\a right to be the top,
- left, bottom, and right margins.
-
- This function has been superseded by paperRect() and pageRect().
- Use paperRect().top() - pageRect().top() for the top margin,
- paperRect().left() - pageRect().left() for the left margin,
- paperRect().bottom() - pageRect().bottom() for the bottom margin,
- and papaerRect().right() - pageRect().right() for the right
- margin.
-
- \oldcode
- uint rightMargin;
- uint bottomMargin;
- printer->margins(0, 0, &bottomMargin, &rightMargin);
- \newcode
- int rightMargin = printer->paperRect().right() - printer->pageRect().right();
- int bottomMargin = printer->paperRect().bottom() - printer->pageRect().bottom();
- \endcode
-*/
-
-/*! \fn QSize QPrinter::margins() const
-
- \overload
-
- Returns a QSize containing the left margin and the top margin.
-
- This function has been superseded by paperRect() and pageRect().
- Use paperRect().left() - pageRect().left() for the left margin,
- and paperRect().top() - pageRect().top() for the top margin.
-
- \oldcode
- QSize margins = printer->margins();
- int leftMargin = margins.width();
- int topMargin = margins.height();
- \newcode
- int leftMargin = printer->paperRect().left() - printer->pageRect().left();
- int topMargin = printer->paperRect().top() - printer->pageRect().top();
- \endcode
-*/
-
-/*! \fn bool QPrinter::aborted()
-
- Use printerState() == QPrinter::Aborted instead.
-*/
-
-#ifdef Q_WS_WIN
-/*!
- \internal
-*/
-HDC QPrinter::getDC() const
-{
- Q_D(const QPrinter);
- return d->printEngine->getPrinterDC();
-}
-
-/*!
- \internal
-*/
-void QPrinter::releaseDC(HDC hdc) const
-{
- Q_D(const QPrinter);
- d->printEngine->releasePrinterDC(hdc);
-}
-
-/*!
- Returns the supported paper sizes for this printer.
-
- The values will be either a value that matches an entry in the
- QPrinter::PaperSource enum or a driver spesific value. The driver
- spesific values are greater than the constant DMBIN_USER declared
- in wingdi.h.
-
- \warning This function is only available in windows.
-*/
-
-QList<QPrinter::PaperSource> QPrinter::supportedPaperSources() const
-{
- Q_D(const QPrinter);
- QVariant v = d->printEngine->property(QPrintEngine::PPK_PaperSources);
-
- QList<QVariant> variant_list = v.toList();
- QList<QPrinter::PaperSource> int_list;
- for (int i=0; i<variant_list.size(); ++i)
- int_list << (QPrinter::PaperSource) variant_list.at(i).toInt();
-
- return int_list;
-}
-
-#endif
-
-/*!
- \fn QString QPrinter::printerSelectionOption() const
-
- Returns the printer options selection string. This is useful only
- if the print command has been explicitly set.
-
- The default value (an empty string) implies that the printer should
- be selected in a system-dependent manner.
-
- Any other value implies that the given value should be used.
-
- \warning This function is not available on Windows.
-
- \sa setPrinterSelectionOption()
-*/
-
-/*!
- \fn void QPrinter::setPrinterSelectionOption(const QString &option)
-
- Sets the printer to use \a option to select the printer. \a option
- is null by default (which implies that Qt should be smart enough
- to guess correctly), but it can be set to other values to use a
- specific printer selection option.
-
- If the printer selection option is changed while the printer is
- active, the current print job may or may not be affected.
-
- \warning This function is not available on Windows.
-
- \sa printerSelectionOption()
-*/
-
-#ifndef Q_WS_WIN
-QString QPrinter::printerSelectionOption() const
-{
- Q_D(const QPrinter);
- return d->printEngine->property(QPrintEngine::PPK_SelectionOption).toString();
-}
-
-void QPrinter::setPrinterSelectionOption(const QString &option)
-{
- Q_D(QPrinter);
- d->printEngine->setProperty(QPrintEngine::PPK_SelectionOption, option);
- d->addToManualSetList(QPrintEngine::PPK_SelectionOption);
-}
-#endif
-
-/*!
- \since 4.1
- \fn int QPrinter::fromPage() const
-
- Returns the number of the first page in a range of pages to be printed
- (the "from page" setting). Pages in a document are numbered according to
- the convention that the first page is page 1.
-
- By default, this function returns a special value of 0, meaning that
- the "from page" setting is unset.
-
- \note If fromPage() and toPage() both return 0, this indicates that
- \e{the whole document will be printed}.
-
- \sa setFromTo(), toPage()
-*/
-
-int QPrinter::fromPage() const
-{
- Q_D(const QPrinter);
- return d->fromPage;
-}
-
-/*!
- \since 4.1
-
- Returns the number of the last page in a range of pages to be printed
- (the "to page" setting). Pages in a document are numbered according to
- the convention that the first page is page 1.
-
- By default, this function returns a special value of 0, meaning that
- the "to page" setting is unset.
-
- \note If fromPage() and toPage() both return 0, this indicates that
- \e{the whole document will be printed}.
-
- The programmer is responsible for reading this setting and
- printing accordingly.
-
- \sa setFromTo(), fromPage()
-*/
-
-int QPrinter::toPage() const
-{
- Q_D(const QPrinter);
- return d->toPage;
-}
-
-/*!
- \since 4.1
-
- Sets the range of pages to be printed to cover the pages with numbers
- specified by \a from and \a to, where \a from corresponds to the first
- page in the range and \a to corresponds to the last.
-
- \note Pages in a document are numbered according to the convention that
- the first page is page 1. However, if \a from and \a to are both set to 0,
- the \e{whole document will be printed}.
-
- This function is mostly used to set a default value that the user can
- override in the print dialog when you call setup().
-
- \sa fromPage(), toPage()
-*/
-
-void QPrinter::setFromTo(int from, int to)
-{
- Q_D(QPrinter);
- if (from > to) {
- qWarning() << "QPrinter::setFromTo: 'from' must be less than or equal to 'to'";
- from = to;
- }
- d->fromPage = from;
- d->toPage = to;
-
- if (d->minPage == 0 && d->maxPage == 0) {
- d->minPage = 1;
- d->maxPage = to;
- d->options |= QAbstractPrintDialog::PrintPageRange;
- }
-}
-
-/*!
- \since 4.1
-
- Sets the print range option in to be \a range.
-*/
-void QPrinter::setPrintRange( PrintRange range )
-{
- Q_D(QPrinter);
- d->printRange = QAbstractPrintDialog::PrintRange(range);
-}
-
-/*!
- \since 4.1
-
- Returns the page range of the QPrinter. After the print setup
- dialog has been opened, this function returns the value selected
- by the user.
-
- \sa setPrintRange()
-*/
-QPrinter::PrintRange QPrinter::printRange() const
-{
- Q_D(const QPrinter);
- return PrintRange(d->printRange);
-}
-
-#if defined(QT3_SUPPORT)
-
-void QPrinter::setOutputToFile(bool f)
-{
- if (f) {
- if (outputFileName().isEmpty())
- setOutputFileName(QLatin1String("untitled_printer_document"));
- } else {
- setOutputFileName(QString());
- }
-}
-
-bool qt_compat_QPrinter_printSetup(QPrinter *printer, QPrinterPrivate *pd, QWidget *parent)
-{
- Q_UNUSED(pd);
- QPrintDialog dlg(printer, parent);
- return dlg.exec() != 0;
-}
-
-
-#ifdef Q_WS_MAC
-bool qt_compat_QPrinter_pageSetup(QPrinter *p, QWidget *parent)
-{
- QPageSetupDialog psd(p, parent);
- return psd.exec() != 0;
-}
-
-/*!
- Executes a page setup dialog so that the user can configure the type of
- page used for printing. Returns true if the contents of the dialog are
- accepted; returns false if the dialog is canceled.
-*/
-bool QPrinter::pageSetup(QWidget *parent)
-{
- return qt_compat_QPrinter_pageSetup(this, parent);
-}
-
-/*!
- Executes a print setup dialog so that the user can configure the printing
- process. Returns true if the contents of the dialog are accepted; returns
- false if the dialog is canceled.
-*/
-bool QPrinter::printSetup(QWidget *parent)
-{
- Q_D(QPrinter);
- return qt_compat_QPrinter_printSetup(this, d, parent);
-}
-#endif // Q_WS_MAC
-
-/*!
- Use QPrintDialog instead.
-
- \oldcode
- if (printer->setup(parent))
- ...
- \newcode
- QPrintDialog dialog(printer, parent);
- if (dialog.exec())
- ...
- \endcode
-*/
-bool QPrinter::setup(QWidget *parent)
-{
- Q_D(QPrinter);
- return qt_compat_QPrinter_printSetup(this, d, parent)
-#ifdef Q_WS_MAC
- && qt_compat_QPrinter_pageSetup(this, parent);
-#endif
- ;
-}
-
-/*!
- Use QPrintDialog::minPage() instead.
-*/
-int QPrinter::minPage() const
-{
- Q_D(const QPrinter);
- return d->minPage;
-}
-
-/*!
- Use QPrintDialog::maxPage() instead.
-*/
-int QPrinter::maxPage() const
-{
- Q_D(const QPrinter);
- return d->maxPage;
-}
-
-/*!
- Use QPrintDialog::setMinMax() instead.
-*/
-void QPrinter::setMinMax( int minPage, int maxPage )
-{
- Q_D(QPrinter);
- Q_ASSERT_X(minPage <= maxPage, "QPrinter::setMinMax",
- "'min' must be less than or equal to 'max'");
- d->minPage = minPage;
- d->maxPage = maxPage;
- d->options |= QPrintDialog::PrintPageRange;
-}
-
-/*!
- Returns true if the printer is set up to collate copies of printed documents;
- otherwise returns false.
-
- Use QPrintDialog::isOptionEnabled(QPrintDialog::PrintCollateCopies)
- instead.
-
- \sa collateCopies()
-*/
-bool QPrinter::collateCopiesEnabled() const
-{
- Q_D(const QPrinter);
- return (d->options & QPrintDialog::PrintCollateCopies);
-}
-
-/*!
- Use QPrintDialog::setOption(QPrintDialog::PrintCollateCopies)
- or QPrintDialog::setOptions(QPrintDialog::options()
- & ~QPrintDialog::PrintCollateCopies) instead, depending on \a
- enable.
-*/
-void QPrinter::setCollateCopiesEnabled(bool enable)
-{
- Q_D(QPrinter);
-
- if (enable)
- d->options |= QPrintDialog::PrintCollateCopies;
- else
- d->options &= ~QPrintDialog::PrintCollateCopies;
-}
-
-/*!
- Use QPrintDialog instead.
-*/
-void QPrinter::setOptionEnabled( PrinterOption option, bool enable )
-{
- Q_D(QPrinter);
- if (enable)
- d->options |= QPrintDialog::PrintDialogOption(1 << option);
- else
- d->options &= ~QPrintDialog::PrintDialogOption(1 << option);
-}
-
-/*!
- Use QPrintDialog instead.
-*/
-bool QPrinter::isOptionEnabled( PrinterOption option ) const
-{
- Q_D(const QPrinter);
- return (d->options & QPrintDialog::PrintDialogOption(option));
-}
-
-#endif // QT3_SUPPORT
-
-/*!
- \class QPrintEngine
- \reentrant
-
- \ingroup printing
-
- \brief The QPrintEngine class defines an interface for how QPrinter
- interacts with a given printing subsystem.
-
- The common case when creating your own print engine is to derive from both
- QPaintEngine and QPrintEngine. Various properties of a print engine are
- given with property() and set with setProperty().
-
- \sa QPaintEngine
-*/
-
-/*!
- \enum QPrintEngine::PrintEnginePropertyKey
-
- This enum is used to communicate properties between the print
- engine and QPrinter. A property may or may not be supported by a
- given print engine.
-
- \value PPK_CollateCopies A boolean value indicating whether the
- printout should be collated or not.
-
- \value PPK_ColorMode Refers to QPrinter::ColorMode, either color or
- monochrome.
-
- \value PPK_Creator A string describing the document's creator.
-
- \value PPK_Duplex A boolean value indicating whether both sides of
- the printer paper should be used for the printout.
-
- \value PPK_DocumentName A string describing the document name in
- the spooler.
-
- \value PPK_FontEmbedding A boolean value indicating whether data for
- the document's fonts should be embedded in the data sent to the
- printer.
-
- \value PPK_FullPage A boolean describing if the printer should be
- full page or not.
-
- \value PPK_NumberOfCopies Obsolete. An integer specifying the number of
- copies. Use PPK_CopyCount instead.
-
- \value PPK_Orientation Specifies a QPrinter::Orientation value.
-
- \value PPK_OutputFileName The output file name as a string. An
- empty file name indicates that the printer should not print to a file.
-
- \value PPK_PageOrder Specifies a QPrinter::PageOrder value.
-
- \value PPK_PageRect A QRect specifying the page rectangle
-
- \value PPK_PageSize Obsolete. Use PPK_PaperSize instead.
-
- \value PPK_PaperRect A QRect specifying the paper rectangle.
-
- \value PPK_PaperSource Specifies a QPrinter::PaperSource value.
-
- \value PPK_PaperSources Specifies more than one QPrinter::PaperSource value.
-
- \value PPK_PaperSize Specifies a QPrinter::PaperSize value.
-
- \value PPK_PrinterName A string specifying the name of the printer.
-
- \value PPK_PrinterProgram A string specifying the name of the
- printer program used for printing,
-
- \value PPK_Resolution An integer describing the dots per inch for
- this printer.
-
- \value PPK_SelectionOption
-
- \value PPK_SupportedResolutions A list of integer QVariants
- describing the set of supported resolutions that the printer has.
-
- \value PPK_SuppressSystemPrintStatus Suppress the built-in dialog for showing
- printing progress. As of 4.1 this only has effect on Mac OS X where, by default,
- a status dialog is shown.
-
- \value PPK_WindowsPageSize An integer specifying a DM_PAPER entry
- on Windows.
-
- \value PPK_CustomPaperSize A QSizeF specifying a custom paper size
- in the QPrinter::Point unit.
-
- \value PPK_PageMargins A QList<QVariant> containing the left, top,
- right and bottom margin values.
-
- \value PPK_CopyCount An integer specifying the number of copies to print.
-
- \value PPK_SupportsMultipleCopies A boolean value indicating whether or not
- the printer supports printing multiple copies in one job.
-
- \value PPK_CustomBase Basis for extension.
-*/
-
-/*!
- \fn QPrintEngine::~QPrintEngine()
-
- Destroys the print engine.
-*/
-
-/*!
- \fn void QPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &value)
-
- Sets the print engine's property specified by \a key to the given \a value.
-
- \sa property()
-*/
-
-/*!
- \fn void QPrintEngine::property(PrintEnginePropertyKey key) const
-
- Returns the print engine's property specified by \a key.
-
- \sa setProperty()
-*/
-
-/*!
- \fn bool QPrintEngine::newPage()
-
- Instructs the print engine to start a new page. Returns true if
- the printer was able to create the new page; otherwise returns false.
-*/
-
-/*!
- \fn bool QPrintEngine::abort()
-
- Instructs the print engine to abort the printing process. Returns
- true if successful; otherwise returns false.
-*/
-
-/*!
- \fn int QPrintEngine::metric(QPaintDevice::PaintDeviceMetric id) const
-
- Returns the metric for the given \a id.
-*/
-
-/*!
- \fn QPrinter::PrinterState QPrintEngine::printerState() const
-
- Returns the current state of the printer being used by the print engine.
-*/
-
-/*!
- \fn HDC QPrintEngine::getPrinterDC() const
- \internal
-*/
-
-/*!
- \fn void QPrintEngine::releasePrinterDC(HDC) const
- \internal
-*/
-
-/*
- Returns the dimensions for the given paper size, \a size, in millimeters.
-*/
-QSizeF qt_paperSizeToQSizeF(QPrinter::PaperSize size)
-{
- if (size == QPrinter::Custom) return QSizeF(0, 0);
- return QSizeF(qt_paperSizes[size][0], qt_paperSizes[size][1]);
-}
-
-/*
- Returns the PaperSize type that matches \a size, where \a size
- is in millimeters.
-
- Because dimensions may not always be completely accurate (for
- example when converting between units), a particular PaperSize
- will be returned if it matches within -1/+1 millimeters.
-*/
-QPrinter::PaperSize qSizeFTopaperSize(const QSizeF& size)
-{
- for (int i = 0; i < static_cast<int>(QPrinter::NPaperSize); ++i) {
- if (qt_paperSizes[i][0] >= size.width() - 1 &&
- qt_paperSizes[i][0] <= size.width() + 1 &&
- qt_paperSizes[i][1] >= size.height() - 1 &&
- qt_paperSizes[i][1] <= size.height() + 1) {
- return QPrinter::PaperSize(i);
- }
- }
-
- return QPrinter::Custom;
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_PRINTER
diff --git a/src/gui/painting/qprinter.h b/src/gui/painting/qprinter.h
deleted file mode 100644
index 58db6122e0..0000000000
--- a/src/gui/painting/qprinter.h
+++ /dev/null
@@ -1,337 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPRINTER_H
-#define QPRINTER_H
-
-#include <QtCore/qstring.h>
-#include <QtCore/qscopedpointer.h>
-#include <QtGui/qpaintdevice.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_PRINTER
-
-#if defined(B0)
-#undef B0 // Terminal hang-up. We assume that you do not want that.
-#endif
-
-class QPrinterPrivate;
-class QPaintEngine;
-class QPrintEngine;
-class QPrinterInfo;
-
-class Q_GUI_EXPORT QPrinter : public QPaintDevice
-{
- Q_DECLARE_PRIVATE(QPrinter)
-public:
- enum PrinterMode { ScreenResolution, PrinterResolution, HighResolution };
-
- explicit QPrinter(PrinterMode mode = ScreenResolution);
- explicit QPrinter(const QPrinterInfo& printer, PrinterMode mode = ScreenResolution);
- ~QPrinter();
-
- int devType() const;
-
- enum Orientation { Portrait, Landscape };
-
-#ifndef Q_QDOC
- enum PageSize { A4, B5, Letter, Legal, Executive,
- A0, A1, A2, A3, A5, A6, A7, A8, A9, B0, B1,
- B10, B2, B3, B4, B6, B7, B8, B9, C5E, Comm10E,
- DLE, Folio, Ledger, Tabloid, Custom, NPageSize = Custom, NPaperSize = Custom };
- typedef PageSize PaperSize;
-#else
- enum PageSize { A4, B5, Letter, Legal, Executive,
- A0, A1, A2, A3, A5, A6, A7, A8, A9, B0, B1,
- B10, B2, B3, B4, B6, B7, B8, B9, C5E, Comm10E,
- DLE, Folio, Ledger, Tabloid, Custom, NPageSize = Custom };
- enum PaperSize { A4, B5, Letter, Legal, Executive,
- A0, A1, A2, A3, A5, A6, A7, A8, A9, B0, B1,
- B10, B2, B3, B4, B6, B7, B8, B9, C5E, Comm10E,
- DLE, Folio, Ledger, Tabloid, Custom, NPageSize = Custom, NPaperSize = Custom };
-#endif
-
- enum PageOrder { FirstPageFirst,
- LastPageFirst };
-
- enum ColorMode { GrayScale,
- Color };
-
- enum PaperSource { OnlyOne,
- Lower,
- Middle,
- Manual,
- Envelope,
- EnvelopeManual,
- Auto,
- Tractor,
- SmallFormat,
- LargeFormat,
- LargeCapacity,
- Cassette,
- FormSource,
- MaxPageSource
- };
-
- enum PrinterState { Idle,
- Active,
- Aborted,
- Error };
-
- enum OutputFormat { NativeFormat, PdfFormat, PostScriptFormat };
-
- // ### Qt 5: Merge with QAbstractPrintDialog::PrintRange
- enum PrintRange { AllPages, Selection, PageRange, CurrentPage };
-
- enum Unit {
- Millimeter,
- Point,
- Inch,
- Pica,
- Didot,
- Cicero,
- DevicePixel
- };
-
- enum DuplexMode {
- DuplexNone = 0,
- DuplexAuto,
- DuplexLongSide,
- DuplexShortSide
- };
-
-#ifdef QT3_SUPPORT
- enum PrinterOption { PrintToFile, PrintSelection, PrintPageRange };
-#endif // QT3_SUPPORT
-
- void setOutputFormat(OutputFormat format);
- OutputFormat outputFormat() const;
-
- void setPrinterName(const QString &);
- QString printerName() const;
-
- bool isValid() const;
-
- void setOutputFileName(const QString &);
- QString outputFileName()const;
-
- void setPrintProgram(const QString &);
- QString printProgram() const;
-
- void setDocName(const QString &);
- QString docName() const;
-
- void setCreator(const QString &);
- QString creator() const;
-
- void setOrientation(Orientation);
- Orientation orientation() const;
-
- void setPageSize(PageSize);
- PageSize pageSize() const;
-
- void setPaperSize(PaperSize);
- PaperSize paperSize() const;
-
- void setPaperSize(const QSizeF &paperSize, Unit unit);
- QSizeF paperSize(Unit unit) const;
-
- void setPageOrder(PageOrder);
- PageOrder pageOrder() const;
-
- void setResolution(int);
- int resolution() const;
-
- void setColorMode(ColorMode);
- ColorMode colorMode() const;
-
- void setCollateCopies(bool collate);
- bool collateCopies() const;
-
- void setFullPage(bool);
- bool fullPage() const;
-
- void setNumCopies(int);
- int numCopies() const;
-
- int actualNumCopies() const;
-
- void setCopyCount(int);
- int copyCount() const;
- bool supportsMultipleCopies() const;
-
- void setPaperSource(PaperSource);
- PaperSource paperSource() const;
-
- void setDuplex(DuplexMode duplex);
- DuplexMode duplex() const;
-
- QList<int> supportedResolutions() const;
-
-#ifdef Q_WS_WIN
- QList<PaperSource> supportedPaperSources() const;
-#endif
-
- void setFontEmbeddingEnabled(bool enable);
- bool fontEmbeddingEnabled() const;
-
- void setDoubleSidedPrinting(bool enable);
- bool doubleSidedPrinting() const;
-
-#ifdef Q_WS_WIN
- void setWinPageSize(int winPageSize);
- int winPageSize() const;
-#endif
-
- QRect paperRect() const;
- QRect pageRect() const;
- QRectF paperRect(Unit) const;
- QRectF pageRect(Unit) const;
-
-#if !defined(Q_WS_WIN) || defined(qdoc)
- QString printerSelectionOption() const;
- void setPrinterSelectionOption(const QString &);
-#endif
-
- bool newPage();
- bool abort();
-
- PrinterState printerState() const;
-
- QPaintEngine *paintEngine() const;
- QPrintEngine *printEngine() const;
-
-#ifdef Q_WS_WIN
- HDC getDC() const;
- void releaseDC(HDC hdc) const;
-#endif
-
- void setFromTo(int fromPage, int toPage);
- int fromPage() const;
- int toPage() const;
-
- void setPrintRange(PrintRange range);
- PrintRange printRange() const;
-
- void setPageMargins(qreal left, qreal top, qreal right, qreal bottom, Unit unit);
- void getPageMargins(qreal *left, qreal *top, qreal *right, qreal *bottom, Unit unit) const;
-
-#ifdef QT3_SUPPORT
-#ifdef Q_WS_MAC
- QT3_SUPPORT bool pageSetup(QWidget *parent = 0);
- QT3_SUPPORT bool printSetup(QWidget *parent = 0);
-#endif
-
- QT3_SUPPORT bool setup(QWidget *parent = 0);
-
- QT3_SUPPORT void setMinMax(int minPage, int maxPage);
- QT3_SUPPORT int minPage() const;
- QT3_SUPPORT int maxPage() const;
-
- QT3_SUPPORT void setCollateCopiesEnabled(bool);
- QT3_SUPPORT bool collateCopiesEnabled() const;
-
- QT3_SUPPORT void setOptionEnabled(PrinterOption, bool enable);
- QT3_SUPPORT bool isOptionEnabled(PrinterOption) const;
-
- inline QT3_SUPPORT QSize margins() const;
- inline QT3_SUPPORT void margins(uint *top, uint *left, uint *bottom, uint *right) const;
-
- inline QT3_SUPPORT bool aborted() { return printerState() == Aborted; }
-
- QT3_SUPPORT void setOutputToFile(bool);
- inline QT3_SUPPORT bool outputToFile() const { return !outputFileName().isEmpty(); }
-#endif
-
-protected:
- int metric(PaintDeviceMetric) const;
- void setEngines(QPrintEngine *printEngine, QPaintEngine *paintEngine);
-
-private:
- void init(PrinterMode mode);
-
- Q_DISABLE_COPY(QPrinter)
-
- QScopedPointer<QPrinterPrivate> d_ptr;
-
- friend class QPrintDialogPrivate;
- friend class QAbstractPrintDialog;
- friend class QAbstractPrintDialogPrivate;
- friend class QPrintPreviewWidgetPrivate;
- friend class QTextDocument;
- friend class QPageSetupWidget;
-};
-
-#ifdef QT3_SUPPORT
-inline QSize QPrinter::margins() const
-{
- QRect page = pageRect();
- QRect paper = paperRect();
- return QSize(page.left() - paper.left(), page.top() - paper.top());
-}
-
-inline void QPrinter::margins(uint *top, uint *left, uint *bottom, uint *right) const
-{
- QRect page = pageRect();
- QRect paper = paperRect();
- if (top)
- *top = page.top() - paper.top();
- if (left)
- *left = page.left() - paper.left();
- if (bottom)
- *bottom = paper.bottom() - page.bottom();
- if (right)
- *right = paper.right() - page.right();
-}
-#endif
-
-#endif // QT_NO_PRINTER
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QPRINTER_H
diff --git a/src/gui/painting/qprinter_p.h b/src/gui/painting/qprinter_p.h
deleted file mode 100644
index 2d35672c2c..0000000000
--- a/src/gui/painting/qprinter_p.h
+++ /dev/null
@@ -1,140 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPRINTER_P_H
-#define QPRINTER_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-
-#include "QtCore/qglobal.h"
-
-#ifndef QT_NO_PRINTER
-
-#include "QtGui/qprinter.h"
-#include "QtGui/qprintengine.h"
-#include "QtGui/qprintdialog.h"
-#include "QtCore/qpointer.h"
-
-#include <limits.h>
-
-QT_BEGIN_NAMESPACE
-
-class QPrintEngine;
-class QPreviewPaintEngine;
-class QPicture;
-
-class QPrinterPrivate
-{
- Q_DECLARE_PUBLIC(QPrinter)
-public:
- QPrinterPrivate(QPrinter *printer)
- : printEngine(0)
- , paintEngine(0)
- , q_ptr(printer)
- , options(QAbstractPrintDialog::PrintToFile | QAbstractPrintDialog::PrintPageRange |
- QAbstractPrintDialog::PrintCollateCopies | QAbstractPrintDialog::PrintShowPageSize)
- , printRange(QAbstractPrintDialog::AllPages)
- , minPage(1)
- , maxPage(INT_MAX)
- , fromPage(0)
- , toPage(0)
- , use_default_engine(true)
- , validPrinter(false)
- , hasCustomPageMargins(false)
- , hasUserSetPageSize(false)
- {
- }
-
- ~QPrinterPrivate() {
-
- }
-
- void createDefaultEngines();
-#ifndef QT_NO_PRINTPREVIEWWIDGET
- QList<const QPicture *> previewPages() const;
- void setPreviewMode(bool);
-#endif
-
- void addToManualSetList(QPrintEngine::PrintEnginePropertyKey key);
-
- QPrinter::PrinterMode printerMode;
- QPrinter::OutputFormat outputFormat;
- QPrintEngine *printEngine;
- QPaintEngine *paintEngine;
-
- QPrintEngine *realPrintEngine;
- QPaintEngine *realPaintEngine;
-#ifndef QT_NO_PRINTPREVIEWWIDGET
- QPreviewPaintEngine *previewEngine;
-#endif
-
- QPrinter *q_ptr;
-
- QAbstractPrintDialog::PrintDialogOptions options;
- QAbstractPrintDialog::PrintRange printRange;
- int minPage, maxPage, fromPage, toPage;
-
- uint use_default_engine : 1;
- uint had_default_engines : 1;
-
- uint validPrinter : 1;
- uint hasCustomPageMargins : 1;
- uint hasUserSetPageSize : 1;
-
- // Used to remember which properties have been manually set by the user.
- QList<QPrintEngine::PrintEnginePropertyKey> manualSetList;
-};
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_PRINTER
-
-#endif // QPRINTER_P_H
diff --git a/src/gui/painting/qprinterinfo.cpp b/src/gui/painting/qprinterinfo.cpp
deleted file mode 100644
index a7ddc85a54..0000000000
--- a/src/gui/painting/qprinterinfo.cpp
+++ /dev/null
@@ -1,173 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the documentation of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:FDL$
-** GNU Free Documentation License
-** Alternatively, this file may be used under the terms of the GNU Free
-** Documentation License version 1.3 as published by the Free Software
-** Foundation and appearing in the file included in the packaging of
-** this file.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms
-** and conditions contained in a signed written agreement between you
-** and Nokia.
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qprinterinfo.h"
-#include "qprinterinfo_p.h"
-
-#ifndef QT_NO_PRINTER
-
-QT_BEGIN_NAMESPACE
-
-QPrinterInfoPrivate QPrinterInfoPrivate::shared_null;
-
-
-/*!
- \class QPrinterInfo
-
- \brief The QPrinterInfo class gives access to information about
- existing printers.
-
- \ingroup printing
-
- Use the static functions to generate a list of QPrinterInfo
- objects. Each QPrinterInfo object in the list represents a single
- printer and can be queried for name, supported paper sizes, and
- whether or not it is the default printer.
-
- \since 4.4
-*/
-
-/*!
- \fn QList<QPrinterInfo> QPrinterInfo::availablePrinters()
-
- Returns a list of available printers on the system.
-*/
-
-/*!
- \fn QPrinterInfo QPrinterInfo::defaultPrinter()
-
- Returns the default printer on the system.
-
- The return value should be checked using isNull() before being
- used, in case there is no default printer.
-
- \sa isNull()
-*/
-
-/*!
- Constructs an empty QPrinterInfo object.
-
- \sa isNull()
-*/
-QPrinterInfo::QPrinterInfo()
- : d_ptr(&QPrinterInfoPrivate::shared_null)
-{
-}
-
-/*!
- Constructs a copy of \a other.
-*/
-QPrinterInfo::QPrinterInfo(const QPrinterInfo &other)
- : d_ptr(new QPrinterInfoPrivate(*other.d_ptr))
-{
-}
-
-/*!
- Constructs a QPrinterInfo object from \a printer.
-*/
-QPrinterInfo::QPrinterInfo(const QPrinter &printer)
- : d_ptr(&QPrinterInfoPrivate::shared_null)
-{
- foreach (const QPrinterInfo &printerInfo, availablePrinters()) {
- if (printerInfo.printerName() == printer.printerName()) {
- d_ptr.reset(new QPrinterInfoPrivate(*printerInfo.d_ptr));
- break;
- }
- }
-}
-
-/*!
- \internal
-*/
-QPrinterInfo::QPrinterInfo(const QString &name)
- : d_ptr(new QPrinterInfoPrivate(name))
-{
-}
-
-/*!
- Destroys the QPrinterInfo object. References to the values in the
- object become invalid.
-*/
-QPrinterInfo::~QPrinterInfo()
-{
-}
-
-/*!
- Sets the QPrinterInfo object to be equal to \a other.
-*/
-QPrinterInfo &QPrinterInfo::operator=(const QPrinterInfo &other)
-{
- Q_ASSERT(d_ptr);
- d_ptr.reset(new QPrinterInfoPrivate(*other.d_ptr));
- return *this;
-}
-
-/*!
- Returns the name of the printer.
-
- \sa QPrinter::setPrinterName()
-*/
-QString QPrinterInfo::printerName() const
-{
- const Q_D(QPrinterInfo);
- return d->name;
-}
-
-/*!
- Returns whether this QPrinterInfo object holds a printer definition.
-
- An empty QPrinterInfo object could result for example from calling
- defaultPrinter() when there are no printers on the system.
-*/
-bool QPrinterInfo::isNull() const
-{
- const Q_D(QPrinterInfo);
- return d == &QPrinterInfoPrivate::shared_null;
-}
-
-/*!
- Returns whether this printer is the default printer.
-*/
-bool QPrinterInfo::isDefault() const
-{
- const Q_D(QPrinterInfo);
- return d->isDefault;
-}
-
-/*!
- \fn QList< QPrinter::PaperSize> QPrinterInfo::supportedPaperSizes() const
- \since 4.4
-
- Returns a list of supported paper sizes by the printer.
-
- Not all printer drivers support this query, so the list may be empty.
- On Mac OS X 10.3, this function always returns an empty list.
-*/
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_PRINTER
diff --git a/src/gui/painting/qprinterinfo.h b/src/gui/painting/qprinterinfo.h
deleted file mode 100644
index 9ff1bd16bd..0000000000
--- a/src/gui/painting/qprinterinfo.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPRINTERINFO_H
-#define QPRINTERINFO_H
-
-#include <QtCore/QList>
-
-#include <QtGui/QPrinter>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_PRINTER
-class QPrinterInfoPrivate;
-class QPrinterInfoPrivateDeleter;
-class Q_GUI_EXPORT QPrinterInfo
-{
-public:
- QPrinterInfo();
- QPrinterInfo(const QPrinterInfo &other);
- QPrinterInfo(const QPrinter &printer);
- ~QPrinterInfo();
-
- QPrinterInfo &operator=(const QPrinterInfo &other);
-
- QString printerName() const;
- bool isNull() const;
- bool isDefault() const;
- QList<QPrinter::PaperSize> supportedPaperSizes() const;
-
- static QList<QPrinterInfo> availablePrinters();
- static QPrinterInfo defaultPrinter();
-
-private:
- QPrinterInfo(const QString &name);
-
-private:
- Q_DECLARE_PRIVATE(QPrinterInfo)
- QScopedPointer<QPrinterInfoPrivate, QPrinterInfoPrivateDeleter> d_ptr;
-};
-
-#endif // QT_NO_PRINTER
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QPRINTERINFO_H
diff --git a/src/gui/painting/qprinterinfo_p.h b/src/gui/painting/qprinterinfo_p.h
deleted file mode 100644
index a3f7d5d252..0000000000
--- a/src/gui/painting/qprinterinfo_p.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPRINTERINFO_P_H
-#define QPRINTERINFO_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "QtCore/qglobal.h"
-
-#ifndef QT_NO_PRINTER
-
-#include "QtCore/qlist.h"
-
-QT_BEGIN_NAMESPACE
-
-class QPrinterInfoPrivate
-{
-public:
- QPrinterInfoPrivate(const QString& name = QString()) :
- name(name), isDefault(false)
-#if (defined(Q_OS_UNIX) && !defined(Q_OS_MAC) && !defined(Q_OS_SYMBIAN)) || defined(Q_WS_QPA)
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
- , cupsPrinterIndex(0), hasPaperSizes(false)
-#endif
-#endif
- {}
- ~QPrinterInfoPrivate()
- {}
-
- static QPrinterInfoPrivate shared_null;
-
- QString name;
- bool isDefault;
-
-#if (defined(Q_OS_UNIX) && !defined(Q_OS_MAC) && !defined(Q_OS_SYMBIAN)) || defined(Q_WS_QPA)
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
- int cupsPrinterIndex;
- mutable bool hasPaperSizes;
- mutable QList<QPrinter::PaperSize> paperSizes;
-#endif
-#endif
-};
-
-
-class QPrinterInfoPrivateDeleter
-{
-public:
- static inline void cleanup(QPrinterInfoPrivate *d)
- {
- if (d != &QPrinterInfoPrivate::shared_null)
- delete d;
- }
-};
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_PRINTER
-
-#endif // QPRINTERINFO_P_H
diff --git a/src/gui/painting/qprinterinfo_unix.cpp b/src/gui/painting/qprinterinfo_unix.cpp
deleted file mode 100644
index aa220aad57..0000000000
--- a/src/gui/painting/qprinterinfo_unix.cpp
+++ /dev/null
@@ -1,927 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qprinterinfo.h"
-#include "qprinterinfo_p.h"
-
-#include <qfile.h>
-#include <qfileinfo.h>
-#include <qdir.h>
-#include <qprintdialog.h>
-#include <qlibrary.h>
-#include <qtextstream.h>
-
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
-# include <private/qcups_p.h>
-# include <cups/cups.h>
-# include <private/qpdf_p.h>
-#endif
-
-#include <private/qprinterinfo_unix_p.h>
-
-QT_BEGIN_NAMESPACE
-
-#ifndef QT_NO_PRINTER
-
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
-// preserver names in ascending order for the binary search
-static const struct NamedPaperSize {
- const char *const name;
- QPrinter::PaperSize size;
-} named_sizes_map[QPrinter::NPageSize] = {
- { "A0", QPrinter::A0 },
- { "A1", QPrinter::A1 },
- { "A2", QPrinter::A2 },
- { "A3", QPrinter::A3 },
- { "A4", QPrinter::A4 },
- { "A5", QPrinter::A5 },
- { "A6", QPrinter::A6 },
- { "A7", QPrinter::A7 },
- { "A8", QPrinter::A8 },
- { "A9", QPrinter::A9 },
- { "B0", QPrinter::B0 },
- { "B1", QPrinter::B1 },
- { "B10", QPrinter::B10 },
- { "B2", QPrinter::B2 },
- { "B4", QPrinter::B4 },
- { "B5", QPrinter::B5 },
- { "B6", QPrinter::B6 },
- { "B7", QPrinter::B7 },
- { "B8", QPrinter::B8 },
- { "B9", QPrinter::B9 },
- { "C5E", QPrinter::C5E },
- { "Comm10E", QPrinter::Comm10E },
- { "Custom", QPrinter::Custom },
- { "DLE", QPrinter::DLE },
- { "Executive", QPrinter::Executive },
- { "Folio", QPrinter::Folio },
- { "Ledger", QPrinter::Ledger },
- { "Legal", QPrinter::Legal },
- { "Letter", QPrinter::Letter },
- { "Tabloid", QPrinter::Tabloid }
-};
-
-inline bool operator<(const char *name, const NamedPaperSize &data)
-{ return qstrcmp(name, data.name) < 0; }
-inline bool operator<(const NamedPaperSize &data, const char *name)
-{ return qstrcmp(data.name, name) < 0; }
-
-static inline QPrinter::PaperSize string2PaperSize(const char *name)
-{
- const NamedPaperSize *r = qBinaryFind(named_sizes_map, named_sizes_map + QPrinter::NPageSize, name);
- if (r - named_sizes_map != QPrinter::NPageSize)
- return r->size;
- return QPrinter::Custom;
-}
-
-static inline const char *paperSize2String(QPrinter::PaperSize size)
-{
- for (int i = 0; i < QPrinter::NPageSize; ++i) {
- if (size == named_sizes_map[i].size)
- return named_sizes_map[i].name;
- }
- return 0;
-}
-#endif
-
-void qt_perhapsAddPrinter(QList<QPrinterDescription> *printers, const QString &name,
- QString host, QString comment,
- QStringList aliases)
-{
- for (int i = 0; i < printers->size(); ++i)
- if (printers->at(i).samePrinter(name))
- return;
-
-#ifndef QT_NO_PRINTDIALOG
- if (host.isEmpty())
- host = QPrintDialog::tr("locally connected");
-#endif
- printers->append(QPrinterDescription(name.simplified(), host.simplified(), comment.simplified(), aliases));
-}
-
-void qt_parsePrinterDesc(QString printerDesc, QList<QPrinterDescription> *printers)
-{
- if (printerDesc.length() < 1)
- return;
-
- printerDesc = printerDesc.simplified();
- int i = printerDesc.indexOf(QLatin1Char(':'));
- QString printerName, printerComment, printerHost;
- QStringList aliases;
-
- if (i >= 0) {
- // have ':' want '|'
- int j = printerDesc.indexOf(QLatin1Char('|'));
- if (j > 0 && j < i) {
- printerName = printerDesc.left(j);
- aliases = printerDesc.mid(j + 1, i - j - 1).split(QLatin1Char('|'));
-#ifndef QT_NO_PRINTDIALOG
- // try extracting a comment from the aliases
- printerComment = QPrintDialog::tr("Aliases: %1")
- .arg(aliases.join(QLatin1String(", ")));
-#endif
- } else {
- printerName = printerDesc.left(i);
- }
- // look for lprng pseudo all printers entry
- i = printerDesc.indexOf(QRegExp(QLatin1String(": *all *=")));
- if (i >= 0)
- printerName = QString();
- // look for signs of this being a remote printer
- i = printerDesc.indexOf(QRegExp(QLatin1String(": *rm *=")));
- if (i >= 0) {
- // point k at the end of remote host name
- while (printerDesc[i] != QLatin1Char('='))
- i++;
- while (printerDesc[i] == QLatin1Char('=') || printerDesc[i].isSpace())
- i++;
- j = i;
- while (j < (int)printerDesc.length() && printerDesc[j] != QLatin1Char(':'))
- j++;
-
- // and stuff that into the string
- printerHost = printerDesc.mid(i, j - i);
- }
- }
- if (printerName.length())
- qt_perhapsAddPrinter(printers, printerName, printerHost, printerComment,
- aliases);
-}
-
-int qt_parsePrintcap(QList<QPrinterDescription> *printers, const QString& fileName)
-{
- QFile printcap(fileName);
- if (!printcap.open(QIODevice::ReadOnly))
- return NotFound;
-
- char *line_ascii = new char[1025];
- line_ascii[1024] = '\0';
-
- QString printerDesc;
- bool atEnd = false;
-
- while (!atEnd) {
- if (printcap.atEnd() || printcap.readLine(line_ascii, 1024) <= 0)
- atEnd = true;
- QString line = QString::fromLocal8Bit(line_ascii);
- line = line.trimmed();
- if (line.length() >= 1 && line[int(line.length()) - 1] == QLatin1Char('\\'))
- line.chop(1);
- if (line[0] == QLatin1Char('#')) {
- if (!atEnd)
- continue;
- } else if (line[0] == QLatin1Char('|') || line[0] == QLatin1Char(':')
- || line.isEmpty()) {
- printerDesc += line;
- if (!atEnd)
- continue;
- }
-
- qt_parsePrinterDesc(printerDesc, printers);
-
- // add the first line of the new printer definition
- printerDesc = line;
- }
- delete[] line_ascii;
- return Success;
-}
-
-/*!
- \internal
-
- Checks $HOME/.printers for a line matching '_default <name>' (where
- <name> does not contain any white space). The first such match
- results in <name> being returned.
- If no lines match then an empty string is returned.
-*/
-QString qt_getDefaultFromHomePrinters()
-{
- QFile file(QDir::homePath() + QLatin1String("/.printers"));
- if (!file.open(QIODevice::ReadOnly))
- return QString();
- QString all(QLatin1String(file.readAll()));
- QStringList words = all.split(QRegExp(QLatin1String("\\W+")), QString::SkipEmptyParts);
- const int i = words.indexOf(QLatin1String("_default"));
- if (i != -1 && i < words.size() - 1)
- return words.at(i + 1);
- return QString();
-}
-
-// solaris, not 2.6
-void qt_parseEtcLpPrinters(QList<QPrinterDescription> *printers)
-{
- QDir lp(QLatin1String("/etc/lp/printers"));
- QFileInfoList dirs = lp.entryInfoList();
- if (dirs.isEmpty())
- return;
-
- QString tmp;
- for (int i = 0; i < dirs.size(); ++i) {
- QFileInfo printer = dirs.at(i);
- if (printer.isDir()) {
- tmp.sprintf("/etc/lp/printers/%s/configuration",
- printer.fileName().toAscii().data());
- QFile configuration(tmp);
- char *line = new char[1025];
- QString remote(QLatin1String("Remote:"));
- QString contentType(QLatin1String("Content types:"));
- QString printerHost;
- bool canPrintPostscript = false;
- if (configuration.open(QIODevice::ReadOnly)) {
- while (!configuration.atEnd() &&
- configuration.readLine(line, 1024) > 0) {
- if (QString::fromLatin1(line).startsWith(remote)) {
- const char *p = line;
- while (*p != ':')
- p++;
- p++;
- while (isspace((uchar) *p))
- p++;
- printerHost = QString::fromLocal8Bit(p);
- printerHost = printerHost.simplified();
- } else if (QString::fromLatin1(line).startsWith(contentType)) {
- char *p = line;
- while (*p != ':')
- p++;
- p++;
- char *e;
- while (*p) {
- while (isspace((uchar) *p))
- p++;
- if (*p) {
- char s;
- e = p;
- while (isalnum((uchar) *e))
- e++;
- s = *e;
- *e = '\0';
- if (!qstrcmp(p, "postscript") ||
- !qstrcmp(p, "any"))
- canPrintPostscript = true;
- *e = s;
- if (s == ',')
- e++;
- p = e;
- }
- }
- }
- }
- if (canPrintPostscript)
- qt_perhapsAddPrinter(printers, printer.fileName(),
- printerHost, QLatin1String(""));
- }
- delete[] line;
- }
- }
-}
-
-// solaris 2.6
-char *qt_parsePrintersConf(QList<QPrinterDescription> *printers, bool *found)
-{
- QFile pc(QLatin1String("/etc/printers.conf"));
- if (!pc.open(QIODevice::ReadOnly)) {
- if (found)
- *found = false;
- return 0;
- }
- if (found)
- *found = true;
-
- char *line = new char[1025];
- line[1024] = '\0';
-
- QString printerDesc;
- int lineLength = 0;
-
- char *defaultPrinter = 0;
-
- while (!pc.atEnd() &&
- (lineLength=pc.readLine(line, 1024)) > 0) {
- if (*line == '#') {
- *line = '\0';
- lineLength = 0;
- }
- if (lineLength >= 2 && line[lineLength-2] == '\\') {
- line[lineLength-2] = '\0';
- printerDesc += QString::fromLocal8Bit(line);
- } else {
- printerDesc += QString::fromLocal8Bit(line);
- printerDesc = printerDesc.simplified();
- int i = printerDesc.indexOf(QLatin1Char(':'));
- QString printerName, printerHost, printerComment;
- QStringList aliases;
- if (i >= 0) {
- // have : want |
- int j = printerDesc.indexOf(QLatin1Char('|'));
- if (j >= i)
- j = -1;
- printerName = printerDesc.mid(0, j < 0 ? i : j);
- if (printerName == QLatin1String("_default")) {
- i = printerDesc.indexOf(
- QRegExp(QLatin1String(": *use *=")));
- while (printerDesc[i] != QLatin1Char('='))
- i++;
- while (printerDesc[i] == QLatin1Char('=') || printerDesc[i].isSpace())
- i++;
- j = i;
- while (j < (int)printerDesc.length() &&
- printerDesc[j] != QLatin1Char(':') && printerDesc[j] != QLatin1Char(','))
- j++;
- // that's our default printer
- defaultPrinter =
- qstrdup(printerDesc.mid(i, j-i).toAscii().data());
- printerName = QString();
- printerDesc = QString();
- } else if (printerName == QLatin1String("_all")) {
- // skip it.. any other cases we want to skip?
- printerName = QString();
- printerDesc = QString();
- }
-
- if (j > 0) {
- // try extracting a comment from the aliases
- aliases = printerDesc.mid(j + 1, i - j - 1).split(QLatin1Char('|'));
-#ifndef QT_NO_PRINTDIALOG
- printerComment = QPrintDialog::tr("Aliases: %1")
- .arg(aliases.join(QLatin1String(", ")));
-#endif
- }
- // look for signs of this being a remote printer
- i = printerDesc.indexOf(
- QRegExp(QLatin1String(": *bsdaddr *=")));
- if (i >= 0) {
- // point k at the end of remote host name
- while (printerDesc[i] != QLatin1Char('='))
- i++;
- while (printerDesc[i] == QLatin1Char('=') || printerDesc[i].isSpace())
- i++;
- j = i;
- while (j < (int)printerDesc.length() &&
- printerDesc[j] != QLatin1Char(':') && printerDesc[j] != QLatin1Char(','))
- j++;
- // and stuff that into the string
- printerHost = printerDesc.mid(i, j-i);
- // maybe stick the remote printer name into the comment
- if (printerDesc[j] == QLatin1Char(',')) {
- i = ++j;
- while (printerDesc[i].isSpace())
- i++;
- j = i;
- while (j < (int)printerDesc.length() &&
- printerDesc[j] != QLatin1Char(':') && printerDesc[j] != QLatin1Char(','))
- j++;
- if (printerName != printerDesc.mid(i, j-i)) {
- printerComment =
- QLatin1String("Remote name: ");
- printerComment += printerDesc.mid(i, j-i);
- }
- }
- }
- }
- if (printerComment == QLatin1String(":"))
- printerComment = QString(); // for cups
- if (printerName.length())
- qt_perhapsAddPrinter(printers, printerName, printerHost,
- printerComment, aliases);
- // chop away the line, for processing the next one
- printerDesc = QString();
- }
- }
- delete[] line;
- return defaultPrinter;
-}
-
-#ifndef QT_NO_NIS
-
-#if defined(Q_C_CALLBACKS)
-extern "C" {
-#endif
-
-int qt_pd_foreach(int /*status */, char * /*key */, int /*keyLen */,
- char *val, int valLen, char *data)
-{
- qt_parsePrinterDesc(QString::fromLatin1(val, valLen), (QList<QPrinterDescription> *)data);
- return 0;
-}
-
-#if defined(Q_C_CALLBACKS)
-}
-#endif
-
-int qt_retrieveNisPrinters(QList<QPrinterDescription> *printers)
-{
-#ifndef QT_NO_LIBRARY
- typedef int (*WildCast)(int, char *, int, char *, int, char *);
- char printersConfByname[] = "printers.conf.byname";
- char *domain;
- int err;
-
- QLibrary lib(QLatin1String("nsl"));
- typedef int (*ypGetDefaultDomain)(char **);
- ypGetDefaultDomain _ypGetDefaultDomain = (ypGetDefaultDomain)lib.resolve("yp_get_default_domain");
- typedef int (*ypAll)(const char *, const char *, const struct ypall_callback *);
- ypAll _ypAll = (ypAll)lib.resolve("yp_all");
-
- if (_ypGetDefaultDomain && _ypAll) {
- err = _ypGetDefaultDomain(&domain);
- if (err == 0) {
- ypall_callback cb;
- // wild cast to support K&R-style system headers
- (WildCast &) cb.foreach = (WildCast) qt_pd_foreach;
- cb.data = (char *) printers;
- err = _ypAll(domain, printersConfByname, &cb);
- }
- if (!err)
- return Success;
- }
-#endif //QT_NO_LIBRARY
- return Unavail;
-}
-
-#endif // QT_NO_NIS
-
-char *qt_parseNsswitchPrintersEntry(QList<QPrinterDescription> *printers, char *line)
-{
-#define skipSpaces() \
- while (line[k] != '\0' && isspace((uchar) line[k])) \
- k++
-
- char *defaultPrinter = 0;
- bool stop = false;
- int lastStatus = NotFound;
-
- int k = 8;
- skipSpaces();
- if (line[k] != ':')
- return 0;
- k++;
-
- char *cp = strchr(line, '#');
- if (cp != 0)
- *cp = '\0';
-
- while (line[k] != '\0') {
- if (isspace((uchar) line[k])) {
- k++;
- } else if (line[k] == '[') {
- k++;
- skipSpaces();
- while (line[k] != '\0') {
- char status = tolower(line[k]);
- char action = '?';
-
- while (line[k] != '=' && line[k] != ']' && line[k] != '\0')
- k++;
- if (line[k] == '=') {
- k++;
- skipSpaces();
- action = tolower(line[k]);
- while (line[k] != '\0' && !isspace((uchar) line[k]) && line[k] != ']')
- k++;
- } else if (line[k] == ']') {
- k++;
- break;
- }
- skipSpaces();
-
- if (lastStatus == status)
- stop = (action == (char) Return);
- }
- } else {
- if (stop)
- break;
-
- QByteArray source;
- while (line[k] != '\0' && !isspace((uchar) line[k]) && line[k] != '[') {
- source += line[k];
- k++;
- }
-
- if (source == "user") {
- lastStatus = qt_parsePrintcap(printers,
- QDir::homePath() + QLatin1String("/.printers"));
- } else if (source == "files") {
- bool found;
- defaultPrinter = qt_parsePrintersConf(printers, &found);
- if (found)
- lastStatus = Success;
-#ifndef QT_NO_NIS
- } else if (source == "nis") {
- lastStatus = qt_retrieveNisPrinters(printers);
-#endif
- } else {
- // nisplus, dns, etc., are not implemented yet
- lastStatus = NotFound;
- }
- stop = (lastStatus == Success);
- }
- }
- return defaultPrinter;
-}
-
-char *qt_parseNsswitchConf(QList<QPrinterDescription> *printers)
-{
- QFile nc(QLatin1String("/etc/nsswitch.conf"));
- if (!nc.open(QIODevice::ReadOnly))
- return 0;
-
- char *defaultPrinter = 0;
-
- char *line = new char[1025];
- line[1024] = '\0';
-
- while (!nc.atEnd() &&
- nc.readLine(line, 1024) > 0) {
- if (qstrncmp(line, "printers", 8) == 0) {
- defaultPrinter = qt_parseNsswitchPrintersEntry(printers, line);
- delete[] line;
- return defaultPrinter;
- }
- }
-
- strcpy(line, "printers: user files nis nisplus xfn");
- defaultPrinter = qt_parseNsswitchPrintersEntry(printers, line);
- delete[] line;
- return defaultPrinter;
-}
-
-// HP-UX
-void qt_parseEtcLpMember(QList<QPrinterDescription> *printers)
-{
- QDir lp(QLatin1String("/etc/lp/member"));
- if (!lp.exists())
- return;
- QFileInfoList dirs = lp.entryInfoList();
- if (dirs.isEmpty())
- return;
-
-#ifdef QT_NO_PRINTDIALOG
- Q_UNUSED(printers);
-#else
- QString tmp;
- for (int i = 0; i < dirs.size(); ++i) {
- QFileInfo printer = dirs.at(i);
- // I haven't found any real documentation, so I'm guessing that
- // since lpstat uses /etc/lp/member rather than one of the
- // other directories, it's the one to use. I did not find a
- // decent way to locate aliases and remote printers.
- if (printer.isFile())
- qt_perhapsAddPrinter(printers, printer.fileName(),
- QPrintDialog::tr("unknown"),
- QLatin1String(""));
- }
-#endif
-}
-
-// IRIX 6.x
-void qt_parseSpoolInterface(QList<QPrinterDescription> *printers)
-{
- QDir lp(QLatin1String("/usr/spool/lp/interface"));
- if (!lp.exists())
- return;
- QFileInfoList files = lp.entryInfoList();
- if(files.isEmpty())
- return;
-
- for (int i = 0; i < files.size(); ++i) {
- QFileInfo printer = files.at(i);
-
- if (!printer.isFile())
- continue;
-
- // parse out some information
- QFile configFile(printer.filePath());
- if (!configFile.open(QIODevice::ReadOnly))
- continue;
-
- QByteArray line;
- line.resize(1025);
- QString namePrinter;
- QString hostName;
- QString hostPrinter;
- QString printerType;
-
- QString nameKey(QLatin1String("NAME="));
- QString typeKey(QLatin1String("TYPE="));
- QString hostKey(QLatin1String("HOSTNAME="));
- QString hostPrinterKey(QLatin1String("HOSTPRINTER="));
-
- while (!configFile.atEnd() &&
- (configFile.readLine(line.data(), 1024)) > 0) {
- QString uline = QString::fromLocal8Bit(line);
- if (uline.startsWith(typeKey) ) {
- printerType = uline.mid(nameKey.length());
- printerType = printerType.simplified();
- } else if (uline.startsWith(hostKey)) {
- hostName = uline.mid(hostKey.length());
- hostName = hostName.simplified();
- } else if (uline.startsWith(hostPrinterKey)) {
- hostPrinter = uline.mid(hostPrinterKey.length());
- hostPrinter = hostPrinter.simplified();
- } else if (uline.startsWith(nameKey)) {
- namePrinter = uline.mid(nameKey.length());
- namePrinter = namePrinter.simplified();
- }
- }
- configFile.close();
-
- printerType = printerType.trimmed();
- if (printerType.indexOf(QLatin1String("postscript"), 0, Qt::CaseInsensitive) < 0)
- continue;
-
- int ii = 0;
- while ((ii = namePrinter.indexOf(QLatin1Char('"'), ii)) >= 0)
- namePrinter.remove(ii, 1);
-
- if (hostName.isEmpty() || hostPrinter.isEmpty()) {
- qt_perhapsAddPrinter(printers, printer.fileName(),
- QLatin1String(""), namePrinter);
- } else {
- QString comment;
- comment = namePrinter;
- comment += QLatin1String(" (");
- comment += hostPrinter;
- comment += QLatin1Char(')');
- qt_perhapsAddPrinter(printers, printer.fileName(),
- hostName, comment);
- }
- }
-}
-
-
-// Every unix must have its own. It's a standard. Here is AIX.
-void qt_parseQconfig(QList<QPrinterDescription> *printers)
-{
- QFile qconfig(QLatin1String("/etc/qconfig"));
- if (!qconfig.open(QIODevice::ReadOnly))
- return;
-
- QTextStream ts(&qconfig);
- QString line;
-
- QString stanzaName; // either a queue or a device name
- bool up = true; // queue up? default true, can be false
- QString remoteHost; // null if local
- QString deviceName; // null if remote
-
- QRegExp newStanza(QLatin1String("^[0-z\\-]*:$"));
-
- // our basic strategy here is to process each line, detecting new
- // stanzas. each time we see a new stanza, we check if the
- // previous stanza was a valid queue for a) a remote printer or b)
- // a local printer. if it wasn't, we assume that what we see is
- // the start of the first stanza, or that the previous stanza was
- // a device stanza, or that there is some syntax error (we don't
- // report those).
-
- do {
- line = ts.readLine();
- bool indented = line[0].isSpace();
- line = line.simplified();
-
- int i = line.indexOf(QLatin1Char('='));
- if (indented && i != -1) { // line in stanza
- QString variable = line.left(i).simplified();
- QString value=line.mid(i+1, line.length()).simplified();
- if (variable == QLatin1String("device"))
- deviceName = value;
- else if (variable == QLatin1String("host"))
- remoteHost = value;
- else if (variable == QLatin1String("up"))
- up = !(value.toLower() == QLatin1String("false"));
- } else if (line[0] == QLatin1Char('*')) { // comment
- // nothing to do
- } else if (ts.atEnd() || // end of file, or beginning of new stanza
- (!indented && line.contains(newStanza))) {
- if (up && stanzaName.length() > 0 && stanzaName.length() < 21) {
- if (remoteHost.length()) // remote printer
- qt_perhapsAddPrinter(printers, stanzaName, remoteHost,
- QString());
- else if (deviceName.length()) // local printer
- qt_perhapsAddPrinter(printers, stanzaName, QString(),
- QString());
- }
- line.chop(1);
- if (line.length() >= 1 && line.length() <= 20)
- stanzaName = line;
- up = true;
- remoteHost.clear();
- deviceName.clear();
- } else {
- // syntax error? ignore.
- }
- } while (!ts.atEnd());
-}
-
-int qt_getLprPrinters(QList<QPrinterDescription>& printers)
-{
- QByteArray etcLpDefault;
- qt_parsePrintcap(&printers, QLatin1String("/etc/printcap"));
- qt_parseEtcLpMember(&printers);
- qt_parseSpoolInterface(&printers);
- qt_parseQconfig(&printers);
-
- QFileInfo f;
- f.setFile(QLatin1String("/etc/lp/printers"));
- if (f.isDir()) {
- qt_parseEtcLpPrinters(&printers);
- QFile def(QLatin1String("/etc/lp/default"));
- if (def.open(QIODevice::ReadOnly)) {
- etcLpDefault.resize(1025);
- if (def.readLine(etcLpDefault.data(), 1024) > 0) {
- QRegExp rx(QLatin1String("^(\\S+)"));
- if (rx.indexIn(QString::fromLatin1(etcLpDefault)) != -1)
- etcLpDefault = rx.cap(1).toAscii();
- }
- }
- }
-
- char *def = 0;
- f.setFile(QLatin1String("/etc/nsswitch.conf"));
- if (f.isFile()) {
- def = qt_parseNsswitchConf(&printers);
- } else {
- f.setFile(QLatin1String("/etc/printers.conf"));
- if (f.isFile())
- def = qt_parsePrintersConf(&printers);
- }
-
- if (def) {
- etcLpDefault = def;
- delete [] def;
- }
-
- QString homePrintersDefault = qt_getDefaultFromHomePrinters();
-
- // all printers hopefully known. try to find a good default
- QString dollarPrinter;
- {
- dollarPrinter = QString::fromLocal8Bit(qgetenv("PRINTER"));
- if (dollarPrinter.isEmpty())
- dollarPrinter = QString::fromLocal8Bit(qgetenv("LPDEST"));
- if (dollarPrinter.isEmpty())
- dollarPrinter = QString::fromLocal8Bit(qgetenv("NPRINTER"));
- if (dollarPrinter.isEmpty())
- dollarPrinter = QString::fromLocal8Bit(qgetenv("NGPRINTER"));
-#ifndef QT_NO_PRINTDIALOG
- if (!dollarPrinter.isEmpty())
- qt_perhapsAddPrinter(&printers, dollarPrinter,
- QPrintDialog::tr("unknown"),
- QLatin1String(""));
-#endif
- }
-
- QRegExp ps(QLatin1String("[^a-z]ps(?:[^a-z]|$)"));
- QRegExp lp(QLatin1String("[^a-z]lp(?:[^a-z]|$)"));
-
- int quality = 0;
- int best = 0;
- for (int i = 0; i < printers.size(); ++i) {
- QString name = printers.at(i).name;
- QString comment = printers.at(i).comment;
- if (quality < 5 && name == dollarPrinter) {
- best = i;
- quality = 5;
- } else if (quality < 4 && !homePrintersDefault.isEmpty() &&
- name == homePrintersDefault) {
- best = i;
- quality = 4;
- } else if (quality < 3 && !etcLpDefault.isEmpty() &&
- name == QLatin1String(etcLpDefault)) {
- best = i;
- quality = 3;
- } else if (quality < 2 &&
- (name == QLatin1String("ps") ||
- ps.indexIn(comment) != -1)) {
- best = i;
- quality = 2;
- } else if (quality < 1 &&
- (name == QLatin1String("lp") ||
- lp.indexIn(comment) > -1)) {
- best = i;
- quality = 1;
- }
- }
-
- return best;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////////////
-
-QList<QPrinterInfo> QPrinterInfo::availablePrinters()
-{
- QList<QPrinterInfo> printers;
-
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
- if (QCUPSSupport::isAvailable()) {
- QCUPSSupport cups;
- int cupsPrinterCount = cups.availablePrintersCount();
- const cups_dest_t* cupsPrinters = cups.availablePrinters();
- for (int i = 0; i < cupsPrinterCount; ++i) {
- QString printerName(QString::fromLocal8Bit(cupsPrinters[i].name));
- if (cupsPrinters[i].instance)
- printerName += QLatin1Char('/') + QString::fromLocal8Bit(cupsPrinters[i].instance);
-
- QPrinterInfo printerInfo(printerName);
- if (cupsPrinters[i].is_default)
- printerInfo.d_ptr->isDefault = true;
- printerInfo.d_ptr->cupsPrinterIndex = i;
- printers.append(printerInfo);
- }
- } else
-#endif
- {
- QList<QPrinterDescription> lprPrinters;
- int defprn = qt_getLprPrinters(lprPrinters);
- // populating printer combo
- foreach (const QPrinterDescription &description, lprPrinters)
- printers.append(QPrinterInfo(description.name));
- if (defprn >= 0 && defprn < printers.size())
- printers[defprn].d_ptr->isDefault = true;
- }
-
- return printers;
-}
-
-QPrinterInfo QPrinterInfo::defaultPrinter()
-{
- QList<QPrinterInfo> printers = availablePrinters();
- foreach (const QPrinterInfo &printerInfo, printers) {
- if (printerInfo.isDefault())
- return printerInfo;
- }
-
- return printers.value(0);
-}
-
-QList<QPrinter::PaperSize> QPrinterInfo::supportedPaperSizes() const
-{
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
- const Q_D(QPrinterInfo);
-
- if (isNull())
- return d->paperSizes;
-
- if (!d->hasPaperSizes) {
- d->hasPaperSizes = true;
-
- if (QCUPSSupport::isAvailable()) {
- // Find paper sizes from CUPS.
- QCUPSSupport cups;
- cups.setCurrentPrinter(d->cupsPrinterIndex);
- const ppd_option_t* sizes = cups.pageSizes();
- if (sizes) {
- for (int j = 0; j < sizes->num_choices; ++j)
- d->paperSizes.append(string2PaperSize(sizes->choices[j].choice));
- }
- }
- }
-
- return d->paperSizes;
-#else
- return QList<QPrinter::PaperSize>();
-#endif
-}
-
-#endif // QT_NO_PRINTER
-
-QT_END_NAMESPACE
diff --git a/src/gui/painting/qprinterinfo_unix_p.h b/src/gui/painting/qprinterinfo_unix_p.h
deleted file mode 100644
index 1ededf5a36..0000000000
--- a/src/gui/painting/qprinterinfo_unix_p.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPRINTERINFO_UNIX_P_H
-#define QPRINTERINFO_UNIX_P_H
-
-#ifndef QT_NO_NIS
-# ifndef BOOL_DEFINED
-# define BOOL_DEFINED
-# endif
-
-# include <sys/types.h>
-# include <rpc/rpc.h>
-# include <rpcsvc/ypclnt.h>
-# include <rpcsvc/yp_prot.h>
-#endif // QT_NO_NIS
-
-#ifdef Success
-# undef Success
-#endif
-
-#include <ctype.h>
-
-QT_BEGIN_NAMESPACE
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#ifndef QT_NO_PRINTER
-
-struct QPrinterDescription {
- QPrinterDescription(const QString &n, const QString &h, const QString &c, const QStringList &a)
- : name(n), host(h), comment(c), aliases(a) {}
- QString name;
- QString host;
- QString comment;
- QStringList aliases;
- bool samePrinter(const QString& printer) const {
- return name == printer || aliases.contains(printer);
- }
-};
-
-enum { Success = 's', Unavail = 'u', NotFound = 'n', TryAgain = 't' };
-enum { Continue = 'c', Return = 'r' };
-
-void qt_perhapsAddPrinter(QList<QPrinterDescription> *printers, const QString &name,
- QString host, QString comment,
- QStringList aliases = QStringList());
-void qt_parsePrinterDesc(QString printerDesc, QList<QPrinterDescription> *printers);
-
-int qt_parsePrintcap(QList<QPrinterDescription> *printers, const QString& fileName);
-QString qt_getDefaultFromHomePrinters();
-void qt_parseEtcLpPrinters(QList<QPrinterDescription> *printers);
-char *qt_parsePrintersConf(QList<QPrinterDescription> *printers, bool *found = 0);
-
-#ifndef QT_NO_NIS
-#if defined(Q_C_CALLBACKS)
-extern "C" {
-#endif
-int qt_pd_foreach(int /*status */, char * /*key */, int /*keyLen */,
- char *val, int valLen, char *data);
-
-#if defined(Q_C_CALLBACKS)
-}
-#endif
-int qt_retrieveNisPrinters(QList<QPrinterDescription> *printers);
-#endif // QT_NO_NIS
-char *qt_parseNsswitchPrintersEntry(QList<QPrinterDescription> *printers, char *line);
-char *qt_parseNsswitchConf(QList<QPrinterDescription> *printers);
-void qt_parseEtcLpMember(QList<QPrinterDescription> *printers);
-void qt_parseSpoolInterface(QList<QPrinterDescription> *printers);
-void qt_parseQconfig(QList<QPrinterDescription> *printers);
-int qt_getLprPrinters(QList<QPrinterDescription>& printers);
-
-#endif // QT_NO_PRINTER
-
-QT_END_NAMESPACE
-
-#endif // QPRINTERINFO_UNIX_P_H
diff --git a/src/gui/painting/qpsprinter.agl b/src/gui/painting/qpsprinter.agl
deleted file mode 100644
index 137b64c53b..0000000000
--- a/src/gui/painting/qpsprinter.agl
+++ /dev/null
@@ -1,452 +0,0 @@
-# the next table is derived from a list provided by Adobe on its web
-# server: http://partners.adobe.com/asn/developer/typeforum/glyphlist.txt
-
-# the start of the header comment:
-#
-# Name: Adobe Glyph List
-# Table version: 1.2
-# Date: 22 Oct 1998
-#
-# Description:
-#
-# The Adobe Glyph List (AGL) list relates Unicode values (UVs) to glyph
-# names, and should be used only as described in the document "Unicode and
-# Glyph Names," at
-# http://partners.adobe.com:80/asn/developer/type/unicodegn.html
-#
-# IMPORTANT NOTE:
-# the list contains glyphs in the private use area of unicode.
-# These should get removed when regenerating the glyphlist.
-#
-# also 0 should be mapped to .notdef
-#
-# grep '^[0-9A-F][0-9A-F][0-9A-F][0-9A-F];' < /tmp/glyphlist.txt | sed -e 's/;/, "/' -e 's-;-" }, // -' -e 's/^/ { 0x/' | sort
-#
-0x0000, ".notdef"
-0x0020, "space" # SPACE
-0x0021, "exclam" # EXCLAMATION MARK
-0x0022, "quotedbl" # QUOTATION MARK
-0x0023, "numbersign" # NUMBER SIGN
-0x0024, "dollar" # DOLLAR SIGN
-0x0025, "percent" # PERCENT SIGN
-0x0026, "ampersand" # AMPERSAND
-0x0027, "quotesingle" # APOSTROPHE
-0x0028, "parenleft" # LEFT PARENTHESIS
-0x0029, "parenright" # RIGHT PARENTHESIS
-0x002A, "asterisk" # ASTERISK
-0x002B, "plus" # PLUS SIGN
-0x002C, "comma" # COMMA
-0x002D, "hyphen" # HYPHEN-MINUS
-0x002E, "period" # FULL STOP
-0x002F, "slash" # SOLIDUS
-0x0030, "zero" # DIGIT ZERO
-0x0031, "one" # DIGIT ONE
-0x0032, "two" # DIGIT TWO
-0x0033, "three" # DIGIT THREE
-0x0034, "four" # DIGIT FOUR
-0x0035, "five" # DIGIT FIVE
-0x0036, "six" # DIGIT SIX
-0x0037, "seven" # DIGIT SEVEN
-0x0038, "eight" # DIGIT EIGHT
-0x0039, "nine" # DIGIT NINE
-0x003A, "colon" # COLON
-0x003B, "semicolon" # SEMICOLON
-0x003C, "less" # LESS-THAN SIGN
-0x003D, "equal" # EQUALS SIGN
-0x003E, "greater" # GREATER-THAN SIGN
-0x003F, "question" # QUESTION MARK
-0x0040, "at" # COMMERCIAL AT
-0x0041, "A" # LATIN CAPITAL LETTER A
-0x0042, "B" # LATIN CAPITAL LETTER B
-0x0043, "C" # LATIN CAPITAL LETTER C
-0x0044, "D" # LATIN CAPITAL LETTER D
-0x0045, "E" # LATIN CAPITAL LETTER E
-0x0046, "F" # LATIN CAPITAL LETTER F
-0x0047, "G" # LATIN CAPITAL LETTER G
-0x0048, "H" # LATIN CAPITAL LETTER H
-0x0049, "I" # LATIN CAPITAL LETTER I
-0x004A, "J" # LATIN CAPITAL LETTER J
-0x004B, "K" # LATIN CAPITAL LETTER K
-0x004C, "L" # LATIN CAPITAL LETTER L
-0x004D, "M" # LATIN CAPITAL LETTER M
-0x004E, "N" # LATIN CAPITAL LETTER N
-0x004F, "O" # LATIN CAPITAL LETTER O
-0x0050, "P" # LATIN CAPITAL LETTER P
-0x0051, "Q" # LATIN CAPITAL LETTER Q
-0x0052, "R" # LATIN CAPITAL LETTER R
-0x0053, "S" # LATIN CAPITAL LETTER S
-0x0054, "T" # LATIN CAPITAL LETTER T
-0x0055, "U" # LATIN CAPITAL LETTER U
-0x0056, "V" # LATIN CAPITAL LETTER V
-0x0057, "W" # LATIN CAPITAL LETTER W
-0x0058, "X" # LATIN CAPITAL LETTER X
-0x0059, "Y" # LATIN CAPITAL LETTER Y
-0x005A, "Z" # LATIN CAPITAL LETTER Z
-0x005B, "bracketleft" # LEFT SQUARE BRACKET
-0x005C, "backslash" # REVERSE SOLIDUS
-0x005D, "bracketright" # RIGHT SQUARE BRACKET
-0x005E, "asciicircum" # CIRCUMFLEX ACCENT
-0x005F, "underscore" # LOW LINE
-0x0060, "grave" # GRAVE ACCENT
-0x0061, "a" # LATIN SMALL LETTER A
-0x0062, "b" # LATIN SMALL LETTER B
-0x0063, "c" # LATIN SMALL LETTER C
-0x0064, "d" # LATIN SMALL LETTER D
-0x0065, "e" # LATIN SMALL LETTER E
-0x0066, "f" # LATIN SMALL LETTER F
-0x0067, "g" # LATIN SMALL LETTER G
-0x0068, "h" # LATIN SMALL LETTER H
-0x0069, "i" # LATIN SMALL LETTER I
-0x006A, "j" # LATIN SMALL LETTER J
-0x006B, "k" # LATIN SMALL LETTER K
-0x006C, "l" # LATIN SMALL LETTER L
-0x006D, "m" # LATIN SMALL LETTER M
-0x006E, "n" # LATIN SMALL LETTER N
-0x006F, "o" # LATIN SMALL LETTER O
-0x0070, "p" # LATIN SMALL LETTER P
-0x0071, "q" # LATIN SMALL LETTER Q
-0x0072, "r" # LATIN SMALL LETTER R
-0x0073, "s" # LATIN SMALL LETTER S
-0x0074, "t" # LATIN SMALL LETTER T
-0x0075, "u" # LATIN SMALL LETTER U
-0x0076, "v" # LATIN SMALL LETTER V
-0x0077, "w" # LATIN SMALL LETTER W
-0x0078, "x" # LATIN SMALL LETTER X
-0x0079, "y" # LATIN SMALL LETTER Y
-0x007A, "z" # LATIN SMALL LETTER Z
-0x007B, "braceleft" # LEFT CURLY BRACKET
-0x007C, "bar" # VERTICAL LINE
-0x007D, "braceright" # RIGHT CURLY BRACKET
-0x007E, "asciitilde" # TILDE
-0x00A0, "space" # NO-BREAK SPACE;Duplicate
-0x00A1, "exclamdown" # INVERTED EXCLAMATION MARK
-0x00A2, "cent" # CENT SIGN
-0x00A3, "sterling" # POUND SIGN
-0x00A4, "currency" # CURRENCY SIGN
-0x00A5, "yen" # YEN SIGN
-0x00A6, "brokenbar" # BROKEN BAR
-0x00A7, "section" # SECTION SIGN
-0x00A8, "dieresis" # DIAERESIS
-0x00A9, "copyright" # COPYRIGHT SIGN
-0x00AA, "ordfeminine" # FEMININE ORDINAL INDICATOR
-0x00AB, "guillemotleft" # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
-0x00AC, "logicalnot" # NOT SIGN
-0x00AD, "hyphen" # SOFT HYPHEN;Duplicate
-0x00AE, "registered" # REGISTERED SIGN
-0x00AF, "macron" # MACRON
-0x00B0, "degree" # DEGREE SIGN
-0x00B1, "plusminus" # PLUS-MINUS SIGN
-0x00B2, "twosuperior" # SUPERSCRIPT TWO
-0x00B3, "threesuperior" # SUPERSCRIPT THREE
-0x00B4, "acute" # ACUTE ACCENT
-0x00B5, "mu" # MICRO SIGN
-0x00B6, "paragraph" # PILCROW SIGN
-0x00B7, "periodcentered" # MIDDLE DOT
-0x00B8, "cedilla" # CEDILLA
-0x00B9, "onesuperior" # SUPERSCRIPT ONE
-0x00BA, "ordmasculine" # MASCULINE ORDINAL INDICATOR
-0x00BB, "guillemotright" # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
-0x00BC, "onequarter" # VULGAR FRACTION ONE QUARTER
-0x00BD, "onehalf" # VULGAR FRACTION ONE HALF
-0x00BE, "threequarters" # VULGAR FRACTION THREE QUARTERS
-0x00BF, "questiondown" # INVERTED QUESTION MARK
-0x00C0, "Agrave" # LATIN CAPITAL LETTER A WITH GRAVE
-0x00C1, "Aacute" # LATIN CAPITAL LETTER A WITH ACUTE
-0x00C2, "Acircumflex" # LATIN CAPITAL LETTER A WITH CIRCUMFLEX
-0x00C3, "Atilde" # LATIN CAPITAL LETTER A WITH TILDE
-0x00C4, "Adieresis" # LATIN CAPITAL LETTER A WITH DIAERESIS
-0x00C5, "Aring" # LATIN CAPITAL LETTER A WITH RING ABOVE
-0x00C6, "AE" # LATIN CAPITAL LETTER AE
-0x00C7, "Ccedilla" # LATIN CAPITAL LETTER C WITH CEDILLA
-0x00C8, "Egrave" # LATIN CAPITAL LETTER E WITH GRAVE
-0x00C9, "Eacute" # LATIN CAPITAL LETTER E WITH ACUTE
-0x00CA, "Ecircumflex" # LATIN CAPITAL LETTER E WITH CIRCUMFLEX
-0x00CB, "Edieresis" # LATIN CAPITAL LETTER E WITH DIAERESIS
-0x00CC, "Igrave" # LATIN CAPITAL LETTER I WITH GRAVE
-0x00CD, "Iacute" # LATIN CAPITAL LETTER I WITH ACUTE
-0x00CE, "Icircumflex" # LATIN CAPITAL LETTER I WITH CIRCUMFLEX
-0x00CF, "Idieresis" # LATIN CAPITAL LETTER I WITH DIAERESIS
-0x00D0, "Eth" # LATIN CAPITAL LETTER ETH
-0x00D1, "Ntilde" # LATIN CAPITAL LETTER N WITH TILDE
-0x00D2, "Ograve" # LATIN CAPITAL LETTER O WITH GRAVE
-0x00D3, "Oacute" # LATIN CAPITAL LETTER O WITH ACUTE
-0x00D4, "Ocircumflex" # LATIN CAPITAL LETTER O WITH CIRCUMFLEX
-0x00D5, "Otilde" # LATIN CAPITAL LETTER O WITH TILDE
-0x00D6, "Odieresis" # LATIN CAPITAL LETTER O WITH DIAERESIS
-0x00D7, "multiply" # MULTIPLICATION SIGN
-0x00D8, "Oslash" # LATIN CAPITAL LETTER O WITH STROKE
-0x00D9, "Ugrave" # LATIN CAPITAL LETTER U WITH GRAVE
-0x00DA, "Uacute" # LATIN CAPITAL LETTER U WITH ACUTE
-0x00DB, "Ucircumflex" # LATIN CAPITAL LETTER U WITH CIRCUMFLEX
-0x00DC, "Udieresis" # LATIN CAPITAL LETTER U WITH DIAERESIS
-0x00DD, "Yacute" # LATIN CAPITAL LETTER Y WITH ACUTE
-0x00DE, "Thorn" # LATIN CAPITAL LETTER THORN
-0x00DF, "germandbls" # LATIN SMALL LETTER SHARP S
-0x00E0, "agrave" # LATIN SMALL LETTER A WITH GRAVE
-0x00E1, "aacute" # LATIN SMALL LETTER A WITH ACUTE
-0x00E2, "acircumflex" # LATIN SMALL LETTER A WITH CIRCUMFLEX
-0x00E3, "atilde" # LATIN SMALL LETTER A WITH TILDE
-0x00E4, "adieresis" # LATIN SMALL LETTER A WITH DIAERESIS
-0x00E5, "aring" # LATIN SMALL LETTER A WITH RING ABOVE
-0x00E6, "ae" # LATIN SMALL LETTER AE
-0x00E7, "ccedilla" # LATIN SMALL LETTER C WITH CEDILLA
-0x00E8, "egrave" # LATIN SMALL LETTER E WITH GRAVE
-0x00E9, "eacute" # LATIN SMALL LETTER E WITH ACUTE
-0x00EA, "ecircumflex" # LATIN SMALL LETTER E WITH CIRCUMFLEX
-0x00EB, "edieresis" # LATIN SMALL LETTER E WITH DIAERESIS
-0x00EC, "igrave" # LATIN SMALL LETTER I WITH GRAVE
-0x00ED, "iacute" # LATIN SMALL LETTER I WITH ACUTE
-0x00EE, "icircumflex" # LATIN SMALL LETTER I WITH CIRCUMFLEX
-0x00EF, "idieresis" # LATIN SMALL LETTER I WITH DIAERESIS
-0x00F0, "eth" # LATIN SMALL LETTER ETH
-0x00F1, "ntilde" # LATIN SMALL LETTER N WITH TILDE
-0x00F2, "ograve" # LATIN SMALL LETTER O WITH GRAVE
-0x00F3, "oacute" # LATIN SMALL LETTER O WITH ACUTE
-0x00F4, "ocircumflex" # LATIN SMALL LETTER O WITH CIRCUMFLEX
-0x00F5, "otilde" # LATIN SMALL LETTER O WITH TILDE
-0x00F6, "odieresis" # LATIN SMALL LETTER O WITH DIAERESIS
-0x00F7, "divide" # DIVISION SIGN
-0x00F8, "oslash" # LATIN SMALL LETTER O WITH STROKE
-0x00F9, "ugrave" # LATIN SMALL LETTER U WITH GRAVE
-0x00FA, "uacute" # LATIN SMALL LETTER U WITH ACUTE
-0x00FB, "ucircumflex" # LATIN SMALL LETTER U WITH CIRCUMFLEX
-0x00FC, "udieresis" # LATIN SMALL LETTER U WITH DIAERESIS
-0x00FD, "yacute" # LATIN SMALL LETTER Y WITH ACUTE
-0x00FE, "thorn" # LATIN SMALL LETTER THORN
-0x00FF, "ydieresis" # LATIN SMALL LETTER Y WITH DIAERESIS
-0x0100, "Amacron" # LATIN CAPITAL LETTER A WITH MACRON
-0x0101, "amacron" # LATIN SMALL LETTER A WITH MACRON
-0x0102, "Abreve" # LATIN CAPITAL LETTER A WITH BREVE
-0x0103, "abreve" # LATIN SMALL LETTER A WITH BREVE
-0x0104, "Aogonek" # LATIN CAPITAL LETTER A WITH OGONEK
-0x0105, "aogonek" # LATIN SMALL LETTER A WITH OGONEK
-0x0106, "Cacute" # LATIN CAPITAL LETTER C WITH ACUTE
-0x0107, "cacute" # LATIN SMALL LETTER C WITH ACUTE
-0x0108, "Ccircumflex" # LATIN CAPITAL LETTER C WITH CIRCUMFLEX
-0x0109, "ccircumflex" # LATIN SMALL LETTER C WITH CIRCUMFLEX
-0x010A, "Cdotaccent" # LATIN CAPITAL LETTER C WITH DOT ABOVE
-0x010B, "cdotaccent" # LATIN SMALL LETTER C WITH DOT ABOVE
-0x010C, "Ccaron" # LATIN CAPITAL LETTER C WITH CARON
-0x010D, "ccaron" # LATIN SMALL LETTER C WITH CARON
-0x010E, "Dcaron" # LATIN CAPITAL LETTER D WITH CARON
-0x010F, "dcaron" # LATIN SMALL LETTER D WITH CARON
-0x0110, "Dcroat" # LATIN CAPITAL LETTER D WITH STROKE
-0x0111, "dcroat" # LATIN SMALL LETTER D WITH STROKE
-0x0112, "Emacron" # LATIN CAPITAL LETTER E WITH MACRON
-0x0113, "emacron" # LATIN SMALL LETTER E WITH MACRON
-0x0114, "Ebreve" # LATIN CAPITAL LETTER E WITH BREVE
-0x0115, "ebreve" # LATIN SMALL LETTER E WITH BREVE
-0x0116, "Edotaccent" # LATIN CAPITAL LETTER E WITH DOT ABOVE
-0x0117, "edotaccent" # LATIN SMALL LETTER E WITH DOT ABOVE
-0x0118, "Eogonek" # LATIN CAPITAL LETTER E WITH OGONEK
-0x0119, "eogonek" # LATIN SMALL LETTER E WITH OGONEK
-0x011A, "Ecaron" # LATIN CAPITAL LETTER E WITH CARON
-0x011B, "ecaron" # LATIN SMALL LETTER E WITH CARON
-0x011C, "Gcircumflex" # LATIN CAPITAL LETTER G WITH CIRCUMFLEX
-0x011D, "gcircumflex" # LATIN SMALL LETTER G WITH CIRCUMFLEX
-0x011E, "Gbreve" # LATIN CAPITAL LETTER G WITH BREVE
-0x011F, "gbreve" # LATIN SMALL LETTER G WITH BREVE
-0x0120, "Gdotaccent" # LATIN CAPITAL LETTER G WITH DOT ABOVE
-0x0121, "gdotaccent" # LATIN SMALL LETTER G WITH DOT ABOVE
-0x0122, "Gcommaaccent" # LATIN CAPITAL LETTER G WITH CEDILLA
-0x0123, "gcommaaccent" # LATIN SMALL LETTER G WITH CEDILLA
-0x0124, "Hcircumflex" # LATIN CAPITAL LETTER H WITH CIRCUMFLEX
-0x0125, "hcircumflex" # LATIN SMALL LETTER H WITH CIRCUMFLEX
-0x0126, "Hbar" # LATIN CAPITAL LETTER H WITH STROKE
-0x0127, "hbar" # LATIN SMALL LETTER H WITH STROKE
-0x0128, "Itilde" # LATIN CAPITAL LETTER I WITH TILDE
-0x0129, "itilde" # LATIN SMALL LETTER I WITH TILDE
-0x012A, "Imacron" # LATIN CAPITAL LETTER I WITH MACRON
-0x012B, "imacron" # LATIN SMALL LETTER I WITH MACRON
-0x012C, "Ibreve" # LATIN CAPITAL LETTER I WITH BREVE
-0x012D, "ibreve" # LATIN SMALL LETTER I WITH BREVE
-0x012E, "Iogonek" # LATIN CAPITAL LETTER I WITH OGONEK
-0x012F, "iogonek" # LATIN SMALL LETTER I WITH OGONEK
-0x0130, "Idotaccent" # LATIN CAPITAL LETTER I WITH DOT ABOVE
-0x0131, "dotlessi" # LATIN SMALL LETTER DOTLESS I
-0x0132, "IJ" # LATIN CAPITAL LIGATURE IJ
-0x0133, "ij" # LATIN SMALL LIGATURE IJ
-0x0134, "Jcircumflex" # LATIN CAPITAL LETTER J WITH CIRCUMFLEX
-0x0135, "jcircumflex" # LATIN SMALL LETTER J WITH CIRCUMFLEX
-0x0136, "Kcommaaccent" # LATIN CAPITAL LETTER K WITH CEDILLA
-0x0137, "kcommaaccent" # LATIN SMALL LETTER K WITH CEDILLA
-0x0138, "kgreenlandic" # LATIN SMALL LETTER KRA
-0x0139, "Lacute" # LATIN CAPITAL LETTER L WITH ACUTE
-0x013A, "lacute" # LATIN SMALL LETTER L WITH ACUTE
-0x013B, "Lcommaaccent" # LATIN CAPITAL LETTER L WITH CEDILLA
-0x013C, "lcommaaccent" # LATIN SMALL LETTER L WITH CEDILLA
-0x013D, "Lcaron" # LATIN CAPITAL LETTER L WITH CARON
-0x013E, "lcaron" # LATIN SMALL LETTER L WITH CARON
-0x013F, "Ldot" # LATIN CAPITAL LETTER L WITH MIDDLE DOT
-0x0140, "ldot" # LATIN SMALL LETTER L WITH MIDDLE DOT
-0x0141, "Lslash" # LATIN CAPITAL LETTER L WITH STROKE
-0x0142, "lslash" # LATIN SMALL LETTER L WITH STROKE
-0x0143, "Nacute" # LATIN CAPITAL LETTER N WITH ACUTE
-0x0144, "nacute" # LATIN SMALL LETTER N WITH ACUTE
-0x0145, "Ncommaaccent" # LATIN CAPITAL LETTER N WITH CEDILLA
-0x0146, "ncommaaccent" # LATIN SMALL LETTER N WITH CEDILLA
-0x0147, "Ncaron" # LATIN CAPITAL LETTER N WITH CARON
-0x0148, "ncaron" # LATIN SMALL LETTER N WITH CARON
-0x0149, "napostrophe" # LATIN SMALL LETTER N PRECEDED BY APOSTROPHE
-0x014A, "Eng" # LATIN CAPITAL LETTER ENG
-0x014B, "eng" # LATIN SMALL LETTER ENG
-0x014C, "Omacron" # LATIN CAPITAL LETTER O WITH MACRON
-0x014D, "omacron" # LATIN SMALL LETTER O WITH MACRON
-0x014E, "Obreve" # LATIN CAPITAL LETTER O WITH BREVE
-0x014F, "obreve" # LATIN SMALL LETTER O WITH BREVE
-0x0150, "Ohungarumlaut" # LATIN CAPITAL LETTER O WITH DOUBLE ACUTE
-0x0151, "ohungarumlaut" # LATIN SMALL LETTER O WITH DOUBLE ACUTE
-0x0152, "OE" # LATIN CAPITAL LIGATURE OE
-0x0153, "oe" # LATIN SMALL LIGATURE OE
-0x0154, "Racute" # LATIN CAPITAL LETTER R WITH ACUTE
-0x0155, "racute" # LATIN SMALL LETTER R WITH ACUTE
-0x0156, "Rcommaaccent" # LATIN CAPITAL LETTER R WITH CEDILLA
-0x0157, "rcommaaccent" # LATIN SMALL LETTER R WITH CEDILLA
-0x0158, "Rcaron" # LATIN CAPITAL LETTER R WITH CARON
-0x0159, "rcaron" # LATIN SMALL LETTER R WITH CARON
-0x015A, "Sacute" # LATIN CAPITAL LETTER S WITH ACUTE
-0x015B, "sacute" # LATIN SMALL LETTER S WITH ACUTE
-0x015C, "Scircumflex" # LATIN CAPITAL LETTER S WITH CIRCUMFLEX
-0x015D, "scircumflex" # LATIN SMALL LETTER S WITH CIRCUMFLEX
-0x015E, "Scedilla" # LATIN CAPITAL LETTER S WITH CEDILLA
-0x015F, "scedilla" # LATIN SMALL LETTER S WITH CEDILLA
-0x0160, "Scaron" # LATIN CAPITAL LETTER S WITH CARON
-0x0161, "scaron" # LATIN SMALL LETTER S WITH CARON
-0x0164, "Tcaron" # LATIN CAPITAL LETTER T WITH CARON
-0x0165, "tcaron" # LATIN SMALL LETTER T WITH CARON
-0x0166, "Tbar" # LATIN CAPITAL LETTER T WITH STROKE
-0x0167, "tbar" # LATIN SMALL LETTER T WITH STROKE
-0x0168, "Utilde" # LATIN CAPITAL LETTER U WITH TILDE
-0x0169, "utilde" # LATIN SMALL LETTER U WITH TILDE
-0x016A, "Umacron" # LATIN CAPITAL LETTER U WITH MACRON
-0x016B, "umacron" # LATIN SMALL LETTER U WITH MACRON
-0x016C, "Ubreve" # LATIN CAPITAL LETTER U WITH BREVE
-0x016D, "ubreve" # LATIN SMALL LETTER U WITH BREVE
-0x016E, "Uring" # LATIN CAPITAL LETTER U WITH RING ABOVE
-0x016F, "uring" # LATIN SMALL LETTER U WITH RING ABOVE
-0x0170, "Uhungarumlaut" # LATIN CAPITAL LETTER U WITH DOUBLE ACUTE
-0x0171, "uhungarumlaut" # LATIN SMALL LETTER U WITH DOUBLE ACUTE
-0x0172, "Uogonek" # LATIN CAPITAL LETTER U WITH OGONEK
-0x0173, "uogonek" # LATIN SMALL LETTER U WITH OGONEK
-0x0174, "Wcircumflex" # LATIN CAPITAL LETTER W WITH CIRCUMFLEX
-0x0175, "wcircumflex" # LATIN SMALL LETTER W WITH CIRCUMFLEX
-0x0176, "Ycircumflex" # LATIN CAPITAL LETTER Y WITH CIRCUMFLEX
-0x0177, "ycircumflex" # LATIN SMALL LETTER Y WITH CIRCUMFLEX
-0x0178, "Ydieresis" # LATIN CAPITAL LETTER Y WITH DIAERESIS
-0x0179, "Zacute" # LATIN CAPITAL LETTER Z WITH ACUTE
-0x017A, "zacute" # LATIN SMALL LETTER Z WITH ACUTE
-0x017B, "Zdotaccent" # LATIN CAPITAL LETTER Z WITH DOT ABOVE
-0x017C, "zdotaccent" # LATIN SMALL LETTER Z WITH DOT ABOVE
-0x017D, "Zcaron" # LATIN CAPITAL LETTER Z WITH CARON
-0x017E, "zcaron" # LATIN SMALL LETTER Z WITH CARON
-0x017F, "longs" # LATIN SMALL LETTER LONG S
-0x0192, "florin" # LATIN SMALL LETTER F WITH HOOK
-0x01A0, "Ohorn" # LATIN CAPITAL LETTER O WITH HORN
-0x01A1, "ohorn" # LATIN SMALL LETTER O WITH HORN
-0x01AF, "Uhorn" # LATIN CAPITAL LETTER U WITH HORN
-0x01B0, "uhorn" # LATIN SMALL LETTER U WITH HORN
-0x01E6, "Gcaron" # LATIN CAPITAL LETTER G WITH CARON
-0x01E7, "gcaron" # LATIN SMALL LETTER G WITH CARON
-0x01FA, "Aringacute" # LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE
-0x01FB, "aringacute" # LATIN SMALL LETTER A WITH RING ABOVE AND ACUTE
-0x01FC, "AEacute" # LATIN CAPITAL LETTER AE WITH ACUTE
-0x01FD, "aeacute" # LATIN SMALL LETTER AE WITH ACUTE
-0x01FE, "Oslashacute" # LATIN CAPITAL LETTER O WITH STROKE AND ACUTE
-0x01FF, "oslashacute" # LATIN SMALL LETTER O WITH STROKE AND ACUTE
-0x0218, "Scommaaccent" # LATIN CAPITAL LETTER S WITH COMMA BELOW
-0x0219, "scommaaccent" # LATIN SMALL LETTER S WITH COMMA BELOW
-0x021A, "Tcommaaccent" # LATIN CAPITAL LETTER T WITH COMMA BELOW
-0x021B, "tcommaaccent" # LATIN SMALL LETTER T WITH COMMA BELOW
-0x02BC, "afii57929" # MODIFIER LETTER APOSTROPHE
-0x02BD, "afii64937" # MODIFIER LETTER REVERSED COMMA
-0x02C6, "circumflex" # MODIFIER LETTER CIRCUMFLEX ACCENT
-0x02C7, "caron" # CARON
-0x02D8, "breve" # BREVE
-0x02D9, "dotaccent" # DOT ABOVE
-0x02DA, "ring" # RING ABOVE
-0x02DB, "ogonek" # OGONEK
-0x02DC, "tilde" # SMALL TILDE
-0x02DD, "hungarumlaut" # DOUBLE ACUTE ACCENT
-0x0300, "gravecomb" # COMBINING GRAVE ACCENT
-0x0301, "acutecomb" # COMBINING ACUTE ACCENT
-0x0303, "tildecomb" # COMBINING TILDE
-0x0309, "hookabovecomb" # COMBINING HOOK ABOVE
-0x0323, "dotbelowcomb" # COMBINING DOT BELOW
-0x0384, "tonos" # GREEK TONOS
-0x0385, "dieresistonos" # GREEK DIALYTIKA TONOS
-0x0386, "Alphatonos" # GREEK CAPITAL LETTER ALPHA WITH TONOS
-0x0387, "anoteleia" # GREEK ANO TELEIA
-0x0388, "Epsilontonos" # GREEK CAPITAL LETTER EPSILON WITH TONOS
-0x0389, "Etatonos" # GREEK CAPITAL LETTER ETA WITH TONOS
-0x038A, "Iotatonos" # GREEK CAPITAL LETTER IOTA WITH TONOS
-0x038C, "Omicrontonos" # GREEK CAPITAL LETTER OMICRON WITH TONOS
-0x038E, "Upsilontonos" # GREEK CAPITAL LETTER UPSILON WITH TONOS
-0x038F, "Omegatonos" # GREEK CAPITAL LETTER OMEGA WITH TONOS
-0x0390, "iotadieresistonos" # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS
-0x0391, "Alpha" # GREEK CAPITAL LETTER ALPHA
-0x0392, "Beta" # GREEK CAPITAL LETTER BETA
-0x0393, "Gamma" # GREEK CAPITAL LETTER GAMMA
-0x0394, "Delta" # GREEK CAPITAL LETTER DELTA
-0x0395, "Epsilon" # GREEK CAPITAL LETTER EPSILON
-0x0396, "Zeta" # GREEK CAPITAL LETTER ZETA
-0x0397, "Eta" # GREEK CAPITAL LETTER ETA
-0x0398, "Theta" # GREEK CAPITAL LETTER THETA
-0x0399, "Iota" # GREEK CAPITAL LETTER IOTA
-0x039A, "Kappa" # GREEK CAPITAL LETTER KAPPA
-0x039B, "Lambda" # GREEK CAPITAL LETTER LAMDA
-0x039C, "Mu" # GREEK CAPITAL LETTER MU
-0x039D, "Nu" # GREEK CAPITAL LETTER NU
-0x039E, "Xi" # GREEK CAPITAL LETTER XI
-0x039F, "Omicron" # GREEK CAPITAL LETTER OMICRON
-0x03A0, "Pi" # GREEK CAPITAL LETTER PI
-0x03A1, "Rho" # GREEK CAPITAL LETTER RHO
-0x03A3, "Sigma" # GREEK CAPITAL LETTER SIGMA
-0x03A4, "Tau" # GREEK CAPITAL LETTER TAU
-0x03A5, "Upsilon" # GREEK CAPITAL LETTER UPSILON
-0x03A6, "Phi" # GREEK CAPITAL LETTER PHI
-0x03A7, "Chi" # GREEK CAPITAL LETTER CHI
-0x03A8, "Psi" # GREEK CAPITAL LETTER PSI
-0x03A9, "Omega" # GREEK CAPITAL LETTER OMEGA
-0x03AA, "Iotadieresis" # GREEK CAPITAL LETTER IOTA WITH DIALYTIKA
-0x03AB, "Upsilondieresis" # GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA
-0x03AC, "alphatonos" # GREEK SMALL LETTER ALPHA WITH TONOS
-0x03AD, "epsilontonos" # GREEK SMALL LETTER EPSILON WITH TONOS
-0x03AE, "etatonos" # GREEK SMALL LETTER ETA WITH TONOS
-0x03AF, "iotatonos" # GREEK SMALL LETTER IOTA WITH TONOS
-0x03B0, "upsilondieresistonos" # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS
-0x03B1, "alpha" # GREEK SMALL LETTER ALPHA
-0x03B2, "beta" # GREEK SMALL LETTER BETA
-0x03B3, "gamma" # GREEK SMALL LETTER GAMMA
-0x03B4, "delta" # GREEK SMALL LETTER DELTA
-0x03B5, "epsilon" # GREEK SMALL LETTER EPSILON
-0x03B6, "zeta" # GREEK SMALL LETTER ZETA
-0x03B7, "eta" # GREEK SMALL LETTER ETA
-0x03B8, "theta" # GREEK SMALL LETTER THETA
-0x03B9, "iota" # GREEK SMALL LETTER IOTA
-0x03BA, "kappa" # GREEK SMALL LETTER KAPPA
-0x03BB, "lambda" # GREEK SMALL LETTER LAMDA
-0x03BC, "mu" # GREEK SMALL LETTER MU;Duplicate
-0x03BD, "nu" # GREEK SMALL LETTER NU
-0x03BE, "xi" # GREEK SMALL LETTER XI
-0x03BF, "omicron" # GREEK SMALL LETTER OMICRON
-0x03C0, "pi" # GREEK SMALL LETTER PI
-0x03C1, "rho" # GREEK SMALL LETTER RHO
-0x03C2, "sigma1" # GREEK SMALL LETTER FINAL SIGMA
-0x03C3, "sigma" # GREEK SMALL LETTER SIGMA
-0x03C4, "tau" # GREEK SMALL LETTER TAU
-0x03C5, "upsilon" # GREEK SMALL LETTER UPSILON
-0x03C6, "phi" # GREEK SMALL LETTER PHI
-0x03C7, "chi" # GREEK SMALL LETTER CHI
-0x03C8, "psi" # GREEK SMALL LETTER PSI
-0x03C9, "omega" # GREEK SMALL LETTER OMEGA
-0x03CA, "iotadieresis" # GREEK SMALL LETTER IOTA WITH DIALYTIKA
-0x03CB, "upsilondieresis" # GREEK SMALL LETTER UPSILON WITH DIALYTIKA
-0x03CC, "omicrontonos" # GREEK SMALL LETTER OMICRON WITH TONOS
-0x03CD, "upsilontonos" # GREEK SMALL LETTER UPSILON WITH TONOS
-0x03CE, "omegatonos" # GREEK SMALL LETTER OMEGA WITH TONOS
-0x03D1, "theta1" # GREEK THETA SYMBOL
-0x03D2, "Upsilon1" # GREEK UPSILON WITH HOOK SYMBOL
-0x03D5, "phi1" # GREEK PHI SYMBOL
-0x03D6, "omega1" # GREEK PI SYMBOL
-# end of stuff from glyphlist.txt
-0xFFFF, ""
diff --git a/src/gui/painting/qpsprinter.ps b/src/gui/painting/qpsprinter.ps
deleted file mode 100644
index ef3f42970b..0000000000
--- a/src/gui/painting/qpsprinter.ps
+++ /dev/null
@@ -1,449 +0,0 @@
-% the postscript header we use for our qpsprinter in uncompressed and commented form.
-% use the makepsheader perl script to generate a compressed version of this header
-% you can then paste into qpsprinter.cpp
-%
-% some compression of the code is done by the makepsheader script, so we don't need to
-% write too criptically here.
-
-/BD {bind def} bind def
-/d2 {dup dup} BD
-/ED {exch def} BD
-/D0 {0 ED} BD
-
-/F {setfont} BD
-/RL {rlineto} BD
-/CM {currentmatrix} BD
-/SM {setmatrix} BD
-/TR {translate} BD
-/SD {setdash} BD
-/SC {aload pop setrgbcolor} BD
-/CR {currentfile read pop} BD
-/i {index} BD
-/scs {setcolorspace} BD
-/DB {dict dup begin} BD
-/DE {end def} BD
-/ie {ifelse} BD
-/gs {gsave} BD
-/gr {grestore} BD
-
-% these use PDF syntax
-/w {setlinewidth} BD
-/d {setdash} BD
-/J {setlinecap} BD
-/j {setlinejoin} BD
-/scn {3 array astore /BCol exch def} BD
-/SCN {3 array astore /PCol exch def} BD
-/cm {6 array astore concat} BD
-
-/m {moveto} BD
-/l {lineto} BD
-/c {curveto} BD
-/h {closepath} BD
-
-/W {clip} BD
-/W* {eoclip} BD
-/n {newpath} BD
-% ENDUNCOMPRESSED: Warning: leave this line in.
-% Everything before this line will be left untouched by the compression
-
-/q {gsave 10 dict begin} BD
-/Q {end grestore} BD
-
-% PDF operators
-/re { % PDF re operator
- 4 2 roll % w h x y
- moveto % w h
- dup % w h h
- 0 exch rlineto % w h
- exch 0 rlineto % h
- 0 exch neg rlineto
- closepath
-} bind def
-
-/S {
- gsave
- PCol SC stroke
- grestore
- newpath
-} BD
-
-% PDF text operators
-/BT {gsave 10 dict begin /_m matrix currentmatrix def BCol SC} BD
-/ET {end grestore} BD
-/Tf {
- /_fs exch def
- findfont
- [ _fs 0 0 _fs 0 0 ]
- makefont
- setfont
-} BD
-/Tm {6 array astore concat} BD
-/Td {translate} BD
-/Tj {0 0 moveto show} BD
-/BDC {pop pop} BD
-/EMC {} BD
-
-% old operators
-
-/BSt 0 def % brush style
-/WFi false def % winding fill
-
-/BCol [ 1 1 1 ] def % brush color
-/PCol [ 0 0 0 ] def % pen color
-/BDArr [ % Brush dense patterns
- 0.94
- 0.88
- 0.63
- 0.50
- 0.37
- 0.12
- 0.06
-] def
-
-% -- level3 true/false
-/level3 {
- /languagelevel where {
- pop
- languagelevel 3 ge
- } { false } ifelse
-} bind def
-
-
-%% image drawing routines
-
-% defines for QCI
-/QCIgray D0 /QCIcolor D0 /QCIindex D0
-
-% this method prints color images if colorimage is available, otherwise
-% converts the string to a grayscale image and uses the reular postscript image
-% operator for printing.
-% Arguments are the same as for the image operator:
-%
-% width height bits/sample matrix datasrc QCI -
-/QCI {
- /colorimage where {
- pop
- false 3 colorimage
- }{ % the hard way, based on PD code by John Walker <kelvin@autodesk.com>
- exec /QCIcolor exch def
- /QCIgray QCIcolor length 3 idiv string def
- 0 1 QCIcolor length 3 idiv 1 sub
- { /QCIindex exch def
- /_x QCIindex 3 mul def
- QCIgray QCIindex
- QCIcolor _x get 0.30 mul
- QCIcolor _x 1 add get 0.59 mul
- QCIcolor _x 2 add get 0.11 mul
- add add cvi
- put
- } for
- QCIgray image
- } ifelse
-} bind def
-
-% general image drawing routine, used from the postscript driver
-%
-% Draws images with and without mask with 1, 8 and 24(rgb) bits depth.
-%
-% width height matrix image 1|8|24 mask|false x y di
-%
-% width and height specify the width/height of the image,
-% matrix a transformation matrix, image a procedure holding the image data
-% (same for mask) and x/y an additional translation.
-%
-% ### should move the translation into the matrix!!!
-/di
-{
- gsave
- translate
- 1 index 1 eq { % bitmap
- pop pop % get rid of mask and depth
- false 3 1 roll % width height false matrix image
- BCol SC
- imagemask
- } {
- dup false ne {
- % have a mask, see if we can use it
- level3
- } {
- false
- } ifelse
-
- {
- % languagelevel3, we can use image mask and dicts
-
- % store the image mask
- /_ma exch def
- % select colorspace according to 8|24 bit depth and set the decode array /dc
- 8 eq {
- /_dc [0 1] def
- /DeviceGray
- } {
- /_dc [0 1 0 1 0 1] def
- /DeviceRGB
- } ifelse
- setcolorspace
- % the image data
- /_im exch def
- % transformation matrix
- /_mt exch def
- % width and height
- /_h exch def
- /_w exch def
- % and the combined image dict
- <<
- /ImageType 3
- % the image dict
- /DataDict <<
- /ImageType 1
- /Width _w
- /Height _h
- /ImageMatrix _mt
- /DataSource _im
- /BitsPerComponent 8
- /Decode _dc
- >>
- % the mask dictionary
- /MaskDict <<
- /ImageType 1
- /Width _w
- /Height _h
- /ImageMatrix _mt
- /DataSource _ma
- /BitsPerComponent 1
- /Decode [0 1]
- >>
- /InterleaveType 3
- >>
- image
- } {
- pop % no mask or can't use it, get rid of it
- 8 % width height image 8|24 8 matrix
- 4 1 roll
- 8 eq { % grayscale
- image
- } { %color
- QCI
- } ifelse
- } ifelse
- } ifelse
- grestore
-} bind def
-
-
-/BF { % brush fill
- gsave
- BSt 1 eq % solid brush?
- {
- BCol SC
- WFi { fill } { eofill } ifelse
- } if
- BSt 2 ge BSt 8 le and % dense pattern?
- {
- BDArr BSt 2 sub get /_sc exch def
- % the following line scales the brush color according to the pattern. the higher the pattern the lighter the color.
- BCol
- {
- 1. exch sub _sc mul 1. exch sub
- } forall
- 3 array astore
- SC
- WFi { fill } { eofill } ifelse
- } if
- BSt 9 ge BSt 14 le and % brush pattern?
- {
- WFi { clip } { eoclip } ifelse
- pathbbox % left upper right lower
- 3 index 3 index translate
- 4 2 roll % right lower left upper
- 3 2 roll % right left upper lower
- exch % left right lower upper
- sub /_h exch def
- sub /_w exch def
- BCol SC
- 0.3 setlinewidth
- newpath
- BSt 9 eq BSt 11 eq or % horiz or cross pattern
- { 0 4 _h
- { dup 0 exch moveto _w exch lineto } for
- } if
- BSt 10 eq BSt 11 eq or % vert or cross pattern
- { 0 4 _w
- { dup 0 moveto _h lineto } for
- } if
- BSt 12 eq BSt 14 eq or % F-diag or diag cross
- { _w _h gt
- { 0 6 _w _h add
- { dup 0 moveto _h sub _h lineto } for
- } { 0 6 _w _h add
- { dup 0 exch moveto _w sub _w exch lineto } for
- } ifelse
- } if
- BSt 13 eq BSt 14 eq or % B-diag or diag cross
- { _w _h gt
- { 0 6 _w _h add
- { dup _h moveto _h sub 0 lineto } for
- } { 0 6 _w _h add
- { dup _w exch moveto _w sub 0 exch lineto } for
- } ifelse
- } if
- stroke
- } if
- BSt 15 eq
- {
- } if
- BSt 24 eq % TexturePattern
- {
- } if
- grestore
-} bind def
-
-% more PDF operators
-/f { /WFi true def BF newpath } bind def
-/f* { /WFi false def BF newpath } bind def
-/B { /WFi true def BF S newpath } bind def
-/B* { /WFi false def BF S newpath } bind def
-
-%% start of page
-/QI {
- /C save def
- pageinit
- q
- newpath
-} bind def
-
-%% end of page
-/QP {
- Q % show page
- C restore
- showpage
-} bind def
-
-% merges one key value pair into the page device dict
-%
-% key value SPD -
-/SPD {
- /setpagedevice where {
- << 3 1 roll >>
- setpagedevice
- } { pop pop } ifelse
-} bind def
-
-
-% font handling
-
-/T1AddMapping { % basefont [glyphname ...] T1AddMapping -
- 10 dict begin
- /glyphs exch def
- /fnt exch def
- /current fnt /NumGlyphs get def
- /CMap fnt /CMap get def
-
- 0 1 glyphs length 1 sub % 0 1 (num glyphs - 1)
- {
- glyphs exch get /gn exch def
-
- current dup % glyph_index glyph_index
- 256 mod /min exch def % glyph_index
- 256 idiv /maj exch def % -
- CMap dup maj get dup % cmap cmap_maj cmap_maj
- null eq {
- pop 256 array
- 0 1 255 {1 index exch /.notdef put} for
- } if
- dup % cmap cmap_maj cmap_maj
- min gn put % cmap cmap_maj
- maj exch put % -
-
- /current current 1 add def
- } for
-
- fnt /CMap CMap put
- fnt /NumGlyphs current put
- end
-} def
-
-/T1AddGlyphs { % basefont [glyphname charstring ...] T1AddGlyphs -
- 10 dict begin
- /glyphs exch def
- /fnt exch def
- /current fnt /NumGlyphs get def
- /CMap fnt /CMap get def
- /CharStrings fnt /CharStrings get def
-
- 0 1 glyphs length 2 idiv 1 sub % 0 1 (num glyphs - 1)
- {
- 2 mul dup
- glyphs exch get /gn exch def
- 1 add
- glyphs exch get /cs exch def
-
- current dup % glyph_index glyph_index
- 256 mod /min exch def % glyph_index
- 256 idiv /maj exch def % -
- CMap dup maj get dup % cmap cmap_maj cmap_maj
- null eq {
- pop 256 array
- 0 1 255 {1 index exch /.notdef put} for
- } if
- dup % cmap cmap_maj cmap_maj
- min gn put % cmap cmap_maj
- maj exch put % -
-
- CharStrings gn cs put
- /current current 1 add def
- } for
-
- fnt /CharStrings CharStrings put
- fnt /CMap CMap put
- fnt /NumGlyphs current put
- end
-} def
-
-
-
-/StringAdd { % string1 string2 stringadd result
- 1 index length 1 index length add
- string
- 3 1 roll
- 2 index 0 3 index putinterval
- 2 index 2 index length 2 index putinterval
- pop pop
-} def
-
-
-/T1Setup { % fontname T1Setup -
-10 dict begin
- dup /FontName exch def
- (-Base) StringAdd cvx cvn /Font exch def
- /MaxPage Font /NumGlyphs get 1 sub 256 idiv def
-
- /FDepVector MaxPage 1 add array def
- /Encoding MaxPage 1 add array def
-
- 0 1 MaxPage {
- dup Encoding exch dup put
-
-
- dup /Page exch def
- FontName (-) StringAdd
- exch
- 20 string cvs StringAdd % page fontname
- cvn
-
- Font 0 dict copy dup dup /CMap get
- Page get
- /Encoding exch put definefont
- FDepVector exch Page exch put
- } for
-
- FontName cvn <<
- /FontType 0
- /FMapType 2
- /FontMatrix[1 0 0 1 0 0]
- /Encoding Encoding
- /FDepVector FDepVector
- >> definefont pop
- end
-} def
-
diff --git a/src/gui/painting/qregion.cpp b/src/gui/painting/qregion.cpp
index eb9fbf7ba1..d3a43c4193 100644
--- a/src/gui/painting/qregion.cpp
+++ b/src/gui/painting/qregion.cpp
@@ -252,17 +252,6 @@ QRegion::QRegion(int x, int y, int w, int h, RegionType t)
d = tmp.d;
}
-#ifdef QT3_SUPPORT
-/*!
- Use the constructor tha takes a Qt::FillRule as the second
- argument instead.
-*/
-QRegion::QRegion(const QPolygon &pa, bool winding)
-{
- new (this) QRegion(pa, winding ? Qt::WindingFill : Qt::OddEvenFill);
-}
-#endif
-
/*!
\fn QRegion::~QRegion()
\internal
@@ -553,7 +542,7 @@ QRegion& QRegion::operator|=(const QRegion &r)
\sa intersected()
*/
-#if !defined (Q_OS_UNIX) && !defined (Q_WS_WIN)
+#if !defined (Q_OS_UNIX) && !defined (Q_OS_WIN)
QRegion& QRegion::operator+=(const QRect &r)
{
return operator+=(QRegion(r));
@@ -576,7 +565,7 @@ QRegion& QRegion::operator&=(const QRegion &r)
\overload
\since 4.4
*/
-#if defined (Q_OS_UNIX) || defined (Q_WS_WIN)
+#if defined (Q_OS_UNIX) || defined (Q_OS_WIN)
QRegion& QRegion::operator&=(const QRect &r)
{
return *this = *this & r;
@@ -720,7 +709,7 @@ bool QRegion::intersects(const QRegion &region) const
*/
-#if !defined (Q_OS_UNIX) && !defined (Q_WS_WIN)
+#if !defined (Q_OS_UNIX) && !defined (Q_OS_WIN)
/*!
\overload
\since 4.4
@@ -1025,7 +1014,7 @@ void addSegmentsToPath(Segment *segment, QPainterPath &path)
}
-Q_AUTOTEST_EXPORT QPainterPath qt_regionToPath(const QRegion &region)
+Q_GUI_EXPORT QPainterPath qt_regionToPath(const QRegion &region)
{
QPainterPath result;
if (region.rectCount() == 1) {
@@ -1083,7 +1072,7 @@ Q_AUTOTEST_EXPORT QPainterPath qt_regionToPath(const QRegion &region)
return result;
}
-#if defined(Q_OS_UNIX) || defined(Q_WS_WIN)
+#if defined(Q_OS_UNIX) || defined(Q_OS_WIN)
//#define QT_REGION_DEBUG
/*
diff --git a/src/gui/painting/qregion.h b/src/gui/painting/qregion.h
index f4c68a9102..75d29e1ef5 100644
--- a/src/gui/painting/qregion.h
+++ b/src/gui/painting/qregion.h
@@ -74,9 +74,6 @@ public:
QRegion(int x, int y, int w, int h, RegionType t = Rectangle);
QRegion(const QRect &r, RegionType t = Rectangle);
QRegion(const QPolygon &pa, Qt::FillRule fillRule = Qt::OddEvenFill);
-#ifdef QT3_SUPPORT
- QT3_SUPPORT_CONSTRUCTOR QRegion(const QPolygon &pa, bool winding);
-#endif
QRegion(const QRegion &region);
QRegion(const QBitmap &bitmap);
~QRegion();
@@ -86,9 +83,6 @@ public:
{ qSwap(d, other.d); return *this; }
#endif
inline void swap(QRegion &other) { qSwap(d, other.d); }
-#ifdef QT3_SUPPORT
- inline QT3_SUPPORT bool isNull() const { return isEmpty(); }
-#endif
bool isEmpty() const;
bool contains(const QPoint &p) const;
@@ -190,6 +184,9 @@ private:
static OSStatus shape2QRegionHelper(int inMessage, HIShapeRef inShape,
const CGRect *inRect, void *inRefcon);
#endif
+#if defined(Q_WS_QWS) || defined(Q_WS_QPA)
+Q_GUI_EXPORT
+#endif
friend bool qt_region_strictContains(const QRegion &region,
const QRect &rect);
friend struct QRegionPrivate;
diff --git a/src/gui/painting/qregion_mac.cpp b/src/gui/painting/qregion_mac.cpp
deleted file mode 100644
index 3a0346abc4..0000000000
--- a/src/gui/painting/qregion_mac.cpp
+++ /dev/null
@@ -1,286 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <private/qt_mac_p.h>
-#include "qcoreapplication.h"
-#include <qlibrary.h>
-
-QT_BEGIN_NAMESPACE
-
-QRegion::QRegionData QRegion::shared_empty = { Q_BASIC_ATOMIC_INITIALIZER(1), 0 };
-
-#if defined(Q_WS_MAC32) && !defined(QT_MAC_USE_COCOA)
-#define RGN_CACHE_SIZE 200
-#ifdef RGN_CACHE_SIZE
-static bool rgncache_init = false;
-static int rgncache_used;
-static RgnHandle rgncache[RGN_CACHE_SIZE];
-static void qt_mac_cleanup_rgncache()
-{
- rgncache_init = false;
- for(int i = 0; i < RGN_CACHE_SIZE; ++i) {
- if(rgncache[i]) {
- --rgncache_used;
- DisposeRgn(rgncache[i]);
- rgncache[i] = 0;
- }
- }
-}
-#endif
-
-Q_GUI_EXPORT RgnHandle qt_mac_get_rgn()
-{
-#ifdef RGN_CACHE_SIZE
- if(!rgncache_init) {
- rgncache_used = 0;
- rgncache_init = true;
- for(int i = 0; i < RGN_CACHE_SIZE; ++i)
- rgncache[i] = 0;
- qAddPostRoutine(qt_mac_cleanup_rgncache);
- } else if(rgncache_used) {
- for(int i = 0; i < RGN_CACHE_SIZE; ++i) {
- if(rgncache[i]) {
- RgnHandle ret = rgncache[i];
- SetEmptyRgn(ret);
- rgncache[i] = 0;
- --rgncache_used;
- return ret;
- }
- }
- }
-#endif
- return NewRgn();
-}
-
-Q_GUI_EXPORT void qt_mac_dispose_rgn(RgnHandle r)
-{
-#ifdef RGN_CACHE_SIZE
- if(rgncache_init && rgncache_used < RGN_CACHE_SIZE) {
- for(int i = 0; i < RGN_CACHE_SIZE; ++i) {
- if(!rgncache[i]) {
- ++rgncache_used;
- rgncache[i] = r;
- return;
- }
- }
- }
-#endif
- DisposeRgn(r);
-}
-
-static OSStatus qt_mac_get_rgn_rect(UInt16 msg, RgnHandle, const Rect *rect, void *reg)
-{
- if(msg == kQDRegionToRectsMsgParse) {
- QRect rct(rect->left, rect->top, (rect->right - rect->left), (rect->bottom - rect->top));
- if(!rct.isEmpty())
- *((QRegion *)reg) += rct;
- }
- return noErr;
-}
-
-Q_GUI_EXPORT QRegion qt_mac_convert_mac_region(RgnHandle rgn)
-{
- return QRegion::fromQDRgn(rgn);
-}
-
-QRegion QRegion::fromQDRgn(RgnHandle rgn)
-{
- QRegion ret;
- ret.detach();
- OSStatus oss = QDRegionToRects(rgn, kQDParseRegionFromTopLeft, qt_mac_get_rgn_rect, (void *)&ret);
- if(oss != noErr)
- return QRegion();
- return ret;
-}
-
-/*!
- \internal
- Create's a RegionHandle, it's the caller's responsibility to release.
-*/
-RgnHandle QRegion::toQDRgn() const
-{
- RgnHandle rgnHandle = qt_mac_get_rgn();
- if(d->qt_rgn && d->qt_rgn->numRects) {
- RgnHandle tmp_rgn = qt_mac_get_rgn();
- int n = d->qt_rgn->numRects;
- const QRect *qt_r = (n == 1) ? &d->qt_rgn->extents : d->qt_rgn->rects.constData();
- while (n--) {
- SetRectRgn(tmp_rgn,
- qMax(SHRT_MIN, qt_r->x()),
- qMax(SHRT_MIN, qt_r->y()),
- qMin(SHRT_MAX, qt_r->right() + 1),
- qMin(SHRT_MAX, qt_r->bottom() + 1));
- UnionRgn(rgnHandle, tmp_rgn, rgnHandle);
- ++qt_r;
- }
- qt_mac_dispose_rgn(tmp_rgn);
- }
- return rgnHandle;
-}
-
-/*!
- \internal
- Create's a RegionHandle, it's the caller's responsibility to release.
- Returns 0 if the QRegion overflows.
-*/
-RgnHandle QRegion::toQDRgnForUpdate_sys() const
-{
- RgnHandle rgnHandle = qt_mac_get_rgn();
- if(d->qt_rgn && d->qt_rgn->numRects) {
- RgnHandle tmp_rgn = qt_mac_get_rgn();
- int n = d->qt_rgn->numRects;
- const QRect *qt_r = (n == 1) ? &d->qt_rgn->extents : d->qt_rgn->rects.constData();
- while (n--) {
-
- // detect overflow. Tested for use with HIViewSetNeedsDisplayInRegion
- // in QWidgetPrivate::update_sys().
- enum { HIViewSetNeedsDisplayInRegionOverflow = 10000 }; // empirically determined conservative value
- if (qt_r->right() > HIViewSetNeedsDisplayInRegionOverflow || qt_r->bottom() > HIViewSetNeedsDisplayInRegionOverflow) {
- qt_mac_dispose_rgn(tmp_rgn);
- qt_mac_dispose_rgn(rgnHandle);
- return 0;
- }
-
- SetRectRgn(tmp_rgn,
- qMax(SHRT_MIN, qt_r->x()),
- qMax(SHRT_MIN, qt_r->y()),
- qMin(SHRT_MAX, qt_r->right() + 1),
- qMin(SHRT_MAX, qt_r->bottom() + 1));
- UnionRgn(rgnHandle, tmp_rgn, rgnHandle);
- ++qt_r;
- }
- qt_mac_dispose_rgn(tmp_rgn);
- }
- return rgnHandle;
-}
-
-#endif
-
-#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
-OSStatus QRegion::shape2QRegionHelper(int inMessage, HIShapeRef,
- const CGRect *inRect, void *inRefcon)
-{
- QRegion *region = static_cast<QRegion *>(inRefcon);
- if (!region)
- return paramErr;
-
- switch (inMessage) {
- case kHIShapeEnumerateRect:
- *region += QRect(inRect->origin.x, inRect->origin.y,
- inRect->size.width, inRect->size.height);
- break;
- case kHIShapeEnumerateInit:
- // Assume the region is already setup correctly
- case kHIShapeEnumerateTerminate:
- default:
- break;
- }
- return noErr;
-}
-#endif
-
-/*!
- \internal
- Create's a mutable shape, it's the caller's responsibility to release.
- WARNING: this function clamps the coordinates to SHRT_MIN/MAX on 10.4 and below.
-*/
-HIMutableShapeRef QRegion::toHIMutableShape() const
-{
- HIMutableShapeRef shape = HIShapeCreateMutable();
-#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
- if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) {
- if (d->qt_rgn && d->qt_rgn->numRects) {
- int n = d->qt_rgn->numRects;
- const QRect *qt_r = (n == 1) ? &d->qt_rgn->extents : d->qt_rgn->rects.constData();
- while (n--) {
- CGRect cgRect = CGRectMake(qt_r->x(), qt_r->y(), qt_r->width(), qt_r->height());
- HIShapeUnionWithRect(shape, &cgRect);
- ++qt_r;
- }
- }
- } else
-#endif
- {
-#ifndef QT_MAC_USE_COCOA
- QCFType<HIShapeRef> qdShape = HIShapeCreateWithQDRgn(QMacSmartQuickDrawRegion(toQDRgn()));
- HIShapeUnion(qdShape, shape, shape);
-#endif
- }
- return shape;
-}
-
-#if !defined(Q_WS_MAC64) && !defined(QT_MAC_USE_COCOA)
-typedef OSStatus (*PtrHIShapeGetAsQDRgn)(HIShapeRef, RgnHandle);
-static PtrHIShapeGetAsQDRgn ptrHIShapeGetAsQDRgn = 0;
-#endif
-
-
-QRegion QRegion::fromHIShapeRef(HIShapeRef shape)
-{
- QRegion returnRegion;
- returnRegion.detach();
- // Begin gratuitous #if-defery
-#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
-# ifndef Q_WS_MAC64
- if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) {
-# endif
- HIShapeEnumerate(shape, kHIShapeParseFromTopLeft, shape2QRegionHelper, &returnRegion);
-# ifndef Q_WS_MAC64
- } else
-# endif
-#endif
- {
-#if !defined(Q_WS_MAC64) && !defined(QT_MAC_USE_COCOA)
- if (ptrHIShapeGetAsQDRgn == 0) {
- QLibrary library(QLatin1String("/System/Library/Frameworks/Carbon.framework/Carbon"));
- library.setLoadHints(QLibrary::ExportExternalSymbolsHint);
- ptrHIShapeGetAsQDRgn = reinterpret_cast<PtrHIShapeGetAsQDRgn>(library.resolve("HIShapeGetAsQDRgn"));
- }
- RgnHandle rgn = qt_mac_get_rgn();
- ptrHIShapeGetAsQDRgn(shape, rgn);
- returnRegion = QRegion::fromQDRgn(rgn);
- qt_mac_dispose_rgn(rgn);
-#endif
- }
- return returnRegion;
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/painting/qregion_qws.cpp b/src/gui/painting/qregion_qws.cpp
deleted file mode 100644
index 3ec1112aa3..0000000000
--- a/src/gui/painting/qregion_qws.cpp
+++ /dev/null
@@ -1,3183 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-// XXX - add appropriate friendship relationships
-#define private public
-#include "qregion.h"
-#undef private
-#include "qpainterpath.h"
-#include "qpolygon.h"
-#include "qbuffer.h"
-#include "qimage.h"
-#include <qdebug.h>
-#include "qbitmap.h"
-#include <stdlib.h>
-#include <qatomic.h>
-#include <qsemaphore.h>
-
-QT_BEGIN_NAMESPACE
-
-class QFastMutex
-{
- QAtomicInt contenders;
- QSemaphore semaphore;
-public:
- inline QFastMutex()
- : contenders(0), semaphore(0)
- { }
- inline void lock()
- {
- if (contenders.fetchAndAddAcquire(1) != 0) {
- semaphore.acquire();
- contenders.deref();
- }
- }
- inline bool tryLock()
- {
- return contenders.testAndSetAcquire(0, 1);
- }
- inline void unlock()
- {
- if (!contenders.testAndSetRelease(1, 0))
- semaphore.release();
- }
-};
-
-
-/*
- * 1 if r1 contains r2
- * 0 if r1 does not completely contain r2
- */
-#define CONTAINSCHECK(r1, r2) \
- ((r2).left() >= (r1).left() && (r2).right() <= (r1).right() && \
- (r2).top() >= (r1).top() && (r2).bottom() <= (r1).bottom())
-
-/*
- * clip region
- */
-struct QRegionPrivate : public QRegion::QRegionData {
- enum { Single, Vector } mode;
- int numRects;
- QVector<QRect> rects;
- QRect single;
- QRect extents;
- QRect innerRect;
- union {
- int innerArea;
- QRegionPrivate *next;
- };
-
- inline void vector()
- {
- if(mode != Vector && numRects) {
- if(rects.size() < 1) rects.resize(1);
- rects[0] = single;
- }
- mode = Vector;
- }
-
- inline QRegionPrivate() : mode(Single), numRects(0), innerArea(-1) {}
- inline QRegionPrivate(const QRect &r) : mode(Single) {
- numRects = 1;
-// rects[0] = r;
- single = r;
- extents = r;
- innerRect = r;
- innerArea = r.width() * r.height();
- }
-
- inline QRegionPrivate(const QRegionPrivate &r) {
- mode = r.mode;
- rects = r.rects;
- single = r.single;
- numRects = r.numRects;
- extents = r.extents;
- innerRect = r.innerRect;
- innerArea = r.innerArea;
- }
-
- inline QRegionPrivate &operator=(const QRegionPrivate &r) {
- mode = r.mode;
- rects = r.rects;
- single = r.single;
- numRects = r.numRects;
- extents = r.extents;
- innerRect = r.innerRect;
- innerArea = r.innerArea;
- return *this;
- }
-
- /*
- * Returns true if r is guaranteed to be fully contained in this region.
- * A false return value does not guarantee the opposite.
- */
- inline bool contains(const QRegionPrivate &r) const {
- const QRect &r1 = innerRect;
- const QRect &r2 = r.extents;
- return CONTAINSCHECK(r1, r2);
- }
-
- inline void updateInnerRect(const QRect &rect) {
- const int area = rect.width() * rect.height();
- if (area > innerArea) {
- innerArea = area;
- innerRect = rect;
- }
- }
-
- void append(const QRegionPrivate *r);
- void prepend(const QRegionPrivate *r);
- inline bool canAppend(const QRegionPrivate *r) const;
- inline bool canPrepend(const QRegionPrivate *r) const;
-};
-
-static QRegionPrivate *qt_nextRegionPtr = 0;
-static QFastMutex qt_nextRegionLock;
-
-static QRegionPrivate *qt_allocRegionMemory()
-{
- QRegionPrivate *rv = 0;
- qt_nextRegionLock.lock();
-
- if(qt_nextRegionPtr) {
- rv = qt_nextRegionPtr;
- qt_nextRegionPtr = rv->next;
- } else {
- qt_nextRegionPtr =
- (QRegionPrivate *)malloc(256 * sizeof(QRegionPrivate));
- for(int ii = 0; ii < 256; ++ii) {
- if(ii == 255) {
- qt_nextRegionPtr[ii].next = 0;
- } else {
- qt_nextRegionPtr[ii].next = &qt_nextRegionPtr[ii + 1];
- }
- }
-
- rv = qt_nextRegionPtr;
- qt_nextRegionPtr = rv->next;
- }
-
- qt_nextRegionLock.unlock();
- return rv;
-}
-
-static void qt_freeRegionMemory(QRegionPrivate *rp)
-{
- qt_nextRegionLock.lock();
- rp->next = qt_nextRegionPtr;
- qt_nextRegionPtr = rp;
- qt_nextRegionLock.unlock();
-}
-
-static QRegionPrivate *qt_allocRegion()
-{
- QRegionPrivate *mem = qt_allocRegionMemory();
- return new (mem) QRegionPrivate;
-}
-
-static QRegionPrivate *qt_allocRegion(const QRect &r)
-{
- QRegionPrivate *mem = qt_allocRegionMemory();
- return new (mem) QRegionPrivate(r);
-}
-
-static QRegionPrivate *qt_allocRegion(const QRegionPrivate &r)
-{
- QRegionPrivate *mem = qt_allocRegionMemory();
- return new (mem) QRegionPrivate(r);
-}
-
-void qt_freeRegion(QRegionPrivate *rp)
-{
- rp->~QRegionPrivate();
- qt_freeRegionMemory(rp);
-// delete rp;
-}
-
-static inline bool isEmptyHelper(const QRegionPrivate *preg)
-{
- return !preg || preg->numRects == 0;
-}
-
-void QRegionPrivate::append(const QRegionPrivate *r)
-{
- Q_ASSERT(!isEmptyHelper(r));
-
- vector();
- QRect *destRect = rects.data() + numRects;
- const QRect *srcRect = (r->mode==Vector)?r->rects.constData():&r->single;
- int numAppend = r->numRects;
-
- // test for merge in x direction
- {
- const QRect *rFirst = srcRect;
- QRect *myLast = rects.data() + (numRects - 1);
- if (rFirst->top() == myLast->top()
- && rFirst->height() == myLast->height()
- && rFirst->left() == (myLast->right() + 1))
- {
- myLast->setWidth(myLast->width() + rFirst->width());
- updateInnerRect(*myLast);
- ++srcRect;
- --numAppend;
- }
- }
-
- // append rectangles
- const int newNumRects = numRects + numAppend;
- if (newNumRects > rects.size()) {
- rects.resize(newNumRects);
- destRect = rects.data() + numRects;
- }
- memcpy(destRect, srcRect, numAppend * sizeof(QRect));
-
- // update inner rectangle
- if (innerArea < r->innerArea) {
- innerArea = r->innerArea;
- innerRect = r->innerRect;
- }
-
- // update extents
- destRect = &extents;
- srcRect = &r->extents;
- extents.setCoords(qMin(destRect->left(), srcRect->left()),
- qMin(destRect->top(), srcRect->top()),
- qMax(destRect->right(), srcRect->right()),
- qMax(destRect->bottom(), srcRect->bottom()));
-
- numRects = newNumRects;
-}
-
-void QRegionPrivate::prepend(const QRegionPrivate *r)
-{
-#if 1
- Q_UNUSED(r);
-#else
- // XXX ak: does not respect vectorization of region
-
- Q_ASSERT(!isEmpty(r));
-
- // move existing rectangles
- memmove(rects.data() + r->numRects, rects.constData(),
- numRects * sizeof(QRect));
-
- // prepend new rectangles
- memcpy(rects.data(), r->rects.constData(), r->numRects * sizeof(QRect));
-
- // update inner rectangle
- if (innerArea < r->innerArea) {
- innerArea = r->innerArea;
- innerRect = r->innerRect;
- }
-
- // update extents
- destRect = &extents;
- srcRect = &r->extents;
- extents.setCoords(qMin(destRect->left(), srcRect->left()),
- qMin(destRect->top(), srcRect->top()),
- qMax(destRect->right(), srcRect->right()),
- qMax(destRect->bottom(), srcRect->bottom()));
-
- numRects = newNumRects;
-#endif
-}
-
-bool QRegionPrivate::canAppend(const QRegionPrivate *r) const
-{
- Q_ASSERT(!isEmptyHelper(r));
-
- const QRect *rFirst = (r->mode==Vector)?r->rects.constData():&r->single;
- const QRect *myLast = (mode==Vector)?(rects.constData() + (numRects - 1)):&single;
- // XXX: possible improvements:
- // - nFirst->top() == myLast->bottom() + 1, must possibly merge bands
- if (rFirst->top() > (myLast->bottom() + 1)
- || (rFirst->top() == myLast->top()
- && rFirst->height() == myLast->height()
- && rFirst->left() > myLast->right()))
- {
- return true;
- }
-
- return false;
-}
-
-bool QRegionPrivate::canPrepend(const QRegionPrivate *r) const
-{
-#if 1
- Q_UNUSED(r);
- return false;
-#else
- return r->canAppend(this);
-#endif
-}
-
-#if defined(Q_WS_X11)
-QT_BEGIN_INCLUDE_NAMESPACE
-# include "qregion_x11.cpp"
-QT_END_INCLUDE_NAMESPACE
-#elif defined(Q_WS_MAC)
-QT_BEGIN_INCLUDE_NAMESPACE
-# include "qregion_mac.cpp"
-QT_END_INCLUDE_NAMESPACE
-#elif defined(Q_WS_QWS)
-static QRegionPrivate qrp;
-QRegion::QRegionData QRegion::shared_empty = {Q_BASIC_ATOMIC_INITIALIZER(1), &qrp};
-#endif
-
-typedef void (*OverlapFunc)(register QRegionPrivate &dest, register const QRect *r1, const QRect *r1End,
- register const QRect *r2, const QRect *r2End, register int y1, register int y2);
-typedef void (*NonOverlapFunc)(register QRegionPrivate &dest, register const QRect *r, const QRect *rEnd,
- register int y1, register int y2);
-
-static bool EqualRegion(const QRegionPrivate *r1, const QRegionPrivate *r2);
-static void UnionRegion(const QRegionPrivate *reg1, const QRegionPrivate *reg2, QRegionPrivate &dest);
-static void miRegionOp(register QRegionPrivate &dest, const QRegionPrivate *reg1, const QRegionPrivate *reg2,
- OverlapFunc overlapFunc, NonOverlapFunc nonOverlap1Func,
- NonOverlapFunc nonOverlap2Func);
-
-#define RectangleOut 0
-#define RectangleIn 1
-#define RectanglePart 2
-#define EvenOddRule 0
-#define WindingRule 1
-
-// START OF region.h extract
-/* $XConsortium: region.h,v 11.14 94/04/17 20:22:20 rws Exp $ */
-/************************************************************************
-
-Copyright (c) 1987 X Consortium
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of the X Consortium shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from the X Consortium.
-
-
-Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
-
- All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the name of Digital not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.
-
-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
-************************************************************************/
-
-#ifndef _XREGION_H
-#define _XREGION_H
-
-QT_BEGIN_INCLUDE_NAMESPACE
-#include <limits.h>
-QT_END_INCLUDE_NAMESPACE
-
-/* 1 if two BOXs overlap.
- * 0 if two BOXs do not overlap.
- * Remember, x2 and y2 are not in the region
- */
-#define EXTENTCHECK(r1, r2) \
- ((r1)->right() >= (r2)->left() && \
- (r1)->left() <= (r2)->right() && \
- (r1)->bottom() >= (r2)->top() && \
- (r1)->top() <= (r2)->bottom())
-
-/*
- * update region extents
- */
-#define EXTENTS(r,idRect){\
- if((r)->left() < (idRect)->extents.left())\
- (idRect)->extents.setLeft((r)->left());\
- if((r)->top() < (idRect)->extents.top())\
- (idRect)->extents.setTop((r)->top());\
- if((r)->right() > (idRect)->extents.right())\
- (idRect)->extents.setRight((r)->right());\
- if((r)->bottom() > (idRect)->extents.bottom())\
- (idRect)->extents.setBottom((r)->bottom());\
- }
-
-/*
- * Check to see if there is enough memory in the present region.
- */
-#define MEMCHECK(dest, rect, firstrect){\
- if ((dest).numRects >= ((dest).rects.size()-1)){\
- firstrect.resize(firstrect.size() * 2); \
- (rect) = (firstrect).data() + (dest).numRects;\
- }\
- }
-
-
-/*
- * number of points to buffer before sending them off
- * to scanlines(): Must be an even number
- */
-#define NUMPTSTOBUFFER 200
-
-/*
- * used to allocate buffers for points and link
- * the buffers together
- */
-typedef struct _POINTBLOCK {
- QPoint pts[NUMPTSTOBUFFER];
- struct _POINTBLOCK *next;
-} POINTBLOCK;
-
-#endif
-// END OF region.h extract
-
-// START OF Region.c extract
-/* $XConsortium: Region.c /main/30 1996/10/22 14:21:24 kaleb $ */
-/************************************************************************
-
-Copyright (c) 1987, 1988 X Consortium
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of the X Consortium shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from the X Consortium.
-
-
-Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts.
-
- All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the name of Digital not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.
-
-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
-************************************************************************/
-/*
- * The functions in this file implement the Region abstraction, similar to one
- * used in the X11 sample server. A Region is simply an area, as the name
- * implies, and is implemented as a "y-x-banded" array of rectangles. To
- * explain: Each Region is made up of a certain number of rectangles sorted
- * by y coordinate first, and then by x coordinate.
- *
- * Furthermore, the rectangles are banded such that every rectangle with a
- * given upper-left y coordinate (y1) will have the same lower-right y
- * coordinate (y2) and vice versa. If a rectangle has scanlines in a band, it
- * will span the entire vertical distance of the band. This means that some
- * areas that could be merged into a taller rectangle will be represented as
- * several shorter rectangles to account for shorter rectangles to its left
- * or right but within its "vertical scope".
- *
- * An added constraint on the rectangles is that they must cover as much
- * horizontal area as possible. E.g. no two rectangles in a band are allowed
- * to touch.
- *
- * Whenever possible, bands will be merged together to cover a greater vertical
- * distance (and thus reduce the number of rectangles). Two bands can be merged
- * only if the bottom of one touches the top of the other and they have
- * rectangles in the same places (of the same width, of course). This maintains
- * the y-x-banding that's so nice to have...
- */
-/* $XFree86: xc/lib/X11/Region.c,v 1.1.1.2.2.2 1998/10/04 15:22:50 hohndel Exp $ */
-
-static void UnionRectWithRegion(register const QRect *rect, const QRegionPrivate *source,
- QRegionPrivate &dest)
-{
- if (!rect->width() || !rect->height())
- return;
-
- QRegionPrivate region(*rect);
-
- Q_ASSERT(EqualRegion(source, &dest));
- Q_ASSERT(!isEmptyHelper(&region));
-
- if (dest.numRects == 0)
- dest = region;
- else if (dest.canAppend(&region))
- dest.append(&region);
- else
- UnionRegion(&region, source, dest);
-}
-
-/*-
- *-----------------------------------------------------------------------
- * miSetExtents --
- * Reset the extents and innerRect of a region to what they should be.
- * Called by miSubtract and miIntersect b/c they can't figure it out
- * along the way or do so easily, as miUnion can.
- *
- * Results:
- * None.
- *
- * Side Effects:
- * The region's 'extents' and 'innerRect' structure is overwritten.
- *
- *-----------------------------------------------------------------------
- */
-static void miSetExtents(QRegionPrivate &dest)
-{
- register const QRect *pBox,
- *pBoxEnd;
- register QRect *pExtents;
-
- dest.innerRect.setCoords(0, 0, -1, -1);
- dest.innerArea = -1;
- if (dest.numRects == 0) {
- dest.extents.setCoords(0, 0, 0, 0);
- return;
- }
-
- pExtents = &dest.extents;
- pBox = (dest.mode==QRegionPrivate::Vector)?(dest.rects.constData()):(&dest.single);
- pBoxEnd = (dest.mode==QRegionPrivate::Vector)?(&pBox[dest.numRects - 1]):(&dest.single);
-
- /*
- * Since pBox is the first rectangle in the region, it must have the
- * smallest y1 and since pBoxEnd is the last rectangle in the region,
- * it must have the largest y2, because of banding. Initialize x1 and
- * x2 from pBox and pBoxEnd, resp., as good things to initialize them
- * to...
- */
- pExtents->setLeft(pBox->left());
- pExtents->setTop(pBox->top());
- pExtents->setRight(pBoxEnd->right());
- pExtents->setBottom(pBoxEnd->bottom());
-
- Q_ASSERT(pExtents->top() <= pExtents->bottom());
- while (pBox <= pBoxEnd) {
- if (pBox->left() < pExtents->left())
- pExtents->setLeft(pBox->left());
- if (pBox->right() > pExtents->right())
- pExtents->setRight(pBox->right());
- dest.updateInnerRect(*pBox);
- ++pBox;
- }
- Q_ASSERT(pExtents->left() <= pExtents->right());
-}
-
-/* TranslateRegion(pRegion, x, y)
- translates in place
- added by raymond
-*/
-
-static void OffsetRegion(register QRegionPrivate &region, register int x, register int y)
-{
- register int nbox;
- register QRect *pbox;
-
- if(region.mode == QRegionPrivate::Single) {
- region.single.translate(x, y);
- } else {
- pbox = region.rects.data();
- nbox = region.numRects;
-
- while (nbox--) {
- pbox->translate(x, y);
- ++pbox;
- }
- }
- region.extents.translate(x, y);
- region.innerRect.translate(x, y);
-}
-
-/*======================================================================
- * Region Intersection
- *====================================================================*/
-/*-
- *-----------------------------------------------------------------------
- * miIntersectO --
- * Handle an overlapping band for miIntersect.
- *
- * Results:
- * None.
- *
- * Side Effects:
- * Rectangles may be added to the region.
- *
- *-----------------------------------------------------------------------
- */
-static void miIntersectO(register QRegionPrivate &dest, register const QRect *r1, const QRect *r1End,
- register const QRect *r2, const QRect *r2End, int y1, int y2)
-{
- register int x1;
- register int x2;
- register QRect *pNextRect;
-
- pNextRect = dest.rects.data() + dest.numRects;
-
- while (r1 != r1End && r2 != r2End) {
- x1 = qMax(r1->left(), r2->left());
- x2 = qMin(r1->right(), r2->right());
-
- /*
- * If there's any overlap between the two rectangles, add that
- * overlap to the new region.
- * There's no need to check for subsumption because the only way
- * such a need could arise is if some region has two rectangles
- * right next to each other. Since that should never happen...
- */
- if (x1 <= x2) {
- Q_ASSERT(y1 <= y2);
- MEMCHECK(dest, pNextRect, dest.rects)
- pNextRect->setCoords(x1, y1, x2, y2);
- ++dest.numRects;
- ++pNextRect;
- }
-
- /*
- * Need to advance the pointers. Shift the one that extends
- * to the right the least, since the other still has a chance to
- * overlap with that region's next rectangle, if you see what I mean.
- */
- if (r1->right() < r2->right()) {
- ++r1;
- } else if (r2->right() < r1->right()) {
- ++r2;
- } else {
- ++r1;
- ++r2;
- }
- }
-}
-
-/*======================================================================
- * Generic Region Operator
- *====================================================================*/
-
-/*-
- *-----------------------------------------------------------------------
- * miCoalesce --
- * Attempt to merge the boxes in the current band with those in the
- * previous one. Used only by miRegionOp.
- *
- * Results:
- * The new index for the previous band.
- *
- * Side Effects:
- * If coalescing takes place:
- * - rectangles in the previous band will have their y2 fields
- * altered.
- * - dest.numRects will be decreased.
- *
- *-----------------------------------------------------------------------
- */
-static int miCoalesce(register QRegionPrivate &dest, int prevStart, int curStart)
-{
- register QRect *pPrevBox; /* Current box in previous band */
- register QRect *pCurBox; /* Current box in current band */
- register QRect *pRegEnd; /* End of region */
- int curNumRects; /* Number of rectangles in current band */
- int prevNumRects; /* Number of rectangles in previous band */
- int bandY1; /* Y1 coordinate for current band */
- QRect *rData = dest.rects.data();
-
- pRegEnd = rData + dest.numRects;
-
- pPrevBox = rData + prevStart;
- prevNumRects = curStart - prevStart;
-
- /*
- * Figure out how many rectangles are in the current band. Have to do
- * this because multiple bands could have been added in miRegionOp
- * at the end when one region has been exhausted.
- */
- pCurBox = rData + curStart;
- bandY1 = pCurBox->top();
- for (curNumRects = 0; pCurBox != pRegEnd && pCurBox->top() == bandY1; ++curNumRects) {
- ++pCurBox;
- }
-
- if (pCurBox != pRegEnd) {
- /*
- * If more than one band was added, we have to find the start
- * of the last band added so the next coalescing job can start
- * at the right place... (given when multiple bands are added,
- * this may be pointless -- see above).
- */
- --pRegEnd;
- while ((pRegEnd - 1)->top() == pRegEnd->top())
- --pRegEnd;
- curStart = pRegEnd - rData;
- pRegEnd = rData + dest.numRects;
- }
-
- if (curNumRects == prevNumRects && curNumRects != 0) {
- pCurBox -= curNumRects;
- /*
- * The bands may only be coalesced if the bottom of the previous
- * matches the top scanline of the current.
- */
- if (pPrevBox->bottom() == pCurBox->top() - 1) {
- /*
- * Make sure the bands have boxes in the same places. This
- * assumes that boxes have been added in such a way that they
- * cover the most area possible. I.e. two boxes in a band must
- * have some horizontal space between them.
- */
- do {
- if (pPrevBox->left() != pCurBox->left() || pPrevBox->right() != pCurBox->right()) {
- // The bands don't line up so they can't be coalesced.
- return curStart;
- }
- ++pPrevBox;
- ++pCurBox;
- --prevNumRects;
- } while (prevNumRects != 0);
-
- dest.numRects -= curNumRects;
- pCurBox -= curNumRects;
- pPrevBox -= curNumRects;
-
- /*
- * The bands may be merged, so set the bottom y of each box
- * in the previous band to that of the corresponding box in
- * the current band.
- */
- do {
- pPrevBox->setBottom(pCurBox->bottom());
- dest.updateInnerRect(*pPrevBox);
- ++pPrevBox;
- ++pCurBox;
- curNumRects -= 1;
- } while (curNumRects != 0);
-
- /*
- * If only one band was added to the region, we have to backup
- * curStart to the start of the previous band.
- *
- * If more than one band was added to the region, copy the
- * other bands down. The assumption here is that the other bands
- * came from the same region as the current one and no further
- * coalescing can be done on them since it's all been done
- * already... curStart is already in the right place.
- */
- if (pCurBox == pRegEnd) {
- curStart = prevStart;
- } else {
- do {
- *pPrevBox++ = *pCurBox++;
- dest.updateInnerRect(*pPrevBox);
- } while (pCurBox != pRegEnd);
- }
- }
- }
- return curStart;
-}
-
-/*-
- *-----------------------------------------------------------------------
- * miRegionOp --
- * Apply an operation to two regions. Called by miUnion, miInverse,
- * miSubtract, miIntersect...
- *
- * Results:
- * None.
- *
- * Side Effects:
- * The new region is overwritten.
- *
- * Notes:
- * The idea behind this function is to view the two regions as sets.
- * Together they cover a rectangle of area that this function divides
- * into horizontal bands where points are covered only by one region
- * or by both. For the first case, the nonOverlapFunc is called with
- * each the band and the band's upper and lower extents. For the
- * second, the overlapFunc is called to process the entire band. It
- * is responsible for clipping the rectangles in the band, though
- * this function provides the boundaries.
- * At the end of each band, the new region is coalesced, if possible,
- * to reduce the number of rectangles in the region.
- *
- *-----------------------------------------------------------------------
- */
-static void miRegionOp(register QRegionPrivate &dest, const QRegionPrivate *reg1, const QRegionPrivate *reg2,
- OverlapFunc overlapFunc, NonOverlapFunc nonOverlap1Func,
- NonOverlapFunc nonOverlap2Func)
-{
- register const QRect *r1; // Pointer into first region
- register const QRect *r2; // Pointer into 2d region
- const QRect *r1End; // End of 1st region
- const QRect *r2End; // End of 2d region
- register int ybot; // Bottom of intersection
- register int ytop; // Top of intersection
- int prevBand; // Index of start of previous band in dest
- int curBand; // Index of start of current band in dest
- register const QRect *r1BandEnd; // End of current band in r1
- register const QRect *r2BandEnd; // End of current band in r2
- int top; // Top of non-overlapping band
- int bot; // Bottom of non-overlapping band
-
- /*
- * Initialization:
- * set r1, r2, r1End and r2End appropriately, preserve the important
- * parts of the destination region until the end in case it's one of
- * the two source regions, then mark the "new" region empty, allocating
- * another array of rectangles for it to use.
- */
- r1 = (reg1->mode==QRegionPrivate::Vector)?reg1->rects.data():&reg1->single;
- r2 = (reg2->mode==QRegionPrivate::Vector)?reg2->rects.data():&reg2->single;
- r1End = r1 + reg1->numRects;
- r2End = r2 + reg2->numRects;
-
- dest.vector();
- QVector<QRect> oldRects = dest.rects;
-
- dest.numRects = 0;
-
- /*
- * Allocate a reasonable number of rectangles for the new region. The idea
- * is to allocate enough so the individual functions don't need to
- * reallocate and copy the array, which is time consuming, yet we don't
- * have to worry about using too much memory. I hope to be able to
- * nuke the realloc() at the end of this function eventually.
- */
- dest.rects.resize(qMax(reg1->numRects,reg2->numRects) * 2);
-
- /*
- * Initialize ybot and ytop.
- * In the upcoming loop, ybot and ytop serve different functions depending
- * on whether the band being handled is an overlapping or non-overlapping
- * band.
- * In the case of a non-overlapping band (only one of the regions
- * has points in the band), ybot is the bottom of the most recent
- * intersection and thus clips the top of the rectangles in that band.
- * ytop is the top of the next intersection between the two regions and
- * serves to clip the bottom of the rectangles in the current band.
- * For an overlapping band (where the two regions intersect), ytop clips
- * the top of the rectangles of both regions and ybot clips the bottoms.
- */
- if (reg1->extents.top() < reg2->extents.top())
- ybot = reg1->extents.top() - 1;
- else
- ybot = reg2->extents.top() - 1;
-
- /*
- * prevBand serves to mark the start of the previous band so rectangles
- * can be coalesced into larger rectangles. qv. miCoalesce, above.
- * In the beginning, there is no previous band, so prevBand == curBand
- * (curBand is set later on, of course, but the first band will always
- * start at index 0). prevBand and curBand must be indices because of
- * the possible expansion, and resultant moving, of the new region's
- * array of rectangles.
- */
- prevBand = 0;
-
- do {
- curBand = dest.numRects;
-
- /*
- * This algorithm proceeds one source-band (as opposed to a
- * destination band, which is determined by where the two regions
- * intersect) at a time. r1BandEnd and r2BandEnd serve to mark the
- * rectangle after the last one in the current band for their
- * respective regions.
- */
- r1BandEnd = r1;
- while (r1BandEnd != r1End && r1BandEnd->top() == r1->top())
- ++r1BandEnd;
-
- r2BandEnd = r2;
- while (r2BandEnd != r2End && r2BandEnd->top() == r2->top())
- ++r2BandEnd;
-
- /*
- * First handle the band that doesn't intersect, if any.
- *
- * Note that attention is restricted to one band in the
- * non-intersecting region at once, so if a region has n
- * bands between the current position and the next place it overlaps
- * the other, this entire loop will be passed through n times.
- */
- if (r1->top() < r2->top()) {
- top = qMax(r1->top(), ybot + 1);
- bot = qMin(r1->bottom(), r2->top() - 1);
-
- if (nonOverlap1Func != 0 && bot >= top)
- (*nonOverlap1Func)(dest, r1, r1BandEnd, top, bot);
- ytop = r2->top();
- } else if (r2->top() < r1->top()) {
- top = qMax(r2->top(), ybot + 1);
- bot = qMin(r2->bottom(), r1->top() - 1);
-
- if (nonOverlap2Func != 0 && bot >= top)
- (*nonOverlap2Func)(dest, r2, r2BandEnd, top, bot);
- ytop = r1->top();
- } else {
- ytop = r1->top();
- }
-
- /*
- * If any rectangles got added to the region, try and coalesce them
- * with rectangles from the previous band. Note we could just do
- * this test in miCoalesce, but some machines incur a not
- * inconsiderable cost for function calls, so...
- */
- if (dest.numRects != curBand)
- prevBand = miCoalesce(dest, prevBand, curBand);
-
- /*
- * Now see if we've hit an intersecting band. The two bands only
- * intersect if ybot >= ytop
- */
- ybot = qMin(r1->bottom(), r2->bottom());
- curBand = dest.numRects;
- if (ybot >= ytop)
- (*overlapFunc)(dest, r1, r1BandEnd, r2, r2BandEnd, ytop, ybot);
-
- if (dest.numRects != curBand)
- prevBand = miCoalesce(dest, prevBand, curBand);
-
- /*
- * If we've finished with a band (y2 == ybot) we skip forward
- * in the region to the next band.
- */
- if (r1->bottom() == ybot)
- r1 = r1BandEnd;
- if (r2->bottom() == ybot)
- r2 = r2BandEnd;
- } while (r1 != r1End && r2 != r2End);
-
- /*
- * Deal with whichever region still has rectangles left.
- */
- curBand = dest.numRects;
- if (r1 != r1End) {
- if (nonOverlap1Func != 0) {
- do {
- r1BandEnd = r1;
- while (r1BandEnd < r1End && r1BandEnd->top() == r1->top())
- ++r1BandEnd;
- (*nonOverlap1Func)(dest, r1, r1BandEnd, qMax(r1->top(), ybot + 1), r1->bottom());
- r1 = r1BandEnd;
- } while (r1 != r1End);
- }
- } else if ((r2 != r2End) && (nonOverlap2Func != 0)) {
- do {
- r2BandEnd = r2;
- while (r2BandEnd < r2End && r2BandEnd->top() == r2->top())
- ++r2BandEnd;
- (*nonOverlap2Func)(dest, r2, r2BandEnd, qMax(r2->top(), ybot + 1), r2->bottom());
- r2 = r2BandEnd;
- } while (r2 != r2End);
- }
-
- if (dest.numRects != curBand)
- (void)miCoalesce(dest, prevBand, curBand);
-
- /*
- * A bit of cleanup. To keep regions from growing without bound,
- * we shrink the array of rectangles to match the new number of
- * rectangles in the region.
- *
- * Only do this stuff if the number of rectangles allocated is more than
- * twice the number of rectangles in the region (a simple optimization).
- */
- if (qMax(4, dest.numRects) < (dest.rects.size() >> 1))
- dest.rects.resize(dest.numRects);
-}
-
-/*======================================================================
- * Region Union
- *====================================================================*/
-
-/*-
- *-----------------------------------------------------------------------
- * miUnionNonO --
- * Handle a non-overlapping band for the union operation. Just
- * Adds the rectangles into the region. Doesn't have to check for
- * subsumption or anything.
- *
- * Results:
- * None.
- *
- * Side Effects:
- * dest.numRects is incremented and the final rectangles overwritten
- * with the rectangles we're passed.
- *
- *-----------------------------------------------------------------------
- */
-
-static void miUnionNonO(register QRegionPrivate &dest, register const QRect *r, const QRect *rEnd,
- register int y1, register int y2)
-{
- register QRect *pNextRect;
-
- pNextRect = dest.rects.data() + dest.numRects;
-
- Q_ASSERT(y1 <= y2);
-
- while (r != rEnd) {
- Q_ASSERT(r->left() <= r->right());
- MEMCHECK(dest, pNextRect, dest.rects)
- pNextRect->setCoords(r->left(), y1, r->right(), y2);
- dest.numRects++;
- ++pNextRect;
- ++r;
- }
-}
-
-
-/*-
- *-----------------------------------------------------------------------
- * miUnionO --
- * Handle an overlapping band for the union operation. Picks the
- * left-most rectangle each time and merges it into the region.
- *
- * Results:
- * None.
- *
- * Side Effects:
- * Rectangles are overwritten in dest.rects and dest.numRects will
- * be changed.
- *
- *-----------------------------------------------------------------------
- */
-
-static void miUnionO(register QRegionPrivate &dest, register const QRect *r1, const QRect *r1End,
- register const QRect *r2, const QRect *r2End, register int y1, register int y2)
-{
- register QRect *pNextRect;
-
- pNextRect = dest.rects.data() + dest.numRects;
-
-#define MERGERECT(r) \
- if ((dest.numRects != 0) && \
- (pNextRect[-1].top() == y1) && \
- (pNextRect[-1].bottom() == y2) && \
- (pNextRect[-1].right() >= r->left()-1)) { \
- if (pNextRect[-1].right() < r->right()) { \
- pNextRect[-1].setRight(r->right()); \
- dest.updateInnerRect(pNextRect[-1]); \
- Q_ASSERT(pNextRect[-1].left() <= pNextRect[-1].right()); \
- } \
- } else { \
- MEMCHECK(dest, pNextRect, dest.rects) \
- pNextRect->setCoords(r->left(), y1, r->right(), y2); \
- dest.updateInnerRect(*pNextRect); \
- dest.numRects++; \
- pNextRect++; \
- } \
- r++;
-
- Q_ASSERT(y1 <= y2);
- while (r1 != r1End && r2 != r2End) {
- if (r1->left() < r2->left()) {
- MERGERECT(r1)
- } else {
- MERGERECT(r2)
- }
- }
-
- if (r1 != r1End) {
- do {
- MERGERECT(r1)
- } while (r1 != r1End);
- } else {
- while (r2 != r2End) {
- MERGERECT(r2)
- }
- }
-}
-
-static void UnionRegion(const QRegionPrivate *reg1, const QRegionPrivate *reg2, QRegionPrivate &dest)
-{
- Q_ASSERT(!isEmptyHelper(reg1) && !isEmptyHelper(reg2));
- Q_ASSERT(!reg1->contains(*reg2));
- Q_ASSERT(!reg2->contains(*reg1));
- Q_ASSERT(!EqualRegion(reg1, reg2));
- Q_ASSERT(!reg1->canAppend(reg2));
- Q_ASSERT(!reg2->canAppend(reg1));
-
- if (reg1->innerArea > reg2->innerArea) {
- dest.innerArea = reg1->innerArea;
- dest.innerRect = reg1->innerRect;
- } else {
- dest.innerArea = reg2->innerArea;
- dest.innerRect = reg2->innerRect;
- }
- miRegionOp(dest, reg1, reg2, miUnionO, miUnionNonO, miUnionNonO);
-
- dest.extents.setCoords(qMin(reg1->extents.left(), reg2->extents.left()),
- qMin(reg1->extents.top(), reg2->extents.top()),
- qMax(reg1->extents.right(), reg2->extents.right()),
- qMax(reg1->extents.bottom(), reg2->extents.bottom()));
-}
-
-/*======================================================================
- * Region Subtraction
- *====================================================================*/
-
-/*-
- *-----------------------------------------------------------------------
- * miSubtractNonO --
- * Deal with non-overlapping band for subtraction. Any parts from
- * region 2 we discard. Anything from region 1 we add to the region.
- *
- * Results:
- * None.
- *
- * Side Effects:
- * dest may be affected.
- *
- *-----------------------------------------------------------------------
- */
-
-static void miSubtractNonO1(register QRegionPrivate &dest, register const QRect *r,
- const QRect *rEnd, register int y1, register int y2)
-{
- register QRect *pNextRect;
-
- pNextRect = dest.rects.data() + dest.numRects;
-
- Q_ASSERT(y1<=y2);
-
- while (r != rEnd) {
- Q_ASSERT(r->left() <= r->right());
- MEMCHECK(dest, pNextRect, dest.rects)
- pNextRect->setCoords(r->left(), y1, r->right(), y2);
- ++dest.numRects;
- ++pNextRect;
- ++r;
- }
-}
-
-/*-
- *-----------------------------------------------------------------------
- * miSubtractO --
- * Overlapping band subtraction. x1 is the left-most point not yet
- * checked.
- *
- * Results:
- * None.
- *
- * Side Effects:
- * dest may have rectangles added to it.
- *
- *-----------------------------------------------------------------------
- */
-
-static void miSubtractO(register QRegionPrivate &dest, register const QRect *r1, const QRect *r1End,
- register const QRect *r2, const QRect *r2End, register int y1, register int y2)
-{
- register QRect *pNextRect;
- register int x1;
-
- x1 = r1->left();
-
- Q_ASSERT(y1 <= y2);
- pNextRect = dest.rects.data() + dest.numRects;
-
- while (r1 != r1End && r2 != r2End) {
- if (r2->right() < x1) {
- /*
- * Subtrahend missed the boat: go to next subtrahend.
- */
- ++r2;
- } else if (r2->left() <= x1) {
- /*
- * Subtrahend precedes minuend: nuke left edge of minuend.
- */
- x1 = r2->right() + 1;
- if (x1 > r1->right()) {
- /*
- * Minuend completely covered: advance to next minuend and
- * reset left fence to edge of new minuend.
- */
- ++r1;
- if (r1 != r1End)
- x1 = r1->left();
- } else {
- // Subtrahend now used up since it doesn't extend beyond minuend
- ++r2;
- }
- } else if (r2->left() <= r1->right()) {
- /*
- * Left part of subtrahend covers part of minuend: add uncovered
- * part of minuend to region and skip to next subtrahend.
- */
- Q_ASSERT(x1 < r2->left());
- MEMCHECK(dest, pNextRect, dest.rects)
- pNextRect->setCoords(x1, y1, r2->left() - 1, y2);
- ++dest.numRects;
- ++pNextRect;
-
- x1 = r2->right() + 1;
- if (x1 > r1->right()) {
- /*
- * Minuend used up: advance to new...
- */
- ++r1;
- if (r1 != r1End)
- x1 = r1->left();
- } else {
- // Subtrahend used up
- ++r2;
- }
- } else {
- /*
- * Minuend used up: add any remaining piece before advancing.
- */
- if (r1->right() >= x1) {
- MEMCHECK(dest, pNextRect, dest.rects)
- pNextRect->setCoords(x1, y1, r1->right(), y2);
- ++dest.numRects;
- ++pNextRect;
- }
- ++r1;
- if (r1 != r1End)
- x1 = r1->left();
- }
- }
-
- /*
- * Add remaining minuend rectangles to region.
- */
- while (r1 != r1End) {
- Q_ASSERT(x1 <= r1->right());
- MEMCHECK(dest, pNextRect, dest.rects)
- pNextRect->setCoords(x1, y1, r1->right(), y2);
- ++dest.numRects;
- ++pNextRect;
-
- ++r1;
- if (r1 != r1End)
- x1 = r1->left();
- }
-}
-
-/*-
- *-----------------------------------------------------------------------
- * miSubtract --
- * Subtract regS from regM and leave the result in regD.
- * S stands for subtrahend, M for minuend and D for difference.
- *
- * Side Effects:
- * regD is overwritten.
- *
- *-----------------------------------------------------------------------
- */
-
-static void SubtractRegion(QRegionPrivate *regM, QRegionPrivate *regS,
- register QRegionPrivate &dest)
-{
- Q_ASSERT(!isEmptyHelper(regM));
- Q_ASSERT(!isEmptyHelper(regS));
- Q_ASSERT(EXTENTCHECK(&regM->extents, &regS->extents));
- Q_ASSERT(!regS->contains(*regM));
- Q_ASSERT(!EqualRegion(regM, regS));
-
- miRegionOp(dest, regM, regS, miSubtractO, miSubtractNonO1, 0);
-
- /*
- * Can't alter dest's extents before we call miRegionOp because
- * it might be one of the source regions and miRegionOp depends
- * on the extents of those regions being the unaltered. Besides, this
- * way there's no checking against rectangles that will be nuked
- * due to coalescing, so we have to examine fewer rectangles.
- */
- miSetExtents(dest);
-}
-
-static void XorRegion(QRegionPrivate *sra, QRegionPrivate *srb, QRegionPrivate &dest)
-{
- Q_ASSERT(!isEmptyHelper(sra) && !isEmptyHelper(srb));
- Q_ASSERT(EXTENTCHECK(&sra->extents, &srb->extents));
- Q_ASSERT(!EqualRegion(sra, srb));
-
- QRegionPrivate tra, trb;
-
- if (!srb->contains(*sra))
- SubtractRegion(sra, srb, tra);
- if (!sra->contains(*srb))
- SubtractRegion(srb, sra, trb);
-
- Q_ASSERT(isEmptyHelper(&trb) || !tra.contains(trb));
- Q_ASSERT(isEmptyHelper(&tra) || !trb.contains(tra));
-
- if (isEmptyHelper(&tra)) {
- dest = trb;
- } else if (isEmptyHelper(&trb)) {
- dest = tra;
- } else if (tra.canAppend(&trb)) {
- dest = tra;
- dest.append(&trb);
- } else if (trb.canAppend(&tra)) {
- dest = trb;
- dest.append(&tra);
- } else {
- UnionRegion(&tra, &trb, dest);
- }
-}
-
-/*
- * Check to see if two regions are equal
- */
-static bool EqualRegion(const QRegionPrivate *r1, const QRegionPrivate *r2)
-{
- if (r1->numRects != r2->numRects) {
- return false;
- } else if (r1->numRects == 0) {
- return true;
- } else if (r1->extents != r2->extents) {
- return false;
- } else if (r1->mode == QRegionPrivate::Single && r2->mode == QRegionPrivate::Single) {
- return r1->single == r2->single;
- } else {
- const QRect *rr1 = (r1->mode==QRegionPrivate::Vector)?r1->rects.constData():&r1->single;
- const QRect *rr2 = (r2->mode==QRegionPrivate::Vector)?r2->rects.constData():&r2->single;
- for (int i = 0; i < r1->numRects; ++i, ++rr1, ++rr2) {
- if (*rr1 != *rr2)
- return false;
- }
- }
-
- return true;
-}
-
-static bool PointInRegion(QRegionPrivate *pRegion, int x, int y)
-{
- int i;
-
- if (pRegion->mode == QRegionPrivate::Single)
- return pRegion->single.contains(x, y);
- if (isEmptyHelper(pRegion))
- return false;
- if (!pRegion->extents.contains(x, y))
- return false;
- if (pRegion->innerRect.contains(x, y))
- return true;
- for (i = 0; i < pRegion->numRects; ++i) {
- if (pRegion->rects[i].contains(x, y))
- return true;
- }
- return false;
-}
-
-static bool RectInRegion(register QRegionPrivate *region, int rx, int ry, uint rwidth, uint rheight)
-{
- register const QRect *pbox;
- register const QRect *pboxEnd;
- QRect rect(rx, ry, rwidth, rheight);
- register QRect *prect = &rect;
- int partIn, partOut;
-
- if (!region || region->numRects == 0 || !EXTENTCHECK(&region->extents, prect))
- return RectangleOut;
-
- partOut = false;
- partIn = false;
-
- /* can stop when both partOut and partIn are true, or we reach prect->y2 */
- for (pbox = (region->mode==QRegionPrivate::Vector)?region->rects.constData():&region->single, pboxEnd = pbox + region->numRects;
- pbox < pboxEnd; ++pbox) {
- if (pbox->bottom() < ry)
- continue;
-
- if (pbox->top() > ry) {
- partOut = true;
- if (partIn || pbox->top() > prect->bottom())
- break;
- ry = pbox->top();
- }
-
- if (pbox->right() < rx)
- continue; /* not far enough over yet */
-
- if (pbox->left() > rx) {
- partOut = true; /* missed part of rectangle to left */
- if (partIn)
- break;
- }
-
- if (pbox->left() <= prect->right()) {
- partIn = true; /* definitely overlap */
- if (partOut)
- break;
- }
-
- if (pbox->right() >= prect->right()) {
- ry = pbox->bottom() + 1; /* finished with this band */
- if (ry > prect->bottom())
- break;
- rx = prect->left(); /* reset x out to left again */
- } else {
- /*
- * Because boxes in a band are maximal width, if the first box
- * to overlap the rectangle doesn't completely cover it in that
- * band, the rectangle must be partially out, since some of it
- * will be uncovered in that band. partIn will have been set true
- * by now...
- */
- break;
- }
- }
- return partIn ? ((ry <= prect->bottom()) ? RectanglePart : RectangleIn) : RectangleOut;
-}
-// END OF Region.c extract
-// START OF poly.h extract
-/* $XConsortium: poly.h,v 1.4 94/04/17 20:22:19 rws Exp $ */
-/************************************************************************
-
-Copyright (c) 1987 X Consortium
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of the X Consortium shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from the X Consortium.
-
-
-Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
-
- All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the name of Digital not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.
-
-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
-************************************************************************/
-
-/*
- * This file contains a few macros to help track
- * the edge of a filled object. The object is assumed
- * to be filled in scanline order, and thus the
- * algorithm used is an extension of Bresenham's line
- * drawing algorithm which assumes that y is always the
- * major axis.
- * Since these pieces of code are the same for any filled shape,
- * it is more convenient to gather the library in one
- * place, but since these pieces of code are also in
- * the inner loops of output primitives, procedure call
- * overhead is out of the question.
- * See the author for a derivation if needed.
- */
-
-
-/*
- * In scan converting polygons, we want to choose those pixels
- * which are inside the polygon. Thus, we add .5 to the starting
- * x coordinate for both left and right edges. Now we choose the
- * first pixel which is inside the pgon for the left edge and the
- * first pixel which is outside the pgon for the right edge.
- * Draw the left pixel, but not the right.
- *
- * How to add .5 to the starting x coordinate:
- * If the edge is moving to the right, then subtract dy from the
- * error term from the general form of the algorithm.
- * If the edge is moving to the left, then add dy to the error term.
- *
- * The reason for the difference between edges moving to the left
- * and edges moving to the right is simple: If an edge is moving
- * to the right, then we want the algorithm to flip immediately.
- * If it is moving to the left, then we don't want it to flip until
- * we traverse an entire pixel.
- */
-#define BRESINITPGON(dy, x1, x2, xStart, d, m, m1, incr1, incr2) { \
- int dx; /* local storage */ \
-\
- /* \
- * if the edge is horizontal, then it is ignored \
- * and assumed not to be processed. Otherwise, do this stuff. \
- */ \
- if ((dy) != 0) { \
- xStart = (x1); \
- dx = (x2) - xStart; \
- if (dx < 0) { \
- m = dx / (dy); \
- m1 = m - 1; \
- incr1 = -2 * dx + 2 * (dy) * m1; \
- incr2 = -2 * dx + 2 * (dy) * m; \
- d = 2 * m * (dy) - 2 * dx - 2 * (dy); \
- } else { \
- m = dx / (dy); \
- m1 = m + 1; \
- incr1 = 2 * dx - 2 * (dy) * m1; \
- incr2 = 2 * dx - 2 * (dy) * m; \
- d = -2 * m * (dy) + 2 * dx; \
- } \
- } \
-}
-
-#define BRESINCRPGON(d, minval, m, m1, incr1, incr2) { \
- if (m1 > 0) { \
- if (d > 0) { \
- minval += m1; \
- d += incr1; \
- } \
- else { \
- minval += m; \
- d += incr2; \
- } \
- } else {\
- if (d >= 0) { \
- minval += m1; \
- d += incr1; \
- } \
- else { \
- minval += m; \
- d += incr2; \
- } \
- } \
-}
-
-
-/*
- * This structure contains all of the information needed
- * to run the bresenham algorithm.
- * The variables may be hardcoded into the declarations
- * instead of using this structure to make use of
- * register declarations.
- */
-typedef struct {
- int minor_axis; /* minor axis */
- int d; /* decision variable */
- int m, m1; /* slope and slope+1 */
- int incr1, incr2; /* error increments */
-} BRESINFO;
-
-
-#define BRESINITPGONSTRUCT(dmaj, min1, min2, bres) \
- BRESINITPGON(dmaj, min1, min2, bres.minor_axis, bres.d, \
- bres.m, bres.m1, bres.incr1, bres.incr2)
-
-#define BRESINCRPGONSTRUCT(bres) \
- BRESINCRPGON(bres.d, bres.minor_axis, bres.m, bres.m1, bres.incr1, bres.incr2)
-
-
-
-/*
- * These are the data structures needed to scan
- * convert regions. Two different scan conversion
- * methods are available -- the even-odd method, and
- * the winding number method.
- * The even-odd rule states that a point is inside
- * the polygon if a ray drawn from that point in any
- * direction will pass through an odd number of
- * path segments.
- * By the winding number rule, a point is decided
- * to be inside the polygon if a ray drawn from that
- * point in any direction passes through a different
- * number of clockwise and counter-clockwise path
- * segments.
- *
- * These data structures are adapted somewhat from
- * the algorithm in (Foley/Van Dam) for scan converting
- * polygons.
- * The basic algorithm is to start at the top (smallest y)
- * of the polygon, stepping down to the bottom of
- * the polygon by incrementing the y coordinate. We
- * keep a list of edges which the current scanline crosses,
- * sorted by x. This list is called the Active Edge Table (AET)
- * As we change the y-coordinate, we update each entry in
- * in the active edge table to reflect the edges new xcoord.
- * This list must be sorted at each scanline in case
- * two edges intersect.
- * We also keep a data structure known as the Edge Table (ET),
- * which keeps track of all the edges which the current
- * scanline has not yet reached. The ET is basically a
- * list of ScanLineList structures containing a list of
- * edges which are entered at a given scanline. There is one
- * ScanLineList per scanline at which an edge is entered.
- * When we enter a new edge, we move it from the ET to the AET.
- *
- * From the AET, we can implement the even-odd rule as in
- * (Foley/Van Dam).
- * The winding number rule is a little trickier. We also
- * keep the EdgeTableEntries in the AET linked by the
- * nextWETE (winding EdgeTableEntry) link. This allows
- * the edges to be linked just as before for updating
- * purposes, but only uses the edges linked by the nextWETE
- * link as edges representing spans of the polygon to
- * drawn (as with the even-odd rule).
- */
-
-/*
- * for the winding number rule
- */
-#define CLOCKWISE 1
-#define COUNTERCLOCKWISE -1
-
-typedef struct _EdgeTableEntry {
- int ymax; /* ycoord at which we exit this edge. */
- BRESINFO bres; /* Bresenham info to run the edge */
- struct _EdgeTableEntry *next; /* next in the list */
- struct _EdgeTableEntry *back; /* for insertion sort */
- struct _EdgeTableEntry *nextWETE; /* for winding num rule */
- int ClockWise; /* flag for winding number rule */
-} EdgeTableEntry;
-
-
-typedef struct _ScanLineList{
- int scanline; /* the scanline represented */
- EdgeTableEntry *edgelist; /* header node */
- struct _ScanLineList *next; /* next in the list */
-} ScanLineList;
-
-
-typedef struct {
- int ymax; /* ymax for the polygon */
- int ymin; /* ymin for the polygon */
- ScanLineList scanlines; /* header node */
-} EdgeTable;
-
-
-/*
- * Here is a struct to help with storage allocation
- * so we can allocate a big chunk at a time, and then take
- * pieces from this heap when we need to.
- */
-#define SLLSPERBLOCK 25
-
-typedef struct _ScanLineListBlock {
- ScanLineList SLLs[SLLSPERBLOCK];
- struct _ScanLineListBlock *next;
-} ScanLineListBlock;
-
-
-
-/*
- *
- * a few macros for the inner loops of the fill code where
- * performance considerations don't allow a procedure call.
- *
- * Evaluate the given edge at the given scanline.
- * If the edge has expired, then we leave it and fix up
- * the active edge table; otherwise, we increment the
- * x value to be ready for the next scanline.
- * The winding number rule is in effect, so we must notify
- * the caller when the edge has been removed so he
- * can reorder the Winding Active Edge Table.
- */
-#define EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET) { \
- if (pAET->ymax == y) { /* leaving this edge */ \
- pPrevAET->next = pAET->next; \
- pAET = pPrevAET->next; \
- fixWAET = 1; \
- if (pAET) \
- pAET->back = pPrevAET; \
- } \
- else { \
- BRESINCRPGONSTRUCT(pAET->bres) \
- pPrevAET = pAET; \
- pAET = pAET->next; \
- } \
-}
-
-
-/*
- * Evaluate the given edge at the given scanline.
- * If the edge has expired, then we leave it and fix up
- * the active edge table; otherwise, we increment the
- * x value to be ready for the next scanline.
- * The even-odd rule is in effect.
- */
-#define EVALUATEEDGEEVENODD(pAET, pPrevAET, y) { \
- if (pAET->ymax == y) { /* leaving this edge */ \
- pPrevAET->next = pAET->next; \
- pAET = pPrevAET->next; \
- if (pAET) \
- pAET->back = pPrevAET; \
- } \
- else { \
- BRESINCRPGONSTRUCT(pAET->bres) \
- pPrevAET = pAET; \
- pAET = pAET->next; \
- } \
-}
-// END OF poly.h extract
-// START OF PolyReg.c extract
-/* $XConsortium: PolyReg.c,v 11.23 94/11/17 21:59:37 converse Exp $ */
-/************************************************************************
-
-Copyright (c) 1987 X Consortium
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of the X Consortium shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from the X Consortium.
-
-
-Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
-
- All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the name of Digital not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.
-
-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
-************************************************************************/
-/* $XFree86: xc/lib/X11/PolyReg.c,v 1.1.1.2.8.2 1998/10/04 15:22:49 hohndel Exp $ */
-
-#define LARGE_COORDINATE 1000000
-#define SMALL_COORDINATE -LARGE_COORDINATE
-
-/*
- * InsertEdgeInET
- *
- * Insert the given edge into the edge table.
- * First we must find the correct bucket in the
- * Edge table, then find the right slot in the
- * bucket. Finally, we can insert it.
- *
- */
-static void InsertEdgeInET(EdgeTable *ET, EdgeTableEntry *ETE, int scanline,
- ScanLineListBlock **SLLBlock, int *iSLLBlock)
-{
- register EdgeTableEntry *start, *prev;
- register ScanLineList *pSLL, *pPrevSLL;
- ScanLineListBlock *tmpSLLBlock;
-
- /*
- * find the right bucket to put the edge into
- */
- pPrevSLL = &ET->scanlines;
- pSLL = pPrevSLL->next;
- while (pSLL && (pSLL->scanline < scanline)) {
- pPrevSLL = pSLL;
- pSLL = pSLL->next;
- }
-
- /*
- * reassign pSLL (pointer to ScanLineList) if necessary
- */
- if ((!pSLL) || (pSLL->scanline > scanline)) {
- if (*iSLLBlock > SLLSPERBLOCK-1)
- {
- tmpSLLBlock =
- (ScanLineListBlock *)malloc(sizeof(ScanLineListBlock));
- (*SLLBlock)->next = tmpSLLBlock;
- tmpSLLBlock->next = (ScanLineListBlock *)NULL;
- *SLLBlock = tmpSLLBlock;
- *iSLLBlock = 0;
- }
- pSLL = &((*SLLBlock)->SLLs[(*iSLLBlock)++]);
-
- pSLL->next = pPrevSLL->next;
- pSLL->edgelist = (EdgeTableEntry *)NULL;
- pPrevSLL->next = pSLL;
- }
- pSLL->scanline = scanline;
-
- /*
- * now insert the edge in the right bucket
- */
- prev = 0;
- start = pSLL->edgelist;
- while (start && (start->bres.minor_axis < ETE->bres.minor_axis)) {
- prev = start;
- start = start->next;
- }
- ETE->next = start;
-
- if (prev)
- prev->next = ETE;
- else
- pSLL->edgelist = ETE;
-}
-
-/*
- * CreateEdgeTable
- *
- * This routine creates the edge table for
- * scan converting polygons.
- * The Edge Table (ET) looks like:
- *
- * EdgeTable
- * --------
- * | ymax | ScanLineLists
- * |scanline|-->------------>-------------->...
- * -------- |scanline| |scanline|
- * |edgelist| |edgelist|
- * --------- ---------
- * | |
- * | |
- * V V
- * list of ETEs list of ETEs
- *
- * where ETE is an EdgeTableEntry data structure,
- * and there is one ScanLineList per scanline at
- * which an edge is initially entered.
- *
- */
-
-static void CreateETandAET(register int count, register const QPoint *pts,
- EdgeTable *ET, EdgeTableEntry *AET, register EdgeTableEntry *pETEs,
- ScanLineListBlock *pSLLBlock)
-{
- register const QPoint *top,
- *bottom,
- *PrevPt,
- *CurrPt;
- int iSLLBlock = 0;
- int dy;
-
- if (count < 2)
- return;
-
- /*
- * initialize the Active Edge Table
- */
- AET->next = 0;
- AET->back = 0;
- AET->nextWETE = 0;
- AET->bres.minor_axis = SMALL_COORDINATE;
-
- /*
- * initialize the Edge Table.
- */
- ET->scanlines.next = 0;
- ET->ymax = SMALL_COORDINATE;
- ET->ymin = LARGE_COORDINATE;
- pSLLBlock->next = 0;
-
- PrevPt = &pts[count - 1];
-
- /*
- * for each vertex in the array of points.
- * In this loop we are dealing with two vertices at
- * a time -- these make up one edge of the polygon.
- */
- while (count--) {
- CurrPt = pts++;
-
- /*
- * find out which point is above and which is below.
- */
- if (PrevPt->y() > CurrPt->y()) {
- bottom = PrevPt;
- top = CurrPt;
- pETEs->ClockWise = 0;
- } else {
- bottom = CurrPt;
- top = PrevPt;
- pETEs->ClockWise = 1;
- }
-
- /*
- * don't add horizontal edges to the Edge table.
- */
- if (bottom->y() != top->y()) {
- pETEs->ymax = bottom->y() - 1; /* -1 so we don't get last scanline */
-
- /*
- * initialize integer edge algorithm
- */
- dy = bottom->y() - top->y();
- BRESINITPGONSTRUCT(dy, top->x(), bottom->x(), pETEs->bres)
-
- InsertEdgeInET(ET, pETEs, top->y(), &pSLLBlock, &iSLLBlock);
-
- if (PrevPt->y() > ET->ymax)
- ET->ymax = PrevPt->y();
- if (PrevPt->y() < ET->ymin)
- ET->ymin = PrevPt->y();
- ++pETEs;
- }
-
- PrevPt = CurrPt;
- }
-}
-
-/*
- * loadAET
- *
- * This routine moves EdgeTableEntries from the
- * EdgeTable into the Active Edge Table,
- * leaving them sorted by smaller x coordinate.
- *
- */
-
-static void loadAET(register EdgeTableEntry *AET, register EdgeTableEntry *ETEs)
-{
- register EdgeTableEntry *pPrevAET;
- register EdgeTableEntry *tmp;
-
- pPrevAET = AET;
- AET = AET->next;
- while (ETEs) {
- while (AET && AET->bres.minor_axis < ETEs->bres.minor_axis) {
- pPrevAET = AET;
- AET = AET->next;
- }
- tmp = ETEs->next;
- ETEs->next = AET;
- if (AET)
- AET->back = ETEs;
- ETEs->back = pPrevAET;
- pPrevAET->next = ETEs;
- pPrevAET = ETEs;
-
- ETEs = tmp;
- }
-}
-
-/*
- * computeWAET
- *
- * This routine links the AET by the
- * nextWETE (winding EdgeTableEntry) link for
- * use by the winding number rule. The final
- * Active Edge Table (AET) might look something
- * like:
- *
- * AET
- * ---------- --------- ---------
- * |ymax | |ymax | |ymax |
- * | ... | |... | |... |
- * |next |->|next |->|next |->...
- * |nextWETE| |nextWETE| |nextWETE|
- * --------- --------- ^--------
- * | | |
- * V-------------------> V---> ...
- *
- */
-static void computeWAET(register EdgeTableEntry *AET)
-{
- register EdgeTableEntry *pWETE;
- register int inside = 1;
- register int isInside = 0;
-
- AET->nextWETE = 0;
- pWETE = AET;
- AET = AET->next;
- while (AET) {
- if (AET->ClockWise)
- ++isInside;
- else
- --isInside;
-
- if (!inside && !isInside || inside && isInside) {
- pWETE->nextWETE = AET;
- pWETE = AET;
- inside = !inside;
- }
- AET = AET->next;
- }
- pWETE->nextWETE = 0;
-}
-
-/*
- * InsertionSort
- *
- * Just a simple insertion sort using
- * pointers and back pointers to sort the Active
- * Edge Table.
- *
- */
-
-static int InsertionSort(register EdgeTableEntry *AET)
-{
- register EdgeTableEntry *pETEchase;
- register EdgeTableEntry *pETEinsert;
- register EdgeTableEntry *pETEchaseBackTMP;
- register int changed = 0;
-
- AET = AET->next;
- while (AET) {
- pETEinsert = AET;
- pETEchase = AET;
- while (pETEchase->back->bres.minor_axis > AET->bres.minor_axis)
- pETEchase = pETEchase->back;
-
- AET = AET->next;
- if (pETEchase != pETEinsert) {
- pETEchaseBackTMP = pETEchase->back;
- pETEinsert->back->next = AET;
- if (AET)
- AET->back = pETEinsert->back;
- pETEinsert->next = pETEchase;
- pETEchase->back->next = pETEinsert;
- pETEchase->back = pETEinsert;
- pETEinsert->back = pETEchaseBackTMP;
- changed = 1;
- }
- }
- return changed;
-}
-
-/*
- * Clean up our act.
- */
-static void FreeStorage(register ScanLineListBlock *pSLLBlock)
-{
- register ScanLineListBlock *tmpSLLBlock;
-
- while (pSLLBlock) {
- tmpSLLBlock = pSLLBlock->next;
- free(pSLLBlock);
- pSLLBlock = tmpSLLBlock;
- }
-}
-
-/*
- * Create an array of rectangles from a list of points.
- * If indeed these things (POINTS, RECTS) are the same,
- * then this proc is still needed, because it allocates
- * storage for the array, which was allocated on the
- * stack by the calling procedure.
- *
- */
-static void PtsToRegion(register int numFullPtBlocks, register int iCurPtBlock,
- POINTBLOCK *FirstPtBlock, QRegionPrivate *reg)
-{
- register QRect *rects;
- register QPoint *pts;
- register POINTBLOCK *CurPtBlock;
- register int i;
- register QRect *extents;
- register int numRects;
-
- extents = &reg->extents;
- numRects = ((numFullPtBlocks * NUMPTSTOBUFFER) + iCurPtBlock) >> 1;
-
- reg->rects.resize(numRects);
-
- CurPtBlock = FirstPtBlock;
- rects = reg->rects.data() - 1;
- numRects = 0;
- extents->setLeft(INT_MAX);
- extents->setRight(INT_MIN);
- reg->innerArea = -1;
-
- for (; numFullPtBlocks >= 0; --numFullPtBlocks) {
- /* the loop uses 2 points per iteration */
- i = NUMPTSTOBUFFER >> 1;
- if (!numFullPtBlocks)
- i = iCurPtBlock >> 1;
- if(i) {
- for (pts = CurPtBlock->pts; i--; pts += 2) {
- if (pts->x() == pts[1].x())
- continue;
- if (numRects && pts->x() == rects->left() && pts->y() == rects->bottom() + 1
- && pts[1].x() == rects->right()+1 && (numRects == 1 || rects[-1].top() != rects->top())
- && (i && pts[2].y() > pts[1].y())) {
- rects->setBottom(pts[1].y());
- reg->updateInnerRect(*rects);
- continue;
- }
- ++numRects;
- ++rects;
- rects->setCoords(pts->x(), pts->y(), pts[1].x() - 1, pts[1].y());
- if (rects->left() < extents->left())
- extents->setLeft(rects->left());
- if (rects->right() > extents->right())
- extents->setRight(rects->right());
- reg->updateInnerRect(*rects);
- }
- }
- CurPtBlock = CurPtBlock->next;
- }
-
- if (numRects) {
- extents->setTop(reg->rects[0].top());
- extents->setBottom(rects->bottom());
- } else {
- extents->setCoords(0, 0, 0, 0);
- }
- reg->numRects = numRects;
-}
-
-/*
- * polytoregion
- *
- * Scan converts a polygon by returning a run-length
- * encoding of the resultant bitmap -- the run-length
- * encoding is in the form of an array of rectangles.
- */
-static QRegionPrivate *PolygonRegion(const QPoint *Pts, int Count, int rule,
- QRegionPrivate *region)
- //Point *Pts; /* the pts */
- //int Count; /* number of pts */
- //int rule; /* winding rule */
-{
- register EdgeTableEntry *pAET; /* Active Edge Table */
- register int y; /* current scanline */
- register int iPts = 0; /* number of pts in buffer */
- register EdgeTableEntry *pWETE; /* Winding Edge Table Entry*/
- register ScanLineList *pSLL; /* current scanLineList */
- register QPoint *pts; /* output buffer */
- EdgeTableEntry *pPrevAET; /* ptr to previous AET */
- EdgeTable ET; /* header node for ET */
- EdgeTableEntry AET; /* header node for AET */
- EdgeTableEntry *pETEs; /* EdgeTableEntries pool */
- ScanLineListBlock SLLBlock; /* header for scanlinelist */
- int fixWAET = false;
- POINTBLOCK FirstPtBlock, *curPtBlock; /* PtBlock buffers */
- POINTBLOCK *tmpPtBlock;
- int numFullPtBlocks = 0;
-
- region->vector();
-
- /* special case a rectangle */
- if (((Count == 4) ||
- ((Count == 5) && (Pts[4].x() == Pts[0].x()) && (Pts[4].y() == Pts[0].y())))
- && (((Pts[0].y() == Pts[1].y()) && (Pts[1].x() == Pts[2].x()) && (Pts[2].y() == Pts[3].y())
- && (Pts[3].x() == Pts[0].x())) || ((Pts[0].x() == Pts[1].x())
- && (Pts[1].y() == Pts[2].y()) && (Pts[2].x() == Pts[3].x())
- && (Pts[3].y() == Pts[0].y())))) {
- int x = qMin(Pts[0].x(), Pts[2].x());
- region->extents.setLeft(x);
- int y = qMin(Pts[0].y(), Pts[2].y());
- region->extents.setTop(y);
- region->extents.setWidth(qMax(Pts[0].x(), Pts[2].x()) - x);
- region->extents.setHeight(qMax(Pts[0].y(), Pts[2].y()) - y);
- if ((region->extents.left() <= region->extents.right()) &&
- (region->extents.top() <= region->extents.bottom())) {
- region->numRects = 1;
- region->rects.resize(1);
- region->rects[0] = region->extents;
- region->innerRect = region->extents;
- region->innerArea = region->innerRect.width() * region->innerRect.height();
- }
- return region;
- }
-
- if (!(pETEs = static_cast<EdgeTableEntry *>(malloc(sizeof(EdgeTableEntry) * Count))))
- return 0;
-
- pts = FirstPtBlock.pts;
- CreateETandAET(Count, Pts, &ET, &AET, pETEs, &SLLBlock);
- pSLL = ET.scanlines.next;
- curPtBlock = &FirstPtBlock;
-
- if (rule == EvenOddRule) {
- /*
- * for each scanline
- */
- for (y = ET.ymin; y < ET.ymax; ++y) {
- /*
- * Add a new edge to the active edge table when we
- * get to the next edge.
- */
- if (pSLL && y == pSLL->scanline) {
- loadAET(&AET, pSLL->edgelist);
- pSLL = pSLL->next;
- }
- pPrevAET = &AET;
- pAET = AET.next;
-
- /*
- * for each active edge
- */
- while (pAET) {
- pts->setX(pAET->bres.minor_axis);
- pts->setY(y);
- ++pts;
- ++iPts;
-
- /*
- * send out the buffer
- */
- if (iPts == NUMPTSTOBUFFER) {
- tmpPtBlock = (POINTBLOCK *)malloc(sizeof(POINTBLOCK));
- curPtBlock->next = tmpPtBlock;
- curPtBlock = tmpPtBlock;
- pts = curPtBlock->pts;
- ++numFullPtBlocks;
- iPts = 0;
- }
- EVALUATEEDGEEVENODD(pAET, pPrevAET, y)
- }
- InsertionSort(&AET);
- }
- } else {
- /*
- * for each scanline
- */
- for (y = ET.ymin; y < ET.ymax; ++y) {
- /*
- * Add a new edge to the active edge table when we
- * get to the next edge.
- */
- if (pSLL && y == pSLL->scanline) {
- loadAET(&AET, pSLL->edgelist);
- computeWAET(&AET);
- pSLL = pSLL->next;
- }
- pPrevAET = &AET;
- pAET = AET.next;
- pWETE = pAET;
-
- /*
- * for each active edge
- */
- while (pAET) {
- /*
- * add to the buffer only those edges that
- * are in the Winding active edge table.
- */
- if (pWETE == pAET) {
- pts->setX(pAET->bres.minor_axis);
- pts->setY(y);
- ++pts;
- ++iPts;
-
- /*
- * send out the buffer
- */
- if (iPts == NUMPTSTOBUFFER) {
- tmpPtBlock = static_cast<POINTBLOCK *>(malloc(sizeof(POINTBLOCK)));
- curPtBlock->next = tmpPtBlock;
- curPtBlock = tmpPtBlock;
- pts = curPtBlock->pts;
- ++numFullPtBlocks;
- iPts = 0;
- }
- pWETE = pWETE->nextWETE;
- }
- EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET)
- }
-
- /*
- * recompute the winding active edge table if
- * we just resorted or have exited an edge.
- */
- if (InsertionSort(&AET) || fixWAET) {
- computeWAET(&AET);
- fixWAET = false;
- }
- }
- }
- FreeStorage(SLLBlock.next);
- PtsToRegion(numFullPtBlocks, iPts, &FirstPtBlock, region);
- for (curPtBlock = FirstPtBlock.next; --numFullPtBlocks >= 0;) {
- tmpPtBlock = curPtBlock->next;
- free(curPtBlock);
- curPtBlock = tmpPtBlock;
- }
- free(pETEs);
- return region;
-}
-// END OF PolyReg.c extract
-
-QRegionPrivate *qt_bitmapToRegion(const QBitmap& bitmap, QRegionPrivate *region)
-{
- region->vector();
-
- QImage image = bitmap.toImage();
-
- QRect xr;
-
-#define AddSpan \
- { \
- xr.setCoords(prev1, y, x-1, y); \
- UnionRectWithRegion(&xr, region, *region); \
- }
-
- const uchar zero = 0;
- bool little = image.format() == QImage::Format_MonoLSB;
-
- int x,
- y;
- for (y = 0; y < image.height(); ++y) {
- uchar *line = image.scanLine(y);
- int w = image.width();
- uchar all = zero;
- int prev1 = -1;
- for (x = 0; x < w;) {
- uchar byte = line[x / 8];
- if (x > w - 8 || byte!=all) {
- if (little) {
- for (int b = 8; b > 0 && x < w; --b) {
- if (!(byte & 0x01) == !all) {
- // More of the same
- } else {
- // A change.
- if (all!=zero) {
- AddSpan
- all = zero;
- } else {
- prev1 = x;
- all = ~zero;
- }
- }
- byte >>= 1;
- ++x;
- }
- } else {
- for (int b = 8; b > 0 && x < w; --b) {
- if (!(byte & 0x80) == !all) {
- // More of the same
- } else {
- // A change.
- if (all != zero) {
- AddSpan
- all = zero;
- } else {
- prev1 = x;
- all = ~zero;
- }
- }
- byte <<= 1;
- ++x;
- }
- }
- } else {
- x += 8;
- }
- }
- if (all != zero) {
- AddSpan
- }
- }
-#undef AddSpan
-
- return region;
-}
-
-/*
- Constructs an empty region.
-
- \sa isEmpty()
-*/
-
-QRegion::QRegion()
- : d(&shared_empty)
-{
- d->ref.ref();
-}
-
-/*
- \overload
-
- Create a region based on the rectange \a r with region type \a t.
-
- If the rectangle is invalid a null region will be created.
-
- \sa QRegion::RegionType
-*/
-
-QRegion::QRegion(const QRect &r, RegionType t)
-{
- if (r.isEmpty()) {
- d = &shared_empty;
- d->ref.ref();
- } else {
-// d = new QRegionData;
- QRegionPrivate *rp = 0;
- if (t == Rectangle) {
-// rp = new QRegionPrivate(r);
- rp = qt_allocRegion(r);
- } else if (t == Ellipse) {
- QPainterPath path;
- path.addEllipse(r.x(), r.y(), r.width(), r.height());
- QPolygon a = path.toSubpathPolygons().at(0).toPolygon();
- rp = qt_allocRegion();
-// rp = new QRegionPrivate;
- PolygonRegion(a.constData(), a.size(), EvenOddRule, rp);
- }
- d = rp;
- d->ref = 1;
-#if defined(Q_WS_X11)
- d->rgn = 0;
- d->xrectangles = 0;
-#elif defined(Q_WS_MAC)
- d->rgn = 0;
-#endif
- d->qt_rgn = rp;
- }
-}
-
-/*
- Constructs a polygon region from the point array \a a with the fill rule
- specified by \a fillRule.
-
- If \a fillRule is \l{Qt::WindingFill}, the polygon region is defined
- using the winding algorithm; if it is \l{Qt::OddEvenFill}, the odd-even fill
- algorithm is used.
-
- \warning This constructor can be used to create complex regions that will
- slow down painting when used.
-*/
-
-QRegion::QRegion(const QPolygon &a, Qt::FillRule fillRule)
-{
- if (a.count() > 2) {
- //d = new QRegionData;
- // QRegionPrivate *rp = new QRegionPrivate;
- QRegionPrivate *rp = qt_allocRegion();
- PolygonRegion(a.constData(), a.size(),
- fillRule == Qt::WindingFill ? WindingRule : EvenOddRule, rp);
- d = rp;
- d->ref = 1;
-#if defined(Q_WS_X11)
- d->rgn = 0;
- d->xrectangles = 0;
-#elif defined(Q_WS_MAC)
- d->rgn = 0;
-#endif
- d->qt_rgn = rp;
- } else {
- d = &shared_empty;
- d->ref.ref();
- }
-}
-
-
-/*
- Constructs a new region which is equal to region \a r.
-*/
-
-QRegion::QRegion(const QRegion &r)
-{
- d = r.d;
- d->ref.ref();
-}
-
-
-/*
- Constructs a region from the bitmap \a bm.
-
- The resulting region consists of the pixels in bitmap \a bm that
- are Qt::color1, as if each pixel was a 1 by 1 rectangle.
-
- This constructor may create complex regions that will slow down
- painting when used. Note that drawing masked pixmaps can be done
- much faster using QPixmap::setMask().
-*/
-QRegion::QRegion(const QBitmap &bm)
-{
- if (bm.isNull()) {
- d = &shared_empty;
- d->ref.ref();
- } else {
- // d = new QRegionData;
-// QRegionPrivate *rp = new QRegionPrivate;
- QRegionPrivate *rp = qt_allocRegion();
-
- qt_bitmapToRegion(bm, rp);
- d = rp;
- d->ref = 1;
-#if defined(Q_WS_X11)
- d->rgn = 0;
- d->xrectangles = 0;
-#elif defined(Q_WS_MAC)
- d->rgn = 0;
-#endif
- d->qt_rgn = rp;
- }
-}
-
-void QRegion::cleanUp(QRegion::QRegionData *x)
-{
- // delete x->qt_rgn;
-#if defined(Q_WS_X11)
- if (x->rgn)
- XDestroyRegion(x->rgn);
- if (x->xrectangles)
- free(x->xrectangles);
-#elif defined(Q_WS_MAC)
- if (x->rgn)
- qt_mac_dispose_rgn(x->rgn);
-#endif
- if(x->qt_rgn) {
-// delete x->qt_rgn;
- qt_freeRegion(x->qt_rgn);
- } else {
- delete x;
- }
-}
-
-/*
- Destroys the region.
-*/
-
-QRegion::~QRegion()
-{
- if (!d->ref.deref())
- cleanUp(d);
-}
-
-
-/*
- Assigns \a r to this region and returns a reference to the region.
-*/
-
-QRegion &QRegion::operator=(const QRegion &r)
-{
- r.d->ref.ref();
- if (!d->ref.deref())
- cleanUp(d);
- d = r.d;
- return *this;
-}
-
-
-/*
- \internal
-*/
-
-QRegion QRegion::copy() const
-{
- QRegion r;
- QRegionData *x = 0; // new QRegionData;
- QRegionPrivate *rp = 0;
- if (d->qt_rgn)
-// rp = new QRegionPrivate(*d->qt_rgn);
- rp = qt_allocRegion(*d->qt_rgn);
- else
- rp = qt_allocRegion();
- x = rp;
- x->qt_rgn = rp;
- x->ref = 1;
-#if defined(Q_WS_X11)
- x->rgn = 0;
- x->xrectangles = 0;
-#elif defined(Q_WS_MAC)
- x->rgn = 0;
-#endif
-
- if (!r.d->ref.deref())
- cleanUp(r.d);
- r.d = x;
- return r;
-}
-
-/*
- Returns true if the region is empty; otherwise returns false. An
- empty region is a region that contains no points.
-
- Example:
- \snippet doc/src/snippets/code/src.gui.painting.qregion_qws.cpp 0
-*/
-
-bool QRegion::isEmpty() const
-{
- return d == &shared_empty || d->qt_rgn->numRects == 0;
-}
-
-
-/*
- Returns true if the region contains the point \a p; otherwise
- returns false.
-*/
-
-bool QRegion::contains(const QPoint &p) const
-{
- return PointInRegion(d->qt_rgn, p.x(), p.y());
-}
-
-/*
- \overload
-
- Returns true if the region overlaps the rectangle \a r; otherwise
- returns false.
-*/
-
-bool QRegion::contains(const QRect &r) const
-{
- if(!d->qt_rgn)
- return false;
- if(d->qt_rgn->mode == QRegionPrivate::Single)
- return d->qt_rgn->single.contains(r);
-
- return RectInRegion(d->qt_rgn, r.left(), r.top(), r.width(), r.height()) != RectangleOut;
-}
-
-
-
-/*
- Translates (moves) the region \a dx along the X axis and \a dy
- along the Y axis.
-*/
-
-void QRegion::translate(int dx, int dy)
-{
- if ((dx == 0 && dy == 0) || isEmptyHelper(d->qt_rgn))
- return;
-
- detach();
- OffsetRegion(*d->qt_rgn, dx, dy);
-#if defined(Q_WS_X11)
- if (d->xrectangles) {
- free(d->xrectangles);
- d->xrectangles = 0;
- }
-#elif defined(Q_WS_MAC)
- if(d->rgn) {
- qt_mac_dispose_rgn(d->rgn);
- d->rgn = 0;
- }
-#endif
-}
-
-/*
- \fn QRegion QRegion::unite(const QRegion &r) const
- \obsolete
-
- Use united(\a r) instead.
-*/
-
-/*
- \fn QRegion QRegion::united(const QRegion &r) const
- \since 4.2
-
- Returns a region which is the union of this region and \a r.
-
- \img runion.png Region Union
-
- The figure shows the union of two elliptical regions.
-
- \sa intersected(), subtracted(), xored()
-*/
-
-QRegion QRegion::unite(const QRegion &r) const
-{
- if (isEmptyHelper(d->qt_rgn))
- return r;
- if (isEmptyHelper(r.d->qt_rgn))
- return *this;
-
- if (d->qt_rgn->contains(*r.d->qt_rgn)) {
- return *this;
- } else if (r.d->qt_rgn->contains(*d->qt_rgn)) {
- return r;
- } else if (d->qt_rgn->canAppend(r.d->qt_rgn)) {
- QRegion result(*this);
- result.detach();
- result.d->qt_rgn->append(r.d->qt_rgn);
- return result;
- } else if (r.d->qt_rgn->canAppend(d->qt_rgn)) {
- QRegion result(r);
- result.detach();
- result.d->qt_rgn->append(d->qt_rgn);
- return result;
- } else if (EqualRegion(d->qt_rgn, r.d->qt_rgn)) {
- return *this;
- } else {
- QRegion result;
- result.detach();
- UnionRegion(d->qt_rgn, r.d->qt_rgn, *result.d->qt_rgn);
- return result;
- }
-}
-
-QRegion& QRegion::operator+=(const QRegion &r)
-{
- if (isEmptyHelper(d->qt_rgn))
- return *this = r;
- if (isEmptyHelper(r.d->qt_rgn))
- return *this;
-
- if (d->qt_rgn->contains(*r.d->qt_rgn)) {
- return *this;
- } else if (r.d->qt_rgn->contains(*d->qt_rgn)) {
- return *this = r;
- } else if (d->qt_rgn->canAppend(r.d->qt_rgn)) {
- detach();
- d->qt_rgn->append(r.d->qt_rgn);
- return *this;
- } else if (d->qt_rgn->canPrepend(r.d->qt_rgn)) {
- detach();
- d->qt_rgn->prepend(r.d->qt_rgn);
- return *this;
- } else if (EqualRegion(d->qt_rgn, r.d->qt_rgn)) {
- return *this;
- }
-
- return *this = unite(r);
-}
-
-/*
- \fn QRegion QRegion::intersect(const QRegion &r) const
- \obsolete
-
- Use intersected(\a r) instead.
-*/
-
-/*
- \fn QRegion QRegion::intersected(const QRegion &r) const
- \since 4.2
-
- Returns a region which is the intersection of this region and \a r.
-
- \img rintersect.png Region Intersection
-
- The figure shows the intersection of two elliptical regions.
-*/
-
-QRegion QRegion::intersect(const QRegion &r) const
-{
- if (isEmptyHelper(d->qt_rgn) || isEmptyHelper(r.d->qt_rgn)
- || !EXTENTCHECK(&d->qt_rgn->extents, &r.d->qt_rgn->extents))
- return QRegion();
-
- /* this is fully contained in r */
- if (r.d->qt_rgn->contains(*d->qt_rgn))
- return *this;
-
- /* r is fully contained in this */
- if (d->qt_rgn->contains(*r.d->qt_rgn))
- return r;
-
- if(r.d->qt_rgn->mode == QRegionPrivate::Single &&
- d->qt_rgn->mode == QRegionPrivate::Single)
- return QRegion(r.d->qt_rgn->single.intersected(d->qt_rgn->single));
-#ifdef QT_GREENPHONE_OPT
- else if(r.d->qt_rgn->mode == QRegionPrivate::Single)
- return intersect(r.d->qt_rgn->single);
- else if(d->qt_rgn->mode == QRegionPrivate::Single)
- return r.intersect(d->qt_rgn->single);
-#endif
-
- QRegion result;
- result.detach();
- miRegionOp(*result.d->qt_rgn, d->qt_rgn, r.d->qt_rgn, miIntersectO, 0, 0);
-
- /*
- * Can't alter dest's extents before we call miRegionOp because
- * it might be one of the source regions and miRegionOp depends
- * on the extents of those regions being the same. Besides, this
- * way there's no checking against rectangles that will be nuked
- * due to coalescing, so we have to examine fewer rectangles.
- */
- miSetExtents(*result.d->qt_rgn);
- return result;
-}
-
-#ifdef QT_GREENPHONE_OPT
-/*
- \overload
- */
-QRegion QRegion::intersect(const QRect &r) const
-{
- // No intersection
- if(r.isEmpty() || isEmpty() || !EXTENTCHECK(&r, &d->qt_rgn->extents))
- return QRegion();
-
- // This is fully contained in r
- if(CONTAINSCHECK(r, d->qt_rgn->extents))
- return *this;
-
- // r is fully contained in this
- if(CONTAINSCHECK(d->qt_rgn->innerRect, r))
- return QRegion(r);
-
- if(d->qt_rgn->mode == QRegionPrivate::Single) {
- return QRegion(d->qt_rgn->single & r);
- } else {
- QRegion rv(*this);
- rv.detach();
-
- rv.d->qt_rgn->extents &= r;
- rv.d->qt_rgn->innerRect &= r;
- rv.d->qt_rgn->innerArea = rv.d->qt_rgn->innerRect.height() *
- rv.d->qt_rgn->innerRect.width();
-
- int numRects = 0;
- for(int ii = 0; ii < rv.d->qt_rgn->numRects; ++ii) {
- QRect result = rv.d->qt_rgn->rects[ii] & r;
- if(!result.isEmpty())
- rv.d->qt_rgn->rects[numRects++] = result;
- }
- rv.d->qt_rgn->numRects = numRects;
- return rv;
- }
-}
-
-/*
- \overload
- */
-const QRegion QRegion::operator&(const QRect &r) const
-{
- return intersect(r);
-}
-
-/*
- \overload
- */
-QRegion& QRegion::operator&=(const QRect &r)
-{
- if(isEmpty() || CONTAINSCHECK(r, d->qt_rgn->extents)) {
- // Do nothing
- } else if(r.isEmpty() || !EXTENTCHECK(&r, &d->qt_rgn->extents)) {
- *this = QRegion();
- } else if(CONTAINSCHECK(d->qt_rgn->innerRect, r)) {
- *this = QRegion(r);
- } else {
- detach();
- if(d->qt_rgn->mode == QRegionPrivate::Single) {
- QRect result = d->qt_rgn->single & r;
- d->qt_rgn->single = result;
- d->qt_rgn->extents = result;
- d->qt_rgn->innerRect = result;
- d->qt_rgn->innerArea = result.height() * result.width();
- } else {
- d->qt_rgn->extents &= r;
- d->qt_rgn->innerRect &= r;
- d->qt_rgn->innerArea = d->qt_rgn->innerRect.height() *
- d->qt_rgn->innerRect.width();
-
- int numRects = 0;
- for(int ii = 0; ii < d->qt_rgn->numRects; ++ii) {
- QRect result = d->qt_rgn->rects[ii] & r;
- if(!result.isEmpty())
- d->qt_rgn->rects[numRects++] = result;
- }
- d->qt_rgn->numRects = numRects;
- }
- }
- return *this;
-}
-#endif
-
-/*
- \fn QRegion QRegion::subtract(const QRegion &r) const
- \obsolete
-
- Use subtracted(\a r) instead.
-*/
-
-/*
- \fn QRegion QRegion::subtracted(const QRegion &r) const
- \since 4.2
-
- Returns a region which is \a r subtracted from this region.
-
- \img rsubtract.png Region Subtraction
-
- The figure shows the result when the ellipse on the right is
- subtracted from the ellipse on the left (\c {left - right}).
-
- \sa intersected(), united(), xored()
-*/
-
-QRegion QRegion::subtract(const QRegion &r) const
-{
- if (isEmptyHelper(d->qt_rgn) || isEmptyHelper(r.d->qt_rgn))
- return *this;
- if (r.d->qt_rgn->contains(*d->qt_rgn))
- return QRegion();
- if (!EXTENTCHECK(&d->qt_rgn->extents, &r.d->qt_rgn->extents))
- return *this;
- if (EqualRegion(d->qt_rgn, r.d->qt_rgn))
- return QRegion();
-
- QRegion result;
- result.detach();
- SubtractRegion(d->qt_rgn, r.d->qt_rgn, *result.d->qt_rgn);
- return result;
-}
-
-/*
- \fn QRegion QRegion::eor(const QRegion &r) const
- \obsolete
-
- Use xored(\a r) instead.
-*/
-
-/*
- \fn QRegion QRegion::xored(const QRegion &r) const
- \since 4.2
-
- Returns a region which is the exclusive or (XOR) of this region
- and \a r.
-
- \img rxor.png Region XORed
-
- The figure shows the exclusive or of two elliptical regions.
-
- \sa intersected(), united(), subtracted()
-*/
-
-QRegion QRegion::eor(const QRegion &r) const
-{
- if (isEmptyHelper(d->qt_rgn)) {
- return r;
- } else if (isEmptyHelper(r.d->qt_rgn)) {
- return *this;
- } else if (!EXTENTCHECK(&d->qt_rgn->extents, &r.d->qt_rgn->extents)) {
- return (*this + r);
- } else if (EqualRegion(d->qt_rgn, r.d->qt_rgn)) {
- return QRegion();
- } else {
- QRegion result;
- result.detach();
- XorRegion(d->qt_rgn, r.d->qt_rgn, *result.d->qt_rgn);
- return result;
- }
-}
-
-/*
- Returns the bounding rectangle of this region. An empty region
- gives a rectangle that is QRect::isNull().
-*/
-
-QRect QRegion::boundingRect() const
-{
- if (isEmpty())
- return QRect();
- return d->qt_rgn->extents;
-}
-
-/* \internal
- Returns true if \a rect is guaranteed to be fully contained in \a region.
- A false return value does not guarantee the opposite.
-*/
-bool qt_region_strictContains(const QRegion &region, const QRect &rect)
-{
- if (isEmptyHelper(region.d->qt_rgn) || !rect.isValid())
- return false;
-
-#if 0 // TEST_INNERRECT
- static bool guard = false;
- if (guard)
- return QRect();
- guard = true;
- QRegion inner = region.d->qt_rgn->innerRect;
- Q_ASSERT((inner - region).isEmpty());
- guard = false;
-
- int maxArea = 0;
- for (int i = 0; i < region.d->qt_rgn->numRects; ++i) {
- const QRect r = region.d->qt_rgn->rects.at(i);
- if (r.width() * r.height() > maxArea)
- maxArea = r.width() * r.height();
- }
-
- if (maxArea > region.d->qt_rgn->innerArea) {
- qDebug() << "not largest rectangle" << region << region.d->qt_rgn->innerRect;
- }
- Q_ASSERT(maxArea <= region.d->qt_rgn->innerArea);
-#endif
-
- const QRect r1 = region.d->qt_rgn->innerRect;
- return (rect.left() >= r1.left() && rect.right() <= r1.right()
- && rect.top() >= r1.top() && rect.bottom() <= r1.bottom());
-}
-
-/*
- Returns an array of non-overlapping rectangles that make up the
- region.
-
- The union of all the rectangles is equal to the original region.
-*/
-QVector<QRect> QRegion::rects() const
-{
- if (d->qt_rgn) {
- d->qt_rgn->vector();
- d->qt_rgn->rects.resize(d->qt_rgn->numRects);
- return d->qt_rgn->rects;
- } else {
- return QVector<QRect>();
- }
-}
-
-/*
- \fn void QRegion::setRects(const QRect *rects, int number)
-
- Sets the region using the array of rectangles specified by \a rects and
- \a number.
- The rectangles \e must be optimally Y-X sorted and follow these restrictions:
-
- \list
- \o The rectangles must not intersect.
- \o All rectangles with a given top coordinate must have the same height.
- \o No two rectangles may abut horizontally (they should be combined
- into a single wider rectangle in that case).
- \o The rectangles must be sorted in ascending order, with Y as the major
- sort key and X as the minor sort key.
- \endlist
- \omit
- Only some platforms have these restrictions (Qt for Embedded Linux, X11 and Mac OS X).
- \endomit
-*/
-void QRegion::setRects(const QRect *rects, int num)
-{
- *this = QRegion();
- if (!rects || num == 0 || (num == 1 && rects->isEmpty()))
- return;
-
- detach();
-
- if(num == 1) {
- d->qt_rgn->single = *rects;
- d->qt_rgn->mode = QRegionPrivate::Single;
- d->qt_rgn->numRects = num;
- d->qt_rgn->extents = *rects;
- d->qt_rgn->innerRect = *rects;
- } else {
- d->qt_rgn->mode = QRegionPrivate::Vector;
- d->qt_rgn->rects.resize(num);
- d->qt_rgn->numRects = num;
- int left = INT_MAX,
- right = INT_MIN,
- top = INT_MAX,
- bottom = INT_MIN;
- for (int i = 0; i < num; ++i) {
- const QRect &rect = rects[i];
- d->qt_rgn->rects[i] = rect;
- left = qMin(rect.left(), left);
- right = qMax(rect.right(), right);
- top = qMin(rect.top(), top);
- bottom = qMax(rect.bottom(), bottom);
- d->qt_rgn->updateInnerRect(rect);
- }
- d->qt_rgn->extents = QRect(QPoint(left, top), QPoint(right, bottom));
- }
-}
-
-/*
- Returns true if the region is equal to \a r; otherwise returns
- false.
-*/
-
-bool QRegion::operator==(const QRegion &r) const
-{
- if (!d->qt_rgn || !r.d->qt_rgn)
- return r.d->qt_rgn == d->qt_rgn;
-
- if (d == r.d)
- return true;
- else
- return EqualRegion(d->qt_rgn, r.d->qt_rgn);
-}
-
-#ifdef QT_GREENPHONE_OPT
-bool QRegion::isRect() const
-{
- return d->qt_rgn && d->qt_rgn->mode == QRegionPrivate::Single;
-}
-#endif
-
-QT_END_NAMESPACE
diff --git a/src/gui/painting/qstylepainter.h b/src/gui/painting/qstylepainter.h
deleted file mode 100644
index be0ce991cb..0000000000
--- a/src/gui/painting/qstylepainter.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSTYLEPAINTER_H
-#define QSTYLEPAINTER_H
-
-#include <QtGui/qpainter.h>
-#include <QtGui/qstyle.h>
-#include <QtGui/qwidget.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QStylePainter : public QPainter
-{
-public:
- inline QStylePainter() : QPainter(), widget(0), wstyle(0) {}
- inline explicit QStylePainter(QWidget *w) { begin(w, w); }
- inline QStylePainter(QPaintDevice *pd, QWidget *w) { begin(pd, w); }
- inline bool begin(QWidget *w) { return begin(w, w); }
- inline bool begin(QPaintDevice *pd, QWidget *w) {
- Q_ASSERT_X(w, "QStylePainter::QStylePainter", "Widget must be non-zero");
- widget = w;
- wstyle = w->style();
- return QPainter::begin(pd);
- };
- inline void drawPrimitive(QStyle::PrimitiveElement pe, const QStyleOption &opt);
- inline void drawControl(QStyle::ControlElement ce, const QStyleOption &opt);
- inline void drawComplexControl(QStyle::ComplexControl cc, const QStyleOptionComplex &opt);
- inline void drawItemText(const QRect &r, int flags, const QPalette &pal, bool enabled,
- const QString &text, QPalette::ColorRole textRole = QPalette::NoRole);
- inline void drawItemPixmap(const QRect &r, int flags, const QPixmap &pixmap);
- inline QStyle *style() const { return wstyle; }
-
-private:
- QWidget *widget;
- QStyle *wstyle;
- Q_DISABLE_COPY(QStylePainter)
-};
-
-void QStylePainter::drawPrimitive(QStyle::PrimitiveElement pe, const QStyleOption &opt)
-{
- wstyle->drawPrimitive(pe, &opt, this, widget);
-}
-
-void QStylePainter::drawControl(QStyle::ControlElement ce, const QStyleOption &opt)
-{
- wstyle->drawControl(ce, &opt, this, widget);
-}
-
-void QStylePainter::drawComplexControl(QStyle::ComplexControl cc, const QStyleOptionComplex &opt)
-{
- wstyle->drawComplexControl(cc, &opt, this, widget);
-}
-
-void QStylePainter::drawItemText(const QRect &r, int flags, const QPalette &pal, bool enabled,
- const QString &text, QPalette::ColorRole textRole)
-{
- wstyle->drawItemText(this, r, flags, pal, enabled, text, textRole);
-}
-
-void QStylePainter::drawItemPixmap(const QRect &r, int flags, const QPixmap &pixmap)
-{
- wstyle->drawItemPixmap(this, r, flags, pixmap);
-}
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QSTYLEPAINTER_H
diff --git a/src/gui/painting/qtessellator.cpp b/src/gui/painting/qtessellator.cpp
deleted file mode 100644
index 94a5128d90..0000000000
--- a/src/gui/painting/qtessellator.cpp
+++ /dev/null
@@ -1,1498 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qtessellator_p.h"
-
-#include <QRect>
-#include <QList>
-#include <QDebug>
-
-#include <qmath.h>
-#include <limits.h>
-
-QT_BEGIN_NAMESPACE
-
-//#define DEBUG
-#ifdef DEBUG
-#define QDEBUG qDebug
-#else
-#define QDEBUG if (1){} else qDebug
-#endif
-
-static const bool emit_clever = true;
-static const bool mark_clever = false;
-
-enum VertexFlags {
- LineBeforeStarts = 0x1,
- LineBeforeEnds = 0x2,
- LineBeforeHorizontal = 0x4,
- LineAfterStarts = 0x8,
- LineAfterEnds = 0x10,
- LineAfterHorizontal = 0x20
-};
-
-
-
-class QTessellatorPrivate {
-public:
- struct Vertices;
-
- QTessellatorPrivate() {}
-
- QRectF collectAndSortVertices(const QPointF *points, int *maxActiveEdges);
- void cancelCoincidingEdges();
-
- void emitEdges(QTessellator *tessellator);
- void processIntersections();
- void removeEdges();
- void addEdges();
- void addIntersections();
-
- struct Vertex : public QTessellator::Vertex
- {
- int flags;
- };
-
- struct Intersection
- {
- Q27Dot5 y;
- int edge;
- bool operator <(const Intersection &other) const {
- if (y != other.y)
- return y < other.y;
- return edge < other.edge;
- }
- };
- struct IntersectionLink
- {
- int next;
- int prev;
- };
- typedef QMap<Intersection, IntersectionLink> Intersections;
-
- struct Edge {
- Edge(const Vertices &v, int _edge);
- int edge;
- const Vertex *v0;
- const Vertex *v1;
- Q27Dot5 y_left;
- Q27Dot5 y_right;
- signed int winding : 8;
- bool mark;
- bool free;
- bool intersect_left;
- bool intersect_right;
- bool isLeftOf(const Edge &other, Q27Dot5 y) const;
- Q27Dot5 positionAt(Q27Dot5 y) const;
- bool intersect(const Edge &other, Q27Dot5 *y, bool *det_positive) const;
-
- };
-
- class EdgeSorter
- {
- public:
- EdgeSorter(int _y) : y(_y) {}
- bool operator() (const Edge *e1, const Edge *e2);
- int y;
- };
-
- class Scanline {
- public:
- Scanline();
- ~Scanline();
-
- void init(int maxActiveEdges);
- void done();
-
- int findEdgePosition(Q27Dot5 x, Q27Dot5 y) const;
- int findEdgePosition(const Edge &e) const;
- int findEdge(int edge) const;
- void clearMarks();
-
- void swap(int p1, int p2) {
- Edge *tmp = edges[p1];
- edges[p1] = edges[p2];
- edges[p2] = tmp;
- }
- void insert(int pos, const Edge &e);
- void removeAt(int pos);
- void markEdges(int pos1, int pos2);
-
- void prepareLine();
- void lineDone();
-
- Edge **old;
- int old_size;
-
- Edge **edges;
- int size;
-
- private:
- Edge *edge_table;
- int first_unused;
- int max_edges;
- enum { default_alloc = 32 };
- };
-
- struct Vertices {
- enum { default_alloc = 128 };
- Vertices();
- ~Vertices();
- void init(int maxVertices);
- void done();
- Vertex *storage;
- Vertex **sorted;
-
- Vertex *operator[] (int i) { return storage + i; }
- const Vertex *operator[] (int i) const { return storage + i; }
- int position(const Vertex *v) const {
- return v - storage;
- }
- Vertex *next(Vertex *v) {
- ++v;
- if (v == storage + nPoints)
- v = storage;
- return v;
- }
- const Vertex *next(const Vertex *v) const {
- ++v;
- if (v == storage + nPoints)
- v = storage;
- return v;
- }
- int nextPos(const Vertex *v) const {
- ++v;
- if (v == storage + nPoints)
- return 0;
- return v - storage;
- }
- Vertex *prev(Vertex *v) {
- if (v == storage)
- v = storage + nPoints;
- --v;
- return v;
- }
- const Vertex *prev(const Vertex *v) const {
- if (v == storage)
- v = storage + nPoints;
- --v;
- return v;
- }
- int prevPos(const Vertex *v) const {
- if (v == storage)
- v = storage + nPoints;
- --v;
- return v - storage;
- }
- int nPoints;
- int allocated;
- };
- Vertices vertices;
- Intersections intersections;
- Scanline scanline;
- bool winding;
- Q27Dot5 y;
- int currentVertex;
-
-private:
- void addIntersection(const Edge *e1, const Edge *e2);
- bool edgeInChain(Intersection i, int edge);
-};
-
-
-QTessellatorPrivate::Edge::Edge(const QTessellatorPrivate::Vertices &vertices, int edge)
-{
- this->edge = edge;
- intersect_left = intersect_right = true;
- mark = false;
- free = false;
-
- v0 = vertices[edge];
- v1 = vertices.next(v0);
-
- Q_ASSERT(v0->y != v1->y);
-
- if (v0->y > v1->y) {
- qSwap(v0, v1);
- winding = -1;
- } else {
- winding = 1;
- }
- y_left = y_right = v0->y;
-}
-
-// This is basically the algorithm from graphics gems. The algorithm
-// is cubic in the coordinates at one place. Since we use 64bit
-// integers, this implies, that the allowed range for our coordinates
-// is limited to 21 bits. With 5 bits behind the decimal, this
-// implies that differences in coordaintes can range from 2*SHORT_MIN
-// to 2*SHORT_MAX, giving us efficiently a coordinate system from
-// SHORT_MIN to SHORT_MAX.
-//
-
-// WARNING: It's absolutely critical that the intersect() and isLeftOf() methods use
-// exactly the same algorithm to calulate yi. It's also important to be sure the algorithms
-// are transitive (ie. the conditions below are true for all input data):
-//
-// a.intersect(b) == b.intersect(a)
-// a.isLeftOf(b) != b.isLeftOf(a)
-//
-// This is tricky to get right, so be very careful when changing anything in here!
-
-static inline bool sameSign(qint64 a, qint64 b) {
- return (((qint64) ((quint64) a ^ (quint64) b)) >= 0 );
-}
-
-bool QTessellatorPrivate::Edge::intersect(const Edge &other, Q27Dot5 *y, bool *det_positive) const
-{
- qint64 a1 = v1->y - v0->y;
- qint64 b1 = v0->x - v1->x;
-
- qint64 a2 = other.v1->y - other.v0->y;
- qint64 b2 = other.v0->x - other.v1->x;
-
- qint64 det = a1 * b2 - a2 * b1;
- if (det == 0)
- return false;
-
- qint64 c1 = qint64(v1->x) * v0->y - qint64(v0->x) * v1->y;
-
- qint64 r3 = a1 * other.v0->x + b1 * other.v0->y + c1;
- qint64 r4 = a1 * other.v1->x + b1 * other.v1->y + c1;
-
- // Check signs of r3 and r4. If both point 3 and point 4 lie on
- // same side of line 1, the line segments do not intersect.
- QDEBUG() << " " << r3 << r4;
- if (r3 != 0 && r4 != 0 && sameSign( r3, r4 ))
- return false;
-
- qint64 c2 = qint64(other.v1->x) * other.v0->y - qint64(other.v0->x) * other.v1->y;
-
- qint64 r1 = a2 * v0->x + b2 * v0->y + c2;
- qint64 r2 = a2 * v1->x + b2 * v1->y + c2;
-
- // Check signs of r1 and r2. If both point 1 and point 2 lie
- // on same side of second line segment, the line segments do not intersect.
- QDEBUG() << " " << r1 << r2;
- if (r1 != 0 && r2 != 0 && sameSign( r1, r2 ))
- return false;
-
- // The det/2 is to get rounding instead of truncating. It
- // is added or subtracted to the numerator, depending upon the
- // sign of the numerator.
- qint64 offset = det < 0 ? -det : det;
- offset >>= 1;
-
- qint64 num = a2 * c1 - a1 * c2;
- *y = ( num < 0 ? num - offset : num + offset ) / det;
-
- *det_positive = (det > 0);
-
- return true;
-}
-
-#undef SAME_SIGNS
-
-bool QTessellatorPrivate::Edge::isLeftOf(const Edge &other, Q27Dot5 y) const
-{
-// QDEBUG() << "isLeftOf" << edge << other.edge << y;
- qint64 a1 = v1->y - v0->y;
- qint64 b1 = v0->x - v1->x;
- qint64 a2 = other.v1->y - other.v0->y;
- qint64 b2 = other.v0->x - other.v1->x;
-
- qint64 c2 = qint64(other.v1->x) * other.v0->y - qint64(other.v0->x) * other.v1->y;
-
- qint64 det = a1 * b2 - a2 * b1;
- if (det == 0) {
- // lines are parallel. Only need to check side of one point
- // fixed ordering for coincident edges
- qint64 r1 = a2 * v0->x + b2 * v0->y + c2;
-// QDEBUG() << "det = 0" << r1;
- if (r1 == 0)
- return edge < other.edge;
- return (r1 < 0);
- }
-
- // not parallel, need to find the y coordinate of the intersection point
- qint64 c1 = qint64(v1->x) * v0->y - qint64(v0->x) * v1->y;
-
- qint64 offset = det < 0 ? -det : det;
- offset >>= 1;
-
- qint64 num = a2 * c1 - a1 * c2;
- qint64 yi = ( num < 0 ? num - offset : num + offset ) / det;
-// QDEBUG() << " num=" << num << "offset=" << offset << "det=" << det;
-
- return ((yi > y) ^ (det < 0));
-}
-
-static inline bool compareVertex(const QTessellatorPrivate::Vertex *p1,
- const QTessellatorPrivate::Vertex *p2)
-{
- if (p1->y == p2->y) {
- if (p1->x == p2->x)
- return p1 < p2;
- return p1->x < p2->x;
- }
- return p1->y < p2->y;
-}
-
-Q27Dot5 QTessellatorPrivate::Edge::positionAt(Q27Dot5 y) const
-{
- if (y == v0->y)
- return v0->x;
- else if (y == v1->y)
- return v1->x;
-
- qint64 d = v1->x - v0->x;
- return (v0->x + d*(y - v0->y)/(v1->y-v0->y));
-}
-
-bool QTessellatorPrivate::EdgeSorter::operator() (const Edge *e1, const Edge *e2)
-{
- return e1->isLeftOf(*e2, y);
-}
-
-
-QTessellatorPrivate::Scanline::Scanline()
-{
- edges = 0;
- edge_table = 0;
- old = 0;
-}
-
-void QTessellatorPrivate::Scanline::init(int maxActiveEdges)
-{
- maxActiveEdges *= 2;
- if (!edges || maxActiveEdges > default_alloc) {
- max_edges = maxActiveEdges;
- int s = qMax(maxActiveEdges + 1, default_alloc + 1);
- edges = q_check_ptr((Edge **)realloc(edges, s*sizeof(Edge *)));
- edge_table = q_check_ptr((Edge *)realloc(edge_table, s*sizeof(Edge)));
- old = q_check_ptr((Edge **)realloc(old, s*sizeof(Edge *)));
- }
- size = 0;
- old_size = 0;
- first_unused = 0;
- for (int i = 0; i < maxActiveEdges; ++i)
- edge_table[i].edge = i+1;
- edge_table[maxActiveEdges].edge = -1;
-}
-
-void QTessellatorPrivate::Scanline::done()
-{
- if (max_edges > default_alloc) {
- free(edges);
- free(old);
- free(edge_table);
- edges = 0;
- old = 0;
- edge_table = 0;
- }
-}
-
-QTessellatorPrivate::Scanline::~Scanline()
-{
- free(edges);
- free(old);
- free(edge_table);
-}
-
-int QTessellatorPrivate::Scanline::findEdgePosition(Q27Dot5 x, Q27Dot5 y) const
-{
- int min = 0;
- int max = size - 1;
- while (min < max) {
- int pos = min + ((max - min + 1) >> 1);
- Q27Dot5 ax = edges[pos]->positionAt(y);
- if (ax > x) {
- max = pos - 1;
- } else {
- min = pos;
- }
- }
- return min;
-}
-
-int QTessellatorPrivate::Scanline::findEdgePosition(const Edge &e) const
-{
-// qDebug() << ">> findEdgePosition";
- int min = 0;
- int max = size;
- while (min < max) {
- int pos = min + ((max - min) >> 1);
-// qDebug() << " " << min << max << pos << edges[pos]->isLeftOf(e, e.y0);
- if (edges[pos]->isLeftOf(e, e.v0->y)) {
- min = pos + 1;
- } else {
- max = pos;
- }
- }
-// qDebug() << "<< findEdgePosition got" << min;
- return min;
-}
-
-int QTessellatorPrivate::Scanline::findEdge(int edge) const
-{
- for (int i = 0; i < size; ++i) {
- int item_edge = edges[i]->edge;
- if (item_edge == edge)
- return i;
- }
- //Q_ASSERT(false);
- return -1;
-}
-
-void QTessellatorPrivate::Scanline::clearMarks()
-{
- for (int i = 0; i < size; ++i) {
- edges[i]->mark = false;
- edges[i]->intersect_left = false;
- edges[i]->intersect_right = false;
- }
-}
-
-void QTessellatorPrivate::Scanline::prepareLine()
-{
- Edge **end = edges + size;
- Edge **e = edges;
- Edge **o = old;
- while (e < end) {
- *o = *e;
- ++o;
- ++e;
- }
- old_size = size;
-}
-
-void QTessellatorPrivate::Scanline::lineDone()
-{
- Edge **end = old + old_size;
- Edge **e = old;
- while (e < end) {
- if ((*e)->free) {
- (*e)->edge = first_unused;
- first_unused = (*e - edge_table);
- }
- ++e;
- }
-}
-
-void QTessellatorPrivate::Scanline::insert(int pos, const Edge &e)
-{
- Edge *edge = edge_table + first_unused;
- first_unused = edge->edge;
- Q_ASSERT(first_unused != -1);
- *edge = e;
- memmove(edges + pos + 1, edges + pos, (size - pos)*sizeof(Edge *));
- edges[pos] = edge;
- ++size;
-}
-
-void QTessellatorPrivate::Scanline::removeAt(int pos)
-{
- Edge *e = edges[pos];
- e->free = true;
- --size;
- memmove(edges + pos, edges + pos + 1, (size - pos)*sizeof(Edge *));
-}
-
-void QTessellatorPrivate::Scanline::markEdges(int pos1, int pos2)
-{
- if (pos2 < pos1)
- return;
-
- for (int i = pos1; i <= pos2; ++i)
- edges[i]->mark = true;
-}
-
-
-QTessellatorPrivate::Vertices::Vertices()
-{
- storage = 0;
- sorted = 0;
- allocated = 0;
- nPoints = 0;
-}
-
-QTessellatorPrivate::Vertices::~Vertices()
-{
- if (storage) {
- free(storage);
- free(sorted);
- }
-}
-
-void QTessellatorPrivate::Vertices::init(int maxVertices)
-{
- if (!storage || maxVertices > allocated) {
- int size = qMax((int)default_alloc, maxVertices);
- storage = q_check_ptr((Vertex *)realloc(storage, size*sizeof(Vertex)));
- sorted = q_check_ptr((Vertex **)realloc(sorted, size*sizeof(Vertex *)));
- allocated = maxVertices;
- }
-}
-
-void QTessellatorPrivate::Vertices::done()
-{
- if (allocated > default_alloc) {
- free(storage);
- free(sorted);
- storage = 0;
- sorted = 0;
- allocated = 0;
- }
-}
-
-
-
-static inline void fillTrapezoid(Q27Dot5 y1, Q27Dot5 y2, int left, int right,
- const QTessellatorPrivate::Vertices &vertices,
- QTessellator::Trapezoid *trap)
-{
- trap->top = y1;
- trap->bottom = y2;
- const QTessellatorPrivate::Vertex *v = vertices[left];
- trap->topLeft = v;
- trap->bottomLeft = vertices.next(v);
- if (trap->topLeft->y > trap->bottomLeft->y)
- qSwap(trap->topLeft,trap->bottomLeft);
- v = vertices[right];
- trap->topRight = v;
- trap->bottomRight = vertices.next(v);
- if (trap->topRight->y > trap->bottomRight->y)
- qSwap(trap->topRight, trap->bottomRight);
-}
-
-QRectF QTessellatorPrivate::collectAndSortVertices(const QPointF *points, int *maxActiveEdges)
-{
- *maxActiveEdges = 0;
- Vertex *v = vertices.storage;
- Vertex **vv = vertices.sorted;
-
- qreal xmin(points[0].x());
- qreal xmax(points[0].x());
- qreal ymin(points[0].y());
- qreal ymax(points[0].y());
-
- // collect vertex data
- Q27Dot5 y_prev = FloatToQ27Dot5(points[vertices.nPoints-1].y());
- Q27Dot5 x_next = FloatToQ27Dot5(points[0].x());
- Q27Dot5 y_next = FloatToQ27Dot5(points[0].y());
- int j = 0;
- int i = 0;
- while (i < vertices.nPoints) {
- Q27Dot5 y_curr = y_next;
-
- *vv = v;
-
- v->x = x_next;
- v->y = y_next;
- v->flags = 0;
-
- next_point:
-
- xmin = qMin(xmin, points[i+1].x());
- xmax = qMax(xmax, points[i+1].x());
- ymin = qMin(ymin, points[i+1].y());
- ymax = qMax(ymax, points[i+1].y());
-
- y_next = FloatToQ27Dot5(points[i+1].y());
- x_next = FloatToQ27Dot5(points[i+1].x());
-
- // skip vertices on top of each other
- if (v->x == x_next && v->y == y_next) {
- ++i;
- if (i < vertices.nPoints)
- goto next_point;
- Vertex *v0 = vertices.storage;
- v0->flags &= ~(LineBeforeStarts|LineBeforeEnds|LineBeforeHorizontal);
- if (y_prev < y_curr)
- v0->flags |= LineBeforeEnds;
- else if (y_prev > y_curr)
- v0->flags |= LineBeforeStarts;
- else
- v0->flags |= LineBeforeHorizontal;
- if ((v0->flags & (LineBeforeStarts|LineAfterStarts))
- && !(v0->flags & (LineAfterEnds|LineBeforeEnds)))
- *maxActiveEdges += 2;
- break;
- }
-
- if (y_prev < y_curr)
- v->flags |= LineBeforeEnds;
- else if (y_prev > y_curr)
- v->flags |= LineBeforeStarts;
- else
- v->flags |= LineBeforeHorizontal;
-
-
- if (y_curr < y_next)
- v->flags |= LineAfterStarts;
- else if (y_curr > y_next)
- v->flags |= LineAfterEnds;
- else
- v->flags |= LineAfterHorizontal;
- // ### could probably get better limit by looping over sorted list and counting down on ending edges
- if ((v->flags & (LineBeforeStarts|LineAfterStarts))
- && !(v->flags & (LineAfterEnds|LineBeforeEnds)))
- *maxActiveEdges += 2;
- y_prev = y_curr;
- ++v;
- ++vv;
- ++j;
- ++i;
- }
- vertices.nPoints = j;
-
- QDEBUG() << "maxActiveEdges=" << *maxActiveEdges;
- vv = vertices.sorted;
- qSort(vv, vv + vertices.nPoints, compareVertex);
-
- return QRectF(xmin, ymin, xmax-xmin, ymax-ymin);
-}
-
-struct QCoincidingEdge {
- QTessellatorPrivate::Vertex *start;
- QTessellatorPrivate::Vertex *end;
- bool used;
- bool before;
-
- inline bool operator<(const QCoincidingEdge &e2) const
- {
- return end->y == e2.end->y ? end->x < e2.end->x : end->y < e2.end->y;
- }
-};
-
-static void cancelEdges(QCoincidingEdge &e1, QCoincidingEdge &e2)
-{
- if (e1.before) {
- e1.start->flags &= ~(LineBeforeStarts|LineBeforeHorizontal);
- e1.end->flags &= ~(LineAfterEnds|LineAfterHorizontal);
- } else {
- e1.start->flags &= ~(LineAfterStarts|LineAfterHorizontal);
- e1.end->flags &= ~(LineBeforeEnds|LineBeforeHorizontal);
- }
- if (e2.before) {
- e2.start->flags &= ~(LineBeforeStarts|LineBeforeHorizontal);
- e2.end->flags &= ~(LineAfterEnds|LineAfterHorizontal);
- } else {
- e2.start->flags &= ~(LineAfterStarts|LineAfterHorizontal);
- e2.end->flags &= ~(LineBeforeEnds|LineBeforeHorizontal);
- }
- e1.used = e2.used = true;
-}
-
-void QTessellatorPrivate::cancelCoincidingEdges()
-{
- Vertex **vv = vertices.sorted;
-
- QCoincidingEdge *tl = 0;
- int tlSize = 0;
-
- for (int i = 0; i < vertices.nPoints - 1; ++i) {
- Vertex *v = vv[i];
- int testListSize = 0;
- while (i < vertices.nPoints - 1) {
- Vertex *n = vv[i];
- if (v->x != n->x || v->y != n->y)
- break;
-
- if (testListSize > tlSize - 2) {
- tlSize = qMax(tlSize*2, 16);
- tl = q_check_ptr((QCoincidingEdge *)realloc(tl, tlSize*sizeof(QCoincidingEdge)));
- }
- if (n->flags & (LineBeforeStarts|LineBeforeHorizontal)) {
- tl[testListSize].start = n;
- tl[testListSize].end = vertices.prev(n);
- tl[testListSize].used = false;
- tl[testListSize].before = true;
- ++testListSize;
- }
- if (n->flags & (LineAfterStarts|LineAfterHorizontal)) {
- tl[testListSize].start = n;
- tl[testListSize].end = vertices.next(n);
- tl[testListSize].used = false;
- tl[testListSize].before = false;
- ++testListSize;
- }
- ++i;
- }
- if (!testListSize)
- continue;
-
- qSort(tl, tl + testListSize);
-
- for (int j = 0; j < testListSize; ++j) {
- if (tl[j].used)
- continue;
-
- for (int k = j + 1; k < testListSize; ++k) {
- if (tl[j].end->x != tl[k].end->x
- || tl[j].end->y != tl[k].end->y
- || tl[k].used)
- break;
-
- if (!winding || tl[j].before != tl[k].before) {
- cancelEdges(tl[j], tl[k]);
- break;
- }
- ++k;
- }
- ++j;
- }
- }
- free(tl);
-}
-
-
-void QTessellatorPrivate::emitEdges(QTessellator *tessellator)
-{
- //QDEBUG() << "TRAPS:";
- if (!scanline.old_size)
- return;
-
- // emit edges
- if (winding) {
- // winding fill rule
- int w = 0;
-
- scanline.old[0]->y_left = y;
-
- for (int i = 0; i < scanline.old_size - 1; ++i) {
- Edge *left = scanline.old[i];
- Edge *right = scanline.old[i+1];
- w += left->winding;
-// qDebug() << "i=" << i << "edge->winding=" << left->winding << "winding=" << winding;
- if (w == 0) {
- left->y_right = y;
- right->y_left = y;
- } else if (!emit_clever || left->mark || right->mark) {
- Q27Dot5 top = qMax(left->y_right, right->y_left);
- if (top != y) {
- QTessellator::Trapezoid trap;
- fillTrapezoid(top, y, left->edge, right->edge, vertices, &trap);
- tessellator->addTrap(trap);
-// QDEBUG() << " top=" << Q27Dot5ToDouble(top) << "left=" << left->edge << "right=" << right->edge;
- }
- right->y_left = y;
- left->y_right = y;
- }
- left->mark = false;
- }
- if (scanline.old[scanline.old_size - 1]->mark) {
- scanline.old[scanline.old_size - 1]->y_right = y;
- scanline.old[scanline.old_size - 1]->mark = false;
- }
- } else {
- // odd-even fill rule
- for (int i = 0; i < scanline.old_size; i += 2) {
- Edge *left = scanline.old[i];
- Edge *right = scanline.old[i+1];
- if (!emit_clever || left->mark || right->mark) {
- Q27Dot5 top = qMax(left->y_right, right->y_left);
- if (top != y) {
- QTessellator::Trapezoid trap;
- fillTrapezoid(top, y, left->edge, right->edge, vertices, &trap);
- tessellator->addTrap(trap);
- }
-// QDEBUG() << " top=" << Q27Dot5ToDouble(top) << "left=" << left->edge << "right=" << right->edge;
- left->y_left = y;
- left->y_right = y;
- right->y_left = y;
- right->y_right = y;
- left->mark = right->mark = false;
- }
- }
- }
-}
-
-
-void QTessellatorPrivate::processIntersections()
-{
- QDEBUG() << "PROCESS INTERSECTIONS";
- // process intersections
- while (!intersections.isEmpty()) {
- Intersections::iterator it = intersections.begin();
- if (it.key().y != y)
- break;
-
- // swap edges
- QDEBUG() << " swapping intersecting edges ";
- int min = scanline.size;
- int max = 0;
- Q27Dot5 xmin = INT_MAX;
- Q27Dot5 xmax = INT_MIN;
- int num = 0;
- while (1) {
- const Intersection &i = it.key();
- int next = it->next;
-
- int edgePos = scanline.findEdge(i.edge);
- if (edgePos >= 0) {
- ++num;
- min = qMin(edgePos, min);
- max = qMax(edgePos, max);
- Edge *edge = scanline.edges[edgePos];
- xmin = qMin(xmin, edge->positionAt(y));
- xmax = qMax(xmax, edge->positionAt(y));
- }
- Intersection key;
- key.y = y;
- key.edge = next;
- it = intersections.find(key);
- intersections.remove(i);
- if (it == intersections.end())
- break;
- }
- if (num < 2)
- continue;
-
- Q_ASSERT(min != max);
- QDEBUG() << "sorting between" << min << "and" << max << "xpos=" << xmin << xmax;
- while (min > 0 && scanline.edges[min - 1]->positionAt(y) >= xmin) {
- QDEBUG() << " adding edge on left";
- --min;
- }
- while (max + 1 < scanline.size && scanline.edges[max + 1]->positionAt(y) <= xmax) {
- QDEBUG() << " adding edge on right";
- ++max;
- }
-
- qSort(scanline.edges + min, scanline.edges + max + 1, EdgeSorter(y));
-#ifdef DEBUG
- for (int i = min; i <= max; ++i)
- QDEBUG() << " " << scanline.edges[i]->edge << "at pos" << i;
-#endif
- for (int i = min; i <= max; ++i) {
- Edge *edge = scanline.edges[i];
- edge->intersect_left = true;
- edge->intersect_right = true;
- edge->mark = true;
- }
- }
-}
-
-void QTessellatorPrivate::removeEdges()
-{
- int cv = currentVertex;
- while (cv < vertices.nPoints) {
- const Vertex *v = vertices.sorted[cv];
- if (v->y > y)
- break;
- if (v->flags & LineBeforeEnds) {
- QDEBUG() << " removing edge" << vertices.prevPos(v);
- int pos = scanline.findEdge(vertices.prevPos(v));
- if (pos == -1)
- continue;
- scanline.edges[pos]->mark = true;
- if (pos > 0)
- scanline.edges[pos - 1]->intersect_right = true;
- if (pos < scanline.size - 1)
- scanline.edges[pos + 1]->intersect_left = true;
- scanline.removeAt(pos);
- }
- if (v->flags & LineAfterEnds) {
- QDEBUG() << " removing edge" << vertices.position(v);
- int pos = scanline.findEdge(vertices.position(v));
- if (pos == -1)
- continue;
- scanline.edges[pos]->mark = true;
- if (pos > 0)
- scanline.edges[pos - 1]->intersect_right = true;
- if (pos < scanline.size - 1)
- scanline.edges[pos + 1]->intersect_left = true;
- scanline.removeAt(pos);
- }
- ++cv;
- }
-}
-
-void QTessellatorPrivate::addEdges()
-{
- while (currentVertex < vertices.nPoints) {
- const Vertex *v = vertices.sorted[currentVertex];
- if (v->y > y)
- break;
- if (v->flags & LineBeforeStarts) {
- // add new edge
- int start = vertices.prevPos(v);
- Edge e(vertices, start);
- int pos = scanline.findEdgePosition(e);
- QDEBUG() << " adding edge" << start << "at position" << pos;
- scanline.insert(pos, e);
- if (!mark_clever || !(v->flags & LineAfterEnds)) {
- if (pos > 0)
- scanline.edges[pos - 1]->mark = true;
- if (pos < scanline.size - 1)
- scanline.edges[pos + 1]->mark = true;
- }
- }
- if (v->flags & LineAfterStarts) {
- Edge e(vertices, vertices.position(v));
- int pos = scanline.findEdgePosition(e);
- QDEBUG() << " adding edge" << vertices.position(v) << "at position" << pos;
- scanline.insert(pos, e);
- if (!mark_clever || !(v->flags & LineBeforeEnds)) {
- if (pos > 0)
- scanline.edges[pos - 1]->mark = true;
- if (pos < scanline.size - 1)
- scanline.edges[pos + 1]->mark = true;
- }
- }
- if (v->flags & LineAfterHorizontal) {
- int pos1 = scanline.findEdgePosition(v->x, v->y);
- const Vertex *next = vertices.next(v);
- Q_ASSERT(v->y == next->y);
- int pos2 = scanline.findEdgePosition(next->x, next->y);
- if (pos2 < pos1)
- qSwap(pos1, pos2);
- if (pos1 > 0)
- --pos1;
- if (pos2 == scanline.size)
- --pos2;
- //QDEBUG() << "marking horizontal edge from " << pos1 << "to" << pos2;
- scanline.markEdges(pos1, pos2);
- }
- ++currentVertex;
- }
-}
-
-#ifdef DEBUG
-static void checkLinkChain(const QTessellatorPrivate::Intersections &intersections,
- QTessellatorPrivate::Intersection i)
-{
-// qDebug() << " Link chain: ";
- int end = i.edge;
- while (1) {
- QTessellatorPrivate::IntersectionLink l = intersections.value(i);
-// qDebug() << " " << i.edge << "next=" << l.next << "prev=" << l.prev;
- if (l.next == end)
- break;
- Q_ASSERT(l.next != -1);
- Q_ASSERT(l.prev != -1);
-
- QTessellatorPrivate::Intersection i2 = i;
- i2.edge = l.next;
- QTessellatorPrivate::IntersectionLink l2 = intersections.value(i2);
-
- Q_ASSERT(l2.next != -1);
- Q_ASSERT(l2.prev != -1);
- Q_ASSERT(l.next == i2.edge);
- Q_ASSERT(l2.prev == i.edge);
- i = i2;
- }
-}
-#endif
-
-bool QTessellatorPrivate::edgeInChain(Intersection i, int edge)
-{
- int end = i.edge;
- while (1) {
- if (i.edge == edge)
- return true;
- IntersectionLink l = intersections.value(i);
- if (l.next == end)
- break;
- Q_ASSERT(l.next != -1);
- Q_ASSERT(l.prev != -1);
-
- Intersection i2 = i;
- i2.edge = l.next;
-
-#ifndef QT_NO_DEBUG
- IntersectionLink l2 = intersections.value(i2);
- Q_ASSERT(l2.next != -1);
- Q_ASSERT(l2.prev != -1);
- Q_ASSERT(l.next == i2.edge);
- Q_ASSERT(l2.prev == i.edge);
-#endif
- i = i2;
- }
- return false;
-}
-
-
-void QTessellatorPrivate::addIntersection(const Edge *e1, const Edge *e2)
-{
- const IntersectionLink emptyLink = {-1, -1};
-
- int next = vertices.nextPos(vertices[e1->edge]);
- if (e2->edge == next)
- return;
- int prev = vertices.prevPos(vertices[e1->edge]);
- if (e2->edge == prev)
- return;
-
- Q27Dot5 yi;
- bool det_positive;
- bool isect = e1->intersect(*e2, &yi, &det_positive);
- QDEBUG("checking edges %d and %d", e1->edge, e2->edge);
- if (!isect) {
- QDEBUG() << " no intersection";
- return;
- }
-
- // don't emit an intersection if it's at the start of a line segment or above us
- if (yi <= y) {
- if (!det_positive)
- return;
- QDEBUG() << " ----->>>>>> WRONG ORDER!";
- yi = y;
- }
- QDEBUG() << " between edges " << e1->edge << "and" << e2->edge << "at point ("
- << Q27Dot5ToDouble(yi) << ')';
-
- Intersection i1;
- i1.y = yi;
- i1.edge = e1->edge;
- IntersectionLink link1 = intersections.value(i1, emptyLink);
- Intersection i2;
- i2.y = yi;
- i2.edge = e2->edge;
- IntersectionLink link2 = intersections.value(i2, emptyLink);
-
- // new pair of edges
- if (link1.next == -1 && link2.next == -1) {
- link1.next = link1.prev = i2.edge;
- link2.next = link2.prev = i1.edge;
- } else if (link1.next == i2.edge || link1.prev == i2.edge
- || link2.next == i1.edge || link2.prev == i1.edge) {
-#ifdef DEBUG
- checkLinkChain(intersections, i1);
- checkLinkChain(intersections, i2);
- Q_ASSERT(edgeInChain(i1, i2.edge));
-#endif
- return;
- } else if (link1.next == -1 || link2.next == -1) {
- if (link2.next == -1) {
- qSwap(i1, i2);
- qSwap(link1, link2);
- }
- Q_ASSERT(link1.next == -1);
-#ifdef DEBUG
- checkLinkChain(intersections, i2);
-#endif
- // only i2 in list
- link1.next = i2.edge;
- link1.prev = link2.prev;
- link2.prev = i1.edge;
- Intersection other;
- other.y = yi;
- other.edge = link1.prev;
- IntersectionLink link = intersections.value(other, emptyLink);
- Q_ASSERT(link.next == i2.edge);
- Q_ASSERT(link.prev != -1);
- link.next = i1.edge;
- intersections.insert(other, link);
- } else {
- bool connected = edgeInChain(i1, i2.edge);
- if (connected)
- return;
-#ifdef DEBUG
- checkLinkChain(intersections, i1);
- checkLinkChain(intersections, i2);
-#endif
- // both already in some list. Have to make sure they are connected
- // this can be done by cutting open the ring(s) after the two eges and
- // connecting them again
- Intersection other1;
- other1.y = yi;
- other1.edge = link1.next;
- IntersectionLink linko1 = intersections.value(other1, emptyLink);
- Intersection other2;
- other2.y = yi;
- other2.edge = link2.next;
- IntersectionLink linko2 = intersections.value(other2, emptyLink);
-
- linko1.prev = i2.edge;
- link2.next = other1.edge;
-
- linko2.prev = i1.edge;
- link1.next = other2.edge;
- intersections.insert(other1, linko1);
- intersections.insert(other2, linko2);
- }
- intersections.insert(i1, link1);
- intersections.insert(i2, link2);
-#ifdef DEBUG
- checkLinkChain(intersections, i1);
- checkLinkChain(intersections, i2);
- Q_ASSERT(edgeInChain(i1, i2.edge));
-#endif
- return;
-
-}
-
-
-void QTessellatorPrivate::addIntersections()
-{
- if (scanline.size) {
- QDEBUG() << "INTERSECTIONS";
- // check marked edges for intersections
-#ifdef DEBUG
- for (int i = 0; i < scanline.size; ++i) {
- Edge *e = scanline.edges[i];
- QDEBUG() << " " << i << e->edge << "isect=(" << e->intersect_left << e->intersect_right
- << ')';
- }
-#endif
-
- for (int i = 0; i < scanline.size - 1; ++i) {
- Edge *e1 = scanline.edges[i];
- Edge *e2 = scanline.edges[i + 1];
- // check for intersection
- if (e1->intersect_right || e2->intersect_left)
- addIntersection(e1, e2);
- }
- }
-#if 0
- if (intersections.constBegin().key().y == y) {
- QDEBUG() << "----------------> intersection on same line";
- scanline.clearMarks();
- scanline.processIntersections(y, &intersections);
- goto redo;
- }
-#endif
-}
-
-
-QTessellator::QTessellator()
-{
- d = new QTessellatorPrivate;
-}
-
-QTessellator::~QTessellator()
-{
- delete d;
-}
-
-void QTessellator::setWinding(bool w)
-{
- d->winding = w;
-}
-
-
-QRectF QTessellator::tessellate(const QPointF *points, int nPoints)
-{
- Q_ASSERT(points[0] == points[nPoints-1]);
- --nPoints;
-
-#ifdef DEBUG
- QDEBUG()<< "POINTS:";
- for (int i = 0; i < nPoints; ++i) {
- QDEBUG() << points[i];
- }
-#endif
-
- // collect edges and calculate bounds
- d->vertices.nPoints = nPoints;
- d->vertices.init(nPoints);
-
- int maxActiveEdges = 0;
- QRectF br = d->collectAndSortVertices(points, &maxActiveEdges);
- d->cancelCoincidingEdges();
-
-#ifdef DEBUG
- QDEBUG() << "nPoints = " << nPoints << "using " << d->vertices.nPoints;
- QDEBUG()<< "VERTICES:";
- for (int i = 0; i < d->vertices.nPoints; ++i) {
- QDEBUG() << " " << i << ": "
- << "point=" << d->vertices.position(d->vertices.sorted[i])
- << "flags=" << d->vertices.sorted[i]->flags
- << "pos=(" << Q27Dot5ToDouble(d->vertices.sorted[i]->x) << '/'
- << Q27Dot5ToDouble(d->vertices.sorted[i]->y) << ')';
- }
-#endif
-
- d->scanline.init(maxActiveEdges);
- d->y = INT_MIN/256;
- d->currentVertex = 0;
-
- while (d->currentVertex < d->vertices.nPoints) {
- d->scanline.clearMarks();
-
- d->y = d->vertices.sorted[d->currentVertex]->y;
- if (!d->intersections.isEmpty())
- d->y = qMin(d->y, d->intersections.constBegin().key().y);
-
- QDEBUG()<< "===== SCANLINE: y =" << Q27Dot5ToDouble(d->y) << " =====";
-
- d->scanline.prepareLine();
- d->processIntersections();
- d->removeEdges();
- d->addEdges();
- d->addIntersections();
- d->emitEdges(this);
- d->scanline.lineDone();
-
-#ifdef DEBUG
- QDEBUG()<< "===== edges:";
- for (int i = 0; i < d->scanline.size; ++i) {
- QDEBUG() << " " << d->scanline.edges[i]->edge
- << "p0= (" << Q27Dot5ToDouble(d->scanline.edges[i]->v0->x)
- << '/' << Q27Dot5ToDouble(d->scanline.edges[i]->v0->y)
- << ") p1= (" << Q27Dot5ToDouble(d->scanline.edges[i]->v1->x)
- << '/' << Q27Dot5ToDouble(d->scanline.edges[i]->v1->y) << ')'
- << "x=" << Q27Dot5ToDouble(d->scanline.edges[i]->positionAt(d->y))
- << "isLeftOfNext="
- << ((i < d->scanline.size - 1)
- ? d->scanline.edges[i]->isLeftOf(*d->scanline.edges[i+1], d->y)
- : true);
- }
-#endif
-}
-
- d->scanline.done();
- d->intersections.clear();
- return br;
-}
-
-// tessellates the given convex polygon
-void QTessellator::tessellateConvex(const QPointF *points, int nPoints)
-{
- Q_ASSERT(points[0] == points[nPoints-1]);
- --nPoints;
-
- d->vertices.nPoints = nPoints;
- d->vertices.init(nPoints);
-
- for (int i = 0; i < nPoints; ++i) {
- d->vertices[i]->x = FloatToQ27Dot5(points[i].x());
- d->vertices[i]->y = FloatToQ27Dot5(points[i].y());
- }
-
- int left = 0, right = 0;
-
- int top = 0;
- for (int i = 1; i < nPoints; ++i) {
- if (d->vertices[i]->y < d->vertices[top]->y)
- top = i;
- }
-
- left = (top + nPoints - 1) % nPoints;
- right = (top + 1) % nPoints;
-
- while (d->vertices[left]->x == d->vertices[top]->x && d->vertices[left]->y == d->vertices[top]->y && left != right)
- left = (left + nPoints - 1) % nPoints;
-
- while (d->vertices[right]->x == d->vertices[top]->x && d->vertices[right]->y == d->vertices[top]->y && left != right)
- right = (right + 1) % nPoints;
-
- if (left == right)
- return;
-
- int dir = 1;
-
- Vertex dLeft = { d->vertices[top]->x - d->vertices[left]->x,
- d->vertices[top]->y - d->vertices[left]->y };
-
- Vertex dRight = { d->vertices[right]->x - d->vertices[top]->x,
- d->vertices[right]->y - d->vertices[top]->y };
-
- Q27Dot5 cross = dLeft.x * dRight.y - dLeft.y * dRight.x;
-
- // flip direction if polygon is clockwise
- if (cross < 0 || (cross == 0 && dLeft.x > 0)) {
- qSwap(left, right);
- dir = -1;
- }
-
- Vertex *lastLeft = d->vertices[top];
- Vertex *lastRight = d->vertices[top];
-
- QTessellator::Trapezoid trap;
-
- while (lastLeft->y == d->vertices[left]->y && left != right) {
- lastLeft = d->vertices[left];
- left = (left + nPoints - dir) % nPoints;
- }
-
- while (lastRight->y == d->vertices[right]->y && left != right) {
- lastRight = d->vertices[right];
- right = (right + nPoints + dir) % nPoints;
- }
-
- while (true) {
- trap.top = qMax(lastRight->y, lastLeft->y);
- trap.bottom = qMin(d->vertices[left]->y, d->vertices[right]->y);
- trap.topLeft = lastLeft;
- trap.topRight = lastRight;
- trap.bottomLeft = d->vertices[left];
- trap.bottomRight = d->vertices[right];
-
- if (trap.bottom > trap.top)
- addTrap(trap);
-
- if (left == right)
- break;
-
- if (d->vertices[right]->y < d->vertices[left]->y) {
- do {
- lastRight = d->vertices[right];
- right = (right + nPoints + dir) % nPoints;
- }
- while (lastRight->y == d->vertices[right]->y && left != right);
- } else {
- do {
- lastLeft = d->vertices[left];
- left = (left + nPoints - dir) % nPoints;
- }
- while (lastLeft->y == d->vertices[left]->y && left != right);
- }
- }
-}
-
-// tessellates the stroke of the line from a_ to b_ with the given width and a flat cap
-void QTessellator::tessellateRect(const QPointF &a_, const QPointF &b_, qreal width)
-{
- Vertex a = { FloatToQ27Dot5(a_.x()), FloatToQ27Dot5(a_.y()) };
- Vertex b = { FloatToQ27Dot5(b_.x()), FloatToQ27Dot5(b_.y()) };
-
- QPointF pa = a_, pb = b_;
-
- if (a.y > b.y) {
- qSwap(a, b);
- qSwap(pa, pb);
- }
-
- Vertex delta = { b.x - a.x, b.y - a.y };
-
- if (delta.x == 0 && delta.y == 0)
- return;
-
- qreal hw = 0.5 * width;
-
- if (delta.x == 0) {
- Q27Dot5 halfWidth = FloatToQ27Dot5(hw);
-
- if (halfWidth == 0)
- return;
-
- Vertex topLeft = { a.x - halfWidth, a.y };
- Vertex topRight = { a.x + halfWidth, a.y };
- Vertex bottomLeft = { a.x - halfWidth, b.y };
- Vertex bottomRight = { a.x + halfWidth, b.y };
-
- QTessellator::Trapezoid trap = { topLeft.y, bottomLeft.y, &topLeft, &bottomLeft, &topRight, &bottomRight };
- addTrap(trap);
- } else if (delta.y == 0) {
- Q27Dot5 halfWidth = FloatToQ27Dot5(hw);
-
- if (halfWidth == 0)
- return;
-
- if (a.x > b.x)
- qSwap(a.x, b.x);
-
- Vertex topLeft = { a.x, a.y - halfWidth };
- Vertex topRight = { b.x, a.y - halfWidth };
- Vertex bottomLeft = { a.x, a.y + halfWidth };
- Vertex bottomRight = { b.x, a.y + halfWidth };
-
- QTessellator::Trapezoid trap = { topLeft.y, bottomLeft.y, &topLeft, &bottomLeft, &topRight, &bottomRight };
- addTrap(trap);
- } else {
- QPointF perp(pb.y() - pa.y(), pa.x() - pb.x());
- qreal length = qSqrt(perp.x() * perp.x() + perp.y() * perp.y());
-
- if (qFuzzyIsNull(length))
- return;
-
- // need the half of the width
- perp *= hw / length;
-
- QPointF pta = pa + perp;
- QPointF ptb = pa - perp;
- QPointF ptc = pb - perp;
- QPointF ptd = pb + perp;
-
- Vertex ta = { FloatToQ27Dot5(pta.x()), FloatToQ27Dot5(pta.y()) };
- Vertex tb = { FloatToQ27Dot5(ptb.x()), FloatToQ27Dot5(ptb.y()) };
- Vertex tc = { FloatToQ27Dot5(ptc.x()), FloatToQ27Dot5(ptc.y()) };
- Vertex td = { FloatToQ27Dot5(ptd.x()), FloatToQ27Dot5(ptd.y()) };
-
- if (ta.y < tb.y) {
- if (tb.y < td.y) {
- QTessellator::Trapezoid top = { ta.y, tb.y, &ta, &tb, &ta, &td };
- QTessellator::Trapezoid bottom = { td.y, tc.y, &tb, &tc, &td, &tc };
- addTrap(top);
- addTrap(bottom);
-
- QTessellator::Trapezoid middle = { tb.y, td.y, &tb, &tc, &ta, &td };
- addTrap(middle);
- } else {
- QTessellator::Trapezoid top = { ta.y, td.y, &ta, &tb, &ta, &td };
- QTessellator::Trapezoid bottom = { tb.y, tc.y, &tb, &tc, &td, &tc };
- addTrap(top);
- addTrap(bottom);
-
- if (tb.y != td.y) {
- QTessellator::Trapezoid middle = { td.y, tb.y, &ta, &tb, &td, &tc };
- addTrap(middle);
- }
- }
- } else {
- if (ta.y < tc.y) {
- QTessellator::Trapezoid top = { tb.y, ta.y, &tb, &tc, &tb, &ta };
- QTessellator::Trapezoid bottom = { tc.y, td.y, &tc, &td, &ta, &td };
- addTrap(top);
- addTrap(bottom);
-
- QTessellator::Trapezoid middle = { ta.y, tc.y, &tb, &tc, &ta, &td };
- addTrap(middle);
- } else {
- QTessellator::Trapezoid top = { tb.y, tc.y, &tb, &tc, &tb, &ta };
- QTessellator::Trapezoid bottom = { ta.y, td.y, &tc, &td, &ta, &td };
- addTrap(top);
- addTrap(bottom);
-
- if (ta.y != tc.y) {
- QTessellator::Trapezoid middle = { tc.y, ta.y, &tc, &td, &tb, &ta };
- addTrap(middle);
- }
- }
- }
- }
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/painting/qtessellator_p.h b/src/gui/painting/qtessellator_p.h
deleted file mode 100644
index 9f598b6b2e..0000000000
--- a/src/gui/painting/qtessellator_p.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QTESSELATOR_P_H
-#define QTESSELATOR_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <qpoint.h>
-#include <qrect.h>
-
-QT_BEGIN_NAMESPACE
-
-class QTessellatorPrivate;
-
-typedef int Q27Dot5;
-#define Q27Dot5ToDouble(i) ((i)/32.)
-#define FloatToQ27Dot5(i) (int)((i) * 32)
-#define IntToQ27Dot5(i) ((i) << 5)
-#define Q27Dot5ToXFixed(i) ((i) << 11)
-#define Q27Dot5Factor 32
-
-class Q_GUI_EXPORT QTessellator {
-public:
- QTessellator();
- virtual ~QTessellator();
-
- QRectF tessellate(const QPointF *points, int nPoints);
- void tessellateConvex(const QPointF *points, int nPoints);
- void tessellateRect(const QPointF &a, const QPointF &b, qreal width);
-
- void setWinding(bool w);
-
- struct Vertex {
- Q27Dot5 x;
- Q27Dot5 y;
- };
- struct Trapezoid {
- Q27Dot5 top;
- Q27Dot5 bottom;
- const Vertex *topLeft;
- const Vertex *bottomLeft;
- const Vertex *topRight;
- const Vertex *bottomRight;
- };
- virtual void addTrap(const Trapezoid &trap) = 0;
-
-private:
- friend class QTessellatorPrivate;
- QTessellatorPrivate *d;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/gui/painting/qunifiedtoolbarsurface_mac.cpp b/src/gui/painting/qunifiedtoolbarsurface_mac.cpp
deleted file mode 100644
index aecbf2b177..0000000000
--- a/src/gui/painting/qunifiedtoolbarsurface_mac.cpp
+++ /dev/null
@@ -1,265 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qunifiedtoolbarsurface_mac_p.h"
-#include <private/qt_cocoa_helpers_mac_p.h>
-#include <private/qbackingstore_p.h>
-#include <private/qmainwindowlayout_p.h>
-
-#include <QDebug>
-
-#ifdef QT_MAC_USE_COCOA
-
-QT_BEGIN_NAMESPACE
-
-QUnifiedToolbarSurface::QUnifiedToolbarSurface(QWidget *widget)
- : QRasterWindowSurface(widget, false), d_ptr(new QUnifiedToolbarSurfacePrivate)
-{
- d_ptr->image = 0;
- d_ptr->inSetGeometry = false;
-
- setGeometry(QRect(QPoint(0, 0), QSize(widget->width(), 100))); // FIXME: Fix height.
-}
-
-QUnifiedToolbarSurface::~QUnifiedToolbarSurface()
-{
- if (d_ptr->image)
- delete d_ptr->image;
-}
-
-QPaintDevice *QUnifiedToolbarSurface::paintDevice()
-{
- return &d_ptr->image->image;
-}
-
-void QUnifiedToolbarSurface::recursiveRedirect(QObject *object, QWidget *parent_toolbar, const QPoint &offset)
-{
- if (object != 0) {
- if (object->isWidgetType()) {
- QWidget *widget = qobject_cast<QWidget *>(object);
-
- // We redirect the painting only if the widget is in the same window
- // and is not a window in itself.
- if (!(widget->windowType() & Qt::Window)) {
- widget->d_func()->unifiedSurface = this;
- widget->d_func()->isInUnifiedToolbar = true;
- widget->d_func()->toolbar_offset = offset;
- widget->d_func()->toolbar_ancestor = parent_toolbar;
-
- for (int i = 0; i < object->children().size(); ++i) {
- recursiveRedirect(object->children().at(i), parent_toolbar, offset);
- }
- }
- }
- }
-}
-
-void QUnifiedToolbarSurface::insertToolbar(QWidget *toolbar, const QPoint &offset)
-{
- setGeometry(QRect(QPoint(0, 0), QSize(offset.x() + toolbar->width(), 100))); // FIXME
- recursiveRedirect(toolbar, toolbar, offset);
-}
-
-// We basically undo what we set in recursiveRedirect().
-void QUnifiedToolbarSurface::recursiveRemoval(QObject *object)
-{
- if (object != 0) {
- if (object->isWidgetType()) {
- QWidget *widget = qobject_cast<QWidget *>(object);
-
- // If it's a pop-up or something similar, we don't redirect it.
- if (widget->windowType() & Qt::Window)
- return;
-
- widget->d_func()->unifiedSurface = 0;
- widget->d_func()->isInUnifiedToolbar = false;
- widget->d_func()->toolbar_offset = QPoint();
- widget->d_func()->toolbar_ancestor = 0;
- }
-
- for (int i = 0; i < object->children().size(); ++i) {
- recursiveRemoval(object->children().at(i));
- }
- }
-}
-
-void QUnifiedToolbarSurface::removeToolbar(QToolBar *toolbar)
-{
- recursiveRemoval(toolbar);
-}
-
-void QUnifiedToolbarSurface::setGeometry(const QRect &rect)
-{
- QWindowSurface::setGeometry(rect);
- Q_D(QUnifiedToolbarSurface);
- d->inSetGeometry = true;
- if (d->image == 0 || d->image->width() < rect.width() || d->image->height() < rect.height())
- prepareBuffer(QImage::Format_ARGB32_Premultiplied, window());
- d->inSetGeometry = false;
-
- // FIXME: set unified toolbar height.
-}
-
-void QUnifiedToolbarSurface::beginPaint(const QRegion &rgn)
-{
- QPainter p(&d_ptr->image->image);
- p.setCompositionMode(QPainter::CompositionMode_Source);
- const QVector<QRect> rects = rgn.rects();
- const QColor blank = Qt::transparent;
- for (QVector<QRect>::const_iterator it = rects.begin(); it != rects.end(); ++it) {
- p.fillRect(*it, blank);
- }
-}
-
-void QUnifiedToolbarSurface::updateToolbarOffset(QWidget *widget)
-{
- QMainWindowLayout *mlayout = qobject_cast<QMainWindowLayout*> (widget->window()->layout());
- if (mlayout)
- mlayout->updateUnifiedToolbarOffset();
-}
-
-void QUnifiedToolbarSurface::flush(QWidget *widget, const QRegion &region, const QPoint &offset)
-{
- Q_UNUSED(region);
- Q_UNUSED(offset);
-
- this->flush(widget);
-}
-
-void QUnifiedToolbarSurface::flush(QWidget *widget)
-{
- Q_D(QUnifiedToolbarSurface);
-
- if (!d->image)
- return;
-
- if (widget->d_func()->flushRequested) {
- // We call display: directly to avoid flickering in the toolbar.
- qt_mac_display(widget);
- }
-}
-
-void QUnifiedToolbarSurface::prepareBuffer(QImage::Format format, QWidget *widget)
-{
- Q_D(QUnifiedToolbarSurface);
-
- int width = geometry().width();
- int height = 100; // FIXME
- if (d->image) {
- width = qMax(d->image->width(), width);
- height = qMax(d->image->height(), height);
- }
-
- if (width == 0 || height == 0) {
- delete d->image;
- d->image = 0;
- return;
- }
-
- QNativeImage *oldImage = d->image;
-
- d->image = new QNativeImage(width, height, format, false, widget);
-
- if (oldImage && d->inSetGeometry && hasStaticContents()) {
- // Make sure we use the const version of bits() (no detach).
- const uchar *src = const_cast<const QImage &>(oldImage->image).bits();
- uchar *dst = d->image->image.bits();
-
- const int srcBytesPerLine = oldImage->image.bytesPerLine();
- const int dstBytesPerLine = d->image->image.bytesPerLine();
- const int bytesPerPixel = oldImage->image.depth() >> 3;
-
- QRegion staticRegion(staticContents());
- // Make sure we're inside the boundaries of the old image.
- staticRegion &= QRect(0, 0, oldImage->image.width(), oldImage->image.height());
- const QVector<QRect> &rects = staticRegion.rects();
- const QRect *srcRect = rects.constData();
-
- // Copy the static content of the old image into the new one.
- int numRectsLeft = rects.size();
- do {
- const int bytesOffset = srcRect->x() * bytesPerPixel;
- const int dy = srcRect->y();
-
- // Adjust src and dst to point to the right offset.
- const uchar *s = src + dy * srcBytesPerLine + bytesOffset;
- uchar *d = dst + dy * dstBytesPerLine + bytesOffset;
- const int numBytes = srcRect->width() * bytesPerPixel;
-
- int numScanLinesLeft = srcRect->height();
- do {
- ::memcpy(d, s, numBytes);
- d += dstBytesPerLine;
- s += srcBytesPerLine;
- } while (--numScanLinesLeft);
-
- ++srcRect;
- } while (--numRectsLeft);
- }
-
- delete oldImage;
-}
-
-CGContextRef QUnifiedToolbarSurface::imageContext()
-{
- Q_D(QUnifiedToolbarSurface);
- return d->image->cg;
-}
-
-void QUnifiedToolbarSurface::renderToolbar(QWidget *widget, bool forceFlush)
-{
- QWidget *toolbar = widget->d_func()->toolbar_ancestor;
-
- updateToolbarOffset(toolbar);
- QRect beginPaintRect(toolbar->d_func()->toolbar_offset.x(), toolbar->d_func()->toolbar_offset.y(), toolbar->geometry().width(), toolbar->geometry().height());
- QRegion beginPaintRegion(beginPaintRect);
-
- beginPaint(beginPaintRegion);
- toolbar->render(paintDevice(), toolbar->d_func()->toolbar_offset, QRegion(toolbar->geometry()), QWidget::DrawChildren);
- toolbar->d_func()->flushRequested = true;
-
- if (forceFlush)
- flush(toolbar);
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_MAC_USE_COCOA
diff --git a/src/gui/painting/qunifiedtoolbarsurface_mac_p.h b/src/gui/painting/qunifiedtoolbarsurface_mac_p.h
deleted file mode 100644
index 2a9cedad72..0000000000
--- a/src/gui/painting/qunifiedtoolbarsurface_mac_p.h
+++ /dev/null
@@ -1,140 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QUNIFIEDTOOLBARSURFACE_MAC_P_H
-#define QUNIFIEDTOOLBARSURFACE_MAC_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <private/qwindowsurface_raster_p.h>
-#include <QWidget>
-#include <QToolBar>
-#include <private/qwidget_p.h>
-#include <private/qnativeimage_p.h>
-
-#ifdef QT_MAC_USE_COCOA
-
-QT_BEGIN_NAMESPACE
-
-class QNativeImage;
-
-//
-// This is the implementation of the unified toolbar on Mac OS X
-// with the graphics system raster.
-//
-// General idea:
-// -------------
-// We redirect the painting of widgets inside the unified toolbar
-// to a special window surface, the QUnifiedToolbarSurface.
-// We need a separate window surface because the unified toolbar
-// is out of the content view.
-// The input system is the same as for the unified toolbar with the
-// native (CoreGraphics) engine.
-//
-// Execution flow:
-// ---------------
-// The unified toolbar is triggered by QMainWindow::setUnifiedTitleAndToolBarOnMac().
-// It calls QMainWindowLayout::insertIntoMacToolbar() which will
-// set all the appropriate variables (offsets, redirection, ...).
-// When Qt tells a widget to repaint, QWidgetPrivate::drawWidget()
-// checks if the widget is inside the unified toolbar and exits without
-// painting is that is the case.
-// We trigger the rendering of the unified toolbar in QWidget::repaint()
-// and QWidget::update().
-// We keep track of flush requests via "flushRequested" variable. That
-// allow flush() to be a no-op if no repaint occured for a widget.
-// We rely on the needsDisplay: and drawRect: mecanism for drawing our
-// content into the graphics context.
-//
-// Notes:
-// ------
-// The painting of items inside the unified toolbar is expensive.
-// Too many repaints will drastically slow down the whole application.
-//
-
-class QUnifiedToolbarSurfacePrivate
-{
-public:
- QNativeImage *image;
- uint inSetGeometry : 1;
-};
-
-class Q_GUI_EXPORT QUnifiedToolbarSurface : public QRasterWindowSurface
-{
-public:
- QUnifiedToolbarSurface(QWidget *widget);
- ~QUnifiedToolbarSurface();
-
- void flush(QWidget *widget);
- void flush(QWidget *widget, const QRegion &region, const QPoint &offset);
- void setGeometry(const QRect &rect);
- void beginPaint(const QRegion &rgn);
- void insertToolbar(QWidget *toolbar, const QPoint &offset);
- void removeToolbar(QToolBar *toolbar);
- void updateToolbarOffset(QWidget *widget);
- void renderToolbar(QWidget *widget, bool forceFlush = false);
- void recursiveRedirect(QObject *widget, QWidget *parent_toolbar, const QPoint &offset);
-
- QPaintDevice *paintDevice();
- CGContextRef imageContext();
-
-private:
- void prepareBuffer(QImage::Format format, QWidget *widget);
- void recursiveRemoval(QObject *object);
-
- Q_DECLARE_PRIVATE(QUnifiedToolbarSurface)
- QScopedPointer<QUnifiedToolbarSurfacePrivate> d_ptr;
-};
-
-QT_END_NAMESPACE
-
-#endif // QT_MAC_USE_COCOA
-
-#endif // QUNIFIEDTOOLBARSURFACE_MAC_P_H
diff --git a/src/gui/painting/qwindowsurface.cpp b/src/gui/painting/qwindowsurface.cpp
deleted file mode 100644
index fa3c6837b9..0000000000
--- a/src/gui/painting/qwindowsurface.cpp
+++ /dev/null
@@ -1,383 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <private/qwindowsurface_p.h>
-#include <qwidget.h>
-#include <private/qwidget_p.h>
-#include <private/qbackingstore_p.h>
-#include <private/qapplication_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QWindowSurfacePrivate
-{
-public:
- QWindowSurfacePrivate(QWidget *w)
- : window(w)
- {
- }
-
- QWidget *window;
-#if !defined(Q_WS_QPA)
- QRect geometry;
-#else
- QSize size;
-#endif //Q_WS_QPA
- QRegion staticContents;
- QList<QImage*> bufferImages;
-};
-
-/*!
- \class QWindowSurface
- \since 4.3
- \internal
- \preliminary
- \ingroup qws qpa
-
- \brief The QWindowSurface class provides the drawing area for top-level
- windows.
-*/
-
-
-/*!
- \fn void QWindowSurface::beginPaint(const QRegion &region)
-
- This function is called before painting onto the surface begins,
- with the \a region in which the painting will occur.
-
- \sa endPaint(), paintDevice()
-*/
-
-/*!
- \fn void QWindowSurface::endPaint(const QRegion &region)
-
- This function is called after painting onto the surface has ended,
- with the \a region in which the painting was performed.
-
- \sa beginPaint(), paintDevice()
-*/
-
-/*!
- \fn void QWindowSurface::flush(QWidget *widget, const QRegion &region,
- const QPoint &offset)
-
- Flushes the given \a region from the specified \a widget onto the
- screen.
-
- Note that the \a offset parameter is currently unused.
-*/
-
-/*!
- \fn QPaintDevice* QWindowSurface::paintDevice()
-
- Implement this function to return the appropriate paint device.
-*/
-
-/*!
- Constructs an empty surface for the given top-level \a window.
-*/
-QWindowSurface::QWindowSurface(QWidget *window, bool setDefaultSurface)
- : d_ptr(new QWindowSurfacePrivate(window))
-{
- if (!QApplicationPrivate::runtime_graphics_system) {
- if(setDefaultSurface && window)
- window->setWindowSurface(this);
- }
-}
-
-/*!
- Destroys this surface.
-*/
-QWindowSurface::~QWindowSurface()
-{
- if (d_ptr->window)
- d_ptr->window->d_func()->extra->topextra->windowSurface = 0;
- delete d_ptr;
-}
-
-/*!
- Returns a pointer to the top-level window associated with this
- surface.
-*/
-QWidget* QWindowSurface::window() const
-{
- return d_ptr->window;
-}
-
-void QWindowSurface::beginPaint(const QRegion &)
-{
-}
-
-void QWindowSurface::endPaint(const QRegion &)
-{
-// QApplication::syncX();
- qDeleteAll(d_ptr->bufferImages);
- d_ptr->bufferImages.clear();
-}
-
-#if !defined(Q_WS_QPA)
-/*!
- Sets the currently allocated area to be the given \a rect.
-
- This function is called whenever area covered by the top-level
- window changes.
-
- \sa geometry()
-*/
-void QWindowSurface::setGeometry(const QRect &rect)
-{
- d_ptr->geometry = rect;
-}
-
-/*!
- Returns the currently allocated area on the screen.
-*/
-QRect QWindowSurface::geometry() const
-{
- return d_ptr->geometry;
-}
-#else
-
-/*!
- Sets the size of the windowsurface to be \a size.
-
- \sa size()
-*/
-void QWindowSurface::resize(const QSize &size)
-{
- d_ptr->size = size;
-}
-
-/*!
- Returns the current size of the windowsurface.
-*/
-QSize QWindowSurface::size() const
-{
- return d_ptr->size;
-}
-#endif //Q_WS_QPA
-
-/*!
- Scrolls the given \a area \a dx pixels to the right and \a dy
- downward; both \a dx and \a dy may be negative.
-
- Returns true if the area was scrolled successfully; false otherwise.
-*/
-bool QWindowSurface::scroll(const QRegion &area, int dx, int dy)
-{
- Q_UNUSED(area);
- Q_UNUSED(dx);
- Q_UNUSED(dy);
-
- return false;
-}
-
-/*!
- Returns a QImage pointer which represents the actual buffer the \a widget
- is drawn into or 0 if this is unavailable.
-
- You must call beginPaint() before you call this function and the returned
- pointer is only valid until endPaint() is called.
-*/
-QImage* QWindowSurface::buffer(const QWidget *widget)
-{
- if (widget->window() != window())
- return 0;
-
- QPaintDevice *pdev = paintDevice();
- if (!pdev || pdev->devType() != QInternal::Image)
- return 0;
-
- const QPoint off = offset(widget);
- QImage *img = static_cast<QImage*>(pdev);
-
- QRect rect(off, widget->size());
- rect &= QRect(QPoint(), img->size());
-
- if (rect.isEmpty())
- return 0;
-
- img = new QImage(img->scanLine(rect.y()) + rect.x() * img->depth() / 8,
- rect.width(), rect.height(),
- img->bytesPerLine(), img->format());
- d_ptr->bufferImages.append(img);
-
- return img;
-}
-
-/*!
- Returns a QPixmap generated from the part of the backing store
- corresponding to \a widget. Returns a null QPixmap if an error
- occurs. The contents of the pixmap are only defined for the regions
- of \a widget that have received paint events since the last resize
- of the backing store.
-
- If \a rectangle is a null rectangle (the default), the entire widget
- is grabbed. Otherwise, the grabbed area is limited to \a rectangle.
-
- The default implementation uses QWindowSurface::buffer().
-
- \sa QPixmap::grabWidget()
-*/
-QPixmap QWindowSurface::grabWidget(const QWidget *widget, const QRect &rectangle) const
-{
- QPixmap result;
-
- if (widget->window() != window())
- return result;
-
- const QImage *img = const_cast<QWindowSurface *>(this)->buffer(widget->window());
-
- if (!img || img->isNull())
- return result;
-
- QRect rect = rectangle.isEmpty() ? widget->rect() : (widget->rect() & rectangle);
-
- rect.translate(offset(widget) - offset(widget->window()));
- rect &= QRect(QPoint(), img->size());
-
- if (rect.isEmpty())
- return result;
-
- QImage subimg(img->scanLine(rect.y()) + rect.x() * img->depth() / 8,
- rect.width(), rect.height(),
- img->bytesPerLine(), img->format());
- subimg.detach(); //### expensive -- maybe we should have a real SubImage that shares reference count
-
- result = QPixmap::fromImage(subimg);
- return result;
-}
-
-/*!
- Returns the offset of \a widget in the coordinates of this
- window surface.
- */
-QPoint QWindowSurface::offset(const QWidget *widget) const
-{
- QWidget *window = d_ptr->window;
- QPoint offset = widget->mapTo(window, QPoint());
-#ifdef Q_WS_QWS
- offset += window->geometry().topLeft() - window->frameGeometry().topLeft();
-#endif
- return offset;
-}
-
-/*!
- \fn QRect QWindowSurface::rect(const QWidget *widget) const
-
- Returns the rectangle for \a widget in the coordinates of this
- window surface.
-*/
-
-void QWindowSurface::setStaticContents(const QRegion &region)
-{
- d_ptr->staticContents = region;
-}
-
-QRegion QWindowSurface::staticContents() const
-{
- return d_ptr->staticContents;
-}
-
-bool QWindowSurface::hasStaticContents() const
-{
- return hasFeature(QWindowSurface::StaticContents) && !d_ptr->staticContents.isEmpty();
-}
-
-QWindowSurface::WindowSurfaceFeatures QWindowSurface::features() const
-{
- return PartialUpdates | PreservedContents;
-}
-
-#ifdef Q_WS_QPA
-#define Q_EXPORT_SCROLLRECT Q_GUI_EXPORT
-#else
-#define Q_EXPORT_SCROLLRECT
-#endif
-
-void Q_EXPORT_SCROLLRECT qt_scrollRectInImage(QImage &img, const QRect &rect, const QPoint &offset)
-{
- // make sure we don't detach
- uchar *mem = const_cast<uchar*>(const_cast<const QImage &>(img).bits());
-
- int lineskip = img.bytesPerLine();
- int depth = img.depth() >> 3;
-
- 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;
-
- if (r.top() < p.y()) {
- src = mem + r.bottom() * lineskip + r.left() * depth;
- dest = mem + (p.y() + r.height() - 1) * lineskip + p.x() * depth;
- lineskip = -lineskip;
- } else {
- src = mem + r.top() * lineskip + r.left() * depth;
- dest = mem + p.y() * lineskip + p.x() * depth;
- }
-
- const int w = r.width();
- int h = r.height();
- const int bytes = w * depth;
-
- // overlapping segments?
- if (offset.y() == 0 && qAbs(offset.x()) < w) {
- do {
- ::memmove(dest, src, bytes);
- dest += lineskip;
- src += lineskip;
- } while (--h);
- } else {
- do {
- ::memcpy(dest, src, bytes);
- dest += lineskip;
- src += lineskip;
- } while (--h);
- }
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/painting/qwindowsurface_mac.cpp b/src/gui/painting/qwindowsurface_mac.cpp
deleted file mode 100644
index ed794ae466..0000000000
--- a/src/gui/painting/qwindowsurface_mac.cpp
+++ /dev/null
@@ -1,139 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qwindowsurface_mac_p.h"
-
-#include <private/qt_mac_p.h>
-#include <private/qt_cocoa_helpers_mac_p.h>
-#include <QtGui/qwidget.h>
-
-QT_BEGIN_NAMESPACE
-
-struct QMacWindowSurfacePrivate
-{
- QWidget *widget;
- QPixmap device;
-};
-
-QMacWindowSurface::QMacWindowSurface(QWidget *widget)
- : QWindowSurface(widget), d_ptr(new QMacWindowSurfacePrivate)
-{
- d_ptr->widget = widget;
-}
-
-QMacWindowSurface::~QMacWindowSurface()
-{
- delete d_ptr;
-}
-
-QPaintDevice *QMacWindowSurface::paintDevice()
-{
- return &d_ptr->device;
-}
-
-void QMacWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint &offset)
-{
- Q_UNUSED(offset);
-
- // Get a context for the widget.
-#ifndef QT_MAC_USE_COCOA
- CGContextRef context;
- CGrafPtr port = GetWindowPort(qt_mac_window_for(widget));
- QDBeginCGContext(port, &context);
-#else
- extern CGContextRef qt_mac_graphicsContextFor(QWidget *);
- CGContextRef context = qt_mac_graphicsContextFor(widget);
-#endif
- CGContextRetain(context);
- CGContextSaveGState(context);
-
- // Flip context.
- CGContextTranslateCTM(context, 0, widget->height());
- CGContextScaleCTM(context, 1, -1);
-
- // Clip to region.
- const QVector<QRect> &rects = rgn.rects();
- for (int i = 0; i < rects.size(); ++i) {
- const QRect &rect = rects.at(i);
- CGContextAddRect(context, CGRectMake(rect.x(), rect.y(), rect.width(), rect.height()));
- }
- CGContextClip(context);
-
- // Draw the image onto the window.
- const CGRect dest = CGRectMake(0, 0, widget->width(), widget->height());
- const CGImageRef image = d_ptr->device.toMacCGImageRef();
- qt_mac_drawCGImage(context, &dest, image);
- CFRelease(image);
-
- // Restore context.
- CGContextRestoreGState(context);
-#ifndef QT_MAC_USE_COCOA
- QDEndCGContext(port, &context);
-#else
- CGContextFlush(context);
-#endif
- CGContextRelease(context);
-}
-
-void QMacWindowSurface::setGeometry(const QRect &rect)
-{
- QWindowSurface::setGeometry(rect);
- const QSize size = rect.size();
- if (d_ptr->device.size() != size)
- d_ptr->device = QPixmap(size);
-}
-
-bool QMacWindowSurface::scroll(const QRegion &area, int dx, int dy)
-{
- if (d_ptr->device.size().isNull())
- return false;
-
- QCFType<CGImageRef> image = d_ptr->device.toMacCGImageRef();
- const QRect rect(area.boundingRect());
- const CGRect dest = CGRectMake(rect.x(), rect.y(), rect.width(), rect.height());
- QCFType<CGImageRef> subimage = CGImageCreateWithImageInRect(image, dest);
- QCFType<CGContextRef> context = qt_mac_cg_context(&d_ptr->device);
- CGContextTranslateCTM(context, dx, dy);
- qt_mac_drawCGImage(context, &dest, subimage);
- return true;
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/painting/qwindowsurface_mac_p.h b/src/gui/painting/qwindowsurface_mac_p.h
deleted file mode 100644
index 05571646eb..0000000000
--- a/src/gui/painting/qwindowsurface_mac_p.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWINDOWSURFACE_MAC_P_H
-#define QWINDOWSURFACE_MAC_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <qglobal.h>
-#include "private/qwindowsurface_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class QPaintDevice;
-class QPoint;
-class QRegion;
-class QWidget;
-struct QMacWindowSurfacePrivate;
-
-class QMacWindowSurface : public QWindowSurface
-{
-public:
- QMacWindowSurface(QWidget *widget);
- ~QMacWindowSurface();
-
- QPaintDevice *paintDevice();
- void flush(QWidget *widget, const QRegion &region, const QPoint &offset);
- void setGeometry(const QRect &rect);
- bool scroll(const QRegion &area, int dx, int dy);
-
-private:
- QMacWindowSurfacePrivate *d_ptr;
-};
-
-QT_END_NAMESPACE
-
-#endif // QWINDOWSURFACE_MAC_P_H
diff --git a/src/gui/painting/qwindowsurface_p.h b/src/gui/painting/qwindowsurface_p.h
deleted file mode 100644
index 1e6529c788..0000000000
--- a/src/gui/painting/qwindowsurface_p.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWINDOWSURFACE_P_H
-#define QWINDOWSURFACE_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtGui/qwidget.h>
-
-QT_BEGIN_NAMESPACE
-
-class QPaintDevice;
-class QRegion;
-class QRect;
-class QPoint;
-class QImage;
-class QWindowSurfacePrivate;
-class QPlatformWindow;
-
-class Q_GUI_EXPORT QWindowSurface
-{
-public:
- enum WindowSurfaceFeature {
- PartialUpdates = 0x00000001, // Supports doing partial updates.
- PreservedContents = 0x00000002, // Supports doing flush without first doing a repaint.
- StaticContents = 0x00000004, // Supports having static content regions when being resized.
- AllFeatures = 0xffffffff // For convenience
- };
- Q_DECLARE_FLAGS(WindowSurfaceFeatures, WindowSurfaceFeature)
-
- QWindowSurface(QWidget *window, bool setDefaultSurface = true);
- virtual ~QWindowSurface();
-
- QWidget *window() const;
-
- virtual QPaintDevice *paintDevice() = 0;
-
- // 'widget' can be a child widget, in which case 'region' is in child widget coordinates and
- // offset is the (child) widget's offset in relation to the window surface. On QWS, 'offset'
- // can be larger than just the offset from the top-level widget as there may also be window
- // decorations which are painted into the window surface.
- virtual void flush(QWidget *widget, const QRegion &region, const QPoint &offset) = 0;
-#if !defined(Q_WS_QPA)
- virtual void setGeometry(const QRect &rect);
- QRect geometry() const;
-#else
- virtual void resize(const QSize &size);
- QSize size() const;
- inline QRect geometry() const { return QRect(QPoint(), size()); } //### cleanup before Qt 5
-#endif
-
- virtual bool scroll(const QRegion &area, int dx, int dy);
-
- virtual void beginPaint(const QRegion &);
- virtual void endPaint(const QRegion &);
-
- virtual QImage* buffer(const QWidget *widget);
- virtual QPixmap grabWidget(const QWidget *widget, const QRect& rectangle = QRect()) const;
-
- virtual QPoint offset(const QWidget *widget) const;
- inline QRect rect(const QWidget *widget) const;
-
- bool hasFeature(WindowSurfaceFeature feature) const;
- virtual WindowSurfaceFeatures features() const;
-
- void setStaticContents(const QRegion &region);
- QRegion staticContents() const;
-
-protected:
- bool hasStaticContents() const;
-
-private:
- QWindowSurfacePrivate *d_ptr;
-};
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QWindowSurface::WindowSurfaceFeatures)
-
-inline QRect QWindowSurface::rect(const QWidget *widget) const
-{
- return widget->rect().translated(offset(widget));
-}
-
-inline bool QWindowSurface::hasFeature(WindowSurfaceFeature feature) const
-{
- return (features() & feature) != 0;
-}
-
-QT_END_NAMESPACE
-
-#endif // QWINDOWSURFACE_P_H
diff --git a/src/gui/painting/qwindowsurface_qws.cpp b/src/gui/painting/qwindowsurface_qws.cpp
deleted file mode 100644
index c52f864b25..0000000000
--- a/src/gui/painting/qwindowsurface_qws.cpp
+++ /dev/null
@@ -1,1433 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qwindowsurface_qws_p.h"
-#include <qwidget.h>
-#include <qscreen_qws.h>
-#include <qwsmanager_qws.h>
-#include <qapplication.h>
-#include <qwsdisplay_qws.h>
-#include <qrgb.h>
-#include <qpaintengine.h>
-#include <qdesktopwidget.h>
-#include <private/qapplication_p.h>
-#include <private/qwsdisplay_qws_p.h>
-#include <private/qwidget_p.h>
-#include <private/qwsmanager_p.h>
-#include <private/qwslock_p.h>
-#include <private/qbackingstore_p.h>
-#include <stdio.h>
-
-QT_BEGIN_NAMESPACE
-
-#ifdef Q_BACKINGSTORE_SUBSURFACES
-
-typedef QMap<int, QWSWindowSurface*> SurfaceMap;
-Q_GLOBAL_STATIC(SurfaceMap, winIdToSurfaceMap);
-
-QWSWindowSurface* qt_findWindowSurface(int winId)
-{
- return winIdToSurfaceMap()->value(winId);
-}
-
-static void qt_insertWindowSurface(int winId, QWSWindowSurface *surface)
-{
- if (!surface)
- winIdToSurfaceMap()->remove(winId);
- else
- winIdToSurfaceMap()->insert(winId, surface);
-}
-
-#endif // Q_BACKINGSTORE_SUBSURFACES
-
-inline bool isWidgetOpaque(const QWidget *w)
-{
- return w->d_func()->isOpaque && !w->testAttribute(Qt::WA_TranslucentBackground);
-}
-
-static inline QScreen *getScreen(const QWidget *w)
-{
- const QList<QScreen*> subScreens = qt_screen->subScreens();
- if (subScreens.isEmpty())
- return qt_screen;
-
- const int screen = QApplication::desktop()->screenNumber(w);
-
- return qt_screen->subScreens().at(screen < 0 ? 0 : screen);
-}
-
-static int bytesPerPixel(QImage::Format format)
-{
- switch (format) {
- case QImage::Format_Invalid:
- return 0;
-#ifndef QT_NO_DEBUG
- case QImage::Format_Mono:
- case QImage::Format_MonoLSB:
- qFatal("QWSWindowSurface: Invalid backingstore format: %i",
- int(format));
-#endif
- case QImage::Format_Indexed8:
- return 1;
- case QImage::Format_RGB32:
- case QImage::Format_ARGB32:
- case QImage::Format_ARGB32_Premultiplied:
- return 4;
- case QImage::Format_RGB16:
- case QImage::Format_RGB555:
- case QImage::Format_RGB444:
- case QImage::Format_ARGB4444_Premultiplied:
- return 2;
- case QImage::Format_ARGB8565_Premultiplied:
- case QImage::Format_ARGB8555_Premultiplied:
- case QImage::Format_ARGB6666_Premultiplied:
- case QImage::Format_RGB666:
- case QImage::Format_RGB888:
- return 3;
- default:
-#ifndef QT_NO_DEBUG
- qFatal("QWSWindowSurface: Invalid backingstore format: %i",
- int(format));
-#endif
- return 0;
- }
-}
-
-static inline int nextMulOf4(int n)
-{
- return ((n + 3) & 0xfffffffc);
-}
-
-static inline void setImageMetrics(QImage &img, QWidget *window) {
- QScreen *myScreen = getScreen(window);
- if (myScreen) {
- int dpmx = myScreen->width()*1000 / myScreen->physicalWidth();
- int dpmy = myScreen->height()*1000 / myScreen->physicalHeight();
- img.setDotsPerMeterX(dpmx);
- img.setDotsPerMeterY(dpmy);
- }
-}
-
-void QWSWindowSurface::invalidateBuffer()
-{
-
- QWidget *win = window();
- if (win) {
- win->d_func()->invalidateBuffer(win->rect());
-#ifndef QT_NO_QWS_MANAGER
- QTLWExtra *topextra = win->d_func()->extra->topextra;
- QWSManager *manager = topextra->qwsManager;
- if (manager)
- manager->d_func()->dirtyRegion(QDecoration::All,
- QDecoration::Normal);
-#endif
- }
-}
-
-QWSWindowSurfacePrivate::QWSWindowSurfacePrivate()
- : flags(0),
-#ifdef QT_QWS_CLIENTBLIT
- directId(-1),
-#endif
- winId(0)
-{
-}
-
-void QWSWindowSurfacePrivate::setWinId(int id)
-{
- winId = id;
-}
-
-int QWSWindowSurface::winId() const
-{
- // XXX: the widget winId may change during the lifetime of the widget!!!
-
- const QWidget *win = window();
- if (win && win->isWindow())
- return win->internalWinId();
-
-#ifdef Q_BACKINGSTORE_SUBSURFACES
- if (!d_ptr->winId) {
- QWSWindowSurface *that = const_cast<QWSWindowSurface*>(this);
- QWSDisplay *display = QWSDisplay::instance();
- const int id = display->takeId();
- qt_insertWindowSurface(id, that);
- that->d_ptr->winId = id;
-
- if (win)
- display->nameRegion(id, win->objectName(), win->windowTitle());
- else
- display->nameRegion(id, QString(), QString());
-
- display->setAltitude(id, 1, true); // XXX
- }
-#endif
-
- return d_ptr->winId;
-}
-
-void QWSWindowSurface::setWinId(int id)
-{
- d_ptr->winId = id;
-}
-
-/*!
- \class QWSWindowSurface
- \since 4.2
- \ingroup qws
- \preliminary
- \internal
-
- \brief The QWSWindowSurface class provides the drawing area for top-level
- windows in Qt for Embedded Linux.
-
- Note that this class is only available in Qt for Embedded Linux.
-
- In \l{Qt for Embedded Linux}, the default behavior is for each client to
- render its widgets into memory while the server is responsible for
- putting the contents of the memory onto the
- screen. QWSWindowSurface is used by the window system to implement
- the associated memory allocation.
-
- When a screen update is required, the server runs through all the
- top-level windows that intersect with the region that is about to
- be updated, and ensures that the associated clients have updated
- their memory buffer. Then the server uses the screen driver to
- copy the content of the memory to the screen. To locate the
- relevant parts of memory, the driver is provided with the list of
- top-level windows that intersect with the given region. Associated
- with each of the top-level windows there is a window surface
- representing the drawing area of the window.
-
- When deriving from the QWSWindowSurface class, e.g., when adding
- an \l {Adding an Accelerated Graphics Driver to Qt for Embedded Linux}
- {accelerated graphics driver}, there are several pure virtual
- functions that must be implemented. In addition, QWSWindowSurface
- provides several virtual functions that can be reimplemented to
- customize the drawing process.
-
- \tableofcontents
-
- \section1 Pure Virtual Functions
-
- There are in fact two window surface instances for each top-level
- window; one used by the application when drawing a window, and
- another used by the server application to perform window
- compositioning. Implement the attach() to create the server-side
- representation of the surface. The data() function must be
- implemented to provide the required data.
-
- Implement the key() function to uniquely identify the surface
- class, and the isValid() function to determine is a surface
- corresponds to a given widget.
-
- The geometry() function must be implemented to let the window
- system determine the area required by the window surface
- (QWSWindowSurface also provides a corresponding virtual
- setGeometry() function that is called whenever the area necessary
- for the top-level window to be drawn, changes). The image()
- function is called by the window system during window
- compositioning, and must be implemented to return an image of the
- top-level window.
-
- Finally, the paintDevice() function must be implemented to return
- the appropriate paint device, and the scroll() function must be
- implemented to scroll the given region of the surface the given
- number of pixels.
-
- \section1 Virtual Functions
-
- When painting onto the surface, the window system will always call
- the beginPaint() function before any painting operations are
- performed. Likewise the endPaint() function is automatically
- called when the painting is done. Reimplement the painterOffset()
- function to alter the offset that is applied when drawing.
-
- The window system uses the flush() function to put a given region
- of the widget onto the screen, and the release() function to
- deallocate the screen region corresponding to this window surface.
-
- \section1 Other Members
-
- QWSWindowSurface provides the window() function returning a
- pointer to the top-level window the surface is representing. The
- currently visible region of the associated widget can be retrieved
- and set using the clipRegion() and setClipRegion() functions,
- respectively.
-
- When the window system performs the window compositioning, it uses
- the SurfaceFlag enum describing the surface content. The currently
- set surface flags can be retrieved and altered using the
- surfaceFlags() and setSurfaceFlags() functions. In addition,
- QWSWindowSurface provides the isBuffered(), isOpaque() and
- isRegionReserved() convenience functions.
-
- \sa {Qt for Embedded Linux Architecture#Drawing on Screen}{Qt for
- Embedded Linux Architecture}
-*/
-
-/*!
- \enum QWSWindowSurface::SurfaceFlag
-
- This enum is used to describe the window surface's contents. It
- is used by the screen driver to handle region allocation and
- composition.
-
- \value RegionReserved The surface contains a reserved area. Once
- allocated, a reserved area can not not be changed by the window
- system, i.e., no other widgets can be drawn on top of this.
-
- \value Buffered
- The surface is in a memory area which is not part of a framebuffer.
- (A top-level window with QWidget::windowOpacity() other than 1.0 must use
- a buffered surface in order to making blending with the background work.)
-
- \value Opaque
- The surface contains only opaque pixels.
-
- \sa surfaceFlags(), setSurfaceFlags()
-*/
-
-/*!
- \fn bool QWSWindowSurface::isValid() const
- \since 4.3
-
- Implement this function to return true if the surface is a valid
- surface for the given top-level \a window; otherwise return
- false.
-
- \sa window(), key()
-*/
-
-/*!
- \fn QString QWSWindowSurface::key() const
-
- Implement this function to return a string that uniquely
- identifies the class of this surface.
-
- \sa window(), isValid()
-*/
-
-/*!
- \fn QByteArray QWSWindowSurface::permanentState() const
- \since 4.3
-
- Implement this function to return the data required for creating a
- server-side representation of the surface.
-
- \sa attach()
-*/
-
-/*!
- \fn void QWSWindowSurface::setPermanentState(const QByteArray &data)
- \since 4.3
-
- Implement this function to attach a server-side surface instance
- to the corresponding client side instance using the given \a
- data. Return true if successful; otherwise return false.
-
- \sa data()
-*/
-
-/*!
- \fn const QImage QWSWindowSurface::image() const
-
- Implement this function to return an image of the top-level window.
-
- \sa geometry()
-*/
-
-/*!
- \fn bool QWSWindowSurface::isRegionReserved() const
-
- Returns true if the QWSWindowSurface::RegionReserved is set; otherwise
- returns false.
-
- \sa surfaceFlags()
-*/
-
-/*!
- \fn bool QWSWindowSurface::isBuffered() const
-
- Returns true if the QWSWindowSurface::Buffered is set; otherwise returns false.
-
- \sa surfaceFlags()
-*/
-
-/*!
- \fn bool QWSWindowSurface::isOpaque() const
-
- Returns true if the QWSWindowSurface::Opaque is set; otherwise
- returns false.
-
- \sa surfaceFlags()
-*/
-
-
-/*!
- Constructs an empty surface.
-*/
-QWSWindowSurface::QWSWindowSurface()
- : QWindowSurface(0), d_ptr(new QWSWindowSurfacePrivate)
-{
-}
-
-/*!
- Constructs an empty surface for the given top-level \a widget.
-*/
-QWSWindowSurface::QWSWindowSurface(QWidget *widget)
- : QWindowSurface(widget), d_ptr(new QWSWindowSurfacePrivate)
-{
-}
-
-QWSWindowSurface::~QWSWindowSurface()
-{
-#ifdef Q_BACKINGSTORE_SUBSURFACES
- if (d_ptr->winId)
- winIdToSurfaceMap()->remove(d_ptr->winId);
-#endif
-
- delete d_ptr;
-}
-
-/*!
- Returns the offset to be used when painting.
-
- \sa paintDevice()
-*/
-QPoint QWSWindowSurface::painterOffset() const
-{
- const QWidget *w = window();
- if (!w)
- return QPoint();
- return w->geometry().topLeft() - w->frameGeometry().topLeft();
-}
-
-void QWSWindowSurface::beginPaint(const QRegion &)
-{
- lock();
-}
-
-void QWSWindowSurface::endPaint(const QRegion &)
-{
- unlock();
-}
-
-// XXX: documentation!!!
-QByteArray QWSWindowSurface::transientState() const
-{
- return QByteArray();
-}
-
-QByteArray QWSWindowSurface::permanentState() const
-{
- return QByteArray();
-}
-
-void QWSWindowSurface::setTransientState(const QByteArray &state)
-{
- Q_UNUSED(state);
-}
-
-void QWSWindowSurface::setPermanentState(const QByteArray &state)
-{
- Q_UNUSED(state);
-}
-
-bool QWSWindowSurface::lock(int timeout)
-{
- Q_UNUSED(timeout);
- return true;
-}
-
-void QWSWindowSurface::unlock()
-{
-}
-
-#ifdef QT_QWS_CLIENTBLIT
-/*! \internal */
-const QRegion QWSWindowSurface::directRegion() const
-{
- return d_ptr->direct;
-}
-
-/*! \internal */
-int QWSWindowSurface::directRegionId() const
-{
- return d_ptr->directId;
-}
-
-/*! \internal */
-void QWSWindowSurface::setDirectRegion(const QRegion &r, int id)
-{
- d_ptr->direct = r;
- d_ptr->directId = id;
-}
-#endif
-
-/*!
- Returns the region currently visible on the screen.
-
- \sa setClipRegion()
-*/
-const QRegion QWSWindowSurface::clipRegion() const
-{
- return d_ptr->clip;
-}
-
-/*!
- Sets the region currently visible on the screen to be the given \a
- clip region.
-
- \sa clipRegion()
-*/
-void QWSWindowSurface::setClipRegion(const QRegion &clip)
-{
- if (clip == d_ptr->clip)
- return;
-
- QRegion expose = (clip - d_ptr->clip);
- d_ptr->clip = clip;
-
- if (expose.isEmpty() || clip.isEmpty())
- return; // No repaint or flush required.
-
- QWidget *win = window();
- if (!win)
- return;
-
- if (isBuffered()) {
- // No repaint required. Flush exposed area via the backing store.
- win->d_func()->syncBackingStore(expose);
- return;
- }
-
-#ifndef QT_NO_QWS_MANAGER
- // Invalidate exposed decoration area.
- if (win && win->isWindow()) {
- QTLWExtra *topextra = win->d_func()->extra->topextra;
- if (QWSManager *manager = topextra->qwsManager) {
- QRegion decorationExpose(manager->region());
- decorationExpose.translate(-win->geometry().topLeft());
- decorationExpose &= expose;
- if (!decorationExpose.isEmpty()) {
- expose -= decorationExpose;
- manager->d_func()->dirtyRegion(QDecoration::All, QDecoration::Normal, decorationExpose);
- }
- }
- }
-#endif
-
- // Invalidate exposed widget area.
- win->d_func()->invalidateBuffer(expose);
-}
-
-/*!
- Returns the surface flags describing the contents of this surface.
-
- \sa isBuffered(), isOpaque(), isRegionReserved()
-*/
-QWSWindowSurface::SurfaceFlags QWSWindowSurface::surfaceFlags() const
-{
- return d_ptr->flags;
-}
-
-/*!
- Sets the surface flags describing the contents of this surface, to
- be the given \a flags.
-
- \sa surfaceFlags()
-*/
-void QWSWindowSurface::setSurfaceFlags(SurfaceFlags flags)
-{
- d_ptr->flags = flags;
-}
-
-void QWSWindowSurface::setGeometry(const QRect &rect)
-{
- QRegion mask = rect;
-
- const QWidget *win = window();
- if (win) {
-#ifndef QT_NO_QWS_MANAGER
- if (win->isWindow()) {
- QTLWExtra *topextra = win->d_func()->extra->topextra;
- QWSManager *manager = topextra->qwsManager;
-
- if (manager) {
- // The frame geometry is the bounding rect of manager->region,
- // which could be too much, so we need to clip.
- mask &= (manager->region() + win->geometry());
- }
- }
-#endif
-
- const QRegion winMask = win->mask();
- if (!winMask.isEmpty())
- mask &= winMask.translated(win->geometry().topLeft());
- }
-
- setGeometry(rect, mask);
-}
-
-void QWSWindowSurface::setGeometry(const QRect &rect, const QRegion &mask)
-{
- if (rect == geometry()) // XXX: && mask == prevMask
- return;
-
- const bool isResize = rect.size() != geometry().size();
- const bool needsRepaint = isResize || !isBuffered();
-
- QWindowSurface::setGeometry(rect);
-
- const QRegion region = mask & rect;
- QWidget *win = window();
- // Only request regions for widgets visible on the screen.
- // (Added the !win check for compatibility reasons, because
- // there was no "if (win)" check before).
- const bool requestQWSRegion = !win || !win->testAttribute(Qt::WA_DontShowOnScreen);
- if (requestQWSRegion)
- QWidget::qwsDisplay()->requestRegion(winId(), key(), permanentState(), region);
-
- if (needsRepaint)
- invalidateBuffer();
-
- if (!requestQWSRegion) {
- // We didn't request a region, hence we won't get a QWSRegionEvent::Allocation
- // event back from the server so we set the clip directly. We have to
- // do this after the invalidateBuffer() call above, as it might trigger a
- // backing store sync, resulting in too many update requests.
- setClipRegion(region);
- }
-}
-
-static inline void flushUpdate(QWidget *widget, const QRegion &region,
- const QPoint &offset)
-{
-#ifdef QT_NO_PAINT_DEBUG
- Q_UNUSED(widget);
- Q_UNUSED(region);
- Q_UNUSED(offset);
-#else
- static int delay = -1;
-
- if (delay == -1)
- delay = qgetenv("QT_FLUSH_UPDATE").toInt() * 10;
-
- if (delay == 0)
- return;
-
- static QWSYellowSurface surface(true);
- surface.setDelay(delay);
- surface.flush(widget, region, offset);
-#endif // QT_NO_PAINT_DEBUG
-}
-
-void QWSWindowSurface::flush(QWidget *widget, const QRegion &region,
- const QPoint &offset)
-{
- const QWidget *win = window();
- if (!win)
- return;
-
-#ifndef QT_NO_GRAPHICSVIEW
- QWExtra *extra = win->d_func()->extra;
- if (extra && extra->proxyWidget)
- return;
-#endif //QT_NO_GRAPHICSVIEW
-
- Q_UNUSED(offset);
-
- const bool opaque = isOpaque();
-#ifdef QT_QWS_DISABLE_FLUSHCLIPPING
- QRegion toFlush = region;
-#else
- QRegion toFlush = region & d_ptr->clip;
-#endif
-
- if (!toFlush.isEmpty()) {
- flushUpdate(widget, toFlush, QPoint(0, 0));
- QPoint globalZero = win->mapToGlobal(QPoint(0, 0));
- toFlush.translate(globalZero);
-
-#ifdef QT_QWS_CLIENTBLIT
- bool needRepaint = true;
- if (opaque) {
- QScreen* widgetScreen = getScreen(widget);
- if (widgetScreen->supportsBlitInClients()) {
-
- QWSDisplay::grab();
- if(directRegion().intersected(toFlush) == toFlush) {
- QPoint translate = -globalZero + painterOffset() + geometry().topLeft();
- QRegion flushRegion = toFlush.translated(translate);
- widgetScreen->blit(image(), geometry().topLeft(), flushRegion);
- widgetScreen->setDirty(toFlush.boundingRect());
- needRepaint = false;
- }
- QWSDisplay::ungrab();
- }
- }
-
- if(needRepaint)
-#endif
- win->qwsDisplay()->repaintRegion(winId(), win->windowFlags(), opaque, toFlush);
- }
-}
-
-/*!
- Move the surface with the given \a offset.
-
- A subclass may reimplement this function to enable accelerated window move.
- It must return true if the move was successful and no repaint is necessary,
- false otherwise.
-
- The default implementation updates the QWindowSurface geometry and
- returns true if the surface is buffered; false otherwise.
-
- This function is called by the window system on the client instance.
-
- \sa isBuffered()
-*/
-bool QWSWindowSurface::move(const QPoint &offset)
-{
- QWindowSurface::setGeometry(geometry().translated(offset));
- return isBuffered();
-}
-
-/*!
- Move the surface with the given \a offset.
-
- The new visible region after the window move is given by \a newClip
- in screen coordinates.
-
- A subclass may reimplement this function to enable accelerated window move.
- The returned region indicates the area that still needs to be composed
- on the screen.
-
- The default implementation updates the QWindowSurface geometry and
- returns the union of the old and new geometry.
-
- This function is called by the window system on the server instance.
-*/
-QRegion QWSWindowSurface::move(const QPoint &offset, const QRegion &newClip)
-{
- const QRegion oldGeometry = geometry();
- QWindowSurface::setGeometry(geometry().translated(offset));
- return oldGeometry + newClip;
-}
-
-void QWSWindowSurface::releaseSurface()
-{
-}
-
-bool QWSMemorySurface::lock(int timeout)
-{
- Q_UNUSED(timeout);
-#ifndef QT_NO_QWS_MULTIPROCESS
- if (memlock && !memlock->lock(QWSLock::BackingStore))
- return false;
-#endif
-#ifndef QT_NO_THREAD
- threadLock.lock();
-#endif
- return true;
-}
-
-void QWSMemorySurface::unlock()
-{
-#ifndef QT_NO_THREAD
- threadLock.unlock();
-#endif
-#ifndef QT_NO_QWS_MULTIPROCESS
- if (memlock)
- memlock->unlock(QWSLock::BackingStore);
-#endif
-}
-
-QWSMemorySurface::QWSMemorySurface()
- : QWSWindowSurface()
-#ifndef QT_NO_QWS_MULTIPROCESS
- , memlock(0)
-#endif
-{
- setSurfaceFlags(Buffered);
-}
-
-QWSMemorySurface::QWSMemorySurface(QWidget *w)
- : QWSWindowSurface(w)
-{
- SurfaceFlags flags = Buffered;
- if (isWidgetOpaque(w))
- flags |= Opaque;
- setSurfaceFlags(flags);
-
-#ifndef QT_NO_QWS_MULTIPROCESS
- memlock = QWSDisplay::Data::getClientLock();
-#endif
-}
-
-QWSMemorySurface::~QWSMemorySurface()
-{
-}
-
-
-QImage::Format
-QWSMemorySurface::preferredImageFormat(const QWidget *widget) const
-{
- QScreen *screen = getScreen(widget);
- const int depth = screen->depth();
- const bool opaque = isWidgetOpaque(widget);
-
- if (!opaque) {
- if (depth <= 12)
- return QImage::Format_ARGB4444_Premultiplied;
- else if (depth <= 15)
- return QImage::Format_ARGB8555_Premultiplied;
- else if (depth <= 16)
- return QImage::Format_ARGB8565_Premultiplied;
- else if (depth <= 18)
- return QImage::Format_ARGB6666_Premultiplied;
- else
- return QImage::Format_ARGB32_Premultiplied;
- }
-
- QImage::Format format = screen->pixelFormat();
- if (format > QImage::Format_Indexed8) // ### assumes all new image formats supports a QPainter
- return format;
-
- if (depth <= 12)
- return QImage::Format_RGB444;
- else if (depth <= 15)
- return QImage::Format_RGB555;
- else if (depth <= 16)
- return QImage::Format_RGB16;
- else if (depth <= 18)
- return QImage::Format_RGB666;
- else if (depth <= 24)
- return QImage::Format_RGB888;
- else
- return QImage::Format_ARGB32_Premultiplied;
-}
-
-#ifndef QT_NO_QWS_MULTIPROCESS
-void QWSMemorySurface::setLock(int lockId)
-{
- if (memlock && memlock->id() == lockId)
- return;
- delete memlock;
- memlock = (lockId == -1 ? 0 : new QWSLock(lockId));
- return;
-}
-#endif // QT_NO_QWS_MULTIPROCESS
-
-bool QWSMemorySurface::isValid() const
-{
- if (img.isNull())
- return true;
-
- const QWidget *win = window();
- if (preferredImageFormat(win) != img.format())
- return false;
-
- if (isOpaque() != isWidgetOpaque(win)) // XXX: use QWidgetPrivate::isOpaque()
- return false;
-
- return true;
-}
-
-// ### copied from qwindowsurface_raster.cpp -- should be cross-platform
-void QWSMemorySurface::beginPaint(const QRegion &rgn)
-{
- if (!isWidgetOpaque(window())) {
- QPainter p(&img);
- p.setCompositionMode(QPainter::CompositionMode_Source);
- const QVector<QRect> rects = rgn.rects();
- const QColor blank = Qt::transparent;
- for (QVector<QRect>::const_iterator it = rects.begin(); it != rects.end(); ++it) {
- QRect r = *it;
-#ifdef Q_BACKINGSTORE_SUBSURFACES
- r.translate(painterOffset());
-#endif
- p.fillRect(r, blank);
- }
- }
- QWSWindowSurface::beginPaint(rgn);
-}
-
-// from qwindowsurface.cpp
-extern void qt_scrollRectInImage(QImage &img, const QRect &rect, const QPoint &offset);
-
-bool QWSMemorySurface::scroll(const QRegion &area, int dx, int dy)
-{
- const QVector<QRect> rects = area.rects();
- for (int i = 0; i < rects.size(); ++i)
- qt_scrollRectInImage(img, rects.at(i), QPoint(dx, dy));
-
- return true;
-}
-
-QPoint QWSMemorySurface::painterOffset() const
-{
- const QWidget *w = window();
- if (!w)
- return QPoint();
-
- if (w->mask().isEmpty())
- return QWSWindowSurface::painterOffset();
-
- const QRegion region = w->mask()
- & w->frameGeometry().translated(-w->geometry().topLeft());
- return -region.boundingRect().topLeft();
-}
-
-QWSLocalMemSurface::QWSLocalMemSurface()
- : QWSMemorySurface(), mem(0), memsize(0)
-{
-}
-
-QWSLocalMemSurface::QWSLocalMemSurface(QWidget *w)
- : QWSMemorySurface(w), mem(0), memsize(0)
-{
-}
-
-QWSLocalMemSurface::~QWSLocalMemSurface()
-{
- if (memsize)
- delete[] mem;
-}
-
-void QWSLocalMemSurface::setGeometry(const QRect &rect)
-{
- QSize size = rect.size();
-
- QWidget *win = window();
- if (win && !win->mask().isEmpty()) {
- const QRegion region = win->mask()
- & rect.translated(-win->geometry().topLeft());
- size = region.boundingRect().size();
- }
-
- uchar *deleteLater = 0;
- // In case of a Hide event we need to delete the memory after sending the
- // event to the server in order to let the server animate the event.
- if (size.isEmpty()) {
- deleteLater = mem;
- mem = 0;
- }
-
- if (img.size() != size) {
- delete[] mem;
- if (size.isEmpty()) {
- mem = 0;
- img = QImage();
- } else {
- const QImage::Format format = preferredImageFormat(win);
- const int bpl = nextMulOf4(bytesPerPixel(format) * size.width());
- const int memsize = bpl * size.height();
- mem = new uchar[memsize];
- img = QImage(mem, size.width(), size.height(), bpl, format);
- setImageMetrics(img, win);
- }
- }
-
- QWSWindowSurface::setGeometry(rect);
- delete[] deleteLater;
-}
-
-QByteArray QWSLocalMemSurface::permanentState() const
-{
- QByteArray array;
- array.resize(sizeof(uchar*) + 3 * sizeof(int) +
- sizeof(SurfaceFlags));
-
- char *ptr = array.data();
-
- *reinterpret_cast<uchar**>(ptr) = mem;
- ptr += sizeof(uchar*);
-
- reinterpret_cast<int*>(ptr)[0] = img.width();
- reinterpret_cast<int*>(ptr)[1] = img.height();
- ptr += 2 * sizeof(int);
-
- *reinterpret_cast<int *>(ptr) = img.format();
- ptr += sizeof(int);
-
- *reinterpret_cast<SurfaceFlags*>(ptr) = surfaceFlags();
-
- return array;
-}
-
-void QWSLocalMemSurface::setPermanentState(const QByteArray &data)
-{
- int width;
- int height;
- QImage::Format format;
- SurfaceFlags flags;
-
- const char *ptr = data.constData();
-
- mem = *reinterpret_cast<uchar* const*>(ptr);
- ptr += sizeof(uchar*);
-
- width = reinterpret_cast<const int*>(ptr)[0];
- height = reinterpret_cast<const int*>(ptr)[1];
- ptr += 2 * sizeof(int);
-
- format = QImage::Format(*reinterpret_cast<const int*>(ptr));
- ptr += sizeof(int);
-
- flags = *reinterpret_cast<const SurfaceFlags*>(ptr);
-
- const int bpl = nextMulOf4(bytesPerPixel(format) * width);
- QWSMemorySurface::img = QImage(mem, width, height, bpl, format);
- setSurfaceFlags(flags);
-}
-
-void QWSLocalMemSurface::releaseSurface()
-{
- mem = 0;
- img = QImage();
-}
-
-#ifndef QT_NO_QWS_MULTIPROCESS
-
-QWSSharedMemSurface::QWSSharedMemSurface()
- : QWSMemorySurface()
-{
-}
-
-QWSSharedMemSurface::QWSSharedMemSurface(QWidget *widget)
- : QWSMemorySurface(widget)
-{
-}
-
-QWSSharedMemSurface::~QWSSharedMemSurface()
-{
- // mem.detach() is done automatically by ~QSharedMemory
-}
-
-bool QWSSharedMemSurface::setMemory(int memId)
-{
- if (mem.id() == memId)
- return true;
-
- mem.detach();
- if (!mem.attach(memId)) {
- perror("QWSSharedMemSurface: attaching to shared memory");
- qCritical("QWSSharedMemSurface: Error attaching to"
- " shared memory 0x%x", memId);
- return false;
- }
-
- return true;
-}
-
-#ifdef QT_QWS_CLIENTBLIT
-void QWSSharedMemSurface::setDirectRegion(const QRegion &r, int id)
-{
- QWSMemorySurface::setDirectRegion(r, id);
- if(mem.address())
- *(uint *)mem.address() = id;
-}
-
-const QRegion QWSSharedMemSurface::directRegion() const
-{
- QWSSharedMemory *cmem = const_cast<QWSSharedMemory *>(&mem);
- if (cmem->address() && ((int*)cmem->address())[0] == directRegionId())
- return QWSMemorySurface::directRegion();
- else
- return QRegion();
-}
-#endif
-
-void QWSSharedMemSurface::setPermanentState(const QByteArray &data)
-{
- int memId;
- int width;
- int height;
- int lockId;
- QImage::Format format;
- SurfaceFlags flags;
-
- const int *ptr = reinterpret_cast<const int*>(data.constData());
-
- memId = ptr[0];
- width = ptr[1];
- height = ptr[2];
- lockId = ptr[3];
- format = QImage::Format(ptr[4]);
- flags = SurfaceFlags(ptr[5]);
-
- setSurfaceFlags(flags);
- setMemory(memId);
- setLock(lockId);
-
-#ifdef QT_QWS_CLIENTBLIT
- uchar *base = static_cast<uchar*>(mem.address()) + sizeof(uint);
-#else
- uchar *base = static_cast<uchar*>(mem.address());
-#endif
- const int bpl = nextMulOf4(bytesPerPixel(format) * width);
- QWSMemorySurface::img = QImage(base, width, height, bpl, format);
-}
-
-void QWSSharedMemSurface::setGeometry(const QRect &rect)
-{
- const QSize size = rect.size();
- if (img.size() != size) {
- if (size.isEmpty()) {
- mem.detach();
- img = QImage();
- } else {
- mem.detach();
-
- QWidget *win = window();
- const QImage::Format format = preferredImageFormat(win);
- const int bpl = nextMulOf4(bytesPerPixel(format) * size.width());
-#ifdef QT_QWS_CLIENTBLIT
- const int imagesize = bpl * size.height() + sizeof(uint);
-#else
- const int imagesize = bpl * size.height();
-#endif
- if (!mem.create(imagesize)) {
- perror("QWSSharedMemSurface::setGeometry allocating shared memory");
- qFatal("Error creating shared memory of size %d", imagesize);
- }
-#ifdef QT_QWS_CLIENTBLIT
- *((uint *)mem.address()) = 0;
- uchar *base = static_cast<uchar*>(mem.address()) + sizeof(uint);
-#else
- uchar *base = static_cast<uchar*>(mem.address());
-#endif
- img = QImage(base, size.width(), size.height(), bpl, format);
- setImageMetrics(img, win);
- }
- }
-
- QWSWindowSurface::setGeometry(rect);
-}
-
-QByteArray QWSSharedMemSurface::permanentState() const
-{
- QByteArray array;
- array.resize(6 * sizeof(int));
-
- int *ptr = reinterpret_cast<int*>(array.data());
-
- ptr[0] = mem.id();
- ptr[1] = img.width();
- ptr[2] = img.height();
- ptr[3] = (memlock ? memlock->id() : -1);
- ptr[4] = int(img.format());
- ptr[5] = int(surfaceFlags());
-
- return array;
-}
-
-void QWSSharedMemSurface::releaseSurface()
-{
- mem.detach();
- img = QImage();
-}
-
-#endif // QT_NO_QWS_MULTIPROCESS
-
-#ifndef QT_NO_PAINTONSCREEN
-
-QWSOnScreenSurface::QWSOnScreenSurface(QWidget *w)
- : QWSMemorySurface(w)
-{
- attachToScreen(getScreen(w));
- setSurfaceFlags(Opaque);
-}
-
-QWSOnScreenSurface::QWSOnScreenSurface()
- : QWSMemorySurface()
-{
- setSurfaceFlags(Opaque);
-}
-
-void QWSOnScreenSurface::attachToScreen(const QScreen *s)
-{
- screen = s;
- uchar *base = screen->base();
- QImage::Format format = screen->pixelFormat();
-
- if (format == QImage::Format_Invalid || format == QImage::Format_Indexed8) {
- //### currently we have no paint engine for indexed image formats
- qFatal("QWSOnScreenSurface::attachToScreen(): screen depth %d "
- "not implemented", screen->depth());
- return;
- }
- QWSMemorySurface::img = QImage(base, screen->width(), screen->height(),
- screen->linestep(), format );
-}
-
-QWSOnScreenSurface::~QWSOnScreenSurface()
-{
-}
-
-QPoint QWSOnScreenSurface::painterOffset() const
-{
- return geometry().topLeft() + QWSWindowSurface::painterOffset();
-}
-
-bool QWSOnScreenSurface::isValid() const
-{
- const QWidget *win = window();
- if (screen != getScreen(win))
- return false;
- if (img.isNull())
- return false;
- return QScreen::isWidgetPaintOnScreen(win);
-}
-
-QByteArray QWSOnScreenSurface::permanentState() const
-{
- QByteArray array;
- array.resize(sizeof(int));
- int *ptr = reinterpret_cast<int*>(array.data());
- ptr[0] = QApplication::desktop()->screenNumber(window());
- return array;
-}
-
-void QWSOnScreenSurface::setPermanentState(const QByteArray &data)
-{
- const int *ptr = reinterpret_cast<const int*>(data.constData());
- const int screenNo = ptr[0];
-
- QScreen *screen = qt_screen;
- if (screenNo > 0)
- screen = qt_screen->subScreens().at(screenNo);
- attachToScreen(screen);
-}
-
-#endif // QT_NO_PAINTONSCREEN
-
-#ifndef QT_NO_PAINT_DEBUG
-
-QWSYellowSurface::QWSYellowSurface(bool isClient)
- : QWSWindowSurface(), delay(10)
-{
- if (isClient) {
- setWinId(QWidget::qwsDisplay()->takeId());
- QWidget::qwsDisplay()->nameRegion(winId(),
- QLatin1String("Debug flush paint"),
- QLatin1String("Silly yellow thing"));
- QWidget::qwsDisplay()->setAltitude(winId(), 1, true);
- }
- setSurfaceFlags(Buffered);
-}
-
-QWSYellowSurface::~QWSYellowSurface()
-{
-}
-
-QByteArray QWSYellowSurface::permanentState() const
-{
- QByteArray array;
- array.resize(2 * sizeof(int));
-
- int *ptr = reinterpret_cast<int*>(array.data());
- ptr[0] = surfaceSize.width();
- ptr[1] = surfaceSize.height();
-
- return array;
-}
-
-void QWSYellowSurface::setPermanentState(const QByteArray &data)
-{
- const int *ptr = reinterpret_cast<const int*>(data.constData());
-
- const int width = ptr[0];
- const int height = ptr[1];
-
- img = QImage(width, height, QImage::Format_ARGB32);
- img.fill(qRgba(255,255,31,127));
-}
-
-void QWSYellowSurface::flush(QWidget *widget, const QRegion &region,
- const QPoint &offset)
-{
- Q_UNUSED(offset);
-
- QWSDisplay *display = QWidget::qwsDisplay();
- QRegion rgn = region;
-
- if (widget)
- rgn.translate(widget->mapToGlobal(QPoint(0, 0)));
-
- surfaceSize = region.boundingRect().size();
-
- const int id = winId();
- display->requestRegion(id, key(), permanentState(), rgn);
- display->setAltitude(id, 1, true);
- display->repaintRegion(id, 0, false, rgn);
-
- ::usleep(500 * delay);
- display->requestRegion(id, key(), permanentState(), QRegion());
- ::usleep(500 * delay);
-}
-
-#endif // QT_NO_PAINT_DEBUG
-
-#ifndef QT_NO_DIRECTPAINTER
-
-static inline QScreen *getPrimaryScreen()
-{
- QScreen *screen = QScreen::instance();
- if (!screen->base()) {
- QList<QScreen*> subScreens = screen->subScreens();
- if (subScreens.size() < 1)
- return 0;
- screen = subScreens.at(0);
- }
- return screen;
-}
-
-QWSDirectPainterSurface::QWSDirectPainterSurface(bool isClient,
- QDirectPainter::SurfaceFlag flags)
- : QWSWindowSurface(), flushingRegionEvents(false), doLocking(false)
-{
- setSurfaceFlags(Opaque);
- synchronous = (flags == QDirectPainter::ReservedSynchronous);
-
- if (isClient) {
- setWinId(QWidget::qwsDisplay()->takeId());
- QWidget::qwsDisplay()->nameRegion(winId(),
- QLatin1String("QDirectPainter reserved space"),
- QLatin1String("reserved"));
- } else {
- setWinId(0);
- }
- _screen = QScreen::instance();
- if (!_screen->base()) {
- QList<QScreen*> subScreens = _screen->subScreens();
- if (subScreens.size() < 1)
- _screen = 0;
- else
- _screen = subScreens.at(0);
- }
-}
-
-QWSDirectPainterSurface::~QWSDirectPainterSurface()
-{
- if (winId() && QWSDisplay::instance()) // make sure not in QApplication destructor
- QWidget::qwsDisplay()->destroyRegion(winId());
-}
-
-void QWSDirectPainterSurface::setRegion(const QRegion &region)
-{
- const int id = winId();
- QWidget::qwsDisplay()->requestRegion(id, key(), permanentState(), region);
-#ifndef QT_NO_QWS_MULTIPROCESS
- if (synchronous)
- QWSDisplay::instance()->d->waitForRegionAck(id);
-#endif
-}
-
-void QWSDirectPainterSurface::flush(QWidget *, const QRegion &r, const QPoint &)
-{
- QWSDisplay::instance()->repaintRegion(winId(), 0, true, r);
-}
-
-QByteArray QWSDirectPainterSurface::permanentState() const
-{
- QByteArray res;
- if (isRegionReserved())
- res.append( 'r');
- return res;
-}
-
-void QWSDirectPainterSurface::setPermanentState(const QByteArray &ba)
-{
- if (ba.size() > 0 && ba.at(0) == 'r')
- setReserved();
- setSurfaceFlags(surfaceFlags() | Opaque);
-}
-
-void QWSDirectPainterSurface::beginPaint(const QRegion &region)
-{
- QWSWindowSurface::beginPaint(region);
-#ifndef QT_NO_QWS_MULTIPROCESS
- if (!synchronous) {
- flushingRegionEvents = true;
- QWSDisplay::instance()->d->waitForRegionEvents(winId(), doLocking);
- flushingRegionEvents = false;
- }
-#endif
-}
-
-bool QWSDirectPainterSurface::hasPendingRegionEvents() const
-{
-#ifndef QT_NO_QWS_MULTIPROCESS
- if (synchronous)
- return false;
-
- return QWSDisplay::instance()->d->hasPendingRegionEvents();
-#else
- return false;
-#endif
-}
-
-bool QWSDirectPainterSurface::lock(int timeout)
-{
-#ifndef QT_NO_THREAD
- threadLock.lock();
-#endif
- Q_UNUSED(timeout);
- if (doLocking)
- QWSDisplay::grab(true);
- return true;
-}
-
-void QWSDirectPainterSurface::unlock()
-{
- if (doLocking)
- QWSDisplay::ungrab();
-#ifndef QT_NO_THREAD
- threadLock.unlock();
-#endif
-}
-
-#endif // QT_NO_DIRECTPAINTER
-
-QT_END_NAMESPACE
diff --git a/src/gui/painting/qwindowsurface_qws_p.h b/src/gui/painting/qwindowsurface_qws_p.h
deleted file mode 100644
index eaabccf39a..0000000000
--- a/src/gui/painting/qwindowsurface_qws_p.h
+++ /dev/null
@@ -1,355 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWINDOWSURFACE_QWS_P_H
-#define QWINDOWSURFACE_QWS_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qwindowsurface_p.h"
-#include <qregion.h>
-#include <qimage.h>
-#include <qdirectpainter_qws.h>
-#include <qmutex.h>
-#include <private/qwssharedmemory_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QScreen;
-class QWSWindowSurfacePrivate;
-
-class Q_GUI_EXPORT QWSWindowSurface : public QWindowSurface
-{
-public:
- QWSWindowSurface();
- QWSWindowSurface(QWidget *widget);
- ~QWSWindowSurface();
-
- virtual bool isValid() const = 0;
-
- virtual void setGeometry(const QRect &rect);
- virtual void setGeometry(const QRect &rect, const QRegion &mask);
- virtual void flush(QWidget *widget, const QRegion &region,
- const QPoint &offset);
-
- virtual bool move(const QPoint &offset);
- virtual QRegion move(const QPoint &offset, const QRegion &newClip);
-
- virtual QPoint painterOffset() const; // remove!!!
-
- virtual void beginPaint(const QRegion &);
- virtual void endPaint(const QRegion &);
-
- virtual bool lock(int timeout = -1);
- virtual void unlock();
-
- virtual QString key() const = 0;
-
- // XXX: not good enough
- virtual QByteArray transientState() const;
- virtual QByteArray permanentState() const;
- virtual void setTransientState(const QByteArray &state);
- virtual void setPermanentState(const QByteArray &state);
-
- virtual QImage image() const = 0;
- virtual QPaintDevice *paintDevice() = 0;
-
- const QRegion clipRegion() const;
- void setClipRegion(const QRegion &);
-
-#ifdef QT_QWS_CLIENTBLIT
- virtual const QRegion directRegion() const;
- virtual int directRegionId() const;
- virtual void setDirectRegion(const QRegion &, int);
-#endif
-
- enum SurfaceFlag {
- RegionReserved = 0x1,
- Buffered = 0x2,
- Opaque = 0x4
- };
- Q_DECLARE_FLAGS(SurfaceFlags, SurfaceFlag)
-
- SurfaceFlags surfaceFlags() const;
-
- inline bool isRegionReserved() const {
- return surfaceFlags() & RegionReserved;
- }
- inline bool isBuffered() const { return surfaceFlags() & Buffered; }
- inline bool isOpaque() const { return surfaceFlags() & Opaque; }
-
- int winId() const;
- virtual void releaseSurface();
-
-protected:
- void setSurfaceFlags(SurfaceFlags type);
- void setWinId(int id);
-
-private:
- friend class QWidgetPrivate;
-
- void invalidateBuffer();
-
- QWSWindowSurfacePrivate *d_ptr;
-};
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QWSWindowSurface::SurfaceFlags)
-
-class QWSWindowSurfacePrivate
-{
-public:
- QWSWindowSurfacePrivate();
-
- void setWinId(int id);
-
- QWSWindowSurface::SurfaceFlags flags;
- QRegion clip;
-#ifdef QT_QWS_CLIENTBLIT
- QRegion direct;
- int directId;
-#endif
-
- int winId;
-};
-
-class QWSLock;
-
-class Q_GUI_EXPORT QWSMemorySurface : public QWSWindowSurface
-{
-public:
- QWSMemorySurface();
- QWSMemorySurface(QWidget *widget);
- ~QWSMemorySurface();
-
- bool isValid() const;
-
- QPaintDevice *paintDevice() { return &img; }
- bool scroll(const QRegion &area, int dx, int dy);
-
- QImage image() const { return img; }
- QPoint painterOffset() const;
-
- void beginPaint(const QRegion &rgn);
-
- bool lock(int timeout = -1);
- void unlock();
-
-protected:
- QImage::Format preferredImageFormat(const QWidget *widget) const;
-
-#ifndef QT_NO_QWS_MULTIPROCESS
- void setLock(int lockId);
- QWSLock *memlock;
-#endif
-#ifndef QT_NO_THREAD
- QMutex threadLock;
-#endif
-
- QImage img;
-};
-
-class Q_GUI_EXPORT QWSLocalMemSurface : public QWSMemorySurface
-{
-public:
- QWSLocalMemSurface();
- QWSLocalMemSurface(QWidget *widget);
- ~QWSLocalMemSurface();
-
- void setGeometry(const QRect &rect);
-
- QString key() const { return QLatin1String("mem"); }
- QByteArray permanentState() const;
-
- void setPermanentState(const QByteArray &data);
- virtual void releaseSurface();
-protected:
- uchar *mem;
- int memsize;
-};
-
-#ifndef QT_NO_QWS_MULTIPROCESS
-class Q_GUI_EXPORT QWSSharedMemSurface : public QWSMemorySurface
-{
-public:
- QWSSharedMemSurface();
- QWSSharedMemSurface(QWidget *widget);
- ~QWSSharedMemSurface();
-
- void setGeometry(const QRect &rect);
-
- QString key() const { return QLatin1String("shm"); }
- QByteArray permanentState() const;
-
- void setPermanentState(const QByteArray &data);
-
-#ifdef QT_QWS_CLIENTBLIT
- virtual void setDirectRegion(const QRegion &, int);
- virtual const QRegion directRegion() const;
-#endif
- virtual void releaseSurface();
-
-private:
- bool setMemory(int memId);
-
- QWSSharedMemory mem;
-};
-#endif // QT_NO_QWS_MULTIPROCESS
-
-#ifndef QT_NO_PAINTONSCREEN
-class Q_GUI_EXPORT QWSOnScreenSurface : public QWSMemorySurface
-{
-public:
- QWSOnScreenSurface();
- QWSOnScreenSurface(QWidget *widget);
- ~QWSOnScreenSurface();
-
- bool isValid() const;
- QPoint painterOffset() const;
-
- QString key() const { return QLatin1String("OnScreen"); }
- QByteArray permanentState() const;
-
- void setPermanentState(const QByteArray &data);
-
-private:
- void attachToScreen(const QScreen *screen);
-
- const QScreen *screen;
-};
-#endif // QT_NO_PAINTONSCREEN
-
-#ifndef QT_NO_PAINT_DEBUG
-class Q_GUI_EXPORT QWSYellowSurface : public QWSWindowSurface
-{
-public:
- QWSYellowSurface(bool isClient = false);
- ~QWSYellowSurface();
-
- void setDelay(int msec) { delay = msec; }
-
- bool isValid() const { return true; }
-
- void flush(QWidget *widget, const QRegion &region, const QPoint &offset);
-
- QString key() const { return QLatin1String("Yellow"); }
- QByteArray permanentState() const;
-
- void setPermanentState(const QByteArray &data);
-
- QPaintDevice *paintDevice() { return &img; }
- QImage image() const { return img; }
-
-private:
- int delay;
- QSize surfaceSize; // client side
- QImage img; // server side
-};
-#endif // QT_NO_PAINT_DEBUG
-
-#ifndef QT_NO_DIRECTPAINTER
-
-class QScreen;
-
-class Q_GUI_EXPORT QWSDirectPainterSurface : public QWSWindowSurface
-{
-public:
- QWSDirectPainterSurface(bool isClient = false,
- QDirectPainter::SurfaceFlag flags = QDirectPainter::NonReserved);
- ~QWSDirectPainterSurface();
-
- void setReserved() { setSurfaceFlags(RegionReserved); }
-
- void setGeometry(const QRect &rect) { setRegion(rect); }
-
- void setRegion(const QRegion &region);
- QRegion region() const { return clipRegion(); }
-
- void flush(QWidget*, const QRegion &, const QPoint &);
-
- bool isValid() const { return false; }
-
- QString key() const { return QLatin1String("DirectPainter"); }
- QByteArray permanentState() const;
-
- void setPermanentState(const QByteArray &);
-
- QImage image() const { return QImage(); }
- QPaintDevice *paintDevice() { return 0; }
-
- // hw: get rid of this
- WId windowId() const { return static_cast<WId>(winId()); }
-
- QScreen *screen() const { return _screen; }
-
- void beginPaint(const QRegion &);
- bool lock(int timeout = -1);
- void unlock();
-
- void setLocking(bool b) { doLocking = b; }
-
- bool hasPendingRegionEvents() const;
-
-private:
- QScreen *_screen;
-#ifndef QT_NO_THREAD
- QMutex threadLock;
-#endif
-
- friend void qt_directpainter_region(QDirectPainter*, const QRegion&, int);
- bool flushingRegionEvents;
- bool synchronous;
- bool doLocking;
-};
-
-#endif // QT_NO_DIRECTPAINTER
-
-QT_END_NAMESPACE
-
-#endif // QWINDOWSURFACE_QWS_P_H
diff --git a/src/gui/painting/qwindowsurface_raster.cpp b/src/gui/painting/qwindowsurface_raster.cpp
deleted file mode 100644
index d97238427b..0000000000
--- a/src/gui/painting/qwindowsurface_raster.cpp
+++ /dev/null
@@ -1,487 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qdebug.h>
-
-#include <qglobal.h> // for Q_WS_WIN define (non-PCH)
-#ifdef Q_WS_WIN
-#include <qlibrary.h>
-#include <qt_windows.h>
-#endif
-
-#include <QtGui/qpaintdevice.h>
-#include <QtGui/qwidget.h>
-
-#include "private/qwindowsurface_raster_p.h"
-#include "private/qnativeimage_p.h"
-#include "private/qwidget_p.h"
-
-#ifdef Q_WS_X11
-#include "private/qpixmap_x11_p.h"
-#include "private/qt_x11_p.h"
-#include "private/qwidget_p.h"
-#include "qx11info_x11.h"
-#endif
-#include "private/qdrawhelper_p.h"
-
-#ifdef Q_WS_MAC
-#include <private/qt_cocoa_helpers_mac_p.h>
-#include <QMainWindow>
-#include <private/qmainwindowlayout_p.h>
-#include <QToolBar>
-#endif
-
-QT_BEGIN_NAMESPACE
-
-class QRasterWindowSurfacePrivate
-{
-public:
- QNativeImage *image;
-
-#ifdef Q_WS_X11
- GC gc;
-#ifndef QT_NO_MITSHM
- uint needsSync : 1;
-#endif
-#ifndef QT_NO_XRENDER
- uint translucentBackground : 1;
-#endif
-#endif
- uint inSetGeometry : 1;
-};
-
-QRasterWindowSurface::QRasterWindowSurface(QWidget *window, bool setDefaultSurface)
- : QWindowSurface(window, setDefaultSurface), d_ptr(new QRasterWindowSurfacePrivate)
-{
-#ifdef Q_WS_X11
- d_ptr->gc = XCreateGC(X11->display, window->handle(), 0, 0);
-#ifndef QT_NO_XRENDER
- d_ptr->translucentBackground = X11->use_xrender
- && window->x11Info().depth() == 32;
-#endif
-#ifndef QT_NO_MITHSM
- d_ptr->needsSync = false;
-#endif
-#endif
- d_ptr->image = 0;
- d_ptr->inSetGeometry = false;
-
-#ifdef QT_MAC_USE_COCOA
- needsFlush = false;
- regionToFlush = QRegion();
-#endif // QT_MAC_USE_COCOA
-}
-
-
-QRasterWindowSurface::~QRasterWindowSurface()
-{
-#ifdef Q_WS_X11
- XFreeGC(X11->display, d_ptr->gc);
-#endif
- if (d_ptr->image)
- delete d_ptr->image;
-}
-
-
-QPaintDevice *QRasterWindowSurface::paintDevice()
-{
- return &d_ptr->image->image;
-}
-
-#if defined(Q_WS_X11) && !defined(QT_NO_MITSHM)
-void QRasterWindowSurface::syncX()
-{
- // delay writing to the backbuffer until we know for sure X is done reading from it
- if (d_ptr->needsSync) {
- XSync(X11->display, false);
- d_ptr->needsSync = false;
- }
-}
-#endif
-
-void QRasterWindowSurface::beginPaint(const QRegion &rgn)
-{
-#if defined(Q_WS_X11) && !defined(QT_NO_MITSHM)
- syncX();
-#endif
-
-#if (defined(Q_WS_X11) && !defined(QT_NO_XRENDER)) || (defined(Q_WS_WIN) && !defined(Q_WS_WINCE))
- if (!qt_widget_private(window())->isOpaque && window()->testAttribute(Qt::WA_TranslucentBackground)) {
-#if defined(Q_WS_WIN) && !defined(Q_WS_WINCE)
- if (d_ptr->image->image.format() != QImage::Format_ARGB32_Premultiplied)
- prepareBuffer(QImage::Format_ARGB32_Premultiplied, window());
-#endif
- QPainter p(&d_ptr->image->image);
- p.setCompositionMode(QPainter::CompositionMode_Source);
- const QVector<QRect> rects = rgn.rects();
- const QColor blank = Qt::transparent;
- for (QVector<QRect>::const_iterator it = rects.begin(); it != rects.end(); ++it) {
- p.fillRect(*it, blank);
- }
- }
-#else
- Q_UNUSED(rgn);
-#endif
-}
-
-void QRasterWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint &offset)
-{
- Q_D(QRasterWindowSurface);
-
- // Not ready for painting yet, bail out. This can happen in
- // QWidget::create_sys()
- if (!d->image || rgn.rectCount() == 0)
- return;
-
-#ifdef Q_WS_WIN
- QRect br = rgn.boundingRect();
-
-#ifndef Q_WS_WINCE
- if (!qt_widget_private(window())->isOpaque
- && window()->testAttribute(Qt::WA_TranslucentBackground)
- && (qt_widget_private(window())->data.window_flags & Qt::FramelessWindowHint))
- {
- QRect r = window()->frameGeometry();
- QPoint frameOffset = qt_widget_private(window())->frameStrut().topLeft();
- QRect dirtyRect = br.translated(offset + frameOffset);
-
- SIZE size = {r.width(), r.height()};
- POINT ptDst = {r.x(), r.y()};
- POINT ptSrc = {0, 0};
- BLENDFUNCTION blend = {AC_SRC_OVER, 0, (int)(255.0 * window()->windowOpacity()), Q_AC_SRC_ALPHA};
- RECT dirty = {dirtyRect.x(), dirtyRect.y(),
- dirtyRect.x() + dirtyRect.width(), dirtyRect.y() + dirtyRect.height()};
- Q_UPDATELAYEREDWINDOWINFO info = {sizeof(info), NULL, &ptDst, &size, d->image->hdc, &ptSrc, 0, &blend, Q_ULW_ALPHA, &dirty};
- ptrUpdateLayeredWindowIndirect(window()->internalWinId(), &info);
- } else
-#endif
- {
- QPoint wOffset = qt_qwidget_data(widget)->wrect.topLeft();
-
- HDC widget_dc = widget->getDC();
-
- QRect wbr = br.translated(-wOffset);
- BitBlt(widget_dc, wbr.x(), wbr.y(), wbr.width(), wbr.height(),
- d->image->hdc, br.x() + offset.x(), br.y() + offset.y(), SRCCOPY);
- widget->releaseDC(widget_dc);
- }
-
-#ifndef QT_NO_DEBUG
- static bool flush = !qgetenv("QT_FLUSH_WINDOWSURFACE").isEmpty();
- if (flush) {
- SelectObject(qt_win_display_dc(), GetStockObject(BLACK_BRUSH));
- Rectangle(qt_win_display_dc(), 0, 0, d->image->width() + 2, d->image->height() + 2);
- BitBlt(qt_win_display_dc(), 1, 1, d->image->width(), d->image->height(),
- d->image->hdc, 0, 0, SRCCOPY);
- }
-#endif
-
-#endif
-
-#ifdef Q_WS_X11
- extern void *qt_getClipRects(const QRegion &r, int &num); // in qpaintengine_x11.cpp
- extern QWidgetData* qt_widget_data(QWidget *);
- QPoint wOffset = qt_qwidget_data(widget)->wrect.topLeft();
-
- if (widget->window() != window()) {
- XFreeGC(X11->display, d_ptr->gc);
- d_ptr->gc = XCreateGC(X11->display, widget->handle(), 0, 0);
- }
-
- QRegion wrgn(rgn);
- if (!wOffset.isNull())
- wrgn.translate(-wOffset);
- QRect wbr = wrgn.boundingRect();
-
- if (wrgn.rectCount() != 1) {
- int num;
- XRectangle *rects = (XRectangle *)qt_getClipRects(wrgn, num);
- XSetClipRectangles(X11->display, d_ptr->gc, 0, 0, rects, num, YXBanded);
- }
-
- QRect br = rgn.boundingRect().translated(offset);
-#ifndef QT_NO_MITSHM
- if (d_ptr->image->xshmpm) {
- XCopyArea(X11->display, d_ptr->image->xshmpm, widget->handle(), d_ptr->gc,
- br.x(), br.y(), br.width(), br.height(), wbr.x(), wbr.y());
- d_ptr->needsSync = true;
- } else if (d_ptr->image->xshmimg) {
- const QImage &src = d->image->image;
- br = br.intersected(src.rect());
- XShmPutImage(X11->display, widget->handle(), d_ptr->gc, d_ptr->image->xshmimg,
- br.x(), br.y(), wbr.x(), wbr.y(), br.width(), br.height(), False);
- d_ptr->needsSync = true;
- } else
-#endif
- {
- const QImage &src = d->image->image;
- br = br.intersected(src.rect());
- if (src.format() != QImage::Format_RGB32 || widget->x11Info().depth() < 24) {
- Q_ASSERT(src.depth() >= 16);
- const QImage sub_src(src.scanLine(br.y()) + br.x() * (uint(src.depth()) / 8),
- br.width(), br.height(), src.bytesPerLine(), src.format());
- QX11PixmapData *data = new QX11PixmapData(QPixmapData::PixmapType);
- data->xinfo = widget->x11Info();
- data->fromImage(sub_src, Qt::NoOpaqueDetection);
- QPixmap pm = QPixmap(data);
- XCopyArea(X11->display, pm.handle(), widget->handle(), d_ptr->gc, 0 , 0 , br.width(), br.height(), wbr.x(), wbr.y());
- } else {
- // qpaintengine_x11.cpp
- extern void qt_x11_drawImage(const QRect &rect, const QPoint &pos, const QImage &image, Drawable hd, GC gc, Display *dpy, Visual *visual, int depth);
- qt_x11_drawImage(br, wbr.topLeft(), src, widget->handle(), d_ptr->gc, X11->display, (Visual *)widget->x11Info().visual(), widget->x11Info().depth());
- }
- }
-
- if (wrgn.rectCount() != 1)
- XSetClipMask(X11->display, d_ptr->gc, XNone);
-#endif // FALCON
-
-#ifdef Q_WS_MAC
-
- Q_UNUSED(offset);
-
- // This is mainly done for native components like native "open file" dialog.
- if (widget->testAttribute(Qt::WA_DontShowOnScreen)) {
- return;
- }
-
-#ifdef QT_MAC_USE_COCOA
-
- this->needsFlush = true;
- this->regionToFlush += rgn;
-
- // The actual flushing will be processed in [view drawRect:rect]
- qt_mac_setNeedsDisplay(widget);
-
-#else
- // Get a context for the widget.
- CGContextRef context;
- CGrafPtr port = GetWindowPort(qt_mac_window_for(widget));
- QDBeginCGContext(port, &context);
- CGContextRetain(context);
- CGContextSaveGState(context);
-
- // Flip context.
- CGContextTranslateCTM(context, 0, widget->height());
- CGContextScaleCTM(context, 1, -1);
-
- // Clip to region.
- const QVector<QRect> &rects = rgn.rects();
- for (int i = 0; i < rects.size(); ++i) {
- const QRect &rect = rects.at(i);
- CGContextAddRect(context, CGRectMake(rect.x(), rect.y(), rect.width(), rect.height()));
- }
- CGContextClip(context);
-
- QRect r = rgn.boundingRect();
- const CGRect area = CGRectMake(r.x(), r.y(), r.width(), r.height());
- CGImageRef image = CGBitmapContextCreateImage(d->image->cg);
- CGImageRef subImage = CGImageCreateWithImageInRect(image, area);
-
- qt_mac_drawCGImage(context, &area, subImage);
-
- CGImageRelease(subImage);
- CGImageRelease(image);
-
- QDEndCGContext(port, &context);
-
- // Restore context.
- CGContextRestoreGState(context);
- CGContextRelease(context);
-#endif // QT_MAC_USE_COCOA
-
-#endif // Q_WS_MAC
-
-#ifdef Q_OS_SYMBIAN
- Q_UNUSED(widget);
- Q_UNUSED(rgn);
- Q_UNUSED(offset);
-#endif
-}
-
-void QRasterWindowSurface::setGeometry(const QRect &rect)
-{
- QWindowSurface::setGeometry(rect);
- Q_D(QRasterWindowSurface);
- d->inSetGeometry = true;
- if (d->image == 0 || d->image->width() < rect.width() || d->image->height() < rect.height()) {
-#if (defined(Q_WS_X11) && !defined(QT_NO_XRENDER)) || (defined(Q_WS_WIN) && !defined(Q_WS_WINCE))
-#ifndef Q_WS_WIN
- if (d_ptr->translucentBackground)
-#else
- if (!qt_widget_private(window())->isOpaque)
-#endif
- prepareBuffer(QImage::Format_ARGB32_Premultiplied, window());
- else
-#endif
- prepareBuffer(QNativeImage::systemFormat(), window());
- }
- d->inSetGeometry = false;
-
-#if defined(Q_WS_MAC) && defined(QT_MAC_USE_COCOA)
- QMainWindow* mWindow = qobject_cast<QMainWindow*>(window());
- if (mWindow) {
- QMainWindowLayout *mLayout = qobject_cast<QMainWindowLayout*>(mWindow->layout());
- QList<QToolBar *> toolbarList = mLayout->qtoolbarsInUnifiedToolbarList;
-
- for (int i = 0; i < toolbarList.size(); ++i) {
- QToolBar* toolbar = toolbarList.at(i);
- if (mLayout->toolBarArea(toolbar) == Qt::TopToolBarArea) {
- QWidget* tbWidget = (QWidget*) toolbar;
- if (tbWidget->d_func()->unifiedSurface) {
- tbWidget->d_func()->unifiedSurface->setGeometry(rect);
- }
- }
- }
- }
-#endif // Q_WS_MAC && QT_MAC_USE_COCOA
-
-}
-
-// from qwindowsurface.cpp
-extern void qt_scrollRectInImage(QImage &img, const QRect &rect, const QPoint &offset);
-
-bool QRasterWindowSurface::scroll(const QRegion &area, int dx, int dy)
-{
-#ifdef Q_WS_WIN
- Q_D(QRasterWindowSurface);
-
- if (!d->image || !d->image->hdc)
- return false;
-
- QRect rect = area.boundingRect();
- BitBlt(d->image->hdc, rect.x()+dx, rect.y()+dy, rect.width(), rect.height(),
- d->image->hdc, rect.x(), rect.y(), SRCCOPY);
-
- return true;
-#else
- Q_D(QRasterWindowSurface);
-
- if (!d->image || d->image->image.isNull())
- return false;
-
-#if defined(Q_WS_X11) && !defined(QT_NO_MITSHM)
- syncX();
-#endif
-
- const QVector<QRect> rects = area.rects();
- for (int i = 0; i < rects.size(); ++i)
- qt_scrollRectInImage(d->image->image, rects.at(i), QPoint(dx, dy));
-
- return true;
-#endif
-}
-
-QWindowSurface::WindowSurfaceFeatures QRasterWindowSurface::features() const
-{
- return QWindowSurface::AllFeatures;
-}
-
-void QRasterWindowSurface::prepareBuffer(QImage::Format format, QWidget *widget)
-{
- Q_D(QRasterWindowSurface);
-
- int width = window()->width();
- int height = window()->height();
- if (d->image) {
- width = qMax(d->image->width(), width);
- height = qMax(d->image->height(), height);
- }
-
- if (width == 0 || height == 0) {
- delete d->image;
- d->image = 0;
- return;
- }
-
- QNativeImage *oldImage = d->image;
-
- d->image = new QNativeImage(width, height, format, false, widget);
-
- if (oldImage && d->inSetGeometry && hasStaticContents()) {
- // Make sure we use the const version of bits() (no detach).
- const uchar *src = const_cast<const QImage &>(oldImage->image).bits();
- uchar *dst = d->image->image.bits();
-
- const int srcBytesPerLine = oldImage->image.bytesPerLine();
- const int dstBytesPerLine = d->image->image.bytesPerLine();
- const int bytesPerPixel = oldImage->image.depth() >> 3;
-
- QRegion staticRegion(staticContents());
- // Make sure we're inside the boundaries of the old image.
- staticRegion &= QRect(0, 0, oldImage->image.width(), oldImage->image.height());
- const QVector<QRect> &rects = staticRegion.rects();
- const QRect *srcRect = rects.constData();
-
- // Copy the static content of the old image into the new one.
- int numRectsLeft = rects.size();
- do {
- const int bytesOffset = srcRect->x() * bytesPerPixel;
- const int dy = srcRect->y();
-
- // Adjust src and dst to point to the right offset.
- const uchar *s = src + dy * srcBytesPerLine + bytesOffset;
- uchar *d = dst + dy * dstBytesPerLine + bytesOffset;
- const int numBytes = srcRect->width() * bytesPerPixel;
-
- int numScanLinesLeft = srcRect->height();
- do {
- ::memcpy(d, s, numBytes);
- d += dstBytesPerLine;
- s += srcBytesPerLine;
- } while (--numScanLinesLeft);
-
- ++srcRect;
- } while (--numRectsLeft);
- }
-
- delete oldImage;
-}
-
-#ifdef QT_MAC_USE_COCOA
-CGContextRef QRasterWindowSurface::imageContext()
-{
- Q_D(QRasterWindowSurface);
- return d->image->cg;
-}
-#endif // QT_MAC_USE_COCOA
-
-QT_END_NAMESPACE
diff --git a/src/gui/painting/qwindowsurface_raster_p.h b/src/gui/painting/qwindowsurface_raster_p.h
deleted file mode 100644
index 7bac561fa7..0000000000
--- a/src/gui/painting/qwindowsurface_raster_p.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWINDOWSURFACE_RASTER_P_H
-#define QWINDOWSURFACE_RASTER_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of the QLibrary class. This header file may change from
-// version to version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <qglobal.h>
-#include "private/qwindowsurface_p.h"
-
-#ifdef QT_MAC_USE_COCOA
-# include <private/qt_cocoa_helpers_mac_p.h>
-#endif // QT_MAC_USE_COCOA
-
-QT_BEGIN_NAMESPACE
-
-#ifdef Q_WS_WIN
-#define Q_WS_EX_LAYERED 0x00080000 // copied from WS_EX_LAYERED in winuser.h
-#define Q_LWA_ALPHA 0x00000002 // copied from LWA_ALPHA in winuser.h
-#define Q_ULW_ALPHA 0x00000002 // copied from ULW_ALPHA in winuser.h
-#define Q_AC_SRC_ALPHA 0x00000001 // copied from AC_SRC_ALPHA in winuser.h
-
-struct Q_UPDATELAYEREDWINDOWINFO {
- DWORD cbSize;
- HDC hdcDst;
- const POINT *pptDst;
- const SIZE *psize;
- HDC hdcSrc;
- const POINT *pptSrc;
- COLORREF crKey;
- const BLENDFUNCTION *pblend;
- DWORD dwFlags;
- const RECT *prcDirty;
-};
-
-typedef BOOL (WINAPI *PtrUpdateLayeredWindow)(HWND hwnd, HDC hdcDst, const POINT *pptDst,
- const SIZE *psize, HDC hdcSrc, const POINT *pptSrc, COLORREF crKey,
- const BLENDFUNCTION *pblend, DWORD dwflags);
-typedef BOOL (WINAPI *PtrUpdateLayeredWindowIndirect)(HWND hwnd, const Q_UPDATELAYEREDWINDOWINFO *pULWInfo);
-extern PtrUpdateLayeredWindow ptrUpdateLayeredWindow;
-extern PtrUpdateLayeredWindowIndirect ptrUpdateLayeredWindowIndirect;
-#endif
-
-class QPaintDevice;
-class QPoint;
-class QRegion;
-class QRegion;
-class QSize;
-class QWidget;
-class QRasterWindowSurfacePrivate;
-class QNativeImage;
-
-class Q_GUI_EXPORT QRasterWindowSurface : public QWindowSurface
-{
-public:
- QRasterWindowSurface(QWidget *widget, bool setDefaultSurface = true);
- ~QRasterWindowSurface();
-
- QPaintDevice *paintDevice();
- void flush(QWidget *widget, const QRegion &region, const QPoint &offset);
- void beginPaint(const QRegion &rgn);
- void setGeometry(const QRect &rect);
- bool scroll(const QRegion &area, int dx, int dy);
- WindowSurfaceFeatures features() const;
-
-#ifdef QT_MAC_USE_COCOA
- CGContextRef imageContext();
-
- bool needsFlush;
- QRegion regionToFlush;
-#endif // QT_MAC_USE_COCOA
-
-private:
-#if defined(Q_WS_X11) && !defined(QT_NO_MITSHM)
- void syncX();
-#endif
- void prepareBuffer(QImage::Format format, QWidget *widget);
- Q_DECLARE_PRIVATE(QRasterWindowSurface)
- QScopedPointer<QRasterWindowSurfacePrivate> d_ptr;
-};
-
-QT_END_NAMESPACE
-
-#endif // QWINDOWSURFACE_RASTER_P_H
diff --git a/src/gui/painting/qwindowsurface_s60.cpp b/src/gui/painting/qwindowsurface_s60.cpp
deleted file mode 100644
index 8801d75f0f..0000000000
--- a/src/gui/painting/qwindowsurface_s60.cpp
+++ /dev/null
@@ -1,254 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qglobal.h> // for Q_WS_WIN define (non-PCH)
-
-#include <QtGui/qpaintdevice.h>
-#include <private/qwidget_p.h>
-#include <private/qwindowsurface_s60_p.h>
-#include <private/qpixmap_s60_p.h>
-#include <private/qt_s60_p.h>
-#include <private/qapplication_p.h>
-#include <private/qdrawhelper_p.h>
-
-#ifdef QT_GRAPHICSSYSTEM_RUNTIME
-#include <private/qgraphicssystem_runtime_p.h>
-#endif
-
-QT_BEGIN_NAMESPACE
-
-struct QS60WindowSurfacePrivate
-{
- QPixmap device;
- QList<QImage*> bufferImages;
-};
-
-TDisplayMode displayMode(bool opaque)
-{
- TDisplayMode mode = S60->screenDevice()->DisplayMode();
- if (opaque) {
- mode = EColor16MU;
- } else {
- if (QSysInfo::symbianVersion() >= QSysInfo::SV_SF_3)
- mode = Q_SYMBIAN_ECOLOR16MAP; // Symbian^3 WServ has support for ARGB32_PRE
- else
- mode = EColor16MA; // Symbian prior to Symbian^3 sw accelerates EColor16MA
- }
- return mode;
-}
-
-bool blitWriteAlpha(QWidgetPrivate *widgetPrivate)
-{
- QWExtra *extra = widgetPrivate->extraData();
- return extra ? extra->nativePaintMode == QWExtra::BlitWriteAlpha : false;
-}
-
-QS60WindowSurface::QS60WindowSurface(QWidget* widget)
- : QWindowSurface(widget), d_ptr(new QS60WindowSurfacePrivate)
-{
- QWidgetPrivate *widgetPrivate = qt_widget_private(widget);
- const bool opaque = widgetPrivate->isOpaque && !blitWriteAlpha(widgetPrivate);
- TDisplayMode mode = displayMode(opaque);
- // We create empty CFbsBitmap here -> it will be resized in setGeometry
- CFbsBitmap *bitmap = new CFbsBitmap; // CBase derived object needs check on new
- Q_CHECK_PTR(bitmap);
- qt_symbian_throwIfError( bitmap->Create( TSize(0, 0), mode ) );
-
- QS60PixmapData *data = new QS60PixmapData(QPixmapData::PixmapType);
- if (data) {
- data->fromSymbianBitmap(bitmap, true);
- d_ptr->device = QPixmap(data);
- }
-}
-
-QS60WindowSurface::~QS60WindowSurface()
-{
-#if defined(QT_GRAPHICSSYSTEM_RUNTIME) && defined(Q_SYMBIAN_SUPPORTS_SURFACES)
- if(QApplicationPrivate::runtime_graphics_system) {
- QRuntimeGraphicsSystem *runtimeGraphicsSystem =
- static_cast<QRuntimeGraphicsSystem*>(QApplicationPrivate::graphics_system);
- if(runtimeGraphicsSystem->graphicsSystemName() == QLatin1String("openvg")) {
-
- // Graphics system has been switched from raster to openvg.
- // Issue empty redraw to clear the UI surface
-
- QWidget *w = window();
- if (w->testAttribute(Qt::WA_WState_Created)) {
- RWindow *const window = static_cast<RWindow *>(w->winId()->DrawableWindow());
- window->BeginRedraw();
- window->EndRedraw();
- }
- }
- }
-#endif
-
- delete d_ptr;
-}
-
-void QS60WindowSurface::beginPaint(const QRegion &rgn)
-{
-#ifdef Q_SYMBIAN_SUPPORTS_SURFACES
- S60->wsSession().Finish();
-#endif
-
- QWidgetPrivate *windowPrivate = qt_widget_private(window());
- if (!windowPrivate->isOpaque || blitWriteAlpha(windowPrivate)) {
- QS60PixmapData *pixmapData = static_cast<QS60PixmapData *>(d_ptr->device.data_ptr().data());
-
- TDisplayMode mode = displayMode(false);
- if (pixmapData->cfbsBitmap->DisplayMode() != mode)
- pixmapData->convertToDisplayMode(mode);
-
- pixmapData->beginDataAccess();
-
- if (!windowPrivate->isOpaque) {
- QPainter p(&pixmapData->image);
- p.setCompositionMode(QPainter::CompositionMode_Source);
- const QVector<QRect> rects = rgn.rects();
- const QColor blank = Qt::transparent;
- for (QVector<QRect>::const_iterator it = rects.begin(); it != rects.end(); ++it) {
- p.fillRect(*it, blank);
- }
- }
-
- pixmapData->endDataAccess();
- }
-}
-
-void QS60WindowSurface::endPaint(const QRegion &)
-{
- qDeleteAll(d_ptr->bufferImages);
- d_ptr->bufferImages.clear();
-}
-
-QImage* QS60WindowSurface::buffer(const QWidget *widget)
-{
- if (widget->window() != window())
- return 0;
-
- QPaintDevice *pdev = paintDevice();
- if (!pdev)
- return 0;
-
- const QPoint off = offset(widget);
- QImage *img = &(static_cast<QS60PixmapData *>(d_ptr->device.data_ptr().data())->image);
-
- QRect rect(off, widget->size());
- rect &= QRect(QPoint(), img->size());
-
- if (rect.isEmpty())
- return 0;
-
- img = new QImage(img->scanLine(rect.y()) + rect.x() * img->depth() / 8,
- rect.width(), rect.height(),
- img->bytesPerLine(), img->format());
- d_ptr->bufferImages.append(img);
-
- return img;
-}
-
-void QS60WindowSurface::flush(QWidget *widget, const QRegion &region, const QPoint &)
-{
- QWidget *window = widget->window();
- Q_ASSERT(window);
- QTLWExtra *topExtra = window->d_func()->maybeTopData();
- Q_ASSERT(topExtra);
- QRect qr = region.boundingRect();
- if (!topExtra->inExpose) {
- topExtra->inExpose = true; // Prevent DrawNow() from calling syncBackingStore() again
- TRect tr = qt_QRect2TRect(qr);
- widget->winId()->DrawNow(tr);
- topExtra->inExpose = false;
- } else {
- // This handles the case when syncBackingStore updates content outside of the
- // original drawing rectangle. This might happen if there are pending update()
- // events at the same time as we get a Draw() from Symbian.
- QRect drawRect = qt_TRect2QRect(widget->winId()->DrawableWindow()->GetDrawRect());
- if (!drawRect.contains(qr))
- widget->winId()->DrawDeferred();
- }
-}
-
-bool QS60WindowSurface::scroll(const QRegion &area, int dx, int dy)
-{
- QRect rect = area.boundingRect();
-
- if (dx == 0 && dy == 0)
- return false;
-
- if (d_ptr->device.isNull())
- return false;
-
- QS60PixmapData *data = static_cast<QS60PixmapData*>(d_ptr->device.data_ptr().data());
- data->scroll(dx, dy, rect);
-
- return true;
-}
-
-QPaintDevice* QS60WindowSurface::paintDevice()
-{
- return &d_ptr->device;
-}
-
-void QS60WindowSurface::setGeometry(const QRect& rect)
-{
- if (rect == geometry())
- return;
-
- QS60PixmapData *data = static_cast<QS60PixmapData*>(d_ptr->device.data_ptr().data());
- data->resize(rect.width(), rect.height());
-
- QWindowSurface::setGeometry(rect);
-}
-
-QWindowSurface::WindowSurfaceFeatures QS60WindowSurface::features() const
-{
- return QWindowSurface::AllFeatures;
-}
-
-CFbsBitmap* QS60WindowSurface::symbianBitmap() const
-{
- QS60PixmapData *data = static_cast<QS60PixmapData*>(d_ptr->device.data_ptr().data());
- return data->cfbsBitmap;
-}
-
-QT_END_NAMESPACE
-
diff --git a/src/gui/painting/qwindowsurface_s60_p.h b/src/gui/painting/qwindowsurface_s60_p.h
deleted file mode 100644
index a086ca424d..0000000000
--- a/src/gui/painting/qwindowsurface_s60_p.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWINDOWSURFACE_S60_P_H
-#define QWINDOWSURFACE_S60_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <qglobal.h>
-#include "private/qwindowsurface_p.h"
-
-class CFbsBitmap;
-
-QT_BEGIN_NAMESPACE
-
-struct QS60WindowSurfacePrivate;
-
-class QS60WindowSurface : public QWindowSurface
-{
-public:
- QS60WindowSurface(QWidget *widget);
- ~QS60WindowSurface();
-
- QPaintDevice *paintDevice();
- void flush(QWidget *widget, const QRegion &region, const QPoint &offset);
- bool scroll(const QRegion &area, int dx, int dy);
-
- void beginPaint(const QRegion &);
- void endPaint(const QRegion &);
-
- QImage* buffer(const QWidget *widget);
-
- void setGeometry(const QRect &rect);
-
- WindowSurfaceFeatures features() const;
-
- CFbsBitmap *symbianBitmap() const;
-
-private:
- QS60WindowSurfacePrivate* d_ptr;
-
-};
-
-QT_END_NAMESPACE
-
-#endif // QWINDOWSURFACE_S60_P_H
diff --git a/src/gui/painting/qwindowsurface_x11.cpp b/src/gui/painting/qwindowsurface_x11.cpp
deleted file mode 100644
index 1a62f47722..0000000000
--- a/src/gui/painting/qwindowsurface_x11.cpp
+++ /dev/null
@@ -1,265 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtGui/QPaintDevice>
-#include <QtGui/QPainter>
-#include <QtGui/QPixmap>
-#include <QtGui/QWidget>
-
-#include "private/qt_x11_p.h"
-#include "private/qpixmap_x11_p.h"
-#include "private/qwidget_p.h"
-#include "qx11info_x11.h"
-#include "qwindowsurface_x11_p.h"
-
-QT_BEGIN_NAMESPACE
-
-extern void *qt_getClipRects(const QRegion &r, int &num); // in qpaintengine_x11.cpp
-
-struct QX11WindowSurfacePrivate
-{
- QWidget *widget;
- QPixmap device;
-#ifndef QT_NO_XRENDER
- bool translucentBackground;
-#endif
-};
-
-QX11WindowSurface::QX11WindowSurface(QWidget *widget)
- : QWindowSurface(widget), d_ptr(new QX11WindowSurfacePrivate), gc(0)
-{
- d_ptr->widget = widget;
-#ifndef QT_NO_XRENDER
- d_ptr->translucentBackground = X11->use_xrender
- && widget->x11Info().depth() == 32;
-#endif
-}
-
-
-QX11WindowSurface::~QX11WindowSurface()
-{
- delete d_ptr;
- if (gc) {
- XFreeGC(X11->display, gc);
- gc = 0;
- }
-}
-
-QPaintDevice *QX11WindowSurface::paintDevice()
-{
- return &d_ptr->device;
-}
-
-void QX11WindowSurface::beginPaint(const QRegion &rgn)
-{
-#ifndef QT_NO_XRENDER
- Q_ASSERT(!d_ptr->device.isNull());
-
- if (d_ptr->translucentBackground) {
- if (d_ptr->device.depth() != 32)
- static_cast<QX11PixmapData *>(d_ptr->device.data_ptr().data())->convertToARGB32();
- ::Picture src = X11->getSolidFill(d_ptr->device.x11Info().screen(), Qt::transparent);
- ::Picture dst = d_ptr->device.x11PictureHandle();
- const QVector<QRect> rects = rgn.rects();
- const int w = d_ptr->device.width();
- const int h = d_ptr->device.height();
- for (QVector<QRect>::const_iterator it = rects.begin(); it != rects.end(); ++it)
- XRenderComposite(X11->display, PictOpSrc, src, 0, dst,
- 0, 0, w, h, it->x(), it->y(),
- it->width(), it->height());
- }
-#endif
-}
-
-void QX11WindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint &offset)
-{
- if (d_ptr->device.isNull())
- return;
-
- QPoint wOffset = qt_qwidget_data(widget)->wrect.topLeft();
- QRegion wrgn(rgn);
- QRect br = rgn.boundingRect();
- if (!wOffset.isNull())
- wrgn.translate(-wOffset);
- QRect wbr = wrgn.boundingRect();
-
- int num;
- XRectangle *rects = (XRectangle *)qt_getClipRects(wrgn, num);
- if (num <= 0)
- return;
-// qDebug() << "XSetClipRectangles";
-// for (int i = 0; i < num; ++i)
-// qDebug() << ' ' << i << rects[i].x << rects[i].x << rects[i].y << rects[i].width << rects[i].height;
- if (num != 1)
- XSetClipRectangles(X11->display, gc, 0, 0, rects, num, YXBanded);
- XCopyArea(X11->display, d_ptr->device.handle(), widget->handle(), gc,
- br.x() + offset.x(), br.y() + offset.y(), br.width(), br.height(), wbr.x(), wbr.y());
- if (num != 1)
- XSetClipMask(X11->display, gc, XNone);
-}
-
-void QX11WindowSurface::setGeometry(const QRect &rect)
-{
- QWindowSurface::setGeometry(rect);
-
- const QSize size = rect.size();
-
- if (d_ptr->device.size() == size || size.width() <= 0 || size.height() <= 0)
- return;
-#ifndef QT_NO_XRENDER
- if (d_ptr->translucentBackground) {
- QPixmap::x11SetDefaultScreen(d_ptr->widget->x11Info().screen());
-
- QX11PixmapData *data = new QX11PixmapData(QPixmapData::PixmapType);
- data->xinfo = d_ptr->widget->x11Info();
- data->resize(size.width(), size.height());
- d_ptr->device = QPixmap(data);
- } else
-#endif
- {
- QPixmap::x11SetDefaultScreen(d_ptr->widget->x11Info().screen());
-
- QX11PixmapData *oldData = static_cast<QX11PixmapData *>(d_ptr->device.pixmapData());
-
- if (oldData && !(oldData->flags & QX11PixmapData::Uninitialized) && hasStaticContents()) {
- // Copy the content of the old pixmap into the new one.
- QX11PixmapData *newData = new QX11PixmapData(QPixmapData::PixmapType);
- newData->resize(size.width(), size.height());
- Q_ASSERT(oldData->d == newData->d);
-
- QRegion staticRegion(staticContents());
- // Make sure we're inside the boundaries of the old pixmap.
- staticRegion &= QRect(0, 0, oldData->w, oldData->h);
- const QRect boundingRect(staticRegion.boundingRect());
- const int dx = boundingRect.x();
- const int dy = boundingRect.y();
-
- int num;
- XRectangle *rects = (XRectangle *)qt_getClipRects(staticRegion, num);
- GC tmpGc = XCreateGC(X11->display, oldData->hd, 0, 0);
- XSetClipRectangles(X11->display, tmpGc, 0, 0, rects, num, YXBanded);
- XCopyArea(X11->display, oldData->hd, newData->hd, tmpGc,
- dx, dy, qMin(boundingRect.width(), size.width()),
- qMin(boundingRect.height(), size.height()), dx, dy);
- XFreeGC(X11->display, tmpGc);
- newData->flags &= ~QX11PixmapData::Uninitialized;
-
- d_ptr->device = QPixmap(newData);
- } else {
- d_ptr->device = QPixmap(size);
- }
- }
-
- if (gc) {
- XFreeGC(X11->display, gc);
- gc = 0;
- }
- if (!d_ptr->device.isNull()) {
- gc = XCreateGC(X11->display, d_ptr->device.handle(), 0, 0);
- XSetGraphicsExposures(X11->display, gc, False);
- }
-}
-
-bool QX11WindowSurface::scroll(const QRegion &area, int dx, int dy)
-{
- QRect rect = area.boundingRect();
-
- if (d_ptr->device.isNull())
- return false;
-
- GC gc = XCreateGC(X11->display, d_ptr->device.handle(), 0, 0);
- XCopyArea(X11->display, d_ptr->device.handle(), d_ptr->device.handle(), gc,
- rect.x(), rect.y(), rect.width(), rect.height(),
- rect.x()+dx, rect.y()+dy);
- XFreeGC(X11->display, gc);
-
- return true;
-}
-
-QPixmap QX11WindowSurface::grabWidget(const QWidget *widget,
- const QRect& rect) const
-{
- if (!widget || d_ptr->device.isNull())
- return QPixmap();
-
- QRect srcRect;
-
- // make sure the rect is inside the widget & clip to widget's rect
- if (!rect.isEmpty())
- srcRect = rect & widget->rect();
- else
- srcRect = widget->rect();
-
- if (srcRect.isEmpty())
- return QPixmap();
-
- // If it's a child widget we have to translate the coordinates
- if (widget != window())
- srcRect.translate(widget->mapTo(window(), QPoint(0, 0)));
-
- QPixmap::x11SetDefaultScreen(widget->x11Info().screen());
- QPixmap px(srcRect.width(), srcRect.height());
-
- GC tmpGc = XCreateGC(X11->display, d_ptr->device.handle(), 0, 0);
-
- // Copy srcRect from the backing store to the new pixmap
- XSetGraphicsExposures(X11->display, tmpGc, False);
- XCopyArea(X11->display, d_ptr->device.handle(), px.handle(), tmpGc,
- srcRect.x(), srcRect.y(), srcRect.width(), srcRect.height(), 0, 0);
-
- XFreeGC(X11->display, tmpGc);
-
- return px;
-}
-
-QWindowSurface::WindowSurfaceFeatures QX11WindowSurface::features() const
-{
- WindowSurfaceFeatures features = QWindowSurface::PartialUpdates | QWindowSurface::PreservedContents;
-#ifndef QT_NO_XRENDER
- if (!d_ptr->translucentBackground)
- features |= QWindowSurface::StaticContents;
-#else
- features |= QWindowSurface::StaticContents;
-#endif
- return features;
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/painting/qwindowsurface_x11_p.h b/src/gui/painting/qwindowsurface_x11_p.h
deleted file mode 100644
index 23c00a1f63..0000000000
--- a/src/gui/painting/qwindowsurface_x11_p.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWINDOWSURFACE_X11_P_H
-#define QWINDOWSURFACE_X11_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <qglobal.h>
-#include "private/qwindowsurface_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class QPaintDevice;
-class QPoint;
-class QRegion;
-class QRegion;
-class QSize;
-class QWidget;
-struct QX11WindowSurfacePrivate;
-
-class QX11WindowSurface : public QWindowSurface
-{
-public:
- QX11WindowSurface(QWidget *widget);
- ~QX11WindowSurface();
-
- QPaintDevice *paintDevice();
- void flush(QWidget *widget, const QRegion &region, const QPoint &offset);
-
- void beginPaint(const QRegion &rgn);
- void setGeometry(const QRect &rect);
- bool scroll(const QRegion &area, int dx, int dy);
- QPixmap grabWidget(const QWidget *widget,
- const QRect& rectangle = QRect()) const;
- WindowSurfaceFeatures features() const;
-
-private:
- QX11WindowSurfacePrivate *d_ptr;
- GC gc;
-};
-
-QT_END_NAMESPACE
-
-#endif // QWINDOWSURFACE_X11_P_H
diff --git a/src/gui/painting/qwmatrix.h b/src/gui/painting/qwmatrix.h
deleted file mode 100644
index 914d574f90..0000000000
--- a/src/gui/painting/qwmatrix.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWMATRIX_H
-#define QWMATRIX_H
-
-#include <QtGui/qmatrix.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#if defined(QT3_SUPPORT)
-typedef QMatrix QWMatrix;
-#endif
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QWMATRIX_H
diff --git a/src/gui/s60framework/qs60mainapplication.h b/src/gui/s60framework/qs60mainapplication.h
deleted file mode 100644
index 74e3706155..0000000000
--- a/src/gui/s60framework/qs60mainapplication.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the Symbian application wrapper of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QS60MAINAPPLICATION_H
-#define QS60MAINAPPLICATION_H
-
-#include <QtCore/qglobal.h>
-
-#ifdef Q_OS_SYMBIAN
-
-#ifdef Q_WS_S60
-#include <aknapp.h>
-typedef CAknApplication QS60MainApplicationBase;
-#else
-#include <eikapp.h>
-typedef CEikApplication QS60MainApplicationBase;
-#endif
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class Q_GUI_EXPORT QS60MainApplication : public QS60MainApplicationBase
-{
-public:
- QS60MainApplication();
- // The virtuals are for qdoc.
- virtual ~QS60MainApplication();
-
- virtual TUid AppDllUid() const;
-
- virtual TFileName ResourceFileName() const;
-
-public:
-
- virtual void PreDocConstructL();
-
- virtual CDictionaryStore *OpenIniFileLC(RFs &aFs) const;
-
- virtual void NewAppServerL(CApaAppServer *&aAppServer);
-
-protected:
-
- virtual CApaDocument *CreateDocumentL();
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // Q_OS_SYMBIAN
-
-#endif // QS60MAINAPPLICATION_H
diff --git a/src/gui/s60framework/qs60mainappui.cpp b/src/gui/s60framework/qs60mainappui.cpp
deleted file mode 100644
index bfd18256e1..0000000000
--- a/src/gui/s60framework/qs60mainappui.cpp
+++ /dev/null
@@ -1,430 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the Symbian application wrapper of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-// INCLUDE FILES
-#include <exception>
-#include <qglobal.h>
-#ifdef Q_WS_S60
-#include <avkon.hrh>
-#include <eikmenub.h>
-#include <eikmenup.h>
-#include <avkon.rsg>
-#endif
-#include <barsread.h>
-#include <coeutils.h>
-#include <qconfig.h>
-
-#include "qs60mainappui.h"
-#include <QtGui/qapplication.h>
-#include <QtGui/qsymbianevent.h>
-#include <QtGui/qmenu.h>
-#include <private/qmenu_p.h>
-#include <private/qt_s60_p.h>
-#include <qdebug.h>
-
-//Animated wallpapers in Qt applications are not supported.
-const TInt KAknDisableAnimationBackground = 0x02000000;
-const TInt KAknSingleClickCompatible = 0x01000000;
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \class QS60MainAppUi
- \since 4.6
- \brief The QS60MainAppUi class is a helper class for S60 migration.
-
- \warning This class is provided only to get access to S60 specific
- functionality in the application framework classes. It is not
- portable. We strongly recommend against using it in new applications.
-
- The QS60MainAppUi provides a helper class for use in migrating from
- existing S60 based applications to Qt based applications. It is used
- in the exact same way as the \c CAknAppUi class from Symbian, but
- internally provides extensions used by Qt.
-
- When modifying old S60 applications that rely on implementing
- functions in \c CAknAppUi, the class should be modified to inherit
- from this class instead of \c CAknAppUi. Then the application can
- choose to override only certain functions.
-
- For more information on \c CAknAppUi, please see the S60
- documentation.
-
- Unlike other Qt classes, QS60MainAppUi behaves like an S60 class,
- and can throw Symbian leaves.
-
- \sa QS60MainDocument, QS60MainApplication
- */
-
-/*!
- * \brief Second phase Symbian constructor.
- *
- * Constructs all the elements of the class that can cause a leave to happen.
- *
- * If you override this function, you should call the base class implementation as well.
- */
-void QS60MainAppUi::ConstructL()
-{
- // Cone's heap and handle checks on app destruction are not suitable for Qt apps, as many
- // objects can still exist in static data at that point. Instead we will print relevant information
- // so that comparative checks may be made for memory leaks, using ~SPrintExitInfo in corelib.
- iEikonEnv->DisableExitChecks(ETrue);
-
- // Initialise app UI with standard value.
- // ENoAppResourceFile and ENonStandardResourceFile makes UI to work without
- // resource files in most SDKs. S60 3rd FP1 public seems to require resource file
- // even these flags are defined
- TInt flags = CEikAppUi::ENoScreenFurniture
- | CEikAppUi::ENonStandardResourceFile;
-#ifdef Q_WS_S60
- flags |= CAknAppUi::EAknEnableSkin;
- // After 5th Edition S60, native side supports animated wallpapers.
- // However, there is no support for that feature on Qt side, so indicate to
- // native UI framework that this application will not support background animations.
-
- // Also, add support for single touch for post 5th edition platforms.
- // This has only impact when launching native dialogs/menus from inside QApplication.
- if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0) {
- flags |= (KAknDisableAnimationBackground | KAknSingleClickCompatible);
- }
-#endif
- BaseConstructL(flags);
-}
-
-/*!
- * \brief Contructs an instance of QS60MainAppUi.
- */
-QS60MainAppUi::QS60MainAppUi()
-{
- // No implementation required
-}
-
-/*!
- * \brief Destroys the QS60MainAppUi.
- */
-QS60MainAppUi::~QS60MainAppUi()
-{
-}
-
-/*!
- * \brief Handles commands produced by the S60 framework.
- *
- * \a command holds the ID of the command to handle, and is S60 specific.
- *
- * If you override this function, you should call the base class implementation if you do not
- * handle the command.
- */
-void QS60MainAppUi::HandleCommandL(TInt command)
-{
- if (qApp) {
- QSymbianEvent event(QSymbianEvent::CommandEvent, command);
- QT_TRYCATCH_LEAVING(qApp->symbianProcessEvent(&event));
- }
-}
-
-/*!
- * \brief Handles a resource change in the S60 framework.
- *
- * Resource changes include layout switches. \a type holds the type of resource change that
- * occurred.
- *
- * If you override this function, you should call the base class implementation if you do not
- * handle the resource change.
- */
-void QS60MainAppUi::HandleResourceChangeL(TInt type)
-{
- QS60MainAppUiBase::HandleResourceChangeL(type);
-
- if (qApp) {
- QSymbianEvent event(QSymbianEvent::ResourceChangeEvent, type);
- QT_TRYCATCH_LEAVING(qApp->symbianProcessEvent(&event));
- }
-}
-
-/*!
- * \brief Handles raw window server events.
- *
- * The event type and information is passed in \a wsEvent, while the receiving control is passed in
- * \a destination.
- *
- * If you override this function, you should call the base class implementation if you do not
- * handle the event.
- */
-void QS60MainAppUi::HandleWsEventL(const TWsEvent &wsEvent, CCoeControl *destination)
-{
- int result = 0;
- if (qApp) {
- QSymbianEvent event(&wsEvent);
- QT_TRYCATCH_LEAVING(
- result = qApp->symbianProcessEvent(&event)
- );
- }
-
- if (result <= 0)
- QS60MainAppUiBase::HandleWsEventL(wsEvent, destination);
-}
-
-
-/*!
- * \brief Handles changes to the status pane size.
- *
- * Called by the framework when the application status pane size is changed.
- *
- * If you override this function, you should call the base class implementation if you do not
- * handle the size change.
- */
-void QS60MainAppUi::HandleStatusPaneSizeChange()
-{
- TRAP_IGNORE(HandleResourceChangeL(KInternalStatusPaneChange));
- HandleStackedControlsResourceChange(KInternalStatusPaneChange);
-}
-
-/*!
- * \brief Dynamically initializes a menu bar.
- *
- * The resource associated with the menu is given in \a resourceId, and the actual menu bar is
- * passed in \a menuBar.
- *
- * If you override this function, you should call the base class implementation as well.
- */
-void QS60MainAppUi::DynInitMenuBarL(TInt /* resourceId */, CEikMenuBar * /* menuBar */)
-{
-}
-
-/*!
- * \brief Dynamically initializes a menu pane.
- *
- * The resource associated with the menu is given in \a resourceId, and the actual menu pane is
- * passed in \a menuPane.
- *
- * If you override this function, you should call the base class implementation as well.
- */
-void QS60MainAppUi::DynInitMenuPaneL(TInt resourceId, CEikMenuPane *menuPane)
-{
-#ifdef Q_WS_S60
- if (resourceId == R_AVKON_MENUPANE_EMPTY) {
- if (menuPane->NumberOfItemsInPane() <= 1)
- QT_TRYCATCH_LEAVING(qt_symbian_show_toplevel(menuPane));
-
- } else if (resourceId != R_AVKON_MENUPANE_FEP_DEFAULT
- && resourceId != R_AVKON_MENUPANE_EDITTEXT_DEFAULT
- && resourceId != R_AVKON_MENUPANE_LANGUAGE_DEFAULT) {
- QT_TRYCATCH_LEAVING(qt_symbian_show_submenu(menuPane, resourceId));
- }
-#else
- QS60MainAppUiBase::DynInitMenuPaneL(resourceId, menuPane);
-#endif
-}
-
-/*!
- * \brief Restores a menu window.
- *
- * The menu window to restore is given in \a menuWindow. The resource ID and type of menu is given
- * in \a resourceId and \a menuType, respectively.
- *
- * If you override this function, you should call the base class implementation as well.
- */
-void QS60MainAppUi::RestoreMenuL(CCoeControl *menuWindow, TInt resourceId, TMenuType menuType)
-{
-#ifdef Q_WS_S60
- if (resourceId >= QT_SYMBIAN_FIRST_MENU_ITEM && resourceId <= QT_SYMBIAN_LAST_MENU_ITEM) {
- if (menuType == EMenuPane)
- DynInitMenuPaneL(resourceId, (CEikMenuPane*)menuWindow);
- else
- DynInitMenuBarL(resourceId, (CEikMenuBar*)menuWindow);
- } else if(resourceId == R_AVKON_MENUPANE_EMPTY) {
- CEikMenuBarTitle *title = new(ELeave) CEikMenuBarTitle;
- CleanupStack::PushL(title);
-
- title->iData.iMenuPaneResourceId = R_AVKON_MENUPANE_EMPTY;
- title->iTitleFlags = 0;
-
- S60->menuBar()->TitleArray()->AddTitleL(title);
- CleanupStack::Pop( title );
- }
- else
-#endif
- {
- QS60MainAppUiBase::RestoreMenuL(menuWindow, resourceId, menuType);
- }
-}
-
-/*!
- \internal
-*/
-void QS60MainAppUi::Exit()
-{
- QS60MainAppUiBase::Exit();
-}
-
-/*!
- \internal
-*/
-void QS60MainAppUi::SetFadedL(TBool aFaded)
-{
- QS60MainAppUiBase::SetFadedL(aFaded);
-}
-
-/*!
- \internal
-*/
-TRect QS60MainAppUi::ApplicationRect() const
-{
- return QS60MainAppUiBase::ApplicationRect();
-}
-
-/*!
- \internal
-*/
-void QS60MainAppUi::HandleScreenDeviceChangedL()
-{
- QS60MainAppUiBase::HandleScreenDeviceChangedL();
-}
-
-/*!
- \internal
-*/
-void QS60MainAppUi::HandleApplicationSpecificEventL(TInt aType, const TWsEvent &aEvent)
-{
- QS60MainAppUiBase::HandleApplicationSpecificEventL(aType, aEvent);
-}
-
-/*!
- \internal
-*/
-TTypeUid::Ptr QS60MainAppUi::MopSupplyObject(TTypeUid aId)
-{
- return QS60MainAppUiBase::MopSupplyObject(aId);
-}
-
-/*!
- \internal
-*/
-void QS60MainAppUi::ProcessCommandL(TInt aCommand)
-{
- QS60MainAppUiBase::ProcessCommandL(aCommand);
-}
-
-/*!
- \internal
-*/
-TErrorHandlerResponse QS60MainAppUi::HandleError (TInt aError, const SExtendedError &aExtErr, TDes &aErrorText, TDes &aContextText)
-{
- return QS60MainAppUiBase::HandleError(aError, aExtErr, aErrorText, aContextText);
-}
-
-/*!
- \internal
-*/
-void QS60MainAppUi::HandleViewDeactivation(const TVwsViewId &aViewIdToBeDeactivated, const TVwsViewId &aNewlyActivatedViewId)
-{
- QS60MainAppUiBase::HandleViewDeactivation(aViewIdToBeDeactivated, aNewlyActivatedViewId);
-}
-
-/*!
- \internal
-*/
-void QS60MainAppUi::PrepareToExit()
-{
- QS60MainAppUiBase::PrepareToExit();
-}
-
-/*!
- \internal
-*/
-void QS60MainAppUi::HandleTouchPaneSizeChange()
-{
- QS60MainAppUiBase::HandleTouchPaneSizeChange();
-}
-
-/*!
- \internal
-*/
-void QS60MainAppUi::HandleSystemEventL(const TWsEvent &aEvent)
-{
- QS60MainAppUiBase::HandleSystemEventL(aEvent);
-}
-
-/*!
- \internal
-*/
-void QS60MainAppUi::Reserved_MtsmPosition()
-{
- QS60MainAppUiBase::Reserved_MtsmPosition();
-}
-
-/*!
- \internal
-*/
-void QS60MainAppUi::Reserved_MtsmObject()
-{
- QS60MainAppUiBase::Reserved_MtsmObject();
-}
-
-/*!
- \internal
-*/
-void QS60MainAppUi::HandleForegroundEventL(TBool aForeground)
-{
- QS60MainAppUiBase::HandleForegroundEventL(aForeground);
-}
-
-/*!
- \internal
-*/
-TBool QS60MainAppUi::ProcessCommandParametersL(TApaCommand /*aCommand*/, TFileName &/*aDocumentName*/, const TDesC8 &/*aTail*/)
-{
- // bypass CEikAppUi::ProcessCommandParametersL(..) which modifies aDocumentName, preventing apparc document opening from working.
- // The return value is effectively unused in Qt apps (see QS60MainDocument::OpenFileL)
- return EFalse;
-}
-
-#ifndef Q_WS_S60
-
-void QS60StubAknAppUi::HandleViewDeactivation(const TVwsViewId &, const TVwsViewId &) {}
-void QS60StubAknAppUi::HandleTouchPaneSizeChange() {}
-void QS60StubAknAppUi::HandleStatusPaneSizeChange() {}
-void QS60StubAknAppUi::Reserved_MtsmPosition() {}
-void QS60StubAknAppUi::Reserved_MtsmObject() {}
-
-#endif
-
-QT_END_NAMESPACE
diff --git a/src/gui/s60framework/qs60mainappui.h b/src/gui/s60framework/qs60mainappui.h
deleted file mode 100644
index 374bc4428f..0000000000
--- a/src/gui/s60framework/qs60mainappui.h
+++ /dev/null
@@ -1,152 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the Symbian application wrapper of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QS60MAINAPPUI_H
-#define QS60MAINAPPUI_H
-
-#include <QtCore/qglobal.h>
-
-#ifdef Q_OS_SYMBIAN
-
-#ifdef Q_WS_S60
-#include <aknappui.h>
-typedef CAknAppUi QS60MainAppUiBase;
-#else
-#include <eikappui.h>
-// these stub classes simulate the structure of CAknAppUi, to help binary compatibility between Qt configured with and without S60/Avkon
-class QS60StubAknAppUiBase : public CEikAppUi
-{
-private:
- int qS60StubAknAppUiBaseSpace[4];
-};
-
-class QS60StubMEikStatusPaneObserver
-{
-public:
- virtual void HandleStatusPaneSizeChange() = 0;
-};
-
-class QS60StubMAknTouchPaneObserver
-{
-public:
- virtual void HandleTouchPaneSizeChange() = 0;
-};
-
-class QS60StubAknAppUi : public QS60StubAknAppUiBase, QS60StubMEikStatusPaneObserver,
- public MCoeViewDeactivationObserver,
- public QS60StubMAknTouchPaneObserver
-{
-public: // MCoeViewDeactivationObserver
- virtual void HandleViewDeactivation(const TVwsViewId&, const TVwsViewId &);
-
-public: // from MAknTouchPaneObserver
- virtual void HandleTouchPaneSizeChange();
-
-protected: // from MEikStatusPaneObserver
- virtual void HandleStatusPaneSizeChange();
-
-protected: // from CAknAppUi
- virtual void Reserved_MtsmPosition();
- virtual void Reserved_MtsmObject();
-
-private:
- int qS60StubAknAppUiSpace[4];
-};
-
-typedef QS60StubAknAppUi QS60MainAppUiBase;
-#endif
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class Q_GUI_EXPORT QS60MainAppUi : public QS60MainAppUiBase
-{
-public:
- QS60MainAppUi();
- // The virtuals are for qdoc.
- virtual ~QS60MainAppUi();
-
- virtual void ConstructL();
-
- virtual void RestoreMenuL(CCoeControl *menuWindow,TInt resourceId,TMenuType menuType);
- virtual void DynInitMenuBarL(TInt resourceId, CEikMenuBar *menuBar);
- virtual void DynInitMenuPaneL(TInt resourceId, CEikMenuPane *menuPane);
-
- virtual void HandleCommandL( TInt command );
-
- virtual void HandleResourceChangeL(TInt type);
-
- virtual void HandleStatusPaneSizeChange();
-
-protected:
- virtual void HandleWsEventL(const TWsEvent &event, CCoeControl *destination);
-
-public:
- virtual void Exit();
- virtual void SetFadedL(TBool aFaded);
- virtual TRect ApplicationRect() const;
- virtual void ProcessCommandL(TInt aCommand);
- virtual TErrorHandlerResponse HandleError (TInt aError, const SExtendedError &aExtErr, TDes &aErrorText, TDes &aContextText);
- virtual void HandleViewDeactivation(const TVwsViewId &aViewIdToBeDeactivated, const TVwsViewId &aNewlyActivatedViewId);
- virtual void PrepareToExit();
- virtual void HandleTouchPaneSizeChange();
- virtual TBool ProcessCommandParametersL(TApaCommand aCommand, TFileName &aDocumentName, const TDesC8 &aTail);
-
-protected:
- virtual void HandleScreenDeviceChangedL();
- virtual void HandleApplicationSpecificEventL(TInt aType, const TWsEvent &aEvent);
- virtual TTypeUid::Ptr MopSupplyObject(TTypeUid aId);
- virtual void HandleSystemEventL(const TWsEvent &aEvent);
- virtual void Reserved_MtsmPosition();
- virtual void Reserved_MtsmObject();
- virtual void HandleForegroundEventL(TBool aForeground);
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // Q_OS_SYMBIAN
-
-#endif // QS60MAINAPPUI_H
diff --git a/src/gui/s60framework/qs60maindocument.h b/src/gui/s60framework/qs60maindocument.h
deleted file mode 100644
index 6ede66a9bb..0000000000
--- a/src/gui/s60framework/qs60maindocument.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the Symbian application wrapper of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QS60MAINDOCUMENT_H
-#define QS60MAINDOCUMENT_H
-
-#include <QtCore/qglobal.h>
-
-#ifdef Q_OS_SYMBIAN
-
-#ifdef Q_WS_S60
-#include <AknDoc.h>
-typedef CAknDocument QS60MainDocumentBase;
-#else
-#include <eikdoc.h>
-typedef CEikDocument QS60MainDocumentBase;
-#endif
-
-class CEikApplication;
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QS60MainAppUi;
-
-class Q_GUI_EXPORT QS60MainDocument : public QS60MainDocumentBase
-{
-public:
-
- QS60MainDocument(CEikApplication &mainApplication);
- // The virtuals are for qdoc.
- virtual ~QS60MainDocument();
-
-public:
-
- virtual CEikAppUi *CreateAppUiL();
-
-public:
-
- virtual CFileStore *OpenFileL(TBool aDoOpen, const TDesC &aFilename, RFs &aFs);
-
- virtual void OpenFileL(CFileStore *&aFileStore, RFile &aFile);
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // Q_OS_SYMBIAN
-
-#endif // QS60MAINDOCUMENT_H
diff --git a/src/gui/statemachine/qguistatemachine.cpp b/src/gui/statemachine/qguistatemachine.cpp
deleted file mode 100644
index 45bea5ae24..0000000000
--- a/src/gui/statemachine/qguistatemachine.cpp
+++ /dev/null
@@ -1,523 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtCore/qstatemachine.h>
-
-#ifndef QT_NO_STATEMACHINE
-
-#include <private/qstatemachine_p.h>
-#include <QtGui/qevent.h>
-#include <QtGui/qgraphicssceneevent.h>
-
-QT_BEGIN_NAMESPACE
-
-Q_CORE_EXPORT const QStateMachinePrivate::Handler *qcoreStateMachineHandler();
-
-static QEvent *cloneEvent(QEvent *e)
-{
- switch (e->type()) {
- case QEvent::MouseButtonPress:
- case QEvent::MouseButtonRelease:
- case QEvent::MouseButtonDblClick:
- case QEvent::MouseMove:
- return new QMouseEvent(*static_cast<QMouseEvent*>(e));
- case QEvent::KeyPress:
- case QEvent::KeyRelease:
- return new QKeyEvent(*static_cast<QKeyEvent*>(e));
- case QEvent::FocusIn:
- case QEvent::FocusOut:
- return new QFocusEvent(*static_cast<QFocusEvent*>(e));
- case QEvent::Enter:
- return new QEvent(*e);
- case QEvent::Leave:
- return new QEvent(*e);
- break;
- case QEvent::Paint:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
- case QEvent::Move:
- return new QMoveEvent(*static_cast<QMoveEvent*>(e));
- case QEvent::Resize:
- return new QResizeEvent(*static_cast<QResizeEvent*>(e));
- case QEvent::Create:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
- case QEvent::Destroy:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
- case QEvent::Show:
- return new QShowEvent(*static_cast<QShowEvent*>(e));
- case QEvent::Hide:
- return new QHideEvent(*static_cast<QHideEvent*>(e));
- case QEvent::Close:
- return new QCloseEvent(*static_cast<QCloseEvent*>(e));
- case QEvent::Quit:
- return new QEvent(*e);
- case QEvent::ParentChange:
- return new QEvent(*e);
- case QEvent::ParentAboutToChange:
- return new QEvent(*e);
- case QEvent::ThreadChange:
- return new QEvent(*e);
-
- case QEvent::WindowActivate:
- case QEvent::WindowDeactivate:
- return new QEvent(*e);
-
- case QEvent::ShowToParent:
- return new QEvent(*e);
- case QEvent::HideToParent:
- return new QEvent(*e);
-#ifndef QT_NO_WHEELEVENT
- case QEvent::Wheel:
- return new QWheelEvent(*static_cast<QWheelEvent*>(e));
-#endif //QT_NO_WHEELEVENT
- case QEvent::WindowTitleChange:
- return new QEvent(*e);
- case QEvent::WindowIconChange:
- return new QEvent(*e);
- case QEvent::ApplicationWindowIconChange:
- return new QEvent(*e);
- case QEvent::ApplicationFontChange:
- return new QEvent(*e);
- case QEvent::ApplicationLayoutDirectionChange:
- return new QEvent(*e);
- case QEvent::ApplicationPaletteChange:
- return new QEvent(*e);
- case QEvent::PaletteChange:
- return new QEvent(*e);
- case QEvent::Clipboard:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
- case QEvent::Speech:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
- case QEvent::MetaCall:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
- case QEvent::SockAct:
- return new QEvent(*e);
- case QEvent::WinEventAct:
- return new QEvent(*e);
- case QEvent::DeferredDelete:
- return new QEvent(*e);
-#ifndef QT_NO_DRAGANDDROP
- case QEvent::DragEnter:
- return new QDragEnterEvent(*static_cast<QDragEnterEvent*>(e));
- case QEvent::DragMove:
- return new QDragMoveEvent(*static_cast<QDragMoveEvent*>(e));
- case QEvent::DragLeave:
- return new QDragLeaveEvent(*static_cast<QDragLeaveEvent*>(e));
- case QEvent::Drop:
- return new QDropEvent(*static_cast<QDragMoveEvent*>(e));
- case QEvent::DragResponse:
- return new QDragResponseEvent(*static_cast<QDragResponseEvent*>(e));
-#endif
- case QEvent::ChildAdded:
- return new QChildEvent(*static_cast<QChildEvent*>(e));
- case QEvent::ChildPolished:
- return new QChildEvent(*static_cast<QChildEvent*>(e));
-#ifdef QT3_SUPPORT
- case QEvent::ChildInsertedRequest:
- return new QEvent(*e);
- case QEvent::ChildInserted:
- return new QChildEvent(*static_cast<QChildEvent*>(e));
- case QEvent::LayoutHint:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
-#endif
- case QEvent::ChildRemoved:
- return new QChildEvent(*static_cast<QChildEvent*>(e));
- case QEvent::ShowWindowRequest:
- return new QEvent(*e);
- case QEvent::PolishRequest:
- return new QEvent(*e);
- case QEvent::Polish:
- return new QEvent(*e);
- case QEvent::LayoutRequest:
- return new QEvent(*e);
- case QEvent::UpdateRequest:
- return new QEvent(*e);
- case QEvent::UpdateLater:
- return new QEvent(*e);
-
- case QEvent::EmbeddingControl:
- return new QEvent(*e);
- case QEvent::ActivateControl:
- return new QEvent(*e);
- case QEvent::DeactivateControl:
- return new QEvent(*e);
-
-#ifndef QT_NO_CONTEXTMENU
- case QEvent::ContextMenu:
- return new QContextMenuEvent(*static_cast<QContextMenuEvent*>(e));
-#endif
- case QEvent::InputMethod:
- return new QInputMethodEvent(*static_cast<QInputMethodEvent*>(e));
- case QEvent::AccessibilityPrepare:
- return new QEvent(*e);
-#ifndef QT_NO_TABLETEVENT
- case QEvent::TabletMove:
- return new QTabletEvent(*static_cast<QTabletEvent*>(e));
-#endif //QT_NO_TABLETEVENT
- case QEvent::LocaleChange:
- return new QEvent(*e);
- case QEvent::LanguageChange:
- return new QEvent(*e);
- case QEvent::LayoutDirectionChange:
- return new QEvent(*e);
- case QEvent::Style:
- return new QEvent(*e);
-#ifndef QT_NO_TABLETEVENT
- case QEvent::TabletPress:
- return new QTabletEvent(*static_cast<QTabletEvent*>(e));
- case QEvent::TabletRelease:
- return new QTabletEvent(*static_cast<QTabletEvent*>(e));
-#endif //QT_NO_TABLETEVENT
- case QEvent::OkRequest:
- return new QEvent(*e);
- case QEvent::HelpRequest:
- return new QEvent(*e);
-
- case QEvent::IconDrag:
- return new QIconDragEvent(*static_cast<QIconDragEvent*>(e));
-
- case QEvent::FontChange:
- return new QEvent(*e);
- case QEvent::EnabledChange:
- return new QEvent(*e);
- case QEvent::ActivationChange:
- return new QEvent(*e);
- case QEvent::StyleChange:
- return new QEvent(*e);
- case QEvent::IconTextChange:
- return new QEvent(*e);
- case QEvent::ModifiedChange:
- return new QEvent(*e);
- case QEvent::MouseTrackingChange:
- return new QEvent(*e);
-
- case QEvent::WindowBlocked:
- return new QEvent(*e);
- case QEvent::WindowUnblocked:
- return new QEvent(*e);
- case QEvent::WindowStateChange:
- return new QWindowStateChangeEvent(*static_cast<QWindowStateChangeEvent*>(e));
-
- case QEvent::ToolTip:
- return new QHelpEvent(*static_cast<QHelpEvent*>(e));
- case QEvent::WhatsThis:
- return new QHelpEvent(*static_cast<QHelpEvent*>(e));
-#ifndef QT_NO_STATUSTIP
- case QEvent::StatusTip:
- return new QStatusTipEvent(*static_cast<QStatusTipEvent*>(e));
-#endif //QT_NO_STATUSTIP
-#ifndef QT_NO_ACTION
- case QEvent::ActionChanged:
- case QEvent::ActionAdded:
- case QEvent::ActionRemoved:
- return new QActionEvent(*static_cast<QActionEvent*>(e));
-#endif
- case QEvent::FileOpen:
- return new QFileOpenEvent(*static_cast<QFileOpenEvent*>(e));
-
-#ifndef QT_NO_SHORTCUT
- case QEvent::Shortcut:
- return new QShortcutEvent(*static_cast<QShortcutEvent*>(e));
-#endif //QT_NO_SHORTCUT
- case QEvent::ShortcutOverride:
- return new QKeyEvent(*static_cast<QKeyEvent*>(e));
-
-#ifdef QT3_SUPPORT
- case QEvent::Accel:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
- case QEvent::AccelAvailable:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
-#endif
-
-#ifndef QT_NO_WHATSTHIS
- case QEvent::WhatsThisClicked:
- return new QWhatsThisClickedEvent(*static_cast<QWhatsThisClickedEvent*>(e));
-#endif //QT_NO_WHATSTHIS
-
-#ifndef QT_NO_TOOLBAR
- case QEvent::ToolBarChange:
- return new QToolBarChangeEvent(*static_cast<QToolBarChangeEvent*>(e));
-#endif //QT_NO_TOOLBAR
-
- case QEvent::ApplicationActivate:
- return new QEvent(*e);
- case QEvent::ApplicationDeactivate:
- return new QEvent(*e);
-
- case QEvent::QueryWhatsThis:
- return new QHelpEvent(*static_cast<QHelpEvent*>(e));
- case QEvent::EnterWhatsThisMode:
- return new QEvent(*e);
- case QEvent::LeaveWhatsThisMode:
- return new QEvent(*e);
-
- case QEvent::ZOrderChange:
- return new QEvent(*e);
-
- case QEvent::HoverEnter:
- case QEvent::HoverLeave:
- case QEvent::HoverMove:
- return new QHoverEvent(*static_cast<QHoverEvent*>(e));
-
- case QEvent::AccessibilityHelp:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
- case QEvent::AccessibilityDescription:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
-
-#ifdef QT_KEYPAD_NAVIGATION
- case QEvent::EnterEditFocus:
- return new QEvent(*e);
- case QEvent::LeaveEditFocus:
- return new QEvent(*e);
-#endif
- case QEvent::AcceptDropsChange:
- return new QEvent(*e);
-
-#ifdef QT3_SUPPORT
- case QEvent::MenubarUpdated:
- return new QMenubarUpdatedEvent(*static_cast<QMenubarUpdatedEvent*>(e));
-#endif
-
- case QEvent::ZeroTimerEvent:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
-#ifndef QT_NO_GRAPHICSVIEW
- case QEvent::GraphicsSceneMouseMove:
- case QEvent::GraphicsSceneMousePress:
- case QEvent::GraphicsSceneMouseRelease:
- case QEvent::GraphicsSceneMouseDoubleClick: {
- QGraphicsSceneMouseEvent *me = static_cast<QGraphicsSceneMouseEvent*>(e);
- QGraphicsSceneMouseEvent *me2 = new QGraphicsSceneMouseEvent(me->type());
- me2->setWidget(me->widget());
- me2->setPos(me->pos());
- me2->setScenePos(me->scenePos());
- me2->setScreenPos(me->screenPos());
-// ### for all buttons
- me2->setButtonDownPos(Qt::LeftButton, me->buttonDownPos(Qt::LeftButton));
- me2->setButtonDownPos(Qt::RightButton, me->buttonDownPos(Qt::RightButton));
- me2->setButtonDownScreenPos(Qt::LeftButton, me->buttonDownScreenPos(Qt::LeftButton));
- me2->setButtonDownScreenPos(Qt::RightButton, me->buttonDownScreenPos(Qt::RightButton));
- me2->setLastPos(me->lastPos());
- me2->setLastScenePos(me->lastScenePos());
- me2->setLastScreenPos(me->lastScreenPos());
- me2->setButtons(me->buttons());
- me2->setButton(me->button());
- me2->setModifiers(me->modifiers());
- return me2;
- }
-
- case QEvent::GraphicsSceneContextMenu: {
- QGraphicsSceneContextMenuEvent *me = static_cast<QGraphicsSceneContextMenuEvent*>(e);
- QGraphicsSceneContextMenuEvent *me2 = new QGraphicsSceneContextMenuEvent(me->type());
- me2->setWidget(me->widget());
- me2->setPos(me->pos());
- me2->setScenePos(me->scenePos());
- me2->setScreenPos(me->screenPos());
- me2->setModifiers(me->modifiers());
- me2->setReason(me->reason());
- return me2;
- }
-
- case QEvent::GraphicsSceneHoverEnter:
- case QEvent::GraphicsSceneHoverMove:
- case QEvent::GraphicsSceneHoverLeave: {
- QGraphicsSceneHoverEvent *he = static_cast<QGraphicsSceneHoverEvent*>(e);
- QGraphicsSceneHoverEvent *he2 = new QGraphicsSceneHoverEvent(he->type());
- he2->setPos(he->pos());
- he2->setScenePos(he->scenePos());
- he2->setScreenPos(he->screenPos());
- he2->setLastPos(he->lastPos());
- he2->setLastScenePos(he->lastScenePos());
- he2->setLastScreenPos(he->lastScreenPos());
- he2->setModifiers(he->modifiers());
- return he2;
- }
- case QEvent::GraphicsSceneHelp:
- return new QHelpEvent(*static_cast<QHelpEvent*>(e));
- case QEvent::GraphicsSceneDragEnter:
- case QEvent::GraphicsSceneDragMove:
- case QEvent::GraphicsSceneDragLeave:
- case QEvent::GraphicsSceneDrop: {
- QGraphicsSceneDragDropEvent *dde = static_cast<QGraphicsSceneDragDropEvent*>(e);
- QGraphicsSceneDragDropEvent *dde2 = new QGraphicsSceneDragDropEvent(dde->type());
- dde2->setPos(dde->pos());
- dde2->setScenePos(dde->scenePos());
- dde2->setScreenPos(dde->screenPos());
- dde2->setButtons(dde->buttons());
- dde2->setModifiers(dde->modifiers());
- return dde2;
- }
- case QEvent::GraphicsSceneWheel: {
- QGraphicsSceneWheelEvent *we = static_cast<QGraphicsSceneWheelEvent*>(e);
- QGraphicsSceneWheelEvent *we2 = new QGraphicsSceneWheelEvent(we->type());
- we2->setPos(we->pos());
- we2->setScenePos(we->scenePos());
- we2->setScreenPos(we->screenPos());
- we2->setButtons(we->buttons());
- we2->setModifiers(we->modifiers());
- we2->setOrientation(we->orientation());
- we2->setDelta(we->delta());
- return we2;
- }
-#endif
- case QEvent::KeyboardLayoutChange:
- return new QEvent(*e);
-
- case QEvent::DynamicPropertyChange:
- return new QDynamicPropertyChangeEvent(*static_cast<QDynamicPropertyChangeEvent*>(e));
-
-#ifndef QT_NO_TABLETEVENT
- case QEvent::TabletEnterProximity:
- case QEvent::TabletLeaveProximity:
- return new QTabletEvent(*static_cast<QTabletEvent*>(e));
-#endif //QT_NO_TABLETEVENT
-
- case QEvent::NonClientAreaMouseMove:
- case QEvent::NonClientAreaMouseButtonPress:
- case QEvent::NonClientAreaMouseButtonRelease:
- case QEvent::NonClientAreaMouseButtonDblClick:
- return new QMouseEvent(*static_cast<QMouseEvent*>(e));
-
- case QEvent::MacSizeChange:
- return new QEvent(*e);
-
- case QEvent::ContentsRectChange:
- return new QEvent(*e);
-
- case QEvent::MacGLWindowChange:
- return new QEvent(*e);
-
- case QEvent::FutureCallOut:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
-#ifndef QT_NO_GRAPHICSVIEW
- case QEvent::GraphicsSceneResize: {
- QGraphicsSceneResizeEvent *re = static_cast<QGraphicsSceneResizeEvent*>(e);
- QGraphicsSceneResizeEvent *re2 = new QGraphicsSceneResizeEvent();
- re2->setOldSize(re->oldSize());
- re2->setNewSize(re->newSize());
- return re2;
- }
- case QEvent::GraphicsSceneMove: {
- QGraphicsSceneMoveEvent *me = static_cast<QGraphicsSceneMoveEvent*>(e);
- QGraphicsSceneMoveEvent *me2 = new QGraphicsSceneMoveEvent();
- me2->setWidget(me->widget());
- me2->setNewPos(me->newPos());
- me2->setOldPos(me->oldPos());
- return me2;
- }
-#endif
- case QEvent::CursorChange:
- return new QEvent(*e);
- case QEvent::ToolTipChange:
- return new QEvent(*e);
-
- case QEvent::NetworkReplyUpdated:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
-
- case QEvent::GrabMouse:
- case QEvent::UngrabMouse:
- case QEvent::GrabKeyboard:
- case QEvent::UngrabKeyboard:
- return new QEvent(*e);
-
- case QEvent::TouchBegin:
- case QEvent::TouchUpdate:
- case QEvent::TouchEnd:
- return new QTouchEvent(*static_cast<QTouchEvent*>(e));
-
-#ifndef QT_NO_GESTURES
- case QEvent::NativeGesture:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
-#endif
-
- case QEvent::RequestSoftwareInputPanel:
- case QEvent::CloseSoftwareInputPanel:
- return new QEvent(*e);
-
- case QEvent::UpdateSoftKeys:
- return new QEvent(*e);
-
- case QEvent::User:
- case QEvent::MaxUser:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
- default:
- ;
- }
- return qcoreStateMachineHandler()->cloneEvent(e);
-}
-
-const QStateMachinePrivate::Handler qt_gui_statemachine_handler = {
- cloneEvent
-};
-
-static const QStateMachinePrivate::Handler *qt_guistatemachine_last_handler = 0;
-int qRegisterGuiStateMachine()
-{
- qt_guistatemachine_last_handler = QStateMachinePrivate::handler;
- QStateMachinePrivate::handler = &qt_gui_statemachine_handler;
- return 1;
-}
-Q_CONSTRUCTOR_FUNCTION(qRegisterGuiStateMachine)
-
-int qUnregisterGuiStateMachine()
-{
- QStateMachinePrivate::handler = qt_guistatemachine_last_handler;
- return 1;
-}
-Q_DESTRUCTOR_FUNCTION(qUnregisterGuiStateMachine)
-
-QT_END_NAMESPACE
-
-#endif //QT_NO_STATEMACHINE
diff --git a/src/gui/statemachine/qkeyeventtransition.h b/src/gui/statemachine/qkeyeventtransition.h
deleted file mode 100644
index caa540a5d9..0000000000
--- a/src/gui/statemachine/qkeyeventtransition.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QKEYEVENTTRANSITION_H
-#define QKEYEVENTTRANSITION_H
-
-#include <QtCore/qeventtransition.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_STATEMACHINE
-
-class QKeyEventTransitionPrivate;
-class Q_GUI_EXPORT QKeyEventTransition : public QEventTransition
-{
- Q_OBJECT
- Q_PROPERTY(int key READ key WRITE setKey)
- Q_PROPERTY(Qt::KeyboardModifiers modifierMask READ modifierMask WRITE setModifierMask)
-public:
- QKeyEventTransition(QState *sourceState = 0);
- QKeyEventTransition(QObject *object, QEvent::Type type, int key,
- QState *sourceState = 0);
- ~QKeyEventTransition();
-
- int key() const;
- void setKey(int key);
-
- Qt::KeyboardModifiers modifierMask() const;
- void setModifierMask(Qt::KeyboardModifiers modifiers);
-
-protected:
- void onTransition(QEvent *event);
- bool eventTest(QEvent *event);
-
-private:
- Q_DISABLE_COPY(QKeyEventTransition)
- Q_DECLARE_PRIVATE(QKeyEventTransition)
-};
-
-#endif //QT_NO_STATEMACHINE
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif
diff --git a/src/gui/statemachine/qmouseeventtransition.h b/src/gui/statemachine/qmouseeventtransition.h
deleted file mode 100644
index 1304b43b0e..0000000000
--- a/src/gui/statemachine/qmouseeventtransition.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QMOUSEEVENTTRANSITION_H
-#define QMOUSEEVENTTRANSITION_H
-
-#include <QtCore/qeventtransition.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_STATEMACHINE
-
-class QMouseEventTransitionPrivate;
-class QPainterPath;
-class Q_GUI_EXPORT QMouseEventTransition : public QEventTransition
-{
- Q_OBJECT
- Q_PROPERTY(Qt::MouseButton button READ button WRITE setButton)
- Q_PROPERTY(Qt::KeyboardModifiers modifierMask READ modifierMask WRITE setModifierMask)
-public:
- QMouseEventTransition(QState *sourceState = 0);
- QMouseEventTransition(QObject *object, QEvent::Type type,
- Qt::MouseButton button, QState *sourceState = 0);
- ~QMouseEventTransition();
-
- Qt::MouseButton button() const;
- void setButton(Qt::MouseButton button);
-
- Qt::KeyboardModifiers modifierMask() const;
- void setModifierMask(Qt::KeyboardModifiers modifiers);
-
- QPainterPath hitTestPath() const;
- void setHitTestPath(const QPainterPath &path);
-
-protected:
- void onTransition(QEvent *event);
- bool eventTest(QEvent *event);
-
-private:
- Q_DISABLE_COPY(QMouseEventTransition)
- Q_DECLARE_PRIVATE(QMouseEventTransition)
-};
-
-#endif //QT_NO_STATEMACHINE
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif
diff --git a/src/gui/styles/qcdestyle.h b/src/gui/styles/qcdestyle.h
deleted file mode 100644
index 259ac26b6c..0000000000
--- a/src/gui/styles/qcdestyle.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#ifndef QCDESTYLE_H
-#define QCDESTYLE_H
-
-#include <QtGui/qmotifstyle.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#if !defined(QT_NO_STYLE_CDE)
-
-class Q_GUI_EXPORT QCDEStyle : public QMotifStyle
-{
- Q_OBJECT
-public:
- explicit QCDEStyle(bool useHighlightCols = false);
- virtual ~QCDEStyle();
-
- int pixelMetric(PixelMetric metric, const QStyleOption *option = 0,
- const QWidget *widget = 0) const;
- void drawControl(ControlElement element, const QStyleOption *opt, QPainter *p,
- const QWidget *w = 0) const;
- void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p,
- const QWidget *w = 0) const;
- QPalette standardPalette() const;
-
-protected Q_SLOTS:
- QIcon standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *opt = 0,
- const QWidget *widget = 0) const;
-};
-
-#endif // QT_NO_STYLE_CDE
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QCDESTYLE_H
diff --git a/src/gui/styles/qcleanlooksstyle.h b/src/gui/styles/qcleanlooksstyle.h
deleted file mode 100644
index 690b764c0c..0000000000
--- a/src/gui/styles/qcleanlooksstyle.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QCLEANLOOKSSTYLE_H
-#define QCLEANLOOKSSTYLE_H
-
-#include <QtGui/qwindowsstyle.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#if !defined(QT_NO_STYLE_CLEANLOOKS)
-
-class QCleanlooksStylePrivate;
-class Q_GUI_EXPORT QCleanlooksStyle : public QWindowsStyle
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QCleanlooksStyle)
-
-public:
- QCleanlooksStyle();
- ~QCleanlooksStyle();
-
- QPalette standardPalette () const;
- void drawPrimitive(PrimitiveElement elem,
- const QStyleOption *option,
- QPainter *painter, const QWidget *widget = 0) const;
- void drawControl(ControlElement ce, const QStyleOption *option, QPainter *painter,
- const QWidget *widget) const;
- int pixelMetric(PixelMetric metric, const QStyleOption *option = 0, const QWidget *widget = 0) const;
- void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option,
- QPainter *painter, const QWidget *widget) const;
- QRect subElementRect(SubElement r, const QStyleOption *opt, const QWidget *widget = 0) const;
- QSize sizeFromContents(ContentsType type, const QStyleOption *option,
- const QSize &size, const QWidget *widget) const;
- SubControl hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt,
- const QPoint &pt, const QWidget *w = 0) const;
- QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt,
- SubControl sc, const QWidget *widget) const;
- QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap,
- const QStyleOption *opt) const;
- int styleHint(StyleHint hint, const QStyleOption *option = 0, const QWidget *widget = 0,
- QStyleHintReturn *returnData = 0) const;
- QRect itemPixmapRect(const QRect &r, int flags, const QPixmap &pixmap) const;
- QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt,
- const QWidget *widget = 0) const;
- void drawItemPixmap(QPainter *painter, const QRect &rect,
- int alignment, const QPixmap &pixmap) const;
- void drawItemText(QPainter *painter, const QRect &rect,
- int flags, const QPalette &pal, bool enabled,
- const QString &text, QPalette::ColorRole textRole = QPalette::NoRole) const;
- void polish(QWidget *widget);
- void polish(QApplication *app);
- void polish(QPalette &pal);
- void unpolish(QWidget *widget);
- void unpolish(QApplication *app);
-
-protected Q_SLOTS:
- QIcon standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *option,
- const QWidget *widget = 0) const;
-
-protected:
- QCleanlooksStyle(QCleanlooksStylePrivate &dd);
-
-};
-
-#endif // QT_NO_STYLE_CLEANLOOKS
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QCLEANLOOKSSTYLE_H
diff --git a/src/gui/styles/qcommonstyle.h b/src/gui/styles/qcommonstyle.h
deleted file mode 100644
index e879f0d4a3..0000000000
--- a/src/gui/styles/qcommonstyle.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QCOMMONSTYLE_H
-#define QCOMMONSTYLE_H
-
-#include <QtGui/qstyle.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-QT_MODULE(Gui)
-
-class QCommonStylePrivate;
-
-class Q_GUI_EXPORT QCommonStyle: public QStyle
-{
- Q_OBJECT
-
-public:
- QCommonStyle();
- ~QCommonStyle();
-
- void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p,
- const QWidget *w = 0) const;
- void drawControl(ControlElement element, const QStyleOption *opt, QPainter *p,
- const QWidget *w = 0) const;
- QRect subElementRect(SubElement r, const QStyleOption *opt, const QWidget *widget = 0) const;
- void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p,
- const QWidget *w = 0) const;
- SubControl hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt,
- const QPoint &pt, const QWidget *w = 0) const;
- QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc,
- const QWidget *w = 0) const;
- QSize sizeFromContents(ContentsType ct, const QStyleOption *opt,
- const QSize &contentsSize, const QWidget *widget = 0) const;
-
- int pixelMetric(PixelMetric m, const QStyleOption *opt = 0, const QWidget *widget = 0) const;
-
- int styleHint(StyleHint sh, const QStyleOption *opt = 0, const QWidget *w = 0,
- QStyleHintReturn *shret = 0) const;
-
- QPixmap standardPixmap(StandardPixmap sp, const QStyleOption *opt = 0,
- const QWidget *widget = 0) const;
-
- QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap,
- const QStyleOption *opt) const;
-
- void polish(QPalette &);
- void polish(QApplication *app);
- void polish(QWidget *widget);
- void unpolish(QWidget *widget);
- void unpolish(QApplication *application);
-
-protected Q_SLOTS:
- QIcon standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *opt = 0,
- const QWidget *widget = 0) const;
-
-protected:
- QCommonStyle(QCommonStylePrivate &dd);
-
-private:
- Q_DECLARE_PRIVATE(QCommonStyle)
- Q_DISABLE_COPY(QCommonStyle)
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QCOMMONSTYLE_H
diff --git a/src/gui/styles/qgtkpainter.cpp b/src/gui/styles/qgtkpainter.cpp
deleted file mode 100644
index 0b1c3d3328..0000000000
--- a/src/gui/styles/qgtkpainter.cpp
+++ /dev/null
@@ -1,716 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qgtkpainter_p.h"
-
-#include <QtCore/qglobal.h>
-#if !defined(QT_NO_STYLE_GTK)
-
-// This class is primarily a wrapper around the gtk painter functions
-// and takes care of converting all such calls into cached Qt pixmaps.
-
-#include <private/qstylehelper_p.h>
-#include <QtGui/QWidget>
-#include <QtGui/QStyleOption>
-#include <QtGui/QPixmapCache>
-
-QT_BEGIN_NAMESPACE
-
-#undef GTK_OBJECT_FLAGS
-#define GTK_OBJECT_FLAGS(obj)(((GtkObject*)(obj))->flags)
-
-#if Q_BYTE_ORDER == Q_BIG_ENDIAN
-# define QT_RED 3
-# define QT_GREEN 2
-# define QT_BLUE 1
-# define QT_ALPHA 0
-#else
-# define QT_RED 0
-# define QT_GREEN 1
-# define QT_BLUE 2
-# define QT_ALPHA 3
-#endif
-# define GTK_RED 2
-# define GTK_GREEN 1
-# define GTK_BLUE 0
-# define GTK_ALPHA 3
-
-// To recover alpha we apply the gtk painting function two times to
-// white, and black window backgrounds. This can be used to
-// recover the premultiplied alpha channel
-QPixmap QGtkPainter::renderTheme(uchar *bdata, uchar *wdata, const QRect &rect)
-{
- const int bytecount = rect.width() * rect.height() * 4;
- for (int index = 0; index < bytecount ; index += 4) {
- uchar val = bdata[index + GTK_BLUE];
- if (m_alpha) {
- int alphaval = qMax(bdata[index + GTK_BLUE] - wdata[index + GTK_BLUE],
- bdata[index + GTK_GREEN] - wdata[index + GTK_GREEN]);
- alphaval = qMax(alphaval, bdata[index + GTK_RED] - wdata[index + GTK_RED]) + 255;
- bdata[index + QT_ALPHA] = alphaval;
- }
- bdata[index + QT_RED] = bdata[index + GTK_RED];
- bdata[index + QT_GREEN] = bdata[index + GTK_GREEN];
- bdata[index + QT_BLUE] = val;
- }
- QImage converted((const uchar*)bdata, rect.width(), rect.height(), m_alpha ?
- QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32);
-
- if (m_hflipped || m_vflipped) {
- return QPixmap::fromImage(converted.mirrored(m_hflipped, m_vflipped));
- } else {
- // on raster graphicssystem we need to do a copy here, because
- // we intend to deallocate the qimage bits shortly after...
- return QPixmap::fromImage(converted.copy());
- }
-}
-
-// This macro is responsible for painting any GtkStyle painting function onto a QPixmap
-#define DRAW_TO_CACHE(draw_func) \
- if (rect.width() > QWIDGETSIZE_MAX || rect.height() > QWIDGETSIZE_MAX) \
- return; \
- QRect pixmapRect(0, 0, rect.width(), rect.height()); \
- { \
- GdkPixmap *pixmap = QGtkStylePrivate::gdk_pixmap_new((GdkDrawable*)(m_window->window), \
- rect.width(), rect.height(), -1); \
- if (!pixmap) \
- return; \
- style = QGtkStylePrivate::gtk_style_attach (style, m_window->window); \
- QGtkStylePrivate::gdk_draw_rectangle(pixmap, m_alpha ? style->black_gc : *style->bg_gc, true, \
- 0, 0, rect.width(), rect.height()); \
- draw_func; \
- GdkPixbuf *imgb = QGtkStylePrivate::gdk_pixbuf_new(GDK_COLORSPACE_RGB, true, 8, rect.width(), rect.height());\
- if (!imgb) \
- return; \
- imgb = QGtkStylePrivate::gdk_pixbuf_get_from_drawable(imgb, pixmap, NULL, 0, 0, 0, 0, \
- rect.width(), rect.height()); \
- uchar* bdata = (uchar*)QGtkStylePrivate::gdk_pixbuf_get_pixels(imgb); \
- if (m_alpha) { \
- QGtkStylePrivate::gdk_draw_rectangle(pixmap, style->white_gc, true, 0, 0, rect.width(), rect.height()); \
- draw_func; \
- GdkPixbuf *imgw = QGtkStylePrivate::gdk_pixbuf_new(GDK_COLORSPACE_RGB, true, 8, rect. \
- width(), rect.height()); \
- if (!imgw) \
- return; \
- imgw = QGtkStylePrivate::gdk_pixbuf_get_from_drawable(imgw, pixmap, NULL, 0, 0, 0, 0, \
- rect.width(), rect.height()); \
- uchar* wdata = (uchar*)QGtkStylePrivate::gdk_pixbuf_get_pixels(imgw); \
- cache = renderTheme(bdata, wdata, rect); \
- QGtkStylePrivate::gdk_pixbuf_unref(imgw); \
- } else { \
- cache = renderTheme(bdata, 0, rect); \
- } \
- QGtkStylePrivate::gdk_drawable_unref(pixmap); \
- QGtkStylePrivate::gdk_pixbuf_unref(imgb); \
- }
-
-QGtkPainter::QGtkPainter(QPainter *_painter)
- : m_window(QGtkStylePrivate::gtkWidget("GtkWindow"))
- , m_painter(_painter)
- , m_alpha(true)
- , m_hflipped(false)
- , m_vflipped(false)
- , m_usePixmapCache(true)
-{}
-
-
-static QString uniqueName(const QString &key, GtkStateType state, GtkShadowType shadow,
- const QSize &size, GtkWidget *widget = 0)
-{
- // Note the widget arg should ideally use the widget path, though would compromise performance
- QString tmp = key
- % HexString<uint>(state)
- % HexString<uint>(shadow)
- % HexString<uint>(size.width())
- % HexString<uint>(size.height())
- % HexString<quint64>(quint64(widget));
- return tmp;
-}
-
-
-GtkStateType QGtkPainter::gtkState(const QStyleOption *option)
-
-{
- GtkStateType state = GTK_STATE_NORMAL;
- if (!(option->state & QStyle::State_Enabled))
- state = GTK_STATE_INSENSITIVE;
- else if (option->state & QStyle::State_MouseOver)
- state = GTK_STATE_PRELIGHT;
-
- return state;
-}
-
-
-GtkStyle* QGtkPainter::getStyle(GtkWidget *gtkWidget)
-
-{
- Q_ASSERT(gtkWidget);
- GtkStyle* style = gtkWidget->style;
- Q_ASSERT(style);
- return style;
-}
-
-QPixmap QGtkPainter::getIcon(const char* iconName, GtkIconSize size)
-{
- GtkStyle *style = QGtkStylePrivate::gtkStyle();
- GtkIconSet* iconSet = QGtkStylePrivate::gtk_icon_factory_lookup_default (iconName);
- GdkPixbuf* icon = QGtkStylePrivate::gtk_icon_set_render_icon(iconSet,
- style,
- GTK_TEXT_DIR_LTR,
- GTK_STATE_NORMAL,
- size,
- NULL,
- "button");
- uchar* data = (uchar*)QGtkStylePrivate::gdk_pixbuf_get_pixels(icon);
- int width = QGtkStylePrivate::gdk_pixbuf_get_width(icon);
- int height = QGtkStylePrivate::gdk_pixbuf_get_height(icon);
- QImage converted(width, height, QImage::Format_ARGB32);
- uchar* tdata = (uchar*)converted.bits();
-
- for ( int index = 0 ; index < height * width*4 ; index +=4 ) {
- //int index = y * rowstride + x;
- tdata[index + QT_RED] = data[index + GTK_RED];
- tdata[index + QT_GREEN] = data[index + GTK_GREEN];
- tdata[index + QT_BLUE] = data[index + GTK_BLUE];
- tdata[index + QT_ALPHA] = data[index + GTK_ALPHA];
- }
-
- QGtkStylePrivate::gdk_pixbuf_unref(icon);
-
- // should we free iconset?
- return QPixmap::fromImage(converted);
-
-}
-
-// Note currently painted without alpha for performance reasons
-void QGtkPainter::paintBoxGap(GtkWidget *gtkWidget, const gchar* part,
- const QRect &paintRect, GtkStateType state,
- GtkShadowType shadow, GtkPositionType gap_side,
- gint x, gint width,
- GtkStyle *style)
-{
- if (!paintRect.isValid())
- return;
-
- QPixmap cache;
- QRect rect = paintRect;
-
- // To avoid exhausting cache on large tabframes we cheat a bit by
- // tiling the center part.
-
- const int maxHeight = 256;
- const int border = 16;
- if (rect.height() > maxHeight && (gap_side == GTK_POS_TOP || gap_side == GTK_POS_BOTTOM))
- rect.setHeight(2 * border + 1);
-
- QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size(), gtkWidget)
- % HexString<uchar>(gap_side)
- % HexString<gint>(width)
- % HexString<gint>(x);
-
- if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
- DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_box_gap (style,
- pixmap,
- state,
- shadow,
- NULL,
- gtkWidget,
- (gchar*)part,
- 0, 0,
- rect.width(),
- rect.height(),
- gap_side,
- x,
- width));
- if (m_usePixmapCache)
- QPixmapCache::insert(pixmapName, cache);
- }
- if (rect.size() != paintRect.size()) {
- // We assume we can stretch the middle tab part
- // Note: the side effect of this is that pinstripe patterns will get fuzzy
- const QSize size = cache.size();
- // top part
- m_painter->drawPixmap(QRect(paintRect.left(), paintRect.top(),
- paintRect.width(), border), cache,
- QRect(0, 0, size.width(), border));
-
- // tiled center part
- QPixmap tilePart(cache.width(), 1);
- QPainter scanLinePainter(&tilePart);
- scanLinePainter.drawPixmap(QRect(0, 0, tilePart.width(), tilePart.height()), cache, QRect(0, border, size.width(), 1));
- scanLinePainter.end();
- m_painter->drawTiledPixmap(QRect(paintRect.left(), paintRect.top() + border,
- paintRect.width(), paintRect.height() - 2*border), tilePart);
-
- // bottom part
- m_painter->drawPixmap(QRect(paintRect.left(), paintRect.top() + paintRect.height() - border,
- paintRect.width(), border), cache,
- QRect(0, size.height() - border, size.width(), border));
- } else
- m_painter->drawPixmap(paintRect.topLeft(), cache);
-}
-
-void QGtkPainter::paintBox(GtkWidget *gtkWidget, const gchar* part,
- const QRect &paintRect, GtkStateType state,
- GtkShadowType shadow, GtkStyle *style,
- const QString &pmKey)
-{
- if (!paintRect.isValid())
- return;
-
- QPixmap cache;
- QRect rect = paintRect;
-
- // To avoid exhausting cache on large tabframes we cheat a bit by
- // tiling the center part.
-
- const int maxHeight = 256;
- const int maxArea = 256*512;
- const int border = 32;
- if (rect.height() > maxHeight && (rect.width()*rect.height() > maxArea))
- rect.setHeight(2 * border + 1);
-
- QString pixmapName = uniqueName(QLS(part), state, shadow,
- rect.size(), gtkWidget) % pmKey;
-
- if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
- DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_box (style,
- pixmap,
- state,
- shadow,
- NULL,
- gtkWidget,
- part,
- 0, 0,
- rect.width(),
- rect.height()));
- if (m_usePixmapCache)
- QPixmapCache::insert(pixmapName, cache);
- }
- if (rect.size() != paintRect.size()) {
- // We assume we can stretch the middle tab part
- // Note: the side effect of this is that pinstripe patterns will get fuzzy
- const QSize size = cache.size();
- // top part
- m_painter->drawPixmap(QRect(paintRect.left(), paintRect.top(),
- paintRect.width(), border), cache,
- QRect(0, 0, size.width(), border));
-
- // tiled center part
- QPixmap tilePart(cache.width(), 1);
- QPainter scanLinePainter(&tilePart);
- scanLinePainter.drawPixmap(QRect(0, 0, tilePart.width(), tilePart.height()), cache, QRect(0, border, size.width(), 1));
- scanLinePainter.end();
- m_painter->drawTiledPixmap(QRect(paintRect.left(), paintRect.top() + border,
- paintRect.width(), paintRect.height() - 2*border), tilePart);
-
- // bottom part
- m_painter->drawPixmap(QRect(paintRect.left(), paintRect.top() + paintRect.height() - border,
- paintRect.width(), border), cache,
- QRect(0, size.height() - border, size.width(), border));
- } else
- m_painter->drawPixmap(paintRect.topLeft(), cache);
-}
-
-void QGtkPainter::paintHline(GtkWidget *gtkWidget, const gchar* part,
- const QRect &rect, GtkStateType state,
- GtkStyle *style, int x1, int x2, int y,
- const QString &pmKey)
-{
- if (!rect.isValid())
- return;
-
- QPixmap cache;
- QString pixmapName = uniqueName(QLS(part), state, GTK_SHADOW_NONE, rect.size(), gtkWidget)
- % HexString<int>(x1)
- % HexString<int>(x2)
- % HexString<int>(y)
- % pmKey;
- if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
- DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_hline (style,
- pixmap,
- state,
- NULL,
- gtkWidget,
- part,
- x1, x2, y));
- if (m_usePixmapCache)
- QPixmapCache::insert(pixmapName, cache);
- }
-
- m_painter->drawPixmap(rect.topLeft(), cache);
-}
-
-void QGtkPainter::paintVline(GtkWidget *gtkWidget, const gchar* part,
- const QRect &rect, GtkStateType state,
- GtkStyle *style, int y1, int y2, int x,
- const QString &pmKey)
-{
- if (!rect.isValid())
- return;
-
- QPixmap cache;
- QString pixmapName = uniqueName(QLS(part), state, GTK_SHADOW_NONE, rect.size(), gtkWidget)
- % HexString<int>(y1)
- % HexString<int>(y2)
- % HexString<int>(x)
- % pmKey;
-
- if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
- DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_vline (style,
- pixmap,
- state,
- NULL,
- gtkWidget,
- part,
- y1, y2,
- x));
- if (m_usePixmapCache)
- QPixmapCache::insert(pixmapName, cache);
- }
- m_painter->drawPixmap(rect.topLeft(), cache);
-}
-
-
-void QGtkPainter::paintExpander(GtkWidget *gtkWidget,
- const gchar* part, const QRect &rect,
- GtkStateType state, GtkExpanderStyle expander_state,
- GtkStyle *style, const QString &pmKey)
-{
- if (!rect.isValid())
- return;
-
- QPixmap cache;
- QString pixmapName = uniqueName(QLS(part), state, GTK_SHADOW_NONE, rect.size(), gtkWidget)
- % HexString<uchar>(expander_state)
- % pmKey;
-
- if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
- DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_expander (style, pixmap,
- state, NULL,
- gtkWidget, part,
- rect.width()/2,
- rect.height()/2,
- expander_state));
- if (m_usePixmapCache)
- QPixmapCache::insert(pixmapName, cache);
- }
-
- m_painter->drawPixmap(rect.topLeft(), cache);
-}
-
-void QGtkPainter::paintFocus(GtkWidget *gtkWidget, const gchar* part,
- const QRect &rect, GtkStateType state,
- GtkStyle *style, const QString &pmKey)
-{
- if (!rect.isValid())
- return;
-
- QPixmap cache;
- QString pixmapName = uniqueName(QLS(part), state, GTK_SHADOW_NONE, rect.size(), gtkWidget) % pmKey;
- if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
- DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_focus (style, pixmap, state, NULL,
- gtkWidget,
- part,
- 0, 0,
- rect.width(),
- rect.height()));
- if (m_usePixmapCache)
- QPixmapCache::insert(pixmapName, cache);
- }
-
- m_painter->drawPixmap(rect.topLeft(), cache);
-}
-
-
-void QGtkPainter::paintResizeGrip(GtkWidget *gtkWidget, const gchar* part,
- const QRect &rect, GtkStateType state,
- GtkShadowType shadow, GdkWindowEdge edge,
- GtkStyle *style, const QString &pmKey)
-{
- if (!rect.isValid())
- return;
-
- QPixmap cache;
- QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size(), gtkWidget) % pmKey;
- if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
- DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_resize_grip (style, pixmap, state,
- NULL, gtkWidget,
- part, edge, 0, 0,
- rect.width(),
- rect.height()));
- if (m_usePixmapCache)
- QPixmapCache::insert(pixmapName, cache);
- }
-
- m_painter->drawPixmap(rect.topLeft(), cache);
-}
-
-
-void QGtkPainter::paintArrow(GtkWidget *gtkWidget, const gchar* part,
- const QRect &arrowrect, GtkArrowType arrow_type,
- GtkStateType state, GtkShadowType shadow,
- gboolean fill, GtkStyle *style, const QString &pmKey)
-{
- QRect rect = m_cliprect.isValid() ? m_cliprect : arrowrect;
- if (!rect.isValid())
- return;
-
- QPixmap cache;
- QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size())
- % HexString<uchar>(arrow_type)
- % pmKey;
-
- GdkRectangle gtkCliprect = {0, 0, rect.width(), rect.height()};
- int xOffset = m_cliprect.isValid() ? arrowrect.x() - m_cliprect.x() : 0;
- int yOffset = m_cliprect.isValid() ? arrowrect.y() - m_cliprect.y() : 0;
- if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
- DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_arrow (style, pixmap, state, shadow,
- &gtkCliprect,
- gtkWidget,
- part,
- arrow_type, fill,
- xOffset, yOffset,
- arrowrect.width(),
- arrowrect.height()))
- if (m_usePixmapCache)
- QPixmapCache::insert(pixmapName, cache);
- }
-
- m_painter->drawPixmap(rect.topLeft(), cache);
-}
-
-
-void QGtkPainter::paintHandle(GtkWidget *gtkWidget, const gchar* part, const QRect &rect,
- GtkStateType state, GtkShadowType shadow,
- GtkOrientation orientation, GtkStyle *style)
-{
- if (!rect.isValid())
- return;
-
- QPixmap cache;
- QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size())
- % HexString<uchar>(orientation);
-
- if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
- DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_handle (style,
- pixmap,
- state,
- shadow,
- NULL,
- gtkWidget,
- part, 0, 0,
- rect.width(),
- rect.height(),
- orientation));
- if (m_usePixmapCache)
- QPixmapCache::insert(pixmapName, cache);
- }
- m_painter->drawPixmap(rect.topLeft(), cache);
-}
-
-
-void QGtkPainter::paintSlider(GtkWidget *gtkWidget, const gchar* part, const QRect &rect,
- GtkStateType state, GtkShadowType shadow,
- GtkStyle *style, GtkOrientation orientation,
- const QString &pmKey)
-{
- if (!rect.isValid())
- return;
-
- QPixmap cache;
- QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size(), gtkWidget) % pmKey;
- if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
- DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_slider (style,
- pixmap,
- state,
- shadow,
- NULL,
- gtkWidget,
- part,
- 0, 0,
- rect.width(),
- rect.height(),
- orientation));
- if (m_usePixmapCache)
- QPixmapCache::insert(pixmapName, cache);
- }
- m_painter->drawPixmap(rect.topLeft(), cache);
-}
-
-
-void QGtkPainter::paintShadow(GtkWidget *gtkWidget, const gchar* part,
- const QRect &rect, GtkStateType state,
- GtkShadowType shadow, GtkStyle *style,
- const QString &pmKey)
-
-{
- if (!rect.isValid())
- return;
-
- QPixmap cache;
- QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size()) % pmKey;
- if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
- DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_shadow(style, pixmap, state, shadow, NULL,
- gtkWidget, part, 0, 0, rect.width(), rect.height()));
- if (m_usePixmapCache)
- QPixmapCache::insert(pixmapName, cache);
- }
- m_painter->drawPixmap(rect.topLeft(), cache);
-}
-
-void QGtkPainter::paintFlatBox(GtkWidget *gtkWidget, const gchar* part,
- const QRect &rect, GtkStateType state,
- GtkShadowType shadow, GtkStyle *style,
- const QString &pmKey)
-{
- if (!rect.isValid())
- return;
- QPixmap cache;
- QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size()) % pmKey;
- if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
- DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_flat_box (style,
- pixmap,
- state,
- shadow,
- NULL,
- gtkWidget,
- part, 0, 0,
- rect.width(),
- rect.height()));
- if (m_usePixmapCache)
- QPixmapCache::insert(pixmapName, cache);
- }
- m_painter->drawPixmap(rect.topLeft(), cache);
-}
-
-void QGtkPainter::paintExtention(GtkWidget *gtkWidget,
- const gchar *part, const QRect &rect,
- GtkStateType state, GtkShadowType shadow,
- GtkPositionType gap_pos, GtkStyle *style)
-{
- if (!rect.isValid())
- return;
-
- QPixmap cache;
- QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size(), gtkWidget)
- % HexString<uchar>(gap_pos);
-
- if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
- DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_extension (style, pixmap, state, shadow,
- NULL, gtkWidget,
- (gchar*)part, 0, 0,
- rect.width(),
- rect.height(),
- gap_pos));
- if (m_usePixmapCache)
- QPixmapCache::insert(pixmapName, cache);
- }
-
- m_painter->drawPixmap(rect.topLeft(), cache);
-}
-
-void QGtkPainter::paintOption(GtkWidget *gtkWidget, const QRect &radiorect,
- GtkStateType state, GtkShadowType shadow,
- GtkStyle *style, const QString &detail)
-
-{
- QRect rect = m_cliprect.isValid() ? m_cliprect : radiorect;
- if (!rect.isValid())
- return;
-
- QPixmap cache;
- QString pixmapName = uniqueName(detail, state, shadow, rect.size());
- GdkRectangle gtkCliprect = {0, 0, rect.width(), rect.height()};
- int xOffset = m_cliprect.isValid() ? radiorect.x() - m_cliprect.x() : 0;
- int yOffset = m_cliprect.isValid() ? radiorect.y() - m_cliprect.y() : 0;
- if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
- DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_option(style, pixmap,
- state, shadow,
- &gtkCliprect,
- gtkWidget,
- detail.toLatin1(),
- xOffset, yOffset,
- radiorect.width(),
- radiorect.height()));
-
- if (m_usePixmapCache)
- QPixmapCache::insert(pixmapName, cache);
- }
-
- m_painter->drawPixmap(rect.topLeft(), cache);
-}
-
-void QGtkPainter::paintCheckbox(GtkWidget *gtkWidget, const QRect &checkrect,
- GtkStateType state, GtkShadowType shadow,
- GtkStyle *style, const QString &detail)
-
-{
- QRect rect = m_cliprect.isValid() ? m_cliprect : checkrect;
- if (!rect.isValid())
- return;
-
- QPixmap cache;
- QString pixmapName = uniqueName(detail, state, shadow, rect.size());
- GdkRectangle gtkCliprect = {0, 0, rect.width(), rect.height()};
- int xOffset = m_cliprect.isValid() ? checkrect.x() - m_cliprect.x() : 0;
- int yOffset = m_cliprect.isValid() ? checkrect.y() - m_cliprect.y() : 0;
- if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
- DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_check (style,
- pixmap,
- state,
- shadow,
- &gtkCliprect,
- gtkWidget,
- detail.toLatin1(),
- xOffset, yOffset,
- checkrect.width(),
- checkrect.height()));
- if (m_usePixmapCache)
- QPixmapCache::insert(pixmapName, cache);
- }
-
- m_painter->drawPixmap(rect.topLeft(), cache);
-}
-
-QT_END_NAMESPACE
-
-#endif //!defined(QT_NO_STYLE_GTK)
diff --git a/src/gui/styles/qgtkpainter_p.h b/src/gui/styles/qgtkpainter_p.h
deleted file mode 100644
index e2f04c4866..0000000000
--- a/src/gui/styles/qgtkpainter_p.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGTKPAINTER_H
-#define QGTKPAINTER_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/qglobal.h>
-#if !defined(QT_NO_STYLE_GTK)
-
-#include <QtGui/QCleanlooksStyle>
-#include <QtGui/QPainter>
-#include <QtGui/QPalette>
-#include <QtGui/QFont>
-#include <private/qgtkstyle_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QGtkPainter
-{
-
-public:
- QGtkPainter(QPainter *painter);
- GtkStyle *getStyle(GtkWidget *gtkWidget);
- GtkStateType gtkState(const QStyleOption *option);
-
- void setAlphaSupport(bool value) { m_alpha = value; }
- void setClipRect(const QRect &rect) { m_cliprect = rect; }
- void setFlipHorizontal(bool value) { m_hflipped = value; }
- void setFlipVertical(bool value) { m_vflipped = value; }
- void setUsePixmapCache(bool value) { m_usePixmapCache = value; }
-
- void paintBoxGap(GtkWidget *gtkWidget, const gchar* part, const QRect &rect,
- GtkStateType state, GtkShadowType shadow, GtkPositionType gap_side, gint x,
- gint width, GtkStyle *style);
- void paintBox(GtkWidget *gtkWidget, const gchar* part,
- const QRect &rect, GtkStateType state, GtkShadowType shadow, GtkStyle *style,
- const QString &pmKey = QString());
- void paintHline(GtkWidget *gtkWidget, const gchar* part, const QRect &rect, GtkStateType state, GtkStyle *style,
- int x1, int x2, int y, const QString &pmKey = QString());
- void paintVline(GtkWidget *gtkWidget, const gchar* part, const QRect &rect, GtkStateType state, GtkStyle *style,
- int y1, int y2, int x, const QString &pmKey = QString());
- void paintExpander(GtkWidget *gtkWidget, const gchar* part, const QRect &rect, GtkStateType state,
- GtkExpanderStyle expander_state, GtkStyle *style, const QString &pmKey = QString());
- void paintFocus(GtkWidget *gtkWidget, const gchar* part, const QRect &rect, GtkStateType state, GtkStyle *style,
- const QString &pmKey = QString());
- void paintResizeGrip(GtkWidget *gtkWidget, const gchar* part, const QRect &rect, GtkStateType state, GtkShadowType shadow,
- GdkWindowEdge edge, GtkStyle *style, const QString &pmKey = QString());
- void paintArrow(GtkWidget *gtkWidget, const gchar* part, const QRect &arrowrect, GtkArrowType arrow_type, GtkStateType state, GtkShadowType shadow,
- gboolean fill, GtkStyle *style, const QString &pmKey = QString());
- void paintHandle(GtkWidget *gtkWidget, const gchar* part, const QRect &rect,
- GtkStateType state, GtkShadowType shadow, GtkOrientation orientation, GtkStyle *style);
- void paintSlider(GtkWidget *gtkWidget, const gchar* part, const QRect &rect, GtkStateType state, GtkShadowType shadow,
- GtkStyle *style, GtkOrientation orientation, const QString &pmKey = QString());
- void paintShadow(GtkWidget *gtkWidget, const gchar* part, const QRect &rect, GtkStateType state, GtkShadowType shadow,
- GtkStyle *style, const QString &pmKey = QString());
- void paintFlatBox(GtkWidget *gtkWidget, const gchar* part, const QRect &rect, GtkStateType state, GtkShadowType shadow, GtkStyle *style, const QString & = QString());
- void paintExtention(GtkWidget *gtkWidget, const gchar *part, const QRect &rect, GtkStateType state, GtkShadowType shadow,
- GtkPositionType gap_pos, GtkStyle *style);
- void paintOption(GtkWidget *gtkWidget, const QRect &rect, GtkStateType state, GtkShadowType shadow, GtkStyle *style, const QString &detail);
- void paintCheckbox(GtkWidget *gtkWidget, const QRect &rect, GtkStateType state, GtkShadowType shadow, GtkStyle *style, const QString &detail);
-
- static QPixmap getIcon(const char* iconName, GtkIconSize size = GTK_ICON_SIZE_BUTTON);
-private:
- QPixmap renderTheme(uchar *bdata, uchar *wdata, const QRect&);
-
- GtkWidget *m_window;
- QPainter *m_painter;
- bool m_alpha;
- bool m_hflipped;
- bool m_vflipped;
- bool m_usePixmapCache;
- QRect m_cliprect;
-
-};
-
-QT_END_NAMESPACE
-
-#endif //!defined(QT_NO_STYLE_QGTK)
-
-#endif // QGTKPAINTER_H
diff --git a/src/gui/styles/qgtkstyle.cpp b/src/gui/styles/qgtkstyle.cpp
deleted file mode 100644
index 513a546c83..0000000000
--- a/src/gui/styles/qgtkstyle.cpp
+++ /dev/null
@@ -1,3560 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#include "qgtkstyle.h"
-
-#if !defined(QT_NO_STYLE_GTK)
-
-#include <private/qapplication_p.h>
-#include <QtCore/QLibrary>
-#include <QtCore/QSettings>
-#include <QtGui/QDialogButtonBox>
-#include <QtGui/QStatusBar>
-#include <QtGui/QLineEdit>
-#include <QtGui/QWidget>
-#include <QtGui/QListView>
-#include <QtGui/QApplication>
-#include <QtGui/QStyleOption>
-#include <QtGui/QPushButton>
-#include <QtGui/QPainter>
-#include <QtGui/QMainWindow>
-#include <QtGui/QToolBar>
-#include <QtGui/QHeaderView>
-#include <QtGui/QMenuBar>
-#include <QtGui/QComboBox>
-#include <QtGui/QSpinBox>
-#include <QtGui/QScrollBar>
-#include <QtGui/QAbstractButton>
-#include <QtGui/QToolButton>
-#include <QtGui/QGroupBox>
-#include <QtGui/QRadioButton>
-#include <QtGui/QCheckBox>
-#include <QtGui/QTreeView>
-#include <QtGui/QStyledItemDelegate>
-#include <qpixmapcache.h>
-#undef signals // Collides with GTK stymbols
-#include <private/qgtkpainter_p.h>
-#include <private/qstylehelper_p.h>
-#include <private/qgtkstyle_p.h>
-#include <private/qcleanlooksstyle_p.h>
-
-
-QT_BEGIN_NAMESPACE
-
-static const char * const dock_widget_close_xpm[] =
- {
- "11 13 5 1",
- " c None",
- ". c #D5CFCB",
- "+ c #6C6A67",
- "@ c #6C6A67",
- "$ c #B5B0AC",
- " ",
- " @@@@@@@@@ ",
- "@+ +@",
- "@ +@ @+ @",
- "@ @@@ @@@ @",
- "@ @@@@@ @",
- "@ @@@ @",
- "@ @@@@@ @",
- "@ @@@ @@@ @",
- "@ +@ @+ @",
- "@+ +@",
- " @@@@@@@@@ ",
- " "
- };
-
-static const char * const dock_widget_restore_xpm[] =
- {
- "11 13 5 1",
- " c None",
- ". c #D5CFCB",
- "+ c #6C6A67",
- "@ c #6C6A67",
- "# c #6C6A67",
- " ",
- " @@@@@@@@@ ",
- "@+ +@",
- "@ #@@@# @",
- "@ @ @ @",
- "@ #@@@# @ @",
- "@ @ @ @ @",
- "@ @ @@@ @",
- "@ @ @ @",
- "@ #@@@@ @",
- "@+ +@",
- " @@@@@@@@@ ",
- " "
- };
-
-static const int groupBoxBottomMargin = 2; // space below the groupbox
-static const int groupBoxTitleMargin = 6; // space between contents and title
-static const int groupBoxTopMargin = 2;
-
-/*!
- Returns the configuration string for \a value.
- Returns \a fallback if \a value is not found.
- */
-QString QGtkStyle::getGConfString(const QString &value, const QString &fallback)
-{
- return QGtkStylePrivate::getGConfString(value, fallback);
-}
-
-/*!
- Returns the configuration boolean for \a key.
- Returns \a fallback if \a key is not found.
- */
-bool QGtkStyle::getGConfBool(const QString &key, bool fallback)
-{
- return QGtkStylePrivate::getGConfBool(key, fallback);
-}
-
-static QColor mergedColors(const QColor &colorA, const QColor &colorB, int factor = 50)
-{
- const int maxFactor = 100;
- QColor tmp = colorA;
- tmp.setRed((tmp.red() * factor) / maxFactor + (colorB.red() * (maxFactor - factor)) / maxFactor);
- tmp.setGreen((tmp.green() * factor) / maxFactor + (colorB.green() * (maxFactor - factor)) / maxFactor);
- tmp.setBlue((tmp.blue() * factor) / maxFactor + (colorB.blue() * (maxFactor - factor)) / maxFactor);
- return tmp;
-}
-
-static GdkColor fromQColor(const QColor &color)
-{
- GdkColor retval;
- retval.red = color.red() * 255;
- retval.green = color.green() * 255;
- retval.blue = color.blue() * 255;
- return retval;
-}
-
-/*!
- \class QGtkStyle
- \brief The QGtkStyle class provides a widget style rendered by GTK+
- \since 4.5
-
- The QGtkStyle style provides a look and feel that integrates well
- into GTK-based desktop environments such as the XFCe and GNOME.
-
- It does this by making use of the GTK+ theme engine, ensuring
- that Qt applications look and feel native on these platforms.
-
- Note: The style requires GTK+ version 2.10 or later.
- The Qt3-based "Qt" GTK+ theme engine will not work with QGtkStyle.
-
- \sa {Cleanlooks Style Widget Gallery}, QWindowsXPStyle, QMacStyle, QWindowsStyle,
- QCDEStyle, QMotifStyle, QPlastiqueStyle, QCleanlooksStyle
-*/
-
-/*!
- Constructs a QGtkStyle object.
-*/
-QGtkStyle::QGtkStyle()
- : QCleanlooksStyle(*new QGtkStylePrivate)
-{
- Q_D(QGtkStyle);
- d->init();
-}
-
-/*!
- \internal
-
- Constructs a QGtkStyle object.
-*/
-QGtkStyle::QGtkStyle(QGtkStylePrivate &dd)
- : QCleanlooksStyle(dd)
-{
- Q_D(QGtkStyle);
- d->init();
-}
-
-
-/*!
- Destroys the QGtkStyle object.
-*/
-QGtkStyle::~QGtkStyle()
-{
-}
-
-/*!
- \reimp
-*/
-QPalette QGtkStyle::standardPalette() const
-{
- Q_D(const QGtkStyle);
-
- QPalette palette = QCleanlooksStyle::standardPalette();
- if (d->isThemeAvailable()) {
- GtkStyle *style = d->gtkStyle();
- GtkWidget *gtkButton = d->gtkWidget("GtkButton");
- GtkWidget *gtkEntry = d->getTextColorWidget();
- GdkColor gdkBg, gdkBase, gdkText, gdkForeground, gdkSbg, gdkSfg, gdkaSbg, gdkaSfg;
- QColor bg, base, text, fg, highlight, highlightText, inactiveHighlight, inactiveHighlightedTExt;
- gdkBg = style->bg[GTK_STATE_NORMAL];
- gdkForeground = gtkButton->style->fg[GTK_STATE_NORMAL];
-
- // Our base and selected color is primarily used for text
- // so we assume a gtkEntry will have the most correct value
- gdkBase = gtkEntry->style->base[GTK_STATE_NORMAL];
- gdkText = gtkEntry->style->text[GTK_STATE_NORMAL];
- gdkSbg = gtkEntry->style->base[GTK_STATE_SELECTED];
- gdkSfg = gtkEntry->style->text[GTK_STATE_SELECTED];
-
- // The ACTIVE base color is really used for inactive windows
- gdkaSbg = gtkEntry->style->base[GTK_STATE_ACTIVE];
- gdkaSfg = gtkEntry->style->text[GTK_STATE_ACTIVE];
-
- bg = QColor(gdkBg.red>>8, gdkBg.green>>8, gdkBg.blue>>8);
- text = QColor(gdkText.red>>8, gdkText.green>>8, gdkText.blue>>8);
- fg = QColor(gdkForeground.red>>8, gdkForeground.green>>8, gdkForeground.blue>>8);
- base = QColor(gdkBase.red>>8, gdkBase.green>>8, gdkBase.blue>>8);
- highlight = QColor(gdkSbg.red>>8, gdkSbg.green>>8, gdkSbg.blue>>8);
- highlightText = QColor(gdkSfg.red>>8, gdkSfg.green>>8, gdkSfg.blue>>8);
- inactiveHighlight = QColor(gdkaSbg.red>>8, gdkaSbg.green>>8, gdkaSbg.blue>>8);
- inactiveHighlightedTExt = QColor(gdkaSfg.red>>8, gdkaSfg.green>>8, gdkaSfg.blue>>8);
-
- palette.setColor(QPalette::HighlightedText, highlightText);
-
-
- palette.setColor(QPalette::Light, bg.lighter(125));
- palette.setColor(QPalette::Shadow, bg.darker(130));
- palette.setColor(QPalette::Dark, bg.darker(120));
- palette.setColor(QPalette::Text, text);
- palette.setColor(QPalette::WindowText, fg);
- palette.setColor(QPalette::ButtonText, fg);
- palette.setColor(QPalette::Base, base);
-
- QColor alternateRowColor = palette.base().color().lighter(93); // ref gtkstyle.c draw_flat_box
- GtkWidget *gtkTreeView = d->gtkWidget("GtkTreeView");
- GdkColor *gtkAltBase = NULL;
- d->gtk_widget_style_get(gtkTreeView, "odd-row-color", &gtkAltBase, NULL);
- if (gtkAltBase) {
- alternateRowColor = QColor(gtkAltBase->red>>8, gtkAltBase->green>>8, gtkAltBase->blue>>8);
- d->gdk_color_free(gtkAltBase);
- }
- palette.setColor(QPalette::AlternateBase, alternateRowColor);
-
- palette.setColor(QPalette::Window, bg);
- palette.setColor(QPalette::Button, bg);
- palette.setColor(QPalette::Background, bg);
- QColor disabled((fg.red() + bg.red()) / 2,
- (fg.green() + bg.green())/ 2,
- (fg.blue() + bg.blue()) / 2);
- palette.setColor(QPalette::Disabled, QPalette::Text, disabled);
- palette.setColor(QPalette::Disabled, QPalette::WindowText, disabled);
- palette.setColor(QPalette::Disabled, QPalette::Foreground, disabled);
- palette.setColor(QPalette::Disabled, QPalette::ButtonText, disabled);
- palette.setColor(QPalette::Highlight, highlight);
- // calculate disabled colors by removing saturation
- highlight.setHsv(highlight.hue(), 0, highlight.value(), highlight.alpha());
- highlightText.setHsv(highlightText.hue(), 0, highlightText.value(), highlightText.alpha());
- palette.setColor(QPalette::Disabled, QPalette::Highlight, highlight);
- palette.setColor(QPalette::Disabled, QPalette::HighlightedText, highlightText);
-
- palette.setColor(QPalette::Inactive, QPalette::HighlightedText, inactiveHighlightedTExt);
- palette.setColor(QPalette::Inactive, QPalette::Highlight, inactiveHighlight);
-
- style = d->gtk_rc_get_style_by_paths(d->gtk_settings_get_default(), "gtk-tooltips", "GtkWindow",
- d->gtk_window_get_type());
- if (style) {
- gdkText = style->fg[GTK_STATE_NORMAL];
- text = QColor(gdkText.red>>8, gdkText.green>>8, gdkText.blue>>8);
- palette.setColor(QPalette::ToolTipText, text);
- }
- }
- return palette;
-}
-
-/*!
- \reimp
-*/
-void QGtkStyle::polish(QPalette &palette)
-{
- Q_D(QGtkStyle);
-
- // QCleanlooksStyle will alter the palette, hence we do
- // not want to polish the palette unless we are using it as
- // the fallback
- if (!d->isThemeAvailable())
- QCleanlooksStyle::polish(palette);
- else
- palette = palette.resolve(standardPalette());
-}
-
-/*!
- \reimp
-*/
-void QGtkStyle::polish(QApplication *app)
-{
- Q_D(QGtkStyle);
-
- QCleanlooksStyle::polish(app);
- // Custom fonts and palettes with QtConfig are intentionally
- // not supported as these should be entirely determined by
- // current Gtk settings
- if (app->desktopSettingsAware() && d->isThemeAvailable()) {
- QApplicationPrivate::setSystemPalette(standardPalette());
- QApplicationPrivate::setSystemFont(d->getThemeFont());
- d->applyCustomPaletteHash();
- if (!d->isKDE4Session()) {
- qt_filedialog_open_filename_hook = &QGtkStylePrivate::openFilename;
- qt_filedialog_save_filename_hook = &QGtkStylePrivate::saveFilename;
- qt_filedialog_open_filenames_hook = &QGtkStylePrivate::openFilenames;
- qt_filedialog_existing_directory_hook = &QGtkStylePrivate::openDirectory;
- qApp->installEventFilter(&d->filter);
- }
- }
-}
-
-/*!
- \reimp
-*/
-void QGtkStyle::unpolish(QApplication *app)
-{
- Q_D(QGtkStyle);
-
- QCleanlooksStyle::unpolish(app);
- QPixmapCache::clear();
-
- if (app->desktopSettingsAware() && d->isThemeAvailable()
- && !d->isKDE4Session()) {
- qt_filedialog_open_filename_hook = 0;
- qt_filedialog_save_filename_hook = 0;
- qt_filedialog_open_filenames_hook = 0;
- qt_filedialog_existing_directory_hook = 0;
- qApp->removeEventFilter(&d->filter);
- }
-}
-
-/*!
- \reimp
-*/
-
-void QGtkStyle::polish(QWidget *widget)
-{
- Q_D(QGtkStyle);
-
- QCleanlooksStyle::polish(widget);
- if (!d->isThemeAvailable())
- return;
- if (qobject_cast<QAbstractButton*>(widget)
- || qobject_cast<QToolButton*>(widget)
- || qobject_cast<QComboBox*>(widget)
- || qobject_cast<QGroupBox*>(widget)
- || qobject_cast<QScrollBar*>(widget)
- || qobject_cast<QSlider*>(widget)
- || qobject_cast<QAbstractSpinBox*>(widget)
- || qobject_cast<QSpinBox*>(widget)
- || qobject_cast<QHeaderView*>(widget))
- widget->setAttribute(Qt::WA_Hover);
- else if (QTreeView *tree = qobject_cast<QTreeView *> (widget))
- tree->viewport()->setAttribute(Qt::WA_Hover);
-}
-
-/*!
- \reimp
-*/
-void QGtkStyle::unpolish(QWidget *widget)
-{
- QCleanlooksStyle::unpolish(widget);
-}
-
-/*!
- \reimp
-*/
-int QGtkStyle::pixelMetric(PixelMetric metric,
- const QStyleOption *option,
- const QWidget *widget) const
-{
- Q_D(const QGtkStyle);
-
- if (!d->isThemeAvailable())
- return QCleanlooksStyle::pixelMetric(metric, option, widget);
-
- switch (metric) {
- case PM_DefaultFrameWidth:
- if (qobject_cast<const QFrame*>(widget)) {
- if (GtkStyle *style =
- d->gtk_rc_get_style_by_paths(d->gtk_settings_get_default(),
- "*.GtkScrolledWindow",
- "*.GtkScrolledWindow",
- d->gtk_window_get_type()))
- return qMax(style->xthickness, style->ythickness);
- }
- return 2;
-
- case PM_MenuButtonIndicator:
- return 20;
-
- case PM_TabBarBaseOverlap:
- return 1;
-
- case PM_ToolBarSeparatorExtent:
- return 11;
-
- case PM_ToolBarFrameWidth:
- return 1;
-
- case PM_ToolBarItemSpacing:
- return 0;
-
- case PM_ButtonShiftHorizontal: {
- GtkWidget *gtkButton = d->gtkWidget("GtkButton");
- guint horizontal_shift;
- d->gtk_widget_style_get(gtkButton, "child-displacement-x", &horizontal_shift, NULL);
- return horizontal_shift;
- }
-
- case PM_ButtonShiftVertical: {
- GtkWidget *gtkButton = d->gtkWidget("GtkButton");
- guint vertical_shift;
- d->gtk_widget_style_get(gtkButton, "child-displacement-y", &vertical_shift, NULL);
- return vertical_shift;
- }
-
- case PM_MenuBarPanelWidth:
- return 0;
-
- case PM_MenuPanelWidth: {
- GtkWidget *gtkMenu = d->gtkWidget("GtkMenu");
- guint horizontal_padding = 0;
- // horizontal-padding is used by Maemo to get thicker borders
- if (!d->gtk_check_version(2, 10, 0))
- d->gtk_widget_style_get(gtkMenu, "horizontal-padding", &horizontal_padding, NULL);
- int padding = qMax<int>(gtkMenu->style->xthickness, horizontal_padding);
- return padding;
- }
-
- case PM_ButtonIconSize: {
- int retVal = 24;
- GtkSettings *settings = d->gtk_settings_get_default();
- gchararray icon_sizes;
- g_object_get(settings, "gtk-icon-sizes", &icon_sizes, NULL);
- QStringList values = QString(QLS(icon_sizes)).split(QLatin1Char(':'));
- g_free(icon_sizes);
- QChar splitChar(QLatin1Char(','));
- foreach (const QString &value, values) {
- if (value.startsWith(QLS("gtk-button="))) {
- QString iconSize = value.right(value.size() - 11);
-
- if (iconSize.contains(splitChar))
- retVal = iconSize.split(splitChar)[0].toInt();
- break;
- }
- }
- return retVal;
- }
-
- case PM_MenuVMargin:
-
- case PM_MenuHMargin:
- return 0;
-
- case PM_DockWidgetTitleMargin:
- return 0;
-
- case PM_DockWidgetTitleBarButtonMargin:
- return 5;
-
- case PM_TabBarTabVSpace:
- return 12;
-
- case PM_TabBarTabHSpace:
- return 14;
-
- case PM_TabBarTabShiftVertical:
- return 2;
-
- case PM_ToolBarHandleExtent:
- return 9;
-
- case PM_SplitterWidth:
- return 6;
-
- case PM_SliderThickness:
- case PM_SliderControlThickness: {
- GtkWidget *gtkScale = d->gtkWidget("GtkHScale");
- gint val;
- d->gtk_widget_style_get(gtkScale, "slider-width", &val, NULL);
- if (metric == PM_SliderControlThickness)
- return val + 2*gtkScale->style->ythickness;
- return val;
- }
-
- case PM_ScrollBarExtent: {
- gint sliderLength;
- gint trough_border;
- GtkWidget *hScrollbar = d->gtkWidget("GtkHScrollbar");
- d->gtk_widget_style_get(hScrollbar,
- "trough-border", &trough_border,
- "slider-width", &sliderLength,
- NULL);
- return sliderLength + trough_border*2;
- }
-
- case PM_ScrollBarSliderMin:
- return 34;
-
- case PM_SliderLength:
- gint val;
- d->gtk_widget_style_get(d->gtkWidget("GtkHScale"), "slider-length", &val, NULL);
- return val;
-
- case PM_ExclusiveIndicatorWidth:
- case PM_ExclusiveIndicatorHeight:
- case PM_IndicatorWidth:
- case PM_IndicatorHeight: {
- GtkWidget *gtkCheckButton = d->gtkWidget("GtkCheckButton");
- gint size, spacing;
- d->gtk_widget_style_get(gtkCheckButton, "indicator-spacing", &spacing, "indicator-size", &size, NULL);
- return size + 2 * spacing;
- }
-
- case PM_MenuBarVMargin: {
- GtkWidget *gtkMenubar = d->gtkWidget("GtkMenuBar");
- return qMax(0, gtkMenubar->style->ythickness);
- }
- case PM_ScrollView_ScrollBarSpacing:
- {
- gint spacing = 3;
- GtkWidget *gtkScrollWindow = d->gtkWidget("GtkScrolledWindow");
- Q_ASSERT(gtkScrollWindow);
- d->gtk_widget_style_get(gtkScrollWindow, "scrollbar-spacing", &spacing, NULL);
- return spacing;
- }
- case PM_SubMenuOverlap: {
- gint offset = 0;
- GtkWidget *gtkMenu = d->gtkWidget("GtkMenu");
- d->gtk_widget_style_get(gtkMenu, "horizontal-offset", &offset, NULL);
- return offset;
- }
- default:
- return QCleanlooksStyle::pixelMetric(metric, option, widget);
- }
-}
-
-/*!
- \reimp
-*/
-int QGtkStyle::styleHint(StyleHint hint, const QStyleOption *option, const QWidget *widget,
-
- QStyleHintReturn *returnData = 0) const
-{
- Q_D(const QGtkStyle);
-
- if (!d->isThemeAvailable())
- return QCleanlooksStyle::styleHint(hint, option, widget, returnData);
-
- switch (hint) {
-
- case SH_DialogButtonLayout: {
- int ret = QDialogButtonBox::GnomeLayout;
- gboolean alternateOrder = 0;
- GtkSettings *settings = d->gtk_settings_get_default();
- g_object_get(settings, "gtk-alternative-button-order", &alternateOrder, NULL);
-
- if (alternateOrder)
- ret = QDialogButtonBox::WinLayout;
-
- return ret;
- }
-
- break;
-
- case SH_ToolButtonStyle:
- {
- if (d->isKDE4Session())
- return QCleanlooksStyle::styleHint(hint, option, widget, returnData);
- GtkWidget *gtkToolbar = d->gtkWidget("GtkToolbar");
- GtkToolbarStyle toolbar_style = GTK_TOOLBAR_ICONS;
- g_object_get(gtkToolbar, "toolbar-style", &toolbar_style, NULL);
- switch (toolbar_style) {
- case GTK_TOOLBAR_TEXT:
- return Qt::ToolButtonTextOnly;
- case GTK_TOOLBAR_BOTH:
- return Qt::ToolButtonTextUnderIcon;
- case GTK_TOOLBAR_BOTH_HORIZ:
- return Qt::ToolButtonTextBesideIcon;
- case GTK_TOOLBAR_ICONS:
- default:
- return Qt::ToolButtonIconOnly;
- }
- }
- break;
- case SH_SpinControls_DisableOnBounds:
- return int(true);
-
- case SH_DitherDisabledText:
- return int(false);
-
- case SH_ComboBox_Popup: {
- GtkWidget *gtkComboBox = d->gtkWidget("GtkComboBox");
- gboolean appears_as_list;
- d->gtk_widget_style_get((GtkWidget*)gtkComboBox, "appears-as-list", &appears_as_list, NULL);
- return appears_as_list ? 0 : 1;
- }
-
- case SH_MenuBar_AltKeyNavigation:
- return int(false);
-
- case SH_EtchDisabledText:
- return int(false);
-
- case SH_Menu_SubMenuPopupDelay: {
- gint delay = 225;
- GtkSettings *settings = d->gtk_settings_get_default();
- g_object_get(settings, "gtk-menu-popup-delay", &delay, NULL);
- return delay;
- }
-
- case SH_ScrollView_FrameOnlyAroundContents: {
- gboolean scrollbars_within_bevel = false;
- if (widget && widget->isWindow())
- scrollbars_within_bevel = true;
- else if (!d->gtk_check_version(2, 12, 0)) {
- GtkWidget *gtkScrollWindow = d->gtkWidget("GtkScrolledWindow");
- d->gtk_widget_style_get(gtkScrollWindow, "scrollbars-within-bevel", &scrollbars_within_bevel, NULL);
- }
- return !scrollbars_within_bevel;
- }
-
- case SH_DialogButtonBox_ButtonsHaveIcons: {
- static bool buttonsHaveIcons = d->getGConfBool(QLS("/desktop/gnome/interface/buttons_have_icons"));
- return buttonsHaveIcons;
- }
-
- case SH_UnderlineShortcut: {
- gboolean underlineShortcut = true;
- if (!d->gtk_check_version(2, 12, 0)) {
- GtkSettings *settings = d->gtk_settings_get_default();
- g_object_get(settings, "gtk-enable-mnemonics", &underlineShortcut, NULL);
- }
- return underlineShortcut;
- }
-
- default:
- return QCleanlooksStyle::styleHint(hint, option, widget, returnData);
- }
-}
-
-/*!
- \reimp
-*/
-void QGtkStyle::drawPrimitive(PrimitiveElement element,
- const QStyleOption *option,
- QPainter *painter,
- const QWidget *widget) const
-{
- Q_D(const QGtkStyle);
-
- if (!d->isThemeAvailable()) {
- QCleanlooksStyle::drawPrimitive(element, option, painter, widget);
- return;
- }
-
- GtkStyle* style = d->gtkStyle();
- QGtkPainter gtkPainter(painter);
-
- switch (element) {
- case PE_Frame: {
- if (widget && widget->inherits("QComboBoxPrivateContainer")){
- QStyleOption copy = *option;
- copy.state |= State_Raised;
- proxy()->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 = proxy()->pixelMetric(PM_DefaultFrameWidth, option, widget);
- const QString pmKey = QLatin1Literal("windowframe") % HexString<uint>(option->state);
-
- QPixmap pixmap;
- QRect pmRect(QPoint(0,0), QSize(pmSize, pmSize));
-
- // Only draw through style once
- if (!QPixmapCache::find(pmKey, pixmap)) {
- 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 = d->gtk_rc_get_style_by_paths(d->gtk_settings_get_default(),
- "*.GtkScrolledWindow", "*.GtkScrolledWindow", d->gtk_window_get_type());
- if (style)
- gtkFramePainter.paintShadow(d->gtkWidget("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 = d->gtkWidget("GtkWindow"); // The Murrine Engine currently assumes a widget is passed
- style = d->gtk_rc_get_style_by_paths(d->gtk_settings_get_default(), "gtk-tooltips", "GtkWindow",
- d->gtk_window_get_type());
- gtkPainter.paintFlatBox(gtkWindow, "tooltip", option->rect, GTK_STATE_NORMAL, GTK_SHADOW_NONE, style);
- }
- break;
-
- case PE_PanelStatusBar: {
- if (widget && widget->testAttribute(Qt::WA_SetPalette) &&
- option->palette.resolve() & (1 << QPalette::Window)) {
- // Respect custom palette
- painter->fillRect(option->rect, option->palette.window());
- break;
- }
- GtkShadowType shadow_type;
- GtkWidget *gtkStatusbarFrame = d->gtkWidget("GtkStatusbar.GtkFrame");
- d->gtk_widget_style_get(gtkStatusbarFrame->parent, "shadow-type", &shadow_type, NULL);
- gtkPainter.paintShadow(gtkStatusbarFrame, "frame", option->rect, GTK_STATE_NORMAL,
- shadow_type, gtkStatusbarFrame->style);
- }
- break;
-
- case PE_IndicatorHeaderArrow:
- if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
- GtkWidget *gtkTreeHeader = d->gtkWidget("GtkTreeView.GtkButton");
- GtkStateType state = gtkPainter.gtkState(option);
- style = gtkTreeHeader->style;
- GtkArrowType type = GTK_ARROW_UP;
- QImage arrow;
- // This sorting indicator inversion is intentional, and follows the GNOME HIG.
- // See http://library.gnome.org/devel/hig-book/stable/controls-lists.html.en#controls-lists-sortable
- if (header->sortIndicator & QStyleOptionHeader::SortUp)
- type = GTK_ARROW_UP;
- else if (header->sortIndicator & QStyleOptionHeader::SortDown)
- type = GTK_ARROW_DOWN;
-
- gtkPainter.paintArrow(gtkTreeHeader, "button", option->rect.adjusted(1, 1, -1, -1), type, state,
- GTK_SHADOW_NONE, FALSE, style);
- }
- break;
-
- case PE_FrameFocusRect:
- if (!widget || qobject_cast<const QAbstractItemView*>(widget))
- QCleanlooksStyle::drawPrimitive(element, option, painter, widget);
- else {
- // ### this mess should move to subcontrolrect
- QRect frameRect = option->rect.adjusted(1, 1, -1, -2);
-
- if (qobject_cast<const QTabBar*>(widget)) {
- GtkWidget *gtkNotebook = d->gtkWidget("GtkNotebook");
- style = gtkPainter.getStyle(gtkNotebook);
- gtkPainter.paintFocus(gtkNotebook, "tab", frameRect.adjusted(-1, 1, 1, 1), GTK_STATE_ACTIVE, style);
- } else {
- gtkPainter.paintFocus(NULL, "tab", frameRect, GTK_STATE_ACTIVE, style);
- }
- }
- break;
-
- case PE_IndicatorBranch:
- if (option->state & State_Children) {
- QRect rect = option->rect;
- rect = QRect(0, 0, 12, 12);
- rect.moveCenter(option->rect.center());
- rect.translate(2, 0);
- GtkExpanderStyle openState = GTK_EXPANDER_EXPANDED;
- GtkExpanderStyle closedState = GTK_EXPANDER_COLLAPSED;
- GtkWidget *gtkTreeView = d->gtkWidget("GtkTreeView");
-
- GtkStateType state = GTK_STATE_NORMAL;
- if (!(option->state & State_Enabled))
- state = GTK_STATE_INSENSITIVE;
- else if (option->state & State_MouseOver)
- state = GTK_STATE_PRELIGHT;
-
- gtkPainter.paintExpander(gtkTreeView, "treeview", rect, state,
- option->state & State_Open ? openState : closedState , gtkTreeView->style);
- }
- break;
-
- case PE_PanelItemViewRow:
- // This primitive is only used to draw selection behind selected expander arrows.
- // We try not to decorate the tree branch background unless you inherit from StyledItemDelegate
- // The reason for this is that a lot of code that relies on custom item delegates will look odd having
- // a gradient on the branch but a flat shaded color on the item itself.
- QCommonStyle::drawPrimitive(element, option, painter, widget);
- if (!option->state & State_Selected) {
- break;
- } else {
- if (const QAbstractItemView *view = qobject_cast<const QAbstractItemView*>(widget)) {
- if (!qobject_cast<QStyledItemDelegate*>(view->itemDelegate()))
- break;
- }
- } // fall through
-
- case PE_PanelItemViewItem:
- if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(option)) {
- uint resolve_mask = vopt->palette.resolve();
- if (vopt->backgroundBrush.style() != Qt::NoBrush
- || (resolve_mask & (1 << QPalette::Base)))
- {
- QPointF oldBO = painter->brushOrigin();
- painter->setBrushOrigin(vopt->rect.topLeft());
- painter->fillRect(vopt->rect, vopt->backgroundBrush);
- painter->setBrushOrigin(oldBO);
- if (!(option->state & State_Selected))
- break;
- }
- if (GtkWidget *gtkTreeView = d->gtkWidget("GtkTreeView")) {
- const char *detail = "cell_even_ruled";
- if (vopt && vopt->features & QStyleOptionViewItemV2::Alternate)
- detail = "cell_odd_ruled";
- bool isActive = option->state & State_Active;
- QString key;
- if (isActive ) {
- // Required for active/non-active window appearance
- key = QLS("a");
- GTK_WIDGET_SET_FLAGS(gtkTreeView, GTK_HAS_FOCUS);
- }
- bool isEnabled = (widget ? widget->isEnabled() : (vopt->state & QStyle::State_Enabled));
- gtkPainter.paintFlatBox(gtkTreeView, detail, option->rect,
- option->state & State_Selected ? GTK_STATE_SELECTED :
- isEnabled ? GTK_STATE_NORMAL : GTK_STATE_INSENSITIVE,
- GTK_SHADOW_OUT, gtkTreeView->style, key);
- if (isActive )
- GTK_WIDGET_UNSET_FLAGS(gtkTreeView, GTK_HAS_FOCUS);
- }
- }
- break;
- case PE_IndicatorToolBarSeparator:
- {
- const int margin = 6;
- GtkWidget *gtkSeparator = d->gtkWidget("GtkToolbar.GtkSeparatorToolItem");
- if (option->state & State_Horizontal) {
- const int offset = option->rect.width()/2;
- QRect rect = option->rect.adjusted(offset, margin, 0, -margin);
- painter->setPen(QPen(option->palette.background().color().darker(110)));
- gtkPainter.paintVline( gtkSeparator, "vseparator",
- rect, GTK_STATE_NORMAL, gtkSeparator->style,
- 0, rect.height(), 0);
- } else { //Draw vertical separator
- const int offset = option->rect.height()/2;
- QRect rect = option->rect.adjusted(margin, offset, -margin, 0);
- painter->setPen(QPen(option->palette.background().color().darker(110)));
- gtkPainter.paintHline( gtkSeparator, "hseparator",
- rect, GTK_STATE_NORMAL, gtkSeparator->style,
- 0, rect.width(), 0);
- }
- }
- break;
-
- case PE_IndicatorToolBarHandle: {
- GtkWidget *gtkToolbar = d->gtkWidget("GtkToolbar");
- GtkShadowType shadow_type;
- d->gtk_widget_style_get(gtkToolbar, "shadow-type", &shadow_type, NULL);
- //Note when the toolbar is horizontal, the handle is vertical
- painter->setClipRect(option->rect);
- gtkPainter.paintHandle(gtkToolbar, "toolbar", option->rect.adjusted(-1, -1 ,0 ,1),
- GTK_STATE_NORMAL, shadow_type, !(option->state & State_Horizontal) ?
- GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL, gtkToolbar->style);
- }
- break;
-
- case PE_IndicatorArrowUp:
- case PE_IndicatorArrowDown:
- case PE_IndicatorArrowLeft:
- case PE_IndicatorArrowRight: {
-
-
- GtkArrowType type = GTK_ARROW_UP;
-
- switch (element) {
-
- case PE_IndicatorArrowDown:
- type = GTK_ARROW_DOWN;
- break;
-
- case PE_IndicatorArrowLeft:
- type = GTK_ARROW_LEFT;
- break;
-
- case PE_IndicatorArrowRight:
- type = GTK_ARROW_RIGHT;
- break;
-
- default:
- break;
- }
- int size = qMin(option->rect.height(), option->rect.width());
- int border = (size > 9) ? (size/4) : 0; //Allow small arrows to have exact dimensions
- int bsx = 0, bsy = 0;
- if (option->state & State_Sunken) {
- bsx = proxy()->pixelMetric(PM_ButtonShiftHorizontal);
- bsy = proxy()->pixelMetric(PM_ButtonShiftVertical);
- }
- QRect arrowRect = option->rect.adjusted(border + bsx, border + bsy, -border + bsx, -border + bsy);
- GtkShadowType shadow = option->state & State_Sunken ? GTK_SHADOW_IN : GTK_SHADOW_OUT;
- GtkStateType state = gtkPainter.gtkState(option);
-
- QColor arrowColor = option->palette.buttonText().color();
- GtkWidget *gtkArrow = d->gtkWidget("GtkArrow");
- GdkColor color = fromQColor(arrowColor);
- d->gtk_widget_modify_fg (gtkArrow, state, &color);
- gtkPainter.paintArrow(gtkArrow, "button", arrowRect,
- type, state, shadow, FALSE, gtkArrow->style,
- QString::number(arrowColor.rgba(), 16));
- // Passing NULL will revert the color change
- d->gtk_widget_modify_fg (gtkArrow, state, NULL);
- }
- break;
-
- case PE_FrameGroupBox:
- // Do nothing here, the GNOME groupboxes are flat
- break;
-
- case PE_PanelMenu: {
- GtkWidget *gtkMenu = d->gtkWidget("GtkMenu");
- gtkPainter.setAlphaSupport(false); // Note, alpha disabled for performance reasons
- gtkPainter.paintBox(gtkMenu, "menu", option->rect, GTK_STATE_NORMAL, GTK_SHADOW_OUT, gtkMenu->style, QString());
- }
- break;
-
- case PE_FrameMenu:
- //This is actually done by PE_Widget due to a clipping issue
- //Otherwise Menu items will not be able to span the entire menu width
-
- // This is only used by floating tool bars
- if (qobject_cast<const QToolBar *>(widget)) {
- GtkWidget *gtkMenubar = d->gtkWidget("GtkMenuBar");
- gtkPainter.paintBox( gtkMenubar, "toolbar", option->rect,
- GTK_STATE_NORMAL, GTK_SHADOW_OUT, style);
- gtkPainter.paintBox( gtkMenubar, "menu", option->rect,
- GTK_STATE_NORMAL, GTK_SHADOW_OUT, style);
- }
- break;
-
- case PE_FrameLineEdit: {
- GtkWidget *gtkEntry = d->gtkWidget("GtkEntry");
-
-
- gboolean interior_focus;
- gint focus_line_width;
- QRect rect = option->rect;
- d->gtk_widget_style_get(gtkEntry,
- "interior-focus", &interior_focus,
- "focus-line-width", &focus_line_width, NULL);
-
- // See https://bugzilla.mozilla.org/show_bug.cgi?id=405421 for info about this hack
- g_object_set_data(G_OBJECT(gtkEntry), "transparent-bg-hint", GINT_TO_POINTER(TRUE));
-
- if (!interior_focus && option->state & State_HasFocus)
- rect.adjust(focus_line_width, focus_line_width, -focus_line_width, -focus_line_width);
-
- if (option->state & State_HasFocus)
- GTK_WIDGET_SET_FLAGS(gtkEntry, GTK_HAS_FOCUS);
- gtkPainter.paintShadow(gtkEntry, "entry", rect, option->state & State_Enabled ?
- GTK_STATE_NORMAL : GTK_STATE_INSENSITIVE,
- GTK_SHADOW_IN, gtkEntry->style,
- option->state & State_HasFocus ? QLS("focus") : QString());
- if (!interior_focus && option->state & State_HasFocus)
- gtkPainter.paintShadow(gtkEntry, "entry", option->rect, option->state & State_Enabled ?
- GTK_STATE_ACTIVE : GTK_STATE_INSENSITIVE,
- GTK_SHADOW_IN, gtkEntry->style, QLS("GtkEntryShadowIn"));
-
- if (option->state & State_HasFocus)
- GTK_WIDGET_UNSET_FLAGS(gtkEntry, GTK_HAS_FOCUS);
- }
- break;
-
- case PE_PanelLineEdit:
- if (const QStyleOptionFrame *panel = qstyleoption_cast<const QStyleOptionFrame *>(option)) {
- GtkWidget *gtkEntry = d->gtkWidget("GtkEntry");
- if (panel->lineWidth > 0)
- proxy()->drawPrimitive(PE_FrameLineEdit, option, painter, widget);
- uint resolve_mask = option->palette.resolve();
- QRect textRect = option->rect.adjusted(gtkEntry->style->xthickness, gtkEntry->style->ythickness,
- -gtkEntry->style->xthickness, -gtkEntry->style->ythickness);
-
- if (widget && widget->testAttribute(Qt::WA_SetPalette) &&
- resolve_mask & (1 << QPalette::Base)) // Palette overridden by user
- 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);
- }
- break;
-
- case PE_FrameTabWidget:
- if (const QStyleOptionTabWidgetFrame *frame = qstyleoption_cast<const QStyleOptionTabWidgetFrame*>(option)) {
- GtkWidget *gtkNotebook = d->gtkWidget("GtkNotebook");
- style = gtkPainter.getStyle(gtkNotebook);
- gtkPainter.setAlphaSupport(false);
- GtkShadowType shadow = GTK_SHADOW_OUT;
- GtkStateType state = GTK_STATE_NORMAL; // Only state supported by gtknotebook
- bool reverse = (option->direction == Qt::RightToLeft);
- QGtkStylePrivate::gtk_widget_set_direction(gtkNotebook, reverse ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR);
- if (const QStyleOptionTabWidgetFrameV2 *tabframe = qstyleoption_cast<const QStyleOptionTabWidgetFrameV2*>(option)) {
- GtkPositionType frameType = GTK_POS_TOP;
- QTabBar::Shape shape = frame->shape;
- int gapStart = 0;
- int gapSize = 0;
- if (shape == QTabBar::RoundedNorth || shape == QTabBar::RoundedSouth) {
- frameType = (shape == QTabBar::RoundedNorth) ? GTK_POS_TOP : GTK_POS_BOTTOM;
- gapStart = tabframe->selectedTabRect.left();
- gapSize = tabframe->selectedTabRect.width();
- } else {
- frameType = (shape == QTabBar::RoundedWest) ? GTK_POS_LEFT : GTK_POS_RIGHT;
- gapStart = tabframe->selectedTabRect.y();
- gapSize = tabframe->selectedTabRect.height();
- }
- gtkPainter.paintBoxGap(gtkNotebook, "notebook", option->rect, state, shadow, frameType,
- gapStart, gapSize, style);
- break; // done
- }
-
- // Note this is only the fallback option
- gtkPainter.paintBox(gtkNotebook, "notebook", option->rect, state, shadow, style);
- }
- break;
-
- case PE_PanelButtonCommand:
- case PE_PanelButtonTool: {
- bool isDefault = false;
- bool isTool = (element == PE_PanelButtonTool);
- if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton*>(option))
- isDefault = btn->features & QStyleOptionButton::DefaultButton;
-
- // don't draw a frame for tool buttons that have the autoRaise flag and are not enabled or on
- if (isTool && !(option->state & State_Enabled || option->state & State_On) && (option->state & State_AutoRaise))
- break;
- // don't draw a frame for dock widget buttons, unless we are hovering
- if (widget && widget->inherits("QDockWidgetTitleButton") && !(option->state & State_MouseOver))
- break;
-
- GtkStateType state = gtkPainter.gtkState(option);
- if (option->state & State_On || option->state & State_Sunken)
- state = GTK_STATE_ACTIVE;
- GtkWidget *gtkButton = isTool ? d->gtkWidget("GtkToolButton.GtkButton") : d->gtkWidget("GtkButton");
- gint focusWidth, focusPad;
- gboolean interiorFocus = false;
- d->gtk_widget_style_get (gtkButton,
- "focus-line-width", &focusWidth,
- "focus-padding", &focusPad,
- "interior-focus", &interiorFocus, NULL);
-
- style = gtkButton->style;
-
- QRect buttonRect = option->rect;
-
- QString key;
- if (isDefault) {
- key += QLS("def");
- GTK_WIDGET_SET_FLAGS(gtkButton, GTK_HAS_DEFAULT);
- gtkPainter.paintBox(gtkButton, "buttondefault", buttonRect, state, GTK_SHADOW_IN,
- style, isDefault ? QLS("d") : QString());
- }
-
- bool hasFocus = option->state & State_HasFocus;
-
- if (hasFocus) {
- key += QLS("def");
- GTK_WIDGET_SET_FLAGS(gtkButton, GTK_HAS_FOCUS);
- }
-
- if (!interiorFocus)
- buttonRect = buttonRect.adjusted(focusWidth, focusWidth, -focusWidth, -focusWidth);
-
- GtkShadowType shadow = (option->state & State_Sunken || option->state & State_On ) ?
- GTK_SHADOW_IN : GTK_SHADOW_OUT;
-
- gtkPainter.paintBox(gtkButton, "button", buttonRect, state, shadow,
- style, key);
- if (isDefault)
- GTK_WIDGET_UNSET_FLAGS(gtkButton, GTK_HAS_DEFAULT);
- if (hasFocus)
- GTK_WIDGET_UNSET_FLAGS(gtkButton, GTK_HAS_FOCUS);
- }
- break;
-
- case PE_IndicatorRadioButton: {
- GtkShadowType shadow = GTK_SHADOW_OUT;
- GtkStateType state = gtkPainter.gtkState(option);
-
- if (option->state & State_Sunken)
- state = GTK_STATE_ACTIVE;
-
- if (option->state & State_NoChange)
- shadow = GTK_SHADOW_ETCHED_IN;
- else if (option->state & State_On)
- shadow = GTK_SHADOW_IN;
- else
- shadow = GTK_SHADOW_OUT;
-
- GtkWidget *gtkRadioButton = d->gtkWidget("GtkRadioButton");
- gint spacing;
- d->gtk_widget_style_get(gtkRadioButton, "indicator-spacing", &spacing, NULL);
- QRect buttonRect = option->rect.adjusted(spacing, spacing, -spacing, -spacing);
- gtkPainter.setClipRect(option->rect);
- // ### Note: Ubuntulooks breaks when the proper widget is passed
- // Murrine engine requires a widget not to get RGBA check - warnings
- GtkWidget *gtkCheckButton = d->gtkWidget("GtkCheckButton");
- QString key(QLS("radiobutton"));
- if (option->state & State_HasFocus) { // Themes such as Nodoka check this flag
- key += QLatin1Char('f');
- GTK_WIDGET_SET_FLAGS(gtkCheckButton, GTK_HAS_FOCUS);
- }
- gtkPainter.paintOption(gtkCheckButton , buttonRect, state, shadow, gtkRadioButton->style, key);
- if (option->state & State_HasFocus)
- GTK_WIDGET_UNSET_FLAGS(gtkCheckButton, GTK_HAS_FOCUS);
- }
- break;
-
- case PE_IndicatorCheckBox: {
- GtkShadowType shadow = GTK_SHADOW_OUT;
- GtkStateType state = gtkPainter.gtkState(option);
-
- if (option->state & State_Sunken)
- state = GTK_STATE_ACTIVE;
-
- if (option->state & State_NoChange)
- shadow = GTK_SHADOW_ETCHED_IN;
- else if (option->state & State_On)
- shadow = GTK_SHADOW_IN;
- else
- shadow = GTK_SHADOW_OUT;
-
- int spacing;
-
- GtkWidget *gtkCheckButton = d->gtkWidget("GtkCheckButton");
- QString key(QLS("checkbutton"));
- if (option->state & State_HasFocus) { // Themes such as Nodoka checks this flag
- key += QLatin1Char('f');
- GTK_WIDGET_SET_FLAGS(gtkCheckButton, GTK_HAS_FOCUS);
- }
-
- // Some styles such as aero-clone assume they can paint in the spacing area
- gtkPainter.setClipRect(option->rect);
-
- d->gtk_widget_style_get(gtkCheckButton, "indicator-spacing", &spacing, NULL);
-
- QRect checkRect = option->rect.adjusted(spacing, spacing, -spacing, -spacing);
-
- gtkPainter.paintCheckbox(gtkCheckButton, checkRect, state, shadow, gtkCheckButton->style,
- key);
- if (option->state & State_HasFocus)
- GTK_WIDGET_UNSET_FLAGS(gtkCheckButton, GTK_HAS_FOCUS);
-
- }
- break;
-
-#ifndef QT_NO_TABBAR
-
- case PE_FrameTabBarBase:
- if (const QStyleOptionTabBarBase *tbb
- = qstyleoption_cast<const QStyleOptionTabBarBase *>(option)) {
- QRect tabRect = tbb->rect;
- painter->save();
- painter->setPen(QPen(option->palette.dark().color().dark(110), 0));
- switch (tbb->shape) {
-
- case QTabBar::RoundedNorth:
- painter->drawLine(tabRect.topLeft(), tabRect.topRight());
- break;
-
- case QTabBar::RoundedWest:
- painter->drawLine(tabRect.left(), tabRect.top(), tabRect.left(), tabRect.bottom());
- break;
-
- case QTabBar::RoundedSouth:
- painter->drawLine(tbb->rect.left(), tbb->rect.bottom(),
- tabRect.right(), tabRect.bottom());
- break;
-
- case QTabBar::RoundedEast:
- painter->drawLine(tabRect.topRight(), tabRect.bottomRight());
- break;
-
- case QTabBar::TriangularNorth:
- case QTabBar::TriangularEast:
- case QTabBar::TriangularWest:
- case QTabBar::TriangularSouth:
- painter->restore();
- QWindowsStyle::drawPrimitive(element, option, painter, widget);
- return;
- }
-
- painter->restore();
- }
- return;
-
-#endif // QT_NO_TABBAR
-
- case PE_Widget:
- break;
-
- default:
- QCleanlooksStyle::drawPrimitive(element, option, painter, widget);
- }
-}
-
-/*!
- \reimp
-*/
-void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionComplex *option,
-
- QPainter *painter, const QWidget *widget) const
-{
- Q_D(const QGtkStyle);
-
- if (!d->isThemeAvailable()) {
- QCleanlooksStyle::drawComplexControl(control, option, painter, widget);
- return;
- }
-
- GtkStyle* style = d->gtkStyle();
- QGtkPainter gtkPainter(painter);
- QColor button = option->palette.button().color();
- QColor dark;
- QColor grooveColor;
- QColor darkOutline;
- dark.setHsv(button.hue(),
- qMin(255, (int)(button.saturation()*1.9)),
- qMin(255, (int)(button.value()*0.7)));
- grooveColor.setHsv(button.hue(),
- qMin(255, (int)(button.saturation()*2.6)),
- qMin(255, (int)(button.value()*0.9)));
- darkOutline.setHsv(button.hue(),
- qMin(255, (int)(button.saturation()*3.0)),
- qMin(255, (int)(button.value()*0.6)));
-
- QColor alphaCornerColor;
-
- if (widget)
- alphaCornerColor = mergedColors(option->palette.color(widget->backgroundRole()), darkOutline);
- else
- alphaCornerColor = mergedColors(option->palette.background().color(), darkOutline);
-
- switch (control) {
-
- case CC_TitleBar:
- if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(option)) {
- // Since this is drawn by metacity and not Gtk we
- // have to rely on Cleanlooks for a fallback
- QStyleOptionTitleBar copyOpt = *tb;
- QPalette pal = copyOpt.palette;
- // Bg color is closer to the window selection than
- // the base selection color
- GdkColor gdkBg = style->bg[GTK_STATE_SELECTED];
- QColor bgColor(gdkBg.red>>8, gdkBg.green>>8, gdkBg.blue>>8);
- pal.setBrush(QPalette::Active, QPalette::Highlight, bgColor);
- copyOpt.palette = pal;
- QCleanlooksStyle::drawComplexControl(control, &copyOpt, painter, widget);
- }
- break;
-
-#ifndef QT_NO_GROUPBOX
-
- case CC_GroupBox:
- painter->save();
-
- if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(option)) {
- QRect textRect = proxy()->subControlRect(CC_GroupBox, groupBox, SC_GroupBoxLabel, widget);
- QRect checkBoxRect = proxy()->subControlRect(CC_GroupBox, groupBox, SC_GroupBoxCheckBox, widget);
- // Draw title
-
- if ((groupBox->subControls & QStyle::SC_GroupBoxLabel) && !groupBox->text.isEmpty()) {
- // Draw prelight background
- GtkWidget *gtkCheckButton = d->gtkWidget("GtkCheckButton");
-
- if (option->state & State_MouseOver) {
- QRect bgRect = textRect | checkBoxRect;
- gtkPainter.paintFlatBox(gtkCheckButton, "checkbutton", bgRect.adjusted(0, 0, 0, -2),
- GTK_STATE_PRELIGHT, GTK_SHADOW_ETCHED_OUT, gtkCheckButton->style);
- }
-
- if (!groupBox->text.isEmpty()) {
- int alignment = int(groupBox->textAlignment);
- if (!proxy()->styleHint(QStyle::SH_UnderlineShortcut, option, widget))
- alignment |= Qt::TextHideMnemonic;
- QColor textColor = groupBox->textColor; // Note: custom textColor is currently ignored
- int labelState = GTK_STATE_INSENSITIVE;
-
- if (option->state & State_Enabled)
- labelState = (option->state & State_MouseOver) ? GTK_STATE_PRELIGHT : GTK_STATE_NORMAL;
-
- GdkColor gdkText = gtkCheckButton->style->fg[labelState];
- textColor = QColor(gdkText.red>>8, gdkText.green>>8, gdkText.blue>>8);
- painter->setPen(textColor);
- QFont font = painter->font();
- font.setBold(true);
- painter->setFont(font);
- painter->drawText(textRect, Qt::TextShowMnemonic | Qt::AlignLeft| alignment, groupBox->text);
-
- if (option->state & State_HasFocus)
- gtkPainter.paintFocus( NULL, "tab", textRect.adjusted(-4, -1, 0, -3), GTK_STATE_ACTIVE, style);
- }
- }
-
- if (groupBox->subControls & SC_GroupBoxCheckBox) {
- QStyleOptionButton box;
- box.QStyleOption::operator=(*groupBox);
- box.rect = checkBoxRect;
- proxy()->drawPrimitive(PE_IndicatorCheckBox, &box, painter, widget);
- }
- }
-
- painter->restore();
- break;
-#endif // QT_NO_GROUPBOX
-
-#ifndef QT_NO_COMBOBOX
-
- case CC_ComboBox:
- // See: http://live.gnome.org/GnomeArt/Tutorials/GtkThemes/GtkComboBox
- // and http://live.gnome.org/GnomeArt/Tutorials/GtkThemes/GtkComboBoxEntry
- if (const QStyleOptionComboBox *comboBox = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
- bool sunken = comboBox->state & State_On; // play dead, if combobox has no items
- BEGIN_STYLE_PIXMAPCACHE(QString::fromLatin1("cb-%0-%1").arg(sunken).arg(comboBox->editable));
- QGtkPainter gtkCachedPainter(p);
- gtkCachedPainter.setUsePixmapCache(false); // cached externally
-
- bool isEnabled = (comboBox->state & State_Enabled);
- bool focus = isEnabled && (comboBox->state & State_HasFocus);
- GtkStateType state = gtkPainter.gtkState(option);
- int appears_as_list = !proxy()->styleHint(QStyle::SH_ComboBox_Popup, comboBox, widget);
- QStyleOptionComboBox comboBoxCopy = *comboBox;
- comboBoxCopy.rect = option->rect;
-
- bool reverse = (option->direction == Qt::RightToLeft);
- QRect rect = option->rect;
- QRect arrowButtonRect = proxy()->subControlRect(CC_ComboBox, &comboBoxCopy,
- SC_ComboBoxArrow, widget);
-
- GtkShadowType shadow = (option->state & State_Sunken || option->state & State_On ) ?
- GTK_SHADOW_IN : GTK_SHADOW_OUT;
- const QHashableLatin1Literal comboBoxPath = comboBox->editable ? QHashableLatin1Literal("GtkComboBoxEntry") : QHashableLatin1Literal("GtkComboBox");
-
- // We use the gtk widget to position arrows and separators for us
- GtkWidget *gtkCombo = d->gtkWidget(comboBoxPath);
- GtkAllocation geometry = {0, 0, option->rect.width(), option->rect.height()};
- d->gtk_widget_set_direction(gtkCombo, reverse ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR);
- d->gtk_widget_size_allocate(gtkCombo, &geometry);
-
- QHashableLatin1Literal buttonPath = comboBox->editable ? QHashableLatin1Literal("GtkComboBoxEntry.GtkToggleButton")
- : QHashableLatin1Literal("GtkComboBox.GtkToggleButton");
- GtkWidget *gtkToggleButton = d->gtkWidget(buttonPath);
- d->gtk_widget_set_direction(gtkToggleButton, reverse ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR);
- if (gtkToggleButton && (appears_as_list || comboBox->editable)) {
- if (focus)
- GTK_WIDGET_SET_FLAGS(gtkToggleButton, GTK_HAS_FOCUS);
- // Draw the combo box as a line edit with a button next to it
- if (comboBox->editable || appears_as_list) {
- GtkStateType frameState = (state == GTK_STATE_PRELIGHT) ? GTK_STATE_NORMAL : state;
- QHashableLatin1Literal entryPath = comboBox->editable ? QHashableLatin1Literal("GtkComboBoxEntry.GtkEntry") : QHashableLatin1Literal("GtkComboBox.GtkFrame");
- GtkWidget *gtkEntry = d->gtkWidget(entryPath);
- d->gtk_widget_set_direction(gtkEntry, reverse ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR);
- QRect frameRect = option->rect;
-
- if (reverse)
- frameRect.setLeft(arrowButtonRect.right());
- else
- frameRect.setRight(arrowButtonRect.left());
-
- // Fill the line edit background
- // We could have used flat_box with "entry_bg" but that is probably not worth the overhead
- uint resolve_mask = option->palette.resolve();
- int xt = gtkEntry->style->xthickness;
- int yt = gtkEntry->style->ythickness;
- QRect contentRect = frameRect.adjusted(xt, yt, -xt, -yt);
- // Required for inner blue highlight with clearlooks
- if (focus)
- GTK_WIDGET_SET_FLAGS(gtkEntry, GTK_HAS_FOCUS);
-
- if (widget && widget->testAttribute(Qt::WA_SetPalette) &&
- resolve_mask & (1 << QPalette::Base)) // Palette overridden by user
- p->fillRect(contentRect, option->palette.base().color());
- else {
- gtkCachedPainter.paintFlatBox(gtkEntry, "entry_bg", contentRect,
- option->state & State_Enabled ? GTK_STATE_NORMAL : GTK_STATE_INSENSITIVE,
- GTK_SHADOW_NONE, gtkEntry->style, entryPath.toString() + QString::number(focus));
- }
-
- gtkCachedPainter.paintShadow(gtkEntry, comboBox->editable ? "entry" : "frame", frameRect, frameState,
- GTK_SHADOW_IN, gtkEntry->style, entryPath.toString() +
- QString::number(focus) + QString::number(comboBox->editable) +
- QString::number(option->direction));
- if (focus)
- GTK_WIDGET_UNSET_FLAGS(gtkEntry, GTK_HAS_FOCUS);
- }
-
- GtkStateType buttonState = GTK_STATE_NORMAL;
-
- if (!(option->state & State_Enabled))
- buttonState = GTK_STATE_INSENSITIVE;
- else if (option->state & State_Sunken || option->state & State_On)
- buttonState = GTK_STATE_ACTIVE;
- else if (option->state & State_MouseOver && comboBox->activeSubControls & SC_ComboBoxArrow)
- buttonState = GTK_STATE_PRELIGHT;
-
- Q_ASSERT(gtkToggleButton);
- gtkCachedPainter.paintBox( gtkToggleButton, "button", arrowButtonRect, buttonState,
- shadow, gtkToggleButton->style, buttonPath.toString() +
- QString::number(focus) + QString::number(option->direction));
- if (focus)
- GTK_WIDGET_UNSET_FLAGS(gtkToggleButton, GTK_HAS_FOCUS);
- } else {
- // Draw combo box as a button
- QRect buttonRect = option->rect;
-
- if (focus) // Clearlooks actually check the widget for the default state
- GTK_WIDGET_SET_FLAGS(gtkToggleButton, GTK_HAS_FOCUS);
- gtkCachedPainter.paintBox(gtkToggleButton, "button",
- buttonRect, state,
- shadow, gtkToggleButton->style,
- buttonPath.toString() + QString::number(focus));
- if (focus)
- GTK_WIDGET_UNSET_FLAGS(gtkToggleButton, GTK_HAS_FOCUS);
-
-
- // Draw the separator between label and arrows
- QHashableLatin1Literal vSeparatorPath = comboBox->editable
- ? QHashableLatin1Literal("GtkComboBoxEntry.GtkToggleButton.GtkHBox.GtkVSeparator")
- : QHashableLatin1Literal("GtkComboBox.GtkToggleButton.GtkHBox.GtkVSeparator");
-
- if (GtkWidget *gtkVSeparator = d->gtkWidget(vSeparatorPath)) {
- QRect vLineRect(gtkVSeparator->allocation.x,
- gtkVSeparator->allocation.y,
- gtkVSeparator->allocation.width,
- gtkVSeparator->allocation.height);
-
- gtkCachedPainter.paintVline( gtkVSeparator, "vseparator",
- vLineRect, state, gtkVSeparator->style,
- 0, vLineRect.height(), 0, vSeparatorPath.toString());
-
-
- gint interiorFocus = true;
- d->gtk_widget_style_get(gtkToggleButton, "interior-focus", &interiorFocus, NULL);
- int xt = interiorFocus ? gtkToggleButton->style->xthickness : 0;
- int yt = interiorFocus ? gtkToggleButton->style->ythickness : 0;
- if (focus && ((option->state & State_KeyboardFocusChange) || styleHint(SH_UnderlineShortcut, option, widget)))
- gtkCachedPainter.paintFocus(gtkToggleButton, "button",
- option->rect.adjusted(xt, yt, -xt, -yt),
- option->state & State_Sunken ? GTK_STATE_ACTIVE : GTK_STATE_NORMAL,
- gtkToggleButton->style);
- }
- }
-
- if (comboBox->subControls & SC_ComboBoxArrow) {
- if (!isEnabled)
- state = GTK_STATE_INSENSITIVE;
- else if (sunken)
- state = GTK_STATE_ACTIVE;
- else if (option->state & State_MouseOver)
- state = GTK_STATE_PRELIGHT;
- else
- state = GTK_STATE_NORMAL;
-
- QHashableLatin1Literal arrowPath("");
- if (comboBox->editable) {
- if (appears_as_list)
- arrowPath = QHashableLatin1Literal("GtkComboBoxEntry.GtkToggleButton.GtkArrow");
- else
- arrowPath = QHashableLatin1Literal("GtkComboBoxEntry.GtkToggleButton.GtkHBox.GtkArrow");
- } else {
- if (appears_as_list)
- arrowPath = QHashableLatin1Literal("GtkComboBox.GtkToggleButton.GtkArrow");
- else
- arrowPath = QHashableLatin1Literal("GtkComboBox.GtkToggleButton.GtkHBox.GtkArrow");
- }
-
- GtkWidget *gtkArrow = d->gtkWidget(arrowPath);
- gfloat scale = 0.7;
- gint minSize = 15;
- QRect arrowWidgetRect;
-
- if (gtkArrow && !d->gtk_check_version(2, 12, 0)) {
- d->gtk_widget_style_get(gtkArrow, "arrow-scaling", &scale, NULL);
- d->gtk_widget_style_get(gtkCombo, "arrow-size", &minSize, NULL);
- }
- if (gtkArrow) {
- arrowWidgetRect = QRect(gtkArrow->allocation.x, gtkArrow->allocation.y,
- gtkArrow->allocation.width, gtkArrow->allocation.height);
- style = gtkArrow->style;
- }
-
- // Note that for some reason the arrow-size is not properly respected with Hildon
- // Hence we enforce the minimum "arrow-size" ourselves
- int arrowSize = qMax(qMin(rect.height() - gtkCombo->style->ythickness * 2, minSize),
- qMin(arrowWidgetRect.width(), arrowWidgetRect.height()));
- QRect arrowRect(0, 0, static_cast<int>(arrowSize * scale), static_cast<int>(arrowSize * scale));
-
- arrowRect.moveCenter(arrowWidgetRect.center());
-
- if (sunken) {
- int xoff, yoff;
- const QHashableLatin1Literal toggleButtonPath = comboBox->editable
- ? QHashableLatin1Literal("GtkComboBoxEntry.GtkToggleButton")
- : QHashableLatin1Literal("GtkComboBox.GtkToggleButton");
-
- GtkWidget *gtkButton = d->gtkWidget(toggleButtonPath);
- d->gtk_widget_style_get(gtkButton, "child-displacement-x", &xoff, NULL);
- d->gtk_widget_style_get(gtkButton, "child-displacement-y", &yoff, NULL);
- arrowRect = arrowRect.adjusted(xoff, yoff, xoff, yoff);
- }
-
- // Some styles such as Nimbus paint outside the arrowRect
- // hence we have provide the whole widget as the cliprect
- if (gtkArrow) {
- gtkCachedPainter.setClipRect(option->rect);
- gtkCachedPainter.paintArrow( gtkArrow, "arrow", arrowRect,
- GTK_ARROW_DOWN, state, GTK_SHADOW_NONE, TRUE,
- style, arrowPath.toString() + QString::number(option->direction));
- }
- }
- END_STYLE_PIXMAPCACHE;
- }
- break;
-#endif // QT_NO_COMBOBOX
-#ifndef QT_NO_TOOLBUTTON
-
- case CC_ToolButton:
- if (const QStyleOptionToolButton *toolbutton
- = qstyleoption_cast<const QStyleOptionToolButton *>(option)) {
- QRect button, menuarea;
- button = proxy()->subControlRect(control, toolbutton, SC_ToolButton, widget);
- menuarea = proxy()->subControlRect(control, toolbutton, SC_ToolButtonMenu, widget);
- State bflags = toolbutton->state & ~(State_Sunken | State_MouseOver);
-
- if (bflags & State_AutoRaise)
- if (!(bflags & State_MouseOver))
- bflags &= ~State_Raised;
-
- State mflags = bflags;
-
- if (toolbutton->state & State_Sunken) {
- if (toolbutton->activeSubControls & SC_ToolButton)
- bflags |= State_Sunken;
- if (toolbutton->activeSubControls & SC_ToolButtonMenu)
- mflags |= State_Sunken;
- } else if (toolbutton->state & State_MouseOver) {
- if (toolbutton->activeSubControls & SC_ToolButton)
- bflags |= State_MouseOver;
- if (toolbutton->activeSubControls & SC_ToolButtonMenu)
- mflags |= State_MouseOver;
- }
-
- QStyleOption tool(0);
-
- tool.palette = toolbutton->palette;
-
- if (toolbutton->subControls & SC_ToolButton) {
- if (bflags & (State_Sunken | State_On | State_Raised | State_MouseOver)) {
- tool.rect = button;
- tool.state = bflags;
- proxy()->drawPrimitive(PE_PanelButtonTool, &tool, painter, widget);
- }
- }
-
- bool drawMenuArrow = toolbutton->features & QStyleOptionToolButton::HasMenu &&
- !(toolbutton->features & QStyleOptionToolButton::MenuButtonPopup);
- int popupArrowSize = drawMenuArrow ? 7 : 0;
-
- if (toolbutton->state & State_HasFocus) {
- QStyleOptionFocusRect fr;
- fr.QStyleOption::operator=(*toolbutton);
- fr.rect = proxy()->subControlRect(CC_ToolButton, toolbutton, SC_ToolButton, widget);
- fr.rect.adjust(1, 1, -1, -1);
- proxy()->drawPrimitive(PE_FrameFocusRect, &fr, painter, widget);
- }
-
- QStyleOptionToolButton label = *toolbutton;
- label.state = bflags;
- GtkWidget *gtkButton = d->gtkWidget("GtkToolButton.GtkButton");
- QPalette pal = toolbutton->palette;
- if (option->state & State_Enabled &&
- option->state & State_MouseOver && !(widget && widget->testAttribute(Qt::WA_SetPalette))) {
- GdkColor gdkText = gtkButton->style->fg[GTK_STATE_PRELIGHT];
- QColor textColor = QColor(gdkText.red>>8, gdkText.green>>8, gdkText.blue>>8);
- pal.setBrush(QPalette::All, QPalette::ButtonText, textColor);
- label.palette = pal;
- }
- label.rect = button.adjusted(style->xthickness, style->ythickness,
- -style->xthickness - popupArrowSize, -style->ythickness);
- proxy()->drawControl(CE_ToolButtonLabel, &label, painter, widget);
-
- if (toolbutton->subControls & SC_ToolButtonMenu) {
- tool.rect = menuarea;
- tool.state = mflags;
- if ((mflags & State_Enabled && (mflags & (State_Sunken | State_Raised | State_MouseOver))) || !(mflags & State_AutoRaise))
- proxy()->drawPrimitive(PE_IndicatorButtonDropDown, &tool, painter, widget);
-
- proxy()->drawPrimitive(PE_IndicatorArrowDown, &tool, painter, widget);
-
- } else if (drawMenuArrow) {
- QRect ir = toolbutton->rect;
- QStyleOptionToolButton newBtn = *toolbutton;
- newBtn.rect = QRect(ir.right() - popupArrowSize - style->xthickness - 3, ir.height()/2 - 1, popupArrowSize, popupArrowSize);
- proxy()->drawPrimitive(PE_IndicatorArrowDown, &newBtn, painter, widget);
- }
- }
- break;
-
-#endif // QT_NO_TOOLBUTTON
-#ifndef QT_NO_SCROLLBAR
-
- case CC_ScrollBar:
- if (const QStyleOptionSlider *scrollBar = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
- GtkWidget *gtkHScrollBar = d->gtkWidget("GtkHScrollbar");
- GtkWidget *gtkVScrollBar = d->gtkWidget("GtkVScrollbar");
-
- // Fill background in case the scrollbar is partially transparent
- painter->fillRect(option->rect, option->palette.background());
-
- QRect rect = scrollBar->rect;
- QRect scrollBarSubLine = proxy()->subControlRect(control, scrollBar, SC_ScrollBarSubLine, widget);
- QRect scrollBarAddLine = proxy()->subControlRect(control, scrollBar, SC_ScrollBarAddLine, widget);
- QRect scrollBarSlider = proxy()->subControlRect(control, scrollBar, SC_ScrollBarSlider, widget);
- QRect grooveRect = proxy()->subControlRect(control, scrollBar, SC_ScrollBarGroove, widget);
- bool horizontal = scrollBar->orientation == Qt::Horizontal;
- GtkWidget * scrollbarWidget = horizontal ? gtkHScrollBar : gtkVScrollBar;
- style = scrollbarWidget->style;
- gboolean trough_under_steppers = true;
- gboolean trough_side_details = false;
- gboolean activate_slider = false;
- gboolean stepper_size = 14;
- gint trough_border = 1;
- if (!d->gtk_check_version(2, 10, 0)) {
- d->gtk_widget_style_get((GtkWidget*)(scrollbarWidget),
- "trough-border", &trough_border,
- "trough-side-details", &trough_side_details,
- "trough-under-steppers", &trough_under_steppers,
- "activate-slider", &activate_slider,
- "stepper-size", &stepper_size, NULL);
- }
- if (trough_under_steppers) {
- scrollBarAddLine.adjust(trough_border, trough_border, -trough_border, -trough_border);
- scrollBarSubLine.adjust(trough_border, trough_border, -trough_border, -trough_border);
- scrollBarSlider.adjust(horizontal ? -trough_border : 0, horizontal ? 0 : -trough_border,
- horizontal ? trough_border : 0, horizontal ? 0 : trough_border);
- }
-
- // Some styles check the position of scrollbars in order to determine
- // if lines should be painted when the scrollbar is in max or min positions.
- int maximum = 2;
- int fakePos = 0;
- bool reverse = (option->direction == Qt::RightToLeft);
- if (scrollBar->minimum == scrollBar->maximum)
- maximum = 0;
- if (scrollBar->sliderPosition == scrollBar->maximum)
- fakePos = maximum;
- else if (scrollBar->sliderPosition > scrollBar->minimum)
- fakePos = maximum - 1;
-
-
- GtkRange *range = (GtkRange*)(horizontal ? gtkHScrollBar : gtkVScrollBar);
- GtkAdjustment *adjustment = d->gtk_range_get_adjustment(range);
-
- if (adjustment) {
- d->gtk_adjustment_configure(adjustment, fakePos, 0, maximum, 0, 0, 0);
- } else {
- adjustment = (GtkAdjustment*)d->gtk_adjustment_new(fakePos, 0, maximum, 0, 0, 0);
- d->gtk_range_set_adjustment(range, adjustment);
- }
-
- if (scrollBar->subControls & SC_ScrollBarGroove) {
- GtkStateType state = GTK_STATE_ACTIVE;
-
- if (!(option->state & State_Enabled))
- state = GTK_STATE_INSENSITIVE;
-
- if (trough_under_steppers)
- grooveRect = option->rect;
-
- gtkPainter.paintBox( scrollbarWidget, "trough", grooveRect, state, GTK_SHADOW_IN, style);
- }
-
- //paint slider
- if (scrollBar->subControls & SC_ScrollBarSlider) {
- GtkStateType state = GTK_STATE_NORMAL;
-
- if (!(option->state & State_Enabled))
- state = GTK_STATE_INSENSITIVE;
- else if (activate_slider &&
- option->state & State_Sunken && (scrollBar->activeSubControls & SC_ScrollBarSlider))
- state = GTK_STATE_ACTIVE;
- else if (option->state & State_MouseOver && (scrollBar->activeSubControls & SC_ScrollBarSlider))
- state = GTK_STATE_PRELIGHT;
-
- GtkShadowType shadow = GTK_SHADOW_OUT;
-
- if (trough_under_steppers) {
- if (!horizontal)
- scrollBarSlider.adjust(trough_border, 0, -trough_border, 0);
- else
- scrollBarSlider.adjust(0, trough_border, 0, -trough_border);
- }
-
- gtkPainter.paintSlider( scrollbarWidget, "slider", scrollBarSlider, state, shadow, style,
-
- horizontal ? GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL, QString(QLS("%0%1")).arg(fakePos).arg(maximum));
- }
-
- if (scrollBar->subControls & SC_ScrollBarAddLine) {
- gtkVScrollBar->allocation.y = scrollBarAddLine.top();
- gtkVScrollBar->allocation.height = scrollBarAddLine.height() - rect.height() + 6;
- gtkHScrollBar->allocation.x = scrollBarAddLine.right();
- gtkHScrollBar->allocation.width = scrollBarAddLine.width() - rect.width();
-
- GtkShadowType shadow = GTK_SHADOW_OUT;
- GtkStateType state = GTK_STATE_NORMAL;
-
- if (!(option->state & State_Enabled) || (fakePos == maximum))
- state = GTK_STATE_INSENSITIVE;
- else if (option->state & State_Sunken && (scrollBar->activeSubControls & SC_ScrollBarAddLine)) {
- state = GTK_STATE_ACTIVE;
- shadow = GTK_SHADOW_IN;
-
- } else if (option->state & State_MouseOver && (scrollBar->activeSubControls & SC_ScrollBarAddLine))
- state = GTK_STATE_PRELIGHT;
-
- gtkPainter.paintBox( scrollbarWidget,
- horizontal ? "hscrollbar" : "vscrollbar", scrollBarAddLine,
- state, shadow, style, QLS("add"));
-
- gtkPainter.paintArrow( scrollbarWidget, horizontal ? "hscrollbar" : "vscrollbar", scrollBarAddLine.adjusted(4, 4, -4, -4),
- horizontal ? (reverse ? GTK_ARROW_LEFT : GTK_ARROW_RIGHT) :
- GTK_ARROW_DOWN, state, GTK_SHADOW_NONE, FALSE, style);
- }
-
- if (scrollBar->subControls & SC_ScrollBarSubLine) {
- gtkVScrollBar->allocation.y = 0;
- gtkVScrollBar->allocation.height = scrollBarSubLine.height();
- gtkHScrollBar->allocation.x = 0;
- gtkHScrollBar->allocation.width = scrollBarSubLine.width();
-
- GtkShadowType shadow = GTK_SHADOW_OUT;
- GtkStateType state = GTK_STATE_NORMAL;
-
- if (!(option->state & State_Enabled) || (fakePos == 0))
- state = GTK_STATE_INSENSITIVE;
- else if (option->state & State_Sunken && (scrollBar->activeSubControls & SC_ScrollBarSubLine)) {
- shadow = GTK_SHADOW_IN;
- state = GTK_STATE_ACTIVE;
-
- } else if (option->state & State_MouseOver && (scrollBar->activeSubControls & SC_ScrollBarSubLine))
- state = GTK_STATE_PRELIGHT;
-
- gtkPainter.paintBox(scrollbarWidget, horizontal ? "hscrollbar" : "vscrollbar", scrollBarSubLine,
- state, shadow, style, QLS("sub"));
-
- gtkPainter.paintArrow(scrollbarWidget, horizontal ? "hscrollbar" : "vscrollbar", scrollBarSubLine.adjusted(4, 4, -4, -4),
- horizontal ? (reverse ? GTK_ARROW_RIGHT : GTK_ARROW_LEFT) :
- GTK_ARROW_UP, state, GTK_SHADOW_NONE, FALSE, style);
- }
- }
- break;
-
-#endif //QT_NO_SCROLLBAR
-#ifndef QT_NO_SPINBOX
-
- case CC_SpinBox:
- if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
-
- GtkWidget *gtkSpinButton = spinBox->buttonSymbols == QAbstractSpinBox::NoButtons
- ? d->gtkWidget("GtkEntry")
- : d->gtkWidget("GtkSpinButton");
- bool isEnabled = (spinBox->state & State_Enabled);
- bool hover = isEnabled && (spinBox->state & State_MouseOver);
- bool sunken = (spinBox->state & State_Sunken);
- bool upIsActive = (spinBox->activeSubControls == SC_SpinBoxUp);
- bool downIsActive = (spinBox->activeSubControls == SC_SpinBoxDown);
- bool reverse = (spinBox->direction == Qt::RightToLeft);
-
- QRect editArea = option->rect;
- QRect editRect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxEditField, widget);
- QRect upRect, downRect, buttonRect;
- if (spinBox->buttonSymbols != QAbstractSpinBox::NoButtons) {
- upRect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxUp, widget);
- downRect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxDown, widget);
-
- //### Move this to subControlRect
- upRect.setTop(option->rect.top());
-
- if (reverse)
- upRect.setLeft(option->rect.left());
- else
- upRect.setRight(option->rect.right());
-
- downRect.setBottom(option->rect.bottom());
-
- if (reverse)
- downRect.setLeft(option->rect.left());
- else
- downRect.setRight(option->rect.right());
-
- buttonRect = upRect | downRect;
-
- if (reverse)
- editArea.setLeft(upRect.right());
- else
- editArea.setRight(upRect.left());
- }
- if (spinBox->frame) {
- GtkStateType state = gtkPainter.gtkState(option);
-
- if (!(option->state & State_Enabled))
- state = GTK_STATE_INSENSITIVE;
- else if (option->state & State_HasFocus)
- state = GTK_STATE_NORMAL;
- else if (state == GTK_STATE_PRELIGHT)
- state = GTK_STATE_NORMAL;
-
- style = gtkPainter.getStyle(gtkSpinButton);
-
-
- QString key;
-
- if (option->state & State_HasFocus) {
- key += QLatin1Char('f');
- GTK_WIDGET_SET_FLAGS(gtkSpinButton, GTK_HAS_FOCUS);
- }
-
- uint resolve_mask = option->palette.resolve();
-
- if (resolve_mask & (1 << QPalette::Base)) // Palette overridden by user
- painter->fillRect(editRect, option->palette.base().color());
- else
- gtkPainter.paintFlatBox(gtkSpinButton, "entry_bg", editArea.adjusted(style->xthickness, style->ythickness,
- -style->xthickness, -style->ythickness),
- option->state & State_Enabled ?
- GTK_STATE_NORMAL : GTK_STATE_INSENSITIVE, GTK_SHADOW_NONE, style, key);
-
- gtkPainter.paintShadow(gtkSpinButton, "entry", editArea, state, GTK_SHADOW_IN, gtkSpinButton->style, key);
- if (spinBox->buttonSymbols != QAbstractSpinBox::NoButtons) {
- gtkPainter.paintBox(gtkSpinButton, "spinbutton", buttonRect, state, GTK_SHADOW_IN, style, key);
-
- upRect.setSize(downRect.size());
- if (!(option->state & State_Enabled))
- gtkPainter.paintBox( gtkSpinButton, "spinbutton_up", upRect, GTK_STATE_INSENSITIVE, GTK_SHADOW_IN, style, key);
- else if (upIsActive && sunken)
- gtkPainter.paintBox( gtkSpinButton, "spinbutton_up", upRect, GTK_STATE_ACTIVE, GTK_SHADOW_IN, style, key);
- else if (upIsActive && hover)
- gtkPainter.paintBox( gtkSpinButton, "spinbutton_up", upRect, GTK_STATE_PRELIGHT, GTK_SHADOW_OUT, style, key);
- else
- gtkPainter.paintBox( gtkSpinButton, "spinbutton_up", upRect, GTK_STATE_NORMAL, GTK_SHADOW_OUT, style, key);
-
- if (!(option->state & State_Enabled))
- gtkPainter.paintBox( gtkSpinButton, "spinbutton_down", downRect, GTK_STATE_INSENSITIVE, GTK_SHADOW_IN, style, key);
- else if (downIsActive && sunken)
- gtkPainter.paintBox( gtkSpinButton, "spinbutton_down", downRect, GTK_STATE_ACTIVE, GTK_SHADOW_IN, style, key);
- else if (downIsActive && hover)
- gtkPainter.paintBox( gtkSpinButton, "spinbutton_down", downRect, GTK_STATE_PRELIGHT, GTK_SHADOW_OUT, style, key);
- else
- gtkPainter.paintBox( gtkSpinButton, "spinbutton_down", downRect, GTK_STATE_NORMAL, GTK_SHADOW_OUT, style, key);
-
- if (option->state & State_HasFocus)
- GTK_WIDGET_UNSET_FLAGS(gtkSpinButton, GTK_HAS_FOCUS);
- }
- }
-
- if (spinBox->buttonSymbols == QAbstractSpinBox::PlusMinus) {
- int centerX = upRect.center().x();
- int centerY = upRect.center().y();
- // plus/minus
-
- if (spinBox->activeSubControls == SC_SpinBoxUp && sunken) {
- painter->drawLine(1 + centerX - 2, 1 + centerY, 1 + centerX + 2, 1 + centerY);
- painter->drawLine(1 + centerX, 1 + centerY - 2, 1 + centerX, 1 + centerY + 2);
-
- } else {
- painter->drawLine(centerX - 2, centerY, centerX + 2, centerY);
- painter->drawLine(centerX, centerY - 2, centerX, centerY + 2);
- }
- centerX = downRect.center().x();
- centerY = downRect.center().y();
-
- if (spinBox->activeSubControls == SC_SpinBoxDown && sunken) {
- painter->drawLine(1 + centerX - 2, 1 + centerY, 1 + centerX + 2, 1 + centerY);
- } else {
- painter->drawLine(centerX - 2, centerY, centerX + 2, centerY);
- }
-
- } else if (spinBox->buttonSymbols == QAbstractSpinBox::UpDownArrows) {
- int size = d->getSpinboxArrowSize();
- int w = size / 2 - 1;
- w -= w % 2 - 1; // force odd
- int h = (w + 1)/2;
- QRect arrowRect(0, 0, w, h);
- arrowRect.moveCenter(upRect.center());
- // arrows
- GtkStateType state = GTK_STATE_NORMAL;
-
- if (!(option->state & State_Enabled) || !(spinBox->stepEnabled & QAbstractSpinBox::StepUpEnabled))
- state = GTK_STATE_INSENSITIVE;
-
- gtkPainter.paintArrow( gtkSpinButton, "spinbutton", arrowRect, GTK_ARROW_UP, state,
- GTK_SHADOW_NONE, FALSE, style);
-
- arrowRect.moveCenter(downRect.center());
-
- if (!(option->state & State_Enabled) || !(spinBox->stepEnabled & QAbstractSpinBox::StepDownEnabled))
- state = GTK_STATE_INSENSITIVE;
-
- gtkPainter.paintArrow( gtkSpinButton, "spinbutton", arrowRect, GTK_ARROW_DOWN, state,
- GTK_SHADOW_NONE, FALSE, style);
- }
- }
- break;
-
-#endif // QT_NO_SPINBOX
-
-#ifndef QT_NO_SLIDER
-
- case CC_Slider:
- if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
- GtkWidget *hScaleWidget = d->gtkWidget("GtkHScale");
- GtkWidget *vScaleWidget = d->gtkWidget("GtkVScale");
-
- QRect groove = proxy()->subControlRect(CC_Slider, option, SC_SliderGroove, widget);
- QRect handle = proxy()->subControlRect(CC_Slider, option, SC_SliderHandle, widget);
-
- bool horizontal = slider->orientation == Qt::Horizontal;
- bool ticksAbove = slider->tickPosition & QSlider::TicksAbove;
- bool ticksBelow = slider->tickPosition & QSlider::TicksBelow;
-
- QBrush oldBrush = painter->brush();
- QPen oldPen = painter->pen();
-
- QColor shadowAlpha(Qt::black);
- shadowAlpha.setAlpha(10);
- QColor highlightAlpha(Qt::white);
- highlightAlpha.setAlpha(80);
-
- QGtkStylePrivate::gtk_widget_set_direction(hScaleWidget, slider->upsideDown ?
- GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR);
- GtkWidget *scaleWidget = horizontal ? hScaleWidget : vScaleWidget;
- style = scaleWidget->style;
-
- if ((option->subControls & SC_SliderGroove) && groove.isValid()) {
-
- GtkRange *range = (GtkRange*)scaleWidget;
- GtkAdjustment *adjustment = d->gtk_range_get_adjustment(range);
- if (adjustment) {
- d->gtk_adjustment_configure(adjustment,
- slider->sliderPosition,
- slider->minimum,
- slider->maximum,
- slider->singleStep,
- slider->singleStep,
- slider->pageStep);
- } else {
- adjustment = (GtkAdjustment*)d->gtk_adjustment_new(slider->sliderPosition,
- slider->minimum,
- slider->maximum,
- slider->singleStep,
- slider->singleStep,
- slider->pageStep);
- d->gtk_range_set_adjustment(range, adjustment);
- }
-
- int outerSize;
- d->gtk_range_set_inverted(range, !horizontal);
- d->gtk_widget_style_get(scaleWidget, "trough-border", &outerSize, NULL);
- outerSize++;
-
- GtkStateType state = gtkPainter.gtkState(option);
- int focusFrameMargin = 2;
- QRect grooveRect = option->rect.adjusted(focusFrameMargin, outerSize + focusFrameMargin,
- -focusFrameMargin, -outerSize - focusFrameMargin);
-
- gboolean trough_side_details = false; // Indicates if the upper or lower scale background differs
- if (!d->gtk_check_version(2, 10, 0))
- d->gtk_widget_style_get((GtkWidget*)(scaleWidget), "trough-side-details", &trough_side_details, NULL);
-
- if (!trough_side_details) {
- gtkPainter.paintBox( scaleWidget, "trough", grooveRect, state,
- GTK_SHADOW_IN, style, QString(QLS("p%0")).arg(slider->sliderPosition));
- } else {
- QRect upperGroove = grooveRect;
- QRect lowerGroove = grooveRect;
-
- if (horizontal) {
- if (slider->upsideDown) {
- lowerGroove.setLeft(handle.center().x());
- upperGroove.setRight(handle.center().x());
- } else {
- upperGroove.setLeft(handle.center().x());
- lowerGroove.setRight(handle.center().x());
- }
- } else {
- if (!slider->upsideDown) {
- lowerGroove.setBottom(handle.center().y());
- upperGroove.setTop(handle.center().y());
- } else {
- upperGroove.setBottom(handle.center().y());
- lowerGroove.setTop(handle.center().y());
- }
- }
-
- gtkPainter.paintBox( scaleWidget, "trough-upper", upperGroove, state,
- GTK_SHADOW_IN, style, QString(QLS("p%0")).arg(slider->sliderPosition));
- gtkPainter.paintBox( scaleWidget, "trough-lower", lowerGroove, state,
- GTK_SHADOW_IN, style, QString(QLS("p%0")).arg(slider->sliderPosition));
- }
- }
-
- if (option->subControls & SC_SliderTickmarks) {
- painter->setPen(darkOutline);
- int tickSize = proxy()->pixelMetric(PM_SliderTickmarkOffset, option, widget);
- int available = proxy()->pixelMetric(PM_SliderSpaceAvailable, slider, widget);
- int interval = slider->tickInterval;
-
- if (interval <= 0) {
- interval = slider->singleStep;
-
- if (QStyle::sliderPositionFromValue(slider->minimum, slider->maximum, interval,
- available)
- - QStyle::sliderPositionFromValue(slider->minimum, slider->maximum,
- 0, available) < 3)
- interval = slider->pageStep;
- }
-
- if (interval <= 0)
- interval = 1;
-
- int v = slider->minimum;
- int len = proxy()->pixelMetric(PM_SliderLength, slider, widget);
- while (v <= slider->maximum + 1) {
- if (v == slider->maximum + 1 && interval == 1)
- break;
- const int v_ = qMin(v, slider->maximum);
- int pos = sliderPositionFromValue(slider->minimum, slider->maximum,
- v_, (horizontal
- ? slider->rect.width()
- : slider->rect.height()) - len,
- slider->upsideDown) + len / 2;
- int extra = 2 - ((v_ == slider->minimum || v_ == slider->maximum) ? 1 : 0);
- if (horizontal) {
- if (ticksAbove)
- painter->drawLine(pos, slider->rect.top() + extra,
- pos, slider->rect.top() + tickSize);
- if (ticksBelow)
- painter->drawLine(pos, slider->rect.bottom() - extra,
- pos, slider->rect.bottom() - tickSize);
-
- } else {
- if (ticksAbove)
- painter->drawLine(slider->rect.left() + extra, pos,
- slider->rect.left() + tickSize, pos);
- if (ticksBelow)
- painter->drawLine(slider->rect.right() - extra, pos,
- slider->rect.right() - tickSize, pos);
- }
-
- // In the case where maximum is max int
- int nextInterval = v + interval;
- if (nextInterval < v)
- break;
- v = nextInterval;
- }
- }
-
- // Draw slider handle
- if (option->subControls & SC_SliderHandle) {
- GtkShadowType shadow = GTK_SHADOW_OUT;
- GtkStateType state = GTK_STATE_NORMAL;
-
- if (!(option->state & State_Enabled))
- state = GTK_STATE_INSENSITIVE;
- else if (option->state & State_MouseOver && option->activeSubControls & SC_SliderHandle)
- state = GTK_STATE_PRELIGHT;
-
- bool horizontal = option->state & State_Horizontal;
-
- if (slider->state & State_HasFocus) {
- QStyleOptionFocusRect fropt;
- fropt.QStyleOption::operator=(*slider);
- fropt.rect = slider->rect.adjusted(-1, -1 ,1, 1);
-
- if (horizontal) {
- fropt.rect.setTop(handle.top() - 3);
- fropt.rect.setBottom(handle.bottom() + 4);
-
- } else {
- fropt.rect.setLeft(handle.left() - 3);
- fropt.rect.setRight(handle.right() + 3);
- }
- proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget);
- }
- gtkPainter.paintSlider( scaleWidget, horizontal ? "hscale" : "vscale", handle, state, shadow, style,
-
- horizontal ? GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL);
- }
- painter->setBrush(oldBrush);
- painter->setPen(oldPen);
- }
- break;
-
-#endif // QT_NO_SLIDER
-
- default:
- QCleanlooksStyle::drawComplexControl(control, option, painter, widget);
-
- break;
- }
-}
-
-
-/*!
- \reimp
-*/
-void QGtkStyle::drawControl(ControlElement element,
- const QStyleOption *option,
- QPainter *painter,
- const QWidget *widget) const
-{
- Q_D(const QGtkStyle);
-
- if (!d->isThemeAvailable()) {
- QCleanlooksStyle::drawControl(element, option, painter, widget);
- return;
- }
-
- GtkStyle* style = d->gtkStyle();
- QGtkPainter gtkPainter(painter);
-
- switch (element) {
- case CE_ProgressBarLabel:
- if (const QStyleOptionProgressBar *bar = qstyleoption_cast<const QStyleOptionProgressBar *>(option)) {
- GtkWidget *gtkProgressBar = d->gtkWidget("GtkProgressBar");
- if (!gtkProgressBar)
- return;
-
- QRect leftRect;
- QRect rect = bar->rect;
- GdkColor gdkText = gtkProgressBar->style->fg[GTK_STATE_NORMAL];
- QColor textColor = QColor(gdkText.red>>8, gdkText.green>>8, gdkText.blue>>8);
- gdkText = gtkProgressBar->style->fg[GTK_STATE_PRELIGHT];
- QColor alternateTextColor= QColor(gdkText.red>>8, gdkText.green>>8, gdkText.blue>>8);
-
- painter->save();
- bool vertical = false, inverted = false;
- if (const QStyleOptionProgressBarV2 *bar2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option)) {
- vertical = (bar2->orientation == Qt::Vertical);
- inverted = bar2->invertedAppearance;
- }
- if (vertical)
- rect = QRect(rect.left(), rect.top(), rect.height(), rect.width()); // flip width and height
- const int progressIndicatorPos = (bar->progress - qreal(bar->minimum)) * rect.width() /
- qMax(qreal(1.0), qreal(bar->maximum) - bar->minimum);
- if (progressIndicatorPos >= 0 && progressIndicatorPos <= rect.width())
- leftRect = QRect(rect.left(), rect.top(), progressIndicatorPos, rect.height());
- if (vertical)
- leftRect.translate(rect.width() - progressIndicatorPos, 0);
-
- bool flip = (!vertical && (((bar->direction == Qt::RightToLeft) && !inverted) ||
- ((bar->direction == Qt::LeftToRight) && inverted)));
-
- QRegion rightRect = rect;
- rightRect = rightRect.subtracted(leftRect);
- painter->setClipRegion(rightRect);
- painter->setPen(flip ? alternateTextColor : textColor);
- painter->drawText(rect, bar->text, QTextOption(Qt::AlignAbsolute | Qt::AlignHCenter | Qt::AlignVCenter));
- if (!leftRect.isNull()) {
- painter->setPen(flip ? textColor : alternateTextColor);
- painter->setClipRect(leftRect);
- painter->drawText(rect, bar->text, QTextOption(Qt::AlignAbsolute | Qt::AlignHCenter | Qt::AlignVCenter));
- }
- painter->restore();
- }
- break;
- case CE_PushButtonLabel:
- if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
- QRect ir = button->rect;
- uint tf = Qt::AlignVCenter | Qt::TextShowMnemonic;
- QPoint buttonShift;
-
- if (option->state & State_Sunken)
- buttonShift = QPoint(pixelMetric(PM_ButtonShiftHorizontal, option, widget),
- proxy()->pixelMetric(PM_ButtonShiftVertical, option, widget));
-
- if (proxy()->styleHint(SH_UnderlineShortcut, button, widget))
- tf |= Qt::TextShowMnemonic;
- else
- tf |= Qt::TextHideMnemonic;
-
- if (!button->icon.isNull()) {
- //Center both icon and text
- QPoint point;
-
- QIcon::Mode mode = button->state & State_Enabled ? QIcon::Normal : QIcon::Disabled;
- if (mode == QIcon::Normal && button->state & State_HasFocus)
- mode = QIcon::Active;
-
- QIcon::State state = QIcon::Off;
-
- if (button->state & State_On)
- state = QIcon::On;
-
- QPixmap pixmap = button->icon.pixmap(button->iconSize, mode, state);
- int w = pixmap.width();
- int h = pixmap.height();
-
- if (!button->text.isEmpty())
- w += button->fontMetrics.boundingRect(option->rect, tf, button->text).width() + 4;
-
- point = QPoint(ir.x() + ir.width() / 2 - w / 2,
- ir.y() + ir.height() / 2 - h / 2);
-
- if (button->direction == Qt::RightToLeft)
- point.rx() += pixmap.width();
-
- painter->drawPixmap(visualPos(button->direction, button->rect, point + buttonShift), pixmap);
-
- if (button->direction == Qt::RightToLeft)
- ir.translate(-point.x() - 2, 0);
- else
- ir.translate(point.x() + pixmap.width() + 2, 0);
-
- // left-align text if there is
- if (!button->text.isEmpty())
- tf |= Qt::AlignLeft;
-
- } else {
- tf |= Qt::AlignHCenter;
- }
-
- ir.translate(buttonShift);
-
- if (button->features & QStyleOptionButton::HasMenu)
- ir = ir.adjusted(0, 0, -pixelMetric(PM_MenuButtonIndicator, button, widget), 0);
-
- GtkWidget *gtkButton = d->gtkWidget("GtkButton");
- QPalette pal = button->palette;
- int labelState = GTK_STATE_INSENSITIVE;
- if (option->state & State_Enabled)
- labelState = (option->state & State_MouseOver && !(option->state & State_Sunken)) ?
- GTK_STATE_PRELIGHT : GTK_STATE_NORMAL;
-
- GdkColor gdkText = gtkButton->style->fg[labelState];
- QColor textColor = QColor(gdkText.red>>8, gdkText.green>>8, gdkText.blue>>8);
- pal.setBrush(QPalette::ButtonText, textColor);
- proxy()->drawItemText(painter, ir, tf, pal, (button->state & State_Enabled),
- button->text, QPalette::ButtonText);
- }
- break;
-
- case CE_RadioButton: // Fall through
- case CE_CheckBox:
- if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
- bool isRadio = (element == CE_RadioButton);
-
- // Draw prelight background
- GtkWidget *gtkRadioButton = d->gtkWidget("GtkRadioButton");
-
- if (option->state & State_MouseOver) {
- gtkPainter.paintFlatBox(gtkRadioButton, "checkbutton", option->rect,
- GTK_STATE_PRELIGHT, GTK_SHADOW_ETCHED_OUT, gtkRadioButton->style);
- }
-
- QStyleOptionButton subopt = *btn;
- subopt.rect = subElementRect(isRadio ? SE_RadioButtonIndicator
- : SE_CheckBoxIndicator, btn, widget);
- proxy()->drawPrimitive(isRadio ? PE_IndicatorRadioButton : PE_IndicatorCheckBox,
- &subopt, painter, widget);
- subopt.rect = subElementRect(isRadio ? SE_RadioButtonContents
- : SE_CheckBoxContents, btn, widget);
- // Get label text color
- QPalette pal = subopt.palette;
- int labelState = GTK_STATE_INSENSITIVE;
- if (option->state & State_Enabled)
- labelState = (option->state & State_MouseOver) ? GTK_STATE_PRELIGHT : GTK_STATE_NORMAL;
-
- GdkColor gdkText = gtkRadioButton->style->fg[labelState];
- QColor textColor = QColor(gdkText.red>>8, gdkText.green>>8, gdkText.blue>>8);
- pal.setBrush(QPalette::WindowText, textColor);
- subopt.palette = pal;
- proxy()->drawControl(isRadio ? CE_RadioButtonLabel : CE_CheckBoxLabel, &subopt, painter, widget);
-
- if (btn->state & State_HasFocus) {
- QStyleOptionFocusRect fropt;
- fropt.QStyleOption::operator=(*btn);
- fropt.rect = subElementRect(isRadio ? SE_RadioButtonFocusRect
- : SE_CheckBoxFocusRect, btn, widget);
- proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget);
- }
- }
- break;
-
-#ifndef QT_NO_COMBOBOX
-
- case CE_ComboBoxLabel:
- if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
- QRect editRect = proxy()->subControlRect(CC_ComboBox, cb, SC_ComboBoxEditField, widget);
- bool appearsAsList = !proxy()->styleHint(QStyle::SH_ComboBox_Popup, cb, widget);
- painter->save();
- painter->setClipRect(editRect);
-
- if (!cb->currentIcon.isNull()) {
- QIcon::Mode mode = cb->state & State_Enabled ? QIcon::Normal
- : QIcon::Disabled;
- QPixmap pixmap = cb->currentIcon.pixmap(cb->iconSize, mode);
- QRect iconRect(editRect);
- iconRect.setWidth(cb->iconSize.width() + 4);
-
- iconRect = alignedRect(cb->direction,
- Qt::AlignLeft | Qt::AlignVCenter,
- iconRect.size(), editRect);
-
- if (cb->editable)
- painter->fillRect(iconRect, option->palette.brush(QPalette::Base));
-
- proxy()->drawItemPixmap(painter, iconRect, Qt::AlignCenter, pixmap);
-
- if (cb->direction == Qt::RightToLeft)
- editRect.translate(-4 - cb->iconSize.width(), 0);
- else
- editRect.translate(cb->iconSize.width() + 4, 0);
- }
-
- if (!cb->currentText.isEmpty() && !cb->editable) {
- GtkWidget *gtkCombo = d->gtkWidget("GtkComboBox");
- QPalette pal = cb->palette;
- int labelState = GTK_STATE_INSENSITIVE;
-
- if (option->state & State_Enabled)
- labelState = (option->state & State_MouseOver && !appearsAsList) ? GTK_STATE_PRELIGHT : GTK_STATE_NORMAL;
-
- GdkColor gdkText = gtkCombo->style->fg[labelState];
-
- QColor textColor = QColor(gdkText.red>>8, gdkText.green>>8, gdkText.blue>>8);
-
- pal.setBrush(QPalette::ButtonText, textColor);
-
- proxy()->drawItemText(painter, editRect.adjusted(1, 0, -1, 0),
- visualAlignment(cb->direction, Qt::AlignLeft | Qt::AlignVCenter),
- pal, cb->state & State_Enabled, cb->currentText, QPalette::ButtonText);
- }
-
- painter->restore();
- }
- break;
-
-#endif // QT_NO_COMBOBOX
-
- case CE_DockWidgetTitle:
- painter->save();
- if (const QStyleOptionDockWidget *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(option)) {
- const QStyleOptionDockWidgetV2 *v2
- = qstyleoption_cast<const QStyleOptionDockWidgetV2*>(dwOpt);
- bool verticalTitleBar = v2 == 0 ? false : v2->verticalTitleBar;
-
- QRect rect = dwOpt->rect;
- QRect titleRect = subElementRect(SE_DockWidgetTitleBarText, option, widget).adjusted(-2, 0, -2, 0);
- QRect r = rect.adjusted(0, 0, -1, -1);
- if (verticalTitleBar)
- r.adjust(0, 0, 0, -1);
-
- if (verticalTitleBar) {
- QRect r = rect;
- QSize s = r.size();
- s.transpose();
- r.setSize(s);
-
- titleRect = QRect(r.left() + rect.bottom()
- - titleRect.bottom(),
- r.top() + titleRect.left() - rect.left(),
- titleRect.height(), titleRect.width());
-
- painter->translate(r.left(), r.top() + r.width());
- painter->rotate(-90);
- painter->translate(-r.left(), -r.top());
-
- rect = r;
- }
-
- if (!dwOpt->title.isEmpty()) {
- QString titleText
- = painter->fontMetrics().elidedText(dwOpt->title,
- Qt::ElideRight, titleRect.width());
- proxy()->drawItemText(painter,
- titleRect,
- Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic, dwOpt->palette,
- dwOpt->state & State_Enabled, titleText,
- QPalette::WindowText);
- }
- }
- painter->restore();
- break;
-
-
-
- case CE_HeaderSection:
- painter->save();
-
- // Draws the header in tables.
- if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
- Q_UNUSED(header);
- GtkWidget *gtkTreeView = d->gtkWidget("GtkTreeView");
- // Get the middle column
- GtkTreeViewColumn *column = d->gtk_tree_view_get_column((GtkTreeView*)gtkTreeView, 1);
- Q_ASSERT(column);
-
- GtkWidget *gtkTreeHeader = column->button;
- GtkStateType state = gtkPainter.gtkState(option);
- GtkShadowType shadow = GTK_SHADOW_OUT;
-
- if (option->state & State_Sunken)
- shadow = GTK_SHADOW_IN;
-
- gtkPainter.paintBox(gtkTreeHeader, "button", option->rect.adjusted(-1, 0, 0, 0), state, shadow, gtkTreeHeader->style);
- }
-
- painter->restore();
- break;
-
-#ifndef QT_NO_SIZEGRIP
-
- case CE_SizeGrip: {
- GtkWidget *gtkStatusbar = d->gtkWidget("GtkStatusbar.GtkFrame");
- QRect gripRect = option->rect.adjusted(0, 0, -gtkStatusbar->style->xthickness, -gtkStatusbar->style->ythickness);
- gtkPainter.paintResizeGrip( gtkStatusbar, "statusbar", gripRect, GTK_STATE_NORMAL,
- GTK_SHADOW_OUT, QApplication::isRightToLeft() ?
- GDK_WINDOW_EDGE_SOUTH_WEST : GDK_WINDOW_EDGE_SOUTH_EAST,
- gtkStatusbar->style);
- }
- break;
-
-#endif // QT_NO_SIZEGRIP
-
- case CE_MenuBarEmptyArea: {
- GtkWidget *gtkMenubar = d->gtkWidget("GtkMenuBar");
- GdkColor gdkBg = gtkMenubar->style->bg[GTK_STATE_NORMAL]; // Theme can depend on transparency
- painter->fillRect(option->rect, QColor(gdkBg.red>>8, gdkBg.green>>8, gdkBg.blue>>8));
- if (widget) { // See CE_MenuBarItem
- QRect menuBarRect = widget->rect();
- QPixmap pixmap(menuBarRect.size());
- pixmap.fill(Qt::transparent);
- QPainter pmPainter(&pixmap);
- QGtkPainter gtkMenuBarPainter(&pmPainter);
- GtkShadowType shadow_type;
- d->gtk_widget_style_get(gtkMenubar, "shadow-type", &shadow_type, NULL);
- gtkMenuBarPainter.paintBox( gtkMenubar, "menubar", menuBarRect,
- GTK_STATE_NORMAL, shadow_type, gtkMenubar->style);
- pmPainter.end();
- painter->drawPixmap(option->rect, pixmap, option->rect);
- }
- }
- break;
-
- case CE_MenuBarItem:
- painter->save();
-
- if (const QStyleOptionMenuItem *mbi = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
- GtkWidget *gtkMenubarItem = d->gtkWidget("GtkMenuBar.GtkMenuItem");
- GtkWidget *gtkMenubar = d->gtkWidget("GtkMenuBar");
-
- style = gtkMenubarItem->style;
-
- if (widget) {
- // Since Qt does not currently allow filling the entire background
- // we use a hack for this by making a complete menubar each time and
- // paint with the correct offset inside it. Pixmap caching should resolve
- // most of the performance penalty.
- QRect menuBarRect = widget->rect();
- QPixmap pixmap(menuBarRect.size());
- pixmap.fill(Qt::transparent);
- QPainter pmPainter(&pixmap);
- QGtkPainter menubarPainter(&pmPainter);
- GtkShadowType shadow_type;
- d->gtk_widget_style_get(gtkMenubar, "shadow-type", &shadow_type, NULL);
- GdkColor gdkBg = gtkMenubar->style->bg[GTK_STATE_NORMAL]; // Theme can depend on transparency
- painter->fillRect(option->rect, QColor(gdkBg.red>>8, gdkBg.green>>8, gdkBg.blue>>8));
- menubarPainter.paintBox(gtkMenubar, "menubar", menuBarRect,
- GTK_STATE_NORMAL, shadow_type, gtkMenubar->style);
- pmPainter.end();
- painter->drawPixmap(option->rect, pixmap, option->rect);
- }
-
- QStyleOptionMenuItem item = *mbi;
- bool act = mbi->state & State_Selected && mbi->state & State_Sunken;
- bool dis = !(mbi->state & State_Enabled);
- item.rect = mbi->rect;
- GdkColor gdkText = gtkMenubarItem->style->fg[dis ? GTK_STATE_INSENSITIVE : GTK_STATE_NORMAL];
- GdkColor gdkHText = gtkMenubarItem->style->fg[GTK_STATE_PRELIGHT];
- QColor normalTextColor = QColor(gdkText.red>>8, gdkText.green>>8, gdkText.blue>>8);
- QColor highlightedTextColor = QColor(gdkHText.red>>8, gdkHText.green>>8, gdkHText.blue>>8);
- item.palette.setBrush(QPalette::HighlightedText, highlightedTextColor);
- item.palette.setBrush(QPalette::Text, normalTextColor);
- item.palette.setBrush(QPalette::ButtonText, normalTextColor);
- QCommonStyle::drawControl(element, &item, painter, widget);
-
- if (act) {
- GtkShadowType shadowType = GTK_SHADOW_NONE;
- d->gtk_widget_style_get (gtkMenubarItem, "selected-shadow-type", &shadowType, NULL);
- gtkPainter.paintBox(gtkMenubarItem, "menuitem", option->rect.adjusted(0, 0, 0, 3),
- GTK_STATE_PRELIGHT, shadowType, gtkMenubarItem->style);
- //draw text
- QPalette::ColorRole textRole = dis ? QPalette::Text : QPalette::HighlightedText;
- uint alignment = Qt::AlignCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
-
- if (!proxy()->styleHint(SH_UnderlineShortcut, mbi, widget))
- alignment |= Qt::TextHideMnemonic;
-
- proxy()->drawItemText(painter, item.rect, alignment, item.palette, mbi->state & State_Enabled, mbi->text, textRole);
- }
- }
- painter->restore();
- break;
-
- case CE_Splitter: {
- GtkWidget *gtkWindow = d->gtkWidget("GtkWindow"); // The Murrine Engine currently assumes a widget is passed
- gtkPainter.paintHandle(gtkWindow, "splitter", option->rect, gtkPainter.gtkState(option), GTK_SHADOW_NONE,
- !(option->state & State_Horizontal) ? GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL,
- style);
- }
- break;
-
-#ifndef QT_NO_TOOLBAR
-
- case CE_ToolBar:
- if (const QStyleOptionToolBar *toolbar = qstyleoption_cast<const QStyleOptionToolBar *>(option)) {
- // Reserve the beveled appearance only for mainwindow toolbars
- if (!(widget && qobject_cast<const QMainWindow*> (widget->parentWidget())))
- break;
-
- QRect rect = option->rect;
- // There is a 1 pixel gap between toolbar lines in some styles (i.e Human)
- if (toolbar->positionWithinLine != QStyleOptionToolBar::End)
- rect.adjust(0, 0, 1, 0);
-
- GtkWidget *gtkToolbar = d->gtkWidget("GtkToolbar");
- GtkShadowType shadow_type = GTK_SHADOW_NONE;
- d->gtk_widget_style_get(gtkToolbar, "shadow-type", &shadow_type, NULL);
- gtkPainter.paintBox( gtkToolbar, "toolbar", rect,
- GTK_STATE_NORMAL, shadow_type, gtkToolbar->style);
- }
- break;
-
-#endif // QT_NO_TOOLBAR
-
- case CE_MenuItem:
- painter->save();
-
- // Draws one item in a popup menu.
- if (const QStyleOptionMenuItem *menuItem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
- const int windowsItemFrame = 2; // menu item frame width
- const int windowsItemHMargin = 3; // menu item hor text margin
- const int windowsItemVMargin = 26; // menu item ver text margin
- const int windowsRightBorder = 15; // right border on windows
- GtkWidget *gtkMenuItem = menuItem->checked ? d->gtkWidget("GtkMenu.GtkCheckMenuItem") :
- d->gtkWidget("GtkMenu.GtkMenuItem");
-
- style = gtkPainter.getStyle(gtkMenuItem);
- QColor shadow = option->palette.dark().color();
-
- if (menuItem->menuItemType == QStyleOptionMenuItem::Separator) {
- GtkWidget *gtkMenuSeparator = d->gtkWidget("GtkMenu.GtkSeparatorMenuItem");
- painter->setPen(shadow.lighter(106));
- gboolean wide_separators = 0;
- gint separator_height = 0;
- guint horizontal_padding = 3;
- QRect separatorRect = option->rect;
- if (!d->gtk_check_version(2, 10, 0)) {
- d->gtk_widget_style_get(gtkMenuSeparator,
- "wide-separators", &wide_separators,
- "separator-height", &separator_height,
- "horizontal-padding", &horizontal_padding,
- NULL);
- }
- separatorRect.setHeight(option->rect.height() - 2 * gtkMenuSeparator->style->ythickness);
- separatorRect.setWidth(option->rect.width() - 2 * (horizontal_padding + gtkMenuSeparator->style->xthickness));
- separatorRect.moveCenter(option->rect.center());
- if (wide_separators)
- gtkPainter.paintBox( gtkMenuSeparator, "hseparator",
- separatorRect, GTK_STATE_NORMAL, GTK_SHADOW_NONE, gtkMenuSeparator->style);
- else
- gtkPainter.paintHline( gtkMenuSeparator, "hseparator",
- separatorRect, GTK_STATE_NORMAL, gtkMenuSeparator->style,
- 0, option->rect.right() - 1, 1);
- painter->restore();
- break;
- }
-
- bool selected = menuItem->state & State_Selected && menuItem->state & State_Enabled;
-
- if (selected) {
- QRect rect = option->rect;
-#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);
- }
-
- bool checkable = menuItem->checkType != QStyleOptionMenuItem::NotCheckable;
- bool checked = menuItem->checked;
- bool enabled = menuItem->state & State_Enabled;
- bool ignoreCheckMark = false;
-
- gint checkSize;
- d->gtk_widget_style_get(d->gtkWidget("GtkMenu.GtkCheckMenuItem"), "indicator-size", &checkSize, NULL);
-
- int checkcol = qMax(menuItem->maxIconWidth, qMax(20, checkSize));
-
-#ifndef QT_NO_COMBOBOX
-
- if (qobject_cast<const QComboBox*>(widget))
- ignoreCheckMark = true; // Ignore the checkmarks provided by the QComboMenuDelegate
-
-#endif
- if (!ignoreCheckMark) {
- // Check
- QRect checkRect(option->rect.left() + 7, option->rect.center().y() - checkSize/2 + 1, checkSize, checkSize);
- checkRect = visualRect(menuItem->direction, menuItem->rect, checkRect);
-
- if (checkable && menuItem->icon.isNull()) {
- // Some themes such as aero-clone draw slightly outside the paint rect
- int spacing = 1; // ### Consider using gtkCheckBox : "indicator-spacing" instead
-
- if (menuItem->checkType & QStyleOptionMenuItem::Exclusive) {
- // Radio button
- GtkShadowType shadow = GTK_SHADOW_OUT;
- GtkStateType state = gtkPainter.gtkState(option);
-
- if (selected)
- state = GTK_STATE_PRELIGHT;
- if (checked)
- shadow = GTK_SHADOW_IN;
-
- gtkPainter.setClipRect(checkRect.adjusted(-spacing, -spacing, spacing, spacing));
- gtkPainter.paintOption(gtkMenuItem, checkRect.translated(-spacing, -spacing), state, shadow,
- gtkMenuItem->style, QLS("option"));
- gtkPainter.setClipRect(QRect());
-
- } else {
- // Check box
- if (menuItem->icon.isNull()) {
- GtkShadowType shadow = GTK_SHADOW_OUT;
- GtkStateType state = gtkPainter.gtkState(option);
-
- if (selected)
- state = GTK_STATE_PRELIGHT;
- if (checked)
- shadow = GTK_SHADOW_IN;
-
- gtkPainter.setClipRect(checkRect.adjusted(-spacing, -spacing, -spacing, -spacing));
- gtkPainter.paintCheckbox(gtkMenuItem, checkRect.translated(-spacing, -spacing), state, shadow,
- gtkMenuItem->style, QLS("check"));
- gtkPainter.setClipRect(QRect());
- }
- }
- }
-
- } else {
- // Ignore checkmark
- if (menuItem->icon.isNull())
- checkcol = 0;
- else
- checkcol = menuItem->maxIconWidth;
- }
-
- bool dis = !(menuItem->state & State_Enabled);
- bool act = menuItem->state & State_Selected;
- const QStyleOption *opt = option;
- const QStyleOptionMenuItem *menuitem = menuItem;
- QPainter *p = painter;
- QRect vCheckRect = visualRect(opt->direction, menuitem->rect,
- QRect(menuitem->rect.x() + 3, menuitem->rect.y(),
- checkcol, menuitem->rect.height()));
-
- if (!menuItem->icon.isNull()) {
- QIcon::Mode mode = dis ? QIcon::Disabled : QIcon::Normal;
-
- if (act && !dis)
- mode = QIcon::Active;
-
- QPixmap pixmap;
- int smallIconSize = proxy()->pixelMetric(PM_SmallIconSize, option, widget);
- QSize iconSize(smallIconSize, smallIconSize);
-
-#ifndef QT_NO_COMBOBOX
- if (const QComboBox *combo = qobject_cast<const QComboBox*>(widget))
- iconSize = combo->iconSize();
-
-#endif // QT_NO_COMBOBOX
- if (checked)
- pixmap = menuItem->icon.pixmap(iconSize, mode, QIcon::On);
- else
- pixmap = menuItem->icon.pixmap(iconSize, mode);
-
- int pixw = pixmap.width();
- int pixh = pixmap.height();
- QRect pmr(0, 0, pixw, pixh);
- pmr.moveCenter(vCheckRect.center() - QPoint(0, 1));
- painter->setPen(menuItem->palette.text().color());
- if (!ignoreCheckMark && checkable && checked) {
- QStyleOption opt = *option;
-
- if (act) {
- QColor activeColor = mergedColors(option->palette.background().color(),
- option->palette.highlight().color());
- opt.palette.setBrush(QPalette::Button, activeColor);
- }
- opt.state |= State_Sunken;
- opt.rect = vCheckRect;
- proxy()->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);
- else
- painter->setPen(textColor);
-
- int x, y, w, h;
- menuitem->rect.getRect(&x, &y, &w, &h);
- int tab = menuitem->tabWidth;
- int xm = windowsItemFrame + checkcol + windowsItemHMargin;
- int xpos = menuitem->rect.x() + xm + 1;
- QRect textRect(xpos, y + windowsItemVMargin, w - xm - windowsRightBorder - tab + 1, h - 2 * windowsItemVMargin);
- QRect vTextRect = visualRect(opt->direction, menuitem->rect, textRect);
- QString s = menuitem->text;
-
- if (!s.isEmpty()) { // Draw text
- p->save();
- int t = s.indexOf(QLatin1Char('\t'));
- int text_flags = Qt::AlignVCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
-
- if (!proxy()->styleHint(SH_UnderlineShortcut, menuitem, widget))
- text_flags |= Qt::TextHideMnemonic;
-
- // Draw shortcut right aligned
- text_flags |= Qt::AlignRight;
-
- if (t >= 0) {
- int rightMargin = 12; // Hardcode for now
- QRect vShortcutRect = visualRect(opt->direction, menuitem->rect,
- QRect(textRect.topRight(), QPoint(menuitem->rect.right() - rightMargin, textRect.bottom())));
-
- if (dis)
- p->setPen(disabledTextColor);
- p->drawText(vShortcutRect, text_flags , s.mid(t + 1));
- s = s.left(t);
- }
-
- text_flags &= ~Qt::AlignRight;
- text_flags |= Qt::AlignLeft;
- QFont font = menuitem->font;
- if (menuitem->menuItemType == QStyleOptionMenuItem::DefaultItem)
- font.setBold(true);
- p->setFont(font);
-
- if (dis)
- p->setPen(disabledTextColor);
- p->drawText(vTextRect, text_flags, s.left(t));
- p->restore();
- }
-
- // Arrow
- if (menuItem->menuItemType == QStyleOptionMenuItem::SubMenu) {// draw sub menu arrow
-
- QFontMetrics fm(menuitem->font);
- int arrow_size = fm.ascent() + fm.descent() - 2 * gtkMenuItem->style->ythickness;
- gfloat arrow_scaling = 0.8;
- int extra = 0;
- if (!d->gtk_check_version(2, 16, 0)) {
- // "arrow-scaling" is actually hardcoded and fails on hardy (see gtk+-2.12/gtkmenuitem.c)
- // though the current documentation states otherwise
- d->gtk_widget_style_get(gtkMenuItem, "arrow-scaling", &arrow_scaling, NULL);
- // in versions < 2.16 ythickness was previously subtracted from the arrow_size
- extra = 2 * gtkMenuItem->style->ythickness;
- }
-
- int horizontal_padding;
- d->gtk_widget_style_get(gtkMenuItem, "horizontal-padding", &horizontal_padding, NULL);
-
- const int dim = static_cast<int>(arrow_size * arrow_scaling) + extra;
- int xpos = menuItem->rect.left() + menuItem->rect.width() - horizontal_padding - dim;
- QRect vSubMenuRect = visualRect(option->direction, menuItem->rect,
- QRect(xpos, menuItem->rect.top() +
- menuItem->rect.height() / 2 - dim / 2, dim, dim));
- GtkStateType state = enabled ? (act ? GTK_STATE_PRELIGHT: GTK_STATE_NORMAL) : GTK_STATE_INSENSITIVE;
- GtkShadowType shadowType = (state == GTK_STATE_PRELIGHT) ? GTK_SHADOW_OUT : GTK_SHADOW_IN;
- gtkPainter.paintArrow(gtkMenuItem, "menuitem", vSubMenuRect, QApplication::isRightToLeft() ? GTK_ARROW_LEFT : GTK_ARROW_RIGHT, state,
- shadowType, FALSE, style);
- }
- }
- painter->restore();
- break;
-
- case CE_PushButton:
- if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
- GtkWidget *gtkButton = d->gtkWidget("GtkButton");
- proxy()->drawControl(CE_PushButtonBevel, btn, painter, widget);
- QStyleOptionButton subopt = *btn;
- subopt.rect = subElementRect(SE_PushButtonContents, btn, widget);
- gint interiorFocus = true;
- d->gtk_widget_style_get(gtkButton, "interior-focus", &interiorFocus, NULL);
- int xt = interiorFocus ? gtkButton->style->xthickness : 0;
- int yt = interiorFocus ? gtkButton->style->ythickness : 0;
-
- if (btn->features & QStyleOptionButton::Flat && btn->state & State_HasFocus)
- // The normal button focus rect does not work well for flat buttons in Clearlooks
- proxy()->drawPrimitive(PE_FrameFocusRect, option, painter, widget);
- else if (btn->state & State_HasFocus)
- gtkPainter.paintFocus(gtkButton, "button",
- option->rect.adjusted(xt, yt, -xt, -yt),
- btn->state & State_Sunken ? GTK_STATE_ACTIVE : GTK_STATE_NORMAL,
- gtkButton->style);
-
- proxy()->drawControl(CE_PushButtonLabel, &subopt, painter, widget);
- }
- break;
-
-#ifndef QT_NO_TABBAR
-
- case CE_TabBarTabShape:
- if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(option)) {
- GtkWidget *gtkNotebook = d->gtkWidget("GtkNotebook");
- style = gtkPainter.getStyle(gtkNotebook);
-
- QRect rect = option->rect;
- GtkShadowType shadow = GTK_SHADOW_OUT;
- GtkStateType state = GTK_STATE_ACTIVE;
- if (tab->state & State_Selected)
- state = GTK_STATE_NORMAL;
-
- bool selected = (tab->state & State_Selected);
- 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;
- }
- int topIndent = 3;
- int bottomIndent = 1;
- int tabOverlap = 1;
- painter->save();
-
- switch (tab->shape) {
- case QTabBar::RoundedNorth:
- if (!selected)
- rect.adjust(first ? 0 : -tabOverlap, topIndent, last ? 0 : tabOverlap, -bottomIndent);
- gtkPainter.paintExtention( gtkNotebook, "tab", rect,
- state, shadow, GTK_POS_BOTTOM, style);
- break;
-
- case QTabBar::RoundedSouth:
- if (!selected)
- rect.adjust(first ? 0 : -tabOverlap, 0, last ? 0 : tabOverlap, -topIndent);
- gtkPainter.paintExtention( gtkNotebook, "tab", rect.adjusted(0, 1, 0, 0),
- state, shadow, GTK_POS_TOP, style);
- break;
-
- case QTabBar::RoundedWest:
- if (!selected)
- rect.adjust(topIndent, 0, -bottomIndent, 0);
- gtkPainter.paintExtention( gtkNotebook, "tab", rect, state, shadow, GTK_POS_RIGHT, style);
- break;
-
- case QTabBar::RoundedEast:
- if (!selected)
- rect.adjust(bottomIndent, 0, -topIndent, 0);
- gtkPainter.paintExtention( gtkNotebook, "tab", rect, state, shadow, GTK_POS_LEFT, style);
- break;
-
- default:
- QCleanlooksStyle::drawControl(element, option, painter, widget);
- break;
- }
-
- painter->restore();
- }
-
- break;
-
-#endif //QT_NO_TABBAR
-
- case CE_ProgressBarGroove:
- if (const QStyleOptionProgressBar *bar = qstyleoption_cast<const QStyleOptionProgressBar *>(option)) {
- Q_UNUSED(bar);
- GtkWidget *gtkProgressBar = d->gtkWidget("GtkProgressBar");
- GtkStateType state = gtkPainter.gtkState(option);
- gtkPainter.paintBox( gtkProgressBar, "trough", option->rect, state, GTK_SHADOW_IN, gtkProgressBar->style);
- }
-
- break;
-
- case CE_ProgressBarContents:
- if (const QStyleOptionProgressBar *bar = qstyleoption_cast<const QStyleOptionProgressBar *>(option)) {
- GtkStateType state = option->state & State_Enabled ? GTK_STATE_NORMAL : GTK_STATE_INSENSITIVE;
- GtkWidget *gtkProgressBar = d->gtkWidget("GtkProgressBar");
- style = gtkProgressBar->style;
- gtkPainter.paintBox( gtkProgressBar, "trough", option->rect, state, GTK_SHADOW_IN, style);
- int xt = style->xthickness;
- int yt = style->ythickness;
- QRect rect = bar->rect.adjusted(xt, yt, -xt, -yt);
- bool vertical = false;
- bool inverted = false;
- bool indeterminate = (bar->minimum == 0 && bar->maximum == 0);
- // Get extra style options if version 2
-
- if (const QStyleOptionProgressBarV2 *bar2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option)) {
- vertical = (bar2->orientation == Qt::Vertical);
- inverted = bar2->invertedAppearance;
- }
-
- // If the orientation is vertical, we use a transform to rotate
- // the progress bar 90 degrees clockwise. This way we can use the
- // same rendering code for both orientations.
- if (vertical) {
- rect.translate(xt, -yt * 2);
- rect = QRect(rect.left(), rect.top(), rect.height(), rect.width()); // Flip width and height
- QTransform m = QTransform::fromTranslate(rect.height(), 0);
- m.rotate(90.0);
- painter->setTransform(m);
- }
-
- int maxWidth = rect.width();
- int minWidth = 4;
-
- qint64 progress = (qint64)qMax(bar->progress, bar->minimum); // Workaround for bug in QProgressBar
- double vc6_workaround = ((progress - qint64(bar->minimum)) / double(qint64(bar->maximum) - qint64(bar->minimum))) * maxWidth;
- int progressBarWidth = (int(vc6_workaround) > minWidth ) ? int(vc6_workaround) : minWidth;
- int width = indeterminate ? maxWidth : progressBarWidth;
- bool reverse = (!vertical && (bar->direction == Qt::RightToLeft)) || vertical;
-
- if (inverted)
- reverse = !reverse;
-
- int maximum = 2;
- int fakePos = 0;
- if (bar->minimum == bar->maximum)
- maximum = 0;
- if (bar->progress == bar->maximum)
- fakePos = maximum;
- else if (bar->progress > bar->minimum)
- fakePos = maximum - 1;
-
- d->gtk_progress_configure((GtkProgress*)gtkProgressBar, fakePos, 0, maximum);
-
- QRect progressBar;
-
- if (!indeterminate) {
- if (!reverse)
- progressBar.setRect(rect.left(), rect.top(), width, rect.height());
- else
- progressBar.setRect(rect.right() - width, rect.top(), width, rect.height());
-
- } else {
- Q_D(const QGtkStyle);
- int slideWidth = ((rect.width() - 4) * 2) / 3;
- int step = ((d->animateStep * slideWidth) / d->animationFps) % slideWidth;
- if ((((d->animateStep * slideWidth) / d->animationFps) % (2 * slideWidth)) >= slideWidth)
- step = slideWidth - step;
- progressBar.setRect(rect.left() + step, rect.top(), slideWidth / 2, rect.height());
- }
-
- QString key = QString(QLS("%0")).arg(fakePos);
- if (inverted) {
- key += QLatin1String("inv");
- gtkPainter.setFlipHorizontal(true);
- }
- gtkPainter.paintBox( gtkProgressBar, "bar", progressBar, GTK_STATE_SELECTED, GTK_SHADOW_OUT, style, key);
- }
-
- break;
-
- default:
- QCleanlooksStyle::drawControl(element, option, painter, widget);
- }
-}
-
-/*!
- \reimp
-*/
-QRect QGtkStyle::subControlRect(ComplexControl control, const QStyleOptionComplex *option,
- SubControl subControl, const QWidget *widget) const
-{
- Q_D(const QGtkStyle);
-
- QRect rect = QWindowsStyle::subControlRect(control, option, subControl, widget);
- if (!d->isThemeAvailable())
- return QCleanlooksStyle::subControlRect(control, option, subControl, widget);
-
- switch (control) {
- case CC_TitleBar:
- return QCleanlooksStyle::subControlRect(control, option, subControl, widget);
-
- case CC_Slider:
- if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
- // Reserve space for outside focus rect
- QStyleOptionSlider sliderCopy = *slider;
- sliderCopy.rect = option->rect.adjusted(2, 2, -2, -2);
- return QCleanlooksStyle::subControlRect(control, &sliderCopy, subControl, widget);
- }
-
- break;
-
-#ifndef QT_NO_GROUPBOX
-
- case CC_GroupBox:
- if (qstyleoption_cast<const QStyleOptionGroupBox *>(option)) {
- rect = option->rect.adjusted(0, groupBoxTopMargin, 0, -groupBoxBottomMargin);
- int topMargin = 0;
- int topHeight = 0;
- topHeight = 10;
- QRect frameRect = rect;
- frameRect.setTop(topMargin);
-
- if (subControl == SC_GroupBoxFrame)
- return rect;
- else if (subControl == SC_GroupBoxContents) {
- int margin = 0;
- int leftMarginExtension = 8;
- return frameRect.adjusted(leftMarginExtension + margin, margin + topHeight + groupBoxTitleMargin, -margin, -margin);
- }
-
- if (const QGroupBox *groupBoxWidget = qobject_cast<const QGroupBox *>(widget)) {
- //Prepare metrics for a bold font
- QFont font = widget->font();
- font.setBold(true);
- QFontMetrics fontMetrics(font);
- QSize textRect = fontMetrics.boundingRect(groupBoxWidget->title()).size() + QSize(4, 4);
- int indicatorWidth = proxy()->pixelMetric(PM_IndicatorWidth, option, widget);
- int indicatorHeight = proxy()->pixelMetric(PM_IndicatorHeight, option, widget);
-
- if (subControl == SC_GroupBoxCheckBox) {
- rect.setWidth(indicatorWidth);
- rect.setHeight(indicatorHeight);
- rect.moveTop((textRect.height() - indicatorHeight) / 2);
-
- } else if (subControl == SC_GroupBoxLabel) {
- if (groupBoxWidget->isCheckable())
- rect.adjust(indicatorWidth + 4, 0, 0, 0);
- rect.setSize(textRect);
- }
- rect = visualRect(option->direction, option->rect, rect);
- }
- }
-
- return rect;
-
-#endif
-#ifndef QT_NO_SPINBOX
-
- case CC_SpinBox:
- if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
- GtkWidget *gtkSpinButton = d->gtkWidget("GtkSpinButton");
- int center = spinbox->rect.height() / 2;
- int xt = spinbox->frame ? gtkSpinButton->style->xthickness : 0;
- int yt = spinbox->frame ? gtkSpinButton->style->ythickness : 0;
- int y = yt;
-
- QSize bs;
- bs.setHeight(qMax(8, spinbox->rect.height()/2 - y));
- bs.setWidth(d->getSpinboxArrowSize());
- int x, lx, rx;
- x = spinbox->rect.width() - y - bs.width() + 2;
- lx = xt;
- rx = x - xt;
-
- switch (subControl) {
-
- case SC_SpinBoxUp:
- if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons)
- return QRect();
- rect = QRect(x, xt, bs.width(), center - yt);
- break;
-
- case SC_SpinBoxDown:
- if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons)
- return QRect();
- rect = QRect(x, center, bs.width(), spinbox->rect.bottom() - center - yt + 1);
- break;
-
- case SC_SpinBoxEditField:
- if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons)
- rect = QRect(lx, yt, spinbox->rect.width() - 2*xt, spinbox->rect.height() - 2*yt);
- else
- rect = QRect(lx, yt, rx - qMax(xt - 1, 0), spinbox->rect.height() - 2*yt);
- break;
-
- case SC_SpinBoxFrame:
- rect = spinbox->rect;
-
- default:
- break;
- }
-
- rect = visualRect(spinbox->direction, spinbox->rect, rect);
- }
-
- break;
-
-#endif // Qt_NO_SPINBOX
-#ifndef QT_NO_COMBOBOX
-
- case CC_ComboBox:
- if (const QStyleOptionComboBox *box = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
- // We employ the gtk widget to position arrows and separators for us
- GtkWidget *gtkCombo = box->editable ? d->gtkWidget("GtkComboBoxEntry")
- : d->gtkWidget("GtkComboBox");
- d->gtk_widget_set_direction(gtkCombo, (option->direction == Qt::RightToLeft) ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR);
- GtkAllocation geometry = {0, 0, qMax(0, option->rect.width()), qMax(0, option->rect.height())};
- d->gtk_widget_size_allocate(gtkCombo, &geometry);
- int appears_as_list = !proxy()->styleHint(QStyle::SH_ComboBox_Popup, option, widget);
- QHashableLatin1Literal arrowPath("GtkComboBoxEntry.GtkToggleButton");
- if (!box->editable) {
- if (appears_as_list)
- arrowPath = "GtkComboBox.GtkToggleButton";
- else
- arrowPath = "GtkComboBox.GtkToggleButton.GtkHBox.GtkArrow";
- }
-
- GtkWidget *arrowWidget = d->gtkWidget(arrowPath);
- if (!arrowWidget)
- return QCleanlooksStyle::subControlRect(control, option, subControl, widget);
-
- QRect buttonRect(option->rect.left() + arrowWidget->allocation.x,
- option->rect.top() + arrowWidget->allocation.y,
- arrowWidget->allocation.width, arrowWidget->allocation.height);
-
- switch (subControl) {
-
- case SC_ComboBoxArrow: // Note: this indicates the arrowbutton for editable combos
- rect = buttonRect;
- break;
-
- case SC_ComboBoxEditField: {
- rect = visualRect(option->direction, option->rect, rect);
- int xMargin = box->editable ? 1 : 4, yMargin = 2;
- rect.setRect(option->rect.left() + gtkCombo->style->xthickness + xMargin,
- option->rect.top() + gtkCombo->style->ythickness + yMargin,
- option->rect.width() - buttonRect.width() - 2*(gtkCombo->style->xthickness + xMargin),
- option->rect.height() - 2*(gtkCombo->style->ythickness + yMargin));
- rect = visualRect(option->direction, option->rect, rect);
- break;
- }
-
- default:
- break;
- }
- }
-
- break;
-
-#endif // QT_NO_COMBOBOX
-
- default:
- break;
- }
-
- return rect;
-}
-
-/*!
- \reimp
-*/
-QSize QGtkStyle::sizeFromContents(ContentsType type, const QStyleOption *option,
- const QSize &size, const QWidget *widget) const
-{
- Q_D(const QGtkStyle);
-
- QSize newSize = QCleanlooksStyle::sizeFromContents(type, option, size, widget);
- if (!d->isThemeAvailable())
- return newSize;
-
- switch (type) {
-
- case CT_ToolButton:
- if (const QStyleOptionToolButton *toolbutton = qstyleoption_cast<const QStyleOptionToolButton *>(option)) {
- GtkWidget *gtkButton = d->gtkWidget("GtkToolButton.GtkButton");
- newSize = size + QSize(2 * gtkButton->style->xthickness, 2 + 2 * gtkButton->style->ythickness);
- if (widget && qobject_cast<QToolBar *>(widget->parentWidget())) {
- QSize minSize(0, 25);
- if (toolbutton->toolButtonStyle != Qt::ToolButtonTextOnly)
- minSize = toolbutton->iconSize + QSize(12, 12);
- newSize = newSize.expandedTo(minSize);
- }
-
- if (toolbutton->features & QStyleOptionToolButton::HasMenu)
- newSize += QSize(6, 0);
- }
- break;
- case CT_MenuItem:
- if (const QStyleOptionMenuItem *menuItem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
- int textMargin = 8;
-
- if (menuItem->menuItemType == QStyleOptionMenuItem::Separator) {
- GtkWidget *gtkMenuSeparator = d->gtkWidget("GtkMenu.GtkSeparatorMenuItem");
- GtkRequisition sizeReq = {0, 0};
- d->gtk_widget_size_request(gtkMenuSeparator, &sizeReq);
- newSize = QSize(size.width(), sizeReq.height);
- break;
- }
-
- GtkWidget *gtkMenuItem = d->gtkWidget("GtkMenu.GtkCheckMenuItem");
- GtkStyle* style = gtkMenuItem->style;
-
- // Note we get the perfect height for the default font since we
- // set a fake text label on the gtkMenuItem
- // But if custom fonts are used on the widget we need a minimum size
- GtkRequisition sizeReq = {0, 0};
- d->gtk_widget_size_request(gtkMenuItem, &sizeReq);
- newSize.setHeight(qMax(newSize.height() - 4, sizeReq.height));
- newSize += QSize(textMargin + style->xthickness - 1, 0);
-
- // Cleanlooks assumes a check column of 20 pixels so we need to
- // expand it a bit
- gint checkSize;
- d->gtk_widget_style_get(gtkMenuItem, "indicator-size", &checkSize, NULL);
- newSize.setWidth(newSize.width() + qMax(0, checkSize - 20));
- }
-
- break;
-
- case CT_SpinBox:
- // QSpinBox does some nasty things that depends on CT_LineEdit
- newSize = size + QSize(0, -d->gtkWidget("GtkSpinButton")->style->ythickness * 2);
- break;
-
- case CT_PushButton:
- if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
- GtkWidget *gtkButton = d->gtkWidget("GtkButton");
- gint focusPadding, focusWidth;
- d->gtk_widget_style_get(gtkButton, "focus-padding", &focusPadding, NULL);
- d->gtk_widget_style_get(gtkButton, "focus-line-width", &focusWidth, NULL);
- newSize = size;
- newSize += QSize(2*gtkButton->style->xthickness + 4, 2*gtkButton->style->ythickness);
- newSize += QSize(2*(focusWidth + focusPadding + 2), 2*(focusWidth + focusPadding));
-
- GtkWidget *gtkButtonBox = d->gtkWidget("GtkHButtonBox");
- gint minWidth = 85, minHeight = 0;
- d->gtk_widget_style_get(gtkButtonBox, "child-min-width", &minWidth,
- "child-min-height", &minHeight, NULL);
- if (!btn->text.isEmpty() && newSize.width() < minWidth)
- newSize.setWidth(minWidth);
- if (newSize.height() < minHeight)
- newSize.setHeight(minHeight);
- }
-
- break;
-
- case CT_Slider: {
- GtkWidget *gtkSlider = d->gtkWidget("GtkHScale");
- newSize = size + QSize(2*gtkSlider->style->xthickness, 2*gtkSlider->style->ythickness);
- }
- break;
-
- case CT_LineEdit: {
- GtkWidget *gtkEntry = d->gtkWidget("GtkEntry");
- newSize = size + QSize(2*gtkEntry->style->xthickness, 2 + 2*gtkEntry->style->ythickness);
- }
- break;
-
- case CT_ItemViewItem:
- newSize += QSize(0, 2);
- break;
-
- case CT_ComboBox:
- if (const QStyleOptionComboBox *combo = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
- GtkWidget *gtkCombo = d->gtkWidget("GtkComboBox");
- QRect arrowButtonRect = proxy()->subControlRect(CC_ComboBox, combo, SC_ComboBoxArrow, widget);
- newSize = size + QSize(12 + arrowButtonRect.width() + 2*gtkCombo->style->xthickness, 4 + 2*gtkCombo->style->ythickness);
-
- if (!(widget && qobject_cast<QToolBar *>(widget->parentWidget())))
- newSize += QSize(0, 2);
- }
- break;
-
- case CT_GroupBox:
- newSize += QSize(4, groupBoxBottomMargin + groupBoxTopMargin + groupBoxTitleMargin); // Add some space below the groupbox
- break;
-
- case CT_TabBarTab:
- if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(option)) {
- if (!tab->icon.isNull())
- newSize += QSize(6, 0);
- }
- newSize += QSize(1, 1);
- break;
-
- default:
- break;
- }
-
- return newSize;
-}
-
-
-/*! \reimp */
-QPixmap QGtkStyle::standardPixmap(StandardPixmap sp, const QStyleOption *option,
- const QWidget *widget) const
-{
- Q_D(const QGtkStyle);
-
- if (!d->isThemeAvailable())
- return QCleanlooksStyle::standardPixmap(sp, option, widget);
-
- QPixmap pixmap;
- switch (sp) {
-
- case SP_TitleBarNormalButton: {
- QImage restoreButton((const char **)dock_widget_restore_xpm);
- QColor alphaCorner = restoreButton.color(2);
- alphaCorner.setAlpha(80);
- restoreButton.setColor(2, alphaCorner.rgba());
- alphaCorner.setAlpha(180);
- restoreButton.setColor(4, alphaCorner.rgba());
- return QPixmap::fromImage(restoreButton);
- }
- break;
-
- case SP_TitleBarCloseButton: // Fall through
- case SP_DockWidgetCloseButton: {
-
- QImage closeButton((const char **)dock_widget_close_xpm);
- QColor alphaCorner = closeButton.color(2);
- alphaCorner.setAlpha(80);
- closeButton.setColor(2, alphaCorner.rgba());
- return QPixmap::fromImage(closeButton);
- }
- break;
-
- case SP_DialogDiscardButton:
- return QGtkPainter::getIcon(GTK_STOCK_DELETE);
- case SP_DialogOkButton:
- return QGtkPainter::getIcon(GTK_STOCK_OK);
- case SP_DialogCancelButton:
- return QGtkPainter::getIcon(GTK_STOCK_CANCEL);
- case SP_DialogYesButton:
- return QGtkPainter::getIcon(GTK_STOCK_YES);
- case SP_DialogNoButton:
- return QGtkPainter::getIcon(GTK_STOCK_NO);
- case SP_DialogOpenButton:
- return QGtkPainter::getIcon(GTK_STOCK_OPEN);
- case SP_DialogCloseButton:
- return QGtkPainter::getIcon(GTK_STOCK_CLOSE);
- case SP_DialogApplyButton:
- return QGtkPainter::getIcon(GTK_STOCK_APPLY);
- case SP_DialogSaveButton:
- return QGtkPainter::getIcon(GTK_STOCK_SAVE);
- case SP_MessageBoxWarning:
- return QGtkPainter::getIcon(GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_DIALOG);
- case SP_MessageBoxQuestion:
- return QGtkPainter::getIcon(GTK_STOCK_DIALOG_QUESTION, GTK_ICON_SIZE_DIALOG);
- case SP_MessageBoxInformation:
- return QGtkPainter::getIcon(GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_DIALOG);
- case SP_MessageBoxCritical:
- return QGtkPainter::getIcon(GTK_STOCK_DIALOG_ERROR, GTK_ICON_SIZE_DIALOG);
- default:
- return QCleanlooksStyle::standardPixmap(sp, option, widget);
- }
- return pixmap;
-}
-
-/*!
- \internal
-*/
-QIcon QGtkStyle::standardIconImplementation(StandardPixmap standardIcon,
- const QStyleOption *option,
- const QWidget *widget) const
-{
- Q_D(const QGtkStyle);
-
- if (!d->isThemeAvailable())
- return QCleanlooksStyle::standardIconImplementation(standardIcon, option, widget);
- switch (standardIcon) {
- case SP_DialogDiscardButton:
- return QGtkPainter::getIcon(GTK_STOCK_DELETE);
- case SP_DialogOkButton:
- return QGtkPainter::getIcon(GTK_STOCK_OK);
- case SP_DialogCancelButton:
- return QGtkPainter::getIcon(GTK_STOCK_CANCEL);
- case SP_DialogYesButton:
- return QGtkPainter::getIcon(GTK_STOCK_YES);
- case SP_DialogNoButton:
- return QGtkPainter::getIcon(GTK_STOCK_NO);
- case SP_DialogOpenButton:
- return QGtkPainter::getIcon(GTK_STOCK_OPEN);
- case SP_DialogCloseButton:
- return QGtkPainter::getIcon(GTK_STOCK_CLOSE);
- case SP_DialogApplyButton:
- return QGtkPainter::getIcon(GTK_STOCK_APPLY);
- case SP_DialogSaveButton:
- return QGtkPainter::getIcon(GTK_STOCK_SAVE);
- case SP_MessageBoxWarning:
- return QGtkPainter::getIcon(GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_DIALOG);
- case SP_MessageBoxQuestion:
- return QGtkPainter::getIcon(GTK_STOCK_DIALOG_QUESTION, GTK_ICON_SIZE_DIALOG);
- case SP_MessageBoxInformation:
- return QGtkPainter::getIcon(GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_DIALOG);
- case SP_MessageBoxCritical:
- return QGtkPainter::getIcon(GTK_STOCK_DIALOG_ERROR, GTK_ICON_SIZE_DIALOG);
- default:
- return QCleanlooksStyle::standardIconImplementation(standardIcon, option, widget);
- }
-}
-
-
-/*! \reimp */
-QRect QGtkStyle::subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const
-{
- Q_D(const QGtkStyle);
-
- QRect r = QCleanlooksStyle::subElementRect(element, option, widget);
- if (!d->isThemeAvailable())
- return r;
-
- switch (element) {
- case SE_ProgressBarLabel:
- case SE_ProgressBarContents:
- case SE_ProgressBarGroove:
- return option->rect;
- case SE_PushButtonContents:
- if (!d->gtk_check_version(2, 10, 0)) {
- GtkWidget *gtkButton = d->gtkWidget("GtkButton");
- GtkBorder *border = 0;
- d->gtk_widget_style_get(gtkButton, "inner-border", &border, NULL);
- if (border) {
- r = option->rect.adjusted(border->left, border->top, -border->right, -border->bottom);
- d->gtk_border_free(border);
- } else {
- r = option->rect.adjusted(1, 1, -1, -1);
- }
- r = visualRect(option->direction, option->rect, r);
- }
- break;
- default:
- break;
- }
-
- return r;
-}
-
-/*!
- \reimp
-*/
-QRect QGtkStyle::itemPixmapRect(const QRect &r, int flags, const QPixmap &pixmap) const
-{
- return QCleanlooksStyle::itemPixmapRect(r, flags, pixmap);
-}
-
-/*!
- \reimp
-*/
-void QGtkStyle::drawItemPixmap(QPainter *painter, const QRect &rect,
- int alignment, const QPixmap &pixmap) const
-{
- QCleanlooksStyle::drawItemPixmap(painter, rect, alignment, pixmap);
-}
-
-/*!
- \reimp
-*/
-QStyle::SubControl QGtkStyle::hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt,
- const QPoint &pt, const QWidget *w) const
-{
- return QCleanlooksStyle::hitTestComplexControl(cc, opt, pt, w);
-}
-
-/*!
- \reimp
-*/
-QPixmap QGtkStyle::generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap,
- const QStyleOption *opt) const
-{
- return QCleanlooksStyle::generatedIconPixmap(iconMode, pixmap, opt);
-}
-
-/*!
- \reimp
-*/
-void QGtkStyle::drawItemText(QPainter *painter, const QRect &rect, int alignment, const QPalette &pal,
- bool enabled, const QString& text, QPalette::ColorRole textRole) const
-{
- return QCleanlooksStyle::drawItemText(painter, rect, alignment, pal, enabled, text, textRole);
-}
-
-QT_END_NAMESPACE
-
-#endif //!defined(QT_NO_STYLE_QGTK)
diff --git a/src/gui/styles/qgtkstyle.h b/src/gui/styles/qgtkstyle.h
deleted file mode 100644
index 355c1b473a..0000000000
--- a/src/gui/styles/qgtkstyle.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGTKSTYLE_H
-#define QGTKSTYLE_H
-
-#include <QtGui/QCleanlooksStyle>
-#include <QtGui/QPalette>
-#include <QtGui/QFont>
-#include <QtGui/QFileDialog>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#if !defined(QT_NO_STYLE_GTK)
-
-class QPainterPath;
-class QGtkStylePrivate;
-
-class Q_GUI_EXPORT QGtkStyle : public QCleanlooksStyle
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QGtkStyle)
-
-public:
- QGtkStyle();
- QGtkStyle(QGtkStylePrivate &dd);
-
- ~QGtkStyle();
-
- QPalette standardPalette() const;
-
- void drawPrimitive(PrimitiveElement element, const QStyleOption *option,
- QPainter *painter, const QWidget *widget) const;
- void drawControl(ControlElement control, const QStyleOption *option,
- QPainter *painter, const QWidget *widget) const;
- void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option,
- QPainter *painter, const QWidget *widget) const;
- void drawItemPixmap(QPainter *painter, const QRect &rect, int alignment,
- const QPixmap &pixmap) const;
- void drawItemText(QPainter *painter, const QRect &rect, int alignment, const QPalette &pal,
- bool enabled, const QString& text, QPalette::ColorRole textRole) const;
-
- int pixelMetric(PixelMetric metric, const QStyleOption *option = 0,
- const QWidget *widget = 0) const;
- int styleHint(StyleHint hint, const QStyleOption *option,
- const QWidget *widget, QStyleHintReturn *returnData) const;
-
- QStyle::SubControl hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt,
- const QPoint &pt, const QWidget *w) const;
-
- QRect subControlRect(ComplexControl control, const QStyleOptionComplex *option,
- SubControl subControl, const QWidget *widget) const;
- QRect subElementRect(SubElement sr, const QStyleOption *opt, const QWidget *w) const;
- QRect itemPixmapRect(const QRect &r, int flags, const QPixmap &pixmap) const;
-
-
- QSize sizeFromContents(ContentsType type, const QStyleOption *option,
- const QSize &size, const QWidget *widget) const;
- QPixmap standardPixmap(StandardPixmap sp, const QStyleOption *option,
- const QWidget *widget) const;
- QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap,
- const QStyleOption *opt) const;
-
- void polish(QWidget *widget);
- void polish(QApplication *app);
- void polish(QPalette &palette);
-
- void unpolish(QWidget *widget);
- void unpolish(QApplication *app);
-
- static bool getGConfBool(const QString &key, bool fallback = 0);
- static QString getGConfString(const QString &key, const QString &fallback = QString());
-
-
-protected Q_SLOTS:
- QIcon standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *option,
- const QWidget *widget = 0) const;
-};
-
-#endif //!defined(QT_NO_STYLE_QGTK)
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif //QGTKSTYLE_H
diff --git a/src/gui/styles/qgtkstyle_p.cpp b/src/gui/styles/qgtkstyle_p.cpp
deleted file mode 100644
index ae2b918095..0000000000
--- a/src/gui/styles/qgtkstyle_p.cpp
+++ /dev/null
@@ -1,1146 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qgtkstyle_p.h"
-
-// This file is responsible for resolving all GTK functions we use
-// dynamically. This is done to avoid link-time dependancy on GTK
-// as well as crashes occurring due to usage of the GTK_QT engines
-//
-// Additionally we create a map of common GTK widgets that we can pass
-// to the GTK theme engine as many engines resort to querying the
-// actual widget pointers for details that are not covered by the
-// state flags
-
-#include <QtCore/qglobal.h>
-#if !defined(QT_NO_STYLE_GTK)
-
-#include <QtCore/QEvent>
-#include <QtCore/QFile>
-#include <QtCore/QStringList>
-#include <QtCore/QTextStream>
-#include <QtCore/QHash>
-#include <QtCore/QUrl>
-#include <QtCore/QLibrary>
-#include <QtCore/QDebug>
-
-#include <private/qapplication_p.h>
-#include <private/qiconloader_p.h>
-
-#include <QtGui/QMenu>
-#include <QtGui/QStyle>
-#include <QtGui/QApplication>
-#include <QtGui/QPixmapCache>
-#include <QtGui/QStatusBar>
-#include <QtGui/QMenuBar>
-#include <QtGui/QToolBar>
-#include <QtGui/QToolButton>
-#include <QtGui/QX11Info>
-
-#include <private/qt_x11_p.h>
-
-QT_BEGIN_NAMESPACE
-
-static bool displayDepth = -1;
-Q_GLOBAL_STATIC(QGtkStyleUpdateScheduler, styleScheduler)
-
-Ptr_gtk_container_forall QGtkStylePrivate::gtk_container_forall = 0;
-Ptr_gtk_init QGtkStylePrivate::gtk_init = 0;
-Ptr_gtk_style_attach QGtkStylePrivate::gtk_style_attach = 0;
-Ptr_gtk_window_new QGtkStylePrivate::gtk_window_new = 0;
-Ptr_gtk_widget_destroy QGtkStylePrivate::gtk_widget_destroy = 0;
-Ptr_gtk_widget_realize QGtkStylePrivate::gtk_widget_realize = 0;
-Ptr_gtk_widget_set_default_direction QGtkStylePrivate::gtk_widget_set_default_direction = 0;
-Ptr_gtk_widget_modify_color QGtkStylePrivate::gtk_widget_modify_fg = 0;
-Ptr_gtk_widget_modify_color QGtkStylePrivate::gtk_widget_modify_bg = 0;
-Ptr_gtk_arrow_new QGtkStylePrivate::gtk_arrow_new = 0;
-Ptr_gtk_menu_item_new_with_label QGtkStylePrivate::gtk_menu_item_new_with_label = 0;
-Ptr_gtk_check_menu_item_new_with_label QGtkStylePrivate::gtk_check_menu_item_new_with_label = 0;
-Ptr_gtk_menu_bar_new QGtkStylePrivate::gtk_menu_bar_new = 0;
-Ptr_gtk_menu_new QGtkStylePrivate::gtk_menu_new = 0;
-Ptr_gtk_button_new QGtkStylePrivate::gtk_button_new = 0;
-Ptr_gtk_tool_button_new QGtkStylePrivate::gtk_tool_button_new = 0;
-Ptr_gtk_hbutton_box_new QGtkStylePrivate::gtk_hbutton_box_new = 0;
-Ptr_gtk_check_button_new QGtkStylePrivate::gtk_check_button_new = 0;
-Ptr_gtk_radio_button_new QGtkStylePrivate::gtk_radio_button_new = 0;
-Ptr_gtk_spin_button_new QGtkStylePrivate::gtk_spin_button_new = 0;
-Ptr_gtk_frame_new QGtkStylePrivate::gtk_frame_new = 0;
-Ptr_gtk_expander_new QGtkStylePrivate::gtk_expander_new = 0;
-Ptr_gtk_statusbar_new QGtkStylePrivate::gtk_statusbar_new = 0;
-Ptr_gtk_entry_new QGtkStylePrivate::gtk_entry_new = 0;
-Ptr_gtk_hscale_new QGtkStylePrivate::gtk_hscale_new = 0;
-Ptr_gtk_vscale_new QGtkStylePrivate::gtk_vscale_new = 0;
-Ptr_gtk_hscrollbar_new QGtkStylePrivate::gtk_hscrollbar_new = 0;
-Ptr_gtk_vscrollbar_new QGtkStylePrivate::gtk_vscrollbar_new = 0;
-Ptr_gtk_scrolled_window_new QGtkStylePrivate::gtk_scrolled_window_new = 0;
-Ptr_gtk_notebook_new QGtkStylePrivate::gtk_notebook_new = 0;
-Ptr_gtk_toolbar_new QGtkStylePrivate::gtk_toolbar_new = 0;
-Ptr_gtk_toolbar_insert QGtkStylePrivate::gtk_toolbar_insert = 0;
-Ptr_gtk_separator_tool_item_new QGtkStylePrivate::gtk_separator_tool_item_new = 0;
-Ptr_gtk_tree_view_new QGtkStylePrivate::gtk_tree_view_new = 0;
-Ptr_gtk_combo_box_new QGtkStylePrivate::gtk_combo_box_new = 0;
-Ptr_gtk_combo_box_entry_new QGtkStylePrivate::gtk_combo_box_entry_new = 0;
-Ptr_gtk_progress_bar_new QGtkStylePrivate::gtk_progress_bar_new = 0;
-Ptr_gtk_container_add QGtkStylePrivate::gtk_container_add = 0;
-Ptr_gtk_menu_shell_append QGtkStylePrivate::gtk_menu_shell_append = 0;
-Ptr_gtk_progress_configure QGtkStylePrivate::gtk_progress_configure = 0;
-Ptr_gtk_range_get_adjustment QGtkStylePrivate::gtk_range_get_adjustment = 0;
-Ptr_gtk_range_set_adjustment QGtkStylePrivate::gtk_range_set_adjustment = 0;
-Ptr_gtk_range_set_inverted QGtkStylePrivate::gtk_range_set_inverted = 0;
-Ptr_gtk_icon_factory_lookup_default QGtkStylePrivate::gtk_icon_factory_lookup_default = 0;
-Ptr_gtk_icon_theme_get_default QGtkStylePrivate::gtk_icon_theme_get_default = 0;
-Ptr_gtk_widget_style_get QGtkStylePrivate::gtk_widget_style_get = 0;
-Ptr_gtk_icon_set_render_icon QGtkStylePrivate::gtk_icon_set_render_icon = 0;
-Ptr_gtk_fixed_new QGtkStylePrivate::gtk_fixed_new = 0;
-Ptr_gtk_tree_view_column_new QGtkStylePrivate::gtk_tree_view_column_new = 0;
-Ptr_gtk_tree_view_get_column QGtkStylePrivate::gtk_tree_view_get_column = 0;
-Ptr_gtk_tree_view_append_column QGtkStylePrivate::gtk_tree_view_append_column = 0;
-Ptr_gtk_paint_check QGtkStylePrivate::gtk_paint_check = 0;
-Ptr_gtk_paint_box QGtkStylePrivate::gtk_paint_box = 0;
-Ptr_gtk_paint_box_gap QGtkStylePrivate::gtk_paint_box_gap = 0;
-Ptr_gtk_paint_flat_box QGtkStylePrivate::gtk_paint_flat_box = 0;
-Ptr_gtk_paint_option QGtkStylePrivate::gtk_paint_option = 0;
-Ptr_gtk_paint_extension QGtkStylePrivate::gtk_paint_extension = 0;
-Ptr_gtk_paint_slider QGtkStylePrivate::gtk_paint_slider = 0;
-Ptr_gtk_paint_shadow QGtkStylePrivate::gtk_paint_shadow = 0;
-Ptr_gtk_paint_resize_grip QGtkStylePrivate::gtk_paint_resize_grip = 0;
-Ptr_gtk_paint_focus QGtkStylePrivate::gtk_paint_focus = 0;
-Ptr_gtk_paint_arrow QGtkStylePrivate::gtk_paint_arrow = 0;
-Ptr_gtk_paint_handle QGtkStylePrivate::gtk_paint_handle = 0;
-Ptr_gtk_paint_expander QGtkStylePrivate::gtk_paint_expander = 0;
-Ptr_gtk_adjustment_configure QGtkStylePrivate::gtk_adjustment_configure = 0;
-Ptr_gtk_adjustment_new QGtkStylePrivate::gtk_adjustment_new = 0;
-Ptr_gtk_paint_hline QGtkStylePrivate::gtk_paint_hline = 0;
-Ptr_gtk_paint_vline QGtkStylePrivate::gtk_paint_vline = 0;
-Ptr_gtk_menu_item_set_submenu QGtkStylePrivate::gtk_menu_item_set_submenu = 0;
-Ptr_gtk_settings_get_default QGtkStylePrivate::gtk_settings_get_default = 0;
-Ptr_gtk_separator_menu_item_new QGtkStylePrivate::gtk_separator_menu_item_new = 0;
-Ptr_gtk_widget_size_allocate QGtkStylePrivate::gtk_widget_size_allocate = 0;
-Ptr_gtk_widget_size_request QGtkStylePrivate::gtk_widget_size_request = 0;
-Ptr_gtk_widget_set_direction QGtkStylePrivate::gtk_widget_set_direction = 0;
-Ptr_gtk_widget_path QGtkStylePrivate::gtk_widget_path = 0;
-Ptr_gtk_container_get_type QGtkStylePrivate::gtk_container_get_type = 0;
-Ptr_gtk_window_get_type QGtkStylePrivate::gtk_window_get_type = 0;
-Ptr_gtk_widget_get_type QGtkStylePrivate::gtk_widget_get_type = 0;
-Ptr_gtk_rc_get_style_by_paths QGtkStylePrivate::gtk_rc_get_style_by_paths = 0;
-Ptr_gtk_check_version QGtkStylePrivate::gtk_check_version = 0;
-Ptr_gtk_border_free QGtkStylePrivate::gtk_border_free = 0;
-Ptr_pango_font_description_get_size QGtkStylePrivate::pango_font_description_get_size = 0;
-Ptr_pango_font_description_get_weight QGtkStylePrivate::pango_font_description_get_weight = 0;
-Ptr_pango_font_description_get_family QGtkStylePrivate::pango_font_description_get_family = 0;
-Ptr_pango_font_description_get_style QGtkStylePrivate::pango_font_description_get_style = 0;
-
-Ptr_gtk_file_filter_new QGtkStylePrivate::gtk_file_filter_new = 0;
-Ptr_gtk_file_filter_set_name QGtkStylePrivate::gtk_file_filter_set_name = 0;
-Ptr_gtk_file_filter_add_pattern QGtkStylePrivate::gtk_file_filter_add_pattern = 0;
-Ptr_gtk_file_chooser_add_filter QGtkStylePrivate::gtk_file_chooser_add_filter = 0;
-Ptr_gtk_file_chooser_set_filter QGtkStylePrivate::gtk_file_chooser_set_filter = 0;
-Ptr_gtk_file_chooser_get_filter QGtkStylePrivate::gtk_file_chooser_get_filter = 0;
-Ptr_gtk_file_chooser_dialog_new QGtkStylePrivate::gtk_file_chooser_dialog_new = 0;
-Ptr_gtk_file_chooser_set_current_folder QGtkStylePrivate::gtk_file_chooser_set_current_folder = 0;
-Ptr_gtk_file_chooser_get_filename QGtkStylePrivate::gtk_file_chooser_get_filename = 0;
-Ptr_gtk_file_chooser_get_filenames QGtkStylePrivate::gtk_file_chooser_get_filenames = 0;
-Ptr_gtk_file_chooser_set_current_name QGtkStylePrivate::gtk_file_chooser_set_current_name = 0;
-Ptr_gtk_dialog_run QGtkStylePrivate::gtk_dialog_run = 0;
-Ptr_gtk_file_chooser_set_filename QGtkStylePrivate::gtk_file_chooser_set_filename = 0;
-
-Ptr_gdk_pixbuf_get_pixels QGtkStylePrivate::gdk_pixbuf_get_pixels = 0;
-Ptr_gdk_pixbuf_get_width QGtkStylePrivate::gdk_pixbuf_get_width = 0;
-Ptr_gdk_pixbuf_get_height QGtkStylePrivate::gdk_pixbuf_get_height = 0;
-Ptr_gdk_pixmap_new QGtkStylePrivate::gdk_pixmap_new = 0;
-Ptr_gdk_pixbuf_new QGtkStylePrivate::gdk_pixbuf_new = 0;
-Ptr_gdk_pixbuf_get_from_drawable QGtkStylePrivate::gdk_pixbuf_get_from_drawable = 0;
-Ptr_gdk_draw_rectangle QGtkStylePrivate::gdk_draw_rectangle = 0;
-Ptr_gdk_pixbuf_unref QGtkStylePrivate::gdk_pixbuf_unref = 0;
-Ptr_gdk_drawable_unref QGtkStylePrivate::gdk_drawable_unref = 0;
-Ptr_gdk_drawable_get_depth QGtkStylePrivate::gdk_drawable_get_depth = 0;
-Ptr_gdk_color_free QGtkStylePrivate::gdk_color_free = 0;
-Ptr_gdk_x11_window_set_user_time QGtkStylePrivate::gdk_x11_window_set_user_time = 0;
-Ptr_gdk_x11_drawable_get_xid QGtkStylePrivate::gdk_x11_drawable_get_xid = 0;
-Ptr_gdk_x11_drawable_get_xdisplay QGtkStylePrivate::gdk_x11_drawable_get_xdisplay = 0;
-
-Ptr_gconf_client_get_default QGtkStylePrivate::gconf_client_get_default = 0;
-Ptr_gconf_client_get_string QGtkStylePrivate::gconf_client_get_string = 0;
-Ptr_gconf_client_get_bool QGtkStylePrivate::gconf_client_get_bool = 0;
-
-Ptr_gnome_icon_lookup_sync QGtkStylePrivate::gnome_icon_lookup_sync = 0;
-Ptr_gnome_vfs_init QGtkStylePrivate::gnome_vfs_init = 0;
-
-typedef int (*x11ErrorHandler)(Display*, XErrorEvent*);
-
-QT_END_NAMESPACE
-
-Q_DECLARE_METATYPE(QGtkStylePrivate*);
-
-QT_BEGIN_NAMESPACE
-
-static void gtkStyleSetCallback(GtkWidget*)
-{
- qRegisterMetaType<QGtkStylePrivate *>();
-
- // 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);
-}
-
-static void update_toolbar_style(GtkWidget *gtkToolBar, GParamSpec *, gpointer)
-{
- GtkToolbarStyle toolbar_style = GTK_TOOLBAR_ICONS;
- g_object_get(gtkToolBar, "toolbar-style", &toolbar_style, NULL);
- QWidgetList widgets = QApplication::allWidgets();
- for (int i = 0; i < widgets.size(); ++i) {
- QWidget *widget = widgets.at(i);
- if (qobject_cast<QToolButton*>(widget)) {
- QEvent event(QEvent::StyleChange);
- QApplication::sendEvent(widget, &event);
- }
- }
-}
-
-static QHashableLatin1Literal classPath(GtkWidget *widget)
-{
- char *class_path;
- QGtkStylePrivate::gtk_widget_path (widget, NULL, &class_path, NULL);
-
- char *copy = class_path;
- if (strncmp(copy, "GtkWindow.", 10) == 0)
- copy += 10;
- if (strncmp(copy, "GtkFixed.", 9) == 0)
- copy += 9;
-
- copy = strdup(copy);
-
- g_free(class_path);
-
- return QHashableLatin1Literal::fromData(copy);
-}
-
-
-
-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
- if (!qt_app_palettes_hash() || qt_app_palettes_hash()->isEmpty()) {
- stylePrivate->applyCustomPaletteHash();
- }
- }
- return QObject::eventFilter(obj, e);
-}
-
-QList<QGtkStylePrivate *> QGtkStylePrivate::instances;
-QGtkStylePrivate::WidgetMap *QGtkStylePrivate::widgetMap = 0;
-
-QGtkStylePrivate::QGtkStylePrivate()
- : QCleanlooksStylePrivate()
- , filter(this)
-{
- instances.append(this);
-}
-
-QGtkStylePrivate::~QGtkStylePrivate()
-{
- instances.removeOne(this);
-}
-
-void QGtkStylePrivate::init()
-{
- resolveGtk();
- initGtkWidgets();
-}
-
-GtkWidget* QGtkStylePrivate::gtkWidget(const QHashableLatin1Literal &path)
-{
- GtkWidget *widget = gtkWidgetMap()->value(path);
- if (!widget) {
- // Theme might have rearranged widget internals
- widget = gtkWidgetMap()->value(path);
- }
- return widget;
-}
-
-GtkStyle* QGtkStylePrivate::gtkStyle(const QHashableLatin1Literal &path)
-{
- if (GtkWidget *w = gtkWidgetMap()->value(path))
- return w->style;
- return 0;
-}
-
-/*! \internal
- * Get references to gtk functions after we dynamically load the library.
- */
-void QGtkStylePrivate::resolveGtk() const
-{
- // enforce the "0" suffix, so we'll open libgtk-x11-2.0.so.0
- QLibrary libgtk(QLS("gtk-x11-2.0"), 0, 0);
-
- gtk_init = (Ptr_gtk_init)libgtk.resolve("gtk_init");
- gtk_window_new = (Ptr_gtk_window_new)libgtk.resolve("gtk_window_new");
- gtk_style_attach = (Ptr_gtk_style_attach)libgtk.resolve("gtk_style_attach");
- gtk_widget_destroy = (Ptr_gtk_widget_destroy)libgtk.resolve("gtk_widget_destroy");
- gtk_widget_realize = (Ptr_gtk_widget_realize)libgtk.resolve("gtk_widget_realize");
-
- gtk_file_chooser_set_current_folder = (Ptr_gtk_file_chooser_set_current_folder)libgtk.resolve("gtk_file_chooser_set_current_folder");
- gtk_file_filter_new = (Ptr_gtk_file_filter_new)libgtk.resolve("gtk_file_filter_new");
- gtk_file_filter_set_name = (Ptr_gtk_file_filter_set_name)libgtk.resolve("gtk_file_filter_set_name");
- gtk_file_filter_add_pattern = (Ptr_gtk_file_filter_add_pattern)libgtk.resolve("gtk_file_filter_add_pattern");
- gtk_file_chooser_add_filter = (Ptr_gtk_file_chooser_add_filter)libgtk.resolve("gtk_file_chooser_add_filter");
- gtk_file_chooser_set_filter = (Ptr_gtk_file_chooser_set_filter)libgtk.resolve("gtk_file_chooser_set_filter");
- gtk_file_chooser_get_filter = (Ptr_gtk_file_chooser_get_filter)libgtk.resolve("gtk_file_chooser_get_filter");
- gtk_file_chooser_dialog_new = (Ptr_gtk_file_chooser_dialog_new)libgtk.resolve("gtk_file_chooser_dialog_new");
- gtk_file_chooser_set_current_folder = (Ptr_gtk_file_chooser_set_current_folder)libgtk.resolve("gtk_file_chooser_set_current_folder");
- gtk_file_chooser_get_filename = (Ptr_gtk_file_chooser_get_filename)libgtk.resolve("gtk_file_chooser_get_filename");
- gtk_file_chooser_get_filenames = (Ptr_gtk_file_chooser_get_filenames)libgtk.resolve("gtk_file_chooser_get_filenames");
- gtk_file_chooser_set_current_name = (Ptr_gtk_file_chooser_set_current_name)libgtk.resolve("gtk_file_chooser_set_current_name");
- gtk_dialog_run = (Ptr_gtk_dialog_run)libgtk.resolve("gtk_dialog_run");
- gtk_file_chooser_set_filename = (Ptr_gtk_file_chooser_set_filename)libgtk.resolve("gtk_file_chooser_set_filename");
-
- gdk_pixbuf_get_pixels = (Ptr_gdk_pixbuf_get_pixels)libgtk.resolve("gdk_pixbuf_get_pixels");
- gdk_pixbuf_get_width = (Ptr_gdk_pixbuf_get_width)libgtk.resolve("gdk_pixbuf_get_width");
- gdk_pixbuf_get_height = (Ptr_gdk_pixbuf_get_height)libgtk.resolve("gdk_pixbuf_get_height");
- gdk_pixmap_new = (Ptr_gdk_pixmap_new)libgtk.resolve("gdk_pixmap_new");
- gdk_pixbuf_new = (Ptr_gdk_pixbuf_new)libgtk.resolve("gdk_pixbuf_new");
- gdk_pixbuf_get_from_drawable = (Ptr_gdk_pixbuf_get_from_drawable)libgtk.resolve("gdk_pixbuf_get_from_drawable");
- gdk_draw_rectangle = (Ptr_gdk_draw_rectangle)libgtk.resolve("gdk_draw_rectangle");
- gdk_pixbuf_unref = (Ptr_gdk_pixbuf_unref)libgtk.resolve("gdk_pixbuf_unref");
- gdk_drawable_unref = (Ptr_gdk_drawable_unref)libgtk.resolve("gdk_drawable_unref");
- gdk_drawable_get_depth = (Ptr_gdk_drawable_get_depth)libgtk.resolve("gdk_drawable_get_depth");
- gdk_color_free = (Ptr_gdk_color_free)libgtk.resolve("gdk_color_free");
- gdk_x11_window_set_user_time = (Ptr_gdk_x11_window_set_user_time)libgtk.resolve("gdk_x11_window_set_user_time");
- gdk_x11_drawable_get_xid = (Ptr_gdk_x11_drawable_get_xid)libgtk.resolve("gdk_x11_drawable_get_xid");
- gdk_x11_drawable_get_xdisplay = (Ptr_gdk_x11_drawable_get_xdisplay)libgtk.resolve("gdk_x11_drawable_get_xdisplay");
-
- gtk_widget_set_default_direction = (Ptr_gtk_widget_set_default_direction)libgtk.resolve("gtk_widget_set_default_direction");
- gtk_widget_modify_fg = (Ptr_gtk_widget_modify_color)libgtk.resolve("gtk_widget_modify_fg");
- gtk_widget_modify_bg = (Ptr_gtk_widget_modify_color)libgtk.resolve("gtk_widget_modify_bg");
- gtk_arrow_new = (Ptr_gtk_arrow_new)libgtk.resolve("gtk_arrow_new");
- gtk_menu_item_new_with_label = (Ptr_gtk_menu_item_new_with_label)libgtk.resolve("gtk_menu_item_new_with_label");
- gtk_check_menu_item_new_with_label = (Ptr_gtk_check_menu_item_new_with_label)libgtk.resolve("gtk_check_menu_item_new_with_label");
- gtk_menu_bar_new = (Ptr_gtk_menu_bar_new)libgtk.resolve("gtk_menu_bar_new");
- gtk_menu_new = (Ptr_gtk_menu_new)libgtk.resolve("gtk_menu_new");
- gtk_toolbar_new = (Ptr_gtk_toolbar_new)libgtk.resolve("gtk_toolbar_new");
- gtk_separator_tool_item_new = (Ptr_gtk_separator_tool_item_new)libgtk.resolve("gtk_separator_tool_item_new");
- gtk_toolbar_insert = (Ptr_gtk_toolbar_insert)libgtk.resolve("gtk_toolbar_insert");
- gtk_button_new = (Ptr_gtk_button_new)libgtk.resolve("gtk_button_new");
- gtk_tool_button_new = (Ptr_gtk_tool_button_new)libgtk.resolve("gtk_tool_button_new");
- gtk_hbutton_box_new = (Ptr_gtk_hbutton_box_new)libgtk.resolve("gtk_hbutton_box_new");
- gtk_check_button_new = (Ptr_gtk_check_button_new)libgtk.resolve("gtk_check_button_new");
- gtk_radio_button_new = (Ptr_gtk_radio_button_new)libgtk.resolve("gtk_radio_button_new");
- gtk_notebook_new = (Ptr_gtk_notebook_new)libgtk.resolve("gtk_notebook_new");
- gtk_progress_bar_new = (Ptr_gtk_progress_bar_new)libgtk.resolve("gtk_progress_bar_new");
- gtk_spin_button_new = (Ptr_gtk_spin_button_new)libgtk.resolve("gtk_spin_button_new");
- gtk_hscale_new = (Ptr_gtk_hscale_new)libgtk.resolve("gtk_hscale_new");
- gtk_vscale_new = (Ptr_gtk_vscale_new)libgtk.resolve("gtk_vscale_new");
- gtk_hscrollbar_new = (Ptr_gtk_hscrollbar_new)libgtk.resolve("gtk_hscrollbar_new");
- gtk_vscrollbar_new = (Ptr_gtk_vscrollbar_new)libgtk.resolve("gtk_vscrollbar_new");
- gtk_scrolled_window_new = (Ptr_gtk_scrolled_window_new)libgtk.resolve("gtk_scrolled_window_new");
- gtk_menu_shell_append = (Ptr_gtk_menu_shell_append)libgtk.resolve("gtk_menu_shell_append");
- gtk_entry_new = (Ptr_gtk_entry_new)libgtk.resolve("gtk_entry_new");
- gtk_tree_view_new = (Ptr_gtk_tree_view_new)libgtk.resolve("gtk_tree_view_new");
- gtk_combo_box_new = (Ptr_gtk_combo_box_new)libgtk.resolve("gtk_combo_box_new");
- gtk_progress_configure = (Ptr_gtk_progress_configure)libgtk.resolve("gtk_progress_configure");
- gtk_range_get_adjustment = (Ptr_gtk_range_get_adjustment)libgtk.resolve("gtk_range_get_adjustment");
- gtk_range_set_adjustment = (Ptr_gtk_range_set_adjustment)libgtk.resolve("gtk_range_set_adjustment");
- gtk_range_set_inverted = (Ptr_gtk_range_set_inverted)libgtk.resolve("gtk_range_set_inverted");
- gtk_container_add = (Ptr_gtk_container_add)libgtk.resolve("gtk_container_add");
- gtk_icon_factory_lookup_default = (Ptr_gtk_icon_factory_lookup_default)libgtk.resolve("gtk_icon_factory_lookup_default");
- gtk_icon_theme_get_default = (Ptr_gtk_icon_theme_get_default)libgtk.resolve("gtk_icon_theme_get_default");
- gtk_widget_style_get = (Ptr_gtk_widget_style_get)libgtk.resolve("gtk_widget_style_get");
- gtk_icon_set_render_icon = (Ptr_gtk_icon_set_render_icon)libgtk.resolve("gtk_icon_set_render_icon");
- gtk_fixed_new = (Ptr_gtk_fixed_new)libgtk.resolve("gtk_fixed_new");
- gtk_tree_view_column_new = (Ptr_gtk_tree_view_column_new)libgtk.resolve("gtk_tree_view_column_new");
- gtk_tree_view_append_column= (Ptr_gtk_tree_view_append_column )libgtk.resolve("gtk_tree_view_append_column");
- gtk_tree_view_get_column = (Ptr_gtk_tree_view_get_column )libgtk.resolve("gtk_tree_view_get_column");
- gtk_paint_check = (Ptr_gtk_paint_check)libgtk.resolve("gtk_paint_check");
- gtk_paint_box = (Ptr_gtk_paint_box)libgtk.resolve("gtk_paint_box");
- gtk_paint_flat_box = (Ptr_gtk_paint_flat_box)libgtk.resolve("gtk_paint_flat_box");
- gtk_paint_check = (Ptr_gtk_paint_check)libgtk.resolve("gtk_paint_check");
- gtk_paint_box = (Ptr_gtk_paint_box)libgtk.resolve("gtk_paint_box");
- gtk_paint_resize_grip = (Ptr_gtk_paint_resize_grip)libgtk.resolve("gtk_paint_resize_grip");
- gtk_paint_focus = (Ptr_gtk_paint_focus)libgtk.resolve("gtk_paint_focus");
- gtk_paint_shadow = (Ptr_gtk_paint_shadow)libgtk.resolve("gtk_paint_shadow");
- gtk_paint_slider = (Ptr_gtk_paint_slider)libgtk.resolve("gtk_paint_slider");
- gtk_paint_expander = (Ptr_gtk_paint_expander)libgtk.resolve("gtk_paint_expander");
- gtk_paint_handle = (Ptr_gtk_paint_handle)libgtk.resolve("gtk_paint_handle");
- gtk_paint_option = (Ptr_gtk_paint_option)libgtk.resolve("gtk_paint_option");
- gtk_paint_arrow = (Ptr_gtk_paint_arrow)libgtk.resolve("gtk_paint_arrow");
- gtk_paint_box_gap = (Ptr_gtk_paint_box_gap)libgtk.resolve("gtk_paint_box_gap");
- gtk_paint_extension = (Ptr_gtk_paint_extension)libgtk.resolve("gtk_paint_extension");
- gtk_paint_hline = (Ptr_gtk_paint_hline)libgtk.resolve("gtk_paint_hline");
- gtk_paint_vline = (Ptr_gtk_paint_vline)libgtk.resolve("gtk_paint_vline");
- gtk_adjustment_configure = (Ptr_gtk_adjustment_configure)libgtk.resolve("gtk_adjustment_configure");
- gtk_adjustment_new = (Ptr_gtk_adjustment_new)libgtk.resolve("gtk_adjustment_new");
- gtk_menu_item_set_submenu = (Ptr_gtk_menu_item_set_submenu)libgtk.resolve("gtk_menu_item_set_submenu");
- gtk_settings_get_default = (Ptr_gtk_settings_get_default)libgtk.resolve("gtk_settings_get_default");
- gtk_separator_menu_item_new = (Ptr_gtk_separator_menu_item_new)libgtk.resolve("gtk_separator_menu_item_new");
- gtk_frame_new = (Ptr_gtk_frame_new)libgtk.resolve("gtk_frame_new");
- gtk_expander_new = (Ptr_gtk_expander_new)libgtk.resolve("gtk_expander_new");
- gtk_statusbar_new = (Ptr_gtk_statusbar_new)libgtk.resolve("gtk_statusbar_new");
- gtk_combo_box_entry_new = (Ptr_gtk_combo_box_entry_new)libgtk.resolve("gtk_combo_box_entry_new");
- gtk_container_forall = (Ptr_gtk_container_forall)libgtk.resolve("gtk_container_forall");
- gtk_widget_size_allocate =(Ptr_gtk_widget_size_allocate)libgtk.resolve("gtk_widget_size_allocate");
- gtk_widget_size_request =(Ptr_gtk_widget_size_request)libgtk.resolve("gtk_widget_size_request");
- gtk_widget_set_direction =(Ptr_gtk_widget_set_direction)libgtk.resolve("gtk_widget_set_direction");
- gtk_widget_path =(Ptr_gtk_widget_path)libgtk.resolve("gtk_widget_path");
- gtk_container_get_type =(Ptr_gtk_container_get_type)libgtk.resolve("gtk_container_get_type");
- gtk_window_get_type =(Ptr_gtk_window_get_type)libgtk.resolve("gtk_window_get_type");
- gtk_widget_get_type =(Ptr_gtk_widget_get_type)libgtk.resolve("gtk_widget_get_type");
-
- gtk_rc_get_style_by_paths =(Ptr_gtk_rc_get_style_by_paths)libgtk.resolve("gtk_rc_get_style_by_paths");
- gtk_check_version =(Ptr_gtk_check_version)libgtk.resolve("gtk_check_version");
- gtk_border_free =(Ptr_gtk_border_free)libgtk.resolve("gtk_border_free");
- pango_font_description_get_size = (Ptr_pango_font_description_get_size)libgtk.resolve("pango_font_description_get_size");
- pango_font_description_get_weight = (Ptr_pango_font_description_get_weight)libgtk.resolve("pango_font_description_get_weight");
- pango_font_description_get_family = (Ptr_pango_font_description_get_family)libgtk.resolve("pango_font_description_get_family");
- pango_font_description_get_style = (Ptr_pango_font_description_get_style)libgtk.resolve("pango_font_description_get_style");
-
- gnome_icon_lookup_sync = (Ptr_gnome_icon_lookup_sync)QLibrary::resolve(QLS("gnomeui-2"), 0, "gnome_icon_lookup_sync");
- gnome_vfs_init= (Ptr_gnome_vfs_init)QLibrary::resolve(QLS("gnomevfs-2"), 0, "gnome_vfs_init");
-}
-
-/* \internal
- * Initializes a number of gtk menu widgets.
- * The widgets are cached.
- */
-void QGtkStylePrivate::initGtkMenu() const
-{
- // Create menubar
- GtkWidget *gtkMenuBar = QGtkStylePrivate::gtk_menu_bar_new();
- setupGtkWidget(gtkMenuBar);
-
- GtkWidget *gtkMenuBarItem = QGtkStylePrivate::gtk_menu_item_new_with_label("X");
- gtk_menu_shell_append((GtkMenuShell*)(gtkMenuBar), gtkMenuBarItem);
- gtk_widget_realize(gtkMenuBarItem);
-
- // Create menu
- GtkWidget *gtkMenu = QGtkStylePrivate::gtk_menu_new();
- gtk_menu_item_set_submenu((GtkMenuItem*)(gtkMenuBarItem), gtkMenu);
- gtk_widget_realize(gtkMenu);
-
- GtkWidget *gtkMenuItem = QGtkStylePrivate::gtk_menu_item_new_with_label("X");
- gtk_menu_shell_append((GtkMenuShell*)gtkMenu, gtkMenuItem);
- gtk_widget_realize(gtkMenuItem);
-
- GtkWidget *gtkCheckMenuItem = QGtkStylePrivate::gtk_check_menu_item_new_with_label("X");
- gtk_menu_shell_append((GtkMenuShell*)gtkMenu, gtkCheckMenuItem);
- gtk_widget_realize(gtkCheckMenuItem);
-
- GtkWidget *gtkMenuSeparator = QGtkStylePrivate::gtk_separator_menu_item_new();
- gtk_menu_shell_append((GtkMenuShell*)gtkMenu, gtkMenuSeparator);
-
- addAllSubWidgets(gtkMenuBar);
- addAllSubWidgets(gtkMenu);
-}
-
-
-void QGtkStylePrivate::initGtkTreeview() const
-{
- GtkWidget *gtkTreeView = gtk_tree_view_new();
- gtk_tree_view_append_column((GtkTreeView*)gtkTreeView, gtk_tree_view_column_new());
- gtk_tree_view_append_column((GtkTreeView*)gtkTreeView, gtk_tree_view_column_new());
- gtk_tree_view_append_column((GtkTreeView*)gtkTreeView, gtk_tree_view_column_new());
- addWidget(gtkTreeView);
-}
-
-
-/* \internal
- * Initializes a number of gtk widgets that we can later on use to determine some of our styles.
- * The widgets are cached.
- */
-void QGtkStylePrivate::initGtkWidgets() const
-{
- // From gtkmain.c
- uid_t ruid = getuid ();
- uid_t rgid = getgid ();
- uid_t euid = geteuid ();
- uid_t egid = getegid ();
- if (ruid != euid || rgid != egid) {
- qWarning("\nThis process is currently running setuid or setgid.\nGTK+ does not allow this "
- "therefore Qt cannot use the GTK+ integration.\nTry launching your app using \'gksudo\', "
- "\'kdesudo\' or a similar tool.\n\n"
- "See http://www.gtk.org/setuid.html for more information.\n");
- return;
- }
-
- static QString themeName;
- if (!gtkWidgetMap()->contains("GtkWindow") && themeName.isEmpty()) {
- themeName = getThemeName();
-
- if (themeName.isEmpty()) {
- qWarning("QGtkStyle was unable to detect the current GTK+ theme.");
- return;
- } else if (themeName == QLS("Qt") || themeName == QLS("Qt4")) {
- // Due to namespace conflicts with Qt3 and obvious recursion with Qt4,
- // we cannot support the GTK_Qt Gtk engine
- qWarning("QGtkStyle cannot be used together with the GTK_Qt engine.");
- return;
- }
- }
-
- if (QGtkStylePrivate::gtk_init) {
- // Gtk will set the Qt error handler so we have to reset it afterwards
- x11ErrorHandler qt_x_errhandler = XSetErrorHandler(0);
- QGtkStylePrivate::gtk_init (NULL, NULL);
- XSetErrorHandler(qt_x_errhandler);
-
- // make a window
- GtkWidget* gtkWindow = QGtkStylePrivate::gtk_window_new(GTK_WINDOW_POPUP);
- QGtkStylePrivate::gtk_widget_realize(gtkWindow);
- if (displayDepth == -1)
- displayDepth = QGtkStylePrivate::gdk_drawable_get_depth(gtkWindow->window);
- QHashableLatin1Literal widgetPath = QHashableLatin1Literal::fromData(strdup("GtkWindow"));
- removeWidgetFromMap(widgetPath);
- gtkWidgetMap()->insert(widgetPath, gtkWindow);
-
-
- // Make all other widgets. respect the text direction
- if (qApp->layoutDirection() == Qt::RightToLeft)
- QGtkStylePrivate::gtk_widget_set_default_direction(GTK_TEXT_DIR_RTL);
-
- if (!gtkWidgetMap()->contains("GtkButton")) {
- GtkWidget *gtkButton = QGtkStylePrivate::gtk_button_new();
- addWidget(gtkButton);
- g_signal_connect(gtkButton, "style-set", G_CALLBACK(gtkStyleSetCallback), 0);
- addWidget(QGtkStylePrivate::gtk_tool_button_new(NULL, "Qt"));
- addWidget(QGtkStylePrivate::gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_NONE));
- addWidget(QGtkStylePrivate::gtk_hbutton_box_new());
- addWidget(QGtkStylePrivate::gtk_check_button_new());
- addWidget(QGtkStylePrivate::gtk_radio_button_new(NULL));
- addWidget(QGtkStylePrivate::gtk_combo_box_new());
- addWidget(QGtkStylePrivate::gtk_combo_box_entry_new());
- addWidget(QGtkStylePrivate::gtk_entry_new());
- addWidget(QGtkStylePrivate::gtk_frame_new(NULL));
- addWidget(QGtkStylePrivate::gtk_expander_new(""));
- addWidget(QGtkStylePrivate::gtk_statusbar_new());
- addWidget(QGtkStylePrivate::gtk_hscale_new((GtkAdjustment*)(QGtkStylePrivate::gtk_adjustment_new(1, 0, 1, 0, 0, 0))));
- addWidget(QGtkStylePrivate::gtk_hscrollbar_new(NULL));
- addWidget(QGtkStylePrivate::gtk_scrolled_window_new(NULL, NULL));
-
- initGtkMenu();
- addWidget(QGtkStylePrivate::gtk_notebook_new());
- addWidget(QGtkStylePrivate::gtk_progress_bar_new());
- addWidget(QGtkStylePrivate::gtk_spin_button_new((GtkAdjustment*)
- (QGtkStylePrivate::gtk_adjustment_new(1, 0, 1, 0, 0, 0)), 0.1, 3));
- GtkWidget *toolbar = gtk_toolbar_new();
- g_signal_connect (toolbar, "notify::toolbar-style", G_CALLBACK (update_toolbar_style), toolbar);
- gtk_toolbar_insert((GtkToolbar*)toolbar, gtk_separator_tool_item_new(), -1);
- addWidget(toolbar);
- initGtkTreeview();
- addWidget(gtk_vscale_new((GtkAdjustment*)(QGtkStylePrivate::gtk_adjustment_new(1, 0, 1, 0, 0, 0))));
- addWidget(gtk_vscrollbar_new(NULL));
- }
- else // Rebuild map
- {
- // When styles change subwidgets can get rearranged
- // as with the combo box. We need to update the widget map
- // to reflect this;
- QHash<QHashableLatin1Literal, GtkWidget*> oldMap = *gtkWidgetMap();
- gtkWidgetMap()->clear();
- QHashIterator<QHashableLatin1Literal, GtkWidget*> it(oldMap);
- while (it.hasNext()) {
- it.next();
- if (!strchr(it.key().data(), '.')) {
- addAllSubWidgets(it.value());
- }
- free(const_cast<char *>(it.key().data()));
- }
- }
- } else {
- qWarning("QGtkStyle could not resolve GTK. Make sure you have installed the proper libraries.");
- }
-}
-
-/*! \internal
- * destroys all previously buffered widgets.
- */
-void QGtkStylePrivate::cleanupGtkWidgets()
-{
- if (!widgetMap)
- return;
- if (widgetMap->contains("GtkWindow")) // Gtk will destroy all children
- gtk_widget_destroy(widgetMap->value("GtkWindow"));
- for (QHash<QHashableLatin1Literal, GtkWidget *>::const_iterator it = widgetMap->constBegin();
- it != widgetMap->constEnd(); ++it)
- free(const_cast<char *>(it.key().data()));
-}
-
-static bool resolveGConf()
-{
- if (!QGtkStylePrivate::gconf_client_get_default) {
- QGtkStylePrivate::gconf_client_get_default = (Ptr_gconf_client_get_default)QLibrary::resolve(QLS("gconf-2"), 4, "gconf_client_get_default");
- QGtkStylePrivate::gconf_client_get_string = (Ptr_gconf_client_get_string)QLibrary::resolve(QLS("gconf-2"), 4, "gconf_client_get_string");
- QGtkStylePrivate::gconf_client_get_bool = (Ptr_gconf_client_get_bool)QLibrary::resolve(QLS("gconf-2"), 4, "gconf_client_get_bool");
- }
- return (QGtkStylePrivate::gconf_client_get_default !=0);
-}
-
-QString QGtkStylePrivate::getGConfString(const QString &value, const QString &fallback)
-{
- QString retVal = fallback;
- if (resolveGConf()) {
- g_type_init();
- GConfClient* client = gconf_client_get_default();
- GError *err = 0;
- char *str = gconf_client_get_string(client, qPrintable(value), &err);
- if (!err) {
- retVal = QString::fromUtf8(str);
- g_free(str);
- }
- g_object_unref(client);
- if (err)
- g_error_free (err);
- }
- return retVal;
-}
-
-bool QGtkStylePrivate::getGConfBool(const QString &key, bool fallback)
-{
- bool retVal = fallback;
- if (resolveGConf()) {
- g_type_init();
- GConfClient* client = gconf_client_get_default();
- GError *err = 0;
- bool result = gconf_client_get_bool(client, qPrintable(key), &err);
- g_object_unref(client);
- if (!err)
- retVal = result;
- else
- g_error_free (err);
- }
- return retVal;
-}
-
-QString QGtkStylePrivate::getThemeName()
-{
- QString themeName;
- // We try to parse the gtkrc file first
- // primarily to avoid resolving Gtk functions if
- // the KDE 3 "Qt" style is currently in use
- QString rcPaths = QString::fromLocal8Bit(qgetenv("GTK2_RC_FILES"));
- if (!rcPaths.isEmpty()) {
- QStringList paths = rcPaths.split(QLS(":"));
- foreach (const QString &rcPath, paths) {
- if (!rcPath.isEmpty()) {
- QFile rcFile(rcPath);
- if (rcFile.exists() && rcFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
- QTextStream in(&rcFile);
- while(!in.atEnd()) {
- QString line = in.readLine();
- if (line.contains(QLS("gtk-theme-name"))) {
- line = line.right(line.length() - line.indexOf(QLatin1Char('=')) - 1);
- line.remove(QLatin1Char('\"'));
- line = line.trimmed();
- themeName = line;
- break;
- }
- }
- }
- }
- if (!themeName.isEmpty())
- break;
- }
- }
-
- // Fall back to gconf
- if (themeName.isEmpty() && resolveGConf())
- themeName = getGConfString(QLS("/desktop/gnome/interface/gtk_theme"));
-
- return themeName;
-}
-
-// Get size of the arrow controls in a GtkSpinButton
-int QGtkStylePrivate::getSpinboxArrowSize() const
-{
- const int MIN_ARROW_WIDTH = 6;
- GtkWidget *spinButton = gtkWidget("GtkSpinButton");
- GtkStyle *style = spinButton->style;
- gint size = pango_font_description_get_size (style->font_desc);
- gint arrow_size;
- arrow_size = qMax(PANGO_PIXELS (size), MIN_ARROW_WIDTH) + style->xthickness;
- arrow_size += arrow_size%2 + 1;
- return arrow_size;
-}
-
-
-bool QGtkStylePrivate::isKDE4Session()
-{
- static int version = -1;
- if (version == -1)
- version = qgetenv("KDE_SESSION_VERSION").toInt();
- return (version == 4);
-}
-
-void QGtkStylePrivate::applyCustomPaletteHash()
-{
- QPalette menuPal = gtkWidgetPalette("GtkMenu");
- GdkColor gdkBg = gtkWidget("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 toolbarPal = gtkWidgetPalette("GtkToolbar");
- qApp->setPalette(toolbarPal, "QToolBar");
-
- QPalette menuBarPal = gtkWidgetPalette("GtkMenuBar");
- qApp->setPalette(menuBarPal, "QMenuBar");
-}
-
-/*! \internal
- * Returns the gtk Widget that should be used to determine text foreground and background colors.
-*/
-GtkWidget* QGtkStylePrivate::getTextColorWidget() const
-{
- return gtkWidget("GtkEntry");
-}
-
-void QGtkStylePrivate::setupGtkWidget(GtkWidget* widget)
-{
- if (Q_GTK_IS_WIDGET(widget)) {
- static GtkWidget* protoLayout = 0;
- if (!protoLayout) {
- protoLayout = QGtkStylePrivate::gtk_fixed_new();
- QGtkStylePrivate::gtk_container_add((GtkContainer*)(gtkWidgetMap()->value("GtkWindow")), protoLayout);
- }
- Q_ASSERT(protoLayout);
-
- if (!widget->parent && !GTK_WIDGET_TOPLEVEL(widget))
- QGtkStylePrivate::gtk_container_add((GtkContainer*)(protoLayout), widget);
- QGtkStylePrivate::gtk_widget_realize(widget);
- }
-}
-
-void QGtkStylePrivate::removeWidgetFromMap(const QHashableLatin1Literal &path)
-{
- WidgetMap *map = gtkWidgetMap();
- WidgetMap::iterator it = map->find(path);
- if (it != map->end()) {
- free(const_cast<char *>(it.key().data()));
- map->erase(it);
- }
-}
-
-void QGtkStylePrivate::addWidgetToMap(GtkWidget *widget)
-{
- if (Q_GTK_IS_WIDGET(widget)) {
- gtk_widget_realize(widget);
- QHashableLatin1Literal widgetPath = classPath(widget);
-
- removeWidgetFromMap(widgetPath);
- gtkWidgetMap()->insert(widgetPath, widget);
-#ifdef DUMP_GTK_WIDGET_TREE
- qWarning("Inserted Gtk Widget: %s", widgetPath.data());
-#endif
- }
- }
-
-void QGtkStylePrivate::addAllSubWidgets(GtkWidget *widget, gpointer v)
-{
- Q_UNUSED(v);
- addWidgetToMap(widget);
- if (GTK_CHECK_TYPE ((widget), gtk_container_get_type()))
- gtk_container_forall((GtkContainer*)widget, addAllSubWidgets, NULL);
-}
-
-// Updates window/windowtext palette based on the indicated gtk widget
-QPalette QGtkStylePrivate::gtkWidgetPalette(const QHashableLatin1Literal &gtkWidgetName) const
-{
- GtkWidget *gtkWidget = QGtkStylePrivate::gtkWidget(gtkWidgetName);
- Q_ASSERT(gtkWidget);
- 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];
- QColor bgColor(gdkBg.red>>8, gdkBg.green>>8, gdkBg.blue>>8);
- QColor textColor(gdkText.red>>8, gdkText.green>>8, gdkText.blue>>8);
- QColor disabledTextColor(gdkDisabledText.red>>8, gdkDisabledText.green>>8, gdkDisabledText.blue>>8);
- pal.setBrush(QPalette::Window, bgColor);
- pal.setBrush(QPalette::Button, bgColor);
- pal.setBrush(QPalette::All, QPalette::WindowText, textColor);
- pal.setBrush(QPalette::Disabled, QPalette::WindowText, disabledTextColor);
- pal.setBrush(QPalette::All, QPalette::ButtonText, textColor);
- pal.setBrush(QPalette::Disabled, QPalette::ButtonText, disabledTextColor);
- return pal;
-}
-
-
-void QGtkStyleUpdateScheduler::updateTheme()
-{
- static QString oldTheme(QLS("qt_not_set"));
- QPixmapCache::clear();
-
- QFont font = QGtkStylePrivate::getThemeFont();
- if (QApplication::font() != font)
- qApp->setFont(font);
-
- if (oldTheme != QGtkStylePrivate::getThemeName()) {
- oldTheme = QGtkStylePrivate::getThemeName();
- QPalette newPalette = qApp->style()->standardPalette();
- QApplicationPrivate::setSystemPalette(newPalette);
- QApplication::setPalette(newPalette);
- if (!QGtkStylePrivate::instances.isEmpty()) {
- QGtkStylePrivate::instances.last()->initGtkWidgets();
- QGtkStylePrivate::instances.last()->applyCustomPaletteHash();
- }
- QList<QWidget*> widgets = QApplication::allWidgets();
- // Notify all widgets that size metrics might have changed
- foreach (QWidget *widget, widgets) {
- QEvent e(QEvent::StyleChange);
- QApplication::sendEvent(widget, &e);
- }
- }
- QIconLoader::instance()->updateSystemTheme();
-}
-
-void QGtkStylePrivate::addWidget(GtkWidget *widget)
-{
- if (widget) {
- setupGtkWidget(widget);
- addAllSubWidgets(widget);
- }
-}
-
-
-// Fetch the application font from the pango font description
-// contained in the theme.
-QFont QGtkStylePrivate::getThemeFont()
-{
- QFont font;
- GtkStyle *style = gtkStyle();
- if (style && qApp->desktopSettingsAware())
- {
- PangoFontDescription *gtk_font = style->font_desc;
- font.setPointSizeF((float)(pango_font_description_get_size(gtk_font))/PANGO_SCALE);
-
- QString family = QString::fromLatin1(pango_font_description_get_family(gtk_font));
- if (!family.isEmpty())
- font.setFamily(family);
-
- int weight = pango_font_description_get_weight(gtk_font);
- if (weight >= PANGO_WEIGHT_HEAVY)
- font.setWeight(QFont::Black);
- else if (weight >= PANGO_WEIGHT_BOLD)
- font.setWeight(QFont::Bold);
- else if (weight >= PANGO_WEIGHT_SEMIBOLD)
- font.setWeight(QFont::DemiBold);
- else if (weight >= PANGO_WEIGHT_NORMAL)
- font.setWeight(QFont::Normal);
- else
- font.setWeight(QFont::Light);
-
- PangoStyle fontstyle = pango_font_description_get_style(gtk_font);
- if (fontstyle == PANGO_STYLE_ITALIC)
- font.setStyle(QFont::StyleItalic);
- else if (fontstyle == PANGO_STYLE_OBLIQUE)
- font.setStyle(QFont::StyleOblique);
- else
- font.setStyle(QFont::StyleNormal);
- }
- return font;
-}
-
-
-// ----------- Native file dialogs -----------
-
-// Extract filter list from expressions of type: foo (*.a *.b *.c)"
-QStringList QGtkStylePrivate::extract_filter(const QString &rawFilter)
-{
- QString result = rawFilter;
- QRegExp r(QString::fromLatin1("^([^()]*)\\(([a-zA-Z0-9_.*? +;#\\-\\[\\]@\\{\\}/!<>\\$%&=^~:\\|]*)\\)$"));
- int index = r.indexIn(result);
- if (index >= 0)
- result = r.cap(2);
- return result.split(QLatin1Char(' '));
-}
-
-extern QStringList qt_make_filter_list(const QString &filter);
-
-void QGtkStylePrivate::setupGtkFileChooser(GtkWidget* gtkFileChooser, QWidget *parent,
- const QString &dir, const QString &filter, QString *selectedFilter,
- QFileDialog::Options options, bool isSaveDialog,
- QMap<GtkFileFilter *, QString> *filterMap)
-{
- g_object_set(gtkFileChooser, "do-overwrite-confirmation", gboolean(!(options & QFileDialog::DontConfirmOverwrite)), NULL);
- g_object_set(gtkFileChooser, "local_only", gboolean(true), NULL);
- if (!filter.isEmpty()) {
- QStringList filters = qt_make_filter_list(filter);
- foreach (const QString &rawfilter, filters) {
- GtkFileFilter *gtkFilter = QGtkStylePrivate::gtk_file_filter_new ();
- QString name = rawfilter.left(rawfilter.indexOf(QLatin1Char('(')));
- QStringList extensions = extract_filter(rawfilter);
- QGtkStylePrivate::gtk_file_filter_set_name(gtkFilter, qPrintable(name.isEmpty() ? extensions.join(QLS(", ")) : name));
-
- foreach (const QString &fileExtension, extensions) {
- // Note Gtk file dialogs are by default case sensitive
- // and only supports basic glob syntax so we
- // rewrite .xyz to .[xX][yY][zZ]
- QString caseInsensitive;
- for (int i = 0 ; i < fileExtension.length() ; ++i) {
- QChar ch = fileExtension.at(i);
- if (ch.isLetter()) {
- caseInsensitive.append(
- QLatin1Char('[') +
- ch.toLower() +
- ch.toUpper() +
- QLatin1Char(']'));
- } else {
- caseInsensitive.append(ch);
- }
- }
- QGtkStylePrivate::gtk_file_filter_add_pattern (gtkFilter, qPrintable(caseInsensitive));
-
- }
- if (filterMap)
- filterMap->insert(gtkFilter, rawfilter);
- QGtkStylePrivate::gtk_file_chooser_add_filter((GtkFileChooser*)gtkFileChooser, gtkFilter);
- if (selectedFilter && (rawfilter == *selectedFilter))
- QGtkStylePrivate::gtk_file_chooser_set_filter((GtkFileChooser*)gtkFileChooser, gtkFilter);
- }
- }
-
- // Using the currently active window is not entirely correct, however
- // it gives more sensible behavior for applications that do not provide a
- // parent
- QWidget *modalFor = parent ? parent->window() : qApp->activeWindow();
- if (modalFor) {
- QGtkStylePrivate::gtk_widget_realize(gtkFileChooser); // Creates X window
- XSetTransientForHint(QGtkStylePrivate::gdk_x11_drawable_get_xdisplay(gtkFileChooser->window),
- QGtkStylePrivate::gdk_x11_drawable_get_xid(gtkFileChooser->window),
- modalFor->winId());
- QGtkStylePrivate::gdk_x11_window_set_user_time (gtkFileChooser->window, QX11Info::appUserTime());
-
- }
-
- QFileInfo fileinfo(dir);
- if (dir.isEmpty())
- fileinfo.setFile(QDir::currentPath());
- fileinfo.makeAbsolute();
- if (fileinfo.isDir()) {
- QGtkStylePrivate::gtk_file_chooser_set_current_folder((GtkFileChooser*)gtkFileChooser, qPrintable(dir));
- } else if (isSaveDialog) {
- QGtkStylePrivate::gtk_file_chooser_set_current_folder((GtkFileChooser*)gtkFileChooser, qPrintable(fileinfo.absolutePath()));
- QGtkStylePrivate::gtk_file_chooser_set_current_name((GtkFileChooser*)gtkFileChooser, qPrintable(fileinfo.fileName()));
- } else {
- QGtkStylePrivate::gtk_file_chooser_set_filename((GtkFileChooser*)gtkFileChooser, qPrintable(dir));
- }
-}
-
-QString QGtkStylePrivate::openFilename(QWidget *parent, const QString &caption, const QString &dir, const QString &filter,
- QString *selectedFilter, QFileDialog::Options options)
-{
- QMap<GtkFileFilter *, QString> filterMap;
- GtkWidget *gtkFileChooser = QGtkStylePrivate::gtk_file_chooser_dialog_new (qPrintable(caption),
- NULL,
- GTK_FILE_CHOOSER_ACTION_OPEN,
- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
- GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
- NULL);
-
- setupGtkFileChooser(gtkFileChooser, parent, dir, filter, selectedFilter, options, false, &filterMap);
-
- QWidget modal_widget;
- modal_widget.setAttribute(Qt::WA_NoChildEventsForParent, true);
- modal_widget.setParent(parent, Qt::Window);
- QApplicationPrivate::enterModal(&modal_widget);
-
- QString filename;
- if (QGtkStylePrivate::gtk_dialog_run ((GtkDialog*)gtkFileChooser) == GTK_RESPONSE_ACCEPT) {
- char *gtk_filename = QGtkStylePrivate::gtk_file_chooser_get_filename ((GtkFileChooser*)gtkFileChooser);
- filename = QString::fromUtf8(gtk_filename);
- g_free (gtk_filename);
- if (selectedFilter) {
- GtkFileFilter *gtkFilter = QGtkStylePrivate::gtk_file_chooser_get_filter ((GtkFileChooser*)gtkFileChooser);
- *selectedFilter = filterMap.value(gtkFilter);
- }
- }
-
- QApplicationPrivate::leaveModal(&modal_widget);
- gtk_widget_destroy (gtkFileChooser);
- return filename;
-}
-
-
-QString QGtkStylePrivate::openDirectory(QWidget *parent, const QString &caption, const QString &dir, QFileDialog::Options options)
-{
- QMap<GtkFileFilter *, QString> filterMap;
- GtkWidget *gtkFileChooser = QGtkStylePrivate::gtk_file_chooser_dialog_new (qPrintable(caption),
- NULL,
- GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
- GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
- NULL);
-
- setupGtkFileChooser(gtkFileChooser, parent, dir, QString(), 0, options);
- QWidget modal_widget;
- modal_widget.setAttribute(Qt::WA_NoChildEventsForParent, true);
- modal_widget.setParent(parent, Qt::Window);
- QApplicationPrivate::enterModal(&modal_widget);
-
- QString filename;
- if (QGtkStylePrivate::gtk_dialog_run ((GtkDialog*)gtkFileChooser) == GTK_RESPONSE_ACCEPT) {
- char *gtk_filename = QGtkStylePrivate::gtk_file_chooser_get_filename ((GtkFileChooser*)gtkFileChooser);
- filename = QString::fromUtf8(gtk_filename);
- g_free (gtk_filename);
- }
-
- QApplicationPrivate::leaveModal(&modal_widget);
- gtk_widget_destroy (gtkFileChooser);
- return filename;
-}
-
-QStringList QGtkStylePrivate::openFilenames(QWidget *parent, const QString &caption, const QString &dir, const QString &filter,
- QString *selectedFilter, QFileDialog::Options options)
-{
- QStringList filenames;
- QMap<GtkFileFilter *, QString> filterMap;
- GtkWidget *gtkFileChooser = QGtkStylePrivate::gtk_file_chooser_dialog_new (qPrintable(caption),
- NULL,
- GTK_FILE_CHOOSER_ACTION_OPEN,
- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
- GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
- NULL);
-
- setupGtkFileChooser(gtkFileChooser, parent, dir, filter, selectedFilter, options, false, &filterMap);
- g_object_set(gtkFileChooser, "select-multiple", gboolean(true), NULL);
-
- QWidget modal_widget;
- modal_widget.setAttribute(Qt::WA_NoChildEventsForParent, true);
- modal_widget.setParent(parent, Qt::Window);
- QApplicationPrivate::enterModal(&modal_widget);
-
- if (gtk_dialog_run ((GtkDialog*)gtkFileChooser) == GTK_RESPONSE_ACCEPT) {
- GSList *gtk_file_names = QGtkStylePrivate::gtk_file_chooser_get_filenames((GtkFileChooser*)gtkFileChooser);
- for (GSList *iterator = gtk_file_names ; iterator; iterator = iterator->next)
- filenames << QString::fromUtf8((const char*)iterator->data);
- g_slist_free(gtk_file_names);
- if (selectedFilter) {
- GtkFileFilter *gtkFilter = QGtkStylePrivate::gtk_file_chooser_get_filter ((GtkFileChooser*)gtkFileChooser);
- *selectedFilter = filterMap.value(gtkFilter);
- }
- }
-
- QApplicationPrivate::leaveModal(&modal_widget);
- gtk_widget_destroy (gtkFileChooser);
- return filenames;
-}
-
-QString QGtkStylePrivate::saveFilename(QWidget *parent, const QString &caption, const QString &dir, const QString &filter,
- QString *selectedFilter, QFileDialog::Options options)
-{
- QMap<GtkFileFilter *, QString> filterMap;
- GtkWidget *gtkFileChooser = QGtkStylePrivate::gtk_file_chooser_dialog_new (qPrintable(caption),
- NULL,
- GTK_FILE_CHOOSER_ACTION_SAVE,
- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
- GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
- NULL);
- setupGtkFileChooser(gtkFileChooser, parent, dir, filter, selectedFilter, options, true, &filterMap);
-
- QWidget modal_widget;
- modal_widget.setAttribute(Qt::WA_NoChildEventsForParent, true);
- modal_widget.setParent(parent, Qt::Window);
- QApplicationPrivate::enterModal(&modal_widget);
-
- QString filename;
- if (QGtkStylePrivate::gtk_dialog_run ((GtkDialog*)gtkFileChooser) == GTK_RESPONSE_ACCEPT) {
- char *gtk_filename = QGtkStylePrivate::gtk_file_chooser_get_filename ((GtkFileChooser*)gtkFileChooser);
- filename = QString::fromUtf8(gtk_filename);
- g_free (gtk_filename);
- if (selectedFilter) {
- GtkFileFilter *gtkFilter = QGtkStylePrivate::gtk_file_chooser_get_filter ((GtkFileChooser*)gtkFileChooser);
- *selectedFilter = filterMap.value(gtkFilter);
- }
- }
-
- QApplicationPrivate::leaveModal(&modal_widget);
- gtk_widget_destroy (gtkFileChooser);
- return filename;
-}
-
-QIcon QGtkStylePrivate::getFilesystemIcon(const QFileInfo &info)
-{
- QIcon icon;
- if (gnome_vfs_init && gnome_icon_lookup_sync) {
- gnome_vfs_init();
- GtkIconTheme *theme = gtk_icon_theme_get_default();
- QByteArray fileurl = QUrl::fromLocalFile(info.absoluteFilePath()).toEncoded();
- char * icon_name = gnome_icon_lookup_sync(theme,
- NULL,
- fileurl.data(),
- NULL,
- GNOME_ICON_LOOKUP_FLAGS_NONE,
- NULL);
- QString iconName = QString::fromUtf8(icon_name);
- g_free(icon_name);
- if (iconName.startsWith(QLatin1Char('/')))
- return QIcon(iconName);
- return QIcon::fromTheme(iconName);
- }
- return icon;
-}
-
-bool operator==(const QHashableLatin1Literal &l1, const QHashableLatin1Literal &l2)
-{
- return l1.size() == l2.size() || qstrcmp(l1.data(), l2.data()) == 0;
-}
-
-// copied from qHash.cpp
-uint qHash(const QHashableLatin1Literal &key)
-{
- int n = key.size();
- const uchar *p = reinterpret_cast<const uchar *>(key.data());
- uint h = 0;
- uint g;
-
- while (n--) {
- h = (h << 4) + *p++;
- if ((g = (h & 0xf0000000)) != 0)
- h ^= g >> 23;
- h &= ~g;
- }
- return h;
-}
-
-QT_END_NAMESPACE
-
-#endif // !defined(QT_NO_STYLE_GTK)
diff --git a/src/gui/styles/qgtkstyle_p.h b/src/gui/styles/qgtkstyle_p.h
deleted file mode 100644
index e70ddef20d..0000000000
--- a/src/gui/styles/qgtkstyle_p.h
+++ /dev/null
@@ -1,531 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGTKSTYLE_P_H
-#define QGTKSTYLE_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/qglobal.h>
-#if !defined(QT_NO_STYLE_GTK)
-
-#include <QtCore/qstring.h>
-#include <QtCore/qstringbuilder.h>
-#include <QtCore/qcoreapplication.h>
-
-#include <QtGui/QFileDialog>
-
-#include <QtGui/QGtkStyle>
-#include <private/qcleanlooksstyle_p.h>
-
-#undef signals // Collides with GTK stymbols
-#include <gtk/gtk.h>
-
-typedef unsigned long XID;
-
-#undef GTK_OBJECT_FLAGS
-#define GTK_OBJECT_FLAGS(obj)(((GtkObject*)(obj))->flags)
-#define Q_GTK_IS_WIDGET(widget) widget && GTK_CHECK_TYPE ((widget), QGtkStylePrivate::gtk_widget_get_type())
-
-#define QLS(x) QLatin1String(x)
-
-QT_BEGIN_NAMESPACE
-
-// ### Qt 4.7 - merge with QLatin1Literal
-class QHashableLatin1Literal
-{
-public:
- int size() const { return m_size; }
- const char *data() const { return m_data; }
-
-#ifdef __SUNPRO_CC
- QHashableLatin1Literal(const char* str)
- : m_size(strlen(str)), m_data(str) {}
-#else
- template <int N>
- QHashableLatin1Literal(const char (&str)[N])
- : m_size(N - 1), m_data(str) {}
-#endif
-
- QHashableLatin1Literal(const QHashableLatin1Literal &other)
- : m_size(other.m_size), m_data(other.m_data)
- {}
-
- QHashableLatin1Literal &operator=(const QHashableLatin1Literal &other)
- {
- if (this == &other)
- return *this;
- *const_cast<int *>(&m_size) = other.m_size;
- *const_cast<char **>(&m_data) = const_cast<char *>(other.m_data);
- return *this;
- }
-
- QString toString() const { return QString::fromLatin1(m_data, m_size); }
-
- static QHashableLatin1Literal fromData(const char *str)
- {
- return QHashableLatin1Literal(str, qstrlen(str));
- }
-
-private:
- QHashableLatin1Literal(const char *str, int length)
- : m_size(length), m_data(str)
- {}
-
- const int m_size;
- const char *m_data;
-};
-
-bool operator==(const QHashableLatin1Literal &l1, const QHashableLatin1Literal &l2);
-inline bool operator!=(const QHashableLatin1Literal &l1, const QHashableLatin1Literal &l2) { return !operator==(l1, l2); }
-uint qHash(const QHashableLatin1Literal &key);
-
-QT_END_NAMESPACE
-
-class GConf;
-class GConfClient;
-
-typedef GConfClient* (*Ptr_gconf_client_get_default)();
-typedef char* (*Ptr_gconf_client_get_string)(GConfClient*, const char*, GError **);
-typedef bool (*Ptr_gconf_client_get_bool)(GConfClient*, const char*, GError **);
-
-typedef void (*Ptr_gtk_init)(int *, char ***);
-typedef GtkWidget* (*Ptr_gtk_window_new) (GtkWindowType);
-typedef GtkStyle* (*Ptr_gtk_style_attach)(GtkStyle *, GdkWindow *);
-typedef void (*Ptr_gtk_widget_destroy) (GtkWidget *);
-typedef void (*Ptr_gtk_widget_realize) (GtkWidget *);
-typedef void (*Ptr_gtk_widget_set_default_direction) (GtkTextDirection);
-typedef void (*Ptr_gtk_widget_modify_color)(GtkWidget *widget, GtkStateType state, const GdkColor *color);
-typedef GtkWidget* (*Ptr_gtk_arrow_new)(GtkArrowType, GtkShadowType);
-typedef GtkWidget* (*Ptr_gtk_menu_item_new_with_label)(const gchar *);
-typedef GtkWidget* (*Ptr_gtk_separator_menu_item_new)(void);
-typedef GtkWidget* (*Ptr_gtk_check_menu_item_new_with_label)(const gchar *);
-typedef GtkWidget* (*Ptr_gtk_menu_bar_new)(void);
-typedef GtkWidget* (*Ptr_gtk_menu_new)(void);
-typedef GtkWidget* (*Ptr_gtk_combo_box_entry_new)(void);
-typedef GtkWidget* (*Ptr_gtk_toolbar_new)(void);
-typedef GtkWidget* (*Ptr_gtk_spin_button_new)(GtkAdjustment*, double, int);
-typedef GtkWidget* (*Ptr_gtk_button_new)(void);
-typedef GtkWidget* (*Ptr_gtk_tool_button_new)(GtkWidget *, const gchar *);
-typedef GtkWidget* (*Ptr_gtk_hbutton_box_new)(void);
-typedef GtkWidget* (*Ptr_gtk_check_button_new)(void);
-typedef GtkWidget* (*Ptr_gtk_radio_button_new)(GSList *);
-typedef GtkWidget* (*Ptr_gtk_notebook_new)(void);
-typedef GtkWidget* (*Ptr_gtk_progress_bar_new)(void);
-typedef GtkWidget* (*Ptr_gtk_hscale_new)(GtkAdjustment*);
-typedef GtkWidget* (*Ptr_gtk_vscale_new)(GtkAdjustment*);
-typedef GtkWidget* (*Ptr_gtk_hscrollbar_new)(GtkAdjustment*);
-typedef GtkWidget* (*Ptr_gtk_vscrollbar_new)(GtkAdjustment*);
-typedef GtkWidget* (*Ptr_gtk_scrolled_window_new)(GtkAdjustment*, GtkAdjustment*);
-typedef gchar* (*Ptr_gtk_check_version)(guint, guint, guint);
-typedef GtkToolItem* (*Ptr_gtk_separator_tool_item_new) (void);
-typedef GtkWidget* (*Ptr_gtk_entry_new)(void);
-typedef GtkWidget* (*Ptr_gtk_tree_view_new)(void);
-typedef GtkTreeViewColumn* (*Ptr_gtk_tree_view_get_column)(GtkTreeView *, gint);
-typedef GtkWidget* (*Ptr_gtk_combo_box_new)(void);
-typedef GtkWidget* (*Ptr_gtk_frame_new)(const gchar *);
-typedef GtkWidget* (*Ptr_gtk_expander_new)(const gchar*);
-typedef GtkWidget* (*Ptr_gtk_statusbar_new)(void);
-typedef GtkSettings* (*Ptr_gtk_settings_get_default)(void);
-typedef GtkAdjustment* (*Ptr_gtk_range_get_adjustment)(GtkRange *);
-typedef void (*Ptr_gtk_range_set_adjustment)(GtkRange *, GtkAdjustment *);
-typedef void (*Ptr_gtk_progress_configure)(GtkProgress *, double, double, double);
-typedef void (*Ptr_gtk_range_set_inverted)(GtkRange*, bool);
-typedef void (*Ptr_gtk_container_add)(GtkContainer *container, GtkWidget *widget);
-typedef GtkIconSet* (*Ptr_gtk_icon_factory_lookup_default) (const gchar*);
-typedef GtkIconTheme* (*Ptr_gtk_icon_theme_get_default) (void);
-typedef void (*Ptr_gtk_widget_style_get)(GtkWidget *, const gchar *first_property_name, ...);
-typedef GtkTreeViewColumn* (*Ptr_gtk_tree_view_column_new)(void);
-typedef GtkWidget* (*Ptr_gtk_fixed_new)(void);
-typedef GdkPixbuf* (*Ptr_gtk_icon_set_render_icon)(GtkIconSet *, GtkStyle *, GtkTextDirection, GtkStateType, GtkIconSize, GtkWidget *,const char *);
-typedef void (*Ptr_gtk_tree_view_append_column) (GtkTreeView*, GtkTreeViewColumn*);
-typedef void (*Ptr_gtk_paint_check) (GtkStyle*,GdkWindow*, GtkStateType, GtkShadowType, const GdkRectangle *, GtkWidget *, const gchar *, gint , gint , gint , gint);
-typedef void (*Ptr_gtk_paint_box) (GtkStyle*,GdkWindow*, GtkStateType, GtkShadowType, const GdkRectangle *, GtkWidget *, const gchar *, gint , gint , gint , gint);
-typedef void (*Ptr_gtk_paint_box_gap) (GtkStyle*,GdkWindow*, GtkStateType, GtkShadowType, const GdkRectangle *, GtkWidget *, const gchar *, gint, gint, gint , gint, GtkPositionType, gint gap_x, gint gap_width);
-typedef void (*Ptr_gtk_paint_resize_grip) (GtkStyle*,GdkWindow*, GtkStateType, const GdkRectangle *, GtkWidget *, const gchar *, GdkWindowEdge, gint , gint , gint , gint);
-typedef void (*Ptr_gtk_paint_focus) (GtkStyle*,GdkWindow*, GtkStateType, const GdkRectangle *, GtkWidget *, const gchar *, gint , gint , gint , gint);
-typedef void (*Ptr_gtk_paint_shadow) (GtkStyle*,GdkWindow*, GtkStateType, GtkShadowType, const GdkRectangle *, GtkWidget *, const gchar *, gint , gint , gint , gint);
-typedef void (*Ptr_gtk_paint_slider) (GtkStyle*,GdkWindow*, GtkStateType, GtkShadowType, const GdkRectangle *, GtkWidget *, const gchar *, gint , gint , gint , gint, GtkOrientation);
-typedef void (*Ptr_gtk_paint_expander) (GtkStyle*,GdkWindow*, GtkStateType, const GdkRectangle *, GtkWidget *, const gchar *, gint , gint , GtkExpanderStyle );
-typedef void (*Ptr_gtk_paint_handle) (GtkStyle*,GdkWindow*, GtkStateType, GtkShadowType, const GdkRectangle *, GtkWidget *, const gchar *, gint , gint , gint , gint, GtkOrientation);
-typedef void (*Ptr_gtk_paint_arrow) (GtkStyle*,GdkWindow*, GtkStateType, GtkShadowType, const GdkRectangle *, GtkWidget *, const gchar *, GtkArrowType, gboolean, gint , gint , gint , gint);
-typedef void (*Ptr_gtk_paint_option) (GtkStyle*,GdkWindow*, GtkStateType, GtkShadowType, const GdkRectangle *, GtkWidget *, const gchar *, gint , gint , gint , gint);
-typedef void (*Ptr_gtk_paint_flat_box) (GtkStyle*,GdkWindow*, GtkStateType, GtkShadowType, const GdkRectangle *, GtkWidget *, const gchar *, gint , gint , gint , gint);
-typedef void (*Ptr_gtk_paint_extension) (GtkStyle *, GdkWindow *, GtkStateType, GtkShadowType, const GdkRectangle *, GtkWidget *, const gchar *, gint, gint, gint, gint, GtkPositionType);
-typedef void (*Ptr_gtk_adjustment_configure) (GtkAdjustment *, double, double, double, double, double, double);
-typedef GtkObject* (*Ptr_gtk_adjustment_new) (double, double, double, double, double, double);
-typedef void (*Ptr_gtk_paint_hline) (GtkStyle *, GdkWindow *, GtkStateType, const GdkRectangle *, GtkWidget *, const gchar *, gint, gint, gint y);
-typedef void (*Ptr_gtk_paint_vline) (GtkStyle *, GdkWindow *, GtkStateType, const GdkRectangle *, GtkWidget *, const gchar *, gint, gint, gint);
-typedef void (*Ptr_gtk_menu_item_set_submenu) (GtkMenuItem *, GtkWidget *);
-typedef void (*Ptr_gtk_container_forall) (GtkContainer *, GtkCallback, gpointer);
-typedef void (*Ptr_gtk_widget_size_allocate) (GtkWidget *, GtkAllocation*);
-typedef void (*Ptr_gtk_widget_size_request) (GtkWidget *widget, GtkRequisition *requisition);
-typedef void (*Ptr_gtk_widget_set_direction) (GtkWidget *, GtkTextDirection);
-typedef void (*Ptr_gtk_widget_path) (GtkWidget *, guint *, gchar **, gchar**);
-
-typedef void (*Ptr_gtk_toolbar_insert) (GtkToolbar *toolbar, GtkToolItem *item, int pos);
-typedef void (*Ptr_gtk_menu_shell_append)(GtkMenuShell *, GtkWidget *);
-typedef GtkType (*Ptr_gtk_container_get_type) (void);
-typedef GtkType (*Ptr_gtk_window_get_type) (void);
-typedef GtkType (*Ptr_gtk_widget_get_type) (void);
-typedef GtkStyle* (*Ptr_gtk_rc_get_style_by_paths) (GtkSettings *, const char *, const char *, GType);
-typedef gint (*Ptr_pango_font_description_get_size) (const PangoFontDescription *);
-typedef PangoWeight (*Ptr_pango_font_description_get_weight) (const PangoFontDescription *);
-typedef const char* (*Ptr_pango_font_description_get_family) (const PangoFontDescription *);
-typedef PangoStyle (*Ptr_pango_font_description_get_style) (const PangoFontDescription *desc);
-typedef gboolean (*Ptr_gtk_file_chooser_set_current_folder)(GtkFileChooser *, const gchar *);
-typedef GtkFileFilter* (*Ptr_gtk_file_filter_new)(void);
-typedef void (*Ptr_gtk_file_filter_set_name)(GtkFileFilter *, const gchar *);
-typedef void (*Ptr_gtk_file_filter_add_pattern)(GtkFileFilter *filter, const gchar *pattern);
-typedef void (*Ptr_gtk_file_chooser_add_filter)(GtkFileChooser *chooser, GtkFileFilter *filter);
-typedef void (*Ptr_gtk_file_chooser_set_filter)(GtkFileChooser *chooser, GtkFileFilter *filter);
-typedef GtkFileFilter* (*Ptr_gtk_file_chooser_get_filter)(GtkFileChooser *chooser);
-typedef gchar* (*Ptr_gtk_file_chooser_get_filename)(GtkFileChooser *chooser);
-typedef GSList* (*Ptr_gtk_file_chooser_get_filenames)(GtkFileChooser *chooser);
-typedef GtkWidget* (*Ptr_gtk_file_chooser_dialog_new)(const gchar *title,
- GtkWindow *parent,
- GtkFileChooserAction action,
- const gchar *first_button_text,
- ...);
-typedef void (*Ptr_gtk_file_chooser_set_current_name) (GtkFileChooser *, const gchar *);
-typedef gboolean (*Ptr_gtk_file_chooser_set_filename) (GtkFileChooser *chooser, const gchar *name);
-typedef gint (*Ptr_gtk_dialog_run) (GtkDialog*);
-typedef void (*Ptr_gtk_border_free)(GtkBorder *);
-
-typedef guchar* (*Ptr_gdk_pixbuf_get_pixels) (const GdkPixbuf *pixbuf);
-typedef int (*Ptr_gdk_pixbuf_get_width) (const GdkPixbuf *pixbuf);
-typedef void (*Ptr_gdk_color_free) (const GdkColor *);
-typedef int (*Ptr_gdk_pixbuf_get_height) (const GdkPixbuf *pixbuf);
-typedef GdkPixbuf* (*Ptr_gdk_pixbuf_get_from_drawable) (GdkPixbuf *dest, GdkDrawable *src,
- GdkColormap *cmap, int src_x,
- int src_y, int dest_x, int dest_y,
- int width, int height);
-typedef GdkPixmap* (*Ptr_gdk_pixmap_new) (GdkDrawable *drawable, gint width, gint height, gint depth);
-typedef GdkPixbuf* (*Ptr_gdk_pixbuf_new) (GdkColorspace colorspace, gboolean has_alpha,
- int bits_per_sample, int width, int height);
-typedef void (*Ptr_gdk_draw_rectangle) (GdkDrawable *drawable, GdkGC *gc,
- gboolean filled, gint x, gint y, gint width, gint height);
-typedef void (*Ptr_gdk_pixbuf_unref)(GdkPixbuf *);
-typedef void (*Ptr_gdk_drawable_unref)(GdkDrawable *);
-typedef gint (*Ptr_gdk_drawable_get_depth)(GdkDrawable *);
-typedef void (*Ptr_gdk_x11_window_set_user_time) (GdkWindow *window, guint32);
-typedef XID (*Ptr_gdk_x11_drawable_get_xid) (GdkDrawable *);
-typedef Display* (*Ptr_gdk_x11_drawable_get_xdisplay) ( GdkDrawable *);
-
-
-QT_BEGIN_NAMESPACE
-
-typedef QStringList (*_qt_filedialog_open_filenames_hook)(QWidget * parent, const QString &caption, const QString &dir,
- const QString &filter, QString *selectedFilter, QFileDialog::Options options);
-typedef QString (*_qt_filedialog_open_filename_hook) (QWidget * parent, const QString &caption, const QString &dir,
- const QString &filter, QString *selectedFilter, QFileDialog::Options options);
-typedef QString (*_qt_filedialog_save_filename_hook) (QWidget * parent, const QString &caption, const QString &dir,
- const QString &filter, QString *selectedFilter, QFileDialog::Options options);
-typedef QString (*_qt_filedialog_existing_directory_hook)(QWidget *parent, const QString &caption, const QString &dir,
- QFileDialog::Options options);
-
-extern Q_GUI_EXPORT _qt_filedialog_open_filename_hook qt_filedialog_open_filename_hook;
-extern Q_GUI_EXPORT _qt_filedialog_open_filenames_hook qt_filedialog_open_filenames_hook;
-extern Q_GUI_EXPORT _qt_filedialog_save_filename_hook qt_filedialog_save_filename_hook;
-extern Q_GUI_EXPORT _qt_filedialog_existing_directory_hook qt_filedialog_existing_directory_hook;
-
-class QGtkStylePrivate;
-
-class QGtkStyleFilter : public QObject
-{
-public:
- QGtkStyleFilter(QGtkStylePrivate* sp)
- : stylePrivate(sp)
- {}
-private:
- QGtkStylePrivate* stylePrivate;
- bool eventFilter(QObject *obj, QEvent *e);
-};
-
-typedef enum {
- GNOME_ICON_LOOKUP_FLAGS_NONE = 0,
- GNOME_ICON_LOOKUP_FLAGS_EMBEDDING_TEXT = 1<<0,
- GNOME_ICON_LOOKUP_FLAGS_SHOW_SMALL_IMAGES_AS_THEMSELVES = 1<<1,
- GNOME_ICON_LOOKUP_FLAGS_ALLOW_SVG_AS_THEMSELVES = 1<<2
-} GnomeIconLookupFlags;
-
-typedef enum {
- GNOME_ICON_LOOKUP_RESULT_FLAGS_NONE = 0,
- GNOME_ICON_LOOKUP_RESULT_FLAGS_THUMBNAIL = 1<<0
-} GnomeIconLookupResultFlags;
-
-struct GnomeThumbnailFactory;
-typedef gboolean (*Ptr_gnome_vfs_init) (void);
-typedef char* (*Ptr_gnome_icon_lookup_sync) (
- GtkIconTheme *icon_theme,
- GnomeThumbnailFactory *,
- const char *file_uri,
- const char *custom_icon,
- GnomeIconLookupFlags flags,
- GnomeIconLookupResultFlags *result);
-
-class QGtkStylePrivate : public QCleanlooksStylePrivate
-{
- Q_DECLARE_PUBLIC(QGtkStyle)
-public:
- QGtkStylePrivate();
- ~QGtkStylePrivate();
-
- QGtkStyleFilter filter;
-
- static GtkWidget* gtkWidget(const QHashableLatin1Literal &path);
- static GtkStyle* gtkStyle(const QHashableLatin1Literal &path = QHashableLatin1Literal("GtkWindow"));
-
- virtual void resolveGtk() const;
- virtual void initGtkMenu() const;
- virtual void initGtkTreeview() const;
- virtual void initGtkWidgets() const;
-
- static void cleanupGtkWidgets();
-
- static bool isKDE4Session();
- void applyCustomPaletteHash();
- static QFont getThemeFont();
- static bool isThemeAvailable() { return gtkStyle() != 0; }
-
- static bool getGConfBool(const QString &key, bool fallback = 0);
- static QString getGConfString(const QString &key, const QString &fallback = QString());
-
- static QString getThemeName();
- virtual int getSpinboxArrowSize() const;
-
- static void setupGtkFileChooser(GtkWidget* gtkFileChooser, QWidget *parent,
- const QString &dir, const QString &filter, QString *selectedFilter,
- QFileDialog::Options options, bool isSaveDialog = false,
- QMap<GtkFileFilter *, QString> *filterMap = 0);
-
- static QString openFilename(QWidget *parent, const QString &caption, const QString &dir, const QString &filter,
- QString *selectedFilter, QFileDialog::Options options);
- static QString saveFilename(QWidget *parent, const QString &caption, const QString &dir, const QString &filter,
- QString *selectedFilter, QFileDialog::Options options);
- static QString openDirectory(QWidget *parent, const QString &caption, const QString &dir, QFileDialog::Options options);
- static QStringList openFilenames(QWidget *parent, const QString &caption, const QString &dir, const QString &filter,
- QString *selectedFilter, QFileDialog::Options options);
- static QIcon getFilesystemIcon(const QFileInfo &);
-
- static Ptr_gtk_container_forall gtk_container_forall;
- static Ptr_gtk_init gtk_init;
- static Ptr_gtk_style_attach gtk_style_attach;
- static Ptr_gtk_window_new gtk_window_new;
- static Ptr_gtk_widget_destroy gtk_widget_destroy;
- static Ptr_gtk_widget_realize gtk_widget_realize;
- static Ptr_gtk_widget_set_default_direction gtk_widget_set_default_direction;
- static Ptr_gtk_widget_modify_color gtk_widget_modify_fg;
- static Ptr_gtk_widget_modify_color gtk_widget_modify_bg;
- static Ptr_gtk_menu_item_new_with_label gtk_menu_item_new_with_label;
- static Ptr_gtk_arrow_new gtk_arrow_new;
- static Ptr_gtk_check_menu_item_new_with_label gtk_check_menu_item_new_with_label;
- static Ptr_gtk_menu_bar_new gtk_menu_bar_new;
- static Ptr_gtk_menu_new gtk_menu_new;
- static Ptr_gtk_expander_new gtk_expander_new;
- static Ptr_gtk_button_new gtk_button_new;
- static Ptr_gtk_tool_button_new gtk_tool_button_new;
- static Ptr_gtk_hbutton_box_new gtk_hbutton_box_new;
- static Ptr_gtk_check_button_new gtk_check_button_new;
- static Ptr_gtk_radio_button_new gtk_radio_button_new;
- static Ptr_gtk_spin_button_new gtk_spin_button_new;
- static Ptr_gtk_separator_tool_item_new gtk_separator_tool_item_new;
- static Ptr_gtk_toolbar_insert gtk_toolbar_insert;
- static Ptr_gtk_frame_new gtk_frame_new;
- static Ptr_gtk_statusbar_new gtk_statusbar_new;
- static Ptr_gtk_entry_new gtk_entry_new;
- static Ptr_gtk_hscale_new gtk_hscale_new;
- static Ptr_gtk_vscale_new gtk_vscale_new;
- static Ptr_gtk_hscrollbar_new gtk_hscrollbar_new;
- static Ptr_gtk_vscrollbar_new gtk_vscrollbar_new;
- static Ptr_gtk_scrolled_window_new gtk_scrolled_window_new;
- static Ptr_gtk_notebook_new gtk_notebook_new;
- static Ptr_gtk_toolbar_new gtk_toolbar_new;
- static Ptr_gtk_tree_view_new gtk_tree_view_new;
- static Ptr_gtk_tree_view_get_column gtk_tree_view_get_column;
- static Ptr_gtk_combo_box_new gtk_combo_box_new;
- static Ptr_gtk_combo_box_entry_new gtk_combo_box_entry_new;
- static Ptr_gtk_progress_bar_new gtk_progress_bar_new;
- static Ptr_gtk_container_add gtk_container_add;
- static Ptr_gtk_menu_shell_append gtk_menu_shell_append;
- static Ptr_gtk_progress_configure gtk_progress_configure;
- static Ptr_gtk_range_get_adjustment gtk_range_get_adjustment;
- static Ptr_gtk_range_set_adjustment gtk_range_set_adjustment;
- static Ptr_gtk_range_set_inverted gtk_range_set_inverted;
- static Ptr_gtk_icon_factory_lookup_default gtk_icon_factory_lookup_default;
- static Ptr_gtk_icon_theme_get_default gtk_icon_theme_get_default;
- static Ptr_gtk_widget_style_get gtk_widget_style_get;
- static Ptr_gtk_icon_set_render_icon gtk_icon_set_render_icon;
- static Ptr_gtk_fixed_new gtk_fixed_new;
- static Ptr_gtk_tree_view_column_new gtk_tree_view_column_new;
- static Ptr_gtk_tree_view_append_column gtk_tree_view_append_column;
- static Ptr_gtk_paint_check gtk_paint_check;
- static Ptr_gtk_paint_box gtk_paint_box;
- static Ptr_gtk_paint_box_gap gtk_paint_box_gap;
- static Ptr_gtk_paint_flat_box gtk_paint_flat_box;
- static Ptr_gtk_paint_option gtk_paint_option;
- static Ptr_gtk_paint_extension gtk_paint_extension;
- static Ptr_gtk_paint_slider gtk_paint_slider;
- static Ptr_gtk_paint_shadow gtk_paint_shadow;
- static Ptr_gtk_paint_resize_grip gtk_paint_resize_grip;
- static Ptr_gtk_paint_focus gtk_paint_focus;
- static Ptr_gtk_paint_arrow gtk_paint_arrow;
- static Ptr_gtk_paint_handle gtk_paint_handle;
- static Ptr_gtk_paint_expander gtk_paint_expander;
- static Ptr_gtk_adjustment_configure gtk_adjustment_configure;
- static Ptr_gtk_adjustment_new gtk_adjustment_new;
- static Ptr_gtk_paint_vline gtk_paint_vline;
- static Ptr_gtk_paint_hline gtk_paint_hline;
- static Ptr_gtk_menu_item_set_submenu gtk_menu_item_set_submenu;
- static Ptr_gtk_settings_get_default gtk_settings_get_default;
- static Ptr_gtk_separator_menu_item_new gtk_separator_menu_item_new;
- static Ptr_gtk_widget_size_allocate gtk_widget_size_allocate;
- static Ptr_gtk_widget_size_request gtk_widget_size_request;
- static Ptr_gtk_widget_set_direction gtk_widget_set_direction;
- static Ptr_gtk_widget_path gtk_widget_path;
- static Ptr_gtk_container_get_type gtk_container_get_type;
- static Ptr_gtk_window_get_type gtk_window_get_type;
- static Ptr_gtk_widget_get_type gtk_widget_get_type;
- static Ptr_gtk_rc_get_style_by_paths gtk_rc_get_style_by_paths;
- static Ptr_gtk_check_version gtk_check_version;
- static Ptr_gtk_border_free gtk_border_free;
-
- static Ptr_pango_font_description_get_size pango_font_description_get_size;
- static Ptr_pango_font_description_get_weight pango_font_description_get_weight;
- static Ptr_pango_font_description_get_family pango_font_description_get_family;
- static Ptr_pango_font_description_get_style pango_font_description_get_style;
-
- static Ptr_gtk_file_filter_new gtk_file_filter_new;
- static Ptr_gtk_file_filter_set_name gtk_file_filter_set_name;
- static Ptr_gtk_file_filter_add_pattern gtk_file_filter_add_pattern;
- static Ptr_gtk_file_chooser_add_filter gtk_file_chooser_add_filter;
- static Ptr_gtk_file_chooser_set_filter gtk_file_chooser_set_filter;
- static Ptr_gtk_file_chooser_get_filter gtk_file_chooser_get_filter;
- static Ptr_gtk_file_chooser_dialog_new gtk_file_chooser_dialog_new;
- static Ptr_gtk_file_chooser_set_current_folder gtk_file_chooser_set_current_folder;
- static Ptr_gtk_file_chooser_get_filename gtk_file_chooser_get_filename;
- static Ptr_gtk_file_chooser_get_filenames gtk_file_chooser_get_filenames;
- static Ptr_gtk_file_chooser_set_current_name gtk_file_chooser_set_current_name;
- static Ptr_gtk_dialog_run gtk_dialog_run;
- static Ptr_gtk_file_chooser_set_filename gtk_file_chooser_set_filename;
-
- static Ptr_gdk_pixbuf_get_pixels gdk_pixbuf_get_pixels;
- static Ptr_gdk_pixbuf_get_width gdk_pixbuf_get_width;
- static Ptr_gdk_pixbuf_get_height gdk_pixbuf_get_height;
- static Ptr_gdk_pixmap_new gdk_pixmap_new;
- static Ptr_gdk_pixbuf_new gdk_pixbuf_new;
- static Ptr_gdk_pixbuf_get_from_drawable gdk_pixbuf_get_from_drawable;
- static Ptr_gdk_draw_rectangle gdk_draw_rectangle;
- static Ptr_gdk_pixbuf_unref gdk_pixbuf_unref;
- static Ptr_gdk_drawable_unref gdk_drawable_unref;
- static Ptr_gdk_drawable_get_depth gdk_drawable_get_depth;
- static Ptr_gdk_color_free gdk_color_free;
- static Ptr_gdk_x11_window_set_user_time gdk_x11_window_set_user_time;
- static Ptr_gdk_x11_drawable_get_xid gdk_x11_drawable_get_xid;
- static Ptr_gdk_x11_drawable_get_xdisplay gdk_x11_drawable_get_xdisplay;
-
- static Ptr_gconf_client_get_default gconf_client_get_default;
- static Ptr_gconf_client_get_string gconf_client_get_string;
- static Ptr_gconf_client_get_bool gconf_client_get_bool;
-
- static Ptr_gnome_icon_lookup_sync gnome_icon_lookup_sync;
- static Ptr_gnome_vfs_init gnome_vfs_init;
-
- virtual QPalette gtkWidgetPalette(const QHashableLatin1Literal &gtkWidgetName) const;
-
-protected:
- typedef QHash<QHashableLatin1Literal, GtkWidget*> WidgetMap;
-
- static inline void destroyWidgetMap()
- {
- cleanupGtkWidgets();
- delete widgetMap;
- widgetMap = 0;
- }
-
- static inline WidgetMap *gtkWidgetMap()
- {
- if (!widgetMap) {
- widgetMap = new WidgetMap();
- qAddPostRoutine(destroyWidgetMap);
- }
- return widgetMap;
- }
-
- static QStringList extract_filter(const QString &rawFilter);
-
- virtual GtkWidget* getTextColorWidget() const;
- static void setupGtkWidget(GtkWidget* widget);
- static void addWidgetToMap(GtkWidget* widget);
- static void addAllSubWidgets(GtkWidget *widget, gpointer v = 0);
- static void addWidget(GtkWidget *widget);
- static void removeWidgetFromMap(const QHashableLatin1Literal &path);
-
- virtual void init();
-
-private:
- static QList<QGtkStylePrivate *> instances;
- static WidgetMap *widgetMap;
- friend class QGtkStyleUpdateScheduler;
-};
-
-// 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
-#endif // QGTKSTYLE_P_H
diff --git a/src/gui/styles/qmacstyle_mac.h b/src/gui/styles/qmacstyle_mac.h
deleted file mode 100644
index c51efb9e67..0000000000
--- a/src/gui/styles/qmacstyle_mac.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QMACSTYLE_MAC_H
-#define QMACSTYLE_MAC_H
-
-#include <QtGui/qwindowsstyle.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#if defined(Q_WS_MAC) && !defined(QT_NO_STYLE_MAC)
-
-class QPalette;
-
-#if defined(QT_PLUGIN)
-#define Q_GUI_EXPORT_STYLE_MAC
-#else
-#define Q_GUI_EXPORT_STYLE_MAC Q_GUI_EXPORT
-#endif
-
-class QPushButton;
-class QStyleOptionButton;
-class QMacStylePrivate;
-class Q_GUI_EXPORT_STYLE_MAC QMacStyle : public QWindowsStyle
-{
- Q_OBJECT
-public:
- QMacStyle();
- virtual ~QMacStyle();
-
- void polish(QWidget *w);
- void unpolish(QWidget *w);
-
- void polish(QApplication*);
- void unpolish(QApplication*);
-
- void polish(QPalette &pal);
-
- void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p,
- const QWidget *w = 0) const;
- void drawControl(ControlElement element, const QStyleOption *opt, QPainter *p,
- const QWidget *w = 0) const;
- QRect subElementRect(SubElement r, const QStyleOption *opt, const QWidget *widget = 0) const;
- void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p,
- const QWidget *w = 0) const;
- SubControl hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt,
- const QPoint &pt, const QWidget *w = 0) const;
- QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc,
- const QWidget *w = 0) const;
- QSize sizeFromContents(ContentsType ct, const QStyleOption *opt,
- const QSize &contentsSize, const QWidget *w = 0) const;
-
- int pixelMetric(PixelMetric pm, const QStyleOption *opt = 0, const QWidget *widget = 0) const;
-
- QPalette standardPalette() const;
-
- virtual int styleHint(StyleHint sh, const QStyleOption *opt = 0, const QWidget *w = 0,
- QStyleHintReturn *shret = 0) const;
-
- enum FocusRectPolicy { FocusEnabled, FocusDisabled, FocusDefault };
- static void setFocusRectPolicy(QWidget *w, FocusRectPolicy policy);
- static FocusRectPolicy focusRectPolicy(const QWidget *w);
-
- enum WidgetSizePolicy { SizeSmall, SizeLarge, SizeMini, SizeDefault
-#ifdef QT3_SUPPORT
- , SizeNone = SizeDefault
-#endif
- };
- static void setWidgetSizePolicy(const QWidget *w, WidgetSizePolicy policy);
- static WidgetSizePolicy widgetSizePolicy(const QWidget *w);
-
- QPixmap standardPixmap(StandardPixmap sp, const QStyleOption *opt,
- const QWidget *widget = 0) const;
-
- QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap,
- const QStyleOption *opt) const;
-
- virtual void drawItemText(QPainter *p, const QRect &r, int flags, const QPalette &pal,
- bool enabled, const QString &text, QPalette::ColorRole textRole = QPalette::NoRole) const;
-
- bool event(QEvent *e);
-
-protected Q_SLOTS:
- QIcon standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *opt = 0,
- const QWidget *widget = 0) const;
- int layoutSpacingImplementation(QSizePolicy::ControlType control1,
- QSizePolicy::ControlType control2,
- Qt::Orientation orientation,
- const QStyleOption *option = 0,
- const QWidget *widget = 0) const;
-
-private:
- Q_DISABLE_COPY(QMacStyle)
-
- QMacStylePrivate *d;
-
- friend bool qt_mac_buttonIsRenderedFlat(const QPushButton *pushButton, const QStyleOptionButton *option);
-};
-
-#endif // Q_WS_MAC
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QMACSTYLE_H
diff --git a/src/gui/styles/qmacstyle_mac.mm b/src/gui/styles/qmacstyle_mac.mm
deleted file mode 100644
index 74e3440a54..0000000000
--- a/src/gui/styles/qmacstyle_mac.mm
+++ /dev/null
@@ -1,6042 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*
- Note: The qdoc comments for QMacStyle are contained in
- .../doc/src/qstyles.qdoc.
-*/
-
-#include "qmacstyle_mac.h"
-
-#if defined(Q_WS_MAC) && !defined(QT_NO_STYLE_MAC)
-#define QMAC_QAQUASTYLE_SIZE_CONSTRAIN
-//#define DEBUG_SIZE_CONSTRAINT
-
-#include <private/qapplication_p.h>
-#include <private/qcombobox_p.h>
-#include <private/qmacstylepixmaps_mac_p.h>
-#include <private/qpaintengine_mac_p.h>
-#include <private/qpainter_p.h>
-#include <private/qprintengine_mac_p.h>
-#include <qapplication.h>
-#include <qbitmap.h>
-#include <qcheckbox.h>
-#include <qcombobox.h>
-#include <qdialogbuttonbox.h>
-#include <qdockwidget.h>
-#include <qevent.h>
-#include <qfocusframe.h>
-#include <qformlayout.h>
-#include <qgroupbox.h>
-#include <qhash.h>
-#include <qheaderview.h>
-#include <qlayout.h>
-#include <qlineedit.h>
-#include <qlistview.h>
-#include <qmainwindow.h>
-#include <qmap.h>
-#include <qmenubar.h>
-#include <qpaintdevice.h>
-#include <qpainter.h>
-#include <qpixmapcache.h>
-#include <qpointer.h>
-#include <qprogressbar.h>
-#include <qpushbutton.h>
-#include <qradiobutton.h>
-#include <qrubberband.h>
-#include <qsizegrip.h>
-#include <qspinbox.h>
-#include <qsplitter.h>
-#include <qstyleoption.h>
-#include <qtextedit.h>
-#include <qtextstream.h>
-#include <qtoolbar.h>
-#include <qtoolbutton.h>
-#include <qtreeview.h>
-#include <qtableview.h>
-#include <qwizard.h>
-#include <qdebug.h>
-#include <qlibrary.h>
-#include <qdatetimeedit.h>
-#include <qmath.h>
-#include <QtGui/qgraphicsproxywidget.h>
-#include <QtGui/qgraphicsview.h>
-#include <private/qt_cocoa_helpers_mac_p.h>
-#include "qmacstyle_mac_p.h"
-#include <private/qstylehelper_p.h>
-
-QT_BEGIN_NAMESPACE
-
-// The following constants are used for adjusting the size
-// of push buttons so that they are drawn inside their bounds.
-const int QMacStylePrivate::PushButtonLeftOffset = 6;
-const int QMacStylePrivate::PushButtonTopOffset = 4;
-const int QMacStylePrivate::PushButtonRightOffset = 12;
-const int QMacStylePrivate::PushButtonBottomOffset = 12;
-const int QMacStylePrivate::MiniButtonH = 26;
-const int QMacStylePrivate::SmallButtonH = 30;
-const int QMacStylePrivate::BevelButtonW = 50;
-const int QMacStylePrivate::BevelButtonH = 22;
-const int QMacStylePrivate::PushButtonContentPadding = 6;
-
-// These colors specify the titlebar gradient colors on
-// Leopard. Ideally we should get them from the system.
-static const QColor titlebarGradientActiveBegin(220, 220, 220);
-static const QColor titlebarGradientActiveEnd(151, 151, 151);
-static const QColor titlebarSeparatorLineActive(111, 111, 111);
-static const QColor titlebarGradientInactiveBegin(241, 241, 241);
-static const QColor titlebarGradientInactiveEnd(207, 207, 207);
-static const QColor titlebarSeparatorLineInactive(131, 131, 131);
-
-// Gradient colors used for the dock widget title bar and
-// non-unifed tool bar bacground.
-static const QColor mainWindowGradientBegin(240, 240, 240);
-static const QColor mainWindowGradientEnd(200, 200, 200);
-
-static const int DisclosureOffset = 4;
-
-// Resolve these at run-time, since the functions was moved in Leopard.
-typedef HIRect * (*PtrHIShapeGetBounds)(HIShapeRef, HIRect *);
-static PtrHIShapeGetBounds ptrHIShapeGetBounds = 0;
-
-static int closeButtonSize = 12;
-
-extern QRegion qt_mac_convert_mac_region(RgnHandle); //qregion_mac.cpp
-
-static bool isVerticalTabs(const QTabBar::Shape shape) {
- return (shape == QTabBar::RoundedEast
- || shape == QTabBar::TriangularEast
- || shape == QTabBar::RoundedWest
- || shape == QTabBar::TriangularWest);
-}
-
-void drawTabCloseButton(QPainter *p, bool hover, bool active, bool selected)
-{
- // draw background circle
- p->setRenderHints(QPainter::Antialiasing);
- QRect rect(0, 0, closeButtonSize, closeButtonSize);
- QColor background;
- if (hover) {
- background = QColor(124, 124, 124);
- } else {
- if (active) {
- if (selected)
- background = QColor(104, 104, 104);
- else
- background = QColor(83, 83, 83);
- } else {
- if (selected)
- background = QColor(144, 144, 144);
- else
- background = QColor(114, 114, 114);
- }
- }
- p->setPen(Qt::transparent);
- p->setBrush(background);
- p->drawEllipse(rect);
-
- // draw cross
- int min = 3;
- int max = 9;
- QPen crossPen;
- crossPen.setColor(QColor(194, 194, 194));
- crossPen.setWidthF(1.3);
- crossPen.setCapStyle(Qt::FlatCap);
- p->setPen(crossPen);
- p->drawLine(min, min, max, max);
- p->drawLine(min, max, max, min);
-}
-
-QRect rotateTabPainter(QPainter *p, QTabBar::Shape shape, QRect tabRect)
-{
- if (isVerticalTabs(shape)) {
- int newX, newY, newRot;
- if (shape == QTabBar::RoundedEast
- || shape == QTabBar::TriangularEast) {
- newX = tabRect.width();
- newY = tabRect.y();
- newRot = 90;
- } else {
- newX = 0;
- newY = tabRect.y() + tabRect.height();
- newRot = -90;
- }
- tabRect.setRect(0, 0, tabRect.height(), tabRect.width());
- QMatrix m;
- m.translate(newX, newY);
- m.rotate(newRot);
- p->setMatrix(m, true);
- }
- return tabRect;
-}
-
-void drawTabShape(QPainter *p, const QStyleOptionTabV3 *tabOpt)
-{
- QRect r = tabOpt->rect;
- p->translate(tabOpt->rect.x(), tabOpt->rect.y());
- r.moveLeft(0);
- r.moveTop(0);
- QRect tabRect = rotateTabPainter(p, tabOpt->shape, r);
-
- int width = tabRect.width();
- int height = 20;
- bool active = (tabOpt->state & QStyle::State_Active);
- bool selected = (tabOpt->state & QStyle::State_Selected);
-
- if (selected) {
- QRect rect(1, 0, width - 2, height);
-
- // fill body
- if (active) {
- int d = (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_6) ? 16 : 0;
- p->fillRect(rect, QColor(151 + d, 151 + d, 151 + d));
- } else {
- int d = (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_6) ? 9 : 0;
- QLinearGradient gradient(rect.topLeft(), rect.bottomLeft());
- gradient.setColorAt(0, QColor(207 + d, 207 + d, 207 + d));
- gradient.setColorAt(0.5, QColor(206 + d, 206 + d, 206 + d));
- gradient.setColorAt(1, QColor(201 + d, 201 + d, 201 + d));
- p->fillRect(rect, gradient);
- }
-
- // draw border
- QColor borderSides;
- QColor borderBottom;
- if (active) {
- borderSides = QColor(88, 88, 88);
- borderBottom = QColor(88, 88, 88);
- } else {
- borderSides = QColor(121, 121, 121);
- borderBottom = QColor(116, 116, 116);
- }
-
- p->setPen(borderSides);
-
- int bottom = height;
- // left line
- p->drawLine(0, 1, 0, bottom-2);
- // right line
- p->drawLine(width-1, 1, width-1, bottom-2);
-
- // bottom line
- if (active) {
- p->setPen(QColor(168, 168, 168));
- p->drawLine(3, bottom-1, width-3, bottom-1);
- }
- p->setPen(borderBottom);
- p->drawLine(2, bottom, width-2, bottom);
-
- int w = 3;
- QRectF rectangleLeft(1, height - w, w, w);
- QRectF rectangleRight(width - 2, height - 1, w, w);
- int startAngle = 180 * 16;
- int spanAngle = 90 * 16;
- p->setRenderHint(QPainter::Antialiasing);
- p->drawArc(rectangleLeft, startAngle, spanAngle);
- p->drawArc(rectangleRight, startAngle, -spanAngle);
- } else {
- // when the mouse is over non selected tabs they get a new color
- bool hover = (tabOpt->state & QStyle::State_MouseOver);
- if (hover) {
- QRect rect(1, 2, width - 1, height - 1);
- p->fillRect(rect, QColor(110, 110, 110));
- }
-
- // seperator lines between tabs
- bool west = (tabOpt->shape == QTabBar::RoundedWest || tabOpt->shape == QTabBar::TriangularWest);
- bool drawOnRight = !west;
- if ((!drawOnRight && tabOpt->selectedPosition != QStyleOptionTab::NextIsSelected)
- || (drawOnRight && tabOpt->selectedPosition != QStyleOptionTab::NextIsSelected)) {
- QColor borderColor;
- QColor borderHighlightColor;
- if (active) {
- borderColor = QColor(64, 64, 64);
- borderHighlightColor = QColor(140, 140, 140);
- } else {
- borderColor = QColor(135, 135, 135);
- borderHighlightColor = QColor(178, 178, 178);
- }
-
- int x = drawOnRight ? width : 0;
-
- // tab seperator line
- p->setPen(borderColor);
- p->drawLine(x, 2, x, height + 1);
-
- // tab seperator highlight
- p->setPen(borderHighlightColor);
- p->drawLine(x-1, 2, x-1, height + 1);
- p->drawLine(x+1, 2, x+1, height + 1);
- }
- }
-}
-
-void drawTabBase(QPainter *p, const QStyleOptionTabBarBaseV2 *tbb, const QWidget *w)
-{
- QRect r = tbb->rect;
- if (isVerticalTabs(tbb->shape)) {
- r.setWidth(w->width());
- } else {
- r.setHeight(w->height());
- }
- QRect tabRect = rotateTabPainter(p, tbb->shape, r);
- int width = tabRect.width();
- int height = tabRect.height();
- bool active = (tbb->state & QStyle::State_Active);
-
- // top border lines
- QColor borderHighlightTop;
- QColor borderTop;
- if (active) {
- borderTop = QColor(64, 64, 64);
- borderHighlightTop = QColor(174, 174, 174);
- } else {
- borderTop = QColor(135, 135, 135);
- borderHighlightTop = QColor(207, 207, 207);
- }
- p->setPen(borderHighlightTop);
- p->drawLine(tabRect.x(), 0, width, 0);
- p->setPen(borderTop);
- p->drawLine(tabRect.x(), 1, width, 1);
-
- // center block
- QRect centralRect(tabRect.x(), 2, width, height - 2);
- if (active) {
- QColor mainColor = QColor(120, 120, 120);
- p->fillRect(centralRect, mainColor);
- } else {
- QLinearGradient gradient(centralRect.topLeft(), centralRect.bottomLeft());
- gradient.setColorAt(0, QColor(165, 165, 165));
- gradient.setColorAt(0.5, QColor(164, 164, 164));
- gradient.setColorAt(1, QColor(158, 158, 158));
- p->fillRect(centralRect, gradient);
- }
-
- // bottom border lines
- QColor borderHighlightBottom;
- QColor borderBottom;
- if (active) {
- borderHighlightBottom = QColor(153, 153, 153);
- borderBottom = QColor(64, 64, 64);
- } else {
- borderHighlightBottom = QColor(177, 177, 177);
- borderBottom = QColor(127, 127, 127);
- }
- p->setPen(borderHighlightBottom);
- p->drawLine(tabRect.x(), height - 2, width, height - 2);
- p->setPen(borderBottom);
- p->drawLine(tabRect.x(), height - 1, width, height - 1);
-}
-
-static int getControlSize(const QStyleOption *option, const QWidget *widget)
-{
- if (option) {
- if (option->state & (QStyle::State_Small | QStyle::State_Mini))
- return (option->state & QStyle::State_Mini) ? QAquaSizeMini : QAquaSizeSmall;
- } else if (widget) {
- switch (QMacStyle::widgetSizePolicy(widget)) {
- case QMacStyle::SizeSmall:
- return QAquaSizeSmall;
- case QMacStyle::SizeMini:
- return QAquaSizeMini;
- default:
- break;
- }
- }
- return QAquaSizeLarge;
-}
-
-
-static inline bool isTreeView(const QWidget *widget)
-{
- return (widget && widget->parentWidget() &&
- (qobject_cast<const QTreeView *>(widget->parentWidget())
-#ifdef QT3_SUPPORT
- || widget->parentWidget()->inherits("Q3ListView")
-#endif
- ));
-}
-
-QString qt_mac_removeMnemonics(const QString &original)
-{
- QString returnText(original.size(), 0);
- int finalDest = 0;
- int currPos = 0;
- int l = original.length();
- while (l) {
- if (original.at(currPos) == QLatin1Char('&')
- && (l == 1 || original.at(currPos + 1) != QLatin1Char('&'))) {
- ++currPos;
- --l;
- if (l == 0)
- break;
- }
- returnText[finalDest] = original.at(currPos);
- ++currPos;
- ++finalDest;
- --l;
- }
- returnText.truncate(finalDest);
- return returnText;
-}
-
-static inline ThemeTabDirection getTabDirection(QTabBar::Shape shape)
-{
- ThemeTabDirection ttd;
- switch (shape) {
- case QTabBar::RoundedSouth:
- case QTabBar::TriangularSouth:
- ttd = kThemeTabSouth;
- break;
- default: // Added to remove the warning, since all values are taken care of, really!
- case QTabBar::RoundedNorth:
- case QTabBar::TriangularNorth:
- ttd = kThemeTabNorth;
- break;
- case QTabBar::RoundedWest:
- case QTabBar::TriangularWest:
- ttd = kThemeTabWest;
- break;
- case QTabBar::RoundedEast:
- case QTabBar::TriangularEast:
- ttd = kThemeTabEast;
- break;
- }
- return ttd;
-}
-
-QT_BEGIN_INCLUDE_NAMESPACE
-#include "moc_qmacstyle_mac.cpp"
-#include "moc_qmacstyle_mac_p.cpp"
-QT_END_INCLUDE_NAMESPACE
-
-/*****************************************************************************
- External functions
- *****************************************************************************/
-extern CGContextRef qt_mac_cg_context(const QPaintDevice *); //qpaintdevice_mac.cpp
-extern QRegion qt_mac_convert_mac_region(HIShapeRef); //qregion_mac.cpp
-void qt_mac_dispose_rgn(RgnHandle r); //qregion_mac.cpp
-extern QPaintDevice *qt_mac_safe_pdev; //qapplication_mac.cpp
-
-/*****************************************************************************
- QMacCGStyle globals
- *****************************************************************************/
-const int qt_mac_hitheme_version = 0; //the HITheme version we speak
-const int macItemFrame = 2; // menu item frame width
-const int macItemHMargin = 3; // menu item hor text margin
-const int macItemVMargin = 2; // menu item ver text margin
-const int macRightBorder = 12; // right border on mac
-const ThemeWindowType QtWinType = kThemeDocumentWindow; // Window type we use for QTitleBar.
-QPixmap *qt_mac_backgroundPattern = 0; // stores the standard widget background.
-
-/*****************************************************************************
- QMacCGStyle utility functions
- *****************************************************************************/
-static inline int qt_mac_hitheme_tab_version()
-{
- return 1;
-}
-
-static inline HIRect qt_hirectForQRect(const QRect &convertRect, const QRect &rect = QRect())
-{
- return CGRectMake(convertRect.x() + rect.x(), convertRect.y() + rect.y(),
- convertRect.width() - rect.width(), convertRect.height() - rect.height());
-}
-
-static inline const QRect qt_qrectForHIRect(const HIRect &hirect)
-{
- return QRect(QPoint(int(hirect.origin.x), int(hirect.origin.y)),
- QSize(int(hirect.size.width), int(hirect.size.height)));
-}
-
-inline bool qt_mac_is_metal(const QWidget *w)
-{
- for (; w; w = w->parentWidget()) {
- if (w->testAttribute(Qt::WA_MacBrushedMetal))
- return true;
- if (w->isWindow() && w->testAttribute(Qt::WA_WState_Created)) { // If not created will fall through to the opaque check and be fine anyway.
- return macWindowIsTextured(qt_mac_window_for(w));
- }
- if (w->d_func()->isOpaque)
- break;
- }
- return false;
-}
-
-static int qt_mac_aqua_get_metric(ThemeMetric met)
-{
- SInt32 ret;
- GetThemeMetric(met, &ret);
- return ret;
-}
-
-static QSize qt_aqua_get_known_size(QStyle::ContentsType ct, const QWidget *widg, QSize szHint,
- QAquaWidgetSize sz)
-{
- QSize ret(-1, -1);
- if (sz != QAquaSizeSmall && sz != QAquaSizeLarge && sz != QAquaSizeMini) {
- qDebug("Not sure how to return this...");
- return ret;
- }
- if ((widg && widg->testAttribute(Qt::WA_SetFont)) || !QApplication::desktopSettingsAware()) {
- // If you're using a custom font and it's bigger than the default font,
- // then no constraints for you. If you are smaller, we can try to help you out
- QFont font = qt_app_fonts_hash()->value(widg->metaObject()->className(), QFont());
- if (widg->font().pointSize() > font.pointSize())
- return ret;
- }
-
- if (ct == QStyle::CT_CustomBase && widg) {
- if (qobject_cast<const QPushButton *>(widg))
- ct = QStyle::CT_PushButton;
- else if (qobject_cast<const QRadioButton *>(widg))
- ct = QStyle::CT_RadioButton;
- else if (qobject_cast<const QCheckBox *>(widg))
- ct = QStyle::CT_CheckBox;
- else if (qobject_cast<const QComboBox *>(widg))
- ct = QStyle::CT_ComboBox;
- else if (qobject_cast<const QToolButton *>(widg))
- ct = QStyle::CT_ToolButton;
- else if (qobject_cast<const QSlider *>(widg))
- ct = QStyle::CT_Slider;
- else if (qobject_cast<const QProgressBar *>(widg))
- ct = QStyle::CT_ProgressBar;
- else if (qobject_cast<const QLineEdit *>(widg))
- ct = QStyle::CT_LineEdit;
- else if (qobject_cast<const QHeaderView *>(widg)
-#ifdef QT3_SUPPORT
- || widg->inherits("Q3Header")
-#endif
- )
- ct = QStyle::CT_HeaderSection;
- else if (qobject_cast<const QMenuBar *>(widg)
-#ifdef QT3_SUPPORT
- || widg->inherits("Q3MenuBar")
-#endif
- )
- ct = QStyle::CT_MenuBar;
- else if (qobject_cast<const QSizeGrip *>(widg))
- ct = QStyle::CT_SizeGrip;
- else
- return ret;
- }
-
- switch (ct) {
- case QStyle::CT_PushButton: {
- const QPushButton *psh = qobject_cast<const QPushButton *>(widg);
- // If this comparison is false, then the widget was not a push button.
- // This is bad and there's very little we can do since we were requested to find a
- // sensible size for a widget that pretends to be a QPushButton but is not.
- if(psh) {
- QString buttonText = qt_mac_removeMnemonics(psh->text());
- if (buttonText.contains(QLatin1Char('\n')))
- ret = QSize(-1, -1);
- else if (sz == QAquaSizeLarge)
- ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricPushButtonHeight));
- else if (sz == QAquaSizeSmall)
- ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricSmallPushButtonHeight));
- else if (sz == QAquaSizeMini)
- ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricMiniPushButtonHeight));
-
- if (!psh->icon().isNull()){
- // If the button got an icon, and the icon is larger than the
- // button, we can't decide on a default size
- ret.setWidth(-1);
- if (ret.height() < psh->iconSize().height())
- ret.setHeight(-1);
- }
- else if (buttonText == QLatin1String("OK") || buttonText == QLatin1String("Cancel")){
- // Aqua Style guidelines restrict the size of OK and Cancel buttons to 68 pixels.
- // However, this doesn't work for German, therefore only do it for English,
- // I suppose it would be better to do some sort of lookups for languages
- // that like to have really long words.
- ret.setWidth(77 - 8);
- }
- } else {
- // The only sensible thing to do is to return whatever the style suggests...
- if (sz == QAquaSizeLarge)
- ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricPushButtonHeight));
- else if (sz == QAquaSizeSmall)
- ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricSmallPushButtonHeight));
- else if (sz == QAquaSizeMini)
- ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricMiniPushButtonHeight));
- else
- // Since there's no default size we return the large size...
- ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricPushButtonHeight));
- }
-#if 0 //Not sure we are applying the rules correctly for RadioButtons/CheckBoxes --Sam
- } else if (ct == QStyle::CT_RadioButton) {
- QRadioButton *rdo = static_cast<QRadioButton *>(widg);
- // Exception for case where multiline radio button text requires no size constrainment
- if (rdo->text().find('\n') != -1)
- return ret;
- if (sz == QAquaSizeLarge)
- ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricRadioButtonHeight));
- else if (sz == QAquaSizeSmall)
- ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricSmallRadioButtonHeight));
- else if (sz == QAquaSizeMini)
- ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricMiniRadioButtonHeight));
- } else if (ct == QStyle::CT_CheckBox) {
- if (sz == QAquaSizeLarge)
- ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricCheckBoxHeight));
- else if (sz == QAquaSizeSmall)
- ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricSmallCheckBoxHeight));
- else if (sz == QAquaSizeMini)
- ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricMiniCheckBoxHeight));
-#endif
- break;
- }
- case QStyle::CT_SizeGrip:
- if (sz == QAquaSizeLarge || sz == QAquaSizeSmall) {
- HIRect r;
- HIPoint p = { 0, 0 };
- HIThemeGrowBoxDrawInfo gbi;
- gbi.version = 0;
- gbi.state = kThemeStateActive;
- gbi.kind = kHIThemeGrowBoxKindNormal;
- gbi.direction = QApplication::isRightToLeft() ? kThemeGrowLeft | kThemeGrowDown
- : kThemeGrowRight | kThemeGrowDown;
- gbi.size = sz == QAquaSizeSmall ? kHIThemeGrowBoxSizeSmall : kHIThemeGrowBoxSizeNormal;
- if (HIThemeGetGrowBoxBounds(&p, &gbi, &r) == noErr)
- ret = QSize(r.size.width, r.size.height);
- }
- break;
- case QStyle::CT_ComboBox:
- switch (sz) {
- case QAquaSizeLarge:
- ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricPopupButtonHeight));
- break;
- case QAquaSizeSmall:
- ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricSmallPopupButtonHeight));
- break;
- case QAquaSizeMini:
- ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricMiniPopupButtonHeight));
- break;
- default:
- break;
- }
- break;
- case QStyle::CT_ToolButton:
- if (sz == QAquaSizeSmall) {
- int width = 0, height = 0;
- if (szHint == QSize(-1, -1)) { //just 'guess'..
- const QToolButton *bt = qobject_cast<const QToolButton *>(widg);
- // If this conversion fails then the widget was not what it claimed to be.
- if(bt) {
- if (!bt->icon().isNull()) {
- QSize iconSize = bt->iconSize();
- QSize pmSize = bt->icon().actualSize(QSize(32, 32), QIcon::Normal);
- width = qMax(width, qMax(iconSize.width(), pmSize.width()));
- height = qMax(height, qMax(iconSize.height(), pmSize.height()));
- }
- if (!bt->text().isNull() && bt->toolButtonStyle() != Qt::ToolButtonIconOnly) {
- int text_width = bt->fontMetrics().width(bt->text()),
- text_height = bt->fontMetrics().height();
- if (bt->toolButtonStyle() == Qt::ToolButtonTextUnderIcon) {
- width = qMax(width, text_width);
- height += text_height;
- } else {
- width += text_width;
- width = qMax(height, text_height);
- }
- }
- } else {
- // Let's return the size hint...
- width = szHint.width();
- height = szHint.height();
- }
- } else {
- width = szHint.width();
- height = szHint.height();
- }
- width = qMax(20, width + 5); //border
- height = qMax(20, height + 5); //border
- ret = QSize(width, height);
- }
- break;
- case QStyle::CT_Slider: {
- int w = -1;
- const QSlider *sld = qobject_cast<const QSlider *>(widg);
- // If this conversion fails then the widget was not what it claimed to be.
- if(sld) {
- if (sz == QAquaSizeLarge) {
- if (sld->orientation() == Qt::Horizontal) {
- w = qt_mac_aqua_get_metric(kThemeMetricHSliderHeight);
- if (sld->tickPosition() != QSlider::NoTicks)
- w += qt_mac_aqua_get_metric(kThemeMetricHSliderTickHeight);
- } else {
- w = qt_mac_aqua_get_metric(kThemeMetricVSliderWidth);
- if (sld->tickPosition() != QSlider::NoTicks)
- w += qt_mac_aqua_get_metric(kThemeMetricVSliderTickWidth);
- }
- } else if (sz == QAquaSizeSmall) {
- if (sld->orientation() == Qt::Horizontal) {
- w = qt_mac_aqua_get_metric(kThemeMetricSmallHSliderHeight);
- if (sld->tickPosition() != QSlider::NoTicks)
- w += qt_mac_aqua_get_metric(kThemeMetricSmallHSliderTickHeight);
- } else {
- w = qt_mac_aqua_get_metric(kThemeMetricSmallVSliderWidth);
- if (sld->tickPosition() != QSlider::NoTicks)
- w += qt_mac_aqua_get_metric(kThemeMetricSmallVSliderTickWidth);
- }
- } else if (sz == QAquaSizeMini) {
- if (sld->orientation() == Qt::Horizontal) {
- w = qt_mac_aqua_get_metric(kThemeMetricMiniHSliderHeight);
- if (sld->tickPosition() != QSlider::NoTicks)
- w += qt_mac_aqua_get_metric(kThemeMetricMiniHSliderTickHeight);
- } else {
- w = qt_mac_aqua_get_metric(kThemeMetricMiniVSliderWidth);
- if (sld->tickPosition() != QSlider::NoTicks)
- w += qt_mac_aqua_get_metric(kThemeMetricMiniVSliderTickWidth);
- }
- }
- } else {
- // This is tricky, we were requested to find a size for a slider which is not
- // a slider. We don't know if this is vertical or horizontal or if we need to
- // have tick marks or not.
- // For this case we will return an horizontal slider without tick marks.
- w = qt_mac_aqua_get_metric(kThemeMetricHSliderHeight);
- w += qt_mac_aqua_get_metric(kThemeMetricHSliderTickHeight);
- }
- if (sld->orientation() == Qt::Horizontal)
- ret.setHeight(w);
- else
- ret.setWidth(w);
- break;
- }
- case QStyle::CT_ProgressBar: {
- int finalValue = -1;
- Qt::Orientation orient = Qt::Horizontal;
- if (const QProgressBar *pb = qobject_cast<const QProgressBar *>(widg))
- orient = pb->orientation();
-
- if (sz == QAquaSizeLarge)
- finalValue = qt_mac_aqua_get_metric(kThemeMetricLargeProgressBarThickness)
- + qt_mac_aqua_get_metric(kThemeMetricProgressBarShadowOutset);
- else
- finalValue = qt_mac_aqua_get_metric(kThemeMetricNormalProgressBarThickness)
- + qt_mac_aqua_get_metric(kThemeMetricSmallProgressBarShadowOutset);
- if (orient == Qt::Horizontal)
- ret.setHeight(finalValue);
- else
- ret.setWidth(finalValue);
- break;
- }
- case QStyle::CT_LineEdit:
- if (!widg || !qobject_cast<QComboBox *>(widg->parentWidget())) {
- //should I take into account the font dimentions of the lineedit? -Sam
- if (sz == QAquaSizeLarge)
- ret = QSize(-1, 22);
- else
- ret = QSize(-1, 19);
- }
- break;
- case QStyle::CT_HeaderSection:
- if (isTreeView(widg))
- ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricListHeaderHeight));
- break;
- case QStyle::CT_MenuBar:
- if (sz == QAquaSizeLarge) {
-#ifndef QT_MAC_USE_COCOA
- SInt16 size;
- if (!GetThemeMenuBarHeight(&size))
- ret = QSize(-1, size);
-#else
- ret = QSize(-1, [[NSApp mainMenu] menuBarHeight]);
- // In the qt_mac_set_native_menubar(false) case,
- // we come it here with a zero-height main menu,
- // preventing the in-window menu from displaying.
- // Use 22 pixels for the height, by observation.
- if (ret.height() <= 0)
- ret.setHeight(22);
-#endif
- }
- break;
- default:
- break;
- }
- return ret;
-}
-
-
-#if defined(QMAC_QAQUASTYLE_SIZE_CONSTRAIN) || defined(DEBUG_SIZE_CONSTRAINT)
-static QAquaWidgetSize qt_aqua_guess_size(const QWidget *widg, QSize large, QSize small, QSize mini)
-{
- if (large == QSize(-1, -1)) {
- if (small != QSize(-1, -1))
- return QAquaSizeSmall;
- if (mini != QSize(-1, -1))
- return QAquaSizeMini;
- return QAquaSizeUnknown;
- } else if (small == QSize(-1, -1)) {
- if (mini != QSize(-1, -1))
- return QAquaSizeMini;
- return QAquaSizeLarge;
- } else if (mini == QSize(-1, -1)) {
- return QAquaSizeLarge;
- }
-
-#ifndef QT_NO_MAINWINDOW
- if (qobject_cast<QDockWidget *>(widg->window()) || !qgetenv("QWIDGET_ALL_SMALL").isNull()) {
- //if (small.width() != -1 || small.height() != -1)
- return QAquaSizeSmall;
- } else if (!qgetenv("QWIDGET_ALL_MINI").isNull()) {
- return QAquaSizeMini;
- }
-#endif
-
-#if 0
- /* Figure out which size we're closer to, I just hacked this in, I haven't
- tested it as it would probably look pretty strange to have some widgets
- big and some widgets small in the same window?? -Sam */
- int large_delta=0;
- if (large.width() != -1) {
- int delta = large.width() - widg->width();
- large_delta += delta * delta;
- }
- if (large.height() != -1) {
- int delta = large.height() - widg->height();
- large_delta += delta * delta;
- }
- int small_delta=0;
- if (small.width() != -1) {
- int delta = small.width() - widg->width();
- small_delta += delta * delta;
- }
- if (small.height() != -1) {
- int delta = small.height() - widg->height();
- small_delta += delta * delta;
- }
- int mini_delta=0;
- if (mini.width() != -1) {
- int delta = mini.width() - widg->width();
- mini_delta += delta * delta;
- }
- if (mini.height() != -1) {
- int delta = mini.height() - widg->height();
- mini_delta += delta * delta;
- }
- if (mini_delta < small_delta && mini_delta < large_delta)
- return QAquaSizeMini;
- else if (small_delta < large_delta)
- return QAquaSizeSmall;
-#endif
- return QAquaSizeLarge;
-}
-#endif
-
-QAquaWidgetSize QMacStylePrivate::aquaSizeConstrain(const QStyleOption *option, const QWidget *widg,
- QStyle::ContentsType ct, QSize szHint, QSize *insz) const
-{
-#if defined(QMAC_QAQUASTYLE_SIZE_CONSTRAIN) || defined(DEBUG_SIZE_CONSTRAINT)
- if (option) {
- if (option->state & QStyle::State_Small)
- return QAquaSizeSmall;
- if (option->state & QStyle::State_Mini)
- return QAquaSizeMini;
- }
-
- if (!widg) {
- if (insz)
- *insz = QSize();
- if (!qgetenv("QWIDGET_ALL_SMALL").isNull())
- return QAquaSizeSmall;
- if (!qgetenv("QWIDGET_ALL_MINI").isNull())
- return QAquaSizeMini;
- return QAquaSizeUnknown;
- }
- QSize large = qt_aqua_get_known_size(ct, widg, szHint, QAquaSizeLarge),
- small = qt_aqua_get_known_size(ct, widg, szHint, QAquaSizeSmall),
- mini = qt_aqua_get_known_size(ct, widg, szHint, QAquaSizeMini);
- bool guess_size = false;
- QAquaWidgetSize ret = QAquaSizeUnknown;
- QMacStyle::WidgetSizePolicy wsp = q->widgetSizePolicy(widg);
- if (wsp == QMacStyle::SizeDefault)
- guess_size = true;
- else if (wsp == QMacStyle::SizeMini)
- ret = QAquaSizeMini;
- else if (wsp == QMacStyle::SizeSmall)
- ret = QAquaSizeSmall;
- else if (wsp == QMacStyle::SizeLarge)
- ret = QAquaSizeLarge;
- if (guess_size)
- ret = qt_aqua_guess_size(widg, large, small, mini);
-
- QSize *sz = 0;
- if (ret == QAquaSizeSmall)
- sz = &small;
- else if (ret == QAquaSizeLarge)
- sz = &large;
- else if (ret == QAquaSizeMini)
- sz = &mini;
- if (insz)
- *insz = sz ? *sz : QSize(-1, -1);
-#ifdef DEBUG_SIZE_CONSTRAINT
- if (sz) {
- const char *size_desc = "Unknown";
- if (sz == &small)
- size_desc = "Small";
- else if (sz == &large)
- size_desc = "Large";
- else if (sz == &mini)
- size_desc = "Mini";
- qDebug("%s - %s: %s taken (%d, %d) [%d, %d]",
- widg ? widg->objectName().toLatin1().constData() : "*Unknown*",
- widg ? widg->metaObject()->className() : "*Unknown*", size_desc, widg->width(), widg->height(),
- sz->width(), sz->height());
- }
-#endif
- return ret;
-#else
- if (insz)
- *insz = QSize();
- Q_UNUSED(widg);
- Q_UNUSED(ct);
- Q_UNUSED(szHint);
- return QAquaSizeUnknown;
-#endif
-}
-
-/**
- Returns the free space awailable for contents inside the
- button (and not the size of the contents itself)
-*/
-HIRect QMacStylePrivate::pushButtonContentBounds(const QStyleOptionButton *btn,
- const HIThemeButtonDrawInfo *bdi) const
-{
- HIRect outerBounds = qt_hirectForQRect(btn->rect);
- // Adjust the bounds to correct for
- // carbon not calculating the content bounds fully correct
- if (bdi->kind == kThemePushButton || bdi->kind == kThemePushButtonSmall){
- outerBounds.origin.y += QMacStylePrivate::PushButtonTopOffset;
- outerBounds.size.height -= QMacStylePrivate::PushButtonBottomOffset;
- } else if (bdi->kind == kThemePushButtonMini) {
- outerBounds.origin.y += QMacStylePrivate::PushButtonTopOffset;
- }
-
- HIRect contentBounds;
- HIThemeGetButtonContentBounds(&outerBounds, bdi, &contentBounds);
- return contentBounds;
-}
-
-/**
- Calculates the size of the button contents.
- This includes both the text and the icon.
-*/
-QSize QMacStylePrivate::pushButtonSizeFromContents(const QStyleOptionButton *btn) const
-{
- QSize csz(0, 0);
- QSize iconSize = btn->icon.isNull() ? QSize(0, 0)
- : (btn->iconSize + QSize(QMacStylePrivate::PushButtonContentPadding, 0));
- QRect textRect = btn->text.isEmpty() ? QRect(0, 0, 1, 1)
- : btn->fontMetrics.boundingRect(QRect(), Qt::AlignCenter, btn->text);
- csz.setWidth(iconSize.width() + textRect.width()
- + ((btn->features & QStyleOptionButton::HasMenu)
- ? q->proxy()->pixelMetric(QStyle::PM_MenuButtonIndicator, btn, 0) : 0));
- csz.setHeight(qMax(iconSize.height(), textRect.height()));
- return csz;
-}
-
-/**
- Checks if the actual contents of btn fits inside the free content bounds of
- 'buttonKindToCheck'. Meant as a helper function for 'initHIThemePushButton'
- for determining which button kind to use for drawing.
-*/
-bool QMacStylePrivate::contentFitsInPushButton(const QStyleOptionButton *btn,
- HIThemeButtonDrawInfo *bdi,
- ThemeButtonKind buttonKindToCheck) const
-{
- ThemeButtonKind tmp = bdi->kind;
- bdi->kind = buttonKindToCheck;
- QSize contentSize = pushButtonSizeFromContents(btn);
- QRect freeContentRect = qt_qrectForHIRect(pushButtonContentBounds(btn, bdi));
- bdi->kind = tmp;
- return freeContentRect.contains(QRect(freeContentRect.x(), freeContentRect.y(),
- contentSize.width(), contentSize.height()));
-}
-
-/**
- Creates a HIThemeButtonDrawInfo structure that specifies the correct button
- kind and other details to use for drawing the given push button. Which
- button kind depends on the size of the button, the size of the contents,
- explicit user style settings, etc.
-*/
-void QMacStylePrivate::initHIThemePushButton(const QStyleOptionButton *btn,
- const QWidget *widget,
- const ThemeDrawState tds,
- HIThemeButtonDrawInfo *bdi) const
-{
- bool drawColorless = btn->palette.currentColorGroup() == QPalette::Active;
- ThemeDrawState tdsModified = tds;
- if (btn->state & QStyle::State_On)
- tdsModified = kThemeStatePressed;
- bdi->version = qt_mac_hitheme_version;
- bdi->state = tdsModified;
- bdi->value = kThemeButtonOff;
-
- if (drawColorless && tdsModified == kThemeStateInactive)
- bdi->state = kThemeStateActive;
- if (btn->state & QStyle::State_HasFocus)
- bdi->adornment = kThemeAdornmentFocus;
- else
- bdi->adornment = kThemeAdornmentNone;
-
-
- if (btn->features & (QStyleOptionButton::Flat)) {
- bdi->kind = kThemeBevelButton;
- } else {
- switch (aquaSizeConstrain(btn, widget)) {
- case QAquaSizeSmall:
- bdi->kind = kThemePushButtonSmall;
- break;
- case QAquaSizeMini:
- bdi->kind = kThemePushButtonMini;
- break;
- case QAquaSizeLarge:
- // ... We should honor if the user is explicit about using the
- // large button. But right now Qt will specify the large button
- // as default rather than QAquaSizeUnknown.
- // So we treat it like QAquaSizeUnknown
- // to get the dynamic choosing of button kind.
- case QAquaSizeUnknown:
- // Choose the button kind that closest match the button rect, but at the
- // same time displays the button contents without clipping.
- bdi->kind = kThemeBevelButton;
- if (btn->rect.width() >= QMacStylePrivate::BevelButtonW && btn->rect.height() >= QMacStylePrivate::BevelButtonH){
- if (widget && widget->testAttribute(Qt::WA_MacVariableSize)) {
- if (btn->rect.height() <= QMacStylePrivate::MiniButtonH){
- if (contentFitsInPushButton(btn, bdi, kThemePushButtonMini))
- bdi->kind = kThemePushButtonMini;
- } else if (btn->rect.height() <= QMacStylePrivate::SmallButtonH){
- if (contentFitsInPushButton(btn, bdi, kThemePushButtonSmall))
- bdi->kind = kThemePushButtonSmall;
- } else if (contentFitsInPushButton(btn, bdi, kThemePushButton)) {
- bdi->kind = kThemePushButton;
- }
- } else {
- bdi->kind = kThemePushButton;
- }
- }
- }
- }
-}
-
-bool qt_mac_buttonIsRenderedFlat(const QPushButton *pushButton, const QStyleOptionButton *option)
-{
- QMacStyle *macStyle = qobject_cast<QMacStyle *>(pushButton->style());
- if (!macStyle)
- return false;
- HIThemeButtonDrawInfo bdi;
- macStyle->d->initHIThemePushButton(option, pushButton, kThemeStateActive, &bdi);
- return bdi.kind == kThemeBevelButton;
-}
-
-/**
- Creates a HIThemeButtonDrawInfo structure that specifies the correct button
- kind and other details to use for drawing the given combobox. Which button
- kind depends on the size of the combo, wether or not it is editable,
- explicit user style settings, etc.
-*/
-void QMacStylePrivate::initComboboxBdi(const QStyleOptionComboBox *combo, HIThemeButtonDrawInfo *bdi,
- const QWidget *widget, const ThemeDrawState &tds)
-{
- bdi->version = qt_mac_hitheme_version;
- bdi->adornment = kThemeAdornmentArrowLeftArrow;
- bdi->value = kThemeButtonOff;
- if (combo->state & QStyle::State_HasFocus)
- bdi->adornment = kThemeAdornmentFocus;
- bool drawColorless = combo->palette.currentColorGroup() == QPalette::Active && tds == kThemeStateInactive;
- if (combo->activeSubControls & QStyle::SC_ComboBoxArrow)
- bdi->state = kThemeStatePressed;
- else if (drawColorless)
- bdi->state = kThemeStateActive;
- else
- bdi->state = tds;
-
- QAquaWidgetSize aSize = aquaSizeConstrain(combo, widget);
- switch (aSize) {
- case QAquaSizeMini:
- bdi->kind = combo->editable ? ThemeButtonKind(kThemeComboBoxMini)
- : ThemeButtonKind(kThemePopupButtonMini);
- break;
- case QAquaSizeSmall:
- bdi->kind = combo->editable ? ThemeButtonKind(kThemeComboBoxSmall)
- : ThemeButtonKind(kThemePopupButtonSmall);
- break;
- case QAquaSizeUnknown:
- case QAquaSizeLarge:
- // Unless the user explicitly specified large buttons, determine the
- // kind by looking at the combox size.
- // ... specifying small and mini-buttons it not a current feature of
- // Qt (e.g. QWidget::getAttribute(WA_ButtonSize)). But when it is, add
- // an extra check here before using the mini and small buttons.
- int h = combo->rect.size().height();
- if (combo->editable){
- if (h < 21)
- bdi->kind = kThemeComboBoxMini;
- else if (h < 26)
- bdi->kind = kThemeComboBoxSmall;
- else
- bdi->kind = kThemeComboBox;
- } else {
- // Even if we specify that we want the kThemePopupButton, Carbon
- // will use the kThemePopupButtonSmall if the size matches. So we
- // do the same size check explicit to have the size of the inner
- // text field be correct. Therefore, do this even if the user specifies
- // the use of LargeButtons explicit.
- if (h < 21)
- bdi->kind = kThemePopupButtonMini;
- else if (h < 26)
- bdi->kind = kThemePopupButtonSmall;
- else
- bdi->kind = kThemePopupButton;
- }
- break;
- }
-}
-
-/**
- Carbon draws comboboxes (and other views) outside the rect given as argument. Use this function to obtain
- the corresponding inner rect for drawing the same combobox so that it stays inside the given outerBounds.
-*/
-HIRect QMacStylePrivate::comboboxInnerBounds(const HIRect &outerBounds, int buttonKind)
-{
- HIRect innerBounds = outerBounds;
- // Carbon draw parts of the view outside the rect.
- // So make the rect a bit smaller to compensate
- // (I wish HIThemeGetButtonBackgroundBounds worked)
- switch (buttonKind){
- case kThemePopupButton:
- innerBounds.origin.x += 2;
- innerBounds.origin.y += 3;
- innerBounds.size.width -= 5;
- innerBounds.size.height -= 6;
- break;
- case kThemePopupButtonSmall:
- innerBounds.origin.x += 3;
- innerBounds.origin.y += 3;
- innerBounds.size.width -= 6;
- innerBounds.size.height -= 7;
- break;
- case kThemePopupButtonMini:
- innerBounds.origin.x += 2;
- innerBounds.origin.y += 2;
- innerBounds.size.width -= 5;
- innerBounds.size.height -= 6;
- break;
- case kThemeComboBox:
- innerBounds.origin.x += 3;
- innerBounds.origin.y += 3;
- innerBounds.size.width -= 6;
- innerBounds.size.height -= 6;
- break;
- case kThemeComboBoxSmall:
- innerBounds.origin.x += 3;
- innerBounds.origin.y += 3;
- innerBounds.size.width -= 7;
- innerBounds.size.height -= 8;
- break;
- case kThemeComboBoxMini:
- innerBounds.origin.x += 3;
- innerBounds.origin.y += 3;
- innerBounds.size.width -= 4;
- innerBounds.size.height -= 8;
- break;
- default:
- break;
- }
- return innerBounds;
-}
-
-/**
- Inside a combobox Qt places a line edit widget. The size of this widget should depend on the kind
- of combobox we choose to draw. This function calculates and returns this size.
-*/
-QRect QMacStylePrivate::comboboxEditBounds(const QRect &outerBounds, const HIThemeButtonDrawInfo &bdi)
-{
- QRect ret = outerBounds;
- switch (bdi.kind){
- case kThemeComboBox:
- ret.adjust(5, 8, -22, -4);
- break;
- case kThemeComboBoxSmall:
- ret.adjust(4, 6, -20, 0);
- ret.setHeight(14);
- break;
- case kThemeComboBoxMini:
- ret.adjust(4, 5, -18, -1);
- ret.setHeight(12);
- break;
- case kThemePopupButton:
- ret.adjust(10, 3, -23, -3);
- break;
- case kThemePopupButtonSmall:
- ret.adjust(9, 3, -20, -3);
- break;
- case kThemePopupButtonMini:
- ret.adjust(8, 3, -19, 0);
- ret.setHeight(13);
- break;
- }
- return ret;
-}
-
-/**
- Carbon comboboxes don't scale (sight). If the size of the combo suggest a scaled version,
- create it manually by drawing a small Carbon combo onto a pixmap (use pixmap cache), chop
- it up, and copy it back onto the widget. Othervise, draw the combobox supplied by Carbon directly.
-*/
-void QMacStylePrivate::drawCombobox(const HIRect &outerBounds, const HIThemeButtonDrawInfo &bdi, QPainter *p)
-{
- if (!(bdi.kind == kThemeComboBox && outerBounds.size.height > 28)){
- // We have an unscaled combobox, or popup-button; use Carbon directly.
- HIRect innerBounds = QMacStylePrivate::comboboxInnerBounds(outerBounds, bdi.kind);
- HIThemeDrawButton(&innerBounds, &bdi, QMacCGContext(p), kHIThemeOrientationNormal, 0);
- } else {
- QPixmap buffer;
- QString key = QString(QLatin1String("$qt_cbox%1-%2")).arg(int(bdi.state)).arg(int(bdi.adornment));
- if (!QPixmapCache::find(key, buffer)) {
- HIRect innerBoundsSmallCombo = {{3, 3}, {29, 25}};
- buffer = QPixmap(35, 28);
- buffer.fill(Qt::transparent);
- QPainter buffPainter(&buffer);
- HIThemeDrawButton(&innerBoundsSmallCombo, &bdi, QMacCGContext(&buffPainter), kHIThemeOrientationNormal, 0);
- buffPainter.end();
- QPixmapCache::insert(key, buffer);
- }
-
- const int bwidth = 20;
- const int fwidth = 10;
- const int fheight = 10;
- int w = qRound(outerBounds.size.width);
- int h = qRound(outerBounds.size.height);
- int bstart = w - bwidth;
- int blower = fheight + 1;
- int flower = h - fheight;
- int sheight = flower - fheight;
- int center = qRound(outerBounds.size.height + outerBounds.origin.y) / 2;
-
- // Draw upper and lower gap
- p->drawPixmap(fwidth, 0, bstart - fwidth, fheight, buffer, fwidth, 0, 1, fheight);
- p->drawPixmap(fwidth, flower, bstart - fwidth, fheight, buffer, fwidth, buffer.height() - fheight, 1, fheight);
- // Draw left and right gap. Right gap is drawn top and bottom separatly
- p->drawPixmap(0, fheight, fwidth, sheight, buffer, 0, fheight, fwidth, 1);
- p->drawPixmap(bstart, fheight, bwidth, center - fheight, buffer, buffer.width() - bwidth, fheight - 1, bwidth, 1);
- p->drawPixmap(bstart, center, bwidth, sheight / 2, buffer, buffer.width() - bwidth, fheight + 6, bwidth, 1);
- // Draw arrow
- p->drawPixmap(bstart, center - 4, bwidth - 3, 6, buffer, buffer.width() - bwidth, fheight, bwidth - 3, 6);
- // Draw corners
- p->drawPixmap(0, 0, fwidth, fheight, buffer, 0, 0, fwidth, fheight);
- p->drawPixmap(bstart, 0, bwidth, fheight, buffer, buffer.width() - bwidth, 0, bwidth, fheight);
- p->drawPixmap(0, flower, fwidth, fheight, buffer, 0, buffer.height() - fheight, fwidth, fheight);
- p->drawPixmap(bstart, h - blower, bwidth, blower, buffer, buffer.width() - bwidth, buffer.height() - blower, bwidth, blower);
- }
-}
-
-/**
- Carbon tableheaders don't scale (sight). So create it manually by drawing a small Carbon header
- onto a pixmap (use pixmap cache), chop it up, and copy it back onto the widget.
-*/
-void QMacStylePrivate::drawTableHeader(const HIRect &outerBounds,
- bool drawTopBorder, bool drawLeftBorder, const HIThemeButtonDrawInfo &bdi, QPainter *p)
-{
- static SInt32 headerHeight = 0;
- static OSStatus err = GetThemeMetric(kThemeMetricListHeaderHeight, &headerHeight);
- Q_UNUSED(err);
-
- QPixmap buffer;
- QString key = QString(QLatin1String("$qt_tableh%1-%2-%3")).arg(int(bdi.state)).arg(int(bdi.adornment)).arg(int(bdi.value));
- if (!QPixmapCache::find(key, buffer)) {
- HIRect headerNormalRect = {{0., 0.}, {16., CGFloat(headerHeight)}};
- buffer = QPixmap(headerNormalRect.size.width, headerNormalRect.size.height);
- buffer.fill(Qt::transparent);
- QPainter buffPainter(&buffer);
- HIThemeDrawButton(&headerNormalRect, &bdi, QMacCGContext(&buffPainter), kHIThemeOrientationNormal, 0);
- buffPainter.end();
- QPixmapCache::insert(key, buffer);
- }
- const int buttonw = qRound(outerBounds.size.width);
- const int buttonh = qRound(outerBounds.size.height);
- const int framew = 1;
- const int frameh_n = 4;
- const int frameh_s = 3;
- const int transh = buffer.height() - frameh_n - frameh_s;
- int center = buttonh - frameh_s - int(transh / 2.0f) + 1; // Align bottom;
-
- int skipTopBorder = 0;
- if (!drawTopBorder)
- skipTopBorder = 1;
-
- p->translate(outerBounds.origin.x, outerBounds.origin.y);
-
- p->drawPixmap(QRect(QRect(0, -skipTopBorder, buttonw - framew , frameh_n)), buffer, QRect(framew, 0, 1, frameh_n));
- p->drawPixmap(QRect(0, buttonh - frameh_s, buttonw - framew, frameh_s), buffer, QRect(framew, buffer.height() - frameh_s, 1, frameh_s));
- // Draw upper and lower center blocks
- p->drawPixmap(QRect(0, frameh_n - skipTopBorder, buttonw - framew, center - frameh_n + skipTopBorder), buffer, QRect(framew, frameh_n, 1, 1));
- p->drawPixmap(QRect(0, center, buttonw - framew, buttonh - center - frameh_s), buffer, QRect(framew, buffer.height() - frameh_s, 1, 1));
- // Draw right center block borders
- p->drawPixmap(QRect(buttonw - framew, frameh_n - skipTopBorder, framew, center - frameh_n), buffer, QRect(buffer.width() - framew, frameh_n, framew, 1));
- p->drawPixmap(QRect(buttonw - framew, center, framew, buttonh - center - 1), buffer, QRect(buffer.width() - framew, buffer.height() - frameh_s, framew, 1));
- // Draw right corners
- p->drawPixmap(QRect(buttonw - framew, -skipTopBorder, framew, frameh_n), buffer, QRect(buffer.width() - framew, 0, framew, frameh_n));
- p->drawPixmap(QRect(buttonw - framew, buttonh - frameh_s, framew, frameh_s), buffer, QRect(buffer.width() - framew, buffer.height() - frameh_s, framew, frameh_s));
- // Draw center transition block
- p->drawPixmap(QRect(0, center - qRound(transh / 2.0f), buttonw - framew, buffer.height() - frameh_n - frameh_s), buffer, QRect(framew, frameh_n + 1, 1, transh));
- // Draw right center transition block border
- p->drawPixmap(QRect(buttonw - framew, center - qRound(transh / 2.0f), framew, buffer.height() - frameh_n - frameh_s), buffer, QRect(buffer.width() - framew, frameh_n + 1, framew, transh));
- if (drawLeftBorder){
- // Draw left center block borders
- p->drawPixmap(QRect(0, frameh_n - skipTopBorder, framew, center - frameh_n + skipTopBorder), buffer, QRect(0, frameh_n, framew, 1));
- p->drawPixmap(QRect(0, center, framew, buttonh - center - 1), buffer, QRect(0, buffer.height() - frameh_s, framew, 1));
- // Draw left corners
- p->drawPixmap(QRect(0, -skipTopBorder, framew, frameh_n), buffer, QRect(0, 0, framew, frameh_n));
- p->drawPixmap(QRect(0, buttonh - frameh_s, framew, frameh_s), buffer, QRect(0, buffer.height() - frameh_s, framew, frameh_s));
- // Draw left center transition block border
- p->drawPixmap(QRect(0, center - qRound(transh / 2.0f), framew, buffer.height() - frameh_n - frameh_s), buffer, QRect(0, frameh_n + 1, framew, transh));
- }
-
- p->translate(-outerBounds.origin.x, -outerBounds.origin.y);
-}
-
-/*
- Returns cutoff sizes for scroll bars.
- thumbIndicatorCutoff is the smallest size where the thumb indicator is drawn.
- scrollButtonsCutoff is the smallest size where the up/down buttons is drawn.
-*/
-enum ScrollBarCutoffType { thumbIndicatorCutoff = 0, scrollButtonsCutoff = 1 };
-static int scrollButtonsCutoffSize(ScrollBarCutoffType cutoffType, QMacStyle::WidgetSizePolicy widgetSize)
-{
- // Mini scroll bars do not exist as of version 10.4.
- if (widgetSize == QMacStyle::SizeMini)
- return 0;
-
- const int sizeIndex = (widgetSize == QMacStyle::SizeSmall) ? 1 : 0;
- static const int sizeTable[2][2] = { { 61, 56 }, { 49, 44 } };
- return sizeTable[sizeIndex][cutoffType];
-}
-
-void QMacStylePrivate::getSliderInfo(QStyle::ComplexControl cc, const QStyleOptionSlider *slider,
- HIThemeTrackDrawInfo *tdi, const QWidget *needToRemoveMe)
-{
- memset(tdi, 0, sizeof(HIThemeTrackDrawInfo)); // We don't get it all for some reason or another...
- tdi->version = qt_mac_hitheme_version;
- tdi->reserved = 0;
- tdi->filler1 = 0;
- bool isScrollbar = (cc == QStyle::CC_ScrollBar);
- switch (aquaSizeConstrain(0, needToRemoveMe)) {
- case QAquaSizeUnknown:
- case QAquaSizeLarge:
- if (isScrollbar)
- tdi->kind = kThemeMediumScrollBar;
- else
- tdi->kind = kThemeMediumSlider;
- break;
- case QAquaSizeMini:
- if (isScrollbar)
- tdi->kind = kThemeSmallScrollBar; // should be kThemeMiniScrollBar, but not implemented
- else
- tdi->kind = kThemeMiniSlider;
- break;
- case QAquaSizeSmall:
- if (isScrollbar)
- tdi->kind = kThemeSmallScrollBar;
- else
- tdi->kind = kThemeSmallSlider;
- break;
- }
- tdi->bounds = qt_hirectForQRect(slider->rect);
- tdi->min = slider->minimum;
- tdi->max = slider->maximum;
- tdi->value = slider->sliderPosition;
- tdi->attributes = kThemeTrackShowThumb;
- if (slider->upsideDown)
- tdi->attributes |= kThemeTrackRightToLeft;
- if (slider->orientation == Qt::Horizontal) {
- tdi->attributes |= kThemeTrackHorizontal;
- if (isScrollbar && slider->direction == Qt::RightToLeft) {
- if (!slider->upsideDown)
- tdi->attributes |= kThemeTrackRightToLeft;
- else
- tdi->attributes &= ~kThemeTrackRightToLeft;
- }
- }
-
- // Tiger broke reverse scroll bars so put them back and "fake it"
- if (isScrollbar && (tdi->attributes & kThemeTrackRightToLeft)) {
- tdi->attributes &= ~kThemeTrackRightToLeft;
- tdi->value = tdi->max - slider->sliderPosition;
- }
-
- tdi->enableState = (slider->state & QStyle::State_Enabled) ? kThemeTrackActive
- : kThemeTrackDisabled;
- if (!(slider->state & QStyle::State_Active))
- tdi->enableState = kThemeTrackInactive;
- if (!isScrollbar) {
- if (slider->state & QStyle::QStyle::State_HasFocus)
- tdi->attributes |= kThemeTrackHasFocus;
- if (slider->tickPosition == QSlider::NoTicks || slider->tickPosition == QSlider::TicksBothSides)
- tdi->trackInfo.slider.thumbDir = kThemeThumbPlain;
- else if (slider->tickPosition == QSlider::TicksAbove)
- tdi->trackInfo.slider.thumbDir = kThemeThumbUpward;
- else
- tdi->trackInfo.slider.thumbDir = kThemeThumbDownward;
- } else {
- tdi->trackInfo.scrollbar.viewsize = slider->pageStep;
- }
-}
-#endif
-
-QMacStylePrivate::QMacStylePrivate(QMacStyle *style)
- : timerID(-1), progressFrame(0), q(style), mouseDown(false)
-{
- defaultButtonStart = CFAbsoluteTimeGetCurrent();
- memset(&buttonState, 0, sizeof(ButtonState));
-
- if (ptrHIShapeGetBounds == 0) {
- QLibrary library(QLatin1String("/System/Library/Frameworks/Carbon.framework/Carbon"));
- library.setLoadHints(QLibrary::ExportExternalSymbolsHint);
- ptrHIShapeGetBounds = reinterpret_cast<PtrHIShapeGetBounds>(library.resolve("HIShapeGetBounds"));
- }
-
-}
-
-bool QMacStylePrivate::animatable(QMacStylePrivate::Animates as, const QWidget *w) const
-{
- if (!w)
- return false;
-
- if (as == AquaPushButton) {
- QPushButton *pb = const_cast<QPushButton *>(static_cast<const QPushButton *>(w));
- 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);
- const_cast<QMacStylePrivate *>(this)->startAnimate(as, pb);
- }
- return true;
- }
- } else if (as == AquaProgressBar) {
- if (progressBars.contains((const_cast<QWidget *>(w))))
- return true;
- }
- return false;
-}
-
-void QMacStylePrivate::stopAnimate(QMacStylePrivate::Animates as, QWidget *w)
-{
- if (as == AquaPushButton && defaultButton) {
- QPushButton *tmp = defaultButton;
- defaultButton = 0;
- tmp->update();
- } else if (as == AquaProgressBar) {
- progressBars.removeAll(w);
- }
-}
-
-void QMacStylePrivate::startAnimate(QMacStylePrivate::Animates as, QWidget *w)
-{
- if (as == AquaPushButton)
- defaultButton = static_cast<QPushButton *>(w);
- else if (as == AquaProgressBar)
- progressBars.append(w);
- startAnimationTimer();
-}
-
-void QMacStylePrivate::startAnimationTimer()
-{
- if ((defaultButton || !progressBars.isEmpty()) && timerID <= -1)
- timerID = startTimer(animateSpeed(AquaListViewItemOpen));
-}
-
-bool QMacStylePrivate::addWidget(QWidget *w)
-{
- //already knew of it
- if (static_cast<QPushButton*>(w) == defaultButton
- || progressBars.contains(static_cast<QProgressBar*>(w)))
- return false;
-
- if (QPushButton *btn = qobject_cast<QPushButton *>(w)) {
- btn->installEventFilter(this);
- if (btn->isDefault() || (btn->autoDefault() && btn->hasFocus()))
- startAnimate(AquaPushButton, btn);
- return true;
- } else {
- bool isProgressBar = (qobject_cast<QProgressBar *>(w)
-#ifdef QT3_SUPPORT
- || w->inherits("Q3ProgressBar")
-#endif
- );
- if (isProgressBar) {
- w->installEventFilter(this);
- startAnimate(AquaProgressBar, w);
- return true;
- }
- }
- if (w->isWindow()) {
- w->installEventFilter(this);
- return true;
- }
- return false;
-}
-
-void QMacStylePrivate::removeWidget(QWidget *w)
-{
- QPushButton *btn = qobject_cast<QPushButton *>(w);
- if (btn && btn == defaultButton) {
- stopAnimate(AquaPushButton, btn);
- } else if (qobject_cast<QProgressBar *>(w)
-#ifdef QT3_SUPPORT
- || w->inherits("Q3ProgressBar")
-#endif
- ) {
- stopAnimate(AquaProgressBar, w);
- }
-}
-
-ThemeDrawState QMacStylePrivate::getDrawState(QStyle::State flags)
-{
- ThemeDrawState tds = kThemeStateActive;
- if (flags & QStyle::State_Sunken) {
- tds = kThemeStatePressed;
- } else if (flags & QStyle::State_Active) {
- if (!(flags & QStyle::State_Enabled))
- tds = kThemeStateUnavailable;
- } else {
- if (flags & QStyle::State_Enabled)
- tds = kThemeStateInactive;
- else
- tds = kThemeStateUnavailableInactive;
- }
- return tds;
-}
-
-void QMacStylePrivate::timerEvent(QTimerEvent *)
-{
- int animated = 0;
- if (defaultButton && defaultButton->isEnabled() && defaultButton->window()->isActiveWindow()
- && defaultButton->isVisibleTo(0) && (defaultButton->isDefault()
- || (defaultButton->autoDefault() && defaultButton->hasFocus()))
- && doAnimate(AquaPushButton)) {
- ++animated;
- defaultButton->update();
- }
- if (!progressBars.isEmpty()) {
- int i = 0;
- while (i < progressBars.size()) {
- QWidget *maybeProgress = progressBars.at(i);
- if (!maybeProgress) {
- progressBars.removeAt(i);
- } else {
- if (QProgressBar *pb = qobject_cast<QProgressBar *>(maybeProgress)) {
- if (pb->maximum() == 0 || (pb->value() > 0 && pb->value() < pb->maximum())) {
- if (doAnimate(AquaProgressBar))
- pb->update();
- }
- }
-#ifdef QT3_SUPPORT
- else {
- // Watch me now...
- QVariant progress = maybeProgress->property("progress");
- QVariant totalSteps = maybeProgress->property("totalSteps");
- if (progress.isValid() && totalSteps.isValid()) {
- int intProgress = progress.toInt();
- int intTotalSteps = totalSteps.toInt();
- if (intTotalSteps == 0 || intProgress > 0 && intProgress < intTotalSteps) {
- if (doAnimate(AquaProgressBar))
- maybeProgress->update();
- }
- }
- }
-#endif
- ++i;
- }
- }
- if (i > 0) {
- ++progressFrame;
- animated += i;
- }
- }
- if (animated <= 0) {
- killTimer(timerID);
- timerID = -1;
- }
-}
-
-bool QMacStylePrivate::eventFilter(QObject *o, QEvent *e)
-{
- //animate
- if (QProgressBar *pb = qobject_cast<QProgressBar *>(o)) {
- switch (e->type()) {
- default:
- break;
- case QEvent::Show:
- if (!progressBars.contains(pb))
- startAnimate(AquaProgressBar, pb);
- break;
- case QEvent::Destroy:
- case QEvent::Hide:
- progressBars.removeAll(pb);
- }
- } else if (QPushButton *btn = qobject_cast<QPushButton *>(o)) {
- switch (e->type()) {
- default:
- break;
- case QEvent::FocusIn:
- if (btn->autoDefault())
- startAnimate(AquaPushButton, btn);
- break;
- case QEvent::Destroy:
- case QEvent::Hide:
- if (btn == defaultButton)
- stopAnimate(AquaPushButton, btn);
- 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::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 = btn->window()->findChildren<QPushButton *>();
- for (int i = 0; i < list.size(); ++i) {
- QPushButton *pBtn = list.at(i);
- if ((e->type() == QEvent::FocusOut
- && (pBtn->isDefault() || (pBtn->autoDefault() && pBtn->hasFocus()))
- && pBtn != btn)
- || ((e->type() == QEvent::Show || e->type() == QEvent::MouseButtonRelease
- || e->type() == QEvent::WindowActivate)
- && pBtn->isDefault())) {
- if (pBtn->window()->isActiveWindow()) {
- startAnimate(AquaPushButton, pBtn);
- }
- break;
- }
- }
- break; }
- }
- }
- return false;
-}
-
-bool QMacStylePrivate::doAnimate(QMacStylePrivate::Animates as)
-{
- if (as == AquaPushButton) {
- } else if (as == AquaProgressBar) {
- // something for later...
- } else if (as == AquaListViewItemOpen) {
- // To be revived later...
- }
- return true;
-}
-
-void QMacStylePrivate::drawColorlessButton(const HIRect &macRect, HIThemeButtonDrawInfo *bdi,
- QPainter *p, const QStyleOption *opt) const
-{
- int xoff = 0,
- yoff = 0,
- extraWidth = 0,
- extraHeight = 0,
- finalyoff = 0;
-
- const QStyleOptionComboBox *combo = qstyleoption_cast<const QStyleOptionComboBox *>(opt);
- int width = int(macRect.size.width) + extraWidth;
- int height = int(macRect.size.height) + extraHeight;
-
- if (width <= 0 || height <= 0)
- return; // nothing to draw
-
- QString key = QLatin1String("$qt_mac_style_ctb_") + QString::number(bdi->kind) + QLatin1Char('_')
- + QString::number(bdi->value) + QLatin1Char('_') + QString::number(width)
- + QLatin1Char('_') + QString::number(height);
- QPixmap pm;
- if (!QPixmapCache::find(key, pm)) {
- QPixmap activePixmap(width, height);
- activePixmap.fill(Qt::transparent);
- {
- if (combo){
- // Carbon combos don't scale. Therefore we draw it
- // ourselves, if a scaled version is needed.
- QPainter tmpPainter(&activePixmap);
- QMacStylePrivate::drawCombobox(macRect, *bdi, &tmpPainter);
- }
- else {
- QMacCGContext cg(&activePixmap);
- HIRect newRect = CGRectMake(xoff, yoff, macRect.size.width, macRect.size.height);
- HIThemeDrawButton(&newRect, bdi, cg, kHIThemeOrientationNormal, 0);
- }
- }
-
- if (!combo && bdi->value == kThemeButtonOff) {
- pm = activePixmap;
- } else if (combo) {
- QImage image = activePixmap.toImage();
-
- for (int y = 0; y < height; ++y) {
- QRgb *scanLine = reinterpret_cast<QRgb *>(image.scanLine(y));
-
- for (int x = 0; x < width; ++x) {
- QRgb &pixel = scanLine[x];
-
- int darkest = qRed(pixel);
- int mid = qGreen(pixel);
- int lightest = qBlue(pixel);
-
- if (darkest > mid)
- qSwap(darkest, mid);
- if (mid > lightest)
- qSwap(mid, lightest);
- if (darkest > mid)
- qSwap(darkest, mid);
-
- int gray = (mid + 2 * lightest) / 3;
- pixel = qRgba(gray, gray, gray, qAlpha(pixel));
- }
- }
- pm = QPixmap::fromImage(image);
- } else {
- QImage activeImage = activePixmap.toImage();
- QImage colorlessImage;
- {
- QPixmap colorlessPixmap(width, height);
- colorlessPixmap.fill(Qt::transparent);
-
- QMacCGContext cg(&colorlessPixmap);
- HIRect newRect = CGRectMake(xoff, yoff, macRect.size.width, macRect.size.height);
- int oldValue = bdi->value;
- bdi->value = kThemeButtonOff;
- HIThemeDrawButton(&newRect, bdi, cg, kHIThemeOrientationNormal, 0);
- bdi->value = oldValue;
- colorlessImage = colorlessPixmap.toImage();
- }
-
- for (int y = 0; y < height; ++y) {
- QRgb *colorlessScanLine = reinterpret_cast<QRgb *>(colorlessImage.scanLine(y));
- const QRgb *activeScanLine = reinterpret_cast<const QRgb *>(activeImage.scanLine(y));
-
- for (int x = 0; x < width; ++x) {
- QRgb &colorlessPixel = colorlessScanLine[x];
- QRgb activePixel = activeScanLine[x];
-
- if (activePixel != colorlessPixel) {
- int max = qMax(qMax(qRed(activePixel), qGreen(activePixel)),
- qBlue(activePixel));
- QRgb newPixel = qRgba(max, max, max, qAlpha(activePixel));
- if (qGray(newPixel) < qGray(colorlessPixel)
- || qAlpha(newPixel) > qAlpha(colorlessPixel))
- colorlessPixel = newPixel;
- }
- }
- }
- pm = QPixmap::fromImage(colorlessImage);
- }
- QPixmapCache::insert(key, pm);
- }
- p->drawPixmap(int(macRect.origin.x), int(macRect.origin.y) + finalyoff, width, height, pm);
-}
-
-QMacStyle::QMacStyle()
- : QWindowsStyle()
-{
- d = new QMacStylePrivate(this);
-}
-
-QMacStyle::~QMacStyle()
-{
- delete qt_mac_backgroundPattern;
- qt_mac_backgroundPattern = 0;
- delete d;
-}
-
-/*! \internal
- Generates the standard widget background pattern.
-*/
-QPixmap QMacStylePrivate::generateBackgroundPattern() const
-{
- QPixmap px(4, 4);
- QMacCGContext cg(&px);
- HIThemeSetFill(kThemeBrushDialogBackgroundActive, 0, cg, kHIThemeOrientationNormal);
- const CGRect cgRect = CGRectMake(0, 0, px.width(), px.height());
- CGContextFillRect(cg, cgRect);
- return px;
-}
-
-/*! \internal
- Fills the given \a rect with the pattern stored in \a brush. As an optimization,
- HIThemeSetFill us used directly if we are filling with the standard background.
-*/
-void qt_mac_fill_background(QPainter *painter, const QRegion &rgn, const QBrush &brush)
-{
- QPoint dummy;
- const QPaintDevice *target = painter->device();
- const QPaintDevice *redirected = QPainter::redirected(target, &dummy);
- const bool usePainter = redirected && redirected != target;
-
- if (!usePainter && qt_mac_backgroundPattern
- && qt_mac_backgroundPattern->cacheKey() == brush.texture().cacheKey()) {
-
- painter->setClipRegion(rgn);
-
- QCFType<CGContextRef> cg = qt_mac_cg_context(target);
- CGContextSaveGState(cg);
- HIThemeSetFill(kThemeBrushDialogBackgroundActive, 0, cg, kHIThemeOrientationInverted);
-
- const QVector<QRect> &rects = rgn.rects();
- for (int i = 0; i < rects.size(); ++i) {
- const QRect rect(rects.at(i));
- // Anchor the pattern to the top so it stays put when the window is resized.
- CGContextSetPatternPhase(cg, CGSizeMake(rect.width(), rect.height()));
- CGRect mac_rect = CGRectMake(rect.x(), rect.y(), rect.width(), rect.height());
- CGContextFillRect(cg, mac_rect);
- }
-
- CGContextRestoreGState(cg);
- } else {
- const QRect rect(rgn.boundingRect());
- painter->setClipRegion(rgn);
- painter->drawTiledPixmap(rect, brush.texture(), rect.topLeft());
- }
-}
-
-void QMacStyle::polish(QPalette &pal)
-{
- if (!qt_mac_backgroundPattern) {
- if (!qApp)
- return;
- qt_mac_backgroundPattern = new QPixmap(d->generateBackgroundPattern());
- }
-
- QColor pc(Qt::black);
- pc = qcolorForTheme(kThemeBrushDialogBackgroundActive);
- QBrush background(pc, *qt_mac_backgroundPattern);
- pal.setBrush(QPalette::All, QPalette::Window, background);
- pal.setBrush(QPalette::All, QPalette::Button, background);
-
- QCFString theme;
- const OSErr err = CopyThemeIdentifier(&theme);
- if (err == noErr && CFStringCompare(theme, kThemeAppearanceAquaGraphite, 0) == kCFCompareEqualTo) {
- pal.setBrush(QPalette::All, QPalette::AlternateBase, QColor(240, 240, 240));
- } else {
- pal.setBrush(QPalette::All, QPalette::AlternateBase, QColor(237, 243, 254));
- }
-}
-
-void QMacStyle::polish(QApplication *)
-{
-}
-
-void QMacStyle::unpolish(QApplication *)
-{
-}
-
-void QMacStyle::polish(QWidget* w)
-{
- d->addWidget(w);
- if (qt_mac_is_metal(w) && !w->testAttribute(Qt::WA_SetPalette)) {
- // Set a clear brush so that the metal shines through.
- QPalette pal = w->palette();
- QBrush background(Qt::transparent);
- pal.setBrush(QPalette::All, QPalette::Window, background);
- pal.setBrush(QPalette::All, QPalette::Button, background);
- w->setPalette(pal);
- w->setAttribute(Qt::WA_SetPalette, false);
- }
-
- if (qobject_cast<QMenu*>(w) || qobject_cast<QComboBoxPrivateContainer *>(w)) {
- w->setWindowOpacity(QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5 ? 0.985 : 0.94);
- if (!w->testAttribute(Qt::WA_SetPalette)) {
- QPixmap px(64, 64);
- px.fill(Qt::white);
- HIThemeMenuDrawInfo mtinfo;
- mtinfo.version = qt_mac_hitheme_version;
- mtinfo.menuType = kThemeMenuTypePopUp;
- HIRect rect = CGRectMake(0, 0, px.width(), px.height());
- HIThemeDrawMenuBackground(&rect, &mtinfo, QCFType<CGContextRef>(qt_mac_cg_context(&px)),
- kHIThemeOrientationNormal);
- QPalette pal = w->palette();
- QBrush background(px);
- pal.setBrush(QPalette::All, QPalette::Window, background);
- pal.setBrush(QPalette::All, QPalette::Button, background);
- w->setPalette(pal);
- w->setAttribute(Qt::WA_SetPalette, false);
- }
- }
-
- if (QTabBar *tb = qobject_cast<QTabBar*>(w)) {
- if (tb->documentMode()) {
- w->setAttribute(Qt::WA_Hover);
- w->setFont(qt_app_fonts_hash()->value("QSmallFont", QFont()));
- QPalette p = w->palette();
- p.setColor(QPalette::WindowText, QColor(17, 17, 17));
- w->setPalette(p);
- }
- }
-
- QWindowsStyle::polish(w);
-
- if (QRubberBand *rubber = qobject_cast<QRubberBand*>(w)) {
- rubber->setWindowOpacity(0.25);
- rubber->setAttribute(Qt::WA_PaintOnScreen, false);
- rubber->setAttribute(Qt::WA_NoSystemBackground, false);
- }
-}
-
-void QMacStyle::unpolish(QWidget* w)
-{
- d->removeWidget(w);
- if ((qobject_cast<QMenu*>(w) || qt_mac_is_metal(w)) && !w->testAttribute(Qt::WA_SetPalette)) {
- QPalette pal = qApp->palette(w);
- w->setPalette(pal);
- w->setAttribute(Qt::WA_SetPalette, false);
- w->setWindowOpacity(1.0);
- }
-
- if (QComboBox *combo = qobject_cast<QComboBox *>(w)) {
- if (!combo->isEditable()) {
- if (QWidget *widget = combo->findChild<QComboBoxPrivateContainer *>())
- widget->setWindowOpacity(1.0);
- }
- }
-
- if (QRubberBand *rubber = ::qobject_cast<QRubberBand*>(w)) {
- rubber->setWindowOpacity(1.0);
- rubber->setAttribute(Qt::WA_PaintOnScreen, true);
- rubber->setAttribute(Qt::WA_NoSystemBackground, true);
- }
-
- if (QFocusFrame *frame = qobject_cast<QFocusFrame *>(w))
- frame->setAttribute(Qt::WA_NoSystemBackground, true);
-
- QWindowsStyle::unpolish(w);
-}
-
-int QMacStyle::pixelMetric(PixelMetric metric, const QStyleOption *opt, const QWidget *widget) const
-{
- int controlSize = getControlSize(opt, widget);
- SInt32 ret = 0;
-
- switch (metric) {
- case PM_TabCloseIndicatorWidth:
- case PM_TabCloseIndicatorHeight:
- ret = closeButtonSize;
- break;
- case PM_ToolBarIconSize:
- ret = proxy()->pixelMetric(PM_LargeIconSize);
- break;
- case PM_FocusFrameVMargin:
- case PM_FocusFrameHMargin:
- GetThemeMetric(kThemeMetricFocusRectOutset, &ret);
- break;
- case PM_DialogButtonsSeparator:
- ret = -5;
- break;
- case PM_DialogButtonsButtonHeight: {
- QSize sz;
- ret = d->aquaSizeConstrain(opt, 0, QStyle::CT_PushButton, QSize(-1, -1), &sz);
- if (sz == QSize(-1, -1))
- ret = 32;
- else
- ret = sz.height();
- break; }
- case PM_CheckListButtonSize: {
- switch (d->aquaSizeConstrain(opt, widget)) {
- case QAquaSizeUnknown:
- case QAquaSizeLarge:
- GetThemeMetric(kThemeMetricCheckBoxWidth, &ret);
- break;
- case QAquaSizeMini:
- GetThemeMetric(kThemeMetricMiniCheckBoxWidth, &ret);
- break;
- case QAquaSizeSmall:
- GetThemeMetric(kThemeMetricSmallCheckBoxWidth, &ret);
- break;
- }
- break; }
- case PM_DialogButtonsButtonWidth: {
- QSize sz;
- ret = d->aquaSizeConstrain(opt, 0, QStyle::CT_PushButton, QSize(-1, -1), &sz);
- if (sz == QSize(-1, -1))
- ret = 70;
- else
- ret = sz.width();
- break; }
-
- case PM_MenuBarHMargin:
- ret = 8;
- break;
-
- case PM_MenuBarVMargin:
- ret = 0;
- break;
-
- case QStyle::PM_MenuDesktopFrameWidth:
- ret = 5;
- break;
-
- case PM_CheckBoxLabelSpacing:
- case PM_RadioButtonLabelSpacing:
- ret = 2;
- break;
- case PM_MenuScrollerHeight:
-#if 0
- SInt16 ash, asw;
- GetThemeMenuItemExtra(kThemeMenuItemScrollUpArrow, &ash, &asw);
- ret = ash;
-#else
- ret = 15; // I hate having magic numbers in here...
-#endif
- break;
- case PM_DefaultFrameWidth:
-#ifndef QT_NO_MAINWINDOW
- if (widget && (widget->isWindow() || !widget->parentWidget()
- || (qobject_cast<const QMainWindow*>(widget->parentWidget())
- && static_cast<QMainWindow *>(widget->parentWidget())->centralWidget() == widget))
- && (qobject_cast<const QAbstractScrollArea *>(widget)
-#ifdef QT3_SUPPORT
- || widget->inherits("QScrollView")
-#endif
- || widget->inherits("QWorkspaceChild")))
- ret = 0;
- else
-#endif
- // The combo box popup has no frame.
- if (qstyleoption_cast<const QStyleOptionComboBox *>(opt) != 0)
- ret = 0;
- // Frame of mac style line edits is two pixels on top and one on the bottom
- else if (qobject_cast<const QLineEdit *>(widget) != 0)
- ret = 2;
- else
- ret = 1;
- break;
- case PM_MaximumDragDistance:
- ret = -1;
- break;
- case PM_ScrollBarSliderMin:
- ret = 24;
- break;
- case PM_SpinBoxFrameWidth:
- GetThemeMetric(kThemeMetricEditTextFrameOutset, &ret);
- switch (d->aquaSizeConstrain(opt, widget)) {
- default:
- ret += 2;
- break;
- case QAquaSizeMini:
- ret += 1;
- break;
- }
- break;
- case PM_ButtonShiftHorizontal:
- case PM_ButtonShiftVertical:
- ret = 0;
- break;
- case PM_SliderLength:
- ret = 17;
- break;
- case PM_ButtonDefaultIndicator:
- ret = 0;
- break;
- case PM_TitleBarHeight:
- if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) {
- HIThemeWindowDrawInfo wdi;
- wdi.version = qt_mac_hitheme_version;
- wdi.state = kThemeStateActive;
- wdi.windowType = QtWinType;
- if (tb->titleBarState)
- wdi.attributes = kThemeWindowHasFullZoom | kThemeWindowHasCloseBox
- | kThemeWindowHasCollapseBox;
- else if (tb->titleBarFlags & Qt::WindowSystemMenuHint)
- wdi.attributes = kThemeWindowHasCloseBox;
- else
- wdi.attributes = 0;
- wdi.titleHeight = tb->rect.height();
- wdi.titleWidth = tb->rect.width();
- QCFType<HIShapeRef> region;
- HIRect hirect = qt_hirectForQRect(tb->rect);
- if (hirect.size.width <= 0)
- hirect.size.width = 100;
- if (hirect.size.height <= 0)
- hirect.size.height = 30;
-
- HIThemeGetWindowShape(&hirect, &wdi, kWindowTitleBarRgn, &region);
- HIRect rect;
- ptrHIShapeGetBounds(region, &rect);
- ret = int(rect.size.height);
- ret += 4;
- }
- break;
- case PM_TabBarTabVSpace:
- ret = 4;
- break;
- case PM_TabBarTabShiftHorizontal:
- case PM_TabBarTabShiftVertical:
- ret = 0;
- break;
- case PM_TabBarBaseHeight:
- ret = 0;
- break;
- case PM_TabBarTabOverlap:
- ret = 0;
- break;
- case PM_TabBarBaseOverlap:
- switch (d->aquaSizeConstrain(opt, widget)) {
- case QAquaSizeUnknown:
- case QAquaSizeLarge:
- ret = 11;
- break;
- case QAquaSizeSmall:
- ret = 8;
- break;
- case QAquaSizeMini:
- ret = 7;
- break;
- }
- break;
- case PM_ScrollBarExtent: {
- switch (d->aquaSizeConstrain(opt, widget)) {
- case QAquaSizeUnknown:
- case QAquaSizeLarge:
- GetThemeMetric(kThemeMetricScrollBarWidth, &ret);
- break;
- case QAquaSizeMini:
- case QAquaSizeSmall:
- GetThemeMetric(kThemeMetricSmallScrollBarWidth, &ret);
- break;
- }
- break; }
- case PM_IndicatorHeight: {
- switch (d->aquaSizeConstrain(opt, widget)) {
- case QAquaSizeUnknown:
- case QAquaSizeLarge:
- GetThemeMetric(kThemeMetricCheckBoxHeight, &ret);
- break;
- case QAquaSizeMini:
- GetThemeMetric(kThemeMetricMiniCheckBoxHeight, &ret);
- break;
- case QAquaSizeSmall:
- GetThemeMetric(kThemeMetricSmallCheckBoxHeight, &ret);
- break;
- }
- break; }
- case PM_IndicatorWidth: {
- switch (d->aquaSizeConstrain(opt, widget)) {
- case QAquaSizeUnknown:
- case QAquaSizeLarge:
- GetThemeMetric(kThemeMetricCheckBoxWidth, &ret);
- break;
- case QAquaSizeMini:
- GetThemeMetric(kThemeMetricMiniCheckBoxWidth, &ret);
- break;
- case QAquaSizeSmall:
- GetThemeMetric(kThemeMetricSmallCheckBoxWidth, &ret);
- break;
- }
- ++ret;
- break; }
- case PM_ExclusiveIndicatorHeight: {
- switch (d->aquaSizeConstrain(opt, widget)) {
- case QAquaSizeUnknown:
- case QAquaSizeLarge:
- GetThemeMetric(kThemeMetricRadioButtonHeight, &ret);
- break;
- case QAquaSizeMini:
- GetThemeMetric(kThemeMetricMiniRadioButtonHeight, &ret);
- break;
- case QAquaSizeSmall:
- GetThemeMetric(kThemeMetricSmallRadioButtonHeight, &ret);
- break;
- }
- break; }
- case PM_ExclusiveIndicatorWidth: {
- switch (d->aquaSizeConstrain(opt, widget)) {
- case QAquaSizeUnknown:
- case QAquaSizeLarge:
- GetThemeMetric(kThemeMetricRadioButtonWidth, &ret);
- break;
- case QAquaSizeMini:
- GetThemeMetric(kThemeMetricMiniRadioButtonWidth, &ret);
- break;
- case QAquaSizeSmall:
- GetThemeMetric(kThemeMetricSmallRadioButtonWidth, &ret);
- break;
- }
- ++ret;
- break; }
- case PM_MenuVMargin:
- ret = 4;
- break;
- case PM_MenuPanelWidth:
- ret = 0;
- break;
- case PM_ToolTipLabelFrameWidth:
- ret = 0;
- break;
- case PM_SizeGripSize: {
- QAquaWidgetSize aSize;
- if (widget && widget->window()->windowType() == Qt::Tool)
- aSize = QAquaSizeSmall;
- else
- aSize = QAquaSizeLarge;
- const QSize size = qt_aqua_get_known_size(CT_SizeGrip, widget, QSize(), aSize);
- ret = size.width();
- break; }
- case PM_MdiSubWindowFrameWidth:
- ret = 1;
- break;
- case PM_DockWidgetFrameWidth:
- ret = 2;
- break;
- case PM_DockWidgetTitleMargin:
- ret = 0;
- break;
- case PM_DockWidgetSeparatorExtent:
- ret = 1;
- break;
- case PM_ToolBarHandleExtent:
- ret = 11;
- break;
- case PM_ToolBarItemMargin:
- ret = 0;
- break;
- case PM_ToolBarItemSpacing:
- ret = 4;
- break;
- case PM_SplitterWidth:
- ret = qMax(7, QApplication::globalStrut().width());
- break;
- case PM_LayoutLeftMargin:
- case PM_LayoutTopMargin:
- case PM_LayoutRightMargin:
- case PM_LayoutBottomMargin:
- {
- bool isWindow = false;
- if (opt) {
- isWindow = (opt->state & State_Window);
- } else if (widget) {
- isWindow = widget->isWindow();
- }
-
- if (isWindow) {
- bool isMetal = widget && widget->testAttribute(Qt::WA_MacBrushedMetal);
- if (isMetal) {
- if (metric == PM_LayoutTopMargin) {
- return_SIZE(9 /* AHIG */, 6 /* guess */, 6 /* guess */);
- } else if (metric == PM_LayoutBottomMargin) {
- return_SIZE(18 /* AHIG */, 15 /* guess */, 13 /* guess */);
- } else {
- return_SIZE(14 /* AHIG */, 11 /* guess */, 9 /* guess */);
- }
- } else {
- /*
- AHIG would have (20, 8, 10) here but that makes
- no sense. It would also have 14 for the top margin
- but this contradicts both Builder and most
- applications.
- */
- return_SIZE(20, 10, 10); // AHIG
- }
- } else {
- // hack to detect QTabWidget
- if (widget && widget->parentWidget()
- && widget->parentWidget()->sizePolicy().controlType() == QSizePolicy::TabWidget) {
- if (metric == PM_LayoutTopMargin) {
- /*
- Builder would have 14 (= 20 - 6) instead of 12,
- but that makes the tab look disproportionate.
- */
- return_SIZE(12, 6, 6); // guess
- } else {
- return_SIZE(20 /* Builder */, 8 /* guess */, 8 /* guess */);
- }
- } else {
- /*
- Child margins are highly inconsistent in AHIG and Builder.
- */
- return_SIZE(12, 8, 6); // guess
- }
- }
- }
- case PM_LayoutHorizontalSpacing:
- case PM_LayoutVerticalSpacing:
- return -1;
- case QStyle::PM_TabBarTabHSpace:
- switch (d->aquaSizeConstrain(opt, widget)) {
- case QAquaSizeLarge:
- case QAquaSizeUnknown:
- ret = QWindowsStyle::pixelMetric(metric, opt, widget);
- break;
- case QAquaSizeSmall:
- ret = 20;
- break;
- case QAquaSizeMini:
- ret = 16;
- break;
- }
- break;
- case PM_MenuHMargin:
- ret = 0;
- break;
- case PM_ToolBarFrameWidth:
- ret = 1;
- if (widget) {
- if (QMainWindow * mainWindow = qobject_cast<QMainWindow *>(widget->parent()))
- if (mainWindow->unifiedTitleAndToolBarOnMac())
- ret = 0;
- }
- break;
- default:
- ret = QWindowsStyle::pixelMetric(metric, opt, widget);
- break;
- }
- return ret;
-}
-
-QPalette QMacStyle::standardPalette() const
-{
- QPalette pal = QWindowsStyle::standardPalette();
- pal.setColor(QPalette::Disabled, QPalette::Dark, QColor(191, 191, 191));
- pal.setColor(QPalette::Active, QPalette::Dark, QColor(191, 191, 191));
- pal.setColor(QPalette::Inactive, QPalette::Dark, QColor(191, 191, 191));
- return pal;
-}
-
-int QMacStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *w,
- QStyleHintReturn *hret) const
-{
- SInt32 ret = 0;
- switch (sh) {
- case SH_Menu_SelectionWrap:
- ret = false;
- break;
- case SH_Menu_KeyboardSearch:
- ret = true;
- break;
- case SH_Menu_SpaceActivatesItem:
- ret = true;
- break;
- case SH_Slider_AbsoluteSetButtons:
- ret = Qt::LeftButton|Qt::MidButton;
- break;
- case SH_Slider_PageSetButtons:
- ret = 0;
- break;
- case SH_ScrollBar_ContextMenu:
- ret = false;
- break;
- case SH_TitleBar_AutoRaise:
- ret = true;
- break;
- case SH_Menu_AllowActiveAndDisabled:
- ret = false;
- break;
- case SH_Menu_SubMenuPopupDelay:
- ret = 100;
- break;
- case SH_ScrollBar_LeftClickAbsolutePosition: {
- extern bool qt_scrollbar_jump_to_pos; //qapplication_mac.cpp
- if(QApplication::keyboardModifiers() & Qt::AltModifier)
- ret = !qt_scrollbar_jump_to_pos;
- else
- ret = qt_scrollbar_jump_to_pos;
- break; }
- case SH_TabBar_PreferNoArrows:
- ret = true;
- break;
- case SH_LineEdit_PasswordCharacter:
- ret = kBulletUnicode;
- break;
- /*
- case SH_DialogButtons_DefaultButton:
- ret = QDialogButtons::Reject;
- break;
- */
- case SH_Menu_SloppySubMenus:
- ret = true;
- break;
- case SH_GroupBox_TextLabelVerticalAlignment:
- ret = Qt::AlignTop;
- break;
- case SH_ScrollView_FrameOnlyAroundContents:
- if (w && (w->isWindow() || !w->parentWidget() || w->parentWidget()->isWindow())
- && (w->inherits("QWorkspaceChild")
-#ifdef QT3_SUPPORT
- || w->inherits("QScrollView")
-#endif
- ))
- ret = true;
- else
- ret = QWindowsStyle::styleHint(sh, opt, w, hret);
- break;
- case SH_Menu_FillScreenWithScroll:
- ret = false;
- break;
- case SH_Menu_Scrollable:
- ret = true;
- break;
- case SH_RichText_FullWidthSelection:
- ret = true;
- break;
- case SH_BlinkCursorWhenTextSelected:
- ret = false;
- break;
- case SH_ScrollBar_StopMouseOverSlider:
- ret = true;
- break;
- case SH_Q3ListViewExpand_SelectMouseType:
- ret = QEvent::MouseButtonRelease;
- break;
- case SH_TabBar_SelectMouseType:
- if (const QStyleOptionTabBarBaseV2 *opt2 = qstyleoption_cast<const QStyleOptionTabBarBaseV2 *>(opt)) {
- ret = opt2->documentMode ? QEvent::MouseButtonPress : QEvent::MouseButtonRelease;
- } else {
- ret = QEvent::MouseButtonRelease;
- }
- break;
- case SH_ComboBox_Popup:
- if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(opt))
- ret = !cmb->editable;
- else
- ret = 0;
- break;
- case SH_Workspace_FillSpaceOnMaximize:
- ret = true;
- break;
- case SH_Widget_ShareActivation:
- ret = true;
- break;
- case SH_Header_ArrowAlignment:
- ret = Qt::AlignRight;
- break;
- case SH_TabBar_Alignment: {
- if (const QTabWidget *tab = qobject_cast<const QTabWidget*>(w)) {
- if (tab->documentMode()) {
- ret = Qt::AlignLeft;
- break;
- }
- }
- if (const QTabBar *tab = qobject_cast<const QTabBar*>(w)) {
- if (tab->documentMode()) {
- ret = Qt::AlignLeft;
- break;
- }
- }
- ret = Qt::AlignCenter;
- } break;
- case SH_UnderlineShortcut:
- ret = false;
- break;
- case SH_ToolTipLabel_Opacity:
- ret = 242; // About 95%
- break;
- case SH_Button_FocusPolicy:
- ret = Qt::TabFocus;
- break;
- case SH_EtchDisabledText:
- ret = false;
- break;
- case SH_FocusFrame_Mask: {
- ret = true;
- if(QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask*>(hret)) {
- const uchar fillR = 192, fillG = 191, fillB = 190;
- QImage img;
-
- QSize pixmapSize = opt->rect.size();
- if (pixmapSize.isValid()) {
- QPixmap pix(pixmapSize);
- pix.fill(QColor(fillR, fillG, fillB));
- QPainter pix_paint(&pix);
- proxy()->drawControl(CE_FocusFrame, opt, &pix_paint, w);
- pix_paint.end();
- img = pix.toImage();
- }
-
- const QRgb *sptr = (QRgb*)img.bits(), *srow;
- const int sbpl = img.bytesPerLine();
- const int w = sbpl/4, h = img.height();
-
- QImage img_mask(img.width(), img.height(), QImage::Format_ARGB32);
- QRgb *dptr = (QRgb*)img_mask.bits(), *drow;
- const int dbpl = img_mask.bytesPerLine();
-
- for (int y = 0; y < h; ++y) {
- srow = sptr+((y*sbpl)/4);
- drow = dptr+((y*dbpl)/4);
- for (int x = 0; x < w; ++x) {
- const int diff = (((qRed(*srow)-fillR)*(qRed(*srow)-fillR)) +
- ((qGreen(*srow)-fillG)*((qGreen(*srow)-fillG))) +
- ((qBlue(*srow)-fillB)*((qBlue(*srow)-fillB))));
- (*drow++) = (diff < 100) ? 0xffffffff : 0xff000000;
- ++srow;
- }
- }
- QBitmap qmask = QBitmap::fromImage(img_mask);
- mask->region = QRegion(qmask);
- }
- break; }
- case SH_TitleBar_NoBorder:
- ret = 1;
- break;
- case SH_RubberBand_Mask:
- ret = 0;
- break;
- case SH_ComboBox_LayoutDirection:
- ret = Qt::LeftToRight;
- break;
- case SH_ItemView_EllipsisLocation:
- ret = Qt::AlignHCenter;
- break;
- case SH_ItemView_ShowDecorationSelected:
- ret = true;
- break;
- case SH_TitleBar_ModifyNotification:
- ret = false;
- break;
- case SH_ScrollBar_RollBetweenButtons:
- ret = true;
- break;
- case SH_WindowFrame_Mask:
- ret = 1;
- if (QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask *>(hret)) {
- mask->region = opt->rect;
- mask->region -= QRect(opt->rect.left(), opt->rect.top(), 5, 1);
- mask->region -= QRect(opt->rect.left(), opt->rect.top() + 1, 3, 1);
- mask->region -= QRect(opt->rect.left(), opt->rect.top() + 2, 2, 1);
- mask->region -= QRect(opt->rect.left(), opt->rect.top() + 3, 1, 2);
-
- mask->region -= QRect(opt->rect.right() - 4, opt->rect.top(), 5, 1);
- mask->region -= QRect(opt->rect.right() - 2, opt->rect.top() + 1, 3, 1);
- mask->region -= QRect(opt->rect.right() - 1, opt->rect.top() + 2, 2, 1);
- mask->region -= QRect(opt->rect.right() , opt->rect.top() + 3, 1, 2);
- }
- break;
- case SH_TabBar_ElideMode:
- ret = Qt::ElideRight;
- break;
- case SH_DialogButtonLayout:
- ret = QDialogButtonBox::MacLayout;
- break;
- case SH_FormLayoutWrapPolicy:
- ret = QFormLayout::DontWrapRows;
- break;
- case SH_FormLayoutFieldGrowthPolicy:
- ret = QFormLayout::FieldsStayAtSizeHint;
- break;
- case SH_FormLayoutFormAlignment:
- ret = Qt::AlignHCenter | Qt::AlignTop;
- break;
- case SH_FormLayoutLabelAlignment:
- ret = Qt::AlignRight;
- break;
- case SH_ComboBox_PopupFrameStyle:
- ret = QFrame::NoFrame | QFrame::Plain;
- break;
- case SH_MessageBox_TextInteractionFlags:
- ret = Qt::TextSelectableByMouse | Qt::LinksAccessibleByMouse | Qt::TextSelectableByKeyboard;
- break;
- case SH_SpellCheckUnderlineStyle:
- ret = QTextCharFormat::DashUnderline;
- break;
- case SH_MessageBox_CenterButtons:
- ret = false;
- break;
- case SH_MenuBar_AltKeyNavigation:
- ret = false;
- break;
- case SH_ItemView_MovementWithoutUpdatingSelection:
- ret = false;
- break;
- case SH_FocusFrame_AboveWidget:
- ret = true;
- break;
- case SH_WizardStyle:
- ret = QWizard::MacStyle;
- break;
- case SH_ItemView_ArrowKeysNavigateIntoChildren:
- ret = false;
- break;
- case SH_Menu_FlashTriggeredItem:
- ret = true;
- break;
- case SH_Menu_FadeOutOnHide:
- ret = true;
- break;
- case SH_Menu_Mask:
- if (opt) {
- if (QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask*>(hret)) {
- ret = true;
- HIRect menuRect = CGRectMake(opt->rect.x(), opt->rect.y() + 4,
- opt->rect.width(), opt->rect.height() - 8);
- HIThemeMenuDrawInfo mdi;
- mdi.version = 0;
- if (w && qobject_cast<QMenu *>(w->parentWidget()))
- mdi.menuType = kThemeMenuTypeHierarchical;
- else
- mdi.menuType = kThemeMenuTypePopUp;
- QCFType<HIShapeRef> shape;
- HIThemeGetMenuBackgroundShape(&menuRect, &mdi, &shape);
- mask->region = QRegion::fromHIShapeRef(shape);
- }
- }
- break;
- case SH_ItemView_PaintAlternatingRowColorsForEmptyArea:
- ret = true;
- break;
- case SH_TabBar_CloseButtonPosition:
- ret = QTabBar::LeftSide;
- break;
- case SH_DockWidget_ButtonsHaveFrame:
- ret = false;
- break;
- default:
- ret = QWindowsStyle::styleHint(sh, opt, w, hret);
- break;
- }
- return ret;
-}
-
-QPixmap QMacStyle::generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap,
- const QStyleOption *opt) const
-{
- switch (iconMode) {
- case QIcon::Disabled: {
- QImage img = pixmap.toImage().convertToFormat(QImage::Format_ARGB32);
- int imgh = img.height();
- int imgw = img.width();
- QRgb pixel;
- for (int y = 0; y < imgh; ++y) {
- for (int x = 0; x < imgw; ++x) {
- pixel = img.pixel(x, y);
- img.setPixel(x, y, qRgba(qRed(pixel), qGreen(pixel), qBlue(pixel),
- qAlpha(pixel) / 2));
- }
- }
- return QPixmap::fromImage(img);
- }
- default:
- ;
- }
- return QWindowsStyle::generatedIconPixmap(iconMode, pixmap, opt);
-}
-
-
-QPixmap QMacStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt,
- const QWidget *widget) const
-{
- // The default implementation of QStyle::standardIconImplementation() is to call standardPixmap()
- // I don't want infinite recursion so if we do get in that situation, just return the Window's
- // standard pixmap instead (since there is no mac-specific icon then). This should be fine until
- // someone changes how Windows standard
- // pixmap works.
- static bool recursionGuard = false;
-
- if (recursionGuard)
- return QWindowsStyle::standardPixmap(standardPixmap, opt, widget);
-
- recursionGuard = true;
- QIcon icon = standardIconImplementation(standardPixmap, opt, widget);
- recursionGuard = false;
- int size;
- switch (standardPixmap) {
- default:
- size = 32;
- break;
- case SP_MessageBoxCritical:
- case SP_MessageBoxQuestion:
- case SP_MessageBoxInformation:
- case SP_MessageBoxWarning:
- size = 64;
- break;
- }
- return icon.pixmap(size, size);
-}
-
-void QMacStyle::setFocusRectPolicy(QWidget *w, FocusRectPolicy policy)
-{
- switch (policy) {
- case FocusDefault:
- break;
- case FocusEnabled:
- case FocusDisabled:
- w->setAttribute(Qt::WA_MacShowFocusRect, policy == FocusEnabled);
- break;
- }
-}
-
-QMacStyle::FocusRectPolicy QMacStyle::focusRectPolicy(const QWidget *w)
-{
- return w->testAttribute(Qt::WA_MacShowFocusRect) ? FocusEnabled : FocusDisabled;
-}
-
-void QMacStyle::setWidgetSizePolicy(const QWidget *widget, WidgetSizePolicy policy)
-{
- QWidget *wadget = const_cast<QWidget *>(widget);
- wadget->setAttribute(Qt::WA_MacNormalSize, policy == SizeLarge);
- wadget->setAttribute(Qt::WA_MacSmallSize, policy == SizeSmall);
- wadget->setAttribute(Qt::WA_MacMiniSize, policy == SizeMini);
-}
-
-QMacStyle::WidgetSizePolicy QMacStyle::widgetSizePolicy(const QWidget *widget)
-{
- while (widget) {
- if (widget->testAttribute(Qt::WA_MacMiniSize)) {
- return SizeMini;
- } else if (widget->testAttribute(Qt::WA_MacSmallSize)) {
- return SizeSmall;
- } else if (widget->testAttribute(Qt::WA_MacNormalSize)) {
- return SizeLarge;
- }
- widget = widget->parentWidget();
- }
- return SizeDefault;
-}
-
-void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p,
- const QWidget *w) const
-{
- ThemeDrawState tds = d->getDrawState(opt->state);
- QMacCGContext cg(p);
- switch (pe) {
- case PE_IndicatorArrowUp:
- case PE_IndicatorArrowDown:
- case PE_IndicatorArrowRight:
- case PE_IndicatorArrowLeft: {
- p->save();
- p->setRenderHint(QPainter::Antialiasing);
- int xOffset = opt->direction == Qt::LeftToRight ? 2 : -1;
- QMatrix matrix;
- matrix.translate(opt->rect.center().x() + xOffset, opt->rect.center().y() + 2);
- QPainterPath path;
- switch(pe) {
- default:
- case PE_IndicatorArrowDown:
- break;
- case PE_IndicatorArrowUp:
- matrix.rotate(180);
- break;
- case PE_IndicatorArrowLeft:
- matrix.rotate(90);
- break;
- case PE_IndicatorArrowRight:
- matrix.rotate(-90);
- break;
- }
- path.moveTo(0, 5);
- path.lineTo(-4, -3);
- path.lineTo(4, -3);
- p->setMatrix(matrix);
- p->setPen(Qt::NoPen);
- p->setBrush(QColor(0, 0, 0, 135));
- p->drawPath(path);
- p->restore();
- break; }
- case PE_FrameTabBarBase:
- if (const QStyleOptionTabBarBaseV2 *tbb
- = qstyleoption_cast<const QStyleOptionTabBarBaseV2 *>(opt)) {
- if (tbb->documentMode) {
- p->save();
- drawTabBase(p, tbb, w);
- p->restore();
- return;
- }
-
- QRegion region(tbb->rect);
- region -= tbb->tabBarRect;
- p->save();
- p->setClipRegion(region);
- QStyleOptionTabWidgetFrame twf;
- twf.QStyleOption::operator=(*tbb);
- twf.shape = tbb->shape;
- switch (getTabDirection(twf.shape)) {
- case kThemeTabNorth:
- twf.rect = twf.rect.adjusted(0, 0, 0, 10);
- break;
- case kThemeTabSouth:
- twf.rect = twf.rect.adjusted(0, -10, 0, 0);
- break;
- case kThemeTabWest:
- twf.rect = twf.rect.adjusted(0, 0, 10, 0);
- break;
- case kThemeTabEast:
- twf.rect = twf.rect.adjusted(0, -10, 0, 0);
- break;
- }
- proxy()->drawPrimitive(PE_FrameTabWidget, &twf, p, w);
- p->restore();
- }
- break;
- case PE_PanelTipLabel:
- p->fillRect(opt->rect, opt->palette.brush(QPalette::ToolTipBase));
- break;
- case PE_FrameGroupBox:
- if (const QStyleOptionFrame *groupBox = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
- const QStyleOptionFrameV2 *frame2 = qstyleoption_cast<const QStyleOptionFrameV2 *>(opt);
- if (frame2 && frame2->features & QStyleOptionFrameV2::Flat) {
- QWindowsStyle::drawPrimitive(pe, groupBox, p, w);
- } else {
- HIThemeGroupBoxDrawInfo gdi;
- gdi.version = qt_mac_hitheme_version;
- gdi.state = tds;
- if (w && qobject_cast<QGroupBox *>(w->parentWidget()))
- gdi.kind = kHIThemeGroupBoxKindSecondary;
- else
- gdi.kind = kHIThemeGroupBoxKindPrimary;
- HIRect hirect = qt_hirectForQRect(opt->rect);
- HIThemeDrawGroupBox(&hirect, &gdi, cg, kHIThemeOrientationNormal);
- }
- }
- break;
- case PE_IndicatorToolBarSeparator: {
- QPainterPath path;
- if (opt->state & State_Horizontal) {
- int xpoint = opt->rect.center().x();
- path.moveTo(xpoint + 0.5, opt->rect.top() + 1);
- path.lineTo(xpoint + 0.5, opt->rect.bottom());
- } else {
- int ypoint = opt->rect.center().y();
- path.moveTo(opt->rect.left() + 2 , ypoint + 0.5);
- path.lineTo(opt->rect.right() + 1, ypoint + 0.5);
- }
- QPainterPathStroker theStroker;
- theStroker.setCapStyle(Qt::FlatCap);
- theStroker.setDashPattern(QVector<qreal>() << 1 << 2);
- path = theStroker.createStroke(path);
- p->fillPath(path, QColor(0, 0, 0, 119));
- }
- break;
- case PE_FrameWindow:
- break;
- case PE_IndicatorDockWidgetResizeHandle: {
- // The docwidget resize handle is drawn as a one-pixel wide line.
- p->save();
- if (opt->state & State_Horizontal) {
- p->setPen(QColor(160, 160, 160));
- p->drawLine(opt->rect.topLeft(), opt->rect.topRight());
- } else {
- p->setPen(QColor(145, 145, 145));
- p->drawLine(opt->rect.topRight(), opt->rect.bottomRight());
- }
- p->restore();
- } break;
- case PE_IndicatorToolBarHandle: {
- p->save();
- QPainterPath path;
- int x = opt->rect.x() + 6;
- int y = opt->rect.y() + 5;
- static const int RectHeight = 2;
- if (opt->state & State_Horizontal) {
- while (y < opt->rect.height() - RectHeight - 6) {
- path.moveTo(x, y);
- path.addRect(x, y, RectHeight, RectHeight);
- y += 6;
- }
- } else {
- while (x < opt->rect.width() - RectHeight - 6) {
- path.moveTo(x, y);
- path.addRect(x, y, RectHeight, RectHeight);
- x += 6;
- }
- }
- p->setPen(Qt::NoPen);
- QColor dark = opt->palette.dark().color();
- dark.setAlphaF(0.75);
- QColor light = opt->palette.light().color();
- light.setAlphaF(0.6);
- p->fillPath(path, light);
- p->save();
- p->translate(1, 1);
- p->fillPath(path, dark);
- p->restore();
- p->translate(3, 3);
- p->fillPath(path, light);
- p->translate(1, 1);
- p->fillPath(path, dark);
- p->restore();
-
- break;
- }
- case PE_IndicatorHeaderArrow:
- if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
- // In HITheme, up is down, down is up and hamburgers eat people.
- if (header->sortIndicator != QStyleOptionHeader::None)
- proxy()->drawPrimitive(
- (header->sortIndicator == QStyleOptionHeader::SortDown) ?
- PE_IndicatorArrowUp : PE_IndicatorArrowDown, header, p, w);
- }
- break;
- case PE_IndicatorMenuCheckMark: {
- const int checkw = 8;
- const int checkh = 8;
- const int xoff = qMax(0, (opt->rect.width() - checkw) / 2);
- const int yoff = qMax(0, (opt->rect.width() - checkh) / 2);
- const int x1 = xoff + opt->rect.x();
- const int y1 = yoff + opt->rect.y() + checkw/2;
- const int x2 = xoff + opt->rect.x() + checkw/4;
- const int y2 = yoff + opt->rect.y() + checkh;
- const int x3 = xoff + opt->rect.x() + checkw;
- const int y3 = yoff + opt->rect.y();
-
- QVector<QLineF> a(2);
- a << QLineF(x1, y1, x2, y2);
- a << QLineF(x2, y2, x3, y3);
- if (opt->palette.currentColorGroup() == QPalette::Active)
- p->setPen(QPen(Qt::white, 3));
- else
- p->setPen(QPen(QColor(100, 100, 100), 3));
- p->save();
- p->setRenderHint(QPainter::Antialiasing);
- p->drawLines(a);
- p->restore();
- break; }
- case PE_IndicatorViewItemCheck:
- case PE_Q3CheckListExclusiveIndicator:
- case PE_Q3CheckListIndicator:
- case PE_IndicatorRadioButton:
- case PE_IndicatorCheckBox: {
- bool drawColorless = (!(opt->state & State_Active))
- && opt->palette.currentColorGroup() == QPalette::Active;
- HIThemeButtonDrawInfo bdi;
- bdi.version = qt_mac_hitheme_version;
- bdi.state = tds;
- if (drawColorless && tds == kThemeStateInactive)
- bdi.state = kThemeStateActive;
- bdi.adornment = kThemeDrawIndicatorOnly;
- if (opt->state & State_HasFocus)
- bdi.adornment |= kThemeAdornmentFocus;
- bool isRadioButton = (pe == PE_Q3CheckListExclusiveIndicator
- || pe == PE_IndicatorRadioButton);
- switch (d->aquaSizeConstrain(opt, w)) {
- case QAquaSizeUnknown:
- case QAquaSizeLarge:
- if (isRadioButton)
- bdi.kind = kThemeRadioButton;
- else
- bdi.kind = kThemeCheckBox;
- break;
- case QAquaSizeMini:
- if (isRadioButton)
- bdi.kind = kThemeMiniRadioButton;
- else
- bdi.kind = kThemeMiniCheckBox;
- break;
- case QAquaSizeSmall:
- if (isRadioButton)
- bdi.kind = kThemeSmallRadioButton;
- else
- bdi.kind = kThemeSmallCheckBox;
- break;
- }
- if (opt->state & State_NoChange)
- bdi.value = kThemeButtonMixed;
- else if (opt->state & State_On)
- bdi.value = kThemeButtonOn;
- else
- bdi.value = kThemeButtonOff;
- HIRect macRect;
- if (pe == PE_Q3CheckListExclusiveIndicator || pe == PE_Q3CheckListIndicator)
- macRect = qt_hirectForQRect(opt->rect);
- else
- macRect = qt_hirectForQRect(opt->rect);
- if (!drawColorless)
- HIThemeDrawButton(&macRect, &bdi, cg, kHIThemeOrientationNormal, 0);
- else
- d->drawColorlessButton(macRect, &bdi, p, opt);
- break; }
- case PE_FrameFocusRect:
- // Use the our own focus widget stuff.
- break;
- case PE_IndicatorBranch: {
- if (!(opt->state & State_Children))
- break;
- HIThemeButtonDrawInfo bi;
- bi.version = qt_mac_hitheme_version;
- bi.state = tds;
- if (tds == kThemeStateInactive && opt->palette.currentColorGroup() == QPalette::Active)
- bi.state = kThemeStateActive;
- if (opt->state & State_Sunken)
- bi.state |= kThemeStatePressed;
- bi.kind = kThemeDisclosureButton;
- if (opt->state & State_Open)
- bi.value = kThemeDisclosureDown;
- else
- bi.value = opt->direction == Qt::LeftToRight ? kThemeDisclosureRight : kThemeDisclosureLeft;
- bi.adornment = kThemeAdornmentNone;
- HIRect hirect = qt_hirectForQRect(opt->rect.adjusted(DisclosureOffset,0,-DisclosureOffset,0));
- HIThemeDrawButton(&hirect, &bi, cg, kHIThemeOrientationNormal, 0);
- break; }
-
- case PE_Frame: {
- QPen oldPen = p->pen();
- p->setPen(opt->palette.base().color().darker(140));
- p->drawRect(opt->rect.adjusted(0, 0, -1, -1));
- p->setPen(opt->palette.base().color().darker(180));
- p->drawLine(opt->rect.topLeft(), opt->rect.topRight());
- p->setPen(oldPen);
- break; }
-
- case PE_FrameLineEdit:
- if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
- if (frame->state & State_Sunken) {
- QColor baseColor(frame->palette.background().color());
- HIThemeFrameDrawInfo fdi;
- fdi.version = qt_mac_hitheme_version;
- fdi.state = tds;
- SInt32 frame_size;
- if (pe == PE_FrameLineEdit) {
- fdi.kind = kHIThemeFrameTextFieldSquare;
- GetThemeMetric(kThemeMetricEditTextFrameOutset, &frame_size);
- if ((frame->state & State_ReadOnly) || !(frame->state & State_Enabled))
- fdi.state = kThemeStateInactive;
- } else {
- baseColor = QColor(150, 150, 150); //hardcoded since no query function --Sam
- fdi.kind = kHIThemeFrameListBox;
- GetThemeMetric(kThemeMetricListBoxFrameOutset, &frame_size);
- }
- fdi.isFocused = (frame->state & State_HasFocus);
- int lw = frame->lineWidth;
- if (lw <= 0)
- lw = proxy()->pixelMetric(PM_DefaultFrameWidth, frame, w);
- { //clear to base color
- p->save();
- p->setPen(QPen(baseColor, lw));
- p->setBrush(Qt::NoBrush);
- p->drawRect(frame->rect);
- p->restore();
- }
- HIRect hirect = qt_hirectForQRect(frame->rect,
- QRect(frame_size, frame_size,
- frame_size * 2, frame_size * 2));
-
- HIThemeDrawFrame(&hirect, &fdi, cg, kHIThemeOrientationNormal);
- } else {
- QWindowsStyle::drawPrimitive(pe, opt, p, w);
- }
- }
- break;
- case PE_PanelLineEdit:
- QWindowsStyle::drawPrimitive(pe, opt, p, w);
- // Draw the focus frame for widgets other than QLineEdit (e.g. for line edits in Webkit).
- // Focus frame is drawn outside the rectangle passed in the option-rect.
- if (const QStyleOptionFrame *panel = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
- if ((opt->state & State_HasFocus) && !qobject_cast<const QLineEdit*>(w)) {
- int vmargin = pixelMetric(QStyle::PM_FocusFrameVMargin);
- int hmargin = pixelMetric(QStyle::PM_FocusFrameHMargin);
- QStyleOptionFrame focusFrame = *panel;
- focusFrame.rect = panel->rect.adjusted(-hmargin, -vmargin, hmargin, vmargin);
- drawControl(CE_FocusFrame, &focusFrame, p, w);
- }
- }
-
- break;
- case PE_FrameTabWidget:
- if (const QStyleOptionTabWidgetFrame *twf
- = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
- HIRect hirect = qt_hirectForQRect(twf->rect);
- HIThemeTabPaneDrawInfo tpdi;
- tpdi.version = qt_mac_hitheme_tab_version();
- tpdi.state = tds;
- tpdi.direction = getTabDirection(twf->shape);
- tpdi.size = kHIThemeTabSizeNormal;
- tpdi.kind = kHIThemeTabKindNormal;
- tpdi.adornment = kHIThemeTabPaneAdornmentNormal;
- HIThemeDrawTabPane(&hirect, &tpdi, cg, kHIThemeOrientationNormal);
- }
- break;
- case PE_PanelScrollAreaCorner: {
- const QBrush brush(opt->palette.brush(QPalette::Base));
- p->fillRect(opt->rect, brush);
- p->setPen(QPen(QColor(217, 217, 217)));
- p->drawLine(opt->rect.topLeft(), opt->rect.topRight());
- p->drawLine(opt->rect.topLeft(), opt->rect.bottomLeft());
- } break;
- case PE_FrameStatusBarItem:
- break;
- case PE_IndicatorTabClose: {
- bool hover = (opt->state & State_MouseOver);
- bool selected = (opt->state & State_Selected);
- bool active = (opt->state & State_Active);
- drawTabCloseButton(p, hover, active, selected);
- } break;
- case PE_PanelStatusBar: {
- if (QSysInfo::MacintoshVersion <= QSysInfo::MV_10_4) {
- QWindowsStyle::drawPrimitive(pe, opt, p, w);
- break;
- }
- // Use the Leopard style only if the status bar is the status bar for a
- // QMainWindow with a unifed toolbar.
- if (w == 0 || w->parent() == 0 || qobject_cast<QMainWindow *>(w->parent()) == 0 ||
- qobject_cast<QMainWindow *>(w->parent())->unifiedTitleAndToolBarOnMac() == false ) {
- QWindowsStyle::drawPrimitive(pe, opt, p, w);
- break;
- }
-
- // Fill the status bar with the titlebar gradient.
- QLinearGradient linearGrad(0, opt->rect.top(), 0, opt->rect.bottom());
- if (opt->state & QStyle::State_Active) {
- linearGrad.setColorAt(0, titlebarGradientActiveBegin);
- linearGrad.setColorAt(1, titlebarGradientActiveEnd);
- } else {
- linearGrad.setColorAt(0, titlebarGradientInactiveBegin);
- linearGrad.setColorAt(1, titlebarGradientInactiveEnd);
- }
- p->fillRect(opt->rect, linearGrad);
-
- // Draw the black separator line at the top of the status bar.
- if (opt->state & QStyle::State_Active)
- p->setPen(titlebarSeparatorLineActive);
- else
- p->setPen(titlebarSeparatorLineInactive);
- p->drawLine(opt->rect.left(), opt->rect.top(), opt->rect.right(), opt->rect.top());
-
- break;
- }
-
- default:
- QWindowsStyle::drawPrimitive(pe, opt, p, w);
- break;
- }
-}
-
-static inline QPixmap darkenPixmap(const QPixmap &pixmap)
-{
- QImage img = pixmap.toImage().convertToFormat(QImage::Format_ARGB32);
- int imgh = img.height();
- int imgw = img.width();
- int h, s, v, a;
- QRgb pixel;
- for (int y = 0; y < imgh; ++y) {
- for (int x = 0; x < imgw; ++x) {
- pixel = img.pixel(x, y);
- a = qAlpha(pixel);
- QColor hsvColor(pixel);
- hsvColor.getHsv(&h, &s, &v);
- s = qMin(100, s * 2);
- v = v / 2;
- hsvColor.setHsv(h, s, v);
- pixel = hsvColor.rgb();
- img.setPixel(x, y, qRgba(qRed(pixel), qGreen(pixel), qBlue(pixel), a));
- }
- }
- return QPixmap::fromImage(img);
-}
-
-
-
-void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter *p,
- const QWidget *w) const
-{
- ThemeDrawState tds = d->getDrawState(opt->state);
- QMacCGContext cg(p);
- switch (ce) {
- case CE_HeaderSection:
- if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
- HIThemeButtonDrawInfo bdi;
- bdi.version = qt_mac_hitheme_version;
- State flags = header->state;
- QRect ir = header->rect;
- bdi.kind = kThemeListHeaderButton;
- bdi.adornment = kThemeAdornmentNone;
- bdi.state = kThemeStateActive;
-
- if (flags & State_On)
- bdi.value = kThemeButtonOn;
- else
- bdi.value = kThemeButtonOff;
-
- if (header->orientation == Qt::Horizontal){
- switch (header->position) {
- case QStyleOptionHeader::Beginning:
- ir.adjust(-1, -1, 0, 0);
- break;
- case QStyleOptionHeader::Middle:
- ir.adjust(-1, -1, 0, 0);
- break;
- case QStyleOptionHeader::OnlyOneSection:
- case QStyleOptionHeader::End:
- ir.adjust(-1, -1, 1, 0);
- break;
- default:
- break;
- }
-
- if (header->position != QStyleOptionHeader::Beginning
- && header->position != QStyleOptionHeader::OnlyOneSection) {
- bdi.adornment = header->direction == Qt::LeftToRight
- ? kThemeAdornmentHeaderButtonLeftNeighborSelected
- : kThemeAdornmentHeaderButtonRightNeighborSelected;
- }
- }
-
- if (flags & State_Active) {
- if (!(flags & State_Enabled))
- bdi.state = kThemeStateUnavailable;
- else if (flags & State_Sunken)
- bdi.state = kThemeStatePressed;
- } else {
- if (flags & State_Enabled)
- bdi.state = kThemeStateInactive;
- else
- bdi.state = kThemeStateUnavailableInactive;
- }
-
- if (header->sortIndicator != QStyleOptionHeader::None) {
- bdi.value = kThemeButtonOn;
- if (header->sortIndicator == QStyleOptionHeader::SortDown)
- bdi.adornment = kThemeAdornmentHeaderButtonSortUp;
- }
- if (flags & State_HasFocus)
- bdi.adornment = kThemeAdornmentFocus;
-
- ir = visualRect(header->direction, header->rect, ir);
- HIRect bounds = qt_hirectForQRect(ir);
-
- bool noVerticalHeader = true;
- if (w)
- if (const QTableView *table = qobject_cast<const QTableView *>(w->parentWidget()))
- noVerticalHeader = !table->verticalHeader()->isVisible();
-
- bool drawTopBorder = header->orientation == Qt::Horizontal;
- bool drawLeftBorder = header->orientation == Qt::Vertical
- || header->position == QStyleOptionHeader::OnlyOneSection
- || (header->position == QStyleOptionHeader::Beginning && noVerticalHeader);
- d->drawTableHeader(bounds, drawTopBorder, drawLeftBorder, bdi, p);
- }
- break;
- case CE_HeaderLabel:
- if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
- QRect textr = header->rect;
- if (!header->icon.isNull()) {
- QIcon::Mode mode = QIcon::Disabled;
- if (opt->state & State_Enabled)
- mode = QIcon::Normal;
- QPixmap pixmap = header->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize), mode);
-
- QRect pixr = header->rect;
- pixr.setY(header->rect.center().y() - (pixmap.height() - 1) / 2);
- proxy()->drawItemPixmap(p, pixr, Qt::AlignVCenter, pixmap);
- textr.translate(pixmap.width() + 2, 0);
- }
-
- proxy()->drawItemText(p, textr, header->textAlignment | Qt::AlignVCenter, header->palette,
- header->state & State_Enabled, header->text, QPalette::ButtonText);
- }
- break;
- case CE_ToolButtonLabel:
- if (const QStyleOptionToolButton *tb = qstyleoption_cast<const QStyleOptionToolButton *>(opt)) {
- QStyleOptionToolButton myTb = *tb;
- myTb.state &= ~State_AutoRaise;
- if (w && qobject_cast<QToolBar *>(w->parentWidget())) {
- QRect cr = tb->rect;
- int shiftX = 0;
- int shiftY = 0;
- bool needText = false;
- int alignment = 0;
- bool down = tb->state & (State_Sunken | State_On);
- if (down) {
- shiftX = proxy()->pixelMetric(PM_ButtonShiftHorizontal, tb, w);
- shiftY = proxy()->pixelMetric(PM_ButtonShiftVertical, tb, w);
- }
- // The down state is special for QToolButtons in a toolbar on the Mac
- // The text is a bit bolder and gets a drop shadow and the icons are also darkened.
- // This doesn't really fit into any particular case in QIcon, so we
- // do the majority of the work ourselves.
- if (!(tb->features & QStyleOptionToolButton::Arrow)) {
- Qt::ToolButtonStyle tbstyle = tb->toolButtonStyle;
- if (tb->icon.isNull() && !tb->text.isEmpty())
- tbstyle = Qt::ToolButtonTextOnly;
-
- switch (tbstyle) {
- case Qt::ToolButtonTextOnly: {
- needText = true;
- alignment = Qt::AlignCenter;
- break; }
- case Qt::ToolButtonIconOnly:
- case Qt::ToolButtonTextBesideIcon:
- case Qt::ToolButtonTextUnderIcon: {
- QRect pr = cr;
- QIcon::Mode iconMode = (tb->state & State_Enabled) ? QIcon::Normal
- : QIcon::Disabled;
- QIcon::State iconState = (tb->state & State_On) ? QIcon::On
- : QIcon::Off;
- QPixmap pixmap = tb->icon.pixmap(tb->rect.size().boundedTo(tb->iconSize), iconMode, iconState);
-
- // Draw the text if it's needed.
- if (tb->toolButtonStyle != Qt::ToolButtonIconOnly) {
- needText = true;
- if (tb->toolButtonStyle == Qt::ToolButtonTextUnderIcon) {
- QMainWindow *mw = qobject_cast<QMainWindow *>(w->window());
- if (mw && mw->unifiedTitleAndToolBarOnMac()) {
- pr.setHeight(pixmap.size().height());
- cr.adjust(0, pr.bottom() + 1, 0, 1);
- } else {
- pr.setHeight(pixmap.size().height() + 6);
- cr.adjust(0, pr.bottom(), 0, -3);
- }
- alignment |= Qt::AlignCenter;
- } else {
- pr.setWidth(pixmap.width() + 8);
- cr.adjust(pr.right(), 0, 0, 0);
- alignment |= Qt::AlignLeft | Qt::AlignVCenter;
- }
- }
- if (opt->state & State_Sunken) {
- pr.translate(shiftX, shiftY);
- pixmap = darkenPixmap(pixmap);
- }
- proxy()->drawItemPixmap(p, pr, Qt::AlignCenter, pixmap);
- break; }
- default:
- Q_ASSERT(false);
- break;
- }
-
- if (needText) {
- QPalette pal = tb->palette;
- QPalette::ColorRole role = QPalette::NoRole;
- if (!proxy()->styleHint(SH_UnderlineShortcut, tb, w))
- alignment |= Qt::TextHideMnemonic;
- if (down)
- cr.translate(shiftX, shiftY);
- if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5
- && (tbstyle == Qt::ToolButtonTextOnly
- || (tbstyle != Qt::ToolButtonTextOnly && !down))) {
- QPen pen = p->pen();
- QColor light = down ? Qt::black : Qt::white;
- light.setAlphaF(0.375f);
- p->setPen(light);
- p->drawText(cr.adjusted(0, 1, 0, 1), alignment, tb->text);
- p->setPen(pen);
- if (down && tbstyle == Qt::ToolButtonTextOnly) {
- pal = QApplication::palette("QMenu");
- pal.setCurrentColorGroup(tb->palette.currentColorGroup());
- role = QPalette::HighlightedText;
- }
- }
- proxy()->drawItemText(p, cr, alignment, pal,
- tb->state & State_Enabled, tb->text, role);
- if (QSysInfo::MacintoshVersion < QSysInfo::MV_10_5 &&
- (tb->state & State_Sunken)) {
- // Draw a "drop shadow" in earlier versions.
- proxy()->drawItemText(p, cr.adjusted(0, 1, 0, 1), alignment,
- tb->palette, tb->state & State_Enabled, tb->text);
- }
- }
- } else {
- QWindowsStyle::drawControl(ce, &myTb, p, w);
- }
- } else {
- QWindowsStyle::drawControl(ce, &myTb, p, w);
- }
- }
- break;
- case CE_ToolBoxTabShape:
- QCommonStyle::drawControl(ce, opt, p, w);
- break;
- case CE_PushButtonBevel:
- if (const QStyleOptionButton *btn = ::qstyleoption_cast<const QStyleOptionButton *>(opt)) {
- if (!(btn->state & (State_Raised | State_Sunken | State_On)))
- break;
-
- if (btn->features & QStyleOptionButton::CommandLinkButton) {
- QWindowsStyle::drawControl(ce, opt, p, w);
- break;
- }
-
- HIThemeButtonDrawInfo bdi;
- d->initHIThemePushButton(btn, w, tds, &bdi);
- if (btn->features & QStyleOptionButton::DefaultButton
- && d->animatable(QMacStylePrivate::AquaPushButton, w)) {
- bdi.adornment |= kThemeAdornmentDefault;
- bdi.animation.time.start = d->defaultButtonStart;
- bdi.animation.time.current = CFAbsoluteTimeGetCurrent();
- if (d->timerID <= -1)
- QMetaObject::invokeMethod(d, "startAnimationTimer", Qt::QueuedConnection);
- }
- // Unlike Carbon, we want the button to always be drawn inside its bounds.
- // Therefore, make the button a bit smaller, so that even if it got focus,
- // the focus 'shadow' will be inside.
- HIRect newRect = qt_hirectForQRect(btn->rect);
- if (bdi.kind == kThemePushButton || bdi.kind == kThemePushButtonSmall) {
- newRect.origin.x += QMacStylePrivate::PushButtonLeftOffset;
- newRect.origin.y += QMacStylePrivate::PushButtonTopOffset;
- newRect.size.width -= QMacStylePrivate::PushButtonRightOffset;
- newRect.size.height -= QMacStylePrivate::PushButtonBottomOffset;
- } else if (bdi.kind == kThemePushButtonMini) {
- newRect.origin.x += QMacStylePrivate::PushButtonLeftOffset - 2;
- newRect.origin.y += QMacStylePrivate::PushButtonTopOffset;
- newRect.size.width -= QMacStylePrivate::PushButtonRightOffset - 4;
- }
- HIThemeDrawButton(&newRect, &bdi, cg, kHIThemeOrientationNormal, 0);
-
- if (btn->features & QStyleOptionButton::HasMenu) {
- int mbi = proxy()->pixelMetric(QStyle::PM_MenuButtonIndicator, btn, w);
- QRect ir = btn->rect;
- HIRect arrowRect = CGRectMake(ir.right() - mbi - QMacStylePrivate::PushButtonRightOffset,
- ir.height() / 2 - 4, mbi, ir.height() / 2);
- bool drawColorless = btn->palette.currentColorGroup() == QPalette::Active;
- if (drawColorless && tds == kThemeStateInactive)
- tds = kThemeStateActive;
-
- HIThemePopupArrowDrawInfo pdi;
- pdi.version = qt_mac_hitheme_version;
- pdi.state = tds;
- pdi.orientation = kThemeArrowDown;
- if (arrowRect.size.width < 8.)
- pdi.size = kThemeArrow5pt;
- else
- pdi.size = kThemeArrow9pt;
- HIThemeDrawPopupArrow(&arrowRect, &pdi, cg, kHIThemeOrientationNormal);
- }
- }
- break;
- case CE_PushButtonLabel:
- if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
- // We really don't want the label to be drawn the same as on
- // windows style if it has an icon and text, then it should be more like a
- // tab. So, cheat a little here. However, if it *is* only an icon
- // the windows style works great, so just use that implementation.
- bool hasMenu = btn->features & QStyleOptionButton::HasMenu;
- bool hasIcon = !btn->icon.isNull();
- bool hasText = !btn->text.isEmpty();
- if (!hasIcon && !hasMenu) {
- // ### this is really overly difficult, simplify.
- // It basically tries to get the right font for "small" and "mini" icons.
- QFont oldFont = p->font();
- QFont newFont = qt_app_fonts_hash()->value("QPushButton", QFont());
- ThemeFontID themeId = kThemePushButtonFont;
- if (oldFont == newFont) { // Yes, use HITheme to draw the text for small sizes.
- switch (d->aquaSizeConstrain(opt, w)) {
- default:
- break;
- case QAquaSizeSmall:
- themeId = kThemeSmallSystemFont;
- break;
- case QAquaSizeMini:
- themeId = kThemeMiniSystemFont;
- break;
- }
- }
- if (themeId == kThemePushButtonFont) {
- QWindowsStyle::drawControl(ce, btn, p, w);
- } else {
- p->save();
- CGContextSetShouldAntialias(cg, true);
- CGContextSetShouldSmoothFonts(cg, true);
- HIThemeTextInfo tti;
- tti.version = qt_mac_hitheme_version;
- tti.state = tds;
- QColor textColor = btn->palette.buttonText().color();
- CGFloat colorComp[] = { textColor.redF(), textColor.greenF(),
- textColor.blueF(), textColor.alphaF() };
- CGContextSetFillColorSpace(cg, QCoreGraphicsPaintEngine::macGenericColorSpace());
- CGContextSetFillColor(cg, colorComp);
- tti.fontID = themeId;
- tti.horizontalFlushness = kHIThemeTextHorizontalFlushCenter;
- tti.verticalFlushness = kHIThemeTextVerticalFlushCenter;
- tti.options = kHIThemeTextBoxOptionNone;
- tti.truncationPosition = kHIThemeTextTruncationNone;
- tti.truncationMaxLines = 1 + btn->text.count(QLatin1Char('\n'));
- QCFString buttonText = qt_mac_removeMnemonics(btn->text);
- QRect r = btn->rect;
- HIRect bounds = qt_hirectForQRect(r);
- HIThemeDrawTextBox(buttonText, &bounds, &tti,
- cg, kHIThemeOrientationNormal);
- p->restore();
- }
- } else {
- if (hasIcon && !hasText) {
- QWindowsStyle::drawControl(ce, btn, p, w);
- } else {
- QRect freeContentRect = btn->rect;
- QRect textRect = itemTextRect(
- btn->fontMetrics, freeContentRect, Qt::AlignCenter, btn->state & State_Enabled, btn->text);
- if (hasMenu)
- textRect.adjust(-1, 0, -1, 0);
- // Draw the icon:
- if (hasIcon) {
- int contentW = textRect.width();
- if (hasMenu)
- contentW += proxy()->pixelMetric(PM_MenuButtonIndicator) + 4;
- QIcon::Mode mode = btn->state & State_Enabled ? QIcon::Normal : QIcon::Disabled;
- if (mode == QIcon::Normal && btn->state & State_HasFocus)
- mode = QIcon::Active;
- // Decide if the icon is should be on or off:
- QIcon::State state = QIcon::Off;
- if (btn->state & State_On)
- state = QIcon::On;
- QPixmap pixmap = btn->icon.pixmap(btn->iconSize, mode, state);
- contentW += pixmap.width() + QMacStylePrivate::PushButtonContentPadding;
- int iconLeftOffset = freeContentRect.x() + (freeContentRect.width() - contentW) / 2;
- int iconTopOffset = freeContentRect.y() + (freeContentRect.height() - pixmap.height()) / 2;
- QRect iconDestRect(iconLeftOffset, iconTopOffset, pixmap.width(), pixmap.height());
- QRect visualIconDestRect = visualRect(btn->direction, freeContentRect, iconDestRect);
- proxy()->drawItemPixmap(p, visualIconDestRect, Qt::AlignLeft | Qt::AlignVCenter, pixmap);
- int newOffset = iconDestRect.x() + iconDestRect.width()
- + QMacStylePrivate::PushButtonContentPadding - textRect.x();
- textRect.adjust(newOffset, 0, newOffset, 0);
- }
- // Draw the text:
- if (hasText) {
- textRect = visualRect(btn->direction, freeContentRect, textRect);
- proxy()->drawItemText(p, textRect, Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic, btn->palette,
- (btn->state & State_Enabled), btn->text, QPalette::ButtonText);
- }
- }
- }
- }
- break;
- case CE_ComboBoxLabel:
- if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
- QStyleOptionComboBox comboCopy = *cb;
- comboCopy.direction = Qt::LeftToRight;
- QWindowsStyle::drawControl(CE_ComboBoxLabel, &comboCopy, p, w);
- }
- break;
- case CE_TabBarTabShape:
- 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;
- }
- }
- HIThemeTabDrawInfo tdi;
- tdi.version = 1;
- tdi.style = kThemeTabNonFront;
- tdi.direction = getTabDirection(tabOpt->shape);
- switch (d->aquaSizeConstrain(opt, w)) {
- default:
- case QAquaSizeUnknown:
- case QAquaSizeLarge:
- tdi.size = kHIThemeTabSizeNormal;
- break;
- case QAquaSizeSmall:
- tdi.size = kHIThemeTabSizeSmall;
- break;
- case QAquaSizeMini:
- tdi.size = kHIThemeTabSizeMini;
- break;
- }
- bool verticalTabs = tdi.direction == kThemeTabWest || tdi.direction == kThemeTabEast;
- QRect tabRect = tabOpt->rect;
-
- bool selected = tabOpt->state & State_Selected;
- if (selected) {
- if (!(tabOpt->state & State_Active))
- tdi.style = kThemeTabFrontUnavailable;
- else if (!(tabOpt->state & State_Enabled))
- tdi.style = kThemeTabFrontInactive;
- else
- tdi.style = kThemeTabFront;
- } else if (!(tabOpt->state & State_Active)) {
- tdi.style = kThemeTabNonFrontUnavailable;
- } else if (!(tabOpt->state & State_Enabled)) {
- tdi.style = kThemeTabNonFrontInactive;
- } else if (tabOpt->state & State_Sunken) {
- tdi.style = kThemeTabFrontInactive; // (should be kThemeTabNonFrontPressed)
- }
- if (tabOpt->state & State_HasFocus)
- tdi.adornment = kHIThemeTabAdornmentFocus;
- else
- tdi.adornment = kHIThemeTabAdornmentNone;
- tdi.kind = kHIThemeTabKindNormal;
- if (!verticalTabs)
- tabRect.setY(tabRect.y() - 1);
- else
- tabRect.setX(tabRect.x() - 1);
- QStyleOptionTab::TabPosition tp = tabOpt->position;
- QStyleOptionTab::SelectedPosition sp = tabOpt->selectedPosition;
- if (tabOpt->direction == Qt::RightToLeft && !verticalTabs) {
- if (sp == QStyleOptionTab::NextIsSelected)
- sp = QStyleOptionTab::PreviousIsSelected;
- else if (sp == QStyleOptionTab::PreviousIsSelected)
- sp = QStyleOptionTab::NextIsSelected;
- switch (tp) {
- case QStyleOptionTab::Beginning:
- tp = QStyleOptionTab::End;
- break;
- case QStyleOptionTab::End:
- tp = QStyleOptionTab::Beginning;
- break;
- default:
- break;
- }
- }
- bool stretchTabs = (!verticalTabs && tabRect.height() > 22) || (verticalTabs && tabRect.width() > 22);
-
- switch (tp) {
- case QStyleOptionTab::Beginning:
- tdi.position = kHIThemeTabPositionFirst;
- if (sp != QStyleOptionTab::NextIsSelected || stretchTabs)
- tdi.adornment |= kHIThemeTabAdornmentTrailingSeparator;
- break;
- case QStyleOptionTab::Middle:
- tdi.position = kHIThemeTabPositionMiddle;
- if (selected)
- tdi.adornment |= kHIThemeTabAdornmentLeadingSeparator;
- if (sp != QStyleOptionTab::NextIsSelected || stretchTabs) // Also when we're selected.
- tdi.adornment |= kHIThemeTabAdornmentTrailingSeparator;
- break;
- case QStyleOptionTab::End:
- tdi.position = kHIThemeTabPositionLast;
- if (selected)
- tdi.adornment |= kHIThemeTabAdornmentLeadingSeparator;
- break;
- case QStyleOptionTab::OnlyOneTab:
- tdi.position = kHIThemeTabPositionOnly;
- break;
- }
- // HITheme doesn't stretch its tabs. Therefore we have to cheat and do the job ourselves.
- if (stretchTabs) {
- HIRect hirect = CGRectMake(0, 0, 23, 23);
- QPixmap pm(23, 23);
- pm.fill(Qt::transparent);
- {
- QMacCGContext pmcg(&pm);
- HIThemeDrawTab(&hirect, &tdi, pmcg, kHIThemeOrientationNormal, 0);
- }
- QStyleHelper::drawBorderPixmap(pm, p, tabRect, 7, 7, 7, 7);
- } else {
- HIRect hirect = qt_hirectForQRect(tabRect);
- HIThemeDrawTab(&hirect, &tdi, cg, kHIThemeOrientationNormal, 0);
- }
- }
- break;
- case CE_TabBarTabLabel:
- if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
- QStyleOptionTabV3 myTab = *tab;
- ThemeTabDirection ttd = getTabDirection(myTab.shape);
- bool verticalTabs = ttd == kThemeTabWest || ttd == kThemeTabEast;
-
- // Check to see if we use have the same as the system font
- // (QComboMenuItem is internal and should never be seen by the
- // outside world, unless they read the source, in which case, it's
- // their own fault).
- bool nonDefaultFont = p->font() != qt_app_fonts_hash()->value("QComboMenuItem");
- if (verticalTabs || nonDefaultFont || !tab->icon.isNull()
- || !myTab.leftButtonSize.isNull() || !myTab.rightButtonSize.isNull()) {
- int heightOffset = 0;
- if (verticalTabs) {
- heightOffset = -1;
- } else if (nonDefaultFont) {
- if (p->fontMetrics().height() == myTab.rect.height())
- heightOffset = 2;
- }
- myTab.rect.setHeight(myTab.rect.height() + heightOffset);
-
- if (myTab.documentMode) {
- p->save();
- rotateTabPainter(p, myTab.shape, myTab.rect);
-
- QPalette np = tab->palette;
- np.setColor(QPalette::WindowText, QColor(255, 255, 255, 75));
- QRect nr = subElementRect(SE_TabBarTabText, opt, w);
- nr.moveTop(-1);
- int alignment = Qt::AlignCenter | Qt::TextShowMnemonic | Qt::TextHideMnemonic;
- proxy()->drawItemText(p, nr, alignment, np, tab->state & State_Enabled,
- tab->text, QPalette::WindowText);
- p->restore();
- }
-
- QCommonStyle::drawControl(ce, &myTab, p, w);
- } else {
- p->save();
- CGContextSetShouldAntialias(cg, true);
- CGContextSetShouldSmoothFonts(cg, true);
- HIThemeTextInfo tti;
- tti.version = qt_mac_hitheme_version;
- tti.state = tds;
- QColor textColor = myTab.palette.windowText().color();
- CGFloat colorComp[] = { textColor.redF(), textColor.greenF(),
- textColor.blueF(), textColor.alphaF() };
- CGContextSetFillColorSpace(cg, QCoreGraphicsPaintEngine::macGenericColorSpace());
- CGContextSetFillColor(cg, colorComp);
- switch (d->aquaSizeConstrain(opt, w)) {
- default:
- case QAquaSizeUnknown:
- case QAquaSizeLarge:
- tti.fontID = kThemeSystemFont;
- break;
- case QAquaSizeSmall:
- tti.fontID = kThemeSmallSystemFont;
- break;
- case QAquaSizeMini:
- tti.fontID = kThemeMiniSystemFont;
- break;
- }
- tti.horizontalFlushness = kHIThemeTextHorizontalFlushCenter;
- tti.verticalFlushness = kHIThemeTextVerticalFlushCenter;
- tti.options = verticalTabs ? kHIThemeTextBoxOptionStronglyVertical : kHIThemeTextBoxOptionNone;
- tti.truncationPosition = kHIThemeTextTruncationNone;
- tti.truncationMaxLines = 1 + myTab.text.count(QLatin1Char('\n'));
- QCFString tabText = qt_mac_removeMnemonics(myTab.text);
- QRect r = myTab.rect.adjusted(0, 0, 0, -1);
- HIRect bounds = qt_hirectForQRect(r);
- HIThemeDrawTextBox(tabText, &bounds, &tti, cg, kHIThemeOrientationNormal);
- p->restore();
- }
- }
- break;
- case CE_DockWidgetTitle:
- if (const QDockWidget *dockWidget = qobject_cast<const QDockWidget *>(w)) {
- bool floating = dockWidget->isFloating();
- if (floating) {
- ThemeDrawState tds = d->getDrawState(opt->state);
- HIThemeWindowDrawInfo wdi;
- wdi.version = qt_mac_hitheme_version;
- wdi.state = tds;
- wdi.windowType = kThemeMovableDialogWindow;
- wdi.titleHeight = opt->rect.height();
- wdi.titleWidth = opt->rect.width();
- wdi.attributes = 0;
-
- HIRect titleBarRect;
- HIRect tmpRect = qt_hirectForQRect(opt->rect);
- {
- QCFType<HIShapeRef> titleRegion;
- QRect newr = opt->rect.adjusted(0, 0, 2, 0);
- HIThemeGetWindowShape(&tmpRect, &wdi, kWindowTitleBarRgn, &titleRegion);
- ptrHIShapeGetBounds(titleRegion, &tmpRect);
- newr.translate(newr.x() - int(tmpRect.origin.x), newr.y() - int(tmpRect.origin.y));
- titleBarRect = qt_hirectForQRect(newr);
- }
- QMacCGContext cg(p);
- HIThemeDrawWindowFrame(&titleBarRect, &wdi, cg, kHIThemeOrientationNormal, 0);
- } else {
- // fill title bar background
- QLinearGradient linearGrad(0, opt->rect.top(), 0, opt->rect.bottom());
- linearGrad.setColorAt(0, mainWindowGradientBegin);
- linearGrad.setColorAt(1, mainWindowGradientEnd);
- p->fillRect(opt->rect, linearGrad);
-
- // draw horizontal lines at top and bottom
- p->save();
- p->setPen(mainWindowGradientBegin.lighter(114));
- p->drawLine(opt->rect.topLeft(), opt->rect.topRight());
- p->setPen(mainWindowGradientEnd.darker(114));
- p->drawLine(opt->rect.bottomLeft(), opt->rect.bottomRight());
- p->restore();
- }
- }
-
- // Draw the text...
- if (const QStyleOptionDockWidget *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(opt)) {
- if (!dwOpt->title.isEmpty()) {
- const QStyleOptionDockWidgetV2 *v2
- = qstyleoption_cast<const QStyleOptionDockWidgetV2*>(dwOpt);
- bool verticalTitleBar = v2 == 0 ? false : v2->verticalTitleBar;
-
- QRect titleRect = subElementRect(SE_DockWidgetTitleBarText, opt, w);
- if (verticalTitleBar) {
- QRect rect = dwOpt->rect;
- QRect r = rect;
- QSize s = r.size();
- s.transpose();
- r.setSize(s);
-
- titleRect = QRect(r.left() + rect.bottom()
- - titleRect.bottom(),
- r.top() + titleRect.left() - rect.left(),
- titleRect.height(), titleRect.width());
-
- p->translate(r.left(), r.top() + r.width());
- p->rotate(-90);
- p->translate(-r.left(), -r.top());
- }
-
- QFont oldFont = p->font();
- p->setFont(qt_app_fonts_hash()->value("QToolButton", p->font()));
- QString text = p->fontMetrics().elidedText(dwOpt->title, Qt::ElideRight,
- titleRect.width());
- drawItemText(p, titleRect,
- Qt::AlignCenter | Qt::TextShowMnemonic, dwOpt->palette,
- dwOpt->state & State_Enabled, text,
- QPalette::WindowText);
- p->setFont(oldFont);
- }
- }
- break;
- case CE_FocusFrame: {
- int xOff = proxy()->pixelMetric(PM_FocusFrameHMargin, opt, w) + 1;
- int yOff = proxy()->pixelMetric(PM_FocusFrameVMargin, opt, w) + 1;
- HIRect hirect = CGRectMake(xOff+opt->rect.x(), yOff+opt->rect.y(), opt->rect.width() - 2 * xOff,
- opt->rect.height() - 2 * yOff);
- HIThemeDrawFocusRect(&hirect, true, QMacCGContext(p), kHIThemeOrientationNormal);
- break; }
- case CE_MenuItem:
- case CE_MenuEmptyArea:
- if (const QStyleOptionMenuItem *mi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
- p->fillRect(mi->rect, opt->palette.background());
- QAquaWidgetSize widgetSize = d->aquaSizeConstrain(opt, w);
- int tabwidth = mi->tabWidth;
- int maxpmw = mi->maxIconWidth;
- bool active = mi->state & State_Selected;
- bool enabled = mi->state & State_Enabled;
- HIRect menuRect = qt_hirectForQRect(mi->menuRect);
- HIRect itemRect = qt_hirectForQRect(mi->rect);
- HIThemeMenuItemDrawInfo mdi;
- mdi.version = qt_mac_hitheme_version;
- mdi.itemType = kThemeMenuItemPlain;
- if (!mi->icon.isNull())
- mdi.itemType |= kThemeMenuItemHasIcon;
- if (mi->menuItemType == QStyleOptionMenuItem::SubMenu)
- mdi.itemType |= kThemeMenuItemHierarchical | kThemeMenuItemHierBackground;
- else
- mdi.itemType |= kThemeMenuItemPopUpBackground;
- if (enabled)
- mdi.state = kThemeMenuActive;
- else
- mdi.state = kThemeMenuDisabled;
- if (active)
- mdi.state |= kThemeMenuSelected;
- QRect contentRect;
- if (mi->menuItemType == QStyleOptionMenuItem::Separator) {
- // First arg should be &menurect, but wacky stuff happens then.
- HIThemeDrawMenuSeparator(&itemRect, &itemRect, &mdi,
- cg, kHIThemeOrientationNormal);
- break;
- } else {
- HIRect cr;
- bool needAlpha = mi->palette.color(QPalette::Button) == Qt::transparent;
- if (needAlpha) {
- needAlpha = true;
- CGContextSaveGState(cg);
- CGContextSetAlpha(cg, 0.0);
- }
- HIThemeDrawMenuItem(&menuRect, &itemRect, &mdi,
- cg, kHIThemeOrientationNormal, &cr);
- if (needAlpha)
- CGContextRestoreGState(cg);
- if (ce == CE_MenuEmptyArea)
- break;
- contentRect = qt_qrectForHIRect(cr);
- }
- int xpos = contentRect.x() + 18;
- int checkcol = maxpmw;
- if (!enabled)
- p->setPen(mi->palette.text().color());
- else if (active)
- p->setPen(mi->palette.highlightedText().color());
- else
- p->setPen(mi->palette.buttonText().color());
-
- if (mi->checked) {
- // Use the HIThemeTextInfo foo to draw the check mark correctly, if we do it,
- // we somehow need to use a special encoding as it doesn't look right with our
- // drawText().
- p->save();
- CGContextSetShouldAntialias(cg, true);
- CGContextSetShouldSmoothFonts(cg, true);
- QColor textColor = p->pen().color();
- CGFloat colorComp[] = { textColor.redF(), textColor.greenF(),
- textColor.blueF(), textColor.alphaF() };
- CGContextSetFillColorSpace(cg, QCoreGraphicsPaintEngine::macGenericColorSpace());
- CGContextSetFillColor(cg, colorComp);
- HIThemeTextInfo tti;
- tti.version = qt_mac_hitheme_version;
- tti.state = tds;
- if (active && enabled)
- tti.state = kThemeStatePressed;
- switch (widgetSize) {
- case QAquaSizeUnknown:
- case QAquaSizeLarge:
- tti.fontID = kThemeMenuItemMarkFont;
- break;
- case QAquaSizeSmall:
- tti.fontID = kThemeSmallSystemFont;
- break;
- case QAquaSizeMini:
- tti.fontID = kThemeMiniSystemFont;
- break;
- }
- tti.horizontalFlushness = kHIThemeTextHorizontalFlushLeft;
- tti.verticalFlushness = kHIThemeTextVerticalFlushCenter;
- tti.options = kHIThemeTextBoxOptionNone;
- tti.truncationPosition = kHIThemeTextTruncationNone;
- tti.truncationMaxLines = 1;
- QCFString checkmark;
-#if 0
- if (mi->checkType == QStyleOptionMenuItem::Exclusive)
- checkmark = QString(QChar(kDiamondUnicode));
- else
-#endif
- checkmark = QString(QChar(kCheckUnicode));
- int mw = checkcol + macItemFrame;
- int mh = contentRect.height() - 2 * macItemFrame;
- int xp = contentRect.x();
- xp += macItemFrame;
- CGFloat outWidth, outHeight, outBaseline;
- HIThemeGetTextDimensions(checkmark, 0, &tti, &outWidth, &outHeight,
- &outBaseline);
- if (widgetSize == QAquaSizeMini)
- outBaseline += 1;
- QRect r(xp, contentRect.y(), mw, mh);
- r.translate(0, p->fontMetrics().ascent() - int(outBaseline) + 1);
- HIRect bounds = qt_hirectForQRect(r);
- HIThemeDrawTextBox(checkmark, &bounds, &tti,
- cg, kHIThemeOrientationNormal);
- p->restore();
- }
- if (!mi->icon.isNull()) {
- QIcon::Mode mode = (mi->state & State_Enabled) ? QIcon::Normal
- : QIcon::Disabled;
- // Always be normal or disabled to follow the Mac style.
- int smallIconSize = proxy()->pixelMetric(PM_SmallIconSize);
- QSize iconSize(smallIconSize, smallIconSize);
- if (const QComboBox *comboBox = qobject_cast<const QComboBox *>(w)) {
- iconSize = comboBox->iconSize();
- }
- QPixmap pixmap = mi->icon.pixmap(iconSize, mode);
- int pixw = pixmap.width();
- int pixh = pixmap.height();
- QRect cr(xpos, contentRect.y(), checkcol, contentRect.height());
- QRect pmr(0, 0, pixw, pixh);
- pmr.moveCenter(cr.center());
- p->drawPixmap(pmr.topLeft(), pixmap);
- xpos += pixw + 6;
- }
-
- QString s = mi->text;
- if (!s.isEmpty()) {
- int t = s.indexOf(QLatin1Char('\t'));
- int text_flags = Qt::AlignRight | Qt::AlignVCenter | Qt::TextHideMnemonic
- | Qt::TextSingleLine | Qt::AlignAbsolute;
- int yPos = contentRect.y();
- if (widgetSize == QAquaSizeMini)
- yPos += 1;
- p->save();
- if (t >= 0) {
- p->setFont(qt_app_fonts_hash()->value("QMenuItem", p->font()));
- int xp = contentRect.right() - tabwidth - macRightBorder
- - macItemHMargin - macItemFrame + 1;
- p->drawText(xp, yPos, tabwidth, contentRect.height(), text_flags,
- s.mid(t + 1));
- s = s.left(t);
- }
-
- const int xm = macItemFrame + maxpmw + macItemHMargin;
- QFont myFont = mi->font;
- // myFont may not have any "hard" flags set. We override
- // the point size so that when it is resolved against the device, this font will win.
- // This is mainly to handle cases where someone sets the font on the window
- // and then the combo inherits it and passes it onward. At that point the resolve mask
- // is very, very weak. This makes it stonger.
- myFont.setPointSizeF(QFontInfo(mi->font).pointSizeF());
- p->setFont(myFont);
- p->drawText(xpos, yPos, contentRect.width() - xm - tabwidth + 1,
- contentRect.height(), text_flags ^ Qt::AlignRight, s);
- p->restore();
- }
- }
- break;
- case CE_MenuHMargin:
- case CE_MenuVMargin:
- case CE_MenuTearoff:
- case CE_MenuScroller:
- if (const QStyleOptionMenuItem *mi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
- p->fillRect(mi->rect, opt->palette.background());
-
- HIRect menuRect = qt_hirectForQRect(mi->menuRect);
- HIRect itemRect = qt_hirectForQRect(mi->rect);
- HIThemeMenuItemDrawInfo mdi;
- mdi.version = qt_mac_hitheme_version;
- if (!(opt->state & State_Enabled))
- mdi.state = kThemeMenuDisabled;
- else if (opt->state & State_Selected)
- mdi.state = kThemeMenuSelected;
- else
- mdi.state = kThemeMenuActive;
- if (ce == CE_MenuScroller) {
- if (opt->state & State_DownArrow)
- mdi.itemType = kThemeMenuItemScrollDownArrow;
- else
- mdi.itemType = kThemeMenuItemScrollUpArrow;
- } else {
- mdi.itemType = kThemeMenuItemPlain;
- }
- HIThemeDrawMenuItem(&menuRect, &itemRect, &mdi,
- cg,
- kHIThemeOrientationNormal, 0);
- if (ce == CE_MenuTearoff) {
- p->setPen(QPen(mi->palette.dark().color(), 1, Qt::DashLine));
- p->drawLine(mi->rect.x() + 2, mi->rect.y() + mi->rect.height() / 2 - 1,
- mi->rect.x() + mi->rect.width() - 4,
- mi->rect.y() + mi->rect.height() / 2 - 1);
- p->setPen(QPen(mi->palette.light().color(), 1, Qt::DashLine));
- p->drawLine(mi->rect.x() + 2, mi->rect.y() + mi->rect.height() / 2,
- mi->rect.x() + mi->rect.width() - 4,
- mi->rect.y() + mi->rect.height() / 2);
- }
- }
- break;
- case CE_MenuBarItem:
- if (const QStyleOptionMenuItem *mi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
- HIRect menuRect = qt_hirectForQRect(mi->menuRect);
- HIRect itemRect = qt_hirectForQRect(mi->rect);
-
- if ((opt->state & State_Selected) && (opt->state & State_Enabled) && (opt->state & State_Sunken)){
- // Draw a selected menu item background:
- HIThemeMenuItemDrawInfo mdi;
- mdi.version = qt_mac_hitheme_version;
- mdi.state = kThemeMenuSelected;
- mdi.itemType = kThemeMenuItemPlain;
- HIThemeDrawMenuItem(&menuRect, &itemRect, &mdi, cg, kHIThemeOrientationNormal, 0);
- } else {
- // Draw the toolbar background:
- HIThemeMenuBarDrawInfo bdi;
- bdi.version = qt_mac_hitheme_version;
- bdi.state = kThemeMenuBarNormal;
- bdi.attributes = 0;
- HIThemeDrawMenuBarBackground(&menuRect, &bdi, cg, kHIThemeOrientationNormal);
- }
-
- if (!mi->icon.isNull()) {
- drawItemPixmap(p, mi->rect,
- Qt::AlignCenter | Qt::TextHideMnemonic | Qt::TextDontClip
- | Qt::TextSingleLine,
- mi->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize),
- (mi->state & State_Enabled) ? QIcon::Normal : QIcon::Disabled));
- } else {
- drawItemText(p, mi->rect,
- Qt::AlignCenter | Qt::TextHideMnemonic | Qt::TextDontClip
- | Qt::TextSingleLine,
- mi->palette, mi->state & State_Enabled,
- mi->text, QPalette::ButtonText);
- }
- }
- break;
- case CE_MenuBarEmptyArea:
- if (const QStyleOptionMenuItem *mi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
- HIThemeMenuBarDrawInfo bdi;
- bdi.version = qt_mac_hitheme_version;
- bdi.state = kThemeMenuBarNormal;
- bdi.attributes = 0;
- HIRect hirect = qt_hirectForQRect(mi->rect);
- HIThemeDrawMenuBarBackground(&hirect, &bdi, cg,
- kHIThemeOrientationNormal);
- break;
- }
- case CE_ProgressBarContents:
- if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) {
- HIThemeTrackDrawInfo tdi;
- tdi.version = qt_mac_hitheme_version;
- tdi.reserved = 0;
- bool isIndeterminate = (pb->minimum == 0 && pb->maximum == 0);
- bool vertical = false;
- bool inverted = false;
- if (const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(opt)) {
- vertical = (pb2->orientation == Qt::Vertical);
- inverted = pb2->invertedAppearance;
- }
- bool reverse = (!vertical && (pb->direction == Qt::RightToLeft));
- if (inverted)
- reverse = !reverse;
- switch (d->aquaSizeConstrain(opt, w)) {
- case QAquaSizeUnknown:
- case QAquaSizeLarge:
- tdi.kind = !isIndeterminate ? kThemeLargeProgressBar
- : kThemeLargeIndeterminateBar;
- break;
- case QAquaSizeMini:
- case QAquaSizeSmall:
- tdi.kind = !isIndeterminate ? kThemeProgressBar : kThemeIndeterminateBar;
- break;
- }
- tdi.bounds = qt_hirectForQRect(pb->rect);
- tdi.max = pb->maximum;
- tdi.min = pb->minimum;
- tdi.value = pb->progress;
- tdi.attributes = vertical ? 0 : kThemeTrackHorizontal;
- tdi.trackInfo.progress.phase = d->progressFrame;
- if (!(pb->state & State_Active))
- tdi.enableState = kThemeTrackInactive;
- else if (!(pb->state & State_Enabled))
- tdi.enableState = kThemeTrackDisabled;
- else
- tdi.enableState = kThemeTrackActive;
- HIThemeOrientation drawOrientation = kHIThemeOrientationNormal;
- if (reverse) {
- if (vertical) {
- drawOrientation = kHIThemeOrientationInverted;
- } else {
- CGContextSaveGState(cg);
- CGContextTranslateCTM(cg, pb->rect.width(), 0);
- CGContextScaleCTM(cg, -1, 1);
- }
- }
- HIThemeDrawTrack(&tdi, 0, cg, drawOrientation);
- if (reverse && !vertical)
- CGContextRestoreGState(cg);
- }
- break;
- case CE_ProgressBarLabel:
- case CE_ProgressBarGroove:
- break;
- case CE_SizeGrip: {
- if (w && w->testAttribute(Qt::WA_MacOpaqueSizeGrip)) {
- HIThemeGrowBoxDrawInfo gdi;
- gdi.version = qt_mac_hitheme_version;
- gdi.state = tds;
- gdi.kind = kHIThemeGrowBoxKindNormal;
- gdi.direction = kThemeGrowRight | kThemeGrowDown;
- gdi.size = kHIThemeGrowBoxSizeNormal;
- HIPoint pt = CGPointMake(opt->rect.x(), opt->rect.y());
- HIThemeDrawGrowBox(&pt, &gdi, cg, kHIThemeOrientationNormal);
- } else {
- // It isn't possible to draw a transparent size grip with the
- // native API, so we do it ourselves here.
- const bool metal = qt_mac_is_metal(w);
- QPen lineColor = metal ? QColor(236, 236, 236) : QColor(82, 82, 82, 192);
- QPen metalHighlight = QColor(5, 5, 5, 192);
- lineColor.setWidth(1);
- p->save();
- p->setRenderHint(QPainter::Antialiasing);
- p->setPen(lineColor);
- const Qt::LayoutDirection layoutDirection = w ? w->layoutDirection() : qApp->layoutDirection();
- const int NumLines = metal ? 4 : 3;
- for (int l = 0; l < NumLines; ++l) {
- const int offset = (l * 4 + (metal ? 2 : 3));
- QPoint start, end;
- if (layoutDirection == Qt::LeftToRight) {
- start = QPoint(opt->rect.width() - offset, opt->rect.height() - 1);
- end = QPoint(opt->rect.width() - 1, opt->rect.height() - offset);
- } else {
- start = QPoint(offset, opt->rect.height() - 1);
- end = QPoint(1, opt->rect.height() - offset);
- }
- p->drawLine(start, end);
- if (metal) {
- p->setPen(metalHighlight);
- p->setRenderHint(QPainter::Antialiasing, false);
- p->drawLine(start + QPoint(0, -1), end + QPoint(0, -1));
- p->setRenderHint(QPainter::Antialiasing, true);
- p->setPen(lineColor);
- }
- }
- p->restore();
- }
- break;
- }
- case CE_Splitter: {
- HIThemeSplitterDrawInfo sdi;
- sdi.version = qt_mac_hitheme_version;
- sdi.state = tds;
- sdi.adornment = qt_mac_is_metal(w) ? kHIThemeSplitterAdornmentMetal
- : kHIThemeSplitterAdornmentNone;
- HIRect hirect = qt_hirectForQRect(opt->rect);
- HIThemeDrawPaneSplitter(&hirect, &sdi, cg, kHIThemeOrientationNormal);
- break; }
- case CE_RubberBand:
- if (const QStyleOptionRubberBand *rubber = qstyleoption_cast<const QStyleOptionRubberBand *>(opt)) {
- QColor fillColor(opt->palette.color(QPalette::Disabled, QPalette::Highlight));
- if (!rubber->opaque) {
- QColor strokeColor;
- // I retrieved these colors from the Carbon-Dev mailing list
- strokeColor.setHsvF(0, 0, 0.86, 1.0);
- fillColor.setHsvF(0, 0, 0.53, 0.25);
- if (opt->rect.width() * opt->rect.height() <= 3) {
- p->fillRect(opt->rect, strokeColor);
- } else {
- QPen oldPen = p->pen();
- QBrush oldBrush = p->brush();
- QPen pen(strokeColor);
- p->setPen(pen);
- p->setBrush(fillColor);
- p->drawRect(opt->rect.adjusted(0, 0, -1, -1));
- p->setPen(oldPen);
- p->setBrush(oldBrush);
- }
- } else {
- p->fillRect(opt->rect, fillColor);
- }
- }
- break;
- case CE_ToolBar: {
- // For unified tool bars, draw nothing.
- if (w) {
- if (QMainWindow * mainWindow = qobject_cast<QMainWindow *>(w->window())) {
- if (mainWindow->unifiedTitleAndToolBarOnMac())
- break;
- }
- }
-
- // draw background gradient
- QLinearGradient linearGrad;
- if (opt->state & State_Horizontal)
- linearGrad = QLinearGradient(0, opt->rect.top(), 0, opt->rect.bottom());
- else
- linearGrad = QLinearGradient(opt->rect.left(), 0, opt->rect.right(), 0);
-
- linearGrad.setColorAt(0, mainWindowGradientBegin);
- linearGrad.setColorAt(1, mainWindowGradientEnd);
- p->fillRect(opt->rect, linearGrad);
-
- p->save();
- if (opt->state & State_Horizontal) {
- p->setPen(mainWindowGradientBegin.lighter(114));
- p->drawLine(opt->rect.topLeft(), opt->rect.topRight());
- p->setPen(mainWindowGradientEnd.darker(114));
- p->drawLine(opt->rect.bottomLeft(), opt->rect.bottomRight());
-
- } else {
- p->setPen(mainWindowGradientBegin.lighter(114));
- p->drawLine(opt->rect.topLeft(), opt->rect.bottomLeft());
- p->setPen(mainWindowGradientEnd.darker(114));
- p->drawLine(opt->rect.topRight(), opt->rect.bottomRight());
- }
- p->restore();
-
-
- } break;
- default:
- QWindowsStyle::drawControl(ce, opt, p, w);
- break;
- }
-}
-
-static void setLayoutItemMargins(int left, int top, int right, int bottom, QRect *rect, Qt::LayoutDirection dir)
-{
- if (dir == Qt::RightToLeft) {
- rect->adjust(-right, top, -left, bottom);
- } else {
- rect->adjust(left, top, right, bottom);
- }
-}
-
-QRect QMacStyle::subElementRect(SubElement sr, const QStyleOption *opt,
- const QWidget *widget) const
-{
- QRect rect;
- int controlSize = getControlSize(opt, widget);
-
- switch (sr) {
- case SE_ItemViewItemText:
- if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(opt)) {
- int fw = proxy()->pixelMetric(PM_FocusFrameHMargin, opt, widget);
- // We add the focusframeargin between icon and text in commonstyle
- rect = QCommonStyle::subElementRect(sr, opt, widget);
- if (vopt->features & QStyleOptionViewItemV2::HasDecoration)
- rect.adjust(-fw, 0, 0, 0);
- }
- break;
- case SE_ToolBoxTabContents:
- rect = QCommonStyle::subElementRect(sr, opt, widget);
- break;
- case SE_PushButtonContents:
- if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
- // Unlike Carbon, we want the button to always be drawn inside its bounds.
- // Therefore, the button is a bit smaller, so that even if it got focus,
- // the focus 'shadow' will be inside. Adjust the content rect likewise.
- HIThemeButtonDrawInfo bdi;
- d->initHIThemePushButton(btn, widget, d->getDrawState(opt->state), &bdi);
- HIRect contentRect = d->pushButtonContentBounds(btn, &bdi);
- rect = qt_qrectForHIRect(contentRect);
- }
- break;
- case SE_HeaderLabel:
- if (qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
- rect = QWindowsStyle::subElementRect(sr, opt, widget);
- if (widget && widget->height() <= 22){
- // We need to allow the text a bit more space when the header is
- // small, otherwise it gets clipped:
- rect.setY(0);
- rect.setHeight(widget->height());
- }
- }
- break;
- case SE_ProgressBarGroove:
- case SE_ProgressBarLabel:
- break;
- case SE_ProgressBarContents:
- rect = opt->rect;
- break;
- case SE_TreeViewDisclosureItem: {
- HIRect inRect = CGRectMake(opt->rect.x(), opt->rect.y(),
- opt->rect.width(), opt->rect.height());
- HIThemeButtonDrawInfo bdi;
- bdi.version = qt_mac_hitheme_version;
- bdi.state = kThemeStateActive;
- bdi.kind = kThemeDisclosureButton;
- bdi.value = kThemeDisclosureRight;
- bdi.adornment = kThemeAdornmentNone;
- HIRect contentRect;
- HIThemeGetButtonContentBounds(&inRect, &bdi, &contentRect);
- QCFType<HIShapeRef> shape;
- HIRect outRect;
- HIThemeGetButtonShape(&inRect, &bdi, &shape);
- ptrHIShapeGetBounds(shape, &outRect);
- rect = QRect(int(outRect.origin.x + DisclosureOffset), int(outRect.origin.y),
- int(contentRect.origin.x - outRect.origin.x + DisclosureOffset),
- int(outRect.size.height));
- break;
- }
- case SE_TabWidgetLeftCorner:
- if (const QStyleOptionTabWidgetFrame *twf
- = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
- switch (twf->shape) {
- case QTabBar::RoundedNorth:
- case QTabBar::TriangularNorth:
- rect = QRect(QPoint(0, 0), twf->leftCornerWidgetSize);
- break;
- case QTabBar::RoundedSouth:
- case QTabBar::TriangularSouth:
- rect = QRect(QPoint(0, twf->rect.height() - twf->leftCornerWidgetSize.height()),
- twf->leftCornerWidgetSize);
- break;
- default:
- break;
- }
- rect = visualRect(twf->direction, twf->rect, rect);
- }
- break;
- case SE_TabWidgetRightCorner:
- if (const QStyleOptionTabWidgetFrame *twf
- = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
- switch (twf->shape) {
- case QTabBar::RoundedNorth:
- case QTabBar::TriangularNorth:
- rect = QRect(QPoint(twf->rect.width() - twf->rightCornerWidgetSize.width(), 0),
- twf->rightCornerWidgetSize);
- break;
- case QTabBar::RoundedSouth:
- case QTabBar::TriangularSouth:
- rect = QRect(QPoint(twf->rect.width() - twf->rightCornerWidgetSize.width(),
- twf->rect.height() - twf->rightCornerWidgetSize.height()),
- twf->rightCornerWidgetSize);
- break;
- default:
- break;
- }
- rect = visualRect(twf->direction, twf->rect, rect);
- }
- break;
- case SE_TabWidgetTabContents:
- rect = QWindowsStyle::subElementRect(sr, opt, widget);
- if (const QStyleOptionTabWidgetFrame *twf
- = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
- if (twf->lineWidth != 0) {
- switch (getTabDirection(twf->shape)) {
- case kThemeTabNorth:
- rect.adjust(+1, +14, -1, -1);
- break;
- case kThemeTabSouth:
- rect.adjust(+1, +1, -1, -14);
- break;
- case kThemeTabWest:
- rect.adjust(+14, +1, -1, -1);
- break;
- case kThemeTabEast:
- rect.adjust(+1, +1, -14, -1);
- }
- }
- }
- break;
- case SE_LineEditContents:
- rect = QWindowsStyle::subElementRect(sr, opt, widget);
- if(widget->parentWidget() && qobject_cast<const QComboBox*>(widget->parentWidget()))
- rect.adjust(-1, -2, 0, 0);
- else
- rect.adjust(-1, 0, 0, +1);
- break;
- case SE_CheckBoxLayoutItem:
- rect = opt->rect;
- if (controlSize == QAquaSizeLarge) {
- setLayoutItemMargins(+2, +3, -9, -4, &rect, opt->direction);
- } else if (controlSize == QAquaSizeSmall) {
- setLayoutItemMargins(+1, +5, 0 /* fix */, -6, &rect, opt->direction);
- } else {
- setLayoutItemMargins(0, +7, 0 /* fix */, -6, &rect, opt->direction);
- }
- break;
- case SE_ComboBoxLayoutItem:
- if (widget && qobject_cast<QToolBar *>(widget->parentWidget())) {
- // Do nothing, because QToolbar needs the entire widget rect.
- // Otherwise it will be clipped. Equivalent to
- // widget->setAttribute(Qt::WA_LayoutUsesWidgetRect), but without
- // all the hassle.
- } else {
- rect = opt->rect;
- if (controlSize == QAquaSizeLarge) {
- rect.adjust(+3, +2, -3, -4);
- } else if (controlSize == QAquaSizeSmall) {
- setLayoutItemMargins(+2, +1, -3, -4, &rect, opt->direction);
- } else {
- setLayoutItemMargins(+1, 0, -2, 0, &rect, opt->direction);
- }
- }
- break;
- case SE_LabelLayoutItem:
- rect = opt->rect;
- setLayoutItemMargins(+1, 0 /* SHOULD be -1, done for alignment */, 0, 0 /* SHOULD be -1, done for alignment */, &rect, opt->direction);
- break;
- case SE_ProgressBarLayoutItem: {
- rect = opt->rect;
- int bottom = SIZE(3, 8, 8);
- if (opt->state & State_Horizontal) {
- rect.adjust(0, +1, 0, -bottom);
- } else {
- setLayoutItemMargins(+1, 0, -bottom, 0, &rect, opt->direction);
- }
- break;
- }
- case SE_PushButtonLayoutItem:
- if (const QStyleOptionButton *buttonOpt
- = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
- if ((buttonOpt->features & QStyleOptionButton::Flat))
- break; // leave rect alone
- }
- rect = opt->rect;
- if (controlSize == QAquaSizeLarge) {
- rect.adjust(+6, +4, -6, -8);
- } else if (controlSize == QAquaSizeSmall) {
- rect.adjust(+5, +4, -5, -6);
- } else {
- rect.adjust(+1, 0, -1, -2);
- }
- break;
- case SE_RadioButtonLayoutItem:
- rect = opt->rect;
- if (controlSize == QAquaSizeLarge) {
- setLayoutItemMargins(+2, +2 /* SHOULD BE +3, done for alignment */,
- 0, -4 /* SHOULD BE -3, done for alignment */, &rect, opt->direction);
- } else if (controlSize == QAquaSizeSmall) {
- rect.adjust(0, +6, 0 /* fix */, -5);
- } else {
- rect.adjust(0, +6, 0 /* fix */, -7);
- }
- break;
- case SE_SliderLayoutItem:
- if (const QStyleOptionSlider *sliderOpt
- = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
- rect = opt->rect;
- if (sliderOpt->tickPosition == QSlider::NoTicks) {
- int above = SIZE(3, 0, 2);
- int below = SIZE(4, 3, 0);
- if (sliderOpt->orientation == Qt::Horizontal) {
- rect.adjust(0, +above, 0, -below);
- } else {
- rect.adjust(+above, 0, -below, 0); //### Seems that QSlider flip the position of the ticks in reverse mode.
- }
- } else if (sliderOpt->tickPosition == QSlider::TicksAbove) {
- int below = SIZE(3, 2, 0);
- if (sliderOpt->orientation == Qt::Horizontal) {
- rect.setHeight(rect.height() - below);
- } else {
- rect.setWidth(rect.width() - below);
- }
- } else if (sliderOpt->tickPosition == QSlider::TicksBelow) {
- int above = SIZE(3, 2, 0);
- if (sliderOpt->orientation == Qt::Horizontal) {
- rect.setTop(rect.top() + above);
- } else {
- rect.setLeft(rect.left() + above);
- }
- }
- }
- break;
- case SE_FrameLayoutItem:
- // hack because QStyleOptionFrameV2 doesn't have a frameStyle member
- if (const QFrame *frame = qobject_cast<const QFrame *>(widget)) {
- rect = opt->rect;
- switch (frame->frameStyle() & QFrame::Shape_Mask) {
- case QFrame::HLine:
- rect.adjust(0, +1, 0, -1);
- break;
- case QFrame::VLine:
- rect.adjust(+1, 0, -1, 0);
- break;
- default:
- ;
- }
- }
- break;
- case SE_GroupBoxLayoutItem:
- rect = opt->rect;
- if (const QStyleOptionGroupBox *groupBoxOpt =
- qstyleoption_cast<const QStyleOptionGroupBox *>(opt)) {
- /*
- AHIG is very inconsistent when it comes to group boxes.
- Basically, we make sure that (non-checkable) group boxes
- and tab widgets look good when laid out side by side.
- */
- if (groupBoxOpt->subControls & (QStyle::SC_GroupBoxCheckBox
- | QStyle::SC_GroupBoxLabel)) {
- int delta;
- if (groupBoxOpt->subControls & QStyle::SC_GroupBoxCheckBox) {
- delta = SIZE(8, 4, 4); // guess
- } else {
- delta = SIZE(15, 12, 12); // guess
- }
- rect.setTop(rect.top() + delta);
- }
- }
- rect.setBottom(rect.bottom() - 1);
- break;
- case SE_TabWidgetLayoutItem:
- if (const QStyleOptionTabWidgetFrame *tabWidgetOpt =
- qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
- /*
- AHIG specifies "12 or 14" as the distance from the window
- edge. We choose 14 and since the default top margin is 20,
- the overlap is 6.
- */
- rect = tabWidgetOpt->rect;
- if (tabWidgetOpt->shape == QTabBar::RoundedNorth)
- rect.setTop(rect.top() + SIZE(6 /* AHIG */, 3 /* guess */, 2 /* AHIG */));
- }
- break;
- default:
- rect = QWindowsStyle::subElementRect(sr, opt, widget);
- break;
- }
- return rect;
-}
-
-static inline void drawToolbarButtonArrow(const QRect &toolButtonRect, ThemeDrawState tds, CGContextRef cg)
-{
- QRect arrowRect = QRect(toolButtonRect.right() - 9, toolButtonRect.bottom() - 9, 7, 5);
- HIThemePopupArrowDrawInfo padi;
- padi.version = qt_mac_hitheme_version;
- padi.state = tds;
- padi.orientation = kThemeArrowDown;
- padi.size = kThemeArrow7pt;
- HIRect hirect = qt_hirectForQRect(arrowRect);
- HIThemeDrawPopupArrow(&hirect, &padi, cg, kHIThemeOrientationNormal);
-}
-
-void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p,
- const QWidget *widget) const
-{
- ThemeDrawState tds = d->getDrawState(opt->state);
- QMacCGContext cg(p);
- switch (cc) {
- case CC_Slider:
- case CC_ScrollBar:
- if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
- HIThemeTrackDrawInfo tdi;
- d->getSliderInfo(cc, slider, &tdi, widget);
- if (slider->state & State_Sunken) {
- if (cc == CC_Slider) {
- if (slider->activeSubControls == SC_SliderHandle)
- tdi.trackInfo.slider.pressState = kThemeThumbPressed;
- else if (slider->activeSubControls == SC_SliderGroove)
- tdi.trackInfo.slider.pressState = kThemeLeftTrackPressed;
- } else {
- if (slider->activeSubControls == SC_ScrollBarSubLine
- || slider->activeSubControls == SC_ScrollBarAddLine) {
- // This test looks complex but it basically boils down
- // to the following: The "RTL look" on the mac also
- // changed the directions of the controls, that's not
- // what people expect (an arrow is an arrow), so we
- // kind of fake and say the opposite button is hit.
- // This works great, up until 10.4 which broke the
- // scroll bars, so I also have actually do something
- // similar when I have an upside down scroll bar
- // because on Tiger I only "fake" the reverse stuff.
- bool reverseHorizontal = (slider->direction == Qt::RightToLeft
- && slider->orientation == Qt::Horizontal);
- if ((reverseHorizontal
- && slider->activeSubControls == SC_ScrollBarAddLine)
- || (!reverseHorizontal
- && slider->activeSubControls == SC_ScrollBarSubLine)) {
- tdi.trackInfo.scrollbar.pressState = kThemeRightInsideArrowPressed
- | kThemeLeftOutsideArrowPressed;
- } else {
- tdi.trackInfo.scrollbar.pressState = kThemeLeftInsideArrowPressed
- | kThemeRightOutsideArrowPressed;
- }
- } else if (slider->activeSubControls == SC_ScrollBarAddPage) {
- tdi.trackInfo.scrollbar.pressState = kThemeRightTrackPressed;
- } else if (slider->activeSubControls == SC_ScrollBarSubPage) {
- tdi.trackInfo.scrollbar.pressState = kThemeLeftTrackPressed;
- } else if (slider->activeSubControls == SC_ScrollBarSlider) {
- tdi.trackInfo.scrollbar.pressState = kThemeThumbPressed;
- }
- }
- }
- HIRect macRect;
- bool tracking = slider->sliderPosition == slider->sliderValue;
- if (!tracking) {
- // Small optimization, the same as q->subControlRect
- QCFType<HIShapeRef> shape;
- HIThemeGetTrackThumbShape(&tdi, &shape);
- ptrHIShapeGetBounds(shape, &macRect);
- tdi.value = slider->sliderValue;
- }
-
- // Remove controls from the scroll bar if it is to short to draw them correctly.
- // This is done in two stages: first the thumb indicator is removed when it is
- // no longer possible to move it, second the up/down buttons are removed when
- // there is not enough space for them.
- if (cc == CC_ScrollBar) {
- const int scrollBarLength = (slider->orientation == Qt::Horizontal)
- ? slider->rect.width() : slider->rect.height();
- const QMacStyle::WidgetSizePolicy sizePolicy = widgetSizePolicy(widget);
- if (scrollBarLength < scrollButtonsCutoffSize(thumbIndicatorCutoff, sizePolicy))
- tdi.attributes &= ~kThemeTrackShowThumb;
- if (scrollBarLength < scrollButtonsCutoffSize(scrollButtonsCutoff, sizePolicy))
- tdi.enableState = kThemeTrackNothingToScroll;
- } else {
- if (!(slider->subControls & SC_SliderHandle))
- tdi.attributes &= ~kThemeTrackShowThumb;
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
- if (!(slider->subControls & SC_SliderGroove))
- tdi.attributes |= kThemeTrackHideTrack;
-#endif
- }
-
- HIThemeDrawTrack(&tdi, tracking ? 0 : &macRect, cg,
- kHIThemeOrientationNormal);
- if (cc == CC_Slider && slider->subControls & SC_SliderTickmarks) {
- if (qt_mac_is_metal(widget)) {
- if (tdi.enableState == kThemeTrackInactive)
- tdi.enableState = kThemeTrackActive; // Looks more Cocoa-like
- }
- int interval = slider->tickInterval;
- if (interval == 0) {
- interval = slider->pageStep;
- if (interval == 0)
- interval = slider->singleStep;
- if (interval == 0)
- interval = 1;
- }
- int numMarks = 1 + ((slider->maximum - slider->minimum) / interval);
-
- if (tdi.trackInfo.slider.thumbDir == kThemeThumbPlain) {
- // They asked for both, so we'll give it to them.
- tdi.trackInfo.slider.thumbDir = kThemeThumbDownward;
- HIThemeDrawTrackTickMarks(&tdi, numMarks,
- cg,
- kHIThemeOrientationNormal);
- tdi.trackInfo.slider.thumbDir = kThemeThumbUpward;
- HIThemeDrawTrackTickMarks(&tdi, numMarks,
- cg,
- kHIThemeOrientationNormal);
- } else {
- HIThemeDrawTrackTickMarks(&tdi, numMarks,
- cg,
- kHIThemeOrientationNormal);
-
- }
- }
- }
- break;
- case CC_Q3ListView:
- if (const QStyleOptionQ3ListView *lv = qstyleoption_cast<const QStyleOptionQ3ListView *>(opt)) {
- if (lv->subControls & SC_Q3ListView)
- QWindowsStyle::drawComplexControl(cc, lv, p, widget);
- if (lv->subControls & (SC_Q3ListViewBranch | SC_Q3ListViewExpand)) {
- int y = lv->rect.y();
- int h = lv->rect.height();
- int x = lv->rect.right() - 10;
- for (int i = 1; i < lv->items.size() && y < h; ++i) {
- QStyleOptionQ3ListViewItem item = lv->items.at(i);
- if (y + item.height > 0 && (item.childCount > 0
- || (item.features & (QStyleOptionQ3ListViewItem::Expandable
- | QStyleOptionQ3ListViewItem::Visible))
- == (QStyleOptionQ3ListViewItem::Expandable
- | QStyleOptionQ3ListViewItem::Visible))) {
- QStyleOption treeOpt(0);
- treeOpt.rect.setRect(x, y + item.height / 2 - 4, 9, 9);
- treeOpt.palette = lv->palette;
- treeOpt.state = lv->state;
- treeOpt.state |= State_Children;
- if (item.state & State_Open)
- treeOpt.state |= State_Open;
- proxy()->drawPrimitive(PE_IndicatorBranch, &treeOpt, p, widget);
- }
- y += item.totalHeight;
- }
- }
- }
- break;
- case CC_SpinBox:
- if (const QStyleOptionSpinBox *sb = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
- QStyleOptionSpinBox newSB = *sb;
- if (sb->frame && (sb->subControls & SC_SpinBoxFrame)) {
- SInt32 frame_size;
- GetThemeMetric(kThemeMetricEditTextFrameOutset, &frame_size);
-
- QRect lineeditRect = proxy()->subControlRect(CC_SpinBox, sb, SC_SpinBoxEditField, widget);
- lineeditRect.adjust(-frame_size, -frame_size, +frame_size, +frame_size);
-
- HIThemeFrameDrawInfo fdi;
- fdi.version = qt_mac_hitheme_version;
- fdi.state = tds;
- fdi.kind = kHIThemeFrameTextFieldSquare;
- fdi.isFocused = false;
- HIRect hirect = qt_hirectForQRect(lineeditRect);
- HIThemeDrawFrame(&hirect, &fdi, cg, kHIThemeOrientationNormal);
- }
- if (sb->subControls & (SC_SpinBoxUp | SC_SpinBoxDown)) {
- HIThemeButtonDrawInfo bdi;
- bdi.version = qt_mac_hitheme_version;
- QAquaWidgetSize aquaSize = d->aquaSizeConstrain(opt, widget);
- switch (aquaSize) {
- case QAquaSizeUnknown:
- case QAquaSizeLarge:
- bdi.kind = kThemeIncDecButton;
- break;
- case QAquaSizeMini:
- bdi.kind = kThemeIncDecButtonMini;
- break;
- case QAquaSizeSmall:
- bdi.kind = kThemeIncDecButtonSmall;
- break;
- }
- if (!(sb->stepEnabled & (QAbstractSpinBox::StepUpEnabled
- | QAbstractSpinBox::StepDownEnabled)))
- tds = kThemeStateUnavailable;
- if (sb->activeSubControls == SC_SpinBoxDown
- && (sb->state & State_Sunken))
- tds = kThemeStatePressedDown;
- else if (sb->activeSubControls == SC_SpinBoxUp
- && (sb->state & State_Sunken))
- tds = kThemeStatePressedUp;
- bdi.state = tds;
- if (!(sb->state & State_Active)
- && sb->palette.currentColorGroup() == QPalette::Active
- && tds == kThemeStateInactive)
- bdi.state = kThemeStateActive;
- bdi.value = kThemeButtonOff;
- bdi.adornment = kThemeAdornmentNone;
-
- QRect updown = proxy()->subControlRect(CC_SpinBox, sb, SC_SpinBoxUp, widget);
-
- updown |= proxy()->subControlRect(CC_SpinBox, sb, SC_SpinBoxDown, widget);
- HIRect newRect = qt_hirectForQRect(updown);
- QRect off_rct;
- HIRect outRect;
- HIThemeGetButtonBackgroundBounds(&newRect, &bdi, &outRect);
- off_rct.setRect(int(newRect.origin.x - outRect.origin.x),
- int(newRect.origin.y - outRect.origin.y),
- int(outRect.size.width - newRect.size.width),
- int(outRect.size.height - newRect.size.height));
-
- newRect = qt_hirectForQRect(updown, off_rct);
- HIThemeDrawButton(&newRect, &bdi, cg, kHIThemeOrientationNormal, 0);
- }
- }
- break;
- case CC_ComboBox:
- if (const QStyleOptionComboBox *combo = qstyleoption_cast<const QStyleOptionComboBox *>(opt)){
- HIThemeButtonDrawInfo bdi;
- d->initComboboxBdi(combo, &bdi, widget, d->getDrawState(opt->state));
- bool drawColorless = combo->palette.currentColorGroup() == QPalette::Active && tds == kThemeStateInactive;
- if (!drawColorless)
- QMacStylePrivate::drawCombobox(qt_hirectForQRect(combo->rect), bdi, p);
- else
- d->drawColorlessButton(qt_hirectForQRect(combo->rect), &bdi, p, opt);
- }
- break;
- case CC_TitleBar:
- if (const QStyleOptionTitleBar *titlebar
- = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) {
- if (titlebar->state & State_Active) {
- if (titlebar->titleBarState & State_Active)
- tds = kThemeStateActive;
- else
- tds = kThemeStateInactive;
- } else {
- tds = kThemeStateInactive;
- }
-
- HIThemeWindowDrawInfo wdi;
- wdi.version = qt_mac_hitheme_version;
- wdi.state = tds;
- wdi.windowType = QtWinType;
- wdi.titleHeight = titlebar->rect.height();
- wdi.titleWidth = titlebar->rect.width();
- wdi.attributes = kThemeWindowHasTitleText;
- // It seems HIThemeDrawTitleBarWidget is not able to draw a dirty
- // close button, so use HIThemeDrawWindowFrame instead.
- if (widget && widget->isWindowModified() && titlebar->subControls & SC_TitleBarCloseButton)
- wdi.attributes |= kThemeWindowHasCloseBox | kThemeWindowHasDirty;
-
- HIRect titleBarRect;
- HIRect tmpRect = qt_hirectForQRect(titlebar->rect);
- {
- QCFType<HIShapeRef> titleRegion;
- QRect newr = titlebar->rect.adjusted(0, 0, 2, 0);
- HIThemeGetWindowShape(&tmpRect, &wdi, kWindowTitleBarRgn, &titleRegion);
- ptrHIShapeGetBounds(titleRegion, &tmpRect);
- newr.translate(newr.x() - int(tmpRect.origin.x), newr.y() - int(tmpRect.origin.y));
- titleBarRect = qt_hirectForQRect(newr);
- }
- HIThemeDrawWindowFrame(&titleBarRect, &wdi, cg, kHIThemeOrientationNormal, 0);
- if (titlebar->subControls & (SC_TitleBarCloseButton
- | SC_TitleBarMaxButton
- | SC_TitleBarMinButton
- | SC_TitleBarNormalButton)) {
- HIThemeWindowWidgetDrawInfo wwdi;
- wwdi.version = qt_mac_hitheme_version;
- wwdi.widgetState = tds;
- if (titlebar->state & State_MouseOver)
- wwdi.widgetState = kThemeStateRollover;
- wwdi.windowType = QtWinType;
- wwdi.attributes = wdi.attributes | kThemeWindowHasFullZoom | kThemeWindowHasCloseBox | kThemeWindowHasCollapseBox;
- wwdi.windowState = wdi.state;
- wwdi.titleHeight = wdi.titleHeight;
- wwdi.titleWidth = wdi.titleWidth;
- ThemeDrawState savedControlState = wwdi.widgetState;
- uint sc = SC_TitleBarMinButton;
- ThemeTitleBarWidget tbw = kThemeWidgetCollapseBox;
- bool active = titlebar->state & State_Active;
- if (qMacVersion() < QSysInfo::MV_10_6) {
- int border = 2;
- titleBarRect.origin.x += border;
- titleBarRect.origin.y -= border;
- }
-
- while (sc <= SC_TitleBarCloseButton) {
- if (sc & titlebar->subControls) {
- uint tmp = sc;
- wwdi.widgetState = savedControlState;
- wwdi.widgetType = tbw;
- if (sc == SC_TitleBarMinButton)
- tmp |= SC_TitleBarNormalButton;
- if (active && (titlebar->activeSubControls & tmp)
- && (titlebar->state & State_Sunken))
- wwdi.widgetState = kThemeStatePressed;
- // Draw all sub controllers except the dirty close button
- // (it is already handled by HIThemeDrawWindowFrame).
- if (!(widget && widget->isWindowModified() && tbw == kThemeWidgetCloseBox)) {
- HIThemeDrawTitleBarWidget(&titleBarRect, &wwdi, cg, kHIThemeOrientationNormal);
- p->paintEngine()->syncState();
- }
- }
- sc = sc << 1;
- tbw = tbw >> 1;
- }
- }
- p->paintEngine()->syncState();
- if (titlebar->subControls & SC_TitleBarLabel) {
- int iw = 0;
- if (!titlebar->icon.isNull()) {
- QCFType<HIShapeRef> titleRegion2;
- HIThemeGetWindowShape(&titleBarRect, &wdi, kWindowTitleProxyIconRgn,
- &titleRegion2);
- ptrHIShapeGetBounds(titleRegion2, &tmpRect);
- if (tmpRect.size.width != 1) {
- int iconExtent = proxy()->pixelMetric(PM_SmallIconSize);
- iw = titlebar->icon.actualSize(QSize(iconExtent, iconExtent)).width();
- }
- }
- if (!titlebar->text.isEmpty()) {
- p->save();
- QCFType<HIShapeRef> titleRegion3;
- HIThemeGetWindowShape(&titleBarRect, &wdi, kWindowTitleTextRgn, &titleRegion3);
- ptrHIShapeGetBounds(titleRegion3, &tmpRect);
- p->setClipRect(qt_qrectForHIRect(tmpRect));
- QRect br = p->clipRegion().boundingRect();
- int x = br.x(),
- y = br.y() + (titlebar->rect.height() / 2 - p->fontMetrics().height() / 2);
- if (br.width() <= (p->fontMetrics().width(titlebar->text) + iw * 2))
- x += iw;
- else
- x += br.width() / 2 - p->fontMetrics().width(titlebar->text) / 2;
- if (iw)
- p->drawPixmap(x - iw, y,
- titlebar->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize), QIcon::Normal));
- drawItemText(p, br, Qt::AlignCenter, opt->palette, tds == kThemeStateActive,
- titlebar->text, QPalette::Text);
- p->restore();
- }
- }
- }
- break;
- case CC_GroupBox:
- if (const QStyleOptionGroupBox *groupBox
- = qstyleoption_cast<const QStyleOptionGroupBox *>(opt)) {
-
- QStyleOptionGroupBox groupBoxCopy(*groupBox);
- if ((widget && !widget->testAttribute(Qt::WA_SetFont))
- && QApplication::desktopSettingsAware())
- groupBoxCopy.subControls = groupBoxCopy.subControls & ~SC_GroupBoxLabel;
- QWindowsStyle::drawComplexControl(cc, &groupBoxCopy, p, widget);
- if (groupBoxCopy.subControls != groupBox->subControls) {
- bool checkable = groupBox->subControls & SC_GroupBoxCheckBox;
- p->save();
- CGContextSetShouldAntialias(cg, true);
- CGContextSetShouldSmoothFonts(cg, true);
- HIThemeTextInfo tti;
- tti.version = qt_mac_hitheme_version;
- tti.state = tds;
- QColor textColor = groupBox->palette.windowText().color();
- CGFloat colorComp[] = { textColor.redF(), textColor.greenF(),
- textColor.blueF(), textColor.alphaF() };
- CGContextSetFillColorSpace(cg, QCoreGraphicsPaintEngine::macGenericColorSpace());
- CGContextSetFillColor(cg, colorComp);
- tti.fontID = checkable ? kThemeSystemFont : kThemeSmallSystemFont;
- tti.horizontalFlushness = kHIThemeTextHorizontalFlushCenter;
- tti.verticalFlushness = kHIThemeTextVerticalFlushCenter;
- tti.options = kHIThemeTextBoxOptionNone;
- tti.truncationPosition = kHIThemeTextTruncationNone;
- tti.truncationMaxLines = 1 + groupBox->text.count(QLatin1Char('\n'));
- QCFString groupText = qt_mac_removeMnemonics(groupBox->text);
- QRect r = proxy()->subControlRect(CC_GroupBox, groupBox, SC_GroupBoxLabel, widget);
- HIRect bounds = qt_hirectForQRect(r);
- HIThemeDrawTextBox(groupText, &bounds, &tti, cg, kHIThemeOrientationNormal);
- p->restore();
- }
- }
- break;
- case CC_ToolButton:
- if (const QStyleOptionToolButton *tb
- = qstyleoption_cast<const QStyleOptionToolButton *>(opt)) {
- if (widget && qobject_cast<QToolBar *>(widget->parentWidget())) {
- if (tb->subControls & SC_ToolButtonMenu) {
- QStyleOption arrowOpt(0);
- arrowOpt.rect = proxy()->subControlRect(cc, tb, SC_ToolButtonMenu, widget);
- arrowOpt.rect.setY(arrowOpt.rect.y() + arrowOpt.rect.height() / 2);
- arrowOpt.rect.setHeight(arrowOpt.rect.height() / 2);
- arrowOpt.state = tb->state;
- arrowOpt.palette = tb->palette;
- proxy()->drawPrimitive(PE_IndicatorArrowDown, &arrowOpt, p, widget);
- } else if ((tb->features & QStyleOptionToolButton::HasMenu)
- && (tb->toolButtonStyle != Qt::ToolButtonTextOnly && !tb->icon.isNull())) {
- drawToolbarButtonArrow(tb->rect, tds, cg);
- }
- if (tb->state & State_On) {
- if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) {
- static QPixmap pm(QLatin1String(":/trolltech/mac/style/images/leopard-unified-toolbar-on.png"));
- p->setRenderHint(QPainter::SmoothPixmapTransform);
- QStyleHelper::drawBorderPixmap(pm, p, tb->rect, 2, 2, 2, 2);
- } else {
- QPen oldPen = p->pen();
- p->setPen(QColor(0, 0, 0, 0x3a));
- p->fillRect(tb->rect.adjusted(1, 1, -1, -1), QColor(0, 0, 0, 0x12));
- p->drawLine(tb->rect.left() + 1, tb->rect.top(),
- tb->rect.right() - 1, tb->rect.top());
- p->drawLine(tb->rect.left() + 1, tb->rect.bottom(),
- tb->rect.right() - 1, tb->rect.bottom());
- p->drawLine(tb->rect.topLeft(), tb->rect.bottomLeft());
- p->drawLine(tb->rect.topRight(), tb->rect.bottomRight());
- p->setPen(oldPen);
- }
- }
- proxy()->drawControl(CE_ToolButtonLabel, opt, p, widget);
- } else {
- ThemeButtonKind bkind = kThemeBevelButton;
- switch (d->aquaSizeConstrain(opt, widget)) {
- case QAquaSizeUnknown:
- case QAquaSizeLarge:
- bkind = kThemeBevelButton;
- break;
- case QAquaSizeMini:
- case QAquaSizeSmall:
- bkind = kThemeSmallBevelButton;
- break;
- }
-
- QRect button, menuarea;
- button = proxy()->subControlRect(cc, tb, SC_ToolButton, widget);
- menuarea = proxy()->subControlRect(cc, tb, SC_ToolButtonMenu, widget);
- State bflags = tb->state,
- mflags = tb->state;
- if (tb->subControls & SC_ToolButton)
- bflags |= State_Sunken;
- if (tb->subControls & SC_ToolButtonMenu)
- mflags |= State_Sunken;
-
- if (tb->subControls & SC_ToolButton) {
- if (bflags & (State_Sunken | State_On | State_Raised)) {
- HIThemeButtonDrawInfo bdi;
- bdi.version = qt_mac_hitheme_version;
- bdi.state = tds;
- bdi.adornment = kThemeAdornmentNone;
- bdi.kind = bkind;
- bdi.value = kThemeButtonOff;
- if (tb->state & State_HasFocus)
- bdi.adornment = kThemeAdornmentFocus;
- if (tb->state & State_Sunken)
- bdi.state = kThemeStatePressed;
- if (tb->state & State_On)
- bdi.value = kThemeButtonOn;
-
- QRect off_rct(0, 0, 0, 0);
- HIRect myRect, macRect;
- myRect = CGRectMake(tb->rect.x(), tb->rect.y(),
- tb->rect.width(), tb->rect.height());
- HIThemeGetButtonBackgroundBounds(&myRect, &bdi, &macRect);
- off_rct.setRect(int(myRect.origin.x - macRect.origin.x),
- int(myRect.origin.y - macRect.origin.y),
- int(macRect.size.width - myRect.size.width),
- int(macRect.size.height - myRect.size.height));
-
- myRect = qt_hirectForQRect(button, off_rct);
- HIThemeDrawButton(&myRect, &bdi, cg, kHIThemeOrientationNormal, 0);
- }
- }
-
- if (tb->subControls & SC_ToolButtonMenu) {
- HIThemeButtonDrawInfo bdi;
- bdi.version = qt_mac_hitheme_version;
- bdi.state = tds;
- bdi.value = kThemeButtonOff;
- bdi.adornment = kThemeAdornmentNone;
- bdi.kind = bkind;
- if (tb->state & State_HasFocus)
- bdi.adornment = kThemeAdornmentFocus;
- if (tb->state & (State_On | State_Sunken)
- || (tb->activeSubControls & SC_ToolButtonMenu))
- bdi.state = kThemeStatePressed;
- HIRect hirect = qt_hirectForQRect(menuarea);
- HIThemeDrawButton(&hirect, &bdi, cg, kHIThemeOrientationNormal, 0);
- QRect r(menuarea.x() + ((menuarea.width() / 2) - 3), menuarea.height() - 8, 8, 8);
- HIThemePopupArrowDrawInfo padi;
- padi.version = qt_mac_hitheme_version;
- padi.state = tds;
- padi.orientation = kThemeArrowDown;
- padi.size = kThemeArrow7pt;
- hirect = qt_hirectForQRect(r);
- HIThemeDrawPopupArrow(&hirect, &padi, cg, kHIThemeOrientationNormal);
- } else if (tb->features & QStyleOptionToolButton::HasMenu) {
- drawToolbarButtonArrow(tb->rect, tds, cg);
- }
- QRect buttonRect = proxy()->subControlRect(CC_ToolButton, tb, SC_ToolButton, widget);
- int fw = proxy()->pixelMetric(PM_DefaultFrameWidth, opt, widget);
- QStyleOptionToolButton label = *tb;
- label.rect = buttonRect.adjusted(fw, fw, -fw, -fw);
- proxy()->drawControl(CE_ToolButtonLabel, &label, p, widget);
- }
- }
- break;
- case CC_Dial:
- if (const QStyleOptionSlider *dial = qstyleoption_cast<const QStyleOptionSlider *>(opt))
- QStyleHelper::drawDial(dial, p);
- break;
- default:
- QWindowsStyle::drawComplexControl(cc, opt, p, widget);
- break;
- }
-}
-
-QStyle::SubControl QMacStyle::hitTestComplexControl(ComplexControl cc,
- const QStyleOptionComplex *opt,
- const QPoint &pt, const QWidget *widget) const
-{
- SubControl sc = QStyle::SC_None;
- switch (cc) {
- case CC_ComboBox:
- if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
- sc = QWindowsStyle::hitTestComplexControl(cc, cmb, pt, widget);
- if (!cmb->editable && sc != QStyle::SC_None)
- sc = SC_ComboBoxArrow; // A bit of a lie, but what we want
- }
- break;
- case CC_Slider:
- if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
- HIThemeTrackDrawInfo tdi;
- d->getSliderInfo(cc, slider, &tdi, widget);
- ControlPartCode part;
- HIPoint pos = CGPointMake(pt.x(), pt.y());
- if (HIThemeHitTestTrack(&tdi, &pos, &part)) {
- if (part == kControlPageUpPart || part == kControlPageDownPart)
- sc = SC_SliderGroove;
- else
- sc = SC_SliderHandle;
- }
- }
- break;
- case CC_ScrollBar:
- if (const QStyleOptionSlider *sb = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
- HIScrollBarTrackInfo sbi;
- sbi.version = qt_mac_hitheme_version;
- if (!(sb->state & State_Active))
- sbi.enableState = kThemeTrackInactive;
- else if (sb->state & State_Enabled)
- sbi.enableState = kThemeTrackActive;
- else
- sbi.enableState = kThemeTrackDisabled;
-
- // The arrow buttons are not drawn if the scroll bar is to short,
- // exclude them from the hit test.
- const int scrollBarLength = (sb->orientation == Qt::Horizontal)
- ? sb->rect.width() : sb->rect.height();
- if (scrollBarLength < scrollButtonsCutoffSize(scrollButtonsCutoff, widgetSizePolicy(widget)))
- sbi.enableState = kThemeTrackNothingToScroll;
-
- sbi.viewsize = sb->pageStep;
- HIPoint pos = CGPointMake(pt.x(), pt.y());
-
- HIRect macSBRect = qt_hirectForQRect(sb->rect);
- ControlPartCode part;
- bool reverseHorizontal = (sb->direction == Qt::RightToLeft
- && sb->orientation == Qt::Horizontal
- && (!sb->upsideDown ||
- (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4
- && sb->upsideDown)));
- if (HIThemeHitTestScrollBarArrows(&macSBRect, &sbi, sb->orientation == Qt::Horizontal,
- &pos, 0, &part)) {
- if (part == kControlUpButtonPart)
- sc = reverseHorizontal ? SC_ScrollBarAddLine : SC_ScrollBarSubLine;
- else if (part == kControlDownButtonPart)
- sc = reverseHorizontal ? SC_ScrollBarSubLine : SC_ScrollBarAddLine;
- } else {
- HIThemeTrackDrawInfo tdi;
- d->getSliderInfo(cc, sb, &tdi, widget);
- if(tdi.enableState == kThemeTrackInactive)
- tdi.enableState = kThemeTrackActive;
- if (HIThemeHitTestTrack(&tdi, &pos, &part)) {
- if (part == kControlPageUpPart)
- sc = reverseHorizontal ? SC_ScrollBarAddPage
- : SC_ScrollBarSubPage;
- else if (part == kControlPageDownPart)
- sc = reverseHorizontal ? SC_ScrollBarSubPage
- : SC_ScrollBarAddPage;
- else
- sc = SC_ScrollBarSlider;
- }
- }
- }
- break;
-/*
- I don't know why, but we only get kWindowContentRgn here, which isn't what we want at all.
- It would be very nice if this would work.
- case QStyle::CC_TitleBar:
- if (const QStyleOptionTitleBar *tbar = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) {
- HIThemeWindowDrawInfo wdi;
- memset(&wdi, 0, sizeof(wdi));
- wdi.version = qt_mac_hitheme_version;
- wdi.state = kThemeStateActive;
- wdi.windowType = QtWinType;
- wdi.titleWidth = tbar->rect.width();
- wdi.titleHeight = tbar->rect.height();
- if (tbar->titleBarState)
- wdi.attributes |= kThemeWindowHasFullZoom | kThemeWindowHasCloseBox
- | kThemeWindowHasCollapseBox;
- else if (tbar->titleBarFlags & Qt::WindowSystemMenuHint)
- wdi.attributes |= kThemeWindowHasCloseBox;
- QRect tmpRect = tbar->rect;
- tmpRect.setHeight(tmpRect.height() + 100);
- HIRect hirect = qt_hirectForQRect(tmpRect);
- WindowRegionCode hit;
- HIPoint hipt = CGPointMake(pt.x(), pt.y());
- if (HIThemeGetWindowRegionHit(&hirect, &wdi, &hipt, &hit)) {
- switch (hit) {
- case kWindowCloseBoxRgn:
- sc = QStyle::SC_TitleBarCloseButton;
- break;
- case kWindowCollapseBoxRgn:
- sc = QStyle::SC_TitleBarMinButton;
- break;
- case kWindowZoomBoxRgn:
- sc = QStyle::SC_TitleBarMaxButton;
- break;
- case kWindowTitleTextRgn:
- sc = QStyle::SC_TitleBarLabel;
- break;
- default:
- qDebug("got something else %d", hit);
- break;
- }
- }
- }
- break;
-*/
- default:
- sc = QWindowsStyle::hitTestComplexControl(cc, opt, pt, widget);
- break;
- }
- return sc;
-}
-
-QRect QMacStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc,
- const QWidget *widget) const
-{
- QRect ret;
- switch (cc) {
- case CC_Slider:
- case CC_ScrollBar:
- if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
- HIThemeTrackDrawInfo tdi;
- d->getSliderInfo(cc, slider, &tdi, widget);
- HIRect macRect;
- QCFType<HIShapeRef> shape;
- bool scrollBar = cc == CC_ScrollBar;
- if ((scrollBar && sc == SC_ScrollBarSlider)
- || (!scrollBar && sc == SC_SliderHandle)) {
- HIThemeGetTrackThumbShape(&tdi, &shape);
- ptrHIShapeGetBounds(shape, &macRect);
- } else if (!scrollBar && sc == SC_SliderGroove) {
- HIThemeGetTrackBounds(&tdi, &macRect);
- } else if (sc == SC_ScrollBarGroove) { // Only scroll bar parts available...
- HIThemeGetTrackDragRect(&tdi, &macRect);
- } else {
- ControlPartCode cpc;
- if (sc == SC_ScrollBarSubPage || sc == SC_ScrollBarAddPage) {
- cpc = sc == SC_ScrollBarSubPage ? kControlPageDownPart
- : kControlPageUpPart;
- } else {
- cpc = sc == SC_ScrollBarSubLine ? kControlUpButtonPart
- : kControlDownButtonPart;
- if (slider->direction == Qt::RightToLeft
- && slider->orientation == Qt::Horizontal) {
- if (cpc == kControlDownButtonPart)
- cpc = kControlUpButtonPart;
- else if (cpc == kControlUpButtonPart)
- cpc = kControlDownButtonPart;
- }
- }
- HIThemeGetTrackPartBounds(&tdi, cpc, &macRect);
- }
- ret = qt_qrectForHIRect(macRect);
-
- // Tweak: the dark line between the sub/add line buttons belong to only one of the buttons
- // when doing hit-testing, but both of them have to repaint it. Extend the rect to cover
- // the line in the cases where HIThemeGetTrackPartBounds returns a rect that doesn't.
- if (slider->orientation == Qt::Horizontal) {
- if (slider->direction == Qt::LeftToRight && sc == SC_ScrollBarSubLine)
- ret.adjust(0, 0, 1, 0);
- else if (slider->direction == Qt::RightToLeft && sc == SC_ScrollBarAddLine)
- ret.adjust(-1, 0, 1, 0);
- } else if (sc == SC_ScrollBarAddLine) {
- ret.adjust(0, -1, 0, 1);
- }
- }
- break;
- case CC_TitleBar:
- if (const QStyleOptionTitleBar *titlebar
- = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) {
- HIThemeWindowDrawInfo wdi;
- memset(&wdi, 0, sizeof(wdi));
- wdi.version = qt_mac_hitheme_version;
- wdi.state = kThemeStateActive;
- wdi.windowType = QtWinType;
- wdi.titleHeight = titlebar->rect.height();
- wdi.titleWidth = titlebar->rect.width();
- wdi.attributes = kThemeWindowHasTitleText;
- if (titlebar->subControls & SC_TitleBarCloseButton)
- wdi.attributes |= kThemeWindowHasCloseBox;
- if (titlebar->subControls & SC_TitleBarMaxButton
- | SC_TitleBarNormalButton)
- wdi.attributes |= kThemeWindowHasFullZoom;
- if (titlebar->subControls & SC_TitleBarMinButton)
- wdi.attributes |= kThemeWindowHasCollapseBox;
- WindowRegionCode wrc = kWindowGlobalPortRgn;
-
- if (sc == SC_TitleBarCloseButton)
- wrc = kWindowCloseBoxRgn;
- else if (sc == SC_TitleBarMinButton)
- wrc = kWindowCollapseBoxRgn;
- else if (sc == SC_TitleBarMaxButton)
- wrc = kWindowZoomBoxRgn;
- else if (sc == SC_TitleBarLabel)
- wrc = kWindowTitleTextRgn;
- else if (sc == SC_TitleBarSysMenu)
- ret.setRect(-1024, -1024, 10, proxy()->pixelMetric(PM_TitleBarHeight,
- titlebar, widget));
- if (wrc != kWindowGlobalPortRgn) {
- QCFType<HIShapeRef> region;
- QRect tmpRect = titlebar->rect;
- HIRect titleRect = qt_hirectForQRect(tmpRect);
- HIThemeGetWindowShape(&titleRect, &wdi, kWindowTitleBarRgn, &region);
- ptrHIShapeGetBounds(region, &titleRect);
- CFRelease(region);
- tmpRect.translate(tmpRect.x() - int(titleRect.origin.x),
- tmpRect.y() - int(titleRect.origin.y));
- titleRect = qt_hirectForQRect(tmpRect);
- HIThemeGetWindowShape(&titleRect, &wdi, wrc, &region);
- ptrHIShapeGetBounds(region, &titleRect);
- ret = qt_qrectForHIRect(titleRect);
- }
- }
- break;
- case CC_ComboBox:
- if (const QStyleOptionComboBox *combo = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
- HIThemeButtonDrawInfo bdi;
- d->initComboboxBdi(combo, &bdi, widget, d->getDrawState(opt->state));
-
- switch (sc) {
- case SC_ComboBoxEditField:{
- ret = QMacStylePrivate::comboboxEditBounds(combo->rect, bdi);
- // hack to posistion the edit feld correctly for QDateTimeEdits
- // in calendarPopup mode.
- if (qobject_cast<const QDateTimeEdit *>(widget)) {
- ret.moveTop(ret.top() - 2);
- ret.setHeight(ret.height() +1);
- }
- break; }
- case SC_ComboBoxArrow:{
- ret = QMacStylePrivate::comboboxEditBounds(combo->rect, bdi);
- ret.setX(ret.x() + ret.width());
- ret.setWidth(combo->rect.right() - ret.right());
- break; }
- case SC_ComboBoxListBoxPopup:{
- if (combo->editable) {
- HIRect inner = QMacStylePrivate::comboboxInnerBounds(qt_hirectForQRect(combo->rect), bdi.kind);
- QRect editRect = QMacStylePrivate::comboboxEditBounds(combo->rect, bdi);
- const int comboTop = combo->rect.top();
- ret = QRect(qRound(inner.origin.x),
- comboTop,
- qRound(inner.origin.x - combo->rect.left() + inner.size.width),
- editRect.bottom() - comboTop + 2);
- } else {
- QRect editRect = QMacStylePrivate::comboboxEditBounds(combo->rect, bdi);
- ret = QRect(combo->rect.x() + 4 - 11,
- combo->rect.y() + 1,
- editRect.width() + 10 + 11,
- 1);
- }
- break; }
- default:
- break;
- }
- }
- break;
- case CC_GroupBox:
- if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(opt)) {
- bool checkable = groupBox->subControls & SC_GroupBoxCheckBox;
- bool flat = (groupBox->features & QStyleOptionFrameV2::Flat);
- bool hasNoText = !checkable && groupBox->text.isEmpty();
- switch (sc) {
- case SC_GroupBoxLabel:
- case SC_GroupBoxCheckBox: {
- // Cheat and use the smaller font if we need to
- bool checkable = groupBox->subControls & SC_GroupBoxCheckBox;
- bool fontIsSet = (widget && widget->testAttribute(Qt::WA_SetFont))
- || !QApplication::desktopSettingsAware();
- int tw;
- int h;
- int margin = flat || hasNoText ? 0 : 12;
- ret = groupBox->rect.adjusted(margin, 0, -margin, 0);
-
- if (!fontIsSet) {
- HIThemeTextInfo tti;
- tti.version = qt_mac_hitheme_version;
- tti.state = kThemeStateActive;
- tti.fontID = checkable ? kThemeSystemFont : kThemeSmallSystemFont;
- tti.horizontalFlushness = kHIThemeTextHorizontalFlushCenter;
- tti.verticalFlushness = kHIThemeTextVerticalFlushCenter;
- tti.options = kHIThemeTextBoxOptionNone;
- tti.truncationPosition = kHIThemeTextTruncationNone;
- tti.truncationMaxLines = 1 + groupBox->text.count(QLatin1Char('\n'));
- CGFloat width;
- CGFloat height;
- QCFString groupText = qt_mac_removeMnemonics(groupBox->text);
- HIThemeGetTextDimensions(groupText, 0, &tti, &width, &height, 0);
- tw = qRound(width);
- h = qCeil(height);
- } else {
- QFontMetricsF fm = QFontMetricsF(groupBox->fontMetrics);
- h = qCeil(fm.height());
- tw = qCeil(fm.size(Qt::TextShowMnemonic, groupBox->text).width());
- }
- ret.setHeight(h);
-
- QRect labelRect = alignedRect(groupBox->direction, groupBox->textAlignment,
- QSize(tw, h), ret);
- int indicatorWidth = proxy()->pixelMetric(PM_IndicatorWidth, opt, widget);
- bool rtl = groupBox->direction == Qt::RightToLeft;
- if (sc == SC_GroupBoxLabel) {
- if (checkable) {
- int newSum = indicatorWidth + 1;
- int newLeft = labelRect.left() + (rtl ? -newSum : newSum);
- labelRect.moveLeft(newLeft);
- } else if (flat) {
- int newLeft = labelRect.left() - (rtl ? 3 : -3);
- labelRect.moveLeft(newLeft);
- labelRect.moveTop(labelRect.top() + 3);
- } else {
- int newLeft = labelRect.left() - (rtl ? 3 : 2);
- labelRect.moveLeft(newLeft);
- labelRect.moveTop(labelRect.top() + 5);
- }
- ret = labelRect;
- }
-
- if (sc == SC_GroupBoxCheckBox) {
- int left = rtl ? labelRect.right() - indicatorWidth : labelRect.left();
- ret.setRect(left, ret.top(),
- indicatorWidth, proxy()->pixelMetric(PM_IndicatorHeight, opt, widget));
- }
- break;
- }
- case SC_GroupBoxContents:
- case SC_GroupBoxFrame: {
- if (flat) {
- ret = QWindowsStyle::subControlRect(cc, groupBox, sc, widget);
- break;
- }
- QFontMetrics fm = groupBox->fontMetrics;
- bool checkable = groupBox->subControls & SC_GroupBoxCheckBox;
- int yOffset = 3;
- if (!checkable) {
- if (widget && !widget->testAttribute(Qt::WA_SetFont)
- && QApplication::desktopSettingsAware())
- fm = QFontMetrics(qt_app_fonts_hash()->value("QSmallFont", QFont()));
- yOffset = 5;
- if (hasNoText)
- yOffset = -qCeil(QFontMetricsF(fm).height());
- }
-
- ret = opt->rect.adjusted(0, qCeil(QFontMetricsF(fm).height()) + yOffset, 0, 0);
- if (sc == SC_GroupBoxContents)
- ret.adjust(3, 3, -3, -4); // guess
- }
- break;
- default:
- ret = QWindowsStyle::subControlRect(cc, groupBox, sc, widget);
- break;
- }
- }
- break;
- case CC_SpinBox:
- if (const QStyleOptionSpinBox *spin = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
- QAquaWidgetSize aquaSize = d->aquaSizeConstrain(spin, widget);
- int spinner_w;
- int spinBoxSep;
- int fw = proxy()->pixelMetric(PM_SpinBoxFrameWidth, spin, widget);
- switch (aquaSize) {
- default:
- case QAquaSizeUnknown:
- case QAquaSizeLarge:
- spinner_w = 14;
- spinBoxSep = 2;
- break;
- case QAquaSizeSmall:
- spinner_w = 12;
- spinBoxSep = 2;
- break;
- case QAquaSizeMini:
- spinner_w = 10;
- spinBoxSep = 1;
- break;
- }
-
- switch (sc) {
- case SC_SpinBoxUp:
- case SC_SpinBoxDown: {
- if (spin->buttonSymbols == QAbstractSpinBox::NoButtons)
- break;
-
- const int y = fw;
- const int x = spin->rect.width() - spinner_w;
- ret.setRect(x + spin->rect.x(), y + spin->rect.y(), spinner_w, spin->rect.height() - y * 2);
- HIThemeButtonDrawInfo bdi;
- bdi.version = qt_mac_hitheme_version;
- bdi.kind = kThemeIncDecButton;
- int hackTranslateX;
- switch (aquaSize) {
- default:
- case QAquaSizeUnknown:
- case QAquaSizeLarge:
- bdi.kind = kThemeIncDecButton;
- hackTranslateX = 0;
- break;
- case QAquaSizeSmall:
- bdi.kind = kThemeIncDecButtonSmall;
- hackTranslateX = -2;
- break;
- case QAquaSizeMini:
- bdi.kind = kThemeIncDecButtonMini;
- hackTranslateX = -1;
- break;
- }
- bdi.state = kThemeStateActive;
- bdi.value = kThemeButtonOff;
- bdi.adornment = kThemeAdornmentNone;
- HIRect hirect = qt_hirectForQRect(ret);
-
- HIRect outRect;
- HIThemeGetButtonBackgroundBounds(&hirect, &bdi, &outRect);
- ret = qt_qrectForHIRect(outRect);
- switch (sc) {
- case SC_SpinBoxUp:
- ret.setHeight(ret.height() / 2);
- break;
- case SC_SpinBoxDown:
- ret.setY(ret.y() + ret.height() / 2);
- break;
- default:
- Q_ASSERT(0);
- break;
- }
- ret.translate(hackTranslateX, 0); // hack: position the buttons correctly (weird that we need this)
- ret = visualRect(spin->direction, spin->rect, ret);
- break;
- }
- case SC_SpinBoxEditField:
- if (spin->buttonSymbols == QAbstractSpinBox::NoButtons) {
- ret.setRect(fw, fw,
- spin->rect.width() - fw * 2,
- spin->rect.height() - fw * 2);
- } else {
- ret.setRect(fw, fw,
- spin->rect.width() - fw * 2 - spinBoxSep - spinner_w,
- spin->rect.height() - fw * 2);
- }
- ret = visualRect(spin->direction, spin->rect, ret);
- break;
- default:
- ret = QWindowsStyle::subControlRect(cc, spin, sc, widget);
- break;
- }
- }
- break;
- case CC_ToolButton:
- ret = QWindowsStyle::subControlRect(cc, opt, sc, widget);
- if (sc == SC_ToolButtonMenu && widget && !qobject_cast<QToolBar*>(widget->parentWidget())) {
- ret.adjust(-1, 0, 0, 0);
- }
- break;
- default:
- ret = QWindowsStyle::subControlRect(cc, opt, sc, widget);
- break;
- }
- return ret;
-}
-
-QSize QMacStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt,
- const QSize &csz, const QWidget *widget) const
-{
- QSize sz(csz);
- bool useAquaGuideline = true;
-
- switch (ct) {
- case QStyle::CT_SpinBox:
- // hack to work around horrible sizeHint() code in QAbstractSpinBox
- sz.setHeight(sz.height() - 3);
- break;
- case QStyle::CT_TabWidget:
- // the size between the pane and the "contentsRect" (+4,+4)
- // (the "contentsRect" is on the inside of the pane)
- sz = QWindowsStyle::sizeFromContents(ct, opt, csz, widget);
- /**
- This is supposed to show the relationship between the tabBar and
- the stack widget of a QTabWidget.
- Unfortunately ascii is not a good way of representing graphics.....
- PS: The '=' line is the painted frame.
-
- top ---+
- |
- |
- |
- | vvv just outside the painted frame is the "pane"
- - -|- - - - - - - - - - <-+
- TAB BAR +=====^============ | +2 pixels
- - - -|- - -|- - - - - - - <-+
- | | ^ ^^^ just inside the painted frame is the "contentsRect"
- | | |
- | overlap |
- | | |
- bottom ------+ <-+ +14 pixels
- |
- v
- ------------------------------ <- top of stack widget
-
-
- To summarize:
- * 2 is the distance between the pane and the contentsRect
- * The 14 and the 1's are the distance from the contentsRect to the stack widget.
- (same value as used in SE_TabWidgetTabContents)
- * overlap is how much the pane should overlap the tab bar
- */
- // then add the size between the stackwidget and the "contentsRect"
-
- if (const QStyleOptionTabWidgetFrame *twf
- = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
- QSize extra(0,0);
- const int overlap = pixelMetric(PM_TabBarBaseOverlap, opt, widget);
- const int gapBetweenTabbarAndStackWidget = 2 + 14 - overlap;
-
- if (getTabDirection(twf->shape) == kThemeTabNorth || getTabDirection(twf->shape) == kThemeTabSouth) {
- extra = QSize(2, gapBetweenTabbarAndStackWidget + 1);
- } else {
- extra = QSize(gapBetweenTabbarAndStackWidget + 1, 2);
- }
- sz+= extra;
- }
-
- break;
- case QStyle::CT_TabBarTab:
- if (const QStyleOptionTabV3 *tab = qstyleoption_cast<const QStyleOptionTabV3 *>(opt)) {
- const QAquaWidgetSize AquaSize = d->aquaSizeConstrain(opt, widget);
- const bool differentFont = (widget && widget->testAttribute(Qt::WA_SetFont))
- || !QApplication::desktopSettingsAware();
- ThemeTabDirection ttd = getTabDirection(tab->shape);
- bool vertTabs = ttd == kThemeTabWest || ttd == kThemeTabEast;
- if (vertTabs)
- sz.transpose();
- int defaultTabHeight;
- int defaultExtraSpace = proxy()->pixelMetric(PM_TabBarTabHSpace, tab, widget); // Remove spurious gcc warning (AFAIK)
- QFontMetrics fm = opt->fontMetrics;
- switch (AquaSize) {
- case QAquaSizeUnknown:
- case QAquaSizeLarge:
- if (tab->documentMode)
- defaultTabHeight = 23;
- else
- defaultTabHeight = 21;
- break;
- case QAquaSizeSmall:
- defaultTabHeight = 18;
- break;
- case QAquaSizeMini:
- defaultTabHeight = 16;
- break;
- }
- bool setWidth = false;
- if (differentFont || !tab->icon.isNull()) {
- sz.rheight() = qMax(defaultTabHeight, sz.height());
- } else {
- QSize textSize = fm.size(Qt::TextShowMnemonic, tab->text);
- sz.rheight() = qMax(defaultTabHeight, textSize.height());
- sz.rwidth() = textSize.width() + defaultExtraSpace;
- setWidth = true;
- }
-
- if (vertTabs)
- sz.transpose();
-
- int maxWidgetHeight = qMax(tab->leftButtonSize.height(), tab->rightButtonSize.height());
- int maxWidgetWidth = qMax(tab->leftButtonSize.width(), tab->rightButtonSize.width());
-
- int widgetWidth = 0;
- int widgetHeight = 0;
- int padding = 0;
- if (tab->leftButtonSize.isValid()) {
- padding += 8;
- widgetWidth += tab->leftButtonSize.width();
- widgetHeight += tab->leftButtonSize.height();
- }
- if (tab->rightButtonSize.isValid()) {
- padding += 8;
- widgetWidth += tab->rightButtonSize.width();
- widgetHeight += tab->rightButtonSize.height();
- }
-
- if (vertTabs) {
- sz.setHeight(sz.height() + widgetHeight + padding);
- sz.setWidth(qMax(sz.width(), maxWidgetWidth));
- } else {
- if (setWidth)
- sz.setWidth(sz.width() + widgetWidth + padding);
- sz.setHeight(qMax(sz.height(), maxWidgetHeight));
- }
- }
- break;
- case QStyle::CT_PushButton:
- // By default, we fit the contents inside a normal rounded push button.
- // Do this by add enough space around the contents so that rounded
- // borders (including highlighting when active) will show.
- sz.rwidth() += QMacStylePrivate::PushButtonLeftOffset + QMacStylePrivate::PushButtonRightOffset + 12;
- sz.rheight() += QMacStylePrivate::PushButtonTopOffset + QMacStylePrivate::PushButtonBottomOffset;
- break;
- case QStyle::CT_MenuItem:
- if (const QStyleOptionMenuItem *mi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
- int maxpmw = mi->maxIconWidth;
- const QComboBox *comboBox = qobject_cast<const QComboBox *>(widget);
- int w = sz.width(),
- h = sz.height();
- if (mi->menuItemType == QStyleOptionMenuItem::Separator) {
- w = 10;
- SInt16 ash;
- GetThemeMenuSeparatorHeight(&ash);
- h = ash;
- } else {
- h = mi->fontMetrics.height() + 2;
- if (!mi->icon.isNull()) {
- if (comboBox) {
- const QSize &iconSize = comboBox->iconSize();
- h = qMax(h, iconSize.height() + 4);
- maxpmw = qMax(maxpmw, iconSize.width());
- } else {
- int iconExtent = proxy()->pixelMetric(PM_SmallIconSize);
- h = qMax(h, mi->icon.actualSize(QSize(iconExtent, iconExtent)).height() + 4);
- }
- }
- }
- if (mi->text.contains(QLatin1Char('\t')))
- w += 12;
- if (mi->menuItemType == QStyleOptionMenuItem::SubMenu)
- w += 20;
- if (maxpmw)
- w += maxpmw + 6;
- // add space for a check. All items have place for a check too.
- w += 20;
- if (comboBox && comboBox->isVisible()) {
- QStyleOptionComboBox cmb;
- cmb.initFrom(comboBox);
- cmb.editable = false;
- cmb.subControls = QStyle::SC_ComboBoxEditField;
- cmb.activeSubControls = QStyle::SC_None;
- w = qMax(w, subControlRect(QStyle::CC_ComboBox, &cmb,
- QStyle::SC_ComboBoxEditField,
- comboBox).width());
- } else {
- w += 12;
- }
- sz = QSize(w, h);
- }
- break;
- case CT_ToolButton:
- if (widget && qobject_cast<const QToolBar *>(widget->parentWidget())) {
- if (QMainWindow * mainWindow = qobject_cast<QMainWindow *>(widget->parent())) {
- if (mainWindow->unifiedTitleAndToolBarOnMac()) {
- sz.rwidth() += 4;
- if (sz.height() <= 32) {
- // Workaround strange HIToolBar bug when getting constraints.
- sz.rheight() += 1;
- }
- return sz;
- }
- }
- }
- sz.rwidth() += 10;
- sz.rheight() += 10;
- return sz;
- case CT_ComboBox:
- sz.rwidth() += 50;
- break;
- case CT_Menu: {
- QStyleHintReturnMask menuMask;
- QStyleOption myOption = *opt;
- myOption.rect.setSize(sz);
- if (proxy()->styleHint(SH_Menu_Mask, &myOption, widget, &menuMask)) {
- sz = menuMask.region.boundingRect().size();
- }
- break; }
- case CT_HeaderSection:{
- const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt);
- sz = QWindowsStyle::sizeFromContents(ct, opt, csz, widget);
- if (header->text.contains(QLatin1Char('\n')))
- useAquaGuideline = false;
- break; }
- case CT_ScrollBar :
- // Make sure that the scroll bar is large enough to display the thumb indicator.
- if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
- const int minimumSize = scrollButtonsCutoffSize(thumbIndicatorCutoff, widgetSizePolicy(widget));
- if (slider->orientation == Qt::Horizontal)
- sz = sz.expandedTo(QSize(minimumSize, sz.height()));
- else
- sz = sz.expandedTo(QSize(sz.width(), minimumSize));
- }
- break;
- case CT_ItemViewItem:
- if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(opt)) {
- sz = QCommonStyle::sizeFromContents(ct, vopt, csz, widget);
- sz.setHeight(sz.height() + 2);
- }
- break;
-
- default:
- sz = QWindowsStyle::sizeFromContents(ct, opt, csz, widget);
- }
-
- if (useAquaGuideline){
- QSize macsz;
- if (d->aquaSizeConstrain(opt, widget, ct, sz, &macsz) != QAquaSizeUnknown) {
- if (macsz.width() != -1)
- sz.setWidth(macsz.width());
- if (macsz.height() != -1)
- sz.setHeight(macsz.height());
- }
- }
-
- // The sizes that Carbon and the guidelines gives us excludes the focus frame.
- // We compensate for this by adding some extra space here to make room for the frame when drawing:
- if (const QStyleOptionComboBox *combo = qstyleoption_cast<const QStyleOptionComboBox *>(opt)){
- QAquaWidgetSize widgetSize = d->aquaSizeConstrain(opt, widget);
- int bkind = 0;
- switch (widgetSize) {
- default:
- case QAquaSizeLarge:
- bkind = combo->editable ? kThemeComboBox : kThemePopupButton;
- break;
- case QAquaSizeSmall:
- bkind = combo->editable ? int(kThemeComboBoxSmall) : int(kThemePopupButtonSmall);
- break;
- case QAquaSizeMini:
- bkind = combo->editable ? kThemeComboBoxMini : kThemePopupButtonMini;
- break;
- }
- HIRect tmpRect = {{0, 0}, {0, 0}};
- HIRect diffRect = QMacStylePrivate::comboboxInnerBounds(tmpRect, bkind);
- sz.rwidth() -= qRound(diffRect.size.width);
- sz.rheight() -= qRound(diffRect.size.height);
- } else if (ct == CT_PushButton || ct == CT_ToolButton){
- ThemeButtonKind bkind;
- QAquaWidgetSize widgetSize = d->aquaSizeConstrain(opt, widget);
- switch (ct) {
- default:
- case CT_PushButton:
- if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
- if (btn->features & QStyleOptionButton::CommandLinkButton) {
- return QWindowsStyle::sizeFromContents(ct, opt, sz, widget);
- }
- }
-
- switch (widgetSize) {
- default:
- case QAquaSizeLarge:
- bkind = kThemePushButton;
- break;
- case QAquaSizeSmall:
- bkind = kThemePushButtonSmall;
- break;
- case QAquaSizeMini:
- bkind = kThemePushButtonMini;
- break;
- }
- break;
- case CT_ToolButton:
- switch (widgetSize) {
- default:
- case QAquaSizeLarge:
- bkind = kThemeLargeBevelButton;
- break;
- case QAquaSizeMini:
- case QAquaSizeSmall:
- bkind = kThemeSmallBevelButton;
- }
- break;
- }
-
- HIThemeButtonDrawInfo bdi;
- bdi.version = qt_mac_hitheme_version;
- bdi.state = kThemeStateActive;
- bdi.kind = bkind;
- bdi.value = kThemeButtonOff;
- bdi.adornment = kThemeAdornmentNone;
- HIRect macRect, myRect;
- myRect = CGRectMake(0, 0, sz.width(), sz.height());
- HIThemeGetButtonBackgroundBounds(&myRect, &bdi, &macRect);
- // Mini buttons only return their actual size in HIThemeGetButtonBackgroundBounds, so help them out a bit (guess),
- if (bkind == kThemePushButtonMini)
- macRect.size.height += 8.;
- else if (bkind == kThemePushButtonSmall)
- macRect.size.height -= 10;
- sz.setWidth(sz.width() + int(macRect.size.width - myRect.size.width));
- sz.setHeight(sz.height() + int(macRect.size.height - myRect.size.height));
- }
- return sz;
-}
-
-void QMacStyle::drawItemText(QPainter *p, const QRect &r, int flags, const QPalette &pal,
- bool enabled, const QString &text, QPalette::ColorRole textRole) const
-{
- if(flags & Qt::TextShowMnemonic)
- flags |= Qt::TextHideMnemonic;
- QWindowsStyle::drawItemText(p, r, flags, pal, enabled, text, textRole);
-}
-
-bool QMacStyle::event(QEvent *e)
-{
- if(e->type() == QEvent::FocusIn) {
- QWidget *f = 0;
- QWidget *focusWidget = QApplication::focusWidget();
-#ifndef QT_NO_GRAPHICSVIEW
- if (QGraphicsView *graphicsView = qobject_cast<QGraphicsView *>(focusWidget)) {
- QGraphicsItem *focusItem = graphicsView->scene() ? graphicsView->scene()->focusItem() : 0;
- if (focusItem && focusItem->type() == QGraphicsProxyWidget::Type) {
- QGraphicsProxyWidget *proxy = static_cast<QGraphicsProxyWidget *>(focusItem);
- if (proxy->widget())
- focusWidget = proxy->widget()->focusWidget();
- }
- }
-#endif
- if (focusWidget && focusWidget->testAttribute(Qt::WA_MacShowFocusRect)) {
- f = focusWidget;
- QWidget *top = f->parentWidget();
- while (top && !top->isWindow() && !(top->windowType() == Qt::SubWindow))
- top = top->parentWidget();
-#ifndef QT_NO_MAINWINDOW
- if (qobject_cast<QMainWindow *>(top)) {
- QWidget *central = static_cast<QMainWindow *>(top)->centralWidget();
- for (const QWidget *par = f; par; par = par->parentWidget()) {
- if (par == central) {
- top = central;
- break;
- }
- if (par->isWindow())
- break;
- }
- }
-#endif
- }
- if (f) {
- if(!d->focusWidget)
- d->focusWidget = new QFocusFrame(f);
- d->focusWidget->setWidget(f);
- } else if(d->focusWidget) {
- d->focusWidget->setWidget(0);
- }
- } else if(e->type() == QEvent::FocusOut) {
- if(d->focusWidget)
- d->focusWidget->setWidget(0);
- }
- return false;
-}
-
-QIcon QMacStyle::standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *opt,
- const QWidget *widget) const
-{
- switch (standardIcon) {
- default:
- return QWindowsStyle::standardIconImplementation(standardIcon, opt, widget);
- case SP_ToolBarHorizontalExtensionButton:
- case SP_ToolBarVerticalExtensionButton: {
- QPixmap pixmap(qt_mac_toolbar_ext);
- if (standardIcon == SP_ToolBarVerticalExtensionButton) {
- QPixmap pix2(pixmap.height(), pixmap.width());
- pix2.fill(Qt::transparent);
- QPainter p(&pix2);
- p.translate(pix2.width(), 0);
- p.rotate(90);
- p.drawPixmap(0, 0, pixmap);
- return pix2;
- }
- return pixmap;
- }
- }
-}
-
-int QMacStyle::layoutSpacingImplementation(QSizePolicy::ControlType control1,
- QSizePolicy::ControlType control2,
- Qt::Orientation orientation,
- const QStyleOption *option,
- const QWidget *widget) const
-{
- const int ButtonMask = QSizePolicy::ButtonBox | QSizePolicy::PushButton;
- bool isMetal = (widget && widget->testAttribute(Qt::WA_MacBrushedMetal));
- int controlSize = getControlSize(option, widget);
-
- if (control2 == QSizePolicy::ButtonBox) {
- /*
- AHIG seems to prefer a 12-pixel margin between group
- boxes and the row of buttons. The 20 pixel comes from
- Builder.
- */
- if (isMetal // (AHIG, guess, guess)
- || (control1 & (QSizePolicy::Frame // guess
- | QSizePolicy::GroupBox // (AHIG, guess, guess)
- | QSizePolicy::TabWidget // guess
- | ButtonMask))) { // AHIG
- return_SIZE(14, 8, 8);
- } else if (control1 == QSizePolicy::LineEdit) {
- return_SIZE(8, 8, 8); // Interface Builder
- } else {
- return_SIZE(20, 7, 7); // Interface Builder
- }
- }
-
- if ((control1 | control2) & ButtonMask) {
- if (control1 == QSizePolicy::LineEdit)
- return_SIZE(8, 8, 8); // Interface Builder
- else if (control2 == QSizePolicy::LineEdit) {
- if (orientation == Qt::Vertical)
- return_SIZE(20, 7, 7); // Interface Builder
- else
- return_SIZE(20, 8, 8);
- }
- return_SIZE(14, 8, 8); // Interface Builder
- }
-
- switch (CT2(control1, control2)) {
- case CT1(QSizePolicy::Label): // guess
- case CT2(QSizePolicy::Label, QSizePolicy::DefaultType): // guess
- case CT2(QSizePolicy::Label, QSizePolicy::CheckBox): // AHIG
- case CT2(QSizePolicy::Label, QSizePolicy::ComboBox): // AHIG
- case CT2(QSizePolicy::Label, QSizePolicy::LineEdit): // guess
- case CT2(QSizePolicy::Label, QSizePolicy::RadioButton): // AHIG
- case CT2(QSizePolicy::Label, QSizePolicy::Slider): // guess
- case CT2(QSizePolicy::Label, QSizePolicy::SpinBox): // guess
- case CT2(QSizePolicy::Label, QSizePolicy::ToolButton): // guess
- return_SIZE(8, 6, 5);
- case CT1(QSizePolicy::ToolButton):
- return 8; // AHIG
- case CT1(QSizePolicy::CheckBox):
- case CT2(QSizePolicy::CheckBox, QSizePolicy::RadioButton):
- case CT2(QSizePolicy::RadioButton, QSizePolicy::CheckBox):
- if (orientation == Qt::Vertical)
- return_SIZE(8, 8, 7); // AHIG and Builder
- break;
- case CT1(QSizePolicy::RadioButton):
- if (orientation == Qt::Vertical)
- return 5; // (Builder, guess, AHIG)
- }
-
- if (orientation == Qt::Horizontal
- && (control2 & (QSizePolicy::CheckBox | QSizePolicy::RadioButton)))
- return_SIZE(12, 10, 8); // guess
-
- if ((control1 | control2) & (QSizePolicy::Frame
- | QSizePolicy::GroupBox
- | QSizePolicy::TabWidget)) {
- /*
- These values were chosen so that nested container widgets
- look good side by side. Builder uses 8, which looks way
- too small, and AHIG doesn't say anything.
- */
- return_SIZE(16, 10, 10); // guess
- }
-
- if ((control1 | control2) & (QSizePolicy::Line | QSizePolicy::Slider))
- return_SIZE(12, 10, 8); // AHIG
-
- if ((control1 | control2) & QSizePolicy::LineEdit)
- return_SIZE(10, 8, 8); // AHIG
-
- /*
- AHIG and Builder differ by up to 4 pixels for stacked editable
- comboboxes. We use some values that work fairly well in all
- cases.
- */
- if ((control1 | control2) & QSizePolicy::ComboBox)
- return_SIZE(10, 8, 7); // guess
-
- /*
- Builder defaults to 8, 6, 5 in lots of cases, but most of the time the
- result looks too cramped.
- */
- return_SIZE(10, 8, 6); // guess
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/styles/qmacstyle_mac_p.h b/src/gui/styles/qmacstyle_mac_p.h
deleted file mode 100644
index d1528593fb..0000000000
--- a/src/gui/styles/qmacstyle_mac_p.h
+++ /dev/null
@@ -1,241 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#ifndef QMACSTYLE_MAC_P_H
-#define QMACSTYLE_MAC_P_H
-
-#include <qmacstyle_mac.h>
-#include <private/qapplication_p.h>
-#include <private/qcombobox_p.h>
-#include <private/qmacstylepixmaps_mac_p.h>
-#include <private/qpaintengine_mac_p.h>
-#include <private/qpainter_p.h>
-#include <private/qprintengine_mac_p.h>
-#include <private/qstylehelper_p.h>
-#include <qapplication.h>
-#include <qbitmap.h>
-#include <qcheckbox.h>
-#include <qcombobox.h>
-#include <qdialogbuttonbox.h>
-#include <qdockwidget.h>
-#include <qevent.h>
-#include <qfocusframe.h>
-#include <qformlayout.h>
-#include <qgroupbox.h>
-#include <qhash.h>
-#include <qheaderview.h>
-#include <qlayout.h>
-#include <qlineedit.h>
-#include <qlistview.h>
-#include <qmainwindow.h>
-#include <qmap.h>
-#include <qmenubar.h>
-#include <qpaintdevice.h>
-#include <qpainter.h>
-#include <qpixmapcache.h>
-#include <qpointer.h>
-#include <qprogressbar.h>
-#include <qpushbutton.h>
-#include <qradiobutton.h>
-#include <qrubberband.h>
-#include <qsizegrip.h>
-#include <qspinbox.h>
-#include <qsplitter.h>
-#include <qstyleoption.h>
-#include <qtextedit.h>
-#include <qtextstream.h>
-#include <qtoolbar.h>
-#include <qtoolbutton.h>
-#include <qtreeview.h>
-#include <qtableview.h>
-#include <qwizard.h>
-#include <qdebug.h>
-#include <qlibrary.h>
-#include <qdatetimeedit.h>
-#include <qmath.h>
-#include <QtGui/qgraphicsproxywidget.h>
-#include <QtGui/qgraphicsview.h>
-#include <private/qt_cocoa_helpers_mac_p.h>
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-QT_BEGIN_NAMESPACE
-
-#if (MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5)
-enum {
- kThemePushButtonTextured = 31,
- kThemePushButtonTexturedSmall = 32,
- kThemePushButtonTexturedMini = 33
-};
-
-/* Search fields */
-enum {
- kHIThemeFrameTextFieldRound = 1000,
- kHIThemeFrameTextFieldRoundSmall = 1001,
- kHIThemeFrameTextFieldRoundMini = 1002
-};
-#endif
-
-/*
- AHIG:
- Apple Human Interface Guidelines
- http://developer.apple.com/documentation/UserExperience/Conceptual/OSXHIGuidelines/
-
- Builder:
- Apple Interface Builder v. 3.1.1
-*/
-
-// this works as long as we have at most 16 different control types
-#define CT1(c) CT2(c, c)
-#define CT2(c1, c2) ((uint(c1) << 16) | uint(c2))
-
-enum QAquaWidgetSize { QAquaSizeLarge = 0, QAquaSizeSmall = 1, QAquaSizeMini = 2,
- QAquaSizeUnknown = -1 };
-
-#define SIZE(large, small, mini) \
- (controlSize == QAquaSizeLarge ? (large) : controlSize == QAquaSizeSmall ? (small) : (mini))
-
-// same as return SIZE(...) but optimized
-#define return_SIZE(large, small, mini) \
- do { \
- static const int sizes[] = { (large), (small), (mini) }; \
- return sizes[controlSize]; \
- } while (0)
-
-bool qt_mac_buttonIsRenderedFlat(const QPushButton *pushButton, const QStyleOptionButton *option);
-
-class QMacStylePrivate : public QObject
-{
- Q_OBJECT
-
-public:
- QMacStylePrivate(QMacStyle *style);
-
- // Ideally these wouldn't exist, but since they already exist we need some accessors.
- static const int PushButtonLeftOffset;
- static const int PushButtonTopOffset;
- static const int PushButtonRightOffset;
- static const int PushButtonBottomOffset;
- static const int MiniButtonH;
- static const int SmallButtonH;
- static const int BevelButtonW;
- static const int BevelButtonH;
- static const int PushButtonContentPadding;
-
-
- // Stuff from QAquaAnimate:
- bool addWidget(QWidget *);
- void removeWidget(QWidget *);
-
- enum Animates { AquaPushButton, AquaProgressBar, AquaListViewItemOpen };
- bool animatable(Animates, const QWidget *) const;
- void stopAnimate(Animates, QWidget *);
- void startAnimate(Animates, QWidget *);
- static ThemeDrawState getDrawState(QStyle::State flags);
- QAquaWidgetSize aquaSizeConstrain(const QStyleOption *option, const QWidget *widg,
- QStyle::ContentsType ct = QStyle::CT_CustomBase,
- QSize szHint=QSize(-1, -1), QSize *insz = 0) const;
- void getSliderInfo(QStyle::ComplexControl cc, const QStyleOptionSlider *slider,
- HIThemeTrackDrawInfo *tdi, const QWidget *needToRemoveMe);
- bool doAnimate(Animates);
- inline int animateSpeed(Animates) const { return 33; }
-
- // Utility functions
- void drawColorlessButton(const HIRect &macRect, HIThemeButtonDrawInfo *bdi,
- QPainter *p, const QStyleOption *opt) const;
-
- QSize pushButtonSizeFromContents(const QStyleOptionButton *btn) const;
-
- HIRect pushButtonContentBounds(const QStyleOptionButton *btn,
- const HIThemeButtonDrawInfo *bdi) const;
-
- void initComboboxBdi(const QStyleOptionComboBox *combo, HIThemeButtonDrawInfo *bdi,
- const QWidget *widget, const ThemeDrawState &tds);
-
- static HIRect comboboxInnerBounds(const HIRect &outerBounds, int buttonKind);
-
- static QRect comboboxEditBounds(const QRect &outerBounds, const HIThemeButtonDrawInfo &bdi);
-
- static void drawCombobox(const HIRect &outerBounds, const HIThemeButtonDrawInfo &bdi, QPainter *p);
- static void drawTableHeader(const HIRect &outerBounds, bool drawTopBorder, bool drawLeftBorder,
- const HIThemeButtonDrawInfo &bdi, QPainter *p);
- bool contentFitsInPushButton(const QStyleOptionButton *btn, HIThemeButtonDrawInfo *bdi,
- ThemeButtonKind buttonKindToCheck) const;
- void initHIThemePushButton(const QStyleOptionButton *btn, const QWidget *widget,
- const ThemeDrawState tds,
- HIThemeButtonDrawInfo *bdi) const;
- QPixmap generateBackgroundPattern() const;
-protected:
- bool eventFilter(QObject *, QEvent *);
- void timerEvent(QTimerEvent *);
-
-private slots:
- void startAnimationTimer();
-
-public:
- QPointer<QPushButton> defaultButton; //default push buttons
- int timerID;
- QList<QPointer<QWidget> > progressBars; //existing progress bars that need animation
-
- struct ButtonState {
- int frame;
- enum { ButtonDark, ButtonLight } dir;
- } buttonState;
- UInt8 progressFrame;
- QPointer<QFocusFrame> focusWidget;
- CFAbsoluteTime defaultButtonStart;
- QMacStyle *q;
- bool mouseDown;
-};
-
-QT_END_NAMESPACE
-
-#endif // QMACSTYLE_MAC_P_H
diff --git a/src/gui/styles/qmotifstyle.cpp b/src/gui/styles/qmotifstyle.cpp
deleted file mode 100644
index c41b92ad6a..0000000000
--- a/src/gui/styles/qmotifstyle.cpp
+++ /dev/null
@@ -1,2721 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qmotifstyle.h"
-#include "qcdestyle.h"
-
-#if !defined(QT_NO_STYLE_MOTIF) || defined(QT_PLUGIN)
-
-#include "qmenu.h"
-#include "qapplication.h"
-#include "qpainter.h"
-#include "qdrawutil.h"
-#include "qpixmap.h"
-#include "qpalette.h"
-#include "qwidget.h"
-#include "qpushbutton.h"
-#include "qscrollbar.h"
-#include "qtabbar.h"
-#include "qtabwidget.h"
-#include "qlistview.h"
-#include "qsplitter.h"
-#include "qslider.h"
-#include "qcombobox.h"
-#include "qlineedit.h"
-#include "qprogressbar.h"
-#include "qimage.h"
-#include "qfocusframe.h"
-#include "qdebug.h"
-#include "qpainterpath.h"
-#include "qmotifstyle_p.h"
-#include "qdialogbuttonbox.h"
-#include "qformlayout.h"
-#include <limits.h>
-#include <QtGui/qgraphicsproxywidget.h>
-#include <QtGui/qgraphicsview.h>
-
-#ifdef Q_WS_X11
-#include "qx11info_x11.h"
-#endif
-
-QT_BEGIN_NAMESPACE
-
-// old constants that might still be useful...
-static const int motifItemFrame = 2; // menu item frame width
-static const int motifSepHeight = 2; // separator item height
-static const int motifItemHMargin = 3; // menu item hor text margin
-static const int motifItemVMargin = 2; // menu item ver text margin
-static const int motifArrowHMargin = 6; // arrow horizontal margin
-static const int motifTabSpacing = 12; // space between text and tab
-static const int motifCheckMarkHMargin = 2; // horiz. margins of check mark
-static const int motifCheckMarkSpace = 16;
-
-
-/*!
- \class QMotifStyle
- \brief The QMotifStyle class provides Motif look and feel.
-
- \ingroup appearance
-
- This class implements the Motif look and feel. It closely
- resembles the original Motif look as defined by the Open Group,
- but with some minor improvements. The Motif style is Qt's default
- GUI style on Unix platforms.
-
- \img qmotifstyle.png
- \sa QWindowsXPStyle, QMacStyle, QWindowsStyle, QPlastiqueStyle, QCDEStyle
-*/
-
-/*!
- \variable QMotifStyle::focus
- \internal
-*/
-
-/*!
- Constructs a QMotifStyle.
-
- If \a useHighlightCols is false (the default), the style will
- polish the application's color palette to emulate the Motif way of
- highlighting, which is a simple inversion between the base and the
- text color.
-*/
-QMotifStyle::QMotifStyle(bool useHighlightCols)
- : QCommonStyle(*new QMotifStylePrivate)
-{
- focus = 0;
- highlightCols = useHighlightCols;
-}
-
-
-/*!
- \internal
-*/
-QMotifStyle::QMotifStyle(QMotifStylePrivate &dd, bool useHighlightColors)
- : QCommonStyle(dd)
-{
- focus = 0;
- highlightCols = useHighlightColors;
-}
-
-
-/*!
- \overload
-
- Destroys the style.
-*/
-QMotifStyle::~QMotifStyle()
-{
- delete focus;
-}
-
-/*!
- \internal
- Animate indeterminate progress bars only when visible
-*/
-bool QMotifStyle::eventFilter(QObject *o, QEvent *e)
-{
-#ifndef QT_NO_PROGRESSBAR
- Q_D(QMotifStyle);
- switch(e->type()) {
- case QEvent::StyleChange:
- case QEvent::Show:
- if (QProgressBar *bar = qobject_cast<QProgressBar *>(o)) {
- d->bars << bar;
- if (d->bars.size() == 1) {
- Q_ASSERT(d->animationFps> 0);
- d->animateTimer = startTimer(1000 / d->animationFps);
- }
- }
- break;
- case QEvent::Destroy:
- case QEvent::Hide:
- // reinterpret_cast because there is no type info when getting
- // the destroy event. We know that it is a QProgressBar.
- if (QProgressBar *bar = reinterpret_cast<QProgressBar *>(o)) {
- d->bars.removeAll(bar);
- if (d->bars.isEmpty() && d->animateTimer) {
- killTimer(d->animateTimer);
- d->animateTimer = 0;
- }
- }
- default:
- break;
- }
-#endif // QT_NO_PROGRESSBAR
- return QStyle::eventFilter(o, e);
-}
-
-/*!
- \internal
-*/
-QIcon QMotifStyle::standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *opt,
- const QWidget *widget) const
-{
- return QCommonStyle::standardIconImplementation(standardIcon, opt, widget);
-}
-
-/*!
- \reimp
-*/
-void QMotifStyle::timerEvent(QTimerEvent *event)
-{
-#ifndef QT_NO_PROGRESSBAR
- Q_D(QMotifStyle);
- if (event->timerId() == d->animateTimer) {
- Q_ASSERT(d->animationFps > 0);
- d->animateStep = d->startTime.elapsed() / (1000 / d->animationFps);
- foreach (QProgressBar *bar, d->bars) {
- if ((bar->minimum() == 0 && bar->maximum() == 0))
- bar->update();
- }
- }
-#endif // QT_NO_PROGRESSBAR
- event->ignore();
-}
-
-
-QMotifStylePrivate::QMotifStylePrivate()
-#ifndef QT_NO_PROGRESSBAR
- : animationFps(25), animateTimer(0), animateStep(0)
-#endif
-{
-}
-
-/*!
- If \a arg is false, the style will polish the application's color
- palette to emulate the Motif way of highlighting, which is a
- simple inversion between the base and the text color.
-
- The effect will show up the next time an application palette is
- set via QApplication::setPalette(). The current color palette of
- the application remains unchanged.
-
- \sa QStyle::polish()
-*/
-void QMotifStyle::setUseHighlightColors(bool arg)
-{
- highlightCols = arg;
-}
-
-/*!
- Returns true if the style treats the highlight colors of the
- palette in a Motif-like manner, which is a simple inversion
- between the base and the text color; otherwise returns false. The
- default is false.
-*/
-bool QMotifStyle::useHighlightColors() const
-{
- return highlightCols;
-}
-
-/*! \reimp */
-
-void QMotifStyle::polish(QPalette& pal)
-{
- if (pal.brush(QPalette::Active, QPalette::Light) == pal.brush(QPalette::Active, QPalette::Base)) {
- QColor nlight = pal.color(QPalette::Active, QPalette::Light).darker(108);
- pal.setColor(QPalette::Active, QPalette::Light, nlight) ;
- pal.setColor(QPalette::Disabled, QPalette::Light, nlight) ;
- pal.setColor(QPalette::Inactive, QPalette::Light, nlight) ;
- }
-
- if (highlightCols)
- return;
-
- // force the ugly motif way of highlighting *sigh*
- pal.setColor(QPalette::Active, QPalette::Highlight,
- pal.color(QPalette::Active, QPalette::Text));
- pal.setColor(QPalette::Active, QPalette::HighlightedText,
- pal.color(QPalette::Active, QPalette::Base));
- pal.setColor(QPalette::Disabled, QPalette::Highlight,
- pal.color(QPalette::Disabled, QPalette::Text));
- pal.setColor(QPalette::Disabled, QPalette::HighlightedText,
- pal.color(QPalette::Disabled, QPalette::Base));
- pal.setColor(QPalette::Inactive, QPalette::Highlight,
- pal.color(QPalette::Active, QPalette::Text));
- pal.setColor(QPalette::Inactive, QPalette::HighlightedText,
- pal.color(QPalette::Active, QPalette::Base));
-}
-
-/*!
- \reimp
- \internal
- Keep QStyle::polish() visible.
-*/
-void QMotifStyle::polish(QWidget* widget)
-{
- QStyle::polish(widget);
-#ifndef QT_NO_PROGRESSBAR
- if (qobject_cast<QProgressBar *>(widget))
- widget->installEventFilter(this);
-#endif
-}
-
-/*!
- \reimp
- \internal
- Keep QStyle::polish() visible.
-*/
-void QMotifStyle::unpolish(QWidget* widget)
-{
- QCommonStyle::unpolish(widget);
-#ifndef QT_NO_PROGRESSBAR
- if (qobject_cast<QProgressBar *>(widget)) {
- Q_D(QMotifStyle);
- widget->removeEventFilter(this);
- d->bars.removeAll(static_cast<QProgressBar*>(widget));
- }
-#endif
-}
-
-
-/*!
- \reimp
- \internal
- Keep QStyle::polish() visible.
-*/
-void QMotifStyle::polish(QApplication* a)
-{
- QCommonStyle::polish(a);
-}
-
-
-/*!
- \reimp
- \internal
- Keep QStyle::polish() visible.
-*/
-void QMotifStyle::unpolish(QApplication* a)
-{
- QCommonStyle::unpolish(a);
-}
-
-static void rot(QPolygon& a, int n)
-{
- QPolygon r(a.size());
- for (int i = 0; i < (int)a.size(); i++) {
- switch (n) {
- case 1: r.setPoint(i,-a[i].y(),a[i].x()); break;
- case 2: r.setPoint(i,-a[i].x(),-a[i].y()); break;
- case 3: r.setPoint(i,a[i].y(),-a[i].x()); break;
- }
- }
- a = r;
-}
-
-
-/*!
- \reimp
-*/
-void QMotifStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p,
- const QWidget *w) const
-{
- switch(pe) {
- case PE_Q3CheckListExclusiveIndicator:
- if (const QStyleOptionQ3ListView *lv = qstyleoption_cast<const QStyleOptionQ3ListView *>(opt)) {
- if (lv->items.isEmpty())
- return;
-
- if (lv->state & State_Enabled)
- p->setPen(QPen(opt->palette.text().color()));
- else
- p->setPen(QPen(lv->palette.color(QPalette::Disabled, QPalette::Text)));
- QPolygon a;
-
- int cx = opt->rect.width()/2 - 1;
- int cy = opt->rect.height()/2;
- int e = opt->rect.width()/2 - 1;
- for (int i = 0; i < 3; i++) { //penWidth 2 doesn't quite work
- a.setPoints(4, cx-e, cy, cx, cy-e, cx+e, cy, cx, cy+e);
- p->drawPolygon(a);
- e--;
- }
- if (opt->state & State_On) {
- if (lv->state & State_Enabled)
- p->setPen(QPen(opt->palette.text().color()));
- else
- p->setPen(QPen(lv->palette.color(QPalette::Disabled,
- QPalette::Text)));
- QBrush saveBrush = p->brush();
- p->setBrush(opt->palette.text());
- e = e - 2;
- a.setPoints(4, cx-e, cy, cx, cy-e, cx+e, cy, cx, cy+e);
- p->drawPolygon(a);
- p->setBrush(saveBrush);
- }
- }
- break;
-
- case PE_FrameTabWidget:
- case PE_FrameWindow:
- qDrawShadePanel(p, opt->rect, opt->palette, QStyle::State_None, proxy()->pixelMetric(PM_DefaultFrameWidth));
- break;
- case PE_FrameFocusRect:
- if (const QStyleOptionFocusRect *fropt = qstyleoption_cast<const QStyleOptionFocusRect *>(opt)) {
- if ((fropt->state & State_HasFocus) && focus && focus->isVisible()
- && !(fropt->state & QStyle::State_Item))
- break;
- QCommonStyle::drawPrimitive(pe, opt, p, w);
- }
- break;
-
- case PE_IndicatorToolBarHandle: {
- p->save();
- p->translate(opt->rect.x(), opt->rect.y());
-
- QColor dark(opt->palette.dark().color());
- QColor light(opt->palette.light().color());
- int i;
- if (opt->state & State_Horizontal) {
- int h = opt->rect.height();
- if (h > 6) {
- if (opt->state & State_On)
- p->fillRect(1, 1, 8, h - 2, opt->palette.highlight());
- QPolygon a(2 * ((h-6)/3));
- int y = 3 + (h%3)/2;
- p->setPen(dark);
- p->drawLine(8, 1, 8, h-2);
- for (i=0; 2*i < a.size(); ++i) {
- a.setPoint(2*i, 5, y+1+3*i);
- a.setPoint(2*i+1, 2, y+2+3*i);
- }
- p->drawPoints(a);
- p->setPen(light);
- p->drawLine(9, 1, 9, h-2);
- for (i=0; 2*i < a.size(); i++) {
- a.setPoint(2*i, 4, y+3*i);
- a.setPoint(2*i+1, 1, y+1+3*i);
- }
- p->drawPoints(a);
- // if (drawBorder) {
- // p->setPen(QPen(Qt::darkGray));
- // p->drawLine(0, opt->rect.height() - 1,
- // tbExtent, opt->rect.height() - 1);
- // }
- }
- } else {
- int w = opt->rect.width();
- if (w > 6) {
- if (opt->state & State_On)
- p->fillRect(1, 1, w - 2, 9, opt->palette.highlight());
- QPolygon a(2 * ((w-6)/3));
-
- int x = 3 + (w%3)/2;
- p->setPen(dark);
- p->drawLine(1, 8, w-2, 8);
- for (i=0; 2*i < a.size(); ++i) {
- a.setPoint(2*i, x+1+3*i, 6);
- a.setPoint(2*i+1, x+2+3*i, 3);
- }
- p->drawPoints(a);
- p->setPen(light);
- p->drawLine(1, 9, w-2, 9);
- for (i=0; 2*i < a.size(); ++i) {
- a.setPoint(2*i, x+3*i, 5);
- a.setPoint(2*i+1, x+1+3*i, 2);
- }
- p->drawPoints(a);
- // if (drawBorder) {
- // p->setPen(QPen(Qt::darkGray));
- // p->drawLine(opt->rect.width() - 1, 0,
- // opt->rect.width() - 1, tbExtent);
- // }
- }
- }
- p->restore();
- break; }
-
- case PE_PanelButtonCommand:
- case PE_PanelButtonBevel:
- case PE_PanelButtonTool: {
- QBrush fill;
- if (opt->state & State_Sunken)
- fill = opt->palette.brush(QPalette::Mid);
- else if ((opt->state & State_On) && (opt->state & State_Enabled))
- fill = QBrush(opt->palette.mid().color(), Qt::Dense4Pattern);
- else
- fill = opt->palette.brush(QPalette::Button);
- if ((opt->state & State_Enabled || opt->state & State_On) || !(opt->state & State_AutoRaise))
- qDrawShadePanel(p, opt->rect, opt->palette, bool(opt->state & (State_Sunken | State_On)),
- proxy()->pixelMetric(PM_DefaultFrameWidth), &fill);
- break; }
-
- case PE_IndicatorCheckBox: {
- bool on = opt->state & State_On;
- bool down = opt->state & State_Sunken;
- bool showUp = !(down ^ on);
- QBrush fill = opt->palette.brush((showUp || opt->state & State_NoChange) ?QPalette::Button : QPalette::Mid);
- if (opt->state & State_NoChange) {
- qDrawPlainRect(p, opt->rect, opt->palette.text().color(),
- 1, &fill);
- p->drawLine(opt->rect.x() + opt->rect.width() - 1, opt->rect.y(),
- opt->rect.x(), opt->rect.y() + opt->rect.height() - 1);
- } else {
- qDrawShadePanel(p, opt->rect, opt->palette, !showUp,
- proxy()->pixelMetric(PM_DefaultFrameWidth), &fill);
- }
- if (!(opt->state & State_Enabled) && proxy()->styleHint(SH_DitherDisabledText))
- p->fillRect(opt->rect, QBrush(p->background().color(), Qt::Dense5Pattern));
- break; }
-
- case PE_IndicatorRadioButton: {
-#define INTARRLEN(x) sizeof(x)/(sizeof(int)*2)
- int inner_pts[] = { // used for filling diamond
- 2,opt->rect.height()/2,
- opt->rect.width()/2,2,
- opt->rect.width()-3,opt->rect.height()/2,
- opt->rect.width()/2,opt->rect.height()-3
- };
- int top_pts[] = { // top (^) of diamond
- 0,opt->rect.height()/2,
- opt->rect.width()/2,0,
- opt->rect.width()-2,opt->rect.height()/2-1,
- opt->rect.width()-3,opt->rect.height()/2-1,
- opt->rect.width()/2,1,
- 1,opt->rect.height()/2,
- 2,opt->rect.height()/2,
- opt->rect.width()/2,2,
- opt->rect.width()-4,opt->rect.height()/2-1
- };
- int bottom_pts[] = { // bottom (v) of diamond
- 1,opt->rect.height()/2+1,
- opt->rect.width()/2,opt->rect.height()-1,
- opt->rect.width()-1,opt->rect.height()/2,
- opt->rect.width()-2,opt->rect.height()/2,
- opt->rect.width()/2,opt->rect.height()-2,
- 2,opt->rect.height()/2+1,
- 3,opt->rect.height()/2+1,
- opt->rect.width()/2,opt->rect.height()-3,
- opt->rect.width()-3,opt->rect.height()/2
- };
- bool on = opt->state & State_On;
- bool down = opt->state & State_Sunken;
- bool showUp = !(down ^ on);
- QPen oldPen = p->pen();
- QBrush oldBrush = p->brush();
- QPolygon a(INTARRLEN(inner_pts), inner_pts);
- p->setPen(Qt::NoPen);
- p->setBrush(opt->palette.brush(showUp ? QPalette::Button : QPalette::Mid));
- a.translate(opt->rect.x(), opt->rect.y());
- p->drawPolygon(a);
- p->setPen(showUp ? opt->palette.light().color() : opt->palette.dark().color());
- p->setBrush(Qt::NoBrush);
- a.setPoints(INTARRLEN(top_pts), top_pts);
- a.translate(opt->rect.x(), opt->rect.y());
- p->drawPolyline(a);
- p->setPen(showUp ? opt->palette.dark().color() : opt->palette.light().color());
- a.setPoints(INTARRLEN(bottom_pts), bottom_pts);
- a.translate(opt->rect.x(), opt->rect.y());
- p->drawPolyline(a);
- if (!(opt->state & State_Enabled) && proxy()->styleHint(SH_DitherDisabledText))
- p->fillRect(opt->rect, QBrush(p->background().color(), Qt::Dense5Pattern));
- p->setPen(oldPen);
- p->setBrush(oldBrush);
- break; }
-
- case PE_IndicatorSpinUp:
- case PE_IndicatorSpinPlus:
- case PE_IndicatorSpinDown:
- case PE_IndicatorSpinMinus:
- case PE_IndicatorArrowUp:
- case PE_IndicatorArrowDown:
- case PE_IndicatorArrowRight:
- case PE_IndicatorArrowLeft: {
- QRect rect = opt->rect;
- QPolygon bFill;
- QPolygon bTop;
- QPolygon bBot;
- QPolygon bLeft;
- if (pe == PE_IndicatorSpinPlus || pe == PE_IndicatorSpinUp)
- pe = PE_IndicatorArrowUp;
- else if (pe == PE_IndicatorSpinMinus || pe == PE_IndicatorSpinDown)
- pe = PE_IndicatorArrowDown;
- bool vertical = pe == PE_IndicatorArrowUp || pe == PE_IndicatorArrowDown;
- bool horizontal = !vertical;
- int dim = rect.width() < rect.height() ? rect.width() : rect.height();
- int colspec = 0x0000;
-
- if (!(opt->state & State_Enabled))
- dim -= 2;
- if(dim < 2)
- break;
-
- // adjust size and center (to fix rotation below)
- if (rect.width() > dim) {
- rect.setX(rect.x() + ((rect.width() - dim) / 2));
- rect.setWidth(dim);
- }
- if (rect.height() > dim) {
- rect.setY(rect.y() + ((rect.height() - dim) / 2));
- rect.setHeight(dim);
- }
-
- if (dim > 3) {
- if (pixelMetric(PM_DefaultFrameWidth) < 2) { // thin style
- bFill.resize( dim & 1 ? 3 : 4 );
- bTop.resize( 2 );
- bBot.resize( 2 );
- bLeft.resize( 2 );
- bLeft.putPoints( 0, 2, 0, 0, 0, dim-1 );
- bTop.putPoints( 0, 2, 1, 0, dim-1, dim/2 );
- bBot.putPoints( 0, 2, 1, dim-1, dim-1, dim/2 );
-
- if ( dim > 6 ) { // dim>6: must fill interior
- bFill.putPoints( 0, 2, 0, dim-1, 0, 0 );
- if ( dim & 1 ) // if size is an odd number
- bFill.setPoint( 2, dim - 1, dim / 2 );
- else
- bFill.putPoints( 2, 2, dim-1, dim/2-1, dim-1, dim/2 );
- }
- } else {
- if (dim > 6)
- bFill.resize(dim & 1 ? 3 : 4);
- bTop.resize((dim/2)*2);
- bBot.resize(dim & 1 ? dim + 1 : dim);
- bLeft.resize(dim > 4 ? 4 : 2);
- bLeft.putPoints(0, 2, 0,0, 0,dim-1);
- if (dim > 4)
- bLeft.putPoints(2, 2, 1,2, 1,dim-3);
- bTop.putPoints(0, 4, 1,0, 1,1, 2,1, 3,1);
- bBot.putPoints(0, 4, 1,dim-1, 1,dim-2, 2,dim-2, 3,dim-2);
-
- for(int i=0; i<dim/2-2 ; i++) {
- bTop.putPoints(i*2+4, 2, 2+i*2,2+i, 5+i*2, 2+i);
- bBot.putPoints(i*2+4, 2, 2+i*2,dim-3-i, 5+i*2,dim-3-i);
- }
- if (dim & 1) // odd number size: extra line
- bBot.putPoints(dim-1, 2, dim-3,dim/2, dim-1,dim/2);
- if (dim > 6) { // dim>6: must fill interior
- bFill.putPoints(0, 2, 1,dim-3, 1,2);
- if (dim & 1) // if size is an odd number
- bFill.setPoint(2, dim - 3, dim / 2);
- else
- bFill.putPoints(2, 2, dim-4,dim/2-1, dim-4,dim/2);
- }
- }
- } else {
- if (dim == 3) { // 3x3 arrow pattern
- bLeft.setPoints(4, 0,0, 0,2, 1,1, 1,1);
- bTop .setPoints(2, 1,0, 1,0);
- bBot .setPoints(2, 1,2, 2,1);
- }
- else { // 2x2 arrow pattern
- bLeft.setPoints(2, 0,0, 0,1);
- bTop .setPoints(2, 1,0, 1,0);
- bBot .setPoints(2, 1,1, 1,1);
- }
- }
-
- // We use rot() and translate() as it is more efficient that
- // matrix transformations on the painter, and because it still
- // works with QT_NO_TRANSFORMATIONS defined.
-
- if (pe == PE_IndicatorArrowUp || pe == PE_IndicatorArrowLeft) {
- if (vertical) {
- rot(bFill,3);
- rot(bLeft,3);
- rot(bTop,3);
- rot(bBot,3);
- bFill.translate(0, rect.height() - 1);
- bLeft.translate(0, rect.height() - 1);
- bTop.translate(0, rect.height() - 1);
- bBot.translate(0, rect.height() - 1);
- } else {
- rot(bFill,2);
- rot(bLeft,2);
- rot(bTop,2);
- rot(bBot,2);
- bFill.translate(rect.width() - 1, rect.height() - 1);
- bLeft.translate(rect.width() - 1, rect.height() - 1);
- bTop.translate(rect.width() - 1, rect.height() - 1);
- bBot.translate(rect.width() - 1, rect.height() - 1);
- }
- if (opt->state & State_Sunken)
- colspec = horizontal ? 0x2334 : 0x2343;
- else
- colspec = horizontal ? 0x1443 : 0x1434;
- } else {
- if (vertical) {
- rot(bFill,1);
- rot(bLeft,1);
- rot(bTop,1);
- rot(bBot,1);
- bFill.translate(rect.width() - 1, 0);
- bLeft.translate(rect.width() - 1, 0);
- bTop.translate(rect.width() - 1, 0);
- bBot.translate(rect.width() - 1, 0);
- }
- if (opt->state & State_Sunken)
- colspec = horizontal ? 0x2443 : 0x2434;
- else
- colspec = horizontal ? 0x1334 : 0x1343;
- }
- bFill.translate(rect.x(), rect.y());
- bLeft.translate(rect.x(), rect.y());
- bTop.translate(rect.x(), rect.y());
- bBot.translate(rect.x(), rect.y());
-
- const QColor *cols[5];
- if (opt->state & State_Enabled) {
- cols[0] = 0;
- cols[1] = &opt->palette.button().color();
- cols[2] = &opt->palette.mid().color();
- cols[3] = &opt->palette.light().color();
- cols[4] = &opt->palette.dark().color();
- } else {
- cols[0] = 0;
- cols[1] = &opt->palette.mid().color();
- cols[2] = &opt->palette.mid().color();
- cols[3] = &opt->palette.mid().color();
- cols[4] = &opt->palette.mid().color();
- }
-
-#define CMID *cols[(colspec>>12) & 0xf]
-#define CLEFT *cols[(colspec>>8) & 0xf]
-#define CTOP *cols[(colspec>>4) & 0xf]
-#define CBOT *cols[colspec & 0xf]
-
- QPen savePen = p->pen();
- QBrush saveBrush = p->brush();
- QPen pen(Qt::NoPen);
- QBrush brush = opt->palette.brush((opt->state & State_Enabled) ?
- QPalette::Button : QPalette::Mid);
- p->setPen(pen);
- p->setBrush(brush);
- p->drawPolygon(bFill);
- p->setBrush(Qt::NoBrush);
-
- p->setPen(CLEFT);
- p->drawPolyline(bLeft);
- p->setPen(CTOP);
- p->drawPolyline(bTop);
- p->setPen(CBOT);
- p->drawPolyline(bBot);
-
- p->setBrush(saveBrush);
- p->setPen(savePen);
-#undef CMID
-#undef CLEFT
-#undef CTOP
-#undef CBOT
- if (!(opt->state & State_Enabled) && proxy()->styleHint(SH_DitherDisabledText))
- p->fillRect(opt->rect, QBrush(p->background().color(), Qt::Dense5Pattern));
- break; }
-
- case PE_IndicatorDockWidgetResizeHandle: {
- const int motifOffset = 10;
- int sw = proxy()->pixelMetric(PM_SplitterWidth);
- if (opt->state & State_Horizontal) {
- int yPos = opt->rect.y() + opt->rect.height() / 2;
- int kPos = opt->rect.right() - motifOffset - sw;
- int kSize = sw - 2;
-
- qDrawShadeLine(p, opt->rect.left(), yPos, kPos, yPos, opt->palette);
- qDrawShadePanel(p, kPos, yPos - sw / 2 + 1, kSize, kSize,
- opt->palette, false, 1, &opt->palette.brush(QPalette::Button));
- qDrawShadeLine(p, kPos + kSize - 1, yPos, opt->rect.right(), yPos, opt->palette);
- } else {
- int xPos = opt->rect.x() + opt->rect.width() / 2;
- int kPos = motifOffset;
- int kSize = sw - 2;
-
- qDrawShadeLine(p, xPos, opt->rect.top() + kPos + kSize - 1, xPos, opt->rect.bottom(), opt->palette);
- qDrawShadePanel(p, xPos - sw / 2 + 1, opt->rect.top() + kPos, kSize, kSize, opt->palette,
- false, 1, &opt->palette.brush(QPalette::Button));
- qDrawShadeLine(p, xPos, opt->rect.top(), xPos, opt->rect.top() + kPos, opt->palette);
- }
- break; }
-
- case PE_IndicatorMenuCheckMark: {
- const int markW = 6;
- const int markH = 6;
- int posX = opt->rect.x() + (opt->rect.width() - markW) / 2 - 1;
- int posY = opt->rect.y() + (opt->rect.height() - markH) / 2;
- int dfw = proxy()->pixelMetric(PM_DefaultFrameWidth);
-
- if (dfw < 2) {
- // Could do with some optimizing/caching...
- QPolygon a(7*2);
- int i, xx, yy;
- xx = posX;
- yy = 3 + posY;
- for (i=0; i<3; i++) {
- a.setPoint(2*i, xx, yy);
- a.setPoint(2*i+1, xx, yy+2);
- xx++; yy++;
- }
- yy -= 2;
- for (i=3; i<7; i++) {
- a.setPoint(2*i, xx, yy);
- a.setPoint(2*i+1, xx, yy+2);
- xx++; yy--;
- }
- if (! (opt->state & State_Enabled) && ! (opt->state & State_On)) {
- int pnt;
- p->setPen(opt->palette.highlightedText().color());
- QPoint offset(1,1);
- for (pnt = 0; pnt < (int)a.size(); pnt++)
- a[pnt] += offset;
- p->drawPolyline(a);
- for (pnt = 0; pnt < (int)a.size(); pnt++)
- a[pnt] -= offset;
- }
- p->setPen(opt->palette.text().color());
- p->drawPolyline(a);
-
- qDrawShadePanel(p, posX-2, posY-2, markW+4, markH+6, opt->palette, true, dfw);
- } else
- qDrawShadePanel(p, posX, posY, markW, markH, opt->palette, true, dfw,
- &opt->palette.brush(QPalette::Mid));
-
- break; }
-
- case PE_IndicatorProgressChunk:
- {
- bool vertical = false;
- if (const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(opt))
- vertical = (pb2->orientation == Qt::Vertical);
- if (!vertical) {
- p->fillRect(opt->rect.x(), opt->rect.y(), opt->rect.width(),
- opt->rect.height(), opt->palette.brush(QPalette::Highlight));
- } else {
- p->fillRect(opt->rect.x(), opt->rect.y(), opt->rect.width(), opt->rect.height(),
- opt->palette.brush(QPalette::Highlight));
- }
- }
- break;
-
- default:
- QCommonStyle::drawPrimitive(pe, opt, p, w);
- break;
- }
-}
-
-
-/*!
- \reimp
-*/
-void QMotifStyle::drawControl(ControlElement element, const QStyleOption *opt, QPainter *p,
- const QWidget *widget) const
-{
- switch(element) {
- case CE_Splitter: {
- QStyleOption handleOpt = *opt;
- if (handleOpt.state & State_Horizontal)
- handleOpt.state &= ~State_Horizontal;
- else
- handleOpt.state |= State_Horizontal;
- proxy()->drawPrimitive(PE_IndicatorDockWidgetResizeHandle, &handleOpt, p, widget);
- break; }
-
- case CE_ScrollBarSubLine:
- case CE_ScrollBarAddLine:{
- PrimitiveElement pe;
- if (element == CE_ScrollBarAddLine)
- pe = (opt->state & State_Horizontal) ? (opt->direction == Qt::LeftToRight ? PE_IndicatorArrowRight : PE_IndicatorArrowLeft) : PE_IndicatorArrowDown;
- else
- pe = (opt->state & State_Horizontal) ? (opt->direction == Qt::LeftToRight ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight) : PE_IndicatorArrowUp;
- QStyleOption arrowOpt = *opt;
- arrowOpt.state |= State_Enabled;
- proxy()->drawPrimitive(pe, &arrowOpt, p, widget);
- if (!(opt->state & State_Enabled) && proxy()->styleHint(SH_DitherDisabledText)) {
- int fw = proxy()->pixelMetric(PM_DefaultFrameWidth);
- p->fillRect(opt->rect.adjusted(fw, fw, -fw, -fw), QBrush(p->background().color(), Qt::Dense5Pattern));
- }
- }break;
-
- case CE_ScrollBarSubPage:
- case CE_ScrollBarAddPage:
- p->fillRect(opt->rect, opt->palette.brush((opt->state & State_Enabled) ? QPalette::Mid : QPalette::Window));
- break;
-
- case CE_ScrollBarSlider: {
- QStyleOption bevelOpt = *opt;
- bevelOpt.state |= State_Raised;
- bevelOpt.state &= ~(State_Sunken | State_On);
- p->save();
- p->setBrushOrigin(bevelOpt.rect.topLeft());
- proxy()->drawPrimitive(PE_PanelButtonBevel, &bevelOpt, p, widget);
- p->restore();
- if (!(opt->state & State_Enabled) && proxy()->styleHint(SH_DitherDisabledText))
- p->fillRect(opt->rect, QBrush(p->background().color(), Qt::Dense5Pattern));
- break; }
-
- case CE_RadioButton:
- case CE_CheckBox:
- if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
- bool isRadio = (element == CE_RadioButton);
- QStyleOptionButton subopt = *btn;
- subopt.rect = subElementRect(isRadio ? SE_RadioButtonIndicator
- : SE_CheckBoxIndicator, btn, widget);
- proxy()->drawPrimitive(isRadio ? PE_IndicatorRadioButton : PE_IndicatorCheckBox,
- &subopt, p, widget);
- subopt.rect = subElementRect(isRadio ? SE_RadioButtonContents
- : SE_CheckBoxContents, btn, widget);
- proxy()->drawControl(isRadio ? CE_RadioButtonLabel : CE_CheckBoxLabel, &subopt, p, widget);
- if ((btn->state & State_HasFocus) && (!focus || !focus->isVisible())) {
- QStyleOptionFocusRect fropt;
- fropt.QStyleOption::operator=(*btn);
- fropt.rect = subElementRect(isRadio ? SE_RadioButtonFocusRect
- : SE_CheckBoxFocusRect, btn, widget);
- proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, p, widget);
- }
- }
- break;
- case CE_PushButton:
- if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
- proxy()->drawControl(CE_PushButtonBevel, btn, p, widget);
- QStyleOptionButton subopt = *btn;
- subopt.rect = subElementRect(SE_PushButtonContents, btn, widget);
- proxy()->drawControl(CE_PushButtonLabel, &subopt, p, widget);
- if ((btn->state & State_HasFocus) && (!focus || !focus->isVisible())) {
- QStyleOptionFocusRect fropt;
- fropt.QStyleOption::operator=(*btn);
- fropt.rect = subElementRect(SE_PushButtonFocusRect, btn, widget);
- proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, p, widget);
- }
- }
- break;
- case CE_PushButtonBevel:
- if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
- int diw, x1, y1, x2, y2;
- p->setPen(opt->palette.foreground().color());
- p->setBrush(QBrush(opt->palette.button().color(), Qt::NoBrush));
- diw = proxy()->pixelMetric(PM_ButtonDefaultIndicator);
- opt->rect.getCoords(&x1, &y1, &x2, &y2);
- if (btn->features & (QStyleOptionButton::AutoDefaultButton|QStyleOptionButton::DefaultButton)) {
- x1 += diw;
- y1 += diw;
- x2 -= diw;
- y2 -= diw;
- }
- if (btn->features & QStyleOptionButton::DefaultButton) {
- if (diw == 0) {
- QPolygon a;
- a.setPoints(9,
- x1, y1, x2, y1, x2, y2, x1, y2, x1, y1+1,
- x2-1, y1+1, x2-1, y2-1, x1+1, y2-1, x1+1, y1+1);
- p->setPen(opt->palette.shadow().color());
- p->drawPolygon(a);
- x1 += 2;
- y1 += 2;
- x2 -= 2;
- y2 -= 2;
- } else {
- qDrawShadePanel(p, opt->rect.adjusted(1, 1, -1, -1), opt->palette, true);
- }
- }
- if (!(btn->features & QStyleOptionButton::Flat) ||
- (btn->state & (State_Sunken | State_On))) {
- QStyleOptionButton newOpt = *btn;
- newOpt.rect = QRect(x1, y1, x2 - x1 + 1, y2 - y1 + 1);
- p->setBrushOrigin(p->brushOrigin());
- proxy()->drawPrimitive(PE_PanelButtonCommand, &newOpt, p, widget);
- }
- if (btn->features & QStyleOptionButton::HasMenu) {
- int mbi = proxy()->pixelMetric(PM_MenuButtonIndicator, btn, widget);
- QRect ir = btn->rect;
- QStyleOptionButton newBtn = *btn;
- newBtn.rect = QRect(ir.right() - mbi - 3, ir.y() + 4, mbi, ir.height() - 8);
- proxy()->drawPrimitive(PE_IndicatorArrowDown, &newBtn, p, widget);
- }
- break;
- }
-
-#ifndef QT_NO_TABBAR
- case CE_TabBarTabShape:
- if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
- const int default_frame = proxy()->pixelMetric(PM_DefaultFrameWidth, tab, widget);
- const int frame_offset = (default_frame > 1) ? 1 : 0;
-
- if (tab->shape == QTabBar::RoundedNorth || tab->shape == QTabBar::RoundedEast ||
- tab->shape == QTabBar::RoundedSouth || tab->shape == QTabBar::RoundedWest) {
- p->save();
- QRect tabRect = opt->rect;
- QColor tabLight = opt->palette.light().color();
- QColor tabDark = opt->palette.dark().color();
-
- p->fillRect(opt->rect.adjusted(default_frame, default_frame,
- -default_frame, -default_frame),
- tab->palette.background());
-
- if(tab->shape == QTabBar::RoundedWest) {
- tabDark = opt->palette.light().color();
- tabLight = opt->palette.dark().color();
- tabRect = QRect(0, 0, tabRect.height(), tabRect.width());
- p->translate(opt->rect.left(), opt->rect.bottom());
- p->rotate(-90);
- } else if(tab->shape == QTabBar::RoundedSouth) {
- tabDark = opt->palette.light().color();
- tabLight = opt->palette.dark().color();
- tabRect = QRect(0, 0, tabRect.width(), tabRect.height());
- p->translate(opt->rect.right(), opt->rect.bottom());
- p->rotate(180);
- } else if(tab->shape == QTabBar::RoundedEast) {
- tabRect = QRect(0, 0, tabRect.height(), tabRect.width());
- p->translate(opt->rect.right(), opt->rect.top());
- p->rotate(90);
- }
-
- if (default_frame > 1) {
- p->setPen(tabLight);
- p->drawLine(tabRect.left(), tabRect.bottom(),
- tabRect.right(), tabRect.bottom());
- p->setPen(tabLight);
- p->drawLine(tabRect.left(), tabRect.bottom()-1,
- tabRect.right(), tabRect.bottom()-1);
- if (tabRect.left() == 0)
- p->drawPoint(tabRect.bottomLeft());
- } else {
- p->setPen(tabLight);
- p->drawLine(tabRect.left(), tabRect.bottom(),
- tabRect.right(), tabRect.bottom());
- }
-
- if (opt->state & State_Selected) {
- p->fillRect(QRect(tabRect.left()+1, tabRect.bottom()-frame_offset,
- tabRect.width()-3, 2),
- tab->palette.brush(QPalette::Active, QPalette::Background));
- p->setPen(tab->palette.background().color());
- p->drawLine(tabRect.left()+1, tabRect.bottom(),
- tabRect.left()+1, tabRect.top()+2);
- p->setPen(tabLight);
- } else {
- p->setPen(tabLight);
- }
- p->drawLine(tabRect.left(), tabRect.bottom()-1,
- tabRect.left(), tabRect.top() + 2);
- p->drawPoint(tabRect.left()+1, tabRect.top() + 1);
- p->drawLine(tabRect.left()+2, tabRect.top(),
- tabRect.right() - 2, tabRect.top());
- p->drawPoint(tabRect.left(), tabRect.bottom());
-
- if (default_frame > 1) {
- p->drawLine(tabRect.left()+1, tabRect.bottom(),
- tabRect.left()+1, tabRect.top() + 2);
- p->drawLine(tabRect.left()+2, tabRect.top()+1,
- tabRect.right() - 2, tabRect.top()+1);
- }
-
- p->setPen(tabDark);
- p->drawLine(tabRect.right() - 1, tabRect.top() + 2,
- tabRect.right() - 1, tabRect.bottom() - 1 +
- ((opt->state & State_Selected) ? frame_offset : -frame_offset));
- if (default_frame > 1) {
- p->drawPoint(tabRect.right() - 1, tabRect.top() + 1);
- p->drawLine(tabRect.right(), tabRect.top() + 2, tabRect.right(),
- tabRect.bottom() -
- ((opt->state & State_Selected) ?
- ((tab->position == QStyleOptionTab::End) ? 0:1):1+frame_offset));
- p->drawPoint(tabRect.right() - 1, tabRect.top() + 1);
- }
- p->restore();
- } else {
- QCommonStyle::drawControl(element, opt, p, widget);
- }
- break; }
-#endif // QT_NO_TABBAR
- case CE_ProgressBarGroove:
- qDrawShadePanel(p, opt->rect, opt->palette, true, 2);
- break;
-
- case CE_ProgressBarLabel:
- if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) {
- QTransform oldMatrix = p->transform();
- QRect rect = pb->rect;
- bool vertical = false;
- bool invert = false;
- bool bottomToTop = false;
- if (const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(opt)) {
- vertical = (pb2->orientation == Qt::Vertical);
- invert = pb2->invertedAppearance;
- bottomToTop = pb2->bottomToTop;
- }
- if (vertical) {
- QTransform m;
- rect = QRect(rect.left(), rect.top(), rect.height(), rect.width()); // flip width and height
- if (bottomToTop) {
- m.translate(0.0, rect.width());
- m.rotate(-90);
- } else {
- m.translate(rect.height(), 0.0);
- m.rotate(90);
- }
- p->setTransform(m, true);
- }
- const int unit_width = proxy()->pixelMetric(PM_ProgressBarChunkWidth, opt, widget);
- int u = rect.width() / unit_width;
- int p_v = pb->progress - pb->minimum;
- int t_s = qMax(0, pb->maximum - pb->minimum);
- if (u > 0 && pb->progress >= INT_MAX / u && t_s >= u) {
- // scale down to something usable.
- p_v /= u;
- t_s /= u;
- }
- if (pb->textVisible && t_s) {
- int nu = (u * p_v + t_s/2) / t_s;
- int x = unit_width * nu;
- QRect left(rect.x(), rect.y(), x, rect.height());
- QRect right(rect.x() + x, rect.y(), rect.width() - x, rect.height());
- Qt::LayoutDirection dir;
- dir = vertical ? (bottomToTop ? Qt::LeftToRight : Qt::RightToLeft) : pb->direction;
- if (invert)
- dir = (dir == Qt::LeftToRight) ? Qt::RightToLeft : Qt::LeftToRight;
- const QRect highlighted = visualRect(dir, rect, left);
- const QRect background = visualRect(dir, rect, right);
- p->setPen(opt->palette.highlightedText().color());
- p->setClipRect(highlighted);
- p->drawText(rect, Qt::AlignCenter | Qt::TextSingleLine, pb->text);
-
- if (pb->progress != pb->maximum) {
- p->setClipRect(background);
- p->setPen(opt->palette.highlight().color());
- p->drawText(rect, Qt::AlignCenter | Qt::TextSingleLine, pb->text);
- }
- }
- p->setTransform(oldMatrix, false);
- break;
- }
-
- case CE_MenuTearoff: {
- if(opt->state & State_Selected) {
- if(pixelMetric(PM_MenuPanelWidth, opt, widget) > 1)
- qDrawShadePanel(p, opt->rect.x(), opt->rect.y(), opt->rect.width(),
- opt->rect.height(), opt->palette, false, motifItemFrame,
- &opt->palette.brush(QPalette::Button));
- else
- qDrawShadePanel(p, opt->rect.x()+1, opt->rect.y()+1, opt->rect.width()-2,
- opt->rect.height()-2, opt->palette, true, 1, &opt->palette.brush(QPalette::Button));
- } else {
- p->fillRect(opt->rect, opt->palette.brush(QPalette::Button));
- }
- p->setPen(QPen(opt->palette.dark().color(), 1, Qt::DashLine));
- p->drawLine(opt->rect.x()+2, opt->rect.y()+opt->rect.height()/2-1, opt->rect.x()+opt->rect.width()-4,
- opt->rect.y()+opt->rect.height()/2-1);
- p->setPen(QPen(opt->palette.light().color(), 1, Qt::DashLine));
- p->drawLine(opt->rect.x()+2, opt->rect.y()+opt->rect.height()/2, opt->rect.x()+opt->rect.width()-4,
- opt->rect.y()+opt->rect.height()/2);
- break; }
-
- case CE_MenuItem:
- if (const QStyleOptionMenuItem *menuitem = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
- int maxpmw = menuitem->maxIconWidth;
- if(menuitem->menuHasCheckableItems)
- maxpmw = qMax(maxpmw, motifCheckMarkSpace);
-
- int x, y, w, h;
- opt->rect.getRect(&x, &y, &w, &h);
-
- if (menuitem->menuItemType == QStyleOptionMenuItem::Separator) { // draw separator
- int textWidth = 0;
- if (!menuitem->text.isEmpty()) {
- QFont oldFont = p->font();
- p->setFont(menuitem->font);
- p->fillRect(x, y, w, h, opt->palette.brush(QPalette::Button));
- proxy()->drawItemText(p, menuitem->rect.adjusted(10, 0, -5, 0), Qt::AlignLeft | Qt::AlignVCenter,
- menuitem->palette, menuitem->state & State_Enabled, menuitem->text,
- QPalette::Text);
- textWidth = menuitem->fontMetrics.width(menuitem->text) + 10;
- y += menuitem->fontMetrics.height() / 2;
- p->setFont(oldFont);
- }
- p->setPen(opt->palette.dark().color());
- p->drawLine(x, y, x + 5, y);
- p->drawLine(x + 5 + textWidth, y, x+w, y);
- p->setPen(opt->palette.light().color());
- p->drawLine(x, y + 1, x + 5, y + 1);
- p->drawLine(x + 5 + textWidth, y + 1, x+w, y + 1);
- return;
- }
-
- int pw = motifItemFrame;
- if((opt->state & State_Selected) && (opt->state & State_Enabled)) { // active item frame
- if(pixelMetric(PM_MenuPanelWidth, opt) > 1)
- qDrawShadePanel(p, x, y, w, h, opt->palette, false, pw,
- &opt->palette.brush(QPalette::Button));
- else
- qDrawShadePanel(p, x+1, y+1, w-2, h-2, opt->palette, true, 1,
- &opt->palette.brush(QPalette::Button));
- } else { // incognito frame
- p->fillRect(x, y, w, h, opt->palette.brush(QPalette::Button));
- }
-
- QRect vrect = visualRect(opt->direction, opt->rect,
- QRect(x+motifItemFrame, y+motifItemFrame, maxpmw,
- h-2*motifItemFrame));
- int xvis = vrect.x();
- if (menuitem->checked) {
- if(!menuitem->icon.isNull())
- qDrawShadePanel(p, xvis, y+motifItemFrame, maxpmw, h-2*motifItemFrame,
- opt->palette, true, 1, &opt->palette.brush(QPalette::Midlight));
- } else if (!(opt->state & State_Selected)) {
- p->fillRect(xvis, y+motifItemFrame, maxpmw, h-2*motifItemFrame,
- opt->palette.brush(QPalette::Button));
- }
-
- if(!menuitem->icon.isNull()) { // draw icon
- QIcon::Mode mode = QIcon::Normal; // no disabled icons in Motif
- if ((opt->state & State_Selected) && !!(opt->state & State_Enabled))
- mode = QIcon::Active;
- QPixmap pixmap;
- if (menuitem->checkType != QStyleOptionMenuItem::NotCheckable && menuitem->checked)
- pixmap = menuitem->icon.pixmap(pixelMetric(PM_SmallIconSize, opt, widget), mode, QIcon::On);
- else
- pixmap = menuitem->icon.pixmap(pixelMetric(PM_SmallIconSize, opt, widget), mode);
-
- int pixw = pixmap.width();
- int pixh = pixmap.height();
- QRect pmr(0, 0, pixw, pixh);
- pmr.moveCenter(vrect.center());
- p->setPen(opt->palette.text().color());
- p->drawPixmap(pmr.topLeft(), pixmap);
-
- } else if (menuitem->checkType != QStyleOptionMenuItem::NotCheckable) { // just "checking"...
- int mh = h - 2*motifItemFrame;
-
- QStyleOptionButton newMenuItem;
- newMenuItem.state = menuitem->checked ? State_On : State_None;
- if (opt->state & State_Enabled) {
- newMenuItem.state |= State_Enabled;
- if (menuitem->state & State_Sunken)
- newMenuItem.state |= State_Sunken;
- }
- if (menuitem->checkType & QStyleOptionMenuItem::Exclusive) {
- newMenuItem.rect.setRect(xvis + 2, y + motifItemFrame + mh / 4, 11, 11);
- proxy()->drawPrimitive(PE_IndicatorRadioButton, &newMenuItem, p, widget);
- } else {
- newMenuItem.rect.setRect(xvis + 5, y + motifItemFrame + mh / 4, 9, 9);
- proxy()->drawPrimitive(PE_IndicatorCheckBox, &newMenuItem, p, widget);
- }
- }
-
- p->setPen(opt->palette.buttonText().color());
-
- QColor discol;
- if (!(opt->state & State_Enabled)) {
- discol = opt->palette.text().color();
- p->setPen(discol);
- }
-
- int xm = motifItemFrame + maxpmw + motifItemHMargin;
-
- vrect = visualRect(opt->direction, opt->rect,
- QRect(x+xm, y+motifItemVMargin, w-xm-menuitem->tabWidth,
- h-2*motifItemVMargin));
- xvis = vrect.x();
-
- QString s = menuitem->text;
- if (!s.isNull()) { // draw text
- int t = s.indexOf(QLatin1Char('\t'));
- int m = motifItemVMargin;
- int text_flags = Qt::AlignVCenter|Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
- text_flags |= Qt::AlignLeft;
- QFont oldFont = p->font();
- p->setFont(menuitem->font);
- if (t >= 0) { // draw tab text
- QRect vr = visualRect(opt->direction, opt->rect,
- QRect(x+w-menuitem->tabWidth-motifItemHMargin-motifItemFrame,
- y+motifItemVMargin, menuitem->tabWidth,
- h-2*motifItemVMargin));
- int xv = vr.x();
- QRect tr(xv, y+m, menuitem->tabWidth, h-2*m);
- p->drawText(tr, text_flags, s.mid(t+1));
- if (!(opt->state & State_Enabled) && proxy()->styleHint(SH_DitherDisabledText))
- p->fillRect(tr, QBrush(p->background().color(), Qt::Dense5Pattern));
- s = s.left(t);
- }
- QRect tr(xvis, y+m, w - xm - menuitem->tabWidth + 1, h-2*m);
- p->drawText(tr, text_flags, s.left(t));
- p->setFont(oldFont);
- if (!(opt->state & State_Enabled) && proxy()->styleHint(SH_DitherDisabledText))
- p->fillRect(tr, QBrush(p->background().color(), Qt::Dense5Pattern));
- }
- if (menuitem->menuItemType == QStyleOptionMenuItem::SubMenu) { // draw sub menu arrow
- int dim = (h-2*motifItemFrame) / 2;
- QStyle::PrimitiveElement arrow = (opt->direction == Qt::RightToLeft ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight);
- QStyleOption arrowOpt = *opt;
- arrowOpt.rect = visualRect(opt->direction, opt->rect,
- QRect(x+w - motifArrowHMargin - motifItemFrame - dim,
- y+h/2-dim/2, dim, dim));
- if ((opt->state & State_Selected))
- arrowOpt.state = (State_Sunken | ((opt->state & State_Enabled) ? State_Enabled : State_None));
- else
- arrowOpt.state = ((opt->state & State_Enabled) ? State_Enabled : State_None);
- proxy()->drawPrimitive(arrow, &arrowOpt, p, widget);
- }
- break; }
-
- case CE_MenuBarItem:
- if (opt->state & State_Selected) // active item
- qDrawShadePanel(p, opt->rect, opt->palette, false, motifItemFrame,
- &opt->palette.brush(QPalette::Button));
- else // other item
- p->fillRect(opt->rect, opt->palette.brush(QPalette::Button));
- QCommonStyle::drawControl(element, opt, p, widget);
- break;
-
- case CE_HeaderSection:
- p->save();
- p->setBrushOrigin(opt->rect.topLeft());
- qDrawShadePanel(p, opt->rect, opt->palette, bool(opt->state & (State_Sunken|State_On)),
- proxy()->pixelMetric(PM_DefaultFrameWidth),
- &opt->palette.brush((opt->state & State_Sunken) ? QPalette::Mid : QPalette::Button));
- p->restore();
- break;
- case CE_RubberBand: {
- QPixmap tiledPixmap(16, 16);
- QPainter pixmapPainter(&tiledPixmap);
- pixmapPainter.setPen(Qt::NoPen);
- pixmapPainter.setBrush(Qt::Dense4Pattern);
- pixmapPainter.setBackground(QBrush(opt->palette.base()));
- pixmapPainter.setBackgroundMode(Qt::OpaqueMode);
- pixmapPainter.drawRect(0, 0, tiledPixmap.width(), tiledPixmap.height());
- pixmapPainter.end();
- // ### workaround for borked XRENDER
- tiledPixmap = QPixmap::fromImage(tiledPixmap.toImage());
-
- p->save();
- QRect r = opt->rect;
- QStyleHintReturnMask mask;
- if (styleHint(QStyle::SH_RubberBand_Mask, opt, widget, &mask))
- p->setClipRegion(mask.region);
- p->drawTiledPixmap(r.x(), r.y(), r.width(), r.height(), tiledPixmap);
- p->restore();
- }
- break;
-#ifndef QT_NO_PROGRESSBAR
- case CE_ProgressBarContents:
- if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) {
- QRect rect = pb->rect;
- bool vertical = false;
- bool inverted = false;
-
- // Get extra style options if version 2
- const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(opt);
- if (pb2) {
- vertical = (pb2->orientation == Qt::Vertical);
- inverted = pb2->invertedAppearance;
- }
-
- QTransform m;
- if (vertical) {
- rect = QRect(rect.left(), rect.top(), rect.height(), rect.width()); // flip width and height
- m.rotate(90);
- m.translate(0, -(rect.height() + rect.y()*2));
- }
-
- QPalette pal2 = pb->palette;
- // Correct the highlight color if it is the same as the background
- if (pal2.highlight() == pal2.background())
- pal2.setColor(QPalette::Highlight, pb->palette.color(QPalette::Active,
- QPalette::Highlight));
- bool reverse = ((!vertical && (pb->direction == Qt::RightToLeft)) || vertical);
- if (inverted)
- reverse = !reverse;
- int w = rect.width();
- if (pb->minimum == 0 && pb->maximum == 0) {
- QRect progressBar;
- Q_D(const QMotifStyle);
- // draw busy indicator
- int x = (d->animateStep*8)% (w * 2);
- if (x > w)
- x = 2 * w - x;
- x = reverse ? rect.right() - x : x + rect.x();
- p->setTransform(m, true);
- p->setPen(QPen(pal2.highlight().color(), 4));
- p->drawLine(x, rect.y(), x, rect.height());
-
- } else
- QCommonStyle::drawControl(element, opt, p, widget);
- }
- break;
-#endif // QT_NO_PROGRESSBAR
- default:
- QCommonStyle::drawControl(element, opt, p, widget);
- break; }
-}
-
-static int get_combo_extra_width(int h, int w, int *return_awh=0)
-{
- int awh,
- tmp;
- if (h < 8) {
- awh = 6;
- } else if (h < 14) {
- awh = h - 2;
- } else {
- awh = h/2;
- }
- tmp = (awh * 3) / 2;
- if (tmp > w / 2) {
- awh = w / 2 - 3;
- tmp = w / 2 + 3;
- }
-
- if (return_awh)
- *return_awh = awh;
-
- return tmp;
-}
-
-static void get_combo_parameters(const QRect &r,
- int &ew, int &awh, int &ax,
- int &ay, int &sh, int &dh,
- int &sy)
-{
- ew = get_combo_extra_width(r.height(), r.width(), &awh);
-
- sh = (awh+3)/4;
- if (sh < 3)
- sh = 3;
- dh = sh/2 + 1;
-
- ay = r.y() + (r.height()-awh-sh-dh)/2;
- if (ay < 0) {
- //panic mode
- ay = 0;
- sy = r.height();
- } else {
- sy = ay+awh+dh;
- }
- ax = r.x() + r.width() - ew;
- ax += (ew-awh)/2;
-}
-
-/*!
- \reimp
-*/
-void QMotifStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p,
- const QWidget *widget) const
-{
- switch (cc) {
- case CC_ToolButton:
- if (const QStyleOptionToolButton *toolbutton
- = qstyleoption_cast<const QStyleOptionToolButton *>(opt)) {
- QRect button, menuarea;
- button = proxy()->subControlRect(cc, toolbutton, SC_ToolButton, widget);
- menuarea = proxy()->subControlRect(cc, toolbutton, SC_ToolButtonMenu, widget);
-
- State bflags = toolbutton->state & ~State_Sunken;
- if (bflags & State_AutoRaise) {
- if (!(bflags & State_MouseOver) || !(bflags & State_Enabled)) {
- bflags &= ~State_Raised;
- }
- }
- State mflags = bflags;
- if (toolbutton->state & State_Sunken) {
- if (toolbutton->activeSubControls & SC_ToolButton)
- bflags |= State_Sunken;
- mflags |= State_Sunken;
- }
-
- QStyleOption tool(0);
- tool.palette = toolbutton->palette;
- if (toolbutton->subControls & SC_ToolButton) {
- if (bflags & (State_Sunken | State_On | State_Raised)) {
- tool.rect = button;
- tool.state = bflags;
- proxy()->drawPrimitive(PE_PanelButtonTool, &tool, p, widget);
- }
- }
-
- if ((toolbutton->state & State_HasFocus) && (!focus || !focus->isVisible())) {
- QStyleOptionFocusRect fr;
- fr.QStyleOption::operator=(*toolbutton);
- fr.rect = toolbutton->rect.adjusted(3, 3, -3, -3);
- proxy()->drawPrimitive(PE_FrameFocusRect, &fr, p, widget);
- }
- QStyleOptionToolButton label = *toolbutton;
- label.state = bflags;
- int fw = proxy()->pixelMetric(PM_DefaultFrameWidth, opt, widget);
- label.rect = button.adjusted(fw, fw, -fw, -fw);
- proxy()->drawControl(CE_ToolButtonLabel, &label, p, widget);
-
- if (toolbutton->subControls & SC_ToolButtonMenu) {
- tool.rect = menuarea;
- tool.state = mflags;
- if (mflags & (State_Sunken | State_On | State_Raised))
- proxy()->drawPrimitive(PE_IndicatorButtonDropDown, &tool, p, widget);
- proxy()->drawPrimitive(PE_IndicatorArrowDown, &tool, p, widget);
- } else if (toolbutton->features & QStyleOptionToolButton::HasMenu) {
- int mbi = proxy()->pixelMetric(PM_MenuButtonIndicator, toolbutton, widget);
- QRect ir = toolbutton->rect;
- QStyleOptionToolButton newBtn = *toolbutton;
- newBtn.rect = QRect(ir.right() + 5 - mbi, ir.height() - mbi + 4, mbi - 6, mbi - 6);
- proxy()->drawPrimitive(PE_IndicatorArrowDown, &newBtn, p, widget);
- }
- }
- break;
-#ifndef QT_NO_SPINBOX
- case CC_SpinBox:
- if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
- QStyleOptionSpinBox copy = *spinbox;
- PrimitiveElement pe;
-
- if (spinbox->frame && (spinbox->subControls & SC_SpinBoxFrame)) {
- QRect r = proxy()->subControlRect(CC_SpinBox, spinbox, SC_SpinBoxFrame, widget);
- qDrawShadePanel(p, r, opt->palette, false, proxy()->pixelMetric(PM_SpinBoxFrameWidth));
-
- int fw = proxy()->pixelMetric(QStyle::PM_DefaultFrameWidth);
- r = proxy()->subControlRect(CC_SpinBox, spinbox, SC_SpinBoxEditField, widget).adjusted(-fw,-fw,fw,fw);
- QStyleOptionFrame lineOpt;
- lineOpt.QStyleOption::operator=(*opt);
- lineOpt.rect = r;
- lineOpt.lineWidth = fw;
- lineOpt.midLineWidth = 0;
- lineOpt.state |= QStyle::State_Sunken;
- proxy()->drawPrimitive(QStyle::PE_FrameLineEdit, &lineOpt, p, widget);
- }
-
- if (spinbox->subControls & SC_SpinBoxUp) {
- copy.subControls = SC_SpinBoxUp;
- QPalette pal2 = spinbox->palette;
- if (!(spinbox->stepEnabled & QAbstractSpinBox::StepUpEnabled)) {
- pal2.setCurrentColorGroup(QPalette::Disabled);
- copy.state &= ~State_Enabled;
- }
-
- copy.palette = pal2;
-
- if (spinbox->activeSubControls == SC_SpinBoxUp && (spinbox->state & State_Sunken)) {
- copy.state |= State_On;
- copy.state |= State_Sunken;
- } else {
- copy.state |= State_Raised;
- copy.state &= ~State_Sunken;
- }
- pe = (spinbox->buttonSymbols == QAbstractSpinBox::PlusMinus ? PE_IndicatorSpinPlus
- : PE_IndicatorSpinUp);
-
- copy.rect = proxy()->subControlRect(CC_SpinBox, spinbox, SC_SpinBoxUp, widget);
- proxy()->drawPrimitive(pe, &copy, p, widget);
- }
-
- if (spinbox->subControls & SC_SpinBoxDown) {
- copy.subControls = SC_SpinBoxDown;
- copy.state = spinbox->state;
- QPalette pal2 = spinbox->palette;
- if (!(spinbox->stepEnabled & QAbstractSpinBox::StepDownEnabled)) {
- pal2.setCurrentColorGroup(QPalette::Disabled);
- copy.state &= ~State_Enabled;
- }
- copy.palette = pal2;
-
- if (spinbox->activeSubControls == SC_SpinBoxDown && (spinbox->state & State_Sunken)) {
- copy.state |= State_On;
- copy.state |= State_Sunken;
- } else {
- copy.state |= State_Raised;
- copy.state &= ~State_Sunken;
- }
- pe = (spinbox->buttonSymbols == QAbstractSpinBox::PlusMinus ? PE_IndicatorSpinMinus
- : PE_IndicatorSpinDown);
-
- copy.rect = proxy()->subControlRect(CC_SpinBox, spinbox, SC_SpinBoxDown, widget);
- proxy()->drawPrimitive(pe, &copy, p, widget);
- }
- }
- break;
-#endif // QT_NO_SPINBOX
-#ifndef QT_NO_SLIDER
- case CC_Slider:
- if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
- QRect groove = proxy()->subControlRect(CC_Slider, opt, SC_SliderGroove, widget),
- handle = proxy()->subControlRect(CC_Slider, opt, SC_SliderHandle, widget);
-
- if ((opt->subControls & SC_SliderGroove) && groove.isValid()) {
- qDrawShadePanel(p, groove, opt->palette, true, proxy()->pixelMetric(PM_DefaultFrameWidth),
- &opt->palette.brush((opt->state & State_Enabled) ? QPalette::Mid : QPalette::Window));
- if ((opt->state & State_HasFocus) && (!focus || !focus->isVisible())) {
- QStyleOption focusOpt = *opt;
- focusOpt.rect = subElementRect(SE_SliderFocusRect, opt, widget);
- proxy()->drawPrimitive(PE_FrameFocusRect, &focusOpt, p, widget);
- }
- }
-
- if ((opt->subControls & SC_SliderHandle) && handle.isValid()) {
- QStyleOption bevelOpt = *opt;
- bevelOpt.state = (opt->state | State_Raised) & ~State_Sunken;
- bevelOpt.rect = handle;
- p->save();
- p->setBrushOrigin(bevelOpt.rect.topLeft());
- proxy()->drawPrimitive(PE_PanelButtonBevel, &bevelOpt, p, widget);
- p->restore();
-
- if (slider->orientation == Qt::Horizontal) {
- int mid = handle.x() + handle.width() / 2;
- qDrawShadeLine(p, mid, handle.y(), mid, handle.y() + handle.height() - 2,
- opt->palette, true, 1);
- } else {
- int mid = handle.y() + handle.height() / 2;
- qDrawShadeLine(p, handle.x(), mid, handle.x() + handle.width() - 2, mid, opt->palette,
- true, 1);
- }
- if (!(opt->state & State_Enabled) && proxy()->styleHint(SH_DitherDisabledText))
- p->fillRect(handle, QBrush(p->background().color(), Qt::Dense5Pattern));
- }
-
- if (slider->subControls & SC_SliderTickmarks) {
- QStyleOptionSlider tmpSlider = *slider;
- tmpSlider.subControls = SC_SliderTickmarks;
- int frameWidth = proxy()->pixelMetric(PM_DefaultFrameWidth);
- tmpSlider.rect.translate(frameWidth - 1, 0);
- QCommonStyle::drawComplexControl(cc, &tmpSlider, p, widget);
- }
- }
- break;
-#endif // QT_NO_SLIDER
- case CC_ComboBox:
- if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
- if (opt->subControls & SC_ComboBoxArrow) {
- int awh, ax, ay, sh, sy, dh, ew;
- int fw = cb->frame ? proxy()->pixelMetric(PM_ComboBoxFrameWidth, opt, widget) : 0;
-
- if (cb->frame) {
- QStyleOptionButton btn;
- btn.QStyleOption::operator=(*cb);
- btn.state |= QStyle::State_Raised;
- proxy()->drawPrimitive(PE_PanelButtonCommand, &btn, p, widget);
- } else {
- p->fillRect(opt->rect, opt->palette.brush(QPalette::Button));
- }
-
- QRect tr = opt->rect;
- tr.adjust(fw, fw, -fw, -fw);
- get_combo_parameters(tr, ew, awh, ax, ay, sh, dh, sy);
-
- QRect ar = QStyle::visualRect(opt->direction, opt->rect, QRect(ax,ay,awh,awh));
-
- QStyleOption arrowOpt = *opt;
- arrowOpt.rect = ar;
- arrowOpt.state |= State_Enabled;
- proxy()->drawPrimitive(PE_IndicatorArrowDown, &arrowOpt, p, widget);
-
-
- // draws the shaded line under the arrow
- p->setPen(opt->palette.light().color());
- p->drawLine(ar.x(), sy, ar.x()+awh-1, sy);
- p->drawLine(ar.x(), sy, ar.x(), sy+sh-1);
- p->setPen(opt->palette.dark().color());
- p->drawLine(ar.x()+1, sy+sh-1, ar.x()+awh-1, sy+sh-1);
- p->drawLine(ar.x()+awh-1, sy+1, ar.x()+awh-1, sy+sh-1);
-
- if ((cb->state & State_HasFocus) && (!focus || !focus->isVisible())) {
- QStyleOptionFocusRect focus;
- focus.QStyleOption::operator=(*opt);
- focus.rect = subElementRect(SE_ComboBoxFocusRect, opt, widget);
- focus.backgroundColor = opt->palette.button().color();
- proxy()->drawPrimitive(PE_FrameFocusRect, &focus, p, widget);
- }
- }
-
- if (opt->subControls & SC_ComboBoxEditField) {
- if (cb->editable) {
- QRect er = proxy()->subControlRect(CC_ComboBox, opt, SC_ComboBoxEditField, widget);
- er.adjust(-1, -1, 1, 1);
- qDrawShadePanel(p, er, opt->palette, true, 1,
- &opt->palette.brush(QPalette::Base));
- }
- }
- p->setPen(opt->palette.buttonText().color());
- }
- break;
-
-#ifndef QT_NO_SCROLLBAR
- case CC_ScrollBar: {
- if (opt->subControls & SC_ScrollBarGroove)
- qDrawShadePanel(p, opt->rect, opt->palette, true,
- proxy()->pixelMetric(PM_DefaultFrameWidth, opt, widget),
- &opt->palette.brush((opt->state & State_Enabled) ? QPalette::Mid : QPalette::Window));
-
- if (const QStyleOptionSlider *scrollbar = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
- QStyleOptionSlider newScrollbar = *scrollbar;
- if (scrollbar->minimum == scrollbar->maximum)
- newScrollbar.state |= State_Enabled; // make sure that the slider is drawn.
- QCommonStyle::drawComplexControl(cc, &newScrollbar, p, widget);
- }
- break; }
-#endif
-
- case CC_Q3ListView:
- if (opt->subControls & (SC_Q3ListViewBranch | SC_Q3ListViewExpand)) {
- int i;
- if (opt->subControls & SC_Q3ListView)
- QCommonStyle::drawComplexControl(cc, opt, p, widget);
- if (const QStyleOptionQ3ListView *lv = qstyleoption_cast<const QStyleOptionQ3ListView *>(opt)) {
- QStyleOptionQ3ListViewItem item = lv->items.at(0);
- int y = opt->rect.y();
- int c;
- QPolygon dotlines;
- if ((opt->activeSubControls & SC_All) && (opt->subControls & SC_Q3ListViewExpand)) {
- c = 2;
- dotlines.resize(2);
- dotlines[0] = QPoint(opt->rect.right(), opt->rect.top());
- dotlines[1] = QPoint(opt->rect.right(), opt->rect.bottom());
- } else {
- int linetop = 0, linebot = 0;
- // each branch needs at most two lines, ie. four end points
- dotlines.resize(item.childCount * 4);
- c = 0;
-
- // skip the stuff above the exposed rectangle
- for (i = 1; i < lv->items.size(); ++i) {
- QStyleOptionQ3ListViewItem child = lv->items.at(i);
- if (child.height + y > 0)
- break;
- y += child.totalHeight;
- }
-
- int bx = opt->rect.width() / 2;
-
- // paint stuff in the magical area
- while (i < lv->items.size() && y < lv->rect.height()) {
- QStyleOptionQ3ListViewItem child = lv->items.at(i);
- if (child.features & QStyleOptionQ3ListViewItem::Visible) {
- int lh;
- if (!(item.features & QStyleOptionQ3ListViewItem::MultiLine))
- lh = child.height;
- else
- lh = p->fontMetrics().height() + 2 * lv->itemMargin;
- lh = qMax(lh, QApplication::globalStrut().height());
- if (lh % 2 > 0)
- lh++;
- linebot = y + lh/2;
- if ((child.features & QStyleOptionQ3ListViewItem::Expandable || child.childCount > 0) &&
- child.height > 0) {
- // needs a box
- p->setPen(opt->palette.text().color());
- p->drawRect(bx-4, linebot-4, 9, 9);
- QPolygon a;
- if ((child.state & State_Open))
- a.setPoints(3, bx-2, linebot-2,
- bx, linebot+2,
- bx+2, linebot-2); //Qt::RightArrow
- else
- a.setPoints(3, bx-2, linebot-2,
- bx+2, linebot,
- bx-2, linebot+2); //Qt::DownArrow
- p->setBrush(opt->palette.text());
- p->drawPolygon(a);
- p->setBrush(Qt::NoBrush);
- // dotlinery
- dotlines[c++] = QPoint(bx, linetop);
- dotlines[c++] = QPoint(bx, linebot - 5);
- dotlines[c++] = QPoint(bx + 5, linebot);
- dotlines[c++] = QPoint(opt->rect.width(), linebot);
- linetop = linebot + 5;
- } else {
- // just dotlinery
- dotlines[c++] = QPoint(bx+1, linebot);
- dotlines[c++] = QPoint(opt->rect.width(), linebot);
- }
- y += child.totalHeight;
- }
- ++i;
- }
-
- // Expand line height to edge of rectangle if there's any
- // visible child below
- while (i < lv->items.size() && lv->items.at(i).height <= 0)
- ++i;
- if (i < lv->items.size())
- linebot = opt->rect.height();
-
- if (linetop < linebot) {
- dotlines[c++] = QPoint(bx, linetop);
- dotlines[c++] = QPoint(bx, linebot);
- }
- }
-
- int line; // index into dotlines
- p->setPen(opt->palette.text().color());
- if (opt->subControls & SC_Q3ListViewBranch) for(line = 0; line < c; line += 2) {
- p->drawLine(dotlines[line].x(), dotlines[line].y(),
- dotlines[line+1].x(), dotlines[line+1].y());
- }
- }
- break; }
-
- default:
- QCommonStyle::drawComplexControl(cc, opt, p, widget);
- break;
- }
-}
-
-
-/*! \reimp */
-int QMotifStyle::pixelMetric(PixelMetric pm, const QStyleOption *opt,
- const QWidget *widget) const
-{
- int ret = 0;
-
- switch(pm) {
- case PM_ButtonDefaultIndicator:
- ret = 5;
- break;
-
- case PM_CheckBoxLabelSpacing:
- case PM_RadioButtonLabelSpacing:
- ret = 10;
- break;
-
- case PM_ToolBarFrameWidth:
- ret = proxy()->pixelMetric(PM_DefaultFrameWidth);
- break;
-
- case PM_ToolBarItemMargin:
- ret = 1;
- break;
-
- case PM_ButtonShiftHorizontal:
- case PM_ButtonShiftVertical:
- ret = 0;
- break;
-
- case PM_SplitterWidth:
- ret = qMax(10, QApplication::globalStrut().width());
- break;
-
- case PM_SliderLength:
- ret = 30;
- break;
-
- case PM_SliderThickness:
- ret = 16 + 4 * proxy()->pixelMetric(PM_DefaultFrameWidth);
- break;
-#ifndef QT_NO_SLIDER
- case PM_SliderControlThickness:
- if (const QStyleOptionSlider *sl = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
- int space = (sl->orientation == Qt::Horizontal) ? sl->rect.height() : sl->rect.width();
- int ticks = sl->tickPosition;
- int n = 0;
- if (ticks & QSlider::TicksAbove)
- n++;
- if (ticks & QSlider::TicksBelow)
- n++;
- if (!n) {
- ret = space;
- break;
- }
-
- int thick = 6; // Magic constant to get 5 + 16 + 5
-
- space -= thick;
- //### the two sides may be unequal in size
- if (space > 0)
- thick += (space * 2) / (n + 2);
- ret = thick;
- }
- break;
-
- case PM_SliderSpaceAvailable:
- if (const QStyleOptionSlider *sl = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
- if (sl->orientation == Qt::Horizontal)
- ret = sl->rect.width() - proxy()->pixelMetric(PM_SliderLength, opt, widget) - 2 * proxy()->pixelMetric(PM_DefaultFrameWidth, opt, widget);
- else
- ret = sl->rect.height() - proxy()->pixelMetric(PM_SliderLength, opt, widget) - 2 * proxy()->pixelMetric(PM_DefaultFrameWidth, opt, widget);
- }
- break;
-#endif // QT_NO_SLIDER
- case PM_DockWidgetFrameWidth:
- ret = 2;
- break;
-
- case PM_DockWidgetHandleExtent:
- ret = 9;
- break;
-
- case PM_ProgressBarChunkWidth:
- ret = 1;
- break;
-
- case PM_ExclusiveIndicatorWidth:
- case PM_ExclusiveIndicatorHeight:
- ret = 13;
- break;
-
- case PM_MenuBarHMargin:
- ret = 2; // really ugly, but Motif
- break;
-
- case PM_MenuButtonIndicator:
- if (!opt)
- ret = 12;
- else
- ret = qMax(12, (opt->rect.height() - 4) / 3);
- break;
- default:
- ret = QCommonStyle::pixelMetric(pm, opt, widget);
- break;
- }
- return ret;
-}
-
-
-/*!
- \reimp
-*/
-QRect
-QMotifStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex *opt,
- SubControl sc, const QWidget *widget) const
-{
- switch (cc) {
-#ifndef QT_NO_SPINBOX
- case CC_SpinBox:
- if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
- int fw = spinbox->frame ? proxy()->pixelMetric(PM_SpinBoxFrameWidth, spinbox, widget) : 0;
- QSize bs;
- bs.setHeight(opt->rect.height()/2 - fw);
- bs.setWidth(qMin(bs.height() * 8 / 5, opt->rect.width() / 4)); // 1.6 -approximate golden mean
- bs = bs.expandedTo(QApplication::globalStrut());
- int y = fw + spinbox->rect.y();
- int x, lx, rx;
- x = spinbox->rect.x() + opt->rect.width() - fw - bs.width();
- lx = fw;
- rx = x - fw * 2;
- const int margin = spinbox->frame ? 4 : 0;
- switch (sc) {
- case SC_SpinBoxUp:
- if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons)
- return QRect();
- return visualRect(spinbox->direction, spinbox->rect,
- QRect(x, y, bs.width(), bs.height() - 1));
- case SC_SpinBoxDown:
- if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons)
- return QRect();
- return visualRect(spinbox->direction, spinbox->rect,
- QRect(x, y + bs.height() + 1, bs.width(), bs.height() - 1));
- case SC_SpinBoxEditField:
- if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons)
- return visualRect(spinbox->direction, spinbox->rect,
- QRect(lx + margin, y + margin,
- spinbox->rect.width() - 2*fw - 2*margin,
- spinbox->rect.height() - 2*fw - 2*margin));
-
- return visualRect(spinbox->direction, spinbox->rect,
- QRect(lx + margin, y + margin, rx - margin,
- spinbox->rect.height() - 2*fw - 2 * margin));
- case SC_SpinBoxFrame:
- return visualRect(spinbox->direction, spinbox->rect, spinbox->rect);
- default:
- break;
- }
- break; }
-#endif // QT_NO_SPINBOX
-#ifndef QT_NO_SLIDER
- case CC_Slider:
- if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
- if (sc == SC_SliderHandle) {
- int tickOffset = proxy()->pixelMetric(PM_SliderTickmarkOffset, opt, widget);
- int thickness = proxy()->pixelMetric(PM_SliderControlThickness, opt, widget);
- bool horizontal = slider->orientation == Qt::Horizontal;
- int len = proxy()->pixelMetric(PM_SliderLength, opt, widget);
- int motifBorder = proxy()->pixelMetric(PM_DefaultFrameWidth);
- int sliderPos = sliderPositionFromValue(slider->minimum, slider->maximum, slider->sliderPosition,
- horizontal ? slider->rect.width() - len - 2 * motifBorder
- : slider->rect.height() - len - 2 * motifBorder,
- slider->upsideDown);
- if (horizontal)
- return visualRect(slider->direction, slider->rect,
- QRect(sliderPos + motifBorder, tickOffset + motifBorder, len,
- thickness - 2 * motifBorder));
- return visualRect(slider->direction, slider->rect,
- QRect(tickOffset + motifBorder, sliderPos + motifBorder,
- thickness - 2 * motifBorder, len));
- }
- }
- break;
-#endif // QT_NO_SLIDER
-#ifndef QT_NO_SCROLLBAR
- case CC_ScrollBar:
- if (const QStyleOptionSlider *scrollbar = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
- int dfw = proxy()->pixelMetric(PM_DefaultFrameWidth);
- QRect rect = visualRect(scrollbar->direction, scrollbar->rect,
- QCommonStyle::subControlRect(cc, scrollbar, sc, widget));
- if (sc == SC_ScrollBarSlider) {
- if (scrollbar->orientation == Qt::Horizontal)
- rect.adjust(-dfw, dfw, dfw, -dfw);
- else
- rect.adjust(dfw, -dfw, -dfw, dfw);
- } else if (sc != SC_ScrollBarGroove) {
- if (scrollbar->orientation == Qt::Horizontal)
- rect.adjust(0, dfw, 0, -dfw);
- else
- rect.adjust(dfw, 0, -dfw, 0);
- }
- return visualRect(scrollbar->direction, scrollbar->rect, rect);
- }
- break;
-#endif // QT_NO_SCROLLBAR
-#ifndef QT_NO_COMBOBOX
- case CC_ComboBox:
- if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
- switch (sc) {
- case SC_ComboBoxArrow: {
- int ew, awh, sh, dh, ax, ay, sy;
- int fw = cb->frame ? proxy()->pixelMetric(PM_ComboBoxFrameWidth, opt, widget) : 0;
- QRect cr = opt->rect;
- cr.adjust(fw, fw, -fw, -fw);
- get_combo_parameters(cr, ew, awh, ax, ay, sh, dh, sy);
- return visualRect(cb->direction, cb->rect, QRect(QPoint(ax, ay), cr.bottomRight()));
- }
-
- case SC_ComboBoxEditField: {
- int fw = cb->frame ? proxy()->pixelMetric(PM_ComboBoxFrameWidth, opt, widget) : 0;
- QRect rect = opt->rect;
- rect.adjust(fw, fw, -fw, -fw);
- int ew = get_combo_extra_width(rect.height(), rect.width());
- rect.adjust(1, 1, -1-ew, -1);
- return visualRect(cb->direction, cb->rect, rect);
- }
-
- default:
- break;
- }
- }
- break;
-#endif // QT_NO_SCROLLBAR
- default:
- break;
- }
- return QCommonStyle::subControlRect(cc, opt, sc, widget);
-}
-
-/*!
- \reimp
-*/
-QSize
-QMotifStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt,
- const QSize &contentsSize, const QWidget *widget) const
-{
- QSize sz(contentsSize);
-
- switch(ct) {
- case CT_RadioButton:
- case CT_CheckBox:
- sz = QCommonStyle::sizeFromContents(ct, opt, contentsSize, widget);
- sz.rwidth() += motifItemFrame;
- break;
-
- case CT_PushButton:
- if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
- sz = QCommonStyle::sizeFromContents(ct, opt, contentsSize, widget);
- if (!btn->text.isEmpty() && (btn->features & (QStyleOptionButton::AutoDefaultButton|QStyleOptionButton::DefaultButton)))
- sz.setWidth(qMax(75, sz.width()));
- sz += QSize(0, 1); // magical extra pixel
- }
- break;
-
- case CT_MenuBarItem: {
- if(!sz.isEmpty())
- sz += QSize(5*motifItemHMargin+1, 2*motifItemVMargin + motifItemFrame);
- break; }
-
- case CT_MenuItem:
- if (const QStyleOptionMenuItem *mi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
- sz = QCommonStyle::sizeFromContents(ct, opt, sz, widget);
- int w = sz.width(), h = sz.height();
-
- if (mi->menuItemType == QStyleOptionMenuItem::Separator) {
- w = 10;
- h = (mi->text.isEmpty()) ? motifSepHeight : mi->fontMetrics.height();
- }
-
- // a little bit of border can never harm
- w += 2*motifItemHMargin + 2*motifItemFrame;
-
- if (!mi->text.isNull() && mi->text.indexOf(QLatin1Char('\t')) >= 0)
- // string contains tab
- w += motifTabSpacing;
- else if (mi->menuItemType == QStyleOptionMenuItem::SubMenu)
- // submenu indicator needs some room if we don't have a tab column
- w += motifArrowHMargin + 4*motifItemFrame;
-
- int checkColumn = mi->maxIconWidth;
- if (mi->menuHasCheckableItems)
- checkColumn = qMax(checkColumn, motifCheckMarkSpace);
- if (checkColumn > 0)
- w += checkColumn + motifCheckMarkHMargin;
-
- sz = QSize(w, h);
- }
- break;
-
-
- default:
- sz = QCommonStyle::sizeFromContents(ct, opt, contentsSize, widget);
- break;
- }
-
- return sz;
-}
-
-/*!
- \reimp
-*/
-QRect
-QMotifStyle::subElementRect(SubElement sr, const QStyleOption *opt, const QWidget *widget) const
-{
- QRect rect;
-
- switch (sr) {
- case SE_SliderFocusRect:
- rect = QCommonStyle::subElementRect(sr, opt, widget);
- rect.adjust(2, 2, -2, -2);
- break;
-
- case SE_CheckBoxIndicator:
- case SE_RadioButtonIndicator:
- {
- rect = visualRect(opt->direction, opt->rect,
- QCommonStyle::subElementRect(sr, opt, widget));
- rect.adjust(motifItemFrame,0, motifItemFrame,0);
- rect = visualRect(opt->direction, opt->rect, rect);
- }
- break;
-
- case SE_ComboBoxFocusRect:
- {
- int awh, ax, ay, sh, sy, dh, ew;
- int fw = proxy()->pixelMetric(PM_DefaultFrameWidth, opt, widget);
- QRect tr = opt->rect;
-
- tr.adjust(fw, fw, -fw, -fw);
- get_combo_parameters(tr, ew, awh, ax, ay, sh, dh, sy);
- rect.setRect(ax-2, ay-2, awh+4, awh+sh+dh+4);
- break;
- }
-
- case SE_Q3DockWindowHandleRect:
- if (const QStyleOptionQ3DockWindow *dw = qstyleoption_cast<const QStyleOptionQ3DockWindow *>(opt)) {
- if (!dw->docked || !dw->closeEnabled)
- rect.setRect(0, 0, opt->rect.width(), opt->rect.height());
- else {
- if (dw->state == State_Horizontal)
- rect.setRect(2, 15, opt->rect.width()-2, opt->rect.height() - 15);
- else
- rect.setRect(0, 2, opt->rect.width() - 15, opt->rect.height() - 2);
- }
- rect = visualRect(dw->direction, dw->rect, rect);
- }
- break;
-
- case SE_ProgressBarLabel:
- case SE_ProgressBarGroove:
- case SE_ProgressBarContents:
- if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) {
- int textw = 0;
- if (pb->textVisible)
- textw = pb->fontMetrics.width(QLatin1String("100%")) + 6;
-
- if (pb->textAlignment == Qt::AlignLeft || pb->textAlignment == Qt::AlignCenter) {
- rect = opt->rect;
- } else {
- if(sr == SE_ProgressBarLabel)
- rect.setCoords(opt->rect.right() - textw, opt->rect.top(),
- opt->rect.right(), opt->rect.bottom());
- else
- rect.setCoords(opt->rect.left(), opt->rect.top(),
- opt->rect.right() - textw, opt->rect.bottom());
- }
- if (sr == SE_ProgressBarContents)
- rect.adjust(2, 2, -2, -2);
- rect = visualRect(pb->direction, pb->rect, rect);
- }
- break;
- case SE_CheckBoxClickRect:
- case SE_RadioButtonClickRect:
- rect = visualRect(opt->direction, opt->rect, opt->rect);
- break;
-
- default:
- rect = QCommonStyle::subElementRect(sr, opt, widget);
- }
- return rect;
-}
-
-#ifndef QT_NO_IMAGEFORMAT_XPM
-static const char * const qt_menu_xpm[] = {
-"16 16 11 1",
-" c #000000",
-", c #336600",
-". c #99CC00",
-"X c #666600",
-"o c #999933",
-"+ c #333300",
-"@ c #669900",
-"# c #999900",
-"$ c #336633",
-"% c #666633",
-"& c #99CC33",
-"................",
-"................",
-".....#,++X#.....",
-"....X X....",
-"...X Xo#% X&..",
-"..# o..&@o o..",
-".., X..#+ @X X..",
-"..+ o.o+ +o# +..",
-"..+ #o+ +## +..",
-".., %@ ++ +, X..",
-"..# o@oo+ #..",
-"...X X##$ o..",
-"....X X..",
-"....&oX++X#oX...",
-"................",
-"................"};
-
-
-static const char * const qt_close_xpm[] = {
- "12 12 2 1",
- " s None c None",
- ". c black",
- " ",
- " ",
- " . . ",
- " ... ... ",
- " ...... ",
- " .... ",
- " .... ",
- " ...... ",
- " ... ... ",
- " . . ",
- " ",
- " "};
-
-static const char * const qt_maximize_xpm[] = {
- "12 12 2 1",
- " s None c None",
- ". c black",
- " ",
- " ",
- " ",
- " . ",
- " ... ",
- " ..... ",
- " ....... ",
- " ......... ",
- " ",
- " ",
- " ",
- " "};
-
-static const char * const qt_minimize_xpm[] = {
- "12 12 2 1",
- " s None c None",
- ". c black",
- " ",
- " ",
- " ",
- " ",
- " ......... ",
- " ....... ",
- " ..... ",
- " ... ",
- " . ",
- " ",
- " ",
- " "};
-
-#if 0 // ### not used???
-static const char * const qt_normalize_xpm[] = {
- "12 12 2 1",
- " s None c None",
- ". c black",
- " ",
- " ",
- " . ",
- " .. ",
- " ... ",
- " .... ",
- " ..... ",
- " ...... ",
- " ....... ",
- " ",
- " ",
- " "};
-#endif
-
-static const char * const qt_normalizeup_xpm[] = {
- "12 12 2 1",
- " s None c None",
- ". c black",
- " ",
- " ",
- " ",
- " ....... ",
- " ...... ",
- " ..... ",
- " .... ",
- " ... ",
- " .. ",
- " . ",
- " ",
- " "};
-
-static const char * const qt_shade_xpm[] = {
- "12 12 2 1", "# c #000000",
- ". c None",
- "............",
- "............",
- ".#########..",
- ".#########..",
- "............",
- "............",
- "............",
- "............",
- "............",
- "............",
- "............",
- "............"};
-
-
-static const char * const qt_unshade_xpm[] = {
- "12 12 2 1",
- "# c #000000",
- ". c None",
- "............",
- "............",
- ".#########..",
- ".#########..",
- ".#.......#..",
- ".#.......#..",
- ".#.......#..",
- ".#.......#..",
- ".#.......#..",
- ".#########..",
- "............",
- "............"};
-
-
-static const char * dock_window_close_xpm[] = {
- "8 8 2 1",
- "# c #000000",
- ". c None",
- "##....##",
- ".##..##.",
- "..####..",
- "...##...",
- "..####..",
- ".##..##.",
- "##....##",
- "........"};
-
-// Message box icons, from page 210 of the Windows style guide.
-
-// Hand-drawn to resemble Microsoft's icons, but in the Mac/Netscape palette.
-// Thanks to TrueColor displays, it is slightly more efficient to have
-// them duplicated.
-/* XPM */
-static const char * const information_xpm[]={
- "32 32 5 1",
- ". c None",
- "c c #000000",
- "* c #999999",
- "a c #ffffff",
- "b c #0000ff",
- "...........********.............",
- "........***aaaaaaaa***..........",
- "......**aaaaaaaaaaaaaa**........",
- ".....*aaaaaaaaaaaaaaaaaa*.......",
- "....*aaaaaaaabbbbaaaaaaaac......",
- "...*aaaaaaaabbbbbbaaaaaaaac.....",
- "..*aaaaaaaaabbbbbbaaaaaaaaac....",
- ".*aaaaaaaaaaabbbbaaaaaaaaaaac...",
- ".*aaaaaaaaaaaaaaaaaaaaaaaaaac*..",
- "*aaaaaaaaaaaaaaaaaaaaaaaaaaaac*.",
- "*aaaaaaaaaabbbbbbbaaaaaaaaaaac*.",
- "*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
- "*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
- "*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
- "*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
- "*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
- ".*aaaaaaaaaaabbbbbaaaaaaaaaac***",
- ".*aaaaaaaaaaabbbbbaaaaaaaaaac***",
- "..*aaaaaaaaaabbbbbaaaaaaaaac***.",
- "...caaaaaaabbbbbbbbbaaaaaac****.",
- "....caaaaaaaaaaaaaaaaaaaac****..",
- ".....caaaaaaaaaaaaaaaaaac****...",
- "......ccaaaaaaaaaaaaaacc****....",
- ".......*cccaaaaaaaaccc*****.....",
- "........***cccaaaac*******......",
- "..........****caaac*****........",
- ".............*caaac**...........",
- "...............caac**...........",
- "................cac**...........",
- ".................cc**...........",
- "..................***...........",
- "...................**..........."};
-/* XPM */
-static const char* const warning_xpm[]={
- "32 32 4 1",
- ". c None",
- "a c #ffff00",
- "* c #000000",
- "b c #999999",
- ".............***................",
- "............*aaa*...............",
- "...........*aaaaa*b.............",
- "...........*aaaaa*bb............",
- "..........*aaaaaaa*bb...........",
- "..........*aaaaaaa*bb...........",
- ".........*aaaaaaaaa*bb..........",
- ".........*aaaaaaaaa*bb..........",
- "........*aaaaaaaaaaa*bb.........",
- "........*aaaa***aaaa*bb.........",
- ".......*aaaa*****aaaa*bb........",
- ".......*aaaa*****aaaa*bb........",
- "......*aaaaa*****aaaaa*bb.......",
- "......*aaaaa*****aaaaa*bb.......",
- ".....*aaaaaa*****aaaaaa*bb......",
- ".....*aaaaaa*****aaaaaa*bb......",
- "....*aaaaaaaa***aaaaaaaa*bb.....",
- "....*aaaaaaaa***aaaaaaaa*bb.....",
- "...*aaaaaaaaa***aaaaaaaaa*bb....",
- "...*aaaaaaaaaa*aaaaaaaaaa*bb....",
- "..*aaaaaaaaaaa*aaaaaaaaaaa*bb...",
- "..*aaaaaaaaaaaaaaaaaaaaaaa*bb...",
- ".*aaaaaaaaaaaa**aaaaaaaaaaa*bb..",
- ".*aaaaaaaaaaa****aaaaaaaaaa*bb..",
- "*aaaaaaaaaaaa****aaaaaaaaaaa*bb.",
- "*aaaaaaaaaaaaa**aaaaaaaaaaaa*bb.",
- "*aaaaaaaaaaaaaaaaaaaaaaaaaaa*bbb",
- "*aaaaaaaaaaaaaaaaaaaaaaaaaaa*bbb",
- ".*aaaaaaaaaaaaaaaaaaaaaaaaa*bbbb",
- "..*************************bbbbb",
- "....bbbbbbbbbbbbbbbbbbbbbbbbbbb.",
- ".....bbbbbbbbbbbbbbbbbbbbbbbbb.."};
-/* XPM */
-static const char* const critical_xpm[]={
- "32 32 4 1",
- ". c None",
- "a c #999999",
- "* c #ff0000",
- "b c #ffffff",
- "...........********.............",
- ".........************...........",
- ".......****************.........",
- "......******************........",
- ".....********************a......",
- "....**********************a.....",
- "...************************a....",
- "..*******b**********b*******a...",
- "..******bbb********bbb******a...",
- ".******bbbbb******bbbbb******a..",
- ".*******bbbbb****bbbbb*******a..",
- "*********bbbbb**bbbbb*********a.",
- "**********bbbbbbbbbb**********a.",
- "***********bbbbbbbb***********aa",
- "************bbbbbb************aa",
- "************bbbbbb************aa",
- "***********bbbbbbbb***********aa",
- "**********bbbbbbbbbb**********aa",
- "*********bbbbb**bbbbb*********aa",
- ".*******bbbbb****bbbbb*******aa.",
- ".******bbbbb******bbbbb******aa.",
- "..******bbb********bbb******aaa.",
- "..*******b**********b*******aa..",
- "...************************aaa..",
- "....**********************aaa...",
- "....a********************aaa....",
- ".....a******************aaa.....",
- "......a****************aaa......",
- ".......aa************aaaa.......",
- ".........aa********aaaaa........",
- "...........aaaaaaaaaaa..........",
- ".............aaaaaaa............"};
-/* XPM */
-static const char *const question_xpm[] = {
- "32 32 5 1",
- ". c None",
- "c c #000000",
- "* c #999999",
- "a c #ffffff",
- "b c #0000ff",
- "...........********.............",
- "........***aaaaaaaa***..........",
- "......**aaaaaaaaaaaaaa**........",
- ".....*aaaaaaaaaaaaaaaaaa*.......",
- "....*aaaaaaaaaaaaaaaaaaaac......",
- "...*aaaaaaaabbbbbbaaaaaaaac.....",
- "..*aaaaaaaabaaabbbbaaaaaaaac....",
- ".*aaaaaaaabbaaaabbbbaaaaaaaac...",
- ".*aaaaaaaabbbbaabbbbaaaaaaaac*..",
- "*aaaaaaaaabbbbaabbbbaaaaaaaaac*.",
- "*aaaaaaaaaabbaabbbbaaaaaaaaaac*.",
- "*aaaaaaaaaaaaabbbbaaaaaaaaaaac**",
- "*aaaaaaaaaaaaabbbaaaaaaaaaaaac**",
- "*aaaaaaaaaaaaabbaaaaaaaaaaaaac**",
- "*aaaaaaaaaaaaabbaaaaaaaaaaaaac**",
- "*aaaaaaaaaaaaaaaaaaaaaaaaaaaac**",
- ".*aaaaaaaaaaaabbaaaaaaaaaaaac***",
- ".*aaaaaaaaaaabbbbaaaaaaaaaaac***",
- "..*aaaaaaaaaabbbbaaaaaaaaaac***.",
- "...caaaaaaaaaabbaaaaaaaaaac****.",
- "....caaaaaaaaaaaaaaaaaaaac****..",
- ".....caaaaaaaaaaaaaaaaaac****...",
- "......ccaaaaaaaaaaaaaacc****....",
- ".......*cccaaaaaaaaccc*****.....",
- "........***cccaaaac*******......",
- "..........****caaac*****........",
- ".............*caaac**...........",
- "...............caac**...........",
- "................cac**...........",
- ".................cc**...........",
- "..................***...........",
- "...................**...........",
-};
-#endif
-
-/*!
- \reimp
-*/
-QPixmap
-QMotifStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt,
- const QWidget *widget) const
-{
-#ifndef QT_NO_IMAGEFORMAT_XPM
- switch (standardPixmap) {
- case SP_TitleBarMenuButton:
- return QPixmap(qt_menu_xpm);
- case SP_TitleBarShadeButton:
- return QPixmap(qt_shade_xpm);
- case SP_TitleBarUnshadeButton:
- return QPixmap(qt_unshade_xpm);
- case SP_TitleBarNormalButton:
- return QPixmap(qt_normalizeup_xpm);
- case SP_TitleBarMinButton:
- return QPixmap(qt_minimize_xpm);
- case SP_TitleBarMaxButton:
- return QPixmap(qt_maximize_xpm);
- case SP_TitleBarCloseButton:
- return QPixmap(qt_close_xpm);
- case SP_DockWidgetCloseButton:
- return QPixmap(dock_window_close_xpm);
-
- case SP_MessageBoxInformation:
- case SP_MessageBoxWarning:
- case SP_MessageBoxCritical:
- case SP_MessageBoxQuestion:
- {
- const char * const * xpm_data;
- switch (standardPixmap) {
- case SP_MessageBoxInformation:
- xpm_data = information_xpm;
- break;
- case SP_MessageBoxWarning:
- xpm_data = warning_xpm;
- break;
- case SP_MessageBoxCritical:
- xpm_data = critical_xpm;
- break;
- case SP_MessageBoxQuestion:
- xpm_data = question_xpm;
- break;
- default:
- xpm_data = 0;
- break;
- }
- QPixmap pm;
- if (xpm_data) {
- QImage image((const char **) xpm_data);
- // All that color looks ugly in Motif
- const QPalette &pal = QApplication::palette();
- switch (standardPixmap) {
- case SP_MessageBoxInformation:
- case SP_MessageBoxQuestion:
- image.setColor(2, 0xff000000 |
- pal.color(QPalette::Active, QPalette::Dark).rgb());
- image.setColor(3, 0xff000000 |
- pal.color(QPalette::Active, QPalette::Base).rgb());
- image.setColor(4, 0xff000000 |
- pal.color(QPalette::Active, QPalette::Text).rgb());
- break;
- case SP_MessageBoxWarning:
- image.setColor(1, 0xff000000 |
- pal.color(QPalette::Active, QPalette::Base).rgb());
- image.setColor(2, 0xff000000 |
- pal.color(QPalette::Active, QPalette::Text).rgb());
- image.setColor(3, 0xff000000 |
- pal.color(QPalette::Active, QPalette::Dark).rgb());
- break;
- case SP_MessageBoxCritical:
- image.setColor(1, 0xff000000 |
- pal.color(QPalette::Active, QPalette::Dark).rgb());
- image.setColor(2, 0xff000000 |
- pal.color(QPalette::Active, QPalette::Text).rgb());
- image.setColor(3, 0xff000000 |
- pal.color(QPalette::Active, QPalette::Base).rgb());
- break;
- default:
- break;
- }
- pm = QPixmap::fromImage(image);
- }
- return pm;
- }
-
- default:
- break;
- }
-#endif
-
- return QCommonStyle::standardPixmap(standardPixmap, opt, widget);
-}
-
-/*! \reimp */
-bool QMotifStyle::event(QEvent *e)
-{
- if(e->type() == QEvent::FocusIn) {
- if (QWidget *focusWidget = QApplication::focusWidget()) {
-#ifndef QT_NO_GRAPHICSVIEW
- if (QGraphicsView *graphicsView = qobject_cast<QGraphicsView *>(focusWidget)) {
- QGraphicsItem *focusItem = graphicsView->scene() ? graphicsView->scene()->focusItem() : 0;
- if (focusItem && focusItem->type() == QGraphicsProxyWidget::Type) {
- QGraphicsProxyWidget *proxy = static_cast<QGraphicsProxyWidget *>(focusItem);
- if (proxy->widget())
- focusWidget = proxy->widget()->focusWidget();
- }
- }
-#endif
- if(!focus)
- focus = new QFocusFrame(focusWidget);
- focus->setWidget(focusWidget);
- } else {
- if(focus)
- focus->setWidget(0);
- }
- } else if(e->type() == QEvent::FocusOut) {
- if(focus)
- focus->setWidget(0);
- }
- return QCommonStyle::event(e);
-}
-
-
-/*! \reimp */
-int
-QMotifStyle::styleHint(StyleHint hint, const QStyleOption *opt, const QWidget *widget,
- QStyleHintReturn *returnData) const
-{
- int ret;
-
- switch (hint) {
-#ifdef QT3_SUPPORT
- case SH_GUIStyle:
- ret = Qt::MotifStyle;
- break;
-#endif
- case SH_DrawMenuBarSeparator:
- ret = true;
- break;
-
- case SH_ScrollBar_MiddleClickAbsolutePosition:
- case SH_Slider_SloppyKeyEvents:
- case SH_ProgressDialog_CenterCancelButton:
- case SH_Menu_SpaceActivatesItem:
- case SH_ScrollView_FrameOnlyAroundContents:
- case SH_DitherDisabledText:
- ret = 1;
- break;
-
- case SH_Menu_SubMenuPopupDelay:
- ret = 96;
- break;
-
- case SH_ProgressDialog_TextLabelAlignment:
- ret = Qt::AlignLeft | Qt::AlignVCenter;
- break;
-
- case SH_ItemView_ChangeHighlightOnFocus:
- ret = 0;
- break;
-
- case SH_MessageBox_UseBorderForButtonSpacing:
- ret = 1;
- break;
-
- case SH_Dial_BackgroundRole:
- ret = QPalette::Mid;
- break;
-
- case SH_DialogButtonLayout:
- ret = QDialogButtonBox::KdeLayout;
- break;
- case SH_LineEdit_PasswordCharacter:
- ret = '*';
- break;
- case SH_DialogButtonBox_ButtonsHaveIcons:
- ret = 0;
- break;
- default:
- ret = QCommonStyle::styleHint(hint, opt, widget, returnData);
- break;
- }
-
- return ret;
-}
-
-/*! \reimp */
-QPalette QMotifStyle::standardPalette() const
-{
-#ifdef Q_WS_X11
- QColor background(0xcf, 0xcf, 0xcf);
- if (QX11Info::appDepth() <= 8)
- background = QColor(0xc0, 0xc0, 0xc0);
-#else
- QColor background = QColor(0xcf, 0xcf, 0xcf);
-#endif
-
- QColor light = background.lighter();
- QColor mid = QColor(0xa6, 0xa6, 0xa6);
- QColor dark = QColor(0x79, 0x7d, 0x79);
- QPalette palette(Qt::black, background, light, dark, mid, Qt::black, Qt::white);
- palette.setBrush(QPalette::Disabled, QPalette::WindowText, dark);
- palette.setBrush(QPalette::Disabled, QPalette::Text, dark);
- palette.setBrush(QPalette::Disabled, QPalette::ButtonText, dark);
- palette.setBrush(QPalette::Disabled, QPalette::Base, background);
- return palette;
-}
-
-QT_END_NAMESPACE
-
-#endif // !defined(QT_NO_STYLE_MOTIF) || defined(QT_PLUGIN)
diff --git a/src/gui/styles/qmotifstyle.h b/src/gui/styles/qmotifstyle.h
deleted file mode 100644
index 3cb3baf5b2..0000000000
--- a/src/gui/styles/qmotifstyle.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QMOTIFSTYLE_H
-#define QMOTIFSTYLE_H
-
-#include <QtGui/qcommonstyle.h>
-#include <QtCore/qpointer.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#if !defined(QT_NO_STYLE_MOTIF)
-
-class QPalette;
-class QFocusFrame;
-
-class QMotifStylePrivate;
-class Q_GUI_EXPORT QMotifStyle : public QCommonStyle
-{
- Q_OBJECT
-public:
- explicit QMotifStyle(bool useHighlightCols=false);
- virtual ~QMotifStyle();
-
- void setUseHighlightColors(bool);
- bool useHighlightColors() const;
-
- void polish(QPalette&);
- void polish(QWidget*);
- void unpolish(QWidget*);
- void polish(QApplication*);
- void unpolish(QApplication*);
-
- void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p,
- const QWidget *w = 0) const;
-
- void drawControl(ControlElement element, const QStyleOption *opt, QPainter *p,
- const QWidget *w = 0) const;
-
- void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p,
- const QWidget *w = 0) const;
-
- QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt,
- SubControl sc, const QWidget *widget = 0) const;
-
- int pixelMetric(PixelMetric metric, const QStyleOption *option = 0,
- const QWidget *widget = 0) const;
-
- QSize sizeFromContents(ContentsType ct, const QStyleOption *opt,
- const QSize &contentsSize, const QWidget *widget = 0) const;
-
- QRect subElementRect(SubElement r, const QStyleOption *opt, const QWidget *widget = 0) const;
-
- QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt,
- const QWidget *widget = 0) const;
-
- int styleHint(StyleHint hint, const QStyleOption *opt = 0, const QWidget *widget = 0,
- QStyleHintReturn *returnData = 0) const;
-
- bool event(QEvent *);
- QPalette standardPalette() const;
-
-protected Q_SLOTS:
- QIcon standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *opt = 0,
- const QWidget *widget = 0) const;
-
-protected:
- QPointer<QFocusFrame> focus;
- QMotifStyle(QMotifStylePrivate &dd, bool useHighlightCols = false);
- void timerEvent(QTimerEvent *event);
- bool eventFilter(QObject *o, QEvent *e);
-
-private:
- Q_DECLARE_PRIVATE(QMotifStyle)
- Q_DISABLE_COPY(QMotifStyle)
-
- bool highlightCols;
-};
-
-#endif // QT_NO_STYLE_MOTIF
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QMOTIFSTYLE_H
diff --git a/src/gui/styles/qplastiquestyle.h b/src/gui/styles/qplastiquestyle.h
deleted file mode 100644
index aab7cce839..0000000000
--- a/src/gui/styles/qplastiquestyle.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPLASTIQUESTYLE_H
-#define QPLASTIQUESTYLE_H
-
-#include <QtGui/qwindowsstyle.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#if !defined(QT_NO_STYLE_PLASTIQUE)
-
-class QPlastiqueStylePrivate;
-class Q_GUI_EXPORT QPlastiqueStyle : public QWindowsStyle
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QPlastiqueStyle)
-public:
- QPlastiqueStyle();
- ~QPlastiqueStyle();
-
- void drawPrimitive(PrimitiveElement element, const QStyleOption *option,
- QPainter *painter, const QWidget *widget = 0) const;
- void drawControl(ControlElement element, const QStyleOption *option,
- QPainter *painter, const QWidget *widget) const;
- void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option,
- QPainter *painter, const QWidget *widget) const;
- QSize sizeFromContents(ContentsType type, const QStyleOption *option,
- const QSize &size, const QWidget *widget) const;
-
- QRect subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const;
- QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt,
- SubControl sc, const QWidget *widget) const;
-
- int styleHint(StyleHint hint, const QStyleOption *option = 0, const QWidget *widget = 0,
- QStyleHintReturn *returnData = 0) const;
- SubControl hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option,
- const QPoint &pos, const QWidget *widget = 0) const;
-
- int pixelMetric(PixelMetric metric, const QStyleOption *option = 0, const QWidget *widget = 0) const;
-
- QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt,
- const QWidget *widget = 0) const;
-
- void polish(QWidget *widget);
- void polish(QApplication *app);
- void polish(QPalette &pal);
- void unpolish(QWidget *widget);
- void unpolish(QApplication *app);
-
- QPalette standardPalette() const;
-
-protected Q_SLOTS:
- QIcon standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *opt = 0,
- const QWidget *widget = 0) const;
- int layoutSpacingImplementation(QSizePolicy::ControlType control1,
- QSizePolicy::ControlType control2,
- Qt::Orientation orientation,
- const QStyleOption *option = 0,
- const QWidget *widget = 0) const;
-
-protected:
- bool eventFilter(QObject *watched, QEvent *event);
- void timerEvent(QTimerEvent *event);
-
-private:
- Q_DISABLE_COPY(QPlastiqueStyle)
- void *reserved;
-};
-
-#endif // QT_NO_STYLE_PLASTIQUE
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QPLASTIQUESTYLE_H
diff --git a/src/gui/styles/qproxystyle.h b/src/gui/styles/qproxystyle.h
deleted file mode 100644
index a63865597a..0000000000
--- a/src/gui/styles/qproxystyle.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPROXYSTYLE_H
-#define QPROXYSTYLE_H
-
-#include <QtGui/QCommonStyle>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#if !defined(QT_NO_STYLE_PROXY)
-
-class QProxyStylePrivate;
-class Q_GUI_EXPORT QProxyStyle : public QCommonStyle
-{
- Q_OBJECT
-
-public:
- QProxyStyle(QStyle *baseStyle = 0);
- ~QProxyStyle();
-
- QStyle *baseStyle() const;
- void setBaseStyle(QStyle *style);
-
- void drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = 0) const;
- void drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = 0) const;
- void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget = 0) const;
- void drawItemText(QPainter *painter, const QRect &rect, int flags, const QPalette &pal, bool enabled,
- const QString &text, QPalette::ColorRole textRole = QPalette::NoRole) const;
- virtual void drawItemPixmap(QPainter *painter, const QRect &rect, int alignment, const QPixmap &pixmap) const;
-
- QSize sizeFromContents(ContentsType type, const QStyleOption *option, const QSize &size, const QWidget *widget) const;
-
- QRect subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const;
- QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc, const QWidget *widget) const;
- QRect itemTextRect(const QFontMetrics &fm, const QRect &r, int flags, bool enabled, const QString &text) const;
- QRect itemPixmapRect(const QRect &r, int flags, const QPixmap &pixmap) const;
-
- SubControl hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option, const QPoint &pos, const QWidget *widget = 0) const;
- int styleHint(StyleHint hint, const QStyleOption *option = 0, const QWidget *widget = 0, QStyleHintReturn *returnData = 0) const;
- int pixelMetric(PixelMetric metric, const QStyleOption *option = 0, const QWidget *widget = 0) const;
-
- QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt, const QWidget *widget = 0) const;
- QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, const QStyleOption *opt) const;
- QPalette standardPalette() const;
-
- void polish(QWidget *widget);
- void polish(QPalette &pal);
- void polish(QApplication *app);
-
- void unpolish(QWidget *widget);
- void unpolish(QApplication *app);
-
-protected:
- bool event(QEvent *e);
-
-protected Q_SLOTS:
- QIcon standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *option, const QWidget *widget) const;
- int layoutSpacingImplementation(QSizePolicy::ControlType control1, QSizePolicy::ControlType control2,
- Qt::Orientation orientation, const QStyleOption *option = 0, const QWidget *widget = 0) const;
-private:
- Q_DISABLE_COPY(QProxyStyle)
- Q_DECLARE_PRIVATE(QProxyStyle)
-};
-
-#endif // QT_NO_STYLE_PROXY
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QPROXYSTYLE_H
diff --git a/src/gui/styles/qs60style.h b/src/gui/styles/qs60style.h
deleted file mode 100644
index 6993bf4aab..0000000000
--- a/src/gui/styles/qs60style.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QS60STYLE_H
-#define QS60STYLE_H
-
-#include <QtGui/qcommonstyle.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-//Public custom pixel metrics values.
-//These can be used to fetch custom pixel metric value from outside QS60Style.
-enum {
- PM_FrameCornerWidth = QStyle::PM_CustomBase + 1,
- PM_FrameCornerHeight,
- PM_BoldLineWidth,
- PM_ThinLineWidth,
- PM_MessageBoxHeight
- };
-
-class QS60StylePrivate;
-
-class Q_GUI_EXPORT QS60Style : public QCommonStyle
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QS60Style)
-
-public:
- QS60Style();
- ~QS60Style();
-
- void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget = 0) const;
- void drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = 0) const;
- void drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = 0) const;
- int pixelMetric(PixelMetric metric, const QStyleOption *option = 0, const QWidget *widget = 0) const;
- QSize sizeFromContents(ContentsType ct, const QStyleOption *opt, const QSize &contentsSize, const QWidget *w = 0) const;
- int styleHint(StyleHint sh, const QStyleOption *opt = 0, const QWidget *w = 0,
- QStyleHintReturn *shret = 0) const;
- QRect subControlRect(ComplexControl control, const QStyleOptionComplex *option, SubControl scontrol, const QWidget *widget = 0) const;
- QRect subElementRect(SubElement element, const QStyleOption *opt, const QWidget *widget = 0) const;
- void polish(QWidget *widget);
- void unpolish(QWidget *widget);
- void polish(QApplication *application);
- void unpolish(QApplication *application);
-#ifndef Q_NO_USING_KEYWORD
- using QCommonStyle::polish;
-#endif
- bool event(QEvent *e);
-
-#ifndef Q_OS_SYMBIAN
- static QStringList partKeys();
- static QStringList colorListKeys();
- void setS60Theme(const QHash<QString, QPicture> &parts,
- const QHash<QPair<QString , int>, QColor> &colors);
- bool loadS60ThemeFromBlob(const QString &blobFile);
- bool saveS60ThemeToBlob(const QString &blobFile) const;
-#endif // !Q_OS_SYMBIAN
-
-protected Q_SLOTS:
- QIcon standardIconImplementation(
- StandardPixmap standardIcon, const QStyleOption * option = 0, const QWidget * widget = 0 ) const;
-
-protected:
- void timerEvent(QTimerEvent *event);
- bool eventFilter(QObject *o, QEvent *e);
-private:
- Q_DISABLE_COPY(QS60Style)
- friend class QStyleFactory;
- friend class QApplicationPrivate;
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QS60STYLE_H
diff --git a/src/gui/styles/qs60style_s60.cpp b/src/gui/styles/qs60style_s60.cpp
deleted file mode 100644
index f272ff4a90..0000000000
--- a/src/gui/styles/qs60style_s60.cpp
+++ /dev/null
@@ -1,1591 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qs60style.h"
-#include "qs60style_p.h"
-#include "qpainter.h"
-#include "qstyleoption.h"
-#include "qstyle.h"
-#include "private/qt_s60_p.h"
-#include "private/qpixmap_s60_p.h"
-#include "private/qcore_symbian_p.h"
-#include "private/qvolatileimage_p.h"
-#include "qapplication.h"
-#include "qsettings.h"
-
-#include <w32std.h>
-#include <AknsConstants.h>
-#include <aknconsts.h>
-#include <AknsItemID.h>
-#include <AknsUtils.h>
-#include <AknsDrawUtils.h>
-#include <AknsSkinInstance.h>
-#include <AknsBasicBackgroundControlContext.h>
-#include <avkon.mbg>
-#include <AknFontAccess.h>
-#include <AknLayoutFont.h>
-#include <AknUtils.h>
-#include <aknnavi.h>
-#include <gulicon.h>
-#include <AknBitmapAnimation.h>
-#include <centralrepository.h>
-
-#if !defined(QT_NO_STYLE_S60) || defined(QT_PLUGIN)
-
-QT_BEGIN_NAMESPACE
-
-enum TDrawType {
- EDrawIcon,
- EDrawGulIcon,
- EDrawBackground,
- EDrawAnimation,
- ENoDraw
-};
-
-const TUid personalisationUID = { 0x101F876F };
-
-enum TSupportRelease {
- ES60_None = 0x0000, //indicates that the commonstyle should draw the graphics
- ES60_3_1 = 0x0001,
- ES60_3_2 = 0x0002,
- ES60_5_0 = 0x0004,
- ES60_5_1 = 0x0008,
- ES60_5_2 = 0x0010,
- ES60_5_3 = 0x0020,
- ES60_3_X = ES60_3_1 | ES60_3_2,
- // Releases before Symbian Foundation
- ES60_PreSF = ES60_3_1 | ES60_3_2 | ES60_5_0,
- // Releases before the S60 5.2
- ES60_Pre52 = ES60_3_1 | ES60_3_2 | ES60_5_0 | ES60_5_1,
- // Releases before S60 5.3
- ES60_Pre53 = ES60_3_1 | ES60_3_2 | ES60_5_0 | ES60_5_1 | ES60_5_2,
- // Add all new releases here
- ES60_All = ES60_3_1 | ES60_3_2 | ES60_5_0 | ES60_5_1 | ES60_5_2 | ES60_5_3
-};
-
-typedef struct {
- const TAknsItemID &skinID; // Determines default theme graphics ID.
- TDrawType drawType; // Determines which native drawing routine is used to draw this item.
- int supportInfo; // Defines the S60 versions that use the default graphics.
- // These two, define new graphics that are used in releases other than partMapEntry.supportInfo defined releases.
- // In general, these are given in numeric form to allow style compilation in earlier
- // native releases that do not contain the new graphics.
- int newMajorSkinId;
- int newMinorSkinId;
-} partMapEntry;
-
-AnimationData::AnimationData(const QS60StyleEnums::SkinParts part, int frames, int interval) : m_id(part),
- m_frames(frames), m_interval(interval), m_mode(QS60StyleEnums::AM_Looping)
-{
-}
-
-AnimationDataV2::AnimationDataV2(const AnimationData &data) : AnimationData(data.m_id, data.m_frames, data.m_interval),
- m_animation(0), m_currentFrame(0), m_resourceBased(false), m_timerId(0)
-{
-}
-AnimationDataV2::~AnimationDataV2()
-{
- delete m_animation;
-}
-
-QS60StyleAnimation::QS60StyleAnimation(const QS60StyleEnums::SkinParts part, int frames, int interval)
-{
- QT_TRAP_THROWING(m_defaultData = new (ELeave) AnimationData(part, frames, interval));
- QT_TRAP_THROWING(m_currentData = new (ELeave) AnimationDataV2(*m_defaultData));
-}
-
-QS60StyleAnimation::~QS60StyleAnimation()
-{
- delete m_currentData;
- delete m_defaultData;
-}
-
-void QS60StyleAnimation::setAnimationObject(CAknBitmapAnimation* animation)
-{
- Q_ASSERT(animation);
- if (m_currentData->m_animation)
- delete m_currentData->m_animation;
- m_currentData->m_animation = animation;
-}
-
-void QS60StyleAnimation::resetToDefaults()
-{
- delete m_currentData;
- m_currentData = 0;
- QT_TRAP_THROWING(m_currentData = new (ELeave) AnimationDataV2(*m_defaultData));
-}
-
-class QS60StyleModeSpecifics
-{
-public:
- static QPixmap skinnedGraphics(QS60StyleEnums::SkinParts stylepart,
- const QSize &size, QS60StylePrivate::SkinElementFlags flags);
- static QPixmap skinnedGraphics(QS60StylePrivate::SkinFrameElements frameElement, const QSize &size, QS60StylePrivate::SkinElementFlags flags);
- static QPixmap colorSkinnedGraphics(const QS60StyleEnums::SkinParts &stylepart,
- const QSize &size, QPainter *painter, QS60StylePrivate::SkinElementFlags flags);
- static QColor colorValue(const TAknsItemID &colorGroup, int colorIndex);
- static QPixmap fromFbsBitmap(CFbsBitmap *icon, CFbsBitmap *mask, QS60StylePrivate::SkinElementFlags flags, const TSize& targetSize);
- static bool disabledPartGraphic(QS60StyleEnums::SkinParts &part);
- static bool disabledFrameGraphic(QS60StylePrivate::SkinFrameElements &frame);
- static QPixmap generateMissingThemeGraphic(QS60StyleEnums::SkinParts &part, const QSize &size, QS60StylePrivate::SkinElementFlags flags);
- static TAknsItemID partSpecificThemeId(int part);
-
- static QVariant themeDefinition(QS60StyleEnums::ThemeDefinitions definition, QS60StyleEnums::SkinParts part);
-
-private:
- static QPixmap createSkinnedGraphicsLX(QS60StyleEnums::SkinParts part,
- const QSize &size, QS60StylePrivate::SkinElementFlags flags);
- static QPixmap createSkinnedGraphicsLX(QS60StylePrivate::SkinFrameElements frameElement, const QSize &size, QS60StylePrivate::SkinElementFlags flags);
- static QPixmap colorSkinnedGraphicsLX(const QS60StyleEnums::SkinParts &stylepart,
- const QSize &size, QPainter *painter, QS60StylePrivate::SkinElementFlags flags);
- static void frameIdAndCenterId(QS60StylePrivate::SkinFrameElements frameElement, TAknsItemID &frameId, TAknsItemID &centerId);
- static TRect innerRectFromElement(QS60StylePrivate::SkinFrameElements frameElement, const TRect &outerRect);
- static void fallbackInfo(const QS60StyleEnums::SkinParts &stylePart, TInt &fallbackIndex);
- static bool checkSupport(const int supportedRelease);
- // Array to match the skin ID, fallback graphics and Qt widget graphics.
- static const partMapEntry m_partMap[];
-};
-
-const partMapEntry QS60StyleModeSpecifics::m_partMap[] = {
- /* SP_QgnGrafBarWaitAnim */ {KAknsIIDQgnGrafBarWaitAnim, EDrawAnimation, ES60_All, -1,-1},
- /* SP_QgnGrafBarFrameCenter */ {KAknsIIDQgnGrafBarFrameCenter, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnGrafBarFrameSideL */ {KAknsIIDQgnGrafBarFrameSideL, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnGrafBarFrameSideR */ {KAknsIIDQgnGrafBarFrameSideR, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnGrafBarProgress */ {KAknsIIDQgnGrafBarProgress, EDrawIcon, ES60_All, -1,-1},
- // No drop area for 3.x non-touch devices
- /* SP_QgnGrafOrgBgGrid */ {KAknsIIDNone, EDrawIcon, ES60_3_X, EAknsMajorGeneric ,0x1eba}, //KAknsIIDQgnGrafOrgBgGrid
- /* SP_QgnGrafScrollArrowDown */ {KAknsIIDQgnGrafScrollArrowDown, EDrawGulIcon, ES60_All, -1,-1},
- /* SP_QgnGrafScrollArrowLeft */ {KAknsIIDQgnGrafScrollArrowLeft, EDrawGulIcon, ES60_All, -1,-1},
- /* SP_QgnGrafScrollArrowRight */ {KAknsIIDQgnGrafScrollArrowRight, EDrawGulIcon, ES60_All, -1,-1},
- /* SP_QgnGrafScrollArrowUp */ {KAknsIIDQgnGrafScrollArrowUp, EDrawGulIcon, ES60_All, -1,-1},
-
- // In S60 5.3 there is a new tab graphic
- /* SP_QgnGrafTabActiveL */ {KAknsIIDQgnGrafTabActiveL, EDrawIcon, ES60_Pre53, EAknsMajorSkin, 0x2219}, //KAknsIIDQtgFrTabActiveNormalL
- /* SP_QgnGrafTabActiveM */ {KAknsIIDQgnGrafTabActiveM, EDrawIcon, ES60_Pre53, EAknsMajorSkin, 0x221b}, //KAknsIIDQtgFrTabActiveNormalC
- /* SP_QgnGrafTabActiveR */ {KAknsIIDQgnGrafTabActiveR, EDrawIcon, ES60_Pre53, EAknsMajorSkin, 0x221a}, //KAknsIIDQtgFrTabActiveNormalR
- /* SP_QgnGrafTabPassiveL */ {KAknsIIDQgnGrafTabPassiveL, EDrawIcon, ES60_Pre53, EAknsMajorSkin, 0x2221}, //KAknsIIDQtgFrTabPassiveNormalL
- /* SP_QgnGrafTabPassiveM */ {KAknsIIDQgnGrafTabPassiveM, EDrawIcon, ES60_Pre53, EAknsMajorSkin, 0x2223}, //KAknsIIDQtgFrTabPassiveNormalC
- /* SP_QgnGrafTabPassiveR */ {KAknsIIDQgnGrafTabPassiveR, EDrawIcon, ES60_Pre53, EAknsMajorSkin, 0x2222}, //KAknsIIDQtgFrTabPassiveNormalR
-
- // In 3.1 there is no slider groove.
- /* SP_QgnGrafNsliderEndLeft */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x19cf /* KAknsIIDQgnGrafNsliderEndLeft */},
- /* SP_QgnGrafNsliderEndRight */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x19d0 /* KAknsIIDQgnGrafNsliderEndRight */},
- /* SP_QgnGrafNsliderMiddle */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x19d2 /* KAknsIIDQgnGrafNsliderMiddle */},
- /* SP_QgnIndiCheckboxOff */ {KAknsIIDQgnIndiCheckboxOff, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnIndiCheckboxOn */ {KAknsIIDQgnIndiCheckboxOn, EDrawIcon, ES60_All, -1,-1},
-
- // Following 5 items (SP_QgnIndiHlColSuper - SP_QgnIndiHlLineStraight) are available starting from S60 release 3.2.
- // In 3.1 CommonStyle drawing is used for these QTreeView elements, since no similar icons in AVKON UI.
- /* SP_QgnIndiHlColSuper */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x17d5 /* KAknsIIDQgnIndiHlColSuper */},
- /* SP_QgnIndiHlExpSuper */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x17d6 /* KAknsIIDQgnIndiHlExpSuper */},
- /* SP_QgnIndiHlLineBranch */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x17d7 /* KAknsIIDQgnIndiHlLineBranch */},
- /* SP_QgnIndiHlLineEnd */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x17d8 /* KAknsIIDQgnIndiHlLineEnd */},
- /* SP_QgnIndiHlLineStraight */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x17d9 /* KAknsIIDQgnIndiHlLineStraight */},
- /* SP_QgnIndiMarkedAdd */ {KAknsIIDQgnIndiMarkedAdd, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnIndiNaviArrowLeft */ {KAknsIIDQgnIndiNaviArrowLeft, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnIndiNaviArrowRight */ {KAknsIIDQgnIndiNaviArrowRight, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnIndiRadiobuttOff */ {KAknsIIDQgnIndiRadiobuttOff, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnIndiRadiobuttOn */ {KAknsIIDQgnIndiRadiobuttOn, EDrawIcon, ES60_All, -1,-1},
-
- // In 3.1 there different slider graphic and no pressed state.
- /* SP_QgnGrafNsliderMarker */ {KAknsIIDQgnIndiSliderEdit, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x19d1 /* KAknsIIDQgnGrafNsliderMarker */},
- /* SP_QgnGrafNsliderMarkerSelected */ {KAknsIIDQgnIndiSliderEdit, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x1a4a /* KAknsIIDQgnGrafNsliderMarkerSelected */},
- /* SP_QgnIndiSubmenu */ {KAknsIIDQgnIndiSubmenu, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnNoteErased */ {KAknsIIDQgnNoteErased, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnNoteError */ {KAknsIIDQgnNoteError, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnNoteInfo */ {KAknsIIDQgnNoteInfo, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnNoteOk */ {KAknsIIDQgnNoteOk, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnNoteQuery */ {KAknsIIDQgnNoteQuery, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnNoteWarning */ {KAknsIIDQgnNoteWarning, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnPropFileSmall */ {KAknsIIDQgnPropFileSmall, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnPropFolderCurrent */ {KAknsIIDQgnPropFolderCurrent, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnPropFolderSmall */ {KAknsIIDQgnPropFolderSmall, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnPropFolderSmallNew */ {KAknsIIDQgnPropFolderSmallNew, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnPropPhoneMemcLarge */ {KAknsIIDQgnPropPhoneMemcLarge, EDrawIcon, ES60_All, -1,-1},
-
- // Toolbar graphics is different in 3.1/3.2 vs. 5.0
- /* SP_QgnFrSctrlButtonCornerTl */ {KAknsIIDQsnFrButtonTbCornerTl, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2301}, /* KAknsIIDQgnFrSctrlButtonCornerTl*/
- /* SP_QgnFrSctrlButtonCornerTr */ {KAknsIIDQsnFrButtonTbCornerTr, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2302},
- /* SP_QgnFrSctrlButtonCornerBl */ {KAknsIIDQsnFrButtonTbCornerBl, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2303},
- /* SP_QgnFrSctrlButtonCornerBr */ {KAknsIIDQsnFrButtonTbCornerBr, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2304},
- /* SP_QgnFrSctrlButtonSideT */ {KAknsIIDQsnFrButtonTbSideT, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2305},
- /* SP_QgnFrSctrlButtonSideB */ {KAknsIIDQsnFrButtonTbSideB, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2306},
- /* SP_QgnFrSctrlButtonSideL */ {KAknsIIDQsnFrButtonTbSideL, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2307},
- /* SP_QgnFrSctrlButtonSideR */ {KAknsIIDQsnFrButtonTbSideR, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2308},
- /* SP_QgnFrSctrlButtonCenter */ {KAknsIIDQsnFrButtonTbCenter, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2309}, /*KAknsIIDQgnFrSctrlButtonCenter*/
-
- // No pressed state for toolbar button in 3.1/3.2.
- /* SP_QgnFrSctrlButtonCornerTlPressed */ {KAknsIIDQsnFrButtonTbCornerTl, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2621}, /*KAknsIIDQgnFrSctrlButtonCornerTlPressed*/
- /* SP_QgnFrSctrlButtonCornerTrPressed */ {KAknsIIDQsnFrButtonTbCornerTr, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2622},
- /* SP_QgnFrSctrlButtonCornerBlPressed */ {KAknsIIDQsnFrButtonTbCornerBl, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2623},
- /* SP_QgnFrSctrlButtonCornerBrPressed */ {KAknsIIDQsnFrButtonTbCornerBr, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2624},
- /* SP_QgnFrSctrlButtonSideTPressed */ {KAknsIIDQsnFrButtonTbSideT, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2625},
- /* SP_QgnFrSctrlButtonSideBPressed */ {KAknsIIDQsnFrButtonTbSideB, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2626},
- /* SP_QgnFrSctrlButtonSideLPressed */ {KAknsIIDQsnFrButtonTbSideL, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2627},
- /* SP_QgnFrSctrlButtonSideRPressed */ {KAknsIIDQsnFrButtonTbSideR, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2628},
- /* SP_QgnFrSctrlButtonCenterPressed */ {KAknsIIDQsnFrButtonTbCenter, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2629},
-
- // 3.1 & 3.2 do not have pressed state for scrollbar, so use normal scrollbar graphics instead.
- /* SP_QsnCpScrollHandleBottomPressed*/ {KAknsIIDQsnCpScrollHandleBottom, EDrawIcon, ES60_3_X, EAknsMajorGeneric, 0x20f8}, /*KAknsIIDQsnCpScrollHandleBottomPressed*/
- /* SP_QsnCpScrollHandleMiddlePressed*/ {KAknsIIDQsnCpScrollHandleMiddle, EDrawIcon, ES60_3_X, EAknsMajorGeneric, 0x20f9}, /*KAknsIIDQsnCpScrollHandleMiddlePressed*/
- /* SP_QsnCpScrollHandleTopPressed*/ {KAknsIIDQsnCpScrollHandleTop, EDrawIcon, ES60_3_X, EAknsMajorGeneric, 0x20fa}, /*KAknsIIDQsnCpScrollHandleTopPressed*/
-
- /* SP_QsnBgScreen */ {KAknsIIDQsnBgScreen, EDrawBackground, ES60_All, -1,-1},
-
- /* SP_QsnCpScrollBgBottom */ {KAknsIIDQsnCpScrollBgBottom, EDrawIcon, ES60_All, -1,-1},
- /* SP_QsnCpScrollBgMiddle */ {KAknsIIDQsnCpScrollBgMiddle, EDrawIcon, ES60_All, -1,-1},
- /* SP_QsnCpScrollBgTop */ {KAknsIIDQsnCpScrollBgTop, EDrawIcon, ES60_All, -1,-1},
-
- /* SP_QsnCpScrollHandleBottom */ {KAknsIIDQsnCpScrollHandleBottom, EDrawIcon, ES60_All, -1,-1},
- /* SP_QsnCpScrollHandleMiddle */ {KAknsIIDQsnCpScrollHandleMiddle, EDrawIcon, ES60_All, -1,-1},
- /* SP_QsnCpScrollHandleTop */ {KAknsIIDQsnCpScrollHandleTop, EDrawIcon, ES60_All, -1,-1},
-
- /* SP_QsnFrButtonTbCornerTl */ {KAknsIIDQsnFrButtonTbCornerTl, ENoDraw, ES60_All, -1, -1},
- /* SP_QsnFrButtonTbCornerTr */ {KAknsIIDQsnFrButtonTbCornerTr, ENoDraw, ES60_All, -1, -1},
- /* SP_QsnFrButtonTbCornerBl */ {KAknsIIDQsnFrButtonTbCornerBl, ENoDraw, ES60_All, -1, -1},
- /* SP_QsnFrButtonTbCornerBr */ {KAknsIIDQsnFrButtonTbCornerBr, ENoDraw, ES60_All, -1, -1},
- /* SP_QsnFrButtonTbSideT */ {KAknsIIDQsnFrButtonTbSideT, ENoDraw, ES60_All, -1, -1},
- /* SP_QsnFrButtonTbSideB */ {KAknsIIDQsnFrButtonTbSideB, ENoDraw, ES60_All, -1, -1},
- /* SP_QsnFrButtonTbSideL */ {KAknsIIDQsnFrButtonTbSideL, ENoDraw, ES60_All, -1, -1},
- /* SP_QsnFrButtonTbSideR */ {KAknsIIDQsnFrButtonTbSideR, ENoDraw, ES60_All, -1, -1},
- /* SP_QsnFrButtonTbCenter */ {KAknsIIDQsnFrButtonTbCenter, EDrawIcon, ES60_All, -1, -1},
-
- /* SP_QsnFrButtonTbCornerTlPressed */{KAknsIIDQsnFrButtonTbCornerTlPressed, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrButtonTbCornerTrPressed */{KAknsIIDQsnFrButtonTbCornerTrPressed, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrButtonTbCornerBlPressed */{KAknsIIDQsnFrButtonTbCornerBlPressed, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrButtonTbCornerBrPressed */{KAknsIIDQsnFrButtonTbCornerBrPressed, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrButtonTbSideTPressed */ {KAknsIIDQsnFrButtonTbSideTPressed, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrButtonTbSideBPressed */ {KAknsIIDQsnFrButtonTbSideBPressed, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrButtonTbSideLPressed */ {KAknsIIDQsnFrButtonTbSideLPressed, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrButtonTbSideRPressed */ {KAknsIIDQsnFrButtonTbSideRPressed, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrButtonTbCenterPressed */ {KAknsIIDQsnFrButtonTbCenterPressed, EDrawIcon, ES60_All, -1,-1},
-
- /* SP_QsnFrCaleCornerTl */ {KAknsIIDQsnFrCaleCornerTl, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrCaleCornerTr */ {KAknsIIDQsnFrCaleCornerTr, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrCaleCornerBl */ {KAknsIIDQsnFrCaleCornerBl, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrCaleCornerBr */ {KAknsIIDQsnFrCaleCornerBr, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrCaleSideT */ {KAknsIIDQsnFrCaleSideT, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrCaleSideB */ {KAknsIIDQsnFrCaleSideB, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrCaleSideL */ {KAknsIIDQsnFrCaleSideL, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrCaleSideR */ {KAknsIIDQsnFrCaleSideR, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrCaleCenter */ {KAknsIIDQsnFrCaleCenter, ENoDraw, ES60_All, -1,-1},
-
- /* SP_QsnFrCaleHeadingCornerTl */ {KAknsIIDQsnFrCaleHeadingCornerTl, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrCaleHeadingCornerTr */ {KAknsIIDQsnFrCaleHeadingCornerTr, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrCaleHeadingCornerBl */ {KAknsIIDQsnFrCaleHeadingCornerBl, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrCaleHeadingCornerBr */ {KAknsIIDQsnFrCaleHeadingCornerBr, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrCaleHeadingSideT */ {KAknsIIDQsnFrCaleHeadingSideT, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrCaleHeadingSideB */ {KAknsIIDQsnFrCaleHeadingSideB, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrCaleHeadingSideL */ {KAknsIIDQsnFrCaleHeadingSideL, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrCaleHeadingSideR */ {KAknsIIDQsnFrCaleHeadingSideR, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrCaleHeadingCenter */ {KAknsIIDQsnFrCaleHeadingCenter, ENoDraw, ES60_All, -1,-1},
-
- /* SP_QsnFrInputCornerTl */ {KAknsIIDQsnFrInputCornerTl, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrInputCornerTr */ {KAknsIIDQsnFrInputCornerTr, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrInputCornerBl */ {KAknsIIDQsnFrInputCornerBl, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrInputCornerBr */ {KAknsIIDQsnFrInputCornerBr, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrInputSideT */ {KAknsIIDQsnFrInputSideT, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrInputSideB */ {KAknsIIDQsnFrInputSideB, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrInputSideL */ {KAknsIIDQsnFrInputSideL, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrInputSideR */ {KAknsIIDQsnFrInputSideR, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrInputCenter */ {KAknsIIDQsnFrInputCenter, ENoDraw, ES60_All, -1,-1},
-
- /* SP_QsnFrListCornerTl */ {KAknsIIDQsnFrListCornerTl, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrListCornerTr */ {KAknsIIDQsnFrListCornerTr, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrListCornerBl */ {KAknsIIDQsnFrListCornerBl, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrListCornerBr */ {KAknsIIDQsnFrListCornerBr, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrListSideT */ {KAknsIIDQsnFrListSideT, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrListSideB */ {KAknsIIDQsnFrListSideB, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrListSideL */ {KAknsIIDQsnFrListSideL, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrListSideR */ {KAknsIIDQsnFrListSideR, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrListCenter */ {KAknsIIDQsnFrListCenter, ENoDraw, ES60_All, -1,-1},
-
- /* SP_QsnFrPopupCornerTl */ {KAknsIIDQsnFrPopupCornerTl, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrPopupCornerTr */ {KAknsIIDQsnFrPopupCornerTr, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrPopupCornerBl */ {KAknsIIDQsnFrPopupCornerBl, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrPopupCornerBr */ {KAknsIIDQsnFrPopupCornerBr, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrPopupSideT */ {KAknsIIDQsnFrPopupSideT, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrPopupSideB */ {KAknsIIDQsnFrPopupSideB, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrPopupSideL */ {KAknsIIDQsnFrPopupSideL, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrPopupSideR */ {KAknsIIDQsnFrPopupSideR, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrPopupCenter */ {KAknsIIDQsnFrPopupCenterSubmenu, ENoDraw, ES60_All, -1,-1},
-
- // ToolTip graphics different in 3.1 vs. 3.2+.
- /* SP_QsnFrPopupPreviewCornerTl */ {KAknsIIDQsnFrPopupCornerTl, ENoDraw, ES60_3_1, EAknsMajorSkin, 0x19c5}, /* KAknsIIDQsnFrPopupPreviewCornerTl */
- /* SP_QsnFrPopupPreviewCornerTr */ {KAknsIIDQsnFrPopupCornerTr, ENoDraw, ES60_3_1, EAknsMajorSkin, 0x19c6},
- /* SP_QsnFrPopupPreviewCornerBl */ {KAknsIIDQsnFrPopupCornerBl, ENoDraw, ES60_3_1, EAknsMajorSkin, 0x19c3},
- /* SP_QsnFrPopupPreviewCornerBr */ {KAknsIIDQsnFrPopupCornerBr, ENoDraw, ES60_3_1, EAknsMajorSkin, 0x19c4},
- /* SP_QsnFrPopupPreviewSideT */ {KAknsIIDQsnFrPopupSideT, ENoDraw, ES60_3_1, EAknsMajorSkin, 0x19ca},
- /* SP_QsnFrPopupPreviewSideB */ {KAknsIIDQsnFrPopupSideB, ENoDraw, ES60_3_1, EAknsMajorSkin, 0x19c7},
- /* SP_QsnFrPopupPreviewSideL */ {KAknsIIDQsnFrPopupSideL, ENoDraw, ES60_3_1, EAknsMajorSkin, 0x19c8},
- /* SP_QsnFrPopupPreviewSideR */ {KAknsIIDQsnFrPopupSideR, ENoDraw, ES60_3_1, EAknsMajorSkin, 0x19c9},
- /* SP_QsnFrPopupPreviewCenter */ {KAknsIIDQsnFrPopupCenter, ENoDraw, ES60_3_1, EAknsMajorSkin, 0x19c2},
-
- /* SP_QsnFrSetOptCornerTl */ {KAknsIIDQsnFrSetOptCornerTl, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrSetOptCornerTr */ {KAknsIIDQsnFrSetOptCornerTr, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrSetOptCornerBl */ {KAknsIIDQsnFrSetOptCornerBl, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrSetOptCornerBr */ {KAknsIIDQsnFrSetOptCornerBr, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrSetOptSideT */ {KAknsIIDQsnFrSetOptSideT, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrSetOptSideB */ {KAknsIIDQsnFrSetOptSideB, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrSetOptSideL */ {KAknsIIDQsnFrSetOptSideL, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrSetOptSideR */ {KAknsIIDQsnFrSetOptSideR, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrSetOptCenter */ {KAknsIIDQsnFrSetOptCenter, ENoDraw, ES60_All, -1,-1},
-
- // No toolbar frame for 5.0+ releases.
- /* SP_QsnFrPopupSubCornerTl */ {KAknsIIDQsnFrPopupSubCornerTl, ENoDraw, ES60_3_X, -1,-1},
- /* SP_QsnFrPopupSubCornerTr */ {KAknsIIDQsnFrPopupSubCornerTr, ENoDraw, ES60_3_X, -1,-1},
- /* SP_QsnFrPopupSubCornerBl */ {KAknsIIDQsnFrPopupSubCornerBl, ENoDraw, ES60_3_X, -1,-1},
- /* SP_QsnFrPopupSubCornerBr */ {KAknsIIDQsnFrPopupSubCornerBr, ENoDraw, ES60_3_X, -1,-1},
- /* SP_QsnFrPopupSubSideT */ {KAknsIIDQsnFrPopupSubSideT, ENoDraw, ES60_3_X, -1,-1},
- /* SP_QsnFrPopupSubSideB */ {KAknsIIDQsnFrPopupSubSideB, ENoDraw, ES60_3_X, -1,-1},
- /* SP_QsnFrPopupSubSideL */ {KAknsIIDQsnFrPopupSubSideL, ENoDraw, ES60_3_X, -1,-1},
- /* SP_QsnFrPopupSubSideR */ {KAknsIIDQsnFrPopupSubSideR, ENoDraw, ES60_3_X, -1,-1},
- /* SP_QsnFrPopupSubCenter */ {KAknsIIDQsnFrPopupCenterSubmenu, ENoDraw, ES60_3_X, -1,-1},
-
- // No inactive button graphics in 3.1/3.2
- /* SP_QsnFrButtonCornerTlInactive */ {KAknsIIDQsnFrButtonTbCornerTl, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x21b1}, /*KAknsIIDQsnFrButtonCornerTlInactive*/
- /* SP_QsnFrButtonCornerTrInactive */ {KAknsIIDQsnFrButtonTbCornerTr, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x21b2},
- /* SP_QsnFrButtonCornerBlInactive */ {KAknsIIDQsnFrButtonTbCornerBl, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x21b3},
- /* SP_QsnFrButtonCornerTrInactive */ {KAknsIIDQsnFrButtonTbCornerBr, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x21b4},
- /* SP_QsnFrButtonSideTInactive */ {KAknsIIDQsnFrButtonTbSideT, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x21b5},
- /* SP_QsnFrButtonSideBInactive */ {KAknsIIDQsnFrButtonTbSideB, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x21b6},
- /* SP_QsnFrButtonSideLInactive */ {KAknsIIDQsnFrButtonTbSideL, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x21b7},
- /* SP_QsnFrButtonSideRInactive */ {KAknsIIDQsnFrButtonTbSideR, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x21b8},
- /* SP_QsnFrButtonCenterInactive */ {KAknsIIDQsnFrButtonTbCenter, EDrawIcon, ES60_3_X, EAknsMajorSkin, 0x21b9},
-
- // No pressed down grid in 3.1/3.2
- /* SP_QsnFrGridCornerTlPressed */ {KAknsIIDQsnFrGridCornerTl, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2681}, /*KAknsIIDQsnFrGridCornerTlPressed*/
- /* SP_QsnFrGridCornerTrPressed */ {KAknsIIDQsnFrGridCornerTr, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2682},
- /* SP_QsnFrGridCornerBlPressed */ {KAknsIIDQsnFrGridCornerBl, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2683},
- /* SP_QsnFrGridCornerBrPressed */ {KAknsIIDQsnFrGridCornerBr, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2684},
- /* SP_QsnFrGridSideTPressed */ {KAknsIIDQsnFrGridSideT, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2685},
- /* SP_QsnFrGridSideBPressed */ {KAknsIIDQsnFrGridSideB, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2686},
- /* SP_QsnFrGridSideLPressed */ {KAknsIIDQsnFrGridSideL, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2687},
- /* SP_QsnFrGridSideRPressed */ {KAknsIIDQsnFrGridSideR, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2688},
- /* SP_QsnFrGridCenterPressed */ {KAknsIIDQsnFrGridCenter, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2689},
-
- // No pressed down list in 3.1/3.2
- /* SP_QsnFrListCornerTlPressed */ {KAknsIIDQsnFrListCornerTl, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x268b}, /*KAknsIIDQsnFrListCornerTlPressed*/
- /* SP_QsnFrListCornerTrPressed */ {KAknsIIDQsnFrListCornerTr, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x268c},
- /* SP_QsnFrListCornerBlPressed */ {KAknsIIDQsnFrListCornerBl, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x268d},
- /* SP_QsnFrListCornerBrPressed */ {KAknsIIDQsnFrListCornerBr, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x268e},
- /* SP_QsnFrListSideTPressed */ {KAknsIIDQsnFrListSideT, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x268f},
- /* SP_QsnFrListSideBPressed */ {KAknsIIDQsnFrListSideB, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2690},
- /* SP_QsnFrListSideLPressed */ {KAknsIIDQsnFrListSideL, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2691},
- /* SP_QsnFrListSideRPressed */ {KAknsIIDQsnFrListSideR, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2692},
- /* SP_QsnFrListCenterPressed */ {KAknsIIDQsnFrListCenter, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2693},
-};
-
-QPixmap QS60StyleModeSpecifics::skinnedGraphics(
- QS60StyleEnums::SkinParts stylepart, const QSize &size,
- QS60StylePrivate::SkinElementFlags flags)
-{
- QPixmap themedImage;
- TRAPD( error, QT_TRYCATCH_LEAVING({
- const QPixmap skinnedImage = createSkinnedGraphicsLX(stylepart, size, flags);
- themedImage = skinnedImage;
- }));
- if (error)
- return themedImage = QPixmap();
- return themedImage;
-}
-
-QPixmap QS60StyleModeSpecifics::skinnedGraphics(
- QS60StylePrivate::SkinFrameElements frame, const QSize &size, QS60StylePrivate::SkinElementFlags flags)
-{
- QPixmap themedImage;
- TRAPD( error, QT_TRYCATCH_LEAVING({
- const QPixmap skinnedImage = createSkinnedGraphicsLX(frame, size, flags);
- themedImage = skinnedImage;
- }));
- if (error)
- return themedImage = QPixmap();
- return themedImage;
-}
-
-QPixmap QS60StyleModeSpecifics::colorSkinnedGraphics(
- const QS60StyleEnums::SkinParts &stylepart, const QSize &size, QPainter *painter,
- QS60StylePrivate::SkinElementFlags flags)
-{
- QPixmap colorGraphics;
- TRAPD(error, QT_TRYCATCH_LEAVING(colorGraphics = colorSkinnedGraphicsLX(stylepart, size, painter, flags)));
- return error ? QPixmap() : colorGraphics;
-}
-
-void QS60StyleModeSpecifics::fallbackInfo(const QS60StyleEnums::SkinParts &stylePart, TInt &fallbackIndex)
-{
- switch(stylePart) {
- case QS60StyleEnums::SP_QgnGrafBarWaitAnim:
- fallbackIndex = EMbmAvkonQgn_graf_bar_wait_1;
- break;
- case QS60StyleEnums::SP_QgnGrafBarFrameCenter:
- fallbackIndex = EMbmAvkonQgn_graf_bar_frame_center;
- break;
- case QS60StyleEnums::SP_QgnGrafBarFrameSideL:
- fallbackIndex = EMbmAvkonQgn_graf_bar_frame_side_l;
- break;
- case QS60StyleEnums::SP_QgnGrafBarFrameSideR:
- fallbackIndex = EMbmAvkonQgn_graf_bar_frame_side_r;
- break;
- case QS60StyleEnums::SP_QgnGrafBarProgress:
- fallbackIndex = EMbmAvkonQgn_graf_bar_progress;
- break;
- case QS60StyleEnums::SP_QgnGrafTabActiveL:
- fallbackIndex = EMbmAvkonQgn_graf_tab_active_l;
- break;
- case QS60StyleEnums::SP_QgnGrafTabActiveM:
- fallbackIndex = EMbmAvkonQgn_graf_tab_active_m;
- break;
- case QS60StyleEnums::SP_QgnGrafTabActiveR:
- fallbackIndex = EMbmAvkonQgn_graf_tab_active_r;
- break;
- case QS60StyleEnums::SP_QgnGrafTabPassiveL:
- fallbackIndex = EMbmAvkonQgn_graf_tab_passive_l;
- break;
- case QS60StyleEnums::SP_QgnGrafTabPassiveM:
- fallbackIndex = EMbmAvkonQgn_graf_tab_passive_m;
- break;
- case QS60StyleEnums::SP_QgnGrafTabPassiveR:
- fallbackIndex = EMbmAvkonQgn_graf_tab_passive_r;
- break;
- case QS60StyleEnums::SP_QgnIndiCheckboxOff:
- fallbackIndex = EMbmAvkonQgn_indi_checkbox_off;
- break;
- case QS60StyleEnums::SP_QgnIndiCheckboxOn:
- fallbackIndex = EMbmAvkonQgn_indi_checkbox_on;
- break;
- case QS60StyleEnums::SP_QgnIndiHlColSuper:
- fallbackIndex = 0x4456; /* EMbmAvkonQgn_indi_hl_col_super */
- break;
- case QS60StyleEnums::SP_QgnIndiHlExpSuper:
- fallbackIndex = 0x4458; /* EMbmAvkonQgn_indi_hl_exp_super */
- break;
- case QS60StyleEnums::SP_QgnIndiHlLineBranch:
- fallbackIndex = 0x445A; /* EMbmAvkonQgn_indi_hl_line_branch */
- break;
- case QS60StyleEnums::SP_QgnIndiHlLineEnd:
- fallbackIndex = 0x445C; /* EMbmAvkonQgn_indi_hl_line_end */
- break;
- case QS60StyleEnums::SP_QgnIndiHlLineStraight:
- fallbackIndex = 0x445E; /* EMbmAvkonQgn_indi_hl_line_straight */
- break;
- case QS60StyleEnums::SP_QgnIndiMarkedAdd:
- fallbackIndex = EMbmAvkonQgn_indi_marked_add;
- break;
- case QS60StyleEnums::SP_QgnIndiNaviArrowLeft:
- fallbackIndex = EMbmAvkonQgn_indi_navi_arrow_left;
- break;
- case QS60StyleEnums::SP_QgnIndiNaviArrowRight:
- fallbackIndex = EMbmAvkonQgn_indi_navi_arrow_right;
- break;
- case QS60StyleEnums::SP_QgnIndiRadiobuttOff:
- fallbackIndex = EMbmAvkonQgn_indi_radiobutt_off;
- break;
- case QS60StyleEnums::SP_QgnIndiRadiobuttOn:
- fallbackIndex = EMbmAvkonQgn_indi_radiobutt_on;
- break;
- case QS60StyleEnums::SP_QgnGrafNsliderMarker:
- fallbackIndex = 17572; /* EMbmAvkonQgn_graf_nslider_marker */
- break;
- case QS60StyleEnums::SP_QgnGrafNsliderMarkerSelected:
- fallbackIndex = 17574; /* EMbmAvkonQgn_graf_nslider_marker_selected */
- break;
- case QS60StyleEnums::SP_QgnIndiSubmenu:
- fallbackIndex = EMbmAvkonQgn_indi_submenu;
- break;
- case QS60StyleEnums::SP_QgnNoteErased:
- fallbackIndex = EMbmAvkonQgn_note_erased;
- break;
- case QS60StyleEnums::SP_QgnNoteError:
- fallbackIndex = EMbmAvkonQgn_note_error;
- break;
- case QS60StyleEnums::SP_QgnNoteInfo:
- fallbackIndex = EMbmAvkonQgn_note_info;
- break;
- case QS60StyleEnums::SP_QgnNoteOk:
- fallbackIndex = EMbmAvkonQgn_note_ok;
- break;
- case QS60StyleEnums::SP_QgnNoteQuery:
- fallbackIndex = EMbmAvkonQgn_note_query;
- break;
- case QS60StyleEnums::SP_QgnNoteWarning:
- fallbackIndex = EMbmAvkonQgn_note_warning;
- break;
- case QS60StyleEnums::SP_QgnPropFileSmall:
- fallbackIndex = EMbmAvkonQgn_prop_file_small;
- break;
- case QS60StyleEnums::SP_QgnPropFolderCurrent:
- fallbackIndex = EMbmAvkonQgn_prop_folder_current;
- break;
- case QS60StyleEnums::SP_QgnPropFolderSmall:
- fallbackIndex = EMbmAvkonQgn_prop_folder_small;
- break;
- case QS60StyleEnums::SP_QgnPropFolderSmallNew:
- fallbackIndex = EMbmAvkonQgn_prop_folder_small_new;
- break;
- case QS60StyleEnums::SP_QgnPropPhoneMemcLarge:
- fallbackIndex = EMbmAvkonQgn_prop_phone_memc_large;
- break;
- default:
- fallbackIndex = -1;
- break;
- }
-}
-
-QPixmap QS60StyleModeSpecifics::colorSkinnedGraphicsLX(
- const QS60StyleEnums::SkinParts &stylepart,
- const QSize &size, QPainter *painter, QS60StylePrivate::SkinElementFlags flags)
-{
- // this function can throw both exceptions and leaves. There are no cleanup dependencies between Qt and Symbian parts.
- const int stylepartIndex = (int)stylepart;
- const TAknsItemID skinId = m_partMap[stylepartIndex].skinID;
-
- TInt fallbackGraphicID = -1;
- HBufC* iconFile = HBufC::NewLC( KMaxFileName );
- fallbackInfo(stylepart, fallbackGraphicID);
-
- TAknsItemID colorGroup = KAknsIIDQsnIconColors;
- TRgb defaultColor = KRgbBlack;
- int colorIndex = -1; //set a bogus value to color index to ensure that painter color is used
- //to color the icon
- if (painter) {
- QRgb widgetColor = painter->pen().color().rgb();
- defaultColor = TRgb(qRed(widgetColor), qGreen(widgetColor), qBlue(widgetColor));
- }
-
- const bool rotatedBy90or270 =
- (flags & (QS60StylePrivate::SF_PointEast | QS60StylePrivate::SF_PointWest));
- const TSize targetSize =
- rotatedBy90or270?TSize(size.height(), size.width()):TSize(size.width(), size.height());
- CFbsBitmap *icon = 0;
- CFbsBitmap *iconMask = 0;
- const TInt fallbackGraphicsMaskID =
- fallbackGraphicID == KErrNotFound?KErrNotFound:fallbackGraphicID+1; //masks are auto-generated as next in mif files
- MAknsSkinInstance* skinInstance = AknsUtils::SkinInstance();
- AknsUtils::CreateColorIconLC(
- skinInstance,
- skinId,
- colorGroup,
- colorIndex,
- icon,
- iconMask,
- AknIconUtils::AvkonIconFileName(),
- fallbackGraphicID,
- fallbackGraphicsMaskID,
- defaultColor);
-
- QPixmap result = fromFbsBitmap(icon, iconMask, flags, targetSize);
- CleanupStack::PopAndDestroy(3); //icon, iconMask, iconFile
- return result;
-}
-
-QColor QS60StyleModeSpecifics::colorValue(const TAknsItemID &colorGroup, int colorIndex)
-{
- TRgb skinnedColor;
- MAknsSkinInstance* skin = AknsUtils::SkinInstance();
- AknsUtils::GetCachedColor(skin, skinnedColor, colorGroup, colorIndex);
- return QColor(skinnedColor.Red(),skinnedColor.Green(),skinnedColor.Blue());
-}
-
-struct QAutoFbsBitmapHeapLock
-{
- QAutoFbsBitmapHeapLock(CFbsBitmap* aBmp) : mBmp(aBmp) { mBmp->LockHeap(); }
- ~QAutoFbsBitmapHeapLock() { mBmp->UnlockHeap(); }
- CFbsBitmap* mBmp;
-};
-
-QPixmap QS60StyleModeSpecifics::fromFbsBitmap(CFbsBitmap *icon, CFbsBitmap *mask, QS60StylePrivate::SkinElementFlags flags, const TSize &targetSize)
-{
- Q_ASSERT(icon);
-
- AknIconUtils::DisableCompression(icon);
- TInt error = AknIconUtils::SetSize(icon, targetSize, EAspectRatioNotPreserved);
-
- if (mask && !error) {
- AknIconUtils::DisableCompression(mask);
- error = AknIconUtils::SetSize(mask, targetSize, EAspectRatioNotPreserved);
- }
- if (error)
- return QPixmap();
-
- QPixmap pixmap;
- QScopedPointer<QPixmapData> pd(QPixmapData::create(0, 0, QPixmapData::PixmapType));
- if (mask) {
- // Try the efficient path with less copying and conversion.
- QVolatileImage img(icon, mask);
- pd->fromNativeType(&img, QPixmapData::VolatileImage);
- if (!pd->isNull())
- pixmap = QPixmap(pd.take());
- }
- if (pixmap.isNull()) {
- // Potentially more expensive path.
- pd->fromNativeType(icon, QPixmapData::FbsBitmap);
- pixmap = QPixmap(pd.take());
- if (mask) {
- pixmap.setAlphaChannel(QPixmap::fromSymbianCFbsBitmap(mask));
- }
- }
-
- if ((flags & QS60StylePrivate::SF_PointEast) ||
- (flags & QS60StylePrivate::SF_PointSouth) ||
- (flags & QS60StylePrivate::SF_PointWest)) {
- QImage iconImage = pixmap.toImage();
- QTransform imageTransform;
- if (flags & QS60StylePrivate::SF_PointEast) {
- imageTransform.rotate(90);
- } else if (flags & QS60StylePrivate::SF_PointSouth) {
- imageTransform.rotate(180);
- iconImage = iconImage.transformed(imageTransform);
- } else if (flags & QS60StylePrivate::SF_PointWest) {
- imageTransform.rotate(270);
- }
- if (imageTransform.isRotating())
- iconImage = iconImage.transformed(imageTransform);
-
- pixmap = QPixmap::fromImage(iconImage);
- }
- if ((flags & QS60StylePrivate::SF_Mirrored_X_Axis) ||
- (flags & QS60StylePrivate::SF_Mirrored_Y_Axis)) {
- QImage iconImage = pixmap.toImage().mirrored(
- flags & QS60StylePrivate::SF_Mirrored_X_Axis,
- flags & QS60StylePrivate::SF_Mirrored_Y_Axis);
- pixmap = QPixmap::fromImage(iconImage);
- }
-
- return pixmap;
-}
-
-bool QS60StylePrivate::isTouchSupported()
-{
- return bool(AknLayoutUtils::PenEnabled());
-}
-
-bool QS60StylePrivate::isToolBarBackground()
-{
- return (QSysInfo::s60Version() == QSysInfo::SV_S60_3_1 || QSysInfo::s60Version() == QSysInfo::SV_S60_3_2);
-}
-
-bool QS60StylePrivate::hasSliderGrooveGraphic()
-{
- return QSysInfo::s60Version() != QSysInfo::SV_S60_3_1;
-}
-
-bool QS60StylePrivate::isSingleClickUi()
-{
- return (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0);
-}
-
-void QS60StylePrivate::deleteStoredSettings()
-{
- QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
- settings.beginGroup(QLatin1String("QS60Style"));
- settings.remove(QString());
- settings.endGroup();
-}
-
-// Since S60Style has 'button' as a graphic, we don't have any native color which to use
-// for QPalette::Button. Therefore S60Style needs to guesstimate palette color by calculating
-// average rgb values for button pixels.
-// Returns Qt::black if there is an issue with the graphics (image is NULL, or no constBits() found).
-QColor QS60StylePrivate::colorFromFrameGraphics(SkinFrameElements frame) const
-{
-#ifndef QT_NO_SETTINGS
- TInt themeID = 0;
- //First we need to fetch active theme ID. We need to store the themeID at the same time
- //as color, so that we can later check if the stored color is still from the same theme.
- //Native side stores active theme UID/Timestamp into central repository.
- int error = 0;
- QT_TRAP_THROWING(
- CRepository *themeRepository = CRepository::NewLC(personalisationUID);
- if (themeRepository) {
- TBuf<32> value; //themeID is currently max of 8 + 1 + 8 characters, but lets have some extra space
- const TUint32 key = 0x00000002; //active theme key in the repository
- error = themeRepository->Get(key, value);
- if (error == KErrNone) {
- TLex lex(value);
- TPtrC numberToken(lex.NextToken());
- if (numberToken.Length())
- error = TLex(numberToken).Val(themeID);
- else
- error = KErrArgument;
- }
- }
- CleanupStack::PopAndDestroy(themeRepository);
- );
-
- QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
- settings.beginGroup(QLatin1String("QS60Style"));
- if (themeID != 0) {
- QVariant buttonColor = settings.value(QLatin1String("ButtonColor"));
- if (!buttonColor.isNull()) {
- //there is a stored color value, lets see if the theme ID matches
- if (error == KErrNone) {
- QVariant themeUID = settings.value(QLatin1String("ThemeUID"));
- if (!themeUID.isNull() && themeUID.toInt() == themeID) {
- QColor storedColor(buttonColor.value<QColor>());
- if (storedColor.isValid())
- return storedColor;
- }
- }
- settings.remove(QString()); //if color was invalid, or theme has been changed, just delete all stored settings
- }
- }
-#endif
-
- QColor color = calculatedColor(frame);
-
-#ifndef QT_NO_SETTINGS
- settings.setValue(QLatin1String("ThemeUID"), QVariant(themeID));
- if (frame == SF_ButtonNormal) //other colors are not currently calculated from graphics
- settings.setValue(QLatin1String("ButtonColor"), QVariant(color));
- settings.endGroup();
-#endif
-
- return color;
-}
-
-QPoint qt_s60_fill_background_offset(const QWidget *targetWidget)
-{
- CCoeControl *control = targetWidget->effectiveWinId();
- TPoint pos(0,0);
- if (control)
- pos = control->PositionRelativeToScreen();
- return QPoint(pos.iX, pos.iY);
-}
-
-QPixmap QS60StyleModeSpecifics::createSkinnedGraphicsLX(
- QS60StyleEnums::SkinParts part, const QSize &size,
- QS60StylePrivate::SkinElementFlags flags)
-{
- // this function can throw both exceptions and leaves. There are no cleanup dependencies between Qt and Symbian parts.
- if (!size.isValid())
- return QPixmap();
-
- // Check release support and change part, if necessary.
- const TAknsItemID skinId = partSpecificThemeId((int)part);
- const int stylepartIndex = (int)part;
- const TDrawType drawType = m_partMap[stylepartIndex].drawType;
- Q_ASSERT(drawType != ENoDraw);
- const bool rotatedBy90or270 =
- (flags & (QS60StylePrivate::SF_PointEast | QS60StylePrivate::SF_PointWest));
- const TSize targetSize =
- rotatedBy90or270 ? TSize(size.height(), size.width()) : qt_QSize2TSize(size);
-
- MAknsSkinInstance* skinInstance = AknsUtils::SkinInstance();
- static const TDisplayMode displayMode = S60->supportsPremultipliedAlpha ? Q_SYMBIAN_ECOLOR16MAP : EColor16MA;
- static const TInt drawParam = S60->supportsPremultipliedAlpha ? KAknsDrawParamDefault : KAknsDrawParamRGBOnly;
-
- QPixmap result;
-
- switch (drawType) {
- case EDrawGulIcon: {
- CGulIcon* icon = AknsUtils::CreateGulIconL( AknsUtils::SkinInstance(), skinId, EFalse );
- if (icon)
- result = fromFbsBitmap(icon->Bitmap(), icon->Mask(), flags, targetSize);
- delete icon;
- break;
- }
- case EDrawIcon: {
- TInt fallbackGraphicID = -1;
- fallbackInfo(part, fallbackGraphicID);
-
- CFbsBitmap *icon = 0;
- CFbsBitmap *iconMask = 0;
- const TInt fallbackGraphicsMaskID =
- fallbackGraphicID == KErrNotFound?KErrNotFound:fallbackGraphicID+1; //masks are auto-generated as next in mif files
-
- AknsUtils::CreateIconL(
- skinInstance,
- skinId,
- icon,
- iconMask,
- AknIconUtils::AvkonIconFileName(),
- fallbackGraphicID ,
- fallbackGraphicsMaskID);
-
- result = fromFbsBitmap(icon, iconMask, flags, targetSize);
- delete icon;
- delete iconMask;
- break;
- }
- case EDrawBackground: {
- // QS60WindowSurface::unlockBitmapHeap();
- CFbsBitmap *background = new (ELeave) CFbsBitmap(); //offscreen
- CleanupStack::PushL(background);
- User::LeaveIfError(background->Create(targetSize, displayMode));
-
- CFbsBitmapDevice *dev = CFbsBitmapDevice::NewL(background);
- CleanupStack::PushL(dev);
- CFbsBitGc *gc = NULL;
- User::LeaveIfError(dev->CreateContext(gc));
- CleanupStack::PushL(gc);
-
- CAknsBasicBackgroundControlContext *bgContext = CAknsBasicBackgroundControlContext::NewL(
- skinId,
- targetSize,
- EFalse);
- CleanupStack::PushL(bgContext);
-
- const TBool drawn = AknsDrawUtils::DrawBackground(
- skinInstance,
- bgContext,
- NULL,
- *gc,
- TPoint(),
- targetSize,
- drawParam);
-
- if (drawn)
- result = fromFbsBitmap(background, NULL, flags, targetSize);
- // if drawing fails in skin server, just ignore the background (probably OOM case)
-
- CleanupStack::PopAndDestroy(4, background); //background, dev, gc, bgContext
- // QS60WindowSurface::lockBitmapHeap();
- break;
- }
- case EDrawAnimation: {
- CFbsBitmap* animationFrame;
- CFbsBitmap* frameMask;
- CAknBitmapAnimation* aknAnimation = 0;
- TBool constructedFromTheme = ETrue;
-
- QS60StyleAnimation* animation = QS60StylePrivate::animationDefinition(part); //ownership is not passed
- if (animation) {
- if (!animation->animationObject() && !animation->isResourceBased()) {// no pre-made item exists, create new animation
- CAknBitmapAnimation* newAnimation = CAknBitmapAnimation::NewL();
- CleanupStack::PushL(newAnimation);
- if (newAnimation)
- constructedFromTheme = newAnimation->ConstructFromSkinL(skinId);
- if (constructedFromTheme && newAnimation->BitmapAnimData()->FrameArray().Count() > 0) {
- animation->setResourceBased(false);
- animation->setAnimationObject(newAnimation); //animation takes ownership
- }
- CleanupStack::Pop(newAnimation);
- }
- //fill-in stored information
- aknAnimation = animation->animationObject();
- constructedFromTheme = !animation->isResourceBased();
- }
-
- const int currentFrame = QS60StylePrivate::currentAnimationFrame(part);
- if (constructedFromTheme && aknAnimation && aknAnimation->BitmapAnimData()->FrameArray().Count() > 0) {
- //Animation was created successfully and contains frames, just fetch current frame
- if(currentFrame >= aknAnimation->BitmapAnimData()->FrameArray().Count())
- User::Leave(KErrOverflow);
- const CBitmapFrameData* frameData = aknAnimation->BitmapAnimData()->FrameArray().At(currentFrame);
- if (frameData) {
- animationFrame = frameData->Bitmap();
- frameMask = frameData->Mask();
- }
- } else {
- //Theme does not contain animation theming, create frames from resource file
- TInt fallbackGraphicID = -1;
- fallbackInfo(part, fallbackGraphicID);
- fallbackGraphicID = fallbackGraphicID + (currentFrame * 2); //skip masks
- TInt fallbackGraphicsMaskID =
- (fallbackGraphicID == KErrNotFound) ? KErrNotFound : fallbackGraphicID + 1; //masks are auto-generated as next in mif files
- if (fallbackGraphicsMaskID != KErrNotFound)
- fallbackGraphicsMaskID = fallbackGraphicsMaskID + (currentFrame * 2); //skip actual graphics
-
- //Then draw animation frame
- AknsUtils::CreateIconL(
- skinInstance,
- KAknsIIDDefault, //animation is not themed, lets force fallback graphics
- animationFrame,
- frameMask,
- AknIconUtils::AvkonIconFileName(),
- fallbackGraphicID ,
- fallbackGraphicsMaskID);
- }
- result = fromFbsBitmap(animationFrame, frameMask, flags, targetSize);
- if (!constructedFromTheme) {
- delete animationFrame;
- animationFrame = 0;
- delete frameMask;
- frameMask = 0;
- }
- break;
- }
- }
- if (!result)
- result = QPixmap();
-
- return result;
-}
-
-QPixmap QS60StyleModeSpecifics::createSkinnedGraphicsLX(QS60StylePrivate::SkinFrameElements frameElement,
- const QSize &size, QS60StylePrivate::SkinElementFlags flags)
-{
- // this function can throw both exceptions and leaves. There are no cleanup dependencies between Qt and Symbian parts.
- if (!size.isValid())
- return QPixmap();
-
- const bool rotatedBy90or270 =
- (flags & (QS60StylePrivate::SF_PointEast | QS60StylePrivate::SF_PointWest));
- const TSize targetSize =
- rotatedBy90or270 ? TSize(size.height(), size.width()) : qt_QSize2TSize(size);
-
- MAknsSkinInstance* skinInstance = AknsUtils::SkinInstance();
- QPixmap result;
-
- static const TDisplayMode displayMode = S60->supportsPremultipliedAlpha ? Q_SYMBIAN_ECOLOR16MAP : EColor16MA;
- static const TInt drawParam = S60->supportsPremultipliedAlpha ? KAknsDrawParamDefault : KAknsDrawParamNoClearUnderImage|KAknsDrawParamRGBOnly;
-
- CFbsBitmap *frame = new (ELeave) CFbsBitmap(); //offscreen
- CleanupStack::PushL(frame);
- User::LeaveIfError(frame->Create(targetSize, displayMode));
-
- CFbsBitmapDevice* bitmapDev = CFbsBitmapDevice::NewL(frame);
- CleanupStack::PushL(bitmapDev);
- CFbsBitGc* bitmapGc = NULL;
- User::LeaveIfError(bitmapDev->CreateContext(bitmapGc));
- CleanupStack::PushL(bitmapGc);
-
- frame->LockHeap();
- memset(frame->DataAddress(), 0, frame->SizeInPixels().iWidth * frame->SizeInPixels().iHeight * 4); // 4: argb bytes
- frame->UnlockHeap();
-
- const TRect outerRect(TPoint(0, 0), targetSize);
- const TRect innerRect = innerRectFromElement(frameElement, outerRect);
-
- TAknsItemID frameSkinID, centerSkinID;
- frameSkinID = centerSkinID = partSpecificThemeId(QS60StylePrivate::m_frameElementsData[frameElement].center);
- frameIdAndCenterId(frameElement, frameSkinID, centerSkinID);
-
- TBool drawn = AknsDrawUtils::DrawFrame(
- skinInstance,
- *bitmapGc,
- outerRect,
- innerRect,
- frameSkinID,
- centerSkinID,
- drawParam );
-
- if (S60->supportsPremultipliedAlpha) {
- if (drawn) {
- result = fromFbsBitmap(frame, NULL, flags, targetSize);
- } else {
- // Drawing might fail due to OOM (we can do nothing about that),
- // or due to skin item not being available.
- // If the latter occurs, lets try switch to non-release specific items (if available)
- // and re-try the drawing.
- frameSkinID = centerSkinID = m_partMap[(int)QS60StylePrivate::m_frameElementsData[frameElement].center].skinID;
- frameIdAndCenterId(frameElement, frameSkinID, centerSkinID);
- drawn = AknsDrawUtils::DrawFrame( skinInstance,
- *bitmapGc, outerRect, innerRect,
- frameSkinID, centerSkinID,
- drawParam );
- // in case drawing fails, even after using default graphics, ignore the error
- if (drawn)
- result = fromFbsBitmap(frame, NULL, flags, targetSize);
- }
- } else {
- TDisplayMode maskDepth = EGray256;
- // Query the skin item for possible frame graphics mask details.
- if (skinInstance) {
- CAknsMaskedBitmapItemData* skinMaskedBmp = static_cast<CAknsMaskedBitmapItemData*>(
- skinInstance->GetCachedItemData(frameSkinID,EAknsITMaskedBitmap));
- if (skinMaskedBmp && skinMaskedBmp->Mask())
- maskDepth = skinMaskedBmp->Mask()->DisplayMode();
- }
- if (maskDepth != ENone) {
- CFbsBitmap *frameMask = new (ELeave) CFbsBitmap(); //offscreen
- CleanupStack::PushL(frameMask);
- User::LeaveIfError(frameMask->Create(targetSize, maskDepth));
-
- CFbsBitmapDevice* maskBitmapDevice = CFbsBitmapDevice::NewL(frameMask);
- CleanupStack::PushL(maskBitmapDevice);
- CFbsBitGc* maskBitGc = NULL;
- User::LeaveIfError(maskBitmapDevice->CreateContext(maskBitGc));
- CleanupStack::PushL(maskBitGc);
-
- if (drawn) {
- //ensure that the mask is really transparent
- maskBitGc->Activate( maskBitmapDevice );
- maskBitGc->SetPenStyle(CGraphicsContext::ENullPen);
- maskBitGc->SetBrushStyle(CGraphicsContext::ESolidBrush);
- maskBitGc->SetBrushColor(KRgbWhite);
- maskBitGc->Clear();
- maskBitGc->SetBrushStyle(CGraphicsContext::ENullBrush);
-
- drawn = AknsDrawUtils::DrawFrame(skinInstance,
- *maskBitGc, outerRect, innerRect,
- frameSkinID, centerSkinID,
- KAknsSDMAlphaOnly |KAknsDrawParamNoClearUnderImage);
- if (drawn)
- result = fromFbsBitmap(frame, frameMask, flags, targetSize);
- }
- CleanupStack::PopAndDestroy(3, frameMask);
- }
- }
- CleanupStack::PopAndDestroy(3, frame); //frame, bitmapDev, bitmapGc
- return result;
-}
-
-void QS60StyleModeSpecifics::frameIdAndCenterId(QS60StylePrivate::SkinFrameElements frameElement, TAknsItemID &frameId, TAknsItemID &centerId)
-{
-// There are some major mix-ups in skin declarations for some frames.
-// First, the frames are not declared in sequence.
-// Second, the parts use different major than the frame-master.
-
- switch(frameElement) {
- case QS60StylePrivate::SF_ToolTip:
- if (QSysInfo::s60Version() != QSysInfo::SV_S60_3_1) {
- centerId.Set(EAknsMajorGeneric, 0x19c2);
- frameId.Set(EAknsMajorSkin, 0x5300);
- } else {
- centerId.Set(KAknsIIDQsnFrPopupCenter);
- frameId.iMinor = centerId.iMinor - 9;
- }
- break;
- case QS60StylePrivate::SF_ToolBar:
- if (QSysInfo::s60Version() == QSysInfo::SV_S60_3_1 ||
- QSysInfo::s60Version() == QSysInfo::SV_S60_3_2) {
- centerId.Set(KAknsIIDQsnFrPopupCenterSubmenu);
- frameId.Set(KAknsIIDQsnFrPopupSub);
- }
- break;
- case QS60StylePrivate::SF_PopupBackground:
- centerId.Set(KAknsIIDQsnFrPopupCenterSubmenu);
- frameId.Set(KAknsIIDQsnFrPopupSub);
- break;
- case QS60StylePrivate::SF_PanelBackground:
- // remove center piece for panel graphics, so that only border is drawn
- centerId.Set(KAknsIIDNone);
- frameId.Set(KAknsIIDQsnFrSetOpt);
- break;
- default:
- // center should be correct here
- frameId.iMinor = centerId.iMinor - 9;
- break;
- }
-}
-
-TRect QS60StyleModeSpecifics::innerRectFromElement(QS60StylePrivate::SkinFrameElements frameElement, const TRect &outerRect)
-{
- TInt widthShrink = QS60StylePrivate::pixelMetric(PM_FrameCornerWidth);
- TInt heightShrink = QS60StylePrivate::pixelMetric(PM_FrameCornerHeight);
- switch(frameElement) {
- case QS60StylePrivate::SF_PanelBackground:
- // panel should have slightly slimmer border to enable thin line of background graphics between closest component
- widthShrink = widthShrink - 2;
- heightShrink = heightShrink - 2;
- break;
- case QS60StylePrivate::SF_ToolTip:
- widthShrink = widthShrink >> 1;
- heightShrink = heightShrink >> 1;
- break;
- case QS60StylePrivate::SF_ListHighlight:
- //In Sym^3 devices highlights are less blocky
- if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0) {
- widthShrink += 2;
- heightShrink += 2;
- } else {
- widthShrink -= 2;
- heightShrink -= 2;
- }
- break;
- case QS60StylePrivate::SF_PopupBackground:
- widthShrink = widthShrink + 5;
- heightShrink = heightShrink + 5;
- break;
- default:
- break;
- }
- TRect innerRect(outerRect);
- innerRect.Shrink(widthShrink, heightShrink);
- return innerRect;
-}
-
-bool QS60StyleModeSpecifics::checkSupport(const int supportedRelease)
-{
- const QSysInfo::S60Version currentRelease = QSysInfo::s60Version();
- return ( (currentRelease == QSysInfo::SV_S60_3_1 && supportedRelease & ES60_3_1) ||
- (currentRelease == QSysInfo::SV_S60_3_2 && supportedRelease & ES60_3_2) ||
- (currentRelease == QSysInfo::SV_S60_5_0 && supportedRelease & ES60_5_0) ||
- (currentRelease == QSysInfo::SV_S60_5_1 && supportedRelease & ES60_5_1) ||
- (currentRelease == QSysInfo::SV_S60_5_2 && supportedRelease & ES60_5_2) ||
- (currentRelease == QSysInfo::SV_S60_5_3 && supportedRelease & ES60_5_3) );
-}
-
-TAknsItemID QS60StyleModeSpecifics::partSpecificThemeId(int part)
-{
- TAknsItemID newSkinId;
- if (!checkSupport(m_partMap[(int)part].supportInfo))
- newSkinId.Set(m_partMap[(int)part].newMajorSkinId, m_partMap[(int)part].newMinorSkinId);
- else
- newSkinId.Set(m_partMap[(int)part].skinID);
- return newSkinId;
-}
-
-QFont QS60StylePrivate::s60Font_specific(
- QS60StyleEnums::FontCategories fontCategory,
- int pointSize, bool resolveFontSize)
-{
- Q_UNUSED(resolveFontSize);
-
- TAknFontCategory aknFontCategory = EAknFontCategoryUndefined;
- switch (fontCategory) {
- case QS60StyleEnums::FC_Primary:
- aknFontCategory = EAknFontCategoryPrimary;
- break;
- case QS60StyleEnums::FC_Secondary:
- aknFontCategory = EAknFontCategorySecondary;
- break;
- case QS60StyleEnums::FC_Title:
- aknFontCategory = EAknFontCategoryTitle;
- break;
- case QS60StyleEnums::FC_PrimarySmall:
- aknFontCategory = EAknFontCategoryPrimarySmall;
- break;
- case QS60StyleEnums::FC_Digital:
- aknFontCategory = EAknFontCategoryDigital;
- break;
- case QS60StyleEnums::FC_Undefined:
- default:
- break;
- }
-
- // Create AVKON font according the given parameters
- CWsScreenDevice* dev = CCoeEnv::Static()->ScreenDevice();
- TAknFontSpecification spec(aknFontCategory, TFontSpec(), NULL);
- if (pointSize > 0) {
- const TInt pixelSize = dev->VerticalTwipsToPixels(pointSize * KTwipsPerPoint);
- spec.SetTextPaneHeight(pixelSize + 4); // TODO: Is 4 a reasonable top+bottom margin?
- }
-
- QFont result;
- TRAPD( error, QT_TRYCATCH_LEAVING({
- const CAknLayoutFont* aknFont =
- AknFontAccess::CreateLayoutFontFromSpecificationL(*dev, spec);
-
- result = qt_TFontSpec2QFontL(aknFont->DoFontSpecInTwips());
- if (result.pointSize() != pointSize)
- result.setPointSize(pointSize); // Correct the font size returned by CreateLayoutFontFromSpecificationL()
-
- delete aknFont;
- }));
- if (error) result = QFont();
- return result;
-}
-
-void QS60StylePrivate::setActiveLayout()
-{
- const QSize activeScreenSize(screenSize());
- int activeLayoutIndex = -1;
- const short screenHeight = (short)activeScreenSize.height();
- const short screenWidth = (short)activeScreenSize.width();
- for (int i=0; i<m_numberOfLayouts; i++) {
- if (screenHeight==m_layoutHeaders[i].height &&
- screenWidth==m_layoutHeaders[i].width) {
- activeLayoutIndex = i;
- break;
- }
- }
-
- //not found, lets try with either of dimensions
- if (activeLayoutIndex==-1){
- const QSysInfo::S60Version currentRelease = QSysInfo::s60Version();
- const bool landscape = screenHeight < screenWidth;
-
- activeLayoutIndex = (currentRelease == QSysInfo::SV_S60_3_1 || currentRelease == QSysInfo::SV_S60_3_2) ? 0 : 2;
- activeLayoutIndex += (!landscape) ? 1 : 0;
- }
-
- setCurrentLayout(activeLayoutIndex);
-}
-
-Q_GLOBAL_STATIC(QList<QS60StyleAnimation *>, m_animations)
-
-QS60StylePrivate::QS60StylePrivate()
-{
- //Animation defaults need to be created when style is instantiated
- QS60StyleAnimation* progressBarAnimation = new QS60StyleAnimation(QS60StyleEnums::SP_QgnGrafBarWaitAnim, 7, 100);
- m_animations()->append(progressBarAnimation);
- // No need to set active layout, if dynamic metrics API is available
- setActiveLayout();
-}
-
-void QS60StylePrivate::removeAnimations()
-{
- //currently only one animation in the list.
- m_animations()->removeFirst();
-}
-
-QColor QS60StylePrivate::s60Color(QS60StyleEnums::ColorLists list,
- int index, const QStyleOption *option)
-{
- static const TAknsItemID *idMap[] = {
- &KAknsIIDQsnHighlightColors,
- &KAknsIIDQsnIconColors,
- &KAknsIIDQsnLineColors,
- &KAknsIIDQsnOtherColors,
- &KAknsIIDQsnParentColors,
- &KAknsIIDQsnTextColors
- };
- Q_ASSERT((int)list < (int)sizeof(idMap)/sizeof(idMap[0]));
- const QColor color = QS60StyleModeSpecifics::colorValue(*idMap[(int) list], index - 1);
- return option ? QS60StylePrivate::stateColor(color, option) : color;
-}
-
-// In some cases, the AVKON UI themegraphic is already in 'disabled state'.
-// If so, return true for these parts.
-bool QS60StyleModeSpecifics::disabledPartGraphic(QS60StyleEnums::SkinParts &part)
-{
- bool disabledGraphic = false;
- switch(part){
- // inactive button graphics are available from 5.0 onwards
- case QS60StyleEnums::SP_QsnFrButtonCornerTlInactive:
- case QS60StyleEnums::SP_QsnFrButtonCornerTrInactive:
- case QS60StyleEnums::SP_QsnFrButtonCornerBlInactive:
- case QS60StyleEnums::SP_QsnFrButtonCornerBrInactive:
- case QS60StyleEnums::SP_QsnFrButtonSideTInactive:
- case QS60StyleEnums::SP_QsnFrButtonSideBInactive:
- case QS60StyleEnums::SP_QsnFrButtonSideLInactive:
- case QS60StyleEnums::SP_QsnFrButtonSideRInactive:
- case QS60StyleEnums::SP_QsnFrButtonCenterInactive:
- if (!(QSysInfo::s60Version()==QSysInfo::SV_S60_3_1 ||
- QSysInfo::s60Version()==QSysInfo::SV_S60_3_2))
- disabledGraphic = true;
- break;
- default:
- break;
- }
- return disabledGraphic;
-}
-
-// In some cases, the AVKON UI themegraphic is already in 'disabled state'.
-// If so, return true for these frames.
-bool QS60StyleModeSpecifics::disabledFrameGraphic(QS60StylePrivate::SkinFrameElements &frame)
-{
- bool disabledGraphic = false;
- switch(frame){
- // inactive button graphics are available from 5.0 onwards
- case QS60StylePrivate::SF_ButtonInactive:
- if (!(QSysInfo::s60Version()==QSysInfo::SV_S60_3_1 ||
- QSysInfo::s60Version()==QSysInfo::SV_S60_3_2))
- disabledGraphic = true;
- break;
- default:
- break;
- }
- return disabledGraphic;
-}
-
-QPixmap QS60StyleModeSpecifics::generateMissingThemeGraphic(QS60StyleEnums::SkinParts &part,
- const QSize &size, QS60StylePrivate::SkinElementFlags flags)
-{
- if (!QS60StylePrivate::isTouchSupported())
- return QPixmap();
-
- QS60StyleEnums::SkinParts updatedPart = part;
- switch(part){
- // AVKON UI has a abnormal handling for scrollbar graphics. It is possible that the root
- // skin does not contain mandatory graphics for scrollbar pressed states. Therefore, AVKON UI
- // creates dynamically these graphics by modifying the normal state scrollbar graphics slightly.
- // S60Style needs to work similarly. Therefore if skingraphics call provides to be a miss
- // (i.e. result is not valid), style needs to draw normal graphics instead and apply some
- // modifications (similar to generatedIconPixmap()) to the result.
- case QS60StyleEnums::SP_QsnCpScrollHandleBottomPressed:
- updatedPart = QS60StyleEnums::SP_QsnCpScrollHandleBottom;
- break;
- case QS60StyleEnums::SP_QsnCpScrollHandleMiddlePressed:
- updatedPart = QS60StyleEnums::SP_QsnCpScrollHandleMiddle;
- break;
- case QS60StyleEnums::SP_QsnCpScrollHandleTopPressed:
- updatedPart = QS60StyleEnums::SP_QsnCpScrollHandleTop;
- break;
- default:
- break;
- }
- if (part==updatedPart) {
- return QPixmap();
- } else {
- QPixmap result = skinnedGraphics(updatedPart, size, flags);
- QStyleOption opt;
- QPalette *themePalette = QS60StylePrivate::themePalette();
- if (themePalette)
- opt.palette = *themePalette;
-
- // For now, always generate new icon based on "selected". In the future possibly, expand
- // this to consist other possibilities as well.
- result = QApplication::style()->generatedIconPixmap(QIcon::Selected, result, &opt);
- return result;
- }
-}
-
-QPixmap QS60StylePrivate::part(QS60StyleEnums::SkinParts part,
- const QSize &size, QPainter *painter, SkinElementFlags flags)
-{
- QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock);
-
- QPixmap result = (flags & SF_ColorSkinned)?
- QS60StyleModeSpecifics::colorSkinnedGraphics(part, size, painter, flags)
- : QS60StyleModeSpecifics::skinnedGraphics(part, size, flags);
-
- lock.relock();
-
- if (flags & SF_StateDisabled && !QS60StyleModeSpecifics::disabledPartGraphic(part)) {
- QStyleOption opt;
- QPalette *themePalette = QS60StylePrivate::themePalette();
- if (themePalette)
- opt.palette = *themePalette;
- result = QApplication::style()->generatedIconPixmap(QIcon::Disabled, result, &opt);
- }
-
- if (!result)
- result = QS60StyleModeSpecifics::generateMissingThemeGraphic(part, size, flags);
-
- return result;
-}
-
-QPixmap QS60StylePrivate::frame(SkinFrameElements frame, const QSize &size, SkinElementFlags flags)
-{
- QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock);
- QPixmap result = QS60StyleModeSpecifics::skinnedGraphics(frame, size, flags);
- lock.relock();
-
- if (flags & SF_StateDisabled && !QS60StyleModeSpecifics::disabledFrameGraphic(frame)) {
- QStyleOption opt;
- QPalette *themePalette = QS60StylePrivate::themePalette();
- if (themePalette)
- opt.palette = *themePalette;
- result = QApplication::style()->generatedIconPixmap(QIcon::Disabled, result, &opt);
- }
- return result;
-}
-
-QPixmap QS60StylePrivate::backgroundTexture(bool skipCreation)
-{
- bool createNewBackground = false;
- TRect applicationRect = (static_cast<CEikAppUi*>(S60->appUi())->ApplicationRect());
- if (!m_background) {
- createNewBackground = true;
- } else {
- //if background brush does not match screensize, re-create it
- if (m_background->width() != applicationRect.Width() ||
- m_background->height() != applicationRect.Height()) {
- delete m_background;
- m_background = 0;
- createNewBackground = true;
- }
- }
-
- if (createNewBackground && !skipCreation) {
- QPixmap background = part(QS60StyleEnums::SP_QsnBgScreen,
- QSize(applicationRect.Width(), applicationRect.Height()), 0, SkinElementFlags());
- m_background = new QPixmap(background);
-
- // Notify all widgets that palette is updated with the actual background texture.
- QPalette pal = QApplication::palette();
- pal.setBrush(QPalette::Window, *m_background);
- QApplication::setPalette(pal);
- setThemePaletteHash(&pal);
- storeThemePalette(&pal);
- foreach (QWidget *widget, QApplication::allWidgets()){
- QEvent e(QEvent::PaletteChange);
- QApplication::sendEvent(widget, &e);
- setThemePalette(widget);
- widget->ensurePolished();
- }
- }
- if (!m_background)
- return QPixmap();
- return *m_background;
-}
-
-QSize QS60StylePrivate::screenSize()
-{
- return QSize(S60->screenWidthInPixels, S60->screenHeightInPixels);
-}
-
-QS60Style::QS60Style()
- : QCommonStyle(*new QS60StylePrivate)
-{
-}
-
-#ifdef Q_WS_S60
-void QS60StylePrivate::handleDynamicLayoutVariantSwitch()
-{
- clearCaches(QS60StylePrivate::CC_LayoutChange);
- setBackgroundTexture(qApp);
- setActiveLayout();
- foreach (QWidget *widget, QApplication::allWidgets())
- widget->ensurePolished();
-}
-
-void QS60StylePrivate::handleSkinChange()
-{
- clearCaches(QS60StylePrivate::CC_ThemeChange);
- setThemePalette(qApp);
- foreach (QWidget *topLevelWidget, QApplication::allWidgets()){
- QEvent e(QEvent::StyleChange);
- QApplication::sendEvent(topLevelWidget, &e);
- setThemePalette(topLevelWidget);
- topLevelWidget->ensurePolished();
- }
-#ifndef QT_NO_PROGRESSBAR
- //re-start animation timer
- stopAnimation(QS60StyleEnums::SP_QgnGrafBarWaitAnim); //todo: once we have more animations, we could say "stop all running ones"
- startAnimation(QS60StyleEnums::SP_QgnGrafBarWaitAnim); //and "re-start all previously running ones"
-#endif
-}
-
-int QS60StylePrivate::currentAnimationFrame(QS60StyleEnums::SkinParts part)
-{
- QS60StyleAnimation *animation = animationDefinition(part);
- // todo: looping could be done in QS60Style::timerEvent
- if (animation->frameCount() == animation->currentFrame())
- animation->setCurrentFrame(0);
- return animation->currentFrame();
-}
-
-QS60StyleAnimation* QS60StylePrivate::animationDefinition(QS60StyleEnums::SkinParts part)
-{
- int i = 0;
- const int animationsCount = m_animations()->isEmpty() ? 0 : m_animations()->count();
- for(; i < animationsCount; i++) {
- if (part == m_animations()->at(i)->animationId())
- break;
- }
- return m_animations()->at(i);
-}
-
-void QS60StylePrivate::startAnimation(QS60StyleEnums::SkinParts animationPart)
-{
- Q_Q(QS60Style);
-
- //Query animation data from theme and store values to local struct.
- QVariant themeAnimationDataVariant = QS60StyleModeSpecifics::themeDefinition(
- QS60StyleEnums::TD_AnimationData, animationPart);
- QList<QVariant> themeAnimationData = themeAnimationDataVariant.toList();
-
- QS60StyleAnimation *animation = QS60StylePrivate::animationDefinition(animationPart);
- if (animation) {
- if (themeAnimationData.at(QS60StyleEnums::AD_Interval).toInt() != 0)
- animation->setInterval(themeAnimationData.at(QS60StyleEnums::AD_Interval).toInt());
-
- if (themeAnimationData.at(QS60StyleEnums::AD_NumberOfFrames).toInt() != 0)
- animation->setFrameCount(themeAnimationData.at(QS60StyleEnums::AD_NumberOfFrames).toInt());
-
- //todo: playmode is ignored for now, since it seems to return invalid data on some themes
- //lets use the table values for play mode
-
- animation->setCurrentFrame(0); //always initialize
- const int timerId = q->startTimer(animation->interval());
- animation->setTimerId(timerId);
- }
-}
-
-void QS60StylePrivate::stopAnimation(QS60StyleEnums::SkinParts animationPart)
-{
- Q_Q(QS60Style);
-
- QS60StyleAnimation *animation = QS60StylePrivate::animationDefinition(animationPart);
- if (animation) {
- animation->setCurrentFrame(0);
- if (animation->timerId() != 0) {
- q->killTimer(animation->timerId());
- animation->setTimerId(0);
- }
- animation->resetToDefaults();
- }
-}
-
-QVariant QS60StyleModeSpecifics::themeDefinition(
- QS60StyleEnums::ThemeDefinitions definition, QS60StyleEnums::SkinParts part)
-{
- MAknsSkinInstance* skinInstance = AknsUtils::SkinInstance();
-
- Q_ASSERT(skinInstance);
-
- switch(definition) {
- //Animation definitions
- case QS60StyleEnums::TD_AnimationData:
- {
- CAknsBmpAnimItemData *animationData;
- TAknsItemID animationSkinId = partSpecificThemeId(part);
- QList<QVariant> list;
-
- TRAPD( error, QT_TRYCATCH_LEAVING(
- animationData = static_cast<CAknsBmpAnimItemData*>(skinInstance->CreateUncachedItemDataL(
- animationSkinId, EAknsITBmpAnim))));
- if (error)
- return list;
-
- if (animationData) {
- list.append((int)animationData->FrameInterval());
- list.append((int)animationData->NumberOfImages());
-
- QS60StyleEnums::AnimationMode playMode;
- switch(animationData->PlayMode()) {
- case CBitmapAnimClientData::EPlay:
- playMode = QS60StyleEnums::AM_PlayOnce;
- break;
- case CBitmapAnimClientData::ECycle:
- playMode = QS60StyleEnums::AM_Looping;
- break;
- case CBitmapAnimClientData::EBounce:
- playMode = QS60StyleEnums::AM_Bounce;
- break;
- default:
- break;
- }
- list.append(QVariant((int)playMode));
- delete animationData;
- } else {
- list.append(0);
- list.append(0);
- }
- return list;
- }
- break;
- default:
- break;
- }
- return QVariant();
-}
-
-#endif // Q_WS_S60
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_STYLE_S60 || QT_PLUGIN
diff --git a/src/gui/styles/qstyle.cpp b/src/gui/styles/qstyle.cpp
deleted file mode 100644
index c5eb330650..0000000000
--- a/src/gui/styles/qstyle.cpp
+++ /dev/null
@@ -1,2493 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qstyle.h"
-#include "qapplication.h"
-#include "qpainter.h"
-#include "qwidget.h"
-#include "qbitmap.h"
-#include "qpixmapcache.h"
-#include "qstyleoption.h"
-#include "private/qstyle_p.h"
-#ifndef QT_NO_DEBUG
-#include "qdebug.h"
-#endif
-
-#ifdef Q_WS_X11
-#include <qx11info_x11.h>
-#endif
-
-#include <limits.h>
-
-QT_BEGIN_NAMESPACE
-
-static const int MaxBits = 8 * sizeof(QSizePolicy::ControlType);
-
-static int unpackControlTypes(QSizePolicy::ControlTypes controls, QSizePolicy::ControlType *array)
-{
- if (!controls)
- return 0;
-
- // optimization: exactly one bit is set
- if ((controls & (controls - 1)) == 0) {
- array[0] = QSizePolicy::ControlType(uint(controls));
- return 1;
- }
-
- int count = 0;
- for (int i = 0; i < MaxBits; ++i) {
- if (uint bit = (controls & (0x1 << i)))
- array[count++] = QSizePolicy::ControlType(bit);
- }
- return count;
-}
-
-/*!
- \class QStyle
- \brief The QStyle class is an abstract base class that encapsulates the look and feel of a GUI.
-
- \ingroup appearance
-
- Qt contains a set of QStyle subclasses that emulate the styles of
- the different platforms supported by Qt (QWindowsStyle,
- QMacStyle, QMotifStyle, etc.). By default, these styles are built
- into the QtGui library. Styles can also be made available as
- plugins.
-
- Qt's built-in widgets use QStyle to perform nearly all of their
- drawing, ensuring that they look exactly like the equivalent
- native widgets. The diagram below shows a QComboBox in eight
- different styles.
-
- \img qstyle-comboboxes.png Eight combo boxes
-
- Topics:
-
- \tableofcontents
-
- \section1 Setting a Style
-
- The style of the entire application can be set using the
- QApplication::setStyle() function. It can also be specified by the
- user of the application, using the \c -style command-line option:
-
- \snippet doc/src/snippets/code/src_gui_styles_qstyle.cpp 0
-
- If no style is specified, Qt will choose the most appropriate
- style for the user's platform or desktop environment.
-
- A style can also be set on an individual widget using the
- QWidget::setStyle() function.
-
- \section1 Developing Style-Aware Custom Widgets
-
- If you are developing custom widgets and want them to look good on
- all platforms, you can use QStyle functions to perform parts of
- the widget drawing, such as drawItemText(), drawItemPixmap(),
- drawPrimitive(), drawControl(), and drawComplexControl().
-
- Most QStyle draw functions take four arguments:
- \list
- \o an enum value specifying which graphical element to draw
- \o a QStyleOption specifying how and where to render that element
- \o a QPainter that should be used to draw the element
- \o a QWidget on which the drawing is performed (optional)
- \endlist
-
- For example, if you want to draw a focus rectangle on your
- widget, you can write:
-
- \snippet doc/src/snippets/styles/styles.cpp 1
-
- QStyle gets all the information it needs to render the graphical
- element from QStyleOption. The widget is passed as the last
- argument in case the style needs it to perform special effects
- (such as animated default buttons on Mac OS X), but it isn't
- mandatory. In fact, you can use QStyle to draw on any paint
- device, not just widgets, by setting the QPainter properly.
-
- QStyleOption has various subclasses for the various types of
- graphical elements that can be drawn. For example,
- PE_FrameFocusRect expects a QStyleOptionFocusRect argument.
-
- To ensure that drawing operations are as fast as possible,
- QStyleOption and its subclasses have public data members. See the
- QStyleOption class documentation for details on how to use it.
-
- For convenience, Qt provides the QStylePainter class, which
- combines a QStyle, a QPainter, and a QWidget. This makes it
- possible to write
-
- \snippet doc/src/snippets/styles/styles.cpp 5
- \dots
- \snippet doc/src/snippets/styles/styles.cpp 7
-
- instead of
-
- \snippet doc/src/snippets/styles/styles.cpp 2
- \dots
- \snippet doc/src/snippets/styles/styles.cpp 3
-
- \section1 Creating a Custom Style
-
- You can create a custom look and feel for your application by
- creating a custom style. There are two approaches to creating a
- custom style. In the static approach, you either choose an
- existing QStyle class, subclass it, and reimplement virtual
- functions to provide the custom behavior, or you create an entire
- QStyle class from scratch. In the dynamic approach, you modify the
- behavior of your system style at runtime. The static approach is
- described below. The dynamic approach is described in QProxyStyle.
-
- The first step in the static approach is to pick one of the styles
- provided by Qt from which you will build your custom style. Your
- choice of QStyle class will depend on which style resembles your
- desired style the most. The most general class that you can use as
- a base is QCommonStyle (not QStyle). This is because Qt requires
- its styles to be \l{QCommonStyle}s.
-
- Depending on which parts of the base style you want to change,
- you must reimplement the functions that are used to draw those
- parts of the interface. To illustrate this, we will modify the
- look of the spin box arrows drawn by QWindowsStyle. The arrows
- are \e{primitive elements} that are drawn by the drawPrimitive()
- function, so we need to reimplement that function. We need the
- following class declaration:
-
- \snippet doc/src/snippets/customstyle/customstyle.h 0
-
- To draw its up and down arrows, QSpinBox uses the
- PE_IndicatorSpinUp and PE_IndicatorSpinDown primitive elements.
- Here's how to reimplement the drawPrimitive() function to draw
- them differently:
-
- \snippet doc/src/snippets/customstyle/customstyle.cpp 2
- \snippet doc/src/snippets/customstyle/customstyle.cpp 3
- \snippet doc/src/snippets/customstyle/customstyle.cpp 4
-
- Notice that we don't use the \c widget argument, except to pass it
- on to the QWindowStyle::drawPrimitive() function. As mentioned
- earlier, the information about what is to be drawn and how it
- should be drawn is specified by a QStyleOption object, so there is
- no need to ask the widget.
-
- If you need to use the \c widget argument to obtain additional
- information, be careful to ensure that it isn't 0 and that it is
- of the correct type before using it. For example:
-
- \snippet doc/src/snippets/customstyle/customstyle.cpp 0
- \dots
- \snippet doc/src/snippets/customstyle/customstyle.cpp 1
-
- When implementing a custom style, you cannot assume that the
- widget is a QSpinBox just because the enum value is called
- PE_IndicatorSpinUp or PE_IndicatorSpinDown.
-
- The documentation for the \l{widgets/styles}{Styles} example
- covers this topic in more detail.
-
- \warning Qt style sheets are currently not supported for custom QStyle
- subclasses. We plan to address this in some future release.
-
-
- \section1 Using a Custom Style
-
- There are several ways of using a custom style in a Qt
- application. The simplest way is to pass the custom style to the
- QApplication::setStyle() static function before creating the
- QApplication object:
-
- \snippet snippets/customstyle/main.cpp using a custom style
-
- You can call QApplication::setStyle() at any time, but by calling
- it before the constructor, you ensure that the user's preference,
- set using the \c -style command-line option, is respected.
-
- You may want to make your custom style available for use in other
- applications, which may not be yours and hence not available for
- you to recompile. The Qt Plugin system makes it possible to create
- styles as plugins. Styles created as plugins are loaded as shared
- objects at runtime by Qt itself. Please refer to the \link
- plugins-howto.html Qt Plugin\endlink documentation for more
- information on how to go about creating a style plugin.
-
- Compile your plugin and put it into Qt's \c plugins/styles
- directory. We now have a pluggable style that Qt can load
- automatically. To use your new style with existing applications,
- simply start the application with the following argument:
-
- \snippet doc/src/snippets/code/src_gui_styles_qstyle.cpp 1
-
- The application will use the look and feel from the custom style you
- implemented.
-
- \section1 Right-to-Left Desktops
-
- Languages written from right to left (such as Arabic and Hebrew)
- usually also mirror the whole layout of widgets, and require the
- light to come from the screen's top-right corner instead of
- top-left.
-
- If you create a custom style, you should take special care when
- drawing asymmetric elements to make sure that they also look
- correct in a mirrored layout. An easy way to test your styles is
- to run applications with the \c -reverse command-line option or
- to call QApplication::setLayoutDirection() in your \c main()
- function.
-
- Here are some things to keep in mind when making a style work well in a
- right-to-left environment:
-
- \list
- \o subControlRect() and subElementRect() return rectangles in screen coordinates
- \o QStyleOption::direction indicates in which direction the item should be drawn in
- \o If a style is not right-to-left aware it will display items as if it were left-to-right
- \o visualRect(), visualPos(), and visualAlignment() are helpful functions that will
- translate from logical to screen representations.
- \o alignedRect() will return a logical rect aligned for the current direction
- \endlist
-
- \section1 Styles in Item Views
-
- The painting of items in views is performed by a delegate. Qt's
- default delegate, QStyledItemDelegate, is also used for for calculating bounding
- rectangles of items, and their sub-elements for the various kind
- of item \l{Qt::ItemDataRole}{data roles}
- QStyledItemDelegate supports. See the QStyledItemDelegate class
- description to find out which datatypes and roles are supported. You
- can read more about item data roles in \l{Model/View Programming}.
-
- When QStyledItemDelegate paints its items, it draws
- CE_ItemViewItem, and calculates their size with CT_ItemViewItem.
- Note also that it uses SE_ItemViewItemText to set the size of
- editors. When implementing a style to customize drawing of item
- views, you need to check the implementation of QCommonStyle (and
- any other subclasses from which your style
- inherits). This way, you find out which and how
- other style elements are painted, and you can then reimplement the
- painting of elements that should be drawn differently.
-
- We include a small example where we customize the drawing of item
- backgrounds.
-
- \snippet doc/src/snippets/customviewstyle.cpp 0
-
- The primitive element PE_PanelItemViewItem is responsible for
- painting the background of items, and is called from
- \l{QCommonStyle}'s implementation of CE_ItemViewItem.
-
- To add support for drawing of new datatypes and item data roles,
- it is necessary to create a custom delegate. But if you only
- need to support the datatypes implemented by the default
- delegate, a custom style does not need an accompanying
- delegate. The QStyledItemDelegate class description gives more
- information on custom delegates.
-
- The drawing of item view headers is also done by the style, giving
- control over size of header items and row and column sizes.
-
- \sa QStyleOption, QStylePainter, {Styles Example},
- {Styles and Style Aware Widgets}, QStyledItemDelegate
-*/
-
-/*!
- Constructs a style object.
-*/
-QStyle::QStyle()
- : QObject(*new QStylePrivate)
-{
- Q_D(QStyle);
- d->proxyStyle = this;
-}
-
-/*!
- \internal
-
- Constructs a style object.
-*/
-QStyle::QStyle(QStylePrivate &dd)
- : QObject(dd)
-{
- Q_D(QStyle);
- d->proxyStyle = this;
-}
-
-/*!
- Destroys the style object.
-*/
-QStyle::~QStyle()
-{
-}
-
-/*!
- Initializes the appearance of the given \a widget.
-
- This function is called for every widget at some point after it
- has been fully created but just \e before it is shown for the very
- first time.
-
- Note that the default implementation does nothing. Reasonable
- actions in this function might be to call the
- QWidget::setBackgroundMode() function for the widget. Do not use
- the function to set, for example, the geometry. Reimplementing
- this function provides a back-door through which the appearance
- of a widget can be changed, but with Qt's style engine it is
- rarely necessary to implement this function; reimplement
- drawItemPixmap(), drawItemText(), drawPrimitive(), etc. instead.
-
- The QWidget::inherits() function may provide enough information to
- allow class-specific customizations. But because new QStyle
- subclasses are expected to work reasonably with all current and \e
- future widgets, limited use of hard-coded customization is
- recommended.
-
- \sa unpolish()
-*/
-void QStyle::polish(QWidget * /* widget */)
-{
-}
-
-/*!
- Uninitialize the given \a{widget}'s appearance.
-
- This function is the counterpart to polish(). It is called for
- every polished widget whenever the style is dynamically changed;
- the former style has to unpolish its settings before the new style
- can polish them again.
-
- Note that unpolish() will only be called if the widget is
- destroyed. This can cause problems in some cases, e.g, if you
- remove a widget from the UI, cache it, and then reinsert it after
- the style has changed; some of Qt's classes cache their widgets.
-
- \sa polish()
-*/
-void QStyle::unpolish(QWidget * /* widget */)
-{
-}
-
-/*!
- \fn void QStyle::polish(QApplication * application)
- \overload
-
- Late initialization of the given \a application object.
-*/
-void QStyle::polish(QApplication * /* app */)
-{
-}
-
-/*!
- \fn void QStyle::unpolish(QApplication * application)
- \overload
-
- Uninitialize the given \a application.
-*/
-void QStyle::unpolish(QApplication * /* app */)
-{
-}
-
-/*!
- \fn void QStyle::polish(QPalette & palette)
- \overload
-
- Changes the \a palette according to style specific requirements
- for color palettes (if any).
-
- \sa QPalette, QApplication::setPalette()
-*/
-void QStyle::polish(QPalette & /* pal */)
-{
-}
-
-/*!
- \fn QRect QStyle::itemTextRect(const QFontMetrics &metrics, const QRect &rectangle, int alignment, bool enabled, const QString &text) const
-
- Returns the area within the given \a rectangle in which to draw
- the provided \a text according to the specified font \a metrics
- and \a alignment. The \a enabled parameter indicates whether or
- not the associated item is enabled.
-
- If the given \a rectangle is larger than the area needed to render
- the \a text, the rectangle that is returned will be offset within
- \a rectangle according to the specified \a alignment. For
- example, if \a alignment is Qt::AlignCenter, the returned
- rectangle will be centered within \a rectangle. If the given \a
- rectangle is smaller than the area needed, the returned rectangle
- will be the smallest rectangle large enough to render the \a text.
-
- \sa Qt::Alignment
-*/
-QRect QStyle::itemTextRect(const QFontMetrics &metrics, const QRect &rect, int alignment, bool enabled,
- const QString &text) const
-{
- QRect result;
- int x, y, w, h;
- rect.getRect(&x, &y, &w, &h);
- if (!text.isEmpty()) {
- result = metrics.boundingRect(x, y, w, h, alignment, text);
- if (!enabled && proxy()->styleHint(SH_EtchDisabledText)) {
- result.setWidth(result.width()+1);
- result.setHeight(result.height()+1);
- }
- } else {
- result = QRect(x, y, w, h);
- }
- return result;
-}
-
-/*!
- \fn QRect QStyle::itemPixmapRect(const QRect &rectangle, int alignment, const QPixmap &pixmap) const
-
- Returns the area within the given \a rectangle in which to draw
- the specified \a pixmap according to the defined \a alignment.
-*/
-QRect QStyle::itemPixmapRect(const QRect &rect, int alignment, const QPixmap &pixmap) const
-{
- QRect result;
- int x, y, w, h;
- rect.getRect(&x, &y, &w, &h);
- if ((alignment & Qt::AlignVCenter) == Qt::AlignVCenter)
- y += h/2 - pixmap.height()/2;
- else if ((alignment & Qt::AlignBottom) == Qt::AlignBottom)
- y += h - pixmap.height();
- if ((alignment & Qt::AlignRight) == Qt::AlignRight)
- x += w - pixmap.width();
- else if ((alignment & Qt::AlignHCenter) == Qt::AlignHCenter)
- x += w/2 - pixmap.width()/2;
- else if ((alignment & Qt::AlignLeft) != Qt::AlignLeft && QApplication::isRightToLeft())
- x += w - pixmap.width();
- result = QRect(x, y, pixmap.width(), pixmap.height());
- return result;
-}
-
-/*!
- \fn void QStyle::drawItemText(QPainter *painter, const QRect &rectangle, int alignment, const QPalette &palette, bool enabled, const QString& text, QPalette::ColorRole textRole) const
-
- Draws the given \a text in the specified \a rectangle using the
- provided \a painter and \a palette.
-
- The text is drawn using the painter's pen, and aligned and wrapped
- according to the specified \a alignment. If an explicit \a
- textRole is specified, the text is drawn using the \a palette's
- color for the given role. The \a enabled parameter indicates
- whether or not the item is enabled; when reimplementing this
- function, the \a enabled parameter should influence how the item is
- drawn.
-
- \sa Qt::Alignment, drawItemPixmap()
-*/
-void QStyle::drawItemText(QPainter *painter, const QRect &rect, int alignment, const QPalette &pal,
- bool enabled, const QString& text, QPalette::ColorRole textRole) const
-{
- if (text.isEmpty())
- return;
- QPen savedPen;
- if (textRole != QPalette::NoRole) {
- savedPen = painter->pen();
- painter->setPen(QPen(pal.brush(textRole), savedPen.widthF()));
- }
- if (!enabled) {
- if (proxy()->styleHint(SH_DitherDisabledText)) {
- QRect br;
- painter->drawText(rect, alignment, text, &br);
- painter->fillRect(br, QBrush(painter->background().color(), Qt::Dense5Pattern));
- return;
- } else if (proxy()->styleHint(SH_EtchDisabledText)) {
- QPen pen = painter->pen();
- painter->setPen(pal.light().color());
- painter->drawText(rect.adjusted(1, 1, 1, 1), alignment, text);
- painter->setPen(pen);
- }
- }
- painter->drawText(rect, alignment, text);
- if (textRole != QPalette::NoRole)
- painter->setPen(savedPen);
-}
-
-/*!
- \fn void QStyle::drawItemPixmap(QPainter *painter, const QRect &rectangle, int alignment,
- const QPixmap &pixmap) const
-
- Draws the given \a pixmap in the specified \a rectangle, according
- to the specified \a alignment, using the provided \a painter.
-
- \sa drawItemText()
-*/
-
-void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment,
- const QPixmap &pixmap) const
-{
- QRect aligned = alignedRect(QApplication::layoutDirection(), QFlag(alignment), pixmap.size(), rect);
- QRect inter = aligned.intersected(rect);
-
- painter->drawPixmap(inter.x(), inter.y(), pixmap, inter.x() - aligned.x(), inter.y() - aligned.y(), inter.width(), inter.height());
-}
-
-/*!
- \enum QStyle::PrimitiveElement
-
- This enum describes the various primitive elements. A
- primitive element is a common GUI element, such as a checkbox
- indicator or button bevel.
-
- \omitvalue PE_IndicatorViewItemCheck
- \value PE_FrameStatusBar Frame
-
- \value PE_PanelButtonCommand Button used to initiate an action, for
- example, a QPushButton.
-
- \value PE_FrameDefaultButton This frame around a default button, e.g. in a dialog.
- \value PE_PanelButtonBevel Generic panel with a button bevel.
- \value PE_PanelButtonTool Panel for a Tool button, used with QToolButton.
- \value PE_PanelLineEdit Panel for a QLineEdit.
- \value PE_IndicatorButtonDropDown Indicator for a drop down button, for example, a tool
- button that displays a menu.
-
- \value PE_FrameFocusRect Generic focus indicator.
-
- \value PE_IndicatorArrowUp Generic Up arrow.
- \value PE_IndicatorArrowDown Generic Down arrow.
- \value PE_IndicatorArrowRight Generic Right arrow.
- \value PE_IndicatorArrowLeft Generic Left arrow.
-
- \value PE_IndicatorSpinUp Up symbol for a spin widget, for example a QSpinBox.
- \value PE_IndicatorSpinDown Down symbol for a spin widget.
- \value PE_IndicatorSpinPlus Increase symbol for a spin widget.
- \value PE_IndicatorSpinMinus Decrease symbol for a spin widget.
-
- \value PE_IndicatorItemViewItemCheck On/off indicator for a view item.
-
- \value PE_IndicatorCheckBox On/off indicator, for example, a QCheckBox.
- \value PE_IndicatorRadioButton Exclusive on/off indicator, for example, a QRadioButton.
-
- \value PE_Q3DockWindowSeparator Item separator for Qt 3 compatible dock window
- and toolbar contents.
- \value PE_IndicatorDockWidgetResizeHandle Resize handle for dock windows.
-
- \value PE_Frame Generic frame
- \value PE_FrameMenu Frame for popup windows/menus; see also QMenu.
- \value PE_PanelMenuBar Panel for menu bars.
- \value PE_PanelScrollAreaCorner Panel at the bottom-right (or
- bottom-left) corner of a scroll area.
-
- \value PE_FrameDockWidget Panel frame for dock windows and toolbars.
- \value PE_FrameTabWidget Frame for tab widgets.
- \value PE_FrameLineEdit Panel frame for line edits.
- \value PE_FrameGroupBox Panel frame around group boxes.
- \value PE_FrameButtonBevel Panel frame for a button bevel.
- \value PE_FrameButtonTool Panel frame for a tool button.
-
- \value PE_IndicatorHeaderArrow Arrow used to indicate sorting on a list or table
- header.
- \value PE_FrameStatusBarItem Frame for an item of a status bar; see also QStatusBar.
-
- \value PE_FrameWindow Frame around a MDI window or a docking window.
-
- \value PE_Q3Separator Qt 3 compatible generic separator.
-
- \value PE_IndicatorMenuCheckMark Check mark used in a menu.
-
- \value PE_IndicatorProgressChunk Section of a progress bar indicator; see also QProgressBar.
-
- \value PE_Q3CheckListController Qt 3 compatible controller part of a list view item.
- \value PE_Q3CheckListIndicator Qt 3 compatible checkbox part of a list view item.
- \value PE_Q3CheckListExclusiveIndicator Qt 3 compatible radio button part of a list view item.
-
- \value PE_IndicatorBranch Lines used to represent the branch of a tree in a tree view.
- \value PE_IndicatorToolBarHandle The handle of a toolbar.
- \value PE_IndicatorToolBarSeparator The separator in a toolbar.
- \value PE_PanelToolBar The panel for a toolbar.
- \value PE_PanelTipLabel The panel for a tip label.
- \value PE_FrameTabBarBase The frame that is drawn for a tab bar, ususally drawn for a tab bar that isn't part of a tab widget.
- \value PE_IndicatorTabTear An indicator that a tab is partially scrolled out of the visible tab bar when there are many tabs.
- \value PE_IndicatorColumnViewArrow An arrow in a QColumnView.
-
- \value PE_Widget A plain QWidget.
-
- \value PE_CustomBase Base value for custom primitive elements.
- All values above this are reserved for custom use. Custom values
- must be greater than this value.
-
- \value PE_IndicatorItemViewItemDrop An indicator that is drawn to show where an item in an item view is about to be dropped
- during a drag-and-drop operation in an item view.
- \value PE_PanelItemViewItem The background for an item in an item view.
- \value PE_PanelItemViewRow The background of a row in an item view.
-
- \value PE_PanelStatusBar The panel for a status bar.
-
- \value PE_IndicatorTabClose The close button on a tab bar.
- \value PE_PanelMenu The panel for a menu.
-
- \sa drawPrimitive()
-*/
-
-/*!
- \typedef QStyle::SFlags
- \internal
-*/
-
-/*!
- \typedef QStyle::SCFlags
- \internal
-*/
-
-/*!
- \enum QStyle::StateFlag
-
- This enum describes flags that are used when drawing primitive
- elements.
-
- Note that not all primitives use all of these flags, and that the
- flags may mean different things to different items.
-
- \value State_None Indicates that the widget does not have a state.
- \value State_Active Indicates that the widget is active.
- \value State_AutoRaise Used to indicate if auto-raise appearance should be usd on a tool button.
- \value State_Children Used to indicate if an item view branch has children.
- \value State_DownArrow Used to indicate if a down arrow should be visible on the widget.
- \value State_Editing Used to indicate if an editor is opened on the widget.
- \value State_Enabled Used to indicate if the widget is enabled.
- \value State_HasEditFocus Used to indicate if the widget currently has edit focus.
- \value State_HasFocus Used to indicate if the widget has focus.
- \value State_Horizontal Used to indicate if the widget is laid out horizontally, for example. a tool bar.
- \value State_KeyboardFocusChange Used to indicate if the focus was changed with the keyboard, e.g., tab, backtab or shortcut.
- \value State_MouseOver Used to indicate if the widget is under the mouse.
- \value State_NoChange Used to indicate a tri-state checkbox.
- \value State_Off Used to indicate if the widget is not checked.
- \value State_On Used to indicate if the widget is checked.
- \value State_Raised Used to indicate if a button is raised.
- \value State_ReadOnly Used to indicate if a widget is read-only.
- \value State_Selected Used to indicate if a widget is selected.
- \value State_Item Used by item views to indicate if a horizontal branch should be drawn.
- \value State_Open Used by item views to indicate if the tree branch is open.
- \value State_Sibling Used by item views to indicate if a vertical line needs to be drawn (for siblings).
- \value State_Sunken Used to indicate if the widget is sunken or pressed.
- \value State_UpArrow Used to indicate if an up arrow should be visible on the widget.
- \value State_Mini Used to indicate a mini style Mac widget or button.
- \value State_Small Used to indicate a small style Mac widget or button.
- \omitvalue State_Window
- \omitvalue State_Bottom
- \omitvalue State_Default
- \omitvalue State_FocusAtBorder
- \omitvalue State_Top
-
- \sa drawPrimitive()
-*/
-
-/*!
- \fn void QStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option, \
- QPainter *painter, const QWidget *widget) const
-
- Draws the given primitive \a element with the provided \a painter using the style
- options specified by \a option.
-
- The \a widget argument is optional and may contain a widget that may
- aid in drawing the primitive element.
-
- The table below is listing the primitive elements and their
- associated style option subclasses. The style options contain all
- the parameters required to draw the elements, including
- QStyleOption::state which holds the style flags that are used when
- drawing. The table also describes which flags that are set when
- casting the given option to the appropriate subclass.
-
- Note that if a primitive element is not listed here, it is because
- it uses a plain QStyleOption object.
-
- \table
- \header \o Primitive Element \o QStyleOption Subclass \o Style Flag \o Remark
- \row \o \l PE_FrameFocusRect \o \l QStyleOptionFocusRect
- \o \l State_FocusAtBorder
- \o Whether the focus is is at the border or inside the widget.
- \row \o{1,2} \l PE_IndicatorCheckBox \o{1,2} \l QStyleOptionButton
- \o \l State_NoChange \o Indicates a "tri-state" checkbox.
- \row \o \l State_On \o Indicates the indicator is checked.
- \row \o \l PE_IndicatorRadioButton \o \l QStyleOptionButton
- \o \l State_On \o Indicates that a radio button is selected.
- \row \o{1,3} \l PE_Q3CheckListExclusiveIndicator, \l PE_Q3CheckListIndicator
- \o{1,3} \l QStyleOptionQ3ListView \o \l State_On
- \o Indicates whether or not the controller is selected.
- \row \o \l State_NoChange \o Indicates a "tri-state" controller.
- \row \o \l State_Enabled \o Indicates the controller is enabled.
- \row \o{1,4} \l PE_IndicatorBranch \o{1,4} \l QStyleOption
- \o \l State_Children \o Indicates that the control for expanding the tree to show child items, should be drawn.
- \row \o \l State_Item \o Indicates that a horizontal branch (to show a child item), should be drawn.
- \row \o \l State_Open \o Indicates that the tree branch is expanded.
- \row \o \l State_Sibling \o Indicates that a vertical line (to show a sibling item), should be drawn.
- \row \o \l PE_IndicatorHeaderArrow \o \l QStyleOptionHeader
- \o \l State_UpArrow \o Indicates that the arrow should be drawn up;
- otherwise it should be down.
- \row \o \l PE_FrameGroupBox, \l PE_Frame, \l PE_FrameLineEdit,
- \l PE_FrameMenu, \l PE_FrameDockWidget, \l PE_FrameWindow
- \o \l QStyleOptionFrame \o \l State_Sunken
- \o Indicates that the Frame should be sunken.
- \row \o \l PE_IndicatorToolBarHandle \o \l QStyleOption
- \o \l State_Horizontal \o Indicates that the window handle is horizontal
- instead of vertical.
- \row \o \l PE_Q3DockWindowSeparator \o \l QStyleOption
- \o \l State_Horizontal \o Indicates that the separator is horizontal
- instead of vertical.
- \row \o \l PE_IndicatorSpinPlus, \l PE_IndicatorSpinMinus, \l PE_IndicatorSpinUp,
- \l PE_IndicatorSpinDown,
- \o \l QStyleOptionSpinBox
- \o \l State_Sunken \o Indicates that the button is pressed.
- \row \o{1,5} \l PE_PanelButtonCommand
- \o{1,5} \l QStyleOptionButton
- \o \l State_Enabled \o Set if the button is enabled.
- \row \o \l State_HasFocus \o Set if the button has input focus.
- \row \o \l State_Raised \o Set if the button is not down, not on and not flat.
- \row \o \l State_On \o Set if the button is a toggle button and is toggled on.
- \row \o \l State_Sunken
- \o Set if the button is down (i.e., the mouse button or the
- space bar is pressed on the button).
- \endtable
-
- \sa drawComplexControl(), drawControl()
-*/
-
-/*!
- \enum QStyle::ControlElement
-
- This enum represents a control element. A control element is a
- part of a widget that performs some action or displays information
- to the user.
-
- \value CE_PushButton A QPushButton, draws CE_PushButtonBevel, CE_PushButtonLabel and PE_FrameFocusRect.
- \value CE_PushButtonBevel The bevel and default indicator of a QPushButton.
- \value CE_PushButtonLabel The label (an icon with text or pixmap) of a QPushButton.
-
- \value CE_DockWidgetTitle Dock window title.
- \value CE_Splitter Splitter handle; see also QSplitter.
-
-
- \value CE_CheckBox A QCheckBox, draws a PE_IndicatorCheckBox, a CE_CheckBoxLabel and a PE_FrameFocusRect.
- \value CE_CheckBoxLabel The label (text or pixmap) of a QCheckBox.
-
- \value CE_RadioButton A QRadioButton, draws a PE_IndicatorRadioButton, a CE_RadioButtonLabel and a PE_FrameFocusRect.
- \value CE_RadioButtonLabel The label (text or pixmap) of a QRadioButton.
-
- \value CE_TabBarTab The tab and label within a QTabBar.
- \value CE_TabBarTabShape The tab shape within a tab bar.
- \value CE_TabBarTabLabel The label within a tab.
-
- \value CE_ProgressBar A QProgressBar, draws CE_ProgressBarGroove, CE_ProgressBarContents and CE_ProgressBarLabel.
- \value CE_ProgressBarGroove The groove where the progress
- indicator is drawn in a QProgressBar.
- \value CE_ProgressBarContents The progress indicator of a QProgressBar.
- \value CE_ProgressBarLabel The text label of a QProgressBar.
-
- \value CE_ToolButtonLabel A tool button's label.
-
- \value CE_MenuBarItem A menu item in a QMenuBar.
- \value CE_MenuBarEmptyArea The empty area of a QMenuBar.
-
- \value CE_MenuItem A menu item in a QMenu.
- \value CE_MenuScroller Scrolling areas in a QMenu when the
- style supports scrolling.
- \value CE_MenuTearoff A menu item representing the tear off section of
- a QMenu.
- \value CE_MenuEmptyArea The area in a menu without menu items.
- \value CE_MenuHMargin The horizontal extra space on the left/right of a menu.
- \value CE_MenuVMargin The vertical extra space on the top/bottom of a menu.
-
- \value CE_Q3DockWindowEmptyArea The empty area of a QDockWidget.
-
- \value CE_ToolBoxTab The toolbox's tab and label within a QToolBox.
- \value CE_SizeGrip Window resize handle; see also QSizeGrip.
-
- \value CE_Header A header.
- \value CE_HeaderSection A header section.
- \value CE_HeaderLabel The header's label.
-
- \value CE_ScrollBarAddLine Scroll bar line increase indicator.
- (i.e., scroll down); see also QScrollBar.
- \value CE_ScrollBarSubLine Scroll bar line decrease indicator (i.e., scroll up).
- \value CE_ScrollBarAddPage Scolllbar page increase indicator (i.e., page down).
- \value CE_ScrollBarSubPage Scroll bar page decrease indicator (i.e., page up).
- \value CE_ScrollBarSlider Scroll bar slider.
- \value CE_ScrollBarFirst Scroll bar first line indicator (i.e., home).
- \value CE_ScrollBarLast Scroll bar last line indicator (i.e., end).
-
- \value CE_RubberBand Rubber band used in for example an icon view.
-
- \value CE_FocusFrame Focus frame that is style controlled.
-
- \value CE_ItemViewItem An item inside an item view.
-
- \value CE_CustomBase Base value for custom control elements;
- custom values must be greater than this value.
- \value CE_ComboBoxLabel The label of a non-editable QComboBox.
- \value CE_ToolBar A toolbar like QToolBar.
- \value CE_ToolBoxTabShape The toolbox's tab shape.
- \value CE_ToolBoxTabLabel The toolbox's tab label.
- \value CE_HeaderEmptyArea The area of a header view where there are no header sections.
-
- \value CE_ShapedFrame The frame with the shape specified in the QStyleOptionFrameV3; see QFrame.
-
- \omitvalue CE_ColumnViewGrip
-
- \sa drawControl()
-*/
-
-/*!
- \fn void QStyle::drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const
-
- Draws the given \a element with the provided \a painter with the
- style options specified by \a option.
-
- The \a widget argument is optional and can be used as aid in
- drawing the control. The \a option parameter is a pointer to a
- QStyleOption object that can be cast to the correct subclass
- using the qstyleoption_cast() function.
-
- The table below is listing the control elements and their
- associated style option subclass. The style options contain all
- the parameters required to draw the controls, including
- QStyleOption::state which holds the style flags that are used when
- drawing. The table also describes which flags that are set when
- casting the given option to the appropriate subclass.
-
- Note that if a control element is not listed here, it is because
- it uses a plain QStyleOption object.
-
- \table
- \header \o Control Element \o QStyleOption Subclass \o Style Flag \o Remark
- \row \o{1,5} \l CE_MenuItem, \l CE_MenuBarItem
- \o{1,5} \l QStyleOptionMenuItem
- \o \l State_Selected \o The menu item is currently selected item.
- \row \o \l State_Enabled \o The item is enabled.
- \row \o \l State_DownArrow \o Indicates that a scroll down arrow should be drawn.
- \row \o \l State_UpArrow \o Indicates that a scroll up arrow should be drawn
- \row \o \l State_HasFocus \o Set if the menu bar has input focus.
-
- \row \o{1,5} \l CE_PushButton, \l CE_PushButtonBevel, \l CE_PushButtonLabel
- \o{1,5} \l QStyleOptionButton
- \o \l State_Enabled \o Set if the button is enabled.
- \row \o \l State_HasFocus \o Set if the button has input focus.
- \row \o \l State_Raised \o Set if the button is not down, not on and not flat.
- \row \o \l State_On \o Set if the button is a toggle button and is toggled on.
- \row \o \l State_Sunken
- \o Set if the button is down (i.e., the mouse button or the
- space bar is pressed on the button).
-
- \row \o{1,6} \l CE_RadioButton, \l CE_RadioButtonLabel,
- \l CE_CheckBox, \l CE_CheckBoxLabel
- \o{1,6} \l QStyleOptionButton
- \o \l State_Enabled \o Set if the button is enabled.
- \row \o \l State_HasFocus \o Set if the button has input focus.
- \row \o \l State_On \o Set if the button is checked.
- \row \o \l State_Off \o Set if the button is not checked.
- \row \o \l State_NoChange \o Set if the button is in the NoChange state.
- \row \o \l State_Sunken
- \o Set if the button is down (i.e., the mouse button or
- the space bar is pressed on the button).
-
- \row \o{1,2} \l CE_ProgressBarContents, \l CE_ProgressBarLabel,
- \l CE_ProgressBarGroove
- \o{1,2} \l QStyleOptionProgressBar
- \o \l State_Enabled \o Set if the progress bar is enabled.
- \row \o \l State_HasFocus \o Set if the progress bar has input focus.
-
- \row \o \l CE_Header, \l CE_HeaderSection, \l CE_HeaderLabel \o \l QStyleOptionHeader \o \o
-
- \row \o{1,3} \l CE_TabBarTab, CE_TabBarTabShape, CE_TabBarTabLabel
- \o{1,3} \l QStyleOptionTab
- \o \l State_Enabled \o Set if the tab bar is enabled.
- \row \o \l State_Selected \o The tab bar is the currently selected tab bar.
- \row \o \l State_HasFocus \o Set if the tab bar tab has input focus.
-
- \row \o{1,7} \l CE_ToolButtonLabel
- \o{1,7} \l QStyleOptionToolButton
- \o \l State_Enabled \o Set if the tool button is enabled.
- \row \o \l State_HasFocus \o Set if the tool button has input focus.
- \row \o \l State_Sunken
- \o Set if the tool button is down (i.e., a mouse button or
- the space bar is pressed).
- \row \o \l State_On \o Set if the tool button is a toggle button and is toggled on.
- \row \o \l State_AutoRaise \o Set if the tool button has auto-raise enabled.
- \row \o \l State_MouseOver \o Set if the mouse pointer is over the tool button.
- \row \o \l State_Raised \o Set if the button is not down and is not on.
-
- \row \o \l CE_ToolBoxTab \o \l QStyleOptionToolBox
- \o \l State_Selected \o The tab is the currently selected tab.
- \row \o{1,3} \l CE_HeaderSection \o{1,3} \l QStyleOptionHeader
- \o \l State_Sunken \o Indicates that the section is pressed.
- \row \o \l State_UpArrow \o Indicates that the sort indicator should be pointing up.
- \row \o \l State_DownArrow \o Indicates that the sort indicator should be pointing down.
- \endtable
-
- \sa drawPrimitive(), drawComplexControl()
-*/
-
-/*!
- \enum QStyle::SubElement
-
- This enum represents a sub-area of a widget. Style implementations
- use these areas to draw the different parts of a widget.
-
- \value SE_PushButtonContents Area containing the label (icon
- with text or pixmap).
- \value SE_PushButtonFocusRect Area for the focus rect (usually
- larger than the contents rect).
- \value SE_PushButtonLayoutItem Area that counts for the parent layout.
-
- \value SE_CheckBoxIndicator Area for the state indicator (e.g., check mark).
- \value SE_CheckBoxContents Area for the label (text or pixmap).
- \value SE_CheckBoxFocusRect Area for the focus indicator.
- \value SE_CheckBoxClickRect Clickable area, defaults to SE_CheckBoxFocusRect.
- \value SE_CheckBoxLayoutItem Area that counts for the parent layout.
-
- \value SE_DateTimeEditLayoutItem Area that counts for the parent layout.
-
- \value SE_RadioButtonIndicator Area for the state indicator.
- \value SE_RadioButtonContents Area for the label.
- \value SE_RadioButtonFocusRect Area for the focus indicator.
- \value SE_RadioButtonClickRect Clickable area, defaults to SE_RadioButtonFocusRect.
- \value SE_RadioButtonLayoutItem Area that counts for the parent layout.
-
- \value SE_ComboBoxFocusRect Area for the focus indicator.
-
- \value SE_SliderFocusRect Area for the focus indicator.
- \value SE_SliderLayoutItem Area that counts for the parent layout.
-
- \value SE_SpinBoxLayoutItem Area that counts for the parent layout.
-
- \value SE_Q3DockWindowHandleRect Area for the tear-off handle.
-
- \value SE_ProgressBarGroove Area for the groove.
- \value SE_ProgressBarContents Area for the progress indicator.
- \value SE_ProgressBarLabel Area for the text label.
- \value SE_ProgressBarLayoutItem Area that counts for the parent layout.
-
- \omitvalue SE_DialogButtonAccept
- \omitvalue SE_DialogButtonReject
- \omitvalue SE_DialogButtonApply
- \omitvalue SE_DialogButtonHelp
- \omitvalue SE_DialogButtonAll
- \omitvalue SE_DialogButtonRetry
- \omitvalue SE_DialogButtonAbort
- \omitvalue SE_DialogButtonIgnore
- \omitvalue SE_DialogButtonCustom
- \omitvalue SE_ViewItemCheckIndicator
-
- \value SE_FrameContents Area for a frame's contents.
- \value SE_ShapedFrameContents Area for a frame's contents using the shape in QStyleOptionFrameV3; see QFrame
- \value SE_FrameLayoutItem Area that counts for the parent layout.
-
- \value SE_HeaderArrow Area for the sort indicator for a header.
- \value SE_HeaderLabel Area for the label in a header.
-
- \value SE_LabelLayoutItem Area that counts for the parent layout.
-
- \value SE_LineEditContents Area for a line edit's contents.
-
- \value SE_TabWidgetLeftCorner Area for the left corner widget in a tab widget.
- \value SE_TabWidgetRightCorner Area for the right corner widget in a tab widget.
- \value SE_TabWidgetTabBar Area for the tab bar widget in a tab widget.
- \value SE_TabWidgetTabContents Area for the contents of the tab widget.
- \value SE_TabWidgetTabPane Area for the pane of a tab widget.
- \value SE_TabWidgetLayoutItem Area that counts for the parent layout.
-
- \value SE_ToolBoxTabContents Area for a toolbox tab's icon and label.
-
- \value SE_ToolButtonLayoutItem Area that counts for the parent layout.
-
- \value SE_ItemViewItemCheckIndicator Area for a view item's check mark.
-
- \value SE_TabBarTearIndicator Area for the tear indicator on a tab bar with scroll arrows.
-
- \value SE_TreeViewDisclosureItem Area for the actual disclosure item in a tree branch.
-
- \value SE_DialogButtonBoxLayoutItem Area that counts for the parent layout.
-
- \value SE_GroupBoxLayoutItem Area that counts for the parent layout.
-
- \value SE_CustomBase Base value for custom sub-elements.
- Custom values must be greater than this value.
-
- \value SE_DockWidgetFloatButton The float button of a dock
- widget.
- \value SE_DockWidgetTitleBarText The text bounds of the dock
- widgets title.
- \value SE_DockWidgetCloseButton The close button of a dock
- widget.
- \value SE_DockWidgetIcon The icon of a dock widget.
- \value SE_ComboBoxLayoutItem Area that counts for the parent layout.
-
-
- \value SE_ItemViewItemDecoration Area for a view item's decoration (icon).
- \value SE_ItemViewItemText Area for a view item's text.
- \value SE_ItemViewItemFocusRect Area for a view item's focus rect.
-
- \value SE_TabBarTabLeftButton Area for a widget on the left side of a tab in a tab bar.
- \value SE_TabBarTabRightButton Area for a widget on the right side of a tab in a tab bar.
- \value SE_TabBarTabText Area for the text on a tab in a tab bar.
-
- \value SE_ToolBarHandle Area for the handle of a tool bar.
-
- \sa subElementRect()
-*/
-
-/*!
- \fn QRect QStyle::subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const
-
- Returns the sub-area for the given \a element as described in the
- provided style \a option. The returned rectangle is defined in
- screen coordinates.
-
- The \a widget argument is optional and can be used to aid
- determining the area. The QStyleOption object can be cast to the
- appropriate type using the qstyleoption_cast() function. See the
- table below for the appropriate \a option casts:
-
- \table
- \header \o Sub Element \o QStyleOption Subclass
- \row \o \l SE_PushButtonContents \o \l QStyleOptionButton
- \row \o \l SE_PushButtonFocusRect \o \l QStyleOptionButton
- \row \o \l SE_CheckBoxIndicator \o \l QStyleOptionButton
- \row \o \l SE_CheckBoxContents \o \l QStyleOptionButton
- \row \o \l SE_CheckBoxFocusRect \o \l QStyleOptionButton
- \row \o \l SE_RadioButtonIndicator \o \l QStyleOptionButton
- \row \o \l SE_RadioButtonContents \o \l QStyleOptionButton
- \row \o \l SE_RadioButtonFocusRect \o \l QStyleOptionButton
- \row \o \l SE_ComboBoxFocusRect \o \l QStyleOptionComboBox
- \row \o \l SE_Q3DockWindowHandleRect \o \l QStyleOptionQ3DockWindow
- \row \o \l SE_ProgressBarGroove \o \l QStyleOptionProgressBar
- \row \o \l SE_ProgressBarContents \o \l QStyleOptionProgressBar
- \row \o \l SE_ProgressBarLabel \o \l QStyleOptionProgressBar
- \endtable
-*/
-
-/*!
- \enum QStyle::ComplexControl
-
- This enum describes the available complex controls. Complex
- controls have different behavior depending upon where the user
- clicks on them or which keys are pressed.
-
- \value CC_SpinBox A spinbox, like QSpinBox.
- \value CC_ComboBox A combobox, like QComboBox.
- \value CC_ScrollBar A scroll bar, like QScrollBar.
- \value CC_Slider A slider, like QSlider.
- \value CC_ToolButton A tool button, like QToolButton.
- \value CC_TitleBar A Title bar, like those used in QMdiSubWindow.
- \value CC_Q3ListView Used for drawing the Q3ListView class.
- \value CC_GroupBox A group box, like QGroupBox.
- \value CC_Dial A dial, like QDial.
- \value CC_MdiControls The minimize, close, and normal
- button in the menu bar for a
- maximized MDI subwindow.
-
- \value CC_CustomBase Base value for custom complex controls. Custom
- values must be greater than this value.
-
- \sa SubControl drawComplexControl()
-*/
-
-/*!
- \enum QStyle::SubControl
-
- This enum describes the available sub controls. A subcontrol is a
- control element within a complex control (ComplexControl).
-
- \value SC_None Special value that matches no other sub control.
-
- \value SC_ScrollBarAddLine Scroll bar add line (i.e., down/right
- arrow); see also QScrollBar.
- \value SC_ScrollBarSubLine Scroll bar sub line (i.e., up/left arrow).
- \value SC_ScrollBarAddPage Scroll bar add page (i.e., page down).
- \value SC_ScrollBarSubPage Scroll bar sub page (i.e., page up).
- \value SC_ScrollBarFirst Scroll bar first line (i.e., home).
- \value SC_ScrollBarLast Scroll bar last line (i.e., end).
- \value SC_ScrollBarSlider Scroll bar slider handle.
- \value SC_ScrollBarGroove Special sub-control which contains the
- area in which the slider handle may move.
-
- \value SC_SpinBoxUp Spin widget up/increase; see also QSpinBox.
- \value SC_SpinBoxDown Spin widget down/decrease.
- \value SC_SpinBoxFrame Spin widget frame.
- \value SC_SpinBoxEditField Spin widget edit field.
-
- \value SC_ComboBoxEditField Combobox edit field; see also QComboBox.
- \value SC_ComboBoxArrow Combobox arrow button.
- \value SC_ComboBoxFrame Combobox frame.
- \value SC_ComboBoxListBoxPopup The reference rectangle for the combobox popup.
- Used to calculate the position of the popup.
-
- \value SC_SliderGroove Special sub-control which contains the area
- in which the slider handle may move.
- \value SC_SliderHandle Slider handle.
- \value SC_SliderTickmarks Slider tickmarks.
-
- \value SC_ToolButton Tool button (see also QToolButton).
- \value SC_ToolButtonMenu Sub-control for opening a popup menu in a
- tool button; see also Q3PopupMenu.
-
- \value SC_TitleBarSysMenu System menu button (i.e., restore, close, etc.).
- \value SC_TitleBarMinButton Minimize button.
- \value SC_TitleBarMaxButton Maximize button.
- \value SC_TitleBarCloseButton Close button.
- \value SC_TitleBarLabel Window title label.
- \value SC_TitleBarNormalButton Normal (restore) button.
- \value SC_TitleBarShadeButton Shade button.
- \value SC_TitleBarUnshadeButton Unshade button.
- \value SC_TitleBarContextHelpButton Context Help button.
-
- \value SC_Q3ListView The list view area.
- \value SC_Q3ListViewExpand Expand item (i.e., show/hide child items).
-
- \value SC_DialHandle The handle of the dial (i.e. what you use to control the dial).
- \value SC_DialGroove The groove for the dial.
- \value SC_DialTickmarks The tickmarks for the dial.
-
- \value SC_GroupBoxFrame The frame of a group box.
- \value SC_GroupBoxLabel The title of a group box.
- \value SC_GroupBoxCheckBox The optional check box of a group box.
- \value SC_GroupBoxContents The group box contents.
-
- \value SC_MdiNormalButton The normal button for a MDI
- subwindow in the menu bar.
- \value SC_MdiMinButton The minimize button for a MDI
- subwindow in the menu bar.
- \value SC_MdiCloseButton The close button for a MDI subwindow
- in the menu bar.
-
- \value SC_All Special value that matches all sub-controls.
- \omitvalue SC_Q3ListViewBranch
- \omitvalue SC_CustomBase
-
- \sa ComplexControl
-*/
-
-/*!
- \fn void QStyle::drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget) const
-
- Draws the given \a control using the provided \a painter with the
- style options specified by \a option.
-
- The \a widget argument is optional and can be used as aid in
- drawing the control.
-
- The \a option parameter is a pointer to a QStyleOptionComplex
- object that can be cast to the correct subclass using the
- qstyleoption_cast() function. Note that the \c rect member of the
- specified \a option must be in logical
- coordinates. Reimplementations of this function should use
- visualRect() to change the logical coordinates into screen
- coordinates before calling the drawPrimitive() or drawControl()
- function.
-
- The table below is listing the complex control elements and their
- associated style option subclass. The style options contain all
- the parameters required to draw the controls, including
- QStyleOption::state which holds the \l {QStyle::StateFlag}{style
- flags} that are used when drawing. The table also describes which
- flags that are set when casting the given \a option to the
- appropriate subclass.
-
- \table
- \header \o Complex Control \o QStyleOptionComplex Subclass \o Style Flag \o Remark
- \row \o{1,2} \l{CC_SpinBox} \o{1,2} \l QStyleOptionSpinBox
- \o \l State_Enabled \o Set if the spin box is enabled.
- \row \o \l State_HasFocus \o Set if the spin box has input focus.
-
- \row \o{1,2} \l {CC_ComboBox} \o{1,2} \l QStyleOptionComboBox
- \o \l State_Enabled \o Set if the combobox is enabled.
- \row \o \l State_HasFocus \o Set if the combobox has input focus.
-
- \row \o{1,2} \l {CC_ScrollBar} \o{1,2} \l QStyleOptionSlider
- \o \l State_Enabled \o Set if the scroll bar is enabled.
- \row \o \l State_HasFocus \o Set if the scroll bar has input focus.
-
- \row \o{1,2} \l {CC_Slider} \o{1,2} \l QStyleOptionSlider
- \o \l State_Enabled \o Set if the slider is enabled.
- \row \o \l State_HasFocus \o Set if the slider has input focus.
-
- \row \o{1,2} \l {CC_Dial} \o{1,2} \l QStyleOptionSlider
- \o \l State_Enabled \o Set if the dial is enabled.
- \row \o \l State_HasFocus \o Set if the dial has input focus.
-
- \row \o{1,6} \l {CC_ToolButton} \o{1,6} \l QStyleOptionToolButton
- \o \l State_Enabled \o Set if the tool button is enabled.
- \row \o \l State_HasFocus \o Set if the tool button has input focus.
- \row \o \l State_DownArrow \o Set if the tool button is down (i.e., a mouse
- button or the space bar is pressed).
- \row \o \l State_On \o Set if the tool button is a toggle button
- and is toggled on.
- \row \o \l State_AutoRaise \o Set if the tool button has auto-raise enabled.
- \row \o \l State_Raised \o Set if the button is not down, not on, and doesn't
- contain the mouse when auto-raise is enabled.
-
- \row \o \l{CC_TitleBar} \o \l QStyleOptionTitleBar
- \o \l State_Enabled \o Set if the title bar is enabled.
-
- \row \o \l{CC_Q3ListView} \o \l QStyleOptionQ3ListView
- \o \l State_Enabled \o Set if the list view is enabled.
-
- \endtable
-
- \sa drawPrimitive(), drawControl()
-*/
-
-
-/*!
- \fn QRect QStyle::subControlRect(ComplexControl control,
- const QStyleOptionComplex *option, SubControl subControl,
- const QWidget *widget) const = 0
-
- Returns the rectangle containing the specified \a subControl of
- the given complex \a control (with the style specified by \a
- option). The rectangle is defined in screen coordinates.
-
- The \a option argument is a pointer to QStyleOptionComplex or
- one of its subclasses, and can be cast to the appropriate type
- using the qstyleoption_cast() function. See drawComplexControl()
- for details. The \a widget is optional and can contain additional
- information for the function.
-
- \sa drawComplexControl()
-*/
-
-/*!
- \fn QStyle::SubControl QStyle::hitTestComplexControl(ComplexControl control,
- const QStyleOptionComplex *option, const QPoint &position,
- const QWidget *widget) const = 0
-
- Returns the sub control at the given \a position in the given
- complex \a control (with the style options specified by \a
- option).
-
- Note that the \a position is expressed in screen coordinates.
-
- The \a option argument is a pointer to a QStyleOptionComplex
- object (or one of its subclasses). The object can be cast to the
- appropriate type using the qstyleoption_cast() function. See
- drawComplexControl() for details. The \a widget argument is
- optional and can contain additional information for the function.
-
- \sa drawComplexControl(), subControlRect()
-*/
-
-/*!
- \enum QStyle::PixelMetric
-
- This enum describes the various available pixel metrics. A pixel
- metric is a style dependent size represented by a single pixel
- value.
-
- \value PM_ButtonMargin Amount of whitespace between push button
- labels and the frame.
- \value PM_DockWidgetTitleBarButtonMargin Amount of whitespace between dock widget's
- title bar button labels and the frame.
- \value PM_ButtonDefaultIndicator Width of the default-button indicator frame.
- \value PM_MenuButtonIndicator Width of the menu button indicator
- proportional to the widget height.
- \value PM_ButtonShiftHorizontal Horizontal contents shift of a
- button when the button is down.
- \value PM_ButtonShiftVertical Vertical contents shift of a button when the
- button is down.
-
- \value PM_DefaultFrameWidth Default frame width (usually 2).
- \value PM_SpinBoxFrameWidth Frame width of a spin box, defaults to PM_DefaultFrameWidth.
- \value PM_ComboBoxFrameWidth Frame width of a combo box, defaults to PM_DefaultFrameWidth.
-
- \value PM_MDIFrameWidth Obsolete. Use PM_MdiSubWindowFrameWidth instead.
- \value PM_MdiSubWindowFrameWidth Frame width of an MDI window.
- \value PM_MDIMinimizedWidth Obsolete. Use PM_MdiSubWindowMinimizedWidth instead.
- \value PM_MdiSubWindowMinimizedWidth Width of a minimized MDI window.
-
- \value PM_LayoutLeftMargin Default \l{QLayout::setContentsMargins()}{left margin} for a
- QLayout.
- \value PM_LayoutTopMargin Default \l{QLayout::setContentsMargins()}{top margin} for a QLayout.
- \value PM_LayoutRightMargin Default \l{QLayout::setContentsMargins()}{right margin} for a
- QLayout.
- \value PM_LayoutBottomMargin Default \l{QLayout::setContentsMargins()}{bottom margin} for a
- QLayout.
- \value PM_LayoutHorizontalSpacing Default \l{QLayout::spacing}{horizontal spacing} for a
- QLayout.
- \value PM_LayoutVerticalSpacing Default \l{QLayout::spacing}{vertical spacing} for a QLayout.
-
- \value PM_MaximumDragDistance The maximum allowed distance between
- the mouse and a scrollbar when dragging. Exceeding the specified
- distance will cause the slider to jump back to the original
- position; a value of -1 disables this behavior.
-
- \value PM_ScrollBarExtent Width of a vertical scroll bar and the
- height of a horizontal scroll bar.
- \value PM_ScrollBarSliderMin The minimum height of a vertical
- scroll bar's slider and the minimum width of a horizontal
- scroll bar's slider.
-
- \value PM_SliderThickness Total slider thickness.
- \value PM_SliderControlThickness Thickness of the slider handle.
- \value PM_SliderLength Length of the slider.
- \value PM_SliderTickmarkOffset The offset between the tickmarks
- and the slider.
- \value PM_SliderSpaceAvailable The available space for the slider to move.
-
- \value PM_DockWidgetSeparatorExtent Width of a separator in a
- horizontal dock window and the height of a separator in a
- vertical dock window.
- \value PM_DockWidgetHandleExtent Width of the handle in a
- horizontal dock window and the height of the handle in a
- vertical dock window.
- \value PM_DockWidgetFrameWidth Frame width of a dock window.
- \value PM_DockWidgetTitleMargin Margin of the dock window title.
-
- \value PM_MenuBarPanelWidth Frame width of a menu bar, defaults to PM_DefaultFrameWidth.
- \value PM_MenuBarItemSpacing Spacing between menu bar items.
- \value PM_MenuBarHMargin Spacing between menu bar items and left/right of bar.
- \value PM_MenuBarVMargin Spacing between menu bar items and top/bottom of bar.
-
- \value PM_ToolBarFrameWidth Width of the frame around toolbars.
- \value PM_ToolBarHandleExtent Width of a toolbar handle in a
- horizontal toolbar and the height of the handle in a vertical toolbar.
- \value PM_ToolBarItemMargin Spacing between the toolbar frame and the items.
- \value PM_ToolBarItemSpacing Spacing between toolbar items.
- \value PM_ToolBarSeparatorExtent Width of a toolbar separator in a
- horizontal toolbar and the height of a separator in a vertical toolbar.
- \value PM_ToolBarExtensionExtent Width of a toolbar extension
- button in a horizontal toolbar and the height of the button in a
- vertical toolbar.
-
- \value PM_TabBarTabOverlap Number of pixels the tabs should overlap.
- (Currently only used in styles, not inside of QTabBar)
- \value PM_TabBarTabHSpace Extra space added to the tab width.
- \value PM_TabBarTabVSpace Extra space added to the tab height.
- \value PM_TabBarBaseHeight Height of the area between the tab bar
- and the tab pages.
- \value PM_TabBarBaseOverlap Number of pixels the tab bar overlaps
- the tab bar base.
- \value PM_TabBarScrollButtonWidth
- \value PM_TabBarTabShiftHorizontal Horizontal pixel shift when a
- tab is selected.
- \value PM_TabBarTabShiftVertical Vertical pixel shift when a
- tab is selected.
-
- \value PM_ProgressBarChunkWidth Width of a chunk in a progress bar indicator.
-
- \value PM_SplitterWidth Width of a splitter.
-
- \value PM_TitleBarHeight Height of the title bar.
-
- \value PM_IndicatorWidth Width of a check box indicator.
- \value PM_IndicatorHeight Height of a checkbox indicator.
- \value PM_ExclusiveIndicatorWidth Width of a radio button indicator.
- \value PM_ExclusiveIndicatorHeight Height of a radio button indicator.
-
- \value PM_MenuPanelWidth Border width (applied on all sides) for a QMenu.
- \value PM_MenuHMargin Additional border (used on left and right) for a QMenu.
- \value PM_MenuVMargin Additional border (used for bottom and top) for a QMenu.
- \value PM_MenuScrollerHeight Height of the scroller area in a QMenu.
- \value PM_MenuTearoffHeight Height of a tear off area in a QMenu.
- \value PM_MenuDesktopFrameWidth The frame width for the menu on the desktop.
-
- \value PM_CheckListButtonSize Area (width/height) of the
- checkbox/radio button in a Q3CheckListItem.
- \value PM_CheckListControllerSize Area (width/height) of the
- controller in a Q3CheckListItem.
-
- \omitvalue PM_DialogButtonsSeparator
- \omitvalue PM_DialogButtonsButtonWidth
- \omitvalue PM_DialogButtonsButtonHeight
-
- \value PM_HeaderMarkSize The size of the sort indicator in a header.
- \value PM_HeaderGripMargin The size of the resize grip in a header.
- \value PM_HeaderMargin The size of the margin between the sort indicator and the text.
- \value PM_SpinBoxSliderHeight The height of the optional spin box slider.
-
- \value PM_ToolBarIconSize Default tool bar icon size
- \value PM_SmallIconSize Default small icon size
- \value PM_LargeIconSize Default large icon size
-
- \value PM_FocusFrameHMargin Horizontal margin that the focus frame will outset the widget by.
- \value PM_FocusFrameVMargin Vertical margin that the focus frame will outset the widget by.
- \value PM_IconViewIconSize The default size for icons in an icon view.
- \value PM_ListViewIconSize The default size for icons in a list view.
-
- \value PM_ToolTipLabelFrameWidth The frame width for a tool tip label.
- \value PM_CheckBoxLabelSpacing The spacing between a check box indicator and its label.
- \value PM_RadioButtonLabelSpacing The spacing between a radio button indicator and its label.
- \value PM_TabBarIconSize The default icon size for a tab bar.
- \value PM_SizeGripSize The size of a size grip.
- \value PM_MessageBoxIconSize The size of the standard icons in a message box
- \value PM_ButtonIconSize The default size of button icons
- \value PM_TextCursorWidth The width of the cursor in a line edit or text edit
- \value PM_TabBar_ScrollButtonOverlap The distance between the left and right buttons in a tab bar.
-
- \value PM_TabCloseIndicatorWidth The default width of a close button on a tab in a tab bar.
- \value PM_TabCloseIndicatorHeight The default height of a close button on a tab in a tab bar.
-
- \value PM_CustomBase Base value for custom pixel metrics. Custom
- values must be greater than this value.
-
- The following values are obsolete:
-
- \value PM_DefaultTopLevelMargin Use PM_LayoutLeftMargin,
- PM_LayoutTopMargin,
- PM_LayoutRightMargin, and
- PM_LayoutBottomMargin instead.
- \value PM_DefaultChildMargin Use PM_LayoutLeftMargin,
- PM_LayoutTopMargin,
- PM_LayoutRightMargin, and
- PM_LayoutBottomMargin instead.
- \value PM_DefaultLayoutSpacing Use PM_LayoutHorizontalSpacing
- and PM_LayoutVerticalSpacing
- instead.
-
- \value PM_ScrollView_ScrollBarSpacing Distance between frame and scrollbar
- with SH_ScrollView_FrameOnlyAroundContents set.
- \value PM_SubMenuOverlap The horizontal overlap between a submenu and its parent.
-
-
- \sa pixelMetric()
-*/
-
-/*!
- \fn int QStyle::pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const;
-
- Returns the value of the given pixel \a metric.
-
- The specified \a option and \a widget can be used for calculating
- the metric. In general, the \a widget argument is not used. The \a
- option can be cast to the appropriate type using the
- qstyleoption_cast() function. Note that the \a option may be zero
- even for PixelMetrics that can make use of it. See the table below
- for the appropriate \a option casts:
-
- \table
- \header \o Pixel Metric \o QStyleOption Subclass
- \row \o \l PM_SliderControlThickness \o \l QStyleOptionSlider
- \row \o \l PM_SliderLength \o \l QStyleOptionSlider
- \row \o \l PM_SliderTickmarkOffset \o \l QStyleOptionSlider
- \row \o \l PM_SliderSpaceAvailable \o \l QStyleOptionSlider
- \row \o \l PM_ScrollBarExtent \o \l QStyleOptionSlider
- \row \o \l PM_TabBarTabOverlap \o \l QStyleOptionTab
- \row \o \l PM_TabBarTabHSpace \o \l QStyleOptionTab
- \row \o \l PM_TabBarTabVSpace \o \l QStyleOptionTab
- \row \o \l PM_TabBarBaseHeight \o \l QStyleOptionTab
- \row \o \l PM_TabBarBaseOverlap \o \l QStyleOptionTab
- \endtable
-
- Some pixel metrics are called from widgets and some are only called
- internally by the style. If the metric is not called by a widget, it is the
- discretion of the style author to make use of it. For some styles, this
- may not be appropriate.
-*/
-
-/*!
- \enum QStyle::ContentsType
-
- This enum describes the available contents types. These are used to
- calculate sizes for the contents of various widgets.
-
- \value CT_CheckBox A check box, like QCheckBox.
- \value CT_ComboBox A combo box, like QComboBox.
- \omitvalue CT_DialogButtons
- \value CT_Q3DockWindow A Q3DockWindow.
- \value CT_HeaderSection A header section, like QHeader.
- \value CT_LineEdit A line edit, like QLineEdit.
- \value CT_Menu A menu, like QMenu.
- \value CT_Q3Header A Qt 3 header section, like Q3Header.
- \value CT_MenuBar A menu bar, like QMenuBar.
- \value CT_MenuBarItem A menu bar item, like the buttons in a QMenuBar.
- \value CT_MenuItem A menu item, like QMenuItem.
- \value CT_ProgressBar A progress bar, like QProgressBar.
- \value CT_PushButton A push button, like QPushButton.
- \value CT_RadioButton A radio button, like QRadioButton.
- \value CT_SizeGrip A size grip, like QSizeGrip.
- \value CT_Slider A slider, like QSlider.
- \value CT_ScrollBar A scroll bar, like QScrollBar.
- \value CT_SpinBox A spin box, like QSpinBox.
- \value CT_Splitter A splitter, like QSplitter.
- \value CT_TabBarTab A tab on a tab bar, like QTabBar.
- \value CT_TabWidget A tab widget, like QTabWidget.
- \value CT_ToolButton A tool button, like QToolButton.
- \value CT_GroupBox A group box, like QGroupBox.
- \value CT_ItemViewItem An item inside an item view.
-
- \value CT_CustomBase Base value for custom contents types.
- Custom values must be greater than this value.
-
- \value CT_MdiControls The minimize, normal, and close button
- in the menu bar for a maximized MDI
- subwindow.
-
- \sa sizeFromContents()
-*/
-
-/*!
- \fn QSize QStyle::sizeFromContents(ContentsType type, const QStyleOption *option, \
- const QSize &contentsSize, const QWidget *widget) const
-
- Returns the size of the element described by the specified
- \a option and \a type, based on the provided \a contentsSize.
-
- The \a option argument is a pointer to a QStyleOption or one of
- its subclasses. The \a option can be cast to the appropriate type
- using the qstyleoption_cast() function. The \a widget is an
- optional argument and can contain extra information used for
- calculating the size.
-
- See the table below for the appropriate \a option casts:
-
- \table
- \header \o Contents Type \o QStyleOption Subclass
- \row \o \l CT_PushButton \o \l QStyleOptionButton
- \row \o \l CT_CheckBox \o \l QStyleOptionButton
- \row \o \l CT_RadioButton \o \l QStyleOptionButton
- \row \o \l CT_ToolButton \o \l QStyleOptionToolButton
- \row \o \l CT_ComboBox \o \l QStyleOptionComboBox
- \row \o \l CT_Splitter \o \l QStyleOption
- \row \o \l CT_Q3DockWindow \o \l QStyleOptionQ3DockWindow
- \row \o \l CT_ProgressBar \o \l QStyleOptionProgressBar
- \row \o \l CT_MenuItem \o \l QStyleOptionMenuItem
- \endtable
-
- \sa ContentsType QStyleOption
-*/
-
-/*!
- \enum QStyle::RequestSoftwareInputPanel
-
- This enum describes under what circumstances a software input panel will be
- requested by input capable widgets.
-
- \value RSIP_OnMouseClickAndAlreadyFocused Requests an input panel if the user
- clicks on the widget, but only if it is already focused.
- \value RSIP_OnMouseClick Requests an input panel if the user clicks on the
- widget.
-
- \sa QEvent::RequestSoftwareInputPanel, QInputContext
-*/
-
-/*!
- \enum QStyle::StyleHint
-
- This enum describes the available style hints. A style hint is a general look
- and/or feel hint.
-
- \value SH_EtchDisabledText Disabled text is "etched" as it is on Windows.
-
- \value SH_DitherDisabledText Disabled text is dithered as it is on Motif.
-
- \value SH_GUIStyle The GUI style to use.
-
- \value SH_ScrollBar_ContextMenu Whether or not a scroll bar has a context menu.
-
- \value SH_ScrollBar_MiddleClickAbsolutePosition A boolean value.
- If true, middle clicking on a scroll bar causes the slider to
- jump to that position. If false, middle clicking is
- ignored.
-
- \value SH_ScrollBar_LeftClickAbsolutePosition A boolean value.
- If true, left clicking on a scroll bar causes the slider to
- jump to that position. If false, left clicking will
- behave as appropriate for each control.
-
- \value SH_ScrollBar_ScrollWhenPointerLeavesControl A boolean
- value. If true, when clicking a scroll bar SubControl, holding
- the mouse button down and moving the pointer outside the
- SubControl, the scroll bar continues to scroll. If false, the
- scollbar stops scrolling when the pointer leaves the
- SubControl.
-
- \value SH_ScrollBar_RollBetweenButtons A boolean value.
- If true, when clicking a scroll bar button (SC_ScrollBarAddLine or
- SC_ScrollBarSubLine) and dragging over to the opposite button (rolling)
- will press the new button and release the old one. When it is false, the
- original button is released and nothing happens (like a push button).
-
- \value SH_TabBar_Alignment The alignment for tabs in a
- QTabWidget. Possible values are Qt::AlignLeft,
- Qt::AlignCenter and Qt::AlignRight.
-
- \value SH_Header_ArrowAlignment The placement of the sorting
- indicator may appear in list or table headers. Possible values
- are Qt::Left or Qt::Right.
-
- \value SH_Slider_SnapToValue Sliders snap to values while moving,
- as they do on Windows.
-
- \value SH_Slider_SloppyKeyEvents Key presses handled in a sloppy
- manner, i.e., left on a vertical slider subtracts a line.
-
- \value SH_ProgressDialog_CenterCancelButton Center button on
- progress dialogs, like Motif, otherwise right aligned.
-
- \value SH_ProgressDialog_TextLabelAlignment The alignment for text
- labels in progress dialogs; Qt::AlignCenter on Windows,
- Qt::AlignVCenter otherwise.
-
- \value SH_PrintDialog_RightAlignButtons Right align buttons in
- the print dialog, as done on Windows.
-
- \value SH_MainWindow_SpaceBelowMenuBar One or two pixel space between
- the menu bar and the dockarea, as done on Windows.
-
- \value SH_FontDialog_SelectAssociatedText Select the text in the
- line edit, or when selecting an item from the listbox, or when
- the line edit receives focus, as done on Windows.
-
- \value SH_Menu_KeyboardSearch Typing causes a menu to be search
- for relevant items, otherwise only mnemnonic is considered.
-
- \value SH_Menu_AllowActiveAndDisabled Allows disabled menu
- items to be active.
-
- \value SH_Menu_SpaceActivatesItem Pressing the space bar activates
- the item, as done on Motif.
-
- \value SH_Menu_SubMenuPopupDelay The number of milliseconds
- to wait before opening a submenu (256 on Windows, 96 on Motif).
-
- \value SH_Menu_Scrollable Whether popup menus must support scrolling.
-
- \value SH_Menu_SloppySubMenus Whether popupmenu's must support
- sloppy submenu; as implemented on Mac OS.
-
- \value SH_ScrollView_FrameOnlyAroundContents Whether scrollviews
- draw their frame only around contents (like Motif), or around
- contents, scroll bars and corner widgets (like Windows).
-
- \value SH_MenuBar_AltKeyNavigation Menu bars items are navigable
- by pressing Alt, followed by using the arrow keys to select
- the desired item.
-
- \value SH_ComboBox_ListMouseTracking Mouse tracking in combobox
- drop-down lists.
-
- \value SH_Menu_MouseTracking Mouse tracking in popup menus.
-
- \value SH_MenuBar_MouseTracking Mouse tracking in menu bars.
-
- \value SH_Menu_FillScreenWithScroll Whether scrolling popups
- should fill the screen as they are scrolled.
-
- \value SH_Menu_SelectionWrap Whether popups should allow the selections
- to wrap, that is when selection should the next item be the first item.
-
- \value SH_ItemView_ChangeHighlightOnFocus Gray out selected items
- when losing focus.
-
- \value SH_Widget_ShareActivation Turn on sharing activation with
- floating modeless dialogs.
-
- \value SH_TabBar_SelectMouseType Which type of mouse event should
- cause a tab to be selected.
-
- \value SH_Q3ListViewExpand_SelectMouseType Which type of mouse event should
- cause a list view expansion to be selected.
-
- \value SH_TabBar_PreferNoArrows Whether a tab bar should suggest a size
- to prevent scoll arrows.
-
- \value SH_ComboBox_Popup Allows popups as a combobox drop-down
- menu.
-
- \value SH_Workspace_FillSpaceOnMaximize The workspace should
- maximize the client area.
-
- \value SH_TitleBar_NoBorder The title bar has no border.
-
- \value SH_ScrollBar_StopMouseOverSlider Obsolete. Use
- SH_Slider_StopMouseOverSlider instead.
-
- \value SH_Slider_StopMouseOverSlider Stops auto-repeat when
- the slider reaches the mouse position.
-
- \value SH_BlinkCursorWhenTextSelected Whether cursor should blink
- when text is selected.
-
- \value SH_RichText_FullWidthSelection Whether richtext selections
- should extend to the full width of the document.
-
- \value SH_GroupBox_TextLabelVerticalAlignment How to vertically align a
- group box's text label.
-
- \value SH_GroupBox_TextLabelColor How to paint a group box's text label.
-
- \value SH_DialogButtons_DefaultButton Which button gets the
- default status in a dialog's button widget.
-
- \value SH_ToolBox_SelectedPageTitleBold Boldness of the selected
- page title in a QToolBox.
-
- \value SH_LineEdit_PasswordCharacter The Unicode character to be
- used for passwords.
-
- \value SH_Table_GridLineColor The RGB value of the grid for a table.
-
- \value SH_UnderlineShortcut Whether shortcuts are underlined.
-
- \value SH_SpellCheckUnderlineStyle A
- QTextCharFormat::UnderlineStyle value that specifies the way
- misspelled words should be underlined.
-
- \value SH_SpinBox_AnimateButton Animate a click when up or down is
- pressed in a spin box.
- \value SH_SpinBox_KeyPressAutoRepeatRate Auto-repeat interval for
- spinbox key presses.
- \value SH_SpinBox_ClickAutoRepeatRate Auto-repeat interval for
- spinbox mouse clicks.
- \value SH_SpinBox_ClickAutoRepeatThreshold Auto-repeat threshold for
- spinbox mouse clicks.
- \value SH_ToolTipLabel_Opacity An integer indicating the opacity for
- the tip label, 0 is completely transparent, 255 is completely
- opaque.
- \value SH_DrawMenuBarSeparator Indicates whether or not the menu bar draws separators.
- \value SH_TitleBar_ModifyNotification Indicates if the title bar should show
- a '*' for windows that are modified.
-
- \value SH_Button_FocusPolicy The default focus policy for buttons.
-
- \value SH_CustomBase Base value for custom style hints.
- Custom values must be greater than this value.
-
- \value SH_MenuBar_DismissOnSecondClick A boolean indicating if a menu in
- the menu bar should be dismissed when it is clicked on a second time. (Example:
- Clicking and releasing on the File Menu in a menu bar and then
- immediately clicking on the File Menu again.)
-
- \value SH_MessageBox_UseBorderForButtonSpacing A boolean indicating what the to
- use the border of the buttons (computed as half the button height) for the spacing
- of the button in a message box.
-
- \value SH_MessageBox_CenterButtons A boolean indicating whether the buttons in the
- message box should be centered or not (see QDialogButtonBox::setCentered()).
-
- \value SH_MessageBox_TextInteractionFlags A boolean indicating if
- the text in a message box should allow user interfactions (e.g.
- selection) or not.
-
- \value SH_TitleBar_AutoRaise A boolean indicating whether
- controls on a title bar ought to update when the mouse is over them.
-
- \value SH_ToolButton_PopupDelay An int indicating the popup delay in milliseconds
- for menus attached to tool buttons.
-
- \value SH_FocusFrame_Mask The mask of the focus frame.
-
- \value SH_RubberBand_Mask The mask of the rubber band.
-
- \value SH_WindowFrame_Mask The mask of the window frame.
-
- \value SH_SpinControls_DisableOnBounds Determines if the spin controls will shown
- as disabled when reaching the spin range boundary.
-
- \value SH_Dial_BackgroundRole Defines the style's preferred
- background role (as QPalette::ColorRole) for a dial widget.
-
- \value SH_ScrollBar_BackgroundMode The background mode for a scroll bar.
-
- \value SH_ComboBox_LayoutDirection The layout direction for the
- combo box. By default it should be the same as indicated by the
- QStyleOption::direction variable.
-
- \value SH_ItemView_EllipsisLocation The location where ellipses should be
- added for item text that is too long to fit in an view item.
-
- \value SH_ItemView_ShowDecorationSelected When an item in an item
- view is selected, also highlight the branch or other decoration.
-
- \value SH_ItemView_ActivateItemOnSingleClick Emit the activated signal
- when the user single clicks on an item in an item in an item view.
- Otherwise the signal is emitted when the user double clicks on an item.
-
- \value SH_Slider_AbsoluteSetButtons Which mouse buttons cause a slider
- to set the value to the position clicked on.
-
- \value SH_Slider_PageSetButtons Which mouse buttons cause a slider
- to page step the value.
-
- \value SH_TabBar_ElideMode The default eliding style for a tab bar.
-
- \value SH_DialogButtonLayout Controls how buttons are laid out in a QDialogButtonBox, returns a QDialogButtonBox::ButtonLayout enum.
-
- \value SH_WizardStyle Controls the look and feel of a QWizard. Returns a QWizard::WizardStyle enum.
-
- \value SH_FormLayoutWrapPolicy Provides a default for how rows are wrapped in a QFormLayout. Returns a QFormLayout::RowWrapPolicy enum.
- \value SH_FormLayoutFieldGrowthPolicy Provides a default for how fields can grow in a QFormLayout. Returns a QFormLayout::FieldGrowthPolicy enum.
- \value SH_FormLayoutFormAlignment Provides a default for how a QFormLayout aligns its contents within the available space. Returns a Qt::Alignment enum.
- \value SH_FormLayoutLabelAlignment Provides a default for how a QFormLayout aligns labels within the available space. Returns a Qt::Alignment enum.
-
- \value SH_ItemView_ArrowKeysNavigateIntoChildren Controls whether the tree view will select the first child when it is exapanded and the right arrow key is pressed.
- \value SH_ComboBox_PopupFrameStyle The frame style used when drawing a combobox popup menu.
-
- \value SH_DialogButtonBox_ButtonsHaveIcons Indicates whether or not StandardButtons in QDialogButtonBox should have icons or not.
- \value SH_ItemView_MovementWithoutUpdatingSelection The item view is able to indicate a current item without changing the selection.
- \value SH_ToolTip_Mask The mask of a tool tip.
-
- \value SH_FocusFrame_AboveWidget The FocusFrame is stacked above the widget that it is "focusing on".
-
- \value SH_TextControl_FocusIndicatorTextCharFormat Specifies the text format used to highlight focused anchors in rich text
- documents displayed for example in QTextBrowser. The format has to be a QTextCharFormat returned in the variant of the
- QStyleHintReturnVariant return value. The QTextFormat::OutlinePen property is used for the outline and QTextFormat::BackgroundBrush
- for the background of the highlighted area.
-
- \value SH_Menu_FlashTriggeredItem Flash triggered item.
- \value SH_Menu_FadeOutOnHide Fade out the menu instead of hiding it immediately.
-
- \value SH_TabWidget_DefaultTabPosition Default position of the tab bar in a tab widget.
-
- \value SH_ToolBar_Movable Determines if the tool bar is movable by default.
-
- \value SH_ItemView_PaintAlternatingRowColorsForEmptyArea Whether QTreeView paints alternating row colors for the area that does not have any items.
-
- \value SH_Menu_Mask The mask for a popup menu.
-
- \value SH_ItemView_DrawDelegateFrame Determines if there should be a frame for a delegate widget.
-
- \value SH_TabBar_CloseButtonPosition Determines the position of the close button on a tab in a tab bar.
-
- \value SH_DockWidget_ButtonsHaveFrame Determines if dockwidget buttons should have frames. Default is true.
-
- \value SH_ToolButtonStyle Determines the default system style for tool buttons that uses Qt::ToolButtonFollowStyle.
-
- \value SH_RequestSoftwareInputPanel Determines when a software input panel should
- be requested by input widgets. Returns an enum of type QStyle::RequestSoftwareInputPanel.
-
- \omitvalue SH_UnderlineAccelerator
-
- \sa styleHint()
-*/
-
-/*!
- \fn int QStyle::styleHint(StyleHint hint, const QStyleOption *option, \
- const QWidget *widget, QStyleHintReturn *returnData) const
-
- Returns an integer representing the specified style \a hint for
- the given \a widget described by the provided style \a option.
-
- \a returnData is used when the querying widget needs more detailed data than
- the integer that styleHint() returns. See the QStyleHintReturn class
- description for details.
-*/
-
-/*!
- \enum QStyle::StandardPixmap
-
- This enum describes the available standard pixmaps. A standard pixmap is a pixmap that
- can follow some existing GUI style or guideline.
-
- \value SP_TitleBarMinButton Minimize button on title bars (e.g.,
- in QMdiSubWindow).
- \value SP_TitleBarMenuButton Menu button on a title bar.
- \value SP_TitleBarMaxButton Maximize button on title bars.
- \value SP_TitleBarCloseButton Close button on title bars.
- \value SP_TitleBarNormalButton Normal (restore) button on title bars.
- \value SP_TitleBarShadeButton Shade button on title bars.
- \value SP_TitleBarUnshadeButton Unshade button on title bars.
- \value SP_TitleBarContextHelpButton The Context help button on title bars.
- \value SP_MessageBoxInformation The "information" icon.
- \value SP_MessageBoxWarning The "warning" icon.
- \value SP_MessageBoxCritical The "critical" icon.
- \value SP_MessageBoxQuestion The "question" icon.
- \value SP_DesktopIcon The "desktop" icon.
- \value SP_TrashIcon The "trash" icon.
- \value SP_ComputerIcon The "My computer" icon.
- \value SP_DriveFDIcon The floppy icon.
- \value SP_DriveHDIcon The harddrive icon.
- \value SP_DriveCDIcon The CD icon.
- \value SP_DriveDVDIcon The DVD icon.
- \value SP_DriveNetIcon The network icon.
- \value SP_DirHomeIcon The home directory icon.
- \value SP_DirOpenIcon The open directory icon.
- \value SP_DirClosedIcon The closed directory icon.
- \value SP_DirIcon The directory icon.
- \value SP_DirLinkIcon The link to directory icon.
- \value SP_FileIcon The file icon.
- \value SP_FileLinkIcon The link to file icon.
- \value SP_FileDialogStart The "start" icon in a file dialog.
- \value SP_FileDialogEnd The "end" icon in a file dialog.
- \value SP_FileDialogToParent The "parent directory" icon in a file dialog.
- \value SP_FileDialogNewFolder The "create new folder" icon in a file dialog.
- \value SP_FileDialogDetailedView The detailed view icon in a file dialog.
- \value SP_FileDialogInfoView The file info icon in a file dialog.
- \value SP_FileDialogContentsView The contents view icon in a file dialog.
- \value SP_FileDialogListView The list view icon in a file dialog.
- \value SP_FileDialogBack The back arrow in a file dialog.
- \value SP_DockWidgetCloseButton Close button on dock windows (see also QDockWidget).
- \value SP_ToolBarHorizontalExtensionButton Extension button for horizontal toolbars.
- \value SP_ToolBarVerticalExtensionButton Extension button for vertical toolbars.
- \value SP_DialogOkButton Icon for a standard OK button in a QDialogButtonBox.
- \value SP_DialogCancelButton Icon for a standard Cancel button in a QDialogButtonBox.
- \value SP_DialogHelpButton Icon for a standard Help button in a QDialogButtonBox.
- \value SP_DialogOpenButton Icon for a standard Open button in a QDialogButtonBox.
- \value SP_DialogSaveButton Icon for a standard Save button in a QDialogButtonBox.
- \value SP_DialogCloseButton Icon for a standard Close button in a QDialogButtonBox.
- \value SP_DialogApplyButton Icon for a standard Apply button in a QDialogButtonBox.
- \value SP_DialogResetButton Icon for a standard Reset button in a QDialogButtonBox.
- \value SP_DialogDiscardButton Icon for a standard Discard button in a QDialogButtonBox.
- \value SP_DialogYesButton Icon for a standard Yes button in a QDialogButtonBox.
- \value SP_DialogNoButton Icon for a standard No button in a QDialogButtonBox.
- \value SP_ArrowUp Icon arrow pointing up.
- \value SP_ArrowDown Icon arrow pointing down.
- \value SP_ArrowLeft Icon arrow pointing left.
- \value SP_ArrowRight Icon arrow pointing right.
- \value SP_ArrowBack Equivalent to SP_ArrowLeft when the current layout direction is Qt::LeftToRight, otherwise SP_ArrowRight.
- \value SP_ArrowForward Equivalent to SP_ArrowRight when the current layout direction is Qt::LeftToRight, otherwise SP_ArrowLeft.
- \value SP_CommandLink Icon used to indicate a Vista style command link glyph.
- \value SP_VistaShield Icon used to indicate UAC prompts on Windows Vista. This will return a null pixmap or icon on all other platforms.
- \value SP_BrowserReload Icon indicating that the current page should be reloaded.
- \value SP_BrowserStop Icon indicating that the page loading should stop.
- \value SP_MediaPlay Icon indicating that media should begin playback.
- \value SP_MediaStop Icon indicating that media should stop playback.
- \value SP_MediaPause Icon indicating that media should pause playback.
- \value SP_MediaSkipForward Icon indicating that media should skip forward.
- \value SP_MediaSkipBackward Icon indicating that media should skip backward.
- \value SP_MediaSeekForward Icon indicating that media should seek forward.
- \value SP_MediaSeekBackward Icon indicating that media should seek backward.
- \value SP_MediaVolume Icon indicating a volume control.
- \value SP_MediaVolumeMuted Icon indicating a muted volume control.
- \value SP_CustomBase Base value for custom standard pixmaps;
- custom values must be greater than this value.
-
- \sa standardIcon()
-*/
-
-/*!
- \fn QPixmap QStyle::generatedIconPixmap(QIcon::Mode iconMode,
- const QPixmap &pixmap, const QStyleOption *option) const
-
- Returns a copy of the given \a pixmap, styled to conform to the
- specified \a iconMode and taking into account the palette
- specified by \a option.
-
- The \a option parameter can pass extra information, but
- it must contain a palette.
-
- Note that not all pixmaps will conform, in which case the returned
- pixmap is a plain copy.
-
- \sa QIcon
-*/
-
-/*!
- \fn QPixmap QStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *option, \
- const QWidget *widget) const
-
- \obsolete
- Returns a pixmap for the given \a standardPixmap.
-
- A standard pixmap is a pixmap that can follow some existing GUI
- style or guideline. The \a option argument can be used to pass
- extra information required when defining the appropriate
- pixmap. The \a widget argument is optional and can also be used to
- aid the determination of the pixmap.
-
- Developers calling standardPixmap() should instead call standardIcon()
- Developers who re-implemented standardPixmap() should instead re-implement
- the slot standardIconImplementation().
-
- \sa standardIcon()
-*/
-
-
-/*!
- \fn QRect QStyle::visualRect(Qt::LayoutDirection direction, const QRect &boundingRectangle, const QRect &logicalRectangle)
-
- Returns the given \a logicalRectangle converted to screen
- coordinates based on the specified \a direction. The \a
- boundingRectangle is used when performing the translation.
-
- This function is provided to support right-to-left desktops, and
- is typically used in implementations of the subControlRect()
- function.
-
- \sa QWidget::layoutDirection
-*/
-QRect QStyle::visualRect(Qt::LayoutDirection direction, const QRect &boundingRect, const QRect &logicalRect)
-{
- if (direction == Qt::LeftToRight)
- return logicalRect;
- QRect rect = logicalRect;
- rect.translate(2 * (boundingRect.right() - logicalRect.right()) +
- logicalRect.width() - boundingRect.width(), 0);
- return rect;
-}
-
-/*!
- \fn QPoint QStyle::visualPos(Qt::LayoutDirection direction, const QRect &boundingRectangle, const QPoint &logicalPosition)
-
- Returns the given \a logicalPosition converted to screen
- coordinates based on the specified \a direction. The \a
- boundingRectangle is used when performing the translation.
-
- \sa QWidget::layoutDirection
-*/
-QPoint QStyle::visualPos(Qt::LayoutDirection direction, const QRect &boundingRect, const QPoint &logicalPos)
-{
- if (direction == Qt::LeftToRight)
- return logicalPos;
- return QPoint(boundingRect.right() - logicalPos.x(), logicalPos.y());
-}
-
-/*!
- Returns a new rectangle of the specified \a size that is aligned to the given \a
- rectangle according to the specified \a alignment and \a direction.
- */
-QRect QStyle::alignedRect(Qt::LayoutDirection direction, Qt::Alignment alignment, const QSize &size, const QRect &rectangle)
-{
- alignment = visualAlignment(direction, alignment);
- int x = rectangle.x();
- int y = rectangle.y();
- int w = size.width();
- int h = size.height();
- if ((alignment & Qt::AlignVCenter) == Qt::AlignVCenter)
- y += rectangle.size().height()/2 - h/2;
- else if ((alignment & Qt::AlignBottom) == Qt::AlignBottom)
- y += rectangle.size().height() - h;
- if ((alignment & Qt::AlignRight) == Qt::AlignRight)
- x += rectangle.size().width() - w;
- else if ((alignment & Qt::AlignHCenter) == Qt::AlignHCenter)
- x += rectangle.size().width()/2 - w/2;
- return QRect(x, y, w, h);
-}
-
-/*!
- Transforms an \a alignment of Qt::AlignLeft or Qt::AlignRight
- without Qt::AlignAbsolute into Qt::AlignLeft or Qt::AlignRight with
- Qt::AlignAbsolute according to the layout \a direction. The other
- alignment flags are left untouched.
-
- If no horizontal alignment was specified, the function returns the
- default alignment for the given layout \a direction.
-
- QWidget::layoutDirection
-*/
-Qt::Alignment QStyle::visualAlignment(Qt::LayoutDirection direction, Qt::Alignment alignment)
-{
- if (!(alignment & Qt::AlignHorizontal_Mask))
- alignment |= Qt::AlignLeft;
- if ((alignment & Qt::AlignAbsolute) == 0 && (alignment & (Qt::AlignLeft | Qt::AlignRight))) {
- if (direction == Qt::RightToLeft)
- alignment ^= (Qt::AlignLeft | Qt::AlignRight);
- alignment |= Qt::AlignAbsolute;
- }
- return alignment;
-}
-
-/*!
- Converts the given \a logicalValue to a pixel position. The \a min
- parameter maps to 0, \a max maps to \a span and other values are
- distributed evenly in-between.
-
- This function can handle the entire integer range without
- overflow, providing that \a span is less than 4096.
-
- By default, this function assumes that the maximum value is on the
- right for horizontal items and on the bottom for vertical items.
- Set the \a upsideDown parameter to true to reverse this behavior.
-
- \sa sliderValueFromPosition()
-*/
-
-int QStyle::sliderPositionFromValue(int min, int max, int logicalValue, int span, bool upsideDown)
-{
- if (span <= 0 || logicalValue < min || max <= min)
- return 0;
- if (logicalValue > max)
- return upsideDown ? span : min;
-
- uint range = max - min;
- uint p = upsideDown ? max - logicalValue : logicalValue - min;
-
- if (range > (uint)INT_MAX/4096) {
- double dpos = (double(p))/(double(range)/span);
- return int(dpos);
- } else if (range > (uint)span) {
- return (2 * p * span + range) / (2*range);
- } else {
- uint div = span / range;
- uint mod = span % range;
- return p * div + (2 * p * mod + range) / (2 * range);
- }
- // equiv. to (p * span) / range + 0.5
- // no overflow because of this implicit assumption:
- // span <= 4096
-}
-
-/*!
- \fn int QStyle::sliderValueFromPosition(int min, int max, int position, int span, bool upsideDown)
-
- Converts the given pixel \a position to a logical value. 0 maps to
- the \a min parameter, \a span maps to \a max and other values are
- distributed evenly in-between.
-
- This function can handle the entire integer range without
- overflow.
-
- By default, this function assumes that the maximum value is on the
- right for horizontal items and on the bottom for vertical
- items. Set the \a upsideDown parameter to true to reverse this
- behavior.
-
- \sa sliderPositionFromValue()
-*/
-
-int QStyle::sliderValueFromPosition(int min, int max, int pos, int span, bool upsideDown)
-{
- if (span <= 0 || pos <= 0)
- return upsideDown ? max : min;
- if (pos >= span)
- return upsideDown ? min : max;
-
- uint range = max - min;
-
- if ((uint)span > range) {
- int tmp = (2 * pos * range + span) / (2 * span);
- return upsideDown ? max - tmp : tmp + min;
- } else {
- uint div = range / span;
- uint mod = range % span;
- int tmp = pos * div + (2 * pos * mod + span) / (2 * span);
- return upsideDown ? max - tmp : tmp + min;
- }
- // equiv. to min + (pos*range)/span + 0.5
- // no overflow because of this implicit assumption:
- // pos <= span < sqrt(INT_MAX+0.0625)+0.25 ~ sqrt(INT_MAX)
-}
-
-/*### \fn void QStyle::drawItem(QPainter *p, const QRect &r,
- int flags, const QColorGroup &colorgroup, bool enabled,
- const QString &text, int len = -1,
- const QColor *penColor = 0) const
-
- Use one of the drawItem() overloads that takes a QPalette instead
- of a QColorGroup.
-*/
-
-/*### \fn void QStyle::drawItem(QPainter *p, const QRect &r,
- int flags, const QColorGroup colorgroup, bool enabled,
- const QPixmap &pixmap,
- const QColor *penColor = 0) const
-
- Use one of the drawItem() overloads that takes a QPalette instead
- of a QColorGroup.
-*/
-
-/*### \fn void QStyle::drawItem(QPainter *p, const QRect &r,
- int flags, const QColorGroup colorgroup, bool enabled,
- const QPixmap *pixmap,
- const QString &text, int len = -1,
- const QColor *penColor = 0) const
-
- Use one of the drawItem() overloads that takes a QPalette instead
- of a QColorGroup.
-*/
-
-/*!
- Returns the style's standard palette.
-
- Note that on systems that support system colors, the style's
- standard palette is not used. In particular, the Windows XP,
- Vista, and Mac styles do not use the standard palette, but make
- use of native theme engines. With these styles, you should not set
- the palette with QApplication::setStandardPalette().
-
- */
-QPalette QStyle::standardPalette() const
-{
-#ifdef Q_WS_X11
- QColor background;
- if (QX11Info::appDepth() > 8)
- background = QColor(0xd4, 0xd0, 0xc8); // win 2000 grey
- else
- background = QColor(192, 192, 192);
-#else
- QColor background(0xd4, 0xd0, 0xc8); // win 2000 grey
-#endif
- QColor light(background.lighter());
- QColor dark(background.darker());
- QColor mid(Qt::gray);
- QPalette palette(Qt::black, background, light, dark, mid, Qt::black, Qt::white);
- palette.setBrush(QPalette::Disabled, QPalette::WindowText, dark);
- palette.setBrush(QPalette::Disabled, QPalette::Text, dark);
- palette.setBrush(QPalette::Disabled, QPalette::ButtonText, dark);
- palette.setBrush(QPalette::Disabled, QPalette::Base, background);
- return palette;
-}
-
-/*!
- \since 4.1
-
- Returns an icon for the given \a standardIcon.
-
- The \a standardIcon is a standard pixmap which can follow some
- existing GUI style or guideline. The \a option argument can be
- used to pass extra information required when defining the
- appropriate icon. The \a widget argument is optional and can also
- be used to aid the determination of the icon.
-
- \warning Because of binary compatibility constraints, this
- function is not virtual. If you want to provide your own icons in
- a QStyle subclass, reimplement the standardIconImplementation()
- slot in your subclass instead. The standardIcon() function will
- dynamically detect the slot and call it.
-
- \sa standardIconImplementation()
-*/
-QIcon QStyle::standardIcon(StandardPixmap standardIcon, const QStyleOption *option,
- const QWidget *widget) const
-{
- QIcon result;
- // ### Qt 4.1: invokeMethod should accept const functions, to avoid this dirty cast
- QMetaObject::invokeMethod(const_cast<QStyle*>(this),
- "standardIconImplementation", Qt::DirectConnection,
- Q_RETURN_ARG(QIcon, result),
- Q_ARG(StandardPixmap, standardIcon),
- Q_ARG(const QStyleOption*, option),
- Q_ARG(const QWidget*, widget));
- return result;
-}
-
-/*!
- \since 4.1
-
- Returns an icon for the given \a standardIcon.
-
- Reimplement this slot to provide your own icons in a QStyle
- subclass; because of binary compatibility constraints, the
- standardIcon() function (introduced in Qt 4.1) is not
- virtual. Instead, standardIcon() will dynamically detect and call
- \e this slot.
-
- The \a standardIcon is a standard pixmap which can follow some
- existing GUI style or guideline. The \a option argument can be
- used to pass extra information required when defining the
- appropriate icon. The \a widget argument is optional and can also
- be used to aid the determination of the icon.
-
- \sa standardIcon()
-*/
-QIcon QStyle::standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *option,
- const QWidget *widget) const
-{
- return QIcon(standardPixmap(standardIcon, option, widget));
-}
-
-/*!
- \since 4.3
-
- Returns the spacing that should be used between \a control1 and
- \a control2 in a layout. \a orientation specifies whether the
- controls are laid out side by side or stacked vertically. The \a
- option parameter can be used to pass extra information about the
- parent widget. The \a widget parameter is optional and can also
- be used if \a option is 0.
-
- This function is called by the layout system. It is used only if
- PM_LayoutHorizontalSpacing or PM_LayoutVerticalSpacing returns a
- negative value.
-
- For binary compatibility reasons, this function is not virtual.
- If you want to specify custom layout spacings in a QStyle
- subclass, implement a slot called layoutSpacingImplementation().
- QStyle will discover the slot at run-time (using Qt's
- \l{meta-object system}) and direct all calls to layoutSpacing()
- to layoutSpacingImplementation().
-
- \sa combinedLayoutSpacing(), layoutSpacingImplementation()
-*/
-int QStyle::layoutSpacing(QSizePolicy::ControlType control1, QSizePolicy::ControlType control2,
- Qt::Orientation orientation, const QStyleOption *option,
- const QWidget *widget) const
-{
- Q_D(const QStyle);
- if (d->layoutSpacingIndex == -1) {
- d->layoutSpacingIndex = metaObject()->indexOfMethod(
- "layoutSpacingImplementation(QSizePolicy::ControlType,QSizePolicy::ControlType,"
- "Qt::Orientation,const QStyleOption*,const QWidget*)"
- );
- }
- if (d->layoutSpacingIndex < 0)
- return -1;
- int result = -1;
- void *param[] = {&result, &control1, &control2, &orientation, &option, &widget};
-
- const_cast<QStyle *>(this)->qt_metacall(QMetaObject::InvokeMetaMethod,
- d->layoutSpacingIndex, param);
- return result;
-}
-
-/*!
- \since 4.3
-
- Returns the spacing that should be used between \a controls1 and
- \a controls2 in a layout. \a orientation specifies whether the
- controls are laid out side by side or stacked vertically. The \a
- option parameter can be used to pass extra information about the
- parent widget. The \a widget parameter is optional and can also
- be used if \a option is 0.
-
- \a controls1 and \a controls2 are OR-combination of zero or more
- \l{QSizePolicy::ControlTypes}{control types}.
-
- This function is called by the layout system. It is used only if
- PM_LayoutHorizontalSpacing or PM_LayoutVerticalSpacing returns a
- negative value.
-
- \sa layoutSpacing(), layoutSpacingImplementation()
-*/
-int QStyle::combinedLayoutSpacing(QSizePolicy::ControlTypes controls1,
- QSizePolicy::ControlTypes controls2, Qt::Orientation orientation,
- QStyleOption *option, QWidget *widget) const
-{
- QSizePolicy::ControlType array1[MaxBits];
- QSizePolicy::ControlType array2[MaxBits];
- int count1 = unpackControlTypes(controls1, array1);
- int count2 = unpackControlTypes(controls2, array2);
- int result = -1;
-
- for (int i = 0; i < count1; ++i) {
- for (int j = 0; j < count2; ++j) {
- int spacing = layoutSpacing(array1[i], array2[j], orientation, option, widget);
- result = qMax(spacing, result);
- }
- }
- return result;
-}
-
-/*!
- \since 4.3
-
- This slot is called by layoutSpacing() to determine the spacing
- that should be used between \a control1 and \a control2 in a
- layout. \a orientation specifies whether the controls are laid
- out side by side or stacked vertically. The \a option parameter
- can be used to pass extra information about the parent widget.
- The \a widget parameter is optional and can also be used if \a
- option is 0.
-
- If you want to provide custom layout spacings in a QStyle
- subclass, implement a slot called layoutSpacingImplementation()
- in your subclass. Be aware that this slot will only be called if
- PM_LayoutHorizontalSpacing or PM_LayoutVerticalSpacing returns a
- negative value.
-
- The default implementation returns -1.
-
- \sa layoutSpacing(), combinedLayoutSpacing()
-*/
-int QStyle::layoutSpacingImplementation(QSizePolicy::ControlType /* control1 */,
- QSizePolicy::ControlType /* control2 */,
- Qt::Orientation /*orientation*/,
- const QStyleOption * /* option */,
- const QWidget * /* widget */) const
-{
- return -1;
-}
-
-QT_BEGIN_INCLUDE_NAMESPACE
-#include <QDebug>
-QT_END_INCLUDE_NAMESPACE
-
-#if !defined(QT_NO_DEBUG_STREAM)
-QDebug operator<<(QDebug debug, QStyle::State state)
-{
-#if !defined(QT_NO_DEBUG)
- debug << "QStyle::State(";
-
- QStringList states;
- if (state & QStyle::State_Active) states << QLatin1String("Active");
- if (state & QStyle::State_AutoRaise) states << QLatin1String("AutoRaise");
- if (state & QStyle::State_Bottom) states << QLatin1String("Bottom");
- if (state & QStyle::State_Children) states << QLatin1String("Children");
- if (state & QStyle::State_DownArrow) states << QLatin1String("DownArrow");
- if (state & QStyle::State_Editing) states << QLatin1String("Editing");
- if (state & QStyle::State_Enabled) states << QLatin1String("Enabled");
- if (state & QStyle::State_FocusAtBorder) states << QLatin1String("FocusAtBorder");
- if (state & QStyle::State_HasFocus) states << QLatin1String("HasFocus");
- if (state & QStyle::State_Horizontal) states << QLatin1String("Horizontal");
- if (state & QStyle::State_Item) states << QLatin1String("Item");
- if (state & QStyle::State_KeyboardFocusChange) states << QLatin1String("KeyboardFocusChange");
- if (state & QStyle::State_MouseOver) states << QLatin1String("MouseOver");
- if (state & QStyle::State_NoChange) states << QLatin1String("NoChange");
- if (state & QStyle::State_Off) states << QLatin1String("Off");
- if (state & QStyle::State_On) states << QLatin1String("On");
- if (state & QStyle::State_Open) states << QLatin1String("Open");
- if (state & QStyle::State_Raised) states << QLatin1String("Raised");
- if (state & QStyle::State_ReadOnly) states << QLatin1String("ReadOnly");
- if (state & QStyle::State_Selected) states << QLatin1String("Selected");
- if (state & QStyle::State_Sibling) states << QLatin1String("Sibling");
- if (state & QStyle::State_Sunken) states << QLatin1String("Sunken");
- if (state & QStyle::State_Top) states << QLatin1String("Top");
- if (state & QStyle::State_UpArrow) states << QLatin1String("UpArrow");
-
- qSort(states);
- debug << states.join(QLatin1String(" | "));
- debug << ')';
-#else
- Q_UNUSED(state);
-#endif
- return debug;
-}
-#endif
-
-/*!
- \since 4.6
-
- \fn const QStyle *QStyle::proxy() const
-
- This function returns the current proxy for this style.
- By default most styles will return themselves. However
- when a proxy style is in use, it will allow the style to
- call back into its proxy.
-*/
-const QStyle * QStyle::proxy() const
-{
- Q_D(const QStyle);
- return d->proxyStyle;
-}
-
-/* \internal
-
- This function sets the base style that style calls will be
- redirected to. Note that ownership is not transferred.
-*/
-void QStyle::setProxy(QStyle *style)
-{
- Q_D(QStyle);
- d->proxyStyle = style;
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/styles/qstyle.h b/src/gui/styles/qstyle.h
deleted file mode 100644
index 452d750211..0000000000
--- a/src/gui/styles/qstyle.h
+++ /dev/null
@@ -1,889 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSTYLE_H
-#define QSTYLE_H
-
-#include <QtCore/qobject.h>
-#include <QtCore/qrect.h>
-#include <QtCore/qsize.h>
-#include <QtGui/qicon.h>
-#include <QtGui/qpixmap.h>
-#include <QtGui/qpalette.h>
-#include <QtGui/qsizepolicy.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QAction;
-class QDebug;
-class QTab;
-class QFontMetrics;
-class QStyleHintReturn;
-class QStyleOption;
-class QStyleOptionComplex;
-class QStylePrivate;
-
-class Q_GUI_EXPORT QStyle : public QObject
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QStyle)
-
-protected:
- QStyle(QStylePrivate &dd);
-
-public:
- QStyle();
- virtual ~QStyle();
-
- virtual void polish(QWidget *);
- virtual void unpolish(QWidget *);
-
- virtual void polish(QApplication *);
- virtual void unpolish(QApplication *);
-
- virtual void polish(QPalette &);
-
- virtual QRect itemTextRect(const QFontMetrics &fm, const QRect &r,
- int flags, bool enabled,
- const QString &text) const;
-
- virtual QRect itemPixmapRect(const QRect &r, int flags, const QPixmap &pixmap) const;
-
- virtual void drawItemText(QPainter *painter, const QRect &rect,
- int flags, const QPalette &pal, bool enabled,
- const QString &text, QPalette::ColorRole textRole = QPalette::NoRole) const;
-
- virtual void drawItemPixmap(QPainter *painter, const QRect &rect,
- int alignment, const QPixmap &pixmap) const;
-
- virtual QPalette standardPalette() const;
-
- enum StateFlag {
- State_None = 0x00000000,
-#ifdef QT3_SUPPORT
- State_Default = State_None,
-#endif
- State_Enabled = 0x00000001,
- State_Raised = 0x00000002,
- State_Sunken = 0x00000004,
- State_Off = 0x00000008,
- State_NoChange = 0x00000010,
- State_On = 0x00000020,
- State_DownArrow = 0x00000040,
- State_Horizontal = 0x00000080,
- State_HasFocus = 0x00000100,
- State_Top = 0x00000200,
- State_Bottom = 0x00000400,
- State_FocusAtBorder = 0x00000800,
- State_AutoRaise = 0x00001000,
- State_MouseOver = 0x00002000,
- State_UpArrow = 0x00004000,
- State_Selected = 0x00008000,
- State_Active = 0x00010000,
- State_Window = 0x00020000,
- State_Open = 0x00040000,
- State_Children = 0x00080000,
- State_Item = 0x00100000,
- State_Sibling = 0x00200000,
- State_Editing = 0x00400000,
- State_KeyboardFocusChange = 0x00800000,
-#ifdef QT_KEYPAD_NAVIGATION
- State_HasEditFocus = 0x01000000,
-#endif
- State_ReadOnly = 0x02000000,
- State_Small = 0x04000000,
- State_Mini = 0x08000000
- };
- Q_DECLARE_FLAGS(State, StateFlag)
-
-#ifdef QT3_SUPPORT
- typedef State SFlags;
-#endif
-
- enum PrimitiveElement {
- PE_Q3CheckListController,
- PE_Q3CheckListExclusiveIndicator,
- PE_Q3CheckListIndicator,
- PE_Q3DockWindowSeparator,
- PE_Q3Separator,
-
- PE_Frame,
- PE_FrameDefaultButton,
- PE_FrameDockWidget,
- PE_FrameFocusRect,
- PE_FrameGroupBox,
- PE_FrameLineEdit,
- PE_FrameMenu,
- PE_FrameStatusBar, // obsolete
- PE_FrameStatusBarItem = PE_FrameStatusBar,
- PE_FrameTabWidget,
- PE_FrameWindow,
- PE_FrameButtonBevel,
- PE_FrameButtonTool,
- PE_FrameTabBarBase,
-
- PE_PanelButtonCommand,
- PE_PanelButtonBevel,
- PE_PanelButtonTool,
- PE_PanelMenuBar,
- PE_PanelToolBar,
- PE_PanelLineEdit,
-
- PE_IndicatorArrowDown,
- PE_IndicatorArrowLeft,
- PE_IndicatorArrowRight,
- PE_IndicatorArrowUp,
- PE_IndicatorBranch,
- PE_IndicatorButtonDropDown,
- PE_IndicatorViewItemCheck,
- PE_IndicatorItemViewItemCheck = PE_IndicatorViewItemCheck,
- PE_IndicatorCheckBox,
- PE_IndicatorDockWidgetResizeHandle,
- PE_IndicatorHeaderArrow,
- PE_IndicatorMenuCheckMark,
- PE_IndicatorProgressChunk,
- PE_IndicatorRadioButton,
- PE_IndicatorSpinDown,
- PE_IndicatorSpinMinus,
- PE_IndicatorSpinPlus,
- PE_IndicatorSpinUp,
- PE_IndicatorToolBarHandle,
- PE_IndicatorToolBarSeparator,
- PE_PanelTipLabel,
- PE_IndicatorTabTear,
- PE_PanelScrollAreaCorner,
-
- PE_Widget,
-
- PE_IndicatorColumnViewArrow,
- PE_IndicatorItemViewItemDrop,
-
- PE_PanelItemViewItem,
- PE_PanelItemViewRow, // ### Qt 5: remove
-
- PE_PanelStatusBar,
-
- PE_IndicatorTabClose,
- PE_PanelMenu,
-
- // do not add any values below/greater this
- PE_CustomBase = 0xf000000
- };
-
- virtual void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p,
- const QWidget *w = 0) const = 0;
- enum ControlElement {
- CE_PushButton,
- CE_PushButtonBevel,
- CE_PushButtonLabel,
-
- CE_CheckBox,
- CE_CheckBoxLabel,
-
- CE_RadioButton,
- CE_RadioButtonLabel,
-
- CE_TabBarTab,
- CE_TabBarTabShape,
- CE_TabBarTabLabel,
-
- CE_ProgressBar,
- CE_ProgressBarGroove,
- CE_ProgressBarContents,
- CE_ProgressBarLabel,
-
- CE_MenuItem,
- CE_MenuScroller,
- CE_MenuVMargin,
- CE_MenuHMargin,
- CE_MenuTearoff,
- CE_MenuEmptyArea,
-
- CE_MenuBarItem,
- CE_MenuBarEmptyArea,
-
- CE_ToolButtonLabel,
-
- CE_Header,
- CE_HeaderSection,
- CE_HeaderLabel,
-
- CE_Q3DockWindowEmptyArea,
- CE_ToolBoxTab,
- CE_SizeGrip,
- CE_Splitter,
- CE_RubberBand,
- CE_DockWidgetTitle,
-
- CE_ScrollBarAddLine,
- CE_ScrollBarSubLine,
- CE_ScrollBarAddPage,
- CE_ScrollBarSubPage,
- CE_ScrollBarSlider,
- CE_ScrollBarFirst,
- CE_ScrollBarLast,
-
- CE_FocusFrame,
- CE_ComboBoxLabel,
-
- CE_ToolBar,
- CE_ToolBoxTabShape,
- CE_ToolBoxTabLabel,
- CE_HeaderEmptyArea,
-
- CE_ColumnViewGrip,
-
- CE_ItemViewItem,
-
- CE_ShapedFrame,
-
- // do not add any values below/greater than this
- CE_CustomBase = 0xf0000000
- };
-
- virtual void drawControl(ControlElement element, const QStyleOption *opt, QPainter *p,
- const QWidget *w = 0) const = 0;
-
- enum SubElement {
- SE_PushButtonContents,
- SE_PushButtonFocusRect,
-
- SE_CheckBoxIndicator,
- SE_CheckBoxContents,
- SE_CheckBoxFocusRect,
- SE_CheckBoxClickRect,
-
- SE_RadioButtonIndicator,
- SE_RadioButtonContents,
- SE_RadioButtonFocusRect,
- SE_RadioButtonClickRect,
-
- SE_ComboBoxFocusRect,
-
- SE_SliderFocusRect,
-
- SE_Q3DockWindowHandleRect,
-
- SE_ProgressBarGroove,
- SE_ProgressBarContents,
- SE_ProgressBarLabel,
-
- // ### Qt 5: These values are unused; eliminate them
- SE_DialogButtonAccept,
- SE_DialogButtonReject,
- SE_DialogButtonApply,
- SE_DialogButtonHelp,
- SE_DialogButtonAll,
- SE_DialogButtonAbort,
- SE_DialogButtonIgnore,
- SE_DialogButtonRetry,
- SE_DialogButtonCustom,
-
- SE_ToolBoxTabContents,
-
- SE_HeaderLabel,
- SE_HeaderArrow,
-
- SE_TabWidgetTabBar,
- SE_TabWidgetTabPane,
- SE_TabWidgetTabContents,
- SE_TabWidgetLeftCorner,
- SE_TabWidgetRightCorner,
-
- SE_ViewItemCheckIndicator,
- SE_ItemViewItemCheckIndicator = SE_ViewItemCheckIndicator,
-
- SE_TabBarTearIndicator,
-
- SE_TreeViewDisclosureItem,
-
- SE_LineEditContents,
- SE_FrameContents,
-
- SE_DockWidgetCloseButton,
- SE_DockWidgetFloatButton,
- SE_DockWidgetTitleBarText,
- SE_DockWidgetIcon,
-
- SE_CheckBoxLayoutItem,
- SE_ComboBoxLayoutItem,
- SE_DateTimeEditLayoutItem,
- SE_DialogButtonBoxLayoutItem, // ### remove
- SE_LabelLayoutItem,
- SE_ProgressBarLayoutItem,
- SE_PushButtonLayoutItem,
- SE_RadioButtonLayoutItem,
- SE_SliderLayoutItem,
- SE_SpinBoxLayoutItem,
- SE_ToolButtonLayoutItem,
-
- SE_FrameLayoutItem,
- SE_GroupBoxLayoutItem,
- SE_TabWidgetLayoutItem,
-
- SE_ItemViewItemDecoration,
- SE_ItemViewItemText,
- SE_ItemViewItemFocusRect,
-
- SE_TabBarTabLeftButton,
- SE_TabBarTabRightButton,
- SE_TabBarTabText,
-
- SE_ShapedFrameContents,
-
- SE_ToolBarHandle,
-
- // do not add any values below/greater than this
- SE_CustomBase = 0xf0000000
- };
-
- virtual QRect subElementRect(SubElement subElement, const QStyleOption *option,
- const QWidget *widget = 0) const = 0;
-
-
- enum ComplexControl {
- CC_SpinBox,
- CC_ComboBox,
- CC_ScrollBar,
- CC_Slider,
- CC_ToolButton,
- CC_TitleBar,
- CC_Q3ListView,
- CC_Dial,
- CC_GroupBox,
- CC_MdiControls,
-
- // do not add any values below/greater than this
- CC_CustomBase = 0xf0000000
- };
-
- enum SubControl {
- SC_None = 0x00000000,
-
- SC_ScrollBarAddLine = 0x00000001,
- SC_ScrollBarSubLine = 0x00000002,
- SC_ScrollBarAddPage = 0x00000004,
- SC_ScrollBarSubPage = 0x00000008,
- SC_ScrollBarFirst = 0x00000010,
- SC_ScrollBarLast = 0x00000020,
- SC_ScrollBarSlider = 0x00000040,
- SC_ScrollBarGroove = 0x00000080,
-
- SC_SpinBoxUp = 0x00000001,
- SC_SpinBoxDown = 0x00000002,
- SC_SpinBoxFrame = 0x00000004,
- SC_SpinBoxEditField = 0x00000008,
-
- SC_ComboBoxFrame = 0x00000001,
- SC_ComboBoxEditField = 0x00000002,
- SC_ComboBoxArrow = 0x00000004,
- SC_ComboBoxListBoxPopup = 0x00000008,
-
- SC_SliderGroove = 0x00000001,
- SC_SliderHandle = 0x00000002,
- SC_SliderTickmarks = 0x00000004,
-
- SC_ToolButton = 0x00000001,
- SC_ToolButtonMenu = 0x00000002,
-
- SC_TitleBarSysMenu = 0x00000001,
- SC_TitleBarMinButton = 0x00000002,
- SC_TitleBarMaxButton = 0x00000004,
- SC_TitleBarCloseButton = 0x00000008,
- SC_TitleBarNormalButton = 0x00000010,
- SC_TitleBarShadeButton = 0x00000020,
- SC_TitleBarUnshadeButton = 0x00000040,
- SC_TitleBarContextHelpButton = 0x00000080,
- SC_TitleBarLabel = 0x00000100,
-
- SC_Q3ListView = 0x00000001,
- SC_Q3ListViewBranch = 0x00000002,
- SC_Q3ListViewExpand = 0x00000004,
-
- SC_DialGroove = 0x00000001,
- SC_DialHandle = 0x00000002,
- SC_DialTickmarks = 0x00000004,
-
- SC_GroupBoxCheckBox = 0x00000001,
- SC_GroupBoxLabel = 0x00000002,
- SC_GroupBoxContents = 0x00000004,
- SC_GroupBoxFrame = 0x00000008,
-
- SC_MdiMinButton = 0x00000001,
- SC_MdiNormalButton = 0x00000002,
- SC_MdiCloseButton = 0x00000004,
-
- SC_CustomBase = 0xf0000000,
- SC_All = 0xffffffff
- };
- Q_DECLARE_FLAGS(SubControls, SubControl)
-
-#ifdef QT3_SUPPORT
- typedef SubControls SCFlags;
-#endif
-
- virtual void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p,
- const QWidget *widget = 0) const = 0;
- virtual SubControl hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt,
- const QPoint &pt, const QWidget *widget = 0) const = 0;
- virtual QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt,
- SubControl sc, const QWidget *widget = 0) const = 0;
-
- enum PixelMetric {
- PM_ButtonMargin,
- PM_ButtonDefaultIndicator,
- PM_MenuButtonIndicator,
- PM_ButtonShiftHorizontal,
- PM_ButtonShiftVertical,
-
- PM_DefaultFrameWidth,
- PM_SpinBoxFrameWidth,
- PM_ComboBoxFrameWidth,
-
- PM_MaximumDragDistance,
-
- PM_ScrollBarExtent,
- PM_ScrollBarSliderMin,
-
- PM_SliderThickness, // total slider thickness
- PM_SliderControlThickness, // thickness of the business part
- PM_SliderLength, // total length of slider
- PM_SliderTickmarkOffset, //
- PM_SliderSpaceAvailable, // available space for slider to move
-
- PM_DockWidgetSeparatorExtent,
- PM_DockWidgetHandleExtent,
- PM_DockWidgetFrameWidth,
-
- PM_TabBarTabOverlap,
- PM_TabBarTabHSpace,
- PM_TabBarTabVSpace,
- PM_TabBarBaseHeight,
- PM_TabBarBaseOverlap,
-
- PM_ProgressBarChunkWidth,
-
- PM_SplitterWidth,
- PM_TitleBarHeight,
-
- PM_MenuScrollerHeight,
- PM_MenuHMargin,
- PM_MenuVMargin,
- PM_MenuPanelWidth,
- PM_MenuTearoffHeight,
- PM_MenuDesktopFrameWidth,
-
- PM_MenuBarPanelWidth,
- PM_MenuBarItemSpacing,
- PM_MenuBarVMargin,
- PM_MenuBarHMargin,
-
- PM_IndicatorWidth,
- PM_IndicatorHeight,
- PM_ExclusiveIndicatorWidth,
- PM_ExclusiveIndicatorHeight,
- PM_CheckListButtonSize,
- PM_CheckListControllerSize,
-
- PM_DialogButtonsSeparator,
- PM_DialogButtonsButtonWidth,
- PM_DialogButtonsButtonHeight,
-
- PM_MdiSubWindowFrameWidth,
- PM_MDIFrameWidth = PM_MdiSubWindowFrameWidth, //obsolete
- PM_MdiSubWindowMinimizedWidth,
- PM_MDIMinimizedWidth = PM_MdiSubWindowMinimizedWidth, //obsolete
-
- PM_HeaderMargin,
- PM_HeaderMarkSize,
- PM_HeaderGripMargin,
- PM_TabBarTabShiftHorizontal,
- PM_TabBarTabShiftVertical,
- PM_TabBarScrollButtonWidth,
-
- PM_ToolBarFrameWidth,
- PM_ToolBarHandleExtent,
- PM_ToolBarItemSpacing,
- PM_ToolBarItemMargin,
- PM_ToolBarSeparatorExtent,
- PM_ToolBarExtensionExtent,
-
- PM_SpinBoxSliderHeight,
-
- PM_DefaultTopLevelMargin,
- PM_DefaultChildMargin,
- PM_DefaultLayoutSpacing,
-
- PM_ToolBarIconSize,
- PM_ListViewIconSize,
- PM_IconViewIconSize,
- PM_SmallIconSize,
- PM_LargeIconSize,
-
- PM_FocusFrameVMargin,
- PM_FocusFrameHMargin,
-
- PM_ToolTipLabelFrameWidth,
- PM_CheckBoxLabelSpacing,
- PM_TabBarIconSize,
- PM_SizeGripSize,
- PM_DockWidgetTitleMargin,
- PM_MessageBoxIconSize,
- PM_ButtonIconSize,
-
- PM_DockWidgetTitleBarButtonMargin,
-
- PM_RadioButtonLabelSpacing,
- PM_LayoutLeftMargin,
- PM_LayoutTopMargin,
- PM_LayoutRightMargin,
- PM_LayoutBottomMargin,
- PM_LayoutHorizontalSpacing,
- PM_LayoutVerticalSpacing,
- PM_TabBar_ScrollButtonOverlap,
-
- PM_TextCursorWidth,
-
- PM_TabCloseIndicatorWidth,
- PM_TabCloseIndicatorHeight,
-
- PM_ScrollView_ScrollBarSpacing,
- PM_SubMenuOverlap,
-
- // do not add any values below/greater than this
- PM_CustomBase = 0xf0000000
- };
-
- virtual int pixelMetric(PixelMetric metric, const QStyleOption *option = 0,
- const QWidget *widget = 0) const = 0;
-
- enum ContentsType {
- CT_PushButton,
- CT_CheckBox,
- CT_RadioButton,
- CT_ToolButton,
- CT_ComboBox,
- CT_Splitter,
- CT_Q3DockWindow,
- CT_ProgressBar,
- CT_MenuItem,
- CT_MenuBarItem,
- CT_MenuBar,
- CT_Menu,
- CT_TabBarTab,
- CT_Slider,
- CT_ScrollBar,
- CT_Q3Header,
- CT_LineEdit,
- CT_SpinBox,
- CT_SizeGrip,
- CT_TabWidget,
- CT_DialogButtons,
- CT_HeaderSection,
- CT_GroupBox,
- CT_MdiControls,
- CT_ItemViewItem,
- // do not add any values below/greater than this
- CT_CustomBase = 0xf0000000
- };
-
- virtual QSize sizeFromContents(ContentsType ct, const QStyleOption *opt,
- const QSize &contentsSize, const QWidget *w = 0) const = 0;
-
- enum RequestSoftwareInputPanel {
- RSIP_OnMouseClickAndAlreadyFocused,
- RSIP_OnMouseClick
- };
-
- enum StyleHint {
- SH_EtchDisabledText,
- SH_DitherDisabledText,
- SH_ScrollBar_MiddleClickAbsolutePosition,
- SH_ScrollBar_ScrollWhenPointerLeavesControl,
- SH_TabBar_SelectMouseType,
- SH_TabBar_Alignment,
- SH_Header_ArrowAlignment,
- SH_Slider_SnapToValue,
- SH_Slider_SloppyKeyEvents,
- SH_ProgressDialog_CenterCancelButton,
- SH_ProgressDialog_TextLabelAlignment,
- SH_PrintDialog_RightAlignButtons,
- SH_MainWindow_SpaceBelowMenuBar,
- SH_FontDialog_SelectAssociatedText,
- SH_Menu_AllowActiveAndDisabled,
- SH_Menu_SpaceActivatesItem,
- SH_Menu_SubMenuPopupDelay,
- SH_ScrollView_FrameOnlyAroundContents,
- SH_MenuBar_AltKeyNavigation,
- SH_ComboBox_ListMouseTracking,
- SH_Menu_MouseTracking,
- SH_MenuBar_MouseTracking,
- SH_ItemView_ChangeHighlightOnFocus,
- SH_Widget_ShareActivation,
- SH_Workspace_FillSpaceOnMaximize,
- SH_ComboBox_Popup,
- SH_TitleBar_NoBorder,
- SH_Slider_StopMouseOverSlider,
- SH_ScrollBar_StopMouseOverSlider = SH_Slider_StopMouseOverSlider, // obsolete
- SH_BlinkCursorWhenTextSelected,
- SH_RichText_FullWidthSelection,
- SH_Menu_Scrollable,
- SH_GroupBox_TextLabelVerticalAlignment,
- SH_GroupBox_TextLabelColor,
- SH_Menu_SloppySubMenus,
- SH_Table_GridLineColor,
- SH_LineEdit_PasswordCharacter,
- SH_DialogButtons_DefaultButton,
- SH_ToolBox_SelectedPageTitleBold,
- SH_TabBar_PreferNoArrows,
- SH_ScrollBar_LeftClickAbsolutePosition,
- SH_Q3ListViewExpand_SelectMouseType,
- SH_UnderlineShortcut,
- SH_SpinBox_AnimateButton,
- SH_SpinBox_KeyPressAutoRepeatRate,
- SH_SpinBox_ClickAutoRepeatRate,
- SH_Menu_FillScreenWithScroll,
- SH_ToolTipLabel_Opacity,
- SH_DrawMenuBarSeparator,
- SH_TitleBar_ModifyNotification,
- SH_Button_FocusPolicy,
- SH_MenuBar_DismissOnSecondClick,
- SH_MessageBox_UseBorderForButtonSpacing,
- SH_TitleBar_AutoRaise,
- SH_ToolButton_PopupDelay,
- SH_FocusFrame_Mask,
- SH_RubberBand_Mask,
- SH_WindowFrame_Mask,
- SH_SpinControls_DisableOnBounds,
- SH_Dial_BackgroundRole,
- SH_ComboBox_LayoutDirection,
- SH_ItemView_EllipsisLocation,
- SH_ItemView_ShowDecorationSelected,
- SH_ItemView_ActivateItemOnSingleClick,
- SH_ScrollBar_ContextMenu,
- SH_ScrollBar_RollBetweenButtons,
- SH_Slider_AbsoluteSetButtons,
- SH_Slider_PageSetButtons,
- SH_Menu_KeyboardSearch,
- SH_TabBar_ElideMode,
- SH_DialogButtonLayout,
- SH_ComboBox_PopupFrameStyle,
- SH_MessageBox_TextInteractionFlags,
- SH_DialogButtonBox_ButtonsHaveIcons,
- SH_SpellCheckUnderlineStyle,
- SH_MessageBox_CenterButtons,
- SH_Menu_SelectionWrap,
- SH_ItemView_MovementWithoutUpdatingSelection,
- SH_ToolTip_Mask,
- SH_FocusFrame_AboveWidget,
- SH_TextControl_FocusIndicatorTextCharFormat,
- SH_WizardStyle,
- SH_ItemView_ArrowKeysNavigateIntoChildren,
- SH_Menu_Mask,
- SH_Menu_FlashTriggeredItem,
- SH_Menu_FadeOutOnHide,
- SH_SpinBox_ClickAutoRepeatThreshold,
- SH_ItemView_PaintAlternatingRowColorsForEmptyArea,
- SH_FormLayoutWrapPolicy,
- SH_TabWidget_DefaultTabPosition,
- SH_ToolBar_Movable,
- SH_FormLayoutFieldGrowthPolicy,
- SH_FormLayoutFormAlignment,
- SH_FormLayoutLabelAlignment,
- SH_ItemView_DrawDelegateFrame,
- SH_TabBar_CloseButtonPosition,
- SH_DockWidget_ButtonsHaveFrame,
- SH_ToolButtonStyle,
- SH_RequestSoftwareInputPanel,
- // Add new style hint values here
-
-#ifdef QT3_SUPPORT
- SH_GUIStyle = 0x00000100,
- SH_ScrollBar_BackgroundMode,
- // Add other compat values here
-
- SH_UnderlineAccelerator = SH_UnderlineShortcut,
-#endif
- SH_CustomBase = 0xf0000000
- };
-
- virtual int styleHint(StyleHint stylehint, const QStyleOption *opt = 0,
- const QWidget *widget = 0, QStyleHintReturn* returnData = 0) const = 0;
-
- enum StandardPixmap {
- SP_TitleBarMenuButton,
- SP_TitleBarMinButton,
- SP_TitleBarMaxButton,
- SP_TitleBarCloseButton,
- SP_TitleBarNormalButton,
- SP_TitleBarShadeButton,
- SP_TitleBarUnshadeButton,
- SP_TitleBarContextHelpButton,
- SP_DockWidgetCloseButton,
- SP_MessageBoxInformation,
- SP_MessageBoxWarning,
- SP_MessageBoxCritical,
- SP_MessageBoxQuestion,
- SP_DesktopIcon,
- SP_TrashIcon,
- SP_ComputerIcon,
- SP_DriveFDIcon,
- SP_DriveHDIcon,
- SP_DriveCDIcon,
- SP_DriveDVDIcon,
- SP_DriveNetIcon,
- SP_DirOpenIcon,
- SP_DirClosedIcon,
- SP_DirLinkIcon,
- SP_FileIcon,
- SP_FileLinkIcon,
- SP_ToolBarHorizontalExtensionButton,
- SP_ToolBarVerticalExtensionButton,
- SP_FileDialogStart,
- SP_FileDialogEnd,
- SP_FileDialogToParent,
- SP_FileDialogNewFolder,
- SP_FileDialogDetailedView,
- SP_FileDialogInfoView,
- SP_FileDialogContentsView,
- SP_FileDialogListView,
- SP_FileDialogBack,
- SP_DirIcon,
- SP_DialogOkButton,
- SP_DialogCancelButton,
- SP_DialogHelpButton,
- SP_DialogOpenButton,
- SP_DialogSaveButton,
- SP_DialogCloseButton,
- SP_DialogApplyButton,
- SP_DialogResetButton,
- SP_DialogDiscardButton,
- SP_DialogYesButton,
- SP_DialogNoButton,
- SP_ArrowUp,
- SP_ArrowDown,
- SP_ArrowLeft,
- SP_ArrowRight,
- SP_ArrowBack,
- SP_ArrowForward,
- SP_DirHomeIcon,
- SP_CommandLink,
- SP_VistaShield,
- SP_BrowserReload,
- SP_BrowserStop,
- SP_MediaPlay,
- SP_MediaStop,
- SP_MediaPause,
- SP_MediaSkipForward,
- SP_MediaSkipBackward,
- SP_MediaSeekForward,
- SP_MediaSeekBackward,
- SP_MediaVolume,
- SP_MediaVolumeMuted,
- // do not add any values below/greater than this
- SP_CustomBase = 0xf0000000
- };
-
- virtual QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt = 0,
- const QWidget *widget = 0) const = 0;
-
- QIcon standardIcon(StandardPixmap standardIcon, const QStyleOption *option = 0,
- const QWidget *widget = 0) const;
-
- virtual QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap,
- const QStyleOption *opt) const = 0;
-
- static QRect visualRect(Qt::LayoutDirection direction, const QRect &boundingRect,
- const QRect &logicalRect);
- static QPoint visualPos(Qt::LayoutDirection direction, const QRect &boundingRect,
- const QPoint &logicalPos);
- static int sliderPositionFromValue(int min, int max, int val, int space,
- bool upsideDown = false);
- static int sliderValueFromPosition(int min, int max, int pos, int space,
- bool upsideDown = false);
- static Qt::Alignment visualAlignment(Qt::LayoutDirection direction, Qt::Alignment alignment);
- static QRect alignedRect(Qt::LayoutDirection direction, Qt::Alignment alignment,
- const QSize &size, const QRect &rectangle);
-
- int layoutSpacing(QSizePolicy::ControlType control1,
- QSizePolicy::ControlType control2, Qt::Orientation orientation,
- const QStyleOption *option = 0, const QWidget *widget = 0) const;
- int combinedLayoutSpacing(QSizePolicy::ControlTypes controls1,
- QSizePolicy::ControlTypes controls2, Qt::Orientation orientation,
- QStyleOption *option = 0, QWidget *widget = 0) const;
-
- const QStyle * proxy() const;
-
-protected Q_SLOTS:
- QIcon standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *opt = 0,
- const QWidget *widget = 0) const;
- int layoutSpacingImplementation(QSizePolicy::ControlType control1,
- QSizePolicy::ControlType control2,
- Qt::Orientation orientation,
- const QStyleOption *option = 0,
- const QWidget *widget = 0) const;
-
-private:
- Q_DISABLE_COPY(QStyle)
- friend class QWidget;
- friend class QWidgetPrivate;
- friend class QApplication;
- friend class QProxyStyle;
- friend class QProxyStylePrivate;
- void setProxy(QStyle *style);
-};
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QStyle::State)
-Q_DECLARE_OPERATORS_FOR_FLAGS(QStyle::SubControls)
-
-#if !defined(QT_NO_DEBUG_STREAM)
-Q_GUI_EXPORT QDebug operator<<(QDebug debug, QStyle::State state);
-#endif
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QSTYLE_H
diff --git a/src/gui/styles/qstyle_p.h b/src/gui/styles/qstyle_p.h
deleted file mode 100644
index 09d79f255a..0000000000
--- a/src/gui/styles/qstyle_p.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSTYLE_P_H
-#define QSTYLE_P_H
-
-#include "private/qobject_p.h"
-#include <QtGui/qstyle.h>
-
-QT_BEGIN_NAMESPACE
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of qstyle_*.cpp. This header file may change from version to version
-// without notice, or even be removed.
-//
-// We mean it.
-//
-
-// Private class
-
-class QStyle;
-
-class QStylePrivate: public QObjectPrivate
-{
- Q_DECLARE_PUBLIC(QStyle)
-public:
- inline QStylePrivate()
- : layoutSpacingIndex(-1), proxyStyle(0) {}
- mutable int layoutSpacingIndex;
- QStyle *proxyStyle;
-};
-
-
-#define BEGIN_STYLE_PIXMAPCACHE(a) \
- QRect rect = option->rect; \
- QPixmap internalPixmapCache; \
- QImage imageCache; \
- QPainter *p = painter; \
- QString unique = QStyleHelper::uniqueName((a), option, option->rect.size()); \
- int txType = painter->deviceTransform().type() | painter->worldTransform().type(); \
- bool doPixmapCache = txType <= QTransform::TxTranslate; \
- if (doPixmapCache && QPixmapCache::find(unique, internalPixmapCache)) { \
- painter->drawPixmap(option->rect.topLeft(), internalPixmapCache); \
- } else { \
- if (doPixmapCache) { \
- rect.setRect(0, 0, option->rect.width(), option->rect.height()); \
- imageCache = QImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied); \
- imageCache.fill(0); \
- p = new QPainter(&imageCache); \
- }
-
-
-
-#define END_STYLE_PIXMAPCACHE \
- if (doPixmapCache) { \
- p->end(); \
- delete p; \
- internalPixmapCache = QPixmap::fromImage(imageCache); \
- painter->drawPixmap(option->rect.topLeft(), internalPixmapCache); \
- QPixmapCache::insert(unique, internalPixmapCache); \
- } \
- }
-
-QT_END_NAMESPACE
-
-#endif //QSTYLE_P_H
diff --git a/src/gui/styles/qstylefactory.h b/src/gui/styles/qstylefactory.h
deleted file mode 100644
index 92bd24fddb..0000000000
--- a/src/gui/styles/qstylefactory.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSTYLEFACTORY_H
-#define QSTYLEFACTORY_H
-
-#include <QtCore/qstringlist.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QStyle;
-
-class Q_GUI_EXPORT QStyleFactory
-{
-public:
- static QStringList keys();
- static QStyle *create(const QString&);
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QSTYLEFACTORY_H
diff --git a/src/gui/styles/qstylehelper_p.h b/src/gui/styles/qstylehelper_p.h
deleted file mode 100644
index a5959e7afc..0000000000
--- a/src/gui/styles/qstylehelper_p.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtCore/qglobal.h>
-#include <QtCore/qpoint.h>
-#include <QtCore/qstring.h>
-#include <QtGui/qpolygon.h>
-#include <QtCore/qstringbuilder.h>
-
-#ifndef QSTYLEHELPER_P_H
-#define QSTYLEHELPER_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-QT_BEGIN_NAMESPACE
-
-class QPainter;
-class QPixmap;
-class QStyleOptionSlider;
-class QStyleOption;
-
-namespace QStyleHelper
-{
- QString uniqueName(const QString &key, const QStyleOption *option, const QSize &size);
- qreal dpiScaled(qreal value);
-#ifndef QT_NO_DIAL
- qreal angle(const QPointF &p1, const QPointF &p2);
- QPolygonF calcLines(const QStyleOptionSlider *dial);
- int calcBigLineSize(int radius);
- void drawDial(const QStyleOptionSlider *dial, QPainter *painter);
-#endif //QT_NO_DIAL
- void drawBorderPixmap(const QPixmap &pixmap, QPainter *painter, const QRect &rect,
- int left = 0, int top = 0, int right = 0,
- int bottom = 0);
-}
-
-// internal helper. Converts an integer value to an unique string token
-template <typename T>
- struct HexString
-{
- inline HexString(const T t)
- : val(t)
- {}
-
- inline void write(QChar *&dest) const
- {
- const ushort hexChars[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
- const char *c = reinterpret_cast<const char *>(&val);
- for (uint i = 0; i < sizeof(T); ++i) {
- *dest++ = hexChars[*c & 0xf];
- *dest++ = hexChars[(*c & 0xf0) >> 4];
- ++c;
- }
- }
- const T val;
-};
-
-// specialization to enable fast concatenating of our string tokens to a string
-template <typename T>
- struct QConcatenable<HexString<T> >
-{
- typedef HexString<T> type;
- enum { ExactSize = true };
- static int size(const HexString<T> &) { return sizeof(T) * 2; }
- static inline void appendTo(const HexString<T> &str, QChar *&out) { str.write(out); }
- typedef QString ConvertTo;
-};
-
-QT_END_NAMESPACE
-
-#endif // QSTYLEHELPER_P_H
diff --git a/src/gui/styles/qstyleoption.h b/src/gui/styles/qstyleoption.h
deleted file mode 100644
index 1e5dec2ac1..0000000000
--- a/src/gui/styles/qstyleoption.h
+++ /dev/null
@@ -1,970 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSTYLEOPTION_H
-#define QSTYLEOPTION_H
-
-#include <QtCore/qvariant.h>
-#include <QtGui/qabstractspinbox.h>
-#include <QtGui/qicon.h>
-#include <QtGui/qmatrix.h>
-#include <QtGui/qslider.h>
-#include <QtGui/qstyle.h>
-#include <QtGui/qtabbar.h>
-#include <QtGui/qtabwidget.h>
-#include <QtGui/qrubberband.h>
-#include <QtGui/qframe.h>
-#ifndef QT_NO_ITEMVIEWS
-# include <QtCore/qabstractitemmodel.h>
-#endif
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QDebug;
-
-class Q_GUI_EXPORT QStyleOption
-{
-public:
- enum OptionType {
- SO_Default, SO_FocusRect, SO_Button, SO_Tab, SO_MenuItem,
- SO_Frame, SO_ProgressBar, SO_ToolBox, SO_Header, SO_Q3DockWindow,
- SO_DockWidget, SO_Q3ListViewItem, SO_ViewItem, SO_TabWidgetFrame,
- SO_TabBarBase, SO_RubberBand, SO_ToolBar, SO_GraphicsItem,
-
- SO_Complex = 0xf0000, SO_Slider, SO_SpinBox, SO_ToolButton, SO_ComboBox,
- SO_Q3ListView, SO_TitleBar, SO_GroupBox, SO_SizeGrip,
-
- SO_CustomBase = 0xf00,
- SO_ComplexCustomBase = 0xf000000
- };
-
- enum StyleOptionType { Type = SO_Default };
- enum StyleOptionVersion { Version = 1 };
-
- int version;
- int type;
- QStyle::State state;
- Qt::LayoutDirection direction;
- QRect rect;
- QFontMetrics fontMetrics;
- QPalette palette;
-
- QStyleOption(int version = QStyleOption::Version, int type = SO_Default);
- QStyleOption(const QStyleOption &other);
- ~QStyleOption();
-
- void init(const QWidget *w);
- inline void initFrom(const QWidget *w) { init(w); }
- QStyleOption &operator=(const QStyleOption &other);
-};
-
-class Q_GUI_EXPORT QStyleOptionFocusRect : public QStyleOption
-{
-public:
- enum StyleOptionType { Type = SO_FocusRect };
- enum StyleOptionVersion { Version = 1 };
-
- QColor backgroundColor;
-
- QStyleOptionFocusRect();
- QStyleOptionFocusRect(const QStyleOptionFocusRect &other) : QStyleOption(Version, Type) { *this = other; }
-
-protected:
- QStyleOptionFocusRect(int version);
-};
-
-class Q_GUI_EXPORT QStyleOptionFrame : public QStyleOption
-{
-public:
- enum StyleOptionType { Type = SO_Frame };
- enum StyleOptionVersion { Version = 1 };
-
- int lineWidth;
- int midLineWidth;
-
- QStyleOptionFrame();
- QStyleOptionFrame(const QStyleOptionFrame &other) : QStyleOption(Version, Type) { *this = other; }
-
-protected:
- QStyleOptionFrame(int version);
-};
-
-class Q_GUI_EXPORT QStyleOptionFrameV2 : public QStyleOptionFrame
-{
-public:
- enum StyleOptionVersion { Version = 2 };
- enum FrameFeature {
- None = 0x00,
- Flat = 0x01
- };
- Q_DECLARE_FLAGS(FrameFeatures, FrameFeature)
- FrameFeatures features;
-
- QStyleOptionFrameV2();
- QStyleOptionFrameV2(const QStyleOptionFrameV2 &other) : QStyleOptionFrame(Version) { *this = other; }
- QStyleOptionFrameV2(const QStyleOptionFrame &other);
- QStyleOptionFrameV2 &operator=(const QStyleOptionFrame &other);
-
-protected:
- QStyleOptionFrameV2(int version);
-};
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QStyleOptionFrameV2::FrameFeatures)
-
-
-class Q_GUI_EXPORT QStyleOptionFrameV3 : public QStyleOptionFrameV2
-{
-public:
- enum StyleOptionVersion { Version = 3 };
- QFrame::Shape frameShape : 4;
- uint unused : 28;
-
- QStyleOptionFrameV3();
- QStyleOptionFrameV3(const QStyleOptionFrameV3 &other) : QStyleOptionFrameV2(Version) { *this = other; }
- QStyleOptionFrameV3(const QStyleOptionFrame &other);
- QStyleOptionFrameV3 &operator=(const QStyleOptionFrame &other);
-
-protected:
- QStyleOptionFrameV3(int version);
-};
-
-
-#ifndef QT_NO_TABWIDGET
-class Q_GUI_EXPORT QStyleOptionTabWidgetFrame : public QStyleOption
-{
-public:
- enum StyleOptionType { Type = SO_TabWidgetFrame };
- enum StyleOptionVersion { Version = 1 };
-
- int lineWidth;
- int midLineWidth;
- QTabBar::Shape shape;
- QSize tabBarSize;
- QSize rightCornerWidgetSize;
- QSize leftCornerWidgetSize;
-
- QStyleOptionTabWidgetFrame();
- inline QStyleOptionTabWidgetFrame(const QStyleOptionTabWidgetFrame &other)
- : QStyleOption(Version, Type) { *this = other; }
-
-protected:
- QStyleOptionTabWidgetFrame(int version);
-};
-
-class Q_GUI_EXPORT QStyleOptionTabWidgetFrameV2 : public QStyleOptionTabWidgetFrame
-{
-public:
- enum StyleOptionVersion { Version = 2 };
-
- QRect tabBarRect;
- QRect selectedTabRect;
-
- QStyleOptionTabWidgetFrameV2();
- QStyleOptionTabWidgetFrameV2(const QStyleOptionTabWidgetFrameV2 &other) :
- QStyleOptionTabWidgetFrame(Version) { *this = other; }
- QStyleOptionTabWidgetFrameV2(const QStyleOptionTabWidgetFrame &other);
- QStyleOptionTabWidgetFrameV2 &operator=(const QStyleOptionTabWidgetFrame &other);
-
-protected:
- QStyleOptionTabWidgetFrameV2(int version);
-};
-
-#endif
-
-
-#ifndef QT_NO_TABBAR
-class Q_GUI_EXPORT QStyleOptionTabBarBase : public QStyleOption
-{
-public:
- enum StyleOptionType { Type = SO_TabBarBase };
- enum StyleOptionVersion { Version = 1 };
-
- QTabBar::Shape shape;
- QRect tabBarRect;
- QRect selectedTabRect;
-
- QStyleOptionTabBarBase();
- QStyleOptionTabBarBase(const QStyleOptionTabBarBase &other) : QStyleOption(Version, Type) { *this = other; }
-
-protected:
- QStyleOptionTabBarBase(int version);
-};
-
-class Q_GUI_EXPORT QStyleOptionTabBarBaseV2 : public QStyleOptionTabBarBase
-{
-public:
- enum StyleOptionVersion { Version = 2 };
- bool documentMode;
- QStyleOptionTabBarBaseV2();
- QStyleOptionTabBarBaseV2(const QStyleOptionTabBarBaseV2 &other) : QStyleOptionTabBarBase(Version) { *this = other; }
- QStyleOptionTabBarBaseV2(const QStyleOptionTabBarBase &other);
- QStyleOptionTabBarBaseV2 &operator=(const QStyleOptionTabBarBase &other);
-
-protected:
- QStyleOptionTabBarBaseV2(int version);
-};
-
-#endif
-
-class Q_GUI_EXPORT QStyleOptionHeader : public QStyleOption
-{
-public:
- enum StyleOptionType { Type = SO_Header };
- enum StyleOptionVersion { Version = 1 };
-
- enum SectionPosition { Beginning, Middle, End, OnlyOneSection };
- enum SelectedPosition { NotAdjacent, NextIsSelected, PreviousIsSelected,
- NextAndPreviousAreSelected };
- enum SortIndicator { None, SortUp, SortDown };
-
- int section;
- QString text;
- Qt::Alignment textAlignment;
- QIcon icon;
- Qt::Alignment iconAlignment;
- SectionPosition position;
- SelectedPosition selectedPosition;
- SortIndicator sortIndicator;
- Qt::Orientation orientation;
-
- QStyleOptionHeader();
- QStyleOptionHeader(const QStyleOptionHeader &other) : QStyleOption(Version, Type) { *this = other; }
-
-protected:
- QStyleOptionHeader(int version);
-};
-
-class Q_GUI_EXPORT QStyleOptionButton : public QStyleOption
-{
-public:
- enum StyleOptionType { Type = SO_Button };
- enum StyleOptionVersion { Version = 1 };
-
- enum ButtonFeature { None = 0x00, Flat = 0x01, HasMenu = 0x02, DefaultButton = 0x04,
- AutoDefaultButton = 0x08, CommandLinkButton = 0x10 };
- Q_DECLARE_FLAGS(ButtonFeatures, ButtonFeature)
-
- ButtonFeatures features;
- QString text;
- QIcon icon;
- QSize iconSize;
-
- QStyleOptionButton();
- QStyleOptionButton(const QStyleOptionButton &other) : QStyleOption(Version, Type) { *this = other; }
-
-protected:
- QStyleOptionButton(int version);
-};
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QStyleOptionButton::ButtonFeatures)
-
-#ifndef QT_NO_TABBAR
-class Q_GUI_EXPORT QStyleOptionTab : public QStyleOption
-{
-public:
- enum StyleOptionType { Type = SO_Tab };
- enum StyleOptionVersion { Version = 1 };
-
- enum TabPosition { Beginning, Middle, End, OnlyOneTab };
- enum SelectedPosition { NotAdjacent, NextIsSelected, PreviousIsSelected };
- enum CornerWidget { NoCornerWidgets = 0x00, LeftCornerWidget = 0x01,
- RightCornerWidget = 0x02 };
- Q_DECLARE_FLAGS(CornerWidgets, CornerWidget)
-
- QTabBar::Shape shape;
- QString text;
- QIcon icon;
- int row;
- TabPosition position;
- SelectedPosition selectedPosition;
- CornerWidgets cornerWidgets;
-
- QStyleOptionTab();
- QStyleOptionTab(const QStyleOptionTab &other) : QStyleOption(Version, Type) { *this = other; }
-
-protected:
- QStyleOptionTab(int version);
-};
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QStyleOptionTab::CornerWidgets)
-
-class Q_GUI_EXPORT QStyleOptionTabV2 : public QStyleOptionTab
-{
-public:
- enum StyleOptionVersion { Version = 2 };
- QSize iconSize;
- QStyleOptionTabV2();
- QStyleOptionTabV2(const QStyleOptionTabV2 &other) : QStyleOptionTab(Version) { *this = other; }
- QStyleOptionTabV2(const QStyleOptionTab &other);
- QStyleOptionTabV2 &operator=(const QStyleOptionTab &other);
-
-protected:
- QStyleOptionTabV2(int version);
-};
-
-class Q_GUI_EXPORT QStyleOptionTabV3 : public QStyleOptionTabV2
-{
-public:
- enum StyleOptionVersion { Version = 3 };
- bool documentMode;
- QSize leftButtonSize;
- QSize rightButtonSize;
- QStyleOptionTabV3();
- QStyleOptionTabV3(const QStyleOptionTabV3 &other) : QStyleOptionTabV2(Version) { *this = other; }
- QStyleOptionTabV3(const QStyleOptionTabV2 &other) : QStyleOptionTabV2(Version) { *this = other; }
- QStyleOptionTabV3(const QStyleOptionTab &other);
- QStyleOptionTabV3 &operator=(const QStyleOptionTab &other);
-
-protected:
- QStyleOptionTabV3(int version);
-};
-
-#endif
-
-
-#ifndef QT_NO_TOOLBAR
-
-class Q_GUI_EXPORT QStyleOptionToolBar : public QStyleOption
-{
-public:
- enum StyleOptionType { Type = SO_ToolBar };
- enum StyleOptionVersion { Version = 1 };
- enum ToolBarPosition { Beginning, Middle, End, OnlyOne };
- enum ToolBarFeature { None = 0x0, Movable = 0x1 };
- Q_DECLARE_FLAGS(ToolBarFeatures, ToolBarFeature)
- ToolBarPosition positionOfLine; // The toolbar line position
- ToolBarPosition positionWithinLine; // The position within a toolbar
- Qt::ToolBarArea toolBarArea; // The toolbar docking area
- ToolBarFeatures features;
- int lineWidth;
- int midLineWidth;
- QStyleOptionToolBar();
- QStyleOptionToolBar(const QStyleOptionToolBar &other) : QStyleOption(Version, Type) { *this = other; }
-
-protected:
- QStyleOptionToolBar(int version);
-};
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QStyleOptionToolBar::ToolBarFeatures)
-
-#endif
-
-
-
-class Q_GUI_EXPORT QStyleOptionProgressBar : public QStyleOption
-{
-public:
- enum StyleOptionType { Type = SO_ProgressBar };
- enum StyleOptionVersion { Version = 1 };
-
- int minimum;
- int maximum;
- int progress;
- QString text;
- Qt::Alignment textAlignment;
- bool textVisible;
-
- QStyleOptionProgressBar();
- QStyleOptionProgressBar(const QStyleOptionProgressBar &other) : QStyleOption(Version, Type) { *this = other; }
-
-protected:
- QStyleOptionProgressBar(int version);
-};
-
-// Adds style info for vertical progress bars
-class Q_GUI_EXPORT QStyleOptionProgressBarV2 : public QStyleOptionProgressBar
-{
-public:
- enum StyleOptionType { Type = SO_ProgressBar };
- enum StyleOptionVersion { Version = 2 };
- Qt::Orientation orientation;
- bool invertedAppearance;
- bool bottomToTop;
-
- QStyleOptionProgressBarV2();
- QStyleOptionProgressBarV2(const QStyleOptionProgressBar &other);
- QStyleOptionProgressBarV2(const QStyleOptionProgressBarV2 &other);
- QStyleOptionProgressBarV2 &operator=(const QStyleOptionProgressBar &other);
-
-protected:
- QStyleOptionProgressBarV2(int version);
-};
-
-class Q_GUI_EXPORT QStyleOptionMenuItem : public QStyleOption
-{
-public:
- enum StyleOptionType { Type = SO_MenuItem };
- enum StyleOptionVersion { Version = 1 };
-
- enum MenuItemType { Normal, DefaultItem, Separator, SubMenu, Scroller, TearOff, Margin,
- EmptyArea };
- enum CheckType { NotCheckable, Exclusive, NonExclusive };
-
- MenuItemType menuItemType;
- CheckType checkType;
- bool checked;
- bool menuHasCheckableItems;
- QRect menuRect;
- QString text;
- QIcon icon;
- int maxIconWidth;
- int tabWidth;
- QFont font;
-
- QStyleOptionMenuItem();
- QStyleOptionMenuItem(const QStyleOptionMenuItem &other) : QStyleOption(Version, Type) { *this = other; }
-
-protected:
- QStyleOptionMenuItem(int version);
-};
-
-class Q_GUI_EXPORT QStyleOptionQ3ListViewItem : public QStyleOption
-{
-public:
- enum StyleOptionType { Type = SO_Q3ListViewItem };
- enum StyleOptionVersion { Version = 1 };
-
- enum Q3ListViewItemFeature { None = 0x00, Expandable = 0x01, MultiLine = 0x02, Visible = 0x04,
- ParentControl = 0x08 };
- Q_DECLARE_FLAGS(Q3ListViewItemFeatures, Q3ListViewItemFeature)
-
- Q3ListViewItemFeatures features;
- int height;
- int totalHeight;
- int itemY;
- int childCount;
-
- QStyleOptionQ3ListViewItem();
- QStyleOptionQ3ListViewItem(const QStyleOptionQ3ListViewItem &other) : QStyleOption(Version, Type) { *this = other; }
-
-protected:
- QStyleOptionQ3ListViewItem(int version);
-};
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QStyleOptionQ3ListViewItem::Q3ListViewItemFeatures)
-
-class Q_GUI_EXPORT QStyleOptionQ3DockWindow : public QStyleOption
-{
-public:
- enum StyleOptionType { Type = SO_Q3DockWindow };
- enum StyleOptionVersion { Version = 1 };
-
- bool docked;
- bool closeEnabled;
-
- QStyleOptionQ3DockWindow();
- QStyleOptionQ3DockWindow(const QStyleOptionQ3DockWindow &other) : QStyleOption(Version, Type) { *this = other; }
-
-protected:
- QStyleOptionQ3DockWindow(int version);
-};
-
-class Q_GUI_EXPORT QStyleOptionDockWidget : public QStyleOption
-{
-public:
- enum StyleOptionType { Type = SO_DockWidget };
- enum StyleOptionVersion { Version = 1 };
-
- QString title;
- bool closable;
- bool movable;
- bool floatable;
-
- QStyleOptionDockWidget();
- QStyleOptionDockWidget(const QStyleOptionDockWidget &other) : QStyleOption(Version, Type) { *this = other; }
-
-protected:
- QStyleOptionDockWidget(int version);
-};
-
-class Q_GUI_EXPORT QStyleOptionDockWidgetV2 : public QStyleOptionDockWidget
-{
-public:
- enum StyleOptionVersion { Version = 2 };
-
- bool verticalTitleBar;
-
- QStyleOptionDockWidgetV2();
- QStyleOptionDockWidgetV2(const QStyleOptionDockWidgetV2 &other)
- : QStyleOptionDockWidget(Version) { *this = other; }
- QStyleOptionDockWidgetV2(const QStyleOptionDockWidget &other);
- QStyleOptionDockWidgetV2 &operator = (const QStyleOptionDockWidget &other);
-
-protected:
- QStyleOptionDockWidgetV2(int version);
-};
-
-class Q_GUI_EXPORT QStyleOptionViewItem : public QStyleOption
-{
-public:
- enum StyleOptionType { Type = SO_ViewItem };
- enum StyleOptionVersion { Version = 1 };
-
- enum Position { Left, Right, Top, Bottom };
-
- Qt::Alignment displayAlignment;
- Qt::Alignment decorationAlignment;
- Qt::TextElideMode textElideMode;
- Position decorationPosition;
- QSize decorationSize;
- QFont font;
- bool showDecorationSelected;
-
- QStyleOptionViewItem();
- QStyleOptionViewItem(const QStyleOptionViewItem &other) : QStyleOption(Version, Type) { *this = other; }
-
-protected:
- QStyleOptionViewItem(int version);
-};
-
-class Q_GUI_EXPORT QStyleOptionViewItemV2 : public QStyleOptionViewItem
-{
-public:
- enum StyleOptionVersion { Version = 2 };
-
- enum ViewItemFeature {
- None = 0x00,
- WrapText = 0x01,
- Alternate = 0x02,
- HasCheckIndicator = 0x04,
- HasDisplay = 0x08,
- HasDecoration = 0x10
- };
- Q_DECLARE_FLAGS(ViewItemFeatures, ViewItemFeature)
-
- ViewItemFeatures features;
-
- QStyleOptionViewItemV2();
- QStyleOptionViewItemV2(const QStyleOptionViewItemV2 &other) : QStyleOptionViewItem(Version) { *this = other; }
- QStyleOptionViewItemV2(const QStyleOptionViewItem &other);
- QStyleOptionViewItemV2 &operator=(const QStyleOptionViewItem &other);
-
-protected:
- QStyleOptionViewItemV2(int version);
-};
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QStyleOptionViewItemV2::ViewItemFeatures)
-
-class Q_GUI_EXPORT QStyleOptionViewItemV3 : public QStyleOptionViewItemV2
-{
-public:
- enum StyleOptionVersion { Version = 3 };
-
- QLocale locale;
- const QWidget *widget;
-
- QStyleOptionViewItemV3();
- QStyleOptionViewItemV3(const QStyleOptionViewItemV3 &other)
- : QStyleOptionViewItemV2(Version) { *this = other; }
- QStyleOptionViewItemV3(const QStyleOptionViewItem &other);
- QStyleOptionViewItemV3 &operator = (const QStyleOptionViewItem &other);
-
-protected:
- QStyleOptionViewItemV3(int version);
-};
-
-#ifndef QT_NO_ITEMVIEWS
-class Q_GUI_EXPORT QStyleOptionViewItemV4 : public QStyleOptionViewItemV3
-{
-public:
- enum StyleOptionVersion { Version = 4 };
- enum ViewItemPosition { Invalid, Beginning, Middle, End, OnlyOne };
-
- QModelIndex index;
- Qt::CheckState checkState;
- QIcon icon;
- QString text;
- ViewItemPosition viewItemPosition;
- QBrush backgroundBrush;
-
- QStyleOptionViewItemV4();
- QStyleOptionViewItemV4(const QStyleOptionViewItemV4 &other)
- : QStyleOptionViewItemV3(Version) { *this = other; }
- QStyleOptionViewItemV4(const QStyleOptionViewItem &other);
- QStyleOptionViewItemV4 &operator = (const QStyleOptionViewItem &other);
-
-protected:
- QStyleOptionViewItemV4(int version);
-};
-#endif
-
-class Q_GUI_EXPORT QStyleOptionToolBox : public QStyleOption
-{
-public:
- enum StyleOptionType { Type = SO_ToolBox };
- enum StyleOptionVersion { Version = 1 };
-
- QString text;
- QIcon icon;
-
- QStyleOptionToolBox();
- QStyleOptionToolBox(const QStyleOptionToolBox &other) : QStyleOption(Version, Type) { *this = other; }
-
-protected:
- QStyleOptionToolBox(int version);
-};
-
-class Q_GUI_EXPORT QStyleOptionToolBoxV2 : public QStyleOptionToolBox
-{
-public:
- enum StyleOptionVersion { Version = 2 };
- enum TabPosition { Beginning, Middle, End, OnlyOneTab };
- enum SelectedPosition { NotAdjacent, NextIsSelected, PreviousIsSelected };
-
- TabPosition position;
- SelectedPosition selectedPosition;
-
- QStyleOptionToolBoxV2();
- QStyleOptionToolBoxV2(const QStyleOptionToolBoxV2 &other) : QStyleOptionToolBox(Version) { *this = other; }
- QStyleOptionToolBoxV2(const QStyleOptionToolBox &other);
- QStyleOptionToolBoxV2 &operator=(const QStyleOptionToolBox &other);
-
-protected:
- QStyleOptionToolBoxV2(int version);
-};
-
-#ifndef QT_NO_RUBBERBAND
-class Q_GUI_EXPORT QStyleOptionRubberBand : public QStyleOption
-{
-public:
- enum StyleOptionType { Type = SO_RubberBand };
- enum StyleOptionVersion { Version = 1 };
-
- QRubberBand::Shape shape;
- bool opaque;
-
- QStyleOptionRubberBand();
- QStyleOptionRubberBand(const QStyleOptionRubberBand &other) : QStyleOption(Version, Type) { *this = other; }
-
-protected:
- QStyleOptionRubberBand(int version);
-};
-#endif // QT_NO_RUBBERBAND
-
-// -------------------------- Complex style options -------------------------------
-class Q_GUI_EXPORT QStyleOptionComplex : public QStyleOption
-{
-public:
- enum StyleOptionType { Type = SO_Complex };
- enum StyleOptionVersion { Version = 1 };
-
- QStyle::SubControls subControls;
- QStyle::SubControls activeSubControls;
-
- QStyleOptionComplex(int version = QStyleOptionComplex::Version, int type = SO_Complex);
- QStyleOptionComplex(const QStyleOptionComplex &other) : QStyleOption(Version, Type) { *this = other; }
-};
-
-#ifndef QT_NO_SLIDER
-class Q_GUI_EXPORT QStyleOptionSlider : public QStyleOptionComplex
-{
-public:
- enum StyleOptionType { Type = SO_Slider };
- enum StyleOptionVersion { Version = 1 };
-
- Qt::Orientation orientation;
- int minimum;
- int maximum;
- QSlider::TickPosition tickPosition;
- int tickInterval;
- bool upsideDown;
- int sliderPosition;
- int sliderValue;
- int singleStep;
- int pageStep;
- qreal notchTarget;
- bool dialWrapping;
-
- QStyleOptionSlider();
- QStyleOptionSlider(const QStyleOptionSlider &other) : QStyleOptionComplex(Version, Type) { *this = other; }
-
-protected:
- QStyleOptionSlider(int version);
-};
-#endif // QT_NO_SLIDER
-
-#ifndef QT_NO_SPINBOX
-class Q_GUI_EXPORT QStyleOptionSpinBox : public QStyleOptionComplex
-{
-public:
- enum StyleOptionType { Type = SO_SpinBox };
- enum StyleOptionVersion { Version = 1 };
-
- QAbstractSpinBox::ButtonSymbols buttonSymbols;
- QAbstractSpinBox::StepEnabled stepEnabled;
- bool frame;
-
- QStyleOptionSpinBox();
- QStyleOptionSpinBox(const QStyleOptionSpinBox &other) : QStyleOptionComplex(Version, Type) { *this = other; }
-
-protected:
- QStyleOptionSpinBox(int version);
-};
-#endif // QT_NO_SPINBOX
-
-class Q_GUI_EXPORT QStyleOptionQ3ListView : public QStyleOptionComplex
-{
-public:
- enum StyleOptionType { Type = SO_Q3ListView };
- enum StyleOptionVersion { Version = 1 };
-
- QList<QStyleOptionQ3ListViewItem> items;
- QPalette viewportPalette;
- QPalette::ColorRole viewportBGRole;
- int sortColumn;
- int itemMargin;
- int treeStepSize;
- bool rootIsDecorated;
-
- QStyleOptionQ3ListView();
- QStyleOptionQ3ListView(const QStyleOptionQ3ListView &other) : QStyleOptionComplex(Version, Type) { *this = other; }
-
-protected:
- QStyleOptionQ3ListView(int version);
-};
-
-class Q_GUI_EXPORT QStyleOptionToolButton : public QStyleOptionComplex
-{
-public:
- enum StyleOptionType { Type = SO_ToolButton };
- enum StyleOptionVersion { Version = 1 };
-
- enum ToolButtonFeature { None = 0x00, Arrow = 0x01, Menu = 0x04, MenuButtonPopup = Menu, PopupDelay = 0x08,
- HasMenu = 0x10 };
- Q_DECLARE_FLAGS(ToolButtonFeatures, ToolButtonFeature)
-
- ToolButtonFeatures features;
- QIcon icon;
- QSize iconSize;
- QString text;
- Qt::ArrowType arrowType;
- Qt::ToolButtonStyle toolButtonStyle;
- QPoint pos;
- QFont font;
-
- QStyleOptionToolButton();
- QStyleOptionToolButton(const QStyleOptionToolButton &other) : QStyleOptionComplex(Version, Type) { *this = other; }
-
-protected:
- QStyleOptionToolButton(int version);
-};
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QStyleOptionToolButton::ToolButtonFeatures)
-
-class Q_GUI_EXPORT QStyleOptionComboBox : public QStyleOptionComplex
-{
-public:
- enum StyleOptionType { Type = SO_ComboBox };
- enum StyleOptionVersion { Version = 1 };
-
- bool editable;
- QRect popupRect;
- bool frame;
- QString currentText;
- QIcon currentIcon;
- QSize iconSize;
-
- QStyleOptionComboBox();
- QStyleOptionComboBox(const QStyleOptionComboBox &other) : QStyleOptionComplex(Version, Type) { *this = other; }
-
-protected:
- QStyleOptionComboBox(int version);
-};
-
-class Q_GUI_EXPORT QStyleOptionTitleBar : public QStyleOptionComplex
-{
-public:
- enum StyleOptionType { Type = SO_TitleBar };
- enum StyleOptionVersion { Version = 1 };
-
- QString text;
- QIcon icon;
- int titleBarState;
- Qt::WindowFlags titleBarFlags;
-
- QStyleOptionTitleBar();
- QStyleOptionTitleBar(const QStyleOptionTitleBar &other) : QStyleOptionComplex(Version, Type) { *this = other; }
-
-protected:
- QStyleOptionTitleBar(int version);
-};
-
-class Q_GUI_EXPORT QStyleOptionGroupBox : public QStyleOptionComplex
-{
-public:
- enum StyleOptionType { Type = SO_GroupBox };
- enum StyleOptionVersion { Version = 1 };
-
- QStyleOptionFrameV2::FrameFeatures features;
- QString text;
- Qt::Alignment textAlignment;
- QColor textColor;
- int lineWidth;
- int midLineWidth;
-
- QStyleOptionGroupBox();
- QStyleOptionGroupBox(const QStyleOptionGroupBox &other) : QStyleOptionComplex(Version, Type) { *this = other; }
-protected:
- QStyleOptionGroupBox(int version);
-};
-
-class Q_GUI_EXPORT QStyleOptionSizeGrip : public QStyleOptionComplex
-{
-public:
- enum StyleOptionType { Type = SO_SizeGrip };
- enum StyleOptionVersion { Version = 1 };
-
- Qt::Corner corner;
-
- QStyleOptionSizeGrip();
- QStyleOptionSizeGrip(const QStyleOptionSizeGrip &other) : QStyleOptionComplex(Version, Type) { *this = other; }
-protected:
- QStyleOptionSizeGrip(int version);
-};
-
-class Q_GUI_EXPORT QStyleOptionGraphicsItem : public QStyleOption
-{
-public:
- enum StyleOptionType { Type = SO_GraphicsItem };
- enum StyleOptionVersion { Version = 1 };
-
- QRectF exposedRect;
- QMatrix matrix;
- qreal levelOfDetail;
-
- QStyleOptionGraphicsItem();
- QStyleOptionGraphicsItem(const QStyleOptionGraphicsItem &other) : QStyleOption(Version, Type) { *this = other; }
- static qreal levelOfDetailFromTransform(const QTransform &worldTransform);
-protected:
- QStyleOptionGraphicsItem(int version);
-};
-
-template <typename T>
-T qstyleoption_cast(const QStyleOption *opt)
-{
- if (opt && opt->version >= static_cast<T>(0)->Version && (opt->type == static_cast<T>(0)->Type
- || int(static_cast<T>(0)->Type) == QStyleOption::SO_Default
- || (int(static_cast<T>(0)->Type) == QStyleOption::SO_Complex
- && opt->type > QStyleOption::SO_Complex)))
- return static_cast<T>(opt);
- return 0;
-}
-
-template <typename T>
-T qstyleoption_cast(QStyleOption *opt)
-{
- if (opt && opt->version >= static_cast<T>(0)->Version && (opt->type == static_cast<T>(0)->Type
- || int(static_cast<T>(0)->Type) == QStyleOption::SO_Default
- || (int(static_cast<T>(0)->Type) == QStyleOption::SO_Complex
- && opt->type > QStyleOption::SO_Complex)))
- return static_cast<T>(opt);
- return 0;
-}
-
-// -------------------------- QStyleHintReturn -------------------------------
-class Q_GUI_EXPORT QStyleHintReturn {
-public:
- enum HintReturnType {
- SH_Default=0xf000, SH_Mask, SH_Variant
- };
-
- enum StyleOptionType { Type = SH_Default };
- enum StyleOptionVersion { Version = 1 };
-
- QStyleHintReturn(int version = QStyleOption::Version, int type = SH_Default);
- ~QStyleHintReturn();
-
- int version;
- int type;
-};
-
-class Q_GUI_EXPORT QStyleHintReturnMask : public QStyleHintReturn {
-public:
- enum StyleOptionType { Type = SH_Mask };
- enum StyleOptionVersion { Version = 1 };
-
- QStyleHintReturnMask();
-
- QRegion region;
-};
-
-class Q_GUI_EXPORT QStyleHintReturnVariant : public QStyleHintReturn {
-public:
- enum StyleOptionType { Type = SH_Variant };
- enum StyleOptionVersion { Version = 1 };
-
- QStyleHintReturnVariant();
-
- QVariant variant;
-};
-
-template <typename T>
-T qstyleoption_cast(const QStyleHintReturn *hint)
-{
- if (hint && hint->version <= static_cast<T>(0)->Version &&
- (hint->type == static_cast<T>(0)->Type || int(static_cast<T>(0)->Type) == QStyleHintReturn::SH_Default))
- return static_cast<T>(hint);
- return 0;
-}
-
-template <typename T>
-T qstyleoption_cast(QStyleHintReturn *hint)
-{
- if (hint && hint->version <= static_cast<T>(0)->Version &&
- (hint->type == static_cast<T>(0)->Type || int(static_cast<T>(0)->Type) == QStyleHintReturn::SH_Default))
- return static_cast<T>(hint);
- return 0;
-}
-
-#if !defined(QT_NO_DEBUG_STREAM)
-Q_GUI_EXPORT QDebug operator<<(QDebug debug, const QStyleOption::OptionType &optionType);
-Q_GUI_EXPORT QDebug operator<<(QDebug debug, const QStyleOption &option);
-#endif
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QSTYLEOPTION_H
diff --git a/src/gui/styles/qstyleplugin.h b/src/gui/styles/qstyleplugin.h
deleted file mode 100644
index 2dd8ccfcfd..0000000000
--- a/src/gui/styles/qstyleplugin.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSTYLEPLUGIN_H
-#define QSTYLEPLUGIN_H
-
-#include <QtCore/qplugin.h>
-#include <QtCore/qfactoryinterface.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QStyle;
-
-struct Q_GUI_EXPORT QStyleFactoryInterface : public QFactoryInterface
-{
- virtual QStyle *create(const QString &key) = 0;
-};
-
-#define QStyleFactoryInterface_iid "com.trolltech.Qt.QStyleFactoryInterface"
-
-Q_DECLARE_INTERFACE(QStyleFactoryInterface, QStyleFactoryInterface_iid)
-
-class Q_GUI_EXPORT QStylePlugin : public QObject, public QStyleFactoryInterface
-{
- Q_OBJECT
- Q_INTERFACES(QStyleFactoryInterface:QFactoryInterface)
-public:
- explicit QStylePlugin(QObject *parent = 0);
- ~QStylePlugin();
-
- virtual QStringList keys() const = 0;
- virtual QStyle *create(const QString &key) = 0;
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QSTYLEPLUGIN_H
diff --git a/src/gui/styles/qstylesheetstyle.cpp b/src/gui/styles/qstylesheetstyle.cpp
deleted file mode 100644
index 7d2ed2af8c..0000000000
--- a/src/gui/styles/qstylesheetstyle.cpp
+++ /dev/null
@@ -1,5898 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qglobal.h>
-
-#ifndef QT_NO_STYLE_STYLESHEET
-
-#include "qstylesheetstyle_p.h"
-#include "private/qcssutil_p.h"
-#include <qdebug.h>
-#include <qapplication.h>
-#include <qmenu.h>
-#include <qmenubar.h>
-#include <qpainter.h>
-#include <qstyleoption.h>
-#include <qlineedit.h>
-#include <qwindowsstyle.h>
-#include <qcombobox.h>
-#include <qwindowsstyle.h>
-#include <qplastiquestyle.h>
-#include "private/qcssparser_p.h"
-#include "private/qmath_p.h"
-#include <qabstractscrollarea.h>
-#include "private/qabstractscrollarea_p.h"
-#include <qtooltip.h>
-#include <qshareddata.h>
-#include <qradiobutton.h>
-#include <qtoolbutton.h>
-#include <qscrollbar.h>
-#include <qstring.h>
-#include <qfile.h>
-#include <qcheckbox.h>
-#include <qstatusbar.h>
-#include <qheaderview.h>
-#include <qprogressbar.h>
-#include <private/qwindowsstyle_p.h>
-#include <qtabbar.h>
-#include <QMetaProperty>
-#include <qmainwindow.h>
-#include <qdockwidget.h>
-#include <qmdisubwindow.h>
-#include <qdialog.h>
-#include <private/qwidget_p.h>
-#include <QAbstractSpinBox>
-#include <QLabel>
-#include "qdrawutil.h"
-
-#include <limits.h>
-#include <QtGui/qtoolbar.h>
-
-QT_BEGIN_NAMESPACE
-
-using namespace QCss;
-
-
-class QStyleSheetStylePrivate : public QWindowsStylePrivate
-{
- Q_DECLARE_PUBLIC(QStyleSheetStyle)
-public:
- QStyleSheetStylePrivate() { }
-};
-
-
-static QStyleSheetStyleCaches *styleSheetCaches = 0;
-
-/* RECURSION_GUARD:
- * the QStyleSheetStyle is a proxy. If used with others proxy style, we may end up with something like:
- * QStyleSheetStyle -> ProxyStyle -> QStyleSheetStyle -> OriginalStyle
- * Recursion may happen if the style call the widget()->style() again.
- * Not to mention the performence penalty of having two lookup of rules.
- *
- * The first instance of QStyleSheetStyle will set globalStyleSheetStyle to itself. The second one
- * will notice the globalStyleSheetStyle is not istelf and call its base style directly.
- */
-static const QStyleSheetStyle *globalStyleSheetStyle = 0;
-class QStyleSheetStyleRecursionGuard
-{
- public:
- QStyleSheetStyleRecursionGuard(const QStyleSheetStyle *that)
- : guarded(globalStyleSheetStyle == 0)
- {
- if (guarded) globalStyleSheetStyle = that;
- }
- ~QStyleSheetStyleRecursionGuard() { if (guarded) globalStyleSheetStyle = 0; }
- bool guarded;
-};
-#define RECURSION_GUARD(RETURN) \
- if (globalStyleSheetStyle != 0 && globalStyleSheetStyle != this) { RETURN; } \
- QStyleSheetStyleRecursionGuard recursion_guard(this);
-
-#define ceil(x) ((int)(x) + ((x) > 0 && (x) != (int)(x)))
-
-enum PseudoElement {
- PseudoElement_None,
- PseudoElement_DownArrow,
- PseudoElement_UpArrow,
- PseudoElement_LeftArrow,
- PseudoElement_RightArrow,
- PseudoElement_Indicator,
- PseudoElement_ExclusiveIndicator,
- PseudoElement_PushButtonMenuIndicator,
- PseudoElement_ComboBoxDropDown,
- PseudoElement_ComboBoxArrow,
- PseudoElement_Item,
- PseudoElement_SpinBoxUpButton,
- PseudoElement_SpinBoxUpArrow,
- PseudoElement_SpinBoxDownButton,
- PseudoElement_SpinBoxDownArrow,
- PseudoElement_GroupBoxTitle,
- PseudoElement_GroupBoxIndicator,
- PseudoElement_ToolButtonMenu,
- PseudoElement_ToolButtonMenuArrow,
- PseudoElement_ToolButtonDownArrow,
- PseudoElement_ToolBoxTab,
- PseudoElement_ScrollBarSlider,
- PseudoElement_ScrollBarAddPage,
- PseudoElement_ScrollBarSubPage,
- PseudoElement_ScrollBarAddLine,
- PseudoElement_ScrollBarSubLine,
- PseudoElement_ScrollBarFirst,
- PseudoElement_ScrollBarLast,
- PseudoElement_ScrollBarUpArrow,
- PseudoElement_ScrollBarDownArrow,
- PseudoElement_ScrollBarLeftArrow,
- PseudoElement_ScrollBarRightArrow,
- PseudoElement_SplitterHandle,
- PseudoElement_ToolBarHandle,
- PseudoElement_ToolBarSeparator,
- PseudoElement_MenuScroller,
- PseudoElement_MenuTearoff,
- PseudoElement_MenuCheckMark,
- PseudoElement_MenuSeparator,
- PseudoElement_MenuIcon,
- PseudoElement_MenuRightArrow,
- PseudoElement_TreeViewBranch,
- PseudoElement_HeaderViewSection,
- PseudoElement_HeaderViewUpArrow,
- PseudoElement_HeaderViewDownArrow,
- PseudoElement_ProgressBarChunk,
- PseudoElement_TabBarTab,
- PseudoElement_TabBarScroller,
- PseudoElement_TabBarTear,
- PseudoElement_SliderGroove,
- PseudoElement_SliderHandle,
- PseudoElement_SliderAddPage,
- PseudoElement_SliderSubPage,
- PseudoElement_SliderTickmark,
- PseudoElement_TabWidgetPane,
- PseudoElement_TabWidgetTabBar,
- PseudoElement_TabWidgetLeftCorner,
- PseudoElement_TabWidgetRightCorner,
- PseudoElement_DockWidgetTitle,
- PseudoElement_DockWidgetCloseButton,
- PseudoElement_DockWidgetFloatButton,
- PseudoElement_DockWidgetSeparator,
- PseudoElement_MdiCloseButton,
- PseudoElement_MdiMinButton,
- PseudoElement_MdiNormalButton,
- PseudoElement_TitleBar,
- PseudoElement_TitleBarCloseButton,
- PseudoElement_TitleBarMinButton,
- PseudoElement_TitleBarMaxButton,
- PseudoElement_TitleBarShadeButton,
- PseudoElement_TitleBarUnshadeButton,
- PseudoElement_TitleBarNormalButton,
- PseudoElement_TitleBarContextHelpButton,
- PseudoElement_TitleBarSysMenu,
- PseudoElement_ViewItem,
- PseudoElement_ViewItemIcon,
- PseudoElement_ViewItemText,
- PseudoElement_ViewItemIndicator,
- PseudoElement_ScrollAreaCorner,
- PseudoElement_TabBarTabCloseButton,
- NumPseudoElements
-};
-
-struct PseudoElementInfo {
- QStyle::SubControl subControl;
- const char *name;
-};
-
-static const PseudoElementInfo knownPseudoElements[NumPseudoElements] = {
- { QStyle::SC_None, "" },
- { QStyle::SC_None, "down-arrow" },
- { QStyle::SC_None, "up-arrow" },
- { QStyle::SC_None, "left-arrow" },
- { QStyle::SC_None, "right-arrow" },
- { QStyle::SC_None, "indicator" },
- { QStyle::SC_None, "indicator" },
- { QStyle::SC_None, "menu-indicator" },
- { QStyle::SC_ComboBoxArrow, "drop-down" },
- { QStyle::SC_ComboBoxArrow, "down-arrow" },
- { QStyle::SC_None, "item" },
- { QStyle::SC_SpinBoxUp, "up-button" },
- { QStyle::SC_SpinBoxUp, "up-arrow" },
- { QStyle::SC_SpinBoxDown, "down-button" },
- { QStyle::SC_SpinBoxDown, "down-arrow" },
- { QStyle::SC_GroupBoxLabel, "title" },
- { QStyle::SC_GroupBoxCheckBox, "indicator" },
- { QStyle::SC_ToolButtonMenu, "menu-button" },
- { QStyle::SC_ToolButtonMenu, "menu-arrow" },
- { QStyle::SC_None, "menu-indicator" },
- { QStyle::SC_None, "tab" },
- { QStyle::SC_ScrollBarSlider, "handle" },
- { QStyle::SC_ScrollBarAddPage, "add-page" },
- { QStyle::SC_ScrollBarSubPage, "sub-page" },
- { QStyle::SC_ScrollBarAddLine, "add-line" },
- { QStyle::SC_ScrollBarSubLine, "sub-line" },
- { QStyle::SC_ScrollBarFirst, "first" },
- { QStyle::SC_ScrollBarLast, "last" },
- { QStyle::SC_ScrollBarSubLine, "up-arrow" },
- { QStyle::SC_ScrollBarAddLine, "down-arrow" },
- { QStyle::SC_ScrollBarSubLine, "left-arrow" },
- { QStyle::SC_ScrollBarAddLine, "right-arrow" },
- { QStyle::SC_None, "handle" },
- { QStyle::SC_None, "handle" },
- { QStyle::SC_None, "separator" },
- { QStyle::SC_None, "scroller" },
- { QStyle::SC_None, "tearoff" },
- { QStyle::SC_None, "indicator" },
- { QStyle::SC_None, "separator" },
- { QStyle::SC_None, "icon" },
- { QStyle::SC_None, "right-arrow" },
- { QStyle::SC_None, "branch" },
- { QStyle::SC_None, "section" },
- { QStyle::SC_None, "down-arrow" },
- { QStyle::SC_None, "up-arrow" },
- { QStyle::SC_None, "chunk" },
- { QStyle::SC_None, "tab" },
- { QStyle::SC_None, "scroller" },
- { QStyle::SC_None, "tear" },
- { QStyle::SC_SliderGroove, "groove" },
- { QStyle::SC_SliderHandle, "handle" },
- { QStyle::SC_None, "add-page" },
- { QStyle::SC_None, "sub-page"},
- { QStyle::SC_SliderTickmarks, "tick-mark" },
- { QStyle::SC_None, "pane" },
- { QStyle::SC_None, "tab-bar" },
- { QStyle::SC_None, "left-corner" },
- { QStyle::SC_None, "right-corner" },
- { QStyle::SC_None, "title" },
- { QStyle::SC_None, "close-button" },
- { QStyle::SC_None, "float-button" },
- { QStyle::SC_None, "separator" },
- { QStyle::SC_MdiCloseButton, "close-button" },
- { QStyle::SC_MdiMinButton, "minimize-button" },
- { QStyle::SC_MdiNormalButton, "normal-button" },
- { QStyle::SC_TitleBarLabel, "title" },
- { QStyle::SC_TitleBarCloseButton, "close-button" },
- { QStyle::SC_TitleBarMinButton, "minimize-button" },
- { QStyle::SC_TitleBarMaxButton, "maximize-button" },
- { QStyle::SC_TitleBarShadeButton, "shade-button" },
- { QStyle::SC_TitleBarUnshadeButton, "unshade-button" },
- { QStyle::SC_TitleBarNormalButton, "normal-button" },
- { QStyle::SC_TitleBarContextHelpButton, "contexthelp-button" },
- { QStyle::SC_TitleBarSysMenu, "sys-menu" },
- { QStyle::SC_None, "item" },
- { QStyle::SC_None, "icon" },
- { QStyle::SC_None, "text" },
- { QStyle::SC_None, "indicator" },
- { QStyle::SC_None, "corner" },
- { QStyle::SC_None, "close-button" },
-};
-
-
-struct QStyleSheetBorderImageData : public QSharedData
-{
- QStyleSheetBorderImageData()
- : horizStretch(QCss::TileMode_Unknown), vertStretch(QCss::TileMode_Unknown)
- {
- for (int i = 0; i < 4; i++)
- cuts[i] = -1;
- }
- int cuts[4];
- QPixmap pixmap;
- QImage image;
- QCss::TileMode horizStretch, vertStretch;
-};
-
-struct QStyleSheetBackgroundData : public QSharedData
-{
- QStyleSheetBackgroundData(const QBrush& b, const QPixmap& p, QCss::Repeat r,
- Qt::Alignment a, QCss::Origin o, Attachment t, QCss::Origin c)
- : brush(b), pixmap(p), repeat(r), position(a), origin(o), attachment(t), clip(c) { }
-
- bool isTransparent() const {
- if (brush.style() != Qt::NoBrush)
- return !brush.isOpaque();
- return pixmap.isNull() ? false : pixmap.hasAlpha();
- }
- QBrush brush;
- QPixmap pixmap;
- QCss::Repeat repeat;
- Qt::Alignment position;
- QCss::Origin origin;
- QCss::Attachment attachment;
- QCss::Origin clip;
-};
-
-struct QStyleSheetBorderData : public QSharedData
-{
- QStyleSheetBorderData() : bi(0)
- {
- for (int i = 0; i < 4; i++) {
- borders[i] = 0;
- styles[i] = QCss::BorderStyle_None;
- }
- }
-
- QStyleSheetBorderData(int *b, QBrush *c, QCss::BorderStyle *s, QSize *r) : bi(0)
- {
- for (int i = 0; i < 4; i++) {
- borders[i] = b[i];
- styles[i] = s[i];
- colors[i] = c[i];
- radii[i] = r[i];
- }
- }
-
- int borders[4];
- QBrush colors[4];
- QCss::BorderStyle styles[4];
- QSize radii[4]; // topleft, topright, bottomleft, bottomright
-
- const QStyleSheetBorderImageData *borderImage() const
- { return bi; }
- bool hasBorderImage() const { return bi!=0; }
-
- QSharedDataPointer<QStyleSheetBorderImageData> bi;
-
- bool isOpaque() const
- {
- for (int i = 0; i < 4; i++) {
- if (styles[i] == QCss::BorderStyle_Native || styles[i] == QCss::BorderStyle_None)
- continue;
- if (styles[i] >= QCss::BorderStyle_Dotted && styles[i] <= QCss::BorderStyle_DotDotDash
- && styles[i] != BorderStyle_Solid)
- return false;
- if (!colors[i].isOpaque())
- return false;
- if (!radii[i].isEmpty())
- return false;
- }
- if (bi != 0 && bi->pixmap.hasAlpha())
- return false;
- return true;
- }
-};
-
-
-struct QStyleSheetOutlineData : public QStyleSheetBorderData
-{
- QStyleSheetOutlineData()
- {
- for (int i = 0; i < 4; i++) {
- offsets[i] = 0;
- }
- }
-
- QStyleSheetOutlineData(int *b, QBrush *c, QCss::BorderStyle *s, QSize *r, int *o)
- : QStyleSheetBorderData(b, c, s, r)
- {
- for (int i = 0; i < 4; i++) {
- offsets[i] = o[i];
- }
- }
-
- int offsets[4];
-};
-
-struct QStyleSheetBoxData : public QSharedData
-{
- QStyleSheetBoxData(int *m, int *p, int s) : spacing(s)
- {
- for (int i = 0; i < 4; i++) {
- margins[i] = m[i];
- paddings[i] = p[i];
- }
- }
-
- int margins[4];
- int paddings[4];
-
- int spacing;
-};
-
-struct QStyleSheetPaletteData : public QSharedData
-{
- QStyleSheetPaletteData(const QBrush &fg, const QBrush &sfg, const QBrush &sbg,
- const QBrush &abg)
- : foreground(fg), selectionForeground(sfg), selectionBackground(sbg),
- alternateBackground(abg) { }
-
- QBrush foreground;
- QBrush selectionForeground;
- QBrush selectionBackground;
- QBrush alternateBackground;
-};
-
-struct QStyleSheetGeometryData : public QSharedData
-{
- QStyleSheetGeometryData(int w, int h, int minw, int minh, int maxw, int maxh)
- : minWidth(minw), minHeight(minh), width(w), height(h), maxWidth(maxw), maxHeight(maxh) { }
-
- int minWidth, minHeight, width, height, maxWidth, maxHeight;
-};
-
-struct QStyleSheetPositionData : public QSharedData
-{
- QStyleSheetPositionData(int l, int t, int r, int b, Origin o, Qt::Alignment p, QCss::PositionMode m, Qt::Alignment a = 0)
- : left(l), top(t), bottom(b), right(r), origin(o), position(p), mode(m), textAlignment(a) { }
-
- int left, top, bottom, right;
- Origin origin;
- Qt::Alignment position;
- QCss::PositionMode mode;
- Qt::Alignment textAlignment;
-};
-
-struct QStyleSheetImageData : public QSharedData
-{
- QStyleSheetImageData(const QIcon &i, Qt::Alignment a, const QSize &sz)
- : icon(i), alignment(a), size(sz) { }
-
- QIcon icon;
- Qt::Alignment alignment;
- QSize size;
-};
-
-class QRenderRule
-{
-public:
- QRenderRule() : features(0), hasFont(false), pal(0), b(0), bg(0), bd(0), ou(0), geo(0), p(0), img(0), clipset(0) { }
- QRenderRule(const QVector<QCss::Declaration> &, const QWidget *);
- ~QRenderRule() { }
-
- QRect borderRect(const QRect &r) const;
- QRect outlineRect(const QRect &r) const;
- QRect paddingRect(const QRect &r) const;
- QRect contentsRect(const QRect &r) const;
-
- enum { Margin = 1, Border = 2, Padding = 4, All=Margin|Border|Padding };
- QRect boxRect(const QRect &r, int flags = All) const;
- QSize boxSize(const QSize &s, int flags = All) const;
- QRect originRect(const QRect &rect, Origin origin) const;
-
- QPainterPath borderClip(QRect rect);
- void drawBorder(QPainter *, const QRect&);
- void drawOutline(QPainter *, const QRect&);
- void drawBorderImage(QPainter *, const QRect&);
- void drawBackground(QPainter *, const QRect&, const QPoint& = QPoint(0, 0));
- void drawBackgroundImage(QPainter *, const QRect&, QPoint = QPoint(0, 0));
- void drawFrame(QPainter *, const QRect&);
- void drawImage(QPainter *p, const QRect &rect);
- void drawRule(QPainter *, const QRect&);
- void configurePalette(QPalette *, QPalette::ColorGroup, const QWidget *, bool);
- void configurePalette(QPalette *p, QPalette::ColorRole fr, QPalette::ColorRole br);
-
- const QStyleSheetPaletteData *palette() const { return pal; }
- const QStyleSheetBoxData *box() const { return b; }
- const QStyleSheetBackgroundData *background() const { return bg; }
- const QStyleSheetBorderData *border() const { return bd; }
- const QStyleSheetOutlineData *outline() const { return ou; }
- const QStyleSheetGeometryData *geometry() const { return geo; }
- const QStyleSheetPositionData *position() const { return p; }
-
- bool hasPalette() const { return pal != 0; }
- bool hasBackground() const { return bg != 0 && (!bg->pixmap.isNull() || bg->brush.style() != Qt::NoBrush); }
- bool hasGradientBackground() const { return bg && bg->brush.style() >= Qt::LinearGradientPattern
- && bg->brush.style() <= Qt::ConicalGradientPattern; }
-
- bool hasNativeBorder() const {
- return bd == 0
- || (!bd->hasBorderImage() && bd->styles[0] == BorderStyle_Native);
- }
-
- bool hasNativeOutline() const {
- return (ou == 0
- || (!ou->hasBorderImage() && ou->styles[0] == BorderStyle_Native));
- }
-
- bool baseStyleCanDraw() const {
- if (!hasBackground() || (background()->brush.style() == Qt::NoBrush && bg->pixmap.isNull()))
- return true;
- if (bg && !bg->pixmap.isNull())
- return false;
- if (hasGradientBackground())
- return features & StyleFeature_BackgroundGradient;
- return features & StyleFeature_BackgroundColor;
- }
-
- bool hasBox() const { return b != 0; }
- bool hasBorder() const { return bd != 0; }
- bool hasOutline() const { return ou != 0; }
- bool hasPosition() const { return p != 0; }
- bool hasGeometry() const { return geo != 0; }
- bool hasDrawable() const { return !hasNativeBorder() || hasBackground() || hasImage(); }
- bool hasImage() const { return img != 0; }
-
- QSize minimumContentsSize() const
- { return geo ? QSize(geo->minWidth, geo->minHeight) : QSize(0, 0); }
- QSize minimumSize() const
- { return boxSize(minimumContentsSize()); }
-
- QSize contentsSize() const
- { return geo ? QSize(geo->width, geo->height)
- : ((img && img->size.isValid()) ? img->size : QSize()); }
- QSize contentsSize(const QSize &sz) const
- {
- QSize csz = contentsSize();
- if (csz.width() == -1) csz.setWidth(sz.width());
- if (csz.height() == -1) csz.setHeight(sz.height());
- return csz;
- }
- bool hasContentsSize() const
- { return (geo && (geo->width != -1 || geo->height != -1)) || (img && img->size.isValid()); }
-
- QSize size() const { return boxSize(contentsSize()); }
- QSize size(const QSize &sz) const { return boxSize(contentsSize(sz)); }
- QSize adjustSize(const QSize &sz)
- {
- if (!geo)
- return sz;
- QSize csz = contentsSize();
- if (csz.width() == -1) csz.setWidth(sz.width());
- if (csz.height() == -1) csz.setHeight(sz.height());
- if (geo->maxWidth != -1 && csz.width() > geo->maxWidth) csz.setWidth(geo->maxWidth);
- if (geo->maxHeight != -1 && csz.height() > geo->maxHeight) csz.setHeight(geo->maxHeight);
- csz=csz.expandedTo(QSize(geo->minWidth, geo->minHeight));
- return csz;
- }
-
- int features;
- QBrush defaultBackground;
- QFont font;
- bool hasFont;
-
- QHash<QString, QVariant> styleHints;
- bool hasStyleHint(const QString& sh) const { return styleHints.contains(sh); }
- QVariant styleHint(const QString& sh) const { return styleHints.value(sh); }
-
- void fixupBorder(int);
-
- QSharedDataPointer<QStyleSheetPaletteData> pal;
- QSharedDataPointer<QStyleSheetBoxData> b;
- QSharedDataPointer<QStyleSheetBackgroundData> bg;
- QSharedDataPointer<QStyleSheetBorderData> bd;
- QSharedDataPointer<QStyleSheetOutlineData> ou;
- QSharedDataPointer<QStyleSheetGeometryData> geo;
- QSharedDataPointer<QStyleSheetPositionData> p;
- QSharedDataPointer<QStyleSheetImageData> img;
-
- // Shouldn't be here
- void setClip(QPainter *p, const QRect &rect);
- void unsetClip(QPainter *);
- int clipset;
- QPainterPath clipPath;
-};
-
-///////////////////////////////////////////////////////////////////////////////////////////
-static const char *knownStyleHints[] = {
- "activate-on-singleclick",
- "alignment",
- "arrow-keys-navigate-into-children",
- "backward-icon",
- "button-layout",
- "cd-icon",
- "combobox-list-mousetracking",
- "combobox-popup",
- "computer-icon",
- "desktop-icon",
- "dialog-apply-icon",
- "dialog-cancel-icon",
- "dialog-close-icon",
- "dialog-discard-icon",
- "dialog-help-icon",
- "dialog-no-icon",
- "dialog-ok-icon",
- "dialog-open-icon",
- "dialog-reset-icon",
- "dialog-save-icon",
- "dialog-yes-icon",
- "dialogbuttonbox-buttons-have-icons",
- "directory-closed-icon",
- "directory-icon",
- "directory-link-icon",
- "directory-open-icon",
- "dither-disable-text",
- "dockwidget-close-icon",
- "downarrow-icon",
- "dvd-icon",
- "etch-disabled-text",
- "file-icon",
- "file-link-icon",
- "filedialog-backward-icon", // unused
- "filedialog-contentsview-icon",
- "filedialog-detailedview-icon",
- "filedialog-end-icon",
- "filedialog-infoview-icon",
- "filedialog-listview-icon",
- "filedialog-new-directory-icon",
- "filedialog-parent-directory-icon",
- "filedialog-start-icon",
- "floppy-icon",
- "forward-icon",
- "gridline-color",
- "harddisk-icon",
- "home-icon",
- "icon-size",
- "leftarrow-icon",
- "lineedit-password-character",
- "mdi-fill-space-on-maximize",
- "menu-scrollable",
- "menubar-altkey-navigation",
- "menubar-separator",
- "messagebox-critical-icon",
- "messagebox-information-icon",
- "messagebox-question-icon",
- "messagebox-text-interaction-flags",
- "messagebox-warning-icon",
- "mouse-tracking",
- "network-icon",
- "opacity",
- "paint-alternating-row-colors-for-empty-area",
- "rightarrow-icon",
- "scrollbar-contextmenu",
- "scrollbar-leftclick-absolute-position",
- "scrollbar-middleclick-absolute-position",
- "scrollbar-roll-between-buttons",
- "scrollbar-scroll-when-pointer-leaves-control",
- "scrollview-frame-around-contents",
- "show-decoration-selected",
- "spinbox-click-autorepeat-rate",
- "spincontrol-disable-on-bounds",
- "tabbar-elide-mode",
- "tabbar-prefer-no-arrows",
- "titlebar-close-icon",
- "titlebar-contexthelp-icon",
- "titlebar-maximize-icon",
- "titlebar-menu-icon",
- "titlebar-minimize-icon",
- "titlebar-normal-icon",
- "titlebar-shade-icon",
- "titlebar-unshade-icon",
- "toolbutton-popup-delay",
- "trash-icon",
- "uparrow-icon"
-};
-
-static const int numKnownStyleHints = sizeof(knownStyleHints)/sizeof(knownStyleHints[0]);
-
-static QList<QVariant> subControlLayout(const QString& layout)
-{
- QList<QVariant> buttons;
- for (int i = 0; i < layout.count(); i++) {
- int button = layout[i].toAscii();
- switch (button) {
- case 'm':
- buttons.append(PseudoElement_MdiMinButton);
- buttons.append(PseudoElement_TitleBarMinButton);
- break;
- case 'M':
- buttons.append(PseudoElement_TitleBarMaxButton);
- break;
- case 'X':
- buttons.append(PseudoElement_MdiCloseButton);
- buttons.append(PseudoElement_TitleBarCloseButton);
- break;
- case 'N':
- buttons.append(PseudoElement_MdiNormalButton);
- buttons.append(PseudoElement_TitleBarNormalButton);
- break;
- case 'I':
- buttons.append(PseudoElement_TitleBarSysMenu);
- break;
- case 'T':
- buttons.append(PseudoElement_TitleBar);
- break;
- case 'H':
- buttons.append(PseudoElement_TitleBarContextHelpButton);
- break;
- case 'S':
- buttons.append(PseudoElement_TitleBarShadeButton);
- break;
- default:
- buttons.append(button);
- break;
- }
- }
- return buttons;
-}
-
-namespace {
- struct ButtonInfo {
- QRenderRule rule;
- int element;
- int offset;
- int where;
- int width;
- };
-}
-
-QHash<QStyle::SubControl, QRect> QStyleSheetStyle::titleBarLayout(const QWidget *w, const QStyleOptionTitleBar *tb) const
-{
- QHash<QStyle::SubControl, QRect> layoutRects;
- const bool isMinimized = tb->titleBarState & Qt::WindowMinimized;
- const bool isMaximized = tb->titleBarState & Qt::WindowMaximized;
- QRenderRule subRule = renderRule(w, tb);
- QRect cr = subRule.contentsRect(tb->rect);
- QList<QVariant> layout = subRule.styleHint(QLatin1String("button-layout")).toList();
- if (layout.isEmpty())
- layout = subControlLayout(QLatin1String("I(T)HSmMX"));
-
- int offsets[3] = { 0, 0, 0 };
- enum Where { Left, Right, Center, NoWhere } where = Left;
- QList<ButtonInfo> infos;
- for (int i = 0; i < layout.count(); i++) {
- ButtonInfo info;
- info.element = layout[i].toInt();
- if (info.element == '(') {
- where = Center;
- } else if (info.element == ')') {
- where = Right;
- } else {
- switch (info.element) {
- case PseudoElement_TitleBar:
- if (!(tb->titleBarFlags & (Qt::WindowTitleHint | Qt::WindowSystemMenuHint)))
- continue;
- break;
- case PseudoElement_TitleBarContextHelpButton:
- if (!(tb->titleBarFlags & Qt::WindowContextHelpButtonHint))
- continue;
- break;
- case PseudoElement_TitleBarMinButton:
- if (!(tb->titleBarFlags & Qt::WindowMinimizeButtonHint))
- continue;
- if (isMinimized)
- info.element = PseudoElement_TitleBarNormalButton;
- break;
- case PseudoElement_TitleBarMaxButton:
- if (!(tb->titleBarFlags & Qt::WindowMaximizeButtonHint))
- continue;
- if (isMaximized)
- info.element = PseudoElement_TitleBarNormalButton;
- break;
- case PseudoElement_TitleBarShadeButton:
- if (!(tb->titleBarFlags & Qt::WindowShadeButtonHint))
- continue;
- if (isMinimized)
- info.element = PseudoElement_TitleBarUnshadeButton;
- break;
- case PseudoElement_TitleBarCloseButton:
- case PseudoElement_TitleBarSysMenu:
- if (!(tb->titleBarFlags & Qt::WindowSystemMenuHint))
- continue;
- break;
- default:
- continue;
- }
- if (info.element == PseudoElement_TitleBar) {
- info.width = tb->fontMetrics.width(tb->text) + 6;
- subRule.geo = new QStyleSheetGeometryData(info.width, tb->fontMetrics.height(), -1, -1, -1, -1);
- } else {
- subRule = renderRule(w, tb, info.element);
- info.width = subRule.size().width();
- }
- info.rule = subRule;
- info.offset = offsets[where];
- info.where = where;
- infos.append(info);
-
- offsets[where] += info.width;
- }
- }
-
- for (int i = 0; i < infos.count(); i++) {
- ButtonInfo info = infos[i];
- QRect lr = cr;
- switch (info.where) {
- case Center: {
- lr.setLeft(cr.left() + offsets[Left]);
- lr.setRight(cr.right() - offsets[Right]);
- QRect r(0, 0, offsets[Center], lr.height());
- r.moveCenter(lr.center());
- r.setLeft(r.left()+info.offset);
- r.setWidth(info.width);
- lr = r;
- break; }
- case Left:
- lr.translate(info.offset, 0);
- lr.setWidth(info.width);
- break;
- case Right:
- lr.moveLeft(cr.right() + 1 - offsets[Right] + info.offset);
- lr.setWidth(info.width);
- break;
- default:
- break;
- }
- QStyle::SubControl control = knownPseudoElements[info.element].subControl;
- layoutRects[control] = positionRect(w, info.rule, info.element, lr, tb->direction);
- }
-
- return layoutRects;
-}
-
-static QStyle::StandardPixmap subControlIcon(int pe)
-{
- switch (pe) {
- case PseudoElement_MdiCloseButton: return QStyle::SP_TitleBarCloseButton;
- case PseudoElement_MdiMinButton: return QStyle::SP_TitleBarMinButton;
- case PseudoElement_MdiNormalButton: return QStyle::SP_TitleBarNormalButton;
- case PseudoElement_TitleBarCloseButton: return QStyle::SP_TitleBarCloseButton;
- case PseudoElement_TitleBarMinButton: return QStyle::SP_TitleBarMinButton;
- case PseudoElement_TitleBarMaxButton: return QStyle::SP_TitleBarMaxButton;
- case PseudoElement_TitleBarShadeButton: return QStyle::SP_TitleBarShadeButton;
- case PseudoElement_TitleBarUnshadeButton: return QStyle::SP_TitleBarUnshadeButton;
- case PseudoElement_TitleBarNormalButton: return QStyle::SP_TitleBarNormalButton;
- case PseudoElement_TitleBarContextHelpButton: return QStyle::SP_TitleBarContextHelpButton;
- default: break;
- }
- return QStyle::SP_CustomBase;
-}
-
-QRenderRule::QRenderRule(const QVector<Declaration> &declarations, const QWidget *widget)
-: features(0), hasFont(false), pal(0), b(0), bg(0), bd(0), ou(0), geo(0), p(0), img(0), clipset(0)
-{
- QPalette palette = QApplication::palette(); // ###: ideally widget's palette
- ValueExtractor v(declarations, palette);
- features = v.extractStyleFeatures();
-
- int w = -1, h = -1, minw = -1, minh = -1, maxw = -1, maxh = -1;
- if (v.extractGeometry(&w, &h, &minw, &minh, &maxw, &maxh))
- geo = new QStyleSheetGeometryData(w, h, minw, minh, maxw, maxh);
-
- int left = 0, top = 0, right = 0, bottom = 0;
- Origin origin = Origin_Unknown;
- Qt::Alignment position = 0;
- QCss::PositionMode mode = PositionMode_Unknown;
- Qt::Alignment textAlignment = 0;
- if (v.extractPosition(&left, &top, &right, &bottom, &origin, &position, &mode, &textAlignment))
- p = new QStyleSheetPositionData(left, top, right, bottom, origin, position, mode, textAlignment);
-
- int margins[4], paddings[4], spacing = -1;
- for (int i = 0; i < 4; i++)
- margins[i] = paddings[i] = 0;
- if (v.extractBox(margins, paddings, &spacing))
- b = new QStyleSheetBoxData(margins, paddings, spacing);
-
- int borders[4];
- QBrush colors[4];
- QCss::BorderStyle styles[4];
- QSize radii[4];
- for (int i = 0; i < 4; i++) {
- borders[i] = 0;
- styles[i] = BorderStyle_None;
- }
- if (v.extractBorder(borders, colors, styles, radii))
- bd = new QStyleSheetBorderData(borders, colors, styles, radii);
-
- int offsets[4];
- for (int i = 0; i < 4; i++) {
- borders[i] = offsets[i] = 0;
- styles[i] = BorderStyle_None;
- }
- if (v.extractOutline(borders, colors, styles, radii, offsets))
- ou = new QStyleSheetOutlineData(borders, colors, styles, radii, offsets);
-
- QBrush brush;
- QString uri;
- Repeat repeat = Repeat_XY;
- Qt::Alignment alignment = Qt::AlignTop | Qt::AlignLeft;
- Attachment attachment = Attachment_Scroll;
- origin = Origin_Padding;
- Origin clip = Origin_Border;
- if (v.extractBackground(&brush, &uri, &repeat, &alignment, &origin, &attachment, &clip))
- bg = new QStyleSheetBackgroundData(brush, QPixmap(uri), repeat, alignment, origin, attachment, clip);
-
- QBrush sfg, fg;
- QBrush sbg, abg;
- if (v.extractPalette(&fg, &sfg, &sbg, &abg))
- pal = new QStyleSheetPaletteData(fg, sfg, sbg, abg);
-
- QIcon icon;
- alignment = Qt::AlignCenter;
- QSize size;
- if (v.extractImage(&icon, &alignment, &size))
- img = new QStyleSheetImageData(icon, alignment, size);
-
- int adj = -255;
- hasFont = v.extractFont(&font, &adj);
-
-#ifndef QT_NO_TOOLTIP
- if (widget && qstrcmp(widget->metaObject()->className(), "QTipLabel") == 0)
- palette = QToolTip::palette();
-#endif
-
- for (int i = 0; i < declarations.count(); i++) {
- const Declaration& decl = declarations.at(i);
- if (decl.d->propertyId == BorderImage) {
- QString uri;
- QCss::TileMode horizStretch, vertStretch;
- int cuts[4];
-
- decl.borderImageValue(&uri, cuts, &horizStretch, &vertStretch);
- if (uri.isEmpty() || uri == QLatin1String("none")) {
- if (bd && bd->bi)
- bd->bi->pixmap = QPixmap();
- } else {
- if (!bd)
- bd = new QStyleSheetBorderData;
- if (!bd->bi)
- bd->bi = new QStyleSheetBorderImageData;
-
- QStyleSheetBorderImageData *bi = bd->bi;
- bi->pixmap = QPixmap(uri);
- for (int i = 0; i < 4; i++)
- bi->cuts[i] = cuts[i];
- bi->horizStretch = horizStretch;
- bi->vertStretch = vertStretch;
- }
- } else if (decl.d->propertyId == QtBackgroundRole) {
- if (bg && bg->brush.style() != Qt::NoBrush)
- continue;
- int role = decl.d->values.at(0).variant.toInt();
- if (role >= Value_FirstColorRole && role <= Value_LastColorRole)
- defaultBackground = palette.color((QPalette::ColorRole)(role-Value_FirstColorRole));
- } else if (decl.d->property.startsWith(QLatin1String("qproperty-"), Qt::CaseInsensitive)) {
- // intentionally left blank...
- } else if (decl.d->propertyId == UnknownProperty) {
- bool knownStyleHint = false;
- for (int i = 0; i < numKnownStyleHints; i++) {
- QLatin1String styleHint(knownStyleHints[i]);
- if (decl.d->property.compare(styleHint) == 0) {
- QString hintName = QString(styleHint);
- QVariant hintValue;
- if (hintName.endsWith(QLatin1String("alignment"))) {
- hintValue = (int) decl.alignmentValue();
- } else if (hintName.endsWith(QLatin1String("color"))) {
- hintValue = (int) decl.colorValue().rgba();
- } else if (hintName.endsWith(QLatin1String("size"))) {
- hintValue = decl.sizeValue();
- } else if (hintName.endsWith(QLatin1String("icon"))) {
- hintValue = decl.iconValue();
- } else if (hintName == QLatin1String("button-layout")
- && decl.d->values.count() != 0 && decl.d->values.at(0).type == Value::String) {
- hintValue = subControlLayout(decl.d->values.at(0).variant.toString());
- } else {
- int integer;
- decl.intValue(&integer);
- hintValue = integer;
- }
- styleHints[decl.d->property] = hintValue;
- knownStyleHint = true;
- break;
- }
- }
- if (!knownStyleHint)
- qDebug("Unknown property %s", qPrintable(decl.d->property));
- }
- }
-
- if (widget) {
- QStyleSheetStyle *style = const_cast<QStyleSheetStyle *>(globalStyleSheetStyle);
- if (!style)
- style = qobject_cast<QStyleSheetStyle *>(widget->style());
- if (style)
- fixupBorder(style->nativeFrameWidth(widget));
-
- }
- if (hasBorder() && border()->hasBorderImage())
- defaultBackground = QBrush();
-}
-
-QRect QRenderRule::borderRect(const QRect& r) const
-{
- if (!hasBox())
- return r;
- const int* m = box()->margins;
- return r.adjusted(m[LeftEdge], m[TopEdge], -m[RightEdge], -m[BottomEdge]);
-}
-
-QRect QRenderRule::outlineRect(const QRect& r) const
-{
- QRect br = borderRect(r);
- if (!hasOutline())
- return br;
- const int *b = outline()->borders;
- return r.adjusted(b[LeftEdge], b[TopEdge], -b[RightEdge], -b[BottomEdge]);
-}
-
-QRect QRenderRule::paddingRect(const QRect& r) const
-{
- QRect br = borderRect(r);
- if (!hasBorder())
- return br;
- const int *b = border()->borders;
- return br.adjusted(b[LeftEdge], b[TopEdge], -b[RightEdge], -b[BottomEdge]);
-}
-
-QRect QRenderRule::contentsRect(const QRect& r) const
-{
- QRect pr = paddingRect(r);
- if (!hasBox())
- return pr;
- const int *p = box()->paddings;
- return pr.adjusted(p[LeftEdge], p[TopEdge], -p[RightEdge], -p[BottomEdge]);
-}
-
-QRect QRenderRule::boxRect(const QRect& cr, int flags) const
-{
- QRect r = cr;
- if (hasBox()) {
- if (flags & Margin) {
- const int *m = box()->margins;
- r.adjust(-m[LeftEdge], -m[TopEdge], m[RightEdge], m[BottomEdge]);
- }
- if (flags & Padding) {
- const int *p = box()->paddings;
- r.adjust(-p[LeftEdge], -p[TopEdge], p[RightEdge], p[BottomEdge]);
- }
- }
- if (hasBorder() && (flags & Border)) {
- const int *b = border()->borders;
- r.adjust(-b[LeftEdge], -b[TopEdge], b[RightEdge], b[BottomEdge]);
- }
- return r;
-}
-
-QSize QRenderRule::boxSize(const QSize &cs, int flags) const
-{
- QSize bs = boxRect(QRect(QPoint(0, 0), cs), flags).size();
- if (cs.width() < 0) bs.setWidth(-1);
- if (cs.height() < 0) bs.setHeight(-1);
- return bs;
-}
-
-void QRenderRule::fixupBorder(int nativeWidth)
-{
- if (bd == 0)
- return;
-
- if (!bd->hasBorderImage() || bd->bi->pixmap.isNull()) {
- bd->bi = 0;
- // ignore the color, border of edges that have none border-style
- QBrush color = pal ? pal->foreground : QBrush();
- const bool hasRadius = bd->radii[0].isValid() || bd->radii[1].isValid()
- || bd->radii[2].isValid() || bd->radii[3].isValid();
- for (int i = 0; i < 4; i++) {
- if ((bd->styles[i] == BorderStyle_Native) && hasRadius)
- bd->styles[i] = BorderStyle_None;
-
- switch (bd->styles[i]) {
- case BorderStyle_None:
- // border-style: none forces width to be 0
- bd->colors[i] = QBrush();
- bd->borders[i] = 0;
- break;
- case BorderStyle_Native:
- if (bd->borders[i] == 0)
- bd->borders[i] = nativeWidth;
- // intentional fall through
- default:
- if (!bd->colors[i].style() != Qt::NoBrush) // auto-acquire 'color'
- bd->colors[i] = color;
- break;
- }
- }
-
- return;
- }
-
- // inspect the border image
- QStyleSheetBorderImageData *bi = bd->bi;
- if (bi->cuts[0] == -1) {
- for (int i = 0; i < 4; i++) // assume, cut = border
- bi->cuts[i] = int(border()->borders[i]);
- }
-}
-
-void QRenderRule::drawBorderImage(QPainter *p, const QRect& rect)
-{
- setClip(p, rect);
- static const Qt::TileRule tileMode2TileRule[] = {
- Qt::StretchTile, Qt::RoundTile, Qt::StretchTile, Qt::RepeatTile, Qt::StretchTile };
-
- const QStyleSheetBorderImageData *borderImageData = border()->borderImage();
- const int *targetBorders = border()->borders;
- const int *sourceBorders = borderImageData->cuts;
- QMargins sourceMargins(sourceBorders[LeftEdge], sourceBorders[TopEdge],
- sourceBorders[RightEdge], sourceBorders[BottomEdge]);
- QMargins targetMargins(targetBorders[LeftEdge], targetBorders[TopEdge],
- targetBorders[RightEdge], targetBorders[BottomEdge]);
-
- bool wasSmoothPixmapTransform = p->renderHints() & QPainter::SmoothPixmapTransform;
- p->setRenderHint(QPainter::SmoothPixmapTransform);
- qDrawBorderPixmap(p, rect, targetMargins, borderImageData->pixmap,
- QRect(QPoint(), borderImageData->pixmap.size()), sourceMargins,
- QTileRules(tileMode2TileRule[borderImageData->horizStretch], tileMode2TileRule[borderImageData->vertStretch]));
- p->setRenderHint(QPainter::SmoothPixmapTransform, wasSmoothPixmapTransform);
- unsetClip(p);
-}
-
-QRect QRenderRule::originRect(const QRect &rect, Origin origin) const
-{
- switch (origin) {
- case Origin_Padding:
- return paddingRect(rect);
- case Origin_Border:
- return borderRect(rect);
- case Origin_Content:
- return contentsRect(rect);
- case Origin_Margin:
- default:
- return rect;
- }
-}
-
-void QRenderRule::drawBackgroundImage(QPainter *p, const QRect &rect, QPoint off)
-{
- if (!hasBackground())
- return;
-
- const QPixmap& bgp = background()->pixmap;
- if (bgp.isNull())
- return;
-
- setClip(p, borderRect(rect));
-
- if (background()->origin != background()->clip) {
- p->save();
- p->setClipRect(originRect(rect, background()->clip), Qt::IntersectClip);
- }
-
- if (background()->attachment == Attachment_Fixed)
- off = QPoint(0, 0);
-
- QRect r = originRect(rect, background()->origin);
- QRect aligned = QStyle::alignedRect(Qt::LeftToRight, background()->position, bgp.size(), r);
- QRect inter = aligned.translated(-off).intersected(r);
-
- switch (background()->repeat) {
- case Repeat_Y:
- p->drawTiledPixmap(inter.x(), r.y(), inter.width(), r.height(), bgp,
- inter.x() - aligned.x() + off.x(),
- bgp.height() - int(aligned.y() - r.y()) % bgp.height() + off.y());
- break;
- case Repeat_X:
- p->drawTiledPixmap(r.x(), inter.y(), r.width(), inter.height(), bgp,
- bgp.width() - int(aligned.x() - r.x())%bgp.width() + off.x(),
- inter.y() - aligned.y() + off.y());
- break;
- case Repeat_XY:
- p->drawTiledPixmap(r, bgp,
- QPoint(bgp.width() - int(aligned.x() - r.x())% bgp.width() + off.x(),
- bgp.height() - int(aligned.y() - r.y())%bgp.height() + off.y()));
- break;
- case Repeat_None:
- default:
- p->drawPixmap(inter.x(), inter.y(), bgp, inter.x() - aligned.x() + off.x(),
- inter.y() - aligned.y() + off.y(), inter.width(), inter.height());
- break;
- }
-
-
- if (background()->origin != background()->clip)
- p->restore();
-
- unsetClip(p);
-}
-
-void QRenderRule::drawOutline(QPainter *p, const QRect &rect)
-{
- if (!hasOutline())
- return;
-
- bool wasAntialiased = p->renderHints() & QPainter::Antialiasing;
- p->setRenderHint(QPainter::Antialiasing);
- qDrawBorder(p, rect, ou->styles, ou->borders, ou->colors, ou->radii);
- p->setRenderHint(QPainter::Antialiasing, wasAntialiased);
-}
-
-void QRenderRule::drawBorder(QPainter *p, const QRect& rect)
-{
- if (!hasBorder())
- return;
-
- if (border()->hasBorderImage()) {
- drawBorderImage(p, rect);
- return;
- }
-
- bool wasAntialiased = p->renderHints() & QPainter::Antialiasing;
- p->setRenderHint(QPainter::Antialiasing);
- qDrawBorder(p, rect, bd->styles, bd->borders, bd->colors, bd->radii);
- p->setRenderHint(QPainter::Antialiasing, wasAntialiased);
-}
-
-QPainterPath QRenderRule::borderClip(QRect r)
-{
- if (!hasBorder())
- return QPainterPath();
-
- QSize tlr, trr, blr, brr;
- qNormalizeRadii(r, bd->radii, &tlr, &trr, &blr, &brr);
- if (tlr.isNull() && trr.isNull() && blr.isNull() && brr.isNull())
- return QPainterPath();
-
- const QRectF rect(r);
- const int *borders = border()->borders;
- QPainterPath path;
- qreal curY = rect.y() + borders[TopEdge]/2.0;
- path.moveTo(rect.x() + tlr.width(), curY);
- path.lineTo(rect.right() - trr.width(), curY);
- qreal curX = rect.right() - borders[RightEdge]/2.0;
- path.arcTo(curX - 2*trr.width() + borders[RightEdge], curY,
- trr.width()*2 - borders[RightEdge], trr.height()*2 - borders[TopEdge], 90, -90);
-
- path.lineTo(curX, rect.bottom() - brr.height());
- curY = rect.bottom() - borders[BottomEdge]/2.0;
- path.arcTo(curX - 2*brr.width() + borders[RightEdge], curY - 2*brr.height() + borders[BottomEdge],
- brr.width()*2 - borders[RightEdge], brr.height()*2 - borders[BottomEdge], 0, -90);
-
- path.lineTo(rect.x() + blr.width(), curY);
- curX = rect.left() + borders[LeftEdge]/2.0;
- path.arcTo(curX, rect.bottom() - 2*blr.height() + borders[BottomEdge]/2,
- blr.width()*2 - borders[LeftEdge], blr.height()*2 - borders[BottomEdge], 270, -90);
-
- path.lineTo(curX, rect.top() + tlr.height());
- path.arcTo(curX, rect.top() + borders[TopEdge]/2,
- tlr.width()*2 - borders[LeftEdge], tlr.height()*2 - borders[TopEdge], 180, -90);
-
- path.closeSubpath();
- return path;
-}
-
-/*! \internal
- Clip the painter to the border (in case we are using radius border)
- */
-void QRenderRule::setClip(QPainter *p, const QRect &rect)
-{
- if (clipset++)
- return;
- clipPath = borderClip(rect);
- if (!clipPath.isEmpty()) {
- p->save();
- p->setClipPath(clipPath, Qt::IntersectClip);
- }
-}
-
-void QRenderRule::unsetClip(QPainter *p)
-{
- if (--clipset)
- return;
- if (!clipPath.isEmpty())
- p->restore();
-}
-
-void QRenderRule::drawBackground(QPainter *p, const QRect& rect, const QPoint& off)
-{
- QBrush brush = hasBackground() ? background()->brush : QBrush();
- if (brush.style() == Qt::NoBrush)
- brush = defaultBackground;
-
- if (brush.style() != Qt::NoBrush) {
- Origin origin = hasBackground() ? background()->clip : Origin_Border;
- // ### fix for gradients
- const QPainterPath &borderPath = borderClip(originRect(rect, origin));
- if (!borderPath.isEmpty()) {
- // Drawn intead of being used as clipping path for better visual quality
- bool wasAntialiased = p->renderHints() & QPainter::Antialiasing;
- p->setRenderHint(QPainter::Antialiasing);
- p->fillPath(borderPath, brush);
- p->setRenderHint(QPainter::Antialiasing, wasAntialiased);
- } else {
- p->fillRect(originRect(rect, origin), brush);
- }
- }
-
- drawBackgroundImage(p, rect, off);
-}
-
-void QRenderRule::drawFrame(QPainter *p, const QRect& rect)
-{
- drawBackground(p, rect);
- if (hasBorder())
- drawBorder(p, borderRect(rect));
-}
-
-void QRenderRule::drawImage(QPainter *p, const QRect &rect)
-{
- if (!hasImage())
- return;
- img->icon.paint(p, rect, img->alignment);
-}
-
-void QRenderRule::drawRule(QPainter *p, const QRect& rect)
-{
- drawFrame(p, rect);
- drawImage(p, contentsRect(rect));
-}
-
-// *shudder* , *horror*, *whoa* <-- what you might feel when you see the functions below
-void QRenderRule::configurePalette(QPalette *p, QPalette::ColorRole fr, QPalette::ColorRole br)
-{
- if (bg && bg->brush.style() != Qt::NoBrush) {
- if (br != QPalette::NoRole)
- p->setBrush(br, bg->brush);
- p->setBrush(QPalette::Window, bg->brush);
- if (bg->brush.style() == Qt::SolidPattern) {
- p->setBrush(QPalette::Light, bg->brush.color().lighter(115));
- p->setBrush(QPalette::Midlight, bg->brush.color().lighter(107));
- p->setBrush(QPalette::Dark, bg->brush.color().darker(150));
- p->setBrush(QPalette::Shadow, bg->brush.color().darker(300));
- }
- }
-
- if (!hasPalette())
- return;
-
- if (pal->foreground.style() != Qt::NoBrush) {
- if (fr != QPalette::NoRole)
- p->setBrush(fr, pal->foreground);
- p->setBrush(QPalette::WindowText, pal->foreground);
- p->setBrush(QPalette::Text, pal->foreground);
- }
- if (pal->selectionBackground.style() != Qt::NoBrush)
- p->setBrush(QPalette::Highlight, pal->selectionBackground);
- if (pal->selectionForeground.style() != Qt::NoBrush)
- p->setBrush(QPalette::HighlightedText, pal->selectionForeground);
- if (pal->alternateBackground.style() != Qt::NoBrush)
- p->setBrush(QPalette::AlternateBase, pal->alternateBackground);
-}
-
-void QRenderRule::configurePalette(QPalette *p, QPalette::ColorGroup cg, const QWidget *w, bool embedded)
-{
- if (bg && bg->brush.style() != Qt::NoBrush) {
- 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) {
- /* For embedded widgets (ComboBox, SpinBox and ScrollArea) we want the embedded widget
- * to be transparent when we have a transparent background or border image */
- if ((hasBackground() && background()->isTransparent())
- || (hasBorder() && border()->hasBorderImage() && !border()->borderImage()->pixmap.isNull()))
- p->setBrush(cg, w->backgroundRole(), Qt::NoBrush);
- }
-
- if (!hasPalette())
- return;
-
- if (pal->foreground.style() != Qt::NoBrush) {
- 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)
- p->setBrush(cg, QPalette::Highlight, pal->selectionBackground);
- if (pal->selectionForeground.style() != Qt::NoBrush)
- p->setBrush(cg, QPalette::HighlightedText, pal->selectionForeground);
- if (pal->alternateBackground.style() != Qt::NoBrush)
- p->setBrush(cg, QPalette::AlternateBase, pal->alternateBackground);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Style rules
-#define WIDGET(x) (static_cast<QWidget *>(x.ptr))
-
-static inline QWidget *parentWidget(const QWidget *w)
-{
- if(qobject_cast<const QLabel *>(w) && qstrcmp(w->metaObject()->className(), "QTipLabel") == 0) {
- QWidget *p = qvariant_cast<QWidget *>(w->property("_q_stylesheet_parent"));
- if (p)
- return p;
- }
- return w->parentWidget();
-}
-
-class QStyleSheetStyleSelector : public StyleSelector
-{
-public:
- QStyleSheetStyleSelector() { }
-
- QStringList nodeNames(NodePtr node) const
- {
- if (isNullNode(node))
- return QStringList();
- const QMetaObject *metaObject = WIDGET(node)->metaObject();
-#ifndef QT_NO_TOOLTIP
- if (qstrcmp(metaObject->className(), "QTipLabel") == 0)
- return QStringList(QLatin1String("QToolTip"));
-#endif
- QStringList result;
- do {
- result += QString::fromLatin1(metaObject->className()).replace(QLatin1Char(':'), QLatin1Char('-'));
- metaObject = metaObject->superClass();
- } while (metaObject != 0);
- return result;
- }
- QString attribute(NodePtr node, const QString& name) const
- {
- if (isNullNode(node))
- return QString();
-
- QHash<QString, QString> &cache = m_attributeCache[WIDGET(node)];
- QHash<QString, QString>::const_iterator cacheIt = cache.constFind(name);
- if (cacheIt != cache.constEnd())
- return cacheIt.value();
-
- QVariant value = WIDGET(node)->property(name.toLatin1());
- if (!value.isValid()) {
- if (name == QLatin1String("class")) {
- QString className = QString::fromLatin1(WIDGET(node)->metaObject()->className());
- if (className.contains(QLatin1Char(':')))
- className.replace(QLatin1Char(':'), QLatin1Char('-'));
- cache[name] = className;
- return className;
- } else if (name == QLatin1String("style")) {
- QStyleSheetStyle *proxy = qobject_cast<QStyleSheetStyle *>(WIDGET(node)->style());
- if (proxy) {
- QString styleName = QString::fromLatin1(proxy->baseStyle()->metaObject()->className());
- cache[name] = styleName;
- return styleName;
- }
- }
- }
- QString valueStr;
- if(value.type() == QVariant::StringList || value.type() == QVariant::List)
- valueStr = value.toStringList().join(QLatin1String(" "));
- else
- valueStr = value.toString();
- cache[name] = valueStr;
- return valueStr;
- }
- bool nodeNameEquals(NodePtr node, const QString& nodeName) const
- {
- if (isNullNode(node))
- return false;
- const QMetaObject *metaObject = WIDGET(node)->metaObject();
-#ifndef QT_NO_TOOLTIP
- if (qstrcmp(metaObject->className(), "QTipLabel") == 0)
- return nodeName == QLatin1String("QToolTip");
-#endif
- do {
- const ushort *uc = (const ushort *)nodeName.constData();
- const ushort *e = uc + nodeName.length();
- const uchar *c = (uchar *)metaObject->className();
- while (*c && uc != e && (*uc == *c || (*c == ':' && *uc == '-'))) {
- ++uc;
- ++c;
- }
- if (uc == e && !*c)
- return true;
- metaObject = metaObject->superClass();
- } while (metaObject != 0);
- return false;
- }
- bool hasAttributes(NodePtr) const
- { return true; }
- QStringList nodeIds(NodePtr node) const
- { return isNullNode(node) ? QStringList() : QStringList(WIDGET(node)->objectName()); }
- bool isNullNode(NodePtr node) const
- { return node.ptr == 0; }
- NodePtr parentNode(NodePtr node) const
- { NodePtr n; n.ptr = isNullNode(node) ? 0 : parentWidget(WIDGET(node)); return n; }
- NodePtr previousSiblingNode(NodePtr) const
- { NodePtr n; n.ptr = 0; return n; }
- NodePtr duplicateNode(NodePtr node) const
- { return node; }
- void freeNode(NodePtr) const
- { }
-
-private:
- mutable QHash<const QWidget *, QHash<QString, QString> > m_attributeCache;
-};
-
-QVector<QCss::StyleRule> QStyleSheetStyle::styleRules(const QWidget *w) const
-{
- QHash<const QWidget *, QVector<StyleRule> >::const_iterator cacheIt = styleSheetCaches->styleRulesCache.constFind(w);
- if (cacheIt != styleSheetCaches->styleRulesCache.constEnd())
- return cacheIt.value();
-
- if (!initWidget(w)) {
- return QVector<StyleRule>();
- }
-
- QStyleSheetStyleSelector styleSelector;
-
- StyleSheet defaultSs;
- QHash<const void *, StyleSheet>::const_iterator defaultCacheIt = styleSheetCaches->styleSheetCache.constFind(baseStyle());
- if (defaultCacheIt == styleSheetCaches->styleSheetCache.constEnd()) {
- defaultSs = getDefaultStyleSheet();
- QStyle *bs = baseStyle();
- styleSheetCaches->styleSheetCache.insert(bs, defaultSs);
- QObject::connect(bs, SIGNAL(destroyed(QObject*)), styleSheetCaches, SLOT(styleDestroyed(QObject*)), Qt::UniqueConnection);
- } else {
- defaultSs = defaultCacheIt.value();
- }
- styleSelector.styleSheets += defaultSs;
-
- if (!qApp->styleSheet().isEmpty()) {
- StyleSheet appSs;
- QHash<const void *, StyleSheet>::const_iterator appCacheIt = styleSheetCaches->styleSheetCache.constFind(qApp);
- if (appCacheIt == styleSheetCaches->styleSheetCache.constEnd()) {
- QString ss = qApp->styleSheet();
- if (ss.startsWith(QLatin1String("file:///")))
- ss.remove(0, 8);
- parser.init(ss, qApp->styleSheet() != ss);
- if (!parser.parse(&appSs))
- qWarning("Could not parse application stylesheet");
- appSs.origin = StyleSheetOrigin_Inline;
- appSs.depth = 1;
- styleSheetCaches->styleSheetCache.insert(qApp, appSs);
- } else {
- appSs = appCacheIt.value();
- }
- styleSelector.styleSheets += appSs;
- }
-
- QVector<QCss::StyleSheet> widgetSs;
- for (const QWidget *wid = w; wid; wid = parentWidget(wid)) {
- if (wid->styleSheet().isEmpty())
- continue;
- StyleSheet ss;
- QHash<const void *, StyleSheet>::const_iterator widCacheIt = styleSheetCaches->styleSheetCache.constFind(wid);
- if (widCacheIt == styleSheetCaches->styleSheetCache.constEnd()) {
- parser.init(wid->styleSheet());
- if (!parser.parse(&ss)) {
- parser.init(QLatin1String("* {") + wid->styleSheet() + QLatin1Char('}'));
- if (!parser.parse(&ss))
- qWarning("Could not parse stylesheet of widget %p", wid);
- }
- ss.origin = StyleSheetOrigin_Inline;
- styleSheetCaches->styleSheetCache.insert(wid, ss);
- } else {
- ss = widCacheIt.value();
- }
- widgetSs.append(ss);
- }
-
- for (int i = 0; i < widgetSs.count(); i++)
- widgetSs[i].depth = widgetSs.count() - i + 2;
-
- styleSelector.styleSheets += widgetSs;
-
- StyleSelector::NodePtr n;
- n.ptr = (void *)w;
- QVector<QCss::StyleRule> rules = styleSelector.styleRulesForNode(n);
- styleSheetCaches->styleRulesCache.insert(w, rules);
- return rules;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// Rendering rules
-static QVector<Declaration> declarations(const QVector<StyleRule> &styleRules, const QString &part, quint64 pseudoClass = PseudoClass_Unspecified)
-{
- QVector<Declaration> decls;
- for (int i = 0; i < styleRules.count(); i++) {
- const Selector& selector = styleRules.at(i).selectors.at(0);
- // Rules with pseudo elements don't cascade. This is an intentional
- // diversion for CSS
- if (part.compare(selector.pseudoElement(), Qt::CaseInsensitive) != 0)
- continue;
- quint64 negated = 0;
- quint64 cssClass = selector.pseudoClass(&negated);
- if ((pseudoClass == PseudoClass_Any) || (cssClass == PseudoClass_Unspecified)
- || ((((cssClass & pseudoClass) == cssClass)) && ((negated & pseudoClass) == 0)))
- decls += styleRules.at(i).declarations;
- }
- return decls;
-}
-
-int QStyleSheetStyle::nativeFrameWidth(const QWidget *w)
-{
- QStyle *base = baseStyle();
-
-#ifndef QT_NO_SPINBOX
- if (qobject_cast<const QAbstractSpinBox *>(w))
- return base->pixelMetric(QStyle::PM_SpinBoxFrameWidth, 0, w);
-#endif
-
-#ifndef QT_NO_COMBOBOX
- if (qobject_cast<const QComboBox *>(w))
- return base->pixelMetric(QStyle::PM_ComboBoxFrameWidth, 0, w);
-#endif
-
-#ifndef QT_NO_MENU
- if (qobject_cast<const QMenu *>(w))
- return base->pixelMetric(QStyle::PM_MenuPanelWidth, 0, w);
-#endif
-
-#ifndef QT_NO_MENUBAR
- if (qobject_cast<const QMenuBar *>(w))
- return base->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, w);
-#endif
-#ifndef QT_NO_FRAME
- if (const QFrame *frame = qobject_cast<const QFrame *>(w)) {
- if (frame->frameShape() == QFrame::NoFrame)
- return 0;
- }
-#endif
-
- if (qstrcmp(w->metaObject()->className(), "QTipLabel") == 0)
- return base->pixelMetric(QStyle::PM_ToolTipLabelFrameWidth, 0, w);
-
- return base->pixelMetric(QStyle::PM_DefaultFrameWidth, 0, w);
-}
-
-static quint64 pseudoClass(QStyle::State state)
-{
- quint64 pc = 0;
- if (state & QStyle::State_Enabled) {
- pc |= PseudoClass_Enabled;
- if (state & QStyle::State_MouseOver)
- pc |= PseudoClass_Hover;
- } else {
- pc |= PseudoClass_Disabled;
- }
- if (state & QStyle::State_Active)
- pc |= PseudoClass_Active;
- if (state & QStyle::State_Window)
- pc |= PseudoClass_Window;
- if (state & QStyle::State_Sunken)
- pc |= PseudoClass_Pressed;
- if (state & QStyle::State_HasFocus)
- pc |= PseudoClass_Focus;
- if (state & QStyle::State_On)
- pc |= (PseudoClass_On | PseudoClass_Checked);
- if (state & QStyle::State_Off)
- pc |= (PseudoClass_Off | PseudoClass_Unchecked);
- if (state & QStyle::State_NoChange)
- pc |= PseudoClass_Indeterminate;
- if (state & QStyle::State_Selected)
- pc |= PseudoClass_Selected;
- if (state & QStyle::State_Horizontal)
- pc |= PseudoClass_Horizontal;
- else
- pc |= PseudoClass_Vertical;
- if (state & (QStyle::State_Open | QStyle::State_On | QStyle::State_Sunken))
- pc |= PseudoClass_Open;
- else
- pc |= PseudoClass_Closed;
- if (state & QStyle::State_Children)
- pc |= PseudoClass_Children;
- if (state & QStyle::State_Sibling)
- pc |= PseudoClass_Sibling;
- if (state & QStyle::State_ReadOnly)
- pc |= PseudoClass_ReadOnly;
- if (state & QStyle::State_Item)
- pc |= PseudoClass_Item;
-#ifdef QT_KEYPAD_NAVIGATION
- if (state & QStyle::State_HasEditFocus)
- pc |= PseudoClass_EditFocus;
-#endif
- return pc;
-}
-
-static void qt_check_if_internal_widget(const QWidget **w, int *element)
-{
-#ifdef QT_NO_DOCKWIDGET
- Q_UNUSED(w);
- Q_UNUSED(element);
-#else
- if (*w && qstrcmp((*w)->metaObject()->className(), "QDockWidgetTitleButton") == 0) {
- if ((*w)->objectName() == QLatin1String("qt_dockwidget_closebutton")) {
- *element = PseudoElement_DockWidgetCloseButton;
- } else if ((*w)->objectName() == QLatin1String("qt_dockwidget_floatbutton")) {
- *element = PseudoElement_DockWidgetFloatButton;
- }
- *w = (*w)->parentWidget();
- }
-#endif
-}
-
-QRenderRule QStyleSheetStyle::renderRule(const QWidget *w, int element, quint64 state) const
-{
- qt_check_if_internal_widget(&w, &element);
- QHash<quint64, QRenderRule> &cache = styleSheetCaches->renderRulesCache[w][element];
- QHash<quint64, QRenderRule>::const_iterator cacheIt = cache.constFind(state);
- if (cacheIt != cache.constEnd())
- return cacheIt.value();
-
- if (!initWidget(w))
- return QRenderRule();
-
- quint64 stateMask = 0;
- const QVector<StyleRule> rules = styleRules(w);
- for (int i = 0; i < rules.count(); i++) {
- const Selector& selector = rules.at(i).selectors.at(0);
- quint64 negated = 0;
- stateMask |= selector.pseudoClass(&negated);
- stateMask |= negated;
- }
-
- cacheIt = cache.constFind(state & stateMask);
- if (cacheIt != cache.constEnd()) {
- const QRenderRule &newRule = cacheIt.value();
- cache[state] = newRule;
- return newRule;
- }
-
-
- const QString part = QLatin1String(knownPseudoElements[element].name);
- QVector<Declaration> decls = declarations(rules, part, state);
- QRenderRule newRule(decls, w);
- cache[state] = newRule;
- if ((state & stateMask) != state)
- cache[state&stateMask] = newRule;
- return newRule;
-}
-
-QRenderRule QStyleSheetStyle::renderRule(const QWidget *w, const QStyleOption *opt, int pseudoElement) const
-{
- quint64 extraClass = 0;
- QStyle::State state = opt ? opt->state : QStyle::State(QStyle::State_None);
-
- if (const QStyleOptionComplex *complex = qstyleoption_cast<const QStyleOptionComplex *>(opt)) {
- if (pseudoElement != PseudoElement_None) {
- // if not an active subcontrol, just pass enabled/disabled
- QStyle::SubControl subControl = knownPseudoElements[pseudoElement].subControl;
-
- if (!(complex->activeSubControls & subControl))
- state &= (QStyle::State_Enabled | QStyle::State_Horizontal | QStyle::State_HasFocus);
- }
-
- switch (pseudoElement) {
- case PseudoElement_ComboBoxDropDown:
- case PseudoElement_ComboBoxArrow:
- state |= (complex->state & (QStyle::State_On|QStyle::State_ReadOnly));
- break;
- case PseudoElement_SpinBoxUpButton:
- case PseudoElement_SpinBoxDownButton:
- case PseudoElement_SpinBoxUpArrow:
- case PseudoElement_SpinBoxDownArrow:
-#ifndef QT_NO_SPINBOX
- if (const QStyleOptionSpinBox *sb = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
- bool on = false;
- bool up = pseudoElement == PseudoElement_SpinBoxUpButton
- || pseudoElement == PseudoElement_SpinBoxUpArrow;
- if ((sb->stepEnabled & QAbstractSpinBox::StepUpEnabled) && up)
- on = true;
- else if ((sb->stepEnabled & QAbstractSpinBox::StepDownEnabled) && !up)
- on = true;
- state |= (on ? QStyle::State_On : QStyle::State_Off);
- }
-#endif // QT_NO_SPINBOX
- break;
- case PseudoElement_GroupBoxTitle:
- state |= (complex->state & (QStyle::State_MouseOver | QStyle::State_Sunken));
- break;
- case PseudoElement_ToolButtonMenu:
- case PseudoElement_ToolButtonMenuArrow:
- case PseudoElement_ToolButtonDownArrow:
- state |= complex->state & QStyle::State_MouseOver;
- if (complex->state & QStyle::State_Sunken ||
- complex->activeSubControls & QStyle::SC_ToolButtonMenu)
- state |= QStyle::State_Sunken;
- break;
- case PseudoElement_SliderGroove:
- state |= complex->state & QStyle::State_MouseOver;
- break;
- default:
- break;
- }
-
- if (const QStyleOptionComboBox *combo = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
- // QStyle::State_On is set when the popup is being shown
- // Propagate EditField Pressed state
- if (pseudoElement == PseudoElement_None
- && (complex->activeSubControls & QStyle::SC_ComboBoxEditField)
- && (!(state & QStyle::State_MouseOver))) {
- state |= QStyle::State_Sunken;
- }
-
- if (!combo->frame)
- extraClass |= PseudoClass_Frameless;
- if (!combo->editable)
- extraClass |= PseudoClass_ReadOnly;
- else
- extraClass |= PseudoClass_Editable;
-#ifndef QT_NO_SPINBOX
- } else if (const QStyleOptionSpinBox *spin = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
- if (!spin->frame)
- extraClass |= PseudoClass_Frameless;
-#endif // QT_NO_SPINBOX
- } else if (const QStyleOptionGroupBox *gb = qstyleoption_cast<const QStyleOptionGroupBox *>(opt)) {
- if (gb->features & QStyleOptionFrameV2::Flat)
- extraClass |= PseudoClass_Flat;
- if (gb->lineWidth == 0)
- extraClass |= PseudoClass_Frameless;
- } else if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) {
- if (tb->titleBarState & Qt::WindowMinimized) {
- extraClass |= PseudoClass_Minimized;
- }
- else if (tb->titleBarState & Qt::WindowMaximized)
- extraClass |= PseudoClass_Maximized;
- }
- } else {
- // handle simple style options
- if (const QStyleOptionMenuItem *mi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
- if (mi->menuItemType == QStyleOptionMenuItem::DefaultItem)
- extraClass |= PseudoClass_Default;
- if (mi->checkType == QStyleOptionMenuItem::Exclusive)
- extraClass |= PseudoClass_Exclusive;
- else if (mi->checkType == QStyleOptionMenuItem::NonExclusive)
- extraClass |= PseudoClass_NonExclusive;
- if (mi->checkType != QStyleOptionMenuItem::NotCheckable)
- extraClass |= (mi->checked) ? (PseudoClass_On|PseudoClass_Checked)
- : (PseudoClass_Off|PseudoClass_Unchecked);
- } else if (const QStyleOptionHeader *hdr = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
- if (hdr->position == QStyleOptionHeader::OnlyOneSection)
- extraClass |= PseudoClass_OnlyOne;
- else if (hdr->position == QStyleOptionHeader::Beginning)
- extraClass |= PseudoClass_First;
- else if (hdr->position == QStyleOptionHeader::End)
- extraClass |= PseudoClass_Last;
- else if (hdr->position == QStyleOptionHeader::Middle)
- extraClass |= PseudoClass_Middle;
-
- if (hdr->selectedPosition == QStyleOptionHeader::NextAndPreviousAreSelected)
- extraClass |= (PseudoClass_NextSelected | PseudoClass_PreviousSelected);
- else if (hdr->selectedPosition == QStyleOptionHeader::NextIsSelected)
- extraClass |= PseudoClass_NextSelected;
- else if (hdr->selectedPosition == QStyleOptionHeader::PreviousIsSelected)
- extraClass |= PseudoClass_PreviousSelected;
-#ifndef QT_NO_TABWIDGET
- } else if (const QStyleOptionTabWidgetFrame *tab = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
- switch (tab->shape) {
- case QTabBar::RoundedNorth:
- case QTabBar::TriangularNorth:
- extraClass |= PseudoClass_Top;
- break;
- case QTabBar::RoundedSouth:
- case QTabBar::TriangularSouth:
- extraClass |= PseudoClass_Bottom;
- break;
- case QTabBar::RoundedEast:
- case QTabBar::TriangularEast:
- extraClass |= PseudoClass_Left;
- break;
- case QTabBar::RoundedWest:
- case QTabBar::TriangularWest:
- extraClass |= PseudoClass_Right;
- break;
- default:
- break;
- }
-#endif
-#ifndef QT_NO_TABBAR
- } else if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
- if (tab->position == QStyleOptionTab::OnlyOneTab)
- extraClass |= PseudoClass_OnlyOne;
- else if (tab->position == QStyleOptionTab::Beginning)
- extraClass |= PseudoClass_First;
- else if (tab->position == QStyleOptionTab::End)
- extraClass |= PseudoClass_Last;
- else if (tab->position == QStyleOptionTab::Middle)
- extraClass |= PseudoClass_Middle;
-
- if (tab->selectedPosition == QStyleOptionTab::NextIsSelected)
- extraClass |= PseudoClass_NextSelected;
- else if (tab->selectedPosition == QStyleOptionTab::PreviousIsSelected)
- extraClass |= PseudoClass_PreviousSelected;
-
- switch (tab->shape) {
- case QTabBar::RoundedNorth:
- case QTabBar::TriangularNorth:
- extraClass |= PseudoClass_Top;
- break;
- case QTabBar::RoundedSouth:
- case QTabBar::TriangularSouth:
- extraClass |= PseudoClass_Bottom;
- break;
- case QTabBar::RoundedEast:
- case QTabBar::TriangularEast:
- extraClass |= PseudoClass_Left;
- break;
- case QTabBar::RoundedWest:
- case QTabBar::TriangularWest:
- extraClass |= PseudoClass_Right;
- break;
- default:
- break;
- }
-#endif // QT_NO_TABBAR
- } else if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
- if (btn->features & QStyleOptionButton::Flat)
- extraClass |= PseudoClass_Flat;
- if (btn->features & QStyleOptionButton::DefaultButton)
- extraClass |= PseudoClass_Default;
- } else if (const QStyleOptionFrame *frm = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
- if (frm->lineWidth == 0)
- extraClass |= PseudoClass_Frameless;
- if (const QStyleOptionFrameV2 *frame2 = qstyleoption_cast<const QStyleOptionFrameV2 *>(opt)) {
- if (frame2->features & QStyleOptionFrameV2::Flat)
- extraClass |= PseudoClass_Flat;
- }
- }
-#ifndef QT_NO_TOOLBAR
- else if (const QStyleOptionToolBar *tb = qstyleoption_cast<const QStyleOptionToolBar *>(opt)) {
- if (tb->toolBarArea == Qt::LeftToolBarArea)
- extraClass |= PseudoClass_Left;
- else if (tb->toolBarArea == Qt::RightToolBarArea)
- extraClass |= PseudoClass_Right;
- else if (tb->toolBarArea == Qt::TopToolBarArea)
- extraClass |= PseudoClass_Top;
- else if (tb->toolBarArea == Qt::BottomToolBarArea)
- extraClass |= PseudoClass_Bottom;
-
- if (tb->positionWithinLine == QStyleOptionToolBar::Beginning)
- extraClass |= PseudoClass_First;
- else if (tb->positionWithinLine == QStyleOptionToolBar::Middle)
- extraClass |= PseudoClass_Middle;
- else if (tb->positionWithinLine == QStyleOptionToolBar::End)
- extraClass |= PseudoClass_Last;
- else if (tb->positionWithinLine == QStyleOptionToolBar::OnlyOne)
- extraClass |= PseudoClass_OnlyOne;
- }
-#endif // QT_NO_TOOLBAR
-#ifndef QT_NO_TOOLBOX
- else if (const QStyleOptionToolBoxV2 *tab = qstyleoption_cast<const QStyleOptionToolBoxV2 *>(opt)) {
- if (tab->position == QStyleOptionToolBoxV2::OnlyOneTab)
- extraClass |= PseudoClass_OnlyOne;
- else if (tab->position == QStyleOptionToolBoxV2::Beginning)
- extraClass |= PseudoClass_First;
- else if (tab->position == QStyleOptionToolBoxV2::End)
- extraClass |= PseudoClass_Last;
- else if (tab->position == QStyleOptionToolBoxV2::Middle)
- extraClass |= PseudoClass_Middle;
-
- if (tab->selectedPosition == QStyleOptionToolBoxV2::NextIsSelected)
- extraClass |= PseudoClass_NextSelected;
- else if (tab->selectedPosition == QStyleOptionToolBoxV2::PreviousIsSelected)
- extraClass |= PseudoClass_PreviousSelected;
- }
-#endif // QT_NO_TOOLBOX
-#ifndef QT_NO_DOCKWIDGET
- else if (const QStyleOptionDockWidgetV2 *dw = qstyleoption_cast<const QStyleOptionDockWidgetV2 *>(opt)) {
- if (dw->verticalTitleBar)
- extraClass |= PseudoClass_Vertical;
- else
- extraClass |= PseudoClass_Horizontal;
- if (dw->closable)
- extraClass |= PseudoClass_Closable;
- if (dw->floatable)
- extraClass |= PseudoClass_Floatable;
- if (dw->movable)
- extraClass |= PseudoClass_Movable;
- }
-#endif // QT_NO_DOCKWIDGET
-#ifndef QT_NO_ITEMVIEWS
- else if (const QStyleOptionViewItemV2 *v2 = qstyleoption_cast<const QStyleOptionViewItemV2 *>(opt)) {
- if (v2->features & QStyleOptionViewItemV2::Alternate)
- extraClass |= PseudoClass_Alternate;
- if (const QStyleOptionViewItemV4 *v4 = qstyleoption_cast<const QStyleOptionViewItemV4 *>(opt)) {
- if (v4->viewItemPosition == QStyleOptionViewItemV4::OnlyOne)
- extraClass |= PseudoClass_OnlyOne;
- else if (v4->viewItemPosition == QStyleOptionViewItemV4::Beginning)
- extraClass |= PseudoClass_First;
- else if (v4->viewItemPosition == QStyleOptionViewItemV4::End)
- extraClass |= PseudoClass_Last;
- else if (v4->viewItemPosition == QStyleOptionViewItemV4::Middle)
- extraClass |= PseudoClass_Middle;
- }
- }
-#endif
-#ifndef QT_NO_LINEEDIT
- // LineEdit sets Sunken flag to indicate Sunken frame (argh)
- if (const QLineEdit *lineEdit = qobject_cast<const QLineEdit *>(w)) {
- state &= ~QStyle::State_Sunken;
- if (lineEdit->hasFrame()) {
- extraClass &= ~PseudoClass_Frameless;
- } else {
- extraClass |= PseudoClass_Frameless;
- }
- } else
-#endif
- if (const QFrame *frm = qobject_cast<const QFrame *>(w)) {
- if (frm->lineWidth() == 0)
- extraClass |= PseudoClass_Frameless;
- }
- }
-
- return renderRule(w, pseudoElement, pseudoClass(state) | extraClass);
-}
-
-bool QStyleSheetStyle::hasStyleRule(const QWidget *w, int part) const
-{
- QHash<int, bool> &cache = styleSheetCaches->hasStyleRuleCache[w];
- QHash<int, bool>::const_iterator cacheIt = cache.constFind(part);
- if (cacheIt != cache.constEnd())
- return cacheIt.value();
-
- if (!initWidget(w))
- return false;
-
-
- const QVector<StyleRule> &rules = styleRules(w);
- if (part == PseudoElement_None) {
- bool result = w && !rules.isEmpty();
- cache[part] = result;
- return result;
- }
-
- QString pseudoElement = QLatin1String(knownPseudoElements[part].name);
- QVector<Declaration> declarations;
- for (int i = 0; i < rules.count(); i++) {
- const Selector& selector = rules.at(i).selectors.at(0);
- if (pseudoElement.compare(selector.pseudoElement(), Qt::CaseInsensitive) == 0) {
- cache[part] = true;
- return true;
- }
- }
-
- cache[part] = false;
- return false;
-}
-
-static Origin defaultOrigin(int pe)
-{
- switch (pe) {
- case PseudoElement_ScrollBarAddPage:
- case PseudoElement_ScrollBarSubPage:
- case PseudoElement_ScrollBarAddLine:
- case PseudoElement_ScrollBarSubLine:
- case PseudoElement_ScrollBarFirst:
- case PseudoElement_ScrollBarLast:
- case PseudoElement_GroupBoxTitle:
- case PseudoElement_GroupBoxIndicator: // never used
- case PseudoElement_ToolButtonMenu:
- case PseudoElement_SliderAddPage:
- case PseudoElement_SliderSubPage:
- return Origin_Border;
-
- case PseudoElement_SpinBoxUpButton:
- case PseudoElement_SpinBoxDownButton:
- case PseudoElement_PushButtonMenuIndicator:
- case PseudoElement_ComboBoxDropDown:
- case PseudoElement_ToolButtonDownArrow:
- case PseudoElement_MenuCheckMark:
- case PseudoElement_MenuIcon:
- case PseudoElement_MenuRightArrow:
- return Origin_Padding;
-
- case PseudoElement_Indicator:
- case PseudoElement_ExclusiveIndicator:
- case PseudoElement_ComboBoxArrow:
- case PseudoElement_ScrollBarSlider:
- case PseudoElement_ScrollBarUpArrow:
- case PseudoElement_ScrollBarDownArrow:
- case PseudoElement_ScrollBarLeftArrow:
- case PseudoElement_ScrollBarRightArrow:
- case PseudoElement_SpinBoxUpArrow:
- case PseudoElement_SpinBoxDownArrow:
- case PseudoElement_ToolButtonMenuArrow:
- case PseudoElement_HeaderViewUpArrow:
- case PseudoElement_HeaderViewDownArrow:
- case PseudoElement_SliderGroove:
- case PseudoElement_SliderHandle:
- return Origin_Content;
-
- default:
- return Origin_Margin;
- }
-}
-
-static Qt::Alignment defaultPosition(int pe)
-{
- switch (pe) {
- case PseudoElement_Indicator:
- case PseudoElement_ExclusiveIndicator:
- case PseudoElement_MenuCheckMark:
- case PseudoElement_MenuIcon:
- return Qt::AlignLeft | Qt::AlignVCenter;
-
- case PseudoElement_ScrollBarAddLine:
- case PseudoElement_ScrollBarLast:
- case PseudoElement_SpinBoxDownButton:
- case PseudoElement_PushButtonMenuIndicator:
- case PseudoElement_ToolButtonDownArrow:
- return Qt::AlignRight | Qt::AlignBottom;
-
- case PseudoElement_ScrollBarSubLine:
- case PseudoElement_ScrollBarFirst:
- case PseudoElement_SpinBoxUpButton:
- case PseudoElement_ComboBoxDropDown:
- case PseudoElement_ToolButtonMenu:
- case PseudoElement_DockWidgetCloseButton:
- case PseudoElement_DockWidgetFloatButton:
- return Qt::AlignRight | Qt::AlignTop;
-
- case PseudoElement_ScrollBarUpArrow:
- case PseudoElement_ScrollBarDownArrow:
- case PseudoElement_ScrollBarLeftArrow:
- case PseudoElement_ScrollBarRightArrow:
- case PseudoElement_SpinBoxUpArrow:
- case PseudoElement_SpinBoxDownArrow:
- case PseudoElement_ComboBoxArrow:
- case PseudoElement_DownArrow:
- case PseudoElement_ToolButtonMenuArrow:
- case PseudoElement_SliderGroove:
- return Qt::AlignCenter;
-
- case PseudoElement_GroupBoxTitle:
- case PseudoElement_GroupBoxIndicator: // never used
- return Qt::AlignLeft | Qt::AlignTop;
-
- case PseudoElement_HeaderViewUpArrow:
- case PseudoElement_HeaderViewDownArrow:
- case PseudoElement_MenuRightArrow:
- return Qt::AlignRight | Qt::AlignVCenter;
-
- default:
- return 0;
- }
-}
-
-QSize QStyleSheetStyle::defaultSize(const QWidget *w, QSize sz, const QRect& rect, int pe) const
-{
- QStyle *base = baseStyle();
-
- switch (pe) {
- case PseudoElement_Indicator:
- case PseudoElement_MenuCheckMark:
- if (sz.width() == -1)
- sz.setWidth(base->pixelMetric(PM_IndicatorWidth, 0, w));
- if (sz.height() == -1)
- sz.setHeight(base->pixelMetric(PM_IndicatorHeight, 0, w));
- break;
-
- case PseudoElement_ExclusiveIndicator:
- case PseudoElement_GroupBoxIndicator:
- if (sz.width() == -1)
- sz.setWidth(base->pixelMetric(PM_ExclusiveIndicatorWidth, 0, w));
- if (sz.height() == -1)
- sz.setHeight(base->pixelMetric(PM_ExclusiveIndicatorHeight, 0, w));
- break;
-
- case PseudoElement_PushButtonMenuIndicator: {
- int pm = base->pixelMetric(PM_MenuButtonIndicator, 0, w);
- if (sz.width() == -1)
- sz.setWidth(pm);
- if (sz.height() == -1)
- sz.setHeight(pm);
- }
- break;
-
- case PseudoElement_ComboBoxDropDown:
- if (sz.width() == -1)
- sz.setWidth(16);
- break;
-
- case PseudoElement_ComboBoxArrow:
- case PseudoElement_DownArrow:
- case PseudoElement_ToolButtonMenuArrow:
- case PseudoElement_ToolButtonDownArrow:
- case PseudoElement_MenuRightArrow:
- if (sz.width() == -1)
- sz.setWidth(13);
- if (sz.height() == -1)
- sz.setHeight(13);
- break;
-
- case PseudoElement_SpinBoxUpButton:
- case PseudoElement_SpinBoxDownButton:
- if (sz.width() == -1)
- sz.setWidth(16);
- if (sz.height() == -1)
- sz.setHeight(rect.height()/2);
- break;
-
- case PseudoElement_ToolButtonMenu:
- if (sz.width() == -1)
- sz.setWidth(base->pixelMetric(PM_MenuButtonIndicator, 0, w));
- break;
-
- case PseudoElement_HeaderViewUpArrow:
- case PseudoElement_HeaderViewDownArrow: {
- int pm = base->pixelMetric(PM_HeaderMargin, 0, w);
- if (sz.width() == -1)
- sz.setWidth(pm);
- if (sz.height() == 1)
- sz.setHeight(pm);
- break;
- }
-
- case PseudoElement_ScrollBarFirst:
- case PseudoElement_ScrollBarLast:
- case PseudoElement_ScrollBarAddLine:
- case PseudoElement_ScrollBarSubLine:
- case PseudoElement_ScrollBarSlider: {
- int pm = pixelMetric(QStyle::PM_ScrollBarExtent, 0, w);
- if (sz.width() == -1)
- sz.setWidth(pm);
- if (sz.height() == -1)
- sz.setHeight(pm);
- break;
- }
-
- case PseudoElement_DockWidgetCloseButton:
- case PseudoElement_DockWidgetFloatButton: {
- int iconSize = pixelMetric(PM_SmallIconSize, 0, w);
- return QSize(iconSize, iconSize);
- }
-
- default:
- break;
- }
-
- // expand to rectangle
- if (sz.height() == -1)
- sz.setHeight(rect.height());
- if (sz.width() == -1)
- sz.setWidth(rect.width());
-
- return sz;
-}
-
-static PositionMode defaultPositionMode(int pe)
-{
- switch (pe) {
- case PseudoElement_ScrollBarFirst:
- case PseudoElement_ScrollBarLast:
- case PseudoElement_ScrollBarAddLine:
- case PseudoElement_ScrollBarSubLine:
- case PseudoElement_ScrollBarAddPage:
- case PseudoElement_ScrollBarSubPage:
- case PseudoElement_ScrollBarSlider:
- case PseudoElement_SliderGroove:
- case PseudoElement_SliderHandle:
- case PseudoElement_TabWidgetPane:
- return PositionMode_Absolute;
- default:
- return PositionMode_Static;
- }
-}
-
-QRect QStyleSheetStyle::positionRect(const QWidget *w, const QRenderRule &rule2, int pe,
- const QRect &originRect, Qt::LayoutDirection dir) const
-{
- const QStyleSheetPositionData *p = rule2.position();
- PositionMode mode = (p && p->mode != PositionMode_Unknown) ? p->mode : defaultPositionMode(pe);
- Qt::Alignment position = (p && p->position != 0) ? p->position : defaultPosition(pe);
- QRect r;
-
- if (mode != PositionMode_Absolute) {
- QSize sz = defaultSize(w, rule2.size(), originRect, pe);
- sz = sz.expandedTo(rule2.minimumContentsSize());
- r = QStyle::alignedRect(dir, position, sz, originRect);
- if (p) {
- int left = p->left ? p->left : -p->right;
- int top = p->top ? p->top : -p->bottom;
- r.translate(dir == Qt::LeftToRight ? left : -left, top);
- }
- } else {
- r = p ? originRect.adjusted(dir == Qt::LeftToRight ? p->left : p->right, p->top,
- dir == Qt::LeftToRight ? -p->right : -p->left, -p->bottom)
- : originRect;
- if (rule2.hasContentsSize()) {
- QSize sz = rule2.size().expandedTo(rule2.minimumContentsSize());
- if (sz.width() == -1) sz.setWidth(r.width());
- if (sz.height() == -1) sz.setHeight(r.height());
- r = QStyle::alignedRect(dir, position, sz, r);
- }
- }
- return r;
-}
-
-QRect QStyleSheetStyle::positionRect(const QWidget *w, const QRenderRule& rule1, const QRenderRule& rule2, int pe,
- const QRect& rect, Qt::LayoutDirection dir) const
-{
- const QStyleSheetPositionData *p = rule2.position();
- Origin origin = (p && p->origin != Origin_Unknown) ? p->origin : defaultOrigin(pe);
- QRect originRect = rule1.originRect(rect, origin);
- return positionRect(w, rule2, pe, originRect, dir);
-}
-
-
-/** \internal
- For widget that have an embedded widget (such as combobox) return that embedded widget.
- otherwise return the widget itself
- */
-static QWidget *embeddedWidget(QWidget *w)
-{
-#ifndef QT_NO_COMBOBOX
- if (QComboBox *cmb = qobject_cast<QComboBox *>(w)) {
- if (cmb->isEditable())
- return cmb->lineEdit();
- else
- return cmb;
- }
-#endif
-
-#ifndef QT_NO_SPINBOX
- if (QAbstractSpinBox *sb = qobject_cast<QAbstractSpinBox *>(w))
- return sb->findChild<QLineEdit *>();
-#endif
-
-#ifndef QT_NO_SCROLLAREA
- if (QAbstractScrollArea *sa = qobject_cast<QAbstractScrollArea *>(w))
- return sa->viewport();
-#endif
-
- return w;
-}
-
-/** \internal
- in case w is an embedded widget, return the container widget
- (i.e, the widget for which the rules actualy apply)
- (exemple, if w is a lineedit embedded in a combobox, return the combobox)
-
- if w is not embedded, return w itself
-*/
-static QWidget *containerWidget(const QWidget *w)
-{
-#ifndef QT_NO_LINEEDIT
- if (qobject_cast<const QLineEdit *>(w)) {
- //if the QLineEdit is an embeddedWidget, we need the rule of the real widget
-#ifndef QT_NO_COMBOBOX
- if (qobject_cast<const QComboBox *>(w->parentWidget()))
- return w->parentWidget();
-#endif
-#ifndef QT_NO_SPINBOX
- if (qobject_cast<const QAbstractSpinBox *>(w->parentWidget()))
- return w->parentWidget();
-#endif
- }
-#endif // QT_NO_LINEEDIT
-
-#ifndef QT_NO_SCROLLAREA
- if (const QAbstractScrollArea *sa = qobject_cast<const QAbstractScrollArea *>(w->parentWidget())) {
- if (sa->viewport() == w)
- return w->parentWidget();
- }
-#endif
-
- return const_cast<QWidget *>(w);
-}
-
-/** \internal
- returns true if the widget can NOT be styled directly
- */
-static bool unstylable(const QWidget *w)
-{
- if (w->windowType() == Qt::Desktop)
- return true;
-
- if (!w->styleSheet().isEmpty())
- return false;
-
- if (containerWidget(w) != w)
- return true;
-
-#ifndef QT_NO_FRAME
- // detect QComboBoxPrivateContainer
- else if (qobject_cast<const QFrame *>(w)) {
- if (0
-#ifndef QT_NO_COMBOBOX
- || qobject_cast<const QComboBox *>(w->parentWidget())
-#endif
- )
- return true;
- }
-#endif
- return false;
-}
-
-static quint64 extendedPseudoClass(const QWidget *w)
-{
- quint64 pc = w->isWindow() ? quint64(PseudoClass_Window) : 0;
- if (const QAbstractSlider *slider = qobject_cast<const QAbstractSlider *>(w)) {
- pc |= ((slider->orientation() == Qt::Vertical) ? PseudoClass_Vertical : PseudoClass_Horizontal);
- } else
-#ifndef QT_NO_COMBOBOX
- if (const QComboBox *combo = qobject_cast<const QComboBox *>(w)) {
- if (combo->isEditable())
- pc |= (combo->isEditable() ? PseudoClass_Editable : PseudoClass_ReadOnly);
- } else
-#endif
-#ifndef QT_NO_LINEEDIT
- if (const QLineEdit *edit = qobject_cast<const QLineEdit *>(w)) {
- pc |= (edit->isReadOnly() ? PseudoClass_ReadOnly : PseudoClass_Editable);
- } else
-#endif
- { } // required for the above ifdef'ery to work
- return pc;
-}
-
-// sets up the geometry of the widget. We set a dynamic property when
-// we modify the min/max size of the widget. The min/max size is restored
-// to their original value when a new stylesheet that does not contain
-// the CSS properties is set and when the widget has this dynamic property set.
-// This way we don't trample on users who had setup a min/max size in code and
-// don't use stylesheets at all.
-void QStyleSheetStyle::setGeometry(QWidget *w)
-{
- QRenderRule rule = renderRule(w, PseudoElement_None, PseudoClass_Enabled | extendedPseudoClass(w));
- const QStyleSheetGeometryData *geo = rule.geometry();
- if (w->property("_q_stylesheet_minw").toBool()
- && ((!rule.hasGeometry() || geo->minWidth == -1))) {
- w->setMinimumWidth(0);
- w->setProperty("_q_stylesheet_minw", QVariant());
- }
- if (w->property("_q_stylesheet_minh").toBool()
- && ((!rule.hasGeometry() || geo->minHeight == -1))) {
- w->setMinimumHeight(0);
- w->setProperty("_q_stylesheet_minh", QVariant());
- }
- if (w->property("_q_stylesheet_maxw").toBool()
- && ((!rule.hasGeometry() || geo->maxWidth == -1))) {
- w->setMaximumWidth(QWIDGETSIZE_MAX);
- w->setProperty("_q_stylesheet_maxw", QVariant());
- }
- if (w->property("_q_stylesheet_maxh").toBool()
- && ((!rule.hasGeometry() || geo->maxHeight == -1))) {
- w->setMaximumHeight(QWIDGETSIZE_MAX);
- w->setProperty("_q_stylesheet_maxh", QVariant());
- }
-
-
- if (rule.hasGeometry()) {
- if (geo->minWidth != -1) {
- w->setProperty("_q_stylesheet_minw", true);
- w->setMinimumWidth(rule.boxSize(QSize(qMax(geo->width, geo->minWidth), 0)).width());
- }
- if (geo->minHeight != -1) {
- w->setProperty("_q_stylesheet_minh", true);
- w->setMinimumHeight(rule.boxSize(QSize(0, qMax(geo->height, geo->minHeight))).height());
- }
- if (geo->maxWidth != -1) {
- w->setProperty("_q_stylesheet_maxw", true);
- w->setMaximumWidth(rule.boxSize(QSize(qMin(geo->width == -1 ? QWIDGETSIZE_MAX : geo->width,
- geo->maxWidth == -1 ? QWIDGETSIZE_MAX : geo->maxWidth), 0)).width());
- }
- if (geo->maxHeight != -1) {
- w->setProperty("_q_stylesheet_maxh", true);
- w->setMaximumHeight(rule.boxSize(QSize(0, qMin(geo->height == -1 ? QWIDGETSIZE_MAX : geo->height,
- geo->maxHeight == -1 ? QWIDGETSIZE_MAX : geo->maxHeight))).height());
- }
- }
-}
-
-void QStyleSheetStyle::setProperties(QWidget *w)
-{
- QHash<QString, QVariant> propertyHash;
- QVector<Declaration> decls = declarations(styleRules(w), QString());
-
- // run through the declarations in order
- for (int i = 0; i < decls.count(); i++) {
- const Declaration &decl = decls.at(i);
- QString property = decl.d->property;
- if (!property.startsWith(QLatin1String("qproperty-"), Qt::CaseInsensitive))
- continue;
- property.remove(0, 10); // strip "qproperty-"
- const QVariant value = w->property(property.toLatin1());
- const QMetaObject *metaObject = w->metaObject();
- int index = metaObject->indexOfProperty(property.toLatin1());
- if (index == -1) {
- qWarning() << w << " does not have a property named " << property;
- continue;
- }
- QMetaProperty metaProperty = metaObject->property(index);
- if (!metaProperty.isWritable() || !metaProperty.isDesignable()) {
- qWarning() << w << " cannot design property named " << property;
- continue;
- }
- QVariant v;
- switch (value.type()) {
- case QVariant::Icon: v = decl.iconValue(); break;
- case QVariant::Image: v = QImage(decl.uriValue()); break;
- case QVariant::Pixmap: v = QPixmap(decl.uriValue()); break;
- case QVariant::Rect: v = decl.rectValue(); break;
- case QVariant::Size: v = decl.sizeValue(); break;
- case QVariant::Color: v = decl.colorValue(); break;
- case QVariant::Brush: v = decl.brushValue(); break;
-#ifndef QT_NO_SHORTCUT
- case QVariant::KeySequence: v = QKeySequence(decl.d->values.at(0).variant.toString()); break;
-#endif
- default: v = decl.d->values.at(0).variant; break;
- }
- propertyHash[property] = v;
- }
- // apply the values
- const QList<QString> properties = propertyHash.keys();
- for (int i = 0; i < properties.count(); i++) {
- const QString &property = properties.at(i);
- w->setProperty(property.toLatin1(), propertyHash[property]);
- }
-}
-
-void QStyleSheetStyle::setPalette(QWidget *w)
-{
- struct RuleRoleMap {
- int state;
- QPalette::ColorGroup group;
- } map[3] = {
- { int(PseudoClass_Active | PseudoClass_Enabled), QPalette::Active },
- { PseudoClass_Disabled, QPalette::Disabled },
- { PseudoClass_Enabled, QPalette::Inactive }
- };
-
- QPalette p = w->palette();
- QWidget *ew = embeddedWidget(w);
-
- for (int i = 0; i < 3; i++) {
- QRenderRule rule = renderRule(w, PseudoElement_None, map[i].state | extendedPseudoClass(w));
- if (i == 0) {
- if (!w->property("_q_styleSheetWidgetFont").isValid()) {
- saveWidgetFont(w, w->font());
- }
- updateStyleSheetFont(w);
- if (ew != w)
- updateStyleSheetFont(ew);
- }
-
- rule.configurePalette(&p, map[i].group, ew, ew != w);
- }
-
- styleSheetCaches->customPaletteWidgets.insert(w, w->palette());
- w->setPalette(p);
- if (ew != w)
- ew->setPalette(p);
-}
-
-void QStyleSheetStyle::unsetPalette(QWidget *w)
-{
- if (styleSheetCaches->customPaletteWidgets.contains(w)) {
- QPalette p = styleSheetCaches->customPaletteWidgets.value(w);
- w->setPalette(p);
- QWidget *ew = embeddedWidget(w);
- if (ew != w)
- ew->setPalette(p);
- styleSheetCaches->customPaletteWidgets.remove(w);
- }
- QVariant oldFont = w->property("_q_styleSheetWidgetFont");
- if (oldFont.isValid()) {
- w->setFont(qvariant_cast<QFont>(oldFont));
- }
- if (styleSheetCaches->autoFillDisabledWidgets.contains(w)) {
- embeddedWidget(w)->setAutoFillBackground(true);
- styleSheetCaches->autoFillDisabledWidgets.remove(w);
- }
-}
-
-static void updateWidgets(const QList<const QWidget *>& widgets)
-{
- if (!styleSheetCaches->styleRulesCache.isEmpty() || !styleSheetCaches->hasStyleRuleCache.isEmpty() || !styleSheetCaches->renderRulesCache.isEmpty()) {
- for (int i = 0; i < widgets.size(); ++i) {
- const QWidget *widget = widgets.at(i);
- styleSheetCaches->styleRulesCache.remove(widget);
- styleSheetCaches->hasStyleRuleCache.remove(widget);
- styleSheetCaches->renderRulesCache.remove(widget);
- }
- }
- for (int i = 0; i < widgets.size(); ++i) {
- QWidget *widget = const_cast<QWidget *>(widgets.at(i));
- if (widget == 0)
- continue;
- widget->style()->polish(widget);
- QEvent event(QEvent::StyleChange);
- QApplication::sendEvent(widget, &event);
- widget->update();
- widget->updateGeometry();
- }
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// The stylesheet style
-int QStyleSheetStyle::numinstances = 0;
-
-QStyleSheetStyle::QStyleSheetStyle(QStyle *base)
- : QWindowsStyle(*new QStyleSheetStylePrivate), base(base), refcount(1)
-{
- ++numinstances;
- if (numinstances == 1) {
- styleSheetCaches = new QStyleSheetStyleCaches;
- }
-}
-
-QStyleSheetStyle::~QStyleSheetStyle()
-{
- --numinstances;
- if (numinstances == 0) {
- delete styleSheetCaches;
- }
-}
-QStyle *QStyleSheetStyle::baseStyle() const
-{
- if (base)
- return base;
- if (QStyleSheetStyle *me = qobject_cast<QStyleSheetStyle *>(QApplication::style()))
- return me->base;
- return QApplication::style();
-}
-
-void QStyleSheetStyleCaches::widgetDestroyed(QObject *o)
-{
- styleRulesCache.remove((const QWidget *)o);
- hasStyleRuleCache.remove((const QWidget *)o);
- renderRulesCache.remove((const QWidget *)o);
- customPaletteWidgets.remove((const QWidget *)o);
- styleSheetCache.remove((const QWidget *)o);
- autoFillDisabledWidgets.remove((const QWidget *)o);
-}
-
-void QStyleSheetStyleCaches::styleDestroyed(QObject *o)
-{
- styleSheetCache.remove(o);
-}
-
-/*!
- * Make sure that the cache will be clean by connecting destroyed if needed.
- * return false if the widget is not stylable;
- */
-bool QStyleSheetStyle::initWidget(const QWidget *w) const
-{
- if (!w)
- return false;
- if(w->testAttribute(Qt::WA_StyleSheet))
- return true;
-
- if(unstylable(w))
- return false;
-
- const_cast<QWidget *>(w)->setAttribute(Qt::WA_StyleSheet, true);
- QObject::connect(w, SIGNAL(destroyed(QObject*)), styleSheetCaches, SLOT(widgetDestroyed(QObject*)), Qt::UniqueConnection);
- return true;
-}
-
-void QStyleSheetStyle::polish(QWidget *w)
-{
- baseStyle()->polish(w);
- RECURSION_GUARD(return)
-
- if (!initWidget(w))
- return;
-
- if (styleSheetCaches->styleRulesCache.contains(w)) {
- // the widget accessed its style pointer before polish (or repolish)
- // (exemple: the QAbstractSpinBox constructor ask for the stylehint)
- styleSheetCaches->styleRulesCache.remove(w);
- styleSheetCaches->hasStyleRuleCache.remove(w);
- styleSheetCaches->renderRulesCache.remove(w);
- }
- setGeometry(w);
- setProperties(w);
- unsetPalette(w);
- setPalette(w);
-
- //set the WA_Hover attribute if one of the selector depends of the hover state
- QVector<StyleRule> rules = styleRules(w);
- for (int i = 0; i < rules.count(); i++) {
- const Selector& selector = rules.at(i).selectors.at(0);
- quint64 negated = 0;
- quint64 cssClass = selector.pseudoClass(&negated);
- if ( cssClass & PseudoClass_Hover || negated & PseudoClass_Hover) {
- w->setAttribute(Qt::WA_Hover);
- embeddedWidget(w)->setAttribute(Qt::WA_Hover);
- }
- }
-
-
-#ifndef QT_NO_SCROLLAREA
- if (QAbstractScrollArea *sa = qobject_cast<QAbstractScrollArea *>(w)) {
- QRenderRule rule = renderRule(sa, PseudoElement_None, PseudoClass_Enabled);
- if ((rule.hasBorder() && rule.border()->hasBorderImage())
- || (rule.hasBackground() && !rule.background()->pixmap.isNull())) {
- QObject::connect(sa->horizontalScrollBar(), SIGNAL(valueChanged(int)),
- sa, SLOT(update()), Qt::UniqueConnection);
- QObject::connect(sa->verticalScrollBar(), SIGNAL(valueChanged(int)),
- sa, SLOT(update()), Qt::UniqueConnection);
- }
- }
-#endif
-
-#ifndef QT_NO_PROGRESSBAR
- if (QProgressBar *pb = qobject_cast<QProgressBar *>(w)) {
- QWindowsStyle::polish(pb);
- }
-#endif
-
- QRenderRule rule = renderRule(w, PseudoElement_None, PseudoClass_Any);
- if (rule.hasDrawable() || rule.hasBox()) {
- if (w->metaObject() == &QWidget::staticMetaObject
-#ifndef QT_NO_ITEMVIEWS
- || qobject_cast<QHeaderView *>(w)
-#endif
-#ifndef QT_NO_TABBAR
- || qobject_cast<QTabBar *>(w)
-#endif
-#ifndef QT_NO_FRAME
- || qobject_cast<QFrame *>(w)
-#endif
-#ifndef QT_NO_MAINWINDOW
- || qobject_cast<QMainWindow *>(w)
-#endif
-#ifndef QT_NO_MDIAREA
- || qobject_cast<QMdiSubWindow *>(w)
-#endif
-#ifndef QT_NO_MENUBAR
- || qobject_cast<QMenuBar *>(w)
-#endif
- || qobject_cast<QDialog *>(w)) {
- w->setAttribute(Qt::WA_StyledBackground, true);
- }
- QWidget *ew = embeddedWidget(w);
- if (ew->autoFillBackground()) {
- ew->setAutoFillBackground(false);
- styleSheetCaches->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()))
- w->setAttribute(Qt::WA_OpaquePaintEvent, false);
- }
-}
-
-void QStyleSheetStyle::polish(QApplication *app)
-{
- baseStyle()->polish(app);
-}
-
-void QStyleSheetStyle::polish(QPalette &pal)
-{
- baseStyle()->polish(pal);
-}
-
-void QStyleSheetStyle::repolish(QWidget *w)
-{
- QList<const QWidget *> children = w->findChildren<const QWidget *>(QString());
- children.append(w);
- styleSheetCaches->styleSheetCache.remove(w);
- updateWidgets(children);
-}
-
-void QStyleSheetStyle::repolish(QApplication *app)
-{
- Q_UNUSED(app);
- const QList<const QWidget*> allWidgets = styleSheetCaches->styleRulesCache.keys();
- styleSheetCaches->styleSheetCache.remove(qApp);
- styleSheetCaches->styleRulesCache.clear();
- styleSheetCaches->hasStyleRuleCache.clear();
- styleSheetCaches->renderRulesCache.clear();
- updateWidgets(allWidgets);
-}
-
-void QStyleSheetStyle::unpolish(QWidget *w)
-{
- if (!w || !w->testAttribute(Qt::WA_StyleSheet)) {
- baseStyle()->unpolish(w);
- return;
- }
-
- styleSheetCaches->styleRulesCache.remove(w);
- styleSheetCaches->hasStyleRuleCache.remove(w);
- styleSheetCaches->renderRulesCache.remove(w);
- styleSheetCaches->styleSheetCache.remove(w);
- unsetPalette(w);
- w->setProperty("_q_stylesheet_minw", QVariant());
- w->setProperty("_q_stylesheet_minh", QVariant());
- w->setProperty("_q_stylesheet_maxw", QVariant());
- w->setProperty("_q_stylesheet_maxh", QVariant());
- w->setAttribute(Qt::WA_StyleSheet, false);
- QObject::disconnect(w, 0, this, 0);
-#ifndef QT_NO_SCROLLAREA
- if (QAbstractScrollArea *sa = qobject_cast<QAbstractScrollArea *>(w)) {
- QObject::disconnect(sa->horizontalScrollBar(), SIGNAL(valueChanged(int)),
- sa, SLOT(update()));
- QObject::disconnect(sa->verticalScrollBar(), SIGNAL(valueChanged(int)),
- sa, SLOT(update()));
- }
-#endif
-#ifndef QT_NO_PROGRESSBAR
- if (QProgressBar *pb = qobject_cast<QProgressBar *>(w))
- QWindowsStyle::unpolish(pb);
-#endif
- baseStyle()->unpolish(w);
-}
-
-void QStyleSheetStyle::unpolish(QApplication *app)
-{
- baseStyle()->unpolish(app);
- RECURSION_GUARD(return)
- styleSheetCaches->styleRulesCache.clear();
- styleSheetCaches->hasStyleRuleCache.clear();
- styleSheetCaches->renderRulesCache.clear();
- styleSheetCaches->styleSheetCache.remove(qApp);
-}
-
-#ifndef QT_NO_TABBAR
-inline static bool verticalTabs(QTabBar::Shape shape)
-{
- return shape == QTabBar::RoundedWest
- || shape == QTabBar::RoundedEast
- || shape == QTabBar::TriangularWest
- || shape == QTabBar::TriangularEast;
-}
-#endif // QT_NO_TABBAR
-
-void QStyleSheetStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p,
- const QWidget *w) const
-{
- RECURSION_GUARD(baseStyle()->drawComplexControl(cc, opt, p, w); return)
-
- QRenderRule rule = renderRule(w, opt);
-
- switch (cc) {
- case CC_ComboBox:
- if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
- QStyleOptionComboBox cmbOpt(*cmb);
- cmbOpt.rect = rule.borderRect(opt->rect);
- if (rule.hasNativeBorder()) {
- rule.drawBackgroundImage(p, cmbOpt.rect);
- rule.configurePalette(&cmbOpt.palette, QPalette::ButtonText, QPalette::Button);
- bool customDropDown = (opt->subControls & QStyle::SC_ComboBoxArrow)
- && (hasStyleRule(w, PseudoElement_ComboBoxDropDown) || hasStyleRule(w, PseudoElement_ComboBoxArrow));
- if (customDropDown)
- cmbOpt.subControls &= ~QStyle::SC_ComboBoxArrow;
- if (rule.baseStyleCanDraw()) {
- baseStyle()->drawComplexControl(cc, &cmbOpt, p, w);
- } else {
- QWindowsStyle::drawComplexControl(cc, &cmbOpt, p, w);
- }
- if (!customDropDown)
- return;
- } else {
- rule.drawRule(p, opt->rect);
- }
-
- if (opt->subControls & QStyle::SC_ComboBoxArrow) {
- QRenderRule subRule = renderRule(w, opt, PseudoElement_ComboBoxDropDown);
- if (subRule.hasDrawable()) {
- QRect r = subControlRect(CC_ComboBox, opt, SC_ComboBoxArrow, w);
- subRule.drawRule(p, r);
- QRenderRule subRule2 = renderRule(w, opt, PseudoElement_ComboBoxArrow);
- r = positionRect(w, subRule, subRule2, PseudoElement_ComboBoxArrow, r, opt->direction);
- subRule2.drawRule(p, r);
- } else {
- cmbOpt.subControls = QStyle::SC_ComboBoxArrow;
- QWindowsStyle::drawComplexControl(cc, &cmbOpt, p, w);
- }
- }
-
- return;
- }
- break;
-
-#ifndef QT_NO_SPINBOX
- case CC_SpinBox:
- if (const QStyleOptionSpinBox *spin = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
- QStyleOptionSpinBox spinOpt(*spin);
- rule.configurePalette(&spinOpt.palette, QPalette::ButtonText, QPalette::Button);
- rule.configurePalette(&spinOpt.palette, QPalette::Text, QPalette::Base);
- spinOpt.rect = rule.borderRect(opt->rect);
- bool customUp = true, customDown = true;
- QRenderRule upRule = renderRule(w, opt, PseudoElement_SpinBoxUpButton);
- QRenderRule downRule = renderRule(w, opt, PseudoElement_SpinBoxDownButton);
- bool upRuleMatch = upRule.hasGeometry() || upRule.hasPosition();
- bool downRuleMatch = downRule.hasGeometry() || downRule.hasPosition();
- if (rule.hasNativeBorder() && !upRuleMatch && !downRuleMatch) {
- rule.drawBackgroundImage(p, spinOpt.rect);
- customUp = (opt->subControls & QStyle::SC_SpinBoxUp)
- && (hasStyleRule(w, PseudoElement_SpinBoxUpButton) || hasStyleRule(w, PseudoElement_UpArrow));
- if (customUp)
- spinOpt.subControls &= ~QStyle::SC_SpinBoxUp;
- customDown = (opt->subControls & QStyle::SC_SpinBoxDown)
- && (hasStyleRule(w, PseudoElement_SpinBoxDownButton) || hasStyleRule(w, PseudoElement_DownArrow));
- if (customDown)
- spinOpt.subControls &= ~QStyle::SC_SpinBoxDown;
- if (rule.baseStyleCanDraw()) {
- baseStyle()->drawComplexControl(cc, &spinOpt, p, w);
- } else {
- QWindowsStyle::drawComplexControl(cc, &spinOpt, p, w);
- }
- if (!customUp && !customDown)
- return;
- } else {
- rule.drawRule(p, opt->rect);
- }
-
- if ((opt->subControls & QStyle::SC_SpinBoxUp) && customUp) {
- QRenderRule subRule = renderRule(w, opt, PseudoElement_SpinBoxUpButton);
- if (subRule.hasDrawable()) {
- QRect r = subControlRect(CC_SpinBox, opt, SC_SpinBoxUp, w);
- subRule.drawRule(p, r);
- QRenderRule subRule2 = renderRule(w, opt, PseudoElement_SpinBoxUpArrow);
- r = positionRect(w, subRule, subRule2, PseudoElement_SpinBoxUpArrow, r, opt->direction);
- subRule2.drawRule(p, r);
- } else {
- spinOpt.subControls = QStyle::SC_SpinBoxUp;
- QWindowsStyle::drawComplexControl(cc, &spinOpt, p, w);
- }
- }
-
- if ((opt->subControls & QStyle::SC_SpinBoxDown) && customDown) {
- QRenderRule subRule = renderRule(w, opt, PseudoElement_SpinBoxDownButton);
- if (subRule.hasDrawable()) {
- QRect r = subControlRect(CC_SpinBox, opt, SC_SpinBoxDown, w);
- subRule.drawRule(p, r);
- QRenderRule subRule2 = renderRule(w, opt, PseudoElement_SpinBoxDownArrow);
- r = positionRect(w, subRule, subRule2, PseudoElement_SpinBoxDownArrow, r, opt->direction);
- subRule2.drawRule(p, r);
- } else {
- spinOpt.subControls = QStyle::SC_SpinBoxDown;
- QWindowsStyle::drawComplexControl(cc, &spinOpt, p, w);
- }
- }
- return;
- }
- break;
-#endif // QT_NO_SPINBOX
-
- case CC_GroupBox:
- if (const QStyleOptionGroupBox *gb = qstyleoption_cast<const QStyleOptionGroupBox *>(opt)) {
-
- QRect labelRect, checkBoxRect, titleRect, frameRect;
- bool hasTitle = (gb->subControls & QStyle::SC_GroupBoxCheckBox) || !gb->text.isEmpty();
-
- if (!rule.hasDrawable() && (!hasTitle || !hasStyleRule(w, PseudoElement_GroupBoxTitle))
- && !hasStyleRule(w, PseudoElement_Indicator) && !rule.hasBox() && !rule.hasFont && !rule.hasPalette()) {
- // let the native style draw the combobox if there is no style for it.
- break;
- }
- rule.drawBackground(p, opt->rect);
-
- QRenderRule titleRule = renderRule(w, opt, PseudoElement_GroupBoxTitle);
- bool clipSet = false;
-
- if (hasTitle) {
- labelRect = subControlRect(CC_GroupBox, opt, SC_GroupBoxLabel, w);
- //Some native style (such as mac) may return a too small rectangle (because they use smaller fonts), so we may need to expand it a little bit.
- labelRect.setSize(labelRect.size().expandedTo(ParentStyle::subControlRect(CC_GroupBox, opt, SC_GroupBoxLabel, w).size()));
- if (gb->subControls & QStyle::SC_GroupBoxCheckBox) {
- checkBoxRect = subControlRect(CC_GroupBox, opt, SC_GroupBoxCheckBox, w);
- titleRect = titleRule.boxRect(checkBoxRect.united(labelRect));
- } else {
- titleRect = titleRule.boxRect(labelRect);
- }
- if (!titleRule.hasBackground() || !titleRule.background()->isTransparent()) {
- clipSet = true;
- p->save();
- p->setClipRegion(QRegion(opt->rect) - titleRect);
- }
- }
-
- frameRect = subControlRect(CC_GroupBox, opt, SC_GroupBoxFrame, w);
- QStyleOptionFrameV2 frame;
- frame.QStyleOption::operator=(*gb);
- frame.features = gb->features;
- frame.lineWidth = gb->lineWidth;
- frame.midLineWidth = gb->midLineWidth;
- frame.rect = frameRect;
- drawPrimitive(PE_FrameGroupBox, &frame, p, w);
-
- if (clipSet)
- p->restore();
-
- // draw background and frame of the title
- if (hasTitle)
- titleRule.drawRule(p, titleRect);
-
- // draw the indicator
- if (gb->subControls & QStyle::SC_GroupBoxCheckBox) {
- QStyleOptionButton box;
- box.QStyleOption::operator=(*gb);
- box.rect = checkBoxRect;
- drawPrimitive(PE_IndicatorCheckBox, &box, p, w);
- }
-
- // draw the text
- if (!gb->text.isEmpty()) {
- int alignment = int(Qt::AlignCenter | Qt::TextShowMnemonic);
- if (!styleHint(QStyle::SH_UnderlineShortcut, opt, w)) {
- alignment |= Qt::TextHideMnemonic;
- }
-
- QPalette pal = gb->palette;
- if (gb->textColor.isValid())
- pal.setColor(QPalette::WindowText, gb->textColor);
- titleRule.configurePalette(&pal, QPalette::WindowText, QPalette::Window);
- drawItemText(p, labelRect, alignment, pal, gb->state & State_Enabled,
- gb->text, QPalette::WindowText);
-
- if (gb->state & State_HasFocus) {
- QStyleOptionFocusRect fropt;
- fropt.QStyleOption::operator=(*gb);
- fropt.rect = labelRect;
- drawPrimitive(PE_FrameFocusRect, &fropt, p, w);
- }
- }
-
- return;
- }
- break;
-
- case CC_ToolButton:
- if (const QStyleOptionToolButton *tool = qstyleoption_cast<const QStyleOptionToolButton *>(opt)) {
- QStyleOptionToolButton toolOpt(*tool);
- rule.configurePalette(&toolOpt.palette, QPalette::ButtonText, QPalette::Button);
- toolOpt.font = rule.font.resolve(toolOpt.font);
- toolOpt.rect = rule.borderRect(opt->rect);
- bool customArrow = (tool->features & (QStyleOptionToolButton::HasMenu | QStyleOptionToolButton::MenuButtonPopup));
- bool customDropDown = tool->features & QStyleOptionToolButton::MenuButtonPopup;
- if (rule.hasNativeBorder()) {
- if (tool->subControls & SC_ToolButton) {
- //in some case (eg. the button is "auto raised") the style doesn't draw the background
- //so we need to draw the background.
- // use the same condition as in QCommonStyle
- State bflags = tool->state & ~State_Sunken;
- if (bflags & State_AutoRaise && (!(bflags & State_MouseOver) || !(bflags & State_Enabled)))
- bflags &= ~State_Raised;
- if (tool->state & State_Sunken && tool->activeSubControls & SC_ToolButton)
- bflags |= State_Sunken;
- if (!(bflags & (State_Sunken | State_On | State_Raised)))
- rule.drawBackground(p, toolOpt.rect);
- }
- customArrow = customArrow && hasStyleRule(w, PseudoElement_ToolButtonDownArrow);
- if (customArrow)
- toolOpt.features &= ~QStyleOptionToolButton::HasMenu;
- customDropDown = customDropDown && hasStyleRule(w, PseudoElement_ToolButtonMenu);
- if (customDropDown)
- toolOpt.subControls &= ~QStyle::SC_ToolButtonMenu;
-
- if (rule.baseStyleCanDraw() && !(tool->features & QStyleOptionToolButton::Arrow)) {
- baseStyle()->drawComplexControl(cc, &toolOpt, p, w);
- } else {
- QWindowsStyle::drawComplexControl(cc, &toolOpt, p, w);
- }
-
- if (!customArrow && !customDropDown)
- return;
- } else {
- rule.drawRule(p, opt->rect);
- toolOpt.rect = rule.contentsRect(opt->rect);
- if (rule.hasFont)
- toolOpt.font = rule.font;
- drawControl(CE_ToolButtonLabel, &toolOpt, p, w);
- }
-
- QRenderRule subRule = renderRule(w, opt, PseudoElement_ToolButtonMenu);
- QRect r = subControlRect(CC_ToolButton, opt, QStyle::SC_ToolButtonMenu, w);
- if (customDropDown) {
- if (opt->subControls & QStyle::SC_ToolButtonMenu) {
- if (subRule.hasDrawable()) {
- subRule.drawRule(p, r);
- } else {
- toolOpt.rect = r;
- baseStyle()->drawPrimitive(PE_IndicatorButtonDropDown, &toolOpt, p, w);
- }
- }
- }
-
- if (customArrow) {
- QRenderRule subRule2 = customDropDown ? renderRule(w, opt, PseudoElement_ToolButtonMenuArrow)
- : renderRule(w, opt, PseudoElement_ToolButtonDownArrow);
- QRect r2 = customDropDown
- ? positionRect(w, subRule, subRule2, PseudoElement_ToolButtonMenuArrow, r, opt->direction)
- : positionRect(w, rule, subRule2, PseudoElement_ToolButtonDownArrow, opt->rect, opt->direction);
- if (subRule2.hasDrawable()) {
- subRule2.drawRule(p, r2);
- } else {
- toolOpt.rect = r2;
- baseStyle()->drawPrimitive(QStyle::PE_IndicatorArrowDown, &toolOpt, p, w);
- }
- }
-
- return;
- }
- break;
-
-#ifndef QT_NO_SCROLLBAR
- case CC_ScrollBar:
- if (const QStyleOptionSlider *sb = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
- QStyleOptionSlider sbOpt(*sb);
- if (!rule.hasDrawable()) {
- sbOpt.rect = rule.borderRect(opt->rect);
- rule.drawBackgroundImage(p, opt->rect);
- baseStyle()->drawComplexControl(cc, &sbOpt, p, w);
- } else {
- rule.drawRule(p, opt->rect);
- QWindowsStyle::drawComplexControl(cc, opt, p, w);
- }
- return;
- }
- break;
-#endif // QT_NO_SCROLLBAR
-
-#ifndef QT_NO_SLIDER
- case CC_Slider:
- if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
- rule.drawRule(p, opt->rect);
-
- QRenderRule grooveSubRule = renderRule(w, opt, PseudoElement_SliderGroove);
- QRenderRule handleSubRule = renderRule(w, opt, PseudoElement_SliderHandle);
- if (!grooveSubRule.hasDrawable()) {
- QStyleOptionSlider slOpt(*slider);
- bool handleHasRule = handleSubRule.hasDrawable();
- // If the style specifies a different handler rule, draw the groove without the handler.
- if (handleHasRule)
- slOpt.subControls &= ~SC_SliderHandle;
- baseStyle()->drawComplexControl(cc, &slOpt, p, w);
- if (!handleHasRule)
- return;
- }
-
- QRect gr = subControlRect(cc, opt, SC_SliderGroove, w);
- if (slider->subControls & SC_SliderGroove) {
- grooveSubRule.drawRule(p, gr);
- }
-
- if (slider->subControls & SC_SliderHandle) {
- QRect hr = subControlRect(cc, opt, SC_SliderHandle, w);
-
- QRenderRule subRule1 = renderRule(w, opt, PseudoElement_SliderSubPage);
- if (subRule1.hasDrawable()) {
- QRect r(gr.topLeft(),
- slider->orientation == Qt::Horizontal
- ? QPoint(hr.x()+hr.width()/2, gr.y()+gr.height() - 1)
- : QPoint(gr.x()+gr.width() - 1, hr.y()+hr.height()/2));
- subRule1.drawRule(p, r);
- }
-
- QRenderRule subRule2 = renderRule(w, opt, PseudoElement_SliderAddPage);
- if (subRule2.hasDrawable()) {
- QRect r(slider->orientation == Qt::Horizontal
- ? QPoint(hr.x()+hr.width()/2+1, gr.y())
- : QPoint(gr.x(), hr.y()+hr.height()/2+1),
- gr.bottomRight());
- subRule2.drawRule(p, r);
- }
-
- handleSubRule.drawRule(p, handleSubRule.boxRect(hr, Margin));
- }
-
- if (slider->subControls & SC_SliderTickmarks) {
- // TODO...
- }
-
- return;
- }
- break;
-#endif // QT_NO_SLIDER
-
- case CC_MdiControls:
- if (hasStyleRule(w, PseudoElement_MdiCloseButton)
- || hasStyleRule(w, PseudoElement_MdiNormalButton)
- || hasStyleRule(w, PseudoElement_MdiMinButton)) {
- QList<QVariant> layout = rule.styleHint(QLatin1String("button-layout")).toList();
- if (layout.isEmpty())
- layout = subControlLayout(QLatin1String("mNX"));
-
- QStyleOptionComplex optCopy(*opt);
- optCopy.subControls = 0;
- for (int i = 0; i < layout.count(); i++) {
- int layoutButton = layout[i].toInt();
- if (layoutButton < PseudoElement_MdiCloseButton
- || layoutButton > PseudoElement_MdiNormalButton)
- continue;
- QStyle::SubControl control = knownPseudoElements[layoutButton].subControl;
- if (!(opt->subControls & control))
- continue;
- QRenderRule subRule = renderRule(w, opt, layoutButton);
- if (subRule.hasDrawable()) {
- QRect rect = subRule.boxRect(subControlRect(CC_MdiControls, opt, control, w), Margin);
- subRule.drawRule(p, rect);
- QIcon icon = standardIcon(subControlIcon(layoutButton), opt);
- icon.paint(p, subRule.contentsRect(rect), Qt::AlignCenter);
- } else {
- optCopy.subControls |= control;
- }
- }
-
- if (optCopy.subControls)
- baseStyle()->drawComplexControl(CC_MdiControls, &optCopy, p, w);
- return;
- }
- break;
-
- case CC_TitleBar:
- if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) {
- QRenderRule subRule = renderRule(w, opt, PseudoElement_TitleBar);
- if (!subRule.hasDrawable() && !subRule.hasBox() && !subRule.hasBorder())
- break;
- subRule.drawRule(p, opt->rect);
- QHash<QStyle::SubControl, QRect> layout = titleBarLayout(w, tb);
-
- QRect ir;
- ir = layout[SC_TitleBarLabel];
- if (ir.isValid()) {
- if (subRule.hasPalette())
- p->setPen(subRule.palette()->foreground.color());
- p->fillRect(ir, Qt::white);
- p->drawText(ir.x(), ir.y(), ir.width(), ir.height(), Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine, tb->text);
- }
-
- QPixmap pm;
-
- ir = layout[SC_TitleBarSysMenu];
- if (ir.isValid()) {
- QRenderRule subSubRule = renderRule(w, opt, PseudoElement_TitleBarSysMenu);
- subSubRule.drawRule(p, ir);
- ir = subSubRule.contentsRect(ir);
- if (!tb->icon.isNull()) {
- tb->icon.paint(p, ir);
- } else {
- int iconSize = pixelMetric(PM_SmallIconSize, tb, w);
- pm = standardIcon(SP_TitleBarMenuButton, 0, w).pixmap(iconSize, iconSize);
- drawItemPixmap(p, ir, Qt::AlignCenter, pm);
- }
- }
-
- ir = layout[SC_TitleBarCloseButton];
- if (ir.isValid()) {
- QRenderRule subSubRule = renderRule(w, opt, PseudoElement_TitleBarCloseButton);
- subSubRule.drawRule(p, ir);
-
- QSize sz = subSubRule.contentsRect(ir).size();
- if ((tb->titleBarFlags & Qt::WindowType_Mask) == Qt::Tool)
- pm = standardIcon(SP_DockWidgetCloseButton, 0, w).pixmap(sz);
- else
- pm = standardIcon(SP_TitleBarCloseButton, 0, w).pixmap(sz);
- drawItemPixmap(p, ir, Qt::AlignCenter, pm);
- }
-
- int pes[] = {
- PseudoElement_TitleBarMaxButton,
- PseudoElement_TitleBarMinButton,
- PseudoElement_TitleBarNormalButton,
- PseudoElement_TitleBarShadeButton,
- PseudoElement_TitleBarUnshadeButton,
- PseudoElement_TitleBarContextHelpButton
- };
-
- for (unsigned int i = 0; i < sizeof(pes)/sizeof(int); i++) {
- int pe = pes[i];
- QStyle::SubControl sc = knownPseudoElements[pe].subControl;
- ir = layout[sc];
- if (!ir.isValid())
- continue;
- QRenderRule subSubRule = renderRule(w, opt, pe);
- subSubRule.drawRule(p, ir);
- pm = standardIcon(subControlIcon(pe), 0, w).pixmap(subSubRule.contentsRect(ir).size());
- drawItemPixmap(p, ir, Qt::AlignCenter, pm);
- }
-
- return;
- }
- break;
-
-
- default:
- break;
- }
-
- baseStyle()->drawComplexControl(cc, opt, p, w);
-}
-
-void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter *p,
- const QWidget *w) const
-{
- RECURSION_GUARD(baseStyle()->drawControl(ce, opt, p, w); return)
-
- QRenderRule rule = renderRule(w, opt);
- int pe1 = PseudoElement_None, pe2 = PseudoElement_None;
- bool fallback = false;
-
- switch (ce) {
- case CE_ToolButtonLabel:
- if (const QStyleOptionToolButton *btn = qstyleoption_cast<const QStyleOptionToolButton *>(opt)) {
- if (rule.hasBox() || btn->features & QStyleOptionToolButton::Arrow) {
- QCommonStyle::drawControl(ce, opt, p, w);
- } else {
- QStyleOptionToolButton butOpt(*btn);
- rule.configurePalette(&butOpt.palette, QPalette::ButtonText, QPalette::Button);
- baseStyle()->drawControl(ce, &butOpt, p, w);
- }
- return;
- }
- break;
-
- case CE_FocusFrame:
- if (!rule.hasNativeBorder()) {
- rule.drawBorder(p, opt->rect);
- return;
- }
- break;
-
- case CE_PushButton:
- if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
- if (rule.hasDrawable() || rule.hasBox() || rule.hasPosition() || rule.hasPalette() ||
- ((btn->features & QStyleOptionButton::HasMenu) && hasStyleRule(w, PseudoElement_PushButtonMenuIndicator))) {
- ParentStyle::drawControl(ce, opt, p, w);
- return;
- }
- }
- break;
- case CE_PushButtonBevel:
- if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
- QStyleOptionButton btnOpt(*btn);
- btnOpt.rect = rule.borderRect(opt->rect);
- if (rule.hasNativeBorder()) {
- rule.drawBackgroundImage(p, btnOpt.rect);
- rule.configurePalette(&btnOpt.palette, QPalette::ButtonText, QPalette::Button);
- bool customMenu = (btn->features & QStyleOptionButton::HasMenu
- && hasStyleRule(w, PseudoElement_PushButtonMenuIndicator));
- if (customMenu)
- btnOpt.features &= ~QStyleOptionButton::HasMenu;
- if (rule.baseStyleCanDraw()) {
- baseStyle()->drawControl(ce, &btnOpt, p, w);
- } else {
- QWindowsStyle::drawControl(ce, &btnOpt, p, w);
- }
- if (!customMenu)
- return;
- } else {
- rule.drawRule(p, opt->rect);
- }
-
- if (btn->features & QStyleOptionButton::HasMenu) {
- QRenderRule subRule = renderRule(w, opt, PseudoElement_PushButtonMenuIndicator);
- QRect ir = positionRect(w, rule, subRule, PseudoElement_PushButtonMenuIndicator, opt->rect, opt->direction);
- if (subRule.hasDrawable()) {
- subRule.drawRule(p, ir);
- } else {
- btnOpt.rect = ir;
- baseStyle()->drawPrimitive(PE_IndicatorArrowDown, &btnOpt, p, w);
- }
- }
- }
- return;
-
- case CE_PushButtonLabel:
- if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
- QStyleOptionButton butOpt(*button);
- rule.configurePalette(&butOpt.palette, QPalette::ButtonText, QPalette::Button);
- if (rule.hasPosition() && rule.position()->textAlignment != 0) {
- Qt::Alignment textAlignment = rule.position()->textAlignment;
- QRect textRect = button->rect;
- uint tf = Qt::TextShowMnemonic;
- const uint verticalAlignMask = Qt::AlignVCenter | Qt::AlignTop | Qt::AlignLeft;
- tf |= (textAlignment & verticalAlignMask) ? (textAlignment & verticalAlignMask) : Qt::AlignVCenter;
- if (!styleHint(SH_UnderlineShortcut, button, w))
- tf |= Qt::TextHideMnemonic;
- if (!button->icon.isNull()) {
- //Group both icon and text
- QRect iconRect;
- QIcon::Mode mode = button->state & State_Enabled ? QIcon::Normal : QIcon::Disabled;
- if (mode == QIcon::Normal && button->state & State_HasFocus)
- mode = QIcon::Active;
- QIcon::State state = QIcon::Off;
- if (button->state & State_On)
- state = QIcon::On;
-
- QPixmap pixmap = button->icon.pixmap(button->iconSize, mode, state);
- int labelWidth = pixmap.width();
- int labelHeight = pixmap.height();
- int iconSpacing = 4;//### 4 is currently hardcoded in QPushButton::sizeHint()
- int textWidth = button->fontMetrics.boundingRect(opt->rect, tf, button->text).width();
- if (!button->text.isEmpty())
- labelWidth += (textWidth + iconSpacing);
-
- //Determine label alignment:
- if (textAlignment & Qt::AlignLeft) { /*left*/
- iconRect = QRect(textRect.x(), textRect.y() + (textRect.height() - labelHeight) / 2,
- pixmap.width(), pixmap.height());
- } else if (textAlignment & Qt::AlignHCenter) { /* center */
- iconRect = QRect(textRect.x() + (textRect.width() - labelWidth) / 2,
- textRect.y() + (textRect.height() - labelHeight) / 2,
- pixmap.width(), pixmap.height());
- } else { /*right*/
- iconRect = QRect(textRect.x() + textRect.width() - labelWidth,
- textRect.y() + (textRect.height() - labelHeight) / 2,
- pixmap.width(), pixmap.height());
- }
-
- iconRect = visualRect(button->direction, textRect, iconRect);
-
- tf |= Qt::AlignLeft; //left align, we adjust the text-rect instead
-
- if (button->direction == Qt::RightToLeft)
- textRect.setRight(iconRect.left() - iconSpacing);
- else
- textRect.setLeft(iconRect.left() + iconRect.width() + iconSpacing);
-
- if (button->state & (State_On | State_Sunken))
- iconRect.translate(pixelMetric(PM_ButtonShiftHorizontal, opt, w),
- pixelMetric(PM_ButtonShiftVertical, opt, w));
- p->drawPixmap(iconRect, pixmap);
- } else {
- tf |= textAlignment;
- }
- if (button->state & (State_On | State_Sunken))
- textRect.translate(pixelMetric(PM_ButtonShiftHorizontal, opt, w),
- pixelMetric(PM_ButtonShiftVertical, opt, w));
-
- if (button->features & QStyleOptionButton::HasMenu) {
- int indicatorSize = pixelMetric(PM_MenuButtonIndicator, button, w);
- if (button->direction == Qt::LeftToRight)
- textRect = textRect.adjusted(0, 0, -indicatorSize, 0);
- else
- textRect = textRect.adjusted(indicatorSize, 0, 0, 0);
- }
- drawItemText(p, textRect, tf, butOpt.palette, (button->state & State_Enabled),
- button->text, QPalette::ButtonText);
- } else {
- ParentStyle::drawControl(ce, &butOpt, p, w);
- }
- }
- return;
-
- case CE_RadioButton:
- case CE_CheckBox:
- if (rule.hasBox() || !rule.hasNativeBorder() || rule.hasDrawable() || hasStyleRule(w, PseudoElement_Indicator)) {
- rule.drawRule(p, opt->rect);
- ParentStyle::drawControl(ce, opt, p, w);
- return;
- } else if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
- QStyleOptionButton butOpt(*btn);
- rule.configurePalette(&butOpt.palette, QPalette::ButtonText, QPalette::Button);
- baseStyle()->drawControl(ce, &butOpt, p, w);
- return;
- }
- break;
- case CE_RadioButtonLabel:
- case CE_CheckBoxLabel:
- if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
- QStyleOptionButton butOpt(*btn);
- rule.configurePalette(&butOpt.palette, QPalette::ButtonText, QPalette::Button);
- ParentStyle::drawControl(ce, &butOpt, p, w);
- }
- return;
-
- case CE_Splitter:
- pe1 = PseudoElement_SplitterHandle;
- break;
-
- case CE_ToolBar:
- if (rule.hasBackground()) {
- rule.drawBackground(p, opt->rect);
- }
- if (rule.hasBorder()) {
- rule.drawBorder(p, rule.borderRect(opt->rect));
- } else {
-#ifndef QT_NO_TOOLBAR
- if (const QStyleOptionToolBar *tb = qstyleoption_cast<const QStyleOptionToolBar *>(opt)) {
- QStyleOptionToolBar newTb(*tb);
- newTb.rect = rule.borderRect(opt->rect);
- baseStyle()->drawControl(ce, &newTb, p, w);
- }
-#endif // QT_NO_TOOLBAR
- }
- return;
-
- case CE_MenuEmptyArea:
- case CE_MenuBarEmptyArea:
- if (rule.hasDrawable()) {
- // Drawn by PE_Widget
- return;
- }
- break;
-
- case CE_MenuTearoff:
- case CE_MenuScroller:
- if (const QStyleOptionMenuItem *m = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
- QStyleOptionMenuItem mi(*m);
- int pe = ce == CE_MenuTearoff ? PseudoElement_MenuTearoff : PseudoElement_MenuScroller;
- QRenderRule subRule = renderRule(w, opt, pe);
- mi.rect = subRule.contentsRect(opt->rect);
- rule.configurePalette(&mi.palette, QPalette::ButtonText, QPalette::Button);
- subRule.configurePalette(&mi.palette, QPalette::ButtonText, QPalette::Button);
-
- if (subRule.hasDrawable()) {
- subRule.drawRule(p, opt->rect);
- } else {
- baseStyle()->drawControl(ce, &mi, p, w);
- }
- }
- return;
-
- case CE_MenuItem:
- if (const QStyleOptionMenuItem *m = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
- QStyleOptionMenuItem mi(*m);
-
- int pseudo = (mi.menuItemType == QStyleOptionMenuItem::Separator) ? PseudoElement_MenuSeparator : PseudoElement_Item;
- QRenderRule subRule = renderRule(w, opt, pseudo);
- mi.rect = subRule.contentsRect(opt->rect);
- rule.configurePalette(&mi.palette, QPalette::ButtonText, QPalette::Button);
- rule.configurePalette(&mi.palette, QPalette::HighlightedText, QPalette::Highlight);
- subRule.configurePalette(&mi.palette, QPalette::ButtonText, QPalette::Button);
- subRule.configurePalette(&mi.palette, QPalette::HighlightedText, QPalette::Highlight);
- QFont oldFont = p->font();
- if (subRule.hasFont)
- p->setFont(subRule.font.resolve(p->font()));
-
- // We fall back to drawing with the style sheet code whenever at least one of the
- // items are styled in an incompatible way, such as having a background image.
- QRenderRule allRules = renderRule(w, PseudoElement_Item, PseudoClass_Any);
-
- if ((pseudo == PseudoElement_MenuSeparator) && subRule.hasDrawable()) {
- subRule.drawRule(p, opt->rect);
- } else if ((pseudo == PseudoElement_Item)
- && (allRules.hasBox() || allRules.hasBorder()
- || (allRules.background() && !allRules.background()->pixmap.isNull()))) {
- subRule.drawRule(p, opt->rect);
- if (subRule.hasBackground()) {
- mi.palette.setBrush(QPalette::Highlight, Qt::NoBrush);
- mi.palette.setBrush(QPalette::Button, Qt::NoBrush);
- } else {
- mi.palette.setBrush(QPalette::Highlight, mi.palette.brush(QPalette::Button));
- }
- mi.palette.setBrush(QPalette::HighlightedText, mi.palette.brush(QPalette::ButtonText));
-
- bool checkable = mi.checkType != QStyleOptionMenuItem::NotCheckable;
- bool checked = checkable ? mi.checked : false;
-
- bool dis = !(opt->state & QStyle::State_Enabled),
- act = opt->state & QStyle::State_Selected;
-
- if (!mi.icon.isNull()) {
- QIcon::Mode mode = dis ? QIcon::Disabled : QIcon::Normal;
- if (act && !dis)
- mode = QIcon::Active;
- QPixmap pixmap;
- if (checked)
- pixmap = mi.icon.pixmap(pixelMetric(PM_SmallIconSize), mode, QIcon::On);
- else
- pixmap = mi.icon.pixmap(pixelMetric(PM_SmallIconSize), mode);
- int pixw = pixmap.width();
- int pixh = pixmap.height();
- QRenderRule iconRule = renderRule(w, opt, PseudoElement_MenuIcon);
- if (!iconRule.hasGeometry()) {
- iconRule.geo = new QStyleSheetGeometryData(pixw, pixh, pixw, pixh, -1, -1);
- } else {
- iconRule.geo->width = pixw;
- iconRule.geo->height = pixh;
- }
- QRect iconRect = positionRect(w, subRule, iconRule, PseudoElement_MenuIcon, opt->rect, opt->direction);
- iconRule.drawRule(p, iconRect);
- QRect pmr(0, 0, pixw, pixh);
- pmr.moveCenter(iconRect.center());
- p->drawPixmap(pmr.topLeft(), pixmap);
- } else if (checkable) {
- QRenderRule subSubRule = renderRule(w, opt, PseudoElement_MenuCheckMark);
- if (subSubRule.hasDrawable() || checked) {
- QStyleOptionMenuItem newMi = mi;
- newMi.rect = positionRect(w, subRule, subSubRule, PseudoElement_MenuCheckMark, opt->rect, opt->direction);
- drawPrimitive(PE_IndicatorMenuCheckMark, &newMi, p, w);
- }
- }
-
- QRect textRect = subRule.contentsRect(opt->rect);
- textRect.setWidth(textRect.width() - mi.tabWidth);
- QString s = mi.text;
- p->setPen(mi.palette.buttonText().color());
- if (!s.isEmpty()) {
- int text_flags = Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
- if (!styleHint(SH_UnderlineShortcut, &mi, w))
- text_flags |= Qt::TextHideMnemonic;
- int t = s.indexOf(QLatin1Char('\t'));
- if (t >= 0) {
- QRect vShortcutRect = visualRect(opt->direction, mi.rect,
- QRect(textRect.topRight(), QPoint(mi.rect.right(), textRect.bottom())));
- p->drawText(vShortcutRect, text_flags, s.mid(t + 1));
- s = s.left(t);
- }
- p->drawText(textRect, text_flags, s.left(t));
- }
-
- if (mi.menuItemType == QStyleOptionMenuItem::SubMenu) {// draw sub menu arrow
- PrimitiveElement arrow = (opt->direction == Qt::RightToLeft) ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight;
- QRenderRule subRule2 = renderRule(w, opt, PseudoElement_MenuRightArrow);
- mi.rect = positionRect(w, subRule, subRule2, PseudoElement_MenuRightArrow, opt->rect, mi.direction);
- drawPrimitive(arrow, &mi, p, w);
- }
- } else if (hasStyleRule(w, PseudoElement_MenuCheckMark) || hasStyleRule(w, PseudoElement_MenuRightArrow)) {
- QWindowsStyle::drawControl(ce, &mi, p, w);
- if (mi.checkType != QStyleOptionMenuItem::NotCheckable && !mi.checked) {
- // We have a style defined, but QWindowsStyle won't draw anything if not checked.
- // So we mimick what QWindowsStyle would do.
- int checkcol = qMax<int>(mi.maxIconWidth, QWindowsStylePrivate::windowsCheckMarkWidth);
- QRect vCheckRect = visualRect(opt->direction, mi.rect, QRect(mi.rect.x(), mi.rect.y(), checkcol, mi.rect.height()));
- if (mi.state.testFlag(State_Enabled) && mi.state.testFlag(State_Selected)) {
- qDrawShadePanel(p, vCheckRect, mi.palette, true, 1, &mi.palette.brush(QPalette::Button));
- } else {
- QBrush fill(mi.palette.light().color(), Qt::Dense4Pattern);
- qDrawShadePanel(p, vCheckRect, mi.palette, true, 1, &fill);
- }
- QRenderRule subSubRule = renderRule(w, opt, PseudoElement_MenuCheckMark);
- if (subSubRule.hasDrawable()) {
- QStyleOptionMenuItem newMi(mi);
- newMi.rect = visualRect(opt->direction, mi.rect, QRect(mi.rect.x() + QWindowsStylePrivate::windowsItemFrame,
- mi.rect.y() + QWindowsStylePrivate::windowsItemFrame,
- checkcol - 2 * QWindowsStylePrivate::windowsItemFrame,
- mi.rect.height() - 2 * QWindowsStylePrivate::windowsItemFrame));
- drawPrimitive(PE_IndicatorMenuCheckMark, &newMi, p, w);
- }
- }
- } else {
- if (rule.hasDrawable() && !subRule.hasDrawable() && !(opt->state & QStyle::State_Selected)) {
- mi.palette.setColor(QPalette::Window, Qt::transparent);
- mi.palette.setColor(QPalette::Button, Qt::transparent);
- }
- if (rule.baseStyleCanDraw() && subRule.baseStyleCanDraw()) {
- baseStyle()->drawControl(ce, &mi, p, w);
- } else {
- ParentStyle::drawControl(ce, &mi, p, w);
- }
- }
-
- if (subRule.hasFont)
- p->setFont(oldFont);
-
- return;
- }
- return;
-
- case CE_MenuBarItem:
- if (const QStyleOptionMenuItem *m = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
- QStyleOptionMenuItem mi(*m);
- QRenderRule subRule = renderRule(w, opt, PseudoElement_Item);
- mi.rect = subRule.contentsRect(opt->rect);
- rule.configurePalette(&mi.palette, QPalette::ButtonText, QPalette::Button);
- subRule.configurePalette(&mi.palette, QPalette::ButtonText, QPalette::Button);
-
- if (subRule.hasDrawable()) {
- subRule.drawRule(p, opt->rect);
- QCommonStyle::drawControl(ce, &mi, p, w);
- } else {
- if (rule.hasDrawable() && !(opt->state & QStyle::State_Selected)) {
- // So that the menu bar background is not hidden by the items
- mi.palette.setColor(QPalette::Window, Qt::transparent);
- mi.palette.setColor(QPalette::Button, Qt::transparent);
- }
- baseStyle()->drawControl(ce, &mi, p, w);
- }
- }
- return;
-
-#ifndef QT_NO_COMBOBOX
- case CE_ComboBoxLabel:
- if (!rule.hasBox())
- break;
- if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
- QRect editRect = subControlRect(CC_ComboBox, cb, SC_ComboBoxEditField, w);
- p->save();
- p->setClipRect(editRect);
- if (!cb->currentIcon.isNull()) {
- int spacing = rule.hasBox() ? rule.box()->spacing : -1;
- if (spacing == -1)
- spacing = 6;
- QIcon::Mode mode = cb->state & State_Enabled ? QIcon::Normal : QIcon::Disabled;
- QPixmap pixmap = cb->currentIcon.pixmap(cb->iconSize, mode);
- QRect iconRect(editRect);
- iconRect.setWidth(cb->iconSize.width());
- iconRect = alignedRect(cb->direction,
- Qt::AlignLeft | Qt::AlignVCenter,
- iconRect.size(), editRect);
- drawItemPixmap(p, iconRect, Qt::AlignCenter, pixmap);
-
- if (cb->direction == Qt::RightToLeft)
- editRect.translate(-spacing - cb->iconSize.width(), 0);
- else
- editRect.translate(cb->iconSize.width() + spacing, 0);
- }
- if (!cb->currentText.isEmpty() && !cb->editable) {
- QPalette styledPalette(cb->palette);
- rule.configurePalette(&styledPalette, QPalette::Text, QPalette::Base);
- drawItemText(p, editRect.adjusted(0, 0, 0, 0), Qt::AlignLeft | Qt::AlignVCenter, styledPalette,
- cb->state & State_Enabled, cb->currentText, QPalette::Text);
- }
- p->restore();
- return;
- }
- break;
-#endif // QT_NO_COMBOBOX
-
- case CE_Header:
- if (hasStyleRule(w, PseudoElement_HeaderViewUpArrow)
- || hasStyleRule(w, PseudoElement_HeaderViewDownArrow)) {
- ParentStyle::drawControl(ce, opt, p, w);
- return;
- }
- if(hasStyleRule(w, PseudoElement_HeaderViewSection)) {
- QRenderRule subRule = renderRule(w, opt, PseudoElement_HeaderViewSection);
- if (!subRule.hasNativeBorder() || !subRule.baseStyleCanDraw()
- || subRule.hasBackground() || subRule.hasPalette()) {
- ParentStyle::drawControl(ce, opt, p, w);
- return;
- }
- }
- break;
- case CE_HeaderSection:
- if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
- QRenderRule subRule = renderRule(w, opt, PseudoElement_HeaderViewSection);
- if (subRule.hasNativeBorder()) {
- QStyleOptionHeader hdr(*header);
- subRule.configurePalette(&hdr.palette, QPalette::ButtonText, QPalette::Button);
-
- if (subRule.baseStyleCanDraw()) {
- baseStyle()->drawControl(CE_HeaderSection, &hdr, p, w);
- } else {
- QWindowsStyle::drawControl(CE_HeaderSection, &hdr, p, w);
- }
- } else {
- subRule.drawRule(p, opt->rect);
- }
- return;
- }
- break;
-
- case CE_HeaderLabel:
- if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
- QStyleOptionHeader hdr(*header);
- QRenderRule subRule = renderRule(w, opt, PseudoElement_HeaderViewSection);
- subRule.configurePalette(&hdr.palette, QPalette::ButtonText, QPalette::Button);
- QFont oldFont = p->font();
- if (subRule.hasFont)
- p->setFont(subRule.font.resolve(p->font()));
- baseStyle()->drawControl(ce, &hdr, p, w);
- if (subRule.hasFont)
- p->setFont(oldFont);
- return;
- }
- break;
-
- case CE_HeaderEmptyArea:
- if (rule.hasDrawable()) {
- return;
- }
- break;
-
- case CE_ProgressBar:
- QWindowsStyle::drawControl(ce, opt, p, w);
- return;
-
- case CE_ProgressBarGroove:
- if (!rule.hasNativeBorder()) {
- rule.drawRule(p, rule.boxRect(opt->rect, Margin));
- return;
- }
- break;
-
- case CE_ProgressBarContents: {
- QRenderRule subRule = renderRule(w, opt, PseudoElement_ProgressBarChunk);
- if (subRule.hasDrawable()) {
- if (const QStyleOptionProgressBarV2 *pb = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(opt)) {
- p->save();
- p->setClipRect(pb->rect);
-
- qint64 minimum = qint64(pb->minimum);
- qint64 maximum = qint64(pb->maximum);
- qint64 progress = qint64(pb->progress);
- bool vertical = (pb->orientation == Qt::Vertical);
- bool inverted = pb->invertedAppearance;
-
- QTransform m;
- QRect rect = pb->rect;
- if (vertical) {
- rect = QRect(rect.y(), rect.x(), rect.height(), rect.width());
- m.rotate(90);
- m.translate(0, -(rect.height() + rect.y()*2));
- }
-
- bool reverse = ((!vertical && (pb->direction == Qt::RightToLeft)) || vertical);
- if (inverted)
- reverse = !reverse;
- const bool indeterminate = pb->minimum == pb->maximum;
- qreal fillRatio = indeterminate ? 0.50 : qreal(progress - minimum)/(maximum - minimum);
- int fillWidth = int(rect.width() * fillRatio);
- int chunkWidth = fillWidth;
- if (subRule.hasContentsSize()) {
- QSize sz = subRule.size();
- chunkWidth = (opt->state & QStyle::State_Horizontal) ? sz.width() : sz.height();
- }
-
- QRect r = rect;
- if (pb->minimum == 0 && pb->maximum == 0) {
- Q_D(const QWindowsStyle);
- int chunkCount = fillWidth/chunkWidth;
- int offset = (d->animateStep*8%rect.width());
- int x = reverse ? r.left() + r.width() - offset - chunkWidth : r.x() + offset;
- while (chunkCount > 0) {
- r.setRect(x, rect.y(), chunkWidth, rect.height());
- r = m.mapRect(QRectF(r)).toRect();
- subRule.drawRule(p, r);
- x += reverse ? -chunkWidth : chunkWidth;
- if (reverse ? x < rect.left() : x > rect.right())
- break;
- --chunkCount;
- }
-
- r = rect;
- x = reverse ? r.right() - (r.left() - x - chunkWidth)
- : r.left() + (x - r.right() - chunkWidth);
- while (chunkCount > 0) {
- r.setRect(x, rect.y(), chunkWidth, rect.height());
- r = m.mapRect(QRectF(r)).toRect();
- subRule.drawRule(p, r);
- x += reverse ? -chunkWidth : chunkWidth;
- --chunkCount;
- };
- } else {
- int x = reverse ? r.left() + r.width() - chunkWidth : r.x();
-
- for (int i = 0; i < ceil(qreal(fillWidth)/chunkWidth); ++i) {
- r.setRect(x, rect.y(), chunkWidth, rect.height());
- r = m.mapRect(QRectF(r)).toRect();
- subRule.drawRule(p, r);
- x += reverse ? -chunkWidth : chunkWidth;
- }
- }
-
- p->restore();
- return;
- }
- }
- }
- break;
-
- case CE_ProgressBarLabel:
- if (const QStyleOptionProgressBarV2 *pb = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(opt)) {
- if (rule.hasBox() || rule.hasBorder() || hasStyleRule(w, PseudoElement_ProgressBarChunk)) {
- drawItemText(p, pb->rect, pb->textAlignment | Qt::TextSingleLine, pb->palette,
- pb->state & State_Enabled, pb->text, QPalette::Text);
- } else {
- QStyleOptionProgressBarV2 pbCopy(*pb);
- rule.configurePalette(&pbCopy.palette, QPalette::HighlightedText, QPalette::Highlight);
- baseStyle()->drawControl(ce, &pbCopy, p, w);
- }
- return;
- }
- break;
-
- case CE_SizeGrip:
- if (const QStyleOptionSizeGrip *sgOpt = qstyleoption_cast<const QStyleOptionSizeGrip *>(opt)) {
- if (rule.hasDrawable()) {
- rule.drawFrame(p, opt->rect);
- p->save();
- switch (sgOpt->corner) {
- case Qt::BottomRightCorner: break;
- case Qt::BottomLeftCorner: p->rotate(90); break;
- case Qt::TopLeftCorner: p->rotate(180); break;
- case Qt::TopRightCorner: p->rotate(270); break;
- default: break;
- }
- rule.drawImage(p, opt->rect);
- p->restore();
- } else {
- QStyleOptionSizeGrip sg(*sgOpt);
- sg.rect = rule.contentsRect(opt->rect);
- baseStyle()->drawControl(CE_SizeGrip, &sg, p, w);
- }
- return;
- }
- break;
-
- case CE_ToolBoxTab:
- QWindowsStyle::drawControl(ce, opt, p, w);
- return;
-
- case CE_ToolBoxTabShape: {
- QRenderRule subRule = renderRule(w, opt, PseudoElement_ToolBoxTab);
- if (subRule.hasDrawable()) {
- subRule.drawRule(p, opt->rect);
- return;
- }
- }
- break;
-
- case CE_ToolBoxTabLabel:
- if (const QStyleOptionToolBox *box = qstyleoption_cast<const QStyleOptionToolBox *>(opt)) {
- QStyleOptionToolBox boxCopy(*box);
- QRenderRule subRule = renderRule(w, opt, PseudoElement_ToolBoxTab);
- subRule.configurePalette(&boxCopy.palette, QPalette::ButtonText, QPalette::Button);
- QFont oldFont = p->font();
- if (subRule.hasFont)
- p->setFont(subRule.font);
- boxCopy.rect = subRule.contentsRect(opt->rect);
- QWindowsStyle::drawControl(ce, &boxCopy, p , w);
- if (subRule.hasFont)
- p->setFont(oldFont);
- return;
- }
- break;
-
- case CE_ScrollBarAddPage:
- pe1 = PseudoElement_ScrollBarAddPage;
- break;
-
- case CE_ScrollBarSubPage:
- pe1 = PseudoElement_ScrollBarSubPage;
- break;
-
- case CE_ScrollBarAddLine:
- pe1 = PseudoElement_ScrollBarAddLine;
- pe2 = (opt->state & QStyle::State_Horizontal) ? PseudoElement_ScrollBarRightArrow : PseudoElement_ScrollBarDownArrow;
- fallback = true;
- break;
-
- case CE_ScrollBarSubLine:
- pe1 = PseudoElement_ScrollBarSubLine;
- pe2 = (opt->state & QStyle::State_Horizontal) ? PseudoElement_ScrollBarLeftArrow : PseudoElement_ScrollBarUpArrow;
- fallback = true;
- break;
-
- case CE_ScrollBarFirst:
- pe1 = PseudoElement_ScrollBarFirst;
- break;
-
- case CE_ScrollBarLast:
- pe1 = PseudoElement_ScrollBarLast;
- break;
-
- case CE_ScrollBarSlider:
- pe1 = PseudoElement_ScrollBarSlider;
- fallback = true;
- break;
-
-#ifndef QT_NO_ITEMVIEWS
- case CE_ItemViewItem:
- if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(opt)) {
- QRenderRule subRule = renderRule(w, opt, PseudoElement_ViewItem);
- if (subRule.hasDrawable() || hasStyleRule(w, PseudoElement_Indicator)) {
- QStyleOptionViewItemV4 optCopy(*vopt);
- subRule.configurePalette(&optCopy.palette, vopt->state & QStyle::State_Selected ? QPalette::HighlightedText : QPalette::Text,
- vopt->state & QStyle::State_Selected ? QPalette::Highlight : QPalette::Base);
- QWindowsStyle::drawControl(ce, &optCopy, p, w);
- } else {
- QStyleOptionViewItemV4 voptCopy(*vopt);
- subRule.configurePalette(&voptCopy.palette, QPalette::Text, QPalette::NoRole);
- baseStyle()->drawControl(ce, &voptCopy, p, w);
- }
- return;
- }
- break;
-#endif // QT_NO_ITEMVIEWS
-
-#ifndef QT_NO_TABBAR
- case CE_TabBarTab:
- if (hasStyleRule(w, PseudoElement_TabBarTab)) {
- QWindowsStyle::drawControl(ce, opt, p, w);
- return;
- }
- break;
-
- case CE_TabBarTabLabel:
- case CE_TabBarTabShape:
- if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
- QStyleOptionTabV3 tabCopy(*tab);
- QRenderRule subRule = renderRule(w, opt, PseudoElement_TabBarTab);
- QRect r = positionRect(w, subRule, PseudoElement_TabBarTab, opt->rect, opt->direction);
- if (ce == CE_TabBarTabShape && subRule.hasDrawable()) {
- subRule.drawRule(p, r);
- return;
- }
- subRule.configurePalette(&tabCopy.palette, QPalette::WindowText, QPalette::Window);
- QFont oldFont = p->font();
- if (subRule.hasFont)
- p->setFont(subRule.font);
- if (subRule.hasBox() || !subRule.hasNativeBorder()) {
- tabCopy.rect = ce == CE_TabBarTabShape ? subRule.borderRect(r)
- : subRule.contentsRect(r);
- QWindowsStyle::drawControl(ce, &tabCopy, p, w);
- } else {
- baseStyle()->drawControl(ce, &tabCopy, p, w);
- }
- if (subRule.hasFont)
- p->setFont(oldFont);
-
- return;
- }
- break;
-#endif // QT_NO_TABBAR
-
- case CE_ColumnViewGrip:
- if (rule.hasDrawable()) {
- rule.drawRule(p, opt->rect);
- return;
- }
- break;
-
- case CE_DockWidgetTitle:
- if (const QStyleOptionDockWidgetV2 *dwOpt = qstyleoption_cast<const QStyleOptionDockWidgetV2 *>(opt)) {
- QRenderRule subRule = renderRule(w, opt, PseudoElement_DockWidgetTitle);
- if (!subRule.hasDrawable() && !subRule.hasPosition())
- break;
- if (subRule.hasDrawable()) {
- subRule.drawRule(p, opt->rect);
- } else {
- QStyleOptionDockWidgetV2 dwCopy(*dwOpt);
- dwCopy.title = QString();
- baseStyle()->drawControl(ce, &dwCopy, p, w);
- }
-
- if (!dwOpt->title.isEmpty()) {
- QRect r = opt->rect;
- if (dwOpt->verticalTitleBar) {
- QSize s = r.size();
- s.transpose();
- r.setSize(s);
-
- p->save();
- p->translate(r.left(), r.top() + r.width());
- p->rotate(-90);
- p->translate(-r.left(), -r.top());
- }
-
- Qt::Alignment alignment = 0;
- if (subRule.hasPosition())
- alignment = subRule.position()->textAlignment;
- if (alignment == 0)
- alignment = Qt::AlignLeft;
- drawItemText(p, subRule.contentsRect(opt->rect),
- alignment | Qt::TextShowMnemonic, dwOpt->palette,
- dwOpt->state & State_Enabled, dwOpt->title,
- QPalette::WindowText);
-
- if (dwOpt->verticalTitleBar)
- p->restore();
- }
-
- return;
- }
- break;
- case CE_ShapedFrame:
- if (const QStyleOptionFrame *frm = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
- if (rule.hasNativeBorder()) {
- QStyleOptionFrameV3 frmOpt(*frm);
- rule.configurePalette(&frmOpt.palette, QPalette::Text, QPalette::Base);
- frmOpt.rect = rule.borderRect(frmOpt.rect);
- baseStyle()->drawControl(ce, &frmOpt, p, w);
- }
- // else, borders are already drawn in PE_Widget
- }
- return;
-
-
- default:
- break;
- }
-
- if (pe1 != PseudoElement_None) {
- QRenderRule subRule = renderRule(w, opt, pe1);
- if (subRule.bg != 0 || subRule.hasDrawable()) {
- //We test subRule.bg directly because hasBackground() would return false for background:none.
- //But we still don't want the default drawning in that case (example for QScrollBar::add-page) (task 198926)
- subRule.drawRule(p, opt->rect);
- } else if (fallback) {
- QWindowsStyle::drawControl(ce, opt, p, w);
- pe2 = PseudoElement_None;
- } else {
- baseStyle()->drawControl(ce, opt, p, w);
- }
- if (pe2 != PseudoElement_None) {
- QRenderRule subSubRule = renderRule(w, opt, pe2);
- QRect r = positionRect(w, subRule, subSubRule, pe2, opt->rect, opt->direction);
- subSubRule.drawRule(p, r);
- }
- return;
- }
-
- baseStyle()->drawControl(ce, opt, p, w);
-}
-
-void QStyleSheetStyle::drawItemPixmap(QPainter *p, const QRect &rect, int alignment, const
- QPixmap &pixmap) const
-{
- baseStyle()->drawItemPixmap(p, rect, alignment, pixmap);
-}
-
-void QStyleSheetStyle::drawItemText(QPainter *painter, const QRect& rect, int alignment, const QPalette &pal,
- bool enabled, const QString& text, QPalette::ColorRole textRole) const
-{
- baseStyle()->drawItemText(painter, rect, alignment, pal, enabled, text, textRole);
-}
-
-void QStyleSheetStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p,
- const QWidget *w) const
-{
- RECURSION_GUARD(baseStyle()->drawPrimitive(pe, opt, p, w); return)
-
- int pseudoElement = PseudoElement_None;
- QRenderRule rule = renderRule(w, opt);
- QRect rect = opt->rect;
-
- switch (pe) {
-
- case PE_FrameStatusBar: {
- QRenderRule subRule = renderRule(w->parentWidget(), opt, PseudoElement_Item);
- if (subRule.hasDrawable()) {
- subRule.drawRule(p, opt->rect);
- return;
- }
- break;
- }
-
- case PE_IndicatorArrowDown:
- pseudoElement = PseudoElement_DownArrow;
- break;
-
- case PE_IndicatorArrowUp:
- pseudoElement = PseudoElement_UpArrow;
- break;
-
- case PE_IndicatorRadioButton:
- pseudoElement = PseudoElement_ExclusiveIndicator;
- break;
-
- case PE_IndicatorViewItemCheck:
- pseudoElement = PseudoElement_ViewItemIndicator;
- break;
-
- case PE_IndicatorCheckBox:
- pseudoElement = PseudoElement_Indicator;
- break;
-
- case PE_IndicatorHeaderArrow:
- if (const QStyleOptionHeader *hdr = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
- pseudoElement = hdr->sortIndicator == QStyleOptionHeader::SortUp
- ? PseudoElement_HeaderViewUpArrow
- : PseudoElement_HeaderViewDownArrow;
- }
- break;
-
- case PE_PanelButtonTool:
- case PE_PanelButtonCommand:
- if (qobject_cast<const QAbstractButton *>(w) && rule.hasBackground() && rule.hasNativeBorder()) {
- //the window style will draw the borders
- ParentStyle::drawPrimitive(pe, opt, p, w);
- if (!rule.background()->pixmap.isNull() || rule.hasImage()) {
- rule.drawRule(p, rule.boxRect(opt->rect, QRenderRule::Margin).adjusted(1,1,-1,-1));
- }
- return;
- }
- if (!rule.hasNativeBorder()) {
- rule.drawRule(p, rule.boxRect(opt->rect, QRenderRule::Margin));
- return;
- }
- break;
-
- case PE_IndicatorButtonDropDown: {
- QRenderRule subRule = renderRule(w, opt, PseudoElement_ToolButtonMenu);
- if (!subRule.hasNativeBorder()) {
- rule.drawBorder(p, opt->rect);
- return;
- }
- break;
- }
-
- case PE_FrameDefaultButton:
- if (rule.hasNativeBorder()) {
- if (rule.baseStyleCanDraw())
- break;
- QWindowsStyle::drawPrimitive(pe, opt, p, w);
- }
- return;
-
- case PE_FrameWindow:
- case PE_FrameDockWidget:
- case PE_Frame:
- if (const QStyleOptionFrame *frm = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
- if (rule.hasNativeBorder()) {
- QStyleOptionFrameV2 frmOpt(*frm);
- rule.configurePalette(&frmOpt.palette, QPalette::Text, QPalette::Base);
- if (!qstyleoption_cast<const QStyleOptionFrameV3 *>(opt)) //if it comes from CE_ShapedFrame, the margins are already sustracted
- frmOpt.rect = rule.borderRect(frmOpt.rect);
- baseStyle()->drawPrimitive(pe, &frmOpt, p, w);
- } else {
- rule.drawBorder(p, rule.borderRect(opt->rect));
- }
- }
- return;
-
- case PE_PanelLineEdit:
- if (const QStyleOptionFrame *frm = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
-#ifndef QT_NO_SPINBOX
- if (w && qobject_cast<const QAbstractSpinBox *>(w->parentWidget())) {
- QRenderRule spinboxRule = renderRule(w->parentWidget(), opt);
- if (!spinboxRule.hasNativeBorder() || !spinboxRule.baseStyleCanDraw())
- return;
- rule = spinboxRule;
- }
-#endif
- if (rule.hasNativeBorder()) {
- QStyleOptionFrame frmOpt(*frm);
- rule.configurePalette(&frmOpt.palette, QPalette::Text, QPalette::Base);
- frmOpt.rect = rule.borderRect(frmOpt.rect);
- if (rule.baseStyleCanDraw()) {
- rule.drawBackgroundImage(p, opt->rect);
- baseStyle()->drawPrimitive(pe, &frmOpt, p, w);
- } else {
- rule.drawBackground(p, opt->rect);
- if (frmOpt.lineWidth > 0)
- baseStyle()->drawPrimitive(PE_FrameLineEdit, &frmOpt, p, w);
- }
- } else {
- rule.drawRule(p, opt->rect);
- }
- }
- return;
-
- case PE_Widget:
- if (w && !rule.hasDrawable()) {
- QWidget *container = containerWidget(w);
- if (styleSheetCaches->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)) {
- const QAbstractScrollAreaPrivate *sap = sa->d_func();
- rule.drawBackground(p, opt->rect, sap->contentsOffset());
- if (rule.hasBorder()) {
- QRect brect = rule.borderRect(opt->rect);
- if (styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents, opt, w)) {
- QRect r = brect.adjusted(0, 0, sa->verticalScrollBar()->isVisible() ? -sa->verticalScrollBar()->width() : 0,
- sa->horizontalScrollBar()->isVisible() ? -sa->horizontalScrollBar()->height() : 0);
- brect = QStyle::visualRect(opt->direction, brect, r);
- }
- rule.drawBorder(p, brect);
- }
- break;
- }
-#endif
- //fall tghought
- case PE_PanelMenu:
- case PE_PanelStatusBar:
- if(rule.hasDrawable()) {
- rule.drawRule(p, opt->rect);
- return;
- }
- break;
-
- case PE_FrameMenu:
- if (rule.hasDrawable()) {
- // Drawn by PE_PanelMenu
- return;
- }
- break;
-
- case PE_PanelMenuBar:
- if (rule.hasDrawable()) {
- // Drawn by PE_Widget
- return;
- }
- break;
-
- case PE_IndicatorToolBarSeparator:
- case PE_IndicatorToolBarHandle: {
- PseudoElement ps = pe == PE_IndicatorToolBarHandle ? PseudoElement_ToolBarHandle : PseudoElement_ToolBarSeparator;
- QRenderRule subRule = renderRule(w, opt, ps);
- if (subRule.hasDrawable()) {
- subRule.drawRule(p, opt->rect);
- return;
- }
- }
- break;
-
- case PE_IndicatorMenuCheckMark:
- pseudoElement = PseudoElement_MenuCheckMark;
- break;
-
- case PE_IndicatorArrowLeft:
- pseudoElement = PseudoElement_LeftArrow;
- break;
-
- case PE_IndicatorArrowRight:
- pseudoElement = PseudoElement_RightArrow;
- break;
-
- case PE_IndicatorColumnViewArrow:
- if (const QStyleOptionViewItem *viewOpt = qstyleoption_cast<const QStyleOptionViewItem *>(opt)) {
- bool reverse = (viewOpt->direction == Qt::RightToLeft);
- pseudoElement = reverse ? PseudoElement_LeftArrow : PseudoElement_RightArrow;
- } else {
- pseudoElement = PseudoElement_RightArrow;
- }
- break;
-
- case PE_IndicatorBranch:
- if (const QStyleOptionViewItemV2 *v2 = qstyleoption_cast<const QStyleOptionViewItemV2 *>(opt)) {
- QRenderRule subRule = renderRule(w, opt, PseudoElement_TreeViewBranch);
- if (subRule.hasDrawable()) {
- if ((v2->state & QStyle::State_Selected) && v2->showDecorationSelected)
- p->fillRect(v2->rect, v2->palette.highlight());
- else if (v2->features & QStyleOptionViewItemV2::Alternate)
- p->fillRect(v2->rect, v2->palette.alternateBase());
- subRule.drawRule(p, opt->rect);
- } else {
- baseStyle()->drawPrimitive(pe, v2, p, w);
- }
- }
- return;
-
- case PE_PanelTipLabel:
- if (!rule.hasDrawable())
- break;
-
- if (const QStyleOptionFrame *frmOpt = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
- if (rule.hasNativeBorder()) {
- rule.drawBackground(p, opt->rect);
- QStyleOptionFrame optCopy(*frmOpt);
- optCopy.rect = rule.borderRect(opt->rect);
- optCopy.palette.setBrush(QPalette::Window, Qt::NoBrush); // oh dear
- baseStyle()->drawPrimitive(pe, &optCopy, p, w);
- } else {
- rule.drawRule(p, opt->rect);
- }
- }
- return;
-
- case PE_FrameGroupBox:
- if (rule.hasNativeBorder())
- break;
- rule.drawBorder(p, opt->rect);
- return;
-
-#ifndef QT_NO_TABWIDGET
- case PE_FrameTabWidget:
- if (const QStyleOptionTabWidgetFrame *frm = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
- QRenderRule subRule = renderRule(w, opt, PseudoElement_TabWidgetPane);
- if (subRule.hasNativeBorder()) {
- subRule.drawBackground(p, opt->rect);
- QStyleOptionTabWidgetFrameV2 frmCopy(*frm);
- subRule.configurePalette(&frmCopy.palette, QPalette::WindowText, QPalette::Window);
- baseStyle()->drawPrimitive(pe, &frmCopy, p, w);
- } else {
- subRule.drawRule(p, opt->rect);
- }
- return;
- }
- break;
-#endif // QT_NO_TABWIDGET
-
- case PE_IndicatorProgressChunk:
- pseudoElement = PseudoElement_ProgressBarChunk;
- break;
-
- case PE_IndicatorTabTear:
- pseudoElement = PseudoElement_TabBarTear;
- break;
-
- case PE_FrameFocusRect:
- if (!rule.hasNativeOutline()) {
- rule.drawOutline(p, opt->rect);
- return;
- }
- break;
-
- case PE_IndicatorDockWidgetResizeHandle:
- pseudoElement = PseudoElement_DockWidgetSeparator;
- break;
-
- case PE_PanelItemViewItem:
- pseudoElement = PseudoElement_ViewItem;
- break;
-
- case PE_PanelScrollAreaCorner:
- pseudoElement = PseudoElement_ScrollAreaCorner;
- break;
-
- case PE_IndicatorSpinDown:
- case PE_IndicatorSpinMinus:
- pseudoElement = PseudoElement_SpinBoxDownArrow;
- break;
-
- case PE_IndicatorSpinUp:
- case PE_IndicatorSpinPlus:
- pseudoElement = PseudoElement_SpinBoxUpArrow;
- break;
-#ifndef QT_NO_TABBAR
- case PE_IndicatorTabClose:
- if (w)
- w = w->parentWidget(); //match on the QTabBar instead of the CloseButton
- pseudoElement = PseudoElement_TabBarTabCloseButton;
-#endif
-
- default:
- break;
- }
-
- if (pseudoElement != PseudoElement_None) {
- QRenderRule subRule = renderRule(w, opt, pseudoElement);
- if (subRule.hasDrawable()) {
- subRule.drawRule(p, rect);
- } else {
- baseStyle()->drawPrimitive(pe, opt, p, w);
- }
- } else {
- baseStyle()->drawPrimitive(pe, opt, p, w);
- }
-}
-
-QPixmap QStyleSheetStyle::generatedIconPixmap(QIcon::Mode iconMode, const QPixmap& pixmap,
- const QStyleOption *option) const
-{
- return baseStyle()->generatedIconPixmap(iconMode, pixmap, option);
-}
-
-QStyle::SubControl QStyleSheetStyle::hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt,
- const QPoint &pt, const QWidget *w) const
-{
- RECURSION_GUARD(return baseStyle()->hitTestComplexControl(cc, opt, pt, w))
- switch (cc) {
- case CC_TitleBar:
- if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) {
- QRenderRule rule = renderRule(w, opt, PseudoElement_TitleBar);
- if (rule.hasDrawable() || rule.hasBox() || rule.hasBorder()) {
- QHash<QStyle::SubControl, QRect> layout = titleBarLayout(w, tb);
- QRect r;
- QStyle::SubControl sc = QStyle::SC_None;
- uint ctrl = SC_TitleBarSysMenu;
- while (ctrl <= SC_TitleBarLabel) {
- r = layout[QStyle::SubControl(ctrl)];
- if (r.isValid() && r.contains(pt)) {
- sc = QStyle::SubControl(ctrl);
- break;
- }
- ctrl <<= 1;
- }
- return sc;
- }
- }
- break;
-
- case CC_MdiControls:
- if (hasStyleRule(w, PseudoElement_MdiCloseButton)
- || hasStyleRule(w, PseudoElement_MdiNormalButton)
- || hasStyleRule(w, PseudoElement_MdiMinButton))
- return QWindowsStyle::hitTestComplexControl(cc, opt, pt, w);
- break;
-
- case CC_ScrollBar: {
- QRenderRule rule = renderRule(w, opt);
- if (!rule.hasDrawable() && !rule.hasBox())
- break;
- }
- // intentionally falls through
- case CC_SpinBox:
- case CC_GroupBox:
- case CC_ComboBox:
- case CC_Slider:
- case CC_ToolButton:
- return QWindowsStyle::hitTestComplexControl(cc, opt, pt, w);
- default:
- break;
- }
-
- return baseStyle()->hitTestComplexControl(cc, opt, pt, w);
-}
-
-QRect QStyleSheetStyle::itemPixmapRect(const QRect &rect, int alignment, const QPixmap &pixmap) const
-{
- return baseStyle()->itemPixmapRect(rect, alignment, pixmap);
-}
-
-QRect QStyleSheetStyle::itemTextRect(const QFontMetrics &metrics, const QRect& rect, int alignment,
- bool enabled, const QString& text) const
-{
- return baseStyle()->itemTextRect(metrics, rect, alignment, enabled, text);
-}
-
-int QStyleSheetStyle::pixelMetric(PixelMetric m, const QStyleOption *opt, const QWidget *w) const
-{
- RECURSION_GUARD(return baseStyle()->pixelMetric(m, opt, w))
-
- QRenderRule rule = renderRule(w, opt);
- QRenderRule subRule;
-
- switch (m) {
- case PM_MenuButtonIndicator:
-#ifndef QT_NO_TOOLBUTTON
- // QToolButton adds this directly to the width
- if (qobject_cast<const QToolButton *>(w) && (rule.hasBox() || !rule.hasNativeBorder()))
- return 0;
-#endif
- subRule = renderRule(w, opt, PseudoElement_PushButtonMenuIndicator);
- if (subRule.hasContentsSize())
- return subRule.size().width();
- break;
-
- case PM_ButtonShiftHorizontal:
- case PM_ButtonShiftVertical:
- case PM_ButtonMargin:
- case PM_ButtonDefaultIndicator:
- if (rule.hasBox())
- return 0;
- break;
-
- case PM_DefaultFrameWidth:
- if (!rule.hasNativeBorder())
- return rule.border()->borders[LeftEdge];
- break;
-
- case PM_ExclusiveIndicatorWidth:
- case PM_IndicatorWidth:
- case PM_ExclusiveIndicatorHeight:
- case PM_IndicatorHeight:
- subRule = renderRule(w, opt, PseudoElement_Indicator);
- if (subRule.hasContentsSize()) {
- return (m == PM_ExclusiveIndicatorWidth) || (m == PM_IndicatorWidth)
- ? subRule.size().width() : subRule.size().height();
- }
- break;
-
- case PM_DockWidgetFrameWidth:
- case PM_ToolTipLabelFrameWidth: // border + margin + padding (support only one width)
- if (!rule.hasDrawable())
- break;
-
- return (rule.border() ? rule.border()->borders[LeftEdge] : 0)
- + (rule.hasBox() ? rule.box()->margins[LeftEdge] + rule.box()->paddings[LeftEdge]: 0);
-
- case PM_ToolBarFrameWidth:
- if (rule.hasBorder() || rule.hasBox())
- return (rule.border() ? rule.border()->borders[LeftEdge] : 0)
- + (rule.hasBox() ? rule.box()->paddings[LeftEdge]: 0);
- break;
-
- case PM_MenuPanelWidth:
- case PM_MenuBarPanelWidth:
- if (rule.hasBorder() || rule.hasBox())
- return (rule.border() ? rule.border()->borders[LeftEdge] : 0)
- + (rule.hasBox() ? rule.box()->margins[LeftEdge]: 0);
- break;
-
-
- case PM_MenuHMargin:
- case PM_MenuBarHMargin:
- if (rule.hasBox())
- return rule.box()->paddings[LeftEdge];
- break;
-
- case PM_MenuVMargin:
- case PM_MenuBarVMargin:
- if (rule.hasBox())
- return rule.box()->paddings[TopEdge];
- break;
-
- case PM_DockWidgetTitleBarButtonMargin:
- case PM_ToolBarItemMargin:
- if (rule.hasBox())
- return rule.box()->margins[TopEdge];
- break;
-
- case PM_ToolBarItemSpacing:
- case PM_MenuBarItemSpacing:
- if (rule.hasBox() && rule.box()->spacing != -1)
- return rule.box()->spacing;
- break;
-
- case PM_MenuTearoffHeight:
- case PM_MenuScrollerHeight: {
- PseudoElement ps = m == PM_MenuTearoffHeight ? PseudoElement_MenuTearoff : PseudoElement_MenuScroller;
- subRule = renderRule(w, opt, ps);
- if (subRule.hasContentsSize())
- return subRule.size().height();
- break;
- }
-
- case PM_ToolBarExtensionExtent:
- break;
-
- case PM_SplitterWidth:
- case PM_ToolBarSeparatorExtent:
- case PM_ToolBarHandleExtent: {
- PseudoElement ps;
- if (m == PM_ToolBarHandleExtent) ps = PseudoElement_ToolBarHandle;
- else if (m == PM_SplitterWidth) ps = PseudoElement_SplitterHandle;
- else ps = PseudoElement_ToolBarSeparator;
- subRule = renderRule(w, opt, ps);
- if (subRule.hasContentsSize()) {
- QSize sz = subRule.size();
- return (opt && opt->state & QStyle::State_Horizontal) ? sz.width() : sz.height();
- }
- break;
- }
-
- case PM_RadioButtonLabelSpacing:
- if (rule.hasBox() && rule.box()->spacing != -1)
- return rule.box()->spacing;
- break;
- case PM_CheckBoxLabelSpacing:
- if (qobject_cast<const QCheckBox *>(w)) {
- if (rule.hasBox() && rule.box()->spacing != -1)
- return rule.box()->spacing;
- }
- // assume group box
- subRule = renderRule(w, opt, PseudoElement_GroupBoxTitle);
- if (subRule.hasBox() && subRule.box()->spacing != -1)
- return subRule.box()->spacing;
- break;
-
-#ifndef QT_NO_SCROLLBAR
- case PM_ScrollBarExtent:
- if (rule.hasContentsSize()) {
- QSize sz = rule.size();
- if (const QStyleOptionSlider *sb = qstyleoption_cast<const QStyleOptionSlider *>(opt))
- return sb->orientation == Qt::Horizontal ? sz.height() : sz.width();
- return sz.width() == -1 ? sz.height() : sz.width();
- }
- break;
-
- case PM_ScrollBarSliderMin:
- if (hasStyleRule(w, PseudoElement_ScrollBarSlider)) {
- subRule = renderRule(w, opt, PseudoElement_ScrollBarSlider);
- QSize msz = subRule.minimumSize();
- if (const QStyleOptionSlider *sb = qstyleoption_cast<const QStyleOptionSlider *>(opt))
- return sb->orientation == Qt::Horizontal ? msz.width() : msz.height();
- return msz.width() == -1 ? msz.height() : msz.width();
- }
- break;
-
- case PM_ScrollView_ScrollBarSpacing:
- if(!rule.hasNativeBorder() || rule.hasBox())
- return 0;
- break;
-#endif // QT_NO_SCROLLBAR
-
- case PM_ProgressBarChunkWidth:
- subRule = renderRule(w, opt, PseudoElement_ProgressBarChunk);
- if (subRule.hasContentsSize()) {
- QSize sz = subRule.size();
- return (opt->state & QStyle::State_Horizontal)
- ? sz.width() : sz.height();
- }
- break;
-
-#ifndef QT_NO_TABWIDGET
- case PM_TabBarTabHSpace:
- case PM_TabBarTabVSpace:
- subRule = renderRule(w, opt, PseudoElement_TabBarTab);
- if (subRule.hasBox() || subRule.hasBorder())
- return 0;
- break;
-
- case PM_TabBarScrollButtonWidth: {
- subRule = renderRule(w, opt, PseudoElement_TabBarScroller);
- if (subRule.hasContentsSize()) {
- QSize sz = subRule.size();
- return sz.width() != -1 ? sz.width() : sz.height();
- }
- }
- break;
-
- case PM_TabBarTabShiftHorizontal:
- case PM_TabBarTabShiftVertical:
- subRule = renderRule(w, opt, PseudoElement_TabBarTab);
- if (subRule.hasBox())
- return 0;
- break;
-
- case PM_TabBarBaseOverlap: {
- const QWidget *tabWidget = qobject_cast<const QTabWidget *>(w) ? w : w->parentWidget();
- if (hasStyleRule(tabWidget, PseudoElement_TabWidgetPane)) {
- return 0;
- }
- break;
- }
-#endif // QT_NO_TABWIDGET
-
- case PM_SliderThickness: // horizontal slider's height (sizeHint)
- case PM_SliderLength: // minimum length of slider
- if (rule.hasContentsSize()) {
- bool horizontal = opt->state & QStyle::State_Horizontal;
- if (m == PM_SliderThickness) {
- QSize sz = rule.size();
- return horizontal ? sz.height() : sz.width();
- } else {
- QSize msz = rule.minimumContentsSize();
- return horizontal ? msz.width() : msz.height();
- }
- }
- break;
-
- case PM_SliderControlThickness: {
- QRenderRule subRule = renderRule(w, opt, PseudoElement_SliderHandle);
- if (!subRule.hasContentsSize())
- break;
- QSize size = subRule.size();
- return (opt->state & QStyle::State_Horizontal) ? size.height() : size.width();
- }
-
- case PM_ToolBarIconSize:
- case PM_ListViewIconSize:
- case PM_IconViewIconSize:
- case PM_TabBarIconSize:
- case PM_MessageBoxIconSize:
- case PM_ButtonIconSize:
- case PM_SmallIconSize:
- if (rule.hasStyleHint(QLatin1String("icon-size"))) {
- return rule.styleHint(QLatin1String("icon-size")).toSize().width();
- }
- break;
-
- case PM_DockWidgetTitleMargin: {
- QRenderRule subRule = renderRule(w, opt, PseudoElement_DockWidgetTitle);
- if (!subRule.hasBox())
- break;
- return (subRule.border() ? subRule.border()->borders[TopEdge] : 0)
- + (subRule.hasBox() ? subRule.box()->margins[TopEdge] + subRule.box()->paddings[TopEdge]: 0);
- }
-
- case PM_DockWidgetSeparatorExtent: {
- QRenderRule subRule = renderRule(w, opt, PseudoElement_DockWidgetSeparator);
- if (!subRule.hasContentsSize())
- break;
- QSize sz = subRule.size();
- return qMax(sz.width(), sz.height());
- }
-
- case PM_TitleBarHeight: {
- QRenderRule subRule = renderRule(w, opt, PseudoElement_TitleBar);
- if (subRule.hasContentsSize())
- return subRule.size().height();
- else if (subRule.hasBox() || subRule.hasBorder()) {
- QFontMetrics fm = opt ? opt->fontMetrics : w->fontMetrics();
- return subRule.size(QSize(0, fm.height())).height();
- }
- break;
- }
-
- case PM_MdiSubWindowFrameWidth:
- if (rule.hasBox() || rule.hasBorder()) {
- return (rule.border() ? rule.border()->borders[LeftEdge] : 0)
- + (rule.hasBox() ? rule.box()->paddings[LeftEdge]+rule.box()->margins[LeftEdge]: 0);
- }
- break;
-
- case PM_MdiSubWindowMinimizedWidth: {
- QRenderRule subRule = renderRule(w, PseudoElement_None, PseudoClass_Minimized);
- int width = subRule.size().width();
- if (width != -1)
- return width;
- break;
- }
- default:
- break;
- }
-
- return baseStyle()->pixelMetric(m, opt, w);
-}
-
-QSize QStyleSheetStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt,
- const QSize &csz, const QWidget *w) const
-{
- RECURSION_GUARD(return baseStyle()->sizeFromContents(ct, opt, csz, w))
-
- QRenderRule rule = renderRule(w, opt);
- QSize sz = rule.adjustSize(csz);
-
- switch (ct) {
- case CT_SpinBox: // ### hopelessly broken QAbstractSpinBox (part 1)
- if (rule.hasBox() || !rule.hasNativeBorder())
- return csz;
- return rule.baseStyleCanDraw() ? baseStyle()->sizeFromContents(ct, opt, sz, w)
- : QWindowsStyle::sizeFromContents(ct, opt, sz, w);
- case CT_ToolButton:
- if (rule.hasBox() || !rule.hasNativeBorder() || !rule.baseStyleCanDraw())
- sz += QSize(3, 3); // ### broken QToolButton
- //fall thought
- case CT_ComboBox:
- case CT_PushButton:
- if (rule.hasBox() || !rule.hasNativeBorder()) {
- if(ct == CT_ComboBox) {
- //add some space for the drop down.
- QRenderRule subRule = renderRule(w, opt, PseudoElement_ComboBoxDropDown);
- QRect comboRect = positionRect(w, rule, subRule, PseudoElement_ComboBoxDropDown, opt->rect, opt->direction);
- //+2 because there is hardcoded margins in QCommonStyle::drawControl(CE_ComboBoxLabel)
- sz += QSize(comboRect.width() + 2, 0);
- }
- return rule.boxSize(sz);
- }
- sz = rule.baseStyleCanDraw() ? baseStyle()->sizeFromContents(ct, opt, sz, w)
- : QWindowsStyle::sizeFromContents(ct, opt, sz, w);
- return rule.boxSize(sz, Margin);
-
- case CT_HeaderSection: {
- if (const QStyleOptionHeader *hdr = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
- QRenderRule subRule = renderRule(w, opt, PseudoElement_HeaderViewSection);
- if (subRule.hasGeometry() || subRule.hasBox() || !subRule.hasNativeBorder()) {
- sz = subRule.adjustSize(csz);
- if (!subRule.hasGeometry()) {
- QSize nativeContentsSize;
- bool nullIcon = hdr->icon.isNull();
- int iconSize = nullIcon ? 0 : pixelMetric(QStyle::PM_SmallIconSize, hdr, w);
- QSize txt = hdr->fontMetrics.size(0, hdr->text);
- nativeContentsSize.setHeight(qMax(iconSize, txt.height()));
- nativeContentsSize.setWidth(iconSize + txt.width());
- sz = sz.expandedTo(nativeContentsSize);
- }
- return subRule.size(sz);
- }
- return subRule.baseStyleCanDraw() ? baseStyle()->sizeFromContents(ct, opt, sz, w)
- : QWindowsStyle::sizeFromContents(ct, opt, sz, w);
- }
- }
- break;
- case CT_GroupBox:
- case CT_LineEdit:
-#ifndef QT_NO_SPINBOX
- // ### hopelessly broken QAbstractSpinBox (part 2)
- if (QAbstractSpinBox *spinBox = qobject_cast<QAbstractSpinBox *>(w ? w->parentWidget() : 0)) {
- QRenderRule rule = renderRule(spinBox, opt);
- if (rule.hasBox() || !rule.hasNativeBorder())
- return csz;
- return rule.baseStyleCanDraw() ? baseStyle()->sizeFromContents(ct, opt, sz, w)
- : QWindowsStyle::sizeFromContents(ct, opt, sz, w);
- }
-#endif
- if (rule.hasBox() || !rule.hasNativeBorder()) {
- return rule.boxSize(sz);
- }
- break;
-
- case CT_CheckBox:
- case CT_RadioButton:
- if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
- if (rule.hasBox() || rule.hasBorder() || hasStyleRule(w, PseudoElement_Indicator)) {
- bool isRadio = (ct == CT_RadioButton);
- int iw = pixelMetric(isRadio ? PM_ExclusiveIndicatorWidth
- : PM_IndicatorWidth, btn, w);
- int ih = pixelMetric(isRadio ? PM_ExclusiveIndicatorHeight
- : PM_IndicatorHeight, btn, w);
-
- int spacing = pixelMetric(isRadio ? PM_RadioButtonLabelSpacing
- : PM_CheckBoxLabelSpacing, btn, w);
- sz.setWidth(sz.width() + iw + spacing);
- sz.setHeight(qMax(sz.height(), ih));
- return rule.boxSize(sz);
- }
- }
- break;
-
- case CT_Menu:
- case CT_MenuBar: // already has everything!
- case CT_ScrollBar:
- if (rule.hasBox() || rule.hasBorder())
- return sz;
- break;
-
- case CT_MenuItem:
- if (const QStyleOptionMenuItem *mi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
- PseudoElement pe = (mi->menuItemType == QStyleOptionMenuItem::Separator)
- ? PseudoElement_MenuSeparator : PseudoElement_Item;
- QRenderRule subRule = renderRule(w, opt, pe);
- if ((pe == PseudoElement_MenuSeparator) && subRule.hasContentsSize()) {
- return QSize(sz.width(), subRule.size().height());
- } else if ((pe == PseudoElement_Item) && (subRule.hasBox() || subRule.hasBorder())) {
- int width = csz.width();
- if (mi->text.contains(QLatin1Char('\t')))
- width += 12; //as in QCommonStyle
- return subRule.boxSize(subRule.adjustSize(QSize(width, csz.height())));
- }
- }
- break;
-
- case CT_Splitter:
- case CT_MenuBarItem: {
- PseudoElement pe = (ct == CT_Splitter) ? PseudoElement_SplitterHandle : PseudoElement_Item;
- QRenderRule subRule = renderRule(w, opt, pe);
- if (subRule.hasBox() || subRule.hasBorder())
- return subRule.boxSize(sz);
- break;
- }
-
- case CT_ProgressBar:
- case CT_SizeGrip:
- return (rule.hasContentsSize())
- ? rule.size(sz)
- : rule.boxSize(baseStyle()->sizeFromContents(ct, opt, sz, w));
- break;
-
- case CT_Slider:
- if (rule.hasBorder() || rule.hasBox() || rule.hasGeometry())
- return rule.boxSize(sz);
- break;
-
-#ifndef QT_NO_TABBAR
- case CT_TabBarTab: {
- QRenderRule subRule = renderRule(w, opt, PseudoElement_TabBarTab);
- if (subRule.hasBox() || !subRule.hasNativeBorder()) {
- int spaceForIcon = 0;
- bool vertical = false;
- if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
- if (!tab->icon.isNull())
- spaceForIcon = 6 /* icon offset */ + 4 /* spacing */ + 2 /* magic */; // ###: hardcoded to match with common style
- vertical = verticalTabs(tab->shape);
- }
- sz = csz + QSize(vertical ? 0 : spaceForIcon, vertical ? spaceForIcon : 0);
- return subRule.boxSize(subRule.adjustSize(sz));
- }
-#ifdef Q_WS_MAC
- if (baseStyle()->inherits("QMacStyle")) {
- //adjust the size after the call to the style because the mac style ignore the size arguments anyway.
- //this might cause the (max-){width,height} property to include the native style border while they should not.
- return subRule.adjustSize(baseStyle()->sizeFromContents(ct, opt, csz, w));
- }
-#endif
- sz = subRule.adjustSize(csz);
- break;
- }
-#endif // QT_NO_TABBAR
-
- case CT_MdiControls:
- if (const QStyleOptionComplex *ccOpt = qstyleoption_cast<const QStyleOptionComplex *>(opt)) {
- if (!hasStyleRule(w, PseudoElement_MdiCloseButton)
- && !hasStyleRule(w, PseudoElement_MdiNormalButton)
- && !hasStyleRule(w, PseudoElement_MdiMinButton))
- break;
-
- QList<QVariant> layout = rule.styleHint(QLatin1String("button-layout")).toList();
- if (layout.isEmpty())
- layout = subControlLayout(QLatin1String("mNX"));
-
- int width = 0, height = 0;
- for (int i = 0; i < layout.count(); i++) {
- int layoutButton = layout[i].toInt();
- if (layoutButton < PseudoElement_MdiCloseButton
- || layoutButton > PseudoElement_MdiNormalButton)
- continue;
- QStyle::SubControl sc = knownPseudoElements[layoutButton].subControl;
- if (!(ccOpt->subControls & sc))
- continue;
- QRenderRule subRule = renderRule(w, opt, layoutButton);
- QSize sz = subRule.size();
- width += sz.width();
- height = qMax(height, sz.height());
- }
-
- return QSize(width, height);
- }
- break;
-
-#ifndef QT_NO_ITEMVIEWS
- case CT_ItemViewItem: {
- QRenderRule subRule = renderRule(w, opt, PseudoElement_ViewItem);
- sz = baseStyle()->sizeFromContents(ct, opt, csz, w);
- sz = subRule.adjustSize(sz);
- if (subRule.hasBox() || subRule.hasBorder())
- sz = subRule.boxSize(sz);
- return sz;
- }
-#endif // QT_NO_ITEMVIEWS
-
- default:
- break;
- }
-
- return baseStyle()->sizeFromContents(ct, opt, sz, w);
-}
-
-/*!
- \internal
-*/
-static QLatin1String propertyNameForStandardPixmap(QStyle::StandardPixmap sp)
-{
- switch (sp) {
- case QStyle::SP_TitleBarMenuButton: return QLatin1String("titlebar-menu-icon");
- case QStyle::SP_TitleBarMinButton: return QLatin1String("titlebar-minimize-icon");
- case QStyle::SP_TitleBarMaxButton: return QLatin1String("titlebar-maximize-icon");
- case QStyle::SP_TitleBarCloseButton: return QLatin1String("titlebar-close-icon");
- case QStyle::SP_TitleBarNormalButton: return QLatin1String("titlebar-normal-icon");
- case QStyle::SP_TitleBarShadeButton: return QLatin1String("titlebar-shade-icon");
- case QStyle::SP_TitleBarUnshadeButton: return QLatin1String("titlebar-unshade-icon");
- case QStyle::SP_TitleBarContextHelpButton: return QLatin1String("titlebar-contexthelp-icon");
- case QStyle::SP_DockWidgetCloseButton: return QLatin1String("dockwidget-close-icon");
- case QStyle::SP_MessageBoxInformation: return QLatin1String("messagebox-information-icon");
- case QStyle::SP_MessageBoxWarning: return QLatin1String("messagebox-warning-icon");
- case QStyle::SP_MessageBoxCritical: return QLatin1String("messagebox-critical-icon");
- case QStyle::SP_MessageBoxQuestion: return QLatin1String("messagebox-question-icon");
- case QStyle::SP_DesktopIcon: return QLatin1String("desktop-icon");
- case QStyle::SP_TrashIcon: return QLatin1String("trash-icon");
- case QStyle::SP_ComputerIcon: return QLatin1String("computer-icon");
- case QStyle::SP_DriveFDIcon: return QLatin1String("floppy-icon");
- case QStyle::SP_DriveHDIcon: return QLatin1String("harddisk-icon");
- case QStyle::SP_DriveCDIcon: return QLatin1String("cd-icon");
- case QStyle::SP_DriveDVDIcon: return QLatin1String("dvd-icon");
- case QStyle::SP_DriveNetIcon: return QLatin1String("network-icon");
- case QStyle::SP_DirOpenIcon: return QLatin1String("directory-open-icon");
- case QStyle::SP_DirClosedIcon: return QLatin1String("directory-closed-icon");
- case QStyle::SP_DirLinkIcon: return QLatin1String("directory-link-icon");
- case QStyle::SP_FileIcon: return QLatin1String("file-icon");
- case QStyle::SP_FileLinkIcon: return QLatin1String("file-link-icon");
- case QStyle::SP_FileDialogStart: return QLatin1String("filedialog-start-icon");
- case QStyle::SP_FileDialogEnd: return QLatin1String("filedialog-end-icon");
- case QStyle::SP_FileDialogToParent: return QLatin1String("filedialog-parent-directory-icon");
- case QStyle::SP_FileDialogNewFolder: return QLatin1String("filedialog-new-directory-icon");
- case QStyle::SP_FileDialogDetailedView: return QLatin1String("filedialog-detailedview-icon");
- case QStyle::SP_FileDialogInfoView: return QLatin1String("filedialog-infoview-icon");
- case QStyle::SP_FileDialogContentsView: return QLatin1String("filedialog-contentsview-icon");
- case QStyle::SP_FileDialogListView: return QLatin1String("filedialog-listview-icon");
- case QStyle::SP_FileDialogBack: return QLatin1String("filedialog-backward-icon");
- case QStyle::SP_DirIcon: return QLatin1String("directory-icon");
- case QStyle::SP_DialogOkButton: return QLatin1String("dialog-ok-icon");
- case QStyle::SP_DialogCancelButton: return QLatin1String("dialog-cancel-icon");
- case QStyle::SP_DialogHelpButton: return QLatin1String("dialog-help-icon");
- case QStyle::SP_DialogOpenButton: return QLatin1String("dialog-open-icon");
- case QStyle::SP_DialogSaveButton: return QLatin1String("dialog-save-icon");
- case QStyle::SP_DialogCloseButton: return QLatin1String("dialog-close-icon");
- case QStyle::SP_DialogApplyButton: return QLatin1String("dialog-apply-icon");
- case QStyle::SP_DialogResetButton: return QLatin1String("dialog-reset-icon");
- case QStyle::SP_DialogDiscardButton: return QLatin1String("discard-icon");
- case QStyle::SP_DialogYesButton: return QLatin1String("dialog-yes-icon");
- case QStyle::SP_DialogNoButton: return QLatin1String("dialog-no-icon");
- case QStyle::SP_ArrowUp: return QLatin1String("uparrow-icon");
- case QStyle::SP_ArrowDown: return QLatin1String("downarrow-icon");
- case QStyle::SP_ArrowLeft: return QLatin1String("leftarrow-icon");
- case QStyle::SP_ArrowRight: return QLatin1String("rightarrow-icon");
- case QStyle::SP_ArrowBack: return QLatin1String("backward-icon");
- case QStyle::SP_ArrowForward: return QLatin1String("forward-icon");
- case QStyle::SP_DirHomeIcon: return QLatin1String("home-icon");
- default: return QLatin1String("");
- }
-}
-
-QIcon QStyleSheetStyle::standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *opt,
- const QWidget *w) const
-{
- RECURSION_GUARD(return baseStyle()->standardIcon(standardIcon, opt, w))
- QString s = propertyNameForStandardPixmap(standardIcon);
- if (!s.isEmpty()) {
- QRenderRule rule = renderRule(w, opt);
- if (rule.hasStyleHint(s))
- return qvariant_cast<QIcon>(rule.styleHint(s));
- }
- return baseStyle()->standardIcon(standardIcon, opt, w);
-}
-
-QPalette QStyleSheetStyle::standardPalette() const
-{
- return baseStyle()->standardPalette();
-}
-
-QPixmap QStyleSheetStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt,
- const QWidget *w) const
-{
- RECURSION_GUARD(return baseStyle()->standardPixmap(standardPixmap, opt, w))
- QString s = propertyNameForStandardPixmap(standardPixmap);
- if (!s.isEmpty()) {
- QRenderRule rule = renderRule(w, opt);
- if (rule.hasStyleHint(s)) {
- QIcon icon = qvariant_cast<QIcon>(rule.styleHint(s));
- return icon.pixmap(16, 16); // ###: unhard-code this if someone complains
- }
- }
- return baseStyle()->standardPixmap(standardPixmap, opt, w);
-}
-
-int QStyleSheetStyle::layoutSpacing(QSizePolicy::ControlType control1, QSizePolicy::ControlType control2,
- Qt::Orientation orientation, const QStyleOption *option,
- const QWidget *widget) const
-{
- return baseStyle()->layoutSpacing(control1, control2, orientation, option, widget);
-}
-
-int QStyleSheetStyle::layoutSpacingImplementation(QSizePolicy::ControlType control1 ,
- QSizePolicy::ControlType control2,
- Qt::Orientation orientation,
- const QStyleOption * option ,
- const QWidget * widget) const
-{
- return baseStyle()->layoutSpacing(control1, control2, orientation, option, widget);
-}
-
-int QStyleSheetStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *w,
- QStyleHintReturn *shret) const
-{
- RECURSION_GUARD(return baseStyle()->styleHint(sh, opt, w, shret))
- // Prevent endless loop if somebody use isActiveWindow property as selector.
- // QWidget::isActiveWindow uses this styleHint to determine if the window is active or not
- if (sh == SH_Widget_ShareActivation)
- return baseStyle()->styleHint(sh, opt, w, shret);
-
- QRenderRule rule = renderRule(w, opt);
- QString s;
- switch (sh) {
- case SH_LineEdit_PasswordCharacter: s = QLatin1String("lineedit-password-character"); break;
- case SH_DitherDisabledText: s = QLatin1String("dither-disabled-text"); break;
- case SH_EtchDisabledText: s = QLatin1String("etch-disabled-text"); break;
- case SH_ItemView_ActivateItemOnSingleClick: s = QLatin1String("activate-on-singleclick"); break;
- case SH_ItemView_ShowDecorationSelected: s = QLatin1String("show-decoration-selected"); break;
- case SH_Table_GridLineColor: s = QLatin1String("gridline-color"); break;
- case SH_DialogButtonLayout: s = QLatin1String("button-layout"); break;
- case SH_ToolTipLabel_Opacity: s = QLatin1String("opacity"); break;
- case SH_ComboBox_Popup: s = QLatin1String("combobox-popup"); break;
- case SH_ComboBox_ListMouseTracking: s = QLatin1String("combobox-list-mousetracking"); break;
- case SH_MenuBar_AltKeyNavigation: s = QLatin1String("menubar-altkey-navigation"); break;
- case SH_Menu_Scrollable: s = QLatin1String("menu-scrollable"); break;
- case SH_DrawMenuBarSeparator: s = QLatin1String("menubar-separator"); break;
- case SH_MenuBar_MouseTracking: s = QLatin1String("mouse-tracking"); break;
- case SH_SpinBox_ClickAutoRepeatRate: s = QLatin1String("spinbox-click-autorepeat-rate"); break;
- case SH_SpinControls_DisableOnBounds: s = QLatin1String("spincontrol-disable-on-bounds"); break;
- case SH_MessageBox_TextInteractionFlags: s = QLatin1String("messagebox-text-interaction-flags"); break;
- case SH_ToolButton_PopupDelay: s = QLatin1String("toolbutton-popup-delay"); break;
- case SH_ToolBox_SelectedPageTitleBold:
- if (renderRule(w, opt, PseudoElement_ToolBoxTab).hasFont)
- return 0;
- break;
- case SH_GroupBox_TextLabelColor:
- if (rule.hasPalette() && rule.palette()->foreground.style() != Qt::NoBrush)
- return rule.palette()->foreground.color().rgba();
- break;
- case SH_ScrollView_FrameOnlyAroundContents: s = QLatin1String("scrollview-frame-around-contents"); break;
- case SH_ScrollBar_ContextMenu: s = QLatin1String("scrollbar-contextmenu"); break;
- case SH_ScrollBar_LeftClickAbsolutePosition: s = QLatin1String("scrollbar-leftclick-absolute-position"); break;
- case SH_ScrollBar_MiddleClickAbsolutePosition: s = QLatin1String("scrollbar-middleclick-absolute-position"); break;
- case SH_ScrollBar_RollBetweenButtons: s = QLatin1String("scrollbar-roll-between-buttons"); break;
- case SH_ScrollBar_ScrollWhenPointerLeavesControl: s = QLatin1String("scrollbar-scroll-when-pointer-leaves-control"); break;
- case SH_TabBar_Alignment:
-#ifndef QT_NO_TABWIDGET
- if (qobject_cast<const QTabWidget *>(w)) {
- rule = renderRule(w, opt, PseudoElement_TabWidgetTabBar);
- if (rule.hasPosition())
- return rule.position()->position;
- }
-#endif // QT_NO_TABWIDGET
- s = QLatin1String("alignment");
- break;
-#ifndef QT_NO_TABBAR
- case SH_TabBar_CloseButtonPosition:
- rule = renderRule(w, opt, PseudoElement_TabBarTabCloseButton);
- if (rule.hasPosition()) {
- Qt::Alignment align = rule.position()->position;
- if (align & Qt::AlignLeft || align & Qt::AlignTop)
- return QTabBar::LeftSide;
- if (align & Qt::AlignRight || align & Qt::AlignBottom)
- return QTabBar::RightSide;
- }
- break;
-#endif
- case SH_TabBar_ElideMode: s = QLatin1String("tabbar-elide-mode"); break;
- case SH_TabBar_PreferNoArrows: s = QLatin1String("tabbar-prefer-no-arrows"); break;
- case SH_ComboBox_PopupFrameStyle:
-#ifndef QT_NO_COMBOBOX
- if (qobject_cast<const QComboBox *>(w)) {
- QAbstractItemView *view = w->findChild<QAbstractItemView *>();
- if (view) {
- view->ensurePolished();
- QRenderRule subRule = renderRule(view, PseudoElement_None);
- if (subRule.hasBox() || !subRule.hasNativeBorder())
- return QFrame::NoFrame;
- }
- }
-#endif // QT_NO_COMBOBOX
- break;
- case SH_DialogButtonBox_ButtonsHaveIcons: s = QLatin1String("dialogbuttonbox-buttons-have-icons"); break;
- case SH_Workspace_FillSpaceOnMaximize: s = QLatin1String("mdi-fill-space-on-maximize"); break;
- case SH_TitleBar_NoBorder:
- if (rule.hasBorder())
- return !rule.border()->borders[LeftEdge];
- break;
- case SH_TitleBar_AutoRaise: { // plain absurd
- QRenderRule subRule = renderRule(w, opt, PseudoElement_TitleBar);
- if (subRule.hasDrawable())
- return 1;
- break;
- }
- case SH_ItemView_ArrowKeysNavigateIntoChildren: s = QLatin1String("arrow-keys-navigate-into-children"); break;
- case SH_ItemView_PaintAlternatingRowColorsForEmptyArea: s = QLatin1String("paint-alternating-row-colors-for-empty-area"); break;
- default: break;
- }
- if (!s.isEmpty() && rule.hasStyleHint(s)) {
- return rule.styleHint(s).toInt();
- }
-
- return baseStyle()->styleHint(sh, opt, w, shret);
-}
-
-QRect QStyleSheetStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc,
- const QWidget *w) const
-{
- RECURSION_GUARD(return baseStyle()->subControlRect(cc, opt, sc, w))
-
- QRenderRule rule = renderRule(w, opt);
- switch (cc) {
- case CC_ComboBox:
- if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
- if (rule.hasBox() || !rule.hasNativeBorder()) {
- switch (sc) {
- case SC_ComboBoxFrame: return rule.borderRect(opt->rect);
- case SC_ComboBoxEditField:
- {
- QRenderRule subRule = renderRule(w, opt, PseudoElement_ComboBoxDropDown);
- QRect r = rule.contentsRect(opt->rect);
- QRect r2 = positionRect(w, rule, subRule, PseudoElement_ComboBoxDropDown,
- opt->rect, opt->direction);
- if (subRule.hasPosition() && subRule.position()->position & Qt::AlignLeft) {
- return visualRect(opt->direction, r, r.adjusted(r2.width(),0,0,0));
- } else {
- return visualRect(opt->direction, r, r.adjusted(0,0,-r2.width(),0));
- }
- }
- case SC_ComboBoxArrow: {
- QRenderRule subRule = renderRule(w, opt, PseudoElement_ComboBoxDropDown);
- return positionRect(w, rule, subRule, PseudoElement_ComboBoxDropDown, opt->rect, opt->direction);
- }
- case SC_ComboBoxListBoxPopup:
- default:
- return baseStyle()->subControlRect(cc, opt, sc, w);
- }
- }
-
- QStyleOptionComboBox comboBox(*cb);
- comboBox.rect = rule.borderRect(opt->rect);
- return rule.baseStyleCanDraw() ? baseStyle()->subControlRect(cc, &comboBox, sc, w)
- : QWindowsStyle::subControlRect(cc, &comboBox, sc, w);
- }
- break;
-
-#ifndef QT_NO_SPINBOX
- case CC_SpinBox:
- if (const QStyleOptionSpinBox *spin = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
- QRenderRule upRule = renderRule(w, opt, PseudoElement_SpinBoxUpButton);
- QRenderRule downRule = renderRule(w, opt, PseudoElement_SpinBoxDownButton);
- bool ruleMatch = rule.hasBox() || !rule.hasNativeBorder();
- bool upRuleMatch = upRule.hasGeometry() || upRule.hasPosition();
- bool downRuleMatch = downRule.hasGeometry() || upRule.hasPosition();
- if (ruleMatch || upRuleMatch || downRuleMatch) {
- switch (sc) {
- case SC_SpinBoxFrame:
- return rule.borderRect(opt->rect);
- case SC_SpinBoxEditField:
- {
- QRect r = rule.contentsRect(opt->rect);
- // Use the widest button on each side to determine edit field size.
- Qt::Alignment upAlign, downAlign;
-
- upAlign = upRule.hasPosition() ? upRule.position()->position
- : Qt::Alignment(Qt::AlignRight);
- upAlign = resolveAlignment(opt->direction, upAlign);
-
- downAlign = downRule.hasPosition() ? downRule.position()->position
- : Qt::Alignment(Qt::AlignRight);
- downAlign = resolveAlignment(opt->direction, downAlign);
-
- int upSize = subControlRect(CC_SpinBox, opt, SC_SpinBoxUp, w).width();
- int downSize = subControlRect(CC_SpinBox, opt, SC_SpinBoxDown, w).width();
- int widestL = qMax((upAlign & Qt::AlignLeft) ? upSize : 0,
- (downAlign & Qt::AlignLeft) ? downSize : 0);
- int widestR = qMax((upAlign & Qt::AlignRight) ? upSize : 0,
- (downAlign & Qt::AlignRight) ? downSize : 0);
- r.setRight(r.right() - widestR);
- r.setLeft(r.left() + widestL);
- return r;
- }
- case SC_SpinBoxDown:
- if (downRuleMatch)
- return positionRect(w, rule, downRule, PseudoElement_SpinBoxDownButton,
- opt->rect, opt->direction);
- break;
- case SC_SpinBoxUp:
- if (upRuleMatch)
- return positionRect(w, rule, upRule, PseudoElement_SpinBoxUpButton,
- opt->rect, opt->direction);
- break;
- default:
- break;
- }
-
- return baseStyle()->subControlRect(cc, opt, sc, w);
- }
-
- QStyleOptionSpinBox spinBox(*spin);
- spinBox.rect = rule.borderRect(opt->rect);
- return rule.baseStyleCanDraw() ? baseStyle()->subControlRect(cc, &spinBox, sc, w)
- : QWindowsStyle::subControlRect(cc, &spinBox, sc, w);
- }
- break;
-#endif // QT_NO_SPINBOX
-
- case CC_GroupBox:
- if (const QStyleOptionGroupBox *gb = qstyleoption_cast<const QStyleOptionGroupBox *>(opt)) {
- switch (sc) {
- case SC_GroupBoxFrame:
- case SC_GroupBoxContents: {
- if (rule.hasBox() || !rule.hasNativeBorder()) {
- return sc == SC_GroupBoxFrame ? rule.borderRect(opt->rect)
- : rule.contentsRect(opt->rect);
- }
- QStyleOptionGroupBox groupBox(*gb);
- groupBox.rect = rule.borderRect(opt->rect);
- return baseStyle()->subControlRect(cc, &groupBox, sc, w);
- }
- default:
- case SC_GroupBoxLabel:
- case SC_GroupBoxCheckBox: {
- QRenderRule indRule = renderRule(w, opt, PseudoElement_GroupBoxIndicator);
- QRenderRule labelRule = renderRule(w, opt, PseudoElement_GroupBoxTitle);
- if (!labelRule.hasPosition() && !labelRule.hasGeometry() && !labelRule.hasBox()
- && !labelRule.hasBorder() && !indRule.hasContentsSize()) {
- QStyleOptionGroupBox groupBox(*gb);
- groupBox.rect = rule.borderRect(opt->rect);
- return baseStyle()->subControlRect(cc, &groupBox, sc, w);
- }
- int tw = opt->fontMetrics.width(gb->text);
- int th = opt->fontMetrics.height();
- int spacing = pixelMetric(QStyle::PM_CheckBoxLabelSpacing, opt, w);
- int iw = pixelMetric(QStyle::PM_IndicatorWidth, opt, w);
- int ih = pixelMetric(QStyle::PM_IndicatorHeight, opt, w);
-
- if (gb->subControls & QStyle::SC_GroupBoxCheckBox) {
- tw = tw + iw + spacing;
- th = qMax(th, ih);
- }
- if (!labelRule.hasGeometry()) {
- labelRule.geo = new QStyleSheetGeometryData(tw, th, tw, th, -1, -1);
- } else {
- labelRule.geo->width = tw;
- labelRule.geo->height = th;
- }
- if (!labelRule.hasPosition()) {
- labelRule.p = new QStyleSheetPositionData(0, 0, 0, 0, defaultOrigin(PseudoElement_GroupBoxTitle),
- gb->textAlignment, PositionMode_Static);
- }
- QRect r = positionRect(w, rule, labelRule, PseudoElement_GroupBoxTitle,
- opt->rect, opt->direction);
- if (gb->subControls & SC_GroupBoxCheckBox) {
- r = labelRule.contentsRect(r);
- if (sc == SC_GroupBoxLabel) {
- r.setLeft(r.left() + iw + spacing);
- r.setTop(r.center().y() - th/2);
- } else {
- r = QRect(r.left(), r.center().y() - ih/2, iw, ih);
- }
- return r;
- } else {
- return labelRule.contentsRect(r);
- }
- }
- } // switch
- }
- break;
-
- case CC_ToolButton:
- if (const QStyleOptionToolButton *tb = qstyleoption_cast<const QStyleOptionToolButton *>(opt)) {
- if (rule.hasBox() || !rule.hasNativeBorder()) {
- switch (sc) {
- case SC_ToolButton: return rule.borderRect(opt->rect);
- case SC_ToolButtonMenu: {
- QRenderRule subRule = renderRule(w, opt, PseudoElement_ToolButtonMenu);
- return positionRect(w, rule, subRule, PseudoElement_ToolButtonMenu, opt->rect, opt->direction);
- }
- default:
- break;
- }
- }
-
- QStyleOptionToolButton tool(*tb);
- tool.rect = rule.borderRect(opt->rect);
- return rule.baseStyleCanDraw() ? baseStyle()->subControlRect(cc, &tool, sc, w)
- : QWindowsStyle::subControlRect(cc, &tool, sc, w);
- }
- break;
-
-#ifndef QT_NO_SCROLLBAR
- case CC_ScrollBar:
- if (const QStyleOptionSlider *sb = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
- QStyleOptionSlider styleOptionSlider(*sb);
- styleOptionSlider.rect = rule.borderRect(opt->rect);
- if (rule.hasDrawable() || rule.hasBox()) {
- QRect grooveRect;
- if (!rule.hasBox()) {
- grooveRect = rule.baseStyleCanDraw() ? baseStyle()->subControlRect(cc, sb, SC_ScrollBarGroove, w)
- : QWindowsStyle::subControlRect(cc, sb, SC_ScrollBarGroove, w);
- } else {
- grooveRect = rule.contentsRect(opt->rect);
- }
-
- PseudoElement pe = PseudoElement_None;
-
- switch (sc) {
- case SC_ScrollBarGroove:
- return grooveRect;
- case SC_ScrollBarAddPage:
- case SC_ScrollBarSubPage:
- case SC_ScrollBarSlider: {
- QRect contentRect = grooveRect;
- if (hasStyleRule(w, PseudoElement_ScrollBarSlider)) {
- QRenderRule sliderRule = renderRule(w, opt, PseudoElement_ScrollBarSlider);
- Origin origin = sliderRule.hasPosition() ? sliderRule.position()->origin : defaultOrigin(PseudoElement_ScrollBarSlider);
- contentRect = rule.originRect(opt->rect, origin);
- }
- int maxlen = (styleOptionSlider.orientation == Qt::Horizontal) ? contentRect.width() : contentRect.height();
- int sliderlen;
- if (sb->maximum != sb->minimum) {
- uint range = sb->maximum - sb->minimum;
- sliderlen = (qint64(sb->pageStep) * maxlen) / (range + sb->pageStep);
-
- int slidermin = pixelMetric(PM_ScrollBarSliderMin, sb, w);
- if (sliderlen < slidermin || range > INT_MAX / 2)
- sliderlen = slidermin;
- if (sliderlen > maxlen)
- sliderlen = maxlen;
- } else {
- sliderlen = maxlen;
- }
-
- int sliderstart = (styleOptionSlider.orientation == Qt::Horizontal ? contentRect.left() : contentRect.top())
- + sliderPositionFromValue(sb->minimum, sb->maximum, sb->sliderPosition,
- maxlen - sliderlen, sb->upsideDown);
-
- QRect sr = (sb->orientation == Qt::Horizontal)
- ? QRect(sliderstart, contentRect.top(), sliderlen, contentRect.height())
- : QRect(contentRect.left(), sliderstart, contentRect.width(), sliderlen);
- if (sc == SC_ScrollBarSlider) {
- return sr;
- } else if (sc == SC_ScrollBarSubPage) {
- return QRect(contentRect.topLeft(), sb->orientation == Qt::Horizontal ? sr.bottomLeft() : sr.topRight());
- } else { // SC_ScrollBarAddPage
- return QRect(sb->orientation == Qt::Horizontal ? sr.topRight() : sr.bottomLeft(), contentRect.bottomRight());
- }
- break;
- }
- case SC_ScrollBarAddLine: pe = PseudoElement_ScrollBarAddLine; break;
- case SC_ScrollBarSubLine: pe = PseudoElement_ScrollBarSubLine; break;
- case SC_ScrollBarFirst: pe = PseudoElement_ScrollBarFirst; break;
- case SC_ScrollBarLast: pe = PseudoElement_ScrollBarLast; break;
- default: break;
- }
- if (hasStyleRule(w,pe)) {
- QRenderRule subRule = renderRule(w, opt, pe);
- if (subRule.hasPosition() || subRule.hasGeometry() || subRule.hasBox()) {
- const QStyleSheetPositionData *pos = subRule.position();
- QRect originRect = grooveRect;
- if (rule.hasBox()) {
- Origin origin = (pos && pos->origin != Origin_Unknown) ? pos->origin : defaultOrigin(pe);
- originRect = rule.originRect(opt->rect, origin);
- }
- return positionRect(w, subRule, pe, originRect, styleOptionSlider.direction);
- }
- }
- }
- return rule.baseStyleCanDraw() ? baseStyle()->subControlRect(cc, &styleOptionSlider, sc, w)
- : QWindowsStyle::subControlRect(cc, &styleOptionSlider, sc, w);
- }
- break;
-#endif // QT_NO_SCROLLBAR
-
-#ifndef QT_NO_SLIDER
- case CC_Slider:
- if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
- QRenderRule subRule = renderRule(w, opt, PseudoElement_SliderGroove);
- if (!subRule.hasDrawable())
- break;
- subRule.img = 0;
- QRect gr = positionRect(w, rule, subRule, PseudoElement_SliderGroove, opt->rect, opt->direction);
- switch (sc) {
- case SC_SliderGroove:
- return gr;
- case SC_SliderHandle: {
- bool horizontal = slider->orientation & Qt::Horizontal;
- QRect cr = subRule.contentsRect(gr);
- QRenderRule subRule2 = renderRule(w, opt, PseudoElement_SliderHandle);
- int len = horizontal ? subRule2.size().width() : subRule2.size().height();
- subRule2.img = 0;
- subRule2.geo = 0;
- cr = positionRect(w, subRule2, PseudoElement_SliderHandle, cr, opt->direction);
- int thickness = horizontal ? cr.height() : cr.width();
- int sliderPos = sliderPositionFromValue(slider->minimum, slider->maximum, slider->sliderPosition,
- (horizontal ? cr.width() : cr.height()) - len, slider->upsideDown);
- cr = horizontal ? QRect(cr.x() + sliderPos, cr.y(), len, thickness)
- : QRect(cr.x(), cr.y() + sliderPos, thickness, len);
- return subRule2.borderRect(cr);
- break; }
- case SC_SliderTickmarks:
- // TODO...
- default:
- break;
- }
- }
- break;
-#endif // QT_NO_SLIDER
-
- case CC_MdiControls:
- if (hasStyleRule(w, PseudoElement_MdiCloseButton)
- || hasStyleRule(w, PseudoElement_MdiNormalButton)
- || hasStyleRule(w, PseudoElement_MdiMinButton)) {
- QList<QVariant> layout = rule.styleHint(QLatin1String("button-layout")).toList();
- if (layout.isEmpty())
- layout = subControlLayout(QLatin1String("mNX"));
-
- int x = 0, width = 0;
- QRenderRule subRule;
- for (int i = 0; i < layout.count(); i++) {
- int layoutButton = layout[i].toInt();
- if (layoutButton < PseudoElement_MdiCloseButton
- || layoutButton > PseudoElement_MdiNormalButton)
- continue;
- QStyle::SubControl control = knownPseudoElements[layoutButton].subControl;
- if (!(opt->subControls & control))
- continue;
- subRule = renderRule(w, opt, layoutButton);
- width = subRule.size().width();
- if (sc == control)
- break;
- x += width;
- }
-
- return subRule.borderRect(QRect(x, opt->rect.top(), width, opt->rect.height()));
- }
- break;
-
- case CC_TitleBar:
- if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) {
- QRenderRule subRule = renderRule(w, opt, PseudoElement_TitleBar);
- if (!subRule.hasDrawable() && !subRule.hasBox() && !subRule.hasBorder())
- break;
- QHash<QStyle::SubControl, QRect> layoutRects = titleBarLayout(w, tb);
- return layoutRects.value(sc);
- }
- break;
-
- default:
- break;
- }
-
- return baseStyle()->subControlRect(cc, opt, sc, w);
-}
-
-QRect QStyleSheetStyle::subElementRect(SubElement se, const QStyleOption *opt, const QWidget *w) const
-{
- RECURSION_GUARD(return baseStyle()->subElementRect(se, opt, w))
-
- QRenderRule rule = renderRule(w, opt);
-#ifndef QT_NO_TABBAR
- int pe = PseudoElement_None;
-#endif
-
- switch (se) {
- case SE_PushButtonContents:
- case SE_PushButtonFocusRect:
- if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
- QStyleOptionButton btnOpt(*btn);
- if (rule.hasBox() || !rule.hasNativeBorder())
- return visualRect(opt->direction, opt->rect, rule.contentsRect(opt->rect));
- return rule.baseStyleCanDraw() ? baseStyle()->subElementRect(se, &btnOpt, w)
- : QWindowsStyle::subElementRect(se, &btnOpt, w);
- }
- break;
-
- case SE_LineEditContents:
- case SE_FrameContents:
- case SE_ShapedFrameContents:
- if (rule.hasBox() || !rule.hasNativeBorder()) {
- return visualRect(opt->direction, opt->rect, rule.contentsRect(opt->rect));
- }
- break;
-
- case SE_CheckBoxIndicator:
- case SE_RadioButtonIndicator:
- if (rule.hasBox() || rule.hasBorder() || hasStyleRule(w, PseudoElement_Indicator)) {
- PseudoElement pe = se == SE_CheckBoxIndicator ? PseudoElement_Indicator : PseudoElement_ExclusiveIndicator;
- QRenderRule subRule = renderRule(w, opt, pe);
- return positionRect(w, rule, subRule, pe, opt->rect, opt->direction);
- }
- break;
-
- case SE_CheckBoxContents:
- case SE_RadioButtonContents:
- if (rule.hasBox() || rule.hasBorder() || hasStyleRule(w, PseudoElement_Indicator)) {
- bool isRadio = se == SE_RadioButtonContents;
- QRect ir = subElementRect(isRadio ? SE_RadioButtonIndicator : SE_CheckBoxIndicator,
- opt, w);
- ir = visualRect(opt->direction, opt->rect, ir);
- int spacing = pixelMetric(isRadio ? PM_RadioButtonLabelSpacing : PM_CheckBoxLabelSpacing, 0, w);
- QRect cr = rule.contentsRect(opt->rect);
- ir.setRect(ir.left() + ir.width() + spacing, cr.y(),
- cr.width() - ir.width() - spacing, cr.height());
- return visualRect(opt->direction, opt->rect, ir);
- }
- break;
-
- case SE_ToolBoxTabContents:
- if (w && hasStyleRule(w->parentWidget(), PseudoElement_ToolBoxTab)) {
- QRenderRule subRule = renderRule(w->parentWidget(), opt, PseudoElement_ToolBoxTab);
- return visualRect(opt->direction, opt->rect, subRule.contentsRect(opt->rect));
- }
- break;
-
- case SE_RadioButtonFocusRect:
- case SE_RadioButtonClickRect: // focusrect | indicator
- if (rule.hasBox() || rule.hasBorder() || hasStyleRule(w, PseudoElement_Indicator)) {
- return opt->rect;
- }
- break;
-
- case SE_CheckBoxFocusRect:
- case SE_CheckBoxClickRect: // relies on indicator and contents
- return ParentStyle::subElementRect(se, opt, w);
-
-#ifndef QT_NO_ITEMVIEWS
- case SE_ViewItemCheckIndicator:
- if (!qstyleoption_cast<const QStyleOptionViewItemV4 *>(opt)) {
- return subElementRect(SE_CheckBoxIndicator, opt, w);
- }
- // intentionally falls through
- case SE_ItemViewItemText:
- case SE_ItemViewItemDecoration:
- case SE_ItemViewItemFocusRect:
- if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(opt)) {
- QRenderRule subRule = renderRule(w, opt, PseudoElement_ViewItem);
- PseudoElement pe = PseudoElement_None;
- if (se == SE_ItemViewItemText || se == SE_ItemViewItemFocusRect)
- pe = PseudoElement_ViewItemText;
- else if (se == SE_ItemViewItemDecoration && vopt->features & QStyleOptionViewItemV2::HasDecoration)
- pe = PseudoElement_ViewItemIcon;
- else if (se == SE_ItemViewItemCheckIndicator && vopt->features & QStyleOptionViewItemV2::HasCheckIndicator)
- pe = PseudoElement_ViewItemIndicator;
- else
- break;
- if (subRule.hasGeometry() || subRule.hasBox() || !subRule.hasNativeBorder() || hasStyleRule(w, pe)) {
- QRenderRule subRule2 = renderRule(w, opt, pe);
- QStyleOptionViewItemV4 optCopy(*vopt);
- optCopy.rect = subRule.contentsRect(vopt->rect);
- QRect rect = ParentStyle::subElementRect(se, &optCopy, w);
- return positionRect(w, subRule2, pe, rect, opt->direction);
- }
- }
- break;
-#endif // QT_NO_ITEMVIEWS
-
- case SE_HeaderArrow: {
- QRenderRule subRule = renderRule(w, opt, PseudoElement_HeaderViewUpArrow);
- if (subRule.hasPosition() || subRule.hasGeometry())
- return positionRect(w, rule, subRule, PseudoElement_HeaderViewUpArrow, opt->rect, opt->direction);
- }
- break;
-
- case SE_HeaderLabel: {
- QRenderRule subRule = renderRule(w, opt, PseudoElement_HeaderViewSection);
- if (subRule.hasBox() || !subRule.hasNativeBorder())
- return subRule.contentsRect(opt->rect);
- }
- break;
-
- case SE_ProgressBarGroove:
- case SE_ProgressBarContents:
- case SE_ProgressBarLabel:
- if (const QStyleOptionProgressBarV2 *pb = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(opt)) {
- if (rule.hasBox() || !rule.hasNativeBorder() || rule.hasPosition() || hasStyleRule(w, PseudoElement_ProgressBarChunk)) {
- if (se == SE_ProgressBarGroove)
- return rule.borderRect(pb->rect);
- else if (se == SE_ProgressBarContents)
- return rule.contentsRect(pb->rect);
-
- QSize sz = pb->fontMetrics.size(0, pb->text);
- return QStyle::alignedRect(Qt::LeftToRight, rule.hasPosition() ? rule.position()->textAlignment : pb->textAlignment,
- sz, pb->rect);
- }
- }
- break;
-
-#ifndef QT_NO_TABBAR
- case SE_TabWidgetLeftCorner:
- pe = PseudoElement_TabWidgetLeftCorner;
- // intentionally falls through
- case SE_TabWidgetRightCorner:
- if (pe == PseudoElement_None)
- pe = PseudoElement_TabWidgetRightCorner;
- // intentionally falls through
- case SE_TabWidgetTabBar:
- if (pe == PseudoElement_None)
- pe = PseudoElement_TabWidgetTabBar;
- // intentionally falls through
- case SE_TabWidgetTabPane:
- case SE_TabWidgetTabContents:
- if (pe == PseudoElement_None)
- pe = PseudoElement_TabWidgetPane;
-
- if (hasStyleRule(w, pe)) {
- QRect r = QWindowsStyle::subElementRect(pe == PseudoElement_TabWidgetPane ? SE_TabWidgetTabPane : se, opt, w);
- QRenderRule subRule = renderRule(w, opt, pe);
- r = positionRect(w, subRule, pe, r, opt->direction);
- if (pe == PseudoElement_TabWidgetTabBar) {
- Q_ASSERT(opt);
- r = opt->rect.intersected(r);
- }
- if (se == SE_TabWidgetTabContents)
- r = subRule.contentsRect(r);
- return r;
- }
- break;
-
- case SE_TabBarTearIndicator: {
- QRenderRule subRule = renderRule(w, opt, PseudoElement_TabBarTear);
- if (subRule.hasContentsSize()) {
- QRect r;
- if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
- switch (tab->shape) {
- case QTabBar::RoundedNorth:
- case QTabBar::TriangularNorth:
- case QTabBar::RoundedSouth:
- case QTabBar::TriangularSouth:
- r.setRect(tab->rect.left(), tab->rect.top(), subRule.size().width(), opt->rect.height());
- break;
- case QTabBar::RoundedWest:
- case QTabBar::TriangularWest:
- case QTabBar::RoundedEast:
- case QTabBar::TriangularEast:
- r.setRect(tab->rect.left(), tab->rect.top(), opt->rect.width(), subRule.size().height());
- break;
- default:
- break;
- }
- r = visualRect(opt->direction, opt->rect, r);
- }
- return r;
- }
- break;
- }
- case SE_TabBarTabText:
- case SE_TabBarTabLeftButton:
- case SE_TabBarTabRightButton: {
- QRenderRule subRule = renderRule(w, opt, PseudoElement_TabBarTab);
- if (subRule.hasBox() || !subRule.hasNativeBorder()) {
- return ParentStyle::subElementRect(se, opt, w);
- }
- break;
- }
-#endif // QT_NO_TABBAR
-
- case SE_DockWidgetCloseButton:
- case SE_DockWidgetFloatButton: {
- PseudoElement pe = (se == SE_DockWidgetCloseButton) ? PseudoElement_DockWidgetCloseButton : PseudoElement_DockWidgetFloatButton;
- QRenderRule subRule2 = renderRule(w, opt, pe);
- if (!subRule2.hasPosition())
- break;
- QRenderRule subRule = renderRule(w, opt, PseudoElement_DockWidgetTitle);
- return positionRect(w, subRule, subRule2, pe, opt->rect, opt->direction);
- }
-
-#ifndef QT_NO_TOOLBAR
- case SE_ToolBarHandle:
- if (hasStyleRule(w, PseudoElement_ToolBarHandle))
- return ParentStyle::subElementRect(se, opt, w);
- break;
-#endif //QT_NO_TOOLBAR
-
- default:
- break;
- }
-
- return baseStyle()->subElementRect(se, opt, w);
-}
-
-bool QStyleSheetStyle::event(QEvent *e)
-{
- return (baseStyle()->event(e) && e->isAccepted()) || ParentStyle::event(e);
-}
-
-void QStyleSheetStyle::updateStyleSheetFont(QWidget* w) const
-{
- QWidget *container = containerWidget(w);
- QRenderRule rule = renderRule(container, PseudoElement_None,
- PseudoClass_Active | PseudoClass_Enabled | extendedPseudoClass(container));
- QFont font = rule.font.resolve(w->font());
-
- if ((!w->isWindow() || w->testAttribute(Qt::WA_WindowPropagation))
- && isNaturalChild(w) && qobject_cast<QWidget *>(w->parent())) {
-
- font = font.resolve(static_cast<QWidget *>(w->parent())->font());
- }
-
- if (w->data->fnt == font)
- return;
-
-#ifdef QT3_SUPPORT
- QFont old = w->data->fnt;
-#endif
- w->data->fnt = font;
-#if defined(Q_WS_X11)
- // make sure the font set on this widget is associated with the correct screen
- //w->data->fnt.x11SetScreen(w->d_func()->xinfo.screen());
-#endif
-
- QEvent e(QEvent::FontChange);
- QApplication::sendEvent(w, &e);
-#ifdef QT3_SUPPORT
- w->fontChange(old);
-#endif
-}
-
-void QStyleSheetStyle::saveWidgetFont(QWidget* w, const QFont& font) const
-{
- w->setProperty("_q_styleSheetWidgetFont", font);
-}
-
-void QStyleSheetStyle::clearWidgetFont(QWidget* w) const
-{
- w->setProperty("_q_styleSheetWidgetFont", QVariant(QVariant::Invalid));
-}
-
-// Polish palette that should be used for a particular widget, with particular states
-// (eg. :focus, :hover, ...)
-// this is called by widgets that paint themself in their paint event
-// Returns true if there is a new palette in pal.
-bool QStyleSheetStyle::styleSheetPalette(const QWidget* w, const QStyleOption* opt, QPalette* pal)
-{
- if (!w || !opt || !pal)
- return false;
-
- RECURSION_GUARD(return false)
-
- w = containerWidget(w);
-
- QRenderRule rule = renderRule(w, PseudoElement_None, pseudoClass(opt->state) | extendedPseudoClass(w));
- if (!rule.hasPalette())
- return false;
-
- rule.configurePalette(pal, QPalette::NoRole, QPalette::NoRole);
- return true;
-}
-
-Qt::Alignment QStyleSheetStyle::resolveAlignment(Qt::LayoutDirection layDir, Qt::Alignment src)
-{
- if (layDir == Qt::LeftToRight || src & Qt::AlignAbsolute)
- return src;
-
- if (src & Qt::AlignLeft) {
- src &= ~Qt::AlignLeft;
- src |= Qt::AlignRight;
- } else if (src & Qt::AlignRight) {
- src &= ~Qt::AlignRight;
- src |= Qt::AlignLeft;
- }
- src |= Qt::AlignAbsolute;
- return src;
-}
-
-// Returns whether the given QWidget has a "natural" parent, meaning that
-// the parent contains this child as part of its normal operation.
-// An example is the QTabBar inside a QTabWidget.
-// This does not mean that any QTabBar which is a child of QTabWidget will
-// match, only the one that was created by the QTabWidget initialization
-// (and hence has the correct object name).
-bool QStyleSheetStyle::isNaturalChild(const QWidget *w)
-{
- if (w->objectName().startsWith(QLatin1String("qt_")))
- return true;
-
- return false;
-}
-
-QT_END_NAMESPACE
-
-#include "moc_qstylesheetstyle_p.cpp"
-
-#endif // QT_NO_STYLE_STYLESHEET
diff --git a/src/gui/styles/qstylesheetstyle_p.h b/src/gui/styles/qstylesheetstyle_p.h
deleted file mode 100644
index e597ba1639..0000000000
--- a/src/gui/styles/qstylesheetstyle_p.h
+++ /dev/null
@@ -1,204 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSTYLESHEETSTYLE_P_H
-#define QSTYLESHEETSTYLE_P_H
-
-#include "QtGui/qwindowsstyle.h"
-
-#ifndef QT_NO_STYLE_STYLESHEET
-
-#include "QtGui/qstyleoption.h"
-#include "QtCore/qhash.h"
-#include "QtGui/qevent.h"
-#include "QtCore/qvector.h"
-#include "QtGui/qapplication.h"
-#include "private/qcssparser_p.h"
-#include "QtGui/qbrush.h"
-
-QT_BEGIN_NAMESPACE
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-class QRenderRule;
-class QAbstractScrollArea;
-class QStyleSheetStylePrivate;
-class QStyleOptionTitleBar;
-
-class Q_AUTOTEST_EXPORT QStyleSheetStyle : public QWindowsStyle
-{
- typedef QWindowsStyle ParentStyle;
-
- Q_OBJECT
-public:
- QStyleSheetStyle(QStyle *baseStyle);
- ~QStyleSheetStyle();
-
- void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p,
- const QWidget *w = 0) const;
- void drawControl(ControlElement element, const QStyleOption *opt, QPainter *p,
- const QWidget *w = 0) const;
- void drawItemPixmap(QPainter *painter, const QRect &rect, int alignment, const QPixmap &pixmap) const;
- void drawItemText(QPainter *painter, const QRect& rect, int alignment, const QPalette &pal,
- bool enabled, const QString& text, QPalette::ColorRole textRole = QPalette::NoRole) const;
- void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p,
- const QWidget *w = 0) const;
- QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap,
- const QStyleOption *option) const;
- SubControl hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt,
- const QPoint &pt, const QWidget *w = 0) const;
- QRect itemPixmapRect(const QRect &rect, int alignment, const QPixmap &pixmap) const;
- QRect itemTextRect(const QFontMetrics &metrics, const QRect &rect, int alignment, bool enabled,
- const QString &text) const;
- int pixelMetric(PixelMetric metric, const QStyleOption *option = 0, const QWidget *widget = 0) const;
- void polish(QWidget *widget);
- void polish(QApplication *app);
- void polish(QPalette &pal);
- QSize sizeFromContents(ContentsType ct, const QStyleOption *opt,
- const QSize &contentsSize, const QWidget *widget = 0) const;
- QPalette standardPalette() const;
- QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *option = 0,
- const QWidget *w = 0 ) const;
- int layoutSpacing(QSizePolicy::ControlType control1, QSizePolicy::ControlType control2,
- Qt::Orientation orientation, const QStyleOption *option = 0,
- const QWidget *widget = 0) const;
- int styleHint(StyleHint sh, const QStyleOption *opt = 0, const QWidget *w = 0,
- QStyleHintReturn *shret = 0) const;
- QRect subElementRect(SubElement r, const QStyleOption *opt, const QWidget *widget = 0) const;
- QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc,
- const QWidget *w = 0) const;
-
- // These functions are called from QApplication/QWidget. Be careful.
- QStyle *baseStyle() const;
- void repolish(QWidget *widget);
- void repolish(QApplication *app);
-
- void unpolish(QWidget *widget);
- void unpolish(QApplication *app);
-
- QStyle *base;
- void ref() { ++refcount; }
- void deref() { Q_ASSERT(refcount > 0); if (!--refcount) delete this; }
-
- void updateStyleSheetFont(QWidget* w) const;
- void saveWidgetFont(QWidget* w, const QFont& font) const;
- void clearWidgetFont(QWidget* w) const;
-
- bool styleSheetPalette(const QWidget* w, const QStyleOption* opt, QPalette* pal);
-
-protected Q_SLOTS:
- QIcon standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *opt = 0,
- const QWidget *widget = 0) const;
- int layoutSpacingImplementation(QSizePolicy::ControlType control1,
- QSizePolicy::ControlType control2,
- Qt::Orientation orientation,
- const QStyleOption *option = 0,
- const QWidget *widget = 0) const;
-
-protected:
- bool event(QEvent *e);
-
-private:
- int refcount;
-
- friend class QRenderRule;
- int nativeFrameWidth(const QWidget *);
- QRenderRule renderRule(const QWidget *, int, quint64 = 0) const;
- QRenderRule renderRule(const QWidget *, const QStyleOption *, int = 0) const;
- QSize defaultSize(const QWidget *, QSize, const QRect&, int) const;
- QRect positionRect(const QWidget *, const QRenderRule&, const QRenderRule&, int,
- const QRect&, Qt::LayoutDirection) const;
- QRect positionRect(const QWidget *w, const QRenderRule &rule2, int pe,
- const QRect &originRect, Qt::LayoutDirection dir) const;
-
- mutable QCss::Parser parser;
-
- void setPalette(QWidget *);
- void unsetPalette(QWidget *);
- void setProperties(QWidget *);
- void setGeometry(QWidget *);
- QVector<QCss::StyleRule> styleRules(const QWidget *w) const;
- bool hasStyleRule(const QWidget *w, int part) const;
-
- QHash<QStyle::SubControl, QRect> titleBarLayout(const QWidget *w, const QStyleOptionTitleBar *tb) const;
-
- QCss::StyleSheet getDefaultStyleSheet() const;
-
- static Qt::Alignment resolveAlignment(Qt::LayoutDirection, Qt::Alignment);
- static bool isNaturalChild(const QWidget *w);
- bool initWidget(const QWidget *w) const;
-public:
- static int numinstances;
-
-private:
- Q_DISABLE_COPY(QStyleSheetStyle)
- Q_DECLARE_PRIVATE(QStyleSheetStyle)
-};
-
-class QStyleSheetStyleCaches : public QObject
-{
- Q_OBJECT
-public Q_SLOTS:
- void widgetDestroyed(QObject *);
- void styleDestroyed(QObject *);
-public:
- QHash<const QWidget *, QVector<QCss::StyleRule> > styleRulesCache;
- QHash<const QWidget *, QHash<int, bool> > hasStyleRuleCache;
- typedef QHash<int, QHash<quint64, QRenderRule> > QRenderRules;
- QHash<const QWidget *, QRenderRules> renderRulesCache;
- QHash<const QWidget *, QPalette> customPaletteWidgets; // widgets whose palette we tampered
- QHash<const void *, QCss::StyleSheet> styleSheetCache; // parsed style sheets
- QSet<const QWidget *> autoFillDisabledWidgets;
-};
-
-
-QT_END_NAMESPACE
-#endif // QT_NO_STYLE_STYLESHEET
-#endif // QSTYLESHEETSTYLE_P_H
diff --git a/src/gui/styles/qwindowscestyle.h b/src/gui/styles/qwindowscestyle.h
deleted file mode 100644
index e5f26be79b..0000000000
--- a/src/gui/styles/qwindowscestyle.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWINDOWSCESTYLE_H
-#define QWINDOWSCESTYLE_H
-
-#include <QtGui/qwindowsstyle.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#if !defined(QT_NO_STYLE_WINDOWSCE)
-
-class Q_GUI_EXPORT QWindowsCEStyle : public QWindowsStyle
-{
- Q_OBJECT
-public:
- QWindowsCEStyle();
-
- void drawPrimitive(PrimitiveElement element, const QStyleOption *option,
- QPainter *painter, const QWidget *widget = 0) const;
-
- void drawControl(ControlElement element, const QStyleOption *option,
- QPainter *painter, const QWidget *widget) const;
-
- void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option,
- QPainter *painter, const QWidget *widget) const;
-
- virtual void drawItemText(QPainter *painter, const QRect &rect,
- int flags, const QPalette &pal, bool enabled,
- const QString &text, QPalette::ColorRole textRole = QPalette::NoRole) const;
-
- QSize sizeFromContents(ContentsType type, const QStyleOption *option,
- const QSize &size, const QWidget *widget) const;
-
- QRect subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const;
- QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt,
- SubControl sc, const QWidget *widget) const;
-
- SubControl hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option,
- const QPoint &pos, const QWidget *widget = 0) const;
-
- QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt,
- const QWidget *widget = 0) const;
- int pixelMetric(PixelMetric metric, const QStyleOption *option = 0, const QWidget *widget = 0) const;
-
- int styleHint(StyleHint hint, const QStyleOption *opt = 0, const QWidget *widget = 0,
- QStyleHintReturn *returnData = 0) const;
-
- void polish(QWidget *widget);
- void polish(QPalette &palette);
- void polish(QApplication *app);
- QPalette standardPalette() const;
-};
-
-#endif // QT_NO_STYLE_WINDOWSCE
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QWINDOWSCESTYLE_H
diff --git a/src/gui/styles/qwindowsmobilestyle.h b/src/gui/styles/qwindowsmobilestyle.h
deleted file mode 100644
index 74e4733126..0000000000
--- a/src/gui/styles/qwindowsmobilestyle.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWINDOWSMOBILESTYLE_H
-#define QWINDOWSMOBILESTYLE_H
-
-#include <QtGui/qwindowsstyle.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#if !defined(QT_NO_STYLE_WINDOWSMOBILE)
-
-class QWindowsMobileStylePrivate;
-
-class Q_GUI_EXPORT QWindowsMobileStyle : public QWindowsStyle
-{
- Q_OBJECT
-public:
- QWindowsMobileStyle();
-
- void drawPrimitive(PrimitiveElement element, const QStyleOption *option,
- QPainter *painter, const QWidget *widget = 0) const;
-
- void drawControl(ControlElement element, const QStyleOption *option,
- QPainter *painter, const QWidget *widget) const;
-
- void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option,
- QPainter *painter, const QWidget *widget) const;
-
- QSize sizeFromContents(ContentsType type, const QStyleOption *option,
- const QSize &size, const QWidget *widget) const;
-
- QRect subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const;
-
- QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt,
- SubControl sc, const QWidget *widget) const;
-
- QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap,
- const QStyleOption *option) const;
-
- QPixmap standardPixmap(StandardPixmap sp, const QStyleOption *option,
- const QWidget *widget) const;
-
- int pixelMetric(PixelMetric metric, const QStyleOption *option = 0, const QWidget *widget = 0) const;
-
- int styleHint(StyleHint hint, const QStyleOption *opt = 0, const QWidget *widget = 0,
- QStyleHintReturn *returnData = 0) const;
-
- void polish(QApplication*);
- void unpolish(QApplication*);
- void polish(QWidget *widget);
- void unpolish(QWidget *widget);
- void polish(QPalette &);
-
- QPalette standardPalette() const;
-
- bool doubleControls() const;
-
- void setDoubleControls(bool);
-
-protected:
- QWindowsMobileStyle(QWindowsMobileStylePrivate &dd);
-
-private:
- Q_DECLARE_PRIVATE(QWindowsMobileStyle)
-};
-
-#endif // QT_NO_STYLE_WINDOWSMOBILE
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif //QWINDOWSMOBILESTYLE_H
diff --git a/src/gui/styles/qwindowsstyle.cpp b/src/gui/styles/qwindowsstyle.cpp
deleted file mode 100644
index c0992733f8..0000000000
--- a/src/gui/styles/qwindowsstyle.cpp
+++ /dev/null
@@ -1,3390 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qwindowsstyle.h"
-#include "qwindowsstyle_p.h"
-
-#if !defined(QT_NO_STYLE_WINDOWS) || defined(QT_PLUGIN)
-
-#include <private/qsystemlibrary_p.h>
-#include "qapplication.h"
-#include "qbitmap.h"
-#include "qdrawutil.h" // for now
-#include "qevent.h"
-#include "qmenu.h"
-#include "qmenubar.h"
-#include <private/qmenubar_p.h>
-#include "qpaintengine.h"
-#include "qpainter.h"
-#include "qprogressbar.h"
-#include "qrubberband.h"
-#include "qstyleoption.h"
-#include "qtabbar.h"
-#include "qwidget.h"
-#include "qdebug.h"
-#include "qmainwindow.h"
-#include "qfile.h"
-#include "qtextstream.h"
-#include "qpixmapcache.h"
-#include "qwizard.h"
-#include "qlistview.h"
-#include <private/qmath_p.h>
-#include <qmath.h>
-
-#ifdef Q_WS_X11
-#include "qfileinfo.h"
-#include "qdir.h"
-#include <private/qt_x11_p.h>
-#endif
-
-#include <private/qstylehelper_p.h>
-
-QT_BEGIN_NAMESPACE
-
-#if defined(Q_WS_WIN)
-
-QT_BEGIN_INCLUDE_NAMESPACE
-#include "qt_windows.h"
-QT_END_INCLUDE_NAMESPACE
-# ifndef COLOR_GRADIENTACTIVECAPTION
-# define COLOR_GRADIENTACTIVECAPTION 27
-# endif
-# ifndef COLOR_GRADIENTINACTIVECAPTION
-# define COLOR_GRADIENTINACTIVECAPTION 28
-# endif
-
-
-typedef struct
-{
- DWORD cbSize;
- HICON hIcon;
- int iSysImageIndex;
- int iIcon;
- WCHAR szPath[MAX_PATH];
-} QSHSTOCKICONINFO;
-
-#define _SHGFI_SMALLICON 0x000000001
-#define _SHGFI_LARGEICON 0x000000000
-#define _SHGFI_ICON 0x000000100
-#define _SIID_SHIELD 77
-
-typedef HRESULT (WINAPI *PtrSHGetStockIconInfo)(int siid, int uFlags, QSHSTOCKICONINFO *psii);
-static PtrSHGetStockIconInfo pSHGetStockIconInfo = 0;
-
-#endif //Q_WS_WIN
-
-QT_BEGIN_INCLUDE_NAMESPACE
-#include <limits.h>
-QT_END_INCLUDE_NAMESPACE
-
-enum QSliderDirection { SlUp, SlDown, SlLeft, SlRight };
-
-/*
- \internal
-*/
-QWindowsStylePrivate::QWindowsStylePrivate()
- : alt_down(false), menuBarTimer(0), animationFps(10), animateTimer(0), animateStep(0)
-{
-#if defined(Q_WS_WIN) && !defined(Q_OS_WINCE)
- if ((QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA
- && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)) {
- QSystemLibrary shellLib(QLatin1String("shell32"));
- pSHGetStockIconInfo = (PtrSHGetStockIconInfo)shellLib.resolve("SHGetStockIconInfo");
- }
-#endif
- startTime.start();
-}
-
-// Returns true if the toplevel parent of \a widget has seen the Alt-key
-bool QWindowsStylePrivate::hasSeenAlt(const QWidget *widget) const
-{
- widget = widget->window();
- return seenAlt.contains(widget);
-}
-
-/*!
- \reimp
-*/
-void QWindowsStyle::timerEvent(QTimerEvent *event)
-{
-#ifndef QT_NO_PROGRESSBAR
- Q_D(QWindowsStyle);
- if (event->timerId() == d->animateTimer) {
- Q_ASSERT(d->animationFps> 0);
- d->animateStep = d->startTime.elapsed() / (1000 / d->animationFps);
- foreach (QProgressBar *bar, d->bars) {
- if ((bar->minimum() == 0 && bar->maximum() == 0))
- bar->update();
- }
- }
-#endif // QT_NO_PROGRESSBAR
- event->ignore();
-}
-
-/*!
- \reimp
-*/
-bool QWindowsStyle::eventFilter(QObject *o, QEvent *e)
-{
- // Records Alt- and Focus events
- if (!o->isWidgetType())
- return QObject::eventFilter(o, e);
-
- QWidget *widget = qobject_cast<QWidget*>(o);
- Q_D(QWindowsStyle);
- switch(e->type()) {
- case QEvent::KeyPress:
- if (static_cast<QKeyEvent *>(e)->key() == Qt::Key_Alt) {
- widget = widget->window();
-
- // Alt has been pressed - find all widgets that care
- QList<QWidget *> l = widget->findChildren<QWidget *>();
- for (int pos=0 ; pos < l.size() ; ++pos) {
- QWidget *w = l.at(pos);
- if (w->isWindow() || !w->isVisible() ||
- w->style()->styleHint(SH_UnderlineShortcut, 0, w))
- l.removeAt(pos);
- }
- // Update states before repainting
- d->seenAlt.append(widget);
- d->alt_down = true;
-
- // Repaint all relevant widgets
- for (int pos = 0; pos < l.size(); ++pos)
- l.at(pos)->update();
- }
- break;
- case QEvent::KeyRelease:
- if (static_cast<QKeyEvent*>(e)->key() == Qt::Key_Alt) {
- widget = widget->window();
-
- // Update state and repaint the menu bars.
- d->alt_down = false;
-#ifndef QT_NO_MENUBAR
- QList<QMenuBar *> l = widget->findChildren<QMenuBar *>();
- for (int i = 0; i < l.size(); ++i)
- l.at(i)->update();
-#endif
- }
- break;
- case QEvent::Close:
- // Reset widget when closing
- d->seenAlt.removeAll(widget);
- d->seenAlt.removeAll(widget->window());
- break;
-#ifndef QT_NO_PROGRESSBAR
- case QEvent::StyleChange:
- case QEvent::Show:
- if (QProgressBar *bar = qobject_cast<QProgressBar *>(o)) {
- if (!d->bars.contains(bar)) {
- d->bars << bar;
- if (d->bars.size() == 1) {
- Q_ASSERT(d->animationFps> 0);
- d->animateTimer = startTimer(1000 / d->animationFps);
- }
- }
- }
- break;
- case QEvent::Destroy:
- case QEvent::Hide:
- // reinterpret_cast because there is no type info when getting
- // the destroy event. We know that it is a QProgressBar.
- if (QProgressBar *bar = reinterpret_cast<QProgressBar *>(o)) {
- d->bars.removeAll(bar);
- if (d->bars.isEmpty() && d->animateTimer) {
- killTimer(d->animateTimer);
- d->animateTimer = 0;
- }
- }
- break;
-#endif // QT_NO_PROGRESSBAR
- default:
- break;
- }
- return QCommonStyle::eventFilter(o, e);
-}
-
-/*!
- \class QWindowsStyle
- \brief The QWindowsStyle class provides a Microsoft Windows-like look and feel.
-
- \ingroup appearance
-
- This style is Qt's default GUI style on Windows.
-
- \img qwindowsstyle.png
- \sa QWindowsXPStyle, QMacStyle, QPlastiqueStyle, QCDEStyle, QMotifStyle
-*/
-
-/*!
- Constructs a QWindowsStyle object.
-*/
-QWindowsStyle::QWindowsStyle() : QCommonStyle(*new QWindowsStylePrivate)
-{
-}
-
-/*!
- \internal
-
- Constructs a QWindowsStyle object.
-*/
-QWindowsStyle::QWindowsStyle(QWindowsStylePrivate &dd) : QCommonStyle(dd)
-{
-}
-
-
-/*! Destroys the QWindowsStyle object. */
-QWindowsStyle::~QWindowsStyle()
-{
-}
-
-#ifdef Q_WS_WIN
-static inline QRgb colorref2qrgb(COLORREF col)
-{
- return qRgb(GetRValue(col), GetGValue(col), GetBValue(col));
-}
-#endif
-
-/*! \reimp */
-void QWindowsStyle::polish(QApplication *app)
-{
- QCommonStyle::polish(app);
- QWindowsStylePrivate *d = const_cast<QWindowsStylePrivate*>(d_func());
- // We only need the overhead when shortcuts are sometimes hidden
- if (!proxy()->styleHint(SH_UnderlineShortcut, 0) && app)
- app->installEventFilter(this);
-
- d->activeCaptionColor = app->palette().highlight().color();
- d->activeGradientCaptionColor = app->palette().highlight() .color();
- d->inactiveCaptionColor = app->palette().dark().color();
- d->inactiveGradientCaptionColor = app->palette().dark().color();
- d->inactiveCaptionText = app->palette().background().color();
-
-#if defined(Q_WS_WIN) //fetch native title bar colors
- if(app->desktopSettingsAware()){
- DWORD activeCaption = GetSysColor(COLOR_ACTIVECAPTION);
- DWORD gradientActiveCaption = GetSysColor(COLOR_GRADIENTACTIVECAPTION);
- DWORD inactiveCaption = GetSysColor(COLOR_INACTIVECAPTION);
- DWORD gradientInactiveCaption = GetSysColor(COLOR_GRADIENTINACTIVECAPTION);
- DWORD inactiveCaptionText = GetSysColor(COLOR_INACTIVECAPTIONTEXT);
- d->activeCaptionColor = colorref2qrgb(activeCaption);
- d->activeGradientCaptionColor = colorref2qrgb(gradientActiveCaption);
- d->inactiveCaptionColor = colorref2qrgb(inactiveCaption);
- d->inactiveGradientCaptionColor = colorref2qrgb(gradientInactiveCaption);
- d->inactiveCaptionText = colorref2qrgb(inactiveCaptionText);
- }
-#endif
-}
-
-/*! \reimp */
-void QWindowsStyle::unpolish(QApplication *app)
-{
- QCommonStyle::unpolish(app);
- app->removeEventFilter(this);
-}
-
-/*! \reimp */
-void QWindowsStyle::polish(QWidget *widget)
-{
- QCommonStyle::polish(widget);
-#ifndef QT_NO_PROGRESSBAR
- if (qobject_cast<QProgressBar *>(widget))
- widget->installEventFilter(this);
-#endif
-}
-
-/*! \reimp */
-void QWindowsStyle::unpolish(QWidget *widget)
-{
- QCommonStyle::unpolish(widget);
-#ifndef QT_NO_PROGRESSBAR
- if (QProgressBar *bar=qobject_cast<QProgressBar *>(widget)) {
- Q_D(QWindowsStyle);
- widget->removeEventFilter(this);
- d->bars.removeAll(bar);
- }
-#endif
-}
-
-/*!
- \reimp
-*/
-void QWindowsStyle::polish(QPalette &pal)
-{
- QCommonStyle::polish(pal);
-}
-
-/*!
- \reimp
-*/
-int QWindowsStyle::pixelMetric(PixelMetric pm, const QStyleOption *opt, const QWidget *widget) const
-{
- int ret;
-
- switch (pm) {
- case PM_ButtonDefaultIndicator:
- case PM_ButtonShiftHorizontal:
- case PM_ButtonShiftVertical:
- case PM_MenuHMargin:
- case PM_MenuVMargin:
- ret = 1;
- break;
-#ifndef QT_NO_TABBAR
- case PM_TabBarTabShiftHorizontal:
- ret = 0;
- break;
- case PM_TabBarTabShiftVertical:
- ret = 2;
- break;
-#endif
- case PM_MaximumDragDistance:
-#if defined(Q_WS_WIN)
- {
- HDC hdcScreen = GetDC(0);
- int dpi = GetDeviceCaps(hdcScreen, LOGPIXELSX);
- ReleaseDC(0, hdcScreen);
- ret = (int)(dpi * 1.375);
- }
-#else
- ret = 60;
-#endif
- break;
-
-#ifndef QT_NO_SLIDER
- case PM_SliderLength:
- ret = int(QStyleHelper::dpiScaled(11.));
- break;
-
- // Returns the number of pixels to use for the business part of the
- // slider (i.e., the non-tickmark portion). The remaining space is shared
- // equally between the tickmark regions.
- case PM_SliderControlThickness:
- if (const QStyleOptionSlider *sl = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
- int space = (sl->orientation == Qt::Horizontal) ? sl->rect.height() : sl->rect.width();
- int ticks = sl->tickPosition;
- int n = 0;
- if (ticks & QSlider::TicksAbove)
- ++n;
- if (ticks & QSlider::TicksBelow)
- ++n;
- if (!n) {
- ret = space;
- break;
- }
-
- int thick = 6; // Magic constant to get 5 + 16 + 5
- if (ticks != QSlider::TicksBothSides && ticks != QSlider::NoTicks)
- thick += proxy()->pixelMetric(PM_SliderLength, sl, widget) / 4;
-
- space -= thick;
- if (space > 0)
- thick += (space * 2) / (n + 2);
- ret = thick;
- } else {
- ret = 0;
- }
- break;
-#endif // QT_NO_SLIDER
-
-#ifndef QT_NO_MENU
- case PM_MenuBarHMargin:
- ret = 0;
- break;
-
- case PM_MenuBarVMargin:
- ret = 0;
- break;
-
- case PM_MenuBarPanelWidth:
- ret = 0;
- break;
-
- case PM_SmallIconSize:
- ret = int(QStyleHelper::dpiScaled(16.));
- break;
-
- case PM_LargeIconSize:
- ret = int(QStyleHelper::dpiScaled(32.));
- break;
-
- case PM_IconViewIconSize:
- ret = proxy()->pixelMetric(PM_LargeIconSize, opt, widget);
- break;
-
- case PM_DockWidgetTitleMargin:
- ret = int(QStyleHelper::dpiScaled(2.));
- break;
- case PM_DockWidgetTitleBarButtonMargin:
- ret = int(QStyleHelper::dpiScaled(4.));
- break;
-#if defined(Q_WS_WIN)
- case PM_DockWidgetFrameWidth:
-#if defined(Q_OS_WINCE)
- ret = GetSystemMetrics(SM_CXDLGFRAME);
-#else
- ret = GetSystemMetrics(SM_CXFRAME);
-#endif
- break;
-#else
- case PM_DockWidgetFrameWidth:
- ret = 4;
- break;
-#endif // Q_WS_WIN
- break;
-
-#endif // QT_NO_MENU
-
-
-#if defined(Q_WS_WIN)
- case PM_TitleBarHeight:
-#ifdef QT3_SUPPORT
- // qt3 dockwindow height should be equal to tool windows
- if (widget && widget->inherits("Q3DockWindowTitleBar")) {
- ret = GetSystemMetrics(SM_CYSMCAPTION) - 1;
- } else
-#endif
- if (widget && (widget->windowType() == Qt::Tool)) {
- // MS always use one less than they say
-#if defined(Q_OS_WINCE)
- ret = GetSystemMetrics(SM_CYCAPTION) - 1;
-#else
- ret = GetSystemMetrics(SM_CYSMCAPTION) - 1;
-#endif
- } else {
- ret = GetSystemMetrics(SM_CYCAPTION) - 1;
- }
-
- break;
-
- case PM_ScrollBarExtent:
- {
-#ifndef Q_OS_WINCE
- NONCLIENTMETRICS ncm;
- ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICS, lfMessageFont) + sizeof(LOGFONT);
- if (SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0))
- ret = qMax(ncm.iScrollHeight, ncm.iScrollWidth);
- else
-#endif
- ret = QCommonStyle::pixelMetric(pm, opt, widget);
- }
- break;
-#endif // Q_WS_WIN
-
- case PM_SplitterWidth:
- ret = qMax(4, QApplication::globalStrut().width());
- break;
-
-#if defined(Q_WS_WIN)
- case PM_MdiSubWindowFrameWidth:
-#if defined(Q_OS_WINCE)
- ret = GetSystemMetrics(SM_CYDLGFRAME);
-#else
- ret = GetSystemMetrics(SM_CYFRAME);
-#endif
- break;
- case PM_TextCursorWidth: {
- DWORD caretWidth = 1;
-#if defined(SPI_GETCARETWIDTH)
- SystemParametersInfo(SPI_GETCARETWIDTH, 0, &caretWidth, 0);
-#endif
- ret = (int)caretWidth;
- break; }
-#endif
- case PM_ToolBarItemMargin:
- ret = 1;
- break;
- case PM_ToolBarItemSpacing:
- ret = 0;
- break;
- case PM_ToolBarHandleExtent:
- ret = int(QStyleHelper::dpiScaled(10.));
- break;
- default:
- ret = QCommonStyle::pixelMetric(pm, opt, widget);
- break;
- }
-
- return ret;
-}
-
-#ifndef QT_NO_IMAGEFORMAT_XPM
-
-/* XPM */
-static const char * const qt_menu_xpm[] = {
-"16 16 72 1",
-" c None",
-". c #65AF36",
-"+ c #66B036",
-"@ c #77B94C",
-"# c #A7D28C",
-"$ c #BADBA4",
-"% c #A4D088",
-"& c #72B646",
-"* c #9ACB7A",
-"= c #7FBD56",
-"- c #85C05F",
-"; c #F4F9F0",
-"> c #FFFFFF",
-", c #E5F1DC",
-"' c #ECF5E7",
-") c #7ABA50",
-"! c #83BF5C",
-"~ c #AED595",
-"{ c #D7EACA",
-"] c #A9D28D",
-"^ c #BCDDA8",
-"/ c #C4E0B1",
-"( c #81BE59",
-"_ c #D0E7C2",
-": c #D4E9C6",
-"< c #6FB542",
-"[ c #6EB440",
-"} c #88C162",
-"| c #98CA78",
-"1 c #F4F9F1",
-"2 c #8FC56C",
-"3 c #F1F8EC",
-"4 c #E8F3E1",
-"5 c #D4E9C7",
-"6 c #74B748",
-"7 c #80BE59",
-"8 c #73B747",
-"9 c #6DB43F",
-"0 c #CBE4BA",
-"a c #80BD58",
-"b c #6DB33F",
-"c c #FEFFFE",
-"d c #68B138",
-"e c #F9FCF7",
-"f c #91C66F",
-"g c #E8F3E0",
-"h c #DCEDD0",
-"i c #91C66E",
-"j c #A3CF86",
-"k c #C9E3B8",
-"l c #B0D697",
-"m c #E3F0DA",
-"n c #95C873",
-"o c #E6F2DE",
-"p c #9ECD80",
-"q c #BEDEAA",
-"r c #C7E2B6",
-"s c #79BA4F",
-"t c #6EB441",
-"u c #BCDCA7",
-"v c #FAFCF8",
-"w c #F6FAF3",
-"x c #84BF5D",
-"y c #EDF6E7",
-"z c #FAFDF9",
-"A c #88C263",
-"B c #98CA77",
-"C c #CDE5BE",
-"D c #67B037",
-"E c #D9EBCD",
-"F c #6AB23C",
-"G c #77B94D",
-" .++++++++++++++",
-".+++++++++++++++",
-"+++@#$%&+++*=+++",
-"++-;>,>')+!>~+++",
-"++{>]+^>/(_>:~<+",
-"+[>>}+|>123>456+",
-"+7>>8+->>90>~+++",
-"+a>>b+a>c[0>~+++",
-"+de>=+f>g+0>~+++",
-"++h>i+j>k+0>~+++",
-"++l>mno>p+q>rst+",
-"++duv>wl++xy>zA+",
-"++++B>Cb++++&D++",
-"+++++0zE++++++++",
-"++++++FG+++++++.",
-"++++++++++++++. "};
-
-static const char * const qt_close_xpm[] = {
-"10 10 2 1",
-"# c #000000",
-". c None",
-"..........",
-".##....##.",
-"..##..##..",
-"...####...",
-"....##....",
-"...####...",
-"..##..##..",
-".##....##.",
-"..........",
-".........."};
-
-static const char * const qt_maximize_xpm[]={
-"10 10 2 1",
-"# c #000000",
-". c None",
-"#########.",
-"#########.",
-"#.......#.",
-"#.......#.",
-"#.......#.",
-"#.......#.",
-"#.......#.",
-"#.......#.",
-"#########.",
-".........."};
-
-static const char * const qt_minimize_xpm[] = {
-"10 10 2 1",
-"# c #000000",
-". c None",
-"..........",
-"..........",
-"..........",
-"..........",
-"..........",
-"..........",
-"..........",
-".#######..",
-".#######..",
-".........."};
-
-static const char * const qt_normalizeup_xpm[] = {
-"10 10 2 1",
-"# c #000000",
-". c None",
-"...######.",
-"...######.",
-"...#....#.",
-".######.#.",
-".######.#.",
-".#....###.",
-".#....#...",
-".#....#...",
-".######...",
-".........."};
-
-static const char * const qt_help_xpm[] = {
-"10 10 2 1",
-". c None",
-"# c #000000",
-"..........",
-"..######..",
-".##....##.",
-"......##..",
-".....##...",
-"....##....",
-"....##....",
-"..........",
-"....##....",
-".........."};
-
-static const char * const qt_shade_xpm[] = {
-"10 10 2 1",
-"# c #000000",
-". c None",
-"..........",
-"..........",
-"..........",
-"..........",
-"....#.....",
-"...###....",
-"..#####...",
-".#######..",
-"..........",
-".........."};
-
-static const char * const qt_unshade_xpm[] = {
-"10 10 2 1",
-"# c #000000",
-". c None",
-"..........",
-"..........",
-"..........",
-".#######..",
-"..#####...",
-"...###....",
-"....#.....",
-"..........",
-"..........",
-".........."};
-
-static const char * dock_widget_close_xpm[] = {
-"8 8 2 1",
-"# c #000000",
-". c None",
-"........",
-".##..##.",
-"..####..",
-"...##...",
-"..####..",
-".##..##.",
-"........",
-"........"};
-
-/* XPM */
-static const char * const information_xpm[]={
-"32 32 5 1",
-". c None",
-"c c #000000",
-"* c #999999",
-"a c #ffffff",
-"b c #0000ff",
-"...........********.............",
-"........***aaaaaaaa***..........",
-"......**aaaaaaaaaaaaaa**........",
-".....*aaaaaaaaaaaaaaaaaa*.......",
-"....*aaaaaaaabbbbaaaaaaaac......",
-"...*aaaaaaaabbbbbbaaaaaaaac.....",
-"..*aaaaaaaaabbbbbbaaaaaaaaac....",
-".*aaaaaaaaaaabbbbaaaaaaaaaaac...",
-".*aaaaaaaaaaaaaaaaaaaaaaaaaac*..",
-"*aaaaaaaaaaaaaaaaaaaaaaaaaaaac*.",
-"*aaaaaaaaaabbbbbbbaaaaaaaaaaac*.",
-"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
-"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
-"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
-"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
-"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
-".*aaaaaaaaaaabbbbbaaaaaaaaaac***",
-".*aaaaaaaaaaabbbbbaaaaaaaaaac***",
-"..*aaaaaaaaaabbbbbaaaaaaaaac***.",
-"...caaaaaaabbbbbbbbbaaaaaac****.",
-"....caaaaaaaaaaaaaaaaaaaac****..",
-".....caaaaaaaaaaaaaaaaaac****...",
-"......ccaaaaaaaaaaaaaacc****....",
-".......*cccaaaaaaaaccc*****.....",
-"........***cccaaaac*******......",
-"..........****caaac*****........",
-".............*caaac**...........",
-"...............caac**...........",
-"................cac**...........",
-".................cc**...........",
-"..................***...........",
-"...................**..........."};
-/* XPM */
-static const char* const warning_xpm[]={
-"32 32 4 1",
-". c None",
-"a c #ffff00",
-"* c #000000",
-"b c #999999",
-".............***................",
-"............*aaa*...............",
-"...........*aaaaa*b.............",
-"...........*aaaaa*bb............",
-"..........*aaaaaaa*bb...........",
-"..........*aaaaaaa*bb...........",
-".........*aaaaaaaaa*bb..........",
-".........*aaaaaaaaa*bb..........",
-"........*aaaaaaaaaaa*bb.........",
-"........*aaaa***aaaa*bb.........",
-".......*aaaa*****aaaa*bb........",
-".......*aaaa*****aaaa*bb........",
-"......*aaaaa*****aaaaa*bb.......",
-"......*aaaaa*****aaaaa*bb.......",
-".....*aaaaaa*****aaaaaa*bb......",
-".....*aaaaaa*****aaaaaa*bb......",
-"....*aaaaaaaa***aaaaaaaa*bb.....",
-"....*aaaaaaaa***aaaaaaaa*bb.....",
-"...*aaaaaaaaa***aaaaaaaaa*bb....",
-"...*aaaaaaaaaa*aaaaaaaaaa*bb....",
-"..*aaaaaaaaaaa*aaaaaaaaaaa*bb...",
-"..*aaaaaaaaaaaaaaaaaaaaaaa*bb...",
-".*aaaaaaaaaaaa**aaaaaaaaaaa*bb..",
-".*aaaaaaaaaaa****aaaaaaaaaa*bb..",
-"*aaaaaaaaaaaa****aaaaaaaaaaa*bb.",
-"*aaaaaaaaaaaaa**aaaaaaaaaaaa*bb.",
-"*aaaaaaaaaaaaaaaaaaaaaaaaaaa*bbb",
-"*aaaaaaaaaaaaaaaaaaaaaaaaaaa*bbb",
-".*aaaaaaaaaaaaaaaaaaaaaaaaa*bbbb",
-"..*************************bbbbb",
-"....bbbbbbbbbbbbbbbbbbbbbbbbbbb.",
-".....bbbbbbbbbbbbbbbbbbbbbbbbb.."};
-/* XPM */
-static const char* const critical_xpm[]={
-"32 32 4 1",
-". c None",
-"a c #999999",
-"* c #ff0000",
-"b c #ffffff",
-"...........********.............",
-".........************...........",
-".......****************.........",
-"......******************........",
-".....********************a......",
-"....**********************a.....",
-"...************************a....",
-"..*******b**********b*******a...",
-"..******bbb********bbb******a...",
-".******bbbbb******bbbbb******a..",
-".*******bbbbb****bbbbb*******a..",
-"*********bbbbb**bbbbb*********a.",
-"**********bbbbbbbbbb**********a.",
-"***********bbbbbbbb***********aa",
-"************bbbbbb************aa",
-"************bbbbbb************aa",
-"***********bbbbbbbb***********aa",
-"**********bbbbbbbbbb**********aa",
-"*********bbbbb**bbbbb*********aa",
-".*******bbbbb****bbbbb*******aa.",
-".******bbbbb******bbbbb******aa.",
-"..******bbb********bbb******aaa.",
-"..*******b**********b*******aa..",
-"...************************aaa..",
-"....**********************aaa...",
-"....a********************aaa....",
-".....a******************aaa.....",
-"......a****************aaa......",
-".......aa************aaaa.......",
-".........aa********aaaaa........",
-"...........aaaaaaaaaaa..........",
-".............aaaaaaa............"};
-/* XPM */
-static const char *const question_xpm[] = {
-"32 32 5 1",
-". c None",
-"c c #000000",
-"* c #999999",
-"a c #ffffff",
-"b c #0000ff",
-"...........********.............",
-"........***aaaaaaaa***..........",
-"......**aaaaaaaaaaaaaa**........",
-".....*aaaaaaaaaaaaaaaaaa*.......",
-"....*aaaaaaaaaaaaaaaaaaaac......",
-"...*aaaaaaaabbbbbbaaaaaaaac.....",
-"..*aaaaaaaabaaabbbbaaaaaaaac....",
-".*aaaaaaaabbaaaabbbbaaaaaaaac...",
-".*aaaaaaaabbbbaabbbbaaaaaaaac*..",
-"*aaaaaaaaabbbbaabbbbaaaaaaaaac*.",
-"*aaaaaaaaaabbaabbbbaaaaaaaaaac*.",
-"*aaaaaaaaaaaaabbbbaaaaaaaaaaac**",
-"*aaaaaaaaaaaaabbbaaaaaaaaaaaac**",
-"*aaaaaaaaaaaaabbaaaaaaaaaaaaac**",
-"*aaaaaaaaaaaaabbaaaaaaaaaaaaac**",
-"*aaaaaaaaaaaaaaaaaaaaaaaaaaaac**",
-".*aaaaaaaaaaaabbaaaaaaaaaaaac***",
-".*aaaaaaaaaaabbbbaaaaaaaaaaac***",
-"..*aaaaaaaaaabbbbaaaaaaaaaac***.",
-"...caaaaaaaaaabbaaaaaaaaaac****.",
-"....caaaaaaaaaaaaaaaaaaaac****..",
-".....caaaaaaaaaaaaaaaaaac****...",
-"......ccaaaaaaaaaaaaaacc****....",
-".......*cccaaaaaaaaccc*****.....",
-"........***cccaaaac*******......",
-"..........****caaac*****........",
-".............*caaac**...........",
-"...............caac**...........",
-"................cac**...........",
-".................cc**...........",
-"..................***...........",
-"...................**..........."};
-
-#endif //QT_NO_IMAGEFORMAT_XPM
-
-#ifdef Q_OS_WIN
-static QPixmap loadIconFromShell32( int resourceId, int size )
-{
-#ifdef Q_OS_WINCE
- HMODULE hmod = LoadLibrary(L"ceshell");
-#else
- HMODULE hmod = QSystemLibrary::load(L"shell32");
-#endif
- if( hmod ) {
- HICON iconHandle = (HICON)LoadImage(hmod, MAKEINTRESOURCE(resourceId), IMAGE_ICON, size, size, 0);
- if( iconHandle ) {
- QPixmap iconpixmap = QPixmap::fromWinHICON( iconHandle );
- DestroyIcon(iconHandle);
- return iconpixmap;
- }
- }
- return QPixmap();
-}
-#endif
-
-/*!
- \reimp
- */
-QPixmap QWindowsStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt,
- const QWidget *widget) const
-{
-#if defined(Q_WS_WIN) && !defined(Q_OS_WINCE)
- QPixmap desktopIcon;
- switch(standardPixmap) {
- case SP_DriveCDIcon:
- case SP_DriveDVDIcon:
- {
- desktopIcon = loadIconFromShell32(12, 16);
- break;
- }
- case SP_DriveNetIcon:
- {
- desktopIcon = loadIconFromShell32(10, 16);
- break;
- }
- case SP_DriveHDIcon:
- {
- desktopIcon = loadIconFromShell32(9, 16);
- break;
- }
- case SP_DriveFDIcon:
- {
- desktopIcon = loadIconFromShell32(7, 16);
- break;
- }
- case SP_FileIcon:
- {
- desktopIcon = loadIconFromShell32(1, 16);
- break;
- }
- case SP_FileLinkIcon:
- {
- desktopIcon = loadIconFromShell32(1, 16);
- QPainter painter(&desktopIcon);
- QPixmap link = loadIconFromShell32(30, 16);
- painter.drawPixmap(0, 0, 16, 16, link);
- break;
- }
- case SP_DirLinkIcon:
- {
- desktopIcon = loadIconFromShell32(4, 16);
- QPainter painter(&desktopIcon);
- QPixmap link = loadIconFromShell32(30, 16);
- painter.drawPixmap(0, 0, 16, 16, link);
- break;
- }
- case SP_DirClosedIcon:
- {
- desktopIcon = loadIconFromShell32(4, 16);
- break;
- }
- case SP_DesktopIcon:
- {
- desktopIcon = loadIconFromShell32(35, 16);
- break;
- }
- case SP_ComputerIcon:
- {
- desktopIcon = loadIconFromShell32(16, 16);
- break;
- }
- case SP_DirOpenIcon:
- {
- desktopIcon = loadIconFromShell32(5, 16);
- break;
- }
- case SP_FileDialogNewFolder:
- {
- desktopIcon = loadIconFromShell32(319, 16);
- break;
- }
- case SP_DirHomeIcon:
- {
- desktopIcon = loadIconFromShell32(235, 16);
- break;
- }
- case SP_TrashIcon:
- {
- desktopIcon = loadIconFromShell32(191, 16);
- break;
- }
- case SP_MessageBoxInformation:
- {
- HICON iconHandle = LoadIcon(NULL, IDI_INFORMATION);
- desktopIcon = QPixmap::fromWinHICON( iconHandle );
- DestroyIcon(iconHandle);
- break;
- }
- case SP_MessageBoxWarning:
- {
- HICON iconHandle = LoadIcon(NULL, IDI_WARNING);
- desktopIcon = QPixmap::fromWinHICON( iconHandle );
- DestroyIcon(iconHandle);
- break;
- }
- case SP_MessageBoxCritical:
- {
- HICON iconHandle = LoadIcon(NULL, IDI_ERROR);
- desktopIcon = QPixmap::fromWinHICON( iconHandle );
- DestroyIcon(iconHandle);
- break;
- }
- case SP_MessageBoxQuestion:
- {
- HICON iconHandle = LoadIcon(NULL, IDI_QUESTION);
- desktopIcon = QPixmap::fromWinHICON( iconHandle );
- DestroyIcon(iconHandle);
- break;
- }
- case SP_VistaShield:
- {
- if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA
- && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based
- && pSHGetStockIconInfo)
- {
- QPixmap pixmap;
- QSHSTOCKICONINFO iconInfo;
- memset(&iconInfo, 0, sizeof(iconInfo));
- iconInfo.cbSize = sizeof(iconInfo);
- if (pSHGetStockIconInfo(_SIID_SHIELD, _SHGFI_ICON | _SHGFI_SMALLICON, &iconInfo) == S_OK) {
- pixmap = QPixmap::fromWinHICON(iconInfo.hIcon);
- DestroyIcon(iconInfo.hIcon);
- return pixmap;
- }
- }
- }
- break;
- default:
- break;
- }
- if (!desktopIcon.isNull()) {
- return desktopIcon;
- }
-#endif
-#ifndef QT_NO_IMAGEFORMAT_XPM
- switch (standardPixmap) {
- case SP_TitleBarMenuButton:
- return QPixmap(qt_menu_xpm);
- case SP_TitleBarShadeButton:
- return QPixmap(qt_shade_xpm);
- case SP_TitleBarUnshadeButton:
- return QPixmap(qt_unshade_xpm);
- case SP_TitleBarNormalButton:
- return QPixmap(qt_normalizeup_xpm);
- case SP_TitleBarMinButton:
- return QPixmap(qt_minimize_xpm);
- case SP_TitleBarMaxButton:
- return QPixmap(qt_maximize_xpm);
- case SP_TitleBarCloseButton:
- return QPixmap(qt_close_xpm);
- case SP_TitleBarContextHelpButton:
- return QPixmap(qt_help_xpm);
- case SP_DockWidgetCloseButton:
- return QPixmap(dock_widget_close_xpm);
- case SP_MessageBoxInformation:
- return QPixmap(information_xpm);
- case SP_MessageBoxWarning:
- return QPixmap(warning_xpm);
- case SP_MessageBoxCritical:
- return QPixmap(critical_xpm);
- case SP_MessageBoxQuestion:
- return QPixmap(question_xpm);
- default:
- break;
- }
-#endif //QT_NO_IMAGEFORMAT_XPM
- return QCommonStyle::standardPixmap(standardPixmap, opt, widget);
-}
-
-/*! \reimp */
-int QWindowsStyle::styleHint(StyleHint hint, const QStyleOption *opt, const QWidget *widget,
- QStyleHintReturn *returnData) const
-{
- int ret = 0;
-
- switch (hint) {
- case SH_EtchDisabledText:
- case SH_Slider_SnapToValue:
- case SH_PrintDialog_RightAlignButtons:
- case SH_FontDialog_SelectAssociatedText:
- case SH_Menu_AllowActiveAndDisabled:
- case SH_MenuBar_AltKeyNavigation:
- case SH_MenuBar_MouseTracking:
- case SH_Menu_MouseTracking:
- case SH_ComboBox_ListMouseTracking:
- case SH_ScrollBar_StopMouseOverSlider:
- case SH_MainWindow_SpaceBelowMenuBar:
- ret = 1;
-
- break;
- case SH_ItemView_ShowDecorationSelected:
-#ifndef QT_NO_LISTVIEW
- if (qobject_cast<const QListView*>(widget))
- ret = 1;
-#endif
- break;
- case SH_ItemView_ChangeHighlightOnFocus:
- ret = 1;
- break;
- case SH_ToolBox_SelectedPageTitleBold:
- ret = 0;
- break;
-
-#if defined(Q_WS_WIN)
- case SH_UnderlineShortcut:
- {
- ret = 1;
- BOOL cues = false;
- SystemParametersInfo(SPI_GETKEYBOARDCUES, 0, &cues, 0);
- ret = int(cues);
- // Do nothing if we always paint underlines
- Q_D(const QWindowsStyle);
- if (!ret && widget && d) {
-#ifndef QT_NO_MENUBAR
- const QMenuBar *menuBar = qobject_cast<const QMenuBar *>(widget);
- if (!menuBar && qobject_cast<const QMenu *>(widget)) {
- QWidget *w = QApplication::activeWindow();
- if (w && w != widget)
- menuBar = w->findChild<QMenuBar *>();
- }
- // If we paint a menu bar draw underlines if is in the keyboardState
- if (menuBar) {
- if (menuBar->d_func()->keyboardState || d->altDown())
- ret = 1;
- // Otherwise draw underlines if the toplevel widget has seen an alt-press
- } else
-#endif // QT_NO_MENUBAR
- if (d->hasSeenAlt(widget)) {
- ret = 1;
- }
- }
- break;
- }
-#endif
-#ifndef QT_NO_RUBBERBAND
- case SH_RubberBand_Mask:
- if (const QStyleOptionRubberBand *rbOpt = qstyleoption_cast<const QStyleOptionRubberBand *>(opt)) {
- ret = 0;
- if (rbOpt->shape == QRubberBand::Rectangle) {
- ret = true;
- if(QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask*>(returnData)) {
- mask->region = opt->rect;
- int size = 1;
- if (widget && widget->isWindow())
- size = 4;
- mask->region -= opt->rect.adjusted(size, size, -size, -size);
- }
- }
- }
- break;
-#endif // QT_NO_RUBBERBAND
- case SH_LineEdit_PasswordCharacter:
- {
-#ifdef Q_WS_WIN
- if (widget && (QSysInfo::WindowsVersion >= QSysInfo::WV_XP && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)) {
- const QFontMetrics &fm = widget->fontMetrics();
- if (fm.inFont(QChar(0x25CF)))
- ret = 0x25CF;
- else if (fm.inFont(QChar(0x2022)))
- ret = 0x2022;
- }
-#endif
- if (!ret)
- ret = '*';
- }
- break;
-#ifndef QT_NO_WIZARD
- case SH_WizardStyle:
- ret = QWizard::ModernStyle;
- break;
-#endif
- case SH_ItemView_ArrowKeysNavigateIntoChildren:
- ret = true;
- break;
- case SH_DialogButtonBox_ButtonsHaveIcons:
- ret = 0;
- break;
- default:
- ret = QCommonStyle::styleHint(hint, opt, widget, returnData);
- break;
- }
- return ret;
-}
-
-/*! \reimp */
-void QWindowsStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p,
- const QWidget *w) const
-{
- // Used to restore across fallthrough cases. Currently only used in PE_IndicatorCheckBox
- bool doRestore = false;
-
- switch (pe) {
-#ifndef QT_NO_TOOLBAR
- case PE_IndicatorToolBarSeparator:
- {
- QRect rect = opt->rect;
- const int margin = 2;
- QPen oldPen = p->pen();
- if(opt->state & State_Horizontal){
- const int offset = rect.width()/2;
- p->setPen(QPen(opt->palette.dark().color()));
- p->drawLine(rect.bottomLeft().x() + offset,
- rect.bottomLeft().y() - margin,
- rect.topLeft().x() + offset,
- rect.topLeft().y() + margin);
- p->setPen(QPen(opt->palette.light().color()));
- p->drawLine(rect.bottomLeft().x() + offset + 1,
- rect.bottomLeft().y() - margin,
- rect.topLeft().x() + offset + 1,
- rect.topLeft().y() + margin);
- }
- else{ //Draw vertical separator
- const int offset = rect.height()/2;
- p->setPen(QPen(opt->palette.dark().color()));
- p->drawLine(rect.topLeft().x() + margin ,
- rect.topLeft().y() + offset,
- rect.topRight().x() - margin,
- rect.topRight().y() + offset);
- p->setPen(QPen(opt->palette.light().color()));
- p->drawLine(rect.topLeft().x() + margin ,
- rect.topLeft().y() + offset + 1,
- rect.topRight().x() - margin,
- rect.topRight().y() + offset + 1);
- }
- p->setPen(oldPen);
- }
- break;
- case PE_IndicatorToolBarHandle:
- p->save();
- p->translate(opt->rect.x(), opt->rect.y());
- if (opt->state & State_Horizontal) {
- int x = opt->rect.width() / 2 - 4;
- if (opt->direction == Qt::RightToLeft)
- x -= 2;
- if (opt->rect.height() > 4) {
- qDrawShadePanel(p, x, 2, 3, opt->rect.height() - 4,
- opt->palette, false, 1, 0);
- qDrawShadePanel(p, x + 3, 2, 3, opt->rect.height() - 4,
- opt->palette, false, 1, 0);
- }
- } else {
- if (opt->rect.width() > 4) {
- int y = opt->rect.height() / 2 - 4;
- qDrawShadePanel(p, 2, y, opt->rect.width() - 4, 3,
- opt->palette, false, 1, 0);
- qDrawShadePanel(p, 2, y + 3, opt->rect.width() - 4, 3,
- opt->palette, false, 1, 0);
- }
- }
- p->restore();
- break;
-
-#endif // QT_NO_TOOLBAR
- case PE_FrameButtonTool:
- case PE_PanelButtonTool: {
- QPen oldPen = p->pen();
-#ifndef QT_NO_DOCKWIDGET
- if (w && w->inherits("QDockWidgetTitleButton")) {
- if (const QWidget *dw = w->parentWidget())
- if (dw->isWindow()){
- qDrawWinButton(p, opt->rect.adjusted(1, 1, 0, 0), opt->palette, opt->state & (State_Sunken | State_On),
- &opt->palette.button());
-
- return;
- }
- }
-#endif // QT_NO_DOCKWIDGET
- QBrush fill;
- bool stippled;
- bool panel = (pe == PE_PanelButtonTool);
- if ((!(opt->state & State_Sunken ))
- && (!(opt->state & State_Enabled)
- || !(opt->state & State_MouseOver && opt->state & State_AutoRaise))
- && (opt->state & State_On)) {
- fill = QBrush(opt->palette.light().color(), Qt::Dense4Pattern);
- stippled = true;
- } else {
- fill = opt->palette.brush(QPalette::Button);
- stippled = false;
- }
-
- if (opt->state & (State_Raised | State_Sunken | State_On)) {
- if (opt->state & State_AutoRaise) {
- if(opt->state & (State_Enabled | State_Sunken | State_On)){
- if (panel)
- qDrawShadePanel(p, opt->rect, opt->palette,
- opt->state & (State_Sunken | State_On), 1, &fill);
- else
- qDrawShadeRect(p, opt->rect, opt->palette,
- opt->state & (State_Sunken | State_On), 1);
- }
- if (stippled) {
- p->setPen(opt->palette.button().color());
- p->drawRect(opt->rect.adjusted(1,1,-2,-2));
- }
- } else {
- qDrawWinButton(p, opt->rect, opt->palette,
- opt->state & (State_Sunken | State_On), panel ? &fill : 0);
- }
- } else {
- p->fillRect(opt->rect, fill);
- }
- p->setPen(oldPen);
- break; }
- case PE_PanelButtonCommand:
- if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
- QBrush fill;
- State flags = opt->state;
- QPalette pal = opt->palette;
- QRect r = opt->rect;
- if (! (flags & State_Sunken) && (flags & State_On))
- fill = QBrush(pal.light().color(), Qt::Dense4Pattern);
- else
- fill = pal.brush(QPalette::Button);
-
- if (btn->features & QStyleOptionButton::DefaultButton && flags & State_Sunken) {
- p->setPen(pal.dark().color());
- p->setBrush(fill);
- p->drawRect(r.adjusted(0, 0, -1, -1));
- } else if (flags & (State_Raised | State_Sunken | State_On | State_Sunken)) {
- qDrawWinButton(p, r, pal, flags & (State_Sunken | State_On),
- &fill);
- } else {
- p->fillRect(r, fill);
- }
- }
- break;
- case PE_FrameDefaultButton: {
- QPen oldPen = p->pen();
- p->setPen(opt->palette.shadow().color());
- QRect rect = opt->rect;
- rect.adjust(0, 0, -1, -1);
- p->drawRect(rect);
- p->setPen(oldPen);
- break;
- }
- case PE_IndicatorArrowUp:
- case PE_IndicatorArrowDown:
- case PE_IndicatorArrowRight:
- case PE_IndicatorArrowLeft:
- {
- if (opt->rect.width() <= 1 || opt->rect.height() <= 1)
- break;
- QRect r = opt->rect;
- int size = qMin(r.height(), r.width());
- QPixmap pixmap;
- QString pixmapName = QStyleHelper::uniqueName(QLatin1String("$qt_ia-")
- % QLatin1String(metaObject()->className()), opt, QSize(size, size))
- % HexString<uint>(pe);
- if (!QPixmapCache::find(pixmapName, pixmap)) {
- int border = size/5;
- int sqsize = 2*(size/2);
- QImage image(sqsize, sqsize, QImage::Format_ARGB32_Premultiplied);
- image.fill(0);
- QPainter imagePainter(&image);
-
- QPolygon a;
- switch (pe) {
- case PE_IndicatorArrowUp:
- a.setPoints(3, border, sqsize/2, sqsize/2, border, sqsize - border, sqsize/2);
- break;
- case PE_IndicatorArrowDown:
- a.setPoints(3, border, sqsize/2, sqsize/2, sqsize - border, sqsize - border, sqsize/2);
- break;
- case PE_IndicatorArrowRight:
- a.setPoints(3, sqsize - border, sqsize/2, sqsize/2, border, sqsize/2, sqsize - border);
- break;
- case PE_IndicatorArrowLeft:
- a.setPoints(3, border, sqsize/2, sqsize/2, border, sqsize/2, sqsize - border);
- break;
- default:
- break;
- }
-
- int bsx = 0;
- int bsy = 0;
-
- if (opt->state & State_Sunken) {
- bsx = proxy()->pixelMetric(PM_ButtonShiftHorizontal, opt, w);
- bsy = proxy()->pixelMetric(PM_ButtonShiftVertical, opt, w);
- }
-
- QRect bounds = a.boundingRect();
- int sx = sqsize / 2 - bounds.center().x() - 1;
- int sy = sqsize / 2 - bounds.center().y() - 1;
- imagePainter.translate(sx + bsx, sy + bsy);
- imagePainter.setPen(opt->palette.buttonText().color());
- imagePainter.setBrush(opt->palette.buttonText());
-
- if (!(opt->state & State_Enabled)) {
- imagePainter.translate(1, 1);
- imagePainter.setBrush(opt->palette.light().color());
- imagePainter.setPen(opt->palette.light().color());
- imagePainter.drawPolygon(a);
- imagePainter.translate(-1, -1);
- imagePainter.setBrush(opt->palette.mid().color());
- imagePainter.setPen(opt->palette.mid().color());
- }
-
- imagePainter.drawPolygon(a);
- imagePainter.end();
- pixmap = QPixmap::fromImage(image);
- QPixmapCache::insert(pixmapName, pixmap);
- }
- int xOffset = r.x() + (r.width() - size)/2;
- int yOffset = r.y() + (r.height() - size)/2;
- p->drawPixmap(xOffset, yOffset, pixmap);
- }
- break;
- case PE_IndicatorCheckBox: {
- QBrush fill;
- if (opt->state & State_NoChange)
- fill = QBrush(opt->palette.base().color(), Qt::Dense4Pattern);
- else if (opt->state & State_Sunken)
- fill = opt->palette.button();
- else if (opt->state & State_Enabled)
- fill = opt->palette.base();
- else
- fill = opt->palette.background();
- p->save();
- doRestore = true;
- qDrawWinPanel(p, opt->rect, opt->palette, true, &fill);
- if (opt->state & State_NoChange)
- p->setPen(opt->palette.dark().color());
- else
- p->setPen(opt->palette.text().color());
- } // Fall through!
- case PE_IndicatorViewItemCheck:
- case PE_Q3CheckListIndicator:
- if (!doRestore) {
- p->save();
- doRestore = true;
- }
- if (pe == PE_Q3CheckListIndicator || pe == PE_IndicatorViewItemCheck) {
- const QStyleOptionViewItem *itemViewOpt = qstyleoption_cast<const QStyleOptionViewItem *>(opt);
- p->setPen(itemViewOpt
- && itemViewOpt->showDecorationSelected
- && opt->state & State_Selected
- ? opt->palette.highlightedText().color()
- : opt->palette.text().color());
- if (opt->state & State_NoChange)
- p->setBrush(opt->palette.brush(QPalette::Button));
- p->drawRect(opt->rect.x() + 1, opt->rect.y() + 1, 11, 11);
- }
- if (!(opt->state & State_Off)) {
- QLineF lines[7];
- int i, xx, yy;
- xx = opt->rect.x() + 3;
- yy = opt->rect.y() + 5;
- for (i = 0; i < 3; ++i) {
- lines[i] = QLineF(xx, yy, xx, yy + 2);
- ++xx;
- ++yy;
- }
- yy -= 2;
- for (i = 3; i < 7; ++i) {
- lines[i] = QLineF(xx, yy, xx, yy + 2);
- ++xx;
- --yy;
- }
- p->drawLines(lines, 7);
- }
- if (doRestore)
- p->restore();
- break;
- case PE_FrameFocusRect:
- if (const QStyleOptionFocusRect *fropt = qstyleoption_cast<const QStyleOptionFocusRect *>(opt)) {
- //### check for d->alt_down
- if (!(fropt->state & State_KeyboardFocusChange) && !proxy()->styleHint(SH_UnderlineShortcut, opt))
- return;
- QRect r = opt->rect;
- p->save();
- p->setBackgroundMode(Qt::TransparentMode);
- QColor bg_col = fropt->backgroundColor;
- if (!bg_col.isValid())
- bg_col = p->background().color();
- // Create an "XOR" color.
- QColor patternCol((bg_col.red() ^ 0xff) & 0xff,
- (bg_col.green() ^ 0xff) & 0xff,
- (bg_col.blue() ^ 0xff) & 0xff);
- p->setBrush(QBrush(patternCol, Qt::Dense4Pattern));
- p->setBrushOrigin(r.topLeft());
- p->setPen(Qt::NoPen);
- p->drawRect(r.left(), r.top(), r.width(), 1); // Top
- p->drawRect(r.left(), r.bottom(), r.width(), 1); // Bottom
- p->drawRect(r.left(), r.top(), 1, r.height()); // Left
- p->drawRect(r.right(), r.top(), 1, r.height()); // Right
- p->restore();
- }
- break;
- case PE_IndicatorRadioButton:
- {
-#define PTSARRLEN(x) sizeof(x)/(sizeof(QPoint))
- static const QPoint pts1[] = { // dark lines
- QPoint(1, 9), QPoint(1, 8), QPoint(0, 7), QPoint(0, 4), QPoint(1, 3), QPoint(1, 2),
- QPoint(2, 1), QPoint(3, 1), QPoint(4, 0), QPoint(7, 0), QPoint(8, 1), QPoint(9, 1)
- };
- static const QPoint pts2[] = { // black lines
- QPoint(2, 8), QPoint(1, 7), QPoint(1, 4), QPoint(2, 3), QPoint(2, 2), QPoint(3, 2),
- QPoint(4, 1), QPoint(7, 1), QPoint(8, 2), QPoint(9, 2)
- };
- static const QPoint pts3[] = { // background lines
- QPoint(2, 9), QPoint(3, 9), QPoint(4, 10), QPoint(7, 10), QPoint(8, 9), QPoint(9, 9),
- QPoint(9, 8), QPoint(10, 7), QPoint(10, 4), QPoint(9, 3)
- };
- static const QPoint pts4[] = { // white lines
- QPoint(2, 10), QPoint(3, 10), QPoint(4, 11), QPoint(7, 11), QPoint(8, 10),
- QPoint(9, 10), QPoint(10, 9), QPoint(10, 8), QPoint(11, 7), QPoint(11, 4),
- QPoint(10, 3), QPoint(10, 2)
- };
- static const QPoint pts5[] = { // inner fill
- QPoint(4, 2), QPoint(7, 2), QPoint(9, 4), QPoint(9, 7), QPoint(7, 9), QPoint(4, 9),
- QPoint(2, 7), QPoint(2, 4)
- };
-
- // make sure the indicator is square
- QRect ir = opt->rect;
-
- if (opt->rect.width() < opt->rect.height()) {
- ir.setTop(opt->rect.top() + (opt->rect.height() - opt->rect.width()) / 2);
- ir.setHeight(opt->rect.width());
- } else if (opt->rect.height() < opt->rect.width()) {
- ir.setLeft(opt->rect.left() + (opt->rect.width() - opt->rect.height()) / 2);
- ir.setWidth(opt->rect.height());
- }
-
- p->save();
- bool down = opt->state & State_Sunken;
- bool enabled = opt->state & State_Enabled;
- bool on = opt->state & State_On;
- QPolygon a;
-
- //center when rect is larger than indicator size
- int xOffset = 0;
- int yOffset = 0;
- int indicatorWidth = proxy()->pixelMetric(PM_ExclusiveIndicatorWidth);
- int indicatorHeight = proxy()->pixelMetric(PM_ExclusiveIndicatorWidth);
- if (ir.width() > indicatorWidth)
- xOffset += (ir.width() - indicatorWidth)/2;
- if (ir.height() > indicatorHeight)
- yOffset += (ir.height() - indicatorHeight)/2;
- p->translate(xOffset, yOffset);
-
- p->translate(ir.x(), ir.y());
-
- p->setPen(opt->palette.dark().color());
- p->drawPolyline(pts1, PTSARRLEN(pts1));
-
- p->setPen(opt->palette.shadow().color());
- p->drawPolyline(pts2, PTSARRLEN(pts2));
-
- p->setPen(opt->palette.midlight().color());
- p->drawPolyline(pts3, PTSARRLEN(pts3));
-
- p->setPen(opt->palette.light().color());
- p->drawPolyline(pts4, PTSARRLEN(pts4));
-
- QColor fillColor = (down || !enabled)
- ? opt->palette.button().color()
- : opt->palette.base().color();
- p->setPen(fillColor);
- p->setBrush(fillColor) ;
- p->drawPolygon(pts5, PTSARRLEN(pts5));
-
- p->translate(-ir.x(), -ir.y()); // restore translate
-
- if (on) {
- p->setPen(Qt::NoPen);
- p->setBrush(opt->palette.text());
- p->drawRect(ir.x() + 5, ir.y() + 4, 2, 4);
- p->drawRect(ir.x() + 4, ir.y() + 5, 4, 2);
- }
- p->restore();
- break;
- }
-#ifndef QT_NO_FRAME
- case PE_Frame:
- case PE_FrameMenu:
- if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
- if (frame->lineWidth == 2 || pe == PE_Frame) {
- QPalette popupPal = frame->palette;
- if (pe == PE_FrameMenu) {
- popupPal.setColor(QPalette::Light, frame->palette.background().color());
- popupPal.setColor(QPalette::Midlight, frame->palette.light().color());
- }
- if (pe == PE_Frame && (frame->state & State_Raised))
- qDrawWinButton(p, frame->rect, popupPal, frame->state & State_Sunken);
- else if (pe == PE_Frame && (frame->state & State_Sunken))
- {
- popupPal.setColor(QPalette::Midlight, frame->palette.background().color());
- qDrawWinPanel(p, frame->rect, popupPal, frame->state & State_Sunken);
- }
- else
- qDrawWinPanel(p, frame->rect, popupPal, frame->state & State_Sunken);
- } else {
- QCommonStyle::drawPrimitive(pe, opt, p, w);
- }
- } else {
- QPalette popupPal = opt->palette;
- popupPal.setColor(QPalette::Light, opt->palette.background().color());
- popupPal.setColor(QPalette::Midlight, opt->palette.light().color());
- qDrawWinPanel(p, opt->rect, popupPal, opt->state & State_Sunken);
- }
- break;
-#endif // QT_NO_FRAME
- case PE_IndicatorBranch: {
- // This is _way_ too similar to the common style.
- static const int decoration_size = 9;
- int mid_h = opt->rect.x() + opt->rect.width() / 2;
- int mid_v = opt->rect.y() + opt->rect.height() / 2;
- int bef_h = mid_h;
- int bef_v = mid_v;
- int aft_h = mid_h;
- int aft_v = mid_v;
- if (opt->state & State_Children) {
- int delta = decoration_size / 2;
- bef_h -= delta;
- bef_v -= delta;
- aft_h += delta;
- aft_v += delta;
- p->drawLine(bef_h + 2, bef_v + 4, bef_h + 6, bef_v + 4);
- if (!(opt->state & State_Open))
- p->drawLine(bef_h + 4, bef_v + 2, bef_h + 4, bef_v + 6);
- QPen oldPen = p->pen();
- p->setPen(opt->palette.dark().color());
- p->drawRect(bef_h, bef_v, decoration_size - 1, decoration_size - 1);
- p->setPen(oldPen);
- }
- QBrush brush(opt->palette.dark().color(), Qt::Dense4Pattern);
- if (opt->state & State_Item) {
- if (opt->direction == Qt::RightToLeft)
- p->fillRect(opt->rect.left(), mid_v, bef_h - opt->rect.left(), 1, brush);
- else
- p->fillRect(aft_h, mid_v, opt->rect.right() - aft_h + 1, 1, brush);
- }
- if (opt->state & State_Sibling)
- p->fillRect(mid_h, aft_v, 1, opt->rect.bottom() - aft_v + 1, brush);
- if (opt->state & (State_Open | State_Children | State_Item | State_Sibling))
- p->fillRect(mid_h, opt->rect.y(), 1, bef_v - opt->rect.y(), brush);
- break; }
- case PE_FrameButtonBevel:
- case PE_PanelButtonBevel: {
- QBrush fill;
- bool panel = pe != PE_FrameButtonBevel;
- p->setBrushOrigin(opt->rect.topLeft());
- if (!(opt->state & State_Sunken) && (opt->state & State_On))
- fill = QBrush(opt->palette.light().color(), Qt::Dense4Pattern);
- else
- fill = opt->palette.brush(QPalette::Button);
-
- if (opt->state & (State_Raised | State_On | State_Sunken)) {
- qDrawWinButton(p, opt->rect, opt->palette, opt->state & (State_Sunken | State_On),
- panel ? &fill : 0);
- } else {
- if (panel)
- p->fillRect(opt->rect, fill);
- else
- p->drawRect(opt->rect);
- }
- break; }
- case PE_FrameWindow: {
- QPalette popupPal = opt->palette;
- popupPal.setColor(QPalette::Light, opt->palette.background().color());
- popupPal.setColor(QPalette::Midlight, opt->palette.light().color());
- qDrawWinPanel(p, opt->rect, popupPal, opt->state & State_Sunken);
- break; }
-#ifndef QT_NO_DOCKWIDGET
- case PE_IndicatorDockWidgetResizeHandle: {
- QPen oldPen = p->pen();
- p->setPen(opt->palette.light().color());
- if (opt->state & State_Horizontal) {
- p->drawLine(opt->rect.left(), opt->rect.top(),
- opt->rect.right(), opt->rect.top());
- p->setPen(opt->palette.dark().color());
- p->drawLine(opt->rect.left(), opt->rect.bottom() - 1,
- opt->rect.right(), opt->rect.bottom() - 1);
- p->setPen(opt->palette.shadow().color());
- p->drawLine(opt->rect.left(), opt->rect.bottom(),
- opt->rect.right(), opt->rect.bottom());
- } else {
- p->drawLine(opt->rect.left(), opt->rect.top(),
- opt->rect.left(), opt->rect.bottom());
- p->setPen(opt->palette.dark().color());
- p->drawLine(opt->rect.right() - 1, opt->rect.top(),
- opt->rect.right() - 1, opt->rect.bottom());
- p->setPen(opt->palette.shadow().color());
- p->drawLine(opt->rect.right(), opt->rect.top(),
- opt->rect.right(), opt->rect.bottom());
- }
- p->setPen(oldPen);
- break; }
-case PE_FrameDockWidget:
- if (qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
- proxy()->drawPrimitive(QStyle::PE_FrameWindow, opt, p, w);
- }
- break;
-#endif // QT_NO_DOCKWIDGET
-
- case PE_FrameStatusBarItem:
- qDrawShadePanel(p, opt->rect, opt->palette, true, 1, 0);
- break;
-
-#ifndef QT_NO_PROGRESSBAR
- case PE_IndicatorProgressChunk:
- {
- bool vertical = false, inverted = false;
- if (const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(opt)) {
- vertical = (pb2->orientation == Qt::Vertical);
- inverted = pb2->invertedAppearance;
- }
-
- int space = 2;
- int chunksize = proxy()->pixelMetric(PM_ProgressBarChunkWidth, opt, w) - space;
- if (!vertical) {
- if (opt->rect.width() <= chunksize)
- space = 0;
-
- if (inverted)
- p->fillRect(opt->rect.x() + space, opt->rect.y(), opt->rect.width() - space, opt->rect.height(),
- opt->palette.brush(QPalette::Highlight));
- else
- p->fillRect(opt->rect.x(), opt->rect.y(), opt->rect.width() - space, opt->rect.height(),
- opt->palette.brush(QPalette::Highlight));
- } else {
- if (opt->rect.height() <= chunksize)
- space = 0;
-
- if (inverted)
- p->fillRect(opt->rect.x(), opt->rect.y(), opt->rect.width(), opt->rect.height() - space,
- opt->palette.brush(QPalette::Highlight));
- else
- p->fillRect(opt->rect.x(), opt->rect.y() + space, opt->rect.width(), opt->rect.height() - space,
- opt->palette.brush(QPalette::Highlight));
- }
- }
- break;
-#endif // QT_NO_PROGRESSBAR
-
- case PE_FrameTabWidget: {
- qDrawWinButton(p, opt->rect, opt->palette, false, 0);
- break;
- }
- default:
- QCommonStyle::drawPrimitive(pe, opt, p, w);
- }
-}
-
-/*! \reimp */
-void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter *p,
- const QWidget *widget) const
-{
- switch (ce) {
-#ifndef QT_NO_RUBBERBAND
- case CE_RubberBand:
- if (qstyleoption_cast<const QStyleOptionRubberBand *>(opt)) {
- // ### workaround for slow general painter path
- QPixmap tiledPixmap(16, 16);
- QPainter pixmapPainter(&tiledPixmap);
- pixmapPainter.setPen(Qt::NoPen);
- pixmapPainter.setBrush(Qt::Dense4Pattern);
- pixmapPainter.setBackground(Qt::white);
- pixmapPainter.setBackgroundMode(Qt::OpaqueMode);
- pixmapPainter.drawRect(0, 0, tiledPixmap.width(), tiledPixmap.height());
- pixmapPainter.end();
- tiledPixmap = QPixmap::fromImage(tiledPixmap.toImage());
- p->save();
- QRect r = opt->rect;
- QStyleHintReturnMask mask;
- if (proxy()->styleHint(QStyle::SH_RubberBand_Mask, opt, widget, &mask))
- p->setClipRegion(mask.region);
- p->drawTiledPixmap(r.x(), r.y(), r.width(), r.height(), tiledPixmap);
- p->restore();
- return;
- }
- break;
-#endif // QT_NO_RUBBERBAND
-
-#if !defined(QT_NO_MENU) && !defined(QT_NO_MAINWINDOW)
- case CE_MenuBarEmptyArea:
- if (widget && qobject_cast<const QMainWindow *>(widget->parentWidget())) {
- p->fillRect(opt->rect, opt->palette.button());
- QPen oldPen = p->pen();
- p->setPen(QPen(opt->palette.dark().color()));
- p->drawLine(opt->rect.bottomLeft(), opt->rect.bottomRight());
- p->setPen(oldPen);
- }
- break;
-#endif
-#ifndef QT_NO_MENU
- case CE_MenuItem:
- if (const QStyleOptionMenuItem *menuitem = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
- int x, y, w, h;
- menuitem->rect.getRect(&x, &y, &w, &h);
- int tab = menuitem->tabWidth;
- bool dis = !(menuitem->state & State_Enabled);
- bool checked = menuitem->checkType != QStyleOptionMenuItem::NotCheckable
- ? menuitem->checked : false;
- bool act = menuitem->state & State_Selected;
-
- // windows always has a check column, regardless whether we have an icon or not
- int checkcol = qMax<int>(menuitem->maxIconWidth, QWindowsStylePrivate::windowsCheckMarkWidth);
-
- QBrush fill = menuitem->palette.brush(act ? QPalette::Highlight : QPalette::Button);
- p->fillRect(menuitem->rect.adjusted(0, 0, -1, 0), fill);
-
- if (menuitem->menuItemType == QStyleOptionMenuItem::Separator){
- int yoff = y-1 + h / 2;
- p->setPen(menuitem->palette.dark().color());
- p->drawLine(x + 2, yoff, x + w - 4, yoff);
- p->setPen(menuitem->palette.light().color());
- p->drawLine(x + 2, yoff + 1, x + w - 4, yoff + 1);
- return;
- }
-
- QRect vCheckRect = visualRect(opt->direction, menuitem->rect, QRect(menuitem->rect.x(), menuitem->rect.y(), checkcol, menuitem->rect.height()));
- if (!menuitem->icon.isNull() && checked) {
- if (act) {
- qDrawShadePanel(p, vCheckRect,
- menuitem->palette, true, 1,
- &menuitem->palette.brush(QPalette::Button));
- } else {
- QBrush fill(menuitem->palette.light().color(), Qt::Dense4Pattern);
- qDrawShadePanel(p, vCheckRect, menuitem->palette, true, 1, &fill);
- }
- } else if (!act) {
- p->fillRect(vCheckRect, menuitem->palette.brush(QPalette::Button));
- }
-
- // On Windows Style, if we have a checkable item and an icon we
- // draw the icon recessed to indicate an item is checked. If we
- // have no icon, we draw a checkmark instead.
- if (!menuitem->icon.isNull()) {
- QIcon::Mode mode = dis ? QIcon::Disabled : QIcon::Normal;
- if (act && !dis)
- mode = QIcon::Active;
- QPixmap pixmap;
- if (checked)
- pixmap = menuitem->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, opt, widget), mode, QIcon::On);
- else
- pixmap = menuitem->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, opt, widget), mode);
- int pixw = pixmap.width();
- int pixh = pixmap.height();
- if (act && !dis && !checked)
- qDrawShadePanel(p, vCheckRect, menuitem->palette, false, 1,
- &menuitem->palette.brush(QPalette::Button));
- QRect pmr(0, 0, pixw, pixh);
- pmr.moveCenter(vCheckRect.center());
- p->setPen(menuitem->palette.text().color());
- p->drawPixmap(pmr.topLeft(), pixmap);
- } else if (checked) {
- QStyleOptionMenuItem newMi = *menuitem;
- newMi.state = State_None;
- if (!dis)
- newMi.state |= State_Enabled;
- if (act)
- newMi.state |= State_On;
- newMi.rect = visualRect(opt->direction, menuitem->rect, QRect(menuitem->rect.x() + QWindowsStylePrivate::windowsItemFrame,
- menuitem->rect.y() + QWindowsStylePrivate::windowsItemFrame,
- checkcol - 2 * QWindowsStylePrivate::windowsItemFrame,
- menuitem->rect.height() - 2 * QWindowsStylePrivate::windowsItemFrame));
- proxy()->drawPrimitive(PE_IndicatorMenuCheckMark, &newMi, p, widget);
- }
- p->setPen(act ? menuitem->palette.highlightedText().color() : menuitem->palette.buttonText().color());
-
- QColor discol;
- if (dis) {
- discol = menuitem->palette.text().color();
- p->setPen(discol);
- }
-
- int xm = int(QWindowsStylePrivate::windowsItemFrame) + checkcol + int(QWindowsStylePrivate::windowsItemHMargin);
- int xpos = menuitem->rect.x() + xm;
- QRect textRect(xpos, y + QWindowsStylePrivate::windowsItemVMargin,
- w - xm - QWindowsStylePrivate::windowsRightBorder - tab + 1, h - 2 * QWindowsStylePrivate::windowsItemVMargin);
- QRect vTextRect = visualRect(opt->direction, menuitem->rect, textRect);
- QString s = menuitem->text;
- if (!s.isEmpty()) { // draw text
- p->save();
- int t = s.indexOf(QLatin1Char('\t'));
- int text_flags = Qt::AlignVCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
- if (!proxy()->styleHint(SH_UnderlineShortcut, menuitem, widget))
- text_flags |= Qt::TextHideMnemonic;
- text_flags |= Qt::AlignLeft;
- if (t >= 0) {
- QRect vShortcutRect = visualRect(opt->direction, menuitem->rect,
- QRect(textRect.topRight(), QPoint(menuitem->rect.right(), textRect.bottom())));
- if (dis && !act && proxy()->styleHint(SH_EtchDisabledText, opt, widget)) {
- p->setPen(menuitem->palette.light().color());
- p->drawText(vShortcutRect.adjusted(1,1,1,1), text_flags, s.mid(t + 1));
- p->setPen(discol);
- }
- p->drawText(vShortcutRect, text_flags, s.mid(t + 1));
- s = s.left(t);
- }
- QFont font = menuitem->font;
- if (menuitem->menuItemType == QStyleOptionMenuItem::DefaultItem)
- font.setBold(true);
- p->setFont(font);
- if (dis && !act && proxy()->styleHint(SH_EtchDisabledText, opt, widget)) {
- p->setPen(menuitem->palette.light().color());
- p->drawText(vTextRect.adjusted(1,1,1,1), text_flags, s.left(t));
- p->setPen(discol);
- }
- p->drawText(vTextRect, text_flags, s.left(t));
- p->restore();
- }
- if (menuitem->menuItemType == QStyleOptionMenuItem::SubMenu) {// draw sub menu arrow
- int dim = (h - 2 * QWindowsStylePrivate::windowsItemFrame) / 2;
- PrimitiveElement arrow;
- arrow = (opt->direction == Qt::RightToLeft) ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight;
- xpos = x + w - QWindowsStylePrivate::windowsArrowHMargin - QWindowsStylePrivate::windowsItemFrame - dim;
- QRect vSubMenuRect = visualRect(opt->direction, menuitem->rect, QRect(xpos, y + h / 2 - dim / 2, dim, dim));
- QStyleOptionMenuItem newMI = *menuitem;
- newMI.rect = vSubMenuRect;
- newMI.state = dis ? State_None : State_Enabled;
- if (act)
- newMI.palette.setColor(QPalette::ButtonText,
- newMI.palette.highlightedText().color());
- proxy()->drawPrimitive(arrow, &newMI, p, widget);
- }
-
- }
- break;
-#endif // QT_NO_MENU
-#ifndef QT_NO_MENUBAR
- case CE_MenuBarItem:
- if (const QStyleOptionMenuItem *mbi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
- bool active = mbi->state & State_Selected;
- bool hasFocus = mbi->state & State_HasFocus;
- bool down = mbi->state & State_Sunken;
- QStyleOptionMenuItem newMbi = *mbi;
- p->fillRect(mbi->rect, mbi->palette.brush(QPalette::Button));
- if (active || hasFocus) {
- QBrush b = mbi->palette.brush(QPalette::Button);
- if (active && down)
- p->setBrushOrigin(p->brushOrigin() + QPoint(1, 1));
- if (active && hasFocus)
- qDrawShadeRect(p, mbi->rect.x(), mbi->rect.y(), mbi->rect.width(),
- mbi->rect.height(), mbi->palette, active && down, 1, 0, &b);
- if (active && down) {
- newMbi.rect.translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, mbi, widget),
- proxy()->pixelMetric(PM_ButtonShiftVertical, mbi, widget));
- p->setBrushOrigin(p->brushOrigin() - QPoint(1, 1));
- }
- }
- QCommonStyle::drawControl(ce, &newMbi, p, widget);
- }
- break;
-#endif // QT_NO_MENUBAR
-#ifndef QT_NO_TABBAR
- case CE_TabBarTabShape:
- if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
- bool rtlHorTabs = (tab->direction == Qt::RightToLeft
- && (tab->shape == QTabBar::RoundedNorth
- || tab->shape == QTabBar::RoundedSouth));
- bool selected = tab->state & State_Selected;
- bool lastTab = ((!rtlHorTabs && tab->position == QStyleOptionTab::End)
- || (rtlHorTabs
- && tab->position == QStyleOptionTab::Beginning));
- bool firstTab = ((!rtlHorTabs
- && tab->position == QStyleOptionTab::Beginning)
- || (rtlHorTabs
- && tab->position == QStyleOptionTab::End));
- bool onlyOne = tab->position == QStyleOptionTab::OnlyOneTab;
- bool previousSelected =
- ((!rtlHorTabs
- && tab->selectedPosition == QStyleOptionTab::PreviousIsSelected)
- || (rtlHorTabs
- && tab->selectedPosition == QStyleOptionTab::NextIsSelected));
- bool nextSelected =
- ((!rtlHorTabs
- && tab->selectedPosition == QStyleOptionTab::NextIsSelected)
- || (rtlHorTabs
- && tab->selectedPosition
- == QStyleOptionTab::PreviousIsSelected));
- int tabBarAlignment = proxy()->styleHint(SH_TabBar_Alignment, tab, widget);
- bool leftAligned = (!rtlHorTabs && tabBarAlignment == Qt::AlignLeft)
- || (rtlHorTabs
- && tabBarAlignment == Qt::AlignRight);
-
- bool rightAligned = (!rtlHorTabs && tabBarAlignment == Qt::AlignRight)
- || (rtlHorTabs
- && tabBarAlignment == Qt::AlignLeft);
-
- QColor light = tab->palette.light().color();
- QColor dark = tab->palette.dark().color();
- QColor shadow = tab->palette.shadow().color();
- int borderThinkness = proxy()->pixelMetric(PM_TabBarBaseOverlap, tab, widget);
- if (selected)
- borderThinkness /= 2;
- QRect r2(opt->rect);
- int x1 = r2.left();
- int x2 = r2.right();
- int y1 = r2.top();
- int y2 = r2.bottom();
- switch (tab->shape) {
- default:
- QCommonStyle::drawControl(ce, tab, p, widget);
- break;
- case QTabBar::RoundedNorth: {
- if (!selected) {
- y1 += 2;
- x1 += onlyOne || firstTab ? borderThinkness : 0;
- x2 -= onlyOne || lastTab ? borderThinkness : 0;
- }
-
- p->fillRect(QRect(x1 + 1, y1 + 1, (x2 - x1) - 1, (y2 - y1) - 2), tab->palette.background());
-
- // Delete border
- if (selected) {
- p->fillRect(QRect(x1,y2-1,x2-x1,1), tab->palette.background());
- p->fillRect(QRect(x1,y2,x2-x1,1), tab->palette.background());
- }
- // Left
- if (firstTab || selected || onlyOne || !previousSelected) {
- p->setPen(light);
- p->drawLine(x1, y1 + 2, x1, y2 - ((onlyOne || firstTab) && selected && leftAligned ? 0 : borderThinkness));
- p->drawPoint(x1 + 1, y1 + 1);
- }
- // Top
- {
- int beg = x1 + (previousSelected ? 0 : 2);
- int end = x2 - (nextSelected ? 0 : 2);
- p->setPen(light);
- p->drawLine(beg, y1, end, y1);
- }
- // Right
- if (lastTab || selected || onlyOne || !nextSelected) {
- p->setPen(shadow);
- p->drawLine(x2, y1 + 2, x2, y2 - ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness));
- p->drawPoint(x2 - 1, y1 + 1);
- p->setPen(dark);
- p->drawLine(x2 - 1, y1 + 2, x2 - 1, y2 - ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness));
- }
- break; }
- case QTabBar::RoundedSouth: {
- if (!selected) {
- y2 -= 2;
- x1 += firstTab ? borderThinkness : 0;
- x2 -= lastTab ? borderThinkness : 0;
- }
-
- p->fillRect(QRect(x1 + 1, y1 + 2, (x2 - x1) - 1, (y2 - y1) - 1), tab->palette.background());
-
- // Delete border
- if (selected) {
- p->fillRect(QRect(x1, y1 + 1, (x2 - 1)-x1, 1), tab->palette.background());
- p->fillRect(QRect(x1, y1, (x2 - 1)-x1, 1), tab->palette.background());
- }
- // Left
- if (firstTab || selected || onlyOne || !previousSelected) {
- p->setPen(light);
- p->drawLine(x1, y2 - 2, x1, y1 + ((onlyOne || firstTab) && selected && leftAligned ? 0 : borderThinkness));
- p->drawPoint(x1 + 1, y2 - 1);
- }
- // Bottom
- {
- int beg = x1 + (previousSelected ? 0 : 2);
- int end = x2 - (nextSelected ? 0 : 2);
- p->setPen(shadow);
- p->drawLine(beg, y2, end, y2);
- p->setPen(dark);
- p->drawLine(beg, y2 - 1, end, y2 - 1);
- }
- // Right
- if (lastTab || selected || onlyOne || !nextSelected) {
- p->setPen(shadow);
- p->drawLine(x2, y2 - 2, x2, y1 + ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness));
- p->drawPoint(x2 - 1, y2 - 1);
- p->setPen(dark);
- p->drawLine(x2 - 1, y2 - 2, x2 - 1, y1 + ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness));
- }
- break; }
- case QTabBar::RoundedWest: {
- if (!selected) {
- x1 += 2;
- y1 += firstTab ? borderThinkness : 0;
- y2 -= lastTab ? borderThinkness : 0;
- }
-
- p->fillRect(QRect(x1 + 1, y1 + 1, (x2 - x1) - 2, (y2 - y1) - 1), tab->palette.background());
-
- // Delete border
- if (selected) {
- p->fillRect(QRect(x2 - 1, y1, 1, y2-y1), tab->palette.background());
- p->fillRect(QRect(x2, y1, 1, y2-y1), tab->palette.background());
- }
- // Top
- if (firstTab || selected || onlyOne || !previousSelected) {
- p->setPen(light);
- p->drawLine(x1 + 2, y1, x2 - ((onlyOne || firstTab) && selected && leftAligned ? 0 : borderThinkness), y1);
- p->drawPoint(x1 + 1, y1 + 1);
- }
- // Left
- {
- int beg = y1 + (previousSelected ? 0 : 2);
- int end = y2 - (nextSelected ? 0 : 2);
- p->setPen(light);
- p->drawLine(x1, beg, x1, end);
- }
- // Bottom
- if (lastTab || selected || onlyOne || !nextSelected) {
- p->setPen(shadow);
- p->drawLine(x1 + 3, y2, x2 - ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness), y2);
- p->drawPoint(x1 + 2, y2 - 1);
- p->setPen(dark);
- p->drawLine(x1 + 3, y2 - 1, x2 - ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness), y2 - 1);
- p->drawPoint(x1 + 1, y2 - 1);
- p->drawPoint(x1 + 2, y2);
- }
- break; }
- case QTabBar::RoundedEast: {
- if (!selected) {
- x2 -= 2;
- y1 += firstTab ? borderThinkness : 0;
- y2 -= lastTab ? borderThinkness : 0;
- }
-
- p->fillRect(QRect(x1 + 2, y1 + 1, (x2 - x1) - 1, (y2 - y1) - 1), tab->palette.background());
-
- // Delete border
- if (selected) {
- p->fillRect(QRect(x1 + 1, y1, 1, (y2 - 1)-y1),tab->palette.background());
- p->fillRect(QRect(x1, y1, 1, (y2-1)-y1), tab->palette.background());
- }
- // Top
- if (firstTab || selected || onlyOne || !previousSelected) {
- p->setPen(light);
- p->drawLine(x2 - 2, y1, x1 + ((onlyOne || firstTab) && selected && leftAligned ? 0 : borderThinkness), y1);
- p->drawPoint(x2 - 1, y1 + 1);
- }
- // Right
- {
- int beg = y1 + (previousSelected ? 0 : 2);
- int end = y2 - (nextSelected ? 0 : 2);
- p->setPen(shadow);
- p->drawLine(x2, beg, x2, end);
- p->setPen(dark);
- p->drawLine(x2 - 1, beg, x2 - 1, end);
- }
- // Bottom
- if (lastTab || selected || onlyOne || !nextSelected) {
- p->setPen(shadow);
- p->drawLine(x2 - 2, y2, x1 + ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness), y2);
- p->drawPoint(x2 - 1, y2 - 1);
- p->setPen(dark);
- p->drawLine(x2 - 2, y2 - 1, x1 + ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness), y2 - 1);
- }
- break; }
- }
- }
- break;
-#endif // QT_NO_TABBAR
- case CE_ToolBoxTabShape:
- qDrawShadePanel(p, opt->rect, opt->palette,
- opt->state & (State_Sunken | State_On), 1,
- &opt->palette.brush(QPalette::Button));
- break;
-#ifndef QT_NO_SPLITTER
- case CE_Splitter:
- p->eraseRect(opt->rect);
- break;
-#endif // QT_NO_SPLITTER
-#ifndef QT_NO_SCROLLBAR
- case CE_ScrollBarSubLine:
- case CE_ScrollBarAddLine: {
- if ((opt->state & State_Sunken)) {
- p->setPen(opt->palette.dark().color());
- p->setBrush(opt->palette.brush(QPalette::Button));
- p->drawRect(opt->rect.adjusted(0, 0, -1, -1));
- } else {
- QStyleOption buttonOpt = *opt;
- if (!(buttonOpt.state & State_Sunken))
- buttonOpt.state |= State_Raised;
- QPalette pal(opt->palette);
- pal.setColor(QPalette::Button, opt->palette.light().color());
- pal.setColor(QPalette::Light, opt->palette.button().color());
- qDrawWinButton(p, opt->rect, pal, opt->state & (State_Sunken | State_On),
- &opt->palette.brush(QPalette::Button));
- }
- PrimitiveElement arrow;
- if (opt->state & State_Horizontal) {
- if (ce == CE_ScrollBarAddLine)
- arrow = opt->direction == Qt::LeftToRight ? PE_IndicatorArrowRight : PE_IndicatorArrowLeft;
- else
- arrow = opt->direction == Qt::LeftToRight ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight;
- } else {
- if (ce == CE_ScrollBarAddLine)
- arrow = PE_IndicatorArrowDown;
- else
- arrow = PE_IndicatorArrowUp;
- }
- QStyleOption arrowOpt = *opt;
- arrowOpt.rect = opt->rect.adjusted(4, 4, -4, -4);
- proxy()->drawPrimitive(arrow, &arrowOpt, p, widget);
- break; }
- case CE_ScrollBarAddPage:
- case CE_ScrollBarSubPage: {
- QBrush br;
- QBrush bg = p->background();
- Qt::BGMode bg_mode = p->backgroundMode();
- p->setPen(Qt::NoPen);
- p->setBackgroundMode(Qt::OpaqueMode);
-
- if (opt->state & State_Sunken) {
- br = QBrush(opt->palette.shadow().color(), Qt::Dense4Pattern);
- p->setBackground(opt->palette.dark().color());
- p->setBrush(br);
- } else {
- QPixmap pm = opt->palette.brush(QPalette::Light).texture();
- br = !pm.isNull() ? QBrush(pm) : QBrush(opt->palette.light().color(), Qt::Dense4Pattern);
- p->setBackground(opt->palette.background().color());
- p->setBrush(br);
- }
- p->drawRect(opt->rect);
- p->setBackground(bg);
- p->setBackgroundMode(bg_mode);
- break; }
- case CE_ScrollBarSlider:
- if (!(opt->state & State_Enabled)) {
- QPixmap pm = opt->palette.brush(QPalette::Light).texture();
- QBrush br = !pm.isNull() ? QBrush(pm) : QBrush(opt->palette.light().color(), Qt::Dense4Pattern);
- p->setPen(Qt::NoPen);
- p->setBrush(br);
- p->setBackgroundMode(Qt::OpaqueMode);
- p->drawRect(opt->rect);
- } else {
- QStyleOptionButton buttonOpt;
- buttonOpt.QStyleOption::operator=(*opt);
- buttonOpt.state = State_Enabled | State_Raised;
-
- QPalette pal(opt->palette);
- pal.setColor(QPalette::Button, opt->palette.light().color());
- pal.setColor(QPalette::Light, opt->palette.button().color());
- qDrawWinButton(p, opt->rect, pal, false, &opt->palette.brush(QPalette::Button));
- }
- break;
-#endif // QT_NO_SCROLLBAR
- case CE_HeaderSection: {
- QBrush fill;
- if (opt->state & State_On)
- fill = QBrush(opt->palette.light().color(), Qt::Dense4Pattern);
- else
- fill = opt->palette.brush(QPalette::Button);
-
- if (opt->state & (State_Raised | State_Sunken)) {
- qDrawWinButton(p, opt->rect, opt->palette, opt->state & State_Sunken, &fill);
- } else {
- p->fillRect(opt->rect, fill);
- }
- break; }
-#ifndef QT_NO_TOOLBAR
- case CE_ToolBar:
- if (const QStyleOptionToolBar *toolbar = qstyleoption_cast<const QStyleOptionToolBar *>(opt)) {
- QRect rect = opt->rect;
-
- bool paintLeftBorder = true;
- bool paintRightBorder = true;
- bool paintBottomBorder = true;
-
- switch (toolbar->toolBarArea){
- case Qt::BottomToolBarArea :
- switch(toolbar->positionOfLine){
- case QStyleOptionToolBar::Beginning:
- case QStyleOptionToolBar::OnlyOne:
- paintBottomBorder = false;
- default:
- break;
- }
- case Qt::TopToolBarArea :
- switch(toolbar->positionWithinLine){
- case QStyleOptionToolBar::Beginning:
- paintLeftBorder = false;
- break;
- case QStyleOptionToolBar::End:
- paintRightBorder = false;
- break;
- case QStyleOptionToolBar::OnlyOne:
- paintRightBorder = false;
- paintLeftBorder = false;
- default:
- break;
- }
- if(opt->direction == Qt::RightToLeft){ //reverse layout changes the order of Beginning/end
- bool tmp = paintLeftBorder;
- paintRightBorder=paintLeftBorder;
- paintLeftBorder=tmp;
- }
- break;
- case Qt::RightToolBarArea :
- switch (toolbar->positionOfLine){
- case QStyleOptionToolBar::Beginning:
- case QStyleOptionToolBar::OnlyOne:
- paintRightBorder = false;
- break;
- default:
- break;
- }
- break;
- case Qt::LeftToolBarArea :
- switch (toolbar->positionOfLine){
- case QStyleOptionToolBar::Beginning:
- case QStyleOptionToolBar::OnlyOne:
- paintLeftBorder = false;
- break;
- default:
- break;
- }
- break;
- default:
- break;
- }
-
-
- //draw top border
- p->setPen(QPen(opt->palette.light().color()));
- p->drawLine(rect.topLeft().x(),
- rect.topLeft().y(),
- rect.topRight().x(),
- rect.topRight().y());
-
- if (paintLeftBorder){
- p->setPen(QPen(opt->palette.light().color()));
- p->drawLine(rect.topLeft().x(),
- rect.topLeft().y(),
- rect.bottomLeft().x(),
- rect.bottomLeft().y());
- }
-
- if (paintRightBorder){
- p->setPen(QPen(opt->palette.dark().color()));
- p->drawLine(rect.topRight().x(),
- rect.topRight().y(),
- rect.bottomRight().x(),
- rect.bottomRight().y());
- }
-
- if (paintBottomBorder){
- p->setPen(QPen(opt->palette.dark().color()));
- p->drawLine(rect.bottomLeft().x(),
- rect.bottomLeft().y(),
- rect.bottomRight().x(),
- rect.bottomRight().y());
- }
- }
- break;
-
-
-#endif // QT_NO_TOOLBAR
-#ifndef QT_NO_PROGRESSBAR
- case CE_ProgressBarContents:
- if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) {
- QRect rect = pb->rect;
- if (!rect.isValid())
- return;
-
- bool vertical = false;
- bool inverted = false;
-
- // Get extra style options if version 2
- const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(opt);
- if (pb2) {
- vertical = (pb2->orientation == Qt::Vertical);
- inverted = pb2->invertedAppearance;
- }
- QMatrix m;
- if (vertical) {
- rect = QRect(rect.y(), rect.x(), rect.height(), rect.width()); // flip width and height
- m.rotate(90);
- m.translate(0, -(rect.height() + rect.y()*2));
- }
- QPalette pal2 = pb->palette;
- // Correct the highlight color if it is the same as the background
- if (pal2.highlight() == pal2.background())
- pal2.setColor(QPalette::Highlight, pb->palette.color(QPalette::Active,
- QPalette::Highlight));
- bool reverse = ((!vertical && (pb->direction == Qt::RightToLeft)) || vertical);
- if (inverted)
- reverse = !reverse;
- int w = rect.width();
- if (pb->minimum == 0 && pb->maximum == 0) {
- Q_D(const QWindowsStyle);
- const int unit_width = proxy()->pixelMetric(PM_ProgressBarChunkWidth, pb, widget);
- QStyleOptionProgressBarV2 pbBits = *pb;
- Q_ASSERT(unit_width >0);
-
- pbBits.rect = rect;
- pbBits.palette = pal2;
-
- int chunkCount = w / unit_width + 1;
- int step = d->animateStep%chunkCount;
- int chunksInRow = 5;
- int myY = pbBits.rect.y();
- int myHeight = pbBits.rect.height();
- int chunksToDraw = chunksInRow;
-
- if(step > chunkCount - 5)chunksToDraw = (chunkCount - step);
- p->save();
- p->setClipRect(m.mapRect(QRectF(rect)).toRect());
-
- int x0 = reverse ? rect.left() + rect.width() - unit_width*(step) - unit_width : rect.left() + unit_width * step;
- int x = 0;
-
- for (int i = 0; i < chunksToDraw ; ++i) {
- pbBits.rect.setRect(x0 + x, myY, unit_width, myHeight);
- pbBits.rect = m.mapRect(QRectF(pbBits.rect)).toRect();
- proxy()->drawPrimitive(PE_IndicatorProgressChunk, &pbBits, p, widget);
- x += reverse ? -unit_width : unit_width;
- }
- //Draw wrap-around chunks
- if( step > chunkCount-5){
- x0 = reverse ? rect.left() + rect.width() - unit_width : rect.left() ;
- x = 0;
- int chunksToDraw = step - (chunkCount - chunksInRow);
- for (int i = 0; i < chunksToDraw ; ++i) {
- pbBits.rect.setRect(x0 + x, myY, unit_width, myHeight);
- pbBits.rect = m.mapRect(QRectF(pbBits.rect)).toRect();
- proxy()->drawPrimitive(PE_IndicatorProgressChunk, &pbBits, p, widget);
- x += reverse ? -unit_width : unit_width;
- }
- }
- p->restore(); //restore state
- }
- else {
- QCommonStyle::drawControl(ce, opt, p, widget);
- }
- }
- break;
-#endif // QT_NO_PROGRESSBAR
-
-#ifndef QT_NO_DOCKWIDGET
- case CE_DockWidgetTitle:
-
- if (const QStyleOptionDockWidget *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(opt)) {
- Q_D(const QWindowsStyle);
-
- const QStyleOptionDockWidgetV2 *v2
- = qstyleoption_cast<const QStyleOptionDockWidgetV2*>(opt);
- bool verticalTitleBar = v2 == 0 ? false : v2->verticalTitleBar;
-
- QRect rect = dwOpt->rect;
- QRect r = rect;
-
- if (verticalTitleBar) {
- QSize s = r.size();
- s.transpose();
- r.setSize(s);
-
- p->save();
- p->translate(r.left(), r.top() + r.width());
- p->rotate(-90);
- p->translate(-r.left(), -r.top());
- }
-
- bool floating = false;
- bool active = dwOpt->state & State_Active;
- QColor inactiveCaptionTextColor = d->inactiveCaptionText;
- if (dwOpt->movable) {
- QColor left, right;
-
- //Titlebar gradient
- if (widget && widget->isWindow()) {
- floating = true;
- if (active) {
- left = d->activeCaptionColor;
- right = d->activeGradientCaptionColor;
- } else {
- left = d->inactiveCaptionColor;
- right = d->inactiveGradientCaptionColor;
- }
- QBrush fillBrush(left);
- if (left != right) {
- QPoint p1(r.x(), r.top() + r.height()/2);
- QPoint p2(rect.right(), r.top() + r.height()/2);
- QLinearGradient lg(p1, p2);
- lg.setColorAt(0, left);
- lg.setColorAt(1, right);
- fillBrush = lg;
- }
- p->fillRect(r.adjusted(0, 0, 0, -3), fillBrush);
- }
- p->setPen(dwOpt->palette.color(QPalette::Light));
- if (!widget || !widget->isWindow()) {
- p->drawLine(r.topLeft(), r.topRight());
- p->setPen(dwOpt->palette.color(QPalette::Dark));
- p->drawLine(r.bottomLeft(), r.bottomRight()); }
- }
- if (!dwOpt->title.isEmpty()) {
- QFont oldFont = p->font();
- if (floating) {
- QFont font = oldFont;
- font.setBold(true);
- p->setFont(font);
- }
- QPalette palette = dwOpt->palette;
- palette.setColor(QPalette::Window, inactiveCaptionTextColor);
- QRect titleRect = subElementRect(SE_DockWidgetTitleBarText, opt, widget);
- if (verticalTitleBar) {
- titleRect = QRect(r.left() + rect.bottom()
- - titleRect.bottom(),
- r.top() + titleRect.left() - rect.left(),
- titleRect.height(), titleRect.width());
- }
- proxy()->drawItemText(p, titleRect,
- Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic, palette,
- dwOpt->state & State_Enabled, dwOpt->title,
- floating ? (active ? QPalette::BrightText : QPalette::Window) : QPalette::WindowText);
- p->setFont(oldFont);
- }
- if (verticalTitleBar)
- p->restore();
- }
- return;
-#endif // QT_NO_DOCKWIDGET
- default:
- QCommonStyle::drawControl(ce, opt, p, widget);
- }
-}
-
-/*! \reimp */
-QRect QWindowsStyle::subElementRect(SubElement sr, const QStyleOption *opt, const QWidget *w) const
-{
- QRect r;
- switch (sr) {
- case SE_SliderFocusRect:
- case SE_ToolBoxTabContents:
- r = visualRect(opt->direction, opt->rect, opt->rect);
- break;
- case SE_DockWidgetTitleBarText: {
- r = QCommonStyle::subElementRect(sr, opt, w);
- const QStyleOptionDockWidgetV2 *v2
- = qstyleoption_cast<const QStyleOptionDockWidgetV2*>(opt);
- bool verticalTitleBar = v2 == 0 ? false : v2->verticalTitleBar;
- int m = proxy()->pixelMetric(PM_DockWidgetTitleMargin, opt, w);
- if (verticalTitleBar) {
- r.adjust(0, 0, 0, -m);
- } else {
- if (opt->direction == Qt::LeftToRight)
- r.adjust(m, 0, 0, 0);
- else
- r.adjust(0, 0, -m, 0);
- }
- break;
- }
- case SE_ProgressBarContents:
- r = QCommonStyle::subElementRect(SE_ProgressBarGroove, opt, w);
- r.adjust(3, 3, -3, -3);
- break;
- default:
- r = QCommonStyle::subElementRect(sr, opt, w);
- }
- return r;
-}
-
-#ifdef QT3_SUPPORT
-Q_GLOBAL_STATIC_WITH_ARGS(QBitmap, globalVerticalLine, (1, 129))
-Q_GLOBAL_STATIC_WITH_ARGS(QBitmap, globalHorizontalLine, (128, 1))
-#endif
-
-/*! \reimp */
-void QWindowsStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt,
- QPainter *p, const QWidget *widget) const
-{
- switch (cc) {
-#ifndef QT_NO_SLIDER
- case CC_Slider:
- if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
- int thickness = proxy()->pixelMetric(PM_SliderControlThickness, slider, widget);
- int len = proxy()->pixelMetric(PM_SliderLength, slider, widget);
- int ticks = slider->tickPosition;
- QRect groove = proxy()->subControlRect(CC_Slider, slider, SC_SliderGroove, widget);
- QRect handle = proxy()->subControlRect(CC_Slider, slider, SC_SliderHandle, widget);
-
- if ((slider->subControls & SC_SliderGroove) && groove.isValid()) {
- int mid = thickness / 2;
-
- if (ticks & QSlider::TicksAbove)
- mid += len / 8;
- if (ticks & QSlider::TicksBelow)
- mid -= len / 8;
-
- p->setPen(slider->palette.shadow().color());
- if (slider->orientation == Qt::Horizontal) {
- qDrawWinPanel(p, groove.x(), groove.y() + mid - 2,
- groove.width(), 4, slider->palette, true);
- p->drawLine(groove.x() + 1, groove.y() + mid - 1,
- groove.x() + groove.width() - 3, groove.y() + mid - 1);
- } else {
- qDrawWinPanel(p, groove.x() + mid - 2, groove.y(),
- 4, groove.height(), slider->palette, true);
- p->drawLine(groove.x() + mid - 1, groove.y() + 1,
- groove.x() + mid - 1, groove.y() + groove.height() - 3);
- }
- }
-
- if (slider->subControls & SC_SliderTickmarks) {
- QStyleOptionSlider tmpSlider = *slider;
- tmpSlider.subControls = SC_SliderTickmarks;
- QCommonStyle::drawComplexControl(cc, &tmpSlider, p, widget);
- }
-
- if (slider->subControls & SC_SliderHandle) {
- // 4444440
- // 4333310
- // 4322210
- // 4322210
- // 4322210
- // 4322210
- // *43210*
- // **410**
- // ***0***
- const QColor c0 = slider->palette.shadow().color();
- const QColor c1 = slider->palette.dark().color();
- // const QColor c2 = g.button();
- const QColor c3 = slider->palette.midlight().color();
- const QColor c4 = slider->palette.light().color();
- QBrush handleBrush;
-
- if (slider->state & State_Enabled) {
- handleBrush = slider->palette.color(QPalette::Button);
- } else {
- handleBrush = QBrush(slider->palette.color(QPalette::Button),
- Qt::Dense4Pattern);
- }
-
-
- int x = handle.x(), y = handle.y(),
- wi = handle.width(), he = handle.height();
-
- int x1 = x;
- int x2 = x+wi-1;
- int y1 = y;
- int y2 = y+he-1;
-
- Qt::Orientation orient = slider->orientation;
- bool tickAbove = slider->tickPosition == QSlider::TicksAbove;
- bool tickBelow = slider->tickPosition == QSlider::TicksBelow;
-
- if (slider->state & State_HasFocus) {
- QStyleOptionFocusRect fropt;
- fropt.QStyleOption::operator=(*slider);
- fropt.rect = subElementRect(SE_SliderFocusRect, slider, widget);
- proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, p, widget);
- }
-
- if ((tickAbove && tickBelow) || (!tickAbove && !tickBelow)) {
- Qt::BGMode oldMode = p->backgroundMode();
- p->setBackgroundMode(Qt::OpaqueMode);
- qDrawWinButton(p, QRect(x, y, wi, he), slider->palette, false,
- &handleBrush);
- p->setBackgroundMode(oldMode);
- return;
- }
-
- QSliderDirection dir;
-
- if (orient == Qt::Horizontal)
- if (tickAbove)
- dir = SlUp;
- else
- dir = SlDown;
- else
- if (tickAbove)
- dir = SlLeft;
- else
- dir = SlRight;
-
- QPolygon a;
-
- int d = 0;
- switch (dir) {
- case SlUp:
- y1 = y1 + wi/2;
- d = (wi + 1) / 2 - 1;
- a.setPoints(5, x1,y1, x1,y2, x2,y2, x2,y1, x1+d,y1-d);
- break;
- case SlDown:
- y2 = y2 - wi/2;
- d = (wi + 1) / 2 - 1;
- a.setPoints(5, x1,y1, x1,y2, x1+d,y2+d, x2,y2, x2,y1);
- break;
- case SlLeft:
- d = (he + 1) / 2 - 1;
- x1 = x1 + he/2;
- a.setPoints(5, x1,y1, x1-d,y1+d, x1,y2, x2,y2, x2,y1);
- break;
- case SlRight:
- d = (he + 1) / 2 - 1;
- x2 = x2 - he/2;
- a.setPoints(5, x1,y1, x1,y2, x2,y2, x2+d,y1+d, x2,y1);
- break;
- }
-
- QBrush oldBrush = p->brush();
- p->setPen(Qt::NoPen);
- p->setBrush(handleBrush);
- Qt::BGMode oldMode = p->backgroundMode();
- p->setBackgroundMode(Qt::OpaqueMode);
- p->drawRect(x1, y1, x2-x1+1, y2-y1+1);
- p->drawPolygon(a);
- p->setBrush(oldBrush);
- p->setBackgroundMode(oldMode);
-
- if (dir != SlUp) {
- p->setPen(c4);
- p->drawLine(x1, y1, x2, y1);
- p->setPen(c3);
- p->drawLine(x1, y1+1, x2, y1+1);
- }
- if (dir != SlLeft) {
- p->setPen(c3);
- p->drawLine(x1+1, y1+1, x1+1, y2);
- p->setPen(c4);
- p->drawLine(x1, y1, x1, y2);
- }
- if (dir != SlRight) {
- p->setPen(c0);
- p->drawLine(x2, y1, x2, y2);
- p->setPen(c1);
- p->drawLine(x2-1, y1+1, x2-1, y2-1);
- }
- if (dir != SlDown) {
- p->setPen(c0);
- p->drawLine(x1, y2, x2, y2);
- p->setPen(c1);
- p->drawLine(x1+1, y2-1, x2-1, y2-1);
- }
-
- switch (dir) {
- case SlUp:
- p->setPen(c4);
- p->drawLine(x1, y1, x1+d, y1-d);
- p->setPen(c0);
- d = wi - d - 1;
- p->drawLine(x2, y1, x2-d, y1-d);
- d--;
- p->setPen(c3);
- p->drawLine(x1+1, y1, x1+1+d, y1-d);
- p->setPen(c1);
- p->drawLine(x2-1, y1, x2-1-d, y1-d);
- break;
- case SlDown:
- p->setPen(c4);
- p->drawLine(x1, y2, x1+d, y2+d);
- p->setPen(c0);
- d = wi - d - 1;
- p->drawLine(x2, y2, x2-d, y2+d);
- d--;
- p->setPen(c3);
- p->drawLine(x1+1, y2, x1+1+d, y2+d);
- p->setPen(c1);
- p->drawLine(x2-1, y2, x2-1-d, y2+d);
- break;
- case SlLeft:
- p->setPen(c4);
- p->drawLine(x1, y1, x1-d, y1+d);
- p->setPen(c0);
- d = he - d - 1;
- p->drawLine(x1, y2, x1-d, y2-d);
- d--;
- p->setPen(c3);
- p->drawLine(x1, y1+1, x1-d, y1+1+d);
- p->setPen(c1);
- p->drawLine(x1, y2-1, x1-d, y2-1-d);
- break;
- case SlRight:
- p->setPen(c4);
- p->drawLine(x2, y1, x2+d, y1+d);
- p->setPen(c0);
- d = he - d - 1;
- p->drawLine(x2, y2, x2+d, y2-d);
- d--;
- p->setPen(c3);
- p->drawLine(x2, y1+1, x2+d, y1+1+d);
- p->setPen(c1);
- p->drawLine(x2, y2-1, x2+d, y2-1-d);
- break;
- }
- }
- }
- break;
-#endif // QT_NO_SLIDER
-#ifndef QT_NO_SCROLLBAR
- case CC_ScrollBar:
- if (const QStyleOptionSlider *scrollbar = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
- QStyleOptionSlider newScrollbar = *scrollbar;
- if (scrollbar->minimum == scrollbar->maximum)
- newScrollbar.state &= ~State_Enabled; //do not draw the slider.
- QCommonStyle::drawComplexControl(cc, &newScrollbar, p, widget);
- }
- break;
-#endif // QT_NO_SCROLLBAR
-#ifdef QT3_SUPPORT
- case CC_Q3ListView:
- if (const QStyleOptionQ3ListView *lv = qstyleoption_cast<const QStyleOptionQ3ListView *>(opt)) {
- int i;
- if (lv->subControls & SC_Q3ListView)
- QCommonStyle::drawComplexControl(cc, lv, p, widget);
- if (lv->subControls & (SC_Q3ListViewBranch | SC_Q3ListViewExpand)) {
- if (lv->items.isEmpty())
- break;
- QStyleOptionQ3ListViewItem item = lv->items.at(0);
- int y = lv->rect.y();
- int c;
- int dotoffset = 0;
- QPolygon dotlines;
- if ((lv->activeSubControls & SC_All) && (lv->subControls & SC_Q3ListViewExpand)) {
- c = 2;
- dotlines.resize(2);
- dotlines[0] = QPoint(lv->rect.right(), lv->rect.top());
- dotlines[1] = QPoint(lv->rect.right(), lv->rect.bottom());
- } else {
- int linetop = 0, linebot = 0;
- // each branch needs at most two lines, ie. four end points
- dotoffset = (item.itemY + item.height - y) % 2;
- dotlines.resize(item.childCount * 4);
- c = 0;
-
- // skip the stuff above the exposed rectangle
- for (i = 1; i < lv->items.size(); ++i) {
- QStyleOptionQ3ListViewItem child = lv->items.at(i);
- if (child.height + y > 0)
- break;
- y += child.totalHeight;
- }
- int bx = lv->rect.width() / 2;
-
- // paint stuff in the magical area
- while (i < lv->items.size() && y < lv->rect.height()) {
- QStyleOptionQ3ListViewItem child = lv->items.at(i);
- if (child.features & QStyleOptionQ3ListViewItem::Visible) {
- int lh;
- if (!(item.features & QStyleOptionQ3ListViewItem::MultiLine))
- lh = child.height;
- else
- lh = p->fontMetrics().height() + 2 * lv->itemMargin;
- lh = qMax(lh, QApplication::globalStrut().height());
- if (lh % 2 > 0)
- ++lh;
- linebot = y + lh / 2;
- if (child.features & QStyleOptionQ3ListViewItem::Expandable
- || (child.childCount > 0 && child.height > 0)) {
- // needs a box
- p->setPen(lv->palette.mid().color());
- p->drawRect(bx - 4, linebot - 4, 8, 8);
- // plus or minus
- p->setPen(lv->palette.text().color());
- p->drawLine(bx - 2, linebot, bx + 2, linebot);
- if (!(child.state & State_Open))
- p->drawLine(bx, linebot - 2, bx, linebot + 2);
- // dotlinery
- p->setPen(lv->palette.mid().color());
- dotlines[c++] = QPoint(bx, linetop);
- dotlines[c++] = QPoint(bx, linebot - 4);
- dotlines[c++] = QPoint(bx + 5, linebot);
- dotlines[c++] = QPoint(lv->rect.width(), linebot);
- linetop = linebot + 5;
- } else {
- // just dotlinery
- dotlines[c++] = QPoint(bx+1, linebot -1);
- dotlines[c++] = QPoint(lv->rect.width(), linebot -1);
- }
- y += child.totalHeight;
- }
- ++i;
- }
-
- // Expand line height to edge of rectangle if there's any
- // visible child below
- while (i < lv->items.size() && lv->items.at(i).height <= 0)
- ++i;
- if (i < lv->items.size())
- linebot = lv->rect.height();
-
- if (linetop < linebot) {
- dotlines[c++] = QPoint(bx, linetop);
- dotlines[c++] = QPoint(bx, linebot);
- }
- }
- p->setPen(lv->palette.text().color());
- QBitmap *verticalLine = globalVerticalLine();
- QBitmap *horizontalLine = globalHorizontalLine();
- static bool isInit = false;
- if (!isInit) {
- isInit = true;
- // make 128*1 and 1*128 bitmaps that can be used for
- // drawing the right sort of lines.
- verticalLine->clear();
- horizontalLine->clear();
- QPolygon a(64);
- QPainter p;
- p.begin(verticalLine);
- for(i = 0; i < 64; ++i)
- a.setPoint(i, 0, i * 2 + 1);
- p.setPen(Qt::color1);
- p.drawPoints(a);
- p.end();
- QApplication::flush();
- verticalLine->setMask(*verticalLine);
- p.begin(horizontalLine);
- for(i = 0; i < 64; ++i)
- a.setPoint(i, i * 2 + 1, 0);
- p.setPen(Qt::color1);
- p.drawPoints(a);
- p.end();
- QApplication::flush();
- horizontalLine->setMask(*horizontalLine);
- }
-
- int line; // index into dotlines
- if (lv->subControls & SC_Q3ListViewBranch) for(line = 0; line < c; line += 2) {
- // assumptions here: lines are horizontal or vertical.
- // lines always start with the numerically lowest
- // coordinate.
-
- // point ... relevant coordinate of current point
- // end ..... same coordinate of the end of the current line
- // other ... the other coordinate of the current point/line
- if (dotlines[line].y() == dotlines[line+1].y()) {
- int end = dotlines[line + 1].x();
- int point = dotlines[line].x();
- int other = dotlines[line].y();
- while (point < end) {
- int i = 128;
- if (i + point > end)
- i = end-point;
- p->drawPixmap(point, other, *horizontalLine, 0, 0, i, 1);
- point += i;
- }
- } else {
- int end = dotlines[line + 1].y();
- int point = dotlines[line].y();
- int other = dotlines[line].x();
- int pixmapoffset = ((point & 1) != dotoffset) ? 1 : 0;
- while(point < end) {
- int i = 128;
- if (i + point > end)
- i = end-point;
- p->drawPixmap(other, point, *verticalLine, 0, pixmapoffset, 1, i);
- point += i;
- }
- }
- }
- }
- }
- break;
-#endif // QT3_SUPPORT
-#ifndef QT_NO_COMBOBOX
- case CC_ComboBox:
- if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
- QBrush editBrush = cmb->palette.brush(QPalette::Base);
- if ((cmb->subControls & SC_ComboBoxFrame)) {
- if (cmb->frame) {
- QPalette shadePal = opt->palette;
- shadePal.setColor(QPalette::Midlight, shadePal.button().color());
- qDrawWinPanel(p, opt->rect, shadePal, true, &editBrush);
- }
- else {
- p->fillRect(opt->rect, editBrush);
- }
- }
- if (cmb->subControls & SC_ComboBoxArrow) {
- State flags = State_None;
-
- QRect ar = proxy()->subControlRect(CC_ComboBox, cmb, SC_ComboBoxArrow, widget);
- bool sunkenArrow = cmb->activeSubControls == SC_ComboBoxArrow
- && cmb->state & State_Sunken;
- if (sunkenArrow) {
- p->setPen(cmb->palette.dark().color());
- p->setBrush(cmb->palette.brush(QPalette::Button));
- p->drawRect(ar.adjusted(0,0,-1,-1));
- } else {
- // Make qDrawWinButton use the right colors for drawing the shade of the button
- QPalette pal(cmb->palette);
- pal.setColor(QPalette::Button, cmb->palette.light().color());
- pal.setColor(QPalette::Light, cmb->palette.button().color());
- qDrawWinButton(p, ar, pal, false,
- &cmb->palette.brush(QPalette::Button));
- }
-
- ar.adjust(2, 2, -2, -2);
- if (opt->state & State_Enabled)
- flags |= State_Enabled;
- if (opt->state & State_HasFocus)
- flags |= State_HasFocus;
-
- if (sunkenArrow)
- flags |= State_Sunken;
- QStyleOption arrowOpt(0);
- arrowOpt.rect = ar.adjusted(1, 1, -1, -1);
- arrowOpt.palette = cmb->palette;
- arrowOpt.state = flags;
- proxy()->drawPrimitive(PE_IndicatorArrowDown, &arrowOpt, p, widget);
- }
-
- if (cmb->subControls & SC_ComboBoxEditField) {
- QRect re = proxy()->subControlRect(CC_ComboBox, cmb, SC_ComboBoxEditField, widget);
- if (cmb->state & State_HasFocus && !cmb->editable)
- p->fillRect(re.x(), re.y(), re.width(), re.height(),
- cmb->palette.brush(QPalette::Highlight));
-
- if (cmb->state & State_HasFocus) {
- p->setPen(cmb->palette.highlightedText().color());
- p->setBackground(cmb->palette.highlight());
-
- } else {
- p->setPen(cmb->palette.text().color());
- p->setBackground(cmb->palette.background());
- }
-
- if (cmb->state & State_HasFocus && !cmb->editable) {
- QStyleOptionFocusRect focus;
- focus.QStyleOption::operator=(*cmb);
- focus.rect = subElementRect(SE_ComboBoxFocusRect, cmb, widget);
- focus.state |= State_FocusAtBorder;
- focus.backgroundColor = cmb->palette.highlight().color();
- proxy()->drawPrimitive(PE_FrameFocusRect, &focus, p, widget);
- }
- }
- }
- break;
-#endif // QT_NO_COMBOBOX
-#ifndef QT_NO_SPINBOX
- case CC_SpinBox:
- if (const QStyleOptionSpinBox *sb = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
- QStyleOptionSpinBox copy = *sb;
- PrimitiveElement pe;
- bool enabled = opt->state & State_Enabled;
- if (sb->frame && (sb->subControls & SC_SpinBoxFrame)) {
- QBrush editBrush = sb->palette.brush(QPalette::Base);
- QRect r = proxy()->subControlRect(CC_SpinBox, sb, SC_SpinBoxFrame, widget);
- QPalette shadePal = sb->palette;
- shadePal.setColor(QPalette::Midlight, shadePal.button().color());
- qDrawWinPanel(p, r, shadePal, true, &editBrush);
- }
-
- QPalette shadePal(opt->palette);
- shadePal.setColor(QPalette::Button, opt->palette.light().color());
- shadePal.setColor(QPalette::Light, opt->palette.button().color());
-
- if (sb->subControls & SC_SpinBoxUp) {
- copy.subControls = SC_SpinBoxUp;
- QPalette pal2 = sb->palette;
- if (!(sb->stepEnabled & QAbstractSpinBox::StepUpEnabled)) {
- pal2.setCurrentColorGroup(QPalette::Disabled);
- copy.state &= ~State_Enabled;
- }
-
- copy.palette = pal2;
-
- if (sb->activeSubControls == SC_SpinBoxUp && (sb->state & State_Sunken)) {
- copy.state |= State_On;
- copy.state |= State_Sunken;
- } else {
- copy.state |= State_Raised;
- copy.state &= ~State_Sunken;
- }
- pe = (sb->buttonSymbols == QAbstractSpinBox::PlusMinus ? PE_IndicatorSpinPlus
- : PE_IndicatorSpinUp);
-
- copy.rect = proxy()->subControlRect(CC_SpinBox, sb, SC_SpinBoxUp, widget);
- qDrawWinButton(p, copy.rect, shadePal, copy.state & (State_Sunken | State_On),
- &copy.palette.brush(QPalette::Button));
- copy.rect.adjust(4, 1, -5, -1);
- if ((!enabled || !(sb->stepEnabled & QAbstractSpinBox::StepUpEnabled))
- && proxy()->styleHint(SH_EtchDisabledText, opt, widget) )
- {
- QStyleOptionSpinBox lightCopy = copy;
- lightCopy.rect.adjust(1, 1, 1, 1);
- lightCopy.palette.setBrush(QPalette::ButtonText, copy.palette.light());
- proxy()->drawPrimitive(pe, &lightCopy, p, widget);
- }
- proxy()->drawPrimitive(pe, &copy, p, widget);
- }
-
- if (sb->subControls & SC_SpinBoxDown) {
- copy.subControls = SC_SpinBoxDown;
- copy.state = sb->state;
- QPalette pal2 = sb->palette;
- if (!(sb->stepEnabled & QAbstractSpinBox::StepDownEnabled)) {
- pal2.setCurrentColorGroup(QPalette::Disabled);
- copy.state &= ~State_Enabled;
- }
- copy.palette = pal2;
-
- if (sb->activeSubControls == SC_SpinBoxDown && (sb->state & State_Sunken)) {
- copy.state |= State_On;
- copy.state |= State_Sunken;
- } else {
- copy.state |= State_Raised;
- copy.state &= ~State_Sunken;
- }
- pe = (sb->buttonSymbols == QAbstractSpinBox::PlusMinus ? PE_IndicatorSpinMinus
- : PE_IndicatorSpinDown);
-
- copy.rect = proxy()->subControlRect(CC_SpinBox, sb, SC_SpinBoxDown, widget);
- qDrawWinButton(p, copy.rect, shadePal, copy.state & (State_Sunken | State_On),
- &copy.palette.brush(QPalette::Button));
- copy.rect.adjust(4, 0, -5, -1);
- if ((!enabled || !(sb->stepEnabled & QAbstractSpinBox::StepDownEnabled))
- && proxy()->styleHint(SH_EtchDisabledText, opt, widget) )
- {
- QStyleOptionSpinBox lightCopy = copy;
- lightCopy.rect.adjust(1, 1, 1, 1);
- lightCopy.palette.setBrush(QPalette::ButtonText, copy.palette.light());
- proxy()->drawPrimitive(pe, &lightCopy, p, widget);
- }
- proxy()->drawPrimitive(pe, &copy, p, widget);
- }
- }
- break;
-#endif // QT_NO_SPINBOX
-
- default:
- QCommonStyle::drawComplexControl(cc, opt, p, widget);
- }
-}
-
-/*! \reimp */
-QSize QWindowsStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt,
- const QSize &csz, const QWidget *widget) const
-{
- QSize sz(csz);
- switch (ct) {
- case CT_PushButton:
- if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
- sz = QCommonStyle::sizeFromContents(ct, opt, csz, widget);
- int w = sz.width(),
- h = sz.height();
- int defwidth = 0;
- if (btn->features & QStyleOptionButton::AutoDefaultButton)
- defwidth = 2 * proxy()->pixelMetric(PM_ButtonDefaultIndicator, btn, widget);
- int minwidth = int(QStyleHelper::dpiScaled(75.));
- int minheight = int(QStyleHelper::dpiScaled(23.));
-
-#ifndef QT_QWS_SMALL_PUSHBUTTON
- if (w < minwidth + defwidth && !btn->text.isEmpty())
- w = minwidth + defwidth;
- if (h < minheight + defwidth)
- h = minheight + defwidth;
-#endif
- sz = QSize(w, h);
- }
- break;
-#ifndef QT_NO_MENU
- case CT_MenuItem:
- if (const QStyleOptionMenuItem *mi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
- int w = sz.width();
- sz = QCommonStyle::sizeFromContents(ct, opt, csz, widget);
-
- if (mi->menuItemType == QStyleOptionMenuItem::Separator) {
- sz = QSize(10, QWindowsStylePrivate::windowsSepHeight);
- }
- else if (mi->icon.isNull()) {
- sz.setHeight(sz.height() - 2);
- w -= 6;
- }
-
- if (mi->menuItemType != QStyleOptionMenuItem::Separator && !mi->icon.isNull()) {
- int iconExtent = proxy()->pixelMetric(PM_SmallIconSize, opt, widget);
- sz.setHeight(qMax(sz.height(),
- mi->icon.actualSize(QSize(iconExtent, iconExtent)).height()
- + 2 * QWindowsStylePrivate::windowsItemFrame));
- }
- int maxpmw = mi->maxIconWidth;
- int tabSpacing = 20;
- if (mi->text.contains(QLatin1Char('\t')))
- w += tabSpacing;
- else if (mi->menuItemType == QStyleOptionMenuItem::SubMenu)
- w += 2 * QWindowsStylePrivate::windowsArrowHMargin;
- else if (mi->menuItemType == QStyleOptionMenuItem::DefaultItem) {
- // adjust the font and add the difference in size.
- // it would be better if the font could be adjusted in the initStyleOption qmenu func!!
- QFontMetrics fm(mi->font);
- QFont fontBold = mi->font;
- fontBold.setBold(true);
- QFontMetrics fmBold(fontBold);
- w += fmBold.width(mi->text) - fm.width(mi->text);
- }
-
- int checkcol = qMax<int>(maxpmw, QWindowsStylePrivate::windowsCheckMarkWidth); // Windows always shows a check column
- w += checkcol;
- w += int(QWindowsStylePrivate::windowsRightBorder) + 10;
- sz.setWidth(w);
- }
- break;
-#endif // QT_NO_MENU
-#ifndef QT_NO_MENUBAR
- case CT_MenuBarItem:
- if (!sz.isEmpty())
- sz += QSize(QWindowsStylePrivate::windowsItemHMargin * 4, QWindowsStylePrivate::windowsItemVMargin * 2);
- break;
-#endif
- // Otherwise, fall through
- case CT_ToolButton:
- if (qstyleoption_cast<const QStyleOptionToolButton *>(opt))
- return sz += QSize(7, 6);
- // Otherwise, fall through
-
- default:
- sz = QCommonStyle::sizeFromContents(ct, opt, csz, widget);
- }
- return sz;
-}
-
-/*!
- \internal
-*/
-QIcon QWindowsStyle::standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *option,
- const QWidget *widget) const
-{
- QIcon icon;
- QPixmap pixmap;
-#ifdef Q_OS_WIN
- switch (standardIcon) {
- case SP_FileDialogNewFolder:
- {
- for (int size = 16 ; size <= 32 ; size += 16) {
- pixmap = loadIconFromShell32(319, size);
- icon.addPixmap(pixmap, QIcon::Normal);
- }
- break;
- }
- case SP_DirHomeIcon:
- {
- for (int size = 16 ; size <= 32 ; size += 16) {
- pixmap = loadIconFromShell32(235, size);
- icon.addPixmap(pixmap, QIcon::Normal);
- }
- break;
- }
- case SP_DirIcon:
- for (int size = 16 ; size <= 32 ; size += 16) {
- pixmap = loadIconFromShell32(4, size);
- icon.addPixmap(pixmap, QIcon::Normal, QIcon::Off);
- pixmap = loadIconFromShell32(5, size);
- icon.addPixmap(pixmap, QIcon::Normal, QIcon::On);
- }
- break;
- case SP_DirLinkIcon:
- for (int size = 16 ; size <= 32 ; size += 16) {
- QPixmap link = loadIconFromShell32(30, size);
- pixmap = loadIconFromShell32(4, size);
- if (!pixmap.isNull() && !link.isNull()) {
- QPainter painter(&pixmap);
- painter.drawPixmap(0, 0, size, size, link);
- icon.addPixmap(pixmap, QIcon::Normal, QIcon::Off);
- }
- link = loadIconFromShell32(30, size);
- pixmap = loadIconFromShell32(5, size);
- if (!pixmap.isNull() && !link.isNull()) {
- QPainter painter(&pixmap);
- painter.drawPixmap(0, 0, size, size, link);
- icon.addPixmap(pixmap, QIcon::Normal, QIcon::On);
- }
- }
- break;
- case SP_FileIcon:
- for (int size = 16 ; size <= 32 ; size += 16) {
- pixmap = loadIconFromShell32(1, size);
- icon.addPixmap(pixmap, QIcon::Normal);
- }
- break;
- case SP_ComputerIcon:
- for (int size = 16 ; size <= 32 ; size += 16) {
- pixmap = loadIconFromShell32(16, size);
- icon.addPixmap(pixmap, QIcon::Normal);
- }
- break;
-
- case SP_DesktopIcon:
- for (int size = 16 ; size <= 32 ; size += 16) {
- pixmap = loadIconFromShell32(35, size);
- icon.addPixmap(pixmap, QIcon::Normal);
- }
- break;
- case SP_DriveCDIcon:
- case SP_DriveDVDIcon:
- for (int size = 16 ; size <= 32 ; size += 16) {
- pixmap = loadIconFromShell32(12, size);
- icon.addPixmap(pixmap, QIcon::Normal);
- }
- break;
- case SP_DriveNetIcon:
- for (int size = 16 ; size <= 32 ; size += 16) {
- pixmap = loadIconFromShell32(10, size);
- icon.addPixmap(pixmap, QIcon::Normal);
- }
- break;
- case SP_DriveHDIcon:
- for (int size = 16 ; size <= 32 ; size += 16) {
- pixmap = loadIconFromShell32(9, size);
- icon.addPixmap(pixmap, QIcon::Normal);
- }
- break;
- case SP_DriveFDIcon:
- for (int size = 16 ; size <= 32 ; size += 16) {
- pixmap = loadIconFromShell32(7, size);
- icon.addPixmap(pixmap, QIcon::Normal);
- }
- break;
- case SP_FileLinkIcon:
- for (int size = 16 ; size <= 32 ; size += 16) {
- QPixmap link;
- link = loadIconFromShell32(30, size);
- pixmap = loadIconFromShell32(1, size);
- if (!pixmap.isNull() && !link.isNull()) {
- QPainter painter(&pixmap);
- painter.drawPixmap(0, 0, size, size, link);
- icon.addPixmap(pixmap, QIcon::Normal);
- }
- }
- break;
- case SP_VistaShield:
- {
- if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA
- && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based
- && pSHGetStockIconInfo)
- {
- icon.addPixmap(proxy()->standardPixmap(SP_VistaShield, option, widget)); //fetches small icon
- QSHSTOCKICONINFO iconInfo; //append large icon
- memset(&iconInfo, 0, sizeof(iconInfo));
- iconInfo.cbSize = sizeof(iconInfo);
- if (pSHGetStockIconInfo(_SIID_SHIELD, _SHGFI_ICON | _SHGFI_LARGEICON, &iconInfo) == S_OK) {
- icon.addPixmap(QPixmap::fromWinHICON(iconInfo.hIcon));
- DestroyIcon(iconInfo.hIcon);
- }
- }
- }
- break;
- default:
- break;
- }
-#endif
-
- if (icon.isNull())
- icon = QCommonStyle::standardIconImplementation(standardIcon, option, widget);
- return icon;
-}
-
-
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_STYLE_WINDOWS
diff --git a/src/gui/styles/qwindowsstyle.h b/src/gui/styles/qwindowsstyle.h
deleted file mode 100644
index ecc6e2f2fb..0000000000
--- a/src/gui/styles/qwindowsstyle.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWINDOWSSTYLE_H
-#define QWINDOWSSTYLE_H
-
-#include <QtGui/qcommonstyle.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#if !defined(QT_NO_STYLE_WINDOWS)
-
-class QWindowsStylePrivate;
-
-class Q_GUI_EXPORT QWindowsStyle : public QCommonStyle
-{
- Q_OBJECT
-public:
- QWindowsStyle();
- ~QWindowsStyle();
-
- void polish(QApplication*);
- void unpolish(QApplication*);
-
- void polish(QWidget*);
- void unpolish(QWidget*);
-
- void polish(QPalette &);
-
- void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p,
- const QWidget *w = 0) const;
- void drawControl(ControlElement element, const QStyleOption *opt, QPainter *p,
- const QWidget *w = 0) const;
- QRect subElementRect(SubElement r, const QStyleOption *opt, const QWidget *widget = 0) const;
- void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p,
- const QWidget *w = 0) const;
- QSize sizeFromContents(ContentsType ct, const QStyleOption *opt,
- const QSize &contentsSize, const QWidget *widget = 0) const;
-
- int pixelMetric(PixelMetric pm, const QStyleOption *option = 0, const QWidget *widget = 0) const;
-
- int styleHint(StyleHint hint, const QStyleOption *opt = 0, const QWidget *widget = 0,
- QStyleHintReturn *returnData = 0) const;
-
- QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt,
- const QWidget *widget = 0) const;
-
-protected Q_SLOTS:
- QIcon standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *option,
- const QWidget *widget = 0) const;
-
-protected:
- bool eventFilter(QObject *o, QEvent *e);
- void timerEvent(QTimerEvent *event);
- QWindowsStyle(QWindowsStylePrivate &dd);
-
-private:
- Q_DISABLE_COPY(QWindowsStyle)
- Q_DECLARE_PRIVATE(QWindowsStyle)
- void *reserved;
-};
-
-#endif // QT_NO_STYLE_WINDOWS
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QWINDOWSSTYLE_H
diff --git a/src/gui/styles/qwindowsvistastyle.cpp b/src/gui/styles/qwindowsvistastyle.cpp
deleted file mode 100644
index da484bafe1..0000000000
--- a/src/gui/styles/qwindowsvistastyle.cpp
+++ /dev/null
@@ -1,2669 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qwindowsvistastyle.h"
-#include "qwindowsvistastyle_p.h"
-#include <private/qstylehelper_p.h>
-#include <private/qsystemlibrary_p.h>
-
-#if !defined(QT_NO_STYLE_WINDOWSVISTA) || defined(QT_PLUGIN)
-
-QT_BEGIN_NAMESPACE
-
-static const int windowsItemFrame = 2; // menu item frame width
-static const int windowsItemHMargin = 3; // menu item hor text margin
-static const int windowsItemVMargin = 4; // menu item ver text margin
-static const int windowsArrowHMargin = 6; // arrow horizontal margin
-static const int windowsRightBorder = 15; // right border on windows
-
-#ifndef TMT_CONTENTMARGINS
-# define TMT_CONTENTMARGINS 3602
-#endif
-#ifndef TMT_SIZINGMARGINS
-# define TMT_SIZINGMARGINS 3601
-#endif
-#ifndef LISS_NORMAL
-# define LISS_NORMAL 1
-# define LISS_HOT 2
-# define LISS_SELECTED 3
-# define LISS_DISABLED 4
-# define LISS_SELECTEDNOTFOCUS 5
-# define LISS_HOTSELECTED 6
-#endif
-#ifndef BP_COMMANDLINK
-# define BP_COMMANDLINK 6
-# define BP_COMMANDLINKGLYPH 7
-# define CMDLGS_NORMAL 1
-# define CMDLGS_HOT 2
-# define CMDLGS_PRESSED 3
-# define CMDLGS_DISABLED 4
-#endif
-
-// Runtime resolved theme engine function calls
-
-
-typedef HRESULT (WINAPI *PtrGetThemePartSize)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, OPTIONAL RECT *prc, enum THEMESIZE eSize, OUT SIZE *psz);
-typedef HTHEME (WINAPI *PtrOpenThemeData)(HWND hwnd, LPCWSTR pszClassList);
-typedef HTHEME (WINAPI *PtrOpenThemeData)(HWND hwnd, LPCWSTR pszClassList);
-typedef HRESULT (WINAPI *PtrCloseThemeData)(HTHEME hTheme);
-typedef HRESULT (WINAPI *PtrDrawThemeBackground)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, OPTIONAL const RECT *pClipRect);
-typedef HRESULT (WINAPI *PtrDrawThemeBackgroundEx)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, OPTIONAL const DTBGOPTS *pOptions);
-typedef HRESULT (WINAPI *PtrGetCurrentThemeName)(OUT LPWSTR pszThemeFileName, int cchMaxNameChars, OUT OPTIONAL LPWSTR pszColorBuff, int cchMaxColorChars, OUT OPTIONAL LPWSTR pszSizeBuff, int cchMaxSizeChars);
-typedef HRESULT (WINAPI *PtrGetThemeBool)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT BOOL *pfVal);
-typedef HRESULT (WINAPI *PtrGetThemeColor)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT COLORREF *pColor);
-typedef HRESULT (WINAPI *PtrGetThemeEnumValue)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT int *piVal);
-typedef HRESULT (WINAPI *PtrGetThemeFilename)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT LPWSTR pszThemeFileName, int cchMaxBuffChars);
-typedef HRESULT (WINAPI *PtrGetThemeFont)(HTHEME hTheme, OPTIONAL HDC hdc, int iPartId, int iStateId, int iPropId, OUT LOGFONT *pFont);
-typedef HRESULT (WINAPI *PtrGetThemeInt)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT int *piVal);
-typedef HRESULT (WINAPI *PtrGetThemeIntList)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT INTLIST *pIntList);
-typedef HRESULT (WINAPI *PtrGetThemeMargins)(HTHEME hTheme, OPTIONAL HDC hdc, int iPartId, int iStateId, int iPropId, OPTIONAL RECT *prc, OUT MARGINS *pMargins);
-typedef HRESULT (WINAPI *PtrGetThemeMetric)(HTHEME hTheme, OPTIONAL HDC hdc, int iPartId, int iStateId, int iPropId, OUT int *piVal);
-typedef HRESULT (WINAPI *PtrGetThemePartSize)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, OPTIONAL RECT *prc, enum THEMESIZE eSize, OUT SIZE *psz);
-typedef HRESULT (WINAPI *PtrGetThemePosition)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT POINT *pPoint);
-typedef HRESULT (WINAPI *PtrGetThemeRect)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT RECT *pRect);
-typedef HRESULT (WINAPI *PtrGetThemeString)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT LPWSTR pszBuff, int cchMaxBuffChars);
-typedef HRESULT (WINAPI *PtrGetThemeTransitionDuration)(HTHEME hTheme, int iPartId, int iStateFromId, int iStateToId, int iPropId, int *pDuration);
-typedef HRESULT (WINAPI *PtrIsThemePartDefined)(HTHEME hTheme, int iPartId, int iStateId);
-typedef HRESULT (WINAPI *PtrSetWindowTheme)(HWND hwnd, LPCWSTR pszSubAppName, LPCWSTR pszSubIdList);
-typedef HRESULT (WINAPI *PtrGetThemePropertyOrigin)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT enum PROPERTYORIGIN *pOrigin);
-
-static PtrIsThemePartDefined pIsThemePartDefined = 0;
-static PtrOpenThemeData pOpenThemeData = 0;
-static PtrCloseThemeData pCloseThemeData = 0;
-static PtrDrawThemeBackground pDrawThemeBackground = 0;
-static PtrDrawThemeBackgroundEx pDrawThemeBackgroundEx = 0;
-static PtrGetCurrentThemeName pGetCurrentThemeName = 0;
-static PtrGetThemeBool pGetThemeBool = 0;
-static PtrGetThemeColor pGetThemeColor = 0;
-static PtrGetThemeEnumValue pGetThemeEnumValue = 0;
-static PtrGetThemeFilename pGetThemeFilename = 0;
-static PtrGetThemeFont pGetThemeFont = 0;
-static PtrGetThemeInt pGetThemeInt = 0;
-static PtrGetThemeIntList pGetThemeIntList = 0;
-static PtrGetThemeMargins pGetThemeMargins = 0;
-static PtrGetThemeMetric pGetThemeMetric = 0;
-static PtrGetThemePartSize pGetThemePartSize = 0;
-static PtrGetThemePosition pGetThemePosition = 0;
-static PtrGetThemeRect pGetThemeRect = 0;
-static PtrGetThemeString pGetThemeString = 0;
-static PtrGetThemeTransitionDuration pGetThemeTransitionDuration= 0;
-static PtrSetWindowTheme pSetWindowTheme = 0;
-static PtrGetThemePropertyOrigin pGetThemePropertyOrigin = 0;
-
-/* \internal
- Checks if we should use Vista style , or if we should
- fall back to Windows style.
-*/
-bool QWindowsVistaStylePrivate::useVista()
-{
- return (QWindowsVistaStylePrivate::useXP() &&
- (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA &&
- QSysInfo::WindowsVersion < QSysInfo::WV_NT_based));
-}
-
-/*!
- \class QWindowsVistaStyle
- \brief The QWindowsVistaStyle class provides a look and feel suitable for applications on Microsoft Windows Vista.
- \since 4.3
- \ingroup appearance
-
- \warning This style is only available on the Windows Vista platform
- because it makes use of Windows Vista's style engine.
-
- \sa QMacStyle, QWindowsXPStyle, QPlastiqueStyle, QCleanlooksStyle, QMotifStyle
-*/
-
-/*!
- Constructs a QWindowsVistaStyle object.
-*/
-QWindowsVistaStyle::QWindowsVistaStyle()
- : QWindowsXPStyle(*new QWindowsVistaStylePrivate)
-{
-}
-
-//convert Qt state flags to uxtheme button states
-static int buttonStateId(int flags, int partId)
-{
- int stateId = 0;
- if (partId == BP_RADIOBUTTON || partId == BP_CHECKBOX) {
- if (!(flags & QStyle::State_Enabled))
- stateId = RBS_UNCHECKEDDISABLED;
- else if (flags & QStyle::State_Sunken)
- stateId = RBS_UNCHECKEDPRESSED;
- else if (flags & QStyle::State_MouseOver)
- stateId = RBS_UNCHECKEDHOT;
- else
- stateId = RBS_UNCHECKEDNORMAL;
-
- if (flags & QStyle::State_On)
- stateId += RBS_CHECKEDNORMAL-1;
-
- } else if (partId == BP_PUSHBUTTON) {
- if (!(flags & QStyle::State_Enabled))
- stateId = PBS_DISABLED;
- else if (flags & (QStyle::State_Sunken | QStyle::State_On))
- stateId = PBS_PRESSED;
- else if (flags & QStyle::State_MouseOver)
- stateId = PBS_HOT;
- else
- stateId = PBS_NORMAL;
- } else {
- Q_ASSERT(1);
- }
- return stateId;
-}
-
-void QWindowsVistaAnimation::paint(QPainter *painter, const QStyleOption *option)
-{
- Q_UNUSED(option);
- Q_UNUSED(painter);
-}
-
-/*! \internal
-
- Helperfunction to paint the current transition state between two
- animation frames.
-
- The result is a blended image consisting of ((alpha)*_primaryImage)
- + ((1-alpha)*_secondaryImage)
-
-*/
-void QWindowsVistaAnimation::drawBlendedImage(QPainter *painter, QRect rect, float alpha) {
- if (_secondaryImage.isNull() || _primaryImage.isNull())
- return;
-
- if (_tempImage.isNull())
- _tempImage = _secondaryImage;
-
- const int a = qRound(alpha*256);
- const int ia = 256 - a;
- const int sw = _primaryImage.width();
- const int sh = _primaryImage.height();
- const int bpl = _primaryImage.bytesPerLine();
- switch(_primaryImage.depth()) {
- case 32:
- {
- uchar *mixed_data = _tempImage.bits();
- const uchar *back_data = _primaryImage.bits();
- const uchar *front_data = _secondaryImage.bits();
- for (int sy = 0; sy < sh; sy++) {
- quint32* mixed = (quint32*)mixed_data;
- const quint32* back = (const quint32*)back_data;
- const quint32* front = (const quint32*)front_data;
- for (int sx = 0; sx < sw; sx++) {
- quint32 bp = back[sx];
- quint32 fp = front[sx];
- mixed[sx] = qRgba ((qRed(bp)*ia + qRed(fp)*a)>>8,
- (qGreen(bp)*ia + qGreen(fp)*a)>>8,
- (qBlue(bp)*ia + qBlue(fp)*a)>>8,
- (qAlpha(bp)*ia + qAlpha(fp)*a)>>8);
- }
- mixed_data += bpl;
- back_data += bpl;
- front_data += bpl;
- }
- }
- default:
- break;
- }
- painter->drawImage(rect, _tempImage);
-}
-
-/*! \internal
- Paints a transition state. The result will be a mix between the
- initial and final state of the transition, depending on the time
- difference between _startTime and current time.
-*/
-void QWindowsVistaTransition::paint(QPainter *painter, const QStyleOption *option)
-{
- float alpha = 1.0;
- if (_duration > 0) {
- QTime current = QTime::currentTime();
-
- if (_startTime > current)
- _startTime = current;
-
- int timeDiff = _startTime.msecsTo(current);
- alpha = timeDiff/(float)_duration;
- if (timeDiff > _duration) {
- _running = false;
- alpha = 1.0;
- }
- }
- else {
- _running = false;
- }
- drawBlendedImage(painter, option->rect, alpha);
-}
-
-/*! \internal
- Paints a pulse. The result will be a mix between the primary and
- secondary pulse images depending on the time difference between
- _startTime and current time.
-*/
-void QWindowsVistaPulse::paint(QPainter *painter, const QStyleOption *option)
-{
- float alpha = 1.0;
- if (_duration > 0) {
- QTime current = QTime::currentTime();
-
- if (_startTime > current)
- _startTime = current;
-
- int timeDiff = _startTime.msecsTo(current) % _duration*2;
- if (timeDiff > _duration)
- timeDiff = _duration*2 - timeDiff;
- alpha = timeDiff/(float)_duration;
- } else {
- _running = false;
- }
- drawBlendedImage(painter, option->rect, alpha);
-}
-
-
-/*!
- \internal
-
- Animations are used for some state transitions on specific widgets.
-
- Only one running animation can exist for a widget at any specific
- time. Animations can be added through
- QWindowsVistaStylePrivate::startAnimation(Animation *) and any
- existing animation on a widget can be retrieved with
- QWindowsVistaStylePrivate::widgetAnimation(Widget *).
-
- Once an animation has been started,
- QWindowsVistaStylePrivate::timerEvent(QTimerEvent *) will
- continuously call update() on the widget until it is stopped,
- meaning that drawPrimitive will be called many times until the
- transition has completed. During this time, the result will be
- retrieved by the Animation::paint(...) function and not by the style
- itself.
-
- To determine if a transition should occur, the style needs to know
- the previous state of the widget as well as the current one. This is
- solved by updating dynamic properties on the widget every time the
- function is called.
-
- Transitions interrupting existing transitions should always be
- smooth, so whenever a hover-transition is started on a pulsating
- button, it uses the current frame of the pulse-animation as the
- starting image for the hover transition.
-
- */
-void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option,
- QPainter *painter, const QWidget *widget) const
-{
- QWindowsVistaStylePrivate *d = const_cast<QWindowsVistaStylePrivate*>(d_func());
-
- int state = option->state;
- if (!QWindowsVistaStylePrivate::useVista()) {
- QWindowsStyle::drawPrimitive(element, option, painter, widget);
- return;
- }
-
- QRect oldRect;
- QRect newRect;
-
- if (widget && d->transitionsEnabled())
- {
- /* all widgets that supports state transitions : */
- if (
-#ifndef QT_NO_LINEEDIT
- (qobject_cast<const QLineEdit*>(widget) && element == PE_FrameLineEdit) ||
-#endif // QT_NO_LINEEDIT
- (qobject_cast<const QRadioButton*>(widget)&& element == PE_IndicatorRadioButton) ||
- (qobject_cast<const QCheckBox*>(widget) && element == PE_IndicatorCheckBox) ||
- (qobject_cast<const QGroupBox *>(widget)&& element == PE_IndicatorCheckBox) ||
- (qobject_cast<const QToolButton*>(widget) && element == PE_PanelButtonBevel)
- )
- {
- // Retrieve and update the dynamic properties tracking
- // the previous state of the widget:
- QWidget *w = const_cast<QWidget *> (widget);
- int oldState = w->property("_q_stylestate").toInt();
- oldRect = w->property("_q_stylerect").toRect();
- newRect = w->rect();
- w->setProperty("_q_stylestate", (int)option->state);
- w->setProperty("_q_stylerect", w->rect());
-
- bool doTransition = oldState &&
- ((state & State_Sunken) != (oldState & State_Sunken) ||
- (state & State_On) != (oldState & State_On) ||
- (state & State_MouseOver) != (oldState & State_MouseOver));
-
- if (oldRect != newRect ||
- (state & State_Enabled) != (oldState & State_Enabled) ||
- (state & State_Active) != (oldState & State_Active))
- d->stopAnimation(widget);
-
-#ifndef QT_NO_LINEEDIT
- if (const QLineEdit *edit = qobject_cast<const QLineEdit *>(widget))
- if (edit->isReadOnly() && element == PE_FrameLineEdit) // Do not animate read only line edits
- doTransition = false;
-#endif // QT_NO_LINEEDIT
-
- if (doTransition) {
-
- // We create separate images for the initial and final transition states and store them in the
- // Transition object.
- QImage startImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
- QImage endImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
- QStyleOption opt = *option;
-
- opt.rect.setRect(0, 0, option->rect.width(), option->rect.height());
- opt.state = (QStyle::State)oldState;
- startImage.fill(0);
- QPainter startPainter(&startImage);
-
- QWindowsVistaAnimation *anim = d->widgetAnimation(widget);
- QWindowsVistaTransition *t = new QWindowsVistaTransition;
- t->setWidget(w);
-
- // If we have a running animation on the widget already, we will use that to paint the initial
- // state of the new transition, this ensures a smooth transition from a current animation such as a
- // pulsating default button into the intended target state.
-
- if (!anim)
- proxy()->drawPrimitive(element, &opt, &startPainter, 0); // Note that the widget pointer is intentionally 0
- else // this ensures that we do not recurse in the animation logic above
- anim->paint(&startPainter, &opt);
-
- d->startAnimation(t);
- t->setStartImage(startImage);
-
- // The end state of the transition is simply the result we would have painted
- // if the style was not animated.
-
- QPainter endPainter(&endImage);
- endImage.fill(0);
- QStyleOption opt2 = opt;
- opt2.state = option->state;
- proxy()->drawPrimitive(element, &opt2, &endPainter, 0); // Note that the widget pointer is intentionally 0
- // this ensures that we do not recurse in the animation logic above
- t->setEndImage(endImage);
-
- HTHEME theme;
- int partId;
- int duration;
- int fromState = 0;
- int toState = 0;
-
- //translate state flags to UXTHEME states :
- if (element == PE_FrameLineEdit) {
- theme = pOpenThemeData(0, L"Edit");
- partId = EP_EDITBORDER_NOSCROLL;
-
- if (oldState & State_MouseOver)
- fromState = ETS_HOT;
- else if (oldState & State_HasFocus)
- fromState = ETS_FOCUSED;
- else
- fromState = ETS_NORMAL;
-
- if (state & State_MouseOver)
- toState = ETS_HOT;
- else if (state & State_HasFocus)
- toState = ETS_FOCUSED;
- else
- toState = ETS_NORMAL;
-
- } else {
- theme = pOpenThemeData(0, L"Button");
- if (element == PE_IndicatorRadioButton)
- partId = BP_RADIOBUTTON;
- else if (element == PE_IndicatorCheckBox)
- partId = BP_CHECKBOX;
- else
- partId = BP_PUSHBUTTON;
-
- fromState = buttonStateId(oldState, partId);
- toState = buttonStateId(option->state, partId);
- }
-
- // Retrieve the transition time between the states from the system.
- if (theme && pGetThemeTransitionDuration(theme, partId, fromState, toState,
- TMT_TRANSITIONDURATIONS, &duration) == S_OK)
- {
- t->setDuration(duration);
- }
- t->setStartTime(QTime::currentTime());
- }
- }
- } // End of animation part
-
-
- QRect rect = option->rect;
-
- switch (element) {
- case PE_IndicatorHeaderArrow:
- if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
- int stateId = HSAS_SORTEDDOWN;
- if (header->sortIndicator & QStyleOptionHeader::SortDown)
- stateId = HSAS_SORTEDUP; //note that the uxtheme sort down indicator is the inverse of ours
- XPThemeData theme(widget, painter, QLatin1String("HEADER"), HP_HEADERSORTARROW, stateId, option->rect);
- d->drawBackground(theme);
- }
- break;
-
- case PE_IndicatorBranch:
- {
- XPThemeData theme(d->treeViewHelper(), painter, QLatin1String("TREEVIEW"));
- static int decoration_size = 0;
- if (theme.isValid() && !decoration_size) {
- SIZE size;
- pGetThemePartSize(theme.handle(), 0, TVP_HOTGLYPH, GLPS_OPENED, 0, TS_TRUE, &size);
- decoration_size = qMax(size.cx, size.cy);
- }
- int mid_h = option->rect.x() + option->rect.width() / 2;
- int mid_v = option->rect.y() + option->rect.height() / 2;
- int bef_h = mid_h;
- int bef_v = mid_v;
- int aft_h = mid_h;
- int aft_v = mid_v;
- if (option->state & State_Children) {
- int delta = decoration_size / 2;
- theme.rect = QRect(bef_h - delta, bef_v - delta, decoration_size, decoration_size);
- theme.partId = option->state & State_MouseOver ? TVP_HOTGLYPH : TVP_GLYPH;
- theme.stateId = option->state & QStyle::State_Open ? GLPS_OPENED : GLPS_CLOSED;
- if (option->direction == Qt::RightToLeft)
- theme.mirrorHorizontally = true;
- d->drawBackground(theme);
- bef_h -= delta + 2;
- bef_v -= delta + 2;
- aft_h += delta - 2;
- aft_v += delta - 2;
- }
-#if 0
- QBrush brush(option->palette.dark().color(), Qt::Dense4Pattern);
- if (option->state & State_Item) {
- if (option->direction == Qt::RightToLeft)
- painter->fillRect(option->rect.left(), mid_v, bef_h - option->rect.left(), 1, brush);
- else
- painter->fillRect(aft_h, mid_v, option->rect.right() - aft_h + 1, 1, brush);
- }
- if (option->state & State_Sibling && option->rect.bottom() > aft_v)
- painter->fillRect(mid_h, aft_v, 1, option->rect.bottom() - aft_v + 1, brush);
- if (option->state & (State_Open | State_Children | State_Item | State_Sibling) && (bef_v > option->rect.y()))
- painter->fillRect(mid_h, option->rect.y(), 1, bef_v - option->rect.y(), brush);
-#endif
- }
- break;
-
- case PE_PanelButtonBevel:
- case PE_IndicatorCheckBox:
- case PE_IndicatorRadioButton:
- {
- if (QWindowsVistaAnimation *a = d->widgetAnimation(widget)) {
- a->paint(painter, option);
- } else {
- QWindowsXPStyle::drawPrimitive(element, option, painter, widget);
- }
- }
- break;
-
- case PE_FrameMenu:
- {
- int stateId = option->state & State_Active ? MB_ACTIVE : MB_INACTIVE;
- XPThemeData theme(widget, painter, QLatin1String("MENU"), MENU_POPUPBORDERS, stateId, option->rect);
- d->drawBackground(theme);
- }
- break;
- case PE_Frame:
-#ifndef QT_NO_TEXTEDIT
- if (const QTextEdit *edit = qobject_cast<const QTextEdit*>(widget)) {
- painter->save();
- int stateId = ETS_NORMAL;
- if (!(state & State_Enabled))
- stateId = ETS_DISABLED;
- else if (edit->isReadOnly())
- stateId = ETS_READONLY;
- else if (state & State_HasFocus)
- stateId = ETS_SELECTED;
- XPThemeData theme(widget, painter, QLatin1String("EDIT"), EP_EDITBORDER_HVSCROLL, stateId, option->rect);
- uint resolve_mask = option->palette.resolve();
- if (resolve_mask & (1 << QPalette::Base)) {
- // Since EP_EDITBORDER_HVSCROLL does not us borderfill, theme.noContent cannot be used for clipping
- int borderSize = 1;
- pGetThemeInt(theme.handle(), theme.partId, theme.stateId, TMT_BORDERSIZE, &borderSize);
- QRegion clipRegion = option->rect;
- QRegion content = option->rect.adjusted(borderSize, borderSize, -borderSize, -borderSize);
- clipRegion ^= content;
- painter->setClipRegion(clipRegion);
- }
- d->drawBackground(theme);
- painter->restore();
- } else
-#endif // QT_NO_TEXTEDIT
- QWindowsXPStyle::drawPrimitive(element, option, painter, widget);
- break;
-
- case PE_PanelLineEdit:
- if (const QStyleOptionFrame *panel = qstyleoption_cast<const QStyleOptionFrame *>(option)) {
- QBrush bg;
- bool usePalette = false;
- bool isEnabled = option->state & State_Enabled;
- uint resolve_mask = panel->palette.resolve();
- if (widget) {
- //Since spin box and combo box includes a line edit we need to resolve the palette on the parent instead
-#ifndef QT_NO_SPINBOX
- if (QAbstractSpinBox *spinbox = qobject_cast<QAbstractSpinBox*>(widget->parentWidget()))
- resolve_mask = spinbox->palette().resolve();
-#endif // QT_NO_SPINBOX
- }
- if (resolve_mask & (1 << QPalette::Base)) {
- // Base color is set for this widget, so use it
- bg = panel->palette.brush(QPalette::Base);
- usePalette = true;
- }
- if (usePalette) {
- painter->fillRect(panel->rect, bg);
- } else {
- int partId = EP_BACKGROUND;
- int stateId = EBS_NORMAL;
- if (!isEnabled)
- stateId = EBS_DISABLED;
- else if (state & State_ReadOnly)
- stateId = EBS_READONLY;
- else if (state & State_MouseOver)
- stateId = EBS_HOT;
-
- XPThemeData theme(0, painter, QLatin1String("EDIT"), partId, stateId, rect);
- if (!theme.isValid()) {
- QWindowsStyle::drawPrimitive(element, option, painter, widget);
- return;
- }
- int bgType;
- pGetThemeEnumValue( theme.handle(),
- partId,
- stateId,
- TMT_BGTYPE,
- &bgType);
- if( bgType == BT_IMAGEFILE ) {
- d->drawBackground(theme);
- } else {
- QBrush fillColor = option->palette.brush(QPalette::Base);
- if (!isEnabled) {
- PROPERTYORIGIN origin = PO_NOTFOUND;
- pGetThemePropertyOrigin(theme.handle(), theme.partId, theme.stateId, TMT_FILLCOLOR, &origin);
- // Use only if the fill property comes from our part
- if ((origin == PO_PART || origin == PO_STATE)) {
- COLORREF bgRef;
- pGetThemeColor(theme.handle(), partId, stateId, TMT_FILLCOLOR, &bgRef);
- fillColor = QBrush(qRgb(GetRValue(bgRef), GetGValue(bgRef), GetBValue(bgRef)));
- }
- }
- painter->fillRect(option->rect, fillColor);
- }
- }
- if (panel->lineWidth > 0)
- proxy()->drawPrimitive(PE_FrameLineEdit, panel, painter, widget);
- return;
- }
- break;
-
- case PE_FrameLineEdit:
- if (QWindowsVistaAnimation *anim = d->widgetAnimation(widget)) {
- anim->paint(painter, option);
- } else {
- QPainter *p = painter;
- QWidget *parentWidget = 0;
- if (widget) {
- parentWidget = widget->parentWidget();
- if (parentWidget)
- parentWidget = parentWidget->parentWidget();
- }
- if (widget && widget->inherits("QLineEdit")
- && parentWidget && parentWidget->inherits("QAbstractItemView")) {
- // we try to check if this lineedit is a delegate on a QAbstractItemView-derived class.
- QPen oldPen = p->pen();
- // Inner white border
- p->setPen(QPen(option->palette.base().color(), 1));
- p->drawRect(option->rect.adjusted(1, 1, -2, -2));
- // Outer dark border
- p->setPen(QPen(option->palette.shadow().color(), 1));
- p->drawRect(option->rect.adjusted(0, 0, -1, -1));
- p->setPen(oldPen);
- return;
- } else {
- int stateId = ETS_NORMAL;
- if (!(state & State_Enabled))
- stateId = ETS_DISABLED;
- else if (state & State_ReadOnly)
- stateId = ETS_READONLY;
- else if (state & State_MouseOver)
- stateId = ETS_HOT;
- else if (state & State_HasFocus)
- stateId = ETS_SELECTED;
- XPThemeData theme(widget, painter, QLatin1String("EDIT"), EP_EDITBORDER_NOSCROLL, stateId, option->rect);
- painter->save();
- QRegion clipRegion = option->rect;
- clipRegion -= option->rect.adjusted(2, 2, -2, -2);
- painter->setClipRegion(clipRegion);
- d->drawBackground(theme);
- painter->restore();
- }
- }
- break;
-
- case PE_IndicatorToolBarHandle:
- {
- XPThemeData theme;
- QRect rect;
- if (option->state & State_Horizontal) {
- theme = XPThemeData(widget, painter, QLatin1String("REBAR"), RP_GRIPPER, ETS_NORMAL, option->rect.adjusted(0, 1, -2, -2));
- rect = option->rect.adjusted(0, 1, 0, -2);
- rect.setWidth(4);
- } else {
- theme = XPThemeData(widget, painter, QLatin1String("REBAR"), RP_GRIPPERVERT, ETS_NORMAL, option->rect.adjusted(0, 1, -2, -2));
- rect = option->rect.adjusted(1, 0, -1, 0);
- rect.setHeight(4);
- }
- theme.rect = rect;
- d->drawBackground(theme);
- }
- break;
-
- case PE_IndicatorToolBarSeparator:
- {
- QPen pen = painter->pen();
- int margin = 3;
- painter->setPen(option->palette.background().color().darker(114));
- if (option->state & State_Horizontal) {
- int x1 = option->rect.center().x();
- painter->drawLine(QPoint(x1, option->rect.top() + margin), QPoint(x1, option->rect.bottom() - margin));
- } else {
- int y1 = option->rect.center().y();
- painter->drawLine(QPoint(option->rect.left() + margin, y1), QPoint(option->rect.right() - margin, y1));
- }
- painter->setPen(pen);
- }
- break;
-
- case PE_PanelTipLabel: {
- XPThemeData theme(widget, painter, QLatin1String("TOOLTIP"), TTP_STANDARD, TTSS_NORMAL, option->rect);
- d->drawBackground(theme);
- break;
- }
-
- case PE_PanelItemViewItem:
- {
- const QStyleOptionViewItemV4 *vopt;
- const QAbstractItemView *view = qobject_cast<const QAbstractItemView *>(widget);
- bool newStyle = true;
-
- if (qobject_cast<const QTableView*>(widget))
- newStyle = false;
-
- if (newStyle && view && (vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(option))) {
- bool selected = vopt->state & QStyle::State_Selected;
- bool hover = vopt->state & QStyle::State_MouseOver;
- bool active = vopt->state & QStyle::State_Active;
-
- if (vopt->features & QStyleOptionViewItemV2::Alternate)
- painter->fillRect(vopt->rect, vopt->palette.alternateBase());
-
- QPalette::ColorGroup cg = vopt->state & QStyle::State_Enabled
- ? QPalette::Normal : QPalette::Disabled;
- if (cg == QPalette::Normal && !(vopt->state & QStyle::State_Active))
- cg = QPalette::Inactive;
-
- QRect textRect = subElementRect(QStyle::SE_ItemViewItemText, option, widget);
- QRect itemRect = subElementRect(QStyle::SE_ItemViewItemFocusRect, option, widget).adjusted(-1, 0, 1, 0);
- itemRect.setTop(vopt->rect.top());
- itemRect.setBottom(vopt->rect.bottom());
-
- QSize sectionSize = itemRect.size();
- if (vopt->showDecorationSelected)
- sectionSize = vopt->rect.size();
-
- if (view->selectionBehavior() == QAbstractItemView::SelectRows)
- sectionSize.setWidth(vopt->rect.width());
- if (view->selectionMode() == QAbstractItemView::NoSelection)
- hover = false;
- QPixmap pixmap;
-
- if (vopt->backgroundBrush.style() != Qt::NoBrush) {
- QPointF oldBO = painter->brushOrigin();
- painter->setBrushOrigin(vopt->rect.topLeft());
- painter->fillRect(vopt->rect, vopt->backgroundBrush);
- }
-
- if (hover || selected) {
- QString key = QString::fromLatin1("qvdelegate-%1-%2-%3-%4-%5").arg(sectionSize.width())
- .arg(sectionSize.height()).arg(selected).arg(active).arg(hover);
- if (!QPixmapCache::find(key, pixmap)) {
- pixmap = QPixmap(sectionSize);
- pixmap.fill(Qt::transparent);
-
- int state;
- if (selected && hover)
- state = LISS_HOTSELECTED;
- else if (selected && !active)
- state = LISS_SELECTEDNOTFOCUS;
- else if (selected)
- state = LISS_SELECTED;
- else
- state = LISS_HOT;
-
- QPainter pixmapPainter(&pixmap);
- XPThemeData theme(d->treeViewHelper(), &pixmapPainter, QLatin1String("TREEVIEW"),
- LVP_LISTITEM, state, QRect(0, 0, sectionSize.width(), sectionSize.height()));
- if (theme.isValid()) {
- d->drawBackground(theme);
- } else {
- QWindowsXPStyle::drawPrimitive(PE_PanelItemViewItem, option, painter, widget);
- break;;
- }
- QPixmapCache::insert(key, pixmap);
- }
-
- if (vopt->showDecorationSelected) {
- const int frame = 2; //Assumes a 2 pixel pixmap border
- QRect srcRect = QRect(0, 0, sectionSize.width(), sectionSize.height());
- QRect pixmapRect = vopt->rect;
- bool reverse = vopt->direction == Qt::RightToLeft;
- bool leftSection = vopt->viewItemPosition == QStyleOptionViewItemV4::Beginning;
- bool rightSection = vopt->viewItemPosition == QStyleOptionViewItemV4::End;
- if (vopt->viewItemPosition == QStyleOptionViewItemV4::OnlyOne
- || vopt->viewItemPosition == QStyleOptionViewItemV4::Invalid)
- painter->drawPixmap(pixmapRect.topLeft(), pixmap);
- 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 {
- if (vopt->text.isEmpty() && vopt->icon.isNull())
- break;
- painter->drawPixmap(itemRect.topLeft(), pixmap);
- }
- }
- } else {
- QWindowsXPStyle::drawPrimitive(element, option, painter, widget);
- }
- break;
- }
- case PE_Widget:
- {
- const QDialogButtonBox *buttonBox = 0;
-
- if (qobject_cast<const QMessageBox *> (widget))
- buttonBox = widget->findChild<const QDialogButtonBox *>(QLatin1String("qt_msgbox_buttonbox"));
-#ifndef QT_NO_INPUTDIALOG
- else if (qobject_cast<const QInputDialog *> (widget))
- buttonBox = widget->findChild<const QDialogButtonBox *>(QLatin1String("qt_inputdlg_buttonbox"));
-#endif // QT_NO_INPUTDIALOG
-
- if (buttonBox) {
- //draw white panel part
- XPThemeData theme(widget, painter, QLatin1String("TASKDIALOG"), TDLG_PRIMARYPANEL, 0, option->rect);
- QRect toprect = option->rect;
- toprect.setBottom(buttonBox->geometry().top());
- theme.rect = toprect;
- d->drawBackground(theme);
-
- //draw bottom panel part
- QRect buttonRect = option->rect;
- buttonRect.setTop(buttonBox->geometry().top());
- theme.rect = buttonRect;
- theme.partId = TDLG_SECONDARYPANEL;
- d->drawBackground(theme);
- }
- }
- break;
- default:
- QWindowsXPStyle::drawPrimitive(element, option, painter, widget);
- break;
- }
-}
-
-
-/*!
- \internal
-
- see drawPrimitive for comments on the animation support
- */
-void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption *option,
- QPainter *painter, const QWidget *widget) const
-{
- QWindowsVistaStylePrivate *d = const_cast<QWindowsVistaStylePrivate*>(d_func());
-
- if (!QWindowsVistaStylePrivate::useVista()) {
- QWindowsStyle::drawControl(element, option, painter, widget);
- return;
- }
-
- bool selected = option->state & State_Selected;
- bool pressed = option->state & State_Sunken;
- bool disabled = !(option->state & State_Enabled);
-
- int state = option->state;
- QString name;
-
- QRect rect(option->rect);
- State flags = option->state;
- int partId = 0;
- int stateId = 0;
-
- QRect oldRect;
- QRect newRect;
-
- if (d->transitionsEnabled() && widget) {
- if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
- if ((qobject_cast<const QPushButton*>(widget) && element == CE_PushButtonBevel))
- {
- QWidget *w = const_cast<QWidget *> (widget);
- int oldState = w->property("_q_stylestate").toInt();
- oldRect = w->property("_q_stylerect").toRect();
- newRect = w->rect();
- w->setProperty("_q_stylestate", (int)option->state);
- w->setProperty("_q_stylerect", w->rect());
-
- bool wasDefault = w->property("_q_isdefault").toBool();
- bool isDefault = button->features & QStyleOptionButton::DefaultButton;
- w->setProperty("_q_isdefault", isDefault);
-
- bool doTransition = ((state & State_Sunken) != (oldState & State_Sunken) ||
- (state & State_On) != (oldState & State_On) ||
- (state & State_MouseOver) != (oldState & State_MouseOver));
-
- if (oldRect != newRect || (wasDefault && !isDefault))
- {
- doTransition = false;
- d->stopAnimation(widget);
- }
-
- if (doTransition) {
- QImage startImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
- QImage endImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
- QWindowsVistaAnimation *anim = d->widgetAnimation(widget);
-
- QStyleOptionButton opt = *button;
- opt.state = (QStyle::State)oldState;
-
- startImage.fill(0);
- QWindowsVistaTransition *t = new QWindowsVistaTransition;
- t->setWidget(w);
- QPainter startPainter(&startImage);
-
- if (!anim) {
- proxy()->drawControl(element, &opt, &startPainter, 0 /* Intentional */);
- } else {
- anim->paint(&startPainter, &opt);
- d->stopAnimation(widget);
- }
-
- t->setStartImage(startImage);
- d->startAnimation(t);
-
- endImage.fill(0);
- QPainter endPainter(&endImage);
- proxy()->drawControl(element, option, &endPainter, 0 /* Intentional */);
- t->setEndImage(endImage);
- int duration = 0;
- HTHEME theme = pOpenThemeData(0, L"Button");
-
- int fromState = buttonStateId(oldState, BP_PUSHBUTTON);
- int toState = buttonStateId(option->state, BP_PUSHBUTTON);
- if (pGetThemeTransitionDuration(theme, BP_PUSHBUTTON, fromState, toState, TMT_TRANSITIONDURATIONS, &duration) == S_OK)
- t->setDuration(duration);
- else
- t->setDuration(0);
- t->setStartTime(QTime::currentTime());
- }
- }
- }
- }
- switch (element) {
- case CE_PushButtonBevel:
- if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option))
- {
-
- QWindowsVistaAnimation *anim = d->widgetAnimation(widget);
- if (anim && (btn->state & State_Enabled)) {
- anim->paint(painter, option);
- } else {
- name = QLatin1String("BUTTON");
- partId = BP_PUSHBUTTON;
- if (btn->features & QStyleOptionButton::CommandLinkButton)
- partId = BP_COMMANDLINK;
- bool justFlat = (btn->features & QStyleOptionButton::Flat) && !(flags & (State_On|State_Sunken));
- if (!(flags & State_Enabled) && !(btn->features & QStyleOptionButton::Flat))
- stateId = PBS_DISABLED;
- else if (justFlat)
- ;
- else if (flags & (State_Sunken | State_On))
- stateId = PBS_PRESSED;
- else if (flags & State_MouseOver)
- stateId = PBS_HOT;
- else if (btn->features & QStyleOptionButton::DefaultButton && (state & State_Active))
- stateId = PBS_DEFAULTED;
- else
- stateId = PBS_NORMAL;
-
- if (!justFlat) {
-
- if (widget && d->transitionsEnabled() && (btn->features & QStyleOptionButton::DefaultButton) &&
- !(state & (State_Sunken | State_On)) && !(state & State_MouseOver) &&
- (state & State_Enabled) && (state & State_Active))
- {
- if (!anim && widget) {
- QImage startImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
- startImage.fill(0);
- QImage alternateImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
- alternateImage.fill(0);
-
- QWindowsVistaPulse *pulse = new QWindowsVistaPulse;
- pulse->setWidget(const_cast<QWidget*>(widget));
-
- QPainter startPainter(&startImage);
- stateId = PBS_DEFAULTED;
- XPThemeData theme(widget, &startPainter, name, partId, stateId, rect);
- d->drawBackground(theme);
-
- QPainter alternatePainter(&alternateImage);
- theme.stateId = PBS_DEFAULTED_ANIMATING;
- theme.painter = &alternatePainter;
- d->drawBackground(theme);
- pulse->setPrimaryImage(startImage);
- pulse->setAlternateImage(alternateImage);
- pulse->setStartTime(QTime::currentTime());
- pulse->setDuration(2000);
- d->startAnimation(pulse);
- anim = pulse;
- }
-
- if (anim)
- anim->paint(painter, option);
- else {
- XPThemeData theme(widget, painter, name, partId, stateId, rect);
- d->drawBackground(theme);
- }
- }
- else {
- d->stopAnimation(widget);
- XPThemeData theme(widget, painter, name, partId, stateId, rect);
- d->drawBackground(theme);
- }
- }
- }
- if (btn->features & QStyleOptionButton::HasMenu) {
- int mbiw = 0, mbih = 0;
- XPThemeData theme(widget, 0, QLatin1String("TOOLBAR"), TP_DROPDOWNBUTTON);
- if (theme.isValid()) {
- SIZE size;
- if (pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size) == S_OK) {
- mbiw = size.cx;
- mbih = size.cy;
- }
- }
- QRect ir = subElementRect(SE_PushButtonContents, option, 0);
- QStyleOptionButton newBtn = *btn;
- newBtn.rect = QStyle::visualRect(option->direction, option->rect,
- QRect(ir.right() - mbiw - 2,
- option->rect.top() + (option->rect.height()/2) - (mbih/2),
- mbiw + 1, mbih + 1));
- proxy()->drawPrimitive(PE_IndicatorArrowDown, &newBtn, painter, widget);
- }
- return;
- }
- break;
-#ifndef QT_NO_PROGRESSBAR
- case CE_ProgressBarContents:
- if (const QStyleOptionProgressBar *bar
- = qstyleoption_cast<const QStyleOptionProgressBar *>(option)) {
- int stateId = MBI_NORMAL;
- if (disabled)
- stateId = MBI_DISABLED;
- bool isIndeterminate = (bar->minimum == 0 && bar->maximum == 0);
- bool vertical = false;
- bool inverted = false;
- if (const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option)) {
- vertical = (pb2->orientation == Qt::Vertical);
- inverted = pb2->invertedAppearance;
- }
-
- if (const QProgressBar *progressbar = qobject_cast<const QProgressBar *>(widget)) {
- if (isIndeterminate || (progressbar->value() > 0 && (progressbar->value() < progressbar->maximum()) && d->transitionsEnabled())) {
- if (!d->widgetAnimation(progressbar)) {
- QWindowsVistaAnimation *a = new QWindowsVistaAnimation;
- a->setWidget(const_cast<QWidget*>(widget));
- a->setStartTime(QTime::currentTime());
- d->startAnimation(a);
- }
- } else {
- d->stopAnimation(progressbar);
- }
- }
-
- XPThemeData theme(widget, painter, QLatin1String("PROGRESS"), vertical ? PP_FILLVERT : PP_FILL);
- theme.rect = option->rect;
- bool reverse = (bar->direction == Qt::LeftToRight && inverted) || (bar->direction == Qt::RightToLeft && !inverted);
- QTime current = QTime::currentTime();
-
- if (isIndeterminate) {
- if (QWindowsVistaAnimation *a = d->widgetAnimation(widget)) {
- int glowSize = 120;
- int animationWidth = glowSize * 2 + (vertical ? theme.rect.height() : theme.rect.width());
- int animOffset = a->startTime().msecsTo(current) / 4;
- if (animOffset > animationWidth)
- a->setStartTime(QTime::currentTime());
- painter->save();
- painter->setClipRect(theme.rect);
- QRect animRect;
- QSize pixmapSize(14, 14);
- if (vertical) {
- animRect = QRect(theme.rect.left(),
- inverted ? rect.top() - glowSize + animOffset :
- rect.bottom() + glowSize - animOffset,
- rect.width(), glowSize);
- pixmapSize.setHeight(animRect.height());
- } else {
- animRect = QRect(rect.left() - glowSize + animOffset,
- rect.top(), glowSize, rect.height());
- animRect = QStyle::visualRect(reverse ? Qt::RightToLeft : Qt::LeftToRight,
- option->rect, animRect);
- pixmapSize.setWidth(animRect.width());
- }
- QString name = QString::fromLatin1("qiprogress-%1-%2").arg(pixmapSize.width()).arg(pixmapSize.height());
- QPixmap pixmap;
- if (!QPixmapCache::find(name, pixmap)) {
- QImage image(pixmapSize, QImage::Format_ARGB32);
- image.fill(Qt::transparent);
- QPainter imagePainter(&image);
- theme.painter = &imagePainter;
- theme.partId = vertical ? PP_FILLVERT : PP_FILL;
- theme.rect = QRect(QPoint(0,0), theme.rect.size());
- QLinearGradient alphaGradient(0, 0, vertical ? 0 : image.width(),
- vertical ? image.height() : 0);
- alphaGradient.setColorAt(0, QColor(0, 0, 0, 0));
- alphaGradient.setColorAt(0.5, QColor(0, 0, 0, 220));
- alphaGradient.setColorAt(1, QColor(0, 0, 0, 0));
- imagePainter.fillRect(image.rect(), alphaGradient);
- imagePainter.setCompositionMode(QPainter::CompositionMode_SourceIn);
- d->drawBackground(theme);
- imagePainter.end();
- pixmap = QPixmap::fromImage(image);
- QPixmapCache::insert(name, pixmap);
- }
- painter->drawPixmap(animRect, pixmap);
- painter->restore();
- }
- }
- else {
- qint64 progress = qMax<qint64>(bar->progress, bar->minimum); // workaround for bug in QProgressBar
-
- if (vertical) {
- int maxHeight = option->rect.height();
- int minHeight = 0;
- double vc6_workaround = ((progress - qint64(bar->minimum)) / qMax(double(1.0), double(qint64(bar->maximum) - qint64(bar->minimum))) * maxHeight);
- int height = isIndeterminate ? maxHeight: qMax(int(vc6_workaround), minHeight);
- theme.rect.setHeight(height);
- if (!inverted)
- theme.rect.moveTop(rect.height() - theme.rect.height());
- } else {
- int maxWidth = option->rect.width();
- int minWidth = 0;
- double vc6_workaround = ((progress - qint64(bar->minimum)) / qMax(double(1.0), double(qint64(bar->maximum) - qint64(bar->minimum))) * maxWidth);
- int width = isIndeterminate ? maxWidth : qMax(int(vc6_workaround), minWidth);
- theme.rect.setWidth(width);
- theme.rect = QStyle::visualRect(reverse ? Qt::RightToLeft : Qt::LeftToRight,
- option->rect, theme.rect);
- }
- d->drawBackground(theme);
-
- if (QWindowsVistaAnimation *a = d->widgetAnimation(widget)) {
- int glowSize = 140;
- int animationWidth = glowSize * 2 + (vertical ? theme.rect.height() : theme.rect.width());
- int animOffset = a->startTime().msecsTo(current) / 4;
- theme.partId = vertical ? PP_MOVEOVERLAYVERT : PP_MOVEOVERLAY;
- if (animOffset > animationWidth) {
- if (bar->progress < bar->maximum)
- a->setStartTime(QTime::currentTime());
- else
- d->stopAnimation(widget); //we stop the glow motion only after it has
- //moved out of view
- }
- painter->save();
- painter->setClipRect(theme.rect);
- if (vertical) {
- theme.rect = QRect(theme.rect.left(),
- inverted ? rect.top() - glowSize + animOffset :
- rect.bottom() + glowSize - animOffset,
- rect.width(), glowSize);
- } else {
- theme.rect = QRect(rect.left() - glowSize + animOffset,rect.top(), glowSize, rect.height());
- theme.rect = QStyle::visualRect(reverse ? Qt::RightToLeft : Qt::LeftToRight, option->rect, theme.rect);
- }
- d->drawBackground(theme);
- painter->restore();
- }
- }
- }
- break;
-#endif // QT_NO_PROGRESSBAR
- case CE_MenuBarItem:
- {
-
- if (const QStyleOptionMenuItem *mbi = qstyleoption_cast<const QStyleOptionMenuItem *>(option))
- {
- if (mbi->menuItemType == QStyleOptionMenuItem::DefaultItem)
- break;
-
- QPalette::ColorRole textRole = disabled ? QPalette::Text : QPalette::ButtonText;
- QPixmap pix = mbi->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, option, widget), QIcon::Normal);
-
- uint alignment = Qt::AlignCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
- if (!proxy()->styleHint(SH_UnderlineShortcut, mbi, widget))
- alignment |= Qt::TextHideMnemonic;
-
- //The rect adjustment is a workaround for the menu not really filling its background.
- XPThemeData theme(widget, painter, QLatin1String("MENU"), MENU_BARBACKGROUND, 0, option->rect.adjusted(-1, 0, 2, 1));
- d->drawBackground(theme);
-
- int stateId = MBI_NORMAL;
- if (disabled)
- stateId = MBI_DISABLED;
- else if (pressed)
- stateId = MBI_PUSHED;
- else if (selected)
- stateId = MBI_HOT;
-
- XPThemeData theme2(widget, painter, QLatin1String("MENU"), MENU_BARITEM, stateId, option->rect);
- d->drawBackground(theme2);
-
- if (!pix.isNull())
- drawItemPixmap(painter, mbi->rect, alignment, pix);
- else
- drawItemText(painter, mbi->rect, alignment, mbi->palette, mbi->state & State_Enabled, mbi->text, textRole);
- }
- }
- break;
-#ifndef QT_NO_MENU
- case CE_MenuItem:
- if (const QStyleOptionMenuItem *menuitem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
- // windows always has a check column, regardless whether we have an icon or not
- int checkcol = 28;
- {
- SIZE size;
- MARGINS margins;
- XPThemeData theme(widget, 0, QLatin1String("MENU"), MENU_POPUPCHECKBACKGROUND, MBI_HOT);
- pGetThemePartSize(theme.handle(), NULL, MENU_POPUPCHECK, 0, NULL,TS_TRUE, &size);
- pGetThemeMargins(theme.handle(), NULL, MENU_POPUPCHECK, 0, TMT_CONTENTMARGINS, NULL, &margins);
- checkcol = qMax(menuitem->maxIconWidth, int(6 + size.cx + margins.cxLeftWidth + margins.cxRightWidth));
- }
- QColor darkLine = option->palette.background().color().darker(108);
- QColor lightLine = option->palette.background().color().lighter(107);
- QRect rect = option->rect;
- QStyleOptionMenuItem mbiCopy = *menuitem;
-
- //draw vertical menu line
- QPoint p1 = QStyle::visualPos(option->direction, menuitem->rect, QPoint(checkcol, rect.top()));
- QPoint p2 = QStyle::visualPos(option->direction, menuitem->rect, QPoint(checkcol, rect.bottom()));
- QRect gutterRect(p1.x(), p1.y(), 3, p2.y() - p1.y() + 1);
- XPThemeData theme2(widget, painter, QLatin1String("MENU"), MENU_POPUPGUTTER, stateId, gutterRect);
- d->drawBackground(theme2);
-
- int x, y, w, h;
- menuitem->rect.getRect(&x, &y, &w, &h);
- int tab = menuitem->tabWidth;
- bool dis = !(menuitem->state & State_Enabled);
- bool checked = menuitem->checkType != QStyleOptionMenuItem::NotCheckable
- ? menuitem->checked : false;
- bool act = menuitem->state & State_Selected;
-
- if (menuitem->menuItemType == QStyleOptionMenuItem::Separator) {
- int yoff = y-2 + h / 2;
- QPoint p1 = QPoint(x + checkcol, yoff);
- QPoint p2 = QPoint(x + w + 6 , yoff);
- stateId = MBI_HOT;
- QRect subRect(p1.x(), p1.y(), p2.x() - p1.x(), 6);
- subRect = QStyle::visualRect(option->direction, option->rect, subRect );
- XPThemeData theme2(widget, painter, QLatin1String("MENU"), MENU_POPUPSEPARATOR, stateId, subRect);
- d->drawBackground(theme2);
- return;
- }
-
- QRect vCheckRect = visualRect(option->direction, menuitem->rect, QRect(menuitem->rect.x(),
- menuitem->rect.y(), checkcol - 6, menuitem->rect.height()));
-
- if (act) {
- stateId = MBI_HOT;
- XPThemeData theme2(widget, painter, QLatin1String("MENU"), MENU_POPUPITEM, stateId, option->rect);
- d->drawBackground(theme2);
- }
-
- if (checked) {
- XPThemeData theme(widget, painter, QLatin1String("MENU"), MENU_POPUPCHECKBACKGROUND,
- menuitem->icon.isNull() ? MBI_HOT : MBI_PUSHED, vCheckRect);
- SIZE size;
- MARGINS margins;
- pGetThemePartSize(theme.handle(), NULL, MENU_POPUPCHECK, 0, NULL,TS_TRUE, &size);
- pGetThemeMargins(theme.handle(), NULL, MENU_POPUPCHECK, 0,
- TMT_CONTENTMARGINS, NULL, &margins);
- QRect checkRect(0, 0, size.cx + margins.cxLeftWidth + margins.cxRightWidth ,
- size.cy + margins.cyBottomHeight + margins.cyTopHeight);
- checkRect.moveCenter(vCheckRect.center());
- theme.rect = checkRect;
-
- d->drawBackground(theme);
-
- if (menuitem->icon.isNull()) {
- checkRect = QRect(0, 0, size.cx, size.cy);
- checkRect.moveCenter(theme.rect.center());
- theme.rect = checkRect;
-
- theme.partId = MENU_POPUPCHECK;
- bool bullet = menuitem->checkType & QStyleOptionMenuItem::Exclusive;
- if (dis)
- theme.stateId = bullet ? MC_BULLETDISABLED: MC_CHECKMARKDISABLED;
- else
- theme.stateId = bullet ? MC_BULLETNORMAL: MC_CHECKMARKNORMAL;
- d->drawBackground(theme);
- }
- }
-
- if (!menuitem->icon.isNull()) {
- QIcon::Mode mode = dis ? QIcon::Disabled : QIcon::Normal;
- if (act && !dis)
- mode = QIcon::Active;
- QPixmap pixmap;
- if (checked)
- pixmap = menuitem->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, option, widget), mode, QIcon::On);
- else
- pixmap = menuitem->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, option, widget), mode);
- int pixw = pixmap.width();
- int pixh = pixmap.height();
- QRect pmr(0, 0, pixw, pixh);
- pmr.moveCenter(vCheckRect.center());
- painter->setPen(menuitem->palette.text().color());
- painter->drawPixmap(pmr.topLeft(), pixmap);
- }
-
- painter->setPen(menuitem->palette.buttonText().color());
-
- QColor discol;
- if (dis) {
- discol = menuitem->palette.text().color();
- painter->setPen(discol);
- }
-
- int xm = windowsItemFrame + checkcol + windowsItemHMargin;
- int xpos = menuitem->rect.x() + xm;
- QRect textRect(xpos, y + windowsItemVMargin, w - xm - windowsRightBorder - tab + 1, h - 2 * windowsItemVMargin);
- QRect vTextRect = visualRect(option->direction, menuitem->rect, textRect);
- QString s = menuitem->text;
- if (!s.isEmpty()) { // draw text
- painter->save();
- int t = s.indexOf(QLatin1Char('\t'));
- int text_flags = Qt::AlignVCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
- if (!proxy()->styleHint(SH_UnderlineShortcut, menuitem, widget))
- text_flags |= Qt::TextHideMnemonic;
- text_flags |= Qt::AlignLeft;
- if (t >= 0) {
- QRect vShortcutRect = visualRect(option->direction, menuitem->rect,
- QRect(textRect.topRight(), QPoint(menuitem->rect.right(), textRect.bottom())));
- painter->drawText(vShortcutRect, text_flags, s.mid(t + 1));
- s = s.left(t);
- }
- QFont font = menuitem->font;
- if (menuitem->menuItemType == QStyleOptionMenuItem::DefaultItem)
- font.setBold(true);
- painter->setFont(font);
- painter->setPen(discol);
- painter->drawText(vTextRect, text_flags, s.left(t));
- painter->restore();
- }
- if (menuitem->menuItemType == QStyleOptionMenuItem::SubMenu) {// draw sub menu arrow
- int dim = (h - 2 * windowsItemFrame) / 2;
- PrimitiveElement arrow;
- arrow = (option->direction == Qt::RightToLeft) ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight;
- xpos = x + w - windowsArrowHMargin - windowsItemFrame - dim;
- QRect vSubMenuRect = visualRect(option->direction, menuitem->rect, QRect(xpos, y + h / 2 - dim / 2, dim, dim));
- QStyleOptionMenuItem newMI = *menuitem;
- newMI.rect = vSubMenuRect;
- newMI.state = dis ? State_None : State_Enabled;
- proxy()->drawPrimitive(arrow, &newMI, painter, widget);
- }
- }
- break;
-#endif // QT_NO_MENU
- case CE_HeaderSection:
- if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
- name = QLatin1String("HEADER");
- partId = HP_HEADERITEM;
- if (flags & State_Sunken)
- stateId = HIS_PRESSED;
- else if (flags & State_MouseOver)
- stateId = HIS_HOT;
- else
- stateId = HIS_NORMAL;
-
- if (header->sortIndicator != QStyleOptionHeader::None)
- stateId += 3;
-
- XPThemeData theme(widget, painter, name, partId, stateId, option->rect);
- d->drawBackground(theme);
- }
- break;
- case CE_MenuBarEmptyArea:
- {
- stateId = MBI_NORMAL;
- if (!(state & State_Enabled))
- stateId = MBI_DISABLED;
- XPThemeData theme(widget, painter, QLatin1String("MENU"), MENU_BARBACKGROUND, stateId, option->rect);
- d->drawBackground(theme);
- }
- break;
- case CE_ToolBar:
- if (const QStyleOptionToolBar *toolbar = qstyleoption_cast<const QStyleOptionToolBar *>(option)) {
- QPalette pal = option->palette;
- pal.setColor(QPalette::Dark, option->palette.background().color().darker(130));
- QStyleOptionToolBar copyOpt = *toolbar;
- copyOpt.palette = pal;
- QWindowsStyle::drawControl(element, &copyOpt, painter, widget);
- }
- break;
- case CE_DockWidgetTitle:
- if (const QDockWidget *dockWidget = qobject_cast<const QDockWidget *>(widget)) {
- QRect rect = option->rect;
- if (dockWidget->isFloating()) {
- QWindowsXPStyle::drawControl(element, option, painter, widget);
- break; //otherwise fall through
- }
-
- if (const QStyleOptionDockWidget *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(option)) {
-
- const QStyleOptionDockWidgetV2 *v2
- = qstyleoption_cast<const QStyleOptionDockWidgetV2*>(dwOpt);
- bool verticalTitleBar = v2 == 0 ? false : v2->verticalTitleBar;
-
- if (verticalTitleBar) {
- QSize s = rect.size();
- s.transpose();
- rect.setSize(s);
-
- painter->translate(rect.left() - 1, rect.top() + rect.width());
- painter->rotate(-90);
- painter->translate(-rect.left() + 1, -rect.top());
- }
-
- painter->setBrush(option->palette.background().color().darker(110));
- painter->setPen(option->palette.background().color().darker(130));
- painter->drawRect(rect.adjusted(0, 1, -1, -3));
-
- int buttonMargin = 4;
- int mw = proxy()->pixelMetric(QStyle::PM_DockWidgetTitleMargin, dwOpt, widget);
- int fw = proxy()->pixelMetric(PM_DockWidgetFrameWidth, dwOpt, widget);
- const QDockWidget *dw = qobject_cast<const QDockWidget *>(widget);
- bool isFloating = dw != 0 && dw->isFloating();
-
- QRect r = option->rect.adjusted(0, 2, -1, -3);
- QRect titleRect = r;
-
- if (dwOpt->closable) {
- QSize sz = standardIcon(QStyle::SP_TitleBarCloseButton, dwOpt, widget).actualSize(QSize(10, 10));
- titleRect.adjust(0, 0, -sz.width() - mw - buttonMargin, 0);
- }
-
- if (dwOpt->floatable) {
- QSize sz = standardIcon(QStyle::SP_TitleBarMaxButton, dwOpt, widget).actualSize(QSize(10, 10));
- titleRect.adjust(0, 0, -sz.width() - mw - buttonMargin, 0);
- }
-
- if (isFloating) {
- titleRect.adjust(0, -fw, 0, 0);
- if (widget != 0 && widget->windowIcon().cacheKey() != QApplication::windowIcon().cacheKey())
- titleRect.adjust(titleRect.height() + mw, 0, 0, 0);
- } else {
- titleRect.adjust(mw, 0, 0, 0);
- if (!dwOpt->floatable && !dwOpt->closable)
- titleRect.adjust(0, 0, -mw, 0);
- }
- if (!verticalTitleBar)
- titleRect = visualRect(dwOpt->direction, r, titleRect);
-
- if (!dwOpt->title.isEmpty()) {
- QString titleText = painter->fontMetrics().elidedText(dwOpt->title, Qt::ElideRight,
- verticalTitleBar ? titleRect.height() : titleRect.width());
- const int indent = painter->fontMetrics().descent();
- drawItemText(painter, rect.adjusted(indent + 1, 1, -indent - 1, -1),
- Qt::AlignLeft | Qt::AlignVCenter, dwOpt->palette,
- dwOpt->state & State_Enabled, titleText,
- QPalette::WindowText);
- }
- }
- break;
- }
-#ifndef QT_NO_ITEMVIEWS
- case CE_ItemViewItem:
- {
- const QStyleOptionViewItemV4 *vopt;
- const QAbstractItemView *view = qobject_cast<const QAbstractItemView *>(widget);
- bool newStyle = true;
-
- if (qobject_cast<const QTableView*>(widget))
- newStyle = false;
-
- if (newStyle && view && (vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(option))) {
- /*
- // We cannot currently get the correct selection color for "explorer style" views
- COLORREF cref = 0;
- XPThemeData theme(d->treeViewHelper(), 0, QLatin1String("LISTVIEW"), 0, 0);
- unsigned int res = pGetThemeColor(theme.handle(), LVP_LISTITEM, LISS_SELECTED, TMT_TEXTCOLOR, &cref);
- QColor textColor(GetRValue(cref), GetGValue(cref), GetBValue(cref));
- */
- QPalette palette = vopt->palette;
- palette.setColor(QPalette::All, QPalette::HighlightedText, palette.color(QPalette::Active, QPalette::Text));
- // Note that setting a saturated color here results in ugly XOR colors in the focus rect
- palette.setColor(QPalette::All, QPalette::Highlight, palette.base().color().darker(108));
- QStyleOptionViewItemV4 adjustedOption = *vopt;
- adjustedOption.palette = palette;
- // We hide the focusrect in singleselection as it is not required
- if ((view->selectionMode() == QAbstractItemView::SingleSelection)
- && !(vopt->state & State_KeyboardFocusChange))
- adjustedOption.state &= ~State_HasFocus;
- QWindowsXPStyle::drawControl(element, &adjustedOption, painter, widget);
- } else {
- QWindowsXPStyle::drawControl(element, option, painter, widget);
- }
- break;
- }
-#endif // QT_NO_ITEMVIEWS
-
- default:
- QWindowsXPStyle::drawControl(element, option, painter, widget);
- break;
- }
-}
-
-/*!
- \internal
-
- see drawPrimitive for comments on the animation support
-
- */
-void QWindowsVistaStyle::drawComplexControl(ComplexControl control, const QStyleOptionComplex *option,
- QPainter *painter, const QWidget *widget) const
-{
- QWindowsVistaStylePrivate *d = const_cast<QWindowsVistaStylePrivate*>(d_func());
- if (!QWindowsVistaStylePrivate::useVista()) {
- QWindowsStyle::drawComplexControl(control, option, painter, widget);
- return;
- }
-
- State state = option->state;
- SubControls sub = option->subControls;
- QRect r = option->rect;
-
- int partId = 0;
- int stateId = 0;
-
- State flags = option->state;
- if (widget && widget->testAttribute(Qt::WA_UnderMouse) && widget->isActiveWindow())
- flags |= State_MouseOver;
-
- if (d->transitionsEnabled() && widget) {
- if ((qobject_cast<const QScrollBar *>(widget) && control == CC_ScrollBar)
-#ifndef QT_NO_SPINBOX
- || (qobject_cast<const QAbstractSpinBox*>(widget) && control == CC_SpinBox)
-#endif // QT_NO_SPINBOX
-#ifndef QT_NO_COMBOBOX
- || (qobject_cast<const QComboBox*>(widget) && control == CC_ComboBox)
-#endif // QT_NO_COMBOBOX
- )
- {
- QWidget *w = const_cast<QWidget *> (widget);
-
- int oldState = w->property("_q_stylestate").toInt();
- int oldActiveControls = w->property("_q_stylecontrols").toInt();
- QRect oldRect = w->property("_q_stylerect").toRect();
- w->setProperty("_q_stylestate", (int)option->state);
- w->setProperty("_q_stylecontrols", (int)option->activeSubControls);
- w->setProperty("_q_stylerect", w->rect());
-
- bool doTransition = ((state & State_Sunken) != (oldState & State_Sunken) ||
- (state & State_On) != (oldState & State_On) ||
- (state & State_MouseOver) != (oldState & State_MouseOver) ||
- oldActiveControls != option->activeSubControls);
-
-
- if (qstyleoption_cast<const QStyleOptionSlider *>(option)) {
- QRect oldSliderPos = w->property("_q_stylesliderpos").toRect();
- QRect currentPos = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider, widget);
- w->setProperty("_q_stylesliderpos", currentPos);
- if (oldSliderPos != currentPos) {
- doTransition = false;
- d->stopAnimation(widget);
- }
- } else if (control == CC_SpinBox) {
- //spinboxes have a transition when focus changes
- if (!doTransition)
- doTransition = (state & State_HasFocus) != (oldState & State_HasFocus);
- }
-
- if (oldRect != option->rect) {
- doTransition = false;
- d->stopAnimation(widget);
- }
-
- if (doTransition) {
- QImage startImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
- QImage endImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
- QWindowsVistaAnimation *anim = d->widgetAnimation(widget);
- QWindowsVistaTransition *t = new QWindowsVistaTransition;
- t->setWidget(w);
- if (!anim) {
- if (const QStyleOptionComboBox *combo = qstyleoption_cast<const QStyleOptionComboBox*>(option)) {
- //Combo boxes are special cased to avoid cleartype issues
- startImage.fill(0);
- QPainter startPainter(&startImage);
- QStyleOptionComboBox startCombo = *combo;
- startCombo.state = (QStyle::State)oldState;
- startCombo.activeSubControls = (QStyle::SubControl)oldActiveControls;
- proxy()->drawComplexControl(control, &startCombo, &startPainter, 0 /* Intentional */);
- t->setStartImage(startImage);
- } else if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider*>(option)) {
- //This is a workaround for the direct3d engine as it currently has some issues with grabWindow
- startImage.fill(0);
- QPainter startPainter(&startImage);
- QStyleOptionSlider startSlider = *slider;
- startSlider.state = (QStyle::State)oldState;
- startSlider.activeSubControls = (QStyle::SubControl)oldActiveControls;
- proxy()->drawComplexControl(control, &startSlider, &startPainter, 0 /* Intentional */);
- t->setStartImage(startImage);
- } else {
- QPoint offset(0, 0);
- if (!widget->internalWinId())
- offset = widget->mapTo(widget->nativeParentWidget(), offset);
- t->setStartImage(QPixmap::grabWindow(widget->effectiveWinId(), offset.x(), offset.y(),
- option->rect.width(), option->rect.height()).toImage());
- }
- } else {
- startImage.fill(0);
- QPainter startPainter(&startImage);
- anim->paint(&startPainter, option);
- t->setStartImage(startImage);
- }
- d->startAnimation(t);
- endImage.fill(0);
- QPainter endPainter(&endImage);
- proxy()->drawComplexControl(control, option, &endPainter, 0 /* Intentional */);
- t->setEndImage(endImage);
- t->setStartTime(QTime::currentTime());
-
- if (option->state & State_MouseOver || option->state & State_Sunken)
- t->setDuration(150);
- else
- t->setDuration(500);
- }
-
- if (QWindowsVistaAnimation *anim = d->widgetAnimation(widget)) {
- anim->paint(painter, option);
- return;
- }
-
- }
- }
-
- switch (control) {
- case CC_ComboBox:
- if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(option))
- {
- if (cmb->editable) {
- if (sub & SC_ComboBoxEditField) {
- partId = EP_EDITBORDER_NOSCROLL;
- if (!(flags & State_Enabled))
- stateId = ETS_DISABLED;
- else if (flags & State_MouseOver)
- stateId = ETS_HOT;
- else if (flags & State_HasFocus)
- stateId = ETS_FOCUSED;
- else
- stateId = ETS_NORMAL;
-
- XPThemeData theme(widget, painter, QLatin1String("EDIT"), partId, stateId, r);
-
- d->drawBackground(theme);
- }
- if (sub & SC_ComboBoxArrow) {
- QRect subRect = proxy()->subControlRect(CC_ComboBox, option, SC_ComboBoxArrow, widget);
- XPThemeData theme(widget, painter, QLatin1String("COMBOBOX"));
- theme.rect = subRect;
- partId = option->direction == Qt::RightToLeft ? CP_DROPDOWNBUTTONLEFT : CP_DROPDOWNBUTTONRIGHT;
-
- if (!(cmb->state & State_Enabled))
- stateId = CBXS_DISABLED;
- else if (cmb->state & State_Sunken || cmb->state & State_On)
- stateId = CBXS_PRESSED;
- else if (cmb->state & State_MouseOver && option->activeSubControls & SC_ComboBoxArrow)
- stateId = CBXS_HOT;
- else
- stateId = CBXS_NORMAL;
-
- theme.partId = partId;
- theme.stateId = stateId;
- d->drawBackground(theme);
- }
-
- } else {
- if (sub & SC_ComboBoxFrame) {
- QStyleOptionButton btn;
- btn.QStyleOption::operator=(*option);
- btn.rect = option->rect.adjusted(-1, -1, 1, 1);
- if (sub & SC_ComboBoxArrow)
- btn.features = QStyleOptionButton::HasMenu;
- proxy()->drawControl(QStyle::CE_PushButton, &btn, painter, widget);
- }
- }
- }
- break;
- case CC_ScrollBar:
- if (const QStyleOptionSlider *scrollbar = qstyleoption_cast<const QStyleOptionSlider *>(option))
- {
- XPThemeData theme(widget, painter, QLatin1String("SCROLLBAR"));
-
- bool maxedOut = (scrollbar->maximum == scrollbar->minimum);
- if (maxedOut)
- flags &= ~State_Enabled;
-
- bool isHorz = flags & State_Horizontal;
- bool isRTL = option->direction == Qt::RightToLeft;
- if (sub & SC_ScrollBarAddLine) {
- theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarAddLine, widget);
- partId = SBP_ARROWBTN;
- if (!(flags & State_Enabled))
- stateId = (isHorz ? (isRTL ? ABS_LEFTDISABLED : ABS_RIGHTDISABLED) : ABS_DOWNDISABLED);
- else if (scrollbar->activeSubControls & SC_ScrollBarAddLine && (scrollbar->state & State_Sunken))
- stateId = (isHorz ? (isRTL ? ABS_LEFTPRESSED : ABS_RIGHTPRESSED) : ABS_DOWNPRESSED);
- else if (scrollbar->activeSubControls & SC_ScrollBarAddLine && (scrollbar->state & State_MouseOver))
- stateId = (isHorz ? (isRTL ? ABS_LEFTHOT : ABS_RIGHTHOT) : ABS_DOWNHOT);
- else if (scrollbar->state & State_MouseOver)
- stateId = (isHorz ? (isRTL ? ABS_LEFTHOVER : ABS_RIGHTHOVER) : ABS_DOWNHOVER);
- else
- stateId = (isHorz ? (isRTL ? ABS_LEFTNORMAL : ABS_RIGHTNORMAL) : ABS_DOWNNORMAL);
- theme.partId = partId;
- theme.stateId = stateId;
- d->drawBackground(theme);
- }
- if (sub & SC_ScrollBarSubLine) {
- theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSubLine, widget);
- partId = SBP_ARROWBTN;
- if (!(flags & State_Enabled))
- stateId = (isHorz ? (isRTL ? ABS_RIGHTDISABLED : ABS_LEFTDISABLED) : ABS_UPDISABLED);
- else if (scrollbar->activeSubControls & SC_ScrollBarSubLine && (scrollbar->state & State_Sunken))
- stateId = (isHorz ? (isRTL ? ABS_RIGHTPRESSED : ABS_LEFTPRESSED) : ABS_UPPRESSED);
- else if (scrollbar->activeSubControls & SC_ScrollBarSubLine && (scrollbar->state & State_MouseOver))
- stateId = (isHorz ? (isRTL ? ABS_RIGHTHOT : ABS_LEFTHOT) : ABS_UPHOT);
- else if (scrollbar->state & State_MouseOver)
- stateId = (isHorz ? (isRTL ? ABS_RIGHTHOVER : ABS_LEFTHOVER) : ABS_UPHOVER);
- else
- stateId = (isHorz ? (isRTL ? ABS_RIGHTNORMAL : ABS_LEFTNORMAL) : ABS_UPNORMAL);
- theme.partId = partId;
- theme.stateId = stateId;
- d->drawBackground(theme);
- }
- if (maxedOut) {
- theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider, widget);
- theme.rect = theme.rect.united(proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSubPage, widget));
- theme.rect = theme.rect.united(proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarAddPage, widget));
- partId = flags & State_Horizontal ? SBP_LOWERTRACKHORZ : SBP_LOWERTRACKVERT;
- stateId = SCRBS_DISABLED;
- theme.partId = partId;
- theme.stateId = stateId;
- d->drawBackground(theme);
- } else {
- if (sub & SC_ScrollBarSubPage) {
- theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSubPage, widget);
- partId = flags & State_Horizontal ? SBP_UPPERTRACKHORZ : SBP_UPPERTRACKVERT;
- if (!(flags & State_Enabled))
- stateId = SCRBS_DISABLED;
- else if (scrollbar->activeSubControls & SC_ScrollBarSubPage && (scrollbar->state & State_Sunken))
- stateId = SCRBS_PRESSED;
- else if (scrollbar->activeSubControls & SC_ScrollBarSubPage && (scrollbar->state & State_MouseOver))
- stateId = SCRBS_HOT;
- else
- stateId = SCRBS_NORMAL;
- theme.partId = partId;
- theme.stateId = stateId;
- d->drawBackground(theme);
- }
- if (sub & SC_ScrollBarAddPage) {
- theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarAddPage, widget);
- partId = flags & State_Horizontal ? SBP_LOWERTRACKHORZ : SBP_LOWERTRACKVERT;
- if (!(flags & State_Enabled))
- stateId = SCRBS_DISABLED;
- else if (scrollbar->activeSubControls & SC_ScrollBarAddPage && (scrollbar->state & State_Sunken))
- stateId = SCRBS_PRESSED;
- else if (scrollbar->activeSubControls & SC_ScrollBarAddPage && (scrollbar->state & State_MouseOver))
- stateId = SCRBS_HOT;
- else
- stateId = SCRBS_NORMAL;
- theme.partId = partId;
- theme.stateId = stateId;
- d->drawBackground(theme);
- }
- if (sub & SC_ScrollBarSlider) {
- theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider, widget);
- if (!(flags & State_Enabled))
- stateId = SCRBS_DISABLED;
- else if (scrollbar->activeSubControls & SC_ScrollBarSlider && (scrollbar->state & State_Sunken))
- stateId = SCRBS_PRESSED;
- else if (scrollbar->activeSubControls & SC_ScrollBarSlider && (scrollbar->state & State_MouseOver))
- stateId = SCRBS_HOT;
- else if (option->state & State_MouseOver)
- stateId = SCRBS_HOVER;
- else
- stateId = SCRBS_NORMAL;
-
- // Draw handle
- theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider, widget);
- theme.partId = flags & State_Horizontal ? SBP_THUMBBTNHORZ : SBP_THUMBBTNVERT;
- theme.stateId = stateId;
- d->drawBackground(theme);
-
- // Calculate rect of gripper
- const int swidth = theme.rect.width();
- const int sheight = theme.rect.height();
-
- MARGINS contentsMargin;
- RECT rect = theme.toRECT(theme.rect);
- pGetThemeMargins(theme.handle(), 0, theme.partId, theme.stateId, TMT_SIZINGMARGINS, &rect, &contentsMargin);
-
- SIZE size;
- theme.partId = flags & State_Horizontal ? SBP_GRIPPERHORZ : SBP_GRIPPERVERT;
- pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
- int gw = size.cx, gh = size.cy;
-
-
- QRect gripperBounds;
- if (flags & State_Horizontal && ((swidth - contentsMargin.cxLeftWidth - contentsMargin.cxRightWidth) > gw)) {
- gripperBounds.setLeft(theme.rect.left() + swidth/2 - gw/2);
- gripperBounds.setTop(theme.rect.top() + sheight/2 - gh/2);
- gripperBounds.setWidth(gw);
- gripperBounds.setHeight(gh);
- } else if ((sheight - contentsMargin.cyTopHeight - contentsMargin.cyBottomHeight) > gh) {
- gripperBounds.setLeft(theme.rect.left() + swidth/2 - gw/2);
- gripperBounds.setTop(theme.rect.top() + sheight/2 - gh/2);
- gripperBounds.setWidth(gw);
- gripperBounds.setHeight(gh);
- }
-
- // Draw gripper if there is enough space
- if (!gripperBounds.isEmpty() && flags & State_Enabled) {
- painter->save();
- XPThemeData grippBackground = theme;
- grippBackground.partId = flags & State_Horizontal ? SBP_LOWERTRACKHORZ : SBP_LOWERTRACKVERT;
- theme.rect = gripperBounds;
- painter->setClipRegion(d->region(theme));// Only change inside the region of the gripper
- d->drawBackground(grippBackground);// The gutter is the grippers background
- d->drawBackground(theme); // Transparent gripper ontop of background
- painter->restore();
- }
- }
- }
- }
- break;
-#ifndef QT_NO_SPINBOX
- case CC_SpinBox:
- if (const QStyleOptionSpinBox *sb = qstyleoption_cast<const QStyleOptionSpinBox *>(option))
- {
- XPThemeData theme(widget, painter, QLatin1String("SPIN"));
- if (sb->frame && (sub & SC_SpinBoxFrame)) {
- partId = EP_EDITBORDER_NOSCROLL;
- if (!(flags & State_Enabled))
- stateId = ETS_DISABLED;
- else if (flags & State_MouseOver)
- stateId = ETS_HOT;
- else if (flags & State_HasFocus)
- stateId = ETS_SELECTED;
- else
- stateId = ETS_NORMAL;
-
- XPThemeData ftheme(widget, painter, QLatin1String("EDIT"), partId, stateId, r);
- ftheme.noContent = true;
- d->drawBackground(ftheme);
- }
- if (sub & SC_SpinBoxUp) {
- theme.rect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxUp, widget).adjusted(0, 0, 0, 1);
- partId = SPNP_UP;
- if (!(sb->stepEnabled & QAbstractSpinBox::StepUpEnabled) || !(flags & State_Enabled))
- stateId = UPS_DISABLED;
- else if (sb->activeSubControls == SC_SpinBoxUp && (sb->state & State_Sunken))
- stateId = UPS_PRESSED;
- else if (sb->activeSubControls == SC_SpinBoxUp && (sb->state & State_MouseOver))
- stateId = UPS_HOT;
- else
- stateId = UPS_NORMAL;
- theme.partId = partId;
- theme.stateId = stateId;
- d->drawBackground(theme);
- }
- if (sub & SC_SpinBoxDown) {
- theme.rect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxDown, widget);
- partId = SPNP_DOWN;
- if (!(sb->stepEnabled & QAbstractSpinBox::StepDownEnabled) || !(flags & State_Enabled))
- stateId = DNS_DISABLED;
- else if (sb->activeSubControls == SC_SpinBoxDown && (sb->state & State_Sunken))
- stateId = DNS_PRESSED;
- else if (sb->activeSubControls == SC_SpinBoxDown && (sb->state & State_MouseOver))
- stateId = DNS_HOT;
- else
- stateId = DNS_NORMAL;
- theme.partId = partId;
- theme.stateId = stateId;
- d->drawBackground(theme);
- }
- }
- break;
-#endif // QT_NO_SPINBOX
- default:
- QWindowsXPStyle::drawComplexControl(control, option, painter, widget);
- break;
- }
-}
-
-/*!
- \internal
- */
-QSize QWindowsVistaStyle::sizeFromContents(ContentsType type, const QStyleOption *option,
- const QSize &size, const QWidget *widget) const
-{
- if (!QWindowsVistaStylePrivate::useVista())
- return QWindowsStyle::sizeFromContents(type, option, size, widget);
-
- QSize sz(size);
- switch (type) {
- case CT_MenuItem:
- sz = QWindowsXPStyle::sizeFromContents(type, option, size, widget);
- int minimumHeight;
- {
- SIZE size;
- MARGINS margins;
- XPThemeData theme(widget, 0, QLatin1String("MENU"), MENU_POPUPCHECKBACKGROUND, MBI_HOT);
- pGetThemePartSize(theme.handle(), NULL, MENU_POPUPCHECK, 0, NULL,TS_TRUE, &size);
- pGetThemeMargins(theme.handle(), NULL, MENU_POPUPCHECK, 0, TMT_CONTENTMARGINS, NULL, &margins);
- minimumHeight = qMax<qint32>(size.cy + margins.cyBottomHeight+ margins.cyTopHeight, sz.height());
- sz.rwidth() += size.cx + margins.cxLeftWidth + margins.cxRightWidth;
- }
-
- if (const QStyleOptionMenuItem *menuitem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
- if (menuitem->menuItemType != QStyleOptionMenuItem::Separator)
- sz.setHeight(minimumHeight);
- }
- return sz;
-#ifndef QT_NO_MENUBAR
- case CT_MenuBarItem:
- if (!sz.isEmpty())
- sz += QSize(windowsItemHMargin * 5 + 1, 5);
- return sz;
- break;
-#endif
- case CT_ItemViewItem:
- sz = QWindowsXPStyle::sizeFromContents(type, option, size, widget);
- sz.rheight() += 2;
- return sz;
- case CT_SpinBox:
- {
- //Spinbox adds frame twice
- sz = QWindowsStyle::sizeFromContents(type, option, size, widget);
- int border = proxy()->pixelMetric(PM_SpinBoxFrameWidth, option, widget);
- sz -= QSize(2*border, 2*border);
- }
- return sz;
- default:
- break;
- }
- return QWindowsXPStyle::sizeFromContents(type, option, size, widget);
-}
-
-/*!
- \internal
- */
-QRect QWindowsVistaStyle::subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const
-{
- if (!QWindowsVistaStylePrivate::useVista())
- return QWindowsStyle::subElementRect(element, option, widget);
-
- QRect rect = QWindowsXPStyle::subElementRect(element, option, widget);
- switch (element) {
-
- case SE_PushButtonContents:
- if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
- MARGINS borderSize;
- HTHEME theme = pOpenThemeData(widget ? QWindowsVistaStylePrivate::winId(widget) : 0, L"Button");
- if (theme) {
- int stateId = PBS_NORMAL;
- if (!(option->state & State_Enabled))
- stateId = PBS_DISABLED;
- else if (option->state & State_Sunken)
- stateId = PBS_PRESSED;
- else if (option->state & State_MouseOver)
- stateId = PBS_HOT;
- else if (btn->features & QStyleOptionButton::DefaultButton)
- stateId = PBS_DEFAULTED;
-
- int border = proxy()->pixelMetric(PM_DefaultFrameWidth, btn, widget);
- rect = option->rect.adjusted(border, border, -border, -border);
-
- int result = pGetThemeMargins(theme,
- NULL,
- BP_PUSHBUTTON,
- stateId,
- TMT_CONTENTMARGINS,
- NULL,
- &borderSize);
-
- if (result == S_OK) {
- rect.adjust(borderSize.cxLeftWidth, borderSize.cyTopHeight,
- -borderSize.cxRightWidth, -borderSize.cyBottomHeight);
- rect = visualRect(option->direction, option->rect, rect);
- }
- }
- }
- break;
-
- case SE_HeaderArrow:
- {
- QRect r = rect;
- int h = option->rect.height();
- int w = option->rect.width();
- int x = option->rect.x();
- int y = option->rect.y();
- int margin = proxy()->pixelMetric(QStyle::PM_HeaderMargin, option, widget);
-
- XPThemeData theme(widget, 0, QLatin1String("HEADER"), HP_HEADERSORTARROW, HSAS_SORTEDDOWN, option->rect);
-
- int arrowWidth = 13;
- int arrowHeight = 5;
- if (theme.isValid()) {
- SIZE size;
- if (pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size) == S_OK) {
- arrowWidth = size.cx;
- arrowHeight = size.cy;
- }
- }
- if (option->state & State_Horizontal) {
- r.setRect(x + w/2 - arrowWidth/2, y , arrowWidth, arrowHeight);
- } else {
- int vert_size = w / 2;
- r.setRect(x + 5, y + h - margin * 2 - vert_size,
- w - margin * 2 - 5, vert_size);
- }
- rect = visualRect(option->direction, option->rect, r);
- }
- break;
-
- case SE_HeaderLabel:
- {
- int margin = proxy()->pixelMetric(QStyle::PM_HeaderMargin, option, widget);
- QRect r = option->rect;
- r.setRect(option->rect.x() + margin, option->rect.y() + margin,
- option->rect.width() - margin * 2, option->rect.height() - margin * 2);
- if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
- // Subtract width needed for arrow, if there is one
- if (header->sortIndicator != QStyleOptionHeader::None) {
- if (!(option->state & State_Horizontal)) //horizontal arrows are positioned on top
- r.setHeight(r.height() - (option->rect.width() / 2) - (margin * 2));
- }
- }
- rect = visualRect(option->direction, option->rect, r);
- }
- break;
- case SE_ProgressBarContents:
- rect = QCommonStyle::subElementRect(SE_ProgressBarGroove, option, widget);
- break;
- case SE_ItemViewItemDecoration:
- if (qstyleoption_cast<const QStyleOptionViewItemV4 *>(option))
- rect.adjust(-2, 0, 2, 0);
- break;
- case SE_ItemViewItemFocusRect:
- if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(option)) {
- QRect textRect = subElementRect(QStyle::SE_ItemViewItemText, option, widget);
- QRect displayRect = subElementRect(QStyle::SE_ItemViewItemDecoration, option, widget);
- if (!vopt->icon.isNull())
- rect = textRect.united(displayRect);
- else
- rect = textRect;
- rect = rect.adjusted(1, 0, -1, 0);
- }
- break;
- default:
- break;
- }
- return rect;
-}
-
-
-/*
- This function is used by subControlRect to check if a button
- should be drawn for the given subControl given a set of window flags.
-*/
-static bool buttonVisible(const QStyle::SubControl sc, const QStyleOptionTitleBar *tb){
-
- bool isMinimized = tb->titleBarState & Qt::WindowMinimized;
- bool isMaximized = tb->titleBarState & Qt::WindowMaximized;
- const uint flags = tb->titleBarFlags;
- bool retVal = false;
- switch (sc) {
- case QStyle::SC_TitleBarContextHelpButton:
- if (flags & Qt::WindowContextHelpButtonHint)
- retVal = true;
- break;
- case QStyle::SC_TitleBarMinButton:
- if (!isMinimized && (flags & Qt::WindowMinimizeButtonHint))
- retVal = true;
- break;
- case QStyle::SC_TitleBarNormalButton:
- if (isMinimized && (flags & Qt::WindowMinimizeButtonHint))
- retVal = true;
- else if (isMaximized && (flags & Qt::WindowMaximizeButtonHint))
- retVal = true;
- break;
- case QStyle::SC_TitleBarMaxButton:
- if (!isMaximized && (flags & Qt::WindowMaximizeButtonHint))
- retVal = true;
- break;
- case QStyle::SC_TitleBarShadeButton:
- if (!isMinimized && flags & Qt::WindowShadeButtonHint)
- retVal = true;
- break;
- case QStyle::SC_TitleBarUnshadeButton:
- if (isMinimized && flags & Qt::WindowShadeButtonHint)
- retVal = true;
- break;
- case QStyle::SC_TitleBarCloseButton:
- if (flags & Qt::WindowSystemMenuHint)
- retVal = true;
- break;
- case QStyle::SC_TitleBarSysMenu:
- if (flags & Qt::WindowSystemMenuHint)
- retVal = true;
- break;
- default :
- retVal = true;
- }
- return retVal;
-}
-
-
-/*! \internal */
-int QWindowsVistaStyle::styleHint(StyleHint hint, const QStyleOption *option, const QWidget *widget,
- QStyleHintReturn *returnData) const
-{
- QWindowsVistaStylePrivate *d = const_cast<QWindowsVistaStylePrivate*>(d_func());
- int ret = 0;
- switch (hint) {
- case SH_MessageBox_CenterButtons:
- ret = false;
- break;
- case SH_ToolTip_Mask:
- if (option) {
- if (QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask*>(returnData)) {
- ret = true;
- XPThemeData themeData(widget, 0, QLatin1String("TOOLTIP"), TTP_STANDARD, TTSS_NORMAL, option->rect);
- mask->region = d->region(themeData);
- }
- }
- break;
- case SH_Table_GridLineColor:
- if (option)
- ret = option->palette.color(QPalette::Base).darker(118).rgb();
- else
- ret = -1;
- break;
- default:
- ret = QWindowsXPStyle::styleHint(hint, option, widget, returnData);
- break;
- }
- return ret;
-}
-
-
-/*!
- \internal
- */
-QRect QWindowsVistaStyle::subControlRect(ComplexControl control, const QStyleOptionComplex *option,
- SubControl subControl, const QWidget *widget) const
-{
- if (!QWindowsVistaStylePrivate::useVista())
- return QWindowsStyle::subControlRect(control, option, subControl, widget);
-
- QRect rect = QWindowsXPStyle::subControlRect(control, option, subControl, widget);
- switch (control) {
-#ifndef QT_NO_COMBOBOX
- case CC_ComboBox:
- if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
- int x = cb->rect.x(),
- y = cb->rect.y(),
- wi = cb->rect.width(),
- he = cb->rect.height();
- int xpos = x;
- int margin = cb->frame ? 3 : 0;
- int bmarg = cb->frame ? 2 : 0;
- int arrowButtonWidth = bmarg + 16;
- xpos += wi - arrowButtonWidth;
-
- switch (subControl) {
- case SC_ComboBoxFrame:
- rect = cb->rect;
- break;
- case SC_ComboBoxArrow:
- rect.setRect(xpos, y , arrowButtonWidth, he);
- break;
- case SC_ComboBoxEditField:
- rect.setRect(x + margin, y + margin, wi - 2 * margin - 16, he - 2 * margin);
- break;
- case SC_ComboBoxListBoxPopup:
- rect = cb->rect;
- break;
- default:
- break;
- }
- rect = visualRect(cb->direction, cb->rect, rect);
- return rect;
- }
-#endif // QT_NO_COMBOBOX
- case CC_TitleBar:
- if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(option)) {
- if (!buttonVisible(subControl, tb))
- return rect;
- const bool isToolTitle = false;
- const int height = tb->rect.height();
- const int width = tb->rect.width();
- int buttonWidth = GetSystemMetrics(SM_CXSIZE) - 4;
-
- const int frameWidth = proxy()->pixelMetric(PM_MdiSubWindowFrameWidth, option, widget);
- const bool sysmenuHint = (tb->titleBarFlags & Qt::WindowSystemMenuHint) != 0;
- const bool minimizeHint = (tb->titleBarFlags & Qt::WindowMinimizeButtonHint) != 0;
- const bool maximizeHint = (tb->titleBarFlags & Qt::WindowMaximizeButtonHint) != 0;
- const bool contextHint = (tb->titleBarFlags & Qt::WindowContextHelpButtonHint) != 0;
- const bool shadeHint = (tb->titleBarFlags & Qt::WindowShadeButtonHint) != 0;
-
- switch (subControl) {
- case SC_TitleBarLabel:
- rect = QRect(frameWidth, 0, width - (buttonWidth + frameWidth + 10), height);
- if (isToolTitle) {
- if (sysmenuHint) {
- rect.adjust(0, 0, -buttonWidth - 3, 0);
- }
- if (minimizeHint || maximizeHint)
- rect.adjust(0, 0, -buttonWidth - 2, 0);
- } else {
- if (sysmenuHint) {
- const int leftOffset = height - 8;
- rect.adjust(leftOffset, 0, 0, 4);
- }
- if (minimizeHint)
- rect.adjust(0, 0, -buttonWidth - 2, 0);
- if (maximizeHint)
- rect.adjust(0, 0, -buttonWidth - 2, 0);
- if (contextHint)
- rect.adjust(0, 0, -buttonWidth - 2, 0);
- if (shadeHint)
- rect.adjust(0, 0, -buttonWidth - 2, 0);
- }
- rect.translate(0, 2);
- rect = visualRect(option->direction, option->rect, rect);
- break;
- case SC_TitleBarSysMenu:
- {
- const int controlTop = 6;
- const int controlHeight = height - controlTop - 3;
- int iconExtent = proxy()->pixelMetric(PM_SmallIconSize);
- QSize iconSize = tb->icon.actualSize(QSize(iconExtent, iconExtent));
- if (tb->icon.isNull())
- iconSize = QSize(controlHeight, controlHeight);
- int hPad = (controlHeight - iconSize.height())/2;
- int vPad = (controlHeight - iconSize.width())/2;
- rect = QRect(frameWidth + hPad, controlTop + vPad, iconSize.width(), iconSize.height());
- rect.translate(0, 3);
- rect = visualRect(option->direction, option->rect, rect);
- }
- break;
- default:
- break;
- }
- }
- break;
- default:
- break;
- }
- return rect;
-}
-
-/*!
- \internal
- */
-bool QWindowsVistaStyle::event(QEvent *e)
-{
- Q_D(QWindowsVistaStyle);
- switch (e->type()) {
- case QEvent::Timer:
- {
- QTimerEvent *timerEvent = (QTimerEvent *)e;
- if (d->animationTimer.timerId() == timerEvent->timerId()) {
- d->timerEvent();
- e->accept();
- return true;
- }
- }
- break;
- default:
- break;
- }
- return QWindowsXPStyle::event(e);
-}
-
-/*!
- \internal
- */
-QStyle::SubControl QWindowsVistaStyle::hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option,
- const QPoint &pos, const QWidget *widget) const
-{
- if (!QWindowsVistaStylePrivate::useVista()) {
- return QWindowsStyle::hitTestComplexControl(control, option, pos, widget);
- }
- return QWindowsXPStyle::hitTestComplexControl(control, option, pos, widget);
-}
-
-/*!
- \internal
- */
-int QWindowsVistaStyle::pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const
-{
- if (!QWindowsVistaStylePrivate::useVista()) {
- return QWindowsStyle::pixelMetric(metric, option, widget);
- }
- switch (metric) {
-
- case PM_DockWidgetTitleBarButtonMargin:
- return int(QStyleHelper::dpiScaled(5.));
- case PM_ScrollBarSliderMin:
- return int(QStyleHelper::dpiScaled(18.));
- case PM_MenuHMargin:
- case PM_MenuVMargin:
- return 0;
- case PM_MenuPanelWidth:
- return 3;
- default:
- break;
- }
- return QWindowsXPStyle::pixelMetric(metric, option, widget);
-}
-
-/*!
- \internal
- */
-QPalette QWindowsVistaStyle::standardPalette() const
-{
- return QWindowsXPStyle::standardPalette();
-}
-
-/*!
- \internal
- */
-void QWindowsVistaStyle::polish(QApplication *app)
-{
- QWindowsXPStyle::polish(app);
-}
-
-/*!
- \internal
- */
-void QWindowsVistaStyle::polish(QWidget *widget)
-{
- QWindowsXPStyle::polish(widget);
-#ifndef QT_NO_LINEEDIT
- if (qobject_cast<QLineEdit*>(widget))
- widget->setAttribute(Qt::WA_Hover);
- else
-#endif // QT_NO_LINEEDIT
- if (qobject_cast<QGroupBox*>(widget))
- widget->setAttribute(Qt::WA_Hover);
- else if (qobject_cast<QCommandLinkButton*>(widget)) {
- QFont buttonFont = widget->font();
- buttonFont.setFamily(QLatin1String("Segoe UI"));
- widget->setFont(buttonFont);
- }
- else if (widget->inherits("QTipLabel")){
- //note that since tooltips are not reused
- //we do not have to care about unpolishing
- widget->setContentsMargins(3, 0, 4, 0);
- COLORREF bgRef;
- HTHEME theme = pOpenThemeData(widget ? QWindowsVistaStylePrivate::winId(widget) : 0, L"TOOLTIP");
- if (theme) {
- if (pGetThemeColor(theme, TTP_STANDARD, TTSS_NORMAL, TMT_TEXTCOLOR, &bgRef) == S_OK) {
- QColor textColor = QColor::fromRgb(bgRef);
- QPalette pal;
- pal.setColor(QPalette::All, QPalette::ToolTipText, textColor);
- widget->setPalette(pal);
- }
- }
- } else if (qobject_cast<QMessageBox *> (widget)) {
- widget->setAttribute(Qt::WA_StyledBackground);
- QDialogButtonBox *buttonBox = widget->findChild<QDialogButtonBox *>(QLatin1String("qt_msgbox_buttonbox"));
- if (buttonBox)
- buttonBox->setContentsMargins(0, 9, 0, 0);
- }
-#ifndef QT_NO_INPUTDIALOG
- else if (qobject_cast<QInputDialog *> (widget)) {
- widget->setAttribute(Qt::WA_StyledBackground);
- QDialogButtonBox *buttonBox = widget->findChild<QDialogButtonBox *>(QLatin1String("qt_inputdlg_buttonbox"));
- if (buttonBox)
- buttonBox->setContentsMargins(0, 9, 0, 0);
- }
-#endif // QT_NO_INPUTDIALOG
- 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);
- }
-}
-
-/*!
- \internal
- */
-void QWindowsVistaStyle::unpolish(QWidget *widget)
-{
- QWindowsXPStyle::unpolish(widget);
-
- QWindowsVistaStylePrivate *d = const_cast<QWindowsVistaStylePrivate*>(d_func());
- d->stopAnimation(widget);
-
-#ifndef QT_NO_LINEEDIT
- if (qobject_cast<QLineEdit*>(widget))
- widget->setAttribute(Qt::WA_Hover, false);
- else
-#endif // QT_NO_LINEEDIT
- if (qobject_cast<QGroupBox*>(widget))
- widget->setAttribute(Qt::WA_Hover, false);
- else if (qobject_cast<QMessageBox *> (widget)) {
- widget->setAttribute(Qt::WA_StyledBackground, false);
- QDialogButtonBox *buttonBox = widget->findChild<QDialogButtonBox *>(QLatin1String("qt_msgbox_buttonbox"));
- if (buttonBox)
- buttonBox->setContentsMargins(0, 0, 0, 0);
- }
-#ifndef QT_NO_INPUTDIALOG
- else if (qobject_cast<QInputDialog *> (widget)) {
- widget->setAttribute(Qt::WA_StyledBackground, false);
- QDialogButtonBox *buttonBox = widget->findChild<QDialogButtonBox *>(QLatin1String("qt_inputdlg_buttonbox"));
- if (buttonBox)
- buttonBox->setContentsMargins(0, 0, 0, 0);
- }
-#endif // QT_NO_INPUTDIALOG
- else if (QTreeView *tree = qobject_cast<QTreeView *> (widget)) {
- tree->viewport()->setAttribute(Qt::WA_Hover, false);
- } else if (qobject_cast<QCommandLinkButton*>(widget)) {
- QFont font = QApplication::font("QCommandLinkButton");
- QFont widgetFont = widget->font();
- widgetFont.setFamily(font.family()); //Only family set by polish
- widget->setFont(widgetFont);
- }
-}
-
-
-/*!
- \internal
- */
-void QWindowsVistaStyle::unpolish(QApplication *app)
-{
- QWindowsXPStyle::unpolish(app);
-}
-
-/*!
- \internal
- */
-void QWindowsVistaStyle::polish(QPalette &pal)
-{
- QWindowsStyle::polish(pal);
- pal.setBrush(QPalette::AlternateBase, pal.base().color().darker(104));
-}
-
-/*!
- \internal
- */
-QPixmap QWindowsVistaStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *option,
- const QWidget *widget) const
-{
- if (!QWindowsVistaStylePrivate::useVista()) {
- return QWindowsStyle::standardPixmap(standardPixmap, option, widget);
- }
- return QWindowsXPStyle::standardPixmap(standardPixmap, option, widget);
-}
-
-QWindowsVistaStylePrivate::QWindowsVistaStylePrivate() :
- QWindowsXPStylePrivate(), m_treeViewHelper(0)
-{
- resolveSymbols();
-}
-
-QWindowsVistaStylePrivate::~QWindowsVistaStylePrivate()
-{
- delete m_treeViewHelper;
-}
-
-void QWindowsVistaStylePrivate::timerEvent()
-{
- for (int i = animations.size() - 1 ; i >= 0 ; --i) {
-
- if (animations[i]->widget())
- animations[i]->widget()->update();
-
- if (!animations[i]->widget() ||
- !animations[i]->widget()->isVisible() ||
- animations[i]->widget()->window()->isMinimized() ||
- !animations[i]->running() ||
- !QWindowsVistaStylePrivate::useVista())
- {
- QWindowsVistaAnimation *a = animations.takeAt(i);
- delete a;
- }
- }
- if (animations.size() == 0 && animationTimer.isActive()) {
- animationTimer.stop();
- }
-}
-
-void QWindowsVistaStylePrivate::stopAnimation(const QWidget *w)
-{
- for (int i = animations.size() - 1 ; i >= 0 ; --i) {
- if (animations[i]->widget() == w) {
- QWindowsVistaAnimation *a = animations.takeAt(i);
- delete a;
- break;
- }
- }
-}
-
-void QWindowsVistaStylePrivate::startAnimation(QWindowsVistaAnimation *t)
-{
- Q_Q(QWindowsVistaStyle);
- stopAnimation(t->widget());
- animations.append(t);
- if (animations.size() > 0 && !animationTimer.isActive()) {
- animationTimer.start(45, q);
- }
-}
-
-bool QWindowsVistaStylePrivate::transitionsEnabled() const
-{
- BOOL animEnabled = false;
- if (SystemParametersInfo(SPI_GETCLIENTAREAANIMATION, 0, &animEnabled, 0))
- {
- if (animEnabled)
- return true;
- }
- return false;
-}
-
-
-QWindowsVistaAnimation * QWindowsVistaStylePrivate::widgetAnimation(const QWidget *widget) const
-{
- if (!widget)
- return 0;
- foreach (QWindowsVistaAnimation *a, animations) {
- if (a->widget() == widget)
- return a;
- }
- return 0;
-}
-
-
-/*! \internal
- Returns true if all the necessary theme engine symbols were
- resolved.
-*/
-bool QWindowsVistaStylePrivate::resolveSymbols()
-{
- static bool tried = false;
- if (!tried) {
- tried = true;
- QSystemLibrary themeLib(QLatin1String("uxtheme"));
- pSetWindowTheme = (PtrSetWindowTheme )themeLib.resolve("SetWindowTheme");
- pIsThemePartDefined = (PtrIsThemePartDefined )themeLib.resolve("IsThemePartDefined");
- pGetThemePartSize = (PtrGetThemePartSize )themeLib.resolve("GetThemePartSize");
- pOpenThemeData = (PtrOpenThemeData )themeLib.resolve("OpenThemeData");
- pCloseThemeData = (PtrCloseThemeData )themeLib.resolve("CloseThemeData");
- pDrawThemeBackground = (PtrDrawThemeBackground )themeLib.resolve("DrawThemeBackground");
- pDrawThemeBackgroundEx = (PtrDrawThemeBackgroundEx )themeLib.resolve("DrawThemeBackgroundEx");
- pGetCurrentThemeName = (PtrGetCurrentThemeName )themeLib.resolve("GetCurrentThemeName");
- pGetThemeBool = (PtrGetThemeBool )themeLib.resolve("GetThemeBool");
- pGetThemeColor = (PtrGetThemeColor )themeLib.resolve("GetThemeColor");
- pGetThemeEnumValue = (PtrGetThemeEnumValue )themeLib.resolve("GetThemeEnumValue");
- pGetThemeFilename = (PtrGetThemeFilename )themeLib.resolve("GetThemeFilename");
- pGetThemeFont = (PtrGetThemeFont )themeLib.resolve("GetThemeFont");
- pGetThemeInt = (PtrGetThemeInt )themeLib.resolve("GetThemeInt");
- pGetThemeIntList = (PtrGetThemeIntList )themeLib.resolve("GetThemeIntList");
- pGetThemeMargins = (PtrGetThemeMargins )themeLib.resolve("GetThemeMargins");
- pGetThemeMetric = (PtrGetThemeMetric )themeLib.resolve("GetThemeMetric");
- pGetThemePartSize = (PtrGetThemePartSize )themeLib.resolve("GetThemePartSize");
- pGetThemePosition = (PtrGetThemePosition )themeLib.resolve("GetThemePosition");
- pGetThemeRect = (PtrGetThemeRect )themeLib.resolve("GetThemeRect");
- pGetThemeString = (PtrGetThemeString )themeLib.resolve("GetThemeString");
- pGetThemeTransitionDuration = (PtrGetThemeTransitionDuration)themeLib.resolve("GetThemeTransitionDuration");
- pGetThemePropertyOrigin = (PtrGetThemePropertyOrigin)themeLib.resolve("GetThemePropertyOrigin");
- }
- return pGetThemeTransitionDuration != 0;
-}
-
-/*
- * We need to set the windows explorer theme explicitly on a native widget
- * in order to get Vista-style item view themes
- */
-QWidget *QWindowsVistaStylePrivate::treeViewHelper()
-{
- if (!m_treeViewHelper) {
- m_treeViewHelper = new QWidget(0);
- pSetWindowTheme(m_treeViewHelper->winId(), L"explorer", NULL);
- }
- return m_treeViewHelper;
-}
-
-
-/*!
-\internal
-*/
-QIcon QWindowsVistaStyle::standardIconImplementation(StandardPixmap standardIcon,
- const QStyleOption *option,
- const QWidget *widget) const
-{
- if (!QWindowsVistaStylePrivate::useVista()) {
- return QWindowsStyle::standardIconImplementation(standardIcon, option, widget);
- }
-
- QWindowsVistaStylePrivate *d = const_cast<QWindowsVistaStylePrivate *>(d_func());
- switch(standardIcon) {
- case SP_CommandLink:
- {
- XPThemeData theme(0, 0, QLatin1String("BUTTON"), BP_COMMANDLINKGLYPH, CMDLGS_NORMAL);
- if (theme.isValid()) {
- SIZE size;
- pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
- QIcon linkGlyph;
- QPixmap pm = QPixmap(size.cx, size.cy);
- pm.fill(Qt::transparent);
- QPainter p(&pm);
- theme.painter = &p;
- theme.rect = QRect(0, 0, size.cx, size.cy);
- d->drawBackground(theme);
- linkGlyph.addPixmap(pm, QIcon::Normal, QIcon::Off); // Normal
- pm.fill(Qt::transparent);
-
- theme.stateId = CMDLGS_PRESSED;
- d->drawBackground(theme);
- linkGlyph.addPixmap(pm, QIcon::Normal, QIcon::On); // Pressed
- pm.fill(Qt::transparent);
-
- theme.stateId = CMDLGS_HOT;
- d->drawBackground(theme);
- linkGlyph.addPixmap(pm, QIcon::Active, QIcon::Off); // Hover
- pm.fill(Qt::transparent);
-
- theme.stateId = CMDLGS_DISABLED;
- d->drawBackground(theme);
- linkGlyph.addPixmap(pm, QIcon::Disabled, QIcon::Off); // Disabled
- return linkGlyph;
- }
- }
- break;
- default:
- break;
- }
- return QWindowsXPStyle::standardIconImplementation(standardIcon, option, widget);
-}
-
-QT_END_NAMESPACE
-
-#endif //QT_NO_WINDOWSVISTA
diff --git a/src/gui/styles/qwindowsvistastyle.h b/src/gui/styles/qwindowsvistastyle.h
deleted file mode 100644
index c0170809d3..0000000000
--- a/src/gui/styles/qwindowsvistastyle.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWINDOWSVISTASTYLE_H
-#define QWINDOWSVISTASTYLE_H
-
-#include <QtGui/qwindowsxpstyle.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#if !defined(QT_NO_STYLE_WINDOWSVISTA)
-
-class QWindowsVistaStylePrivate;
-class Q_GUI_EXPORT QWindowsVistaStyle : public QWindowsXPStyle
-{
- Q_OBJECT
-public:
- QWindowsVistaStyle();
-
- void drawPrimitive(PrimitiveElement element, const QStyleOption *option,
- QPainter *painter, const QWidget *widget = 0) const;
- void drawControl(ControlElement element, const QStyleOption *option,
- QPainter *painter, const QWidget *widget) const;
- void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option,
- QPainter *painter, const QWidget *widget) const;
- QSize sizeFromContents(ContentsType type, const QStyleOption *option,
- const QSize &size, const QWidget *widget) const;
-
- QRect subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const;
- QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt,
- SubControl sc, const QWidget *widget) const;
-
- SubControl hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option,
- const QPoint &pos, const QWidget *widget = 0) const;
-
- QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt,
- const QWidget *widget = 0) const;
- int pixelMetric(PixelMetric metric, const QStyleOption *option = 0, const QWidget *widget = 0) const;
- int styleHint(StyleHint hint, const QStyleOption *opt = 0, const QWidget *widget = 0,
- QStyleHintReturn *returnData = 0) const;
-
-
- void polish(QWidget *widget);
- void unpolish(QWidget *widget);
- void polish(QPalette &pal);
- void polish(QApplication *app);
- void unpolish(QApplication *app);
- bool event(QEvent *event);
- QPalette standardPalette() const;
-
-protected Q_SLOTS:
- QIcon standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *option,
- const QWidget *widget = 0) const;
-
-private:
- Q_DISABLE_COPY(QWindowsVistaStyle)
- Q_DECLARE_PRIVATE(QWindowsVistaStyle)
- friend class QStyleFactory;
-};
-#endif //QT_NO_STYLE_WINDOWSVISTA
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif //QWINDOWSVISTASTYLE_H
diff --git a/src/gui/styles/qwindowsxpstyle.cpp b/src/gui/styles/qwindowsxpstyle.cpp
deleted file mode 100644
index 3c33df3d11..0000000000
--- a/src/gui/styles/qwindowsxpstyle.cpp
+++ /dev/null
@@ -1,4277 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#include "qwindowsxpstyle.h"
-#include "qwindowsxpstyle_p.h"
-
-#if !defined(QT_NO_STYLE_WINDOWSXP) || defined(QT_PLUGIN)
-
-#include <private/qobject_p.h>
-#include <private/qpaintengine_raster_p.h>
-#include <private/qapplication_p.h>
-#include <private/qstylehelper_p.h>
-#include <private/qwidget_p.h>
-#include <private/qsystemlibrary_p.h>
-#include <qpainter.h>
-#include <qpaintengine.h>
-#include <qwidget.h>
-#include <qapplication.h>
-#include <qpixmapcache.h>
-
-#include <qdesktopwidget.h>
-#include <qtoolbutton.h>
-#include <qtabbar.h>
-#include <qcombobox.h>
-#include <qscrollbar.h>
-#include <qheaderview.h>
-#include <qspinbox.h>
-#include <qlistview.h>
-#include <qstackedwidget.h>
-#include <qpushbutton.h>
-#include <qtoolbar.h>
-#include <qlabel.h>
-#include <qvarlengtharray.h>
-#include <qdebug.h>
-
-QT_BEGIN_NAMESPACE
-
-// Runtime resolved theme engine function calls
-typedef bool (WINAPI *PtrIsAppThemed)();
-typedef bool (WINAPI *PtrIsThemeActive)();
-typedef HRESULT (WINAPI *PtrGetThemePartSize)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, OPTIONAL RECT *prc, enum THEMESIZE eSize, OUT SIZE *psz);
-typedef HTHEME (WINAPI *PtrOpenThemeData)(HWND hwnd, LPCWSTR pszClassList);
-typedef HRESULT (WINAPI *PtrCloseThemeData)(HTHEME hTheme);
-typedef HRESULT (WINAPI *PtrDrawThemeBackground)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, OPTIONAL const RECT *pClipRect);
-typedef HRESULT (WINAPI *PtrDrawThemeBackgroundEx)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, OPTIONAL const DTBGOPTS *pOptions);
-typedef HRESULT (WINAPI *PtrGetCurrentThemeName)(OUT LPWSTR pszThemeFileName, int cchMaxNameChars, OUT OPTIONAL LPWSTR pszColorBuff, int cchMaxColorChars, OUT OPTIONAL LPWSTR pszSizeBuff, int cchMaxSizeChars);
-typedef HRESULT (WINAPI *PtrGetThemeDocumentationProperty)(LPCWSTR pszThemeName, LPCWSTR pszPropertyName, OUT LPWSTR pszValueBuff, int cchMaxValChars);
-typedef HRESULT (WINAPI *PtrGetThemeBool)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT BOOL *pfVal);
-typedef HRESULT (WINAPI *PtrGetThemeColor)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT COLORREF *pColor);
-typedef HRESULT (WINAPI *PtrGetThemeEnumValue)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT int *piVal);
-typedef HRESULT (WINAPI *PtrGetThemeFilename)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT LPWSTR pszThemeFileName, int cchMaxBuffChars);
-typedef HRESULT (WINAPI *PtrGetThemeFont)(HTHEME hTheme, OPTIONAL HDC hdc, int iPartId, int iStateId, int iPropId, OUT LOGFONT *pFont);
-typedef HRESULT (WINAPI *PtrGetThemeInt)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT int *piVal);
-typedef HRESULT (WINAPI *PtrGetThemeIntList)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT INTLIST *pIntList);
-typedef HRESULT (WINAPI *PtrGetThemeMargins)(HTHEME hTheme, OPTIONAL HDC hdc, int iPartId, int iStateId, int iPropId, OPTIONAL RECT *prc, OUT MARGINS *pMargins);
-typedef HRESULT (WINAPI *PtrGetThemeMetric)(HTHEME hTheme, OPTIONAL HDC hdc, int iPartId, int iStateId, int iPropId, OUT int *piVal);
-typedef HRESULT (WINAPI *PtrGetThemePartSize)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, OPTIONAL RECT *prc, enum THEMESIZE eSize, OUT SIZE *psz);
-typedef HRESULT (WINAPI *PtrGetThemePosition)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT POINT *pPoint);
-typedef HRESULT (WINAPI *PtrGetThemePropertyOrigin)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT enum PROPERTYORIGIN *pOrigin);
-typedef HRESULT (WINAPI *PtrGetThemeRect)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT RECT *pRect);
-typedef HRESULT (WINAPI *PtrGetThemeString)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT LPWSTR pszBuff, int cchMaxBuffChars);
-typedef HRESULT (WINAPI *PtrGetThemeBackgroundRegion)(HTHEME hTheme, OPTIONAL HDC hdc, int iPartId, int iStateId, const RECT *pRect, OUT HRGN *pRegion);
-typedef BOOL (WINAPI *PtrIsThemeBackgroundPartiallyTransparent)(HTHEME hTheme, int iPartId, int iStateId);
-
-static PtrIsAppThemed pIsAppThemed = 0;
-static PtrIsThemeActive pIsThemeActive = 0;
-static PtrOpenThemeData pOpenThemeData = 0;
-static PtrCloseThemeData pCloseThemeData = 0;
-static PtrDrawThemeBackground pDrawThemeBackground = 0;
-static PtrDrawThemeBackgroundEx pDrawThemeBackgroundEx = 0;
-static PtrGetCurrentThemeName pGetCurrentThemeName = 0;
-static PtrGetThemeBool pGetThemeBool = 0;
-static PtrGetThemeColor pGetThemeColor = 0;
-static PtrGetThemeEnumValue pGetThemeEnumValue = 0;
-static PtrGetThemeFilename pGetThemeFilename = 0;
-static PtrGetThemeFont pGetThemeFont = 0;
-static PtrGetThemeInt pGetThemeInt = 0;
-static PtrGetThemeIntList pGetThemeIntList = 0;
-static PtrGetThemeMargins pGetThemeMargins = 0;
-static PtrGetThemeMetric pGetThemeMetric = 0;
-static PtrGetThemePartSize pGetThemePartSize = 0;
-static PtrGetThemePosition pGetThemePosition = 0;
-static PtrGetThemePropertyOrigin pGetThemePropertyOrigin = 0;
-static PtrGetThemeRect pGetThemeRect = 0;
-static PtrGetThemeString pGetThemeString = 0;
-static PtrGetThemeBackgroundRegion pGetThemeBackgroundRegion = 0;
-static PtrGetThemeDocumentationProperty pGetThemeDocumentationProperty = 0;
-static PtrIsThemeBackgroundPartiallyTransparent pIsThemeBackgroundPartiallyTransparent = 0;
-
-// General const values
-static const int windowsItemFrame = 2; // menu item frame width
-static const int windowsItemHMargin = 3; // menu item hor text margin
-static const int windowsItemVMargin = 0; // menu item ver text margin
-static const int windowsArrowHMargin = 6; // arrow horizontal margin
-static const int windowsRightBorder = 12; // right border on windows
-
-// External function calls
-extern Q_GUI_EXPORT HDC qt_win_display_dc();
-extern QRegion qt_region_from_HRGN(HRGN rgn);
-
-
-
-// Theme data helper ------------------------------------------------------------------------------
-/* \internal
- Returns true if the themedata is valid for use.
-*/
-bool XPThemeData::isValid()
-{
- return QWindowsXPStylePrivate::useXP() && name.size() && handle();
-}
-
-
-/* \internal
- Returns the theme engine handle to the specific class.
- If the handle hasn't been opened before, it opens the data, and
- adds it to a static map, for caching.
-*/
-HTHEME XPThemeData::handle()
-{
- if (!QWindowsXPStylePrivate::useXP())
- return 0;
-
- if (!htheme && QWindowsXPStylePrivate::handleMap)
- htheme = QWindowsXPStylePrivate::handleMap->operator[](name);
-
- if (!htheme) {
- htheme = pOpenThemeData(QWindowsXPStylePrivate::winId(widget), (wchar_t*)name.utf16());
- if (htheme) {
- if (!QWindowsXPStylePrivate::handleMap)
- QWindowsXPStylePrivate::handleMap = new QMap<QString, HTHEME>;
- QWindowsXPStylePrivate::handleMap->operator[](name) = htheme;
- }
- }
-
- return htheme;
-}
-
-/* \internal
- Converts a QRect to the native RECT structure.
-*/
-RECT XPThemeData::toRECT(const QRect &qr)
-{
- RECT r;
- r.left = qr.x();
- r.right = qr.x() + qr.width();
- r.top = qr.y();
- r.bottom = qr.y() + qr.height();
- return r;
-}
-
-/* \internal
- Returns the native region of a part, if the part is considered
- transparent. The region is scaled to the parts size (rect).
-*/
-HRGN XPThemeData::mask()
-{
- if (!pIsThemeBackgroundPartiallyTransparent(handle(), partId, stateId))
- return 0;
-
- HRGN hrgn;
- HDC dc = painter == 0 ? 0 : painter->paintEngine()->getDC();
- RECT nativeRect = toRECT(rect);
- pGetThemeBackgroundRegion(handle(), dc, partId, stateId, &nativeRect, &hrgn);
- if (dc)
- painter->paintEngine()->releaseDC(dc);
- return hrgn;
-}
-
-// QWindowsXPStylePrivate -------------------------------------------------------------------------
-// Static initializations
-QWidget *QWindowsXPStylePrivate::limboWidget = 0;
-QPixmap *QWindowsXPStylePrivate::tabbody = 0;
-QMap<QString,HTHEME> *QWindowsXPStylePrivate::handleMap = 0;
-bool QWindowsXPStylePrivate::use_xp = false;
-QBasicAtomicInt QWindowsXPStylePrivate::ref = Q_BASIC_ATOMIC_INITIALIZER(-1); // -1 based refcounting
-
-/* \internal
- Checks if the theme engine can/should be used, or if we should
- fall back to Windows style.
-*/
-bool QWindowsXPStylePrivate::useXP(bool update)
-{
- if (!update)
- return use_xp;
- return (use_xp = resolveSymbols() && pIsThemeActive()
- && (pIsAppThemed() || !QApplication::instance()));
-}
-
-/* \internal
- Handles refcounting, and queries the theme engine for usage.
-*/
-void QWindowsXPStylePrivate::init(bool force)
-{
- if (ref.ref() && !force)
- return;
- if (!force) // -1 based atomic refcounting
- ref.ref();
-
- useXP(true);
-}
-
-/* \internal
- Cleans up all static data.
-*/
-void QWindowsXPStylePrivate::cleanup(bool force)
-{
- if(bufferBitmap) {
- if (bufferDC && nullBitmap)
- SelectObject(bufferDC, nullBitmap);
- DeleteObject(bufferBitmap);
- bufferBitmap = 0;
- }
-
- if(bufferDC)
- DeleteDC(bufferDC);
- bufferDC = 0;
-
- if (ref.deref() && !force)
- return;
- if (!force) // -1 based atomic refcounting
- ref.deref();
-
- use_xp = false;
- cleanupHandleMap();
- if (limboWidget) {
- if (QApplication::closingDown())
- delete limboWidget;
- else
- limboWidget->deleteLater();
- }
- delete tabbody;
- limboWidget = 0;
- tabbody = 0;
-}
-
-/* \internal
- Closes all open theme data handles to ensure that we don't leak
- resources, and that we don't refere to old handles when for
- example the user changes the theme style.
-*/
-void QWindowsXPStylePrivate::cleanupHandleMap()
-{
- if (!handleMap)
- return;
-
- QMap<QString, HTHEME>::Iterator it;
- for (it = handleMap->begin(); it != handleMap->end(); ++it)
- pCloseThemeData(it.value());
- delete handleMap;
- handleMap = 0;
-}
-
-/*! \internal
- This function will always return a valid window handle, and might
- create a limbo widget to do so.
- We often need a window handle to for example open theme data, so
- this function ensures that we get one.
-*/
-HWND QWindowsXPStylePrivate::winId(const QWidget *widget)
-{
- if (widget && widget->internalWinId())
- return widget->internalWinId();
-
- if (!limboWidget) {
- limboWidget = new QWidget(0);
- limboWidget->createWinId();
- limboWidget->setObjectName(QLatin1String("xp_limbo_widget"));
- // We don't need this internal widget to appear in QApplication::topLevelWidgets()
- if (QWidgetPrivate::allWidgets)
- QWidgetPrivate::allWidgets->remove(limboWidget);
- }
-
- return limboWidget->winId();
-}
-
-/*! \internal
- Returns the pointer to a tab widgets body pixmap, scaled to the
- height of the screen. This way the theme engine doesn't need to
- scale the body for every time we ask for it. (Speed optimization)
-*/
-const QPixmap *QWindowsXPStylePrivate::tabBody(QWidget *)
-{
- if (!tabbody) {
- SIZE sz;
- XPThemeData theme(0, 0, QLatin1String("TAB"), TABP_BODY);
- pGetThemePartSize(theme.handle(), qt_win_display_dc(), TABP_BODY, 0, 0, TS_TRUE, &sz);
-
- tabbody = new QPixmap(sz.cx, QApplication::desktop()->screenGeometry().height());
- QPainter painter(tabbody);
- theme.rect = QRect(0, 0, sz.cx, sz.cy);
- drawBackground(theme);
- // We fill with the last line of the themedata, that
- // way we don't get a tiled pixmap inside big tabs
- QPixmap temp(sz.cx, 1);
- painter.drawPixmap(0, 0, temp, 0, sz.cy-1, -1, -1);
- painter.drawTiledPixmap(0, sz.cy, sz.cx, tabbody->height()-sz.cy, temp);
- }
- return tabbody;
-}
-
-/*! \internal
- Returns true if all the necessary theme engine symbols were
- resolved.
-*/
-bool QWindowsXPStylePrivate::resolveSymbols()
-{
- static bool tried = false;
- if (!tried) {
- tried = true;
- QSystemLibrary themeLib(QLatin1String("uxtheme"));
- pIsAppThemed = (PtrIsAppThemed)themeLib.resolve("IsAppThemed");
- if (pIsAppThemed) {
- pIsThemeActive = (PtrIsThemeActive )themeLib.resolve("IsThemeActive");
- pGetThemePartSize = (PtrGetThemePartSize )themeLib.resolve("GetThemePartSize");
- pOpenThemeData = (PtrOpenThemeData )themeLib.resolve("OpenThemeData");
- pCloseThemeData = (PtrCloseThemeData )themeLib.resolve("CloseThemeData");
- pDrawThemeBackground = (PtrDrawThemeBackground )themeLib.resolve("DrawThemeBackground");
- pDrawThemeBackgroundEx = (PtrDrawThemeBackgroundEx )themeLib.resolve("DrawThemeBackgroundEx");
- pGetCurrentThemeName = (PtrGetCurrentThemeName )themeLib.resolve("GetCurrentThemeName");
- pGetThemeBool = (PtrGetThemeBool )themeLib.resolve("GetThemeBool");
- pGetThemeColor = (PtrGetThemeColor )themeLib.resolve("GetThemeColor");
- pGetThemeEnumValue = (PtrGetThemeEnumValue )themeLib.resolve("GetThemeEnumValue");
- pGetThemeFilename = (PtrGetThemeFilename )themeLib.resolve("GetThemeFilename");
- pGetThemeFont = (PtrGetThemeFont )themeLib.resolve("GetThemeFont");
- pGetThemeInt = (PtrGetThemeInt )themeLib.resolve("GetThemeInt");
- pGetThemeIntList = (PtrGetThemeIntList )themeLib.resolve("GetThemeIntList");
- pGetThemeMargins = (PtrGetThemeMargins )themeLib.resolve("GetThemeMargins");
- pGetThemeMetric = (PtrGetThemeMetric )themeLib.resolve("GetThemeMetric");
- pGetThemePartSize = (PtrGetThemePartSize )themeLib.resolve("GetThemePartSize");
- pGetThemePosition = (PtrGetThemePosition )themeLib.resolve("GetThemePosition");
- pGetThemePropertyOrigin = (PtrGetThemePropertyOrigin)themeLib.resolve("GetThemePropertyOrigin");
- pGetThemeRect = (PtrGetThemeRect )themeLib.resolve("GetThemeRect");
- pGetThemeString = (PtrGetThemeString )themeLib.resolve("GetThemeString");
- pGetThemeBackgroundRegion = (PtrGetThemeBackgroundRegion )themeLib.resolve("GetThemeBackgroundRegion");
- pGetThemeDocumentationProperty = (PtrGetThemeDocumentationProperty )themeLib.resolve("GetThemeDocumentationProperty");
- pIsThemeBackgroundPartiallyTransparent = (PtrIsThemeBackgroundPartiallyTransparent)themeLib.resolve("IsThemeBackgroundPartiallyTransparent");
- }
- }
-
- return pIsAppThemed != 0;
-}
-
-/*! \internal
- Returns a native buffer (DIB section) of at least the size of
- ( \a x , \a y ). The buffer has a 32 bit depth, to not lose
- the alpha values on proper alpha-pixmaps.
-*/
-HBITMAP QWindowsXPStylePrivate::buffer(int w, int h)
-{
- // If we already have a HBITMAP which is of adequate size, just return that
- if (bufferBitmap) {
- if (bufferW >= w && bufferH >= h)
- return bufferBitmap;
- // Not big enough, discard the old one
- if (bufferDC && nullBitmap)
- SelectObject(bufferDC, nullBitmap);
- DeleteObject(bufferBitmap);
- bufferBitmap = 0;
- }
-
- w = qMax(bufferW, w);
- h = qMax(bufferH, h);
-
- if (!bufferDC)
- bufferDC = CreateCompatibleDC(qt_win_display_dc());
-
- // Define the header
- BITMAPINFO bmi;
- memset(&bmi, 0, sizeof(bmi));
- bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- bmi.bmiHeader.biWidth = w;
- bmi.bmiHeader.biHeight = -h;
- bmi.bmiHeader.biPlanes = 1;
- bmi.bmiHeader.biBitCount = 32;
- bmi.bmiHeader.biCompression = BI_RGB;
-
- // Create the pixmap
- bufferPixels = 0;
- bufferBitmap = CreateDIBSection(bufferDC, &bmi, DIB_RGB_COLORS, (void **) &bufferPixels, 0, 0);
- GdiFlush();
- nullBitmap = (HBITMAP)SelectObject(bufferDC, bufferBitmap);
-
- if (!bufferBitmap) {
- qErrnoWarning("QWindowsXPStylePrivate::buffer(w,h), failed to create dibsection");
- bufferW = 0;
- bufferH = 0;
- return 0;
- }
- if (!bufferPixels) {
- qErrnoWarning("QWindowsXPStylePrivate::buffer(w,h), did not allocate pixel data");
- bufferW = 0;
- bufferH = 0;
- return 0;
- }
- bufferW = w;
- bufferH = h;
-#ifdef DEBUG_XP_STYLE
- qDebug("Creating new dib section (%d, %d)", w, h);
-#endif
- return bufferBitmap;
-}
-
-/*! \internal
- Returns true if the part contains any transparency at all. This does
- not indicate what kind of transparency we're dealing with. It can be
- - Alpha transparency
- - Masked transparency
-*/
-bool QWindowsXPStylePrivate::isTransparent(XPThemeData &themeData)
-{
- return pIsThemeBackgroundPartiallyTransparent(themeData.handle(), themeData.partId,
- themeData.stateId);
-}
-
-
-/*! \internal
- Returns a QRegion of the region of the part
-*/
-QRegion QWindowsXPStylePrivate::region(XPThemeData &themeData)
-{
- HRGN hRgn = 0;
- RECT rect = themeData.toRECT(themeData.rect);
- if (!SUCCEEDED(pGetThemeBackgroundRegion(themeData.handle(), bufferHDC(), themeData.partId,
- themeData.stateId, &rect, &hRgn)))
- return QRegion();
-
- HRGN dest = CreateRectRgn(0, 0, 0, 0);
- const bool success = CombineRgn(dest, hRgn, 0, RGN_COPY) != ERROR;
-
- QRegion region;
-
- if (success)
- region = qt_region_from_HRGN(dest);
-
- DeleteObject(hRgn);
- DeleteObject(dest);
-
- return region;
-}
-
-/*! \internal
- Sets the parts region on a window.
-*/
-void QWindowsXPStylePrivate::setTransparency(QWidget *widget, XPThemeData &themeData)
-{
- HRGN hrgn = themeData.mask();
- if (hrgn && widget)
- SetWindowRgn(winId(widget), hrgn, true);
-}
-
-/*! \internal
- Returns true if the native doublebuffer contains a pixel which
- has a non-0xFF alpha value. Should only be use when its
- guaranteed that data painted into the buffer wasn't a proper
- alpha pixmap.
-*/
-bool QWindowsXPStylePrivate::hasAnyData(const QRect &rect)
-{
- const int startX = rect.left();
- const int startY = rect.top();
- const int w = rect.width();
- const int h = rect.height();
-
- for (int y = startY; y < h; ++y) {
- register DWORD *buffer = (DWORD*)bufferPixels + (y * bufferW);
- for (int x = startX; x < w; ++x, ++buffer) {
- int alpha = (*buffer) >> 24;
- if (alpha != 0xFF) // buffer has been touched
- return true;
- }
- }
- return false;
-}
-
-/*! \internal
- Returns true if the native doublebuffer contains pixels with
- varying alpha value.
-*/
-bool QWindowsXPStylePrivate::hasAlphaChannel(const QRect &rect)
-{
- const int startX = rect.left();
- const int startY = rect.top();
- const int w = rect.width();
- const int h = rect.height();
-
- int firstAlpha = -1;
- for (int y = startY; y < h/2; ++y) {
- register DWORD *buffer = (DWORD*)bufferPixels + (y * bufferW);
- for (int x = startX; x < w; ++x, ++buffer) {
- int alpha = (*buffer) >> 24;
- if (firstAlpha == -1)
- firstAlpha = alpha;
- else if (alpha != firstAlpha)
- return true;
- }
- }
- return false;
-}
-
-/*! \internal
- When the theme engine paints both a true alpha pixmap and a glyph
- into our buffer, the glyph might not contain a proper alpha value.
- The rule of thumb for premultiplied pixmaps is that the color
- values of a pixel can never be higher than the alpha values, so
- we use this to our advantage here, and fix all instances where
- this occures.
-*/
-bool QWindowsXPStylePrivate::fixAlphaChannel(const QRect &rect)
-{
- const int startX = rect.left();
- const int startY = rect.top();
- const int w = rect.width();
- const int h = rect.height();
- bool hasFixedAlphaValue = false;
-
- for (int y = startY; y < h; ++y) {
- register DWORD *buffer = (DWORD*)bufferPixels + (y * bufferW);
- for (register int x = startX; x < w; ++x, ++buffer) {
- uint pixel = *buffer;
- int alpha = qAlpha(pixel);
- if (qRed(pixel) > alpha || qGreen(pixel) > alpha || qBlue(pixel) > alpha) {
- *buffer |= 0xff000000;
- hasFixedAlphaValue = true;
- }
- }
- }
- return hasFixedAlphaValue;
-}
-
-/*! \internal
- Swaps the alpha values on certain pixels:
- 0xFF?????? -> 0x00??????
- 0x00?????? -> 0xFF??????
- Used to determin the mask of a non-alpha transparent pixmap in
- the native doublebuffer, and swap the alphas so we may paint
- the image as a Premultiplied QImage with drawImage(), and obtain
- the mask transparency.
-*/
-bool QWindowsXPStylePrivate::swapAlphaChannel(const QRect &rect, bool allPixels)
-{
- const int startX = rect.left();
- const int startY = rect.top();
- const int w = rect.width();
- const int h = rect.height();
- bool valueChange = false;
-
- // Flip the alphas, so that 255-alpha pixels are 0, and 0-alpha are 255.
- for (int y = startY; y < h; ++y) {
- register DWORD *buffer = (DWORD*)bufferPixels + (y * bufferW);
- for (register int x = startX; x < w; ++x, ++buffer) {
- if (allPixels) {
- *buffer |= 0xFF000000;
- continue;
- }
- register unsigned int alphaValue = (*buffer) & 0xFF000000;
- if (alphaValue == 0xFF000000) {
- *buffer = 0;
- valueChange = true;
- } else if (alphaValue == 0) {
- *buffer |= 0xFF000000;
- valueChange = true;
- }
- }
- }
- return valueChange;
-}
-
-/*! \internal
- Main theme drawing function.
- Determines the correct lowlevel drawing method depending on several
- factors.
- Use drawBackgroundThruNativeBuffer() if:
- - Painter does not have an HDC
- - Theme part is flipped (mirrored horizontally)
- else use drawBackgroundDirectly().
-*/
-void QWindowsXPStylePrivate::drawBackground(XPThemeData &themeData)
-{
- if (themeData.rect.isEmpty())
- return;
-
- QPainter *painter = themeData.painter;
- Q_ASSERT_X(painter != 0, "QWindowsXPStylePrivate::drawBackground()", "Trying to draw a theme part without a painter");
- if (!painter || !painter->isActive())
- return;
-
- painter->save();
-
- bool complexXForm = painter->deviceTransform().type() > QTransform::TxTranslate;
-
- bool translucentToplevel = false;
- QPaintDevice *pdev = painter->device();
- if (pdev->devType() == QInternal::Widget) {
- QWidget *win = ((QWidget *) pdev)->window();
- translucentToplevel = win->testAttribute(Qt::WA_TranslucentBackground);
- }
-
- bool useFallback = painter->paintEngine()->getDC() == 0
- || painter->opacity() != 1.0
- || themeData.rotate
- || complexXForm
- || themeData.mirrorVertically
- || (themeData.mirrorHorizontally && pDrawThemeBackgroundEx == 0)
- || translucentToplevel;
-
- if (!useFallback)
- drawBackgroundDirectly(themeData);
- else
- drawBackgroundThruNativeBuffer(themeData);
-
- painter->restore();
-}
-
-/*! \internal
- This function draws the theme parts directly to the paintengines HDC.
- Do not use this if you need to perform other transformations on the
- resulting data.
-*/
-void QWindowsXPStylePrivate::drawBackgroundDirectly(XPThemeData &themeData)
-{
- QPainter *painter = themeData.painter;
- HDC dc = painter->paintEngine()->getDC();
-
- QPoint redirectionDelta(int(painter->deviceMatrix().dx()),
- int(painter->deviceMatrix().dy()));
- QRect area = themeData.rect.translated(redirectionDelta);
-
- QRegion sysRgn = painter->paintEngine()->systemClip();
- if (sysRgn.isEmpty())
- sysRgn = area;
- else
- sysRgn &= area;
- if (painter->hasClipping())
- sysRgn &= painter->clipRegion().translated(redirectionDelta);
- SelectClipRgn(dc, sysRgn.handle());
-
-#ifdef DEBUG_XP_STYLE
- printf("---[ DIRECT PAINTING ]------------------> Name(%-10s) Part(%d) State(%d)\n",
- qPrintable(themeData.name), themeData.partId, themeData.stateId);
- showProperties(themeData);
-#endif
-
- RECT drawRECT = themeData.toRECT(area);
- DTBGOPTS drawOptions;
- drawOptions.dwSize = sizeof(drawOptions);
- drawOptions.rcClip = themeData.toRECT(sysRgn.boundingRect());
- drawOptions.dwFlags = DTBG_CLIPRECT
- | (themeData.noBorder ? DTBG_OMITBORDER : 0)
- | (themeData.noContent ? DTBG_OMITCONTENT : 0)
- | (themeData.mirrorHorizontally ? DTBG_MIRRORDC : 0);
-
- if (pDrawThemeBackgroundEx != 0) {
- pDrawThemeBackgroundEx(themeData.handle(), dc, themeData.partId, themeData.stateId, &(drawRECT), &drawOptions);
- } else {
- // We are running on a system where the uxtheme.dll does not have
- // the DrawThemeBackgroundEx function, so we need to clip away
- // borders or contents manually. All flips and mirrors uses the
- // fallback implementation
-
- int borderSize = 0;
- PROPERTYORIGIN origin = PO_NOTFOUND;
- pGetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, TMT_BORDERSIZE, &origin);
- pGetThemeInt(themeData.handle(), themeData.partId, themeData.stateId, TMT_BORDERSIZE, &borderSize);
-
- // Clip away border region
- QRegion extraClip = sysRgn;
- if ((origin == PO_CLASS || origin == PO_PART || origin == PO_STATE) && borderSize > 0) {
- if (themeData.noBorder) {
- // extraClip &= area is already done
- drawRECT = themeData.toRECT(area.adjusted(-borderSize, -borderSize, borderSize, borderSize));
- }
-
- // Clip away content region
- if (themeData.noContent) {
- QRegion content = area.adjusted(borderSize, borderSize, -borderSize, -borderSize);
- extraClip ^= content;
- }
-
- // Set the clip region, if used..
- if (themeData.noBorder || themeData.noContent)
- SelectClipRgn(dc, extraClip.handle());
- }
-
- pDrawThemeBackground(themeData.handle(), dc, themeData.partId, themeData.stateId, &(drawRECT), &(drawOptions.rcClip));
- }
- SelectClipRgn(dc, 0);
-}
-
-/*! \internal
- This function uses a secondary Native doublebuffer for painting parts.
- It should only be used when the painteengine doesn't provide a proper
- HDC for direct painting (e.g. when doing a grabWidget(), painting to
- other pixmaps etc), or when special transformations are needed (e.g.
- flips (horizonal mirroring only, vertical are handled by the theme
- engine).
-*/
-void QWindowsXPStylePrivate::drawBackgroundThruNativeBuffer(XPThemeData &themeData)
-{
- QPainter *painter = themeData.painter;
- QRect rect = themeData.rect;
-
- if ((themeData.rotate + 90) % 180 == 0) { // Catch 90,270,etc.. degree flips.
- rect = QRect(0, 0, rect.height(), rect.width());
- }
- rect.moveTo(0,0);
- int partId = themeData.partId;
- int stateId = themeData.stateId;
- int w = rect.width();
- int h = rect.height();
-
- // Values initialized later, either from cached values, or from function calls
- AlphaChannelType alphaType = UnknownAlpha;
- bool stateHasData = true; // We assume so;
- bool hasAlpha = false;
- bool partIsTransparent;
- bool inspectData;
- bool potentialInvalidAlpha;
-
- QString pixmapCacheKey = QString::fromLatin1("$qt_xp_%1p%2s%3s%4b%5c%6w%7h").arg(themeData.name)
- .arg(partId).arg(stateId).arg(!themeData.noBorder).arg(!themeData.noContent)
- .arg(w).arg(h);
- QPixmap cachedPixmap;
- ThemeMapKey key(themeData);
- ThemeMapData data = alphaCache.value(key);
-
- bool haveCachedPixmap = false;
- bool isCached = data.dataValid;
- if (isCached) {
- if (!(stateHasData = data.hasAnyData))
- return; // Cached NOOP
- inspectData = data.wasAlphaSwapped;
- partIsTransparent = data.partIsTransparent;
- hasAlpha = data.hasAlphaChannel;
- alphaType = data.alphaType;
- potentialInvalidAlpha = data.hadInvalidAlpha;
-
- haveCachedPixmap = QPixmapCache::find(pixmapCacheKey, cachedPixmap);
-
-#ifdef DEBUG_XP_STYLE
- char buf[25];
- ::sprintf(buf, "+ Pixmap(%3d, %3d) ]", w, h);
- printf("---[ CACHED %s--------> Name(%-10s) Part(%d) State(%d)\n",
- haveCachedPixmap ? buf : "]-------------------",
- qPrintable(themeData.name), themeData.partId, themeData.stateId);
-#endif
- } else {
- // Not cached, so get values from Theme Engine
- BOOL tmt_borderonly = false;
- COLORREF tmt_transparentcolor = 0x0;
- PROPERTYORIGIN proporigin = PO_NOTFOUND;
- pGetThemeBool(themeData.handle(), themeData.partId, themeData.stateId, TMT_BORDERONLY, &tmt_borderonly);
- pGetThemeColor(themeData.handle(), themeData.partId, themeData.stateId, TMT_TRANSPARENTCOLOR, &tmt_transparentcolor);
- pGetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, TMT_CAPTIONMARGINS, &proporigin);
- inspectData = (tmt_transparentcolor != 0 || tmt_borderonly || proporigin == PO_PART || proporigin == PO_STATE);
-
- // ### This is a vista-specific workaround for broken alpha in titlebar pixmaps
- if ((QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)) {
- if (themeData.partId == WP_CAPTION || themeData.partId == WP_SMALLCAPTION)
- inspectData = false;
- }
-
- partIsTransparent = isTransparent(themeData);
-
- potentialInvalidAlpha = false;
- pGetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, TMT_GLYPHTYPE, &proporigin);
- if (proporigin == PO_PART || proporigin == PO_STATE) {
- int tmt_glyphtype = GT_NONE;
- pGetThemeEnumValue(themeData.handle(), themeData.partId, themeData.stateId, TMT_GLYPHTYPE, &tmt_glyphtype);
- potentialInvalidAlpha = partIsTransparent && !inspectData && tmt_glyphtype == GT_IMAGEGLYPH;
- }
-
-#ifdef DEBUG_XP_STYLE
- printf("---[ NOT CACHED ]-----------------------> Name(%-10s) Part(%d) State(%d)\n",
- qPrintable(themeData.name), themeData.partId, themeData.stateId);
- printf("-->partIsTransparen = %d\n", partIsTransparent);
- printf("-->inspectData = %d\n", inspectData);
- printf("-->potentialInvalidAlpha = %d\n", potentialInvalidAlpha);
- showProperties(themeData);
-#endif
- }
- bool wasAlphaSwapped = false;
- bool wasAlphaFixed = false;
-
- // OLD PSDK Workaround ------------------------------------------------------------------------
- // See if we need extra clipping for the older PSDK, which does
- // not have a DrawThemeBackgroundEx function for DTGB_OMITBORDER
- // and DTGB_OMITCONTENT
- bool addBorderContentClipping = false;
- QRegion extraClip;
- QRect area = rect;
- if (themeData.noBorder || themeData.noContent) {
- extraClip = area;
- // We are running on a system where the uxtheme.dll does not have
- // the DrawThemeBackgroundEx function, so we need to clip away
- // borders or contents manually.
-
- int borderSize = 0;
- PROPERTYORIGIN origin = PO_NOTFOUND;
- pGetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, TMT_BORDERSIZE, &origin);
- pGetThemeInt(themeData.handle(), themeData.partId, themeData.stateId, TMT_BORDERSIZE, &borderSize);
-
- // Clip away border region
- if ((origin == PO_CLASS || origin == PO_PART || origin == PO_STATE) && borderSize > 0) {
- if (themeData.noBorder) {
- extraClip &= area;
- area = area.adjusted(-borderSize, -borderSize, borderSize, borderSize);
- }
-
- // Clip away content region
- if (themeData.noContent) {
- QRegion content = area.adjusted(borderSize, borderSize, -borderSize, -borderSize);
- extraClip ^= content;
- }
- }
- addBorderContentClipping = (themeData.noBorder | themeData.noContent);
- }
-
- QImage img;
- if (!haveCachedPixmap) { // If the pixmap is not cached, generate it! -------------------------
- buffer(w, h); // Ensure a buffer of at least (w, h) in size
- HDC dc = bufferHDC();
-
- // Clear the buffer
- if (alphaType != NoAlpha) {
- // Consider have separate "memset" function for small chunks for more speedup
- memset(bufferPixels, inspectData ? 0xFF : 0x00, bufferW * h * 4);
- }
-
- // Difference between area and rect
- int dx = area.x() - rect.x();
- int dy = area.y() - rect.y();
- int dr = area.right() - rect.right();
- int db = area.bottom() - rect.bottom();
-
- // Adjust so painting rect starts from Origo
- rect.moveTo(0,0);
- area.moveTo(dx,dy);
- DTBGOPTS drawOptions;
- drawOptions.dwSize = sizeof(drawOptions);
- drawOptions.rcClip = themeData.toRECT(rect);
- drawOptions.dwFlags = DTBG_CLIPRECT
- | (themeData.noBorder ? DTBG_OMITBORDER : 0)
- | (themeData.noContent ? DTBG_OMITCONTENT : 0);
-
- // Drawing the part into the backing store
- if (pDrawThemeBackgroundEx != 0) {
- RECT rect(themeData.toRECT(area));
- pDrawThemeBackgroundEx(themeData.handle(), dc, themeData.partId, themeData.stateId, &rect, &drawOptions);
- } else {
- // Set the clip region, if used..
- if (addBorderContentClipping) {
- SelectClipRgn(dc, extraClip.handle());
- // Compensate for the noBorder area difference (noContent has the same area)
- drawOptions.rcClip = themeData.toRECT(rect.adjusted(dx, dy, dr, db));
- }
-
- pDrawThemeBackground(themeData.handle(), dc, themeData.partId, themeData.stateId, &(drawOptions.rcClip), 0);
-
- if (addBorderContentClipping)
- SelectClipRgn(dc, 0);
- }
-
- // If not cached, analyze the buffer data to figure
- // out alpha type, and if it contains data
- if (!isCached) {
- if (inspectData)
- stateHasData = hasAnyData(rect);
- // SHORTCUT: If the part's state has no data, cache it for NOOP later
- if (!stateHasData) {
- memset(&data, 0, sizeof(data));
- data.dataValid = true;
- alphaCache.insert(key, data);
- return;
- }
- hasAlpha = hasAlphaChannel(rect);
- if (!hasAlpha && partIsTransparent)
- potentialInvalidAlpha = true;
-#if defined(DEBUG_XP_STYLE) && 1
- dumpNativeDIB(w, h);
-#endif
- }
-
- // Swap alpha values, if needed
- if (inspectData)
- wasAlphaSwapped = swapAlphaChannel(rect);
-
- // Fix alpha values, if needed
- if (potentialInvalidAlpha)
- wasAlphaFixed = fixAlphaChannel(rect);
-
- QImage::Format format;
- if ((partIsTransparent && !wasAlphaSwapped) || (!partIsTransparent && hasAlpha)) {
- format = QImage::Format_ARGB32_Premultiplied;
- alphaType = RealAlpha;
- } else if (wasAlphaSwapped) {
- format = QImage::Format_ARGB32_Premultiplied;
- alphaType = MaskAlpha;
- } else {
- format = QImage::Format_RGB32;
- // The image data we got from the theme engine does not have any transparency,
- // thus the alpha channel is set to 0.
- // However, Format_RGB32 requires the alpha part to be set to 0xff, thus
- // we must flip it from 0x00 to 0xff
- swapAlphaChannel(rect, true);
- alphaType = NoAlpha;
- }
-#if defined(DEBUG_XP_STYLE) && 1
- printf("Image format is: %s\n", alphaType == RealAlpha ? "Real Alpha" : alphaType == MaskAlpha ? "Masked Alpha" : "No Alpha");
-#endif
- img = QImage(bufferPixels, bufferW, bufferH, format);
- }
-
- // Blitting backing store
- bool useRegion = partIsTransparent && !hasAlpha && !wasAlphaSwapped;
-
- QRegion newRegion;
- QRegion oldRegion;
- if (useRegion) {
- newRegion = region(themeData);
- oldRegion = painter->clipRegion();
- painter->setClipRegion(newRegion);
-#if defined(DEBUG_XP_STYLE) && 0
- printf("Using region:\n");
- QVector<QRect> rects = newRegion.rects();
- for (int i = 0; i < rects.count(); ++i) {
- const QRect &r = rects.at(i);
- printf(" (%d, %d, %d, %d)\n", r.x(), r.y(), r.right(), r.bottom());
- }
-#endif
- }
-
- if (addBorderContentClipping)
- painter->setClipRegion(extraClip, Qt::IntersectClip);
-
- if (!themeData.mirrorHorizontally && !themeData.mirrorVertically && !themeData.rotate) {
- if (!haveCachedPixmap)
- painter->drawImage(themeData.rect, img, rect);
- else
- painter->drawPixmap(themeData.rect, cachedPixmap);
- } else {
- // This is _slow_!
- // Make a copy containing only the necessary data, and mirror
- // on all wanted axes. Then draw the copy.
- // If cached, the normal pixmap is cached, instead of caching
- // all possible orientations for each part and state.
- QImage imgCopy;
- if (!haveCachedPixmap)
- imgCopy = img.copy(rect);
- else
- imgCopy = cachedPixmap.toImage();
-
- if (themeData.rotate) {
- QMatrix rotMatrix;
- rotMatrix.rotate(themeData.rotate);
- imgCopy = imgCopy.transformed(rotMatrix);
- }
- if (themeData.mirrorHorizontally || themeData.mirrorVertically) {
- imgCopy = imgCopy.mirrored(themeData.mirrorHorizontally, themeData.mirrorVertically);
- }
- painter->drawImage(themeData.rect,
- imgCopy);
- }
-
- if (useRegion || addBorderContentClipping) {
- if (oldRegion.isEmpty())
- painter->setClipping(false);
- else
- painter->setClipRegion(oldRegion);
- }
-
- // Cache the pixmap to avoid expensive swapAlphaChannel() calls
- if (!haveCachedPixmap && w && h) {
- QPixmap pix = QPixmap::fromImage(img).copy(rect);
- QPixmapCache::insert(pixmapCacheKey, pix);
-#ifdef DEBUG_XP_STYLE
- printf("+++Adding pixmap to cache, size(%d, %d), wasAlphaSwapped(%d), wasAlphaFixed(%d), name(%s)\n",
- w, h, wasAlphaSwapped, wasAlphaFixed, qPrintable(pixmapCacheKey));
-#endif
- }
-
- // Add to theme part cache
- if (!isCached) {
- memset(&data, 0, sizeof(data));
- data.dataValid = true;
- data.partIsTransparent = partIsTransparent;
- data.alphaType = alphaType;
- data.hasAlphaChannel = hasAlpha;
- data.hasAnyData = stateHasData;
- data.wasAlphaSwapped = wasAlphaSwapped;
- data.hadInvalidAlpha = wasAlphaFixed;
- alphaCache.insert(key, data);
- }
-}
-
-
-// ------------------------------------------------------------------------------------------------
-
-/*!
- \class QWindowsXPStyle
- \brief The QWindowsXPStyle class provides a Microsoft Windows XP-like look and feel.
-
- \ingroup appearance
-
- \warning This style is only available on the Windows XP platform
- because it makes use of Windows XP's style engine.
-
- Most of the functions are documented in the base classes
- QWindowsStyle, QCommonStyle, and QStyle, but the
- QWindowsXPStyle overloads of drawComplexControl(), drawControl(),
- drawControlMask(), drawPrimitive(), proxy()->subControlRect(), and
- sizeFromContents(), are documented here.
-
- \img qwindowsxpstyle.png
- \sa QMacStyle, QWindowsStyle, QPlastiqueStyle, QCDEStyle, QMotifStyle
-*/
-
-/*!
- Constructs a QWindowsStyle
-*/
-QWindowsXPStyle::QWindowsXPStyle()
- : QWindowsStyle(*new QWindowsXPStylePrivate)
-{
-}
-
-/*!
- Destroys the style.
-*/
-QWindowsXPStyle::~QWindowsXPStyle()
-{
-}
-
-/*! \reimp */
-void QWindowsXPStyle::unpolish(QApplication *app)
-{
- QWindowsStyle::unpolish(app);
-}
-
-/*! \reimp */
-void QWindowsXPStyle::polish(QApplication *app)
-{
- QWindowsStyle::polish(app);
- if (!QWindowsXPStylePrivate::useXP())
- return;
-}
-
-/*! \reimp */
-void QWindowsXPStyle::polish(QWidget *widget)
-{
- QWindowsStyle::polish(widget);
- if (!QWindowsXPStylePrivate::useXP())
- return;
-
- if (qobject_cast<QAbstractButton*>(widget)
- || qobject_cast<QToolButton*>(widget)
- || qobject_cast<QTabBar*>(widget)
-#ifndef QT_NO_COMBOBOX
- || qobject_cast<QComboBox*>(widget)
-#endif // QT_NO_COMBOBOX
- || qobject_cast<QScrollBar*>(widget)
- || qobject_cast<QSlider*>(widget)
- || qobject_cast<QHeaderView*>(widget)
-#ifndef QT_NO_SPINBOX
- || qobject_cast<QAbstractSpinBox*>(widget)
- || qobject_cast<QSpinBox*>(widget)
-#endif // QT_NO_SPINBOX
- || widget->inherits("QWorkspaceChild")
- || widget->inherits("Q3TitleBar"))
- widget->setAttribute(Qt::WA_Hover);
-
-#ifndef QT_NO_RUBBERBAND
- if (qobject_cast<QRubberBand*>(widget)) {
- widget->setWindowOpacity(0.6);
- }
-#endif
- if (qobject_cast<QStackedWidget*>(widget) &&
- qobject_cast<QTabWidget*>(widget->parent()))
- widget->parentWidget()->setAttribute(Qt::WA_ContentsPropagated);
-
- Q_D(QWindowsXPStyle);
- if (!d->hasInitColors) {
- // Get text color for group box labels
- COLORREF cref;
- XPThemeData theme(0, 0, QLatin1String("BUTTON"), 0, 0);
- pGetThemeColor(theme.handle(), BP_GROUPBOX, GBS_NORMAL, TMT_TEXTCOLOR, &cref);
- d->groupBoxTextColor = qRgb(GetRValue(cref), GetGValue(cref), GetBValue(cref));
- pGetThemeColor(theme.handle(), BP_GROUPBOX, GBS_DISABLED, TMT_TEXTCOLOR, &cref);
- d->groupBoxTextColorDisabled = qRgb(GetRValue(cref), GetGValue(cref), GetBValue(cref));
- // Where does this color come from?
- //pGetThemeColor(theme.handle(), TKP_TICS, TSS_NORMAL, TMT_COLOR, &cref);
- d->sliderTickColor = qRgb(165, 162, 148);
- d->hasInitColors = true;
- }
-}
-
-/*! \reimp */
-void QWindowsXPStyle::polish(QPalette &pal)
-{
- QWindowsStyle::polish(pal);
- pal.setBrush(QPalette::AlternateBase, pal.base().color().darker(110));
-}
-
-/*! \reimp */
-void QWindowsXPStyle::unpolish(QWidget *widget)
-{
-#ifndef QT_NO_RUBBERBAND
- if (qobject_cast<QRubberBand*>(widget)) {
- widget->setWindowOpacity(1.0);
- }
-#endif
- Q_D(QWindowsXPStyle);
- // Unpolish of widgets is the first thing that
- // happens when a theme changes, or the theme
- // engine is turned off. So we detect it here.
- bool oldState = QWindowsXPStylePrivate::useXP();
- bool newState = QWindowsXPStylePrivate::useXP(true);
- if ((oldState != newState) && newState) {
- d->cleanup(true);
- d->init(true);
- } else {
- // Cleanup handle map, if just changing style,
- // or turning it on. In both cases the values
- // already in the map might be old (other style).
- d->cleanupHandleMap();
- }
- if (qobject_cast<QAbstractButton*>(widget)
- || qobject_cast<QToolButton*>(widget)
- || qobject_cast<QTabBar*>(widget)
-#ifndef QT_NO_COMBOBOX
- || qobject_cast<QComboBox*>(widget)
-#endif // QT_NO_COMBOBOX
- || qobject_cast<QScrollBar*>(widget)
- || qobject_cast<QSlider*>(widget)
- || qobject_cast<QHeaderView*>(widget)
-#ifndef QT_NO_SPINBOX
- || qobject_cast<QAbstractSpinBox*>(widget)
- || qobject_cast<QSpinBox*>(widget)
-#endif // QT_NO_SPINBOX
- || widget->inherits("QWorkspaceChild")
- || widget->inherits("Q3TitleBar"))
- widget->setAttribute(Qt::WA_Hover, false);
- QWindowsStyle::unpolish(widget);
-}
-
-/*! \reimp */
-QRect QWindowsXPStyle::subElementRect(SubElement sr, const QStyleOption *option, const QWidget *widget) const
-{
- if (!QWindowsXPStylePrivate::useXP()) {
- return QWindowsStyle::subElementRect(sr, option, widget);
- }
-
- QRect rect(option->rect);
- switch(sr) {
- case SE_DockWidgetCloseButton:
- case SE_DockWidgetFloatButton:
- rect = QWindowsStyle::subElementRect(sr, option, widget);
- return rect.translated(0, 1);
- break;
- case SE_TabWidgetTabContents:
- if (qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(option))
- {
- rect = QWindowsStyle::subElementRect(sr, option, widget);
- if (sr == SE_TabWidgetTabContents) {
- if (const QTabWidget *tabWidget = qobject_cast<const QTabWidget *>(widget)) {
- if (tabWidget->documentMode())
- break;
- }
-
- rect.adjust(0, 0, -2, -2);
- }
- }
- break;
- case SE_TabWidgetTabBar: {
- rect = QWindowsStyle::subElementRect(sr, option, widget);
- const QStyleOptionTabWidgetFrame *twfOption =
- qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(option);
- if (twfOption && twfOption->direction == Qt::RightToLeft
- && (twfOption->shape == QTabBar::RoundedNorth
- || twfOption->shape == QTabBar::RoundedSouth))
- {
- QStyleOptionTab otherOption;
- otherOption.shape = (twfOption->shape == QTabBar::RoundedNorth
- ? QTabBar::RoundedEast : QTabBar::RoundedSouth);
- int overlap = proxy()->pixelMetric(PM_TabBarBaseOverlap, &otherOption, widget);
- int borderThickness = proxy()->pixelMetric(PM_DefaultFrameWidth, option, widget);
- rect.adjust(-overlap + borderThickness, 0, -overlap + borderThickness, 0);
- }
- break;}
-
- case SE_PushButtonContents:
- if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
- MARGINS borderSize;
- if (widget) {
- XPThemeData buttontheme(widget, 0, QLatin1String("Button"));
- HTHEME theme = buttontheme.handle();
- if (theme) {
- int stateId;
- if (!(option->state & State_Enabled))
- stateId = PBS_DISABLED;
- else if (option->state & State_Sunken)
- stateId = PBS_PRESSED;
- else if (option->state & State_MouseOver)
- stateId = PBS_HOT;
- else if (btn->features & QStyleOptionButton::DefaultButton)
- stateId = PBS_DEFAULTED;
- else
- stateId = PBS_NORMAL;
-
- int border = proxy()->pixelMetric(PM_DefaultFrameWidth, btn, widget);
- rect = option->rect.adjusted(border, border, -border, -border);
-
- int result = pGetThemeMargins(theme,
- NULL,
- BP_PUSHBUTTON,
- stateId,
- TMT_CONTENTMARGINS,
- NULL,
- &borderSize);
-
- if (result == S_OK) {
- rect.adjust(borderSize.cxLeftWidth, borderSize.cyTopHeight,
- -borderSize.cxRightWidth, -borderSize.cyBottomHeight);
- rect = visualRect(option->direction, option->rect, rect);
- }
- }
- }
- }
- break;
- case SE_ProgressBarContents:
- rect = QCommonStyle::subElementRect(SE_ProgressBarGroove, option, widget);
- if (option->state & QStyle::State_Horizontal)
- rect.adjust(4, 3, -4, -3);
- else
- rect.adjust(3, 2, -3, -2);
- break;
- default:
- rect = QWindowsStyle::subElementRect(sr, option, widget);
- }
- return rect;
-}
-
-/*!
- \reimp
-*/
-void QWindowsXPStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *option, QPainter *p,
- const QWidget *widget) const
-{
- QWindowsXPStylePrivate *d = const_cast<QWindowsXPStylePrivate*>(d_func());
-
- if (!QWindowsXPStylePrivate::useXP()) {
- QWindowsStyle::drawPrimitive(pe, option, p, widget);
- return;
- }
-
- QString name;
- int partId = 0;
- int stateId = 0;
- QRect rect = option->rect;
- State flags = option->state;
- bool hMirrored = false;
- bool vMirrored = false;
- bool noBorder = false;
- bool noContent = false;
- int rotate = 0;
-
- switch (pe) {
- case PE_FrameTabBarBase:
- if (const QStyleOptionTabBarBase *tbb
- = qstyleoption_cast<const QStyleOptionTabBarBase *>(option)) {
- p->save();
- switch (tbb->shape) {
- case QTabBar::RoundedNorth:
- p->setPen(QPen(tbb->palette.dark(), 0));
- p->drawLine(tbb->rect.topLeft(), tbb->rect.topRight());
- break;
- case QTabBar::RoundedWest:
- p->setPen(QPen(tbb->palette.dark(), 0));
- p->drawLine(tbb->rect.left(), tbb->rect.top(), tbb->rect.left(), tbb->rect.bottom());
- break;
- case QTabBar::RoundedSouth:
- p->setPen(QPen(tbb->palette.dark(), 0));
- p->drawLine(tbb->rect.left(), tbb->rect.top(),
- tbb->rect.right(), tbb->rect.top());
- break;
- case QTabBar::RoundedEast:
- p->setPen(QPen(tbb->palette.dark(), 0));
- p->drawLine(tbb->rect.topLeft(), tbb->rect.bottomLeft());
- break;
- case QTabBar::TriangularNorth:
- case QTabBar::TriangularEast:
- case QTabBar::TriangularWest:
- case QTabBar::TriangularSouth:
- p->restore();
- QWindowsStyle::drawPrimitive(pe, option, p, widget);
- return;
- }
- p->restore();
- }
- return;
- case PE_PanelButtonBevel:
- name = QLatin1String("BUTTON");
- partId = BP_PUSHBUTTON;
- if (!(flags & State_Enabled))
- stateId = PBS_DISABLED;
- else if ((flags & State_Sunken) || (flags & State_On))
- stateId = PBS_PRESSED;
- else if (flags & State_MouseOver)
- stateId = PBS_HOT;
- //else if (flags & State_ButtonDefault)
- // stateId = PBS_DEFAULTED;
- else
- stateId = PBS_NORMAL;
- break;
-
- case PE_PanelButtonTool:
- if (widget && widget->inherits("QDockWidgetTitleButton")) {
- if (const QWidget *dw = widget->parentWidget())
- if (dw->isWindow())
- return;
- }
- name = QLatin1String("TOOLBAR");
- partId = TP_BUTTON;
- if (!(flags & State_Enabled))
- stateId = TS_DISABLED;
- else if (flags & State_Sunken)
- stateId = TS_PRESSED;
- else if (flags & State_MouseOver)
- stateId = flags & State_On ? TS_HOTCHECKED : TS_HOT;
- else if (flags & State_On)
- stateId = TS_CHECKED;
- else if (!(flags & State_AutoRaise))
- stateId = TS_HOT;
- else
- stateId = TS_NORMAL;
- break;
-
- case PE_IndicatorButtonDropDown:
- name = QLatin1String("TOOLBAR");
- partId = TP_SPLITBUTTONDROPDOWN;
- if (!(flags & State_Enabled))
- stateId = TS_DISABLED;
- else if (flags & State_Sunken)
- stateId = TS_PRESSED;
- else if (flags & State_MouseOver)
- stateId = flags & State_On ? TS_HOTCHECKED : TS_HOT;
- else if (flags & State_On)
- stateId = TS_CHECKED;
- else if (!(flags & State_AutoRaise))
- stateId = TS_HOT;
- else
- stateId = TS_NORMAL;
- if (option->direction == Qt::RightToLeft)
- hMirrored = true;
- break;
-
- case PE_IndicatorCheckBox:
- name = QLatin1String("BUTTON");
- partId = BP_CHECKBOX;
- if (!(flags & State_Enabled))
- stateId = CBS_UNCHECKEDDISABLED;
- else if (flags & State_Sunken)
- stateId = CBS_UNCHECKEDPRESSED;
- else if (flags & State_MouseOver)
- stateId = CBS_UNCHECKEDHOT;
- else
- stateId = CBS_UNCHECKEDNORMAL;
-
- if (flags & State_On)
- stateId += CBS_CHECKEDNORMAL-1;
- else if (flags & State_NoChange)
- stateId += CBS_MIXEDNORMAL-1;
-
- break;
-
- case PE_IndicatorRadioButton:
- name = QLatin1String("BUTTON");
- partId = BP_RADIOBUTTON;
- if (!(flags & State_Enabled))
- stateId = RBS_UNCHECKEDDISABLED;
- else if (flags & State_Sunken)
- stateId = RBS_UNCHECKEDPRESSED;
- else if (flags & State_MouseOver)
- stateId = RBS_UNCHECKEDHOT;
- else
- stateId = RBS_UNCHECKEDNORMAL;
-
- if (flags & State_On)
- stateId += RBS_CHECKEDNORMAL-1;
- break;
-
- case PE_IndicatorDockWidgetResizeHandle:
- return;
-
-case PE_Frame:
- {
- if (flags & State_Raised)
- return;
- name = QLatin1String("LISTVIEW");
- partId = LVP_LISTGROUP;
- XPThemeData theme(0, 0, name, partId, 0);
-
- if (!(flags & State_Enabled))
- stateId = ETS_DISABLED;
- else
- stateId = ETS_NORMAL;
- int fillType;
- if (pGetThemeEnumValue(theme.handle(), partId, stateId, TMT_BGTYPE, &fillType) == S_OK) {
- if (fillType == BT_BORDERFILL) {
- COLORREF bcRef;
- pGetThemeColor(theme.handle(), partId, stateId, TMT_BORDERCOLOR, &bcRef);
- QColor bordercolor(qRgb(GetRValue(bcRef), GetGValue(bcRef), GetBValue(bcRef)));
- QPen oldPen = p->pen();
- // int borderSize = 1;
- // pGetThemeInt(theme.handle(), partId, stateId, TMT_BORDERCOLOR, &borderSize);
-
- // Inner white border
- p->setPen(QPen(option->palette.base().color(), 1));
- p->drawRect(option->rect.adjusted(1, 1, -2, -2));
- // Outer dark border
- p->setPen(QPen(bordercolor, 1));
- p->drawRect(option->rect.adjusted(0, 0, -1, -1));
- p->setPen(oldPen);
- return;
- } else if (fillType == BT_NONE) {
- return;
- } else {
- break;
- }
- }
- }
- case PE_FrameLineEdit: {
- // we try to check if this lineedit is a delegate on a QAbstractItemView-derived class.
- QWidget *parentWidget = 0;
- if (widget)
- parentWidget = widget->parentWidget();
- if (parentWidget)
- parentWidget = parentWidget->parentWidget();
- if (widget && widget->inherits("QLineEdit")
- && parentWidget && parentWidget->inherits("QAbstractItemView")) {
- QPen oldPen = p->pen();
- // Inner white border
- p->setPen(QPen(option->palette.base().color(), 1));
- p->drawRect(option->rect.adjusted(1, 1, -2, -2));
- // Outer dark border
- p->setPen(QPen(option->palette.shadow().color(), 1));
- p->drawRect(option->rect.adjusted(0, 0, -1, -1));
- p->setPen(oldPen);
- return;
- } else if (qstyleoption_cast<const QStyleOptionFrame *>(option)) {
- name = QLatin1String("EDIT");
- partId = EP_EDITTEXT;
- noContent = true;
- if (!(flags & State_Enabled))
- stateId = ETS_DISABLED;
- else
- stateId = ETS_NORMAL;
- }
- break;
- }
-
- case PE_PanelLineEdit:
- if (const QStyleOptionFrame *panel = qstyleoption_cast<const QStyleOptionFrame *>(option)) {
- name = QLatin1String("EDIT");
- partId = EP_EDITTEXT;
- noBorder = true;
- QBrush bg;
- bool usePalette = false;
- bool isEnabled = flags & State_Enabled;
- uint resolve_mask = panel->palette.resolve();
-
-#ifndef QT_NO_SPINBOX
- //Since spin box includes a line edit we need to resolve the palette on the spin box instead
- if (widget) {
- if (QAbstractSpinBox *spinbox = qobject_cast<QAbstractSpinBox*>(widget->parentWidget()))
- resolve_mask = spinbox->palette().resolve();
- }
-#endif // QT_NO_SPINBOX
- if (resolve_mask & (1 << QPalette::Base)) {
- // Base color is set for this widget, so use it
- bg = panel->palette.brush(QPalette::Base);
- usePalette = true;
- }
-
- stateId = isEnabled ? ETS_NORMAL : ETS_DISABLED;
-
- if (usePalette) {
- p->fillRect(panel->rect, bg);
- } else {
- XPThemeData theme(0, p, name, partId, stateId, rect);
- if (!theme.isValid()) {
- QWindowsStyle::drawPrimitive(pe, option, p, widget);
- return;
- }
- int bgType;
- pGetThemeEnumValue( theme.handle(),
- partId,
- stateId,
- TMT_BGTYPE,
- &bgType);
- if( bgType == BT_IMAGEFILE ) {
- theme.mirrorHorizontally = hMirrored;
- theme.mirrorVertically = vMirrored;
- theme.noBorder = noBorder;
- theme.noContent = noContent;
- theme.rotate = rotate;
- d->drawBackground(theme);
- } else {
- QBrush fillColor = option->palette.brush(QPalette::Base);
-
- if (!isEnabled) {
- PROPERTYORIGIN origin = PO_NOTFOUND;
- pGetThemePropertyOrigin(theme.handle(), theme.partId, theme.stateId, TMT_FILLCOLOR, &origin);
- // Use only if the fill property comes from our part
- if ((origin == PO_PART || origin == PO_STATE)) {
- COLORREF bgRef;
- pGetThemeColor(theme.handle(), partId, stateId, TMT_FILLCOLOR, &bgRef);
- fillColor = QBrush(qRgb(GetRValue(bgRef), GetGValue(bgRef), GetBValue(bgRef)));
- }
- }
- p->fillRect(option->rect, fillColor);
- }
- }
-
- if (panel->lineWidth > 0)
- proxy()->drawPrimitive(PE_FrameLineEdit, panel, p, widget);
- return;
- }
- break;
-
- case PE_FrameTabWidget:
- if (const QStyleOptionTabWidgetFrame *tab = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(option))
- {
- name = QLatin1String("TAB");
- partId = TABP_PANE;
-
- if (widget) {
- bool useGradient = true;
- const int maxlength = 256;
- wchar_t themeFileName[maxlength];
- wchar_t themeColor[maxlength];
- // Due to a a scaling issue with the XP Silver theme, tab gradients are not used with it
- if (pGetCurrentThemeName(themeFileName, maxlength, themeColor, maxlength, NULL, 0) == S_OK) {
- wchar_t *offset = 0;
- if ((offset = wcsrchr(themeFileName, QChar(QLatin1Char('\\')).unicode())) != NULL) {
- offset++;
- if (!lstrcmp(offset, L"Luna.msstyles") && !lstrcmp(offset, L"Metallic")) {
- useGradient = false;
- }
- }
- }
- // This should work, but currently there's an error in the ::drawBackgroundDirectly()
- // code, when using the HDC directly..
- if (useGradient) {
- QStyleOptionTabWidgetFrameV2 frameOpt = *tab;
- frameOpt.rect = widget->rect();
- QRect contentsRect = subElementRect(SE_TabWidgetTabContents, &frameOpt, widget);
- QRegion reg = option->rect;
- reg -= contentsRect;
- p->setClipRegion(reg);
- XPThemeData theme(widget, p, name, partId, stateId, rect);
- theme.mirrorHorizontally = hMirrored;
- theme.mirrorVertically = vMirrored;
- d->drawBackground(theme);
- p->setClipRect(contentsRect);
- partId = TABP_BODY;
- }
- }
- switch (tab->shape) {
- case QTabBar::RoundedNorth:
- case QTabBar::TriangularNorth:
- break;
- case QTabBar::RoundedSouth:
- case QTabBar::TriangularSouth:
- vMirrored = true;
- break;
- case QTabBar::RoundedEast:
- case QTabBar::TriangularEast:
- rotate = 90;
- break;
- case QTabBar::RoundedWest:
- case QTabBar::TriangularWest:
- rotate = 90;
- hMirrored = true;
- break;
- default:
- break;
- }
- }
- break;
-
- case PE_FrameMenu:
- p->save();
- p->setPen(option->palette.dark().color());
- p->drawRect(rect.adjusted(0, 0, -1, -1));
- p->restore();
- return;
-
- case PE_PanelMenuBar:
- break;
-
- case PE_FrameDockWidget:
- if (const QStyleOptionFrame *frm = qstyleoption_cast<const QStyleOptionFrame *>(option))
- {
- name = QLatin1String("WINDOW");
- if (flags & State_Active)
- stateId = FS_ACTIVE;
- else
- stateId = FS_INACTIVE;
-
- int fwidth = proxy()->pixelMetric(PM_DockWidgetFrameWidth, frm, widget);
-
- XPThemeData theme(widget, p, name, 0, stateId);
- if (!theme.isValid())
- break;
- theme.rect = QRect(frm->rect.x(), frm->rect.y(), frm->rect.x()+fwidth, frm->rect.height()-fwidth); theme.partId = WP_SMALLFRAMELEFT;
- d->drawBackground(theme);
- theme.rect = QRect(frm->rect.width()-fwidth, frm->rect.y(), fwidth, frm->rect.height()-fwidth);
- theme.partId = WP_SMALLFRAMERIGHT;
- d->drawBackground(theme);
- theme.rect = QRect(frm->rect.x(), frm->rect.bottom()-fwidth+1, frm->rect.width(), fwidth);
- theme.partId = WP_SMALLFRAMEBOTTOM;
- d->drawBackground(theme);
- return;
- }
- break;
-
- case PE_IndicatorHeaderArrow:
- {
-#if 0 // XP theme engine doesn't know about this :(
- name = QLatin1String("HEADER");
- partId = HP_HEADERSORTARROW;
- if (flags & State_Down)
- stateId = HSAS_SORTEDDOWN;
- else
- stateId = HSAS_SORTEDUP;
-#else
- if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
- p->save();
- p->setPen(option->palette.dark().color());
- p->translate(0, option->rect.height()/2 - 4);
- if (header->sortIndicator & QStyleOptionHeader::SortUp) { // invert logic to follow Windows style guide
- p->drawLine(option->rect.x(), option->rect.y(), option->rect.x()+8, option->rect.y());
- p->drawLine(option->rect.x()+1, option->rect.y()+1, option->rect.x()+7, option->rect.y()+1);
- p->drawLine(option->rect.x()+2, option->rect.y()+2, option->rect.x()+6, option->rect.y()+2);
- p->drawLine(option->rect.x()+3, option->rect.y()+3, option->rect.x()+5, option->rect.y()+3);
- p->drawPoint(option->rect.x()+4, option->rect.y()+4);
- } else if(header->sortIndicator & QStyleOptionHeader::SortDown) {
- p->drawLine(option->rect.x(), option->rect.y()+4, option->rect.x()+8, option->rect.y()+4);
- p->drawLine(option->rect.x()+1, option->rect.y()+3, option->rect.x()+7, option->rect.y()+3);
- p->drawLine(option->rect.x()+2, option->rect.y()+2, option->rect.x()+6, option->rect.y()+2);
- p->drawLine(option->rect.x()+3, option->rect.y()+1, option->rect.x()+5, option->rect.y()+1);
- p->drawPoint(option->rect.x()+4, option->rect.y());
- }
- p->restore();
- return;
- }
-#endif
- }
- break;
-
- case PE_FrameStatusBarItem:
- name = QLatin1String("STATUS");
- partId = SP_PANE;
- break;
-
- case PE_FrameGroupBox:
- name = QLatin1String("BUTTON");
- partId = BP_GROUPBOX;
- if (!(flags & State_Enabled))
- stateId = GBS_DISABLED;
- else
- stateId = GBS_NORMAL;
- if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(option)) {
- const QStyleOptionFrameV2 *frame2 = qstyleoption_cast<const QStyleOptionFrameV2 *>(option);
- if (frame2->features & QStyleOptionFrameV2::Flat) {
- // Windows XP does not have a theme part for a flat GroupBox, paint it with the windows style
- QRect fr = frame->rect;
- QPoint p1(fr.x(), fr.y() + 1);
- QPoint p2(fr.x() + fr.width(), p1.y() + 1);
- rect = QRect(p1, p2);
- name = QLatin1String("");
- }
- }
- break;
-
- case PE_IndicatorProgressChunk:
- {
- Qt::Orientation orient = Qt::Horizontal;
- bool inverted = false;
- if (const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option)) {
- orient = pb2->orientation;
- if (pb2->invertedAppearance)
- inverted = true;
- }
- if (orient == Qt::Horizontal) {
- partId = PP_CHUNK;
- rect = QRect(option->rect.x(), option->rect.y(), option->rect.width(), option->rect.height() );
- if (inverted && option->direction == Qt::LeftToRight)
- hMirrored = true;
- } else {
- partId = PP_CHUNKVERT;
- rect = QRect(option->rect.x(), option->rect.y(), option->rect.width(), option->rect.height());
- }
- name = QLatin1String("PROGRESS");
- stateId = 1;
- }
- break;
-
- case PE_Q3DockWindowSeparator:
- name = QLatin1String("TOOLBAR");
- if (flags & State_Horizontal)
- partId = TP_SEPARATOR;
- else
- partId = TP_SEPARATORVERT;
- break;
-
- case PE_FrameWindow:
- if (const QStyleOptionFrame *frm = qstyleoption_cast<const QStyleOptionFrame *>(option))
- {
- name = QLatin1String("WINDOW");
- if (flags & State_Active)
- stateId = FS_ACTIVE;
- else
- stateId = FS_INACTIVE;
-
- int fwidth = frm->lineWidth + frm->midLineWidth;
-
- XPThemeData theme(0, p, name, 0, stateId);
- if (!theme.isValid())
- break;
-
- theme.rect = QRect(option->rect.x(), option->rect.y()+fwidth, option->rect.x()+fwidth, option->rect.height()-fwidth);
- theme.partId = WP_FRAMELEFT;
- d->drawBackground(theme);
- theme.rect = QRect(option->rect.width()-fwidth, option->rect.y()+fwidth, fwidth, option->rect.height()-fwidth);
- theme.partId = WP_FRAMERIGHT;
- d->drawBackground(theme);
- theme.rect = QRect(option->rect.x(), option->rect.height()-fwidth, option->rect.width(), fwidth);
- theme.partId = WP_FRAMEBOTTOM;
- d->drawBackground(theme);
- theme.rect = QRect(option->rect.x(), option->rect.y(), option->rect.width(), option->rect.y()+fwidth);
- theme.partId = WP_CAPTION;
- d->drawBackground(theme);
- return;
- }
- break;
-
- case PE_IndicatorBranch:
- {
- static const int decoration_size = 9;
- int mid_h = option->rect.x() + option->rect.width() / 2;
- int mid_v = option->rect.y() + option->rect.height() / 2;
- int bef_h = mid_h;
- int bef_v = mid_v;
- int aft_h = mid_h;
- int aft_v = mid_v;
- QBrush brush(option->palette.dark().color(), Qt::Dense4Pattern);
- if (option->state & State_Item) {
- if (option->direction == Qt::RightToLeft)
- p->fillRect(option->rect.left(), mid_v, bef_h - option->rect.left(), 1, brush);
- else
- p->fillRect(aft_h, mid_v, option->rect.right() - aft_h + 1, 1, brush);
- }
- if (option->state & State_Sibling)
- p->fillRect(mid_h, aft_v, 1, option->rect.bottom() - aft_v + 1, brush);
- if (option->state & (State_Open | State_Children | State_Item | State_Sibling))
- p->fillRect(mid_h, option->rect.y(), 1, bef_v - option->rect.y(), brush);
- if (option->state & State_Children) {
- int delta = decoration_size / 2;
- bef_h -= delta;
- bef_v -= delta;
- aft_h += delta;
- aft_v += delta;
- XPThemeData theme(0, p, QLatin1String("TREEVIEW"));
- theme.rect = QRect(bef_h, bef_v, decoration_size, decoration_size);
- theme.partId = TVP_GLYPH;
- theme.stateId = flags & QStyle::State_Open ? GLPS_OPENED : GLPS_CLOSED;
- d->drawBackground(theme);
- }
- }
- return;
-
- case PE_IndicatorToolBarSeparator:
- if (option->rect.height() < 3) {
- // XP style requires a few pixels for the separator
- // to be visible.
- QWindowsStyle::drawPrimitive(pe, option, p, widget);
- return;
- }
- name = QLatin1String("TOOLBAR");
- partId = TP_SEPARATOR;
-
- if (option->state & State_Horizontal)
- partId = TP_SEPARATOR;
- else
- partId = TP_SEPARATORVERT;
-
- break;
-
- case PE_IndicatorToolBarHandle:
-
- name = QLatin1String("REBAR");
- partId = RP_GRIPPER;
- if (option->state & State_Horizontal) {
- partId = RP_GRIPPER;
- rect.adjust(0, 0, -2, 0);
- }
- else {
- partId = RP_GRIPPERVERT;
- rect.adjust(0, 0, 0, -2);
- }
- break;
-
- case PE_IndicatorItemViewItemCheck: {
- QStyleOptionButton button;
- button.QStyleOption::operator=(*option);
- button.state &= ~State_MouseOver;
- proxy()->drawPrimitive(PE_IndicatorCheckBox, &button, p, widget);
- return;
- }
-
- default:
- break;
- }
-
- XPThemeData theme(0, p, name, partId, stateId, rect);
- if (!theme.isValid()) {
- QWindowsStyle::drawPrimitive(pe, option, p, widget);
- return;
- }
- theme.mirrorHorizontally = hMirrored;
- theme.mirrorVertically = vMirrored;
- theme.noBorder = noBorder;
- theme.noContent = noContent;
- theme.rotate = rotate;
- d->drawBackground(theme);
-}
-
-/*!
- \reimp
-*/
-void QWindowsXPStyle::drawControl(ControlElement element, const QStyleOption *option, QPainter *p,
- const QWidget *widget) const
-{
- QWindowsXPStylePrivate *d = const_cast<QWindowsXPStylePrivate*>(d_func());
- if (!QWindowsXPStylePrivate::useXP()) {
- QWindowsStyle::drawControl(element, option, p, widget);
- return;
- }
-
- QRect rect(option->rect);
- State flags = option->state;
-
- int rotate = 0;
- bool hMirrored = false;
- bool vMirrored = false;
-
- QString name;
- int partId = 0;
- int stateId = 0;
- switch (element) {
- case CE_SizeGrip:
- {
- name = QLatin1String("STATUS");
- partId = SP_GRIPPER;
- SIZE sz;
- XPThemeData theme(0, p, name, partId, 0);
- pGetThemePartSize(theme.handle(), 0, partId, 0, 0, TS_TRUE, &sz);
- --sz.cy;
- if (const QStyleOptionSizeGrip *sg = qstyleoption_cast<const QStyleOptionSizeGrip *>(option)) {
- switch (sg->corner) {
- case Qt::BottomRightCorner:
- rect = QRect(rect.right() - sz.cx, rect.bottom() - sz.cy, sz.cx, sz.cy);
- break;
- case Qt::BottomLeftCorner:
- rect = QRect(rect.left() + 1, rect.bottom() - sz.cy, sz.cx, sz.cy);
- hMirrored = true;
- break;
- case Qt::TopRightCorner:
- rect = QRect(rect.right() - sz.cx, rect.top() + 1, sz.cx, sz.cy);
- vMirrored = true;
- break;
- case Qt::TopLeftCorner:
- rect = QRect(rect.left() + 1, rect.top() + 1, sz.cx, sz.cy);
- hMirrored = vMirrored = true;
- }
- }
- }
- break;
-
- case CE_HeaderSection:
- name = QLatin1String("HEADER");
- partId = HP_HEADERITEM;
- if (flags & State_Sunken)
- stateId = HIS_PRESSED;
- else if (flags & State_MouseOver)
- stateId = HIS_HOT;
- else
- stateId = HIS_NORMAL;
- break;
-
- case CE_Splitter:
- p->eraseRect(option->rect);
- return;
-
- case CE_PushButtonBevel:
- if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option))
- {
- name = QLatin1String("BUTTON");
- partId = BP_PUSHBUTTON;
- bool justFlat = ((btn->features & QStyleOptionButton::Flat) && !(flags & (State_On|State_Sunken)))
- || ((btn->features & QStyleOptionButton::CommandLinkButton)
- && !(flags & State_MouseOver)
- && !(btn->features & QStyleOptionButton::DefaultButton));
- if (!(flags & State_Enabled) && !(btn->features & QStyleOptionButton::Flat))
- stateId = PBS_DISABLED;
- else if (justFlat)
- ;
- else if (flags & (State_Sunken | State_On))
- stateId = PBS_PRESSED;
- else if (flags & State_MouseOver)
- stateId = PBS_HOT;
- else if (btn->features & QStyleOptionButton::DefaultButton)
- stateId = PBS_DEFAULTED;
- else
- stateId = PBS_NORMAL;
-
- if (!justFlat) {
- XPThemeData theme(widget, p, name, partId, stateId, rect);
- d->drawBackground(theme);
- }
-
- if (btn->features & QStyleOptionButton::HasMenu) {
- int mbiw = 0, mbih = 0;
- XPThemeData theme(widget, 0, QLatin1String("TOOLBAR"), TP_SPLITBUTTONDROPDOWN);
- if (theme.isValid()) {
- SIZE size;
- pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
- mbiw = size.cx;
- mbih = size.cy;
- }
-
- QRect ir = btn->rect;
- QStyleOptionButton newBtn = *btn;
- newBtn.rect = QRect(ir.right() - mbiw - 1, 1 + (ir.height()/2) - (mbih/2), mbiw, mbih);
- proxy()->drawPrimitive(PE_IndicatorArrowDown, &newBtn, p, widget);
- }
- return;
- }
- break;
- case CE_TabBarTab:
- if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(option))
- {
- stateId = tab->state & State_Enabled ? TIS_NORMAL : TIS_DISABLED;
- }
- break;
-
- case CE_TabBarTabShape:
- if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(option))
- {
- name = QLatin1String("TAB");
- bool isDisabled = !(tab->state & State_Enabled);
- bool hasFocus = tab->state & State_HasFocus;
- bool isHot = tab->state & State_MouseOver;
- bool selected = tab->state & State_Selected;
- bool lastTab = tab->position == QStyleOptionTab::End;
- bool firstTab = tab->position == QStyleOptionTab::Beginning;
- bool onlyOne = tab->position == QStyleOptionTab::OnlyOneTab;
- bool leftAligned = proxy()->styleHint(SH_TabBar_Alignment, tab, widget) == Qt::AlignLeft;
- bool centerAligned = proxy()->styleHint(SH_TabBar_Alignment, tab, widget) == Qt::AlignCenter;
- int borderThickness = proxy()->pixelMetric(PM_DefaultFrameWidth, option, widget);
- int tabOverlap = proxy()->pixelMetric(PM_TabBarTabOverlap, option, widget);
-
- if (isDisabled)
- stateId = TIS_DISABLED;
- else if (selected)
- stateId = TIS_SELECTED;
- else if (hasFocus)
- stateId = TIS_FOCUSED;
- else if (isHot)
- stateId = TIS_HOT;
- else
- stateId = TIS_NORMAL;
-
- // Selecting proper part depending on position
- if (firstTab || onlyOne) {
- if (leftAligned) {
- partId = TABP_TABITEMLEFTEDGE;
- } else if (centerAligned) {
- partId = TABP_TABITEM;
- } else { // rightAligned
- partId = TABP_TABITEMRIGHTEDGE;
- }
- } else {
- partId = TABP_TABITEM;
- }
-
- if (tab->direction == Qt::RightToLeft
- && (tab->shape == QTabBar::RoundedNorth
- || tab->shape == QTabBar::RoundedSouth)) {
- bool temp = firstTab;
- firstTab = lastTab;
- lastTab = temp;
- }
- bool begin = firstTab || onlyOne;
- bool end = lastTab || onlyOne;
- switch (tab->shape) {
- case QTabBar::RoundedNorth:
- if (selected)
- rect.adjust(begin ? 0 : -tabOverlap, 0, end ? 0 : tabOverlap, borderThickness);
- else
- rect.adjust(begin? tabOverlap : 0, tabOverlap, end ? -tabOverlap : 0, 0);
- break;
- case QTabBar::RoundedSouth:
- //vMirrored = true;
- rotate = 180; // Not 100% correct, but works
- if (selected)
- rect.adjust(begin ? 0 : -tabOverlap , -borderThickness, end ? 0 : tabOverlap, 0);
- else
- rect.adjust(begin ? tabOverlap : 0, 0, end ? -tabOverlap : 0 , -tabOverlap);
- break;
- case QTabBar::RoundedEast:
- rotate = 90;
- if (selected) {
- rect.adjust(-borderThickness, begin ? 0 : -tabOverlap, 0, end ? 0 : tabOverlap);
- }else{
- rect.adjust(0, begin ? tabOverlap : 0, -tabOverlap, end ? -tabOverlap : 0);
- }
- break;
- case QTabBar::RoundedWest:
- hMirrored = true;
- rotate = 90;
- if (selected) {
- rect.adjust(0, begin ? 0 : -tabOverlap, borderThickness, end ? 0 : tabOverlap);
- }else{
- rect.adjust(tabOverlap, begin ? tabOverlap : 0, 0, end ? -tabOverlap : 0);
- }
- break;
- default:
- name = QLatin1String(""); // Do our own painting for triangular
- break;
- }
-
- if (!selected) {
- switch (tab->shape) {
- case QTabBar::RoundedNorth:
- rect.adjust(0,0, 0,-1);
- break;
- case QTabBar::RoundedSouth:
- rect.adjust(0,1, 0,0);
- break;
- case QTabBar::RoundedEast:
- rect.adjust( 1,0, 0,0);
- break;
- case QTabBar::RoundedWest:
- rect.adjust(0,0, -1,0);
- break;
- default:
- break;
- }
- }
- }
- break;
-
- case CE_ProgressBarGroove:
- {
- Qt::Orientation orient = Qt::Horizontal;
- if (const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option))
- orient = pb2->orientation;
- partId = (orient == Qt::Horizontal) ? PP_BAR : PP_BARVERT;
- name = QLatin1String("PROGRESS");
- stateId = 1;
- }
- break;
-
- case CE_MenuEmptyArea:
- case CE_MenuItem:
- if (const QStyleOptionMenuItem *menuitem = qstyleoption_cast<const QStyleOptionMenuItem *>(option))
- {
- int tab = menuitem->tabWidth;
- bool dis = !(menuitem->state & State_Enabled);
- bool act = menuitem->state & State_Selected;
- bool checkable = menuitem->menuHasCheckableItems;
- bool checked = checkable ? menuitem->checked : false;
-
- // windows always has a check column, regardless whether we have an icon or not
- int checkcol = qMax(menuitem->maxIconWidth, 12);
-
- int x, y, w, h;
- rect.getRect(&x, &y, &w, &h);
-
- QBrush fill = menuitem->palette.brush(act ? QPalette::Highlight : QPalette::Button);
- p->fillRect(rect, fill);
-
- if (element == CE_MenuEmptyArea)
- break;
-
- // draw separator -------------------------------------------------
- if (menuitem->menuItemType == QStyleOptionMenuItem::Separator) {
- int yoff = y-1 + h / 2;
- p->setPen(menuitem->palette.dark().color());
- p->drawLine(x, yoff, x+w, yoff);
- ++yoff;
- p->setPen(menuitem->palette.light().color());
- p->drawLine(x, yoff, x+w, yoff);
- return;
- }
-
- int xpos = x;
-
- // draw icon ------------------------------------------------------
- if (!menuitem->icon.isNull()) {
- QIcon::Mode mode = dis ? QIcon::Disabled : QIcon::Normal;
- if (act && !dis)
- mode = QIcon::Active;
- QPixmap pixmap = checked ?
- menuitem->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, option, widget), mode, QIcon::On) :
- menuitem->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, option, widget), mode);
- int pixw = pixmap.width();
- int pixh = pixmap.height();
- QRect iconRect(0, 0, pixw, pixh);
- iconRect.moveCenter(QRect(xpos, y, checkcol, h).center());
- QRect vIconRect = visualRect(option->direction, option->rect, iconRect);
- p->setPen(menuitem->palette.text().color());
- p->setBrush(Qt::NoBrush);
- if (checked)
- p->drawRect(vIconRect.adjusted(-1, -1, 0, 0));
- p->drawPixmap(vIconRect.topLeft(), pixmap);
-
- // draw checkmark -------------------------------------------------
- } else if (checked) {
- QStyleOptionMenuItem newMi = *menuitem;
- newMi.state = State_None;
- if (!dis)
- newMi.state |= State_Enabled;
- if (act)
- newMi.state |= State_On;
-
- QRect checkMarkRect = QRect(menuitem->rect.x() + windowsItemFrame,
- menuitem->rect.y() + windowsItemFrame,
- checkcol - 2 * windowsItemFrame,
- menuitem->rect.height() - 2*windowsItemFrame);
- newMi.rect = visualRect(option->direction, option->rect, checkMarkRect);
- proxy()->drawPrimitive(PE_IndicatorMenuCheckMark, &newMi, p, widget);
- }
-
- QColor textColor = dis ? menuitem->palette.text().color() :
- act ? menuitem->palette.highlightedText().color() : menuitem->palette.buttonText().color();
- p->setPen(textColor);
-
- // draw text ------------------------------------------------------
- int xm = windowsItemFrame + checkcol + windowsItemHMargin;
- xpos = menuitem->rect.x() + xm;
- QRect textRect(xpos, y + windowsItemVMargin, w - xm - windowsRightBorder - tab + 1, h - 2 * windowsItemVMargin);
- QRect vTextRect = visualRect(option->direction, option->rect, textRect);
- QString s = menuitem->text;
- if (!s.isEmpty()) {
- p->save();
- int t = s.indexOf(QLatin1Char('\t'));
- int text_flags = Qt::AlignVCenter|Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine | Qt::AlignLeft;
- if (!proxy()->styleHint(SH_UnderlineShortcut, menuitem, widget))
- text_flags |= Qt::TextHideMnemonic;
- // draw tab text ----------------
- if (t >= 0) {
- QRect vShortcutRect = visualRect(option->direction, option->rect, QRect(textRect.topRight(), menuitem->rect.bottomRight()));
- if (dis && !act && proxy()->styleHint(SH_EtchDisabledText, option, widget)) {
- p->setPen(menuitem->palette.light().color());
- p->drawText(vShortcutRect.adjusted(1,1,1,1), text_flags, s.mid(t + 1));
- p->setPen(textColor);
- }
- p->drawText(vShortcutRect, text_flags, s.mid(t + 1));
- s = s.left(t);
- }
- QFont font = menuitem->font;
- if (menuitem->menuItemType == QStyleOptionMenuItem::DefaultItem)
- font.setBold(true);
- p->setFont(font);
- if (dis && !act && proxy()->styleHint(SH_EtchDisabledText, option, widget)) {
- p->setPen(menuitem->palette.light().color());
- p->drawText(vTextRect.adjusted(1,1,1,1), text_flags, s.left(t));
- p->setPen(textColor);
- }
- p->drawText(vTextRect, text_flags, s);
- p->restore();
- }
-
- // draw sub menu arrow --------------------------------------------
- if (menuitem->menuItemType == QStyleOptionMenuItem::SubMenu) {
- int dim = (h - 2) / 2;
- PrimitiveElement arrow;
- arrow = (option->direction == Qt::RightToLeft) ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight;
- xpos = x + w - windowsArrowHMargin - windowsItemFrame - dim;
- QRect vSubMenuRect = visualRect(option->direction, option->rect, QRect(xpos, y + h / 2 - dim / 2, dim, dim));
- QStyleOptionMenuItem newMI = *menuitem;
- newMI.rect = vSubMenuRect;
- newMI.state = dis ? State_None : State_Enabled;
- if (act)
- newMI.palette.setColor(QPalette::ButtonText, newMI.palette.highlightedText().color());
- proxy()->drawPrimitive(arrow, &newMI, p, widget);
- }
- }
- return;
-
- case CE_MenuBarItem:
- if (const QStyleOptionMenuItem *mbi = qstyleoption_cast<const QStyleOptionMenuItem *>(option))
- {
- if (mbi->menuItemType == QStyleOptionMenuItem::DefaultItem)
- break;
-
- bool act = mbi->state & State_Selected;
- bool dis = !(mbi->state & State_Enabled);
-
- QBrush fill = mbi->palette.brush(act ? QPalette::Highlight : QPalette::Button);
- QPalette::ColorRole textRole = dis ? QPalette::Text:
- act ? QPalette::HighlightedText : QPalette::ButtonText;
- QPixmap pix = mbi->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, option, widget), QIcon::Normal);
-
- uint alignment = Qt::AlignCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
- if (!proxy()->styleHint(SH_UnderlineShortcut, mbi, widget))
- alignment |= Qt::TextHideMnemonic;
-
- p->fillRect(rect, fill);
- if (!pix.isNull())
- drawItemPixmap(p, mbi->rect, alignment, pix);
- else
- drawItemText(p, mbi->rect, alignment, mbi->palette, mbi->state & State_Enabled, mbi->text, textRole);
- }
- return;
-#ifndef QT_NO_DOCKWIDGET
- case CE_DockWidgetTitle:
- if (const QStyleOptionDockWidget *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(option))
- {
- int buttonMargin = 4;
- int mw = proxy()->pixelMetric(QStyle::PM_DockWidgetTitleMargin, dwOpt, widget);
- int fw = proxy()->pixelMetric(PM_DockWidgetFrameWidth, dwOpt, widget);
- bool isFloating = widget && widget->isWindow();
- bool isActive = dwOpt->state & State_Active;
-
- const QStyleOptionDockWidgetV2 *v2
- = qstyleoption_cast<const QStyleOptionDockWidgetV2*>(dwOpt);
- bool verticalTitleBar = v2 == 0 ? false : v2->verticalTitleBar;
-
- if (verticalTitleBar) {
- QSize s = rect.size();
- s.transpose();
- rect.setSize(s);
-
- p->translate(rect.left() - 1, rect.top() + rect.width());
- p->rotate(-90);
- p->translate(-rect.left() + 1, -rect.top());
- }
- QRect r = rect.adjusted(0, 2, -1, -3);
- QRect titleRect = r;
-
- if (dwOpt->closable) {
- QSize sz = proxy()->standardIcon(QStyle::SP_TitleBarCloseButton, dwOpt, widget).actualSize(QSize(10, 10));
- titleRect.adjust(0, 0, -sz.width() - mw - buttonMargin, 0);
- }
-
- if (dwOpt->floatable) {
- QSize sz = proxy()->standardIcon(QStyle::SP_TitleBarMaxButton, dwOpt, widget).actualSize(QSize(10, 10));
- titleRect.adjust(0, 0, -sz.width() - mw - buttonMargin, 0);
- }
-
- if (isFloating) {
- titleRect.adjust(0, -fw, 0, 0);
- if (widget != 0 && widget->windowIcon().cacheKey() != QApplication::windowIcon().cacheKey())
- titleRect.adjust(titleRect.height() + mw, 0, 0, 0);
- } else {
- titleRect.adjust(mw, 0, 0, 0);
- if (!dwOpt->floatable && !dwOpt->closable)
- titleRect.adjust(0, 0, -mw, 0);
- }
-
- if (!verticalTitleBar)
- titleRect = visualRect(dwOpt->direction, r, titleRect);
-
- if (!isFloating) {
- QPen oldPen = p->pen();
- QString titleText = p->fontMetrics().elidedText(dwOpt->title, Qt::ElideRight, titleRect.width());
- p->setPen(dwOpt->palette.color(QPalette::Dark));
- p->drawRect(r);
-
- if (!titleText.isEmpty()) {
- drawItemText(p, titleRect,
- Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic, dwOpt->palette,
- dwOpt->state & State_Enabled, titleText,
- QPalette::WindowText);
- }
-
- p->setPen(oldPen);
- } else {
- name = QLatin1String("WINDOW");
- if (isActive)
- stateId = CS_ACTIVE;
- else
- stateId = CS_INACTIVE;
-
- int titleHeight = rect.height() - 2;
- rect = rect.adjusted(-fw, -fw, fw, 0);
-
- XPThemeData theme(widget, p, name, 0, stateId);
- if (!theme.isValid())
- break;
-
- // Draw small type title bar
- theme.rect = rect;
- theme.partId = WP_SMALLCAPTION;
- d->drawBackground(theme);
-
- // Figure out maximal button space on title bar
-
- QIcon ico = widget->windowIcon();
- bool hasIcon = (ico.cacheKey() != QApplication::windowIcon().cacheKey());
- if (hasIcon) {
- QPixmap pxIco = ico.pixmap(titleHeight);
- if (!verticalTitleBar && dwOpt->direction == Qt::RightToLeft)
- p->drawPixmap(rect.width() - titleHeight - pxIco.width(), rect.bottom() - titleHeight - 2, pxIco);
- else
- p->drawPixmap(fw, rect.bottom() - titleHeight - 2, pxIco);
- }
- if (!dwOpt->title.isEmpty()) {
- QPen oldPen = p->pen();
- QFont oldFont = p->font();
- QFont titleFont = oldFont;
- titleFont.setBold(true);
- p->setFont(titleFont);
- QString titleText
- = p->fontMetrics().elidedText(dwOpt->title, Qt::ElideRight, titleRect.width());
-
- int result = TST_NONE;
- pGetThemeEnumValue(theme.handle(), WP_SMALLCAPTION, isActive ? CS_ACTIVE : CS_INACTIVE, TMT_TEXTSHADOWTYPE, &result);
- if (result != TST_NONE) {
- COLORREF textShadowRef;
- pGetThemeColor(theme.handle(), WP_SMALLCAPTION, isActive ? CS_ACTIVE : CS_INACTIVE, TMT_TEXTSHADOWCOLOR, &textShadowRef);
- QColor textShadow = qRgb(GetRValue(textShadowRef), GetGValue(textShadowRef), GetBValue(textShadowRef));
- p->setPen(textShadow);
- drawItemText(p, titleRect.adjusted(1, 1, 1, 1),
- Qt::AlignLeft | Qt::AlignBottom, dwOpt->palette,
- dwOpt->state & State_Enabled, titleText);
- }
-
- COLORREF captionText = GetSysColor(isActive ? COLOR_CAPTIONTEXT : COLOR_INACTIVECAPTIONTEXT);
- QColor textColor = qRgb(GetRValue(captionText), GetGValue(captionText), GetBValue(captionText));
- p->setPen(textColor);
- drawItemText(p, titleRect,
- Qt::AlignLeft | Qt::AlignBottom, dwOpt->palette,
- dwOpt->state & State_Enabled, titleText);
- p->setFont(oldFont);
- p->setPen(oldPen);
- }
-
- }
-
- return;
- }
- break;
-#endif // QT_NO_DOCKWIDGET
-#ifndef QT_NO_RUBBERBAND
- case CE_RubberBand:
- if (qstyleoption_cast<const QStyleOptionRubberBand *>(option)) {
- QColor highlight = option->palette.color(QPalette::Active, QPalette::Highlight);
- p->save();
- QRect r = option->rect;
- p->setPen(highlight.darker(120));
- QColor dimHighlight(qMin(highlight.red()/2 + 110, 255),
- qMin(highlight.green()/2 + 110, 255),
- qMin(highlight.blue()/2 + 110, 255),
- (widget && widget->isTopLevel())? 255 : 127);
- p->setBrush(dimHighlight);
- p->drawRect(option->rect.adjusted(0, 0, -1, -1));
- p->restore();
- return;
- }
-#endif // QT_NO_RUBBERBAND
- case CE_HeaderEmptyArea:
- if (option->state & State_Horizontal)
- {
- name = QLatin1String("HEADER");
- stateId = HIS_NORMAL;
- }
- else {
- QWindowsStyle::drawControl(CE_HeaderEmptyArea, option, p, widget);
- return;
- }
- break;
- default:
- break;
- }
-
- XPThemeData theme(widget, p, name, partId, stateId, rect);
- if (!theme.isValid()) {
- QWindowsStyle::drawControl(element, option, p, widget);
- return;
- }
-
- theme.rotate = rotate;
- theme.mirrorHorizontally = hMirrored;
- theme.mirrorVertically = vMirrored;
- d->drawBackground(theme);
-}
-
-
-/*!
- \reimp
-*/
-void QWindowsXPStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex *option,
- QPainter *p, const QWidget *widget) const
-{
- QWindowsXPStylePrivate *d = const_cast<QWindowsXPStylePrivate*>(d_func());
-
- if (!QWindowsXPStylePrivate::useXP()) {
- QWindowsStyle::drawComplexControl(cc, option, p, widget);
- return;
- }
-
- State flags = option->state;
- SubControls sub = option->subControls;
- QRect r = option->rect;
-
- int partId = 0;
- int stateId = 0;
- if (widget && widget->testAttribute(Qt::WA_UnderMouse) && widget->isActiveWindow())
- flags |= State_MouseOver;
-
- switch (cc) {
-#ifndef QT_NO_SPINBOX
- case CC_SpinBox:
- if (const QStyleOptionSpinBox *sb = qstyleoption_cast<const QStyleOptionSpinBox *>(option))
- {
- XPThemeData theme(widget, p, QLatin1String("SPIN"));
-
- if (sb->frame && (sub & SC_SpinBoxFrame)) {
- partId = EP_EDITTEXT;
- if (!(flags & State_Enabled))
- stateId = ETS_DISABLED;
- else if (flags & State_HasFocus)
- stateId = ETS_FOCUSED;
- else
- stateId = ETS_NORMAL;
-
- XPThemeData ftheme(widget, p, QLatin1String("EDIT"), partId, stateId, r);
- ftheme.noContent = true;
- d->drawBackground(ftheme);
- }
- if (sub & SC_SpinBoxUp) {
- theme.rect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxUp, widget);
- partId = SPNP_UP;
- if (!(sb->stepEnabled & QAbstractSpinBox::StepUpEnabled) || !(flags & State_Enabled))
- stateId = UPS_DISABLED;
- else if (sb->activeSubControls == SC_SpinBoxUp && (sb->state & State_Sunken))
- stateId = UPS_PRESSED;
- else if (sb->activeSubControls == SC_SpinBoxUp && (sb->state & State_MouseOver))
- stateId = UPS_HOT;
- else
- stateId = UPS_NORMAL;
- theme.partId = partId;
- theme.stateId = stateId;
- d->drawBackground(theme);
- }
- if (sub & SC_SpinBoxDown) {
- theme.rect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxDown, widget);
- partId = SPNP_DOWN;
- if (!(sb->stepEnabled & QAbstractSpinBox::StepDownEnabled) || !(flags & State_Enabled))
- stateId = DNS_DISABLED;
- else if (sb->activeSubControls == SC_SpinBoxDown && (sb->state & State_Sunken))
- stateId = DNS_PRESSED;
- else if (sb->activeSubControls == SC_SpinBoxDown && (sb->state & State_MouseOver))
- stateId = DNS_HOT;
- else
- stateId = DNS_NORMAL;
- theme.partId = partId;
- theme.stateId = stateId;
- d->drawBackground(theme);
- }
- }
- break;
-#endif // QT_NO_SPINBOX
-#ifndef QT_NO_COMBOBOX
- case CC_ComboBox:
- if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(option))
- {
- if (sub & SC_ComboBoxEditField) {
- if (cmb->frame) {
- partId = EP_EDITTEXT;
- if (!(flags & State_Enabled))
- stateId = ETS_DISABLED;
- else if (flags & State_HasFocus)
- stateId = ETS_FOCUSED;
- else
- stateId = ETS_NORMAL;
- XPThemeData theme(widget, p, QLatin1String("EDIT"), partId, stateId, r);
- d->drawBackground(theme);
- } else {
- QBrush editBrush = cmb->palette.brush(QPalette::Base);
- p->fillRect(option->rect, editBrush);
- }
- if (!cmb->editable) {
- QRect re = proxy()->subControlRect(CC_ComboBox, option, SC_ComboBoxEditField, widget);
- if (option->state & State_HasFocus) {
- p->fillRect(re, option->palette.highlight());
- p->setPen(option->palette.highlightedText().color());
- p->setBackground(option->palette.highlight());
- } else {
- p->fillRect(re, option->palette.base());
- p->setPen(option->palette.text().color());
- p->setBackground(option->palette.base());
- }
- }
- }
-
- if (sub & SC_ComboBoxArrow) {
- XPThemeData theme(widget, p, QLatin1String("COMBOBOX"));
- theme.rect = proxy()->subControlRect(CC_ComboBox, option, SC_ComboBoxArrow, widget);
- partId = CP_DROPDOWNBUTTON;
- if (!(flags & State_Enabled))
- stateId = CBXS_DISABLED;
- else if (cmb->activeSubControls == SC_ComboBoxArrow && (cmb->state & State_Sunken))
- stateId = CBXS_PRESSED;
- else if (cmb->activeSubControls == SC_ComboBoxArrow && (cmb->state & State_MouseOver))
- stateId = CBXS_HOT;
- else
- stateId = CBXS_NORMAL;
- theme.partId = partId;
- theme.stateId = stateId;
- d->drawBackground(theme);
- }
- }
- break;
-#endif // QT_NO_COMBOBOX
- case CC_ScrollBar:
- if (const QStyleOptionSlider *scrollbar = qstyleoption_cast<const QStyleOptionSlider *>(option))
- {
- XPThemeData theme(widget, p, QLatin1String("SCROLLBAR"));
- bool maxedOut = (scrollbar->maximum == scrollbar->minimum);
- if (maxedOut)
- flags &= ~State_Enabled;
-
- bool isHorz = flags & State_Horizontal;
- bool isRTL = option->direction == Qt::RightToLeft;
- if (sub & SC_ScrollBarAddLine) {
- theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarAddLine, widget);
- partId = SBP_ARROWBTN;
- if (!(flags & State_Enabled))
- stateId = (isHorz ? (isRTL ? ABS_LEFTDISABLED : ABS_RIGHTDISABLED) : ABS_DOWNDISABLED);
- else if (scrollbar->activeSubControls & SC_ScrollBarAddLine && (scrollbar->state & State_Sunken))
- stateId = (isHorz ? (isRTL ? ABS_LEFTPRESSED : ABS_RIGHTPRESSED) : ABS_DOWNPRESSED);
- else if (scrollbar->activeSubControls & SC_ScrollBarAddLine && (scrollbar->state & State_MouseOver))
- stateId = (isHorz ? (isRTL ? ABS_LEFTHOT : ABS_RIGHTHOT) : ABS_DOWNHOT);
- else
- stateId = (isHorz ? (isRTL ? ABS_LEFTNORMAL : ABS_RIGHTNORMAL) : ABS_DOWNNORMAL);
- theme.partId = partId;
- theme.stateId = stateId;
- d->drawBackground(theme);
- }
- if (sub & SC_ScrollBarSubLine) {
- theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSubLine, widget);
- partId = SBP_ARROWBTN;
- if (!(flags & State_Enabled))
- stateId = (isHorz ? (isRTL ? ABS_RIGHTDISABLED : ABS_LEFTDISABLED) : ABS_UPDISABLED);
- else if (scrollbar->activeSubControls & SC_ScrollBarSubLine && (scrollbar->state & State_Sunken))
- stateId = (isHorz ? (isRTL ? ABS_RIGHTPRESSED : ABS_LEFTPRESSED) : ABS_UPPRESSED);
- else if (scrollbar->activeSubControls & SC_ScrollBarSubLine && (scrollbar->state & State_MouseOver))
- stateId = (isHorz ? (isRTL ? ABS_RIGHTHOT : ABS_LEFTHOT) : ABS_UPHOT);
- else
- stateId = (isHorz ? (isRTL ? ABS_RIGHTNORMAL : ABS_LEFTNORMAL) : ABS_UPNORMAL);
- theme.partId = partId;
- theme.stateId = stateId;
- d->drawBackground(theme);
- }
- if (maxedOut) {
- theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider, widget);
- theme.rect = theme.rect.united(proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSubPage, widget));
- theme.rect = theme.rect.united(proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarAddPage, widget));
- partId = scrollbar->orientation == Qt::Horizontal ? SBP_LOWERTRACKHORZ : SBP_LOWERTRACKVERT;
- stateId = SCRBS_DISABLED;
- theme.partId = partId;
- theme.stateId = stateId;
- d->drawBackground(theme);
- } else {
- if (sub & SC_ScrollBarSubPage) {
- theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSubPage, widget);
- partId = flags & State_Horizontal ? SBP_UPPERTRACKHORZ : SBP_UPPERTRACKVERT;
- if (!(flags & State_Enabled))
- stateId = SCRBS_DISABLED;
- else if (scrollbar->activeSubControls & SC_ScrollBarSubPage && (scrollbar->state & State_Sunken))
- stateId = SCRBS_PRESSED;
- else if (scrollbar->activeSubControls & SC_ScrollBarSubPage && (scrollbar->state & State_MouseOver))
- stateId = SCRBS_HOT;
- else
- stateId = SCRBS_NORMAL;
- theme.partId = partId;
- theme.stateId = stateId;
- d->drawBackground(theme);
- }
- if (sub & SC_ScrollBarAddPage) {
- theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarAddPage, widget);
- partId = flags & State_Horizontal ? SBP_LOWERTRACKHORZ : SBP_LOWERTRACKVERT;
- if (!(flags & State_Enabled))
- stateId = SCRBS_DISABLED;
- else if (scrollbar->activeSubControls & SC_ScrollBarAddPage && (scrollbar->state & State_Sunken))
- stateId = SCRBS_PRESSED;
- else if (scrollbar->activeSubControls & SC_ScrollBarAddPage && (scrollbar->state & State_MouseOver))
- stateId = SCRBS_HOT;
- else
- stateId = SCRBS_NORMAL;
- theme.partId = partId;
- theme.stateId = stateId;
- d->drawBackground(theme);
- }
- if (sub & SC_ScrollBarSlider) {
- theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider, widget);
- if (!(flags & State_Enabled))
- stateId = SCRBS_DISABLED;
- else if (scrollbar->activeSubControls & SC_ScrollBarSlider && (scrollbar->state & State_Sunken))
- stateId = SCRBS_PRESSED;
- else if (scrollbar->activeSubControls & SC_ScrollBarSlider && (scrollbar->state & State_MouseOver))
- stateId = SCRBS_HOT;
- else
- stateId = SCRBS_NORMAL;
-
- // Draw handle
- theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider, widget);
- theme.partId = flags & State_Horizontal ? SBP_THUMBBTNHORZ : SBP_THUMBBTNVERT;
- theme.stateId = stateId;
- d->drawBackground(theme);
-
- // Calculate rect of gripper
- const int swidth = theme.rect.width();
- const int sheight = theme.rect.height();
-
- MARGINS contentsMargin;
- RECT rect = theme.toRECT(theme.rect);
- pGetThemeMargins(theme.handle(), 0, theme.partId, theme.stateId, TMT_SIZINGMARGINS, &rect, &contentsMargin);
-
- SIZE size;
- theme.partId = flags & State_Horizontal ? SBP_GRIPPERHORZ : SBP_GRIPPERVERT;
- pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
- int gw = size.cx, gh = size.cy;
-
-
- QRect gripperBounds;
- if (flags & State_Horizontal && ((swidth - contentsMargin.cxLeftWidth - contentsMargin.cxRightWidth) > gw)) {
- gripperBounds.setLeft(theme.rect.left() + swidth/2 - gw/2);
- gripperBounds.setTop(theme.rect.top() + sheight/2 - gh/2);
- gripperBounds.setWidth(gw);
- gripperBounds.setHeight(gh);
- } else if ((sheight - contentsMargin.cyTopHeight - contentsMargin.cyBottomHeight) > gh) {
- gripperBounds.setLeft(theme.rect.left() + swidth/2 - gw/2);
- gripperBounds.setTop(theme.rect.top() + sheight/2 - gh/2);
- gripperBounds.setWidth(gw);
- gripperBounds.setHeight(gh);
- }
-
- // Draw gripper if there is enough space
- if (!gripperBounds.isEmpty()) {
- p->save();
- theme.rect = gripperBounds;
- p->setClipRegion(d->region(theme));// Only change inside the region of the gripper
- d->drawBackground(theme); // Transparent gripper ontop of background
- p->restore();
- }
- }
- }
- }
- break;
-
-#ifndef QT_NO_SLIDER
- case CC_Slider:
- if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option))
- {
- XPThemeData theme(widget, p, QLatin1String("TRACKBAR"));
- QRect slrect = slider->rect;
- QRegion tickreg = slrect;
- if (sub & SC_SliderGroove) {
- theme.rect = proxy()->subControlRect(CC_Slider, option, SC_SliderGroove, widget);
- if (slider->orientation == Qt::Horizontal) {
- partId = TKP_TRACK;
- stateId = TRS_NORMAL;
- theme.rect = QRect(slrect.left(), theme.rect.center().y() - 2, slrect.width(), 4);
- } else {
- partId = TKP_TRACKVERT;
- stateId = TRVS_NORMAL;
- theme.rect = QRect(theme.rect.center().x() - 2, slrect.top(), 4, slrect.height());
- }
- theme.partId = partId;
- theme.stateId = stateId;
- d->drawBackground(theme);
- tickreg -= theme.rect;
- }
- if (sub & SC_SliderTickmarks) {
- int tickOffset = proxy()->pixelMetric(PM_SliderTickmarkOffset, slider, widget);
- int ticks = slider->tickPosition;
- int thickness = proxy()->pixelMetric(PM_SliderControlThickness, slider, widget);
- int len = proxy()->pixelMetric(PM_SliderLength, slider, widget);
- int available = proxy()->pixelMetric(PM_SliderSpaceAvailable, slider, widget);
- int interval = slider->tickInterval;
- if (interval <= 0) {
- interval = slider->singleStep;
- if (QStyle::sliderPositionFromValue(slider->minimum, slider->maximum, interval,
- available)
- - QStyle::sliderPositionFromValue(slider->minimum, slider->maximum,
- 0, available) < 3)
- interval = slider->pageStep;
- }
- if (!interval)
- interval = 1;
- int fudge = len / 2;
- int pos;
- int bothOffset = (ticks & QSlider::TicksAbove && ticks & QSlider::TicksBelow) ? 1 : 0;
- p->setPen(d->sliderTickColor);
- QVarLengthArray<QLine, 32> lines;
- int v = slider->minimum;
- while (v <= slider->maximum + 1) {
- if (v == slider->maximum + 1 && interval == 1)
- break;
- const int v_ = qMin(v, slider->maximum);
- int tickLength = (v_ == slider->minimum || v_ >= slider->maximum) ? 4 : 3;
- pos = QStyle::sliderPositionFromValue(slider->minimum, slider->maximum,
- v_, available) + fudge;
- if (slider->orientation == Qt::Horizontal) {
- if (ticks & QSlider::TicksAbove)
- lines.append(QLine(pos, tickOffset - 1 - bothOffset,
- pos, tickOffset - 1 - bothOffset - tickLength));
-
- if (ticks & QSlider::TicksBelow)
- lines.append(QLine(pos, tickOffset + thickness + bothOffset,
- pos, tickOffset + thickness + bothOffset + tickLength));
- } else {
- if (ticks & QSlider::TicksAbove)
- lines.append(QLine(tickOffset - 1 - bothOffset, pos,
- tickOffset - 1 - bothOffset - tickLength, pos));
-
- if (ticks & QSlider::TicksBelow)
- lines.append(QLine(tickOffset + thickness + bothOffset, pos,
- tickOffset + thickness + bothOffset + tickLength, pos));
- }
- // in the case where maximum is max int
- int nextInterval = v + interval;
- if (nextInterval < v)
- break;
- v = nextInterval;
- }
- if (lines.size() > 0) {
- p->save();
- p->translate(slrect.topLeft());
- p->drawLines(lines.constData(), lines.size());
- p->restore();
- }
- }
- if (sub & SC_SliderHandle) {
- theme.rect = proxy()->subControlRect(CC_Slider, option, SC_SliderHandle, widget);
- if (slider->orientation == Qt::Horizontal) {
- if (slider->tickPosition == QSlider::TicksAbove)
- partId = TKP_THUMBTOP;
- else if (slider->tickPosition == QSlider::TicksBelow)
- partId = TKP_THUMBBOTTOM;
- else
- partId = TKP_THUMB;
-
- if (!(slider->state & State_Enabled))
- stateId = TUS_DISABLED;
- else if (slider->activeSubControls & SC_SliderHandle && (slider->state & State_Sunken))
- stateId = TUS_PRESSED;
- else if (slider->activeSubControls & SC_SliderHandle && (slider->state & State_MouseOver))
- stateId = TUS_HOT;
- else if (flags & State_HasFocus)
- stateId = TUS_FOCUSED;
- else
- stateId = TUS_NORMAL;
- } else {
- if (slider->tickPosition == QSlider::TicksLeft)
- partId = TKP_THUMBLEFT;
- else if (slider->tickPosition == QSlider::TicksRight)
- partId = TKP_THUMBRIGHT;
- else
- partId = TKP_THUMBVERT;
-
- if (!(slider->state & State_Enabled))
- stateId = TUVS_DISABLED;
- else if (slider->activeSubControls & SC_SliderHandle && (slider->state & State_Sunken))
- stateId = TUVS_PRESSED;
- else if (slider->activeSubControls & SC_SliderHandle && (slider->state & State_MouseOver))
- stateId = TUVS_HOT;
- else if (flags & State_HasFocus)
- stateId = TUVS_FOCUSED;
- else
- stateId = TUVS_NORMAL;
- }
- theme.partId = partId;
- theme.stateId = stateId;
- d->drawBackground(theme);
- }
- if (slider->state & State_HasFocus) {
- QStyleOptionFocusRect fropt;
- fropt.QStyleOption::operator=(*slider);
- fropt.rect = subElementRect(SE_SliderFocusRect, slider, widget);
- proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, p, widget);
- }
- }
- break;
-#endif
-#ifndef QT_NO_TOOLBUTTON
- case CC_ToolButton:
- if (const QStyleOptionToolButton *toolbutton
- = qstyleoption_cast<const QStyleOptionToolButton *>(option)) {
- QRect button, menuarea;
- button = proxy()->subControlRect(cc, toolbutton, SC_ToolButton, widget);
- menuarea = proxy()->subControlRect(cc, toolbutton, SC_ToolButtonMenu, widget);
-
- State bflags = toolbutton->state & ~State_Sunken;
- State mflags = bflags;
- bool autoRaise = flags & State_AutoRaise;
- if (autoRaise) {
- if (!(bflags & State_MouseOver) || !(bflags & State_Enabled)) {
- bflags &= ~State_Raised;
- }
- }
-
- if (toolbutton->state & State_Sunken) {
- if (toolbutton->activeSubControls & SC_ToolButton) {
- bflags |= State_Sunken;
- mflags |= State_MouseOver | State_Sunken;
- } else if (toolbutton->activeSubControls & SC_ToolButtonMenu) {
- mflags |= State_Sunken;
- bflags |= State_MouseOver;
- }
- }
-
- QStyleOption tool(0);
- tool.palette = toolbutton->palette;
- if (toolbutton->subControls & SC_ToolButton) {
- if (flags & (State_Sunken | State_On | State_Raised) || !autoRaise) {
- if (toolbutton->features & QStyleOptionToolButton::MenuButtonPopup && autoRaise) {
- XPThemeData theme(widget, p, QLatin1String("TOOLBAR"));
- theme.partId = TP_SPLITBUTTON;
- theme.rect = button;
- if (!(bflags & State_Enabled))
- stateId = TS_DISABLED;
- else if (bflags & State_Sunken)
- stateId = TS_PRESSED;
- else if (bflags & State_MouseOver || !(flags & State_AutoRaise))
- stateId = flags & State_On ? TS_HOTCHECKED : TS_HOT;
- else if (bflags & State_On)
- stateId = TS_CHECKED;
- else
- stateId = TS_NORMAL;
- if (option->direction == Qt::RightToLeft)
- theme.mirrorHorizontally = true;
- theme.stateId = stateId;
- d->drawBackground(theme);
- } else {
- tool.rect = option->rect;
- tool.state = bflags;
- if (autoRaise) // for tool bars
- proxy()->drawPrimitive(PE_PanelButtonTool, &tool, p, widget);
- else
- proxy()->drawPrimitive(PE_PanelButtonBevel, &tool, p, widget);
- }
- }
- }
-
- if (toolbutton->state & State_HasFocus) {
- QStyleOptionFocusRect fr;
- fr.QStyleOption::operator=(*toolbutton);
- fr.rect.adjust(3, 3, -3, -3);
- if (toolbutton->features & QStyleOptionToolButton::MenuButtonPopup)
- fr.rect.adjust(0, 0, -proxy()->pixelMetric(QStyle::PM_MenuButtonIndicator,
- toolbutton, widget), 0);
- proxy()->drawPrimitive(PE_FrameFocusRect, &fr, p, widget);
- }
- QStyleOptionToolButton label = *toolbutton;
- label.state = bflags;
- int fw = 2;
- if (!autoRaise)
- label.state &= ~State_Sunken;
- label.rect = button.adjusted(fw, fw, -fw, -fw);
- proxy()->drawControl(CE_ToolButtonLabel, &label, p, widget);
-
- if (toolbutton->subControls & SC_ToolButtonMenu) {
- tool.rect = menuarea;
- tool.state = mflags;
- if (autoRaise) {
- proxy()->drawPrimitive(PE_IndicatorButtonDropDown, &tool, p, widget);
- } else {
- tool.state = mflags;
- menuarea.adjust(-2, 0, 0, 0);
- // Draw menu button
- if ((bflags & State_Sunken) != (mflags & State_Sunken)){
- p->save();
- p->setClipRect(menuarea);
- tool.rect = option->rect;
- proxy()->drawPrimitive(PE_PanelButtonBevel, &tool, p, 0);
- p->restore();
- }
- // Draw arrow
- p->save();
- p->setPen(option->palette.dark().color());
- p->drawLine(menuarea.left(), menuarea.top() + 3,
- menuarea.left(), menuarea.bottom() - 3);
- p->setPen(option->palette.light().color());
- p->drawLine(menuarea.left() - 1, menuarea.top() + 3,
- menuarea.left() - 1, menuarea.bottom() - 3);
-
- tool.rect = menuarea.adjusted(2, 3, -2, -1);
- proxy()->drawPrimitive(PE_IndicatorArrowDown, &tool, p, widget);
- p->restore();
- }
- } else if (toolbutton->features & QStyleOptionToolButton::HasMenu) {
- int mbi = proxy()->pixelMetric(PM_MenuButtonIndicator, toolbutton, widget);
- QRect ir = toolbutton->rect;
- QStyleOptionToolButton newBtn = *toolbutton;
- newBtn.rect = QRect(ir.right() + 4 - mbi, ir.height() - mbi + 4, mbi - 5, mbi - 5);
- proxy()->drawPrimitive(PE_IndicatorArrowDown, &newBtn, p, widget);
- }
- }
- break;
-#endif // QT_NO_TOOLBUTTON
-
- case CC_TitleBar:
- {
- if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(option))
- {
- bool isActive = tb->titleBarState & QStyle::State_Active;
- XPThemeData theme(widget, p, QLatin1String("WINDOW"));
- if (sub & SC_TitleBarLabel) {
-
-#ifdef QT3_SUPPORT
- if (widget && widget->inherits("Q3DockWindowTitleBar")) {
- partId = WP_SMALLCAPTION;
- } else
-#endif
- partId = (tb->titleBarState & Qt::WindowMinimized) ? WP_MINCAPTION : WP_CAPTION;
- theme.rect = option->rect;
- if (widget && !widget->isEnabled())
- stateId = CS_DISABLED;
- else if (isActive)
- stateId = CS_ACTIVE;
- else
- stateId = CS_INACTIVE;
-
- theme.partId = partId;
- theme.stateId = stateId;
- d->drawBackground(theme);
-
- QRect ir = proxy()->subControlRect(CC_TitleBar, tb, SC_TitleBarLabel, widget);
-
- int result = TST_NONE;
- pGetThemeEnumValue(theme.handle(), WP_CAPTION, isActive ? CS_ACTIVE : CS_INACTIVE, TMT_TEXTSHADOWTYPE, &result);
- if (result != TST_NONE) {
- COLORREF textShadowRef;
- pGetThemeColor(theme.handle(), WP_CAPTION, isActive ? CS_ACTIVE : CS_INACTIVE, TMT_TEXTSHADOWCOLOR, &textShadowRef);
- QColor textShadow = qRgb(GetRValue(textShadowRef), GetGValue(textShadowRef), GetBValue(textShadowRef));
- p->setPen(textShadow);
- p->drawText(ir.x() + 3, ir.y() + 2, ir.width() - 1, ir.height(),
- Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine, tb->text);
- }
- COLORREF captionText = GetSysColor(isActive ? COLOR_CAPTIONTEXT : COLOR_INACTIVECAPTIONTEXT);
- QColor textColor = qRgb(GetRValue(captionText), GetGValue(captionText), GetBValue(captionText));
- p->setPen(textColor);
- p->drawText(ir.x() + 2, ir.y() + 1, ir.width() - 2, ir.height(),
- Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine, tb->text);
- }
- if (sub & SC_TitleBarSysMenu && tb->titleBarFlags & Qt::WindowSystemMenuHint) {
- theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarSysMenu, widget);
- partId = WP_SYSBUTTON;
- if ((widget && !widget->isEnabled()) || !isActive)
- stateId = SBS_DISABLED;
- else if (option->activeSubControls == SC_TitleBarSysMenu && (option->state & State_Sunken))
- stateId = SBS_PUSHED;
- else if (option->activeSubControls == SC_TitleBarSysMenu && (option->state & State_MouseOver))
- stateId = SBS_HOT;
- else
- stateId = SBS_NORMAL;
- if (!tb->icon.isNull()) {
- tb->icon.paint(p, theme.rect);
- } else {
- theme.partId = partId;
- theme.stateId = stateId;
- SIZE sz;
- pGetThemePartSize(theme.handle(), qt_win_display_dc(), theme.partId, theme.stateId, 0, TS_TRUE, &sz);
- if (sz.cx == 0 || sz.cy == 0) {
- int iconSize = proxy()->pixelMetric(PM_SmallIconSize, tb, widget);
- QPixmap pm = proxy()->standardIcon(SP_TitleBarMenuButton, tb, widget).pixmap(iconSize, iconSize);
- p->save();
- drawItemPixmap(p, theme.rect, Qt::AlignCenter, pm);
- p->restore();
- } else {
- d->drawBackground(theme);
- }
- }
- }
-
- if (sub & SC_TitleBarMinButton && tb->titleBarFlags & Qt::WindowMinimizeButtonHint
- && !(tb->titleBarState & Qt::WindowMinimized)) {
- theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarMinButton, widget);
- partId = WP_MINBUTTON;
- if (widget && !widget->isEnabled())
- stateId = MINBS_DISABLED;
- else if (option->activeSubControls == SC_TitleBarMinButton && (option->state & State_Sunken))
- stateId = MINBS_PUSHED;
- else if (option->activeSubControls == SC_TitleBarMinButton && (option->state & State_MouseOver))
- stateId = MINBS_HOT;
- else if (!isActive)
- stateId = MINBS_INACTIVE;
- else
- stateId = MINBS_NORMAL;
- theme.partId = partId;
- theme.stateId = stateId;
- d->drawBackground(theme);
- }
- if (sub & SC_TitleBarMaxButton && tb->titleBarFlags & Qt::WindowMaximizeButtonHint
- && !(tb->titleBarState & Qt::WindowMaximized)) {
- theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarMaxButton, widget);
- partId = WP_MAXBUTTON;
- if (widget && !widget->isEnabled())
- stateId = MAXBS_DISABLED;
- else if (option->activeSubControls == SC_TitleBarMaxButton && (option->state & State_Sunken))
- stateId = MAXBS_PUSHED;
- else if (option->activeSubControls == SC_TitleBarMaxButton && (option->state & State_MouseOver))
- stateId = MAXBS_HOT;
- else if (!isActive)
- stateId = MAXBS_INACTIVE;
- else
- stateId = MAXBS_NORMAL;
- theme.partId = partId;
- theme.stateId = stateId;
- d->drawBackground(theme);
- }
- if (sub & SC_TitleBarContextHelpButton
- && tb->titleBarFlags & Qt::WindowContextHelpButtonHint) {
- theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarContextHelpButton, widget);
- partId = WP_HELPBUTTON;
- if (widget && !widget->isEnabled())
- stateId = MINBS_DISABLED;
- else if (option->activeSubControls == SC_TitleBarContextHelpButton && (option->state & State_Sunken))
- stateId = MINBS_PUSHED;
- else if (option->activeSubControls == SC_TitleBarContextHelpButton && (option->state & State_MouseOver))
- stateId = MINBS_HOT;
- else if (!isActive)
- stateId = MINBS_INACTIVE;
- else
- stateId = MINBS_NORMAL;
- theme.partId = partId;
- theme.stateId = stateId;
- d->drawBackground(theme);
- }
- bool drawNormalButton = (sub & SC_TitleBarNormalButton)
- && (((tb->titleBarFlags & Qt::WindowMinimizeButtonHint)
- && (tb->titleBarState & Qt::WindowMinimized))
- || ((tb->titleBarFlags & Qt::WindowMaximizeButtonHint)
- && (tb->titleBarState & Qt::WindowMaximized)));
- if (drawNormalButton) {
- theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarNormalButton, widget);
- partId = WP_RESTOREBUTTON;
- if (widget && !widget->isEnabled())
- stateId = RBS_DISABLED;
- else if (option->activeSubControls == SC_TitleBarNormalButton && (option->state & State_Sunken))
- stateId = RBS_PUSHED;
- else if (option->activeSubControls == SC_TitleBarNormalButton && (option->state & State_MouseOver))
- stateId = RBS_HOT;
- else if (!isActive)
- stateId = RBS_INACTIVE;
- else
- stateId = RBS_NORMAL;
- theme.partId = partId;
- theme.stateId = stateId;
- d->drawBackground(theme);
- }
- if (sub & SC_TitleBarShadeButton && tb->titleBarFlags & Qt::WindowShadeButtonHint
- && !(tb->titleBarState & Qt::WindowMinimized)) {
- theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarShadeButton, widget);
- partId = WP_MINBUTTON;
- if (widget && !widget->isEnabled())
- stateId = MINBS_DISABLED;
- else if (option->activeSubControls == SC_TitleBarShadeButton && (option->state & State_Sunken))
- stateId = MINBS_PUSHED;
- else if (option->activeSubControls == SC_TitleBarShadeButton && (option->state & State_MouseOver))
- stateId = MINBS_HOT;
- else if (!isActive)
- stateId = MINBS_INACTIVE;
- else
- stateId = MINBS_NORMAL;
- theme.partId = partId;
- theme.stateId = stateId;
- d->drawBackground(theme);
- }
- if (sub & SC_TitleBarUnshadeButton && tb->titleBarFlags & Qt::WindowShadeButtonHint
- && tb->titleBarState & Qt::WindowMinimized) {
- theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarUnshadeButton, widget);
- partId = WP_RESTOREBUTTON;
- if (widget && !widget->isEnabled())
- stateId = RBS_DISABLED;
- else if (option->activeSubControls == SC_TitleBarUnshadeButton && (option->state & State_Sunken))
- stateId = RBS_PUSHED;
- else if (option->activeSubControls == SC_TitleBarUnshadeButton && (option->state & State_MouseOver))
- stateId = RBS_HOT;
- else if (!isActive)
- stateId = RBS_INACTIVE;
- else
- stateId = RBS_NORMAL;
- theme.partId = partId;
- theme.stateId = stateId;
- d->drawBackground(theme);
- }
- if (sub & SC_TitleBarCloseButton && tb->titleBarFlags & Qt::WindowSystemMenuHint) {
- theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarCloseButton, widget);
- //partId = titlebar->testWFlags(Qt::WA_WState_Tool) ? WP_SMALLCLOSEBUTTON : WP_CLOSEBUTTON;
- partId = WP_CLOSEBUTTON;
- if (widget && !widget->isEnabled())
- stateId = CBS_DISABLED;
- else if (option->activeSubControls == SC_TitleBarCloseButton && (option->state & State_Sunken))
- stateId = CBS_PUSHED;
- else if (option->activeSubControls == SC_TitleBarCloseButton && (option->state & State_MouseOver))
- stateId = CBS_HOT;
- else if (!isActive)
- stateId = CBS_INACTIVE;
- else
- stateId = CBS_NORMAL;
- theme.partId = partId;
- theme.stateId = stateId;
- d->drawBackground(theme);
- }
- }
- }
- break;
-
-#ifndef QT_NO_WORKSPACE
- case CC_MdiControls:
- {
- QRect buttonRect;
- XPThemeData theme(widget, p, QLatin1String("WINDOW"), WP_MDICLOSEBUTTON, CBS_NORMAL);
-
- if (option->subControls & SC_MdiCloseButton) {
- buttonRect = proxy()->subControlRect(CC_MdiControls, option, SC_MdiCloseButton, widget);
- if (theme.isValid()) {
- theme.partId = WP_MDICLOSEBUTTON;
- theme.rect = buttonRect;
- if (!(flags & State_Enabled))
- theme.stateId = CBS_INACTIVE;
- else if (flags & State_Sunken && (option->activeSubControls & SC_MdiCloseButton))
- theme.stateId = CBS_PUSHED;
- else if (flags & State_MouseOver && (option->activeSubControls & SC_MdiCloseButton))
- theme.stateId = CBS_HOT;
- else
- theme.stateId = CBS_NORMAL;
- d->drawBackground(theme);
- }
- }
- if (option->subControls & SC_MdiNormalButton) {
- buttonRect = proxy()->subControlRect(CC_MdiControls, option, SC_MdiNormalButton, widget);
- if (theme.isValid()) {
- theme.partId = WP_MDIRESTOREBUTTON;
- theme.rect = buttonRect;
- if (!(flags & State_Enabled))
- theme.stateId = CBS_INACTIVE;
- else if (flags & State_Sunken && (option->activeSubControls & SC_MdiNormalButton))
- theme.stateId = CBS_PUSHED;
- else if (flags & State_MouseOver && (option->activeSubControls & SC_MdiNormalButton))
- theme.stateId = CBS_HOT;
- else
- theme.stateId = CBS_NORMAL;
- d->drawBackground(theme);
- }
- }
- if (option->subControls & QStyle::SC_MdiMinButton) {
- buttonRect = proxy()->subControlRect(CC_MdiControls, option, SC_MdiMinButton, widget);
- if (theme.isValid()) {
- theme.partId = WP_MDIMINBUTTON;
- theme.rect = buttonRect;
- if (!(flags & State_Enabled))
- theme.stateId = CBS_INACTIVE;
- else if (flags & State_Sunken && (option->activeSubControls & SC_MdiMinButton))
- theme.stateId = CBS_PUSHED;
- else if (flags & State_MouseOver && (option->activeSubControls & SC_MdiMinButton))
- theme.stateId = CBS_HOT;
- else
- theme.stateId = CBS_NORMAL;
- d->drawBackground(theme);
- }
- }
- }
- break;
-#endif //QT_NO_WORKSPACE
-#ifndef QT_NO_DIAL
- case CC_Dial:
- if (const QStyleOptionSlider *dial = qstyleoption_cast<const QStyleOptionSlider *>(option))
- QStyleHelper::drawDial(dial, p);
- break;
-#endif // QT_NO_DIAL
- default:
- QWindowsStyle::drawComplexControl(cc, option, p, widget);
- break;
- }
-}
-
-/*! \reimp */
-int QWindowsXPStyle::pixelMetric(PixelMetric pm, const QStyleOption *option, const QWidget *widget) const
-{
- if (!QWindowsXPStylePrivate::useXP())
- return QWindowsStyle::pixelMetric(pm, option, widget);
-
- int res = 0;
- switch (pm) {
- case PM_MenuBarPanelWidth:
- res = 0;
- break;
-
- case PM_DefaultFrameWidth:
- if (qobject_cast<const QListView*>(widget))
- res = 2;
- else
- res = 1;
- break;
- case PM_MenuPanelWidth:
- case PM_SpinBoxFrameWidth:
- res = 1;
- break;
-
- case PM_TabBarTabOverlap:
- case PM_MenuHMargin:
- case PM_MenuVMargin:
- res = 2;
- break;
-
- case PM_TabBarBaseOverlap:
- if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(option)) {
- switch (tab->shape) {
- case QTabBar::RoundedNorth:
- case QTabBar::TriangularNorth:
- res = 1;
- break;
- case QTabBar::RoundedSouth:
- case QTabBar::TriangularSouth:
- res = 2;
- break;
- case QTabBar::RoundedEast:
- case QTabBar::TriangularEast:
- res = 3;
- break;
- case QTabBar::RoundedWest:
- case QTabBar::TriangularWest:
- res = 1;
- break;
- }
- }
- break;
-
- case PM_SplitterWidth:
- res = qMax(int(QStyleHelper::dpiScaled(5.)), QApplication::globalStrut().width());
- break;
-
- case PM_IndicatorWidth:
- case PM_IndicatorHeight:
- {
- XPThemeData theme(widget, 0, QLatin1String("BUTTON"), BP_CHECKBOX, CBS_UNCHECKEDNORMAL);
- if (theme.isValid()) {
- SIZE size;
- pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
- res = (pm == PM_IndicatorWidth) ? size.cx : size.cy;
- }
- }
- break;
-
- case PM_ExclusiveIndicatorWidth:
- case PM_ExclusiveIndicatorHeight:
- {
- XPThemeData theme(widget, 0, QLatin1String("BUTTON"), BP_RADIOBUTTON, RBS_UNCHECKEDNORMAL);
- if (theme.isValid()) {
- SIZE size;
- pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
- res = (pm == PM_ExclusiveIndicatorWidth) ? size.cx : size.cy;
- }
- }
- break;
-
- case PM_ProgressBarChunkWidth:
- {
- Qt::Orientation orient = Qt::Horizontal;
- if (const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option))
- orient = pb2->orientation;
- XPThemeData theme(widget, 0, QLatin1String("PROGRESS"), (orient == Qt::Horizontal) ? PP_CHUNK : PP_CHUNKVERT);
- if (theme.isValid()) {
- SIZE size;
- pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
- res = (orient == Qt::Horizontal) ? size.cx : size.cy;
- }
- }
- break;
-
- case PM_SliderThickness:
- {
- XPThemeData theme(widget, 0, QLatin1String("TRACKBAR"), TKP_THUMB);
- if (theme.isValid()) {
- SIZE size;
- pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
- res = size.cy;
- }
- }
- break;
-
- case PM_TitleBarHeight:
- {
-#ifdef QT3_SUPPORT
- if (widget && widget->inherits("Q3DockWindowTitleBar")) {
- res = GetSystemMetrics(SM_CYSMCAPTION) + GetSystemMetrics(SM_CXSIZEFRAME);
- } else
-#endif
- if (widget && (widget->windowType() == Qt::Tool))
- res = GetSystemMetrics(SM_CYSMCAPTION) + GetSystemMetrics(SM_CXSIZEFRAME);
- else
- res = GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CXSIZEFRAME);
- }
- break;
-
- case PM_MdiSubWindowFrameWidth:
- {
- XPThemeData theme(widget, 0, QLatin1String("WINDOW"), WP_FRAMELEFT, FS_ACTIVE);
- if (theme.isValid()) {
- SIZE size;
- pGetThemePartSize(theme.handle(), 0, WP_FRAMELEFT, FS_ACTIVE, 0, TS_TRUE, &size);
- res = size.cx-1;
- }
- }
- break;
-
- case PM_MdiSubWindowMinimizedWidth:
- res = 160;
- break;
-
-#ifndef QT_NO_TOOLBAR
- case PM_ToolBarHandleExtent:
- res = int(QStyleHelper::dpiScaled(8.));
- break;
-
-#endif // QT_NO_TOOLBAR
- case PM_DockWidgetFrameWidth:
- {
- XPThemeData theme(widget, 0, QLatin1String("WINDOW"), WP_SMALLFRAMERIGHT, FS_ACTIVE);
- if (theme.isValid()) {
- SIZE size;
- pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
- res = size.cx;
- }
- }
- break;
- case PM_DockWidgetSeparatorExtent:
- res = int(QStyleHelper::dpiScaled(4.));
- break;
- case PM_DockWidgetTitleMargin:
- res = int(QStyleHelper::dpiScaled(4.));
- break;
-
- case PM_ButtonShiftHorizontal:
- case PM_ButtonShiftVertical:
- if (qstyleoption_cast<const QStyleOptionToolButton *>(option))
- res = 1;
- else
- res = 0;
- break;
-
- case PM_ButtonDefaultIndicator:
- res = 0;
- break;
-
- default:
- res = QWindowsStyle::pixelMetric(pm, option, widget);
- }
-
- return res;
-}
-
-/*
- This function is used by subControlRect to check if a button
- should be drawn for the given subControl given a set of window flags.
-*/
-static bool buttonVisible(const QStyle::SubControl sc, const QStyleOptionTitleBar *tb){
-
- bool isMinimized = tb->titleBarState & Qt::WindowMinimized;
- bool isMaximized = tb->titleBarState & Qt::WindowMaximized;
- const uint flags = tb->titleBarFlags;
- bool retVal = false;
- switch (sc) {
- case QStyle::SC_TitleBarContextHelpButton:
- if (flags & Qt::WindowContextHelpButtonHint)
- retVal = true;
- break;
- case QStyle::SC_TitleBarMinButton:
- if (!isMinimized && (flags & Qt::WindowMinimizeButtonHint))
- retVal = true;
- break;
- case QStyle::SC_TitleBarNormalButton:
- if (isMinimized && (flags & Qt::WindowMinimizeButtonHint))
- retVal = true;
- else if (isMaximized && (flags & Qt::WindowMaximizeButtonHint))
- retVal = true;
- break;
- case QStyle::SC_TitleBarMaxButton:
- if (!isMaximized && (flags & Qt::WindowMaximizeButtonHint))
- retVal = true;
- break;
- case QStyle::SC_TitleBarShadeButton:
- if (!isMinimized && flags & Qt::WindowShadeButtonHint)
- retVal = true;
- break;
- case QStyle::SC_TitleBarUnshadeButton:
- if (isMinimized && flags & Qt::WindowShadeButtonHint)
- retVal = true;
- break;
- case QStyle::SC_TitleBarCloseButton:
- if (flags & Qt::WindowSystemMenuHint)
- retVal = true;
- break;
- case QStyle::SC_TitleBarSysMenu:
- if (flags & Qt::WindowSystemMenuHint)
- retVal = true;
- break;
- default :
- retVal = true;
- }
- return retVal;
-}
-
-/*!
- \reimp
-*/
-QRect QWindowsXPStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex *option,
- SubControl subControl, const QWidget *widget) const
-{
- if (!QWindowsXPStylePrivate::useXP())
- return QWindowsStyle::subControlRect(cc, option, subControl, widget);
-
- QRect rect;
-
- switch (cc) {
- case CC_TitleBar:
- if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(option)) {
- if (!buttonVisible(subControl, tb))
- return rect;
- const bool isToolTitle = false;
- const int height = tb->rect.height();
- const int width = tb->rect.width();
- int buttonHeight = GetSystemMetrics(SM_CYSIZE) - 4;
- int buttonWidth = GetSystemMetrics(SM_CXSIZE) - 4;
- const int delta = buttonWidth + 2;
- int controlTop = option->rect.bottom() - buttonHeight - 2;
- const int frameWidth = proxy()->pixelMetric(PM_MdiSubWindowFrameWidth, option, widget);
- const bool sysmenuHint = (tb->titleBarFlags & Qt::WindowSystemMenuHint) != 0;
- const bool minimizeHint = (tb->titleBarFlags & Qt::WindowMinimizeButtonHint) != 0;
- const bool maximizeHint = (tb->titleBarFlags & Qt::WindowMaximizeButtonHint) != 0;
- const bool contextHint = (tb->titleBarFlags & Qt::WindowContextHelpButtonHint) != 0;
- const bool shadeHint = (tb->titleBarFlags & Qt::WindowShadeButtonHint) != 0;
- bool isMinimized = tb->titleBarState & Qt::WindowMinimized;
- bool isMaximized = tb->titleBarState & Qt::WindowMaximized;
- int offset = 0;
-
- switch (subControl) {
- case SC_TitleBarLabel:
- rect = QRect(frameWidth, 0, width - (buttonWidth + frameWidth + 10), height);
- if (isToolTitle) {
- if (sysmenuHint) {
- rect.adjust(0, 0, -buttonWidth - 3, 0);
- }
- if (minimizeHint || maximizeHint)
- rect.adjust(0, 0, -buttonWidth - 2, 0);
- } else {
- if (sysmenuHint) {
- const int leftOffset = height - 8;
- rect.adjust(leftOffset, 0, 0, 0);
- }
- if (minimizeHint)
- rect.adjust(0, 0, -buttonWidth - 2, 0);
- if (maximizeHint)
- rect.adjust(0, 0, -buttonWidth - 2, 0);
- if (contextHint)
- rect.adjust(0, 0, -buttonWidth - 2, 0);
- if (shadeHint)
- rect.adjust(0, 0, -buttonWidth - 2, 0);
- }
- break;
-
- case SC_TitleBarContextHelpButton:
- if (tb->titleBarFlags & Qt::WindowContextHelpButtonHint)
- offset += delta;
- //fall through
- case SC_TitleBarMinButton:
- if (!isMinimized && (tb->titleBarFlags & Qt::WindowMinimizeButtonHint))
- offset += delta;
- else if (subControl == SC_TitleBarMinButton)
- break;
- //fall through
- case SC_TitleBarNormalButton:
- if (isMinimized && (tb->titleBarFlags & Qt::WindowMinimizeButtonHint))
- offset += delta;
- else if (isMaximized && (tb->titleBarFlags & Qt::WindowMaximizeButtonHint))
- offset += delta;
- else if (subControl == SC_TitleBarNormalButton)
- break;
- //fall through
- case SC_TitleBarMaxButton:
- if (!isMaximized && (tb->titleBarFlags & Qt::WindowMaximizeButtonHint))
- offset += delta;
- else if (subControl == SC_TitleBarMaxButton)
- break;
- //fall through
- case SC_TitleBarShadeButton:
- if (!isMinimized && (tb->titleBarFlags & Qt::WindowShadeButtonHint))
- offset += delta;
- else if (subControl == SC_TitleBarShadeButton)
- break;
- //fall through
- case SC_TitleBarUnshadeButton:
- if (isMinimized && (tb->titleBarFlags & Qt::WindowShadeButtonHint))
- offset += delta;
- else if (subControl == SC_TitleBarUnshadeButton)
- break;
- //fall through
- case SC_TitleBarCloseButton:
- if (tb->titleBarFlags & Qt::WindowSystemMenuHint)
- offset += delta;
- else if (subControl == SC_TitleBarCloseButton)
- break;
-
- rect.setRect(width - offset - controlTop + 1, controlTop,
- buttonWidth, buttonHeight);
- break;
-
- case SC_TitleBarSysMenu:
- {
- const int controlTop = 6;
- const int controlHeight = height - controlTop - 3;
- const int iconExtent = proxy()->pixelMetric(PM_SmallIconSize);
- QSize iconSize = tb->icon.actualSize(QSize(iconExtent, iconExtent));
- if (tb->icon.isNull())
- iconSize = QSize(controlHeight, controlHeight);
- int hPad = (controlHeight - iconSize.height())/2;
- int vPad = (controlHeight - iconSize.width())/2;
- rect = QRect(frameWidth + hPad, controlTop + vPad, iconSize.width(), iconSize.height());
- }
- break;
- default:
- break;
- }
- }
- break;
-
- case CC_ComboBox:
- if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
- int x = cmb->rect.x(), y = cmb->rect.y(), wi = cmb->rect.width(), he = cmb->rect.height();
- int xpos = x;
- xpos += wi - 1 - 16;
-
- switch (subControl) {
- case SC_ComboBoxFrame:
- rect = cmb->rect;
- break;
-
- case SC_ComboBoxArrow:
- rect = QRect(xpos, y+1, 16, he-2);
- break;
-
- case SC_ComboBoxEditField:
- rect = QRect(x+2, y+2, wi-3-16, he-4);
- break;
-
- case SC_ComboBoxListBoxPopup:
- rect = cmb->rect;
- break;
-
- default:
- break;
- }
- }
- break;
-#ifndef QT_NO_WORKSPACE
- case CC_MdiControls:
- {
- int numSubControls = 0;
- if (option->subControls & SC_MdiCloseButton)
- ++numSubControls;
- if (option->subControls & SC_MdiMinButton)
- ++numSubControls;
- if (option->subControls & SC_MdiNormalButton)
- ++numSubControls;
- if (numSubControls == 0)
- break;
-
- int buttonWidth = option->rect.width()/ numSubControls;
- int offset = 0;
- switch (subControl) {
- case SC_MdiCloseButton:
- // Only one sub control, no offset needed.
- if (numSubControls == 1)
- break;
- offset += buttonWidth;
- //FALL THROUGH
- case SC_MdiNormalButton:
- // No offset needed if
- // 1) There's only one sub control
- // 2) We have a close button and a normal button (offset already added in SC_MdiClose)
- if (numSubControls == 1 || (numSubControls == 2 && !(option->subControls & SC_MdiMinButton)))
- break;
- if (option->subControls & SC_MdiNormalButton)
- offset += buttonWidth;
- break;
- default:
- break;
- }
- rect = QRect(offset, 0, buttonWidth, option->rect.height());
- break;
- }
-#endif // QT_NO_WORKSPACE
-
- default:
- rect = visualRect(option->direction, option->rect,
- QWindowsStyle::subControlRect(cc, option, subControl, widget));
- break;
- }
- return visualRect(option->direction, option->rect, rect);
-}
-
-/*!
- \reimp
-*/
-QSize QWindowsXPStyle::sizeFromContents(ContentsType ct, const QStyleOption *option,
- const QSize &contentsSize, const QWidget *widget) const
-{
- if (!QWindowsXPStylePrivate::useXP())
- return QWindowsStyle::sizeFromContents(ct, option, contentsSize, widget);
-
- QSize sz(contentsSize);
- switch (ct) {
- case CT_LineEdit:
- case CT_ComboBox:
- {
- XPThemeData buttontheme(widget, 0, QLatin1String("Button"));
- HTHEME theme = buttontheme.handle();
- MARGINS borderSize;
- if (theme) {
- int result = pGetThemeMargins(theme,
- NULL,
- BP_PUSHBUTTON,
- PBS_NORMAL,
- TMT_CONTENTMARGINS,
- NULL,
- &borderSize);
- if (result == S_OK) {
- sz += QSize(borderSize.cxLeftWidth + borderSize.cxRightWidth - 2,
- borderSize.cyBottomHeight + borderSize.cyTopHeight - 2);
- }
- const int textMargins = 2*(proxy()->pixelMetric(PM_FocusFrameHMargin) + 1);
- sz += QSize(qMax(pixelMetric(QStyle::PM_ScrollBarExtent, option, widget)
- + textMargins, 23), 0); //arrow button
- }
- }
- break;
- case CT_SpinBox:
- {
- //Spinbox adds frame twice
- sz = QWindowsStyle::sizeFromContents(ct, option, contentsSize, widget);
- int border = proxy()->pixelMetric(PM_SpinBoxFrameWidth, option, widget);
- sz -= QSize(2*border, 2*border);
- }
- break;
- case CT_TabWidget:
- sz += QSize(6, 6);
- break;
- case CT_Menu:
- sz += QSize(1, 0);
- break;
-#ifndef QT_NO_MENUBAR
- case CT_MenuBarItem:
- if (!sz.isEmpty())
- sz += QSize(windowsItemHMargin * 5 + 1, 6);
- break;
-#endif
- case CT_MenuItem:
- if (const QStyleOptionMenuItem *menuitem = qstyleoption_cast<const QStyleOptionMenuItem *>(option))
- {
- if (menuitem->menuItemType != QStyleOptionMenuItem::Separator) {
- sz = QWindowsStyle::sizeFromContents(ct, option, sz, widget);
- sz.setHeight(sz.height() - 2);
- return sz;
- }
- }
- sz = QWindowsStyle::sizeFromContents(ct, option, sz, widget);
- break;
-
- case CT_MdiControls:
- if (const QStyleOptionComplex *styleOpt = qstyleoption_cast<const QStyleOptionComplex *>(option)) {
- int width = 0;
- if (styleOpt->subControls & SC_MdiMinButton)
- width += 17 + 1;
- if (styleOpt->subControls & SC_MdiNormalButton)
- width += 17 + 1;
- if (styleOpt->subControls & SC_MdiCloseButton)
- width += 17 + 1;
- sz = QSize(width, 19);
- } else {
- sz = QSize(54, 19);
- }
- break;
-
- default:
- sz = QWindowsStyle::sizeFromContents(ct, option, sz, widget);
- break;
- }
-
- return sz;
-}
-
-
-/*! \reimp */
-int QWindowsXPStyle::styleHint(StyleHint hint, const QStyleOption *option, const QWidget *widget,
- QStyleHintReturn *returnData) const
-{
- QWindowsXPStylePrivate *d = const_cast<QWindowsXPStylePrivate*>(d_func());
- if (!QWindowsXPStylePrivate::useXP())
- return QWindowsStyle::styleHint(hint, option, widget, returnData);
-
- int res = 0;
- switch (hint) {
-
- case SH_EtchDisabledText:
- res = (qobject_cast<const QLabel*>(widget) != 0);
- break;
-
- case SH_SpinControls_DisableOnBounds:
- res = 0;
- break;
-
- case SH_TitleBar_AutoRaise:
- case SH_TitleBar_NoBorder:
- res = 1;
- break;
-
- case SH_GroupBox_TextLabelColor:
- if (!widget || (widget && widget->isEnabled()))
- res = d->groupBoxTextColor;
- else
- res = d->groupBoxTextColorDisabled;
- break;
-
- case SH_Table_GridLineColor:
- res = 0xC0C0C0;
- break;
-
- case SH_WindowFrame_Mask:
- {
- res = 1;
- QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask *>(returnData);
- const QStyleOptionTitleBar *titlebar = qstyleoption_cast<const QStyleOptionTitleBar *>(option);
- if (mask && titlebar) {
- // Note certain themes will not return the whole window frame but only the titlebar part when
- // queried This function needs to return the entire window mask, hence we will only fetch the mask for the
- // titlebar itself and add the remaining part of the window rect at the bottom.
- int tbHeight = proxy()->pixelMetric(PM_TitleBarHeight, option, widget);
- QRect titleBarRect = option->rect;
- titleBarRect.setHeight(tbHeight);
- XPThemeData themeData;
- if (titlebar->titleBarState & Qt::WindowMinimized) {
- themeData = XPThemeData(widget, 0, QLatin1String("WINDOW"), WP_MINCAPTION, CS_ACTIVE, titleBarRect);
- } else
- themeData = XPThemeData(widget, 0, QLatin1String("WINDOW"), WP_CAPTION, CS_ACTIVE, titleBarRect);
- mask->region = d->region(themeData) +
- QRect(0, tbHeight, option->rect.width(), option->rect.height() - tbHeight);
- }
- }
- break;
-#ifndef QT_NO_RUBBERBAND
- case SH_RubberBand_Mask:
- if (qstyleoption_cast<const QStyleOptionRubberBand *>(option)) {
- res = 0;
- break;
- }
-#endif // QT_NO_RUBBERBAND
-
- case SH_ItemView_DrawDelegateFrame:
- res = 1;
- break;
-
- default:
- res =QWindowsStyle::styleHint(hint, option, widget, returnData);
- }
-
- return res;
-}
-
-/*! \reimp */
-QPalette QWindowsXPStyle::standardPalette() const
-{
- if (QWindowsXPStylePrivate::useXP() && QApplicationPrivate::sys_pal)
- return *QApplicationPrivate::sys_pal;
- else
- return QWindowsStyle::standardPalette();
-}
-
-/*!
- \reimp
-*/
-QPixmap QWindowsXPStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *option,
- const QWidget *widget) const
-{
- if (!QWindowsXPStylePrivate::useXP())
- return QWindowsStyle::standardPixmap(standardPixmap, option, widget);
-
- switch(standardPixmap) {
- case SP_TitleBarMaxButton:
- case SP_TitleBarCloseButton:
- if (qstyleoption_cast<const QStyleOptionDockWidget *>(option))
- {
- if (widget && widget->isWindow()) {
- XPThemeData theme(widget, 0, QLatin1String("WINDOW"), WP_SMALLCLOSEBUTTON, CBS_NORMAL);
- if (theme.isValid()) {
- SIZE sz;
- pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &sz);
- return QIcon(QWindowsStyle::standardPixmap(standardPixmap, option, widget)).pixmap(QSize(sz.cx, sz.cy));
- }
- }
- }
- break;
- default:
- break;
- }
- return QWindowsStyle::standardPixmap(standardPixmap, option, widget);
-}
-
-/*!
- \internal
-*/
-QIcon QWindowsXPStyle::standardIconImplementation(StandardPixmap standardIcon,
- const QStyleOption *option,
- const QWidget *widget) const
-{
- if (!QWindowsXPStylePrivate::useXP()) {
- return QWindowsStyle::standardIconImplementation(standardIcon, option, widget);
- }
-
- QWindowsXPStylePrivate *d = const_cast<QWindowsXPStylePrivate*>(d_func());
- switch(standardIcon) {
- case SP_TitleBarMaxButton:
- if (qstyleoption_cast<const QStyleOptionDockWidget *>(option))
- {
- if (d->dockFloat.isNull()) {
- XPThemeData themeSize(0, 0, QLatin1String("WINDOW"), WP_SMALLCLOSEBUTTON, CBS_NORMAL);
- XPThemeData theme(0, 0, QLatin1String("WINDOW"), WP_MAXBUTTON, MAXBS_NORMAL);
- if (theme.isValid()) {
- SIZE size;
- pGetThemePartSize(themeSize.handle(), 0, themeSize.partId, themeSize.stateId, 0, TS_TRUE, &size);
- QPixmap pm = QPixmap(size.cx, size.cy);
- pm.fill(Qt::transparent);
- QPainter p(&pm);
- theme.painter = &p;
- theme.rect = QRect(0, 0, size.cx, size.cy);
- d->drawBackground(theme);
- d->dockFloat.addPixmap(pm, QIcon::Normal, QIcon::Off); // Normal
- pm.fill(Qt::transparent);
- theme.stateId = MAXBS_PUSHED;
- d->drawBackground(theme);
- d->dockFloat.addPixmap(pm, QIcon::Normal, QIcon::On); // Pressed
- pm.fill(Qt::transparent);
- theme.stateId = MAXBS_HOT;
- d->drawBackground(theme);
- d->dockFloat.addPixmap(pm, QIcon::Active, QIcon::Off); // Hover
- pm.fill(Qt::transparent);
- theme.stateId = MAXBS_INACTIVE;
- d->drawBackground(theme);
- d->dockFloat.addPixmap(pm, QIcon::Disabled, QIcon::Off); // Disabled
- }
- }
- if (widget && widget->isWindow())
- return d->dockFloat;
-
- }
- break;
- case SP_TitleBarCloseButton:
- if (qstyleoption_cast<const QStyleOptionDockWidget *>(option))
- {
- if (d->dockClose.isNull()) {
- XPThemeData theme(0, 0, QLatin1String("WINDOW"), WP_SMALLCLOSEBUTTON, CBS_NORMAL);
- if (theme.isValid()) {
- SIZE size;
- pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
- QPixmap pm = QPixmap(size.cx, size.cy);
- pm.fill(Qt::transparent);
- QPainter p(&pm);
- theme.painter = &p;
- theme.partId = WP_CLOSEBUTTON; // ####
- theme.rect = QRect(0, 0, size.cx, size.cy);
- d->drawBackground(theme);
- d->dockClose.addPixmap(pm, QIcon::Normal, QIcon::Off); // Normal
- pm.fill(Qt::transparent);
- theme.stateId = CBS_PUSHED;
- d->drawBackground(theme);
- d->dockClose.addPixmap(pm, QIcon::Normal, QIcon::On); // Pressed
- pm.fill(Qt::transparent);
- theme.stateId = CBS_HOT;
- d->drawBackground(theme);
- d->dockClose.addPixmap(pm, QIcon::Active, QIcon::Off); // Hover
- pm.fill(Qt::transparent);
- theme.stateId = CBS_INACTIVE;
- d->drawBackground(theme);
- d->dockClose.addPixmap(pm, QIcon::Disabled, QIcon::Off); // Disabled
- }
- }
- if (widget && widget->isWindow())
- return d->dockClose;
- }
- break;
- case SP_TitleBarNormalButton:
- if (qstyleoption_cast<const QStyleOptionDockWidget *>(option))
- {
- if (d->dockFloat.isNull()) {
- XPThemeData themeSize(0, 0, QLatin1String("WINDOW"), WP_SMALLCLOSEBUTTON, CBS_NORMAL);
- XPThemeData theme(0, 0, QLatin1String("WINDOW"), WP_RESTOREBUTTON, RBS_NORMAL);
- if (theme.isValid()) {
- SIZE size;
- pGetThemePartSize(themeSize.handle(), 0, themeSize.partId, themeSize.stateId, 0, TS_TRUE, &size);
- QPixmap pm = QPixmap(size.cx, size.cy);
- pm.fill(Qt::transparent);
- QPainter p(&pm);
- theme.painter = &p;
- theme.rect = QRect(0, 0, size.cx, size.cy);
- d->drawBackground(theme);
- d->dockFloat.addPixmap(pm, QIcon::Normal, QIcon::Off); // Normal
- pm.fill(Qt::transparent);
- theme.stateId = RBS_PUSHED;
- d->drawBackground(theme);
- d->dockFloat.addPixmap(pm, QIcon::Normal, QIcon::On); // Pressed
- pm.fill(Qt::transparent);
- theme.stateId = RBS_HOT;
- d->drawBackground(theme);
- d->dockFloat.addPixmap(pm, QIcon::Active, QIcon::Off); // Hover
- pm.fill(Qt::transparent);
- theme.stateId = RBS_INACTIVE;
- d->drawBackground(theme);
- d->dockFloat.addPixmap(pm, QIcon::Disabled, QIcon::Off); // Disabled
- }
- }
- if (widget && widget->isWindow())
- return d->dockFloat;
-
- }
- break;
- default:
- break;
- }
-
- return QWindowsStyle::standardIconImplementation(standardIcon, option, widget);
-}
-
-/*!
- \internal
-
- Constructs a QWindowsXPStyle object.
-*/
-QWindowsXPStyle::QWindowsXPStyle(QWindowsXPStylePrivate &dd) : QWindowsStyle(dd)
-{
-}
-
-
-// Debugging code ---------------------------------------------------------------------[ START ]---
-// The code for this point on is not compiled by default, but only used as assisting
-// debugging code when you uncomment the DEBUG_XP_STYLE define at the top of the file.
-
-#ifdef DEBUG_XP_STYLE
-// The schema file expects these to be defined by the user.
-#define TMT_ENUMDEF 8
-#define TMT_ENUMVAL TEXT('A')
-#define TMT_ENUM TEXT('B')
-#define SCHEMA_STRINGS // For 2nd pass on schema file
-QT_BEGIN_INCLUDE_NAMESPACE
-#include <tmschema.h>
-QT_END_INCLUDE_NAMESPACE
-
-// A property's value, type and name combo
-struct PropPair {
- int propValue;
- int propType;
- LPCWSTR propName;
-};
-
-// Operator for sorting of PropPairs
-bool operator<(PropPair a, PropPair b) {
- return wcscmp(a.propName, b.propName) < 0;
-}
-
-// Our list of all possible properties
-static QList<PropPair> all_props;
-
-
-/*! \internal
- Dumps a portion of the full native DIB section double buffer.
- The DIB section double buffer is only used when doing special
- transformations to the theme part, or when the real double
- buffer in the paintengine does not have an HDC we may use
- directly.
- Since we cannot rely on the pixel data we get from Microsoft
- when drawing into the DIB section, we use this function to
- see the actual data we got, and can determin the appropriate
- action.
-*/
-void QWindowsXPStylePrivate::dumpNativeDIB(int w, int h)
-{
- if (w && h) {
- static int pCount = 0;
- DWORD *bufPix = (DWORD*)bufferPixels;
-
- char *bufferDump = new char[bufferH * bufferW * 16];
- char *bufferPos = bufferDump;
-
- memset(bufferDump, 0, sizeof(bufferDump));
- bufferPos += sprintf(bufferPos, "const int pixelBufferW%d = %d;\n", pCount, w);
- bufferPos += sprintf(bufferPos, "const int pixelBufferH%d = %d;\n", pCount, h);
- bufferPos += sprintf(bufferPos, "const unsigned DWORD pixelBuffer%d[] = {", pCount);
- for (int iy = 0; iy < h; ++iy) {
- bufferPos += sprintf(bufferPos, "\n ");
- bufPix = (DWORD*)(bufferPixels + (iy * bufferW * 4));
- for (int ix = 0; ix < w; ++ix) {
- bufferPos += sprintf(bufferPos, "0x%08x, ", *bufPix);
- ++bufPix;
- }
- }
- bufferPos += sprintf(bufferPos, "\n};\n\n");
- printf(bufferDump);
-
- delete[] bufferDump;
- ++pCount;
- }
-}
-
-/*! \internal
- Shows the value of a given property for a part.
-*/
-static void showProperty(XPThemeData &themeData, const PropPair &prop)
-{
- PROPERTYORIGIN origin = PO_NOTFOUND;
- pGetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &origin);
- const char *originStr;
- switch(origin) {
- case PO_STATE:
- originStr = "State ";
- break;
- case PO_PART:
- originStr = "Part ";
- break;
- case PO_CLASS:
- originStr = "Class ";
- break;
- case PO_GLOBAL:
- originStr = "Globl ";
- break;
- case PO_NOTFOUND:
- default:
- originStr = "Unkwn ";
- break;
- }
-
- switch(prop.propType) {
- case TMT_STRING:
- {
- wchar_t buffer[512];
- pGetThemeString(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, buffer, 512);
- printf(" (%sString) %-20S: %S\n", originStr, prop.propName, buffer);
- }
- break;
- case TMT_ENUM:
- {
- int result = -1;
- pGetThemeEnumValue(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &result);
- printf(" (%sEnum) %-20S: %d\n", originStr, prop.propName, result);
- }
- break;
- case TMT_INT:
- {
- int result = -1;
- pGetThemeInt(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &result);
- printf(" (%sint) %-20S: %d\n", originStr, prop.propName, result);
- }
- break;
- case TMT_BOOL:
- {
- BOOL result = false;
- pGetThemeBool(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &result);
- printf(" (%sbool) %-20S: %d\n", originStr, prop.propName, result);
- }
- break;
- case TMT_COLOR:
- {
- COLORREF result = 0;
- pGetThemeColor(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &result);
- printf(" (%scolor) %-20S: 0x%08X\n", originStr, prop.propName, result);
- }
- break;
- case TMT_MARGINS:
- {
- MARGINS result;
- memset(&result, 0, sizeof(result));
- pGetThemeMargins(themeData.handle(), 0, themeData.partId, themeData.stateId, prop.propValue, 0, &result);
- printf(" (%smargins) %-20S: (%d, %d, %d, %d)\n", originStr,
- prop.propName, result.cxLeftWidth, result.cyTopHeight, result.cxRightWidth, result.cyBottomHeight);
- }
- break;
- case TMT_FILENAME:
- {
- wchar_t buffer[512];
- pGetThemeFilename(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, buffer, 512);
- printf(" (%sfilename)%-20S: %S\n", originStr, prop.propName, buffer);
- }
- break;
- case TMT_SIZE:
- {
- SIZE result1;
- SIZE result2;
- SIZE result3;
- memset(&result1, 0, sizeof(result1));
- memset(&result2, 0, sizeof(result2));
- memset(&result3, 0, sizeof(result3));
- pGetThemePartSize(themeData.handle(), 0, themeData.partId, themeData.stateId, 0, TS_MIN, &result1);
- pGetThemePartSize(themeData.handle(), 0, themeData.partId, themeData.stateId, 0, TS_TRUE, &result2);
- pGetThemePartSize(themeData.handle(), 0, themeData.partId, themeData.stateId, 0, TS_DRAW, &result3);
- printf(" (%ssize) %-20S: Min (%d, %d), True(%d, %d), Draw(%d, %d)\n", originStr, prop.propName,
- result1.cx, result1.cy, result2.cx, result2.cy, result3.cx, result3.cy);
- }
- break;
- case TMT_POSITION:
- {
- POINT result;
- memset(&result, 0, sizeof(result));
- pGetThemePosition(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &result);
- printf(" (%sPosition)%-20S: (%d, %d)\n", originStr, prop.propName, result.x, result.y);
- }
- break;
- case TMT_RECT:
- {
- RECT result;
- memset(&result, 0, sizeof(result));
- pGetThemeRect(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &result);
- printf(" (%sRect) %-20S: (%d, %d, %d, %d)\n", originStr, prop.propName, result.left, result.top, result.right, result.bottom);
- }
- break;
- case TMT_FONT:
- {
- LOGFONT result;
- memset(&result, 0, sizeof(result));
- pGetThemeFont(themeData.handle(), 0, themeData.partId, themeData.stateId, prop.propValue, &result);
- printf(" (%sFont) %-20S: %S height(%d) width(%d) weight(%d)\n", originStr, prop.propName,
- result.lfFaceName, result.lfHeight, result.lfWidth, result.lfWeight);
- }
- break;
- case TMT_INTLIST:
- {
- INTLIST result;
- memset(&result, 0, sizeof(result));
- pGetThemeIntList(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &result);
- printf(" (%sInt list)%-20S: { ", originStr, prop.propName);
- for (int i = 0; i < result.iValueCount; ++i)
- printf("%d ", result.iValues[i]);
- printf("}\n");
- }
- break;
- default:
- printf(" %s%S : Unknown property type (%d)!\n", originStr, prop.propName, prop.propType);
- }
-}
-
-/*! \internal
- Dump all valid properties for a part.
- If it's the first time this function is called, then the name,
- enum value and documentation of all properties are shown, as
- well as all global properties.
-*/
-void QWindowsXPStylePrivate::showProperties(XPThemeData &themeData)
-{
- if (!all_props.count()) {
- const TMSCHEMAINFO *infoTable = GetSchemaInfo();
- for (int i = 0; i < infoTable->iPropCount; ++i) {
- int propType = infoTable->pPropTable[i].bPrimVal;
- int propValue = infoTable->pPropTable[i].sEnumVal;
- LPCWSTR propName = infoTable->pPropTable[i].pszName;
-
- switch(propType) {
- case TMT_ENUMDEF:
- case TMT_ENUMVAL:
- continue;
- default:
- if (propType != propValue) {
- PropPair prop;
- prop.propValue = propValue;
- prop.propName = propName;
- prop.propType = propType;
- all_props.append(prop);
- }
- }
- }
- qSort(all_props);
-
- {// List all properties
- printf("part properties count = %d:\n", all_props.count());
- printf(" Enum Property Name Description\n");
- printf("-----------------------------------------------------------\n");
- wchar_t themeName[256];
- pGetCurrentThemeName(themeName, 256, 0, 0, 0, 0);
- for (int j = 0; j < all_props.count(); ++j) {
- PropPair prop = all_props.at(j);
- wchar_t buf[500];
- pGetThemeDocumentationProperty(themeName, prop.propName, buf, 500);
- printf("%3d: (%4d) %-20S %S\n", j, prop.propValue, prop.propName, buf);
- }
- }
-
- {// Show Global values
- printf("Global Properties:\n");
- for (int j = 0; j < all_props.count(); ++j) {
- PropPair prop = all_props.at(j);
- PROPERTYORIGIN origin = PO_NOTFOUND;
- pGetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &origin);
- if (origin == PO_GLOBAL) {
- showProperty(themeData, prop);
- }
- }
- }
- }
-
- for (int j = 0; j < all_props.count(); ++j) {
- PropPair prop = all_props.at(j);
- PROPERTYORIGIN origin = PO_NOTFOUND;
- pGetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &origin);
- if (origin != PO_NOTFOUND)
- {
- showProperty(themeData, prop);
- }
- }
-}
-#endif
-// Debugging code -----------------------------------------------------------------------[ END ]---
-
-
-QT_END_NAMESPACE
-
-#endif //QT_NO_WINDOWSXP
diff --git a/src/gui/styles/qwindowsxpstyle.h b/src/gui/styles/qwindowsxpstyle.h
deleted file mode 100644
index 71a2e1233d..0000000000
--- a/src/gui/styles/qwindowsxpstyle.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWINDOWSXPSTYLE_H
-#define QWINDOWSXPSTYLE_H
-
-#include <QtGui/qwindowsstyle.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#if !defined(QT_NO_STYLE_WINDOWSXP)
-
-class QWindowsXPStylePrivate;
-class Q_GUI_EXPORT QWindowsXPStyle : public QWindowsStyle
-{
- Q_OBJECT
-public:
- QWindowsXPStyle();
- QWindowsXPStyle(QWindowsXPStylePrivate &dd);
- ~QWindowsXPStyle();
-
- void unpolish(QApplication*);
- void polish(QApplication*);
- void polish(QWidget*);
- void polish(QPalette&);
- void unpolish(QWidget*);
-
- void drawPrimitive(PrimitiveElement pe, const QStyleOption *option, QPainter *p,
- const QWidget *widget = 0) const;
- void drawControl(ControlElement element, const QStyleOption *option, QPainter *p,
- const QWidget *wwidget = 0) const;
- QRect subElementRect(SubElement r, const QStyleOption *option, const QWidget *widget = 0) const;
- QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *option, SubControl sc,
- const QWidget *widget = 0) const;
- void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *option, QPainter *p,
- const QWidget *widget = 0) const;
- QSize sizeFromContents(ContentsType ct, const QStyleOption *option, const QSize &contentsSize,
- const QWidget *widget = 0) const;
- int pixelMetric(PixelMetric pm, const QStyleOption *option = 0,
- const QWidget *widget = 0) const;
- int styleHint(StyleHint hint, const QStyleOption *option = 0, const QWidget *widget = 0,
- QStyleHintReturn *returnData = 0) const;
-
- QPalette standardPalette() const;
- QPixmap standardPixmap(StandardPixmap standardIcon, const QStyleOption *option,
- const QWidget *widget = 0) const;
-
-protected Q_SLOTS:
- QIcon standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *option,
- const QWidget *widget = 0) const;
-
-private:
- Q_DISABLE_COPY(QWindowsXPStyle)
- Q_DECLARE_PRIVATE(QWindowsXPStyle)
- friend class QStyleFactory;
- void *reserved;
-};
-
-#endif // QT_NO_STYLE_WINDOWSXP
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QWINDOWSXPSTYLE_H
diff --git a/src/gui/styles/qwindowsxpstyle_p.h b/src/gui/styles/qwindowsxpstyle_p.h
deleted file mode 100644
index 73803607a1..0000000000
--- a/src/gui/styles/qwindowsxpstyle_p.h
+++ /dev/null
@@ -1,356 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWINDOWSXPSTYLE_P_H
-#define QWINDOWSXPSTYLE_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header
-// file may change from version to version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qwindowsxpstyle.h"
-#include "qwindowsstyle_p.h"
-#include <qmap.h>
-#include <qt_windows.h>
-
-// Note, these tests are duplicated in qwizard_win.cpp.
-#ifdef Q_CC_GNU
-# include <w32api.h>
-# if (__W32API_MAJOR_VERSION >= 3 || (__W32API_MAJOR_VERSION == 2 && __W32API_MINOR_VERSION >= 5))
-# ifdef _WIN32_WINNT
-# undef _WIN32_WINNT
-# endif
-# define _WIN32_WINNT 0x0501
-# include <commctrl.h>
-# endif
-#endif
-
-#include <uxtheme.h>
-
-#if WINVER >= 0x0600
-#include <vssym32.h>
-#else
-#include <tmschema.h>
-#endif
-
-#include <limits.h>
-
-QT_BEGIN_NAMESPACE
-
-// Older Platform SDKs do not have the extended DrawThemeBackgroundEx
-// function. We add the needed parts here, and use the extended
-// function dynamically, if available in uxtheme.dll. Else, we revert
-// back to using the DrawThemeBackground function.
-#ifndef DTBG_OMITBORDER
-# ifndef DTBG_CLIPRECT
-# define DTBG_CLIPRECT 0x00000001
-# endif
-# ifndef DTBG_DRAWSOLID
-# define DTBG_DRAWSOLID 0x00000002
-# endif
-# ifndef DTBG_OMITBORDER
-# define DTBG_OMITBORDER 0x00000004
-# endif
-# ifndef DTBG_OMITCONTENT
-# define DTBG_OMITCONTENT 0x00000008
-# endif
-# ifndef DTBG_COMPUTINGREGION
-# define DTBG_COMPUTINGREGION 0x00000010
-# endif
-# ifndef DTBG_MIRRORDC
-# define DTBG_MIRRORDC 0x00000020
-# endif
- typedef struct _DTBGOPTS
- {
- DWORD dwSize;
- DWORD dwFlags;
- RECT rcClip;
- } DTBGOPTS, *PDTBGOPTS;
-#endif // _DTBGOPTS
-
-// Undefined for some compile environments
-#ifndef TMT_TEXTCOLOR
-# define TMT_TEXTCOLOR 3803
-#endif
-#ifndef TMT_BORDERCOLORHINT
-# define TMT_BORDERCOLORHINT 3822
-#endif
-#ifndef TMT_BORDERSIZE
-# define TMT_BORDERSIZE 2403
-#endif
-#ifndef TMT_BORDERONLY
-# define TMT_BORDERONLY 2203
-#endif
-#ifndef TMT_TRANSPARENTCOLOR
-# define TMT_TRANSPARENTCOLOR 3809
-#endif
-#ifndef TMT_CAPTIONMARGINS
-# define TMT_CAPTIONMARGINS 3603
-#endif
-#ifndef TMT_CONTENTMARGINS
-# define TMT_CONTENTMARGINS 3602
-#endif
-#ifndef TMT_SIZINGMARGINS
-# define TMT_SIZINGMARGINS 3601
-#endif
-#ifndef TMT_GLYPHTYPE
-# define TMT_GLYPHTYPE 4012
-#endif
-#ifndef TMT_BGTYPE
-# define TMT_BGTYPE 4001
-#endif
-#ifndef TMT_TEXTSHADOWTYPE
-# define TMT_TEXTSHADOWTYPE 4010
-#endif
-#ifndef TMT_BORDERCOLOR
-# define TMT_BORDERCOLOR 3801
-#endif
-#ifndef BT_IMAGEFILE
-# define BT_IMAGEFILE 0
-#endif
-#ifndef BT_BORDERFILL
-# define BT_BORDERFILL 1
-#endif
-#ifndef BT_NONE
-# define BT_NONE 2
-#endif
-#ifndef TMT_FILLCOLOR
-# define TMT_FILLCOLOR 3802
-#endif
-#ifndef TMT_PROGRESSCHUNKSIZE
-# define TMT_PROGRESSCHUNKSIZE 2411
-#endif
-
-// TMT_TEXTSHADOWCOLOR is wrongly defined in mingw
-#if TMT_TEXTSHADOWCOLOR != 3818
-#undef TMT_TEXTSHADOWCOLOR
-#define TMT_TEXTSHADOWCOLOR 3818
-#endif
-#ifndef TST_NONE
-# define TST_NONE 0
-#endif
-
-#ifndef GT_NONE
-# define GT_NONE 0
-#endif
-#ifndef GT_IMAGEGLYPH
-# define GT_IMAGEGLYPH 1
-#endif
-
-// These defines are missing from the tmschema, but still exist as
-// states for their parts
-#ifndef MINBS_INACTIVE
-#define MINBS_INACTIVE 5
-#endif
-#ifndef MAXBS_INACTIVE
-#define MAXBS_INACTIVE 5
-#endif
-#ifndef RBS_INACTIVE
-#define RBS_INACTIVE 5
-#endif
-#ifndef HBS_INACTIVE
-#define HBS_INACTIVE 5
-#endif
-#ifndef CBS_INACTIVE
-#define CBS_INACTIVE 5
-#endif
-
-// Uncomment define below to build debug assisting code, and output
-// #define DEBUG_XP_STYLE
-
-#if !defined(QT_NO_STYLE_WINDOWSXP)
-
-// Declarations -----------------------------------------------------------------------------------
-class XPThemeData
-{
-public:
- XPThemeData(const QWidget *w = 0, QPainter *p = 0, const QString &theme = QString(),
- int part = 0, int state = 0, const QRect &r = QRect())
- : widget(w), painter(p), name(theme), htheme(0), partId(part), stateId(state),
- mirrorHorizontally(false), mirrorVertically(false), noBorder(false),
- noContent(false), rotate(0), rect(r)
- {}
-
- HRGN mask();
- HTHEME handle();
-
- RECT toRECT(const QRect &qr);
- bool isValid();
-
- const QWidget *widget;
- QPainter *painter;
- QString name;
- HTHEME htheme;
- int partId;
- int stateId;
-
- uint mirrorHorizontally : 1;
- uint mirrorVertically : 1;
- uint noBorder : 1;
- uint noContent : 1;
- uint rotate;
- QRect rect;
-};
-
-struct ThemeMapKey {
- QString name;
- int partId;
- int stateId;
- bool noBorder;
- bool noContent;
-
- ThemeMapKey() : partId(-1), stateId(-1) {}
- ThemeMapKey(const XPThemeData &data)
- : name(data.name), partId(data.partId), stateId(data.stateId),
- noBorder(data.noBorder), noContent(data.noContent) {}
-
-};
-
-inline uint qHash(const ThemeMapKey &key)
-{ return qHash(key.name) ^ key.partId ^ key.stateId; }
-
-inline bool operator==(const ThemeMapKey &k1, const ThemeMapKey &k2)
-{
- return k1.name == k2.name
- && k1.partId == k2.partId
- && k1.stateId == k2.stateId;
-}
-
-enum AlphaChannelType {
- UnknownAlpha = -1, // Alpha of part & state not yet known
- NoAlpha, // Totally opaque, no need to touch alpha (RGB)
- MaskAlpha, // Alpha channel must be fixed (ARGB)
- RealAlpha // Proper alpha values from Windows (ARGB_Premultiplied)
-};
-
-struct ThemeMapData {
- AlphaChannelType alphaType; // Which type of alpha on part & state
-
- bool dataValid : 1; // Only used to detect if hash value is ok
- bool partIsTransparent : 1;
- bool hasAnyData : 1; // False = part & state has not data, NOP
- bool hasAlphaChannel : 1; // True = part & state has real Alpha
- bool wasAlphaSwapped : 1; // True = alpha channel needs to be swapped
- bool hadInvalidAlpha : 1; // True = alpha channel contained invalid alpha values
-
- ThemeMapData() : dataValid(false), partIsTransparent(false), hasAnyData(false),
- hasAlphaChannel(false), wasAlphaSwapped(false), hadInvalidAlpha(false) {}
-};
-
-class QWindowsXPStylePrivate : public QWindowsStylePrivate
-{
- Q_DECLARE_PUBLIC(QWindowsXPStyle)
-public:
- QWindowsXPStylePrivate()
- : QWindowsStylePrivate(), hasInitColors(false), bufferDC(0), bufferBitmap(0), nullBitmap(0),
- bufferPixels(0), bufferW(0), bufferH(0)
- { init(); }
-
- ~QWindowsXPStylePrivate()
- { cleanup(); }
-
- static HWND winId(const QWidget *widget);
-
- void init(bool force = false);
- void cleanup(bool force = false);
- void cleanupHandleMap();
- const QPixmap *tabBody(QWidget *widget);
-
- HBITMAP buffer(int w = 0, int h = 0);
- HDC bufferHDC()
- { return bufferDC;}
-
- static bool resolveSymbols();
- static bool useXP(bool update = false);
-
- bool isTransparent(XPThemeData &themeData);
- QRegion region(XPThemeData &themeData);
-
- void setTransparency(QWidget *widget, XPThemeData &themeData);
- void drawBackground(XPThemeData &themeData);
- void drawBackgroundThruNativeBuffer(XPThemeData &themeData);
- void drawBackgroundDirectly(XPThemeData &themeData);
-
- bool hasAnyData(const QRect &rect);
- bool hasAlphaChannel(const QRect &rect);
- bool fixAlphaChannel(const QRect &rect);
- bool swapAlphaChannel(const QRect &rect, bool allPixels = false);
-
- QRgb groupBoxTextColor;
- QRgb groupBoxTextColorDisabled;
- QRgb sliderTickColor;
- bool hasInitColors;
-
- static QMap<QString,HTHEME> *handleMap;
-
- QIcon dockFloat, dockClose;
-
-private:
-#ifdef DEBUG_XP_STYLE
- void dumpNativeDIB(int w, int h);
- void showProperties(XPThemeData &themeData);
-#endif
-
- static QBasicAtomicInt ref;
- static bool use_xp;
- static QWidget *limboWidget;
- static QPixmap *tabbody;
-
- QHash<ThemeMapKey, ThemeMapData> alphaCache;
- HDC bufferDC;
- HBITMAP bufferBitmap;
- HBITMAP nullBitmap;
- uchar *bufferPixels;
- int bufferW, bufferH;
-};
-
-#endif // QT_NO_STYLE_WINDOWS
-
-QT_END_NAMESPACE
-
-#endif //QWINDOWSXPSTYLE_P_H
diff --git a/src/gui/styles/styles.pri b/src/gui/styles/styles.pri
deleted file mode 100644
index b6eeec9af8..0000000000
--- a/src/gui/styles/styles.pri
+++ /dev/null
@@ -1,190 +0,0 @@
-# Qt styles module
-
-HEADERS += \
- styles/qstyle.h \
- styles/qstylefactory.h \
- styles/qstyleoption.h \
- styles/qstyleplugin.h \
- styles/qcommonstylepixmaps_p.h \
- styles/qcommonstyle.h \
- styles/qstylehelper_p.h \
- styles/qproxystyle.h \
- styles/qproxystyle_p.h \
- styles/qstylesheetstyle_p.h
-
-SOURCES += \
- styles/qstyle.cpp \
- styles/qstylefactory.cpp \
- styles/qstyleoption.cpp \
- styles/qstyleplugin.cpp \
- styles/qstylehelper.cpp \
- styles/qcommonstyle.cpp \
- styles/qproxystyle.cpp \
- styles/qstylesheetstyle.cpp \
- styles/qstylesheetstyle_default.cpp
-
-wince* {
- RESOURCES += styles/qstyle_wince.qrc
-} else:symbian {
- RESOURCES += styles/qstyle_s60.qrc
-} else {
- RESOURCES += styles/qstyle.qrc
-}
-
-contains( styles, all ) {
- styles = mac windows windowsxp windowsvista
-}
-
-x11|embedded|qpa|!macx-*:styles -= mac
-
-x11{
- QMAKE_CXXFLAGS += $$QT_CFLAGS_QGTKSTYLE
- LIBS_PRIVATE += $$QT_LIBS_QGTKSTYLE
- styles += gtk
-}
-
-contains( styles, mac ) {
- HEADERS += \
- styles/qmacstyle_mac.h \
- styles/qmacstylepixmaps_mac_p.h \
- styles/qmacstyle_mac_p.h
- OBJECTIVE_SOURCES += styles/qmacstyle_mac.mm
-
- !contains( styles, windows ) {
- message( mac requires windows )
- styles += windows
- DEFINES+= QT_STYLE_WINDOWS
- }
-} else {
- DEFINES += QT_NO_STYLE_MAC
-}
-
-contains( styles, cde ) {
- HEADERS += styles/qcdestyle.h
- SOURCES += styles/qcdestyle.cpp
-
- !contains( styles, motif ) {
- message( cde requires motif )
- styles += motif
- DEFINES+= QT_STYLE_MOTIF
- }
-} else {
- DEFINES += QT_NO_STYLE_CDE
-}
-
-contains( styles, windowsvista ) {
- HEADERS += styles/qwindowsvistastyle.h
- HEADERS += styles/qwindowsvistastyle_p.h
- SOURCES += styles/qwindowsvistastyle.cpp
- !contains( styles, windowsxp ) {
- message( windowsvista requires windowsxp )
- styles += windowsxp
- DEFINES+= QT_STYLE_WINDOWSXP
- }
-} else {
- DEFINES += QT_NO_STYLE_WINDOWSVISTA
-}
-
-contains( styles, windowsxp ) {
- HEADERS += styles/qwindowsxpstyle.h
- SOURCES += styles/qwindowsxpstyle.cpp
- !contains( styles, windows ) {
- message( windowsxp requires windows )
- styles += windows
- DEFINES+= QT_STYLE_WINDOWS
- }
-} else {
- DEFINES += QT_NO_STYLE_WINDOWSXP
-}
-
-contains( styles, plastique ) {
- HEADERS += styles/qplastiquestyle.h
- SOURCES += styles/qplastiquestyle.cpp
- !contains( styles, windows ) {
- message( plastique requires windows )
- styles += windows
- DEFINES+= QT_STYLE_WINDOWS
- }
-} else {
- DEFINES += QT_NO_STYLE_PLASTIQUE
-}
-
-contains( styles, gtk ) {
- HEADERS += styles/qgtkstyle.h
- HEADERS += styles/qgtkpainter_p.h
- HEADERS += styles/qgtkstyle_p.h
- SOURCES += styles/qgtkstyle.cpp
- SOURCES += styles/qgtkpainter.cpp
- SOURCES += styles/qgtkstyle_p.cpp
- !contains( styles, cleanlooks ) {
- styles += cleanlooks
- DEFINES+= QT_STYLE_CLEANLOOKS
- }
-} else {
- DEFINES += QT_NO_STYLE_GTK
-}
-
-contains( styles, cleanlooks ) {
- HEADERS += styles/qcleanlooksstyle.h
- HEADERS += styles/qcleanlooksstyle_p.h
- SOURCES += styles/qcleanlooksstyle.cpp
- !contains( styles, windows ) {
- styles += windows
- DEFINES+= QT_STYLE_WINDOWS
- }
-} else {
- DEFINES += QT_NO_STYLE_CLEANLOOKS
-}
-
-contains( styles, windows ) {
- HEADERS += styles/qwindowsstyle.h
- SOURCES += styles/qwindowsstyle.cpp
-} else {
- DEFINES += QT_NO_STYLE_WINDOWS
-}
-
-contains( styles, motif ) {
- HEADERS += styles/qmotifstyle.h
- SOURCES += styles/qmotifstyle.cpp
-} else {
- DEFINES += QT_NO_STYLE_MOTIF
-}
-
-contains( styles, windowsce ) {
- HEADERS += styles/qwindowscestyle.h
- SOURCES += styles/qwindowscestyle.cpp
-} else {
- DEFINES += QT_NO_STYLE_WINDOWSCE
-}
-
-contains( styles, windowsmobile ) {
- HEADERS += styles/qwindowsmobilestyle.h
- SOURCES += styles/qwindowsmobilestyle.cpp
-} else {
- DEFINES += QT_NO_STYLE_WINDOWSMOBILE
-}
-
-contains( styles, s60 ):contains(QT_CONFIG, s60) {
- HEADERS += \
- styles/qs60style.h \
- styles/qs60style_p.h
- SOURCES += styles/qs60style.cpp
- symbian {
- SOURCES += styles/qs60style_s60.cpp
- LIBS += -legul -lbmpanim
- contains(CONFIG, is_using_gnupoc) {
- LIBS += -laknicon -laknskins -laknskinsrv -lfontutils
- } else {
- LIBS += -lAknIcon -lAKNSKINS -lAKNSKINSRV -lFontUtils
- }
- } else {
- SOURCES += styles/qs60style_simulated.cpp
- RESOURCES += styles/qstyle_s60_simulated.qrc
- }
-} else {
- symbian {
- HEADERS += styles/qs60style.h
- SOURCES += styles/qs60style_stub.cpp
- }
- DEFINES += QT_NO_STYLE_S60
-}
diff --git a/src/gui/symbian/qsymbianevent.h b/src/gui/symbian/qsymbianevent.h
deleted file mode 100644
index 6a7984ed0b..0000000000
--- a/src/gui/symbian/qsymbianevent.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSYMBIANEVENT_H
-#define QSYMBIANEVENT_H
-
-#include <QtCore/qglobal.h>
-
-#ifdef Q_OS_SYMBIAN
-
-class TWsEvent;
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class Q_GUI_EXPORT QSymbianEvent
-{
-public:
- enum Type {
- InvalidEvent,
- WindowServerEvent,
- CommandEvent,
- ResourceChangeEvent
- };
-
- QSymbianEvent(const TWsEvent *windowServerEvent);
- QSymbianEvent(Type eventType, int value);
- ~QSymbianEvent();
-
- Type type() const;
- bool isValid() const;
-
- const TWsEvent *windowServerEvent() const;
- int command() const;
- int resourceChangeType() const;
-
-private:
- Type m_type;
- union {
- const void *m_eventPtr;
- int m_eventValue;
-
- qint64 m_reserved;
- };
-};
-
-inline QSymbianEvent::Type QSymbianEvent::type() const
-{
- return m_type;
-}
-
-inline bool QSymbianEvent::isValid() const
-{
- return m_type != InvalidEvent;
-}
-
-#ifndef QT_NO_DEBUG_STREAM
-Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QSymbianEvent *o);
-#endif
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // Q_OS_SYMBIAN
-
-#endif // QSYMBIANEVENT_H
diff --git a/src/gui/text/qabstractfontengine_qws.cpp b/src/gui/text/qabstractfontengine_qws.cpp
deleted file mode 100644
index b2c9cc478a..0000000000
--- a/src/gui/text/qabstractfontengine_qws.cpp
+++ /dev/null
@@ -1,776 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qabstractfontengine_qws.h"
-#include "qabstractfontengine_p.h"
-
-#include <private/qtextengine_p.h>
-#include <private/qpaintengine_raster_p.h>
-
-#include <qmath.h>
-
-QT_BEGIN_NAMESPACE
-
-class QFontEngineInfoPrivate
-{
-public:
- inline QFontEngineInfoPrivate()
- : pixelSize(0), weight(QFont::Normal), style(QFont::StyleNormal)
- {}
-
- QString family;
- qreal pixelSize;
- int weight;
- QFont::Style style;
- QList<QFontDatabase::WritingSystem> writingSystems;
-};
-
-/*!
- \class QFontEngineInfo
- \preliminary
- \brief The QFontEngineInfo class describes a specific font provided by a font engine plugin.
- \since 4.3
- \ingroup qws
-
- \tableofcontents
-
- QFontEngineInfo is used to describe a request of a font to a font engine plugin as well as to
- describe the actual fonts a plugin provides.
-
- \sa QAbstractFontEngine, QFontEnginePlugin
-*/
-
-/*!
- Constructs a new empty QFontEngineInfo.
-*/
-QFontEngineInfo::QFontEngineInfo()
-{
- d = new QFontEngineInfoPrivate;
-}
-
-/*!
- Constructs a new QFontEngineInfo with the specified \a family.
- The resulting object represents a freely scalable font with normal
- weight and style.
-*/
-QFontEngineInfo::QFontEngineInfo(const QString &family)
-{
- d = new QFontEngineInfoPrivate;
- d->family = family;
-}
-
-/*!
- Creates a new font engine info object with the same attributes as \a other.
-*/
-QFontEngineInfo::QFontEngineInfo(const QFontEngineInfo &other)
- : d(new QFontEngineInfoPrivate(*other.d))
-{
-}
-
-/*!
- Assigns \a other to this font engine info object, and returns a reference
- to this.
-*/
-QFontEngineInfo &QFontEngineInfo::operator=(const QFontEngineInfo &other)
-{
- *d = *other.d;
- return *this;
-}
-
-/*!
- Destroys this QFontEngineInfo object.
-*/
-QFontEngineInfo::~QFontEngineInfo()
-{
- delete d;
-}
-
-/*!
- \property QFontEngineInfo::family
- the family name of the font
-*/
-
-void QFontEngineInfo::setFamily(const QString &family)
-{
- d->family = family;
-}
-
-QString QFontEngineInfo::family() const
-{
- return d->family;
-}
-
-/*!
- \property QFontEngineInfo::pixelSize
- the pixel size of the font
-
- A pixel size of 0 represents a freely scalable font.
-*/
-
-void QFontEngineInfo::setPixelSize(qreal size)
-{
- d->pixelSize = size;
-}
-
-qreal QFontEngineInfo::pixelSize() const
-{
- return d->pixelSize;
-}
-
-/*!
- \property QFontEngineInfo::weight
- the weight of the font
-
- The value should be from the \l{QFont::Weight} enumeration.
-*/
-
-void QFontEngineInfo::setWeight(int weight)
-{
- d->weight = weight;
-}
-
-int QFontEngineInfo::weight() const
-{
- return d->weight;
-}
-
-/*!
- \property QFontEngineInfo::style
- the style of the font
-*/
-
-void QFontEngineInfo::setStyle(QFont::Style style)
-{
- d->style = style;
-}
-
-QFont::Style QFontEngineInfo::style() const
-{
- return d->style;
-}
-
-/*!
- \property QFontEngineInfo::writingSystems
- the writing systems supported by the font
-
- An empty list means that any writing system is supported.
-*/
-
-QList<QFontDatabase::WritingSystem> QFontEngineInfo::writingSystems() const
-{
- return d->writingSystems;
-}
-
-void QFontEngineInfo::setWritingSystems(const QList<QFontDatabase::WritingSystem> &writingSystems)
-{
- d->writingSystems = writingSystems;
-}
-
-class QFontEnginePluginPrivate : public QObjectPrivate
-{
- Q_DECLARE_PUBLIC(QFontEnginePlugin)
-
- QString foundry;
-};
-
-/*!
- \class QFontEnginePlugin
- \preliminary
- \brief The QFontEnginePlugin class is the base class for font engine factory plugins in Qt for Embedded Linux.
- \since 4.3
- \ingroup qws
- \ingroup plugins
-
- \tableofcontents
-
- QFontEnginePlugin is provided by font engine plugins to create
- instances of subclasses of QAbstractFontEngine.
-
- The member functions create() and availableFontEngines() must be
- implemented.
-
- \sa QAbstractFontEngine, QFontEngineInfo
-*/
-
-/*!
- Creates a font engine plugin that creates font engines with the
- specified \a foundry and \a parent.
-*/
-QFontEnginePlugin::QFontEnginePlugin(const QString &foundry, QObject *parent)
- : QObject(*new QFontEnginePluginPrivate, parent)
-{
- Q_D(QFontEnginePlugin);
- d->foundry = foundry;
-}
-
-/*!
- Destroys this font engine plugin.
-*/
-QFontEnginePlugin::~QFontEnginePlugin()
-{
-}
-
-/*!
- Returns a list of foundries the font engine plugin provides.
- The default implementation returns the foundry specified with the constructor.
-*/
-QStringList QFontEnginePlugin::keys() const
-{
- Q_D(const QFontEnginePlugin);
- return QStringList(d->foundry);
-}
-
-/*!
- \fn QAbstractFontEngine *QFontEnginePlugin::create(const QFontEngineInfo &info)
-
- Implemented in subclasses to create a new font engine that provides a font that
- matches \a info.
-*/
-
-/*!
- \fn QList<QFontEngineInfo> QFontEnginePlugin::availableFontEngines() const
-
- Implemented in subclasses to return a list of QFontEngineInfo objects that represents all font
- engines the plugin can create.
-*/
-
-class QAbstractFontEnginePrivate : public QObjectPrivate
-{
- Q_DECLARE_PUBLIC(QAbstractFontEngine)
-public:
-};
-
-//The <classname> class is|provides|contains|specifies...
-/*!
- \class QAbstractFontEngine
- \preliminary
- \brief The QAbstractFontEngine class is the base class for font engine plugins in Qt for Embedded Linux.
- \since 4.3
- \ingroup qws
-
- \tableofcontents
-
- QAbstractFontEngine is implemented by font engine plugins through QFontEnginePlugin.
-
- \sa QFontEnginePlugin, QFontEngineInfo
-*/
-
-/*!
- \enum QAbstractFontEngine::Capability
-
- This enum describes the capabilities of a font engine.
-
- \value CanRenderGlyphs_Gray The font engine can render individual glyphs into 8 bpp images.
- \value CanRenderGlyphs_Mono The font engine can render individual glyphs into 1 bpp images.
- \value CanRenderGlyphs The font engine can render individual glyphs into images.
- \value CanOutlineGlyphs The font engine can convert glyphs to painter paths.
-*/
-
-/*!
- \enum QAbstractFontEngine::FontProperty
-
- This enum describes the properties of a font provided by a font engine.
-
- \value Ascent The ascent of the font, specified as a 26.6 fixed point value.
- \value Descent The descent of the font, specified as a 26.6 fixed point value.
- \value Leading The leading of the font, specified as a 26.6 fixed point value.
- \value XHeight The 'x' height of the font, specified as a 26.6 fixed point value.
- \value AverageCharWidth The average character width of the font, specified as a 26.6 fixed point value.
- \value LineThickness The thickness of the underline and strikeout lines for the font, specified as a 26.6 fixed point value.
- \value UnderlinePosition The distance from the base line to the underline position for the font, specified as a 26.6 fixed point value.
- \value MaxCharWidth The width of the widest character in the font, specified as a 26.6 fixed point value.
- \value MinLeftBearing The minimum left bearing of the font, specified as a 26.6 fixed point value.
- \value MinRightBearing The maximum right bearing of the font, specified as a 26.6 fixed point value.
- \value GlyphCount The number of glyphs in the font, specified as an integer value.
- \value CacheGlyphsHint A boolean value specifying whether rendered glyphs should be cached by Qt.
- \value OutlineGlyphsHint A boolean value specifying whether the font engine prefers outline drawing over image rendering for uncached glyphs.
-*/
-
-/*!
- \enum QAbstractFontEngine::TextShapingFlag
-
- This enum describes flags controlling conversion of characters to glyphs and their metrics.
-
- \value RightToLeft The text is used in a right-to-left context.
- \value ReturnDesignMetrics Return font design metrics instead of pixel metrics.
-*/
-
-/*!
- \typedef QAbstractFontEngine::Fixed
-
- This type is \c int, interpreted as a 26.6 fixed point value.
-*/
-
-/*!
- \class QAbstractFontEngine::GlyphMetrics
- \brief QAbstractFontEngine::GlyphMetrics defines the metrics of a single glyph.
- \preliminary
- \since 4.3
-*/
-
-/*!
- \variable QAbstractFontEngine::GlyphMetrics::x
-
- The horizontal offset from the origin.
-*/
-
-/*!
- \fn QAbstractFontEngine::GlyphMetrics::GlyphMetrics()
-
- Constructs an empty glyph metrics object with all values
- set to zero.
-*/
-
-/*!
- \variable QAbstractFontEngine::GlyphMetrics::y
-
- The vertical offset from the origin (baseline).
-*/
-
-/*!
- \variable QAbstractFontEngine::GlyphMetrics::width
-
- The width of the glyph.
-*/
-
-/*!
- \variable QAbstractFontEngine::GlyphMetrics::height
-
- The height of the glyph.
-*/
-
-/*!
- \variable QAbstractFontEngine::GlyphMetrics::advance
-
- The advance of the glyph.
-*/
-
-/*!
- \class QAbstractFontEngine::FixedPoint
- \brief QAbstractFontEngine::FixedPoint defines a point in the place using 26.6 fixed point precision.
- \preliminary
- \since 4.3
-*/
-
-/*!
- \variable QAbstractFontEngine::FixedPoint::x
-
- The x coordinate of this point.
-*/
-
-/*!
- \variable QAbstractFontEngine::FixedPoint::y
-
- The y coordinate of this point.
-*/
-
-/*!
- Constructs a new QAbstractFontEngine with the given \a parent.
-*/
-QAbstractFontEngine::QAbstractFontEngine(QObject *parent)
- : QObject(*new QAbstractFontEnginePrivate, parent)
-{
-}
-
-/*!
- Destroys this QAbstractFontEngine object.
-*/
-QAbstractFontEngine::~QAbstractFontEngine()
-{
-}
-
-/*!
- \fn QAbstractFontEngine::Capabilities QAbstractFontEngine::capabilities() const
-
- Implemented in subclasses to specify the font engine's capabilities. The return value
- may be cached by the caller and is expected not to change during the lifetime of the
- font engine.
-*/
-
-/*!
- \fn QVariant QAbstractFontEngine::fontProperty(FontProperty property) const
-
- Implemented in subclasses to return the value of the font attribute \a property. The return
- value may be cached by the caller and is expected not to change during the lifetime of the font
- engine.
-*/
-
-/*!
- \fn bool QAbstractFontEngine::convertStringToGlyphIndices(const QChar *string, int length, uint *glyphs, int *numGlyphs, TextShapingFlags flags) const
-
- Implemented in subclasses to convert the characters specified by \a string and \a length to
- glyph indicies, using \a flags. The glyph indicies should be returned in the \a glyphs array
- provided by the caller. The maximum size of \a glyphs is specified by the value pointed to by \a
- numGlyphs. If successful, the subclass implementation sets the value pointed to by \a numGlyphs
- to the actual number of glyph indices generated, and returns true. Otherwise, e.g. if there is
- not enough space in the provided \a glyphs array, it should set \a numGlyphs to the number of
- glyphs needed for the conversion and return false.
-*/
-
-/*!
- \fn void QAbstractFontEngine::getGlyphAdvances(const uint *glyphs, int numGlyphs, Fixed *advances, TextShapingFlags flags) const
-
- Implemented in subclasses to retrieve the advances of the array specified by \a glyphs and \a
- numGlyphs, using \a flags. The result is returned in \a advances, which is allocated by the
- caller and contains \a numGlyphs elements.
-*/
-
-/*!
- \fn QAbstractFontEngine::GlyphMetrics QAbstractFontEngine::glyphMetrics(uint glyph) const
-
- Implemented in subclass to return the metrics for \a glyph.
-*/
-
-/*!
- Implemented in subclasses to render the specified \a glyph into a \a buffer with the given \a depth ,
- \a bytesPerLine and \a height.
-
- Returns true if rendering succeeded, false otherwise.
-*/
-bool QAbstractFontEngine::renderGlyph(uint glyph, int depth, int bytesPerLine, int height, uchar *buffer)
-{
- Q_UNUSED(glyph)
- Q_UNUSED(depth)
- Q_UNUSED(bytesPerLine)
- Q_UNUSED(height)
- Q_UNUSED(buffer)
- qWarning("QAbstractFontEngine: renderGlyph is not implemented in font plugin!");
- return false;
-}
-
-/*!
- Implemented in subclasses to add the outline of the glyphs specified by \a glyphs and \a
- numGlyphs at the specified \a positions to the painter path \a path.
-*/
-void QAbstractFontEngine::addGlyphOutlinesToPath(uint *glyphs, int numGlyphs, FixedPoint *positions, QPainterPath *path)
-{
- Q_UNUSED(glyphs)
- Q_UNUSED(numGlyphs)
- Q_UNUSED(positions)
- Q_UNUSED(path)
- qWarning("QAbstractFontEngine: addGlyphOutlinesToPath is not implemented in font plugin!");
-}
-
-/*
-bool QAbstractFontEngine::supportsExtension(Extension extension) const
-{
- Q_UNUSED(extension)
- return false;
-}
-
-QVariant QAbstractFontEngine::extension(Extension extension, const QVariant &argument)
-{
- Q_UNUSED(argument)
- Q_UNUSED(extension)
- return QVariant();
-}
-*/
-
-QProxyFontEngine::QProxyFontEngine(QAbstractFontEngine *customEngine, const QFontDef &def)
- : engine(customEngine)
-{
- fontDef = def;
- engineCapabilities = engine->capabilities();
-}
-
-QProxyFontEngine::~QProxyFontEngine()
-{
- delete engine;
-}
-
-bool QProxyFontEngine::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const
-{
- if (*nglyphs < len) {
- *nglyphs = len;
- return false;
- }
-
- QVarLengthArray<uint> glyphIndicies(*nglyphs);
- if (!engine->convertStringToGlyphIndices(str, len, glyphIndicies.data(), nglyphs, QAbstractFontEngine::TextShapingFlags(int(flags))))
- return false;
-
- // ### use memcopy instead
- for (int i = 0; i < *nglyphs; ++i) {
- glyphs->glyphs[i] = glyphIndicies[i];
- }
- glyphs->numGlyphs = *nglyphs;
-
- recalcAdvances(glyphs, flags);
- return true;
-}
-
-void QProxyFontEngine::recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFlags flags) const
-{
- const int nglyphs = glyphs->numGlyphs;
-
- QVarLengthArray<QAbstractFontEngine::Fixed> advances(nglyphs);
- engine->getGlyphAdvances(glyphs->glyphs, nglyphs, advances.data(), QAbstractFontEngine::TextShapingFlags(int(flags)));
-
-
- // ### use memcopy instead
- for (int i = 0; i < nglyphs; ++i) {
- glyphs->advances_x[i] = QFixed::fromFixed(advances[i]);
- glyphs->advances_y[i] = 0;
- }
-}
-
-
-static QImage alphaMapFromPath(QFontEngine *fe, glyph_t glyph)
-{
- glyph_metrics_t gm = fe->boundingBox(glyph);
- int glyph_x = qFloor(gm.x.toReal());
- int glyph_y = qFloor(gm.y.toReal());
- int glyph_width = qCeil((gm.x + gm.width).toReal()) - glyph_x;
- int glyph_height = qCeil((gm.y + gm.height).toReal()) - glyph_y;
-
- if (glyph_width <= 0 || glyph_height <= 0)
- return QImage();
- QFixedPoint pt;
- pt.x = 0;
- pt.y = -glyph_y; // the baseline
- QPainterPath path;
- QImage im(glyph_width + qAbs(glyph_x) + 4, glyph_height, QImage::Format_ARGB32_Premultiplied);
- im.fill(Qt::transparent);
- QPainter p(&im);
- p.setRenderHint(QPainter::Antialiasing);
- fe->addGlyphsToPath(&glyph, &pt, 1, &path, 0);
- p.setPen(Qt::NoPen);
- p.setBrush(Qt::black);
- p.drawPath(path);
- p.end();
-
- QImage indexed(im.width(), im.height(), QImage::Format_Indexed8);
- QVector<QRgb> colors(256);
- for (int i=0; i<256; ++i)
- colors[i] = qRgba(0, 0, 0, i);
- indexed.setColorTable(colors);
-
- for (int y=0; y<im.height(); ++y) {
- uchar *dst = (uchar *) indexed.scanLine(y);
- uint *src = (uint *) im.scanLine(y);
- for (int x=0; x<im.width(); ++x)
- dst[x] = qAlpha(src[x]);
- }
-
- return indexed;
-}
-
-
-QImage QProxyFontEngine::alphaMapForGlyph(glyph_t glyph)
-{
- if (!(engineCapabilities & QAbstractFontEngine::CanRenderGlyphs_Gray))
- return alphaMapFromPath(this, glyph);
-
- QAbstractFontEngine::GlyphMetrics metrics = engine->glyphMetrics(glyph);
- if (metrics.width <= 0 || metrics.height <= 0)
- return QImage();
-
- QImage img(metrics.width >> 6, metrics.height >> 6, QImage::Format_Indexed8);
-
- // ### we should have QImage::Format_GrayScale8
- static QVector<QRgb> colorMap;
- if (colorMap.isEmpty()) {
- colorMap.resize(256);
- for (int i=0; i<256; ++i)
- colorMap[i] = qRgba(0, 0, 0, i);
- }
-
- img.setColorTable(colorMap);
-
- engine->renderGlyph(glyph, /*depth*/8, img.bytesPerLine(), img.height(), img.bits());
-
- return img;
-}
-
-void QProxyFontEngine::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nglyphs, QPainterPath *path, QTextItem::RenderFlags flags)
-{
- if (engineCapabilities & QAbstractFontEngine::CanOutlineGlyphs)
- engine->addGlyphOutlinesToPath(glyphs, nglyphs, reinterpret_cast<QAbstractFontEngine::FixedPoint *>(positions), path);
- else
- QFontEngine::addGlyphsToPath(glyphs, positions, nglyphs, path, flags);
-}
-
-glyph_metrics_t QProxyFontEngine::boundingBox(const QGlyphLayout &glyphs)
-{
- if (glyphs.numGlyphs == 0)
- return glyph_metrics_t();
-
- QFixed w = 0;
- for (int i = 0; i < glyphs.numGlyphs; ++i)
- w += glyphs.effectiveAdvance(i);
-
- return glyph_metrics_t(0, -ascent(), w, ascent() + descent(), w, 0);
-}
-
-glyph_metrics_t QProxyFontEngine::boundingBox(glyph_t glyph)
-{
- glyph_metrics_t m;
-
- QAbstractFontEngine::GlyphMetrics metrics = engine->glyphMetrics(glyph);
- m.x = QFixed::fromFixed(metrics.x);
- m.y = QFixed::fromFixed(metrics.y);
- m.width = QFixed::fromFixed(metrics.width);
- m.height = QFixed::fromFixed(metrics.height);
- m.xoff = QFixed::fromFixed(metrics.advance);
-
- return m;
-}
-
-QFixed QProxyFontEngine::ascent() const
-{
- return QFixed::fromFixed(engine->fontProperty(QAbstractFontEngine::Ascent).toInt());
-}
-
-QFixed QProxyFontEngine::descent() const
-{
- return QFixed::fromFixed(engine->fontProperty(QAbstractFontEngine::Descent).toInt());
-}
-
-QFixed QProxyFontEngine::leading() const
-{
- return QFixed::fromFixed(engine->fontProperty(QAbstractFontEngine::Leading).toInt());
-}
-
-QFixed QProxyFontEngine::xHeight() const
-{
- return QFixed::fromFixed(engine->fontProperty(QAbstractFontEngine::XHeight).toInt());
-}
-
-QFixed QProxyFontEngine::averageCharWidth() const
-{
- return QFixed::fromFixed(engine->fontProperty(QAbstractFontEngine::AverageCharWidth).toInt());
-}
-
-QFixed QProxyFontEngine::lineThickness() const
-{
- return QFixed::fromFixed(engine->fontProperty(QAbstractFontEngine::LineThickness).toInt());
-}
-
-QFixed QProxyFontEngine::underlinePosition() const
-{
- return QFixed::fromFixed(engine->fontProperty(QAbstractFontEngine::UnderlinePosition).toInt());
-}
-
-qreal QProxyFontEngine::maxCharWidth() const
-{
- return QFixed::fromFixed(engine->fontProperty(QAbstractFontEngine::MaxCharWidth).toInt()).toReal();
-}
-
-qreal QProxyFontEngine::minLeftBearing() const
-{
- return QFixed::fromFixed(engine->fontProperty(QAbstractFontEngine::MinLeftBearing).toInt()).toReal();
-}
-
-qreal QProxyFontEngine::minRightBearing() const
-{
- return QFixed::fromFixed(engine->fontProperty(QAbstractFontEngine::MinRightBearing).toInt()).toReal();
-}
-
-int QProxyFontEngine::glyphCount() const
-{
- return engine->fontProperty(QAbstractFontEngine::GlyphCount).toInt();
-}
-
-bool QProxyFontEngine::canRender(const QChar *string, int len)
-{
- QVarLengthArray<uint> glyphs(len);
- int numGlyphs = len;
-
- if (!engine->convertStringToGlyphIndices(string, len, glyphs.data(), &numGlyphs, /*flags*/0))
- return false;
-
- for (int i = 0; i < numGlyphs; ++i)
- if (!glyphs[i])
- return false;
-
- return true;
-}
-
-void QProxyFontEngine::draw(QPaintEngine *p, qreal _x, qreal _y, const QTextItemInt &si)
-{
- QPaintEngineState *pState = p->state;
- QRasterPaintEngine *paintEngine = static_cast<QRasterPaintEngine*>(p);
-
- QTransform matrix = pState->transform();
- matrix.translate(_x, _y);
- QFixed x = QFixed::fromReal(matrix.dx());
- QFixed y = QFixed::fromReal(matrix.dy());
-
- QVarLengthArray<QFixedPoint> positions;
- QVarLengthArray<glyph_t> glyphs;
- getGlyphPositions(si.glyphs, matrix, si.flags, glyphs, positions);
- if (glyphs.size() == 0)
- return;
-
- for(int i = 0; i < glyphs.size(); i++) {
- QImage glyph = alphaMapForGlyph(glyphs[i]);
- if (glyph.isNull())
- continue;
-
- if (glyph.format() != QImage::Format_Indexed8
- && glyph.format() != QImage::Format_Mono)
- continue;
-
- QAbstractFontEngine::GlyphMetrics metrics = engine->glyphMetrics(glyphs[i]);
-
- int depth = glyph.format() == QImage::Format_Mono ? 1 : 8;
- paintEngine->alphaPenBlt(glyph.bits(), glyph.bytesPerLine(), depth,
- qRound(positions[i].x + QFixed::fromFixed(metrics.x)),
- qRound(positions[i].y + QFixed::fromFixed(metrics.y)),
- glyph.width(), glyph.height());
- }
-}
-
-/*
- * This is only called when we use the proxy fontengine directly (without sharing the rendered
- * glyphs). So we prefer outline rendering over rendering of unshared glyphs. That decision is
- * done in qfontdatabase_qws.cpp by looking at the ShareGlyphsHint and the pixel size of the font.
- */
-bool QProxyFontEngine::drawAsOutline() const
-{
- if (!(engineCapabilities & QAbstractFontEngine::CanOutlineGlyphs))
- return false;
-
- QVariant outlineHint = engine->fontProperty(QAbstractFontEngine::OutlineGlyphsHint);
- return !outlineHint.isValid() || outlineHint.toBool();
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/text/qabstractfontengine_qws.h b/src/gui/text/qabstractfontengine_qws.h
deleted file mode 100644
index 4c85a0a063..0000000000
--- a/src/gui/text/qabstractfontengine_qws.h
+++ /dev/null
@@ -1,221 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QABSTRACTFONTENGINE_QWS_H
-#define QABSTRACTFONTENGINE_QWS_H
-
-#include <QtCore/qobject.h>
-#include <QtCore/qhash.h>
-#include <QtCore/qvariant.h>
-#include <QtCore/qfactoryinterface.h>
-#include <QtGui/qpaintengine.h>
-#include <QtGui/qfontdatabase.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QFontEngineInfoPrivate;
-
-class Q_GUI_EXPORT QFontEngineInfo
-{
-public:
- QDOC_PROPERTY(QString family READ family WRITE setFamily)
- QDOC_PROPERTY(qreal pixelSize READ pixelSize WRITE setPixelSize)
- QDOC_PROPERTY(int weight READ weight WRITE setWeight)
- QDOC_PROPERTY(QFont::Style style READ style WRITE setStyle)
- QDOC_PROPERTY(QList<QFontDatabase::WritingSystem> writingSystems READ writingSystems WRITE setWritingSystems)
-
- QFontEngineInfo();
- explicit QFontEngineInfo(const QString &family);
- QFontEngineInfo(const QFontEngineInfo &other);
- QFontEngineInfo &operator=(const QFontEngineInfo &other);
- ~QFontEngineInfo();
-
- void setFamily(const QString &name);
- QString family() const;
-
- void setPixelSize(qreal size);
- qreal pixelSize() const;
-
- void setWeight(int weight);
- int weight() const;
-
- void setStyle(QFont::Style style);
- QFont::Style style() const;
-
- QList<QFontDatabase::WritingSystem> writingSystems() const;
- void setWritingSystems(const QList<QFontDatabase::WritingSystem> &writingSystems);
-
-private:
- QFontEngineInfoPrivate *d;
-};
-
-class QAbstractFontEngine;
-
-struct Q_GUI_EXPORT QFontEngineFactoryInterface : public QFactoryInterface
-{
- virtual QAbstractFontEngine *create(const QFontEngineInfo &info) = 0;
- virtual QList<QFontEngineInfo> availableFontEngines() const = 0;
-};
-
-#define QFontEngineFactoryInterface_iid "com.trolltech.Qt.QFontEngineFactoryInterface"
-Q_DECLARE_INTERFACE(QFontEngineFactoryInterface, QFontEngineFactoryInterface_iid)
-
-class QFontEnginePluginPrivate;
-
-class Q_GUI_EXPORT QFontEnginePlugin : public QObject, public QFontEngineFactoryInterface
-{
- Q_OBJECT
- Q_INTERFACES(QFontEngineFactoryInterface:QFactoryInterface)
-public:
- QFontEnginePlugin(const QString &foundry, QObject *parent = 0);
- ~QFontEnginePlugin();
-
- virtual QStringList keys() const;
-
- virtual QAbstractFontEngine *create(const QFontEngineInfo &info) = 0;
- virtual QList<QFontEngineInfo> availableFontEngines() const = 0;
-
-private:
- Q_DECLARE_PRIVATE(QFontEnginePlugin)
- Q_DISABLE_COPY(QFontEnginePlugin)
-};
-
-class QAbstractFontEnginePrivate;
-
-class Q_GUI_EXPORT QAbstractFontEngine : public QObject
-{
- Q_OBJECT
-public:
- enum Capability {
- CanOutlineGlyphs = 1,
- CanRenderGlyphs_Mono = 2,
- CanRenderGlyphs_Gray = 4,
- CanRenderGlyphs = CanRenderGlyphs_Mono | CanRenderGlyphs_Gray
- };
- Q_DECLARE_FLAGS(Capabilities, Capability)
-
- explicit QAbstractFontEngine(QObject *parent = 0);
- ~QAbstractFontEngine();
-
- typedef int Fixed; // 26.6
-
- struct FixedPoint
- {
- Fixed x;
- Fixed y;
- };
-
- struct GlyphMetrics
- {
- inline GlyphMetrics()
- : x(0), y(0), width(0), height(0),
- advance(0) {}
- Fixed x;
- Fixed y;
- Fixed width;
- Fixed height;
- Fixed advance;
- };
-
- enum FontProperty {
- Ascent,
- Descent,
- Leading,
- XHeight,
- AverageCharWidth,
- LineThickness,
- UnderlinePosition,
- MaxCharWidth,
- MinLeftBearing,
- MinRightBearing,
- GlyphCount,
-
- // hints
- CacheGlyphsHint,
- OutlineGlyphsHint
- };
-
- // keep in sync with QTextEngine::ShaperFlag!!
- enum TextShapingFlag {
- RightToLeft = 0x0001,
- ReturnDesignMetrics = 0x0002
- };
- Q_DECLARE_FLAGS(TextShapingFlags, TextShapingFlag)
-
- virtual Capabilities capabilities() const = 0;
- virtual QVariant fontProperty(FontProperty property) const = 0;
-
- virtual bool convertStringToGlyphIndices(const QChar *string, int length, uint *glyphs, int *numGlyphs, TextShapingFlags flags) const = 0;
-
- virtual void getGlyphAdvances(const uint *glyphs, int numGlyphs, Fixed *advances, TextShapingFlags flags) const = 0;
-
- virtual GlyphMetrics glyphMetrics(uint glyph) const = 0;
-
- virtual bool renderGlyph(uint glyph, int depth, int bytesPerLine, int height, uchar *buffer);
-
- virtual void addGlyphOutlinesToPath(uint *glyphs, int numGlyphs, FixedPoint *positions, QPainterPath *path);
-
- /*
- enum Extension {
- GetTrueTypeTable
- };
-
- virtual bool supportsExtension(Extension extension) const;
- virtual QVariant extension(Extension extension, const QVariant &argument = QVariant());
- */
-
-private:
- Q_DECLARE_PRIVATE(QAbstractFontEngine)
- Q_DISABLE_COPY(QAbstractFontEngine)
-};
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QAbstractFontEngine::Capabilities)
-Q_DECLARE_OPERATORS_FOR_FLAGS(QAbstractFontEngine::TextShapingFlags)
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif
diff --git a/src/gui/text/qabstracttextdocumentlayout.h b/src/gui/text/qabstracttextdocumentlayout.h
index 12f3ed1217..8e792e9b80 100644
--- a/src/gui/text/qabstracttextdocumentlayout.h
+++ b/src/gui/text/qabstracttextdocumentlayout.h
@@ -122,6 +122,7 @@ protected:
QTextCharFormat format(int pos);
private:
+ friend class QWidgetTextControl;
friend class QTextControl;
friend class QTextDocument;
friend class QTextDocumentPrivate;
diff --git a/src/gui/text/qcssparser.cpp b/src/gui/text/qcssparser.cpp
index 028011bfe8..6a28ff2d74 100644
--- a/src/gui/text/qcssparser.cpp
+++ b/src/gui/text/qcssparser.cpp
@@ -1275,6 +1275,8 @@ void ValueExtractor::extractFont()
bool ValueExtractor::extractImage(QIcon *icon, Qt::Alignment *a, QSize *size)
{
bool hit = false;
+#if 0
+ // ### Qt5
for (int i = 0; i < declarations.count(); ++i) {
const Declaration &decl = declarations.at(i);
switch (decl.d->propertyId) {
@@ -1295,6 +1297,7 @@ bool ValueExtractor::extractImage(QIcon *icon, Qt::Alignment *a, QSize *size)
}
hit = true;
}
+#endif
return hit;
}
@@ -1643,6 +1646,8 @@ void Declaration::borderImageValue(QString *image, int *cuts,
*h = *v;
}
+#if 0
+// ### Qt 5
QIcon Declaration::iconValue() const
{
if (d->parsed.isValid())
@@ -1689,6 +1694,7 @@ QIcon Declaration::iconValue() const
d->parsed = QVariant::fromValue<QIcon>(icon);
return icon;
}
+#endif
///////////////////////////////////////////////////////////////////////////////
// Selector
diff --git a/src/gui/text/qcssparser_p.h b/src/gui/text/qcssparser_p.h
index 9c974f773a..4fa8bb0540 100644
--- a/src/gui/text/qcssparser_p.h
+++ b/src/gui/text/qcssparser_p.h
@@ -61,9 +61,9 @@
#include <QtCore/QMultiHash>
#include <QtGui/QFont>
#include <QtGui/QPalette>
-#include <QtGui/QIcon>
#include <QtCore/QSharedData>
+class QIcon;
#ifndef QT_NO_CSSPARSER
@@ -416,7 +416,7 @@ struct BorderData {
// 4. QVector<Declaration> - { prop1: value1; prop2: value2; }
// 5. Declaration - prop1: value1;
-struct Q_AUTOTEST_EXPORT Declaration
+struct Q_GUI_EXPORT Declaration
{
struct DeclarationData : public QSharedData
{
@@ -453,7 +453,7 @@ struct Q_AUTOTEST_EXPORT Declaration
QSize sizeValue() const;
QRect rectValue() const;
QString uriValue() const;
- QIcon iconValue() const;
+// QIcon iconValue() const;
void borderImageValue(QString *image, int *cuts, TileMode *h, TileMode *v) const;
};
@@ -552,7 +552,7 @@ struct BasicSelector
Relation relationToNext;
};
-struct Q_AUTOTEST_EXPORT Selector
+struct Q_GUI_EXPORT Selector
{
QVector<BasicSelector> basicSelectors;
int specificity() const;
@@ -565,7 +565,7 @@ struct MediaRule;
struct PageRule;
struct ImportRule;
-struct Q_AUTOTEST_EXPORT ValueExtractor
+struct Q_GUI_EXPORT ValueExtractor
{
ValueExtractor(const QVector<Declaration> &declarations, const QPalette & = QPalette());
@@ -633,7 +633,7 @@ enum StyleSheetOrigin {
StyleSheetOrigin_Inline
};
-struct StyleSheet
+struct Q_GUI_EXPORT StyleSheet
{
StyleSheet() : origin(StyleSheetOrigin_Unspecified), depth(0) { }
QVector<StyleRule> styleRules; //only contains rules that are not indexed
@@ -739,7 +739,7 @@ struct Q_GUI_EXPORT Symbol
QString lexem() const;
};
-class Q_AUTOTEST_EXPORT Scanner
+class Q_GUI_EXPORT Scanner
{
public:
static QString preprocess(const QString &input, bool *hasEscapeSequences = 0);
diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp
index cf97310ea3..e8308dba06 100644
--- a/src/gui/text/qfont.cpp
+++ b/src/gui/text/qfont.cpp
@@ -48,8 +48,9 @@
#include "qpainter.h"
#include "qhash.h"
#include "qdatastream.h"
-#include "qapplication.h"
+#include "qguiapplication.h"
#include "qstringlist.h"
+#include "qscreen.h"
#include "qthread.h"
#include "qthreadstorage.h"
@@ -65,19 +66,12 @@
#include "qx11info_x11.h"
#include <private/qt_x11_p.h>
#endif
-#ifdef Q_WS_QWS
-#include "qscreen_qws.h"
-#if !defined(QT_NO_QWS_QPF2)
-#include <qfile.h>
-#include "qfontengine_qpf_p.h"
-#endif
-#endif
#ifdef Q_OS_SYMBIAN
#include <private/qt_s60_p.h>
#endif
#ifdef Q_WS_QPA
#include <QtGui/qplatformscreen_qpa.h>
-#include <QtGui/private/qapplication_p.h>
+#include <QtGui/private/qguiapplication_p.h>
#endif
#include <QtCore/QMutexLocker>
@@ -173,20 +167,11 @@ Q_GUI_EXPORT int qt_defaultDpiX()
#elif defined(Q_WS_MAC)
extern float qt_mac_defaultDpi_x(); //qpaintdevice_mac.cpp
dpi = qt_mac_defaultDpi_x();
-#elif defined(Q_WS_QWS)
- if (!qt_screen)
- return 72;
- QScreen *screen = qt_screen;
- const QList<QScreen*> subScreens = qt_screen->subScreens();
- if (!subScreens.isEmpty())
- screen = subScreens.at(0);
- dpi = qRound(screen->width() / (screen->physicalWidth() / qreal(25.4)));
#elif defined(Q_WS_QPA)
- QPlatformIntegration *pi = QApplicationPrivate::platformIntegration();
- if (pi) {
- QPlatformScreen *screen = QApplicationPrivate::platformIntegration()->screens().at(0);
+ QScreen *screen = QGuiApplication::primaryScreen();
+ if (screen) {
const QSize screenSize = screen->geometry().size();
- const QSize physicalSize = screen->physicalSize();
+ const QSize physicalSize = screen->handle()->physicalSize();
dpi = qRound(screenSize.width() / (physicalSize.width() / qreal(25.4)));
} else {
//PI has not been initialised, or it is being initialised. Give a default dpi
@@ -212,20 +197,11 @@ Q_GUI_EXPORT int qt_defaultDpiY()
#elif defined(Q_WS_MAC)
extern float qt_mac_defaultDpi_y(); //qpaintdevice_mac.cpp
dpi = qt_mac_defaultDpi_y();
-#elif defined(Q_WS_QWS)
- if (!qt_screen)
- return 72;
- QScreen *screen = qt_screen;
- const QList<QScreen*> subScreens = qt_screen->subScreens();
- if (!subScreens.isEmpty())
- screen = subScreens.at(0);
- dpi = qRound(screen->height() / (screen->physicalHeight() / qreal(25.4)));
#elif defined(Q_WS_QPA)
- QPlatformIntegration *pi = QApplicationPrivate::platformIntegration();
- if (pi) {
- QPlatformScreen *screen = QApplicationPrivate::platformIntegration()->screens().at(0);
+ QScreen *screen = QGuiApplication::primaryScreen();
+ if (screen) {
const QSize screenSize = screen->geometry().size();
- const QSize physicalSize = screen->physicalSize();
+ const QSize physicalSize = screen->handle()->physicalSize();
dpi = qRound(screenSize.height() / (physicalSize.height() / qreal(25.4)));
} else {
//PI has not been initialised, or it is being initialised. Give a default dpi
@@ -453,9 +429,9 @@ QFontEngineData::~QFontEngineData()
Use QFontMetrics to get measurements, e.g. the pixel length of a
string using QFontMetrics::width().
- Note that a QApplication instance must exist before a QFont can be
+ Note that a QGuiApplication instance must exist before a QFont can be
used. You can set the application's default font with
- QApplication::setFont().
+ QGuiApplication::setFont().
If a chosen font does not include all the characters that
need to be displayed, QFont will try to find the characters in the
@@ -786,10 +762,10 @@ void QFont::detach()
/*!
Constructs a font object that uses the application's default font.
- \sa QApplication::setFont(), QApplication::font()
+ \sa QGuiApplication::setFont(), QGuiApplication::font()
*/
QFont::QFont()
- : d(QApplication::font().d.data()), resolve_mask(0)
+ : d(QGuiApplication::font().d.data()), resolve_mask(0)
{
}
@@ -809,7 +785,7 @@ QFont::QFont()
algorithm.
\sa Weight, setFamily(), setPointSize(), setWeight(), setItalic(),
- setStyleHint() QApplication::font()
+ setStyleHint() QGuiApplication::font()
*/
QFont::QFont(const QString &family, int pointSize, int weight, bool italic)
: d(new QFontPrivate()), resolve_mask(QFont::FamilyResolved)
@@ -1133,18 +1109,6 @@ int QFont::pixelSize() const
return d->request.pixelSize;
}
-#ifdef QT3_SUPPORT
-/*! \obsolete
-
- Sets the logical pixel height of font characters when shown on
- the screen to \a pixelSize.
-*/
-void QFont::setPixelSizeFloat(qreal pixelSize)
-{
- setPixelSize((int)pixelSize);
-}
-#endif
-
/*!
\fn bool QFont::italic() const
@@ -1912,43 +1876,6 @@ QFont QFont::resolve(const QFont &other) const
\internal
*/
-#ifdef QT3_SUPPORT
-
-/*! \obsolete
-
- Please use QApplication::font() instead.
-*/
-QFont QFont::defaultFont()
-{
- return QApplication::font();
-}
-
-/*! \obsolete
-
- Please use QApplication::setFont() instead.
-*/
-void QFont::setDefaultFont(const QFont &f)
-{
- QApplication::setFont(f);
-}
-
-/*!
- \fn qreal QFont::pointSizeFloat() const
- \compat
-
- Use pointSizeF() instead.
-*/
-
-/*!
- \fn void QFont::setPointSizeFloat(qreal size)
- \compat
-
- Use setPointSizeF() instead.
-*/
-#endif
-
-
-
/*****************************************************************************
QFont substitution management
diff --git a/src/gui/text/qfont.h b/src/gui/text/qfont.h
index 14f290ceb3..421c1dd2de 100644
--- a/src/gui/text/qfont.h
+++ b/src/gui/text/qfont.h
@@ -287,14 +287,6 @@ public:
inline uint resolve() const { return resolve_mask; }
inline void resolve(uint mask) { resolve_mask = mask; }
-#ifdef QT3_SUPPORT
- static QT3_SUPPORT QFont defaultFont();
- static QT3_SUPPORT void setDefaultFont(const QFont &);
- QT3_SUPPORT void setPixelSizeFloat(qreal);
- QT3_SUPPORT qreal pointSizeFloat() const { return pointSizeF(); }
- QT3_SUPPORT void setPointSizeFloat(qreal size) { setPointSizeF(size); }
-#endif
-
private:
QFont(QFontPrivate *);
@@ -324,7 +316,7 @@ private:
friend class QStackTextEngine;
friend class QTextLine;
friend struct QScriptLine;
- friend class QGLContext;
+ friend class QOpenGLContext;
friend class QWin32PaintEngine;
friend class QAlphaPaintEngine;
friend class QPainterPath;
diff --git a/src/gui/text/qfont_qpa.cpp b/src/gui/text/qfont_qpa.cpp
index 54ef9119e0..e151a389cd 100644
--- a/src/gui/text/qfont_qpa.cpp
+++ b/src/gui/text/qfont_qpa.cpp
@@ -39,13 +39,14 @@
**
****************************************************************************/
-#include <QtGui/private/qapplication_p.h>
+#include <QtGui/private/qguiapplication_p.h>
#include <QtGui/QPlatformFontDatabase>
QT_BEGIN_NAMESPACE
void QFont::initialize()
{
+ QGuiApplicationPrivate::platformIntegration()->fontDatabase()->populateFontDatabase();
}
void QFont::cleanup()
@@ -89,7 +90,7 @@ QString QFont::defaultFamily() const
familyName = QString::fromLatin1("helvetica");
}
- QStringList list = QApplicationPrivate::platformIntegration()->fontDatabase()->fallbacksForFamily(familyName,QFont::StyleNormal,QFont::StyleHint(d->request.styleHint),QUnicodeTables::Common);
+ QStringList list = QGuiApplicationPrivate::platformIntegration()->fontDatabase()->fallbacksForFamily(familyName,QFont::StyleNormal,QFont::StyleHint(d->request.styleHint),QUnicodeTables::Common);
if (list.size()) {
familyName = list.at(0);
}
diff --git a/src/gui/text/qfont_qws.cpp b/src/gui/text/qfont_qws.cpp
deleted file mode 100644
index 3674e178ea..0000000000
--- a/src/gui/text/qfont_qws.cpp
+++ /dev/null
@@ -1,135 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qwidget.h"
-#include "qpainter.h"
-#include "qfont_p.h"
-#include <private/qunicodetables_p.h>
-#include "qfontdatabase.h"
-#include "qtextcodec.h"
-#include "qapplication.h"
-#include "qfile.h"
-#include "qtextstream.h"
-#include "qmap.h"
-//#include "qmemorymanager_qws.h"
-#include "qtextengine_p.h"
-#include "qfontengine_p.h"
-#if !defined(QT_NO_FREETYPE)
-#include "qfontengine_ft_p.h"
-#endif
-
-QT_BEGIN_NAMESPACE
-
-void QFont::initialize()
-{ }
-
-void QFont::cleanup()
-{
- QFontCache::cleanup();
-}
-
-
-/*****************************************************************************
- QFont member functions
- *****************************************************************************/
-
-Qt::HANDLE QFont::handle() const
-{
-#ifndef QT_NO_FREETYPE
- return freetypeFace();
-#endif
- return 0;
-}
-
-FT_Face QFont::freetypeFace() const
-{
-#ifndef QT_NO_FREETYPE
- QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
- if (engine->type() == QFontEngine::Multi)
- engine = static_cast<QFontEngineMulti *>(engine)->engine(0);
- if (engine->type() == QFontEngine::Freetype) {
- const QFontEngineFT *ft = static_cast<const QFontEngineFT *>(engine);
- return ft->non_locked_face();
- }
-#endif
- return 0;
-}
-
-QString QFont::rawName() const
-{
- return QLatin1String("unknown");
-}
-
-void QFont::setRawName(const QString &)
-{
-}
-
-QString QFont::defaultFamily() const
-{
- switch(d->request.styleHint) {
- case QFont::Times:
- return QString::fromLatin1("times");
- case QFont::Courier:
- case QFont::Monospace:
- return QString::fromLatin1("courier");
- case QFont::Decorative:
- return QString::fromLatin1("old english");
- case QFont::Helvetica:
- case QFont::System:
- default:
- return QString::fromLatin1("helvetica");
- }
-}
-
-QString QFont::lastResortFamily() const
-{
- return QString::fromLatin1("helvetica");
-}
-
-QString QFont::lastResortFont() const
-{
- qFatal("QFont::lastResortFont: Cannot find any reasonable font");
- // Shut compiler up
- return QString();
-}
-
-
-QT_END_NAMESPACE
diff --git a/src/gui/text/qfont_x11.cpp b/src/gui/text/qfont_x11.cpp
deleted file mode 100644
index e89e0d9dc2..0000000000
--- a/src/gui/text/qfont_x11.cpp
+++ /dev/null
@@ -1,368 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#define QT_FATAL_ASSERT
-
-#include "qplatformdefs.h"
-
-#include "qfont.h"
-#include "qapplication.h"
-#include "qfontinfo.h"
-#include "qfontdatabase.h"
-#include "qfontmetrics.h"
-#include "qpaintdevice.h"
-#include "qtextcodec.h"
-#include "qiodevice.h"
-#include "qhash.h"
-
-#include <private/qunicodetables_p.h>
-#include "qfont_p.h"
-#include "qfontengine_p.h"
-#include "qfontengine_x11_p.h"
-#include "qtextengine_p.h"
-
-#include <private/qt_x11_p.h>
-#include "qx11info_x11.h"
-
-#include <time.h>
-#include <stdlib.h>
-#include <ctype.h>
-
-#define QFONTLOADER_DEBUG
-#define QFONTLOADER_DEBUG_VERBOSE
-
-QT_BEGIN_NAMESPACE
-
-double qt_pixelSize(double pointSize, int dpi)
-{
- if (pointSize < 0)
- return -1.;
- if (dpi == 75) // the stupid 75 dpi setting on X11
- dpi = 72;
- return (pointSize * dpi) /72.;
-}
-
-double qt_pointSize(double pixelSize, int dpi)
-{
- if (pixelSize < 0)
- return -1.;
- if (dpi == 75) // the stupid 75 dpi setting on X11
- dpi = 72;
- return pixelSize * 72. / ((double) dpi);
-}
-
-/*
- Removes wildcards from an XLFD.
-
- Returns \a xlfd with all wildcards removed if a match for \a xlfd is
- found, otherwise it returns \a xlfd.
-*/
-static QByteArray qt_fixXLFD(const QByteArray &xlfd)
-{
- QByteArray ret = xlfd;
- int count = 0;
- char **fontNames =
- XListFonts(QX11Info::display(), xlfd, 32768, &count);
- if (count > 0)
- ret = fontNames[0];
- XFreeFontNames(fontNames);
- return ret ;
-}
-
-typedef QHash<int, QString> FallBackHash;
-Q_GLOBAL_STATIC(FallBackHash, fallBackHash)
-
-// Returns the user-configured fallback family for the specified script.
-QString qt_fallback_font_family(int script)
-{
- FallBackHash *hash = fallBackHash();
- return hash->value(script);
-}
-
-// Sets the fallback family for the specified script.
-Q_GUI_EXPORT void qt_x11_set_fallback_font_family(int script, const QString &family)
-{
- FallBackHash *hash = fallBackHash();
- if (!family.isEmpty())
- hash->insert(script, family);
- else
- hash->remove(script);
-}
-
-int QFontPrivate::defaultEncodingID = -1;
-
-void QFont::initialize()
-{
- extern int qt_encoding_id_for_mib(int mib); // from qfontdatabase_x11.cpp
- QTextCodec *codec = QTextCodec::codecForLocale();
- // determine the default encoding id using the locale, otherwise
- // fallback to latin1 (mib == 4)
- int mib = codec ? codec->mibEnum() : 4;
-
- // for asian locales, use the mib for the font codec instead of the locale codec
- switch (mib) {
- case 38: // eucKR
- mib = 36;
- break;
-
- case 2025: // GB2312
- mib = 57;
- break;
-
- case 113: // GBK
- mib = -113;
- break;
-
- case 114: // GB18030
- mib = -114;
- break;
-
- case 2026: // Big5
- mib = -2026;
- break;
-
- case 2101: // Big5-HKSCS
- mib = -2101;
- break;
-
- case 16: // JIS7
- mib = 15;
- break;
-
- case 17: // SJIS
- case 18: // eucJP
- mib = 63;
- break;
- }
-
- // get the default encoding id for the locale encoding...
- QFontPrivate::defaultEncodingID = qt_encoding_id_for_mib(mib);
-}
-
-void QFont::cleanup()
-{
- QFontCache::cleanup();
-}
-
-/*!
- \internal
- X11 Only: Returns the screen with which this font is associated.
-*/
-int QFont::x11Screen() const
-{
- return d->screen;
-}
-
-/*! \internal
- X11 Only: Associate the font with the specified \a screen.
-*/
-void QFont::x11SetScreen(int screen)
-{
- if (screen < 0) // assume default
- screen = QX11Info::appScreen();
-
- if (screen == d->screen)
- return; // nothing to do
-
- detach();
- d->screen = screen;
-}
-
-Qt::HANDLE QFont::handle() const
-{
- QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
- Q_ASSERT(engine != 0);
- if (engine->type() == QFontEngine::Multi)
- engine = static_cast<QFontEngineMulti *>(engine)->engine(0);
- if (engine->type() == QFontEngine::XLFD)
- return static_cast<QFontEngineXLFD *>(engine)->fontStruct()->fid;
- return 0;
-}
-
-
-FT_Face QFont::freetypeFace() const
-{
-#ifndef QT_NO_FREETYPE
- QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
- if (engine->type() == QFontEngine::Multi)
- engine = static_cast<QFontEngineMulti *>(engine)->engine(0);
-#ifndef QT_NO_FONTCONFIG
- if (engine->type() == QFontEngine::Freetype) {
- const QFontEngineFT *ft = static_cast<const QFontEngineFT *>(engine);
- return ft->non_locked_face();
- } else
-#endif
- if (engine->type() == QFontEngine::XLFD) {
- const QFontEngineXLFD *xlfd = static_cast<const QFontEngineXLFD *>(engine);
- return xlfd->non_locked_face();
- }
-#endif
- return 0;
-}
-
-QString QFont::rawName() const
-{
- QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
- Q_ASSERT(engine != 0);
- if (engine->type() == QFontEngine::Multi)
- engine = static_cast<QFontEngineMulti *>(engine)->engine(0);
- if (engine->type() == QFontEngine::XLFD)
- return QString::fromLatin1(engine->name());
- return QString();
-}
-struct QtFontDesc;
-
-void QFont::setRawName(const QString &name)
-{
- detach();
-
- // from qfontdatabase_x11.cpp
- extern bool qt_fillFontDef(const QByteArray &xlfd, QFontDef *fd, int dpi, QtFontDesc *desc);
-
- if (!qt_fillFontDef(qt_fixXLFD(name.toLatin1()), &d->request, d->dpi, 0)) {
- qWarning("QFont::setRawName: Invalid XLFD: \"%s\"", name.toLatin1().constData());
-
- setFamily(name);
- setRawMode(true);
- } else {
- resolve_mask = QFont::AllPropertiesResolved;
- }
-}
-
-QString QFont::lastResortFamily() const
-{
- return QString::fromLatin1("Helvetica");
-}
-
-QString QFont::defaultFamily() const
-{
- switch (d->request.styleHint) {
- case QFont::Times:
- return QString::fromLatin1("Times");
-
- case QFont::Courier:
- return QString::fromLatin1("Courier");
-
- case QFont::Monospace:
- return QString::fromLatin1("Courier New");
-
- case QFont::Cursive:
- return QString::fromLatin1("Comic Sans MS");
-
- case QFont::Fantasy:
- return QString::fromLatin1("Impact");
-
- case QFont::Decorative:
- return QString::fromLatin1("Old English");
-
- case QFont::Helvetica:
- case QFont::System:
- default:
- return QString::fromLatin1("Helvetica");
- }
-}
-
-/*
- Returns a last resort raw font name for the font matching algorithm.
- This is used if even the last resort family is not available. It
- returns \e something, almost no matter what. The current
- implementation tries a wide variety of common fonts, returning the
- first one it finds. The implementation may change at any time.
-*/
-static const char * const tryFonts[] = {
- "-*-helvetica-medium-r-*-*-*-120-*-*-*-*-*-*",
- "-*-courier-medium-r-*-*-*-120-*-*-*-*-*-*",
- "-*-times-medium-r-*-*-*-120-*-*-*-*-*-*",
- "-*-lucida-medium-r-*-*-*-120-*-*-*-*-*-*",
- "-*-helvetica-*-*-*-*-*-120-*-*-*-*-*-*",
- "-*-courier-*-*-*-*-*-120-*-*-*-*-*-*",
- "-*-times-*-*-*-*-*-120-*-*-*-*-*-*",
- "-*-lucida-*-*-*-*-*-120-*-*-*-*-*-*",
- "-*-helvetica-*-*-*-*-*-*-*-*-*-*-*-*",
- "-*-courier-*-*-*-*-*-*-*-*-*-*-*-*",
- "-*-times-*-*-*-*-*-*-*-*-*-*-*-*",
- "-*-lucida-*-*-*-*-*-*-*-*-*-*-*-*",
- "-*-fixed-*-*-*-*-*-*-*-*-*-*-*-*",
- "6x13",
- "7x13",
- "8x13",
- "9x15",
- "fixed",
- 0
-};
-
-// Returns true if the font exists, false otherwise
-static bool fontExists(const QString &fontName)
-{
- int count;
- char **fontNames = XListFonts(QX11Info::display(), (char*)fontName.toLatin1().constData(), 32768, &count);
- if (fontNames) XFreeFontNames(fontNames);
-
- return count != 0;
-}
-
-QString QFont::lastResortFont() const
-{
- static QString last;
-
- // already found
- if (! last.isNull())
- return last;
-
- int i = 0;
- const char* f;
-
- while ((f = tryFonts[i])) {
- last = QString::fromLatin1(f);
-
- if (fontExists(last))
- return last;
-
- i++;
- }
-
-#if defined(CHECK_NULL)
- qFatal("QFontPrivate::lastResortFont: Cannot find any reasonable font");
-#endif
- return last;
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp
index 6202fbac52..fa67dc1a8a 100644
--- a/src/gui/text/qfontdatabase.cpp
+++ b/src/gui/text/qfontdatabase.cpp
@@ -43,7 +43,7 @@
#include "qfontdatabase.h"
#include "qdebug.h"
#include "qalgorithms.h"
-#include "qapplication.h"
+#include "qguiapplication.h"
#include "qvarlengtharray.h" // here or earlier - workaround for VC++6
#include "qthread.h"
#include "qmutex.h"
@@ -51,7 +51,7 @@
#include "qfontengine_p.h"
#ifdef Q_WS_QPA
-#include <QtGui/private/qapplication_p.h>
+#include <QtGui/private/qguiapplication_p.h>
#include <QtGui/qplatformfontdatabase_qpa.h>
#include "qabstractfileengine.h"
#endif
@@ -103,34 +103,34 @@ static int getFontWeight(const QString &weightString)
// Test in decreasing order of commonness
if (s == QLatin1String("medium") ||
s == QLatin1String("normal")
- || s.compare(QApplication::translate("QFontDatabase", "Normal"), Qt::CaseInsensitive) == 0)
+ || s.compare(QCoreApplication::translate("QFontDatabase", "Normal"), Qt::CaseInsensitive) == 0)
return QFont::Normal;
if (s == QLatin1String("bold")
- || s.compare(QApplication::translate("QFontDatabase", "Bold"), Qt::CaseInsensitive) == 0)
+ || s.compare(QCoreApplication::translate("QFontDatabase", "Bold"), Qt::CaseInsensitive) == 0)
return QFont::Bold;
if (s == QLatin1String("demibold") || s == QLatin1String("demi bold")
- || s.compare(QApplication::translate("QFontDatabase", "Demi Bold"), Qt::CaseInsensitive) == 0)
+ || s.compare(QCoreApplication::translate("QFontDatabase", "Demi Bold"), Qt::CaseInsensitive) == 0)
return QFont::DemiBold;
if (s == QLatin1String("black")
- || s.compare(QApplication::translate("QFontDatabase", "Black"), Qt::CaseInsensitive) == 0)
+ || s.compare(QCoreApplication::translate("QFontDatabase", "Black"), Qt::CaseInsensitive) == 0)
return QFont::Black;
if (s == QLatin1String("light"))
return QFont::Light;
if (s.contains(QLatin1String("bold"))
- || s.contains(QApplication::translate("QFontDatabase", "Bold"), Qt::CaseInsensitive)) {
+ || s.contains(QCoreApplication::translate("QFontDatabase", "Bold"), Qt::CaseInsensitive)) {
if (s.contains(QLatin1String("demi"))
- || s.compare(QApplication::translate("QFontDatabase", "Demi"), Qt::CaseInsensitive) == 0)
+ || s.compare(QCoreApplication::translate("QFontDatabase", "Demi"), Qt::CaseInsensitive) == 0)
return (int) QFont::DemiBold;
return (int) QFont::Bold;
}
if (s.contains(QLatin1String("light"))
- || s.compare(QApplication::translate("QFontDatabase", "Light"), Qt::CaseInsensitive) == 0)
+ || s.compare(QCoreApplication::translate("QFontDatabase", "Light"), Qt::CaseInsensitive) == 0)
return (int) QFont::Light;
if (s.contains(QLatin1String("black"))
- || s.compare(QApplication::translate("QFontDatabase", "Black"), Qt::CaseInsensitive) == 0)
+ || s.compare(QCoreApplication::translate("QFontDatabase", "Black"), Qt::CaseInsensitive) == 0)
return (int) QFont::Black;
return (int) QFont::Normal;
@@ -262,7 +262,7 @@ struct QtFontStyle
pixelSizes[count].fileName.~QByteArray();
#endif
#if defined (Q_WS_QPA)
- QPlatformIntegration *integration = QApplicationPrivate::platformIntegration();
+ QPlatformIntegration *integration = QGuiApplicationPrivate::platformIntegration();
if (integration) { //on shut down there will be some that we don't release.
integration->fontDatabase()->releaseHandle(pixelSizes[count].handle);
}
@@ -296,10 +296,10 @@ QtFontStyle::Key::Key(const QString &styleString)
weight = getFontWeight(styleString);
if (styleString.contains(QLatin1String("Italic"))
- || styleString.contains(QApplication::translate("QFontDatabase", "Italic")))
+ || styleString.contains(QCoreApplication::translate("QFontDatabase", "Italic")))
style = QFont::StyleItalic;
else if (styleString.contains(QLatin1String("Oblique"))
- || styleString.contains(QApplication::translate("QFontDatabase", "Oblique")))
+ || styleString.contains(QCoreApplication::translate("QFontDatabase", "Oblique")))
style = QFont::StyleOblique;
}
@@ -755,7 +755,7 @@ void QFontDatabasePrivate::invalidate()
{
QFontCache::instance()->clear();
free();
- emit static_cast<QApplication *>(QApplication::instance())->fontDatabaseChanged();
+ emit static_cast<QGuiApplication *>(QCoreApplication::instance())->fontDatabaseChanged();
}
QtFontFamily *QFontDatabasePrivate::family(const QString &f, bool create)
@@ -1520,21 +1520,21 @@ static QString styleStringHelper(int weight, QFont::Style style)
{
QString result;
if (weight >= QFont::Black)
- result = QApplication::translate("QFontDatabase", "Black");
+ result = QCoreApplication::translate("QFontDatabase", "Black");
else if (weight >= QFont::Bold)
- result = QApplication::translate("QFontDatabase", "Bold");
+ result = QCoreApplication::translate("QFontDatabase", "Bold");
else if (weight >= QFont::DemiBold)
- result = QApplication::translate("QFontDatabase", "Demi Bold");
+ result = QCoreApplication::translate("QFontDatabase", "Demi Bold");
else if (weight < QFont::Normal)
- result = QApplication::translate("QFontDatabase", "Light");
+ result = QCoreApplication::translate("QFontDatabase", "Light");
if (style == QFont::StyleItalic)
- result += QLatin1Char(' ') + QApplication::translate("QFontDatabase", "Italic");
+ result += QLatin1Char(' ') + QCoreApplication::translate("QFontDatabase", "Italic");
else if (style == QFont::StyleOblique)
- result += QLatin1Char(' ') + QApplication::translate("QFontDatabase", "Oblique");
+ result += QLatin1Char(' ') + QCoreApplication::translate("QFontDatabase", "Oblique");
if (result.isEmpty())
- result = QApplication::translate("QFontDatabase", "Normal");
+ result = QCoreApplication::translate("QFontDatabase", "Normal");
return result.simplified();
}
@@ -2026,7 +2026,7 @@ QFont QFontDatabase::font(const QString &family, const QString &style,
QtFontFoundry allStyles(foundryName);
QtFontFamily *f = d->family(familyName);
- if (!f) return QApplication::font();
+ if (!f) return QGuiApplication::font();
for (int j = 0; j < f->count; j++) {
QtFontFoundry *foundry = f->foundries[j];
@@ -2040,7 +2040,7 @@ QFont QFontDatabase::font(const QString &family, const QString &style,
QtFontStyle *s = bestStyle(&allStyles, styleKey, style);
if (!s) // no styles found?
- return QApplication::font();
+ return QGuiApplication::font();
QFont fnt(family, pointSize, s->key.weight);
fnt.setStyle((QFont::Style)s->key.style);
@@ -2363,7 +2363,7 @@ QString QFontDatabase::writingSystemName(WritingSystem writingSystem)
Q_ASSERT_X(false, "QFontDatabase::writingSystemName", "invalid 'writingSystem' parameter");
break;
}
- return QApplication::translate("QFontDatabase", name);
+ return QCoreApplication::translate("QFontDatabase", name);
}
diff --git a/src/gui/text/qfontdatabase.h b/src/gui/text/qfontdatabase.h
index b1f370e6d1..994a7a4a7d 100644
--- a/src/gui/text/qfontdatabase.h
+++ b/src/gui/text/qfontdatabase.h
@@ -45,10 +45,6 @@
#include <QtGui/qwindowdefs.h>
#include <QtCore/qstring.h>
#include <QtGui/qfont.h>
-#ifdef QT3_SUPPORT
-#include <QtCore/qstringlist.h>
-#include <QtCore/qlist.h>
-#endif
QT_BEGIN_HEADER
diff --git a/src/gui/text/qfontdatabase_qpa.cpp b/src/gui/text/qfontdatabase_qpa.cpp
index 032a42b9b1..c0edce1009 100644
--- a/src/gui/text/qfontdatabase_qpa.cpp
+++ b/src/gui/text/qfontdatabase_qpa.cpp
@@ -45,7 +45,7 @@
#include "qfontengine_qpa_p.h"
#include "qplatformdefs.h"
-#include <QtGui/private/qapplication_p.h>
+#include <QtGui/private/qguiapplication_p.h>
#include <QtGui/qplatformfontdatabase_qpa.h>
#include <QtCore/qmath.h>
@@ -82,7 +82,7 @@ Q_GUI_EXPORT void qt_registerFont(const QString &familyName, const QString &fou
static QStringList fallbackFamilies(const QString &family, const QFont::Style &style, const QFont::StyleHint &styleHint, const QUnicodeTables::Script &script)
{
- QStringList retList = QApplicationPrivate::platformIntegration()->fontDatabase()->fallbacksForFamily(family,style,styleHint,script);
+ QStringList retList = QGuiApplicationPrivate::platformIntegration()->fontDatabase()->fallbacksForFamily(family,style,styleHint,script);
QFontDatabasePrivate *db = privateDb();
QStringList::iterator i;
@@ -109,28 +109,11 @@ static void initializeDb()
if (!initialized) {
//init by asking for the platformfontdb for the first time :)
- QApplicationPrivate::platformIntegration()->fontDatabase()->populateFontDatabase();
+ QGuiApplicationPrivate::platformIntegration()->fontDatabase()->populateFontDatabase();
initialized = true;
}
}
-#ifndef QT_NO_SETTINGS
-// called from qapplication_qws.cpp
-void qt_applyFontDatabaseSettings(const QSettings &settings)
-{
- initializeDb();
- QFontDatabasePrivate *db = privateDb();
- for (int i = 0; i < db->count; ++i) {
- QtFontFamily *family = db->families[i];
- if (settings.contains(family->name))
- family->fallbackFamilies = settings.value(family->name).toStringList();
- }
-
- if (settings.contains(QLatin1String("Global Fallbacks")))
- db->fallbackFamilies = settings.value(QLatin1String("Global Fallbacks")).toStringList();
-}
-#endif // QT_NO_SETTINGS
-
static inline void load(const QString & = QString(), int = -1)
{
initializeDb();
@@ -155,7 +138,7 @@ QFontEngine *loadSingleEngine(int script,
QFontCache::Key key(def,script);
QFontEngine *engine = QFontCache::instance()->findEngine(key);
if (!engine) {
- QPlatformFontDatabase *pfdb = QApplicationPrivate::platformIntegration()->fontDatabase();
+ QPlatformFontDatabase *pfdb = QGuiApplicationPrivate::platformIntegration()->fontDatabase();
engine = pfdb->fontEngine(def,QUnicodeTables::Script(script),size->handle);
if (engine) {
QFontCache::Key key(def,script);
@@ -173,7 +156,7 @@ QFontEngine *loadEngine(int script, const QFontDef &request,
QFontEngine *engine = loadSingleEngine(script, request, foundry, style, size);
//make sure that the db has all fallback families
- if (engine
+ if (engine && engine->type() != QFontEngine::Multi
&& !(request.styleStrategy & QFont::NoFontMerging) && !engine->symbol ) {
if (family && !family->askedForFallback) {
@@ -200,7 +183,7 @@ static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt)
{
QFontDatabasePrivate *db = privateDb();
- fnt->families = QApplicationPrivate::platformIntegration()->fontDatabase()->addApplicationFont(fnt->data,fnt->fileName);
+ fnt->families = QGuiApplicationPrivate::platformIntegration()->fontDatabase()->addApplicationFont(fnt->data,fnt->fileName);
db->reregisterAppFonts = true;
}
@@ -359,7 +342,7 @@ void QFontDatabase::load(const QFontPrivate *d, int script)
family_list = familyList(req);
// add the default family
- QString defaultFamily = QApplication::font().family();
+ QString defaultFamily = QGuiApplication::font().family();
if (! family_list.contains(defaultFamily))
family_list << defaultFamily;
diff --git a/src/gui/text/qfontdatabase_qws.cpp b/src/gui/text/qfontdatabase_qws.cpp
deleted file mode 100644
index c83e9297d9..0000000000
--- a/src/gui/text/qfontdatabase_qws.cpp
+++ /dev/null
@@ -1,972 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qdir.h"
-#if defined(Q_WS_QWS)
-#include "qscreen_qws.h" //so we can check for rotation
-#include "qwindowsystem_qws.h"
-#endif
-#include "qlibraryinfo.h"
-#include "qabstractfileengine.h"
-#include <QtCore/qsettings.h>
-#if !defined(QT_NO_FREETYPE)
-#include "qfontengine_ft_p.h"
-
-#include <ft2build.h>
-#include FT_FREETYPE_H
-
-#endif
-#include "qfontengine_qpf_p.h"
-#include "private/qfactoryloader_p.h"
-#include "private/qcore_unix_p.h" // overrides QT_OPEN
-#include "qabstractfontengine_qws.h"
-#include "qabstractfontengine_p.h"
-#include <qdatetime.h>
-#include "qplatformdefs.h"
-
-// for mmap
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <fcntl.h>
-#include <errno.h>
-
-#ifdef QT_FONTS_ARE_RESOURCES
-#include <qresource.h>
-#endif
-
-QT_BEGIN_NAMESPACE
-
-#ifndef QT_NO_LIBRARY
-Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
- (QFontEngineFactoryInterface_iid, QLatin1String("/fontengines"), Qt::CaseInsensitive))
-#endif
-
-const quint8 DatabaseVersion = 4;
-
-// QFontDatabasePrivate::addFont() went into qfontdatabase.cpp
-
-#ifndef QT_NO_QWS_QPF2
-void QFontDatabasePrivate::addQPF2File(const QByteArray &file)
-{
-#ifndef QT_FONTS_ARE_RESOURCES
- struct stat st;
- if (stat(file.constData(), &st))
- return;
- int f = QT_OPEN(file, O_RDONLY, 0);
- if (f < 0)
- return;
- const uchar *data = (const uchar *)mmap(0, st.st_size, PROT_READ, MAP_SHARED, f, 0);
- const int dataSize = st.st_size;
-#else
- QResource res(QLatin1String(file.constData()));
- const uchar *data = res.data();
- const int dataSize = res.size();
- //qDebug() << "addQPF2File" << file << data;
-#endif
- if (data && data != (const uchar *)MAP_FAILED) {
- if (QFontEngineQPF::verifyHeader(data, dataSize)) {
- QString fontName = QFontEngineQPF::extractHeaderField(data, QFontEngineQPF::Tag_FontName).toString();
- int pixelSize = QFontEngineQPF::extractHeaderField(data, QFontEngineQPF::Tag_PixelSize).toInt();
- QVariant weight = QFontEngineQPF::extractHeaderField(data, QFontEngineQPF::Tag_Weight);
- QVariant style = QFontEngineQPF::extractHeaderField(data, QFontEngineQPF::Tag_Style);
- QByteArray writingSystemBits = QFontEngineQPF::extractHeaderField(data, QFontEngineQPF::Tag_WritingSystems).toByteArray();
-
- if (!fontName.isEmpty() && pixelSize) {
- int fontWeight = 50;
- if (weight.type() == QVariant::Int || weight.type() == QVariant::UInt)
- fontWeight = weight.toInt();
-
- bool italic = static_cast<QFont::Style>(style.toInt()) & QFont::StyleItalic;
-
- QList<QFontDatabase::WritingSystem> writingSystems;
- for (int i = 0; i < writingSystemBits.count(); ++i) {
- uchar currentByte = writingSystemBits.at(i);
- for (int j = 0; j < 8; ++j) {
- if (currentByte & 1)
- writingSystems << QFontDatabase::WritingSystem(i * 8 + j);
- currentByte >>= 1;
- }
- }
-
- addFont(fontName, /*foundry*/ "prerendered", fontWeight, italic,
- pixelSize, file, /*fileIndex*/ 0,
- /*antialiased*/ true, writingSystems);
- }
- } else {
- qDebug() << "header verification of QPF2 font" << file << "failed. maybe it is corrupt?";
- }
-#ifndef QT_FONTS_ARE_RESOURCES
- munmap((void *)data, st.st_size);
-#endif
- }
-#ifndef QT_FONTS_ARE_RESOURCES
- QT_CLOSE(f);
-#endif
-}
-#endif // QT_NO_QWS_QPF2
-
-// QFontDatabasePrivate::addTTFile() went into qfontdatabase.cpp
-
-static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt);
-
-extern QString qws_fontCacheDir();
-
-#ifndef QT_FONTS_ARE_RESOURCES
-bool QFontDatabasePrivate::loadFromCache(const QString &fontPath)
-{
-#ifdef Q_WS_QWS
- const bool weAreTheServer = QWSServer::instance();
-#else
- const bool weAreTheServer = true; // assume single-process
-#endif
-
- QString fontDirFile = fontPath + QLatin1String("/fontdir");
-
- QFile binaryDb(qws_fontCacheDir() + QLatin1String("/fontdb"));
-
- if (weAreTheServer) {
- QDateTime dbTimeStamp = QFileInfo(binaryDb.fileName()).lastModified();
-
- QDateTime fontPathTimeStamp = QFileInfo(fontPath).lastModified();
- if (dbTimeStamp < fontPathTimeStamp)
- return false; // let the caller create the cache
-
- if (QFile::exists(fontDirFile)) {
- QDateTime fontDirTimeStamp = QFileInfo(fontDirFile).lastModified();
- if (dbTimeStamp < fontDirTimeStamp)
- return false;
- }
- }
-
- if (!binaryDb.open(QIODevice::ReadOnly)) {
- if (weAreTheServer)
- return false; // let the caller create the cache
- qFatal("QFontDatabase::loadFromCache: Could not open font database cache!");
- }
-
- QDataStream stream(&binaryDb);
- quint8 version = 0;
- quint8 dataStreamVersion = 0;
- stream >> version >> dataStreamVersion;
- if (version != DatabaseVersion || dataStreamVersion != stream.version()) {
- if (weAreTheServer)
- return false; // let the caller create the cache
- qFatal("QFontDatabase::loadFromCache: Wrong version of the font database cache detected. Found %d/%d expected %d/%d",
- version, dataStreamVersion, DatabaseVersion, stream.version());
- }
-
- QString originalFontPath;
- stream >> originalFontPath;
- if (originalFontPath != fontPath) {
- if (weAreTheServer)
- return false; // let the caller create the cache
- qFatal("QFontDatabase::loadFromCache: Font path doesn't match. Found %s in database, expected %s", qPrintable(originalFontPath), qPrintable(fontPath));
- }
-
- QString familyname;
- stream >> familyname;
- //qDebug() << "populating database from" << binaryDb.fileName();
- while (!familyname.isEmpty() && !stream.atEnd()) {
- QString foundryname;
- int weight;
- quint8 italic;
- int pixelSize;
- QByteArray file;
- int fileIndex;
- quint8 antialiased;
- quint8 writingSystemCount;
-
- QList<QFontDatabase::WritingSystem> writingSystems;
-
- stream >> foundryname >> weight >> italic >> pixelSize
- >> file >> fileIndex >> antialiased >> writingSystemCount;
-
- for (quint8 i = 0; i < writingSystemCount; ++i) {
- quint8 ws;
- stream >> ws;
- writingSystems.append(QFontDatabase::WritingSystem(ws));
- }
-
- addFont(familyname, foundryname.toLatin1().constData(), weight, italic, pixelSize, file, fileIndex, antialiased,
- writingSystems);
-
- stream >> familyname;
- }
-
- stream >> fallbackFamilies;
- //qDebug() << "fallback families from cache:" << fallbackFamilies;
- return true;
-}
-#endif // QT_FONTS_ARE_RESOURCES
-
-/*!
- \internal
-*/
-
-static QString qwsFontPath()
-{
- QString fontpath = QString::fromLocal8Bit(qgetenv("QT_QWS_FONTDIR"));
- if (fontpath.isEmpty()) {
-#ifdef QT_FONTS_ARE_RESOURCES
- fontpath = QLatin1String(":/qt/fonts");
-#else
-#ifndef QT_NO_SETTINGS
- fontpath = QLibraryInfo::location(QLibraryInfo::LibrariesPath);
- fontpath += QLatin1String("/fonts");
-#else
- fontpath = QLatin1String("/lib/fonts");
-#endif
-#endif //QT_FONTS_ARE_RESOURCES
- }
-
- return fontpath;
-}
-
-#if defined(QFONTDATABASE_DEBUG) && defined(QT_FONTS_ARE_RESOURCES)
-class FriendlyResource : public QResource
-{
-public:
- bool isDir () const { return QResource::isDir(); }
- bool isFile () const { return QResource::isFile(); }
- QStringList children () const { return QResource::children(); }
-};
-#endif
-/*!
- \internal
-*/
-static void initializeDb()
-{
- QFontDatabasePrivate *db = privateDb();
- if (!db || db->count)
- return;
-
- QString fontpath = qwsFontPath();
-#ifndef QT_FONTS_ARE_RESOURCES
- QString fontDirFile = fontpath + QLatin1String("/fontdir");
-
- if(!QFile::exists(fontpath)) {
- qFatal("QFontDatabase: Cannot find font directory %s - is Qt installed correctly?",
- fontpath.toLocal8Bit().constData());
- }
-
- const bool loaded = db->loadFromCache(fontpath);
-
- if (db->reregisterAppFonts) {
- db->reregisterAppFonts = false;
- for (int i = 0; i < db->applicationFonts.count(); ++i)
- if (!db->applicationFonts.at(i).families.isEmpty()) {
- registerFont(&db->applicationFonts[i]);
- }
- }
-
- if (loaded)
- return;
-
- QString dbFileName = qws_fontCacheDir() + QLatin1String("/fontdb");
-
- QFile binaryDb(dbFileName + QLatin1String(".tmp"));
- binaryDb.open(QIODevice::WriteOnly | QIODevice::Truncate);
- db->stream = new QDataStream(&binaryDb);
- *db->stream << DatabaseVersion << quint8(db->stream->version()) << fontpath;
-// qDebug() << "creating binary database at" << binaryDb.fileName();
-
- // Load in font definition file
- FILE* fontdef=fopen(fontDirFile.toLocal8Bit().constData(),"r");
- if (fontdef) {
- char buf[200]="";
- char name[200]="";
- char render[200]="";
- char file[200]="";
- char isitalic[10]="";
- char flags[10]="";
- do {
- fgets(buf,200,fontdef);
- if (buf[0] != '#') {
- int weight=50;
- int size=0;
- sscanf(buf,"%s %s %s %s %d %d %s",name,file,render,isitalic,&weight,&size,flags);
- QString filename;
- if (file[0] != '/')
- filename.append(fontpath).append(QLatin1Char('/'));
- filename += QLatin1String(file);
- bool italic = isitalic[0] == 'y';
- bool smooth = QByteArray(flags).contains('s');
- if (file[0] && QFile::exists(filename))
- db->addFont(QString::fromUtf8(name), /*foundry*/"", weight, italic, size/10, QFile::encodeName(filename), /*fileIndex*/ 0, smooth);
- }
- } while (!feof(fontdef));
- fclose(fontdef);
- }
-
-
- QDir dir(fontpath, QLatin1String("*.qpf"));
- for (int i=0; i<int(dir.count()); i++) {
- int u0 = dir[i].indexOf(QLatin1Char('_'));
- int u1 = dir[i].indexOf(QLatin1Char('_'), u0+1);
- int u2 = dir[i].indexOf(QLatin1Char('_'), u1+1);
- int u3 = dir[i].indexOf(QLatin1Char('.'), u1+1);
- if (u2 < 0) u2 = u3;
-
- QString familyname = dir[i].left(u0);
- int pixelSize = dir[i].mid(u0+1,u1-u0-1).toInt()/10;
- bool italic = dir[i].mid(u2-1,1) == QLatin1String("i");
- int weight = dir[i].mid(u1+1,u2-u1-1-(italic?1:0)).toInt();
-
- db->addFont(familyname, /*foundry*/ "qt", weight, italic, pixelSize, QFile::encodeName(dir.absoluteFilePath(dir[i])),
- /*fileIndex*/ 0, /*antialiased*/ true);
- }
-
-#ifndef QT_NO_FREETYPE
- dir.setNameFilters(QStringList() << QLatin1String("*.ttf")
- << QLatin1String("*.ttc") << QLatin1String("*.pfa")
- << QLatin1String("*.pfb"));
- dir.refresh();
- for (int i = 0; i < int(dir.count()); ++i) {
- const QByteArray file = QFile::encodeName(dir.absoluteFilePath(dir[i]));
-// qDebug() << "looking at" << file;
- db->addTTFile(file);
- }
-#endif
-
-#ifndef QT_NO_QWS_QPF2
- dir.setNameFilters(QStringList() << QLatin1String("*.qpf2"));
- dir.refresh();
- for (int i = 0; i < int(dir.count()); ++i) {
- const QByteArray file = QFile::encodeName(dir.absoluteFilePath(dir[i]));
-// qDebug() << "looking at" << file;
- db->addQPF2File(file);
- }
-#endif
-
-#else //QT_FONTS_ARE_RESOURCES
-#ifdef QFONTDATABASE_DEBUG
- {
- QResource fontdir(fontpath);
- FriendlyResource *fr = static_cast<FriendlyResource*>(&fontdir);
- qDebug() << "fontdir" << fr->isValid() << fr->isDir() << fr->children();
-
- }
-#endif
-#ifndef QT_NO_QWS_QPF2
- QDir dir(fontpath, QLatin1String("*.qpf2"));
- for (int i = 0; i < int(dir.count()); ++i) {
- const QByteArray file = QFile::encodeName(dir.absoluteFilePath(dir[i]));
- //qDebug() << "looking at" << file;
- db->addQPF2File(file);
- }
-#endif
-#endif //QT_FONTS_ARE_RESOURCES
-
-
-#ifdef QFONTDATABASE_DEBUG
- // print the database
- for (int f = 0; f < db->count; f++) {
- QtFontFamily *family = db->families[f];
- FD_DEBUG("'%s' %s", qPrintable(family->name), (family->fixedPitch ? "fixed" : ""));
-#if 0
- for (int i = 0; i < QFont::LastPrivateScript; ++i) {
- FD_DEBUG("\t%s: %s", qPrintable(QFontDatabase::scriptName((QFont::Script) i)),
- ((family->scripts[i] & QtFontFamily::Supported) ? "Supported" :
- (family->scripts[i] & QtFontFamily::UnSupported) == QtFontFamily::UnSupported ?
- "UnSupported" : "Unknown"));
- }
-#endif
-
- for (int fd = 0; fd < family->count; fd++) {
- QtFontFoundry *foundry = family->foundries[fd];
- FD_DEBUG("\t\t'%s'", qPrintable(foundry->name));
- for (int s = 0; s < foundry->count; s++) {
- QtFontStyle *style = foundry->styles[s];
- FD_DEBUG("\t\t\tstyle: style=%d weight=%d\n"
- "\t\t\tstretch=%d",
- style->key.style, style->key.weight,
- style->key.stretch);
- if (style->smoothScalable)
- FD_DEBUG("\t\t\t\tsmooth scalable");
- else if (style->bitmapScalable)
- FD_DEBUG("\t\t\t\tbitmap scalable");
- if (style->pixelSizes) {
- FD_DEBUG("\t\t\t\t%d pixel sizes", style->count);
- for (int z = 0; z < style->count; ++z) {
- QtFontSize *size = style->pixelSizes + z;
- FD_DEBUG("\t\t\t\t size %5d",
- size->pixelSize);
- }
- }
- }
- }
- }
-#endif // QFONTDATABASE_DEBUG
-
-#ifndef QT_NO_LIBRARY
- QStringList pluginFoundries = loader()->keys();
-// qDebug() << "plugin foundries:" << pluginFoundries;
- for (int i = 0; i < pluginFoundries.count(); ++i) {
- const QString foundry(pluginFoundries.at(i));
-
- QFontEngineFactoryInterface *factory = qobject_cast<QFontEngineFactoryInterface *>(loader()->instance(foundry));
- if (!factory) {
- qDebug() << "Could not load plugin for foundry" << foundry;
- continue;
- }
-
- QList<QFontEngineInfo> fonts = factory->availableFontEngines();
- for (int i = 0; i < fonts.count(); ++i) {
- QFontEngineInfo info = fonts.at(i);
-
- int weight = info.weight();
- if (weight <= 0)
- weight = QFont::Normal;
-
- db->addFont(info.family(), foundry.toLatin1().constData(),
- weight, info.style() != QFont::StyleNormal,
- qRound(info.pixelSize()), /*file*/QByteArray(),
- /*fileIndex*/0, /*antiAliased*/true,
- info.writingSystems());
- }
- }
-#endif
-
-#ifndef QT_FONTS_ARE_RESOURCES
- // the empty string/familyname signifies the end of the font list.
- *db->stream << QString();
-#endif
- {
- bool coveredWritingSystems[QFontDatabase::WritingSystemsCount] = { 0 };
-
- db->fallbackFamilies.clear();
-
- for (int i = 0; i < db->count; ++i) {
- QtFontFamily *family = db->families[i];
- bool add = false;
- if (family->count == 0)
- continue;
- if (family->bogusWritingSystems)
- continue;
- for (int ws = 1; ws < QFontDatabase::WritingSystemsCount; ++ws) {
- if (coveredWritingSystems[ws])
- continue;
- if (family->writingSystems[ws] & QtFontFamily::Supported) {
- coveredWritingSystems[ws] = true;
- add = true;
- }
- }
- if (add)
- db->fallbackFamilies << family->name;
- }
- //qDebug() << "fallbacks on the server:" << db->fallbackFamilies;
-#ifndef QT_FONTS_ARE_RESOURCES
- *db->stream << db->fallbackFamilies;
-#endif
- }
-#ifndef QT_FONTS_ARE_RESOURCES
- delete db->stream;
- db->stream = 0;
- QFile::remove(dbFileName);
- binaryDb.rename(dbFileName);
-#endif
-}
-
-// called from qwindowsystem_qws.cpp
-void qt_qws_init_fontdb()
-{
- initializeDb();
-}
-
-#ifndef QT_NO_SETTINGS
-// called from qapplication_qws.cpp
-void qt_applyFontDatabaseSettings(const QSettings &settings)
-{
- initializeDb();
- QFontDatabasePrivate *db = privateDb();
- for (int i = 0; i < db->count; ++i) {
- QtFontFamily *family = db->families[i];
- if (settings.contains(family->name))
- family->fallbackFamilies = settings.value(family->name).toStringList();
- }
-
- if (settings.contains(QLatin1String("Global Fallbacks")))
- db->fallbackFamilies = settings.value(QLatin1String("Global Fallbacks")).toStringList();
-}
-#endif // QT_NO_SETTINGS
-
-static inline void load(const QString & = QString(), int = -1)
-{
- initializeDb();
-}
-
-#ifndef QT_NO_FREETYPE
-
-#if (FREETYPE_MAJOR*10000+FREETYPE_MINOR*100+FREETYPE_PATCH) >= 20105
-#define X_SIZE(face,i) ((face)->available_sizes[i].x_ppem)
-#define Y_SIZE(face,i) ((face)->available_sizes[i].y_ppem)
-#else
-#define X_SIZE(face,i) ((face)->available_sizes[i].width << 6)
-#define Y_SIZE(face,i) ((face)->available_sizes[i].height << 6)
-#endif
-
-#endif // QT_NO_FREETYPE
-
-static
-QFontEngine *loadSingleEngine(int script, const QFontPrivate *fp,
- const QFontDef &request,
- QtFontFamily *family, QtFontFoundry *foundry,
- QtFontStyle *style, QtFontSize *size)
-{
- Q_UNUSED(script);
- Q_UNUSED(fp);
-#ifdef QT_NO_FREETYPE
- Q_UNUSED(foundry);
-#endif
-#ifdef QT_NO_QWS_QPF
- Q_UNUSED(family);
-#endif
- Q_ASSERT(size);
-
- int pixelSize = size->pixelSize;
- if (!pixelSize || (style->smoothScalable && pixelSize == SMOOTH_SCALABLE))
- pixelSize = request.pixelSize;
-
-#ifndef QT_NO_QWS_QPF2
- if (foundry->name == QLatin1String("prerendered")) {
-#ifdef QT_FONTS_ARE_RESOURCES
- QResource res(QLatin1String(size->fileName.constData()));
- if (res.isValid()) {
- QFontEngineQPF *fe = new QFontEngineQPF(request, res.data(), res.size());
- if (fe->isValid())
- return fe;
- delete fe;
- qDebug() << "fontengine is not valid! " << size->fileName;
- } else {
- qDebug() << "Resource not valid" << size->fileName;
- }
-#else
- int f = ::open(size->fileName, O_RDONLY, 0);
- if (f >= 0) {
- QFontEngineQPF *fe = new QFontEngineQPF(request, f);
- if (fe->isValid())
- return fe;
- delete fe; // will close f
- qDebug() << "fontengine is not valid!";
- }
-#endif
- } else
-#endif
- if ( foundry->name != QLatin1String("qt") ) { ///#### is this the best way????
- QString file = QFile::decodeName(size->fileName);
-
- QFontDef def = request;
- def.pixelSize = pixelSize;
-
-#ifdef QT_NO_QWS_SHARE_FONTS
- bool shareFonts = false;
-#else
- static bool dontShareFonts = !qgetenv("QWS_NO_SHARE_FONTS").isEmpty();
- bool shareFonts = !dontShareFonts;
-#endif
-
- QScopedPointer<QFontEngine> engine;
-
-#ifndef QT_NO_LIBRARY
- QFontEngineFactoryInterface *factory = qobject_cast<QFontEngineFactoryInterface *>(loader()->instance(foundry->name));
- if (factory) {
- QFontEngineInfo info;
- info.setFamily(request.family);
- info.setPixelSize(request.pixelSize);
- info.setStyle(QFont::Style(request.style));
- info.setWeight(request.weight);
- // #### antialiased
-
- QAbstractFontEngine *customEngine = factory->create(info);
- if (customEngine) {
- engine.reset(new QProxyFontEngine(customEngine, def));
-
- if (shareFonts) {
- QVariant hint = customEngine->fontProperty(QAbstractFontEngine::CacheGlyphsHint);
- if (hint.isValid())
- shareFonts = hint.toBool();
- else
- shareFonts = (pixelSize < 64);
- }
- }
- }
-#endif // QT_NO_LIBRARY
- if ((engine.isNull() && !file.isEmpty() && QFile::exists(file)) || privateDb()->isApplicationFont(file)) {
- QFontEngine::FaceId faceId;
- faceId.filename = file.toLocal8Bit();
- faceId.index = size->fileIndex;
-
-#ifndef QT_NO_FREETYPE
-
- QScopedPointer<QFontEngineFT> fte(new QFontEngineFT(def));
- bool antialias = style->antialiased && !(request.styleStrategy & QFont::NoAntialias);
- if (fte->init(faceId, antialias,
- antialias ? QFontEngineFT::Format_A8 : QFontEngineFT::Format_Mono)) {
-#ifdef QT_NO_QWS_QPF2
- return fte.take();
-#else
- // try to distinguish between bdf and ttf fonts we can pre-render
- // and don't try to share outline fonts
- shareFonts = shareFonts
- && !fte->defaultGlyphs()->outline_drawing
- && !fte->getSfntTable(MAKE_TAG('h', 'e', 'a', 'd')).isEmpty();
- engine.reset(fte.take());
-#endif
- }
-#endif // QT_NO_FREETYPE
- }
- if (!engine.isNull()) {
-#if !defined(QT_NO_QWS_QPF2) && !defined(QT_FONTS_ARE_RESOURCES)
- if (shareFonts) {
- QScopedPointer<QFontEngineQPF> fe(new QFontEngineQPF(def, -1, engine.data()));
- engine.take();
- if (fe->isValid())
- return fe.take();
- qWarning("Initializing QFontEngineQPF failed for %s", qPrintable(file));
- engine.reset(fe->takeRenderingEngine());
- }
-#endif
- return engine.take();
- }
- } else
- {
-#ifndef QT_NO_QWS_QPF
- QString fn = qwsFontPath();
- fn += QLatin1Char('/');
- fn += family->name.toLower()
- + QLatin1Char('_') + QString::number(pixelSize*10)
- + QLatin1Char('_') + QString::number(style->key.weight)
- + (style->key.style == QFont::StyleItalic ?
- QLatin1String("i.qpf") : QLatin1String(".qpf"));
- //###rotation ###
-
- QFontEngine *fe = new QFontEngineQPF1(request, fn);
- return fe;
-#endif // QT_NO_QWS_QPF
- }
- return new QFontEngineBox(pixelSize);
-}
-
-static
-QFontEngine *loadEngine(int script, const QFontPrivate *fp,
- const QFontDef &request,
- QtFontFamily *family, QtFontFoundry *foundry,
- QtFontStyle *style, QtFontSize *size)
-{
- QScopedPointer<QFontEngine> engine(loadSingleEngine(script, fp, request, family, foundry,
- style, size));
-#ifndef QT_NO_QWS_QPF
- if (!engine.isNull()
- && script == QUnicodeTables::Common
- && !(request.styleStrategy & QFont::NoFontMerging) && !engine->symbol) {
-
- QStringList fallbacks = privateDb()->fallbackFamilies;
-
- if (family && !family->fallbackFamilies.isEmpty())
- fallbacks = family->fallbackFamilies;
-
- QFontEngine *fe = new QFontEngineMultiQWS(engine.data(), script, fallbacks);
- engine.take();
- engine.reset(fe);
- }
-#endif
- return engine.take();
-}
-
-static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt)
-{
- QFontDatabasePrivate *db = privateDb();
-#ifdef QT_NO_FREETYPE
- Q_UNUSED(fnt);
-#else
- fnt->families = db->addTTFile(QFile::encodeName(fnt->fileName), fnt->data);
- db->fallbackFamilies += fnt->families;
-#endif
- db->reregisterAppFonts = true;
-}
-
-bool QFontDatabase::removeApplicationFont(int handle)
-{
- QMutexLocker locker(fontDatabaseMutex());
-
- QFontDatabasePrivate *db = privateDb();
- if (handle < 0 || handle >= db->applicationFonts.count())
- return false;
-
- db->applicationFonts[handle] = QFontDatabasePrivate::ApplicationFont();
-
- db->reregisterAppFonts = true;
- db->invalidate();
- return true;
-}
-
-bool QFontDatabase::removeAllApplicationFonts()
-{
- QMutexLocker locker(fontDatabaseMutex());
-
- QFontDatabasePrivate *db = privateDb();
- if (db->applicationFonts.isEmpty())
- return false;
-
- db->applicationFonts.clear();
- db->invalidate();
- return true;
-}
-
-bool QFontDatabase::supportsThreadedFontRendering()
-{
- return true;
-}
-
-QFontEngine *
-QFontDatabase::findFont(int script, const QFontPrivate *fp,
- const QFontDef &request)
-{
- QMutexLocker locker(fontDatabaseMutex());
-
- const int force_encoding_id = -1;
-
- if (!privateDb()->count)
- initializeDb();
-
- QScopedPointer<QFontEngine> fe;
- if (fp) {
- if (fp->rawMode) {
- fe.reset(loadEngine(script, fp, request, 0, 0, 0, 0));
-
- // if we fail to load the rawmode font, use a 12pixel box engine instead
- if (fe.isNull())
- fe.reset(new QFontEngineBox(12));
- return fe.take();
- }
-
- QFontCache::Key key(request, script);
- fe.reset(QFontCache::instance()->findEngine(key));
- if (! fe.isNull())
- return fe.take();
- }
-
- QString family_name, foundry_name;
- QtFontStyle::Key styleKey;
- styleKey.style = request.style;
- styleKey.weight = request.weight;
- styleKey.stretch = request.stretch;
- char pitch = request.ignorePitch ? '*' : request.fixedPitch ? 'm' : 'p';
-
- parseFontName(request.family, foundry_name, family_name);
-
- FM_DEBUG("QFontDatabase::findFont\n"
- " request:\n"
- " family: %s [%s], script: %d\n"
- " weight: %d, style: %d\n"
- " stretch: %d\n"
- " pixelSize: %g\n"
- " pitch: %c",
- family_name.isEmpty() ? "-- first in script --" : family_name.toLatin1().constData(),
- foundry_name.isEmpty() ? "-- any --" : foundry_name.toLatin1().constData(),
- script, request.weight, request.style, request.stretch, request.pixelSize, pitch);
-
- if (qt_enable_test_font && request.family == QLatin1String("__Qt__Box__Engine__")) {
- fe.reset(new QTestFontEngine(request.pixelSize));
- fe->fontDef = request;
- }
-
- if (fe.isNull())
- {
- QtFontDesc desc;
- match(script, request, family_name, foundry_name, force_encoding_id, &desc);
-
- if (desc.family != 0 && desc.foundry != 0 && desc.style != 0
- ) {
- FM_DEBUG(" BEST:\n"
- " family: %s [%s]\n"
- " weight: %d, style: %d\n"
- " stretch: %d\n"
- " pixelSize: %d\n"
- " pitch: %c\n"
- " encoding: %d\n",
- desc.family->name.toLatin1().constData(),
- desc.foundry->name.isEmpty() ? "-- none --" : desc.foundry->name.toLatin1().constData(),
- desc.style->key.weight, desc.style->key.style,
- desc.style->key.stretch, desc.size ? desc.size->pixelSize : 0xffff,
- 'p', 0
- );
-
- fe.reset(loadEngine(script, fp, request, desc.family, desc.foundry, desc.style, desc.size
- ));
- } else {
- FM_DEBUG(" NO MATCH FOUND\n");
- }
- if (! fe.isNull())
- initFontDef(desc, request, &fe->fontDef);
- }
-
-#ifndef QT_NO_FREETYPE
- if (! fe.isNull()) {
- if (scriptRequiresOpenType(script) && fe->type() == QFontEngine::Freetype) {
- HB_Face hbFace = static_cast<QFontEngineFT *>(fe.data())->harfbuzzFace();
- if (!hbFace || !hbFace->supported_scripts[script]) {
- FM_DEBUG(" OpenType support missing for script\n");
- fe.reset(0);
- }
- }
- }
-#endif
-
- if (! fe.isNull()) {
- if (fp) {
- QFontDef def = request;
- if (def.family.isEmpty()) {
- def.family = fp->request.family;
- def.family = def.family.left(def.family.indexOf(QLatin1Char(',')));
- }
- QFontCache::Key key(def, script);
- QFontCache::instance()->insertEngine(key, fe.data());
- }
- }
-
- if (fe.isNull()) {
- if (!request.family.isEmpty())
- return 0;
-
- FM_DEBUG("returning box engine");
-
- fe.reset(new QFontEngineBox(request.pixelSize));
-
- if (fp) {
- QFontCache::Key key(request, script);
- QFontCache::instance()->insertEngine(key, fe.data());
- }
- }
-
- if (fp && fp->dpi > 0) {
- fe->fontDef.pointSize = qreal(double((fe->fontDef.pixelSize * 72) / fp->dpi));
- } else {
- fe->fontDef.pointSize = request.pointSize;
- }
-
- return fe.take();
-}
-
-void QFontDatabase::load(const QFontPrivate *d, int script)
-{
- QFontDef req = d->request;
-
- if (req.pixelSize == -1)
- req.pixelSize = qRound(req.pointSize*d->dpi/72);
- if (req.pointSize < 0)
- req.pointSize = req.pixelSize*72.0/d->dpi;
-
- if (!d->engineData) {
- QFontCache::Key key(req, script);
-
- // look for the requested font in the engine data cache
- d->engineData = QFontCache::instance()->findEngineData(key);
-
- if (!d->engineData) {
- // create a new one
- d->engineData = new QFontEngineData;
- QT_TRY {
- QFontCache::instance()->insertEngineData(key, d->engineData);
- } QT_CATCH(...) {
- delete d->engineData;
- d->engineData = 0;
- QT_RETHROW;
- }
- } else {
- d->engineData->ref.ref();
- }
- }
-
- // the cached engineData could have already loaded the engine we want
- if (d->engineData->engines[script]) return;
-
- // double scale = 1.0; // ### TODO: fix the scale calculations
-
- // list of families to try
- QStringList family_list;
-
- if (!req.family.isEmpty()) {
- family_list = req.family.split(QLatin1Char(','));
-
- // append the substitute list for each family in family_list
- QStringList subs_list;
- QStringList::ConstIterator it = family_list.constBegin(), end = family_list.constEnd();
- for (; it != end; ++it)
- subs_list += QFont::substitutes(*it);
- family_list += subs_list;
-
- // append the default fallback font for the specified script
- // family_list << ... ; ###########
-
- // add the default family
- QString defaultFamily = QApplication::font().family();
- if (! family_list.contains(defaultFamily))
- family_list << defaultFamily;
-
- // add QFont::defaultFamily() to the list, for compatibility with
- // previous versions
- family_list << QApplication::font().defaultFamily();
- }
-
- // null family means find the first font matching the specified script
- family_list << QString();
-
- // load the font
- QFontEngine *engine = 0;
- QStringList::ConstIterator it = family_list.constBegin(), end = family_list.constEnd();
- for (; !engine && it != end; ++it) {
- req.family = *it;
-
- engine = QFontDatabase::findFont(script, d, req);
- if (engine && (engine->type()==QFontEngine::Box) && !req.family.isEmpty())
- engine = 0;
- }
-
- engine->ref.ref();
- d->engineData->engines[script] = engine;
-}
-
-
-QT_END_NAMESPACE
diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp
index 2cf0fdb040..f7f3b0e900 100644
--- a/src/gui/text/qfontengine.cpp
+++ b/src/gui/text/qfontengine.cpp
@@ -280,6 +280,8 @@ void QFontEngine::getGlyphPositions(const QGlyphLayout &glyphs, const QTransform
int i = glyphs.numGlyphs;
int totalKashidas = 0;
while(i--) {
+ if (glyphs.attributes[i].dontPrint)
+ continue;
xpos += glyphs.advances_x[i] + QFixed::fromFixed(glyphs.justifications[i].space_18d6);
ypos += glyphs.advances_y[i];
totalKashidas += glyphs.justifications[i].nKashidas;
@@ -1680,11 +1682,42 @@ bool QFontEngineMulti::canRender(const QChar *string, int len)
return allExist;
}
-QImage QFontEngineMulti::alphaMapForGlyph(glyph_t)
+/* Implement alphaMapForGlyph() which is called by Lighthouse/Windows code.
+ * Ideally, that code should be fixed to correctly handle QFontEngineMulti. */
+
+QImage QFontEngineMulti::alphaMapForGlyph(glyph_t glyph)
+{
+ const int which = highByte(glyph);
+ Q_ASSERT(which < engines.size());
+ return engine(which)->alphaMapForGlyph(stripped(glyph));
+}
+
+QImage QFontEngineMulti::alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition)
{
- Q_ASSERT(false);
- return QImage();
+ const int which = highByte(glyph);
+ Q_ASSERT(which < engines.size());
+ return engine(which)->alphaMapForGlyph(stripped(glyph), subPixelPosition);
}
+QImage QFontEngineMulti::alphaMapForGlyph(glyph_t glyph, const QTransform &t)
+{
+ const int which = highByte(glyph);
+ Q_ASSERT(which < engines.size());
+ return engine(which)->alphaMapForGlyph(stripped(glyph), t);
+}
+
+QImage QFontEngineMulti::alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &t)
+{
+ const int which = highByte(glyph);
+ Q_ASSERT(which < engines.size());
+ return engine(which)->alphaMapForGlyph(stripped(glyph), subPixelPosition, t);
+}
+
+QImage QFontEngineMulti::alphaRGBMapForGlyph(glyph_t glyph, QFixed subPixelPosition, int margin, const QTransform &t)
+{
+ const int which = highByte(glyph);
+ Q_ASSERT(which < engines.size());
+ return engine(which)->alphaRGBMapForGlyph(stripped(glyph), subPixelPosition, margin, t);
+}
QT_END_NAMESPACE
diff --git a/src/gui/text/qfontengine_ft_p.h b/src/gui/text/qfontengine_ft_p.h
index bd8e24a3fe..e320be4421 100644
--- a/src/gui/text/qfontengine_ft_p.h
+++ b/src/gui/text/qfontengine_ft_p.h
@@ -51,7 +51,7 @@
// We mean it.
//
-#include "qfontengine_p.h"
+#include "private/qfontengine_p.h"
#ifndef QT_NO_FREETYPE
diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h
index e9a8d6f607..a5858ffc7d 100644
--- a/src/gui/text/qfontengine_p.h
+++ b/src/gui/text/qfontengine_p.h
@@ -394,7 +394,7 @@ private:
int _size;
};
-class QFontEngineMulti : public QFontEngine
+class Q_GUI_EXPORT QFontEngineMulti : public QFontEngine
{
public:
explicit QFontEngineMulti(int engineCount);
@@ -417,6 +417,10 @@ public:
virtual QFixed xHeight() const;
virtual QFixed averageCharWidth() const;
virtual QImage alphaMapForGlyph(glyph_t);
+ virtual QImage alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition);
+ virtual QImage alphaMapForGlyph(glyph_t, const QTransform &t);
+ virtual QImage alphaMapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t);
+ virtual QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, int margin, const QTransform &t);
virtual QFixed lineThickness() const;
virtual QFixed underlinePosition() const;
diff --git a/src/gui/text/qfontengine_qpa.cpp b/src/gui/text/qfontengine_qpa.cpp
index c829c2f875..7c09ae7cf8 100644
--- a/src/gui/text/qfontengine_qpa.cpp
+++ b/src/gui/text/qfontengine_qpa.cpp
@@ -46,7 +46,6 @@
#include <QtCore/QDir>
#include <QtCore/QBuffer>
-#include <QtGui/private/qapplication_p.h>
#include <QtGui/QPlatformFontDatabase>
#include <QtGui/private/qpaintengine_raster_p.h>
@@ -664,9 +663,11 @@ QFontEngineMultiQPA::QFontEngineMultiQPA(QFontEngine *fe, int _script, const QSt
: QFontEngineMulti(fallbacks.size() + 1),
fallbackFamilies(fallbacks), script(_script)
{
+ Q_ASSERT(fe && fe->type() != QFontEngine::Multi);
engines[0] = fe;
fe->ref.ref();
fontDef = engines[0]->fontDef;
+ setObjectName(QStringLiteral("QFontEngineMultiQPA"));
}
void QFontEngineMultiQPA::loadEngine(int at)
diff --git a/src/gui/text/qfontengine_qws.cpp b/src/gui/text/qfontengine_qws.cpp
deleted file mode 100644
index fe2e002e5d..0000000000
--- a/src/gui/text/qfontengine_qws.cpp
+++ /dev/null
@@ -1,662 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qfontengine_p.h"
-#include <private/qunicodetables_p.h>
-#include <qwsdisplay_qws.h>
-#include <qvarlengtharray.h>
-#include <private/qpainter_p.h>
-#include <private/qpaintengine_raster_p.h>
-#include <private/qpdf_p.h>
-#include "qtextengine_p.h"
-#include "private/qcore_unix_p.h" // overrides QT_OPEN
-
-#include <qdebug.h>
-
-
-#ifndef QT_NO_QWS_QPF
-
-#include "qfile.h"
-#include "qdir.h"
-
-#define QT_USE_MMAP
-#include <stdlib.h>
-
-#ifdef QT_USE_MMAP
-// for mmap
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <fcntl.h>
-#include <errno.h>
-
-# if defined(QT_LINUXBASE) && !defined(MAP_FILE)
- // LSB 3.2 does not define MAP_FILE
-# define MAP_FILE 0
-# endif
-
-#endif
-
-#endif // QT_NO_QWS_QPF
-
-QT_BEGIN_NAMESPACE
-
-#ifndef QT_NO_QWS_QPF
-QT_BEGIN_INCLUDE_NAMESPACE
-#include "qplatformdefs.h"
-QT_END_INCLUDE_NAMESPACE
-
-static inline unsigned int getChar(const QChar *str, int &i, const int len)
-{
- uint ucs4 = str[i].unicode();
- if (str[i].isHighSurrogate() && i < len-1 && str[i+1].isLowSurrogate()) {
- ++i;
- ucs4 = QChar::surrogateToUcs4(ucs4, str[i].unicode());
- }
- return ucs4;
-}
-
-#define FM_SMOOTH 1
-
-
-class Q_PACKED QPFGlyphMetrics {
-
-public:
- quint8 linestep;
- quint8 width;
- quint8 height;
- quint8 flags;
-
- qint8 bearingx; // Difference from pen position to glyph's left bbox
- quint8 advance; // Difference between pen positions
- qint8 bearingy; // Used for putting characters on baseline
-
- qint8 reserved; // Do not use
-
- // Flags:
- // RendererOwnsData - the renderer is responsible for glyph data
- // memory deletion otherwise QPFGlyphTree must
- // delete [] the data when the glyph is deleted.
- enum Flags { RendererOwnsData=0x01 };
-};
-
-class QPFGlyph {
-public:
- QPFGlyph() { metrics=0; data=0; }
- QPFGlyph(QPFGlyphMetrics* m, uchar* d) :
- metrics(m), data(d) { }
- ~QPFGlyph() {}
-
- QPFGlyphMetrics* metrics;
- uchar* data;
-};
-
-struct Q_PACKED QPFFontMetrics{
- qint8 ascent,descent;
- qint8 leftbearing,rightbearing;
- quint8 maxwidth;
- qint8 leading;
- quint8 flags;
- quint8 underlinepos;
- quint8 underlinewidth;
- quint8 reserved3;
-};
-
-
-class QPFGlyphTree {
-public:
- /* reads in a tree like this:
-
- A-Z
- / \
- 0-9 a-z
-
- etc.
-
- */
- glyph_t min,max;
- QPFGlyphTree* less;
- QPFGlyphTree* more;
- QPFGlyph* glyph;
-public:
-#ifdef QT_USE_MMAP
- QPFGlyphTree(uchar*& data)
- {
- read(data);
- }
-#else
- QPFGlyphTree(QIODevice& f)
- {
- read(f);
- }
-#endif
-
- ~QPFGlyphTree()
- {
- // NOTE: does not delete glyph[*].metrics or .data.
- // the caller does this (only they know who owns
- // the data). See clear().
- delete less;
- delete more;
- delete [] glyph;
- }
-
- bool inFont(glyph_t g) const
- {
- if ( g < min ) {
- if ( !less )
- return false;
- return less->inFont(g);
- } else if ( g > max ) {
- if ( !more )
- return false;
- return more->inFont(g);
- }
- return true;
- }
-
- QPFGlyph* get(glyph_t g)
- {
- if ( g < min ) {
- if ( !less )
- return 0;
- return less->get(g);
- } else if ( g > max ) {
- if ( !more )
- return 0;
- return more->get(g);
- }
- return &glyph[g - min];
- }
- int totalChars() const
- {
- if ( !this ) return 0;
- return max-min+1 + less->totalChars() + more->totalChars();
- }
- int weight() const
- {
- if ( !this ) return 0;
- return 1 + less->weight() + more->weight();
- }
-
- void dump(int indent=0)
- {
- for (int i=0; i<indent; i++) printf(" ");
- printf("%d..%d",min,max);
- //if ( indent == 0 )
- printf(" (total %d)",totalChars());
- printf("\n");
- if ( less ) less->dump(indent+1);
- if ( more ) more->dump(indent+1);
- }
-
-private:
- QPFGlyphTree()
- {
- }
-
-#ifdef QT_USE_MMAP
- void read(uchar*& data)
- {
- // All node data first
- readNode(data);
- // Then all non-video data
- readMetrics(data);
- // Then all video data
- readData(data);
- }
-#else
- void read(QIODevice& f)
- {
- // All node data first
- readNode(f);
- // Then all non-video data
- readMetrics(f);
- // Then all video data
- readData(f);
- }
-#endif
-
-#ifdef QT_USE_MMAP
- void readNode(uchar*& data)
- {
- uchar rw = *data++;
- uchar cl = *data++;
- min = (rw << 8) | cl;
- rw = *data++;
- cl = *data++;
- max = (rw << 8) | cl;
- int flags = *data++;
- if ( flags & 1 )
- less = new QPFGlyphTree;
- else
- less = 0;
- if ( flags & 2 )
- more = new QPFGlyphTree;
- else
- more = 0;
- int n = max-min+1;
- glyph = new QPFGlyph[n];
-
- if ( less )
- less->readNode(data);
- if ( more )
- more->readNode(data);
- }
-#else
- void readNode(QIODevice& f)
- {
- char rw;
- char cl;
- f.getChar(&rw);
- f.getChar(&cl);
- min = (rw << 8) | cl;
- f.getChar(&rw);
- f.getChar(&cl);
- max = (rw << 8) | cl;
- char flags;
- f.getChar(&flags);
- if ( flags & 1 )
- less = new QPFGlyphTree;
- else
- less = 0;
- if ( flags & 2 )
- more = new QPFGlyphTree;
- else
- more = 0;
- int n = max-min+1;
- glyph = new QPFGlyph[n];
-
- if ( less )
- less->readNode(f);
- if ( more )
- more->readNode(f);
- }
-#endif
-
-#ifdef QT_USE_MMAP
- void readMetrics(uchar*& data)
- {
- int n = max-min+1;
- for (int i=0; i<n; i++) {
- glyph[i].metrics = (QPFGlyphMetrics*)data;
- data += sizeof(QPFGlyphMetrics);
- }
- if ( less )
- less->readMetrics(data);
- if ( more )
- more->readMetrics(data);
- }
-#else
- void readMetrics(QIODevice& f)
- {
- int n = max-min+1;
- for (int i=0; i<n; i++) {
- glyph[i].metrics = new QPFGlyphMetrics;
- f.read((char*)glyph[i].metrics, sizeof(QPFGlyphMetrics));
- }
- if ( less )
- less->readMetrics(f);
- if ( more )
- more->readMetrics(f);
- }
-#endif
-
-#ifdef QT_USE_MMAP
- void readData(uchar*& data)
- {
- int n = max-min+1;
- for (int i=0; i<n; i++) {
- QSize s( glyph[i].metrics->width, glyph[i].metrics->height );
- //######### s = qt_screen->mapToDevice( s );
- uint datasize = glyph[i].metrics->linestep * s.height();
- glyph[i].data = data; data += datasize;
- }
- if ( less )
- less->readData(data);
- if ( more )
- more->readData(data);
- }
-#else
- void readData(QIODevice& f)
- {
- int n = max-min+1;
- for (int i=0; i<n; i++) {
- QSize s( glyph[i].metrics->width, glyph[i].metrics->height );
- //############### s = qt_screen->mapToDevice( s );
- uint datasize = glyph[i].metrics->linestep * s.height();
- glyph[i].data = new uchar[datasize]; // ### deleted?
- f.read((char*)glyph[i].data, datasize);
- }
- if ( less )
- less->readData(f);
- if ( more )
- more->readData(f);
- }
-#endif
-
-};
-
-class QFontEngineQPF1Data
-{
-public:
- QPFFontMetrics fm;
- QPFGlyphTree *tree;
- void *mmapStart;
- size_t mmapLength;
-};
-
-#if defined(Q_OS_INTEGRITY)
-static void *qt_mmap(void *start, size_t length, int /*prot*/, int /*flags*/, int fd, off_t offset)
-{
- // INTEGRITY cannot mmap local files - load it into a local buffer
- if (::lseek(fd, offset, SEEK_SET) == -1) {
-# if defined(DEBUG_FONTENGINE)
- perror("lseek failed");
-# endif
- }
- void *buf = malloc(length);
- if (::read(fd, buf, length) != (ssize_t)length) {
-# if defined(DEBUG_FONTENGINE)
- perror("read failed");
-# endif
- }
-
- return buf;
-}
-#else
-static inline void *qt_mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset)
-{
- return mmap(start, length, prot, flags, fd, offset);
-}
-#endif
-
-
-
-QFontEngineQPF1::QFontEngineQPF1(const QFontDef&, const QString &fn)
-{
- cache_cost = 1;
-
- int f = QT_OPEN( QFile::encodeName(fn), O_RDONLY, 0);
- Q_ASSERT(f>=0);
- QT_STATBUF st;
- if ( QT_FSTAT( f, &st ) )
- qFatal("Failed to stat %s",QFile::encodeName(fn).data());
- uchar* data = (uchar*)qt_mmap( 0, // any address
- st.st_size, // whole file
- PROT_READ, // read-only memory
-#if defined(Q_OS_INTEGRITY)
- 0,
-#elif !defined(Q_OS_SOLARIS) && !defined(Q_OS_QNX4) && !defined(Q_OS_VXWORKS)
- MAP_FILE | MAP_PRIVATE, // swap-backed map from file
-#else
- MAP_PRIVATE,
-#endif
- f, 0 ); // from offset 0 of f
-#if !defined(MAP_FAILED) && (defined(Q_OS_QNX4) || defined(Q_OS_INTEGRITY))
-#define MAP_FAILED ((void *)-1)
-#endif
- if ( !data || data == (uchar*)MAP_FAILED )
- qFatal("Failed to mmap %s",QFile::encodeName(fn).data());
- QT_CLOSE(f);
-
- d = new QFontEngineQPF1Data;
- d->mmapStart = data;
- d->mmapLength = st.st_size;
- memcpy(reinterpret_cast<char*>(&d->fm),data,sizeof(d->fm));
-
- data += sizeof(d->fm);
- d->tree = new QPFGlyphTree(data);
- glyphFormat = (d->fm.flags & FM_SMOOTH) ? QFontEngineGlyphCache::Raster_A8
- : QFontEngineGlyphCache::Raster_Mono;
-#if 0
- qDebug() << "font file" << fn
- << "ascent" << d->fm.ascent << "descent" << d->fm.descent
- << "leftbearing" << d->fm.leftbearing
- << "rightbearing" << d->fm.rightbearing
- << "maxwidth" << d->fm.maxwidth
- << "leading" << d->fm.leading
- << "flags" << d->fm.flags
- << "underlinepos" << d->fm.underlinepos
- << "underlinewidth" << d->fm.underlinewidth;
-#endif
-}
-
-QFontEngineQPF1::~QFontEngineQPF1()
-{
- if (d->mmapStart)
- munmap(d->mmapStart, d->mmapLength);
- delete d->tree;
- delete d;
-}
-
-
-bool QFontEngineQPF1::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const
-{
- if(*nglyphs < len) {
- *nglyphs = len;
- return false;
- }
- *nglyphs = 0;
-
- bool mirrored = flags & QTextEngine::RightToLeft;
- for(int i = 0; i < len; i++) {
- unsigned int uc = getChar(str, i, len);
- if (mirrored)
- uc = QChar::mirroredChar(uc);
- glyphs->glyphs[*nglyphs] = uc < 0x10000 ? uc : 0;
- ++*nglyphs;
- }
-
- glyphs->numGlyphs = *nglyphs;
-
- if (flags & QTextEngine::GlyphIndicesOnly)
- return true;
-
- recalcAdvances(glyphs, flags);
-
- return true;
-}
-
-void QFontEngineQPF1::recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFlags) const
-{
- for(int i = 0; i < glyphs->numGlyphs; i++) {
- QPFGlyph *glyph = d->tree->get(glyphs->glyphs[i]);
-
- glyphs->advances_x[i] = glyph ? glyph->metrics->advance : 0;
- glyphs->advances_y[i] = 0;
-
- if (!glyph)
- glyphs->glyphs[i] = 0;
- }
-}
-
-void QFontEngineQPF1::draw(QPaintEngine *p, qreal _x, qreal _y, const QTextItemInt &si)
-{
- QPaintEngineState *pState = p->state;
- QRasterPaintEngine *paintEngine = static_cast<QRasterPaintEngine*>(p);
-
- QTransform matrix = pState->transform();
- matrix.translate(_x, _y);
- QFixed x = QFixed::fromReal(matrix.dx());
- QFixed y = QFixed::fromReal(matrix.dy());
-
- QVarLengthArray<QFixedPoint> positions;
- QVarLengthArray<glyph_t> glyphs;
- getGlyphPositions(si.glyphs, matrix, si.flags, glyphs, positions);
- if (glyphs.size() == 0)
- return;
-
- int depth = (d->fm.flags & FM_SMOOTH) ? 8 : 1;
- for(int i = 0; i < glyphs.size(); i++) {
- const QPFGlyph *glyph = d->tree->get(glyphs[i]);
- if (!glyph)
- continue;
-
- int bpl = glyph->metrics->linestep;
-
- if(glyph->data)
- paintEngine->alphaPenBlt(glyph->data, bpl, depth,
- qRound(positions[i].x) + glyph->metrics->bearingx,
- qRound(positions[i].y) - glyph->metrics->bearingy,
- glyph->metrics->width,glyph->metrics->height);
- }
-}
-
-
-QImage QFontEngineQPF1::alphaMapForGlyph(glyph_t g)
-{
- const QPFGlyph *glyph = d->tree->get(g);
- if (!glyph)
- return QImage();
-
- int mono = !(d->fm.flags & FM_SMOOTH);
-
- const uchar *bits = glyph->data;//((const uchar *) glyph);
-
- QImage image;
- if (mono) {
- image = QImage((glyph->metrics->width+7)&~7, glyph->metrics->height, QImage::Format_Mono);
- image.setColor(0, qRgba(0, 0, 0, 0));
- image.setColor(1, qRgba(0, 0, 0, 255));
- } else {
- image = QImage(glyph->metrics->width, glyph->metrics->height, QImage::Format_Indexed8);
- for (int j=0; j<256; ++j)
- image.setColor(j, qRgba(0, 0, 0, j));
- }
- for (int i=0; i<glyph->metrics->height; ++i) {
- memcpy(image.scanLine(i), bits, glyph->metrics->linestep);
- bits += glyph->metrics->linestep;
- }
- return image;
-}
-
-
-
-void QFontEngineQPF1::addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs, QPainterPath *path, QTextItem::RenderFlags flags)
-{
- addBitmapFontToPath(x, y, glyphs, path, flags);
-}
-
-glyph_metrics_t QFontEngineQPF1::boundingBox(const QGlyphLayout &glyphs)
-{
- if (glyphs.numGlyphs == 0)
- return glyph_metrics_t();
-
- QFixed w = 0;
- for (int i = 0; i < glyphs.numGlyphs; ++i)
- w += glyphs.effectiveAdvance(i);
- return glyph_metrics_t(0, -ascent(), w - lastRightBearing(glyphs), ascent()+descent()+1, w, 0);
-}
-
-glyph_metrics_t QFontEngineQPF1::boundingBox(glyph_t glyph)
-{
- const QPFGlyph *g = d->tree->get(glyph);
- if (!g)
- return glyph_metrics_t();
- Q_ASSERT(g);
- return glyph_metrics_t(g->metrics->bearingx, -g->metrics->bearingy,
- g->metrics->width, g->metrics->height,
- g->metrics->advance, 0);
-}
-
-QFixed QFontEngineQPF1::ascent() const
-{
- return d->fm.ascent;
-}
-
-QFixed QFontEngineQPF1::descent() const
-{
- return d->fm.descent;
-}
-
-QFixed QFontEngineQPF1::leading() const
-{
- return d->fm.leading;
-}
-
-qreal QFontEngineQPF1::maxCharWidth() const
-{
- return d->fm.maxwidth;
-}
-/*
-const char *QFontEngineQPF1::name() const
-{
- return "qt";
-}
-*/
-bool QFontEngineQPF1::canRender(const QChar *str, int len)
-{
- for(int i = 0; i < len; i++)
- if (!d->tree->inFont(str[i].unicode()))
- return false;
- return true;
-}
-
-QFontEngine::Type QFontEngineQPF1::type() const
-{
- return QPF1;
-}
-
-qreal QFontEngineQPF1::minLeftBearing() const
-{
- return d->fm.leftbearing;
-}
-
-qreal QFontEngineQPF1::minRightBearing() const
-{
- return d->fm.rightbearing;
-}
-
-QFixed QFontEngineQPF1::underlinePosition() const
-{
- return d->fm.underlinepos;
-}
-
-QFixed QFontEngineQPF1::lineThickness() const
-{
- return d->fm.underlinewidth;
-}
-
-#endif //QT_NO_QWS_QPF
-
-QT_END_NAMESPACE
diff --git a/src/gui/text/qfontengine_x11.cpp b/src/gui/text/qfontengine_x11.cpp
deleted file mode 100644
index 6e87f4c2f6..0000000000
--- a/src/gui/text/qfontengine_x11.cpp
+++ /dev/null
@@ -1,1203 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qbitmap.h"
-
-// #define FONTENGINE_DEBUG
-
-#include <qapplication.h>
-#include <qbytearray.h>
-#include <qdebug.h>
-#include <qtextcodec.h>
-#include <qthread.h>
-
-#include "qfontdatabase.h"
-#include "qpaintdevice.h"
-#include "qpainter.h"
-#include "qvarlengtharray.h"
-#include "qwidget.h"
-#include "qsettings.h"
-#include "qfile.h"
-
-#include <private/qpaintengine_x11_p.h>
-#include "qfont.h"
-#include "qfont_p.h"
-#include "qfontengine_p.h"
-#include <qhash.h>
-
-#include <private/qpainter_p.h>
-#include <private/qunicodetables_p.h>
-
-#include <private/qt_x11_p.h>
-#include <private/qpixmap_x11_p.h>
-#include "qx11info_x11.h"
-#include "qfontengine_x11_p.h"
-
-#include <limits.h>
-
-#include <ft2build.h>
-#if defined(FT_LCD_FILTER_H)
-#include FT_LCD_FILTER_H
-#endif
-
-#if defined(FC_LCD_FILTER)
-
-#ifndef FC_LCD_FILTER_NONE
-#define FC_LCD_FILTER_NONE FC_LCD_NONE
-#endif
-
-#ifndef FC_LCD_FILTER_DEFAULT
-#define FC_LCD_FILTER_DEFAULT FC_LCD_DEFAULT
-#endif
-
-#ifndef FC_LCD_FILTER_LIGHT
-#define FC_LCD_FILTER_LIGHT FC_LCD_LIGHT
-#endif
-
-#ifndef FC_LCD_FILTER_LEGACY
-#define FC_LCD_FILTER_LEGACY FC_LCD_LEGACY
-#endif
-
-#endif
-
-QT_BEGIN_NAMESPACE
-
-
-// ------------------------------------------------------------------
-// Multi XLFD engine
-// ------------------------------------------------------------------
-
-QFontEngineMultiXLFD::QFontEngineMultiXLFD(const QFontDef &r, const QList<int> &l, int s)
- : QFontEngineMulti(l.size()), encodings(l), screen(s), request(r)
-{
- loadEngine(0);
- fontDef = engines[0]->fontDef;
-}
-
-QFontEngineMultiXLFD::~QFontEngineMultiXLFD()
-{ }
-
-void QFontEngineMultiXLFD::loadEngine(int at)
-{
- Q_ASSERT(at < engines.size());
- Q_ASSERT(engines.at(at) == 0);
- const int encoding = encodings.at(at);
- QFontEngine *fontEngine = QFontDatabase::loadXlfd(0, QUnicodeTables::Common, request, encoding);
- Q_ASSERT(fontEngine != 0);
- fontEngine->ref.ref();
- engines[at] = fontEngine;
-}
-
-// ------------------------------------------------------------------
-// Xlfd font engine
-// ------------------------------------------------------------------
-
-#ifndef QT_NO_FREETYPE
-
-static QStringList *qt_fontpath = 0;
-
-static QStringList fontPath()
-{
- if (qt_fontpath)
- return *qt_fontpath;
-
- // append qsettings fontpath
- QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
- settings.beginGroup(QLatin1String("Qt"));
-
- QStringList fontpath;
-
- int npaths;
- char** font_path;
- font_path = XGetFontPath(X11->display, &npaths);
- bool xfsconfig_read = false;
- for (int i=0; i<npaths; i++) {
- // If we're using xfs, append font paths from /etc/X11/fs/config
- // can't hurt, and chances are we'll get all fonts that way.
- if (((font_path[i])[0] != '/') && !xfsconfig_read) {
- // We're using xfs -> read its config
- bool finished = false;
- QFile f(QLatin1String("/etc/X11/fs/config"));
- if (!f.exists())
- f.setFileName(QLatin1String("/usr/X11R6/lib/X11/fs/config"));
- if (!f.exists())
- f.setFileName(QLatin1String("/usr/X11/lib/X11/fs/config"));
- if (f.exists()) {
- f.open(QIODevice::ReadOnly);
- while (f.error()==QFile::NoError && !finished) {
- QString fs = QString::fromLocal8Bit(f.readLine(1024));
- fs=fs.trimmed();
- if (fs.left(9)==QLatin1String("catalogue") && fs.contains(QLatin1Char('='))) {
- fs = fs.mid(fs.indexOf(QLatin1Char('=')) + 1).trimmed();
- bool end = false;
- while (f.error()==QFile::NoError && !end) {
- if (fs[int(fs.length())-1] == QLatin1Char(','))
- fs = fs.left(fs.length()-1);
- else
- end = true;
-
- fs = fs.left(fs.indexOf(QLatin1String(":unscaled")));
- if (fs[0] != QLatin1Char('#'))
- fontpath += fs;
- fs = QLatin1String(f.readLine(1024));
- fs = fs.trimmed();
- if (fs.isEmpty())
- end = true;
- }
- finished = true;
- }
- }
- f.close();
- }
- xfsconfig_read = true;
- } else {
- QString fs = QString::fromLocal8Bit(font_path[i]);
- fontpath += fs.left(fs.indexOf(QLatin1String(":unscaled")));
- }
- }
- XFreeFontPath(font_path);
-
- // append qsettings fontpath
- QStringList fp = settings.value(QLatin1String("fontPath")).toStringList();
- if (!fp.isEmpty())
- fontpath += fp;
-
- qt_fontpath = new QStringList(fontpath);
- return fontpath;
-}
-
-static QFontEngine::FaceId fontFile(const QByteArray &_xname, QFreetypeFace **freetype, int *synth)
-{
- *freetype = 0;
- *synth = 0;
-
- QByteArray xname = _xname.toLower();
-
- int pos = 0;
- int minus = 0;
- while (minus < 5 && (pos = xname.indexOf('-', pos + 1)))
- ++minus;
- QByteArray searchname = xname.left(pos);
- while (minus < 12 && (pos = xname.indexOf('-', pos + 1)))
- ++minus;
- QByteArray encoding = xname.mid(pos + 1);
- //qDebug("xname='%s', searchname='%s', encoding='%s'", xname.data(), searchname.data(), encoding.data());
- QStringList fontpath = fontPath();
- QFontEngine::FaceId face_id;
- face_id.index = 0;
-
- QByteArray best_mapping;
-
- for (QStringList::ConstIterator it = fontpath.constBegin(); it != fontpath.constEnd(); ++it) {
- if (!(*it).startsWith(QLatin1Char('/')))
- continue; // not a path name, a font server
- QString fontmapname;
- int num = 0;
- // search font.dir and font.scale for the right file
- while (num < 2) {
- if (num == 0)
- fontmapname = (*it) + QLatin1String("/fonts.scale");
- else
- fontmapname = (*it) + QLatin1String("/fonts.dir");
- ++num;
- //qWarning(fontmapname);
- QFile fontmap(fontmapname);
- if (!fontmap.open(QIODevice::ReadOnly))
- continue;
- while (!fontmap.atEnd()) {
- QByteArray mapping = fontmap.readLine();
- QByteArray lmapping = mapping.toLower();
-
- //qWarning(xfontname);
- //qWarning(mapping);
- if (!lmapping.contains(searchname))
- continue;
- int index = mapping.indexOf(' ');
- QByteArray ffn = mapping.mid(0,index);
- // remove bitmap formats freetype can't handle
- if (ffn.contains(".spd") || ffn.contains(".phont"))
- continue;
- bool best_match = false;
- if (!best_mapping.isEmpty()) {
- if (lmapping.contains("-0-0-0-0-")) { // scalable font
- best_match = true;
- goto found;
- }
- if (lmapping.contains(encoding) && !best_mapping.toLower().contains(encoding))
- goto found;
- continue;
- }
-
- found:
- int colon = ffn.lastIndexOf(':');
- if (colon != -1) {
- QByteArray s = ffn.left(colon);
- ffn = ffn.mid(colon + 1);
- if (s.contains("ds="))
- *synth |= QFontEngine::SynthesizedBold;
- if (s.contains("ai="))
- *synth |= QFontEngine::SynthesizedItalic;
- }
- face_id.filename = (*it).toLocal8Bit() + '/' + ffn;
- best_mapping = mapping;
- if (best_match)
- goto end;
- }
- }
- }
-end:
-// qDebug("fontfile for %s is from '%s'\n got %s synth=%d", xname.data(),
-// best_mapping.data(), face_id.filename.data(), *synth);
- *freetype = QFreetypeFace::getFace(face_id);
- if (!*freetype) {
- face_id.index = 0;
- face_id.filename = QByteArray();
- }
- return face_id;
-}
-
-#endif // QT_NO_FREETYPE
-
-// defined in qfontdatabase_x11.cpp
-extern int qt_mib_for_xlfd_encoding(const char *encoding);
-extern int qt_xlfd_encoding_id(const char *encoding);
-
-static inline XCharStruct *charStruct(XFontStruct *xfs, uint ch)
-{
- XCharStruct *xcs = 0;
- unsigned char r = ch>>8;
- unsigned char c = ch&0xff;
- if (xfs->per_char &&
- r >= xfs->min_byte1 &&
- r <= xfs->max_byte1 &&
- c >= xfs->min_char_or_byte2 &&
- c <= xfs->max_char_or_byte2) {
- xcs = xfs->per_char + ((r - xfs->min_byte1) *
- (xfs->max_char_or_byte2 -
- xfs->min_char_or_byte2 + 1)) +
- (c - xfs->min_char_or_byte2);
- if (xcs->width == 0 && xcs->ascent == 0 && xcs->descent == 0)
- xcs = 0;
- }
- return xcs;
-}
-
-QFontEngineXLFD::QFontEngineXLFD(XFontStruct *fs, const QByteArray &name, int mib)
- : _fs(fs), _name(name), _codec(0), _cmap(mib)
-{
- if (_cmap) _codec = QTextCodec::codecForMib(_cmap);
-
- cache_cost = (((fs->max_byte1 - fs->min_byte1) *
- (fs->max_char_or_byte2 - fs->min_char_or_byte2 + 1)) +
- fs->max_char_or_byte2 - fs->min_char_or_byte2);
- cache_cost = ((fs->max_bounds.ascent + fs->max_bounds.descent) *
- (fs->max_bounds.width * cache_cost / 8));
- lbearing = SHRT_MIN;
- rbearing = SHRT_MIN;
- face_id.index = -1;
- freetype = 0;
- synth = 0;
-}
-
-QFontEngineXLFD::~QFontEngineXLFD()
-{
- XFreeFont(QX11Info::display(), _fs);
- _fs = 0;
-#ifndef QT_NO_FREETYPE
- if (freetype)
- freetype->release(face_id);
-#endif
-}
-
-bool QFontEngineXLFD::stringToCMap(const QChar *s, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const
-{
- if (*nglyphs < len) {
- *nglyphs = len;
- return false;
- }
-
- // filter out surrogates, we can't handle them anyway with XLFD fonts
- QVarLengthArray<ushort> _s(len);
- QChar *str = (QChar *)_s.data();
- for (int i = 0; i < len; ++i) {
- if (s[i].isHighSurrogate() && i < len-1 && s[i+1].isLowSurrogate()) {
- *str = QChar();
- ++i;
- } else {
- *str = s[i];
- }
- ++str;
- }
-
- len = str - (QChar *)_s.data();
- str = (QChar *)_s.data();
-
- bool mirrored = flags & QTextEngine::RightToLeft;
- if (_codec) {
- bool haveNbsp = false;
- for (int i = 0; i < len; i++)
- if (str[i].unicode() == 0xa0) {
- haveNbsp = true;
- break;
- }
-
- QVarLengthArray<unsigned short> ch(len);
- QChar *chars = (QChar *)ch.data();
- if (haveNbsp || mirrored) {
- for (int i = 0; i < len; i++)
- chars[i] = (str[i].unicode() == 0xa0 ? 0x20 :
- (mirrored ? QChar::mirroredChar(str[i].unicode()) : str[i].unicode()));
- } else {
- for (int i = 0; i < len; i++)
- chars[i] = str[i].unicode();
- }
- QTextCodec::ConverterState state;
- state.flags = QTextCodec::ConvertInvalidToNull;
- QByteArray ba = _codec->fromUnicode(chars, len, &state);
- if (ba.length() == 2*len) {
- // double byte encoding
- const uchar *data = (const uchar *)ba.constData();
- for (int i = 0; i < len; i++) {
- glyphs->glyphs[i] = ((ushort)data[0] << 8) + data[1];
- data += 2;
- }
- } else {
- const uchar *data = (const uchar *)ba.constData();
- for (int i = 0; i < len; i++)
- glyphs->glyphs[i] = (ushort)data[i];
- }
- } else {
- int i = len;
- const QChar *c = str + len;
- if (mirrored) {
- while (c != str)
- glyphs->glyphs[--i] = (--c)->unicode() == 0xa0 ? 0x20 : QChar::mirroredChar(c->unicode());
- } else {
- while (c != str)
- glyphs->glyphs[--i] = (--c)->unicode() == 0xa0 ? 0x20 : c->unicode();
- }
- }
- *nglyphs = len;
- glyphs->numGlyphs = len;
-
- if (!(flags & QTextEngine::GlyphIndicesOnly))
- recalcAdvances(glyphs, flags);
- return true;
-}
-
-void QFontEngineXLFD::recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFlags /*flags*/) const
-{
- int i = glyphs->numGlyphs;
- XCharStruct *xcs;
- // inlined for better performance
- if (!_fs->per_char) {
- xcs = &_fs->min_bounds;
- while (i != 0) {
- --i;
- const unsigned char r = glyphs->glyphs[i] >> 8;
- const unsigned char c = glyphs->glyphs[i] & 0xff;
- if (r >= _fs->min_byte1 &&
- r <= _fs->max_byte1 &&
- c >= _fs->min_char_or_byte2 &&
- c <= _fs->max_char_or_byte2) {
- glyphs->advances_x[i] = xcs->width;
- } else {
- glyphs->glyphs[i] = 0;
- }
- }
- }
- else if (!_fs->max_byte1) {
- XCharStruct *base = _fs->per_char - _fs->min_char_or_byte2;
- while (i != 0) {
- unsigned int gl = glyphs->glyphs[--i];
- xcs = (gl >= _fs->min_char_or_byte2 && gl <= _fs->max_char_or_byte2) ?
- base + gl : 0;
- if (!xcs || (!xcs->width && !xcs->ascent && !xcs->descent)) {
- glyphs->glyphs[i] = 0;
- } else {
- glyphs->advances_x[i] = xcs->width;
- }
- }
- }
- else {
- while (i != 0) {
- xcs = charStruct(_fs, glyphs->glyphs[--i]);
- if (!xcs) {
- glyphs->glyphs[i] = 0;
- } else {
- glyphs->advances_x[i] = xcs->width;
- }
- }
- }
-}
-
-glyph_metrics_t QFontEngineXLFD::boundingBox(const QGlyphLayout &glyphs)
-{
- int i;
-
- glyph_metrics_t overall;
- // initialize with line height, we get the same behaviour on all platforms
- overall.y = -ascent();
- overall.height = ascent() + descent() + 1;
- QFixed ymax;
- QFixed xmax;
- for (i = 0; i < glyphs.numGlyphs; i++) {
- XCharStruct *xcs = charStruct(_fs, glyphs.glyphs[i]);
- if (xcs) {
- QFixed x = overall.xoff + glyphs.offsets[i].x + xcs->lbearing;
- QFixed y = overall.yoff + glyphs.offsets[i].y - xcs->ascent;
- overall.x = qMin(overall.x, x);
- overall.y = qMin(overall.y, y);
- // XCharStruct::rbearing is defined as distance from left edge to rightmost pixel
- xmax = qMax(xmax, overall.xoff + glyphs.offsets[i].x + xcs->rbearing);
- ymax = qMax(ymax, y + xcs->ascent + xcs->descent);
- overall.xoff += glyphs.advances_x[i] + QFixed::fromFixed(glyphs.justifications[i].space_18d6);
- } else {
- QFixed size = _fs->ascent;
- overall.x = qMin(overall.x, overall.xoff);
- overall.y = qMin(overall.y, overall.yoff - size);
- ymax = qMax(ymax, overall.yoff);
- overall.xoff += size;
- xmax = qMax(xmax, overall.xoff);
- }
- }
- overall.height = qMax(overall.height, ymax - overall.y);
- overall.width = xmax - overall.x;
-
- return overall;
-}
-
-glyph_metrics_t QFontEngineXLFD::boundingBox(glyph_t glyph)
-{
- glyph_metrics_t gm;
- XCharStruct *xcs = charStruct(_fs, glyph);
- if (xcs) {
- // XCharStruct::rbearing is defined as distance from left edge to rightmost pixel
- // XCharStruct::width is defined as the advance
- gm = glyph_metrics_t(xcs->lbearing, -xcs->ascent, xcs->rbearing- xcs->lbearing, xcs->ascent + xcs->descent,
- xcs->width, 0);
- } else {
- QFixed size = ascent();
- gm = glyph_metrics_t(0, size, size, size, size, 0);
- }
- return gm;
-}
-
-QFixed QFontEngineXLFD::ascent() const
-{
- return _fs->ascent;
-}
-
-QFixed QFontEngineXLFD::descent() const
-{
- return (_fs->descent-1);
-}
-
-QFixed QFontEngineXLFD::leading() const
-{
- QFixed l = QFixed(qMin<int>(_fs->ascent, _fs->max_bounds.ascent)
- + qMin<int>(_fs->descent, _fs->max_bounds.descent)) * QFixed::fromReal(0.15);
- return l.ceil();
-}
-
-qreal QFontEngineXLFD::maxCharWidth() const
-{
- return _fs->max_bounds.width;
-}
-
-
-// Loads the font for the specified script
-static inline int maxIndex(XFontStruct *f) {
- return (((f->max_byte1 - f->min_byte1) *
- (f->max_char_or_byte2 - f->min_char_or_byte2 + 1)) +
- f->max_char_or_byte2 - f->min_char_or_byte2);
-}
-
-qreal QFontEngineXLFD::minLeftBearing() const
-{
- if (lbearing == SHRT_MIN) {
- if (_fs->per_char) {
- XCharStruct *cs = _fs->per_char;
- int nc = maxIndex(_fs) + 1;
- int mx = cs->lbearing;
-
- for (int c = 1; c < nc; c++) {
- // ignore the bearings for characters whose ink is
- // completely outside the normal bounding box
- if ((cs[c].lbearing <= 0 && cs[c].rbearing <= 0) ||
- (cs[c].lbearing >= cs[c].width && cs[c].rbearing >= cs[c].width))
- continue;
-
- int nmx = cs[c].lbearing;
-
- if (nmx < mx)
- mx = nmx;
- }
-
- ((QFontEngineXLFD *)this)->lbearing = mx;
- } else
- ((QFontEngineXLFD *)this)->lbearing = _fs->min_bounds.lbearing;
- }
- return lbearing;
-}
-
-qreal QFontEngineXLFD::minRightBearing() const
-{
- if (rbearing == SHRT_MIN) {
- if (_fs->per_char) {
- XCharStruct *cs = _fs->per_char;
- int nc = maxIndex(_fs) + 1;
- int mx = cs->rbearing;
-
- for (int c = 1; c < nc; c++) {
- // ignore the bearings for characters whose ink is
- // completely outside the normal bounding box
- if ((cs[c].lbearing <= 0 && cs[c].rbearing <= 0) ||
- (cs[c].lbearing >= cs[c].width && cs[c].rbearing >= cs[c].width))
- continue;
-
- int nmx = cs[c].rbearing;
-
- if (nmx < mx)
- mx = nmx;
- }
-
- ((QFontEngineXLFD *)this)->rbearing = mx;
- } else
- ((QFontEngineXLFD *)this)->rbearing = _fs->min_bounds.rbearing;
- }
- return rbearing;
-}
-
-const char *QFontEngineXLFD::name() const
-{
- return _name;
-}
-
-bool QFontEngineXLFD::canRender(const QChar *string, int len)
-{
- QVarLengthGlyphLayoutArray glyphs(len);
- int nglyphs = len;
- if (stringToCMap(string, len, &glyphs, &nglyphs, 0) == false) {
- glyphs.resize(nglyphs);
- stringToCMap(string, len, &glyphs, &nglyphs, 0);
- }
-
- bool allExist = true;
- for (int i = 0; i < nglyphs; i++) {
- if (!glyphs.glyphs[i] || !charStruct(_fs, glyphs.glyphs[i])) {
- allExist = false;
- break;
- }
- }
-
- return allExist;
-}
-
-QBitmap QFontEngineXLFD::bitmapForGlyphs(const QGlyphLayout &glyphs, const glyph_metrics_t &metrics, QTextItem::RenderFlags flags)
-{
- int w = metrics.width.toInt();
- int h = metrics.height.toInt();
- if (w <= 0 || h <= 0)
- return QBitmap();
-
- QPixmapData *data = new QX11PixmapData(QPixmapData::BitmapType);
- data->resize(w, h);
- QPixmap bm(data);
- QPainter p(&bm);
- p.fillRect(0, 0, w, h, Qt::color0);
- p.setPen(Qt::color1);
-
- QTextItemInt item;
- item.flags = flags;
- item.ascent = -metrics.y;
- item.descent = metrics.height - item.ascent;
- item.width = metrics.width;
- item.chars = 0;
- item.num_chars = 0;
- item.logClusters = 0;
- item.glyphs = glyphs;
- item.fontEngine = this;
- item.f = 0;
-
- p.drawTextItem(QPointF(-metrics.x.toReal(), item.ascent.toReal()), item);
- p.end();
-
- return QBitmap(bm);
-}
-
-void QFontEngineXLFD::addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs, QPainterPath *path, QTextItem::RenderFlags flags)
-{
- // cannot use QFontEngine::addBitmapFontToPath(), since we don't
- // have direct access to the glyph bitmaps, so we have to draw
- // onto a QBitmap, then convert to QImage, then to path
- glyph_metrics_t metrics = boundingBox(glyphs);
-
- QImage image = bitmapForGlyphs(glyphs, metrics, flags).toImage();
- if (image.isNull())
- return;
-
- image = image.convertToFormat(QImage::Format_Mono);
- const uchar *image_data = image.bits();
- uint bpl = image.bytesPerLine();
- // from qfontengine.cpp
- extern void qt_addBitmapToPath(qreal x0, qreal y0, const uchar *image_data,
- int bpl, int w, int h, QPainterPath *path);
- qt_addBitmapToPath(x, y + metrics.y.toReal(), image_data, bpl, image.width(), image.height(), path);
-}
-
-QFontEngine::FaceId QFontEngineXLFD::faceId() const
-{
-#ifndef QT_NO_FREETYPE
- if (face_id.index == -1) {
- face_id = fontFile(_name, &freetype, &synth);
- if (_codec)
- face_id.encoding = _codec->mibEnum();
- if (freetype) {
- const_cast<QFontEngineXLFD *>(this)->fsType = freetype->fsType();
- } else {
- face_id.index = 0;
- face_id.filename = '-' + QFontEngine::properties().postscriptName;
- }
- }
-#endif
-
- return face_id;
-}
-
-QFontEngine::Properties QFontEngineXLFD::properties() const
-{
- if (face_id.index == -1)
- (void)faceId();
-
-#ifndef QT_NO_FREETYPE
- if (freetype)
- return freetype->properties();
-#endif
- return QFontEngine::properties();
-}
-
-void QFontEngineXLFD::getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics)
-{
- if (face_id.index == -1)
- (void)faceId();
-#ifndef QT_NO_FREETYPE
- if (!freetype)
-#endif
- {
- QFontEngine::getUnscaledGlyph(glyph, path, metrics);
- return;
- }
-
-#ifndef QT_NO_FREETYPE
- freetype->lock();
-
- FT_Face face = freetype->face;
- FT_Set_Char_Size(face, face->units_per_EM << 6, face->units_per_EM << 6, 0, 0);
- freetype->xsize = face->units_per_EM << 6;
- freetype->ysize = face->units_per_EM << 6;
- FT_Set_Transform(face, 0, 0);
- glyph = glyphIndexToFreetypeGlyphIndex(glyph);
- FT_Load_Glyph(face, glyph, FT_LOAD_NO_BITMAP);
-
- int left = face->glyph->metrics.horiBearingX;
- int right = face->glyph->metrics.horiBearingX + face->glyph->metrics.width;
- int top = face->glyph->metrics.horiBearingY;
- int bottom = face->glyph->metrics.horiBearingY - face->glyph->metrics.height;
-
- QFixedPoint p;
- p.x = 0;
- p.y = 0;
- metrics->width = QFixed::fromFixed(right-left);
- metrics->height = QFixed::fromFixed(top-bottom);
- metrics->x = QFixed::fromFixed(left);
- metrics->y = QFixed::fromFixed(-top);
- metrics->xoff = QFixed::fromFixed(face->glyph->advance.x);
-
- if (!FT_IS_SCALABLE(freetype->face))
- QFreetypeFace::addBitmapToPath(face->glyph, p, path);
- else
- QFreetypeFace::addGlyphToPath(face, face->glyph, p, path, face->units_per_EM << 6, face->units_per_EM << 6);
-
- FT_Set_Transform(face, &freetype->matrix, 0);
- freetype->unlock();
-#endif // QT_NO_FREETYPE
-}
-
-
-bool QFontEngineXLFD::getSfntTableData(uint tag, uchar *buffer, uint *length) const
-{
-#ifndef QT_NO_FREETYPE
- if (face_id.index == -1)
- (void)faceId();
- if (!freetype)
- return false;
- return freetype->getSfntTable(tag, buffer, length);
-#else
- Q_UNUSED(tag);
- Q_UNUSED(buffer);
- Q_UNUSED(length);
- return false;
-#endif
-}
-
-int QFontEngineXLFD::synthesized() const
-{
- return synth;
-}
-
-QImage QFontEngineXLFD::alphaMapForGlyph(glyph_t glyph)
-{
- glyph_metrics_t metrics = boundingBox(glyph);
-
-/*
- printf("a) w=%.2f, h=%.2f, xoff=%.2f, yoff=%.2f, x=%.2f, y=%.2f\n",
- metrics.width.toReal(),
- metrics.height.toReal(),
- metrics.xoff.toReal(),
- metrics.yoff.toReal(),
- metrics.x.toReal(),
- metrics.y.toReal());
-*/
-
- QGlyphLayoutArray<1> glyphs;
- glyphs.glyphs[0] = glyph;
-
- QImage image = bitmapForGlyphs(glyphs, metrics).toImage();
-//image.save(QString::fromLatin1("x11cache-%1.png").arg((int)glyph));
-
- image = image.convertToFormat(QImage::Format_Indexed8);
- QVector<QRgb> colors(256);
- for (int i = 0; i < 256; ++i)
- colors[i] = qRgba(0, 0, 0, i);
- image.setColorTable(colors);
-
- int width = image.width();
- int height = image.height();
- for (int y = 0; y < height; ++y) {
- uchar *bits = image.scanLine(y);
- for (int x = 0; x < width; ++x)
- bits[x] = ~(bits[x]-1);
- }
-
- return image;
-}
-
-#ifndef QT_NO_FREETYPE
-
-FT_Face QFontEngineXLFD::non_locked_face() const
-{
- return freetype ? freetype->face : 0;
-}
-
-uint QFontEngineXLFD::toUnicode(glyph_t g) const
-{
- if (_codec) {
- QTextCodec::ConverterState state;
- state.flags = QTextCodec::ConvertInvalidToNull;
- uchar data[2];
- int l = 1;
- if (g > 255) {
- data[0] = (g >> 8);
- data[1] = (g & 255);
- l = 2;
- } else {
- data[0] = g;
- }
- QString s = _codec->toUnicode((char *)data, l, &state);
- Q_ASSERT(s.length() == 1);
- g = s.at(0).unicode();
- }
- return g;
-}
-
-glyph_t QFontEngineXLFD::glyphIndexToFreetypeGlyphIndex(glyph_t g) const
-{
- return FT_Get_Char_Index(freetype->face, toUnicode(g));
-}
-#endif
-
-#ifndef QT_NO_FONTCONFIG
-
-// ------------------------------------------------------------------
-// Multi FT engine
-// ------------------------------------------------------------------
-
-static QFontEngine *engineForPattern(FcPattern *match, const QFontDef &request, int screen)
-{
- QFontEngineX11FT *engine = new QFontEngineX11FT(match, request, screen);
- if (!engine->invalid())
- return engine;
-
- delete engine;
- QFontEngine *fe = new QFontEngineBox(request.pixelSize);
- fe->fontDef = request;
- return fe;
-}
-
-QFontEngineMultiFT::QFontEngineMultiFT(QFontEngine *fe, FcPattern *matchedPattern, FcPattern *p, int s, const QFontDef &req)
- : QFontEngineMulti(2), request(req), pattern(p), fontSet(0), screen(s)
-{
- firstEnginePattern = FcPatternDuplicate(matchedPattern);
- engines[0] = fe;
- engines.at(0)->ref.ref();
- fontDef = engines[0]->fontDef;
- cache_cost = 100;
- firstFontIndex = 1;
-}
-
-QFontEngineMultiFT::~QFontEngineMultiFT()
-{
- extern QMutex *qt_fontdatabase_mutex();
- QMutexLocker locker(qt_fontdatabase_mutex());
-
- FcPatternDestroy(pattern);
- if (firstEnginePattern)
- FcPatternDestroy(firstEnginePattern);
- if (fontSet)
- FcFontSetDestroy(fontSet);
-}
-
-
-void QFontEngineMultiFT::loadEngine(int at)
-{
- extern QMutex *qt_fontdatabase_mutex();
- QMutexLocker locker(qt_fontdatabase_mutex());
-
- extern QFontDef qt_FcPatternToQFontDef(FcPattern *pattern, const QFontDef &);
- extern FcFontSet *qt_fontSetForPattern(FcPattern *pattern, const QFontDef &request);
-
- Q_ASSERT(at > 0);
- if (!fontSet) {
- fontSet = qt_fontSetForPattern(pattern, request);
-
- // it may happen that the fontset of fallbacks consists of only one font. In this case we
- // have to fall back to the box fontengine as we cannot render the glyph.
- if (fontSet->nfont == 1 && at == 1 && engines.size() == 2) {
- Q_ASSERT(engines.at(at) == 0);
- QFontEngine *fe = new QFontEngineBox(request.pixelSize);
- fe->fontDef = request;
- engines[at] = fe;
- return;
- }
-
- if (firstEnginePattern) {
-
- if (!FcPatternEqual(firstEnginePattern, fontSet->fonts[0]))
- firstFontIndex = 0;
-
- FcPatternDestroy(firstEnginePattern);
- firstEnginePattern = 0;
- }
-
- engines.resize(fontSet->nfont + 1 - firstFontIndex);
- }
- Q_ASSERT(at < engines.size());
- Q_ASSERT(engines.at(at) == 0);
-
- FcPattern *match = FcFontRenderPrepare(NULL, pattern, fontSet->fonts[at + firstFontIndex - 1]);
- QFontDef fontDef = qt_FcPatternToQFontDef(match, this->request);
-
- // note: we use -1 for the script to make sure that we keep real
- // FT engines separate from Multi engines in the font cache
- QFontCache::Key key(fontDef, -1, screen);
- QFontEngine *fontEngine = QFontCache::instance()->findEngine(key);
- if (!fontEngine) {
- fontEngine = engineForPattern(match, request, screen);
- QFontCache::instance()->insertEngine(key, fontEngine);
- }
- FcPatternDestroy(match);
- fontEngine->ref.ref();
- engines[at] = fontEngine;
-}
-
-// ------------------------------------------------------------------
-// X11 FT engine
-// ------------------------------------------------------------------
-
-
-
-Q_GUI_EXPORT void qt_x11ft_convert_pattern(FcPattern *pattern, QByteArray *file_name, int *index, bool *antialias)
-{
- FcChar8 *fileName;
- FcPatternGetString(pattern, FC_FILE, 0, &fileName);
- *file_name = (const char *)fileName;
- if (!FcPatternGetInteger(pattern, FC_INDEX, 0, index))
- index = 0;
- FcBool b;
- if (FcPatternGetBool(pattern, FC_ANTIALIAS, 0, &b) == FcResultMatch)
- *antialias = b;
-}
-
-
-QFontEngineX11FT::QFontEngineX11FT(FcPattern *pattern, const QFontDef &fd, int screen)
- : QFontEngineFT(fd)
-{
-// FcPatternPrint(pattern);
-
- bool antialias = X11->fc_antialias;
- QByteArray file_name;
- int face_index;
- qt_x11ft_convert_pattern(pattern, &file_name, &face_index, &antialias);
- QFontEngine::FaceId face_id;
- face_id.filename = file_name;
- face_id.index = face_index;
-
- canUploadGlyphsToServer = QApplication::testAttribute(Qt::AA_X11InitThreads) || (qApp->thread() == QThread::currentThread());
-
- subpixelType = Subpixel_None;
- if (antialias) {
- int subpixel = X11->display ? X11->screens[screen].subpixel : FC_RGBA_UNKNOWN;
- if (subpixel == FC_RGBA_UNKNOWN)
- (void) FcPatternGetInteger(pattern, FC_RGBA, 0, &subpixel);
- if (!antialias || subpixel == FC_RGBA_UNKNOWN)
- subpixel = FC_RGBA_NONE;
-
- switch (subpixel) {
- case FC_RGBA_NONE: subpixelType = Subpixel_None; break;
- case FC_RGBA_RGB: subpixelType = Subpixel_RGB; break;
- case FC_RGBA_BGR: subpixelType = Subpixel_BGR; break;
- case FC_RGBA_VRGB: subpixelType = Subpixel_VRGB; break;
- case FC_RGBA_VBGR: subpixelType = Subpixel_VBGR; break;
- default: break;
- }
- }
-
- if (fd.hintingPreference != QFont::PreferDefaultHinting) {
- switch (fd.hintingPreference) {
- case QFont::PreferNoHinting:
- default_hint_style = HintNone;
- break;
- case QFont::PreferVerticalHinting:
- default_hint_style = HintLight;
- break;
- case QFont::PreferFullHinting:
- default:
- default_hint_style = HintFull;
- break;
- }
- }
-#ifdef FC_HINT_STYLE
- else {
- int hint_style = 0;
- // Try to use Xft.hintstyle from XDefaults first if running in GNOME, to match
- // the behavior of cairo
- if (X11->fc_hint_style > -1 && X11->desktopEnvironment == DE_GNOME)
- hint_style = X11->fc_hint_style;
- else if (FcPatternGetInteger (pattern, FC_HINT_STYLE, 0, &hint_style) == FcResultNoMatch
- && X11->fc_hint_style > -1)
- hint_style = X11->fc_hint_style;
-
- switch (hint_style) {
- case FC_HINT_NONE:
- default_hint_style = HintNone;
- break;
- case FC_HINT_SLIGHT:
- default_hint_style = HintLight;
- break;
- case FC_HINT_MEDIUM:
- default_hint_style = HintMedium;
- break;
- default:
- default_hint_style = HintFull;
- break;
- }
- }
-#endif
-
-#if defined(FC_AUTOHINT) && defined(FT_LOAD_FORCE_AUTOHINT)
- {
- bool autohint = false;
-
- FcBool b;
- if (FcPatternGetBool(pattern, FC_AUTOHINT, 0, &b) == FcResultMatch)
- autohint = b;
-
- if (autohint)
- default_load_flags |= FT_LOAD_FORCE_AUTOHINT;
- }
-#endif
-
-#if defined(FC_LCD_FILTER) && defined(FT_LCD_FILTER_H)
- {
- int filter = FC_LCD_FILTER_NONE;
- if (FcPatternGetInteger(pattern, FC_LCD_FILTER, 0, &filter) == FcResultMatch) {
- switch (filter) {
- case FC_LCD_FILTER_NONE:
- lcdFilterType = FT_LCD_FILTER_NONE;
- break;
- case FC_LCD_FILTER_DEFAULT:
- lcdFilterType = FT_LCD_FILTER_DEFAULT;
- break;
- case FC_LCD_FILTER_LIGHT:
- lcdFilterType = FT_LCD_FILTER_LIGHT;
- break;
- case FC_LCD_FILTER_LEGACY:
- lcdFilterType = FT_LCD_FILTER_LEGACY;
- break;
- default:
- // new unknown lcd filter type?!
- break;
- }
- }
- }
-#endif
-
-#ifdef FC_EMBEDDED_BITMAP
- {
- FcBool b;
- if (FcPatternGetBool(pattern, FC_EMBEDDED_BITMAP, 0, &b) == FcResultMatch)
- embeddedbitmap = b;
- }
-#endif
-
- GlyphFormat defaultFormat = Format_None;
-
-#ifndef QT_NO_XRENDER
- if (X11->use_xrender) {
- int format = PictStandardA8;
- if (!antialias)
- format = PictStandardA1;
- else if (subpixelType == Subpixel_RGB
- || subpixelType == Subpixel_BGR
- || subpixelType == Subpixel_VRGB
- || subpixelType == Subpixel_VBGR)
- format = PictStandardARGB32;
- xglyph_format = format;
-
- if (subpixelType != QFontEngineFT::Subpixel_None)
- defaultFormat = Format_A32;
- else if (antialias)
- defaultFormat = Format_A8;
- else
- defaultFormat = Format_Mono;
- }
-#endif
-
- if (!init(face_id, antialias, defaultFormat))
- return;
-
- if (!freetype->charset) {
- FcCharSet *cs;
- FcPatternGetCharSet (pattern, FC_CHARSET, 0, &cs);
- freetype->charset = FcCharSetCopy(cs);
- }
-}
-
-QFontEngineX11FT::~QFontEngineX11FT()
-{
- freeGlyphSets();
-}
-
-unsigned long QFontEngineX11FT::allocateServerGlyphSet()
-{
-#ifndef QT_NO_XRENDER
- if (!canUploadGlyphsToServer || !X11->use_xrender)
- return 0;
- return XRenderCreateGlyphSet(X11->display, XRenderFindStandardFormat(X11->display, xglyph_format));
-#else
- return 0;
-#endif
-}
-
-void QFontEngineX11FT::freeServerGlyphSet(unsigned long id)
-{
-#ifndef QT_NO_XRENDER
- if (!id)
- return;
- XRenderFreeGlyphSet(X11->display, id);
-#endif
-}
-
-bool QFontEngineX11FT::uploadGlyphToServer(QGlyphSet *set, uint glyphid, Glyph *g, GlyphInfo *info, int glyphDataSize) const
-{
-#ifndef QT_NO_XRENDER
- if (!canUploadGlyphsToServer)
- return false;
- if (g->format == Format_Mono) {
- /*
- * swap bit order around; FreeType is always MSBFirst
- */
- if (BitmapBitOrder(X11->display) != MSBFirst) {
- unsigned char *line = g->data;
- int i = glyphDataSize;
- while (i--) {
- unsigned char c;
- c = *line;
- c = ((c << 1) & 0xaa) | ((c >> 1) & 0x55);
- c = ((c << 2) & 0xcc) | ((c >> 2) & 0x33);
- c = ((c << 4) & 0xf0) | ((c >> 4) & 0x0f);
- *line++ = c;
- }
- }
- }
-
- ::Glyph xglyph = glyphid;
- XRenderAddGlyphs (X11->display, set->id, &xglyph, info, 1, (const char *)g->data, glyphDataSize);
- delete [] g->data;
- g->data = 0;
- g->format = Format_None;
- g->uploadedToServer = true;
- return true;
-#else
- return false;
-#endif
-}
-
-QFontEngine *QFontEngineX11FT::cloneWithSize(qreal pixelSize) const
-{
- QFontDef fontDef;
- fontDef.pixelSize = pixelSize;
- QFontEngineX11FT *fe = new QFontEngineX11FT(fontDef);
- if (!fe->initFromFontEngine(this)) {
- delete fe;
- return 0;
- } else {
-#ifndef QT_NO_XRENDER
- fe->xglyph_format = xglyph_format;
-#endif
- return fe;
- }
-}
-
-#endif // QT_NO_FONTCONFIG
-
-QT_END_NAMESPACE
diff --git a/src/gui/text/qfontengine_x11_p.h b/src/gui/text/qfontengine_x11_p.h
deleted file mode 100644
index 1c0bcada11..0000000000
--- a/src/gui/text/qfontengine_x11_p.h
+++ /dev/null
@@ -1,180 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QFONTENGINE_X11_P_H
-#define QFONTENGINE_X11_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-#include <private/qt_x11_p.h>
-
-#include <private/qfontengine_ft_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QFreetypeFace;
-
-// --------------------------------------------------------------------------
-
-class QFontEngineMultiXLFD : public QFontEngineMulti
-{
-public:
- QFontEngineMultiXLFD(const QFontDef &r, const QList<int> &l, int s);
- ~QFontEngineMultiXLFD();
-
- void loadEngine(int at);
-
-private:
- QList<int> encodings;
- int screen;
- QFontDef request;
-};
-
-/**
- * \internal The font engine for X Logical Font Description (XLFD) fonts, which is for X11 systems without freetype.
- */
-class QFontEngineXLFD : public QFontEngine
-{
-public:
- QFontEngineXLFD(XFontStruct *f, const QByteArray &name, int mib);
- ~QFontEngineXLFD();
-
- virtual QFontEngine::FaceId faceId() const;
- QFontEngine::Properties properties() const;
- virtual void getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics);
- virtual bool getSfntTableData(uint tag, uchar *buffer, uint *length) const;
- virtual int synthesized() const;
-
- virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs,
- QTextEngine::ShaperFlags flags) const;
- virtual void recalcAdvances(QGlyphLayout *, QTextEngine::ShaperFlags) const;
-
- virtual glyph_metrics_t boundingBox(const QGlyphLayout &glyphs);
- virtual glyph_metrics_t boundingBox(glyph_t glyph);
-
- virtual void addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs, QPainterPath *path, QTextItem::RenderFlags);
- virtual QFixed ascent() const;
- virtual QFixed descent() const;
- virtual QFixed leading() const;
- virtual qreal maxCharWidth() const;
- virtual qreal minLeftBearing() const;
- virtual qreal minRightBearing() const;
- virtual QImage alphaMapForGlyph(glyph_t);
-
- virtual inline Type type() const
- { return QFontEngine::XLFD; }
-
- virtual bool canRender(const QChar *string, int len);
- virtual const char *name() const;
-
- inline XFontStruct *fontStruct() const
- { return _fs; }
-
-#ifndef QT_NO_FREETYPE
- FT_Face non_locked_face() const;
- glyph_t glyphIndexToFreetypeGlyphIndex(glyph_t g) const;
-#endif
- uint toUnicode(glyph_t g) const;
-
-private:
- QBitmap bitmapForGlyphs(const QGlyphLayout &glyphs, const glyph_metrics_t &metrics, QTextItem::RenderFlags flags = 0);
-
- XFontStruct *_fs;
- QByteArray _name;
- QTextCodec *_codec;
- int _cmap;
- int lbearing, rbearing;
- mutable QFontEngine::FaceId face_id;
- mutable QFreetypeFace *freetype;
- mutable int synth;
-};
-
-#ifndef QT_NO_FONTCONFIG
-
-class Q_GUI_EXPORT QFontEngineMultiFT : public QFontEngineMulti
-{
-public:
- QFontEngineMultiFT(QFontEngine *fe, FcPattern *firstEnginePattern, FcPattern *p, int s, const QFontDef &request);
- ~QFontEngineMultiFT();
-
- void loadEngine(int at);
-
-private:
- QFontDef request;
- FcPattern *pattern;
- FcPattern *firstEnginePattern;
- FcFontSet *fontSet;
- int screen;
- int firstFontIndex; // first font in fontset
-};
-
-class Q_GUI_EXPORT QFontEngineX11FT : public QFontEngineFT
-{
-public:
- explicit QFontEngineX11FT(const QFontDef &fontDef) : QFontEngineFT(fontDef) {}
- explicit QFontEngineX11FT(FcPattern *pattern, const QFontDef &fd, int screen);
- ~QFontEngineX11FT();
-
- QFontEngine *cloneWithSize(qreal pixelSize) const;
-
-#ifndef QT_NO_XRENDER
- int xglyph_format;
-#endif
-
-protected:
- virtual bool uploadGlyphToServer(QGlyphSet *set, uint glyphid, Glyph *g, GlyphInfo *info, int glyphDataSize) const;
- virtual unsigned long allocateServerGlyphSet();
- virtual void freeServerGlyphSet(unsigned long id);
-};
-
-#endif // QT_NO_FONTCONFIG
-
-QT_END_NAMESPACE
-
-#endif // QFONTENGINE_X11_P_H
diff --git a/src/gui/text/qfontmetrics.h b/src/gui/text/qfontmetrics.h
index a23bb34e0d..f21e820556 100644
--- a/src/gui/text/qfontmetrics.h
+++ b/src/gui/text/qfontmetrics.h
@@ -120,15 +120,6 @@ public:
bool operator==(const QFontMetrics &other) const;
inline bool operator !=(const QFontMetrics &other) const { return !operator==(other); }
-#ifdef QT3_SUPPORT
- inline QRect boundingRect(const QString &text, int len) const
- { return boundingRect(text.left(len)); }
- inline QRect boundingRect(int x, int y, int w, int h, int flags, const QString& str, int len,
- int tabstops=0, int *tabarray=0) const
- { return boundingRect(QRect(x, y, w, h), flags, str.left(len), tabstops, tabarray); }
- inline QSize size(int flags, const QString& str, int len, int tabstops=0, int *tabarray=0) const
- { return size(flags, str.left(len), tabstops, tabarray); }
-#endif
private:
#if defined(Q_WS_MAC)
friend class QFontPrivate;
diff --git a/src/gui/text/qfontsubset.cpp b/src/gui/text/qfontsubset.cpp
index ccb1f247da..dc2a14a52a 100644
--- a/src/gui/text/qfontsubset.cpp
+++ b/src/gui/text/qfontsubset.cpp
@@ -57,8 +57,6 @@
#include FT_FREETYPE_H
#endif
-#ifndef QT_NO_PRINTER
-
QT_BEGIN_NAMESPACE
static const char * const agl =
@@ -1493,251 +1491,4 @@ QByteArray QFontSubset::toTruetype() const
return bindFont(tables);
}
-// ------------------ Type 1 generation ---------------------------
-
-// needs at least 6 bytes of space in tmp
-static const char *encodeNumber(int num, char *tmp)
-{
- const char *ret = tmp;
- if(num >= -107 && num <= 107) {
- QPdf::toHex((uchar)(num + 139), tmp);
- tmp += 2;
- } else if (num > 107 && num <= 1131) {
- num -= 108;
- QPdf::toHex((uchar)((num >> 8) + 247), tmp);
- tmp += 2;
- QPdf::toHex((uchar)(num & 0xff), tmp);
- tmp += 2;
- } else if(num < - 107 && num >= -1131) {
- num += 108;
- num = -num;
- QPdf::toHex((uchar)((num >> 8) + 251), tmp);
- tmp += 2;
- QPdf::toHex((uchar)(num & 0xff), tmp);
- tmp += 2;
- } else {
- *tmp++ = 'f';
- *tmp++ = 'f';
- QPdf::toHex((uchar)(num >> 24), tmp);
- tmp += 2;
- QPdf::toHex((uchar)(num >> 16), tmp);
- tmp += 2;
- QPdf::toHex((uchar)(num >> 8), tmp);
- tmp += 2;
- QPdf::toHex((uchar)(num >> 0), tmp);
- tmp += 2;
- }
- *tmp = 0;
-// qDebug("encodeNumber: %d -> '%s'", num, ret);
- return ret;
-}
-
-static QByteArray charString(const QPainterPath &path, qreal advance, qreal lsb, qreal ppem)
-{
- // the charstring commands we need
- const char *hsbw = "0D";
- const char *closepath = "09";
- const char *moveto[3] = { "16", "04", "15" };
- const char *lineto[3] = { "06", "07", "05" };
- const char *rcurveto = "08";
- const char *endchar = "0E";
-
- enum { horizontal = 1, vertical = 2 };
-
- char tmp[16];
-
- qreal factor = 1000./ppem;
-
- int lsb_i = qRound(lsb*factor);
- int advance_i = qRound(advance*factor);
-// qDebug("--- charstring");
-
- // first of all add lsb and width to the charstring using the hsbw command
- QByteArray charstring;
- charstring += encodeNumber(lsb_i, tmp);
- charstring += encodeNumber(advance_i, tmp);
- charstring += hsbw;
-
- // add the path
- int xl = lsb_i;
- int yl = 0;
- bool openpath = false;
- for (int i = 0; i < path.elementCount(); ++i) {
- const QPainterPath::Element &elm = path.elementAt(i);
- int x = qRound(elm.x*factor);
- int y = -qRound(elm.y*factor);
- int dx = x - xl;
- int dy = y - yl;
- if (elm.type == QPainterPath::MoveToElement && openpath) {
-// qDebug("closepath %s", closepath);
- charstring += closepath;
- }
- if (elm.type == QPainterPath::MoveToElement ||
- elm.type == QPainterPath::LineToElement) {
- int type = -1;
- if (dx || !dy) {
- charstring += encodeNumber(dx, tmp);
- type += horizontal;
-// qDebug("horizontal");
- }
- if (dy) {
- charstring += encodeNumber(dy, tmp);
- type += vertical;
-// qDebug("vertical");
- }
-// qDebug("moveto/lineto %s", (elm.type == QPainterPath::MoveToElement ? moveto[type] : lineto[type]));
- charstring += (elm.type == QPainterPath::MoveToElement ? moveto[type] : lineto[type]);
- openpath = true;
- xl = x;
- yl = y;
- } else {
- Q_ASSERT(elm.type == QPainterPath::CurveToElement);
- const QPainterPath::Element &elm2 = path.elementAt(++i);
- const QPainterPath::Element &elm3 = path.elementAt(++i);
- int x2 = qRound(elm2.x*factor);
- int y2 = -qRound(elm2.y*factor);
- int x3 = qRound(elm3.x*factor);
- int y3 = -qRound(elm3.y*factor);
- charstring += encodeNumber(dx, tmp);
- charstring += encodeNumber(dy, tmp);
- charstring += encodeNumber(x2 - x, tmp);
- charstring += encodeNumber(y2 - y, tmp);
- charstring += encodeNumber(x3 - x2, tmp);
- charstring += encodeNumber(y3 - y2, tmp);
- charstring += rcurveto;
- openpath = true;
- xl = x3;
- yl = y3;
-// qDebug("rcurveto");
- }
- }
- if (openpath)
- charstring += closepath;
- charstring += endchar;
- if (charstring.length() > 240) {
- int pos = 240;
- while (pos < charstring.length()) {
- charstring.insert(pos, '\n');
- pos += 241;
- }
- }
- return charstring;
-}
-
-#ifndef QT_NO_FREETYPE
-static const char *helvetica_styles[4] = {
- "Helvetica",
- "Helvetica-Bold",
- "Helvetica-Oblique",
- "Helvetica-BoldOblique"
-};
-static const char *times_styles[4] = {
- "Times-Regular",
- "Times-Bold",
- "Times-Italic",
- "Times-BoldItalic"
-};
-static const char *courier_styles[4] = {
- "Courier",
- "Courier-Bold",
- "Courier-Oblique",
- "Courier-BoldOblique"
-};
-#endif
-
-QByteArray QFontSubset::toType1() const
-{
- QFontEngine::Properties properties = fontEngine->properties();
- QVector<int> reverseMap = getReverseMap();
-
- QByteArray font;
- QPdf::ByteStream s(&font);
-
- QByteArray id = QByteArray::number(object_id);
- QByteArray psname = properties.postscriptName;
- psname.replace(' ', "");
-
- standard_font = false;
-
-#ifndef QT_NO_FREETYPE
- FT_Face face = ft_face(fontEngine);
- if (face && !FT_IS_SCALABLE(face)) {
- int style = 0;
- if (fontEngine->fontDef.style)
- style += 2;
- if (fontEngine->fontDef.weight >= QFont::Bold)
- style++;
- if (fontEngine->fontDef.family.contains(QLatin1String("Helvetica"))) {
- psname = helvetica_styles[style];
- standard_font = true;
- } else if (fontEngine->fontDef.family.contains(QLatin1String("Times"))) {
- psname = times_styles[style];
- standard_font = true;
- } else if (fontEngine->fontDef.family.contains(QLatin1String("Courier"))) {
- psname = courier_styles[style];
- standard_font = true;
- }
- }
-#endif
- s << "/F" << id << "-Base\n";
- if (standard_font) {
- s << '/' << psname << " findfont\n"
- "0 dict copy dup /NumGlyphs 0 put dup /CMap 256 array put def\n";
- } else {
- s << "<<\n";
- if(!psname.isEmpty())
- s << "/FontName /" << psname << '\n';
- s << "/FontInfo <</FsType " << (int)fontEngine->fsType << ">>\n"
- "/FontType 1\n"
- "/PaintType 0\n"
- "/FontMatrix [.001 0 0 .001 0 0]\n"
- "/FontBBox { 0 0 0 0 }\n"
- "/Private <<\n"
- "/password 5839\n"
- "/MinFeature {16 16}\n"
- "/BlueValues []\n"
- "/lenIV -1\n"
- ">>\n"
- "/CharStrings << >>\n"
- "/NumGlyphs 0\n"
- "/CMap 256 array\n"
- ">> def\n";
- }
- s << type1AddedGlyphs();
- downloaded_glyphs = glyph_indices.size();
-
- return font;
-}
-
-QByteArray QFontSubset::type1AddedGlyphs() const
-{
- if (downloaded_glyphs == glyph_indices.size())
- return QByteArray();
-
- QFontEngine::Properties properties = fontEngine->properties();
- QVector<int> reverseMap = getReverseMap();
- QByteArray glyphs;
- QPdf::ByteStream s(&glyphs);
-
- int nGlyphs = glyph_indices.size();
- QByteArray id = QByteArray::number(object_id);
-
- s << 'F' << id << "-Base [\n";
- for (int i = downloaded_glyphs; i < nGlyphs; ++i) {
- glyph_t g = glyph_indices.at(i);
- QPainterPath path;
- glyph_metrics_t metric;
- fontEngine->getUnscaledGlyph(g, &path, &metric);
- QByteArray charstring = charString(path, metric.xoff.toReal(), metric.x.toReal(),
- properties.emSquare.toReal());
- s << glyphName(i, reverseMap);
- if (!standard_font)
- s << "\n<" << charstring << ">\n";
- }
- s << (standard_font ? "] T1AddMapping\n" : "] T1AddGlyphs\n");
- return glyphs;
-}
-
QT_END_NAMESPACE
-
-#endif // QT_NO_PRINTER
diff --git a/src/gui/text/qfontsubset_p.h b/src/gui/text/qfontsubset_p.h
index 7b9b47486c..a99236f4cc 100644
--- a/src/gui/text/qfontsubset_p.h
+++ b/src/gui/text/qfontsubset_p.h
@@ -55,8 +55,6 @@
#include "private/qfontengine_p.h"
-#ifndef QT_NO_PRINTER
-
QT_BEGIN_NAMESPACE
class QFontSubset
@@ -71,8 +69,6 @@ public:
}
QByteArray toTruetype() const;
- QByteArray toType1() const;
- QByteArray type1AddedGlyphs() const;
QByteArray widthArray() const;
QByteArray createToUnicodeMap() const;
QVector<int> getReverseMap() const;
@@ -94,6 +90,4 @@ public:
QT_END_NAMESPACE
-#endif // QT_NO_PRINTER
-
#endif // QFONTSUBSET_P_H
diff --git a/src/gui/text/qglyphrun.cpp b/src/gui/text/qglyphrun.cpp
index be9c058693..90efc4db21 100644
--- a/src/gui/text/qglyphrun.cpp
+++ b/src/gui/text/qglyphrun.cpp
@@ -141,14 +141,18 @@ bool QGlyphRun::operator==(const QGlyphRun &other) const
return false;
}
- for (int i=0; i<qMax(d->glyphIndexDataSize, d->glyphPositionDataSize); ++i) {
- if (i < d->glyphIndexDataSize && d->glyphIndexData[i] != other.d->glyphIndexData[i])
- return false;
-
- if (i < d->glyphPositionDataSize && d->glyphPositionData[i] != other.d->glyphPositionData[i])
- return false;
+ if (d->glyphIndexData != other.d->glyphIndexData) {
+ for (int i = 0; i < d->glyphIndexDataSize; ++i) {
+ if (d->glyphIndexData[i] != other.d->glyphIndexData[i])
+ return false;
+ }
+ }
+ if (d->glyphPositionData != other.d->glyphPositionData) {
+ for (int i = 0; i < d->glyphPositionDataSize; ++i) {
+ if (d->glyphPositionData[i] != other.d->glyphPositionData[i])
+ return false;
+ }
}
-
return (d->overline == other.d->overline
&& d->underline == other.d->underline
@@ -157,13 +161,11 @@ bool QGlyphRun::operator==(const QGlyphRun &other) const
}
/*!
+ \fn bool QGlyphRun::operator!=(const QGlyphRun &other) const
+
Compares \a other to this QGlyphRun object. Returns true if any of the list of glyph
indexes, the list of positions or the font are different, otherwise returns false.
*/
-bool QGlyphRun::operator!=(const QGlyphRun &other) const
-{
- return !(*this == other);
-}
/*!
Returns the font selected for this QGlyphRun object.
@@ -295,6 +297,9 @@ bool QGlyphRun::overline() const
*/
void QGlyphRun::setOverline(bool overline)
{
+ if (d->overline == overline)
+ return;
+
detach();
d->overline = overline;
}
@@ -317,6 +322,9 @@ bool QGlyphRun::underline() const
*/
void QGlyphRun::setUnderline(bool underline)
{
+ if (d->underline == underline)
+ return;
+
detach();
d->underline = underline;
}
@@ -339,6 +347,9 @@ bool QGlyphRun::strikeOut() const
*/
void QGlyphRun::setStrikeOut(bool strikeOut)
{
+ if (d->strikeOut == strikeOut)
+ return;
+
detach();
d->strikeOut = strikeOut;
}
diff --git a/src/gui/text/qglyphrun.h b/src/gui/text/qglyphrun.h
index da88bc72f9..81783a8653 100644
--- a/src/gui/text/qglyphrun.h
+++ b/src/gui/text/qglyphrun.h
@@ -39,8 +39,8 @@
**
****************************************************************************/
-#ifndef QGLYPHRUN_H
-#define QGLYPHRUN_H
+#ifndef QOpenGLYPHRUN_H
+#define QOpenGLYPHRUN_H
#include <QtCore/qsharedpointer.h>
#include <QtCore/qvector.h>
@@ -79,8 +79,10 @@ public:
void clear();
QGlyphRun &operator=(const QGlyphRun &other);
+
bool operator==(const QGlyphRun &other) const;
- bool operator!=(const QGlyphRun &other) const;
+ inline bool operator!=(const QGlyphRun &other) const
+ { return !operator==(other); }
void setOverline(bool overline);
bool overline() const;
@@ -113,4 +115,4 @@ QT_END_HEADER
#endif // QT_NO_RAWFONT
-#endif // QGLYPHS_H
+#endif // QOpenGLYPHS_H
diff --git a/src/gui/text/qglyphrun_p.h b/src/gui/text/qglyphrun_p.h
index b632678971..96a80bebe9 100644
--- a/src/gui/text/qglyphrun_p.h
+++ b/src/gui/text/qglyphrun_p.h
@@ -39,8 +39,8 @@
**
****************************************************************************/
-#ifndef QGLYPHRUN_P_H
-#define QGLYPHRUN_P_H
+#ifndef QOpenGLYPHRUN_P_H
+#define QOpenGLYPHRUN_P_H
//
// W A R N I N G
@@ -119,6 +119,6 @@ QT_END_NAMESPACE
QT_END_HEADER
-#endif // QGLYPHS_P_H
+#endif // QOpenGLYPHS_P_H
#endif // QT_NO_RAWFONT
diff --git a/src/gui/text/qlinecontrol.cpp b/src/gui/text/qlinecontrol.cpp
new file mode 100644
index 0000000000..eb6f22b726
--- /dev/null
+++ b/src/gui/text/qlinecontrol.cpp
@@ -0,0 +1,1705 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// ###
+#define QT_NO_ACCESSIBILITY
+#define QT_NO_IM
+
+#include "qlinecontrol_p.h"
+
+#ifndef QT_NO_LINEEDIT
+
+#include "qclipboard.h"
+#ifndef QT_NO_ACCESSIBILITY
+#include "qaccessible.h"
+#endif
+#include "qguiapplication.h"
+#include "qstylehints.h"
+
+QT_BEGIN_NAMESPACE
+
+// ### these should come from QStyleHints
+const int textCursorWidth = 1;
+const bool fullWidthSelection = true;
+
+/*!
+ \internal
+
+ Updates the display text based of the current edit text
+ If the text has changed will emit displayTextChanged()
+*/
+void QLineControl::updateDisplayText(bool forceUpdate)
+{
+ QString orig = m_textLayout.text();
+ QString str;
+ if (m_echoMode == NoEcho)
+ str = QString::fromLatin1("");
+ else
+ str = m_text;
+
+ if (m_echoMode == Password || (m_echoMode == PasswordEchoOnEdit
+ && !m_passwordEchoEditing))
+ str.fill(m_passwordCharacter);
+
+ // replace certain non-printable characters with spaces (to avoid
+ // drawing boxes when using fonts that don't have glyphs for such
+ // characters)
+ QChar* uc = str.data();
+ for (int i = 0; i < (int)str.length(); ++i) {
+ if ((uc[i] < 0x20 && uc[i] != 0x09)
+ || uc[i] == QChar::LineSeparator
+ || uc[i] == QChar::ParagraphSeparator
+ || uc[i] == QChar::ObjectReplacementCharacter)
+ uc[i] = QChar(0x0020);
+ }
+
+ m_textLayout.setText(str);
+
+ QTextOption option;
+ option.setTextDirection(m_layoutDirection);
+ option.setFlags(QTextOption::IncludeTrailingSpaces);
+ m_textLayout.setTextOption(option);
+
+ m_textLayout.beginLayout();
+ QTextLine l = m_textLayout.createLine();
+ m_textLayout.endLayout();
+ m_ascent = qRound(l.ascent());
+
+ if (str != orig || forceUpdate)
+ emit displayTextChanged(str);
+}
+
+#ifndef QT_NO_CLIPBOARD
+/*!
+ \internal
+
+ Copies the currently selected text into the clipboard using the given
+ \a mode.
+
+ \note If the echo mode is set to a mode other than Normal then copy
+ will not work. This is to prevent using copy as a method of bypassing
+ password features of the line control.
+*/
+void QLineControl::copy(QClipboard::Mode mode) const
+{
+ QString t = selectedText();
+ if (!t.isEmpty() && m_echoMode == Normal) {
+ disconnect(QGuiApplication::clipboard(), SIGNAL(selectionChanged()), this, 0);
+ QGuiApplication::clipboard()->setText(t, mode);
+ connect(QGuiApplication::clipboard(), SIGNAL(selectionChanged()),
+ this, SLOT(_q_clipboardChanged()));
+ }
+}
+
+/*!
+ \internal
+
+ Inserts the text stored in the application clipboard into the line
+ control.
+
+ \sa insert()
+*/
+void QLineControl::paste(QClipboard::Mode clipboardMode)
+{
+ QString clip = QGuiApplication::clipboard()->text(clipboardMode);
+ if (!clip.isEmpty() || hasSelectedText()) {
+ separate(); //make it a separate undo/redo command
+ insert(clip);
+ separate();
+ }
+}
+
+#endif // !QT_NO_CLIPBOARD
+
+/*!
+ \internal
+
+ Handles the behavior for the backspace key or function.
+ Removes the current selection if there is a selection, otherwise
+ removes the character prior to the cursor position.
+
+ \sa del()
+*/
+void QLineControl::backspace()
+{
+ int priorState = m_undoState;
+ if (hasSelectedText()) {
+ removeSelectedText();
+ } else if (m_cursor) {
+ --m_cursor;
+ if (m_maskData)
+ m_cursor = prevMaskBlank(m_cursor);
+ QChar uc = m_text.at(m_cursor);
+ if (m_cursor > 0 && uc.unicode() >= 0xdc00 && uc.unicode() < 0xe000) {
+ // second half of a surrogate, check if we have the first half as well,
+ // if yes delete both at once
+ uc = m_text.at(m_cursor - 1);
+ if (uc.unicode() >= 0xd800 && uc.unicode() < 0xdc00) {
+ internalDelete(true);
+ --m_cursor;
+ }
+ }
+ internalDelete(true);
+ }
+ finishChange(priorState);
+}
+
+/*!
+ \internal
+
+ Handles the behavior for the delete key or function.
+ Removes the current selection if there is a selection, otherwise
+ removes the character after the cursor position.
+
+ \sa del()
+*/
+void QLineControl::del()
+{
+ int priorState = m_undoState;
+ if (hasSelectedText()) {
+ removeSelectedText();
+ } else {
+ int n = m_textLayout.nextCursorPosition(m_cursor) - m_cursor;
+ while (n--)
+ internalDelete();
+ }
+ finishChange(priorState);
+}
+
+/*!
+ \internal
+
+ Inserts the given \a newText at the current cursor position.
+ If there is any selected text it is removed prior to insertion of
+ the new text.
+*/
+void QLineControl::insert(const QString &newText)
+{
+ int priorState = m_undoState;
+ removeSelectedText();
+ internalInsert(newText);
+ finishChange(priorState);
+}
+
+/*!
+ \internal
+
+ Clears the line control text.
+*/
+void QLineControl::clear()
+{
+ int priorState = m_undoState;
+ m_selstart = 0;
+ m_selend = m_text.length();
+ removeSelectedText();
+ separate();
+ finishChange(priorState, /*update*/false, /*edited*/false);
+}
+
+/*!
+ \internal
+
+ Sets \a length characters from the given \a start position as selected.
+ The given \a start position must be within the current text for
+ the line control. If \a length characters cannot be selected, then
+ the selection will extend to the end of the current text.
+*/
+void QLineControl::setSelection(int start, int length)
+{
+ if(start < 0 || start > (int)m_text.length()){
+ qWarning("QLineControl::setSelection: Invalid start position");
+ return;
+ }
+
+ if (length > 0) {
+ if (start == m_selstart && start + length == m_selend)
+ return;
+ m_selstart = start;
+ m_selend = qMin(start + length, (int)m_text.length());
+ m_cursor = m_selend;
+ } else if (length < 0){
+ if (start == m_selend && start + length == m_selstart)
+ return;
+ m_selstart = qMax(start + length, 0);
+ m_selend = start;
+ m_cursor = m_selstart;
+ } else if (m_selstart != m_selend) {
+ m_selstart = 0;
+ m_selend = 0;
+ m_cursor = start;
+ } else {
+ m_cursor = start;
+ emitCursorPositionChanged();
+ return;
+ }
+ emit selectionChanged();
+ emitCursorPositionChanged();
+}
+
+void QLineControl::_q_clipboardChanged()
+{
+}
+
+void QLineControl::_q_deleteSelected()
+{
+ if (!hasSelectedText())
+ return;
+
+ int priorState = m_undoState;
+ emit resetInputContext();
+ removeSelectedText();
+ separate();
+ finishChange(priorState);
+}
+
+/*!
+ \internal
+
+ Initializes the line control with a starting text value of \a txt.
+*/
+void QLineControl::init(const QString &txt)
+{
+ m_text = txt;
+ updateDisplayText();
+ m_cursor = m_text.length();
+}
+
+/*!
+ \internal
+
+ Sets the password echo editing to \a editing. If password echo editing
+ is true, then the text of the password is displayed even if the echo
+ mode is set to QLineEdit::PasswordEchoOnEdit. Password echoing editing
+ does not affect other echo modes.
+*/
+void QLineControl::updatePasswordEchoEditing(bool editing)
+{
+ m_passwordEchoEditing = editing;
+ updateDisplayText();
+}
+
+/*!
+ \internal
+
+ Returns the cursor position of the given \a x pixel value in relation
+ to the displayed text. The given \a betweenOrOn specified what kind
+ of cursor position is requested.
+*/
+int QLineControl::xToPos(int x, QTextLine::CursorPosition betweenOrOn) const
+{
+ return m_textLayout.lineAt(0).xToCursor(x, betweenOrOn);
+}
+
+/*!
+ \internal
+
+ Returns the bounds of the current cursor, as defined as a
+ between characters cursor.
+*/
+QRect QLineControl::cursorRect() const
+{
+ QTextLine l = m_textLayout.lineAt(0);
+ int c = m_cursor;
+ if (m_preeditCursor != -1)
+ c += m_preeditCursor;
+ int cix = qRound(l.cursorToX(c));
+ int w = m_cursorWidth;
+ int ch = l.height() + 1;
+
+ return QRect(cix-5, 0, w+9, ch);
+}
+
+/*!
+ \internal
+
+ Fixes the current text so that it is valid given any set validators.
+
+ Returns true if the text was changed. Otherwise returns false.
+*/
+bool QLineControl::fixup() // this function assumes that validate currently returns != Acceptable
+{
+#ifndef QT_NO_VALIDATOR
+ if (m_validator) {
+ QString textCopy = m_text;
+ int cursorCopy = m_cursor;
+ m_validator->fixup(textCopy);
+ if (m_validator->validate(textCopy, cursorCopy) == QValidator::Acceptable) {
+ if (textCopy != m_text || cursorCopy != m_cursor)
+ internalSetText(textCopy, cursorCopy);
+ return true;
+ }
+ }
+#endif
+ return false;
+}
+
+/*!
+ \internal
+
+ Moves the cursor to the given position \a pos. If \a mark is true will
+ adjust the currently selected text.
+*/
+void QLineControl::moveCursor(int pos, bool mark)
+{
+ if (pos != m_cursor) {
+ separate();
+ if (m_maskData)
+ pos = pos > m_cursor ? nextMaskBlank(pos) : prevMaskBlank(pos);
+ }
+ if (mark) {
+ int anchor;
+ if (m_selend > m_selstart && m_cursor == m_selstart)
+ anchor = m_selend;
+ else if (m_selend > m_selstart && m_cursor == m_selend)
+ anchor = m_selstart;
+ else
+ anchor = m_cursor;
+ m_selstart = qMin(anchor, pos);
+ m_selend = qMax(anchor, pos);
+ updateDisplayText();
+ } else {
+ internalDeselect();
+ }
+ m_cursor = pos;
+ if (mark || m_selDirty) {
+ m_selDirty = false;
+ emit selectionChanged();
+ }
+ emitCursorPositionChanged();
+}
+
+/*!
+ \internal
+
+ Applies the given input method event \a event to the text of the line
+ control
+*/
+void QLineControl::processInputMethodEvent(QInputMethodEvent *event)
+{
+ int priorState = 0;
+ bool isGettingInput = !event->commitString().isEmpty()
+ || event->preeditString() != preeditAreaText()
+ || event->replacementLength() > 0;
+ bool cursorPositionChanged = false;
+
+ if (isGettingInput) {
+ // If any text is being input, remove selected text.
+ priorState = m_undoState;
+ if (echoMode() == PasswordEchoOnEdit && !passwordEchoEditing()) {
+ updatePasswordEchoEditing(true);
+ m_selstart = 0;
+ m_selend = m_text.length();
+ }
+ removeSelectedText();
+ }
+
+ int c = m_cursor; // cursor position after insertion of commit string
+ if (event->replacementStart() <= 0)
+ c += event->commitString().length() - qMin(-event->replacementStart(), event->replacementLength());
+
+ m_cursor += event->replacementStart();
+ if (m_cursor < 0)
+ m_cursor = 0;
+
+ // insert commit string
+ if (event->replacementLength()) {
+ m_selstart = m_cursor;
+ m_selend = m_selstart + event->replacementLength();
+ removeSelectedText();
+ }
+ if (!event->commitString().isEmpty()) {
+ internalInsert(event->commitString());
+ cursorPositionChanged = true;
+ }
+
+ m_cursor = qBound(0, c, m_text.length());
+
+ for (int i = 0; i < event->attributes().size(); ++i) {
+ const QInputMethodEvent::Attribute &a = event->attributes().at(i);
+ if (a.type == QInputMethodEvent::Selection) {
+ m_cursor = qBound(0, a.start + a.length, m_text.length());
+ if (a.length) {
+ m_selstart = qMax(0, qMin(a.start, m_text.length()));
+ m_selend = m_cursor;
+ if (m_selend < m_selstart) {
+ qSwap(m_selstart, m_selend);
+ }
+ } else {
+ m_selstart = m_selend = 0;
+ }
+ cursorPositionChanged = true;
+ }
+ }
+#ifndef QT_NO_IM
+ setPreeditArea(m_cursor, event->preeditString());
+#endif //QT_NO_IM
+ const int oldPreeditCursor = m_preeditCursor;
+ m_preeditCursor = event->preeditString().length();
+ m_hideCursor = false;
+ QList<QTextLayout::FormatRange> formats;
+ for (int i = 0; i < event->attributes().size(); ++i) {
+ const QInputMethodEvent::Attribute &a = event->attributes().at(i);
+ if (a.type == QInputMethodEvent::Cursor) {
+ m_preeditCursor = a.start;
+ m_hideCursor = !a.length;
+ } else if (a.type == QInputMethodEvent::TextFormat) {
+ QTextCharFormat f = qvariant_cast<QTextFormat>(a.value).toCharFormat();
+ if (f.isValid()) {
+ QTextLayout::FormatRange o;
+ o.start = a.start + m_cursor;
+ o.length = a.length;
+ o.format = f;
+ formats.append(o);
+ }
+ }
+ }
+ m_textLayout.setAdditionalFormats(formats);
+ updateDisplayText(/*force*/ true);
+ if (cursorPositionChanged)
+ emitCursorPositionChanged();
+ else if (m_preeditCursor != oldPreeditCursor)
+ emit updateMicroFocus();
+ if (isGettingInput)
+ finishChange(priorState);
+}
+
+/*!
+ \internal
+
+ Draws the display text for the line control using the given
+ \a painter, \a clip, and \a offset. Which aspects of the display text
+ are drawn is specified by the given \a flags.
+
+ If the flags contain DrawSelections, then the selection or input mask
+ backgrounds and foregrounds will be applied before drawing the text.
+
+ If the flags contain DrawCursor a cursor of the current cursorWidth()
+ will be drawn after drawing the text.
+
+ The display text will only be drawn if the flags contain DrawText
+*/
+void QLineControl::draw(QPainter *painter, const QPoint &offset, const QRect &clip, int flags)
+{
+ QVector<QTextLayout::FormatRange> selections;
+ if (flags & DrawSelections) {
+ QTextLayout::FormatRange o;
+ if (m_selstart < m_selend) {
+ o.start = m_selstart;
+ o.length = m_selend - m_selstart;
+ o.format.setBackground(m_palette.brush(QPalette::Highlight));
+ o.format.setForeground(m_palette.brush(QPalette::HighlightedText));
+ } else {
+ // mask selection
+ if(!m_blinkPeriod || m_blinkStatus){
+ o.start = m_cursor;
+ o.length = 1;
+ o.format.setBackground(m_palette.brush(QPalette::Text));
+ o.format.setForeground(m_palette.brush(QPalette::Window));
+ }
+ }
+ selections.append(o);
+ }
+
+ if (flags & DrawText)
+ m_textLayout.draw(painter, offset, selections, clip);
+
+ if (flags & DrawCursor){
+ int cursor = m_cursor;
+ if (m_preeditCursor != -1)
+ cursor += m_preeditCursor;
+ if (!m_hideCursor && (!m_blinkPeriod || m_blinkStatus))
+ m_textLayout.drawCursor(painter, offset, cursor, m_cursorWidth);
+ }
+}
+
+/*!
+ \internal
+
+ Sets the selection to cover the word at the given cursor position.
+ The word boundaries are defined by the behavior of QTextLayout::SkipWords
+ cursor mode.
+*/
+void QLineControl::selectWordAtPos(int cursor)
+{
+ int next = cursor + 1;
+ if(next > end())
+ --next;
+ int c = m_textLayout.previousCursorPosition(next, QTextLayout::SkipWords);
+ moveCursor(c, false);
+ // ## text layout should support end of words.
+ int end = m_textLayout.nextCursorPosition(c, QTextLayout::SkipWords);
+ while (end > cursor && m_text[end-1].isSpace())
+ --end;
+ moveCursor(end, true);
+}
+
+/*!
+ \internal
+
+ Completes a change to the line control text. If the change is not valid
+ will undo the line control state back to the given \a validateFromState.
+
+ If \a edited is true and the change is valid, will emit textEdited() in
+ addition to textChanged(). Otherwise only emits textChanged() on a valid
+ change.
+
+ The \a update value is currently unused.
+*/
+bool QLineControl::finishChange(int validateFromState, bool update, bool edited)
+{
+ Q_UNUSED(update)
+ bool lineDirty = m_selDirty;
+ if (m_textDirty) {
+ // do validation
+ bool wasValidInput = m_validInput;
+ m_validInput = true;
+#ifndef QT_NO_VALIDATOR
+ if (m_validator) {
+ m_validInput = false;
+ QString textCopy = m_text;
+ int cursorCopy = m_cursor;
+ m_validInput = (m_validator->validate(textCopy, cursorCopy) != QValidator::Invalid);
+ if (m_validInput) {
+ if (m_text != textCopy) {
+ internalSetText(textCopy, cursorCopy);
+ return true;
+ }
+ m_cursor = cursorCopy;
+ }
+ }
+#endif
+ if (validateFromState >= 0 && wasValidInput && !m_validInput) {
+ if (m_transactions.count())
+ return false;
+ internalUndo(validateFromState);
+ m_history.resize(m_undoState);
+ if (m_modifiedState > m_undoState)
+ m_modifiedState = -1;
+ m_validInput = true;
+ m_textDirty = false;
+ }
+ updateDisplayText();
+ lineDirty |= m_textDirty;
+ if (m_textDirty) {
+ m_textDirty = false;
+ QString actualText = text();
+ if (edited)
+ emit textEdited(actualText);
+ emit textChanged(actualText);
+ }
+ }
+ if (m_selDirty) {
+ m_selDirty = false;
+ emit selectionChanged();
+ }
+ emitCursorPositionChanged();
+ return true;
+}
+
+/*!
+ \internal
+
+ An internal function for setting the text of the line control.
+*/
+void QLineControl::internalSetText(const QString &txt, int pos, bool edited)
+{
+ internalDeselect();
+ emit resetInputContext();
+ QString oldText = m_text;
+ if (m_maskData) {
+ m_text = maskString(0, txt, true);
+ m_text += clearString(m_text.length(), m_maxLength - m_text.length());
+ } else {
+ m_text = txt.isEmpty() ? txt : txt.left(m_maxLength);
+ }
+ m_history.clear();
+ m_modifiedState = m_undoState = 0;
+ m_cursor = (pos < 0 || pos > m_text.length()) ? m_text.length() : pos;
+ m_textDirty = (oldText != m_text);
+
+#ifdef QT_NO_ACCESSIBILITY
+ Q_UNUSED(edited)
+#else
+ bool changed = finishChange(-1, true, edited);
+ if (changed)
+ QAccessible::updateAccessibility(parent(), 0, QAccessible::TextUpdated);
+#endif
+}
+
+
+/*!
+ \internal
+
+ Adds the given \a command to the undo history
+ of the line control. Does not apply the command.
+*/
+void QLineControl::addCommand(const Command &cmd)
+{
+ if (m_separator && m_undoState && m_history[m_undoState - 1].type != Separator) {
+ m_history.resize(m_undoState + 2);
+ m_history[m_undoState++] = Command(Separator, m_cursor, 0, m_selstart, m_selend);
+ } else {
+ m_history.resize(m_undoState + 1);
+ }
+ m_separator = false;
+ m_history[m_undoState++] = cmd;
+}
+
+/*!
+ \internal
+
+ Inserts the given string \a s into the line
+ control.
+
+ Also adds the appropriate commands into the undo history.
+ This function does not call finishChange(), and may leave the text
+ in an invalid state.
+*/
+void QLineControl::internalInsert(const QString &s)
+{
+ if (hasSelectedText())
+ addCommand(Command(SetSelection, m_cursor, 0, m_selstart, m_selend));
+ if (m_maskData) {
+ QString ms = maskString(m_cursor, s);
+ for (int i = 0; i < (int) ms.length(); ++i) {
+ addCommand (Command(DeleteSelection, m_cursor + i, m_text.at(m_cursor + i), -1, -1));
+ addCommand(Command(Insert, m_cursor + i, ms.at(i), -1, -1));
+ }
+ m_text.replace(m_cursor, ms.length(), ms);
+ m_cursor += ms.length();
+ m_cursor = nextMaskBlank(m_cursor);
+ m_textDirty = true;
+ } else {
+ int remaining = m_maxLength - m_text.length();
+ if (remaining != 0) {
+ m_text.insert(m_cursor, s.left(remaining));
+ for (int i = 0; i < (int) s.left(remaining).length(); ++i)
+ addCommand(Command(Insert, m_cursor++, s.at(i), -1, -1));
+ m_textDirty = true;
+ }
+ }
+}
+
+/*!
+ \internal
+
+ deletes a single character from the current text. If \a wasBackspace,
+ the character prior to the cursor is removed. Otherwise the character
+ after the cursor is removed.
+
+ Also adds the appropriate commands into the undo history.
+ This function does not call finishChange(), and may leave the text
+ in an invalid state.
+*/
+void QLineControl::internalDelete(bool wasBackspace)
+{
+ if (m_cursor < (int) m_text.length()) {
+ if (hasSelectedText())
+ addCommand(Command(SetSelection, m_cursor, 0, m_selstart, m_selend));
+ addCommand(Command((CommandType)((m_maskData ? 2 : 0) + (wasBackspace ? Remove : Delete)),
+ m_cursor, m_text.at(m_cursor), -1, -1));
+ if (m_maskData) {
+ m_text.replace(m_cursor, 1, clearString(m_cursor, 1));
+ addCommand(Command(Insert, m_cursor, m_text.at(m_cursor), -1, -1));
+ } else {
+ m_text.remove(m_cursor, 1);
+ }
+ m_textDirty = true;
+ }
+}
+
+/*!
+ \internal
+
+ removes the currently selected text from the line control.
+
+ Also adds the appropriate commands into the undo history.
+ This function does not call finishChange(), and may leave the text
+ in an invalid state.
+*/
+void QLineControl::removeSelectedText()
+{
+ if (m_selstart < m_selend && m_selend <= (int) m_text.length()) {
+ separate();
+ int i ;
+ addCommand(Command(SetSelection, m_cursor, 0, m_selstart, m_selend));
+ if (m_selstart <= m_cursor && m_cursor < m_selend) {
+ // cursor is within the selection. Split up the commands
+ // to be able to restore the correct cursor position
+ for (i = m_cursor; i >= m_selstart; --i)
+ addCommand (Command(DeleteSelection, i, m_text.at(i), -1, 1));
+ for (i = m_selend - 1; i > m_cursor; --i)
+ addCommand (Command(DeleteSelection, i - m_cursor + m_selstart - 1, m_text.at(i), -1, -1));
+ } else {
+ for (i = m_selend-1; i >= m_selstart; --i)
+ addCommand (Command(RemoveSelection, i, m_text.at(i), -1, -1));
+ }
+ if (m_maskData) {
+ m_text.replace(m_selstart, m_selend - m_selstart, clearString(m_selstart, m_selend - m_selstart));
+ for (int i = 0; i < m_selend - m_selstart; ++i)
+ addCommand(Command(Insert, m_selstart + i, m_text.at(m_selstart + i), -1, -1));
+ } else {
+ m_text.remove(m_selstart, m_selend - m_selstart);
+ }
+ if (m_cursor > m_selstart)
+ m_cursor -= qMin(m_cursor, m_selend) - m_selstart;
+ internalDeselect();
+ m_textDirty = true;
+ }
+}
+
+/*!
+ \internal
+
+ Parses the input mask specified by \a maskFields to generate
+ the mask data used to handle input masks.
+*/
+void QLineControl::parseInputMask(const QString &maskFields)
+{
+ int delimiter = maskFields.indexOf(QLatin1Char(';'));
+ if (maskFields.isEmpty() || delimiter == 0) {
+ if (m_maskData) {
+ delete [] m_maskData;
+ m_maskData = 0;
+ m_maxLength = 32767;
+ internalSetText(QString());
+ }
+ return;
+ }
+
+ if (delimiter == -1) {
+ m_blank = QLatin1Char(' ');
+ m_inputMask = maskFields;
+ } else {
+ m_inputMask = maskFields.left(delimiter);
+ m_blank = (delimiter + 1 < maskFields.length()) ? maskFields[delimiter + 1] : QLatin1Char(' ');
+ }
+
+ // calculate m_maxLength / m_maskData length
+ m_maxLength = 0;
+ QChar c = 0;
+ for (int i=0; i<m_inputMask.length(); i++) {
+ c = m_inputMask.at(i);
+ if (i > 0 && m_inputMask.at(i-1) == QLatin1Char('\\')) {
+ m_maxLength++;
+ continue;
+ }
+ if (c != QLatin1Char('\\') && c != QLatin1Char('!') &&
+ c != QLatin1Char('<') && c != QLatin1Char('>') &&
+ c != QLatin1Char('{') && c != QLatin1Char('}') &&
+ c != QLatin1Char('[') && c != QLatin1Char(']'))
+ m_maxLength++;
+ }
+
+ delete [] m_maskData;
+ m_maskData = new MaskInputData[m_maxLength];
+
+ MaskInputData::Casemode m = MaskInputData::NoCaseMode;
+ c = 0;
+ bool s;
+ bool escape = false;
+ int index = 0;
+ for (int i = 0; i < m_inputMask.length(); i++) {
+ c = m_inputMask.at(i);
+ if (escape) {
+ s = true;
+ m_maskData[index].maskChar = c;
+ m_maskData[index].separator = s;
+ m_maskData[index].caseMode = m;
+ index++;
+ escape = false;
+ } else if (c == QLatin1Char('<')) {
+ m = MaskInputData::Lower;
+ } else if (c == QLatin1Char('>')) {
+ m = MaskInputData::Upper;
+ } else if (c == QLatin1Char('!')) {
+ m = MaskInputData::NoCaseMode;
+ } else if (c != QLatin1Char('{') && c != QLatin1Char('}') && c != QLatin1Char('[') && c != QLatin1Char(']')) {
+ switch (c.unicode()) {
+ case 'A':
+ case 'a':
+ case 'N':
+ case 'n':
+ case 'X':
+ case 'x':
+ case '9':
+ case '0':
+ case 'D':
+ case 'd':
+ case '#':
+ case 'H':
+ case 'h':
+ case 'B':
+ case 'b':
+ s = false;
+ break;
+ case '\\':
+ escape = true;
+ default:
+ s = true;
+ break;
+ }
+
+ if (!escape) {
+ m_maskData[index].maskChar = c;
+ m_maskData[index].separator = s;
+ m_maskData[index].caseMode = m;
+ index++;
+ }
+ }
+ }
+ internalSetText(m_text);
+}
+
+
+/*!
+ \internal
+
+ checks if the key is valid compared to the inputMask
+*/
+bool QLineControl::isValidInput(QChar key, QChar mask) const
+{
+ switch (mask.unicode()) {
+ case 'A':
+ if (key.isLetter())
+ return true;
+ break;
+ case 'a':
+ if (key.isLetter() || key == m_blank)
+ return true;
+ break;
+ case 'N':
+ if (key.isLetterOrNumber())
+ return true;
+ break;
+ case 'n':
+ if (key.isLetterOrNumber() || key == m_blank)
+ return true;
+ break;
+ case 'X':
+ if (key.isPrint())
+ return true;
+ break;
+ case 'x':
+ if (key.isPrint() || key == m_blank)
+ return true;
+ break;
+ case '9':
+ if (key.isNumber())
+ return true;
+ break;
+ case '0':
+ if (key.isNumber() || key == m_blank)
+ return true;
+ break;
+ case 'D':
+ if (key.isNumber() && key.digitValue() > 0)
+ return true;
+ break;
+ case 'd':
+ if ((key.isNumber() && key.digitValue() > 0) || key == m_blank)
+ return true;
+ break;
+ case '#':
+ if (key.isNumber() || key == QLatin1Char('+') || key == QLatin1Char('-') || key == m_blank)
+ return true;
+ break;
+ case 'B':
+ if (key == QLatin1Char('0') || key == QLatin1Char('1'))
+ return true;
+ break;
+ case 'b':
+ if (key == QLatin1Char('0') || key == QLatin1Char('1') || key == m_blank)
+ return true;
+ break;
+ case 'H':
+ if (key.isNumber() || (key >= QLatin1Char('a') && key <= QLatin1Char('f')) || (key >= QLatin1Char('A') && key <= QLatin1Char('F')))
+ return true;
+ break;
+ case 'h':
+ if (key.isNumber() || (key >= QLatin1Char('a') && key <= QLatin1Char('f')) || (key >= QLatin1Char('A') && key <= QLatin1Char('F')) || key == m_blank)
+ return true;
+ break;
+ default:
+ break;
+ }
+ return false;
+}
+
+/*!
+ \internal
+
+ Returns true if the given text \a str is valid for any
+ validator or input mask set for the line control.
+
+ Otherwise returns false
+*/
+bool QLineControl::hasAcceptableInput(const QString &str) const
+{
+#ifndef QT_NO_VALIDATOR
+ QString textCopy = str;
+ int cursorCopy = m_cursor;
+ if (m_validator && m_validator->validate(textCopy, cursorCopy)
+ != QValidator::Acceptable)
+ return false;
+#endif
+
+ if (!m_maskData)
+ return true;
+
+ if (str.length() != m_maxLength)
+ return false;
+
+ for (int i=0; i < m_maxLength; ++i) {
+ if (m_maskData[i].separator) {
+ if (str.at(i) != m_maskData[i].maskChar)
+ return false;
+ } else {
+ if (!isValidInput(str.at(i), m_maskData[i].maskChar))
+ return false;
+ }
+ }
+ return true;
+}
+
+/*!
+ \internal
+
+ Applies the inputMask on \a str starting from position \a pos in the mask. \a clear
+ specifies from where characters should be gotten when a separator is met in \a str - true means
+ that blanks will be used, false that previous input is used.
+ Calling this when no inputMask is set is undefined.
+*/
+QString QLineControl::maskString(uint pos, const QString &str, bool clear) const
+{
+ if (pos >= (uint)m_maxLength)
+ return QString::fromLatin1("");
+
+ QString fill;
+ fill = clear ? clearString(0, m_maxLength) : m_text;
+
+ int strIndex = 0;
+ QString s = QString::fromLatin1("");
+ int i = pos;
+ while (i < m_maxLength) {
+ if (strIndex < str.length()) {
+ if (m_maskData[i].separator) {
+ s += m_maskData[i].maskChar;
+ if (str[(int)strIndex] == m_maskData[i].maskChar)
+ strIndex++;
+ ++i;
+ } else {
+ if (isValidInput(str[(int)strIndex], m_maskData[i].maskChar)) {
+ switch (m_maskData[i].caseMode) {
+ case MaskInputData::Upper:
+ s += str[(int)strIndex].toUpper();
+ break;
+ case MaskInputData::Lower:
+ s += str[(int)strIndex].toLower();
+ break;
+ default:
+ s += str[(int)strIndex];
+ }
+ ++i;
+ } else {
+ // search for separator first
+ int n = findInMask(i, true, true, str[(int)strIndex]);
+ if (n != -1) {
+ if (str.length() != 1 || i == 0 || (i > 0 && (!m_maskData[i-1].separator || m_maskData[i-1].maskChar != str[(int)strIndex]))) {
+ s += fill.mid(i, n-i+1);
+ i = n + 1; // update i to find + 1
+ }
+ } else {
+ // search for valid m_blank if not
+ n = findInMask(i, true, false, str[(int)strIndex]);
+ if (n != -1) {
+ s += fill.mid(i, n-i);
+ switch (m_maskData[n].caseMode) {
+ case MaskInputData::Upper:
+ s += str[(int)strIndex].toUpper();
+ break;
+ case MaskInputData::Lower:
+ s += str[(int)strIndex].toLower();
+ break;
+ default:
+ s += str[(int)strIndex];
+ }
+ i = n + 1; // updates i to find + 1
+ }
+ }
+ }
+ ++strIndex;
+ }
+ } else
+ break;
+ }
+
+ return s;
+}
+
+
+
+/*!
+ \internal
+
+ Returns a "cleared" string with only separators and blank chars.
+ Calling this when no inputMask is set is undefined.
+*/
+QString QLineControl::clearString(uint pos, uint len) const
+{
+ if (pos >= (uint)m_maxLength)
+ return QString();
+
+ QString s;
+ int end = qMin((uint)m_maxLength, pos + len);
+ for (int i = pos; i < end; ++i)
+ if (m_maskData[i].separator)
+ s += m_maskData[i].maskChar;
+ else
+ s += m_blank;
+
+ return s;
+}
+
+/*!
+ \internal
+
+ Strips blank parts of the input in a QLineControl when an inputMask is set,
+ separators are still included. Typically "127.0__.0__.1__" becomes "127.0.0.1".
+*/
+QString QLineControl::stripString(const QString &str) const
+{
+ if (!m_maskData)
+ return str;
+
+ QString s;
+ int end = qMin(m_maxLength, (int)str.length());
+ for (int i = 0; i < end; ++i)
+ if (m_maskData[i].separator)
+ s += m_maskData[i].maskChar;
+ else
+ if (str[i] != m_blank)
+ s += str[i];
+
+ return s;
+}
+
+/*!
+ \internal
+ searches forward/backward in m_maskData for either a separator or a m_blank
+*/
+int QLineControl::findInMask(int pos, bool forward, bool findSeparator, QChar searchChar) const
+{
+ if (pos >= m_maxLength || pos < 0)
+ return -1;
+
+ int end = forward ? m_maxLength : -1;
+ int step = forward ? 1 : -1;
+ int i = pos;
+
+ while (i != end) {
+ if (findSeparator) {
+ if (m_maskData[i].separator && m_maskData[i].maskChar == searchChar)
+ return i;
+ } else {
+ if (!m_maskData[i].separator) {
+ if (searchChar.isNull())
+ return i;
+ else if (isValidInput(searchChar, m_maskData[i].maskChar))
+ return i;
+ }
+ }
+ i += step;
+ }
+ return -1;
+}
+
+void QLineControl::internalUndo(int until)
+{
+ if (!isUndoAvailable())
+ return;
+ internalDeselect();
+ while (m_undoState && m_undoState > until) {
+ Command& cmd = m_history[--m_undoState];
+ switch (cmd.type) {
+ case Insert:
+ m_text.remove(cmd.pos, 1);
+ m_cursor = cmd.pos;
+ break;
+ case SetSelection:
+ m_selstart = cmd.selStart;
+ m_selend = cmd.selEnd;
+ m_cursor = cmd.pos;
+ break;
+ case Remove:
+ case RemoveSelection:
+ m_text.insert(cmd.pos, cmd.uc);
+ m_cursor = cmd.pos + 1;
+ break;
+ case Delete:
+ case DeleteSelection:
+ m_text.insert(cmd.pos, cmd.uc);
+ m_cursor = cmd.pos;
+ break;
+ case Separator:
+ continue;
+ }
+ if (until < 0 && m_undoState) {
+ Command& next = m_history[m_undoState-1];
+ if (next.type != cmd.type && next.type < RemoveSelection
+ && (cmd.type < RemoveSelection || next.type == Separator))
+ break;
+ }
+ }
+ m_textDirty = true;
+ emitCursorPositionChanged();
+}
+
+void QLineControl::internalRedo()
+{
+ if (!isRedoAvailable())
+ return;
+ internalDeselect();
+ while (m_undoState < (int)m_history.size()) {
+ Command& cmd = m_history[m_undoState++];
+ switch (cmd.type) {
+ case Insert:
+ m_text.insert(cmd.pos, cmd.uc);
+ m_cursor = cmd.pos + 1;
+ break;
+ case SetSelection:
+ m_selstart = cmd.selStart;
+ m_selend = cmd.selEnd;
+ m_cursor = cmd.pos;
+ break;
+ case Remove:
+ case Delete:
+ case RemoveSelection:
+ case DeleteSelection:
+ m_text.remove(cmd.pos, 1);
+ m_selstart = cmd.selStart;
+ m_selend = cmd.selEnd;
+ m_cursor = cmd.pos;
+ break;
+ case Separator:
+ m_selstart = cmd.selStart;
+ m_selend = cmd.selEnd;
+ m_cursor = cmd.pos;
+ break;
+ }
+ if (m_undoState < (int)m_history.size()) {
+ Command& next = m_history[m_undoState];
+ if (next.type != cmd.type && cmd.type < RemoveSelection && next.type != Separator
+ && (next.type < RemoveSelection || cmd.type == Separator))
+ break;
+ }
+ }
+ m_textDirty = true;
+ emitCursorPositionChanged();
+}
+
+/*!
+ \internal
+
+ If the current cursor position differs from the last emitted cursor
+ position, emits cursorPositionChanged().
+*/
+void QLineControl::emitCursorPositionChanged()
+{
+ if (m_cursor != m_lastCursorPos) {
+ const int oldLast = m_lastCursorPos;
+ m_lastCursorPos = m_cursor;
+ cursorPositionChanged(oldLast, m_cursor);
+#ifndef QT_NO_ACCESSIBILITY
+ QAccessible::updateAccessibility(parent(), 0, QAccessible::TextCaretMoved);
+#endif
+ }
+}
+
+
+void QLineControl::setCursorBlinkPeriod(int msec)
+{
+ if (msec == m_blinkPeriod)
+ return;
+ if (m_blinkTimer) {
+ killTimer(m_blinkTimer);
+ }
+ if (msec) {
+ m_blinkTimer = startTimer(msec / 2);
+ m_blinkStatus = 1;
+ } else {
+ m_blinkTimer = 0;
+ if (m_blinkStatus == 1)
+ emit updateNeeded(inputMask().isEmpty() ? cursorRect() : QRect());
+ }
+ m_blinkPeriod = msec;
+}
+
+void QLineControl::resetCursorBlinkTimer()
+{
+ if (m_blinkPeriod == 0 || m_blinkTimer == 0)
+ return;
+ killTimer(m_blinkTimer);
+ m_blinkTimer = startTimer(m_blinkPeriod / 2);
+ m_blinkStatus = 1;
+}
+
+void QLineControl::timerEvent(QTimerEvent *event)
+{
+ if (event->timerId() == m_blinkTimer) {
+ m_blinkStatus = !m_blinkStatus;
+ emit updateNeeded(inputMask().isEmpty() ? cursorRect() : QRect());
+ } else if (event->timerId() == m_deleteAllTimer) {
+ killTimer(m_deleteAllTimer);
+ m_deleteAllTimer = 0;
+ clear();
+ } else if (event->timerId() == m_tripleClickTimer) {
+ killTimer(m_tripleClickTimer);
+ m_tripleClickTimer = 0;
+ }
+}
+
+bool QLineControl::processEvent(QEvent* ev)
+{
+#ifdef QT_KEYPAD_NAVIGATION
+ if (QGuiApplication::keypadNavigationEnabled()) {
+ if ((ev->type() == QEvent::KeyPress) || (ev->type() == QEvent::KeyRelease)) {
+ QKeyEvent *ke = (QKeyEvent *)ev;
+ if (ke->key() == Qt::Key_Back) {
+ if (ke->isAutoRepeat()) {
+ // Swallow it. We don't want back keys running amok.
+ ke->accept();
+ return true;
+ }
+ if ((ev->type() == QEvent::KeyRelease)
+ && !isReadOnly()
+ && m_deleteAllTimer) {
+ killTimer(m_deleteAllTimer);
+ m_deleteAllTimer = 0;
+ backspace();
+ ke->accept();
+ return true;
+ }
+ }
+ }
+ }
+#endif
+ switch(ev->type()){
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseButtonDblClick:
+ case QEvent::MouseMove:
+ processMouseEvent(static_cast<QMouseEvent*>(ev)); break;
+ case QEvent::KeyPress:
+ case QEvent::KeyRelease:
+ processKeyEvent(static_cast<QKeyEvent*>(ev)); break;
+ case QEvent::InputMethod:
+ processInputMethodEvent(static_cast<QInputMethodEvent*>(ev)); break;
+#ifndef QT_NO_SHORTCUT
+ case QEvent::ShortcutOverride:{
+ if (isReadOnly())
+ return false;
+ QKeyEvent* ke = static_cast<QKeyEvent*>(ev);
+ if (ke == QKeySequence::Copy
+ || ke == QKeySequence::Paste
+ || ke == QKeySequence::Cut
+ || ke == QKeySequence::Redo
+ || ke == QKeySequence::Undo
+ || ke == QKeySequence::MoveToNextWord
+ || ke == QKeySequence::MoveToPreviousWord
+ || ke == QKeySequence::MoveToStartOfDocument
+ || ke == QKeySequence::MoveToEndOfDocument
+ || ke == QKeySequence::SelectNextWord
+ || ke == QKeySequence::SelectPreviousWord
+ || ke == QKeySequence::SelectStartOfLine
+ || ke == QKeySequence::SelectEndOfLine
+ || ke == QKeySequence::SelectStartOfBlock
+ || ke == QKeySequence::SelectEndOfBlock
+ || ke == QKeySequence::SelectStartOfDocument
+ || ke == QKeySequence::SelectAll
+ || ke == QKeySequence::SelectEndOfDocument) {
+ ke->accept();
+ } else if (ke->modifiers() == Qt::NoModifier || ke->modifiers() == Qt::ShiftModifier
+ || ke->modifiers() == Qt::KeypadModifier) {
+ if (ke->key() < Qt::Key_Escape) {
+ ke->accept();
+ } else {
+ switch (ke->key()) {
+ case Qt::Key_Delete:
+ case Qt::Key_Home:
+ case Qt::Key_End:
+ case Qt::Key_Backspace:
+ case Qt::Key_Left:
+ case Qt::Key_Right:
+ ke->accept();
+ default:
+ break;
+ }
+ }
+ }
+ }
+#endif
+ default:
+ return false;
+ }
+ return true;
+}
+
+void QLineControl::processMouseEvent(QMouseEvent* ev)
+{
+
+ switch (ev->type()) {
+ case QEvent::MouseButtonPress:{
+ if (m_tripleClickTimer
+ && (ev->pos() - m_tripleClick).manhattanLength() < qApp->styleHints()->startDragDistance()) {
+ selectAll();
+ return;
+ }
+ if (ev->button() == Qt::RightButton)
+ return;
+
+ bool mark = ev->modifiers() & Qt::ShiftModifier;
+ int cursor = xToPos(ev->pos().x());
+ moveCursor(cursor, mark);
+ break;
+ }
+ case QEvent::MouseButtonDblClick:
+ if (ev->button() == Qt::LeftButton) {
+ selectWordAtPos(xToPos(ev->pos().x()));
+ if (m_tripleClickTimer)
+ killTimer(m_tripleClickTimer);
+ m_tripleClickTimer = startTimer(qApp->styleHints()->mouseDoubleClickInterval());
+ m_tripleClick = ev->pos();
+ }
+ break;
+ case QEvent::MouseButtonRelease:
+#ifndef QT_NO_CLIPBOARD
+ if (QGuiApplication::clipboard()->supportsSelection()) {
+ if (ev->button() == Qt::LeftButton) {
+ copy(QClipboard::Selection);
+ } else if (!isReadOnly() && ev->button() == Qt::MidButton) {
+ deselect();
+ insert(QGuiApplication::clipboard()->text(QClipboard::Selection));
+ }
+ }
+#endif
+ break;
+ case QEvent::MouseMove:
+ if (ev->buttons() & Qt::LeftButton) {
+ moveCursor(xToPos(ev->pos().x()), true);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void QLineControl::processKeyEvent(QKeyEvent* event)
+{
+ bool inlineCompletionAccepted = false;
+
+ if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) {
+ if (hasAcceptableInput() || fixup()) {
+ emit accepted();
+ emit editingFinished();
+ }
+ if (inlineCompletionAccepted)
+ event->accept();
+ else
+ event->ignore();
+ return;
+ }
+
+ if (echoMode() == PasswordEchoOnEdit
+ && !passwordEchoEditing()
+ && !isReadOnly()
+ && !event->text().isEmpty()
+#ifdef QT_KEYPAD_NAVIGATION
+ && event->key() != Qt::Key_Select
+ && event->key() != Qt::Key_Up
+ && event->key() != Qt::Key_Down
+ && event->key() != Qt::Key_Back
+#endif
+ && !(event->modifiers() & Qt::ControlModifier)) {
+ // Clear the edit and reset to normal echo mode while editing; the
+ // echo mode switches back when the edit loses focus
+ // ### resets current content. dubious code; you can
+ // navigate with keys up, down, back, and select(?), but if you press
+ // "left" or "right" it clears?
+ updatePasswordEchoEditing(true);
+ clear();
+ }
+
+ bool unknown = false;
+ bool visual = cursorMoveStyle() == Qt::VisualMoveStyle;
+
+ if (false) {
+ }
+#ifndef QT_NO_SHORTCUT
+ else if (event == QKeySequence::Undo) {
+ if (!isReadOnly())
+ undo();
+ }
+ else if (event == QKeySequence::Redo) {
+ if (!isReadOnly())
+ redo();
+ }
+ else if (event == QKeySequence::SelectAll) {
+ selectAll();
+ }
+#ifndef QT_NO_CLIPBOARD
+ else if (event == QKeySequence::Copy) {
+ copy();
+ }
+ else if (event == QKeySequence::Paste) {
+ if (!isReadOnly()) {
+ QClipboard::Mode mode = QClipboard::Clipboard;
+#ifdef Q_WS_X11
+ if (event->modifiers() == (Qt::CTRL | Qt::SHIFT) && event->key() == Qt::Key_Insert)
+ mode = QClipboard::Selection;
+#endif
+ paste(mode);
+ }
+ }
+ else if (event == QKeySequence::Cut) {
+ if (!isReadOnly()) {
+ copy();
+ del();
+ }
+ }
+ else if (event == QKeySequence::DeleteEndOfLine) {
+ if (!isReadOnly()) {
+ setSelection(cursor(), end());
+ copy();
+ del();
+ }
+ }
+#endif //QT_NO_CLIPBOARD
+ else if (event == QKeySequence::MoveToStartOfLine || event == QKeySequence::MoveToStartOfBlock) {
+ home(0);
+ }
+ else if (event == QKeySequence::MoveToEndOfLine || event == QKeySequence::MoveToEndOfBlock) {
+ end(0);
+ }
+ else if (event == QKeySequence::SelectStartOfLine || event == QKeySequence::SelectStartOfBlock) {
+ home(1);
+ }
+ else if (event == QKeySequence::SelectEndOfLine || event == QKeySequence::SelectEndOfBlock) {
+ end(1);
+ }
+ else if (event == QKeySequence::MoveToNextChar) {
+#if !defined(Q_WS_WIN) || defined(QT_NO_COMPLETER)
+ if (hasSelectedText()) {
+#else
+ if (hasSelectedText() && m_completer
+ && m_completer->completionMode() == QCompleter::InlineCompletion) {
+#endif
+ moveCursor(selectionEnd(), false);
+ } else {
+ cursorForward(0, visual ? 1 : (layoutDirection() == Qt::LeftToRight ? 1 : -1));
+ }
+ }
+ else if (event == QKeySequence::SelectNextChar) {
+ cursorForward(1, visual ? 1 : (layoutDirection() == Qt::LeftToRight ? 1 : -1));
+ }
+ else if (event == QKeySequence::MoveToPreviousChar) {
+#if !defined(Q_WS_WIN) || defined(QT_NO_COMPLETER)
+ if (hasSelectedText()) {
+#else
+ if (hasSelectedText() && m_completer
+ && m_completer->completionMode() == QCompleter::InlineCompletion) {
+#endif
+ moveCursor(selectionStart(), false);
+ } else {
+ cursorForward(0, visual ? -1 : (layoutDirection() == Qt::LeftToRight ? -1 : 1));
+ }
+ }
+ else if (event == QKeySequence::SelectPreviousChar) {
+ cursorForward(1, visual ? -1 : (layoutDirection() == Qt::LeftToRight ? -1 : 1));
+ }
+ else if (event == QKeySequence::MoveToNextWord) {
+ if (echoMode() == Normal)
+ layoutDirection() == Qt::LeftToRight ? cursorWordForward(0) : cursorWordBackward(0);
+ else
+ layoutDirection() == Qt::LeftToRight ? end(0) : home(0);
+ }
+ else if (event == QKeySequence::MoveToPreviousWord) {
+ if (echoMode() == Normal)
+ layoutDirection() == Qt::LeftToRight ? cursorWordBackward(0) : cursorWordForward(0);
+ else if (!isReadOnly()) {
+ layoutDirection() == Qt::LeftToRight ? home(0) : end(0);
+ }
+ }
+ else if (event == QKeySequence::SelectNextWord) {
+ if (echoMode() == Normal)
+ layoutDirection() == Qt::LeftToRight ? cursorWordForward(1) : cursorWordBackward(1);
+ else
+ layoutDirection() == Qt::LeftToRight ? end(1) : home(1);
+ }
+ else if (event == QKeySequence::SelectPreviousWord) {
+ if (echoMode() == Normal)
+ layoutDirection() == Qt::LeftToRight ? cursorWordBackward(1) : cursorWordForward(1);
+ else
+ layoutDirection() == Qt::LeftToRight ? home(1) : end(1);
+ }
+ else if (event == QKeySequence::Delete) {
+ if (!isReadOnly())
+ del();
+ }
+ else if (event == QKeySequence::DeleteEndOfWord) {
+ if (!isReadOnly()) {
+ cursorWordForward(true);
+ del();
+ }
+ }
+ else if (event == QKeySequence::DeleteStartOfWord) {
+ if (!isReadOnly()) {
+ cursorWordBackward(true);
+ del();
+ }
+ }
+#endif // QT_NO_SHORTCUT
+ else {
+ bool handled = false;
+#ifdef Q_WS_MAC
+ if (event->key() == Qt::Key_Up || event->key() == Qt::Key_Down) {
+ Qt::KeyboardModifiers myModifiers = (event->modifiers() & ~Qt::KeypadModifier);
+ if (myModifiers & Qt::ShiftModifier) {
+ if (myModifiers == (Qt::ControlModifier|Qt::ShiftModifier)
+ || myModifiers == (Qt::AltModifier|Qt::ShiftModifier)
+ || myModifiers == Qt::ShiftModifier) {
+
+ event->key() == Qt::Key_Up ? home(1) : end(1);
+ }
+ } else {
+ if ((myModifiers == Qt::ControlModifier
+ || myModifiers == Qt::AltModifier
+ || myModifiers == Qt::NoModifier)) {
+ event->key() == Qt::Key_Up ? home(0) : end(0);
+ }
+ }
+ handled = true;
+ }
+#endif
+ if (event->modifiers() & Qt::ControlModifier) {
+ switch (event->key()) {
+ case Qt::Key_Backspace:
+ if (!isReadOnly()) {
+ cursorWordBackward(true);
+ del();
+ }
+ break;
+#if defined(Q_WS_X11)
+ case Qt::Key_E:
+ end(0);
+ break;
+
+ case Qt::Key_U:
+ if (!isReadOnly()) {
+ setSelection(0, text().size());
+#ifndef QT_NO_CLIPBOARD
+ copy();
+#endif
+ del();
+ }
+ break;
+#endif
+ default:
+ if (!handled)
+ unknown = true;
+ }
+ } else { // ### check for *no* modifier
+ switch (event->key()) {
+ case Qt::Key_Backspace:
+ if (!isReadOnly()) {
+ backspace();
+ }
+ break;
+#ifdef QT_KEYPAD_NAVIGATION
+ case Qt::Key_Back:
+ if (QGuiApplication::keypadNavigationEnabled() && !event->isAutoRepeat()
+ && !isReadOnly()) {
+ if (text().length() == 0) {
+ setText(m_cancelText);
+
+ if (passwordEchoEditing())
+ updatePasswordEchoEditing(false);
+
+ emit editFocusChange(false);
+ } else if (!m_deleteAllTimer) {
+ m_deleteAllTimer = startTimer(750);
+ }
+ } else {
+ unknown = true;
+ }
+ break;
+#endif
+ default:
+ if (!handled)
+ unknown = true;
+ }
+ }
+ }
+
+ if (event->key() == Qt::Key_Direction_L || event->key() == Qt::Key_Direction_R) {
+ setLayoutDirection((event->key() == Qt::Key_Direction_L) ? Qt::LeftToRight : Qt::RightToLeft);
+ unknown = false;
+ }
+
+ if (unknown && !isReadOnly()) {
+ QString t = event->text();
+ if (!t.isEmpty() && t.at(0).isPrint()) {
+ insert(t);
+ event->accept();
+ return;
+ }
+ }
+
+ if (unknown)
+ event->ignore();
+ else
+ event->accept();
+}
+
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/gui/text/qlinecontrol_p.h b/src/gui/text/qlinecontrol_p.h
new file mode 100644
index 0000000000..e5435c22f6
--- /dev/null
+++ b/src/gui/text/qlinecontrol_p.h
@@ -0,0 +1,455 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QLINECONTROL_P_H
+#define QLINECONTROL_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "QtCore/qglobal.h"
+
+#include "QtGui/qtextlayout.h"
+#include "QtCore/qpointer.h"
+#include "QtGui/qclipboard.h"
+#include "QtGui/qvalidator.h"
+#include "QtGui/qpalette.h"
+#include "QtGui/qguiapplication.h"
+#include "QtCore/qpoint.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class Q_GUI_EXPORT QLineControl : public QObject
+{
+ Q_OBJECT
+
+public:
+ QLineControl(const QString &txt = QString())
+ : m_cursor(0), m_preeditCursor(0), m_cursorWidth(0), m_layoutDirection(Qt::LayoutDirectionAuto),
+ m_hideCursor(false), m_separator(0), m_readOnly(0),
+ m_dragEnabled(0), m_echoMode(Normal), m_textDirty(0), m_selDirty(0),
+ m_validInput(1), m_blinkStatus(0), m_blinkPeriod(0), m_blinkTimer(0), m_deleteAllTimer(0),
+ m_ascent(0), m_maxLength(32767), m_lastCursorPos(-1),
+ m_tripleClickTimer(0), m_maskData(0), m_modifiedState(0), m_undoState(0),
+ m_selstart(0), m_selend(0), m_passwordEchoEditing(false)
+ {
+ init(txt);
+ }
+
+ enum EchoMode {
+ Normal,
+ NoEcho,
+ Password,
+ PasswordEchoOnEdit
+ };
+
+
+ ~QLineControl()
+ {
+ delete [] m_maskData;
+ }
+
+ int nextMaskBlank(int pos)
+ {
+ int c = findInMask(pos, true, false);
+ m_separator |= (c != pos);
+ return (c != -1 ? c : m_maxLength);
+ }
+
+ int prevMaskBlank(int pos)
+ {
+ int c = findInMask(pos, false, false);
+ m_separator |= (c != pos);
+ return (c != -1 ? c : 0);
+ }
+
+ bool isUndoAvailable() const { return !m_readOnly && m_undoState; }
+ bool isRedoAvailable() const { return !m_readOnly && m_undoState < (int)m_history.size(); }
+ void clearUndo() { m_history.clear(); m_modifiedState = m_undoState = 0; }
+
+ bool isModified() const { return m_modifiedState != m_undoState; }
+ void setModified(bool modified) { m_modifiedState = modified ? -1 : m_undoState; }
+
+ bool allSelected() const { return !m_text.isEmpty() && m_selstart == 0 && m_selend == (int)m_text.length(); }
+ bool hasSelectedText() const { return !m_text.isEmpty() && m_selend > m_selstart; }
+
+ int width() const { return qRound(m_textLayout.lineAt(0).width()) + 1; }
+ int height() const { return qRound(m_textLayout.lineAt(0).height()) + 1; }
+ int ascent() const { return m_ascent; }
+ qreal naturalTextWidth() const { return m_textLayout.lineAt(0).naturalTextWidth(); }
+
+ void setSelection(int start, int length);
+
+ inline QString selectedText() const { return hasSelectedText() ? m_text.mid(m_selstart, m_selend - m_selstart) : QString(); }
+ QString textBeforeSelection() const { return hasSelectedText() ? m_text.left(m_selstart) : QString(); }
+ QString textAfterSelection() const { return hasSelectedText() ? m_text.mid(m_selend) : QString(); }
+
+ int selectionStart() const { return hasSelectedText() ? m_selstart : -1; }
+ int selectionEnd() const { return hasSelectedText() ? m_selend : -1; }
+ bool inSelection(int x) const
+ {
+ if (m_selstart >= m_selend)
+ return false;
+ int pos = xToPos(x, QTextLine::CursorOnCharacter);
+ return pos >= m_selstart && pos < m_selend;
+ }
+
+ void removeSelection()
+ {
+ int priorState = m_undoState;
+ removeSelectedText();
+ finishChange(priorState);
+ }
+
+ int start() const { return 0; }
+ int end() const { return m_text.length(); }
+
+#ifndef QT_NO_CLIPBOARD
+ void copy(QClipboard::Mode mode = QClipboard::Clipboard) const;
+ void paste(QClipboard::Mode mode = QClipboard::Clipboard);
+#endif
+
+ int cursor() const{ return m_cursor; }
+ int preeditCursor() const { return m_preeditCursor; }
+
+ int cursorWidth() const { return m_cursorWidth; }
+ void setCursorWidth(int value) { m_cursorWidth = value; }
+
+ Qt::CursorMoveStyle cursorMoveStyle() const { return m_textLayout.cursorMoveStyle(); }
+ void setCursorMoveStyle(Qt::CursorMoveStyle style) { m_textLayout.setCursorMoveStyle(style); }
+
+ void moveCursor(int pos, bool mark = false);
+ void cursorForward(bool mark, int steps)
+ {
+ int c = m_cursor;
+ if (steps > 0) {
+ while (steps--)
+ c = cursorMoveStyle() == Qt::VisualMoveStyle ? m_textLayout.rightCursorPosition(c)
+ : m_textLayout.nextCursorPosition(c);
+ } else if (steps < 0) {
+ while (steps++)
+ c = cursorMoveStyle() == Qt::VisualMoveStyle ? m_textLayout.leftCursorPosition(c)
+ : m_textLayout.previousCursorPosition(c);
+ }
+ moveCursor(c, mark);
+ }
+
+ void cursorWordForward(bool mark) { moveCursor(m_textLayout.nextCursorPosition(m_cursor, QTextLayout::SkipWords), mark); }
+ void cursorWordBackward(bool mark) { moveCursor(m_textLayout.previousCursorPosition(m_cursor, QTextLayout::SkipWords), mark); }
+
+ void home(bool mark) { moveCursor(0, mark); }
+ void end(bool mark) { moveCursor(text().length(), mark); }
+
+ int xToPos(int x, QTextLine::CursorPosition = QTextLine::CursorBetweenCharacters) const;
+ QRect cursorRect() const;
+
+ qreal cursorToX(int cursor) const { return m_textLayout.lineAt(0).cursorToX(cursor); }
+ qreal cursorToX() const
+ {
+ int cursor = m_cursor;
+ if (m_preeditCursor != -1)
+ cursor += m_preeditCursor;
+ return cursorToX(cursor);
+ }
+
+ bool isReadOnly() const { return m_readOnly; }
+ void setReadOnly(bool enable) { m_readOnly = enable; }
+
+ QString text() const
+ {
+ QString res = m_maskData ? stripString(m_text) : m_text;
+ return (res.isNull() ? QString::fromLatin1("") : res);
+ }
+ void setText(const QString &txt) { internalSetText(txt, -1, false); }
+ QString displayText() const { return m_textLayout.text(); }
+
+ void backspace();
+ void del();
+ void deselect() { internalDeselect(); finishChange(); }
+ void selectAll() { m_selstart = m_selend = m_cursor = 0; moveCursor(m_text.length(), true); }
+
+ void insert(const QString &);
+ void clear();
+ void undo() { internalUndo(); finishChange(-1, true); }
+ void redo() { internalRedo(); finishChange(); }
+ void selectWordAtPos(int);
+
+ EchoMode echoMode() const { return EchoMode(m_echoMode); }
+ void setEchoMode(EchoMode mode)
+ {
+ m_echoMode = mode;
+ m_passwordEchoEditing = false;
+ updateDisplayText();
+ }
+
+ int maxLength() const { return m_maxLength; }
+ void setMaxLength(int maxLength)
+ {
+ if (m_maskData)
+ return;
+ m_maxLength = maxLength;
+ setText(m_text);
+ }
+
+#ifndef QT_NO_VALIDATOR
+ const QValidator *validator() const { return m_validator; }
+ void setValidator(const QValidator *v) { m_validator = const_cast<QValidator*>(v); }
+#endif
+
+ int cursorPosition() const { return m_cursor; }
+ void setCursorPosition(int pos) { if (pos <= m_text.length()) moveCursor(qMax(0, pos)); }
+
+ bool hasAcceptableInput() const { return hasAcceptableInput(m_text); }
+ bool fixup();
+
+ QString inputMask() const { return m_maskData ? m_inputMask + QLatin1Char(';') + m_blank : QString(); }
+ void setInputMask(const QString &mask)
+ {
+ parseInputMask(mask);
+ if (m_maskData)
+ moveCursor(nextMaskBlank(0));
+ }
+
+ // input methods
+#ifndef QT_NO_IM
+ bool composeMode() const { return !m_textLayout.preeditAreaText().isEmpty(); }
+ void setPreeditArea(int cursor, const QString &text) { m_textLayout.setPreeditArea(cursor, text); }
+#endif
+
+ QString preeditAreaText() const { return m_textLayout.preeditAreaText(); }
+
+ void updatePasswordEchoEditing(bool editing);
+ bool passwordEchoEditing() const { return m_passwordEchoEditing; }
+
+ QChar passwordCharacter() const { return m_passwordCharacter; }
+ void setPasswordCharacter(const QChar &character) { m_passwordCharacter = character; updateDisplayText(); }
+
+ Qt::LayoutDirection layoutDirection() const {
+ if (m_layoutDirection == Qt::LayoutDirectionAuto) {
+ if (m_text.isEmpty())
+ return QGuiApplication::keyboardInputDirection();
+ return m_text.isRightToLeft() ? Qt::RightToLeft : Qt::LeftToRight;
+ }
+ return m_layoutDirection;
+ }
+ void setLayoutDirection(Qt::LayoutDirection direction)
+ {
+ if (direction != m_layoutDirection) {
+ m_layoutDirection = direction;
+ updateDisplayText();
+ }
+ }
+
+ void setFont(const QFont &font) { m_textLayout.setFont(font); updateDisplayText(); }
+
+ void processInputMethodEvent(QInputMethodEvent *event);
+ void processMouseEvent(QMouseEvent* ev);
+ void processKeyEvent(QKeyEvent* ev);
+
+ int cursorBlinkPeriod() const { return m_blinkPeriod; }
+ void setCursorBlinkPeriod(int msec);
+ void resetCursorBlinkTimer();
+
+ bool cursorBlinkStatus() const { return m_blinkStatus; }
+
+ QString cancelText() const { return m_cancelText; }
+ void setCancelText(const QString &text) { m_cancelText = text; }
+
+ const QPalette &palette() const { return m_palette; }
+ void setPalette(const QPalette &p) { m_palette = p; }
+
+ enum DrawFlags {
+ DrawText = 0x01,
+ DrawSelections = 0x02,
+ DrawCursor = 0x04,
+ DrawAll = DrawText | DrawSelections | DrawCursor
+ };
+ void draw(QPainter *, const QPoint &, const QRect &, int flags = DrawAll);
+
+ bool processEvent(QEvent *ev);
+
+ QTextLayout *textLayout()
+ {
+ return &m_textLayout;
+ }
+
+private:
+ void init(const QString &txt);
+ void removeSelectedText();
+ void internalSetText(const QString &txt, int pos = -1, bool edited = true);
+ void updateDisplayText(bool forceUpdate = false);
+
+ void internalInsert(const QString &s);
+ void internalDelete(bool wasBackspace = false);
+ void internalRemove(int pos);
+
+ inline void internalDeselect()
+ {
+ m_selDirty |= (m_selend > m_selstart);
+ m_selstart = m_selend = 0;
+ }
+
+ void internalUndo(int until = -1);
+ void internalRedo();
+
+ QString m_text;
+ QPalette m_palette;
+ int m_cursor;
+ int m_preeditCursor;
+ int m_cursorWidth;
+ Qt::LayoutDirection m_layoutDirection;
+ uint m_hideCursor : 1; // used to hide the m_cursor inside preedit areas
+ uint m_separator : 1;
+ uint m_readOnly : 1;
+ uint m_dragEnabled : 1;
+ uint m_echoMode : 2;
+ uint m_textDirty : 1;
+ uint m_selDirty : 1;
+ uint m_validInput : 1;
+ uint m_blinkStatus : 1;
+ int m_blinkPeriod; // 0 for non-blinking cursor
+ int m_blinkTimer;
+ int m_deleteAllTimer;
+ int m_ascent;
+ int m_maxLength;
+ int m_lastCursorPos;
+ QList<int> m_transactions;
+ QPoint m_tripleClick;
+ int m_tripleClickTimer;
+ QString m_cancelText;
+
+ void emitCursorPositionChanged();
+
+ bool finishChange(int validateFromState = -1, bool update = false, bool edited = true);
+
+#ifndef QT_NO_VALIDATOR
+ QPointer<QValidator> m_validator;
+#endif
+
+ struct MaskInputData {
+ enum Casemode { NoCaseMode, Upper, Lower };
+ QChar maskChar; // either the separator char or the inputmask
+ bool separator;
+ Casemode caseMode;
+ };
+ QString m_inputMask;
+ QChar m_blank;
+ MaskInputData *m_maskData;
+
+ // undo/redo handling
+ enum CommandType { Separator, Insert, Remove, Delete, RemoveSelection, DeleteSelection, SetSelection };
+ struct Command {
+ inline Command() {}
+ inline Command(CommandType t, int p, QChar c, int ss, int se) : type(t),uc(c),pos(p),selStart(ss),selEnd(se) {}
+ uint type : 4;
+ QChar uc;
+ int pos, selStart, selEnd;
+ };
+ int m_modifiedState;
+ int m_undoState;
+ QVector<Command> m_history;
+ void addCommand(const Command& cmd);
+
+ inline void separate() { m_separator = true; }
+
+ // selection
+ int m_selstart;
+ int m_selend;
+
+ // masking
+ void parseInputMask(const QString &maskFields);
+ bool isValidInput(QChar key, QChar mask) const;
+ bool hasAcceptableInput(const QString &text) const;
+ QString maskString(uint pos, const QString &str, bool clear = false) const;
+ QString clearString(uint pos, uint len) const;
+ QString stripString(const QString &str) const;
+ int findInMask(int pos, bool forward, bool findSeparator, QChar searchChar = QChar()) const;
+
+ // complex text layout
+ QTextLayout m_textLayout;
+
+ bool m_passwordEchoEditing;
+ QChar m_passwordCharacter;
+
+Q_SIGNALS:
+ void cursorPositionChanged(int, int);
+ void selectionChanged();
+
+ void displayTextChanged(const QString &);
+ void textChanged(const QString &);
+ void textEdited(const QString &);
+
+ void resetInputContext();
+ void updateMicroFocus();
+
+ void accepted();
+ void editingFinished();
+ void updateNeeded(const QRect &);
+
+#ifdef QT_KEYPAD_NAVIGATION
+ void editFocusChange(bool);
+#endif
+protected:
+ virtual void timerEvent(QTimerEvent *event);
+
+private Q_SLOTS:
+ void _q_clipboardChanged();
+ void _q_deleteSelected();
+
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QLineControl_P_H
diff --git a/src/gui/text/qplatformfontdatabase_qpa.cpp b/src/gui/text/qplatformfontdatabase_qpa.cpp
index 059dc3e188..7ad838561b 100644
--- a/src/gui/text/qplatformfontdatabase_qpa.cpp
+++ b/src/gui/text/qplatformfontdatabase_qpa.cpp
@@ -344,6 +344,30 @@ QString QPlatformFontDatabase::fontDir() const
}
/*!
+ Returns the default system font.
+
+ \sa QGuiApplication::font()
+ \since 5.0
+*/
+
+QFont QPlatformFontDatabase::defaultFont() const
+{
+ return QFont(QLatin1String("Helvetica"));
+}
+
+/*!
+ Returns fonts for class names.
+
+ \sa QGuiApplication::font()
+ \since 5.0
+*/
+
+QHash<QByteArray, QFont> QPlatformFontDatabase::defaultFonts() const
+{
+ return QHash<QByteArray, QFont>();
+}
+
+/*!
\class QPlatformFontDatabase
\brief The QPlatformFontDatabase class makes it possible to customize how fonts
are discovered and how they are rendered
diff --git a/src/gui/text/qplatformfontdatabase_qpa.h b/src/gui/text/qplatformfontdatabase_qpa.h
index 1fb3c32fea..d34d602e43 100644
--- a/src/gui/text/qplatformfontdatabase_qpa.h
+++ b/src/gui/text/qplatformfontdatabase_qpa.h
@@ -46,6 +46,7 @@
#include <QtCore/QString>
#include <QtCore/QStringList>
#include <QtCore/QList>
+#include <QtCore/QHash>
#include <QtGui/QFontDatabase>
#include <QtGui/private/qfont_p.h>
@@ -96,6 +97,9 @@ public:
virtual QString fontDir() const;
+ virtual QFont defaultFont() const;
+ virtual QHash<QByteArray, QFont> defaultFonts() const;
+
//callback
static void registerQPF2Font(const QByteArray &dataArray, void *handle);
static void registerFont(const QString &familyname, const QString &foundryname, QFont::Weight weight,
diff --git a/src/gui/text/qrawfont.cpp b/src/gui/text/qrawfont.cpp
index 26b6a8aad7..e060c57aee 100644
--- a/src/gui/text/qrawfont.cpp
+++ b/src/gui/text/qrawfont.cpp
@@ -46,7 +46,6 @@
#include "qrawfont.h"
#include "qrawfont_p.h"
-#include <QtCore/qthread.h>
#include <QtCore/qendian.h>
QT_BEGIN_NAMESPACE
@@ -77,7 +76,7 @@ QT_BEGIN_NAMESPACE
A QRawFont object represents a single, physical instance of a given font in a given pixel size.
I.e. in the typical case it represents a set of TrueType or OpenType font tables and uses a
- user specified pixel size to convert metrics into logical pixel units. In can be used in
+ user specified pixel size to convert metrics into logical pixel units. It can be used in
combination with the QGlyphRun class to draw specific glyph indexes at specific positions, and
also have accessors to some relevant data in the physical font.
@@ -190,8 +189,7 @@ QRawFont &QRawFont::operator=(const QRawFont &other)
*/
bool QRawFont::isValid() const
{
- Q_ASSERT(d->thread == 0 || d->thread == QThread::currentThread());
- return d->fontEngine != 0;
+ return d->isValid();
}
/*!
@@ -225,7 +223,7 @@ void QRawFont::loadFromData(const QByteArray &fontData,
qreal pixelSize,
QFont::HintingPreference hintingPreference)
{
- detach();
+ d.detach();
d->cleanUp();
d->hintingPreference = hintingPreference;
d->thread = QThread::currentThread();
@@ -247,13 +245,13 @@ void QRawFont::loadFromData(const QByteArray &fontData,
QImage QRawFont::alphaMapForGlyph(quint32 glyphIndex, AntialiasingType antialiasingType,
const QTransform &transform) const
{
- if (!isValid())
+ if (!d->isValid())
return QImage();
if (antialiasingType == SubPixelAntialiasing)
return d->fontEngine->alphaRGBMapForGlyph(glyphIndex, QFixed(), 0, transform);
- else
- return d->fontEngine->alphaMapForGlyph(glyphIndex, QFixed(), transform);
+
+ return d->fontEngine->alphaMapForGlyph(glyphIndex, QFixed(), transform);
}
/*!
@@ -266,7 +264,7 @@ QImage QRawFont::alphaMapForGlyph(quint32 glyphIndex, AntialiasingType antialias
*/
QPainterPath QRawFont::pathForGlyph(quint32 glyphIndex) const
{
- if (!isValid())
+ if (!d->isValid())
return QPainterPath();
QFixedPoint position;
@@ -284,16 +282,19 @@ bool QRawFont::operator==(const QRawFont &other) const
}
/*!
+ \fn bool QRawFont::operator!=(const QRawFont &other) const
+
+ Returns true if this QRawFont is not equal to \a other. Otherwise, returns false.
+*/
+
+/*!
Returns the ascent of this QRawFont in pixel units.
\sa QFontMetricsF::ascent()
*/
qreal QRawFont::ascent() const
{
- if (!isValid())
- return 0.0;
-
- return d->fontEngine->ascent().toReal();
+ return d->isValid() ? d->fontEngine->ascent().toReal() : 0.0;
}
/*!
@@ -303,10 +304,7 @@ qreal QRawFont::ascent() const
*/
qreal QRawFont::descent() const
{
- if (!isValid())
- return 0.0;
-
- return d->fontEngine->descent().toReal();
+ return d->isValid() ? d->fontEngine->descent().toReal() : 0.0;
}
/*!
@@ -316,10 +314,7 @@ qreal QRawFont::descent() const
*/
qreal QRawFont::xHeight() const
{
- if (!isValid())
- return 0.0;
-
- return d->fontEngine->xHeight().toReal();
+ return d->isValid() ? d->fontEngine->xHeight().toReal() : 0.0;
}
/*!
@@ -329,10 +324,7 @@ qreal QRawFont::xHeight() const
*/
qreal QRawFont::leading() const
{
- if (!isValid())
- return 0.0;
-
- return d->fontEngine->leading().toReal();
+ return d->isValid() ? d->fontEngine->leading().toReal() : 0.0;
}
/*!
@@ -342,10 +334,7 @@ qreal QRawFont::leading() const
*/
qreal QRawFont::averageCharWidth() const
{
- if (!isValid())
- return 0.0;
-
- return d->fontEngine->averageCharWidth().toReal();
+ return d->isValid() ? d->fontEngine->averageCharWidth().toReal() : 0.0;
}
/*!
@@ -355,10 +344,7 @@ qreal QRawFont::averageCharWidth() const
*/
qreal QRawFont::maxCharWidth() const
{
- if (!isValid())
- return 0.0;
-
- return d->fontEngine->maxCharWidth();
+ return d->isValid() ? d->fontEngine->maxCharWidth() : 0.0;
}
/*!
@@ -370,10 +356,7 @@ qreal QRawFont::maxCharWidth() const
*/
qreal QRawFont::pixelSize() const
{
- if (!isValid())
- return 0.0;
-
- return d->fontEngine->fontDef.pixelSize;
+ return d->isValid() ? d->fontEngine->fontDef.pixelSize : 0.0;
}
/*!
@@ -386,10 +369,7 @@ qreal QRawFont::pixelSize() const
*/
qreal QRawFont::unitsPerEm() const
{
- if (!isValid())
- return 0.0;
-
- return d->fontEngine->emSquareSize().toReal();
+ return d->isValid() ? d->fontEngine->emSquareSize().toReal() : 0.0;
}
/*!
@@ -421,10 +401,7 @@ qreal QRawFont::underlinePosition() const
*/
QString QRawFont::familyName() const
{
- if (!isValid())
- return QString();
-
- return d->fontEngine->fontDef.family;
+ return d->isValid() ? d->fontEngine->fontDef.family : QString();
}
/*!
@@ -434,10 +411,7 @@ QString QRawFont::familyName() const
*/
QString QRawFont::styleName() const
{
- if (!isValid())
- return QString();
-
- return d->fontEngine->fontDef.styleName;
+ return d->isValid() ? d->fontEngine->fontDef.styleName : QString();
}
/*!
@@ -447,10 +421,7 @@ QString QRawFont::styleName() const
*/
QFont::Style QRawFont::style() const
{
- if (!isValid())
- return QFont::StyleNormal;
-
- return QFont::Style(d->fontEngine->fontDef.style);
+ return d->isValid() ? QFont::Style(d->fontEngine->fontDef.style) : QFont::StyleNormal;
}
/*!
@@ -460,10 +431,7 @@ QFont::Style QRawFont::style() const
*/
int QRawFont::weight() const
{
- if (!isValid())
- return -1;
-
- return int(d->fontEngine->fontDef.weight);
+ return d->isValid() ? int(d->fontEngine->fontDef.weight) : -1;
}
/*!
@@ -481,7 +449,7 @@ int QRawFont::weight() const
*/
QVector<quint32> QRawFont::glyphIndexesForString(const QString &text) const
{
- if (!isValid())
+ if (!d->isValid())
return QVector<quint32>();
int nglyphs = text.size();
@@ -513,7 +481,7 @@ QVector<quint32> QRawFont::glyphIndexesForString(const QString &text) const
*/
bool QRawFont::glyphIndexesForChars(const QChar *chars, int numChars, quint32 *glyphIndexes, int *numGlyphs) const
{
- if (!isValid())
+ if (!d->isValid())
return false;
QGlyphLayout glyphs;
@@ -530,7 +498,7 @@ bool QRawFont::glyphIndexesForChars(const QChar *chars, int numChars, quint32 *g
*/
QVector<QPointF> QRawFont::advancesForGlyphIndexes(const QVector<quint32> &glyphIndexes) const
{
- if (!isValid())
+ if (!d->isValid())
return QVector<QPointF>();
int numGlyphs = glyphIndexes.size();
@@ -557,7 +525,7 @@ QVector<QPointF> QRawFont::advancesForGlyphIndexes(const QVector<quint32> &glyph
*/
bool QRawFont::advancesForGlyphIndexes(const quint32 *glyphIndexes, QPointF *advances, int numGlyphs) const
{
- if (!isValid())
+ if (!d->isValid())
return false;
QGlyphLayout glyphs;
@@ -583,10 +551,7 @@ bool QRawFont::advancesForGlyphIndexes(const quint32 *glyphIndexes, QPointF *adv
*/
QFont::HintingPreference QRawFont::hintingPreference() const
{
- if (!isValid())
- return QFont::PreferDefaultHinting;
-
- return d->hintingPreference;
+ return d->isValid() ? d->hintingPreference : QFont::PreferDefaultHinting;
}
/*!
@@ -597,7 +562,7 @@ QFont::HintingPreference QRawFont::hintingPreference() const
*/
QByteArray QRawFont::fontTable(const char *tagName) const
{
- if (!isValid())
+ if (!d->isValid())
return QByteArray();
const quint32 *tagId = reinterpret_cast<const quint32 *>(tagName);
@@ -620,9 +585,9 @@ extern QList<QFontDatabase::WritingSystem> qt_determine_writing_systems_from_tru
*/
QList<QFontDatabase::WritingSystem> QRawFont::supportedWritingSystems() const
{
- if (isValid()) {
+ if (d->isValid()) {
QByteArray os2Table = fontTable("OS/2");
- if (!os2Table.isEmpty() && os2Table.size() > 86) {
+ if (os2Table.size() > 86) {
char *data = os2Table.data();
quint32 *bigEndianUnicodeRanges = reinterpret_cast<quint32 *>(data + 42);
quint32 *bigEndianCodepageRanges = reinterpret_cast<quint32 *>(data + 78);
@@ -650,10 +615,7 @@ QList<QFontDatabase::WritingSystem> QRawFont::supportedWritingSystems() const
*/
bool QRawFont::supportsCharacter(const QChar &character) const
{
- if (!isValid())
- return false;
-
- return d->fontEngine->canRender(&character, 1);
+ return d->isValid() && d->fontEngine->canRender(&character, 1);
}
/*!
@@ -663,7 +625,7 @@ bool QRawFont::supportsCharacter(const QChar &character) const
*/
bool QRawFont::supportsCharacter(quint32 ucs4) const
{
- if (!isValid())
+ if (!d->isValid())
return false;
QString str = QString::fromUcs4(&ucs4, 1);
@@ -682,6 +644,7 @@ extern int qt_script_for_writing_system(QFontDatabase::WritingSystem writingSyst
*/
QRawFont QRawFont::fromFont(const QFont &font, QFontDatabase::WritingSystem writingSystem)
{
+ QRawFont rawFont;
#if defined(Q_WS_MAC)
QTextLayout layout(QFontDatabase::writingSystemSample(writingSystem), font);
layout.beginLayout();
@@ -692,14 +655,12 @@ QRawFont QRawFont::fromFont(const QFont &font, QFontDatabase::WritingSystem writ
// Pick the one matches the family name we originally requested,
// if none of them match, just pick the first one
for (int i = 0; i < list.size(); i++) {
- QGlyphRun glyphs = list.at(i);
- QRawFont rawfont = glyphs.rawFont();
+ rawfont = list.at(i).rawFont();
if (rawfont.familyName() == font.family())
return rawfont;
}
return list.at(0).rawFont();
}
- return QRawFont();
#else
QFontPrivate *font_d = QFontPrivate::get(font);
int script = qt_script_for_writing_system(writingSystem);
@@ -715,15 +676,12 @@ QRawFont QRawFont::fromFont(const QFont &font, QFontDatabase::WritingSystem writ
}
if (fe != 0) {
- QRawFont rawFont;
rawFont.d.data()->fontEngine = fe;
rawFont.d.data()->fontEngine->ref.ref();
rawFont.d.data()->hintingPreference = font.hintingPreference();
- return rawFont;
- } else {
- return QRawFont();
}
#endif
+ return rawFont;
}
/*!
@@ -734,7 +692,7 @@ void QRawFont::setPixelSize(qreal pixelSize)
if (d->fontEngine == 0)
return;
- detach();
+ d.detach();
QFontEngine *oldFontEngine = d->fontEngine;
d->fontEngine = d->fontEngine->cloneWithSize(pixelSize);
@@ -749,15 +707,6 @@ void QRawFont::setPixelSize(qreal pixelSize)
/*!
\internal
*/
-void QRawFont::detach()
-{
- if (d->ref != 1)
- d.detach();
-}
-
-/*!
- \internal
-*/
void QRawFontPrivate::cleanUp()
{
platformCleanUp();
diff --git a/src/gui/text/qrawfont.h b/src/gui/text/qrawfont.h
index f7d7494f0b..b66bc04eab 100644
--- a/src/gui/text/qrawfont.h
+++ b/src/gui/text/qrawfont.h
@@ -81,7 +81,10 @@ public:
bool isValid() const;
QRawFont &operator=(const QRawFont &other);
+
bool operator==(const QRawFont &other) const;
+ inline bool operator!=(const QRawFont &other) const
+ { return !operator==(other); }
QString familyName() const;
QString styleName() const;
@@ -137,8 +140,6 @@ private:
friend class QRawFontPrivate;
friend class QTextLayout;
- void detach();
-
QExplicitlySharedDataPointer<QRawFontPrivate> d;
};
diff --git a/src/gui/text/qrawfont_p.h b/src/gui/text/qrawfont_p.h
index 4a4ed56223..0187c374a0 100644
--- a/src/gui/text/qrawfont_p.h
+++ b/src/gui/text/qrawfont_p.h
@@ -54,7 +54,9 @@
//
#include "qrawfont.h"
+
#include "qfontengine_p.h"
+#include <QtCore/qthread.h>
#include <QtCore/qthreadstorage.h>
#if !defined(QT_NO_RAWFONT)
@@ -96,6 +98,12 @@ public:
cleanUp();
}
+ inline bool isValid() const
+ {
+ Q_ASSERT(thread == 0 || thread == QThread::currentThread());
+ return fontEngine != 0;
+ }
+
void cleanUp();
void platformCleanUp();
void platformLoadFromData(const QByteArray &fontData,
diff --git a/src/gui/text/qrawfont_qpa.cpp b/src/gui/text/qrawfont_qpa.cpp
index 6a69804fac..47815baf06 100644
--- a/src/gui/text/qrawfont_qpa.cpp
+++ b/src/gui/text/qrawfont_qpa.cpp
@@ -45,7 +45,7 @@
#include "qrawfont_p.h"
#include <QtGui/qplatformfontdatabase_qpa.h>
-#include <private/qapplication_p.h>
+#include <private/qguiapplication_p.h>
QT_BEGIN_NAMESPACE
@@ -58,7 +58,7 @@ void QRawFontPrivate::platformLoadFromData(const QByteArray &fontData, qreal pix
{
Q_ASSERT(fontEngine == 0);
- QPlatformFontDatabase *pfdb = QApplicationPrivate::platformIntegration()->fontDatabase();
+ QPlatformFontDatabase *pfdb = QGuiApplicationPrivate::platformIntegration()->fontDatabase();
fontEngine = pfdb->fontEngine(fontData, pixelSize, hintingPreference);
if (fontEngine != 0)
fontEngine->ref.ref();
diff --git a/src/gui/text/qstatictext.cpp b/src/gui/text/qstatictext.cpp
index 388be3999c..bed0da62da 100644
--- a/src/gui/text/qstatictext.cpp
+++ b/src/gui/text/qstatictext.cpp
@@ -45,8 +45,6 @@
#include <private/qfontengine_p.h>
#include <qabstracttextdocumentlayout.h>
-#include <QtGui/qapplication.h>
-
QT_BEGIN_NAMESPACE
/*!
@@ -141,7 +139,7 @@ QT_BEGIN_NAMESPACE
can be used to indicate that the QStaticText should use additional caches, if possible,
to improve performance at the expense of memory. In particular, setting the performance hint
AggressiveCaching on the QStaticText will improve performance when using the OpenGL graphics
- system or when drawing to a QGLWidget.
+ system or when drawing to a QOpenGLWidget.
\value ModerateCaching Do basic caching for high performance at a low memory cost.
\value AggressiveCaching Use additional caching when available. This may improve performance
diff --git a/src/gui/text/qsyntaxhighlighter.cpp b/src/gui/text/qsyntaxhighlighter.cpp
index 5d6c0052f4..5f1a53b556 100644
--- a/src/gui/text/qsyntaxhighlighter.cpp
+++ b/src/gui/text/qsyntaxhighlighter.cpp
@@ -50,7 +50,6 @@
#include <qtextobject.h>
#include <qtextcursor.h>
#include <qdebug.h>
-#include <qtextedit.h>
#include <qtimer.h>
QT_BEGIN_NAMESPACE
@@ -311,10 +310,19 @@ void QSyntaxHighlighterPrivate::reformatBlock(const QTextBlock &block)
/*!
Constructs a QSyntaxHighlighter with the given \a parent.
+
+ If the parent is a QTextEdit, it installs the syntaxhighlighter on the
+ parents document. The specified QTextEdit also becomes the owner of
+ the QSyntaxHighlighter.
*/
QSyntaxHighlighter::QSyntaxHighlighter(QObject *parent)
: QObject(*new QSyntaxHighlighterPrivate, parent)
{
+ if (parent->inherits("QTextEdit")) {
+ QTextDocument *doc = qobject_cast<QTextDocument *>(parent->property("document").value<QObject *>());
+ if (doc)
+ setDocument(doc);
+ }
}
/*!
@@ -329,17 +337,6 @@ QSyntaxHighlighter::QSyntaxHighlighter(QTextDocument *parent)
}
/*!
- Constructs a QSyntaxHighlighter and installs it on \a parent 's
- QTextDocument. The specified QTextEdit also becomes the owner of
- the QSyntaxHighlighter.
-*/
-QSyntaxHighlighter::QSyntaxHighlighter(QTextEdit *parent)
- : QObject(*new QSyntaxHighlighterPrivate, parent)
-{
- setDocument(parent->document());
-}
-
-/*!
Destructor. Uninstalls this syntax highlighter from the text document.
*/
QSyntaxHighlighter::~QSyntaxHighlighter()
diff --git a/src/gui/text/qsyntaxhighlighter.h b/src/gui/text/qsyntaxhighlighter.h
index 9ee09c1f1d..1c421d1c26 100644
--- a/src/gui/text/qsyntaxhighlighter.h
+++ b/src/gui/text/qsyntaxhighlighter.h
@@ -61,7 +61,6 @@ class QTextCharFormat;
class QFont;
class QColor;
class QTextBlockUserData;
-class QTextEdit;
class Q_GUI_EXPORT QSyntaxHighlighter : public QObject
{
@@ -70,7 +69,6 @@ class Q_GUI_EXPORT QSyntaxHighlighter : public QObject
public:
QSyntaxHighlighter(QObject *parent);
QSyntaxHighlighter(QTextDocument *parent);
- QSyntaxHighlighter(QTextEdit *parent);
virtual ~QSyntaxHighlighter();
void setDocument(QTextDocument *doc);
diff --git a/src/gui/text/qtextcontrol.cpp b/src/gui/text/qtextcontrol.cpp
index a04bcc561a..2faa5e2078 100644
--- a/src/gui/text/qtextcontrol.cpp
+++ b/src/gui/text/qtextcontrol.cpp
@@ -51,43 +51,40 @@
#include <qmime.h>
#include <qdrag.h>
#include <qclipboard.h>
-#include <qmenu.h>
-#include <qstyle.h>
#include <qtimer.h>
+#include <qinputpanel.h>
#include "private/qtextdocumentlayout_p.h"
#include "private/qabstracttextdocumentlayout_p.h"
-#include "private/qtextedit_p.h"
#include "qtextdocument.h"
#include "private/qtextdocument_p.h"
#include "qtextlist.h"
-#include "private/qtextcontrol_p.h"
-#include "qgraphicssceneevent.h"
-#include "qprinter.h"
#include "qtextdocumentwriter.h"
#include "private/qtextcursor_p.h"
+#include "qpagedpaintdevice.h"
+#include "private/qpagedpaintdevice_p.h"
#include <qtextformat.h>
#include <qdatetime.h>
#include <qbuffer.h>
-#include <qapplication.h>
+#include <qguiapplication.h>
#include <limits.h>
#include <qtexttable.h>
#include <qvariant.h>
#include <qurl.h>
-#include <qdesktopservices.h>
-#include <qinputcontext.h>
-#include <qtooltip.h>
-#include <qstyleoption.h>
-#include <QtGui/qlineedit.h>
+#include <qstylehints.h>
-#ifndef QT_NO_SHORTCUT
-#include "private/qapplication_p.h"
-#include "private/qshortcutmap_p.h"
-#include <qkeysequence.h>
-#define ACCEL_KEY(k) (!qApp->d_func()->shortcutMap.hasShortcutForKeySequence(k) ? QLatin1Char('\t') + QString(QKeySequence(k)) : QString())
-#else
-#define ACCEL_KEY(k) QString()
-#endif
+// ### these should come from QStyleHints
+const int textCursorWidth = 1;
+const bool fullWidthSelection = true;
+
+//#ifndef QT_NO_SHORTCUT
+//#include "private/QGuiApplication_p.h"
+//#include "private/qshortcutmap_p.h"
+//#include <qkeysequence.h>
+//#define ACCEL_KEY(k) (!qApp->d_func()->shortcutMap.hasShortcutForKeySequence(k) ? QLatin1Char('\t') + QString(QKeySequence(k)) : QString())
+//#else
+//#define ACCEL_KEY(k) QString()
+//#endif
QT_BEGIN_NAMESPACE
@@ -273,9 +270,9 @@ bool QTextControlPrivate::cursorMoveKeyEvent(QKeyEvent *e)
bool isNavigationEvent = e->key() == Qt::Key_Up || e->key() == Qt::Key_Down;
#ifdef QT_KEYPAD_NAVIGATION
- ignoreNavigationEvents = ignoreNavigationEvents || QApplication::keypadNavigationEnabled();
+ ignoreNavigationEvents = ignoreNavigationEvents || QGuiApplication::keypadNavigationEnabled();
isNavigationEvent = isNavigationEvent ||
- (QApplication::navigationMode() == Qt::NavigationModeKeypadDirectional
+ (QGuiApplication::navigationMode() == Qt::NavigationModeKeypadDirectional
&& (e->key() == Qt::Key_Left || e->key() == Qt::Key_Right));
#else
isNavigationEvent = isNavigationEvent || e->key() == Qt::Key_Left || e->key() == Qt::Key_Right;
@@ -427,7 +424,7 @@ void QTextControlPrivate::setContent(Qt::TextFormat format, const QString &text,
doc = document;
clearDocument = false;
} else {
- palette = QApplication::palette("QTextControl");
+ palette = QGuiApplication::palette();
doc = new QTextDocument(q);
}
_q_documentLayoutChanged();
@@ -506,11 +503,11 @@ void QTextControlPrivate::startDrag()
#ifndef QT_NO_DRAGANDDROP
Q_Q(QTextControl);
mousePressed = false;
- if (!contextWidget)
+ if (!contextObject)
return;
QMimeData *data = q->createMimeDataFromSelection();
- QDrag *drag = new QDrag(contextWidget);
+ QDrag *drag = new QDrag(contextObject);
drag->setMimeData(data);
Qt::DropActions actions = Qt::CopyAction;
@@ -522,7 +519,7 @@ void QTextControlPrivate::startDrag()
action = drag->exec(actions, Qt::CopyAction);
}
- if (action == Qt::MoveAction && drag->target() != contextWidget)
+ if (action == Qt::MoveAction && drag->target() != contextObject)
cursor.removeSelectedText();
#endif
}
@@ -606,7 +603,7 @@ void QTextControlPrivate::_q_updateCurrentCharFormatAndSelection()
#ifndef QT_NO_CLIPBOARD
void QTextControlPrivate::setClipboardSelection()
{
- QClipboard *clipboard = QApplication::clipboard();
+ QClipboard *clipboard = QGuiApplication::clipboard();
if (!cursor.hasSelection() || !clipboard->supportsSelection())
return;
Q_Q(QTextControl);
@@ -638,8 +635,8 @@ void QTextControlPrivate::setBlinkingCursorEnabled(bool enable)
{
Q_Q(QTextControl);
- if (enable && QApplication::cursorFlashTime() > 0)
- cursorBlinkTimer.start(QApplication::cursorFlashTime() / 2, q);
+ if (enable && qApp->styleHints()->cursorFlashTime() > 0)
+ cursorBlinkTimer.start(qApp->styleHints()->cursorFlashTime() / 2, q);
else
cursorBlinkTimer.stop();
@@ -808,6 +805,18 @@ QTextControl::~QTextControl()
{
}
+void QTextControl::setView(QObject *view)
+{
+ Q_D(QTextControl);
+ d->contextObject = view;
+}
+
+QObject *QTextControl::view() const
+{
+ Q_D(const QTextControl);
+ return d->contextObject;
+}
+
void QTextControl::setDocument(QTextDocument *document)
{
Q_D(QTextControl);
@@ -869,12 +878,12 @@ void QTextControl::copy()
if (!d->cursor.hasSelection())
return;
QMimeData *data = createMimeDataFromSelection();
- QApplication::clipboard()->setMimeData(data);
+ QGuiApplication::clipboard()->setMimeData(data);
}
void QTextControl::paste(QClipboard::Mode mode)
{
- const QMimeData *md = QApplication::clipboard()->mimeData(mode);
+ const QMimeData *md = QGuiApplication::clipboard()->mimeData(mode);
if (md)
insertFromMimeData(md);
}
@@ -899,14 +908,14 @@ void QTextControl::selectAll()
emit updateRequest();
}
-void QTextControl::processEvent(QEvent *e, const QPointF &coordinateOffset, QWidget *contextWidget)
+void QTextControl::processEvent(QEvent *e, const QPointF &coordinateOffset)
{
QMatrix m;
m.translate(coordinateOffset.x(), coordinateOffset.y());
- processEvent(e, m, contextWidget);
+ processEvent(e, m);
}
-void QTextControl::processEvent(QEvent *e, const QMatrix &matrix, QWidget *contextWidget)
+void QTextControl::processEvent(QEvent *e, const QMatrix &matrix)
{
Q_D(QTextControl);
if (d->interactionFlags == Qt::NoTextInteraction) {
@@ -914,33 +923,6 @@ void QTextControl::processEvent(QEvent *e, const QMatrix &matrix, QWidget *conte
return;
}
- d->contextWidget = contextWidget;
-
- if (!d->contextWidget) {
- switch (e->type()) {
-#ifndef QT_NO_GRAPHICSVIEW
- case QEvent::GraphicsSceneMouseMove:
- case QEvent::GraphicsSceneMousePress:
- case QEvent::GraphicsSceneMouseRelease:
- case QEvent::GraphicsSceneMouseDoubleClick:
- case QEvent::GraphicsSceneContextMenu:
- case QEvent::GraphicsSceneHoverEnter:
- case QEvent::GraphicsSceneHoverMove:
- case QEvent::GraphicsSceneHoverLeave:
- case QEvent::GraphicsSceneHelp:
- case QEvent::GraphicsSceneDragEnter:
- case QEvent::GraphicsSceneDragMove:
- case QEvent::GraphicsSceneDragLeave:
- case QEvent::GraphicsSceneDrop: {
- QGraphicsSceneEvent *ev = static_cast<QGraphicsSceneEvent *>(e);
- d->contextWidget = ev->widget();
- break;
- }
-#endif // QT_NO_GRAPHICSVIEW
- default: break;
- };
- }
-
switch (e->type()) {
case QEvent::KeyPress:
d->keyPressEvent(static_cast<QKeyEvent *>(e));
@@ -968,12 +950,6 @@ void QTextControl::processEvent(QEvent *e, const QMatrix &matrix, QWidget *conte
case QEvent::InputMethod:
d->inputMethodEvent(static_cast<QInputMethodEvent *>(e));
break;
-#ifndef QT_NO_CONTEXTMENU
- case QEvent::ContextMenu: {
- QContextMenuEvent *ev = static_cast<QContextMenuEvent *>(e);
- d->contextMenuEvent(ev->globalPos(), matrix.map(ev->pos()), contextWidget);
- break; }
-#endif // QT_NO_CONTEXTMENU
case QEvent::FocusIn:
case QEvent::FocusOut:
d->focusEvent(static_cast<QFocusEvent *>(e));
@@ -983,14 +959,6 @@ void QTextControl::processEvent(QEvent *e, const QMatrix &matrix, QWidget *conte
d->isEnabled = e->isAccepted();
break;
-#ifndef QT_NO_TOOLTIP
- case QEvent::ToolTip: {
- QHelpEvent *ev = static_cast<QHelpEvent *>(e);
- d->showToolTip(ev->globalPos(), matrix.map(ev->pos()), contextWidget);
- break;
- }
-#endif // QT_NO_TOOLTIP
-
#ifndef QT_NO_DRAGANDDROP
case QEvent::DragEnter: {
QDragEnterEvent *ev = static_cast<QDragEnterEvent *>(e);
@@ -1015,61 +983,10 @@ void QTextControl::processEvent(QEvent *e, const QMatrix &matrix, QWidget *conte
}
#endif
-#ifndef QT_NO_GRAPHICSVIEW
- case QEvent::GraphicsSceneMousePress: {
- QGraphicsSceneMouseEvent *ev = static_cast<QGraphicsSceneMouseEvent *>(e);
- d->mousePressEvent(ev, ev->button(), matrix.map(ev->pos()), ev->modifiers(), ev->buttons(),
- ev->screenPos());
- break; }
- case QEvent::GraphicsSceneMouseMove: {
- QGraphicsSceneMouseEvent *ev = static_cast<QGraphicsSceneMouseEvent *>(e);
- d->mouseMoveEvent(ev, ev->button(), matrix.map(ev->pos()), ev->modifiers(), ev->buttons(),
- ev->screenPos());
- break; }
- case QEvent::GraphicsSceneMouseRelease: {
- QGraphicsSceneMouseEvent *ev = static_cast<QGraphicsSceneMouseEvent *>(e);
- d->mouseReleaseEvent(ev, ev->button(), matrix.map(ev->pos()), ev->modifiers(), ev->buttons(),
- ev->screenPos());
- break; }
- case QEvent::GraphicsSceneMouseDoubleClick: {
- QGraphicsSceneMouseEvent *ev = static_cast<QGraphicsSceneMouseEvent *>(e);
- d->mouseDoubleClickEvent(ev, ev->button(), matrix.map(ev->pos()), ev->modifiers(), ev->buttons(),
- ev->screenPos());
- break; }
- case QEvent::GraphicsSceneContextMenu: {
- QGraphicsSceneContextMenuEvent *ev = static_cast<QGraphicsSceneContextMenuEvent *>(e);
- d->contextMenuEvent(ev->screenPos(), matrix.map(ev->pos()), contextWidget);
- break; }
-
- case QEvent::GraphicsSceneHoverMove: {
- QGraphicsSceneHoverEvent *ev = static_cast<QGraphicsSceneHoverEvent *>(e);
- d->mouseMoveEvent(ev, Qt::NoButton, matrix.map(ev->pos()), ev->modifiers(),Qt::NoButton,
- ev->screenPos());
- break; }
-
- case QEvent::GraphicsSceneDragEnter: {
- QGraphicsSceneDragDropEvent *ev = static_cast<QGraphicsSceneDragDropEvent *>(e);
- if (d->dragEnterEvent(e, ev->mimeData()))
- ev->acceptProposedAction();
- break; }
- case QEvent::GraphicsSceneDragLeave:
- d->dragLeaveEvent();
- break;
- case QEvent::GraphicsSceneDragMove: {
- QGraphicsSceneDragDropEvent *ev = static_cast<QGraphicsSceneDragDropEvent *>(e);
- if (d->dragMoveEvent(e, ev->mimeData(), matrix.map(ev->pos())))
- ev->acceptProposedAction();
- break; }
- case QEvent::GraphicsSceneDrop: {
- QGraphicsSceneDragDropEvent *ev = static_cast<QGraphicsSceneDragDropEvent *>(e);
- if (d->dropEvent(ev->mimeData(), matrix.map(ev->pos()), ev->dropAction(), ev->source()))
- ev->accept();
- break; }
-#endif // QT_NO_GRAPHICSVIEW
#ifdef QT_KEYPAD_NAVIGATION
case QEvent::EnterEditFocus:
case QEvent::LeaveEditFocus:
- if (QApplication::keypadNavigationEnabled())
+ if (QGuiApplication::keypadNavigationEnabled())
d->editFocusEvent(e);
break;
#endif
@@ -1140,9 +1057,10 @@ void QTextControl::timerEvent(QTimerEvent *e)
if (e->timerId() == d->cursorBlinkTimer.timerId()) {
d->cursorOn = !d->cursorOn;
- if (d->cursor.hasSelection())
- d->cursorOn &= (QApplication::style()->styleHint(QStyle::SH_BlinkCursorWhenTextSelected)
- != 0);
+ // ###
+// if (d->cursor.hasSelection())
+// d->cursorOn &= (QGuiApplication::style()->styleHint(QStyle::SH_BlinkCursorWhenTextSelected)
+// != 0);
d->repaintCursor();
} else if (e->timerId() == d->trippleClickTimer.timerId()) {
@@ -1323,7 +1241,7 @@ process:
QVariant QTextControl::loadResource(int type, const QUrl &name)
{
-#ifdef QT_NO_TEXTEDIT
+#if 1
Q_UNUSED(type);
Q_UNUSED(name);
#else
@@ -1544,7 +1462,7 @@ void QTextControlPrivate::mousePressEvent(QEvent *e, Qt::MouseButton button, con
#endif
if (trippleClickTimer.isActive()
- && ((pos - trippleClickPoint).toPoint().manhattanLength() < QApplication::startDragDistance())) {
+ && ((pos - trippleClickPoint).toPoint().manhattanLength() < qApp->styleHints()->startDragDistance())) {
cursor.movePosition(QTextCursor::StartOfBlock);
cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
@@ -1642,7 +1560,7 @@ void QTextControlPrivate::mouseMoveEvent(QEvent *e, Qt::MouseButton button, cons
const int oldCursorPos = cursor.position();
if (mightStartDrag) {
- if ((mousePos.toPoint() - dragStartPos).manhattanLength() > QApplication::startDragDistance())
+ if ((mousePos.toPoint() - dragStartPos).manhattanLength() > qApp->styleHints()->startDragDistance())
startDrag();
return;
}
@@ -1675,13 +1593,8 @@ void QTextControlPrivate::mouseMoveEvent(QEvent *e, Qt::MouseButton button, cons
if (cursor.position() != oldCursorPos)
emit q->cursorPositionChanged();
_q_updateCurrentCharFormatAndSelection();
-#ifndef QT_NO_IM
- if (contextWidget) {
- if (QInputContext *ic = inputContext()) {
- ic->update();
- }
- }
-#endif //QT_NO_IM
+ if (qGuiApp)
+ qGuiApp->inputPanel()->update(Qt::ImQueryAll);
} else {
//emit q->visibilityRequest(QRectF(mousePos, QSizeF(1, 1)));
if (cursor.position() != oldCursorPos) {
@@ -1721,9 +1634,9 @@ void QTextControlPrivate::mouseReleaseEvent(QEvent *e, Qt::MouseButton button, c
selectionChanged(true);
} else if (button == Qt::MidButton
&& (interactionFlags & Qt::TextEditable)
- && QApplication::clipboard()->supportsSelection()) {
+ && QGuiApplication::clipboard()->supportsSelection()) {
setCursorPosition(pos);
- const QMimeData *md = QApplication::clipboard()->mimeData(QClipboard::Selection);
+ const QMimeData *md = QGuiApplication::clipboard()->mimeData(QClipboard::Selection);
if (md)
q->insertFromMimeData(md);
#endif
@@ -1793,7 +1706,7 @@ void QTextControlPrivate::mouseDoubleClickEvent(QEvent *e, Qt::MouseButton butto
selectedWordOnDoubleClick = cursor;
trippleClickPoint = pos;
- trippleClickTimer.start(QApplication::doubleClickInterval(), q);
+ trippleClickTimer.start(qApp->styleHints()->mouseDoubleClickInterval(), q);
if (doEmit) {
selectionChanged();
#ifndef QT_NO_CLIPBOARD
@@ -1807,11 +1720,11 @@ bool QTextControlPrivate::sendMouseEventToInputContext(
QEvent *e, QEvent::Type eventType, Qt::MouseButton button, const QPointF &pos,
Qt::KeyboardModifiers modifiers, Qt::MouseButtons buttons, const QPoint &globalPos)
{
-#if !defined(QT_NO_IM)
+#if 0 // ### !defined(QT_NO_IM)
Q_Q(QTextControl);
QTextLayout *layout = cursor.block().layout();
- if (contextWidget && layout && !layout->preeditAreaText().isEmpty()) {
+ if (contextObject && layout && !layout->preeditAreaText().isEmpty()) {
QInputContext *ctx = inputContext();
int cursorPos = q->hitTest(pos, Qt::FuzzyHit) - cursor.position();
@@ -1822,7 +1735,7 @@ bool QTextControlPrivate::sendMouseEventToInputContext(
return true;
}
if (ctx) {
- QMouseEvent ev(eventType, contextWidget->mapFromGlobal(globalPos), globalPos,
+ QMouseEvent ev(eventType, contextObject->mapFromGlobal(globalPos), globalPos,
button, buttons, modifiers);
ctx->mouseHandler(cursorPos, &ev);
e->setAccepted(ev.isAccepted());
@@ -1842,24 +1755,6 @@ bool QTextControlPrivate::sendMouseEventToInputContext(
return false;
}
-void QTextControlPrivate::contextMenuEvent(const QPoint &screenPos, const QPointF &docPos, QWidget *contextWidget)
-{
-#ifdef QT_NO_CONTEXTMENU
- Q_UNUSED(screenPos);
- Q_UNUSED(docPos);
- Q_UNUSED(contextWidget);
-#else
- Q_Q(QTextControl);
- if (!hasFocus)
- return;
- QMenu *menu = q->createStandardContextMenu(docPos, contextWidget);
- if (!menu)
- return;
- menu->setAttribute(Qt::WA_DeleteOnClose);
- menu->popup(screenPos);
-#endif
-}
-
bool QTextControlPrivate::dragEnterEvent(QEvent *e, const QMimeData *mimeData)
{
Q_Q(QTextControl);
@@ -1908,7 +1803,7 @@ bool QTextControlPrivate::dragMoveEvent(QEvent *e, const QMimeData *mimeData, co
return true; // accept proposed action
}
-bool QTextControlPrivate::dropEvent(const QMimeData *mimeData, const QPointF &pos, Qt::DropAction dropAction, QWidget *source)
+bool QTextControlPrivate::dropEvent(const QMimeData *mimeData, const QPointF &pos, Qt::DropAction dropAction, QObject *source)
{
Q_Q(QTextControl);
dndFeedbackCursor = QTextCursor();
@@ -1921,7 +1816,7 @@ bool QTextControlPrivate::dropEvent(const QMimeData *mimeData, const QPointF &po
QTextCursor insertionCursor = q->cursorForPosition(pos);
insertionCursor.beginEditBlock();
- if (dropAction == Qt::MoveAction && source == contextWidget)
+ if (dropAction == Qt::MoveAction && source == contextObject)
cursor.removeSelectedText();
cursor = insertionCursor;
@@ -1995,8 +1890,9 @@ void QTextControlPrivate::inputMethodEvent(QInputMethodEvent *e)
}
layout->setAdditionalFormats(overrides);
cursor.endEditBlock();
- if (cursor.d)
- cursor.d->setX();
+ QTextCursorPrivate *cursor_d = QTextCursorPrivate::getPrivate(&cursor);
+ if (cursor_d)
+ cursor_d->setX();
if (oldPreeditCursor != preeditCursor)
emit q->microFocusChanged();
selectionChanged(forceSelectionChanged);
@@ -2007,7 +1903,7 @@ QVariant QTextControl::inputMethodQuery(Qt::InputMethodQuery property) const
Q_D(const QTextControl);
QTextBlock block = d->cursor.block();
switch(property) {
- case Qt::ImMicroFocus:
+ case Qt::ImCursorRectangle:
return cursorRect();
case Qt::ImFont:
return QVariant(d->cursor.charFormat().font());
@@ -2039,7 +1935,7 @@ void QTextControlPrivate::focusEvent(QFocusEvent *e)
emit q->updateRequest(q->selectionRect());
if (e->gotFocus()) {
#ifdef QT_KEYPAD_NAVIGATION
- if (!QApplication::keypadNavigationEnabled() || (hasEditFocus && (e->reason() == Qt::PopupFocusReason
+ if (!QGuiApplication::keypadNavigationEnabled() || (hasEditFocus && (e->reason() == Qt::PopupFocusReason
#ifdef Q_OS_SYMBIAN
|| e->reason() == Qt::ActiveWindowFocusReason
#endif
@@ -2084,7 +1980,7 @@ void QTextControlPrivate::editFocusEvent(QEvent *e)
{
Q_Q(QTextControl);
- if (QApplication::keypadNavigationEnabled()) {
+ if (QGuiApplication::keypadNavigationEnabled()) {
if (e->type() == QEvent::EnterEditFocus && interactionFlags & Qt::TextEditable) {
const QTextCursor oldSelection = cursor;
const int oldCursorPos = cursor.position();
@@ -2107,87 +2003,6 @@ void QTextControlPrivate::editFocusEvent(QEvent *e)
}
#endif
-#ifndef QT_NO_CONTEXTMENU
-QMenu *QTextControl::createStandardContextMenu(const QPointF &pos, QWidget *parent)
-{
- Q_D(QTextControl);
-
- const bool showTextSelectionActions = d->interactionFlags & (Qt::TextEditable | Qt::TextSelectableByKeyboard | Qt::TextSelectableByMouse);
-
- d->linkToCopy = QString();
- if (!pos.isNull())
- d->linkToCopy = anchorAt(pos);
-
- if (d->linkToCopy.isEmpty() && !showTextSelectionActions)
- return 0;
-
- QMenu *menu = new QMenu(parent);
- QAction *a;
-
- if (d->interactionFlags & Qt::TextEditable) {
- a = menu->addAction(tr("&Undo") + ACCEL_KEY(QKeySequence::Undo), this, SLOT(undo()));
- a->setEnabled(d->doc->isUndoAvailable());
- a = menu->addAction(tr("&Redo") + ACCEL_KEY(QKeySequence::Redo), this, SLOT(redo()));
- a->setEnabled(d->doc->isRedoAvailable());
- menu->addSeparator();
-
- a = menu->addAction(tr("Cu&t") + ACCEL_KEY(QKeySequence::Cut), this, SLOT(cut()));
- a->setEnabled(d->cursor.hasSelection());
- }
-
- if (showTextSelectionActions) {
- a = menu->addAction(tr("&Copy") + ACCEL_KEY(QKeySequence::Copy), this, SLOT(copy()));
- a->setEnabled(d->cursor.hasSelection());
- }
-
- if ((d->interactionFlags & Qt::LinksAccessibleByKeyboard)
- || (d->interactionFlags & Qt::LinksAccessibleByMouse)) {
-
- a = menu->addAction(tr("Copy &Link Location"), this, SLOT(_q_copyLink()));
- a->setEnabled(!d->linkToCopy.isEmpty());
- }
-
- if (d->interactionFlags & Qt::TextEditable) {
-#if !defined(QT_NO_CLIPBOARD)
- a = menu->addAction(tr("&Paste") + ACCEL_KEY(QKeySequence::Paste), this, SLOT(paste()));
- a->setEnabled(canPaste());
-#endif
- a = menu->addAction(tr("Delete"), this, SLOT(_q_deleteSelected()));
- a->setEnabled(d->cursor.hasSelection());
- }
-
-
- if (showTextSelectionActions) {
- menu->addSeparator();
- a = menu->addAction(tr("Select All") + ACCEL_KEY(QKeySequence::SelectAll), this, SLOT(selectAll()));
- a->setEnabled(!d->doc->isEmpty());
- }
-
-#if !defined(QT_NO_IM)
- if (d->contextWidget) {
- QInputContext *qic = d->inputContext();
- if (qic) {
- QList<QAction *> imActions = qic->actions();
- for (int i = 0; i < imActions.size(); ++i)
- menu->addAction(imActions.at(i));
- }
- }
-#endif
-
-#if defined(Q_WS_WIN) || defined(Q_WS_X11)
- if ((d->interactionFlags & Qt::TextEditable) && qt_use_rtl_extensions) {
-#else
- if (d->interactionFlags & Qt::TextEditable) {
-#endif
- menu->addSeparator();
- QUnicodeControlCharacterMenu *ctrlCharacterMenu = new QUnicodeControlCharacterMenu(this, menu);
- menu->addMenu(ctrlCharacterMenu);
- }
-
- return menu;
-}
-#endif // QT_NO_CONTEXTMENU
-
QTextCursor QTextControl::cursorForPosition(const QPointF &pos) const
{
Q_D(const QTextControl);
@@ -2264,7 +2079,7 @@ void QTextControl::setCursorWidth(int width)
Q_UNUSED(width);
#else
if (width == -1)
- width = QApplication::style()->pixelMetric(QStyle::PM_TextCursorWidth);
+ width = textCursorWidth;
d->doc->documentLayout()->setProperty("cursorWidth", width);
#endif
d->repaintCursor();
@@ -2282,9 +2097,7 @@ void QTextControl::setAcceptRichText(bool accept)
d->acceptRichText = accept;
}
-#ifndef QT_NO_TEXTEDIT
-
-void QTextControl::setExtraSelections(const QList<QTextEdit::ExtraSelection> &selections)
+void QTextControl::setExtraSelections(const QVector<QAbstractTextDocumentLayout::Selection> &selections)
{
Q_D(QTextControl);
@@ -2295,7 +2108,7 @@ void QTextControl::setExtraSelections(const QList<QTextEdit::ExtraSelection> &se
}
for (int i = 0; i < selections.count(); ++i) {
- const QTextEdit::ExtraSelection &sel = selections.at(i);
+ const QAbstractTextDocumentLayout::Selection &sel = selections.at(i);
QHash<int, int>::iterator it = hash.find(sel.cursor.anchor());
if (it != hash.end()) {
const QAbstractTextDocumentLayout::Selection &esel = d->extraSelections.at(it.value());
@@ -2323,28 +2136,15 @@ void QTextControl::setExtraSelections(const QList<QTextEdit::ExtraSelection> &se
emit updateRequest(r);
}
- d->extraSelections.resize(selections.count());
- for (int i = 0; i < selections.count(); ++i) {
- d->extraSelections[i].cursor = selections.at(i).cursor;
- d->extraSelections[i].format = selections.at(i).format;
- }
+ d->extraSelections = selections;
}
-QList<QTextEdit::ExtraSelection> QTextControl::extraSelections() const
+QVector<QAbstractTextDocumentLayout::Selection> QTextControl::extraSelections() const
{
Q_D(const QTextControl);
- QList<QTextEdit::ExtraSelection> selections;
- for (int i = 0; i < d->extraSelections.count(); ++i) {
- QTextEdit::ExtraSelection sel;
- sel.cursor = d->extraSelections.at(i).cursor;
- sel.format = d->extraSelections.at(i).format;
- selections.append(sel);
- }
- return selections;
+ return d->extraSelections;
}
-#endif // QT_NO_TEXTEDIT
-
void QTextControl::setTextWidth(qreal width)
{
Q_D(QTextControl);
@@ -2404,7 +2204,7 @@ bool QTextControl::canPaste() const
#ifndef QT_NO_CLIPBOARD
Q_D(const QTextControl);
if (d->interactionFlags & Qt::TextEditable) {
- const QMimeData *md = QApplication::clipboard()->mimeData();
+ const QMimeData *md = QGuiApplication::clipboard()->mimeData();
return md && canInsertFromMimeData(md);
}
#endif
@@ -2449,16 +2249,14 @@ bool QTextControl::isWordSelectionEnabled() const
return d->wordSelectionEnabled;
}
-#ifndef QT_NO_PRINTER
-void QTextControl::print(QPrinter *printer) const
+void QTextControl::print(QPagedPaintDevice *printer) const
{
-#ifndef QT_NO_PRINTER
Q_D(const QTextControl);
- if (!printer || !printer->isValid())
+ if (!printer)
return;
QTextDocument *tempDoc = 0;
const QTextDocument *doc = d->doc;
- if (printer->printRange() == QPrinter::Selection) {
+ if (QPagedPaintDevicePrivate::get(printer)->printSelectionOnly) {
if (!d->cursor.hasSelection())
return;
tempDoc = new QTextDocument(const_cast<QTextDocument *>(doc));
@@ -2474,9 +2272,7 @@ void QTextControl::print(QPrinter *printer) const
}
doc->print(printer);
delete tempDoc;
-#endif
}
-#endif // QT_NO_PRINTER
QMimeData *QTextControl::createMimeDataFromSelection() const
{
@@ -2734,7 +2530,7 @@ void QTextControlPrivate::activateLinkUnderCursor(QString href)
}
repaintOldAndNewSelection(oldCursor);
-#ifndef QT_NO_DESKTOPSERVICES
+#if 0 // ###ndef QT_NO_DESKTOPSERVICES
if (openExternalLinks)
QDesktopServices::openUrl(href);
else
@@ -2742,16 +2538,6 @@ void QTextControlPrivate::activateLinkUnderCursor(QString href)
emit q_func()->linkActivated(href);
}
-#ifndef QT_NO_TOOLTIP
-void QTextControlPrivate::showToolTip(const QPoint &globalPos, const QPointF &pos, QWidget *contextWidget)
-{
- const QString toolTip = q_func()->cursorForPosition(pos).charFormat().toolTip();
- if (toolTip.isEmpty())
- return;
- QToolTip::showText(globalPos, toolTip, contextWidget);
-}
-#endif // QT_NO_TOOLTIP
-
bool QTextControl::setFocusToNextOrPreviousAnchor(bool next)
{
Q_D(QTextControl);
@@ -2988,7 +2774,7 @@ bool QTextControl::cursorOn() const
return d->cursorOn;
}
-QAbstractTextDocumentLayout::PaintContext QTextControl::getPaintContext(QWidget *widget) const
+QAbstractTextDocumentLayout::PaintContext QTextControl::getPaintContext() const
{
Q_D(const QTextControl);
@@ -3008,31 +2794,28 @@ QAbstractTextDocumentLayout::PaintContext QTextControl::getPaintContext(QWidget
if (!d->dndFeedbackCursor.isNull())
ctx.cursorPosition = d->dndFeedbackCursor.position();
#ifdef QT_KEYPAD_NAVIGATION
- if (!QApplication::keypadNavigationEnabled() || d->hasEditFocus)
+ if (!QGuiApplication::keypadNavigationEnabled() || d->hasEditFocus)
#endif
if (d->cursor.hasSelection()) {
QAbstractTextDocumentLayout::Selection selection;
selection.cursor = d->cursor;
- if (d->cursorIsFocusIndicator) {
+ if (0 && d->cursorIsFocusIndicator) {
+#if 0
+ // ###
QStyleOption opt;
opt.palette = ctx.palette;
QStyleHintReturnVariant ret;
- QStyle *style = QApplication::style();
+ QStyle *style = QGuiApplication::style();
if (widget)
style = widget->style();
style->styleHint(QStyle::SH_TextControl_FocusIndicatorTextCharFormat, &opt, widget, &ret);
selection.format = qvariant_cast<QTextFormat>(ret.variant).toCharFormat();
+#endif
} else {
QPalette::ColorGroup cg = d->hasFocus ? QPalette::Active : QPalette::Inactive;
selection.format.setBackground(ctx.palette.brush(cg, QPalette::Highlight));
selection.format.setForeground(ctx.palette.brush(cg, QPalette::HighlightedText));
- QStyleOption opt;
- QStyle *style = QApplication::style();
- if (widget) {
- opt.initFrom(widget);
- style = widget->style();
- }
- if (style->styleHint(QStyle::SH_RichText_FullWidthSelection, &opt, widget))
+ if (fullWidthSelection)
selection.format.setProperty(QTextFormat::FullWidthSelection, true);
}
ctx.selections.append(selection);
@@ -3041,11 +2824,11 @@ QAbstractTextDocumentLayout::PaintContext QTextControl::getPaintContext(QWidget
return ctx;
}
-void QTextControl::drawContents(QPainter *p, const QRectF &rect, QWidget *widget)
+void QTextControl::drawContents(QPainter *p, const QRectF &rect)
{
Q_D(QTextControl);
p->save();
- QAbstractTextDocumentLayout::PaintContext ctx = getPaintContext(widget);
+ QAbstractTextDocumentLayout::PaintContext ctx = getPaintContext();
if (rect.isValid())
p->setClipRect(rect, Qt::IntersectClip);
ctx.clip = rect;
@@ -3059,16 +2842,21 @@ void QTextControlPrivate::_q_copyLink()
#ifndef QT_NO_CLIPBOARD
QMimeData *md = new QMimeData;
md->setText(linkToCopy);
- QApplication::clipboard()->setMimeData(md);
+ QGuiApplication::clipboard()->setMimeData(md);
#endif
}
QInputContext *QTextControlPrivate::inputContext()
{
- QInputContext *ctx = contextWidget->inputContext();
- if (!ctx && contextWidget->parentWidget())
- ctx = contextWidget->parentWidget()->inputContext();
+#if 0
+ // ###
+ QInputContext *ctx = contextObject->inputContext();
+ if (!ctx && contextObject->parentWidget())
+ ctx = contextObject->parentWidget()->inputContext();
return ctx;
+#else
+ return 0;
+#endif
}
int QTextControl::hitTest(const QPointF &point, Qt::HitTestAccuracy accuracy) const
@@ -3083,59 +2871,7 @@ QRectF QTextControl::blockBoundingRect(const QTextBlock &block) const
return d->doc->documentLayout()->blockBoundingRect(block);
}
-#ifndef QT_NO_CONTEXTMENU
-#define NUM_CONTROL_CHARACTERS 10
-const struct QUnicodeControlCharacter {
- const char *text;
- ushort character;
-} qt_controlCharacters[NUM_CONTROL_CHARACTERS] = {
- { QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "LRM Left-to-right mark"), 0x200e },
- { QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "RLM Right-to-left mark"), 0x200f },
- { QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "ZWJ Zero width joiner"), 0x200d },
- { QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "ZWNJ Zero width non-joiner"), 0x200c },
- { QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "ZWSP Zero width space"), 0x200b },
- { QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "LRE Start of left-to-right embedding"), 0x202a },
- { QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "RLE Start of right-to-left embedding"), 0x202b },
- { QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "LRO Start of left-to-right override"), 0x202d },
- { QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "RLO Start of right-to-left override"), 0x202e },
- { QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "PDF Pop directional formatting"), 0x202c },
-};
-
-QUnicodeControlCharacterMenu::QUnicodeControlCharacterMenu(QObject *_editWidget, QWidget *parent)
- : QMenu(parent), editWidget(_editWidget)
-{
- setTitle(tr("Insert Unicode control character"));
- for (int i = 0; i < NUM_CONTROL_CHARACTERS; ++i) {
- addAction(tr(qt_controlCharacters[i].text), this, SLOT(menuActionTriggered()));
- }
-}
-
-void QUnicodeControlCharacterMenu::menuActionTriggered()
-{
- QAction *a = qobject_cast<QAction *>(sender());
- int idx = actions().indexOf(a);
- if (idx < 0 || idx >= NUM_CONTROL_CHARACTERS)
- return;
- QChar c(qt_controlCharacters[idx].character);
- QString str(c);
-#ifndef QT_NO_TEXTEDIT
- if (QTextEdit *edit = qobject_cast<QTextEdit *>(editWidget)) {
- edit->insertPlainText(str);
- return;
- }
-#endif
- if (QTextControl *control = qobject_cast<QTextControl *>(editWidget)) {
- control->insertPlainText(str);
- }
-#ifndef QT_NO_LINEEDIT
- if (QLineEdit *edit = qobject_cast<QLineEdit *>(editWidget)) {
- edit->insert(str);
- return;
- }
-#endif
-}
-#endif // QT_NO_CONTEXTMENU
QStringList QTextEditMimeData::formats() const
{
diff --git a/src/gui/text/qtextcontrol_p.h b/src/gui/text/qtextcontrol_p.h
index c5ed0ee1e0..bb91415fd2 100644
--- a/src/gui/text/qtextcontrol_p.h
+++ b/src/gui/text/qtextcontrol_p.h
@@ -57,18 +57,11 @@
#include <QtGui/qtextoption.h>
#include <QtGui/qtextcursor.h>
#include <QtGui/qtextformat.h>
-#include <QtGui/qtextedit.h>
-#include <QtGui/qmenu.h>
#include <QtCore/qrect.h>
#include <QtGui/qabstracttextdocumentlayout.h>
#include <QtGui/qtextdocumentfragment.h>
#include <QtGui/qclipboard.h>
-#ifdef QT3_SUPPORT
-#include <QtGui/qtextobject.h>
-#include <QtGui/qtextlayout.h>
-#endif
-
QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
@@ -77,12 +70,12 @@ QT_MODULE(Gui)
class QStyleSheet;
class QTextDocument;
-class QMenu;
class QTextControlPrivate;
class QMimeData;
class QAbstractScrollArea;
class QEvent;
class QTimerEvent;
+class QPagedPaintDevice;
class Q_GUI_EXPORT QTextControl : public QObject
{
@@ -103,6 +96,9 @@ public:
explicit QTextControl(QTextDocument *doc, QObject *parent = 0);
virtual ~QTextControl();
+ void setView(QObject *view);
+ QObject *view() const;
+
void setDocument(QTextDocument *document);
QTextDocument *document() const;
@@ -129,9 +125,6 @@ public:
virtual void ensureCursorVisible();
virtual QVariant loadResource(int type, const QUrl &name);
-#ifndef QT_NO_CONTEXTMENU
- QMenu *createStandardContextMenu(const QPointF &pos, QWidget *parent);
-#endif
QTextCursor cursorForPosition(const QPointF &pos) const;
QRectF cursorRect(const QTextCursor &cursor) const;
@@ -153,10 +146,8 @@ public:
bool acceptRichText() const;
void setAcceptRichText(bool accept);
-#ifndef QT_NO_TEXTEDIT
- void setExtraSelections(const QList<QTextEdit::ExtraSelection> &selections);
- QList<QTextEdit::ExtraSelection> extraSelections() const;
-#endif
+ void setExtraSelections(const QVector<QAbstractTextDocumentLayout::Selection> &selections);
+ QVector<QAbstractTextDocumentLayout::Selection> extraSelections() const;
void setTextWidth(qreal width);
qreal textWidth() const;
@@ -181,13 +172,11 @@ public:
bool isWordSelectionEnabled() const;
void setWordSelectionEnabled(bool enabled);
-#ifndef QT_NO_PRINTER
- void print(QPrinter *printer) const;
-#endif
+ void print(QPagedPaintDevice *printer) const;
virtual int hitTest(const QPointF &point, Qt::HitTestAccuracy accuracy) const;
virtual QRectF blockBoundingRect(const QTextBlock &block) const;
- QAbstractTextDocumentLayout::PaintContext getPaintContext(QWidget *widget) const;
+ QAbstractTextDocumentLayout::PaintContext getPaintContext() const;
public Q_SLOTS:
void setPlainText(const QString &text);
@@ -241,11 +230,11 @@ public:
QPalette palette() const;
void setPalette(const QPalette &pal);
- virtual void processEvent(QEvent *e, const QMatrix &matrix, QWidget *contextWidget = 0);
- void processEvent(QEvent *e, const QPointF &coordinateOffset = QPointF(), QWidget *contextWidget = 0);
+ virtual void processEvent(QEvent *e, const QMatrix &matrix);
+ void processEvent(QEvent *e, const QPointF &coordinateOffset = QPointF());
// control methods
- void drawContents(QPainter *painter, const QRectF &rect = QRectF(), QWidget *widget = 0);
+ void drawContents(QPainter *painter, const QRectF &rect = QRectF());
void setFocus(bool focus, Qt::FocusReason = Qt::OtherFocusReason);
@@ -277,22 +266,6 @@ private:
};
-#ifndef QT_NO_CONTEXTMENU
-class QUnicodeControlCharacterMenu : public QMenu
-{
- Q_OBJECT
-public:
- QUnicodeControlCharacterMenu(QObject *editWidget, QWidget *parent);
-
-private Q_SLOTS:
- void menuActionTriggered();
-
-private:
- QObject *editWidget;
-};
-#endif // QT_NO_CONTEXTMENU
-
-
// also used by QLabel
class QTextEditMimeData : public QMimeData
{
@@ -312,4 +285,4 @@ QT_END_NAMESPACE
QT_END_HEADER
-#endif // QTEXTCONTROL_H
+#endif // QTextControl_H
diff --git a/src/gui/text/qtextcontrol_p_p.h b/src/gui/text/qtextcontrol_p_p.h
index 1d7f9e9945..9c7ab56395 100644
--- a/src/gui/text/qtextcontrol_p_p.h
+++ b/src/gui/text/qtextcontrol_p_p.h
@@ -54,10 +54,8 @@
//
#include "QtGui/qtextdocumentfragment.h"
-#include "QtGui/qscrollbar.h"
#include "QtGui/qtextcursor.h"
#include "QtGui/qtextformat.h"
-#include "QtGui/qmenu.h"
#include "QtGui/qabstracttextdocumentlayout.h"
#include "QtCore/qbasictimer.h"
#include "QtCore/qpointer.h"
@@ -160,16 +158,12 @@ public:
bool dragEnterEvent(QEvent *e, const QMimeData *mimeData);
void dragLeaveEvent();
bool dragMoveEvent(QEvent *e, const QMimeData *mimeData, const QPointF &pos);
- bool dropEvent(const QMimeData *mimeData, const QPointF &pos, Qt::DropAction dropAction, QWidget *source);
+ bool dropEvent(const QMimeData *mimeData, const QPointF &pos, Qt::DropAction dropAction, QObject *source);
void inputMethodEvent(QInputMethodEvent *);
void activateLinkUnderCursor(QString href = QString());
-#ifndef QT_NO_TOOLTIP
- void showToolTip(const QPoint &globalPos, const QPointF &pos, QWidget *contextWidget);
-#endif
-
void append(const QString &text, Qt::TextFormat format = Qt::AutoText);
QInputContext *inputContext();
@@ -194,7 +188,7 @@ public:
bool mightStartDrag;
QPoint dragStartPos;
- QPointer<QWidget> contextWidget;
+ QPointer<QObject> contextObject;
bool lastSelectionState;
@@ -235,4 +229,4 @@ public:
QT_END_NAMESPACE
-#endif // QTEXTCONTROL_P_H
+#endif // QTextControl_P_H
diff --git a/src/gui/text/qtextcursor.h b/src/gui/text/qtextcursor.h
index 697899bcfa..bc4cdb5fb6 100644
--- a/src/gui/text/qtextcursor.h
+++ b/src/gui/text/qtextcursor.h
@@ -228,9 +228,10 @@ public:
private:
QSharedDataPointer<QTextCursorPrivate> d;
+ friend class QTextCursorPrivate;
friend class QTextDocumentFragmentPrivate;
friend class QTextCopyHelper;
- friend class QTextControlPrivate;
+ friend class QWidgetTextControlPrivate;
};
QT_END_NAMESPACE
diff --git a/src/gui/text/qtextcursor_p.h b/src/gui/text/qtextcursor_p.h
index aae512b0d1..c612169acf 100644
--- a/src/gui/text/qtextcursor_p.h
+++ b/src/gui/text/qtextcursor_p.h
@@ -61,13 +61,15 @@
QT_BEGIN_NAMESPACE
-class QTextCursorPrivate : public QSharedData
+class Q_GUI_EXPORT QTextCursorPrivate : public QSharedData
{
public:
QTextCursorPrivate(QTextDocumentPrivate *p);
QTextCursorPrivate(const QTextCursorPrivate &rhs);
~QTextCursorPrivate();
+ static inline QTextCursorPrivate *getPrivate(QTextCursor *c) { return c->d; }
+
enum AdjustResult { CursorMoved, CursorUnchanged };
AdjustResult adjustPosition(int positionOfChange, int charsAddedOrRemoved, QTextUndoCommand::Operation op);
diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp
index 143dc1ab8c..c1714edb0c 100644
--- a/src/gui/text/qtextdocument.cpp
+++ b/src/gui/text/qtextdocument.cpp
@@ -51,22 +51,20 @@
#include <qvarlengtharray.h>
#include <qtextcodec.h>
#include <qthread.h>
+#include <qcoreapplication.h>
+
#include "qtexthtmlparser_p.h"
#include "qpainter.h"
-#include "qprinter.h"
-#include "qtextedit.h"
#include <qfile.h>
#include <qfileinfo.h>
#include <qdir.h>
-#include <qapplication.h>
-#include "qtextcontrol_p.h"
#include "qfont_p.h"
-#include "private/qtextedit_p.h"
#include "private/qdataurl_p.h"
#include "qtextdocument_p.h"
-#include <private/qprinter_p.h>
#include <private/qabstracttextdocumentlayout_p.h>
+#include "qpagedpaintdevice.h"
+#include "private/qpagedpaintdevice_p.h"
#include <limits.h>
@@ -1696,7 +1694,7 @@ static void printPage(int index, QPainter *painter, const QTextDocument *doc, co
}
/*!
- Prints the document to the given \a printer. The QPrinter must be
+ Prints the document to the given \a device. The QPageablePaintDevice must be
set up before being used with this function.
This is only a convenience method to print the whole document to the printer.
@@ -1706,33 +1704,32 @@ static void printPage(int index, QPainter *painter, const QTextDocument *doc, co
If the document is not paginated, like for example a document used in a QTextEdit,
then a temporary copy of the document is created and the copy is broken into
- multiple pages according to the size of the QPrinter's paperRect(). By default
+ multiple pages according to the size of the paint device's paperRect(). By default
a 2 cm margin is set around the document contents. In addition the current page
number is printed at the bottom of each page.
- Note that QPrinter::Selection is not supported as print range with this function since
- the selection is a property of QTextCursor. If you have a QTextEdit associated with
- your QTextDocument then you can use QTextEdit's print() function because QTextEdit has
- access to the user's selection.
-
\sa QTextEdit::print()
*/
-void QTextDocument::print(QPrinter *printer) const
+void QTextDocument::print(QPagedPaintDevice *printer) const
{
Q_D(const QTextDocument);
- if (!printer || !printer->isValid())
+ if (!printer)
return;
- if (!d->title.isEmpty())
- printer->setDocName(d->title);
-
bool documentPaginated = d->pageSize.isValid() && !d->pageSize.isNull()
&& d->pageSize.height() != INT_MAX;
- if (!documentPaginated && !printer->fullPage() && !printer->d_func()->hasCustomPageMargins)
- printer->setPageMargins(23.53, 23.53, 23.53, 23.53, QPrinter::Millimeter);
+ QPagedPaintDevicePrivate *pd = QPagedPaintDevicePrivate::get(printer);
+
+ // ### set page size to paginated size?
+ QPagedPaintDevice::Margins m = printer->margins();
+ if (!documentPaginated && m.left == 0. && m.right == 0. && m.top == 0. && m.bottom == 0.) {
+ m.left = m.right = m.top = m.bottom = 2.;
+ printer->setMargins(m);
+ }
+ // ### use the margins correctly
QPainter p(printer);
@@ -1767,7 +1764,7 @@ void QTextDocument::print(QPrinter *printer) const
scaledPageSize.rwidth() *= dpiScaleX;
scaledPageSize.rheight() *= dpiScaleY;
- const QSizeF printerPageSize(printer->pageRect().size());
+ const QSizeF printerPageSize(printer->width(), printer->height());
// scale to page
p.scale(printerPageSize.width() / scaledPageSize.width(),
@@ -1789,17 +1786,12 @@ void QTextDocument::print(QPrinter *printer) const
layout->d_func()->handlers = documentLayout()->d_func()->handlers;
int dpiy = p.device()->logicalDpiY();
- int margin = 0;
- if (printer->fullPage() && !printer->d_func()->hasCustomPageMargins) {
- // for compatibility
- margin = (int) ((2/2.54)*dpiy); // 2 cm margins
- QTextFrameFormat fmt = doc->rootFrame()->frameFormat();
- fmt.setMargin(margin);
- doc->rootFrame()->setFrameFormat(fmt);
- }
+ int margin = (int) ((2/2.54)*dpiy); // 2 cm margins
+ QTextFrameFormat fmt = doc->rootFrame()->frameFormat();
+ fmt.setMargin(margin);
+ doc->rootFrame()->setFrameFormat(fmt);
- QRectF pageRect(printer->pageRect());
- body = QRectF(0, 0, pageRect.width(), pageRect.height());
+ body = QRectF(0, 0, printer->width(), printer->height());
pageNumberPos = QPointF(body.width() - margin,
body.height() - margin
+ QFontMetrics(doc->defaultFont(), p.device()).ascent()
@@ -1807,18 +1799,8 @@ void QTextDocument::print(QPrinter *printer) const
clonedDoc->setPageSize(body.size());
}
- int docCopies;
- int pageCopies;
- if (printer->collateCopies() == true){
- docCopies = 1;
- pageCopies = printer->supportsMultipleCopies() ? 1 : printer->copyCount();
- } else {
- docCopies = printer->supportsMultipleCopies() ? 1 : printer->copyCount();
- pageCopies = 1;
- }
-
- int fromPage = printer->fromPage();
- int toPage = printer->toPage();
+ int fromPage = pd->fromPage;
+ int toPage = pd->toPage;
bool ascending = true;
if (fromPage == 0 && toPage == 0) {
@@ -1835,39 +1817,27 @@ void QTextDocument::print(QPrinter *printer) const
return;
}
- if (printer->pageOrder() == QPrinter::LastPageFirst) {
- int tmp = fromPage;
- fromPage = toPage;
- toPage = tmp;
- ascending = false;
- }
-
- for (int i = 0; i < docCopies; ++i) {
+// if (printer->pageOrder() == QPrinter::LastPageFirst) {
+// int tmp = fromPage;
+// fromPage = toPage;
+// toPage = tmp;
+// ascending = false;
+// }
- int page = fromPage;
- while (true) {
- for (int j = 0; j < pageCopies; ++j) {
- if (printer->printerState() == QPrinter::Aborted
- || printer->printerState() == QPrinter::Error)
- return;
- printPage(page, &p, doc, body, pageNumberPos);
- if (j < pageCopies - 1)
- printer->newPage();
- }
+ int page = fromPage;
+ while (true) {
+ printPage(page, &p, doc, body, pageNumberPos);
- if (page == toPage)
- break;
-
- if (ascending)
- ++page;
- else
- --page;
+ if (page == toPage)
+ break;
- printer->newPage();
- }
+ if (ascending)
+ ++page;
+ else
+ --page;
- if ( i < docCopies - 1)
- printer->newPage();
+ if (!printer->newPage())
+ return;
}
}
#endif
@@ -1971,6 +1941,8 @@ QVariant QTextDocument::loadResource(int type, const QUrl &name)
if (doc) {
r = doc->loadResource(type, name);
}
+#if 0
+ // ### Qt5: reenable
#ifndef QT_NO_TEXTEDIT
else if (QTextEdit *edit = qobject_cast<QTextEdit *>(parent())) {
QUrl resolvedName = edit->d_func()->resolveUrl(name);
@@ -1978,10 +1950,11 @@ QVariant QTextDocument::loadResource(int type, const QUrl &name)
}
#endif
#ifndef QT_NO_TEXTCONTROL
- else if (QTextControl *control = qobject_cast<QTextControl *>(parent())) {
+ else if (QWidgetTextControl *control = qobject_cast<QWidgetTextControl *>(parent())) {
r = control->loadResource(type, name);
}
#endif
+#endif
// handle data: URLs
if (r.isNull() && name.scheme().compare(QLatin1String("data"), Qt::CaseInsensitive) == 0)
diff --git a/src/gui/text/qtextdocument.h b/src/gui/text/qtextdocument.h
index 268b72e514..363d7abb21 100644
--- a/src/gui/text/qtextdocument.h
+++ b/src/gui/text/qtextdocument.h
@@ -57,7 +57,7 @@ class QTextFormatCollection;
class QTextListFormat;
class QRect;
class QPainter;
-class QPrinter;
+class QPagedPaintDevice;
class QAbstractTextDocumentLayout;
class QPoint;
class QTextObject;
@@ -206,9 +206,7 @@ public:
bool isModified() const;
-#ifndef QT_NO_PRINTER
- void print(QPrinter *printer) const;
-#endif
+ void print(QPagedPaintDevice *printer) const;
enum ResourceType {
HtmlResource = 1,
diff --git a/src/gui/text/qtextdocumentlayout.cpp b/src/gui/text/qtextdocumentlayout.cpp
index a50798834a..04bdfa8d30 100644
--- a/src/gui/text/qtextdocumentlayout.cpp
+++ b/src/gui/text/qtextdocumentlayout.cpp
@@ -46,6 +46,7 @@
#include "qtextlist.h"
#include "qtextengine_p.h"
#include "private/qcssutil_p.h"
+#include "private/qguiapplication_p.h"
#include "qabstracttextdocumentlayout_p.h"
#include "qcssparser_p.h"
@@ -57,7 +58,6 @@
#include <qdebug.h>
#include <qvarlengtharray.h>
#include <limits.h>
-#include <qstyle.h>
#include <qbasictimer.h>
#include "private/qfunctions_p.h"
@@ -2572,7 +2572,7 @@ void QTextDocumentLayoutPrivate::layoutBlock(const QTextBlock &bl, int blockPosi
Qt::Alignment align = docPrivate->defaultTextOption.alignment();
if (blockFormat.hasProperty(QTextFormat::BlockAlignment))
align = blockFormat.alignment();
- option.setAlignment(QStyle::visualAlignment(dir, align)); // for paragraph that are RTL, alignment is auto-reversed;
+ option.setAlignment(QGuiApplicationPrivate::visualAlignment(dir, align)); // for paragraph that are RTL, alignment is auto-reversed;
if (blockFormat.nonBreakableLines() || document->pageSize().width() < 0) {
option.setWrapMode(QTextOption::ManualWrap);
diff --git a/src/gui/text/qtextdocumentlayout_p.h b/src/gui/text/qtextdocumentlayout_p.h
index 620b9bd7dd..b103d886be 100644
--- a/src/gui/text/qtextdocumentlayout_p.h
+++ b/src/gui/text/qtextdocumentlayout_p.h
@@ -63,7 +63,7 @@ class QTextListFormat;
class QTextDocumentLayoutPrivate;
-class Q_AUTOTEST_EXPORT QTextDocumentLayout : public QAbstractTextDocumentLayout
+class Q_GUI_EXPORT QTextDocumentLayout : public QAbstractTextDocumentLayout
{
Q_DECLARE_PRIVATE(QTextDocumentLayout)
Q_OBJECT
diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
index 7539ea7d2d..97d5a3baaf 100644
--- a/src/gui/text/qtextengine.cpp
+++ b/src/gui/text/qtextengine.cpp
@@ -53,7 +53,7 @@
#include "qstring.h"
#include <private/qunicodetables_p.h>
#include "qtextdocument_p.h"
-#include <qapplication.h>
+#include <qguiapplication.h>
#include <stdlib.h>
@@ -968,7 +968,7 @@ void QTextEngine::shapeText(int item) const
}
for (int i = 0; i < si.num_glyphs; ++i)
- si.width += glyphs.advances_x[i];
+ si.width += glyphs.advances_x[i] * !glyphs.attributes[i].dontPrint;
}
static inline bool hasCaseChange(const QScriptItem &si)
@@ -1628,7 +1628,7 @@ bool QTextEngine::isRightToLeft() const
itemize();
// this places the cursor in the right position depending on the keyboard layout
if (layoutData->string.isEmpty())
- return QApplication::keyboardInputDirection() == Qt::RightToLeft;
+ return QGuiApplication::keyboardInputDirection() == Qt::RightToLeft;
return layoutData->string.isRightToLeft();
}
@@ -2663,7 +2663,7 @@ void QTextEngine::splitItem(int item, int pos) const
QFixed w = 0;
const QGlyphLayout g = shapedGlyphs(&oldItem);
for(int j = 0; j < breakGlyph; ++j)
- w += g.advances_x[j];
+ w += g.advances_x[j] * !g.attributes[j].dontPrint;
newItem.width = oldItem.width - w;
oldItem.width = w;
diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h
index 6e82de8f5c..325623fc63 100644
--- a/src/gui/text/qtextengine_p.h
+++ b/src/gui/text/qtextengine_p.h
@@ -93,7 +93,7 @@ class QAbstractTextDocumentLayout;
// * negative yoff means the following stuff is drawn higher up.
// the characters bounding rect is given by QRect(x,y,width,height), its advance by
// xoo and yoff
-struct glyph_metrics_t
+struct Q_GUI_EXPORT glyph_metrics_t
{
inline glyph_metrics_t()
: x(100000), y(100000) {}
@@ -426,7 +426,7 @@ public:
InLayout,
LayoutFailed,
};
- struct LayoutData {
+ struct Q_GUI_EXPORT LayoutData {
LayoutData(const QString &str, void **stack_memory, int mem_size);
LayoutData();
~LayoutData();
@@ -650,7 +650,7 @@ private:
int getClusterLength(unsigned short *logClusters, const HB_CharAttributes *attributes, int from, int to, int glyph_pos, int *start);
};
-class QStackTextEngine : public QTextEngine {
+class Q_GUI_EXPORT QStackTextEngine : public QTextEngine {
public:
enum { MemSize = 256*40/sizeof(void *) };
QStackTextEngine(const QString &string, const QFont &f);
diff --git a/src/gui/text/qtexthtmlparser.cpp b/src/gui/text/qtexthtmlparser.cpp
index d130c61445..ced71f5c60 100644
--- a/src/gui/text/qtexthtmlparser.cpp
+++ b/src/gui/text/qtexthtmlparser.cpp
@@ -43,10 +43,10 @@
#include <qbytearray.h>
#include <qtextcodec.h>
-#include <qapplication.h>
#include <qstack.h>
#include <qdebug.h>
#include <qthread.h>
+#include <qcoreapplication.h>
#include "qtextdocument.h"
#include "qtextformat_p.h"
@@ -1051,7 +1051,7 @@ void QTextHtmlParserNode::initializeProperties(const QTextHtmlParserNode *parent
&& !attributes.at(i + 1).isEmpty()) {
hasHref = true;
charFormat.setUnderlineStyle(QTextCharFormat::SingleUnderline);
- charFormat.setForeground(QApplication::palette().link());
+ charFormat.setForeground(Qt::blue); // ### Qt5: QApplication::palette().link());
}
}
@@ -1402,7 +1402,7 @@ void QTextHtmlParserNode::applyBackgroundImage(const QString &url, const QTextDo
if (!url.isEmpty() && resourceProvider) {
QVariant val = resourceProvider->resource(QTextDocument::ImageResource, url);
- if (qApp->thread() != QThread::currentThread()) {
+ if (QCoreApplication::instance()->thread() != QThread::currentThread()) {
// must use images in non-GUI threads
if (val.type() == QVariant::Image) {
QImage image = qvariant_cast<QImage>(val);
diff --git a/src/gui/text/qtextimagehandler.cpp b/src/gui/text/qtextimagehandler.cpp
index 78761184df..fcc13a58ff 100644
--- a/src/gui/text/qtextimagehandler.cpp
+++ b/src/gui/text/qtextimagehandler.cpp
@@ -42,13 +42,12 @@
#include "qtextimagehandler_p.h"
-#include <qapplication.h>
+#include <qcoreapplication.h>
#include <qtextformat.h>
#include <qpainter.h>
#include <qdebug.h>
#include <private/qtextengine_p.h>
#include <qpalette.h>
-#include <qtextbrowser.h>
#include <qthread.h>
QT_BEGIN_NAMESPACE
@@ -73,7 +72,8 @@ static QPixmap getPixmap(QTextDocument *doc, const QTextImageFormat &format)
if (pm.isNull()) {
QString context;
-#ifndef QT_NO_TEXTBROWSER
+#if 0
+ // ### Qt5
QTextBrowser *browser = qobject_cast<QTextBrowser *>(doc->parent());
if (browser)
context = browser->source().toString();
@@ -150,7 +150,9 @@ static QImage getImage(QTextDocument *doc, const QTextImageFormat &format)
if (image.isNull()) {
QString context;
-#ifndef QT_NO_TEXTBROWSER
+
+#if 0
+ // ### Qt5
QTextBrowser *browser = qobject_cast<QTextBrowser *>(doc->parent());
if (browser)
context = browser->source().toString();
@@ -210,7 +212,7 @@ QSizeF QTextImageHandler::intrinsicSize(QTextDocument *doc, int posInDocument, c
Q_UNUSED(posInDocument)
const QTextImageFormat imageFormat = format.toImageFormat();
- if (qApp->thread() != QThread::currentThread())
+ if (QCoreApplication::instance()->thread() != QThread::currentThread())
return getImageSize(doc, imageFormat);
return getPixmapSize(doc, imageFormat);
}
@@ -220,7 +222,7 @@ void QTextImageHandler::drawObject(QPainter *p, const QRectF &rect, QTextDocumen
Q_UNUSED(posInDocument)
const QTextImageFormat imageFormat = format.toImageFormat();
- if (qApp->thread() != QThread::currentThread()) {
+ if (QCoreApplication::instance()->thread() != QThread::currentThread()) {
const QImage image = getImage(doc, imageFormat);
p->drawImage(rect, image, image.rect());
} else {
diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp
index d253c02052..5539acffd7 100644
--- a/src/gui/text/qtextlayout.cpp
+++ b/src/gui/text/qtextlayout.cpp
@@ -44,14 +44,12 @@
#include <qthread.h>
#include <qfont.h>
-#include <qapplication.h>
#include <qpainter.h>
#include <qvarlengtharray.h>
#include <qtextformat.h>
#include <qabstracttextdocumentlayout.h>
#include "qtextdocument_p.h"
#include "qtextformat_p.h"
-#include "qstyleoption.h"
#include "qpainterpath.h"
#include "qglyphrun.h"
#include "qglyphrun_p.h"
diff --git a/src/gui/text/qtextoption.cpp b/src/gui/text/qtextoption.cpp
index d384cbeaee..fe58583d04 100644
--- a/src/gui/text/qtextoption.cpp
+++ b/src/gui/text/qtextoption.cpp
@@ -40,7 +40,7 @@
****************************************************************************/
#include "qtextoption.h"
-#include "qapplication.h"
+#include "qguiapplication.h"
#include "qlist.h"
QT_BEGIN_NAMESPACE
@@ -82,7 +82,7 @@ QTextOption::QTextOption(Qt::Alignment alignment)
tab(-1),
d(0)
{
- direction = QApplication::layoutDirection();
+ direction = QGuiApplication::layoutDirection();
}
/*!
diff --git a/src/gui/text/text.pri b/src/gui/text/text.pri
index eb5937a493..5e5f8e31c8 100644
--- a/src/gui/text/text.pri
+++ b/src/gui/text/text.pri
@@ -9,9 +9,8 @@ HEADERS += \
text/qfontmetrics.h \
text/qfont_p.h \
text/qfontsubset_p.h \
- text/qtextcontrol_p.h \
- text/qtextcontrol_p_p.h \
- text/qtextengine_p.h \
+ text/qlinecontrol_p.h \
+ text/qtextengine_p.h \
text/qtextlayout.h \
text/qtextformat.h \
text/qtextformat_p.h \
@@ -24,7 +23,9 @@ HEADERS += \
text/qtexthtmlparser_p.h \
text/qabstracttextdocumentlayout.h \
text/qtextdocumentlayout_p.h \
- text/qtextcursor.h \
+ text/qtextcontrol_p.h \
+ text/qtextcontrol_p_p.h \
+ text/qtextcursor.h \
text/qtextcursor_p.h \
text/qtextdocumentfragment.h \
text/qtextdocumentfragment_p.h \
@@ -52,8 +53,9 @@ SOURCES += \
text/qfontsubset.cpp \
text/qfontmetrics.cpp \
text/qfontdatabase.cpp \
- text/qtextcontrol.cpp \
- text/qtextengine.cpp \
+ text/qlinecontrol.cpp \
+ text/qtextcontrol.cpp \
+ text/qtextengine.cpp \
text/qtextlayout.cpp \
text/qtextformat.cpp \
text/qtextobject.cpp \
@@ -78,7 +80,7 @@ SOURCES += \
text/qrawfont.cpp \
text/qglyphrun.cpp
-win32 {
+win32:!qpa {
SOURCES += \
text/qfont_win.cpp \
text/qfontengine_win.cpp \
@@ -104,7 +106,7 @@ unix:x11 {
text/qrawfont_ft.cpp
}
-!embedded:!qpa:!x11:mac {
+!qpa:!x11:mac {
HEADERS += \
text/qfontengine_mac_p.h
OBJECTIVE_HEADERS += \
@@ -120,22 +122,6 @@ unix:x11 {
}
}
-embedded {
- SOURCES += \
- text/qfont_qws.cpp \
- text/qfontengine_qws.cpp \
- text/qfontengine_ft.cpp \
- text/qfontengine_qpf.cpp \
- text/qabstractfontengine_qws.cpp \
- text/qrawfont_ft.cpp
- HEADERS += \
- text/qfontengine_ft_p.h \
- text/qfontengine_qpf_p.h \
- text/qabstractfontengine_qws.h \
- text/qabstractfontengine_p.h
- DEFINES += QT_NO_FONTCONFIG
-}
-
qpa {
SOURCES += \
text/qfont_qpa.cpp \
@@ -233,9 +219,7 @@ contains(QT_CONFIG, freetype) {
DEFINES += FT2_BUILD_LIBRARY FT_CONFIG_OPTION_SYSTEM_ZLIB
- embedded:CONFIG += opentype
} else:contains(QT_CONFIG, system-freetype) {
- embedded:CONFIG += opentype
# pull in the proper freetype2 include directory
include($$QT_SOURCE_TREE/config.tests/unix/freetype/freetype.pri)
LIBS_PRIVATE += -lfreetype
diff --git a/src/gui/util/qcompleter.cpp b/src/gui/util/qcompleter.cpp
deleted file mode 100644
index 07bfac729d..0000000000
--- a/src/gui/util/qcompleter.cpp
+++ /dev/null
@@ -1,1833 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*!
- \class QCompleter
- \brief The QCompleter class provides completions based on an item model.
- \since 4.2
-
- You can use QCompleter to provide auto completions in any Qt
- widget, such as QLineEdit and QComboBox.
- When the user starts typing a word, QCompleter suggests possible ways of
- completing the word, based on a word list. The word list is
- provided as a QAbstractItemModel. (For simple applications, where
- the word list is static, you can pass a QStringList to
- QCompleter's constructor.)
-
- \tableofcontents
-
- \section1 Basic Usage
-
- A QCompleter is used typically with a QLineEdit or QComboBox.
- For example, here's how to provide auto completions from a simple
- word list in a QLineEdit:
-
- \snippet doc/src/snippets/code/src_gui_util_qcompleter.cpp 0
-
- A QFileSystemModel can be used to provide auto completion of file names.
- For example:
-
- \snippet doc/src/snippets/code/src_gui_util_qcompleter.cpp 1
-
- To set the model on which QCompleter should operate, call
- setModel(). By default, QCompleter will attempt to match the \l
- {completionPrefix}{completion prefix} (i.e., the word that the
- user has started typing) against the Qt::EditRole data stored in
- column 0 in the model case sensitively. This can be changed
- using setCompletionRole(), setCompletionColumn(), and
- setCaseSensitivity().
-
- If the model is sorted on the column and role that are used for completion,
- you can call setModelSorting() with either
- QCompleter::CaseSensitivelySortedModel or
- QCompleter::CaseInsensitivelySortedModel as the argument. On large models,
- this can lead to significant performance improvements, because QCompleter
- can then use binary search instead of linear search.
-
- The model can be a \l{QAbstractListModel}{list model},
- a \l{QAbstractTableModel}{table model}, or a
- \l{QAbstractItemModel}{tree model}. Completion on tree models
- is slightly more involved and is covered in the \l{Handling
- Tree Models} section below.
-
- The completionMode() determines the mode used to provide completions to
- the user.
-
- \section1 Iterating Through Completions
-
- To retrieve a single candidate string, call setCompletionPrefix()
- with the text that needs to be completed and call
- currentCompletion(). You can iterate through the list of
- completions as below:
-
- \snippet doc/src/snippets/code/src_gui_util_qcompleter.cpp 2
-
- completionCount() returns the total number of completions for the
- current prefix. completionCount() should be avoided when possible,
- since it requires a scan of the entire model.
-
- \section1 The Completion Model
-
- completionModel() return a list model that contains all possible
- completions for the current completion prefix, in the order in which
- they appear in the model. This model can be used to display the current
- completions in a custom view. Calling setCompletionPrefix() automatically
- refreshes the completion model.
-
- \section1 Handling Tree Models
-
- QCompleter can look for completions in tree models, assuming
- that any item (or sub-item or sub-sub-item) can be unambiguously
- represented as a string by specifying the path to the item. The
- completion is then performed one level at a time.
-
- Let's take the example of a user typing in a file system path.
- The model is a (hierarchical) QFileSystemModel. The completion
- occurs for every element in the path. For example, if the current
- text is \c C:\Wind, QCompleter might suggest \c Windows to
- complete the current path element. Similarly, if the current text
- is \c C:\Windows\Sy, QCompleter might suggest \c System.
-
- For this kind of completion to work, QCompleter needs to be able to
- split the path into a list of strings that are matched at each level.
- For \c C:\Windows\Sy, it needs to be split as "C:", "Windows" and "Sy".
- The default implementation of splitPath(), splits the completionPrefix
- using QDir::separator() if the model is a QFileSystemModel.
-
- To provide completions, QCompleter needs to know the path from an index.
- This is provided by pathFromIndex(). The default implementation of
- pathFromIndex(), returns the data for the \l{Qt::EditRole}{edit role}
- for list models and the absolute file path if the mode is a QFileSystemModel.
-
- \sa QAbstractItemModel, QLineEdit, QComboBox, {Completer Example}
-*/
-
-#include "qcompleter_p.h"
-
-#ifndef QT_NO_COMPLETER
-
-#include "QtGui/qscrollbar.h"
-#include "QtGui/qstringlistmodel.h"
-#include "QtGui/qdirmodel.h"
-#include "QtGui/qfilesystemmodel.h"
-#include "QtGui/qheaderview.h"
-#include "QtGui/qlistview.h"
-#include "QtGui/qapplication.h"
-#include "QtGui/qevent.h"
-#include "QtGui/qheaderview.h"
-#include "QtGui/qdesktopwidget.h"
-#include "QtGui/qlineedit.h"
-
-QT_BEGIN_NAMESPACE
-
-QCompletionModel::QCompletionModel(QCompleterPrivate *c, QObject *parent)
- : QAbstractProxyModel(*new QCompletionModelPrivate, parent),
- c(c), showAll(false)
-{
- createEngine();
-}
-
-int QCompletionModel::columnCount(const QModelIndex &) const
-{
- Q_D(const QCompletionModel);
- return d->model->columnCount();
-}
-
-void QCompletionModel::setSourceModel(QAbstractItemModel *source)
-{
- bool hadModel = (sourceModel() != 0);
-
- if (hadModel)
- QObject::disconnect(sourceModel(), 0, this, 0);
-
- QAbstractProxyModel::setSourceModel(source);
-
- if (source) {
- // TODO: Optimize updates in the source model
- connect(source, SIGNAL(modelReset()), this, SLOT(invalidate()));
- connect(source, SIGNAL(destroyed()), this, SLOT(modelDestroyed()));
- connect(source, SIGNAL(layoutChanged()), this, SLOT(invalidate()));
- connect(source, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(rowsInserted()));
- connect(source, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(invalidate()));
- connect(source, SIGNAL(columnsInserted(QModelIndex,int,int)), this, SLOT(invalidate()));
- connect(source, SIGNAL(columnsRemoved(QModelIndex,int,int)), this, SLOT(invalidate()));
- connect(source, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(invalidate()));
- }
-
- invalidate();
-}
-
-void QCompletionModel::createEngine()
-{
- bool sortedEngine = false;
- switch (c->sorting) {
- case QCompleter::UnsortedModel:
- sortedEngine = false;
- break;
- case QCompleter::CaseSensitivelySortedModel:
- sortedEngine = c->cs == Qt::CaseSensitive;
- break;
- case QCompleter::CaseInsensitivelySortedModel:
- sortedEngine = c->cs == Qt::CaseInsensitive;
- break;
- }
-
- if (sortedEngine)
- engine.reset(new QSortedModelEngine(c));
- else
- engine.reset(new QUnsortedModelEngine(c));
-}
-
-QModelIndex QCompletionModel::mapToSource(const QModelIndex& index) const
-{
- Q_D(const QCompletionModel);
- if (!index.isValid())
- return engine->curParent;
-
- int row;
- QModelIndex parent = engine->curParent;
- if (!showAll) {
- if (!engine->matchCount())
- return QModelIndex();
- Q_ASSERT(index.row() < engine->matchCount());
- QIndexMapper& rootIndices = engine->historyMatch.indices;
- if (index.row() < rootIndices.count()) {
- row = rootIndices[index.row()];
- parent = QModelIndex();
- } else {
- row = engine->curMatch.indices[index.row() - rootIndices.count()];
- }
- } else {
- row = index.row();
- }
-
- return d->model->index(row, index.column(), parent);
-}
-
-QModelIndex QCompletionModel::mapFromSource(const QModelIndex& idx) const
-{
- if (!idx.isValid())
- return QModelIndex();
-
- int row = -1;
- if (!showAll) {
- if (!engine->matchCount())
- return QModelIndex();
-
- QIndexMapper& rootIndices = engine->historyMatch.indices;
- if (idx.parent().isValid()) {
- if (idx.parent() != engine->curParent)
- return QModelIndex();
- } else {
- row = rootIndices.indexOf(idx.row());
- if (row == -1 && engine->curParent.isValid())
- return QModelIndex(); // source parent and our parent don't match
- }
-
- if (row == -1) {
- QIndexMapper& indices = engine->curMatch.indices;
- engine->filterOnDemand(idx.row() - indices.last());
- row = indices.indexOf(idx.row()) + rootIndices.count();
- }
-
- if (row == -1)
- return QModelIndex();
- } else {
- if (idx.parent() != engine->curParent)
- return QModelIndex();
- row = idx.row();
- }
-
- return createIndex(row, idx.column());
-}
-
-bool QCompletionModel::setCurrentRow(int row)
-{
- if (row < 0 || !engine->matchCount())
- return false;
-
- if (row >= engine->matchCount())
- engine->filterOnDemand(row + 1 - engine->matchCount());
-
- if (row >= engine->matchCount()) // invalid row
- return false;
-
- engine->curRow = row;
- return true;
-}
-
-QModelIndex QCompletionModel::currentIndex(bool sourceIndex) const
-{
- if (!engine->matchCount())
- return QModelIndex();
-
- int row = engine->curRow;
- if (showAll)
- row = engine->curMatch.indices[engine->curRow];
-
- QModelIndex idx = createIndex(row, c->column);
- if (!sourceIndex)
- return idx;
- return mapToSource(idx);
-}
-
-QModelIndex QCompletionModel::index(int row, int column, const QModelIndex& parent) const
-{
- Q_D(const QCompletionModel);
- if (row < 0 || column < 0 || column >= columnCount(parent) || parent.isValid())
- return QModelIndex();
-
- if (!showAll) {
- if (!engine->matchCount())
- return QModelIndex();
- if (row >= engine->historyMatch.indices.count()) {
- int want = row + 1 - engine->matchCount();
- if (want > 0)
- engine->filterOnDemand(want);
- if (row >= engine->matchCount())
- return QModelIndex();
- }
- } else {
- if (row >= d->model->rowCount(engine->curParent))
- return QModelIndex();
- }
-
- return createIndex(row, column);
-}
-
-int QCompletionModel::completionCount() const
-{
- if (!engine->matchCount())
- return 0;
-
- engine->filterOnDemand(INT_MAX);
- return engine->matchCount();
-}
-
-int QCompletionModel::rowCount(const QModelIndex &parent) const
-{
- Q_D(const QCompletionModel);
- if (parent.isValid())
- return 0;
-
- if (showAll) {
- // Show all items below current parent, even if we have no valid matches
- if (engine->curParts.count() != 1 && !engine->matchCount()
- && !engine->curParent.isValid())
- return 0;
- return d->model->rowCount(engine->curParent);
- }
-
- return completionCount();
-}
-
-void QCompletionModel::setFiltered(bool filtered)
-{
- if (showAll == !filtered)
- return;
- showAll = !filtered;
- resetModel();
-}
-
-bool QCompletionModel::hasChildren(const QModelIndex &parent) const
-{
- Q_D(const QCompletionModel);
- if (parent.isValid())
- return false;
-
- if (showAll)
- return d->model->hasChildren(mapToSource(parent));
-
- if (!engine->matchCount())
- return false;
-
- return true;
-}
-
-QVariant QCompletionModel::data(const QModelIndex& index, int role) const
-{
- Q_D(const QCompletionModel);
- return d->model->data(mapToSource(index), role);
-}
-
-void QCompletionModel::modelDestroyed()
-{
- QAbstractProxyModel::setSourceModel(0); // switch to static empty model
- invalidate();
-}
-
-void QCompletionModel::rowsInserted()
-{
- invalidate();
- emit rowsAdded();
-}
-
-void QCompletionModel::invalidate()
-{
- engine->cache.clear();
- filter(engine->curParts);
-}
-
-void QCompletionModel::filter(const QStringList& parts)
-{
- Q_D(QCompletionModel);
- engine->filter(parts);
- resetModel();
-
- if (d->model->canFetchMore(engine->curParent))
- d->model->fetchMore(engine->curParent);
-}
-
-void QCompletionModel::resetModel()
-{
- if (rowCount() == 0) {
- reset();
- return;
- }
-
- emit layoutAboutToBeChanged();
- QModelIndexList piList = persistentIndexList();
- QModelIndexList empty;
- for (int i = 0; i < piList.size(); i++)
- empty.append(QModelIndex());
- changePersistentIndexList(piList, empty);
- emit layoutChanged();
-}
-
-//////////////////////////////////////////////////////////////////////////////
-void QCompletionEngine::filter(const QStringList& parts)
-{
- const QAbstractItemModel *model = c->proxy->sourceModel();
- curParts = parts;
- if (curParts.isEmpty())
- curParts.append(QString());
-
- curRow = -1;
- curParent = QModelIndex();
- curMatch = QMatchData();
- historyMatch = filterHistory();
-
- if (!model)
- return;
-
- QModelIndex parent;
- for (int i = 0; i < curParts.count() - 1; i++) {
- QString part = curParts[i];
- int emi = filter(part, parent, -1).exactMatchIndex;
- if (emi == -1)
- return;
- parent = model->index(emi, c->column, parent);
- }
-
- // Note that we set the curParent to a valid parent, even if we have no matches
- // When filtering is disabled, we show all the items under this parent
- curParent = parent;
- if (curParts.last().isEmpty())
- curMatch = QMatchData(QIndexMapper(0, model->rowCount(curParent) - 1), -1, false);
- else
- curMatch = filter(curParts.last(), curParent, 1); // build at least one
- curRow = curMatch.isValid() ? 0 : -1;
-}
-
-QMatchData QCompletionEngine::filterHistory()
-{
- QAbstractItemModel *source = c->proxy->sourceModel();
- if (curParts.count() <= 1 || c->proxy->showAll || !source)
- return QMatchData();
- bool isDirModel = false;
- bool isFsModel = false;
-#ifndef QT_NO_DIRMODEL
- isDirModel = (qobject_cast<QDirModel *>(source) != 0);
-#endif
-#ifndef QT_NO_FILESYSTEMMODEL
- isFsModel = (qobject_cast<QFileSystemModel *>(source) != 0);
-#endif
- QVector<int> v;
- QIndexMapper im(v);
- QMatchData m(im, -1, true);
-
- for (int i = 0; i < source->rowCount(); i++) {
- QString str = source->index(i, c->column).data().toString();
- if (str.startsWith(c->prefix, c->cs)
-#if (!defined(Q_OS_WIN) || defined(Q_OS_WINCE)) && !defined(Q_OS_SYMBIAN)
- && ((!isFsModel && !isDirModel) || QDir::toNativeSeparators(str) != QDir::separator())
-#endif
- )
- m.indices.append(i);
- }
- return m;
-}
-
-// Returns a match hint from the cache by chopping the search string
-bool QCompletionEngine::matchHint(QString part, const QModelIndex& parent, QMatchData *hint)
-{
- if (c->cs == Qt::CaseInsensitive)
- part = part.toLower();
-
- const CacheItem& map = cache[parent];
-
- QString key = part;
- while (!key.isEmpty()) {
- key.chop(1);
- if (map.contains(key)) {
- *hint = map[key];
- return true;
- }
- }
-
- return false;
-}
-
-bool QCompletionEngine::lookupCache(QString part, const QModelIndex& parent, QMatchData *m)
-{
- if (c->cs == Qt::CaseInsensitive)
- part = part.toLower();
- const CacheItem& map = cache[parent];
- if (!map.contains(part))
- return false;
- *m = map[part];
- return true;
-}
-
-// When the cache size exceeds 1MB, it clears out about 1/2 of the cache.
-void QCompletionEngine::saveInCache(QString part, const QModelIndex& parent, const QMatchData& m)
-{
- QMatchData old = cache[parent].take(part);
- cost = cost + m.indices.cost() - old.indices.cost();
- if (cost * sizeof(int) > 1024 * 1024) {
- QMap<QModelIndex, CacheItem>::iterator it1 = cache.begin();
- while (it1 != cache.end()) {
- CacheItem& ci = it1.value();
- int sz = ci.count()/2;
- QMap<QString, QMatchData>::iterator it2 = ci.begin();
- int i = 0;
- while (it2 != ci.end() && i < sz) {
- cost -= it2.value().indices.cost();
- it2 = ci.erase(it2);
- i++;
- }
- if (ci.count() == 0) {
- it1 = cache.erase(it1);
- } else {
- ++it1;
- }
- }
- }
-
- if (c->cs == Qt::CaseInsensitive)
- part = part.toLower();
- cache[parent][part] = m;
-}
-
-///////////////////////////////////////////////////////////////////////////////////
-QIndexMapper QSortedModelEngine::indexHint(QString part, const QModelIndex& parent, Qt::SortOrder order)
-{
- const QAbstractItemModel *model = c->proxy->sourceModel();
-
- if (c->cs == Qt::CaseInsensitive)
- part = part.toLower();
-
- const CacheItem& map = cache[parent];
-
- // Try to find a lower and upper bound for the search from previous results
- int to = model->rowCount(parent) - 1;
- int from = 0;
- const CacheItem::const_iterator it = map.lowerBound(part);
-
- // look backward for first valid hint
- for(CacheItem::const_iterator it1 = it; it1-- != map.constBegin();) {
- const QMatchData& value = it1.value();
- if (value.isValid()) {
- if (order == Qt::AscendingOrder) {
- from = value.indices.last() + 1;
- } else {
- to = value.indices.first() - 1;
- }
- break;
- }
- }
-
- // look forward for first valid hint
- for(CacheItem::const_iterator it2 = it; it2 != map.constEnd(); ++it2) {
- const QMatchData& value = it2.value();
- if (value.isValid() && !it2.key().startsWith(part)) {
- if (order == Qt::AscendingOrder) {
- to = value.indices.first() - 1;
- } else {
- from = value.indices.first() + 1;
- }
- break;
- }
- }
-
- return QIndexMapper(from, to);
-}
-
-Qt::SortOrder QSortedModelEngine::sortOrder(const QModelIndex &parent) const
-{
- const QAbstractItemModel *model = c->proxy->sourceModel();
-
- int rowCount = model->rowCount(parent);
- if (rowCount < 2)
- return Qt::AscendingOrder;
- QString first = model->data(model->index(0, c->column, parent), c->role).toString();
- QString last = model->data(model->index(rowCount - 1, c->column, parent), c->role).toString();
- return QString::compare(first, last, c->cs) <= 0 ? Qt::AscendingOrder : Qt::DescendingOrder;
-}
-
-QMatchData QSortedModelEngine::filter(const QString& part, const QModelIndex& parent, int)
-{
- const QAbstractItemModel *model = c->proxy->sourceModel();
-
- QMatchData hint;
- if (lookupCache(part, parent, &hint))
- return hint;
-
- QIndexMapper indices;
- Qt::SortOrder order = sortOrder(parent);
-
- if (matchHint(part, parent, &hint)) {
- if (!hint.isValid())
- return QMatchData();
- indices = hint.indices;
- } else {
- indices = indexHint(part, parent, order);
- }
-
- // binary search the model within 'indices' for 'part' under 'parent'
- int high = indices.to() + 1;
- int low = indices.from() - 1;
- int probe;
- QModelIndex probeIndex;
- QString probeData;
-
- while (high - low > 1)
- {
- probe = (high + low) / 2;
- probeIndex = model->index(probe, c->column, parent);
- probeData = model->data(probeIndex, c->role).toString();
- const int cmp = QString::compare(probeData, part, c->cs);
- if ((order == Qt::AscendingOrder && cmp >= 0)
- || (order == Qt::DescendingOrder && cmp < 0)) {
- high = probe;
- } else {
- low = probe;
- }
- }
-
- if ((order == Qt::AscendingOrder && low == indices.to())
- || (order == Qt::DescendingOrder && high == indices.from())) { // not found
- saveInCache(part, parent, QMatchData());
- return QMatchData();
- }
-
- probeIndex = model->index(order == Qt::AscendingOrder ? low+1 : high-1, c->column, parent);
- probeData = model->data(probeIndex, c->role).toString();
- if (!probeData.startsWith(part, c->cs)) {
- saveInCache(part, parent, QMatchData());
- return QMatchData();
- }
-
- const bool exactMatch = QString::compare(probeData, part, c->cs) == 0;
- int emi = exactMatch ? (order == Qt::AscendingOrder ? low+1 : high-1) : -1;
-
- int from = 0;
- int to = 0;
- if (order == Qt::AscendingOrder) {
- from = low + 1;
- high = indices.to() + 1;
- low = from;
- } else {
- to = high - 1;
- low = indices.from() - 1;
- high = to;
- }
-
- while (high - low > 1)
- {
- probe = (high + low) / 2;
- probeIndex = model->index(probe, c->column, parent);
- probeData = model->data(probeIndex, c->role).toString();
- const bool startsWith = probeData.startsWith(part, c->cs);
- if ((order == Qt::AscendingOrder && startsWith)
- || (order == Qt::DescendingOrder && !startsWith)) {
- low = probe;
- } else {
- high = probe;
- }
- }
-
- QMatchData m(order == Qt::AscendingOrder ? QIndexMapper(from, high - 1) : QIndexMapper(low+1, to), emi, false);
- saveInCache(part, parent, m);
- return m;
-}
-
-////////////////////////////////////////////////////////////////////////////////////////
-int QUnsortedModelEngine::buildIndices(const QString& str, const QModelIndex& parent, int n,
- const QIndexMapper& indices, QMatchData* m)
-{
- Q_ASSERT(m->partial);
- Q_ASSERT(n != -1 || m->exactMatchIndex == -1);
- const QAbstractItemModel *model = c->proxy->sourceModel();
- int i, count = 0;
-
- for (i = 0; i < indices.count() && count != n; ++i) {
- QModelIndex idx = model->index(indices[i], c->column, parent);
- QString data = model->data(idx, c->role).toString();
- if (!data.startsWith(str, c->cs) || !(model->flags(idx) & Qt::ItemIsSelectable))
- continue;
- m->indices.append(indices[i]);
- ++count;
- if (m->exactMatchIndex == -1 && QString::compare(data, str, c->cs) == 0) {
- m->exactMatchIndex = indices[i];
- if (n == -1)
- return indices[i];
- }
- }
- return indices[i-1];
-}
-
-void QUnsortedModelEngine::filterOnDemand(int n)
-{
- Q_ASSERT(matchCount());
- if (!curMatch.partial)
- return;
- Q_ASSERT(n >= -1);
- const QAbstractItemModel *model = c->proxy->sourceModel();
- int lastRow = model->rowCount(curParent) - 1;
- QIndexMapper im(curMatch.indices.last() + 1, lastRow);
- int lastIndex = buildIndices(curParts.last(), curParent, n, im, &curMatch);
- curMatch.partial = (lastRow != lastIndex);
- saveInCache(curParts.last(), curParent, curMatch);
-}
-
-QMatchData QUnsortedModelEngine::filter(const QString& part, const QModelIndex& parent, int n)
-{
- QMatchData hint;
-
- QVector<int> v;
- QIndexMapper im(v);
- QMatchData m(im, -1, true);
-
- const QAbstractItemModel *model = c->proxy->sourceModel();
- bool foundInCache = lookupCache(part, parent, &m);
-
- if (!foundInCache) {
- if (matchHint(part, parent, &hint) && !hint.isValid())
- return QMatchData();
- }
-
- if (!foundInCache && !hint.isValid()) {
- const int lastRow = model->rowCount(parent) - 1;
- QIndexMapper all(0, lastRow);
- int lastIndex = buildIndices(part, parent, n, all, &m);
- m.partial = (lastIndex != lastRow);
- } else {
- if (!foundInCache) { // build from hint as much as we can
- buildIndices(part, parent, INT_MAX, hint.indices, &m);
- m.partial = hint.partial;
- }
- if (m.partial && ((n == -1 && m.exactMatchIndex == -1) || (m.indices.count() < n))) {
- // need more and have more
- const int lastRow = model->rowCount(parent) - 1;
- QIndexMapper rest(hint.indices.last() + 1, lastRow);
- int want = n == -1 ? -1 : n - m.indices.count();
- int lastIndex = buildIndices(part, parent, want, rest, &m);
- m.partial = (lastRow != lastIndex);
- }
- }
-
- saveInCache(part, parent, m);
- return m;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-QCompleterPrivate::QCompleterPrivate()
-: widget(0), proxy(0), popup(0), cs(Qt::CaseSensitive), role(Qt::EditRole), column(0),
- maxVisibleItems(7), sorting(QCompleter::UnsortedModel), wrap(true), eatFocusOut(true),
- hiddenBecauseNoMatch(false)
-{
-}
-
-void QCompleterPrivate::init(QAbstractItemModel *m)
-{
- Q_Q(QCompleter);
- proxy = new QCompletionModel(this, q);
- QObject::connect(proxy, SIGNAL(rowsAdded()), q, SLOT(_q_autoResizePopup()));
- q->setModel(m);
-#ifdef QT_NO_LISTVIEW
- q->setCompletionMode(QCompleter::InlineCompletion);
-#else
- q->setCompletionMode(QCompleter::PopupCompletion);
-#endif // QT_NO_LISTVIEW
-}
-
-void QCompleterPrivate::setCurrentIndex(QModelIndex index, bool select)
-{
- Q_Q(QCompleter);
- if (!q->popup())
- return;
- if (!select) {
- popup->selectionModel()->setCurrentIndex(index, QItemSelectionModel::NoUpdate);
- } else {
- if (!index.isValid())
- popup->selectionModel()->clear();
- else
- popup->selectionModel()->setCurrentIndex(index, QItemSelectionModel::Select
- | QItemSelectionModel::Rows);
- }
- index = popup->selectionModel()->currentIndex();
- if (!index.isValid())
- popup->scrollToTop();
- else
- popup->scrollTo(index, QAbstractItemView::PositionAtTop);
-}
-
-void QCompleterPrivate::_q_completionSelected(const QItemSelection& selection)
-{
- QModelIndex index;
- if (!selection.indexes().isEmpty())
- index = selection.indexes().first();
-
- _q_complete(index, true);
-}
-
-void QCompleterPrivate::_q_complete(QModelIndex index, bool highlighted)
-{
- Q_Q(QCompleter);
- QString completion;
-
- if (!index.isValid() || (!proxy->showAll && (index.row() >= proxy->engine->matchCount()))) {
- completion = prefix;
- } else {
- if (!(index.flags() & Qt::ItemIsEnabled))
- return;
- QModelIndex si = proxy->mapToSource(index);
- si = si.sibling(si.row(), column); // for clicked()
- completion = q->pathFromIndex(si);
-#ifndef QT_NO_DIRMODEL
- // add a trailing separator in inline
- if (mode == QCompleter::InlineCompletion) {
- if (qobject_cast<QDirModel *>(proxy->sourceModel()) && QFileInfo(completion).isDir())
- completion += QDir::separator();
- }
-#endif
-#ifndef QT_NO_FILESYSTEMMODEL
- // add a trailing separator in inline
- if (mode == QCompleter::InlineCompletion) {
- if (qobject_cast<QFileSystemModel *>(proxy->sourceModel()) && QFileInfo(completion).isDir())
- completion += QDir::separator();
- }
-#endif
- }
-
- if (highlighted) {
- emit q->highlighted(index);
- emit q->highlighted(completion);
- } else {
- emit q->activated(index);
- emit q->activated(completion);
- }
-}
-
-void QCompleterPrivate::_q_autoResizePopup()
-{
- if (!popup || !popup->isVisible())
- return;
- showPopup(popupRect);
-}
-
-void QCompleterPrivate::showPopup(const QRect& rect)
-{
- const QRect screen = QApplication::desktop()->availableGeometry(widget);
- Qt::LayoutDirection dir = widget->layoutDirection();
- QPoint pos;
- int rh, w;
- int h = (popup->sizeHintForRow(0) * qMin(maxVisibleItems, popup->model()->rowCount()) + 3) + 3;
- QScrollBar *hsb = popup->horizontalScrollBar();
- if (hsb && hsb->isVisible())
- h += popup->horizontalScrollBar()->sizeHint().height();
-
- if (rect.isValid()) {
- rh = rect.height();
- w = rect.width();
- pos = widget->mapToGlobal(dir == Qt::RightToLeft ? rect.bottomRight() : rect.bottomLeft());
- } else {
- rh = widget->height();
- pos = widget->mapToGlobal(QPoint(0, widget->height() - 2));
- w = widget->width();
- }
-
- if (w > screen.width())
- w = screen.width();
- if ((pos.x() + w) > (screen.x() + screen.width()))
- pos.setX(screen.x() + screen.width() - w);
- if (pos.x() < screen.x())
- pos.setX(screen.x());
-
- int top = pos.y() - rh - screen.top() + 2;
- int bottom = screen.bottom() - pos.y();
- h = qMax(h, popup->minimumHeight());
- if (h > bottom) {
- h = qMin(qMax(top, bottom), h);
-
- if (top > bottom)
- pos.setY(pos.y() - h - rh + 2);
- }
-
- popup->setGeometry(pos.x(), pos.y(), w, h);
-
- if (!popup->isVisible())
- popup->show();
-}
-
-void QCompleterPrivate::_q_fileSystemModelDirectoryLoaded(const QString &path)
-{
- Q_Q(QCompleter);
- // Slot called when QFileSystemModel has finished loading.
- // If we hide the popup because there was no match because the model was not loaded yet,
- // we re-start the completion when we get the results
- if (hiddenBecauseNoMatch
- && prefix.startsWith(path) && prefix != (path + QLatin1Char('/'))
- && widget) {
- q->complete();
- }
-}
-
-/*!
- Constructs a completer object with the given \a parent.
-*/
-QCompleter::QCompleter(QObject *parent)
-: QObject(*new QCompleterPrivate(), parent)
-{
- Q_D(QCompleter);
- d->init();
-}
-
-/*!
- Constructs a completer object with the given \a parent that provides completions
- from the specified \a model.
-*/
-QCompleter::QCompleter(QAbstractItemModel *model, QObject *parent)
- : QObject(*new QCompleterPrivate(), parent)
-{
- Q_D(QCompleter);
- d->init(model);
-}
-
-#ifndef QT_NO_STRINGLISTMODEL
-/*!
- Constructs a QCompleter object with the given \a parent that uses the specified
- \a list as a source of possible completions.
-*/
-QCompleter::QCompleter(const QStringList& list, QObject *parent)
-: QObject(*new QCompleterPrivate(), parent)
-{
- Q_D(QCompleter);
- d->init(new QStringListModel(list, this));
-}
-#endif // QT_NO_STRINGLISTMODEL
-
-/*!
- Destroys the completer object.
-*/
-QCompleter::~QCompleter()
-{
-}
-
-/*!
- Sets the widget for which completion are provided for to \a widget. This
- function is automatically called when a QCompleter is set on a QLineEdit
- using QLineEdit::setCompleter() or on a QComboBox using
- QComboBox::setCompleter(). The widget needs to be set explicitly when
- providing completions for custom widgets.
-
- \sa widget(), setModel(), setPopup()
- */
-void QCompleter::setWidget(QWidget *widget)
-{
- Q_D(QCompleter);
- if (d->widget)
- d->widget->removeEventFilter(this);
- d->widget = widget;
- if (d->widget)
- d->widget->installEventFilter(this);
- if (d->popup) {
- d->popup->hide();
- d->popup->setFocusProxy(d->widget);
- }
-}
-
-/*!
- Returns the widget for which the completer object is providing completions.
-
- \sa setWidget()
- */
-QWidget *QCompleter::widget() const
-{
- Q_D(const QCompleter);
- return d->widget;
-}
-
-/*!
- Sets the model which provides completions to \a model. The \a model can
- be list model or a tree model. If a model has been already previously set
- and it has the QCompleter as its parent, it is deleted.
-
- For convenience, if \a model is a QFileSystemModel, QCompleter switches its
- caseSensitivity to Qt::CaseInsensitive on Windows and Qt::CaseSensitive
- on other platforms.
-
- \sa completionModel(), modelSorting, {Handling Tree Models}
-*/
-void QCompleter::setModel(QAbstractItemModel *model)
-{
- Q_D(QCompleter);
- QAbstractItemModel *oldModel = d->proxy->sourceModel();
- d->proxy->setSourceModel(model);
- if (d->popup)
- setPopup(d->popup); // set the model and make new connections
- if (oldModel && oldModel->QObject::parent() == this)
- delete oldModel;
-#ifndef QT_NO_DIRMODEL
- if (qobject_cast<QDirModel *>(model)) {
-#if (defined(Q_OS_WIN) && !defined(Q_OS_WINCE)) || defined(Q_OS_SYMBIAN)
- setCaseSensitivity(Qt::CaseInsensitive);
-#else
- setCaseSensitivity(Qt::CaseSensitive);
-#endif
- }
-#endif // QT_NO_DIRMODEL
-#ifndef QT_NO_FILESYSTEMMODEL
- QFileSystemModel *fsModel = qobject_cast<QFileSystemModel *>(model);
- if (fsModel) {
-#if (defined(Q_OS_WIN) && !defined(Q_OS_WINCE)) || defined(Q_OS_SYMBIAN)
- setCaseSensitivity(Qt::CaseInsensitive);
-#else
- setCaseSensitivity(Qt::CaseSensitive);
-#endif
- setCompletionRole(QFileSystemModel::FileNameRole);
- connect(fsModel, SIGNAL(directoryLoaded(QString)), this, SLOT(_q_fileSystemModelDirectoryLoaded(QString)));
- }
-#endif // QT_NO_FILESYSTEMMODEL
-}
-
-/*!
- Returns the model that provides completion strings.
-
- \sa completionModel()
-*/
-QAbstractItemModel *QCompleter::model() const
-{
- Q_D(const QCompleter);
- return d->proxy->sourceModel();
-}
-
-/*!
- \enum QCompleter::CompletionMode
-
- This enum specifies how completions are provided to the user.
-
- \value PopupCompletion Current completions are displayed in a popup window.
- \value InlineCompletion Completions appear inline (as selected text).
- \value UnfilteredPopupCompletion All possible completions are displayed in a popup window with the most likely suggestion indicated as current.
-
- \sa setCompletionMode()
-*/
-
-/*!
- \property QCompleter::completionMode
- \brief how the completions are provided to the user
-
- The default value is QCompleter::PopupCompletion.
-*/
-void QCompleter::setCompletionMode(QCompleter::CompletionMode mode)
-{
- Q_D(QCompleter);
- d->mode = mode;
- d->proxy->setFiltered(mode != QCompleter::UnfilteredPopupCompletion);
-
- if (mode == QCompleter::InlineCompletion) {
- if (d->widget)
- d->widget->removeEventFilter(this);
- if (d->popup) {
- d->popup->deleteLater();
- d->popup = 0;
- }
- } else {
- if (d->widget)
- d->widget->installEventFilter(this);
- }
-}
-
-QCompleter::CompletionMode QCompleter::completionMode() const
-{
- Q_D(const QCompleter);
- return d->mode;
-}
-
-/*!
- Sets the popup used to display completions to \a popup. QCompleter takes
- ownership of the view.
-
- A QListView is automatically created when the completionMode() is set to
- QCompleter::PopupCompletion or QCompleter::UnfilteredPopupCompletion. The
- default popup displays the completionColumn().
-
- Ensure that this function is called before the view settings are modified.
- This is required since view's properties may require that a model has been
- set on the view (for example, hiding columns in the view requires a model
- to be set on the view).
-
- \sa popup()
-*/
-void QCompleter::setPopup(QAbstractItemView *popup)
-{
- Q_D(QCompleter);
- Q_ASSERT(popup != 0);
- if (d->popup) {
- QObject::disconnect(d->popup->selectionModel(), 0, this, 0);
- QObject::disconnect(d->popup, 0, this, 0);
- }
- if (d->popup != popup)
- delete d->popup;
- if (popup->model() != d->proxy)
- popup->setModel(d->proxy);
-#if defined(Q_OS_MAC) && !defined(QT_MAC_USE_COCOA)
- popup->show();
-#else
- popup->hide();
-#endif
-
- Qt::FocusPolicy origPolicy = Qt::NoFocus;
- if (d->widget)
- origPolicy = d->widget->focusPolicy();
- popup->setParent(0, Qt::Popup);
- popup->setFocusPolicy(Qt::NoFocus);
- if (d->widget)
- d->widget->setFocusPolicy(origPolicy);
-
- popup->setFocusProxy(d->widget);
- popup->installEventFilter(this);
- popup->setItemDelegate(new QCompleterItemDelegate(popup));
-#ifndef QT_NO_LISTVIEW
- if (QListView *listView = qobject_cast<QListView *>(popup)) {
- listView->setModelColumn(d->column);
- }
-#endif
-
- QObject::connect(popup, SIGNAL(clicked(QModelIndex)),
- this, SLOT(_q_complete(QModelIndex)));
- QObject::connect(this, SIGNAL(activated(QModelIndex)),
- popup, SLOT(hide()));
-
- QObject::connect(popup->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
- this, SLOT(_q_completionSelected(QItemSelection)));
- d->popup = popup;
-}
-
-/*!
- Returns the popup used to display completions.
-
- \sa setPopup()
-*/
-QAbstractItemView *QCompleter::popup() const
-{
- Q_D(const QCompleter);
-#ifndef QT_NO_LISTVIEW
- if (!d->popup && completionMode() != QCompleter::InlineCompletion) {
- QListView *listView = new QListView;
- listView->setEditTriggers(QAbstractItemView::NoEditTriggers);
- listView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
- listView->setSelectionBehavior(QAbstractItemView::SelectRows);
- listView->setSelectionMode(QAbstractItemView::SingleSelection);
- listView->setModelColumn(d->column);
- QCompleter *that = const_cast<QCompleter*>(this);
- that->setPopup(listView);
- }
-#endif // QT_NO_LISTVIEW
- return d->popup;
-}
-
-/*!
- \reimp
-*/
-bool QCompleter::event(QEvent *ev)
-{
- return QObject::event(ev);
-}
-
-/*!
- \reimp
-*/
-bool QCompleter::eventFilter(QObject *o, QEvent *e)
-{
- Q_D(QCompleter);
-
- if (d->eatFocusOut && o == d->widget && e->type() == QEvent::FocusOut) {
- d->hiddenBecauseNoMatch = false;
- if (d->popup && d->popup->isVisible())
- return true;
- }
-
- if (o != d->popup)
- return QObject::eventFilter(o, e);
-
- switch (e->type()) {
- case QEvent::KeyPress: {
- QKeyEvent *ke = static_cast<QKeyEvent *>(e);
-
- QModelIndex curIndex = d->popup->currentIndex();
- QModelIndexList selList = d->popup->selectionModel()->selectedIndexes();
-
- const int key = ke->key();
- // In UnFilteredPopup mode, select the current item
- if ((key == Qt::Key_Up || key == Qt::Key_Down) && selList.isEmpty() && curIndex.isValid()
- && d->mode == QCompleter::UnfilteredPopupCompletion) {
- d->setCurrentIndex(curIndex);
- return true;
- }
-
- // Handle popup navigation keys. These are hardcoded because up/down might make the
- // widget do something else (lineedit cursor moves to home/end on mac, for instance)
- switch (key) {
- case Qt::Key_End:
- case Qt::Key_Home:
- if (ke->modifiers() & Qt::ControlModifier)
- return false;
- break;
-
- case Qt::Key_Up:
- if (!curIndex.isValid()) {
- int rowCount = d->proxy->rowCount();
- QModelIndex lastIndex = d->proxy->index(rowCount - 1, d->column);
- d->setCurrentIndex(lastIndex);
- return true;
- } else if (curIndex.row() == 0) {
- if (d->wrap)
- d->setCurrentIndex(QModelIndex());
- return true;
- }
- return false;
-
- case Qt::Key_Down:
- if (!curIndex.isValid()) {
- QModelIndex firstIndex = d->proxy->index(0, d->column);
- d->setCurrentIndex(firstIndex);
- return true;
- } else if (curIndex.row() == d->proxy->rowCount() - 1) {
- if (d->wrap)
- d->setCurrentIndex(QModelIndex());
- return true;
- }
- return false;
-
- case Qt::Key_PageUp:
- case Qt::Key_PageDown:
- return false;
- }
-
- // Send the event to the widget. If the widget accepted the event, do nothing
- // If the widget did not accept the event, provide a default implementation
- d->eatFocusOut = false;
- (static_cast<QObject *>(d->widget))->event(ke);
- d->eatFocusOut = true;
- if (!d->widget || e->isAccepted() || !d->popup->isVisible()) {
- // widget lost focus, hide the popup
- if (d->widget && (!d->widget->hasFocus()
-#ifdef QT_KEYPAD_NAVIGATION
- || (QApplication::keypadNavigationEnabled() && !d->widget->hasEditFocus())
-#endif
- ))
- d->popup->hide();
- if (e->isAccepted())
- return true;
- }
-
- // default implementation for keys not handled by the widget when popup is open
- switch (key) {
-#ifdef QT_KEYPAD_NAVIGATION
- case Qt::Key_Select:
- if (!QApplication::keypadNavigationEnabled())
- break;
-#endif
- case Qt::Key_Return:
- case Qt::Key_Enter:
- case Qt::Key_Tab:
- d->popup->hide();
- if (curIndex.isValid())
- d->_q_complete(curIndex);
- break;
-
- case Qt::Key_F4:
- if (ke->modifiers() & Qt::AltModifier)
- d->popup->hide();
- break;
-
- case Qt::Key_Backtab:
- case Qt::Key_Escape:
- d->popup->hide();
- break;
-
- default:
- break;
- }
-
- return true;
- }
-
-#ifdef QT_KEYPAD_NAVIGATION
- case QEvent::KeyRelease: {
- QKeyEvent *ke = static_cast<QKeyEvent *>(e);
- if (QApplication::keypadNavigationEnabled() && ke->key() == Qt::Key_Back) {
- // Send the event to the 'widget'. This is what we did for KeyPress, so we need
- // to do the same for KeyRelease, in case the widget's KeyPress event set
- // up something (such as a timer) that is relying on also receiving the
- // key release. I see this as a bug in Qt, and should really set it up for all
- // the affected keys. However, it is difficult to tell how this will affect
- // existing code, and I can't test for every combination!
- d->eatFocusOut = false;
- static_cast<QObject *>(d->widget)->event(ke);
- d->eatFocusOut = true;
- }
- break;
- }
-#endif
-
- case QEvent::MouseButtonPress: {
-#ifdef QT_KEYPAD_NAVIGATION
- if (QApplication::keypadNavigationEnabled()) {
- // if we've clicked in the widget (or its descendant), let it handle the click
- QWidget *source = qobject_cast<QWidget *>(o);
- if (source) {
- QPoint pos = source->mapToGlobal((static_cast<QMouseEvent *>(e))->pos());
- QWidget *target = QApplication::widgetAt(pos);
- if (target && (d->widget->isAncestorOf(target) ||
- target == d->widget)) {
- d->eatFocusOut = false;
- static_cast<QObject *>(target)->event(e);
- d->eatFocusOut = true;
- return true;
- }
- }
- }
-#endif
- if (!d->popup->underMouse()) {
- d->popup->hide();
- return true;
- }
- }
- return false;
-
- case QEvent::InputMethod:
- case QEvent::ShortcutOverride:
- QApplication::sendEvent(d->widget, e);
- break;
-
- default:
- return false;
- }
- return false;
-}
-
-/*!
- For QCompleter::PopupCompletion and QCompletion::UnfilteredPopupCompletion
- modes, calling this function displays the popup displaying the current
- completions. By default, if \a rect is not specified, the popup is displayed
- on the bottom of the widget(). If \a rect is specified the popup is
- displayed on the left edge of the rectangle.
-
- For QCompleter::InlineCompletion mode, the highlighted() signal is fired
- with the current completion.
-*/
-void QCompleter::complete(const QRect& rect)
-{
- Q_D(QCompleter);
- QModelIndex idx = d->proxy->currentIndex(false);
- d->hiddenBecauseNoMatch = false;
- if (d->mode == QCompleter::InlineCompletion) {
- if (idx.isValid())
- d->_q_complete(idx, true);
- return;
- }
-
- Q_ASSERT(d->widget != 0);
- if ((d->mode == QCompleter::PopupCompletion && !idx.isValid())
- || (d->mode == QCompleter::UnfilteredPopupCompletion && d->proxy->rowCount() == 0)) {
- if (d->popup)
- d->popup->hide(); // no suggestion, hide
- d->hiddenBecauseNoMatch = true;
- return;
- }
-
- popup();
- if (d->mode == QCompleter::UnfilteredPopupCompletion)
- d->setCurrentIndex(idx, false);
-
- d->showPopup(rect);
- d->popupRect = rect;
-}
-
-/*!
- Sets the current row to the \a row specified. Returns true if successful;
- otherwise returns false.
-
- This function may be used along with currentCompletion() to iterate
- through all the possible completions.
-
- \sa currentCompletion(), completionCount()
-*/
-bool QCompleter::setCurrentRow(int row)
-{
- Q_D(QCompleter);
- return d->proxy->setCurrentRow(row);
-}
-
-/*!
- Returns the current row.
-
- \sa setCurrentRow()
-*/
-int QCompleter::currentRow() const
-{
- Q_D(const QCompleter);
- return d->proxy->currentRow();
-}
-
-/*!
- Returns the number of completions for the current prefix. For an unsorted
- model with a large number of items this can be expensive. Use setCurrentRow()
- and currentCompletion() to iterate through all the completions.
-*/
-int QCompleter::completionCount() const
-{
- Q_D(const QCompleter);
- return d->proxy->completionCount();
-}
-
-/*!
- \enum QCompleter::ModelSorting
-
- This enum specifies how the items in the model are sorted.
-
- \value UnsortedModel The model is unsorted.
- \value CaseSensitivelySortedModel The model is sorted case sensitively.
- \value CaseInsensitivelySortedModel The model is sorted case insensitively.
-
- \sa setModelSorting()
-*/
-
-/*!
- \property QCompleter::modelSorting
- \brief the way the model is sorted
-
- By default, no assumptions are made about the order of the items
- in the model that provides the completions.
-
- If the model's data for the completionColumn() and completionRole() is sorted in
- ascending order, you can set this property to \l CaseSensitivelySortedModel
- or \l CaseInsensitivelySortedModel. On large models, this can lead to
- significant performance improvements because the completer object can
- then use a binary search algorithm instead of linear search algorithm.
-
- The sort order (i.e ascending or descending order) of the model is determined
- dynamically by inspecting the contents of the model.
-
- \bold{Note:} The performance improvements described above cannot take place
- when the completer's \l caseSensitivity is different to the case sensitivity
- used by the model's when sorting.
-
- \sa setCaseSensitivity(), QCompleter::ModelSorting
-*/
-void QCompleter::setModelSorting(QCompleter::ModelSorting sorting)
-{
- Q_D(QCompleter);
- if (d->sorting == sorting)
- return;
- d->sorting = sorting;
- d->proxy->createEngine();
- d->proxy->invalidate();
-}
-
-QCompleter::ModelSorting QCompleter::modelSorting() const
-{
- Q_D(const QCompleter);
- return d->sorting;
-}
-
-/*!
- \property QCompleter::completionColumn
- \brief the column in the model in which completions are searched for.
-
- If the popup() is a QListView, it is automatically setup to display
- this column.
-
- By default, the match column is 0.
-
- \sa completionRole, caseSensitivity
-*/
-void QCompleter::setCompletionColumn(int column)
-{
- Q_D(QCompleter);
- if (d->column == column)
- return;
-#ifndef QT_NO_LISTVIEW
- if (QListView *listView = qobject_cast<QListView *>(d->popup))
- listView->setModelColumn(column);
-#endif
- d->column = column;
- d->proxy->invalidate();
-}
-
-int QCompleter::completionColumn() const
-{
- Q_D(const QCompleter);
- return d->column;
-}
-
-/*!
- \property QCompleter::completionRole
- \brief the item role to be used to query the contents of items for matching.
-
- The default role is Qt::EditRole.
-
- \sa completionColumn, caseSensitivity
-*/
-void QCompleter::setCompletionRole(int role)
-{
- Q_D(QCompleter);
- if (d->role == role)
- return;
- d->role = role;
- d->proxy->invalidate();
-}
-
-int QCompleter::completionRole() const
-{
- Q_D(const QCompleter);
- return d->role;
-}
-
-/*!
- \property QCompleter::wrapAround
- \brief the completions wrap around when navigating through items
- \since 4.3
-
- The default is true.
-*/
-void QCompleter::setWrapAround(bool wrap)
-{
- Q_D(QCompleter);
- if (d->wrap == wrap)
- return;
- d->wrap = wrap;
-}
-
-bool QCompleter::wrapAround() const
-{
- Q_D(const QCompleter);
- return d->wrap;
-}
-
-/*!
- \property QCompleter::maxVisibleItems
- \brief the maximum allowed size on screen of the completer, measured in items
- \since 4.6
-
- By default, this property has a value of 7.
-*/
-int QCompleter::maxVisibleItems() const
-{
- Q_D(const QCompleter);
- return d->maxVisibleItems;
-}
-
-void QCompleter::setMaxVisibleItems(int maxItems)
-{
- Q_D(QCompleter);
- if (maxItems < 0) {
- qWarning("QCompleter::setMaxVisibleItems: "
- "Invalid max visible items (%d) must be >= 0", maxItems);
- return;
- }
- d->maxVisibleItems = maxItems;
-}
-
-/*!
- \property QCompleter::caseSensitivity
- \brief the case sensitivity of the matching
-
- The default is Qt::CaseSensitive.
-
- \sa completionColumn, completionRole, modelSorting
-*/
-void QCompleter::setCaseSensitivity(Qt::CaseSensitivity cs)
-{
- Q_D(QCompleter);
- if (d->cs == cs)
- return;
- d->cs = cs;
- d->proxy->createEngine();
- d->proxy->invalidate();
-}
-
-Qt::CaseSensitivity QCompleter::caseSensitivity() const
-{
- Q_D(const QCompleter);
- return d->cs;
-}
-
-/*!
- \property QCompleter::completionPrefix
- \brief the completion prefix used to provide completions.
-
- The completionModel() is updated to reflect the list of possible
- matches for \a prefix.
-*/
-void QCompleter::setCompletionPrefix(const QString &prefix)
-{
- Q_D(QCompleter);
- d->prefix = prefix;
- d->proxy->filter(splitPath(prefix));
-}
-
-QString QCompleter::completionPrefix() const
-{
- Q_D(const QCompleter);
- return d->prefix;
-}
-
-/*!
- Returns the model index of the current completion in the completionModel().
-
- \sa setCurrentRow(), currentCompletion(), model()
-*/
-QModelIndex QCompleter::currentIndex() const
-{
- Q_D(const QCompleter);
- return d->proxy->currentIndex(false);
-}
-
-/*!
- Returns the current completion string. This includes the \l completionPrefix.
- When used alongside setCurrentRow(), it can be used to iterate through
- all the matches.
-
- \sa setCurrentRow(), currentIndex()
-*/
-QString QCompleter::currentCompletion() const
-{
- Q_D(const QCompleter);
- return pathFromIndex(d->proxy->currentIndex(true));
-}
-
-/*!
- Returns the completion model. The completion model is a read-only list model
- that contains all the possible matches for the current completion prefix.
- The completion model is auto-updated to reflect the current completions.
-
- \note The return value of this function is defined to be an QAbstractItemModel
- purely for generality. This actual kind of model returned is an instance of an
- QAbstractProxyModel subclass.
-
- \sa completionPrefix, model()
-*/
-QAbstractItemModel *QCompleter::completionModel() const
-{
- Q_D(const QCompleter);
- return d->proxy;
-}
-
-/*!
- Returns the path for the given \a index. The completer object uses this to
- obtain the completion text from the underlying model.
-
- The default implementation returns the \l{Qt::EditRole}{edit role} of the
- item for list models. It returns the absolute file path if the model is a
- QFileSystemModel.
-
- \sa splitPath()
-*/
-
-QString QCompleter::pathFromIndex(const QModelIndex& index) const
-{
- Q_D(const QCompleter);
- if (!index.isValid())
- return QString();
-
- QAbstractItemModel *sourceModel = d->proxy->sourceModel();
- if (!sourceModel)
- return QString();
- bool isDirModel = false;
- bool isFsModel = false;
-#ifndef QT_NO_DIRMODEL
- isDirModel = qobject_cast<QDirModel *>(d->proxy->sourceModel()) != 0;
-#endif
-#ifndef QT_NO_FILESYSTEMMODEL
- isFsModel = qobject_cast<QFileSystemModel *>(d->proxy->sourceModel()) != 0;
-#endif
- if (!isDirModel && !isFsModel)
- return sourceModel->data(index, d->role).toString();
-
- QModelIndex idx = index;
- QStringList list;
- do {
- QString t;
- if (isDirModel)
- t = sourceModel->data(idx, Qt::EditRole).toString();
-#ifndef QT_NO_FILESYSTEMMODEL
- else
- t = sourceModel->data(idx, QFileSystemModel::FileNameRole).toString();
-#endif
- list.prepend(t);
- QModelIndex parent = idx.parent();
- idx = parent.sibling(parent.row(), index.column());
- } while (idx.isValid());
-
-#if (!defined(Q_OS_WIN) || defined(Q_OS_WINCE)) && !defined(Q_OS_SYMBIAN)
- if (list.count() == 1) // only the separator or some other text
- return list[0];
- list[0].clear() ; // the join below will provide the separator
-#endif
-
- return list.join(QDir::separator());
-}
-
-/*!
- Splits the given \a path into strings that are used to match at each level
- in the model().
-
- The default implementation of splitPath() splits a file system path based on
- QDir::separator() when the sourceModel() is a QFileSystemModel.
-
- When used with list models, the first item in the returned list is used for
- matching.
-
- \sa pathFromIndex(), {Handling Tree Models}
-*/
-QStringList QCompleter::splitPath(const QString& path) const
-{
- bool isDirModel = false;
- bool isFsModel = false;
-#ifndef QT_NO_DIRMODEL
- Q_D(const QCompleter);
- isDirModel = qobject_cast<QDirModel *>(d->proxy->sourceModel()) != 0;
-#endif
-#ifndef QT_NO_FILESYSTEMMODEL
-#ifdef QT_NO_DIRMODEL
- Q_D(const QCompleter);
-#endif
- isFsModel = qobject_cast<QFileSystemModel *>(d->proxy->sourceModel()) != 0;
-#endif
-
- if ((!isDirModel && !isFsModel) || path.isEmpty())
- return QStringList(completionPrefix());
-
- QString pathCopy = QDir::toNativeSeparators(path);
- QString sep = QDir::separator();
-#if defined(Q_OS_SYMBIAN)
- if (pathCopy == QLatin1String("\\"))
- return QStringList(pathCopy);
-#elif defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
- if (pathCopy == QLatin1String("\\") || pathCopy == QLatin1String("\\\\"))
- return QStringList(pathCopy);
- QString doubleSlash(QLatin1String("\\\\"));
- if (pathCopy.startsWith(doubleSlash))
- pathCopy = pathCopy.mid(2);
- else
- doubleSlash.clear();
-#endif
-
- QRegExp re(QLatin1Char('[') + QRegExp::escape(sep) + QLatin1Char(']'));
- QStringList parts = pathCopy.split(re);
-
-#if defined(Q_OS_SYMBIAN)
- // Do nothing
-#elif defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
- if (!doubleSlash.isEmpty())
- parts[0].prepend(doubleSlash);
-#else
- if (pathCopy[0] == sep[0]) // readd the "/" at the beginning as the split removed it
- parts[0] = QDir::fromNativeSeparators(QString(sep[0]));
-#endif
-
- return parts;
-}
-
-/*!
- \fn void QCompleter::activated(const QModelIndex& index)
-
- This signal is sent when an item in the popup() is activated by the user.
- (by clicking or pressing return). The item's \a index in the completionModel()
- is given.
-
-*/
-
-/*!
- \fn void QCompleter::activated(const QString &text)
-
- This signal is sent when an item in the popup() is activated by the user (by
- clicking or pressing return). The item's \a text is given.
-
-*/
-
-/*!
- \fn void QCompleter::highlighted(const QModelIndex& index)
-
- This signal is sent when an item in the popup() is highlighted by
- the user. It is also sent if complete() is called with the completionMode()
- set to QCompleter::InlineCompletion. The item's \a index in the completionModel()
- is given.
-*/
-
-/*!
- \fn void QCompleter::highlighted(const QString &text)
-
- This signal is sent when an item in the popup() is highlighted by
- the user. It is also sent if complete() is called with the completionMode()
- set to QCompleter::InlineCompletion. The item's \a text is given.
-*/
-
-QT_END_NAMESPACE
-
-#include "moc_qcompleter.cpp"
-
-#endif // QT_NO_COMPLETER
diff --git a/src/gui/util/qcompleter.h b/src/gui/util/qcompleter.h
deleted file mode 100644
index 61797ee645..0000000000
--- a/src/gui/util/qcompleter.h
+++ /dev/null
@@ -1,171 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QCOMPLETER_H
-#define QCOMPLETER_H
-
-#include <QtCore/qobject.h>
-#include <QtCore/qpoint.h>
-#include <QtCore/qstring.h>
-#include <QtCore/qabstractitemmodel.h>
-#include <QtCore/qrect.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_COMPLETER
-
-class QCompleterPrivate;
-class QAbstractItemView;
-class QAbstractProxyModel;
-class QWidget;
-
-class Q_GUI_EXPORT QCompleter : public QObject
-{
- Q_OBJECT
- Q_PROPERTY(QString completionPrefix READ completionPrefix WRITE setCompletionPrefix)
- Q_PROPERTY(ModelSorting modelSorting READ modelSorting WRITE setModelSorting)
- Q_PROPERTY(CompletionMode completionMode READ completionMode WRITE setCompletionMode)
- Q_PROPERTY(int completionColumn READ completionColumn WRITE setCompletionColumn)
- Q_PROPERTY(int completionRole READ completionRole WRITE setCompletionRole)
- Q_PROPERTY(int maxVisibleItems READ maxVisibleItems WRITE setMaxVisibleItems)
- Q_PROPERTY(Qt::CaseSensitivity caseSensitivity READ caseSensitivity WRITE setCaseSensitivity)
- Q_PROPERTY(bool wrapAround READ wrapAround WRITE setWrapAround)
-
-public:
- enum CompletionMode {
- PopupCompletion,
- UnfilteredPopupCompletion,
- InlineCompletion
- };
-
- enum ModelSorting {
- UnsortedModel = 0,
- CaseSensitivelySortedModel,
- CaseInsensitivelySortedModel
- };
-
- QCompleter(QObject *parent = 0);
- QCompleter(QAbstractItemModel *model, QObject *parent = 0);
-#ifndef QT_NO_STRINGLISTMODEL
- QCompleter(const QStringList& completions, QObject *parent = 0);
-#endif
- ~QCompleter();
-
- void setWidget(QWidget *widget);
- QWidget *widget() const;
-
- void setModel(QAbstractItemModel *c);
- QAbstractItemModel *model() const;
-
- void setCompletionMode(CompletionMode mode);
- CompletionMode completionMode() const;
-
- QAbstractItemView *popup() const;
- void setPopup(QAbstractItemView *popup);
-
- void setCaseSensitivity(Qt::CaseSensitivity caseSensitivity);
- Qt::CaseSensitivity caseSensitivity() const;
-
- void setModelSorting(ModelSorting sorting);
- ModelSorting modelSorting() const;
-
- void setCompletionColumn(int column);
- int completionColumn() const;
-
- void setCompletionRole(int role);
- int completionRole() const;
-
- bool wrapAround() const;
-
- int maxVisibleItems() const;
- void setMaxVisibleItems(int maxItems);
-
- int completionCount() const;
- bool setCurrentRow(int row);
- int currentRow() const;
-
- QModelIndex currentIndex() const;
- QString currentCompletion() const;
-
- QAbstractItemModel *completionModel() const;
-
- QString completionPrefix() const;
-
-public Q_SLOTS:
- void setCompletionPrefix(const QString &prefix);
- void complete(const QRect& rect = QRect());
- void setWrapAround(bool wrap);
-
-public:
- virtual QString pathFromIndex(const QModelIndex &index) const;
- virtual QStringList splitPath(const QString &path) const;
-
-protected:
- bool eventFilter(QObject *o, QEvent *e);
- bool event(QEvent *);
-
-Q_SIGNALS:
- void activated(const QString &text);
- void activated(const QModelIndex &index);
- void highlighted(const QString &text);
- void highlighted(const QModelIndex &index);
-
-private:
- Q_DISABLE_COPY(QCompleter)
- Q_DECLARE_PRIVATE(QCompleter)
-
- Q_PRIVATE_SLOT(d_func(), void _q_complete(QModelIndex))
- Q_PRIVATE_SLOT(d_func(), void _q_completionSelected(const QItemSelection&))
- Q_PRIVATE_SLOT(d_func(), void _q_autoResizePopup())
- Q_PRIVATE_SLOT(d_func(), void _q_fileSystemModelDirectoryLoaded(const QString&))
-};
-
-#endif // QT_NO_COMPLETER
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QCOMPLETER_H
diff --git a/src/gui/util/qcompleter_p.h b/src/gui/util/qcompleter_p.h
deleted file mode 100644
index e06440cb07..0000000000
--- a/src/gui/util/qcompleter_p.h
+++ /dev/null
@@ -1,264 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QCOMPLETER_P_H
-#define QCOMPLETER_P_H
-
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "private/qobject_p.h"
-
-#ifndef QT_NO_COMPLETER
-
-#include "QtGui/qtreeview.h"
-#include "QtGui/qabstractproxymodel.h"
-#include "qcompleter.h"
-#include "QtGui/qitemdelegate.h"
-#include "QtGui/qpainter.h"
-#include "private/qabstractproxymodel_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class QCompletionModel;
-
-class QCompleterPrivate : public QObjectPrivate
-{
- Q_DECLARE_PUBLIC(QCompleter)
-
-public:
- QCompleterPrivate();
- ~QCompleterPrivate() { delete popup; }
- void init(QAbstractItemModel *model = 0);
-
- QPointer<QWidget> widget;
- QCompletionModel *proxy;
- QAbstractItemView *popup;
- QCompleter::CompletionMode mode;
-
- QString prefix;
- Qt::CaseSensitivity cs;
- int role;
- int column;
- int maxVisibleItems;
- QCompleter::ModelSorting sorting;
- bool wrap;
-
- bool eatFocusOut;
- QRect popupRect;
- bool hiddenBecauseNoMatch;
-
- void showPopup(const QRect&);
- void _q_complete(QModelIndex, bool = false);
- void _q_completionSelected(const QItemSelection&);
- void _q_autoResizePopup();
- void _q_fileSystemModelDirectoryLoaded(const QString &path);
- void setCurrentIndex(QModelIndex, bool = true);
-};
-
-class QIndexMapper
-{
-public:
- QIndexMapper() : v(false), f(0), t(-1) { }
- QIndexMapper(int f, int t) : v(false), f(f), t(t) { }
- QIndexMapper(QVector<int> vec) : v(true), vector(vec), f(-1), t(-1) { }
-
- inline int count() const { return v ? vector.count() : t - f + 1; }
- inline int operator[] (int index) const { return v ? vector[index] : f + index; }
- inline int indexOf(int x) const { return v ? vector.indexOf(x) : ((t < f) ? -1 : x - f); }
- inline bool isValid() const { return !isEmpty(); }
- inline bool isEmpty() const { return v ? vector.isEmpty() : (t < f); }
- inline void append(int x) { Q_ASSERT(v); vector.append(x); }
- inline int first() const { return v ? vector.first() : f; }
- inline int last() const { return v ? vector.last() : t; }
- inline int from() const { Q_ASSERT(!v); return f; }
- inline int to() const { Q_ASSERT(!v); return t; }
- inline int cost() const { return vector.count()+2; }
-
-private:
- bool v;
- QVector<int> vector;
- int f, t;
-};
-
-struct QMatchData {
- QMatchData() : exactMatchIndex(-1) { }
- QMatchData(const QIndexMapper& indices, int em, bool p) :
- indices(indices), exactMatchIndex(em), partial(p) { }
- QIndexMapper indices;
- inline bool isValid() const { return indices.isValid(); }
- int exactMatchIndex;
- bool partial;
-};
-
-class QCompletionEngine
-{
-public:
- typedef QMap<QString, QMatchData> CacheItem;
- typedef QMap<QModelIndex, CacheItem> Cache;
-
- QCompletionEngine(QCompleterPrivate *c) : c(c), curRow(-1), cost(0) { }
- virtual ~QCompletionEngine() { }
-
- void filter(const QStringList &parts);
-
- QMatchData filterHistory();
- bool matchHint(QString, const QModelIndex&, QMatchData*);
-
- void saveInCache(QString, const QModelIndex&, const QMatchData&);
- bool lookupCache(QString part, const QModelIndex& parent, QMatchData *m);
-
- virtual void filterOnDemand(int) { }
- virtual QMatchData filter(const QString&, const QModelIndex&, int) = 0;
-
- int matchCount() const { return curMatch.indices.count() + historyMatch.indices.count(); }
-
- QMatchData curMatch, historyMatch;
- QCompleterPrivate *c;
- QStringList curParts;
- QModelIndex curParent;
- int curRow;
-
- Cache cache;
- int cost;
-};
-
-class QSortedModelEngine : public QCompletionEngine
-{
-public:
- QSortedModelEngine(QCompleterPrivate *c) : QCompletionEngine(c) { }
- QMatchData filter(const QString&, const QModelIndex&, int);
- QIndexMapper indexHint(QString, const QModelIndex&, Qt::SortOrder);
- Qt::SortOrder sortOrder(const QModelIndex&) const;
-};
-
-class QUnsortedModelEngine : public QCompletionEngine
-{
-public:
- QUnsortedModelEngine(QCompleterPrivate *c) : QCompletionEngine(c) { }
-
- void filterOnDemand(int);
- QMatchData filter(const QString&, const QModelIndex&, int);
-private:
- int buildIndices(const QString& str, const QModelIndex& parent, int n,
- const QIndexMapper& iv, QMatchData* m);
-};
-
-class QCompleterItemDelegate : public QItemDelegate
-{
-public:
- QCompleterItemDelegate(QAbstractItemView *view)
- : QItemDelegate(view), view(view) { }
- void paint(QPainter *p, const QStyleOptionViewItem& opt, const QModelIndex& idx) const {
- QStyleOptionViewItem optCopy = opt;
- optCopy.showDecorationSelected = true;
- if (view->currentIndex() == idx)
- optCopy.state |= QStyle::State_HasFocus;
- QItemDelegate::paint(p, optCopy, idx);
- }
-
-private:
- QAbstractItemView *view;
-};
-
-class QCompletionModelPrivate;
-
-class QCompletionModel : public QAbstractProxyModel
-{
- Q_OBJECT
-
-public:
- QCompletionModel(QCompleterPrivate *c, QObject *parent);
-
- void createEngine();
- void setFiltered(bool);
- void filter(const QStringList& parts);
- int completionCount() const;
- int currentRow() const { return engine->curRow; }
- bool setCurrentRow(int row);
- QModelIndex currentIndex(bool) const;
- void resetModel();
-
- QModelIndex index(int row, int column, const QModelIndex & = QModelIndex()) const;
- int rowCount(const QModelIndex &index = QModelIndex()) const;
- int columnCount(const QModelIndex &index = QModelIndex()) const;
- bool hasChildren(const QModelIndex &parent = QModelIndex()) const;
- QModelIndex parent(const QModelIndex & = QModelIndex()) const { return QModelIndex(); }
- QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
-
- void setSourceModel(QAbstractItemModel *sourceModel);
- QModelIndex mapToSource(const QModelIndex& proxyIndex) const;
- QModelIndex mapFromSource(const QModelIndex& sourceIndex) const;
-
- QCompleterPrivate *c;
- QScopedPointer<QCompletionEngine> engine;
- bool showAll;
-
- Q_DECLARE_PRIVATE(QCompletionModel)
-
-signals:
- void rowsAdded();
-
-public Q_SLOTS:
- void invalidate();
- void rowsInserted();
- void modelDestroyed();
-};
-
-class QCompletionModelPrivate : public QAbstractProxyModelPrivate
-{
- Q_DECLARE_PUBLIC(QCompletionModel)
-};
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_COMPLETER
-
-#endif // QCOMPLETER_P_H
diff --git a/src/gui/util/qdesktopservices.cpp b/src/gui/util/qdesktopservices.cpp
index e79819e69f..669f7ea893 100644
--- a/src/gui/util/qdesktopservices.cpp
+++ b/src/gui/util/qdesktopservices.cpp
@@ -46,7 +46,7 @@
#include <qdebug.h>
#if defined(Q_WS_QWS) || defined(Q_WS_QPA)
-#include "qdesktopservices_qws.cpp"
+#include "qdesktopservices_qpa.cpp"
#elif defined(Q_WS_X11)
#include "qdesktopservices_x11.cpp"
#elif defined(Q_WS_WIN)
diff --git a/src/gui/util/qdesktopservices_qpa.cpp b/src/gui/util/qdesktopservices_qpa.cpp
new file mode 100644
index 0000000000..374b06b4f0
--- /dev/null
+++ b/src/gui/util/qdesktopservices_qpa.cpp
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qcoreapplication.h>
+#include <qdir.h>
+#include <qurl.h>
+
+QT_BEGIN_NAMESPACE
+
+static bool launchWebBrowser(const QUrl &url)
+{
+ Q_UNUSED(url);
+ qWarning("QDesktopServices::launchWebBrowser not implemented");
+ return false;
+}
+
+static bool openDocument(const QUrl &file)
+{
+ Q_UNUSED(file);
+ qWarning("QDesktopServices::openDocument not implemented");
+ return false;
+}
+
+
+QString QDesktopServices::storageLocation(StandardLocation type)
+{
+ if (type == DataLocation) {
+ QString qwsDataHome = QLatin1String(qgetenv("QWS_DATA_HOME"));
+ if (qwsDataHome.isEmpty())
+ qwsDataHome = QDir::homePath() + QLatin1String("/.qws/share");
+ qwsDataHome += QLatin1String("/data/")
+ + QCoreApplication::organizationName() + QLatin1Char('/')
+ + QCoreApplication::applicationName();
+ return qwsDataHome;
+ }
+ if (type == QDesktopServices::CacheLocation) {
+ QString qwsCacheHome = QLatin1String(qgetenv("QWS_CACHE_HOME"));
+ if (qwsCacheHome.isEmpty())
+ qwsCacheHome = QDir::homePath() + QLatin1String("/.qws/cache/");
+ qwsCacheHome += QCoreApplication::organizationName() + QLatin1Char('/')
+ + QCoreApplication::applicationName();
+ return qwsCacheHome;
+ }
+
+ qWarning("QDesktopServices::storageLocation %d not implemented", type);
+ return QString();
+}
+
+QString QDesktopServices::displayName(StandardLocation type)
+{
+ Q_UNUSED(type);
+ qWarning("QDesktopServices::displayName not implemented");
+ return QString();
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/util/qdesktopservices_qws.cpp b/src/gui/util/qdesktopservices_qws.cpp
deleted file mode 100644
index e3847e5bfd..0000000000
--- a/src/gui/util/qdesktopservices_qws.cpp
+++ /dev/null
@@ -1,93 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qcoreapplication.h>
-#include <qdir.h>
-
-QT_BEGIN_NAMESPACE
-
-static bool launchWebBrowser(const QUrl &url)
-{
- Q_UNUSED(url);
- qWarning("QDesktopServices::launchWebBrowser not implemented");
- return false;
-}
-
-static bool openDocument(const QUrl &file)
-{
- Q_UNUSED(file);
- qWarning("QDesktopServices::openDocument not implemented");
- return false;
-}
-
-
-QString QDesktopServices::storageLocation(StandardLocation type)
-{
- if (type == DataLocation) {
- QString qwsDataHome = QLatin1String(qgetenv("QWS_DATA_HOME"));
- if (qwsDataHome.isEmpty())
- qwsDataHome = QDir::homePath() + QLatin1String("/.qws/share");
- qwsDataHome += QLatin1String("/data/")
- + QCoreApplication::organizationName() + QLatin1Char('/')
- + QCoreApplication::applicationName();
- return qwsDataHome;
- }
- if (type == QDesktopServices::CacheLocation) {
- QString qwsCacheHome = QLatin1String(qgetenv("QWS_CACHE_HOME"));
- if (qwsCacheHome.isEmpty())
- qwsCacheHome = QDir::homePath() + QLatin1String("/.qws/cache/");
- qwsCacheHome += QCoreApplication::organizationName() + QLatin1Char('/')
- + QCoreApplication::applicationName();
- return qwsCacheHome;
- }
-
- qWarning("QDesktopServices::storageLocation %d not implemented", type);
- return QString();
-}
-
-QString QDesktopServices::displayName(StandardLocation type)
-{
- Q_UNUSED(type);
- qWarning("QDesktopServices::displayName not implemented");
- return QString();
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/util/qflickgesture.cpp b/src/gui/util/qflickgesture.cpp
deleted file mode 100644
index 07eca6c53b..0000000000
--- a/src/gui/util/qflickgesture.cpp
+++ /dev/null
@@ -1,715 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qgesture.h"
-#include "qapplication.h"
-#include "qevent.h"
-#include "qwidget.h"
-#include "qgraphicsitem.h"
-#include "qgraphicsscene.h"
-#include "qgraphicssceneevent.h"
-#include "qgraphicsview.h"
-#include "qscroller.h"
-#include "private/qevent_p.h"
-#include "private/qflickgesture_p.h"
-#include "qdebug.h"
-
-#ifndef QT_NO_GESTURES
-
-QT_BEGIN_NAMESPACE
-
-//#define QFLICKGESTURE_DEBUG
-
-#ifdef QFLICKGESTURE_DEBUG
-# define qFGDebug qDebug
-#else
-# define qFGDebug while (false) qDebug
-#endif
-
-extern bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event);
-
-static QMouseEvent *copyMouseEvent(QEvent *e)
-{
- switch (e->type()) {
- case QEvent::MouseButtonPress:
- case QEvent::MouseButtonRelease:
- case QEvent::MouseMove: {
- QMouseEvent *me = static_cast<QMouseEvent *>(e);
- return new QMouseEvent(me->type(), QPoint(0, 0), me->globalPos(), me->button(), me->buttons(), me->modifiers());
- }
-#ifndef QT_NO_GRAPHICSVIEW
- case QEvent::GraphicsSceneMousePress:
- case QEvent::GraphicsSceneMouseRelease:
- case QEvent::GraphicsSceneMouseMove: {
- QGraphicsSceneMouseEvent *me = static_cast<QGraphicsSceneMouseEvent *>(e);
-#if 1
- QEvent::Type met = me->type() == QEvent::GraphicsSceneMousePress ? QEvent::MouseButtonPress :
- (me->type() == QEvent::GraphicsSceneMouseRelease ? QEvent::MouseButtonRelease : QEvent::MouseMove);
- return new QMouseEvent(met, QPoint(0, 0), me->screenPos(), me->button(), me->buttons(), me->modifiers());
-#else
- QGraphicsSceneMouseEvent *copy = new QGraphicsSceneMouseEvent(me->type());
- copy->setPos(me->pos());
- copy->setScenePos(me->scenePos());
- copy->setScreenPos(me->screenPos());
- for (int i = 0x1; i <= 0x10; i <<= 1) {
- Qt::MouseButton button = Qt::MouseButton(i);
- copy->setButtonDownPos(button, me->buttonDownPos(button));
- copy->setButtonDownScenePos(button, me->buttonDownScenePos(button));
- copy->setButtonDownScreenPos(button, me->buttonDownScreenPos(button));
- }
- copy->setLastPos(me->lastPos());
- copy->setLastScenePos(me->lastScenePos());
- copy->setLastScreenPos(me->lastScreenPos());
- copy->setButtons(me->buttons());
- copy->setButton(me->button());
- copy->setModifiers(me->modifiers());
- return copy;
-#endif
- }
-#endif // QT_NO_GRAPHICSVIEW
- default:
- return 0;
- }
-}
-
-class PressDelayHandler : public QObject
-{
-private:
- PressDelayHandler(QObject *parent = 0)
- : QObject(parent)
- , pressDelayTimer(0)
- , sendingEvent(false)
- , mouseButton(Qt::NoButton)
- , mouseTarget(0)
- { }
-
- static PressDelayHandler *inst;
-
-public:
- enum {
- UngrabMouseBefore = 1,
- RegrabMouseAfterwards = 2
- };
-
- static PressDelayHandler *instance()
- {
- static PressDelayHandler *inst = 0;
- if (!inst)
- inst = new PressDelayHandler(QCoreApplication::instance());
- return inst;
- }
-
- bool shouldEventBeIgnored(QEvent *) const
- {
- return sendingEvent;
- }
-
- bool isDelaying() const
- {
- return !pressDelayEvent.isNull();
- }
-
- void pressed(QEvent *e, int delay)
- {
- if (!pressDelayEvent) {
- pressDelayEvent.reset(copyMouseEvent(e));
- pressDelayTimer = startTimer(delay);
- mouseTarget = QApplication::widgetAt(pressDelayEvent->globalPos());
- mouseButton = pressDelayEvent->button();
- qFGDebug() << "QFG: consuming/delaying mouse press";
- } else {
- qFGDebug() << "QFG: NOT consuming/delaying mouse press";
- }
- e->setAccepted(true);
- }
-
- bool released(QEvent *e, bool scrollerWasActive, bool scrollerIsActive)
- {
- // consume this event if the scroller was or is active
- bool result = scrollerWasActive || scrollerIsActive;
-
- // stop the timer
- if (pressDelayTimer) {
- killTimer(pressDelayTimer);
- pressDelayTimer = 0;
- }
- // we still haven't even sent the press, so do it now
- if (pressDelayEvent && mouseTarget && !scrollerIsActive) {
- QScopedPointer<QMouseEvent> releaseEvent(copyMouseEvent(e));
-
- qFGDebug() << "QFG: re-sending mouse press (due to release) for " << mouseTarget;
- sendMouseEvent(pressDelayEvent.data(), UngrabMouseBefore);
-
- qFGDebug() << "QFG: faking mouse release (due to release) for " << mouseTarget;
- sendMouseEvent(releaseEvent.data());
-
- result = true; // consume this event
- } else if (mouseTarget && scrollerIsActive) {
- // we grabbed the mouse expicitly when the scroller became active, so undo that now
- sendMouseEvent(0, UngrabMouseBefore);
- }
- pressDelayEvent.reset(0);
- mouseTarget = 0;
- return result;
- }
-
- void scrollerWasIntercepted()
- {
- qFGDebug() << "QFG: deleting delayed mouse press, since scroller was only intercepted";
- if (pressDelayEvent) {
- // we still haven't even sent the press, so just throw it away now
- if (pressDelayTimer) {
- killTimer(pressDelayTimer);
- pressDelayTimer = 0;
- }
- pressDelayEvent.reset(0);
- }
- mouseTarget = 0;
- }
-
- void scrollerBecameActive()
- {
- if (pressDelayEvent) {
- // we still haven't even sent the press, so just throw it away now
- qFGDebug() << "QFG: deleting delayed mouse press, since scroller is active now";
- if (pressDelayTimer) {
- killTimer(pressDelayTimer);
- pressDelayTimer = 0;
- }
- pressDelayEvent.reset(0);
- mouseTarget = 0;
- } else if (mouseTarget) {
- // we did send a press, so we need to fake a release now
-
- // release all pressed mouse buttons
- /* Qt::MouseButtons mouseButtons = QApplication::mouseButtons();
- for (int i = 0; i < 32; ++i) {
- if (mouseButtons & (1 << i)) {
- Qt::MouseButton b = static_cast<Qt::MouseButton>(1 << i);
- mouseButtons &= ~b;
- QPoint farFarAway(-QWIDGETSIZE_MAX, -QWIDGETSIZE_MAX);
-
- qFGDebug() << "QFG: sending a fake mouse release at far-far-away to " << mouseTarget;
- QMouseEvent re(QEvent::MouseButtonRelease, QPoint(), farFarAway,
- b, mouseButtons, QApplication::keyboardModifiers());
- sendMouseEvent(&re);
- }
- }*/
-
- QPoint farFarAway(-QWIDGETSIZE_MAX, -QWIDGETSIZE_MAX);
-
- qFGDebug() << "QFG: sending a fake mouse release at far-far-away to " << mouseTarget;
- QMouseEvent re(QEvent::MouseButtonRelease, QPoint(), farFarAway,
- mouseButton, QApplication::mouseButtons() & ~mouseButton,
- QApplication::keyboardModifiers());
- sendMouseEvent(&re, RegrabMouseAfterwards);
- // don't clear the mouseTarget just yet, since we need to explicitly ungrab the mouse on release!
- }
- }
-
-protected:
- void timerEvent(QTimerEvent *e)
- {
- if (e->timerId() == pressDelayTimer) {
- if (pressDelayEvent && mouseTarget) {
- qFGDebug() << "QFG: timer event: re-sending mouse press to " << mouseTarget;
- sendMouseEvent(pressDelayEvent.data(), UngrabMouseBefore);
- }
- pressDelayEvent.reset(0);
-
- if (pressDelayTimer) {
- killTimer(pressDelayTimer);
- pressDelayTimer = 0;
- }
- }
- }
-
- void sendMouseEvent(QMouseEvent *me, int flags = 0)
- {
- if (mouseTarget) {
- sendingEvent = true;
-
-#ifndef QT_NO_GRAPHICSVIEW
- QGraphicsItem *grabber = 0;
- if (mouseTarget->parentWidget()) {
- if (QGraphicsView *gv = qobject_cast<QGraphicsView *>(mouseTarget->parentWidget())) {
- if (gv->scene())
- grabber = gv->scene()->mouseGrabberItem();
- }
- }
-
- if (grabber && (flags & UngrabMouseBefore)) {
- // GraphicsView Mouse Handling Workaround #1:
- // we need to ungrab the mouse before re-sending the press,
- // since the scene had already set the mouse grabber to the
- // original (and consumed) event's receiver
- qFGDebug() << "QFG: ungrabbing" << grabber;
- grabber->ungrabMouse();
- }
-#endif // QT_NO_GRAPHICSVIEW
-
- if (me) {
- QMouseEvent copy(me->type(), mouseTarget->mapFromGlobal(me->globalPos()), me->globalPos(), me->button(), me->buttons(), me->modifiers());
- qt_sendSpontaneousEvent(mouseTarget, &copy);
- }
-
-#ifndef QT_NO_GRAPHICSVIEW
- if (grabber && (flags & RegrabMouseAfterwards)) {
- // GraphicsView Mouse Handling Workaround #2:
- // we need to re-grab the mouse after sending a faked mouse
- // release, since we still need the mouse moves for the gesture
- // (the scene will clear the item's mouse grabber status on
- // release).
- qFGDebug() << "QFG: re-grabbing" << grabber;
- grabber->grabMouse();
- }
-#endif
- sendingEvent = false;
- }
- }
-
-
-private:
- int pressDelayTimer;
- QScopedPointer<QMouseEvent> pressDelayEvent;
- bool sendingEvent;
- Qt::MouseButton mouseButton;
- QPointer<QWidget> mouseTarget;
-};
-
-
-/*!
- \internal
- \class QFlickGesture
- \since 4.8
- \brief The QFlickGesture class describes a flicking gesture made by the user.
- \ingroup gestures
- The QFlickGesture is more complex than the QPanGesture that uses QScroller and QScrollerProperties
- to decide if it is triggered.
- This gesture is reacting on touch event as compared to the QMouseFlickGesture.
-
- \sa {Gestures Programming}, QScroller, QScrollerProperties, QMouseFlickGesture
-*/
-
-/*!
- \internal
-*/
-QFlickGesture::QFlickGesture(QObject *receiver, Qt::MouseButton button, QObject *parent)
- : QGesture(*new QFlickGesturePrivate, parent)
-{
- d_func()->q_ptr = this;
- d_func()->receiver = receiver;
- d_func()->receiverScroller = (receiver && QScroller::hasScroller(receiver)) ? QScroller::scroller(receiver) : 0;
- d_func()->button = button;
-}
-
-QFlickGesture::~QFlickGesture()
-{ }
-
-QFlickGesturePrivate::QFlickGesturePrivate()
- : receiverScroller(0), button(Qt::NoButton), macIgnoreWheel(false)
-{ }
-
-
-//
-// QFlickGestureRecognizer
-//
-
-
-QFlickGestureRecognizer::QFlickGestureRecognizer(Qt::MouseButton button)
-{
- this->button = button;
-}
-
-/*! \reimp
- */
-QGesture *QFlickGestureRecognizer::create(QObject *target)
-{
-#ifndef QT_NO_GRAPHICSVIEW
- QGraphicsObject *go = qobject_cast<QGraphicsObject*>(target);
- if (go && button == Qt::NoButton) {
- go->setAcceptTouchEvents(true);
- }
-#endif
- return new QFlickGesture(target, button);
-}
-
-/*! \internal
- The recognize function detects a touch event suitable to start the attached QScroller.
- The QFlickGesture will be triggered as soon as the scroller is no longer in the state
- QScroller::Inactive or QScroller::Pressed. It will be finished or canceled
- at the next QEvent::TouchEnd.
- Note that the QScroller might continue scrolling (kinetically) at this point.
- */
-QGestureRecognizer::Result QFlickGestureRecognizer::recognize(QGesture *state,
- QObject *watched,
- QEvent *event)
-{
- Q_UNUSED(watched);
-
- static QElapsedTimer monotonicTimer;
- if (!monotonicTimer.isValid())
- monotonicTimer.start();
-
- QFlickGesture *q = static_cast<QFlickGesture *>(state);
- QFlickGesturePrivate *d = q->d_func();
-
- QScroller *scroller = d->receiverScroller;
- if (!scroller)
- return Ignore; // nothing to do without a scroller?
-
- QWidget *receiverWidget = qobject_cast<QWidget *>(d->receiver);
-#ifndef QT_NO_GRAPHICSVIEW
- QGraphicsObject *receiverGraphicsObject = qobject_cast<QGraphicsObject *>(d->receiver);
-#endif
-
- // this is only set for events that we inject into the event loop via sendEvent()
- if (PressDelayHandler::instance()->shouldEventBeIgnored(event)) {
- //qFGDebug() << state << "QFG: ignored event: " << event->type();
- return Ignore;
- }
-
- const QMouseEvent *me = 0;
-#ifndef QT_NO_GRAPHICSVIEW
- const QGraphicsSceneMouseEvent *gsme = 0;
-#endif
- const QTouchEvent *te = 0;
- QPoint globalPos;
-
- // qFGDebug() << "FlickGesture "<<state<<"watched:"<<watched<<"receiver"<<d->receiver<<"event"<<event->type()<<"button"<<button;
-
- switch (event->type()) {
- case QEvent::MouseButtonPress:
- case QEvent::MouseButtonRelease:
- case QEvent::MouseMove:
- if (!receiverWidget)
- return Ignore;
- if (button != Qt::NoButton) {
- me = static_cast<const QMouseEvent *>(event);
- globalPos = me->globalPos();
- }
- break;
-#ifndef QT_NO_GRAPHICSVIEW
- case QEvent::GraphicsSceneMousePress:
- case QEvent::GraphicsSceneMouseRelease:
- case QEvent::GraphicsSceneMouseMove:
- if (!receiverGraphicsObject)
- return Ignore;
- if (button != Qt::NoButton) {
- gsme = static_cast<const QGraphicsSceneMouseEvent *>(event);
- globalPos = gsme->screenPos();
- }
- break;
-#endif
- case QEvent::TouchBegin:
- case QEvent::TouchEnd:
- case QEvent::TouchUpdate:
- if (button == Qt::NoButton) {
- te = static_cast<const QTouchEvent *>(event);
- if (!te->touchPoints().isEmpty())
- globalPos = te->touchPoints().at(0).screenPos().toPoint();
- }
- break;
-
-#if defined(Q_WS_MAC)
- // the only way to distinguish between real mouse wheels and wheel
- // events generated by the native 2 finger swipe gesture is to listen
- // for these events (according to Apple's Cocoa Event-Handling Guide)
-
- case QEvent::NativeGesture: {
- QNativeGestureEvent *nge = static_cast<QNativeGestureEvent *>(event);
- if (nge->gestureType == QNativeGestureEvent::GestureBegin)
- d->macIgnoreWheel = true;
- else if (nge->gestureType == QNativeGestureEvent::GestureEnd)
- d->macIgnoreWheel = false;
- break;
- }
-#endif
-
- // consume all wheel events if the scroller is active
- case QEvent::Wheel:
- if (d->macIgnoreWheel || (scroller->state() != QScroller::Inactive))
- return Ignore | ConsumeEventHint;
- break;
-
- // consume all dbl click events if the scroller is active
- case QEvent::MouseButtonDblClick:
- if (scroller->state() != QScroller::Inactive)
- return Ignore | ConsumeEventHint;
- break;
-
- default:
- break;
- }
-
- if (!me
-#ifndef QT_NO_GRAPHICSVIEW
- && !gsme
-#endif
- && !te) // Neither mouse nor touch
- return Ignore;
-
- // get the current pointer position in local coordinates.
- QPointF point;
- QScroller::Input inputType = (QScroller::Input) 0;
-
- switch (event->type()) {
- case QEvent::MouseButtonPress:
- if (me && me->button() == button && me->buttons() == button) {
- point = me->globalPos();
- inputType = QScroller::InputPress;
- } else if (me) {
- scroller->stop();
- return CancelGesture;
- }
- break;
- case QEvent::MouseButtonRelease:
- if (me && me->button() == button) {
- point = me->globalPos();
- inputType = QScroller::InputRelease;
- }
- break;
- case QEvent::MouseMove:
-#ifdef Q_OS_SYMBIAN
- // Qt on Symbian tracks the button state internally, while Qt on Win/Mac/Unix
- // relies on the windowing system to report the current buttons state.
- if (me && (me->buttons() == button || !me->buttons())) {
-#else
- if (me && me->buttons() == button) {
-#endif
- point = me->globalPos();
- inputType = QScroller::InputMove;
- }
- break;
-
-#ifndef QT_NO_GRAPHICSVIEW
- case QEvent::GraphicsSceneMousePress:
- if (gsme && gsme->button() == button && gsme->buttons() == button) {
- point = gsme->scenePos();
- inputType = QScroller::InputPress;
- } else if (gsme) {
- scroller->stop();
- return CancelGesture;
- }
- break;
- case QEvent::GraphicsSceneMouseRelease:
- if (gsme && gsme->button() == button) {
- point = gsme->scenePos();
- inputType = QScroller::InputRelease;
- }
- break;
- case QEvent::GraphicsSceneMouseMove:
-#ifdef Q_OS_SYMBIAN
- // Qt on Symbian tracks the button state internally, while Qt on Win/Mac/Unix
- // relies on the windowing system to report the current buttons state.
- if (gsme && (gsme->buttons() == button || !me->buttons())) {
-#else
- if (gsme && gsme->buttons() == button) {
-#endif
- point = gsme->scenePos();
- inputType = QScroller::InputMove;
- }
- break;
-#endif
-
- case QEvent::TouchBegin:
- inputType = QScroller::InputPress;
- // fall through
- case QEvent::TouchEnd:
- if (!inputType)
- inputType = QScroller::InputRelease;
- // fallthrough
- case QEvent::TouchUpdate:
- if (!inputType)
- inputType = QScroller::InputMove;
-
- if (te->deviceType() == QTouchEvent::TouchPad) {
- if (te->touchPoints().count() != 2) // 2 fingers on pad
- return Ignore;
-
- point = te->touchPoints().at(0).startScenePos() +
- ((te->touchPoints().at(0).scenePos() - te->touchPoints().at(0).startScenePos()) +
- (te->touchPoints().at(1).scenePos() - te->touchPoints().at(1).startScenePos())) / 2;
- } else { // TouchScreen
- if (te->touchPoints().count() != 1) // 1 finger on screen
- return Ignore;
-
- point = te->touchPoints().at(0).scenePos();
- }
- break;
-
- default:
- break;
- }
-
- // Check for an active scroller at globalPos
- if (inputType == QScroller::InputPress) {
- foreach (QScroller *as, QScroller::activeScrollers()) {
- if (as != scroller) {
- QRegion scrollerRegion;
-
- if (QWidget *w = qobject_cast<QWidget *>(as->target())) {
- scrollerRegion = QRect(w->mapToGlobal(QPoint(0, 0)), w->size());
-#ifndef QT_NO_GRAPHICSVIEW
- } else if (QGraphicsObject *go = qobject_cast<QGraphicsObject *>(as->target())) {
- if (go->scene() && !go->scene()->views().isEmpty()) {
- foreach (QGraphicsView *gv, go->scene()->views())
- scrollerRegion |= gv->mapFromScene(go->mapToScene(go->boundingRect()))
- .translated(gv->mapToGlobal(QPoint(0, 0)));
- }
-#endif
- }
- // active scrollers always have priority
- if (scrollerRegion.contains(globalPos))
- return Ignore;
- }
- }
- }
-
- bool scrollerWasDragging = (scroller->state() == QScroller::Dragging);
- bool scrollerWasScrolling = (scroller->state() == QScroller::Scrolling);
-
- if (inputType) {
- if (QWidget *w = qobject_cast<QWidget *>(d->receiver))
- point = w->mapFromGlobal(point.toPoint());
-#ifndef QT_NO_GRAPHICSVIEW
- else if (QGraphicsObject *go = qobject_cast<QGraphicsObject *>(d->receiver))
- point = go->mapFromScene(point);
-#endif
-
- // inform the scroller about the new event
- scroller->handleInput(inputType, point, monotonicTimer.elapsed());
- }
-
- // depending on the scroller state return the gesture state
- Result result(0);
- bool scrollerIsActive = (scroller->state() == QScroller::Dragging ||
- scroller->state() == QScroller::Scrolling);
-
- // Consume all mouse events while dragging or scrolling to avoid nasty
- // side effects with Qt's standard widgets.
- if ((me
-#ifndef QT_NO_GRAPHICSVIEW
- || gsme
-#endif
- ) && scrollerIsActive)
- result |= ConsumeEventHint;
-
- // The only problem with this approach is that we consume the
- // MouseRelease when we start the scrolling with a flick gesture, so we
- // have to fake a MouseRelease "somewhere" to not mess with the internal
- // states of Qt's widgets (a QPushButton would stay in 'pressed' state
- // forever, if it doesn't receive a MouseRelease).
- if (me
-#ifndef QT_NO_GRAPHICSVIEW
- || gsme
-#endif
- ) {
- if (!scrollerWasDragging && !scrollerWasScrolling && scrollerIsActive)
- PressDelayHandler::instance()->scrollerBecameActive();
- else if (scrollerWasScrolling && (scroller->state() == QScroller::Dragging || scroller->state() == QScroller::Inactive))
- PressDelayHandler::instance()->scrollerWasIntercepted();
- }
-
- if (!inputType) {
- result |= Ignore;
- } else {
- switch (event->type()) {
- case QEvent::MouseButtonPress:
-#ifndef QT_NO_GRAPHICSVIEW
- case QEvent::GraphicsSceneMousePress:
-#endif
- if (scroller->state() == QScroller::Pressed) {
- int pressDelay = int(1000 * scroller->scrollerProperties().scrollMetric(QScrollerProperties::MousePressEventDelay).toReal());
- if (pressDelay > 0) {
- result |= ConsumeEventHint;
-
- PressDelayHandler::instance()->pressed(event, pressDelay);
- event->accept();
- }
- }
- // fall through
- case QEvent::TouchBegin:
- q->setHotSpot(globalPos);
- result |= scrollerIsActive ? TriggerGesture : MayBeGesture;
- break;
-
- case QEvent::MouseMove:
-#ifndef QT_NO_GRAPHICSVIEW
- case QEvent::GraphicsSceneMouseMove:
-#endif
- if (PressDelayHandler::instance()->isDelaying())
- result |= ConsumeEventHint;
- // fall through
- case QEvent::TouchUpdate:
- result |= scrollerIsActive ? TriggerGesture : Ignore;
- break;
-
-#ifndef QT_NO_GRAPHICSVIEW
- case QEvent::GraphicsSceneMouseRelease:
-#endif
- case QEvent::MouseButtonRelease:
- if (PressDelayHandler::instance()->released(event, scrollerWasDragging || scrollerWasScrolling, scrollerIsActive))
- result |= ConsumeEventHint;
- // fall through
- case QEvent::TouchEnd:
- result |= scrollerIsActive ? FinishGesture : CancelGesture;
- break;
-
- default:
- result |= Ignore;
- break;
- }
- }
- return result;
-}
-
-
-/*! \reimp
- */
-void QFlickGestureRecognizer::reset(QGesture *state)
-{
- QGestureRecognizer::reset(state);
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_GESTURES
diff --git a/src/gui/util/qflickgesture_p.h b/src/gui/util/qflickgesture_p.h
deleted file mode 100644
index e095cf5eab..0000000000
--- a/src/gui/util/qflickgesture_p.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QFLICKGESTURE_P_H
-#define QFLICKGESTURE_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qevent.h"
-#include "qgesturerecognizer.h"
-#include "private/qgesture_p.h"
-#include "qscroller.h"
-#include "qscopedpointer.h"
-
-#ifndef QT_NO_GESTURES
-
-QT_BEGIN_NAMESPACE
-
-class QFlickGesturePrivate;
-class QGraphicsItem;
-
-class Q_GUI_EXPORT QFlickGesture : public QGesture
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QFlickGesture)
-
-public:
- QFlickGesture(QObject *receiver, Qt::MouseButton button, QObject *parent = 0);
- ~QFlickGesture();
-
- friend class QFlickGestureRecognizer;
-};
-
-class PressDelayHandler;
-
-class QFlickGesturePrivate : public QGesturePrivate
-{
- Q_DECLARE_PUBLIC(QFlickGesture)
-public:
- QFlickGesturePrivate();
-
- QPointer<QObject> receiver;
- QScroller *receiverScroller;
- Qt::MouseButton button; // NoButton == Touch
- bool macIgnoreWheel;
- static PressDelayHandler *pressDelayHandler;
-};
-
-class QFlickGestureRecognizer : public QGestureRecognizer
-{
-public:
- QFlickGestureRecognizer(Qt::MouseButton button);
-
- QGesture *create(QObject *target);
- QGestureRecognizer::Result recognize(QGesture *state, QObject *watched, QEvent *event);
- void reset(QGesture *state);
-
-private:
- Qt::MouseButton button; // NoButton == Touch
-};
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_GESTURES
-
-#endif // QFLICKGESTURE_P_H
diff --git a/src/gui/util/qhexstring_p.h b/src/gui/util/qhexstring_p.h
new file mode 100644
index 0000000000..3c8d562756
--- /dev/null
+++ b/src/gui/util/qhexstring_p.h
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qglobal.h>
+#include <QtCore/qpoint.h>
+#include <QtCore/qstring.h>
+#include <QtGui/qpolygon.h>
+#include <QtCore/qstringbuilder.h>
+
+#ifndef QHEXSTRING_P_H
+#define QHEXSTRING_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+QT_BEGIN_NAMESPACE
+
+// internal helper. Converts an integer value to an unique string token
+template <typename T>
+ struct HexString
+{
+ inline HexString(const T t)
+ : val(t)
+ {}
+
+ inline void write(QChar *&dest) const
+ {
+ const ushort hexChars[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
+ const char *c = reinterpret_cast<const char *>(&val);
+ for (uint i = 0; i < sizeof(T); ++i) {
+ *dest++ = hexChars[*c & 0xf];
+ *dest++ = hexChars[(*c & 0xf0) >> 4];
+ ++c;
+ }
+ }
+ const T val;
+};
+
+// specialization to enable fast concatenating of our string tokens to a string
+template <typename T>
+ struct QConcatenable<HexString<T> >
+{
+ typedef HexString<T> type;
+ enum { ExactSize = true };
+ static int size(const HexString<T> &) { return sizeof(T) * 2; }
+ static inline void appendTo(const HexString<T> &str, QChar *&out) { str.write(out); }
+ typedef QString ConvertTo;
+};
+
+QT_END_NAMESPACE
+
+#endif // QHEXSTRING_P_H
diff --git a/src/gui/util/qscroller.h b/src/gui/util/qscroller.h
deleted file mode 100644
index 16a7f2e421..0000000000
--- a/src/gui/util/qscroller.h
+++ /dev/null
@@ -1,155 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSCROLLER_H
-#define QSCROLLER_H
-
-#include <QtCore/QObject>
-#include <QtCore/QPointF>
-#include <QtGui/QScrollerProperties>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QWidget;
-class QScrollerPrivate;
-class QScrollerProperties;
-#ifndef QT_NO_GESTURES
-class QFlickGestureRecognizer;
-class QMouseFlickGestureRecognizer;
-#endif
-
-class Q_GUI_EXPORT QScroller : public QObject
-{
- Q_OBJECT
- Q_PROPERTY(State state READ state NOTIFY stateChanged)
- Q_PROPERTY(QScrollerProperties scrollerProperties READ scrollerProperties WRITE setScrollerProperties NOTIFY scrollerPropertiesChanged)
- Q_ENUMS(State)
-
-public:
- enum State
- {
- Inactive,
- Pressed,
- Dragging,
- Scrolling
- };
-
- enum ScrollerGestureType
- {
- TouchGesture,
- LeftMouseButtonGesture,
- RightMouseButtonGesture,
- MiddleMouseButtonGesture
- };
-
- enum Input
- {
- InputPress = 1,
- InputMove,
- InputRelease
- };
-
- static bool hasScroller(QObject *target);
-
- static QScroller *scroller(QObject *target);
- static const QScroller *scroller(const QObject *target);
-
-#ifndef QT_NO_GESTURES
- static Qt::GestureType grabGesture(QObject *target, ScrollerGestureType gestureType = TouchGesture);
- static Qt::GestureType grabbedGesture(QObject *target);
- static void ungrabGesture(QObject *target);
-#endif
-
- static QList<QScroller *> activeScrollers();
-
- QObject *target() const;
-
- State state() const;
-
- bool handleInput(Input input, const QPointF &position, qint64 timestamp = 0);
-
- void stop();
- QPointF velocity() const;
- QPointF finalPosition() const;
- QPointF pixelPerMeter() const;
-
- QScrollerProperties scrollerProperties() const;
-
- void setSnapPositionsX( const QList<qreal> &positions );
- void setSnapPositionsX( qreal first, qreal interval );
- void setSnapPositionsY( const QList<qreal> &positions );
- void setSnapPositionsY( qreal first, qreal interval );
-
-public Q_SLOTS:
- void setScrollerProperties(const QScrollerProperties &prop);
- void scrollTo(const QPointF &pos);
- void scrollTo(const QPointF &pos, int scrollTime);
- void ensureVisible(const QRectF &rect, qreal xmargin, qreal ymargin);
- void ensureVisible(const QRectF &rect, qreal xmargin, qreal ymargin, int scrollTime);
- void resendPrepareEvent();
-
-Q_SIGNALS:
- void stateChanged(QScroller::State newstate);
- void scrollerPropertiesChanged(const QScrollerProperties &);
-
-private:
- QScrollerPrivate *d_ptr;
-
- QScroller(QObject *target);
- virtual ~QScroller();
-
- Q_DISABLE_COPY(QScroller)
- Q_DECLARE_PRIVATE(QScroller)
-
-#ifndef QT_NO_GESTURES
- friend class QFlickGestureRecognizer;
-#endif
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QSCROLLER_H
diff --git a/src/gui/util/qscrollerproperties.h b/src/gui/util/qscrollerproperties.h
deleted file mode 100644
index 46d1c2f44a..0000000000
--- a/src/gui/util/qscrollerproperties.h
+++ /dev/null
@@ -1,140 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSCROLLERPROPERTIES_H
-#define QSCROLLERPROPERTIES_H
-
-#include <QtCore/QScopedPointer>
-#include <QtCore/QMetaType>
-#include <QtCore/QVariant>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QScroller;
-class QScrollerPrivate;
-class QScrollerPropertiesPrivate;
-
-class Q_GUI_EXPORT QScrollerProperties
-{
-public:
- QScrollerProperties();
- QScrollerProperties(const QScrollerProperties &sp);
- QScrollerProperties &operator=(const QScrollerProperties &sp);
- virtual ~QScrollerProperties();
-
- bool operator==(const QScrollerProperties &sp) const;
- bool operator!=(const QScrollerProperties &sp) const;
-
- static void setDefaultScrollerProperties(const QScrollerProperties &sp);
- static void unsetDefaultScrollerProperties();
-
- enum OvershootPolicy
- {
- OvershootWhenScrollable,
- OvershootAlwaysOff,
- OvershootAlwaysOn
- };
-
- enum FrameRates {
- Standard,
- Fps60,
- Fps30,
- Fps20
- };
-
- enum ScrollMetric
- {
- MousePressEventDelay, // qreal [s]
- DragStartDistance, // qreal [m]
- DragVelocitySmoothingFactor, // qreal [0..1/s] (complex calculation involving time) v = v_new* DASF + v_old * (1-DASF)
- AxisLockThreshold, // qreal [0..1] atan(|min(dx,dy)|/|max(dx,dy)|)
-
- ScrollingCurve, // QEasingCurve
- DecelerationFactor, // slope of the curve
-
- MinimumVelocity, // qreal [m/s]
- MaximumVelocity, // qreal [m/s]
- MaximumClickThroughVelocity, // qreal [m/s]
-
- AcceleratingFlickMaximumTime, // qreal [s]
- AcceleratingFlickSpeedupFactor, // qreal [1..]
-
- SnapPositionRatio, // qreal [0..1]
- SnapTime, // qreal [s]
-
- OvershootDragResistanceFactor, // qreal [0..1]
- OvershootDragDistanceFactor, // qreal [0..1]
- OvershootScrollDistanceFactor, // qreal [0..1]
- OvershootScrollTime, // qreal [s]
-
- HorizontalOvershootPolicy, // enum OvershootPolicy
- VerticalOvershootPolicy, // enum OvershootPolicy
- FrameRate, // enum FrameRates
-
- ScrollMetricCount
- };
-
- QVariant scrollMetric(ScrollMetric metric) const;
- void setScrollMetric(ScrollMetric metric, const QVariant &value);
-
-protected:
- QScopedPointer<QScrollerPropertiesPrivate> d;
-
-private:
- QScrollerProperties(QScrollerPropertiesPrivate &dd);
-
- friend class QScrollerPropertiesPrivate;
- friend class QScroller;
- friend class QScrollerPrivate;
-};
-
-QT_END_NAMESPACE
-
-Q_DECLARE_METATYPE(QScrollerProperties::OvershootPolicy)
-Q_DECLARE_METATYPE(QScrollerProperties::FrameRates)
-
-QT_END_HEADER
-
-#endif // QSCROLLERPROPERTIES_H
diff --git a/src/gui/util/qsystemtrayicon.cpp b/src/gui/util/qsystemtrayicon.cpp
deleted file mode 100644
index 28d493248f..0000000000
--- a/src/gui/util/qsystemtrayicon.cpp
+++ /dev/null
@@ -1,674 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qsystemtrayicon.h"
-#include "qsystemtrayicon_p.h"
-
-#ifndef QT_NO_SYSTEMTRAYICON
-
-#include "qmenu.h"
-#include "qevent.h"
-#include "qpoint.h"
-#include "qlabel.h"
-#include "qpushbutton.h"
-#include "qpainterpath.h"
-#include "qpainter.h"
-#include "qstyle.h"
-#include "qgridlayout.h"
-#include "qapplication.h"
-#include "qdesktopwidget.h"
-#include "qbitmap.h"
-#include "private/qlabel_p.h"
-#include "qapplication.h"
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \class QSystemTrayIcon
- \brief The QSystemTrayIcon class provides an icon for an application in the system tray.
- \since 4.2
- \ingroup desktop
-
- Modern operating systems usually provide a special area on the desktop,
- called the \e{system tray} or \e{notification area}, where long-running
- applications can display icons and short messages.
-
- \image system-tray.png The system tray on Windows XP.
-
- The QSystemTrayIcon class can be used on the following platforms:
-
- \list
- \o All supported versions of Windows.
- \o All window managers for X11 that implement the \l{freedesktop.org} system
- tray specification, including recent versions of KDE and GNOME.
- \o All supported versions of Mac OS X. Note that the Growl
- notification system must be installed for
- QSystemTrayIcon::showMessage() to display messages.
- \endlist
-
- To check whether a system tray is present on the user's desktop,
- call the QSystemTrayIcon::isSystemTrayAvailable() static function.
-
- To add a system tray entry, create a QSystemTrayIcon object, call setContextMenu()
- to provide a context menu for the icon, and call show() to make it visible in the
- system tray. Status notification messages ("balloon messages") can be displayed at
- any time using showMessage().
-
- If the system tray is unavailable when a system tray icon is constructed, but
- becomes available later, QSystemTrayIcon will automatically add an entry for the
- application in the system tray if the icon is \l visible.
-
- The activated() signal is emitted when the user activates the icon.
-
- Only on X11, when a tooltip is requested, the QSystemTrayIcon receives a QHelpEvent
- of type QEvent::ToolTip. Additionally, the QSystemTrayIcon receives wheel events of
- type QEvent::Wheel. These are not supported on any other platform.
-
- \sa QDesktopServices, QDesktopWidget, {Desktop Integration}, {System Tray Icon Example}
-*/
-
-/*!
- \enum QSystemTrayIcon::MessageIcon
-
- This enum describes the icon that is shown when a balloon message is displayed.
-
- \value NoIcon No icon is shown.
- \value Information An information icon is shown.
- \value Warning A standard warning icon is shown.
- \value Critical A critical warning icon is shown.
-
- \sa QMessageBox
-*/
-
-/*!
- Constructs a QSystemTrayIcon object with the given \a parent.
-
- The icon is initially invisible.
-
- \sa visible
-*/
-QSystemTrayIcon::QSystemTrayIcon(QObject *parent)
-: QObject(*new QSystemTrayIconPrivate(), parent)
-{
-}
-
-/*!
- Constructs a QSystemTrayIcon object with the given \a icon and \a parent.
-
- The icon is initially invisible.
-
- \sa visible
-*/
-QSystemTrayIcon::QSystemTrayIcon(const QIcon &icon, QObject *parent)
-: QObject(*new QSystemTrayIconPrivate(), parent)
-{
- setIcon(icon);
-}
-
-/*!
- Removes the icon from the system tray and frees all allocated resources.
-*/
-QSystemTrayIcon::~QSystemTrayIcon()
-{
- Q_D(QSystemTrayIcon);
- d->remove_sys();
-}
-
-#ifndef QT_NO_MENU
-
-/*!
- Sets the specified \a menu to be the context menu for the system tray icon.
-
- The menu will pop up when the user requests the context menu for the system
- tray icon by clicking the mouse button.
-
- On Mac OS X, this is currenly converted to a NSMenu, so the
- aboutToHide() signal is not emitted.
-
- \note The system tray icon does not take ownership of the menu. You must
- ensure that it is deleted at the appropriate time by, for example, creating
- the menu with a suitable parent object.
-*/
-void QSystemTrayIcon::setContextMenu(QMenu *menu)
-{
- Q_D(QSystemTrayIcon);
- d->menu = menu;
- d->updateMenu_sys();
-}
-
-/*!
- Returns the current context menu for the system tray entry.
-*/
-QMenu* QSystemTrayIcon::contextMenu() const
-{
- Q_D(const QSystemTrayIcon);
- return d->menu;
-}
-
-#endif // QT_NO_MENU
-
-/*!
- \property QSystemTrayIcon::icon
- \brief the system tray icon
-
- On Windows, the system tray icon size is 16x16; on X11, the preferred size is
- 22x22. The icon will be scaled to the appropriate size as necessary.
-*/
-void QSystemTrayIcon::setIcon(const QIcon &icon)
-{
- Q_D(QSystemTrayIcon);
- d->icon = icon;
- d->updateIcon_sys();
-}
-
-QIcon QSystemTrayIcon::icon() const
-{
- Q_D(const QSystemTrayIcon);
- return d->icon;
-}
-
-/*!
- \property QSystemTrayIcon::toolTip
- \brief the tooltip for the system tray entry
-
- On some systems, the tooltip's length is limited. The tooltip will be truncated
- if necessary.
-*/
-void QSystemTrayIcon::setToolTip(const QString &tooltip)
-{
- Q_D(QSystemTrayIcon);
- d->toolTip = tooltip;
- d->updateToolTip_sys();
-}
-
-QString QSystemTrayIcon::toolTip() const
-{
- Q_D(const QSystemTrayIcon);
- return d->toolTip;
-}
-
-/*!
- \fn void QSystemTrayIcon::show()
-
- Shows the icon in the system tray.
-
- \sa hide(), visible
-*/
-
-/*!
- \fn void QSystemTrayIcon::hide()
-
- Hides the system tray entry.
-
- \sa show(), visible
-*/
-
-/*!
- \since 4.3
- Returns the geometry of the system tray icon in screen coordinates.
-
- \sa visible
-*/
-QRect QSystemTrayIcon::geometry() const
-{
- Q_D(const QSystemTrayIcon);
- if (!d->visible)
- return QRect();
- return d->geometry_sys();
-}
-
-/*!
- \property QSystemTrayIcon::visible
- \brief whether the system tray entry is visible
-
- Setting this property to true or calling show() makes the system tray icon
- visible; setting this property to false or calling hide() hides it.
-*/
-void QSystemTrayIcon::setVisible(bool visible)
-{
- Q_D(QSystemTrayIcon);
- if (visible == d->visible)
- return;
- if (d->icon.isNull() && visible)
- qWarning("QSystemTrayIcon::setVisible: No Icon set");
- d->visible = visible;
- if (d->visible)
- d->install_sys();
- else
- d->remove_sys();
-}
-
-bool QSystemTrayIcon::isVisible() const
-{
- Q_D(const QSystemTrayIcon);
- return d->visible;
-}
-
-/*!
- \reimp
-*/
-bool QSystemTrayIcon::event(QEvent *e)
-{
-#if defined(Q_WS_X11)
- if (e->type() == QEvent::ToolTip) {
- Q_D(QSystemTrayIcon);
- return d->sys->deliverToolTipEvent(e);
- }
-#endif
- return QObject::event(e);
-}
-
-/*!
- \enum QSystemTrayIcon::ActivationReason
-
- This enum describes the reason the system tray was activated.
-
- \value Unknown Unknown reason
- \value Context The context menu for the system tray entry was requested
- \value DoubleClick The system tray entry was double clicked
- \value Trigger The system tray entry was clicked
- \value MiddleClick The system tray entry was clicked with the middle mouse button
-
- \sa activated()
-*/
-
-/*!
- \fn void QSystemTrayIcon::activated(QSystemTrayIcon::ActivationReason reason)
-
- This signal is emitted when the user activates the system tray icon. \a reason
- specifies the reason for activation. QSystemTrayIcon::ActivationReason enumerates
- the various reasons.
-
- \sa QSystemTrayIcon::ActivationReason
-*/
-
-/*!
- \fn void QSystemTrayIcon::messageClicked()
-
- This signal is emitted when the message displayed using showMessage()
- was clicked by the user.
-
- Currently this signal is not sent on Mac OS X.
-
- \note We follow Microsoft Windows XP/Vista behavior, so the
- signal is also emitted when the user clicks on a tray icon with
- a balloon message displayed.
-
- \sa activated()
-*/
-
-
-/*!
- Returns true if the system tray is available; otherwise returns false.
-
- If the system tray is currently unavailable but becomes available later,
- QSystemTrayIcon will automatically add an entry in the system tray if it
- is \l visible.
-*/
-
-bool QSystemTrayIcon::isSystemTrayAvailable()
-{
- return QSystemTrayIconPrivate::isSystemTrayAvailable_sys();
-}
-
-/*!
- Returns true if the system tray supports balloon messages; otherwise returns false.
-
- \sa showMessage()
-*/
-bool QSystemTrayIcon::supportsMessages()
-{
- return QSystemTrayIconPrivate::supportsMessages_sys();
-}
-
-/*!
- \fn void QSystemTrayIcon::showMessage(const QString &title, const QString &message, MessageIcon icon, int millisecondsTimeoutHint)
- \since 4.3
-
- Shows a balloon message for the entry with the given \a title, \a message and
- \a icon for the time specified in \a millisecondsTimeoutHint. \a title and \a message
- must be plain text strings.
-
- Message can be clicked by the user; the messageClicked() signal will emitted when
- this occurs.
-
- Note that display of messages are dependent on the system configuration and user
- preferences, and that messages may not appear at all. Hence, it should not be
- relied upon as the sole means for providing critical information.
-
- On Windows, the \a millisecondsTimeoutHint is usually ignored by the system
- when the application has focus.
-
- On Mac OS X, the Growl notification system must be installed for this function to
- display messages.
-
- \sa show() supportsMessages()
- */
-void QSystemTrayIcon::showMessage(const QString& title, const QString& msg,
- QSystemTrayIcon::MessageIcon icon, int msecs)
-{
- Q_D(QSystemTrayIcon);
- if (d->visible)
- d->showMessage_sys(title, msg, icon, msecs);
-}
-
-//////////////////////////////////////////////////////////////////////
-static QBalloonTip *theSolitaryBalloonTip = 0;
-
-void QBalloonTip::showBalloon(QSystemTrayIcon::MessageIcon icon, const QString& title,
- const QString& message, QSystemTrayIcon *trayIcon,
- const QPoint& pos, int timeout, bool showArrow)
-{
- hideBalloon();
- if (message.isEmpty() && title.isEmpty())
- return;
-
- theSolitaryBalloonTip = new QBalloonTip(icon, title, message, trayIcon);
- if (timeout < 0)
- timeout = 10000; //10 s default
- theSolitaryBalloonTip->balloon(pos, timeout, showArrow);
-}
-
-void QBalloonTip::hideBalloon()
-{
- if (!theSolitaryBalloonTip)
- return;
- theSolitaryBalloonTip->hide();
- delete theSolitaryBalloonTip;
- theSolitaryBalloonTip = 0;
-}
-
-bool QBalloonTip::isBalloonVisible()
-{
- return theSolitaryBalloonTip;
-}
-
-QBalloonTip::QBalloonTip(QSystemTrayIcon::MessageIcon icon, const QString& title,
- const QString& message, QSystemTrayIcon *ti)
- : QWidget(0, Qt::ToolTip), trayIcon(ti), timerId(-1)
-{
- setAttribute(Qt::WA_DeleteOnClose);
- QObject::connect(ti, SIGNAL(destroyed()), this, SLOT(close()));
-
- QLabel *titleLabel = new QLabel;
- titleLabel->installEventFilter(this);
- titleLabel->setText(title);
- QFont f = titleLabel->font();
- f.setBold(true);
-#ifdef Q_WS_WINCE
- f.setPointSize(f.pointSize() - 2);
-#endif
- titleLabel->setFont(f);
- titleLabel->setTextFormat(Qt::PlainText); // to maintain compat with windows
-
-#ifdef Q_WS_WINCE
- const int iconSize = style()->pixelMetric(QStyle::PM_SmallIconSize);
- const int closeButtonSize = style()->pixelMetric(QStyle::PM_SmallIconSize) - 2;
-#else
- const int iconSize = 18;
- const int closeButtonSize = 15;
-#endif
-
- QPushButton *closeButton = new QPushButton;
- closeButton->setIcon(style()->standardIcon(QStyle::SP_TitleBarCloseButton));
- closeButton->setIconSize(QSize(closeButtonSize, closeButtonSize));
- closeButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
- closeButton->setFixedSize(closeButtonSize, closeButtonSize);
- QObject::connect(closeButton, SIGNAL(clicked()), this, SLOT(close()));
-
- QLabel *msgLabel = new QLabel;
-#ifdef Q_WS_WINCE
- f.setBold(false);
- msgLabel->setFont(f);
-#endif
- msgLabel->installEventFilter(this);
- msgLabel->setText(message);
- msgLabel->setTextFormat(Qt::PlainText);
- msgLabel->setAlignment(Qt::AlignTop | Qt::AlignLeft);
-
- // smart size for the message label
-#ifdef Q_WS_WINCE
- int limit = QApplication::desktop()->availableGeometry(msgLabel).size().width() / 2;
-#else
- int limit = QApplication::desktop()->availableGeometry(msgLabel).size().width() / 3;
-#endif
- if (msgLabel->sizeHint().width() > limit) {
- msgLabel->setWordWrap(true);
- if (msgLabel->sizeHint().width() > limit) {
- msgLabel->d_func()->ensureTextControl();
- if (QTextControl *control = msgLabel->d_func()->control) {
- QTextOption opt = control->document()->defaultTextOption();
- opt.setWrapMode(QTextOption::WrapAnywhere);
- control->document()->setDefaultTextOption(opt);
- }
- }
-#ifdef Q_WS_WINCE
- // Make sure that the text isn't wrapped "somewhere" in the balloon widget
- // in the case that we have a long title label.
- setMaximumWidth(limit);
-#else
- // Here we allow the text being much smaller than the balloon widget
- // to emulate the weird standard windows behavior.
- msgLabel->setFixedSize(limit, msgLabel->heightForWidth(limit));
-#endif
- }
-
- QIcon si;
- switch (icon) {
- case QSystemTrayIcon::Warning:
- si = style()->standardIcon(QStyle::SP_MessageBoxWarning);
- break;
- case QSystemTrayIcon::Critical:
- si = style()->standardIcon(QStyle::SP_MessageBoxCritical);
- break;
- case QSystemTrayIcon::Information:
- si = style()->standardIcon(QStyle::SP_MessageBoxInformation);
- break;
- case QSystemTrayIcon::NoIcon:
- default:
- break;
- }
-
- QGridLayout *layout = new QGridLayout;
- if (!si.isNull()) {
- QLabel *iconLabel = new QLabel;
- iconLabel->setPixmap(si.pixmap(iconSize, iconSize));
- iconLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
- iconLabel->setMargin(2);
- layout->addWidget(iconLabel, 0, 0);
- layout->addWidget(titleLabel, 0, 1);
- } else {
- layout->addWidget(titleLabel, 0, 0, 1, 2);
- }
-
- layout->addWidget(closeButton, 0, 2);
- layout->addWidget(msgLabel, 1, 0, 1, 3);
- layout->setSizeConstraint(QLayout::SetFixedSize);
- layout->setMargin(3);
- setLayout(layout);
-
- QPalette pal = palette();
- pal.setColor(QPalette::Window, QColor(0xff, 0xff, 0xe1));
- pal.setColor(QPalette::WindowText, Qt::black);
- setPalette(pal);
-}
-
-QBalloonTip::~QBalloonTip()
-{
- theSolitaryBalloonTip = 0;
-}
-
-void QBalloonTip::paintEvent(QPaintEvent *)
-{
- QPainter painter(this);
- painter.drawPixmap(rect(), pixmap);
-}
-
-void QBalloonTip::resizeEvent(QResizeEvent *ev)
-{
- QWidget::resizeEvent(ev);
-}
-
-void QBalloonTip::balloon(const QPoint& pos, int msecs, bool showArrow)
-{
- QRect scr = QApplication::desktop()->screenGeometry(pos);
- QSize sh = sizeHint();
- const int border = 1;
- const int ah = 18, ao = 18, aw = 18, rc = 7;
- bool arrowAtTop = (pos.y() + sh.height() + ah < scr.height());
- bool arrowAtLeft = (pos.x() + sh.width() - ao < scr.width());
- setContentsMargins(border + 3, border + (arrowAtTop ? ah : 0) + 2, border + 3, border + (arrowAtTop ? 0 : ah) + 2);
- updateGeometry();
- sh = sizeHint();
-
- int ml, mr, mt, mb;
- QSize sz = sizeHint();
- if (!arrowAtTop) {
- ml = mt = 0;
- mr = sz.width() - 1;
- mb = sz.height() - ah - 1;
- } else {
- ml = 0;
- mt = ah;
- mr = sz.width() - 1;
- mb = sz.height() - 1;
- }
-
- QPainterPath path;
-#if defined(QT_NO_XSHAPE) && defined(Q_WS_X11)
- // XShape is required for setting the mask, so we just
- // draw an ugly square when its not available
- path.moveTo(0, 0);
- path.lineTo(sz.width() - 1, 0);
- path.lineTo(sz.width() - 1, sz.height() - 1);
- path.lineTo(0, sz.height() - 1);
- path.lineTo(0, 0);
- move(qMax(pos.x() - sz.width(), scr.left()), pos.y());
-#else
- path.moveTo(ml + rc, mt);
- if (arrowAtTop && arrowAtLeft) {
- if (showArrow) {
- path.lineTo(ml + ao, mt);
- path.lineTo(ml + ao, mt - ah);
- path.lineTo(ml + ao + aw, mt);
- }
- move(qMax(pos.x() - ao, scr.left() + 2), pos.y());
- } else if (arrowAtTop && !arrowAtLeft) {
- if (showArrow) {
- path.lineTo(mr - ao - aw, mt);
- path.lineTo(mr - ao, mt - ah);
- path.lineTo(mr - ao, mt);
- }
- move(qMin(pos.x() - sh.width() + ao, scr.right() - sh.width() - 2), pos.y());
- }
- path.lineTo(mr - rc, mt);
- path.arcTo(QRect(mr - rc*2, mt, rc*2, rc*2), 90, -90);
- path.lineTo(mr, mb - rc);
- path.arcTo(QRect(mr - rc*2, mb - rc*2, rc*2, rc*2), 0, -90);
- if (!arrowAtTop && !arrowAtLeft) {
- if (showArrow) {
- path.lineTo(mr - ao, mb);
- path.lineTo(mr - ao, mb + ah);
- path.lineTo(mr - ao - aw, mb);
- }
- move(qMin(pos.x() - sh.width() + ao, scr.right() - sh.width() - 2),
- pos.y() - sh.height());
- } else if (!arrowAtTop && arrowAtLeft) {
- if (showArrow) {
- path.lineTo(ao + aw, mb);
- path.lineTo(ao, mb + ah);
- path.lineTo(ao, mb);
- }
- move(qMax(pos.x() - ao, scr.x() + 2), pos.y() - sh.height());
- }
- path.lineTo(ml + rc, mb);
- path.arcTo(QRect(ml, mb - rc*2, rc*2, rc*2), -90, -90);
- path.lineTo(ml, mt + rc);
- path.arcTo(QRect(ml, mt, rc*2, rc*2), 180, -90);
-
- // Set the mask
- QBitmap bitmap = QBitmap(sizeHint());
- bitmap.fill(Qt::color0);
- QPainter painter1(&bitmap);
- painter1.setPen(QPen(Qt::color1, border));
- painter1.setBrush(QBrush(Qt::color1));
- painter1.drawPath(path);
- setMask(bitmap);
-#endif
-
- // Draw the border
- pixmap = QPixmap(sz);
- QPainter painter2(&pixmap);
- painter2.setPen(QPen(palette().color(QPalette::Window).darker(160), border));
- painter2.setBrush(palette().color(QPalette::Window));
- painter2.drawPath(path);
-
- if (msecs > 0)
- timerId = startTimer(msecs);
- show();
-}
-
-void QBalloonTip::mousePressEvent(QMouseEvent *e)
-{
- close();
- if(e->button() == Qt::LeftButton)
- emit trayIcon->messageClicked();
-}
-
-void QBalloonTip::timerEvent(QTimerEvent *e)
-{
- if (e->timerId() == timerId) {
- killTimer(timerId);
- if (!underMouse())
- close();
- return;
- }
- QWidget::timerEvent(e);
-}
-
-void qtsystray_sendActivated(QSystemTrayIcon *i, int r)
-{
- emit i->activated((QSystemTrayIcon::ActivationReason)r);
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_SYSTEMTRAYICON
diff --git a/src/gui/util/qsystemtrayicon.h b/src/gui/util/qsystemtrayicon.h
deleted file mode 100644
index 879a0d293f..0000000000
--- a/src/gui/util/qsystemtrayicon.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSYSTEMTRAYICON_H
-#define QSYSTEMTRAYICON_H
-
-#include <QtCore/qobject.h>
-
-#ifndef QT_NO_SYSTEMTRAYICON
-
-#include <QtGui/qicon.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QSystemTrayIconPrivate;
-
-class QMenu;
-class QEvent;
-class QWheelEvent;
-class QMouseEvent;
-class QPoint;
-
-class Q_GUI_EXPORT QSystemTrayIcon : public QObject
-{
- Q_OBJECT
- Q_PROPERTY(QString toolTip READ toolTip WRITE setToolTip)
- Q_PROPERTY(QIcon icon READ icon WRITE setIcon)
- Q_PROPERTY(bool visible READ isVisible WRITE setVisible DESIGNABLE false)
-
-public:
- QSystemTrayIcon(QObject *parent = 0);
- QSystemTrayIcon(const QIcon &icon, QObject *parent = 0);
- ~QSystemTrayIcon();
-
- enum ActivationReason {
- Unknown,
- Context,
- DoubleClick,
- Trigger,
- MiddleClick
- };
-
-#ifndef QT_NO_MENU
- void setContextMenu(QMenu *menu);
- QMenu *contextMenu() const;
-#endif
-
- QIcon icon() const;
- void setIcon(const QIcon &icon);
-
- QString toolTip() const;
- void setToolTip(const QString &tip);
-
- static bool isSystemTrayAvailable();
- static bool supportsMessages();
-
- enum MessageIcon { NoIcon, Information, Warning, Critical };
- void showMessage(const QString &title, const QString &msg,
- MessageIcon icon = Information, int msecs = 10000);
-
- QRect geometry() const;
- bool isVisible() const;
-
-public Q_SLOTS:
- void setVisible(bool visible);
- inline void show() { setVisible(true); }
- inline void hide() { setVisible(false); }
-
-Q_SIGNALS:
- void activated(QSystemTrayIcon::ActivationReason reason);
- void messageClicked();
-
-protected:
- bool event(QEvent *event);
-
-private:
- Q_DISABLE_COPY(QSystemTrayIcon)
- Q_DECLARE_PRIVATE(QSystemTrayIcon)
-
- friend class QSystemTrayIconSys;
- friend class QBalloonTip;
- friend void qtsystray_sendActivated(QSystemTrayIcon *, int);
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QT_NO_SYSTEMTRAYICON
-#endif // QSYSTEMTRAYICON_H
diff --git a/src/gui/util/qsystemtrayicon_p.h b/src/gui/util/qsystemtrayicon_p.h
deleted file mode 100644
index 14495eee59..0000000000
--- a/src/gui/util/qsystemtrayicon_p.h
+++ /dev/null
@@ -1,186 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSYSTEMTRAYICON_P_H
-#define QSYSTEMTRAYICON_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of a number of Qt sources files. This header file may change from
-// version to version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qsystemtrayicon.h"
-#include "private/qobject_p.h"
-
-#ifndef QT_NO_SYSTEMTRAYICON
-
-#include "QtGui/qmenu.h"
-#include "QtGui/qpixmap.h"
-#include "QtCore/qstring.h"
-#include "QtCore/qpointer.h"
-
-QT_BEGIN_NAMESPACE
-
-class QSystemTrayIconSys;
-class QToolButton;
-class QLabel;
-
-class QSystemTrayIconPrivate : public QObjectPrivate
-{
- Q_DECLARE_PUBLIC(QSystemTrayIcon)
-
-public:
- QSystemTrayIconPrivate() : sys(0), visible(false) { }
-
- void install_sys();
- void remove_sys();
- void updateIcon_sys();
- void updateToolTip_sys();
- void updateMenu_sys();
- QRect geometry_sys() const;
- void showMessage_sys(const QString &msg, const QString &title, QSystemTrayIcon::MessageIcon icon, int secs);
-
- static bool isSystemTrayAvailable_sys();
- static bool supportsMessages_sys();
-
- QPointer<QMenu> menu;
- QIcon icon;
- QString toolTip;
- QSystemTrayIconSys *sys;
- bool visible;
-};
-
-class QBalloonTip : public QWidget
-{
- Q_OBJECT
-public:
- static void showBalloon(QSystemTrayIcon::MessageIcon icon, const QString& title,
- const QString& msg, QSystemTrayIcon *trayIcon,
- const QPoint& pos, int timeout, bool showArrow = true);
- static void hideBalloon();
- static bool isBalloonVisible();
-
-private:
- QBalloonTip(QSystemTrayIcon::MessageIcon icon, const QString& title,
- const QString& msg, QSystemTrayIcon *trayIcon);
- ~QBalloonTip();
- void balloon(const QPoint&, int, bool);
-
-protected:
- void paintEvent(QPaintEvent *);
- void resizeEvent(QResizeEvent *);
- void mousePressEvent(QMouseEvent *e);
- void timerEvent(QTimerEvent *e);
-
-private:
- QSystemTrayIcon *trayIcon;
- QPixmap pixmap;
- int timerId;
-};
-
-#if defined(Q_WS_X11)
-QT_BEGIN_INCLUDE_NAMESPACE
-#include <QtCore/qcoreapplication.h>
-#include <X11/Xlib.h>
-#include <X11/Xatom.h>
-#include <X11/Xutil.h>
-QT_END_INCLUDE_NAMESPACE
-
-class QSystemTrayIconSys : public QWidget
-{
- friend class QSystemTrayIconPrivate;
-
-public:
- QSystemTrayIconSys(QSystemTrayIcon *q);
- ~QSystemTrayIconSys();
- enum {
- SYSTEM_TRAY_REQUEST_DOCK = 0,
- SYSTEM_TRAY_BEGIN_MESSAGE = 1,
- SYSTEM_TRAY_CANCEL_MESSAGE =2
- };
-
- void addToTray();
- void updateIcon();
- XVisualInfo* getSysTrayVisualInfo();
-
- // QObject::event is public but QWidget's ::event() re-implementation
- // is protected ;(
- inline bool deliverToolTipEvent(QEvent *e)
- { return QWidget::event(e); }
-
- static Window sysTrayWindow;
- static QList<QSystemTrayIconSys *> trayIcons;
- static QCoreApplication::EventFilter oldEventFilter;
- static bool sysTrayTracker(void *message, long *result);
- static Window locateSystemTray();
- static Atom sysTraySelection;
- static XVisualInfo sysTrayVisual;
-
-protected:
- void paintEvent(QPaintEvent *pe);
- void resizeEvent(QResizeEvent *re);
- bool x11Event(XEvent *event);
- void mousePressEvent(QMouseEvent *event);
- void mouseDoubleClickEvent(QMouseEvent *event);
-#ifndef QT_NO_WHEELEVENT
- void wheelEvent(QWheelEvent *event);
-#endif
- bool event(QEvent *e);
-
-private:
- QPixmap background;
- QSystemTrayIcon *q;
- Colormap colormap;
-};
-#endif // Q_WS_X11
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_SYSTEMTRAYICON
-
-#endif // QSYSTEMTRAYICON_P_H
-
diff --git a/src/gui/util/qundogroup.h b/src/gui/util/qundogroup.h
deleted file mode 100644
index 99026fc077..0000000000
--- a/src/gui/util/qundogroup.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QUNDOGROUP_H
-#define QUNDOGROUP_H
-
-#include <QtCore/qobject.h>
-#include <QtCore/qstring.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-class QUndoGroupPrivate;
-class QUndoStack;
-class QAction;
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_UNDOGROUP
-
-class Q_GUI_EXPORT QUndoGroup : public QObject
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QUndoGroup)
-
-public:
- explicit QUndoGroup(QObject *parent = 0);
- ~QUndoGroup();
-
- void addStack(QUndoStack *stack);
- void removeStack(QUndoStack *stack);
- QList<QUndoStack*> stacks() const;
- QUndoStack *activeStack() const;
-
-#ifndef QT_NO_ACTION
- QAction *createUndoAction(QObject *parent,
- const QString &prefix = QString()) const;
- QAction *createRedoAction(QObject *parent,
- const QString &prefix = QString()) const;
-#endif // QT_NO_ACTION
- bool canUndo() const;
- bool canRedo() const;
- QString undoText() const;
- QString redoText() const;
- bool isClean() const;
-
-public Q_SLOTS:
- void undo();
- void redo();
- void setActiveStack(QUndoStack *stack);
-
-Q_SIGNALS:
- void activeStackChanged(QUndoStack *stack);
- void indexChanged(int idx);
- void cleanChanged(bool clean);
- void canUndoChanged(bool canUndo);
- void canRedoChanged(bool canRedo);
- void undoTextChanged(const QString &undoText);
- void redoTextChanged(const QString &redoText);
-
-private:
- Q_DISABLE_COPY(QUndoGroup)
-};
-
-#endif // QT_NO_UNDOGROUP
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QUNDOGROUP_H
diff --git a/src/gui/util/qundostack.h b/src/gui/util/qundostack.h
deleted file mode 100644
index 2cbbc0ad4a..0000000000
--- a/src/gui/util/qundostack.h
+++ /dev/null
@@ -1,159 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QUNDOSTACK_H
-#define QUNDOSTACK_H
-
-#include <QtCore/qobject.h>
-#include <QtCore/qstring.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QAction;
-class QUndoCommandPrivate;
-class QUndoStackPrivate;
-
-#ifndef QT_NO_UNDOCOMMAND
-
-class Q_GUI_EXPORT QUndoCommand
-{
- QUndoCommandPrivate *d;
-
-public:
- explicit QUndoCommand(QUndoCommand *parent = 0);
- explicit QUndoCommand(const QString &text, QUndoCommand *parent = 0);
- virtual ~QUndoCommand();
-
- virtual void undo();
- virtual void redo();
-
- QString text() const;
- QString actionText() const;
- void setText(const QString &text);
-
- virtual int id() const;
- virtual bool mergeWith(const QUndoCommand *other);
-
- int childCount() const;
- const QUndoCommand *child(int index) const;
-
-private:
- Q_DISABLE_COPY(QUndoCommand)
- friend class QUndoStack;
-};
-
-#endif // QT_NO_UNDOCOMMAND
-
-#ifndef QT_NO_UNDOSTACK
-
-class Q_GUI_EXPORT QUndoStack : public QObject
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QUndoStack)
- Q_PROPERTY(bool active READ isActive WRITE setActive)
- Q_PROPERTY(int undoLimit READ undoLimit WRITE setUndoLimit)
-
-public:
- explicit QUndoStack(QObject *parent = 0);
- ~QUndoStack();
- void clear();
-
- void push(QUndoCommand *cmd);
-
- bool canUndo() const;
- bool canRedo() const;
- QString undoText() const;
- QString redoText() const;
-
- int count() const;
- int index() const;
- QString text(int idx) const;
-
-#ifndef QT_NO_ACTION
- QAction *createUndoAction(QObject *parent,
- const QString &prefix = QString()) const;
- QAction *createRedoAction(QObject *parent,
- const QString &prefix = QString()) const;
-#endif // QT_NO_ACTION
-
- bool isActive() const;
- bool isClean() const;
- int cleanIndex() const;
-
- void beginMacro(const QString &text);
- void endMacro();
-
- void setUndoLimit(int limit);
- int undoLimit() const;
-
- const QUndoCommand *command(int index) const;
-
-public Q_SLOTS:
- void setClean();
- void setIndex(int idx);
- void undo();
- void redo();
- void setActive(bool active = true);
-
-Q_SIGNALS:
- void indexChanged(int idx);
- void cleanChanged(bool clean);
- void canUndoChanged(bool canUndo);
- void canRedoChanged(bool canRedo);
- void undoTextChanged(const QString &undoText);
- void redoTextChanged(const QString &redoText);
-
-private:
- Q_DISABLE_COPY(QUndoStack)
- friend class QUndoGroup;
-};
-
-#endif // QT_NO_UNDOSTACK
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QUNDOSTACK_H
diff --git a/src/gui/util/qundostack_p.h b/src/gui/util/qundostack_p.h
deleted file mode 100644
index 7162e19842..0000000000
--- a/src/gui/util/qundostack_p.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QUNDOSTACK_P_H
-#define QUNDOSTACK_P_H
-
-#include <private/qobject_p.h>
-#include <QtCore/qlist.h>
-#include <QtCore/qstring.h>
-#include <QtGui/qaction.h>
-
-#include "qundostack.h"
-
-QT_BEGIN_NAMESPACE
-class QUndoCommand;
-class QUndoGroup;
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header
-// file may change from version to version without notice, or even be removed.
-//
-// We mean it.
-//
-
-class QUndoCommandPrivate
-{
-public:
- QUndoCommandPrivate() : id(-1) {}
- QList<QUndoCommand*> child_list;
- QString text;
- QString actionText;
- int id;
-};
-
-#ifndef QT_NO_UNDOSTACK
-
-class QUndoStackPrivate : public QObjectPrivate
-{
- Q_DECLARE_PUBLIC(QUndoStack)
-public:
- QUndoStackPrivate() : index(0), clean_index(0), group(0), undo_limit(0) {}
-
- QList<QUndoCommand*> command_list;
- QList<QUndoCommand*> macro_stack;
- int index;
- int clean_index;
- QUndoGroup *group;
- int undo_limit;
-
- void setIndex(int idx, bool clean);
- bool checkUndoLimit();
-};
-
-#ifndef QT_NO_ACTION
-class QUndoAction : public QAction
-{
- Q_OBJECT
-public:
- QUndoAction(const QString &prefix, QObject *parent = 0);
- void setTextFormat(const QString &textFormat, const QString &defaultText);
-public Q_SLOTS:
- void setPrefixedText(const QString &text);
-private:
- QString m_prefix;
- QString m_defaultText;
-};
-#endif // QT_NO_ACTION
-
-
-QT_END_NAMESPACE
-#endif // QT_NO_UNDOSTACK
-#endif // QUNDOSTACK_P_H
diff --git a/src/gui/util/qundoview.cpp b/src/gui/util/qundoview.cpp
deleted file mode 100644
index d0f411105b..0000000000
--- a/src/gui/util/qundoview.cpp
+++ /dev/null
@@ -1,476 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qundostack.h"
-#include "qundoview.h"
-
-#ifndef QT_NO_UNDOVIEW
-
-#include "qundogroup.h"
-#include <QtCore/qabstractitemmodel.h>
-#include <QtCore/qpointer.h>
-#include <QtGui/qicon.h>
-#include <private/qlistview_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QUndoModel : public QAbstractItemModel
-{
- Q_OBJECT
-public:
- QUndoModel(QObject *parent = 0);
-
- QUndoStack *stack() const;
-
- virtual QModelIndex index(int row, int column,
- const QModelIndex &parent = QModelIndex()) const;
- virtual QModelIndex parent(const QModelIndex &child) const;
- virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
- virtual int columnCount(const QModelIndex &parent = QModelIndex()) const;
- virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
-
- QModelIndex selectedIndex() const;
- QItemSelectionModel *selectionModel() const;
-
- QString emptyLabel() const;
- void setEmptyLabel(const QString &label);
-
- void setCleanIcon(const QIcon &icon);
- QIcon cleanIcon() const;
-
-public slots:
- void setStack(QUndoStack *stack);
-
-private slots:
- void stackChanged();
- void stackDestroyed(QObject *obj);
- void setStackCurrentIndex(const QModelIndex &index);
-
-private:
- QUndoStack *m_stack;
- QItemSelectionModel *m_sel_model;
- QString m_emty_label;
- QIcon m_clean_icon;
-};
-
-QUndoModel::QUndoModel(QObject *parent)
- : QAbstractItemModel(parent)
-{
- m_stack = 0;
- m_sel_model = new QItemSelectionModel(this, this);
- connect(m_sel_model, SIGNAL(currentChanged(QModelIndex,QModelIndex)),
- this, SLOT(setStackCurrentIndex(QModelIndex)));
- m_emty_label = tr("<empty>");
-}
-
-QItemSelectionModel *QUndoModel::selectionModel() const
-{
- return m_sel_model;
-}
-
-QUndoStack *QUndoModel::stack() const
-{
- return m_stack;
-}
-
-void QUndoModel::setStack(QUndoStack *stack)
-{
- if (m_stack == stack)
- return;
-
- if (m_stack != 0) {
- disconnect(m_stack, SIGNAL(cleanChanged(bool)), this, SLOT(stackChanged()));
- disconnect(m_stack, SIGNAL(indexChanged(int)), this, SLOT(stackChanged()));
- disconnect(m_stack, SIGNAL(destroyed(QObject*)), this, SLOT(stackDestroyed(QObject*)));
- }
- m_stack = stack;
- if (m_stack != 0) {
- connect(m_stack, SIGNAL(cleanChanged(bool)), this, SLOT(stackChanged()));
- connect(m_stack, SIGNAL(indexChanged(int)), this, SLOT(stackChanged()));
- connect(m_stack, SIGNAL(destroyed(QObject*)), this, SLOT(stackDestroyed(QObject*)));
- }
-
- stackChanged();
-}
-
-void QUndoModel::stackDestroyed(QObject *obj)
-{
- if (obj != m_stack)
- return;
- m_stack = 0;
-
- stackChanged();
-}
-
-void QUndoModel::stackChanged()
-{
- reset();
- m_sel_model->setCurrentIndex(selectedIndex(), QItemSelectionModel::ClearAndSelect);
-}
-
-void QUndoModel::setStackCurrentIndex(const QModelIndex &index)
-{
- if (m_stack == 0)
- return;
-
- if (index == selectedIndex())
- return;
-
- if (index.column() != 0)
- return;
-
- m_stack->setIndex(index.row());
-}
-
-QModelIndex QUndoModel::selectedIndex() const
-{
- return m_stack == 0 ? QModelIndex() : createIndex(m_stack->index(), 0);
-}
-
-QModelIndex QUndoModel::index(int row, int column, const QModelIndex &parent) const
-{
- if (m_stack == 0)
- return QModelIndex();
-
- if (parent.isValid())
- return QModelIndex();
-
- if (column != 0)
- return QModelIndex();
-
- if (row < 0 || row > m_stack->count())
- return QModelIndex();
-
- return createIndex(row, column);
-}
-
-QModelIndex QUndoModel::parent(const QModelIndex&) const
-{
- return QModelIndex();
-}
-
-int QUndoModel::rowCount(const QModelIndex &parent) const
-{
- if (m_stack == 0)
- return 0;
-
- if (parent.isValid())
- return 0;
-
- return m_stack->count() + 1;
-}
-
-int QUndoModel::columnCount(const QModelIndex&) const
-{
- return 1;
-}
-
-QVariant QUndoModel::data(const QModelIndex &index, int role) const
-{
- if (m_stack == 0)
- return QVariant();
-
- if (index.column() != 0)
- return QVariant();
-
- if (index.row() < 0 || index.row() > m_stack->count())
- return QVariant();
-
- if (role == Qt::DisplayRole) {
- if (index.row() == 0)
- return m_emty_label;
- return m_stack->text(index.row() - 1);
- } else if (role == Qt::DecorationRole) {
- if (index.row() == m_stack->cleanIndex() && !m_clean_icon.isNull())
- return m_clean_icon;
- return QVariant();
- }
-
- return QVariant();
-}
-
-QString QUndoModel::emptyLabel() const
-{
- return m_emty_label;
-}
-
-void QUndoModel::setEmptyLabel(const QString &label)
-{
- m_emty_label = label;
- stackChanged();
-}
-
-void QUndoModel::setCleanIcon(const QIcon &icon)
-{
- m_clean_icon = icon;
- stackChanged();
-}
-
-QIcon QUndoModel::cleanIcon() const
-{
- return m_clean_icon;
-}
-
-/*!
- \class QUndoView
- \brief The QUndoView class displays the contents of a QUndoStack.
- \since 4.2
-
- \ingroup advanced
-
- QUndoView is a QListView which displays the list of commands pushed on an undo stack.
- The most recently executed command is always selected. Selecting a different command
- results in a call to QUndoStack::setIndex(), rolling the state of the document
- backwards or forward to the new command.
-
- The stack can be set explicitly with setStack(). Alternatively, a QUndoGroup object can
- be set with setGroup(). The view will then update itself automatically whenever the
- active stack of the group changes.
-
- \image qundoview.png
-*/
-
-class QUndoViewPrivate : public QListViewPrivate
-{
- Q_DECLARE_PUBLIC(QUndoView)
-public:
- QUndoViewPrivate() :
-#ifndef QT_NO_UNDOGROUP
- group(0),
-#endif
- model(0) {}
-
-#ifndef QT_NO_UNDOGROUP
- QPointer<QUndoGroup> group;
-#endif
- QUndoModel *model;
-
- void init();
-};
-
-void QUndoViewPrivate::init()
-{
- Q_Q(QUndoView);
-
- model = new QUndoModel(q);
- q->setModel(model);
- q->setSelectionModel(model->selectionModel());
-}
-
-/*!
- Constructs a new view with parent \a parent.
-*/
-
-QUndoView::QUndoView(QWidget *parent)
- : QListView(*new QUndoViewPrivate(), parent)
-{
- Q_D(QUndoView);
- d->init();
-}
-
-/*!
- Constructs a new view with parent \a parent and sets the observed stack to \a stack.
-*/
-
-QUndoView::QUndoView(QUndoStack *stack, QWidget *parent)
- : QListView(*new QUndoViewPrivate(), parent)
-{
- Q_D(QUndoView);
- d->init();
- setStack(stack);
-}
-
-#ifndef QT_NO_UNDOGROUP
-
-/*!
- Constructs a new view with parent \a parent and sets the observed group to \a group.
-
- The view will update itself autmiatically whenever the active stack of the group changes.
-*/
-
-QUndoView::QUndoView(QUndoGroup *group, QWidget *parent)
- : QListView(*new QUndoViewPrivate(), parent)
-{
- Q_D(QUndoView);
- d->init();
- setGroup(group);
-}
-
-#endif // QT_NO_UNDOGROUP
-
-/*!
- Destroys this view.
-*/
-
-QUndoView::~QUndoView()
-{
-}
-
-/*!
- Returns the stack currently displayed by this view. If the view is looking at a
- QUndoGroup, this the group's active stack.
-
- \sa setStack() setGroup()
-*/
-
-QUndoStack *QUndoView::stack() const
-{
- Q_D(const QUndoView);
- return d->model->stack();
-}
-
-/*!
- Sets the stack displayed by this view to \a stack. If \a stack is 0, the view
- will be empty.
-
- If the view was previously looking at a QUndoGroup, the group is set to 0.
-
- \sa stack() setGroup()
-*/
-
-void QUndoView::setStack(QUndoStack *stack)
-{
- Q_D(QUndoView);
-#ifndef QT_NO_UNDOGROUP
- setGroup(0);
-#endif
- d->model->setStack(stack);
-}
-
-#ifndef QT_NO_UNDOGROUP
-
-/*!
- Sets the group displayed by this view to \a group. If \a group is 0, the view will
- be empty.
-
- The view will update itself autmiatically whenever the active stack of the group changes.
-
- \sa group() setStack()
-*/
-
-void QUndoView::setGroup(QUndoGroup *group)
-{
- Q_D(QUndoView);
-
- if (d->group == group)
- return;
-
- if (d->group != 0) {
- disconnect(d->group, SIGNAL(activeStackChanged(QUndoStack*)),
- d->model, SLOT(setStack(QUndoStack*)));
- }
-
- d->group = group;
-
- if (d->group != 0) {
- connect(d->group, SIGNAL(activeStackChanged(QUndoStack*)),
- d->model, SLOT(setStack(QUndoStack*)));
- d->model->setStack(d->group->activeStack());
- } else {
- d->model->setStack(0);
- }
-}
-
-/*!
- Returns the group displayed by this view.
-
- If the view is not looking at group, this function returns 0.
-
- \sa setGroup() setStack()
-*/
-
-QUndoGroup *QUndoView::group() const
-{
- Q_D(const QUndoView);
- return d->group;
-}
-
-#endif // QT_NO_UNDOGROUP
-
-/*!
- \property QUndoView::emptyLabel
- \brief the label used for the empty state.
-
- The empty label is the topmost element in the list of commands, which represents
- the state of the document before any commands were pushed on the stack. The default
- is the string "<empty>".
-*/
-
-void QUndoView::setEmptyLabel(const QString &label)
-{
- Q_D(QUndoView);
- d->model->setEmptyLabel(label);
-}
-
-QString QUndoView::emptyLabel() const
-{
- Q_D(const QUndoView);
- return d->model->emptyLabel();
-}
-
-/*!
- \property QUndoView::cleanIcon
- \brief the icon used to represent the clean state.
-
- A stack may have a clean state set with QUndoStack::setClean(). This is usually
- the state of the document at the point it was saved. QUndoView can display an
- icon in the list of commands to show the clean state. If this property is
- a null icon, no icon is shown. The default value is the null icon.
-*/
-
-void QUndoView::setCleanIcon(const QIcon &icon)
-{
- Q_D(const QUndoView);
- d->model->setCleanIcon(icon);
-
-}
-
-QIcon QUndoView::cleanIcon() const
-{
- Q_D(const QUndoView);
- return d->model->cleanIcon();
-}
-
-QT_END_NAMESPACE
-
-#include "qundoview.moc"
-
-#endif // QT_NO_UNDOVIEW
diff --git a/src/gui/util/qundoview.h b/src/gui/util/qundoview.h
deleted file mode 100644
index 5c3801ddea..0000000000
--- a/src/gui/util/qundoview.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QUNDOVIEW_H
-#define QUNDOVIEW_H
-
-#include <QtGui/qlistview.h>
-#include <QtCore/qstring.h>
-
-#ifndef QT_NO_UNDOVIEW
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-class QUndoViewPrivate;
-class QUndoStack;
-class QUndoGroup;
-class QIcon;
-
-QT_MODULE(Gui)
-
-class Q_GUI_EXPORT QUndoView : public QListView
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QUndoView)
- Q_PROPERTY(QString emptyLabel READ emptyLabel WRITE setEmptyLabel)
- Q_PROPERTY(QIcon cleanIcon READ cleanIcon WRITE setCleanIcon)
-
-public:
- explicit QUndoView(QWidget *parent = 0);
- explicit QUndoView(QUndoStack *stack, QWidget *parent = 0);
-#ifndef QT_NO_UNDOGROUP
- explicit QUndoView(QUndoGroup *group, QWidget *parent = 0);
-#endif
- ~QUndoView();
-
- QUndoStack *stack() const;
-#ifndef QT_NO_UNDOGROUP
- QUndoGroup *group() const;
-#endif
-
- void setEmptyLabel(const QString &label);
- QString emptyLabel() const;
-
- void setCleanIcon(const QIcon &icon);
- QIcon cleanIcon() const;
-
-public Q_SLOTS:
- void setStack(QUndoStack *stack);
-#ifndef QT_NO_UNDOGROUP
- void setGroup(QUndoGroup *group);
-#endif
-
-private:
- Q_DISABLE_COPY(QUndoView)
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QT_NO_UNDOVIEW
-#endif // QUNDOVIEW_H
diff --git a/src/gui/widgets/qvalidator.cpp b/src/gui/util/qvalidator.cpp
index 43251a8829..43251a8829 100644
--- a/src/gui/widgets/qvalidator.cpp
+++ b/src/gui/util/qvalidator.cpp
diff --git a/src/gui/widgets/qvalidator.h b/src/gui/util/qvalidator.h
index cb0436cc3e..cb0436cc3e 100644
--- a/src/gui/widgets/qvalidator.h
+++ b/src/gui/util/qvalidator.h
diff --git a/src/gui/util/util.pri b/src/gui/util/util.pri
index 2814a2d30a..dfb221667e 100644
--- a/src/gui/util/util.pri
+++ b/src/gui/util/util.pri
@@ -1,71 +1,10 @@
# Qt util module
HEADERS += \
- util/qsystemtrayicon.h \
- util/qcompleter.h \
- util/qcompleter_p.h \
util/qdesktopservices.h \
- util/qsystemtrayicon_p.h \
- util/qscroller.h \
- util/qscroller_p.h \
- util/qscrollerproperties.h \
- util/qscrollerproperties_p.h \
- util/qflickgesture_p.h \
- util/qundogroup.h \
- util/qundostack.h \
- util/qundostack_p.h \
- util/qundoview.h
+ util/qhexstring_p.h \
+ util/qvalidator.h
SOURCES += \
- util/qsystemtrayicon.cpp \
- util/qcompleter.cpp \
util/qdesktopservices.cpp \
- util/qscroller.cpp \
- util/qscrollerproperties.cpp \
- util/qflickgesture.cpp \
- util/qundogroup.cpp \
- util/qundostack.cpp \
- util/qundoview.cpp
-
-
-wince* {
- SOURCES += \
- util/qsystemtrayicon_wince.cpp
-} else:win32 {
- SOURCES += \
- util/qsystemtrayicon_win.cpp
-}
-
-unix:x11 {
- SOURCES += \
- util/qsystemtrayicon_x11.cpp
-}
-
-embedded|qpa {
- SOURCES += \
- util/qsystemtrayicon_qws.cpp
-}
-
-!embedded:!qpa:!x11:mac {
- OBJECTIVE_SOURCES += util/qsystemtrayicon_mac.mm
-}
-
-symbian {
- LIBS += -letext -lplatformenv
- contains(S60_VERSION, 3.1)|contains(S60_VERSION, 3.2)|contains(S60_VERSION, 5.0) {
- LIBS += -lsendas2 -lapmime
- contains(QT_CONFIG, s60) {
- contains(CONFIG, is_using_gnupoc) {
- LIBS += -lcommonui
- } else {
- LIBS += -lCommonUI
- }
- }
- } else {
- DEFINES += USE_SCHEMEHANDLER
- }
-}
-
-macx {
- OBJECTIVE_SOURCES += util/qscroller_mac.mm
-}
+ util/qvalidator.cpp
diff --git a/src/gui/widgets/qabstractbutton.cpp b/src/gui/widgets/qabstractbutton.cpp
deleted file mode 100644
index 57e517ab25..0000000000
--- a/src/gui/widgets/qabstractbutton.cpp
+++ /dev/null
@@ -1,1470 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qabstractbutton.h"
-#include "qabstractitemview.h"
-#include "qbuttongroup.h"
-#include "qabstractbutton_p.h"
-#include "qevent.h"
-#include "qpainter.h"
-#include "qapplication.h"
-#include "qstyle.h"
-#include "qaction.h"
-#ifndef QT_NO_ACCESSIBILITY
-#include "qaccessible.h"
-#endif
-
-QT_BEGIN_NAMESPACE
-
-#define AUTO_REPEAT_DELAY 300
-#define AUTO_REPEAT_INTERVAL 100
-
-Q_GUI_EXPORT extern bool qt_tab_all_widgets;
-
-/*!
- \class QAbstractButton
-
- \brief The QAbstractButton class is the abstract base class of
- button widgets, providing functionality common to buttons.
-
- \ingroup abstractwidgets
-
- This class implements an \e abstract button.
- Subclasses of this class handle user actions, and specify how the button
- is drawn.
-
- QAbstractButton provides support for both push buttons and checkable
- (toggle) buttons. Checkable buttons are implemented in the QRadioButton
- and QCheckBox classes. Push buttons are implemented in the
- QPushButton and QToolButton classes; these also provide toggle
- behavior if required.
-
- Any button can display a label containing text and an icon. setText()
- sets the text; setIcon() sets the icon. If a button is disabled, its label
- is changed to give the button a "disabled" appearance.
-
- If the button is a text button with a string containing an
- ampersand ('&'), QAbstractButton automatically creates a shortcut
- key. For example:
-
- \snippet doc/src/snippets/code/src_gui_widgets_qabstractbutton.cpp 0
-
- The \key Alt+C shortcut is assigned to the button, i.e., when the
- user presses \key Alt+C the button will call animateClick(). See
- the \l {QShortcut#mnemonic}{QShortcut} documentation for details
- (to display an actual ampersand, use '&&').
-
- You can also set a custom shortcut key using the setShortcut()
- function. This is useful mostly for buttons that do not have any
- text, because they have no automatic shortcut.
-
- \snippet doc/src/snippets/code/src_gui_widgets_qabstractbutton.cpp 1
-
- All of the buttons provided by Qt (QPushButton, QToolButton,
- QCheckBox, and QRadioButton) can display both \l text and \l{icon}{icons}.
-
- A button can be made the default button in a dialog are provided by
- QPushButton::setDefault() and QPushButton::setAutoDefault().
-
- QAbstractButton provides most of the states used for buttons:
-
- \list
-
- \o isDown() indicates whether the button is \e pressed down.
-
- \o isChecked() indicates whether the button is \e checked. Only
- checkable buttons can be checked and unchecked (see below).
-
- \o isEnabled() indicates whether the button can be pressed by the
- user.
-
- \o setAutoRepeat() sets whether the button will auto-repeat if the
- user holds it down. \l autoRepeatDelay and \l autoRepeatInterval
- define how auto-repetition is done.
-
- \o setCheckable() sets whether the button is a toggle button or not.
-
- \endlist
-
- The difference between isDown() and isChecked() is as follows.
- When the user clicks a toggle button to check it, the button is first
- \e pressed then released into the \e checked state. When the user
- clicks it again (to uncheck it), the button moves first to the
- \e pressed state, then to the \e unchecked state (isChecked() and
- isDown() are both false).
-
- QAbstractButton provides four signals:
-
- \list 1
-
- \o pressed() is emitted when the left mouse button is pressed while
- the mouse cursor is inside the button.
-
- \o released() is emitted when the left mouse button is released.
-
- \o clicked() is emitted when the button is first pressed and then
- released, when the shortcut key is typed, or when click() or
- animateClick() is called.
-
- \o toggled() is emitted when the state of a toggle button changes.
-
- \endlist
-
- To subclass QAbstractButton, you must reimplement at least
- paintEvent() to draw the button's outline and its text or pixmap. It
- is generally advisable to reimplement sizeHint() as well, and
- sometimes hitButton() (to determine whether a button press is within
- the button). For buttons with more than two states (like tri-state
- buttons), you will also have to reimplement checkStateSet() and
- nextCheckState().
-
- \sa QButtonGroup
-*/
-
-QAbstractButtonPrivate::QAbstractButtonPrivate(QSizePolicy::ControlType type)
- :
-#ifndef QT_NO_SHORTCUT
- shortcutId(0),
-#endif
- checkable(false), checked(false), autoRepeat(false), autoExclusive(false),
- down(false), blockRefresh(false), pressed(false),
-#ifndef QT_NO_BUTTONGROUP
- group(0),
-#endif
- autoRepeatDelay(AUTO_REPEAT_DELAY),
- autoRepeatInterval(AUTO_REPEAT_INTERVAL),
- controlType(type)
-{}
-
-#ifndef QT_NO_BUTTONGROUP
-
-class QButtonGroupPrivate: public QObjectPrivate
-{
- Q_DECLARE_PUBLIC(QButtonGroup)
-
-public:
- QButtonGroupPrivate():exclusive(true){}
- QList<QAbstractButton *> buttonList;
- QPointer<QAbstractButton> checkedButton;
- void detectCheckedButton();
- void notifyChecked(QAbstractButton *button);
- bool exclusive;
- QMap<QAbstractButton*, int> mapping;
-};
-
-QButtonGroup::QButtonGroup(QObject *parent)
- : QObject(*new QButtonGroupPrivate, parent)
-{
-}
-
-QButtonGroup::~QButtonGroup()
-{
- Q_D(QButtonGroup);
- for (int i = 0; i < d->buttonList.count(); ++i)
- d->buttonList.at(i)->d_func()->group = 0;
-}
-
-
-bool QButtonGroup::exclusive() const
-{
- Q_D(const QButtonGroup);
- return d->exclusive;
-}
-
-void QButtonGroup::setExclusive(bool exclusive)
-{
- Q_D(QButtonGroup);
- d->exclusive = exclusive;
-}
-
-
-// TODO: Qt 5: Merge with addButton(QAbstractButton *button, int id)
-void QButtonGroup::addButton(QAbstractButton *button)
-{
- addButton(button, -1);
-}
-
-void QButtonGroup::addButton(QAbstractButton *button, int id)
-{
- Q_D(QButtonGroup);
- if (QButtonGroup *previous = button->d_func()->group)
- previous->removeButton(button);
- button->d_func()->group = this;
- d->buttonList.append(button);
- if (id == -1) {
- QList<int> ids = d->mapping.values();
- if (ids.isEmpty())
- d->mapping[button] = -2;
- else {
- qSort(ids);
- d->mapping[button] = ids.first()-1;
- }
- } else {
- d->mapping[button] = id;
- }
-
- if (d->exclusive && button->isChecked())
- button->d_func()->notifyChecked();
-}
-
-void QButtonGroup::removeButton(QAbstractButton *button)
-{
- Q_D(QButtonGroup);
- if (d->checkedButton == button) {
- d->detectCheckedButton();
- }
- if (button->d_func()->group == this) {
- button->d_func()->group = 0;
- d->buttonList.removeAll(button);
- d->mapping.remove(button);
- }
-}
-
-QList<QAbstractButton*> QButtonGroup::buttons() const
-{
- Q_D(const QButtonGroup);
- return d->buttonList;
-}
-
-QAbstractButton *QButtonGroup::checkedButton() const
-{
- Q_D(const QButtonGroup);
- return d->checkedButton;
-}
-
-QAbstractButton *QButtonGroup::button(int id) const
-{
- Q_D(const QButtonGroup);
- return d->mapping.key(id);
-}
-
-void QButtonGroup::setId(QAbstractButton *button, int id)
-{
- Q_D(QButtonGroup);
- if (button && id != -1)
- d->mapping[button] = id;
-}
-
-int QButtonGroup::id(QAbstractButton *button) const
-{
- Q_D(const QButtonGroup);
- return d->mapping.value(button, -1);
-}
-
-int QButtonGroup::checkedId() const
-{
- Q_D(const QButtonGroup);
- return d->mapping.value(d->checkedButton, -1);
-}
-
-// detect a checked button other than the current one
-void QButtonGroupPrivate::detectCheckedButton()
-{
- QAbstractButton *previous = checkedButton;
- checkedButton = 0;
- if (exclusive)
- return;
- for (int i = 0; i < buttonList.count(); i++) {
- if (buttonList.at(i) != previous && buttonList.at(i)->isChecked()) {
- checkedButton = buttonList.at(i);
- return;
- }
- }
-}
-
-#endif // QT_NO_BUTTONGROUP
-
-QList<QAbstractButton *>QAbstractButtonPrivate::queryButtonList() const
-{
-#ifndef QT_NO_BUTTONGROUP
- if (group)
- return group->d_func()->buttonList;
-#endif
-
- QList<QAbstractButton*>candidates = parent->findChildren<QAbstractButton *>();
- if (autoExclusive) {
- for (int i = candidates.count() - 1; i >= 0; --i) {
- QAbstractButton *candidate = candidates.at(i);
- if (!candidate->autoExclusive()
-#ifndef QT_NO_BUTTONGROUP
- || candidate->group()
-#endif
- )
- candidates.removeAt(i);
- }
- }
- return candidates;
-}
-
-QAbstractButton *QAbstractButtonPrivate::queryCheckedButton() const
-{
-#ifndef QT_NO_BUTTONGROUP
- if (group)
- return group->d_func()->checkedButton;
-#endif
-
- Q_Q(const QAbstractButton);
- QList<QAbstractButton *> buttonList = queryButtonList();
- if (!autoExclusive || buttonList.count() == 1) // no group
- return 0;
-
- for (int i = 0; i < buttonList.count(); ++i) {
- QAbstractButton *b = buttonList.at(i);
- if (b->d_func()->checked && b != q)
- return b;
- }
- return checked ? const_cast<QAbstractButton *>(q) : 0;
-}
-
-void QAbstractButtonPrivate::notifyChecked()
-{
-#ifndef QT_NO_BUTTONGROUP
- Q_Q(QAbstractButton);
- if (group) {
- QAbstractButton *previous = group->d_func()->checkedButton;
- group->d_func()->checkedButton = q;
- if (group->d_func()->exclusive && previous && previous != q)
- previous->nextCheckState();
- } else
-#endif
- if (autoExclusive) {
- if (QAbstractButton *b = queryCheckedButton())
- b->setChecked(false);
- }
-}
-
-void QAbstractButtonPrivate::moveFocus(int key)
-{
- QList<QAbstractButton *> buttonList = queryButtonList();;
-#ifndef QT_NO_BUTTONGROUP
- bool exclusive = group ? group->d_func()->exclusive : autoExclusive;
-#else
- bool exclusive = autoExclusive;
-#endif
- QWidget *f = QApplication::focusWidget();
- QAbstractButton *fb = qobject_cast<QAbstractButton *>(f);
- if (!fb || !buttonList.contains(fb))
- return;
-
- QAbstractButton *candidate = 0;
- int bestScore = -1;
- QRect target = f->rect().translated(f->mapToGlobal(QPoint(0,0)));
- QPoint goal = target.center();
- uint focus_flag = qt_tab_all_widgets ? Qt::TabFocus : Qt::StrongFocus;
-
- for (int i = 0; i < buttonList.count(); ++i) {
- QAbstractButton *button = buttonList.at(i);
- if (button != f && button->window() == f->window() && button->isEnabled() && !button->isHidden() &&
- (autoExclusive || (button->focusPolicy() & focus_flag) == focus_flag)) {
- QRect buttonRect = button->rect().translated(button->mapToGlobal(QPoint(0,0)));
- QPoint p = buttonRect.center();
-
- //Priority to widgets that overlap on the same coordinate.
- //In that case, the distance in the direction will be used as significant score,
- //take also in account orthogonal distance in case two widget are in the same distance.
- int score;
- if ((buttonRect.x() < target.right() && target.x() < buttonRect.right())
- && (key == Qt::Key_Up || key == Qt::Key_Down)) {
- //one item's is at the vertical of the other
- score = (qAbs(p.y() - goal.y()) << 16) + qAbs(p.x() - goal.x());
- } else if ((buttonRect.y() < target.bottom() && target.y() < buttonRect.bottom())
- && (key == Qt::Key_Left || key == Qt::Key_Right) ) {
- //one item's is at the horizontal of the other
- score = (qAbs(p.x() - goal.x()) << 16) + qAbs(p.y() - goal.y());
- } else {
- score = (1 << 30) + (p.y() - goal.y()) * (p.y() - goal.y()) + (p.x() - goal.x()) * (p.x() - goal.x());
- }
-
- if (score > bestScore && candidate)
- continue;
-
- switch(key) {
- case Qt::Key_Up:
- if (p.y() < goal.y()) {
- candidate = button;
- bestScore = score;
- }
- break;
- case Qt::Key_Down:
- if (p.y() > goal.y()) {
- candidate = button;
- bestScore = score;
- }
- break;
- case Qt::Key_Left:
- if (p.x() < goal.x()) {
- candidate = button;
- bestScore = score;
- }
- break;
- case Qt::Key_Right:
- if (p.x() > goal.x()) {
- candidate = button;
- bestScore = score;
- }
- break;
- }
- }
- }
-
- if (exclusive
-#ifdef QT_KEYPAD_NAVIGATION
- && !QApplication::keypadNavigationEnabled()
-#endif
- && candidate
- && fb->d_func()->checked
- && candidate->d_func()->checkable)
- candidate->click();
-
- if (candidate) {
- if (key == Qt::Key_Up || key == Qt::Key_Left)
- candidate->setFocus(Qt::BacktabFocusReason);
- else
- candidate->setFocus(Qt::TabFocusReason);
- }
-}
-
-void QAbstractButtonPrivate::fixFocusPolicy()
-{
- Q_Q(QAbstractButton);
-#ifndef QT_NO_BUTTONGROUP
- if (!group && !autoExclusive)
-#else
- if (!autoExclusive)
-#endif
- return;
-
- QList<QAbstractButton *> buttonList = queryButtonList();
- for (int i = 0; i < buttonList.count(); ++i) {
- QAbstractButton *b = buttonList.at(i);
- if (!b->isCheckable())
- continue;
- b->setFocusPolicy((Qt::FocusPolicy) ((b == q || !q->isCheckable())
- ? (b->focusPolicy() | Qt::TabFocus)
- : (b->focusPolicy() & ~Qt::TabFocus)));
- }
-}
-
-void QAbstractButtonPrivate::init()
-{
- Q_Q(QAbstractButton);
-
- q->setFocusPolicy(Qt::FocusPolicy(q->style()->styleHint(QStyle::SH_Button_FocusPolicy)));
- q->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed, controlType));
- q->setAttribute(Qt::WA_WState_OwnSizePolicy, false);
- q->setForegroundRole(QPalette::ButtonText);
- q->setBackgroundRole(QPalette::Button);
-}
-
-void QAbstractButtonPrivate::refresh()
-{
- Q_Q(QAbstractButton);
-
- if (blockRefresh)
- return;
- q->update();
-#ifndef QT_NO_ACCESSIBILITY
- QAccessible::updateAccessibility(q, 0, QAccessible::StateChanged);
-#endif
-}
-
-void QAbstractButtonPrivate::click()
-{
- Q_Q(QAbstractButton);
-
- down = false;
- blockRefresh = true;
- bool changeState = true;
- if (checked && queryCheckedButton() == q) {
- // the checked button of an exclusive or autoexclusive group cannot be unchecked
-#ifndef QT_NO_BUTTONGROUP
- if (group ? group->d_func()->exclusive : autoExclusive)
-#else
- if (autoExclusive)
-#endif
- changeState = false;
- }
-
- QPointer<QAbstractButton> guard(q);
- if (changeState) {
- q->nextCheckState();
- if (!guard)
- return;
- }
- blockRefresh = false;
- refresh();
- q->repaint(); //flush paint event before invoking potentially expensive operation
- QApplication::flush();
- if (guard)
- emitReleased();
- if (guard)
- emitClicked();
-}
-
-void QAbstractButtonPrivate::emitClicked()
-{
- Q_Q(QAbstractButton);
- QPointer<QAbstractButton> guard(q);
- emit q->clicked(checked);
-#ifndef QT_NO_BUTTONGROUP
- if (guard && group) {
- emit group->buttonClicked(group->id(q));
- if (guard && group)
- emit group->buttonClicked(q);
- }
-#endif
-}
-
-void QAbstractButtonPrivate::emitPressed()
-{
- Q_Q(QAbstractButton);
- QPointer<QAbstractButton> guard(q);
- emit q->pressed();
-#ifndef QT_NO_BUTTONGROUP
- if (guard && group) {
- emit group->buttonPressed(group->id(q));
- if (guard && group)
- emit group->buttonPressed(q);
- }
-#endif
-}
-
-void QAbstractButtonPrivate::emitReleased()
-{
- Q_Q(QAbstractButton);
- QPointer<QAbstractButton> guard(q);
- emit q->released();
-#ifndef QT_NO_BUTTONGROUP
- if (guard && group) {
- emit group->buttonReleased(group->id(q));
- if (guard && group)
- emit group->buttonReleased(q);
- }
-#endif
-}
-
-/*!
- Constructs an abstract button with a \a parent.
-*/
-QAbstractButton::QAbstractButton(QWidget *parent)
- : QWidget(*new QAbstractButtonPrivate, parent, 0)
-{
- Q_D(QAbstractButton);
- d->init();
-}
-
-/*!
- Destroys the button.
- */
- QAbstractButton::~QAbstractButton()
-{
-#ifndef QT_NO_BUTTONGROUP
- Q_D(QAbstractButton);
- if (d->group)
- d->group->removeButton(this);
-#endif
-}
-
-
-/*! \internal
- */
-QAbstractButton::QAbstractButton(QAbstractButtonPrivate &dd, QWidget *parent)
- : QWidget(dd, parent, 0)
-{
- Q_D(QAbstractButton);
- d->init();
-}
-
-/*!
-\property QAbstractButton::text
-\brief the text shown on the button
-
-If the button has no text, the text() function will return a an empty
-string.
-
-If the text contains an ampersand character ('&'), a shortcut is
-automatically created for it. The character that follows the '&' will
-be used as the shortcut key. Any previous shortcut will be
-overwritten, or cleared if no shortcut is defined by the text. See the
-\l {QShortcut#mnemonic}{QShortcut} documentation for details (to
-display an actual ampersand, use '&&').
-
-There is no default text.
-*/
-
-void QAbstractButton::setText(const QString &text)
-{
- Q_D(QAbstractButton);
- if (d->text == text)
- return;
- d->text = text;
-#ifndef QT_NO_SHORTCUT
- QKeySequence newMnemonic = QKeySequence::mnemonic(text);
- setShortcut(newMnemonic);
-#endif
- d->sizeHint = QSize();
- update();
- updateGeometry();
-#ifndef QT_NO_ACCESSIBILITY
- QAccessible::updateAccessibility(this, 0, QAccessible::NameChanged);
-#endif
-}
-
-QString QAbstractButton::text() const
-{
- Q_D(const QAbstractButton);
- return d->text;
-}
-
-
-/*!
- \property QAbstractButton::icon
- \brief the icon shown on the button
-
- The icon's default size is defined by the GUI style, but can be
- adjusted by setting the \l iconSize property.
-*/
-void QAbstractButton::setIcon(const QIcon &icon)
-{
- Q_D(QAbstractButton);
- d->icon = icon;
- d->sizeHint = QSize();
- update();
- updateGeometry();
-}
-
-QIcon QAbstractButton::icon() const
-{
- Q_D(const QAbstractButton);
- return d->icon;
-}
-
-#ifndef QT_NO_SHORTCUT
-/*!
-\property QAbstractButton::shortcut
-\brief the mnemonic associated with the button
-*/
-
-void QAbstractButton::setShortcut(const QKeySequence &key)
-{
- Q_D(QAbstractButton);
- if (d->shortcutId != 0)
- releaseShortcut(d->shortcutId);
- d->shortcut = key;
- d->shortcutId = grabShortcut(key);
-}
-
-QKeySequence QAbstractButton::shortcut() const
-{
- Q_D(const QAbstractButton);
- return d->shortcut;
-}
-#endif // QT_NO_SHORTCUT
-
-/*!
-\property QAbstractButton::checkable
-\brief whether the button is checkable
-
-By default, the button is not checkable.
-
-\sa checked
-*/
-void QAbstractButton::setCheckable(bool checkable)
-{
- Q_D(QAbstractButton);
- if (d->checkable == checkable)
- return;
-
- d->checkable = checkable;
- d->checked = false;
-}
-
-bool QAbstractButton::isCheckable() const
-{
- Q_D(const QAbstractButton);
- return d->checkable;
-}
-
-/*!
-\property QAbstractButton::checked
-\brief whether the button is checked
-
-Only checkable buttons can be checked. By default, the button is unchecked.
-
-\sa checkable
-*/
-void QAbstractButton::setChecked(bool checked)
-{
- Q_D(QAbstractButton);
- if (!d->checkable || d->checked == checked) {
- if (!d->blockRefresh)
- checkStateSet();
- return;
- }
-
- if (!checked && d->queryCheckedButton() == this) {
- // the checked button of an exclusive or autoexclusive group cannot be unchecked
-#ifndef QT_NO_BUTTONGROUP
- if (d->group ? d->group->d_func()->exclusive : d->autoExclusive)
- return;
- if (d->group)
- d->group->d_func()->detectCheckedButton();
-#else
- if (d->autoExclusive)
- return;
-#endif
- }
-
- QPointer<QAbstractButton> guard(this);
-
- d->checked = checked;
- if (!d->blockRefresh)
- checkStateSet();
- d->refresh();
-
- if (guard && checked)
- d->notifyChecked();
- if (guard)
- emit toggled(checked);
-}
-
-bool QAbstractButton::isChecked() const
-{
- Q_D(const QAbstractButton);
- return d->checked;
-}
-
-/*!
- \property QAbstractButton::down
- \brief whether the button is pressed down
-
- If this property is true, the button is pressed down. The signals
- pressed() and clicked() are not emitted if you set this property
- to true. The default is false.
-*/
-
-void QAbstractButton::setDown(bool down)
-{
- Q_D(QAbstractButton);
- if (d->down == down)
- return;
- d->down = down;
- d->refresh();
- if (d->autoRepeat && d->down)
- d->repeatTimer.start(d->autoRepeatDelay, this);
- else
- d->repeatTimer.stop();
-}
-
-bool QAbstractButton::isDown() const
-{
- Q_D(const QAbstractButton);
- return d->down;
-}
-
-/*!
-\property QAbstractButton::autoRepeat
-\brief whether autoRepeat is enabled
-
-If autoRepeat is enabled, then the pressed(), released(), and clicked() signals are emitted at
-regular intervals when the button is down. autoRepeat is off by default.
-The initial delay and the repetition interval are defined in milliseconds by \l
-autoRepeatDelay and \l autoRepeatInterval.
-
-Note: If a button is pressed down by a shortcut key, then auto-repeat is enabled and timed by the
-system and not by this class. The pressed(), released(), and clicked() signals will be emitted
-like in the normal case.
-*/
-
-void QAbstractButton::setAutoRepeat(bool autoRepeat)
-{
- Q_D(QAbstractButton);
- if (d->autoRepeat == autoRepeat)
- return;
- d->autoRepeat = autoRepeat;
- if (d->autoRepeat && d->down)
- d->repeatTimer.start(d->autoRepeatDelay, this);
- else
- d->repeatTimer.stop();
-}
-
-bool QAbstractButton::autoRepeat() const
-{
- Q_D(const QAbstractButton);
- return d->autoRepeat;
-}
-
-/*!
- \property QAbstractButton::autoRepeatDelay
- \brief the initial delay of auto-repetition
- \since 4.2
-
- If \l autoRepeat is enabled, then autoRepeatDelay defines the initial
- delay in milliseconds before auto-repetition kicks in.
-
- \sa autoRepeat, autoRepeatInterval
-*/
-
-void QAbstractButton::setAutoRepeatDelay(int autoRepeatDelay)
-{
- Q_D(QAbstractButton);
- d->autoRepeatDelay = autoRepeatDelay;
-}
-
-int QAbstractButton::autoRepeatDelay() const
-{
- Q_D(const QAbstractButton);
- return d->autoRepeatDelay;
-}
-
-/*!
- \property QAbstractButton::autoRepeatInterval
- \brief the interval of auto-repetition
- \since 4.2
-
- If \l autoRepeat is enabled, then autoRepeatInterval defines the
- length of the auto-repetition interval in millisecons.
-
- \sa autoRepeat, autoRepeatDelay
-*/
-
-void QAbstractButton::setAutoRepeatInterval(int autoRepeatInterval)
-{
- Q_D(QAbstractButton);
- d->autoRepeatInterval = autoRepeatInterval;
-}
-
-int QAbstractButton::autoRepeatInterval() const
-{
- Q_D(const QAbstractButton);
- return d->autoRepeatInterval;
-}
-
-
-
-/*!
-\property QAbstractButton::autoExclusive
-\brief whether auto-exclusivity is enabled
-
-If auto-exclusivity is enabled, checkable buttons that belong to the
-same parent widget behave as if they were part of the same
-exclusive button group. In an exclusive button group, only one button
-can be checked at any time; checking another button automatically
-unchecks the previously checked one.
-
-The property has no effect on buttons that belong to a button
-group.
-
-autoExclusive is off by default, except for radio buttons.
-
-\sa QRadioButton
-*/
-void QAbstractButton::setAutoExclusive(bool autoExclusive)
-{
- Q_D(QAbstractButton);
- d->autoExclusive = autoExclusive;
-}
-
-bool QAbstractButton::autoExclusive() const
-{
- Q_D(const QAbstractButton);
- return d->autoExclusive;
-}
-
-#ifndef QT_NO_BUTTONGROUP
-/*!
- Returns the group that this button belongs to.
-
- If the button is not a member of any QButtonGroup, this function
- returns 0.
-
- \sa QButtonGroup
-*/
-QButtonGroup *QAbstractButton::group() const
-{
- Q_D(const QAbstractButton);
- return d->group;
-}
-#endif // QT_NO_BUTTONGROUP
-
-/*!
-Performs an animated click: the button is pressed immediately, and
-released \a msec milliseconds later (the default is 100 ms).
-
-Calling this function again before the button was released will reset
-the release timer.
-
-All signals associated with a click are emitted as appropriate.
-
-This function does nothing if the button is \link setEnabled()
-disabled. \endlink
-
-\sa click()
-*/
-void QAbstractButton::animateClick(int msec)
-{
- if (!isEnabled())
- return;
- Q_D(QAbstractButton);
- if (d->checkable && focusPolicy() & Qt::ClickFocus)
- setFocus();
- setDown(true);
- repaint(); //flush paint event before invoking potentially expensive operation
- QApplication::flush();
- if (!d->animateTimer.isActive())
- d->emitPressed();
- d->animateTimer.start(msec, this);
-}
-
-/*!
-Performs a click.
-
-All the usual signals associated with a click are emitted as
-appropriate. If the button is checkable, the state of the button is
-toggled.
-
-This function does nothing if the button is \link setEnabled()
-disabled. \endlink
-
-\sa animateClick()
- */
-void QAbstractButton::click()
-{
- if (!isEnabled())
- return;
- Q_D(QAbstractButton);
- QPointer<QAbstractButton> guard(this);
- d->down = true;
- d->emitPressed();
- if (guard) {
- d->down = false;
- nextCheckState();
- if (guard)
- d->emitReleased();
- if (guard)
- d->emitClicked();
- }
-}
-
-/*! \fn void QAbstractButton::toggle()
-
- Toggles the state of a checkable button.
-
- \sa checked
-*/
-void QAbstractButton::toggle()
-{
- Q_D(QAbstractButton);
- setChecked(!d->checked);
-}
-
-
-/*! This virtual handler is called when setChecked() was called,
-unless it was called from within nextCheckState(). It allows
-subclasses to reset their intermediate button states.
-
-\sa nextCheckState()
- */
-void QAbstractButton::checkStateSet()
-{
-}
-
-/*! This virtual handler is called when a button is clicked. The
-default implementation calls setChecked(!isChecked()) if the button
-isCheckable(). It allows subclasses to implement intermediate button
-states.
-
-\sa checkStateSet()
-*/
-void QAbstractButton::nextCheckState()
-{
- if (isCheckable())
- setChecked(!isChecked());
-}
-
-/*!
-Returns true if \a pos is inside the clickable button rectangle;
-otherwise returns false.
-
-By default, the clickable area is the entire widget. Subclasses
-may reimplement this function to provide support for clickable
-areas of different shapes and sizes.
-*/
-bool QAbstractButton::hitButton(const QPoint &pos) const
-{
- return rect().contains(pos);
-}
-
-/*! \reimp */
-bool QAbstractButton::event(QEvent *e)
-{
- // as opposed to other widgets, disabled buttons accept mouse
- // events. This avoids surprising click-through scenarios
- if (!isEnabled()) {
- switch(e->type()) {
- case QEvent::TabletPress:
- case QEvent::TabletRelease:
- case QEvent::TabletMove:
- case QEvent::MouseButtonPress:
- case QEvent::MouseButtonRelease:
- case QEvent::MouseButtonDblClick:
- case QEvent::MouseMove:
- case QEvent::HoverMove:
- case QEvent::HoverEnter:
- case QEvent::HoverLeave:
- case QEvent::ContextMenu:
-#ifndef QT_NO_WHEELEVENT
- case QEvent::Wheel:
-#endif
- return true;
- default:
- break;
- }
- }
-
-#ifndef QT_NO_SHORTCUT
- if (e->type() == QEvent::Shortcut) {
- Q_D(QAbstractButton);
- QShortcutEvent *se = static_cast<QShortcutEvent *>(e);
- if (d->shortcutId != se->shortcutId())
- return false;
- if (!se->isAmbiguous()) {
- if (!d->animateTimer.isActive())
- animateClick();
- } else {
- if (focusPolicy() != Qt::NoFocus)
- setFocus(Qt::ShortcutFocusReason);
- window()->setAttribute(Qt::WA_KeyboardFocusChange);
- }
- return true;
- }
-#endif
- return QWidget::event(e);
-}
-
-/*! \reimp */
-void QAbstractButton::mousePressEvent(QMouseEvent *e)
-{
- Q_D(QAbstractButton);
- if (e->button() != Qt::LeftButton) {
- e->ignore();
- return;
- }
- if (hitButton(e->pos())) {
- setDown(true);
- d->pressed = true;
- repaint(); //flush paint event before invoking potentially expensive operation
- QApplication::flush();
- d->emitPressed();
- e->accept();
- } else {
- e->ignore();
- }
-}
-
-/*! \reimp */
-void QAbstractButton::mouseReleaseEvent(QMouseEvent *e)
-{
- Q_D(QAbstractButton);
- d->pressed = false;
-
- if (e->button() != Qt::LeftButton) {
- e->ignore();
- return;
- }
-
- if (!d->down) {
- e->ignore();
- return;
- }
-
- if (hitButton(e->pos())) {
- d->repeatTimer.stop();
- d->click();
- e->accept();
- } else {
- setDown(false);
- e->ignore();
- }
-}
-
-/*! \reimp */
-void QAbstractButton::mouseMoveEvent(QMouseEvent *e)
-{
- Q_D(QAbstractButton);
- if (!(e->buttons() & Qt::LeftButton) || !d->pressed) {
- e->ignore();
- return;
- }
-
- if (hitButton(e->pos()) != d->down) {
- setDown(!d->down);
- repaint(); //flush paint event before invoking potentially expensive operation
- QApplication::flush();
- if (d->down)
- d->emitPressed();
- else
- d->emitReleased();
- e->accept();
- } else if (!hitButton(e->pos())) {
- e->ignore();
- }
-}
-
-/*! \reimp */
-void QAbstractButton::keyPressEvent(QKeyEvent *e)
-{
- Q_D(QAbstractButton);
- bool next = true;
- switch (e->key()) {
- case Qt::Key_Enter:
- case Qt::Key_Return:
- e->ignore();
- break;
- case Qt::Key_Select:
- case Qt::Key_Space:
- if (!e->isAutoRepeat()) {
- setDown(true);
- repaint(); //flush paint event before invoking potentially expensive operation
- QApplication::flush();
- d->emitPressed();
- }
- break;
- case Qt::Key_Up:
- case Qt::Key_Left:
- next = false;
- // fall through
- case Qt::Key_Right:
- case Qt::Key_Down:
-#ifdef QT_KEYPAD_NAVIGATION
- if ((QApplication::keypadNavigationEnabled()
- && (e->key() == Qt::Key_Left || e->key() == Qt::Key_Right))
- || (!QApplication::navigationMode() == Qt::NavigationModeKeypadDirectional
- || (e->key() == Qt::Key_Up || e->key() == Qt::Key_Down))) {
- e->ignore();
- return;
- }
-#endif
- QWidget *pw;
- if (d->autoExclusive
-#ifndef QT_NO_BUTTONGROUP
- || d->group
-#endif
-#ifndef QT_NO_ITEMVIEWS
- || ((pw = parentWidget()) && qobject_cast<QAbstractItemView *>(pw->parentWidget()))
-#endif
- ) {
- // ### Using qobject_cast to check if the parent is a viewport of
- // QAbstractItemView is a crude hack, and should be revisited and
- // cleaned up when fixing task 194373. It's here to ensure that we
- // keep compatibility outside QAbstractItemView.
- d->moveFocus(e->key());
- if (hasFocus()) // nothing happend, propagate
- e->ignore();
- } else {
- focusNextPrevChild(next);
- }
- break;
- case Qt::Key_Escape:
- if (d->down) {
- setDown(false);
- repaint(); //flush paint event before invoking potentially expensive operation
- QApplication::flush();
- d->emitReleased();
- break;
- }
- // fall through
- default:
- e->ignore();
- }
-}
-
-/*! \reimp */
-void QAbstractButton::keyReleaseEvent(QKeyEvent *e)
-{
- Q_D(QAbstractButton);
-
- if (!e->isAutoRepeat())
- d->repeatTimer.stop();
-
- switch (e->key()) {
- case Qt::Key_Select:
- case Qt::Key_Space:
- if (!e->isAutoRepeat() && d->down)
- d->click();
- break;
- default:
- e->ignore();
- }
-}
-
-/*!\reimp
- */
-void QAbstractButton::timerEvent(QTimerEvent *e)
-{
- Q_D(QAbstractButton);
- if (e->timerId() == d->repeatTimer.timerId()) {
- d->repeatTimer.start(d->autoRepeatInterval, this);
- if (d->down) {
- QPointer<QAbstractButton> guard(this);
- nextCheckState();
- if (guard)
- d->emitReleased();
- if (guard)
- d->emitClicked();
- if (guard)
- d->emitPressed();
- }
- } else if (e->timerId() == d->animateTimer.timerId()) {
- d->animateTimer.stop();
- d->click();
- }
-}
-
-/*! \reimp */
-void QAbstractButton::focusInEvent(QFocusEvent *e)
-{
- Q_D(QAbstractButton);
-#ifdef QT_KEYPAD_NAVIGATION
- if (!QApplication::keypadNavigationEnabled())
-#endif
- d->fixFocusPolicy();
- QWidget::focusInEvent(e);
-}
-
-/*! \reimp */
-void QAbstractButton::focusOutEvent(QFocusEvent *e)
-{
- Q_D(QAbstractButton);
- if (e->reason() != Qt::PopupFocusReason)
- d->down = false;
- QWidget::focusOutEvent(e);
-}
-
-/*! \reimp */
-void QAbstractButton::changeEvent(QEvent *e)
-{
- Q_D(QAbstractButton);
- switch (e->type()) {
- case QEvent::EnabledChange:
- if (!isEnabled())
- setDown(false);
- break;
- default:
- d->sizeHint = QSize();
- break;
- }
- QWidget::changeEvent(e);
-}
-
-/*!
- \fn void QAbstractButton::paintEvent(QPaintEvent *e)
- \reimp
-*/
-
-/*!
- \fn void QAbstractButton::pressed()
-
- This signal is emitted when the button is pressed down.
-
- \sa released(), clicked()
-*/
-
-/*!
- \fn void QAbstractButton::released()
-
- This signal is emitted when the button is released.
-
- \sa pressed(), clicked(), toggled()
-*/
-
-/*!
-\fn void QAbstractButton::clicked(bool checked)
-
-This signal is emitted when the button is activated (i.e. pressed down
-then released while the mouse cursor is inside the button), when the
-shortcut key is typed, or when click() or animateClick() is called.
-Notably, this signal is \e not emitted if you call setDown(),
-setChecked() or toggle().
-
-If the button is checkable, \a checked is true if the button is
-checked, or false if the button is unchecked.
-
-\sa pressed(), released(), toggled()
-*/
-
-/*!
-\fn void QAbstractButton::toggled(bool checked)
-
-This signal is emitted whenever a checkable button changes its state.
-\a checked is true if the button is checked, or false if the button is
-unchecked.
-
-This may be the result of a user action, click() slot activation,
-or because setChecked() was called.
-
-The states of buttons in exclusive button groups are updated before this
-signal is emitted. This means that slots can act on either the "off"
-signal or the "on" signal emitted by the buttons in the group whose
-states have changed.
-
-For example, a slot that reacts to signals emitted by newly checked
-buttons but which ignores signals from buttons that have been unchecked
-can be implemented using the following pattern:
-
-\snippet doc/src/snippets/code/src_gui_widgets_qabstractbutton.cpp 2
-
-Button groups can be created using the QButtonGroup class, and
-updates to the button states monitored with the
-\l{QButtonGroup::buttonClicked()} signal.
-
-\sa checked, clicked()
-*/
-
-/*!
- \property QAbstractButton::iconSize
- \brief the icon size used for this button.
-
- The default size is defined by the GUI style. This is a maximum
- size for the icons. Smaller icons will not be scaled up.
-*/
-
-QSize QAbstractButton::iconSize() const
-{
- Q_D(const QAbstractButton);
- if (d->iconSize.isValid())
- return d->iconSize;
- int e = style()->pixelMetric(QStyle::PM_ButtonIconSize, 0, this);
- return QSize(e, e);
-}
-
-void QAbstractButton::setIconSize(const QSize &size)
-{
- Q_D(QAbstractButton);
- if (d->iconSize == size)
- return;
-
- d->iconSize = size;
- d->sizeHint = QSize();
- updateGeometry();
- if (isVisible()) {
- update();
- }
-}
-
-
-#ifdef QT3_SUPPORT
-/*!
- Use icon() instead.
-*/
-QIcon *QAbstractButton::iconSet() const
-{
- Q_D(const QAbstractButton);
- if (!d->icon.isNull())
- return const_cast<QIcon *>(&d->icon);
- return 0;
-}
-
-/*!
- Use QAbstractButton(QWidget *) instead.
-
- Call setObjectName() if you want to specify an object name, and
- setParent() if you want to set the window flags.
-*/
-QAbstractButton::QAbstractButton(QWidget *parent, const char *name, Qt::WindowFlags f)
- : QWidget(*new QAbstractButtonPrivate, parent, f)
-{
- Q_D(QAbstractButton);
- setObjectName(QString::fromAscii(name));
- d->init();
-}
-
-/*! \fn bool QAbstractButton::isOn() const
-
- Use isChecked() instead.
-*/
-
-/*!
- \fn QPixmap *QAbstractButton::pixmap() const
-
- This compatibility function always returns 0.
-
- Use icon() instead.
-*/
-
-/*! \fn void QAbstractButton::setPixmap(const QPixmap &p)
-
- Use setIcon() instead.
-*/
-
-/*! \fn void QAbstractButton::setIconSet(const QIcon &icon)
-
- Use setIcon() instead.
-*/
-
-/*! \fn void QAbstractButton::setOn(bool b)
-
- Use setChecked() instead.
-*/
-
-/*! \fn bool QAbstractButton::isToggleButton() const
-
- Use isCheckable() instead.
-*/
-
-/*!
- \fn void QAbstractButton::setToggleButton(bool b)
-
- Use setCheckable() instead.
-*/
-
-/*! \fn void QAbstractButton::setAccel(const QKeySequence &key)
-
- Use setShortcut() instead.
-*/
-
-/*! \fn QKeySequence QAbstractButton::accel() const
-
- Use shortcut() instead.
-*/
-#endif
-
-QT_END_NAMESPACE
diff --git a/src/gui/widgets/qabstractbutton.h b/src/gui/widgets/qabstractbutton.h
deleted file mode 100644
index 8924346696..0000000000
--- a/src/gui/widgets/qabstractbutton.h
+++ /dev/null
@@ -1,180 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QABSTRACTBUTTON_H
-#define QABSTRACTBUTTON_H
-
-#include <QtGui/qicon.h>
-#include <QtGui/qkeysequence.h>
-#include <QtGui/qwidget.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QButtonGroup;
-class QAbstractButtonPrivate;
-
-class Q_GUI_EXPORT QAbstractButton : public QWidget
-{
- Q_OBJECT
-
- Q_PROPERTY(QString text READ text WRITE setText)
- Q_PROPERTY(QIcon icon READ icon WRITE setIcon)
- Q_PROPERTY(QSize iconSize READ iconSize WRITE setIconSize)
-#ifndef QT_NO_SHORTCUT
- Q_PROPERTY(QKeySequence shortcut READ shortcut WRITE setShortcut)
-#endif
- Q_PROPERTY(bool checkable READ isCheckable WRITE setCheckable)
- Q_PROPERTY(bool checked READ isChecked WRITE setChecked DESIGNABLE isCheckable NOTIFY toggled USER true)
- Q_PROPERTY(bool autoRepeat READ autoRepeat WRITE setAutoRepeat)
- Q_PROPERTY(bool autoExclusive READ autoExclusive WRITE setAutoExclusive)
- Q_PROPERTY(int autoRepeatDelay READ autoRepeatDelay WRITE setAutoRepeatDelay)
- Q_PROPERTY(int autoRepeatInterval READ autoRepeatInterval WRITE setAutoRepeatInterval)
- Q_PROPERTY(bool down READ isDown WRITE setDown DESIGNABLE false)
-
-public:
- explicit QAbstractButton(QWidget* parent=0);
- ~QAbstractButton();
-
- void setText(const QString &text);
- QString text() const;
-
- void setIcon(const QIcon &icon);
- QIcon icon() const;
-
- QSize iconSize() const;
-
-#ifndef QT_NO_SHORTCUT
- void setShortcut(const QKeySequence &key);
- QKeySequence shortcut() const;
-#endif
-
- void setCheckable(bool);
- bool isCheckable() const;
-
- bool isChecked() const;
-
- void setDown(bool);
- bool isDown() const;
-
- void setAutoRepeat(bool);
- bool autoRepeat() const;
-
- void setAutoRepeatDelay(int);
- int autoRepeatDelay() const;
-
- void setAutoRepeatInterval(int);
- int autoRepeatInterval() const;
-
- void setAutoExclusive(bool);
- bool autoExclusive() const;
-
-#ifndef QT_NO_BUTTONGROUP
- QButtonGroup *group() const;
-#endif
-
-public Q_SLOTS:
- void setIconSize(const QSize &size);
- void animateClick(int msec = 100);
- void click();
- void toggle();
- void setChecked(bool);
-
-Q_SIGNALS:
- void pressed();
- void released();
- void clicked(bool checked = false);
- void toggled(bool checked);
-
-protected:
- virtual void paintEvent(QPaintEvent *e) = 0;
- virtual bool hitButton(const QPoint &pos) const;
- virtual void checkStateSet();
- virtual void nextCheckState();
-
- bool event(QEvent *e);
- void keyPressEvent(QKeyEvent *e);
- void keyReleaseEvent(QKeyEvent *e);
- void mousePressEvent(QMouseEvent *e);
- void mouseReleaseEvent(QMouseEvent *e);
- void mouseMoveEvent(QMouseEvent *e);
- void focusInEvent(QFocusEvent *e);
- void focusOutEvent(QFocusEvent *e);
- void changeEvent(QEvent *e);
- void timerEvent(QTimerEvent *e);
-
-#ifdef QT3_SUPPORT
-public:
- QT3_SUPPORT_CONSTRUCTOR QAbstractButton(QWidget *parent, const char *name, Qt::WindowFlags f=0);
- inline QT3_SUPPORT bool isOn() const { return isChecked(); }
- inline QT3_SUPPORT const QPixmap *pixmap() const { return 0; } // help styles compile
- inline QT3_SUPPORT void setPixmap( const QPixmap &p ) {
- setIcon(QIcon(p));
- setIconSize(p.size());
- }
- QT3_SUPPORT QIcon *iconSet() const;
- inline QT3_SUPPORT void setIconSet(const QIcon &icon) { setIcon(icon); }
- inline QT3_SUPPORT bool isToggleButton() const { return isCheckable(); }
- inline QT3_SUPPORT void setToggleButton(bool b) { setCheckable(b); }
- inline QT3_SUPPORT void setAccel(const QKeySequence &key) { setShortcut(key); }
- inline QT3_SUPPORT QKeySequence accel() const { return shortcut(); }
-
-public Q_SLOTS:
- inline QT_MOC_COMPAT void setOn(bool b) { setChecked(b); }
-#endif
-
-protected:
- QAbstractButton(QAbstractButtonPrivate &dd, QWidget* parent = 0);
-
-private:
- Q_DECLARE_PRIVATE(QAbstractButton)
- Q_DISABLE_COPY(QAbstractButton)
- friend class QButtonGroup;
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QABSTRACTBUTTON_H
diff --git a/src/gui/widgets/qabstractplatformmenubar_p.h b/src/gui/widgets/qabstractplatformmenubar_p.h
deleted file mode 100644
index 10e6fdcab2..0000000000
--- a/src/gui/widgets/qabstractplatformmenubar_p.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QABSTRACTPLATFORMMENUBAR_P_H
-#define QABSTRACTPLATFORMMENUBAR_P_H
-
-#include <qfactoryinterface.h>
-#include <qglobal.h>
-#include <qplugin.h>
-
-#ifndef QT_NO_MENUBAR
-
-QT_BEGIN_NAMESPACE
-
-class QAction;
-class QActionEvent;
-class QEvent;
-class QMenuBar;
-class QObject;
-class QWidget;
-
-class QAbstractPlatformMenuBar;
-
-struct QPlatformMenuBarFactoryInterface : public QFactoryInterface
-{
- virtual QAbstractPlatformMenuBar *create() = 0;
-};
-
-#define QPlatformMenuBarFactoryInterface_iid "com.nokia.qt.QPlatformMenuBarFactoryInterface"
-Q_DECLARE_INTERFACE(QPlatformMenuBarFactoryInterface, QPlatformMenuBarFactoryInterface_iid)
-
-/*!
- The platform-specific implementation of a menubar
-*/
-class QAbstractPlatformMenuBar
-{
-public:
- virtual ~QAbstractPlatformMenuBar() {}
-
- virtual void init(QMenuBar *) = 0;
-
- virtual void setVisible(bool visible) = 0;
-
- virtual void actionEvent(QActionEvent *) = 0;
-
- virtual void handleReparent(QWidget *oldParent, QWidget *newParent, QWidget *oldWindow, QWidget *newWindow) = 0;
-
- virtual bool allowCornerWidgets() const = 0;
-
- virtual void popupAction(QAction *) = 0;
-
- virtual void setNativeMenuBar(bool) = 0;
-
- virtual bool isNativeMenuBar() const = 0;
-
- /*!
- Return true if the native menubar is capable of listening to the
- shortcut keys. If false is returned, QMenuBar will trigger actions on
- shortcut itself.
- */
- virtual bool shortcutsHandledByNativeMenuBar() const = 0;
-
- virtual bool menuBarEventFilter(QObject *, QEvent *event) = 0;
-};
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_MENUBAR
-
-#endif // QABSTRACTPLATFORMMENUBAR_P_H
diff --git a/src/gui/widgets/qabstractscrollarea.h b/src/gui/widgets/qabstractscrollarea.h
deleted file mode 100644
index e95b30435a..0000000000
--- a/src/gui/widgets/qabstractscrollarea.h
+++ /dev/null
@@ -1,144 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QABSTRACTSCROLLAREA_H
-#define QABSTRACTSCROLLAREA_H
-
-#include <QtGui/qframe.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_SCROLLAREA
-
-class QMargins;
-class QScrollBar;
-class QAbstractScrollAreaPrivate;
-
-class Q_GUI_EXPORT QAbstractScrollArea : public QFrame
-{
- Q_OBJECT
- Q_PROPERTY(Qt::ScrollBarPolicy verticalScrollBarPolicy READ verticalScrollBarPolicy WRITE setVerticalScrollBarPolicy)
- Q_PROPERTY(Qt::ScrollBarPolicy horizontalScrollBarPolicy READ horizontalScrollBarPolicy WRITE setHorizontalScrollBarPolicy)
-
-public:
- explicit QAbstractScrollArea(QWidget* parent=0);
- ~QAbstractScrollArea();
-
- Qt::ScrollBarPolicy verticalScrollBarPolicy() const;
- void setVerticalScrollBarPolicy(Qt::ScrollBarPolicy);
- QScrollBar *verticalScrollBar() const;
- void setVerticalScrollBar(QScrollBar *scrollbar);
-
- Qt::ScrollBarPolicy horizontalScrollBarPolicy() const;
- void setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy);
- QScrollBar *horizontalScrollBar() const;
- void setHorizontalScrollBar(QScrollBar *scrollbar);
-
- QWidget *cornerWidget() const;
- void setCornerWidget(QWidget *widget);
-
- void addScrollBarWidget(QWidget *widget, Qt::Alignment alignment);
- QWidgetList scrollBarWidgets(Qt::Alignment alignment);
-
- QWidget *viewport() const;
- void setViewport(QWidget *widget);
- QSize maximumViewportSize() const;
-
- QSize minimumSizeHint() const;
-
- QSize sizeHint() const;
-
-protected Q_SLOTS:
- void setupViewport(QWidget *viewport);
-
-protected:
- QAbstractScrollArea(QAbstractScrollAreaPrivate &dd, QWidget *parent = 0);
- void setViewportMargins(int left, int top, int right, int bottom);
- void setViewportMargins(const QMargins &margins);
-
- bool event(QEvent *);
- virtual bool viewportEvent(QEvent *);
-
- void resizeEvent(QResizeEvent *);
- void paintEvent(QPaintEvent *);
- void mousePressEvent(QMouseEvent *);
- void mouseReleaseEvent(QMouseEvent *);
- void mouseDoubleClickEvent(QMouseEvent *);
- void mouseMoveEvent(QMouseEvent *);
-#ifndef QT_NO_WHEELEVENT
- void wheelEvent(QWheelEvent *);
-#endif
-#ifndef QT_NO_CONTEXTMENU
- void contextMenuEvent(QContextMenuEvent *);
-#endif
-#ifndef QT_NO_DRAGANDDROP
- void dragEnterEvent(QDragEnterEvent *);
- void dragMoveEvent(QDragMoveEvent *);
- void dragLeaveEvent(QDragLeaveEvent *);
- void dropEvent(QDropEvent *);
-#endif
-
- void keyPressEvent(QKeyEvent *);
-
- virtual void scrollContentsBy(int dx, int dy);
-
-private:
- Q_DECLARE_PRIVATE(QAbstractScrollArea)
- Q_DISABLE_COPY(QAbstractScrollArea)
- Q_PRIVATE_SLOT(d_func(), void _q_hslide(int))
- Q_PRIVATE_SLOT(d_func(), void _q_vslide(int))
- Q_PRIVATE_SLOT(d_func(), void _q_showOrHideScrollBars())
-
- friend class QStyleSheetStyle;
- friend class QWidgetPrivate;
-};
-
-#endif // QT_NO_SCROLLAREA
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QABSTRACTSCROLLAREA_H
diff --git a/src/gui/widgets/qabstractscrollarea_p.h b/src/gui/widgets/qabstractscrollarea_p.h
deleted file mode 100644
index 27ee19f579..0000000000
--- a/src/gui/widgets/qabstractscrollarea_p.h
+++ /dev/null
@@ -1,146 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QABSTRACTSCROLLAREA_P_H
-#define QABSTRACTSCROLLAREA_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "private/qframe_p.h"
-#include "qabstractscrollarea.h"
-
-QT_BEGIN_NAMESPACE
-
-#ifndef QT_NO_SCROLLAREA
-
-class QScrollBar;
-class QAbstractScrollAreaScrollBarContainer;
-class Q_GUI_EXPORT QAbstractScrollAreaPrivate: public QFramePrivate
-{
- Q_DECLARE_PUBLIC(QAbstractScrollArea)
-
-public:
- QAbstractScrollAreaPrivate();
-
- void replaceScrollBar(QScrollBar *scrollBar, Qt::Orientation orientation);
-
- QAbstractScrollAreaScrollBarContainer *scrollBarContainers[Qt::Vertical + 1];
- QScrollBar *hbar, *vbar;
- Qt::ScrollBarPolicy vbarpolicy, hbarpolicy;
-
- QWidget *viewport;
- QWidget *cornerWidget;
- QRect cornerPaintingRect;
-#ifdef Q_WS_MAC
- QRect reverseCornerPaintingRect;
-#endif
- int left, top, right, bottom; // viewport margin
-
- int xoffset, yoffset;
- QPoint overshoot;
-
- void init();
- void layoutChildren();
- // ### Fix for 4.4, talk to Bjoern E or Girish.
- virtual void scrollBarPolicyChanged(Qt::Orientation, Qt::ScrollBarPolicy) {}
- bool canStartScrollingAt( const QPoint &startPos );
-
- void _q_hslide(int);
- void _q_vslide(int);
- void _q_showOrHideScrollBars();
-
- virtual QPoint contentsOffset() const;
-
- inline bool viewportEvent(QEvent *event)
- { return q_func()->viewportEvent(event); }
- QScopedPointer<QObject> viewportFilter;
-
-#ifdef Q_WS_WIN
- bool singleFingerPanEnabled;
- void setSingleFingerPanEnabled(bool on = true);
-#endif
-};
-
-class QAbstractScrollAreaFilter : public QObject
-{
- Q_OBJECT
-public:
- QAbstractScrollAreaFilter(QAbstractScrollAreaPrivate *p) : d(p)
- { setObjectName(QLatin1String("qt_abstractscrollarea_filter")); }
- bool eventFilter(QObject *o, QEvent *e)
- { return (o == d->viewport ? d->viewportEvent(e) : false); }
-private:
- QAbstractScrollAreaPrivate *d;
-};
-
-class QBoxLayout;
-class QAbstractScrollAreaScrollBarContainer : public QWidget
-{
-public:
- enum LogicalPosition { LogicalLeft = 1, LogicalRight = 2 };
-
- QAbstractScrollAreaScrollBarContainer(Qt::Orientation orientation, QWidget *parent);
- void addWidget(QWidget *widget, LogicalPosition position);
- QWidgetList widgets(LogicalPosition position);
- void removeWidget(QWidget *widget);
-
- QScrollBar *scrollBar;
- QBoxLayout *layout;
-private:
- int scrollBarLayoutIndex() const;
-
- Qt::Orientation orientation;
-};
-
-#endif // QT_NO_SCROLLAREA
-
-QT_END_NAMESPACE
-
-#endif // QABSTRACTSCROLLAREA_P_H
diff --git a/src/gui/widgets/qabstractslider.h b/src/gui/widgets/qabstractslider.h
deleted file mode 100644
index 2f548a730e..0000000000
--- a/src/gui/widgets/qabstractslider.h
+++ /dev/null
@@ -1,184 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QABSTRACTSLIDER_H
-#define QABSTRACTSLIDER_H
-
-#include <QtGui/qwidget.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QAbstractSliderPrivate;
-
-class Q_GUI_EXPORT QAbstractSlider : public QWidget
-{
- Q_OBJECT
-
- Q_PROPERTY(int minimum READ minimum WRITE setMinimum)
- Q_PROPERTY(int maximum READ maximum WRITE setMaximum)
- Q_PROPERTY(int singleStep READ singleStep WRITE setSingleStep)
- Q_PROPERTY(int pageStep READ pageStep WRITE setPageStep)
- Q_PROPERTY(int value READ value WRITE setValue NOTIFY valueChanged USER true)
- Q_PROPERTY(int sliderPosition READ sliderPosition WRITE setSliderPosition NOTIFY sliderMoved)
- Q_PROPERTY(bool tracking READ hasTracking WRITE setTracking)
- Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation)
- Q_PROPERTY(bool invertedAppearance READ invertedAppearance WRITE setInvertedAppearance)
- Q_PROPERTY(bool invertedControls READ invertedControls WRITE setInvertedControls)
- Q_PROPERTY(bool sliderDown READ isSliderDown WRITE setSliderDown DESIGNABLE false)
-
-public:
- explicit QAbstractSlider(QWidget *parent=0);
- ~QAbstractSlider();
-
- Qt::Orientation orientation() const;
-
- void setMinimum(int);
- int minimum() const;
-
- void setMaximum(int);
- int maximum() const;
-
- void setRange(int min, int max);
-
- void setSingleStep(int);
- int singleStep() const;
-
- void setPageStep(int);
- int pageStep() const;
-
- void setTracking(bool enable);
- bool hasTracking() const;
-
- void setSliderDown(bool);
- bool isSliderDown() const;
-
- void setSliderPosition(int);
- int sliderPosition() const;
-
- void setInvertedAppearance(bool);
- bool invertedAppearance() const;
-
- void setInvertedControls(bool);
- bool invertedControls() const;
-
- enum SliderAction {
- SliderNoAction,
- SliderSingleStepAdd,
- SliderSingleStepSub,
- SliderPageStepAdd,
- SliderPageStepSub,
- SliderToMinimum,
- SliderToMaximum,
- SliderMove
- };
-
- int value() const;
-
- void triggerAction(SliderAction action);
-
-public Q_SLOTS:
- void setValue(int);
- void setOrientation(Qt::Orientation);
-
-Q_SIGNALS:
- void valueChanged(int value);
-
- void sliderPressed();
- void sliderMoved(int position);
- void sliderReleased();
-
- void rangeChanged(int min, int max);
-
- void actionTriggered(int action);
-
-protected:
- bool event(QEvent *e);
-
- void setRepeatAction(SliderAction action, int thresholdTime = 500, int repeatTime = 50);
- SliderAction repeatAction() const;
-
- enum SliderChange {
- SliderRangeChange,
- SliderOrientationChange,
- SliderStepsChange,
- SliderValueChange
- };
- virtual void sliderChange(SliderChange change);
-
- void keyPressEvent(QKeyEvent *ev);
- void timerEvent(QTimerEvent *);
-#ifndef QT_NO_WHEELEVENT
- void wheelEvent(QWheelEvent *e);
-#endif
- void changeEvent(QEvent *e);
-
-#ifdef QT3_SUPPORT
-public:
- inline QT3_SUPPORT int minValue() const { return minimum(); }
- inline QT3_SUPPORT int maxValue() const { return maximum(); }
- inline QT3_SUPPORT int lineStep() const { return singleStep(); }
- inline QT3_SUPPORT void setMinValue(int v) { setMinimum(v); }
- inline QT3_SUPPORT void setMaxValue(int v) { setMaximum(v); }
- inline QT3_SUPPORT void setLineStep(int v) { setSingleStep(v); }
- inline QT3_SUPPORT void setSteps(int single, int page) { setSingleStep(single); setPageStep(page); }
- inline QT3_SUPPORT void addPage() { triggerAction(SliderPageStepAdd); }
- inline QT3_SUPPORT void subtractPage() { triggerAction(SliderPageStepSub); }
- inline QT3_SUPPORT void addLine() { triggerAction(SliderSingleStepAdd); }
- inline QT3_SUPPORT void subtractLine() { triggerAction(SliderSingleStepSub); }
-#endif
-
-protected:
- QAbstractSlider(QAbstractSliderPrivate &dd, QWidget *parent=0);
-
-private:
- Q_DISABLE_COPY(QAbstractSlider)
- Q_DECLARE_PRIVATE(QAbstractSlider)
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QABSTRACTSLIDER_H
diff --git a/src/gui/widgets/qabstractspinbox.h b/src/gui/widgets/qabstractspinbox.h
deleted file mode 100644
index 92259f9e27..0000000000
--- a/src/gui/widgets/qabstractspinbox.h
+++ /dev/null
@@ -1,181 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QABSTRACTSPINBOX_H
-#define QABSTRACTSPINBOX_H
-
-#include <QtGui/qwidget.h>
-#include <QtGui/qvalidator.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_SPINBOX
-
-class QLineEdit;
-
-class QAbstractSpinBoxPrivate;
-class QStyleOptionSpinBox;
-
-class Q_GUI_EXPORT QAbstractSpinBox : public QWidget
-{
- Q_OBJECT
-
- Q_ENUMS(ButtonSymbols)
- Q_ENUMS(CorrectionMode)
- Q_PROPERTY(bool wrapping READ wrapping WRITE setWrapping)
- Q_PROPERTY(bool frame READ hasFrame WRITE setFrame)
- Q_PROPERTY(Qt::Alignment alignment READ alignment WRITE setAlignment)
- Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly)
- Q_PROPERTY(ButtonSymbols buttonSymbols READ buttonSymbols WRITE setButtonSymbols)
- Q_PROPERTY(QString specialValueText READ specialValueText WRITE setSpecialValueText)
- Q_PROPERTY(QString text READ text)
- Q_PROPERTY(bool accelerated READ isAccelerated WRITE setAccelerated)
- Q_PROPERTY(CorrectionMode correctionMode READ correctionMode WRITE setCorrectionMode)
- Q_PROPERTY(bool acceptableInput READ hasAcceptableInput)
- Q_PROPERTY(bool keyboardTracking READ keyboardTracking WRITE setKeyboardTracking)
-public:
- explicit QAbstractSpinBox(QWidget *parent = 0);
- ~QAbstractSpinBox();
-
- enum StepEnabledFlag { StepNone = 0x00, StepUpEnabled = 0x01,
- StepDownEnabled = 0x02 };
- Q_DECLARE_FLAGS(StepEnabled, StepEnabledFlag)
-
- enum ButtonSymbols { UpDownArrows, PlusMinus, NoButtons };
-
- ButtonSymbols buttonSymbols() const;
- void setButtonSymbols(ButtonSymbols bs);
-
- enum CorrectionMode { CorrectToPreviousValue, CorrectToNearestValue };
-
- void setCorrectionMode(CorrectionMode cm);
- CorrectionMode correctionMode() const;
-
- bool hasAcceptableInput() const;
- QString text() const;
-
- QString specialValueText() const;
- void setSpecialValueText(const QString &txt);
-
- bool wrapping() const;
- void setWrapping(bool w);
-
- void setReadOnly(bool r);
- bool isReadOnly() const;
-
- void setKeyboardTracking(bool kt);
- bool keyboardTracking() const;
-
- void setAlignment(Qt::Alignment flag);
- Qt::Alignment alignment() const;
-
- void setFrame(bool);
- bool hasFrame() const;
-
- void setAccelerated(bool on);
- bool isAccelerated() const;
-
- QSize sizeHint() const;
- QSize minimumSizeHint() const;
- void interpretText();
- bool event(QEvent *event);
-
- QVariant inputMethodQuery(Qt::InputMethodQuery) const;
-
- virtual QValidator::State validate(QString &input, int &pos) const;
- virtual void fixup(QString &input) const;
-
- virtual void stepBy(int steps);
-public Q_SLOTS:
- void stepUp();
- void stepDown();
- void selectAll();
- virtual void clear();
-protected:
- void resizeEvent(QResizeEvent *event);
- void keyPressEvent(QKeyEvent *event);
- void keyReleaseEvent(QKeyEvent *event);
-#ifndef QT_NO_WHEELEVENT
- void wheelEvent(QWheelEvent *event);
-#endif
- void focusInEvent(QFocusEvent *event);
- void focusOutEvent(QFocusEvent *event);
- void contextMenuEvent(QContextMenuEvent *event);
- void changeEvent(QEvent *event);
- void closeEvent(QCloseEvent *event);
- void hideEvent(QHideEvent *event);
- void mousePressEvent(QMouseEvent *event);
- void mouseReleaseEvent(QMouseEvent *event);
- void mouseMoveEvent(QMouseEvent *event);
- void timerEvent(QTimerEvent *event);
- void paintEvent(QPaintEvent *event);
- void showEvent(QShowEvent *event);
- void initStyleOption(QStyleOptionSpinBox *option) const;
-
- QLineEdit *lineEdit() const;
- void setLineEdit(QLineEdit *edit);
-
- virtual StepEnabled stepEnabled() const;
-Q_SIGNALS:
- void editingFinished();
-protected:
- QAbstractSpinBox(QAbstractSpinBoxPrivate &dd, QWidget *parent = 0);
-
-private:
- Q_PRIVATE_SLOT(d_func(), void _q_editorTextChanged(const QString &))
- Q_PRIVATE_SLOT(d_func(), void _q_editorCursorPositionChanged(int, int))
-
- Q_DECLARE_PRIVATE(QAbstractSpinBox)
- Q_DISABLE_COPY(QAbstractSpinBox)
-};
-Q_DECLARE_OPERATORS_FOR_FLAGS(QAbstractSpinBox::StepEnabled)
-
-#endif // QT_NO_SPINBOX
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QABSTRACTSPINBOX_H
diff --git a/src/gui/widgets/qabstractspinbox_p.h b/src/gui/widgets/qabstractspinbox_p.h
deleted file mode 100644
index b25fe25896..0000000000
--- a/src/gui/widgets/qabstractspinbox_p.h
+++ /dev/null
@@ -1,170 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QABSTRACTSPINBOX_P_H
-#define QABSTRACTSPINBOX_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "QtGui/qabstractspinbox.h"
-
-#ifndef QT_NO_SPINBOX
-
-#include "QtGui/qlineedit.h"
-#include "QtGui/qstyleoption.h"
-#include "QtGui/qvalidator.h"
-#include "QtCore/qdatetime.h"
-#include "QtCore/qvariant.h"
-#include "private/qwidget_p.h"
-#include "private/qdatetime_p.h"
-
-QT_BEGIN_NAMESPACE
-
-QVariant operator+(const QVariant &arg1, const QVariant &arg2);
-QVariant operator-(const QVariant &arg1, const QVariant &arg2);
-QVariant operator*(const QVariant &arg1, double multiplier);
-double operator/(const QVariant &arg1, const QVariant &arg2);
-
-enum EmitPolicy {
- EmitIfChanged,
- AlwaysEmit,
- NeverEmit
-};
-
-enum Button {
- None = 0x000,
- Keyboard = 0x001,
- Mouse = 0x002,
- Wheel = 0x004,
- ButtonMask = 0x008,
- Up = 0x010,
- Down = 0x020,
- DirectionMask = 0x040
-};
-class QSpinBoxValidator;
-class QAbstractSpinBoxPrivate : public QWidgetPrivate
-{
- Q_DECLARE_PUBLIC(QAbstractSpinBox)
-public:
- QAbstractSpinBoxPrivate();
- ~QAbstractSpinBoxPrivate();
-
- void init();
- void reset();
- void updateState(bool up, bool fromKeyboard = false);
- QString stripped(const QString &text, int *pos = 0) const;
- bool specialValue() const;
- virtual QVariant getZeroVariant() const;
- virtual void setRange(const QVariant &min, const QVariant &max);
- void setValue(const QVariant &val, EmitPolicy ep, bool updateEdit = true);
- virtual QVariant bound(const QVariant &val, const QVariant &old = QVariant(), int steps = 0) const;
- virtual void updateEdit();
-
- virtual void emitSignals(EmitPolicy ep, const QVariant &old);
- virtual void interpret(EmitPolicy ep);
- virtual QString textFromValue(const QVariant &n) const;
- virtual QVariant valueFromText(const QString &input) const;
-
- void _q_editorTextChanged(const QString &);
- virtual void _q_editorCursorPositionChanged(int oldpos, int newpos);
-
- virtual QStyle::SubControl newHoverControl(const QPoint &pos);
- bool updateHoverControl(const QPoint &pos);
-
- virtual void clearCache() const;
- virtual void updateEditFieldGeometry();
-
- static int variantCompare(const QVariant &arg1, const QVariant &arg2);
- static QVariant variantBound(const QVariant &min, const QVariant &value, const QVariant &max);
-
- QLineEdit *edit;
- QString prefix, suffix, specialValueText;
- QVariant value, minimum, maximum, singleStep;
- QVariant::Type type;
- int spinClickTimerId, spinClickTimerInterval, spinClickThresholdTimerId, spinClickThresholdTimerInterval;
- int effectiveSpinRepeatRate;
- uint buttonState;
- mutable QString cachedText;
- mutable QVariant cachedValue;
- mutable QValidator::State cachedState;
- mutable QSize cachedSizeHint, cachedMinimumSizeHint;
- uint pendingEmit : 1;
- uint readOnly : 1;
- uint wrapping : 1;
- uint ignoreCursorPositionChanged : 1;
- uint frame : 1;
- uint accelerate : 1;
- uint keyboardTracking : 1;
- uint cleared : 1;
- uint ignoreUpdateEdit : 1;
- QAbstractSpinBox::CorrectionMode correctionMode;
- int acceleration;
- QStyle::SubControl hoverControl;
- QRect hoverRect;
- QAbstractSpinBox::ButtonSymbols buttonSymbols;
- QSpinBoxValidator *validator;
-};
-
-class QSpinBoxValidator : public QValidator
-{
-public:
- QSpinBoxValidator(QAbstractSpinBox *qptr, QAbstractSpinBoxPrivate *dptr);
- QValidator::State validate(QString &input, int &) const;
- void fixup(QString &) const;
-private:
- QAbstractSpinBox *qptr;
- QAbstractSpinBoxPrivate *dptr;
-};
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_SPINBOX
-
-#endif // QABSTRACTSPINBOX_P_H
diff --git a/src/gui/widgets/qbuttongroup.h b/src/gui/widgets/qbuttongroup.h
deleted file mode 100644
index a0472fd2db..0000000000
--- a/src/gui/widgets/qbuttongroup.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QBUTTONGROUP_H
-#define QBUTTONGROUP_H
-
-#include <QtCore/qobject.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_BUTTONGROUP
-
-class QAbstractButton;
-class QAbstractButtonPrivate;
-class QButtonGroupPrivate;
-
-class Q_GUI_EXPORT QButtonGroup : public QObject
-{
- Q_OBJECT
-
- Q_PROPERTY(bool exclusive READ exclusive WRITE setExclusive)
-public:
- explicit QButtonGroup(QObject *parent = 0);
- ~QButtonGroup();
-
- void setExclusive(bool);
- bool exclusive() const;
-
- void addButton(QAbstractButton *);
- void addButton(QAbstractButton *, int id);
- void removeButton(QAbstractButton *);
-
- QList<QAbstractButton*> buttons() const;
-
- QAbstractButton * checkedButton() const;
- // no setter on purpose!
-
- QAbstractButton *button(int id) const;
- void setId(QAbstractButton *button, int id);
- int id(QAbstractButton *button) const;
- int checkedId() const;
-
-Q_SIGNALS:
- void buttonClicked(QAbstractButton *);
- void buttonClicked(int);
- void buttonPressed(QAbstractButton *);
- void buttonPressed(int);
- void buttonReleased(QAbstractButton *);
- void buttonReleased(int);
-
-#ifdef QT3_SUPPORT
-public:
- inline QT3_SUPPORT void insert(QAbstractButton *b) { addButton(b); }
- inline QT3_SUPPORT void remove(QAbstractButton *b) { removeButton(b); }
-#endif
-
-private:
- Q_DISABLE_COPY(QButtonGroup)
- Q_DECLARE_PRIVATE(QButtonGroup)
- friend class QAbstractButton;
- friend class QAbstractButtonPrivate;
-};
-
-#endif // QT_NO_BUTTONGROUP
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QBUTTONGROUP_H
diff --git a/src/gui/widgets/qcalendarwidget.h b/src/gui/widgets/qcalendarwidget.h
deleted file mode 100644
index d6bf8b20da..0000000000
--- a/src/gui/widgets/qcalendarwidget.h
+++ /dev/null
@@ -1,204 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QCALENDARWIDGET_H
-#define QCALENDARWIDGET_H
-
-#include <QtGui/qwidget.h>
-#include <QtCore/qdatetime.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_CALENDARWIDGET
-
-class QDate;
-class QTextCharFormat;
-class QCalendarWidgetPrivate;
-
-class Q_GUI_EXPORT QCalendarWidget : public QWidget
-{
- Q_OBJECT
- Q_ENUMS(Qt::DayOfWeek)
- Q_ENUMS(HorizontalHeaderFormat)
- Q_ENUMS(VerticalHeaderFormat)
- Q_ENUMS(SelectionMode)
- Q_PROPERTY(QDate selectedDate READ selectedDate WRITE setSelectedDate)
- Q_PROPERTY(QDate minimumDate READ minimumDate WRITE setMinimumDate)
- Q_PROPERTY(QDate maximumDate READ maximumDate WRITE setMaximumDate)
- Q_PROPERTY(Qt::DayOfWeek firstDayOfWeek READ firstDayOfWeek WRITE setFirstDayOfWeek)
- Q_PROPERTY(bool gridVisible READ isGridVisible WRITE setGridVisible)
- Q_PROPERTY(SelectionMode selectionMode READ selectionMode WRITE setSelectionMode)
- Q_PROPERTY(HorizontalHeaderFormat horizontalHeaderFormat READ horizontalHeaderFormat WRITE setHorizontalHeaderFormat)
- Q_PROPERTY(VerticalHeaderFormat verticalHeaderFormat READ verticalHeaderFormat WRITE setVerticalHeaderFormat)
- Q_PROPERTY(bool headerVisible READ isHeaderVisible WRITE setHeaderVisible STORED false DESIGNABLE false) // obsolete
- Q_PROPERTY(bool navigationBarVisible READ isNavigationBarVisible WRITE setNavigationBarVisible)
- Q_PROPERTY(bool dateEditEnabled READ isDateEditEnabled WRITE setDateEditEnabled)
- Q_PROPERTY(int dateEditAcceptDelay READ dateEditAcceptDelay WRITE setDateEditAcceptDelay)
-
-public:
- enum HorizontalHeaderFormat {
- NoHorizontalHeader,
- SingleLetterDayNames,
- ShortDayNames,
- LongDayNames
- };
-
- enum VerticalHeaderFormat {
- NoVerticalHeader,
- ISOWeekNumbers
- };
-
- enum SelectionMode {
- NoSelection,
- SingleSelection
- };
-
- explicit QCalendarWidget(QWidget *parent = 0);
- ~QCalendarWidget();
-
- virtual QSize sizeHint() const;
- virtual QSize minimumSizeHint() const;
-
- QDate selectedDate() const;
-
- int yearShown() const;
- int monthShown() const;
-
- QDate minimumDate() const;
- void setMinimumDate(const QDate &date);
-
- QDate maximumDate() const;
- void setMaximumDate(const QDate &date);
-
- Qt::DayOfWeek firstDayOfWeek() const;
- void setFirstDayOfWeek(Qt::DayOfWeek dayOfWeek);
-
- // ### Qt 5: eliminate these two
- bool isHeaderVisible() const;
- void setHeaderVisible(bool show);
-
- inline bool isNavigationBarVisible() const { return isHeaderVisible(); }
-
- bool isGridVisible() const;
-
- SelectionMode selectionMode() const;
- void setSelectionMode(SelectionMode mode);
-
- HorizontalHeaderFormat horizontalHeaderFormat() const;
- void setHorizontalHeaderFormat(HorizontalHeaderFormat format);
-
- VerticalHeaderFormat verticalHeaderFormat() const;
- void setVerticalHeaderFormat(VerticalHeaderFormat format);
-
- QTextCharFormat headerTextFormat() const;
- void setHeaderTextFormat(const QTextCharFormat &format);
-
- QTextCharFormat weekdayTextFormat(Qt::DayOfWeek dayOfWeek) const;
- void setWeekdayTextFormat(Qt::DayOfWeek dayOfWeek, const QTextCharFormat &format);
-
- QMap<QDate, QTextCharFormat> dateTextFormat() const;
- QTextCharFormat dateTextFormat(const QDate &date) const;
- void setDateTextFormat(const QDate &date, const QTextCharFormat &format);
-
- bool isDateEditEnabled() const;
- void setDateEditEnabled(bool enable);
-
- int dateEditAcceptDelay() const;
- void setDateEditAcceptDelay(int delay);
-
-protected:
- bool event(QEvent *event);
- bool eventFilter(QObject *watched, QEvent *event);
- void mousePressEvent(QMouseEvent *event);
- void resizeEvent(QResizeEvent * event);
- void keyPressEvent(QKeyEvent * event);
-
- virtual void paintCell(QPainter *painter, const QRect &rect, const QDate &date) const;
- void updateCell(const QDate &date);
- void updateCells();
-
-public Q_SLOTS:
- void setSelectedDate(const QDate &date);
- void setDateRange(const QDate &min, const QDate &max);
- void setCurrentPage(int year, int month);
- void setGridVisible(bool show);
- void setNavigationBarVisible(bool visible);
- void showNextMonth();
- void showPreviousMonth();
- void showNextYear();
- void showPreviousYear();
- void showSelectedDate();
- void showToday();
-
-Q_SIGNALS:
- void selectionChanged();
- void clicked(const QDate &date);
- void activated(const QDate &date);
- void currentPageChanged(int year, int month);
-
-private:
- Q_DECLARE_PRIVATE(QCalendarWidget)
- Q_DISABLE_COPY(QCalendarWidget)
-
- Q_PRIVATE_SLOT(d_func(), void _q_slotShowDate(const QDate &date))
- Q_PRIVATE_SLOT(d_func(), void _q_slotChangeDate(const QDate &date))
- Q_PRIVATE_SLOT(d_func(), void _q_slotChangeDate(const QDate &date, bool changeMonth))
- Q_PRIVATE_SLOT(d_func(), void _q_editingFinished())
- Q_PRIVATE_SLOT(d_func(), void _q_prevMonthClicked())
- Q_PRIVATE_SLOT(d_func(), void _q_nextMonthClicked())
- Q_PRIVATE_SLOT(d_func(), void _q_yearEditingFinished())
- Q_PRIVATE_SLOT(d_func(), void _q_yearClicked())
- Q_PRIVATE_SLOT(d_func(), void _q_monthChanged(QAction *act))
-
-};
-
-#endif // QT_NO_CALENDARWIDGET
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QCALENDARWIDGET_H
-
diff --git a/src/gui/widgets/qcheckbox.h b/src/gui/widgets/qcheckbox.h
deleted file mode 100644
index 263fa4a152..0000000000
--- a/src/gui/widgets/qcheckbox.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QCHECKBOX_H
-#define QCHECKBOX_H
-
-#include <QtGui/qabstractbutton.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QCheckBoxPrivate;
-class QStyleOptionButton;
-
-class Q_GUI_EXPORT QCheckBox : public QAbstractButton
-{
- Q_OBJECT
-
- Q_PROPERTY(bool tristate READ isTristate WRITE setTristate)
-
-public:
- explicit QCheckBox(QWidget *parent=0);
- explicit QCheckBox(const QString &text, QWidget *parent=0);
-
-
- QSize sizeHint() const;
- QSize minimumSizeHint() const;
-
- void setTristate(bool y = true);
- bool isTristate() const;
-
- Qt::CheckState checkState() const;
- void setCheckState(Qt::CheckState state);
-
-Q_SIGNALS:
- void stateChanged(int);
-
-protected:
- bool event(QEvent *e);
- bool hitButton(const QPoint &pos) const;
- void checkStateSet();
- void nextCheckState();
- void paintEvent(QPaintEvent *);
- void mouseMoveEvent(QMouseEvent *);
- void initStyleOption(QStyleOptionButton *option) const;
-
-#ifdef QT3_SUPPORT
-public:
- enum ToggleState {
- Off = Qt::Unchecked,
- NoChange = Qt::PartiallyChecked,
- On = Qt::Checked
- };
- inline QT3_SUPPORT ToggleState state() const
- { return static_cast<QCheckBox::ToggleState>(static_cast<int>(checkState())); }
- inline QT3_SUPPORT void setState(ToggleState state)
- { setCheckState(static_cast<Qt::CheckState>(static_cast<int>(state))); }
- inline QT3_SUPPORT void setNoChange()
- { setCheckState(Qt::PartiallyChecked); }
- QT3_SUPPORT_CONSTRUCTOR QCheckBox(QWidget *parent, const char* name);
- QT3_SUPPORT_CONSTRUCTOR QCheckBox(const QString &text, QWidget *parent, const char* name);
-#endif
-
-private:
- Q_DECLARE_PRIVATE(QCheckBox)
- Q_DISABLE_COPY(QCheckBox)
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QCHECKBOX_H
diff --git a/src/gui/widgets/qcocoamenu_mac.mm b/src/gui/widgets/qcocoamenu_mac.mm
deleted file mode 100644
index 95075b95d1..0000000000
--- a/src/gui/widgets/qcocoamenu_mac.mm
+++ /dev/null
@@ -1,244 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qmacdefines_mac.h"
-#include "qapplication.h"
-#ifdef QT_MAC_USE_COCOA
-#import <private/qcocoamenu_mac_p.h>
-#import <private/qcocoamenuloader_mac_p.h>
-#import <private/qcocoaapplication_mac_p.h>
-#include <private/qt_cocoa_helpers_mac_p.h>
-#include <private/qapplication_p.h>
-#include <private/qaction_p.h>
-#include <private/qcocoaapplication_mac_p.h>
-
-#include <QtGui/QMenu>
-
-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
-extern NSString *qt_mac_removePrivateUnicode(NSString* string);
-QT_END_NAMESPACE
-
-QT_USE_NAMESPACE
-
-@implementation QT_MANGLE_NAMESPACE(QCocoaMenu)
-
-- (id)initWithQMenu:(QMenu*)menu
-{
- self = [super init];
- if (self) {
- qmenu = menu;
- previousAction = 0;
- [self setAutoenablesItems:NO];
- [self setDelegate:self];
- }
- return self;
-}
-
-- (void)menu:(NSMenu*)menu willHighlightItem:(NSMenuItem*)item
-{
- Q_UNUSED(menu);
-
- if (!item) {
- if (previousAction) {
- qt_mac_clear_status_text(previousAction);
- previousAction = 0;
- }
- return;
- }
-
- if (QAction *action = reinterpret_cast<QAction *>([item tag])) {
- QMenu *qtmenu = static_cast<QT_MANGLE_NAMESPACE(QCocoaMenu) *>(menu)->qmenu;
- previousAction = action;
- action->activate(QAction::Hover);
- qt_mac_menu_emit_hovered(qtmenu, action);
- action->showStatusText(0); // 0 widget -> action's parent
- }
-}
-
-- (void)menuWillOpen:(NSMenu*)menu
-{
- while (QWidget *popup
- = QApplication::activePopupWidget())
- popup->close();
- QMenu *qtmenu = static_cast<QT_MANGLE_NAMESPACE(QCocoaMenu) *>(menu)->qmenu;
- qt_mac_emit_menuSignals(qtmenu, true);
- qt_mac_menu_collapseSeparators(menu, qtmenu->separatorsCollapsible());
-}
-
-- (void)menuDidClose:(NSMenu*)menu
-{
- qt_mac_emit_menuSignals(((QT_MANGLE_NAMESPACE(QCocoaMenu) *)menu)->qmenu, false);
- if (previousAction) {
- qt_mac_clear_status_text(previousAction);
- previousAction = 0;
- }
-}
-
-- (BOOL)hasShortcut:(NSMenu *)menu forKey:(NSString *)key forModifiers:(NSUInteger)modifier
- whichItem:(NSMenuItem**)outItem
-{
- for (NSMenuItem *item in [menu itemArray]) {
- if (![item isEnabled] || [item isHidden] || [item isSeparatorItem])
- continue;
- if ([item hasSubmenu]) {
- if ([self hasShortcut:[item submenu]
- forKey:key
- forModifiers:modifier whichItem:outItem]) {
- if (outItem)
- *outItem = item;
- return YES;
- }
- }
- NSString *menuKey = [item keyEquivalent];
- if (menuKey && NSOrderedSame == [menuKey compare:key]
- && (modifier == [item keyEquivalentModifierMask])) {
- if (outItem)
- *outItem = item;
- return YES;
- }
- }
- if (outItem)
- *outItem = 0;
- return NO;
-}
-
-- (BOOL)menuHasKeyEquivalent:(NSMenu *)menu forEvent:(NSEvent *)event target:(id *)target action:(SEL *)action
-{
- // Check if the menu actually has a keysequence defined for this key event.
- // 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, 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;
- // Change the private unicode keys to the ones used in setting the "Key Equivalents"
- NSString *characters = qt_mac_removePrivateUnicode([event characters]);
- if ([self hasShortcut:menu
- forKey:characters
- // Interested only in Shift, Cmd, Ctrl & Alt Keys, so ignoring masks like, Caps lock, Num Lock ...
- forModifiers:([event modifierFlags] & (NSShiftKeyMask | NSControlKeyMask | NSCommandKeyMask | NSAlternateKeyMask))
- whichItem:&whichItem]) {
- QWidget *widget = 0;
- QAction *qaction = 0;
- if (whichItem && [whichItem tag]) {
- qaction = reinterpret_cast<QAction *>([whichItem tag]);
- }
- if (qApp->activePopupWidget())
- widget = (qApp->activePopupWidget()->focusWidget() ?
- qApp->activePopupWidget()->focusWidget() : qApp->activePopupWidget());
- else if (QApplicationPrivate::focus_widget)
- widget = QApplicationPrivate::focus_widget;
- // If we could not find any receivers, pass it to the active window
- if (!widget)
- widget = qApp->activeWindow();
- if (qaction && widget) {
- int key = qaction->shortcut();
- QKeyEvent accel_ev(QEvent::ShortcutOverride, (key & (~Qt::KeyboardModifierMask)),
- Qt::KeyboardModifiers(key & Qt::KeyboardModifierMask));
- accel_ev.ignore();
- qt_sendSpontaneousEvent(widget, &accel_ev);
- if (accel_ev.isAccepted()) {
- qt_dispatchKeyEvent(event, widget);
- *target = nil;
- *action = nil;
- return YES;
- }
- }
- }
- return NO;
-}
-
-- (NSInteger)indexOfItemWithTarget:(id)anObject andAction:(SEL)actionSelector
-{
- NSInteger index = [super indexOfItemWithTarget:anObject andAction:actionSelector];
- static SEL selForOFCP = NSSelectorFromString(@"orderFrontCharacterPalette:");
- if (index == -1 && selForOFCP == actionSelector) {
- // Check if the 'orderFrontCharacterPalette' SEL exists for QCocoaMenuLoader object
- QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = [NSApp QT_MANGLE_NAMESPACE(qt_qcocoamenuLoader)];
- return [super indexOfItemWithTarget:loader andAction:actionSelector];
- }
- return index;
-}
-
-@end
-
-QT_BEGIN_NAMESPACE
-extern int qt_mac_menus_open_count; // qmenu_mac.mm
-
-void qt_mac_emit_menuSignals(QMenu *menu, bool show)
-{
- if (!menu)
- return;
- int delta;
- if (show) {
- emit menu->aboutToShow();
- delta = 1;
- } else {
- emit menu->aboutToHide();
- delta = -1;
- }
- qt_mac_menus_open_count += delta;
-}
-
-void qt_mac_clear_status_text(QAction *action)
-{
- action->d_func()->showStatusText(0, QString());
-}
-
-void qt_mac_menu_emit_hovered(QMenu *menu, QAction *action)
-{
- emit menu->hovered(action);
-}
-
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/gui/widgets/qcocoamenu_mac_p.h b/src/gui/widgets/qcocoamenu_mac_p.h
deleted file mode 100644
index 6160a2656f..0000000000
--- a/src/gui/widgets/qcocoamenu_mac_p.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qmacdefines_mac.h"
-#ifdef QT_MAC_USE_COCOA
-#import <Cocoa/Cocoa.h>
-
-QT_FORWARD_DECLARE_CLASS(QMenu)
-QT_FORWARD_DECLARE_CLASS(QAction)
-
-#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5
-
-@protocol NSMenuDelegate <NSObject>
-- (void)menu:(NSMenu*)menu willHighlightItem:(NSMenuItem*)item;
-- (void)menuWillOpen:(NSMenu*)menu;
-- (void)menuDidClose:(NSMenu*)menu;
-- (BOOL)hasShortcut:(NSMenu *)menu forKey:(NSString *)key forModifiers:(NSUInteger)modifier
- whichItem:(NSMenuItem**)outItem;
-@end
-
-#endif
-
-@interface QT_MANGLE_NAMESPACE(QCocoaMenu) : NSMenu <NSMenuDelegate>
-{
- QMenu *qmenu;
- QAction *previousAction;
-}
-- (id)initWithQMenu:(QMenu*)menu;
-- (BOOL)menuHasKeyEquivalent:(NSMenu *)menu forEvent:(NSEvent *)event target:(id *)target action:(SEL *)action;
-- (NSInteger)indexOfItemWithTarget:(id)anObject andAction:(SEL)actionSelector;
-@end
-#endif
-
diff --git a/src/gui/widgets/qcombobox.h b/src/gui/widgets/qcombobox.h
deleted file mode 100644
index 9cbf48330b..0000000000
--- a/src/gui/widgets/qcombobox.h
+++ /dev/null
@@ -1,339 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QCOMBOBOX_H
-#define QCOMBOBOX_H
-
-#include <QtGui/qwidget.h>
-#include <QtGui/qabstractitemdelegate.h>
-#include <QtCore/qabstractitemmodel.h>
-#include <QtCore/qvariant.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-#ifndef QT_NO_COMBOBOX
-
-class QAbstractItemView;
-class QLineEdit;
-class QComboBoxPrivate;
-class QCompleter;
-
-class Q_GUI_EXPORT QComboBox : public QWidget
-{
- Q_OBJECT
-
- Q_ENUMS(InsertPolicy)
- Q_ENUMS(SizeAdjustPolicy)
- Q_PROPERTY(bool editable READ isEditable WRITE setEditable)
- Q_PROPERTY(int count READ count)
- Q_PROPERTY(QString currentText READ currentText)
- Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged USER true)
- Q_PROPERTY(int maxVisibleItems READ maxVisibleItems WRITE setMaxVisibleItems)
- Q_PROPERTY(int maxCount READ maxCount WRITE setMaxCount)
- Q_PROPERTY(InsertPolicy insertPolicy READ insertPolicy WRITE setInsertPolicy)
- Q_PROPERTY(SizeAdjustPolicy sizeAdjustPolicy READ sizeAdjustPolicy WRITE setSizeAdjustPolicy)
- Q_PROPERTY(int minimumContentsLength READ minimumContentsLength WRITE setMinimumContentsLength)
- Q_PROPERTY(QSize iconSize READ iconSize WRITE setIconSize)
-
-#ifndef QT_NO_COMPLETER
- Q_PROPERTY(bool autoCompletion READ autoCompletion WRITE setAutoCompletion DESIGNABLE false)
- Q_PROPERTY(Qt::CaseSensitivity autoCompletionCaseSensitivity READ autoCompletionCaseSensitivity WRITE setAutoCompletionCaseSensitivity DESIGNABLE false)
-#endif // QT_NO_COMPLETER
-
- Q_PROPERTY(bool duplicatesEnabled READ duplicatesEnabled WRITE setDuplicatesEnabled)
- Q_PROPERTY(bool frame READ hasFrame WRITE setFrame)
- Q_PROPERTY(int modelColumn READ modelColumn WRITE setModelColumn)
-
-public:
- explicit QComboBox(QWidget *parent = 0);
- ~QComboBox();
-
- int maxVisibleItems() const;
- void setMaxVisibleItems(int maxItems);
-
- int count() const;
- void setMaxCount(int max);
- int maxCount() const;
-
-#ifndef QT_NO_COMPLETER
- bool autoCompletion() const;
- void setAutoCompletion(bool enable);
-
- Qt::CaseSensitivity autoCompletionCaseSensitivity() const;
- void setAutoCompletionCaseSensitivity(Qt::CaseSensitivity sensitivity);
-#endif
-
- bool duplicatesEnabled() const;
- void setDuplicatesEnabled(bool enable);
-
- void setFrame(bool);
- bool hasFrame() const;
-
- inline int findText(const QString &text,
- Qt::MatchFlags flags = static_cast<Qt::MatchFlags>(Qt::MatchExactly|Qt::MatchCaseSensitive)) const
- { return findData(text, Qt::DisplayRole, flags); }
- int findData(const QVariant &data, int role = Qt::UserRole,
- Qt::MatchFlags flags = static_cast<Qt::MatchFlags>(Qt::MatchExactly|Qt::MatchCaseSensitive)) const;
-
- enum InsertPolicy {
- NoInsert,
- InsertAtTop,
- InsertAtCurrent,
- InsertAtBottom,
- InsertAfterCurrent,
- InsertBeforeCurrent,
- InsertAlphabetically
-#if defined(QT3_SUPPORT) && !defined(Q_MOC_RUN)
- ,
- NoInsertion = NoInsert,
- AtTop = InsertAtTop,
- AtCurrent = InsertAtCurrent,
- AtBottom = InsertAtBottom,
- AfterCurrent = InsertAfterCurrent,
- BeforeCurrent = InsertBeforeCurrent
-#endif
- };
-#ifdef QT3_SUPPORT
- typedef InsertPolicy Policy;
-#endif
-
- InsertPolicy insertPolicy() const;
- void setInsertPolicy(InsertPolicy policy);
-
- enum SizeAdjustPolicy {
- AdjustToContents,
- AdjustToContentsOnFirstShow,
- AdjustToMinimumContentsLength, // ### Qt 5: remove
- AdjustToMinimumContentsLengthWithIcon
- };
-
- SizeAdjustPolicy sizeAdjustPolicy() const;
- void setSizeAdjustPolicy(SizeAdjustPolicy policy);
- int minimumContentsLength() const;
- void setMinimumContentsLength(int characters);
- QSize iconSize() const;
- void setIconSize(const QSize &size);
-
- bool isEditable() const;
- void setEditable(bool editable);
- void setLineEdit(QLineEdit *edit);
- QLineEdit *lineEdit() const;
-#ifndef QT_NO_VALIDATOR
- void setValidator(const QValidator *v);
- const QValidator *validator() const;
-#endif
-
-#ifndef QT_NO_COMPLETER
- void setCompleter(QCompleter *c);
- QCompleter *completer() const;
-#endif
-
- QAbstractItemDelegate *itemDelegate() const;
- void setItemDelegate(QAbstractItemDelegate *delegate);
-
- QAbstractItemModel *model() const;
- void setModel(QAbstractItemModel *model);
-
- QModelIndex rootModelIndex() const;
- void setRootModelIndex(const QModelIndex &index);
-
- int modelColumn() const;
- void setModelColumn(int visibleColumn);
-
- int currentIndex() const;
-
- QString currentText() const;
-
- QString itemText(int index) const;
- QIcon itemIcon(int index) const;
- QVariant itemData(int index, int role = Qt::UserRole) const;
-
- inline void addItem(const QString &text, const QVariant &userData = QVariant());
- inline void addItem(const QIcon &icon, const QString &text,
- const QVariant &userData = QVariant());
- inline void addItems(const QStringList &texts)
- { insertItems(count(), texts); }
-
- inline void insertItem(int index, const QString &text, const QVariant &userData = QVariant());
- void insertItem(int index, const QIcon &icon, const QString &text,
- const QVariant &userData = QVariant());
- void insertItems(int index, const QStringList &texts);
- void insertSeparator(int index);
-
- void removeItem(int index);
-
- void setItemText(int index, const QString &text);
- void setItemIcon(int index, const QIcon &icon);
- void setItemData(int index, const QVariant &value, int role = Qt::UserRole);
-
- QAbstractItemView *view() const;
- void setView(QAbstractItemView *itemView);
-
- QSize sizeHint() const;
- QSize minimumSizeHint() const;
-
- virtual void showPopup();
- virtual void hidePopup();
-
- bool event(QEvent *event);
-
-public Q_SLOTS:
- void clear();
- void clearEditText();
- void setEditText(const QString &text);
- void setCurrentIndex(int index);
-
-Q_SIGNALS:
- void editTextChanged(const QString &);
- void activated(int index);
- void activated(const QString &);
- void highlighted(int index);
- void highlighted(const QString &);
- void currentIndexChanged(int index);
- void currentIndexChanged(const QString &);
-
-protected:
- void focusInEvent(QFocusEvent *e);
- void focusOutEvent(QFocusEvent *e);
- void changeEvent(QEvent *e);
- void resizeEvent(QResizeEvent *e);
- void paintEvent(QPaintEvent *e);
- void showEvent(QShowEvent *e);
- void hideEvent(QHideEvent *e);
- void mousePressEvent(QMouseEvent *e);
- void mouseReleaseEvent(QMouseEvent *e);
- void keyPressEvent(QKeyEvent *e);
- void keyReleaseEvent(QKeyEvent *e);
-#ifndef QT_NO_WHEELEVENT
- void wheelEvent(QWheelEvent *e);
-#endif
- void contextMenuEvent(QContextMenuEvent *e);
- void inputMethodEvent(QInputMethodEvent *);
- QVariant inputMethodQuery(Qt::InputMethodQuery) const;
- void initStyleOption(QStyleOptionComboBox *option) const;
-
-#ifdef QT3_SUPPORT
-public:
- QT3_SUPPORT_CONSTRUCTOR QComboBox(QWidget *parent, const char *name);
- QT3_SUPPORT_CONSTRUCTOR QComboBox(bool rw, QWidget *parent, const char *name = 0);
- inline QT3_SUPPORT int currentItem() const { return currentIndex(); }
- inline QT3_SUPPORT void setCurrentItem(int index) { setCurrentIndex(index); }
- inline QT3_SUPPORT InsertPolicy insertionPolicy() const { return insertPolicy(); }
- inline QT3_SUPPORT void setInsertionPolicy(InsertPolicy policy) { setInsertPolicy(policy); }
- inline QT3_SUPPORT bool editable() const { return isEditable(); }
- inline QT3_SUPPORT void popup() { showPopup(); }
- inline QT3_SUPPORT void setCurrentText(const QString& text) {
- int i = findText(text);
- if (i != -1)
- setCurrentIndex(i);
- else if (isEditable())
- setEditText(text);
- else
- setItemText(currentIndex(), text);
- }
- inline QT3_SUPPORT QString text(int index) const { return itemText(index); }
-
- inline QT3_SUPPORT QPixmap pixmap(int index) const
- { return itemIcon(index).pixmap(iconSize(), isEnabled() ? QIcon::Normal : QIcon::Disabled); }
- inline QT3_SUPPORT void insertStringList(const QStringList &list, int index = -1)
- { insertItems((index < 0 ? count() : index), list); }
- inline QT3_SUPPORT void insertItem(const QString &text, int index = -1)
- { insertItem((index < 0 ? count() : index), text); }
- inline QT3_SUPPORT void insertItem(const QPixmap &pix, int index = -1)
- { insertItem((index < 0 ? count() : index), QIcon(pix), QString()); }
- inline QT3_SUPPORT void insertItem(const QPixmap &pix, const QString &text, int index = -1)
- { insertItem((index < 0 ? count() : index), QIcon(pix), text); }
- inline QT3_SUPPORT void changeItem(const QString &text, int index)
- { setItemText(index, text); }
- inline QT3_SUPPORT void changeItem(const QPixmap &pix, int index)
- { setItemIcon(index, QIcon(pix)); }
- inline QT3_SUPPORT void changeItem(const QPixmap &pix, const QString &text, int index)
- { setItemIcon(index, QIcon(pix)); setItemText(index, text); }
- inline QT3_SUPPORT void clearValidator() { setValidator(0); }
- inline QT3_SUPPORT void clearEdit() { clearEditText(); }
-
-Q_SIGNALS:
- QT_MOC_COMPAT void textChanged(const QString &);
-#endif
-
-protected:
- QComboBox(QComboBoxPrivate &, QWidget *);
-
-private:
- Q_DECLARE_PRIVATE(QComboBox)
- Q_DISABLE_COPY(QComboBox)
- Q_PRIVATE_SLOT(d_func(), void _q_itemSelected(const QModelIndex &item))
- Q_PRIVATE_SLOT(d_func(), void _q_emitHighlighted(const QModelIndex &))
- Q_PRIVATE_SLOT(d_func(), void _q_emitCurrentIndexChanged(const QModelIndex &index))
- Q_PRIVATE_SLOT(d_func(), void _q_editingFinished())
- Q_PRIVATE_SLOT(d_func(), void _q_returnPressed())
- Q_PRIVATE_SLOT(d_func(), void _q_resetButton())
- Q_PRIVATE_SLOT(d_func(), void _q_dataChanged(const QModelIndex &, const QModelIndex &))
- Q_PRIVATE_SLOT(d_func(), void _q_updateIndexBeforeChange())
- Q_PRIVATE_SLOT(d_func(), void _q_rowsInserted(const QModelIndex & parent, int start, int end))
- Q_PRIVATE_SLOT(d_func(), void _q_rowsRemoved(const QModelIndex & parent, int start, int end))
- Q_PRIVATE_SLOT(d_func(), void _q_modelDestroyed())
- Q_PRIVATE_SLOT(d_func(), void _q_modelReset())
-#ifdef QT_KEYPAD_NAVIGATION
- Q_PRIVATE_SLOT(d_func(), void _q_completerActivated())
-#endif
-};
-
-inline void QComboBox::addItem(const QString &atext, const QVariant &auserData)
-{ insertItem(count(), atext, auserData); }
-inline void QComboBox::addItem(const QIcon &aicon, const QString &atext,
- const QVariant &auserData)
-{ insertItem(count(), aicon, atext, auserData); }
-
-inline void QComboBox::insertItem(int aindex, const QString &atext,
- const QVariant &auserData)
-{ insertItem(aindex, QIcon(), atext, auserData); }
-
-#endif // QT_NO_COMBOBOX
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QCOMBOBOX_H
diff --git a/src/gui/widgets/qcombobox_p.h b/src/gui/widgets/qcombobox_p.h
deleted file mode 100644
index a17f9d9574..0000000000
--- a/src/gui/widgets/qcombobox_p.h
+++ /dev/null
@@ -1,421 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QCOMBOBOX_P_H
-#define QCOMBOBOX_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "QtGui/qcombobox.h"
-
-#ifndef QT_NO_COMBOBOX
-#include "QtGui/qabstractslider.h"
-#include "QtGui/qapplication.h"
-#include "QtGui/qitemdelegate.h"
-#include "QtGui/qstandarditemmodel.h"
-#include "QtGui/qlineedit.h"
-#include "QtGui/qlistview.h"
-#include "QtGui/qpainter.h"
-#include "QtGui/qstyle.h"
-#include "QtGui/qstyleoption.h"
-#include "QtCore/qhash.h"
-#include "QtCore/qpair.h"
-#include "QtCore/qtimer.h"
-#include "private/qwidget_p.h"
-#include "QtCore/qpointer.h"
-#include "QtGui/qcompleter.h"
-#include "QtGui/qevent.h"
-#include "QtCore/qdebug.h"
-
-#include <limits.h>
-
-QT_BEGIN_NAMESPACE
-
-class QAction;
-
-class QComboBoxListView : public QListView
-{
- Q_OBJECT
-public:
- QComboBoxListView(QComboBox *cmb = 0) : combo(cmb) {}
-
-protected:
- void resizeEvent(QResizeEvent *event)
- {
- resizeContents(viewport()->width(), contentsSize().height());
- QListView::resizeEvent(event);
- }
-
- QStyleOptionViewItem viewOptions() const
- {
- QStyleOptionViewItem option = QListView::viewOptions();
- option.showDecorationSelected = true;
- if (combo)
- option.font = combo->font();
- return option;
- }
-
- void paintEvent(QPaintEvent *e)
- {
- if (combo) {
- QStyleOptionComboBox opt;
- opt.initFrom(combo);
- opt.editable = combo->isEditable();
- if (combo->style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, combo)) {
- //we paint the empty menu area to avoid having blank space that can happen when scrolling
- QStyleOptionMenuItem menuOpt;
- menuOpt.initFrom(this);
- menuOpt.palette = palette();
- menuOpt.state = QStyle::State_None;
- menuOpt.checkType = QStyleOptionMenuItem::NotCheckable;
- menuOpt.menuRect = e->rect();
- menuOpt.maxIconWidth = 0;
- menuOpt.tabWidth = 0;
- QPainter p(viewport());
- combo->style()->drawControl(QStyle::CE_MenuEmptyArea, &menuOpt, &p, this);
- }
- }
- QListView::paintEvent(e);
- }
-
-private:
- QComboBox *combo;
-};
-
-
-class QStandardItemModel;
-
-class Q_AUTOTEST_EXPORT QComboBoxPrivateScroller : public QWidget
-{
- Q_OBJECT
-
-public:
- QComboBoxPrivateScroller(QAbstractSlider::SliderAction action, QWidget *parent)
- : QWidget(parent), sliderAction(action)
- {
- setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
- setAttribute(Qt::WA_NoMousePropagation);
- }
- QSize sizeHint() const {
- return QSize(20, style()->pixelMetric(QStyle::PM_MenuScrollerHeight));
- }
-
-protected:
- inline void stopTimer() {
- timer.stop();
- }
-
- inline void startTimer() {
- timer.start(100, this);
- fast = false;
- }
-
- void enterEvent(QEvent *) {
- startTimer();
- }
-
- void leaveEvent(QEvent *) {
- stopTimer();
- }
- void timerEvent(QTimerEvent *e) {
- if (e->timerId() == timer.timerId()) {
- emit doScroll(sliderAction);
- if (fast) {
- emit doScroll(sliderAction);
- emit doScroll(sliderAction);
- }
- }
- }
- void hideEvent(QHideEvent *) {
- stopTimer();
- }
-
- void mouseMoveEvent(QMouseEvent *e)
- {
- // Enable fast scrolling if the cursor is directly above or below the popup.
- const int mouseX = e->pos().x();
- const int mouseY = e->pos().y();
- const bool horizontallyInside = pos().x() < mouseX && mouseX < rect().right() + 1;
- const bool verticallyOutside = (sliderAction == QAbstractSlider::SliderSingleStepAdd) ?
- rect().bottom() + 1 < mouseY : mouseY < pos().y();
-
- fast = horizontallyInside && verticallyOutside;
- }
-
- void paintEvent(QPaintEvent *) {
- QPainter p(this);
- QStyleOptionMenuItem menuOpt;
- menuOpt.init(this);
- menuOpt.checkType = QStyleOptionMenuItem::NotCheckable;
- menuOpt.menuRect = rect();
- menuOpt.maxIconWidth = 0;
- menuOpt.tabWidth = 0;
- menuOpt.menuItemType = QStyleOptionMenuItem::Scroller;
- if (sliderAction == QAbstractSlider::SliderSingleStepAdd)
- menuOpt.state |= QStyle::State_DownArrow;
-#ifndef Q_WS_S60
- p.eraseRect(rect());
-#endif
- style()->drawControl(QStyle::CE_MenuScroller, &menuOpt, &p);
- }
-
-Q_SIGNALS:
- void doScroll(int action);
-
-private:
- QAbstractSlider::SliderAction sliderAction;
- QBasicTimer timer;
- bool fast;
-};
-
-class Q_AUTOTEST_EXPORT QComboBoxPrivateContainer : public QFrame
-{
- Q_OBJECT
-
-public:
- QComboBoxPrivateContainer(QAbstractItemView *itemView, QComboBox *parent);
- QAbstractItemView *itemView() const;
- void setItemView(QAbstractItemView *itemView);
- int spacing() const;
- void updateTopBottomMargin();
-
- QTimer blockMouseReleaseTimer;
- QBasicTimer adjustSizeTimer;
- QPoint initialClickPosition;
-
-public Q_SLOTS:
- void scrollItemView(int action);
- void updateScrollers();
- void viewDestroyed();
-
-protected:
- void changeEvent(QEvent *e);
- bool eventFilter(QObject *o, QEvent *e);
- void mousePressEvent(QMouseEvent *e);
- void mouseReleaseEvent(QMouseEvent *e);
- void showEvent(QShowEvent *e);
- void hideEvent(QHideEvent *e);
- void timerEvent(QTimerEvent *timerEvent);
- void leaveEvent(QEvent *e);
- void resizeEvent(QResizeEvent *e);
- QStyleOptionComboBox comboStyleOption() const;
-
-Q_SIGNALS:
- void itemSelected(const QModelIndex &);
- void resetButton();
-
-private:
- QComboBox *combo;
- QAbstractItemView *view;
- QComboBoxPrivateScroller *top;
- QComboBoxPrivateScroller *bottom;
-#ifdef QT_SOFTKEYS_ENABLED
- QAction *selectAction;
- QAction *cancelAction;
-#endif
-};
-
-class QComboMenuDelegate : public QAbstractItemDelegate
-{ Q_OBJECT
-public:
- QComboMenuDelegate(QObject *parent, QComboBox *cmb) : QAbstractItemDelegate(parent), mCombo(cmb) {}
-
-protected:
- void paint(QPainter *painter,
- const QStyleOptionViewItem &option,
- const QModelIndex &index) const {
- QStyleOptionMenuItem opt = getStyleOption(option, index);
-#ifndef Q_WS_S60
- painter->fillRect(option.rect, opt.palette.background());
-#endif
- mCombo->style()->drawControl(QStyle::CE_MenuItem, &opt, painter, mCombo);
- }
- QSize sizeHint(const QStyleOptionViewItem &option,
- const QModelIndex &index) const {
- QStyleOptionMenuItem opt = getStyleOption(option, index);
- return mCombo->style()->sizeFromContents(
- QStyle::CT_MenuItem, &opt, option.rect.size(), mCombo);
- }
-
-private:
- QStyleOptionMenuItem getStyleOption(const QStyleOptionViewItem &option,
- const QModelIndex &index) const;
- QComboBox *mCombo;
-};
-
-// Note that this class is intentionally not using QStyledItemDelegate
-// Vista does not use the new theme for combo boxes and there might
-// be other side effects from using the new class
-class QComboBoxDelegate : public QItemDelegate
-{ Q_OBJECT
-public:
- QComboBoxDelegate(QObject *parent, QComboBox *cmb) : QItemDelegate(parent), mCombo(cmb) {}
-
- static bool isSeparator(const QModelIndex &index) {
- return index.data(Qt::AccessibleDescriptionRole).toString() == QLatin1String("separator");
- }
- static void setSeparator(QAbstractItemModel *model, const QModelIndex &index) {
- model->setData(index, QString::fromLatin1("separator"), Qt::AccessibleDescriptionRole);
- if (QStandardItemModel *m = qobject_cast<QStandardItemModel*>(model))
- if (QStandardItem *item = m->itemFromIndex(index))
- item->setFlags(item->flags() & ~(Qt::ItemIsSelectable|Qt::ItemIsEnabled));
- }
-
-protected:
- void paint(QPainter *painter,
- const QStyleOptionViewItem &option,
- const QModelIndex &index) const {
- if (isSeparator(index)) {
- QRect rect = option.rect;
- if (const QStyleOptionViewItemV3 *v3 = qstyleoption_cast<const QStyleOptionViewItemV3*>(&option))
- if (const QAbstractItemView *view = qobject_cast<const QAbstractItemView*>(v3->widget))
- rect.setWidth(view->viewport()->width());
- QStyleOption opt;
- opt.rect = rect;
- mCombo->style()->drawPrimitive(QStyle::PE_IndicatorToolBarSeparator, &opt, painter, mCombo);
- } else {
- QItemDelegate::paint(painter, option, index);
- }
- }
-
- QSize sizeHint(const QStyleOptionViewItem &option,
- const QModelIndex &index) const {
- if (isSeparator(index)) {
- int pm = mCombo->style()->pixelMetric(QStyle::PM_DefaultFrameWidth, 0, mCombo);
- return QSize(pm, pm);
- }
- return QItemDelegate::sizeHint(option, index);
- }
-private:
- QComboBox *mCombo;
-};
-
-class Q_AUTOTEST_EXPORT QComboBoxPrivate : public QWidgetPrivate
-{
- Q_DECLARE_PUBLIC(QComboBox)
-public:
- QComboBoxPrivate();
- ~QComboBoxPrivate() {}
- void init();
- QComboBoxPrivateContainer* viewContainer();
- void updateLineEditGeometry();
- Qt::MatchFlags matchFlags() const;
- void _q_editingFinished();
- void _q_returnPressed();
- void _q_complete();
- void _q_itemSelected(const QModelIndex &item);
- bool contains(const QString &text, int role);
- void emitActivated(const QModelIndex&);
- void _q_emitHighlighted(const QModelIndex&);
- void _q_emitCurrentIndexChanged(const QModelIndex &index);
- void _q_modelDestroyed();
- void _q_modelReset();
-#ifdef QT_KEYPAD_NAVIGATION
- void _q_completerActivated();
-#endif
- void _q_resetButton();
- void _q_dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
- void _q_updateIndexBeforeChange();
- void _q_rowsInserted(const QModelIndex & parent, int start, int end);
- void _q_rowsRemoved(const QModelIndex & parent, int start, int end);
- void updateArrow(QStyle::StateFlag state);
- bool updateHoverControl(const QPoint &pos);
- QRect popupGeometry(int screen = -1) const;
- QStyle::SubControl newHoverControl(const QPoint &pos);
- int computeWidthHint() const;
- QSize recomputeSizeHint(QSize &sh) const;
- void adjustComboBoxSize();
- QString itemText(const QModelIndex &index) const;
- QIcon itemIcon(const QModelIndex &index) const;
- int itemRole() const;
- void updateLayoutDirection();
- void setCurrentIndex(const QModelIndex &index);
- void updateDelegate(bool force = false);
- void keyboardSearchString(const QString &text);
- void modelChanged();
- void updateViewContainerPaletteAndOpacity();
-
- QAbstractItemModel *model;
- QLineEdit *lineEdit;
- QComboBoxPrivateContainer *container;
- QComboBox::InsertPolicy insertPolicy;
- QComboBox::SizeAdjustPolicy sizeAdjustPolicy;
- int minimumContentsLength;
- QSize iconSize;
- uint shownOnce : 1;
- uint autoCompletion : 1;
- uint duplicatesEnabled : 1;
- uint frame : 1;
- uint padding : 26;
- int maxVisibleItems;
- int maxCount;
- int modelColumn;
- bool inserting;
- mutable QSize minimumSizeHint;
- mutable QSize sizeHint;
- QStyle::StateFlag arrowState;
- QStyle::SubControl hoverControl;
- QRect hoverRect;
- QPersistentModelIndex currentIndex;
- QPersistentModelIndex root;
- Qt::CaseSensitivity autoCompletionCaseSensitivity;
- int indexBeforeChange;
-#ifndef QT_NO_COMPLETER
- QPointer<QCompleter> completer;
-#endif
- static QPalette viewContainerPalette(QComboBox *cmb)
- { return cmb->d_func()->viewContainer()->palette(); }
-};
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_COMBOBOX
-
-#endif // QCOMBOBOX_P_H
diff --git a/src/gui/widgets/qcommandlinkbutton.h b/src/gui/widgets/qcommandlinkbutton.h
deleted file mode 100644
index c502d96da0..0000000000
--- a/src/gui/widgets/qcommandlinkbutton.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QCOMMANDLINKBUTTON_H
-#define QCOMMANDLINKBUTTON_H
-
-#include <QtGui/qpushbutton.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QCommandLinkButtonPrivate;
-
-class Q_GUI_EXPORT QCommandLinkButton: public QPushButton
-{
- Q_OBJECT
-
- Q_PROPERTY(QString description READ description WRITE setDescription)
- Q_PROPERTY(bool flat READ isFlat WRITE setFlat DESIGNABLE false)
-
-public:
- explicit QCommandLinkButton(QWidget *parent=0);
- explicit QCommandLinkButton(const QString &text, QWidget *parent=0);
- QCommandLinkButton(const QString &text, const QString &description, QWidget *parent=0);
- QString description() const;
- void setDescription(const QString &description);
-
-protected:
- QSize sizeHint() const;
- int heightForWidth(int) const;
- QSize minimumSizeHint() const;
- bool event(QEvent *e);
- void paintEvent(QPaintEvent *);
-
-private:
- Q_DISABLE_COPY(QCommandLinkButton)
- Q_DECLARE_PRIVATE(QCommandLinkButton)
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QCOMMANDLINKBUTTON
diff --git a/src/gui/widgets/qdatetimeedit.h b/src/gui/widgets/qdatetimeedit.h
deleted file mode 100644
index cd88dbfd12..0000000000
--- a/src/gui/widgets/qdatetimeedit.h
+++ /dev/null
@@ -1,230 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDATETIMEEDIT_H
-#define QDATETIMEEDIT_H
-
-#include <QtCore/qdatetime.h>
-#include <QtCore/qvariant.h>
-#include <QtGui/qabstractspinbox.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_DATETIMEEDIT
-
-class QDateTimeEditPrivate;
-class QStyleOptionSpinBox;
-class QCalendarWidget;
-
-class Q_GUI_EXPORT QDateTimeEdit : public QAbstractSpinBox
-{
- Q_OBJECT
-
- Q_ENUMS(Section)
- Q_FLAGS(Sections)
- Q_PROPERTY(QDateTime dateTime READ dateTime WRITE setDateTime NOTIFY dateTimeChanged USER true)
- Q_PROPERTY(QDate date READ date WRITE setDate NOTIFY dateChanged)
- Q_PROPERTY(QTime time READ time WRITE setTime NOTIFY timeChanged)
- Q_PROPERTY(QDateTime maximumDateTime READ maximumDateTime WRITE setMaximumDateTime RESET clearMaximumDateTime)
- Q_PROPERTY(QDateTime minimumDateTime READ minimumDateTime WRITE setMinimumDateTime RESET clearMinimumDateTime)
- Q_PROPERTY(QDate maximumDate READ maximumDate WRITE setMaximumDate RESET clearMaximumDate)
- Q_PROPERTY(QDate minimumDate READ minimumDate WRITE setMinimumDate RESET clearMinimumDate)
- Q_PROPERTY(QTime maximumTime READ maximumTime WRITE setMaximumTime RESET clearMaximumTime)
- Q_PROPERTY(QTime minimumTime READ minimumTime WRITE setMinimumTime RESET clearMinimumTime)
- Q_PROPERTY(Section currentSection READ currentSection WRITE setCurrentSection)
- Q_PROPERTY(Sections displayedSections READ displayedSections)
- Q_PROPERTY(QString displayFormat READ displayFormat WRITE setDisplayFormat)
- Q_PROPERTY(bool calendarPopup READ calendarPopup WRITE setCalendarPopup)
- Q_PROPERTY(int currentSectionIndex READ currentSectionIndex WRITE setCurrentSectionIndex)
- Q_PROPERTY(int sectionCount READ sectionCount)
- Q_PROPERTY(Qt::TimeSpec timeSpec READ timeSpec WRITE setTimeSpec)
-public:
- enum Section {
- NoSection = 0x0000,
- AmPmSection = 0x0001,
- MSecSection = 0x0002,
- SecondSection = 0x0004,
- MinuteSection = 0x0008,
- HourSection = 0x0010,
- DaySection = 0x0100,
- MonthSection = 0x0200,
- YearSection = 0x0400,
- TimeSections_Mask = AmPmSection|MSecSection|SecondSection|MinuteSection|HourSection,
- DateSections_Mask = DaySection|MonthSection|YearSection
- };
-
- Q_DECLARE_FLAGS(Sections, Section)
-
- explicit QDateTimeEdit(QWidget *parent = 0);
- explicit QDateTimeEdit(const QDateTime &dt, QWidget *parent = 0);
- explicit QDateTimeEdit(const QDate &d, QWidget *parent = 0);
- explicit QDateTimeEdit(const QTime &t, QWidget *parent = 0);
-
- QDateTime dateTime() const;
- QDate date() const;
- QTime time() const;
-
- QDateTime minimumDateTime() const;
- void clearMinimumDateTime();
- void setMinimumDateTime(const QDateTime &dt);
-
- QDateTime maximumDateTime() const;
- void clearMaximumDateTime();
- void setMaximumDateTime(const QDateTime &dt);
-
- void setDateTimeRange(const QDateTime &min, const QDateTime &max);
-
- QDate minimumDate() const;
- void setMinimumDate(const QDate &min);
- void clearMinimumDate();
-
- QDate maximumDate() const;
- void setMaximumDate(const QDate &max);
- void clearMaximumDate();
-
- void setDateRange(const QDate &min, const QDate &max);
-
- QTime minimumTime() const;
- void setMinimumTime(const QTime &min);
- void clearMinimumTime();
-
- QTime maximumTime() const;
- void setMaximumTime(const QTime &max);
- void clearMaximumTime();
-
- void setTimeRange(const QTime &min, const QTime &max);
-
- Sections displayedSections() const;
- Section currentSection() const;
- Section sectionAt(int index) const;
- void setCurrentSection(Section section);
-
- int currentSectionIndex() const;
- void setCurrentSectionIndex(int index);
-
- QCalendarWidget *calendarWidget() const;
- void setCalendarWidget(QCalendarWidget *calendarWidget);
-
- int sectionCount() const;
-
- void setSelectedSection(Section section);
-
- QString sectionText(Section section) const;
-
- QString displayFormat() const;
- void setDisplayFormat(const QString &format);
-
- bool calendarPopup() const;
- void setCalendarPopup(bool enable);
-
- Qt::TimeSpec timeSpec() const;
- void setTimeSpec(Qt::TimeSpec spec);
-
- QSize sizeHint() const;
-
- virtual void clear();
- virtual void stepBy(int steps);
-
- bool event(QEvent *event);
-Q_SIGNALS:
- void dateTimeChanged(const QDateTime &date);
- void timeChanged(const QTime &date);
- void dateChanged(const QDate &date);
-
-public Q_SLOTS:
- void setDateTime(const QDateTime &dateTime);
- void setDate(const QDate &date);
- void setTime(const QTime &time);
-
-protected:
- virtual void keyPressEvent(QKeyEvent *event);
-#ifndef QT_NO_WHEELEVENT
- virtual void wheelEvent(QWheelEvent *event);
-#endif
- virtual void focusInEvent(QFocusEvent *event);
- virtual bool focusNextPrevChild(bool next);
- virtual QValidator::State validate(QString &input, int &pos) const;
- virtual void fixup(QString &input) const;
-
- virtual QDateTime dateTimeFromText(const QString &text) const;
- virtual QString textFromDateTime(const QDateTime &dt) const;
- virtual StepEnabled stepEnabled() const;
- virtual void mousePressEvent(QMouseEvent *event);
- virtual void paintEvent(QPaintEvent *event);
- void initStyleOption(QStyleOptionSpinBox *option) const;
-
- QDateTimeEdit(const QVariant &val, QVariant::Type parserType, QWidget *parent = 0);
-private:
- Q_DECLARE_PRIVATE(QDateTimeEdit)
- Q_DISABLE_COPY(QDateTimeEdit)
-
- Q_PRIVATE_SLOT(d_func(), void _q_resetButton())
-};
-
-class Q_GUI_EXPORT QTimeEdit : public QDateTimeEdit
-{
- Q_OBJECT
-public:
- QTimeEdit(QWidget *parent = 0);
- QTimeEdit(const QTime &time, QWidget *parent = 0);
-};
-
-class Q_GUI_EXPORT QDateEdit : public QDateTimeEdit
-{
- Q_OBJECT
-public:
- QDateEdit(QWidget *parent = 0);
- QDateEdit(const QDate &date, QWidget *parent = 0);
-};
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QDateTimeEdit::Sections)
-
-#endif // QT_NO_DATETIMEEDIT
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QDATETIMEEDIT_H
diff --git a/src/gui/widgets/qdatetimeedit_p.h b/src/gui/widgets/qdatetimeedit_p.h
deleted file mode 100644
index 3c6ca962ab..0000000000
--- a/src/gui/widgets/qdatetimeedit_p.h
+++ /dev/null
@@ -1,185 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDATETIMEEDIT_P_H
-#define QDATETIMEEDIT_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "QtGui/qcombobox.h"
-#include "QtGui/qcalendarwidget.h"
-#include "QtGui/qspinbox.h"
-#include "QtGui/qtoolbutton.h"
-#include "QtGui/qmenu.h"
-#include "QtGui/qlabel.h"
-#include "QtGui/qdatetimeedit.h"
-#include "QtGui/private/qabstractspinbox_p.h"
-#include "QtCore/private/qdatetime_p.h"
-
-#include "qdebug.h"
-
-#ifndef QT_NO_DATETIMEEDIT
-
-QT_BEGIN_NAMESPACE
-
-class QCalendarPopup;
-class QDateTimeEditPrivate : public QAbstractSpinBoxPrivate, public QDateTimeParser
-{
- Q_DECLARE_PUBLIC(QDateTimeEdit)
-public:
- QDateTimeEditPrivate();
-
- void init(const QVariant &var);
- void readLocaleSettings();
-
- void emitSignals(EmitPolicy ep, const QVariant &old);
- QString textFromValue(const QVariant &f) const;
- QVariant valueFromText(const QString &f) const;
- virtual void _q_editorCursorPositionChanged(int oldpos, int newpos);
- virtual void interpret(EmitPolicy ep);
- virtual void clearCache() const;
-
- QDateTime validateAndInterpret(QString &input, int &, QValidator::State &state,
- bool fixup = false) const;
- void clearSection(int index);
- virtual QString displayText() const { return edit->text(); } // this is from QDateTimeParser
-
- int absoluteIndex(QDateTimeEdit::Section s, int index) const;
- int absoluteIndex(const SectionNode &s) const;
- void updateEdit();
- QDateTime stepBy(int index, int steps, bool test = false) const;
- int sectionAt(int pos) const;
- int closestSection(int index, bool forward) const;
- int nextPrevSection(int index, bool forward) const;
- void setSelected(int index, bool forward = false);
-
- void updateCache(const QVariant &val, const QString &str) const;
-
- void updateTimeSpec();
- virtual QDateTime getMinimum() const { return minimum.toDateTime(); }
- virtual QDateTime getMaximum() const { return maximum.toDateTime(); }
- virtual QLocale locale() const { return q_func()->locale(); }
- QString valueToText(const QVariant &var) const { return textFromValue(var); }
- QString getAmPmText(AmPm ap, Case cs) const;
- int cursorPosition() const { return edit ? edit->cursorPosition() : -1; }
-
- virtual QStyle::SubControl newHoverControl(const QPoint &pos);
- virtual void updateEditFieldGeometry();
- virtual QVariant getZeroVariant() const;
- virtual void setRange(const QVariant &min, const QVariant &max);
-
- void _q_resetButton();
- void updateArrow(QStyle::StateFlag state);
- bool calendarPopupEnabled() const;
- void syncCalendarWidget();
-
- bool isSeparatorKey(const QKeyEvent *k) const;
-
- static QDateTimeEdit::Sections convertSections(QDateTimeParser::Sections s);
- static QDateTimeEdit::Section convertToPublic(QDateTimeParser::Section s);
-
- void initCalendarPopup(QCalendarWidget *cw = 0);
- void positionCalendarPopup();
-
- QDateTimeEdit::Sections sections;
- mutable bool cacheGuard;
-
- QString defaultDateFormat, defaultTimeFormat, defaultDateTimeFormat, unreversedFormat;
- mutable QVariant conflictGuard;
- bool hasHadFocus, formatExplicitlySet, calendarPopup;
- QStyle::StateFlag arrowState;
- QCalendarPopup *monthCalendar;
-
-#ifdef QT_KEYPAD_NAVIGATION
- bool focusOnButton;
-#endif
-};
-
-
-class QCalendarPopup : public QWidget
-{
- Q_OBJECT
-public:
- QCalendarPopup(QWidget *parent = 0, QCalendarWidget *cw = 0);
- QDate selectedDate() { return verifyCalendarInstance()->selectedDate(); }
- void setDate(const QDate &date);
- void setDateRange(const QDate &min, const QDate &max);
- void setFirstDayOfWeek(Qt::DayOfWeek dow) { verifyCalendarInstance()->setFirstDayOfWeek(dow); }
- QCalendarWidget *calendarWidget() const { return const_cast<QCalendarPopup*>(this)->verifyCalendarInstance(); }
- void setCalendarWidget(QCalendarWidget *cw);
-Q_SIGNALS:
- void activated(const QDate &date);
- void newDateSelected(const QDate &newDate);
- void hidingCalendar(const QDate &oldDate);
- void resetButton();
-
-private Q_SLOTS:
- void dateSelected(const QDate &date);
- void dateSelectionChanged();
-
-protected:
- void hideEvent(QHideEvent *);
- void mousePressEvent(QMouseEvent *e);
- void mouseReleaseEvent(QMouseEvent *);
- bool event(QEvent *e);
-
-private:
- QCalendarWidget *verifyCalendarInstance();
-
- QWeakPointer<QCalendarWidget> calendar;
- QDate oldDate;
- bool dateChanged;
-};
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_DATETIMEEDIT
-
-#endif // QDATETIMEEDIT_P_H
diff --git a/src/gui/widgets/qdial.h b/src/gui/widgets/qdial.h
deleted file mode 100644
index 89de72467b..0000000000
--- a/src/gui/widgets/qdial.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#ifndef QDIAL_H
-#define QDIAL_H
-
-#include <QtGui/qabstractslider.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_DIAL
-
-class QDialPrivate;
-class QStyleOptionSlider;
-
-class Q_GUI_EXPORT QDial: public QAbstractSlider
-{
- Q_OBJECT
-
- Q_PROPERTY(bool wrapping READ wrapping WRITE setWrapping)
- Q_PROPERTY(int notchSize READ notchSize)
- Q_PROPERTY(qreal notchTarget READ notchTarget WRITE setNotchTarget)
- Q_PROPERTY(bool notchesVisible READ notchesVisible WRITE setNotchesVisible)
-public:
- explicit QDial(QWidget *parent = 0);
-
- ~QDial();
-
- bool wrapping() const;
-
- int notchSize() const;
-
- void setNotchTarget(double target);
- qreal notchTarget() const;
- bool notchesVisible() const;
-
- QSize sizeHint() const;
- QSize minimumSizeHint() const;
-
-public Q_SLOTS:
- void setNotchesVisible(bool visible);
- void setWrapping(bool on);
-
-protected:
- bool event(QEvent *e);
- void resizeEvent(QResizeEvent *re);
- void paintEvent(QPaintEvent *pe);
-
- void mousePressEvent(QMouseEvent *me);
- void mouseReleaseEvent(QMouseEvent *me);
- void mouseMoveEvent(QMouseEvent *me);
-
- void sliderChange(SliderChange change);
- void initStyleOption(QStyleOptionSlider *option) const;
-
-#ifdef QT3_SUPPORT
-public:
- QT3_SUPPORT_CONSTRUCTOR QDial(int minValue, int maxValue, int pageStep, int value,
- QWidget* parent = 0, const char* name = 0);
- QT3_SUPPORT_CONSTRUCTOR QDial(QWidget *parent, const char *name);
-
-Q_SIGNALS:
- QT_MOC_COMPAT void dialPressed();
- QT_MOC_COMPAT void dialMoved(int value);
- QT_MOC_COMPAT void dialReleased();
-#endif
-
-private:
- Q_DECLARE_PRIVATE(QDial)
- Q_DISABLE_COPY(QDial)
-};
-
-#endif // QT_NO_DIAL
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QDIAL_H
diff --git a/src/gui/widgets/qdialogbuttonbox.cpp b/src/gui/widgets/qdialogbuttonbox.cpp
deleted file mode 100644
index 6c29141d66..0000000000
--- a/src/gui/widgets/qdialogbuttonbox.cpp
+++ /dev/null
@@ -1,1285 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtCore/qhash.h>
-#include <QtGui/qpushbutton.h>
-#include <QtGui/qstyle.h>
-#include <QtGui/qlayout.h>
-#include <QtGui/qdialog.h>
-#include <QtGui/qapplication.h>
-#include <QtGui/private/qwidget_p.h>
-#include <QtGui/qaction.h>
-
-#include "qdialogbuttonbox.h"
-
-#ifdef QT_SOFTKEYS_ENABLED
-#include <QtGui/qaction.h>
-#endif
-
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \class QDialogButtonBox
- \since 4.2
- \brief The QDialogButtonBox class is a widget that presents buttons in a
- layout that is appropriate to the current widget style.
-
- \ingroup dialog-classes
-
-
- Dialogs and message boxes typically present buttons in a layout that
- conforms to the interface guidelines for that platform. Invariably,
- different platforms have different layouts for their dialogs.
- QDialogButtonBox allows a developer to add buttons to it and will
- automatically use the appropriate layout for the user's desktop
- environment.
-
- Most buttons for a dialog follow certain roles. Such roles include:
-
- \list
- \o Accepting or rejecting the dialog.
- \o Asking for help.
- \o Performing actions on the dialog itself (such as resetting fields or
- applying changes).
- \endlist
-
- There can also be alternate ways of dismissing the dialog which may cause
- destructive results.
-
- Most dialogs have buttons that can almost be considered standard (e.g.
- \gui OK and \gui Cancel buttons). It is sometimes convenient to create these
- buttons in a standard way.
-
- There are a couple ways of using QDialogButtonBox. One ways is to create
- the buttons (or button texts) yourself and add them to the button box,
- specifying their role.
-
- \snippet examples/dialogs/extension/finddialog.cpp 1
-
- Alternatively, QDialogButtonBox provides several standard buttons (e.g. OK, Cancel, Save)
- that you can use. They exist as flags so you can OR them together in the constructor.
-
- \snippet examples/dialogs/tabdialog/tabdialog.cpp 2
-
- You can mix and match normal buttons and standard buttons.
-
- Currently the buttons are laid out in the following way if the button box is horizontal:
- \table
- \row \o \inlineimage buttonbox-gnomelayout-horizontal.png GnomeLayout Horizontal
- \o Button box laid out in horizontal GnomeLayout
- \row \o \inlineimage buttonbox-kdelayout-horizontal.png KdeLayout Horizontal
- \o Button box laid out in horizontal KdeLayout
- \row \o \inlineimage buttonbox-maclayout-horizontal.png MacLayout Horizontal
- \o Button box laid out in horizontal MacLayout
- \row \o \inlineimage buttonbox-winlayout-horizontal.png WinLayout Horizontal
- \o Button box laid out in horizontal WinLayout
- \endtable
-
- The buttons are laid out the following way if the button box is vertical:
-
- \table
- \row \o GnomeLayout
- \o KdeLayout
- \o MacLayout
- \o WinLayout
- \row \o \inlineimage buttonbox-gnomelayout-vertical.png GnomeLayout Vertical
- \o \inlineimage buttonbox-kdelayout-vertical.png KdeLayout Vertical
- \o \inlineimage buttonbox-maclayout-vertical.png MacLayout Vertical
- \o \inlineimage buttonbox-winlayout-vertical.png WinLayout Vertical
- \endtable
-
- Additionally, button boxes that contain only buttons with ActionRole or
- HelpRole can be considered modeless and have an alternate look on Mac OS X:
-
- \table
- \row \o modeless horizontal MacLayout
- \o \inlineimage buttonbox-mac-modeless-horizontal.png Screenshot of modeless horizontal MacLayout
- \endtable
-
- When a button is clicked in the button box, the clicked() signal is emitted
- for the actual button is that is pressed. For convenience, if the button
- has an AcceptRole, RejectRole, or HelpRole, the accepted(), rejected(), or
- helpRequested() signals are emitted respectively.
-
- If you want a specific button to be default you need to call
- QPushButton::setDefault() on it yourself. However, if there is no default
- button set and to preserve which button is the default button across
- platforms when using the QPushButton::autoDefault property, the first push
- button with the accept role is made the default button when the
- QDialogButtonBox is shown,
-
- \sa QMessageBox, QPushButton, QDialog
-*/
-
-enum {
- AcceptRole = QDialogButtonBox::AcceptRole,
- RejectRole = QDialogButtonBox::RejectRole,
- DestructiveRole = QDialogButtonBox::DestructiveRole,
- ActionRole = QDialogButtonBox::ActionRole,
- HelpRole = QDialogButtonBox::HelpRole,
- YesRole = QDialogButtonBox::YesRole,
- NoRole = QDialogButtonBox::NoRole,
- ApplyRole = QDialogButtonBox::ApplyRole,
- ResetRole = QDialogButtonBox::ResetRole,
-
- AlternateRole = 0x10000000,
- Stretch = 0x20000000,
- EOL = 0x40000000,
- Reverse = 0x80000000
-};
-
-static QDialogButtonBox::ButtonRole roleFor(QDialogButtonBox::StandardButton button)
-{
- switch (button) {
- case QDialogButtonBox::Ok:
- case QDialogButtonBox::Save:
- case QDialogButtonBox::Open:
- case QDialogButtonBox::SaveAll:
- case QDialogButtonBox::Retry:
- case QDialogButtonBox::Ignore:
- return QDialogButtonBox::AcceptRole;
-
- case QDialogButtonBox::Cancel:
- case QDialogButtonBox::Close:
- case QDialogButtonBox::Abort:
- return QDialogButtonBox::RejectRole;
-
- case QDialogButtonBox::Discard:
- return QDialogButtonBox::DestructiveRole;
-
- case QDialogButtonBox::Help:
- return QDialogButtonBox::HelpRole;
-
- case QDialogButtonBox::Apply:
- return QDialogButtonBox::ApplyRole;
-
- case QDialogButtonBox::Yes:
- case QDialogButtonBox::YesToAll:
- return QDialogButtonBox::YesRole;
-
- case QDialogButtonBox::No:
- case QDialogButtonBox::NoToAll:
- return QDialogButtonBox::NoRole;
-
- case QDialogButtonBox::RestoreDefaults:
- case QDialogButtonBox::Reset:
- return QDialogButtonBox::ResetRole;
-
- case QDialogButtonBox::NoButton: // NoButton means zero buttons, not "No" button
- ;
- }
-
- return QDialogButtonBox::InvalidRole;
-}
-
-static const int layouts[2][5][14] =
-{
- // Qt::Horizontal
- {
- // WinLayout
- { ResetRole, Stretch, YesRole, AcceptRole, AlternateRole, DestructiveRole, NoRole, ActionRole, RejectRole, ApplyRole,
- HelpRole, EOL, EOL, EOL },
-
- // MacLayout
- { HelpRole, ResetRole, ApplyRole, ActionRole, Stretch, DestructiveRole | Reverse,
- AlternateRole | Reverse, RejectRole | Reverse, AcceptRole | Reverse, NoRole | Reverse, YesRole | Reverse, EOL, EOL },
-
- // KdeLayout
- { HelpRole, ResetRole, Stretch, YesRole, NoRole, ActionRole, AcceptRole, AlternateRole,
- ApplyRole, DestructiveRole, RejectRole, EOL },
-
- // GnomeLayout
- { HelpRole, ResetRole, Stretch, ActionRole, ApplyRole | Reverse, DestructiveRole | Reverse,
- AlternateRole | Reverse, RejectRole | Reverse, AcceptRole | Reverse, NoRole | Reverse, YesRole | Reverse, EOL },
-
- // Mac modeless
- { ResetRole, ApplyRole, ActionRole, Stretch, HelpRole, EOL, EOL, EOL, EOL, EOL, EOL, EOL, EOL, EOL }
- },
-
- // Qt::Vertical
- {
- // WinLayout
- { ActionRole, YesRole, AcceptRole, AlternateRole, DestructiveRole, NoRole, RejectRole, ApplyRole, ResetRole,
- HelpRole, Stretch, EOL, EOL, EOL },
-
- // MacLayout
- { YesRole, NoRole, AcceptRole, RejectRole, AlternateRole, DestructiveRole, Stretch, ActionRole, ApplyRole,
- ResetRole, HelpRole, EOL, EOL },
-
- // KdeLayout
- { AcceptRole, AlternateRole, ApplyRole, ActionRole, YesRole, NoRole, Stretch, ResetRole,
- DestructiveRole, RejectRole, HelpRole, EOL },
-
- // GnomeLayout
- { YesRole, NoRole, AcceptRole, RejectRole, AlternateRole, DestructiveRole, ApplyRole, ActionRole, Stretch,
- ResetRole, HelpRole, EOL, EOL, EOL },
-
- // Mac modeless
- { ActionRole, ApplyRole, ResetRole, Stretch, HelpRole, EOL, EOL, EOL, EOL, EOL, EOL, EOL, EOL, EOL }
- }
-};
-
-#if defined(QT_SOFTKEYS_ENABLED) && !defined(QT_NO_ACTION)
-class QDialogButtonEnabledProxy : public QObject
-{
-public:
- QDialogButtonEnabledProxy(QObject *parent, QWidget *src, QAction *trg) : QObject(parent), source(src), target(trg)
- {
- source->installEventFilter(this);
- target->setEnabled(source->isEnabled());
- }
- ~QDialogButtonEnabledProxy()
- {
- source->removeEventFilter(this);
- }
- bool eventFilter(QObject *object, QEvent *event)
- {
- if (object == source && event->type() == QEvent::EnabledChange) {
- target->setEnabled(source->isEnabled());
- }
- return false;
- };
-private:
- QWidget *source;
- QAction *target;
-};
-#endif
-
-class QDialogButtonBoxPrivate : public QWidgetPrivate
-{
- Q_DECLARE_PUBLIC(QDialogButtonBox)
-
-public:
- QDialogButtonBoxPrivate(Qt::Orientation orient);
-
- QList<QAbstractButton *> buttonLists[QDialogButtonBox::NRoles];
- QHash<QPushButton *, QDialogButtonBox::StandardButton> standardButtonHash;
-#ifdef QT_SOFTKEYS_ENABLED
- QHash<QAbstractButton *, QAction *> softKeyActions;
-#endif
-
- Qt::Orientation orientation;
- QDialogButtonBox::ButtonLayout layoutPolicy;
- QBoxLayout *buttonLayout;
- bool internalRemove;
- bool center;
-
- void createStandardButtons(QDialogButtonBox::StandardButtons buttons);
-
- void layoutButtons();
- void initLayout();
- void resetLayout();
- QPushButton *createButton(QDialogButtonBox::StandardButton button, bool doLayout = true);
- void addButton(QAbstractButton *button, QDialogButtonBox::ButtonRole role, bool doLayout = true);
- void _q_handleButtonDestroyed();
- void _q_handleButtonClicked();
- void addButtonsToLayout(const QList<QAbstractButton *> &buttonList, bool reverse);
- void retranslateStrings();
- const char *standardButtonText(QDialogButtonBox::StandardButton sbutton) const;
-#if defined(QT_SOFTKEYS_ENABLED) && !defined(QT_NO_ACTION)
- QAction *createSoftKey(QAbstractButton *button, QDialogButtonBox::ButtonRole role);
-#endif
-};
-
-QDialogButtonBoxPrivate::QDialogButtonBoxPrivate(Qt::Orientation orient)
- : orientation(orient), buttonLayout(0), internalRemove(false), center(false)
-{
-}
-
-void QDialogButtonBoxPrivate::initLayout()
-{
- Q_Q(QDialogButtonBox);
- layoutPolicy = QDialogButtonBox::ButtonLayout(q->style()->styleHint(QStyle::SH_DialogButtonLayout, 0, q));
- bool createNewLayout = buttonLayout == 0
- || (orientation == Qt::Horizontal && qobject_cast<QVBoxLayout *>(buttonLayout) != 0)
- || (orientation == Qt::Vertical && qobject_cast<QHBoxLayout *>(buttonLayout) != 0);
- if (createNewLayout) {
- delete buttonLayout;
- if (orientation == Qt::Horizontal)
- buttonLayout = new QHBoxLayout(q);
- else
- buttonLayout = new QVBoxLayout(q);
- }
-
- int left, top, right, bottom;
- setLayoutItemMargins(QStyle::SE_PushButtonLayoutItem);
- getLayoutItemMargins(&left, &top, &right, &bottom);
- buttonLayout->setContentsMargins(-left, -top, -right, -bottom);
-
- if (!q->testAttribute(Qt::WA_WState_OwnSizePolicy)) {
- QSizePolicy sp(QSizePolicy::Expanding, QSizePolicy::Fixed, QSizePolicy::ButtonBox);
- if (orientation == Qt::Vertical)
- sp.transpose();
- q->setSizePolicy(sp);
- q->setAttribute(Qt::WA_WState_OwnSizePolicy, false);
- }
-
- // ### move to a real init() function
- q->setFocusPolicy(Qt::TabFocus);
-}
-
-void QDialogButtonBoxPrivate::resetLayout()
-{
- //delete buttonLayout;
- initLayout();
- layoutButtons();
-}
-
-void QDialogButtonBoxPrivate::addButtonsToLayout(const QList<QAbstractButton *> &buttonList,
- bool reverse)
-{
- int start = reverse ? buttonList.count() - 1 : 0;
- int end = reverse ? -1 : buttonList.count();
- int step = reverse ? -1 : 1;
-
- for (int i = start; i != end; i += step) {
- QAbstractButton *button = buttonList.at(i);
- buttonLayout->addWidget(button);
- button->show();
- }
-}
-
-void QDialogButtonBoxPrivate::layoutButtons()
-{
- Q_Q(QDialogButtonBox);
- const int MacGap = 36 - 8; // 8 is the default gap between a widget and a spacer item
-
- for (int i = buttonLayout->count() - 1; i >= 0; --i) {
- QLayoutItem *item = buttonLayout->takeAt(i);
- if (QWidget *widget = item->widget())
- widget->hide();
- delete item;
- }
-
- int tmpPolicy = layoutPolicy;
-
- static const int M = 5;
- static const int ModalRoles[M] = { AcceptRole, RejectRole, DestructiveRole, YesRole, NoRole };
- if (tmpPolicy == QDialogButtonBox::MacLayout) {
- bool hasModalButton = false;
- for (int i = 0; i < M; ++i) {
- if (!buttonLists[ModalRoles[i]].isEmpty()) {
- hasModalButton = true;
- break;
- }
- }
- if (!hasModalButton)
- tmpPolicy = 4; // Mac modeless
- }
-
- const int *currentLayout = layouts[orientation == Qt::Vertical][tmpPolicy];
-
- if (center)
- buttonLayout->addStretch();
-
- QList<QAbstractButton *> acceptRoleList = buttonLists[AcceptRole];
-
- while (*currentLayout != EOL) {
- int role = (*currentLayout & ~Reverse);
- bool reverse = (*currentLayout & Reverse);
-
- switch (role) {
- case Stretch:
- if (!center)
- buttonLayout->addStretch();
- break;
- case AcceptRole: {
- if (acceptRoleList.isEmpty())
- break;
- // Only the first one
- QAbstractButton *button = acceptRoleList.first();
- buttonLayout->addWidget(button);
- button->show();
- }
- break;
- case AlternateRole:
- {
- if (acceptRoleList.size() < 2)
- break;
- QList<QAbstractButton *> list = acceptRoleList;
- list.removeFirst();
- addButtonsToLayout(list, reverse);
- }
- break;
- case DestructiveRole:
- {
- const QList<QAbstractButton *> &list = buttonLists[role];
-
- /*
- Mac: Insert a gap on the left of the destructive
- buttons to ensure that they don't get too close to
- the help and action buttons (but only if there are
- some buttons to the left of the destructive buttons
- (and the stretch, whence buttonLayout->count() > 1
- and not 0)).
- */
- if (tmpPolicy == QDialogButtonBox::MacLayout
- && !list.isEmpty() && buttonLayout->count() > 1)
- buttonLayout->addSpacing(MacGap);
-
- addButtonsToLayout(list, reverse);
-
- /*
- Insert a gap between the destructive buttons and the
- accept and reject buttons.
- */
- if (tmpPolicy == QDialogButtonBox::MacLayout && !list.isEmpty())
- buttonLayout->addSpacing(MacGap);
- }
- break;
- case RejectRole:
- case ActionRole:
- case HelpRole:
- case YesRole:
- case NoRole:
- case ApplyRole:
- case ResetRole:
- addButtonsToLayout(buttonLists[role], reverse);
- }
- ++currentLayout;
- }
-
- QWidget *lastWidget = 0;
- q->setFocusProxy(0);
- for (int i = 0; i < buttonLayout->count(); ++i) {
- QLayoutItem *item = buttonLayout->itemAt(i);
- if (QWidget *widget = item->widget()) {
- if (lastWidget)
- QWidget::setTabOrder(lastWidget, widget);
- else
- q->setFocusProxy(widget);
- lastWidget = widget;
- }
- }
-
- if (center)
- buttonLayout->addStretch();
-}
-
-QPushButton *QDialogButtonBoxPrivate::createButton(QDialogButtonBox::StandardButton sbutton,
- bool doLayout)
-{
- Q_Q(QDialogButtonBox);
- const char *buttonText = 0;
- int icon = 0;
-
- switch (sbutton) {
- case QDialogButtonBox::Ok:
- icon = QStyle::SP_DialogOkButton;
- break;
- case QDialogButtonBox::Save:
- icon = QStyle::SP_DialogSaveButton;
- break;
- case QDialogButtonBox::Open:
- icon = QStyle::SP_DialogOpenButton;
- break;
- case QDialogButtonBox::Cancel:
- icon = QStyle::SP_DialogCancelButton;
- break;
- case QDialogButtonBox::Close:
- icon = QStyle::SP_DialogCloseButton;
- break;
- case QDialogButtonBox::Apply:
- icon = QStyle::SP_DialogApplyButton;
- break;
- case QDialogButtonBox::Reset:
- icon = QStyle::SP_DialogResetButton;
- break;
- case QDialogButtonBox::Help:
- icon = QStyle::SP_DialogHelpButton;
- break;
- case QDialogButtonBox::Discard:
- icon = QStyle::SP_DialogDiscardButton;
- break;
- case QDialogButtonBox::Yes:
- icon = QStyle::SP_DialogYesButton;
- break;
- case QDialogButtonBox::No:
- icon = QStyle::SP_DialogNoButton;
- break;
- case QDialogButtonBox::YesToAll:
- case QDialogButtonBox::NoToAll:
- case QDialogButtonBox::SaveAll:
- case QDialogButtonBox::Abort:
- case QDialogButtonBox::Retry:
- case QDialogButtonBox::Ignore:
- case QDialogButtonBox::RestoreDefaults:
- break;
- case QDialogButtonBox::NoButton:
- return 0;
- ;
- }
- buttonText = standardButtonText(sbutton);
-
- QPushButton *button = new QPushButton(QDialogButtonBox::tr(buttonText), q);
- QStyle *style = q->style();
- if (style->styleHint(QStyle::SH_DialogButtonBox_ButtonsHaveIcons, 0, q) && icon != 0)
- button->setIcon(style->standardIcon(QStyle::StandardPixmap(icon), 0, q));
- if (style != QApplication::style()) // Propagate style
- button->setStyle(style);
- standardButtonHash.insert(button, sbutton);
- if (roleFor(sbutton) != QDialogButtonBox::InvalidRole) {
- addButton(button, roleFor(sbutton), doLayout);
- } else {
- qWarning("QDialogButtonBox::createButton: Invalid ButtonRole, button not added");
- }
-
-#ifdef Q_WS_MAC
- // Since mnemonics is off by default on Mac, we add a Cmd-D
- // shortcut here to e.g. make the "Don't Save" button work nativly:
- if (sbutton == QDialogButtonBox::Discard)
- button->setShortcut(QKeySequence(QLatin1String("Ctrl+D")));
-#endif
-
- return button;
-}
-
-void QDialogButtonBoxPrivate::addButton(QAbstractButton *button, QDialogButtonBox::ButtonRole role,
- bool doLayout)
-{
- Q_Q(QDialogButtonBox);
- QObject::connect(button, SIGNAL(clicked()), q, SLOT(_q_handleButtonClicked()));
- QObject::connect(button, SIGNAL(destroyed()), q, SLOT(_q_handleButtonDestroyed()));
- buttonLists[role].append(button);
-#if defined(QT_SOFTKEYS_ENABLED) && !defined(QT_NO_ACTION)
- QAction *action = createSoftKey(button, role);
- softKeyActions.insert(button, action);
- new QDialogButtonEnabledProxy(action, button, action);
-#endif
- if (doLayout)
- layoutButtons();
-}
-
-#if defined(QT_SOFTKEYS_ENABLED) && !defined(QT_NO_ACTION)
-QAction* QDialogButtonBoxPrivate::createSoftKey(QAbstractButton *button, QDialogButtonBox::ButtonRole role)
-{
- Q_Q(QDialogButtonBox);
- QAction::SoftKeyRole softkeyRole;
-
- QAction *action = new QAction(button->text(), button);
-
- switch (role) {
- case ApplyRole:
- case AcceptRole:
- case YesRole:
- case ActionRole:
- case HelpRole:
- softkeyRole = QAction::PositiveSoftKey;
- break;
- case RejectRole:
- case DestructiveRole:
- case NoRole:
- case ResetRole:
- softkeyRole = QAction::NegativeSoftKey;
- break;
- default:
- break;
- }
- QObject::connect(action, SIGNAL(triggered()), button, SIGNAL(clicked()));
- action->setSoftKeyRole(softkeyRole);
-
-
- QWidget *dialog = 0;
- QWidget *p = q;
- while (p && !p->isWindow()) {
- p = p->parentWidget();
- if ((dialog = qobject_cast<QDialog *>(p)))
- break;
- }
-
- if (dialog) {
- dialog->addAction(action);
- } else {
- q->addAction(action);
- }
-
- return action;
-}
-#endif
-
-void QDialogButtonBoxPrivate::createStandardButtons(QDialogButtonBox::StandardButtons buttons)
-{
- uint i = QDialogButtonBox::FirstButton;
- while (i <= QDialogButtonBox::LastButton) {
- if (i & buttons) {
- createButton(QDialogButtonBox::StandardButton(i), false);
- }
- i = i << 1;
- }
- layoutButtons();
-}
-
-const char *QDialogButtonBoxPrivate::standardButtonText(QDialogButtonBox::StandardButton sbutton) const
-{
- const char *buttonText = 0;
- bool gnomeLayout = (layoutPolicy == QDialogButtonBox::GnomeLayout);
- switch (sbutton) {
- case QDialogButtonBox::Ok:
- buttonText = gnomeLayout ? QT_TRANSLATE_NOOP("QDialogButtonBox", "&OK") : QT_TRANSLATE_NOOP("QDialogButtonBox", "OK");
- break;
- case QDialogButtonBox::Save:
- buttonText = gnomeLayout ? QT_TRANSLATE_NOOP("QDialogButtonBox", "&Save") : QT_TRANSLATE_NOOP("QDialogButtonBox", "Save");
- break;
- case QDialogButtonBox::Open:
- buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "Open");
- break;
- case QDialogButtonBox::Cancel:
- buttonText = gnomeLayout ? QT_TRANSLATE_NOOP("QDialogButtonBox", "&Cancel") : QT_TRANSLATE_NOOP("QDialogButtonBox", "Cancel");
- break;
- case QDialogButtonBox::Close:
- buttonText = gnomeLayout ? QT_TRANSLATE_NOOP("QDialogButtonBox", "&Close") : QT_TRANSLATE_NOOP("QDialogButtonBox", "Close");
- break;
- case QDialogButtonBox::Apply:
- buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "Apply");
- break;
- case QDialogButtonBox::Reset:
- buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "Reset");
- break;
- case QDialogButtonBox::Help:
- buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "Help");
- break;
- case QDialogButtonBox::Discard:
- if (layoutPolicy == QDialogButtonBox::MacLayout)
- buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "Don't Save");
- else if (layoutPolicy == QDialogButtonBox::GnomeLayout)
- buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "Close without Saving");
- else
- buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "Discard");
- break;
- case QDialogButtonBox::Yes:
- buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "&Yes");
- break;
- case QDialogButtonBox::YesToAll:
- buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "Yes to &All");
- break;
- case QDialogButtonBox::No:
- buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "&No");
- break;
- case QDialogButtonBox::NoToAll:
- buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "N&o to All");
- break;
- case QDialogButtonBox::SaveAll:
- buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "Save All");
- break;
- case QDialogButtonBox::Abort:
- buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "Abort");
- break;
- case QDialogButtonBox::Retry:
- buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "Retry");
- break;
- case QDialogButtonBox::Ignore:
- buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "Ignore");
- break;
- case QDialogButtonBox::RestoreDefaults:
- buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "Restore Defaults");
- break;
- case QDialogButtonBox::NoButton:
- ;
- } // switch
- return buttonText;
-}
-
-void QDialogButtonBoxPrivate::retranslateStrings()
-{
- const char *buttonText = 0;
- QHash<QPushButton *, QDialogButtonBox::StandardButton>::iterator it = standardButtonHash.begin();
- while (it != standardButtonHash.end()) {
- buttonText = standardButtonText(it.value());
- if (buttonText) {
- QPushButton *button = it.key();
- button->setText(QDialogButtonBox::tr(buttonText));
-#if defined(QT_SOFTKEYS_ENABLED) && !defined(QT_NO_ACTION)
- QAction *action = softKeyActions.value(button, 0);
- if (action)
- action->setText(button->text());
-#endif
- }
- ++it;
- }
-}
-
-/*!
- Constructs an empty, horizontal button box with the given \a parent.
-
- \sa orientation, addButton()
-*/
-QDialogButtonBox::QDialogButtonBox(QWidget *parent)
- : QWidget(*new QDialogButtonBoxPrivate(Qt::Horizontal), parent, 0)
-{
- d_func()->initLayout();
-}
-
-/*!
- Constructs an empty button box with the given \a orientation and \a parent.
-
- \sa orientation, addButton()
-*/
-QDialogButtonBox::QDialogButtonBox(Qt::Orientation orientation, QWidget *parent)
- : QWidget(*new QDialogButtonBoxPrivate(orientation), parent, 0)
-{
- d_func()->initLayout();
-}
-
-/*!
- Constructs a button box with the given \a orientation and \a parent, containing
- the standard buttons specified by \a buttons.
-
- \sa orientation, addButton()
-*/
-QDialogButtonBox::QDialogButtonBox(StandardButtons buttons, Qt::Orientation orientation,
- QWidget *parent)
- : QWidget(*new QDialogButtonBoxPrivate(orientation), parent, 0)
-{
- d_func()->initLayout();
- d_func()->createStandardButtons(buttons);
-}
-
-/*!
- Destroys the button box.
-*/
-QDialogButtonBox::~QDialogButtonBox()
-{
-}
-
-/*!
- \enum QDialogButtonBox::ButtonRole
- \enum QMessageBox::ButtonRole
-
- This enum describes the roles that can be used to describe buttons in
- the button box. Combinations of these roles are as flags used to
- describe different aspects of their behavior.
-
- \value InvalidRole The button is invalid.
- \value AcceptRole Clicking the button causes the dialog to be accepted
- (e.g. OK).
- \value RejectRole Clicking the button causes the dialog to be rejected
- (e.g. Cancel).
- \value DestructiveRole Clicking the button causes a destructive change
- (e.g. for Discarding Changes) and closes the dialog.
- \value ActionRole Clicking the button causes changes to the elements within
- the dialog.
- \value HelpRole The button can be clicked to request help.
- \value YesRole The button is a "Yes"-like button.
- \value NoRole The button is a "No"-like button.
- \value ApplyRole The button applies current changes.
- \value ResetRole The button resets the dialog's fields to default values.
-
- \omitvalue NRoles
-
- \sa StandardButton
-*/
-
-/*!
- \enum QDialogButtonBox::StandardButton
-
- These enums describe flags for standard buttons. Each button has a
- defined \l ButtonRole.
-
- \value Ok An "OK" button defined with the \l AcceptRole.
- \value Open A "Open" button defined with the \l AcceptRole.
- \value Save A "Save" button defined with the \l AcceptRole.
- \value Cancel A "Cancel" button defined with the \l RejectRole.
- \value Close A "Close" button defined with the \l RejectRole.
- \value Discard A "Discard" or "Don't Save" button, depending on the platform,
- defined with the \l DestructiveRole.
- \value Apply An "Apply" button defined with the \l ApplyRole.
- \value Reset A "Reset" button defined with the \l ResetRole.
- \value RestoreDefaults A "Restore Defaults" button defined with the \l ResetRole.
- \value Help A "Help" button defined with the \l HelpRole.
- \value SaveAll A "Save All" button defined with the \l AcceptRole.
- \value Yes A "Yes" button defined with the \l YesRole.
- \value YesToAll A "Yes to All" button defined with the \l YesRole.
- \value No A "No" button defined with the \l NoRole.
- \value NoToAll A "No to All" button defined with the \l NoRole.
- \value Abort An "Abort" button defined with the \l RejectRole.
- \value Retry A "Retry" button defined with the \l AcceptRole.
- \value Ignore An "Ignore" button defined with the \l AcceptRole.
-
- \value NoButton An invalid button.
-
- \omitvalue FirstButton
- \omitvalue LastButton
-
- \sa ButtonRole, standardButtons
-*/
-
-/*!
- \enum QDialogButtonBox::ButtonLayout
-
- This enum describes the layout policy to be used when arranging the buttons
- contained in the button box.
-
- \value WinLayout Use a policy appropriate for applications on Windows.
- \value MacLayout Use a policy appropriate for applications on Mac OS X.
- \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}. However,
- on the X11 platform, it may be influenced by the desktop environment.
-*/
-
-/*!
- \fn void QDialogButtonBox::clicked(QAbstractButton *button)
-
- This signal is emitted when a button inside the button box is clicked. The
- specific button that was pressed is specified by \a button.
-
- \sa accepted(), rejected(), helpRequested()
-*/
-
-/*!
- \fn void QDialogButtonBox::accepted()
-
- This signal is emitted when a button inside the button box is clicked, as long
- as it was defined with the \l AcceptRole or \l YesRole.
-
- \sa rejected(), clicked() helpRequested()
-*/
-
-/*!
- \fn void QDialogButtonBox::rejected()
-
- This signal is emitted when a button inside the button box is clicked, as long
- as it was defined with the \l RejectRole or \l NoRole.
-
- \sa accepted() helpRequested() clicked()
-*/
-
-/*!
- \fn void QDialogButtonBox::helpRequested()
-
- This signal is emitted when a button inside the button box is clicked, as long
- as it was defined with the \l HelpRole.
-
- \sa accepted() rejected() clicked()
-*/
-
-/*!
- \property QDialogButtonBox::orientation
- \brief the orientation of the button box
-
- By default, the orientation is horizontal (i.e. the buttons are laid out
- side by side). The possible orientations are Qt::Horizontal and
- Qt::Vertical.
-*/
-Qt::Orientation QDialogButtonBox::orientation() const
-{
- return d_func()->orientation;
-}
-
-void QDialogButtonBox::setOrientation(Qt::Orientation orientation)
-{
- Q_D(QDialogButtonBox);
- if (orientation == d->orientation)
- return;
-
- d->orientation = orientation;
- d->resetLayout();
-}
-
-/*!
- Clears the button box, deleting all buttons within it.
-
- \sa removeButton(), addButton()
-*/
-void QDialogButtonBox::clear()
-{
- Q_D(QDialogButtonBox);
-#ifdef QT_SOFTKEYS_ENABLED
- // Delete softkey actions as they have the buttons as parents
- qDeleteAll(d->softKeyActions.values());
- d->softKeyActions.clear();
-#endif
- // Remove the created standard buttons, they should be in the other lists, which will
- // do the deletion
- d->standardButtonHash.clear();
- for (int i = 0; i < NRoles; ++i) {
- QList<QAbstractButton *> &list = d->buttonLists[i];
- while (list.count()) {
- QAbstractButton *button = list.takeAt(0);
- QObject::disconnect(button, SIGNAL(destroyed()), this, SLOT(_q_handleButtonDestroyed()));
- delete button;
- }
- }
-}
-
-/*!
- Returns a list of all the buttons that have been added to the button box.
-
- \sa buttonRole(), addButton(), removeButton()
-*/
-QList<QAbstractButton *> QDialogButtonBox::buttons() const
-{
- Q_D(const QDialogButtonBox);
- QList<QAbstractButton *> finalList;
- for (int i = 0; i < NRoles; ++i) {
- const QList<QAbstractButton *> &list = d->buttonLists[i];
- for (int j = 0; j < list.count(); ++j)
- finalList.append(list.at(j));
- }
- return finalList;
-}
-
-/*!
- Returns the button role for the specified \a button. This function returns
- \l InvalidRole if \a button is 0 or has not been added to the button box.
-
- \sa buttons(), addButton()
-*/
-QDialogButtonBox::ButtonRole QDialogButtonBox::buttonRole(QAbstractButton *button) const
-{
- Q_D(const QDialogButtonBox);
- for (int i = 0; i < NRoles; ++i) {
- const QList<QAbstractButton *> &list = d->buttonLists[i];
- for (int j = 0; j < list.count(); ++j) {
- if (list.at(j) == button)
- return ButtonRole(i);
- }
- }
- return InvalidRole;
-}
-
-/*!
- Removes \a button from the button box without deleting it and sets its parent to zero.
-
- \sa clear(), buttons(), addButton()
-*/
-void QDialogButtonBox::removeButton(QAbstractButton *button)
-{
- Q_D(QDialogButtonBox);
-
- if (!button)
- return;
-
- // Remove it from the standard button hash first and then from the roles
- if (QPushButton *pushButton = qobject_cast<QPushButton *>(button))
- d->standardButtonHash.remove(pushButton);
- for (int i = 0; i < NRoles; ++i) {
- QList<QAbstractButton *> &list = d->buttonLists[i];
- for (int j = 0; j < list.count(); ++j) {
- if (list.at(j) == button) {
- list.takeAt(j);
- if (!d->internalRemove) {
- disconnect(button, SIGNAL(clicked()), this, SLOT(_q_handleButtonClicked()));
- disconnect(button, SIGNAL(destroyed()), this, SLOT(_q_handleButtonDestroyed()));
- }
- break;
- }
- }
- }
-#if defined(QT_SOFTKEYS_ENABLED) && !defined(QT_NO_ACTION)
- QAction *action = d->softKeyActions.value(button, 0);
- if (action) {
- d->softKeyActions.remove(button);
- delete action;
- }
-#endif
- if (!d->internalRemove)
- button->setParent(0);
-}
-
-/*!
- Adds the given \a button to the button box with the specified \a role.
- If the role is invalid, the button is not added.
-
- If the button has already been added, it is removed and added again with the
- new role.
-
- \note The button box takes ownership of the button.
-
- \sa removeButton(), clear()
-*/
-void QDialogButtonBox::addButton(QAbstractButton *button, ButtonRole role)
-{
- Q_D(QDialogButtonBox);
- if (role <= InvalidRole || role >= NRoles) {
- qWarning("QDialogButtonBox::addButton: Invalid ButtonRole, button not added");
- return;
- }
- removeButton(button);
- button->setParent(this);
- d->addButton(button, role);
-}
-
-/*!
- Creates a push button with the given \a text, adds it to the button box for the
- specified \a role, and returns the corresponding push button. If \a role is
- invalid, no button is created, and zero is returned.
-
- \sa removeButton(), clear()
-*/
-QPushButton *QDialogButtonBox::addButton(const QString &text, ButtonRole role)
-{
- Q_D(QDialogButtonBox);
- if (role <= InvalidRole || role >= NRoles) {
- qWarning("QDialogButtonBox::addButton: Invalid ButtonRole, button not added");
- return 0;
- }
- QPushButton *button = new QPushButton(text, this);
- d->addButton(button, role);
- return button;
-}
-
-/*!
- Adds a standard \a button to the button box if it is valid to do so, and returns
- a push button. If \a button is invalid, it is not added to the button box, and
- zero is returned.
-
- \sa removeButton(), clear()
-*/
-QPushButton *QDialogButtonBox::addButton(StandardButton button)
-{
- Q_D(QDialogButtonBox);
- return d->createButton(button);
-}
-
-/*!
- \property QDialogButtonBox::standardButtons
- \brief collection of standard buttons in the button box
-
- This property controls which standard buttons are used by the button box.
-
- \sa addButton()
-*/
-void QDialogButtonBox::setStandardButtons(StandardButtons buttons)
-{
- Q_D(QDialogButtonBox);
-#ifdef QT_SOFTKEYS_ENABLED
- // Delete softkey actions since they have the buttons as parents
- qDeleteAll(d->softKeyActions.values());
- d->softKeyActions.clear();
-#endif
- // Clear out all the old standard buttons, then recreate them.
- qDeleteAll(d->standardButtonHash.keys());
- d->standardButtonHash.clear();
-
- d->createStandardButtons(buttons);
-}
-
-QDialogButtonBox::StandardButtons QDialogButtonBox::standardButtons() const
-{
- Q_D(const QDialogButtonBox);
- StandardButtons standardButtons = NoButton;
- QHash<QPushButton *, StandardButton>::const_iterator it = d->standardButtonHash.constBegin();
- while (it != d->standardButtonHash.constEnd()) {
- standardButtons |= it.value();
- ++it;
- }
- return standardButtons;
-}
-
-/*!
- Returns the QPushButton corresponding to the standard button \a which,
- or 0 if the standard button doesn't exist in this button box.
-
- \sa standardButton(), standardButtons(), buttons()
-*/
-QPushButton *QDialogButtonBox::button(StandardButton which) const
-{
- Q_D(const QDialogButtonBox);
- return d->standardButtonHash.key(which);
-}
-
-/*!
- Returns the standard button enum value corresponding to the given \a button,
- or NoButton if the given \a button isn't a standard button.
-
- \sa button(), buttons(), standardButtons()
-*/
-QDialogButtonBox::StandardButton QDialogButtonBox::standardButton(QAbstractButton *button) const
-{
- Q_D(const QDialogButtonBox);
- return d->standardButtonHash.value(static_cast<QPushButton *>(button));
-}
-
-void QDialogButtonBoxPrivate::_q_handleButtonClicked()
-{
- Q_Q(QDialogButtonBox);
- if (QAbstractButton *button = qobject_cast<QAbstractButton *>(q->sender())) {
- emit q->clicked(button);
-
- switch (q->buttonRole(button)) {
- case AcceptRole:
- case YesRole:
- emit q->accepted();
- break;
- case RejectRole:
- case NoRole:
- emit q->rejected();
- break;
- case HelpRole:
- emit q->helpRequested();
- break;
- default:
- break;
- }
- }
-}
-
-void QDialogButtonBoxPrivate::_q_handleButtonDestroyed()
-{
- Q_Q(QDialogButtonBox);
- if (QObject *object = q->sender()) {
- QBoolBlocker skippy(internalRemove);
- q->removeButton(static_cast<QAbstractButton *>(object));
- }
-}
-
-/*!
- \property QDialogButtonBox::centerButtons
- \brief whether the buttons in the button box are centered
-
- By default, this property is false. This behavior is appopriate
- for most types of dialogs. A notable exception is message boxes
- on most platforms (e.g. Windows), where the button box is
- centered horizontally.
-
- \sa QMessageBox
-*/
-void QDialogButtonBox::setCenterButtons(bool center)
-{
- Q_D(QDialogButtonBox);
- if (d->center != center) {
- d->center = center;
- d->resetLayout();
- }
-}
-
-bool QDialogButtonBox::centerButtons() const
-{
- Q_D(const QDialogButtonBox);
- return d->center;
-}
-
-/*!
- \reimp
-*/
-void QDialogButtonBox::changeEvent(QEvent *event)
-{
- typedef QHash<QPushButton *, QDialogButtonBox::StandardButton> StandardButtonHash;
-
- Q_D(QDialogButtonBox);
- switch (event->type()) {
- case QEvent::StyleChange: // Propagate style
- if (!d->standardButtonHash.empty()) {
- QStyle *newStyle = style();
- const StandardButtonHash::iterator end = d->standardButtonHash.end();
- for (StandardButtonHash::iterator it = d->standardButtonHash.begin(); it != end; ++it)
- it.key()->setStyle(newStyle);
- }
- // fallthrough intended
-#ifdef Q_WS_MAC
- case QEvent::MacSizeChange:
-#endif
- d->resetLayout();
- QWidget::changeEvent(event);
- break;
- default:
- QWidget::changeEvent(event);
- break;
- }
-}
-
-/*!
- \reimp
-*/
-bool QDialogButtonBox::event(QEvent *event)
-{
- Q_D(QDialogButtonBox);
- if (event->type() == QEvent::Show) {
- QList<QAbstractButton *> acceptRoleList = d->buttonLists[AcceptRole];
- QPushButton *firstAcceptButton = acceptRoleList.isEmpty() ? 0 : qobject_cast<QPushButton *>(acceptRoleList.at(0));
- bool hasDefault = false;
- QWidget *dialog = 0;
- QWidget *p = this;
- while (p && !p->isWindow()) {
- p = p->parentWidget();
- if ((dialog = qobject_cast<QDialog *>(p)))
- break;
- }
-
- foreach (QPushButton *pb, (dialog ? dialog : this)->findChildren<QPushButton *>()) {
- if (pb->isDefault() && pb != firstAcceptButton) {
- hasDefault = true;
- break;
- }
- }
- if (!hasDefault && firstAcceptButton)
- firstAcceptButton->setDefault(true);
-#ifdef QT_SOFTKEYS_ENABLED
- if (dialog)
- setFixedSize(0,0);
-#endif
- }else if (event->type() == QEvent::LanguageChange) {
- d->retranslateStrings();
- }
-#if defined(QT_SOFTKEYS_ENABLED) && !defined(QT_NO_ACTION)
- else if (event->type() == QEvent::ParentChange) {
- QWidget *dialog = 0;
- QWidget *p = this;
- while (p && !p->isWindow()) {
- p = p->parentWidget();
- if ((dialog = qobject_cast<QDialog *>(p)))
- break;
- }
-
- // If the parent changes, then move the softkeys
- for (QHash<QAbstractButton *, QAction *>::const_iterator it = d->softKeyActions.constBegin();
- it != d->softKeyActions.constEnd(); ++it) {
- QAction *current = it.value();
- QList<QWidget *> widgets = current->associatedWidgets();
- foreach (QWidget *w, widgets)
- w->removeAction(current);
- if (dialog)
- dialog->addAction(current);
- else
- addAction(current);
- }
- }
-#endif
-
- return QWidget::event(event);
-}
-
-QT_END_NAMESPACE
-
-#include "moc_qdialogbuttonbox.cpp"
diff --git a/src/gui/widgets/qdialogbuttonbox.h b/src/gui/widgets/qdialogbuttonbox.h
deleted file mode 100644
index 3b022e92ee..0000000000
--- a/src/gui/widgets/qdialogbuttonbox.h
+++ /dev/null
@@ -1,168 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDIALOGBUTTONBOX_H
-#define QDIALOGBUTTONBOX_H
-
-#include <QtGui/qwidget.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QAbstractButton;
-class QPushButton;
-class QDialogButtonBoxPrivate;
-
-class Q_GUI_EXPORT QDialogButtonBox : public QWidget
-{
- Q_OBJECT
- Q_FLAGS(StandardButtons)
- Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation)
- Q_PROPERTY(StandardButtons standardButtons READ standardButtons WRITE setStandardButtons)
- Q_PROPERTY(bool centerButtons READ centerButtons WRITE setCenterButtons)
-
-public:
- enum ButtonRole {
- // keep this in sync with QMessageBox::ButtonRole
- InvalidRole = -1,
- AcceptRole,
- RejectRole,
- DestructiveRole,
- ActionRole,
- HelpRole,
- YesRole,
- NoRole,
- ResetRole,
- ApplyRole,
-
- NRoles
- };
-
- enum StandardButton {
- // keep this in sync with QMessageBox::StandardButton
- NoButton = 0x00000000,
- Ok = 0x00000400,
- Save = 0x00000800,
- SaveAll = 0x00001000,
- Open = 0x00002000,
- Yes = 0x00004000,
- YesToAll = 0x00008000,
- No = 0x00010000,
- NoToAll = 0x00020000,
- Abort = 0x00040000,
- Retry = 0x00080000,
- Ignore = 0x00100000,
- Close = 0x00200000,
- Cancel = 0x00400000,
- Discard = 0x00800000,
- Help = 0x01000000,
- Apply = 0x02000000,
- Reset = 0x04000000,
- RestoreDefaults = 0x08000000,
-
-#ifndef Q_MOC_RUN
- FirstButton = Ok,
- LastButton = RestoreDefaults
-#endif
- };
-
- Q_DECLARE_FLAGS(StandardButtons, StandardButton)
-
- enum ButtonLayout {
- WinLayout,
- MacLayout,
- KdeLayout,
- GnomeLayout
- };
-
- QDialogButtonBox(QWidget *parent = 0);
- QDialogButtonBox(Qt::Orientation orientation, QWidget *parent = 0);
- QDialogButtonBox(StandardButtons buttons, Qt::Orientation orientation = Qt::Horizontal,
- QWidget *parent = 0);
- ~QDialogButtonBox();
-
- void setOrientation(Qt::Orientation orientation);
- Qt::Orientation orientation() const;
-
- void addButton(QAbstractButton *button, ButtonRole role);
- QPushButton *addButton(const QString &text, ButtonRole role);
- QPushButton *addButton(StandardButton button);
- void removeButton(QAbstractButton *button);
- void clear();
-
- QList<QAbstractButton *> buttons() const;
- ButtonRole buttonRole(QAbstractButton *button) const;
-
- void setStandardButtons(StandardButtons buttons);
- StandardButtons standardButtons() const;
- StandardButton standardButton(QAbstractButton *button) const;
- QPushButton *button(StandardButton which) const;
-
- void setCenterButtons(bool center);
- bool centerButtons() const;
-
-Q_SIGNALS:
- void clicked(QAbstractButton *button);
- void accepted();
- void helpRequested();
- void rejected();
-
-protected:
- void changeEvent(QEvent *event);
- bool event(QEvent *event);
-
-private:
- Q_DISABLE_COPY(QDialogButtonBox)
- Q_DECLARE_PRIVATE(QDialogButtonBox)
- Q_PRIVATE_SLOT(d_func(), void _q_handleButtonClicked())
- Q_PRIVATE_SLOT(d_func(), void _q_handleButtonDestroyed())
-};
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QDialogButtonBox::StandardButtons)
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QDIALOGBUTTONBOX_H
diff --git a/src/gui/widgets/qdockarealayout.cpp b/src/gui/widgets/qdockarealayout.cpp
deleted file mode 100644
index 83506e5012..0000000000
--- a/src/gui/widgets/qdockarealayout.cpp
+++ /dev/null
@@ -1,3329 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "QtGui/qapplication.h"
-#include "QtGui/qwidget.h"
-#include "QtGui/qtabbar.h"
-#include "QtGui/qstyle.h"
-#include "QtGui/qdesktopwidget.h"
-#include "QtCore/qvariant.h"
-#include "qdockarealayout_p.h"
-#include "qdockwidget.h"
-#include "qmainwindow.h"
-#include "qwidgetanimator_p.h"
-#include "qmainwindowlayout_p.h"
-#include "qdockwidget_p.h"
-#include <private/qlayoutengine_p.h>
-
-#include <qpainter.h>
-#include <qstyleoption.h>
-
-#ifndef QT_NO_DOCKWIDGET
-
-QT_BEGIN_NAMESPACE
-
-// qmainwindow.cpp
-extern QMainWindowLayout *qt_mainwindow_layout(const QMainWindow *window);
-
-enum { StateFlagVisible = 1, StateFlagFloating = 2 };
-
-/******************************************************************************
-** QPlaceHolderItem
-*/
-
-QPlaceHolderItem::QPlaceHolderItem(QWidget *w)
-{
- objectName = w->objectName();
- hidden = w->isHidden();
- window = w->isWindow();
- if (window)
- topLevelRect = w->geometry();
-}
-
-/******************************************************************************
-** QDockAreaLayoutItem
-*/
-
-QDockAreaLayoutItem::QDockAreaLayoutItem(QLayoutItem *_widgetItem)
- : widgetItem(_widgetItem), subinfo(0), placeHolderItem(0), pos(0), size(-1), flags(NoFlags)
-{
-}
-
-QDockAreaLayoutItem::QDockAreaLayoutItem(QDockAreaLayoutInfo *_subinfo)
- : widgetItem(0), subinfo(_subinfo), placeHolderItem(0), pos(0), size(-1), flags(NoFlags)
-{
-}
-
-QDockAreaLayoutItem::QDockAreaLayoutItem(QPlaceHolderItem *_placeHolderItem)
- : widgetItem(0), subinfo(0), placeHolderItem(_placeHolderItem), pos(0), size(-1), flags(NoFlags)
-{
-}
-
-QDockAreaLayoutItem::QDockAreaLayoutItem(const QDockAreaLayoutItem &other)
- : widgetItem(other.widgetItem), subinfo(0), placeHolderItem(0), pos(other.pos),
- size(other.size), flags(other.flags)
-{
- if (other.subinfo != 0)
- subinfo = new QDockAreaLayoutInfo(*other.subinfo);
- else if (other.placeHolderItem != 0)
- placeHolderItem = new QPlaceHolderItem(*other.placeHolderItem);
-}
-
-QDockAreaLayoutItem::~QDockAreaLayoutItem()
-{
- delete subinfo;
- delete placeHolderItem;
-}
-
-bool QDockAreaLayoutItem::skip() const
-{
- if (placeHolderItem != 0)
- return true;
-
- if (flags & GapItem)
- return false;
-
- if (widgetItem != 0)
- return widgetItem->isEmpty();
-
- if (subinfo != 0) {
- for (int i = 0; i < subinfo->item_list.count(); ++i) {
- if (!subinfo->item_list.at(i).skip())
- return false;
- }
- }
-
- return true;
-}
-
-QSize QDockAreaLayoutItem::minimumSize() const
-{
- if (widgetItem != 0) {
- int left, top, right, bottom;
- widgetItem->widget()->getContentsMargins(&left, &top, &right, &bottom);
- return widgetItem->minimumSize() + QSize(left+right, top+bottom);
- }
- if (subinfo != 0)
- return subinfo->minimumSize();
- return QSize(0, 0);
-}
-
-QSize QDockAreaLayoutItem::maximumSize() const
-{
- if (widgetItem != 0) {
- int left, top, right, bottom;
- widgetItem->widget()->getContentsMargins(&left, &top, &right, &bottom);
- return widgetItem->maximumSize()+ QSize(left+right, top+bottom);
- }
- if (subinfo != 0)
- return subinfo->maximumSize();
- return QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
-}
-
-bool QDockAreaLayoutItem::hasFixedSize(Qt::Orientation o) const
-{
- return perp(o, minimumSize()) == perp(o, maximumSize());
-}
-
-bool QDockAreaLayoutItem::expansive(Qt::Orientation o) const
-{
- if ((flags & GapItem) || placeHolderItem != 0)
- return false;
- if (widgetItem != 0)
- return ((widgetItem->expandingDirections() & o) == o);
- if (subinfo != 0)
- return subinfo->expansive(o);
- return false;
-}
-
-QSize QDockAreaLayoutItem::sizeHint() const
-{
- if (placeHolderItem != 0)
- return QSize(0, 0);
- if (widgetItem != 0) {
- int left, top, right, bottom;
- widgetItem->widget()->getContentsMargins(&left, &top, &right, &bottom);
- return widgetItem->sizeHint() + QSize(left+right, top+bottom);
- }
- if (subinfo != 0)
- return subinfo->sizeHint();
- return QSize(-1, -1);
-}
-
-QDockAreaLayoutItem
- &QDockAreaLayoutItem::operator = (const QDockAreaLayoutItem &other)
-{
- widgetItem = other.widgetItem;
- if (other.subinfo == 0)
- subinfo = 0;
- else
- subinfo = new QDockAreaLayoutInfo(*other.subinfo);
-
- delete placeHolderItem;
- if (other.placeHolderItem == 0)
- placeHolderItem = 0;
- else
- placeHolderItem = new QPlaceHolderItem(*other.placeHolderItem);
-
- pos = other.pos;
- size = other.size;
- flags = other.flags;
-
- return *this;
-}
-
-/******************************************************************************
-** QDockAreaLayoutInfo
-*/
-
-#ifndef QT_NO_TABBAR
-static quintptr tabId(const QDockAreaLayoutItem &item)
-{
- if (item.widgetItem == 0)
- return 0;
- return reinterpret_cast<quintptr>(item.widgetItem->widget());
-}
-#endif
-
-static const int zero = 0;
-
-QDockAreaLayoutInfo::QDockAreaLayoutInfo()
- : sep(&zero), dockPos(QInternal::LeftDock), o(Qt::Horizontal), mainWindow(0)
-#ifndef QT_NO_TABBAR
- , tabbed(false), tabBar(0), tabBarShape(QTabBar::RoundedSouth)
-#endif
-{
-}
-
-QDockAreaLayoutInfo::QDockAreaLayoutInfo(const int *_sep, QInternal::DockPosition _dockPos,
- Qt::Orientation _o, int tbshape,
- QMainWindow *window)
- : sep(_sep), dockPos(_dockPos), o(_o), mainWindow(window)
-#ifndef QT_NO_TABBAR
- , tabbed(false), tabBar(0), tabBarShape(static_cast<QTabBar::Shape>(tbshape))
-#endif
-{
-#ifdef QT_NO_TABBAR
- Q_UNUSED(tbshape);
-#endif
-}
-
-QSize QDockAreaLayoutInfo::size() const
-{
- return isEmpty() ? QSize(0, 0) : rect.size();
-}
-
-void QDockAreaLayoutInfo::clear()
-{
- item_list.clear();
- rect = QRect();
-#ifndef QT_NO_TABBAR
- tabbed = false;
- tabBar = 0;
-#endif
-}
-
-bool QDockAreaLayoutInfo::isEmpty() const
-{
- return next(-1) == -1;
-}
-
-QSize QDockAreaLayoutInfo::minimumSize() const
-{
- if (isEmpty())
- return QSize(0, 0);
-
- int a = 0, b = 0;
- bool first = true;
- for (int i = 0; i < item_list.size(); ++i) {
- const QDockAreaLayoutItem &item = item_list.at(i);
- if (item.skip())
- continue;
-
- QSize min_size = item.minimumSize();
-#ifndef QT_NO_TABBAR
- if (tabbed) {
- a = qMax(a, pick(o, min_size));
- } else
-#endif
- {
- if (!first)
- a += *sep;
- a += pick(o, min_size);
- }
- b = qMax(b, perp(o, min_size));
-
- first = false;
- }
-
- QSize result;
- rpick(o, result) = a;
- rperp(o, result) = b;
-
-#ifndef QT_NO_TABBAR
- QSize tbm = tabBarMinimumSize();
- if (!tbm.isNull()) {
- switch (tabBarShape) {
- case QTabBar::RoundedNorth:
- case QTabBar::RoundedSouth:
- case QTabBar::TriangularNorth:
- case QTabBar::TriangularSouth:
- result.rheight() += tbm.height();
- result.rwidth() = qMax(tbm.width(), result.width());
- break;
- case QTabBar::RoundedEast:
- case QTabBar::RoundedWest:
- case QTabBar::TriangularEast:
- case QTabBar::TriangularWest:
- result.rheight() = qMax(tbm.height(), result.height());
- result.rwidth() += tbm.width();
- break;
- default:
- break;
- }
- }
-#endif // QT_NO_TABBAR
-
- return result;
-}
-
-QSize QDockAreaLayoutInfo::maximumSize() const
-{
- if (isEmpty())
- return QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
-
- int a = 0, b = QWIDGETSIZE_MAX;
-#ifndef QT_NO_TABBAR
- if (tabbed)
- a = QWIDGETSIZE_MAX;
-#endif
-
- int min_perp = 0;
-
- bool first = true;
- for (int i = 0; i < item_list.size(); ++i) {
- const QDockAreaLayoutItem &item = item_list.at(i);
- if (item.skip())
- continue;
-
- QSize max_size = item.maximumSize();
- min_perp = qMax(min_perp, perp(o, item.minimumSize()));
-
-#ifndef QT_NO_TABBAR
- if (tabbed) {
- a = qMin(a, pick(o, max_size));
- } else
-#endif
- {
- if (!first)
- a += *sep;
- a += pick(o, max_size);
- }
- b = qMin(b, perp(o, max_size));
-
- a = qMin(a, int(QWIDGETSIZE_MAX));
- b = qMin(b, int(QWIDGETSIZE_MAX));
-
- first = false;
- }
-
- b = qMax(b, min_perp);
-
- QSize result;
- rpick(o, result) = a;
- rperp(o, result) = b;
-
-#ifndef QT_NO_TABBAR
- QSize tbh = tabBarSizeHint();
- if (!tbh.isNull()) {
- switch (tabBarShape) {
- case QTabBar::RoundedNorth:
- case QTabBar::RoundedSouth:
- result.rheight() += tbh.height();
- break;
- case QTabBar::RoundedEast:
- case QTabBar::RoundedWest:
- result.rwidth() += tbh.width();
- break;
- default:
- break;
- }
- }
-#endif // QT_NO_TABBAR
-
- return result;
-}
-
-QSize QDockAreaLayoutInfo::sizeHint() const
-{
- if (isEmpty())
- return QSize(0, 0);
-
- int a = 0, b = 0;
- int min_perp = 0;
- int max_perp = QWIDGETSIZE_MAX;
- const QDockAreaLayoutItem *previous = 0;
- for (int i = 0; i < item_list.size(); ++i) {
- const QDockAreaLayoutItem &item = item_list.at(i);
- if (item.skip())
- continue;
-
- bool gap = item.flags & QDockAreaLayoutItem::GapItem;
-
- QSize size_hint = item.sizeHint();
- min_perp = qMax(min_perp, perp(o, item.minimumSize()));
- max_perp = qMin(max_perp, perp(o, item.maximumSize()));
-
-#ifndef QT_NO_TABBAR
- if (tabbed) {
- a = qMax(a, gap ? item.size : pick(o, size_hint));
- } else
-#endif
- {
- if (previous && !gap && !(previous->flags & QDockAreaLayoutItem::GapItem)
- && !previous->hasFixedSize(o)) {
- a += *sep;
- }
- a += gap ? item.size : pick(o, size_hint);
- }
- b = qMax(b, perp(o, size_hint));
-
- previous = &item;
- }
-
- max_perp = qMax(max_perp, min_perp);
- b = qMax(b, min_perp);
- b = qMin(b, max_perp);
-
- QSize result;
- rpick(o, result) = a;
- rperp(o, result) = b;
-
-#ifndef QT_NO_TABBAR
- if (tabbed) {
- QSize tbh = tabBarSizeHint();
- switch (tabBarShape) {
- case QTabBar::RoundedNorth:
- case QTabBar::RoundedSouth:
- case QTabBar::TriangularNorth:
- case QTabBar::TriangularSouth:
- result.rheight() += tbh.height();
- result.rwidth() = qMax(tbh.width(), result.width());
- break;
- case QTabBar::RoundedEast:
- case QTabBar::RoundedWest:
- case QTabBar::TriangularEast:
- case QTabBar::TriangularWest:
- result.rheight() = qMax(tbh.height(), result.height());
- result.rwidth() += tbh.width();
- break;
- default:
- break;
- }
- }
-#endif // QT_NO_TABBAR
-
- return result;
-}
-
-bool QDockAreaLayoutInfo::expansive(Qt::Orientation o) const
-{
- for (int i = 0; i < item_list.size(); ++i) {
- if (item_list.at(i).expansive(o))
- return true;
- }
- return false;
-}
-
-/* QDockAreaLayoutInfo::maximumSize() doesn't return the real max size. For example,
- if the layout is empty, it returns QWIDGETSIZE_MAX. This is so that empty dock areas
- don't constrain the size of the QMainWindow, but sometimes we really need to know the
- maximum size. Also, these functions take into account widgets that want to keep their
- size (f.ex. when they are hidden and then shown, they should not change size).
-*/
-
-static int realMinSize(const QDockAreaLayoutInfo &info)
-{
- int result = 0;
- bool first = true;
- for (int i = 0; i < info.item_list.size(); ++i) {
- const QDockAreaLayoutItem &item = info.item_list.at(i);
- if (item.skip())
- continue;
-
- int min = 0;
- if ((item.flags & QDockAreaLayoutItem::KeepSize) && item.size != -1)
- min = item.size;
- else
- min = pick(info.o, item.minimumSize());
-
- if (!first)
- result += *info.sep;
- result += min;
-
- first = false;
- }
-
- return result;
-}
-
-static int realMaxSize(const QDockAreaLayoutInfo &info)
-{
- int result = 0;
- bool first = true;
- for (int i = 0; i < info.item_list.size(); ++i) {
- const QDockAreaLayoutItem &item = info.item_list.at(i);
- if (item.skip())
- continue;
-
- int max = 0;
- if ((item.flags & QDockAreaLayoutItem::KeepSize) && item.size != -1)
- max = item.size;
- else
- max = pick(info.o, item.maximumSize());
-
- if (!first)
- result += *info.sep;
- result += max;
-
- if (result >= QWIDGETSIZE_MAX)
- return QWIDGETSIZE_MAX;
-
- first = false;
- }
-
- return result;
-}
-
-void QDockAreaLayoutInfo::fitItems()
-{
-#ifndef QT_NO_TABBAR
- if (tabbed) {
- return;
- }
-#endif
-
- QVector<QLayoutStruct> layout_struct_list(item_list.size()*2);
- int j = 0;
-
- int size = pick(o, rect.size());
- int min_size = realMinSize(*this);
- int max_size = realMaxSize(*this);
- int last_index = -1;
-
- const QDockAreaLayoutItem *previous = 0;
- for (int i = 0; i < item_list.size(); ++i) {
- QDockAreaLayoutItem &item = item_list[i];
- if (item.skip())
- continue;
-
- bool gap = item.flags & QDockAreaLayoutItem::GapItem;
- if (previous && !gap) {
- if (!(previous->flags & QDockAreaLayoutItem::GapItem)) {
- QLayoutStruct &ls = layout_struct_list[j++];
- ls.init();
- ls.minimumSize = ls.maximumSize = ls.sizeHint = previous->hasFixedSize(o) ? 0 : *sep;
- ls.empty = false;
- }
- }
-
- if (item.flags & QDockAreaLayoutItem::KeepSize) {
- // Check if the item can keep its size, without violating size constraints
- // of other items.
-
- if (size < min_size) {
- // There is too little space to keep this widget's size
- item.flags &= ~QDockAreaLayoutItem::KeepSize;
- min_size -= item.size;
- min_size += pick(o, item.minimumSize());
- min_size = qMax(0, min_size);
- } else if (size > max_size) {
- // There is too much space to keep this widget's size
- item.flags &= ~QDockAreaLayoutItem::KeepSize;
- max_size -= item.size;
- max_size += pick(o, item.maximumSize());
- max_size = qMin<int>(QWIDGETSIZE_MAX, max_size);
- }
- }
-
- last_index = j;
- QLayoutStruct &ls = layout_struct_list[j++];
- ls.init();
- ls.empty = false;
- if (item.flags & QDockAreaLayoutItem::KeepSize) {
- ls.minimumSize = ls.maximumSize = ls.sizeHint = item.size;
- ls.expansive = false;
- ls.stretch = 0;
- } else {
- ls.maximumSize = pick(o, item.maximumSize());
- ls.expansive = item.expansive(o);
- ls.minimumSize = pick(o, item.minimumSize());
- ls.sizeHint = item.size == -1 ? pick(o, item.sizeHint()) : item.size;
- ls.stretch = ls.expansive ? ls.sizeHint : 0;
- }
-
- item.flags &= ~QDockAreaLayoutItem::KeepSize;
- previous = &item;
- }
- layout_struct_list.resize(j);
-
- // If there is more space than the widgets can take (due to maximum size constraints),
- // we detect it here and stretch the last widget to take up the rest of the space.
- if (size > max_size && last_index != -1) {
- layout_struct_list[last_index].maximumSize = QWIDGETSIZE_MAX;
- layout_struct_list[last_index].expansive = true;
- }
-
- qGeomCalc(layout_struct_list, 0, j, pick(o, rect.topLeft()), size, 0);
-
- j = 0;
- bool prev_gap = false;
- bool first = true;
- for (int i = 0; i < item_list.size(); ++i) {
- QDockAreaLayoutItem &item = item_list[i];
- if (item.skip())
- continue;
-
- bool gap = item.flags & QDockAreaLayoutItem::GapItem;
- if (!first && !gap && !prev_gap)
- ++j;
-
- const QLayoutStruct &ls = layout_struct_list.at(j++);
- item.size = ls.size;
- item.pos = ls.pos;
-
- if (item.subinfo != 0) {
- item.subinfo->rect = itemRect(i);
- item.subinfo->fitItems();
- }
-
- prev_gap = gap;
- first = false;
- }
-}
-
-static QInternal::DockPosition dockPosHelper(const QRect &rect, const QPoint &_pos,
- Qt::Orientation o,
- bool nestingEnabled,
- QDockAreaLayoutInfo::TabMode tabMode)
-{
- if (tabMode == QDockAreaLayoutInfo::ForceTabs)
- return QInternal::DockCount;
-
- QPoint pos = _pos - rect.topLeft();
-
- int x = pos.x();
- int y = pos.y();
- int w = rect.width();
- int h = rect.height();
-
- if (tabMode != QDockAreaLayoutInfo::NoTabs) {
- // is it in the center?
- if (nestingEnabled) {
- /* 2/3
- +--------------+
- | |
- | CCCCCCCC |
- 2/3 | CCCCCCCC |
- | CCCCCCCC |
- | |
- +--------------+ */
-
- QRect center(w/6, h/6, 2*w/3, 2*h/3);
- if (center.contains(pos))
- return QInternal::DockCount;
- } else if (o == Qt::Horizontal) {
- /* 2/3
- +--------------+
- | CCCCCCCC |
- | CCCCCCCC |
- | CCCCCCCC |
- | CCCCCCCC |
- | CCCCCCCC |
- +--------------+ */
-
- if (x > w/6 && x < w*5/6)
- return QInternal::DockCount;
- } else {
- /*
- +--------------+
- | |
- 2/3 |CCCCCCCCCCCCCC|
- |CCCCCCCCCCCCCC|
- | |
- +--------------+ */
- if (y > h/6 && y < 5*h/6)
- return QInternal::DockCount;
- }
- }
-
- // not in the center. which edge?
- if (nestingEnabled) {
- if (o == Qt::Horizontal) {
- /* 1/3 1/3 1/3
- +------------+ (we've already ruled out the center)
- |LLLLTTTTRRRR|
- |LLLLTTTTRRRR|
- |LLLLBBBBRRRR|
- |LLLLBBBBRRRR|
- +------------+ */
-
- if (x < w/3)
- return QInternal::LeftDock;
- if (x > 2*w/3)
- return QInternal::RightDock;
- if (y < h/2)
- return QInternal::TopDock;
- return QInternal::BottomDock;
- } else {
- /* +------------+ (we've already ruled out the center)
- 1/3 |TTTTTTTTTTTT|
- |LLLLLLRRRRRR|
- 1/3 |LLLLLLRRRRRR|
- 1/3 |BBBBBBBBBBBB|
- +------------+ */
-
- if (y < h/3)
- return QInternal::TopDock;
- if (y > 2*h/3)
- return QInternal::BottomDock;
- if (x < w/2)
- return QInternal::LeftDock;
- return QInternal::RightDock;
- }
- } else {
- if (o == Qt::Horizontal) {
- return x < w/2
- ? QInternal::LeftDock
- : QInternal::RightDock;
- } else {
- return y < h/2
- ? QInternal::TopDock
- : QInternal::BottomDock;
- }
- }
-}
-
-QList<int> QDockAreaLayoutInfo::gapIndex(const QPoint& _pos,
- bool nestingEnabled, TabMode tabMode) const
-{
- QList<int> result;
- QRect item_rect;
- int item_index = 0;
-
-#ifndef QT_NO_TABBAR
- if (tabbed) {
- item_rect = tabContentRect();
- } else
-#endif
- {
- int pos = pick(o, _pos);
-
- int last = -1;
- for (int i = 0; i < item_list.size(); ++i) {
- const QDockAreaLayoutItem &item = item_list.at(i);
- if (item.skip())
- continue;
-
- last = i;
-
- if (item.pos + item.size < pos)
- continue;
-
- if (item.subinfo != 0
-#ifndef QT_NO_TABBAR
- && !item.subinfo->tabbed
-#endif
- ) {
- result = item.subinfo->gapIndex(_pos, nestingEnabled,
- tabMode);
- result.prepend(i);
- return result;
- }
-
- item_rect = itemRect(i);
- item_index = i;
- break;
- }
-
- if (item_rect.isNull()) {
- result.append(last + 1);
- return result;
- }
- }
-
- Q_ASSERT(!item_rect.isNull());
-
- QInternal::DockPosition dock_pos
- = dockPosHelper(item_rect, _pos, o, nestingEnabled, tabMode);
-
- switch (dock_pos) {
- case QInternal::LeftDock:
- if (o == Qt::Horizontal)
- result << item_index;
- else
- result << item_index << 0; // this subinfo doesn't exist yet, but insertGap()
- // handles this by inserting it
- break;
- case QInternal::RightDock:
- if (o == Qt::Horizontal)
- result << item_index + 1;
- else
- result << item_index << 1;
- break;
- case QInternal::TopDock:
- if (o == Qt::Horizontal)
- result << item_index << 0;
- else
- result << item_index;
- break;
- case QInternal::BottomDock:
- if (o == Qt::Horizontal)
- result << item_index << 1;
- else
- result << item_index + 1;
- break;
- case QInternal::DockCount:
- result << (-item_index - 1) << 0; // negative item_index means "on top of"
- // -item_index - 1, insertGap()
- // will insert a tabbed subinfo
- break;
- default:
- break;
- }
-
- return result;
-}
-
-static inline int shrink(QLayoutStruct &ls, int delta)
-{
- if (ls.empty)
- return 0;
- int old_size = ls.size;
- ls.size = qMax(ls.size - delta, ls.minimumSize);
- return old_size - ls.size;
-}
-
-static inline int grow(QLayoutStruct &ls, int delta)
-{
- if (ls.empty)
- return 0;
- int old_size = ls.size;
- ls.size = qMin(ls.size + delta, ls.maximumSize);
- return ls.size - old_size;
-}
-
-static int separatorMoveHelper(QVector<QLayoutStruct> &list, int index, int delta, int sep)
-{
- // adjust sizes
- int pos = -1;
- for (int i = 0; i < list.size(); ++i) {
- const QLayoutStruct &ls = list.at(i);
- if (!ls.empty) {
- pos = ls.pos;
- break;
- }
- }
- if (pos == -1)
- return 0;
-
- if (delta > 0) {
- int growlimit = 0;
- for (int i = 0; i<=index; ++i) {
- const QLayoutStruct &ls = list.at(i);
- if (ls.empty)
- continue;
- if (ls.maximumSize == QLAYOUTSIZE_MAX) {
- growlimit = QLAYOUTSIZE_MAX;
- break;
- }
- growlimit += ls.maximumSize - ls.size;
- }
- if (delta > growlimit)
- delta = growlimit;
-
- int d = 0;
- for (int i = index + 1; d < delta && i < list.count(); ++i)
- d += shrink(list[i], delta - d);
- delta = d;
- d = 0;
- for (int i = index; d < delta && i >= 0; --i)
- d += grow(list[i], delta - d);
- } else if (delta < 0) {
- int growlimit = 0;
- for (int i = index + 1; i < list.count(); ++i) {
- const QLayoutStruct &ls = list.at(i);
- if (ls.empty)
- continue;
- if (ls.maximumSize == QLAYOUTSIZE_MAX) {
- growlimit = QLAYOUTSIZE_MAX;
- break;
- }
- growlimit += ls.maximumSize - ls.size;
- }
- if (-delta > growlimit)
- delta = -growlimit;
-
- int d = 0;
- for (int i = index; d < -delta && i >= 0; --i)
- d += shrink(list[i], -delta - d);
- delta = -d;
- d = 0;
- for (int i = index + 1; d < -delta && i < list.count(); ++i)
- d += grow(list[i], -delta - d);
- }
-
- // adjust positions
- bool first = true;
- for (int i = 0; i < list.size(); ++i) {
- QLayoutStruct &ls = list[i];
- if (ls.empty) {
- ls.pos = pos + (first ? 0 : sep);
- continue;
- }
- if (!first)
- pos += sep;
- ls.pos = pos;
- pos += ls.size;
- first = false;
- }
-
- return delta;
-}
-
-int QDockAreaLayoutInfo::separatorMove(int index, int delta)
-{
-#ifndef QT_NO_TABBAR
- Q_ASSERT(!tabbed);
-#endif
-
- QVector<QLayoutStruct> list(item_list.size());
- for (int i = 0; i < list.size(); ++i) {
- const QDockAreaLayoutItem &item = item_list.at(i);
- QLayoutStruct &ls = list[i];
- Q_ASSERT(!(item.flags & QDockAreaLayoutItem::GapItem));
- if (item.skip()) {
- ls.empty = true;
- } else {
- const int separatorSpace = item.hasFixedSize(o) ? 0 : *sep;
- ls.empty = false;
- ls.pos = item.pos;
- ls.size = item.size + separatorSpace;
- ls.minimumSize = pick(o, item.minimumSize()) + separatorSpace;
- ls.maximumSize = pick(o, item.maximumSize()) + separatorSpace;
-
- }
- }
-
- //the separator space has been added to the size, so we pass 0 as a parameter
- delta = separatorMoveHelper(list, index, delta, 0 /*separator*/);
-
- for (int i = 0; i < list.size(); ++i) {
- QDockAreaLayoutItem &item = item_list[i];
- if (item.skip())
- continue;
- QLayoutStruct &ls = list[i];
- const int separatorSpace = item.hasFixedSize(o) ? 0 : *sep;
- item.size = ls.size - separatorSpace;
- item.pos = ls.pos;
- if (item.subinfo != 0) {
- item.subinfo->rect = itemRect(i);
- item.subinfo->fitItems();
- }
- }
-
- return delta;
-}
-
-void QDockAreaLayoutInfo::unnest(int index)
-{
- QDockAreaLayoutItem &item = item_list[index];
- if (item.subinfo == 0)
- return;
- if (item.subinfo->item_list.count() > 1)
- return;
-
- if (item.subinfo->item_list.count() == 0) {
- item_list.removeAt(index);
- } else if (item.subinfo->item_list.count() == 1) {
- QDockAreaLayoutItem &child = item.subinfo->item_list.first();
- if (child.widgetItem != 0) {
- item.widgetItem = child.widgetItem;
- delete item.subinfo;
- item.subinfo = 0;
- } else if (child.subinfo != 0) {
- QDockAreaLayoutInfo *tmp = item.subinfo;
- item.subinfo = child.subinfo;
- child.subinfo = 0;
- tmp->item_list.clear();
- delete tmp;
- }
- }
-}
-
-void QDockAreaLayoutInfo::remove(const QList<int> &path)
-{
- Q_ASSERT(!path.isEmpty());
-
- if (path.count() > 1) {
- const int index = path.first();
- QDockAreaLayoutItem &item = item_list[index];
- Q_ASSERT(item.subinfo != 0);
- item.subinfo->remove(path.mid(1));
- unnest(index);
- } else {
- int index = path.first();
- item_list.removeAt(index);
- }
-}
-
-QLayoutItem *QDockAreaLayoutInfo::plug(const QList<int> &path)
-{
- Q_ASSERT(!path.isEmpty());
-
- int index = path.first();
- if (index < 0)
- index = -index - 1;
-
- if (path.count() > 1) {
- const QDockAreaLayoutItem &item = item_list.at(index);
- Q_ASSERT(item.subinfo != 0);
- return item.subinfo->plug(path.mid(1));
- }
-
- QDockAreaLayoutItem &item = item_list[index];
-
- Q_ASSERT(item.widgetItem != 0);
- Q_ASSERT(item.flags & QDockAreaLayoutItem::GapItem);
- item.flags &= ~QDockAreaLayoutItem::GapItem;
-
- QRect result;
-
-#ifndef QT_NO_TABBAR
- if (tabbed) {
- } else
-#endif
- {
- int prev = this->prev(index);
- int next = this->next(index);
-
- if (prev != -1 && !(item_list.at(prev).flags & QDockAreaLayoutItem::GapItem)) {
- item.pos += *sep;
- item.size -= *sep;
- }
- if (next != -1 && !(item_list.at(next).flags & QDockAreaLayoutItem::GapItem))
- item.size -= *sep;
-
- QPoint pos;
- rpick(o, pos) = item.pos;
- rperp(o, pos) = perp(o, rect.topLeft());
- QSize s;
- rpick(o, s) = item.size;
- rperp(o, s) = perp(o, rect.size());
- result = QRect(pos, s);
- }
-
- return item.widgetItem;
-}
-
-QLayoutItem *QDockAreaLayoutInfo::unplug(const QList<int> &path)
-{
- Q_ASSERT(!path.isEmpty());
-
- const int index = path.first();
- if (path.count() > 1) {
- const QDockAreaLayoutItem &item = item_list.at(index);
- Q_ASSERT(item.subinfo != 0);
- return item.subinfo->unplug(path.mid(1));
- }
-
- QDockAreaLayoutItem &item = item_list[index];
- int prev = this->prev(index);
- int next = this->next(index);
-
- Q_ASSERT(!(item.flags & QDockAreaLayoutItem::GapItem));
- item.flags |= QDockAreaLayoutItem::GapItem;
-
-#ifndef QT_NO_TABBAR
- if (tabbed) {
- } else
-#endif
- {
- if (prev != -1 && !(item_list.at(prev).flags & QDockAreaLayoutItem::GapItem)) {
- item.pos -= *sep;
- item.size += *sep;
- }
- if (next != -1 && !(item_list.at(next).flags & QDockAreaLayoutItem::GapItem))
- item.size += *sep;
- }
-
- return item.widgetItem;
-}
-
-#ifndef QT_NO_TABBAR
-
-quintptr QDockAreaLayoutInfo::currentTabId() const
-{
- if (!tabbed || tabBar == 0)
- return 0;
-
- int index = tabBar->currentIndex();
- if (index == -1)
- return 0;
-
- return qvariant_cast<quintptr>(tabBar->tabData(index));
-}
-
-void QDockAreaLayoutInfo::setCurrentTab(QWidget *widget)
-{
- setCurrentTabId(reinterpret_cast<quintptr>(widget));
-}
-
-void QDockAreaLayoutInfo::setCurrentTabId(quintptr id)
-{
- if (!tabbed || tabBar == 0)
- return;
-
- for (int i = 0; i < tabBar->count(); ++i) {
- if (qvariant_cast<quintptr>(tabBar->tabData(i)) == id) {
- tabBar->setCurrentIndex(i);
- return;
- }
- }
-}
-
-#endif // QT_NO_TABBAR
-
-static QRect dockedGeometry(QWidget *widget)
-{
- int titleHeight = 0;
-
- QDockWidgetLayout *layout
- = qobject_cast<QDockWidgetLayout*>(widget->layout());
- if(layout != 0 && layout->nativeWindowDeco())
- titleHeight = layout->titleHeight();
-
- QRect result = widget->geometry();
- result.adjust(0, -titleHeight, 0, 0);
- return result;
-}
-
-bool QDockAreaLayoutInfo::insertGap(const QList<int> &path, QLayoutItem *dockWidgetItem)
-{
- Q_ASSERT(!path.isEmpty());
-
- bool insert_tabbed = false;
- int index = path.first();
- if (index < 0) {
- insert_tabbed = true;
- index = -index - 1;
- }
-
-// dump(qDebug() << "insertGap() before:" << index << tabIndex, *this, QString());
-
- if (path.count() > 1) {
- QDockAreaLayoutItem &item = item_list[index];
-
- if (item.subinfo == 0
-#ifndef QT_NO_TABBAR
- || (item.subinfo->tabbed && !insert_tabbed)
-#endif
- ) {
-
- // this is not yet a nested layout - make it
-
- QDockAreaLayoutInfo *subinfo = item.subinfo;
- QLayoutItem *widgetItem = item.widgetItem;
- QPlaceHolderItem *placeHolderItem = item.placeHolderItem;
- QRect r = subinfo == 0 ? widgetItem ? dockedGeometry(widgetItem->widget()) : placeHolderItem->topLevelRect : subinfo->rect;
-
- Qt::Orientation opposite = o == Qt::Horizontal ? Qt::Vertical : Qt::Horizontal;
-#ifdef QT_NO_TABBAR
- const int tabBarShape = 0;
-#endif
- QDockAreaLayoutInfo *new_info
- = new QDockAreaLayoutInfo(sep, dockPos, opposite, tabBarShape, mainWindow);
-
- //item become a new top-level
- item.subinfo = new_info;
- item.widgetItem = 0;
- item.placeHolderItem = 0;
-
- QDockAreaLayoutItem new_item
- = widgetItem == 0
- ? QDockAreaLayoutItem(subinfo)
- : widgetItem ? QDockAreaLayoutItem(widgetItem) : QDockAreaLayoutItem(placeHolderItem);
- new_item.size = pick(opposite, r.size());
- new_item.pos = pick(opposite, r.topLeft());
- new_info->item_list.append(new_item);
-#ifndef QT_NO_TABBAR
- if (insert_tabbed) {
- new_info->tabbed = true;
- }
-#endif
- }
-
- return item.subinfo->insertGap(path.mid(1), dockWidgetItem);
- }
-
- // create the gap item
- QDockAreaLayoutItem gap_item;
- gap_item.flags |= QDockAreaLayoutItem::GapItem;
- gap_item.widgetItem = dockWidgetItem; // so minimumSize(), maximumSize() and
- // sizeHint() will work
-#ifndef QT_NO_TABBAR
- if (!tabbed)
-#endif
- {
- int prev = this->prev(index);
- int next = this->next(index - 1);
- // find out how much space we have in the layout
- int space = 0;
- if (isEmpty()) {
- // I am an empty dock area, therefore I am a top-level dock area.
- switch (dockPos) {
- case QInternal::LeftDock:
- case QInternal::RightDock:
- if (o == Qt::Vertical) {
- // the "size" is the height of the dock area (remember we are empty)
- space = pick(Qt::Vertical, rect.size());
- } else {
- space = pick(Qt::Horizontal, dockWidgetItem->widget()->size());
- }
- break;
- case QInternal::TopDock:
- case QInternal::BottomDock:
- default:
- if (o == Qt::Horizontal) {
- // the "size" is width of the dock area
- space = pick(Qt::Horizontal, rect.size());
- } else {
- space = pick(Qt::Vertical, dockWidgetItem->widget()->size());
- }
- break;
- }
- } else {
- for (int i = 0; i < item_list.count(); ++i) {
- const QDockAreaLayoutItem &item = item_list.at(i);
- if (item.skip())
- continue;
- Q_ASSERT(!(item.flags & QDockAreaLayoutItem::GapItem));
- space += item.size - pick(o, item.minimumSize());
- }
- }
-
- // find the actual size of the gap
- int gap_size = 0;
- int sep_size = 0;
- if (isEmpty()) {
- gap_size = space;
- sep_size = 0;
- } else {
- QRect r = dockedGeometry(dockWidgetItem->widget());
- gap_size = pick(o, r.size());
- if (prev != -1 && !(item_list.at(prev).flags & QDockAreaLayoutItem::GapItem))
- sep_size += *sep;
- if (next != -1 && !(item_list.at(next).flags & QDockAreaLayoutItem::GapItem))
- sep_size += *sep;
- }
- if (gap_size + sep_size > space)
- gap_size = pick(o, gap_item.minimumSize());
- gap_item.size = gap_size + sep_size;
- }
-
- // finally, insert the gap
- item_list.insert(index, gap_item);
-
-// dump(qDebug() << "insertGap() after:" << index << tabIndex, *this, QString());
-
- return true;
-}
-
-QDockAreaLayoutInfo *QDockAreaLayoutInfo::info(QWidget *widget)
-{
- for (int i = 0; i < item_list.count(); ++i) {
- const QDockAreaLayoutItem &item = item_list.at(i);
- if (item.skip())
- continue;
-
-#ifndef QT_NO_TABBAR
- if (tabbed && widget == tabBar)
- return this;
-#endif
-
- if (item.widgetItem != 0 && item.widgetItem->widget() == widget)
- return this;
-
- if (item.subinfo != 0) {
- if (QDockAreaLayoutInfo *result = item.subinfo->info(widget))
- return result;
- }
- }
-
- return 0;
-}
-
-QDockAreaLayoutInfo *QDockAreaLayoutInfo::info(const QList<int> &path)
-{
- int index = path.first();
- if (index < 0)
- index = -index - 1;
- if (index >= item_list.count())
- return this;
- if (path.count() == 1 || item_list[index].subinfo == 0)
- return this;
- return item_list[index].subinfo->info(path.mid(1));
-}
-
-QRect QDockAreaLayoutInfo::itemRect(int index) const
-{
- const QDockAreaLayoutItem &item = item_list.at(index);
-
- if (item.skip())
- return QRect();
-
- QRect result;
-
-#ifndef QT_NO_TABBAR
- if (tabbed) {
- if (tabId(item) == currentTabId())
- result = tabContentRect();
- } else
-#endif
- {
- QPoint pos;
- rpick(o, pos) = item.pos;
- rperp(o, pos) = perp(o, rect.topLeft());
- QSize s;
- rpick(o, s) = item.size;
- rperp(o, s) = perp(o, rect.size());
- result = QRect(pos, s);
- }
-
- return result;
-}
-
-QRect QDockAreaLayoutInfo::itemRect(const QList<int> &path) const
-{
- Q_ASSERT(!path.isEmpty());
-
- const int index = path.first();
- if (path.count() > 1) {
- const QDockAreaLayoutItem &item = item_list.at(index);
- Q_ASSERT(item.subinfo != 0);
- return item.subinfo->itemRect(path.mid(1));
- }
-
- return itemRect(index);
-}
-
-QRect QDockAreaLayoutInfo::separatorRect(int index) const
-{
-#ifndef QT_NO_TABBAR
- if (tabbed)
- return QRect();
-#endif
-
- const QDockAreaLayoutItem &item = item_list.at(index);
- if (item.skip())
- return QRect();
-
- QPoint pos = rect.topLeft();
- rpick(o, pos) = item.pos + item.size;
- QSize s = rect.size();
- rpick(o, s) = *sep;
-
- return QRect(pos, s);
-}
-
-QRect QDockAreaLayoutInfo::separatorRect(const QList<int> &path) const
-{
- Q_ASSERT(!path.isEmpty());
-
- const int index = path.first();
- if (path.count() > 1) {
- const QDockAreaLayoutItem &item = item_list.at(index);
- Q_ASSERT(item.subinfo != 0);
- return item.subinfo->separatorRect(path.mid(1));
- }
- return separatorRect(index);
-}
-
-QList<int> QDockAreaLayoutInfo::findSeparator(const QPoint &_pos) const
-{
-#ifndef QT_NO_TABBAR
- if (tabbed)
- return QList<int>();
-#endif
-
- int pos = pick(o, _pos);
-
- for (int i = 0; i < item_list.size(); ++i) {
- const QDockAreaLayoutItem &item = item_list.at(i);
- if (item.skip() || (item.flags & QDockAreaLayoutItem::GapItem))
- continue;
-
- if (item.pos + item.size > pos) {
- if (item.subinfo != 0) {
- QList<int> result = item.subinfo->findSeparator(_pos);
- if (!result.isEmpty()) {
- result.prepend(i);
- return result;
- } else {
- return QList<int>();
- }
- }
- }
-
- int next = this->next(i);
- if (next == -1 || (item_list.at(next).flags & QDockAreaLayoutItem::GapItem))
- continue;
-
- QRect sepRect = separatorRect(i);
- if (!sepRect.isNull() && *sep == 1)
- sepRect.adjust(-2, -2, 2, 2);
- //we also make sure we don't find a separator that's not there
- if (sepRect.contains(_pos) && !item.hasFixedSize(o)) {
- return QList<int>() << i;
- }
-
- }
-
- return QList<int>();
-}
-
-QList<int> QDockAreaLayoutInfo::indexOfPlaceHolder(const QString &objectName) const
-{
- for (int i = 0; i < item_list.size(); ++i) {
- const QDockAreaLayoutItem &item = item_list.at(i);
-
- if (item.subinfo != 0) {
- QList<int> result = item.subinfo->indexOfPlaceHolder(objectName);
- if (!result.isEmpty()) {
- result.prepend(i);
- return result;
- }
- continue;
- }
-
- if (item.placeHolderItem != 0 && item.placeHolderItem->objectName == objectName) {
- QList<int> result;
- result << i;
- return result;
- }
- }
-
- return QList<int>();
-}
-
-QList<int> QDockAreaLayoutInfo::indexOf(QWidget *widget) const
-{
- for (int i = 0; i < item_list.size(); ++i) {
- const QDockAreaLayoutItem &item = item_list.at(i);
-
- if (item.placeHolderItem != 0)
- continue;
-
- if (item.subinfo != 0) {
- QList<int> result = item.subinfo->indexOf(widget);
- if (!result.isEmpty()) {
- result.prepend(i);
- return result;
- }
- continue;
- }
-
- if (!(item.flags & QDockAreaLayoutItem::GapItem) && item.widgetItem->widget() == widget) {
- QList<int> result;
- result << i;
- return result;
- }
- }
-
- return QList<int>();
-}
-
-QMainWindowLayout *QDockAreaLayoutInfo::mainWindowLayout() const
-{
- QMainWindowLayout *result = qt_mainwindow_layout(mainWindow);
- Q_ASSERT(result != 0);
- return result;
-}
-
-bool QDockAreaLayoutInfo::hasFixedSize() const
-{
- return perp(o, minimumSize()) == perp(o, maximumSize());
-}
-
-
-void QDockAreaLayoutInfo::apply(bool animate)
-{
- QWidgetAnimator &widgetAnimator = mainWindowLayout()->widgetAnimator;
-
-#ifndef QT_NO_TABBAR
- if (tabbed) {
- QRect tab_rect;
- QSize tbh = tabBarSizeHint();
-
- if (!tbh.isNull()) {
- switch (tabBarShape) {
- case QTabBar::RoundedNorth:
- case QTabBar::TriangularNorth:
- tab_rect = QRect(rect.left(), rect.top(), rect.width(), tbh.height());
- break;
- case QTabBar::RoundedSouth:
- case QTabBar::TriangularSouth:
- tab_rect = QRect(rect.left(), rect.bottom() - tbh.height() + 1,
- rect.width(), tbh.height());
- break;
- case QTabBar::RoundedEast:
- case QTabBar::TriangularEast:
- tab_rect = QRect(rect.right() - tbh.width() + 1, rect.top(),
- tbh.width(), rect.height());
- break;
- case QTabBar::RoundedWest:
- case QTabBar::TriangularWest:
- tab_rect = QRect(rect.left(), rect.top(),
- tbh.width(), rect.height());
- break;
- default:
- break;
- }
- }
-
- widgetAnimator.animate(tabBar, tab_rect, animate);
- }
-#endif // QT_NO_TABBAR
-
- for (int i = 0; i < item_list.size(); ++i) {
- QDockAreaLayoutItem &item = item_list[i];
-
- if (item.flags & QDockAreaLayoutItem::GapItem)
- continue;
-
- if (item.subinfo != 0) {
- item.subinfo->apply(animate);
- continue;
- }
-
- if (item.skip())
- continue;
-
- Q_ASSERT(item.widgetItem);
- QRect r = itemRect(i);
- QWidget *w = item.widgetItem->widget();
-
- QRect geo = w->geometry();
- widgetAnimator.animate(w, r, animate);
- if (!w->isHidden() && w->window()->isVisible()) {
- QDockWidget *dw = qobject_cast<QDockWidget*>(w);
- if (!r.isValid() && geo.right() >= 0 && geo.bottom() >= 0) {
- dw->lower();
- emit dw->visibilityChanged(false);
- } else if (r.isValid()
- && (geo.right() < 0 || geo.bottom() < 0)) {
- emit dw->visibilityChanged(true);
- }
- }
- }
-#ifndef QT_NO_TABBAR
- if (*sep == 1)
- updateSeparatorWidgets();
-#endif //QT_NO_TABBAR
-}
-
-static void paintSep(QPainter *p, QWidget *w, const QRect &r, Qt::Orientation o, bool mouse_over)
-{
- QStyleOption opt(0);
- opt.state = QStyle::State_None;
- if (w->isEnabled())
- opt.state |= QStyle::State_Enabled;
- if (o != Qt::Horizontal)
- opt.state |= QStyle::State_Horizontal;
- if (mouse_over)
- opt.state |= QStyle::State_MouseOver;
- opt.rect = r;
- opt.palette = w->palette();
-
- w->style()->drawPrimitive(QStyle::PE_IndicatorDockWidgetResizeHandle, &opt, p, w);
-}
-
-QRegion QDockAreaLayoutInfo::separatorRegion() const
-{
- QRegion result;
-
- if (isEmpty())
- return result;
-#ifndef QT_NO_TABBAR
- if (tabbed)
- return result;
-#endif
-
- for (int i = 0; i < item_list.count(); ++i) {
- const QDockAreaLayoutItem &item = item_list.at(i);
-
- if (item.skip())
- continue;
-
- int next = this->next(i);
-
- if (item.subinfo)
- result |= item.subinfo->separatorRegion();
-
- if (next == -1)
- break;
- result |= separatorRect(i);
- }
-
- return result;
-}
-
-void QDockAreaLayoutInfo::paintSeparators(QPainter *p, QWidget *widget,
- const QRegion &clip,
- const QPoint &mouse) const
-{
- if (isEmpty())
- return;
-#ifndef QT_NO_TABBAR
- if (tabbed)
- return;
-#endif
-
- for (int i = 0; i < item_list.count(); ++i) {
- const QDockAreaLayoutItem &item = item_list.at(i);
-
- if (item.skip())
- continue;
-
- int next = this->next(i);
- if ((item.flags & QDockAreaLayoutItem::GapItem)
- || (next != -1 && (item_list.at(next).flags & QDockAreaLayoutItem::GapItem)))
- continue;
-
- if (item.subinfo) {
- if (clip.contains(item.subinfo->rect))
- item.subinfo->paintSeparators(p, widget, clip, mouse);
- }
-
- if (next == -1)
- break;
- QRect r = separatorRect(i);
- if (clip.contains(r) && !item.hasFixedSize(o))
- paintSep(p, widget, r, o, r.contains(mouse));
- }
-}
-
-int QDockAreaLayoutInfo::next(int index) const
-{
- for (int i = index + 1; i < item_list.size(); ++i) {
- if (!item_list.at(i).skip())
- return i;
- }
- return -1;
-}
-
-int QDockAreaLayoutInfo::prev(int index) const
-{
- for (int i = index - 1; i >= 0; --i) {
- if (!item_list.at(i).skip())
- return i;
- }
- return -1;
-}
-
-void QDockAreaLayoutInfo::tab(int index, QLayoutItem *dockWidgetItem)
-{
-#ifdef QT_NO_TABBAR
- Q_UNUSED(index);
- Q_UNUSED(dockWidgetItem);
-#else
- if (tabbed) {
- item_list.append(QDockAreaLayoutItem(dockWidgetItem));
- updateTabBar();
- setCurrentTab(dockWidgetItem->widget());
- } else {
- QDockAreaLayoutInfo *new_info
- = new QDockAreaLayoutInfo(sep, dockPos, o, tabBarShape, mainWindow);
- item_list[index].subinfo = new_info;
- new_info->item_list.append(item_list.at(index).widgetItem);
- item_list[index].widgetItem = 0;
- new_info->item_list.append(dockWidgetItem);
- new_info->tabbed = true;
- new_info->updateTabBar();
- new_info->setCurrentTab(dockWidgetItem->widget());
- }
-#endif // QT_NO_TABBAR
-}
-
-void QDockAreaLayoutInfo::split(int index, Qt::Orientation orientation,
- QLayoutItem *dockWidgetItem)
-{
- if (orientation == o) {
- item_list.insert(index + 1, QDockAreaLayoutItem(dockWidgetItem));
- } else {
-#ifdef QT_NO_TABBAR
- const int tabBarShape = 0;
-#endif
- QDockAreaLayoutInfo *new_info
- = new QDockAreaLayoutInfo(sep, dockPos, orientation, tabBarShape, mainWindow);
- item_list[index].subinfo = new_info;
- new_info->item_list.append(item_list.at(index).widgetItem);
- item_list[index].widgetItem = 0;
- new_info->item_list.append(dockWidgetItem);
- }
-}
-
-QDockAreaLayoutItem &QDockAreaLayoutInfo::item(const QList<int> &path)
-{
- Q_ASSERT(!path.isEmpty());
- const int index = path.first();
- if (path.count() > 1) {
- const QDockAreaLayoutItem &item = item_list[index];
- Q_ASSERT(item.subinfo != 0);
- return item.subinfo->item(path.mid(1));
- }
- return item_list[index];
-}
-
-QLayoutItem *QDockAreaLayoutInfo::itemAt(int *x, int index) const
-{
- for (int i = 0; i < item_list.count(); ++i) {
- const QDockAreaLayoutItem &item = item_list.at(i);
- if (item.placeHolderItem != 0)
- continue;
- if (item.subinfo) {
- if (QLayoutItem *ret = item.subinfo->itemAt(x, index))
- return ret;
- } else if (item.widgetItem) {
- if ((*x)++ == index)
- return item.widgetItem;
- }
- }
- return 0;
-}
-
-QLayoutItem *QDockAreaLayoutInfo::takeAt(int *x, int index)
-{
- for (int i = 0; i < item_list.count(); ++i) {
- QDockAreaLayoutItem &item = item_list[i];
- if (item.placeHolderItem != 0)
- continue;
- else if (item.subinfo) {
- if (QLayoutItem *ret = item.subinfo->takeAt(x, index)) {
- unnest(i);
- return ret;
- }
- } else if (item.widgetItem) {
- if ((*x)++ == index) {
- item.placeHolderItem = new QPlaceHolderItem(item.widgetItem->widget());
- QLayoutItem *ret = item.widgetItem;
- item.widgetItem = 0;
- if (item.size != -1)
- item.flags |= QDockAreaLayoutItem::KeepSize;
- return ret;
- }
- }
- }
- return 0;
-}
-
-void QDockAreaLayoutInfo::deleteAllLayoutItems()
-{
- for (int i = 0; i < item_list.count(); ++i) {
- QDockAreaLayoutItem &item= item_list[i];
- if (item.subinfo) {
- item.subinfo->deleteAllLayoutItems();
- } else {
- delete item.widgetItem;
- item.widgetItem = 0;
- }
- }
-}
-
-void QDockAreaLayoutInfo::saveState(QDataStream &stream) const
-{
-#ifndef QT_NO_TABBAR
- if (tabbed) {
- stream << (uchar) TabMarker;
-
- // write the index in item_list of the widget that's currently on top.
- quintptr id = currentTabId();
- int index = -1;
- for (int i = 0; i < item_list.count(); ++i) {
- if (tabId(item_list.at(i)) == id) {
- index = i;
- break;
- }
- }
- stream << index;
- } else
-#endif // QT_NO_TABBAR
- {
- stream << (uchar) SequenceMarker;
- }
-
- stream << (uchar) o << item_list.count();
-
- for (int i = 0; i < item_list.count(); ++i) {
- const QDockAreaLayoutItem &item = item_list.at(i);
- if (item.widgetItem != 0) {
- stream << (uchar) WidgetMarker;
- QWidget *w = item.widgetItem->widget();
- QString name = w->objectName();
- if (name.isEmpty()) {
- qWarning("QMainWindow::saveState(): 'objectName' not set for QDockWidget %p '%s;",
- w, qPrintable(w->windowTitle()));
- }
- stream << name;
-
- uchar flags = 0;
- if (!w->isHidden())
- flags |= StateFlagVisible;
- if (w->isWindow())
- flags |= StateFlagFloating;
- stream << flags;
-
- if (w->isWindow()) {
- stream << w->x() << w->y() << w->width() << w->height();
- } else {
- stream << item.pos << item.size << pick(o, item.minimumSize())
- << pick(o, item.maximumSize());
- }
- } else if (item.placeHolderItem != 0) {
- stream << (uchar) WidgetMarker;
- stream << item.placeHolderItem->objectName;
- uchar flags = 0;
- if (!item.placeHolderItem->hidden)
- flags |= StateFlagVisible;
- if (item.placeHolderItem->window)
- flags |= StateFlagFloating;
- stream << flags;
- if (item.placeHolderItem->window) {
- QRect r = item.placeHolderItem->topLevelRect;
- stream << r.x() << r.y() << r.width() << r.height();
- } else {
- stream << item.pos << item.size << (int)0 << (int)0;
- }
- } else if (item.subinfo != 0) {
- stream << (uchar) SequenceMarker << item.pos << item.size << pick(o, item.minimumSize()) << pick(o, item.maximumSize());
- item.subinfo->saveState(stream);
- }
- }
-}
-
-static Qt::DockWidgetArea toDockWidgetArea(QInternal::DockPosition pos)
-{
- switch (pos) {
- case QInternal::LeftDock: return Qt::LeftDockWidgetArea;
- case QInternal::RightDock: return Qt::RightDockWidgetArea;
- case QInternal::TopDock: return Qt::TopDockWidgetArea;
- case QInternal::BottomDock: return Qt::BottomDockWidgetArea;
- default: break;
- }
- return Qt::NoDockWidgetArea;
-}
-
-static QRect constrainedRect(QRect rect, const QRect &desktop)
-{
- if (desktop.isValid()) {
- rect.setWidth(qMin(rect.width(), desktop.width()));
- rect.setHeight(qMin(rect.height(), desktop.height()));
- rect.moveLeft(qMax(rect.left(), desktop.left()));
- rect.moveTop(qMax(rect.top(), desktop.top()));
- rect.moveRight(qMin(rect.right(), desktop.right()));
- rect.moveBottom(qMin(rect.bottom(), desktop.bottom()));
- }
-
- return rect;
-}
-
-bool QDockAreaLayoutInfo::restoreState(QDataStream &stream, QList<QDockWidget*> &widgets, bool testing)
-{
- uchar marker;
- stream >> marker;
- if (marker != TabMarker && marker != SequenceMarker)
- return false;
-
-#ifndef QT_NO_TABBAR
- tabbed = marker == TabMarker;
-
- int index = -1;
- if (tabbed)
- stream >> index;
-#endif
-
- uchar orientation;
- stream >> orientation;
- o = static_cast<Qt::Orientation>(orientation);
-
- int cnt;
- stream >> cnt;
-
- for (int i = 0; i < cnt; ++i) {
- uchar nextMarker;
- stream >> nextMarker;
- if (nextMarker == WidgetMarker) {
- QString name;
- uchar flags;
- stream >> name >> flags;
- if (name.isEmpty()) {
- int dummy;
- stream >> dummy >> dummy >> dummy >> dummy;
- continue;
- }
-
- QDockWidget *widget = 0;
- for (int j = 0; j < widgets.count(); ++j) {
- if (widgets.at(j)->objectName() == name) {
- widget = widgets.takeAt(j);
- break;
- }
- }
-
- if (widget == 0) {
- QPlaceHolderItem *placeHolder = new QPlaceHolderItem;
- QDockAreaLayoutItem item(placeHolder);
-
- placeHolder->objectName = name;
- placeHolder->window = flags & StateFlagFloating;
- placeHolder->hidden = !(flags & StateFlagVisible);
- if (placeHolder->window) {
- int x, y, w, h;
- stream >> x >> y >> w >> h;
- placeHolder->topLevelRect = QRect(x, y, w, h);
- } else {
- int dummy;
- stream >> item.pos >> item.size >> dummy >> dummy;
- }
- if (item.size != -1)
- item.flags |= QDockAreaLayoutItem::KeepSize;
- if (!testing)
- item_list.append(item);
- } else {
- QDockAreaLayoutItem item(new QDockWidgetItem(widget));
- if (flags & StateFlagFloating) {
- bool drawer = false;
-#ifdef Q_WS_MAC // drawer support
- extern bool qt_mac_is_macdrawer(const QWidget *); //qwidget_mac.cpp
- extern bool qt_mac_set_drawer_preferred_edge(QWidget *, Qt::DockWidgetArea); //qwidget_mac.cpp
- drawer = qt_mac_is_macdrawer(widget);
-#endif
-
- if (!testing) {
- widget->hide();
- if (!drawer)
- widget->setFloating(true);
- }
-
- int x, y, w, h;
- stream >> x >> y >> w >> h;
-
-#ifdef Q_WS_MAC // drawer support
- if (drawer) {
- mainWindow->window()->createWinId();
- widget->window()->createWinId();
- qt_mac_set_drawer_preferred_edge(widget, toDockWidgetArea(dockPos));
- } else
-#endif
- if (!testing) {
- QRect r(x, y, w, h);
- QDesktopWidget *desktop = QApplication::desktop();
- if (desktop->isVirtualDesktop())
- r = constrainedRect(r, desktop->screenGeometry(desktop->screenNumber(r.topLeft())));
- else
- r = constrainedRect(r, desktop->screenGeometry(widget));
- widget->move(r.topLeft());
- widget->resize(r.size());
- }
-
- if (!testing) {
- widget->setVisible(flags & StateFlagVisible);
- item_list.append(item);
- }
- } else {
- int dummy;
- stream >> item.pos >> item.size >> dummy >> dummy;
- if (!testing) {
- item_list.append(item);
- widget->setFloating(false);
- widget->setVisible(flags & StateFlagVisible);
- emit widget->dockLocationChanged(toDockWidgetArea(dockPos));
- }
- }
- if (testing) {
- //was it is not really added to the layout, we need to delete the object here
- delete item.widgetItem;
- }
- }
- } else if (nextMarker == SequenceMarker) {
- int dummy;
-#ifdef QT_NO_TABBAR
- const int tabBarShape = 0;
-#endif
- QDockAreaLayoutItem item(new QDockAreaLayoutInfo(sep, dockPos, o,
- tabBarShape, mainWindow));
- stream >> item.pos >> item.size >> dummy >> dummy;
- //we need to make sure the element is in the list so the dock widget can eventually be docked correctly
- if (!testing)
- item_list.append(item);
-
- //here we need to make sure we change the item in the item_list
- QDockAreaLayoutItem &lastItem = testing ? item : item_list.last();
-
- if (!lastItem.subinfo->restoreState(stream, widgets, testing))
- return false;
-
- } else {
- return false;
- }
- }
-
-#ifndef QT_NO_TABBAR
- if (!testing && tabbed && index >= 0 && index < item_list.count()) {
- updateTabBar();
- setCurrentTabId(tabId(item_list.at(index)));
- }
- if (!testing && *sep == 1)
- updateSeparatorWidgets();
-#endif
-
- return true;
-}
-
-#ifndef QT_NO_TABBAR
-void QDockAreaLayoutInfo::updateSeparatorWidgets() const
-{
- if (tabbed) {
- separatorWidgets.clear();
- return;
- }
-
- int j = 0;
- for (int i = 0; i < item_list.count(); ++i) {
- const QDockAreaLayoutItem &item = item_list.at(i);
-
- if (item.skip())
- continue;
-
- int next = this->next(i);
- if ((item.flags & QDockAreaLayoutItem::GapItem)
- || (next != -1 && (item_list.at(next).flags & QDockAreaLayoutItem::GapItem)))
- continue;
-
- if (item.subinfo) {
- item.subinfo->updateSeparatorWidgets();
- }
-
- if (next == -1)
- break;
-
- QWidget *sepWidget;
- if (j < separatorWidgets.size() && separatorWidgets.at(j)) {
- sepWidget = separatorWidgets.at(j);
- } else {
- sepWidget = mainWindowLayout()->getSeparatorWidget();
- separatorWidgets.append(sepWidget);
- }
- j++;
-
-#ifndef QT_MAC_USE_COCOA
- sepWidget->raise();
-#endif
- QRect sepRect = separatorRect(i).adjusted(-2, -2, 2, 2);
- sepWidget->setGeometry(sepRect);
- sepWidget->setMask( QRegion(separatorRect(i).translated( - sepRect.topLeft())));
- sepWidget->show();
- }
-
- for (int k = j; k < separatorWidgets.size(); ++k) {
- separatorWidgets[k]->hide();
- }
- separatorWidgets.resize(j);
- Q_ASSERT(separatorWidgets.size() == j);
-}
-#endif //QT_NO_TABBAR
-
-#ifndef QT_NO_TABBAR
-//returns whether the tabbar is visible or not
-bool QDockAreaLayoutInfo::updateTabBar() const
-{
- if (!tabbed)
- return false;
-
- QDockAreaLayoutInfo *that = const_cast<QDockAreaLayoutInfo*>(this);
-
- if (that->tabBar == 0) {
- that->tabBar = mainWindowLayout()->getTabBar();
- that->tabBar->setShape(static_cast<QTabBar::Shape>(tabBarShape));
- that->tabBar->setDrawBase(true);
- }
-
- bool blocked = tabBar->blockSignals(true);
- bool gap = false;
-
- int tab_idx = 0;
- for (int i = 0; i < item_list.count(); ++i) {
- const QDockAreaLayoutItem &item = item_list.at(i);
- if (item.skip())
- continue;
- if (item.flags & QDockAreaLayoutItem::GapItem) {
- gap = true;
- continue;
- }
- if (item.widgetItem == 0)
- continue;
-
- QDockWidget *dw = qobject_cast<QDockWidget*>(item.widgetItem->widget());
- QString title = dw->d_func()->fixedWindowTitle;
- quintptr id = tabId(item);
- if (tab_idx == tabBar->count()) {
- tabBar->insertTab(tab_idx, title);
-#ifndef QT_NO_TOOLTIP
- tabBar->setTabToolTip(tab_idx, title);
-#endif
- tabBar->setTabData(tab_idx, id);
- } else if (qvariant_cast<quintptr>(tabBar->tabData(tab_idx)) != id) {
- if (tab_idx + 1 < tabBar->count()
- && qvariant_cast<quintptr>(tabBar->tabData(tab_idx + 1)) == id)
- tabBar->removeTab(tab_idx);
- else {
- tabBar->insertTab(tab_idx, title);
-#ifndef QT_NO_TOOLTIP
- tabBar->setTabToolTip(tab_idx, title);
-#endif
- tabBar->setTabData(tab_idx, id);
- }
- }
-
- if (title != tabBar->tabText(tab_idx)) {
- tabBar->setTabText(tab_idx, title);
-#ifndef QT_NO_TOOLTIP
- tabBar->setTabToolTip(tab_idx, title);
-#endif
- }
-
- ++tab_idx;
- }
-
- while (tab_idx < tabBar->count()) {
- tabBar->removeTab(tab_idx);
- }
-
- tabBar->blockSignals(blocked);
-
- //returns if the tabbar is visible or not
- return ( (gap ? 1 : 0) + tabBar->count()) > 1;
-}
-
-void QDockAreaLayoutInfo::setTabBarShape(int shape)
-{
- if (shape == tabBarShape)
- return;
- tabBarShape = shape;
- if (tabBar != 0)
- tabBar->setShape(static_cast<QTabBar::Shape>(shape));
-
- for (int i = 0; i < item_list.count(); ++i) {
- QDockAreaLayoutItem &item = item_list[i];
- if (item.subinfo != 0)
- item.subinfo->setTabBarShape(shape);
- }
-}
-
-QSize QDockAreaLayoutInfo::tabBarMinimumSize() const
-{
- if (!updateTabBar())
- return QSize(0, 0);
-
- return tabBar->minimumSizeHint();
-}
-
-QSize QDockAreaLayoutInfo::tabBarSizeHint() const
-{
- if (!updateTabBar())
- return QSize(0, 0);
-
- return tabBar->sizeHint();
-}
-
-QSet<QTabBar*> QDockAreaLayoutInfo::usedTabBars() const
-{
- QSet<QTabBar*> result;
-
- if (tabbed) {
- updateTabBar();
- result.insert(tabBar);
- }
-
- for (int i = 0; i < item_list.count(); ++i) {
- const QDockAreaLayoutItem &item = item_list.at(i);
- if (item.subinfo != 0)
- result += item.subinfo->usedTabBars();
- }
-
- return result;
-}
-
-// returns a set of all used separator widgets for this dockarelayout info
-// and all subinfos
-QSet<QWidget*> QDockAreaLayoutInfo::usedSeparatorWidgets() const
-{
- QSet<QWidget*> result;
-
- for (int i = 0; i < separatorWidgets.count(); ++i)
- result << separatorWidgets.at(i);
-
- for (int i = 0; i < item_list.count(); ++i) {
- const QDockAreaLayoutItem &item = item_list.at(i);
- if (item.subinfo != 0)
- result += item.subinfo->usedSeparatorWidgets();
- }
-
- return result;
-}
-
-QRect QDockAreaLayoutInfo::tabContentRect() const
-{
- if (!tabbed)
- return QRect();
-
- QRect result = rect;
- QSize tbh = tabBarSizeHint();
-
- if (!tbh.isNull()) {
- switch (tabBarShape) {
- case QTabBar::RoundedNorth:
- case QTabBar::TriangularNorth:
- result.adjust(0, tbh.height(), 0, 0);
- break;
- case QTabBar::RoundedSouth:
- case QTabBar::TriangularSouth:
- result.adjust(0, 0, 0, -tbh.height());
- break;
- case QTabBar::RoundedEast:
- case QTabBar::TriangularEast:
- result.adjust(0, 0, -tbh.width(), 0);
- break;
- case QTabBar::RoundedWest:
- case QTabBar::TriangularWest:
- result.adjust(tbh.width(), 0, 0, 0);
- break;
- default:
- break;
- }
- }
-
- return result;
-}
-#endif // QT_NO_TABBAR
-
-/******************************************************************************
-** QDockAreaLayout
-*/
-
-QDockAreaLayout::QDockAreaLayout(QMainWindow *win) : fallbackToSizeHints(true)
-{
- mainWindow = win;
- sep = win->style()->pixelMetric(QStyle::PM_DockWidgetSeparatorExtent, 0, win);
-#ifndef QT_NO_TABBAR
- const int tabShape = QTabBar::RoundedSouth;
-#else
- const int tabShape = 0;
-#endif
- docks[QInternal::LeftDock]
- = QDockAreaLayoutInfo(&sep, QInternal::LeftDock, Qt::Vertical, tabShape, win);
- docks[QInternal::RightDock]
- = QDockAreaLayoutInfo(&sep, QInternal::RightDock, Qt::Vertical, tabShape, win);
- docks[QInternal::TopDock]
- = QDockAreaLayoutInfo(&sep, QInternal::TopDock, Qt::Horizontal, tabShape, win);
- docks[QInternal::BottomDock]
- = QDockAreaLayoutInfo(&sep, QInternal::BottomDock, Qt::Horizontal, tabShape, win);
- centralWidgetItem = 0;
-
-
- corners[Qt::TopLeftCorner] = Qt::TopDockWidgetArea;
- corners[Qt::TopRightCorner] = Qt::TopDockWidgetArea;
- corners[Qt::BottomLeftCorner] = Qt::BottomDockWidgetArea;
- corners[Qt::BottomRightCorner] = Qt::BottomDockWidgetArea;
-}
-
-bool QDockAreaLayout::isValid() const
-{
- return rect.isValid();
-}
-
-void QDockAreaLayout::saveState(QDataStream &stream) const
-{
- stream << (uchar) DockWidgetStateMarker;
- int cnt = 0;
- for (int i = 0; i < QInternal::DockCount; ++i) {
- if (!docks[i].item_list.isEmpty())
- ++cnt;
- }
- stream << cnt;
- for (int i = 0; i < QInternal::DockCount; ++i) {
- if (docks[i].item_list.isEmpty())
- continue;
- stream << i << docks[i].rect.size();
- docks[i].saveState(stream);
- }
-
- stream << centralWidgetRect.size();
-
- for (int i = 0; i < 4; ++i)
- stream << static_cast<int>(corners[i]);
-}
-
-bool QDockAreaLayout::restoreState(QDataStream &stream, const QList<QDockWidget*> &_dockwidgets, bool testing)
-{
- QList<QDockWidget*> dockwidgets = _dockwidgets;
-
- int cnt;
- stream >> cnt;
- for (int i = 0; i < cnt; ++i) {
- int pos;
- stream >> pos;
- QSize size;
- stream >> size;
- if (!testing) {
- docks[pos].rect = QRect(QPoint(0, 0), size);
- }
- if (!docks[pos].restoreState(stream, dockwidgets, testing)) {
- stream.setStatus(QDataStream::ReadCorruptData);
- return false;
- }
- }
-
- QSize size;
- stream >> size;
- centralWidgetRect = QRect(QPoint(0, 0), size);
-
- bool ok = stream.status() == QDataStream::Ok;
-
- if (ok) {
- int cornerData[4];
- for (int i = 0; i < 4; ++i)
- stream >> cornerData[i];
- if (stream.status() == QDataStream::Ok) {
- for (int i = 0; i < 4; ++i)
- corners[i] = static_cast<Qt::DockWidgetArea>(cornerData[i]);
- }
-
- if (!testing)
- fallbackToSizeHints = false;
- }
-
- return ok;
-}
-
-QList<int> QDockAreaLayout::indexOfPlaceHolder(const QString &objectName) const
-{
- for (int i = 0; i < QInternal::DockCount; ++i) {
- QList<int> result = docks[i].indexOfPlaceHolder(objectName);
- if (!result.isEmpty()) {
- result.prepend(i);
- return result;
- }
- }
- return QList<int>();
-}
-
-QList<int> QDockAreaLayout::indexOf(QWidget *dockWidget) const
-{
- for (int i = 0; i < QInternal::DockCount; ++i) {
- QList<int> result = docks[i].indexOf(dockWidget);
- if (!result.isEmpty()) {
- result.prepend(i);
- return result;
- }
- }
- return QList<int>();
-}
-
-QList<int> QDockAreaLayout::gapIndex(const QPoint &pos) const
-{
- QMainWindow::DockOptions opts = mainWindow->dockOptions();
- bool nestingEnabled = opts & QMainWindow::AllowNestedDocks;
- QDockAreaLayoutInfo::TabMode tabMode = QDockAreaLayoutInfo::NoTabs;
-#ifndef QT_NO_TABBAR
- if (opts & QMainWindow::AllowTabbedDocks
- || opts & QMainWindow::VerticalTabs)
- tabMode = QDockAreaLayoutInfo::AllowTabs;
- if (opts & QMainWindow::ForceTabbedDocks)
- tabMode = QDockAreaLayoutInfo::ForceTabs;
-
- if (tabMode == QDockAreaLayoutInfo::ForceTabs)
- nestingEnabled = false;
-#endif
-
-
- for (int i = 0; i < QInternal::DockCount; ++i) {
- const QDockAreaLayoutInfo &info = docks[i];
-
- if (!info.isEmpty() && info.rect.contains(pos)) {
- QList<int> result
- = docks[i].gapIndex(pos, nestingEnabled, tabMode);
- if (!result.isEmpty())
- result.prepend(i);
- return result;
- }
- }
-
- for (int i = 0; i < QInternal::DockCount; ++i) {
- const QDockAreaLayoutInfo &info = docks[i];
-
- if (info.isEmpty()) {
- QRect r;
- switch (i) {
- case QInternal::LeftDock:
- r = QRect(rect.left(), rect.top(), EmptyDropAreaSize, rect.height());
- break;
- case QInternal::RightDock:
- r = QRect(rect.right() - EmptyDropAreaSize, rect.top(),
- EmptyDropAreaSize, rect.height());
- break;
- case QInternal::TopDock:
- r = QRect(rect.left(), rect.top(), rect.width(), EmptyDropAreaSize);
- break;
- case QInternal::BottomDock:
- r = QRect(rect.left(), rect.bottom() - EmptyDropAreaSize,
- rect.width(), EmptyDropAreaSize);
- break;
- }
- if (r.contains(pos)) {
- if (opts & QMainWindow::ForceTabbedDocks && !info.item_list.isEmpty()) {
- //in case of ForceTabbedDocks, we pass -1 in order to force the gap to be tabbed
- //it mustn't be completely empty otherwise it won't work
- return QList<int>() << i << -1 << 0;
- } else {
- return QList<int>() << i << 0;
- }
- }
- }
- }
-
- return QList<int>();
-}
-
-QList<int> QDockAreaLayout::findSeparator(const QPoint &pos) const
-{
- QList<int> result;
- for (int i = 0; i < QInternal::DockCount; ++i) {
- const QDockAreaLayoutInfo &info = docks[i];
- if (info.isEmpty())
- continue;
- QRect rect = separatorRect(i);
- if (!rect.isNull() && sep == 1)
- rect.adjust(-2, -2, 2, 2);
- if (rect.contains(pos) && !info.hasFixedSize()) {
- result << i;
- break;
- } else if (info.rect.contains(pos)) {
- result = docks[i].findSeparator(pos);
- if (!result.isEmpty()) {
- result.prepend(i);
- break;
- }
- }
- }
-
- return result;
-}
-
-QDockAreaLayoutInfo *QDockAreaLayout::info(QWidget *widget)
-{
- for (int i = 0; i < QInternal::DockCount; ++i) {
- if (QDockAreaLayoutInfo *result = docks[i].info(widget))
- return result;
- }
-
- return 0;
-}
-
-QDockAreaLayoutInfo *QDockAreaLayout::info(const QList<int> &path)
-{
- Q_ASSERT(!path.isEmpty());
- const int index = path.first();
- Q_ASSERT(index >= 0 && index < QInternal::DockCount);
-
- if (path.count() == 1)
- return &docks[index];
-
- return docks[index].info(path.mid(1));
-}
-
-const QDockAreaLayoutInfo *QDockAreaLayout::info(const QList<int> &path) const
-{
- return const_cast<QDockAreaLayout*>(this)->info(path);
-}
-
-QDockAreaLayoutItem &QDockAreaLayout::item(const QList<int> &path)
-{
- Q_ASSERT(!path.isEmpty());
- const int index = path.first();
- Q_ASSERT(index >= 0 && index < QInternal::DockCount);
- return docks[index].item(path.mid(1));
-}
-
-QRect QDockAreaLayout::itemRect(const QList<int> &path) const
-{
- Q_ASSERT(!path.isEmpty());
- const int index = path.first();
- Q_ASSERT(index >= 0 && index < QInternal::DockCount);
- return docks[index].itemRect(path.mid(1));
-}
-
-QRect QDockAreaLayout::separatorRect(int index) const
-{
- const QDockAreaLayoutInfo &dock = docks[index];
- if (dock.isEmpty())
- return QRect();
- QRect r = dock.rect;
- switch (index) {
- case QInternal::LeftDock:
- return QRect(r.right() + 1, r.top(), sep, r.height());
- case QInternal::RightDock:
- return QRect(r.left() - sep, r.top(), sep, r.height());
- case QInternal::TopDock:
- return QRect(r.left(), r.bottom() + 1, r.width(), sep);
- case QInternal::BottomDock:
- return QRect(r.left(), r.top() - sep, r.width(), sep);
- default:
- break;
- }
- return QRect();
-}
-
-QRect QDockAreaLayout::separatorRect(const QList<int> &path) const
-{
- Q_ASSERT(!path.isEmpty());
-
- const int index = path.first();
- Q_ASSERT(index >= 0 && index < QInternal::DockCount);
-
- if (path.count() == 1)
- return separatorRect(index);
- else
- return docks[index].separatorRect(path.mid(1));
-}
-
-bool QDockAreaLayout::insertGap(const QList<int> &path, QLayoutItem *dockWidgetItem)
-{
- Q_ASSERT(!path.isEmpty());
- const int index = path.first();
- Q_ASSERT(index >= 0 && index < QInternal::DockCount);
- return docks[index].insertGap(path.mid(1), dockWidgetItem);
-}
-
-QLayoutItem *QDockAreaLayout::plug(const QList<int> &path)
-{
- Q_ASSERT(!path.isEmpty());
- const int index = path.first();
- Q_ASSERT(index >= 0 && index < QInternal::DockCount);
- return docks[index].plug(path.mid(1));
-}
-
-QLayoutItem *QDockAreaLayout::unplug(const QList<int> &path)
-{
- Q_ASSERT(!path.isEmpty());
- const int index = path.first();
- Q_ASSERT(index >= 0 && index < QInternal::DockCount);
- return docks[index].unplug(path.mid(1));
-}
-
-void QDockAreaLayout::remove(const QList<int> &path)
-{
- Q_ASSERT(!path.isEmpty());
- const int index = path.first();
- Q_ASSERT(index >= 0 && index < QInternal::DockCount);
- docks[index].remove(path.mid(1));
-}
-
-static inline int qMin(int i1, int i2, int i3) { return qMin(i1, qMin(i2, i3)); }
-static inline int qMax(int i1, int i2, int i3) { return qMax(i1, qMax(i2, i3)); }
-
-void QDockAreaLayout::getGrid(QVector<QLayoutStruct> *_ver_struct_list,
- QVector<QLayoutStruct> *_hor_struct_list)
-{
- QSize center_hint(0, 0);
- QSize center_min(0, 0);
- const bool have_central = centralWidgetItem != 0 && !centralWidgetItem->isEmpty();
- if (have_central) {
- center_hint = centralWidgetRect.size();
- if (!center_hint.isValid())
- center_hint = centralWidgetItem->sizeHint();
- center_min = centralWidgetItem->minimumSize();
- }
-
- QRect center_rect = rect;
- if (!docks[QInternal::LeftDock].isEmpty())
- center_rect.setLeft(rect.left() + docks[QInternal::LeftDock].rect.width() + sep);
- if (!docks[QInternal::TopDock].isEmpty())
- center_rect.setTop(rect.top() + docks[QInternal::TopDock].rect.height() + sep);
- if (!docks[QInternal::RightDock].isEmpty())
- center_rect.setRight(rect.right() - docks[QInternal::RightDock].rect.width() - sep);
- if (!docks[QInternal::BottomDock].isEmpty())
- center_rect.setBottom(rect.bottom() - docks[QInternal::BottomDock].rect.height() - sep);
-
- QSize left_hint = docks[QInternal::LeftDock].size();
- if (left_hint.isNull() || fallbackToSizeHints)
- left_hint = docks[QInternal::LeftDock].sizeHint();
- QSize left_min = docks[QInternal::LeftDock].minimumSize();
- QSize left_max = docks[QInternal::LeftDock].maximumSize();
- left_hint = left_hint.boundedTo(left_max).expandedTo(left_min);
-
- QSize right_hint = docks[QInternal::RightDock].size();
- if (right_hint.isNull() || fallbackToSizeHints)
- right_hint = docks[QInternal::RightDock].sizeHint();
- QSize right_min = docks[QInternal::RightDock].minimumSize();
- QSize right_max = docks[QInternal::RightDock].maximumSize();
- right_hint = right_hint.boundedTo(right_max).expandedTo(right_min);
-
- QSize top_hint = docks[QInternal::TopDock].size();
- if (top_hint.isNull() || fallbackToSizeHints)
- top_hint = docks[QInternal::TopDock].sizeHint();
- QSize top_min = docks[QInternal::TopDock].minimumSize();
- QSize top_max = docks[QInternal::TopDock].maximumSize();
- top_hint = top_hint.boundedTo(top_max).expandedTo(top_min);
-
- QSize bottom_hint = docks[QInternal::BottomDock].size();
- if (bottom_hint.isNull() || fallbackToSizeHints)
- bottom_hint = docks[QInternal::BottomDock].sizeHint();
- QSize bottom_min = docks[QInternal::BottomDock].minimumSize();
- QSize bottom_max = docks[QInternal::BottomDock].maximumSize();
- bottom_hint = bottom_hint.boundedTo(bottom_max).expandedTo(bottom_min);
-
- fallbackToSizeHints = false;
-
- if (_ver_struct_list != 0) {
- QVector<QLayoutStruct> &ver_struct_list = *_ver_struct_list;
- ver_struct_list.resize(3);
-
- // top --------------------------------------------------
- ver_struct_list[0].init();
- ver_struct_list[0].stretch = 0;
- ver_struct_list[0].sizeHint = top_hint.height();
- ver_struct_list[0].minimumSize = top_min.height();
- ver_struct_list[0].maximumSize = top_max.height();
- ver_struct_list[0].expansive = false;
- ver_struct_list[0].empty = docks[QInternal::TopDock].isEmpty();
- ver_struct_list[0].pos = docks[QInternal::TopDock].rect.top();
- ver_struct_list[0].size = docks[QInternal::TopDock].rect.height();
-
- // center --------------------------------------------------
- ver_struct_list[1].init();
- ver_struct_list[1].stretch = center_hint.height();
-
- bool tl_significant = corners[Qt::TopLeftCorner] == Qt::TopDockWidgetArea
- || docks[QInternal::TopDock].isEmpty();
- bool bl_significant = corners[Qt::BottomLeftCorner] == Qt::BottomDockWidgetArea
- || docks[QInternal::BottomDock].isEmpty();
- bool tr_significant = corners[Qt::TopRightCorner] == Qt::TopDockWidgetArea
- || docks[QInternal::TopDock].isEmpty();
- bool br_significant = corners[Qt::BottomRightCorner] == Qt::BottomDockWidgetArea
- || docks[QInternal::BottomDock].isEmpty();
-
- int left = (tl_significant && bl_significant) ? left_hint.height() : 0;
- int right = (tr_significant && br_significant) ? right_hint.height() : 0;
- ver_struct_list[1].sizeHint = qMax(left, center_hint.height(), right);
-
- left = (tl_significant && bl_significant) ? left_min.height() : 0;
- right = (tr_significant && br_significant) ? right_min.height() : 0;
- ver_struct_list[1].minimumSize = qMax(left, center_min.height(), right);
- ver_struct_list[1].maximumSize = have_central ? QWIDGETSIZE_MAX : 0;
- ver_struct_list[1].expansive = have_central;
- ver_struct_list[1].empty = docks[QInternal::LeftDock].isEmpty()
- && !have_central
- && docks[QInternal::RightDock].isEmpty();
- ver_struct_list[1].pos = center_rect.top();
- ver_struct_list[1].size = center_rect.height();
-
- // bottom --------------------------------------------------
- ver_struct_list[2].init();
- ver_struct_list[2].stretch = 0;
- ver_struct_list[2].sizeHint = bottom_hint.height();
- ver_struct_list[2].minimumSize = bottom_min.height();
- ver_struct_list[2].maximumSize = bottom_max.height();
- ver_struct_list[2].expansive = false;
- ver_struct_list[2].empty = docks[QInternal::BottomDock].isEmpty();
- ver_struct_list[2].pos = docks[QInternal::BottomDock].rect.top();
- ver_struct_list[2].size = docks[QInternal::BottomDock].rect.height();
-
- for (int i = 0; i < 3; ++i) {
- ver_struct_list[i].sizeHint
- = qMax(ver_struct_list[i].sizeHint, ver_struct_list[i].minimumSize);
- }
- }
-
- if (_hor_struct_list != 0) {
- QVector<QLayoutStruct> &hor_struct_list = *_hor_struct_list;
- hor_struct_list.resize(3);
-
- // left --------------------------------------------------
- hor_struct_list[0].init();
- hor_struct_list[0].stretch = 0;
- hor_struct_list[0].sizeHint = left_hint.width();
- hor_struct_list[0].minimumSize = left_min.width();
- hor_struct_list[0].maximumSize = left_max.width();
- hor_struct_list[0].expansive = false;
- hor_struct_list[0].empty = docks[QInternal::LeftDock].isEmpty();
- hor_struct_list[0].pos = docks[QInternal::LeftDock].rect.left();
- hor_struct_list[0].size = docks[QInternal::LeftDock].rect.width();
-
- // center --------------------------------------------------
- hor_struct_list[1].init();
- hor_struct_list[1].stretch = center_hint.width();
-
- bool tl_significant = corners[Qt::TopLeftCorner] == Qt::LeftDockWidgetArea
- || docks[QInternal::LeftDock].isEmpty();
- bool tr_significant = corners[Qt::TopRightCorner] == Qt::RightDockWidgetArea
- || docks[QInternal::RightDock].isEmpty();
- bool bl_significant = corners[Qt::BottomLeftCorner] == Qt::LeftDockWidgetArea
- || docks[QInternal::LeftDock].isEmpty();
- bool br_significant = corners[Qt::BottomRightCorner] == Qt::RightDockWidgetArea
- || docks[QInternal::RightDock].isEmpty();
-
- int top = (tl_significant && tr_significant) ? top_hint.width() : 0;
- int bottom = (bl_significant && br_significant) ? bottom_hint.width() : 0;
- hor_struct_list[1].sizeHint = qMax(top, center_hint.width(), bottom);
-
- top = (tl_significant && tr_significant) ? top_min.width() : 0;
- bottom = (bl_significant && br_significant) ? bottom_min.width() : 0;
- hor_struct_list[1].minimumSize = qMax(top, center_min.width(), bottom);
-
- hor_struct_list[1].maximumSize = have_central ? QWIDGETSIZE_MAX : 0;
- hor_struct_list[1].expansive = have_central;
- hor_struct_list[1].empty = !have_central;
- hor_struct_list[1].pos = center_rect.left();
- hor_struct_list[1].size = center_rect.width();
-
- // right --------------------------------------------------
- hor_struct_list[2].init();
- hor_struct_list[2].stretch = 0;
- hor_struct_list[2].sizeHint = right_hint.width();
- hor_struct_list[2].minimumSize = right_min.width();
- hor_struct_list[2].maximumSize = right_max.width();
- hor_struct_list[2].expansive = false;
- hor_struct_list[2].empty = docks[QInternal::RightDock].isEmpty();
- hor_struct_list[2].pos = docks[QInternal::RightDock].rect.left();
- hor_struct_list[2].size = docks[QInternal::RightDock].rect.width();
-
- for (int i = 0; i < 3; ++i) {
- hor_struct_list[i].sizeHint
- = qMax(hor_struct_list[i].sizeHint, hor_struct_list[i].minimumSize);
- }
- }
-}
-
-void QDockAreaLayout::setGrid(QVector<QLayoutStruct> *ver_struct_list,
- QVector<QLayoutStruct> *hor_struct_list)
-{
-
- // top ---------------------------------------------------
-
- if (!docks[QInternal::TopDock].isEmpty()) {
- QRect r = docks[QInternal::TopDock].rect;
- if (hor_struct_list != 0) {
- r.setLeft(corners[Qt::TopLeftCorner] == Qt::TopDockWidgetArea
- || docks[QInternal::LeftDock].isEmpty()
- ? rect.left() : hor_struct_list->at(1).pos);
- r.setRight(corners[Qt::TopRightCorner] == Qt::TopDockWidgetArea
- || docks[QInternal::RightDock].isEmpty()
- ? rect.right() : hor_struct_list->at(2).pos - sep - 1);
- }
- if (ver_struct_list != 0) {
- r.setTop(rect.top());
- r.setBottom(ver_struct_list->at(1).pos - sep - 1);
- }
- docks[QInternal::TopDock].rect = r;
- docks[QInternal::TopDock].fitItems();
- }
-
- // bottom ---------------------------------------------------
-
- if (!docks[QInternal::BottomDock].isEmpty()) {
- QRect r = docks[QInternal::BottomDock].rect;
- if (hor_struct_list != 0) {
- r.setLeft(corners[Qt::BottomLeftCorner] == Qt::BottomDockWidgetArea
- || docks[QInternal::LeftDock].isEmpty()
- ? rect.left() : hor_struct_list->at(1).pos);
- r.setRight(corners[Qt::BottomRightCorner] == Qt::BottomDockWidgetArea
- || docks[QInternal::RightDock].isEmpty()
- ? rect.right() : hor_struct_list->at(2).pos - sep - 1);
- }
- if (ver_struct_list != 0) {
- r.setTop(ver_struct_list->at(2).pos);
- r.setBottom(rect.bottom());
- }
- docks[QInternal::BottomDock].rect = r;
- docks[QInternal::BottomDock].fitItems();
- }
-
- // left ---------------------------------------------------
-
- if (!docks[QInternal::LeftDock].isEmpty()) {
- QRect r = docks[QInternal::LeftDock].rect;
- if (hor_struct_list != 0) {
- r.setLeft(rect.left());
- r.setRight(hor_struct_list->at(1).pos - sep - 1);
- }
- if (ver_struct_list != 0) {
- r.setTop(corners[Qt::TopLeftCorner] == Qt::LeftDockWidgetArea
- || docks[QInternal::TopDock].isEmpty()
- ? rect.top() : ver_struct_list->at(1).pos);
- r.setBottom(corners[Qt::BottomLeftCorner] == Qt::LeftDockWidgetArea
- || docks[QInternal::BottomDock].isEmpty()
- ? rect.bottom() : ver_struct_list->at(2).pos - sep - 1);
- }
- docks[QInternal::LeftDock].rect = r;
- docks[QInternal::LeftDock].fitItems();
- }
-
- // right ---------------------------------------------------
-
- if (!docks[QInternal::RightDock].isEmpty()) {
- QRect r = docks[QInternal::RightDock].rect;
- if (hor_struct_list != 0) {
- r.setLeft(hor_struct_list->at(2).pos);
- r.setRight(rect.right());
- }
- if (ver_struct_list != 0) {
- r.setTop(corners[Qt::TopRightCorner] == Qt::RightDockWidgetArea
- || docks[QInternal::TopDock].isEmpty()
- ? rect.top() : ver_struct_list->at(1).pos);
- r.setBottom(corners[Qt::BottomRightCorner] == Qt::RightDockWidgetArea
- || docks[QInternal::BottomDock].isEmpty()
- ? rect.bottom() : ver_struct_list->at(2).pos - sep - 1);
- }
- docks[QInternal::RightDock].rect = r;
- docks[QInternal::RightDock].fitItems();
- }
-
- // center ---------------------------------------------------
-
- if (hor_struct_list != 0) {
- centralWidgetRect.setLeft(hor_struct_list->at(1).pos);
- centralWidgetRect.setWidth(hor_struct_list->at(1).size);
- }
- if (ver_struct_list != 0) {
- centralWidgetRect.setTop(ver_struct_list->at(1).pos);
- centralWidgetRect.setHeight(ver_struct_list->at(1).size);
- }
-}
-
-void QDockAreaLayout::fitLayout()
-{
- QVector<QLayoutStruct> ver_struct_list(3);
- QVector<QLayoutStruct> hor_struct_list(3);
- getGrid(&ver_struct_list, &hor_struct_list);
-
- qGeomCalc(ver_struct_list, 0, 3, rect.top(), rect.height(), sep);
- qGeomCalc(hor_struct_list, 0, 3, rect.left(), rect.width(), sep);
-
- setGrid(&ver_struct_list, &hor_struct_list);
-}
-
-void QDockAreaLayout::clear()
-{
- for (int i = 0; i < QInternal::DockCount; ++i)
- docks[i].clear();
-
- rect = QRect();
- centralWidgetRect = QRect();
-}
-
-QSize QDockAreaLayout::sizeHint() const
-{
- int left_sep = 0;
- int right_sep = 0;
- int top_sep = 0;
- int bottom_sep = 0;
-
- if (centralWidgetItem != 0) {
- left_sep = docks[QInternal::LeftDock].isEmpty() ? 0 : sep;
- right_sep = docks[QInternal::RightDock].isEmpty() ? 0 : sep;
- top_sep = docks[QInternal::TopDock].isEmpty() ? 0 : sep;
- bottom_sep = docks[QInternal::BottomDock].isEmpty() ? 0 : sep;
- }
-
- QSize left = docks[QInternal::LeftDock].sizeHint() + QSize(left_sep, 0);
- QSize right = docks[QInternal::RightDock].sizeHint() + QSize(right_sep, 0);
- QSize top = docks[QInternal::TopDock].sizeHint() + QSize(0, top_sep);
- QSize bottom = docks[QInternal::BottomDock].sizeHint() + QSize(0, bottom_sep);
- QSize center = centralWidgetItem == 0 ? QSize(0, 0) : centralWidgetItem->sizeHint();
-
- int row1 = top.width();
- int row2 = left.width() + center.width() + right.width();
- int row3 = bottom.width();
- int col1 = left.height();
- int col2 = top.height() + center.height() + bottom.height();
- int col3 = right.height();
-
- if (corners[Qt::TopLeftCorner] == Qt::LeftDockWidgetArea)
- row1 += left.width();
- else
- col1 += top.height();
-
- if (corners[Qt::TopRightCorner] == Qt::RightDockWidgetArea)
- row1 += right.width();
- else
- col3 += top.height();
-
- if (corners[Qt::BottomLeftCorner] == Qt::LeftDockWidgetArea)
- row3 += left.width();
- else
- col1 += bottom.height();
-
- if (corners[Qt::BottomRightCorner] == Qt::RightDockWidgetArea)
- row3 += right.width();
- else
- col3 += bottom.height();
-
- return QSize(qMax(row1, row2, row3), qMax(col1, col2, col3));
-}
-
-QSize QDockAreaLayout::minimumSize() const
-{
- int left_sep = 0;
- int right_sep = 0;
- int top_sep = 0;
- int bottom_sep = 0;
-
- if (centralWidgetItem != 0) {
- left_sep = docks[QInternal::LeftDock].isEmpty() ? 0 : sep;
- right_sep = docks[QInternal::RightDock].isEmpty() ? 0 : sep;
- top_sep = docks[QInternal::TopDock].isEmpty() ? 0 : sep;
- bottom_sep = docks[QInternal::BottomDock].isEmpty() ? 0 : sep;
- }
-
- QSize left = docks[QInternal::LeftDock].minimumSize() + QSize(left_sep, 0);
- QSize right = docks[QInternal::RightDock].minimumSize() + QSize(right_sep, 0);
- QSize top = docks[QInternal::TopDock].minimumSize() + QSize(0, top_sep);
- QSize bottom = docks[QInternal::BottomDock].minimumSize() + QSize(0, bottom_sep);
- QSize center = centralWidgetItem == 0 ? QSize(0, 0) : centralWidgetItem->minimumSize();
-
- int row1 = top.width();
- int row2 = left.width() + center.width() + right.width();
- int row3 = bottom.width();
- int col1 = left.height();
- int col2 = top.height() + center.height() + bottom.height();
- int col3 = right.height();
-
- if (corners[Qt::TopLeftCorner] == Qt::LeftDockWidgetArea)
- row1 += left.width();
- else
- col1 += top.height();
-
- if (corners[Qt::TopRightCorner] == Qt::RightDockWidgetArea)
- row1 += right.width();
- else
- col3 += top.height();
-
- if (corners[Qt::BottomLeftCorner] == Qt::LeftDockWidgetArea)
- row3 += left.width();
- else
- col1 += bottom.height();
-
- if (corners[Qt::BottomRightCorner] == Qt::RightDockWidgetArea)
- row3 += right.width();
- else
- col3 += bottom.height();
-
- return QSize(qMax(row1, row2, row3), qMax(col1, col2, col3));
-}
-
-bool QDockAreaLayout::restoreDockWidget(QDockWidget *dockWidget)
-{
- QList<int> index = indexOfPlaceHolder(dockWidget->objectName());
- if (index.isEmpty())
- return false;
-
- QDockAreaLayoutItem &item = this->item(index);
- QPlaceHolderItem *placeHolder = item.placeHolderItem;
- Q_ASSERT(placeHolder != 0);
-
- item.widgetItem = new QDockWidgetItem(dockWidget);
-
- if (placeHolder->window) {
- QDesktopWidget desktop;
- QRect r = constrainedRect(placeHolder->topLevelRect, desktop.screenGeometry(dockWidget));
- dockWidget->d_func()->setWindowState(true, true, r);
- }
- dockWidget->setVisible(!placeHolder->hidden);
-#ifdef Q_WS_X11
- if (placeHolder->window) // gets rid of the X11BypassWindowManager window flag
- dockWidget->d_func()->setWindowState(true);
-#endif
-
- item.placeHolderItem = 0;
- delete placeHolder;
-
- return true;
-}
-
-void QDockAreaLayout::addDockWidget(QInternal::DockPosition pos, QDockWidget *dockWidget,
- Qt::Orientation orientation)
-{
- QLayoutItem *dockWidgetItem = new QDockWidgetItem(dockWidget);
- QDockAreaLayoutInfo &info = docks[pos];
- if (orientation == info.o || info.item_list.count() <= 1) {
- // empty dock areas, or dock areas containing exactly one widget can have their orientation
- // switched.
- info.o = orientation;
-
- QDockAreaLayoutItem new_item(dockWidgetItem);
- info.item_list.append(new_item);
-#ifndef QT_NO_TABBAR
- if (info.tabbed && !new_item.skip()) {
- info.updateTabBar();
- info.setCurrentTabId(tabId(new_item));
- }
-#endif
- } else {
-#ifndef QT_NO_TABBAR
- int tbshape = info.tabBarShape;
-#else
- int tbshape = 0;
-#endif
- QDockAreaLayoutInfo new_info(&sep, pos, orientation, tbshape, mainWindow);
- new_info.item_list.append(new QDockAreaLayoutInfo(info));
- new_info.item_list.append(dockWidgetItem);
- info = new_info;
- }
-
- QList<int> index = indexOfPlaceHolder(dockWidget->objectName());
- if (!index.isEmpty())
- remove(index);
-}
-
-void QDockAreaLayout::tabifyDockWidget(QDockWidget *first, QDockWidget *second)
-{
- QList<int> path = indexOf(first);
- if (path.isEmpty())
- return;
-
- QDockAreaLayoutInfo *info = this->info(path);
- Q_ASSERT(info != 0);
- info->tab(path.last(), new QDockWidgetItem(second));
-
- QList<int> index = indexOfPlaceHolder(second->objectName());
- if (!index.isEmpty())
- remove(index);
-}
-
-void QDockAreaLayout::splitDockWidget(QDockWidget *after,
- QDockWidget *dockWidget,
- Qt::Orientation orientation)
-{
- QList<int> path = indexOf(after);
- if (path.isEmpty())
- return;
-
- QDockAreaLayoutInfo *info = this->info(path);
- Q_ASSERT(info != 0);
- info->split(path.last(), orientation, new QDockWidgetItem(dockWidget));
-
- QList<int> index = indexOfPlaceHolder(dockWidget->objectName());
- if (!index.isEmpty())
- remove(index);
-}
-
-void QDockAreaLayout::apply(bool animate)
-{
- QWidgetAnimator &widgetAnimator = qt_mainwindow_layout(mainWindow)->widgetAnimator;
-
- for (int i = 0; i < QInternal::DockCount; ++i)
- docks[i].apply(animate);
- if (centralWidgetItem != 0 && !centralWidgetItem->isEmpty()) {
- widgetAnimator.animate(centralWidgetItem->widget(), centralWidgetRect,
- animate);
- }
-#ifndef QT_NO_TABBAR
- if (sep == 1)
- updateSeparatorWidgets();
-#endif //QT_NO_TABBAR
-}
-
-void QDockAreaLayout::paintSeparators(QPainter *p, QWidget *widget,
- const QRegion &clip,
- const QPoint &mouse) const
-{
- for (int i = 0; i < QInternal::DockCount; ++i) {
- const QDockAreaLayoutInfo &dock = docks[i];
- if (dock.isEmpty())
- continue;
- QRect r = separatorRect(i);
- if (clip.contains(r) && !dock.hasFixedSize()) {
- Qt::Orientation opposite = dock.o == Qt::Horizontal
- ? Qt::Vertical : Qt::Horizontal;
- paintSep(p, widget, r, opposite, r.contains(mouse));
- }
- if (clip.contains(dock.rect))
- dock.paintSeparators(p, widget, clip, mouse);
- }
-}
-
-QRegion QDockAreaLayout::separatorRegion() const
-{
- QRegion result;
-
- for (int i = 0; i < QInternal::DockCount; ++i) {
- const QDockAreaLayoutInfo &dock = docks[i];
- if (dock.isEmpty())
- continue;
- result |= separatorRect(i);
- result |= dock.separatorRegion();
- }
-
- return result;
-}
-
-int QDockAreaLayout::separatorMove(const QList<int> &separator, const QPoint &origin,
- const QPoint &dest)
-{
- int delta = 0;
- int index = separator.last();
-
- if (separator.count() > 1) {
- QDockAreaLayoutInfo *info = this->info(separator);
- delta = pick(info->o, dest - origin);
- if (delta != 0)
- delta = info->separatorMove(index, delta);
- info->apply(false);
- return delta;
- }
-
- QVector<QLayoutStruct> list;
-
- if (index == QInternal::LeftDock || index == QInternal::RightDock)
- getGrid(0, &list);
- else
- getGrid(&list, 0);
-
- int sep_index = index == QInternal::LeftDock || index == QInternal::TopDock
- ? 0 : 1;
- Qt::Orientation o = index == QInternal::LeftDock || index == QInternal::RightDock
- ? Qt::Horizontal
- : Qt::Vertical;
-
- delta = pick(o, dest - origin);
- delta = separatorMoveHelper(list, sep_index, delta, sep);
-
- if (index == QInternal::LeftDock || index == QInternal::RightDock)
- setGrid(0, &list);
- else
- setGrid(&list, 0);
-
- apply(false);
-
- return delta;
-}
-
-#ifndef QT_NO_TABBAR
-// Sets the correct positions for the separator widgets
-// Allocates new sepearator widgets with getSeparatorWidget
-void QDockAreaLayout::updateSeparatorWidgets() const
-{
- int j = 0;
-
- for (int i = 0; i < QInternal::DockCount; ++i) {
- const QDockAreaLayoutInfo &dock = docks[i];
- if (dock.isEmpty())
- continue;
-
- QWidget *sepWidget;
- if (j < separatorWidgets.size()) {
- sepWidget = separatorWidgets.at(j);
- } else {
- sepWidget = qt_mainwindow_layout(mainWindow)->getSeparatorWidget();
- separatorWidgets.append(sepWidget);
- }
- j++;
-
-#ifndef QT_MAC_USE_COCOA
- sepWidget->raise();
-#endif
- QRect sepRect = separatorRect(i).adjusted(-2, -2, 2, 2);
- sepWidget->setGeometry(sepRect);
- sepWidget->setMask( QRegion(separatorRect(i).translated( - sepRect.topLeft())));
- sepWidget->show();
- }
- for (int i = j; i < separatorWidgets.size(); ++i)
- separatorWidgets.at(i)->hide();
-
- separatorWidgets.resize(j);
-}
-#endif //QT_NO_TABBAR
-
-QLayoutItem *QDockAreaLayout::itemAt(int *x, int index) const
-{
- Q_ASSERT(x != 0);
-
- for (int i = 0; i < QInternal::DockCount; ++i) {
- const QDockAreaLayoutInfo &dock = docks[i];
- if (QLayoutItem *ret = dock.itemAt(x, index))
- return ret;
- }
-
- if (centralWidgetItem && (*x)++ == index)
- return centralWidgetItem;
-
- return 0;
-}
-
-QLayoutItem *QDockAreaLayout::takeAt(int *x, int index)
-{
- Q_ASSERT(x != 0);
-
- for (int i = 0; i < QInternal::DockCount; ++i) {
- QDockAreaLayoutInfo &dock = docks[i];
- if (QLayoutItem *ret = dock.takeAt(x, index))
- return ret;
- }
-
- if (centralWidgetItem && (*x)++ == index) {
- QLayoutItem *ret = centralWidgetItem;
- centralWidgetItem = 0;
- return ret;
- }
-
- return 0;
-}
-
-void QDockAreaLayout::deleteAllLayoutItems()
-{
- for (int i = 0; i < QInternal::DockCount; ++i)
- docks[i].deleteAllLayoutItems();
-}
-
-#ifndef QT_NO_TABBAR
-QSet<QTabBar*> QDockAreaLayout::usedTabBars() const
-{
- QSet<QTabBar*> result;
- for (int i = 0; i < QInternal::DockCount; ++i) {
- const QDockAreaLayoutInfo &dock = docks[i];
- result += dock.usedTabBars();
- }
- return result;
-}
-
-// Returns the set of all used separator widgets
-QSet<QWidget*> QDockAreaLayout::usedSeparatorWidgets() const
-{
- QSet<QWidget*> result;
-
- for (int i = 0; i < separatorWidgets.count(); ++i)
- result << separatorWidgets.at(i);
- for (int i = 0; i < QInternal::DockCount; ++i) {
- const QDockAreaLayoutInfo &dock = docks[i];
- result += dock.usedSeparatorWidgets();
- }
- return result;
-}
-#endif
-
-QRect QDockAreaLayout::gapRect(const QList<int> &path) const
-{
- const QDockAreaLayoutInfo *info = this->info(path);
- if (info == 0)
- return QRect();
- const QList<QDockAreaLayoutItem> &item_list = info->item_list;
- Qt::Orientation o = info->o;
- int index = path.last();
- if (index < 0 || index >= item_list.count())
- return QRect();
- const QDockAreaLayoutItem &item = item_list.at(index);
- if (!(item.flags & QDockAreaLayoutItem::GapItem))
- return QRect();
-
- QRect result;
-
-#ifndef QT_NO_TABBAR
- if (info->tabbed) {
- result = info->tabContentRect();
- } else
-#endif
- {
- int pos = item.pos;
- int size = item.size;
-
- int prev = info->prev(index);
- int next = info->next(index);
-
- if (prev != -1 && !(item_list.at(prev).flags & QDockAreaLayoutItem::GapItem)) {
- pos += sep;
- size -= sep;
- }
- if (next != -1 && !(item_list.at(next).flags & QDockAreaLayoutItem::GapItem))
- size -= sep;
-
- QPoint p;
- rpick(o, p) = pos;
- rperp(o, p) = perp(o, info->rect.topLeft());
- QSize s;
- rpick(o, s) = size;
- rperp(o, s) = perp(o, info->rect.size());
-
- result = QRect(p, s);
- }
-
- return result;
-}
-
-void QDockAreaLayout::keepSize(QDockWidget *w)
-{
- QList<int> path = indexOf(w);
- if (path.isEmpty())
- return;
- QDockAreaLayoutItem &item = this->item(path);
- if (item.size != -1)
- item.flags |= QDockAreaLayoutItem::KeepSize;
-}
-
-void QDockAreaLayout::styleChangedEvent()
-{
- sep = mainWindow->style()->pixelMetric(QStyle::PM_DockWidgetSeparatorExtent, 0, mainWindow);
- fitLayout();
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_DOCKWIDGET
diff --git a/src/gui/widgets/qdockarealayout_p.h b/src/gui/widgets/qdockarealayout_p.h
deleted file mode 100644
index e253eb60ce..0000000000
--- a/src/gui/widgets/qdockarealayout_p.h
+++ /dev/null
@@ -1,308 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDOCKAREALAYOUT_P_H
-#define QDOCKAREALAYOUT_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "QtCore/qrect.h"
-#include "QtCore/qpair.h"
-#include "QtCore/qlist.h"
-#include "QtCore/qvector.h"
-#include "QtGui/qlayout.h"
-
-#ifndef QT_NO_DOCKWIDGET
-
-QT_BEGIN_NAMESPACE
-
-class QLayoutItem;
-class QWidget;
-class QLayoutItem;
-class QDockAreaLayoutInfo;
-class QPlaceHolderItem;
-class QDockWidget;
-class QMainWindow;
-class QWidgetAnimator;
-class QMainWindowLayout;
-struct QLayoutStruct;
-class QTabBar;
-
-// The classes in this file represent the tree structure that represents all the docks
-// Also see the wiki internal documentation
-// At the root of the tree is: QDockAreaLayout, which handles all 4 sides, so there is only one.
-// For each side it has one QDockAreaLayoutInfo child. (See QDockAreaLayout::docks.)
-// The QDockAreaLayoutInfo have QDockAreaLayoutItems as children (See QDockAreaLayoutInfo::item_list),
-// which then has one QDockAreaLayoutInfo as a child. (QDockAreaLayoutItem::subInfo) or
-// a widgetItem if this is a node of the tree (QDockAreaLayoutItem::widgetItem)
-//
-// A path indetifies uniquely one object in this tree, the first number being the side and all the following
-// indexes into the QDockAreaLayoutInfo::item_list.
-
-struct QDockAreaLayoutItem
-{
- enum ItemFlags { NoFlags = 0, GapItem = 1, KeepSize = 2 };
-
- QDockAreaLayoutItem(QLayoutItem *_widgetItem = 0);
- QDockAreaLayoutItem(QDockAreaLayoutInfo *_subinfo);
- QDockAreaLayoutItem(QPlaceHolderItem *_placeHolderItem);
- QDockAreaLayoutItem(const QDockAreaLayoutItem &other);
- ~QDockAreaLayoutItem();
-
- QDockAreaLayoutItem &operator = (const QDockAreaLayoutItem &other);
-
- bool skip() const;
- QSize minimumSize() const;
- QSize maximumSize() const;
- QSize sizeHint() const;
- bool expansive(Qt::Orientation o) const;
- bool hasFixedSize(Qt::Orientation o) const;
-
- QLayoutItem *widgetItem;
- QDockAreaLayoutInfo *subinfo;
- QPlaceHolderItem *placeHolderItem;
- int pos;
- int size;
- uint flags;
-};
-
-class Q_AUTOTEST_EXPORT QPlaceHolderItem
-{
-public:
- QPlaceHolderItem() : hidden(false), window(false) {}
- QPlaceHolderItem(QWidget *w);
-
- QString objectName;
- bool hidden, window;
- QRect topLevelRect;
-};
-
-class Q_AUTOTEST_EXPORT QDockAreaLayoutInfo
-{
-public:
- QDockAreaLayoutInfo();
- QDockAreaLayoutInfo(const int *_sep, QInternal::DockPosition _dockPos, Qt::Orientation _o,
- int tbhape, QMainWindow *window);
-
- QSize minimumSize() const;
- QSize maximumSize() const;
- QSize sizeHint() const;
- QSize size() const;
-
- bool insertGap(const QList<int> &path, QLayoutItem *dockWidgetItem);
- QLayoutItem *plug(const QList<int> &path);
- QLayoutItem *unplug(const QList<int> &path);
- enum TabMode { NoTabs, AllowTabs, ForceTabs };
- QList<int> gapIndex(const QPoint &pos, bool nestingEnabled,
- TabMode tabMode) const;
- void remove(const QList<int> &path);
- void unnest(int index);
- void split(int index, Qt::Orientation orientation, QLayoutItem *dockWidgetItem);
- void tab(int index, QLayoutItem *dockWidgetItem);
- QDockAreaLayoutItem &item(const QList<int> &path);
- QDockAreaLayoutInfo *info(const QList<int> &path);
- QDockAreaLayoutInfo *info(QWidget *widget);
-
- enum { // sentinel values used to validate state data
- SequenceMarker = 0xfc,
- TabMarker = 0xfa,
- WidgetMarker = 0xfb
- };
- void saveState(QDataStream &stream) const;
- bool restoreState(QDataStream &stream, QList<QDockWidget*> &widgets, bool testing);
-
- void fitItems();
- bool expansive(Qt::Orientation o) const;
- int changeSize(int index, int size, bool below);
- QRect itemRect(int index) const;
- QRect itemRect(const QList<int> &path) const;
- QRect separatorRect(int index) const;
- QRect separatorRect(const QList<int> &path) const;
-
- void clear();
- bool isEmpty() const;
- bool hasFixedSize() const;
- QList<int> findSeparator(const QPoint &pos) const;
- int next(int idx) const;
- int prev(int idx) const;
-
- QList<int> indexOf(QWidget *widget) const;
- QList<int> indexOfPlaceHolder(const QString &objectName) const;
-
- void apply(bool animate);
-
- void paintSeparators(QPainter *p, QWidget *widget, const QRegion &clip,
- const QPoint &mouse) const;
- QRegion separatorRegion() const;
- int separatorMove(int index, int delta);
-
- QLayoutItem *itemAt(int *x, int index) const;
- QLayoutItem *takeAt(int *x, int index);
- void deleteAllLayoutItems();
-
- QMainWindowLayout *mainWindowLayout() const;
-
- const int *sep;
- mutable QVector<QWidget*> separatorWidgets;
- QInternal::DockPosition dockPos;
- Qt::Orientation o;
- QRect rect;
- QMainWindow *mainWindow;
- QList<QDockAreaLayoutItem> item_list;
-#ifndef QT_NO_TABBAR
- void updateSeparatorWidgets() const;
- QSet<QWidget*> usedSeparatorWidgets() const;
-#endif //QT_NO_TABBAR
-
-#ifndef QT_NO_TABBAR
- quintptr currentTabId() const;
- void setCurrentTab(QWidget *widget);
- void setCurrentTabId(quintptr id);
- QRect tabContentRect() const;
- bool tabbed;
- QTabBar *tabBar;
- int tabBarShape;
-
- bool updateTabBar() const;
- void setTabBarShape(int shape);
- QSize tabBarMinimumSize() const;
- QSize tabBarSizeHint() const;
-
- QSet<QTabBar*> usedTabBars() const;
-#endif // QT_NO_TABBAR
-};
-
-class Q_AUTOTEST_EXPORT QDockAreaLayout
-{
-public:
- enum { EmptyDropAreaSize = 80 }; // when a dock area is empty, how "wide" is it?
-
- Qt::DockWidgetArea corners[4]; // use a Qt::Corner for indexing
- QRect rect;
- QLayoutItem *centralWidgetItem;
- QMainWindow *mainWindow;
- QRect centralWidgetRect;
- QDockAreaLayout(QMainWindow *win);
- QDockAreaLayoutInfo docks[4];
- int sep; // separator extent
- bool fallbackToSizeHints; //determines if we should use the sizehint for the dock areas (true until the layout is restored or the central widget is set)
- mutable QVector<QWidget*> separatorWidgets;
-
- bool isValid() const;
-
- enum { DockWidgetStateMarker = 0xfd };
- void saveState(QDataStream &stream) const;
- bool restoreState(QDataStream &stream, const QList<QDockWidget*> &widgets, bool testing = false);
-
- QList<int> indexOfPlaceHolder(const QString &objectName) const;
- QList<int> indexOf(QWidget *dockWidget) const;
- QList<int> gapIndex(const QPoint &pos) const;
- QList<int> findSeparator(const QPoint &pos) const;
-
- QDockAreaLayoutItem &item(const QList<int> &path);
- QDockAreaLayoutInfo *info(const QList<int> &path);
- const QDockAreaLayoutInfo *info(const QList<int> &path) const;
- QDockAreaLayoutInfo *info(QWidget *widget);
- QRect itemRect(const QList<int> &path) const;
- QRect separatorRect(int index) const;
- QRect separatorRect(const QList<int> &path) const;
-
- bool insertGap(const QList<int> &path, QLayoutItem *dockWidgetItem);
- QLayoutItem *plug(const QList<int> &path);
- QLayoutItem *unplug(const QList<int> &path);
- void remove(const QList<int> &path);
-
- void fitLayout();
-
- void clear();
-
- QSize sizeHint() const;
- QSize minimumSize() const;
-
- void addDockWidget(QInternal::DockPosition pos, QDockWidget *dockWidget, Qt::Orientation orientation);
- bool restoreDockWidget(QDockWidget *dockWidget);
- void splitDockWidget(QDockWidget *after, QDockWidget *dockWidget,
- Qt::Orientation orientation);
- void tabifyDockWidget(QDockWidget *first, QDockWidget *second);
-
- void apply(bool animate);
-
- void paintSeparators(QPainter *p, QWidget *widget, const QRegion &clip,
- const QPoint &mouse) const;
- QRegion separatorRegion() const;
- int separatorMove(const QList<int> &separator, const QPoint &origin, const QPoint &dest);
-#ifndef QT_NO_TABBAR
- void updateSeparatorWidgets() const;
-#endif //QT_NO_TABBAR
-
- QLayoutItem *itemAt(int *x, int index) const;
- QLayoutItem *takeAt(int *x, int index);
- void deleteAllLayoutItems();
-
- void getGrid(QVector<QLayoutStruct> *ver_struct_list,
- QVector<QLayoutStruct> *hor_struct_list);
- void setGrid(QVector<QLayoutStruct> *ver_struct_list,
- QVector<QLayoutStruct> *hor_struct_list);
-
- QRect gapRect(const QList<int> &path) const;
-
- void keepSize(QDockWidget *w);
-#ifndef QT_NO_TABBAR
- QSet<QTabBar*> usedTabBars() const;
- QSet<QWidget*> usedSeparatorWidgets() const;
-#endif //QT_NO_TABBAR
- void styleChangedEvent();
-};
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_QDOCKWIDGET
-
-#endif // QDOCKAREALAYOUT_P_H
diff --git a/src/gui/widgets/qdockwidget.cpp b/src/gui/widgets/qdockwidget.cpp
deleted file mode 100644
index 6e37683020..0000000000
--- a/src/gui/widgets/qdockwidget.cpp
+++ /dev/null
@@ -1,1605 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qdockwidget.h"
-
-#ifndef QT_NO_DOCKWIDGET
-#include <qaction.h>
-#include <qapplication.h>
-#include <qdesktopwidget.h>
-#include <qdrawutil.h>
-#include <qevent.h>
-#include <qfontmetrics.h>
-#include <qmainwindow.h>
-#include <qrubberband.h>
-#include <qstylepainter.h>
-#include <qtoolbutton.h>
-#include <qdebug.h>
-
-#include <private/qwidgetresizehandler_p.h>
-
-#include "qdockwidget_p.h"
-#include "qmainwindowlayout_p.h"
-#ifdef Q_WS_MAC
-#include <private/qapplication_p.h>
-#include <private/qt_mac_p.h>
-#include <qmacstyle_mac.h>
-#endif
-
-QT_BEGIN_NAMESPACE
-
-extern QString qt_setWindowTitle_helperHelper(const QString&, const QWidget*); // qwidget.cpp
-
-// qmainwindow.cpp
-extern QMainWindowLayout *qt_mainwindow_layout(const QMainWindow *window);
-
-static inline bool hasFeature(const QDockWidgetPrivate *priv, QDockWidget::DockWidgetFeature feature)
-{ return (priv->features & feature) == feature; }
-
-static inline bool hasFeature(const QDockWidget *dockwidget, QDockWidget::DockWidgetFeature feature)
-{ return (dockwidget->features() & feature) == feature; }
-
-
-/*
- A Dock Window:
-
- [+] is the float button
- [X] is the close button
-
- +-------------------------------+
- | Dock Window Title [+][X]|
- +-------------------------------+
- | |
- | place to put the single |
- | QDockWidget child (this space |
- | does not yet have a name) |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- | |
- +-------------------------------+
-
-*/
-
-/******************************************************************************
-** QDockWidgetTitleButton
-*/
-
-class QDockWidgetTitleButton : public QAbstractButton
-{
- Q_OBJECT
-
-public:
- QDockWidgetTitleButton(QDockWidget *dockWidget);
-
- QSize sizeHint() const;
- inline QSize minimumSizeHint() const
- { return sizeHint(); }
-
- void enterEvent(QEvent *event);
- void leaveEvent(QEvent *event);
- void paintEvent(QPaintEvent *event);
-};
-
-
-QDockWidgetTitleButton::QDockWidgetTitleButton(QDockWidget *dockWidget)
- : QAbstractButton(dockWidget)
-{
- setFocusPolicy(Qt::NoFocus);
-}
-
-QSize QDockWidgetTitleButton::sizeHint() const
-{
- ensurePolished();
-
- int size = 2*style()->pixelMetric(QStyle::PM_DockWidgetTitleBarButtonMargin, 0, this);
- if (!icon().isNull()) {
- int iconSize = style()->pixelMetric(QStyle::PM_SmallIconSize, 0, this);
- QSize sz = icon().actualSize(QSize(iconSize, iconSize));
- size += qMax(sz.width(), sz.height());
- }
-
- return QSize(size, size);
-}
-
-void QDockWidgetTitleButton::enterEvent(QEvent *event)
-{
- if (isEnabled()) update();
- QAbstractButton::enterEvent(event);
-}
-
-void QDockWidgetTitleButton::leaveEvent(QEvent *event)
-{
- if (isEnabled()) update();
- QAbstractButton::leaveEvent(event);
-}
-
-void QDockWidgetTitleButton::paintEvent(QPaintEvent *)
-{
- QPainter p(this);
-
- QStyleOptionToolButton opt;
- opt.init(this);
- opt.state |= QStyle::State_AutoRaise;
-
- if (style()->styleHint(QStyle::SH_DockWidget_ButtonsHaveFrame, 0, this))
- {
- if (isEnabled() && underMouse() && !isChecked() && !isDown())
- opt.state |= QStyle::State_Raised;
- if (isChecked())
- opt.state |= QStyle::State_On;
- if (isDown())
- opt.state |= QStyle::State_Sunken;
- style()->drawPrimitive(QStyle::PE_PanelButtonTool, &opt, &p, this);
- }
-
- opt.icon = icon();
- opt.subControls = 0;
- opt.activeSubControls = 0;
- opt.features = QStyleOptionToolButton::None;
- opt.arrowType = Qt::NoArrow;
- int size = style()->pixelMetric(QStyle::PM_SmallIconSize, 0, this);
- opt.iconSize = QSize(size, size);
- style()->drawComplexControl(QStyle::CC_ToolButton, &opt, &p, this);
-}
-
-/******************************************************************************
-** QDockWidgetLayout
-*/
-
-QDockWidgetLayout::QDockWidgetLayout(QWidget *parent)
- : QLayout(parent), verticalTitleBar(false), item_list(RoleCount, 0)
-{
-}
-
-QDockWidgetLayout::~QDockWidgetLayout()
-{
- qDeleteAll(item_list);
-}
-
-bool QDockWidgetLayout::nativeWindowDeco() const
-{
- return nativeWindowDeco(parentWidget()->isWindow());
-}
-
-bool QDockWidgetLayout::nativeWindowDeco(bool floating) const
-{
-#if defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_WS_WINCE)
- Q_UNUSED(floating);
- return false;
-#else
- return floating && item_list[QDockWidgetLayout::TitleBar] == 0;
-#endif
-}
-
-
-void QDockWidgetLayout::addItem(QLayoutItem*)
-{
- qWarning() << "QDockWidgetLayout::addItem(): please use QDockWidgetLayout::setWidget()";
- return;
-}
-
-QLayoutItem *QDockWidgetLayout::itemAt(int index) const
-{
- int cnt = 0;
- for (int i = 0; i < item_list.count(); ++i) {
- QLayoutItem *item = item_list.at(i);
- if (item == 0)
- continue;
- if (index == cnt++)
- return item;
- }
- return 0;
-}
-
-QLayoutItem *QDockWidgetLayout::takeAt(int index)
-{
- int j = 0;
- for (int i = 0; i < item_list.count(); ++i) {
- QLayoutItem *item = item_list.at(i);
- if (item == 0)
- continue;
- if (index == j) {
- item_list[i] = 0;
- invalidate();
- return item;
- }
- ++j;
- }
- return 0;
-}
-
-int QDockWidgetLayout::count() const
-{
- int result = 0;
- for (int i = 0; i < item_list.count(); ++i) {
- if (item_list.at(i))
- ++result;
- }
- return result;
-}
-
-QSize QDockWidgetLayout::sizeFromContent(const QSize &content, bool floating) const
-{
- QSize result = content;
-
- if (verticalTitleBar) {
- result.setHeight(qMax(result.height(), minimumTitleWidth()));
- result.setWidth(qMax(content.width(), 0));
- } else {
- result.setHeight(qMax(result.height(), 0));
- result.setWidth(qMax(content.width(), minimumTitleWidth()));
- }
-
- QDockWidget *w = qobject_cast<QDockWidget*>(parentWidget());
- const bool nativeDeco = nativeWindowDeco(floating);
-
- int fw = floating && !nativeDeco
- ? w->style()->pixelMetric(QStyle::PM_DockWidgetFrameWidth, 0, w)
- : 0;
-
- const int th = titleHeight();
- if (!nativeDeco) {
- if (verticalTitleBar)
- result += QSize(th + 2*fw, 2*fw);
- else
- result += QSize(2*fw, th + 2*fw);
- }
-
- result.setHeight(qMin(result.height(), (int) QWIDGETSIZE_MAX));
- result.setWidth(qMin(result.width(), (int) QWIDGETSIZE_MAX));
-
- if (content.width() < 0)
- result.setWidth(-1);
- if (content.height() < 0)
- result.setHeight(-1);
-
- 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()
- into account if the user set it herself. Otherwise we end up expanding the result
- of a calculation for a non-floating dock widget to a floating dock widget's
- minimum size + window decorations. */
-
- uint explicitMin = 0;
- uint explicitMax = 0;
- if (w->d_func()->extra != 0) {
- explicitMin = w->d_func()->extra->explicitMinSize;
- explicitMax = w->d_func()->extra->explicitMaxSize;
- }
-
- if (!(explicitMin & Qt::Horizontal) || min.width() == 0)
- min.setWidth(-1);
- if (!(explicitMin & Qt::Vertical) || min.height() == 0)
- min.setHeight(-1);
-
- if (!(explicitMax & Qt::Horizontal))
- max.setWidth(QWIDGETSIZE_MAX);
- if (!(explicitMax & Qt::Vertical))
- max.setHeight(QWIDGETSIZE_MAX);
-
- return result.boundedTo(max).expandedTo(min);
-}
-
-QSize QDockWidgetLayout::sizeHint() const
-{
- QDockWidget *w = qobject_cast<QDockWidget*>(parentWidget());
-
- QSize content(-1, -1);
- if (item_list[Content] != 0)
- content = item_list[Content]->sizeHint();
-
- return sizeFromContent(content, w->isFloating());
-}
-
-QSize QDockWidgetLayout::maximumSize() const
-{
- if (item_list[Content] != 0) {
- const QSize content = item_list[Content]->maximumSize();
- return sizeFromContent(content, parentWidget()->isWindow());
- } else {
- return parentWidget()->maximumSize();
- }
-
-}
-
-QSize QDockWidgetLayout::minimumSize() const
-{
- QDockWidget *w = qobject_cast<QDockWidget*>(parentWidget());
-
- QSize content(0, 0);
- if (item_list[Content] != 0)
- content = item_list[Content]->minimumSize();
-
- return sizeFromContent(content, w->isFloating());
-}
-
-QWidget *QDockWidgetLayout::widgetForRole(Role r) const
-{
- QLayoutItem *item = item_list.at(r);
- return item == 0 ? 0 : item->widget();
-}
-
-QLayoutItem *QDockWidgetLayout::itemForRole(Role r) const
-{
- return item_list.at(r);
-}
-
-void QDockWidgetLayout::setWidgetForRole(Role r, QWidget *w)
-{
- QWidget *old = widgetForRole(r);
- if (old != 0) {
- old->hide();
- removeWidget(old);
- }
-
- if (w != 0) {
- addChildWidget(w);
- item_list[r] = new QWidgetItemV2(w);
- w->show();
- } else {
- item_list[r] = 0;
- }
-
- invalidate();
-}
-
-static inline int pick(bool vertical, const QSize &size)
-{
- return vertical ? size.height() : size.width();
-}
-
-static inline int perp(bool vertical, const QSize &size)
-{
- return vertical ? size.width() : size.height();
-}
-
-int QDockWidgetLayout::minimumTitleWidth() const
-{
- QDockWidget *q = qobject_cast<QDockWidget*>(parentWidget());
-
- if (QWidget *title = widgetForRole(TitleBar))
- return pick(verticalTitleBar, title->minimumSizeHint());
-
- QSize closeSize(0, 0);
- QSize floatSize(0, 0);
- 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();
-
- int mw = q->style()->pixelMetric(QStyle::PM_DockWidgetTitleMargin, 0, q);
- int fw = q->style()->pixelMetric(QStyle::PM_DockWidgetFrameWidth, 0, q);
-
- return pick(verticalTitleBar, closeSize)
- + pick(verticalTitleBar, floatSize)
- + titleHeight + 2*fw + 3*mw;
-}
-
-int QDockWidgetLayout::titleHeight() const
-{
- QDockWidget *q = qobject_cast<QDockWidget*>(parentWidget());
-
- if (QWidget *title = widgetForRole(TitleBar))
- return perp(verticalTitleBar, title->sizeHint());
-
- QSize closeSize(0, 0);
- QSize floatSize(0, 0);
- if (QLayoutItem *item = item_list[CloseButton])
- closeSize = item->widget()->sizeHint();
- if (QLayoutItem *item = item_list[FloatButton])
- floatSize = item->widget()->sizeHint();
-
- int buttonHeight = qMax(perp(verticalTitleBar, closeSize),
- perp(verticalTitleBar, floatSize));
-
- QFontMetrics titleFontMetrics = q->fontMetrics();
-#ifdef Q_WS_MAC
- if (qobject_cast<QMacStyle *>(q->style())) {
- //### this breaks on proxy styles. (But is this code still called?)
- QFont font = qt_app_fonts_hash()->value("QToolButton", q->font());
- titleFontMetrics = QFontMetrics(font);
- }
-#endif
-
- int mw = q->style()->pixelMetric(QStyle::PM_DockWidgetTitleMargin, 0, q);
-
- return qMax(buttonHeight + 2, titleFontMetrics.height() + 2*mw);
-}
-
-void QDockWidgetLayout::setGeometry(const QRect &geometry)
-{
- QDockWidget *q = qobject_cast<QDockWidget*>(parentWidget());
-
- bool nativeDeco = nativeWindowDeco();
-
- int fw = q->isFloating() && !nativeDeco
- ? q->style()->pixelMetric(QStyle::PM_DockWidgetFrameWidth, 0, q)
- : 0;
-
- if (nativeDeco) {
- if (QLayoutItem *item = item_list[Content])
- item->setGeometry(geometry);
- } else {
- int titleHeight = this->titleHeight();
-
- if (verticalTitleBar) {
- _titleArea = QRect(QPoint(fw, fw),
- QSize(titleHeight, geometry.height() - (fw * 2)));
- } else {
- _titleArea = QRect(QPoint(fw, fw),
- QSize(geometry.width() - (fw * 2), titleHeight));
- }
-
- if (QLayoutItem *item = item_list[TitleBar]) {
- item->setGeometry(_titleArea);
- } else {
- QStyleOptionDockWidgetV2 opt;
- q->initStyleOption(&opt);
-
- if (QLayoutItem *item = item_list[CloseButton]) {
- if (!item->isEmpty()) {
- QRect r = q->style()
- ->subElementRect(QStyle::SE_DockWidgetCloseButton,
- &opt, q);
- if (!r.isNull())
- item->setGeometry(r);
- }
- }
-
- if (QLayoutItem *item = item_list[FloatButton]) {
- if (!item->isEmpty()) {
- QRect r = q->style()
- ->subElementRect(QStyle::SE_DockWidgetFloatButton,
- &opt, q);
- if (!r.isNull())
- item->setGeometry(r);
- }
- }
- }
-
- if (QLayoutItem *item = item_list[Content]) {
- QRect r = geometry;
- if (verticalTitleBar) {
- r.setLeft(_titleArea.right() + 1);
- r.adjust(0, fw, -fw, -fw);
- } else {
- r.setTop(_titleArea.bottom() + 1);
- r.adjust(fw, 0, -fw, -fw);
- }
- item->setGeometry(r);
- }
- }
-}
-
-void QDockWidgetLayout::setVerticalTitleBar(bool b)
-{
- if (b == verticalTitleBar)
- return;
- verticalTitleBar = b;
- invalidate();
- parentWidget()->update();
-}
-
-/******************************************************************************
-** QDockWidgetItem
-*/
-
-QDockWidgetItem::QDockWidgetItem(QDockWidget *dockWidget)
- : QWidgetItem(dockWidget)
-{
-}
-
-QSize QDockWidgetItem::minimumSize() const
-{
- QSize widgetMin(0, 0);
- if (QLayoutItem *item = dockWidgetChildItem())
- widgetMin = item->minimumSize();
- return dockWidgetLayout()->sizeFromContent(widgetMin, false);
-}
-
-QSize QDockWidgetItem::maximumSize() const
-{
- if (QLayoutItem *item = dockWidgetChildItem()) {
- return dockWidgetLayout()->sizeFromContent(item->maximumSize(), false);
- } else {
- return QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
- }
-}
-
-
-QSize QDockWidgetItem::sizeHint() const
-{
- if (QLayoutItem *item = dockWidgetChildItem()) {
- return dockWidgetLayout()->sizeFromContent(item->sizeHint(), false);
- } else {
- return QWidgetItem::sizeHint();
- }
-}
-
-/******************************************************************************
-** QDockWidgetPrivate
-*/
-
-void QDockWidgetPrivate::init()
-{
- Q_Q(QDockWidget);
-
- QDockWidgetLayout *layout = new QDockWidgetLayout(q);
- layout->setSizeConstraint(QLayout::SetMinAndMaxSize);
-
- QAbstractButton *button = new QDockWidgetTitleButton(q);
- button->setObjectName(QLatin1String("qt_dockwidget_floatbutton"));
- QObject::connect(button, SIGNAL(clicked()), q, SLOT(_q_toggleTopLevel()));
- layout->setWidgetForRole(QDockWidgetLayout::FloatButton, button);
-
- button = new QDockWidgetTitleButton(q);
- button->setObjectName(QLatin1String("qt_dockwidget_closebutton"));
- QObject::connect(button, SIGNAL(clicked()), q, SLOT(close()));
- layout->setWidgetForRole(QDockWidgetLayout::CloseButton, button);
-
- resizer = new QWidgetResizeHandler(q);
- resizer->setMovingEnabled(false);
- resizer->setActive(false);
-
-#ifndef QT_NO_ACTION
- toggleViewAction = new QAction(q);
- toggleViewAction->setCheckable(true);
- fixedWindowTitle = qt_setWindowTitle_helperHelper(q->windowTitle(), q);
- toggleViewAction->setText(fixedWindowTitle);
- QObject::connect(toggleViewAction, SIGNAL(triggered(bool)),
- q, SLOT(_q_toggleView(bool)));
-#endif
-
- updateButtons();
-}
-
-/*!
- Initialize \a option with the values from this QDockWidget. This method
- is useful for subclasses when they need a QStyleOptionDockWidget, but don't want
- to fill in all the information themselves.
-
- \sa QStyleOption::initFrom()
-*/
-void QDockWidget::initStyleOption(QStyleOptionDockWidget *option) const
-{
- Q_D(const QDockWidget);
-
- if (!option)
- return;
- QDockWidgetLayout *dwlayout = qobject_cast<QDockWidgetLayout*>(layout());
-
- option->initFrom(this);
- option->rect = dwlayout->titleArea();
- option->title = d->fixedWindowTitle;
- option->closable = hasFeature(this, QDockWidget::DockWidgetClosable);
- option->movable = hasFeature(this, QDockWidget::DockWidgetMovable);
- option->floatable = hasFeature(this, QDockWidget::DockWidgetFloatable);
-
- QDockWidgetLayout *l = qobject_cast<QDockWidgetLayout*>(layout());
- QStyleOptionDockWidgetV2 *v2
- = qstyleoption_cast<QStyleOptionDockWidgetV2*>(option);
- if (v2 != 0)
- v2->verticalTitleBar = l->verticalTitleBar;
-}
-
-void QDockWidgetPrivate::_q_toggleView(bool b)
-{
- Q_Q(QDockWidget);
- if (b == q->isHidden()) {
- if (b)
- q->show();
- else
- q->close();
- }
-}
-
-void QDockWidgetPrivate::updateButtons()
-{
- Q_Q(QDockWidget);
- QDockWidgetLayout *dwLayout = qobject_cast<QDockWidgetLayout*>(layout);
-
- QStyleOptionDockWidget opt;
- q->initStyleOption(&opt);
-
- bool customTitleBar = dwLayout->widgetForRole(QDockWidgetLayout::TitleBar) != 0;
- bool nativeDeco = dwLayout->nativeWindowDeco();
- bool hideButtons = nativeDeco || customTitleBar;
-
- bool canClose = hasFeature(this, QDockWidget::DockWidgetClosable);
- bool canFloat = hasFeature(this, QDockWidget::DockWidgetFloatable);
-
- QAbstractButton *button
- = qobject_cast<QAbstractButton*>(dwLayout->widgetForRole(QDockWidgetLayout::FloatButton));
- button->setIcon(q->style()->standardIcon(QStyle::SP_TitleBarNormalButton, &opt, q));
- button->setVisible(canFloat && !hideButtons);
-
- button
- = qobject_cast <QAbstractButton*>(dwLayout->widgetForRole(QDockWidgetLayout::CloseButton));
- button->setIcon(q->style()->standardIcon(QStyle::SP_TitleBarCloseButton, &opt, q));
- button->setVisible(canClose && !hideButtons);
-
- q->setAttribute(Qt::WA_ContentsPropagated,
- (canFloat || canClose) && !hideButtons);
-
- layout->invalidate();
-}
-
-void QDockWidgetPrivate::_q_toggleTopLevel()
-{
- Q_Q(QDockWidget);
- q->setFloating(!q->isFloating());
-}
-
-void QDockWidgetPrivate::initDrag(const QPoint &pos, bool nca)
-{
- if (state != 0)
- return;
-
- QMainWindow *win = qobject_cast<QMainWindow*>(parent);
- Q_ASSERT(win != 0);
- QMainWindowLayout *layout = qt_mainwindow_layout(win);
- Q_ASSERT(layout != 0);
- if (layout->pluggingWidget != 0) // the main window is animating a docking operation
- return;
-
- state = new QDockWidgetPrivate::DragState;
- state->pressPos = pos;
- state->dragging = false;
- state->widgetItem = 0;
- state->ownWidgetItem = false;
- state->nca = nca;
- state->ctrlDrag = false;
-}
-
-void QDockWidgetPrivate::startDrag()
-{
- Q_Q(QDockWidget);
-
- if (state == 0 || state->dragging)
- return;
-
- QMainWindowLayout *layout = qt_mainwindow_layout(qobject_cast<QMainWindow *>(q->parentWidget()));
- Q_ASSERT(layout != 0);
-
- state->widgetItem = layout->unplug(q);
- if (state->widgetItem == 0) {
- /* I have a QMainWindow parent, but I was never inserted with
- QMainWindow::addDockWidget, so the QMainWindowLayout has no
- widget item for me. :( I have to create it myself, and then
- delete it if I don't get dropped into a dock area. */
- state->widgetItem = new QDockWidgetItem(q);
- state->ownWidgetItem = true;
- }
-
- if (state->ctrlDrag)
- layout->restore();
-
- state->dragging = true;
-}
-
-void QDockWidgetPrivate::endDrag(bool abort)
-{
- Q_Q(QDockWidget);
- Q_ASSERT(state != 0);
-
- q->releaseMouse();
-
- if (state->dragging) {
- QMainWindowLayout *mwLayout = qt_mainwindow_layout(qobject_cast<QMainWindow *>(q->parentWidget()));
- Q_ASSERT(mwLayout != 0);
-
- if (abort || !mwLayout->plug(state->widgetItem)) {
- if (hasFeature(this, QDockWidget::DockWidgetFloatable)) {
- if (state->ownWidgetItem)
- delete state->widgetItem;
- mwLayout->restore();
-#ifdef Q_WS_X11
- // get rid of the X11BypassWindowManager window flag and activate the resizer
- Qt::WindowFlags flags = q->windowFlags();
- flags &= ~Qt::X11BypassWindowManagerHint;
- q->setWindowFlags(flags);
- resizer->setActive(QWidgetResizeHandler::Resize, true);
- q->show();
-#else
- QDockWidgetLayout *myLayout
- = qobject_cast<QDockWidgetLayout*>(layout);
- resizer->setActive(QWidgetResizeHandler::Resize,
- myLayout->widgetForRole(QDockWidgetLayout::TitleBar) != 0);
-#endif
- undockedGeometry = q->geometry();
- q->activateWindow();
- } else {
- mwLayout->revert(state->widgetItem);
- }
- }
- }
- delete state;
- state = 0;
-}
-
-bool QDockWidgetPrivate::isAnimating() const
-{
- Q_Q(const QDockWidget);
-
- QMainWindow *mainWin = qobject_cast<QMainWindow*>(parent);
- if (mainWin == 0)
- return false;
-
- QMainWindowLayout *mainWinLayout = qt_mainwindow_layout(mainWin);
- if (mainWinLayout == 0)
- return false;
-
- return (void*)mainWinLayout->pluggingWidget == (void*)q;
-}
-
-bool QDockWidgetPrivate::mousePressEvent(QMouseEvent *event)
-{
-#if !defined(QT_NO_MAINWINDOW)
- Q_Q(QDockWidget);
-
- QDockWidgetLayout *dwLayout
- = qobject_cast<QDockWidgetLayout*>(layout);
-
- if (!dwLayout->nativeWindowDeco()) {
- QRect titleArea = dwLayout->titleArea();
-
- if (event->button() != Qt::LeftButton ||
- !titleArea.contains(event->pos()) ||
- // check if the tool window is movable... do nothing if it
- // is not (but allow moving if the window is floating)
- (!hasFeature(this, QDockWidget::DockWidgetMovable) && !q->isFloating()) ||
- qobject_cast<QMainWindow*>(parent) == 0 ||
- isAnimating() || state != 0) {
- return false;
- }
-
- initDrag(event->pos(), false);
-
- if (state)
- state->ctrlDrag = hasFeature(this, QDockWidget::DockWidgetFloatable) && event->modifiers() & Qt::ControlModifier;
-
- return true;
- }
-
-#endif // !defined(QT_NO_MAINWINDOW)
- return false;
-}
-
-bool QDockWidgetPrivate::mouseDoubleClickEvent(QMouseEvent *event)
-{
- QDockWidgetLayout *dwLayout = qobject_cast<QDockWidgetLayout*>(layout);
-
- if (!dwLayout->nativeWindowDeco()) {
- QRect titleArea = dwLayout->titleArea();
-
- if (event->button() == Qt::LeftButton && titleArea.contains(event->pos()) &&
- hasFeature(this, QDockWidget::DockWidgetFloatable)) {
- _q_toggleTopLevel();
- return true;
- }
- }
- return false;
-}
-
-bool QDockWidgetPrivate::mouseMoveEvent(QMouseEvent *event)
-{
- bool ret = false;
-#if !defined(QT_NO_MAINWINDOW)
- Q_Q(QDockWidget);
-
- if (!state)
- return ret;
-
- QDockWidgetLayout *dwlayout
- = qobject_cast<QDockWidgetLayout *>(layout);
- QMainWindowLayout *mwlayout = qt_mainwindow_layout(qobject_cast<QMainWindow *>(q->parentWidget()));
- if (!dwlayout->nativeWindowDeco()) {
- if (!state->dragging
- && mwlayout->pluggingWidget == 0
- && (event->pos() - state->pressPos).manhattanLength()
- > QApplication::startDragDistance()) {
- startDrag();
-#ifdef Q_OS_WIN
- grabMouseWhileInWindow();
-#else
- q->grabMouse();
-#endif
- ret = true;
- }
- }
-
- if (state->dragging && !state->nca) {
- QPoint pos = event->globalPos() - state->pressPos;
- q->move(pos);
-
- if (!state->ctrlDrag)
- mwlayout->hover(state->widgetItem, event->globalPos());
-
- ret = true;
- }
-
-#endif // !defined(QT_NO_MAINWINDOW)
- return ret;
-}
-
-bool QDockWidgetPrivate::mouseReleaseEvent(QMouseEvent *event)
-{
-#if !defined(QT_NO_MAINWINDOW)
-
- if (event->button() == Qt::LeftButton && state && !state->nca) {
- endDrag();
- return true; //filter out the event
- }
-
-#endif // !defined(QT_NO_MAINWINDOW)
- return false;
-}
-
-void QDockWidgetPrivate::nonClientAreaMouseEvent(QMouseEvent *event)
-{
- Q_Q(QDockWidget);
-
- int fw = q->style()->pixelMetric(QStyle::PM_DockWidgetFrameWidth, 0, q);
-
- QRect geo = q->geometry();
- QRect titleRect = q->frameGeometry();
-#ifdef Q_WS_MAC
- if ((features & QDockWidget::DockWidgetVerticalTitleBar)) {
- titleRect.setTop(geo.top());
- titleRect.setBottom(geo.bottom());
- titleRect.setRight(geo.left() - 1);
- } else
-#endif
- {
- titleRect.setLeft(geo.left());
- titleRect.setRight(geo.right());
- titleRect.setBottom(geo.top() - 1);
- titleRect.adjust(0, fw, 0, 0);
- }
-
- switch (event->type()) {
- case QEvent::NonClientAreaMouseButtonPress:
- if (!titleRect.contains(event->globalPos()))
- break;
- if (state != 0)
- break;
- if (qobject_cast<QMainWindow*>(parent) == 0)
- break;
- if (isAnimating())
- break;
- initDrag(event->pos(), true);
- if (state == 0)
- break;
-#ifdef Q_OS_WIN
- // On Windows, NCA mouse events don't contain modifier info
- state->ctrlDrag = GetKeyState(VK_CONTROL) & 0x8000;
-#else
- state->ctrlDrag = event->modifiers() & Qt::ControlModifier;
-#endif
- startDrag();
- break;
- case QEvent::NonClientAreaMouseMove:
- if (state == 0 || !state->dragging)
- break;
- if (state->nca) {
- endDrag();
- }
-#ifdef Q_OS_MAC
- else { // workaround for lack of mouse-grab on Mac
- QMainWindowLayout *layout = qt_mainwindow_layout(qobject_cast<QMainWindow *>(q->parentWidget()));
- Q_ASSERT(layout != 0);
-
- q->move(event->globalPos() - state->pressPos);
- if (!state->ctrlDrag)
- layout->hover(state->widgetItem, event->globalPos());
- }
-#endif
- break;
- case QEvent::NonClientAreaMouseButtonRelease:
-#ifdef Q_OS_MAC
- if (state)
- endDrag();
-#endif
- break;
- case QEvent::NonClientAreaMouseButtonDblClick:
- _q_toggleTopLevel();
- break;
- default:
- break;
- }
-}
-
-void QDockWidgetPrivate::moveEvent(QMoveEvent *event)
-{
- Q_Q(QDockWidget);
-
- if (state == 0 || !state->dragging || !state->nca || !q->isWindow())
- return;
-
- // When the native window frame is being dragged, all we get is these mouse
- // move events.
-
- if (state->ctrlDrag)
- return;
-
- QMainWindowLayout *layout = qt_mainwindow_layout(qobject_cast<QMainWindow *>(q->parentWidget()));
- Q_ASSERT(layout != 0);
-
- QPoint globalMousePos = event->pos() + state->pressPos;
- layout->hover(state->widgetItem, globalMousePos);
-}
-
-void QDockWidgetPrivate::unplug(const QRect &rect)
-{
- Q_Q(QDockWidget);
- QRect r = rect;
- r.moveTopLeft(q->mapToGlobal(QPoint(0, 0)));
- QDockWidgetLayout *dwLayout = qobject_cast<QDockWidgetLayout*>(layout);
- if (dwLayout->nativeWindowDeco(true))
- r.adjust(0, dwLayout->titleHeight(), 0, 0);
- setWindowState(true, true, r);
-}
-
-void QDockWidgetPrivate::plug(const QRect &rect)
-{
- setWindowState(false, false, rect);
-}
-
-void QDockWidgetPrivate::setWindowState(bool floating, bool unplug, const QRect &rect)
-{
- Q_Q(QDockWidget);
-
- if (!floating && parent) {
- QMainWindowLayout *mwlayout = qt_mainwindow_layout(qobject_cast<QMainWindow *>(q->parentWidget()));
- if (mwlayout && mwlayout->dockWidgetArea(q) == Qt::NoDockWidgetArea)
- return; // this dockwidget can't be redocked
- }
-
- bool wasFloating = q->isFloating();
- bool hidden = q->isHidden();
-
- if (q->isVisible())
- q->hide();
-
- Qt::WindowFlags flags = floating ? Qt::Tool : Qt::Widget;
-
- QDockWidgetLayout *dwLayout = qobject_cast<QDockWidgetLayout*>(layout);
- const bool nativeDeco = dwLayout->nativeWindowDeco(floating);
-
- if (nativeDeco) {
- flags |= Qt::CustomizeWindowHint | Qt::WindowTitleHint;
- if (hasFeature(this, QDockWidget::DockWidgetClosable))
- flags |= Qt::WindowCloseButtonHint;
- } else {
- flags |= Qt::FramelessWindowHint;
- }
-
- if (unplug)
- flags |= Qt::X11BypassWindowManagerHint;
-
- q->setWindowFlags(flags);
-
-#if defined(Q_WS_MAC) && !defined(QT_MAC_USE_COCOA)
- if (floating && nativeDeco && (q->features() & QDockWidget::DockWidgetVerticalTitleBar)) {
- ChangeWindowAttributes(HIViewGetWindow(HIViewRef(q->winId())), kWindowSideTitlebarAttribute, 0);
- }
-#endif
-
- if (!rect.isNull())
- q->setGeometry(rect);
-
- updateButtons();
-
- if (!hidden)
- q->show();
-
- if (floating != wasFloating) {
- emit q->topLevelChanged(floating);
- if (!floating && parent) {
- QMainWindowLayout *mwlayout = qt_mainwindow_layout(qobject_cast<QMainWindow *>(q->parentWidget()));
- if (mwlayout)
- emit q->dockLocationChanged(mwlayout->dockWidgetArea(q));
- }
- }
-
- resizer->setActive(QWidgetResizeHandler::Resize, !unplug && floating && !nativeDeco);
-}
-
-/*!
- \class QDockWidget
-
- \brief The QDockWidget class provides a widget that can be docked
- inside a QMainWindow or floated as a top-level window on the
- desktop.
-
- \ingroup mainwindow-classes
-
- QDockWidget provides the concept of dock widgets, also know as
- tool palettes or utility windows. Dock windows are secondary
- windows placed in the \e {dock widget area} around the
- \l{QMainWindow::centralWidget()}{central widget} in a
- QMainWindow.
-
- \image mainwindow-docks.png
-
- Dock windows can be moved inside their current area, moved into
- new areas and floated (e.g., undocked) by the end-user. The
- QDockWidget API allows the programmer to restrict the dock widgets
- ability to move, float and close, as well as the areas in which
- they can be placed.
-
- \section1 Appearance
-
- A QDockWidget consists of a title bar and the content area. The
- title bar displays the dock widgets \link QWidget::windowTitle()
- window title\endlink, a \e float button and a \e close button.
- Depending on the state of the QDockWidget, the \e float and \e
- close buttons may be either disabled or not shown at all.
-
- The visual appearance of the title bar and buttons is dependent
- on the \l{QStyle}{style} in use.
-
- A QDockWidget acts as a wrapper for its child widget, set with setWidget().
- Custom size hints, minimum and maximum sizes and size policies should be
- implemented in the child widget. QDockWidget will respect them, adjusting
- its own constraints to include the frame and title. Size constraints
- should not be set on the QDockWidget itself, because they change depending
- on whether it is docked; a docked QDockWidget has no frame and a smaller title
- bar.
-
- \sa QMainWindow, {Dock Widgets Example}
-*/
-
-/*!
- \enum QDockWidget::DockWidgetFeature
-
- \value DockWidgetClosable The dock widget can be closed. On some systems the dock
- widget always has a close button when it's floating
- (for example on MacOS 10.5).
- \value DockWidgetMovable The dock widget can be moved between docks
- by the user.
- \value DockWidgetFloatable The dock widget can be detached from the
- main window, and floated as an independent
- window.
- \value DockWidgetVerticalTitleBar The dock widget displays a vertical title
- bar on its left side. This can be used to
- increase the amount of vertical space in
- a QMainWindow.
- \value AllDockWidgetFeatures (Deprecated) The dock widget can be closed, moved,
- and floated. Since new features might be added in future
- releases, the look and behavior of dock widgets might
- change if you use this flag. Please specify individual
- flags instead.
- \value NoDockWidgetFeatures The dock widget cannot be closed, moved,
- or floated.
-
- \omitvalue DockWidgetFeatureMask
- \omitvalue Reserved
-*/
-
-/*!
- \property QDockWidget::windowTitle
- \brief the dock widget title (caption)
-
- By default, this property contains an empty string.
-*/
-
-/*!
- Constructs a QDockWidget with parent \a parent and window flags \a
- flags. The dock widget will be placed in the left dock widget
- area.
-*/
-QDockWidget::QDockWidget(QWidget *parent, Qt::WindowFlags flags)
- : QWidget(*new QDockWidgetPrivate, parent, flags)
-{
- Q_D(QDockWidget);
- d->init();
-}
-
-/*!
- Constructs a QDockWidget with parent \a parent and window flags \a
- flags. The dock widget will be placed in the left dock widget
- area.
-
- The window title is set to \a title. This title is used when the
- QDockWidget is docked and undocked. It is also used in the context
- menu provided by QMainWindow.
-
- \sa setWindowTitle()
-*/
-QDockWidget::QDockWidget(const QString &title, QWidget *parent, Qt::WindowFlags flags)
- : QWidget(*new QDockWidgetPrivate, parent, flags)
-{
- Q_D(QDockWidget);
- d->init();
- setWindowTitle(title);
-}
-
-/*!
- Destroys the dock widget.
-*/
-QDockWidget::~QDockWidget()
-{ }
-
-/*!
- Returns the widget for the dock widget. This function returns zero
- if the widget has not been set.
-
- \sa setWidget()
-*/
-QWidget *QDockWidget::widget() const
-{
- QDockWidgetLayout *layout = qobject_cast<QDockWidgetLayout*>(this->layout());
- return layout->widgetForRole(QDockWidgetLayout::Content);
-}
-
-/*!
- Sets the widget for the dock widget to \a widget.
-
- If the dock widget is visible when \a widget is added, you must
- \l{QWidget::}{show()} it explicitly.
-
- Note that you must add the layout of the \a widget before you call
- this function; if not, the \a widget will not be visible.
-
- \sa widget()
-*/
-void QDockWidget::setWidget(QWidget *widget)
-{
- QDockWidgetLayout *layout = qobject_cast<QDockWidgetLayout*>(this->layout());
- layout->setWidgetForRole(QDockWidgetLayout::Content, widget);
-}
-
-/*!
- \property QDockWidget::features
- \brief whether the dock widget is movable, closable, and floatable
-
- By default, this property is set to a combination of DockWidgetClosable,
- DockWidgetMovable and DockWidgetFloatable.
-
- \sa DockWidgetFeature
-*/
-
-void QDockWidget::setFeatures(QDockWidget::DockWidgetFeatures features)
-{
- Q_D(QDockWidget);
- features &= DockWidgetFeatureMask;
- if (d->features == features)
- return;
- const bool closableChanged = (d->features ^ features) & DockWidgetClosable;
- d->features = features;
- QDockWidgetLayout *layout
- = qobject_cast<QDockWidgetLayout*>(this->layout());
- layout->setVerticalTitleBar(features & DockWidgetVerticalTitleBar);
- d->updateButtons();
- d->toggleViewAction->setEnabled((d->features & DockWidgetClosable) == DockWidgetClosable);
- emit featuresChanged(d->features);
- update();
- if (closableChanged && layout->nativeWindowDeco()) {
- //this ensures the native decoration is drawn
- d->setWindowState(true /*floating*/, true /*unplug*/);
- }
-}
-
-QDockWidget::DockWidgetFeatures QDockWidget::features() const
-{
- Q_D(const QDockWidget);
- return d->features;
-}
-
-/*!
- \property QDockWidget::floating
- \brief whether the dock widget is floating
-
- A floating dock widget is presented to the user as an independent
- window "on top" of its parent QMainWindow, instead of being
- docked in the QMainWindow.
-
- By default, this property is true.
-
- \sa isWindow()
-*/
-void QDockWidget::setFloating(bool floating)
-{
- Q_D(QDockWidget);
-
- // the initial click of a double-click may have started a drag...
- if (d->state != 0)
- d->endDrag(true);
-
- QRect r = d->undockedGeometry;
-
- d->setWindowState(floating, false, floating ? r : QRect());
-
- if (floating && r.isNull()) {
- if (x() < 0 || y() < 0) //may happen if we have been hidden
- move(QPoint());
- setAttribute(Qt::WA_Moved, false); //we want it at the default position
- }
-}
-
-/*!
- \property QDockWidget::allowedAreas
- \brief areas where the dock widget may be placed
-
- The default is Qt::AllDockWidgetAreas.
-
- \sa Qt::DockWidgetArea
-*/
-
-void QDockWidget::setAllowedAreas(Qt::DockWidgetAreas areas)
-{
- Q_D(QDockWidget);
- areas &= Qt::DockWidgetArea_Mask;
- if (areas == d->allowedAreas)
- return;
- d->allowedAreas = areas;
- emit allowedAreasChanged(d->allowedAreas);
-}
-
-Qt::DockWidgetAreas QDockWidget::allowedAreas() const
-{
- Q_D(const QDockWidget);
- return d->allowedAreas;
-}
-
-/*!
- \fn bool QDockWidget::isAreaAllowed(Qt::DockWidgetArea area) const
-
- Returns true if this dock widget can be placed in the given \a area;
- otherwise returns false.
-*/
-
-/*! \reimp */
-void QDockWidget::changeEvent(QEvent *event)
-{
- Q_D(QDockWidget);
- QDockWidgetLayout *layout = qobject_cast<QDockWidgetLayout*>(this->layout());
-
- switch (event->type()) {
- case QEvent::ModifiedChange:
- case QEvent::WindowTitleChange:
- update(layout->titleArea());
-#ifndef QT_NO_ACTION
- d->fixedWindowTitle = qt_setWindowTitle_helperHelper(windowTitle(), this);
- d->toggleViewAction->setText(d->fixedWindowTitle);
-#endif
-#ifndef QT_NO_TABBAR
- {
- QMainWindow *win = qobject_cast<QMainWindow*>(parentWidget());
- if (QMainWindowLayout *winLayout = qt_mainwindow_layout(win)) {
- if (QDockAreaLayoutInfo *info = winLayout->layoutState.dockAreaLayout.info(this))
- info->updateTabBar();
- }
- }
-#endif // QT_NO_TABBAR
- break;
- default:
- break;
- }
- QWidget::changeEvent(event);
-}
-
-/*! \reimp */
-void QDockWidget::closeEvent(QCloseEvent *event)
-{
- Q_D(QDockWidget);
- if (d->state)
- d->endDrag(true);
- QWidget::closeEvent(event);
-}
-
-/*! \reimp */
-void QDockWidget::paintEvent(QPaintEvent *event)
-{
- Q_UNUSED(event)
-
- QDockWidgetLayout *layout
- = qobject_cast<QDockWidgetLayout*>(this->layout());
- bool customTitleBar = layout->widgetForRole(QDockWidgetLayout::TitleBar) != 0;
- bool nativeDeco = layout->nativeWindowDeco();
-
- if (!nativeDeco && !customTitleBar) {
- QStylePainter p(this);
- // ### Add PixelMetric to change spacers, so style may show border
- // when not floating.
- if (isFloating()) {
- QStyleOptionFrame framOpt;
- framOpt.init(this);
- p.drawPrimitive(QStyle::PE_FrameDockWidget, framOpt);
- }
-
- // Title must be painted after the frame, since the areas overlap, and
- // the title may wish to extend out to all sides (eg. XP style)
- QStyleOptionDockWidgetV2 titleOpt;
- initStyleOption(&titleOpt);
- p.drawControl(QStyle::CE_DockWidgetTitle, titleOpt);
- }
-}
-
-/*! \reimp */
-bool QDockWidget::event(QEvent *event)
-{
- Q_D(QDockWidget);
-
- QMainWindow *win = qobject_cast<QMainWindow*>(parentWidget());
- QMainWindowLayout *layout = qt_mainwindow_layout(win);
-
- switch (event->type()) {
-#ifndef QT_NO_ACTION
- case QEvent::Hide:
- if (layout != 0)
- layout->keepSize(this);
- d->toggleViewAction->setChecked(false);
- emit visibilityChanged(false);
- break;
- case QEvent::Show:
- d->toggleViewAction->setChecked(true);
- emit visibilityChanged(geometry().right() >= 0 && geometry().bottom() >= 0);
- break;
-#endif
- case QEvent::ApplicationLayoutDirectionChange:
- case QEvent::LayoutDirectionChange:
- case QEvent::StyleChange:
- case QEvent::ParentChange:
- d->updateButtons();
- break;
- case QEvent::ZOrderChange: {
- bool onTop = false;
- if (win != 0) {
- const QObjectList &siblings = win->children();
- onTop = siblings.count() > 0 && siblings.last() == (QObject*)this;
- }
- if (!isFloating() && layout != 0 && onTop)
- layout->raise(this);
- break;
- }
- case QEvent::WindowActivate:
- case QEvent::WindowDeactivate:
- update(qobject_cast<QDockWidgetLayout *>(this->layout())->titleArea());
- break;
- case QEvent::ContextMenu:
- if (d->state) {
- event->accept();
- return true;
- }
- break;
- // return true after calling the handler since we don't want
- // them to be passed onto the default handlers
- case QEvent::MouseButtonPress:
- if (d->mousePressEvent(static_cast<QMouseEvent *>(event)))
- return true;
- break;
- case QEvent::MouseButtonDblClick:
- if (d->mouseDoubleClickEvent(static_cast<QMouseEvent *>(event)))
- return true;
- break;
- case QEvent::MouseMove:
- if (d->mouseMoveEvent(static_cast<QMouseEvent *>(event)))
- return true;
- break;
-#ifdef Q_OS_WIN
- case QEvent::Leave:
- if (d->state != 0 && d->state->dragging && !d->state->nca) {
- // This is a workaround for loosing the mouse on Vista.
- QPoint pos = QCursor::pos();
- QMouseEvent fake(QEvent::MouseMove, mapFromGlobal(pos), pos, Qt::NoButton,
- QApplication::mouseButtons(), QApplication::keyboardModifiers());
- d->mouseMoveEvent(&fake);
- }
- break;
-#endif
- case QEvent::MouseButtonRelease:
- if (d->mouseReleaseEvent(static_cast<QMouseEvent *>(event)))
- return true;
- break;
- case QEvent::NonClientAreaMouseMove:
- case QEvent::NonClientAreaMouseButtonPress:
- case QEvent::NonClientAreaMouseButtonRelease:
- case QEvent::NonClientAreaMouseButtonDblClick:
- d->nonClientAreaMouseEvent(static_cast<QMouseEvent*>(event));
- return true;
- case QEvent::Move:
- d->moveEvent(static_cast<QMoveEvent*>(event));
- break;
- case QEvent::Resize:
- // if the mainwindow is plugging us, we don't want to update undocked geometry
- if (isFloating() && layout != 0 && layout->pluggingWidget != this)
- d->undockedGeometry = geometry();
- break;
- default:
- break;
- }
- return QWidget::event(event);
-}
-
-#ifndef QT_NO_ACTION
-/*!
- Returns a checkable action that can be used to show or close this
- dock widget.
-
- The action's text is set to the dock widget's window title.
-
- \sa QAction::text QWidget::windowTitle
- */
-QAction * QDockWidget::toggleViewAction() const
-{
- Q_D(const QDockWidget);
- return d->toggleViewAction;
-}
-#endif // QT_NO_ACTION
-
-/*!
- \fn void QDockWidget::featuresChanged(QDockWidget::DockWidgetFeatures features)
-
- This signal is emitted when the \l features property changes. The
- \a features parameter gives the new value of the property.
-*/
-
-/*!
- \fn void QDockWidget::topLevelChanged(bool topLevel)
-
- This signal is emitted when the \l floating property changes.
- The \a topLevel parameter is true if the dock widget is now floating;
- otherwise it is false.
-
- \sa isWindow()
-*/
-
-/*!
- \fn void QDockWidget::allowedAreasChanged(Qt::DockWidgetAreas allowedAreas)
-
- This signal is emitted when the \l allowedAreas property changes. The
- \a allowedAreas parameter gives the new value of the property.
-*/
-
-/*!
- \fn void QDockWidget::visibilityChanged(bool visible)
- \since 4.3
-
- This signal is emitted when the dock widget becomes \a visible (or
- invisible). This happens when the widget is hidden or shown, as
- well as when it is docked in a tabbed dock area and its tab
- becomes selected or unselected.
-*/
-
-/*!
- \fn void QDockWidget::dockLocationChanged(Qt::DockWidgetArea area)
- \since 4.3
-
- This signal is emitted when the dock widget is moved to another
- dock \a area, or is moved to a different location in its current
- dock area. This happens when the dock widget is moved
- programmatically or is dragged to a new location by the user.
-*/
-
-/*!
- \since 4.3
-
- Sets an arbitrary \a widget as the dock widget's title bar. If \a widget
- is 0, any custom title bar widget previously set on the dock widget is
- removed, but not deleted, and the default title bar will be used
- instead.
-
- If a title bar widget is set, QDockWidget will not use native window
- decorations when it is floated.
-
- Here are some tips for implementing custom title bars:
-
- \list
- \o Mouse events that are not explicitly handled by the title bar widget
- must be ignored by calling QMouseEvent::ignore(). These events then
- propagate to the QDockWidget parent, which handles them in the usual
- manner, moving when the title bar is dragged, docking and undocking
- when it is double-clicked, etc.
-
- \o When DockWidgetVerticalTitleBar is set on QDockWidget, the title
- bar widget is repositioned accordingly. In resizeEvent(), the title
- bar should check what orientation it should assume:
- \snippet doc/src/snippets/code/src_gui_widgets_qdockwidget.cpp 0
-
- \o The title bar widget must have a valid QWidget::sizeHint() and
- QWidget::minimumSizeHint(). These functions should take into account
- the current orientation of the title bar.
-
- \o It is not possible to remove a title bar from a dock widget. However,
- a similar effect can be achieved by setting a default constructed
- QWidget as the title bar widget.
- \endlist
-
- Using qobject_cast() as shown above, the title bar widget has full access
- to its parent QDockWidget. Hence it can perform such operations as docking
- and hiding in response to user actions.
-
- \sa titleBarWidget() DockWidgetVerticalTitleBar
-*/
-
-void QDockWidget::setTitleBarWidget(QWidget *widget)
-{
- Q_D(QDockWidget);
- QDockWidgetLayout *layout
- = qobject_cast<QDockWidgetLayout*>(this->layout());
- layout->setWidgetForRole(QDockWidgetLayout::TitleBar, widget);
- d->updateButtons();
- if (isWindow()) {
- //this ensures the native decoration is drawn
- d->setWindowState(true /*floating*/, true /*unplug*/);
- }
-}
-
-/*!
- \since 4.3
- Returns the custom title bar widget set on the QDockWidget, or 0 if no
- custom title bar has been set.
-
- \sa setTitleBarWidget()
-*/
-
-QWidget *QDockWidget::titleBarWidget() const
-{
- QDockWidgetLayout *layout
- = qobject_cast<QDockWidgetLayout*>(this->layout());
- return layout->widgetForRole(QDockWidgetLayout::TitleBar);
-}
-
-QT_END_NAMESPACE
-
-#include "qdockwidget.moc"
-#include "moc_qdockwidget.cpp"
-
-#endif // QT_NO_DOCKWIDGET
diff --git a/src/gui/widgets/qdockwidget.h b/src/gui/widgets/qdockwidget.h
deleted file mode 100644
index 58b9f1968b..0000000000
--- a/src/gui/widgets/qdockwidget.h
+++ /dev/null
@@ -1,146 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDYNAMICDOCKWIDGET_H
-#define QDYNAMICDOCKWIDGET_H
-
-#include <QtGui/qwidget.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_DOCKWIDGET
-
-class QDockAreaLayout;
-class QDockWidgetPrivate;
-class QMainWindow;
-class QStyleOptionDockWidget;
-
-class Q_GUI_EXPORT QDockWidget : public QWidget
-{
- Q_OBJECT
-
- Q_FLAGS(DockWidgetFeatures)
- Q_PROPERTY(bool floating READ isFloating WRITE setFloating)
- Q_PROPERTY(DockWidgetFeatures features READ features WRITE setFeatures NOTIFY featuresChanged)
- Q_PROPERTY(Qt::DockWidgetAreas allowedAreas READ allowedAreas
- WRITE setAllowedAreas NOTIFY allowedAreasChanged)
- Q_PROPERTY(QString windowTitle READ windowTitle WRITE setWindowTitle DESIGNABLE true)
-
-public:
- explicit QDockWidget(const QString &title, QWidget *parent = 0, Qt::WindowFlags flags = 0);
- explicit QDockWidget(QWidget *parent = 0, Qt::WindowFlags flags = 0);
- ~QDockWidget();
-
- QWidget *widget() const;
- void setWidget(QWidget *widget);
-
- enum DockWidgetFeature {
- DockWidgetClosable = 0x01,
- DockWidgetMovable = 0x02,
- DockWidgetFloatable = 0x04,
- DockWidgetVerticalTitleBar = 0x08,
-
- DockWidgetFeatureMask = 0x0f,
- AllDockWidgetFeatures = DockWidgetClosable|DockWidgetMovable|DockWidgetFloatable, // ### remove in 5.0
- NoDockWidgetFeatures = 0x00,
-
- Reserved = 0xff
- };
- Q_DECLARE_FLAGS(DockWidgetFeatures, DockWidgetFeature)
-
- void setFeatures(DockWidgetFeatures features);
- DockWidgetFeatures features() const;
-
- void setFloating(bool floating);
- inline bool isFloating() const { return isWindow(); }
-
- void setAllowedAreas(Qt::DockWidgetAreas areas);
- Qt::DockWidgetAreas allowedAreas() const;
-
- void setTitleBarWidget(QWidget *widget);
- QWidget *titleBarWidget() const;
-
- inline bool isAreaAllowed(Qt::DockWidgetArea area) const
- { return (allowedAreas() & area) == area; }
-
-#ifndef QT_NO_ACTION
- QAction *toggleViewAction() const;
-#endif
-
-Q_SIGNALS:
- void featuresChanged(QDockWidget::DockWidgetFeatures features);
- void topLevelChanged(bool topLevel);
- void allowedAreasChanged(Qt::DockWidgetAreas allowedAreas);
- void visibilityChanged(bool visible);
- void dockLocationChanged(Qt::DockWidgetArea area);
-
-protected:
- void changeEvent(QEvent *event);
- void closeEvent(QCloseEvent *event);
- void paintEvent(QPaintEvent *event);
- bool event(QEvent *event);
- void initStyleOption(QStyleOptionDockWidget *option) const;
-
-private:
- Q_DECLARE_PRIVATE(QDockWidget)
- Q_DISABLE_COPY(QDockWidget)
- Q_PRIVATE_SLOT(d_func(), void _q_toggleView(bool))
- Q_PRIVATE_SLOT(d_func(), void _q_toggleTopLevel())
- friend class QDockAreaLayout;
- friend class QDockWidgetItem;
- friend class QMainWindowLayout;
- friend class QDockWidgetLayout;
- friend class QDockAreaLayoutInfo;
-};
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QDockWidget::DockWidgetFeatures)
-
-#endif // QT_NO_DOCKWIDGET
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QDYNAMICDOCKWIDGET_H
diff --git a/src/gui/widgets/qdockwidget_p.h b/src/gui/widgets/qdockwidget_p.h
deleted file mode 100644
index 699c7dd2eb..0000000000
--- a/src/gui/widgets/qdockwidget_p.h
+++ /dev/null
@@ -1,207 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDYNAMICDOCKWIDGET_P_H
-#define QDYNAMICDOCKWIDGET_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "QtGui/qstyleoption.h"
-#include "private/qwidget_p.h"
-#include "QtGui/qboxlayout.h"
-#include "QtGui/qdockwidget.h"
-
-#ifndef QT_NO_DOCKWIDGET
-
-QT_BEGIN_NAMESPACE
-
-class QGridLayout;
-class QWidgetResizeHandler;
-class QRubberBand;
-class QDockWidgetTitleButton;
-class QSpacerItem;
-class QDockWidgetItem;
-
-class QDockWidgetPrivate : public QWidgetPrivate
-{
- Q_DECLARE_PUBLIC(QDockWidget)
-
- struct DragState {
- QPoint pressPos;
- bool dragging;
- QLayoutItem *widgetItem;
- bool ownWidgetItem;
- bool nca;
- bool ctrlDrag;
- };
-
-public:
- inline QDockWidgetPrivate()
- : QWidgetPrivate(), state(0),
- features(QDockWidget::DockWidgetClosable
- | QDockWidget::DockWidgetMovable
- | QDockWidget::DockWidgetFloatable),
- allowedAreas(Qt::AllDockWidgetAreas)
- { }
-
- void init();
- void _q_toggleView(bool); // private slot
- void _q_toggleTopLevel(); // private slot
-
- void updateButtons();
- DragState *state;
-
- QDockWidget::DockWidgetFeatures features;
- Qt::DockWidgetAreas allowedAreas;
-
- QWidgetResizeHandler *resizer;
-
-#ifndef QT_NO_ACTION
- QAction *toggleViewAction;
-#endif
-
-// QMainWindow *findMainWindow(QWidget *widget) const;
- QRect undockedGeometry;
- QString fixedWindowTitle;
-
- bool mousePressEvent(QMouseEvent *event);
- bool mouseDoubleClickEvent(QMouseEvent *event);
- bool mouseMoveEvent(QMouseEvent *event);
- bool mouseReleaseEvent(QMouseEvent *event);
- void setWindowState(bool floating, bool unplug = false, const QRect &rect = QRect());
- void nonClientAreaMouseEvent(QMouseEvent *event);
- void initDrag(const QPoint &pos, bool nca);
- void startDrag();
- void endDrag(bool abort = false);
- void moveEvent(QMoveEvent *event);
-
- void unplug(const QRect &rect);
- void plug(const QRect &rect);
-
- bool isAnimating() const;
-};
-
-class Q_GUI_EXPORT QDockWidgetLayout : public QLayout
-{
- Q_OBJECT
-public:
- QDockWidgetLayout(QWidget *parent = 0);
- ~QDockWidgetLayout();
- void addItem(QLayoutItem *item);
- QLayoutItem *itemAt(int index) const;
- QLayoutItem *takeAt(int index);
- int count() const;
-
- QSize maximumSize() const;
- QSize minimumSize() const;
- QSize sizeHint() const;
-
- QSize sizeFromContent(const QSize &content, bool floating) const;
-
- void setGeometry(const QRect &r);
-
- enum Role { Content, CloseButton, FloatButton, TitleBar, RoleCount };
- QWidget *widgetForRole(Role r) const;
- void setWidgetForRole(Role r, QWidget *w);
- QLayoutItem *itemForRole(Role r) const;
-
- QRect titleArea() const { return _titleArea; }
-
- int minimumTitleWidth() const;
- int titleHeight() const;
- void updateMaxSize();
- bool nativeWindowDeco() const;
- bool nativeWindowDeco(bool floating) const;
-
- void setVerticalTitleBar(bool b);
-
- bool verticalTitleBar;
-
-private:
- QVector<QLayoutItem*> item_list;
- QRect _titleArea;
-};
-
-/* The size hints of a QDockWidget will depend on whether it is docked or not.
- This layout item always returns the size hints as if the dock widget was docked. */
-
-class QDockWidgetItem : public QWidgetItem
-{
-public:
- QDockWidgetItem(QDockWidget *dockWidget);
- QSize minimumSize() const;
- QSize maximumSize() const;
- QSize sizeHint() const;
-
-private:
- inline QLayoutItem *dockWidgetChildItem() const;
- inline QDockWidgetLayout *dockWidgetLayout() const;
-};
-
-inline QLayoutItem *QDockWidgetItem::dockWidgetChildItem() const
-{
- if (QDockWidgetLayout *layout = dockWidgetLayout())
- return layout->itemForRole(QDockWidgetLayout::Content);
- return 0;
-}
-
-inline QDockWidgetLayout *QDockWidgetItem::dockWidgetLayout() const
-{
- QWidget *w = const_cast<QDockWidgetItem*>(this)->widget();
- if (w != 0)
- return qobject_cast<QDockWidgetLayout*>(w->layout());
- return 0;
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_DOCKWIDGET
-
-#endif // QDYNAMICDOCKWIDGET_P_H
diff --git a/src/gui/widgets/qeffects_p.h b/src/gui/widgets/qeffects_p.h
deleted file mode 100644
index 4290fd16ad..0000000000
--- a/src/gui/widgets/qeffects_p.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QEFFECTS_P_H
-#define QEFFECTS_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of qeffects.cpp, qcombobox.cpp, qpopupmenu.cpp and qtooltip.cpp.
-// This header file may change from version to version without notice,
-// or even be removed.
-//
-// We mean it.
-//
-
-#include "QtCore/qnamespace.h"
-
-#ifndef QT_NO_EFFECTS
-
-QT_BEGIN_NAMESPACE
-
-class QWidget;
-
-struct QEffects
-{
- enum Direction {
- LeftScroll = 0x0001,
- RightScroll = 0x0002,
- UpScroll = 0x0004,
- DownScroll = 0x0008
- };
-
- typedef uint DirFlags;
-};
-
-extern void Q_GUI_EXPORT qScrollEffect(QWidget*, QEffects::DirFlags dir = QEffects::DownScroll, int time = -1);
-extern void Q_GUI_EXPORT qFadeEffect(QWidget*, int time = -1);
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_EFFECTS
-
-#endif // QEFFECTS_P_H
diff --git a/src/gui/widgets/qfocusframe.h b/src/gui/widgets/qfocusframe.h
deleted file mode 100644
index 23ea79fe5d..0000000000
--- a/src/gui/widgets/qfocusframe.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QFOCUSFRAME_H
-#define QFOCUSFRAME_H
-
-#include <QtGui/qwidget.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QFocusFramePrivate;
-class QStyleOption;
-
-class Q_GUI_EXPORT QFocusFrame : public QWidget
-{
- Q_OBJECT
-public:
- QFocusFrame(QWidget *parent=0);
- ~QFocusFrame();
-
- void setWidget(QWidget *widget);
- QWidget *widget() const;
-
-protected:
- bool event(QEvent *e);
-
- bool eventFilter(QObject *, QEvent *);
- void paintEvent(QPaintEvent *);
- void initStyleOption(QStyleOption *option) const;
-
-private:
- Q_DECLARE_PRIVATE(QFocusFrame)
- Q_DISABLE_COPY(QFocusFrame)
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QFOCUSFRAME_H
diff --git a/src/gui/widgets/qfontcombobox.h b/src/gui/widgets/qfontcombobox.h
deleted file mode 100644
index e554c7f13e..0000000000
--- a/src/gui/widgets/qfontcombobox.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QFONTCOMBOBOX_H
-#define QFONTCOMBOBOX_H
-
-#include <QtGui/qcombobox.h>
-#include <QtGui/qfontdatabase.h>
-
-#ifndef QT_NO_FONTCOMBOBOX
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QFontComboBoxPrivate;
-
-class Q_GUI_EXPORT QFontComboBox : public QComboBox
-{
- Q_OBJECT
- Q_FLAGS(FontFilters)
- Q_PROPERTY(QFontDatabase::WritingSystem writingSystem READ writingSystem WRITE setWritingSystem)
- Q_PROPERTY(FontFilters fontFilters READ fontFilters WRITE setFontFilters)
- Q_PROPERTY(QFont currentFont READ currentFont WRITE setCurrentFont NOTIFY currentFontChanged)
- Q_ENUMS(FontSelection)
-
-public:
- explicit QFontComboBox(QWidget *parent = 0);
- ~QFontComboBox();
-
- void setWritingSystem(QFontDatabase::WritingSystem);
- QFontDatabase::WritingSystem writingSystem() const;
-
- enum FontFilter {
- AllFonts = 0,
- ScalableFonts = 0x1,
- NonScalableFonts = 0x2,
- MonospacedFonts = 0x4,
- ProportionalFonts = 0x8
- };
- Q_DECLARE_FLAGS(FontFilters, FontFilter)
-
- void setFontFilters(FontFilters filters);
- FontFilters fontFilters() const;
-
- QFont currentFont() const;
- QSize sizeHint() const;
-
-public Q_SLOTS:
- void setCurrentFont(const QFont &f);
-
-Q_SIGNALS:
- void currentFontChanged(const QFont &f);
-
-protected:
- bool event(QEvent *e);
-
-private:
- Q_DISABLE_COPY(QFontComboBox)
- Q_DECLARE_PRIVATE(QFontComboBox)
- Q_PRIVATE_SLOT(d_func(), void _q_currentChanged(const QString &))
- Q_PRIVATE_SLOT(d_func(), void _q_updateModel())
-};
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QFontComboBox::FontFilters)
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QT_NO_FONTCOMBOBOX
-#endif
diff --git a/src/gui/widgets/qframe.h b/src/gui/widgets/qframe.h
deleted file mode 100644
index e35cbce0d3..0000000000
--- a/src/gui/widgets/qframe.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QFRAME_H
-#define QFRAME_H
-
-#include <QtGui/qwidget.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QFramePrivate;
-
-class Q_GUI_EXPORT QFrame : public QWidget
-{
- Q_OBJECT
-
- Q_ENUMS(Shape Shadow)
- Q_PROPERTY(Shape frameShape READ frameShape WRITE setFrameShape)
- Q_PROPERTY(Shadow frameShadow READ frameShadow WRITE setFrameShadow)
- Q_PROPERTY(int lineWidth READ lineWidth WRITE setLineWidth)
- Q_PROPERTY(int midLineWidth READ midLineWidth WRITE setMidLineWidth)
- Q_PROPERTY(int frameWidth READ frameWidth)
- Q_PROPERTY(QRect frameRect READ frameRect WRITE setFrameRect DESIGNABLE false)
-
-public:
- explicit QFrame(QWidget* parent = 0, Qt::WindowFlags f = 0);
- ~QFrame();
-
- int frameStyle() const;
- void setFrameStyle(int);
-
- int frameWidth() const;
-
- QSize sizeHint() const;
-
- enum Shape {
- NoFrame = 0, // no frame
- Box = 0x0001, // rectangular box
- Panel = 0x0002, // rectangular panel
- WinPanel = 0x0003, // rectangular panel (Windows)
- HLine = 0x0004, // horizontal line
- VLine = 0x0005, // vertical line
- StyledPanel = 0x0006 // rectangular panel depending on the GUI style
-
-#if defined(QT3_SUPPORT) && !defined(Q_MOC_RUN)
- ,PopupPanel = StyledPanel, // rectangular panel depending on the GUI style
- MenuBarPanel = StyledPanel,
- ToolBarPanel = StyledPanel,
- LineEditPanel = StyledPanel,
- TabWidgetPanel = StyledPanel,
- GroupBoxPanel = StyledPanel
-#endif
- };
- enum Shadow {
- Plain = 0x0010, // plain line
- Raised = 0x0020, // raised shadow effect
- Sunken = 0x0030 // sunken shadow effect
- };
-
- enum StyleMask {
- Shadow_Mask = 0x00f0, // mask for the shadow
- Shape_Mask = 0x000f // mask for the shape
-#if defined(QT3_SUPPORT)
- ,MShadow = Shadow_Mask,
- MShape = Shape_Mask
-#endif
- };
-
- Shape frameShape() const;
- void setFrameShape(Shape);
- Shadow frameShadow() const;
- void setFrameShadow(Shadow);
-
- int lineWidth() const;
- void setLineWidth(int);
-
- int midLineWidth() const;
- void setMidLineWidth(int);
-
- QRect frameRect() const;
- void setFrameRect(const QRect &);
-
-protected:
- bool event(QEvent *e);
- void paintEvent(QPaintEvent *);
- void changeEvent(QEvent *);
- void drawFrame(QPainter *);
-
-#ifdef QT3_SUPPORT
-public:
- QT3_SUPPORT_CONSTRUCTOR QFrame(QWidget* parent, const char* name, Qt::WindowFlags f = 0);
-#endif
-
-protected:
- QFrame(QFramePrivate &dd, QWidget* parent = 0, Qt::WindowFlags f = 0);
-
-private:
- Q_DISABLE_COPY(QFrame)
- Q_DECLARE_PRIVATE(QFrame)
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QFRAME_H
diff --git a/src/gui/widgets/qgroupbox.h b/src/gui/widgets/qgroupbox.h
deleted file mode 100644
index 311f233cc5..0000000000
--- a/src/gui/widgets/qgroupbox.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGROUPBOX_H
-#define QGROUPBOX_H
-
-#include <QtGui/qframe.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_GROUPBOX
-
-class QGroupBoxPrivate;
-class QStyleOptionGroupBox;
-class Q_GUI_EXPORT QGroupBox : public QWidget
-{
- Q_OBJECT
-
- Q_PROPERTY(QString title READ title WRITE setTitle)
- Q_PROPERTY(Qt::Alignment alignment READ alignment WRITE setAlignment)
- Q_PROPERTY(bool flat READ isFlat WRITE setFlat)
- Q_PROPERTY(bool checkable READ isCheckable WRITE setCheckable)
- Q_PROPERTY(bool checked READ isChecked WRITE setChecked DESIGNABLE isCheckable NOTIFY toggled USER true)
-public:
- explicit QGroupBox(QWidget* parent=0);
- explicit QGroupBox(const QString &title, QWidget* parent=0);
- ~QGroupBox();
-
- QString title() const;
- void setTitle(const QString &title);
-
- Qt::Alignment alignment() const;
- void setAlignment(int alignment);
-
- QSize minimumSizeHint() const;
-
- bool isFlat() const;
- void setFlat(bool flat);
- bool isCheckable() const;
- void setCheckable(bool checkable);
- bool isChecked() const;
-
-public Q_SLOTS:
- void setChecked(bool checked);
-
-Q_SIGNALS:
- void clicked(bool checked = false);
- void toggled(bool);
-
-protected:
- bool event(QEvent *event);
- void childEvent(QChildEvent *event);
- void resizeEvent(QResizeEvent *event);
- void paintEvent(QPaintEvent *event);
- void focusInEvent(QFocusEvent *event);
- void changeEvent(QEvent *event);
- void mousePressEvent(QMouseEvent *event);
- void mouseMoveEvent(QMouseEvent *event);
- void mouseReleaseEvent(QMouseEvent *event);
- void initStyleOption(QStyleOptionGroupBox *option) const;
-
-#ifdef QT3_SUPPORT
-public:
- QT3_SUPPORT_CONSTRUCTOR QGroupBox(QWidget* parent, const char* name);
- QT3_SUPPORT_CONSTRUCTOR QGroupBox(const QString &title, QWidget* parent, const char* name);
-#endif
-
-private:
- Q_DISABLE_COPY(QGroupBox)
- Q_DECLARE_PRIVATE(QGroupBox)
- Q_PRIVATE_SLOT(d_func(), void _q_setChildrenEnabled(bool b))
-};
-
-#endif // QT_NO_GROUPBOX
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QGROUPBOX_H
diff --git a/src/gui/widgets/qlabel.cpp b/src/gui/widgets/qlabel.cpp
deleted file mode 100644
index ab88f38bbb..0000000000
--- a/src/gui/widgets/qlabel.cpp
+++ /dev/null
@@ -1,1734 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qpainter.h"
-#include "qevent.h"
-#include "qdrawutil.h"
-#include "qapplication.h"
-#include "qabstractbutton.h"
-#include "qstyle.h"
-#include "qstyleoption.h"
-#include <limits.h>
-#include "qaction.h"
-#include "qclipboard.h"
-#include <qdebug.h>
-#include <qurl.h>
-#include "qlabel_p.h"
-#include "private/qstylesheetstyle_p.h"
-#include <qmath.h>
-
-#ifndef QT_NO_ACCESSIBILITY
-#include <qaccessible.h>
-#endif
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \class QLabel
- \brief The QLabel widget provides a text or image display.
-
- \ingroup basicwidgets
-
- QLabel is used for displaying text or an image. No user
- interaction functionality is provided. The visual appearance of
- the label can be configured in various ways, and it can be used
- for specifying a focus mnemonic key for another widget.
-
- A QLabel can contain any of the following content types:
-
- \table
- \header \o Content \o Setting
- \row \o Plain text
- \o Pass a QString to setText().
- \row \o Rich text
- \o Pass a QString that contains rich text to setText().
- \row \o A pixmap
- \o Pass a QPixmap to setPixmap().
- \row \o A movie
- \o Pass a QMovie to setMovie().
- \row \o A number
- \o Pass an \e int or a \e double to setNum(), which converts
- the number to plain text.
- \row \o Nothing
- \o The same as an empty plain text. This is the default. Set
- by clear().
- \endtable
-
- \warning When passing a QString to the constructor or calling setText(),
- make sure to sanitize your input, as QLabel tries to guess whether it
- displays the text as plain text or as rich text. You may want to call
- setTextFormat() explicitly, e.g. in case you expect the text to be in
- plain format but cannot control the text source (for instance when
- displaying data loaded from the Web).
-
- When the content is changed using any of these functions, any
- previous content is cleared.
-
- By default, labels display \l{alignment}{left-aligned, vertically-centered}
- text and images, where any tabs in the text to be displayed are
- \l{Qt::TextExpandTabs}{automatically expanded}. However, the look
- of a QLabel can be adjusted and fine-tuned in several ways.
-
- The positioning of the content within the QLabel widget area can
- be tuned with setAlignment() and setIndent(). Text content can
- also wrap lines along word boundaries with setWordWrap(). For
- example, this code sets up a sunken panel with a two-line text in
- the bottom right corner (both lines being flush with the right
- side of the label):
-
- \snippet doc/src/snippets/code/src_gui_widgets_qlabel.cpp 0
-
- The properties and functions QLabel inherits from QFrame can also
- be used to specify the widget frame to be used for any given label.
-
- A QLabel is often used as a label for an interactive widget. For
- this use QLabel provides a useful mechanism for adding an
- mnemonic (see QKeySequence) that will set the keyboard focus to
- the other widget (called the QLabel's "buddy"). For example:
-
- \snippet doc/src/snippets/code/src_gui_widgets_qlabel.cpp 1
-
- In this example, keyboard focus is transferred to the label's
- buddy (the QLineEdit) when the user presses Alt+P. If the buddy
- was a button (inheriting from QAbstractButton), triggering the
- mnemonic would emulate a button click.
-
- \table 100%
- \row
- \o \inlineimage macintosh-label.png Screenshot of a Macintosh style label
- \o A label shown in the \l{Macintosh Style Widget Gallery}{Macintosh widget style}.
- \row
- \o \inlineimage plastique-label.png Screenshot of a Plastique style label
- \o A label shown in the \l{Plastique Style Widget Gallery}{Plastique widget style}.
- \row
- \o \inlineimage windowsxp-label.png Screenshot of a Windows XP style label
- \o A label shown in the \l{Windows XP Style Widget Gallery}{Windows XP widget style}.
- \endtable
-
- \sa QLineEdit, QTextEdit, QPixmap, QMovie,
- {fowler}{GUI Design Handbook: Label}
-*/
-
-#ifndef QT_NO_PICTURE
-/*!
- Returns the label's picture or 0 if the label doesn't have a
- picture.
-*/
-
-const QPicture *QLabel::picture() const
-{
- Q_D(const QLabel);
- return d->picture;
-}
-#endif
-
-
-/*!
- Constructs an empty label.
-
- The \a parent and widget flag \a f, arguments are passed
- to the QFrame constructor.
-
- \sa setAlignment(), setFrameStyle(), setIndent()
-*/
-QLabel::QLabel(QWidget *parent, Qt::WindowFlags f)
- : QFrame(*new QLabelPrivate(), parent, f)
-{
- Q_D(QLabel);
- d->init();
-}
-
-/*!
- Constructs a label that displays the text, \a text.
-
- The \a parent and widget flag \a f, arguments are passed
- to the QFrame constructor.
-
- \sa setText(), setAlignment(), setFrameStyle(), setIndent()
-*/
-QLabel::QLabel(const QString &text, QWidget *parent, Qt::WindowFlags f)
- : QFrame(*new QLabelPrivate(), parent, f)
-{
- Q_D(QLabel);
- d->init();
- setText(text);
-}
-
-
-#ifdef QT3_SUPPORT
-/*! \obsolete
- Constructs an empty label.
-
- The \a parent, \a name and widget flag \a f, arguments are passed
- to the QFrame constructor.
-
- \sa setAlignment(), setFrameStyle(), setIndent()
-*/
-
-QLabel::QLabel(QWidget *parent, const char *name, Qt::WindowFlags f)
- : QFrame(*new QLabelPrivate(), parent, f)
-{
- Q_D(QLabel);
- if (name)
- setObjectName(QString::fromAscii(name));
- d->init();
-}
-
-
-/*! \obsolete
- Constructs a label that displays the text, \a text.
-
- The \a parent, \a name and widget flag \a f, arguments are passed
- to the QFrame constructor.
-
- \sa setText(), setAlignment(), setFrameStyle(), setIndent()
-*/
-
-QLabel::QLabel(const QString &text, QWidget *parent, const char *name,
- Qt::WindowFlags f)
- : QFrame(*new QLabelPrivate(), parent, f)
-{
- Q_D(QLabel);
- if (name)
- setObjectName(QString::fromAscii(name));
- d->init();
- setText(text);
-}
-
-
-/*! \obsolete
- Constructs a label that displays the text \a text. The label has a
- buddy widget, \a buddy.
-
- If the \a text contains an underlined letter (a letter preceded by
- an ampersand, \&), when the user presses Alt+ the underlined letter,
- focus is passed to the buddy widget.
-
- The \a parent, \a name and widget flag, \a f, arguments are passed
- to the QFrame constructor.
-
- \sa setText(), setBuddy(), setAlignment(), setFrameStyle(),
- setIndent()
-*/
-QLabel::QLabel(QWidget *buddy, const QString &text,
- QWidget *parent, const char *name, Qt::WindowFlags f)
- : QFrame(*new QLabelPrivate(), parent, f)
-{
- Q_D(QLabel);
- if (name)
- setObjectName(QString::fromAscii(name));
- d->init();
-#ifndef QT_NO_SHORTCUT
- setBuddy(buddy);
-#endif
- setText(text);
-}
-#endif //QT3_SUPPORT
-
-/*!
- Destroys the label.
-*/
-
-QLabel::~QLabel()
-{
- Q_D(QLabel);
- d->clearContents();
-}
-
-void QLabelPrivate::init()
-{
- Q_Q(QLabel);
-
- valid_hints = false;
- margin = 0;
-#ifndef QT_NO_MOVIE
- movie = 0;
-#endif
-#ifndef QT_NO_SHORTCUT
- shortcutId = 0;
-#endif
- pixmap = 0;
- scaledpixmap = 0;
- cachedimage = 0;
-#ifndef QT_NO_PICTURE
- picture = 0;
-#endif
- align = Qt::AlignLeft | Qt::AlignVCenter | Qt::TextExpandTabs;
- indent = -1;
- scaledcontents = false;
- textLayoutDirty = false;
- textDirty = false;
- textformat = Qt::AutoText;
- control = 0;
- textInteractionFlags = Qt::LinksAccessibleByMouse;
- isRichText = false;
- isTextLabel = false;
-
- q->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred,
- QSizePolicy::Label));
-
-#ifndef QT_NO_CURSOR
- validCursor = false;
- onAnchor = false;
-#endif
-
- openExternalLinks = false;
-
- setLayoutItemMargins(QStyle::SE_LabelLayoutItem);
-}
-
-
-/*!
- \property QLabel::text
- \brief the label's text
-
- If no text has been set this will return an empty string. Setting
- the text clears any previous content.
-
- The text will be interpreted either as plain text or as rich
- text, depending on the text format setting; see setTextFormat().
- The default setting is Qt::AutoText; i.e. QLabel will try to
- auto-detect the format of the text set.
-
- If a buddy has been set, the buddy mnemonic key is updated
- from the new text.
-
- Note that QLabel is well-suited to display small rich text
- documents, such as small documents that get their document
- specific settings (font, text color, link color) from the label's
- palette and font properties. For large documents, use QTextEdit
- in read-only mode instead. QTextEdit can also provide a scroll bar
- when necessary.
-
- \note This function enables mouse tracking if \a text contains rich
- text.
-
- \sa setTextFormat(), setBuddy(), alignment
-*/
-
-void QLabel::setText(const QString &text)
-{
- Q_D(QLabel);
- if (d->text == text)
- return;
-
- QTextControl *oldControl = d->control;
- d->control = 0;
-
- d->clearContents();
- d->text = text;
- d->isTextLabel = true;
- d->textDirty = true;
- d->isRichText = d->textformat == Qt::RichText
- || (d->textformat == Qt::AutoText && Qt::mightBeRichText(d->text));
-
- d->control = oldControl;
-
- if (d->needTextControl()) {
- d->ensureTextControl();
- } else {
- delete d->control;
- d->control = 0;
- }
-
- if (d->isRichText) {
- setMouseTracking(true);
- } else {
- // Note: mouse tracking not disabled intentionally
- }
-
-#ifndef QT_NO_SHORTCUT
- if (d->buddy)
- d->updateShortcut();
-#endif
-
- d->updateLabel();
-
-#ifndef QT_NO_ACCESSIBILITY
- if (accessibleName().isEmpty())
- QAccessible::updateAccessibility(this, 0, QAccessible::NameChanged);
-#endif
-}
-
-QString QLabel::text() const
-{
- Q_D(const QLabel);
- return d->text;
-}
-
-/*!
- Clears any label contents.
-*/
-
-void QLabel::clear()
-{
- Q_D(QLabel);
- d->clearContents();
- d->updateLabel();
-}
-
-/*!
- \property QLabel::pixmap
- \brief the label's pixmap
-
- If no pixmap has been set this will return 0.
-
- Setting the pixmap clears any previous content. The buddy
- shortcut, if any, is disabled.
-*/
-void QLabel::setPixmap(const QPixmap &pixmap)
-{
- Q_D(QLabel);
- if (!d->pixmap || d->pixmap->cacheKey() != pixmap.cacheKey()) {
- d->clearContents();
- d->pixmap = new QPixmap(pixmap);
- }
-
- if (d->pixmap->depth() == 1 && !d->pixmap->mask())
- d->pixmap->setMask(*((QBitmap *)d->pixmap));
-
- d->updateLabel();
-}
-
-const QPixmap *QLabel::pixmap() const
-{
- Q_D(const QLabel);
- return d->pixmap;
-}
-
-#ifndef QT_NO_PICTURE
-/*!
- Sets the label contents to \a picture. Any previous content is
- cleared.
-
- The buddy shortcut, if any, is disabled.
-
- \sa picture(), setBuddy()
-*/
-
-void QLabel::setPicture(const QPicture &picture)
-{
- Q_D(QLabel);
- d->clearContents();
- d->picture = new QPicture(picture);
-
- d->updateLabel();
-}
-#endif // QT_NO_PICTURE
-
-/*!
- Sets the label contents to plain text containing the textual
- representation of integer \a num. Any previous content is cleared.
- Does nothing if the integer's string representation is the same as
- the current contents of the label.
-
- The buddy shortcut, if any, is disabled.
-
- \sa setText(), QString::setNum(), setBuddy()
-*/
-
-void QLabel::setNum(int num)
-{
- QString str;
- str.setNum(num);
- setText(str);
-}
-
-/*!
- \overload
-
- Sets the label contents to plain text containing the textual
- representation of double \a num. Any previous content is cleared.
- Does nothing if the double's string representation is the same as
- the current contents of the label.
-
- The buddy shortcut, if any, is disabled.
-
- \sa setText(), QString::setNum(), setBuddy()
-*/
-
-void QLabel::setNum(double num)
-{
- QString str;
- str.setNum(num);
- setText(str);
-}
-
-/*!
- \property QLabel::alignment
- \brief the alignment of the label's contents
-
- By default, the contents of the label are left-aligned and vertically-centered.
-
- \sa text
-*/
-
-void QLabel::setAlignment(Qt::Alignment alignment)
-{
- Q_D(QLabel);
- if (alignment == (d->align & (Qt::AlignVertical_Mask|Qt::AlignHorizontal_Mask)))
- return;
- d->align = (d->align & ~(Qt::AlignVertical_Mask|Qt::AlignHorizontal_Mask))
- | (alignment & (Qt::AlignVertical_Mask|Qt::AlignHorizontal_Mask));
-
- d->updateLabel();
-}
-
-#ifdef QT3_SUPPORT
-/*!
- Use setAlignment(Qt::Alignment) instead.
-
- If \a alignment specifies text flags as well, use setTextFormat()
- to set those.
-*/
-void QLabel::setAlignment(int alignment)
-{
- Q_D(QLabel);
- d->align = alignment & ~(Qt::AlignVertical_Mask|Qt::AlignHorizontal_Mask|Qt::TextWordWrap);
- setAlignment(Qt::Alignment(QFlag(alignment)));
-}
-#endif
-
-Qt::Alignment QLabel::alignment() const
-{
- Q_D(const QLabel);
- return QFlag(d->align & (Qt::AlignVertical_Mask|Qt::AlignHorizontal_Mask));
-}
-
-
-/*!
- \property QLabel::wordWrap
- \brief the label's word-wrapping policy
-
- If this property is true then label text is wrapped where
- necessary at word-breaks; otherwise it is not wrapped at all.
-
- By default, word wrap is disabled.
-
- \sa text
-*/
-void QLabel::setWordWrap(bool on)
-{
- Q_D(QLabel);
- if (on)
- d->align |= Qt::TextWordWrap;
- else
- d->align &= ~Qt::TextWordWrap;
-
- d->updateLabel();
-}
-
-bool QLabel::wordWrap() const
-{
- Q_D(const QLabel);
- return d->align & Qt::TextWordWrap;
-}
-
-/*!
- \property QLabel::indent
- \brief the label's text indent in pixels
-
- If a label displays text, the indent applies to the left edge if
- alignment() is Qt::AlignLeft, to the right edge if alignment() is
- Qt::AlignRight, to the top edge if alignment() is Qt::AlignTop, and
- to to the bottom edge if alignment() is Qt::AlignBottom.
-
- If indent is negative, or if no indent has been set, the label
- computes the effective indent as follows: If frameWidth() is 0,
- the effective indent becomes 0. If frameWidth() is greater than 0,
- the effective indent becomes half the width of the "x" character
- of the widget's current font().
-
- By default, the indent is -1, meaning that an effective indent is
- calculating in the manner described above.
-
- \sa alignment, margin, frameWidth(), font()
-*/
-
-void QLabel::setIndent(int indent)
-{
- Q_D(QLabel);
- d->indent = indent;
- d->updateLabel();
-}
-
-int QLabel::indent() const
-{
- Q_D(const QLabel);
- return d->indent;
-}
-
-
-/*!
- \property QLabel::margin
- \brief the width of the margin
-
- The margin is the distance between the innermost pixel of the
- frame and the outermost pixel of contents.
-
- The default margin is 0.
-
- \sa indent
-*/
-int QLabel::margin() const
-{
- Q_D(const QLabel);
- return d->margin;
-}
-
-void QLabel::setMargin(int margin)
-{
- Q_D(QLabel);
- if (d->margin == margin)
- return;
- d->margin = margin;
- d->updateLabel();
-}
-
-/*!
- Returns the size that will be used if the width of the label is \a
- w. If \a w is -1, the sizeHint() is returned. If \a w is 0 minimumSizeHint() is returned
-*/
-QSize QLabelPrivate::sizeForWidth(int w) const
-{
- Q_Q(const QLabel);
- if(q->minimumWidth() > 0)
- w = qMax(w, q->minimumWidth());
- QSize contentsMargin(leftmargin + rightmargin, topmargin + bottommargin);
-
- QRect br;
-
- int hextra = 2 * margin;
- int vextra = hextra;
- QFontMetrics fm = q->fontMetrics();
-
- if (pixmap && !pixmap->isNull())
- br = pixmap->rect();
-#ifndef QT_NO_PICTURE
- else if (picture && !picture->isNull())
- br = picture->boundingRect();
-#endif
-#ifndef QT_NO_MOVIE
- else if (movie && !movie->currentPixmap().isNull())
- br = movie->currentPixmap().rect();
-#endif
- else if (isTextLabel) {
- int align = QStyle::visualAlignment(textDirection(), QFlag(this->align));
- // Add indentation
- int m = indent;
-
- if (m < 0 && q->frameWidth()) // no indent, but we do have a frame
- m = fm.width(QLatin1Char('x')) - margin*2;
- if (m > 0) {
- if ((align & Qt::AlignLeft) || (align & Qt::AlignRight))
- hextra += m;
- if ((align & Qt::AlignTop) || (align & Qt::AlignBottom))
- vextra += m;
- }
-
- if (control) {
- ensureTextLayouted();
- const qreal oldTextWidth = control->textWidth();
- // Calculate the length of document if w is the width
- if (align & Qt::TextWordWrap) {
- if (w >= 0) {
- w = qMax(w-hextra-contentsMargin.width(), 0); // strip margin and indent
- control->setTextWidth(w);
- } else {
- control->adjustSize();
- }
- } else {
- control->setTextWidth(-1);
- }
-
- QSizeF controlSize = control->size();
- br = QRect(QPoint(0, 0), QSize(qCeil(controlSize.width()), qCeil(controlSize.height())));
-
- // restore state
- control->setTextWidth(oldTextWidth);
- } else {
- // Turn off center alignment in order to avoid rounding errors for centering,
- // since centering involves a division by 2. At the end, all we want is the size.
- int flags = align & ~(Qt::AlignVCenter | Qt::AlignHCenter);
- if (hasShortcut) {
- flags |= Qt::TextShowMnemonic;
- QStyleOption opt;
- opt.initFrom(q);
- if (!q->style()->styleHint(QStyle::SH_UnderlineShortcut, &opt, q))
- flags |= Qt::TextHideMnemonic;
- }
-
- bool tryWidth = (w < 0) && (align & Qt::TextWordWrap);
- if (tryWidth)
- w = qMin(fm.averageCharWidth() * 80, q->maximumSize().width());
- else if (w < 0)
- w = 2000;
- w -= (hextra + contentsMargin.width());
- br = fm.boundingRect(0, 0, w ,2000, flags, text);
- if (tryWidth && br.height() < 4*fm.lineSpacing() && br.width() > w/2)
- br = fm.boundingRect(0, 0, w/2, 2000, flags, text);
- if (tryWidth && br.height() < 2*fm.lineSpacing() && br.width() > w/4)
- br = fm.boundingRect(0, 0, w/4, 2000, flags, text);
- }
- } else {
- br = QRect(QPoint(0, 0), QSize(fm.averageCharWidth(), fm.lineSpacing()));
- }
-
- const QSize contentsSize(br.width() + hextra, br.height() + vextra);
- return (contentsSize + contentsMargin).expandedTo(q->minimumSize());
-}
-
-
-/*!
- \reimp
-*/
-
-int QLabel::heightForWidth(int w) const
-{
- Q_D(const QLabel);
- if (d->isTextLabel)
- return d->sizeForWidth(w).height();
- return QWidget::heightForWidth(w);
-}
-
-/*!
- \property QLabel::openExternalLinks
- \since 4.2
-
- Specifies whether QLabel should automatically open links using
- QDesktopServices::openUrl() instead of emitting the
- linkActivated() signal.
-
- \bold{Note:} The textInteractionFlags set on the label need to include
- either LinksAccessibleByMouse or LinksAccessibleByKeyboard.
-
- The default value is false.
-
- \sa textInteractionFlags()
-*/
-bool QLabel::openExternalLinks() const
-{
- Q_D(const QLabel);
- return d->openExternalLinks;
-}
-
-void QLabel::setOpenExternalLinks(bool open)
-{
- Q_D(QLabel);
- d->openExternalLinks = open;
- if (d->control)
- d->control->setOpenExternalLinks(open);
-}
-
-/*!
- \property QLabel::textInteractionFlags
- \since 4.2
-
- Specifies how the label should interact with user input if it displays text.
-
- If the flags contain Qt::LinksAccessibleByKeyboard the focus policy is also
- automatically set to Qt::StrongFocus. If Qt::TextSelectableByKeyboard is set
- then the focus policy is set to Qt::ClickFocus.
-
- The default value is Qt::LinksAccessibleByMouse.
-*/
-void QLabel::setTextInteractionFlags(Qt::TextInteractionFlags flags)
-{
- Q_D(QLabel);
- if (d->textInteractionFlags == flags)
- return;
- d->textInteractionFlags = flags;
- if (flags & Qt::LinksAccessibleByKeyboard)
- setFocusPolicy(Qt::StrongFocus);
- else if (flags & (Qt::TextSelectableByKeyboard | Qt::TextSelectableByMouse))
- setFocusPolicy(Qt::ClickFocus);
- else
- setFocusPolicy(Qt::NoFocus);
-
- if (d->needTextControl()) {
- d->ensureTextControl();
- } else {
- delete d->control;
- d->control = 0;
- }
-
- if (d->control)
- d->control->setTextInteractionFlags(d->textInteractionFlags);
-}
-
-Qt::TextInteractionFlags QLabel::textInteractionFlags() const
-{
- Q_D(const QLabel);
- return d->textInteractionFlags;
-}
-
-/*!
- Selects text from position \a start and for \a length characters.
-
- \sa selectedText()
-
- \bold{Note:} The textInteractionFlags set on the label need to include
- either TextSelectableByMouse or TextSelectableByKeyboard.
-
- \since 4.7
-*/
-void QLabel::setSelection(int start, int length)
-{
- Q_D(QLabel);
- if (d->control) {
- d->ensureTextPopulated();
- QTextCursor cursor = d->control->textCursor();
- cursor.setPosition(start);
- cursor.setPosition(start + length, QTextCursor::KeepAnchor);
- d->control->setTextCursor(cursor);
- }
-}
-
-/*!
- \property QLabel::hasSelectedText
- \brief whether there is any text selected
-
- hasSelectedText() returns true if some or all of the text has been
- selected by the user; otherwise returns false.
-
- By default, this property is false.
-
- \sa selectedText()
-
- \bold{Note:} The textInteractionFlags set on the label need to include
- either TextSelectableByMouse or TextSelectableByKeyboard.
-
- \since 4.7
-*/
-bool QLabel::hasSelectedText() const
-{
- Q_D(const QLabel);
- if (d->control)
- return d->control->textCursor().hasSelection();
- return false;
-}
-
-/*!
- \property QLabel::selectedText
- \brief the selected text
-
- If there is no selected text this property's value is
- an empty string.
-
- By default, this property contains an empty string.
-
- \sa hasSelectedText()
-
- \bold{Note:} The textInteractionFlags set on the label need to include
- either TextSelectableByMouse or TextSelectableByKeyboard.
-
- \since 4.7
-*/
-QString QLabel::selectedText() const
-{
- Q_D(const QLabel);
- if (d->control)
- return d->control->textCursor().selectedText();
- return QString();
-}
-
-/*!
- selectionStart() returns the index of the first selected character in the
- label or -1 if no text is selected.
-
- \sa selectedText()
-
- \bold{Note:} The textInteractionFlags set on the label need to include
- either TextSelectableByMouse or TextSelectableByKeyboard.
-
- \since 4.7
-*/
-int QLabel::selectionStart() const
-{
- Q_D(const QLabel);
- if (d->control && d->control->textCursor().hasSelection())
- return d->control->textCursor().selectionStart();
- return -1;
-}
-
-/*!\reimp
-*/
-QSize QLabel::sizeHint() const
-{
- Q_D(const QLabel);
- if (!d->valid_hints)
- (void) QLabel::minimumSizeHint();
- return d->sh;
-}
-
-/*!
- \reimp
-*/
-QSize QLabel::minimumSizeHint() const
-{
- Q_D(const QLabel);
- if (d->valid_hints) {
- if (d->sizePolicy == sizePolicy())
- return d->msh;
- }
-
- ensurePolished();
- d->valid_hints = true;
- d->sh = d->sizeForWidth(-1); // wrap ? golden ratio : min doc size
- QSize msh(-1, -1);
-
- if (!d->isTextLabel) {
- msh = d->sh;
- } else {
- msh.rheight() = d->sizeForWidth(QWIDGETSIZE_MAX).height(); // height for one line
- msh.rwidth() = d->sizeForWidth(0).width(); // wrap ? size of biggest word : min doc size
- if (d->sh.height() < msh.height())
- msh.rheight() = d->sh.height();
- }
- d->msh = msh;
- d->sizePolicy = sizePolicy();
- return msh;
-}
-
-/*!\reimp
-*/
-void QLabel::mousePressEvent(QMouseEvent *ev)
-{
- Q_D(QLabel);
- d->sendControlEvent(ev);
-}
-
-/*!\reimp
-*/
-void QLabel::mouseMoveEvent(QMouseEvent *ev)
-{
- Q_D(QLabel);
- d->sendControlEvent(ev);
-}
-
-/*!\reimp
-*/
-void QLabel::mouseReleaseEvent(QMouseEvent *ev)
-{
- Q_D(QLabel);
- d->sendControlEvent(ev);
-}
-
-/*!\reimp
-*/
-void QLabel::contextMenuEvent(QContextMenuEvent *ev)
-{
-#ifdef QT_NO_CONTEXTMENU
- Q_UNUSED(ev);
-#else
- Q_D(QLabel);
- if (!d->isTextLabel) {
- ev->ignore();
- return;
- }
- QMenu *menu = d->createStandardContextMenu(ev->pos());
- if (!menu) {
- ev->ignore();
- return;
- }
- ev->accept();
- menu->setAttribute(Qt::WA_DeleteOnClose);
- menu->popup(ev->globalPos());
-#endif
-}
-
-/*!
- \reimp
-*/
-void QLabel::focusInEvent(QFocusEvent *ev)
-{
- Q_D(QLabel);
- if (d->isTextLabel) {
- d->ensureTextControl();
- d->sendControlEvent(ev);
- }
- QFrame::focusInEvent(ev);
-}
-
-/*!
- \reimp
-*/
-void QLabel::focusOutEvent(QFocusEvent *ev)
-{
- Q_D(QLabel);
- if (d->control) {
- d->sendControlEvent(ev);
- QTextCursor cursor = d->control->textCursor();
- Qt::FocusReason reason = ev->reason();
- if (reason != Qt::ActiveWindowFocusReason
- && reason != Qt::PopupFocusReason
- && cursor.hasSelection()) {
- cursor.clearSelection();
- d->control->setTextCursor(cursor);
- }
- }
-
- QFrame::focusOutEvent(ev);
-}
-
-/*!\reimp
-*/
-bool QLabel::focusNextPrevChild(bool next)
-{
- Q_D(QLabel);
- if (d->control && d->control->setFocusToNextOrPreviousAnchor(next))
- return true;
- return QFrame::focusNextPrevChild(next);
-}
-
-/*!\reimp
-*/
-void QLabel::keyPressEvent(QKeyEvent *ev)
-{
- Q_D(QLabel);
- d->sendControlEvent(ev);
-}
-
-/*!\reimp
-*/
-bool QLabel::event(QEvent *e)
-{
- Q_D(QLabel);
- QEvent::Type type = e->type();
-
-#ifndef QT_NO_SHORTCUT
- if (type == QEvent::Shortcut) {
- QShortcutEvent *se = static_cast<QShortcutEvent *>(e);
- if (se->shortcutId() == d->shortcutId) {
- QWidget * w = d->buddy;
- QAbstractButton *button = qobject_cast<QAbstractButton *>(w);
- if (w->focusPolicy() != Qt::NoFocus)
- w->setFocus(Qt::ShortcutFocusReason);
- if (button && !se->isAmbiguous())
- button->animateClick();
- else
- window()->setAttribute(Qt::WA_KeyboardFocusChange);
- return true;
- }
- } else
-#endif
- if (type == QEvent::Resize) {
- if (d->control)
- d->textLayoutDirty = true;
- } else if (e->type() == QEvent::StyleChange
-#ifdef Q_WS_MAC
- || e->type() == QEvent::MacSizeChange
-#endif
- ) {
- d->setLayoutItemMargins(QStyle::SE_LabelLayoutItem);
- d->updateLabel();
- }
-
- return QFrame::event(e);
-}
-
-/*!\reimp
-*/
-void QLabel::paintEvent(QPaintEvent *)
-{
- Q_D(QLabel);
- QStyle *style = QWidget::style();
- QPainter painter(this);
- drawFrame(&painter);
- QRect cr = contentsRect();
- cr.adjust(d->margin, d->margin, -d->margin, -d->margin);
- int align = QStyle::visualAlignment(d->isTextLabel ? d->textDirection()
- : layoutDirection(), QFlag(d->align));
-
-#ifndef QT_NO_MOVIE
- if (d->movie) {
- if (d->scaledcontents)
- style->drawItemPixmap(&painter, cr, align, d->movie->currentPixmap().scaled(cr.size()));
- else
- style->drawItemPixmap(&painter, cr, align, d->movie->currentPixmap());
- }
- else
-#endif
- if (d->isTextLabel) {
- QRectF lr = d->layoutRect().toAlignedRect();
- QStyleOption opt;
- opt.initFrom(this);
-#ifndef QT_NO_STYLE_STYLESHEET
- if (QStyleSheetStyle* cssStyle = qobject_cast<QStyleSheetStyle*>(style)) {
- cssStyle->styleSheetPalette(this, &opt, &opt.palette);
- }
-#endif
- if (d->control) {
-#ifndef QT_NO_SHORTCUT
- const bool underline = (bool)style->styleHint(QStyle::SH_UnderlineShortcut, 0, this, 0);
- if (d->shortcutId != 0
- && underline != d->shortcutCursor.charFormat().fontUnderline()) {
- QTextCharFormat fmt;
- fmt.setFontUnderline(underline);
- d->shortcutCursor.mergeCharFormat(fmt);
- }
-#endif
- d->ensureTextLayouted();
-
- QAbstractTextDocumentLayout::PaintContext context;
- if (!isEnabled() && !d->control &&
- // We cannot support etched for rich text controls because custom
- // colors and links will override the light palette
- style->styleHint(QStyle::SH_EtchDisabledText, &opt, this)) {
- context.palette = opt.palette;
- context.palette.setColor(QPalette::Text, context.palette.light().color());
- painter.save();
- painter.translate(lr.x() + 1, lr.y() + 1);
- painter.setClipRect(lr.translated(-lr.x() - 1, -lr.y() - 1));
- QAbstractTextDocumentLayout *layout = d->control->document()->documentLayout();
- layout->draw(&painter, context);
- painter.restore();
- }
-
- // Adjust the palette
- context.palette = opt.palette;
-
- if (foregroundRole() != QPalette::Text && isEnabled())
- context.palette.setColor(QPalette::Text, context.palette.color(foregroundRole()));
-
- painter.save();
- painter.translate(lr.topLeft());
- painter.setClipRect(lr.translated(-lr.x(), -lr.y()));
- d->control->setPalette(context.palette);
- d->control->drawContents(&painter, QRectF(), this);
- painter.restore();
- } else {
- int flags = align | (d->textDirection() == Qt::LeftToRight ? Qt::TextForceLeftToRight
- : Qt::TextForceRightToLeft);
- if (d->hasShortcut) {
- flags |= Qt::TextShowMnemonic;
- if (!style->styleHint(QStyle::SH_UnderlineShortcut, &opt, this))
- flags |= Qt::TextHideMnemonic;
- }
- style->drawItemText(&painter, lr.toRect(), flags, opt.palette, isEnabled(), d->text, foregroundRole());
- }
- } else
-#ifndef QT_NO_PICTURE
- if (d->picture) {
- QRect br = d->picture->boundingRect();
- int rw = br.width();
- int rh = br.height();
- if (d->scaledcontents) {
- painter.save();
- painter.translate(cr.x(), cr.y());
- painter.scale((double)cr.width()/rw, (double)cr.height()/rh);
- painter.drawPicture(-br.x(), -br.y(), *d->picture);
- painter.restore();
- } else {
- int xo = 0;
- int yo = 0;
- if (align & Qt::AlignVCenter)
- yo = (cr.height()-rh)/2;
- else if (align & Qt::AlignBottom)
- yo = cr.height()-rh;
- if (align & Qt::AlignRight)
- xo = cr.width()-rw;
- else if (align & Qt::AlignHCenter)
- xo = (cr.width()-rw)/2;
- painter.drawPicture(cr.x()+xo-br.x(), cr.y()+yo-br.y(), *d->picture);
- }
- } else
-#endif
- if (d->pixmap && !d->pixmap->isNull()) {
- QPixmap pix;
- if (d->scaledcontents) {
- if (!d->scaledpixmap || d->scaledpixmap->size() != cr.size()) {
- if (!d->cachedimage)
- d->cachedimage = new QImage(d->pixmap->toImage());
- delete d->scaledpixmap;
- d->scaledpixmap = new QPixmap(QPixmap::fromImage(d->cachedimage->scaled(cr.size(),Qt::IgnoreAspectRatio,Qt::SmoothTransformation)));
- }
- pix = *d->scaledpixmap;
- } else
- pix = *d->pixmap;
- QStyleOption opt;
- opt.initFrom(this);
- if (!isEnabled())
- pix = style->generatedIconPixmap(QIcon::Disabled, pix, &opt);
- style->drawItemPixmap(&painter, cr, align, pix);
- }
-}
-
-
-/*!
- Updates the label, but not the frame.
-*/
-
-void QLabelPrivate::updateLabel()
-{
- Q_Q(QLabel);
- valid_hints = false;
-
- if (isTextLabel) {
- QSizePolicy policy = q->sizePolicy();
- const bool wrap = align & Qt::TextWordWrap;
- policy.setHeightForWidth(wrap);
- if (policy != q->sizePolicy()) // ### should be replaced by WA_WState_OwnSizePolicy idiom
- q->setSizePolicy(policy);
- textLayoutDirty = true;
- }
- q->updateGeometry();
- q->update(q->contentsRect());
-}
-
-#ifndef QT_NO_SHORTCUT
-/*!
- Sets this label's buddy to \a buddy.
-
- When the user presses the shortcut key indicated by this label,
- the keyboard focus is transferred to the label's buddy widget.
-
- The buddy mechanism is only available for QLabels that contain
- text in which one character is prefixed with an ampersand, '&'.
- This character is set as the shortcut key. See the \l
- QKeySequence::mnemonic() documentation for details (to display an
- actual ampersand, use '&&').
-
- In a dialog, you might create two data entry widgets and a label
- for each, and set up the geometry layout so each label is just to
- the left of its data entry widget (its "buddy"), for example:
- \snippet doc/src/snippets/code/src_gui_widgets_qlabel.cpp 2
-
- With the code above, the focus jumps to the Name field when the
- user presses Alt+N, and to the Phone field when the user presses
- Alt+P.
-
- To unset a previously set buddy, call this function with \a buddy
- set to 0.
-
- \sa buddy(), setText(), QShortcut, setAlignment()
-*/
-
-void QLabel::setBuddy(QWidget *buddy)
-{
- Q_D(QLabel);
- d->buddy = buddy;
- if (d->isTextLabel) {
- if (d->shortcutId)
- releaseShortcut(d->shortcutId);
- d->shortcutId = 0;
- d->textDirty = true;
- if (buddy)
- d->updateShortcut(); // grab new shortcut
- d->updateLabel();
- }
-}
-
-
-/*!
- Returns this label's buddy, or 0 if no buddy is currently set.
-
- \sa setBuddy()
-*/
-
-QWidget * QLabel::buddy() const
-{
- Q_D(const QLabel);
- return d->buddy;
-}
-
-void QLabelPrivate::updateShortcut()
-{
- Q_Q(QLabel);
- Q_ASSERT(shortcutId == 0);
- // Introduce an extra boolean to indicate the presence of a shortcut in the
- // text. We cannot use the shortcutId itself because on the mac mnemonics are
- // off by default, so QKeySequence::mnemonic always returns an empty sequence.
- // But then we do want to hide the ampersands, so we can't use shortcutId.
- hasShortcut = false;
-
- if (!text.contains(QLatin1Char('&')))
- return;
- hasShortcut = true;
- shortcutId = q->grabShortcut(QKeySequence::mnemonic(text));
-}
-
-#endif // QT_NO_SHORTCUT
-
-#ifndef QT_NO_MOVIE
-void QLabelPrivate::_q_movieUpdated(const QRect& rect)
-{
- Q_Q(QLabel);
- if (movie && movie->isValid()) {
- QRect r;
- if (scaledcontents) {
- QRect cr = q->contentsRect();
- QRect pixmapRect(cr.topLeft(), movie->currentPixmap().size());
- if (pixmapRect.isEmpty())
- return;
- r.setRect(cr.left(), cr.top(),
- (rect.width() * cr.width()) / pixmapRect.width(),
- (rect.height() * cr.height()) / pixmapRect.height());
- } else {
- r = q->style()->itemPixmapRect(q->contentsRect(), align, movie->currentPixmap());
- r.translate(rect.x(), rect.y());
- r.setWidth(qMin(r.width(), rect.width()));
- r.setHeight(qMin(r.height(), rect.height()));
- }
- q->update(r);
- }
-}
-
-void QLabelPrivate::_q_movieResized(const QSize& size)
-{
- Q_Q(QLabel);
- q->update(); //we need to refresh the whole background in case the new size is smaler
- valid_hints = false;
- _q_movieUpdated(QRect(QPoint(0,0), size));
- q->updateGeometry();
-}
-
-/*!
- Sets the label contents to \a movie. Any previous content is
- cleared. The label does NOT take ownership of the movie.
-
- The buddy shortcut, if any, is disabled.
-
- \sa movie(), setBuddy()
-*/
-
-void QLabel::setMovie(QMovie *movie)
-{
- Q_D(QLabel);
- d->clearContents();
-
- if (!movie)
- return;
-
- d->movie = movie;
- connect(movie, SIGNAL(resized(QSize)), this, SLOT(_q_movieResized(QSize)));
- connect(movie, SIGNAL(updated(QRect)), this, SLOT(_q_movieUpdated(QRect)));
-
- // Assume that if the movie is running,
- // resize/update signals will come soon enough
- if (movie->state() != QMovie::Running)
- d->updateLabel();
-}
-
-#endif // QT_NO_MOVIE
-
-/*!
- \internal
-
- Clears any contents, without updating/repainting the label.
-*/
-
-void QLabelPrivate::clearContents()
-{
- delete control;
- control = 0;
- isTextLabel = false;
- hasShortcut = false;
-
-#ifndef QT_NO_PICTURE
- delete picture;
- picture = 0;
-#endif
- delete scaledpixmap;
- scaledpixmap = 0;
- delete cachedimage;
- cachedimage = 0;
- delete pixmap;
- pixmap = 0;
-
- text.clear();
- Q_Q(QLabel);
-#ifndef QT_NO_SHORTCUT
- if (shortcutId)
- q->releaseShortcut(shortcutId);
- shortcutId = 0;
-#endif
-#ifndef QT_NO_MOVIE
- if (movie) {
- QObject::disconnect(movie, SIGNAL(resized(QSize)), q, SLOT(_q_movieResized(QSize)));
- QObject::disconnect(movie, SIGNAL(updated(QRect)), q, SLOT(_q_movieUpdated(QRect)));
- }
- movie = 0;
-#endif
-#ifndef QT_NO_CURSOR
- if (onAnchor) {
- if (validCursor)
- q->setCursor(cursor);
- else
- q->unsetCursor();
- }
- validCursor = false;
- onAnchor = false;
-#endif
-}
-
-
-#ifndef QT_NO_MOVIE
-
-/*!
- Returns a pointer to the label's movie, or 0 if no movie has been
- set.
-
- \sa setMovie()
-*/
-
-QMovie *QLabel::movie() const
-{
- Q_D(const QLabel);
- return d->movie;
-}
-
-#endif // QT_NO_MOVIE
-
-/*!
- \property QLabel::textFormat
- \brief the label's text format
-
- See the Qt::TextFormat enum for an explanation of the possible
- options.
-
- The default format is Qt::AutoText.
-
- \sa text()
-*/
-
-Qt::TextFormat QLabel::textFormat() const
-{
- Q_D(const QLabel);
- return d->textformat;
-}
-
-void QLabel::setTextFormat(Qt::TextFormat format)
-{
- Q_D(QLabel);
- if (format != d->textformat) {
- d->textformat = format;
- QString t = d->text;
- if (!t.isNull()) {
- d->text.clear();
- setText(t);
- }
- }
-}
-
-/*!
- \reimp
-*/
-void QLabel::changeEvent(QEvent *ev)
-{
- Q_D(QLabel);
- if(ev->type() == QEvent::FontChange || ev->type() == QEvent::ApplicationFontChange) {
- if (d->isTextLabel) {
- if (d->control)
- d->control->document()->setDefaultFont(font());
- d->updateLabel();
- }
- } else if (ev->type() == QEvent::PaletteChange && d->control) {
- d->control->setPalette(palette());
- } else if (ev->type() == QEvent::ContentsRectChange) {
- d->updateLabel();
- }
- QFrame::changeEvent(ev);
-}
-
-/*!
- \property QLabel::scaledContents
- \brief whether the label will scale its contents to fill all
- available space.
-
- When enabled and the label shows a pixmap, it will scale the
- pixmap to fill the available space.
-
- This property's default is false.
-*/
-bool QLabel::hasScaledContents() const
-{
- Q_D(const QLabel);
- return d->scaledcontents;
-}
-
-void QLabel::setScaledContents(bool enable)
-{
- Q_D(QLabel);
- if ((bool)d->scaledcontents == enable)
- return;
- d->scaledcontents = enable;
- if (!enable) {
- delete d->scaledpixmap;
- d->scaledpixmap = 0;
- delete d->cachedimage;
- d->cachedimage = 0;
- }
- update(contentsRect());
-}
-
-Qt::LayoutDirection QLabelPrivate::textDirection() const
-{
- if (control) {
- QTextOption opt = control->document()->defaultTextOption();
- return opt.textDirection();
- }
-
- return text.isRightToLeft() ? Qt::RightToLeft : Qt::LeftToRight;
-}
-
-/*!
- \fn void QLabel::setAlignment(Qt::AlignmentFlag flag)
- \internal
-
- Without this function, a call to e.g. setAlignment(Qt::AlignTop)
- results in the \c QT3_SUPPORT function setAlignment(int) being called,
- rather than setAlignment(Qt::Alignment).
-*/
-
-// Returns the rect that is available for us to draw the document
-QRect QLabelPrivate::documentRect() const
-{
- Q_Q(const QLabel);
- Q_ASSERT_X(isTextLabel, "documentRect", "document rect called for label that is not a text label!");
- QRect cr = q->contentsRect();
- cr.adjust(margin, margin, -margin, -margin);
- const int align = QStyle::visualAlignment(isTextLabel ? textDirection()
- : q->layoutDirection(), QFlag(this->align));
- int m = indent;
- if (m < 0 && q->frameWidth()) // no indent, but we do have a frame
- m = q->fontMetrics().width(QLatin1Char('x')) / 2 - margin;
- if (m > 0) {
- if (align & Qt::AlignLeft)
- cr.setLeft(cr.left() + m);
- if (align & Qt::AlignRight)
- cr.setRight(cr.right() - m);
- if (align & Qt::AlignTop)
- cr.setTop(cr.top() + m);
- if (align & Qt::AlignBottom)
- cr.setBottom(cr.bottom() - m);
- }
- return cr;
-}
-
-void QLabelPrivate::ensureTextPopulated() const
-{
- if (!textDirty)
- return;
- if (control) {
- QTextDocument *doc = control->document();
- if (textDirty) {
-#ifndef QT_NO_TEXTHTMLPARSER
- if (isRichText)
- doc->setHtml(text);
- else
- doc->setPlainText(text);
-#else
- doc->setPlainText(text);
-#endif
- doc->setUndoRedoEnabled(false);
-
-#ifndef QT_NO_SHORTCUT
- if (hasShortcut) {
- // Underline the first character that follows an ampersand (and remove the others ampersands)
- int from = 0;
- bool found = false;
- QTextCursor cursor;
- while (!(cursor = control->document()->find((QLatin1String("&")), from)).isNull()) {
- cursor.deleteChar(); // remove the ampersand
- cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);
- from = cursor.position();
- if (!found && cursor.selectedText() != QLatin1String("&")) { //not a second &
- found = true;
- shortcutCursor = cursor;
- }
- }
- }
-#endif
- }
- }
- textDirty = false;
-}
-
-void QLabelPrivate::ensureTextLayouted() const
-{
- if (!textLayoutDirty)
- return;
- ensureTextPopulated();
- if (control) {
- QTextDocument *doc = control->document();
- QTextOption opt = doc->defaultTextOption();
-
- opt.setAlignment(QFlag(this->align));
-
- if (this->align & Qt::TextWordWrap)
- opt.setWrapMode(QTextOption::WordWrap);
- else
- opt.setWrapMode(QTextOption::ManualWrap);
-
- doc->setDefaultTextOption(opt);
-
- QTextFrameFormat fmt = doc->rootFrame()->frameFormat();
- fmt.setMargin(0);
- doc->rootFrame()->setFrameFormat(fmt);
- doc->setTextWidth(documentRect().width());
- }
- textLayoutDirty = false;
-}
-
-void QLabelPrivate::ensureTextControl() const
-{
- Q_Q(const QLabel);
- if (!isTextLabel)
- return;
- if (!control) {
- control = new QTextControl(const_cast<QLabel *>(q));
- control->document()->setUndoRedoEnabled(false);
- control->document()->setDefaultFont(q->font());
- control->setTextInteractionFlags(textInteractionFlags);
- control->setOpenExternalLinks(openExternalLinks);
- control->setPalette(q->palette());
- control->setFocus(q->hasFocus());
- QObject::connect(control, SIGNAL(updateRequest(QRectF)),
- q, SLOT(update()));
- QObject::connect(control, SIGNAL(linkHovered(QString)),
- q, SLOT(_q_linkHovered(QString)));
- QObject::connect(control, SIGNAL(linkActivated(QString)),
- q, SIGNAL(linkActivated(QString)));
- textLayoutDirty = true;
- textDirty = true;
- }
-}
-
-void QLabelPrivate::sendControlEvent(QEvent *e)
-{
- Q_Q(QLabel);
- if (!isTextLabel || !control || textInteractionFlags == Qt::NoTextInteraction) {
- e->ignore();
- return;
- }
- control->processEvent(e, -layoutRect().topLeft(), q);
-}
-
-void QLabelPrivate::_q_linkHovered(const QString &anchor)
-{
- Q_Q(QLabel);
-#ifndef QT_NO_CURSOR
- if (anchor.isEmpty()) { // restore cursor
- if (validCursor)
- q->setCursor(cursor);
- else
- q->unsetCursor();
- onAnchor = false;
- } else if (!onAnchor) {
- validCursor = q->testAttribute(Qt::WA_SetCursor);
- if (validCursor) {
- cursor = q->cursor();
- }
- q->setCursor(Qt::PointingHandCursor);
- onAnchor = true;
- }
-#endif
- emit q->linkHovered(anchor);
-}
-
-// Return the layout rect - this is the rect that is given to the layout painting code
-// This may be different from the document rect since vertical alignment is not
-// done by the text layout code
-QRectF QLabelPrivate::layoutRect() const
-{
- QRectF cr = documentRect();
- if (!control)
- return cr;
- ensureTextLayouted();
- // Caculate y position manually
- qreal rh = control->document()->documentLayout()->documentSize().height();
- qreal yo = 0;
- if (align & Qt::AlignVCenter)
- yo = qMax((cr.height()-rh)/2, qreal(0));
- else if (align & Qt::AlignBottom)
- yo = qMax(cr.height()-rh, qreal(0));
- return QRectF(cr.x(), yo + cr.y(), cr.width(), cr.height());
-}
-
-// Returns the point in the document rect adjusted with p
-QPoint QLabelPrivate::layoutPoint(const QPoint& p) const
-{
- QRect lr = layoutRect().toRect();
- return p - lr.topLeft();
-}
-
-#ifndef QT_NO_CONTEXTMENU
-QMenu *QLabelPrivate::createStandardContextMenu(const QPoint &pos)
-{
- QString linkToCopy;
- QPoint p;
- if (control && isRichText) {
- p = layoutPoint(pos);
- linkToCopy = control->document()->documentLayout()->anchorAt(p);
- }
-
- if (linkToCopy.isEmpty() && !control)
- return 0;
-
- return control->createStandardContextMenu(p, q_func());
-}
-#endif
-
-/*!
- \fn void QLabel::linkHovered(const QString &link)
- \since 4.2
-
- This signal is emitted when the user hovers over a link. The URL
- referred to by the anchor is passed in \a link.
-
- \sa linkActivated()
-*/
-
-
-/*!
- \fn void QLabel::linkActivated(const QString &link)
- \since 4.2
-
- This signal is emitted when the user clicks a link. The URL
- referred to by the anchor is passed in \a link.
-
- \sa linkHovered()
-*/
-
-QT_END_NAMESPACE
-
-#include "moc_qlabel.cpp"
diff --git a/src/gui/widgets/qlabel.h b/src/gui/widgets/qlabel.h
deleted file mode 100644
index f1971eb3fe..0000000000
--- a/src/gui/widgets/qlabel.h
+++ /dev/null
@@ -1,182 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QLABEL_H
-#define QLABEL_H
-
-#include <QtGui/qframe.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QLabelPrivate;
-
-class Q_GUI_EXPORT QLabel : public QFrame
-{
- Q_OBJECT
- Q_PROPERTY(QString text READ text WRITE setText)
- Q_PROPERTY(Qt::TextFormat textFormat READ textFormat WRITE setTextFormat)
- Q_PROPERTY(QPixmap pixmap READ pixmap WRITE setPixmap)
- Q_PROPERTY(bool scaledContents READ hasScaledContents WRITE setScaledContents)
- Q_PROPERTY(Qt::Alignment alignment READ alignment WRITE setAlignment)
- Q_PROPERTY(bool wordWrap READ wordWrap WRITE setWordWrap)
- Q_PROPERTY(int margin READ margin WRITE setMargin)
- Q_PROPERTY(int indent READ indent WRITE setIndent)
- Q_PROPERTY(bool openExternalLinks READ openExternalLinks WRITE setOpenExternalLinks)
- Q_PROPERTY(Qt::TextInteractionFlags textInteractionFlags READ textInteractionFlags WRITE setTextInteractionFlags)
- Q_PROPERTY(bool hasSelectedText READ hasSelectedText)
- Q_PROPERTY(QString selectedText READ selectedText)
-
-public:
- explicit QLabel(QWidget *parent=0, Qt::WindowFlags f=0);
- explicit QLabel(const QString &text, QWidget *parent=0, Qt::WindowFlags f=0);
- ~QLabel();
-
- QString text() const;
- const QPixmap *pixmap() const;
-#ifndef QT_NO_PICTURE
- const QPicture *picture() const;
-#endif
-#ifndef QT_NO_MOVIE
- QMovie *movie() const;
-#endif
-
- Qt::TextFormat textFormat() const;
- void setTextFormat(Qt::TextFormat);
-
- Qt::Alignment alignment() const;
- void setAlignment(Qt::Alignment);
-
- void setWordWrap(bool on);
- bool wordWrap() const;
-
- int indent() const;
- void setIndent(int);
-
- int margin() const;
- void setMargin(int);
-
- bool hasScaledContents() const;
- void setScaledContents(bool);
- QSize sizeHint() const;
- QSize minimumSizeHint() const;
-#ifndef QT_NO_SHORTCUT
- void setBuddy(QWidget *);
- QWidget *buddy() const;
-#endif
- int heightForWidth(int) const;
-
- bool openExternalLinks() const;
- void setOpenExternalLinks(bool open);
-
- void setTextInteractionFlags(Qt::TextInteractionFlags flags);
- Qt::TextInteractionFlags textInteractionFlags() const;
-
- void setSelection(int, int);
- bool hasSelectedText() const;
- QString selectedText() const;
- int selectionStart() const;
-
-public Q_SLOTS:
- void setText(const QString &);
- void setPixmap(const QPixmap &);
-#ifndef QT_NO_PICTURE
- void setPicture(const QPicture &);
-#endif
-#ifndef QT_NO_MOVIE
- void setMovie(QMovie *movie);
-#endif
- void setNum(int);
- void setNum(double);
- void clear();
-
-Q_SIGNALS:
- void linkActivated(const QString& link);
- void linkHovered(const QString& link);
-
-protected:
- bool event(QEvent *e);
- void keyPressEvent(QKeyEvent *ev);
- void paintEvent(QPaintEvent *);
- void changeEvent(QEvent *);
- void mousePressEvent(QMouseEvent *ev);
- void mouseMoveEvent(QMouseEvent *ev);
- void mouseReleaseEvent(QMouseEvent *ev);
- void contextMenuEvent(QContextMenuEvent *ev);
- void focusInEvent(QFocusEvent *ev);
- void focusOutEvent(QFocusEvent *ev);
- bool focusNextPrevChild(bool next);
-
-#ifdef QT3_SUPPORT
-public:
- QT3_SUPPORT_CONSTRUCTOR QLabel(QWidget *parent, const char* name, Qt::WindowFlags f=0);
- QT3_SUPPORT_CONSTRUCTOR QLabel(const QString &text, QWidget *parent, const char* name,
- Qt::WindowFlags f=0);
- QT3_SUPPORT_CONSTRUCTOR QLabel(QWidget *buddy, const QString &,
- QWidget *parent=0, const char* name=0, Qt::WindowFlags f=0);
- QT3_SUPPORT void setAlignment(int alignment);
-
- // don't mark the next function with QT3_SUPPORT
- inline void setAlignment(Qt::AlignmentFlag flag) { setAlignment((Qt::Alignment)flag); }
-#endif
-
-private:
- Q_DISABLE_COPY(QLabel)
- Q_DECLARE_PRIVATE(QLabel)
-#ifndef QT_NO_MOVIE
- Q_PRIVATE_SLOT(d_func(), void _q_movieUpdated(const QRect&))
- Q_PRIVATE_SLOT(d_func(), void _q_movieResized(const QSize&))
-#endif
- Q_PRIVATE_SLOT(d_func(), void _q_linkHovered(const QString &))
-
- friend class QTipLabel;
- friend class QMessageBoxPrivate;
- friend class QBalloonTip;
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QLABEL_H
diff --git a/src/gui/widgets/qlabel_p.h b/src/gui/widgets/qlabel_p.h
deleted file mode 100644
index 000fcd2fec..0000000000
--- a/src/gui/widgets/qlabel_p.h
+++ /dev/null
@@ -1,153 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QLABEL_P_H
-#define QLABEL_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qlabel.h"
-
-#include "private/qtextdocumentlayout_p.h"
-#include "private/qtextcontrol_p.h"
-#include "qtextdocumentfragment.h"
-#include "qframe_p.h"
-#include "qtextdocument.h"
-#include "qmovie.h"
-#include "qimage.h"
-#include "qbitmap.h"
-#include "qpicture.h"
-#include "qmenu.h"
-
-QT_BEGIN_NAMESPACE
-
-class QLabelPrivate : public QFramePrivate
-{
- Q_DECLARE_PUBLIC(QLabel)
-public:
- QLabelPrivate() {}
-
- void init();
- void clearContents();
- void updateLabel();
- QSize sizeForWidth(int w) const;
-
- mutable QSize sh;
- mutable QSize msh;
- mutable bool valid_hints;
- mutable QSizePolicy sizePolicy;
- int margin;
- QString text;
- QPixmap *pixmap;
- QPixmap *scaledpixmap;
- QImage *cachedimage;
-#ifndef QT_NO_PICTURE
- QPicture *picture;
-#endif
-#ifndef QT_NO_MOVIE
- QPointer<QMovie> movie;
- void _q_movieUpdated(const QRect&);
- void _q_movieResized(const QSize&);
-#endif
-#ifndef QT_NO_SHORTCUT
- void updateShortcut();
-#endif
-#ifndef QT_NO_SHORTCUT
- QPointer<QWidget> buddy;
- int shortcutId;
-#endif
- ushort align;
- short indent;
- uint scaledcontents :1;
- mutable uint textLayoutDirty : 1;
- mutable uint textDirty : 1;
- mutable uint isRichText : 1;
- mutable uint isTextLabel : 1;
- mutable uint hasShortcut : 1;
- Qt::TextFormat textformat;
- mutable QTextControl *control;
- mutable QTextCursor shortcutCursor;
- Qt::TextInteractionFlags textInteractionFlags;
-
- inline bool needTextControl() const {
- return isTextLabel
- && (isRichText
- || (!isRichText && (textInteractionFlags & (Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard))));
- }
-
- void ensureTextPopulated() const;
- void ensureTextLayouted() const;
- void ensureTextControl() const;
- void sendControlEvent(QEvent *e);
-
- void _q_linkHovered(const QString &link);
-
- QRectF layoutRect() const;
- QRect documentRect() const;
- QPoint layoutPoint(const QPoint& p) const;
- Qt::LayoutDirection textDirection() const;
-#ifndef QT_NO_CONTEXTMENU
- QMenu *createStandardContextMenu(const QPoint &pos);
-#endif
-
- bool openExternalLinks;
-
-#ifndef QT_NO_CURSOR
- uint validCursor : 1;
- uint onAnchor : 1;
- QCursor cursor;
-#endif
-
- friend class QMessageBoxPrivate;
-};
-
-QT_END_NAMESPACE
-
-#endif // QLABEL_P_H
diff --git a/src/gui/widgets/qlcdnumber.h b/src/gui/widgets/qlcdnumber.h
deleted file mode 100644
index 9d530943c2..0000000000
--- a/src/gui/widgets/qlcdnumber.h
+++ /dev/null
@@ -1,144 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QLCDNUMBER_H
-#define QLCDNUMBER_H
-
-#include <QtGui/qframe.h>
-#include <QtCore/qbitarray.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_LCDNUMBER
-
-class QLCDNumberPrivate;
-class Q_GUI_EXPORT QLCDNumber : public QFrame // LCD number widget
-{
- Q_OBJECT
- Q_ENUMS(Mode SegmentStyle)
- Q_PROPERTY(bool smallDecimalPoint READ smallDecimalPoint WRITE setSmallDecimalPoint)
- Q_PROPERTY(int numDigits READ numDigits WRITE setNumDigits)
- Q_PROPERTY(int digitCount READ digitCount WRITE setDigitCount)
- Q_PROPERTY(Mode mode READ mode WRITE setMode)
- Q_PROPERTY(SegmentStyle segmentStyle READ segmentStyle WRITE setSegmentStyle)
- Q_PROPERTY(double value READ value WRITE display)
- Q_PROPERTY(int intValue READ intValue WRITE display)
-
-public:
- explicit QLCDNumber(QWidget* parent = 0);
- explicit QLCDNumber(uint numDigits, QWidget* parent = 0);
- ~QLCDNumber();
-
- enum Mode {
- Hex, Dec, Oct, Bin
-#if defined(QT3_SUPPORT) && !defined(Q_MOC_RUN)
- , HEX = Hex, DEC = Dec, OCT = Oct, BIN = Bin
-#endif
- };
- enum SegmentStyle {
- Outline, Filled, Flat
- };
-
- bool smallDecimalPoint() const;
-#ifdef QT_DEPRECATED
- QT_DEPRECATED int numDigits() const;
- QT_DEPRECATED void setNumDigits(int nDigits);
-#endif
- int digitCount() const;
- void setDigitCount(int nDigits);
-
- bool checkOverflow(double num) const;
- bool checkOverflow(int num) const;
-
- Mode mode() const;
- void setMode(Mode);
-
- SegmentStyle segmentStyle() const;
- void setSegmentStyle(SegmentStyle);
-
- double value() const;
- int intValue() const;
-
- QSize sizeHint() const;
-
-public Q_SLOTS:
- void display(const QString &str);
- void display(int num);
- void display(double num);
- void setHexMode();
- void setDecMode();
- void setOctMode();
- void setBinMode();
- void setSmallDecimalPoint(bool);
-
-Q_SIGNALS:
- void overflow();
-
-protected:
- bool event(QEvent *e);
- void paintEvent(QPaintEvent *);
-
-public:
-#ifdef QT3_SUPPORT
- QT3_SUPPORT_CONSTRUCTOR QLCDNumber(QWidget* parent, const char* name);
- QT3_SUPPORT_CONSTRUCTOR QLCDNumber(uint numDigits, QWidget* parent, const char* name);
-
- QT3_SUPPORT void setMargin(int margin) { setContentsMargins(margin, margin, margin, margin); }
- QT3_SUPPORT int margin() const
- { int margin; int dummy; getContentsMargins(&margin, &dummy, &dummy, &dummy); return margin; }
-#endif
-
-private:
- Q_DISABLE_COPY(QLCDNumber)
- Q_DECLARE_PRIVATE(QLCDNumber)
-};
-
-#endif // QT_NO_LCDNUMBER
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QLCDNUMBER_H
diff --git a/src/gui/widgets/qlinecontrol.cpp b/src/gui/widgets/qlinecontrol.cpp
deleted file mode 100644
index 79c2498fa1..0000000000
--- a/src/gui/widgets/qlinecontrol.cpp
+++ /dev/null
@@ -1,1920 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qlinecontrol_p.h"
-
-#ifndef QT_NO_LINEEDIT
-
-#include "qabstractitemview.h"
-#include "qclipboard.h"
-#ifndef QT_NO_ACCESSIBILITY
-#include "qaccessible.h"
-#endif
-#ifndef QT_NO_IM
-#include "qinputcontext.h"
-#include "qlist.h"
-#endif
-#include "qapplication.h"
-#ifndef QT_NO_GRAPHICSVIEW
-#include "qgraphicssceneevent.h"
-#endif
-
-QT_BEGIN_NAMESPACE
-
-#ifdef QT_GUI_PASSWORD_ECHO_DELAY
-static const int qt_passwordEchoDelay = QT_GUI_PASSWORD_ECHO_DELAY;
-#endif
-
-/*!
- \macro QT_GUI_PASSWORD_ECHO_DELAY
-
- \internal
-
- Defines the amount of time in milliseconds the last entered character
- should be displayed unmasked in the Password echo mode.
-
- If not defined in qplatformdefs.h there will be no delay in masking
- password characters.
-*/
-
-/*!
- \internal
-
- Updates the internal text layout. Returns the ascent of the
- created QTextLine.
-*/
-int QLineControl::redoTextLayout() const
-{
- m_textLayout.clearLayout();
-
- m_textLayout.beginLayout();
- QTextLine l = m_textLayout.createLine();
- m_textLayout.endLayout();
-
-#if defined(Q_WS_MAC)
- if (m_threadChecks)
- m_textLayoutThread = QThread::currentThread();
-#endif
-
- return qRound(l.ascent());
-}
-
-/*!
- \internal
-
- Updates the display text based of the current edit text
- If the text has changed will emit displayTextChanged()
-*/
-void QLineControl::updateDisplayText(bool forceUpdate)
-{
- QString orig = m_textLayout.text();
- QString str;
- if (m_echoMode == QLineEdit::NoEcho)
- str = QString::fromLatin1("");
- else
- str = m_text;
-
- if (m_echoMode == QLineEdit::Password) {
- str.fill(m_passwordCharacter);
-#ifdef QT_GUI_PASSWORD_ECHO_DELAY
- if (m_passwordEchoTimer != 0 && m_cursor > 0 && m_cursor <= m_text.length()) {
- int cursor = m_cursor - 1;
- QChar uc = m_text.at(cursor);
- str[cursor] = uc;
- if (cursor > 0 && uc.unicode() >= 0xdc00 && uc.unicode() < 0xe000) {
- // second half of a surrogate, check if we have the first half as well,
- // if yes restore both at once
- uc = m_text.at(cursor - 1);
- if (uc.unicode() >= 0xd800 && uc.unicode() < 0xdc00)
- str[cursor - 1] = uc;
- }
- }
-#endif
- } else if (m_echoMode == QLineEdit::PasswordEchoOnEdit && !m_passwordEchoEditing) {
- str.fill(m_passwordCharacter);
- }
-
- // replace certain non-printable characters with spaces (to avoid
- // drawing boxes when using fonts that don't have glyphs for such
- // characters)
- QChar* uc = str.data();
- for (int i = 0; i < (int)str.length(); ++i) {
- if ((uc[i] < 0x20 && uc[i] != 0x09)
- || uc[i] == QChar::LineSeparator
- || uc[i] == QChar::ParagraphSeparator
- || uc[i] == QChar::ObjectReplacementCharacter)
- uc[i] = QChar(0x0020);
- }
-
- m_textLayout.setText(str);
-
- QTextOption option = m_textLayout.textOption();
- option.setTextDirection(m_layoutDirection);
- option.setFlags(QTextOption::IncludeTrailingSpaces);
- m_textLayout.setTextOption(option);
-
- m_ascent = redoTextLayout();
-
- if (str != orig || forceUpdate)
- emit displayTextChanged(str);
-}
-
-#ifndef QT_NO_CLIPBOARD
-/*!
- \internal
-
- Copies the currently selected text into the clipboard using the given
- \a mode.
-
- \note If the echo mode is set to a mode other than Normal then copy
- will not work. This is to prevent using copy as a method of bypassing
- password features of the line control.
-*/
-void QLineControl::copy(QClipboard::Mode mode) const
-{
- QString t = selectedText();
- if (!t.isEmpty() && m_echoMode == QLineEdit::Normal) {
- disconnect(QApplication::clipboard(), SIGNAL(selectionChanged()), this, 0);
- QApplication::clipboard()->setText(t, mode);
- connect(QApplication::clipboard(), SIGNAL(selectionChanged()),
- this, SLOT(_q_clipboardChanged()));
- }
-}
-
-/*!
- \internal
-
- Inserts the text stored in the application clipboard into the line
- control.
-
- \sa insert()
-*/
-void QLineControl::paste(QClipboard::Mode clipboardMode)
-{
- QString clip = QApplication::clipboard()->text(clipboardMode);
- if (!clip.isEmpty() || hasSelectedText()) {
- separate(); //make it a separate undo/redo command
- insert(clip);
- separate();
- }
-}
-
-#endif // !QT_NO_CLIPBOARD
-
-/*!
- \internal
-
- Handles the behavior for the backspace key or function.
- Removes the current selection if there is a selection, otherwise
- removes the character prior to the cursor position.
-
- \sa del()
-*/
-void QLineControl::backspace()
-{
- int priorState = m_undoState;
- if (hasSelectedText()) {
- removeSelectedText();
- } else if (m_cursor) {
- --m_cursor;
- if (m_maskData)
- m_cursor = prevMaskBlank(m_cursor);
- if (m_cursor > 0 && m_text.at(m_cursor).isLowSurrogate()) {
- // second half of a surrogate, check if we have the first half as well,
- // if yes delete both at once
- if (m_text.at(m_cursor - 1).isHighSurrogate()) {
- internalDelete(true);
- --m_cursor;
- }
- }
- internalDelete(true);
- }
- finishChange(priorState);
-}
-
-/*!
- \internal
-
- Handles the behavior for the delete key or function.
- Removes the current selection if there is a selection, otherwise
- removes the character after the cursor position.
-
- \sa del()
-*/
-void QLineControl::del()
-{
- int priorState = m_undoState;
- if (hasSelectedText()) {
- removeSelectedText();
- } else {
- int n = textLayout()->nextCursorPosition(m_cursor) - m_cursor;
- while (n--)
- internalDelete();
- }
- finishChange(priorState);
-}
-
-/*!
- \internal
-
- Inserts the given \a newText at the current cursor position.
- If there is any selected text it is removed prior to insertion of
- the new text.
-*/
-void QLineControl::insert(const QString &newText)
-{
- int priorState = m_undoState;
- removeSelectedText();
- internalInsert(newText);
- finishChange(priorState);
-}
-
-/*!
- \internal
-
- Clears the line control text.
-*/
-void QLineControl::clear()
-{
- int priorState = m_undoState;
- m_selstart = 0;
- m_selend = m_text.length();
- removeSelectedText();
- separate();
- finishChange(priorState, /*update*/false, /*edited*/false);
-}
-
-/*!
- \internal
-
- Sets \a length characters from the given \a start position as selected.
- The given \a start position must be within the current text for
- the line control. If \a length characters cannot be selected, then
- the selection will extend to the end of the current text.
-*/
-void QLineControl::setSelection(int start, int length)
-{
- if(start < 0 || start > (int)m_text.length()){
- qWarning("QLineControl::setSelection: Invalid start position");
- return;
- }
-
- if (length > 0) {
- m_selDirty |= (start != m_selstart || start + length != m_selend);
- m_selstart = start;
- m_selend = qMin(start + length, (int)m_text.length());
- m_cursor = m_selend;
- } else if (length < 0){
- m_selDirty |= (start != m_selend || start + length != m_selstart);
- m_selstart = qMax(start + length, 0);
- m_selend = start;
- m_cursor = m_selstart;
- } else if (m_selstart != m_selend) {
- m_selDirty = true;
- m_selstart = 0;
- m_selend = 0;
- m_cursor = start;
- } else {
- m_cursor = start;
- }
- if (m_selDirty) {
- m_selDirty = false;
- emit selectionChanged();
- }
- emitCursorPositionChanged();
-}
-
-void QLineControl::_q_clipboardChanged()
-{
-}
-
-void QLineControl::_q_deleteSelected()
-{
- if (!hasSelectedText())
- return;
-
- int priorState = m_undoState;
- emit resetInputContext();
- removeSelectedText();
- separate();
- finishChange(priorState);
-}
-
-/*!
- \internal
-
- Initializes the line control with a starting text value of \a txt.
-*/
-void QLineControl::init(const QString &txt)
-{
- m_text = txt;
- updateDisplayText();
- m_cursor = m_text.length();
-}
-
-/*!
- \internal
-
- Sets the password echo editing to \a editing. If password echo editing
- is true, then the text of the password is displayed even if the echo
- mode is set to QLineEdit::PasswordEchoOnEdit. Password echoing editing
- does not affect other echo modes.
-*/
-void QLineControl::updatePasswordEchoEditing(bool editing)
-{
- cancelPasswordEchoTimer();
- m_passwordEchoEditing = editing;
- updateDisplayText();
-}
-
-/*!
- \internal
-
- Returns the cursor position of the given \a x pixel value in relation
- to the displayed text. The given \a betweenOrOn specified what kind
- of cursor position is requested.
-*/
-int QLineControl::xToPos(int x, QTextLine::CursorPosition betweenOrOn) const
-{
- return textLayout()->lineAt(0).xToCursor(x, betweenOrOn);
-}
-
-/*!
- \internal
-
- Returns the bounds of the current cursor, as defined as a
- between characters cursor.
-*/
-QRect QLineControl::cursorRect() const
-{
- QTextLine l = textLayout()->lineAt(0);
- int c = m_cursor;
- if (m_preeditCursor != -1)
- c += m_preeditCursor;
- int cix = qRound(l.cursorToX(c));
- int w = m_cursorWidth;
- int ch = l.height() + 1;
-
- return QRect(cix-5, 0, w+9, ch);
-}
-
-/*!
- \internal
-
- Fixes the current text so that it is valid given any set validators.
-
- Returns true if the text was changed. Otherwise returns false.
-*/
-bool QLineControl::fixup() // this function assumes that validate currently returns != Acceptable
-{
-#ifndef QT_NO_VALIDATOR
- if (m_validator) {
- QString textCopy = m_text;
- int cursorCopy = m_cursor;
- m_validator->fixup(textCopy);
- if (m_validator->validate(textCopy, cursorCopy) == QValidator::Acceptable) {
- if (textCopy != m_text || cursorCopy != m_cursor)
- internalSetText(textCopy, cursorCopy);
- return true;
- }
- }
-#endif
- return false;
-}
-
-/*!
- \internal
-
- Moves the cursor to the given position \a pos. If \a mark is true will
- adjust the currently selected text.
-*/
-void QLineControl::moveCursor(int pos, bool mark)
-{
- if (pos != m_cursor) {
- separate();
- if (m_maskData)
- pos = pos > m_cursor ? nextMaskBlank(pos) : prevMaskBlank(pos);
- }
- if (mark) {
- int anchor;
- if (m_selend > m_selstart && m_cursor == m_selstart)
- anchor = m_selend;
- else if (m_selend > m_selstart && m_cursor == m_selend)
- anchor = m_selstart;
- else
- anchor = m_cursor;
- m_selstart = qMin(anchor, pos);
- m_selend = qMax(anchor, pos);
- updateDisplayText();
- } else {
- internalDeselect();
- }
- m_cursor = pos;
- if (mark || m_selDirty) {
- m_selDirty = false;
- emit selectionChanged();
- }
- emitCursorPositionChanged();
-}
-
-/*!
- \internal
-
- Applies the given input method event \a event to the text of the line
- control
-*/
-void QLineControl::processInputMethodEvent(QInputMethodEvent *event)
-{
- int priorState = 0;
- bool isGettingInput = !event->commitString().isEmpty()
- || event->preeditString() != preeditAreaText()
- || event->replacementLength() > 0;
- bool cursorPositionChanged = false;
-
- if (isGettingInput) {
- // If any text is being input, remove selected text.
- priorState = m_undoState;
- if (echoMode() == QLineEdit::PasswordEchoOnEdit && !passwordEchoEditing()) {
- updatePasswordEchoEditing(true);
- m_selstart = 0;
- m_selend = m_text.length();
- }
- removeSelectedText();
- }
-
- int c = m_cursor; // cursor position after insertion of commit string
- if (event->replacementStart() <= 0)
- c += event->commitString().length() - qMin(-event->replacementStart(), event->replacementLength());
-
- m_cursor += event->replacementStart();
- if (m_cursor < 0)
- m_cursor = 0;
-
- // insert commit string
- if (event->replacementLength()) {
- m_selstart = m_cursor;
- m_selend = m_selstart + event->replacementLength();
- removeSelectedText();
- }
- if (!event->commitString().isEmpty()) {
- internalInsert(event->commitString());
- cursorPositionChanged = true;
- }
-
- m_cursor = qBound(0, c, m_text.length());
-
- for (int i = 0; i < event->attributes().size(); ++i) {
- const QInputMethodEvent::Attribute &a = event->attributes().at(i);
- if (a.type == QInputMethodEvent::Selection) {
- m_cursor = qBound(0, a.start + a.length, m_text.length());
- if (a.length) {
- m_selstart = qMax(0, qMin(a.start, m_text.length()));
- m_selend = m_cursor;
- if (m_selend < m_selstart) {
- qSwap(m_selstart, m_selend);
- }
- m_selDirty = true;
- } else {
- m_selstart = m_selend = 0;
- }
- cursorPositionChanged = true;
- }
- }
-
-#ifndef QT_NO_IM
- setPreeditArea(m_cursor, event->preeditString());
-#endif //QT_NO_IM
- const int oldPreeditCursor = m_preeditCursor;
- m_preeditCursor = event->preeditString().length();
- m_hideCursor = false;
- QList<QTextLayout::FormatRange> formats;
- for (int i = 0; i < event->attributes().size(); ++i) {
- const QInputMethodEvent::Attribute &a = event->attributes().at(i);
- if (a.type == QInputMethodEvent::Cursor) {
- m_preeditCursor = a.start;
- m_hideCursor = !a.length;
- } else if (a.type == QInputMethodEvent::TextFormat) {
- QTextCharFormat f = qvariant_cast<QTextFormat>(a.value).toCharFormat();
- if (f.isValid()) {
- QTextLayout::FormatRange o;
- o.start = a.start + m_cursor;
- o.length = a.length;
- o.format = f;
- formats.append(o);
- }
- }
- }
- m_textLayout.setAdditionalFormats(formats);
- updateDisplayText(/*force*/ true);
- if (isGettingInput) {
- finishChange(priorState);
- } else {
- if (cursorPositionChanged)
- emitCursorPositionChanged();
- else if (m_preeditCursor != oldPreeditCursor)
- emit updateMicroFocus();
- if (m_selDirty) {
- m_selDirty = false;
- emit selectionChanged();
- }
- }
-}
-
-/*!
- \internal
-
- Draws the display text for the line control using the given
- \a painter, \a clip, and \a offset. Which aspects of the display text
- are drawn is specified by the given \a flags.
-
- If the flags contain DrawSelections, then the selection or input mask
- backgrounds and foregrounds will be applied before drawing the text.
-
- If the flags contain DrawCursor a cursor of the current cursorWidth()
- will be drawn after drawing the text.
-
- The display text will only be drawn if the flags contain DrawText
-*/
-void QLineControl::draw(QPainter *painter, const QPoint &offset, const QRect &clip, int flags)
-{
- QVector<QTextLayout::FormatRange> selections;
- if (flags & DrawSelections) {
- QTextLayout::FormatRange o;
- if (m_selstart < m_selend) {
- o.start = m_selstart;
- o.length = m_selend - m_selstart;
- o.format.setBackground(m_palette.brush(QPalette::Highlight));
- o.format.setForeground(m_palette.brush(QPalette::HighlightedText));
- } else {
- // mask selection
- if(!m_blinkPeriod || m_blinkStatus){
- o.start = m_cursor;
- o.length = 1;
- o.format.setBackground(m_palette.brush(QPalette::Text));
- o.format.setForeground(m_palette.brush(QPalette::Window));
- }
- }
- selections.append(o);
- }
-
- if (flags & DrawText)
- textLayout()->draw(painter, offset, selections, clip);
-
- if (flags & DrawCursor){
- int cursor = m_cursor;
- if (m_preeditCursor != -1)
- cursor += m_preeditCursor;
- if (!m_hideCursor && (!m_blinkPeriod || m_blinkStatus))
- textLayout()->drawCursor(painter, offset, cursor, m_cursorWidth);
- }
-}
-
-/*!
- \internal
-
- Sets the selection to cover the word at the given cursor position.
- The word boundaries are defined by the behavior of QTextLayout::SkipWords
- cursor mode.
-*/
-void QLineControl::selectWordAtPos(int cursor)
-{
- int next = cursor + 1;
- if(next > end())
- --next;
- int c = textLayout()->previousCursorPosition(next, QTextLayout::SkipWords);
- moveCursor(c, false);
- // ## text layout should support end of words.
- int end = textLayout()->nextCursorPosition(c, QTextLayout::SkipWords);
- while (end > cursor && m_text[end-1].isSpace())
- --end;
- moveCursor(end, true);
-}
-
-/*!
- \internal
-
- Completes a change to the line control text. If the change is not valid
- will undo the line control state back to the given \a validateFromState.
-
- If \a edited is true and the change is valid, will emit textEdited() in
- addition to textChanged(). Otherwise only emits textChanged() on a valid
- change.
-
- The \a update value is currently unused.
-*/
-bool QLineControl::finishChange(int validateFromState, bool update, bool edited)
-{
- Q_UNUSED(update)
- bool lineDirty = m_selDirty;
- if (m_textDirty) {
- // do validation
- bool wasValidInput = m_validInput;
- m_validInput = true;
-#ifndef QT_NO_VALIDATOR
- if (m_validator) {
- m_validInput = false;
- QString textCopy = m_text;
- int cursorCopy = m_cursor;
- m_validInput = (m_validator->validate(textCopy, cursorCopy) != QValidator::Invalid);
- if (m_validInput) {
- if (m_text != textCopy) {
- internalSetText(textCopy, cursorCopy);
- return true;
- }
- m_cursor = cursorCopy;
- }
- }
-#endif
- if (validateFromState >= 0 && wasValidInput && !m_validInput) {
- if (m_transactions.count())
- return false;
- internalUndo(validateFromState);
- m_history.resize(m_undoState);
- if (m_modifiedState > m_undoState)
- m_modifiedState = -1;
- m_validInput = true;
- m_textDirty = false;
- }
- updateDisplayText();
- lineDirty |= m_textDirty;
- if (m_textDirty) {
- m_textDirty = false;
- QString actualText = text();
- if (edited)
- emit textEdited(actualText);
- emit textChanged(actualText);
- }
- }
- if (m_selDirty) {
- m_selDirty = false;
- emit selectionChanged();
- }
- if (m_cursor == m_lastCursorPos)
- updateMicroFocus();
- emitCursorPositionChanged();
- return true;
-}
-
-/*!
- \internal
-
- An internal function for setting the text of the line control.
-*/
-void QLineControl::internalSetText(const QString &txt, int pos, bool edited)
-{
- cancelPasswordEchoTimer();
- internalDeselect();
- emit resetInputContext();
- QString oldText = m_text;
- if (m_maskData) {
- m_text = maskString(0, txt, true);
- m_text += clearString(m_text.length(), m_maxLength - m_text.length());
- } else {
- m_text = txt.isEmpty() ? txt : txt.left(m_maxLength);
- }
- m_history.clear();
- m_modifiedState = m_undoState = 0;
- m_cursor = (pos < 0 || pos > m_text.length()) ? m_text.length() : pos;
- m_textDirty = (oldText != m_text);
- bool changed = finishChange(-1, true, edited);
-
-#ifndef QT_NO_ACCESSIBILITY
- if (changed)
- QAccessible::updateAccessibility(parent(), 0, QAccessible::TextUpdated);
-#endif
-}
-
-
-/*!
- \internal
-
- Adds the given \a command to the undo history
- of the line control. Does not apply the command.
-*/
-void QLineControl::addCommand(const Command &cmd)
-{
- if (m_separator && m_undoState && m_history[m_undoState - 1].type != Separator) {
- m_history.resize(m_undoState + 2);
- m_history[m_undoState++] = Command(Separator, m_cursor, 0, m_selstart, m_selend);
- } else {
- m_history.resize(m_undoState + 1);
- }
- m_separator = false;
- m_history[m_undoState++] = cmd;
-}
-
-/*!
- \internal
-
- Inserts the given string \a s into the line
- control.
-
- Also adds the appropriate commands into the undo history.
- This function does not call finishChange(), and may leave the text
- in an invalid state.
-*/
-void QLineControl::internalInsert(const QString &s)
-{
-#ifdef QT_GUI_PASSWORD_ECHO_DELAY
- if (m_echoMode == QLineEdit::Password) {
- if (m_passwordEchoTimer != 0)
- killTimer(m_passwordEchoTimer);
- m_passwordEchoTimer = startTimer(qt_passwordEchoDelay);
- }
-#endif
- if (hasSelectedText())
- addCommand(Command(SetSelection, m_cursor, 0, m_selstart, m_selend));
- if (m_maskData) {
- QString ms = maskString(m_cursor, s);
- for (int i = 0; i < (int) ms.length(); ++i) {
- addCommand (Command(DeleteSelection, m_cursor + i, m_text.at(m_cursor + i), -1, -1));
- addCommand(Command(Insert, m_cursor + i, ms.at(i), -1, -1));
- }
- m_text.replace(m_cursor, ms.length(), ms);
- m_cursor += ms.length();
- m_cursor = nextMaskBlank(m_cursor);
- m_textDirty = true;
- } else {
- int remaining = m_maxLength - m_text.length();
- if (remaining != 0) {
- m_text.insert(m_cursor, s.left(remaining));
- for (int i = 0; i < (int) s.left(remaining).length(); ++i)
- addCommand(Command(Insert, m_cursor++, s.at(i), -1, -1));
- m_textDirty = true;
- }
- }
-}
-
-/*!
- \internal
-
- deletes a single character from the current text. If \a wasBackspace,
- the character prior to the cursor is removed. Otherwise the character
- after the cursor is removed.
-
- Also adds the appropriate commands into the undo history.
- This function does not call finishChange(), and may leave the text
- in an invalid state.
-*/
-void QLineControl::internalDelete(bool wasBackspace)
-{
- if (m_cursor < (int) m_text.length()) {
- cancelPasswordEchoTimer();
- if (hasSelectedText())
- addCommand(Command(SetSelection, m_cursor, 0, m_selstart, m_selend));
- addCommand(Command((CommandType)((m_maskData ? 2 : 0) + (wasBackspace ? Remove : Delete)),
- m_cursor, m_text.at(m_cursor), -1, -1));
- if (m_maskData) {
- m_text.replace(m_cursor, 1, clearString(m_cursor, 1));
- addCommand(Command(Insert, m_cursor, m_text.at(m_cursor), -1, -1));
- } else {
- m_text.remove(m_cursor, 1);
- }
- m_textDirty = true;
- }
-}
-
-/*!
- \internal
-
- removes the currently selected text from the line control.
-
- Also adds the appropriate commands into the undo history.
- This function does not call finishChange(), and may leave the text
- in an invalid state.
-*/
-void QLineControl::removeSelectedText()
-{
- if (m_selstart < m_selend && m_selend <= (int) m_text.length()) {
- cancelPasswordEchoTimer();
- separate();
- int i ;
- addCommand(Command(SetSelection, m_cursor, 0, m_selstart, m_selend));
- if (m_selstart <= m_cursor && m_cursor < m_selend) {
- // cursor is within the selection. Split up the commands
- // to be able to restore the correct cursor position
- for (i = m_cursor; i >= m_selstart; --i)
- addCommand (Command(DeleteSelection, i, m_text.at(i), -1, 1));
- for (i = m_selend - 1; i > m_cursor; --i)
- addCommand (Command(DeleteSelection, i - m_cursor + m_selstart - 1, m_text.at(i), -1, -1));
- } else {
- for (i = m_selend-1; i >= m_selstart; --i)
- addCommand (Command(RemoveSelection, i, m_text.at(i), -1, -1));
- }
- if (m_maskData) {
- m_text.replace(m_selstart, m_selend - m_selstart, clearString(m_selstart, m_selend - m_selstart));
- for (int i = 0; i < m_selend - m_selstart; ++i)
- addCommand(Command(Insert, m_selstart + i, m_text.at(m_selstart + i), -1, -1));
- } else {
- m_text.remove(m_selstart, m_selend - m_selstart);
- }
- if (m_cursor > m_selstart)
- m_cursor -= qMin(m_cursor, m_selend) - m_selstart;
- internalDeselect();
- m_textDirty = true;
- }
-}
-
-/*!
- \internal
-
- Parses the input mask specified by \a maskFields to generate
- the mask data used to handle input masks.
-*/
-void QLineControl::parseInputMask(const QString &maskFields)
-{
- int delimiter = maskFields.indexOf(QLatin1Char(';'));
- if (maskFields.isEmpty() || delimiter == 0) {
- if (m_maskData) {
- delete [] m_maskData;
- m_maskData = 0;
- m_maxLength = 32767;
- internalSetText(QString());
- }
- return;
- }
-
- if (delimiter == -1) {
- m_blank = QLatin1Char(' ');
- m_inputMask = maskFields;
- } else {
- m_inputMask = maskFields.left(delimiter);
- m_blank = (delimiter + 1 < maskFields.length()) ? maskFields[delimiter + 1] : QLatin1Char(' ');
- }
-
- // calculate m_maxLength / m_maskData length
- m_maxLength = 0;
- QChar c = 0;
- for (int i=0; i<m_inputMask.length(); i++) {
- c = m_inputMask.at(i);
- if (i > 0 && m_inputMask.at(i-1) == QLatin1Char('\\')) {
- m_maxLength++;
- continue;
- }
- if (c != QLatin1Char('\\') && c != QLatin1Char('!') &&
- c != QLatin1Char('<') && c != QLatin1Char('>') &&
- c != QLatin1Char('{') && c != QLatin1Char('}') &&
- c != QLatin1Char('[') && c != QLatin1Char(']'))
- m_maxLength++;
- }
-
- delete [] m_maskData;
- m_maskData = new MaskInputData[m_maxLength];
-
- MaskInputData::Casemode m = MaskInputData::NoCaseMode;
- c = 0;
- bool s;
- bool escape = false;
- int index = 0;
- for (int i = 0; i < m_inputMask.length(); i++) {
- c = m_inputMask.at(i);
- if (escape) {
- s = true;
- m_maskData[index].maskChar = c;
- m_maskData[index].separator = s;
- m_maskData[index].caseMode = m;
- index++;
- escape = false;
- } else if (c == QLatin1Char('<')) {
- m = MaskInputData::Lower;
- } else if (c == QLatin1Char('>')) {
- m = MaskInputData::Upper;
- } else if (c == QLatin1Char('!')) {
- m = MaskInputData::NoCaseMode;
- } else if (c != QLatin1Char('{') && c != QLatin1Char('}') && c != QLatin1Char('[') && c != QLatin1Char(']')) {
- switch (c.unicode()) {
- case 'A':
- case 'a':
- case 'N':
- case 'n':
- case 'X':
- case 'x':
- case '9':
- case '0':
- case 'D':
- case 'd':
- case '#':
- case 'H':
- case 'h':
- case 'B':
- case 'b':
- s = false;
- break;
- case '\\':
- escape = true;
- default:
- s = true;
- break;
- }
-
- if (!escape) {
- m_maskData[index].maskChar = c;
- m_maskData[index].separator = s;
- m_maskData[index].caseMode = m;
- index++;
- }
- }
- }
- internalSetText(m_text);
-}
-
-
-/*!
- \internal
-
- checks if the key is valid compared to the inputMask
-*/
-bool QLineControl::isValidInput(QChar key, QChar mask) const
-{
- switch (mask.unicode()) {
- case 'A':
- if (key.isLetter())
- return true;
- break;
- case 'a':
- if (key.isLetter() || key == m_blank)
- return true;
- break;
- case 'N':
- if (key.isLetterOrNumber())
- return true;
- break;
- case 'n':
- if (key.isLetterOrNumber() || key == m_blank)
- return true;
- break;
- case 'X':
- if (key.isPrint())
- return true;
- break;
- case 'x':
- if (key.isPrint() || key == m_blank)
- return true;
- break;
- case '9':
- if (key.isNumber())
- return true;
- break;
- case '0':
- if (key.isNumber() || key == m_blank)
- return true;
- break;
- case 'D':
- if (key.isNumber() && key.digitValue() > 0)
- return true;
- break;
- case 'd':
- if ((key.isNumber() && key.digitValue() > 0) || key == m_blank)
- return true;
- break;
- case '#':
- if (key.isNumber() || key == QLatin1Char('+') || key == QLatin1Char('-') || key == m_blank)
- return true;
- break;
- case 'B':
- if (key == QLatin1Char('0') || key == QLatin1Char('1'))
- return true;
- break;
- case 'b':
- if (key == QLatin1Char('0') || key == QLatin1Char('1') || key == m_blank)
- return true;
- break;
- case 'H':
- if (key.isNumber() || (key >= QLatin1Char('a') && key <= QLatin1Char('f')) || (key >= QLatin1Char('A') && key <= QLatin1Char('F')))
- return true;
- break;
- case 'h':
- if (key.isNumber() || (key >= QLatin1Char('a') && key <= QLatin1Char('f')) || (key >= QLatin1Char('A') && key <= QLatin1Char('F')) || key == m_blank)
- return true;
- break;
- default:
- break;
- }
- return false;
-}
-
-/*!
- \internal
-
- Returns true if the given text \a str is valid for any
- validator or input mask set for the line control.
-
- Otherwise returns false
-*/
-bool QLineControl::hasAcceptableInput(const QString &str) const
-{
-#ifndef QT_NO_VALIDATOR
- QString textCopy = str;
- int cursorCopy = m_cursor;
- if (m_validator && m_validator->validate(textCopy, cursorCopy)
- != QValidator::Acceptable)
- return false;
-#endif
-
- if (!m_maskData)
- return true;
-
- if (str.length() != m_maxLength)
- return false;
-
- for (int i=0; i < m_maxLength; ++i) {
- if (m_maskData[i].separator) {
- if (str.at(i) != m_maskData[i].maskChar)
- return false;
- } else {
- if (!isValidInput(str.at(i), m_maskData[i].maskChar))
- return false;
- }
- }
- return true;
-}
-
-/*!
- \internal
-
- Applies the inputMask on \a str starting from position \a pos in the mask. \a clear
- specifies from where characters should be gotten when a separator is met in \a str - true means
- that blanks will be used, false that previous input is used.
- Calling this when no inputMask is set is undefined.
-*/
-QString QLineControl::maskString(uint pos, const QString &str, bool clear) const
-{
- if (pos >= (uint)m_maxLength)
- return QString::fromLatin1("");
-
- QString fill;
- fill = clear ? clearString(0, m_maxLength) : m_text;
-
- int strIndex = 0;
- QString s = QString::fromLatin1("");
- int i = pos;
- while (i < m_maxLength) {
- if (strIndex < str.length()) {
- if (m_maskData[i].separator) {
- s += m_maskData[i].maskChar;
- if (str[(int)strIndex] == m_maskData[i].maskChar)
- strIndex++;
- ++i;
- } else {
- if (isValidInput(str[(int)strIndex], m_maskData[i].maskChar)) {
- switch (m_maskData[i].caseMode) {
- case MaskInputData::Upper:
- s += str[(int)strIndex].toUpper();
- break;
- case MaskInputData::Lower:
- s += str[(int)strIndex].toLower();
- break;
- default:
- s += str[(int)strIndex];
- }
- ++i;
- } else {
- // search for separator first
- int n = findInMask(i, true, true, str[(int)strIndex]);
- if (n != -1) {
- if (str.length() != 1 || i == 0 || (i > 0 && (!m_maskData[i-1].separator || m_maskData[i-1].maskChar != str[(int)strIndex]))) {
- s += fill.mid(i, n-i+1);
- i = n + 1; // update i to find + 1
- }
- } else {
- // search for valid m_blank if not
- n = findInMask(i, true, false, str[(int)strIndex]);
- if (n != -1) {
- s += fill.mid(i, n-i);
- switch (m_maskData[n].caseMode) {
- case MaskInputData::Upper:
- s += str[(int)strIndex].toUpper();
- break;
- case MaskInputData::Lower:
- s += str[(int)strIndex].toLower();
- break;
- default:
- s += str[(int)strIndex];
- }
- i = n + 1; // updates i to find + 1
- }
- }
- }
- ++strIndex;
- }
- } else
- break;
- }
-
- return s;
-}
-
-
-
-/*!
- \internal
-
- Returns a "cleared" string with only separators and blank chars.
- Calling this when no inputMask is set is undefined.
-*/
-QString QLineControl::clearString(uint pos, uint len) const
-{
- if (pos >= (uint)m_maxLength)
- return QString();
-
- QString s;
- int end = qMin((uint)m_maxLength, pos + len);
- for (int i = pos; i < end; ++i)
- if (m_maskData[i].separator)
- s += m_maskData[i].maskChar;
- else
- s += m_blank;
-
- return s;
-}
-
-/*!
- \internal
-
- Strips blank parts of the input in a QLineControl when an inputMask is set,
- separators are still included. Typically "127.0__.0__.1__" becomes "127.0.0.1".
-*/
-QString QLineControl::stripString(const QString &str) const
-{
- if (!m_maskData)
- return str;
-
- QString s;
- int end = qMin(m_maxLength, (int)str.length());
- for (int i = 0; i < end; ++i)
- if (m_maskData[i].separator)
- s += m_maskData[i].maskChar;
- else
- if (str[i] != m_blank)
- s += str[i];
-
- return s;
-}
-
-/*!
- \internal
- searches forward/backward in m_maskData for either a separator or a m_blank
-*/
-int QLineControl::findInMask(int pos, bool forward, bool findSeparator, QChar searchChar) const
-{
- if (pos >= m_maxLength || pos < 0)
- return -1;
-
- int end = forward ? m_maxLength : -1;
- int step = forward ? 1 : -1;
- int i = pos;
-
- while (i != end) {
- if (findSeparator) {
- if (m_maskData[i].separator && m_maskData[i].maskChar == searchChar)
- return i;
- } else {
- if (!m_maskData[i].separator) {
- if (searchChar.isNull())
- return i;
- else if (isValidInput(searchChar, m_maskData[i].maskChar))
- return i;
- }
- }
- i += step;
- }
- return -1;
-}
-
-void QLineControl::internalUndo(int until)
-{
- if (!isUndoAvailable())
- return;
- cancelPasswordEchoTimer();
- internalDeselect();
- while (m_undoState && m_undoState > until) {
- Command& cmd = m_history[--m_undoState];
- switch (cmd.type) {
- case Insert:
- m_text.remove(cmd.pos, 1);
- m_cursor = cmd.pos;
- break;
- case SetSelection:
- m_selstart = cmd.selStart;
- m_selend = cmd.selEnd;
- m_cursor = cmd.pos;
- break;
- case Remove:
- case RemoveSelection:
- m_text.insert(cmd.pos, cmd.uc);
- m_cursor = cmd.pos + 1;
- break;
- case Delete:
- case DeleteSelection:
- m_text.insert(cmd.pos, cmd.uc);
- m_cursor = cmd.pos;
- break;
- case Separator:
- continue;
- }
- if (until < 0 && m_undoState) {
- Command& next = m_history[m_undoState-1];
- if (next.type != cmd.type && next.type < RemoveSelection
- && (cmd.type < RemoveSelection || next.type == Separator))
- break;
- }
- }
- m_textDirty = true;
- emitCursorPositionChanged();
-}
-
-void QLineControl::internalRedo()
-{
- if (!isRedoAvailable())
- return;
- internalDeselect();
- while (m_undoState < (int)m_history.size()) {
- Command& cmd = m_history[m_undoState++];
- switch (cmd.type) {
- case Insert:
- m_text.insert(cmd.pos, cmd.uc);
- m_cursor = cmd.pos + 1;
- break;
- case SetSelection:
- m_selstart = cmd.selStart;
- m_selend = cmd.selEnd;
- m_cursor = cmd.pos;
- break;
- case Remove:
- case Delete:
- case RemoveSelection:
- case DeleteSelection:
- m_text.remove(cmd.pos, 1);
- m_selstart = cmd.selStart;
- m_selend = cmd.selEnd;
- m_cursor = cmd.pos;
- break;
- case Separator:
- m_selstart = cmd.selStart;
- m_selend = cmd.selEnd;
- m_cursor = cmd.pos;
- break;
- }
- if (m_undoState < (int)m_history.size()) {
- Command& next = m_history[m_undoState];
- if (next.type != cmd.type && cmd.type < RemoveSelection && next.type != Separator
- && (next.type < RemoveSelection || cmd.type == Separator))
- break;
- }
- }
- m_textDirty = true;
- emitCursorPositionChanged();
-}
-
-/*!
- \internal
-
- If the current cursor position differs from the last emitted cursor
- position, emits cursorPositionChanged().
-*/
-void QLineControl::emitCursorPositionChanged()
-{
- if (m_cursor != m_lastCursorPos) {
- const int oldLast = m_lastCursorPos;
- m_lastCursorPos = m_cursor;
- cursorPositionChanged(oldLast, m_cursor);
-#ifndef QT_NO_ACCESSIBILITY
- QAccessible::updateAccessibility(parent(), 0, QAccessible::TextCaretMoved);
-#endif
- }
-}
-
-#ifndef QT_NO_COMPLETER
-// iterating forward(dir=1)/backward(dir=-1) from the
-// current row based. dir=0 indicates a new completion prefix was set.
-bool QLineControl::advanceToEnabledItem(int dir)
-{
- int start = m_completer->currentRow();
- if (start == -1)
- return false;
- int i = start + dir;
- if (dir == 0) dir = 1;
- do {
- if (!m_completer->setCurrentRow(i)) {
- if (!m_completer->wrapAround())
- break;
- i = i > 0 ? 0 : m_completer->completionCount() - 1;
- } else {
- QModelIndex currentIndex = m_completer->currentIndex();
- if (m_completer->completionModel()->flags(currentIndex) & Qt::ItemIsEnabled)
- return true;
- i += dir;
- }
- } while (i != start);
-
- m_completer->setCurrentRow(start); // restore
- return false;
-}
-
-void QLineControl::complete(int key)
-{
- if (!m_completer || isReadOnly() || echoMode() != QLineEdit::Normal)
- return;
-
- QString text = this->text();
- if (m_completer->completionMode() == QCompleter::InlineCompletion) {
- if (key == Qt::Key_Backspace)
- return;
- int n = 0;
- if (key == Qt::Key_Up || key == Qt::Key_Down) {
- if (textAfterSelection().length())
- return;
- QString prefix = hasSelectedText() ? textBeforeSelection()
- : text;
- if (text.compare(m_completer->currentCompletion(), m_completer->caseSensitivity()) != 0
- || prefix.compare(m_completer->completionPrefix(), m_completer->caseSensitivity()) != 0) {
- m_completer->setCompletionPrefix(prefix);
- } else {
- n = (key == Qt::Key_Up) ? -1 : +1;
- }
- } else {
- m_completer->setCompletionPrefix(text);
- }
- if (!advanceToEnabledItem(n))
- return;
- } else {
-#ifndef QT_KEYPAD_NAVIGATION
- if (text.isEmpty()) {
- m_completer->popup()->hide();
- return;
- }
-#endif
- m_completer->setCompletionPrefix(text);
- }
-
- m_completer->complete();
-}
-#endif
-
-void QLineControl::setCursorBlinkPeriod(int msec)
-{
- if (msec == m_blinkPeriod)
- return;
- if (m_blinkTimer) {
- killTimer(m_blinkTimer);
- }
- if (msec) {
- m_blinkTimer = startTimer(msec / 2);
- m_blinkStatus = 1;
- } else {
- m_blinkTimer = 0;
- if (m_blinkStatus == 1)
- emit updateNeeded(inputMask().isEmpty() ? cursorRect() : QRect());
- }
- m_blinkPeriod = msec;
-}
-
-void QLineControl::resetCursorBlinkTimer()
-{
- if (m_blinkPeriod == 0 || m_blinkTimer == 0)
- return;
- killTimer(m_blinkTimer);
- m_blinkTimer = startTimer(m_blinkPeriod / 2);
- m_blinkStatus = 1;
-}
-
-void QLineControl::timerEvent(QTimerEvent *event)
-{
- if (event->timerId() == m_blinkTimer) {
- m_blinkStatus = !m_blinkStatus;
- emit updateNeeded(inputMask().isEmpty() ? cursorRect() : QRect());
- } else if (event->timerId() == m_deleteAllTimer) {
- killTimer(m_deleteAllTimer);
- m_deleteAllTimer = 0;
- clear();
- } else if (event->timerId() == m_tripleClickTimer) {
- killTimer(m_tripleClickTimer);
- m_tripleClickTimer = 0;
-#ifdef QT_GUI_PASSWORD_ECHO_DELAY
- } else if (event->timerId() == m_passwordEchoTimer) {
- killTimer(m_passwordEchoTimer);
- m_passwordEchoTimer = 0;
- updateDisplayText();
-#endif
- }
-}
-
-bool QLineControl::processEvent(QEvent* ev)
-{
-#ifdef QT_KEYPAD_NAVIGATION
- if (QApplication::keypadNavigationEnabled()) {
- if ((ev->type() == QEvent::KeyPress) || (ev->type() == QEvent::KeyRelease)) {
- QKeyEvent *ke = (QKeyEvent *)ev;
- if (ke->key() == Qt::Key_Back) {
- if (ke->isAutoRepeat()) {
- // Swallow it. We don't want back keys running amok.
- ke->accept();
- return true;
- }
- if ((ev->type() == QEvent::KeyRelease)
- && !isReadOnly()
- && m_deleteAllTimer) {
- killTimer(m_deleteAllTimer);
- m_deleteAllTimer = 0;
- backspace();
- ke->accept();
- return true;
- }
- }
- }
- }
-#endif
- switch(ev->type()){
-#ifndef QT_NO_GRAPHICSVIEW
- case QEvent::GraphicsSceneMouseDoubleClick:
- case QEvent::GraphicsSceneMouseMove:
- case QEvent::GraphicsSceneMouseRelease:
- case QEvent::GraphicsSceneMousePress:{
- QGraphicsSceneMouseEvent *gvEv = static_cast<QGraphicsSceneMouseEvent*>(ev);
- QMouseEvent mouse(ev->type(),
- gvEv->pos().toPoint(), gvEv->button(), gvEv->buttons(), gvEv->modifiers());
- processMouseEvent(&mouse); break;
- }
-#endif
- case QEvent::MouseButtonPress:
- case QEvent::MouseButtonRelease:
- case QEvent::MouseButtonDblClick:
- case QEvent::MouseMove:
- processMouseEvent(static_cast<QMouseEvent*>(ev)); break;
- case QEvent::KeyPress:
- case QEvent::KeyRelease:
- processKeyEvent(static_cast<QKeyEvent*>(ev)); break;
- case QEvent::InputMethod:
- processInputMethodEvent(static_cast<QInputMethodEvent*>(ev)); break;
-#ifndef QT_NO_SHORTCUT
- case QEvent::ShortcutOverride:{
- if (isReadOnly())
- return false;
- QKeyEvent* ke = static_cast<QKeyEvent*>(ev);
- if (ke == QKeySequence::Copy
- || ke == QKeySequence::Paste
- || ke == QKeySequence::Cut
- || ke == QKeySequence::Redo
- || ke == QKeySequence::Undo
- || ke == QKeySequence::MoveToNextWord
- || ke == QKeySequence::MoveToPreviousWord
- || ke == QKeySequence::MoveToStartOfDocument
- || ke == QKeySequence::MoveToEndOfDocument
- || ke == QKeySequence::SelectNextWord
- || ke == QKeySequence::SelectPreviousWord
- || ke == QKeySequence::SelectStartOfLine
- || ke == QKeySequence::SelectEndOfLine
- || ke == QKeySequence::SelectStartOfBlock
- || ke == QKeySequence::SelectEndOfBlock
- || ke == QKeySequence::SelectStartOfDocument
- || ke == QKeySequence::SelectAll
- || ke == QKeySequence::SelectEndOfDocument) {
- ke->accept();
- } else if (ke->modifiers() == Qt::NoModifier || ke->modifiers() == Qt::ShiftModifier
- || ke->modifiers() == Qt::KeypadModifier) {
- if (ke->key() < Qt::Key_Escape) {
- ke->accept();
- } else {
- switch (ke->key()) {
- case Qt::Key_Delete:
- case Qt::Key_Home:
- case Qt::Key_End:
- case Qt::Key_Backspace:
- case Qt::Key_Left:
- case Qt::Key_Right:
- ke->accept();
- default:
- break;
- }
- }
- }
- }
-#endif
- default:
- return false;
- }
- return true;
-}
-
-void QLineControl::processMouseEvent(QMouseEvent* ev)
-{
-
- switch (ev->type()) {
- case QEvent::GraphicsSceneMousePress:
- case QEvent::MouseButtonPress:{
- if (m_tripleClickTimer
- && (ev->pos() - m_tripleClick).manhattanLength()
- < QApplication::startDragDistance()) {
- selectAll();
- return;
- }
- if (ev->button() == Qt::RightButton)
- return;
-
- bool mark = ev->modifiers() & Qt::ShiftModifier;
- int cursor = xToPos(ev->pos().x());
- moveCursor(cursor, mark);
- break;
- }
- case QEvent::GraphicsSceneMouseDoubleClick:
- case QEvent::MouseButtonDblClick:
- if (ev->button() == Qt::LeftButton) {
- selectWordAtPos(xToPos(ev->pos().x()));
- if (m_tripleClickTimer)
- killTimer(m_tripleClickTimer);
- m_tripleClickTimer = startTimer(QApplication::doubleClickInterval());
- m_tripleClick = ev->pos();
- }
- break;
- case QEvent::GraphicsSceneMouseRelease:
- case QEvent::MouseButtonRelease:
-#ifndef QT_NO_CLIPBOARD
- if (QApplication::clipboard()->supportsSelection()) {
- if (ev->button() == Qt::LeftButton) {
- copy(QClipboard::Selection);
- } else if (!isReadOnly() && ev->button() == Qt::MidButton) {
- deselect();
- insert(QApplication::clipboard()->text(QClipboard::Selection));
- }
- }
-#endif
- break;
- case QEvent::GraphicsSceneMouseMove:
- case QEvent::MouseMove:
- if (ev->buttons() & Qt::LeftButton) {
- moveCursor(xToPos(ev->pos().x()), true);
- }
- break;
- default:
- break;
- }
-}
-
-void QLineControl::processKeyEvent(QKeyEvent* event)
-{
- bool inlineCompletionAccepted = false;
-
-#ifndef QT_NO_COMPLETER
- if (m_completer) {
- QCompleter::CompletionMode completionMode = m_completer->completionMode();
- if ((completionMode == QCompleter::PopupCompletion
- || completionMode == QCompleter::UnfilteredPopupCompletion)
- && m_completer->popup()
- && m_completer->popup()->isVisible()) {
- // The following keys are forwarded by the completer to the widget
- // Ignoring the events lets the completer provide suitable default behavior
- switch (event->key()) {
- case Qt::Key_Escape:
- event->ignore();
- return;
- case Qt::Key_Enter:
- case Qt::Key_Return:
- case Qt::Key_F4:
-#ifdef QT_KEYPAD_NAVIGATION
- case Qt::Key_Select:
- if (!QApplication::keypadNavigationEnabled())
- break;
-#endif
- m_completer->popup()->hide(); // just hide. will end up propagating to parent
- default:
- break; // normal key processing
- }
- } else if (completionMode == QCompleter::InlineCompletion) {
- switch (event->key()) {
- case Qt::Key_Enter:
- case Qt::Key_Return:
- case Qt::Key_F4:
-#ifdef QT_KEYPAD_NAVIGATION
- case Qt::Key_Select:
- if (!QApplication::keypadNavigationEnabled())
- break;
-#endif
- if (!m_completer->currentCompletion().isEmpty() && hasSelectedText()
- && textAfterSelection().isEmpty()) {
- setText(m_completer->currentCompletion());
- inlineCompletionAccepted = true;
- }
- default:
- break; // normal key processing
- }
- }
- }
-#endif // QT_NO_COMPLETER
-
- if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) {
- if (hasAcceptableInput() || fixup()) {
- emit accepted();
- emit editingFinished();
- }
- if (inlineCompletionAccepted)
- event->accept();
- else
- event->ignore();
- return;
- }
-
- if (echoMode() == QLineEdit::PasswordEchoOnEdit
- && !passwordEchoEditing()
- && !isReadOnly()
- && !event->text().isEmpty()
-#ifdef QT_KEYPAD_NAVIGATION
- && event->key() != Qt::Key_Select
- && event->key() != Qt::Key_Up
- && event->key() != Qt::Key_Down
- && event->key() != Qt::Key_Back
-#endif
- && !(event->modifiers() & Qt::ControlModifier)) {
- // Clear the edit and reset to normal echo mode while editing; the
- // echo mode switches back when the edit loses focus
- // ### resets current content. dubious code; you can
- // navigate with keys up, down, back, and select(?), but if you press
- // "left" or "right" it clears?
- updatePasswordEchoEditing(true);
- clear();
- }
-
- bool unknown = false;
- bool visual = cursorMoveStyle() == Qt::VisualMoveStyle;
-
- if (false) {
- }
-#ifndef QT_NO_SHORTCUT
- else if (event == QKeySequence::Undo) {
- if (!isReadOnly())
- undo();
- }
- else if (event == QKeySequence::Redo) {
- if (!isReadOnly())
- redo();
- }
- else if (event == QKeySequence::SelectAll) {
- selectAll();
- }
-#ifndef QT_NO_CLIPBOARD
- else if (event == QKeySequence::Copy) {
- copy();
- }
- else if (event == QKeySequence::Paste) {
- if (!isReadOnly()) {
- QClipboard::Mode mode = QClipboard::Clipboard;
-#ifdef Q_WS_X11
- if (event->modifiers() == (Qt::CTRL | Qt::SHIFT) && event->key() == Qt::Key_Insert)
- mode = QClipboard::Selection;
-#endif
- paste(mode);
- }
- }
- else if (event == QKeySequence::Cut) {
- if (!isReadOnly()) {
- copy();
- del();
- }
- }
- else if (event == QKeySequence::DeleteEndOfLine) {
- if (!isReadOnly()) {
- setSelection(cursor(), end());
- copy();
- del();
- }
- }
-#endif //QT_NO_CLIPBOARD
- else if (event == QKeySequence::MoveToStartOfLine || event == QKeySequence::MoveToStartOfBlock) {
- home(0);
- }
- else if (event == QKeySequence::MoveToEndOfLine || event == QKeySequence::MoveToEndOfBlock) {
- end(0);
- }
- else if (event == QKeySequence::SelectStartOfLine || event == QKeySequence::SelectStartOfBlock) {
- home(1);
- }
- else if (event == QKeySequence::SelectEndOfLine || event == QKeySequence::SelectEndOfBlock) {
- end(1);
- }
- else if (event == QKeySequence::MoveToNextChar) {
-#if !defined(Q_WS_WIN) || defined(QT_NO_COMPLETER)
- if (hasSelectedText()) {
-#else
- if (hasSelectedText() && m_completer
- && m_completer->completionMode() == QCompleter::InlineCompletion) {
-#endif
- moveCursor(selectionEnd(), false);
- } else {
- cursorForward(0, visual ? 1 : (layoutDirection() == Qt::LeftToRight ? 1 : -1));
- }
- }
- else if (event == QKeySequence::SelectNextChar) {
- cursorForward(1, visual ? 1 : (layoutDirection() == Qt::LeftToRight ? 1 : -1));
- }
- else if (event == QKeySequence::MoveToPreviousChar) {
-#if !defined(Q_WS_WIN) || defined(QT_NO_COMPLETER)
- if (hasSelectedText()) {
-#else
- if (hasSelectedText() && m_completer
- && m_completer->completionMode() == QCompleter::InlineCompletion) {
-#endif
- moveCursor(selectionStart(), false);
- } else {
- cursorForward(0, visual ? -1 : (layoutDirection() == Qt::LeftToRight ? -1 : 1));
- }
- }
- else if (event == QKeySequence::SelectPreviousChar) {
- cursorForward(1, visual ? -1 : (layoutDirection() == Qt::LeftToRight ? -1 : 1));
- }
- else if (event == QKeySequence::MoveToNextWord) {
- if (echoMode() == QLineEdit::Normal)
- layoutDirection() == Qt::LeftToRight ? cursorWordForward(0) : cursorWordBackward(0);
- else
- layoutDirection() == Qt::LeftToRight ? end(0) : home(0);
- }
- else if (event == QKeySequence::MoveToPreviousWord) {
- if (echoMode() == QLineEdit::Normal)
- layoutDirection() == Qt::LeftToRight ? cursorWordBackward(0) : cursorWordForward(0);
- else if (!isReadOnly()) {
- layoutDirection() == Qt::LeftToRight ? home(0) : end(0);
- }
- }
- else if (event == QKeySequence::SelectNextWord) {
- if (echoMode() == QLineEdit::Normal)
- layoutDirection() == Qt::LeftToRight ? cursorWordForward(1) : cursorWordBackward(1);
- else
- layoutDirection() == Qt::LeftToRight ? end(1) : home(1);
- }
- else if (event == QKeySequence::SelectPreviousWord) {
- if (echoMode() == QLineEdit::Normal)
- layoutDirection() == Qt::LeftToRight ? cursorWordBackward(1) : cursorWordForward(1);
- else
- layoutDirection() == Qt::LeftToRight ? home(1) : end(1);
- }
- else if (event == QKeySequence::Delete) {
- if (!isReadOnly())
- del();
- }
- else if (event == QKeySequence::DeleteEndOfWord) {
- if (!isReadOnly()) {
- cursorWordForward(true);
- del();
- }
- }
- else if (event == QKeySequence::DeleteStartOfWord) {
- if (!isReadOnly()) {
- cursorWordBackward(true);
- del();
- }
- }
-#endif // QT_NO_SHORTCUT
- else {
- bool handled = false;
-#ifdef Q_WS_MAC
- if (event->key() == Qt::Key_Up || event->key() == Qt::Key_Down) {
- Qt::KeyboardModifiers myModifiers = (event->modifiers() & ~Qt::KeypadModifier);
- if (myModifiers & Qt::ShiftModifier) {
- if (myModifiers == (Qt::ControlModifier|Qt::ShiftModifier)
- || myModifiers == (Qt::AltModifier|Qt::ShiftModifier)
- || myModifiers == Qt::ShiftModifier) {
-
- event->key() == Qt::Key_Up ? home(1) : end(1);
- }
- } else {
- if ((myModifiers == Qt::ControlModifier
- || myModifiers == Qt::AltModifier
- || myModifiers == Qt::NoModifier)) {
- event->key() == Qt::Key_Up ? home(0) : end(0);
- }
- }
- handled = true;
- }
-#endif
- if (event->modifiers() & Qt::ControlModifier) {
- switch (event->key()) {
- case Qt::Key_Backspace:
- if (!isReadOnly()) {
- cursorWordBackward(true);
- del();
- }
- break;
-#ifndef QT_NO_COMPLETER
- case Qt::Key_Up:
- case Qt::Key_Down:
- complete(event->key());
- break;
-#endif
-#if defined(Q_WS_X11)
- case Qt::Key_E:
- end(0);
- break;
-
- case Qt::Key_U:
- if (!isReadOnly()) {
- setSelection(0, text().size());
-#ifndef QT_NO_CLIPBOARD
- copy();
-#endif
- del();
- }
- break;
-#endif
- default:
- if (!handled)
- unknown = true;
- }
- } else { // ### check for *no* modifier
- switch (event->key()) {
- case Qt::Key_Backspace:
- if (!isReadOnly()) {
- backspace();
-#ifndef QT_NO_COMPLETER
- complete(Qt::Key_Backspace);
-#endif
- }
- break;
-#ifdef QT_KEYPAD_NAVIGATION
- case Qt::Key_Back:
- if (QApplication::keypadNavigationEnabled() && !event->isAutoRepeat()
- && !isReadOnly()) {
- if (text().length() == 0) {
- setText(m_cancelText);
-
- if (passwordEchoEditing())
- updatePasswordEchoEditing(false);
-
- emit editFocusChange(false);
- } else if (!m_deleteAllTimer) {
- m_deleteAllTimer = startTimer(750);
- }
- } else {
- unknown = true;
- }
- break;
-#endif
- default:
- if (!handled)
- unknown = true;
- }
- }
- }
-
- if (event->key() == Qt::Key_Direction_L || event->key() == Qt::Key_Direction_R) {
- setLayoutDirection((event->key() == Qt::Key_Direction_L) ? Qt::LeftToRight : Qt::RightToLeft);
- unknown = false;
- }
-
- if (unknown && !isReadOnly()) {
- QString t = event->text();
- if (!t.isEmpty() && t.at(0).isPrint()) {
- insert(t);
-#ifndef QT_NO_COMPLETER
- complete(event->key());
-#endif
- event->accept();
- return;
- }
- }
-
- if (unknown)
- event->ignore();
- else
- event->accept();
-}
-
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/gui/widgets/qlinecontrol_p.h b/src/gui/widgets/qlinecontrol_p.h
deleted file mode 100644
index d4c4154b3d..0000000000
--- a/src/gui/widgets/qlinecontrol_p.h
+++ /dev/null
@@ -1,514 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QLINECONTROL_P_H
-#define QLINECONTROL_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "QtCore/qglobal.h"
-
-#ifndef QT_NO_LINEEDIT
-#include "private/qwidget_p.h"
-#include "QtGui/qlineedit.h"
-#include "QtGui/qtextlayout.h"
-#include "QtGui/qstyleoption.h"
-#include "QtCore/qpointer.h"
-#include "QtGui/qclipboard.h"
-#include "QtCore/qpoint.h"
-#include "QtGui/qcompleter.h"
-#include "QtGui/qaccessible.h"
-#include "QtCore/qthread.h"
-
-#include "qplatformdefs.h"
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class Q_GUI_EXPORT QLineControl : public QObject
-{
- Q_OBJECT
-
-public:
- QLineControl(const QString &txt = QString())
- : m_cursor(0), m_preeditCursor(0), m_cursorWidth(0), m_layoutDirection(Qt::LayoutDirectionAuto),
- m_hideCursor(false), m_separator(0), m_readOnly(0),
- m_dragEnabled(0), m_echoMode(0), m_textDirty(0), m_selDirty(0),
- m_validInput(1), m_blinkStatus(0), m_blinkPeriod(0), m_blinkTimer(0), m_deleteAllTimer(0),
- m_ascent(0), m_maxLength(32767), m_lastCursorPos(-1),
- m_tripleClickTimer(0), m_maskData(0), m_modifiedState(0), m_undoState(0),
- m_selstart(0), m_selend(0), m_passwordEchoEditing(false)
-#ifdef QT_GUI_PASSWORD_ECHO_DELAY
- , m_passwordEchoTimer(0)
-#endif
-#if defined(Q_WS_MAC)
- , m_threadChecks(false)
- , m_textLayoutThread(0)
- #endif
- {
- init(txt);
- }
-
- ~QLineControl()
- {
- delete [] m_maskData;
- }
-
- int nextMaskBlank(int pos)
- {
- int c = findInMask(pos, true, false);
- m_separator |= (c != pos);
- return (c != -1 ? c : m_maxLength);
- }
-
- int prevMaskBlank(int pos)
- {
- int c = findInMask(pos, false, false);
- m_separator |= (c != pos);
- return (c != -1 ? c : 0);
- }
-
- bool isUndoAvailable() const { return !m_readOnly && m_undoState; }
- bool isRedoAvailable() const { return !m_readOnly && m_undoState < (int)m_history.size(); }
- void clearUndo() { m_history.clear(); m_modifiedState = m_undoState = 0; }
-
- bool isModified() const { return m_modifiedState != m_undoState; }
- void setModified(bool modified) { m_modifiedState = modified ? -1 : m_undoState; }
-
- bool allSelected() const { return !m_text.isEmpty() && m_selstart == 0 && m_selend == (int)m_text.length(); }
- bool hasSelectedText() const { return !m_text.isEmpty() && m_selend > m_selstart; }
-
- int width() const { return qRound(m_textLayout.lineAt(0).width()) + 1; }
- int height() const { return qRound(m_textLayout.lineAt(0).height()) + 1; }
- int ascent() const { return m_ascent; }
- qreal naturalTextWidth() const { return m_textLayout.lineAt(0).naturalTextWidth(); }
-
- void setSelection(int start, int length);
-
- inline QString selectedText() const { return hasSelectedText() ? m_text.mid(m_selstart, m_selend - m_selstart) : QString(); }
- QString textBeforeSelection() const { return hasSelectedText() ? m_text.left(m_selstart) : QString(); }
- QString textAfterSelection() const { return hasSelectedText() ? m_text.mid(m_selend) : QString(); }
-
- int selectionStart() const { return hasSelectedText() ? m_selstart : -1; }
- int selectionEnd() const { return hasSelectedText() ? m_selend : -1; }
- bool inSelection(int x) const
- {
- if (m_selstart >= m_selend)
- return false;
- int pos = xToPos(x, QTextLine::CursorOnCharacter);
- return pos >= m_selstart && pos < m_selend;
- }
-
- void removeSelection()
- {
- int priorState = m_undoState;
- removeSelectedText();
- finishChange(priorState);
- }
-
- int start() const { return 0; }
- int end() const { return m_text.length(); }
-
-#ifndef QT_NO_CLIPBOARD
- void copy(QClipboard::Mode mode = QClipboard::Clipboard) const;
- void paste(QClipboard::Mode mode = QClipboard::Clipboard);
-#endif
-
- int cursor() const{ return m_cursor; }
- int preeditCursor() const { return m_preeditCursor; }
-
- int cursorWidth() const { return m_cursorWidth; }
- void setCursorWidth(int value) { m_cursorWidth = value; }
-
- Qt::CursorMoveStyle cursorMoveStyle() const { return m_textLayout.cursorMoveStyle(); }
- void setCursorMoveStyle(Qt::CursorMoveStyle style) { m_textLayout.setCursorMoveStyle(style); }
-
- void moveCursor(int pos, bool mark = false);
- void cursorForward(bool mark, int steps)
- {
- int c = m_cursor;
- if (steps > 0) {
- while (steps--)
- c = cursorMoveStyle() == Qt::VisualMoveStyle ? m_textLayout.rightCursorPosition(c)
- : m_textLayout.nextCursorPosition(c);
- } else if (steps < 0) {
- while (steps++)
- c = cursorMoveStyle() == Qt::VisualMoveStyle ? m_textLayout.leftCursorPosition(c)
- : m_textLayout.previousCursorPosition(c);
- }
- moveCursor(c, mark);
- }
-
- void cursorWordForward(bool mark) { moveCursor(m_textLayout.nextCursorPosition(m_cursor, QTextLayout::SkipWords), mark); }
- void cursorWordBackward(bool mark) { moveCursor(m_textLayout.previousCursorPosition(m_cursor, QTextLayout::SkipWords), mark); }
-
- void home(bool mark) { moveCursor(0, mark); }
- void end(bool mark) { moveCursor(text().length(), mark); }
-
- int xToPos(int x, QTextLine::CursorPosition = QTextLine::CursorBetweenCharacters) const;
- QRect cursorRect() const;
-
- qreal cursorToX(int cursor) const { return m_textLayout.lineAt(0).cursorToX(cursor); }
- qreal cursorToX() const
- {
- int cursor = m_cursor;
- if (m_preeditCursor != -1)
- cursor += m_preeditCursor;
- return cursorToX(cursor);
- }
-
- bool isReadOnly() const { return m_readOnly; }
- void setReadOnly(bool enable) { m_readOnly = enable; }
-
- QString text() const
- {
- QString res = m_maskData ? stripString(m_text) : m_text;
- return (res.isNull() ? QString::fromLatin1("") : res);
- }
- void setText(const QString &txt) { internalSetText(txt, -1, false); }
- QString displayText() const { return m_textLayout.text(); }
-
- void backspace();
- void del();
- void deselect() { internalDeselect(); finishChange(); }
- void selectAll() { m_selstart = m_selend = m_cursor = 0; moveCursor(m_text.length(), true); }
-
- void insert(const QString &);
- void clear();
- void undo() { internalUndo(); finishChange(-1, true); }
- void redo() { internalRedo(); finishChange(); }
- void selectWordAtPos(int);
-
- uint echoMode() const { return m_echoMode; }
- void setEchoMode(uint mode)
- {
- cancelPasswordEchoTimer();
- m_echoMode = mode;
- m_passwordEchoEditing = false;
- updateDisplayText();
- }
-
- int maxLength() const { return m_maxLength; }
- void setMaxLength(int maxLength)
- {
- if (m_maskData)
- return;
- m_maxLength = maxLength;
- setText(m_text);
- }
-
-#ifndef QT_NO_VALIDATOR
- const QValidator *validator() const { return m_validator; }
- void setValidator(const QValidator *v) { m_validator = const_cast<QValidator*>(v); }
-#endif
-
-#ifndef QT_NO_COMPLETER
- QCompleter *completer() const { return m_completer; }
- /* Note that you must set the widget for the completer separately */
- void setCompleter(const QCompleter *c) { m_completer = const_cast<QCompleter*>(c); }
- void complete(int key);
-#endif
-
- int cursorPosition() const { return m_cursor; }
- void setCursorPosition(int pos) { if (pos <= m_text.length()) moveCursor(qMax(0, pos)); }
-
- bool hasAcceptableInput() const { return hasAcceptableInput(m_text); }
- bool fixup();
-
- QString inputMask() const { return m_maskData ? m_inputMask + QLatin1Char(';') + m_blank : QString(); }
- void setInputMask(const QString &mask)
- {
- parseInputMask(mask);
- if (m_maskData)
- moveCursor(nextMaskBlank(0));
- }
-
- // input methods
-#ifndef QT_NO_IM
- bool composeMode() const { return !m_textLayout.preeditAreaText().isEmpty(); }
- void setPreeditArea(int cursor, const QString &text) { m_textLayout.setPreeditArea(cursor, text); }
-#endif
-
- QString preeditAreaText() const { return m_textLayout.preeditAreaText(); }
-
- void updatePasswordEchoEditing(bool editing);
- bool passwordEchoEditing() const {
-#ifdef QT_GUI_PASSWORD_ECHO_DELAY
- if (m_passwordEchoTimer != 0)
- return true;
-#endif
- return m_passwordEchoEditing ;
- }
-
- QChar passwordCharacter() const { return m_passwordCharacter; }
- void setPasswordCharacter(const QChar &character) { m_passwordCharacter = character; updateDisplayText(); }
-
- Qt::LayoutDirection layoutDirection() const {
- if (m_layoutDirection == Qt::LayoutDirectionAuto) {
- if (m_text.isEmpty())
- return QApplication::keyboardInputDirection();
- return m_text.isRightToLeft() ? Qt::RightToLeft : Qt::LeftToRight;
- }
- return m_layoutDirection;
- }
- void setLayoutDirection(Qt::LayoutDirection direction)
- {
- if (direction != m_layoutDirection) {
- m_layoutDirection = direction;
- updateDisplayText();
- }
- }
-
- void setFont(const QFont &font) { m_textLayout.setFont(font); updateDisplayText(); }
-
- void processInputMethodEvent(QInputMethodEvent *event);
- void processMouseEvent(QMouseEvent* ev);
- void processKeyEvent(QKeyEvent* ev);
-
- int cursorBlinkPeriod() const { return m_blinkPeriod; }
- void setCursorBlinkPeriod(int msec);
- void resetCursorBlinkTimer();
-
- bool cursorBlinkStatus() const { return m_blinkStatus; }
-
- QString cancelText() const { return m_cancelText; }
- void setCancelText(const QString &text) { m_cancelText = text; }
-
- const QPalette &palette() const { return m_palette; }
- void setPalette(const QPalette &p) { m_palette = p; }
-
- enum DrawFlags {
- DrawText = 0x01,
- DrawSelections = 0x02,
- DrawCursor = 0x04,
- DrawAll = DrawText | DrawSelections | DrawCursor
- };
- void draw(QPainter *, const QPoint &, const QRect &, int flags = DrawAll);
-
- bool processEvent(QEvent *ev);
-
- QTextLayout *textLayout() const
- {
-#if defined(Q_WS_MAC)
- if (m_threadChecks && QThread::currentThread() != m_textLayoutThread)
- redoTextLayout();
-#endif
- return &m_textLayout;
- }
-
-#if defined(Q_WS_MAC)
- void setThreadChecks(bool threadChecks)
- {
- m_threadChecks = threadChecks;
- }
-
- bool threadChecks() const
- {
- return m_threadChecks;
- }
-#endif
-
-private:
- void init(const QString &txt);
- void removeSelectedText();
- void internalSetText(const QString &txt, int pos = -1, bool edited = true);
- void updateDisplayText(bool forceUpdate = false);
-
- void internalInsert(const QString &s);
- void internalDelete(bool wasBackspace = false);
- void internalRemove(int pos);
-
- inline void internalDeselect()
- {
- m_selDirty |= (m_selend > m_selstart);
- m_selstart = m_selend = 0;
- }
-
- void internalUndo(int until = -1);
- void internalRedo();
-
- QString m_text;
- QPalette m_palette;
- int m_cursor;
- int m_preeditCursor;
- int m_cursorWidth;
- Qt::LayoutDirection m_layoutDirection;
- uint m_hideCursor : 1; // used to hide the m_cursor inside preedit areas
- uint m_separator : 1;
- uint m_readOnly : 1;
- uint m_dragEnabled : 1;
- uint m_echoMode : 2;
- uint m_textDirty : 1;
- uint m_selDirty : 1;
- uint m_validInput : 1;
- uint m_blinkStatus : 1;
- int m_blinkPeriod; // 0 for non-blinking cursor
- int m_blinkTimer;
- int m_deleteAllTimer;
- int m_ascent;
- int m_maxLength;
- int m_lastCursorPos;
- QList<int> m_transactions;
- QPoint m_tripleClick;
- int m_tripleClickTimer;
- QString m_cancelText;
-
- void emitCursorPositionChanged();
-
- bool finishChange(int validateFromState = -1, bool update = false, bool edited = true);
-
-#ifndef QT_NO_VALIDATOR
- QPointer<QValidator> m_validator;
-#endif
- QPointer<QCompleter> m_completer;
-#ifndef QT_NO_COMPLETER
- bool advanceToEnabledItem(int dir);
-#endif
-
- struct MaskInputData {
- enum Casemode { NoCaseMode, Upper, Lower };
- QChar maskChar; // either the separator char or the inputmask
- bool separator;
- Casemode caseMode;
- };
- QString m_inputMask;
- QChar m_blank;
- MaskInputData *m_maskData;
-
- // undo/redo handling
- enum CommandType { Separator, Insert, Remove, Delete, RemoveSelection, DeleteSelection, SetSelection };
- struct Command {
- inline Command() {}
- inline Command(CommandType t, int p, QChar c, int ss, int se) : type(t),uc(c),pos(p),selStart(ss),selEnd(se) {}
- uint type : 4;
- QChar uc;
- int pos, selStart, selEnd;
- };
- int m_modifiedState;
- int m_undoState;
- QVector<Command> m_history;
- void addCommand(const Command& cmd);
-
- inline void separate() { m_separator = true; }
-
- // selection
- int m_selstart;
- int m_selend;
-
- // masking
- void parseInputMask(const QString &maskFields);
- bool isValidInput(QChar key, QChar mask) const;
- bool hasAcceptableInput(const QString &text) const;
- QString maskString(uint pos, const QString &str, bool clear = false) const;
- QString clearString(uint pos, uint len) const;
- QString stripString(const QString &str) const;
- int findInMask(int pos, bool forward, bool findSeparator, QChar searchChar = QChar()) const;
-
- // complex text layout (must be mutable so it can be reshaped at will)
- mutable QTextLayout m_textLayout;
-
- bool m_passwordEchoEditing;
- QChar m_passwordCharacter;
-#ifdef QT_GUI_PASSWORD_ECHO_DELAY
- int m_passwordEchoTimer;
-#endif
- void cancelPasswordEchoTimer()
- {
-#ifdef QT_GUI_PASSWORD_ECHO_DELAY
- if (m_passwordEchoTimer != 0) {
- killTimer(m_passwordEchoTimer);
- m_passwordEchoTimer = 0;
- }
-#endif
- }
-
- int redoTextLayout() const;
-#if defined(Q_WS_MAC)
- bool m_threadChecks;
- mutable QThread *m_textLayoutThread;
-#endif
-
-Q_SIGNALS:
- void cursorPositionChanged(int, int);
- void selectionChanged();
-
- void displayTextChanged(const QString &);
- void textChanged(const QString &);
- void textEdited(const QString &);
-
- void resetInputContext();
- void updateMicroFocus();
-
- void accepted();
- void editingFinished();
- void updateNeeded(const QRect &);
-
-#ifdef QT_KEYPAD_NAVIGATION
- void editFocusChange(bool);
-#endif
-protected:
- virtual void timerEvent(QTimerEvent *event);
-
-private Q_SLOTS:
- void _q_clipboardChanged();
- void _q_deleteSelected();
-
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QT_NO_LINEEDIT
-
-#endif // QLINECONTROL_P_H
diff --git a/src/gui/widgets/qlineedit.cpp b/src/gui/widgets/qlineedit.cpp
deleted file mode 100644
index 8a93c286ac..0000000000
--- a/src/gui/widgets/qlineedit.cpp
+++ /dev/null
@@ -1,2360 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qlineedit.h"
-#include "qlineedit_p.h"
-
-#ifndef QT_NO_LINEEDIT
-#include "qaction.h"
-#include "qapplication.h"
-#include "qclipboard.h"
-#include "qdrag.h"
-#include "qdrawutil.h"
-#include "qevent.h"
-#include "qfontmetrics.h"
-#include "qmenu.h"
-#include "qpainter.h"
-#include "qpixmap.h"
-#include "qpointer.h"
-#include "qstringlist.h"
-#include "qstyle.h"
-#include "qstyleoption.h"
-#include "qtimer.h"
-#include "qvalidator.h"
-#include "qvariant.h"
-#include "qvector.h"
-#include "qwhatsthis.h"
-#include "qdebug.h"
-#include "qtextedit.h"
-#include <private/qtextedit_p.h>
-#ifndef QT_NO_ACCESSIBILITY
-#include "qaccessible.h"
-#endif
-#ifndef QT_NO_IM
-#include "qinputcontext.h"
-#include "qlist.h"
-#endif
-#include "qabstractitemview.h"
-#include "private/qstylesheetstyle_p.h"
-
-#ifndef QT_NO_SHORTCUT
-#include "private/qapplication_p.h"
-#include "private/qshortcutmap_p.h"
-#include "qkeysequence.h"
-#define ACCEL_KEY(k) (!qApp->d_func()->shortcutMap.hasShortcutForKeySequence(k) ? QLatin1Char('\t') + QString(QKeySequence(k)) : QString())
-#else
-#define ACCEL_KEY(k) QString()
-#endif
-
-#include <limits.h>
-
-QT_BEGIN_NAMESPACE
-
-#ifdef Q_WS_MAC
-extern void qt_mac_secure_keyboard(bool); //qapplication_mac.cpp
-#endif
-
-/*!
- Initialize \a option with the values from this QLineEdit. This method
- is useful for subclasses when they need a QStyleOptionFrame or QStyleOptionFrameV2, but don't want
- to fill in all the information themselves. This function will check the version
- of the QStyleOptionFrame and fill in the additional values for a
- QStyleOptionFrameV2.
-
- \sa QStyleOption::initFrom()
-*/
-void QLineEdit::initStyleOption(QStyleOptionFrame *option) const
-{
- if (!option)
- return;
-
- Q_D(const QLineEdit);
- option->initFrom(this);
- option->rect = contentsRect();
- option->lineWidth = d->frame ? style()->pixelMetric(QStyle::PM_DefaultFrameWidth, option, this)
- : 0;
- option->midLineWidth = 0;
- option->state |= QStyle::State_Sunken;
- if (d->control->isReadOnly())
- option->state |= QStyle::State_ReadOnly;
-#ifdef QT_KEYPAD_NAVIGATION
- if (hasEditFocus())
- option->state |= QStyle::State_HasEditFocus;
-#endif
- if (QStyleOptionFrameV2 *optionV2 = qstyleoption_cast<QStyleOptionFrameV2 *>(option))
- optionV2->features = QStyleOptionFrameV2::None;
-}
-
-/*!
- \class QLineEdit
- \brief The QLineEdit widget is a one-line text editor.
-
- \ingroup basicwidgets
-
-
- A line edit allows the user to enter and edit a single line of
- plain text with a useful collection of editing functions,
- including undo and redo, cut and paste, and drag and drop.
-
- By changing the echoMode() of a line edit, it can also be used as
- a "write-only" field, for inputs such as passwords.
-
- The length of the text can be constrained to maxLength(). The text
- can be arbitrarily constrained using a validator() or an
- inputMask(), or both. When switching between a validator and an input mask
- on the same line edit, it is best to clear the validator or input mask to
- prevent undefined behavior.
-
-
- A related class is QTextEdit which allows multi-line, rich text
- editing.
-
- You can change the text with setText() or insert(). The text is
- retrieved with text(); the displayed text (which may be different,
- see \l{EchoMode}) is retrieved with displayText(). Text can be
- selected with setSelection() or selectAll(), and the selection can
- be cut(), copy()ied and paste()d. The text can be aligned with
- setAlignment().
-
- When the text changes the textChanged() signal is emitted; when
- the text changes other than by calling setText() the textEdited()
- signal is emitted; when the cursor is moved the
- cursorPositionChanged() signal is emitted; and when the Return or
- Enter key is pressed the returnPressed() signal is emitted.
-
- When editing is finished, either because the line edit lost focus
- or Return/Enter is pressed the editingFinished() signal is
- emitted.
-
- Note that if there is a validator set on the line edit, the
- returnPressed()/editingFinished() signals will only be emitted if
- the validator returns QValidator::Acceptable.
-
- By default, QLineEdits have a frame as specified by the Windows
- and Motif style guides; you can turn it off by calling
- setFrame(false).
-
- The default key bindings are described below. The line edit also
- provides a context menu (usually invoked by a right mouse click)
- that presents some of these editing options.
- \target desc
- \table
- \header \i Keypress \i Action
- \row \i Left Arrow \i Moves the cursor one character to the left.
- \row \i Shift+Left Arrow \i Moves and selects text one character to the left.
- \row \i Right Arrow \i Moves the cursor one character to the right.
- \row \i Shift+Right Arrow \i Moves and selects text one character to the right.
- \row \i Home \i Moves the cursor to the beginning of the line.
- \row \i End \i Moves the cursor to the end of the line.
- \row \i Backspace \i Deletes the character to the left of the cursor.
- \row \i Ctrl+Backspace \i Deletes the word to the left of the cursor.
- \row \i Delete \i Deletes the character to the right of the cursor.
- \row \i Ctrl+Delete \i Deletes the word to the right of the cursor.
- \row \i Ctrl+A \i Select all.
- \row \i Ctrl+C \i Copies the selected text to the clipboard.
- \row \i Ctrl+Insert \i Copies the selected text to the clipboard.
- \row \i Ctrl+K \i Deletes to the end of the line.
- \row \i Ctrl+V \i Pastes the clipboard text into line edit.
- \row \i Shift+Insert \i Pastes the clipboard text into line edit.
- \row \i Ctrl+X \i Deletes the selected text and copies it to the clipboard.
- \row \i Shift+Delete \i Deletes the selected text and copies it to the clipboard.
- \row \i Ctrl+Z \i Undoes the last operation.
- \row \i Ctrl+Y \i Redoes the last undone operation.
- \endtable
-
- Any other key sequence that represents a valid character, will
- cause the character to be inserted into the line edit.
-
- \table 100%
- \row \o \inlineimage macintosh-lineedit.png Screenshot of a Macintosh style line edit
- \o A line edit shown in the \l{Macintosh Style Widget Gallery}{Macintosh widget style}.
- \row \o \inlineimage windows-lineedit.png Screenshot of a Windows XP style line edit
- \o A line edit shown in the \l{Windows XP Style Widget Gallery}{Windows XP widget style}.
- \row \o \inlineimage plastique-lineedit.png Screenshot of a Plastique style line edit
- \o A line edit shown in the \l{Plastique Style Widget Gallery}{Plastique widget style}.
- \endtable
-
- \sa QTextEdit, QLabel, QComboBox, {fowler}{GUI Design Handbook: Field, Entry}, {Line Edits Example}
-*/
-
-
-/*!
- \fn void QLineEdit::textChanged(const QString &text)
-
- This signal is emitted whenever the text changes. The \a text
- argument is the new text.
-
- Unlike textEdited(), this signal is also emitted when the text is
- changed programmatically, for example, by calling setText().
-*/
-
-/*!
- \fn void QLineEdit::textEdited(const QString &text)
-
- This signal is emitted whenever the text is edited. The \a text
- argument is the next text.
-
- Unlike textChanged(), this signal is not emitted when the text is
- changed programmatically, for example, by calling setText().
-*/
-
-/*!
- \fn void QLineEdit::cursorPositionChanged(int old, int new)
-
- This signal is emitted whenever the cursor moves. The previous
- position is given by \a old, and the new position by \a new.
-
- \sa setCursorPosition(), cursorPosition()
-*/
-
-/*!
- \fn void QLineEdit::selectionChanged()
-
- This signal is emitted whenever the selection changes.
-
- \sa hasSelectedText(), selectedText()
-*/
-
-/*!
- Constructs a line edit with no text.
-
- The maximum text length is set to 32767 characters.
-
- The \a parent argument is sent to the QWidget constructor.
-
- \sa setText(), setMaxLength()
-*/
-QLineEdit::QLineEdit(QWidget* parent)
- : QWidget(*new QLineEditPrivate, parent,0)
-{
- Q_D(QLineEdit);
- d->init(QString());
-}
-
-/*!
- Constructs a line edit containing the text \a contents.
-
- The cursor position is set to the end of the line and the maximum
- text length to 32767 characters.
-
- The \a parent and argument is sent to the QWidget
- constructor.
-
- \sa text(), setMaxLength()
-*/
-QLineEdit::QLineEdit(const QString& contents, QWidget* parent)
- : QWidget(*new QLineEditPrivate, parent, 0)
-{
- Q_D(QLineEdit);
- d->init(contents);
-}
-
-
-#ifdef QT3_SUPPORT
-/*!
- Constructs a line edit with no text.
-
- The maximum text length is set to 32767 characters.
-
- The \a parent and \a name arguments are sent to the QWidget constructor.
-
- \sa setText(), setMaxLength()
-*/
-QLineEdit::QLineEdit(QWidget* parent, const char* name)
- : QWidget(*new QLineEditPrivate, parent,0)
-{
- Q_D(QLineEdit);
- setObjectName(QString::fromAscii(name));
- d->init(QString());
-}
-
-/*!
- Constructs a line edit containing the text \a contents.
-
- The cursor position is set to the end of the line and the maximum
- text length to 32767 characters.
-
- The \a parent and \a name arguments are sent to the QWidget
- constructor.
-
- \sa text(), setMaxLength()
-*/
-
-QLineEdit::QLineEdit(const QString& contents, QWidget* parent, const char* name)
- : QWidget(*new QLineEditPrivate, parent, 0)
-{
- Q_D(QLineEdit);
- setObjectName(QString::fromAscii(name));
- d->init(contents);
-}
-
-/*!
- Constructs a line edit with an input \a inputMask and the text \a
- contents.
-
- The cursor position is set to the end of the line and the maximum
- text length is set to the length of the mask (the number of mask
- characters and separators).
-
- The \a parent and \a name arguments are sent to the QWidget
- constructor.
-
- \sa setMask() text()
-*/
-QLineEdit::QLineEdit(const QString& contents, const QString &inputMask, QWidget* parent, const char* name)
- : QWidget(*new QLineEditPrivate, parent, 0)
-{
- Q_D(QLineEdit);
- setObjectName(QString::fromAscii(name));
- d->init(contents);
- d->control->setInputMask(inputMask);
- d->control->moveCursor(d->control->nextMaskBlank(contents.length()));
-}
-#endif
-
-/*!
- Destroys the line edit.
-*/
-
-QLineEdit::~QLineEdit()
-{
-}
-
-
-/*!
- \property QLineEdit::text
- \brief the line edit's text
-
- Setting this property clears the selection, clears the undo/redo
- history, moves the cursor to the end of the line and resets the
- \l modified property to false. The text is not validated when
- inserted with setText().
-
- The text is truncated to maxLength() length.
-
- By default, this property contains an empty string.
-
- \sa insert(), clear()
-*/
-QString QLineEdit::text() const
-{
- Q_D(const QLineEdit);
- return d->control->text();
-}
-
-void QLineEdit::setText(const QString& text)
-{
- Q_D(QLineEdit);
- d->control->setText(text);
-}
-
-/*!
- \since 4.7
-
- \property QLineEdit::placeholderText
- \brief the line edit's placeholder text
-
- Setting this property makes the line edit display a grayed-out
- placeholder text as long as the text() is empty and the widget doesn't
- have focus.
-
- By default, this property contains an empty string.
-
- \sa text()
-*/
-QString QLineEdit::placeholderText() const
-{
- Q_D(const QLineEdit);
- return d->placeholderText;
-}
-
-void QLineEdit::setPlaceholderText(const QString& placeholderText)
-{
- Q_D(QLineEdit);
- if (d->placeholderText != placeholderText) {
- d->placeholderText = placeholderText;
- if (!hasFocus())
- update();
- }
-}
-
-/*!
- \property QLineEdit::displayText
- \brief the displayed text
-
- If \l echoMode is \l Normal this returns the same as text(); if
- \l EchoMode is \l Password or \l PasswordEchoOnEdit it returns a string of asterisks
- text().length() characters long, e.g. "******"; if \l EchoMode is
- \l NoEcho returns an empty string, "".
-
- By default, this property contains an empty string.
-
- \sa setEchoMode() text() EchoMode
-*/
-
-QString QLineEdit::displayText() const
-{
- Q_D(const QLineEdit);
- return d->control->displayText();
-}
-
-
-/*!
- \property QLineEdit::maxLength
- \brief the maximum permitted length of the text
-
- If the text is too long, it is truncated at the limit.
-
- If truncation occurs any selected text will be unselected, the
- cursor position is set to 0 and the first part of the string is
- shown.
-
- If the line edit has an input mask, the mask defines the maximum
- string length.
-
- By default, this property contains a value of 32767.
-
- \sa inputMask
-*/
-
-int QLineEdit::maxLength() const
-{
- Q_D(const QLineEdit);
- return d->control->maxLength();
-}
-
-void QLineEdit::setMaxLength(int maxLength)
-{
- Q_D(QLineEdit);
- d->control->setMaxLength(maxLength);
-}
-
-/*!
- \property QLineEdit::frame
- \brief whether the line edit draws itself with a frame
-
- If enabled (the default) the line edit draws itself inside a
- frame, otherwise the line edit draws itself without any frame.
-*/
-bool QLineEdit::hasFrame() const
-{
- Q_D(const QLineEdit);
- return d->frame;
-}
-
-
-void QLineEdit::setFrame(bool enable)
-{
- Q_D(QLineEdit);
- d->frame = enable;
- update();
- updateGeometry();
-}
-
-
-/*!
- \enum QLineEdit::EchoMode
-
- This enum type describes how a line edit should display its
- contents.
-
- \value Normal Display characters as they are entered. This is the
- default.
- \value NoEcho Do not display anything. This may be appropriate
- for passwords where even the length of the
- password should be kept secret.
- \value Password Display asterisks instead of the characters
- actually entered.
- \value PasswordEchoOnEdit Display characters as they are entered
- while editing otherwise display asterisks.
-
- \sa setEchoMode() echoMode()
-*/
-
-
-/*!
- \property QLineEdit::echoMode
- \brief the line edit's echo mode
-
- The echo mode determines how the text entered in the line edit is
- displayed (or echoed) to the user.
-
- The most common setting is \l Normal, in which the text entered by the
- user is displayed verbatim, but QLineEdit also supports modes that allow
- the entered text to be suppressed or obscured: these include \l NoEcho,
- \l Password and \l PasswordEchoOnEdit.
-
- The widget's display and the ability to copy or drag the text is
- affected by this setting.
-
- By default, this property is set to \l Normal.
-
- \sa EchoMode displayText()
-*/
-
-QLineEdit::EchoMode QLineEdit::echoMode() const
-{
- Q_D(const QLineEdit);
- return (EchoMode) d->control->echoMode();
-}
-
-void QLineEdit::setEchoMode(EchoMode mode)
-{
- Q_D(QLineEdit);
- if (mode == (EchoMode)d->control->echoMode())
- return;
- Qt::InputMethodHints imHints = inputMethodHints();
- if (mode == Password || mode == NoEcho) {
- imHints |= Qt::ImhHiddenText;
- } else {
- imHints &= ~Qt::ImhHiddenText;
- }
- if (mode != Normal) {
- imHints |= (Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText);
- } else {
- imHints &= ~(Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText);
- }
- setInputMethodHints(imHints);
- d->control->setEchoMode(mode);
- update();
-#ifdef Q_WS_MAC
- if (hasFocus())
- qt_mac_secure_keyboard(mode == Password || mode == NoEcho);
-#endif
-}
-
-
-#ifndef QT_NO_VALIDATOR
-/*!
- Returns a pointer to the current input validator, or 0 if no
- validator has been set.
-
- \sa setValidator()
-*/
-
-const QValidator * QLineEdit::validator() const
-{
- Q_D(const QLineEdit);
- return d->control->validator();
-}
-
-/*!
- Sets this line edit to only accept input that the validator, \a v,
- will accept. This allows you to place any arbitrary constraints on
- the text which may be entered.
-
- If \a v == 0, setValidator() removes the current input validator.
- The initial setting is to have no input validator (i.e. any input
- is accepted up to maxLength()).
-
- \sa validator() QIntValidator QDoubleValidator QRegExpValidator
-*/
-
-void QLineEdit::setValidator(const QValidator *v)
-{
- Q_D(QLineEdit);
- d->control->setValidator(v);
-}
-#endif // QT_NO_VALIDATOR
-
-#ifndef QT_NO_COMPLETER
-/*!
- \since 4.2
-
- Sets this line edit to provide auto completions from the completer, \a c.
- The completion mode is set using QCompleter::setCompletionMode().
-
- To use a QCompleter with a QValidator or QLineEdit::inputMask, you need to
- ensure that the model provided to QCompleter contains valid entries. You can
- use the QSortFilterProxyModel to ensure that the QCompleter's model contains
- only valid entries.
-
- If \a c == 0, setCompleter() removes the current completer, effectively
- disabling auto completion.
-
- \sa QCompleter
-*/
-void QLineEdit::setCompleter(QCompleter *c)
-{
- Q_D(QLineEdit);
- if (c == d->control->completer())
- return;
- if (d->control->completer()) {
- disconnect(d->control->completer(), 0, this, 0);
- d->control->completer()->setWidget(0);
- if (d->control->completer()->parent() == this)
- delete d->control->completer();
- }
- d->control->setCompleter(c);
- if (!c)
- return;
- if (c->widget() == 0)
- c->setWidget(this);
- if (hasFocus()) {
- QObject::connect(d->control->completer(), SIGNAL(activated(QString)),
- this, SLOT(setText(QString)));
- QObject::connect(d->control->completer(), SIGNAL(highlighted(QString)),
- this, SLOT(_q_completionHighlighted(QString)));
- }
-}
-
-/*!
- \since 4.2
-
- Returns the current QCompleter that provides completions.
-*/
-QCompleter *QLineEdit::completer() const
-{
- Q_D(const QLineEdit);
- return d->control->completer();
-}
-
-#endif // QT_NO_COMPLETER
-
-/*!
- Returns a recommended size for the widget.
-
- The width returned, in pixels, is usually enough for about 15 to
- 20 characters.
-*/
-
-QSize QLineEdit::sizeHint() const
-{
- Q_D(const QLineEdit);
- ensurePolished();
- QFontMetrics fm(font());
- int h = qMax(fm.height(), 14) + 2*d->verticalMargin
- + d->topTextMargin + d->bottomTextMargin
- + d->topmargin + d->bottommargin;
- int w = fm.width(QLatin1Char('x')) * 17 + 2*d->horizontalMargin
- + d->leftTextMargin + d->rightTextMargin
- + d->leftmargin + d->rightmargin; // "some"
- QStyleOptionFrameV2 opt;
- initStyleOption(&opt);
- return (style()->sizeFromContents(QStyle::CT_LineEdit, &opt, QSize(w, h).
- expandedTo(QApplication::globalStrut()), this));
-}
-
-
-/*!
- Returns a minimum size for the line edit.
-
- The width returned is enough for at least one character.
-*/
-
-QSize QLineEdit::minimumSizeHint() const
-{
- Q_D(const QLineEdit);
- ensurePolished();
- QFontMetrics fm = fontMetrics();
- int h = fm.height() + qMax(2*d->verticalMargin, fm.leading())
- + d->topmargin + d->bottommargin;
- int w = fm.maxWidth() + d->leftmargin + d->rightmargin;
- QStyleOptionFrameV2 opt;
- initStyleOption(&opt);
- return (style()->sizeFromContents(QStyle::CT_LineEdit, &opt, QSize(w, h).
- expandedTo(QApplication::globalStrut()), this));
-}
-
-
-/*!
- \property QLineEdit::cursorPosition
- \brief the current cursor position for this line edit
-
- Setting the cursor position causes a repaint when appropriate.
-
- By default, this property contains a value of 0.
-*/
-
-int QLineEdit::cursorPosition() const
-{
- Q_D(const QLineEdit);
- return d->control->cursorPosition();
-}
-
-void QLineEdit::setCursorPosition(int pos)
-{
- Q_D(QLineEdit);
- d->control->setCursorPosition(pos);
-}
-
-/*!
- Returns the cursor position under the point \a pos.
-*/
-// ### What should this do if the point is outside of contentsRect? Currently returns 0.
-int QLineEdit::cursorPositionAt(const QPoint &pos)
-{
- Q_D(QLineEdit);
- return d->xToPos(pos.x());
-}
-
-
-#ifdef QT3_SUPPORT
-/*! \obsolete
-
- Use setText(), setCursorPosition() and setSelection() instead.
-*/
-bool QLineEdit::validateAndSet(const QString &newText, int newPos,
- int newMarkAnchor, int newMarkDrag)
-{
- // The suggested functions above in the docs don't seem to validate,
- // below code tries to mimic previous behaviour.
- QString oldText = text();
- setText(newText);
- if(!hasAcceptableInput()){
- setText(oldText);
- return false;
- }
- int selstart = qMin(newMarkAnchor, newMarkDrag);
- int sellength = qAbs(newMarkAnchor - newMarkDrag);
- if (selstart == newPos) {
- selstart = qMax(newMarkAnchor, newMarkDrag);
- sellength = -sellength;
- }
- //setSelection also set the position
- setSelection(selstart, sellength);
- return true;
-}
-#endif //QT3_SUPPORT
-
-/*!
- \property QLineEdit::alignment
- \brief the alignment of the line edit
-
- Both horizontal and vertical alignment is allowed here, Qt::AlignJustify
- will map to Qt::AlignLeft.
-
- By default, this property contains a combination of Qt::AlignLeft and Qt::AlignVCenter.
-
- \sa Qt::Alignment
-*/
-
-Qt::Alignment QLineEdit::alignment() const
-{
- Q_D(const QLineEdit);
- return QFlag(d->alignment);
-}
-
-void QLineEdit::setAlignment(Qt::Alignment alignment)
-{
- Q_D(QLineEdit);
- d->alignment = alignment;
- update();
-}
-
-
-/*!
- Moves the cursor forward \a steps characters. If \a mark is true
- each character moved over is added to the selection; if \a mark is
- false the selection is cleared.
-
- \sa cursorBackward()
-*/
-
-void QLineEdit::cursorForward(bool mark, int steps)
-{
- Q_D(QLineEdit);
- d->control->cursorForward(mark, steps);
-}
-
-
-/*!
- Moves the cursor back \a steps characters. If \a mark is true each
- character moved over is added to the selection; if \a mark is
- false the selection is cleared.
-
- \sa cursorForward()
-*/
-void QLineEdit::cursorBackward(bool mark, int steps)
-{
- cursorForward(mark, -steps);
-}
-
-/*!
- Moves the cursor one word forward. If \a mark is true, the word is
- also selected.
-
- \sa cursorWordBackward()
-*/
-void QLineEdit::cursorWordForward(bool mark)
-{
- Q_D(QLineEdit);
- d->control->cursorWordForward(mark);
-}
-
-/*!
- Moves the cursor one word backward. If \a mark is true, the word
- is also selected.
-
- \sa cursorWordForward()
-*/
-
-void QLineEdit::cursorWordBackward(bool mark)
-{
- Q_D(QLineEdit);
- d->control->cursorWordBackward(mark);
-}
-
-
-/*!
- If no text is selected, deletes the character to the left of the
- text cursor and moves the cursor one position to the left. If any
- text is selected, the cursor is moved to the beginning of the
- selected text and the selected text is deleted.
-
- \sa del()
-*/
-void QLineEdit::backspace()
-{
- Q_D(QLineEdit);
- d->control->backspace();
-}
-
-/*!
- If no text is selected, deletes the character to the right of the
- text cursor. If any text is selected, the cursor is moved to the
- beginning of the selected text and the selected text is deleted.
-
- \sa backspace()
-*/
-
-void QLineEdit::del()
-{
- Q_D(QLineEdit);
- d->control->del();
-}
-
-/*!
- Moves the text cursor to the beginning of the line unless it is
- already there. If \a mark is true, text is selected towards the
- first position; otherwise, any selected text is unselected if the
- cursor is moved.
-
- \sa end()
-*/
-
-void QLineEdit::home(bool mark)
-{
- Q_D(QLineEdit);
- d->control->home(mark);
-}
-
-/*!
- Moves the text cursor to the end of the line unless it is already
- there. If \a mark is true, text is selected towards the last
- position; otherwise, any selected text is unselected if the cursor
- is moved.
-
- \sa home()
-*/
-
-void QLineEdit::end(bool mark)
-{
- Q_D(QLineEdit);
- d->control->end(mark);
-}
-
-
-/*!
- \property QLineEdit::modified
- \brief whether the line edit's contents has been modified by the user
-
- The modified flag is never read by QLineEdit; it has a default value
- of false and is changed to true whenever the user changes the line
- edit's contents.
-
- This is useful for things that need to provide a default value but
- do not start out knowing what the default should be (perhaps it
- depends on other fields on the form). Start the line edit without
- the best default, and when the default is known, if modified()
- returns false (the user hasn't entered any text), insert the
- default value.
-
- Calling setText() resets the modified flag to false.
-*/
-
-bool QLineEdit::isModified() const
-{
- Q_D(const QLineEdit);
- return d->control->isModified();
-}
-
-void QLineEdit::setModified(bool modified)
-{
- Q_D(QLineEdit);
- d->control->setModified(modified);
-}
-
-
-/*!\fn QLineEdit::clearModified()
-
-Use setModified(false) instead.
-
- \sa isModified()
-*/
-
-
-/*!
- \property QLineEdit::hasSelectedText
- \brief whether there is any text selected
-
- hasSelectedText() returns true if some or all of the text has been
- selected by the user; otherwise returns false.
-
- By default, this property is false.
-
- \sa selectedText()
-*/
-
-
-bool QLineEdit::hasSelectedText() const
-{
- Q_D(const QLineEdit);
- return d->control->hasSelectedText();
-}
-
-/*!
- \property QLineEdit::selectedText
- \brief the selected text
-
- If there is no selected text this property's value is
- an empty string.
-
- By default, this property contains an empty string.
-
- \sa hasSelectedText()
-*/
-
-QString QLineEdit::selectedText() const
-{
- Q_D(const QLineEdit);
- return d->control->selectedText();
-}
-
-/*!
- selectionStart() returns the index of the first selected character in the
- line edit or -1 if no text is selected.
-
- \sa selectedText()
-*/
-
-int QLineEdit::selectionStart() const
-{
- Q_D(const QLineEdit);
- return d->control->selectionStart();
-}
-
-
-#ifdef QT3_SUPPORT
-
-/*!
- \fn void QLineEdit::lostFocus()
-
- This signal is emitted when the line edit has lost focus.
-
- Use editingFinished() instead
- \sa editingFinished(), returnPressed()
-*/
-
-/*!
- Use isModified() instead.
-*/
-bool QLineEdit::edited() const { return isModified(); }
-/*!
- Use setModified() or setText().
-*/
-void QLineEdit::setEdited(bool on) { setModified(on); }
-
-/*!
- There exists no equivalent functionality in Qt 4.
-*/
-int QLineEdit::characterAt(int xpos, QChar *chr) const
-{
- Q_D(const QLineEdit);
- int pos = d->xToPos(xpos + contentsRect().x() - d->hscroll + d->horizontalMargin);
- QString txt = d->control->text();
- if (chr && pos < (int) txt.length())
- *chr = txt.at(pos);
- return pos;
-
-}
-
-/*!
- Use selectedText() and selectionStart() instead.
-*/
-bool QLineEdit::getSelection(int *start, int *end)
-{
- Q_D(QLineEdit);
- if (d->control->hasSelectedText() && start && end) {
- *start = selectionStart();
- *end = *start + selectedText().length();
- return true;
- }
- return false;
-}
-#endif
-
-
-/*!
- Selects text from position \a start and for \a length characters.
- Negative lengths are allowed.
-
- \sa deselect() selectAll() selectedText()
-*/
-
-void QLineEdit::setSelection(int start, int length)
-{
- Q_D(QLineEdit);
- if (start < 0 || start > (int)d->control->text().length()) {
- qWarning("QLineEdit::setSelection: Invalid start position (%d)", start);
- return;
- }
-
- d->control->setSelection(start, length);
-
- if (d->control->hasSelectedText()){
- QStyleOptionFrameV2 opt;
- initStyleOption(&opt);
- if (!style()->styleHint(QStyle::SH_BlinkCursorWhenTextSelected, &opt, this))
- d->setCursorVisible(false);
- }
-}
-
-
-/*!
- \property QLineEdit::undoAvailable
- \brief whether undo is available
-
- Undo becomes available once the user has modified the text in the line edit.
-
- By default, this property is false.
-*/
-
-bool QLineEdit::isUndoAvailable() const
-{
- Q_D(const QLineEdit);
- return d->control->isUndoAvailable();
-}
-
-/*!
- \property QLineEdit::redoAvailable
- \brief whether redo is available
-
- Redo becomes available once the user has performed one or more undo operations
- on text in the line edit.
-
- By default, this property is false.
-*/
-
-bool QLineEdit::isRedoAvailable() const
-{
- Q_D(const QLineEdit);
- return d->control->isRedoAvailable();
-}
-
-/*!
- \property QLineEdit::dragEnabled
- \brief whether the lineedit starts a drag if the user presses and
- moves the mouse on some selected text
-
- Dragging is disabled by default.
-*/
-
-bool QLineEdit::dragEnabled() const
-{
- Q_D(const QLineEdit);
- return d->dragEnabled;
-}
-
-void QLineEdit::setDragEnabled(bool b)
-{
- Q_D(QLineEdit);
- d->dragEnabled = b;
-}
-
-
-/*!
- \property QLineEdit::cursorMoveStyle
- \brief the movement style of cursor in this line edit
- \since 4.8
-
- When this property is set to Qt::VisualMoveStyle, the line edit will use visual
- movement style. Pressing the left arrow key will always cause the cursor to move
- left, regardless of the text's writing direction. The same behavior applies to
- right arrow key.
-
- When the property is Qt::LogicalMoveStyle (the default), within a LTR text block,
- increase cursor position when pressing left arrow key, decrease cursor position
- when pressing the right arrow key. If the text block is right to left, the opposite
- behavior applies.
-*/
-
-Qt::CursorMoveStyle QLineEdit::cursorMoveStyle() const
-{
- Q_D(const QLineEdit);
- return d->control->cursorMoveStyle();
-}
-
-void QLineEdit::setCursorMoveStyle(Qt::CursorMoveStyle style)
-{
- Q_D(QLineEdit);
- d->control->setCursorMoveStyle(style);
-}
-
-/*!
- \property QLineEdit::acceptableInput
- \brief whether the input satisfies the inputMask and the
- validator.
-
- By default, this property is true.
-
- \sa setInputMask(), setValidator()
-*/
-bool QLineEdit::hasAcceptableInput() const
-{
- Q_D(const QLineEdit);
- return d->control->hasAcceptableInput();
-}
-
-/*!
- Sets the margins around the text inside the frame to have the
- sizes \a left, \a top, \a right, and \a bottom.
- \since 4.5
-
- See also getTextMargins().
-*/
-void QLineEdit::setTextMargins(int left, int top, int right, int bottom)
-{
- Q_D(QLineEdit);
- d->leftTextMargin = left;
- d->topTextMargin = top;
- d->rightTextMargin = right;
- d->bottomTextMargin = bottom;
- updateGeometry();
- update();
-}
-
-/*!
- \since 4.6
- Sets the \a margins around the text inside the frame.
-
- See also textMargins().
-*/
-void QLineEdit::setTextMargins(const QMargins &margins)
-{
- setTextMargins(margins.left(), margins.top(), margins.right(), margins.bottom());
-}
-
-/*!
- Returns the widget's text margins for \a left, \a top, \a right, and \a bottom.
- \since 4.5
-
- \sa setTextMargins()
-*/
-void QLineEdit::getTextMargins(int *left, int *top, int *right, int *bottom) const
-{
- Q_D(const QLineEdit);
- if (left)
- *left = d->leftTextMargin;
- if (top)
- *top = d->topTextMargin;
- if (right)
- *right = d->rightTextMargin;
- if (bottom)
- *bottom = d->bottomTextMargin;
-}
-
-/*!
- \since 4.6
- Returns the widget's text margins.
-
- \sa setTextMargins()
-*/
-QMargins QLineEdit::textMargins() const
-{
- Q_D(const QLineEdit);
- return QMargins(d->leftTextMargin, d->topTextMargin, d->rightTextMargin, d->bottomTextMargin);
-}
-
-/*!
- \property QLineEdit::inputMask
- \brief The validation input mask
-
- If no mask is set, inputMask() returns an empty string.
-
- Sets the QLineEdit's validation mask. Validators can be used
- instead of, or in conjunction with masks; see setValidator().
-
- Unset the mask and return to normal QLineEdit operation by passing
- an empty string ("") or just calling setInputMask() with no
- arguments.
-
- The table below shows the characters that can be used in an input mask.
- A space character, the default character for a blank, is needed for cases
- where a character is \e{permitted but not required}.
-
- \table
- \header \i Character \i Meaning
- \row \i \c A \i ASCII alphabetic character required. A-Z, a-z.
- \row \i \c a \i ASCII alphabetic character permitted but not required.
- \row \i \c N \i ASCII alphanumeric character required. A-Z, a-z, 0-9.
- \row \i \c n \i ASCII alphanumeric character permitted but not required.
- \row \i \c X \i Any character required.
- \row \i \c x \i Any character permitted but not required.
- \row \i \c 9 \i ASCII digit required. 0-9.
- \row \i \c 0 \i ASCII digit permitted but not required.
- \row \i \c D \i ASCII digit required. 1-9.
- \row \i \c d \i ASCII digit permitted but not required (1-9).
- \row \i \c # \i ASCII digit or plus/minus sign permitted but not required.
- \row \i \c H \i Hexadecimal character required. A-F, a-f, 0-9.
- \row \i \c h \i Hexadecimal character permitted but not required.
- \row \i \c B \i Binary character required. 0-1.
- \row \i \c b \i Binary character permitted but not required.
- \row \i \c > \i All following alphabetic characters are uppercased.
- \row \i \c < \i All following alphabetic characters are lowercased.
- \row \i \c ! \i Switch off case conversion.
- \row \i \tt{\\} \i Use \tt{\\} to escape the special
- characters listed above to use them as
- separators.
- \endtable
-
- The mask consists of a string of mask characters and separators,
- optionally followed by a semicolon and the character used for
- blanks. The blank characters are always removed from the text
- after editing.
-
- Examples:
- \table
- \header \i Mask \i Notes
- \row \i \c 000.000.000.000;_ \i IP address; blanks are \c{_}.
- \row \i \c HH:HH:HH:HH:HH:HH;_ \i MAC address
- \row \i \c 0000-00-00 \i ISO Date; blanks are \c space
- \row \i \c >AAAAA-AAAAA-AAAAA-AAAAA-AAAAA;# \i License number;
- blanks are \c - and all (alphabetic) characters are converted to
- uppercase.
- \endtable
-
- To get range control (e.g., for an IP address) use masks together
- with \link setValidator() validators\endlink.
-
- \sa maxLength
-*/
-QString QLineEdit::inputMask() const
-{
- Q_D(const QLineEdit);
- return d->control->inputMask();
-}
-
-void QLineEdit::setInputMask(const QString &inputMask)
-{
- Q_D(QLineEdit);
- d->control->setInputMask(inputMask);
-}
-
-/*!
- Selects all the text (i.e. highlights it) and moves the cursor to
- the end. This is useful when a default value has been inserted
- because if the user types before clicking on the widget, the
- selected text will be deleted.
-
- \sa setSelection() deselect()
-*/
-
-void QLineEdit::selectAll()
-{
- Q_D(QLineEdit);
- d->control->selectAll();
-}
-
-/*!
- Deselects any selected text.
-
- \sa setSelection() selectAll()
-*/
-
-void QLineEdit::deselect()
-{
- Q_D(QLineEdit);
- d->control->deselect();
-}
-
-
-/*!
- Deletes any selected text, inserts \a newText, and validates the
- result. If it is valid, it sets it as the new contents of the line
- edit.
-
- \sa setText(), clear()
-*/
-void QLineEdit::insert(const QString &newText)
-{
-// q->resetInputContext(); //#### FIX ME IN QT
- Q_D(QLineEdit);
- d->control->insert(newText);
-}
-
-/*!
- Clears the contents of the line edit.
-
- \sa setText(), insert()
-*/
-void QLineEdit::clear()
-{
- Q_D(QLineEdit);
- resetInputContext();
- d->control->clear();
-}
-
-/*!
- Undoes the last operation if undo is \link
- QLineEdit::undoAvailable available\endlink. Deselects any current
- selection, and updates the selection start to the current cursor
- position.
-*/
-void QLineEdit::undo()
-{
- Q_D(QLineEdit);
- resetInputContext();
- d->control->undo();
-}
-
-/*!
- Redoes the last operation if redo is \link
- QLineEdit::redoAvailable available\endlink.
-*/
-void QLineEdit::redo()
-{
- Q_D(QLineEdit);
- resetInputContext();
- d->control->redo();
-}
-
-
-/*!
- \property QLineEdit::readOnly
- \brief whether the line edit is read only.
-
- In read-only mode, the user can still copy the text to the
- clipboard, or drag and drop the text (if echoMode() is \l Normal),
- but cannot edit it.
-
- QLineEdit does not show a cursor in read-only mode.
-
- By default, this property is false.
-
- \sa setEnabled()
-*/
-
-bool QLineEdit::isReadOnly() const
-{
- Q_D(const QLineEdit);
- return d->control->isReadOnly();
-}
-
-void QLineEdit::setReadOnly(bool enable)
-{
- Q_D(QLineEdit);
- if (d->control->isReadOnly() != enable) {
- d->control->setReadOnly(enable);
- setAttribute(Qt::WA_MacShowFocusRect, !enable);
- setAttribute(Qt::WA_InputMethodEnabled, d->shouldEnableInputMethod());
-#ifndef QT_NO_CURSOR
- setCursor(enable ? Qt::ArrowCursor : Qt::IBeamCursor);
-#endif
- update();
- }
-}
-
-
-#ifndef QT_NO_CLIPBOARD
-/*!
- Copies the selected text to the clipboard and deletes it, if there
- is any, and if echoMode() is \l Normal.
-
- If the current validator disallows deleting the selected text,
- cut() will copy without deleting.
-
- \sa copy() paste() setValidator()
-*/
-
-void QLineEdit::cut()
-{
- if (hasSelectedText()) {
- copy();
- del();
- }
-}
-
-
-/*!
- Copies the selected text to the clipboard, if there is any, and if
- echoMode() is \l Normal.
-
- \sa cut() paste()
-*/
-
-void QLineEdit::copy() const
-{
- Q_D(const QLineEdit);
- d->control->copy();
-}
-
-/*!
- Inserts the clipboard's text at the cursor position, deleting any
- selected text, providing the line edit is not \link
- QLineEdit::readOnly read-only\endlink.
-
- If the end result would not be acceptable to the current
- \link setValidator() validator\endlink, nothing happens.
-
- \sa copy() cut()
-*/
-
-void QLineEdit::paste()
-{
- Q_D(QLineEdit);
- d->control->paste();
-}
-
-#endif // !QT_NO_CLIPBOARD
-
-/*! \reimp
-*/
-bool QLineEdit::event(QEvent * e)
-{
- Q_D(QLineEdit);
- if (e->type() == QEvent::Timer) {
- // should be timerEvent, is here for binary compatibility
- int timerId = ((QTimerEvent*)e)->timerId();
- if (false) {
-#ifndef QT_NO_DRAGANDDROP
- } else if (timerId == d->dndTimer.timerId()) {
- d->drag();
-#endif
- }
- else if (timerId == d->tripleClickTimer.timerId())
- d->tripleClickTimer.stop();
- } else if (e->type() == QEvent::ContextMenu) {
-#ifndef QT_NO_IM
- if (d->control->composeMode())
- return true;
-#endif
- //d->separate();
- } else if (e->type() == QEvent::WindowActivate) {
- QTimer::singleShot(0, this, SLOT(_q_handleWindowActivate()));
- }else if(e->type() == QEvent::ShortcutOverride){
- d->control->processEvent(e);
- } else if (e->type() == QEvent::KeyRelease) {
- d->control->setCursorBlinkPeriod(QApplication::cursorFlashTime());
- } else if (e->type() == QEvent::Show) {
- //In order to get the cursor blinking if QComboBox::setEditable is called when the combobox has focus
- if (hasFocus()) {
- d->control->setCursorBlinkPeriod(QApplication::cursorFlashTime());
- QStyleOptionFrameV2 opt;
- initStyleOption(&opt);
- if ((!hasSelectedText() && d->control->preeditAreaText().isEmpty())
- || style()->styleHint(QStyle::SH_BlinkCursorWhenTextSelected, &opt, this))
- d->setCursorVisible(true);
- }
- }
-
-#ifdef QT_KEYPAD_NAVIGATION
- if (QApplication::keypadNavigationEnabled()) {
- if (e->type() == QEvent::EnterEditFocus) {
- end(false);
- d->setCursorVisible(true);
- d->control->setCursorBlinkPeriod(QApplication::cursorFlashTime());
- } else if (e->type() == QEvent::LeaveEditFocus) {
- d->setCursorVisible(false);
- d->control->setCursorBlinkPeriod(0);
- if (d->control->hasAcceptableInput() || d->control->fixup())
- emit editingFinished();
- }
- }
-#endif
- return QWidget::event(e);
-}
-
-/*! \reimp
-*/
-void QLineEdit::mousePressEvent(QMouseEvent* e)
-{
- Q_D(QLineEdit);
- if (d->sendMouseEventToInputContext(e))
- return;
- if (e->button() == Qt::RightButton)
- return;
-#ifdef QT_KEYPAD_NAVIGATION
- if (QApplication::keypadNavigationEnabled() && !hasEditFocus()) {
- setEditFocus(true);
- // Get the completion list to pop up.
- if (d->control->completer())
- d->control->completer()->complete();
- }
-#endif
- if (d->tripleClickTimer.isActive() && (e->pos() - d->tripleClick).manhattanLength() <
- QApplication::startDragDistance()) {
- selectAll();
- return;
- }
- bool mark = e->modifiers() & Qt::ShiftModifier;
- int cursor = d->xToPos(e->pos().x());
-#ifndef QT_NO_DRAGANDDROP
- if (!mark && d->dragEnabled && d->control->echoMode() == Normal &&
- e->button() == Qt::LeftButton && d->control->inSelection(e->pos().x())) {
- d->dndPos = e->pos();
- if (!d->dndTimer.isActive())
- d->dndTimer.start(QApplication::startDragTime(), this);
- } else
-#endif
- {
- d->control->moveCursor(cursor, mark);
- }
-}
-
-/*! \reimp
-*/
-void QLineEdit::mouseMoveEvent(QMouseEvent * e)
-{
- Q_D(QLineEdit);
- if (d->sendMouseEventToInputContext(e))
- return;
-
- if (e->buttons() & Qt::LeftButton) {
-#ifndef QT_NO_DRAGANDDROP
- if (d->dndTimer.isActive()) {
- if ((d->dndPos - e->pos()).manhattanLength() > QApplication::startDragDistance())
- d->drag();
- } else
-#endif
- {
- d->control->moveCursor(d->xToPos(e->pos().x()), true);
- }
- }
-}
-
-/*! \reimp
-*/
-void QLineEdit::mouseReleaseEvent(QMouseEvent* e)
-{
- Q_D(QLineEdit);
- if (d->sendMouseEventToInputContext(e))
- return;
-#ifndef QT_NO_DRAGANDDROP
- if (e->button() == Qt::LeftButton) {
- if (d->dndTimer.isActive()) {
- d->dndTimer.stop();
- deselect();
- return;
- }
- }
-#endif
-#ifndef QT_NO_CLIPBOARD
- if (QApplication::clipboard()->supportsSelection()) {
- if (e->button() == Qt::LeftButton) {
- d->control->copy(QClipboard::Selection);
- } else if (!d->control->isReadOnly() && e->button() == Qt::MidButton) {
- deselect();
- insert(QApplication::clipboard()->text(QClipboard::Selection));
- }
- }
-#endif
-
- if (!isReadOnly() && rect().contains(e->pos()))
- d->handleSoftwareInputPanel(e->button(), d->clickCausedFocus);
- d->clickCausedFocus = 0;
-}
-
-/*! \reimp
-*/
-void QLineEdit::mouseDoubleClickEvent(QMouseEvent* e)
-{
- Q_D(QLineEdit);
- if (d->sendMouseEventToInputContext(e))
- return;
- if (e->button() == Qt::LeftButton) {
- d->control->selectWordAtPos(d->xToPos(e->pos().x()));
- d->tripleClickTimer.start(QApplication::doubleClickInterval(), this);
- d->tripleClick = e->pos();
- }
-}
-
-/*!
- \fn void QLineEdit::returnPressed()
-
- This signal is emitted when the Return or Enter key is pressed.
- Note that if there is a validator() or inputMask() set on the line
- edit, the returnPressed() signal will only be emitted if the input
- follows the inputMask() and the validator() returns
- QValidator::Acceptable.
-*/
-
-/*!
- \fn void QLineEdit::editingFinished()
-
- This signal is emitted when the Return or Enter key is pressed or
- the line edit loses focus. Note that if there is a validator() or
- inputMask() set on the line edit and enter/return is pressed, the
- editingFinished() signal will only be emitted if the input follows
- the inputMask() and the validator() returns QValidator::Acceptable.
-*/
-
-/*!
- Converts the given key press \a event into a line edit action.
-
- If Return or Enter is pressed and the current text is valid (or
- can be \link QValidator::fixup() made valid\endlink by the
- validator), the signal returnPressed() is emitted.
-
- The default key bindings are listed in the class's detailed
- description.
-*/
-
-void QLineEdit::keyPressEvent(QKeyEvent *event)
-{
- Q_D(QLineEdit);
- #ifdef QT_KEYPAD_NAVIGATION
- bool select = false;
- switch (event->key()) {
- case Qt::Key_Select:
- if (QApplication::keypadNavigationEnabled()) {
- if (hasEditFocus()) {
- setEditFocus(false);
- if (d->control->completer() && d->control->completer()->popup()->isVisible())
- d->control->completer()->popup()->hide();
- select = true;
- }
- }
- break;
- case Qt::Key_Back:
- case Qt::Key_No:
- if (!QApplication::keypadNavigationEnabled() || !hasEditFocus()) {
- event->ignore();
- return;
- }
- break;
- default:
- if (QApplication::keypadNavigationEnabled()) {
- if (!hasEditFocus() && !(event->modifiers() & Qt::ControlModifier)) {
- if (!event->text().isEmpty() && event->text().at(0).isPrint()
- && !isReadOnly())
- setEditFocus(true);
- else {
- event->ignore();
- return;
- }
- }
- }
- }
-
-
-
- if (QApplication::keypadNavigationEnabled() && !select && !hasEditFocus()) {
- setEditFocus(true);
- if (event->key() == Qt::Key_Select)
- return; // Just start. No action.
- }
-#endif
- d->control->processKeyEvent(event);
- if (event->isAccepted()) {
- if (layoutDirection() != d->control->layoutDirection())
- setLayoutDirection(d->control->layoutDirection());
- d->control->setCursorBlinkPeriod(0);
- }
-}
-
-/*!
- \since 4.4
-
- Returns a rectangle that includes the lineedit cursor.
-*/
-QRect QLineEdit::cursorRect() const
-{
- Q_D(const QLineEdit);
- return d->cursorRect();
-}
-
-/*! \reimp
- */
-void QLineEdit::inputMethodEvent(QInputMethodEvent *e)
-{
- Q_D(QLineEdit);
- if (d->control->isReadOnly()) {
- e->ignore();
- return;
- }
-
- if (echoMode() == PasswordEchoOnEdit && !d->control->passwordEchoEditing()) {
- // Clear the edit and reset to normal echo mode while entering input
- // method data; the echo mode switches back when the edit loses focus.
- // ### changes a public property, resets current content.
- d->updatePasswordEchoEditing(true);
- clear();
- }
-
-#ifdef QT_KEYPAD_NAVIGATION
- // Focus in if currently in navigation focus on the widget
- // Only focus in on preedits, to allow input methods to
- // commit text as they focus out without interfering with focus
- if (QApplication::keypadNavigationEnabled()
- && hasFocus() && !hasEditFocus()
- && !e->preeditString().isEmpty())
- setEditFocus(true);
-#endif
-
- d->control->processInputMethodEvent(e);
-
-#ifndef QT_NO_COMPLETER
- if (!e->commitString().isEmpty())
- d->control->complete(Qt::Key_unknown);
-#endif
-}
-
-/*!\reimp
-*/
-QVariant QLineEdit::inputMethodQuery(Qt::InputMethodQuery property) const
-{
- Q_D(const QLineEdit);
- switch(property) {
- case Qt::ImMicroFocus:
- return d->cursorRect();
- case Qt::ImFont:
- return font();
- case Qt::ImCursorPosition:
- return QVariant(d->control->cursor());
- case Qt::ImSurroundingText:
- return QVariant(text());
- case Qt::ImCurrentSelection:
- return QVariant(selectedText());
- case Qt::ImMaximumTextLength:
- return QVariant(maxLength());
- case Qt::ImAnchorPosition:
- if (d->control->selectionStart() == d->control->selectionEnd())
- return QVariant(d->control->cursor());
- else if (d->control->selectionStart() == d->control->cursor())
- return QVariant(d->control->selectionEnd());
- else
- return QVariant(d->control->selectionStart());
- default:
- return QVariant();
- }
-}
-
-/*!\reimp
-*/
-
-void QLineEdit::focusInEvent(QFocusEvent *e)
-{
- Q_D(QLineEdit);
- if (e->reason() == Qt::TabFocusReason ||
- e->reason() == Qt::BacktabFocusReason ||
- e->reason() == Qt::ShortcutFocusReason) {
- if (!d->control->inputMask().isEmpty())
- d->control->moveCursor(d->control->nextMaskBlank(0));
- else if (!d->control->hasSelectedText())
- selectAll();
- } else if (e->reason() == Qt::MouseFocusReason) {
- d->clickCausedFocus = 1;
- }
-#ifdef QT_KEYPAD_NAVIGATION
- if (!QApplication::keypadNavigationEnabled() || (hasEditFocus() && ( e->reason() == Qt::PopupFocusReason
-#ifdef Q_OS_SYMBIAN
- || e->reason() == Qt::ActiveWindowFocusReason
-#endif
- ))) {
-#endif
- d->control->setCursorBlinkPeriod(QApplication::cursorFlashTime());
- QStyleOptionFrameV2 opt;
- initStyleOption(&opt);
- if((!hasSelectedText() && d->control->preeditAreaText().isEmpty())
- || style()->styleHint(QStyle::SH_BlinkCursorWhenTextSelected, &opt, this))
- d->setCursorVisible(true);
-#ifdef Q_WS_MAC
- if (d->control->echoMode() == Password || d->control->echoMode() == NoEcho)
- qt_mac_secure_keyboard(true);
-#endif
-#ifdef QT_KEYPAD_NAVIGATION
- d->control->setCancelText(d->control->text());
- }
-#endif
-#ifndef QT_NO_COMPLETER
- if (d->control->completer()) {
- d->control->completer()->setWidget(this);
- QObject::connect(d->control->completer(), SIGNAL(activated(QString)),
- this, SLOT(setText(QString)));
- QObject::connect(d->control->completer(), SIGNAL(highlighted(QString)),
- this, SLOT(_q_completionHighlighted(QString)));
- }
-#endif
- update();
-}
-
-/*!\reimp
-*/
-
-void QLineEdit::focusOutEvent(QFocusEvent *e)
-{
- Q_D(QLineEdit);
- if (d->control->passwordEchoEditing()) {
- // Reset the echomode back to PasswordEchoOnEdit when the widget loses
- // focus.
- d->updatePasswordEchoEditing(false);
- }
-
- Qt::FocusReason reason = e->reason();
- if (reason != Qt::ActiveWindowFocusReason &&
- reason != Qt::PopupFocusReason)
- deselect();
-
- d->setCursorVisible(false);
- d->control->setCursorBlinkPeriod(0);
-#ifdef QT_KEYPAD_NAVIGATION
- // editingFinished() is already emitted on LeaveEditFocus
- if (!QApplication::keypadNavigationEnabled())
-#endif
- if (reason != Qt::PopupFocusReason
- || !(QApplication::activePopupWidget() && QApplication::activePopupWidget()->parentWidget() == this)) {
- if (hasAcceptableInput() || d->control->fixup())
- emit editingFinished();
-#ifdef QT3_SUPPORT
- emit lostFocus();
-#endif
- }
-#ifdef Q_WS_MAC
- if (d->control->echoMode() == Password || d->control->echoMode() == NoEcho)
- qt_mac_secure_keyboard(false);
-#endif
-#ifdef QT_KEYPAD_NAVIGATION
- d->control->setCancelText(QString());
-#endif
-#ifndef QT_NO_COMPLETER
- if (d->control->completer()) {
- QObject::disconnect(d->control->completer(), 0, this, 0);
- }
-#endif
- update();
-}
-
-/*!\reimp
-*/
-void QLineEdit::paintEvent(QPaintEvent *)
-{
- Q_D(QLineEdit);
- QPainter p(this);
-
- QRect r = rect();
- QPalette pal = palette();
-
- QStyleOptionFrameV2 panel;
- initStyleOption(&panel);
- style()->drawPrimitive(QStyle::PE_PanelLineEdit, &panel, &p, this);
- r = style()->subElementRect(QStyle::SE_LineEditContents, &panel, this);
- r.setX(r.x() + d->leftTextMargin);
- r.setY(r.y() + d->topTextMargin);
- r.setRight(r.right() - d->rightTextMargin);
- r.setBottom(r.bottom() - d->bottomTextMargin);
- p.setClipRect(r);
-
- QFontMetrics fm = fontMetrics();
- Qt::Alignment va = QStyle::visualAlignment(d->control->layoutDirection(), QFlag(d->alignment));
- switch (va & Qt::AlignVertical_Mask) {
- case Qt::AlignBottom:
- d->vscroll = r.y() + r.height() - fm.height() - d->verticalMargin;
- break;
- case Qt::AlignTop:
- d->vscroll = r.y() + d->verticalMargin;
- break;
- default:
- //center
- d->vscroll = r.y() + (r.height() - fm.height() + 1) / 2;
- break;
- }
- QRect lineRect(r.x() + d->horizontalMargin, d->vscroll, r.width() - 2*d->horizontalMargin, fm.height());
-
- int minLB = qMax(0, -fm.minLeftBearing());
- int minRB = qMax(0, -fm.minRightBearing());
-
- if (d->control->text().isEmpty()) {
- if (!hasFocus() && !d->placeholderText.isEmpty()) {
- QColor col = pal.text().color();
- col.setAlpha(128);
- QPen oldpen = p.pen();
- p.setPen(col);
- lineRect.adjust(minLB, 0, 0, 0);
- QString elidedText = fm.elidedText(d->placeholderText, Qt::ElideRight, lineRect.width());
- p.drawText(lineRect, va, elidedText);
- p.setPen(oldpen);
- return;
- }
- }
-
- int cix = qRound(d->control->cursorToX());
-
- // horizontal scrolling. d->hscroll is the left indent from the beginning
- // of the text line to the left edge of lineRect. we update this value
- // depending on the delta from the last paint event; in effect this means
- // the below code handles all scrolling based on the textline (widthUsed,
- // minLB, minRB), the line edit rect (lineRect) and the cursor position
- // (cix).
- int widthUsed = qRound(d->control->naturalTextWidth()) + 1 + minRB;
- if ((minLB + widthUsed) <= lineRect.width()) {
- // text fits in lineRect; use hscroll for alignment
- switch (va & ~(Qt::AlignAbsolute|Qt::AlignVertical_Mask)) {
- case Qt::AlignRight:
- d->hscroll = widthUsed - lineRect.width() + 1;
- break;
- case Qt::AlignHCenter:
- d->hscroll = (widthUsed - lineRect.width()) / 2;
- break;
- default:
- // Left
- d->hscroll = 0;
- break;
- }
- d->hscroll -= minLB;
- } else if (cix - d->hscroll >= lineRect.width()) {
- // text doesn't fit, cursor is to the right of lineRect (scroll right)
- d->hscroll = cix - lineRect.width() + 1;
- } else if (cix - d->hscroll < 0 && d->hscroll < widthUsed) {
- // text doesn't fit, cursor is to the left of lineRect (scroll left)
- d->hscroll = cix;
- } else if (widthUsed - d->hscroll < lineRect.width()) {
- // text doesn't fit, text document is to the left of lineRect; align
- // right
- d->hscroll = widthUsed - lineRect.width() + 1;
- } else {
- //in case the text is bigger than the lineedit, the hscroll can never be negative
- d->hscroll = qMax(0, d->hscroll);
- }
-
- // the y offset is there to keep the baseline constant in case we have script changes in the text.
- QPoint topLeft = lineRect.topLeft() - QPoint(d->hscroll, d->control->ascent() - fm.ascent());
-
- // draw text, selections and cursors
-#ifndef QT_NO_STYLE_STYLESHEET
- if (QStyleSheetStyle* cssStyle = qobject_cast<QStyleSheetStyle*>(style())) {
- cssStyle->styleSheetPalette(this, &panel, &pal);
- }
-#endif
- p.setPen(pal.text().color());
-
- int flags = QLineControl::DrawText;
-
-#ifdef QT_KEYPAD_NAVIGATION
- if (!QApplication::keypadNavigationEnabled() || hasEditFocus())
-#endif
- if (d->control->hasSelectedText() || (d->cursorVisible && !d->control->inputMask().isEmpty() && !d->control->isReadOnly())){
- flags |= QLineControl::DrawSelections;
- // Palette only used for selections/mask and may not be in sync
- if (d->control->palette() != pal
- || d->control->palette().currentColorGroup() != pal.currentColorGroup())
- d->control->setPalette(pal);
- }
-
- // Asian users see an IM selection text as cursor on candidate
- // selection phase of input method, so the ordinary cursor should be
- // invisible if we have a preedit string.
- if (d->cursorVisible && !d->control->isReadOnly())
- flags |= QLineControl::DrawCursor;
-
- d->control->setCursorWidth(style()->pixelMetric(QStyle::PM_TextCursorWidth));
- d->control->draw(&p, topLeft, r, flags);
-
-}
-
-
-#ifndef QT_NO_DRAGANDDROP
-/*!\reimp
-*/
-void QLineEdit::dragMoveEvent(QDragMoveEvent *e)
-{
- Q_D(QLineEdit);
- if (!d->control->isReadOnly() && e->mimeData()->hasFormat(QLatin1String("text/plain"))) {
- e->acceptProposedAction();
- d->control->moveCursor(d->xToPos(e->pos().x()), false);
- d->cursorVisible = true;
- update();
- }
-}
-
-/*!\reimp */
-void QLineEdit::dragEnterEvent(QDragEnterEvent * e)
-{
- QLineEdit::dragMoveEvent(e);
-}
-
-/*!\reimp */
-void QLineEdit::dragLeaveEvent(QDragLeaveEvent *)
-{
- Q_D(QLineEdit);
- if (d->cursorVisible) {
- d->cursorVisible = false;
- update();
- }
-}
-
-/*!\reimp */
-void QLineEdit::dropEvent(QDropEvent* e)
-{
- Q_D(QLineEdit);
- QString str = e->mimeData()->text();
-
- if (!str.isNull() && !d->control->isReadOnly()) {
- if (e->source() == this && e->dropAction() == Qt::CopyAction)
- deselect();
- int cursorPos = d->xToPos(e->pos().x());
- int selStart = cursorPos;
- int oldSelStart = d->control->selectionStart();
- int oldSelEnd = d->control->selectionEnd();
- d->control->moveCursor(cursorPos, false);
- d->cursorVisible = false;
- e->acceptProposedAction();
- insert(str);
- if (e->source() == this) {
- if (e->dropAction() == Qt::MoveAction) {
- if (selStart > oldSelStart && selStart <= oldSelEnd)
- setSelection(oldSelStart, str.length());
- else if (selStart > oldSelEnd)
- setSelection(selStart - str.length(), str.length());
- else
- setSelection(selStart, str.length());
- } else {
- setSelection(selStart, str.length());
- }
- }
- } else {
- e->ignore();
- update();
- }
-}
-
-#endif // QT_NO_DRAGANDDROP
-
-#ifndef QT_NO_CONTEXTMENU
-/*!
- Shows the standard context menu created with
- createStandardContextMenu().
-
- If you do not want the line edit to have a context menu, you can set
- its \l contextMenuPolicy to Qt::NoContextMenu. If you want to
- customize the context menu, reimplement this function. If you want
- to extend the standard context menu, reimplement this function, call
- createStandardContextMenu() and extend the menu returned.
-
- \snippet doc/src/snippets/code/src_gui_widgets_qlineedit.cpp 0
-
- The \a event parameter is used to obtain the position where
- the mouse cursor was when the event was generated.
-
- \sa setContextMenuPolicy()
-*/
-void QLineEdit::contextMenuEvent(QContextMenuEvent *event)
-{
- if (QMenu *menu = createStandardContextMenu()) {
- menu->setAttribute(Qt::WA_DeleteOnClose);
- menu->popup(event->globalPos());
- }
-}
-
-#if defined(Q_WS_WIN) || defined(Q_WS_X11)
- extern bool qt_use_rtl_extensions;
-#endif
-
-/*! This function creates the standard context menu which is shown
- when the user clicks on the line edit with the right mouse
- button. It is called from the default contextMenuEvent() handler.
- The popup menu's ownership is transferred to the caller.
-*/
-
-QMenu *QLineEdit::createStandardContextMenu()
-{
- Q_D(QLineEdit);
- QMenu *popup = new QMenu(this);
- popup->setObjectName(QLatin1String("qt_edit_menu"));
- QAction *action = 0;
-
- if (!isReadOnly()) {
- action = popup->addAction(QLineEdit::tr("&Undo") + ACCEL_KEY(QKeySequence::Undo));
- action->setEnabled(d->control->isUndoAvailable());
- connect(action, SIGNAL(triggered()), SLOT(undo()));
-
- action = popup->addAction(QLineEdit::tr("&Redo") + ACCEL_KEY(QKeySequence::Redo));
- action->setEnabled(d->control->isRedoAvailable());
- connect(action, SIGNAL(triggered()), SLOT(redo()));
-
- popup->addSeparator();
- }
-
-#ifndef QT_NO_CLIPBOARD
- if (!isReadOnly()) {
- action = popup->addAction(QLineEdit::tr("Cu&t") + ACCEL_KEY(QKeySequence::Cut));
- action->setEnabled(!d->control->isReadOnly() && d->control->hasSelectedText()
- && d->control->echoMode() == QLineEdit::Normal);
- connect(action, SIGNAL(triggered()), SLOT(cut()));
- }
-
- action = popup->addAction(QLineEdit::tr("&Copy") + ACCEL_KEY(QKeySequence::Copy));
- action->setEnabled(d->control->hasSelectedText()
- && d->control->echoMode() == QLineEdit::Normal);
- connect(action, SIGNAL(triggered()), SLOT(copy()));
-
- if (!isReadOnly()) {
- action = popup->addAction(QLineEdit::tr("&Paste") + ACCEL_KEY(QKeySequence::Paste));
- action->setEnabled(!d->control->isReadOnly() && !QApplication::clipboard()->text().isEmpty());
- connect(action, SIGNAL(triggered()), SLOT(paste()));
- }
-#endif
-
- if (!isReadOnly()) {
- action = popup->addAction(QLineEdit::tr("Delete"));
- action->setEnabled(!d->control->isReadOnly() && !d->control->text().isEmpty() && d->control->hasSelectedText());
- connect(action, SIGNAL(triggered()), d->control, SLOT(_q_deleteSelected()));
- }
-
- if (!popup->isEmpty())
- popup->addSeparator();
-
- action = popup->addAction(QLineEdit::tr("Select All") + ACCEL_KEY(QKeySequence::SelectAll));
- action->setEnabled(!d->control->text().isEmpty() && !d->control->allSelected());
- d->selectAllAction = action;
- connect(action, SIGNAL(triggered()), SLOT(selectAll()));
-
-#if !defined(QT_NO_IM)
- QInputContext *qic = inputContext();
- if (qic) {
- QList<QAction *> imActions = qic->actions();
- for (int i = 0; i < imActions.size(); ++i)
- popup->addAction(imActions.at(i));
- }
-#endif
-
-#if defined(Q_WS_WIN) || defined(Q_WS_X11)
- if (!d->control->isReadOnly() && qt_use_rtl_extensions) {
-#else
- if (!d->control->isReadOnly()) {
-#endif
- popup->addSeparator();
- QUnicodeControlCharacterMenu *ctrlCharacterMenu = new QUnicodeControlCharacterMenu(this, popup);
- popup->addMenu(ctrlCharacterMenu);
- }
- return popup;
-}
-#endif // QT_NO_CONTEXTMENU
-
-/*! \reimp */
-void QLineEdit::changeEvent(QEvent *ev)
-{
- Q_D(QLineEdit);
- switch(ev->type())
- {
- case QEvent::ActivationChange:
- if (!palette().isEqual(QPalette::Active, QPalette::Inactive))
- update();
- break;
- case QEvent::FontChange:
- d->control->setFont(font());
- break;
- case QEvent::StyleChange:
- {
- QStyleOptionFrameV2 opt;
- initStyleOption(&opt);
- d->control->setPasswordCharacter(style()->styleHint(QStyle::SH_LineEdit_PasswordCharacter, &opt, this));
- }
- update();
- break;
- default:
- break;
- }
- QWidget::changeEvent(ev);
-}
-
-/*!
- \fn void QLineEdit::repaintArea(int a, int b)
-
- Use update() instead.
-*/
-
-/*!
- \fn void QLineEdit::cursorLeft(bool mark, int steps)
-
- Use cursorForward() with a negative number of steps instead. For
- example, cursorForward(mark, -steps).
-*/
-
-/*!
- \fn void QLineEdit::cursorRight(bool mark, int steps)
-
- Use cursorForward() instead.
-*/
-
-/*!
- \fn bool QLineEdit::frame() const
-
- Use hasFrame() instead.
-*/
-
-/*!
- \fn void QLineEdit::clearValidator()
-
- Use setValidator(0) instead.
-*/
-
-/*!
- \fn bool QLineEdit::hasMarkedText() const
-
- Use hasSelectedText() instead.
-*/
-
-/*!
- \fn QString QLineEdit::markedText() const
-
- Use selectedText() instead.
-*/
-
-/*!
- \fn void QLineEdit::setFrameRect(QRect)
- \internal
-*/
-
-/*!
- \fn QRect QLineEdit::frameRect() const
- \internal
-*/
-/*!
- \enum QLineEdit::DummyFrame
- \internal
-
- \value Box
- \value Sunken
- \value Plain
- \value Raised
- \value MShadow
- \value NoFrame
- \value Panel
- \value StyledPanel
- \value HLine
- \value VLine
- \value GroupBoxPanel
- \value WinPanel
- \value ToolBarPanel
- \value MenuBarPanel
- \value PopupPanel
- \value LineEditPanel
- \value TabWidgetPanel
- \value MShape
-*/
-
-/*!
- \fn void QLineEdit::setFrameShadow(DummyFrame)
- \internal
-*/
-
-/*!
- \fn DummyFrame QLineEdit::frameShadow() const
- \internal
-*/
-
-/*!
- \fn void QLineEdit::setFrameShape(DummyFrame)
- \internal
-*/
-
-/*!
- \fn DummyFrame QLineEdit::frameShape() const
- \internal
-*/
-
-/*!
- \fn void QLineEdit::setFrameStyle(int)
- \internal
-*/
-
-/*!
- \fn int QLineEdit::frameStyle() const
- \internal
-*/
-
-/*!
- \fn int QLineEdit::frameWidth() const
- \internal
-*/
-
-/*!
- \fn void QLineEdit::setLineWidth(int)
- \internal
-*/
-
-/*!
- \fn int QLineEdit::lineWidth() const
- \internal
-*/
-
-/*!
- \fn void QLineEdit::setMargin(int margin)
- Sets the width of the margin around the contents of the widget to \a margin.
-
- Use QWidget::setContentsMargins() instead.
- \sa margin(), QWidget::setContentsMargins()
-*/
-
-/*!
- \fn int QLineEdit::margin() const
- Returns the width of the margin around the contents of the widget.
-
- Use QWidget::getContentsMargins() instead.
- \sa setMargin(), QWidget::getContentsMargins()
-*/
-
-/*!
- \fn void QLineEdit::setMidLineWidth(int)
- \internal
-*/
-
-/*!
- \fn int QLineEdit::midLineWidth() const
- \internal
-*/
-
-QT_END_NAMESPACE
-
-#include "moc_qlineedit.cpp"
-
-#endif // QT_NO_LINEEDIT
diff --git a/src/gui/widgets/qlineedit.h b/src/gui/widgets/qlineedit.h
deleted file mode 100644
index 73d228907f..0000000000
--- a/src/gui/widgets/qlineedit.h
+++ /dev/null
@@ -1,300 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QLINEEDIT_H
-#define QLINEEDIT_H
-
-#include <QtGui/qframe.h>
-#include <QtGui/qtextcursor.h>
-#include <QtCore/qstring.h>
-#include <QtCore/qmargins.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_LINEEDIT
-
-class QValidator;
-class QMenu;
-class QLineEditPrivate;
-class QCompleter;
-class QStyleOptionFrame;
-class QAbstractSpinBox;
-class QDateTimeEdit;
-
-class Q_GUI_EXPORT QLineEdit : public QWidget
-{
- Q_OBJECT
-
- Q_ENUMS(EchoMode)
- Q_PROPERTY(QString inputMask READ inputMask WRITE setInputMask)
- Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged USER true)
- Q_PROPERTY(int maxLength READ maxLength WRITE setMaxLength)
- Q_PROPERTY(bool frame READ hasFrame WRITE setFrame)
- Q_PROPERTY(EchoMode echoMode READ echoMode WRITE setEchoMode)
- Q_PROPERTY(QString displayText READ displayText)
- Q_PROPERTY(int cursorPosition READ cursorPosition WRITE setCursorPosition)
- Q_PROPERTY(Qt::Alignment alignment READ alignment WRITE setAlignment)
- Q_PROPERTY(bool modified READ isModified WRITE setModified DESIGNABLE false)
- Q_PROPERTY(bool hasSelectedText READ hasSelectedText)
- Q_PROPERTY(QString selectedText READ selectedText)
- Q_PROPERTY(bool dragEnabled READ dragEnabled WRITE setDragEnabled)
- Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly)
- Q_PROPERTY(bool undoAvailable READ isUndoAvailable)
- Q_PROPERTY(bool redoAvailable READ isRedoAvailable)
- Q_PROPERTY(bool acceptableInput READ hasAcceptableInput)
- Q_PROPERTY(QString placeholderText READ placeholderText WRITE setPlaceholderText)
- Q_PROPERTY(Qt::CursorMoveStyle cursorMoveStyle READ cursorMoveStyle WRITE setCursorMoveStyle)
-
-public:
- explicit QLineEdit(QWidget* parent=0);
- explicit QLineEdit(const QString &, QWidget* parent=0);
-#ifdef QT3_SUPPORT
- QT3_SUPPORT_CONSTRUCTOR QLineEdit(QWidget* parent, const char* name);
- QT3_SUPPORT_CONSTRUCTOR QLineEdit(const QString &, QWidget* parent, const char* name);
- QT3_SUPPORT_CONSTRUCTOR QLineEdit(const QString &, const QString &, QWidget* parent=0, const char* name=0);
-#endif
- ~QLineEdit();
-
- QString text() const;
-
- QString displayText() const;
-
- QString placeholderText() const;
- void setPlaceholderText(const QString &);
-
- int maxLength() const;
- void setMaxLength(int);
-
- void setFrame(bool);
- bool hasFrame() const;
-
- enum EchoMode { Normal, NoEcho, Password, PasswordEchoOnEdit };
- EchoMode echoMode() const;
- void setEchoMode(EchoMode);
-
- bool isReadOnly() const;
- void setReadOnly(bool);
-
-#ifndef QT_NO_VALIDATOR
- void setValidator(const QValidator *);
- const QValidator * validator() const;
-#endif
-
-#ifndef QT_NO_COMPLETER
- void setCompleter(QCompleter *completer);
- QCompleter *completer() const;
-#endif
-
- QSize sizeHint() const;
- QSize minimumSizeHint() const;
-
- int cursorPosition() const;
- void setCursorPosition(int);
- int cursorPositionAt(const QPoint &pos);
-
- void setAlignment(Qt::Alignment flag);
- Qt::Alignment alignment() const;
-
- void cursorForward(bool mark, int steps = 1);
- void cursorBackward(bool mark, int steps = 1);
- void cursorWordForward(bool mark);
- void cursorWordBackward(bool mark);
- void backspace();
- void del();
- void home(bool mark);
- void end(bool mark);
-
- bool isModified() const;
- void setModified(bool);
-
- void setSelection(int, int);
- bool hasSelectedText() const;
- QString selectedText() const;
- int selectionStart() const;
-
- bool isUndoAvailable() const;
- bool isRedoAvailable() const;
-
- void setDragEnabled(bool b);
- bool dragEnabled() const;
-
- void setCursorMoveStyle(Qt::CursorMoveStyle style);
- Qt::CursorMoveStyle cursorMoveStyle() const;
-
- QString inputMask() const;
- void setInputMask(const QString &inputMask);
- bool hasAcceptableInput() const;
-
- void setTextMargins(int left, int top, int right, int bottom);
- void setTextMargins(const QMargins &margins);
- void getTextMargins(int *left, int *top, int *right, int *bottom) const;
- QMargins textMargins() const;
-
-public Q_SLOTS:
- void setText(const QString &);
- void clear();
- void selectAll();
- void undo();
- void redo();
-#ifndef QT_NO_CLIPBOARD
- void cut();
- void copy() const;
- void paste();
-#endif
-
-public:
- void deselect();
- void insert(const QString &);
-#ifndef QT_NO_CONTEXTMENU
- QMenu *createStandardContextMenu();
-#endif
-
-Q_SIGNALS:
- void textChanged(const QString &);
- void textEdited(const QString &);
- void cursorPositionChanged(int, int);
- void returnPressed();
- void editingFinished();
- void selectionChanged();
-
-protected:
- void mousePressEvent(QMouseEvent *);
- void mouseMoveEvent(QMouseEvent *);
- void mouseReleaseEvent(QMouseEvent *);
- void mouseDoubleClickEvent(QMouseEvent *);
- void keyPressEvent(QKeyEvent *);
- void focusInEvent(QFocusEvent *);
- void focusOutEvent(QFocusEvent *);
- void paintEvent(QPaintEvent *);
-#ifndef QT_NO_DRAGANDDROP
- void dragEnterEvent(QDragEnterEvent *);
- void dragMoveEvent(QDragMoveEvent *e);
- void dragLeaveEvent(QDragLeaveEvent *e);
- void dropEvent(QDropEvent *);
-#endif
- void changeEvent(QEvent *);
-#ifndef QT_NO_CONTEXTMENU
- void contextMenuEvent(QContextMenuEvent *);
-#endif
-#ifdef QT3_SUPPORT
- inline QT3_SUPPORT void repaintArea(int, int) { update(); }
-#endif
-
- void inputMethodEvent(QInputMethodEvent *);
- void initStyleOption(QStyleOptionFrame *option) const;
-public:
- QVariant inputMethodQuery(Qt::InputMethodQuery) const;
- bool event(QEvent *);
-protected:
- QRect cursorRect() const;
-
-public:
-#ifdef QT3_SUPPORT
- inline QT3_SUPPORT void clearModified() { setModified(false); }
- inline QT3_SUPPORT void cursorLeft(bool mark, int steps = 1) { cursorForward(mark, -steps); }
- inline QT3_SUPPORT void cursorRight(bool mark, int steps = 1) { cursorForward(mark, steps); }
- QT3_SUPPORT bool validateAndSet(const QString &, int, int, int);
- inline QT3_SUPPORT bool frame() const { return hasFrame(); }
-#ifndef QT_NO_VALIDATOR
- inline QT3_SUPPORT void clearValidator() { setValidator(0); }
-#endif
- inline QT3_SUPPORT bool hasMarkedText() const { return hasSelectedText(); }
- inline QT3_SUPPORT QString markedText() const { return selectedText(); }
- QT3_SUPPORT bool edited() const;
- QT3_SUPPORT void setEdited(bool);
- QT3_SUPPORT int characterAt(int, QChar*) const;
- QT3_SUPPORT bool getSelection(int *, int *);
-
- QT3_SUPPORT void setFrameRect(QRect) {}
- QT3_SUPPORT QRect frameRect() const { return QRect(); }
- enum DummyFrame { Box, Sunken, Plain, Raised, MShadow, NoFrame, Panel, StyledPanel,
- HLine, VLine, GroupBoxPanel, WinPanel, ToolBarPanel, MenuBarPanel,
- PopupPanel, LineEditPanel, TabWidgetPanel, MShape };
- QT3_SUPPORT void setFrameShadow(DummyFrame) {}
- QT3_SUPPORT DummyFrame frameShadow() const { return Plain; }
- QT3_SUPPORT void setFrameShape(DummyFrame) {}
- QT3_SUPPORT DummyFrame frameShape() const { return NoFrame; }
- QT3_SUPPORT void setFrameStyle(int) {}
- QT3_SUPPORT int frameStyle() const { return 0; }
- QT3_SUPPORT int frameWidth() const { return 0; }
- QT3_SUPPORT void setLineWidth(int) {}
- QT3_SUPPORT int lineWidth() const { return 0; }
- QT3_SUPPORT void setMargin(int margin) { setContentsMargins(margin, margin, margin, margin); }
- QT3_SUPPORT int margin() const
- { int margin; int dummy; getContentsMargins(&margin, &dummy, &dummy, &dummy); return margin; }
- QT3_SUPPORT void setMidLineWidth(int) {}
- QT3_SUPPORT int midLineWidth() const { return 0; }
-
-Q_SIGNALS:
- QT_MOC_COMPAT void lostFocus();
-#endif
-
-private:
- friend class QAbstractSpinBox;
-#ifdef QT_KEYPAD_NAVIGATION
- friend class QDateTimeEdit;
-#endif
- Q_DISABLE_COPY(QLineEdit)
- Q_DECLARE_PRIVATE(QLineEdit)
- Q_PRIVATE_SLOT(d_func(), void _q_handleWindowActivate())
- Q_PRIVATE_SLOT(d_func(), void _q_textEdited(const QString &))
- Q_PRIVATE_SLOT(d_func(), void _q_cursorPositionChanged(int, int))
-#ifndef QT_NO_COMPLETER
- Q_PRIVATE_SLOT(d_func(), void _q_completionHighlighted(QString))
-#endif
-#ifdef QT_KEYPAD_NAVIGATION
- Q_PRIVATE_SLOT(d_func(), void _q_editFocusChange(bool))
-#endif
- Q_PRIVATE_SLOT(d_func(), void _q_selectionChanged())
- Q_PRIVATE_SLOT(d_func(), void _q_updateNeeded(const QRect &))
-};
-
-#endif // QT_NO_LINEEDIT
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QLINEEDIT_H
diff --git a/src/gui/widgets/qlineedit_p.cpp b/src/gui/widgets/qlineedit_p.cpp
deleted file mode 100644
index 090c0b6641..0000000000
--- a/src/gui/widgets/qlineedit_p.cpp
+++ /dev/null
@@ -1,292 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qlineedit.h"
-#include "qlineedit_p.h"
-
-#ifndef QT_NO_LINEEDIT
-
-#include "qabstractitemview.h"
-#include "qclipboard.h"
-#ifndef QT_NO_ACCESSIBILITY
-#include "qaccessible.h"
-#endif
-#ifndef QT_NO_IM
-#include "qinputcontext.h"
-#include "qlist.h"
-#endif
-
-QT_BEGIN_NAMESPACE
-
-const int QLineEditPrivate::verticalMargin(1);
-const int QLineEditPrivate::horizontalMargin(2);
-
-QRect QLineEditPrivate::adjustedControlRect(const QRect &rect) const
-{
- QRect cr = adjustedContentsRect();
- int cix = cr.x() - hscroll + horizontalMargin;
- return rect.translated(QPoint(cix, vscroll));
-}
-
-int QLineEditPrivate::xToPos(int x, QTextLine::CursorPosition betweenOrOn) const
-{
- QRect cr = adjustedContentsRect();
- x-= cr.x() - hscroll + horizontalMargin;
- return control->xToPos(x, betweenOrOn);
-}
-
-QRect QLineEditPrivate::cursorRect() const
-{
- return adjustedControlRect(control->cursorRect());
-}
-
-#ifndef QT_NO_COMPLETER
-
-void QLineEditPrivate::_q_completionHighlighted(QString newText)
-{
- Q_Q(QLineEdit);
- if (control->completer()->completionMode() != QCompleter::InlineCompletion) {
- q->setText(newText);
- } else {
- int c = control->cursor();
- QString text = control->text();
- q->setText(text.left(c) + newText.mid(c));
- control->moveCursor(control->end(), false);
- control->moveCursor(c, true);
- }
-}
-
-#endif // QT_NO_COMPLETER
-
-void QLineEditPrivate::_q_handleWindowActivate()
-{
- Q_Q(QLineEdit);
- if (!q->hasFocus() && control->hasSelectedText())
- control->deselect();
-}
-
-void QLineEditPrivate::_q_textEdited(const QString &text)
-{
- Q_Q(QLineEdit);
- emit q->textEdited(text);
-#ifndef QT_NO_COMPLETER
- if (control->completer()
- && control->completer()->completionMode() != QCompleter::InlineCompletion)
- control->complete(-1); // update the popup on cut/paste/del
-#endif
-}
-
-void QLineEditPrivate::_q_cursorPositionChanged(int from, int to)
-{
- Q_Q(QLineEdit);
- q->update();
- emit q->cursorPositionChanged(from, to);
-}
-
-#ifdef QT_KEYPAD_NAVIGATION
-void QLineEditPrivate::_q_editFocusChange(bool e)
-{
- Q_Q(QLineEdit);
- q->setEditFocus(e);
-}
-#endif
-
-void QLineEditPrivate::_q_selectionChanged()
-{
- Q_Q(QLineEdit);
- if (!control->text().isEmpty() && control->preeditAreaText().isEmpty()) {
- QStyleOptionFrameV2 opt;
- q->initStyleOption(&opt);
- bool showCursor = control->hasSelectedText() ?
- q->style()->styleHint(QStyle::SH_BlinkCursorWhenTextSelected, &opt, q):
- q->hasFocus();
- setCursorVisible(showCursor);
- }
-
- emit q->selectionChanged();
-}
-
-void QLineEditPrivate::_q_updateNeeded(const QRect &rect)
-{
- q_func()->update(adjustedControlRect(rect));
-}
-
-void QLineEditPrivate::init(const QString& txt)
-{
- Q_Q(QLineEdit);
- control = new QLineControl(txt);
- control->setParent(q);
- control->setFont(q->font());
- QObject::connect(control, SIGNAL(textChanged(QString)),
- q, SIGNAL(textChanged(QString)));
- QObject::connect(control, SIGNAL(textEdited(QString)),
- q, SLOT(_q_textEdited(QString)));
- QObject::connect(control, SIGNAL(cursorPositionChanged(int,int)),
- q, SLOT(_q_cursorPositionChanged(int,int)));
- QObject::connect(control, SIGNAL(selectionChanged()),
- q, SLOT(_q_selectionChanged()));
- QObject::connect(control, SIGNAL(accepted()),
- q, SIGNAL(returnPressed()));
- QObject::connect(control, SIGNAL(editingFinished()),
- q, SIGNAL(editingFinished()));
-#ifdef QT_KEYPAD_NAVIGATION
- QObject::connect(control, SIGNAL(editFocusChange(bool)),
- q, SLOT(_q_editFocusChange(bool)));
-#endif
- QObject::connect(control, SIGNAL(cursorPositionChanged(int,int)),
- q, SLOT(updateMicroFocus()));
-
- QObject::connect(control, SIGNAL(textChanged(const QString &)),
- q, SLOT(updateMicroFocus()));
-
- // for now, going completely overboard with updates.
- QObject::connect(control, SIGNAL(selectionChanged()),
- q, SLOT(update()));
-
- QObject::connect(control, SIGNAL(displayTextChanged(QString)),
- q, SLOT(update()));
-
- QObject::connect(control, SIGNAL(updateNeeded(QRect)),
- q, SLOT(_q_updateNeeded(QRect)));
-
- QStyleOptionFrameV2 opt;
- q->initStyleOption(&opt);
- control->setPasswordCharacter(q->style()->styleHint(QStyle::SH_LineEdit_PasswordCharacter, &opt, q));
-#ifndef QT_NO_CURSOR
- q->setCursor(Qt::IBeamCursor);
-#endif
- q->setFocusPolicy(Qt::StrongFocus);
- q->setAttribute(Qt::WA_InputMethodEnabled);
- // Specifies that this widget can use more, but is able to survive on
- // less, horizontal space; and is fixed vertically.
- q->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed, QSizePolicy::LineEdit));
- q->setBackgroundRole(QPalette::Base);
- q->setAttribute(Qt::WA_KeyCompression);
- q->setMouseTracking(true);
- q->setAcceptDrops(true);
-
- q->setAttribute(Qt::WA_MacShowFocusRect);
-}
-
-QRect QLineEditPrivate::adjustedContentsRect() const
-{
- Q_Q(const QLineEdit);
- QStyleOptionFrameV2 opt;
- q->initStyleOption(&opt);
- QRect r = q->style()->subElementRect(QStyle::SE_LineEditContents, &opt, q);
- r.setX(r.x() + leftTextMargin);
- r.setY(r.y() + topTextMargin);
- r.setRight(r.right() - rightTextMargin);
- r.setBottom(r.bottom() - bottomTextMargin);
- return r;
-}
-
-void QLineEditPrivate::setCursorVisible(bool visible)
-{
- Q_Q(QLineEdit);
- if ((bool)cursorVisible == visible)
- return;
- cursorVisible = visible;
- if (control->inputMask().isEmpty())
- q->update(cursorRect());
- else
- q->update();
-}
-
-void QLineEditPrivate::updatePasswordEchoEditing(bool editing)
-{
- Q_Q(QLineEdit);
- control->updatePasswordEchoEditing(editing);
- q->setAttribute(Qt::WA_InputMethodEnabled, shouldEnableInputMethod());
-}
-
-/*!
- This function is not intended as polymorphic usage. Just a shared code
- fragment that calls QInputContext::mouseHandler for this
- class.
-*/
-bool QLineEditPrivate::sendMouseEventToInputContext( QMouseEvent *e )
-{
-#if !defined QT_NO_IM
- Q_Q(QLineEdit);
- if ( control->composeMode() ) {
- int tmp_cursor = xToPos(e->pos().x());
- int mousePos = tmp_cursor - control->cursor();
- if ( mousePos < 0 || mousePos > control->preeditAreaText().length() ) {
- mousePos = -1;
- // don't send move events outside the preedit area
- if ( e->type() == QEvent::MouseMove )
- return true;
- }
-
- QInputContext *qic = q->inputContext();
- if ( qic )
- // may be causing reset() in some input methods
- qic->mouseHandler(mousePos, e);
- if (!control->preeditAreaText().isEmpty())
- return true;
- }
-#else
- Q_UNUSED(e);
-#endif
-
- return false;
-}
-
-#ifndef QT_NO_DRAGANDDROP
-void QLineEditPrivate::drag()
-{
- Q_Q(QLineEdit);
- dndTimer.stop();
- QMimeData *data = new QMimeData;
- data->setText(control->selectedText());
- QDrag *drag = new QDrag(q);
- drag->setMimeData(data);
- Qt::DropAction action = drag->start();
- if (action == Qt::MoveAction && !control->isReadOnly() && drag->target() != q)
- control->removeSelection();
-}
-
-#endif // QT_NO_DRAGANDDROP
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/gui/widgets/qlineedit_p.h b/src/gui/widgets/qlineedit_p.h
deleted file mode 100644
index f396af69a7..0000000000
--- a/src/gui/widgets/qlineedit_p.h
+++ /dev/null
@@ -1,155 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QLINEEDIT_P_H
-#define QLINEEDIT_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "QtCore/qglobal.h"
-
-#ifndef QT_NO_LINEEDIT
-#include "private/qwidget_p.h"
-#include "QtGui/qlineedit.h"
-#include "QtGui/qtextlayout.h"
-#include "QtGui/qstyleoption.h"
-#include "QtCore/qbasictimer.h"
-#include "QtGui/qcompleter.h"
-#include "QtCore/qpointer.h"
-#include "QtGui/qlineedit.h"
-
-#include "private/qlinecontrol_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class QLineEditPrivate : public QWidgetPrivate
-{
- Q_DECLARE_PUBLIC(QLineEdit)
-public:
-
- QLineEditPrivate()
- : control(0), frame(1), contextMenuEnabled(1), cursorVisible(0),
- dragEnabled(0), clickCausedFocus(0), hscroll(0), vscroll(0),
- alignment(Qt::AlignLeading | Qt::AlignVCenter),
- leftTextMargin(0), topTextMargin(0), rightTextMargin(0), bottomTextMargin(0)
- {
- }
-
- ~QLineEditPrivate()
- {
- }
-
- QLineControl *control;
-
-#ifndef QT_NO_CONTEXTMENU
- QPointer<QAction> selectAllAction;
-#endif
- void init(const QString&);
-
- QRect adjustedControlRect(const QRect &) const;
-
- int xToPos(int x, QTextLine::CursorPosition = QTextLine::CursorBetweenCharacters) const;
- QRect cursorRect() const;
- void setCursorVisible(bool visible);
-
- void updatePasswordEchoEditing(bool);
-
- inline bool shouldEnableInputMethod() const
- {
- return !control->isReadOnly();
- }
-
- QPoint tripleClick;
- QBasicTimer tripleClickTimer;
- uint frame : 1;
- uint contextMenuEnabled : 1;
- uint cursorVisible : 1;
- uint dragEnabled : 1;
- uint clickCausedFocus : 1;
- int hscroll;
- int vscroll;
- uint alignment;
- static const int verticalMargin;
- static const int horizontalMargin;
-
- bool sendMouseEventToInputContext(QMouseEvent *e);
-
- QRect adjustedContentsRect() const;
-
- void _q_handleWindowActivate();
- void _q_textEdited(const QString &);
- void _q_cursorPositionChanged(int, int);
-#ifdef QT_KEYPAD_NAVIGATION
- void _q_editFocusChange(bool);
-#endif
- void _q_selectionChanged();
- void _q_updateNeeded(const QRect &);
-#ifndef QT_NO_COMPLETER
- void _q_completionHighlighted(QString);
-#endif
-#ifndef QT_NO_DRAGANDDROP
- QPoint dndPos;
- QBasicTimer dndTimer;
- void drag();
-#endif
-
- int leftTextMargin;
- int topTextMargin;
- int rightTextMargin;
- int bottomTextMargin;
-
- QString placeholderText;
-};
-
-#endif // QT_NO_LINEEDIT
-
-QT_END_NAMESPACE
-
-#endif // QLINEEDIT_P_H
diff --git a/src/gui/widgets/qmaccocoaviewcontainer_mac.h b/src/gui/widgets/qmaccocoaviewcontainer_mac.h
deleted file mode 100644
index b56dda46c6..0000000000
--- a/src/gui/widgets/qmaccocoaviewcontainer_mac.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QCOCOAVIEWCONTAINER_H
-#define QCOCOAVIEWCONTAINER_H
-
-#include <QtGui/QWidget>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QMacCocoaViewContainerPrivate;
-
-class Q_GUI_EXPORT QMacCocoaViewContainer : public QWidget
-{
- Q_OBJECT
-public:
- QMacCocoaViewContainer(void *cocoaViewToWrap, QWidget *parent = 0);
- virtual ~QMacCocoaViewContainer();
-
- void setCocoaView(void *cocoaViewToWrap);
- void *cocoaView() const;
-
-private:
- Q_DECLARE_PRIVATE(QMacCocoaViewContainer)
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QCOCOAVIEWCONTAINER_H
diff --git a/src/gui/widgets/qmacnativewidget_mac.h b/src/gui/widgets/qmacnativewidget_mac.h
deleted file mode 100644
index 884ee19e32..0000000000
--- a/src/gui/widgets/qmacnativewidget_mac.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QMACNATIVEWIDGET_H
-#define QMACNATIVEWIDGET_H
-
-#include <QtGui/QWidget>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QMacNativeWidgetPrivate;
-class Q_GUI_EXPORT QMacNativeWidget : public QWidget
-{
- Q_OBJECT
-public:
- QMacNativeWidget(void *parentRef = 0);
- ~QMacNativeWidget();
-
- QSize sizeHint() const;
-
-protected:
- bool event(QEvent *ev);
-
-private:
- Q_DECLARE_PRIVATE(QMacNativeWidget)
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QMACNATIVEWIDGET_H
diff --git a/src/gui/widgets/qmainwindow.cpp b/src/gui/widgets/qmainwindow.cpp
deleted file mode 100644
index f214bcb1a5..0000000000
--- a/src/gui/widgets/qmainwindow.cpp
+++ /dev/null
@@ -1,1686 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-//#define QT_EXPERIMENTAL_CLIENT_DECORATIONS
-
-#include "qmainwindow.h"
-#include "qmainwindowlayout_p.h"
-
-#ifndef QT_NO_MAINWINDOW
-
-#include "qdockwidget.h"
-#include "qtoolbar.h"
-
-#include <qapplication.h>
-#include <qmenubar.h>
-#include <qstatusbar.h>
-#include <qevent.h>
-#include <qstyle.h>
-#include <qdebug.h>
-#include <qpainter.h>
-
-#include <private/qwidget_p.h>
-#include "qtoolbar_p.h"
-#include "qwidgetanimator_p.h"
-#ifdef Q_WS_MAC
-#include <private/qt_mac_p.h>
-#include <private/qt_cocoa_helpers_mac_p.h>
-QT_BEGIN_NAMESPACE
-extern OSWindowRef qt_mac_window_for(const QWidget *); // qwidget_mac.cpp
-QT_END_NAMESPACE
-#endif
-
-QT_BEGIN_NAMESPACE
-
-class QMainWindowPrivate : public QWidgetPrivate
-{
- Q_DECLARE_PUBLIC(QMainWindow)
-public:
- inline QMainWindowPrivate()
- : layout(0), explicitIconSize(false), toolButtonStyle(Qt::ToolButtonIconOnly)
-#ifdef Q_WS_MAC
- , useHIToolBar(false)
- , activateUnifiedToolbarAfterFullScreen(false)
-#endif
-#if !defined(QT_NO_DOCKWIDGET) && !defined(QT_NO_CURSOR)
- , hasOldCursor(false) , cursorAdjusted(false)
-#endif
- { }
- QMainWindowLayout *layout;
- QSize iconSize;
- bool explicitIconSize;
- Qt::ToolButtonStyle toolButtonStyle;
-#ifdef Q_WS_MAC
- bool useHIToolBar;
- bool activateUnifiedToolbarAfterFullScreen;
-#endif
- void init();
- QList<int> hoverSeparator;
- QPoint hoverPos;
-
-#if !defined(QT_NO_DOCKWIDGET) && !defined(QT_NO_CURSOR)
- QCursor separatorCursor(const QList<int> &path) const;
- void adjustCursor(const QPoint &pos);
- QCursor oldCursor;
- uint hasOldCursor : 1;
- uint cursorAdjusted : 1;
-#endif
-
- static inline QMainWindowLayout *mainWindowLayout(const QMainWindow *mainWindow)
- {
- return mainWindow ? mainWindow->d_func()->layout : static_cast<QMainWindowLayout *>(0);
- }
-};
-
-QMainWindowLayout *qt_mainwindow_layout(const QMainWindow *mainWindow)
-{
- return QMainWindowPrivate::mainWindowLayout(mainWindow);
-}
-
-#ifdef QT_EXPERIMENTAL_CLIENT_DECORATIONS
-Q_GUI_EXPORT void qt_setMainWindowTitleWidget(QMainWindow *mainWindow, Qt::DockWidgetArea area, QWidget *widget)
-{
- QGridLayout *topLayout = qobject_cast<QGridLayout *>(mainWindow->layout());
- Q_ASSERT(topLayout);
-
- int row = 0;
- int column = 0;
-
- switch (area) {
- case Qt::LeftDockWidgetArea:
- row = 1;
- column = 0;
- break;
- case Qt::TopDockWidgetArea:
- row = 0;
- column = 1;
- break;
- case Qt::BottomDockWidgetArea:
- row = 2;
- column = 1;
- break;
- case Qt::RightDockWidgetArea:
- row = 1;
- column = 2;
- break;
- default:
- Q_ASSERT_X(false, "qt_setMainWindowTitleWidget", "Unknown area");
- return;
- }
-
- if (QLayoutItem *oldItem = topLayout->itemAtPosition(row, column))
- delete oldItem->widget();
- topLayout->addWidget(widget, row, column);
-}
-#endif
-
-void QMainWindowPrivate::init()
-{
- Q_Q(QMainWindow);
-
-#ifdef QT_EXPERIMENTAL_CLIENT_DECORATIONS
- QGridLayout *topLayout = new QGridLayout(q);
- topLayout->setContentsMargins(0, 0, 0, 0);
-
- layout = new QMainWindowLayout(q, topLayout);
-
- topLayout->addItem(layout, 1, 1);
-#else
- layout = new QMainWindowLayout(q, 0);
-#endif
-
- const int metric = q->style()->pixelMetric(QStyle::PM_ToolBarIconSize, 0, q);
- iconSize = QSize(metric, metric);
- q->setAttribute(Qt::WA_Hover);
-}
-
-/*
- The Main Window:
-
- +----------------------------------------------------------+
- | Menu Bar |
- +----------------------------------------------------------+
- | Tool Bar Area |
- | +--------------------------------------------------+ |
- | | Dock Window Area | |
- | | +------------------------------------------+ | |
- | | | | | |
- | | | Central Widget | | |
- | | | | | |
- | | | | | |
- | | | | | |
- | | | | | |
- | | | | | |
- | | | | | |
- | | | | | |
- | | | | | |
- | | | | | |
- | | | | | |
- | | +------------------------------------------+ | |
- | | | |
- | +--------------------------------------------------+ |
- | |
- +----------------------------------------------------------+
- | Status Bar |
- +----------------------------------------------------------+
-
-*/
-
-/*!
- \class QMainWindow
- \brief The QMainWindow class provides a main application
- window.
- \ingroup mainwindow-classes
-
-
- \tableofcontents
-
- \section1 Qt Main Window Framework
-
- A main window provides a framework for building an
- application's user interface. Qt has QMainWindow and its \l{Main
- Window and Related Classes}{related classes} for main window
- management. QMainWindow has its own layout to which you can add
- \l{QToolBar}s, \l{QDockWidget}s, a
- QMenuBar, and a QStatusBar. The layout has a center area that can
- be occupied by any kind of widget. You can see an image of the
- layout below.
-
- \image mainwindowlayout.png
-
- \note Creating a main window without a central widget is not supported.
- You must have a central widget even if it is just a placeholder.
-
- \section1 Creating Main Window Components
-
- A central widget will typically be a standard Qt widget such
- as a QTextEdit or a QGraphicsView. Custom widgets can also be
- used for advanced applications. You set the central widget with \c
- setCentralWidget().
-
- Main windows have either a single (SDI) or multiple (MDI)
- document interface. You create MDI applications in Qt by using a
- QMdiArea as the central widget.
-
- We will now examine each of the other widgets that can be
- added to a main window. We give examples on how to create and add
- them.
-
- \section2 Creating Menus
-
- Qt implements menus in QMenu and QMainWindow keeps them in a
- QMenuBar. \l{QAction}{QAction}s are added to the menus, which
- display them as menu items.
-
- You can add new menus to the main window's menu bar by calling
- \c menuBar(), which returns the QMenuBar for the window, and then
- add a menu with QMenuBar::addMenu().
-
- QMainWindow comes with a default menu bar, but you can also
- set one yourself with \c setMenuBar(). If you wish to implement a
- custom menu bar (i.e., not use the QMenuBar widget), you can set it
- with \c setMenuWidget().
-
- An example of how to create menus follows:
-
- \snippet examples/mainwindows/application/mainwindow.cpp 26
-
- The \c createPopupMenu() function creates popup menus when the
- main window receives context menu events. The default
- implementation generates a menu with the checkable actions from
- the dock widgets and toolbars. You can reimplement \c
- createPopupMenu() for a custom menu.
-
- \section2 Creating Toolbars
-
- Toolbars are implemented in the QToolBar class. You add a
- toolbar to a main window with \c addToolBar().
-
- You control the initial position of toolbars by assigning them
- to a specific Qt::ToolBarArea. You can split an area by inserting
- a toolbar break - think of this as a line break in text editing -
- with \c addToolBarBreak() or \c insertToolBarBreak(). You can also
- restrict placement by the user with QToolBar::setAllowedAreas()
- and QToolBar::setMovable().
-
- The size of toolbar icons can be retrieved with \c iconSize().
- The sizes are platform dependent; you can set a fixed size with \c
- setIconSize(). You can alter the appearance of all tool buttons in
- the toolbars with \c setToolButtonStyle().
-
- An example of toolbar creation follows:
-
- \snippet examples/mainwindows/application/mainwindow.cpp 29
-
- \section2 Creating Dock Widgets
-
- Dock widgets are implemented in the QDockWidget class. A dock
- widget is a window that can be docked into the main window. You
- add dock widgets to a main window with \c addDockWidget().
-
- There are four dock widget areas as given by the
- Qt::DockWidgetArea enum: left, right, top, and bottom. You can
- specify which dock widget area that should occupy the corners
- where the areas overlap with \c setCorner(). By default
- each area can only contain one row (vertical or horizontal) of
- dock widgets, but if you enable nesting with \c
- setDockNestingEnabled(), dock widgets can be added in either
- direction.
-
- Two dock widgets may also be stacked on top of each other. A
- QTabBar is then used to select which of the widgets that should be
- displayed.
-
- We give an example of how to create and add dock widgets to a
- main window:
-
- \snippet doc/src/snippets/mainwindowsnippet.cpp 0
-
- \section2 The Status Bar
-
- You can set a status bar with \c setStatusBar(), but one is
- created the first time \c statusBar() (which returns the main
- window's status bar) is called. See QStatusBar for information on
- how to use it.
-
- \section1 Storing State
-
- QMainWindow can store the state of its layout with \c
- saveState(); it can later be retrieved with \c restoreState(). It
- is the position and size (relative to the size of the main window)
- of the toolbars and dock widgets that are stored.
-
- \sa QMenuBar, QToolBar, QStatusBar, QDockWidget, {Application
- Example}, {Dock Widgets Example}, {MDI Example}, {SDI Example},
- {Menus Example}
-*/
-
-/*!
- \fn void QMainWindow::iconSizeChanged(const QSize &iconSize)
-
- This signal is emitted when the size of the icons used in the
- window is changed. The new icon size is passed in \a iconSize.
-
- You can connect this signal to other components to help maintain
- a consistent appearance for your application.
-
- \sa setIconSize()
-*/
-
-/*!
- \fn void QMainWindow::toolButtonStyleChanged(Qt::ToolButtonStyle toolButtonStyle)
-
- This signal is emitted when the style used for tool buttons in the
- window is changed. The new style is passed in \a toolButtonStyle.
-
- You can connect this signal to other components to help maintain
- a consistent appearance for your application.
-
- \sa setToolButtonStyle()
-*/
-
-/*!
- Constructs a QMainWindow with the given \a parent and the specified
- widget \a flags.
-
- QMainWindow sets the Qt::Window flag itself, and will hence
- always be created as a top-level widget.
- */
-QMainWindow::QMainWindow(QWidget *parent, Qt::WindowFlags flags)
- : QWidget(*(new QMainWindowPrivate()), parent, flags | Qt::Window)
-{
- d_func()->init();
-}
-
-#ifdef QT3_SUPPORT
-/*!
- \obsolete
- Constructs a QMainWindow with the given \a parent, \a name, and
- with the specified widget \a flags.
- */
-QMainWindow::QMainWindow(QWidget *parent, const char *name, Qt::WindowFlags flags)
- : QWidget(*(new QMainWindowPrivate()), parent, flags | Qt::WType_TopLevel)
-{
- setObjectName(QString::fromAscii(name));
- d_func()->init();
-}
-#endif
-
-/*!
- Destroys the main window.
- */
-QMainWindow::~QMainWindow()
-{ }
-
-/*! \property QMainWindow::iconSize
- \brief size of toolbar icons in this mainwindow.
-
- The default is the default tool bar icon size of the GUI style.
- Note that the icons used must be at least of this size as the
- icons are only scaled down.
-*/
-
-/*!
- \property QMainWindow::dockOptions
- \brief the docking behavior of QMainWindow
- \since 4.3
-
- The default value is AnimatedDocks | AllowTabbedDocks.
-*/
-
-/*!
- \enum QMainWindow::DockOption
- \since 4.3
-
- This enum contains flags that specify the docking behavior of QMainWindow.
-
- \value AnimatedDocks Identical to the \l animated property.
-
- \value AllowNestedDocks Identical to the \l dockNestingEnabled property.
-
- \value AllowTabbedDocks The user can drop one dock widget "on top" of
- another. The two widgets are stacked and a tab
- bar appears for selecting which one is visible.
-
- \value ForceTabbedDocks Each dock area contains a single stack of tabbed
- dock widgets. In other words, dock widgets cannot
- be placed next to each other in a dock area. If
- this option is set, AllowNestedDocks has no effect.
-
- \value VerticalTabs The two vertical dock areas on the sides of the
- main window show their tabs vertically. If this
- option is not set, all dock areas show their tabs
- at the bottom. Implies AllowTabbedDocks. See also
- \l setTabPosition().
-
- These options only control how dock widgets may be dropped in a QMainWindow.
- They do not re-arrange the dock widgets to conform with the specified
- options. For this reason they should be set before any dock widgets
- are added to the main window. Exceptions to this are the AnimatedDocks and
- VerticalTabs options, which may be set at any time.
-*/
-
-void QMainWindow::setDockOptions(DockOptions opt)
-{
- Q_D(QMainWindow);
- d->layout->setDockOptions(opt);
-}
-
-QMainWindow::DockOptions QMainWindow::dockOptions() const
-{
- Q_D(const QMainWindow);
- return d->layout->dockOptions;
-}
-
-QSize QMainWindow::iconSize() const
-{ return d_func()->iconSize; }
-
-void QMainWindow::setIconSize(const QSize &iconSize)
-{
- Q_D(QMainWindow);
- QSize sz = iconSize;
- if (!sz.isValid()) {
- const int metric = style()->pixelMetric(QStyle::PM_ToolBarIconSize, 0, this);
- sz = QSize(metric, metric);
- }
- if (d->iconSize != sz) {
- d->iconSize = sz;
- emit iconSizeChanged(d->iconSize);
- }
- d->explicitIconSize = iconSize.isValid();
-}
-
-/*! \property QMainWindow::toolButtonStyle
- \brief style of toolbar buttons in this mainwindow.
-
- The default is Qt::ToolButtonIconOnly.
-*/
-
-Qt::ToolButtonStyle QMainWindow::toolButtonStyle() const
-{ return d_func()->toolButtonStyle; }
-
-void QMainWindow::setToolButtonStyle(Qt::ToolButtonStyle toolButtonStyle)
-{
- Q_D(QMainWindow);
- if (d->toolButtonStyle == toolButtonStyle)
- return;
- d->toolButtonStyle = toolButtonStyle;
- emit toolButtonStyleChanged(d->toolButtonStyle);
-}
-
-#ifndef QT_NO_MENUBAR
-/*!
- Returns the menu bar for the main window. This function creates
- and returns an empty menu bar if the menu bar does not exist.
-
- If you want all windows in a Mac application to share one menu
- bar, don't use this function to create it, because the menu bar
- created here will have this QMainWindow as its parent. Instead,
- you must create a menu bar that does not have a parent, which you
- can then share among all the Mac windows. Create a parent-less
- menu bar this way:
-
- \snippet doc/src/snippets/code/src_gui_widgets_qmenubar.cpp 1
-
- \sa setMenuBar()
-*/
-QMenuBar *QMainWindow::menuBar() const
-{
- QMenuBar *menuBar = qobject_cast<QMenuBar *>(layout()->menuBar());
- if (!menuBar) {
- QMainWindow *self = const_cast<QMainWindow *>(this);
- menuBar = new QMenuBar(self);
- self->setMenuBar(menuBar);
- }
- return menuBar;
-}
-
-/*!
- Sets the menu bar for the main window to \a menuBar.
-
- Note: QMainWindow takes ownership of the \a menuBar pointer and
- deletes it at the appropriate time.
-
- \sa menuBar()
-*/
-void QMainWindow::setMenuBar(QMenuBar *menuBar)
-{
- QLayout *topLayout = layout();
-
- if (topLayout->menuBar() && topLayout->menuBar() != menuBar) {
- // Reparent corner widgets before we delete the old menu bar.
- QMenuBar *oldMenuBar = qobject_cast<QMenuBar *>(topLayout->menuBar());
- if (menuBar) {
- // TopLeftCorner widget.
- QWidget *cornerWidget = oldMenuBar->cornerWidget(Qt::TopLeftCorner);
- if (cornerWidget)
- menuBar->setCornerWidget(cornerWidget, Qt::TopLeftCorner);
- // TopRightCorner widget.
- cornerWidget = oldMenuBar->cornerWidget(Qt::TopRightCorner);
- if (cornerWidget)
- menuBar->setCornerWidget(cornerWidget, Qt::TopRightCorner);
- }
- oldMenuBar->hide();
- oldMenuBar->deleteLater();
- }
- topLayout->setMenuBar(menuBar);
-}
-
-/*!
- \since 4.2
-
- Returns the menu bar for the main window. This function returns
- null if a menu bar hasn't been constructed yet.
-*/
-QWidget *QMainWindow::menuWidget() const
-{
- QWidget *menuBar = d_func()->layout->menuBar();
- return menuBar;
-}
-
-/*!
- \since 4.2
-
- Sets the menu bar for the main window to \a menuBar.
-
- QMainWindow takes ownership of the \a menuBar pointer and
- deletes it at the appropriate time.
-*/
-void QMainWindow::setMenuWidget(QWidget *menuBar)
-{
- Q_D(QMainWindow);
- if (d->layout->menuBar() && d->layout->menuBar() != menuBar) {
- d->layout->menuBar()->hide();
- d->layout->menuBar()->deleteLater();
- }
- d->layout->setMenuBar(menuBar);
-}
-#endif // QT_NO_MENUBAR
-
-#ifndef QT_NO_STATUSBAR
-/*!
- Returns the status bar for the main window. This function creates
- and returns an empty status bar if the status bar does not exist.
-
- \sa setStatusBar()
-*/
-QStatusBar *QMainWindow::statusBar() const
-{
- QStatusBar *statusbar = d_func()->layout->statusBar();
- if (!statusbar) {
- QMainWindow *self = const_cast<QMainWindow *>(this);
- statusbar = new QStatusBar(self);
- statusbar->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed);
- self->setStatusBar(statusbar);
- }
- return statusbar;
-}
-
-/*!
- Sets the status bar for the main window to \a statusbar.
-
- Setting the status bar to 0 will remove it from the main window.
- Note that QMainWindow takes ownership of the \a statusbar pointer
- and deletes it at the appropriate time.
-
- \sa statusBar()
-*/
-void QMainWindow::setStatusBar(QStatusBar *statusbar)
-{
- Q_D(QMainWindow);
- if (d->layout->statusBar() && d->layout->statusBar() != statusbar) {
- d->layout->statusBar()->hide();
- d->layout->statusBar()->deleteLater();
- }
- d->layout->setStatusBar(statusbar);
-}
-#endif // QT_NO_STATUSBAR
-
-/*!
- Returns the central widget for the main window. This function
- returns zero if the central widget has not been set.
-
- \sa setCentralWidget()
-*/
-QWidget *QMainWindow::centralWidget() const
-{ return d_func()->layout->centralWidget(); }
-
-/*!
- Sets the given \a widget to be the main window's central widget.
-
- Note: QMainWindow takes ownership of the \a widget pointer and
- deletes it at the appropriate time.
-
- \sa centralWidget()
-*/
-void QMainWindow::setCentralWidget(QWidget *widget)
-{
- Q_D(QMainWindow);
- if (d->layout->centralWidget() && d->layout->centralWidget() != widget) {
- d->layout->centralWidget()->hide();
- d->layout->centralWidget()->deleteLater();
- }
- d->layout->setCentralWidget(widget);
-}
-
-#ifndef QT_NO_DOCKWIDGET
-/*!
- Sets the given dock widget \a area to occupy the specified \a
- corner.
-
- \sa corner()
-*/
-void QMainWindow::setCorner(Qt::Corner corner, Qt::DockWidgetArea area)
-{
- bool valid = false;
- switch (corner) {
- case Qt::TopLeftCorner:
- valid = (area == Qt::TopDockWidgetArea || area == Qt::LeftDockWidgetArea);
- break;
- case Qt::TopRightCorner:
- valid = (area == Qt::TopDockWidgetArea || area == Qt::RightDockWidgetArea);
- break;
- case Qt::BottomLeftCorner:
- valid = (area == Qt::BottomDockWidgetArea || area == Qt::LeftDockWidgetArea);
- break;
- case Qt::BottomRightCorner:
- valid = (area == Qt::BottomDockWidgetArea || area == Qt::RightDockWidgetArea);
- break;
- }
- if (!valid)
- qWarning("QMainWindow::setCorner(): 'area' is not valid for 'corner'");
- else
- d_func()->layout->setCorner(corner, area);
-}
-
-/*!
- Returns the dock widget area that occupies the specified \a
- corner.
-
- \sa setCorner()
-*/
-Qt::DockWidgetArea QMainWindow::corner(Qt::Corner corner) const
-{ return d_func()->layout->corner(corner); }
-#endif
-
-#ifndef QT_NO_TOOLBAR
-
-static bool checkToolBarArea(Qt::ToolBarArea area, const char *where)
-{
- switch (area) {
- case Qt::LeftToolBarArea:
- case Qt::RightToolBarArea:
- case Qt::TopToolBarArea:
- case Qt::BottomToolBarArea:
- return true;
- default:
- break;
- }
- qWarning("%s: invalid 'area' argument", where);
- return false;
-}
-
-/*!
- Adds a toolbar break to the given \a area after all the other
- objects that are present.
-*/
-void QMainWindow::addToolBarBreak(Qt::ToolBarArea area)
-{
- if (!checkToolBarArea(area, "QMainWindow::addToolBarBreak"))
- return;
- d_func()->layout->addToolBarBreak(area);
-}
-
-/*!
- Inserts a toolbar break before the toolbar specified by \a before.
-*/
-void QMainWindow::insertToolBarBreak(QToolBar *before)
-{ d_func()->layout->insertToolBarBreak(before); }
-
-/*!
- Removes a toolbar break previously inserted before the toolbar specified by \a before.
-*/
-
-void QMainWindow::removeToolBarBreak(QToolBar *before)
-{
- Q_D(QMainWindow);
- d->layout->removeToolBarBreak(before);
-}
-
-/*!
- Adds the \a toolbar into the specified \a area in this main
- window. The \a toolbar is placed at the end of the current tool
- bar block (i.e. line). If the main window already manages \a toolbar
- then it will only move the toolbar to \a area.
-
- \sa insertToolBar() addToolBarBreak() insertToolBarBreak()
-*/
-void QMainWindow::addToolBar(Qt::ToolBarArea area, QToolBar *toolbar)
-{
- if (!checkToolBarArea(area, "QMainWindow::addToolBar"))
- return;
-
- Q_D(QMainWindow);
-
- disconnect(this, SIGNAL(iconSizeChanged(QSize)),
- toolbar, SLOT(_q_updateIconSize(QSize)));
- disconnect(this, SIGNAL(toolButtonStyleChanged(Qt::ToolButtonStyle)),
- toolbar, SLOT(_q_updateToolButtonStyle(Qt::ToolButtonStyle)));
-
- if(toolbar->d_func()->state && toolbar->d_func()->state->dragging) {
- //removing a toolbar which is dragging will cause crash
-#ifndef QT_NO_DOCKWIDGET
- bool animated = isAnimated();
- setAnimated(false);
-#endif
- toolbar->d_func()->endDrag();
-#ifndef QT_NO_DOCKWIDGET
- setAnimated(animated);
-#endif
- }
-
- if (!d->layout->usesHIToolBar(toolbar)) {
- d->layout->removeWidget(toolbar);
- } else {
- d->layout->removeToolBar(toolbar);
- }
-
- toolbar->d_func()->_q_updateIconSize(d->iconSize);
- toolbar->d_func()->_q_updateToolButtonStyle(d->toolButtonStyle);
- connect(this, SIGNAL(iconSizeChanged(QSize)),
- toolbar, SLOT(_q_updateIconSize(QSize)));
- connect(this, SIGNAL(toolButtonStyleChanged(Qt::ToolButtonStyle)),
- toolbar, SLOT(_q_updateToolButtonStyle(Qt::ToolButtonStyle)));
-
- d->layout->addToolBar(area, toolbar);
-}
-
-/*! \overload
- Equivalent of calling addToolBar(Qt::TopToolBarArea, \a toolbar)
-*/
-void QMainWindow::addToolBar(QToolBar *toolbar)
-{ addToolBar(Qt::TopToolBarArea, toolbar); }
-
-/*!
- \overload
-
- Creates a QToolBar object, setting its window title to \a title,
- and inserts it into the top toolbar area.
-
- \sa setWindowTitle()
-*/
-QToolBar *QMainWindow::addToolBar(const QString &title)
-{
- QToolBar *toolBar = new QToolBar(this);
- toolBar->setWindowTitle(title);
- addToolBar(toolBar);
- return toolBar;
-}
-
-/*!
- Inserts the \a toolbar into the area occupied by the \a before toolbar
- so that it appears before it. For example, in normal left-to-right
- layout operation, this means that \a toolbar will appear to the left
- of the toolbar specified by \a before in a horizontal toolbar area.
-
- \sa insertToolBarBreak() addToolBar() addToolBarBreak()
-*/
-void QMainWindow::insertToolBar(QToolBar *before, QToolBar *toolbar)
-{
- Q_D(QMainWindow);
-
- d->layout->removeToolBar(toolbar);
-
- toolbar->d_func()->_q_updateIconSize(d->iconSize);
- toolbar->d_func()->_q_updateToolButtonStyle(d->toolButtonStyle);
- connect(this, SIGNAL(iconSizeChanged(QSize)),
- toolbar, SLOT(_q_updateIconSize(QSize)));
- connect(this, SIGNAL(toolButtonStyleChanged(Qt::ToolButtonStyle)),
- toolbar, SLOT(_q_updateToolButtonStyle(Qt::ToolButtonStyle)));
-
- d->layout->insertToolBar(before, toolbar);
-}
-
-/*!
- Removes the \a toolbar from the main window layout and hides
- it. Note that the \a toolbar is \e not deleted.
-*/
-void QMainWindow::removeToolBar(QToolBar *toolbar)
-{
- if (toolbar) {
- d_func()->layout->removeToolBar(toolbar);
- toolbar->hide();
- }
-}
-
-/*!
- Returns the Qt::ToolBarArea for \a toolbar. If \a toolbar has not
- been added to the main window, this function returns \c
- Qt::NoToolBarArea.
-
- \sa addToolBar() addToolBarBreak() Qt::ToolBarArea
-*/
-Qt::ToolBarArea QMainWindow::toolBarArea(QToolBar *toolbar) const
-{ return d_func()->layout->toolBarArea(toolbar); }
-
-/*!
-
- Returns whether there is a toolbar
- break before the \a toolbar.
-
- \sa addToolBarBreak(), insertToolBarBreak()
-*/
-bool QMainWindow::toolBarBreak(QToolBar *toolbar) const
-{
- return d_func()->layout->toolBarBreak(toolbar);
-}
-
-#endif // QT_NO_TOOLBAR
-
-#ifndef QT_NO_DOCKWIDGET
-
-/*! \property QMainWindow::animated
- \brief whether manipulating dock widgets and tool bars is animated
- \since 4.2
-
- When a dock widget or tool bar is dragged over the
- main window, the main window adjusts its contents
- to indicate where the dock widget or tool bar will
- be docked if it is dropped. Setting this property
- causes QMainWindow to move its contents in a smooth
- animation. Clearing this property causes the contents
- to snap into their new positions.
-
- By default, this property is set. It may be cleared if
- the main window contains widgets which are slow at resizing
- or repainting themselves.
-
- Setting this property is identical to setting the AnimatedDocks
- option using setDockOptions().
-*/
-
-bool QMainWindow::isAnimated() const
-{
- Q_D(const QMainWindow);
- return d->layout->dockOptions & AnimatedDocks;
-}
-
-void QMainWindow::setAnimated(bool enabled)
-{
- Q_D(QMainWindow);
-
- DockOptions opts = d->layout->dockOptions;
- if (enabled)
- opts |= AnimatedDocks;
- else
- opts &= ~AnimatedDocks;
-
- d->layout->setDockOptions(opts);
-}
-
-/*! \property QMainWindow::dockNestingEnabled
- \brief whether docks can be nested
- \since 4.2
-
- If this property is false, dock areas can only contain a single row
- (horizontal or vertical) of dock widgets. If this property is true,
- the area occupied by a dock widget can be split in either direction to contain
- more dock widgets.
-
- Dock nesting is only necessary in applications that contain a lot of
- dock widgets. It gives the user greater freedom in organizing their
- main window. However, dock nesting leads to more complex
- (and less intuitive) behavior when a dock widget is dragged over the
- main window, since there are more ways in which a dropped dock widget
- may be placed in the dock area.
-
- Setting this property is identical to setting the AllowNestedDocks option
- using setDockOptions().
-*/
-
-bool QMainWindow::isDockNestingEnabled() const
-{
- Q_D(const QMainWindow);
- return d->layout->dockOptions & AllowNestedDocks;
-}
-
-void QMainWindow::setDockNestingEnabled(bool enabled)
-{
- Q_D(QMainWindow);
-
- DockOptions opts = d->layout->dockOptions;
- if (enabled)
- opts |= AllowNestedDocks;
- else
- opts &= ~AllowNestedDocks;
-
- d->layout->setDockOptions(opts);
-}
-
-#if 0
-/*! \property QMainWindow::verticalTabsEnabled
- \brief whether left and right dock areas use vertical tabs
- \since 4.2
-
- If this property is set to false, dock areas containing tabbed dock widgets
- display horizontal tabs, simmilar to Visual Studio.
-
- If this property is set to true, then the right and left dock areas display vertical
- tabs, simmilar to KDevelop.
-
- This property should be set before any dock widgets are added to the main window.
-*/
-
-bool QMainWindow::verticalTabsEnabled() const
-{
- return d_func()->layout->verticalTabsEnabled();
-}
-
-void QMainWindow::setVerticalTabsEnabled(bool enabled)
-{
- d_func()->layout->setVerticalTabsEnabled(enabled);
-}
-#endif
-
-static bool checkDockWidgetArea(Qt::DockWidgetArea area, const char *where)
-{
- switch (area) {
- case Qt::LeftDockWidgetArea:
- case Qt::RightDockWidgetArea:
- case Qt::TopDockWidgetArea:
- case Qt::BottomDockWidgetArea:
- return true;
- default:
- break;
- }
- qWarning("%s: invalid 'area' argument", where);
- return false;
-}
-
-#ifndef QT_NO_TABBAR
-/*!
- \property QMainWindow::documentMode
- \brief whether the tab bar for tabbed dockwidgets is set to document mode.
- \since 4.5
-
- The default is false.
-
- \sa QTabBar::documentMode
-*/
-bool QMainWindow::documentMode() const
-{
- return d_func()->layout->documentMode();
-}
-
-void QMainWindow::setDocumentMode(bool enabled)
-{
- d_func()->layout->setDocumentMode(enabled);
-}
-#endif // QT_NO_TABBAR
-
-#ifndef QT_NO_TABWIDGET
-/*!
- \property QMainWindow::tabShape
- \brief the tab shape used for tabbed dock widgets.
- \since 4.5
-
- The default is \l QTabWidget::Rounded.
-
- \sa setTabPosition()
-*/
-QTabWidget::TabShape QMainWindow::tabShape() const
-{
- return d_func()->layout->tabShape();
-}
-
-void QMainWindow::setTabShape(QTabWidget::TabShape tabShape)
-{
- d_func()->layout->setTabShape(tabShape);
-}
-
-/*!
- \since 4.5
-
- Returns the tab position for \a area.
-
- \note The \l VerticalTabs dock option overrides the tab positions returned
- by this function.
-
- \sa setTabPosition(), tabShape()
-*/
-QTabWidget::TabPosition QMainWindow::tabPosition(Qt::DockWidgetArea area) const
-{
- if (!checkDockWidgetArea(area, "QMainWindow::tabPosition"))
- return QTabWidget::South;
- return d_func()->layout->tabPosition(area);
-}
-
-/*!
- \since 4.5
-
- Sets the tab position for the given dock widget \a areas to the specified
- \a tabPosition. By default, all dock areas show their tabs at the bottom.
-
- \note The \l VerticalTabs dock option overrides the tab positions set by
- this method.
-
- \sa tabPosition(), setTabShape()
-*/
-void QMainWindow::setTabPosition(Qt::DockWidgetAreas areas, QTabWidget::TabPosition tabPosition)
-{
- d_func()->layout->setTabPosition(areas, tabPosition);
-}
-#endif // QT_NO_TABWIDGET
-
-/*!
- Adds the given \a dockwidget to the specified \a area.
-*/
-void QMainWindow::addDockWidget(Qt::DockWidgetArea area, QDockWidget *dockwidget)
-{
- if (!checkDockWidgetArea(area, "QMainWindow::addDockWidget"))
- return;
-
- Qt::Orientation orientation = Qt::Vertical;
- switch (area) {
- case Qt::TopDockWidgetArea:
- case Qt::BottomDockWidgetArea:
- orientation = Qt::Horizontal;
- break;
- default:
- break;
- }
- d_func()->layout->removeWidget(dockwidget); // in case it was already in here
- addDockWidget(area, dockwidget, orientation);
-
-#ifdef Q_WS_MAC //drawer support
- QMacCocoaAutoReleasePool pool;
- extern bool qt_mac_is_macdrawer(const QWidget *); //qwidget_mac.cpp
- if (qt_mac_is_macdrawer(dockwidget)) {
- extern bool qt_mac_set_drawer_preferred_edge(QWidget *, Qt::DockWidgetArea); //qwidget_mac.cpp
- window()->createWinId();
- dockwidget->window()->createWinId();
- qt_mac_set_drawer_preferred_edge(dockwidget, area);
- if (dockwidget->isVisible()) {
- dockwidget->hide();
- dockwidget->show();
- }
- }
-#endif
-}
-
-/*!
- Restores the state of \a dockwidget if it is created after the call
- to restoreState(). Returns true if the state was restored; otherwise
- returns false.
-
- \sa restoreState(), saveState()
-*/
-
-bool QMainWindow::restoreDockWidget(QDockWidget *dockwidget)
-{
- return d_func()->layout->restoreDockWidget(dockwidget);
-}
-
-/*!
- Adds \a dockwidget into the given \a area in the direction
- specified by the \a orientation.
-*/
-void QMainWindow::addDockWidget(Qt::DockWidgetArea area, QDockWidget *dockwidget,
- Qt::Orientation orientation)
-{
- if (!checkDockWidgetArea(area, "QMainWindow::addDockWidget"))
- return;
-
- // add a window to an area, placing done relative to the previous
- d_func()->layout->addDockWidget(area, dockwidget, orientation);
-}
-
-/*!
- \fn void QMainWindow::splitDockWidget(QDockWidget *first, QDockWidget *second, Qt::Orientation orientation)
-
- Splits the space covered by the \a first dock widget into two parts,
- moves the \a first dock widget into the first part, and moves the
- \a second dock widget into the second part.
-
- The \a orientation specifies how the space is divided: A Qt::Horizontal
- split places the second dock widget to the right of the first; a
- Qt::Vertical split places the second dock widget below the first.
-
- \e Note: if \a first is currently in a tabbed docked area, \a second will
- be added as a new tab, not as a neighbor of \a first. This is because a
- single tab can contain only one dock widget.
-
- \e Note: The Qt::LayoutDirection influences the order of the dock widgets
- in the two parts of the divided area. When right-to-left layout direction
- is enabled, the placing of the dock widgets will be reversed.
-
- \sa tabifyDockWidget(), addDockWidget(), removeDockWidget()
-*/
-void QMainWindow::splitDockWidget(QDockWidget *after, QDockWidget *dockwidget,
- Qt::Orientation orientation)
-{
- d_func()->layout->splitDockWidget(after, dockwidget, orientation);
-}
-
-/*!
- \fn void QMainWindow::tabifyDockWidget(QDockWidget *first, QDockWidget *second)
-
- Moves \a second dock widget on top of \a first dock widget, creating a tabbed
- docked area in the main window.
-
- \sa tabifiedDockWidgets()
-*/
-void QMainWindow::tabifyDockWidget(QDockWidget *first, QDockWidget *second)
-{
- d_func()->layout->tabifyDockWidget(first, second);
-}
-
-
-/*!
- \fn QList<QDockWidget*> QMainWindow::tabifiedDockWidgets(QDockWidget *dockwidget) const
-
- Returns the dock widgets that are tabified together with \a dockwidget.
-
- \since 4.5
- \sa tabifyDockWidget()
-*/
-
-QList<QDockWidget*> QMainWindow::tabifiedDockWidgets(QDockWidget *dockwidget) const
-{
- QList<QDockWidget*> ret;
-#if defined(QT_NO_TABBAR)
- Q_UNUSED(dockwidget);
-#else
- const QDockAreaLayoutInfo *info = d_func()->layout->layoutState.dockAreaLayout.info(dockwidget);
- if (info && info->tabbed && info->tabBar) {
- for(int i = 0; i < info->item_list.count(); ++i) {
- const QDockAreaLayoutItem &item = info->item_list.at(i);
- if (item.widgetItem) {
- if (QDockWidget *dock = qobject_cast<QDockWidget*>(item.widgetItem->widget())) {
- if (dock != dockwidget) {
- ret += dock;
- }
- }
- }
- }
- }
-#endif
- return ret;
-}
-
-
-/*!
- Removes the \a dockwidget from the main window layout and hides
- it. Note that the \a dockwidget is \e not deleted.
-*/
-void QMainWindow::removeDockWidget(QDockWidget *dockwidget)
-{
- if (dockwidget) {
- d_func()->layout->removeWidget(dockwidget);
- dockwidget->hide();
- }
-}
-
-/*!
- Returns the Qt::DockWidgetArea for \a dockwidget. If \a dockwidget
- has not been added to the main window, this function returns \c
- Qt::NoDockWidgetArea.
-
- \sa addDockWidget() splitDockWidget() Qt::DockWidgetArea
-*/
-Qt::DockWidgetArea QMainWindow::dockWidgetArea(QDockWidget *dockwidget) const
-{ return d_func()->layout->dockWidgetArea(dockwidget); }
-
-#endif // QT_NO_DOCKWIDGET
-
-/*!
- Saves the current state of this mainwindow's toolbars and
- dockwidgets. The \a version number is stored as part of the data.
-
- The \link QObject::objectName objectName\endlink property is used
- to identify each QToolBar and QDockWidget. You should make sure
- that this property is unique for each QToolBar and QDockWidget you
- add to the QMainWindow
-
- To restore the saved state, pass the return value and \a version
- number to restoreState().
-
- To save the geometry when the window closes, you can
- implement a close event like this:
-
- \snippet doc/src/snippets/code/src_gui_widgets_qmainwindow.cpp 0
-
- \sa restoreState(), QWidget::saveGeometry(), QWidget::restoreGeometry()
-*/
-QByteArray QMainWindow::saveState(int version) const
-{
- QByteArray data;
- QDataStream stream(&data, QIODevice::WriteOnly);
- stream << QMainWindowLayout::VersionMarker;
- stream << version;
- d_func()->layout->saveState(stream);
- return data;
-}
-
-/*!
- Restores the \a state of this mainwindow's toolbars and
- dockwidgets. The \a version number is compared with that stored
- in \a state. If they do not match, the mainwindow's state is left
- unchanged, and this function returns \c false; otherwise, the state
- is restored, and this function returns \c true.
-
- To restore geometry saved using QSettings, you can use code like
- this:
-
- \snippet doc/src/snippets/code/src_gui_widgets_qmainwindow.cpp 1
-
- \sa saveState(), QWidget::saveGeometry(),
- QWidget::restoreGeometry(), restoreDockWidget()
-*/
-bool QMainWindow::restoreState(const QByteArray &state, int version)
-{
- if (state.isEmpty())
- return false;
- QByteArray sd = state;
- QDataStream stream(&sd, QIODevice::ReadOnly);
- int marker, v;
- stream >> marker;
- stream >> v;
- if (stream.status() != QDataStream::Ok || marker != QMainWindowLayout::VersionMarker || v != version)
- return false;
- bool restored = d_func()->layout->restoreState(stream);
- return restored;
-}
-
-#if !defined(QT_NO_DOCKWIDGET) && !defined(QT_NO_CURSOR)
-QCursor QMainWindowPrivate::separatorCursor(const QList<int> &path) const
-{
- QDockAreaLayoutInfo *info = layout->layoutState.dockAreaLayout.info(path);
- Q_ASSERT(info != 0);
- if (path.size() == 1) { // is this the "top-level" separator which separates a dock area
- // from the central widget?
- switch (path.first()) {
- case QInternal::LeftDock:
- case QInternal::RightDock:
- return Qt::SplitHCursor;
- case QInternal::TopDock:
- case QInternal::BottomDock:
- return Qt::SplitVCursor;
- default:
- break;
- }
- }
-
- // no, it's a splitter inside a dock area, separating two dock widgets
-
- return info->o == Qt::Horizontal
- ? Qt::SplitHCursor : Qt::SplitVCursor;
-}
-
-void QMainWindowPrivate::adjustCursor(const QPoint &pos)
-{
- Q_Q(QMainWindow);
-
- hoverPos = pos;
-
- if (pos == QPoint(0, 0)) {
- if (!hoverSeparator.isEmpty())
- q->update(layout->layoutState.dockAreaLayout.separatorRect(hoverSeparator));
- hoverSeparator.clear();
-
- if (cursorAdjusted) {
- cursorAdjusted = false;
- if (hasOldCursor)
- q->setCursor(oldCursor);
- else
- q->unsetCursor();
- }
- } else {
- QList<int> pathToSeparator
- = layout->layoutState.dockAreaLayout.findSeparator(pos);
-
- if (pathToSeparator != hoverSeparator) {
- if (!hoverSeparator.isEmpty())
- q->update(layout->layoutState.dockAreaLayout.separatorRect(hoverSeparator));
-
- hoverSeparator = pathToSeparator;
-
- if (hoverSeparator.isEmpty()) {
- if (cursorAdjusted) {
- cursorAdjusted = false;
- if (hasOldCursor)
- q->setCursor(oldCursor);
- else
- q->unsetCursor();
- }
- } else {
- q->update(layout->layoutState.dockAreaLayout.separatorRect(hoverSeparator));
- if (!cursorAdjusted) {
- oldCursor = q->cursor();
- hasOldCursor = q->testAttribute(Qt::WA_SetCursor);
- }
- QCursor cursor = separatorCursor(hoverSeparator);
- cursorAdjusted = false; //to not reset the oldCursor in event(CursorChange)
- q->setCursor(cursor);
- cursorAdjusted = true;
- }
- }
- }
-}
-#endif
-
-/*! \reimp */
-bool QMainWindow::event(QEvent *event)
-{
- Q_D(QMainWindow);
- switch (event->type()) {
-
-#ifndef QT_NO_DOCKWIDGET
- case QEvent::Paint: {
- QPainter p(this);
- QRegion r = static_cast<QPaintEvent*>(event)->region();
- d->layout->layoutState.dockAreaLayout.paintSeparators(&p, this, r, d->hoverPos);
- break;
- }
-
-#ifndef QT_NO_CURSOR
- case QEvent::HoverMove: {
- d->adjustCursor(static_cast<QHoverEvent*>(event)->pos());
- break;
- }
-
- // We don't want QWidget to call update() on the entire QMainWindow
- // on HoverEnter and HoverLeave, hence accept the event (return true).
- case QEvent::HoverEnter:
- return true;
- case QEvent::HoverLeave:
- d->adjustCursor(QPoint(0, 0));
- return true;
- case QEvent::ShortcutOverride: // when a menu pops up
- d->adjustCursor(QPoint(0, 0));
- break;
-#endif // QT_NO_CURSOR
-
- case QEvent::MouseButtonPress: {
- QMouseEvent *e = static_cast<QMouseEvent*>(event);
- if (e->button() == Qt::LeftButton && d->layout->startSeparatorMove(e->pos())) {
- // The click was on a separator, eat this event
- e->accept();
- return true;
- }
- break;
- }
-
- case QEvent::MouseMove: {
- QMouseEvent *e = static_cast<QMouseEvent*>(event);
-
-#ifndef QT_NO_CURSOR
- d->adjustCursor(e->pos());
-#endif
- if (e->buttons() & Qt::LeftButton) {
- if (d->layout->separatorMove(e->pos())) {
- // We're moving a separator, eat this event
- e->accept();
- return true;
- }
- }
-
- break;
- }
-
- case QEvent::MouseButtonRelease: {
- QMouseEvent *e = static_cast<QMouseEvent*>(event);
- if (d->layout->endSeparatorMove(e->pos())) {
- // We've released a separator, eat this event
- e->accept();
- return true;
- }
- break;
- }
-
-#endif
-
-#ifndef QT_NO_TOOLBAR
- case QEvent::ToolBarChange: {
- d->layout->toggleToolBarsVisible();
- return true;
- }
-#endif
-
-#ifndef QT_NO_STATUSTIP
- case QEvent::StatusTip:
-#ifndef QT_NO_STATUSBAR
- if (QStatusBar *sb = d->layout->statusBar())
- sb->showMessage(static_cast<QStatusTipEvent*>(event)->tip());
- else
-#endif
- static_cast<QStatusTipEvent*>(event)->ignore();
- return true;
-#endif // QT_NO_STATUSTIP
-
- case QEvent::StyleChange:
-#ifndef QT_NO_DOCKWIDGET
- d->layout->layoutState.dockAreaLayout.styleChangedEvent();
-#endif
- if (!d->explicitIconSize)
- setIconSize(QSize());
- break;
-#ifdef Q_WS_MAC
- case QEvent::Show:
- if (unifiedTitleAndToolBarOnMac())
- d->layout->syncUnifiedToolbarVisibility();
- d->layout->blockVisiblityCheck = false;
- break;
- case QEvent::WindowStateChange:
- {
- if (isHidden()) {
- // We are coming out of a minimize, leave things as is.
- d->layout->blockVisiblityCheck = true;
- }
-# ifdef QT_MAC_USE_COCOA
- // We need to update the HIToolbar status when we go out of or into fullscreen.
- QWindowStateChangeEvent *wce = static_cast<QWindowStateChangeEvent *>(event);
- if ((windowState() & Qt::WindowFullScreen) || (wce->oldState() & Qt::WindowFullScreen)) {
- d->layout->updateHIToolBarStatus();
- }
-# endif // Cocoa
- }
- break;
-#endif // Q_WS_MAC
-#if !defined(QT_NO_DOCKWIDGET) && !defined(QT_NO_CURSOR)
- case QEvent::CursorChange:
- if (d->cursorAdjusted) {
- d->oldCursor = cursor();
- d->hasOldCursor = testAttribute(Qt::WA_SetCursor);
- }
- break;
-#endif
- default:
- break;
- }
-
- return QWidget::event(event);
-}
-
-#ifndef QT_NO_TOOLBAR
-
-/*!
- \property QMainWindow::unifiedTitleAndToolBarOnMac
- \brief whether the window uses the unified title and toolbar look on Mac OS X
- \since 4.3
-
- This property is false by default and only has any effect on Mac OS X 10.4 or higher.
-
- If set to true, then the top toolbar area is replaced with a Carbon HIToolbar
- or a Cocoa NSToolbar (depending on whether Qt was built with Carbon or Cocoa).
- All toolbars in the top toolbar area and any toolbars added afterwards are
- moved to that. This means a couple of things.
-
- \list
- \i QToolBars in this toolbar area are not movable and you cannot drag other
- toolbars to it
- \i Toolbar breaks are not respected or preserved
- \i Any custom widgets in the toolbar will not be shown if the toolbar
- becomes too small (only actions will be shown)
- \i Before Qt 4.5, if you called showFullScreen() on the main window, the QToolbar would
- disappear since it is considered to be part of the title bar. Qt 4.5 and up will now work around this by pulling
- the toolbars out and back into the regular toolbar and vice versa when you swap out.
- \endlist
-
- Setting this back to false will remove these restrictions.
-
- The Qt::WA_MacBrushedMetal attribute takes precedence over this property.
-*/
-void QMainWindow::setUnifiedTitleAndToolBarOnMac(bool set)
-{
-#ifdef Q_WS_MAC
- Q_D(QMainWindow);
- if (!isWindow() || d->useHIToolBar == set || QSysInfo::MacintoshVersion < QSysInfo::MV_10_3)
- return;
-
- d->useHIToolBar = set;
- createWinId(); // We need the hiview for down below.
-
-#ifdef QT_MAC_USE_COCOA
- // Activate the unified toolbar with the raster engine.
- if (windowSurface() && set) {
- d->layout->unifiedSurface = new QUnifiedToolbarSurface(this);
- }
-#endif // QT_MAC_USE_COCOA
-
- d->layout->updateHIToolBarStatus();
-
-#ifdef QT_MAC_USE_COCOA
- // Deactivate the unified toolbar with the raster engine.
- if (windowSurface() && !set) {
- if (d->layout->unifiedSurface) {
- delete d->layout->unifiedSurface;
- d->layout->unifiedSurface = 0;
- }
- }
-#endif // QT_MAC_USE_COCOA
-
- // Enabling the unified toolbar clears the opaque size grip setting, update it.
- d->macUpdateOpaqueSizeGrip();
-#else
- Q_UNUSED(set)
-#endif
-}
-
-bool QMainWindow::unifiedTitleAndToolBarOnMac() const
-{
-#ifdef Q_WS_MAC
- return d_func()->useHIToolBar && !testAttribute(Qt::WA_MacBrushedMetal) && !(windowFlags() & Qt::FramelessWindowHint);
-#endif
- return false;
-}
-
-#endif // QT_NO_TOOLBAR
-
-/*!
- \internal
-*/
-bool QMainWindow::isSeparator(const QPoint &pos) const
-{
-#ifndef QT_NO_DOCKWIDGET
- Q_D(const QMainWindow);
- return !d->layout->layoutState.dockAreaLayout.findSeparator(pos).isEmpty();
-#else
- Q_UNUSED(pos);
- return false;
-#endif
-}
-
-#ifndef QT_NO_CONTEXTMENU
-/*!
- \reimp
-*/
-void QMainWindow::contextMenuEvent(QContextMenuEvent *event)
-{
- event->ignore();
- // only show the context menu for direct QDockWidget and QToolBar
- // children and for the menu bar as well
- QWidget *child = childAt(event->pos());
- while (child && child != this) {
-#ifndef QT_NO_MENUBAR
- if (QMenuBar *mb = qobject_cast<QMenuBar *>(child)) {
- if (mb->parentWidget() != this)
- return;
- break;
- }
-#endif
-#ifndef QT_NO_DOCKWIDGET
- if (QDockWidget *dw = qobject_cast<QDockWidget *>(child)) {
- if (dw->parentWidget() != this)
- return;
- if (dw->widget()
- && dw->widget()->geometry().contains(child->mapFrom(this, event->pos()))) {
- // ignore the event if the mouse is over the QDockWidget contents
- return;
- }
- break;
- }
-#endif // QT_NO_DOCKWIDGET
-#ifndef QT_NO_TOOLBAR
- if (QToolBar *tb = qobject_cast<QToolBar *>(child)) {
- if (tb->parentWidget() != this)
- return;
- break;
- }
-#endif
- child = child->parentWidget();
- }
- if (child == this)
- return;
-
-#ifndef QT_NO_MENU
- QMenu *popup = createPopupMenu();
- if (popup) {
- if (!popup->isEmpty()) {
- popup->setAttribute(Qt::WA_DeleteOnClose);
- popup->popup(event->globalPos());
- event->accept();
- } else {
- delete popup;
- }
- }
-#endif
-}
-#endif // QT_NO_CONTEXTMENU
-
-#ifndef QT_NO_MENU
-/*!
- Returns a popup menu containing checkable entries for the toolbars and
- dock widgets present in the main window. If there are no toolbars and
- dock widgets present, this function returns a null pointer.
-
- By default, this function is called by the main window when the user
- activates a context menu, typically by right-clicking on a toolbar or a dock
- widget.
-
- If you want to create a custom popup menu, reimplement this function and
- return a newly-created popup menu. Ownership of the popup menu is transferred
- to the caller.
-
- \sa addDockWidget(), addToolBar(), menuBar()
-*/
-QMenu *QMainWindow::createPopupMenu()
-{
- Q_D(QMainWindow);
- QMenu *menu = 0;
-#ifndef QT_NO_DOCKWIDGET
- QList<QDockWidget *> dockwidgets = findChildren<QDockWidget *>();
- if (dockwidgets.size()) {
- menu = new QMenu(this);
- for (int i = 0; i < dockwidgets.size(); ++i) {
- QDockWidget *dockWidget = dockwidgets.at(i);
- if (dockWidget->parentWidget() == this
- && !d->layout->layoutState.dockAreaLayout.indexOf(dockWidget).isEmpty()) {
- menu->addAction(dockwidgets.at(i)->toggleViewAction());
- }
- }
- menu->addSeparator();
- }
-#endif // QT_NO_DOCKWIDGET
-#ifndef QT_NO_TOOLBAR
- QList<QToolBar *> toolbars = findChildren<QToolBar *>();
- if (toolbars.size()) {
- if (!menu)
- menu = new QMenu(this);
- for (int i = 0; i < toolbars.size(); ++i) {
- QToolBar *toolBar = toolbars.at(i);
- if (toolBar->parentWidget() == this
- && (!d->layout->layoutState.toolBarAreaLayout.indexOf(toolBar).isEmpty()
- || (unifiedTitleAndToolBarOnMac()
- && toolBarArea(toolBar) == Qt::TopToolBarArea))) {
- menu->addAction(toolbars.at(i)->toggleViewAction());
- }
- }
- }
-#endif
- Q_UNUSED(d);
- return menu;
-}
-#endif // QT_NO_MENU
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_MAINWINDOW
diff --git a/src/gui/widgets/qmainwindow.h b/src/gui/widgets/qmainwindow.h
deleted file mode 100644
index 11fb57e3f7..0000000000
--- a/src/gui/widgets/qmainwindow.h
+++ /dev/null
@@ -1,219 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDYNAMICMAINWINDOW_H
-#define QDYNAMICMAINWINDOW_H
-
-#include <QtGui/qwidget.h>
-#include <QtGui/qtabwidget.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_MAINWINDOW
-
-class QDockWidget;
-class QMainWindowPrivate;
-class QMenuBar;
-class QStatusBar;
-class QToolBar;
-class QMenu;
-
-class Q_GUI_EXPORT QMainWindow : public QWidget
-{
- Q_OBJECT
-
- Q_ENUMS(DockOption)
- Q_FLAGS(DockOptions)
- Q_PROPERTY(QSize iconSize READ iconSize WRITE setIconSize)
- Q_PROPERTY(Qt::ToolButtonStyle toolButtonStyle READ toolButtonStyle WRITE setToolButtonStyle)
-#ifndef QT_NO_DOCKWIDGET
- Q_PROPERTY(bool animated READ isAnimated WRITE setAnimated)
-#ifndef QT_NO_TABBAR
- Q_PROPERTY(bool documentMode READ documentMode WRITE setDocumentMode)
-#endif // QT_NO_TABBAR
-#ifndef QT_NO_TABWIDGET
- Q_PROPERTY(QTabWidget::TabShape tabShape READ tabShape WRITE setTabShape)
-#endif // QT_NO_TABWIDGET
- Q_PROPERTY(bool dockNestingEnabled READ isDockNestingEnabled WRITE setDockNestingEnabled)
-#endif // QT_NO_DOCKWIDGET
- Q_PROPERTY(DockOptions dockOptions READ dockOptions WRITE setDockOptions)
-#ifndef QT_NO_TOOLBAR
- Q_PROPERTY(bool unifiedTitleAndToolBarOnMac READ unifiedTitleAndToolBarOnMac WRITE setUnifiedTitleAndToolBarOnMac)
-#endif
-
-public:
- enum DockOption {
- AnimatedDocks = 0x01,
- AllowNestedDocks = 0x02,
- AllowTabbedDocks = 0x04,
- ForceTabbedDocks = 0x08, // implies AllowTabbedDocks, !AllowNestedDocks
- VerticalTabs = 0x10 // implies AllowTabbedDocks
- };
- Q_DECLARE_FLAGS(DockOptions, DockOption)
-
- explicit QMainWindow(QWidget *parent = 0, Qt::WindowFlags flags = 0);
- ~QMainWindow();
-
- QSize iconSize() const;
- void setIconSize(const QSize &iconSize);
-
- Qt::ToolButtonStyle toolButtonStyle() const;
- void setToolButtonStyle(Qt::ToolButtonStyle toolButtonStyle);
-
-#ifndef QT_NO_DOCKWIDGET
- bool isAnimated() const;
- bool isDockNestingEnabled() const;
-#endif
-
-#ifndef QT_NO_TABBAR
- bool documentMode() const;
- void setDocumentMode(bool enabled);
-#endif
-
-#ifndef QT_NO_TABWIDGET
- QTabWidget::TabShape tabShape() const;
- void setTabShape(QTabWidget::TabShape tabShape);
- QTabWidget::TabPosition tabPosition(Qt::DockWidgetArea area) const;
- void setTabPosition(Qt::DockWidgetAreas areas, QTabWidget::TabPosition tabPosition);
-#endif // QT_NO_TABWIDGET
-
- void setDockOptions(DockOptions options);
- DockOptions dockOptions() const;
-
- bool isSeparator(const QPoint &pos) const;
-
-#ifndef QT_NO_MENUBAR
- QMenuBar *menuBar() const;
- void setMenuBar(QMenuBar *menubar);
-
- QWidget *menuWidget() const;
- void setMenuWidget(QWidget *menubar);
-#endif
-
-#ifndef QT_NO_STATUSBAR
- QStatusBar *statusBar() const;
- void setStatusBar(QStatusBar *statusbar);
-#endif
-
- QWidget *centralWidget() const;
- void setCentralWidget(QWidget *widget);
-
-#ifndef QT_NO_DOCKWIDGET
- void setCorner(Qt::Corner corner, Qt::DockWidgetArea area);
- Qt::DockWidgetArea corner(Qt::Corner corner) const;
-#endif
-
-#ifndef QT_NO_TOOLBAR
- void addToolBarBreak(Qt::ToolBarArea area = Qt::TopToolBarArea);
- void insertToolBarBreak(QToolBar *before);
-
- void addToolBar(Qt::ToolBarArea area, QToolBar *toolbar);
- void addToolBar(QToolBar *toolbar);
- QToolBar *addToolBar(const QString &title);
- void insertToolBar(QToolBar *before, QToolBar *toolbar);
- void removeToolBar(QToolBar *toolbar);
- void removeToolBarBreak(QToolBar *before);
-
- void setUnifiedTitleAndToolBarOnMac(bool set);
- bool unifiedTitleAndToolBarOnMac() const;
-
- Qt::ToolBarArea toolBarArea(QToolBar *toolbar) const;
- bool toolBarBreak(QToolBar *toolbar) const;
-#endif
-#ifndef QT_NO_DOCKWIDGET
- void addDockWidget(Qt::DockWidgetArea area, QDockWidget *dockwidget);
- void addDockWidget(Qt::DockWidgetArea area, QDockWidget *dockwidget,
- Qt::Orientation orientation);
- void splitDockWidget(QDockWidget *after, QDockWidget *dockwidget,
- Qt::Orientation orientation);
- void tabifyDockWidget(QDockWidget *first, QDockWidget *second);
- QList<QDockWidget*> tabifiedDockWidgets(QDockWidget *dockwidget) const;
- void removeDockWidget(QDockWidget *dockwidget);
- bool restoreDockWidget(QDockWidget *dockwidget);
-
- Qt::DockWidgetArea dockWidgetArea(QDockWidget *dockwidget) const;
-#endif // QT_NO_DOCKWIDGET
-
- QByteArray saveState(int version = 0) const;
- bool restoreState(const QByteArray &state, int version = 0);
-
-#ifndef QT_NO_MENU
- virtual QMenu *createPopupMenu();
-#endif
-
-#ifdef QT3_SUPPORT
- QT3_SUPPORT_CONSTRUCTOR QMainWindow(QWidget *parent, const char *name, Qt::WindowFlags flags = 0);
-#endif
-
-#ifndef QT_NO_DOCKWIDGET
-public Q_SLOTS:
- void setAnimated(bool enabled);
- void setDockNestingEnabled(bool enabled);
-#endif
-
-Q_SIGNALS:
- void iconSizeChanged(const QSize &iconSize);
- void toolButtonStyleChanged(Qt::ToolButtonStyle toolButtonStyle);
-
-protected:
-#ifndef QT_NO_CONTEXTMENU
- void contextMenuEvent(QContextMenuEvent *event);
-#endif
- bool event(QEvent *event);
-
-private:
- Q_DECLARE_PRIVATE(QMainWindow)
- Q_DISABLE_COPY(QMainWindow)
-};
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QMainWindow::DockOptions)
-
-#endif // QT_NO_MAINWINDOW
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QDYNAMICMAINWINDOW_H
diff --git a/src/gui/widgets/qmainwindowlayout_p.h b/src/gui/widgets/qmainwindowlayout_p.h
deleted file mode 100644
index 439d87d6ce..0000000000
--- a/src/gui/widgets/qmainwindowlayout_p.h
+++ /dev/null
@@ -1,357 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDYNAMICMAINWINDOWLAYOUT_P_H
-#define QDYNAMICMAINWINDOWLAYOUT_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qmainwindow.h"
-
-#ifndef QT_NO_MAINWINDOW
-
-#include "QtGui/qlayout.h"
-#include "QtGui/qtabbar.h"
-#include "QtCore/qvector.h"
-#include "QtCore/qset.h"
-#include "QtCore/qbasictimer.h"
-#include "private/qlayoutengine_p.h"
-#include "private/qwidgetanimator_p.h"
-
-#include "qdockarealayout_p.h"
-#include "qtoolbararealayout_p.h"
-
-//#define Q_DEBUG_MAINWINDOW_LAYOUT
-
-#if defined(Q_DEBUG_MAINWINDOW_LAYOUT) && !defined(QT_NO_DOCKWIDGET)
-QT_BEGIN_NAMESPACE
-class QTextStream;
-Q_GUI_EXPORT void qt_dumpLayout(QTextStream &qout, QMainWindow *window);
-QT_END_NAMESPACE
-#endif // Q_DEBUG_MAINWINDOW_LAYOUT && !QT_NO_DOCKWIDGET
-
-#ifdef Q_WS_MAC
-// Forward defs to make avoid including Carbon.h (faster compile you know ;).
-struct OpaqueHIObjectRef;
-typedef struct OpaqueHIObjectRef* HIObjectRef;
-typedef HIObjectRef HIToolbarItemRef;
-typedef const void * CFTypeRef;
-typedef const struct __CFString * CFStringRef;
-
-# ifdef QT_MAC_USE_COCOA
-#include <private/qunifiedtoolbarsurface_mac_p.h>
-# endif // QT_MAC_USE_COCOA
-
-#endif // Q_WS_MAC
-
-QT_BEGIN_NAMESPACE
-
-class QToolBar;
-class QRubberBand;
-
-/* This data structure represents the state of all the tool-bars and dock-widgets. It's value based
- so it can be easilly copied into a temporary variable. All operations are performed without moving
- any widgets. Only when we are sure we have the desired state, we call apply(), which moves the
- widgets.
-*/
-
-class QMainWindowLayoutState
-{
-public:
- QRect rect;
- QMainWindow *mainWindow;
-
- QMainWindowLayoutState(QMainWindow *win);
-
-#ifndef QT_NO_TOOLBAR
- QToolBarAreaLayout toolBarAreaLayout;
-#endif
-
-#ifndef QT_NO_DOCKWIDGET
- QDockAreaLayout dockAreaLayout;
-#else
- QLayoutItem *centralWidgetItem;
- QRect centralWidgetRect;
-#endif
-
- void apply(bool animated);
- void deleteAllLayoutItems();
- void deleteCentralWidgetItem();
-
- QSize sizeHint() const;
- QSize minimumSize() const;
- void fitLayout();
-
- QLayoutItem *itemAt(int index, int *x) const;
- QLayoutItem *takeAt(int index, int *x);
- QList<int> indexOf(QWidget *widget) const;
- QLayoutItem *item(const QList<int> &path);
- QRect itemRect(const QList<int> &path) const;
- QRect gapRect(const QList<int> &path) const; // ### get rid of this, use itemRect() instead
-
- bool contains(QWidget *widget) const;
-
- void setCentralWidget(QWidget *widget);
- QWidget *centralWidget() const;
-
- QList<int> gapIndex(QWidget *widget, const QPoint &pos) const;
- bool insertGap(const QList<int> &path, QLayoutItem *item);
- void remove(const QList<int> &path);
- void remove(QLayoutItem *item);
- void clear();
- bool isValid() const;
-
- QLayoutItem *plug(const QList<int> &path);
- QLayoutItem *unplug(const QList<int> &path, QMainWindowLayoutState *savedState = 0);
-
- void saveState(QDataStream &stream) const;
- bool checkFormat(QDataStream &stream, bool pre43);
- bool restoreState(QDataStream &stream, const QMainWindowLayoutState &oldState);
-};
-
-class Q_AUTOTEST_EXPORT QMainWindowLayout : public QLayout
-{
- Q_OBJECT
-
-public:
- QMainWindowLayoutState layoutState, savedState;
-
- QMainWindowLayout(QMainWindow *mainwindow, QLayout *parentLayout);
- ~QMainWindowLayout();
-
- QMainWindow::DockOptions dockOptions;
- void setDockOptions(QMainWindow::DockOptions opts);
- bool usesHIToolBar(QToolBar *toolbar) const;
-
- void timerEvent(QTimerEvent *e);
-
- // status bar
-
- QLayoutItem *statusbar;
-
-#ifndef QT_NO_STATUSBAR
- QStatusBar *statusBar() const;
- void setStatusBar(QStatusBar *sb);
-#endif
-
- // central widget
-
- QWidget *centralWidget() const;
- void setCentralWidget(QWidget *cw);
-
- // toolbars
-
-#ifndef QT_NO_TOOLBAR
- void addToolBarBreak(Qt::ToolBarArea area);
- void insertToolBarBreak(QToolBar *before);
- void removeToolBarBreak(QToolBar *before);
-
- void addToolBar(Qt::ToolBarArea area, QToolBar *toolbar, bool needAddChildWidget = true);
- void insertToolBar(QToolBar *before, QToolBar *toolbar);
- Qt::ToolBarArea toolBarArea(QToolBar *toolbar) const;
- bool toolBarBreak(QToolBar *toolBar) const;
- void getStyleOptionInfo(QStyleOptionToolBar *option, QToolBar *toolBar) const;
- void removeToolBar(QToolBar *toolbar);
- void toggleToolBarsVisible();
- void moveToolBar(QToolBar *toolbar, int pos);
-#endif
-
- // dock widgets
-
-#ifndef QT_NO_DOCKWIDGET
- void setCorner(Qt::Corner corner, Qt::DockWidgetArea area);
- Qt::DockWidgetArea corner(Qt::Corner corner) const;
- void addDockWidget(Qt::DockWidgetArea area,
- QDockWidget *dockwidget,
- Qt::Orientation orientation);
- void splitDockWidget(QDockWidget *after,
- QDockWidget *dockwidget,
- Qt::Orientation orientation);
- void tabifyDockWidget(QDockWidget *first, QDockWidget *second);
- Qt::DockWidgetArea dockWidgetArea(QDockWidget *dockwidget) const;
- void raise(QDockWidget *widget);
- void setVerticalTabsEnabled(bool enabled);
- bool restoreDockWidget(QDockWidget *dockwidget);
-
-#ifndef QT_NO_TABBAR
- bool _documentMode;
- bool documentMode() const;
- void setDocumentMode(bool enabled);
-
- QTabBar *getTabBar();
- QSet<QTabBar*> usedTabBars;
- QList<QTabBar*> unusedTabBars;
- bool verticalTabsEnabled;
-
- QWidget *getSeparatorWidget();
- QSet<QWidget*> usedSeparatorWidgets;
- QList<QWidget*> unusedSeparatorWidgets;
- int sep; // separator extent
-
-#ifndef QT_NO_TABWIDGET
- QTabWidget::TabPosition tabPositions[4];
- QTabWidget::TabShape _tabShape;
-
- QTabWidget::TabShape tabShape() const;
- void setTabShape(QTabWidget::TabShape tabShape);
- QTabWidget::TabPosition tabPosition(Qt::DockWidgetArea area) const;
- void setTabPosition(Qt::DockWidgetAreas areas, QTabWidget::TabPosition tabPosition);
-#endif // QT_NO_TABWIDGET
-#endif // QT_NO_TABBAR
-
- // separators
-
- QList<int> movingSeparator;
- QPoint movingSeparatorOrigin, movingSeparatorPos;
- QBasicTimer separatorMoveTimer;
-
- bool startSeparatorMove(const QPoint &pos);
- bool separatorMove(const QPoint &pos);
- bool endSeparatorMove(const QPoint &pos);
- void keepSize(QDockWidget *w);
-#endif // QT_NO_DOCKWIDGET
-
- // save/restore
-
- enum { // sentinel values used to validate state data
- VersionMarker = 0xff
- };
- void saveState(QDataStream &stream) const;
- bool restoreState(QDataStream &stream);
-
- // QLayout interface
-
- void addItem(QLayoutItem *item);
- void setGeometry(const QRect &r);
- QLayoutItem *itemAt(int index) const;
- QLayoutItem *takeAt(int index);
- int count() const;
-
- QSize sizeHint() const;
- QSize minimumSize() const;
- mutable QSize szHint;
- mutable QSize minSize;
- void invalidate();
-
- // animations
-
- QWidgetAnimator widgetAnimator;
- QList<int> currentGapPos;
- QRect currentGapRect;
- QWidget *pluggingWidget;
-#ifndef QT_NO_RUBBERBAND
- QRubberBand *gapIndicator;
-#endif
-
- QList<int> hover(QLayoutItem *widgetItem, const QPoint &mousePos);
- bool plug(QLayoutItem *widgetItem);
- QLayoutItem *unplug(QWidget *widget);
- void revert(QLayoutItem *widgetItem);
- void updateGapIndicator();
- void paintDropIndicator(QPainter *p, QWidget *widget, const QRegion &clip);
- void applyState(QMainWindowLayoutState &newState, bool animate = true);
- void restore(bool keepSavedState = false);
- void updateHIToolBarStatus();
- void animationFinished(QWidget *widget);
-
-private Q_SLOTS:
-#ifndef QT_NO_DOCKWIDGET
-#ifndef QT_NO_TABBAR
- void tabChanged();
-#endif
-#endif
-private:
-#ifndef QT_NO_TABBAR
- void updateTabBarShapes();
-#endif
-#ifdef Q_WS_MAC
-# ifndef QT_MAC_USE_COCOA
- static OSStatus qtmacToolbarDelegate(EventHandlerCallRef, EventRef , void *);
- static OSStatus qtoolbarInHIToolbarHandler(EventHandlerCallRef inCallRef, EventRef event,
- void *data);
- static void qtMacHIToolbarRegisterQToolBarInHIToolborItemClass();
- static HIToolbarItemRef CreateToolbarItemForIdentifier(CFStringRef identifier, CFTypeRef data);
- static HIToolbarItemRef createQToolBarInHIToolbarItem(QToolBar *toolbar,
- QMainWindowLayout *layout);
-# endif
-public:
- struct ToolBarSaveState {
- ToolBarSaveState() : movable(false) { }
- ToolBarSaveState(bool newMovable, const QSize &newMax)
- : movable(newMovable), maximumSize(newMax) { }
- bool movable;
- QSize maximumSize;
- };
- QList<QToolBar *> qtoolbarsInUnifiedToolbarList;
- QList<void *> toolbarItemsCopy;
- QHash<void *, QToolBar *> unifiedToolbarHash;
- QHash<QToolBar *, ToolBarSaveState> toolbarSaveState;
- QHash<QString, QToolBar *> cocoaItemIDToToolbarHash;
- void insertIntoMacToolbar(QToolBar *before, QToolBar *after);
- void removeFromMacToolbar(QToolBar *toolbar);
- void cleanUpMacToolbarItems();
- void fixSizeInUnifiedToolbar(QToolBar *tb) const;
- bool useHIToolBar;
- bool activateUnifiedToolbarAfterFullScreen;
- void syncUnifiedToolbarVisibility();
- bool blockVisiblityCheck;
-
-#ifdef QT_MAC_USE_COCOA
- QUnifiedToolbarSurface *unifiedSurface;
- void updateUnifiedToolbarOffset();
-#endif // QT_MAC_USE_COCOA
-
-#endif // Q_WS_MAC
-};
-QT_END_NAMESPACE
-
-#endif // QT_NO_MAINWINDOW
-
-#endif // QDYNAMICMAINWINDOWLAYOUT_P_H
diff --git a/src/gui/widgets/qmdiarea.h b/src/gui/widgets/qmdiarea.h
deleted file mode 100644
index 48c1c7ba34..0000000000
--- a/src/gui/widgets/qmdiarea.h
+++ /dev/null
@@ -1,179 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QMDIAREA_H
-#define QMDIAREA_H
-
-#include <QtGui/qabstractscrollarea.h>
-#include <QtGui/qtabwidget.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_MDIAREA
-
-class QMdiSubWindow;
-
-class QMdiAreaPrivate;
-class Q_GUI_EXPORT QMdiArea : public QAbstractScrollArea
-{
- Q_OBJECT
- Q_ENUMS(ViewMode)
- Q_PROPERTY(QBrush background READ background WRITE setBackground)
- Q_PROPERTY(WindowOrder activationOrder READ activationOrder WRITE setActivationOrder)
- Q_PROPERTY(ViewMode viewMode READ viewMode WRITE setViewMode)
-#ifndef QT_NO_TABBAR
- Q_PROPERTY(bool documentMode READ documentMode WRITE setDocumentMode)
- Q_PROPERTY(bool tabsClosable READ tabsClosable WRITE setTabsClosable)
- Q_PROPERTY(bool tabsMovable READ tabsMovable WRITE setTabsMovable)
-#endif
-#ifndef QT_NO_TABWIDGET
- Q_PROPERTY(QTabWidget::TabShape tabShape READ tabShape WRITE setTabShape)
- Q_PROPERTY(QTabWidget::TabPosition tabPosition READ tabPosition WRITE setTabPosition)
-#endif
- Q_ENUMS(WindowOrder)
-public:
- enum AreaOption {
- DontMaximizeSubWindowOnActivation = 0x1
- };
- Q_DECLARE_FLAGS(AreaOptions, AreaOption)
-
- enum WindowOrder {
- CreationOrder,
- StackingOrder,
- ActivationHistoryOrder
- };
-
- enum ViewMode {
- SubWindowView,
- TabbedView
- };
-
- QMdiArea(QWidget *parent = 0);
- ~QMdiArea();
-
- QSize sizeHint() const;
- QSize minimumSizeHint() const;
-
- QMdiSubWindow *currentSubWindow() const;
- QMdiSubWindow *activeSubWindow() const;
- QList<QMdiSubWindow *> subWindowList(WindowOrder order = CreationOrder) const;
-
- QMdiSubWindow *addSubWindow(QWidget *widget, Qt::WindowFlags flags = 0);
- void removeSubWindow(QWidget *widget);
-
- QBrush background() const;
- void setBackground(const QBrush &background);
-
- WindowOrder activationOrder() const;
- void setActivationOrder(WindowOrder order);
-
- void setOption(AreaOption option, bool on = true);
- bool testOption(AreaOption opton) const;
-
- void setViewMode(ViewMode mode);
- ViewMode viewMode() const;
-
-#ifndef QT_NO_TABBAR
- bool documentMode() const;
- void setDocumentMode(bool enabled);
-
- void setTabsClosable(bool closable);
- bool tabsClosable() const;
-
- void setTabsMovable(bool movable);
- bool tabsMovable() const;
-#endif
-#ifndef QT_NO_TABWIDGET
- void setTabShape(QTabWidget::TabShape shape);
- QTabWidget::TabShape tabShape() const;
-
- void setTabPosition(QTabWidget::TabPosition position);
- QTabWidget::TabPosition tabPosition() const;
-#endif
-
-Q_SIGNALS:
- void subWindowActivated(QMdiSubWindow *);
-
-public Q_SLOTS:
- void setActiveSubWindow(QMdiSubWindow *window);
- void tileSubWindows();
- void cascadeSubWindows();
- void closeActiveSubWindow();
- void closeAllSubWindows();
- void activateNextSubWindow();
- void activatePreviousSubWindow();
-
-protected Q_SLOTS:
- void setupViewport(QWidget *viewport);
-
-protected:
- bool event(QEvent *event);
- bool eventFilter(QObject *object, QEvent *event);
- void paintEvent(QPaintEvent *paintEvent);
- void childEvent(QChildEvent *childEvent);
- void resizeEvent(QResizeEvent *resizeEvent);
- void timerEvent(QTimerEvent *timerEvent);
- void showEvent(QShowEvent *showEvent);
- bool viewportEvent(QEvent *event);
- void scrollContentsBy(int dx, int dy);
-
-private:
- Q_DISABLE_COPY(QMdiArea)
- Q_DECLARE_PRIVATE(QMdiArea)
- Q_PRIVATE_SLOT(d_func(), void _q_deactivateAllWindows())
- Q_PRIVATE_SLOT(d_func(), void _q_processWindowStateChanged(Qt::WindowStates, Qt::WindowStates))
- Q_PRIVATE_SLOT(d_func(), void _q_currentTabChanged(int))
- Q_PRIVATE_SLOT(d_func(), void _q_closeTab(int))
- Q_PRIVATE_SLOT(d_func(), void _q_moveTab(int, int))
-};
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QMdiArea::AreaOptions)
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QT_NO_MDIAREA
-#endif // QMDIAREA_H
diff --git a/src/gui/widgets/qmdiarea_p.h b/src/gui/widgets/qmdiarea_p.h
deleted file mode 100644
index fe368f2b37..0000000000
--- a/src/gui/widgets/qmdiarea_p.h
+++ /dev/null
@@ -1,285 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QMDIAREA_P_H
-#define QMDIAREA_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qmdiarea.h"
-#include "qmdisubwindow.h"
-
-#ifndef QT_NO_MDIAREA
-
-#include <QList>
-#include <QRect>
-#include <QPoint>
-#include <QtGui/qapplication.h>
-#include <private/qmdisubwindow_p.h>
-#include <private/qabstractscrollarea_p.h>
-
-QT_BEGIN_NAMESPACE
-
-namespace QMdi {
-class Rearranger
-{
-public:
- enum Type {
- RegularTiler,
- SimpleCascader,
- IconTiler
- };
-
- // Rearranges widgets relative to domain.
- virtual void rearrange(QList<QWidget *> &widgets, const QRect &domain) const = 0;
- virtual Type type() const = 0;
- virtual ~Rearranger() {}
-};
-
-class RegularTiler : public Rearranger
-{
- // Rearranges widgets according to a regular tiling pattern
- // covering the entire domain.
- // Both positions and sizes may change.
- void rearrange(QList<QWidget *> &widgets, const QRect &domain) const;
- inline Type type() const { return Rearranger::RegularTiler; }
-};
-
-class SimpleCascader : public Rearranger
-{
- // Rearranges widgets according to a simple, regular cascading pattern.
- // Widgets are resized to minimumSize.
- // Both positions and sizes may change.
- void rearrange(QList<QWidget *> &widgets, const QRect &domain) const;
- inline Type type() const { return Rearranger::SimpleCascader; }
-};
-
-class IconTiler : public Rearranger
-{
- // Rearranges icons (assumed to be the same size) according to a regular
- // tiling pattern filling up the domain from the bottom.
- // Only positions may change.
- void rearrange(QList<QWidget *> &widgets, const QRect &domain) const;
- inline Type type() const { return Rearranger::IconTiler; }
-};
-
-class Placer
-{
-public:
- // Places the rectangle defined by 'size' relative to 'rects' and 'domain'.
- // Returns the position of the resulting rectangle.
- virtual QPoint place(
- const QSize &size, const QList<QRect> &rects, const QRect &domain) const = 0;
- virtual ~Placer() {}
-};
-
-class MinOverlapPlacer : public Placer
-{
- QPoint place(const QSize &size, const QList<QRect> &rects, const QRect &domain) const;
- static int accumulatedOverlap(const QRect &source, const QList<QRect> &rects);
- static QRect findMinOverlapRect(const QList<QRect> &source, const QList<QRect> &rects);
- static void getCandidatePlacements(
- const QSize &size, const QList<QRect> &rects, const QRect &domain,
- QList<QRect> &candidates);
- static QPoint findBestPlacement(
- const QRect &domain, const QList<QRect> &rects, QList<QRect> &source);
- static void findNonInsiders(
- const QRect &domain, QList<QRect> &source, QList<QRect> &result);
- static void findMaxOverlappers(
- const QRect &domain, const QList<QRect> &source, QList<QRect> &result);
-};
-} // namespace QMdi
-
-class QMdiAreaTabBar;
-class QMdiAreaPrivate : public QAbstractScrollAreaPrivate
-{
- Q_DECLARE_PUBLIC(QMdiArea)
-public:
- QMdiAreaPrivate();
-
- // Variables.
- QMdi::Rearranger *cascader;
- QMdi::Rearranger *regularTiler;
- QMdi::Rearranger *iconTiler;
- QMdi::Placer *placer;
-#ifndef QT_NO_RUBBERBAND
- QRubberBand *rubberBand;
-#endif
- QMdiAreaTabBar *tabBar;
- QList<QMdi::Rearranger *> pendingRearrangements;
- QList< QPointer<QMdiSubWindow> > pendingPlacements;
- QList< QPointer<QMdiSubWindow> > childWindows;
- QList<int> indicesToActivatedChildren;
- QPointer<QMdiSubWindow> active;
- QPointer<QMdiSubWindow> aboutToBecomeActive;
- QBrush background;
- QMdiArea::WindowOrder activationOrder;
- QMdiArea::AreaOptions options;
- QMdiArea::ViewMode viewMode;
-#ifndef QT_NO_TABBAR
- bool documentMode;
- bool tabsClosable;
- bool tabsMovable;
-#endif
-#ifndef QT_NO_TABWIDGET
- QTabWidget::TabShape tabShape;
- QTabWidget::TabPosition tabPosition;
-#endif
- bool ignoreGeometryChange;
- bool ignoreWindowStateChange;
- bool isActivated;
- bool isSubWindowsTiled;
- bool showActiveWindowMaximized;
- bool tileCalledFromResizeEvent;
- bool updatesDisabledByUs;
- bool inViewModeChange;
- int indexToNextWindow;
- int indexToPreviousWindow;
- int indexToHighlighted;
- int indexToLastActiveTab;
- int resizeTimerId;
- int tabToPreviousTimerId;
-
- // Slots.
- void _q_deactivateAllWindows(QMdiSubWindow *aboutToActivate = 0);
- void _q_processWindowStateChanged(Qt::WindowStates oldState, Qt::WindowStates newState);
- void _q_currentTabChanged(int index);
- void _q_closeTab(int index);
- void _q_moveTab(int from, int to);
-
- // Functions.
- void appendChild(QMdiSubWindow *child);
- void place(QMdi::Placer *placer, QMdiSubWindow *child);
- void rearrange(QMdi::Rearranger *rearranger);
- void arrangeMinimizedSubWindows();
- void activateWindow(QMdiSubWindow *child);
- void activateCurrentWindow();
- void activateHighlightedWindow();
- void emitWindowActivated(QMdiSubWindow *child);
- void resetActiveWindow(QMdiSubWindow *child = 0);
- void updateActiveWindow(int removedIndex, bool activeRemoved);
- void updateScrollBars();
- void internalRaise(QMdiSubWindow *child) const;
- bool scrollBarsEnabled() const;
- bool lastWindowAboutToBeDestroyed() const;
- void setChildActivationEnabled(bool enable = true, bool onlyNextActivationEvent = false) const;
- QRect resizeToMinimumTileSize(const QSize &minSubWindowSize, int subWindowCount);
- void scrollBarPolicyChanged(Qt::Orientation, Qt::ScrollBarPolicy); // reimp
- QMdiSubWindow *nextVisibleSubWindow(int increaseFactor, QMdiArea::WindowOrder,
- int removed = -1, int fromIndex = -1) const;
- void highlightNextSubWindow(int increaseFactor);
- QList<QMdiSubWindow *> subWindowList(QMdiArea::WindowOrder, bool reversed = false) const;
- void disconnectSubWindow(QObject *subWindow);
- void setViewMode(QMdiArea::ViewMode mode);
-#ifndef QT_NO_TABBAR
- void updateTabBarGeometry();
- void refreshTabBar();
-#endif
-
- inline void startResizeTimer()
- {
- Q_Q(QMdiArea);
- if (resizeTimerId > 0)
- q->killTimer(resizeTimerId);
- resizeTimerId = q->startTimer(200);
- }
-
- inline void startTabToPreviousTimer()
- {
- Q_Q(QMdiArea);
- if (tabToPreviousTimerId > 0)
- q->killTimer(tabToPreviousTimerId);
- tabToPreviousTimerId = q->startTimer(QApplication::keyboardInputInterval());
- }
-
- inline bool windowStaysOnTop(QMdiSubWindow *subWindow) const
- {
- if (!subWindow)
- return false;
- return subWindow->windowFlags() & Qt::WindowStaysOnTopHint;
- }
-
- inline bool isExplicitlyDeactivated(QMdiSubWindow *subWindow) const
- {
- if (!subWindow)
- return true;
- return subWindow->d_func()->isExplicitlyDeactivated;
- }
-
- inline void setActive(QMdiSubWindow *subWindow, bool active = true, bool changeFocus = true) const
- {
- if (subWindow)
- subWindow->d_func()->setActive(active, changeFocus);
- }
-
-#ifndef QT_NO_RUBBERBAND
- inline void showRubberBandFor(QMdiSubWindow *subWindow)
- {
- if (!subWindow || !rubberBand)
- return;
- rubberBand->setGeometry(subWindow->geometry());
- rubberBand->raise();
- rubberBand->show();
- }
-
- inline void hideRubberBand()
- {
- if (rubberBand && rubberBand->isVisible())
- rubberBand->hide();
- indexToHighlighted = -1;
- }
-#endif // QT_NO_RUBBERBAND
-};
-
-#endif // QT_NO_MDIAREA
-
-QT_END_NAMESPACE
-
-#endif // QMDIAREA_P_H
diff --git a/src/gui/widgets/qmdisubwindow.h b/src/gui/widgets/qmdisubwindow.h
deleted file mode 100644
index 530ca4b740..0000000000
--- a/src/gui/widgets/qmdisubwindow.h
+++ /dev/null
@@ -1,159 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QMDISUBWINDOW_H
-#define QMDISUBWINDOW_H
-
-#include <QtGui/qwidget.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_MDIAREA
-
-class QMenu;
-class QMdiArea;
-
-namespace QMdi { class ControlContainer; }
-class QMdiSubWindowPrivate;
-class Q_GUI_EXPORT QMdiSubWindow : public QWidget
-{
- Q_OBJECT
- Q_PROPERTY(int keyboardSingleStep READ keyboardSingleStep WRITE setKeyboardSingleStep)
- Q_PROPERTY(int keyboardPageStep READ keyboardPageStep WRITE setKeyboardPageStep)
-public:
- enum SubWindowOption {
- AllowOutsideAreaHorizontally = 0x1, // internal
- AllowOutsideAreaVertically = 0x2, // internal
- RubberBandResize = 0x4,
- RubberBandMove = 0x8
- };
- Q_DECLARE_FLAGS(SubWindowOptions, SubWindowOption)
-
- QMdiSubWindow(QWidget *parent = 0, Qt::WindowFlags flags = 0);
- ~QMdiSubWindow();
-
- QSize sizeHint() const;
- QSize minimumSizeHint() const;
-
- void setWidget(QWidget *widget);
- QWidget *widget() const;
-
- QWidget *maximizedButtonsWidget() const; // internal
- QWidget *maximizedSystemMenuIconWidget() const; // internal
-
- bool isShaded() const;
-
- void setOption(SubWindowOption option, bool on = true);
- bool testOption(SubWindowOption) const;
-
- void setKeyboardSingleStep(int step);
- int keyboardSingleStep() const;
-
- void setKeyboardPageStep(int step);
- int keyboardPageStep() const;
-
-#ifndef QT_NO_MENU
- void setSystemMenu(QMenu *systemMenu);
- QMenu *systemMenu() const;
-#endif
-
- QMdiArea *mdiArea() const;
-
-Q_SIGNALS:
- void windowStateChanged(Qt::WindowStates oldState, Qt::WindowStates newState);
- void aboutToActivate();
-
-public Q_SLOTS:
-#ifndef QT_NO_MENU
- void showSystemMenu();
-#endif
- void showShaded();
-
-protected:
- bool eventFilter(QObject *object, QEvent *event);
- bool event(QEvent *event);
- void showEvent(QShowEvent *showEvent);
- void hideEvent(QHideEvent *hideEvent);
- void changeEvent(QEvent *changeEvent);
- void closeEvent(QCloseEvent *closeEvent);
- void leaveEvent(QEvent *leaveEvent);
- void resizeEvent(QResizeEvent *resizeEvent);
- void timerEvent(QTimerEvent *timerEvent);
- void moveEvent(QMoveEvent *moveEvent);
- void paintEvent(QPaintEvent *paintEvent);
- void mousePressEvent(QMouseEvent *mouseEvent);
- void mouseDoubleClickEvent(QMouseEvent *mouseEvent);
- void mouseReleaseEvent(QMouseEvent *mouseEvent);
- void mouseMoveEvent(QMouseEvent *mouseEvent);
- void keyPressEvent(QKeyEvent *keyEvent);
-#ifndef QT_NO_CONTEXTMENU
- void contextMenuEvent(QContextMenuEvent *contextMenuEvent);
-#endif
- void focusInEvent(QFocusEvent *focusInEvent);
- void focusOutEvent(QFocusEvent *focusOutEvent);
- void childEvent(QChildEvent *childEvent);
-
-private:
- Q_DISABLE_COPY(QMdiSubWindow)
- Q_DECLARE_PRIVATE(QMdiSubWindow)
- Q_PRIVATE_SLOT(d_func(), void _q_updateStaysOnTopHint())
- Q_PRIVATE_SLOT(d_func(), void _q_enterInteractiveMode())
- Q_PRIVATE_SLOT(d_func(), void _q_processFocusChanged(QWidget *, QWidget *))
- friend class QMdiAreaPrivate;
-#ifndef QT_NO_TABBAR
- friend class QMdiAreaTabBar;
-#endif
- friend class QMdi::ControlContainer;
-};
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QMdiSubWindow::SubWindowOptions)
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QT_NO_MDIAREA
-
-#endif // QMDISUBWINDOW_H
diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp
deleted file mode 100644
index 932b14f6e7..0000000000
--- a/src/gui/widgets/qmenu.cpp
+++ /dev/null
@@ -1,3560 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qmenu.h"
-
-#ifndef QT_NO_MENU
-
-#include "qdebug.h"
-#include "qstyle.h"
-#include "qevent.h"
-#include "qtimer.h"
-#include "qlayout.h"
-#include "qpainter.h"
-#include "qapplication.h"
-#include "qdesktopwidget.h"
-#ifndef QT_NO_ACCESSIBILITY
-# include "qaccessible.h"
-#endif
-#ifndef QT_NO_EFFECTS
-# include <private/qeffects_p.h>
-#endif
-#ifndef QT_NO_WHATSTHIS
-# include <qwhatsthis.h>
-#endif
-
-#include "qmenu_p.h"
-#include "qmenubar_p.h"
-#include "qwidgetaction.h"
-#include "qtoolbutton.h"
-#include "qpushbutton.h"
-#include <private/qpushbutton_p.h>
-#include <private/qaction_p.h>
-#include <private/qsoftkeymanager_p.h>
-#ifdef QT3_SUPPORT
-#include <qmenudata.h>
-#endif // QT3_SUPPORT
-
-#ifdef Q_WS_X11
-# include <private/qt_x11_p.h>
-#endif
-
-#if defined(Q_WS_MAC) && !defined(QT_NO_EFFECTS)
-# include <private/qcore_mac_p.h>
-# include <private/qt_cocoa_helpers_mac_p.h>
-#endif
-
-
-QT_BEGIN_NAMESPACE
-
-QMenu *QMenuPrivate::mouseDown = 0;
-int QMenuPrivate::sloppyDelayTimer = 0;
-
-/* QMenu code */
-// internal class used for the torn off popup
-class QTornOffMenu : public QMenu
-{
- Q_OBJECT
- class QTornOffMenuPrivate : public QMenuPrivate
- {
- Q_DECLARE_PUBLIC(QMenu)
- public:
- QTornOffMenuPrivate(QMenu *p) : causedMenu(p) {
- tornoff = 1;
- causedPopup.widget = 0;
- causedPopup.action = ((QTornOffMenu*)p)->d_func()->causedPopup.action;
- causedStack = ((QTornOffMenu*)p)->d_func()->calcCausedStack();
- }
- QList<QPointer<QWidget> > calcCausedStack() const { return causedStack; }
- QPointer<QMenu> causedMenu;
- QList<QPointer<QWidget> > causedStack;
- };
-public:
- QTornOffMenu(QMenu *p) : QMenu(*(new QTornOffMenuPrivate(p)))
- {
- Q_D(QTornOffMenu);
- // make the torn-off menu a sibling of p (instead of a child)
- QWidget *parentWidget = d->causedStack.isEmpty() ? p : d->causedStack.last();
- if (parentWidget->parentWidget())
- parentWidget = parentWidget->parentWidget();
- setParent(parentWidget, Qt::Window | Qt::Tool);
- setAttribute(Qt::WA_DeleteOnClose, true);
- setAttribute(Qt::WA_X11NetWmWindowTypeMenu, true);
- setWindowTitle(p->windowTitle());
- setEnabled(p->isEnabled());
- //QObject::connect(this, SIGNAL(triggered(QAction*)), this, SLOT(onTrigger(QAction*)));
- //QObject::connect(this, SIGNAL(hovered(QAction*)), this, SLOT(onHovered(QAction*)));
- QList<QAction*> items = p->actions();
- for(int i = 0; i < items.count(); i++)
- addAction(items.at(i));
- }
- void syncWithMenu(QMenu *menu, QActionEvent *act)
- {
- Q_D(QTornOffMenu);
- if(menu != d->causedMenu)
- return;
- if (act->type() == QEvent::ActionAdded) {
- insertAction(act->before(), act->action());
- } else if (act->type() == QEvent::ActionRemoved)
- removeAction(act->action());
- }
- void actionEvent(QActionEvent *e)
- {
- QMenu::actionEvent(e);
- setFixedSize(sizeHint());
- }
-public slots:
- void onTrigger(QAction *action) { d_func()->activateAction(action, QAction::Trigger, false); }
- void onHovered(QAction *action) { d_func()->activateAction(action, QAction::Hover, false); }
-private:
- Q_DECLARE_PRIVATE(QTornOffMenu)
- friend class QMenuPrivate;
-};
-
-void QMenuPrivate::init()
-{
- Q_Q(QMenu);
-#ifndef QT_NO_WHATSTHIS
- q->setAttribute(Qt::WA_CustomWhatsThis);
-#endif
- q->setAttribute(Qt::WA_X11NetWmWindowTypePopupMenu);
- defaultMenuAction = menuAction = new QAction(q);
- menuAction->d_func()->menu = q;
- q->setMouseTracking(q->style()->styleHint(QStyle::SH_Menu_MouseTracking, 0, q));
- if (q->style()->styleHint(QStyle::SH_Menu_Scrollable, 0, q)) {
- scroll = new QMenuPrivate::QMenuScroller;
- scroll->scrollFlags = QMenuPrivate::QMenuScroller::ScrollNone;
- }
-
-#ifdef QT_SOFTKEYS_ENABLED
- selectAction = QSoftKeyManager::createKeyedAction(QSoftKeyManager::SelectSoftKey, Qt::Key_Select, q);
- cancelAction = QSoftKeyManager::createKeyedAction(QSoftKeyManager::CancelSoftKey, Qt::Key_Back, q);
- selectAction->setPriority(QAction::HighPriority);
- cancelAction->setPriority(QAction::HighPriority);
- q->addAction(selectAction);
- q->addAction(cancelAction);
-#endif
-}
-
-int QMenuPrivate::scrollerHeight() const
-{
- Q_Q(const QMenu);
- return qMax(QApplication::globalStrut().height(), q->style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, q));
-}
-
-//Windows and KDE allows menus to cover the taskbar, while GNOME and Mac don't
-QRect QMenuPrivate::popupGeometry(const QWidget *widget) const
-{
-#ifdef Q_WS_WIN
- return QApplication::desktop()->screenGeometry(widget);
-#elif defined Q_WS_X11
- if (X11->desktopEnvironment == DE_KDE)
- return QApplication::desktop()->screenGeometry(widget);
- else
- return QApplication::desktop()->availableGeometry(widget);
-#else
- return QApplication::desktop()->availableGeometry(widget);
-#endif
-}
-
-//Windows and KDE allows menus to cover the taskbar, while GNOME and Mac don't
-QRect QMenuPrivate::popupGeometry(int screen) const
-{
-#ifdef Q_WS_WIN
- return QApplication::desktop()->screenGeometry(screen);
-#elif defined Q_WS_X11
- if (X11->desktopEnvironment == DE_KDE)
- return QApplication::desktop()->screenGeometry(screen);
- else
- return QApplication::desktop()->availableGeometry(screen);
-#else
- return QApplication::desktop()->availableGeometry(screen);
-#endif
-}
-
-QList<QPointer<QWidget> > QMenuPrivate::calcCausedStack() const
-{
- QList<QPointer<QWidget> > ret;
- for(QWidget *widget = causedPopup.widget; widget; ) {
- ret.append(widget);
- if (QTornOffMenu *qtmenu = qobject_cast<QTornOffMenu*>(widget))
- ret += qtmenu->d_func()->causedStack;
- if (QMenu *qmenu = qobject_cast<QMenu*>(widget))
- widget = qmenu->d_func()->causedPopup.widget;
- else
- break;
- }
- return ret;
-}
-
-void QMenuPrivate::updateActionRects() const
-{
- Q_Q(const QMenu);
- updateActionRects(popupGeometry(q));
-}
-
-void QMenuPrivate::updateActionRects(const QRect &screen) const
-{
- Q_Q(const QMenu);
- if (!itemsDirty)
- return;
-
- q->ensurePolished();
-
- //let's reinitialize the buffer
- actionRects.resize(actions.count());
- actionRects.fill(QRect());
-
- int lastVisibleAction = getLastVisibleAction();
-
- int max_column_width = 0,
- dh = screen.height(),
- y = 0;
- QStyle *style = q->style();
- QStyleOption opt;
- opt.init(q);
- const int hmargin = style->pixelMetric(QStyle::PM_MenuHMargin, &opt, q),
- vmargin = style->pixelMetric(QStyle::PM_MenuVMargin, &opt, q),
- icone = style->pixelMetric(QStyle::PM_SmallIconSize, &opt, q);
- const int fw = style->pixelMetric(QStyle::PM_MenuPanelWidth, &opt, q);
- const int deskFw = style->pixelMetric(QStyle::PM_MenuDesktopFrameWidth, &opt, q);
- const int tearoffHeight = tearoff ? style->pixelMetric(QStyle::PM_MenuTearoffHeight, &opt, q) : 0;
-
- //for compatibility now - will have to refactor this away
- tabWidth = 0;
- maxIconWidth = 0;
- hasCheckableItems = false;
- ncols = 1;
- sloppyAction = 0;
-
- for (int i = 0; i < actions.count(); ++i) {
- QAction *action = actions.at(i);
- if (action->isSeparator() || !action->isVisible() || widgetItems.contains(action))
- continue;
- //..and some members
- hasCheckableItems |= action->isCheckable();
- QIcon is = action->icon();
- if (!is.isNull()) {
- maxIconWidth = qMax<uint>(maxIconWidth, icone + 4);
- }
- }
-
- //calculate size
- QFontMetrics qfm = q->fontMetrics();
- bool previousWasSeparator = true; // this is true to allow removing the leading separators
- for(int i = 0; i <= lastVisibleAction; i++) {
- QAction *action = actions.at(i);
-
- if (!action->isVisible() ||
- (collapsibleSeparators && previousWasSeparator && action->isSeparator()))
- continue; // we continue, this action will get an empty QRect
-
- previousWasSeparator = action->isSeparator();
-
- //let the style modify the above size..
- QStyleOptionMenuItem opt;
- q->initStyleOption(&opt, action);
- const QFontMetrics &fm = opt.fontMetrics;
-
- QSize sz;
- if (QWidget *w = widgetItems.value(action)) {
- sz = w->sizeHint().expandedTo(w->minimumSize()).expandedTo(w->minimumSizeHint()).boundedTo(w->maximumSize());
- } else {
- //calc what I think the size is..
- if (action->isSeparator()) {
- sz = QSize(2, 2);
- } else {
- QString s = action->text();
- int t = s.indexOf(QLatin1Char('\t'));
- if (t != -1) {
- tabWidth = qMax(int(tabWidth), qfm.width(s.mid(t+1)));
- s = s.left(t);
- #ifndef QT_NO_SHORTCUT
- } else {
- QKeySequence seq = action->shortcut();
- if (!seq.isEmpty())
- tabWidth = qMax(int(tabWidth), qfm.width(seq));
- #endif
- }
- sz.setWidth(fm.boundingRect(QRect(), Qt::TextSingleLine | Qt::TextShowMnemonic, s).width());
- sz.setHeight(qMax(fm.height(), qfm.height()));
-
- QIcon is = action->icon();
- if (!is.isNull()) {
- QSize is_sz = QSize(icone, icone);
- if (is_sz.height() > sz.height())
- sz.setHeight(is_sz.height());
- }
- }
- sz = style->sizeFromContents(QStyle::CT_MenuItem, &opt, sz, q);
- }
-
-
- if (!sz.isEmpty()) {
- max_column_width = qMax(max_column_width, sz.width());
- //wrapping
- if (!scroll &&
- y+sz.height()+vmargin > dh - (deskFw * 2)) {
- ncols++;
- y = vmargin;
- }
- y += sz.height();
- //update the item
- actionRects[i] = QRect(0, 0, sz.width(), sz.height());
- }
- }
-
- max_column_width += tabWidth; //finally add in the tab width
- const int sfcMargin = style->sizeFromContents(QStyle::CT_Menu, &opt, QApplication::globalStrut(), q).width() - QApplication::globalStrut().width();
- const int min_column_width = q->minimumWidth() - (sfcMargin + leftmargin + rightmargin + 2 * (fw + hmargin));
- max_column_width = qMax(min_column_width, max_column_width);
-
- //calculate position
- const int base_y = vmargin + fw + topmargin +
- (scroll ? scroll->scrollOffset : 0) +
- tearoffHeight;
- int x = hmargin + fw + leftmargin;
- y = base_y;
-
- for(int i = 0; i < actions.count(); i++) {
- QRect &rect = actionRects[i];
- if (rect.isNull())
- continue;
- if (!scroll &&
- y+rect.height() > dh - deskFw * 2) {
- x += max_column_width + hmargin;
- y = base_y;
- }
- rect.translate(x, y); //move
- rect.setWidth(max_column_width); //uniform width
-
- //we need to update the widgets geometry
- if (QWidget *widget = widgetItems.value(actions.at(i))) {
- widget->setGeometry(rect);
- widget->setVisible(actions.at(i)->isVisible());
- }
-
- y += rect.height();
- }
- itemsDirty = 0;
-}
-
-QSize QMenuPrivate::adjustMenuSizeForScreen(const QRect &screen)
-{
- Q_Q(QMenu);
- QSize ret = screen.size();
- itemsDirty = true;
- updateActionRects(screen);
- const int fw = q->style()->pixelMetric(QStyle::PM_MenuPanelWidth, 0, q);
- ret.setWidth(actionRects.at(getLastVisibleAction()).right() + fw);
- return ret;
-}
-
-int QMenuPrivate::getLastVisibleAction() const
-{
- //let's try to get the last visible action
- int lastVisibleAction = actions.count() - 1;
- for (;lastVisibleAction >= 0; --lastVisibleAction) {
- const QAction *action = actions.at(lastVisibleAction);
- if (action->isVisible()) {
- //removing trailing separators
- if (action->isSeparator() && collapsibleSeparators)
- continue;
- break;
- }
- }
- return lastVisibleAction;
-}
-
-
-QRect QMenuPrivate::actionRect(QAction *act) const
-{
- int index = actions.indexOf(act);
- if (index == -1)
- return QRect();
-
- updateActionRects();
-
- //we found the action
- return actionRects.at(index);
-}
-
-#if defined(Q_WS_MAC)
-static const qreal MenuFadeTimeInSec = 0.150;
-#endif
-
-void QMenuPrivate::hideUpToMenuBar()
-{
- Q_Q(QMenu);
- bool fadeMenus = q->style()->styleHint(QStyle::SH_Menu_FadeOutOnHide);
- if (!tornoff) {
- QWidget *caused = causedPopup.widget;
- hideMenu(q); //hide after getting causedPopup
- while(caused) {
-#ifndef QT_NO_MENUBAR
- if (QMenuBar *mb = qobject_cast<QMenuBar*>(caused)) {
- mb->d_func()->setCurrentAction(0);
- mb->d_func()->setKeyboardMode(false);
- caused = 0;
- } else
-#endif
- if (QMenu *m = qobject_cast<QMenu*>(caused)) {
- caused = m->d_func()->causedPopup.widget;
- if (!m->d_func()->tornoff)
- hideMenu(m, fadeMenus);
- if (!fadeMenus) // Mac doesn't clear the action until after hidden.
- m->d_func()->setCurrentAction(0);
- } else { caused = 0;
- }
- }
-#if defined(Q_WS_MAC)
- if (fadeMenus) {
- QEventLoop eventLoop;
- QTimer::singleShot(int(MenuFadeTimeInSec * 1000), &eventLoop, SLOT(quit()));
- QMacWindowFader::currentFader()->performFade();
- eventLoop.exec();
- }
-#endif
- }
- setCurrentAction(0);
-}
-
-void QMenuPrivate::hideMenu(QMenu *menu, bool justRegister)
-{
- if (!menu)
- return;
-#if !defined(QT_NO_EFFECTS)
- menu->blockSignals(true);
- aboutToHide = true;
- // Flash item which is about to trigger (if any).
- if (menu->style()->styleHint(QStyle::SH_Menu_FlashTriggeredItem)
- && currentAction && currentAction == actionAboutToTrigger
- && menu->actions().contains(currentAction)) {
- QEventLoop eventLoop;
- QAction *activeAction = currentAction;
-
- menu->setActiveAction(0);
- QTimer::singleShot(60, &eventLoop, SLOT(quit()));
- eventLoop.exec();
-
- // Select and wait 20 ms.
- menu->setActiveAction(activeAction);
- QTimer::singleShot(20, &eventLoop, SLOT(quit()));
- eventLoop.exec();
- }
-
- // Fade out.
- if (menu->style()->styleHint(QStyle::SH_Menu_FadeOutOnHide)) {
- // ### Qt 4.4:
- // Should be something like: q->transitionWindow(Qt::FadeOutTransition, MenuFadeTimeInSec);
- // Hopefully we'll integrate qt/research/windowtransitions into main before 4.4.
- // Talk to Richard, Trenton or Bjoern.
-#if defined(Q_WS_MAC)
- if (justRegister) {
- QMacWindowFader::currentFader()->setFadeDuration(MenuFadeTimeInSec);
- QMacWindowFader::currentFader()->registerWindowToFade(menu);
- } else {
- macWindowFade(qt_mac_window_for(menu), MenuFadeTimeInSec);
- }
-
-#endif // Q_WS_MAC
- }
- aboutToHide = false;
- menu->blockSignals(false);
-#endif // QT_NO_EFFECTS
- if (!justRegister)
- menu->hide();
-}
-
-void QMenuPrivate::popupAction(QAction *action, int delay, bool activateFirst)
-{
- Q_Q(QMenu);
- if (action && action->isEnabled()) {
- if (!delay)
- q->internalDelayedPopup();
- else if (!menuDelayTimer.isActive() && (!action->menu() || !action->menu()->isVisible()))
- menuDelayTimer.start(delay, q);
- if (activateFirst && action->menu())
- action->menu()->d_func()->setFirstActionActive();
- } else if (QMenu *menu = activeMenu) { //hide the current item
- activeMenu = 0;
- hideMenu(menu);
- }
-}
-
-void QMenuPrivate::setSyncAction()
-{
- Q_Q(QMenu);
- QAction *current = currentAction;
- if(current && (!current->isEnabled() || current->menu() || current->isSeparator()))
- current = 0;
- for(QWidget *caused = q; caused;) {
- if (QMenu *m = qobject_cast<QMenu*>(caused)) {
- caused = m->d_func()->causedPopup.widget;
- if (m->d_func()->eventLoop)
- m->d_func()->syncAction = current; // synchronous operation
- } else {
- break;
- }
- }
-}
-
-
-void QMenuPrivate::setFirstActionActive()
-{
- Q_Q(QMenu);
- updateActionRects();
- for(int i = 0, saccum = 0; i < actions.count(); i++) {
- const QRect &rect = actionRects.at(i);
- if (rect.isNull())
- continue;
- if (scroll && scroll->scrollFlags & QMenuScroller::ScrollUp) {
- saccum -= rect.height();
- if (saccum > scroll->scrollOffset - scrollerHeight())
- continue;
- }
- QAction *act = actions.at(i);
- if (!act->isSeparator() &&
- (q->style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, q)
- || act->isEnabled())) {
- setCurrentAction(act);
- break;
- }
- }
-}
-
-// popup == -1 means do not popup, 0 means immediately, others mean use a timer
-void QMenuPrivate::setCurrentAction(QAction *action, int popup, SelectionReason reason, bool activateFirst)
-{
- Q_Q(QMenu);
- tearoffHighlighted = 0;
- if (currentAction)
- q->update(actionRect(currentAction));
-
- sloppyAction = 0;
- if (!sloppyRegion.isEmpty())
- sloppyRegion = QRegion();
- QMenu *hideActiveMenu = activeMenu;
-#ifndef QT_NO_STATUSTIP
- QAction *previousAction = currentAction;
-#endif
-#ifdef QT3_SUPPORT
- emitHighlighted = action;
-#endif
-
- currentAction = action;
- if (action) {
- if (!action->isSeparator()) {
- activateAction(action, QAction::Hover);
- if (popup != -1) {
- hideActiveMenu = 0; //will be done "later"
- // if the menu is visible then activate the required action,
- // otherwise we just mark the action as currentAction
- // and activate it when the menu will be popuped.
- if (q->isVisible())
- popupAction(currentAction, popup, activateFirst);
- }
- q->update(actionRect(action));
-
- if (reason == SelectedFromKeyboard) {
- QWidget *widget = widgetItems.value(action);
- if (widget) {
- if (widget->focusPolicy() != Qt::NoFocus)
- widget->setFocus(Qt::TabFocusReason);
- } else {
- //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.
- if (!q->hasFocus()) {
- q->setFocus(Qt::PopupFocusReason);
- }
- }
- }
- } else { //action is a separator
- if (popup != -1)
- hideActiveMenu = 0; //will be done "later"
- }
-#ifndef QT_NO_STATUSTIP
- } else if (previousAction) {
- previousAction->d_func()->showStatusText(topCausedWidget(), QString());
-#endif
- }
- if (hideActiveMenu) {
- activeMenu = 0;
-#ifndef QT_NO_EFFECTS
- // kill any running effect
- qFadeEffect(0);
- qScrollEffect(0);
-#endif
- hideMenu(hideActiveMenu);
- }
-}
-
-//return the top causedPopup.widget that is not a QMenu
-QWidget *QMenuPrivate::topCausedWidget() const
-{
- QWidget* top = causedPopup.widget;
- while (QMenu* m = qobject_cast<QMenu *>(top))
- top = m->d_func()->causedPopup.widget;
- return top;
-}
-
-QAction *QMenuPrivate::actionAt(QPoint p) const
-{
- if (!q_func()->rect().contains(p)) //sanity check
- return 0;
-
- for(int i = 0; i < actionRects.count(); i++) {
- if (actionRects.at(i).contains(p))
- return actions.at(i);
- }
- return 0;
-}
-
-void QMenuPrivate::setOverrideMenuAction(QAction *a)
-{
- Q_Q(QMenu);
- QObject::disconnect(menuAction, SIGNAL(destroyed()), q, SLOT(_q_overrideMenuActionDestroyed()));
- if (a) {
- menuAction = a;
- QObject::connect(a, SIGNAL(destroyed()), q, SLOT(_q_overrideMenuActionDestroyed()));
- } else { //we revert back to the default action created by the QMenu itself
- menuAction = defaultMenuAction;
- }
-}
-
-void QMenuPrivate::_q_overrideMenuActionDestroyed()
-{
- menuAction=defaultMenuAction;
-}
-
-
-void QMenuPrivate::updateLayoutDirection()
-{
- Q_Q(QMenu);
- //we need to mimic the cause of the popup's layout direction
- //to allow setting it on a mainwindow for example
- //we call setLayoutDirection_helper to not overwrite a user-defined value
- if (!q->testAttribute(Qt::WA_SetLayoutDirection)) {
- if (QWidget *w = causedPopup.widget)
- setLayoutDirection_helper(w->layoutDirection());
- else if (QWidget *w = q->parentWidget())
- setLayoutDirection_helper(w->layoutDirection());
- else
- setLayoutDirection_helper(QApplication::layoutDirection());
- }
-}
-
-
-/*!
- Returns the action associated with this menu.
-*/
-QAction *QMenu::menuAction() const
-{
- return d_func()->menuAction;
-}
-
-/*!
- \property QMenu::title
- \brief The title of the menu
-
- This is equivalent to the QAction::text property of the menuAction().
-
- By default, this property contains an empty string.
-*/
-QString QMenu::title() const
-{
- return d_func()->menuAction->text();
-}
-
-void QMenu::setTitle(const QString &text)
-{
- d_func()->menuAction->setText(text);
-}
-
-/*!
- \property QMenu::icon
-
- \brief The icon of the menu
-
- This is equivalent to the QAction::icon property of the menuAction().
-
- By default, if no icon is explicitly set, this property contains a null icon.
-*/
-QIcon QMenu::icon() const
-{
- return d_func()->menuAction->icon();
-}
-
-void QMenu::setIcon(const QIcon &icon)
-{
- d_func()->menuAction->setIcon(icon);
-}
-
-
-//actually performs the scrolling
-void QMenuPrivate::scrollMenu(QAction *action, QMenuScroller::ScrollLocation location, bool active)
-{
- Q_Q(QMenu);
- if (!scroll || !scroll->scrollFlags)
- return;
- updateActionRects();
- int newOffset = 0;
- const int topScroll = (scroll->scrollFlags & QMenuScroller::ScrollUp) ? scrollerHeight() : 0;
- const int botScroll = (scroll->scrollFlags & QMenuScroller::ScrollDown) ? scrollerHeight() : 0;
- const int vmargin = q->style()->pixelMetric(QStyle::PM_MenuVMargin, 0, q);
- const int fw = q->style()->pixelMetric(QStyle::PM_MenuPanelWidth, 0, q);
-
- if (location == QMenuScroller::ScrollTop) {
- for(int i = 0, saccum = 0; i < actions.count(); i++) {
- if (actions.at(i) == action) {
- newOffset = topScroll - saccum;
- break;
- }
- saccum += actionRects.at(i).height();
- }
- } else {
- for(int i = 0, saccum = 0; i < actions.count(); i++) {
- saccum += actionRects.at(i).height();
- if (actions.at(i) == action) {
- if (location == QMenuScroller::ScrollCenter)
- newOffset = ((q->height() / 2) - botScroll) - (saccum - topScroll);
- else
- newOffset = (q->height() - botScroll) - saccum;
- break;
- }
- }
- if(newOffset)
- newOffset -= fw * 2;
- }
-
- //figure out which scroll flags
- uint newScrollFlags = QMenuScroller::ScrollNone;
- if (newOffset < 0) //easy and cheap one
- newScrollFlags |= QMenuScroller::ScrollUp;
- int saccum = newOffset;
- for(int i = 0; i < actionRects.count(); i++) {
- saccum += actionRects.at(i).height();
- if (saccum > q->height()) {
- newScrollFlags |= QMenuScroller::ScrollDown;
- break;
- }
- }
-
- if (!(newScrollFlags & QMenuScroller::ScrollDown) && (scroll->scrollFlags & QMenuScroller::ScrollDown)) {
- newOffset = q->height() - (saccum - newOffset) - fw*2 - vmargin; //last item at bottom
- }
-
- if (!(newScrollFlags & QMenuScroller::ScrollUp) && (scroll->scrollFlags & QMenuScroller::ScrollUp)) {
- newOffset = 0; //first item at top
- }
-
- if (newScrollFlags & QMenuScroller::ScrollUp)
- newOffset -= vmargin;
-
- QRect screen = popupGeometry(q);
- const int desktopFrame = q->style()->pixelMetric(QStyle::PM_MenuDesktopFrameWidth, 0, q);
- if (q->height() < screen.height()-(desktopFrame*2)-1) {
- QRect geom = q->geometry();
- if (newOffset > scroll->scrollOffset && (scroll->scrollFlags & newScrollFlags & QMenuScroller::ScrollUp)) { //scroll up
- const int newHeight = geom.height()-(newOffset-scroll->scrollOffset);
- if(newHeight > geom.height())
- geom.setHeight(newHeight);
- } else if(scroll->scrollFlags & newScrollFlags & QMenuScroller::ScrollDown) {
- int newTop = geom.top() + (newOffset-scroll->scrollOffset);
- if (newTop < desktopFrame+screen.top())
- newTop = desktopFrame+screen.top();
- if (newTop < geom.top()) {
- geom.setTop(newTop);
- newOffset = 0;
- newScrollFlags &= ~QMenuScroller::ScrollUp;
- }
- }
- if (geom.bottom() > screen.bottom() - desktopFrame)
- geom.setBottom(screen.bottom() - desktopFrame);
- if (geom.top() < desktopFrame+screen.top())
- geom.setTop(desktopFrame+screen.top());
- if (geom != q->geometry()) {
-#if 0
- if (newScrollFlags & QMenuScroller::ScrollDown &&
- q->geometry().top() - geom.top() >= -newOffset)
- newScrollFlags &= ~QMenuScroller::ScrollDown;
-#endif
- q->setGeometry(geom);
- }
- }
-
- //actually update flags
- const int delta = qMin(0, newOffset) - scroll->scrollOffset; //make sure the new offset is always negative
- if (!itemsDirty && delta) {
- //we've scrolled so we need to update the action rects
- for (int i = 0; i < actionRects.count(); ++i) {
- QRect &current = actionRects[i];
- current.moveTop(current.top() + delta);
-
- //we need to update the widgets geometry
- if (QWidget *w = widgetItems.value(actions.at(i)))
- w->setGeometry(current);
- }
- }
- scroll->scrollOffset += delta;
- scroll->scrollFlags = newScrollFlags;
- if (active)
- setCurrentAction(action);
-
- q->update(); //issue an update so we see all the new state..
-}
-
-void QMenuPrivate::scrollMenu(QMenuScroller::ScrollLocation location, bool active)
-{
- Q_Q(QMenu);
- updateActionRects();
- if(location == QMenuScroller::ScrollBottom) {
- for(int i = actions.size()-1; i >= 0; --i) {
- QAction *act = actions.at(i);
- if (actionRects.at(i).isNull())
- continue;
- if (!act->isSeparator() &&
- (q->style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, q)
- || act->isEnabled())) {
- if(scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollDown)
- scrollMenu(act, QMenuPrivate::QMenuScroller::ScrollBottom, active);
- else if(active)
- setCurrentAction(act, /*popup*/-1, QMenuPrivate::SelectedFromKeyboard);
- break;
- }
- }
- } else if(location == QMenuScroller::ScrollTop) {
- for(int i = 0; i < actions.size(); ++i) {
- QAction *act = actions.at(i);
- if (actionRects.at(i).isNull())
- continue;
- if (!act->isSeparator() &&
- (q->style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, q)
- || act->isEnabled())) {
- if(scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp)
- scrollMenu(act, QMenuPrivate::QMenuScroller::ScrollTop, active);
- else if(active)
- setCurrentAction(act, /*popup*/-1, QMenuPrivate::SelectedFromKeyboard);
- break;
- }
- }
- }
-}
-
-//only directional
-void QMenuPrivate::scrollMenu(QMenuScroller::ScrollDirection direction, bool page, bool active)
-{
- Q_Q(QMenu);
- if (!scroll || !(scroll->scrollFlags & direction)) //not really possible...
- return;
- updateActionRects();
- const int topScroll = (scroll->scrollFlags & QMenuScroller::ScrollUp) ? scrollerHeight() : 0;
- const int botScroll = (scroll->scrollFlags & QMenuScroller::ScrollDown) ? scrollerHeight() : 0;
- const int vmargin = q->style()->pixelMetric(QStyle::PM_MenuVMargin, 0, q);
- const int fw = q->style()->pixelMetric(QStyle::PM_MenuPanelWidth, 0, q);
- const int offset = topScroll ? topScroll-vmargin : 0;
- if (direction == QMenuScroller::ScrollUp) {
- for(int i = 0, saccum = 0; i < actions.count(); i++) {
- saccum -= actionRects.at(i).height();
- if (saccum <= scroll->scrollOffset-offset) {
- scrollMenu(actions.at(i), page ? QMenuScroller::ScrollBottom : QMenuScroller::ScrollTop, active);
- break;
- }
- }
- } else if (direction == QMenuScroller::ScrollDown) {
- bool scrolled = false;
- for(int i = 0, saccum = 0; i < actions.count(); i++) {
- const int iHeight = actionRects.at(i).height();
- saccum -= iHeight;
- if (saccum <= scroll->scrollOffset-offset) {
- const int scrollerArea = q->height() - botScroll - fw*2;
- int visible = (scroll->scrollOffset-offset) - saccum;
- for(i++ ; i < actions.count(); i++) {
- visible += actionRects.at(i).height();
- if (visible > scrollerArea - topScroll) {
- scrolled = true;
- scrollMenu(actions.at(i), page ? QMenuScroller::ScrollTop : QMenuScroller::ScrollBottom, active);
- break;
- }
- }
- break;
- }
- }
- if(!scrolled) {
- scroll->scrollFlags &= ~QMenuScroller::ScrollDown;
- q->update();
- }
- }
-}
-
-/* This is poor-mans eventfilters. This avoids the use of
- eventFilter (which can be nasty for users of QMenuBar's). */
-bool QMenuPrivate::mouseEventTaken(QMouseEvent *e)
-{
- Q_Q(QMenu);
- QPoint pos = q->mapFromGlobal(e->globalPos());
- if (scroll && !activeMenu) { //let the scroller "steal" the event
- bool isScroll = false;
- if (pos.x() >= 0 && pos.x() < q->width()) {
- for(int dir = QMenuScroller::ScrollUp; dir <= QMenuScroller::ScrollDown; dir = dir << 1) {
- if (scroll->scrollFlags & dir) {
- if (dir == QMenuScroller::ScrollUp)
- isScroll = (pos.y() <= scrollerHeight());
- else if (dir == QMenuScroller::ScrollDown)
- isScroll = (pos.y() >= q->height() - scrollerHeight());
- if (isScroll) {
- scroll->scrollDirection = dir;
- break;
- }
- }
- }
- }
- if (isScroll) {
- scroll->scrollTimer.start(50, q);
- return true;
- } else {
- scroll->scrollTimer.stop();
- }
- }
-
- if (tearoff) { //let the tear off thingie "steal" the event..
- QRect tearRect(0, 0, q->width(), q->style()->pixelMetric(QStyle::PM_MenuTearoffHeight, 0, q));
- if (scroll && scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp)
- tearRect.translate(0, scrollerHeight());
- q->update(tearRect);
- if (tearRect.contains(pos) && hasMouseMoved(e->globalPos())) {
- setCurrentAction(0);
- tearoffHighlighted = 1;
- if (e->type() == QEvent::MouseButtonRelease) {
- if (!tornPopup)
- tornPopup = new QTornOffMenu(q);
- tornPopup->setGeometry(q->geometry());
- tornPopup->show();
- hideUpToMenuBar();
- }
- return true;
- }
- tearoffHighlighted = 0;
- }
-
- if (q->frameGeometry().contains(e->globalPos())) //otherwise if the event is in our rect we want it..
- return false;
-
- for(QWidget *caused = causedPopup.widget; caused;) {
- bool passOnEvent = false;
- QWidget *next_widget = 0;
- QPoint cpos = caused->mapFromGlobal(e->globalPos());
-#ifndef QT_NO_MENUBAR
- if (QMenuBar *mb = qobject_cast<QMenuBar*>(caused)) {
- passOnEvent = mb->rect().contains(cpos);
- } else
-#endif
- if (QMenu *m = qobject_cast<QMenu*>(caused)) {
- passOnEvent = m->rect().contains(cpos);
- next_widget = m->d_func()->causedPopup.widget;
- }
- if (passOnEvent) {
- if(e->type() != QEvent::MouseButtonRelease || mouseDown == caused) {
- QMouseEvent new_e(e->type(), cpos, e->button(), e->buttons(), e->modifiers());
- QApplication::sendEvent(caused, &new_e);
- return true;
- }
- }
- if (!next_widget)
- break;
- caused = next_widget;
- }
- return false;
-}
-
-void QMenuPrivate::activateCausedStack(const QList<QPointer<QWidget> > &causedStack, QAction *action, QAction::ActionEvent action_e, bool self)
-{
- QBoolBlocker guard(activationRecursionGuard);
-#ifdef QT3_SUPPORT
- const int actionId = q_func()->findIdForAction(action);
-#endif
- if(self)
- action->activate(action_e);
-
- for(int i = 0; i < causedStack.size(); ++i) {
- QPointer<QWidget> widget = causedStack.at(i);
- if (!widget)
- continue;
- //fire
- if (QMenu *qmenu = qobject_cast<QMenu*>(widget)) {
- widget = qmenu->d_func()->causedPopup.widget;
- if (action_e == QAction::Trigger) {
- emit qmenu->triggered(action);
- } else if (action_e == QAction::Hover) {
- emit qmenu->hovered(action);
-#ifdef QT3_SUPPORT
- if (emitHighlighted) {
- emit qmenu->highlighted(actionId);
- emitHighlighted = false;
- }
-#endif
- }
-#ifndef QT_NO_MENUBAR
- } else if (QMenuBar *qmenubar = qobject_cast<QMenuBar*>(widget)) {
- if (action_e == QAction::Trigger) {
- emit qmenubar->triggered(action);
-#ifdef QT3_SUPPORT
- emit qmenubar->activated(actionId);
-#endif
- } else if (action_e == QAction::Hover) {
- emit qmenubar->hovered(action);
-#ifdef QT3_SUPPORT
- if (emitHighlighted) {
- emit qmenubar->highlighted(actionId);
- emitHighlighted = false;
- }
-#endif
- }
- break; //nothing more..
-#endif
- }
- }
-}
-
-void QMenuPrivate::activateAction(QAction *action, QAction::ActionEvent action_e, bool self)
-{
- Q_Q(QMenu);
-#ifndef QT_NO_WHATSTHIS
- bool inWhatsThisMode = QWhatsThis::inWhatsThisMode();
-#endif
- if (!action || !q->isEnabled()
- || (action_e == QAction::Trigger
-#ifndef QT_NO_WHATSTHIS
- && !inWhatsThisMode
-#endif
- && (action->isSeparator() ||!action->isEnabled())))
- return;
-
- /* I have to save the caused stack here because it will be undone after popup execution (ie in the hide).
- Then I iterate over the list to actually send the events. --Sam
- */
- const QList<QPointer<QWidget> > causedStack = calcCausedStack();
- if (action_e == QAction::Trigger) {
-#ifndef QT_NO_WHATSTHIS
- if (!inWhatsThisMode)
- actionAboutToTrigger = action;
-#endif
-
- if (q->testAttribute(Qt::WA_DontShowOnScreen)) {
- hideUpToMenuBar();
- } else {
- for(QWidget *widget = QApplication::activePopupWidget(); widget; ) {
- if (QMenu *qmenu = qobject_cast<QMenu*>(widget)) {
- if(qmenu == q)
- hideUpToMenuBar();
- widget = qmenu->d_func()->causedPopup.widget;
- } else {
- break;
- }
- }
- }
-
-#ifndef QT_NO_WHATSTHIS
- if (inWhatsThisMode) {
- QString s = action->whatsThis();
- if (s.isEmpty())
- s = whatsThis;
- QWhatsThis::showText(q->mapToGlobal(actionRect(action).center()), s, q);
- return;
- }
-#endif
- }
-
-
- activateCausedStack(causedStack, action, action_e, self);
-
-
- if (action_e == QAction::Hover) {
-#ifndef QT_NO_ACCESSIBILITY
- if (QAccessible::isActive()) {
- int actionIndex = indexOf(action) + 1;
- QAccessible::updateAccessibility(q, actionIndex, QAccessible::Focus);
- QAccessible::updateAccessibility(q, actionIndex, QAccessible::Selection);
- }
-#endif
- action->showStatusText(topCausedWidget());
- } else {
- actionAboutToTrigger = 0;
- }
-}
-
-void QMenuPrivate::_q_actionTriggered()
-{
- Q_Q(QMenu);
- if (QAction *action = qobject_cast<QAction *>(q->sender())) {
- QWeakPointer<QAction> actionGuard = action;
-#ifdef QT3_SUPPORT
- //we store it here because the action might be deleted/changed by connected slots
- const int id = q->findIdForAction(action);
-#endif
- emit q->triggered(action);
-#ifdef QT3_SUPPORT
- emit q->activated(id);
-#endif
-
- if (!activationRecursionGuard && actionGuard) {
- //in case the action has not been activated by the mouse
- //we check the parent hierarchy
- QList< QPointer<QWidget> > list;
- for(QWidget *widget = q->parentWidget(); widget; ) {
- if (qobject_cast<QMenu*>(widget)
-#ifndef QT_NO_MENUBAR
- || qobject_cast<QMenuBar*>(widget)
-#endif
- ) {
- list.append(widget);
- widget = widget->parentWidget();
- } else {
- break;
- }
- }
- activateCausedStack(list, action, QAction::Trigger, false);
- }
- }
-}
-
-void QMenuPrivate::_q_actionHovered()
-{
- Q_Q(QMenu);
- if (QAction * action = qobject_cast<QAction *>(q->sender())) {
-#ifdef QT3_SUPPORT
- //we store it here because the action might be deleted/changed by connected slots
- const int id = q->findIdForAction(action);
-#endif
- emit q->hovered(action);
-#ifdef QT3_SUPPORT
- if (emitHighlighted) {
- emit q->highlighted(id);
- emitHighlighted = false;
- }
-#endif
- }
-}
-
-bool QMenuPrivate::hasMouseMoved(const QPoint &globalPos)
-{
- //determines if the mouse has moved (ie its initial position has
- //changed by more than QApplication::startDragDistance()
- //or if there were at least 6 mouse motions)
- return motions > 6 ||
- QApplication::startDragDistance() < (mousePopupPos - globalPos).manhattanLength();
-}
-
-
-/*!
- Initialize \a option with the values from this menu and information from \a action. This method
- is useful for subclasses when they need a QStyleOptionMenuItem, but don't want
- to fill in all the information themselves.
-
- \sa QStyleOption::initFrom() QMenuBar::initStyleOption()
-*/
-void QMenu::initStyleOption(QStyleOptionMenuItem *option, const QAction *action) const
-{
- if (!option || !action)
- return;
-
- Q_D(const QMenu);
- option->initFrom(this);
- option->palette = palette();
- option->state = QStyle::State_None;
-
- if (window()->isActiveWindow())
- option->state |= QStyle::State_Active;
- if (isEnabled() && action->isEnabled()
- && (!action->menu() || action->menu()->isEnabled()))
- option->state |= QStyle::State_Enabled;
- else
- option->palette.setCurrentColorGroup(QPalette::Disabled);
-
- option->font = action->font().resolve(font());
- option->fontMetrics = QFontMetrics(option->font);
-
- if (d->currentAction && d->currentAction == action && !d->currentAction->isSeparator()) {
- option->state |= QStyle::State_Selected
- | (d->mouseDown ? QStyle::State_Sunken : QStyle::State_None);
- }
-
- option->menuHasCheckableItems = d->hasCheckableItems;
- if (!action->isCheckable()) {
- option->checkType = QStyleOptionMenuItem::NotCheckable;
- } else {
- option->checkType = (action->actionGroup() && action->actionGroup()->isExclusive())
- ? QStyleOptionMenuItem::Exclusive : QStyleOptionMenuItem::NonExclusive;
- option->checked = action->isChecked();
- }
- if (action->menu())
- option->menuItemType = QStyleOptionMenuItem::SubMenu;
- else if (action->isSeparator())
- option->menuItemType = QStyleOptionMenuItem::Separator;
- else if (d->defaultAction == action)
- option->menuItemType = QStyleOptionMenuItem::DefaultItem;
- else
- option->menuItemType = QStyleOptionMenuItem::Normal;
- if (action->isIconVisibleInMenu())
- option->icon = action->icon();
- QString textAndAccel = action->text();
-#ifndef QT_NO_SHORTCUT
- if (textAndAccel.indexOf(QLatin1Char('\t')) == -1) {
- QKeySequence seq = action->shortcut();
- if (!seq.isEmpty())
- textAndAccel += QLatin1Char('\t') + QString(seq);
- }
-#endif
- option->text = textAndAccel;
- option->tabWidth = d->tabWidth;
- option->maxIconWidth = d->maxIconWidth;
- option->menuRect = rect();
-}
-
-/*!
- \class QMenu
- \brief The QMenu class provides a menu widget for use in menu
- bars, context menus, and other popup menus.
-
- \ingroup mainwindow-classes
- \ingroup basicwidgets
-
-
- A menu widget is a selection menu. It can be either a pull-down
- menu in a menu bar or a standalone context menu. Pull-down menus
- are shown by the menu bar when the user clicks on the respective
- item or presses the specified shortcut key. Use
- QMenuBar::addMenu() to insert a menu into a menu bar. Context
- menus are usually invoked by some special keyboard key or by
- right-clicking. They can be executed either asynchronously with
- popup() or synchronously with exec(). Menus can also be invoked in
- response to button presses; these are just like context menus
- except for how they are invoked.
-
- \table 100%
- \row
- \o \inlineimage plastique-menu.png
- \o \inlineimage windowsxp-menu.png
- \o \inlineimage macintosh-menu.png
- \endtable
- \caption Fig. A menu shown in \l{Plastique Style Widget Gallery}{Plastique widget style},
- \l{Windows XP Style Widget Gallery}{Windows XP widget style},
- and \l{Macintosh Style Widget Gallery}{Macintosh widget style}.
-
- \section1 Actions
-
- A menu consists of a list of action items. Actions are added with
- the addAction(), addActions() and insertAction() functions. An action
- is represented vertically and rendered by QStyle. In addition, actions
- can have a text label, an optional icon drawn on the very left side,
- and shortcut key sequence such as "Ctrl+X".
-
- The existing actions held by a menu can be found with actions().
-
- There are four kinds of action items: separators, actions that
- show a submenu, widgets, and actions that perform an action.
- Separators are inserted with addSeparator(), submenus with addMenu(),
- and all other items are considered action items.
-
- When inserting action items you usually specify a receiver and a
- slot. The receiver will be notifed whenever the item is
- \l{QAction::triggered()}{triggered()}. In addition, QMenu provides
- two signals, activated() and highlighted(), which signal the
- QAction that was triggered from the menu.
-
- You clear a menu with clear() and remove individual action items
- with removeAction().
-
- A QMenu can also provide a tear-off menu. A tear-off menu is a
- top-level window that contains a copy of the menu. This makes it
- possible for the user to "tear off" frequently used menus and
- position them in a convenient place on the screen. If you want
- this functionality for a particular menu, insert a tear-off handle
- with setTearOffEnabled(). When using tear-off menus, bear in mind
- that the concept isn't typically used on Microsoft Windows so
- some users may not be familiar with it. Consider using a QToolBar
- instead.
-
- Widgets can be inserted into menus with the QWidgetAction class.
- Instances of this class are used to hold widgets, and are inserted
- into menus with the addAction() overload that takes a QAction.
-
- Conversely, actions can be added to widgets with the addAction(),
- addActions() and insertAction() functions.
-
- \warning To make QMenu visible on the screen, exec() or popup() should be
- used instead of show().
-
- \section1 QMenu on Qt for Windows CE
-
- If a menu is integrated into the native menubar on Windows Mobile we
- do not support the signals: aboutToHide (), aboutToShow () and hovered ().
- It is not possible to display an icon in a native menu on Windows Mobile.
-
- \section1 QMenu on Mac OS X with Qt build against Cocoa
-
- QMenu can be inserted only once in a menu/menubar. Subsequent insertions will
- have no effect or will result in a disabled menu item.
-
- See the \l{mainwindows/menus}{Menus} example for an example of how
- to use QMenuBar and QMenu in your application.
-
- \bold{Important inherited functions:} addAction(), removeAction(), clear(),
- addSeparator(), and addMenu().
-
- \sa QMenuBar, {fowler}{GUI Design Handbook: Menu, Drop-Down and Pop-Up},
- {Application Example}, {Menus Example}, {Recent Files Example}
-*/
-
-
-/*!
- Constructs a menu with parent \a parent.
-
- Although a popup menu is always a top-level widget, if a parent is
- passed the popup menu will be deleted when that parent is
- destroyed (as with any other QObject).
-*/
-QMenu::QMenu(QWidget *parent)
- : QWidget(*new QMenuPrivate, parent, Qt::Popup)
-{
- Q_D(QMenu);
- d->init();
-}
-
-/*!
- Constructs a menu with a \a title and a \a parent.
-
- Although a popup menu is always a top-level widget, if a parent is
- passed the popup menu will be deleted when that parent is
- destroyed (as with any other QObject).
-
- \sa title
-*/
-QMenu::QMenu(const QString &title, QWidget *parent)
- : QWidget(*new QMenuPrivate, parent, Qt::Popup)
-{
- Q_D(QMenu);
- d->init();
- d->menuAction->setText(title);
-}
-
-/*! \internal
- */
-QMenu::QMenu(QMenuPrivate &dd, QWidget *parent)
- : QWidget(dd, parent, Qt::Popup)
-{
- Q_D(QMenu);
- d->init();
-}
-
-/*!
- Destroys the menu.
-*/
-QMenu::~QMenu()
-{
- Q_D(QMenu);
- if (!d->widgetItems.isEmpty()) { // avoid detach on shared null hash
- QHash<QAction *, QWidget *>::iterator it = d->widgetItems.begin();
- for (; it != d->widgetItems.end(); ++it) {
- if (QWidget *widget = it.value()) {
- QWidgetAction *action = static_cast<QWidgetAction *>(it.key());
- action->releaseWidget(widget);
- *it = 0;
- }
- }
- }
-
- if (d->eventLoop)
- d->eventLoop->exit();
- hideTearOffMenu();
-}
-
-/*!
- \overload
-
- This convenience function creates a new action with \a text.
- The function adds the newly created action to the menu's
- list of actions, and returns it.
-
- \sa QWidget::addAction()
-*/
-QAction *QMenu::addAction(const QString &text)
-{
- QAction *ret = new QAction(text, this);
- addAction(ret);
- return ret;
-}
-
-/*!
- \overload
-
- This convenience function creates a new action with an \a icon
- and some \a text. The function adds the newly created action to
- the menu's list of actions, and returns it.
-
- \sa QWidget::addAction()
-*/
-QAction *QMenu::addAction(const QIcon &icon, const QString &text)
-{
- QAction *ret = new QAction(icon, text, this);
- addAction(ret);
- return ret;
-}
-
-/*!
- \overload
-
- This convenience function creates a new action with the text \a
- text and an optional shortcut \a shortcut. The action's
- \l{QAction::triggered()}{triggered()} signal is connected to the
- \a receiver's \a member slot. The function adds the newly created
- action to the menu's list of actions and returns it.
-
- \sa QWidget::addAction()
-*/
-QAction *QMenu::addAction(const QString &text, const QObject *receiver, const char* member, const QKeySequence &shortcut)
-{
- QAction *action = new QAction(text, this);
-#ifdef QT_NO_SHORTCUT
- Q_UNUSED(shortcut);
-#else
- action->setShortcut(shortcut);
-#endif
- QObject::connect(action, SIGNAL(triggered(bool)), receiver, member);
- addAction(action);
- return action;
-}
-
-/*!
- \overload
-
- This convenience function creates a new action with an \a icon and
- some \a text and an optional shortcut \a shortcut. The action's
- \l{QAction::triggered()}{triggered()} signal is connected to the
- \a member slot of the \a receiver object. The function adds the
- newly created action to the menu's list of actions, and returns it.
-
- \sa QWidget::addAction()
-*/
-QAction *QMenu::addAction(const QIcon &icon, const QString &text, const QObject *receiver,
- const char* member, const QKeySequence &shortcut)
-{
- QAction *action = new QAction(icon, text, this);
-#ifdef QT_NO_SHORTCUT
- Q_UNUSED(shortcut);
-#else
- action->setShortcut(shortcut);
-#endif
- QObject::connect(action, SIGNAL(triggered(bool)), receiver, member);
- addAction(action);
- return action;
-}
-
-/*!
- This convenience function adds \a menu as a submenu to this menu.
- It returns \a menu's menuAction(). This menu does not take
- ownership of \a menu.
-
- \sa QWidget::addAction() QMenu::menuAction()
-*/
-QAction *QMenu::addMenu(QMenu *menu)
-{
- QAction *action = menu->menuAction();
- addAction(action);
- return action;
-}
-
-/*!
- Appends a new QMenu with \a title to the menu. The menu
- takes ownership of the menu. Returns the new menu.
-
- \sa QWidget::addAction() QMenu::menuAction()
-*/
-QMenu *QMenu::addMenu(const QString &title)
-{
- QMenu *menu = new QMenu(title, this);
- addAction(menu->menuAction());
- return menu;
-}
-
-/*!
- Appends a new QMenu with \a icon and \a title to the menu. The menu
- takes ownership of the menu. Returns the new menu.
-
- \sa QWidget::addAction() QMenu::menuAction()
-*/
-QMenu *QMenu::addMenu(const QIcon &icon, const QString &title)
-{
- QMenu *menu = new QMenu(title, this);
- menu->setIcon(icon);
- addAction(menu->menuAction());
- return menu;
-}
-
-/*!
- This convenience function creates a new separator action, i.e. an
- action with QAction::isSeparator() returning true, and adds the new
- action to this menu's list of actions. It returns the newly
- created action.
-
- \sa QWidget::addAction()
-*/
-QAction *QMenu::addSeparator()
-{
- QAction *action = new QAction(this);
- action->setSeparator(true);
- addAction(action);
- return action;
-}
-
-/*!
- This convenience function inserts \a menu before action \a before
- and returns the menus menuAction().
-
- \sa QWidget::insertAction(), addMenu()
-*/
-QAction *QMenu::insertMenu(QAction *before, QMenu *menu)
-{
- QAction *action = menu->menuAction();
- insertAction(before, action);
- return action;
-}
-
-/*!
- This convenience function creates a new separator action, i.e. an
- action with QAction::isSeparator() returning true. The function inserts
- the newly created action into this menu's list of actions before
- action \a before and returns it.
-
- \sa QWidget::insertAction(), addSeparator()
-*/
-QAction *QMenu::insertSeparator(QAction *before)
-{
- QAction *action = new QAction(this);
- action->setSeparator(true);
- insertAction(before, action);
- return action;
-}
-
-/*!
- This sets the default action to \a act. The default action may have
- a visual cue, depending on the current QStyle. A default action
- usually indicates what will happen by default when a drop occurs.
-
- \sa defaultAction()
-*/
-void QMenu::setDefaultAction(QAction *act)
-{
- d_func()->defaultAction = act;
-}
-
-/*!
- Returns the current default action.
-
- \sa setDefaultAction()
-*/
-QAction *QMenu::defaultAction() const
-{
- return d_func()->defaultAction;
-}
-
-/*!
- \property QMenu::tearOffEnabled
- \brief whether the menu supports being torn off
-
- When true, the menu contains a special tear-off item (often shown as a dashed
- line at the top of the menu) that creates a copy of the menu when it is
- triggered.
-
- This "torn-off" copy lives in a separate window. It contains the same menu
- items as the original menu, with the exception of the tear-off handle.
-
- By default, this property is false.
-*/
-void QMenu::setTearOffEnabled(bool b)
-{
- Q_D(QMenu);
- if (d->tearoff == b)
- return;
- if (!b)
- hideTearOffMenu();
- d->tearoff = b;
-
- d->itemsDirty = true;
- if (isVisible())
- resize(sizeHint());
-}
-
-bool QMenu::isTearOffEnabled() const
-{
- return d_func()->tearoff;
-}
-
-/*!
- When a menu is torn off a second menu is shown to display the menu
- contents in a new window. When the menu is in this mode and the menu
- is visible returns true; otherwise false.
-
- \sa hideTearOffMenu() isTearOffEnabled()
-*/
-bool QMenu::isTearOffMenuVisible() const
-{
- if (d_func()->tornPopup)
- return d_func()->tornPopup->isVisible();
- return false;
-}
-
-/*!
- This function will forcibly hide the torn off menu making it
- disappear from the users desktop.
-
- \sa isTearOffMenuVisible() isTearOffEnabled()
-*/
-void QMenu::hideTearOffMenu()
-{
- if (QWidget *w = d_func()->tornPopup)
- w->close();
-}
-
-
-/*!
- Sets the currently highlighted action to \a act.
-*/
-void QMenu::setActiveAction(QAction *act)
-{
- Q_D(QMenu);
- d->setCurrentAction(act, 0);
- if (d->scroll)
- d->scrollMenu(act, QMenuPrivate::QMenuScroller::ScrollCenter);
-}
-
-
-/*!
- Returns the currently highlighted action, or 0 if no
- action is currently highlighted.
-*/
-QAction *QMenu::activeAction() const
-{
- return d_func()->currentAction;
-}
-
-/*!
- \since 4.2
-
- Returns true if there are no visible actions inserted into the menu, false
- otherwise.
-
- \sa QWidget::actions()
-*/
-
-bool QMenu::isEmpty() const
-{
- bool ret = true;
- for(int i = 0; ret && i < actions().count(); ++i) {
- const QAction *action = actions().at(i);
- if (!action->isSeparator() && action->isVisible()) {
- ret = false;
- }
- }
- return ret;
-}
-
-/*!
- Removes all the menu's actions. Actions owned by the menu and not
- shown in any other widget are deleted.
-
- \sa removeAction()
-*/
-void QMenu::clear()
-{
- QList<QAction*> acts = actions();
-
- for(int i = 0; i < acts.size(); i++) {
-#ifdef QT_SOFTKEYS_ENABLED
- Q_D(QMenu);
- // Lets not touch to our internal softkey actions
- if(acts[i] == d->selectAction || acts[i] == d->cancelAction)
- continue;
-#endif
- removeAction(acts[i]);
- if (acts[i]->parent() == this && acts[i]->d_func()->widgets.isEmpty())
- delete acts[i];
- }
-}
-
-/*!
- If a menu does not fit on the screen it lays itself out so that it
- does fit. It is style dependent what layout means (for example, on
- Windows it will use multiple columns).
-
- This functions returns the number of columns necessary.
-*/
-int QMenu::columnCount() const
-{
- return d_func()->ncols;
-}
-
-/*!
- Returns the item at \a pt; returns 0 if there is no item there.
-*/
-QAction *QMenu::actionAt(const QPoint &pt) const
-{
- if (QAction *ret = d_func()->actionAt(pt))
- return ret;
- return 0;
-}
-
-/*!
- Returns the geometry of action \a act.
-*/
-QRect QMenu::actionGeometry(QAction *act) const
-{
- return d_func()->actionRect(act);
-}
-
-/*!
- \reimp
-*/
-QSize QMenu::sizeHint() const
-{
- Q_D(const QMenu);
- d->updateActionRects();
-
- QSize s;
- for (int i = 0; i < d->actionRects.count(); ++i) {
- const QRect &rect = d->actionRects.at(i);
- if (rect.isNull())
- continue;
- if (rect.bottom() >= s.height())
- s.setHeight(rect.y() + rect.height());
- if (rect.right() >= s.width())
- s.setWidth(rect.x() + rect.width());
- }
- // Note that the action rects calculated above already include
- // the top and left margins, so we only need to add margins for
- // the bottom and right.
- QStyleOption opt(0);
- opt.init(this);
- const int fw = style()->pixelMetric(QStyle::PM_MenuPanelWidth, &opt, this);
- s.rwidth() += style()->pixelMetric(QStyle::PM_MenuHMargin, &opt, this) + fw + d->rightmargin;
- s.rheight() += style()->pixelMetric(QStyle::PM_MenuVMargin, &opt, this) + fw + d->bottommargin;
-
- return style()->sizeFromContents(QStyle::CT_Menu, &opt,
- s.expandedTo(QApplication::globalStrut()), this);
-}
-
-/*!
- Displays the menu so that the action \a atAction will be at the
- specified \e global position \a p. To translate a widget's local
- coordinates into global coordinates, use QWidget::mapToGlobal().
-
- When positioning a menu with exec() or popup(), bear in mind that
- you cannot rely on the menu's current size(). For performance
- reasons, the menu adapts its size only when necessary, so in many
- cases, the size before and after the show is different. Instead,
- use sizeHint() which calculates the proper size depending on the
- menu's current contents.
-
- \sa QWidget::mapToGlobal(), exec()
-*/
-void QMenu::popup(const QPoint &p, QAction *atAction)
-{
- Q_D(QMenu);
-#ifndef Q_OS_SYMBIAN
- if (d->scroll) { // reset scroll state from last popup
- d->scroll->scrollOffset = 0;
- d->scroll->scrollFlags = QMenuPrivate::QMenuScroller::ScrollNone;
- }
-#endif
- d->tearoffHighlighted = 0;
- d->motions = 0;
- d->doChildEffects = true;
- d->updateLayoutDirection();
-
-#ifndef QT_NO_MENUBAR
- // if this menu is part of a chain attached to a QMenuBar, set the
- // _NET_WM_WINDOW_TYPE_DROPDOWN_MENU X11 window type
- setAttribute(Qt::WA_X11NetWmWindowTypeDropDownMenu, qobject_cast<QMenuBar *>(d->topCausedWidget()) != 0);
-#endif
-
- ensurePolished(); // Get the right font
- emit aboutToShow();
- const bool actionListChanged = d->itemsDirty;
- d->updateActionRects();
- QPoint pos;
- QPushButton *causedButton = qobject_cast<QPushButton*>(d->causedPopup.widget);
- if (actionListChanged && causedButton)
- pos = QPushButtonPrivate::get(causedButton)->adjustedMenuPosition();
- else
- pos = p;
-
- QSize size = sizeHint();
- QRect screen;
-#ifndef QT_NO_GRAPHICSVIEW
- bool isEmbedded = !bypassGraphicsProxyWidget(this) && d->nearestGraphicsProxyWidget(this);
- if (isEmbedded)
- screen = d->popupGeometry(this);
- else
-#endif
- screen = d->popupGeometry(QApplication::desktop()->screenNumber(p));
- const int desktopFrame = style()->pixelMetric(QStyle::PM_MenuDesktopFrameWidth, 0, this);
- bool adjustToDesktop = !window()->testAttribute(Qt::WA_DontShowOnScreen);
-
- // if the screens have very different geometries and the menu is too big, we have to recalculate
- if (size.height() > screen.height() || size.width() > screen.width()) {
- size = d->adjustMenuSizeForScreen(screen);
- adjustToDesktop = true;
- }
- // Layout is not right, we might be able to save horizontal space
- if (d->ncols >1 && size.height() < screen.height()) {
- size = d->adjustMenuSizeForScreen(screen);
- adjustToDesktop = true;
- }
-
-#ifdef QT_KEYPAD_NAVIGATION
- if (!atAction && QApplication::keypadNavigationEnabled()) {
- // Try to have one item activated
- if (d->defaultAction && d->defaultAction->isEnabled()) {
- atAction = d->defaultAction;
- // TODO: This works for first level menus, not yet sub menus
- } else {
- foreach (QAction *action, d->actions)
- if (action->isEnabled()) {
- atAction = action;
- break;
- }
- }
- d->currentAction = atAction;
- }
-#endif
- if (d->ncols > 1) {
- pos.setY(screen.top() + desktopFrame);
- } else if (atAction) {
- for (int i = 0, above_height = 0; i < d->actions.count(); i++) {
- QAction *action = d->actions.at(i);
- if (action == atAction) {
- int newY = pos.y() - above_height;
- if (d->scroll && newY < desktopFrame) {
- d->scroll->scrollFlags = d->scroll->scrollFlags
- | QMenuPrivate::QMenuScroller::ScrollUp;
- d->scroll->scrollOffset = newY;
- newY = desktopFrame;
- }
- pos.setY(newY);
-
- if (d->scroll && d->scroll->scrollFlags != QMenuPrivate::QMenuScroller::ScrollNone
- && !style()->styleHint(QStyle::SH_Menu_FillScreenWithScroll, 0, this)) {
- int below_height = above_height + d->scroll->scrollOffset;
- for (int i2 = i; i2 < d->actionRects.count(); i2++)
- below_height += d->actionRects.at(i2).height();
- size.setHeight(below_height);
- }
- break;
- } else {
- above_height += d->actionRects.at(i).height();
- }
- }
- }
-
- QPoint mouse = QCursor::pos();
- d->mousePopupPos = mouse;
- const bool snapToMouse = (QRect(p.x() - 3, p.y() - 3, 6, 6).contains(mouse));
-
- if (adjustToDesktop) {
- // handle popup falling "off screen"
- if (isRightToLeft()) {
- if (snapToMouse) // position flowing left from the mouse
- pos.setX(mouse.x() - size.width());
-
-#ifndef QT_NO_MENUBAR
- // if in a menubar, it should be right-aligned
- if (qobject_cast<QMenuBar*>(d->causedPopup.widget))
- pos.rx() -= size.width();
-#endif //QT_NO_MENUBAR
-
- if (pos.x() < screen.left() + desktopFrame)
- pos.setX(qMax(p.x(), screen.left() + desktopFrame));
- if (pos.x() + size.width() - 1 > screen.right() - desktopFrame)
- pos.setX(qMax(p.x() - size.width(), screen.right() - desktopFrame - size.width() + 1));
- } else {
- if (pos.x() + size.width() - 1 > screen.right() - desktopFrame)
- pos.setX(screen.right() - desktopFrame - size.width() + 1);
- if (pos.x() < screen.left() + desktopFrame)
- pos.setX(screen.left() + desktopFrame);
- }
- if (pos.y() + size.height() - 1 > screen.bottom() - desktopFrame) {
- if(snapToMouse)
- pos.setY(qMin(mouse.y() - (size.height() + desktopFrame), screen.bottom()-desktopFrame-size.height()+1));
- else
- pos.setY(qMax(p.y() - (size.height() + desktopFrame), screen.bottom()-desktopFrame-size.height()+1));
- } else if (pos.y() < screen.top() + desktopFrame) {
- pos.setY(screen.top() + desktopFrame);
- }
-
- if (pos.y() < screen.top() + desktopFrame)
- pos.setY(screen.top() + desktopFrame);
- if (pos.y() + size.height() - 1 > screen.bottom() - desktopFrame) {
- if (d->scroll) {
- d->scroll->scrollFlags |= uint(QMenuPrivate::QMenuScroller::ScrollDown);
- int y = qMax(screen.y(),pos.y());
- size.setHeight(screen.bottom() - (desktopFrame * 2) - y);
- } else {
- // Too big for screen, bias to see bottom of menu (for some reason)
- pos.setY(screen.bottom() - size.height() + 1);
- }
- }
- }
- const int subMenuOffset = style()->pixelMetric(QStyle::PM_SubMenuOverlap, 0, this);
- const QSize menuSize(sizeHint());
- QMenu *caused = qobject_cast<QMenu*>(d_func()->causedPopup.widget);
- if (caused && caused->geometry().width() + menuSize.width() + subMenuOffset < screen.width()) {
- QRect parentActionRect(caused->d_func()->actionRect(caused->d_func()->currentAction));
- const QPoint actionTopLeft = caused->mapToGlobal(parentActionRect.topLeft());
- parentActionRect.moveTopLeft(actionTopLeft);
- if (isRightToLeft()) {
- if ((pos.x() + menuSize.width() > parentActionRect.left() - subMenuOffset)
- && (pos.x() < parentActionRect.right()))
- {
- pos.rx() = parentActionRect.right();
- }
- } else {
- if ((pos.x() < parentActionRect.right() + subMenuOffset)
- && (pos.x() + menuSize.width() > parentActionRect.left()))
- {
- pos.rx() = parentActionRect.left() - menuSize.width();
- }
- }
- }
- setGeometry(QRect(pos, size));
-#ifndef QT_NO_EFFECTS
- int hGuess = isRightToLeft() ? QEffects::LeftScroll : QEffects::RightScroll;
- int vGuess = QEffects::DownScroll;
- if (isRightToLeft()) {
- if ((snapToMouse && (pos.x() + size.width() / 2 > mouse.x())) ||
- (qobject_cast<QMenu*>(d->causedPopup.widget) && pos.x() + size.width() / 2 > d->causedPopup.widget->x()))
- hGuess = QEffects::RightScroll;
- } else {
- if ((snapToMouse && (pos.x() + size.width() / 2 < mouse.x())) ||
- (qobject_cast<QMenu*>(d->causedPopup.widget) && pos.x() + size.width() / 2 < d->causedPopup.widget->x()))
- hGuess = QEffects::LeftScroll;
- }
-
-#ifndef QT_NO_MENUBAR
- if ((snapToMouse && (pos.y() + size.height() / 2 < mouse.y())) ||
- (qobject_cast<QMenuBar*>(d->causedPopup.widget) &&
- pos.y() + size.width() / 2 < d->causedPopup.widget->mapToGlobal(d->causedPopup.widget->pos()).y()))
- vGuess = QEffects::UpScroll;
-#endif
- if (QApplication::isEffectEnabled(Qt::UI_AnimateMenu)) {
- bool doChildEffects = true;
-#ifndef QT_NO_MENUBAR
- if (QMenuBar *mb = qobject_cast<QMenuBar*>(d->causedPopup.widget)) {
- doChildEffects = mb->d_func()->doChildEffects;
- mb->d_func()->doChildEffects = false;
- } else
-#endif
- if (QMenu *m = qobject_cast<QMenu*>(d->causedPopup.widget)) {
- doChildEffects = m->d_func()->doChildEffects;
- m->d_func()->doChildEffects = false;
- }
-
- if (doChildEffects) {
- if (QApplication::isEffectEnabled(Qt::UI_FadeMenu))
- qFadeEffect(this);
- else if (d->causedPopup.widget)
- qScrollEffect(this, qobject_cast<QMenu*>(d->causedPopup.widget) ? hGuess : vGuess);
- else
- qScrollEffect(this, hGuess | vGuess);
- } else {
- // kill any running effect
- qFadeEffect(0);
- qScrollEffect(0);
-
- show();
- }
- } else
-#endif
- {
- show();
- }
-
-#ifndef QT_NO_ACCESSIBILITY
- QAccessible::updateAccessibility(this, 0, QAccessible::PopupMenuStart);
-#endif
-}
-
-/*!
- Executes this menu synchronously.
-
- This is equivalent to \c{exec(pos())}.
-
- This returns the triggered QAction in either the popup menu or one
- of its submenus, or 0 if no item was triggered (normally because
- the user pressed Esc).
-
- In most situations you'll want to specify the position yourself,
- for example, the current mouse position:
- \snippet doc/src/snippets/code/src_gui_widgets_qmenu.cpp 0
- or aligned to a widget:
- \snippet doc/src/snippets/code/src_gui_widgets_qmenu.cpp 1
- or in reaction to a QMouseEvent *e:
- \snippet doc/src/snippets/code/src_gui_widgets_qmenu.cpp 2
-*/
-QAction *QMenu::exec()
-{
- return exec(pos());
-}
-
-
-/*!
- \overload
-
- Executes this menu synchronously.
-
- Pops up the menu so that the action \a action will be at the
- specified \e global position \a p. To translate a widget's local
- coordinates into global coordinates, use QWidget::mapToGlobal().
-
- This returns the triggered QAction in either the popup menu or one
- of its submenus, or 0 if no item was triggered (normally because
- the user pressed Esc).
-
- Note that all signals are emitted as usual. If you connect a
- QAction to a slot and call the menu's exec(), you get the result
- both via the signal-slot connection and in the return value of
- exec().
-
- Common usage is to position the menu at the current mouse
- position:
- \snippet doc/src/snippets/code/src_gui_widgets_qmenu.cpp 3
- or aligned to a widget:
- \snippet doc/src/snippets/code/src_gui_widgets_qmenu.cpp 4
- or in reaction to a QMouseEvent *e:
- \snippet doc/src/snippets/code/src_gui_widgets_qmenu.cpp 5
-
- When positioning a menu with exec() or popup(), bear in mind that
- you cannot rely on the menu's current size(). For performance
- reasons, the menu adapts its size only when necessary. So in many
- cases, the size before and after the show is different. Instead,
- use sizeHint() which calculates the proper size depending on the
- menu's current contents.
-
- \sa popup(), QWidget::mapToGlobal()
-*/
-QAction *QMenu::exec(const QPoint &p, QAction *action)
-{
- Q_D(QMenu);
- createWinId();
- QEventLoop eventLoop;
- d->eventLoop = &eventLoop;
- popup(p, action);
-
- QPointer<QObject> guard = this;
- (void) eventLoop.exec();
- if (guard.isNull())
- return 0;
-
- action = d->syncAction;
- d->syncAction = 0;
- d->eventLoop = 0;
- return action;
-}
-
-/*!
- \overload
-
- Executes a menu synchronously.
-
- The menu's actions are specified by the list of \a actions. The menu will
- pop up so that the specified action, \a at, appears at global position \a
- pos. If \a at is not specified then the menu appears at position \a
- pos. \a parent is the menu's parent widget; specifying the parent will
- provide context when \a pos alone is not enough to decide where the menu
- should go (e.g., with multiple desktops or when the parent is embedded in
- QGraphicsView).
-
- The function returns the triggered QAction in either the popup
- menu or one of its submenus, or 0 if no item was triggered
- (normally because the user pressed Esc).
-
- This is equivalent to:
- \snippet doc/src/snippets/code/src_gui_widgets_qmenu.cpp 6
-
- \sa popup(), QWidget::mapToGlobal()
-*/
-QAction *QMenu::exec(QList<QAction*> actions, const QPoint &pos, QAction *at, QWidget *parent)
-{
- QMenu menu(parent);
- menu.addActions(actions);
- return menu.exec(pos, at);
-}
-
-/*!
- \overload
-
- Executes a menu synchronously.
-
- The menu's actions are specified by the list of \a actions. The menu
- will pop up so that the specified action, \a at, appears at global
- position \a pos. If \a at is not specified then the menu appears
- at position \a pos.
-
- The function returns the triggered QAction in either the popup
- menu or one of its submenus, or 0 if no item was triggered
- (normally because the user pressed Esc).
-
- This is equivalent to:
- \snippet doc/src/snippets/code/src_gui_widgets_qmenu.cpp 6
-
- \sa popup(), QWidget::mapToGlobal()
-*/
-QAction *QMenu::exec(QList<QAction*> actions, const QPoint &pos, QAction *at)
-{
- // ### Qt 5: merge
- return exec(actions, pos, at, 0);
-}
-
-/*!
- \reimp
-*/
-void QMenu::hideEvent(QHideEvent *)
-{
- Q_D(QMenu);
- emit aboutToHide();
- if (d->eventLoop)
- d->eventLoop->exit();
- d->setCurrentAction(0);
-#ifndef QT_NO_ACCESSIBILITY
- QAccessible::updateAccessibility(this, 0, QAccessible::PopupMenuEnd);
-#endif
-#ifndef QT_NO_MENUBAR
- if (QMenuBar *mb = qobject_cast<QMenuBar*>(d->causedPopup.widget))
- mb->d_func()->setCurrentAction(0);
-#endif
- d->mouseDown = 0;
- d->hasHadMouse = false;
- d->causedPopup.widget = 0;
- d->causedPopup.action = 0;
- if (d->scroll)
- d->scroll->scrollTimer.stop(); //make sure the timer stops
-}
-
-/*!
- \reimp
-*/
-void QMenu::paintEvent(QPaintEvent *e)
-{
- Q_D(QMenu);
- d->updateActionRects();
- QPainter p(this);
- QRegion emptyArea = QRegion(rect());
-
- QStyleOptionMenuItem menuOpt;
- menuOpt.initFrom(this);
- menuOpt.state = QStyle::State_None;
- menuOpt.checkType = QStyleOptionMenuItem::NotCheckable;
- menuOpt.maxIconWidth = 0;
- menuOpt.tabWidth = 0;
- style()->drawPrimitive(QStyle::PE_PanelMenu, &menuOpt, &p, this);
-
- //draw the items that need updating..
- for (int i = 0; i < d->actions.count(); ++i) {
- QAction *action = d->actions.at(i);
- QRect adjustedActionRect = d->actionRects.at(i);
- if (!e->rect().intersects(adjustedActionRect)
- || d->widgetItems.value(action))
- continue;
- //set the clip region to be extra safe (and adjust for the scrollers)
- QRegion adjustedActionReg(adjustedActionRect);
- emptyArea -= adjustedActionReg;
- p.setClipRegion(adjustedActionReg);
-
- QStyleOptionMenuItem opt;
- initStyleOption(&opt, action);
- opt.rect = adjustedActionRect;
- style()->drawControl(QStyle::CE_MenuItem, &opt, &p, this);
- }
-
- const int fw = style()->pixelMetric(QStyle::PM_MenuPanelWidth, 0, this);
- //draw the scroller regions..
- if (d->scroll) {
- menuOpt.menuItemType = QStyleOptionMenuItem::Scroller;
- menuOpt.state |= QStyle::State_Enabled;
- if (d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp) {
- menuOpt.rect.setRect(fw, fw, width() - (fw * 2), d->scrollerHeight());
- emptyArea -= QRegion(menuOpt.rect);
- p.setClipRect(menuOpt.rect);
- style()->drawControl(QStyle::CE_MenuScroller, &menuOpt, &p, this);
- }
- if (d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollDown) {
- menuOpt.rect.setRect(fw, height() - d->scrollerHeight() - fw, width() - (fw * 2),
- d->scrollerHeight());
- emptyArea -= QRegion(menuOpt.rect);
- menuOpt.state |= QStyle::State_DownArrow;
- p.setClipRect(menuOpt.rect);
- style()->drawControl(QStyle::CE_MenuScroller, &menuOpt, &p, this);
- }
- }
- //paint the tear off..
- if (d->tearoff) {
- menuOpt.menuItemType = QStyleOptionMenuItem::TearOff;
- menuOpt.rect.setRect(fw, fw, width() - (fw * 2),
- style()->pixelMetric(QStyle::PM_MenuTearoffHeight, 0, this));
- if (d->scroll && d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp)
- menuOpt.rect.translate(0, d->scrollerHeight());
- emptyArea -= QRegion(menuOpt.rect);
- p.setClipRect(menuOpt.rect);
- menuOpt.state = QStyle::State_None;
- if (d->tearoffHighlighted)
- menuOpt.state |= QStyle::State_Selected;
- style()->drawControl(QStyle::CE_MenuTearoff, &menuOpt, &p, this);
- }
- //draw border
- if (fw) {
- QRegion borderReg;
- borderReg += QRect(0, 0, fw, height()); //left
- borderReg += QRect(width()-fw, 0, fw, height()); //right
- borderReg += QRect(0, 0, width(), fw); //top
- borderReg += QRect(0, height()-fw, width(), fw); //bottom
- p.setClipRegion(borderReg);
- emptyArea -= borderReg;
- QStyleOptionFrame frame;
- frame.rect = rect();
- frame.palette = palette();
- frame.state = QStyle::State_None;
- frame.lineWidth = style()->pixelMetric(QStyle::PM_MenuPanelWidth);
- frame.midLineWidth = 0;
- style()->drawPrimitive(QStyle::PE_FrameMenu, &frame, &p, this);
- }
-
- //finally the rest of the space
- p.setClipRegion(emptyArea);
- menuOpt.state = QStyle::State_None;
- menuOpt.menuItemType = QStyleOptionMenuItem::EmptyArea;
- menuOpt.checkType = QStyleOptionMenuItem::NotCheckable;
- menuOpt.rect = rect();
- menuOpt.menuRect = rect();
- style()->drawControl(QStyle::CE_MenuEmptyArea, &menuOpt, &p, this);
-}
-
-#ifndef QT_NO_WHEELEVENT
-/*!
- \reimp
-*/
-void QMenu::wheelEvent(QWheelEvent *e)
-{
- Q_D(QMenu);
- if (d->scroll && rect().contains(e->pos()))
- d->scrollMenu(e->delta() > 0 ?
- QMenuPrivate::QMenuScroller::ScrollUp : QMenuPrivate::QMenuScroller::ScrollDown);
-}
-#endif
-
-/*!
- \reimp
-*/
-void QMenu::mousePressEvent(QMouseEvent *e)
-{
- Q_D(QMenu);
- if (d->aboutToHide || d->mouseEventTaken(e))
- return;
- if (!rect().contains(e->pos())) {
- if (d->noReplayFor
- && QRect(d->noReplayFor->mapToGlobal(QPoint()), d->noReplayFor->size()).contains(e->globalPos()))
- setAttribute(Qt::WA_NoMouseReplay);
- if (d->eventLoop) // synchronous operation
- d->syncAction = 0;
- d->hideUpToMenuBar();
- return;
- }
- d->mouseDown = this;
-
- QAction *action = d->actionAt(e->pos());
- d->setCurrentAction(action, 20);
- update();
-}
-
-/*!
- \reimp
-*/
-void QMenu::mouseReleaseEvent(QMouseEvent *e)
-{
- Q_D(QMenu);
- if (d->aboutToHide || d->mouseEventTaken(e))
- return;
- if(d->mouseDown != this) {
- d->mouseDown = 0;
- return;
- }
-
- d->mouseDown = 0;
- d->setSyncAction();
- QAction *action = d->actionAt(e->pos());
-
- if (action && action == d->currentAction) {
- if (!action->menu()){
-#if defined(Q_WS_WIN)
- //On Windows only context menus can be activated with the right button
- if (e->button() == Qt::LeftButton || d->topCausedWidget() == 0)
-#endif
- d->activateAction(action, QAction::Trigger);
- }
- } else if (d->hasMouseMoved(e->globalPos())) {
- d->hideUpToMenuBar();
- }
-}
-
-/*!
- \reimp
-*/
-void QMenu::changeEvent(QEvent *e)
-{
- Q_D(QMenu);
- if (e->type() == QEvent::StyleChange || e->type() == QEvent::FontChange ||
- e->type() == QEvent::LayoutDirectionChange) {
- d->itemsDirty = 1;
- setMouseTracking(style()->styleHint(QStyle::SH_Menu_MouseTracking, 0, this));
- if (isVisible())
- resize(sizeHint());
- if (!style()->styleHint(QStyle::SH_Menu_Scrollable, 0, this)) {
- delete d->scroll;
- d->scroll = 0;
- } else if (!d->scroll) {
- d->scroll = new QMenuPrivate::QMenuScroller;
- d->scroll->scrollFlags = QMenuPrivate::QMenuScroller::ScrollNone;
- }
- } else if (e->type() == QEvent::EnabledChange) {
- if (d->tornPopup) // torn-off menu
- d->tornPopup->setEnabled(isEnabled());
- d->menuAction->setEnabled(isEnabled());
-#ifdef Q_WS_MAC
- if (d->mac_menu)
- d->setMacMenuEnabled(isEnabled());
-#endif
- }
- QWidget::changeEvent(e);
-}
-
-
-/*!
- \reimp
-*/
-bool
-QMenu::event(QEvent *e)
-{
- Q_D(QMenu);
- switch (e->type()) {
- case QEvent::Polish:
- d->updateLayoutDirection();
- break;
- case QEvent::ShortcutOverride: {
- QKeyEvent *kev = static_cast<QKeyEvent*>(e);
- if (kev->key() == Qt::Key_Up || kev->key() == Qt::Key_Down
- || kev->key() == Qt::Key_Left || kev->key() == Qt::Key_Right
- || kev->key() == Qt::Key_Enter || kev->key() == Qt::Key_Return
- || kev->key() == Qt::Key_Escape) {
- e->accept();
- return true;
- }
- }
- break;
- case QEvent::KeyPress: {
- QKeyEvent *ke = (QKeyEvent*)e;
- if (ke->key() == Qt::Key_Tab || ke->key() == Qt::Key_Backtab) {
- keyPressEvent(ke);
- return true;
- }
- } break;
- case QEvent::ContextMenu:
- if(d->menuDelayTimer.isActive()) {
- d->menuDelayTimer.stop();
- internalDelayedPopup();
- }
- break;
- case QEvent::Resize: {
- QStyleHintReturnMask menuMask;
- QStyleOption option;
- option.initFrom(this);
- if (style()->styleHint(QStyle::SH_Menu_Mask, &option, this, &menuMask)) {
- setMask(menuMask.region);
- }
- d->itemsDirty = 1;
- d->updateActionRects();
- break; }
- case QEvent::Show:
- d->mouseDown = 0;
- d->updateActionRects();
- if (d->currentAction)
- d->popupAction(d->currentAction, 0, false);
- break;
-#ifndef QT_NO_WHATSTHIS
- case QEvent::QueryWhatsThis:
- e->setAccepted(d->whatsThis.size());
- if (QAction *action = d->actionAt(static_cast<QHelpEvent*>(e)->pos())) {
- if (action->whatsThis().size() || action->menu())
- e->accept();
- }
- return true;
-#endif
-#ifdef QT_SOFTKEYS_ENABLED
- case QEvent::LanguageChange: {
- d->selectAction->setText(QSoftKeyManager::standardSoftKeyText(QSoftKeyManager::SelectSoftKey));
- d->cancelAction->setText(QSoftKeyManager::standardSoftKeyText(QSoftKeyManager::CancelSoftKey));
- }
- break;
-#endif
- default:
- break;
- }
- return QWidget::event(e);
-}
-
-/*!
- \reimp
-*/
-bool QMenu::focusNextPrevChild(bool next)
-{
- setFocus();
- QKeyEvent ev(QEvent::KeyPress, next ? Qt::Key_Tab : Qt::Key_Backtab, Qt::NoModifier);
- keyPressEvent(&ev);
- return true;
-}
-
-/*!
- \reimp
-*/
-void QMenu::keyPressEvent(QKeyEvent *e)
-{
- Q_D(QMenu);
- d->updateActionRects();
- int key = e->key();
- if (isRightToLeft()) { // in reverse mode open/close key for submenues are reversed
- if (key == Qt::Key_Left)
- key = Qt::Key_Right;
- else if (key == Qt::Key_Right)
- key = Qt::Key_Left;
- }
-#ifndef Q_WS_MAC
- if (key == Qt::Key_Tab) //means down
- key = Qt::Key_Down;
- if (key == Qt::Key_Backtab) //means up
- key = Qt::Key_Up;
-#endif
-
- bool key_consumed = false;
- switch(key) {
- case Qt::Key_Home:
- key_consumed = true;
- if (d->scroll)
- d->scrollMenu(QMenuPrivate::QMenuScroller::ScrollTop, true);
- break;
- case Qt::Key_End:
- key_consumed = true;
- if (d->scroll)
- d->scrollMenu(QMenuPrivate::QMenuScroller::ScrollBottom, true);
- break;
- case Qt::Key_PageUp:
- key_consumed = true;
- if (d->currentAction && d->scroll) {
- if(d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp)
- d->scrollMenu(QMenuPrivate::QMenuScroller::ScrollUp, true, true);
- else
- d->scrollMenu(QMenuPrivate::QMenuScroller::ScrollTop, true);
- }
- break;
- case Qt::Key_PageDown:
- key_consumed = true;
- if (d->currentAction && d->scroll) {
- if(d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollDown)
- d->scrollMenu(QMenuPrivate::QMenuScroller::ScrollDown, true, true);
- else
- d->scrollMenu(QMenuPrivate::QMenuScroller::ScrollBottom, true);
- }
- break;
- case Qt::Key_Up:
- case Qt::Key_Down: {
- key_consumed = true;
- QAction *nextAction = 0;
- QMenuPrivate::QMenuScroller::ScrollLocation scroll_loc = QMenuPrivate::QMenuScroller::ScrollStay;
- if (!d->currentAction) {
- if(key == Qt::Key_Down) {
- for(int i = 0; i < d->actions.count(); ++i) {
- QAction *act = d->actions.at(i);
- if (d->actionRects.at(i).isNull())
- continue;
- if (!act->isSeparator() &&
- (style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, this)
- || act->isEnabled())) {
- nextAction = act;
- break;
- }
- }
- } else {
- for(int i = d->actions.count()-1; i >= 0; --i) {
- QAction *act = d->actions.at(i);
- if (d->actionRects.at(i).isNull())
- continue;
- if (!act->isSeparator() &&
- (style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, this)
- || act->isEnabled())) {
- nextAction = act;
- break;
- }
- }
- }
- } else {
- for(int i = 0, y = 0; !nextAction && i < d->actions.count(); i++) {
- QAction *act = d->actions.at(i);
- if (act == d->currentAction) {
- if (key == Qt::Key_Up) {
- for(int next_i = i-1; true; next_i--) {
- if (next_i == -1) {
- if(!style()->styleHint(QStyle::SH_Menu_SelectionWrap, 0, this))
- break;
- if (d->scroll)
- scroll_loc = QMenuPrivate::QMenuScroller::ScrollBottom;
- next_i = d->actionRects.count()-1;
- }
- QAction *next = d->actions.at(next_i);
- if (next == d->currentAction)
- break;
- if (d->actionRects.at(next_i).isNull())
- continue;
- if (next->isSeparator() ||
- (!next->isEnabled() &&
- !style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, this)))
- continue;
- nextAction = next;
- if (d->scroll && (d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp)) {
- int topVisible = d->scrollerHeight();
- if (d->tearoff)
- topVisible += style()->pixelMetric(QStyle::PM_MenuTearoffHeight, 0, this);
- if (((y + d->scroll->scrollOffset) - topVisible) <= d->actionRects.at(next_i).height())
- scroll_loc = QMenuPrivate::QMenuScroller::ScrollTop;
- }
- break;
- }
- if (!nextAction && d->tearoff)
- d->tearoffHighlighted = 1;
- } else {
- y += d->actionRects.at(i).height();
- for(int next_i = i+1; true; next_i++) {
- if (next_i == d->actionRects.count()) {
- if(!style()->styleHint(QStyle::SH_Menu_SelectionWrap, 0, this))
- break;
- if (d->scroll)
- scroll_loc = QMenuPrivate::QMenuScroller::ScrollTop;
- next_i = 0;
- }
- QAction *next = d->actions.at(next_i);
- if (next == d->currentAction)
- break;
- if (d->actionRects.at(next_i).isNull())
- continue;
- if (next->isSeparator() ||
- (!next->isEnabled() &&
- !style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, this)))
- continue;
- nextAction = next;
- if (d->scroll && (d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollDown)) {
- int bottomVisible = height() - d->scrollerHeight();
- if (d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp)
- bottomVisible -= d->scrollerHeight();
- if (d->tearoff)
- bottomVisible -= style()->pixelMetric(QStyle::PM_MenuTearoffHeight, 0, this);
- if ((y + d->scroll->scrollOffset + d->actionRects.at(next_i).height()) > bottomVisible)
- scroll_loc = QMenuPrivate::QMenuScroller::ScrollBottom;
- }
- break;
- }
- }
- break;
- }
- y += d->actionRects.at(i).height();
- }
- }
- if (nextAction) {
- if (d->scroll && scroll_loc != QMenuPrivate::QMenuScroller::ScrollStay) {
- d->scroll->scrollTimer.stop();
- d->scrollMenu(nextAction, scroll_loc);
- }
- d->setCurrentAction(nextAction, /*popup*/-1, QMenuPrivate::SelectedFromKeyboard);
- }
- break; }
-
- case Qt::Key_Right:
- if (d->currentAction && d->currentAction->isEnabled() && d->currentAction->menu()) {
- d->popupAction(d->currentAction, 0, true);
- key_consumed = true;
- break;
- }
- //FALL THROUGH
- case Qt::Key_Left: {
- if (d->currentAction && !d->scroll) {
- QAction *nextAction = 0;
- if (key == Qt::Key_Left) {
- QRect actionR = d->actionRect(d->currentAction);
- for(int x = actionR.left()-1; !nextAction && x >= 0; x--)
- nextAction = d->actionAt(QPoint(x, actionR.center().y()));
- } else {
- QRect actionR = d->actionRect(d->currentAction);
- for(int x = actionR.right()+1; !nextAction && x < width(); x++)
- nextAction = d->actionAt(QPoint(x, actionR.center().y()));
- }
- if (nextAction) {
- d->setCurrentAction(nextAction, /*popup*/-1, QMenuPrivate::SelectedFromKeyboard);
- key_consumed = true;
- }
- }
- if (!key_consumed && key == Qt::Key_Left && qobject_cast<QMenu*>(d->causedPopup.widget)) {
- QPointer<QWidget> caused = d->causedPopup.widget;
- d->hideMenu(this);
- if (caused)
- caused->setFocus();
- key_consumed = true;
- }
- break; }
-
- case Qt::Key_Alt:
- if (d->tornoff)
- break;
-
- key_consumed = true;
- if (style()->styleHint(QStyle::SH_MenuBar_AltKeyNavigation, 0, this))
- {
- d->hideMenu(this);
-#ifndef QT_NO_MENUBAR
- if (QMenuBar *mb = qobject_cast<QMenuBar*>(QApplication::focusWidget())) {
- mb->d_func()->setKeyboardMode(false);
- }
-#endif
- }
- break;
-
- case Qt::Key_Escape:
-#ifdef QT_KEYPAD_NAVIGATION
- case Qt::Key_Back:
-#endif
- key_consumed = true;
- if (d->tornoff) {
- close();
- return;
- }
- {
- QPointer<QWidget> caused = d->causedPopup.widget;
- d->hideMenu(this); // hide after getting causedPopup
-#ifndef QT_NO_MENUBAR
- if (QMenuBar *mb = qobject_cast<QMenuBar*>(caused)) {
- mb->d_func()->setCurrentAction(d->menuAction);
- mb->d_func()->setKeyboardMode(true);
- }
-#endif
- }
- break;
-
- case Qt::Key_Space:
- if (!style()->styleHint(QStyle::SH_Menu_SpaceActivatesItem, 0, this))
- break;
- // for motif, fall through
-#ifdef QT_KEYPAD_NAVIGATION
- case Qt::Key_Select:
-#endif
- case Qt::Key_Return:
- case Qt::Key_Enter: {
- if (!d->currentAction) {
- d->setFirstActionActive();
- key_consumed = true;
- break;
- }
-
- d->setSyncAction();
-
- if (d->currentAction->menu())
- d->popupAction(d->currentAction, 0, true);
- else
- d->activateAction(d->currentAction, QAction::Trigger);
- key_consumed = true;
- break; }
-
-#ifndef QT_NO_WHATSTHIS
- case Qt::Key_F1:
- if (!d->currentAction || d->currentAction->whatsThis().isNull())
- break;
- QWhatsThis::enterWhatsThisMode();
- d->activateAction(d->currentAction, QAction::Trigger);
- return;
-#endif
- default:
- key_consumed = false;
- }
-
- if (!key_consumed) { // send to menu bar
- if ((!e->modifiers() || e->modifiers() == Qt::AltModifier || e->modifiers() == Qt::ShiftModifier) &&
- e->text().length()==1) {
- bool activateAction = false;
- QAction *nextAction = 0;
- if (style()->styleHint(QStyle::SH_Menu_KeyboardSearch, 0, this) && !e->modifiers()) {
- int best_match_count = 0;
- d->searchBufferTimer.start(2000, this);
- d->searchBuffer += e->text();
- for(int i = 0; i < d->actions.size(); ++i) {
- int match_count = 0;
- if (d->actionRects.at(i).isNull())
- continue;
- QAction *act = d->actions.at(i);
- const QString act_text = act->text();
- for(int c = 0; c < d->searchBuffer.size(); ++c) {
- if(act_text.indexOf(d->searchBuffer.at(c), 0, Qt::CaseInsensitive) != -1)
- ++match_count;
- }
- if(match_count > best_match_count) {
- best_match_count = match_count;
- nextAction = act;
- }
- }
- }
-#ifndef QT_NO_SHORTCUT
- else {
- int clashCount = 0;
- QAction *first = 0, *currentSelected = 0, *firstAfterCurrent = 0;
- QChar c = e->text().at(0).toUpper();
- for(int i = 0; i < d->actions.size(); ++i) {
- if (d->actionRects.at(i).isNull())
- continue;
- QAction *act = d->actions.at(i);
- QKeySequence sequence = QKeySequence::mnemonic(act->text());
- int key = sequence[0] & 0xffff;
- if (key == c.unicode()) {
- clashCount++;
- if (!first)
- first = act;
- if (act == d->currentAction)
- currentSelected = act;
- else if (!firstAfterCurrent && currentSelected)
- firstAfterCurrent = act;
- }
- }
- if (clashCount == 1)
- activateAction = true;
- if (clashCount >= 1) {
- if (clashCount == 1 || !currentSelected || !firstAfterCurrent)
- nextAction = first;
- else
- nextAction = firstAfterCurrent;
- }
- }
-#endif
- if (nextAction) {
- key_consumed = true;
- if(d->scroll)
- d->scrollMenu(nextAction, QMenuPrivate::QMenuScroller::ScrollCenter, false);
- d->setCurrentAction(nextAction, 20, QMenuPrivate::SelectedFromElsewhere, true);
- if (!nextAction->menu() && activateAction) {
- d->setSyncAction();
- d->activateAction(nextAction, QAction::Trigger);
- }
- }
- }
- if (!key_consumed) {
-#ifndef QT_NO_MENUBAR
- if (QMenuBar *mb = qobject_cast<QMenuBar*>(d->topCausedWidget())) {
- QAction *oldAct = mb->d_func()->currentAction;
- QApplication::sendEvent(mb, e);
- if (mb->d_func()->currentAction != oldAct)
- key_consumed = true;
- }
-#endif
- }
-
-#ifdef Q_OS_WIN32
- if (key_consumed && (e->key() == Qt::Key_Control || e->key() == Qt::Key_Shift || e->key() == Qt::Key_Meta))
- QApplication::beep();
-#endif // Q_OS_WIN32
- }
- if (key_consumed)
- e->accept();
- else
- e->ignore();
-}
-
-/*!
- \reimp
-*/
-void QMenu::mouseMoveEvent(QMouseEvent *e)
-{
- Q_D(QMenu);
- if (!isVisible() || d->aboutToHide || d->mouseEventTaken(e))
- return;
- d->motions++;
- if (d->motions == 0) // ignore first mouse move event (see enterEvent())
- return;
- d->hasHadMouse = d->hasHadMouse || rect().contains(e->pos());
-
- QAction *action = d->actionAt(e->pos());
- if (!action) {
- if (d->hasHadMouse
- && (!d->currentAction
- || !(d->currentAction->menu() && d->currentAction->menu()->isVisible())))
- d->setCurrentAction(0);
- return;
- } else if(e->buttons()) {
- d->mouseDown = this;
- }
- if (d->sloppyRegion.contains(e->pos())) {
- d->sloppyAction = action;
- QMenuPrivate::sloppyDelayTimer = startTimer(style()->styleHint(QStyle::SH_Menu_SubMenuPopupDelay, 0, this)*6);
- } else if (action != d->currentAction) {
- d->setCurrentAction(action, style()->styleHint(QStyle::SH_Menu_SubMenuPopupDelay, 0, this));
- }
-}
-
-/*!
- \reimp
-*/
-void QMenu::enterEvent(QEvent *)
-{
- d_func()->motions = -1; // force us to ignore the generate mouse move in mouseMoveEvent()
-}
-
-/*!
- \reimp
-*/
-void QMenu::leaveEvent(QEvent *)
-{
- Q_D(QMenu);
- d->sloppyAction = 0;
- if (!d->sloppyRegion.isEmpty())
- d->sloppyRegion = QRegion();
- if (!d->activeMenu && d->currentAction)
- setActiveAction(0);
-}
-
-/*!
- \reimp
-*/
-void
-QMenu::timerEvent(QTimerEvent *e)
-{
- Q_D(QMenu);
- if (d->scroll && d->scroll->scrollTimer.timerId() == e->timerId()) {
- d->scrollMenu((QMenuPrivate::QMenuScroller::ScrollDirection)d->scroll->scrollDirection);
- if (d->scroll->scrollFlags == QMenuPrivate::QMenuScroller::ScrollNone)
- d->scroll->scrollTimer.stop();
- } else if(d->menuDelayTimer.timerId() == e->timerId()) {
- d->menuDelayTimer.stop();
- internalDelayedPopup();
- } else if(QMenuPrivate::sloppyDelayTimer == e->timerId()) {
- killTimer(QMenuPrivate::sloppyDelayTimer);
- QMenuPrivate::sloppyDelayTimer = 0;
- internalSetSloppyAction();
- } else if(d->searchBufferTimer.timerId() == e->timerId()) {
- d->searchBuffer.clear();
- }
-}
-
-/*!
- \reimp
-*/
-void QMenu::actionEvent(QActionEvent *e)
-{
- Q_D(QMenu);
- d->itemsDirty = 1;
- setAttribute(Qt::WA_Resized, false);
- if (d->tornPopup)
- d->tornPopup->syncWithMenu(this, e);
- if (e->type() == QEvent::ActionAdded) {
- if(!d->tornoff) {
- connect(e->action(), SIGNAL(triggered()), this, SLOT(_q_actionTriggered()));
- connect(e->action(), SIGNAL(hovered()), this, SLOT(_q_actionHovered()));
- }
- if (QWidgetAction *wa = qobject_cast<QWidgetAction *>(e->action())) {
- QWidget *widget = wa->requestWidget(this);
- if (widget)
- d->widgetItems.insert(wa, widget);
- }
- } else if (e->type() == QEvent::ActionRemoved) {
- e->action()->disconnect(this);
- if (e->action() == d->currentAction)
- d->currentAction = 0;
- if (QWidgetAction *wa = qobject_cast<QWidgetAction *>(e->action())) {
- if (QWidget *widget = d->widgetItems.value(wa))
- wa->releaseWidget(widget);
- }
- d->widgetItems.remove(e->action());
- }
-
-#ifdef Q_WS_MAC
- if (d->mac_menu) {
- if (e->type() == QEvent::ActionAdded)
- d->mac_menu->addAction(e->action(), d->mac_menu->findAction(e->before()), d);
- else if (e->type() == QEvent::ActionRemoved)
- d->mac_menu->removeAction(e->action());
- else if (e->type() == QEvent::ActionChanged)
- d->mac_menu->syncAction(e->action());
- }
-#endif
-
-#if defined(Q_WS_WINCE) && !defined(QT_NO_MENUBAR)
- if (!d->wce_menu)
- d->wce_menu = new QMenuPrivate::QWceMenuPrivate;
- if (e->type() == QEvent::ActionAdded)
- d->wce_menu->addAction(e->action(), d->wce_menu->findAction(e->before()));
- else if (e->type() == QEvent::ActionRemoved)
- d->wce_menu->removeAction(e->action());
- else if (e->type() == QEvent::ActionChanged)
- d->wce_menu->syncAction(e->action());
-#endif
-
-#ifdef Q_WS_S60
- if (!d->symbian_menu)
- d->symbian_menu = new QMenuPrivate::QSymbianMenuPrivate;
- if (e->type() == QEvent::ActionAdded)
- d->symbian_menu->addAction(e->action(), d->symbian_menu->findAction(e->before()));
- else if (e->type() == QEvent::ActionRemoved)
- d->symbian_menu->removeAction(e->action());
- else if (e->type() == QEvent::ActionChanged)
- d->symbian_menu->syncAction(e->action());
-#endif
- if (isVisible()) {
- d->updateActionRects();
- resize(sizeHint());
- update();
- }
-}
-
-/*!
- \internal
-*/
-void QMenu::internalSetSloppyAction()
-{
- if (d_func()->sloppyAction)
- d_func()->setCurrentAction(d_func()->sloppyAction, 0);
-}
-
-/*!
- \internal
-*/
-void QMenu::internalDelayedPopup()
-{
- Q_D(QMenu);
-
- //hide the current item
- if (QMenu *menu = d->activeMenu) {
- d->activeMenu = 0;
- d->hideMenu(menu);
- }
-
- if (!d->currentAction || !d->currentAction->isEnabled() || !d->currentAction->menu() ||
- !d->currentAction->menu()->isEnabled() || d->currentAction->menu()->isVisible())
- return;
-
- //setup
- d->activeMenu = d->currentAction->menu();
- d->activeMenu->d_func()->causedPopup.widget = this;
- d->activeMenu->d_func()->causedPopup.action = d->currentAction;
-
- 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(actionRect.right() + subMenuOffset + 1, actionRect.top())));
-
- QPoint pos(rightPos);
-
- //calc sloppy focus buffer
- if (style()->styleHint(QStyle::SH_Menu_SloppySubMenus, 0, this)) {
- QPoint cur = QCursor::pos();
- if (actionRect.contains(mapFromGlobal(cur))) {
- QPoint pts[4];
- pts[0] = QPoint(cur.x(), cur.y() - 2);
- pts[3] = QPoint(cur.x(), cur.y() + 2);
- if (pos.x() >= cur.x()) {
- pts[1] = QPoint(geometry().right(), pos.y());
- pts[2] = QPoint(geometry().right(), pos.y() + menuSize.height());
- } else {
- pts[1] = QPoint(pos.x() + menuSize.width(), pos.y());
- pts[2] = QPoint(pos.x() + menuSize.width(), pos.y() + menuSize.height());
- }
- QPolygon points(4);
- for(int i = 0; i < 4; i++)
- points.setPoint(i, mapFromGlobal(pts[i]));
- d->sloppyRegion = QRegion(points);
- }
- }
-
- //do the popup
- d->activeMenu->popup(pos);
-}
-
-/*!
- \fn void QMenu::addAction(QAction *action)
- \overload
-
- Appends the action \a action to the menu's list of actions.
-
- \sa QMenuBar::addAction(), QWidget::addAction()
-*/
-
-/*!
- \fn void QMenu::aboutToHide()
- \since 4.2
-
- This signal is emitted just before the menu is hidden from the user.
-
- \sa aboutToShow(), hide()
-*/
-
-/*!
- \fn void QMenu::aboutToShow()
-
- This signal is emitted just before the menu is shown to the user.
-
- \sa aboutToHide(), show()
-*/
-
-/*!
- \fn void QMenu::triggered(QAction *action)
-
- This signal is emitted when an action in this menu is triggered.
-
- \a action is the action that caused the signal to be emitted.
-
- Normally, you connect each menu action's \l{QAction::}{triggered()} signal
- to its own custom slot, but sometimes you will want to connect several
- actions to a single slot, for example, when you have a group of closely
- related actions, such as "left justify", "center", "right justify".
-
- \note This signal is emitted for the main parent menu in a hierarchy.
- Hence, only the parent menu needs to be connected to a slot; sub-menus need
- not be connected.
-
- \sa hovered(), QAction::triggered()
-*/
-
-/*!
- \fn void QMenu::hovered(QAction *action)
-
- This signal is emitted when a menu action is highlighted; \a action
- is the action that caused the signal to be emitted.
-
- Often this is used to update status information.
-
- \sa triggered(), QAction::hovered()
-*/
-
-
-/*!\internal
-*/
-void QMenu::setNoReplayFor(QWidget *noReplayFor)
-{
-#ifdef Q_WS_WIN
- d_func()->noReplayFor = noReplayFor;
-#else
- Q_UNUSED(noReplayFor);
-#endif
-}
-
-/*!
- \property QMenu::separatorsCollapsible
- \since 4.2
-
- \brief whether consecutive separators should be collapsed
-
- This property specifies whether consecutive separators in the menu
- should be visually collapsed to a single one. Separators at the
- beginning or the end of the menu are also hidden.
-
- By default, this property is true.
-*/
-bool QMenu::separatorsCollapsible() const
-{
- Q_D(const QMenu);
- return d->collapsibleSeparators;
-}
-
-void QMenu::setSeparatorsCollapsible(bool collapse)
-{
- Q_D(QMenu);
- if (d->collapsibleSeparators == collapse)
- return;
-
- d->collapsibleSeparators = collapse;
- d->itemsDirty = 1;
- if (isVisible()) {
- d->updateActionRects();
- update();
- }
-#ifdef Q_WS_MAC
- if (d->mac_menu)
- d->syncSeparatorsCollapsible(collapse);
-#endif
-}
-
-#ifdef QT3_SUPPORT
-
-int QMenu::insertAny(const QIcon *icon, const QString *text, const QObject *receiver, const char *member,
- const QKeySequence *shortcut, const QMenu *popup, int id, int index)
-{
- QAction *act = popup ? popup->menuAction() : new QAction(this);
- if (id != -1)
- static_cast<QMenuItem*>(act)->setId(id);
- if (icon)
- act->setIcon(*icon);
- if (text)
- act->setText(*text);
- if (shortcut)
- act->setShortcut(*shortcut);
- if (receiver && member)
- QObject::connect(act, SIGNAL(activated(int)), receiver, member);
- if (index == -1 || index >= actions().count())
- addAction(act);
- else
- insertAction(actions().value(index), act);
- return findIdForAction(act);
-}
-
-/*!
- Use insertAction() or one of the addAction() overloads instead.
-*/
-int QMenu::insertItem(QMenuItem *item, int id, int index)
-{
- if (index == -1 || index >= actions().count())
- addAction(item);
- else
- insertAction(actions().value(index), item);
- if (id > -1)
- item->d_func()->id = id;
- return findIdForAction(item);
-}
-
-/*!
- Use the insertSeparator() overload that takes a QAction *
- parameter instead.
-*/
-int QMenu::insertSeparator(int index)
-{
- QAction *act = new QAction(this);
- act->setSeparator(true);
- if (index == -1 || index >= actions().count())
- addAction(act);
- else
- insertAction(actions().value(index), act);
- return findIdForAction(act);
-}
-
-QAction *QMenu::findActionForId(int id) const
-{
- Q_D(const QMenu);
- for (int i = 0; i < d->actions.size(); ++i) {
- QAction *act = d->actions.at(i);
- if (findIdForAction(act)== id)
- return act;
- }
- return 0;
-}
-
-/*!
- Use QAction and actions() instead.
-*/
-QMenuItem *QMenu::findPopup( QMenu *popup, int *index )
-{
- QList<QAction *> list = actions();
- for (int i = 0; i < list.size(); ++i) {
- QAction *act = list.at(i);
- if (act->menu() == popup) {
- QMenuItem *item = static_cast<QMenuItem *>(act);
- if (index)
- *index = act->d_func()->id;
- return item;
- }
- }
- return 0;
-}
-
-
-/*!
- Use QAction::setData() instead.
-*/
-bool QMenu::setItemParameter(int id, int param)
-{
- if (QAction *act = findActionForId(id)) {
- act->d_func()->param = param;
- return true;
- }
- return false;
-}
-
-/*!
- Use QAction::data() instead.
-*/
-int QMenu::itemParameter(int id) const
-{
- if (QAction *act = findActionForId(id))
- return act->d_func()->param;
- return id;
-}
-
-/*!
- Use actions instead.
-*/
-void QMenu::setId(int index, int id)
-{
- if(QAction *act = actions().value(index))
- act->d_func()->id = id;
-}
-
-/*!
- Use style()->pixelMetric(QStyle::PM_MenuPanelWidth, this) instead.
-*/
-int QMenu::frameWidth() const
-{
- return style()->pixelMetric(QStyle::PM_MenuPanelWidth, 0, this);
-}
-
-int QMenu::findIdForAction(QAction *act) const
-{
- if (!act)
- return -1;
- return act->d_func()->id;
-}
-#endif // QT3_SUPPORT
-
-/*!
- \fn uint QMenu::count() const
-
- Use actions().count() instead.
-*/
-
-/*!
- \fn int QMenu::insertItem(const QString &text, const QObject *receiver, const char* member, const QKeySequence& shortcut, int id, int index)
-
- Use insertAction() or one of the addAction() overloads instead.
-*/
-
-/*!
- \fn int QMenu::insertItem(const QIcon& icon, const QString &text, const QObject *receiver, const char* member, const QKeySequence& shortcut, int id, int index)
-
- Use insertAction() or one of the addAction() overloads instead.
-*/
-
-/*!
- \fn int QMenu::insertItem(const QPixmap &pixmap, const QObject *receiver, const char* member, const QKeySequence& shortcut, int id, int index)
-
- Use insertAction() or one of the addAction() overloads instead.
-*/
-
-/*!
- \fn int QMenu::insertItem(const QString &text, int id, int index)
-
- Use insertAction() or one of the addAction() overloads instead.
-*/
-
-/*!
- \fn int QMenu::insertItem(const QIcon& icon, const QString &text, int id, int index)
-
- Use insertAction() or one of the addAction() overloads instead.
-*/
-
-/*!
- \fn int QMenu::insertItem(const QString &text, QMenu *popup, int id, int index)
-
- Use insertMenu() or one of the addMenu() overloads instead.
-*/
-
-/*!
- \fn int QMenu::insertItem(const QIcon& icon, const QString &text, QMenu *popup, int id, int index)
-
- Use insertMenu() or one of the addMenu() overloads instead.
-*/
-
-/*!
- \fn int QMenu::insertItem(const QPixmap &pixmap, int id, int index)
-
- Use insertAction() or one of the addAction() overloads instead.
-*/
-
-/*!
- \fn int QMenu::insertItem(const QPixmap &pixmap, QMenu *popup, int id, int index)
-
- Use insertMenu() or one of the addMenu() overloads instead.
-*/
-
-/*!
- \fn void QMenu::removeItem(int id)
-
- Use removeAction() instead.
-*/
-
-/*!
- \fn void QMenu::removeItemAt(int index)
-
- Use removeAction() instead.
-*/
-
-/*!
- \fn QKeySequence QMenu::accel(int id) const
-
- Use shortcut() on the relevant QAction instead.
-*/
-
-/*!
- \fn void QMenu::setAccel(const QKeySequence& key, int id)
-
- Use setShortcut() on the relevant QAction instead.
-*/
-
-/*!
- \fn QIcon QMenu::iconSet(int id) const
-
- Use icon() on the relevant QAction instead.
-*/
-
-/*!
- \fn QString QMenu::text(int id) const
-
- Use text() on the relevant QAction instead.
-*/
-
-/*!
- \fn QPixmap QMenu::pixmap(int id) const
-
- Use QPixmap(icon()) on the relevant QAction instead.
-*/
-
-/*!
- \fn void QMenu::setWhatsThis(int id, const QString &w)
-
- Use setWhatsThis() on the relevant QAction instead.
-*/
-
-/*!
- \fn QString QMenu::whatsThis(int id) const
-
- Use whatsThis() on the relevant QAction instead.
-*/
-
-/*!
- \fn void QMenu::changeItem(int id, const QString &text)
-
- Use setText() on the relevant QAction instead.
-*/
-
-/*!
- \fn void QMenu::changeItem(int id, const QPixmap &pixmap)
-
- Use setText() on the relevant QAction instead.
-*/
-
-/*!
- \fn void QMenu::changeItem(int id, const QIcon &icon, const QString &text)
-
- Use setIcon() and setText() on the relevant QAction instead.
-*/
-
-/*!
- \fn bool QMenu::isItemActive(int id) const
-
- Use activeAction() instead.
-*/
-
-/*!
- \fn bool QMenu::isItemEnabled(int id) const
-
- Use isEnabled() on the relevant QAction instead.
-*/
-
-/*!
- \fn void QMenu::setItemEnabled(int id, bool enable)
-
- Use setEnabled() on the relevant QAction instead.
-*/
-
-/*!
- \fn bool QMenu::isItemChecked(int id) const
-
- Use isChecked() on the relevant QAction instead.
-*/
-
-/*!
- \fn void QMenu::setItemChecked(int id, bool check)
-
- Use setChecked() on the relevant QAction instead.
-*/
-
-/*!
- \fn bool QMenu::isItemVisible(int id) const
-
- Use isVisible() on the relevant QAction instead.
-*/
-
-/*!
- \fn void QMenu::setItemVisible(int id, bool visible)
-
- Use setVisible() on the relevant QAction instead.
-*/
-
-/*!
- \fn QRect QMenu::itemGeometry(int index)
-
- Use actionGeometry() on the relevant QAction instead.
-*/
-
-/*!
- \fn QFont QMenu::itemFont(int id) const
-
- Use font() on the relevant QAction instead.
-*/
-
-/*!
- \fn void QMenu::setItemFont(int id, const QFont &font)
-
- Use setFont() on the relevant QAction instead.
-*/
-
-/*!
- \fn int QMenu::indexOf(int id) const
-
- Use actions().indexOf(action) on the relevant QAction instead.
-*/
-
-/*!
- \fn int QMenu::idAt(int index) const
-
- Use actions instead.
-*/
-
-/*!
- \fn void QMenu::activateItemAt(int index)
-
- Use activate() on the relevant QAction instead.
-*/
-
-/*!
- \fn bool QMenu::connectItem(int id, const QObject *receiver, const char* member)
-
- Use connect() on the relevant QAction instead.
-*/
-
-/*!
- \fn bool QMenu::disconnectItem(int id,const QObject *receiver, const char* member)
- Use disconnect() on the relevant QAction instead.
-
-*/
-
-/*!
- \fn QMenuItem *QMenu::findItem(int id) const
-
- Use actions instead.
-*/
-
-/*!
- \fn void QMenu::popup(const QPoint & pos, int indexAtPoint)
-
- Use popup() on the relevant QAction instead.
-*/
-
-/*!
- \fn int QMenu::insertTearOffHandle(int a, int b)
-
- Use setTearOffEnabled() instead.
-*/
-
-/*!
- \fn int QMenu::itemAtPos(const QPoint &p, bool ignoreSeparator)
-
- Use actions instead.
-*/
-
-/*!
- \fn int QMenu::columns() const
-
- Use columnCount() instead.
-*/
-
-/*!
- \fn int QMenu::itemHeight(int index)
-
- Use actionGeometry(actions().value(index)).height() instead.
-*/
-
-/*!
- \fn int QMenu::itemHeight(QMenuItem *mi)
-
- Use actionGeometry() instead.
-*/
-
-/*!
- \fn void QMenu::activated(int itemId);
-
- Use triggered() instead.
-*/
-
-/*!
- \fn void QMenu::highlighted(int itemId);
-
- Use hovered() instead.
-*/
-
-/*!
- \fn void QMenu::setCheckable(bool checkable)
-
- Not necessary anymore. The \a checkable parameter is ignored.
-*/
-
-/*!
- \fn bool QMenu::isCheckable() const
-
- Not necessary anymore. Always returns true.
-*/
-
-/*!
- \fn void QMenu::setActiveItem(int id)
-
- Use setActiveAction() instead.
-*/
-
-QT_END_NAMESPACE
-
-// for private slots
-#include "moc_qmenu.cpp"
-#include "qmenu.moc"
-
-#endif // QT_NO_MENU
diff --git a/src/gui/widgets/qmenu.h b/src/gui/widgets/qmenu.h
deleted file mode 100644
index 053fdee01e..0000000000
--- a/src/gui/widgets/qmenu.h
+++ /dev/null
@@ -1,434 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QMENU_H
-#define QMENU_H
-
-#include <QtGui/qwidget.h>
-#include <QtCore/qstring.h>
-#include <QtGui/qicon.h>
-#include <QtGui/qaction.h>
-
-#ifdef QT3_SUPPORT
-#include <QtGui/qpixmap.h>
-#endif
-
-#ifdef Q_WS_WINCE
-#include <windef.h> // for HMENU
-#endif
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_MENU
-
-class QMenuPrivate;
-class QStyleOptionMenuItem;
-#ifdef QT3_SUPPORT
-class QMenuItem;
-#endif
-
-class Q_GUI_EXPORT QMenu : public QWidget
-{
-private:
- Q_OBJECT
- Q_DECLARE_PRIVATE(QMenu)
-
- Q_PROPERTY(bool tearOffEnabled READ isTearOffEnabled WRITE setTearOffEnabled)
- Q_PROPERTY(QString title READ title WRITE setTitle)
- Q_PROPERTY(QIcon icon READ icon WRITE setIcon)
- Q_PROPERTY(bool separatorsCollapsible READ separatorsCollapsible WRITE setSeparatorsCollapsible)
-
-public:
- explicit QMenu(QWidget *parent = 0);
- explicit QMenu(const QString &title, QWidget *parent = 0);
- ~QMenu();
-
-#ifdef Q_NO_USING_KEYWORD
- inline void addAction(QAction *action) { QWidget::addAction(action); }
-#else
- using QWidget::addAction;
-#endif
- QAction *addAction(const QString &text);
- QAction *addAction(const QIcon &icon, const QString &text);
- QAction *addAction(const QString &text, const QObject *receiver, const char* member, const QKeySequence &shortcut = 0);
- QAction *addAction(const QIcon &icon, const QString &text, const QObject *receiver, const char* member, const QKeySequence &shortcut = 0);
-
- QAction *addMenu(QMenu *menu);
- QMenu *addMenu(const QString &title);
- QMenu *addMenu(const QIcon &icon, const QString &title);
-
- QAction *addSeparator();
-
- QAction *insertMenu(QAction *before, QMenu *menu);
- QAction *insertSeparator(QAction *before);
-
- bool isEmpty() const;
- void clear();
-
- void setTearOffEnabled(bool);
- bool isTearOffEnabled() const;
-
- bool isTearOffMenuVisible() const;
- void hideTearOffMenu();
-
- void setDefaultAction(QAction *);
- QAction *defaultAction() const;
-
- void setActiveAction(QAction *act);
- QAction *activeAction() const;
-
- void popup(const QPoint &pos, QAction *at=0);
- QAction *exec();
- QAction *exec(const QPoint &pos, QAction *at=0);
-
- // ### Qt 5: merge
- static QAction *exec(QList<QAction*> actions, const QPoint &pos, QAction *at=0);
- static QAction *exec(QList<QAction*> actions, const QPoint &pos, QAction *at, QWidget *parent);
-
- QSize sizeHint() const;
-
- QRect actionGeometry(QAction *) const;
- QAction *actionAt(const QPoint &) const;
-
- QAction *menuAction() const;
-
- QString title() const;
- void setTitle(const QString &title);
-
- QIcon icon() const;
- void setIcon(const QIcon &icon);
-
- void setNoReplayFor(QWidget *widget);
-#ifdef Q_WS_MAC
- OSMenuRef macMenu(OSMenuRef merge=0);
-#endif
-
-#ifdef Q_WS_WINCE
- HMENU wceMenu();
-#endif
-
- bool separatorsCollapsible() const;
- void setSeparatorsCollapsible(bool collapse);
-
-Q_SIGNALS:
- void aboutToShow();
- void aboutToHide();
- void triggered(QAction *action);
- void hovered(QAction *action);
-
-protected:
- int columnCount() const;
-
- void changeEvent(QEvent *);
- void keyPressEvent(QKeyEvent *);
- void mouseReleaseEvent(QMouseEvent *);
- void mousePressEvent(QMouseEvent *);
- void mouseMoveEvent(QMouseEvent *);
-#ifndef QT_NO_WHEELEVENT
- void wheelEvent(QWheelEvent *);
-#endif
- void enterEvent(QEvent *);
- void leaveEvent(QEvent *);
- void hideEvent(QHideEvent *);
- void paintEvent(QPaintEvent *);
- void actionEvent(QActionEvent *);
- void timerEvent(QTimerEvent *);
- bool event(QEvent *);
- bool focusNextPrevChild(bool next);
- void initStyleOption(QStyleOptionMenuItem *option, const QAction *action) const;
-
-#ifdef Q_WS_WINCE
- QAction* wceCommands(uint command);
-#endif
-
-private Q_SLOTS:
- void internalSetSloppyAction();
- void internalDelayedPopup();
-
-private:
- Q_PRIVATE_SLOT(d_func(), void _q_actionTriggered())
- Q_PRIVATE_SLOT(d_func(), void _q_actionHovered())
- Q_PRIVATE_SLOT(d_func(), void _q_overrideMenuActionDestroyed())
-
-#ifdef QT3_SUPPORT
-public:
- //menudata
- inline QT3_SUPPORT uint count() const { return actions().count(); }
- inline QT3_SUPPORT int insertItem(const QString &text, const QObject *receiver, const char* member,
- const QKeySequence& shortcut = 0, int id = -1, int index = -1) {
- return insertAny(0, &text, receiver, member, &shortcut, 0, id, index);
- }
- inline QT3_SUPPORT int insertItem(const QIcon& icon, const QString &text,
- const QObject *receiver, const char* member,
- const QKeySequence& shortcut = 0, int id = -1, int index = -1) {
- return insertAny(&icon, &text, receiver, member, &shortcut, 0, id, index);
- }
- inline QT3_SUPPORT int insertItem(const QPixmap &pixmap, const QObject *receiver, const char* member,
- const QKeySequence& shortcut = 0, int id = -1, int index = -1) {
- QIcon icon(pixmap);
- return insertAny(&icon, 0, receiver, member, &shortcut, 0, id, index);
- }
- inline QT3_SUPPORT int insertItem(const QString &text, int id=-1, int index=-1) {
- return insertAny(0, &text, 0, 0, 0, 0, id, index);
- }
- inline QT3_SUPPORT int insertItem(const QIcon& icon, const QString &text, int id=-1, int index=-1) {
- return insertAny(&icon, &text, 0, 0, 0, 0, id, index);
- }
- inline QT3_SUPPORT int insertItem(const QString &text, QMenu *popup, int id=-1, int index=-1) {
- return insertAny(0, &text, 0, 0, 0, popup, id, index);
- }
- inline QT3_SUPPORT int insertItem(const QIcon& icon, const QString &text, QMenu *popup, int id=-1, int index=-1) {
- return insertAny(&icon, &text, 0, 0, 0, popup, id, index);
- }
- inline QT3_SUPPORT int insertItem(const QPixmap &pixmap, int id=-1, int index=-1) {
- QIcon icon(pixmap);
- return insertAny(&icon, 0, 0, 0, 0, 0, id, index);
- }
- inline QT3_SUPPORT int insertItem(const QPixmap &pixmap, QMenu *popup, int id=-1, int index=-1) {
- QIcon icon(pixmap);
- return insertAny(&icon, 0, 0, 0, 0, popup, id, index);
- }
- QT3_SUPPORT int insertItem(QMenuItem *item, int id=-1, int index=-1);
- QT3_SUPPORT int insertSeparator(int index=-1);
- inline QT3_SUPPORT void removeItem(int id) {
- if(QAction *act = findActionForId(id))
- removeAction(act); }
- inline QT3_SUPPORT void removeItemAt(int index) {
- if(QAction *act = actions().value(index))
- removeAction(act); }
-#ifndef QT_NO_SHORTCUT
- inline QT3_SUPPORT QKeySequence accel(int id) const {
- if(QAction *act = findActionForId(id))
- return act->shortcut();
- return QKeySequence(); }
- inline QT3_SUPPORT void setAccel(const QKeySequence& key, int id) {
- if(QAction *act = findActionForId(id))
- act->setShortcut(key);
- }
-#endif
- inline QT3_SUPPORT QIcon iconSet(int id) const {
- if(QAction *act = findActionForId(id))
- return act->icon();
- return QIcon(); }
- inline QT3_SUPPORT QString text(int id) const {
- if(QAction *act = findActionForId(id))
- return act->text();
- return QString(); }
- inline QT3_SUPPORT QPixmap pixmap(int id) const {
- if(QAction *act = findActionForId(id))
- return act->icon().pixmap(QSize(22, 22));
- return QPixmap(); }
- inline QT3_SUPPORT void setWhatsThis(int id, const QString &w) {
- if(QAction *act = findActionForId(id))
- act->setWhatsThis(w); }
- inline QT3_SUPPORT QString whatsThis(int id) const {
- if(QAction *act = findActionForId(id))
- return act->whatsThis();
- return QString(); }
-
- inline QT3_SUPPORT void changeItem(int id, const QString &text) {
- if(QAction *act = findActionForId(id))
- act->setText(text); }
- inline QT3_SUPPORT void changeItem(int id, const QPixmap &pixmap) {
- if(QAction *act = findActionForId(id))
- act->setIcon(QIcon(pixmap)); }
- inline QT3_SUPPORT void changeItem(int id, const QIcon &icon, const QString &text) {
- if(QAction *act = findActionForId(id)) {
- act->setIcon(icon);
- act->setText(text);
- }
- }
- inline QT3_SUPPORT void setActiveItem(int id) {
- setActiveAction(findActionForId(id));
- }
- inline QT3_SUPPORT bool isItemActive(int id) const {
- return findActionForId(id) == activeAction();
- }
- inline QT3_SUPPORT bool isItemEnabled(int id) const {
- if(QAction *act = findActionForId(id))
- return act->isEnabled();
- return false; }
- inline QT3_SUPPORT void setItemEnabled(int id, bool enable) {
- if(QAction *act = findActionForId(id))
- act->setEnabled(enable);
- }
- inline QT3_SUPPORT bool isItemChecked(int id) const {
- if(QAction *act = findActionForId(id))
- return act->isChecked();
- return false;
- }
- inline QT3_SUPPORT void setItemChecked(int id, bool check) {
- if(QAction *act = findActionForId(id)) {
- act->setCheckable(true);
- act->setChecked(check);
- }
- }
- inline QT3_SUPPORT bool isItemVisible(int id) const {
- if(QAction *act = findActionForId(id))
- return act->isVisible();
- return false;
- }
- inline QT3_SUPPORT void setItemVisible(int id, bool visible) {
- if(QAction *act = findActionForId(id))
- act->setVisible(visible);
- }
- inline QT3_SUPPORT QRect itemGeometry(int index) {
- if(QAction *act = actions().value(index))
- return actionGeometry(act);
- return QRect();
- }
- inline QT3_SUPPORT QFont itemFont(int id) const {
- if(QAction *act = findActionForId(id))
- return act->font();
- return QFont();
- }
- inline QT3_SUPPORT void setItemFont(int id, const QFont &font) {
- if(QAction *act = findActionForId(id))
- act->setFont(font);
- }
- inline QT3_SUPPORT int indexOf(int id) const {
- return actions().indexOf(findActionForId(id));
- }
- inline QT3_SUPPORT int idAt(int index) const {
- return findIdForAction(actions().value(index));
- }
- QT3_SUPPORT void setId (int index, int id);
- inline QT3_SUPPORT void activateItemAt(int index) {
- if(QAction *ret = actions().value(index))
- ret->activate(QAction::Trigger);
- }
- inline QT3_SUPPORT bool connectItem(int id, const QObject *receiver, const char* member) {
- if(QAction *act = findActionForId(id)) {
- QObject::connect(act, SIGNAL(activated(int)), receiver, member);
- return true;
- }
- return false;
- }
- inline QT3_SUPPORT bool disconnectItem(int id,const QObject *receiver, const char* member) {
- if(QAction *act = findActionForId(id)) {
- QObject::disconnect(act, SIGNAL(triggered()), receiver, member);
- return true;
- }
- return false;
- }
- inline QT3_SUPPORT QMenuItem *findItem(int id) const {
- return reinterpret_cast<QMenuItem*>(findActionForId(id));
- }
-
- inline QT3_SUPPORT void setCheckable(bool){}
- inline QT3_SUPPORT bool isCheckable() const {return true;}
-
- QT3_SUPPORT QMenuItem *findPopup( QMenu *popup, int *index );
-
- QT3_SUPPORT bool setItemParameter(int id, int param);
- QT3_SUPPORT int itemParameter(int id) const;
-
- //frame
- QT3_SUPPORT int frameWidth() const;
-
- //popupmenu
- inline QT3_SUPPORT void popup(const QPoint & pos, int indexAtPoint) { popup(pos, actions().value(indexAtPoint)); }
- inline QT3_SUPPORT int insertTearOffHandle(int = 0, int = 0) {
- setTearOffEnabled(true);
- return -1;
- }
-
-protected:
- inline QT3_SUPPORT int itemAtPos(const QPoint &p, bool ignoreSeparator = true) {
- QAction *ret = actionAt(p);
- if(ignoreSeparator && ret && ret->isSeparator())
- return -1;
- return findIdForAction(ret);
- }
- inline QT3_SUPPORT int columns() const { return columnCount(); }
- inline QT3_SUPPORT int itemHeight(int index) {
- return actionGeometry(actions().value(index)).height();
- }
- inline QT3_SUPPORT int itemHeight(QMenuItem *mi) {
- return actionGeometry(reinterpret_cast<QAction *>(mi)).height();
- }
-
-Q_SIGNALS:
- QT_MOC_COMPAT void activated(int itemId);
- QT_MOC_COMPAT void highlighted(int itemId);
-
-private:
- int insertAny(const QIcon *icon, const QString *text, const QObject *receiver, const char *member,
- const QKeySequence *shorcut, const QMenu *popup, int id, int index);
- QAction *findActionForId(int id) const;
- int findIdForAction(QAction*) const;
-#endif
-
-protected:
- QMenu(QMenuPrivate &dd, QWidget* parent = 0);
-
-private:
- Q_DISABLE_COPY(QMenu)
-
- friend class QMenuBar;
- friend class QMenuBarPrivate;
- friend class QTornOffMenu;
- friend class Q3PopupMenu;
- friend class QComboBox;
- friend class QAction;
- friend class QToolButtonPrivate;
-
-#ifdef Q_WS_MAC
- friend void qt_mac_trayicon_activate_action(QMenu *, QAction *action);
- friend bool qt_mac_watchingAboutToShow(QMenu *);
- friend OSStatus qt_mac_menu_event(EventHandlerCallRef, EventRef, void *);
- friend bool qt_mac_activate_action(OSMenuRef, uint, QAction::ActionEvent, bool);
- friend void qt_mac_emit_menuSignals(QMenu *, bool);
- friend void qt_mac_menu_emit_hovered(QMenu *menu, QAction *action);
-#endif
-};
-
-#endif // QT_NO_MENU
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QMENU_H
diff --git a/src/gui/widgets/qmenu_mac.mm b/src/gui/widgets/qmenu_mac.mm
deleted file mode 100644
index 56658b3718..0000000000
--- a/src/gui/widgets/qmenu_mac.mm
+++ /dev/null
@@ -1,2217 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qmenu.h"
-#include "qhash.h"
-#include <qdebug.h>
-#include "qapplication.h"
-#include <private/qt_mac_p.h>
-#include "qregexp.h"
-#include "qmainwindow.h"
-#include "qdockwidget.h"
-#include "qtoolbar.h"
-#include "qevent.h"
-#include "qstyle.h"
-#include "qwidgetaction.h"
-#include "qmacnativewidget_mac.h"
-
-#include <private/qapplication_p.h>
-#include <private/qcocoaapplication_mac_p.h>
-#include <private/qmenu_p.h>
-#include <private/qmenubar_p.h>
-#include <private/qcocoamenuloader_mac_p.h>
-#include <private/qcocoamenu_mac_p.h>
-#include <private/qt_cocoa_helpers_mac_p.h>
-#include <Cocoa/Cocoa.h>
-
-QT_BEGIN_NAMESPACE
-
-/*****************************************************************************
- QMenu debug facilities
- *****************************************************************************/
-
-/*****************************************************************************
- QMenu globals
- *****************************************************************************/
-bool qt_mac_no_menubar_merge = false;
-bool qt_mac_quit_menu_item_enabled = true;
-int qt_mac_menus_open_count = 0;
-
-static OSMenuRef qt_mac_create_menu(QWidget *w);
-
-#ifndef QT_MAC_USE_COCOA
-static uint qt_mac_menu_static_cmd_id = 'QT00';
-const UInt32 kMenuCreatorQt = 'cute';
-enum {
- kMenuPropertyQAction = 'QAcT',
- kMenuPropertyQWidget = 'QWId',
- kMenuPropertyCausedQWidget = 'QCAU',
- kMenuPropertyMergeMenu = 'QApP',
- kMenuPropertyMergeList = 'QAmL',
- kMenuPropertyWidgetActionWidget = 'QWid',
- kMenuPropertyWidgetMenu = 'QWMe',
-
- kHICommandAboutQt = 'AOQT',
- kHICommandCustomMerge = 'AQt0'
-};
-#endif
-
-static struct {
- QPointer<QMenuBar> qmenubar;
- bool modal;
-} qt_mac_current_menubar = { 0, false };
-
-
-
-
-/*****************************************************************************
- Externals
- *****************************************************************************/
-extern OSViewRef qt_mac_hiview_for(const QWidget *w); //qwidget_mac.cpp
-extern HIViewRef qt_mac_hiview_for(OSWindowRef w); //qwidget_mac.cpp
-extern IconRef qt_mac_create_iconref(const QPixmap &px); //qpixmap_mac.cpp
-extern QWidget * mac_keyboard_grabber; //qwidget_mac.cpp
-extern bool qt_sendSpontaneousEvent(QObject*, QEvent*); //qapplication_xxx.cpp
-RgnHandle qt_mac_get_rgn(); //qregion_mac.cpp
-void qt_mac_dispose_rgn(RgnHandle r); //qregion_mac.cpp
-
-/*****************************************************************************
- QMenu utility functions
- *****************************************************************************/
-bool qt_mac_watchingAboutToShow(QMenu *menu)
-{
- return menu && menu->receivers(SIGNAL(aboutToShow()));
-}
-
-static int qt_mac_CountMenuItems(OSMenuRef menu)
-{
- if (menu) {
-#ifndef QT_MAC_USE_COCOA
- int ret = 0;
- const int items = CountMenuItems(menu);
- for(int i = 0; i < items; i++) {
- MenuItemAttributes attr;
- if (GetMenuItemAttributes(menu, i+1, &attr) == noErr &&
- attr & kMenuItemAttrHidden)
- continue;
- ++ret;
- }
- return ret;
-#else
- return [menu numberOfItems];
-#endif
- }
- return 0;
-}
-
-static quint32 constructModifierMask(quint32 accel_key)
-{
- quint32 ret = 0;
- const bool dontSwap = qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta);
-#ifndef QT_MAC_USE_COCOA
- if ((accel_key & Qt::ALT) == Qt::ALT)
- ret |= kMenuOptionModifier;
- if ((accel_key & Qt::SHIFT) == Qt::SHIFT)
- ret |= kMenuShiftModifier;
- if (dontSwap) {
- if ((accel_key & Qt::META) != Qt::META)
- ret |= kMenuNoCommandModifier;
- if ((accel_key & Qt::CTRL) == Qt::CTRL)
- ret |= kMenuControlModifier;
- } else {
- if ((accel_key & Qt::CTRL) != Qt::CTRL)
- ret |= kMenuNoCommandModifier;
- if ((accel_key & Qt::META) == Qt::META)
- ret |= kMenuControlModifier;
- }
-#else
- if ((accel_key & Qt::CTRL) == Qt::CTRL)
- ret |= (dontSwap ? NSControlKeyMask : NSCommandKeyMask);
- if ((accel_key & Qt::META) == Qt::META)
- ret |= (dontSwap ? NSCommandKeyMask : NSControlKeyMask);
- if ((accel_key & Qt::ALT) == Qt::ALT)
- ret |= NSAlternateKeyMask;
- if ((accel_key & Qt::SHIFT) == Qt::SHIFT)
- ret |= NSShiftKeyMask;
-#endif
- return ret;
-}
-
-static void cancelAllMenuTracking()
-{
-#ifdef QT_MAC_USE_COCOA
- QMacCocoaAutoReleasePool pool;
- NSMenu *mainMenu = [NSApp mainMenu];
- [mainMenu cancelTracking];
- for (NSMenuItem *item in [mainMenu itemArray]) {
- if ([item submenu]) {
- [[item submenu] cancelTracking];
- }
- }
-#else
- CancelMenuTracking(AcquireRootMenu(), true, 0);
-#endif
-}
-
-static bool actualMenuItemVisibility(const QMenuBarPrivate::QMacMenuBarPrivate *mbp,
- const QMacMenuAction *action)
-{
- bool visible = action->action->isVisible();
- if (visible && action->action->text() == QString(QChar(0x14)))
- return false;
- if (visible && action->action->menu() && !action->action->menu()->actions().isEmpty() &&
- !qt_mac_CountMenuItems(action->action->menu()->macMenu(mbp->apple_menu)) &&
- !qt_mac_watchingAboutToShow(action->action->menu())) {
- return false;
- }
- return visible;
-}
-
-#ifndef QT_MAC_USE_COCOA
-bool qt_mac_activate_action(MenuRef menu, uint command, QAction::ActionEvent action_e, bool by_accel)
-{
- //fire event
- QMacMenuAction *action = 0;
- if (GetMenuCommandProperty(menu, command, kMenuCreatorQt, kMenuPropertyQAction, sizeof(action), 0, &action) != noErr) {
- QMenuMergeList *list = 0;
- GetMenuItemProperty(menu, 0, kMenuCreatorQt, kMenuPropertyMergeList,
- sizeof(list), 0, &list);
- if (!list && qt_mac_current_menubar.qmenubar && qt_mac_current_menubar.qmenubar->isNativeMenuBar()) {
- MenuRef apple_menu = qt_mac_current_menubar.qmenubar->d_func()->mac_menubar->apple_menu;
- GetMenuItemProperty(apple_menu, 0, kMenuCreatorQt, kMenuPropertyMergeList, sizeof(list), 0, &list);
- if (list)
- menu = apple_menu;
- }
- if (list) {
- for(int i = 0; i < list->size(); ++i) {
- QMenuMergeItem item = list->at(i);
- if (item.command == command && item.action) {
- action = item.action;
- break;
- }
- }
- }
- if (!action)
- return false;
- }
-
- if (action_e == QAction::Trigger && by_accel && action->ignore_accel) //no, not a real accel (ie tab)
- return false;
-
- // Unhighlight the highlighted menu item before triggering the action to
- // prevent items from staying highlighted while a modal dialog is shown.
- // This also fixed the problem that parentless modal dialogs leave
- // the menu item highlighted (since the menu bar is cleared for these types of dialogs).
- if (action_e == QAction::Trigger)
- HiliteMenu(0);
-
- action->action->activate(action_e);
-
- //now walk up firing for each "caused" widget (like in the platform independent menu)
- QWidget *caused = 0;
- if (action_e == QAction::Hover && GetMenuItemProperty(menu, 0, kMenuCreatorQt, kMenuPropertyCausedQWidget, sizeof(caused), 0, &caused) == noErr) {
- MenuRef caused_menu = 0;
- if (QMenu *qmenu2 = qobject_cast<QMenu*>(caused))
- caused_menu = qmenu2->macMenu();
- else if (QMenuBar *qmenubar2 = qobject_cast<QMenuBar*>(caused))
- caused_menu = qmenubar2->macMenu();
- else
- caused_menu = 0;
- while(caused_menu) {
- //fire
- QWidget *widget = 0;
- GetMenuItemProperty(caused_menu, 0, kMenuCreatorQt, kMenuPropertyQWidget, sizeof(widget), 0, &widget);
- if (QMenu *qmenu = qobject_cast<QMenu*>(widget)) {
- action->action->showStatusText(widget);
- emit qmenu->hovered(action->action);
- } else if (QMenuBar *qmenubar = qobject_cast<QMenuBar*>(widget)) {
- action->action->showStatusText(widget);
- emit qmenubar->hovered(action->action);
- break; //nothing more..
- }
-
- //walk up
- if (GetMenuItemProperty(caused_menu, 0, kMenuCreatorQt, kMenuPropertyCausedQWidget,
- sizeof(caused), 0, &caused) != noErr)
- break;
- if (QMenu *qmenu2 = qobject_cast<QMenu*>(caused))
- caused_menu = qmenu2->macMenu();
- else if (QMenuBar *qmenubar2 = qobject_cast<QMenuBar*>(caused))
- caused_menu = qmenubar2->macMenu();
- else
- caused_menu = 0;
- }
- }
- return true;
-}
-
-//lookup a QMacMenuAction in a menu
-static int qt_mac_menu_find_action(MenuRef menu, MenuCommand cmd)
-{
- MenuItemIndex ret_idx;
- MenuRef ret_menu;
- if (GetIndMenuItemWithCommandID(menu, cmd, 1, &ret_menu, &ret_idx) == noErr) {
- if (ret_menu == menu)
- return (int)ret_idx;
- }
- return -1;
-}
-static int qt_mac_menu_find_action(MenuRef menu, QMacMenuAction *action)
-{
- return qt_mac_menu_find_action(menu, action->command);
-}
-
-typedef QMultiHash<OSMenuRef, EventHandlerRef> EventHandlerHash;
-Q_GLOBAL_STATIC(EventHandlerHash, menu_eventHandlers_hash)
-
-static EventTypeSpec widget_in_menu_events[] = {
- { kEventClassMenu, kEventMenuMeasureItemWidth },
- { kEventClassMenu, kEventMenuMeasureItemHeight },
- { kEventClassMenu, kEventMenuDrawItem },
- { kEventClassMenu, kEventMenuCalculateSize }
-};
-
-static OSStatus qt_mac_widget_in_menu_eventHandler(EventHandlerCallRef er, EventRef event, void *)
-{
- UInt32 ekind = GetEventKind(event);
- UInt32 eclass = GetEventClass(event);
- OSStatus result = eventNotHandledErr;
- switch (eclass) {
- case kEventClassMenu:
- switch (ekind) {
- default:
- break;
- case kEventMenuMeasureItemWidth: {
- MenuItemIndex item;
- GetEventParameter(event, kEventParamMenuItemIndex, typeMenuItemIndex,
- 0, sizeof(item), 0, &item);
- OSMenuRef menu;
- GetEventParameter(event, kEventParamDirectObject, typeMenuRef, 0, sizeof(menu), 0, &menu);
- QWidget *widget;
- if (GetMenuItemProperty(menu, item, kMenuCreatorQt, kMenuPropertyWidgetActionWidget,
- sizeof(widget), 0, &widget) == noErr) {
- short width = short(widget->sizeHint().width());
- SetEventParameter(event, kEventParamMenuItemWidth, typeSInt16,
- sizeof(short), &width);
- result = noErr;
- }
- break; }
- case kEventMenuMeasureItemHeight: {
- MenuItemIndex item;
- GetEventParameter(event, kEventParamMenuItemIndex, typeMenuItemIndex,
- 0, sizeof(item), 0, &item);
- OSMenuRef menu;
- GetEventParameter(event, kEventParamDirectObject, typeMenuRef, 0, sizeof(menu), 0, &menu);
- QWidget *widget;
- if (GetMenuItemProperty(menu, item, kMenuCreatorQt, kMenuPropertyWidgetActionWidget,
- sizeof(widget), 0, &widget) == noErr && widget) {
- short height = short(widget->sizeHint().height());
- SetEventParameter(event, kEventParamMenuItemHeight, typeSInt16,
- sizeof(short), &height);
- result = noErr;
- }
- break; }
- case kEventMenuDrawItem:
- result = noErr;
- break;
- case kEventMenuCalculateSize: {
- result = CallNextEventHandler(er, event);
- if (result == noErr) {
- OSMenuRef menu;
- GetEventParameter(event, kEventParamDirectObject, typeMenuRef, 0, sizeof(menu), 0, &menu);
- HIViewRef content;
- HIMenuGetContentView(menu, kThemeMenuTypePullDown, &content);
- UInt16 count = CountMenuItems(menu);
- for (MenuItemIndex i = 1; i <= count; ++i) {
- QWidget *widget;
- if (GetMenuItemProperty(menu, i, kMenuCreatorQt, kMenuPropertyWidgetActionWidget,
- sizeof(widget), 0, &widget) == noErr && widget) {
- RgnHandle itemRgn = qt_mac_get_rgn();
- GetControlRegion(content, i, itemRgn);
-
- Rect bounds;
- GetRegionBounds( itemRgn, &bounds );
- qt_mac_dispose_rgn(itemRgn);
- widget->setGeometry(bounds.left, bounds.top,
- bounds.right - bounds.left, bounds.bottom - bounds.top);
- }
- }
- }
- break; }
- }
- }
- return result;
-}
-
-//handling of events for menurefs created by Qt..
-static EventTypeSpec menu_events[] = {
- { kEventClassCommand, kEventCommandProcess },
- { kEventClassMenu, kEventMenuTargetItem },
- { kEventClassMenu, kEventMenuOpening },
- { kEventClassMenu, kEventMenuClosed }
-};
-
-// Special case for kEventMenuMatchKey, see qt_mac_create_menu below.
-static EventTypeSpec menu_menu_events[] = {
- { kEventClassMenu, kEventMenuMatchKey }
-};
-
-OSStatus qt_mac_menu_event(EventHandlerCallRef er, EventRef event, void *)
-{
- QScopedLoopLevelCounter loopLevelCounter(QApplicationPrivate::instance()->threadData);
-
- bool handled_event = true;
- UInt32 ekind = GetEventKind(event), eclass = GetEventClass(event);
- switch(eclass) {
- case kEventClassCommand:
- if (ekind == kEventCommandProcess) {
- UInt32 context;
- GetEventParameter(event, kEventParamMenuContext, typeUInt32,
- 0, sizeof(context), 0, &context);
- HICommand cmd;
- GetEventParameter(event, kEventParamDirectObject, typeHICommand,
- 0, sizeof(cmd), 0, &cmd);
- if (!mac_keyboard_grabber && (context & kMenuContextKeyMatching)) {
- QMacMenuAction *action = 0;
- if (GetMenuCommandProperty(cmd.menu.menuRef, cmd.commandID, kMenuCreatorQt,
- kMenuPropertyQAction, sizeof(action), 0, &action) == noErr) {
- QWidget *widget = 0;
- if (qApp->activePopupWidget())
- widget = (qApp->activePopupWidget()->focusWidget() ?
- qApp->activePopupWidget()->focusWidget() : qApp->activePopupWidget());
- else if (QApplicationPrivate::focus_widget)
- widget = QApplicationPrivate::focus_widget;
- if (widget) {
- int key = action->action->shortcut();
- QKeyEvent accel_ev(QEvent::ShortcutOverride, (key & (~Qt::KeyboardModifierMask)),
- Qt::KeyboardModifiers(key & Qt::KeyboardModifierMask));
- accel_ev.ignore();
- qt_sendSpontaneousEvent(widget, &accel_ev);
- if (accel_ev.isAccepted()) {
- handled_event = false;
- break;
- }
- }
- }
- }
- handled_event = qt_mac_activate_action(cmd.menu.menuRef, cmd.commandID,
- QAction::Trigger, context & kMenuContextKeyMatching);
- }
- break;
- case kEventClassMenu: {
- MenuRef menu;
- GetEventParameter(event, kEventParamDirectObject, typeMenuRef, NULL, sizeof(menu), NULL, &menu);
- if (ekind == kEventMenuMatchKey) {
- // Don't activate any actions if we are showing a native modal dialog,
- // the key events should go to the dialog in this case.
- if (QApplicationPrivate::native_modal_dialog_active)
- return menuItemNotFoundErr;
-
- handled_event = false;
- } else if (ekind == kEventMenuTargetItem) {
- MenuCommand command;
- GetEventParameter(event, kEventParamMenuCommand, typeMenuCommand,
- 0, sizeof(command), 0, &command);
- handled_event = qt_mac_activate_action(menu, command, QAction::Hover, false);
- } else if (ekind == kEventMenuOpening || ekind == kEventMenuClosed) {
- qt_mac_menus_open_count += (ekind == kEventMenuOpening) ? 1 : -1;
- MenuRef mr;
- GetEventParameter(event, kEventParamDirectObject, typeMenuRef,
- 0, sizeof(mr), 0, &mr);
-
- QWidget *widget = 0;
- if (GetMenuItemProperty(mr, 0, kMenuCreatorQt, kMenuPropertyQWidget, sizeof(widget), 0, &widget) == noErr) {
- if (QMenu *qmenu = qobject_cast<QMenu*>(widget)) {
- handled_event = true;
- if (ekind == kEventMenuOpening) {
- emit qmenu->aboutToShow();
-
- int merged = 0;
- const QMenuPrivate::QMacMenuPrivate *mac_menu = qmenu->d_func()->mac_menu;
- const int ActionItemsCount = mac_menu->actionItems.size();
- for(int i = 0; i < ActionItemsCount; ++i) {
- QMacMenuAction *action = mac_menu->actionItems.at(i);
- if (action->action->isSeparator()) {
- bool hide = false;
- if(!action->action->isVisible()) {
- hide = true;
- } else if (merged && merged == i) {
- hide = true;
- } else {
- for(int l = i+1; l < mac_menu->actionItems.size(); ++l) {
- QMacMenuAction *action = mac_menu->actionItems.at(l);
- if (action->merged) {
- hide = true;
- } else if (action->action->isSeparator()) {
- if (hide)
- break;
- } else if (!action->merged) {
- hide = false;
- break;
- }
- }
- }
-
- const int index = qt_mac_menu_find_action(mr, action);
- if (hide) {
- ++merged;
- ChangeMenuItemAttributes(mr, index, kMenuItemAttrHidden, 0);
- } else {
- ChangeMenuItemAttributes(mr, index, 0, kMenuItemAttrHidden);
- }
- } else if (action->merged) {
- ++merged;
- }
- }
- } else {
- emit qmenu->aboutToHide();
- }
- }
- }
- } else {
- handled_event = false;
- }
- break; }
- default:
- handled_event = false;
- break;
- }
- if (!handled_event) //let the event go through
- return CallNextEventHandler(er, event);
- return noErr; //we eat the event
-}
-static EventHandlerRef mac_menu_event_handler = 0;
-static EventHandlerUPP mac_menu_eventUPP = 0;
-static void qt_mac_cleanup_menu_event()
-{
- if (mac_menu_event_handler) {
- RemoveEventHandler(mac_menu_event_handler);
- mac_menu_event_handler = 0;
- }
- if (mac_menu_eventUPP) {
- DisposeEventHandlerUPP(mac_menu_eventUPP);
- mac_menu_eventUPP = 0;
- }
-}
-static inline void qt_mac_create_menu_event_handler()
-{
- if (!mac_menu_event_handler) {
- mac_menu_eventUPP = NewEventHandlerUPP(qt_mac_menu_event);
- InstallEventHandler(GetApplicationEventTarget(), mac_menu_eventUPP,
- GetEventTypeCount(menu_events), menu_events, 0,
- &mac_menu_event_handler);
- qAddPostRoutine(qt_mac_cleanup_menu_event);
- }
-}
-
-
-//enabling of commands
-static void qt_mac_command_set_enabled(MenuRef menu, UInt32 cmd, bool b)
-{
- if (cmd == kHICommandQuit)
- qt_mac_quit_menu_item_enabled = b;
-
- if (b) {
- EnableMenuCommand(menu, cmd);
- if (MenuRef dock_menu = GetApplicationDockTileMenu())
- EnableMenuCommand(dock_menu, cmd);
- } else {
- DisableMenuCommand(menu, cmd);
- if (MenuRef dock_menu = GetApplicationDockTileMenu())
- DisableMenuCommand(dock_menu, cmd);
- }
-}
-
-static bool qt_mac_auto_apple_menu(MenuCommand cmd)
-{
- return (cmd == kHICommandPreferences || cmd == kHICommandQuit);
-}
-
-static void qt_mac_get_accel(quint32 accel_key, quint32 *modif, quint32 *key) {
- if (modif) {
- *modif = constructModifierMask(accel_key);
- }
-
- accel_key &= ~(Qt::MODIFIER_MASK | Qt::UNICODE_ACCEL);
- if (key) {
- *key = 0;
- if (accel_key == Qt::Key_Return)
- *key = kMenuReturnGlyph;
- else if (accel_key == Qt::Key_Enter)
- *key = kMenuEnterGlyph;
- else if (accel_key == Qt::Key_Tab)
- *key = kMenuTabRightGlyph;
- else if (accel_key == Qt::Key_Backspace)
- *key = kMenuDeleteLeftGlyph;
- else if (accel_key == Qt::Key_Delete)
- *key = kMenuDeleteRightGlyph;
- else if (accel_key == Qt::Key_Escape)
- *key = kMenuEscapeGlyph;
- else if (accel_key == Qt::Key_PageUp)
- *key = kMenuPageUpGlyph;
- else if (accel_key == Qt::Key_PageDown)
- *key = kMenuPageDownGlyph;
- else if (accel_key == Qt::Key_Up)
- *key = kMenuUpArrowGlyph;
- else if (accel_key == Qt::Key_Down)
- *key = kMenuDownArrowGlyph;
- else if (accel_key == Qt::Key_Left)
- *key = kMenuLeftArrowGlyph;
- else if (accel_key == Qt::Key_Right)
- *key = kMenuRightArrowGlyph;
- else if (accel_key == Qt::Key_CapsLock)
- *key = kMenuCapsLockGlyph;
- else if (accel_key >= Qt::Key_F1 && accel_key <= Qt::Key_F15)
- *key = (accel_key - Qt::Key_F1) + kMenuF1Glyph;
- else if (accel_key == Qt::Key_Home)
- *key = kMenuNorthwestArrowGlyph;
- else if (accel_key == Qt::Key_End)
- *key = kMenuSoutheastArrowGlyph;
- }
-}
-#else // Cocoa
-static inline void syncNSMenuItemVisiblity(NSMenuItem *menuItem, bool actionVisibility)
-{
- [menuItem setHidden:NO];
- [menuItem setHidden:YES];
- [menuItem setHidden:!actionVisibility];
-}
-
-static inline void syncNSMenuItemEnabled(NSMenuItem *menuItem, bool enabled)
-{
- [menuItem setEnabled:NO];
- [menuItem setEnabled:YES];
- [menuItem setEnabled:enabled];
-}
-
-static inline void syncMenuBarItemsVisiblity(const QMenuBarPrivate::QMacMenuBarPrivate *mac_menubar)
-{
- const QList<QMacMenuAction *> &menubarActions = mac_menubar->actionItems;
- for (int i = 0; i < menubarActions.size(); ++i) {
- const QMacMenuAction *action = menubarActions.at(i);
- syncNSMenuItemVisiblity(action->menuItem, actualMenuItemVisibility(mac_menubar, action));
- }
-}
-
-static inline QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *getMenuLoader()
-{
- return [NSApp QT_MANGLE_NAMESPACE(qt_qcocoamenuLoader)];
-}
-
-static NSMenuItem *createNSMenuItem(const QString &title)
-{
- NSMenuItem *item = [[NSMenuItem alloc]
- initWithTitle:qt_mac_QStringToNSString(title)
- action:@selector(qtDispatcherToQAction:) keyEquivalent:@""];
- [item setTarget:nil];
- return item;
-}
-#endif
-
-
-
-// helper that recurses into a menu structure and en/dis-ables them
-void qt_mac_set_modal_state_helper_recursive(OSMenuRef menu, OSMenuRef merge, bool on)
-{
-#ifndef QT_MAC_USE_COCOA
- for (int i = 0; i < CountMenuItems(menu); i++) {
- OSMenuRef submenu;
- GetMenuItemHierarchicalMenu(menu, i+1, &submenu);
- if (submenu != merge) {
- if (submenu)
- qt_mac_set_modal_state_helper_recursive(submenu, merge, on);
- if (on)
- DisableMenuItem(submenu, 0);
- else
- EnableMenuItem(submenu, 0);
- }
- }
-#else
- bool modalWindowOnScreen = qApp->activeModalWidget() != 0;
- for (NSMenuItem *item in [menu itemArray]) {
- OSMenuRef submenu = [item submenu];
- if (submenu != merge) {
- if (submenu)
- qt_mac_set_modal_state_helper_recursive(submenu, merge, on);
- if (!on) {
- // The item should follow what the QAction has.
- if ([item tag]) {
- QAction *action = reinterpret_cast<QAction *>([item tag]);
- syncNSMenuItemEnabled(item, action->isEnabled());
- } else {
- syncNSMenuItemEnabled(item, YES);
- }
- // We sneak in some extra code here to handle a menu problem:
- // If there is no window on screen, we cannot set 'nil' as
- // menu item target, because then cocoa will disable the item
- // (guess it assumes that there will be no first responder to
- // catch the trigger anyway?) OTOH, If we have a modal window,
- // then setting the menu loader as target will make cocoa not
- // deliver the trigger because the loader is then seen as modally
- // shaddowed). So either way there are shortcomings. Instead, we
- // decide the target as late as possible:
- [item setTarget:modalWindowOnScreen ? nil : getMenuLoader()];
- } else {
- syncNSMenuItemEnabled(item, NO);
- }
- }
- }
-#endif
-}
-
-//toggling of modal state
-static void qt_mac_set_modal_state(OSMenuRef menu, bool on)
-{
-#ifndef QT_MAC_USE_COCOA
- OSMenuRef merge = 0;
- GetMenuItemProperty(menu, 0, kMenuCreatorQt, kMenuPropertyMergeMenu,
- sizeof(merge), 0, &merge);
-
- qt_mac_set_modal_state_helper_recursive(menu, merge, on);
-
- UInt32 commands[] = { kHICommandQuit, kHICommandPreferences, kHICommandAbout, kHICommandAboutQt, 0 };
- for(int c = 0; commands[c]; c++) {
- bool enabled = !on;
- if (enabled) {
- QMacMenuAction *action = 0;
- GetMenuCommandProperty(menu, commands[c], kMenuCreatorQt, kMenuPropertyQAction,
- sizeof(action), 0, &action);
- if (!action && merge) {
- GetMenuCommandProperty(merge, commands[c], kMenuCreatorQt, kMenuPropertyQAction,
- sizeof(action), 0, &action);
- if (!action) {
- QMenuMergeList *list = 0;
- GetMenuItemProperty(merge, 0, kMenuCreatorQt, kMenuPropertyMergeList,
- sizeof(list), 0, &list);
- for(int i = 0; list && i < list->size(); ++i) {
- QMenuMergeItem item = list->at(i);
- if (item.command == commands[c] && item.action) {
- action = item.action;
- break;
- }
- }
- }
- }
-
- if (!action) {
- if (commands[c] != kHICommandQuit)
- enabled = false;
- } else {
- enabled = action->action ? action->action->isEnabled() : 0;
- }
- }
- qt_mac_command_set_enabled(menu, commands[c], enabled);
- }
-#else
- OSMenuRef merge = QMenuPrivate::mergeMenuHash.value(menu);
- qt_mac_set_modal_state_helper_recursive(menu, merge, on);
- // I'm ignoring the special items now, since they should get handled via a syncAction()
-#endif
-}
-
-bool qt_mac_menubar_is_open()
-{
- return qt_mac_menus_open_count > 0;
-}
-
-QMacMenuAction::~QMacMenuAction()
-{
-#ifdef QT_MAC_USE_COCOA
- [menu release];
- // Update the menu item if this action still owns it. For some items
- // (like 'Quit') ownership will be transferred between all menu bars...
- if (action && action.data() == reinterpret_cast<QAction *>([menuItem tag])) {
- QAction::MenuRole role = action->menuRole();
- // Check if the item is owned by Qt, and should be hidden to keep it from causing
- // problems. Do it for everything but the quit menu item since that should always
- // be visible.
- if (role > QAction::ApplicationSpecificRole && role < QAction::QuitRole) {
- [menuItem setHidden:YES];
- } else if (role == QAction::TextHeuristicRole
- && menuItem != [getMenuLoader() quitMenuItem]) {
- [menuItem setHidden:YES];
- }
- [menuItem setTag:nil];
- }
- [menuItem release];
-#endif
-}
-
-#ifndef QT_MAC_USE_COCOA
-static MenuCommand qt_mac_menu_merge_action(MenuRef merge, QMacMenuAction *action)
-#else
-static NSMenuItem *qt_mac_menu_merge_action(OSMenuRef merge, QMacMenuAction *action)
-#endif
-{
- if (qt_mac_no_menubar_merge || action->action->menu() || action->action->isSeparator()
- || action->action->menuRole() == QAction::NoRole)
- return 0;
-
- QString t = qt_mac_removeMnemonics(action->action->text().toLower());
- int st = t.lastIndexOf(QLatin1Char('\t'));
- if (st != -1)
- t.remove(st, t.length()-st);
- t.replace(QRegExp(QString::fromLatin1("\\.*$")), QLatin1String("")); //no ellipses
- //now the fun part
-#ifndef QT_MAC_USE_COCOA
- MenuCommand ret = 0;
-#else
- NSMenuItem *ret = 0;
- QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader();
-#endif
- switch (action->action->menuRole()) {
- case QAction::NoRole:
- ret = 0;
- break;
- case QAction::ApplicationSpecificRole:
-#ifndef QT_MAC_USE_COCOA
- {
- QMenuMergeList *list = 0;
- if (GetMenuItemProperty(merge, 0, kMenuCreatorQt, kMenuPropertyMergeList,
- sizeof(list), 0, &list) == noErr && list) {
- MenuCommand lastCustom = kHICommandCustomMerge;
- for(int i = 0; i < list->size(); ++i) {
- QMenuMergeItem item = list->at(i);
- if (item.command == lastCustom)
- ++lastCustom;
- }
- ret = lastCustom;
- } else {
- // The list hasn't been created, so, must be the first one.
- ret = kHICommandCustomMerge;
- }
- }
-#else
- ret = [loader appSpecificMenuItem];
-#endif
- break;
- case QAction::AboutRole:
-#ifndef QT_MAC_USE_COCOA
- ret = kHICommandAbout;
-#else
- ret = [loader aboutMenuItem];
-#endif
- break;
- case QAction::AboutQtRole:
-#ifndef QT_MAC_USE_COCOA
- ret = kHICommandAboutQt;
-#else
- ret = [loader aboutQtMenuItem];
-#endif
- break;
- case QAction::QuitRole:
-#ifndef QT_MAC_USE_COCOA
- ret = kHICommandQuit;
-#else
- ret = [loader quitMenuItem];
-#endif
- break;
- case QAction::PreferencesRole:
-#ifndef QT_MAC_USE_COCOA
- ret = kHICommandPreferences;
-#else
- ret = [loader preferencesMenuItem];
-#endif
- break;
- case QAction::TextHeuristicRole: {
- QString aboutString = QMenuBar::tr("About").toLower();
- if (t.startsWith(aboutString) || t.endsWith(aboutString)) {
- if (t.indexOf(QRegExp(QString::fromLatin1("qt$"), Qt::CaseInsensitive)) == -1) {
-#ifndef QT_MAC_USE_COCOA
- ret = kHICommandAbout;
-#else
- ret = [loader aboutMenuItem];
-#endif
- } else {
-#ifndef QT_MAC_USE_COCOA
- ret = kHICommandAboutQt;
-#else
- ret = [loader aboutQtMenuItem];
-#endif
- }
- } else if (t.startsWith(QMenuBar::tr("Config").toLower())
- || t.startsWith(QMenuBar::tr("Preference").toLower())
- || t.startsWith(QMenuBar::tr("Options").toLower())
- || t.startsWith(QMenuBar::tr("Setting").toLower())
- || t.startsWith(QMenuBar::tr("Setup").toLower())) {
-#ifndef QT_MAC_USE_COCOA
- ret = kHICommandPreferences;
-#else
- ret = [loader preferencesMenuItem];
-#endif
- } else if (t.startsWith(QMenuBar::tr("Quit").toLower())
- || t.startsWith(QMenuBar::tr("Exit").toLower())) {
-#ifndef QT_MAC_USE_COCOA
- ret = kHICommandQuit;
-#else
- ret = [loader quitMenuItem];
-#endif
- }
- }
- break;
- }
-
-#ifndef QT_MAC_USE_COCOA
- QMenuMergeList *list = 0;
- if (GetMenuItemProperty(merge, 0, kMenuCreatorQt, kMenuPropertyMergeList,
- sizeof(list), 0, &list) == noErr && list) {
- for(int i = 0; i < list->size(); ++i) {
- QMenuMergeItem item = list->at(i);
- if (item.command == ret && item.action)
- return 0;
- }
- }
-
- QAction *cmd_action = 0;
- if (GetMenuCommandProperty(merge, ret, kMenuCreatorQt, kMenuPropertyQAction,
- sizeof(cmd_action), 0, &cmd_action) == noErr && cmd_action)
- return 0; //already taken
-#else
- if (QMenuMergeList *list = QMenuPrivate::mergeMenuItemsHash.value(merge)) {
- for(int i = 0; i < list->size(); ++i) {
- const QMenuMergeItem &item = list->at(i);
- if (item.menuItem == ret && item.action)
- return 0;
- }
- }
-
-#endif
- return ret;
-}
-
-static QString qt_mac_menu_merge_text(QMacMenuAction *action)
-{
- QString ret;
- extern QString qt_mac_applicationmenu_string(int type);
-#ifdef QT_MAC_USE_COCOA
- QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader();
-#endif
- if (action->action->menuRole() == QAction::ApplicationSpecificRole)
- ret = action->action->text();
-#ifndef QT_MAC_USE_COCOA
- else if (action->command == kHICommandAbout)
- ret = qt_mac_applicationmenu_string(6).arg(qAppName());
- else if (action->command == kHICommandAboutQt)
- ret = QMenuBar::tr("About Qt");
- else if (action->command == kHICommandPreferences)
- ret = qt_mac_applicationmenu_string(4);
- else if (action->command == kHICommandQuit)
- ret = qt_mac_applicationmenu_string(5).arg(qAppName());
-#else
- else if (action->menuItem == [loader aboutMenuItem]) {
- ret = qt_mac_applicationmenu_string(6).arg(qAppName());
- } else if (action->menuItem == [loader aboutQtMenuItem]) {
- if (action->action->text() == QString("About Qt"))
- ret = QMenuBar::tr("About Qt");
- else
- ret = action->action->text();
- } else if (action->menuItem == [loader preferencesMenuItem]) {
- ret = qt_mac_applicationmenu_string(4);
- } else if (action->menuItem == [loader quitMenuItem]) {
- ret = qt_mac_applicationmenu_string(5).arg(qAppName());
- }
-#endif
- return ret;
-}
-
-static QKeySequence qt_mac_menu_merge_accel(QMacMenuAction *action)
-{
- QKeySequence ret;
-#ifdef QT_MAC_USE_COCOA
- QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader();
-#endif
- if (action->action->menuRole() == QAction::ApplicationSpecificRole)
- ret = action->action->shortcut();
-#ifndef QT_MAC_USE_COCOA
- else if (action->command == kHICommandPreferences)
- ret = QKeySequence(QKeySequence::Preferences);
- else if (action->command == kHICommandQuit)
- ret = QKeySequence(QKeySequence::Quit);
-#else
- else if (action->menuItem == [loader preferencesMenuItem])
- ret = QKeySequence(QKeySequence::Preferences);
- else if (action->menuItem == [loader quitMenuItem])
- ret = QKeySequence(QKeySequence::Quit);
-#endif
- return ret;
-}
-
-void Q_GUI_EXPORT qt_mac_set_menubar_icons(bool b)
-{ QApplication::instance()->setAttribute(Qt::AA_DontShowIconsInMenus, !b); }
-void Q_GUI_EXPORT qt_mac_set_native_menubar(bool b)
-{ QApplication::instance()->setAttribute(Qt::AA_DontUseNativeMenuBar, !b); }
-void Q_GUI_EXPORT qt_mac_set_menubar_merge(bool b) { qt_mac_no_menubar_merge = !b; }
-
-/*****************************************************************************
- QMenu bindings
- *****************************************************************************/
-QMenuPrivate::QMacMenuPrivate::QMacMenuPrivate() : menu(0)
-{
-}
-
-QMenuPrivate::QMacMenuPrivate::~QMacMenuPrivate()
-{
-#ifndef QT_MAC_USE_COCOA
- for(QList<QMacMenuAction*>::Iterator it = actionItems.begin(); it != actionItems.end(); ++it) {
- QMacMenuAction *action = (*it);
- RemoveMenuCommandProperty(action->menu, action->command, kMenuCreatorQt, kMenuPropertyQAction);
- if (action->merged) {
- QMenuMergeList *list = 0;
- GetMenuItemProperty(action->menu, 0, kMenuCreatorQt, kMenuPropertyMergeList,
- sizeof(list), 0, &list);
- for(int i = 0; list && i < list->size(); ) {
- QMenuMergeItem item = list->at(i);
- if (item.action == action)
- list->removeAt(i);
- else
- ++i;
- }
- }
- delete action;
- }
- if (menu) {
- EventHandlerHash::iterator it = menu_eventHandlers_hash()->find(menu);
- while (it != menu_eventHandlers_hash()->end() && it.key() == menu) {
- RemoveEventHandler(it.value());
- ++it;
- }
- menu_eventHandlers_hash()->remove(menu);
- ReleaseMenu(menu);
- }
-#else
- QMacCocoaAutoReleasePool pool;
- while (actionItems.size()) {
- QMacMenuAction *action = actionItems.takeFirst();
- if (QMenuMergeList *list = mergeMenuItemsHash.value(action->menu)) {
- int i = 0;
- while (i < list->size()) {
- const QMenuMergeItem &item = list->at(i);
- if (item.action == action)
- list->removeAt(i);
- else
- ++i;
- }
- }
- delete action;
- }
- mergeMenuHash.remove(menu);
- mergeMenuItemsHash.remove(menu);
- [menu release];
-#endif
-}
-
-void
-QMenuPrivate::QMacMenuPrivate::addAction(QAction *a, QMacMenuAction *before, QMenuPrivate *qmenu)
-{
- QMacMenuAction *action = new QMacMenuAction;
- action->action = a;
- action->ignore_accel = 0;
- action->merged = 0;
- action->menu = 0;
-#ifndef QT_MAC_USE_COCOA
- action->command = qt_mac_menu_static_cmd_id++;
-#endif
- addAction(action, before, qmenu);
-}
-
-void
-QMenuPrivate::QMacMenuPrivate::addAction(QMacMenuAction *action, QMacMenuAction *before, QMenuPrivate *qmenu)
-{
-#ifdef QT_MAC_USE_COCOA
- QMacCocoaAutoReleasePool pool;
- Q_UNUSED(qmenu);
-#endif
- if (!action)
- return;
- int before_index = actionItems.indexOf(before);
- if (before_index < 0) {
- before = 0;
- before_index = actionItems.size();
- }
- actionItems.insert(before_index, action);
-
-#ifndef QT_MAC_USE_COCOA
- int index = qt_mac_menu_find_action(menu, action);
-#else
- [menu retain];
- [action->menu release];
-#endif
- action->menu = menu;
-
- /* When the action is considered a mergable action it
- will stay that way, until removed.. */
- if (!qt_mac_no_menubar_merge) {
-#ifndef QT_MAC_USE_COCOA
- MenuRef merge = 0;
- GetMenuItemProperty(menu, 0, kMenuCreatorQt, kMenuPropertyMergeMenu,
- sizeof(merge), 0, &merge);
-#else
- OSMenuRef merge = QMenuPrivate::mergeMenuHash.value(menu);
-#endif
- if (merge) {
-#ifndef QT_MAC_USE_COCOA
- if (MenuCommand cmd = qt_mac_menu_merge_action(merge, action)) {
- action->merged = 1;
- action->menu = merge;
- action->command = cmd;
- if (qt_mac_auto_apple_menu(cmd))
- index = 0; //no need
-
- QMenuMergeList *list = 0;
- if (GetMenuItemProperty(merge, 0, kMenuCreatorQt, kMenuPropertyMergeList,
- sizeof(list), 0, &list) != noErr || !list) {
- list = new QMenuMergeList;
- SetMenuItemProperty(merge, 0, kMenuCreatorQt, kMenuPropertyMergeList,
- sizeof(list), &list);
- }
- list->append(QMenuMergeItem(cmd, action));
- }
-#else
- if (NSMenuItem *cmd = qt_mac_menu_merge_action(merge, action)) {
- action->merged = 1;
- [merge retain];
- [action->menu release];
- action->menu = merge;
- [cmd retain];
- [cmd setAction:@selector(qtDispatcherToQAction:)];
- [cmd setTarget:nil];
- [action->menuItem release];
- action->menuItem = cmd;
- QMenuMergeList *list = QMenuPrivate::mergeMenuItemsHash.value(merge);
- if (!list) {
- list = new QMenuMergeList;
- QMenuPrivate::mergeMenuItemsHash.insert(merge, list);
- }
- list->append(QMenuMergeItem(cmd, action));
- }
-#endif
- }
- }
-
-#ifdef QT_MAC_USE_COCOA
- NSMenuItem *newItem = action->menuItem;
-#endif
- if (
-#ifndef QT_MAC_USE_COCOA
- index == -1
-#else
- newItem == 0
-#endif
- ) {
-#ifndef QT_MAC_USE_COCOA
- index = before_index;
- MenuItemAttributes attr = kMenuItemAttrAutoRepeat;
-#else
- newItem = createNSMenuItem(action->action->text());
- action->menuItem = newItem;
-#endif
- if (before) {
-#ifndef QT_MAC_USE_COCOA
- InsertMenuItemTextWithCFString(action->menu, 0, qMax(before_index, 0), attr, action->command);
-#else
- [menu insertItem:newItem atIndex:qMax(before_index, 0)];
-#endif
- } else {
-#ifndef QT_MAC_USE_COCOA
- // Append the menu item to the menu. If it is a kHICommandAbout or a kHICommandAboutQt append
- // a separator also (to get a separator above "Preferences"), but make sure that we don't
- // add separators between two "about" items.
-
- // Build a set of all commands that could possibly be before the separator.
- QSet<MenuCommand> mergedItems;
- mergedItems.insert(kHICommandAbout);
- mergedItems.insert(kHICommandAboutQt);
- mergedItems.insert(kHICommandCustomMerge);
-
- QMenuMergeList *list = 0;
- if (GetMenuItemProperty(action->menu, 0, kMenuCreatorQt, kMenuPropertyMergeList,
- sizeof(list), 0, &list) == noErr && list) {
- for (int i = 0; i < list->size(); ++i) {
- MenuCommand command = list->at(i).command;
- if (command > kHICommandCustomMerge) {
- mergedItems.insert(command);
- }
- }
- }
-
- const int itemCount = CountMenuItems(action->menu);
- MenuItemAttributes testattr;
- GetMenuItemAttributes(action->menu, itemCount , &testattr);
- if (mergedItems.contains(action->command)
- && (testattr & kMenuItemAttrSeparator)) {
- InsertMenuItemTextWithCFString(action->menu, 0, qMax(itemCount - 1, 0), attr, action->command);
- index = itemCount;
- } else {
- MenuItemIndex tmpIndex;
- AppendMenuItemTextWithCFString(action->menu, 0, attr, action->command, &tmpIndex);
- index = tmpIndex;
- if (mergedItems.contains(action->command))
- AppendMenuItemTextWithCFString(action->menu, 0, kMenuItemAttrSeparator, 0, &tmpIndex);
- }
-#else
- [menu addItem:newItem];
-#endif
- }
-
- QWidget *widget = qmenu ? qmenu->widgetItems.value(action->action) : 0;
- if (widget) {
-#ifndef QT_MAC_USE_COCOA
- ChangeMenuAttributes(action->menu, kMenuAttrDoNotCacheImage, 0);
- attr = kMenuItemAttrCustomDraw;
- SetMenuItemProperty(action->menu, index, kMenuCreatorQt, kMenuPropertyWidgetActionWidget,
- sizeof(QWidget *), &widget);
- HIViewRef content;
- HIMenuGetContentView(action->menu, kThemeMenuTypePullDown, &content);
-
- EventHandlerRef eventHandlerRef;
- InstallMenuEventHandler(action->menu, qt_mac_widget_in_menu_eventHandler,
- GetEventTypeCount(widget_in_menu_events),
- widget_in_menu_events, 0, &eventHandlerRef);
- menu_eventHandlers_hash()->insert(action->menu, eventHandlerRef);
-
- QWidget *menuWidget = 0;
- GetMenuItemProperty(action->menu, 0, kMenuCreatorQt, kMenuPropertyWidgetMenu,
- sizeof(menuWidget), 0, &menuWidget);
- if(!menuWidget) {
- menuWidget = new QMacNativeWidget(content);
- SetMenuItemProperty(menu, 0, kMenuCreatorQt, kMenuPropertyWidgetMenu,
- sizeof(menuWidget), &menuWidget);
- menuWidget->show();
- }
- widget->setParent(menuWidget);
-#else
- QMacNativeWidget *container = new QMacNativeWidget(0);
- container->resize(widget->sizeHint());
- widget->setAttribute(Qt::WA_LayoutUsesWidgetRect);
- widget->setParent(container);
-
- NSView *containerView = qt_mac_nativeview_for(container);
- [containerView setAutoresizesSubviews:YES];
- [containerView setAutoresizingMask:NSViewWidthSizable];
- [qt_mac_nativeview_for(widget) setAutoresizingMask:NSViewWidthSizable];
-
- [newItem setView:containerView];
- container->show();
-#endif
- widget->show();
- }
-
- } else {
-#ifndef QT_MAC_USE_COCOA
- qt_mac_command_set_enabled(action->menu, action->command, !QApplicationPrivate::modalState());
-#else
- [newItem setEnabled:!QApplicationPrivate::modalState()];
-#endif
- }
-#ifndef QT_MAC_USE_COCOA
- SetMenuCommandProperty(action->menu, action->command, kMenuCreatorQt, kMenuPropertyQAction,
- sizeof(action), &action);
-#else
- [newItem setTag:long(static_cast<QAction *>(action->action))];
-#endif
- syncAction(action);
-}
-
-// return an autoreleased string given a QKeySequence (currently only looks at the first one).
-NSString *keySequenceToKeyEqivalent(const QKeySequence &accel)
-{
- quint32 accel_key = (accel[0] & ~(Qt::MODIFIER_MASK | Qt::UNICODE_ACCEL));
- extern QChar qtKey2CocoaKey(Qt::Key key);
- QChar cocoa_key = qtKey2CocoaKey(Qt::Key(accel_key));
- if (cocoa_key.isNull())
- cocoa_key = QChar(accel_key).toLower().unicode();
- return [NSString stringWithCharacters:&cocoa_key.unicode() length:1];
-}
-
-// return the cocoa modifier mask for the QKeySequence (currently only looks at the first one).
-NSUInteger keySequenceModifierMask(const QKeySequence &accel)
-{
- return constructModifierMask(accel[0]);
-}
-
-void
-QMenuPrivate::QMacMenuPrivate::syncAction(QMacMenuAction *action)
-{
- if (!action)
- return;
-
-#ifndef QT_MAC_USE_COCOA
- const int index = qt_mac_menu_find_action(action->menu, action);
- if (index == -1)
- return;
-#else
- NSMenuItem *item = action->menuItem;
- if (!item)
- return;
-#endif
-
-#ifndef QT_MAC_USE_COCOA
- if (!action->action->isVisible()) {
- ChangeMenuItemAttributes(action->menu, index, kMenuItemAttrHidden, 0);
- return;
- }
- ChangeMenuItemAttributes(action->menu, index, 0, kMenuItemAttrHidden);
-#else
- QMacCocoaAutoReleasePool pool;
- NSMenu *menu = [item menu];
- bool actionVisible = action->action->isVisible();
- [item setHidden:!actionVisible];
- if (!actionVisible)
- return;
-#endif
-
-#ifndef QT_MAC_USE_COCOA
- if (action->action->isSeparator()) {
- ChangeMenuItemAttributes(action->menu, index, kMenuItemAttrSeparator, 0);
- return;
- }
- ChangeMenuItemAttributes(action->menu, index, 0, kMenuItemAttrSeparator);
-#else
- int itemIndex = [menu indexOfItem:item];
- Q_ASSERT(itemIndex != -1);
- if (action->action->isSeparator()) {
- action->menuItem = [NSMenuItem separatorItem];
- [action->menuItem retain];
- [menu insertItem: action->menuItem atIndex:itemIndex];
- [menu removeItem:item];
- [item release];
- item = action->menuItem;
- return;
- } else if ([item isSeparatorItem]) {
- // I'm no longer a separator...
- action->menuItem = createNSMenuItem(action->action->text());
- [menu insertItem:action->menuItem atIndex:itemIndex];
- [menu removeItem:item];
- [item release];
- item = action->menuItem;
- }
-#endif
-
- //find text (and accel)
- action->ignore_accel = 0;
- QString text = action->action->text();
- QKeySequence accel = action->action->shortcut();
- {
- int st = text.lastIndexOf(QLatin1Char('\t'));
- if (st != -1) {
- action->ignore_accel = 1;
- accel = QKeySequence(text.right(text.length()-(st+1)));
- text.remove(st, text.length()-st);
- }
- }
- {
- QString cmd_text = qt_mac_menu_merge_text(action);
- if (!cmd_text.isEmpty()) {
- text = cmd_text;
- accel = qt_mac_menu_merge_accel(action);
- }
- }
- // Show multiple key sequences as part of the menu text.
- if (accel.count() > 1)
- text += QLatin1String(" (") + accel.toString(QKeySequence::NativeText) + QLatin1String(")");
-
- QString finalString = qt_mac_removeMnemonics(text);
-
-#ifndef QT_MAC_USE_COCOA
- MenuItemDataRec data;
- memset(&data, '\0', sizeof(data));
-
- //Carbon text
- data.whichData |= kMenuItemDataCFString;
- QCFString cfstring(finalString); // Hold the reference to the end of the function.
- data.cfText = cfstring;
-
- // Carbon enabled
- data.whichData |= kMenuItemDataEnabled;
- data.enabled = action->action->isEnabled();
- // Carbon icon
- data.whichData |= kMenuItemDataIconHandle;
- if (!action->action->icon().isNull()
- && action->action->isIconVisibleInMenu()) {
- data.iconType = kMenuIconRefType;
- data.iconHandle = (Handle)qt_mac_create_iconref(action->action->icon().pixmap(16, QIcon::Normal));
- } else {
- data.iconType = kMenuNoIcon;
- }
- if (action->action->font().resolve()) { // Carbon font
- if (action->action->font().bold())
- data.style |= bold;
- if (action->action->font().underline())
- data.style |= underline;
- if (action->action->font().italic())
- data.style |= italic;
- if (data.style)
- data.whichData |= kMenuItemDataStyle;
- data.whichData |= kMenuItemDataFontID;
- data.fontID = action->action->font().macFontID();
- }
-#else
- // Cocoa Font and title
- if (action->action->font().resolve()) {
- const QFont &actionFont = action->action->font();
- NSFont *customMenuFont = [NSFont fontWithName:qt_mac_QStringToNSString(actionFont.family())
- size:actionFont.pointSize()];
- NSArray *keys = [NSArray arrayWithObjects:NSFontAttributeName, nil];
- NSArray *objects = [NSArray arrayWithObjects:customMenuFont, nil];
- NSDictionary *attributes = [NSDictionary dictionaryWithObjects:objects forKeys:keys];
- NSAttributedString *str = [[[NSAttributedString alloc] initWithString:qt_mac_QStringToNSString(finalString)
- attributes:attributes] autorelease];
- [item setAttributedTitle: str];
- } else {
- [item setTitle: qt_mac_QStringToNSString(finalString)];
- }
-
- if (action->action->menuRole() == QAction::AboutRole || action->action->menuRole() == QAction::QuitRole)
- [item setTitle:qt_mac_QStringToNSString(text)];
- else
- [item setTitle:qt_mac_QStringToNSString(qt_mac_removeMnemonics(text))];
-
- // Cocoa Enabled
- [item setEnabled: action->action->isEnabled()];
-
- // Cocoa icon
- NSImage *nsimage = 0;
- if (!action->action->icon().isNull() && action->action->isIconVisibleInMenu()) {
- nsimage = static_cast<NSImage *>(qt_mac_create_nsimage(action->action->icon().pixmap(16, QIcon::Normal)));
- }
- [item setImage:nsimage];
- [nsimage release];
-#endif
-
- if (action->action->menu()) { //submenu
-#ifndef QT_MAC_USE_COCOA
- data.whichData |= kMenuItemDataSubmenuHandle;
- data.submenuHandle = action->action->menu()->macMenu();
- QWidget *caused = 0;
- GetMenuItemProperty(action->menu, 0, kMenuCreatorQt, kMenuPropertyQWidget, sizeof(caused), 0, &caused);
- SetMenuItemProperty(data.submenuHandle, 0, kMenuCreatorQt, kMenuPropertyCausedQWidget, sizeof(caused), &caused);
-#else
- NSMenu *subMenu = static_cast<NSMenu *>(action->action->menu()->macMenu());
- if ([subMenu supermenu] && [subMenu supermenu] != [item menu]) {
- // The menu is already a sub-menu of another one. Cocoa will throw an exception,
- // in such cases. For the time being, a new QMenu with same set of actions is the
- // only workaround.
- action->action->setEnabled(false);
- } else {
- [item setSubmenu:subMenu];
- }
-#endif
- } else { //respect some other items
-#ifndef QT_MAC_USE_COCOA
- //shortcuts (say we are setting them all so that we can also clear them).
- data.whichData |= kMenuItemDataCmdKey;
- data.whichData |= kMenuItemDataCmdKeyModifiers;
- data.whichData |= kMenuItemDataCmdKeyGlyph;
- if (accel.count() == 1) {
- qt_mac_get_accel(accel[0], (quint32*)&data.cmdKeyModifiers, (quint32*)&data.cmdKeyGlyph);
- if (data.cmdKeyGlyph == 0)
- data.cmdKey = (UniChar)accel[0];
- }
-#else
- [item setSubmenu:0];
- // No key equivalent set for multiple key QKeySequence.
- if (accel.count() == 1) {
- [item setKeyEquivalent:keySequenceToKeyEqivalent(accel)];
- [item setKeyEquivalentModifierMask:keySequenceModifierMask(accel)];
- } else {
- [item setKeyEquivalent:@""];
- [item setKeyEquivalentModifierMask:NSCommandKeyMask];
- }
-#endif
- }
-#ifndef QT_MAC_USE_COCOA
- //mark glyph
- data.whichData |= kMenuItemDataMark;
- if (action->action->isChecked()) {
-#if 0
- if (action->action->actionGroup() &&
- action->action->actionGroup()->isExclusive())
- data.mark = diamondMark;
- else
-#endif
- data.mark = checkMark;
- } else {
- data.mark = noMark;
- }
-
- //actually set it
- SetMenuItemData(action->menu, action->command, true, &data);
-
- // Free up memory
- if (data.iconHandle)
- ReleaseIconRef(IconRef(data.iconHandle));
-#else
- //mark glyph
- [item setState:action->action->isChecked() ? NSOnState : NSOffState];
-#endif
-}
-
-void
-QMenuPrivate::QMacMenuPrivate::removeAction(QMacMenuAction *action)
-{
- if (!action)
- return;
-#ifndef QT_MAC_USE_COCOA
- if (action->command == kHICommandQuit || action->command == kHICommandPreferences)
- qt_mac_command_set_enabled(action->menu, action->command, false);
- else
- DeleteMenuItem(action->menu, qt_mac_menu_find_action(action->menu, action));
-#else
- QMacCocoaAutoReleasePool pool;
- if (action->merged) {
- if (reinterpret_cast<QAction *>([action->menuItem tag]) == action->action) {
- QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader();
- [action->menuItem setEnabled:false];
- if (action->menuItem != [loader quitMenuItem]
- && action->menuItem != [loader preferencesMenuItem]) {
- [[action->menuItem menu] removeItem:action->menuItem];
- }
- }
- } else {
- [[action->menuItem menu] removeItem:action->menuItem];
- }
-#endif
- actionItems.removeAll(action);
-}
-
-OSMenuRef
-QMenuPrivate::macMenu(OSMenuRef merge)
-{
- Q_UNUSED(merge);
- Q_Q(QMenu);
- if (mac_menu && mac_menu->menu)
- return mac_menu->menu;
- if (!mac_menu)
- mac_menu = new QMacMenuPrivate;
- mac_menu->menu = qt_mac_create_menu(q);
- if (merge) {
-#ifndef QT_MAC_USE_COCOA
- SetMenuItemProperty(mac_menu->menu, 0, kMenuCreatorQt, kMenuPropertyMergeMenu, sizeof(merge), &merge);
-#else
- mergeMenuHash.insert(mac_menu->menu, merge);
-#endif
- }
- QList<QAction*> items = q->actions();
- for(int i = 0; i < items.count(); i++)
- mac_menu->addAction(items[i], 0, this);
- syncSeparatorsCollapsible(collapsibleSeparators);
- return mac_menu->menu;
-}
-
-/*!
- \internal
-*/
-void
-QMenuPrivate::syncSeparatorsCollapsible(bool collapse)
-{
-#ifndef QT_MAC_USE_COCOA
- if (collapse)
- ChangeMenuAttributes(mac_menu->menu, kMenuAttrCondenseSeparators, 0);
- else
- ChangeMenuAttributes(mac_menu->menu, 0, kMenuAttrCondenseSeparators);
-#else
- qt_mac_menu_collapseSeparators(mac_menu->menu, collapse);
-#endif
-}
-
-
-
-/*!
- \internal
-*/
-void QMenuPrivate::setMacMenuEnabled(bool enable)
-{
- if (!macMenu(0))
- return;
-
- QMacCocoaAutoReleasePool pool;
- if (enable) {
- for (int i = 0; i < mac_menu->actionItems.count(); ++i) {
- QMacMenuAction *menuItem = mac_menu->actionItems.at(i);
- if (menuItem && menuItem->action && menuItem->action->isEnabled()) {
-#ifndef QT_MAC_USE_COCOA
- // Only enable those items which contains an enabled QAction.
- // i == 0 -> the menu itself, hence i + 1 for items.
- EnableMenuItem(mac_menu->menu, i + 1);
-#else
- [menuItem->menuItem setEnabled:true];
-#endif
- }
- }
- } else {
-#ifndef QT_MAC_USE_COCOA
- DisableAllMenuItems(mac_menu->menu);
-#else
- NSMenu *menu = mac_menu->menu;
- for (NSMenuItem *item in [menu itemArray]) {
- [item setEnabled:false];
- }
-#endif
- }
-}
-
-/*!
- \internal
-
- This function will return the OSMenuRef used to create the native menu bar
- bindings.
-
- If Qt is built against Carbon, the OSMenuRef is a MenuRef that can be used
- with Carbon's Menu Manager API.
-
- If Qt is built against Cocoa, the OSMenuRef is a NSMenu pointer.
-
- \warning This function is not portable.
-
- \sa QMenuBar::macMenu()
-*/
-OSMenuRef QMenu::macMenu(OSMenuRef merge) { return d_func()->macMenu(merge); }
-
-/*****************************************************************************
- QMenuBar bindings
- *****************************************************************************/
-typedef QHash<QWidget *, QMenuBar *> MenuBarHash;
-Q_GLOBAL_STATIC(MenuBarHash, menubars)
-static QMenuBar *fallback = 0;
-QMenuBarPrivate::QMacMenuBarPrivate::QMacMenuBarPrivate() : menu(0), apple_menu(0)
-{
-}
-
-QMenuBarPrivate::QMacMenuBarPrivate::~QMacMenuBarPrivate()
-{
- for(QList<QMacMenuAction*>::Iterator it = actionItems.begin(); it != actionItems.end(); ++it)
- delete (*it);
-#ifndef QT_MAC_USE_COCOA
- if (apple_menu) {
- QMenuMergeList *list = 0;
- GetMenuItemProperty(apple_menu, 0, kMenuCreatorQt, kMenuPropertyMergeList,
- sizeof(list), 0, &list);
- if (list) {
- RemoveMenuItemProperty(apple_menu, 0, kMenuCreatorQt, kMenuPropertyMergeList);
- delete list;
- }
- ReleaseMenu(apple_menu);
- }
- if (menu)
- ReleaseMenu(menu);
-#else
- [apple_menu release];
- [menu release];
-#endif
-}
-
-void
-QMenuBarPrivate::QMacMenuBarPrivate::addAction(QAction *a, QAction *before)
-{
- if (a->isSeparator() || !menu)
- return;
- QMacMenuAction *action = new QMacMenuAction;
- action->action = a;
- action->ignore_accel = 1;
-#ifndef QT_MAC_USE_COCOA
- action->command = qt_mac_menu_static_cmd_id++;
-#endif
- addAction(action, findAction(before));
-}
-
-void
-QMenuBarPrivate::QMacMenuBarPrivate::addAction(QMacMenuAction *action, QMacMenuAction *before)
-{
- if (!action || !menu)
- return;
-
- int before_index = actionItems.indexOf(before);
- if (before_index < 0) {
- before = 0;
- before_index = actionItems.size();
- }
- actionItems.insert(before_index, action);
-
- MenuItemIndex index = actionItems.size()-1;
-
- action->menu = menu;
-#ifdef QT_MAC_USE_COCOA
- QMacCocoaAutoReleasePool pool;
- [action->menu retain];
- NSMenuItem *newItem = createNSMenuItem(action->action->text());
- action->menuItem = newItem;
-#endif
- if (before) {
-#ifndef QT_MAC_USE_COCOA
- InsertMenuItemTextWithCFString(action->menu, 0, qMax(1, before_index+1), 0, action->command);
-#else
- [menu insertItem:newItem atIndex:qMax(1, before_index + 1)];
-#endif
- index = before_index;
- } else {
-#ifndef QT_MAC_USE_COCOA
- AppendMenuItemTextWithCFString(action->menu, 0, 0, action->command, &index);
-#else
- [menu addItem:newItem];
-#endif
- }
-#ifndef QT_MAC_USE_COCOA
- SetMenuItemProperty(action->menu, index, kMenuCreatorQt, kMenuPropertyQAction, sizeof(action),
- &action);
-#else
- [newItem setTag:long(static_cast<QAction *>(action->action))];
-#endif
- syncAction(action);
-}
-
-void
-QMenuBarPrivate::QMacMenuBarPrivate::syncAction(QMacMenuAction *action)
-{
- if (!action || !menu)
- return;
-#ifndef QT_MAC_USE_COCOA
- const int index = qt_mac_menu_find_action(action->menu, action);
-#else
- QMacCocoaAutoReleasePool pool;
- NSMenuItem *item = action->menuItem;
-#endif
-
- OSMenuRef submenu = 0;
- bool release_submenu = false;
- if (action->action->menu()) {
- if ((submenu = action->action->menu()->macMenu(apple_menu))) {
-#ifndef QT_MAC_USE_COCOA
- QWidget *caused = 0;
- GetMenuItemProperty(action->menu, 0, kMenuCreatorQt, kMenuPropertyQWidget, sizeof(caused), 0, &caused);
- SetMenuItemProperty(submenu, 0, kMenuCreatorQt, kMenuPropertyCausedQWidget, sizeof(caused), &caused);
-#else
- if ([submenu supermenu] && [submenu supermenu] != [item menu])
- return;
- else
- [item setSubmenu:submenu];
-#endif
- }
-#ifndef QT_MAC_USE_COCOA
- } else { // create a submenu to act as menu
- release_submenu = true;
- CreateNewMenu(0, 0, &submenu);
-#endif
- }
-
- if (submenu) {
- bool visible = actualMenuItemVisibility(this, action);
-#ifndef QT_MAC_USE_COCOA
- SetMenuItemHierarchicalMenu(action->menu, index, submenu);
- SetMenuTitleWithCFString(submenu, QCFString(qt_mac_removeMnemonics(action->action->text())));
- if (visible)
- ChangeMenuAttributes(submenu, 0, kMenuAttrHidden);
- else
- ChangeMenuAttributes(submenu, kMenuAttrHidden, 0);
-#else
- [item setSubmenu: submenu];
- [submenu setTitle:qt_mac_QStringToNSString(qt_mac_removeMnemonics(action->action->text()))];
- syncNSMenuItemVisiblity(item, visible);
-#endif
- if (release_submenu) { //no pointers to it
-#ifndef QT_MAC_USE_COCOA
- ReleaseMenu(submenu);
-#else
- [submenu release];
-#endif
- }
- } else {
- qWarning("QMenu: No OSMenuRef created for popup menu");
- }
-}
-
-void
-QMenuBarPrivate::QMacMenuBarPrivate::removeAction(QMacMenuAction *action)
-{
- if (!action || !menu)
- return;
-#ifndef QT_MAC_USE_COCOA
- DeleteMenuItem(action->menu, qt_mac_menu_find_action(action->menu, action));
-#else
- QMacCocoaAutoReleasePool pool;
- [action->menu removeItem:action->menuItem];
-#endif
- actionItems.removeAll(action);
-}
-
-bool QMenuBarPrivate::macWidgetHasNativeMenubar(QWidget *widget)
-{
- // This function is different from q->isNativeMenuBar(), as
- // it returns true only if a native menu bar is actually
- // _created_.
- if (!widget)
- return false;
- return menubars()->contains(widget->window());
-}
-
-void
-QMenuBarPrivate::macCreateMenuBar(QWidget *parent)
-{
- Q_Q(QMenuBar);
- static int dontUseNativeMenuBar = -1;
- // We call the isNativeMenuBar function here
- // because that will make sure that local overrides
- // are dealt with correctly. q->isNativeMenuBar() will, if not
- // overridden, depend on the attribute Qt::AA_DontUseNativeMenuBar:
- bool qt_mac_no_native_menubar = !q->isNativeMenuBar();
- if (qt_mac_no_native_menubar == false && dontUseNativeMenuBar < 0) {
- // The menubar is set to be native. Let's check (one time only
- // for all menubars) if this is OK with the rest of the environment.
- // As a result, Qt::AA_DontUseNativeMenuBar is set. NB: the application
- // might still choose to not respect, or change, this flag.
- bool isPlugin = QApplication::testAttribute(Qt::AA_MacPluginApplication);
- bool environmentSaysNo = !qgetenv("QT_MAC_NO_NATIVE_MENUBAR").isEmpty();
- dontUseNativeMenuBar = isPlugin || environmentSaysNo;
- QApplication::instance()->setAttribute(Qt::AA_DontUseNativeMenuBar, dontUseNativeMenuBar);
- qt_mac_no_native_menubar = !q->isNativeMenuBar();
- }
- if (qt_mac_no_native_menubar == false) {
- // INVARIANT: Use native menubar.
- extern void qt_event_request_menubarupdate(); //qapplication_mac.cpp
- qt_event_request_menubarupdate();
- if (!parent && !fallback) {
- fallback = q;
- mac_menubar = new QMacMenuBarPrivate;
- } else if (parent && parent->isWindow()) {
- menubars()->insert(q->window(), q);
- mac_menubar = new QMacMenuBarPrivate;
- }
- }
-}
-
-void QMenuBarPrivate::macDestroyMenuBar()
-{
- Q_Q(QMenuBar);
- QMacCocoaAutoReleasePool pool;
- if (fallback == q)
- fallback = 0;
- delete mac_menubar;
- QWidget *tlw = q->window();
- menubars()->remove(tlw);
- mac_menubar = 0;
-
- if (!qt_mac_current_menubar.qmenubar || qt_mac_current_menubar.qmenubar == q) {
-#ifdef QT_MAC_USE_COCOA
- QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader();
- [loader removeActionsFromAppMenu];
-#else
- cancelAllMenuTracking();
-#endif
- extern void qt_event_request_menubarupdate(); //qapplication_mac.cpp
- qt_event_request_menubarupdate();
- }
-}
-
-OSMenuRef QMenuBarPrivate::macMenu()
-{
- Q_Q(QMenuBar);
- if (!q->isNativeMenuBar() || !mac_menubar) {
- return 0;
- } else if (!mac_menubar->menu) {
- mac_menubar->menu = qt_mac_create_menu(q);
- ProcessSerialNumber mine, front;
- if (GetCurrentProcess(&mine) == noErr && GetFrontProcess(&front) == noErr) {
- if (!qt_mac_no_menubar_merge && !mac_menubar->apple_menu) {
- mac_menubar->apple_menu = qt_mac_create_menu(q);
-#ifndef QT_MAC_USE_COCOA
- MenuItemIndex index;
- AppendMenuItemTextWithCFString(mac_menubar->menu, 0, 0, 0, &index);
-
- SetMenuTitleWithCFString(mac_menubar->apple_menu, QCFString(QString(QChar(0x14))));
- SetMenuItemHierarchicalMenu(mac_menubar->menu, index, mac_menubar->apple_menu);
- SetMenuItemProperty(mac_menubar->apple_menu, 0, kMenuCreatorQt, kMenuPropertyQWidget, sizeof(q), &q);
-#else
- [mac_menubar->apple_menu setTitle:qt_mac_QStringToNSString(QString(QChar(0x14)))];
- NSMenuItem *apple_menuItem = [[NSMenuItem alloc] init];
- [apple_menuItem setSubmenu:mac_menubar->menu];
- [mac_menubar->apple_menu addItem:apple_menuItem];
- [apple_menuItem release];
-#endif
- }
- if (mac_menubar->apple_menu) {
-#ifndef QT_MAC_USE_COCOA
- SetMenuItemProperty(mac_menubar->menu, 0, kMenuCreatorQt, kMenuPropertyMergeMenu,
- sizeof(mac_menubar->apple_menu), &mac_menubar->apple_menu);
-#else
- QMenuPrivate::mergeMenuHash.insert(mac_menubar->menu, mac_menubar->apple_menu);
-#endif
- }
- QList<QAction*> items = q->actions();
- for(int i = 0; i < items.count(); i++)
- mac_menubar->addAction(items[i]);
- }
- }
- return mac_menubar->menu;
-}
-
-/*!
- \internal
-
- This function will return the OSMenuRef used to create the native menu bar
- bindings. This OSMenuRef is then set as the root menu for the Menu
- Manager.
-
- \warning This function is not portable.
-
- \sa QMenu::macMenu()
-*/
-OSMenuRef QMenuBar::macMenu() { return d_func()->macMenu(); }
-
-/* !
- \internal
- Ancestor function that crosses windows (QWidget::isAncestorOf
- only considers widgets within the same window).
-*/
-static bool qt_mac_is_ancestor(QWidget* possibleAncestor, QWidget *child)
-{
- if (!possibleAncestor)
- return false;
-
- QWidget * current = child->parentWidget();
- while (current != 0) {
- if (current == possibleAncestor)
- return true;
- current = current->parentWidget();
- }
- return false;
-}
-
-/* !
- \internal
- Returns true if the entries of menuBar should be disabled,
- based on the modality type of modalWidget.
-*/
-static bool qt_mac_should_disable_menu(QMenuBar *menuBar)
-{
- QWidget *modalWidget = qApp->activeModalWidget();
- if (!modalWidget)
- return false;
-
- if (menuBar && menuBar == menubars()->value(modalWidget))
- // The menu bar is owned by the modal widget.
- // In that case we should enable it:
- return false;
-
- // When there is an application modal window on screen, the entries of
- // the menubar should be disabled. The exception in Qt is that if the
- // modal window is the only window on screen, then we enable the menu bar.
- QWidget *w = modalWidget;
- QWidgetList topLevelWidgets = QApplication::topLevelWidgets();
- while (w) {
- if (w->isVisible() && w->windowModality() == Qt::ApplicationModal) {
- for (int i=0; i<topLevelWidgets.size(); ++i) {
- QWidget *top = topLevelWidgets.at(i);
- if (w != top && top->isVisible()) {
- // INVARIANT: we found another visible window
- // on screen other than our modalWidget. We therefore
- // disable the menu bar to follow normal modality logic:
- return true;
- }
- }
- // INVARIANT: We have only one window on screen that happends
- // to be application modal. We choose to enable the menu bar
- // in that case to e.g. enable the quit menu item.
- return false;
- }
- w = w->parentWidget();
- }
-
- // INVARIANT: modalWidget is window modal. Disable menu entries
- // if the menu bar belongs to an ancestor of modalWidget. If menuBar
- // is nil, we understand it as the default menu bar set by the nib:
- return menuBar ? qt_mac_is_ancestor(menuBar->parentWidget(), modalWidget) : false;
-}
-
-static QWidget *findWindowThatShouldDisplayMenubar()
-{
- QWidget *w = qApp->activeWindow();
- if (!w) {
- // We have no active window on screen. Try to
- // find a window from the list of top levels:
- QWidgetList tlws = QApplication::topLevelWidgets();
- for(int i = 0; i < tlws.size(); ++i) {
- QWidget *tlw = tlws.at(i);
- if ((tlw->isVisible() && tlw->windowType() != Qt::Tool &&
- tlw->windowType() != Qt::Popup)) {
- w = tlw;
- break;
- }
- }
- }
- return w;
-}
-
-static QMenuBar *findMenubarForWindow(QWidget *w)
-{
- QMenuBar *mb = 0;
- if (w) {
- mb = menubars()->value(w);
-#ifndef QT_NO_MAINWINDOW
- QDockWidget *dw = qobject_cast<QDockWidget *>(w);
- if (!mb && dw) {
- QMainWindow *mw = qobject_cast<QMainWindow *>(dw->parentWidget());
- if (mw && (mb = menubars()->value(mw)))
- w = mw;
- }
-#endif
- while(w && !mb)
- mb = menubars()->value((w = w->parentWidget()));
- }
-
- if (!mb) {
- // We could not find a menu bar for the window. Lets
- // check if we have a global (parentless) menu bar instead:
- mb = fallback;
- }
-
- return mb;
-}
-
-void qt_mac_clear_menubar()
-{
- if (QApplication::testAttribute(Qt::AA_MacPluginApplication))
- return;
-
-#ifndef QT_MAC_USE_COCOA
- MenuRef clear_menu = 0;
- if (CreateNewMenu(0, 0, &clear_menu) == noErr) {
- SetRootMenu(clear_menu);
- ReleaseMenu(clear_menu);
- } else {
- qWarning("QMenu: Internal error at %s:%d", __FILE__, __LINE__);
- }
- ClearMenuBar();
- qt_mac_command_set_enabled(0, kHICommandPreferences, false);
- InvalMenuBar();
-#else
- QMacCocoaAutoReleasePool pool;
- QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader();
- NSMenu *menu = [loader menu];
- [loader ensureAppMenuInMenu:menu];
- [NSApp setMainMenu:menu];
- const bool modal = qt_mac_should_disable_menu(0);
- if (qt_mac_current_menubar.qmenubar || modal != qt_mac_current_menubar.modal)
- qt_mac_set_modal_state(menu, modal);
- qt_mac_current_menubar.qmenubar = 0;
- qt_mac_current_menubar.modal = modal;
-#endif
-}
-
-/*!
- \internal
-
- This function will update the current menu bar and set it as the
- active menu bar in the Menu Manager.
-
- \warning This function is not portable.
-
- \sa QMenu::macMenu(), QMenuBar::macMenu()
-*/
-bool QMenuBar::macUpdateMenuBar()
-{
-#ifdef QT_MAC_USE_COCOA
- QMacCocoaAutoReleasePool pool;
- qt_cocoaPostMessage(getMenuLoader(), @selector(qtUpdateMenubar));
- return true;
-#else
- return QMenuBarPrivate::macUpdateMenuBarImmediatly();
-#endif
-}
-
-bool QMenuBarPrivate::macUpdateMenuBarImmediatly()
-{
- bool ret = false;
- cancelAllMenuTracking();
- QWidget *w = findWindowThatShouldDisplayMenubar();
- QMenuBar *mb = findMenubarForWindow(w);
- extern bool qt_mac_app_fullscreen; //qapplication_mac.mm
-
- // We need to see if we are in full screen mode, if so we need to
- // switch the full screen mode to be able to show or hide the menubar.
- if(w && mb) {
- // This case means we are creating a menubar, check if full screen
- if(w->isFullScreen()) {
- // Ok, switch to showing the menubar when hovering over it.
- SetSystemUIMode(kUIModeAllHidden, kUIOptionAutoShowMenuBar);
- qt_mac_app_fullscreen = true;
- }
- } else if(w) {
- // Removing a menubar
- if(w->isFullScreen()) {
- // Ok, switch to not showing the menubar when hovering on it
- SetSystemUIMode(kUIModeAllHidden, 0);
- qt_mac_app_fullscreen = true;
- }
- }
-
- if (mb && mb->isNativeMenuBar()) {
- bool modal = QApplicationPrivate::modalState();
-#ifdef QT_MAC_USE_COCOA
- QMacCocoaAutoReleasePool pool;
-#endif
- if (OSMenuRef menu = mb->macMenu()) {
-#ifndef QT_MAC_USE_COCOA
- SetRootMenu(menu);
-#else
- QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader();
- [loader ensureAppMenuInMenu:menu];
- [NSApp setMainMenu:menu];
- syncMenuBarItemsVisiblity(mb->d_func()->mac_menubar);
-
- if (OSMenuRef tmpMerge = QMenuPrivate::mergeMenuHash.value(menu)) {
- if (QMenuMergeList *mergeList
- = QMenuPrivate::mergeMenuItemsHash.value(tmpMerge)) {
- const int mergeListSize = mergeList->size();
-
- for (int i = 0; i < mergeListSize; ++i) {
- const QMenuMergeItem &mergeItem = mergeList->at(i);
- // Ideally we would call QMenuPrivate::syncAction, but that requires finding
- // the original QMen and likely doing more work than we need.
- // For example, enabled is handled below.
- [mergeItem.menuItem setTag:reinterpret_cast<long>(
- static_cast<QAction *>(mergeItem.action->action))];
- [mergeItem.menuItem setHidden:!(mergeItem.action->action->isVisible())];
- }
- }
- }
-#endif
- // Check if menu is modally shaddowed and should be disabled:
- modal = qt_mac_should_disable_menu(mb);
- if (mb != qt_mac_current_menubar.qmenubar || modal != qt_mac_current_menubar.modal)
- qt_mac_set_modal_state(menu, modal);
- }
- qt_mac_current_menubar.qmenubar = mb;
- qt_mac_current_menubar.modal = modal;
- ret = true;
- } else if (qt_mac_current_menubar.qmenubar && qt_mac_current_menubar.qmenubar->isNativeMenuBar()) {
- // INVARIANT: The currently active menu bar (if any) is not native. But we do have a
- // native menu bar from before. So we need to decide whether or not is should be enabled:
- const bool modal = qt_mac_should_disable_menu(qt_mac_current_menubar.qmenubar);
- if (modal != qt_mac_current_menubar.modal) {
- ret = true;
- if (OSMenuRef menu = qt_mac_current_menubar.qmenubar->macMenu()) {
-#ifndef QT_MAC_USE_COCOA
- SetRootMenu(menu);
-#else
- QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader();
- [loader ensureAppMenuInMenu:menu];
- [NSApp setMainMenu:menu];
- syncMenuBarItemsVisiblity(qt_mac_current_menubar.qmenubar->d_func()->mac_menubar);
-#endif
- qt_mac_set_modal_state(menu, modal);
- }
- qt_mac_current_menubar.modal = modal;
- }
- }
-
- if (!ret) {
- qt_mac_clear_menubar();
- }
- return ret;
-}
-
-QHash<OSMenuRef, OSMenuRef> QMenuPrivate::mergeMenuHash;
-QHash<OSMenuRef, QMenuMergeList*> QMenuPrivate::mergeMenuItemsHash;
-
-bool QMenuPrivate::QMacMenuPrivate::merged(const QAction *action) const
-{
-#ifndef QT_MAC_USE_COCOA
- MenuRef merge = 0;
- GetMenuItemProperty(menu, 0, kMenuCreatorQt, kMenuPropertyMergeMenu,
- sizeof(merge), 0, &merge);
- if (merge) {
- QMenuMergeList *list = 0;
- if (GetMenuItemProperty(merge, 0, kMenuCreatorQt, kMenuPropertyMergeList,
- sizeof(list), 0, &list) == noErr && list) {
- for(int i = 0; i < list->size(); ++i) {
- QMenuMergeItem item = list->at(i);
- if (item.action->action == action)
- return true;
- }
- }
- }
-#else
- if (OSMenuRef merge = mergeMenuHash.value(menu)) {
- if (QMenuMergeList *list = mergeMenuItemsHash.value(merge)) {
- for(int i = 0; i < list->size(); ++i) {
- const QMenuMergeItem &item = list->at(i);
- if (item.action->action == action)
- return true;
- }
- }
- }
-#endif
- return false;
-}
-
-//creation of the OSMenuRef
-static OSMenuRef qt_mac_create_menu(QWidget *w)
-{
- OSMenuRef ret;
-#ifndef QT_MAC_USE_COCOA
- ret = 0;
- if (CreateNewMenu(0, 0, &ret) == noErr) {
- qt_mac_create_menu_event_handler();
- SetMenuItemProperty(ret, 0, kMenuCreatorQt, kMenuPropertyQWidget, sizeof(w), &w);
-
- // kEventMenuMatchKey is only sent to the menu itself and not to
- // the application, install a separate handler for that event.
- EventHandlerRef eventHandlerRef;
- InstallMenuEventHandler(ret, qt_mac_menu_event,
- GetEventTypeCount(menu_menu_events),
- menu_menu_events, 0, &eventHandlerRef);
- menu_eventHandlers_hash()->insert(ret, eventHandlerRef);
- } else {
- qWarning("QMenu: Internal error");
- }
-#else
- if (QMenu *qmenu = qobject_cast<QMenu *>(w)){
- ret = [[QT_MANGLE_NAMESPACE(QCocoaMenu) alloc] initWithQMenu:qmenu];
- } else {
- ret = [[NSMenu alloc] init];
- }
-#endif
- return ret;
-}
-
-
-
-QT_END_NAMESPACE
-
diff --git a/src/gui/widgets/qmenu_p.h b/src/gui/widgets/qmenu_p.h
deleted file mode 100644
index 82bd932be7..0000000000
--- a/src/gui/widgets/qmenu_p.h
+++ /dev/null
@@ -1,395 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QMENU_P_H
-#define QMENU_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "QtGui/qmenubar.h"
-#include "QtGui/qstyleoption.h"
-#include "QtCore/qdatetime.h"
-#include "QtCore/qmap.h"
-#include "QtCore/qhash.h"
-#include "QtCore/qbasictimer.h"
-#include "private/qwidget_p.h"
-
-#ifdef Q_WS_S60
-class CEikMenuPane;
-#define QT_SYMBIAN_FIRST_MENU_ITEM 32000
-#define QT_SYMBIAN_LAST_MENU_ITEM 41999 // 10000 items ought to be enough for anybody...
-#endif
-QT_BEGIN_NAMESPACE
-
-#ifndef QT_NO_MENU
-
-#ifdef Q_WS_S60
-void qt_symbian_next_menu_from_action(QWidget* actionContainer);
-void qt_symbian_show_toplevel(CEikMenuPane* menuPane);
-void qt_symbian_show_submenu(CEikMenuPane* menuPane, int id);
-#endif // Q_WS_S60
-
-class QTornOffMenu;
-class QEventLoop;
-
-#ifdef Q_WS_MAC
-# ifdef __OBJC__
-QT_END_NAMESPACE
-@class NSMenuItem;
-QT_BEGIN_NAMESPACE
-# else
-typedef void NSMenuItem;
-# endif //__OBJC__
-struct QMacMenuAction {
- QMacMenuAction()
-#ifndef QT_MAC_USE_COCOA
- : command(0)
-#else
- : menuItem(0)
-#endif
- , ignore_accel(0), merged(0), menu(0)
- {
- }
- ~QMacMenuAction();
-#ifndef QT_MAC_USE_COCOA
- uint command;
-#else
- NSMenuItem *menuItem;
-#endif
- uchar ignore_accel : 1;
- uchar merged : 1;
- QPointer<QAction> action;
- OSMenuRef menu;
-};
-
-struct QMenuMergeItem
-{
-#ifndef QT_MAC_USE_COCOA
- inline QMenuMergeItem(MenuCommand c, QMacMenuAction *a) : command(c), action(a) { }
- MenuCommand command;
-#else
- inline QMenuMergeItem(NSMenuItem *c, QMacMenuAction *a) : menuItem(c), action(a) { }
- NSMenuItem *menuItem;
-#endif
- QMacMenuAction *action;
-};
-typedef QList<QMenuMergeItem> QMenuMergeList;
-#endif
-
-#ifdef Q_WS_WINCE
-struct QWceMenuAction {
- uint command;
- QPointer<QAction> action;
- HMENU menuHandle;
- QWceMenuAction() : menuHandle(0), command(0) {}
-};
-#endif
-#ifdef Q_WS_S60
-struct QSymbianMenuAction {
- uint command;
- int parent;
- CEikMenuPane* menuPane;
- QPointer<QAction> action;
- QSymbianMenuAction() : command(0) {}
-};
-#endif
-
-class QMenuPrivate : public QWidgetPrivate
-{
- Q_DECLARE_PUBLIC(QMenu)
-public:
- QMenuPrivate() : itemsDirty(0), maxIconWidth(0), tabWidth(0), ncols(0),
- collapsibleSeparators(true), activationRecursionGuard(false), hasHadMouse(0), aboutToHide(0), motions(0),
- currentAction(0),
-#ifdef QT_KEYPAD_NAVIGATION
- selectAction(0),
- cancelAction(0),
-#endif
- scroll(0), eventLoop(0), tearoff(0), tornoff(0), tearoffHighlighted(0),
- hasCheckableItems(0), sloppyAction(0), doChildEffects(false)
-#ifdef QT3_SUPPORT
- ,emitHighlighted(false)
-#endif
-#ifdef Q_WS_MAC
- ,mac_menu(0)
-#endif
-#if defined(Q_WS_WINCE) && !defined(QT_NO_MENUBAR)
- ,wce_menu(0)
-#endif
-#ifdef Q_WS_S60
- ,symbian_menu(0)
-#endif
- { }
- ~QMenuPrivate()
- {
- delete scroll;
-#ifdef Q_WS_MAC
- delete mac_menu;
-#endif
-#if defined(Q_WS_WINCE) && !defined(QT_NO_MENUBAR)
- delete wce_menu;
-#endif
-#ifdef Q_WS_S60
- delete symbian_menu;
-#endif
-
- }
- void init();
-
- static QMenuPrivate *get(QMenu *m) { return m->d_func(); }
- int scrollerHeight() const;
-
- //item calculations
- mutable uint itemsDirty : 1;
- mutable uint maxIconWidth, tabWidth;
- QRect actionRect(QAction *) const;
-
- mutable QVector<QRect> actionRects;
- mutable QHash<QAction *, QWidget *> widgetItems;
- void updateActionRects() const;
- void updateActionRects(const QRect &screen) const;
- QRect popupGeometry(const QWidget *widget) const;
- QRect popupGeometry(int screen = -1) const;
- mutable uint ncols : 4; //4 bits is probably plenty
- uint collapsibleSeparators : 1;
- QSize adjustMenuSizeForScreen(const QRect & screen);
- int getLastVisibleAction() const;
-
- bool activationRecursionGuard;
-
- //selection
- static QMenu *mouseDown;
- QPoint mousePopupPos;
- uint hasHadMouse : 1;
- uint aboutToHide : 1;
- int motions;
- QAction *currentAction;
-#ifdef QT_KEYPAD_NAVIGATION
- QAction *selectAction;
- QAction *cancelAction;
-#endif
- QBasicTimer menuDelayTimer;
- enum SelectionReason {
- SelectedFromKeyboard,
- SelectedFromElsewhere
- };
- QWidget *topCausedWidget() const;
- QAction *actionAt(QPoint p) const;
- void setFirstActionActive();
- void setCurrentAction(QAction *, int popup = -1, SelectionReason reason = SelectedFromElsewhere, bool activateFirst = false);
- void popupAction(QAction *, int, bool);
- void setSyncAction();
-
- //scrolling support
- struct QMenuScroller {
- enum ScrollLocation { ScrollStay, ScrollBottom, ScrollTop, ScrollCenter };
- enum ScrollDirection { ScrollNone=0, ScrollUp=0x01, ScrollDown=0x02 };
- uint scrollFlags : 2, scrollDirection : 2;
- int scrollOffset;
- QBasicTimer scrollTimer;
-
- QMenuScroller() : scrollFlags(ScrollNone), scrollDirection(ScrollNone), scrollOffset(0) { }
- ~QMenuScroller() { }
- } *scroll;
- void scrollMenu(QMenuScroller::ScrollLocation location, bool active=false);
- void scrollMenu(QMenuScroller::ScrollDirection direction, bool page=false, bool active=false);
- void scrollMenu(QAction *action, QMenuScroller::ScrollLocation location, bool active=false);
-
- //synchronous operation (ie exec())
- QEventLoop *eventLoop;
- QPointer<QAction> syncAction;
-
- //search buffer
- QString searchBuffer;
- QBasicTimer searchBufferTimer;
-
- //passing of mouse events up the parent hierarchy
- QPointer<QMenu> activeMenu;
- bool mouseEventTaken(QMouseEvent *);
-
- //used to walk up the popup list
- struct QMenuCaused {
- QPointer<QWidget> widget;
- QPointer<QAction> action;
- };
- virtual QList<QPointer<QWidget> > calcCausedStack() const;
- QMenuCaused causedPopup;
- void hideUpToMenuBar();
- void hideMenu(QMenu *menu, bool justRegister = false);
-
- //index mappings
- inline QAction *actionAt(int i) const { return q_func()->actions().at(i); }
- inline int indexOf(QAction *act) const { return q_func()->actions().indexOf(act); }
-
- //tear off support
- uint tearoff : 1, tornoff : 1, tearoffHighlighted : 1;
- QPointer<QTornOffMenu> tornPopup;
-
- mutable bool hasCheckableItems;
-
- //sloppy selection
- static int sloppyDelayTimer;
- mutable QAction *sloppyAction;
- QRegion sloppyRegion;
-
- //default action
- QPointer<QAction> defaultAction;
-
- QAction *menuAction;
- QAction *defaultMenuAction;
-
- void setOverrideMenuAction(QAction *);
- void _q_overrideMenuActionDestroyed();
-
- //firing of events
- void activateAction(QAction *, QAction::ActionEvent, bool self=true);
- void activateCausedStack(const QList<QPointer<QWidget> > &, QAction *, QAction::ActionEvent, bool);
-
- void _q_actionTriggered();
- void _q_actionHovered();
-
- bool hasMouseMoved(const QPoint &globalPos);
-
- void updateLayoutDirection();
-
- //menu fading/scrolling effects
- bool doChildEffects;
-
-#ifdef Q_WS_MAC
- //mac menu binding
- struct QMacMenuPrivate {
- QList<QMacMenuAction*> actionItems;
- OSMenuRef menu;
- QMacMenuPrivate();
- ~QMacMenuPrivate();
-
- bool merged(const QAction *action) const;
- void addAction(QAction *, QMacMenuAction* =0, QMenuPrivate *qmenu = 0);
- void addAction(QMacMenuAction *, QMacMenuAction* =0, QMenuPrivate *qmenu = 0);
- void syncAction(QMacMenuAction *);
- inline void syncAction(QAction *a) { syncAction(findAction(a)); }
- void removeAction(QMacMenuAction *);
- inline void removeAction(QAction *a) { removeAction(findAction(a)); }
- inline QMacMenuAction *findAction(QAction *a) {
- for(int i = 0; i < actionItems.size(); i++) {
- QMacMenuAction *act = actionItems[i];
- if(a == act->action)
- return act;
- }
- return 0;
- }
- } *mac_menu;
- OSMenuRef macMenu(OSMenuRef merge);
- void setMacMenuEnabled(bool enable = true);
- void syncSeparatorsCollapsible(bool collapsible);
- static QHash<OSMenuRef, OSMenuRef> mergeMenuHash;
- static QHash<OSMenuRef, QMenuMergeList*> mergeMenuItemsHash;
-#endif
-
- QPointer<QAction> actionAboutToTrigger;
-#ifdef QT3_SUPPORT
- bool emitHighlighted;
-#endif
-
-#if defined(Q_WS_WINCE) && !defined(QT_NO_MENUBAR)
- struct QWceMenuPrivate {
- QList<QWceMenuAction*> actionItems;
- HMENU menuHandle;
- QWceMenuPrivate();
- ~QWceMenuPrivate();
- void addAction(QAction *, QWceMenuAction* =0);
- void addAction(QWceMenuAction *, QWceMenuAction* =0);
- void syncAction(QWceMenuAction *);
- inline void syncAction(QAction *a) { syncAction(findAction(a)); }
- void removeAction(QWceMenuAction *);
- void rebuild();
- inline void removeAction(QAction *a) { removeAction(findAction(a)); }
- inline QWceMenuAction *findAction(QAction *a) {
- for(int i = 0; i < actionItems.size(); i++) {
- QWceMenuAction *act = actionItems[i];
- if(a == act->action)
- return act;
- }
- return 0;
- }
- } *wce_menu;
- HMENU wceMenu();
- QAction* wceCommands(uint command);
-#endif
-#if defined(Q_WS_S60)
- struct QSymbianMenuPrivate {
- QList<QSymbianMenuAction*> actionItems;
- QSymbianMenuPrivate();
- ~QSymbianMenuPrivate();
- void addAction(QAction *, QSymbianMenuAction* =0);
- void addAction(QSymbianMenuAction *, QSymbianMenuAction* =0);
- void syncAction(QSymbianMenuAction *);
- inline void syncAction(QAction *a) { syncAction(findAction(a)); }
- void removeAction(QSymbianMenuAction *);
- void rebuild(bool reCreate = false);
- inline void removeAction(QAction *a) { removeAction(findAction(a)); }
- inline QSymbianMenuAction *findAction(QAction *a) {
- for(int i = 0; i < actionItems.size(); i++) {
- QSymbianMenuAction *act = actionItems[i];
- if(a == act->action)
- return act;
- }
- return 0;
- }
- } *symbian_menu;
-#endif
- QPointer<QWidget> noReplayFor;
-};
-
-#endif // QT_NO_MENU
-
-QT_END_NAMESPACE
-
-#endif // QMENU_P_H
diff --git a/src/gui/widgets/qmenubar.cpp b/src/gui/widgets/qmenubar.cpp
deleted file mode 100644
index 018d9f06a3..0000000000
--- a/src/gui/widgets/qmenubar.cpp
+++ /dev/null
@@ -1,2623 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qmenubar.h>
-
-#include <qstyle.h>
-#include <qlayout.h>
-#include <qapplication.h>
-#include <qdesktopwidget.h>
-#ifndef QT_NO_ACCESSIBILITY
-# include <qaccessible.h>
-#endif
-#include <qpainter.h>
-#include <qstylepainter.h>
-#include <qevent.h>
-#include <qmainwindow.h>
-#include <qtoolbar.h>
-#include <qtoolbutton.h>
-#include <qwhatsthis.h>
-#ifdef Q_WS_X11
-#include <qpluginloader.h>
-#endif
-
-#ifndef QT_NO_MENUBAR
-
-#ifdef QT3_SUPPORT
-#include <private/qaction_p.h>
-#include <qmenudata.h>
-#endif
-
-#include "qmenu_p.h"
-#include "qmenubar_p.h"
-#include "qdebug.h"
-#ifdef Q_WS_X11
-#include "qmenubar_x11_p.h"
-#endif
-
-#ifdef Q_WS_WINCE
-extern bool qt_wince_is_mobile(); //defined in qguifunctions_wce.cpp
-#endif
-
-#ifdef QT_SOFTKEYS_ENABLED
-#include <private/qsoftkeymanager_p.h>
-#endif
-
-QT_BEGIN_NAMESPACE
-
-class QMenuBarExtension : public QToolButton
-{
-public:
- explicit QMenuBarExtension(QWidget *parent);
-
- QSize sizeHint() const;
- void paintEvent(QPaintEvent *);
-};
-
-QMenuBarExtension::QMenuBarExtension(QWidget *parent)
- : QToolButton(parent)
-{
- setObjectName(QLatin1String("qt_menubar_ext_button"));
- setAutoRaise(true);
-#ifndef QT_NO_MENU
- setPopupMode(QToolButton::InstantPopup);
-#endif
- setIcon(style()->standardIcon(QStyle::SP_ToolBarHorizontalExtensionButton, 0, parentWidget()));
-}
-
-void QMenuBarExtension::paintEvent(QPaintEvent *)
-{
- QStylePainter p(this);
- QStyleOptionToolButton opt;
- initStyleOption(&opt);
- // We do not need to draw both extension arrows
- opt.features &= ~QStyleOptionToolButton::HasMenu;
- p.drawComplexControl(QStyle::CC_ToolButton, opt);
-}
-
-
-QSize QMenuBarExtension::sizeHint() const
-{
- int ext = style()->pixelMetric(QStyle::PM_ToolBarExtensionExtent, 0, parentWidget());
- return QSize(ext, ext);
-}
-
-
-/*!
- \internal
-*/
-QAction *QMenuBarPrivate::actionAt(QPoint p) const
-{
- for(int i = 0; i < actions.size(); ++i) {
- if(actionRect(actions.at(i)).contains(p))
- return actions.at(i);
- }
- return 0;
-}
-
-QRect QMenuBarPrivate::menuRect(bool extVisible) const
-{
- Q_Q(const QMenuBar);
-
- int hmargin = q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, q);
- QRect result = q->rect();
- result.adjust(hmargin, 0, -hmargin, 0);
-
- if (extVisible) {
- if (q->isRightToLeft())
- result.setLeft(result.left() + extension->sizeHint().width());
- else
- result.setWidth(result.width() - extension->sizeHint().width());
- }
-
- if (leftWidget && leftWidget->isVisible()) {
- QSize sz = leftWidget->sizeHint();
- if (q->isRightToLeft())
- result.setRight(result.right() - sz.width());
- else
- result.setLeft(result.left() + sz.width());
- }
-
- if (rightWidget && rightWidget->isVisible()) {
- QSize sz = rightWidget->sizeHint();
- if (q->isRightToLeft())
- result.setLeft(result.left() + sz.width());
- else
- result.setRight(result.right() - sz.width());
- }
-
- return result;
-}
-
-bool QMenuBarPrivate::isVisible(QAction *action)
-{
- return !hiddenActions.contains(action);
-}
-
-void QMenuBarPrivate::updateGeometries()
-{
- Q_Q(QMenuBar);
- if(!itemsDirty)
- return;
- int q_width = q->width()-(q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, q)*2);
- int q_start = -1;
- if(
-#ifdef Q_WS_X11
- platformMenuBar->allowCornerWidgets() &&
-#endif
- (leftWidget || rightWidget)) {
- int vmargin = q->style()->pixelMetric(QStyle::PM_MenuBarVMargin, 0, q)
- + q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, q);
- int hmargin = q->style()->pixelMetric(QStyle::PM_MenuBarHMargin, 0, q)
- + q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, q);
- if (leftWidget && leftWidget->isVisible()) {
- QSize sz = leftWidget->sizeHint();
- q_width -= sz.width();
- q_start = sz.width();
- QPoint pos(hmargin, (q->height() - leftWidget->height()) / 2);
- QRect vRect = QStyle::visualRect(q->layoutDirection(), q->rect(), QRect(pos, sz));
- leftWidget->setGeometry(vRect);
- }
- if (rightWidget && rightWidget->isVisible()) {
- QSize sz = rightWidget->sizeHint();
- q_width -= sz.width();
- QPoint pos(q->width() - sz.width() - hmargin, vmargin);
- QRect vRect = QStyle::visualRect(q->layoutDirection(), q->rect(), QRect(pos, sz));
- rightWidget->setGeometry(vRect);
- }
- }
-
-#ifdef Q_WS_MAC
- if(q->isNativeMenuBar()) {//nothing to see here folks, move along..
- itemsDirty = false;
- return;
- }
-#endif
- calcActionRects(q_width, q_start);
- currentAction = 0;
-#ifndef QT_NO_SHORTCUT
- if(
-#ifdef Q_WS_X11
- !platformMenuBar->shortcutsHandledByNativeMenuBar() &&
-#endif
- itemsDirty) {
- for(int j = 0; j < shortcutIndexMap.size(); ++j)
- q->releaseShortcut(shortcutIndexMap.value(j));
- shortcutIndexMap.resize(0); // faster than clear
- for(int i = 0; i < actions.count(); i++)
- shortcutIndexMap.append(q->grabShortcut(QKeySequence::mnemonic(actions.at(i)->text())));
- }
-#endif
-#ifdef Q_WS_X11
- if(q->isNativeMenuBar()) {//nothing to see here folks, move along..
- itemsDirty = false;
- return;
- }
-#endif
- itemsDirty = false;
-
- hiddenActions.clear();
- //this is the menu rectangle without any extension
- QRect menuRect = this->menuRect(false);
-
- //we try to see if the actions will fit there
- bool hasHiddenActions = false;
- for (int i = 0; i < actions.count(); ++i) {
- const QRect &rect = actionRects.at(i);
- if (rect.isValid() && !menuRect.contains(rect)) {
- hasHiddenActions = true;
- break;
- }
- }
-
- //...and if not, determine the ones that fit on the menu with the extension visible
- if (hasHiddenActions) {
- menuRect = this->menuRect(true);
- for (int i = 0; i < actions.count(); ++i) {
- const QRect &rect = actionRects.at(i);
- if (rect.isValid() && !menuRect.contains(rect)) {
- hiddenActions.append(actions.at(i));
- }
- }
- }
-
- if (hiddenActions.count() > 0) {
- QMenu *pop = extension->menu();
- if (!pop) {
- pop = new QMenu(q);
- extension->setMenu(pop);
- }
- pop->clear();
- pop->addActions(hiddenActions);
-
- int vmargin = q->style()->pixelMetric(QStyle::PM_MenuBarVMargin, 0, q);
- int x = q->isRightToLeft()
- ? menuRect.left() - extension->sizeHint().width() + 1
- : menuRect.right();
- extension->setGeometry(x, vmargin, extension->sizeHint().width(), menuRect.height() - vmargin*2);
- extension->show();
- } else {
- extension->hide();
- }
- q->updateGeometry();
-#ifdef QT3_SUPPORT
- if (parent) {
- QMenubarUpdatedEvent menubarUpdated(q);
- QApplication::sendEvent(parent, &menubarUpdated);
- }
-#endif
-}
-
-QRect QMenuBarPrivate::actionRect(QAction *act) const
-{
- const int index = actions.indexOf(act);
-
- //makes sure the geometries are up-to-date
- const_cast<QMenuBarPrivate*>(this)->updateGeometries();
-
- if (index < 0 || index >= actionRects.count())
- return QRect(); // that can happen in case of native menubar
-
- return actionRects.at(index);
-}
-
-void QMenuBarPrivate::focusFirstAction()
-{
- if(!currentAction) {
- updateGeometries();
- int index = 0;
- while (index < actions.count() && actionRects.at(index).isNull()) ++index;
- if (index < actions.count())
- setCurrentAction(actions.at(index));
- }
-}
-
-void QMenuBarPrivate::setKeyboardMode(bool b)
-{
- Q_Q(QMenuBar);
- if (b && !q->style()->styleHint(QStyle::SH_MenuBar_AltKeyNavigation, 0, q)) {
- setCurrentAction(0);
- return;
- }
- keyboardState = b;
- if(b) {
- QWidget *fw = QApplication::focusWidget();
- if (fw != q)
- keyboardFocusWidget = fw;
- focusFirstAction();
- q->setFocus(Qt::MenuBarFocusReason);
- } else {
- if(!popupState)
- setCurrentAction(0);
- if(keyboardFocusWidget) {
- if (QApplication::focusWidget() == q)
- keyboardFocusWidget->setFocus(Qt::MenuBarFocusReason);
- keyboardFocusWidget = 0;
- }
- }
- q->update();
-}
-
-void QMenuBarPrivate::popupAction(QAction *action, bool activateFirst)
-{
- Q_Q(QMenuBar);
- if(!action || !action->menu() || closePopupMode)
- return;
- popupState = true;
- if (action->isEnabled() && action->menu()->isEnabled()) {
- closePopupMode = 0;
- activeMenu = action->menu();
- activeMenu->d_func()->causedPopup.widget = q;
- activeMenu->d_func()->causedPopup.action = action;
-
- QRect adjustedActionRect = actionRect(action);
- QPoint pos(q->mapToGlobal(QPoint(adjustedActionRect.left(), adjustedActionRect.bottom() + 1)));
- QSize popup_size = activeMenu->sizeHint();
-
- //we put the popup menu on the screen containing the bottom-center of the action rect
- QRect screenRect = QApplication::desktop()->screenGeometry(pos + QPoint(adjustedActionRect.width() / 2, 0));
- pos = QPoint(qMax(pos.x(), screenRect.x()), qMax(pos.y(), screenRect.y()));
-
- const bool fitUp = (q->mapToGlobal(adjustedActionRect.topLeft()).y() >= popup_size.height());
- const bool fitDown = (pos.y() + popup_size.height() <= screenRect.bottom());
- const bool rtl = q->isRightToLeft();
- const int actionWidth = adjustedActionRect.width();
-
- if (!fitUp && !fitDown) { //we should shift the menu
- bool shouldShiftToRight = !rtl;
- if (rtl && popup_size.width() > pos.x())
- shouldShiftToRight = true;
- else if (actionWidth + popup_size.width() + pos.x() > screenRect.right())
- shouldShiftToRight = false;
-
- if (shouldShiftToRight) {
- pos.rx() += actionWidth + (rtl ? popup_size.width() : 0);
- } else {
- //shift to left
- if (!rtl)
- pos.rx() -= popup_size.width();
- }
- } else if (rtl) {
- pos.rx() += actionWidth;
- }
-
- if(!defaultPopDown || (fitUp && !fitDown))
- pos.setY(qMax(screenRect.y(), q->mapToGlobal(QPoint(0, adjustedActionRect.top()-popup_size.height())).y()));
- activeMenu->popup(pos);
- if(activateFirst)
- activeMenu->d_func()->setFirstActionActive();
- }
- q->update(actionRect(action));
-}
-
-void QMenuBarPrivate::setCurrentAction(QAction *action, bool popup, bool activateFirst)
-{
- if(currentAction == action && popup == popupState)
- return;
-
- autoReleaseTimer.stop();
-
- doChildEffects = (popup && !activeMenu);
- Q_Q(QMenuBar);
- QWidget *fw = 0;
- if(QMenu *menu = activeMenu) {
- activeMenu = 0;
- if (popup) {
- fw = q->window()->focusWidget();
- q->setFocus(Qt::NoFocusReason);
- }
- menu->hide();
- }
-
- if(currentAction)
- q->update(actionRect(currentAction));
-
- popupState = popup;
-#ifndef QT_NO_STATUSTIP
- QAction *previousAction = currentAction;
-#endif
- currentAction = action;
- if (action) {
- activateAction(action, QAction::Hover);
- if(popup)
- popupAction(action, activateFirst);
- q->update(actionRect(action));
-#ifndef QT_NO_STATUSTIP
- } else if (previousAction) {
- QString empty;
- QStatusTipEvent tip(empty);
- QApplication::sendEvent(q, &tip);
-#endif
- }
- if (fw)
- fw->setFocus(Qt::NoFocusReason);
-}
-
-void QMenuBarPrivate::calcActionRects(int max_width, int start) const
-{
- Q_Q(const QMenuBar);
-
- if(!itemsDirty)
- return;
-
- //let's reinitialize the buffer
- actionRects.resize(actions.count());
- actionRects.fill(QRect());
-
- const QStyle *style = q->style();
-
- const int itemSpacing = style->pixelMetric(QStyle::PM_MenuBarItemSpacing, 0, q);
- int max_item_height = 0, separator = -1, separator_start = 0, separator_len = 0;
-
- //calculate size
- const QFontMetrics fm = q->fontMetrics();
- const int hmargin = style->pixelMetric(QStyle::PM_MenuBarHMargin, 0, q),
- vmargin = style->pixelMetric(QStyle::PM_MenuBarVMargin, 0, q),
- icone = style->pixelMetric(QStyle::PM_SmallIconSize, 0, q);
- for(int i = 0; i < actions.count(); i++) {
- QAction *action = actions.at(i);
- if(!action->isVisible())
- continue;
-
- QSize sz;
-
- //calc what I think the size is..
- if(action->isSeparator()) {
- if (style->styleHint(QStyle::SH_DrawMenuBarSeparator, 0, q))
- separator = i;
- continue; //we don't really position these!
- } else {
- const QString s = action->text();
- QIcon is = action->icon();
- // If an icon is set, only the icon is visible
- if (!is.isNull())
- sz = sz.expandedTo(QSize(icone, icone));
- else if (!s.isEmpty())
- sz = fm.size(Qt::TextShowMnemonic, s);
- }
-
- //let the style modify the above size..
- QStyleOptionMenuItem opt;
- q->initStyleOption(&opt, action);
- sz = q->style()->sizeFromContents(QStyle::CT_MenuBarItem, &opt, sz, q);
-
- if(!sz.isEmpty()) {
- { //update the separator state
- int iWidth = sz.width() + itemSpacing;
- if(separator == -1)
- separator_start += iWidth;
- else
- separator_len += iWidth;
- }
- //maximum height
- max_item_height = qMax(max_item_height, sz.height());
- //append
- actionRects[i] = QRect(0, 0, sz.width(), sz.height());
- }
- }
-
- //calculate position
- const int fw = q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, q);
- int x = fw + ((start == -1) ? hmargin : start) + itemSpacing;
- int y = fw + vmargin;
- for(int i = 0; i < actions.count(); i++) {
- QRect &rect = actionRects[i];
- if (rect.isNull())
- continue;
-
- //resize
- rect.setHeight(max_item_height);
-
- //move
- if(separator != -1 && i >= separator) { //after the separator
- int left = (max_width - separator_len - hmargin - itemSpacing) + (x - separator_start - hmargin);
- if(left < separator_start) { //wrap
- separator_start = x = hmargin;
- y += max_item_height;
- }
- rect.moveLeft(left);
- } else {
- rect.moveLeft(x);
- }
- rect.moveTop(y);
-
- //keep moving along..
- x += rect.width() + itemSpacing;
-
- //make sure we follow the layout direction
- rect = QStyle::visualRect(q->layoutDirection(), q->rect(), rect);
- }
-}
-
-void QMenuBarPrivate::activateAction(QAction *action, QAction::ActionEvent action_e)
-{
- Q_Q(QMenuBar);
- if (!action || !action->isEnabled())
- return;
- action->activate(action_e);
- if (action_e == QAction::Hover)
- action->showStatusText(q);
-
-// if(action_e == QAction::Trigger)
-// emit q->activated(action);
-// else if(action_e == QAction::Hover)
-// emit q->highlighted(action);
-}
-
-
-void QMenuBarPrivate::_q_actionTriggered()
-{
- Q_Q(QMenuBar);
- if (QAction *action = qobject_cast<QAction *>(q->sender())) {
- emit q->triggered(action);
-#ifdef QT3_SUPPORT
- emit q->activated(q->findIdForAction(action));
-#endif
- }
-}
-
-void QMenuBarPrivate::_q_actionHovered()
-{
- Q_Q(QMenuBar);
- if (QAction *action = qobject_cast<QAction *>(q->sender())) {
- emit q->hovered(action);
-#ifndef QT_NO_ACCESSIBILITY
- if (QAccessible::isActive()) {
- int actionIndex = actions.indexOf(action);
- ++actionIndex;
- QAccessible::updateAccessibility(q, actionIndex, QAccessible::Focus);
- QAccessible::updateAccessibility(q, actionIndex, QAccessible::Selection);
- }
-#endif //QT_NO_ACCESSIBILITY
-#ifdef QT3_SUPPORT
- emit q->highlighted(q->findIdForAction(action));
-#endif
- }
-}
-
-/*!
- Initialize \a option with the values from the menu bar and information from \a action. This method
- is useful for subclasses when they need a QStyleOptionMenuItem, but don't want
- to fill in all the information themselves.
-
- \sa QStyleOption::initFrom() QMenu::initStyleOption()
-*/
-void QMenuBar::initStyleOption(QStyleOptionMenuItem *option, const QAction *action) const
-{
- if (!option || !action)
- return;
- Q_D(const QMenuBar);
- option->palette = palette();
- option->state = QStyle::State_None;
- if (isEnabled() && action->isEnabled())
- option->state |= QStyle::State_Enabled;
- else
- option->palette.setCurrentColorGroup(QPalette::Disabled);
- option->fontMetrics = fontMetrics();
- if (d->currentAction && d->currentAction == action) {
- option->state |= QStyle::State_Selected;
- if (d->popupState && !d->closePopupMode)
- option->state |= QStyle::State_Sunken;
- }
- if (hasFocus() || d->currentAction)
- option->state |= QStyle::State_HasFocus;
- option->menuRect = rect();
- option->menuItemType = QStyleOptionMenuItem::Normal;
- option->checkType = QStyleOptionMenuItem::NotCheckable;
- option->text = action->text();
- option->icon = action->icon();
-}
-
-/*!
- \class QMenuBar
- \brief The QMenuBar class provides a horizontal menu bar.
-
- \ingroup mainwindow-classes
-
- A menu bar consists of a list of pull-down menu items. You add
- menu items with addMenu(). For example, asuming that \c menubar
- is a pointer to a QMenuBar and \c fileMenu is a pointer to a
- QMenu, the following statement inserts the menu into the menu bar:
- \snippet doc/src/snippets/code/src_gui_widgets_qmenubar.cpp 0
-
- The ampersand in the menu item's text sets Alt+F as a shortcut for
- this menu. (You can use "\&\&" to get a real ampersand in the menu
- bar.)
-
- There is no need to lay out a menu bar. It automatically sets its
- own geometry to the top of the parent widget and changes it
- appropriately whenever the parent is resized.
-
- \section1 Usage
-
- In most main window style applications you would use the
- \l{QMainWindow::}{menuBar()} function provided in QMainWindow,
- adding \l{QMenu}s to the menu bar and adding \l{QAction}s to the
- pop-up menus.
-
- Example (from the \l{mainwindows/menus}{Menus} example):
-
- \snippet examples/mainwindows/menus/mainwindow.cpp 9
-
- Menu items may be removed with removeAction().
-
- Widgets can be added to menus by using instances of the QWidgetAction
- class to hold them. These actions can then be inserted into menus
- in the usual way; see the QMenu documentation for more details.
-
- \section1 Platform Dependent Look and Feel
-
- Different platforms have different requirements for the appearance
- of menu bars and their behavior when the user interacts with them.
- For example, Windows systems are often configured so that the
- underlined character mnemonics that indicate keyboard shortcuts
- for items in the menu bar are only shown when the \gui{Alt} key is
- pressed.
-
- \table
-
- \row \o \inlineimage plastique-menubar.png A menu bar shown in the
- Plastique widget style.
-
- \o The \l{QPlastiqueStyle}{Plastique widget style}, like most
- other styles, handles the \gui{Help} menu in the same way as it
- handles any other menu.
-
- \row \o \inlineimage motif-menubar.png A menu bar shown in the
- Motif widget style.
-
- \o The \l{QMotifStyle}{Motif widget style} treats \gui{Help} menus
- in a special way, placing them at right-hand end of the menu bar.
-
- \endtable
-
- \section1 QMenuBar on Mac OS X
-
- QMenuBar on Mac OS X is a wrapper for using the system-wide menu bar.
- If you have multiple menu bars in one dialog the outermost menu bar
- (normally inside a widget with widget flag Qt::Window) will
- be used for the system-wide menu bar.
-
- Qt for Mac OS X also provides a menu bar merging feature to make
- QMenuBar conform more closely to accepted Mac OS X menu bar layout.
- The merging functionality is based on string matching the title of
- a QMenu entry. These strings are translated (using QObject::tr())
- in the "QMenuBar" context. If an entry is moved its slots will still
- fire as if it was in the original place. The table below outlines
- the strings looked for and where the entry is placed if matched:
-
- \table
- \header \i String matches \i Placement \i Notes
- \row \i about.*
- \i Application Menu | About <application name>
- \i The application name is fetched from the \c {Info.plist} file
- (see note below). If this entry is not found no About item
- will appear in the Application Menu.
- \row \i config, options, setup, settings or preferences
- \i Application Menu | Preferences
- \i If this entry is not found the Settings item will be disabled
- \row \i quit or exit
- \i Application Menu | Quit <application name>
- \i If this entry is not found a default Quit item will be
- created to call QApplication::quit()
- \endtable
-
- You can override this behavior by using the QAction::menuRole()
- property.
-
- If you want all windows in a Mac application to share one menu
- bar, you must create a menu bar that does not have a parent.
- Create a parent-less menu bar this way:
-
- \snippet doc/src/snippets/code/src_gui_widgets_qmenubar.cpp 1
-
- \bold{Note:} Do \e{not} call QMainWindow::menuBar() to create the
- shared menu bar, because that menu bar will have the QMainWindow
- as its parent. That menu bar would only be displayed for the
- parent QMainWindow.
-
- \bold{Note:} The text used for the application name in the menu
- bar is obtained from the value set in the \c{Info.plist} file in
- the application's bundle. See \l{Deploying an Application on
- Mac OS X} for more information.
-
- \section1 QMenuBar on Windows CE
-
- QMenuBar on Windows CE is a wrapper for using the system-wide menu bar,
- similar to the Mac. This feature is activated for Windows Mobile
- and integrates QMenuBar with the native soft keys. The left soft
- key can be controlled with QMenuBar::setDefaultAction() and the
- right soft key can be used to access the menu bar.
-
- The hovered() signal is not supported for the native menu
- integration. Also, it is not possible to display an icon in a
- native menu on Windows Mobile.
-
- \section1 Examples
-
- The \l{mainwindows/menus}{Menus} example shows how to use QMenuBar
- and QMenu. The other \l{Main Window Examples}{main window
- application examples} also provide menus using these classes.
-
- \sa QMenu, QShortcut, QAction,
- {http://developer.apple.com/documentation/UserExperience/Conceptual/AppleHIGuidelines/XHIGIntro/XHIGIntro.html}{Introduction to Apple Human Interface Guidelines},
- {fowler}{GUI Design Handbook: Menu Bar}, {Menus Example}
-*/
-
-
-void QMenuBarPrivate::init()
-{
- Q_Q(QMenuBar);
- q->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum);
- q->setAttribute(Qt::WA_CustomWhatsThis);
-#ifdef Q_WS_MAC
- macCreateMenuBar(q->parentWidget());
- if(mac_menubar)
- q->hide();
-#endif
-#ifdef Q_WS_WINCE
- if (qt_wince_is_mobile()) {
- wceCreateMenuBar(q->parentWidget());
- if(wce_menubar)
- q->hide();
- }
- else {
- QApplication::setAttribute(Qt::AA_DontUseNativeMenuBar, true);
- }
-#endif
-#ifdef Q_WS_X11
- platformMenuBar = qt_guiPlatformMenuBarFactory()->create();
- platformMenuBar->init(q);
-#endif
-
- q->setBackgroundRole(QPalette::Button);
- oldWindow = oldParent = 0;
-#ifdef QT3_SUPPORT
- doAutoResize = false;
-#endif
-#ifdef QT_SOFTKEYS_ENABLED
- menuBarAction = 0;
-#endif
-#ifdef Q_WS_X11
- cornerWidgetToolBar = 0;
- cornerWidgetContainer = 0;
-#endif
- handleReparent();
- q->setMouseTracking(q->style()->styleHint(QStyle::SH_MenuBar_MouseTracking, 0, q));
-
- extension = new QMenuBarExtension(q);
- extension->setFocusPolicy(Qt::NoFocus);
- extension->hide();
-}
-
-//Gets the next action for keyboard navigation
-QAction *QMenuBarPrivate::getNextAction(const int _start, const int increment) const
-{
- Q_Q(const QMenuBar);
- const_cast<QMenuBarPrivate*>(this)->updateGeometries();
- bool allowActiveAndDisabled = q->style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, q);
- const int start = (_start == -1 && increment == -1) ? actions.count() : _start;
- const int end = increment == -1 ? 0 : actions.count() - 1;
-
- for (int i = start; i != end;) {
- i += increment;
- QAction *current = actions.at(i);
- if (!actionRects.at(i).isNull() && (allowActiveAndDisabled || current->isEnabled()))
- return current;
- }
-
- if (_start != -1) //let's try from the beginning or the end
- return getNextAction(-1, increment);
-
- return 0;
-}
-
-/*!
- Constructs a menu bar with parent \a parent.
-*/
-QMenuBar::QMenuBar(QWidget *parent) : QWidget(*new QMenuBarPrivate, parent, 0)
-{
- Q_D(QMenuBar);
- d->init();
-}
-
-#ifdef QT3_SUPPORT
-/*!
- Use one of the constructors that doesn't take the \a name
- argument and then use setObjectName() instead.
-*/
-QMenuBar::QMenuBar(QWidget *parent, const char *name) : QWidget(*new QMenuBarPrivate, parent, 0)
-{
- Q_D(QMenuBar);
- d->init();
- setObjectName(QString::fromAscii(name));
-}
-#endif
-
-/*!
- Destroys the menu bar.
-*/
-QMenuBar::~QMenuBar()
-{
-#ifdef Q_WS_MAC
- Q_D(QMenuBar);
- d->macDestroyMenuBar();
-#endif
-#ifdef Q_WS_WINCE
- Q_D(QMenuBar);
- if (qt_wince_is_mobile())
- d->wceDestroyMenuBar();
-#endif
-#ifdef Q_WS_S60
- Q_D(QMenuBar);
- d->symbianDestroyMenuBar();
-#endif
-#ifdef Q_WS_X11
- Q_D(QMenuBar);
- delete d->cornerWidgetToolBar;
-#endif
-}
-
-/*!
- \overload
-
- This convenience function creates a new action with \a text.
- The function adds the newly created action to the menu's
- list of actions, and returns it.
-
- \sa QWidget::addAction(), QWidget::actions()
-*/
-QAction *QMenuBar::addAction(const QString &text)
-{
- QAction *ret = new QAction(text, this);
- addAction(ret);
- return ret;
-}
-
-/*!
- \overload
-
- This convenience function creates a new action with the given \a
- text. The action's triggered() signal is connected to the \a
- receiver's \a member slot. The function adds the newly created
- action to the menu's list of actions and returns it.
-
- \sa QWidget::addAction(), QWidget::actions()
-*/
-QAction *QMenuBar::addAction(const QString &text, const QObject *receiver, const char* member)
-{
- QAction *ret = new QAction(text, this);
- QObject::connect(ret, SIGNAL(triggered(bool)), receiver, member);
- addAction(ret);
- return ret;
-}
-
-/*!
- Appends a new QMenu with \a title to the menu bar. The menu bar
- takes ownership of the menu. Returns the new menu.
-
- \sa QWidget::addAction() QMenu::menuAction()
-*/
-QMenu *QMenuBar::addMenu(const QString &title)
-{
- QMenu *menu = new QMenu(title, this);
- addAction(menu->menuAction());
- return menu;
-}
-
-/*!
- Appends a new QMenu with \a icon and \a title to the menu bar. The menu bar
- takes ownership of the menu. Returns the new menu.
-
- \sa QWidget::addAction() QMenu::menuAction()
-*/
-QMenu *QMenuBar::addMenu(const QIcon &icon, const QString &title)
-{
- QMenu *menu = new QMenu(title, this);
- menu->setIcon(icon);
- addAction(menu->menuAction());
- return menu;
-}
-
-/*!
- Appends \a menu to the menu bar. Returns the menu's menuAction().
-
- \note The returned QAction object can be used to hide the corresponding
- menu.
-
- \sa QWidget::addAction() QMenu::menuAction()
-*/
-QAction *QMenuBar::addMenu(QMenu *menu)
-{
- QAction *action = menu->menuAction();
- addAction(action);
- return action;
-}
-
-/*!
- Appends a separator to the menu.
-*/
-QAction *QMenuBar::addSeparator()
-{
- QAction *ret = new QAction(this);
- ret->setSeparator(true);
- addAction(ret);
- return ret;
-}
-
-/*!
- This convenience function creates a new separator action, i.e. an
- action with QAction::isSeparator() returning true. The function inserts
- the newly created action into this menu bar's list of actions before
- action \a before and returns it.
-
- \sa QWidget::insertAction(), addSeparator()
-*/
-QAction *QMenuBar::insertSeparator(QAction *before)
-{
- QAction *action = new QAction(this);
- action->setSeparator(true);
- insertAction(before, action);
- return action;
-}
-
-/*!
- This convenience function inserts \a menu before action \a before
- and returns the menus menuAction().
-
- \sa QWidget::insertAction() addMenu()
-*/
-QAction *QMenuBar::insertMenu(QAction *before, QMenu *menu)
-{
- QAction *action = menu->menuAction();
- insertAction(before, action);
- return action;
-}
-
-/*!
- Returns the QAction that is currently highlighted. A null pointer
- will be returned if no action is currently selected.
-*/
-QAction *QMenuBar::activeAction() const
-{
- Q_D(const QMenuBar);
- return d->currentAction;
-}
-
-/*!
- \since 4.1
-
- Sets the currently highlighted action to \a act.
-*/
-void QMenuBar::setActiveAction(QAction *act)
-{
- Q_D(QMenuBar);
- d->setCurrentAction(act, true, false);
-}
-
-
-/*!
- Removes all the actions from the menu bar.
-
- \note On Mac OS X, menu items that have been merged to the system
- menu bar are not removed by this function. One way to handle this
- would be to remove the extra actions yourself. You can set the
- \l{QAction::MenuRole}{menu role} on the different menus, so that
- you know ahead of time which menu items get merged and which do
- not. Then decide what to recreate or remove yourself.
-
- \sa removeAction()
-*/
-void QMenuBar::clear()
-{
- QList<QAction*> acts = actions();
- for(int i = 0; i < acts.size(); i++)
- removeAction(acts[i]);
-}
-
-/*!
- \property QMenuBar::defaultUp
- \brief the popup orientation
-
- The default popup orientation. By default, menus pop "down" the
- screen. By setting the property to true, the menu will pop "up".
- You might call this for menus that are \e below the document to
- which they refer.
-
- If the menu would not fit on the screen, the other direction is
- used automatically.
-*/
-void QMenuBar::setDefaultUp(bool b)
-{
- Q_D(QMenuBar);
- d->defaultPopDown = !b;
-}
-
-bool QMenuBar::isDefaultUp() const
-{
- Q_D(const QMenuBar);
- return !d->defaultPopDown;
-}
-
-/*!
- \reimp
-*/
-void QMenuBar::resizeEvent(QResizeEvent *)
-{
- Q_D(QMenuBar);
- d->itemsDirty = true;
- d->updateGeometries();
-}
-
-/*!
- \reimp
-*/
-void QMenuBar::paintEvent(QPaintEvent *e)
-{
- Q_D(QMenuBar);
- QPainter p(this);
- QRegion emptyArea(rect());
-
- //draw the items
- for (int i = 0; i < d->actions.count(); ++i) {
- QAction *action = d->actions.at(i);
- QRect adjustedActionRect = d->actionRect(action);
- if (adjustedActionRect.isEmpty() || !d->isVisible(action))
- continue;
- if(!e->rect().intersects(adjustedActionRect))
- continue;
-
- emptyArea -= adjustedActionRect;
- QStyleOptionMenuItem opt;
- initStyleOption(&opt, action);
- opt.rect = adjustedActionRect;
- p.setClipRect(adjustedActionRect);
- style()->drawControl(QStyle::CE_MenuBarItem, &opt, &p, this);
- }
- //draw border
- if(int fw = style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, this)) {
- QRegion borderReg;
- borderReg += QRect(0, 0, fw, height()); //left
- borderReg += QRect(width()-fw, 0, fw, height()); //right
- borderReg += QRect(0, 0, width(), fw); //top
- borderReg += QRect(0, height()-fw, width(), fw); //bottom
- p.setClipRegion(borderReg);
- emptyArea -= borderReg;
- QStyleOptionFrame frame;
- frame.rect = rect();
- frame.palette = palette();
- frame.state = QStyle::State_None;
- frame.lineWidth = style()->pixelMetric(QStyle::PM_MenuBarPanelWidth);
- frame.midLineWidth = 0;
- style()->drawPrimitive(QStyle::PE_PanelMenuBar, &frame, &p, this);
- }
- p.setClipRegion(emptyArea);
- QStyleOptionMenuItem menuOpt;
- menuOpt.palette = palette();
- menuOpt.state = QStyle::State_None;
- menuOpt.menuItemType = QStyleOptionMenuItem::EmptyArea;
- menuOpt.checkType = QStyleOptionMenuItem::NotCheckable;
- menuOpt.rect = rect();
- menuOpt.menuRect = rect();
- style()->drawControl(QStyle::CE_MenuBarEmptyArea, &menuOpt, &p, this);
-}
-
-/*!
- \reimp
-*/
-void QMenuBar::setVisible(bool visible)
-{
-#ifdef Q_WS_X11
- Q_D(QMenuBar);
- d->platformMenuBar->setVisible(visible);
-#else
-#if defined(Q_WS_MAC) || defined(Q_OS_WINCE) || defined(Q_WS_S60)
- if (isNativeMenuBar()) {
- if (!visible)
- QWidget::setVisible(false);
- return;
- }
-#endif
- QWidget::setVisible(visible);
-#endif // Q_WS_X11
-}
-
-/*!
- \reimp
-*/
-void QMenuBar::mousePressEvent(QMouseEvent *e)
-{
- Q_D(QMenuBar);
- if(e->button() != Qt::LeftButton)
- return;
-
- d->mouseDown = true;
-
- QAction *action = d->actionAt(e->pos());
- if (!action || !d->isVisible(action)) {
- d->setCurrentAction(0);
-#ifndef QT_NO_WHATSTHIS
- if (QWhatsThis::inWhatsThisMode())
- QWhatsThis::showText(e->globalPos(), d->whatsThis, this);
-#endif
- return;
- }
-
- if(d->currentAction == action && d->popupState) {
- if(QMenu *menu = d->activeMenu) {
- d->activeMenu = 0;
- menu->hide();
- }
-#ifdef Q_WS_WIN
- if((d->closePopupMode = style()->styleHint(QStyle::SH_MenuBar_DismissOnSecondClick)))
- update(d->actionRect(action));
-#endif
- } else {
- d->setCurrentAction(action, true);
- }
-}
-
-/*!
- \reimp
-*/
-void QMenuBar::mouseReleaseEvent(QMouseEvent *e)
-{
- Q_D(QMenuBar);
- if(e->button() != Qt::LeftButton || !d->mouseDown)
- return;
-
- d->mouseDown = false;
- QAction *action = d->actionAt(e->pos());
- if((d->closePopupMode && action == d->currentAction) || !action || !action->menu()) {
- //we set the current action before activating
- //so that we let the leave event set the current back to 0
- d->setCurrentAction(action, false);
- if(action)
- d->activateAction(action, QAction::Trigger);
- }
- d->closePopupMode = 0;
-}
-
-/*!
- \reimp
-*/
-void QMenuBar::keyPressEvent(QKeyEvent *e)
-{
- Q_D(QMenuBar);
- d->updateGeometries();
- int key = e->key();
- if(isRightToLeft()) { // in reverse mode open/close key for submenues are reversed
- if(key == Qt::Key_Left)
- key = Qt::Key_Right;
- else if(key == Qt::Key_Right)
- key = Qt::Key_Left;
- }
- if(key == Qt::Key_Tab) //means right
- key = Qt::Key_Right;
- else if(key == Qt::Key_Backtab) //means left
- key = Qt::Key_Left;
-
- bool key_consumed = false;
- switch(key) {
- case Qt::Key_Up:
- case Qt::Key_Down:
- case Qt::Key_Enter:
- case Qt::Key_Space:
- case Qt::Key_Return: {
- if(!style()->styleHint(QStyle::SH_MenuBar_AltKeyNavigation, 0, this) || !d->currentAction)
- break;
- if(d->currentAction->menu()) {
- d->popupAction(d->currentAction, true);
- } else if(key == Qt::Key_Enter || key == Qt::Key_Return || key == Qt::Key_Space) {
- d->activateAction(d->currentAction, QAction::Trigger);
- d->setCurrentAction(d->currentAction, false);
- d->setKeyboardMode(false);
- }
- key_consumed = true;
- break; }
-
- case Qt::Key_Right:
- case Qt::Key_Left: {
- if(d->currentAction) {
- int index = d->actions.indexOf(d->currentAction);
- if (QAction *nextAction = d->getNextAction(index, key == Qt::Key_Left ? -1 : +1)) {
- d->setCurrentAction(nextAction, d->popupState, true);
- key_consumed = true;
- }
- }
- break; }
-
- case Qt::Key_Escape:
- d->setCurrentAction(0);
- d->setKeyboardMode(false);
- key_consumed = true;
- break;
-
- default:
- key_consumed = false;
- }
-
- if(!key_consumed &&
- (!e->modifiers() ||
- (e->modifiers()&(Qt::MetaModifier|Qt::AltModifier))) && e->text().length()==1 && !d->popupState) {
- int clashCount = 0;
- QAction *first = 0, *currentSelected = 0, *firstAfterCurrent = 0;
- {
- QChar c = e->text()[0].toUpper();
- for(int i = 0; i < d->actions.size(); ++i) {
- if (d->actionRects.at(i).isNull())
- continue;
- QAction *act = d->actions.at(i);
- QString s = act->text();
- if(!s.isEmpty()) {
- int ampersand = s.indexOf(QLatin1Char('&'));
- if(ampersand >= 0) {
- if(s[ampersand+1].toUpper() == c) {
- clashCount++;
- if(!first)
- first = act;
- if(act == d->currentAction)
- currentSelected = act;
- else if (!firstAfterCurrent && currentSelected)
- firstAfterCurrent = act;
- }
- }
- }
- }
- }
- QAction *next_action = 0;
- if(clashCount >= 1) {
- if(clashCount == 1 || !d->currentAction || (currentSelected && !firstAfterCurrent))
- next_action = first;
- else
- next_action = firstAfterCurrent;
- }
- if(next_action) {
- key_consumed = true;
- d->setCurrentAction(next_action, true, true);
- }
- }
- if(key_consumed)
- e->accept();
- else
- e->ignore();
-}
-
-/*!
- \reimp
-*/
-void QMenuBar::mouseMoveEvent(QMouseEvent *e)
-{
- Q_D(QMenuBar);
- if (!(e->buttons() & Qt::LeftButton))
- d->mouseDown = false;
- bool popupState = d->popupState || d->mouseDown;
- QAction *action = d->actionAt(e->pos());
- if ((action && d->isVisible(action)) || !popupState)
- d->setCurrentAction(action, popupState);
-}
-
-/*!
- \reimp
-*/
-void QMenuBar::leaveEvent(QEvent *)
-{
- Q_D(QMenuBar);
- if((!hasFocus() && !d->popupState) ||
- (d->currentAction && d->currentAction->menu() == 0))
- d->setCurrentAction(0);
-}
-
-/*!
- \reimp
-*/
-void QMenuBar::actionEvent(QActionEvent *e)
-{
- Q_D(QMenuBar);
- d->itemsDirty = true;
-#ifdef Q_WS_X11
- d->platformMenuBar->actionEvent(e);
-#endif
-#if defined (Q_WS_MAC) || defined(Q_OS_WINCE) || defined(Q_WS_S60)
- if (isNativeMenuBar()) {
-#ifdef Q_WS_MAC
- QMenuBarPrivate::QMacMenuBarPrivate *nativeMenuBar = d->mac_menubar;
-#elif defined(Q_WS_S60)
- QMenuBarPrivate::QSymbianMenuBarPrivate *nativeMenuBar = d->symbian_menubar;
-#else
- QMenuBarPrivate::QWceMenuBarPrivate *nativeMenuBar = d->wce_menubar;
-#endif
- if (!nativeMenuBar)
- return;
- if(e->type() == QEvent::ActionAdded)
- nativeMenuBar->addAction(e->action(), e->before());
- else if(e->type() == QEvent::ActionRemoved)
- nativeMenuBar->removeAction(e->action());
- else if(e->type() == QEvent::ActionChanged)
- nativeMenuBar->syncAction(e->action());
- }
-#endif
-
- if(e->type() == QEvent::ActionAdded) {
- connect(e->action(), SIGNAL(triggered()), this, SLOT(_q_actionTriggered()));
- connect(e->action(), SIGNAL(hovered()), this, SLOT(_q_actionHovered()));
- } else if(e->type() == QEvent::ActionRemoved) {
- e->action()->disconnect(this);
- }
- if (isVisible()) {
- d->updateGeometries();
- update();
- }
-}
-
-/*!
- \reimp
-*/
-void QMenuBar::focusInEvent(QFocusEvent *)
-{
- Q_D(QMenuBar);
- if(d->keyboardState)
- d->focusFirstAction();
-}
-
-/*!
- \reimp
-*/
-void QMenuBar::focusOutEvent(QFocusEvent *)
-{
- Q_D(QMenuBar);
- if(!d->popupState) {
- d->setCurrentAction(0);
- d->setKeyboardMode(false);
- }
-}
-
-/*!
- \reimp
- */
-void QMenuBar::timerEvent (QTimerEvent *e)
-{
- Q_D(QMenuBar);
- if (e->timerId() == d->autoReleaseTimer.timerId()) {
- d->autoReleaseTimer.stop();
- d->setCurrentAction(0);
- }
- QWidget::timerEvent(e);
-}
-
-
-void QMenuBarPrivate::handleReparent()
-{
- Q_Q(QMenuBar);
- QWidget *newParent = q->parentWidget();
- //Note: if parent is reparented, then window may change even if parent doesn't
-
- // we need to install an event filter on parent, and remove the old one
-
- if (oldParent != newParent) {
- if (oldParent)
- oldParent->removeEventFilter(q);
- if (newParent)
- newParent->installEventFilter(q);
- }
-
- //we also need event filter on top-level (for shortcuts)
- QWidget *newWindow = newParent ? newParent->window() : 0;
-
- if (oldWindow != newWindow) {
- if (oldParent && oldParent != oldWindow)
- oldWindow->removeEventFilter(q);
-
- if (newParent && newParent != newWindow)
- newWindow->installEventFilter(q);
- }
-
-#ifdef Q_WS_X11
- platformMenuBar->handleReparent(oldParent, newParent, oldWindow, newWindow);
-#endif
-
- oldParent = newParent;
- oldWindow = newWindow;
-
-#ifdef Q_WS_MAC
- if (q->isNativeMenuBar() && !macWidgetHasNativeMenubar(newParent)) {
- // If the new parent got a native menubar from before, keep that
- // menubar rather than replace it with this one (because a parents
- // menubar has precedence over children menubars).
- macDestroyMenuBar();
- macCreateMenuBar(newParent);
- }
-#endif
-
-#ifdef Q_WS_WINCE
- if (qt_wince_is_mobile() && wce_menubar)
- wce_menubar->rebuild();
-#endif
-#ifdef Q_WS_S60
-
- // Construct symbian_menubar when this code path is entered first time
- // and when newParent != NULL
- if (!symbian_menubar)
- symbianCreateMenuBar(newParent);
-
- // Reparent and rebuild menubar when parent is changed
- if (symbian_menubar) {
- if (oldParent != newParent)
- reparentMenuBar(oldParent, newParent);
- q->hide();
- symbian_menubar->rebuild();
- }
-
-#ifdef QT_SOFTKEYS_ENABLED
- // Constuct menuBarAction when this code path is entered first time
- if (!menuBarAction) {
- if (newParent) {
- menuBarAction = QSoftKeyManager::createAction(QSoftKeyManager::MenuSoftKey, newParent);
- newParent->addAction(menuBarAction);
- }
- } else {
- // If reparenting i.e. we already have menuBarAction, remove it from old parent
- // and add for a new parent
- if (oldParent)
- oldParent->removeAction(menuBarAction);
- if (newParent)
- newParent->addAction(menuBarAction);
- }
-#endif // QT_SOFTKEYS_ENABLED
-#endif // Q_WS_S60
-}
-
-#ifdef QT3_SUPPORT
-/*!
- Sets whether the menu bar should automatically resize itself
- when its parent widget is resized.
-
- This feature is provided to help porting to Qt 4. We recommend
- against using it in new code.
-
- \sa autoGeometry()
-*/
-void QMenuBar::setAutoGeometry(bool b)
-{
- Q_D(QMenuBar);
- d->doAutoResize = b;
-}
-
-/*!
- Returns true if the menu bar automatically resizes itself
- when its parent widget is resized; otherwise returns false.
-
- This feature is provided to help porting to Qt 4. We recommend
- against using it in new code.
-
- \sa setAutoGeometry()
-*/
-bool QMenuBar::autoGeometry() const
-{
- Q_D(const QMenuBar);
- return d->doAutoResize;
-}
-#endif
-
-/*!
- \reimp
-*/
-void QMenuBar::changeEvent(QEvent *e)
-{
- Q_D(QMenuBar);
- if(e->type() == QEvent::StyleChange) {
- d->itemsDirty = true;
- setMouseTracking(style()->styleHint(QStyle::SH_MenuBar_MouseTracking, 0, this));
- if(parentWidget())
- resize(parentWidget()->width(), heightForWidth(parentWidget()->width()));
- d->updateGeometries();
- } else if (e->type() == QEvent::ParentChange) {
- d->handleReparent();
- } else if (e->type() == QEvent::FontChange
- || e->type() == QEvent::ApplicationFontChange) {
- d->itemsDirty = true;
- d->updateGeometries();
-#ifdef QT_SOFTKEYS_ENABLED
- } else if (e->type() == QEvent::LanguageChange) {
- if (d->menuBarAction)
- d->menuBarAction->setText(QSoftKeyManager::standardSoftKeyText(QSoftKeyManager::MenuSoftKey));
-#endif
- }
-
- QWidget::changeEvent(e);
-}
-
-/*!
- \reimp
-*/
-bool QMenuBar::event(QEvent *e)
-{
- Q_D(QMenuBar);
- switch (e->type()) {
- case QEvent::KeyPress: {
- QKeyEvent *ke = (QKeyEvent*)e;
-#if 0
- if(!d->keyboardState) { //all keypresses..
- d->setCurrentAction(0);
- return ;
- }
-#endif
- if(ke->key() == Qt::Key_Tab || ke->key() == Qt::Key_Backtab) {
- keyPressEvent(ke);
- return true;
- }
-
- } break;
-#ifndef QT_NO_SHORTCUT
- case QEvent::Shortcut: {
- QShortcutEvent *se = static_cast<QShortcutEvent *>(e);
- int shortcutId = se->shortcutId();
- for(int j = 0; j < d->shortcutIndexMap.size(); ++j) {
- if (shortcutId == d->shortcutIndexMap.value(j))
- d->_q_internalShortcutActivated(j);
- }
- } break;
-#endif
- case QEvent::Show:
-#ifdef QT3_SUPPORT
- if(QWidget *p = parentWidget()) {
- // If itemsDirty == true, updateGeometries sends the MenubarUpdated event.
- if (!d->itemsDirty) {
- QMenubarUpdatedEvent menubarUpdated(this);
- QApplication::sendEvent(p, &menubarUpdated);
- }
- }
-#endif
- d->_q_updateLayout();
- break;
- case QEvent::ShortcutOverride: {
- QKeyEvent *kev = static_cast<QKeyEvent*>(e);
- //we only filter out escape if there is a current action
- if (kev->key() == Qt::Key_Escape && d->currentAction) {
- e->accept();
- return true;
- }
- }
- break;
-
-#ifdef QT3_SUPPORT
- case QEvent::Hide: {
- if(QWidget *p = parentWidget()) {
- QMenubarUpdatedEvent menubarUpdated(this);
- QApplication::sendEvent(p, &menubarUpdated);
- }
- } break;
-#endif
-
-#ifndef QT_NO_WHATSTHIS
- case QEvent::QueryWhatsThis:
- e->setAccepted(d->whatsThis.size());
- if (QAction *action = d->actionAt(static_cast<QHelpEvent*>(e)->pos())) {
- if (action->whatsThis().size() || action->menu())
- e->accept();
- }
- return true;
-#endif
- case QEvent::LayoutDirectionChange:
- d->_q_updateLayout();
- break;
- default:
- break;
- }
- return QWidget::event(e);
-}
-
-/*!
- \reimp
-*/
-bool QMenuBar::eventFilter(QObject *object, QEvent *event)
-{
- Q_D(QMenuBar);
-#ifdef Q_WS_X11
- if (d->platformMenuBar->menuBarEventFilter(object, event)) {
- return true;
- }
-#endif
- if (object == parent() && object) {
-#ifdef QT3_SUPPORT
- if (d->doAutoResize && event->type() == QEvent::Resize) {
- QResizeEvent *e = (QResizeEvent *)event;
- int w = e->size().width();
- setGeometry(0, y(), w, heightForWidth(w));
- return false;
- }
-#endif
- if (event->type() == QEvent::ParentChange) //GrandparentChange
- d->handleReparent();
- }
- if (object == d->leftWidget || object == d->rightWidget) {
- switch (event->type()) {
- case QEvent::ShowToParent:
- case QEvent::HideToParent:
- d->_q_updateLayout();
- break;
- default:
- break;
- }
- }
-
- if (style()->styleHint(QStyle::SH_MenuBar_AltKeyNavigation, 0, this)) {
- if (d->altPressed) {
- switch (event->type()) {
- case QEvent::KeyPress:
- case QEvent::KeyRelease:
- {
- QKeyEvent *kev = static_cast<QKeyEvent*>(event);
- if (kev->key() == Qt::Key_Alt || kev->key() == Qt::Key_Meta) {
- if (event->type() == QEvent::KeyPress) // Alt-press does not interest us, we have the shortcut-override event
- break;
- d->setKeyboardMode(!d->keyboardState);
- }
- }
- // fall through
- case QEvent::MouseButtonPress:
- case QEvent::MouseButtonRelease:
- case QEvent::MouseMove:
- case QEvent::FocusIn:
- case QEvent::FocusOut:
- case QEvent::ActivationChange:
- d->altPressed = false;
- qApp->removeEventFilter(this);
- break;
- default:
- break;
- }
- } else if (isVisible()) {
- if (event->type() == QEvent::ShortcutOverride) {
- QKeyEvent *kev = static_cast<QKeyEvent*>(event);
- if ((kev->key() == Qt::Key_Alt || kev->key() == Qt::Key_Meta)
- && kev->modifiers() == Qt::AltModifier) {
- d->altPressed = true;
- qApp->installEventFilter(this);
- }
- }
- }
- }
-
- return false;
-}
-
-/*!
- Returns the QAction at \a pt. Returns 0 if there is no action at \a pt or if
-the location has a separator.
-
- \sa addAction(), addSeparator()
-*/
-QAction *QMenuBar::actionAt(const QPoint &pt) const
-{
- Q_D(const QMenuBar);
- return d->actionAt(pt);
-}
-
-/*!
- Returns the geometry of action \a act as a QRect.
-
- \sa actionAt()
-*/
-QRect QMenuBar::actionGeometry(QAction *act) const
-{
- Q_D(const QMenuBar);
- return d->actionRect(act);
-}
-
-/*!
- \reimp
-*/
-QSize QMenuBar::minimumSizeHint() const
-{
- Q_D(const QMenuBar);
-#if defined(Q_WS_MAC) || defined(Q_WS_WINCE) || defined(Q_WS_S60) || defined(Q_WS_X11)
- const bool as_gui_menubar = !isNativeMenuBar();
-#else
- const bool as_gui_menubar = true;
-#endif
-
- ensurePolished();
- QSize ret(0, 0);
- const_cast<QMenuBarPrivate*>(d)->updateGeometries();
- const int hmargin = style()->pixelMetric(QStyle::PM_MenuBarHMargin, 0, this);
- const int vmargin = style()->pixelMetric(QStyle::PM_MenuBarVMargin, 0, this);
- int fw = style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, this);
- int spaceBelowMenuBar = style()->styleHint(QStyle::SH_MainWindow_SpaceBelowMenuBar, 0, this);
- if(as_gui_menubar) {
- int w = parentWidget() ? parentWidget()->width() : QApplication::desktop()->width();
- d->calcActionRects(w - (2 * fw), 0);
- for (int i = 0; ret.isNull() && i < d->actions.count(); ++i)
- ret = d->actionRects.at(i).size();
- if (!d->extension->isHidden())
- ret += QSize(d->extension->sizeHint().width(), 0);
- ret += QSize(2*fw + hmargin, 2*fw + vmargin);
- }
- int margin = 2*vmargin + 2*fw + spaceBelowMenuBar;
-#ifdef Q_WS_X11
- if (d->platformMenuBar->allowCornerWidgets()) {
-#endif
- if(d->leftWidget) {
- QSize sz = d->leftWidget->minimumSizeHint();
- ret.setWidth(ret.width() + sz.width());
- if(sz.height() + margin > ret.height())
- ret.setHeight(sz.height() + margin);
- }
- if(d->rightWidget) {
- QSize sz = d->rightWidget->minimumSizeHint();
- ret.setWidth(ret.width() + sz.width());
- if(sz.height() + margin > ret.height())
- ret.setHeight(sz.height() + margin);
- }
-#ifdef Q_WS_X11
- }
-#endif
- if(as_gui_menubar) {
- QStyleOptionMenuItem opt;
- opt.rect = rect();
- opt.menuRect = rect();
- opt.state = QStyle::State_None;
- opt.menuItemType = QStyleOptionMenuItem::Normal;
- opt.checkType = QStyleOptionMenuItem::NotCheckable;
- opt.palette = palette();
- return (style()->sizeFromContents(QStyle::CT_MenuBar, &opt,
- ret.expandedTo(QApplication::globalStrut()),
- this));
- }
- return ret;
-}
-
-/*!
- \reimp
-*/
-QSize QMenuBar::sizeHint() const
-{
- Q_D(const QMenuBar);
-#if defined(Q_WS_MAC) || defined(Q_WS_WINCE) || defined(Q_WS_S60) || defined(Q_WS_X11)
- const bool as_gui_menubar = !isNativeMenuBar();
-#else
- const bool as_gui_menubar = true;
-#endif
-
-
- ensurePolished();
- QSize ret(0, 0);
- const_cast<QMenuBarPrivate*>(d)->updateGeometries();
- const int hmargin = style()->pixelMetric(QStyle::PM_MenuBarHMargin, 0, this);
- const int vmargin = style()->pixelMetric(QStyle::PM_MenuBarVMargin, 0, this);
- int fw = style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, this);
- int spaceBelowMenuBar = style()->styleHint(QStyle::SH_MainWindow_SpaceBelowMenuBar, 0, this);
- if(as_gui_menubar) {
- const int w = parentWidget() ? parentWidget()->width() : QApplication::desktop()->width();
- d->calcActionRects(w - (2 * fw), 0);
- for (int i = 0; i < d->actionRects.count(); ++i) {
- const QRect &actionRect = d->actionRects.at(i);
- ret = ret.expandedTo(QSize(actionRect.x() + actionRect.width(), actionRect.y() + actionRect.height()));
- }
- //the action geometries already contain the top and left
- //margins. So we only need to add those from right and bottom.
- ret += QSize(fw + hmargin, fw + vmargin);
- }
- int margin = 2*vmargin + 2*fw + spaceBelowMenuBar;
-#ifdef Q_WS_X11
- if(d->platformMenuBar->allowCornerWidgets()) {
-#endif
- if(d->leftWidget) {
- QSize sz = d->leftWidget->sizeHint();
- ret.setWidth(ret.width() + sz.width());
- if(sz.height() + margin > ret.height())
- ret.setHeight(sz.height() + margin);
- }
- if(d->rightWidget) {
- QSize sz = d->rightWidget->sizeHint();
- ret.setWidth(ret.width() + sz.width());
- if(sz.height() + margin > ret.height())
- ret.setHeight(sz.height() + margin);
- }
-#ifdef Q_WS_X11
- }
-#endif
- if(as_gui_menubar) {
- QStyleOptionMenuItem opt;
- opt.rect = rect();
- opt.menuRect = rect();
- opt.state = QStyle::State_None;
- opt.menuItemType = QStyleOptionMenuItem::Normal;
- opt.checkType = QStyleOptionMenuItem::NotCheckable;
- opt.palette = palette();
- return (style()->sizeFromContents(QStyle::CT_MenuBar, &opt,
- ret.expandedTo(QApplication::globalStrut()),
- this));
- }
- return ret;
-}
-
-/*!
- \reimp
-*/
-int QMenuBar::heightForWidth(int) const
-{
- Q_D(const QMenuBar);
-#if defined(Q_WS_MAC) || defined(Q_WS_WINCE) || defined(Q_WS_S60) || defined(Q_WS_X11)
- const bool as_gui_menubar = !isNativeMenuBar();
-#else
- const bool as_gui_menubar = true;
-#endif
-
- const_cast<QMenuBarPrivate*>(d)->updateGeometries();
- int height = 0;
- const int vmargin = style()->pixelMetric(QStyle::PM_MenuBarVMargin, 0, this);
- int fw = style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, this);
- int spaceBelowMenuBar = style()->styleHint(QStyle::SH_MainWindow_SpaceBelowMenuBar, 0, this);
- if(as_gui_menubar) {
- for (int i = 0; i < d->actionRects.count(); ++i)
- height = qMax(height, d->actionRects.at(i).height());
- if (height) //there is at least one non-null item
- height += spaceBelowMenuBar;
- height += 2*fw;
- height += 2*vmargin;
- }
- int margin = 2*vmargin + 2*fw + spaceBelowMenuBar;
-#ifdef Q_WS_X11
- if(d->platformMenuBar->allowCornerWidgets()) {
-#endif
- if(d->leftWidget)
- height = qMax(d->leftWidget->sizeHint().height() + margin, height);
- if(d->rightWidget)
- height = qMax(d->rightWidget->sizeHint().height() + margin, height);
-#ifdef Q_WS_X11
- }
-#endif
- if(as_gui_menubar) {
- QStyleOptionMenuItem opt;
- opt.init(this);
- opt.menuRect = rect();
- opt.state = QStyle::State_None;
- opt.menuItemType = QStyleOptionMenuItem::Normal;
- opt.checkType = QStyleOptionMenuItem::NotCheckable;
- return style()->sizeFromContents(QStyle::CT_MenuBar, &opt, QSize(0, height), this).height(); //not pretty..
- }
- return height;
-}
-
-/*!
- \internal
-*/
-void QMenuBarPrivate::_q_internalShortcutActivated(int id)
-{
- Q_Q(QMenuBar);
- QAction *act = actions.at(id);
-#ifdef Q_WS_X11
- if (q->isNativeMenuBar()) {
- platformMenuBar->popupAction(act);
- } else {
-#endif
- setCurrentAction(act, true, true);
-#ifdef Q_WS_X11
- }
-#endif
- if (act && !act->menu()) {
- activateAction(act, QAction::Trigger);
- //100 is the same as the default value in QPushButton::animateClick
- autoReleaseTimer.start(100, q);
- } else if (act && q->style()->styleHint(QStyle::SH_MenuBar_AltKeyNavigation, 0, q)) {
- // When we open a menu using a shortcut, we should end up in keyboard state
- setKeyboardMode(true);
- }
-}
-
-void QMenuBarPrivate::_q_updateLayout()
-{
- Q_Q(QMenuBar);
- itemsDirty = true;
- if (q->isVisible()) {
- updateGeometries();
- q->update();
- }
-}
-
-#ifdef Q_WS_X11
-void QMenuBarPrivate::updateCornerWidgetToolBar()
-{
- Q_Q(QMenuBar);
- if (!cornerWidgetToolBar) {
- QMainWindow *window = qobject_cast<QMainWindow *>(q->window());
- if (!window) {
- qWarning() << "Menubar parent is not a QMainWindow, not showing corner widgets";
- return;
- }
- cornerWidgetToolBar = window->addToolBar(QApplication::translate("QMenuBar", "Corner Toolbar"));
- cornerWidgetToolBar->setObjectName(QLatin1String("CornerToolBar"));
- cornerWidgetContainer = new QWidget;
- cornerWidgetToolBar->addWidget(cornerWidgetContainer);
- new QHBoxLayout(cornerWidgetContainer);
- } else {
- QLayout *layout = cornerWidgetContainer->layout();
- while (layout->count() > 0) {
- layout->takeAt(0);
- }
- }
- if (leftWidget) {
- leftWidget->setParent(cornerWidgetContainer);
- cornerWidgetContainer->layout()->addWidget(leftWidget);
- }
- if (rightWidget) {
- rightWidget->setParent(cornerWidgetContainer);
- cornerWidgetContainer->layout()->addWidget(rightWidget);
- }
-}
-#endif
-
-
-/*!
- \fn void QMenuBar::setCornerWidget(QWidget *widget, Qt::Corner corner)
-
- This sets the given \a widget to be shown directly on the left of the first
- menu item, or on the right of the last menu item, depending on \a corner.
-
- The menu bar takes ownership of \a widget, reparenting it into the menu bar.
- However, if the \a corner already contains a widget, this previous widget
- will no longer be managed and will still be a visible child of the menu bar.
-
- \note Using a corner other than Qt::TopRightCorner or Qt::TopLeftCorner
- will result in a warning.
-*/
-void QMenuBar::setCornerWidget(QWidget *w, Qt::Corner corner)
-{
- Q_D(QMenuBar);
- switch (corner) {
- case Qt::TopLeftCorner:
- if (d->leftWidget)
- d->leftWidget->removeEventFilter(this);
- d->leftWidget = w;
- break;
- case Qt::TopRightCorner:
- if (d->rightWidget)
- d->rightWidget->removeEventFilter(this);
- d->rightWidget = w;
- break;
- default:
- qWarning("QMenuBar::setCornerWidget: Only TopLeftCorner and TopRightCorner are supported");
- return;
- }
-
-#ifdef Q_WS_X11
- if(!d->platformMenuBar->allowCornerWidgets()) {
- d->updateCornerWidgetToolBar();
- } else {
-#endif
- if (w) {
- w->setParent(this);
- w->installEventFilter(this);
- }
-#ifdef Q_WS_X11
- }
-#endif
-
- d->_q_updateLayout();
-}
-
-/*!
- Returns the widget on the left of the first or on the right of the last menu
- item, depending on \a corner.
-
- \note Using a corner other than Qt::TopRightCorner or Qt::TopLeftCorner
- will result in a warning.
-*/
-QWidget *QMenuBar::cornerWidget(Qt::Corner corner) const
-{
- Q_D(const QMenuBar);
- QWidget *w = 0;
- switch(corner) {
- case Qt::TopLeftCorner:
- w = d->leftWidget;
- break;
- case Qt::TopRightCorner:
- w = d->rightWidget;
- break;
- default:
- qWarning("QMenuBar::cornerWidget: Only TopLeftCorner and TopRightCorner are supported");
- break;
- }
-
- return w;
-}
-
-/*!
- \property QMenuBar::nativeMenuBar
- \brief Whether or not a menubar will be used as a native menubar on platforms that support it
- \since 4.6
-
- This property specifies whether or not the menubar should be used as a native menubar on platforms
- that support it. The currently supported platforms are Mac OS X and Windows CE. On these platforms
- if this property is true, the menubar is used in the native menubar and is not in the window of
- its parent, if false the menubar remains in the window. On other platforms the value of this
- attribute has no effect.
-
- The default is to follow whether the Qt::AA_DontUseNativeMenuBar attribute
- is set for the application. Explicitly settings this property overrides
- the presence (or abscence) of the attribute.
-*/
-
-void QMenuBar::setNativeMenuBar(bool nativeMenuBar)
-{
- Q_D(QMenuBar);
-#ifdef Q_WS_X11
- d->platformMenuBar->setNativeMenuBar(nativeMenuBar);
-#else
- if (d->nativeMenuBar == -1 || (nativeMenuBar != bool(d->nativeMenuBar))) {
- d->nativeMenuBar = nativeMenuBar;
-#ifdef Q_WS_MAC
- if (!d->nativeMenuBar) {
- extern void qt_mac_clear_menubar();
- qt_mac_clear_menubar();
- d->macDestroyMenuBar();
- const QList<QAction *> &menubarActions = actions();
- for (int i = 0; i < menubarActions.size(); ++i) {
- const QAction *action = menubarActions.at(i);
- if (QMenu *menu = action->menu()) {
- delete menu->d_func()->mac_menu;
- menu->d_func()->mac_menu = 0;
- }
- }
- } else {
- d->macCreateMenuBar(parentWidget());
- }
- macUpdateMenuBar();
- updateGeometry();
- if (!d->nativeMenuBar && parentWidget())
- setVisible(true);
-#endif
- }
-#endif // Q_WS_X11
-}
-
-bool QMenuBar::isNativeMenuBar() const
-{
- Q_D(const QMenuBar);
-#ifdef Q_WS_X11
- return d->platformMenuBar->isNativeMenuBar();
-#else
- if (d->nativeMenuBar == -1) {
- return !QApplication::instance()->testAttribute(Qt::AA_DontUseNativeMenuBar);
- }
- return d->nativeMenuBar;
-#endif
-}
-
-/*!
- \since 4.4
-
- Sets the default action to \a act.
-
- The default action is assigned to the left soft key. The menu is assigned
- to the right soft key.
-
- Currently there is only support for the default action on Windows
- Mobile. On all other platforms this method is not available.
-
- \sa defaultAction()
-*/
-
-#ifdef Q_WS_WINCE
-void QMenuBar::setDefaultAction(QAction *act)
-{
- Q_D(QMenuBar);
- if (d->defaultAction == act)
- return;
-#ifdef Q_WS_WINCE
- if (qt_wince_is_mobile())
- if (d->defaultAction) {
- disconnect(d->defaultAction, SIGNAL(changed()), this, SLOT(_q_updateDefaultAction()));
- disconnect(d->defaultAction, SIGNAL(destroyed()), this, SLOT(_q_updateDefaultAction()));
- }
-#endif
- d->defaultAction = act;
-#ifdef Q_WS_WINCE
- if (qt_wince_is_mobile())
- if (d->defaultAction) {
- connect(d->defaultAction, SIGNAL(changed()), this, SLOT(_q_updateDefaultAction()));
- connect(d->defaultAction, SIGNAL(destroyed()), this, SLOT(_q_updateDefaultAction()));
- }
- if (d->wce_menubar) {
- d->wce_menubar->rebuild();
- }
-#endif
-}
-
-/*!
- \since 4.4
-
- Returns the current default action.
-
- \sa setDefaultAction()
-*/
-QAction *QMenuBar::defaultAction() const
-{
- return d_func()->defaultAction;
-}
-#endif
-
-/*!
- \fn void QMenuBar::triggered(QAction *action)
-
- This signal is emitted when an action in a menu belonging to this menubar
- is triggered as a result of a mouse click; \a action is the action that
- caused the signal to be emitted.
-
- Normally, you connect each menu action to a single slot using
- QAction::triggered(), but sometimes you will want to connect
- several items to a single slot (most often if the user selects
- from an array). This signal is useful in such cases.
-
- \sa hovered(), QAction::triggered()
-*/
-
-/*!
- \fn void QMenuBar::hovered(QAction *action)
-
- This signal is emitted when a menu action is highlighted; \a action
- is the action that caused the event to be sent.
-
- Often this is used to update status information.
-
- \sa triggered(), QAction::hovered()
-*/
-
-
-#ifdef QT3_SUPPORT
-/*!
- Use style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, this)
- instead.
-*/
-int QMenuBar::frameWidth() const
-{
- return style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, this);
-}
-
-int QMenuBar::insertAny(const QIcon *icon, const QString *text, const QObject *receiver, const char *member,
- const QKeySequence *shortcut, const QMenu *popup, int id, int index)
-{
- QAction *act = popup ? popup->menuAction() : new QAction(this);
- if(id != -1)
- static_cast<QMenuItem*>(act)->setId(id);
- if(icon)
- act->setIcon(*icon);
- if(text)
- act->setText(*text);
- if(shortcut)
- act->setShortcut(*shortcut);
- if(receiver && member)
- QObject::connect(act, SIGNAL(triggered(bool)), receiver, member);
- if(index == -1 || index >= actions().count())
- addAction(act);
- else
- insertAction(actions().value(index), act);
- return findIdForAction(act);
-}
-
-/*!
- \since 4.2
-
- Use addSeparator() or insertAction() instead.
-
- \oldcode
- menuBar->insertSeparator();
- \newcode
- menuBar->addSeparator();
- \endcode
-*/
-int QMenuBar::insertSeparator(int index)
-{
- QAction *act = new QAction(this);
- act->setSeparator(true);
- if(index == -1 || index >= actions().count())
- addAction(act);
- else
- insertAction(actions().value(index), act);
- return findIdForAction(act);
-}
-
-/*!
- Use QAction::setData() instead.
-*/
-bool QMenuBar::setItemParameter(int id, int param)
-{
- if(QAction *act = findActionForId(id)) {
- act->d_func()->param = param;
- return true;
- }
- return false;
-}
-
-/*!
- Use QAction::data() instead.
-*/
-int QMenuBar::itemParameter(int id) const
-{
- if(QAction *act = findActionForId(id))
- return act->d_func()->param;
- return id;
-}
-
-QAction *QMenuBar::findActionForId(int id) const
-{
- QList<QAction *> list = actions();
- for (int i = 0; i < list.size(); ++i) {
- QAction *act = list.at(i);
- if (findIdForAction(act) == id)
- return act;
- }
- return 0;
-}
-
-int QMenuBar::findIdForAction(QAction *act) const
-{
- Q_ASSERT(act);
- return act->d_func()->id;
-}
-#endif
-
-/*!
- \fn void QMenuBar::addAction(QAction *action)
- \overload
-
- Appends the action \a action to the menu bar's list of actions.
-
- \sa QMenu::addAction(), QWidget::addAction(), QWidget::actions()
-*/
-
-/*!
- \fn uint QMenuBar::count() const
-
- Use actions().count() instead.
-*/
-
-/*!
- \fn int QMenuBar::insertItem(const QString &text, const QObject *receiver, const char* member, const QKeySequence& shortcut, int id, int index)
-
- Use one of the insertAction() or addAction() overloads instead.
-*/
-
-/*!
- \fn int QMenuBar::insertItem(const QIcon& icon, const QString &text, const QObject *receiver, const char* member, const QKeySequence& shortcut, int id, int index)
-
- Use one of the insertAction() or addAction() overloads instead.
-*/
-
-/*!
- \fn int QMenuBar::insertItem(const QPixmap &pixmap, const QObject *receiver, const char* member, const QKeySequence& shortcut, int id, int index)
-
- Use one of the insertAction(), addAction(), insertMenu(), or
- addMenu() overloads instead.
-*/
-
-/*!
- \fn int QMenuBar::insertItem(const QString &text, int id, int index)
-
- Use one of the insertAction() or addAction() overloads instead.
-*/
-
-/*!
- \fn int QMenuBar::insertItem(const QIcon& icon, const QString &text, int id, int index)
-
- Use one of the insertAction(), addAction(), insertMenu(), or
- addMenu() overloads instead.
-*/
-
-/*!
- \fn int QMenuBar::insertItem(const QString &text, QMenu *popup, int id, int index)
-
- Use one of the insertMenu(), or addMenu() overloads instead.
-*/
-
-/*!
- \fn int QMenuBar::insertItem(const QIcon& icon, const QString &text, QMenu *popup, int id, int index)
-
- Use one of the insertMenu(), or addMenu() overloads instead.
-*/
-
-/*!
- \fn int QMenuBar::insertItem(const QPixmap &pixmap, int id, int index)
-
- Use one of the insertAction(), addAction(), insertMenu(), or
- addMenu() overloads instead.
-*/
-
-/*!
- \fn int QMenuBar::insertItem(const QPixmap &pixmap, QMenu *popup, int id, int index)
-
- Use one of the insertMenu(), or addMenu() overloads instead.
-*/
-
-/*!
- \fn void QMenuBar::removeItem(int id)
-
- Use removeAction() instead.
-*/
-
-/*!
- \fn void QMenuBar::removeItemAt(int index)
-
- Use removeAction() instead.
-*/
-
-/*!
- \fn QKeySequence QMenuBar::accel(int id) const
-
- Use shortcut() on the relevant QAction instead.
-*/
-
-/*!
- \fn void QMenuBar::setAccel(const QKeySequence& key, int id)
-
- Use setShortcut() on the relevant QAction instead.
-*/
-
-/*!
- \fn QIcon QMenuBar::iconSet(int id) const
-
- Use icon() on the relevant QAction instead.
-*/
-
-/*!
- \fn QString QMenuBar::text(int id) const
-
- Use text() on the relevant QAction instead.
-*/
-
-/*!
- \fn QPixmap QMenuBar::pixmap(int id) const
-
- Use QPixmap(icon()) on the relevant QAction instead.
-*/
-
-/*!
- \fn void QMenuBar::setWhatsThis(int id, const QString &w)
-
- Use setWhatsThis() on the relevant QAction instead.
-*/
-
-/*!
- \fn QString QMenuBar::whatsThis(int id) const
-
- Use whatsThis() on the relevant QAction instead.
-*/
-
-/*!
- \fn void QMenuBar::changeItem(int id, const QString &text)
-
- Use setText() on the relevant QAction instead.
-*/
-
-/*!
- \fn void QMenuBar::changeItem(int id, const QPixmap &pixmap)
-
- Use setText() on the relevant QAction instead.
-*/
-
-/*!
- \fn void QMenuBar::changeItem(int id, const QIcon &icon, const QString &text)
-
- Use setIcon() and setText() on the relevant QAction instead.
-*/
-
-/*!
- \fn bool QMenuBar::isItemActive(int id) const
-
- Use activeAction() instead.
-*/
-
-/*!
- \fn bool QMenuBar::isItemEnabled(int id) const
-
- Use isEnabled() on the relevant QAction instead.
-*/
-
-/*!
- \fn void QMenuBar::setItemEnabled(int id, bool enable)
-
- Use setEnabled() on the relevant QAction instead.
-*/
-
-/*!
- \fn bool QMenuBar::isItemChecked(int id) const
-
- Use isChecked() on the relevant QAction instead.
-*/
-
-/*!
- \fn void QMenuBar::setItemChecked(int id, bool check)
-
- Use setChecked() on the relevant QAction instead.
-*/
-
-/*!
- \fn bool QMenuBar::isItemVisible(int id) const
-
- Use isVisible() on the relevant QAction instead.
-*/
-
-/*!
- \fn void QMenuBar::setItemVisible(int id, bool visible)
-
- Use setVisible() on the relevant QAction instead.
-*/
-
-/*!
- \fn int QMenuBar::indexOf(int id) const
-
- Use actions().indexOf(action) on the relevant QAction instead.
-*/
-
-/*!
- \fn int QMenuBar::idAt(int index) const
-
- Use actions instead.
-*/
-
-/*!
- \fn void QMenuBar::activateItemAt(int index)
-
- Use activate() on the relevant QAction instead.
-*/
-
-/*!
- \fn bool QMenuBar::connectItem(int id, const QObject *receiver, const char* member)
-
- Use connect() on the relevant QAction instead.
-*/
-
-/*!
- \fn bool QMenuBar::disconnectItem(int id,const QObject *receiver, const char* member)
-
- Use disconnect() on the relevant QAction instead.
-*/
-
-/*!
- \fn QMenuItem *QMenuBar::findItem(int id) const
-
- Use actions instead.
-*/
-
-/*!
- \fn Separator QMenuBar::separator() const
-
- This function is provided only to make old code compile.
-*/
-
-/*!
- \fn void QMenuBar::setSeparator(Separator sep)
-
- This function is provided only to make old code compile.
-*/
-
-/*!
- \fn QRect QMenuBar::itemRect(int index)
-
- Use actionGeometry() on the relevant QAction instead.
-*/
-
-/*!
- \fn int QMenuBar::itemAtPos(const QPoint &p)
-
- There is no equivalent way to achieve this in Qt 4.
-*/
-
-/*!
- \fn void QMenuBar::activated(int itemId);
-
- Use triggered() instead.
-*/
-
-/*!
- \fn void QMenuBar::highlighted(int itemId);
-
- Use hovered() instead.
-*/
-
-/*!
- \fn void QMenuBar::setFrameRect(QRect)
- \internal
-*/
-
-/*!
- \fn QRect QMenuBar::frameRect() const
- \internal
-*/
-/*!
- \enum QMenuBar::DummyFrame
- \internal
-
- \value Box
- \value Sunken
- \value Plain
- \value Raised
- \value MShadow
- \value NoFrame
- \value Panel
- \value StyledPanel
- \value HLine
- \value VLine
- \value GroupBoxPanel
- \value WinPanel
- \value ToolBarPanel
- \value MenuBarPanel
- \value PopupPanel
- \value LineEditPanel
- \value TabWidgetPanel
- \value MShape
-*/
-
-/*!
- \fn void QMenuBar::setFrameShadow(DummyFrame)
- \internal
-*/
-
-/*!
- \fn DummyFrame QMenuBar::frameShadow() const
- \internal
-*/
-
-/*!
- \fn void QMenuBar::setFrameShape(DummyFrame)
- \internal
-*/
-
-/*!
- \fn DummyFrame QMenuBar::frameShape() const
- \internal
-*/
-
-/*!
- \fn void QMenuBar::setFrameStyle(int)
- \internal
-*/
-
-/*!
- \fn int QMenuBar::frameStyle() const
- \internal
-*/
-
-/*!
- \fn void QMenuBar::setLineWidth(int)
- \internal
-*/
-
-/*!
- \fn int QMenuBar::lineWidth() const
- \internal
-*/
-
-/*!
- \fn void QMenuBar::setMargin(int margin)
- Sets the width of the margin around the contents of the widget to \a margin.
-
- Use QWidget::setContentsMargins() instead.
- \sa margin(), QWidget::setContentsMargins()
-*/
-
-/*!
- \fn int QMenuBar::margin() const
- Returns the width of the margin around the contents of the widget.
-
- Use QWidget::getContentsMargins() instead.
- \sa setMargin(), QWidget::getContentsMargins()
-*/
-
-/*!
- \fn void QMenuBar::setMidLineWidth(int)
- \internal
-*/
-
-/*!
- \fn int QMenuBar::midLineWidth() const
- \internal
-*/
-
-// for private slots
-
-
-QT_END_NAMESPACE
-
-#include <moc_qmenubar.cpp>
-
-#endif // QT_NO_MENUBAR
diff --git a/src/gui/widgets/qmenubar.h b/src/gui/widgets/qmenubar.h
deleted file mode 100644
index 48b0c05a7b..0000000000
--- a/src/gui/widgets/qmenubar.h
+++ /dev/null
@@ -1,367 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QMENUBAR_H
-#define QMENUBAR_H
-
-#include <QtGui/qmenu.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_MENUBAR
-
-class QMenuBarPrivate;
-class QStyleOptionMenuItem;
-class QWindowsStyle;
-#ifdef QT3_SUPPORT
-class QMenuItem;
-#endif
-
-class Q_GUI_EXPORT QMenuBar : public QWidget
-{
- Q_OBJECT
-
- Q_PROPERTY(bool defaultUp READ isDefaultUp WRITE setDefaultUp)
- Q_PROPERTY(bool nativeMenuBar READ isNativeMenuBar WRITE setNativeMenuBar)
-
-public:
- explicit QMenuBar(QWidget *parent = 0);
- ~QMenuBar();
-
-#ifdef Q_NO_USING_KEYWORD
- void addAction(QAction *action) { QWidget::addAction(action); }
-#else
- using QWidget::addAction;
-#endif
- QAction *addAction(const QString &text);
- QAction *addAction(const QString &text, const QObject *receiver, const char* member);
-
- QAction *addMenu(QMenu *menu);
- QMenu *addMenu(const QString &title);
- QMenu *addMenu(const QIcon &icon, const QString &title);
-
-
- QAction *addSeparator();
- QAction *insertSeparator(QAction *before);
-
- QAction *insertMenu(QAction *before, QMenu *menu);
-
- void clear();
-
- QAction *activeAction() const;
- void setActiveAction(QAction *action);
-
- void setDefaultUp(bool);
- bool isDefaultUp() const;
-
- QSize sizeHint() const;
- QSize minimumSizeHint() const;
- int heightForWidth(int) const;
-
- QRect actionGeometry(QAction *) const;
- QAction *actionAt(const QPoint &) const;
-
- void setCornerWidget(QWidget *w, Qt::Corner corner = Qt::TopRightCorner);
- QWidget *cornerWidget(Qt::Corner corner = Qt::TopRightCorner) const;
-
-#ifdef Q_WS_MAC
- OSMenuRef macMenu();
- static bool macUpdateMenuBar();
-#endif
-
-#ifdef Q_WS_WINCE
- void setDefaultAction(QAction *);
- QAction *defaultAction() const;
-
- static void wceCommands(uint command);
- static void wceRefresh();
-#endif
-
- bool isNativeMenuBar() const;
- void setNativeMenuBar(bool nativeMenuBar);
-
-public Q_SLOTS:
- virtual void setVisible(bool visible);
-
-Q_SIGNALS:
- void triggered(QAction *action);
- void hovered(QAction *action);
-
-protected:
- void changeEvent(QEvent *);
- void keyPressEvent(QKeyEvent *);
- void mouseReleaseEvent(QMouseEvent *);
- void mousePressEvent(QMouseEvent *);
- void mouseMoveEvent(QMouseEvent *);
- void leaveEvent(QEvent *);
- void paintEvent(QPaintEvent *);
- void resizeEvent(QResizeEvent *);
- void actionEvent(QActionEvent *);
- void focusOutEvent(QFocusEvent *);
- void focusInEvent(QFocusEvent *);
- void timerEvent(QTimerEvent *);
- bool eventFilter(QObject *, QEvent *);
- bool event(QEvent *);
- void initStyleOption(QStyleOptionMenuItem *option, const QAction *action) const;
-
-#ifdef QT3_SUPPORT
-public:
- QT3_SUPPORT_CONSTRUCTOR QMenuBar(QWidget *parent, const char *name);
- inline QT3_SUPPORT uint count() const { return actions().count(); }
- inline QT3_SUPPORT int insertItem(const QString &text, const QObject *receiver, const char* member,
- const QKeySequence& shortcut = 0, int id = -1, int index = -1) {
- return insertAny(0, &text, receiver, member, &shortcut, 0, id, index);
- }
- inline QT3_SUPPORT int insertItem(const QIcon& icon, const QString &text,
- const QObject *receiver, const char* member,
- const QKeySequence& shortcut = 0, int id = -1, int index = -1) {
- return insertAny(&icon, &text, receiver, member, &shortcut, 0, id, index);
- }
- inline QT3_SUPPORT int insertItem(const QPixmap &pixmap, const QObject *receiver, const char* member,
- const QKeySequence& shortcut = 0, int id = -1, int index = -1) {
- QIcon icon(pixmap);
- return insertAny(&icon, 0, receiver, member, &shortcut, 0, id, index);
- }
- inline QT3_SUPPORT int insertItem(const QString &text, int id=-1, int index=-1) {
- return insertAny(0, &text, 0, 0, 0, 0, id, index);
- }
- inline QT3_SUPPORT int insertItem(const QIcon& icon, const QString &text, int id=-1, int index=-1) {
- return insertAny(&icon, &text, 0, 0, 0, 0, id, index);
- }
- inline QT3_SUPPORT int insertItem(const QString &text, QMenu *popup, int id=-1, int index=-1) {
- return insertAny(0, &text, 0, 0, 0, popup, id, index);
- }
- inline QT3_SUPPORT int insertItem(const QIcon& icon, const QString &text, QMenu *popup, int id=-1, int index=-1) {
- return insertAny(&icon, &text, 0, 0, 0, popup, id, index);
- }
- inline QT3_SUPPORT int insertItem(const QPixmap &pixmap, int id=-1, int index=-1) {
- QIcon icon(pixmap);
- return insertAny(&icon, 0, 0, 0, 0, 0, id, index);
- }
- inline QT3_SUPPORT int insertItem(const QPixmap &pixmap, QMenu *popup, int id=-1, int index=-1) {
- QIcon icon(pixmap);
- return insertAny(&icon, 0, 0, 0, 0, popup, id, index);
- }
- QT3_SUPPORT int insertSeparator(int index=-1);
- inline QT3_SUPPORT void removeItem(int id) {
- if(QAction *act = findActionForId(id))
- removeAction(act); }
- inline QT3_SUPPORT void removeItemAt(int index) {
- if(QAction *act = actions().value(index))
- removeAction(act); }
-#ifndef QT_NO_SHORTCUT
- inline QT3_SUPPORT QKeySequence accel(int id) const {
- if(QAction *act = findActionForId(id))
- return act->shortcut();
- return QKeySequence(); }
- inline QT3_SUPPORT void setAccel(const QKeySequence& key, int id) {
- if(QAction *act = findActionForId(id))
- act->setShortcut(key);
- }
-#endif
- inline QT3_SUPPORT QIcon iconSet(int id) const {
- if(QAction *act = findActionForId(id))
- return act->icon();
- return QIcon(); }
- inline QT3_SUPPORT QString text(int id) const {
- if(QAction *act = findActionForId(id))
- return act->text();
- return QString(); }
- inline QT3_SUPPORT QPixmap pixmap(int id) const {
- if(QAction *act = findActionForId(id))
- return act->icon().pixmap(QSize(22,22));
- return QPixmap(); }
- inline QT3_SUPPORT void setWhatsThis(int id, const QString &w) {
- if(QAction *act = findActionForId(id))
- act->setWhatsThis(w); }
- inline QT3_SUPPORT QString whatsThis(int id) const {
- if(QAction *act = findActionForId(id))
- return act->whatsThis();
- return QString(); }
-
- inline QT3_SUPPORT void changeItem(int id, const QString &text) {
- if(QAction *act = findActionForId(id))
- act->setText(text); }
- inline QT3_SUPPORT void changeItem(int id, const QPixmap &pixmap) {
- if(QAction *act = findActionForId(id))
- act->setIcon(QIcon(pixmap)); }
- inline QT3_SUPPORT void changeItem(int id, const QIcon &icon, const QString &text) {
- if(QAction *act = findActionForId(id)) {
- act->setIcon(icon);
- act->setText(text);
- }
- }
- inline QT3_SUPPORT bool isItemActive(int id) const { return findActionForId(id) == activeAction(); }
- inline QT3_SUPPORT bool isItemEnabled(int id) const {
- if(QAction *act = findActionForId(id))
- return act->isEnabled();
- return false; }
- inline QT3_SUPPORT void setItemEnabled(int id, bool enable) {
- if(QAction *act = findActionForId(id))
- act->setEnabled(enable); }
- inline QT3_SUPPORT bool isItemChecked(int id) const {
- if(QAction *act = findActionForId(id))
- return act->isChecked();
- return false; }
- inline QT3_SUPPORT void setItemChecked(int id, bool check) {
- if(QAction *act = findActionForId(id))
- act->setChecked(check); }
- inline QT3_SUPPORT bool isItemVisible(int id) const {
- if(QAction *act = findActionForId(id))
- return act->isVisible();
- return false; }
- inline QT3_SUPPORT void setItemVisible(int id, bool visible) {
- if(QAction *act = findActionForId(id))
- act->setVisible(visible); }
- inline QT3_SUPPORT int indexOf(int id) const { return actions().indexOf(findActionForId(id)); }
- inline QT3_SUPPORT int idAt(int index) const {
- return index >= 0 && index < actions().size()
- ? findIdForAction(actions().at(index))
- : -1;
- }
- inline QT3_SUPPORT void activateItemAt(int index) {
- if(QAction *ret = actions().value(index))
- setActiveAction(ret);
- }
- inline QT3_SUPPORT bool connectItem(int id, const QObject *receiver, const char* member) {
- if(QAction *act = findActionForId(id)) {
- QObject::connect(act, SIGNAL(triggered()), receiver, member);
- return true;
- }
- return false;
- }
- inline QT3_SUPPORT bool disconnectItem(int id,const QObject *receiver, const char* member) {
- if(QAction *act = findActionForId(id)) {
- QObject::disconnect(act, SIGNAL(triggered()), receiver, member);
- return true;
- }
- return false;
- }
- inline QT3_SUPPORT QMenuItem *findItem(int id) const {
- return (QMenuItem*)findActionForId(id);
- }
- QT3_SUPPORT bool setItemParameter(int id, int param);
- QT3_SUPPORT int itemParameter(int id) const;
-
- //frame
- QT3_SUPPORT int frameWidth() const;
-
- QT3_SUPPORT void setFrameRect(QRect) {}
- QT3_SUPPORT QRect frameRect() const { return QRect(); }
- enum DummyFrame { Box, Sunken, Plain, Raised, MShadow, NoFrame, Panel, StyledPanel,
- HLine, VLine, GroupBoxPanel, WinPanel, ToolBarPanel, MenuBarPanel,
- PopupPanel, LineEditPanel, TabWidgetPanel, MShape };
- QT3_SUPPORT void setFrameShadow(DummyFrame) {}
- QT3_SUPPORT DummyFrame frameShadow() const { return Plain; }
- QT3_SUPPORT void setFrameShape(DummyFrame) {}
- QT3_SUPPORT DummyFrame frameShape() const { return NoFrame; }
- QT3_SUPPORT void setFrameStyle(int) {}
- QT3_SUPPORT int frameStyle() const { return 0; }
- QT3_SUPPORT void setLineWidth(int) {}
- QT3_SUPPORT int lineWidth() const { return 0; }
- QT3_SUPPORT void setMargin(int margin) { setContentsMargins(margin, margin, margin, margin); }
- QT3_SUPPORT int margin() const
- { int margin; int dummy; getContentsMargins(&margin, &dummy, &dummy, &dummy); return margin; }
- QT3_SUPPORT void setMidLineWidth(int) {}
- QT3_SUPPORT int midLineWidth() const { return 0; }
-
- //menubar
- enum Separator { Never=0, InWindowsStyle=1 };
- inline QT3_SUPPORT Separator separator() const { return InWindowsStyle; }
- inline QT3_SUPPORT void setSeparator(Separator) { }
-
- QT3_SUPPORT void setAutoGeometry(bool);
- QT3_SUPPORT bool autoGeometry() const;
-
-Q_SIGNALS:
- QT_MOC_COMPAT void activated(int itemId);
- QT_MOC_COMPAT void highlighted(int itemId);
-
-protected:
- inline QT3_SUPPORT QRect itemRect(int index) {
- if(QAction *act = actions().value(index))
- return actionGeometry(act);
- return QRect();
- }
- inline QT3_SUPPORT int itemAtPos(const QPoint &p) {
- return findIdForAction(actionAt(p));
- }
-private:
- QAction *findActionForId(int id) const;
- int insertAny(const QIcon *icon, const QString *text, const QObject *receiver, const char *member,
- const QKeySequence *shorcut, const QMenu *popup, int id, int index);
- int findIdForAction(QAction*) const;
-#endif
-
-private:
- Q_DECLARE_PRIVATE(QMenuBar)
- Q_DISABLE_COPY(QMenuBar)
- Q_PRIVATE_SLOT(d_func(), void _q_actionTriggered())
- Q_PRIVATE_SLOT(d_func(), void _q_actionHovered())
- Q_PRIVATE_SLOT(d_func(), void _q_internalShortcutActivated(int))
- Q_PRIVATE_SLOT(d_func(), void _q_updateLayout())
-
-#ifdef Q_WS_WINCE
- Q_PRIVATE_SLOT(d_func(), void _q_updateDefaultAction())
-#endif
-
- friend class QMenu;
- friend class QMenuPrivate;
- friend class QWindowsStyle;
-
-#ifdef Q_WS_MAC
- friend class QApplicationPrivate;
- friend class QWidgetPrivate;
- friend bool qt_mac_activate_action(MenuRef, uint, QAction::ActionEvent, bool);
-#endif
-};
-
-#endif // QT_NO_MENUBAR
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QMENUBAR_H
diff --git a/src/gui/widgets/qmenubar_p.h b/src/gui/widgets/qmenubar_p.h
deleted file mode 100644
index 9a1f75884a..0000000000
--- a/src/gui/widgets/qmenubar_p.h
+++ /dev/null
@@ -1,306 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QMENUBAR_P_H
-#define QMENUBAR_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// platformMenuBarementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#ifndef QMAC_Q3MENUBAR_CPP_FILE
-#include "QtGui/qstyleoption.h"
-#include <private/qmenu_p.h> // Mac needs what in this file!
-
-#ifdef Q_WS_WINCE
-#include "qguifunctions_wince.h"
-#endif
-
-#ifdef Q_WS_X11
-#include "qabstractplatformmenubar_p.h"
-#endif
-
-#ifndef QT_NO_MENUBAR
-#ifdef Q_WS_S60
-class CCoeControl;
-class CEikMenuBar;
-#endif
-#endif
-
-QT_BEGIN_NAMESPACE
-
-#ifndef QT_NO_MENUBAR
-class QToolBar;
-class QMenuBarExtension;
-class QMenuBarPrivate : public QWidgetPrivate
-{
- Q_DECLARE_PUBLIC(QMenuBar)
-public:
- QMenuBarPrivate() : itemsDirty(0), currentAction(0), mouseDown(0),
- closePopupMode(0), defaultPopDown(1), popupState(0), keyboardState(0), altPressed(0)
-#ifndef Q_WS_X11
- , nativeMenuBar(-1)
-#endif
- , doChildEffects(false)
-#ifdef QT3_SUPPORT
- , doAutoResize(false)
-#endif
-#ifdef Q_WS_MAC
- , mac_menubar(0)
-#endif
-#ifdef Q_WS_X11
- , platformMenuBar(0)
-#endif
-#ifdef Q_WS_WINCE
- , wce_menubar(0), wceClassicMenu(false)
-#endif
-#ifdef Q_WS_S60
- , symbian_menubar(0)
-#endif
-
- { }
- ~QMenuBarPrivate()
- {
-#ifdef Q_WS_X11
- delete platformMenuBar;
-#endif
-#ifdef Q_WS_MAC
- delete mac_menubar;
-#endif
-#ifdef Q_WS_WINCE
- delete wce_menubar;
-#endif
-#ifdef Q_WS_S60
- delete symbian_menubar;
-#endif
- }
-
- void init();
- QAction *getNextAction(const int start, const int increment) const;
-
- //item calculations
- uint itemsDirty : 1;
-
- QVector<int> shortcutIndexMap;
- mutable QVector<QRect> actionRects;
- void calcActionRects(int max_width, int start) const;
- QRect actionRect(QAction *) const;
- void updateGeometries();
-
- //selection
- QPointer<QAction>currentAction;
- uint mouseDown : 1, closePopupMode : 1, defaultPopDown;
- QAction *actionAt(QPoint p) const;
- void setCurrentAction(QAction *, bool =false, bool =false);
- void popupAction(QAction *, bool);
-
- //active popup state
- uint popupState : 1;
- QPointer<QMenu> activeMenu;
-
- //keyboard mode for keyboard navigation
- void focusFirstAction();
- void setKeyboardMode(bool);
- uint keyboardState : 1, altPressed : 1;
- QPointer<QWidget> keyboardFocusWidget;
-
-#ifndef Q_WS_X11
- int nativeMenuBar : 3; // Only has values -1, 0, and 1
-#endif
- //firing of events
- void activateAction(QAction *, QAction::ActionEvent);
-
- void _q_actionTriggered();
- void _q_actionHovered();
- void _q_internalShortcutActivated(int);
- void _q_updateLayout();
-
-#ifdef Q_WS_WINCE
- void _q_updateDefaultAction();
-#endif
-
- //extra widgets in the menubar
- QPointer<QWidget> leftWidget, rightWidget;
- QMenuBarExtension *extension;
- bool isVisible(QAction *action);
-
- //menu fading/scrolling effects
- bool doChildEffects;
-
- QRect menuRect(bool) const;
-
- // reparenting
- void handleReparent();
- QWidget *oldParent;
- QWidget *oldWindow;
-
- QList<QAction*> hiddenActions;
- //default action
- QPointer<QAction> defaultAction;
-
- QBasicTimer autoReleaseTimer;
-#ifdef QT3_SUPPORT
- bool doAutoResize;
-#endif
-#ifdef Q_WS_X11
- QAbstractPlatformMenuBar *platformMenuBar;
-#endif
-#ifdef Q_WS_MAC
- //mac menubar binding
- struct QMacMenuBarPrivate {
- QList<QMacMenuAction*> actionItems;
- OSMenuRef menu, apple_menu;
- QMacMenuBarPrivate();
- ~QMacMenuBarPrivate();
-
- void addAction(QAction *, QAction* =0);
- void addAction(QMacMenuAction *, QMacMenuAction* =0);
- void syncAction(QMacMenuAction *);
- inline void syncAction(QAction *a) { syncAction(findAction(a)); }
- void removeAction(QMacMenuAction *);
- inline void removeAction(QAction *a) { removeAction(findAction(a)); }
- inline QMacMenuAction *findAction(QAction *a) {
- for(int i = 0; i < actionItems.size(); i++) {
- QMacMenuAction *act = actionItems[i];
- if(a == act->action)
- return act;
- }
- return 0;
- }
- } *mac_menubar;
- static bool macUpdateMenuBarImmediatly();
- bool macWidgetHasNativeMenubar(QWidget *widget);
- void macCreateMenuBar(QWidget *);
- void macDestroyMenuBar();
- OSMenuRef macMenu();
-#endif
-#ifdef Q_WS_WINCE
- void wceCreateMenuBar(QWidget *);
- void wceDestroyMenuBar();
- struct QWceMenuBarPrivate {
- QList<QWceMenuAction*> actionItems;
- QList<QWceMenuAction*> actionItemsLeftButton;
- QList<QList<QWceMenuAction*>> actionItemsClassic;
- HMENU menuHandle;
- HMENU leftButtonMenuHandle;
- HWND menubarHandle;
- HWND parentWindowHandle;
- bool leftButtonIsMenu;
- QPointer<QAction> leftButtonAction;
- QMenuBarPrivate *d;
- int leftButtonCommand;
-
- QWceMenuBarPrivate(QMenuBarPrivate *menubar);
- ~QWceMenuBarPrivate();
- void addAction(QAction *, QAction* =0);
- void addAction(QWceMenuAction *, QWceMenuAction* =0);
- void syncAction(QWceMenuAction *);
- inline void syncAction(QAction *a) { syncAction(findAction(a)); }
- void removeAction(QWceMenuAction *);
- void rebuild();
- inline void removeAction(QAction *a) { removeAction(findAction(a)); }
- inline QWceMenuAction *findAction(QAction *a) {
- for(int i = 0; i < actionItems.size(); i++) {
- QWceMenuAction *act = actionItems[i];
- if(a == act->action)
- return act;
- }
- return 0;
- }
- } *wce_menubar;
- bool wceClassicMenu;
- void wceCommands(uint command);
- void wceRefresh();
- bool wceEmitSignals(QList<QWceMenuAction*> actions, uint command);
-#endif
-#ifdef Q_WS_S60
- void symbianCreateMenuBar(QWidget *);
- void symbianDestroyMenuBar();
- void reparentMenuBar(QWidget *oldParent, QWidget *newParent);
- struct QSymbianMenuBarPrivate {
- QList<QSymbianMenuAction*> actionItems;
- QMenuBarPrivate *d;
- QSymbianMenuBarPrivate(QMenuBarPrivate *menubar);
- ~QSymbianMenuBarPrivate();
- void addAction(QAction *, QAction* =0);
- void addAction(QSymbianMenuAction *, QSymbianMenuAction* =0);
- void syncAction(QSymbianMenuAction *);
- inline void syncAction(QAction *a) { syncAction(findAction(a)); }
- void removeAction(QSymbianMenuAction *);
- void rebuild();
- inline void removeAction(QAction *a) { removeAction(findAction(a)); }
- inline QSymbianMenuAction *findAction(QAction *a) {
- for(int i = 0; i < actionItems.size(); i++) {
- QSymbianMenuAction *act = actionItems[i];
- if(a == act->action)
- return act;
- }
- return 0;
- }
- void insertNativeMenuItems(const QList<QAction*> &actions);
-
- } *symbian_menubar;
- static int symbianCommands(int command);
-#endif
-#ifdef QT_SOFTKEYS_ENABLED
- QAction *menuBarAction;
-#endif
-
-#ifdef Q_WS_X11
- void updateCornerWidgetToolBar();
- QToolBar *cornerWidgetToolBar;
- QWidget *cornerWidgetContainer;
-#endif
-};
-#endif
-
-#endif // QT_NO_MENUBAR
-
-QT_END_NAMESPACE
-
-#endif // QMENUBAR_P_H
diff --git a/src/gui/widgets/qmenubar_x11.cpp b/src/gui/widgets/qmenubar_x11.cpp
deleted file mode 100644
index 25336d4378..0000000000
--- a/src/gui/widgets/qmenubar_x11.cpp
+++ /dev/null
@@ -1,139 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qmenubar_x11_p.h"
-
-#ifndef QT_NO_MENUBAR
-
-#include "qapplication.h"
-#include "qdebug.h"
-#include "qevent.h"
-#include "qmenu.h"
-#include "qmenubar.h"
-
-#include <private/qfactoryloader_p.h>
-
-QT_BEGIN_NAMESPACE
-
-QX11MenuBar::~QX11MenuBar()
-{
-}
-
-void QX11MenuBar::init(QMenuBar *_menuBar)
-{
- nativeMenuBar = -1;
- menuBar = _menuBar;
-}
-
-void QX11MenuBar::setVisible(bool visible)
-{
- menuBar->QWidget::setVisible(visible);
-}
-
-void QX11MenuBar::actionEvent(QActionEvent *e)
-{
- Q_UNUSED(e);
-}
-
-void QX11MenuBar::handleReparent(QWidget *oldParent, QWidget *newParent, QWidget *oldWindow, QWidget *newWindow)
-{
- Q_UNUSED(oldParent)
- Q_UNUSED(newParent)
- Q_UNUSED(oldWindow)
- Q_UNUSED(newWindow)
-}
-
-bool QX11MenuBar::allowCornerWidgets() const
-{
- return true;
-}
-
-void QX11MenuBar::popupAction(QAction *)
-{
-}
-
-void QX11MenuBar::setNativeMenuBar(bool value)
-{
- if (nativeMenuBar == -1 || (value != bool(nativeMenuBar))) {
- nativeMenuBar = value;
- }
-}
-
-bool QX11MenuBar::isNativeMenuBar() const
-{
- return false;
-}
-
-bool QX11MenuBar::shortcutsHandledByNativeMenuBar() const
-{
- return false;
-}
-
-bool QX11MenuBar::menuBarEventFilter(QObject *, QEvent *)
-{
- return false;
-}
-
-struct QX11MenuBarFactory : public QPlatformMenuBarFactoryInterface
-{
- QAbstractPlatformMenuBar *create() { return new QX11MenuBar; }
- virtual QStringList keys() const { return QStringList(); }
-};
-
-QPlatformMenuBarFactoryInterface *qt_guiPlatformMenuBarFactory()
-{
- static QPlatformMenuBarFactoryInterface *factory = 0;
- if (!factory) {
-#ifndef QT_NO_LIBRARY
- QFactoryLoader loader(QPlatformMenuBarFactoryInterface_iid, QLatin1String("/menubar"));
- factory = qobject_cast<QPlatformMenuBarFactoryInterface *>(loader.instance(QLatin1String("default")));
-#endif // QT_NO_LIBRARY
- if(!factory) {
- static QX11MenuBarFactory def;
- factory = &def;
- }
- }
- return factory;
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_MENUBAR
diff --git a/src/gui/widgets/qmenubar_x11_p.h b/src/gui/widgets/qmenubar_x11_p.h
deleted file mode 100644
index 41debd062a..0000000000
--- a/src/gui/widgets/qmenubar_x11_p.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QX11MENUBAR_P_H
-#define QX11MENUBAR_P_H
-
-#ifndef QT_NO_MENUBAR
-
-#include "qabstractplatformmenubar_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class QMenuBar;
-
-class QX11MenuBar : public QAbstractPlatformMenuBar
-{
-public:
- ~QX11MenuBar();
-
- virtual void init(QMenuBar *);
-
- virtual void setVisible(bool visible);
-
- virtual void actionEvent(QActionEvent *e);
-
- virtual void handleReparent(QWidget *oldParent, QWidget *newParent, QWidget *oldWindow, QWidget *newWindow);
-
- virtual bool allowCornerWidgets() const;
-
- virtual void popupAction(QAction*);
-
- virtual void setNativeMenuBar(bool);
- virtual bool isNativeMenuBar() const;
-
- virtual bool shortcutsHandledByNativeMenuBar() const;
- virtual bool menuBarEventFilter(QObject *, QEvent *event);
-
-private:
- QMenuBar *menuBar;
- int nativeMenuBar : 3; // Only has values -1, 0, and 1
-};
-
-QPlatformMenuBarFactoryInterface *qt_guiPlatformMenuBarFactory();
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_MENUBAR
-
-#endif /* QX11MENUBAR_P_H */
diff --git a/src/gui/widgets/qmenudata.cpp b/src/gui/widgets/qmenudata.cpp
deleted file mode 100644
index 595763aed1..0000000000
--- a/src/gui/widgets/qmenudata.cpp
+++ /dev/null
@@ -1,96 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#include "qmenudata.h"
-
-#ifdef QT3_SUPPORT
-#include <qaction.h>
-#include <private/qaction_p.h>
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \class QMenuItem
- \brief The QMenuItem class represents an item in a menu.
-
- \compat
-
- Use QAction instead.
-*/
-
-/*!
- \compat
- Constructs a new menu item.
-*/
-QMenuItem::QMenuItem() : QAction((QWidget*)0)
-{
-}
-
-void QMenuItem::setId(int id)
-{
- d_func()->param = d_func()->id = id;
-}
-
-/*!
- \compat
- Returns the menu item's ID.
-*/
-int QMenuItem::id() const
-{
- return d_func()->id;
-}
-
-void QMenuItem::setSignalValue(int param)
-{
- d_func()->param = param;
-}
-
-/*!
- \compat
- Returns the signal value for the menu item.
-*/
-int QMenuItem::signalValue() const
-{
- return d_func()->param;
-}
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/gui/widgets/qmenudata.h b/src/gui/widgets/qmenudata.h
deleted file mode 100644
index d02fcbb9bb..0000000000
--- a/src/gui/widgets/qmenudata.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QMENUDATA_H
-#define QMENUDATA_H
-
-#include <QtCore/qglobal.h>
-
-#ifdef QT3_SUPPORT
-#include <QtGui/qaction.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class Q_GUI_EXPORT QMenuItem : public QAction
-{
- Q_OBJECT
-
-public:
- QMenuItem();
-
- QT3_SUPPORT int id() const;
- QT3_SUPPORT int signalValue() const;
-private:
- friend class QMenu;
- friend class QMenuBar;
- void setId(int);
- void setSignalValue(int);
-
- Q_DISABLE_COPY(QMenuItem)
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif
-
-#endif // QMENUDATA_H
diff --git a/src/gui/widgets/qplaintextedit.cpp b/src/gui/widgets/qplaintextedit.cpp
deleted file mode 100644
index f2fca8fbdf..0000000000
--- a/src/gui/widgets/qplaintextedit.cpp
+++ /dev/null
@@ -1,2998 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qplaintextedit_p.h"
-
-
-#include <qfont.h>
-#include <qpainter.h>
-#include <qevent.h>
-#include <qdebug.h>
-#include <qmime.h>
-#include <qdrag.h>
-#include <qclipboard.h>
-#include <qmenu.h>
-#include <qstyle.h>
-#include <qtimer.h>
-#include "private/qtextdocumentlayout_p.h"
-#include "private/qabstracttextdocumentlayout_p.h"
-#include "qtextdocument.h"
-#include "private/qtextdocument_p.h"
-#include "qtextlist.h"
-#include "private/qtextcontrol_p.h"
-
-#include <qtextformat.h>
-#include <qdatetime.h>
-#include <qapplication.h>
-#include <limits.h>
-#include <qtexttable.h>
-#include <qvariant.h>
-#include <qinputcontext.h>
-
-#ifndef QT_NO_TEXTEDIT
-
-QT_BEGIN_NAMESPACE
-
-static inline bool shouldEnableInputMethod(QPlainTextEdit *plaintextedit)
-{
- return !plaintextedit->isReadOnly();
-}
-
-class QPlainTextDocumentLayoutPrivate : public QAbstractTextDocumentLayoutPrivate
-{
- Q_DECLARE_PUBLIC(QPlainTextDocumentLayout)
-public:
- QPlainTextDocumentLayoutPrivate() {
- mainViewPrivate = 0;
- width = 0;
- maximumWidth = 0;
- maximumWidthBlockNumber = 0;
- blockCount = 1;
- blockUpdate = blockDocumentSizeChanged = false;
- cursorWidth = 1;
- textLayoutFlags = 0;
- }
-
- qreal width;
- qreal maximumWidth;
- int maximumWidthBlockNumber;
- int blockCount;
- QPlainTextEditPrivate *mainViewPrivate;
- bool blockUpdate;
- bool blockDocumentSizeChanged;
- int cursorWidth;
- int textLayoutFlags;
-
- void layoutBlock(const QTextBlock &block);
- qreal blockWidth(const QTextBlock &block);
-
- void relayout();
-};
-
-
-
-/*! \class QPlainTextDocumentLayout
- \since 4.4
- \brief The QPlainTextDocumentLayout class implements a plain text layout for QTextDocument
-
- \ingroup richtext-processing
-
- A QPlainTextDocumentLayout is required for text documents that can
- be display or edited in a QPlainTextEdit. See
- QTextDocument::setDocumentLayout().
-
- QPlainTextDocumentLayout uses the QAbstractTextDocumentLayout API
- that QTextDocument requires, but redefines it partially in order to
- support plain text better. For instances, it does not operate on
- vertical pixels, but on paragraphs (called blocks) instead. The
- height of a document is identical to the number of paragraphs it
- contains. The layout also doesn't support tables or nested frames,
- or any sort of advanced text layout that goes beyond a list of
- paragraphs with syntax highlighting.
-
-*/
-
-
-
-/*!
- Constructs a plain text document layout for the text \a document.
- */
-QPlainTextDocumentLayout::QPlainTextDocumentLayout(QTextDocument *document)
- :QAbstractTextDocumentLayout(* new QPlainTextDocumentLayoutPrivate, document) {
-}
-/*!
- Destructs a plain text document layout.
- */
-QPlainTextDocumentLayout::~QPlainTextDocumentLayout() {}
-
-
-/*!
- \reimp
- */
-void QPlainTextDocumentLayout::draw(QPainter *, const PaintContext &)
-{
-}
-
-/*!
- \reimp
- */
-int QPlainTextDocumentLayout::hitTest(const QPointF &, Qt::HitTestAccuracy ) const
-{
-// this function is used from
-// QAbstractTextDocumentLayout::anchorAt(), but is not
-// implementable in a plain text document layout, because the
-// layout depends on the top block and top line which depends on
-// the view
- return -1;
-}
-
-/*!
- \reimp
- */
-int QPlainTextDocumentLayout::pageCount() const
-{ return 1; }
-
-/*!
- \reimp
- */
-QSizeF QPlainTextDocumentLayout::documentSize() const
-{
- Q_D(const QPlainTextDocumentLayout);
- return QSizeF(d->maximumWidth, document()->lineCount());
-}
-
-/*!
- \reimp
- */
-QRectF QPlainTextDocumentLayout::frameBoundingRect(QTextFrame *) const
-{
- Q_D(const QPlainTextDocumentLayout);
- return QRectF(0, 0, qMax(d->width, d->maximumWidth), qreal(INT_MAX));
-}
-
-/*!
- \reimp
- */
-QRectF QPlainTextDocumentLayout::blockBoundingRect(const QTextBlock &block) const
-{
- if (!block.isValid()) { return QRectF(); }
- QTextLayout *tl = block.layout();
- if (!tl->lineCount())
- const_cast<QPlainTextDocumentLayout*>(this)->layoutBlock(block);
- QRectF br;
- if (block.isVisible()) {
- br = QRectF(QPointF(0, 0), tl->boundingRect().bottomRight());
- if (tl->lineCount() == 1)
- br.setWidth(qMax(br.width(), tl->lineAt(0).naturalTextWidth()));
- qreal margin = document()->documentMargin();
- br.adjust(0, 0, margin, 0);
- if (!block.next().isValid())
- br.adjust(0, 0, 0, margin);
- }
- return br;
-
-}
-
-/*!
- Ensures that \a block has a valid layout
- */
-void QPlainTextDocumentLayout::ensureBlockLayout(const QTextBlock &block) const
-{
- if (!block.isValid())
- return;
- QTextLayout *tl = block.layout();
- if (!tl->lineCount())
- const_cast<QPlainTextDocumentLayout*>(this)->layoutBlock(block);
-}
-
-
-/*! \property QPlainTextDocumentLayout::cursorWidth
-
- This property specifies the width of the cursor in pixels. The default value is 1.
-*/
-void QPlainTextDocumentLayout::setCursorWidth(int width)
-{
- Q_D(QPlainTextDocumentLayout);
- d->cursorWidth = width;
-}
-
-int QPlainTextDocumentLayout::cursorWidth() const
-{
- Q_D(const QPlainTextDocumentLayout);
- return d->cursorWidth;
-}
-
-QPlainTextDocumentLayoutPrivate *QPlainTextDocumentLayout::priv() const
-{
- Q_D(const QPlainTextDocumentLayout);
- return const_cast<QPlainTextDocumentLayoutPrivate*>(d);
-}
-
-
-/*!
-
- Requests a complete update on all views.
- */
-void QPlainTextDocumentLayout::requestUpdate()
-{
- emit update(QRectF(0., -document()->documentMargin(), 1000000000., 1000000000.));
-}
-
-
-void QPlainTextDocumentLayout::setTextWidth(qreal newWidth)
-{
- Q_D(QPlainTextDocumentLayout);
- d->width = d->maximumWidth = newWidth;
- d->relayout();
-}
-
-qreal QPlainTextDocumentLayout::textWidth() const
-{
- Q_D(const QPlainTextDocumentLayout);
- return d->width;
-}
-
-void QPlainTextDocumentLayoutPrivate::relayout()
-{
- Q_Q(QPlainTextDocumentLayout);
- QTextBlock block = q->document()->firstBlock();
- while (block.isValid()) {
- block.layout()->clearLayout();
- block.setLineCount(block.isVisible() ? 1 : 0);
- block = block.next();
- }
- emit q->update();
-}
-
-
-/*! \reimp
- */
-void QPlainTextDocumentLayout::documentChanged(int from, int /*charsRemoved*/, int charsAdded)
-{
- Q_D(QPlainTextDocumentLayout);
- QTextDocument *doc = document();
- int newBlockCount = doc->blockCount();
-
- QTextBlock changeStartBlock = doc->findBlock(from);
- QTextBlock changeEndBlock = doc->findBlock(qMax(0, from + charsAdded - 1));
-
- if (changeStartBlock == changeEndBlock && newBlockCount == d->blockCount) {
- QTextBlock block = changeStartBlock;
- int blockLineCount = block.layout()->lineCount();
- if (block.isValid() && blockLineCount) {
- QRectF oldBr = blockBoundingRect(block);
- layoutBlock(block);
- QRectF newBr = blockBoundingRect(block);
- if (newBr.height() == oldBr.height()) {
- if (!d->blockUpdate)
- emit updateBlock(block);
- return;
- }
- }
- } else {
- QTextBlock block = changeStartBlock;
- do {
- block.clearLayout();
- if (block == changeEndBlock)
- break;
- block = block.next();
- } while(block.isValid());
- }
-
- if (newBlockCount != d->blockCount) {
-
- int changeEnd = changeEndBlock.blockNumber();
- int blockDiff = newBlockCount - d->blockCount;
- int oldChangeEnd = changeEnd - blockDiff;
-
- if (d->maximumWidthBlockNumber > oldChangeEnd)
- d->maximumWidthBlockNumber += blockDiff;
-
- d->blockCount = newBlockCount;
- if (d->blockCount == 1)
- d->maximumWidth = blockWidth(doc->firstBlock());
-
- if (!d->blockDocumentSizeChanged)
- emit documentSizeChanged(documentSize());
-
- if (blockDiff == 1 && changeEnd == newBlockCount -1 ) {
- if (!d->blockUpdate) {
- QTextBlock b = changeStartBlock;
- for(;;) {
- emit updateBlock(b);
- if (b == changeEndBlock)
- break;
- b = b.next();
- }
- }
- return;
- }
- }
-
- if (!d->blockUpdate)
- emit update(QRectF(0., -doc->documentMargin(), 1000000000., 1000000000.)); // optimization potential
-}
-
-
-void QPlainTextDocumentLayout::layoutBlock(const QTextBlock &block)
-{
- Q_D(QPlainTextDocumentLayout);
- QTextDocument *doc = document();
- qreal margin = doc->documentMargin();
- qreal blockMaximumWidth = 0;
-
- qreal height = 0;
- QTextLayout *tl = block.layout();
- QTextOption option = doc->defaultTextOption();
- tl->setTextOption(option);
-
- int extraMargin = 0;
- if (option.flags() & QTextOption::AddSpaceForLineAndParagraphSeparators) {
- QFontMetrics fm(block.charFormat().font());
- extraMargin += fm.width(QChar(0x21B5));
- }
- tl->beginLayout();
- qreal availableWidth = d->width;
- if (availableWidth <= 0) {
- availableWidth = qreal(INT_MAX); // similar to text edit with pageSize.width == 0
- }
- availableWidth -= 2*margin + extraMargin;
- while (1) {
- QTextLine line = tl->createLine();
- if (!line.isValid())
- break;
- line.setLeadingIncluded(true);
- line.setLineWidth(availableWidth);
- line.setPosition(QPointF(margin, height));
- height += line.height();
- blockMaximumWidth = qMax(blockMaximumWidth, line.naturalTextWidth() + 2*margin);
- }
- tl->endLayout();
-
- int previousLineCount = doc->lineCount();
- const_cast<QTextBlock&>(block).setLineCount(block.isVisible() ? tl->lineCount() : 0);
- int lineCount = doc->lineCount();
-
- bool emitDocumentSizeChanged = previousLineCount != lineCount;
- if (blockMaximumWidth > d->maximumWidth) {
- // new longest line
- d->maximumWidth = blockMaximumWidth;
- d->maximumWidthBlockNumber = block.blockNumber();
- emitDocumentSizeChanged = true;
- } else if (block.blockNumber() == d->maximumWidthBlockNumber && blockMaximumWidth < d->maximumWidth) {
- // longest line shrinking
- QTextBlock b = doc->firstBlock();
- d->maximumWidth = 0;
- QTextBlock maximumBlock;
- while (b.isValid()) {
- qreal blockMaximumWidth = blockWidth(b);
- if (blockMaximumWidth > d->maximumWidth) {
- d->maximumWidth = blockMaximumWidth;
- maximumBlock = b;
- }
- b = b.next();
- }
- if (maximumBlock.isValid()) {
- d->maximumWidthBlockNumber = maximumBlock.blockNumber();
- emitDocumentSizeChanged = true;
- }
- }
- if (emitDocumentSizeChanged && !d->blockDocumentSizeChanged)
- emit documentSizeChanged(documentSize());
-}
-
-qreal QPlainTextDocumentLayout::blockWidth(const QTextBlock &block)
-{
- QTextLayout *layout = block.layout();
- if (!layout->lineCount())
- return 0; // only for layouted blocks
- qreal blockWidth = 0;
- for (int i = 0; i < layout->lineCount(); ++i) {
- QTextLine line = layout->lineAt(i);
- blockWidth = qMax(line.naturalTextWidth() + 8, blockWidth);
- }
- return blockWidth;
-}
-
-
-QPlainTextEditControl::QPlainTextEditControl(QPlainTextEdit *parent)
- : QTextControl(parent), textEdit(parent),
- topBlock(0)
-{
- setAcceptRichText(false);
-}
-
-void QPlainTextEditPrivate::_q_cursorPositionChanged()
-{
- pageUpDownLastCursorYIsValid = false;
-}
-
-void QPlainTextEditPrivate::_q_verticalScrollbarActionTriggered(int action) {
- if (action == QAbstractSlider::SliderPageStepAdd) {
- pageUpDown(QTextCursor::Down, QTextCursor::MoveAnchor, false);
- } else if (action == QAbstractSlider::SliderPageStepSub) {
- pageUpDown(QTextCursor::Up, QTextCursor::MoveAnchor, false);
- }
-}
-
-QMimeData *QPlainTextEditControl::createMimeDataFromSelection() const {
- QPlainTextEdit *ed = qobject_cast<QPlainTextEdit *>(parent());
- if (!ed)
- return QTextControl::createMimeDataFromSelection();
- return ed->createMimeDataFromSelection();
- }
-bool QPlainTextEditControl::canInsertFromMimeData(const QMimeData *source) const {
- QPlainTextEdit *ed = qobject_cast<QPlainTextEdit *>(parent());
- if (!ed)
- return QTextControl::canInsertFromMimeData(source);
- return ed->canInsertFromMimeData(source);
-}
-void QPlainTextEditControl::insertFromMimeData(const QMimeData *source) {
- QPlainTextEdit *ed = qobject_cast<QPlainTextEdit *>(parent());
- if (!ed)
- QTextControl::insertFromMimeData(source);
- else
- ed->insertFromMimeData(source);
-}
-
-int QPlainTextEditPrivate::verticalOffset(int topBlock, int topLine) const
-{
- qreal offset = 0;
- QTextDocument *doc = control->document();
-
- if (topLine) {
- QTextBlock currentBlock = doc->findBlockByNumber(topBlock);
- QPlainTextDocumentLayout *documentLayout = qobject_cast<QPlainTextDocumentLayout*>(doc->documentLayout());
- Q_ASSERT(documentLayout);
- QRectF r = documentLayout->blockBoundingRect(currentBlock);
- Q_UNUSED(r);
- QTextLayout *layout = currentBlock.layout();
- if (layout && topLine <= layout->lineCount()) {
- QTextLine line = layout->lineAt(topLine - 1);
- const QRectF lr = line.naturalTextRect();
- offset = lr.bottom();
- }
- }
- if (topBlock == 0 && topLine == 0)
- offset -= doc->documentMargin(); // top margin
- return (int)offset;
-}
-
-
-int QPlainTextEditPrivate::verticalOffset() const {
- return verticalOffset(control->topBlock, topLine);
-}
-
-
-QTextBlock QPlainTextEditControl::firstVisibleBlock() const
-{
- return document()->findBlockByNumber(topBlock);
-}
-
-
-
-int QPlainTextEditControl::hitTest(const QPointF &point, Qt::HitTestAccuracy ) const {
- int currentBlockNumber = topBlock;
- QTextBlock currentBlock = document()->findBlockByNumber(currentBlockNumber);
- if (!currentBlock.isValid())
- return -1;
-
- QPlainTextDocumentLayout *documentLayout = qobject_cast<QPlainTextDocumentLayout*>(document()->documentLayout());
- Q_ASSERT(documentLayout);
-
- QPointF offset;
- QRectF r = documentLayout->blockBoundingRect(currentBlock);
- while (currentBlock.next().isValid() && r.bottom() + offset.y() <= point.y()) {
- offset.ry() += r.height();
- currentBlock = currentBlock.next();
- ++currentBlockNumber;
- r = documentLayout->blockBoundingRect(currentBlock);
- }
- while (currentBlock.previous().isValid() && r.top() + offset.y() > point.y()) {
- offset.ry() -= r.height();
- currentBlock = currentBlock.previous();
- --currentBlockNumber;
- r = documentLayout->blockBoundingRect(currentBlock);
- }
-
-
- if (!currentBlock.isValid())
- return -1;
- QTextLayout *layout = currentBlock.layout();
- int off = 0;
- QPointF pos = point - offset;
- for (int i = 0; i < layout->lineCount(); ++i) {
- QTextLine line = layout->lineAt(i);
- const QRectF lr = line.naturalTextRect();
- if (lr.top() > pos.y()) {
- off = qMin(off, line.textStart());
- } else if (lr.bottom() <= pos.y()) {
- off = qMax(off, line.textStart() + line.textLength());
- } else {
- off = line.xToCursor(pos.x(), overwriteMode() ?
- QTextLine::CursorOnCharacter : QTextLine::CursorBetweenCharacters);
- break;
- }
- }
-
- return currentBlock.position() + off;
-}
-
-QRectF QPlainTextEditControl::blockBoundingRect(const QTextBlock &block) const {
- int currentBlockNumber = topBlock;
- int blockNumber = block.blockNumber();
- QTextBlock currentBlock = document()->findBlockByNumber(currentBlockNumber);
- if (!currentBlock.isValid())
- return QRectF();
- Q_ASSERT(currentBlock.blockNumber() == currentBlockNumber);
- QTextDocument *doc = document();
- QPlainTextDocumentLayout *documentLayout = qobject_cast<QPlainTextDocumentLayout*>(doc->documentLayout());
- Q_ASSERT(documentLayout);
-
- QPointF offset;
- if (!block.isValid())
- return QRectF();
- QRectF r = documentLayout->blockBoundingRect(currentBlock);
- int maxVerticalOffset = r.height();
- while (currentBlockNumber < blockNumber && offset.y() - maxVerticalOffset <= 2* textEdit->viewport()->height()) {
- offset.ry() += r.height();
- currentBlock = currentBlock.next();
- ++currentBlockNumber;
- if (!currentBlock.isVisible()) {
- currentBlock = doc->findBlockByLineNumber(currentBlock.firstLineNumber());
- currentBlockNumber = currentBlock.blockNumber();
- }
- r = documentLayout->blockBoundingRect(currentBlock);
- }
- while (currentBlockNumber > blockNumber && offset.y() + maxVerticalOffset >= -textEdit->viewport()->height()) {
- currentBlock = currentBlock.previous();
- --currentBlockNumber;
- while (!currentBlock.isVisible()) {
- currentBlock = currentBlock.previous();
- --currentBlockNumber;
- }
- if (!currentBlock.isValid())
- break;
-
- r = documentLayout->blockBoundingRect(currentBlock);
- offset.ry() -= r.height();
- }
-
- if (currentBlockNumber != blockNumber) {
- // fallback for blocks out of reach. Give it some geometry at
- // least, and ensure the layout is up to date.
- r = documentLayout->blockBoundingRect(block);
- if (currentBlockNumber > blockNumber)
- offset.ry() -= r.height();
- }
- r.translate(offset);
- return r;
-}
-
-
-void QPlainTextEditPrivate::setTopLine(int visualTopLine, int dx)
-{
- QTextDocument *doc = control->document();
- QTextBlock block = doc->findBlockByLineNumber(visualTopLine);
- int blockNumber = block.blockNumber();
- int lineNumber = visualTopLine - block.firstLineNumber();
- setTopBlock(blockNumber, lineNumber, dx);
-}
-
-void QPlainTextEditPrivate::setTopBlock(int blockNumber, int lineNumber, int dx)
-{
- Q_Q(QPlainTextEdit);
- blockNumber = qMax(0, blockNumber);
- lineNumber = qMax(0, lineNumber);
- QTextDocument *doc = control->document();
- QTextBlock block = doc->findBlockByNumber(blockNumber);
-
- int newTopLine = block.firstLineNumber() + lineNumber;
- int maxTopLine = vbar->maximum();
-
- if (newTopLine > maxTopLine) {
- block = doc->findBlockByLineNumber(maxTopLine);
- blockNumber = block.blockNumber();
- lineNumber = maxTopLine - block.firstLineNumber();
- }
-
- bool vbarSignalsBlocked = vbar->blockSignals(true);
- vbar->setValue(newTopLine);
- vbar->blockSignals(vbarSignalsBlocked);
-
- if (!dx && blockNumber == control->topBlock && lineNumber == topLine)
- return;
-
- if (viewport->updatesEnabled() && viewport->isVisible()) {
- int dy = 0;
- if (doc->findBlockByNumber(control->topBlock).isValid()) {
- dy = (int)(-q->blockBoundingGeometry(block).y())
- + verticalOffset() - verticalOffset(blockNumber, lineNumber);
- }
- control->topBlock = blockNumber;
- topLine = lineNumber;
-
- bool vbarSignalsBlocked = vbar->blockSignals(true);
- vbar->setValue(block.firstLineNumber() + lineNumber);
- vbar->blockSignals(vbarSignalsBlocked);
-
- if (dx || dy)
- viewport->scroll(q->isRightToLeft() ? -dx : dx, dy);
- else
- viewport->update();
- emit q->updateRequest(viewport->rect(), dy);
- } else {
- control->topBlock = blockNumber;
- topLine = lineNumber;
- }
-
-}
-
-
-
-void QPlainTextEditPrivate::ensureVisible(int position, bool center, bool forceCenter) {
- Q_Q(QPlainTextEdit);
- QRectF visible = QRectF(viewport->rect()).translated(-q->contentOffset());
- QTextBlock block = control->document()->findBlock(position);
- if (!block.isValid())
- return;
- QRectF br = control->blockBoundingRect(block);
- if (!br.isValid())
- return;
- QRectF lr = br;
- QTextLine line = block.layout()->lineForTextPosition(position - block.position());
- Q_ASSERT(line.isValid());
- lr = line.naturalTextRect().translated(br.topLeft());
-
- if (lr.bottom() >= visible.bottom() || (center && lr.top() < visible.top()) || forceCenter){
-
- qreal height = visible.height();
- if (center)
- height /= 2;
-
- qreal h = center ? line.naturalTextRect().center().y() : line.naturalTextRect().bottom();
-
- QTextBlock previousVisibleBlock = block;
- while (h < height && block.previous().isValid()) {
- previousVisibleBlock = block;
- do {
- block = block.previous();
- } while (!block.isVisible() && block.previous().isValid());
- h += q->blockBoundingRect(block).height();
- }
-
- int l = 0;
- int lineCount = block.layout()->lineCount();
- int voffset = verticalOffset(block.blockNumber(), 0);
- while (l < lineCount) {
- QRectF lineRect = block.layout()->lineAt(l).naturalTextRect();
- if (h - voffset - lineRect.top() <= height)
- break;
- ++l;
- }
-
- if (l >= lineCount) {
- block = previousVisibleBlock;
- l = 0;
- }
- setTopBlock(block.blockNumber(), l);
- } else if (lr.top() < visible.top()) {
- setTopBlock(block.blockNumber(), line.lineNumber());
- }
-
-}
-
-
-void QPlainTextEditPrivate::updateViewport()
-{
- Q_Q(QPlainTextEdit);
- viewport->update();
- emit q->updateRequest(viewport->rect(), 0);
-}
-
-QPlainTextEditPrivate::QPlainTextEditPrivate()
- : control(0),
- tabChangesFocus(false),
- lineWrap(QPlainTextEdit::WidgetWidth),
- wordWrap(QTextOption::WrapAtWordBoundaryOrAnywhere),
- clickCausedFocus(0),topLine(0),
- pageUpDownLastCursorYIsValid(false)
-{
- showCursorOnInitialShow = true;
- backgroundVisible = false;
- centerOnScroll = false;
- inDrag = false;
-}
-
-
-void QPlainTextEditPrivate::init(const QString &txt)
-{
- Q_Q(QPlainTextEdit);
- control = new QPlainTextEditControl(q);
-
- QTextDocument *doc = new QTextDocument(control);
- QAbstractTextDocumentLayout *layout = new QPlainTextDocumentLayout(doc);
- doc->setDocumentLayout(layout);
- control->setDocument(doc);
-
- control->setPalette(q->palette());
-
- QObject::connect(vbar, SIGNAL(actionTriggered(int)), q, SLOT(_q_verticalScrollbarActionTriggered(int)));
-
- QObject::connect(control, SIGNAL(microFocusChanged()), q, SLOT(updateMicroFocus()));
- QObject::connect(control, SIGNAL(documentSizeChanged(QSizeF)), q, SLOT(_q_adjustScrollbars()));
- QObject::connect(control, SIGNAL(blockCountChanged(int)), q, SIGNAL(blockCountChanged(int)));
- QObject::connect(control, SIGNAL(updateRequest(QRectF)), q, SLOT(_q_repaintContents(QRectF)));
- QObject::connect(control, SIGNAL(modificationChanged(bool)), q, SIGNAL(modificationChanged(bool)));
-
- QObject::connect(control, SIGNAL(textChanged()), q, SIGNAL(textChanged()));
- QObject::connect(control, SIGNAL(undoAvailable(bool)), q, SIGNAL(undoAvailable(bool)));
- QObject::connect(control, SIGNAL(redoAvailable(bool)), q, SIGNAL(redoAvailable(bool)));
- QObject::connect(control, SIGNAL(copyAvailable(bool)), q, SIGNAL(copyAvailable(bool)));
- QObject::connect(control, SIGNAL(selectionChanged()), q, SIGNAL(selectionChanged()));
- QObject::connect(control, SIGNAL(cursorPositionChanged()), q, SLOT(_q_cursorPositionChanged()));
- QObject::connect(control, SIGNAL(cursorPositionChanged()), q, SIGNAL(cursorPositionChanged()));
-
- QObject::connect(control, SIGNAL(textChanged()), q, SLOT(updateMicroFocus()));
-
- // set a null page size initially to avoid any relayouting until the textedit
- // is shown. relayoutDocument() will take care of setting the page size to the
- // viewport dimensions later.
- doc->setTextWidth(-1);
- doc->documentLayout()->setPaintDevice(viewport);
- doc->setDefaultFont(q->font());
-
-
- if (!txt.isEmpty())
- control->setPlainText(txt);
-
- hbar->setSingleStep(20);
- vbar->setSingleStep(1);
-
- viewport->setBackgroundRole(QPalette::Base);
- q->setAcceptDrops(true);
- q->setFocusPolicy(Qt::WheelFocus);
- q->setAttribute(Qt::WA_KeyCompression);
- q->setAttribute(Qt::WA_InputMethodEnabled);
-
-#ifndef QT_NO_CURSOR
- viewport->setCursor(Qt::IBeamCursor);
-#endif
- originalOffsetY = 0;
-#ifdef Q_WS_WIN
- setSingleFingerPanEnabled(true);
-#endif
-}
-
-void QPlainTextEditPrivate::_q_repaintContents(const QRectF &contentsRect)
-{
- Q_Q(QPlainTextEdit);
- if (!contentsRect.isValid()) {
- updateViewport();
- return;
- }
- const int xOffset = horizontalOffset();
- const int yOffset = verticalOffset();
- const QRect visibleRect(xOffset, yOffset, viewport->width(), viewport->height());
-
- QRect r = contentsRect.adjusted(-1, -1, 1, 1).intersected(visibleRect).toAlignedRect();
- if (r.isEmpty())
- return;
-
- r.translate(-xOffset, -yOffset);
- viewport->update(r);
- emit q->updateRequest(r, 0);
-}
-
-void QPlainTextEditPrivate::pageUpDown(QTextCursor::MoveOperation op, QTextCursor::MoveMode moveMode, bool moveCursor)
-{
-
- Q_Q(QPlainTextEdit);
-
- QTextCursor cursor = control->textCursor();
- if (moveCursor) {
- ensureCursorVisible();
- if (!pageUpDownLastCursorYIsValid)
- pageUpDownLastCursorY = control->cursorRect(cursor).top() - verticalOffset();
- }
-
- qreal lastY = pageUpDownLastCursorY;
-
-
- if (op == QTextCursor::Down) {
- QRectF visible = QRectF(viewport->rect()).translated(-q->contentOffset());
- QTextBlock firstVisibleBlock = q->firstVisibleBlock();
- QTextBlock block = firstVisibleBlock;
- QRectF br = q->blockBoundingRect(block);
- qreal h = 0;
- int atEnd = false;
- while (h + br.height() <= visible.bottom()) {
- if (!block.next().isValid()) {
- atEnd = true;
- lastY = visible.bottom(); // set cursor to last line
- break;
- }
- h += br.height();
- block = block.next();
- br = q->blockBoundingRect(block);
- }
-
- if (!atEnd) {
- int line = 0;
- qreal diff = visible.bottom() - h;
- int lineCount = block.layout()->lineCount();
- while (line < lineCount - 1) {
- if (block.layout()->lineAt(line).naturalTextRect().bottom() > diff) {
- // the first line that did not completely fit the screen
- break;
- }
- ++line;
- }
- setTopBlock(block.blockNumber(), line);
- }
-
- if (moveCursor) {
- // move using movePosition to keep the cursor's x
- lastY += verticalOffset();
- bool moved = false;
- do {
- moved = cursor.movePosition(op, moveMode);
- } while (moved && control->cursorRect(cursor).top() < lastY);
- }
-
- } else if (op == QTextCursor::Up) {
-
- QRectF visible = QRectF(viewport->rect()).translated(-q->contentOffset());
- visible.translate(0, -visible.height()); // previous page
- QTextBlock block = q->firstVisibleBlock();
- qreal h = 0;
- while (h >= visible.top()) {
- if (!block.previous().isValid()) {
- if (control->topBlock == 0 && topLine == 0) {
- lastY = 0; // set cursor to first line
- }
- break;
- }
- block = block.previous();
- QRectF br = q->blockBoundingRect(block);
- h -= br.height();
- }
-
- int line = 0;
- if (block.isValid()) {
- qreal diff = visible.top() - h;
- int lineCount = block.layout()->lineCount();
- while (line < lineCount) {
- if (block.layout()->lineAt(line).naturalTextRect().top() >= diff)
- break;
- ++line;
- }
- if (line == lineCount) {
- if (block.next().isValid() && block.next() != q->firstVisibleBlock()) {
- block = block.next();
- line = 0;
- } else {
- --line;
- }
- }
- }
- setTopBlock(block.blockNumber(), line);
-
- if (moveCursor) {
- cursor.setVisualNavigation(true);
- // move using movePosition to keep the cursor's x
- lastY += verticalOffset();
- bool moved = false;
- do {
- moved = cursor.movePosition(op, moveMode);
- } while (moved && control->cursorRect(cursor).top() > lastY);
- }
- }
-
- if (moveCursor) {
- control->setTextCursor(cursor);
- pageUpDownLastCursorYIsValid = true;
- }
-}
-
-#ifndef QT_NO_SCROLLBAR
-
-void QPlainTextEditPrivate::_q_adjustScrollbars()
-{
- Q_Q(QPlainTextEdit);
- QTextDocument *doc = control->document();
- QPlainTextDocumentLayout *documentLayout = qobject_cast<QPlainTextDocumentLayout*>(doc->documentLayout());
- Q_ASSERT(documentLayout);
- bool documentSizeChangedBlocked = documentLayout->priv()->blockDocumentSizeChanged;
- documentLayout->priv()->blockDocumentSizeChanged = true;
- qreal margin = doc->documentMargin();
-
- int vmax = 0;
-
- int vSliderLength = 0;
- if (!centerOnScroll && q->isVisible()) {
- QTextBlock block = doc->lastBlock();
- const qreal visible = viewport->rect().height() - margin - 1;
- qreal y = 0;
- int visibleFromBottom = 0;
-
- while (block.isValid()) {
- if (!block.isVisible()) {
- block = block.previous();
- continue;
- }
- y += documentLayout->blockBoundingRect(block).height();
-
- QTextLayout *layout = block.layout();
- int layoutLineCount = layout->lineCount();
- if (y > visible) {
- int lineNumber = 0;
- while (lineNumber < layoutLineCount) {
- QTextLine line = layout->lineAt(lineNumber);
- const QRectF lr = line.naturalTextRect();
- if (lr.top() >= y - visible)
- break;
- ++lineNumber;
- }
- if (lineNumber < layoutLineCount)
- visibleFromBottom += (layoutLineCount - lineNumber);
- break;
-
- }
- visibleFromBottom += layoutLineCount;
- block = block.previous();
- }
- vmax = qMax(0, doc->lineCount() - visibleFromBottom);
- vSliderLength = visibleFromBottom;
-
- } else {
- vmax = qMax(0, doc->lineCount() - 1);
- vSliderLength = viewport->height() / q->fontMetrics().lineSpacing();
- }
-
-
-
- QSizeF documentSize = documentLayout->documentSize();
- vbar->setRange(0, qMax(0, vmax));
- vbar->setPageStep(vSliderLength);
- int visualTopLine = vmax;
- QTextBlock firstVisibleBlock = q->firstVisibleBlock();
- if (firstVisibleBlock.isValid())
- visualTopLine = firstVisibleBlock.firstLineNumber() + topLine;
- bool vbarSignalsBlocked = vbar->blockSignals(true);
- vbar->setValue(visualTopLine);
- vbar->blockSignals(vbarSignalsBlocked);
-
- hbar->setRange(0, (int)documentSize.width() - viewport->width());
- hbar->setPageStep(viewport->width());
- documentLayout->priv()->blockDocumentSizeChanged = documentSizeChangedBlocked;
- setTopLine(vbar->value());
-}
-
-#endif
-
-
-void QPlainTextEditPrivate::ensureViewportLayouted()
-{
-}
-
-/*!
- \class QPlainTextEdit
- \since 4.4
- \brief The QPlainTextEdit class provides a widget that is used to edit and display
- plain text.
-
- \ingroup richtext-processing
-
-
- \tableofcontents
-
- \section1 Introduction and Concepts
-
- QPlainTextEdit is an advanced viewer/editor supporting plain
- text. It is optimized to handle large documents and to respond
- quickly to user input.
-
- QPlainText uses very much the same technology and concepts as
- QTextEdit, but is optimized for plain text handling.
-
- QPlainTextEdit works on paragraphs and characters. A paragraph is
- a formatted string which is word-wrapped to fit into the width of
- the widget. By default when reading plain text, one newline
- signifies a paragraph. A document consists of zero or more
- paragraphs. Paragraphs are separated by hard line breaks. Each
- character within a paragraph has its own attributes, for example,
- font and color.
-
- The shape of the mouse cursor on a QPlainTextEdit is
- Qt::IBeamCursor by default. It can be changed through the
- viewport()'s cursor property.
-
- \section1 Using QPlainTextEdit as a Display Widget
-
- The text is set or replaced using setPlainText() which deletes the
- existing text and replaces it with the text passed to setPlainText().
-
- Text can be inserted using the QTextCursor class or using the
- convenience functions insertPlainText(), appendPlainText() or
- paste().
-
- By default, the text edit wraps words at whitespace to fit within
- the text edit widget. The setLineWrapMode() function is used to
- specify the kind of line wrap you want, \l WidgetWidth or \l
- NoWrap if you don't want any wrapping. If you use word wrap to
- the widget's width \l WidgetWidth, you can specify whether to
- break on whitespace or anywhere with setWordWrapMode().
-
- The find() function can be used to find and select a given string
- within the text.
-
- If you want to limit the total number of paragraphs in a
- QPlainTextEdit, as it is for example useful in a log viewer, then
- you can use the maximumBlockCount property. The combination of
- setMaximumBlockCount() and appendPlainText() turns QPlainTextEdit
- into an efficient viewer for log text. The scrolling can be
- reduced with the centerOnScroll() property, making the log viewer
- even faster. Text can be formatted in a limited way, either using
- a syntax highlighter (see below), or by appending html-formatted
- text with appendHtml(). While QPlainTextEdit does not support
- complex rich text rendering with tables and floats, it does
- support limited paragraph-based formatting that you may need in a
- log viewer.
-
- \section2 Read-only Key Bindings
-
- When QPlainTextEdit is used read-only the key bindings are limited to
- navigation, and text may only be selected with the mouse:
- \table
- \header \i Keypresses \i Action
- \row \i Qt::UpArrow \i Moves one line up.
- \row \i Qt::DownArrow \i Moves one line down.
- \row \i Qt::LeftArrow \i Moves one character to the left.
- \row \i Qt::RightArrow \i Moves one character to the right.
- \row \i PageUp \i Moves one (viewport) page up.
- \row \i PageDown \i Moves one (viewport) page down.
- \row \i Home \i Moves to the beginning of the text.
- \row \i End \i Moves to the end of the text.
- \row \i Alt+Wheel
- \i Scrolls the page horizontally (the Wheel is the mouse wheel).
- \row \i Ctrl+Wheel \i Zooms the text.
- \row \i Ctrl+A \i Selects all text.
- \endtable
-
-
- \section1 Using QPlainTextEdit as an Editor
-
- All the information about using QPlainTextEdit as a display widget also
- applies here.
-
- Selection of text is handled by the QTextCursor class, which provides
- functionality for creating selections, retrieving the text contents or
- deleting selections. You can retrieve the object that corresponds with
- the user-visible cursor using the textCursor() method. If you want to set
- a selection in QPlainTextEdit just create one on a QTextCursor object and
- then make that cursor the visible cursor using setCursor(). The selection
- can be copied to the clipboard with copy(), or cut to the clipboard with
- cut(). The entire text can be selected using selectAll().
-
- QPlainTextEdit holds a QTextDocument object which can be retrieved using the
- document() method. You can also set your own document object using setDocument().
- QTextDocument emits a textChanged() signal if the text changes and it also
- provides a isModified() function which will return true if the text has been
- modified since it was either loaded or since the last call to setModified
- with false as argument. In addition it provides methods for undo and redo.
-
- \section2 Syntax Highlighting
-
- Just like QTextEdit, QPlainTextEdit works together with
- QSyntaxHighlighter.
-
- \section2 Editing Key Bindings
-
- The list of key bindings which are implemented for editing:
- \table
- \header \i Keypresses \i Action
- \row \i Backspace \i Deletes the character to the left of the cursor.
- \row \i Delete \i Deletes the character to the right of the cursor.
- \row \i Ctrl+C \i Copy the selected text to the clipboard.
- \row \i Ctrl+Insert \i Copy the selected text to the clipboard.
- \row \i Ctrl+K \i Deletes to the end of the line.
- \row \i Ctrl+V \i Pastes the clipboard text into text edit.
- \row \i Shift+Insert \i Pastes the clipboard text into text edit.
- \row \i Ctrl+X \i Deletes the selected text and copies it to the clipboard.
- \row \i Shift+Delete \i Deletes the selected text and copies it to the clipboard.
- \row \i Ctrl+Z \i Undoes the last operation.
- \row \i Ctrl+Y \i Redoes the last operation.
- \row \i LeftArrow \i Moves the cursor one character to the left.
- \row \i Ctrl+LeftArrow \i Moves the cursor one word to the left.
- \row \i RightArrow \i Moves the cursor one character to the right.
- \row \i Ctrl+RightArrow \i Moves the cursor one word to the right.
- \row \i UpArrow \i Moves the cursor one line up.
- \row \i Ctrl+UpArrow \i Moves the cursor one word up.
- \row \i DownArrow \i Moves the cursor one line down.
- \row \i Ctrl+Down Arrow \i Moves the cursor one word down.
- \row \i PageUp \i Moves the cursor one page up.
- \row \i PageDown \i Moves the cursor one page down.
- \row \i Home \i Moves the cursor to the beginning of the line.
- \row \i Ctrl+Home \i Moves the cursor to the beginning of the text.
- \row \i End \i Moves the cursor to the end of the line.
- \row \i Ctrl+End \i Moves the cursor to the end of the text.
- \row \i Alt+Wheel \i Scrolls the page horizontally (the Wheel is the mouse wheel).
- \row \i Ctrl+Wheel \i Zooms the text.
- \endtable
-
- To select (mark) text hold down the Shift key whilst pressing one
- of the movement keystrokes, for example, \e{Shift+Right Arrow}
- will select the character to the right, and \e{Shift+Ctrl+Right
- Arrow} will select the word to the right, etc.
-
- \section1 Differences to QTextEdit
-
- QPlainTextEdit is a thin class, implemented by using most of the
- technology that is behind QTextEdit and QTextDocument. Its
- performance benefits over QTextEdit stem mostly from using a
- different and simplified text layout called
- QPlainTextDocumentLayout on the text document (see
- QTextDocument::setDocumentLayout()). The plain text document layout
- does not support tables nor embedded frames, and \e{replaces a
- pixel-exact height calculation with a line-by-line respectively
- paragraph-by-paragraph scrolling approach}. This makes it possible
- to handle significantly larger documents, and still resize the
- editor with line wrap enabled in real time. It also makes for a
- fast log viewer (see setMaximumBlockCount()).
-
-
- \sa QTextDocument, QTextCursor, {Application Example},
- {Code Editor Example}, {Syntax Highlighter Example},
- {Rich Text Processing}
-
-*/
-
-/*!
- \property QPlainTextEdit::plainText
-
- This property gets and sets the plain text editor's contents. The previous
- contents are removed and undo/redo history is reset when this property is set.
-
- By default, for an editor with no contents, this property contains an empty string.
-*/
-
-/*!
- \property QPlainTextEdit::undoRedoEnabled
- \brief whether undo and redo are enabled
-
- Users are only able to undo or redo actions if this property is
- true, and if there is an action that can be undone (or redone).
-
- By default, this property is true.
-*/
-
-/*!
- \enum QPlainTextEdit::LineWrapMode
-
- \value NoWrap
- \value WidgetWidth
-*/
-
-
-/*!
- Constructs an empty QPlainTextEdit with parent \a
- parent.
-*/
-QPlainTextEdit::QPlainTextEdit(QWidget *parent)
- : QAbstractScrollArea(*new QPlainTextEditPrivate, parent)
-{
- Q_D(QPlainTextEdit);
- d->init();
-}
-
-/*!
- \internal
-*/
-QPlainTextEdit::QPlainTextEdit(QPlainTextEditPrivate &dd, QWidget *parent)
- : QAbstractScrollArea(dd, parent)
-{
- Q_D(QPlainTextEdit);
- d->init();
-}
-
-/*!
- Constructs a QPlainTextEdit with parent \a parent. The text edit will display
- the plain text \a text.
-*/
-QPlainTextEdit::QPlainTextEdit(const QString &text, QWidget *parent)
- : QAbstractScrollArea(*new QPlainTextEditPrivate, parent)
-{
- Q_D(QPlainTextEdit);
- d->init(text);
-}
-
-
-/*!
- Destructor.
-*/
-QPlainTextEdit::~QPlainTextEdit()
-{
- Q_D(QPlainTextEdit);
- if (d->documentLayoutPtr) {
- if (d->documentLayoutPtr->priv()->mainViewPrivate == d)
- d->documentLayoutPtr->priv()->mainViewPrivate = 0;
- }
-}
-
-/*!
- Makes \a document the new document of the text editor.
-
- The parent QObject of the provided document remains the owner
- of the object. If the current document is a child of the text
- editor, then it is deleted.
-
- The document must have a document layout that inherits
- QPlainTextDocumentLayout (see QTextDocument::setDocumentLayout()).
-
- \sa document()
-*/
-void QPlainTextEdit::setDocument(QTextDocument *document)
-{
- Q_D(QPlainTextEdit);
- QPlainTextDocumentLayout *documentLayout = 0;
-
- if (!document) {
- document = new QTextDocument(d->control);
- documentLayout = new QPlainTextDocumentLayout(document);
- document->setDocumentLayout(documentLayout);
- } else {
- documentLayout = qobject_cast<QPlainTextDocumentLayout*>(document->documentLayout());
- if (!documentLayout) {
- qWarning("QPlainTextEdit::setDocument: Document set does not support QPlainTextDocumentLayout");
- return;
- }
- }
- d->control->setDocument(document);
- if (!documentLayout->priv()->mainViewPrivate)
- documentLayout->priv()->mainViewPrivate = d;
- d->documentLayoutPtr = documentLayout;
- d->updateDefaultTextOption();
- d->relayoutDocument();
- d->_q_adjustScrollbars();
-}
-
-/*!
- Returns a pointer to the underlying document.
-
- \sa setDocument()
-*/
-QTextDocument *QPlainTextEdit::document() const
-{
- Q_D(const QPlainTextEdit);
- return d->control->document();
-}
-
-/*!
- Sets the visible \a cursor.
-*/
-void QPlainTextEdit::setTextCursor(const QTextCursor &cursor)
-{
- Q_D(QPlainTextEdit);
- d->control->setTextCursor(cursor);
-}
-
-/*!
- Returns a copy of the QTextCursor that represents the currently visible cursor.
- Note that changes on the returned cursor do not affect QPlainTextEdit's cursor; use
- setTextCursor() to update the visible cursor.
- */
-QTextCursor QPlainTextEdit::textCursor() const
-{
- Q_D(const QPlainTextEdit);
- return d->control->textCursor();
-}
-
-/*!
- Returns the reference of the anchor at position \a pos, or an
- empty string if no anchor exists at that point.
-
- \since 4.7
- */
-QString QPlainTextEdit::anchorAt(const QPoint &pos) const
-{
- Q_D(const QPlainTextEdit);
- int cursorPos = d->control->hitTest(pos + QPoint(d->horizontalOffset(),
- d->verticalOffset()),
- Qt::ExactHit);
- if (cursorPos < 0)
- return QString();
-
- QTextDocumentPrivate *pieceTable = document()->docHandle();
- QTextDocumentPrivate::FragmentIterator it = pieceTable->find(cursorPos);
- QTextCharFormat fmt = pieceTable->formatCollection()->charFormat(it->format);
- return fmt.anchorHref();
-}
-
-/*!
- Undoes the last operation.
-
- If there is no operation to undo, i.e. there is no undo step in
- the undo/redo history, nothing happens.
-
- \sa redo()
-*/
-void QPlainTextEdit::undo()
-{
- Q_D(QPlainTextEdit);
- d->control->undo();
-}
-
-void QPlainTextEdit::redo()
-{
- Q_D(QPlainTextEdit);
- d->control->redo();
-}
-
-/*!
- \fn void QPlainTextEdit::redo()
-
- Redoes the last operation.
-
- If there is no operation to redo, i.e. there is no redo step in
- the undo/redo history, nothing happens.
-
- \sa undo()
-*/
-
-#ifndef QT_NO_CLIPBOARD
-/*!
- Copies the selected text to the clipboard and deletes it from
- the text edit.
-
- If there is no selected text nothing happens.
-
- \sa copy() paste()
-*/
-
-void QPlainTextEdit::cut()
-{
- Q_D(QPlainTextEdit);
- d->control->cut();
-}
-
-/*!
- Copies any selected text to the clipboard.
-
- \sa copyAvailable()
-*/
-
-void QPlainTextEdit::copy()
-{
- Q_D(QPlainTextEdit);
- d->control->copy();
-}
-
-/*!
- Pastes the text from the clipboard into the text edit at the
- current cursor position.
-
- If there is no text in the clipboard nothing happens.
-
- To change the behavior of this function, i.e. to modify what
- QPlainTextEdit can paste and how it is being pasted, reimplement the
- virtual canInsertFromMimeData() and insertFromMimeData()
- functions.
-
- \sa cut() copy()
-*/
-
-void QPlainTextEdit::paste()
-{
- Q_D(QPlainTextEdit);
- d->control->paste();
-}
-#endif
-
-/*!
- Deletes all the text in the text edit.
-
- Note that the undo/redo history is cleared by this function.
-
- \sa cut() setPlainText()
-*/
-void QPlainTextEdit::clear()
-{
- Q_D(QPlainTextEdit);
- // clears and sets empty content
- d->control->topBlock = d->topLine = 0;
- d->control->clear();
-}
-
-
-/*!
- Selects all text.
-
- \sa copy() cut() textCursor()
- */
-void QPlainTextEdit::selectAll()
-{
- Q_D(QPlainTextEdit);
- d->control->selectAll();
-}
-
-/*! \internal
-*/
-bool QPlainTextEdit::event(QEvent *e)
-{
- Q_D(QPlainTextEdit);
-
-#ifndef QT_NO_CONTEXTMENU
- if (e->type() == QEvent::ContextMenu
- && static_cast<QContextMenuEvent *>(e)->reason() == QContextMenuEvent::Keyboard) {
- ensureCursorVisible();
- const QPoint cursorPos = cursorRect().center();
- QContextMenuEvent ce(QContextMenuEvent::Keyboard, cursorPos, d->viewport->mapToGlobal(cursorPos));
- ce.setAccepted(e->isAccepted());
- const bool result = QAbstractScrollArea::event(&ce);
- e->setAccepted(ce.isAccepted());
- return result;
- }
-#endif // QT_NO_CONTEXTMENU
- if (e->type() == QEvent::ShortcutOverride
- || e->type() == QEvent::ToolTip) {
- d->sendControlEvent(e);
- }
-#ifdef QT_KEYPAD_NAVIGATION
- else if (e->type() == QEvent::EnterEditFocus || e->type() == QEvent::LeaveEditFocus) {
- if (QApplication::keypadNavigationEnabled())
- d->sendControlEvent(e);
- }
-#endif
-#ifndef QT_NO_GESTURES
- else if (e->type() == QEvent::Gesture) {
- QGestureEvent *ge = static_cast<QGestureEvent *>(e);
- QPanGesture *g = static_cast<QPanGesture *>(ge->gesture(Qt::PanGesture));
- if (g) {
- QScrollBar *hBar = horizontalScrollBar();
- QScrollBar *vBar = verticalScrollBar();
- if (g->state() == Qt::GestureStarted)
- d->originalOffsetY = vBar->value();
- QPointF offset = g->offset();
- if (!offset.isNull()) {
- if (QApplication::isRightToLeft())
- offset.rx() *= -1;
- // QPlainTextEdit scrolls by lines only in vertical direction
- QFontMetrics fm(document()->defaultFont());
- int lineHeight = fm.height();
- int newX = hBar->value() - g->delta().x();
- int newY = d->originalOffsetY - offset.y()/lineHeight;
- hBar->setValue(newX);
- vBar->setValue(newY);
- }
- }
- return true;
- }
-#endif // QT_NO_GESTURES
- return QAbstractScrollArea::event(e);
-}
-
-/*! \internal
-*/
-
-void QPlainTextEdit::timerEvent(QTimerEvent *e)
-{
- Q_D(QPlainTextEdit);
- if (e->timerId() == d->autoScrollTimer.timerId()) {
- QRect visible = d->viewport->rect();
- QPoint pos;
- if (d->inDrag) {
- pos = d->autoScrollDragPos;
- visible.adjust(qMin(visible.width()/3,20), qMin(visible.height()/3,20),
- -qMin(visible.width()/3,20), -qMin(visible.height()/3,20));
- } else {
- const QPoint globalPos = QCursor::pos();
- pos = d->viewport->mapFromGlobal(globalPos);
- QMouseEvent ev(QEvent::MouseMove, pos, globalPos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
- mouseMoveEvent(&ev);
- }
- int deltaY = qMax(pos.y() - visible.top(), visible.bottom() - pos.y()) - visible.height();
- int deltaX = qMax(pos.x() - visible.left(), visible.right() - pos.x()) - visible.width();
- int delta = qMax(deltaX, deltaY);
- if (delta >= 0) {
- if (delta < 7)
- delta = 7;
- int timeout = 4900 / (delta * delta);
- d->autoScrollTimer.start(timeout, this);
-
- if (deltaY > 0)
- d->vbar->triggerAction(pos.y() < visible.center().y() ?
- QAbstractSlider::SliderSingleStepSub
- : QAbstractSlider::SliderSingleStepAdd);
- if (deltaX > 0)
- d->hbar->triggerAction(pos.x() < visible.center().x() ?
- QAbstractSlider::SliderSingleStepSub
- : QAbstractSlider::SliderSingleStepAdd);
- }
- }
-#ifdef QT_KEYPAD_NAVIGATION
- else if (e->timerId() == d->deleteAllTimer.timerId()) {
- d->deleteAllTimer.stop();
- clear();
- }
-#endif
-}
-
-/*!
- Changes the text of the text edit to the string \a text.
- Any previous text is removed.
-
- \a text is interpreted as plain text.
-
- Note that the undo/redo history is cleared by this function.
-
- \sa toText()
-*/
-
-void QPlainTextEdit::setPlainText(const QString &text)
-{
- Q_D(QPlainTextEdit);
- d->control->setPlainText(text);
-}
-
-/*!
- \fn QString QPlainTextEdit::toPlainText() const
-
- Returns the text of the text edit as plain text.
-
- \sa QPlainTextEdit::setPlainText()
- */
-
-/*! \reimp
-*/
-void QPlainTextEdit::keyPressEvent(QKeyEvent *e)
-{
- Q_D(QPlainTextEdit);
-
-#ifdef QT_KEYPAD_NAVIGATION
- switch (e->key()) {
- case Qt::Key_Select:
- if (QApplication::keypadNavigationEnabled()) {
- if (!(d->control->textInteractionFlags() & Qt::LinksAccessibleByKeyboard))
- setEditFocus(!hasEditFocus());
- else {
- if (!hasEditFocus())
- setEditFocus(true);
- else {
- QTextCursor cursor = d->control->textCursor();
- QTextCharFormat charFmt = cursor.charFormat();
- if (!cursor.hasSelection() || charFmt.anchorHref().isEmpty()) {
- setEditFocus(false);
- }
- }
- }
- }
- break;
- case Qt::Key_Back:
- case Qt::Key_No:
- if (!QApplication::keypadNavigationEnabled()
- || (QApplication::keypadNavigationEnabled() && !hasEditFocus())) {
- e->ignore();
- return;
- }
- break;
- default:
- if (QApplication::keypadNavigationEnabled()) {
- if (!hasEditFocus() && !(e->modifiers() & Qt::ControlModifier)) {
- if (e->text()[0].isPrint()) {
- setEditFocus(true);
- clear();
- } else {
- e->ignore();
- return;
- }
- }
- }
- break;
- }
-#endif
-
-#ifndef QT_NO_SHORTCUT
-
- Qt::TextInteractionFlags tif = d->control->textInteractionFlags();
-
- if (tif & Qt::TextSelectableByKeyboard){
- if (e == QKeySequence::SelectPreviousPage) {
- e->accept();
- d->pageUpDown(QTextCursor::Up, QTextCursor::KeepAnchor);
- return;
- } else if (e ==QKeySequence::SelectNextPage) {
- e->accept();
- d->pageUpDown(QTextCursor::Down, QTextCursor::KeepAnchor);
- return;
- }
- }
- if (tif & (Qt::TextSelectableByKeyboard | Qt::TextEditable)) {
- if (e == QKeySequence::MoveToPreviousPage) {
- e->accept();
- d->pageUpDown(QTextCursor::Up, QTextCursor::MoveAnchor);
- return;
- } else if (e == QKeySequence::MoveToNextPage) {
- e->accept();
- d->pageUpDown(QTextCursor::Down, QTextCursor::MoveAnchor);
- return;
- }
- }
-
- if (!(tif & Qt::TextEditable)) {
- switch (e->key()) {
- case Qt::Key_Space:
- e->accept();
- if (e->modifiers() & Qt::ShiftModifier)
- d->vbar->triggerAction(QAbstractSlider::SliderPageStepSub);
- else
- d->vbar->triggerAction(QAbstractSlider::SliderPageStepAdd);
- break;
- default:
- d->sendControlEvent(e);
- if (!e->isAccepted() && e->modifiers() == Qt::NoModifier) {
- if (e->key() == Qt::Key_Home) {
- d->vbar->triggerAction(QAbstractSlider::SliderToMinimum);
- e->accept();
- } else if (e->key() == Qt::Key_End) {
- d->vbar->triggerAction(QAbstractSlider::SliderToMaximum);
- e->accept();
- }
- }
- if (!e->isAccepted()) {
- QAbstractScrollArea::keyPressEvent(e);
- }
- }
- return;
- }
-#endif // QT_NO_SHORTCUT
-
- d->sendControlEvent(e);
-#ifdef QT_KEYPAD_NAVIGATION
- if (!e->isAccepted()) {
- switch (e->key()) {
- case Qt::Key_Up:
- case Qt::Key_Down:
- if (QApplication::keypadNavigationEnabled()) {
- // Cursor position didn't change, so we want to leave
- // these keys to change focus.
- e->ignore();
- return;
- }
- break;
- case Qt::Key_Left:
- case Qt::Key_Right:
- if (QApplication::keypadNavigationEnabled()
- && QApplication::navigationMode() == Qt::NavigationModeKeypadDirectional) {
- // Same as for Key_Up and Key_Down.
- e->ignore();
- return;
- }
- break;
- case Qt::Key_Back:
- if (!e->isAutoRepeat()) {
- if (QApplication::keypadNavigationEnabled()) {
- if (document()->isEmpty()) {
- setEditFocus(false);
- e->accept();
- } else if (!d->deleteAllTimer.isActive()) {
- e->accept();
- d->deleteAllTimer.start(750, this);
- }
- } else {
- e->ignore();
- return;
- }
- }
- break;
- default: break;
- }
- }
-#endif
-}
-
-/*! \reimp
-*/
-void QPlainTextEdit::keyReleaseEvent(QKeyEvent *e)
-{
-#ifdef QT_KEYPAD_NAVIGATION
- Q_D(QPlainTextEdit);
- if (QApplication::keypadNavigationEnabled()) {
- if (!e->isAutoRepeat() && e->key() == Qt::Key_Back
- && d->deleteAllTimer.isActive()) {
- d->deleteAllTimer.stop();
- QTextCursor cursor = d->control->textCursor();
- QTextBlockFormat blockFmt = cursor.blockFormat();
-
- QTextList *list = cursor.currentList();
- if (list && cursor.atBlockStart()) {
- list->remove(cursor.block());
- } else if (cursor.atBlockStart() && blockFmt.indent() > 0) {
- blockFmt.setIndent(blockFmt.indent() - 1);
- cursor.setBlockFormat(blockFmt);
- } else {
- cursor.deletePreviousChar();
- }
- setTextCursor(cursor);
- }
- }
-#else
- Q_UNUSED(e);
-#endif
-}
-
-/*!
- Loads the resource specified by the given \a type and \a name.
-
- This function is an extension of QTextDocument::loadResource().
-
- \sa QTextDocument::loadResource()
-*/
-QVariant QPlainTextEdit::loadResource(int type, const QUrl &name)
-{
- Q_UNUSED(type);
- Q_UNUSED(name);
- return QVariant();
-}
-
-/*! \reimp
-*/
-void QPlainTextEdit::resizeEvent(QResizeEvent *e)
-{
- Q_D(QPlainTextEdit);
- if (e->oldSize().width() != e->size().width())
- d->relayoutDocument();
- d->_q_adjustScrollbars();
-}
-
-void QPlainTextEditPrivate::relayoutDocument()
-{
- QTextDocument *doc = control->document();
- QPlainTextDocumentLayout *documentLayout = qobject_cast<QPlainTextDocumentLayout*>(doc->documentLayout());
- Q_ASSERT(documentLayout);
- documentLayoutPtr = documentLayout;
-
- int width = viewport->width();
-
- if (documentLayout->priv()->mainViewPrivate == 0
- || documentLayout->priv()->mainViewPrivate == this
- || width > documentLayout->textWidth()) {
- documentLayout->priv()->mainViewPrivate = this;
- documentLayout->setTextWidth(width);
- }
-}
-
-static void fillBackground(QPainter *p, const QRectF &rect, QBrush brush, QRectF gradientRect = QRectF())
-{
- p->save();
- if (brush.style() >= Qt::LinearGradientPattern && brush.style() <= Qt::ConicalGradientPattern) {
- if (!gradientRect.isNull()) {
- QTransform m = QTransform::fromTranslate(gradientRect.left(), gradientRect.top());
- m.scale(gradientRect.width(), gradientRect.height());
- brush.setTransform(m);
- const_cast<QGradient *>(brush.gradient())->setCoordinateMode(QGradient::LogicalMode);
- }
- } else {
- p->setBrushOrigin(rect.topLeft());
- }
- p->fillRect(rect, brush);
- p->restore();
-}
-
-
-
-/*! \reimp
-*/
-void QPlainTextEdit::paintEvent(QPaintEvent *e)
-{
- QPainter painter(viewport());
- Q_ASSERT(qobject_cast<QPlainTextDocumentLayout*>(document()->documentLayout()));
-
- QPointF offset(contentOffset());
-
- QRect er = e->rect();
- QRect viewportRect = viewport()->rect();
-
- bool editable = !isReadOnly();
-
- QTextBlock block = firstVisibleBlock();
- qreal maximumWidth = document()->documentLayout()->documentSize().width();
-
- // Set a brush origin so that the WaveUnderline knows where the wave started
- painter.setBrushOrigin(offset);
-
- // keep right margin clean from full-width selection
- int maxX = offset.x() + qMax((qreal)viewportRect.width(), maximumWidth)
- - document()->documentMargin();
- er.setRight(qMin(er.right(), maxX));
- painter.setClipRect(er);
-
-
- QAbstractTextDocumentLayout::PaintContext context = getPaintContext();
-
- while (block.isValid()) {
-
- QRectF r = blockBoundingRect(block).translated(offset);
- QTextLayout *layout = block.layout();
-
- if (!block.isVisible()) {
- offset.ry() += r.height();
- block = block.next();
- continue;
- }
-
- if (r.bottom() >= er.top() && r.top() <= er.bottom()) {
-
- QTextBlockFormat blockFormat = block.blockFormat();
-
- QBrush bg = blockFormat.background();
- if (bg != Qt::NoBrush) {
- QRectF contentsRect = r;
- contentsRect.setWidth(qMax(r.width(), maximumWidth));
- fillBackground(&painter, contentsRect, bg);
- }
-
-
- QVector<QTextLayout::FormatRange> selections;
- int blpos = block.position();
- int bllen = block.length();
- for (int i = 0; i < context.selections.size(); ++i) {
- const QAbstractTextDocumentLayout::Selection &range = context.selections.at(i);
- const int selStart = range.cursor.selectionStart() - blpos;
- const int selEnd = range.cursor.selectionEnd() - blpos;
- if (selStart < bllen && selEnd > 0
- && selEnd > selStart) {
- QTextLayout::FormatRange o;
- o.start = selStart;
- o.length = selEnd - selStart;
- o.format = range.format;
- selections.append(o);
- } else if (!range.cursor.hasSelection() && range.format.hasProperty(QTextFormat::FullWidthSelection)
- && block.contains(range.cursor.position())) {
- // for full width selections we don't require an actual selection, just
- // a position to specify the line. that's more convenience in usage.
- QTextLayout::FormatRange o;
- QTextLine l = layout->lineForTextPosition(range.cursor.position() - blpos);
- o.start = l.textStart();
- o.length = l.textLength();
- if (o.start + o.length == bllen - 1)
- ++o.length; // include newline
- o.format = range.format;
- selections.append(o);
- }
- }
-
- bool drawCursor = (editable
- && context.cursorPosition >= blpos
- && context.cursorPosition < blpos + bllen);
-
- bool drawCursorAsBlock = drawCursor && overwriteMode() ;
-
- if (drawCursorAsBlock) {
- if (context.cursorPosition == blpos + bllen - 1) {
- drawCursorAsBlock = false;
- } else {
- QTextLayout::FormatRange o;
- o.start = context.cursorPosition - blpos;
- o.length = 1;
- o.format.setForeground(palette().base());
- o.format.setBackground(palette().text());
- selections.append(o);
- }
- }
-
-
- layout->draw(&painter, offset, selections, er);
- if ((drawCursor && !drawCursorAsBlock)
- || (editable && context.cursorPosition < -1
- && !layout->preeditAreaText().isEmpty())) {
- int cpos = context.cursorPosition;
- if (cpos < -1)
- cpos = layout->preeditAreaPosition() - (cpos + 2);
- else
- cpos -= blpos;
- layout->drawCursor(&painter, offset, cpos, cursorWidth());
- }
- }
-
- offset.ry() += r.height();
- if (offset.y() > viewportRect.height())
- break;
- block = block.next();
- }
-
- if (backgroundVisible() && !block.isValid() && offset.y() <= er.bottom()
- && (centerOnScroll() || verticalScrollBar()->maximum() == verticalScrollBar()->minimum())) {
- painter.fillRect(QRect(QPoint((int)er.left(), (int)offset.y()), er.bottomRight()), palette().background());
- }
-}
-
-
-void QPlainTextEditPrivate::updateDefaultTextOption()
-{
- QTextDocument *doc = control->document();
-
- QTextOption opt = doc->defaultTextOption();
- QTextOption::WrapMode oldWrapMode = opt.wrapMode();
-
- if (lineWrap == QPlainTextEdit::NoWrap)
- opt.setWrapMode(QTextOption::NoWrap);
- else
- opt.setWrapMode(wordWrap);
-
- if (opt.wrapMode() != oldWrapMode)
- doc->setDefaultTextOption(opt);
-}
-
-
-/*! \reimp
-*/
-void QPlainTextEdit::mousePressEvent(QMouseEvent *e)
-{
- Q_D(QPlainTextEdit);
-#ifdef QT_KEYPAD_NAVIGATION
- if (QApplication::keypadNavigationEnabled() && !hasEditFocus())
- setEditFocus(true);
-#endif
- d->sendControlEvent(e);
-}
-
-/*! \reimp
-*/
-void QPlainTextEdit::mouseMoveEvent(QMouseEvent *e)
-{
- Q_D(QPlainTextEdit);
- d->inDrag = false; // paranoia
- const QPoint pos = e->pos();
- d->sendControlEvent(e);
- if (!(e->buttons() & Qt::LeftButton))
- return;
- QRect visible = d->viewport->rect();
- if (visible.contains(pos))
- d->autoScrollTimer.stop();
- else if (!d->autoScrollTimer.isActive())
- d->autoScrollTimer.start(100, this);
-}
-
-/*! \reimp
-*/
-void QPlainTextEdit::mouseReleaseEvent(QMouseEvent *e)
-{
- Q_D(QPlainTextEdit);
- d->sendControlEvent(e);
- if (d->autoScrollTimer.isActive()) {
- d->autoScrollTimer.stop();
- d->ensureCursorVisible();
- }
-
- if (!isReadOnly() && rect().contains(e->pos()))
- d->handleSoftwareInputPanel(e->button(), d->clickCausedFocus);
- d->clickCausedFocus = 0;
-}
-
-/*! \reimp
-*/
-void QPlainTextEdit::mouseDoubleClickEvent(QMouseEvent *e)
-{
- Q_D(QPlainTextEdit);
- d->sendControlEvent(e);
-}
-
-/*! \reimp
-*/
-bool QPlainTextEdit::focusNextPrevChild(bool next)
-{
- Q_D(const QPlainTextEdit);
- if (!d->tabChangesFocus && d->control->textInteractionFlags() & Qt::TextEditable)
- return false;
- return QAbstractScrollArea::focusNextPrevChild(next);
-}
-
-#ifndef QT_NO_CONTEXTMENU
-/*!
- \fn void QPlainTextEdit::contextMenuEvent(QContextMenuEvent *event)
-
- Shows the standard context menu created with createStandardContextMenu().
-
- If you do not want the text edit to have a context menu, you can set
- its \l contextMenuPolicy to Qt::NoContextMenu. If you want to
- customize the context menu, reimplement this function. If you want
- to extend the standard context menu, reimplement this function, call
- createStandardContextMenu() and extend the menu returned.
-
- Information about the event is passed in the \a event object.
-
- \snippet doc/src/snippets/code/src_gui_widgets_qplaintextedit.cpp 0
-*/
-void QPlainTextEdit::contextMenuEvent(QContextMenuEvent *e)
-{
- Q_D(QPlainTextEdit);
- d->sendControlEvent(e);
-}
-#endif // QT_NO_CONTEXTMENU
-
-#ifndef QT_NO_DRAGANDDROP
-/*! \reimp
-*/
-void QPlainTextEdit::dragEnterEvent(QDragEnterEvent *e)
-{
- Q_D(QPlainTextEdit);
- d->inDrag = true;
- d->sendControlEvent(e);
-}
-
-/*! \reimp
-*/
-void QPlainTextEdit::dragLeaveEvent(QDragLeaveEvent *e)
-{
- Q_D(QPlainTextEdit);
- d->inDrag = false;
- d->autoScrollTimer.stop();
- d->sendControlEvent(e);
-}
-
-/*! \reimp
-*/
-void QPlainTextEdit::dragMoveEvent(QDragMoveEvent *e)
-{
- Q_D(QPlainTextEdit);
- d->autoScrollDragPos = e->pos();
- if (!d->autoScrollTimer.isActive())
- d->autoScrollTimer.start(100, this);
- d->sendControlEvent(e);
-}
-
-/*! \reimp
-*/
-void QPlainTextEdit::dropEvent(QDropEvent *e)
-{
- Q_D(QPlainTextEdit);
- d->inDrag = false;
- d->autoScrollTimer.stop();
- d->sendControlEvent(e);
-}
-
-#endif // QT_NO_DRAGANDDROP
-
-/*! \reimp
- */
-void QPlainTextEdit::inputMethodEvent(QInputMethodEvent *e)
-{
- Q_D(QPlainTextEdit);
-#ifdef QT_KEYPAD_NAVIGATION
- if (d->control->textInteractionFlags() & Qt::TextEditable
- && QApplication::keypadNavigationEnabled()
- && !hasEditFocus()) {
- setEditFocus(true);
- selectAll(); // so text is replaced rather than appended to
- }
-#endif
- d->sendControlEvent(e);
- ensureCursorVisible();
-}
-
-/*!\reimp
-*/
-void QPlainTextEdit::scrollContentsBy(int dx, int /*dy*/)
-{
- Q_D(QPlainTextEdit);
- d->setTopLine(d->vbar->value(), dx);
-}
-
-/*!\reimp
-*/
-QVariant QPlainTextEdit::inputMethodQuery(Qt::InputMethodQuery property) const
-{
- Q_D(const QPlainTextEdit);
- QVariant v = d->control->inputMethodQuery(property);
- const QPoint offset(-d->horizontalOffset(), -0);
- if (v.type() == QVariant::RectF)
- v = v.toRectF().toRect().translated(offset);
- else if (v.type() == QVariant::PointF)
- v = v.toPointF().toPoint() + offset;
- else if (v.type() == QVariant::Rect)
- v = v.toRect().translated(offset);
- else if (v.type() == QVariant::Point)
- v = v.toPoint() + offset;
- return v;
-}
-
-/*! \reimp
-*/
-void QPlainTextEdit::focusInEvent(QFocusEvent *e)
-{
- Q_D(QPlainTextEdit);
- if (e->reason() == Qt::MouseFocusReason) {
- d->clickCausedFocus = 1;
- }
- QAbstractScrollArea::focusInEvent(e);
- d->sendControlEvent(e);
-}
-
-/*! \reimp
-*/
-void QPlainTextEdit::focusOutEvent(QFocusEvent *e)
-{
- Q_D(QPlainTextEdit);
- QAbstractScrollArea::focusOutEvent(e);
- d->sendControlEvent(e);
-}
-
-/*! \reimp
-*/
-void QPlainTextEdit::showEvent(QShowEvent *)
-{
- Q_D(QPlainTextEdit);
- if (d->showCursorOnInitialShow) {
- d->showCursorOnInitialShow = false;
- ensureCursorVisible();
- }
-}
-
-/*! \reimp
-*/
-void QPlainTextEdit::changeEvent(QEvent *e)
-{
- Q_D(QPlainTextEdit);
- QAbstractScrollArea::changeEvent(e);
- if (e->type() == QEvent::ApplicationFontChange
- || e->type() == QEvent::FontChange) {
- d->control->document()->setDefaultFont(font());
- } else if(e->type() == QEvent::ActivationChange) {
- if (!isActiveWindow())
- d->autoScrollTimer.stop();
- } else if (e->type() == QEvent::EnabledChange) {
- e->setAccepted(isEnabled());
- d->sendControlEvent(e);
- } else if (e->type() == QEvent::PaletteChange) {
- d->control->setPalette(palette());
- } else if (e->type() == QEvent::LayoutDirectionChange) {
- d->sendControlEvent(e);
- }
-}
-
-/*! \reimp
-*/
-#ifndef QT_NO_WHEELEVENT
-void QPlainTextEdit::wheelEvent(QWheelEvent *e)
-{
- QAbstractScrollArea::wheelEvent(e);
- updateMicroFocus();
-}
-#endif
-
-#ifndef QT_NO_CONTEXTMENU
-/*! This function creates the standard context menu which is shown
- when the user clicks on the line edit with the right mouse
- button. It is called from the default contextMenuEvent() handler.
- The popup menu's ownership is transferred to the caller.
-*/
-
-QMenu *QPlainTextEdit::createStandardContextMenu()
-{
- Q_D(QPlainTextEdit);
- return d->control->createStandardContextMenu(QPointF(), this);
-}
-#endif // QT_NO_CONTEXTMENU
-
-/*!
- returns a QTextCursor at position \a pos (in viewport coordinates).
-*/
-QTextCursor QPlainTextEdit::cursorForPosition(const QPoint &pos) const
-{
- Q_D(const QPlainTextEdit);
- return d->control->cursorForPosition(d->mapToContents(pos));
-}
-
-/*!
- returns a rectangle (in viewport coordinates) that includes the
- \a cursor.
- */
-QRect QPlainTextEdit::cursorRect(const QTextCursor &cursor) const
-{
- Q_D(const QPlainTextEdit);
- if (cursor.isNull())
- return QRect();
-
- QRect r = d->control->cursorRect(cursor).toRect();
- r.translate(-d->horizontalOffset(),-d->verticalOffset());
- return r;
-}
-
-/*!
- returns a rectangle (in viewport coordinates) that includes the
- cursor of the text edit.
- */
-QRect QPlainTextEdit::cursorRect() const
-{
- Q_D(const QPlainTextEdit);
- QRect r = d->control->cursorRect().toRect();
- r.translate(-d->horizontalOffset(),-d->verticalOffset());
- return r;
-}
-
-
-/*!
- \property QPlainTextEdit::overwriteMode
- \brief whether text entered by the user will overwrite existing text
-
- As with many text editors, the plain text editor widget can be configured
- to insert or overwrite existing text with new text entered by the user.
-
- If this property is true, existing text is overwritten, character-for-character
- by new text; otherwise, text is inserted at the cursor position, displacing
- existing text.
-
- By default, this property is false (new text does not overwrite existing text).
-*/
-
-bool QPlainTextEdit::overwriteMode() const
-{
- Q_D(const QPlainTextEdit);
- return d->control->overwriteMode();
-}
-
-void QPlainTextEdit::setOverwriteMode(bool overwrite)
-{
- Q_D(QPlainTextEdit);
- d->control->setOverwriteMode(overwrite);
-}
-
-/*!
- \property QPlainTextEdit::tabStopWidth
- \brief the tab stop width in pixels
-
- By default, this property contains a value of 80.
-*/
-
-int QPlainTextEdit::tabStopWidth() const
-{
- Q_D(const QPlainTextEdit);
- return qRound(d->control->document()->defaultTextOption().tabStop());
-}
-
-void QPlainTextEdit::setTabStopWidth(int width)
-{
- Q_D(QPlainTextEdit);
- QTextOption opt = d->control->document()->defaultTextOption();
- if (opt.tabStop() == width || width < 0)
- return;
- opt.setTabStop(width);
- d->control->document()->setDefaultTextOption(opt);
-}
-
-/*!
- \property QPlainTextEdit::cursorWidth
-
- This property specifies the width of the cursor in pixels. The default value is 1.
-*/
-int QPlainTextEdit::cursorWidth() const
-{
- Q_D(const QPlainTextEdit);
- return d->control->cursorWidth();
-}
-
-void QPlainTextEdit::setCursorWidth(int width)
-{
- Q_D(QPlainTextEdit);
- d->control->setCursorWidth(width);
-}
-
-
-
-/*!
- This function allows temporarily marking certain regions in the document
- with a given color, specified as \a selections. This can be useful for
- example in a programming editor to mark a whole line of text with a given
- background color to indicate the existence of a breakpoint.
-
- \sa QTextEdit::ExtraSelection, extraSelections()
-*/
-void QPlainTextEdit::setExtraSelections(const QList<QTextEdit::ExtraSelection> &selections)
-{
- Q_D(QPlainTextEdit);
- d->control->setExtraSelections(selections);
-}
-
-/*!
- Returns previously set extra selections.
-
- \sa setExtraSelections()
-*/
-QList<QTextEdit::ExtraSelection> QPlainTextEdit::extraSelections() const
-{
- Q_D(const QPlainTextEdit);
- return d->control->extraSelections();
-}
-
-/*!
- This function returns a new MIME data object to represent the contents
- of the text edit's current selection. It is called when the selection needs
- to be encapsulated into a new QMimeData object; for example, when a drag
- and drop operation is started, or when data is copied to the clipboard.
-
- If you reimplement this function, note that the ownership of the returned
- QMimeData object is passed to the caller. The selection can be retrieved
- by using the textCursor() function.
-*/
-QMimeData *QPlainTextEdit::createMimeDataFromSelection() const
-{
- Q_D(const QPlainTextEdit);
- return d->control->QTextControl::createMimeDataFromSelection();
-}
-
-/*!
- This function returns true if the contents of the MIME data object, specified
- by \a source, can be decoded and inserted into the document. It is called
- for example when during a drag operation the mouse enters this widget and it
- is necessary to determine whether it is possible to accept the drag.
- */
-bool QPlainTextEdit::canInsertFromMimeData(const QMimeData *source) const
-{
- Q_D(const QPlainTextEdit);
- return d->control->QTextControl::canInsertFromMimeData(source);
-}
-
-/*!
- This function inserts the contents of the MIME data object, specified
- by \a source, into the text edit at the current cursor position. It is
- called whenever text is inserted as the result of a clipboard paste
- operation, or when the text edit accepts data from a drag and drop
- operation.
-*/
-void QPlainTextEdit::insertFromMimeData(const QMimeData *source)
-{
- Q_D(QPlainTextEdit);
- d->control->QTextControl::insertFromMimeData(source);
-}
-
-/*!
- \property QPlainTextEdit::readOnly
- \brief whether the text edit is read-only
-
- In a read-only text edit the user can only navigate through the
- text and select text; modifying the text is not possible.
-
- This property's default is false.
-*/
-
-bool QPlainTextEdit::isReadOnly() const
-{
- Q_D(const QPlainTextEdit);
- return !(d->control->textInteractionFlags() & Qt::TextEditable);
-}
-
-void QPlainTextEdit::setReadOnly(bool ro)
-{
- Q_D(QPlainTextEdit);
- Qt::TextInteractionFlags flags = Qt::NoTextInteraction;
- if (ro) {
- flags = Qt::TextSelectableByMouse;
- } else {
- flags = Qt::TextEditorInteraction;
- }
- setAttribute(Qt::WA_InputMethodEnabled, shouldEnableInputMethod(this));
- d->control->setTextInteractionFlags(flags);
-}
-
-/*!
- \property QPlainTextEdit::textInteractionFlags
-
- Specifies how the label should interact with user input if it displays text.
-
- If the flags contain either Qt::LinksAccessibleByKeyboard or Qt::TextSelectableByKeyboard
- then the focus policy is also automatically set to Qt::ClickFocus.
-
- The default value depends on whether the QPlainTextEdit is read-only
- or editable.
-*/
-
-void QPlainTextEdit::setTextInteractionFlags(Qt::TextInteractionFlags flags)
-{
- Q_D(QPlainTextEdit);
- d->control->setTextInteractionFlags(flags);
-}
-
-Qt::TextInteractionFlags QPlainTextEdit::textInteractionFlags() const
-{
- Q_D(const QPlainTextEdit);
- return d->control->textInteractionFlags();
-}
-
-/*!
- Merges the properties specified in \a modifier into the current character
- format by calling QTextCursor::mergeCharFormat on the editor's cursor.
- If the editor has a selection then the properties of \a modifier are
- directly applied to the selection.
-
- \sa QTextCursor::mergeCharFormat()
- */
-void QPlainTextEdit::mergeCurrentCharFormat(const QTextCharFormat &modifier)
-{
- Q_D(QPlainTextEdit);
- d->control->mergeCurrentCharFormat(modifier);
-}
-
-/*!
- Sets the char format that is be used when inserting new text to \a
- format by calling QTextCursor::setCharFormat() on the editor's
- cursor. If the editor has a selection then the char format is
- directly applied to the selection.
- */
-void QPlainTextEdit::setCurrentCharFormat(const QTextCharFormat &format)
-{
- Q_D(QPlainTextEdit);
- d->control->setCurrentCharFormat(format);
-}
-
-/*!
- Returns the char format that is used when inserting new text.
- */
-QTextCharFormat QPlainTextEdit::currentCharFormat() const
-{
- Q_D(const QPlainTextEdit);
- return d->control->currentCharFormat();
-}
-
-
-
-/*!
- Convenience slot that inserts \a text at the current
- cursor position.
-
- It is equivalent to
-
- \snippet doc/src/snippets/code/src_gui_widgets_qplaintextedit.cpp 1
- */
-void QPlainTextEdit::insertPlainText(const QString &text)
-{
- Q_D(QPlainTextEdit);
- d->control->insertPlainText(text);
-}
-
-
-/*!
- Moves the cursor by performing the given \a operation.
-
- If \a mode is QTextCursor::KeepAnchor, the cursor selects the text it moves over.
- This is the same effect that the user achieves when they hold down the Shift key
- and move the cursor with the cursor keys.
-
- \sa QTextCursor::movePosition()
-*/
-void QPlainTextEdit::moveCursor(QTextCursor::MoveOperation operation, QTextCursor::MoveMode mode)
-{
- Q_D(QPlainTextEdit);
- d->control->moveCursor(operation, mode);
-}
-
-/*!
- Returns whether text can be pasted from the clipboard into the textedit.
-*/
-bool QPlainTextEdit::canPaste() const
-{
- Q_D(const QPlainTextEdit);
- return d->control->canPaste();
-}
-
-#ifndef QT_NO_PRINTER
-/*!
- Convenience function to print the text edit's document to the given \a printer. This
- is equivalent to calling the print method on the document directly except that this
- function also supports QPrinter::Selection as print range.
-
- \sa QTextDocument::print()
-*/
-void QPlainTextEdit::print(QPrinter *printer) const
-{
- Q_D(const QPlainTextEdit);
- d->control->print(printer);
-}
-#endif // QT _NO_PRINTER
-
-/*! \property QPlainTextEdit::tabChangesFocus
- \brief whether \gui Tab changes focus or is accepted as input
-
- In some occasions text edits should not allow the user to input
- tabulators or change indentation using the \gui Tab key, as this breaks
- the focus chain. The default is false.
-
-*/
-
-bool QPlainTextEdit::tabChangesFocus() const
-{
- Q_D(const QPlainTextEdit);
- return d->tabChangesFocus;
-}
-
-void QPlainTextEdit::setTabChangesFocus(bool b)
-{
- Q_D(QPlainTextEdit);
- d->tabChangesFocus = b;
-}
-
-/*!
- \property QPlainTextEdit::documentTitle
- \brief the title of the document parsed from the text.
-
- By default, this property contains an empty string.
-*/
-
-/*!
- \property QPlainTextEdit::lineWrapMode
- \brief the line wrap mode
-
- The default mode is WidgetWidth which causes words to be
- wrapped at the right edge of the text edit. Wrapping occurs at
- whitespace, keeping whole words intact. If you want wrapping to
- occur within words use setWordWrapMode().
-*/
-
-QPlainTextEdit::LineWrapMode QPlainTextEdit::lineWrapMode() const
-{
- Q_D(const QPlainTextEdit);
- return d->lineWrap;
-}
-
-void QPlainTextEdit::setLineWrapMode(LineWrapMode wrap)
-{
- Q_D(QPlainTextEdit);
- if (d->lineWrap == wrap)
- return;
- d->lineWrap = wrap;
- d->updateDefaultTextOption();
- d->relayoutDocument();
- d->_q_adjustScrollbars();
- ensureCursorVisible();
-}
-
-/*!
- \property QPlainTextEdit::wordWrapMode
- \brief the mode QPlainTextEdit will use when wrapping text by words
-
- By default, this property is set to QTextOption::WrapAtWordBoundaryOrAnywhere.
-
- \sa QTextOption::WrapMode
-*/
-
-QTextOption::WrapMode QPlainTextEdit::wordWrapMode() const
-{
- Q_D(const QPlainTextEdit);
- return d->wordWrap;
-}
-
-void QPlainTextEdit::setWordWrapMode(QTextOption::WrapMode mode)
-{
- Q_D(QPlainTextEdit);
- if (mode == d->wordWrap)
- return;
- d->wordWrap = mode;
- d->updateDefaultTextOption();
-}
-
-/*!
- \property QPlainTextEdit::backgroundVisible
- \brief whether the palette background is visible outside the document area
-
- If set to true, the plain text edit paints the palette background
- on the viewport area not covered by the text document. Otherwise,
- if set to false, it won't. The feature makes it possible for
- the user to visually distinguish between the area of the document,
- painted with the base color of the palette, and the empty
- area not covered by any document.
-
- The default is false.
-*/
-
-bool QPlainTextEdit::backgroundVisible() const
-{
- Q_D(const QPlainTextEdit);
- return d->backgroundVisible;
-}
-
-void QPlainTextEdit::setBackgroundVisible(bool visible)
-{
- Q_D(QPlainTextEdit);
- if (visible == d->backgroundVisible)
- return;
- d->backgroundVisible = visible;
- d->updateViewport();
-}
-
-/*!
- \property QPlainTextEdit::centerOnScroll
- \brief whether the cursor should be centered on screen
-
- If set to true, the plain text edit scrolls the document
- vertically to make the cursor visible at the center of the
- viewport. This also allows the text edit to scroll below the end
- of the document. Otherwise, if set to false, the plain text edit
- scrolls the smallest amount possible to ensure the cursor is
- visible. The same algorithm is applied to any new line appended
- through appendPlainText().
-
- The default is false.
-
- \sa centerCursor(), ensureCursorVisible()
-*/
-
-bool QPlainTextEdit::centerOnScroll() const
-{
- Q_D(const QPlainTextEdit);
- return d->centerOnScroll;
-}
-
-void QPlainTextEdit::setCenterOnScroll(bool enabled)
-{
- Q_D(QPlainTextEdit);
- if (enabled == d->centerOnScroll)
- return;
- d->centerOnScroll = enabled;
-}
-
-
-
-/*!
- Finds the next occurrence of the string, \a exp, using the given
- \a options. Returns true if \a exp was found and changes the
- cursor to select the match; otherwise returns false.
-*/
-bool QPlainTextEdit::find(const QString &exp, QTextDocument::FindFlags options)
-{
- Q_D(QPlainTextEdit);
- return d->control->find(exp, options);
-}
-
-/*!
- \fn void QPlainTextEdit::copyAvailable(bool yes)
-
- This signal is emitted when text is selected or de-selected in the
- text edit.
-
- When text is selected this signal will be emitted with \a yes set
- to true. If no text has been selected or if the selected text is
- de-selected this signal is emitted with \a yes set to false.
-
- If \a yes is true then copy() can be used to copy the selection to
- the clipboard. If \a yes is false then copy() does nothing.
-
- \sa selectionChanged()
-*/
-
-
-/*!
- \fn void QPlainTextEdit::selectionChanged()
-
- This signal is emitted whenever the selection changes.
-
- \sa copyAvailable()
-*/
-
-/*!
- \fn void QPlainTextEdit::cursorPositionChanged()
-
- This signal is emitted whenever the position of the
- cursor changed.
-*/
-
-
-
-/*!
- \fn void QPlainTextEdit::updateRequest(const QRect &rect, int dy)
-
- This signal is emitted when the text document needs an update of
- the specified \a rect. If the text is scrolled, \a rect will cover
- the entire viewport area. If the text is scrolled vertically, \a
- dy carries the amount of pixels the viewport was scrolled.
-
- The purpose of the signal is to support extra widgets in plain
- text edit subclasses that e.g. show line numbers, breakpoints, or
- other extra information.
-*/
-
-/*! \fn void QPlainTextEdit::blockCountChanged(int newBlockCount);
-
- This signal is emitted whenever the block count changes. The new
- block count is passed in \a newBlockCount.
-*/
-
-/*! \fn void QPlainTextEdit::modificationChanged(bool changed);
-
- This signal is emitted whenever the content of the document
- changes in a way that affects the modification state. If \a
- changed is true, the document has been modified; otherwise it is
- false.
-
- For example, calling setModified(false) on a document and then
- inserting text causes the signal to get emitted. If you undo that
- operation, causing the document to return to its original
- unmodified state, the signal will get emitted again.
-*/
-
-
-
-
-void QPlainTextEditPrivate::append(const QString &text, Qt::TextFormat format)
-{
- Q_Q(QPlainTextEdit);
-
- QTextDocument *document = control->document();
- QPlainTextDocumentLayout *documentLayout = qobject_cast<QPlainTextDocumentLayout*>(document->documentLayout());
- Q_ASSERT(documentLayout);
-
- int maximumBlockCount = document->maximumBlockCount();
- if (maximumBlockCount)
- document->setMaximumBlockCount(0);
-
- const bool atBottom = q->isVisible()
- && (control->blockBoundingRect(document->lastBlock()).bottom() - verticalOffset()
- <= viewport->rect().bottom());
-
- if (!q->isVisible())
- showCursorOnInitialShow = true;
-
- bool documentSizeChangedBlocked = documentLayout->priv()->blockDocumentSizeChanged;
- documentLayout->priv()->blockDocumentSizeChanged = true;
-
- if (format == Qt::RichText)
- control->appendHtml(text);
- else if (format == Qt::PlainText)
- control->appendPlainText(text);
- else
- control->append(text);
-
- if (maximumBlockCount > 0) {
- if (document->blockCount() > maximumBlockCount) {
- bool blockUpdate = false;
- if (control->topBlock) {
- control->topBlock--;
- blockUpdate = true;
- emit q->updateRequest(viewport->rect(), 0);
- }
-
- bool updatesBlocked = documentLayout->priv()->blockUpdate;
- documentLayout->priv()->blockUpdate = blockUpdate;
- QTextCursor cursor(document);
- cursor.movePosition(QTextCursor::NextBlock, QTextCursor::KeepAnchor);
- cursor.removeSelectedText();
- documentLayout->priv()->blockUpdate = updatesBlocked;
- }
- document->setMaximumBlockCount(maximumBlockCount);
- }
-
- documentLayout->priv()->blockDocumentSizeChanged = documentSizeChangedBlocked;
- _q_adjustScrollbars();
-
-
- if (atBottom) {
- const bool needScroll = !centerOnScroll
- || control->blockBoundingRect(document->lastBlock()).bottom() - verticalOffset()
- > viewport->rect().bottom();
- if (needScroll)
- vbar->setValue(vbar->maximum());
- }
-}
-
-
-/*!
- Appends a new paragraph with \a text to the end of the text edit.
-
- \sa appendHtml()
-*/
-
-void QPlainTextEdit::appendPlainText(const QString &text)
-{
- Q_D(QPlainTextEdit);
- d->append(text, Qt::PlainText);
-}
-
-/*!
- Appends a new paragraph with \a html to the end of the text edit.
-
- appendPlainText()
-*/
-
-void QPlainTextEdit::appendHtml(const QString &html)
-{
- Q_D(QPlainTextEdit);
- d->append(html, Qt::RichText);
-}
-
-void QPlainTextEditPrivate::ensureCursorVisible(bool center)
-{
- Q_Q(QPlainTextEdit);
- QRect visible = viewport->rect();
- QRect cr = q->cursorRect();
- if (cr.top() < visible.top() || cr.bottom() > visible.bottom()) {
- ensureVisible(control->textCursor().position(), center);
- }
-
- const bool rtl = q->isRightToLeft();
- if (cr.left() < visible.left() || cr.right() > visible.right()) {
- int x = cr.center().x() + horizontalOffset() - visible.width()/2;
- hbar->setValue(rtl ? hbar->maximum() - x : x);
- }
-}
-
-/*!
- Ensures that the cursor is visible by scrolling the text edit if
- necessary.
-
- \sa centerCursor(), centerOnScroll
-*/
-void QPlainTextEdit::ensureCursorVisible()
-{
- Q_D(QPlainTextEdit);
- d->ensureCursorVisible(d->centerOnScroll);
-}
-
-
-/*! Scrolls the document in order to center the cursor vertically.
-
-\sa ensureCursorVisible(), centerOnScroll
- */
-void QPlainTextEdit::centerCursor()
-{
- Q_D(QPlainTextEdit);
- d->ensureVisible(textCursor().position(), true, true);
-}
-
-/*!
- Returns the first visible block.
-
- \sa blockBoundingRect()
- */
-QTextBlock QPlainTextEdit::firstVisibleBlock() const
-{
- Q_D(const QPlainTextEdit);
- return d->control->firstVisibleBlock();
-}
-
-/*! Returns the content's origin in viewport coordinates.
-
- The origin of the content of a plain text edit is always the top
- left corner of the first visible text block. The content offset
- is different from (0,0) when the text has been scrolled
- horizontally, or when the first visible block has been scrolled
- partially off the screen, i.e. the visible text does not start
- with the first line of the first visible block, or when the first
- visible block is the very first block and the editor displays a
- margin.
-
- \sa firstVisibleBlock(), horizontalScrollBar(), verticalScrollBar()
- */
-QPointF QPlainTextEdit::contentOffset() const
-{
- Q_D(const QPlainTextEdit);
- return QPointF(-d->horizontalOffset(), -d->verticalOffset());
-}
-
-
-/*! Returns the bounding rectangle of the text \a block in content
- coordinates. Translate the rectangle with the contentOffset() to get
- visual coordinates on the viewport.
-
- \sa firstVisibleBlock(), blockBoundingRect()
- */
-QRectF QPlainTextEdit::blockBoundingGeometry(const QTextBlock &block) const
-{
- Q_D(const QPlainTextEdit);
- return d->control->blockBoundingRect(block);
-}
-
-/*!
- Returns the bounding rectangle of the text \a block in the block's own coordinates.
-
- \sa blockBoundingGeometry()
- */
-QRectF QPlainTextEdit::blockBoundingRect(const QTextBlock &block) const
-{
- QPlainTextDocumentLayout *documentLayout = qobject_cast<QPlainTextDocumentLayout*>(document()->documentLayout());
- Q_ASSERT(documentLayout);
- return documentLayout->blockBoundingRect(block);
-}
-
-/*!
- \property QPlainTextEdit::blockCount
- \brief the number of text blocks in the document.
-
- By default, in an empty document, this property contains a value of 1.
-*/
-int QPlainTextEdit::blockCount() const
-{
- return document()->blockCount();
-}
-
-/*! Returns the paint context for the viewport(), useful only when
- reimplementing paintEvent().
- */
-QAbstractTextDocumentLayout::PaintContext QPlainTextEdit::getPaintContext() const
-{
- Q_D(const QPlainTextEdit);
- return d->control->getPaintContext(d->viewport);
-}
-
-/*!
- \property QPlainTextEdit::maximumBlockCount
- \brief the limit for blocks in the document.
-
- Specifies the maximum number of blocks the document may have. If there are
- more blocks in the document that specified with this property blocks are removed
- from the beginning of the document.
-
- A negative or zero value specifies that the document may contain an unlimited
- amount of blocks.
-
- The default value is 0.
-
- Note that setting this property will apply the limit immediately to the document
- contents. Setting this property also disables the undo redo history.
-
-*/
-
-
-/*!
- \fn void QPlainTextEdit::textChanged()
-
- This signal is emitted whenever the document's content changes; for
- example, when text is inserted or deleted, or when formatting is applied.
-*/
-
-/*!
- \fn void QPlainTextEdit::undoAvailable(bool available)
-
- This signal is emitted whenever undo operations become available
- (\a available is true) or unavailable (\a available is false).
-*/
-
-/*!
- \fn void QPlainTextEdit::redoAvailable(bool available)
-
- This signal is emitted whenever redo operations become available
- (\a available is true) or unavailable (\a available is false).
-*/
-
-QT_END_NAMESPACE
-
-#include "moc_qplaintextedit.cpp"
-#include "moc_qplaintextedit_p.cpp"
-
-#endif // QT_NO_TEXTEDIT
diff --git a/src/gui/widgets/qplaintextedit.h b/src/gui/widgets/qplaintextedit.h
deleted file mode 100644
index 75173c1f77..0000000000
--- a/src/gui/widgets/qplaintextedit.h
+++ /dev/null
@@ -1,329 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPLAINTEXTEDIT_H
-#define QPLAINTEXTEDIT_H
-
-#include <QtGui/qtextedit.h>
-
-#include <QtGui/qabstractscrollarea.h>
-#include <QtGui/qtextdocument.h>
-#include <QtGui/qtextoption.h>
-#include <QtGui/qtextcursor.h>
-#include <QtGui/qtextformat.h>
-#include <QtGui/qabstracttextdocumentlayout.h>
-
-#ifndef QT_NO_TEXTEDIT
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QStyleSheet;
-class QTextDocument;
-class QMenu;
-class QPlainTextEditPrivate;
-class QMimeData;
-
-
-class Q_GUI_EXPORT QPlainTextEdit : public QAbstractScrollArea
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QPlainTextEdit)
- Q_ENUMS(LineWrapMode)
- Q_PROPERTY(bool tabChangesFocus READ tabChangesFocus WRITE setTabChangesFocus)
- Q_PROPERTY(QString documentTitle READ documentTitle WRITE setDocumentTitle)
- Q_PROPERTY(bool undoRedoEnabled READ isUndoRedoEnabled WRITE setUndoRedoEnabled)
- Q_PROPERTY(LineWrapMode lineWrapMode READ lineWrapMode WRITE setLineWrapMode)
- QDOC_PROPERTY(QTextOption::WrapMode wordWrapMode READ wordWrapMode WRITE setWordWrapMode)
- Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly)
- Q_PROPERTY(QString plainText READ toPlainText WRITE setPlainText NOTIFY textChanged USER true)
- Q_PROPERTY(bool overwriteMode READ overwriteMode WRITE setOverwriteMode)
- Q_PROPERTY(int tabStopWidth READ tabStopWidth WRITE setTabStopWidth)
- Q_PROPERTY(int cursorWidth READ cursorWidth WRITE setCursorWidth)
- Q_PROPERTY(Qt::TextInteractionFlags textInteractionFlags READ textInteractionFlags WRITE setTextInteractionFlags)
- Q_PROPERTY(int blockCount READ blockCount)
- Q_PROPERTY(int maximumBlockCount READ maximumBlockCount WRITE setMaximumBlockCount)
- Q_PROPERTY(bool backgroundVisible READ backgroundVisible WRITE setBackgroundVisible)
- Q_PROPERTY(bool centerOnScroll READ centerOnScroll WRITE setCenterOnScroll)
-public:
- enum LineWrapMode {
- NoWrap,
- WidgetWidth
- };
-
- explicit QPlainTextEdit(QWidget *parent = 0);
- explicit QPlainTextEdit(const QString &text, QWidget *parent = 0);
- virtual ~QPlainTextEdit();
-
- void setDocument(QTextDocument *document);
- QTextDocument *document() const;
-
- void setTextCursor(const QTextCursor &cursor);
- QTextCursor textCursor() const;
-
- bool isReadOnly() const;
- void setReadOnly(bool ro);
-
- void setTextInteractionFlags(Qt::TextInteractionFlags flags);
- Qt::TextInteractionFlags textInteractionFlags() const;
-
- void mergeCurrentCharFormat(const QTextCharFormat &modifier);
- void setCurrentCharFormat(const QTextCharFormat &format);
- QTextCharFormat currentCharFormat() const;
-
- bool tabChangesFocus() const;
- void setTabChangesFocus(bool b);
-
- inline void setDocumentTitle(const QString &title)
- { document()->setMetaInformation(QTextDocument::DocumentTitle, title); }
- inline QString documentTitle() const
- { return document()->metaInformation(QTextDocument::DocumentTitle); }
-
- inline bool isUndoRedoEnabled() const
- { return document()->isUndoRedoEnabled(); }
- inline void setUndoRedoEnabled(bool enable)
- { document()->setUndoRedoEnabled(enable); }
-
- inline void setMaximumBlockCount(int maximum)
- { document()->setMaximumBlockCount(maximum); }
- inline int maximumBlockCount() const
- { return document()->maximumBlockCount(); }
-
-
- LineWrapMode lineWrapMode() const;
- void setLineWrapMode(LineWrapMode mode);
-
- QTextOption::WrapMode wordWrapMode() const;
- void setWordWrapMode(QTextOption::WrapMode policy);
-
- void setBackgroundVisible(bool visible);
- bool backgroundVisible() const;
-
- void setCenterOnScroll(bool enabled);
- bool centerOnScroll() const;
-
- bool find(const QString &exp, QTextDocument::FindFlags options = 0);
-
- inline QString toPlainText() const
- { return document()->toPlainText(); }
-
- void ensureCursorVisible();
-
- virtual QVariant loadResource(int type, const QUrl &name);
-#ifndef QT_NO_CONTEXTMENU
- QMenu *createStandardContextMenu();
-#endif
-
- QTextCursor cursorForPosition(const QPoint &pos) const;
- QRect cursorRect(const QTextCursor &cursor) const;
- QRect cursorRect() const;
-
- QString anchorAt(const QPoint &pos) const;
-
- bool overwriteMode() const;
- void setOverwriteMode(bool overwrite);
-
- int tabStopWidth() const;
- void setTabStopWidth(int width);
-
- int cursorWidth() const;
- void setCursorWidth(int width);
-
- void setExtraSelections(const QList<QTextEdit::ExtraSelection> &selections);
- QList<QTextEdit::ExtraSelection> extraSelections() const;
-
- void moveCursor(QTextCursor::MoveOperation operation, QTextCursor::MoveMode mode = QTextCursor::MoveAnchor);
-
- bool canPaste() const;
-
-#ifndef QT_NO_PRINTER
- void print(QPrinter *printer) const;
-#endif
-
- int blockCount() const;
-
-public Q_SLOTS:
-
- void setPlainText(const QString &text);
-
-#ifndef QT_NO_CLIPBOARD
- void cut();
- void copy();
- void paste();
-#endif
-
- void undo();
- void redo();
-
- void clear();
- void selectAll();
-
- void insertPlainText(const QString &text);
-
- void appendPlainText(const QString &text);
- void appendHtml(const QString &html);
-
- void centerCursor();
-
-Q_SIGNALS:
- void textChanged();
- void undoAvailable(bool b);
- void redoAvailable(bool b);
- void copyAvailable(bool b);
- void selectionChanged();
- void cursorPositionChanged();
-
- void updateRequest(const QRect &rect, int dy);
- void blockCountChanged(int newBlockCount);
- void modificationChanged(bool);
-
-protected:
- virtual bool event(QEvent *e);
- virtual void timerEvent(QTimerEvent *e);
- virtual void keyPressEvent(QKeyEvent *e);
- virtual void keyReleaseEvent(QKeyEvent *e);
- virtual void resizeEvent(QResizeEvent *e);
- virtual void paintEvent(QPaintEvent *e);
- virtual void mousePressEvent(QMouseEvent *e);
- virtual void mouseMoveEvent(QMouseEvent *e);
- virtual void mouseReleaseEvent(QMouseEvent *e);
- virtual void mouseDoubleClickEvent(QMouseEvent *e);
- virtual bool focusNextPrevChild(bool next);
-#ifndef QT_NO_CONTEXTMENU
- virtual void contextMenuEvent(QContextMenuEvent *e);
-#endif
-#ifndef QT_NO_DRAGANDDROP
- virtual void dragEnterEvent(QDragEnterEvent *e);
- virtual void dragLeaveEvent(QDragLeaveEvent *e);
- virtual void dragMoveEvent(QDragMoveEvent *e);
- virtual void dropEvent(QDropEvent *e);
-#endif
- virtual void focusInEvent(QFocusEvent *e);
- virtual void focusOutEvent(QFocusEvent *e);
- virtual void showEvent(QShowEvent *);
- virtual void changeEvent(QEvent *e);
-#ifndef QT_NO_WHEELEVENT
- virtual void wheelEvent(QWheelEvent *e);
-#endif
-
- virtual QMimeData *createMimeDataFromSelection() const;
- virtual bool canInsertFromMimeData(const QMimeData *source) const;
- virtual void insertFromMimeData(const QMimeData *source);
-
- virtual void inputMethodEvent(QInputMethodEvent *);
- QVariant inputMethodQuery(Qt::InputMethodQuery property) const;
-
- QPlainTextEdit(QPlainTextEditPrivate &dd, QWidget *parent);
-
- virtual void scrollContentsBy(int dx, int dy);
-
- QTextBlock firstVisibleBlock() const;
- QPointF contentOffset() const;
- QRectF blockBoundingRect(const QTextBlock &block) const;
- QRectF blockBoundingGeometry(const QTextBlock &block) const;
- QAbstractTextDocumentLayout::PaintContext getPaintContext() const;
-
-
-private:
- Q_DISABLE_COPY(QPlainTextEdit)
- Q_PRIVATE_SLOT(d_func(), void _q_repaintContents(const QRectF &r))
- Q_PRIVATE_SLOT(d_func(), void _q_adjustScrollbars())
- Q_PRIVATE_SLOT(d_func(), void _q_verticalScrollbarActionTriggered(int))
- Q_PRIVATE_SLOT(d_func(), void _q_cursorPositionChanged())
-
- friend class QPlainTextEditControl;
-};
-
-
-class QPlainTextDocumentLayoutPrivate;
-class Q_GUI_EXPORT QPlainTextDocumentLayout : public QAbstractTextDocumentLayout
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QPlainTextDocumentLayout)
- Q_PROPERTY(int cursorWidth READ cursorWidth WRITE setCursorWidth)
-
-public:
- QPlainTextDocumentLayout(QTextDocument *document);
- ~QPlainTextDocumentLayout();
-
- void draw(QPainter *, const PaintContext &);
- int hitTest(const QPointF &, Qt::HitTestAccuracy ) const;
-
- int pageCount() const;
- QSizeF documentSize() const;
-
- QRectF frameBoundingRect(QTextFrame *) const;
- QRectF blockBoundingRect(const QTextBlock &block) const;
-
- void ensureBlockLayout(const QTextBlock &block) const;
-
- void setCursorWidth(int width);
- int cursorWidth() const;
-
- void requestUpdate();
-
-protected:
- void documentChanged(int from, int /*charsRemoved*/, int charsAdded);
-
-
-private:
- void setTextWidth(qreal newWidth);
- qreal textWidth() const;
- void layoutBlock(const QTextBlock &block);
- qreal blockWidth(const QTextBlock &block);
-
- QPlainTextDocumentLayoutPrivate *priv() const;
-
- friend class QPlainTextEdit;
- friend class QPlainTextEditPrivate;
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-
-#endif // QT_NO_TEXTEDIT
-
-#endif // QPLAINTEXTEDIT_H
diff --git a/src/gui/widgets/qplaintextedit_p.h b/src/gui/widgets/qplaintextedit_p.h
deleted file mode 100644
index 90a589193d..0000000000
--- a/src/gui/widgets/qplaintextedit_p.h
+++ /dev/null
@@ -1,187 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPLAINTEXTEDIT_P_H
-#define QPLAINTEXTEDIT_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "private/qabstractscrollarea_p.h"
-#include "QtGui/qtextdocumentfragment.h"
-#include "QtGui/qscrollbar.h"
-#include "QtGui/qtextcursor.h"
-#include "QtGui/qtextformat.h"
-#include "QtGui/qmenu.h"
-#include "QtGui/qabstracttextdocumentlayout.h"
-#include "QtCore/qbasictimer.h"
-#include "private/qtextcontrol_p.h"
-#include "qplaintextedit.h"
-
-#ifndef QT_NO_TEXTEDIT
-
-QT_BEGIN_NAMESPACE
-
-class QMimeData;
-
-class QPlainTextEdit;
-class ExtraArea;
-
-class QPlainTextEditControl : public QTextControl
-{
- Q_OBJECT
-public:
- QPlainTextEditControl(QPlainTextEdit *parent);
-
-
- QMimeData *createMimeDataFromSelection() const;
- bool canInsertFromMimeData(const QMimeData *source) const;
- void insertFromMimeData(const QMimeData *source);
- int hitTest(const QPointF &point, Qt::HitTestAccuracy = Qt::FuzzyHit) const;
- QRectF blockBoundingRect(const QTextBlock &block) const;
- inline QRectF cursorRect(const QTextCursor &cursor) const {
- QRectF r = QTextControl::cursorRect(cursor);
- r.setLeft(qMax(r.left(), (qreal) 0.));
- return r;
- }
- inline QRectF cursorRect() { return cursorRect(textCursor()); }
- void ensureCursorVisible() {
- textEdit->ensureCursorVisible();
- emit microFocusChanged();
- }
-
-
- QPlainTextEdit *textEdit;
- int topBlock;
- QTextBlock firstVisibleBlock() const;
-
- QVariant loadResource(int type, const QUrl &name) {
- return textEdit->loadResource(type, name);
- }
-
-};
-
-
-class QPlainTextEditPrivate : public QAbstractScrollAreaPrivate
-{
- Q_DECLARE_PUBLIC(QPlainTextEdit)
-public:
- QPlainTextEditPrivate();
-
- void init(const QString &txt = QString());
- void _q_repaintContents(const QRectF &contentsRect);
-
- inline QPoint mapToContents(const QPoint &point) const
- { return QPoint(point.x() + horizontalOffset(), point.y() + verticalOffset()); }
-
- void _q_adjustScrollbars();
- void _q_verticalScrollbarActionTriggered(int action);
- void ensureViewportLayouted();
- void relayoutDocument();
-
- void pageUpDown(QTextCursor::MoveOperation op, QTextCursor::MoveMode moveMode, bool moveCursor = true);
-
- inline int horizontalOffset() const
- { return (q_func()->isRightToLeft() ? (hbar->maximum() - hbar->value()) : hbar->value()); }
- int verticalOffset(int topBlock, int topLine) const;
- int verticalOffset() const;
-
- inline void sendControlEvent(QEvent *e)
- { control->processEvent(e, QPointF(horizontalOffset(), verticalOffset()), viewport); }
-
- void updateDefaultTextOption();
-
- QPlainTextEditControl *control;
-
- bool tabChangesFocus;
-
- QBasicTimer autoScrollTimer;
- QPoint autoScrollDragPos;
-
- QPlainTextEdit::LineWrapMode lineWrap;
- QTextOption::WrapMode wordWrap;
-
- uint showCursorOnInitialShow : 1;
- uint backgroundVisible : 1;
- uint centerOnScroll : 1;
- uint inDrag : 1;
- uint clickCausedFocus : 1;
-
- int topLine;
-
- void setTopLine(int visualTopLine, int dx = 0);
- void setTopBlock(int newTopBlock, int newTopLine, int dx = 0);
-
- void ensureVisible(int position, bool center, bool forceCenter = false);
- void ensureCursorVisible(bool center = false);
- void updateViewport();
-
- QPointer<QPlainTextDocumentLayout> documentLayoutPtr;
-
- void append(const QString &text, Qt::TextFormat format = Qt::AutoText);
-
- qreal pageUpDownLastCursorY;
- bool pageUpDownLastCursorYIsValid;
-
-
-#ifdef QT_KEYPAD_NAVIGATION
- QBasicTimer deleteAllTimer;
-#endif
-
- void _q_cursorPositionChanged();
- void _q_modificationChanged(bool);
-
- int originalOffsetY;
-};
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_TEXTEDIT
-
-#endif // QPLAINTEXTEDIT_P_H
diff --git a/src/gui/widgets/qprintpreviewwidget.cpp b/src/gui/widgets/qprintpreviewwidget.cpp
deleted file mode 100644
index 47e67a46fe..0000000000
--- a/src/gui/widgets/qprintpreviewwidget.cpp
+++ /dev/null
@@ -1,844 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qprintpreviewwidget.h"
-#include "private/qwidget_p.h"
-#include <private/qprinter_p.h>
-
-#include <QtCore/qmath.h>
-#include <QtGui/qboxlayout.h>
-#include <QtGui/qgraphicsitem.h>
-#include <QtGui/qgraphicsview.h>
-#include <QtGui/qscrollbar.h>
-#include <QtGui/qstyleoption.h>
-
-#ifndef QT_NO_PRINTPREVIEWWIDGET
-
-QT_BEGIN_NAMESPACE
-
-namespace {
-class PageItem : public QGraphicsItem
-{
-public:
- PageItem(int _pageNum, const QPicture* _pagePicture, QSize _paperSize, QRect _pageRect)
- : pageNum(_pageNum), pagePicture(_pagePicture),
- paperSize(_paperSize), pageRect(_pageRect)
- {
- qreal border = qMax(paperSize.height(), paperSize.width()) / 25;
- brect = QRectF(QPointF(-border, -border),
- QSizeF(paperSize)+QSizeF(2*border, 2*border));
- setCacheMode(DeviceCoordinateCache);
- }
-
- inline QRectF boundingRect() const
- { return brect; }
-
- inline int pageNumber() const
- { return pageNum; }
-
- void paint(QPainter *painter, const QStyleOptionGraphicsItem *item, QWidget *widget);
-
-private:
- int pageNum;
- const QPicture* pagePicture;
- QSize paperSize;
- QRect pageRect;
- QRectF brect;
-};
-
-void PageItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
-{
- Q_UNUSED(widget);
-
-#if 0
- // Draw item bounding rect, for debugging
- painter->save();
- painter->setPen(QPen(Qt::red, 0));
- painter->setBrush(Qt::NoBrush);
- painter->drawRect(QRectF(-border()+1.0, -border()+1.0, boundingRect().width()-2, boundingRect().height()-2));
- painter->restore();
-#endif
-
- QRectF paperRect(0,0, paperSize.width(), paperSize.height());
-
- // Draw shadow
- painter->setClipRect(option->exposedRect);
- qreal shWidth = paperRect.width()/100;
- QRectF rshadow(paperRect.topRight() + QPointF(0, shWidth),
- paperRect.bottomRight() + QPointF(shWidth, 0));
- QLinearGradient rgrad(rshadow.topLeft(), rshadow.topRight());
- rgrad.setColorAt(0.0, QColor(0,0,0,255));
- rgrad.setColorAt(1.0, QColor(0,0,0,0));
- painter->fillRect(rshadow, QBrush(rgrad));
- QRectF bshadow(paperRect.bottomLeft() + QPointF(shWidth, 0),
- paperRect.bottomRight() + QPointF(0, shWidth));
- QLinearGradient bgrad(bshadow.topLeft(), bshadow.bottomLeft());
- bgrad.setColorAt(0.0, QColor(0,0,0,255));
- bgrad.setColorAt(1.0, QColor(0,0,0,0));
- painter->fillRect(bshadow, QBrush(bgrad));
- QRectF cshadow(paperRect.bottomRight(),
- paperRect.bottomRight() + QPointF(shWidth, shWidth));
- QRadialGradient cgrad(cshadow.topLeft(), shWidth, cshadow.topLeft());
- cgrad.setColorAt(0.0, QColor(0,0,0,255));
- cgrad.setColorAt(1.0, QColor(0,0,0,0));
- painter->fillRect(cshadow, QBrush(cgrad));
-
- painter->setClipRect(paperRect & option->exposedRect);
- painter->fillRect(paperRect, Qt::white);
- if (!pagePicture)
- return;
- painter->drawPicture(pageRect.topLeft(), *pagePicture);
-
- // Effect: make anything drawn in the margins look washed out.
- QPainterPath path;
- path.addRect(paperRect);
- path.addRect(pageRect);
- painter->setPen(QPen(Qt::NoPen));
- painter->setBrush(QColor(255, 255, 255, 180));
- painter->drawPath(path);
-
-#if 0
- // Draw frame around paper.
- painter->setPen(QPen(Qt::black, 0));
- painter->setBrush(Qt::NoBrush);
- painter->drawRect(paperRect);
-#endif
-
- // todo: drawtext "Page N" below paper
-}
-
-class GraphicsView : public QGraphicsView
-{
- Q_OBJECT
-public:
- GraphicsView(QWidget* parent = 0)
- : QGraphicsView(parent)
- {
-#ifdef Q_WS_MAC
- setFrameStyle(QFrame::NoFrame);
-#endif
- }
-signals:
- void resized();
-
-protected:
- void resizeEvent(QResizeEvent* e)
- {
- QGraphicsView::resizeEvent(e);
- emit resized();
- }
-
- void showEvent(QShowEvent* e)
- {
- QGraphicsView::showEvent(e);
- emit resized();
- }
-};
-
-} // anonymous namespace
-
-class QPrintPreviewWidgetPrivate : public QWidgetPrivate
-{
- Q_DECLARE_PUBLIC(QPrintPreviewWidget)
-public:
- QPrintPreviewWidgetPrivate()
- : scene(0), curPage(1),
- viewMode(QPrintPreviewWidget::SinglePageView),
- zoomMode(QPrintPreviewWidget::FitInView),
- zoomFactor(1), initialized(false), fitting(true)
- {}
-
- // private slots
- void _q_fit(bool doFitting = false);
- void _q_updateCurrentPage();
-
- void init();
- void populateScene();
- void layoutPages();
- void generatePreview();
- void setCurrentPage(int pageNumber);
- void zoom(qreal zoom);
- void setZoomFactor(qreal zoomFactor);
- int calcCurrentPage();
-
- GraphicsView *graphicsView;
- QGraphicsScene *scene;
-
- int curPage;
- QList<const QPicture *> pictures;
- QList<QGraphicsItem *> pages;
-
- QPrintPreviewWidget::ViewMode viewMode;
- QPrintPreviewWidget::ZoomMode zoomMode;
- qreal zoomFactor;
- bool ownPrinter;
- QPrinter* printer;
- bool initialized;
- bool fitting;
-};
-
-void QPrintPreviewWidgetPrivate::_q_fit(bool doFitting)
-{
- Q_Q(QPrintPreviewWidget);
-
- if (curPage < 1 || curPage > pages.count())
- return;
-
- if (!doFitting && !fitting)
- return;
-
- if (doFitting && fitting) {
- QRect viewRect = graphicsView->viewport()->rect();
- if (zoomMode == QPrintPreviewWidget::FitInView) {
- QList<QGraphicsItem*> containedItems = graphicsView->items(viewRect, Qt::ContainsItemBoundingRect);
- foreach(QGraphicsItem* item, containedItems) {
- PageItem* pg = static_cast<PageItem*>(item);
- if (pg->pageNumber() == curPage)
- return;
- }
- }
-
- int newPage = calcCurrentPage();
- if (newPage != curPage)
- curPage = newPage;
- }
-
- QRectF target = pages.at(curPage-1)->sceneBoundingRect();
- if (viewMode == QPrintPreviewWidget::FacingPagesView) {
- // fit two pages
- if (curPage % 2)
- target.setLeft(target.left() - target.width());
- else
- target.setRight(target.right() + target.width());
- } else if (viewMode == QPrintPreviewWidget::AllPagesView) {
- target = scene->itemsBoundingRect();
- }
-
- if (zoomMode == QPrintPreviewWidget::FitToWidth) {
- QTransform t;
- qreal scale = graphicsView->viewport()->width() / target.width();
- t.scale(scale, scale);
- graphicsView->setTransform(t);
- if (doFitting && fitting) {
- QRectF viewSceneRect = graphicsView->viewportTransform().mapRect(graphicsView->viewport()->rect());
- viewSceneRect.moveTop(target.top());
- graphicsView->ensureVisible(viewSceneRect); // Nah...
- }
- } else {
- graphicsView->fitInView(target, Qt::KeepAspectRatio);
- if (zoomMode == QPrintPreviewWidget::FitInView) {
- int step = qRound(graphicsView->matrix().mapRect(target).height());
- graphicsView->verticalScrollBar()->setSingleStep(step);
- graphicsView->verticalScrollBar()->setPageStep(step);
- }
- }
-
- zoomFactor = graphicsView->transform().m11() * (float(printer->logicalDpiY()) / q->logicalDpiY());
- emit q->previewChanged();
-}
-
-void QPrintPreviewWidgetPrivate::_q_updateCurrentPage()
-{
- Q_Q(QPrintPreviewWidget);
-
- if (viewMode == QPrintPreviewWidget::AllPagesView)
- return;
-
- int newPage = calcCurrentPage();
- if (newPage != curPage) {
- curPage = newPage;
- emit q->previewChanged();
- }
-}
-
-int QPrintPreviewWidgetPrivate::calcCurrentPage()
-{
- int maxArea = 0;
- int newPage = curPage;
- QRect viewRect = graphicsView->viewport()->rect();
- QList<QGraphicsItem*> items = graphicsView->items(viewRect);
- for (int i=0; i<items.size(); ++i) {
- PageItem* pg = static_cast<PageItem*>(items.at(i));
- QRect overlap = graphicsView->mapFromScene(pg->sceneBoundingRect()).boundingRect() & viewRect;
- int area = overlap.width() * overlap.height();
- if (area > maxArea) {
- maxArea = area;
- newPage = pg->pageNumber();
- } else if (area == maxArea && pg->pageNumber() < newPage) {
- newPage = pg->pageNumber();
- }
- }
- return newPage;
-}
-
-void QPrintPreviewWidgetPrivate::init()
-{
- Q_Q(QPrintPreviewWidget);
-
- graphicsView = new GraphicsView;
- graphicsView->setInteractive(false);
- graphicsView->setDragMode(QGraphicsView::ScrollHandDrag);
- graphicsView->setViewportUpdateMode(QGraphicsView::SmartViewportUpdate);
- QObject::connect(graphicsView->verticalScrollBar(), SIGNAL(valueChanged(int)),
- q, SLOT(_q_updateCurrentPage()));
- QObject::connect(graphicsView, SIGNAL(resized()), q, SLOT(_q_fit()));
-
- scene = new QGraphicsScene(graphicsView);
- scene->setBackgroundBrush(Qt::gray);
- graphicsView->setScene(scene);
-
- QVBoxLayout *layout = new QVBoxLayout;
- q->setLayout(layout);
- layout->setContentsMargins(0, 0, 0, 0);
- layout->addWidget(graphicsView);
-}
-
-void QPrintPreviewWidgetPrivate::populateScene()
-{
- // remove old pages
- for (int i = 0; i < pages.size(); i++)
- scene->removeItem(pages.at(i));
- qDeleteAll(pages);
- pages.clear();
-
- int numPages = pictures.count();
- QSize paperSize = printer->paperRect().size();
- QRect pageRect = printer->pageRect();
-
- for (int i = 0; i < numPages; i++) {
- PageItem* item = new PageItem(i+1, pictures.at(i), paperSize, pageRect);
- scene->addItem(item);
- pages.append(item);
- }
-}
-
-void QPrintPreviewWidgetPrivate::layoutPages()
-{
- int numPages = pages.count();
- if (numPages < 1)
- return;
-
- int numPagePlaces = numPages;
- int cols = 1; // singleMode and default
- if (viewMode == QPrintPreviewWidget::AllPagesView) {
- if (printer->orientation() == QPrinter::Portrait)
- cols = qCeil(qSqrt((float) numPages));
- else
- cols = qFloor(qSqrt((float) numPages));
- cols += cols % 2; // Nicer with an even number of cols
- }
- else if (viewMode == QPrintPreviewWidget::FacingPagesView) {
- cols = 2;
- numPagePlaces += 1;
- }
- int rows = qCeil(qreal(numPagePlaces) / cols);
-
- qreal itemWidth = pages.at(0)->boundingRect().width();
- qreal itemHeight = pages.at(0)->boundingRect().height();
- int pageNum = 1;
- for (int i = 0; i < rows && pageNum <= numPages; i++) {
- for (int j = 0; j < cols && pageNum <= numPages; j++) {
- if (!i && !j && viewMode == QPrintPreviewWidget::FacingPagesView) {
- // Front page doesn't have a facing page
- continue;
- } else {
- pages.at(pageNum-1)->setPos(QPointF(j*itemWidth, i*itemHeight));
- pageNum++;
- }
- }
- }
- scene->setSceneRect(scene->itemsBoundingRect());
-}
-
-void QPrintPreviewWidgetPrivate::generatePreview()
-{
- //### If QPrinter::setPreviewMode() becomes public, handle the
- //### case that we have been constructed with a printer that
- //### _already_ has been preview-painted to, so we should
- //### initially just show the pages it already contains, and not
- //### emit paintRequested() until the user changes some parameter
-
- Q_Q(QPrintPreviewWidget);
- printer->d_func()->setPreviewMode(true);
- emit q->paintRequested(printer);
- printer->d_func()->setPreviewMode(false);
- pictures = printer->d_func()->previewPages();
- populateScene(); // i.e. setPreviewPrintedPictures() e.l.
- layoutPages();
- curPage = qBound(1, curPage, pages.count());
- if (fitting)
- _q_fit();
- emit q->previewChanged();
-}
-
-void QPrintPreviewWidgetPrivate::setCurrentPage(int pageNumber)
-{
- if (pageNumber < 1 || pageNumber > pages.count())
- return;
-
- int lastPage = curPage;
- curPage = pageNumber;
-
- if (lastPage != curPage && lastPage > 0 && lastPage <= pages.count()) {
- if (zoomMode != QPrintPreviewWidget::FitInView) {
- QScrollBar *hsc = graphicsView->horizontalScrollBar();
- QScrollBar *vsc = graphicsView->verticalScrollBar();
- QPointF pt = graphicsView->transform().map(pages.at(curPage-1)->pos());
- vsc->setValue(int(pt.y()) - 10);
- hsc->setValue(int(pt.x()) - 10);
- } else {
- graphicsView->centerOn(pages.at(curPage-1));
- }
- }
-}
-
-void QPrintPreviewWidgetPrivate::zoom(qreal zoom)
-{
- zoomFactor *= zoom;
- graphicsView->scale(zoom, zoom);
-}
-
-void QPrintPreviewWidgetPrivate::setZoomFactor(qreal _zoomFactor)
-{
- Q_Q(QPrintPreviewWidget);
- zoomFactor = _zoomFactor;
- graphicsView->resetTransform();
- int dpi_y = q->logicalDpiY();
- int printer_dpi_y = printer->logicalDpiY();
- graphicsView->scale(zoomFactor*(dpi_y/float(printer_dpi_y)),
- zoomFactor*(dpi_y/float(printer_dpi_y)));
-}
-
-///////////////////////////////////////
-
-/*!
- \class QPrintPreviewWidget
- \since 4.4
-
- \brief The QPrintPreviewWidget class provides a widget for
- previewing page layouts for printer output.
-
- \ingroup printing
-
- QPrintPreviewDialog uses a QPrintPreviewWidget internally, and the
- purpose of QPrintPreviewWidget is to make it possible to embed the
- preview into other widgets. It also makes it possible to build a different
- user interface around it than the default one provided with QPrintPreviewDialog.
-
- Using QPrintPreviewWidget is straightforward:
-
- \list 1
- \o Create the QPrintPreviewWidget
-
- Construct the QPrintPreviewWidget either by passing in an
- existing QPrinter object, or have QPrintPreviewWidget create a
- default constructed QPrinter object for you.
-
- \o Connect the paintRequested() signal to a slot.
-
- When the widget needs to generate a set of preview pages, a
- paintRequested() signal will be emitted from the widget. Connect a
- slot to this signal, and draw onto the QPrinter passed in as a
- signal parameter. Call QPrinter::newPage(), to start a new
- page in the preview.
-
- \endlist
-
- \sa QPrinter, QPrintDialog, QPageSetupDialog, QPrintPreviewDialog
-*/
-
-
-/*!
- \enum QPrintPreviewWidget::ViewMode
-
- This enum is used to describe the view mode of the preview widget.
-
- \value SinglePageView A mode where single pages in the preview
- is viewed.
-
- \value FacingPagesView A mode where the facing pages in the preview
- is viewed.
-
- \value AllPagesView A view mode where all the pages in the preview
- is viewed.
-*/
-
-/*!
- \enum QPrintPreviewWidget::ZoomMode
-
- This enum is used to describe zoom mode of the preview widget.
-
- \value CustomZoom The zoom is set to a custom zoom value.
-
- \value FitToWidth This mode fits the current page to the width of the view.
-
- \value FitInView This mode fits the current page inside the view.
-
-*/
-
-/*!
- Constructs a QPrintPreviewWidget based on \a printer and with \a
- parent as the parent widget. The widget flags \a flags are passed on
- to the QWidget constructor.
-
- \sa QWidget::setWindowFlags()
-*/
-QPrintPreviewWidget::QPrintPreviewWidget(QPrinter *printer, QWidget *parent, Qt::WindowFlags flags)
- : QWidget(*new QPrintPreviewWidgetPrivate, parent, flags)
-{
- Q_D(QPrintPreviewWidget);
- d->printer = printer;
- d->ownPrinter = false;
- d->init();
-}
-
-/*!
- \overload
-
- This will cause QPrintPreviewWidget to create an internal, default
- constructed QPrinter object, which will be used to generate the
- preview.
-*/
-QPrintPreviewWidget::QPrintPreviewWidget(QWidget *parent, Qt::WindowFlags flags)
- : QWidget(*new QPrintPreviewWidgetPrivate, parent, flags)
-{
- Q_D(QPrintPreviewWidget);
- d->printer = new QPrinter;
- d->ownPrinter = true;
- d->init();
-}
-
-
-/*!
- Destroys the QPrintPreviewWidget.
-*/
-QPrintPreviewWidget::~QPrintPreviewWidget()
-{
- Q_D(QPrintPreviewWidget);
- if (d->ownPrinter)
- delete d->printer;
-}
-
-/*!
- Returns the current view mode. The default view mode is SinglePageView.
-*/
-QPrintPreviewWidget::ViewMode QPrintPreviewWidget::viewMode() const
-{
- Q_D(const QPrintPreviewWidget);
- return d->viewMode;
-}
-
-/*!
- Sets the view mode to \a mode. The default view mode is
- SinglePageView.
-*/
-void QPrintPreviewWidget::setViewMode(ViewMode mode)
-{
- Q_D(QPrintPreviewWidget);
- d->viewMode = mode;
- d->layoutPages();
- if (d->viewMode == AllPagesView) {
- d->graphicsView->fitInView(d->scene->itemsBoundingRect(), Qt::KeepAspectRatio);
- d->fitting = false;
- d->zoomMode = QPrintPreviewWidget::CustomZoom;
- d->zoomFactor = d->graphicsView->transform().m11() * (float(d->printer->logicalDpiY()) / logicalDpiY());
- emit previewChanged();
- } else {
- d->fitting = true;
- d->_q_fit();
- }
-}
-
-/*!
- Returns the current orientation of the preview. This value is
- obtained from the QPrinter object associated with the preview.
-*/
-QPrinter::Orientation QPrintPreviewWidget::orientation() const
-{
- Q_D(const QPrintPreviewWidget);
- return d->printer->orientation();
-}
-
-/*!
- Sets the current orientation to \a orientation. This value will be
- set on the QPrinter object associated with the preview.
-*/
-void QPrintPreviewWidget::setOrientation(QPrinter::Orientation orientation)
-{
- Q_D(QPrintPreviewWidget);
- d->printer->setOrientation(orientation);
- d->generatePreview();
-}
-
-/*!
- Prints the preview to the printer associated with the preview.
-*/
-void QPrintPreviewWidget::print()
-{
- Q_D(QPrintPreviewWidget);
- // ### make use of the generated pages
- emit paintRequested(d->printer);
-}
-
-/*!
- Zooms the current view in by \a factor. The default value for \a
- factor is 1.1, which means the view will be scaled up by 10%.
-*/
-void QPrintPreviewWidget::zoomIn(qreal factor)
-{
- Q_D(QPrintPreviewWidget);
- d->fitting = false;
- d->zoomMode = QPrintPreviewWidget::CustomZoom;
- d->zoom(factor);
-}
-
-/*!
- Zooms the current view out by \a factor. The default value for \a
- factor is 1.1, which means the view will be scaled down by 10%.
-*/
-void QPrintPreviewWidget::zoomOut(qreal factor)
-{
- Q_D(QPrintPreviewWidget);
- d->fitting = false;
- d->zoomMode = QPrintPreviewWidget::CustomZoom;
- d->zoom(1/factor);
-}
-
-/*!
- Returns the zoom factor of the view.
-*/
-qreal QPrintPreviewWidget::zoomFactor() const
-{
- Q_D(const QPrintPreviewWidget);
- return d->zoomFactor;
-}
-
-/*!
- Sets the zoom factor of the view to \a factor. For example, a
- value of 1.0 indicates an unscaled view, which is approximately
- the size the view will have on paper. A value of 0.5 will halve
- the size of the view, while a value of 2.0 will double the size of
- the view.
-*/
-void QPrintPreviewWidget::setZoomFactor(qreal factor)
-{
- Q_D(QPrintPreviewWidget);
- d->fitting = false;
- d->zoomMode = QPrintPreviewWidget::CustomZoom;
- d->setZoomFactor(factor);
-}
-
-/*!
- \obsolete
- Returns the number of pages in the preview.
- \sa pageCount()
-*/
-int QPrintPreviewWidget::numPages() const
-{
- Q_D(const QPrintPreviewWidget);
- return d->pages.size();
-}
-
-/*!
- \since 4.6
- Returns the number of pages in the preview.
-*/
-int QPrintPreviewWidget::pageCount() const
-{
- Q_D(const QPrintPreviewWidget);
- return d->pages.size();
-}
-
-/*!
- Returns the currently viewed page in the preview.
-*/
-int QPrintPreviewWidget::currentPage() const
-{
- Q_D(const QPrintPreviewWidget);
- return d->curPage;
-}
-
-/*!
- Sets the current page in the preview. This will cause the view to
- skip to the beginning of \a page.
-*/
-void QPrintPreviewWidget::setCurrentPage(int page)
-{
- Q_D(QPrintPreviewWidget);
- d->setCurrentPage(page);
-}
-
-/*!
- This is a convenience function and is the same as calling \c
- {setZoomMode(QPrintPreviewWidget::FitToWidth)}.
-*/
-void QPrintPreviewWidget::fitToWidth()
-{
- setZoomMode(FitToWidth);
-}
-
-/*!
- This is a convenience function and is the same as calling \c
- {setZoomMode(QPrintPreviewWidget::FitInView)}.
-*/
-void QPrintPreviewWidget::fitInView()
-{
- setZoomMode(FitInView);
-}
-
-/*!
- Sets the zoom mode to \a zoomMode. The default zoom mode is FitInView.
-
- \sa zoomMode(), viewMode(), setViewMode()
-*/
-void QPrintPreviewWidget::setZoomMode(QPrintPreviewWidget::ZoomMode zoomMode)
-{
- Q_D(QPrintPreviewWidget);
- d->zoomMode = zoomMode;
- if (d->zoomMode == FitInView || d->zoomMode == FitToWidth) {
- d->fitting = true;
- d->_q_fit(true);
- } else {
- d->fitting = false;
- }
-}
-
-/*!
- Returns the current zoom mode.
-
- \sa setZoomMode(), viewMode(), setViewMode()
-*/
-QPrintPreviewWidget::ZoomMode QPrintPreviewWidget::zoomMode() const
-{
- Q_D(const QPrintPreviewWidget);
- return d->zoomMode;
-}
-
-/*!
- This is a convenience function and is the same as calling \c
- {setOrientation(QPrinter::Landscape)}.
-*/
-void QPrintPreviewWidget::setLandscapeOrientation()
-{
- setOrientation(QPrinter::Landscape);
-}
-
-/*!
- This is a convenience function and is the same as calling \c
- {setOrientation(QPrinter::Portrait)}.
-*/
-void QPrintPreviewWidget::setPortraitOrientation()
-{
- setOrientation(QPrinter::Portrait);
-}
-
-/*!
- This is a convenience function and is the same as calling \c
- {setViewMode(QPrintPreviewWidget::SinglePageView)}.
-*/
-void QPrintPreviewWidget::setSinglePageViewMode()
-{
- setViewMode(SinglePageView);
-}
-
-/*!
- This is a convenience function and is the same as calling \c
- {setViewMode(QPrintPreviewWidget::FacingPagesView)}.
-*/
-void QPrintPreviewWidget::setFacingPagesViewMode()
-{
- setViewMode(FacingPagesView);
-}
-
-/*!
- This is a convenience function and is the same as calling \c
- {setViewMode(QPrintPreviewWidget::AllPagesView)}.
-*/
-void QPrintPreviewWidget::setAllPagesViewMode()
-{
- setViewMode(AllPagesView);
-}
-
-
-/*!
- This function updates the preview, which causes the
- paintRequested() signal to be emitted.
-*/
-void QPrintPreviewWidget::updatePreview()
-{
- Q_D(QPrintPreviewWidget);
- d->initialized = true;
- d->generatePreview();
- d->graphicsView->updateGeometry();
-}
-
-/*! \reimp
-*/
-void QPrintPreviewWidget::setVisible(bool visible)
-{
- Q_D(QPrintPreviewWidget);
- if (visible && !d->initialized)
- updatePreview();
- QWidget::setVisible(visible);
-}
-
-/*!
- \fn void QPrintPreviewWidget::paintRequested(QPrinter *printer)
-
- This signal is emitted when the preview widget needs to generate a
- set of preview pages. \a printer is the printer associated with
- this preview widget.
-*/
-
-/*!
- \fn void QPrintPreviewWidget::previewChanged()
-
- This signal is emitted whenever the preview widget has changed
- some internal state, such as the orientation.
-*/
-
-
-QT_END_NAMESPACE
-
-#include "moc_qprintpreviewwidget.cpp"
-#include "qprintpreviewwidget.moc"
-
-#endif // QT_NO_PRINTPREVIEWWIDGET
diff --git a/src/gui/widgets/qprintpreviewwidget.h b/src/gui/widgets/qprintpreviewwidget.h
deleted file mode 100644
index aa42ba9f09..0000000000
--- a/src/gui/widgets/qprintpreviewwidget.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPRINTPREVIEWWIDGET_H
-#define QPRINTPREVIEWWIDGET_H
-
-#include <QtGui/qwidget.h>
-#include <QtGui/qprinter.h>
-
-#ifndef QT_NO_PRINTPREVIEWWIDGET
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QPrintPreviewWidgetPrivate;
-
-class Q_GUI_EXPORT QPrintPreviewWidget : public QWidget
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QPrintPreviewWidget)
-public:
-
- enum ViewMode {
- SinglePageView,
- FacingPagesView,
- AllPagesView
- };
-
- enum ZoomMode {
- CustomZoom,
- FitToWidth,
- FitInView
- };
-
- explicit QPrintPreviewWidget(QPrinter *printer, QWidget *parent = 0, Qt::WindowFlags flags = 0);
- explicit QPrintPreviewWidget(QWidget *parent = 0, Qt::WindowFlags flags = 0);
- ~QPrintPreviewWidget();
-
- qreal zoomFactor() const;
- QPrinter::Orientation orientation() const;
- ViewMode viewMode() const;
- ZoomMode zoomMode() const;
- int currentPage() const;
-#ifdef QT_DEPRECATED
- QT_DEPRECATED int numPages() const;
-#endif
- int pageCount() const;
- void setVisible(bool visible);
-
-public Q_SLOTS:
- void print();
-
- void zoomIn(qreal zoom = 1.1);
- void zoomOut(qreal zoom = 1.1);
- void setZoomFactor(qreal zoomFactor);
- void setOrientation(QPrinter::Orientation orientation);
- void setViewMode(ViewMode viewMode);
- void setZoomMode(ZoomMode zoomMode);
- void setCurrentPage(int pageNumber);
-
- void fitToWidth();
- void fitInView();
- void setLandscapeOrientation();
- void setPortraitOrientation();
- void setSinglePageViewMode();
- void setFacingPagesViewMode();
- void setAllPagesViewMode();
-
- void updatePreview();
-
-Q_SIGNALS:
- void paintRequested(QPrinter *printer);
- void previewChanged();
-
-private:
- void *dummy; // ### remove in Qt 5.0
- Q_PRIVATE_SLOT(d_func(), void _q_fit())
- Q_PRIVATE_SLOT(d_func(), void _q_updateCurrentPage())
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QT_NO_PRINTPREVIEWWIDGET
-#endif // QPRINTPREVIEWWIDGET_H
diff --git a/src/gui/widgets/qprogressbar.h b/src/gui/widgets/qprogressbar.h
deleted file mode 100644
index 6547f79ff1..0000000000
--- a/src/gui/widgets/qprogressbar.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPROGRESSBAR_H
-#define QPROGRESSBAR_H
-
-#include <QtGui/qframe.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_PROGRESSBAR
-
-class QProgressBarPrivate;
-class QStyleOptionProgressBar;
-
-class Q_GUI_EXPORT QProgressBar : public QWidget
-{
- Q_OBJECT
- Q_ENUMS(Direction)
- Q_PROPERTY(int minimum READ minimum WRITE setMinimum)
- Q_PROPERTY(int maximum READ maximum WRITE setMaximum)
- Q_PROPERTY(QString text READ text)
- Q_PROPERTY(int value READ value WRITE setValue NOTIFY valueChanged)
- Q_PROPERTY(Qt::Alignment alignment READ alignment WRITE setAlignment)
- Q_PROPERTY(bool textVisible READ isTextVisible WRITE setTextVisible)
- Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation)
- Q_PROPERTY(bool invertedAppearance READ invertedAppearance WRITE setInvertedAppearance)
- Q_PROPERTY(Direction textDirection READ textDirection WRITE setTextDirection)
- Q_PROPERTY(QString format READ format WRITE setFormat)
-
-public:
- enum Direction { TopToBottom, BottomToTop };
-
- explicit QProgressBar(QWidget *parent = 0);
-
- int minimum() const;
- int maximum() const;
-
- int value() const;
-
- virtual QString text() const;
- void setTextVisible(bool visible);
- bool isTextVisible() const;
-
- Qt::Alignment alignment() const;
- void setAlignment(Qt::Alignment alignment);
-
- QSize sizeHint() const;
- QSize minimumSizeHint() const;
-
- Qt::Orientation orientation() const;
-
- void setInvertedAppearance(bool invert);
- bool invertedAppearance(); //### Qt5 make const
- bool invertedAppearance() const { return const_cast<QProgressBar *>(this)->invertedAppearance(); }
- void setTextDirection(QProgressBar::Direction textDirection);
- QProgressBar::Direction textDirection(); //### Qt5 make const
- QProgressBar::Direction textDirection() const { return const_cast<QProgressBar *>(this)->textDirection(); }
-
- void setFormat(const QString &format);
- QString format() const;
-
-public Q_SLOTS:
- void reset();
- void setRange(int minimum, int maximum);
- void setMinimum(int minimum);
- void setMaximum(int maximum);
- void setValue(int value);
- void setOrientation(Qt::Orientation);
-
-Q_SIGNALS:
- void valueChanged(int value);
-
-protected:
- bool event(QEvent *e);
- void paintEvent(QPaintEvent *);
- void initStyleOption(QStyleOptionProgressBar *option) const;
-
-private:
- Q_DECLARE_PRIVATE(QProgressBar)
- Q_DISABLE_COPY(QProgressBar)
-};
-
-#endif // QT_NO_PROGRESSBAR
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QPROGRESSBAR_H
diff --git a/src/gui/widgets/qpushbutton.h b/src/gui/widgets/qpushbutton.h
deleted file mode 100644
index 04673d58a1..0000000000
--- a/src/gui/widgets/qpushbutton.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPUSHBUTTON_H
-#define QPUSHBUTTON_H
-
-#include <QtGui/qabstractbutton.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QPushButtonPrivate;
-class QMenu;
-class QStyleOptionButton;
-
-class Q_GUI_EXPORT QPushButton : public QAbstractButton
-{
- Q_OBJECT
-
- Q_PROPERTY(bool autoDefault READ autoDefault WRITE setAutoDefault)
- Q_PROPERTY(bool default READ isDefault WRITE setDefault)
- Q_PROPERTY(bool flat READ isFlat WRITE setFlat)
-
-public:
- explicit QPushButton(QWidget *parent=0);
- explicit QPushButton(const QString &text, QWidget *parent=0);
- QPushButton(const QIcon& icon, const QString &text, QWidget *parent=0);
- ~QPushButton();
-
- QSize sizeHint() const;
- QSize minimumSizeHint() const;
-
- bool autoDefault() const;
- void setAutoDefault(bool);
- bool isDefault() const;
- void setDefault(bool);
-
-#ifndef QT_NO_MENU
- void setMenu(QMenu* menu);
- QMenu* menu() const;
-#endif
-
- void setFlat(bool);
- bool isFlat() const;
-
-public Q_SLOTS:
-#ifndef QT_NO_MENU
- void showMenu();
-#endif
-
-protected:
- bool event(QEvent *e);
-#ifdef Q_WS_MAC
- bool hitButton(const QPoint &pos) const;
-#endif // Q_WS_MAC
- void paintEvent(QPaintEvent *);
- void keyPressEvent(QKeyEvent *);
- void focusInEvent(QFocusEvent *);
- void focusOutEvent(QFocusEvent *);
- void initStyleOption(QStyleOptionButton *option) const;
- QPushButton(QPushButtonPrivate &dd, QWidget* parent = 0);
-
-public:
-#ifdef QT3_SUPPORT
- QT3_SUPPORT_CONSTRUCTOR QPushButton(QWidget *parent, const char* name);
- QT3_SUPPORT_CONSTRUCTOR QPushButton(const QString &text, QWidget *parent, const char* name);
- QT3_SUPPORT_CONSTRUCTOR QPushButton(const QIcon& icon, const QString &text, QWidget *parent, const char* name);
- inline QT3_SUPPORT void openPopup() { showMenu(); }
- inline QT3_SUPPORT bool isMenuButton() const { return menu() != 0; }
- inline QT3_SUPPORT void setPopup(QMenu* popup) {setMenu(popup); }
- inline QT3_SUPPORT QMenu* popup() const { return menu(); }
-#endif
-
-private:
- Q_DISABLE_COPY(QPushButton)
- Q_DECLARE_PRIVATE(QPushButton)
-#ifndef QT_NO_MENU
- Q_PRIVATE_SLOT(d_func(), void _q_popupPressed())
-#endif
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QPUSHBUTTON_H
diff --git a/src/gui/widgets/qradiobutton.h b/src/gui/widgets/qradiobutton.h
deleted file mode 100644
index 2e29876cf5..0000000000
--- a/src/gui/widgets/qradiobutton.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QRADIOBUTTON_H
-#define QRADIOBUTTON_H
-
-#include <QtGui/qabstractbutton.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QRadioButtonPrivate;
-class QStyleOptionButton;
-
-class Q_GUI_EXPORT QRadioButton : public QAbstractButton
-{
- Q_OBJECT
-
-public:
- explicit QRadioButton(QWidget *parent=0);
- explicit QRadioButton(const QString &text, QWidget *parent=0);
-
- QSize sizeHint() const;
- QSize minimumSizeHint() const;
-
-protected:
- bool event(QEvent *e);
- bool hitButton(const QPoint &) const;
- void paintEvent(QPaintEvent *);
- void mouseMoveEvent(QMouseEvent *);
- void initStyleOption(QStyleOptionButton *button) const;
-
-#ifdef QT3_SUPPORT
-public:
- QT3_SUPPORT_CONSTRUCTOR QRadioButton(QWidget *parent, const char* name);
- QT3_SUPPORT_CONSTRUCTOR QRadioButton(const QString &text, QWidget *parent, const char* name);
-#endif
-
-private:
- Q_DECLARE_PRIVATE(QRadioButton)
- Q_DISABLE_COPY(QRadioButton)
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QRADIOBUTTON_H
diff --git a/src/gui/widgets/qrubberband.h b/src/gui/widgets/qrubberband.h
deleted file mode 100644
index 7b94996d41..0000000000
--- a/src/gui/widgets/qrubberband.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QRUBBERBAND_H
-#define QRUBBERBAND_H
-
-#include <QtGui/qwidget.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_RUBBERBAND
-
-class QRubberBandPrivate;
-class QStyleOptionRubberBand;
-
-class Q_GUI_EXPORT QRubberBand : public QWidget
-{
- Q_OBJECT
-
-public:
- enum Shape { Line, Rectangle };
- explicit QRubberBand(Shape, QWidget * =0);
- ~QRubberBand();
-
- Shape shape() const;
-
- void setGeometry(const QRect &r);
-
- inline void setGeometry(int x, int y, int w, int h);
- inline void move(int x, int y);
- inline void move(const QPoint &p)
- { move(p.x(), p.y()); }
- inline void resize(int w, int h)
- { setGeometry(geometry().x(), geometry().y(), w, h); }
- inline void resize(const QSize &s)
- { resize(s.width(), s.height()); }
-
-protected:
- bool event(QEvent *e);
- void paintEvent(QPaintEvent *);
- void changeEvent(QEvent *);
- void showEvent(QShowEvent *);
- void resizeEvent(QResizeEvent *);
- void moveEvent(QMoveEvent *);
- void initStyleOption(QStyleOptionRubberBand *option) const;
-
-private:
- Q_DECLARE_PRIVATE(QRubberBand)
-};
-
-inline void QRubberBand::setGeometry(int ax, int ay, int aw, int ah)
-{ setGeometry(QRect(ax, ay, aw, ah)); }
-inline void QRubberBand::move(int ax, int ay)
-{ setGeometry(ax, ay, width(), height()); }
-
-#endif // QT_NO_RUBBERBAND
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QRUBBERBAND_H
diff --git a/src/gui/widgets/qscrollarea.cpp b/src/gui/widgets/qscrollarea.cpp
deleted file mode 100644
index 314f4fe9d2..0000000000
--- a/src/gui/widgets/qscrollarea.cpp
+++ /dev/null
@@ -1,522 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qscrollarea.h"
-#include "private/qscrollarea_p.h"
-
-#ifndef QT_NO_SCROLLAREA
-
-#include "qscrollbar.h"
-#include "qlayout.h"
-#include "qstyle.h"
-#include "qapplication.h"
-#include "qvariant.h"
-#include "qdebug.h"
-#include "private/qlayoutengine_p.h"
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \class QScrollArea
-
- \brief The QScrollArea class provides a scrolling view onto
- another widget.
-
- \ingroup basicwidgets
-
-
- A scroll area is used to display the contents of a child widget
- within a frame. If the widget exceeds the size of the frame, the
- view can provide scroll bars so that the entire area of the child
- widget can be viewed. The child widget must be specified with
- setWidget(). For example:
-
- \snippet doc/src/snippets/code/src_gui_widgets_qscrollarea.cpp 0
-
- The code above creates a scroll area (shown in the images below)
- containing an image label. When scaling the image, the scroll area
- can provide the necessary scroll bars:
-
- \table
- \row
- \o \inlineimage qscrollarea-noscrollbars.png
- \o \inlineimage qscrollarea-onescrollbar.png
- \o \inlineimage qscrollarea-twoscrollbars.png
- \endtable
-
- The scroll bars appearance depends on the currently set \l
- {Qt::ScrollBarPolicy}{scroll bar policies}. You can control the
- appearance of the scroll bars using the inherited functionality
- from QAbstractScrollArea.
-
- For example, you can set the
- QAbstractScrollArea::horizontalScrollBarPolicy and
- QAbstractScrollArea::verticalScrollBarPolicy properties. Or if you
- want the scroll bars to adjust dynamically when the contents of
- the scroll area changes, you can use the \l
- {QAbstractScrollArea::horizontalScrollBar()}{horizontalScrollBar()}
- and \l
- {QAbstractScrollArea::verticalScrollBar()}{verticalScrollBar()}
- functions (which enable you to access the scroll bars) and set the
- scroll bars' values whenever the scroll area's contents change,
- using the QScrollBar::setValue() function.
-
- You can retrieve the child widget using the widget() function. The
- view can be made to be resizable with the setWidgetResizable()
- function. The alignment of the widget can be specified with
- setAlignment().
-
- Two convenience functions ensureVisible() and
- ensureWidgetVisible() ensure a certain region of the contents is
- visible inside the viewport, by scrolling the contents if
- necessary.
-
- \section1 Size Hints and Layouts
-
- When using a scroll area to display the contents of a custom
- widget, it is important to ensure that the
- \l{QWidget::sizeHint}{size hint} of the child widget is set to a
- suitable value. If a standard QWidget is used for the child
- widget, it may be necessary to call QWidget::setMinimumSize() to
- ensure that the contents of the widget are shown correctly within
- the scroll area.
-
- If a scroll area is used to display the contents of a widget that
- contains child widgets arranged in a layout, it is important to
- realize that the size policy of the layout will also determine the
- size of the widget. This is especially useful to know if you intend
- to dynamically change the contents of the layout. In such cases,
- setting the layout's \l{QLayout::sizeConstraint}{size constraint}
- property to one which provides constraints on the minimum and/or
- maximum size of the layout (e.g., QLayout::SetMinAndMaxSize) will
- cause the size of the scroll area to be updated whenever the
- contents of the layout changes.
-
- For a complete example using the QScrollArea class, see the \l
- {widgets/imageviewer}{Image Viewer} example. The example shows how
- to combine QLabel and QScrollArea to display an image.
-
- \sa QAbstractScrollArea, QScrollBar, {Image Viewer Example}
-*/
-
-
-/*!
- Constructs an empty scroll area with the given \a parent.
-
- \sa setWidget()
-*/
-QScrollArea::QScrollArea(QWidget *parent)
- : QAbstractScrollArea(*new QScrollAreaPrivate,parent)
-{
- Q_D(QScrollArea);
- d->viewport->setBackgroundRole(QPalette::NoRole);
- d->vbar->setSingleStep(20);
- d->hbar->setSingleStep(20);
- d->layoutChildren();
-}
-
-/*!
- \internal
-*/
-QScrollArea::QScrollArea(QScrollAreaPrivate &dd, QWidget *parent)
- : QAbstractScrollArea(dd, parent)
-{
- Q_D(QScrollArea);
- d->viewport->setBackgroundRole(QPalette::NoRole);
- d->vbar->setSingleStep(20);
- d->hbar->setSingleStep(20);
- d->layoutChildren();
-}
-
-/*!
- Destroys the scroll area and its child widget.
-
- \sa setWidget()
-*/
-QScrollArea::~QScrollArea()
-{
-}
-
-void QScrollAreaPrivate::updateWidgetPosition()
-{
- Q_Q(QScrollArea);
- Qt::LayoutDirection dir = q->layoutDirection();
- QRect scrolled = QStyle::visualRect(dir, viewport->rect(), QRect(QPoint(-hbar->value(), -vbar->value()), widget->size()));
- QRect aligned = QStyle::alignedRect(dir, alignment, widget->size(), viewport->rect());
- widget->move(widget->width() < viewport->width() ? aligned.x() : scrolled.x(),
- widget->height() < viewport->height() ? aligned.y() : scrolled.y());
-}
-
-void QScrollAreaPrivate::updateScrollBars()
-{
- Q_Q(QScrollArea);
- if (!widget)
- return;
- QSize p = viewport->size();
- QSize m = q->maximumViewportSize();
-
- QSize min = qSmartMinSize(widget);
- QSize max = qSmartMaxSize(widget);
-
- if (resizable) {
- if ((widget->layout() ? widget->layout()->hasHeightForWidth() : widget->sizePolicy().hasHeightForWidth())) {
- QSize p_hfw = p.expandedTo(min).boundedTo(max);
- int h = widget->heightForWidth( p_hfw.width() );
- min = QSize(p_hfw.width(), qMax(p_hfw.height(), h));
- }
- }
-
- if ((resizable && m.expandedTo(min) == m && m.boundedTo(max) == m)
- || (!resizable && m.expandedTo(widget->size()) == m))
- p = m; // no scroll bars needed
-
- if (resizable)
- widget->resize(p.expandedTo(min).boundedTo(max));
- QSize v = widget->size();
-
- hbar->setRange(0, v.width() - p.width());
- hbar->setPageStep(p.width());
- vbar->setRange(0, v.height() - p.height());
- vbar->setPageStep(p.height());
- updateWidgetPosition();
-
-}
-
-/*!
- Returns the scroll area's widget, or 0 if there is none.
-
- \sa setWidget()
-*/
-
-QWidget *QScrollArea::widget() const
-{
- Q_D(const QScrollArea);
- return d->widget;
-}
-
-/*!
- \fn void QScrollArea::setWidget(QWidget *widget)
-
- Sets the scroll area's \a widget.
-
- The \a widget becomes a child of the scroll area, and will be
- destroyed when the scroll area is deleted or when a new widget is
- set.
-
- The widget's \l{QWidget::setAutoFillBackground()}{autoFillBackground}
- property will be set to \c{true}.
-
- If the scroll area is visible when the \a widget is
- added, you must \l{QWidget::}{show()} it explicitly.
-
- Note that You must add the layout of \a widget before you call
- this function; if you add it later, the \a widget will not be
- visible - regardless of when you \l{QWidget::}{show()} the scroll
- area. In this case, you can also not \l{QWidget::}{show()} the \a
- widget later.
-
- \sa widget()
-*/
-void QScrollArea::setWidget(QWidget *widget)
-{
- Q_D(QScrollArea);
- if (widget == d->widget || !widget)
- return;
-
- delete d->widget;
- d->widget = 0;
- d->hbar->setValue(0);
- d->vbar->setValue(0);
- if (widget->parentWidget() != d->viewport)
- widget->setParent(d->viewport);
- if (!widget->testAttribute(Qt::WA_Resized))
- widget->resize(widget->sizeHint());
- d->widget = widget;
- d->widget->setAutoFillBackground(true);
- widget->installEventFilter(this);
- d->widgetSize = QSize();
- d->updateScrollBars();
- d->widget->show();
-
-}
-
-/*!
- Removes the scroll area's widget, and passes ownership of the
- widget to the caller.
-
- \sa widget()
- */
-QWidget *QScrollArea::takeWidget()
-{
- Q_D(QScrollArea);
- QWidget *w = d->widget;
- d->widget = 0;
- if (w)
- w->setParent(0);
- return w;
-}
-
-/*!
- \reimp
- */
-bool QScrollArea::event(QEvent *e)
-{
- Q_D(QScrollArea);
- if (e->type() == QEvent::StyleChange || e->type() == QEvent::LayoutRequest) {
- d->updateScrollBars();
- }
-#ifdef QT_KEYPAD_NAVIGATION
- else if (QApplication::keypadNavigationEnabled()) {
- if (e->type() == QEvent::Show)
- QApplication::instance()->installEventFilter(this);
- else if (e->type() == QEvent::Hide)
- QApplication::instance()->removeEventFilter(this);
- }
-#endif
- return QAbstractScrollArea::event(e);
-}
-
-
-/*!
- \reimp
- */
-bool QScrollArea::eventFilter(QObject *o, QEvent *e)
-{
- Q_D(QScrollArea);
-#ifdef QT_KEYPAD_NAVIGATION
- if (d->widget && o != d->widget && e->type() == QEvent::FocusIn
- && QApplication::keypadNavigationEnabled()) {
- if (o->isWidgetType())
- ensureWidgetVisible(static_cast<QWidget *>(o));
- }
-#endif
- if (o == d->widget && e->type() == QEvent::Resize)
- d->updateScrollBars();
-
- return false;
-}
-
-/*!
- \reimp
- */
-void QScrollArea::resizeEvent(QResizeEvent *)
-{
- Q_D(QScrollArea);
- d->updateScrollBars();
-
-}
-
-
-/*!\reimp
- */
-void QScrollArea::scrollContentsBy(int, int)
-{
- Q_D(QScrollArea);
- if (!d->widget)
- return;
- d->updateWidgetPosition();
-}
-
-
-/*!
- \property QScrollArea::widgetResizable
- \brief whether the scroll area should resize the view widget
-
- If this property is set to false (the default), the scroll area
- honors the size of its widget. Regardless of this property, you
- can programmatically resize the widget using widget()->resize(),
- and the scroll area will automatically adjust itself to the new
- size.
-
- If this property is set to true, the scroll area will
- automatically resize the widget in order to avoid scroll bars
- where they can be avoided, or to take advantage of extra space.
-*/
-bool QScrollArea::widgetResizable() const
-{
- Q_D(const QScrollArea);
- return d->resizable;
-}
-
-void QScrollArea::setWidgetResizable(bool resizable)
-{
- Q_D(QScrollArea);
- d->resizable = resizable;
- updateGeometry();
- d->updateScrollBars();
-}
-
-/*!
- \reimp
- */
-QSize QScrollArea::sizeHint() const
-{
- Q_D(const QScrollArea);
- int f = 2 * d->frameWidth;
- QSize sz(f, f);
- int h = fontMetrics().height();
- if (d->widget) {
- if (!d->widgetSize.isValid())
- d->widgetSize = d->resizable ? d->widget->sizeHint() : d->widget->size();
- sz += d->widgetSize;
- } else {
- sz += QSize(12 * h, 8 * h);
- }
- if (d->vbarpolicy == Qt::ScrollBarAlwaysOn)
- sz.setWidth(sz.width() + d->vbar->sizeHint().width());
- if (d->hbarpolicy == Qt::ScrollBarAlwaysOn)
- sz.setHeight(sz.height() + d->hbar->sizeHint().height());
- return sz.boundedTo(QSize(36 * h, 24 * h));
-}
-
-
-
-/*!
- \reimp
- */
-bool QScrollArea::focusNextPrevChild(bool next)
-{
- if (QWidget::focusNextPrevChild(next)) {
- if (QWidget *fw = focusWidget())
- ensureWidgetVisible(fw);
- return true;
- }
- return false;
-}
-
-/*!
- Scrolls the contents of the scroll area so that the point (\a x, \a y) is visible
- inside the region of the viewport with margins specified in pixels by \a xmargin and
- \a ymargin. If the specified point cannot be reached, the contents are scrolled to
- the nearest valid position. The default value for both margins is 50 pixels.
-*/
-void QScrollArea::ensureVisible(int x, int y, int xmargin, int ymargin)
-{
- Q_D(QScrollArea);
-
- int logicalX = QStyle::visualPos(layoutDirection(), d->viewport->rect(), QPoint(x, y)).x();
-
- if (logicalX - xmargin < d->hbar->value()) {
- d->hbar->setValue(qMax(0, logicalX - xmargin));
- } else if (logicalX > d->hbar->value() + d->viewport->width() - xmargin) {
- d->hbar->setValue(qMin(logicalX - d->viewport->width() + xmargin, d->hbar->maximum()));
- }
-
- if (y - ymargin < d->vbar->value()) {
- d->vbar->setValue(qMax(0, y - ymargin));
- } else if (y > d->vbar->value() + d->viewport->height() - ymargin) {
- d->vbar->setValue(qMin(y - d->viewport->height() + ymargin, d->vbar->maximum()));
- }
-}
-
-/*!
- \since 4.2
-
- Scrolls the contents of the scroll area so that the \a childWidget
- of QScrollArea::widget() is visible inside the viewport with
- margins specified in pixels by \a xmargin and \a ymargin. If the
- specified point cannot be reached, the contents are scrolled to
- the nearest valid position. The default value for both margins is
- 50 pixels.
-
-*/
-void QScrollArea::ensureWidgetVisible(QWidget *childWidget, int xmargin, int ymargin)
-{
- Q_D(QScrollArea);
-
- if (!d->widget->isAncestorOf(childWidget))
- return;
-
- const QRect microFocus = childWidget->inputMethodQuery(Qt::ImMicroFocus).toRect();
- const QRect defaultMicroFocus =
- childWidget->QWidget::inputMethodQuery(Qt::ImMicroFocus).toRect();
- QRect focusRect = (microFocus != defaultMicroFocus)
- ? QRect(childWidget->mapTo(d->widget, microFocus.topLeft()), microFocus.size())
- : QRect(childWidget->mapTo(d->widget, QPoint(0,0)), childWidget->size());
- const QRect visibleRect(-d->widget->pos(), d->viewport->size());
-
- if (visibleRect.contains(focusRect))
- return;
-
- focusRect.adjust(-xmargin, -ymargin, xmargin, ymargin);
-
- if (focusRect.width() > visibleRect.width())
- d->hbar->setValue(focusRect.center().x() - d->viewport->width() / 2);
- else if (focusRect.right() > visibleRect.right())
- d->hbar->setValue(focusRect.right() - d->viewport->width());
- else if (focusRect.left() < visibleRect.left())
- d->hbar->setValue(focusRect.left());
-
- if (focusRect.height() > visibleRect.height())
- d->vbar->setValue(focusRect.center().y() - d->viewport->height() / 2);
- else if (focusRect.bottom() > visibleRect.bottom())
- d->vbar->setValue(focusRect.bottom() - d->viewport->height());
- else if (focusRect.top() < visibleRect.top())
- d->vbar->setValue(focusRect.top());
-}
-
-
-/*!
- \property QScrollArea::alignment
- \brief the alignment of the scroll area's widget
- \since 4.2
-
- By default, the widget stays rooted to the top-left corner of the
- scroll area.
-*/
-
-void QScrollArea::setAlignment(Qt::Alignment alignment)
-{
- Q_D(QScrollArea);
- d->alignment = alignment;
- if (d->widget)
- d->updateWidgetPosition();
-}
-
-Qt::Alignment QScrollArea::alignment() const
-{
- Q_D(const QScrollArea);
- return d->alignment;
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_SCROLLAREA
diff --git a/src/gui/widgets/qscrollarea.h b/src/gui/widgets/qscrollarea.h
deleted file mode 100644
index 4f824d8438..0000000000
--- a/src/gui/widgets/qscrollarea.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSCROLLAREA_H
-#define QSCROLLAREA_H
-
-#include <QtGui/qabstractscrollarea.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_SCROLLAREA
-
-class QScrollAreaPrivate;
-
-class Q_GUI_EXPORT QScrollArea : public QAbstractScrollArea
-{
- Q_OBJECT
- Q_PROPERTY(bool widgetResizable READ widgetResizable WRITE setWidgetResizable)
- Q_PROPERTY(Qt::Alignment alignment READ alignment WRITE setAlignment)
-
-public:
- explicit QScrollArea(QWidget* parent=0);
- ~QScrollArea();
-
- QWidget *widget() const;
- void setWidget(QWidget *widget);
- QWidget *takeWidget();
-
- bool widgetResizable() const;
- void setWidgetResizable(bool resizable);
-
- QSize sizeHint() const;
- bool focusNextPrevChild(bool next);
-
- Qt::Alignment alignment() const;
- void setAlignment(Qt::Alignment);
-
- void ensureVisible(int x, int y, int xmargin = 50, int ymargin = 50);
- void ensureWidgetVisible(QWidget *childWidget, int xmargin = 50, int ymargin = 50);
-
-protected:
- QScrollArea(QScrollAreaPrivate &dd, QWidget *parent = 0);
- bool event(QEvent *);
- bool eventFilter(QObject *, QEvent *);
- void resizeEvent(QResizeEvent *);
- void scrollContentsBy(int dx, int dy);
-
-private:
- Q_DECLARE_PRIVATE(QScrollArea)
- Q_DISABLE_COPY(QScrollArea)
-};
-
-#endif // QT_NO_SCROLLAREA
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QSCROLLAREA_H
diff --git a/src/gui/widgets/qscrollarea_p.h b/src/gui/widgets/qscrollarea_p.h
deleted file mode 100644
index a7eab6cdfa..0000000000
--- a/src/gui/widgets/qscrollarea_p.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSCROLLAREA_P_H
-#define QSCROLLAREA_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#ifndef QT_NO_SCROLLAREA
-
-#include "private/qabstractscrollarea_p.h"
-#include <QtGui/qscrollbar.h>
-
-QT_BEGIN_NAMESPACE
-
-class QScrollAreaPrivate: public QAbstractScrollAreaPrivate
-{
- Q_DECLARE_PUBLIC(QScrollArea)
-
-public:
- QScrollAreaPrivate(): resizable(false), alignment(0){}
- void updateScrollBars();
- void updateWidgetPosition();
- QPointer<QWidget> widget;
- mutable QSize widgetSize;
- bool resizable;
- Qt::Alignment alignment;
-};
-
-#endif
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/gui/widgets/qscrollbar.cpp b/src/gui/widgets/qscrollbar.cpp
deleted file mode 100644
index 72f461fe63..0000000000
--- a/src/gui/widgets/qscrollbar.cpp
+++ /dev/null
@@ -1,764 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qapplication.h"
-#include "qcursor.h"
-#include "qevent.h"
-#include "qpainter.h"
-#include "qscrollbar.h"
-#include "qstyle.h"
-#include "qstyleoption.h"
-#include "qmenu.h"
-#include <QtCore/qelapsedtimer.h>
-
-#ifndef QT_NO_SCROLLBAR
-
-#ifndef QT_NO_ACCESSIBILITY
-#include "qaccessible.h"
-#endif
-#include <limits.h>
-#include "qabstractslider_p.h"
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \class QScrollBar
- \brief The QScrollBar widget provides a vertical or horizontal scroll bar.
-
- \ingroup basicwidgets
-
- A scroll bar is a control that enables the user to access parts of a
- document that is larger than the widget used to display it. It provides
- a visual indication of the user's current position within the document
- and the amount of the document that is visible. Scroll bars are usually
- equipped with other controls that enable more accurate navigation.
- Qt displays scroll bars in a way that is appropriate for each platform.
-
- If you need to provide a scrolling view onto another widget, it may be
- more convenient to use the QScrollArea class because this provides a
- viewport widget and scroll bars. QScrollBar is useful if you need to
- implement similar functionality for specialized widgets using QAbstractScrollArea;
- for example, if you decide to subclass QAbstractItemView.
- For most other situations where a slider control is used to obtain a value
- within a given range, the QSlider class may be more appropriate for your
- needs.
-
- \table
- \row \o \image qscrollbar-picture.png
- \o Scroll bars typically include four separate controls: a slider,
- scroll arrows, and a page control.
-
- \list
- \o a. The slider provides a way to quickly go to any part of the
- document, but does not support accurate navigation within large
- documents.
- \o b. The scroll arrows are push buttons which can be used to accurately
- navigate to a particular place in a document. For a vertical scroll bar
- connected to a text editor, these typically move the current position one
- "line" up or down, and adjust the position of the slider by a small
- amount. In editors and list boxes a "line" might mean one line of text;
- in an image viewer it might mean 20 pixels.
- \o c. The page control is the area over which the slider is dragged (the
- scroll bar's background). Clicking here moves the scroll bar towards
- the click by one "page". This value is usually the same as the length of
- the slider.
- \endlist
- \endtable
-
- Each scroll bar has a value that indicates how far the slider is from
- the start of the scroll bar; this is obtained with value() and set
- with setValue(). This value always lies within the range of values
- defined for the scroll bar, from \l{QAbstractSlider::minimum()}{minimum()}
- to \l{QAbstractSlider::minimum()}{maximum()} inclusive. The range of
- acceptable values can be set with setMinimum() and setMaximum().
- At the minimum value, the top edge of the slider (for a vertical scroll
- bar) or left edge (for a horizontal scroll bar) will be at the top (or
- left) end of the scroll bar. At the maximum value, the bottom (or right)
- edge of the slider will be at the bottom (or right) end of the scroll bar.
-
- The length of the slider is usually related to the value of the page step,
- and typically represents the proportion of the document area shown in a
- scrolling view. The page step is the amount that the value changes by
- when the user presses the \key{Page Up} and \key{Page Down} keys, and is
- set with setPageStep(). Smaller changes to the value defined by the
- line step are made using the cursor keys, and this quantity is set with
- \l{QAbstractSlider::}{setSingleStep()}.
-
- Note that the range of values used is independent of the actual size
- of the scroll bar widget. You do not need to take this into account when
- you choose values for the range and the page step.
-
- The range of values specified for the scroll bar are often determined
- differently to those for a QSlider because the length of the slider
- needs to be taken into account. If we have a document with 100 lines,
- and we can only show 20 lines in a widget, we may wish to construct a
- scroll bar with a page step of 20, a minimum value of 0, and a maximum
- value of 80. This would give us a scroll bar with five "pages".
-
- \table
- \row \o \inlineimage qscrollbar-values.png
- \o The relationship between a document length, the range of values used
- in a scroll bar, and the page step is simple in many common situations.
- The scroll bar's range of values is determined by subtracting a
- chosen page step from some value representing the length of the document.
- In such cases, the following equation is useful:
- \e{document length} = maximum() - minimum() + pageStep().
- \endtable
-
- QScrollBar only provides integer ranges. Note that although
- QScrollBar handles very large numbers, scroll bars on current
- screens cannot usefully represent ranges above about 100,000 pixels.
- Beyond that, it becomes difficult for the user to control the
- slider using either the keyboard or the mouse, and the scroll
- arrows will have limited use.
-
- ScrollBar inherits a comprehensive set of signals from QAbstractSlider:
- \list
- \o \l{QAbstractSlider::valueChanged()}{valueChanged()} is emitted when the
- scroll bar's value has changed. The tracking() determines whether this
- signal is emitted during user interaction.
- \o \l{QAbstractSlider::rangeChanged()}{rangeChanged()} is emitted when the
- scroll bar's range of values has changed.
- \o \l{QAbstractSlider::sliderPressed()}{sliderPressed()} is emitted when
- the user starts to drag the slider.
- \o \l{QAbstractSlider::sliderMoved()}{sliderMoved()} is emitted when the user
- drags the slider.
- \o \l{QAbstractSlider::sliderReleased()}{sliderReleased()} is emitted when
- the user releases the slider.
- \o \l{QAbstractSlider::actionTriggered()}{actionTriggered()} is emitted
- when the scroll bar is changed by user interaction or via the
- \l{QAbstractSlider::triggerAction()}{triggerAction()} function.
- \endlist
-
- A scroll bar can be controlled by the keyboard, but it has a
- default focusPolicy() of Qt::NoFocus. Use setFocusPolicy() to
- enable keyboard interaction with the scroll bar:
- \list
- \o Left/Right move a horizontal scroll bar by one single step.
- \o Up/Down move a vertical scroll bar by one single step.
- \o PageUp moves up one page.
- \o PageDown moves down one page.
- \o Home moves to the start (mininum).
- \o End moves to the end (maximum).
- \endlist
-
- The slider itself can be controlled by using the
- \l{QAbstractSlider::triggerAction()}{triggerAction()} function to simulate
- user interaction with the scroll bar controls. This is useful if you have
- many different widgets that use a common range of values.
-
- Most GUI styles use the pageStep() value to calculate the size of the
- slider.
-
- \table 100%
- \row \o \inlineimage macintosh-horizontalscrollbar.png Screenshot of a Macintosh style scroll bar
- \o A scroll bar shown in the \l{Macintosh Style Widget Gallery}{Macintosh widget style}.
- \row \o \inlineimage windowsxp-horizontalscrollbar.png Screenshot of a Windows XP style scroll bar
- \o A scroll bar shown in the \l{Windows XP Style Widget Gallery}{Windows XP widget style}.
- \row \o \inlineimage plastique-horizontalscrollbar.png Screenshot of a Plastique style scroll bar
- \o A scroll bar shown in the \l{Plastique Style Widget Gallery}{Plastique widget style}.
- \endtable
-
- \sa QScrollArea, QSlider, QDial, QSpinBox, {fowler}{GUI Design Handbook: Scroll Bar}, {Sliders Example}
-*/
-
-class QScrollBarPrivate : public QAbstractSliderPrivate
-{
- Q_DECLARE_PUBLIC(QScrollBar)
-public:
- QStyle::SubControl pressedControl;
- bool pointerOutsidePressedControl;
-
- int clickOffset, snapBackPosition;
-
- void activateControl(uint control, int threshold = 500);
- void stopRepeatAction();
- int pixelPosToRangeValue(int pos) const;
- void init();
- bool updateHoverControl(const QPoint &pos);
- QStyle::SubControl newHoverControl(const QPoint &pos);
-
- QStyle::SubControl hoverControl;
- QRect hoverRect;
-};
-
-bool QScrollBarPrivate::updateHoverControl(const QPoint &pos)
-{
- Q_Q(QScrollBar);
- QRect lastHoverRect = hoverRect;
- QStyle::SubControl lastHoverControl = hoverControl;
- bool doesHover = q->testAttribute(Qt::WA_Hover);
- if (lastHoverControl != newHoverControl(pos) && doesHover) {
- q->update(lastHoverRect);
- q->update(hoverRect);
- return true;
- }
- return !doesHover;
-}
-
-QStyle::SubControl QScrollBarPrivate::newHoverControl(const QPoint &pos)
-{
- Q_Q(QScrollBar);
- QStyleOptionSlider opt;
- q->initStyleOption(&opt);
- opt.subControls = QStyle::SC_All;
- hoverControl = q->style()->hitTestComplexControl(QStyle::CC_ScrollBar, &opt, pos, q);
- if (hoverControl == QStyle::SC_None)
- hoverRect = QRect();
- else
- hoverRect = q->style()->subControlRect(QStyle::CC_ScrollBar, &opt, hoverControl, q);
- return hoverControl;
-}
-
-void QScrollBarPrivate::activateControl(uint control, int threshold)
-{
- QAbstractSlider::SliderAction action = QAbstractSlider::SliderNoAction;
- switch (control) {
- case QStyle::SC_ScrollBarAddPage:
- action = QAbstractSlider::SliderPageStepAdd;
- break;
- case QStyle::SC_ScrollBarSubPage:
- action = QAbstractSlider::SliderPageStepSub;
- break;
- case QStyle::SC_ScrollBarAddLine:
- action = QAbstractSlider::SliderSingleStepAdd;
- break;
- case QStyle::SC_ScrollBarSubLine:
- action = QAbstractSlider::SliderSingleStepSub;
- break;
- case QStyle::SC_ScrollBarFirst:
- action = QAbstractSlider::SliderToMinimum;
- break;
- case QStyle::SC_ScrollBarLast:
- action = QAbstractSlider::SliderToMaximum;
- break;
- default:
- break;
- }
-
- if (action) {
- q_func()->setRepeatAction(action, threshold);
- q_func()->triggerAction(action);
- }
-}
-
-void QScrollBarPrivate::stopRepeatAction()
-{
- Q_Q(QScrollBar);
- QStyle::SubControl tmp = pressedControl;
- q->setRepeatAction(QAbstractSlider::SliderNoAction);
- pressedControl = QStyle::SC_None;
-
- if (tmp == QStyle::SC_ScrollBarSlider)
- q->setSliderDown(false);
-
- QStyleOptionSlider opt;
- q->initStyleOption(&opt);
- q->repaint(q->style()->subControlRect(QStyle::CC_ScrollBar, &opt, tmp, q));
-}
-
-/*!
- Initialize \a option with the values from this QScrollBar. This method
- is useful for subclasses when they need a QStyleOptionSlider, but don't want
- to fill in all the information themselves.
-
- \sa QStyleOption::initFrom()
-*/
-void QScrollBar::initStyleOption(QStyleOptionSlider *option) const
-{
- if (!option)
- return;
-
- Q_D(const QScrollBar);
- option->initFrom(this);
- option->subControls = QStyle::SC_None;
- option->activeSubControls = QStyle::SC_None;
- option->orientation = d->orientation;
- option->minimum = d->minimum;
- option->maximum = d->maximum;
- option->sliderPosition = d->position;
- option->sliderValue = d->value;
- option->singleStep = d->singleStep;
- option->pageStep = d->pageStep;
- option->upsideDown = d->invertedAppearance;
- if (d->orientation == Qt::Horizontal)
- option->state |= QStyle::State_Horizontal;
-}
-
-
-#define HORIZONTAL (d_func()->orientation == Qt::Horizontal)
-#define VERTICAL !HORIZONTAL
-
-/*!
- Constructs a vertical scroll bar.
-
- The \a parent argument is sent to the QWidget constructor.
-
- The \l {QAbstractSlider::minimum} {minimum} defaults to 0, the
- \l {QAbstractSlider::maximum} {maximum} to 99, with a
- \l {QAbstractSlider::singleStep} {singleStep} size of 1 and a
- \l {QAbstractSlider::pageStep} {pageStep} size of 10, and an
- initial \l {QAbstractSlider::value} {value} of 0.
-*/
-QScrollBar::QScrollBar(QWidget *parent)
- : QAbstractSlider(*new QScrollBarPrivate, parent)
-{
- d_func()->orientation = Qt::Vertical;
- d_func()->init();
-}
-
-/*!
- Constructs a scroll bar with the given \a orientation.
-
- The \a parent argument is passed to the QWidget constructor.
-
- The \l {QAbstractSlider::minimum} {minimum} defaults to 0, the
- \l {QAbstractSlider::maximum} {maximum} to 99, with a
- \l {QAbstractSlider::singleStep} {singleStep} size of 1 and a
- \l {QAbstractSlider::pageStep} {pageStep} size of 10, and an
- initial \l {QAbstractSlider::value} {value} of 0.
-*/
-QScrollBar::QScrollBar(Qt::Orientation orientation, QWidget *parent)
- : QAbstractSlider(*new QScrollBarPrivate, parent)
-{
- d_func()->orientation = orientation;
- d_func()->init();
-}
-
-
-#ifdef QT3_SUPPORT
-/*!
- Use one of the constructors that doesn't take the \a name
- argument and then use setObjectName() instead.
-*/
-QScrollBar::QScrollBar(QWidget *parent, const char *name)
- : QAbstractSlider(*new QScrollBarPrivate, parent)
-{
- setObjectName(QString::fromAscii(name));
- d_func()->orientation = Qt::Vertical;
- d_func()->init();
-}
-
-/*!
- Use one of the constructors that doesn't take the \a name
- argument and then use setObjectName() instead.
-*/
-QScrollBar::QScrollBar(Qt::Orientation orientation, QWidget *parent, const char *name)
- : QAbstractSlider(*new QScrollBarPrivate, parent)
-{
- setObjectName(QString::fromAscii(name));
- d_func()->orientation = orientation;
- d_func()->init();
-}
-
-/*!
- Use one of the constructors that doesn't take the \a name
- argument and then use setObjectName() instead.
-*/
-QScrollBar::QScrollBar(int minimum, int maximum, int lineStep, int pageStep,
- int value, Qt::Orientation orientation,
- QWidget *parent, const char *name)
- : QAbstractSlider(*new QScrollBarPrivate, parent)
-{
- Q_D(QScrollBar);
- setObjectName(QString::fromAscii(name));
- d->minimum = minimum;
- d->maximum = maximum;
- d->singleStep = lineStep;
- d->pageStep = pageStep;
- d->value = value;
- d->orientation = orientation;
- d->init();
-}
-#endif // QT3_SUPPORT
-
-/*!
- Destroys the scroll bar.
-*/
-QScrollBar::~QScrollBar()
-{
-}
-
-void QScrollBarPrivate::init()
-{
- Q_Q(QScrollBar);
- invertedControls = true;
- pressedControl = hoverControl = QStyle::SC_None;
- pointerOutsidePressedControl = false;
- q->setFocusPolicy(Qt::NoFocus);
- QSizePolicy sp(QSizePolicy::Minimum, QSizePolicy::Fixed, QSizePolicy::Slider);
- if (orientation == Qt::Vertical)
- sp.transpose();
- q->setSizePolicy(sp);
- q->setAttribute(Qt::WA_WState_OwnSizePolicy, false);
- q->setAttribute(Qt::WA_OpaquePaintEvent);
-
-#if !defined(QT_NO_CONTEXTMENU) && defined(Q_WS_WINCE)
- if (!q->style()->styleHint(QStyle::SH_ScrollBar_ContextMenu, 0, q)) {
- q->setContextMenuPolicy(Qt::PreventContextMenu);
- }
-#endif
-}
-
-#ifndef QT_NO_CONTEXTMENU
-/*! \reimp */
-void QScrollBar::contextMenuEvent(QContextMenuEvent *event)
-{
- if (!style()->styleHint(QStyle::SH_ScrollBar_ContextMenu, 0, this)) {
- QAbstractSlider::contextMenuEvent(event);
- return ;
- }
-
-#ifndef QT_NO_MENU
- bool horiz = HORIZONTAL;
- 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)
- setValue(d_func()->pixelPosToRangeValue(horiz ? event->pos().x() : event->pos().y()));
- else if (actionSelected == actScrollTop)
- triggerAction(QAbstractSlider::SliderToMinimum);
- else if (actionSelected == actScrollBottom)
- triggerAction(QAbstractSlider::SliderToMaximum);
- else if (actionSelected == actPageUp)
- triggerAction(QAbstractSlider::SliderPageStepSub);
- else if (actionSelected == actPageDn)
- triggerAction(QAbstractSlider::SliderPageStepAdd);
- else if (actionSelected == actScrollUp)
- triggerAction(QAbstractSlider::SliderSingleStepSub);
- else if (actionSelected == actScrollDn)
- triggerAction(QAbstractSlider::SliderSingleStepAdd);
-#endif // QT_NO_MENU
-}
-#endif // QT_NO_CONTEXTMENU
-
-
-/*! \reimp */
-QSize QScrollBar::sizeHint() const
-{
- ensurePolished();
- QStyleOptionSlider opt;
- initStyleOption(&opt);
-
- int scrollBarExtent = style()->pixelMetric(QStyle::PM_ScrollBarExtent, &opt, this);
- int scrollBarSliderMin = style()->pixelMetric(QStyle::PM_ScrollBarSliderMin, &opt, this);
- QSize size;
- if (opt.orientation == Qt::Horizontal)
- size = QSize(scrollBarExtent * 2 + scrollBarSliderMin, scrollBarExtent);
- else
- size = QSize(scrollBarExtent, scrollBarExtent * 2 + scrollBarSliderMin);
-
- return style()->sizeFromContents(QStyle::CT_ScrollBar, &opt, size, this)
- .expandedTo(QApplication::globalStrut());
- }
-
-/*!\reimp */
-void QScrollBar::sliderChange(SliderChange change)
-{
- QAbstractSlider::sliderChange(change);
-}
-
-/*!
- \reimp
-*/
-bool QScrollBar::event(QEvent *event)
-{
- switch(event->type()) {
- case QEvent::HoverEnter:
- case QEvent::HoverLeave:
- case QEvent::HoverMove:
- if (const QHoverEvent *he = static_cast<const QHoverEvent *>(event))
- d_func()->updateHoverControl(he->pos());
- break;
-#ifndef QT_NO_WHEELEVENT
- case QEvent::Wheel: {
- event->ignore();
- // override wheel event without adding virtual function override
- QWheelEvent *ev = static_cast<QWheelEvent *>(event);
- int delta = ev->delta();
- // scrollbar is a special case - in vertical mode it reaches minimum
- // value in the upper position, however QSlider's minimum value is on
- // the bottom. So we need to invert a value, but since the scrollbar is
- // inverted by default, we need to inverse the delta value for the
- // horizontal orientation.
- if (ev->orientation() == Qt::Horizontal)
- delta = -delta;
- Q_D(QScrollBar);
- if (d->scrollByDelta(ev->orientation(), ev->modifiers(), delta))
- event->accept();
- return true;
- }
-#endif
- default:
- break;
- }
- return QAbstractSlider::event(event);
-}
-
-/*!
- \reimp
-*/
-void QScrollBar::paintEvent(QPaintEvent *)
-{
- Q_D(QScrollBar);
- QPainter p(this);
- QStyleOptionSlider opt;
- initStyleOption(&opt);
- opt.subControls = QStyle::SC_All;
- if (d->pressedControl) {
- opt.activeSubControls = (QStyle::SubControl)d->pressedControl;
- if (!d->pointerOutsidePressedControl)
- opt.state |= QStyle::State_Sunken;
- } else {
- opt.activeSubControls = (QStyle::SubControl)d->hoverControl;
- }
- style()->drawComplexControl(QStyle::CC_ScrollBar, &opt, &p, this);
-}
-
-/*!
- \reimp
-*/
-void QScrollBar::mousePressEvent(QMouseEvent *e)
-{
- Q_D(QScrollBar);
-
- if (d->repeatActionTimer.isActive())
- d->stopRepeatAction();
-
- bool midButtonAbsPos = style()->styleHint(QStyle::SH_ScrollBar_MiddleClickAbsolutePosition,
- 0, this);
- QStyleOptionSlider opt;
- initStyleOption(&opt);
-
- if (d->maximum == d->minimum // no range
- || (e->buttons() & (~e->button())) // another button was clicked before
- || !(e->button() == Qt::LeftButton || (midButtonAbsPos && e->button() == Qt::MidButton)))
- return;
-
- d->pressedControl = style()->hitTestComplexControl(QStyle::CC_ScrollBar, &opt, e->pos(), this);
- d->pointerOutsidePressedControl = false;
-
- QRect sr = style()->subControlRect(QStyle::CC_ScrollBar, &opt,
- QStyle::SC_ScrollBarSlider, this);
- QPoint click = e->pos();
- QPoint pressValue = click - sr.center() + sr.topLeft();
- d->pressValue = d->orientation == Qt::Horizontal ? d->pixelPosToRangeValue(pressValue.x()) :
- d->pixelPosToRangeValue(pressValue.y());
- if (d->pressedControl == QStyle::SC_ScrollBarSlider) {
- d->clickOffset = HORIZONTAL ? (click.x()-sr.x()) : (click.y()-sr.y());
- d->snapBackPosition = d->position;
- }
-
- if ((d->pressedControl == QStyle::SC_ScrollBarAddPage
- || d->pressedControl == QStyle::SC_ScrollBarSubPage)
- && ((midButtonAbsPos && e->button() == Qt::MidButton)
- || (style()->styleHint(QStyle::SH_ScrollBar_LeftClickAbsolutePosition, &opt, this)
- && e->button() == Qt::LeftButton))) {
- int sliderLength = HORIZONTAL ? sr.width() : sr.height();
- setSliderPosition(d->pixelPosToRangeValue((HORIZONTAL ? e->pos().x()
- : e->pos().y()) - sliderLength / 2));
- d->pressedControl = QStyle::SC_ScrollBarSlider;
- d->clickOffset = sliderLength / 2;
- }
- const int initialDelay = 500; // default threshold
- d->activateControl(d->pressedControl, initialDelay);
- QElapsedTimer time;
- time.start();
- repaint(style()->subControlRect(QStyle::CC_ScrollBar, &opt, d->pressedControl, this));
- if (time.elapsed() >= initialDelay && d->repeatActionTimer.isActive()) {
- // It took more than 500ms (the initial timer delay) to process the repaint(), we
- // therefore need to restart the timer in case we have a pending mouse release event;
- // otherwise we'll get a timer event right before the release event,
- // causing the repeat action to be invoked twice on a single mouse click.
- // 50ms is the default repeat time (see activateControl/setRepeatAction).
- d->repeatActionTimer.start(50, this);
- }
- if (d->pressedControl == QStyle::SC_ScrollBarSlider)
- setSliderDown(true);
-}
-
-
-/*!
- \reimp
-*/
-void QScrollBar::mouseReleaseEvent(QMouseEvent *e)
-{
- Q_D(QScrollBar);
- if (!d->pressedControl)
- return;
-
- if (e->buttons() & (~e->button())) // some other button is still pressed
- return;
-
- d->stopRepeatAction();
-}
-
-
-/*!
- \reimp
-*/
-void QScrollBar::mouseMoveEvent(QMouseEvent *e)
-{
- Q_D(QScrollBar);
- if (!d->pressedControl)
- return;
-
- QStyleOptionSlider opt;
- initStyleOption(&opt);
- if (!(e->buttons() & Qt::LeftButton
- || ((e->buttons() & Qt::MidButton)
- && style()->styleHint(QStyle::SH_ScrollBar_MiddleClickAbsolutePosition, &opt, this))))
- return;
-
- if (d->pressedControl == QStyle::SC_ScrollBarSlider) {
- QPoint click = e->pos();
- int newPosition = d->pixelPosToRangeValue((HORIZONTAL ? click.x() : click.y()) -d->clickOffset);
- int m = style()->pixelMetric(QStyle::PM_MaximumDragDistance, &opt, this);
- if (m >= 0) {
- QRect r = rect();
- r.adjust(-m, -m, m, m);
- if (! r.contains(e->pos()))
- newPosition = d->snapBackPosition;
- }
- setSliderPosition(newPosition);
- } else if (!style()->styleHint(QStyle::SH_ScrollBar_ScrollWhenPointerLeavesControl, &opt, this)) {
-
- if (style()->styleHint(QStyle::SH_ScrollBar_RollBetweenButtons, &opt, this)
- && d->pressedControl & (QStyle::SC_ScrollBarAddLine | QStyle::SC_ScrollBarSubLine)) {
- QStyle::SubControl newSc = style()->hitTestComplexControl(QStyle::CC_ScrollBar, &opt, e->pos(), this);
- if (newSc == d->pressedControl && !d->pointerOutsidePressedControl)
- return; // nothing to do
- if (newSc & (QStyle::SC_ScrollBarAddLine | QStyle::SC_ScrollBarSubLine)) {
- d->pointerOutsidePressedControl = false;
- QRect scRect = style()->subControlRect(QStyle::CC_ScrollBar, &opt, newSc, this);
- scRect |= style()->subControlRect(QStyle::CC_ScrollBar, &opt, d->pressedControl, this);
- d->pressedControl = newSc;
- d->activateControl(d->pressedControl, 0);
- update(scRect);
- return;
- }
- }
-
- // stop scrolling when the mouse pointer leaves a control
- // similar to push buttons
- QRect pr = style()->subControlRect(QStyle::CC_ScrollBar, &opt, d->pressedControl, this);
- if (pr.contains(e->pos()) == d->pointerOutsidePressedControl) {
- if ((d->pointerOutsidePressedControl = !d->pointerOutsidePressedControl)) {
- d->pointerOutsidePressedControl = true;
- setRepeatAction(SliderNoAction);
- repaint(pr);
- } else {
- d->activateControl(d->pressedControl);
- }
- }
- }
-}
-
-
-int QScrollBarPrivate::pixelPosToRangeValue(int pos) const
-{
- Q_Q(const QScrollBar);
- QStyleOptionSlider opt;
- q->initStyleOption(&opt);
- QRect gr = q->style()->subControlRect(QStyle::CC_ScrollBar, &opt,
- QStyle::SC_ScrollBarGroove, q);
- QRect sr = q->style()->subControlRect(QStyle::CC_ScrollBar, &opt,
- QStyle::SC_ScrollBarSlider, q);
- int sliderMin, sliderMax, sliderLength;
-
- if (orientation == Qt::Horizontal) {
- sliderLength = sr.width();
- sliderMin = gr.x();
- sliderMax = gr.right() - sliderLength + 1;
- if (q->layoutDirection() == Qt::RightToLeft)
- opt.upsideDown = !opt.upsideDown;
- } else {
- sliderLength = sr.height();
- sliderMin = gr.y();
- sliderMax = gr.bottom() - sliderLength + 1;
- }
-
- return QStyle::sliderValueFromPosition(minimum, maximum, pos - sliderMin,
- sliderMax - sliderMin, opt.upsideDown);
-}
-
-/*! \reimp
-*/
-void QScrollBar::hideEvent(QHideEvent *)
-{
- Q_D(QScrollBar);
- if (d->pressedControl) {
- d->pressedControl = QStyle::SC_None;
- setRepeatAction(SliderNoAction);
- }
-}
-
-/*!
- \fn bool QScrollBar::draggingSlider()
-
- Use isSliderDown() instead.
-*/
-
-/*! \internal
- Returns the style option for scroll bar.
-*/
-Q_GUI_EXPORT QStyleOptionSlider qt_qscrollbarStyleOption(QScrollBar *scrollbar)
-{
- QStyleOptionSlider opt;
- scrollbar->initStyleOption(&opt);
- return opt;
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_SCROLLBAR
diff --git a/src/gui/widgets/qscrollbar.h b/src/gui/widgets/qscrollbar.h
deleted file mode 100644
index eb01b669b4..0000000000
--- a/src/gui/widgets/qscrollbar.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSCROLLBAR_H
-#define QSCROLLBAR_H
-
-#include <QtGui/qwidget.h>
-#include <QtGui/qabstractslider.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_SCROLLBAR
-
-class QScrollBarPrivate;
-class QStyleOptionSlider;
-
-class Q_GUI_EXPORT QScrollBar : public QAbstractSlider
-{
- Q_OBJECT
-public:
- explicit QScrollBar(QWidget *parent=0);
- explicit QScrollBar(Qt::Orientation, QWidget *parent=0);
- ~QScrollBar();
-
- QSize sizeHint() const;
- bool event(QEvent *event);
-
-protected:
- void paintEvent(QPaintEvent *);
- void mousePressEvent(QMouseEvent *);
- void mouseReleaseEvent(QMouseEvent *);
- void mouseMoveEvent(QMouseEvent *);
- void hideEvent(QHideEvent*);
- void sliderChange(SliderChange change);
-#ifndef QT_NO_CONTEXTMENU
- void contextMenuEvent(QContextMenuEvent *);
-#endif
- void initStyleOption(QStyleOptionSlider *option) const;
-
-#ifdef QT3_SUPPORT
-public:
- QT3_SUPPORT_CONSTRUCTOR QScrollBar(QWidget *parent, const char* name);
- QT3_SUPPORT_CONSTRUCTOR QScrollBar(Qt::Orientation, QWidget *parent, const char* name);
- QT3_SUPPORT_CONSTRUCTOR QScrollBar(int minValue, int maxValue, int lineStep, int pageStep,
- int value, Qt::Orientation, QWidget *parent=0, const char* name = 0);
- inline QT3_SUPPORT bool draggingSlider() { return isSliderDown(); }
-#endif
-
-private:
- friend Q_GUI_EXPORT QStyleOptionSlider qt_qscrollbarStyleOption(QScrollBar *scrollBar);
-
- Q_DISABLE_COPY(QScrollBar)
- Q_DECLARE_PRIVATE(QScrollBar)
-};
-
-#endif // QT_NO_SCROLLBAR
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QSCROLLBAR_H
diff --git a/src/gui/widgets/qsizegrip.cpp b/src/gui/widgets/qsizegrip.cpp
deleted file mode 100644
index dd77a2fa1c..0000000000
--- a/src/gui/widgets/qsizegrip.cpp
+++ /dev/null
@@ -1,570 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qsizegrip.h"
-
-#ifndef QT_NO_SIZEGRIP
-
-#include "qapplication.h"
-#include "qevent.h"
-#include "qpainter.h"
-#include "qstyle.h"
-#include "qstyleoption.h"
-#include "qlayout.h"
-#include "qdebug.h"
-#include <QDesktopWidget>
-
-#if defined(Q_WS_X11)
-#include <private/qt_x11_p.h>
-#elif defined (Q_WS_WIN)
-#include "qt_windows.h"
-#endif
-#ifdef Q_WS_MAC
-#include <private/qt_mac_p.h>
-#endif
-
-#include <private/qwidget_p.h>
-#include <QtGui/qabstractscrollarea.h>
-
-#define SZ_SIZEBOTTOMRIGHT 0xf008
-#define SZ_SIZEBOTTOMLEFT 0xf007
-#define SZ_SIZETOPLEFT 0xf004
-#define SZ_SIZETOPRIGHT 0xf005
-
-QT_BEGIN_NAMESPACE
-
-static QWidget *qt_sizegrip_topLevelWidget(QWidget* w)
-{
- while (w && !w->isWindow() && w->windowType() != Qt::SubWindow)
- w = w->parentWidget();
- return w;
-}
-
-class QSizeGripPrivate : public QWidgetPrivate
-{
- Q_DECLARE_PUBLIC(QSizeGrip)
-public:
- void init();
- QPoint p;
- QRect r;
- int d;
- int dxMax;
- int dyMax;
- Qt::Corner m_corner;
- bool gotMousePress;
- QWidget *tlw;
-#ifdef Q_WS_MAC
- void updateMacSizer(bool hide) const;
-#endif
- Qt::Corner corner() const;
- inline bool atBottom() const
- {
- return m_corner == Qt::BottomRightCorner || m_corner == Qt::BottomLeftCorner;
- }
-
- inline bool atLeft() const
- {
- return m_corner == Qt::BottomLeftCorner || m_corner == Qt::TopLeftCorner;
- }
-
- void updateTopLevelWidget()
- {
- Q_Q(QSizeGrip);
- QWidget *w = qt_sizegrip_topLevelWidget(q);
- if (tlw == w)
- return;
- if (tlw)
- tlw->removeEventFilter(q);
- tlw = w;
- if (tlw)
- tlw->installEventFilter(q);
- }
-
- // This slot is invoked by QLayout when the size grip is added to
- // a layout or reparented after the tlw is shown. This re-implementation is basically
- // the same as QWidgetPrivate::_q_showIfNotHidden except that it checks
- // for Qt::WindowFullScreen and Qt::WindowMaximized as well.
- void _q_showIfNotHidden()
- {
- Q_Q(QSizeGrip);
- bool showSizeGrip = !(q->isHidden() && q->testAttribute(Qt::WA_WState_ExplicitShowHide));
- updateTopLevelWidget();
- if (tlw && showSizeGrip) {
- Qt::WindowStates sizeGripNotVisibleState = Qt::WindowFullScreen;
-#ifndef Q_WS_MAC
- sizeGripNotVisibleState |= Qt::WindowMaximized;
-#endif
- // Don't show the size grip if the tlw is maximized or in full screen mode.
- showSizeGrip = !(tlw->windowState() & sizeGripNotVisibleState);
- }
- if (showSizeGrip)
- q->setVisible(true);
- }
-};
-
-#ifdef Q_WS_MAC
-void QSizeGripPrivate::updateMacSizer(bool hide) const
-{
- Q_Q(const QSizeGrip);
- if (QApplication::closingDown() || !parent)
- return;
- QWidget *topLevelWindow = qt_sizegrip_topLevelWidget(const_cast<QSizeGrip *>(q));
- if(topLevelWindow && topLevelWindow->isWindow())
- QWidgetPrivate::qt_mac_update_sizer(topLevelWindow, hide ? -1 : 1);
-}
-#endif
-
-Qt::Corner QSizeGripPrivate::corner() const
-{
- Q_Q(const QSizeGrip);
- QWidget *tlw = qt_sizegrip_topLevelWidget(const_cast<QSizeGrip *>(q));
- const QPoint sizeGripPos = q->mapTo(tlw, QPoint(0, 0));
- bool isAtBottom = sizeGripPos.y() >= tlw->height() / 2;
- bool isAtLeft = sizeGripPos.x() <= tlw->width() / 2;
- if (isAtLeft)
- return isAtBottom ? Qt::BottomLeftCorner : Qt::TopLeftCorner;
- else
- return isAtBottom ? Qt::BottomRightCorner : Qt::TopRightCorner;
-}
-
-/*!
- \class QSizeGrip
-
- \brief The QSizeGrip class provides a resize handle for resizing top-level windows.
-
- \ingroup mainwindow-classes
- \ingroup basicwidgets
-
- This widget works like the standard Windows resize handle. In the
- X11 version this resize handle generally works differently from
- the one provided by the system if the X11 window manager does not
- support necessary modern post-ICCCM specifications.
-
- Put this widget anywhere in a widget tree and the user can use it
- to resize the top-level window or any widget with the Qt::SubWindow
- flag set. Generally, this should be in the lower right-hand corner.
- Note that QStatusBar already uses this widget, so if you have a
- status bar (e.g., you are using QMainWindow), then you don't need
- to use this widget explicitly.
-
- On some platforms the size grip automatically hides itself when the
- window is shown full screen or maximised.
-
- \table 50%
- \row \o \inlineimage plastique-sizegrip.png Screenshot of a Plastique style size grip
- \o A size grip widget at the bottom-right corner of a main window, shown in the
- \l{Plastique Style Widget Gallery}{Plastique widget style}.
- \endtable
-
- The QSizeGrip class inherits QWidget and reimplements the \l
- {QWidget::mousePressEvent()}{mousePressEvent()} and \l
- {QWidget::mouseMoveEvent()}{mouseMoveEvent()} functions to feature
- the resize functionality, and the \l
- {QWidget::paintEvent()}{paintEvent()} function to render the
- size grip widget.
-
- \sa QStatusBar QWidget::windowState()
-*/
-
-
-/*!
- Constructs a resize corner as a child widget of the given \a
- parent.
-*/
-QSizeGrip::QSizeGrip(QWidget * parent)
- : QWidget(*new QSizeGripPrivate, parent, 0)
-{
- Q_D(QSizeGrip);
- d->init();
-}
-
-#ifdef QT3_SUPPORT
-/*!
- \obsolete
-
- Constructs a resize corner with the given \a name, as a child
- widget of the given \a parent.
-*/
-QSizeGrip::QSizeGrip(QWidget * parent, const char* name)
- : QWidget(*new QSizeGripPrivate, parent, 0)
-{
- Q_D(QSizeGrip);
- setObjectName(QString::fromAscii(name));
- d->init();
-}
-#endif
-
-void QSizeGripPrivate::init()
-{
- Q_Q(QSizeGrip);
- dxMax = 0;
- dyMax = 0;
- tlw = 0;
- m_corner = q->isLeftToRight() ? Qt::BottomRightCorner : Qt::BottomLeftCorner;
- gotMousePress = false;
-
-#if !defined(QT_NO_CURSOR) && !defined(Q_WS_MAC)
- q->setCursor(m_corner == Qt::TopLeftCorner || m_corner == Qt::BottomRightCorner
- ? Qt::SizeFDiagCursor : Qt::SizeBDiagCursor);
-#endif
- q->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed));
- updateTopLevelWidget();
-}
-
-
-/*!
- Destroys this size grip.
-*/
-QSizeGrip::~QSizeGrip()
-{
-}
-
-/*!
- \reimp
-*/
-QSize QSizeGrip::sizeHint() const
-{
- QStyleOption opt(0);
- opt.init(this);
- return (style()->sizeFromContents(QStyle::CT_SizeGrip, &opt, QSize(13, 13), this).
- expandedTo(QApplication::globalStrut()));
-}
-
-/*!
- Paints the resize grip.
-
- Resize grips are usually rendered as small diagonal textured lines
- in the lower-right corner. The paint event is passed in the \a
- event parameter.
-*/
-void QSizeGrip::paintEvent(QPaintEvent *event)
-{
- Q_UNUSED(event);
- Q_D(QSizeGrip);
- QPainter painter(this);
- QStyleOptionSizeGrip opt;
- opt.init(this);
- opt.corner = d->m_corner;
- style()->drawControl(QStyle::CE_SizeGrip, &opt, &painter, this);
-}
-
-/*!
- \fn void QSizeGrip::mousePressEvent(QMouseEvent * event)
-
- Receives the mouse press events for the widget, and primes the
- resize operation. The mouse press event is passed in the \a event
- parameter.
-*/
-void QSizeGrip::mousePressEvent(QMouseEvent * e)
-{
- if (e->button() != Qt::LeftButton) {
- QWidget::mousePressEvent(e);
- return;
- }
-
- Q_D(QSizeGrip);
- QWidget *tlw = qt_sizegrip_topLevelWidget(this);
- d->p = e->globalPos();
- d->gotMousePress = true;
- d->r = tlw->geometry();
-
-#ifdef Q_WS_X11
- // Use a native X11 sizegrip for "real" top-level windows if supported.
- if (tlw->isWindow() && X11->isSupportedByWM(ATOM(_NET_WM_MOVERESIZE))
- && !(tlw->windowFlags() & Qt::X11BypassWindowManagerHint)
- && !tlw->testAttribute(Qt::WA_DontShowOnScreen) && !qt_widget_private(tlw)->hasHeightForWidth()) {
- XEvent xev;
- xev.xclient.type = ClientMessage;
- xev.xclient.message_type = ATOM(_NET_WM_MOVERESIZE);
- xev.xclient.display = X11->display;
- xev.xclient.window = tlw->winId();
- xev.xclient.format = 32;
- xev.xclient.data.l[0] = e->globalPos().x();
- xev.xclient.data.l[1] = e->globalPos().y();
- if (d->atBottom())
- xev.xclient.data.l[2] = d->atLeft() ? 6 : 4; // bottomleft/bottomright
- else
- xev.xclient.data.l[2] = d->atLeft() ? 0 : 2; // topleft/topright
- xev.xclient.data.l[3] = Button1;
- xev.xclient.data.l[4] = 0;
- XUngrabPointer(X11->display, X11->time);
- XSendEvent(X11->display, QX11Info::appRootWindow(x11Info().screen()), False,
- SubstructureRedirectMask | SubstructureNotifyMask, &xev);
- return;
- }
-#endif // Q_WS_X11
-#ifdef Q_WS_WIN
- if (tlw->isWindow() && !tlw->testAttribute(Qt::WA_DontShowOnScreen) && !qt_widget_private(tlw)->hasHeightForWidth()) {
- uint orientation = 0;
- if (d->atBottom())
- orientation = d->atLeft() ? SZ_SIZEBOTTOMLEFT : SZ_SIZEBOTTOMRIGHT;
- else
- orientation = d->atLeft() ? SZ_SIZETOPLEFT : SZ_SIZETOPRIGHT;
-
- ReleaseCapture();
- PostMessage(tlw->winId(), WM_SYSCOMMAND, orientation, 0);
- return;
- }
-#endif // Q_WS_WIN
-
- // Find available desktop/workspace geometry.
- QRect availableGeometry;
- bool hasVerticalSizeConstraint = true;
- bool hasHorizontalSizeConstraint = true;
- if (tlw->isWindow())
- availableGeometry = QApplication::desktop()->availableGeometry(tlw);
- else {
- const QWidget *tlwParent = tlw->parentWidget();
- // Check if tlw is inside QAbstractScrollArea/QScrollArea.
- // If that's the case tlw->parentWidget() will return the viewport
- // and tlw->parentWidget()->parentWidget() will return the scroll area.
-#ifndef QT_NO_SCROLLAREA
- QAbstractScrollArea *scrollArea = qobject_cast<QAbstractScrollArea *>(tlwParent->parentWidget());
- if (scrollArea) {
- hasHorizontalSizeConstraint = scrollArea->horizontalScrollBarPolicy() == Qt::ScrollBarAlwaysOff;
- hasVerticalSizeConstraint = scrollArea->verticalScrollBarPolicy() == Qt::ScrollBarAlwaysOff;
- }
-#endif // QT_NO_SCROLLAREA
- availableGeometry = tlwParent->contentsRect();
- }
-
- // Find frame geometries, title bar height, and decoration sizes.
- const QRect frameGeometry = tlw->frameGeometry();
- const int titleBarHeight = qMax(tlw->geometry().y() - frameGeometry.y(), 0);
- const int bottomDecoration = qMax(frameGeometry.height() - tlw->height() - titleBarHeight, 0);
- const int leftRightDecoration = qMax((frameGeometry.width() - tlw->width()) / 2, 0);
-
- // Determine dyMax depending on whether the sizegrip is at the bottom
- // of the widget or not.
- if (d->atBottom()) {
- if (hasVerticalSizeConstraint)
- d->dyMax = availableGeometry.bottom() - d->r.bottom() - bottomDecoration;
- else
- d->dyMax = INT_MAX;
- } else {
- if (hasVerticalSizeConstraint)
- d->dyMax = availableGeometry.y() - d->r.y() + titleBarHeight;
- else
- d->dyMax = -INT_MAX;
- }
-
- // In RTL mode, the size grip is to the left; find dxMax from the desktop/workspace
- // geometry, the size grip geometry and the width of the decoration.
- if (d->atLeft()) {
- if (hasHorizontalSizeConstraint)
- d->dxMax = availableGeometry.x() - d->r.x() + leftRightDecoration;
- else
- d->dxMax = -INT_MAX;
- } else {
- if (hasHorizontalSizeConstraint)
- d->dxMax = availableGeometry.right() - d->r.right() - leftRightDecoration;
- else
- d->dxMax = INT_MAX;
- }
-}
-
-
-/*!
- \fn void QSizeGrip::mouseMoveEvent(QMouseEvent * event)
- Resizes the top-level widget containing this widget. The mouse
- move event is passed in the \a event parameter.
-*/
-void QSizeGrip::mouseMoveEvent(QMouseEvent * e)
-{
- if (e->buttons() != Qt::LeftButton) {
- QWidget::mouseMoveEvent(e);
- return;
- }
-
- Q_D(QSizeGrip);
- QWidget* tlw = qt_sizegrip_topLevelWidget(this);
- if (!d->gotMousePress || tlw->testAttribute(Qt::WA_WState_ConfigPending))
- return;
-
-#ifdef Q_WS_X11
- if (tlw->isWindow() && X11->isSupportedByWM(ATOM(_NET_WM_MOVERESIZE))
- && tlw->isTopLevel() && !(tlw->windowFlags() & Qt::X11BypassWindowManagerHint)
- && !tlw->testAttribute(Qt::WA_DontShowOnScreen) && !qt_widget_private(tlw)->hasHeightForWidth())
- return;
-#endif
-#ifdef Q_WS_WIN
- if (tlw->isWindow() && GetSystemMenu(tlw->winId(), FALSE) != 0 && internalWinId()
- && !tlw->testAttribute(Qt::WA_DontShowOnScreen) && !qt_widget_private(tlw)->hasHeightForWidth()) {
- MSG msg;
- while(PeekMessage(&msg, winId(), WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE));
- return;
- }
-#endif
-
- QPoint np(e->globalPos());
-
- // Don't extend beyond the available geometry; bound to dyMax and dxMax.
- QSize ns;
- if (d->atBottom())
- ns.rheight() = d->r.height() + qMin(np.y() - d->p.y(), d->dyMax);
- else
- ns.rheight() = d->r.height() - qMax(np.y() - d->p.y(), d->dyMax);
-
- if (d->atLeft())
- ns.rwidth() = d->r.width() - qMax(np.x() - d->p.x(), d->dxMax);
- else
- ns.rwidth() = d->r.width() + qMin(np.x() - d->p.x(), d->dxMax);
-
- ns = QLayout::closestAcceptableSize(tlw, ns);
-
- QPoint p;
- QRect nr(p, ns);
- if (d->atBottom()) {
- if (d->atLeft())
- nr.moveTopRight(d->r.topRight());
- else
- nr.moveTopLeft(d->r.topLeft());
- } else {
- if (d->atLeft())
- nr.moveBottomRight(d->r.bottomRight());
- else
- nr.moveBottomLeft(d->r.bottomLeft());
- }
-
- tlw->setGeometry(nr);
-}
-
-/*!
- \reimp
-*/
-void QSizeGrip::mouseReleaseEvent(QMouseEvent *mouseEvent)
-{
- if (mouseEvent->button() == Qt::LeftButton) {
- Q_D(QSizeGrip);
- d->gotMousePress = false;
- d->p = QPoint();
- } else {
- QWidget::mouseReleaseEvent(mouseEvent);
- }
-}
-
-/*!
- \reimp
-*/
-void QSizeGrip::moveEvent(QMoveEvent * /*moveEvent*/)
-{
- Q_D(QSizeGrip);
- // We're inside a resize operation; no update necessary.
- if (!d->p.isNull())
- return;
-
- d->m_corner = d->corner();
-#if !defined(QT_NO_CURSOR) && !defined(Q_WS_MAC)
- setCursor(d->m_corner == Qt::TopLeftCorner || d->m_corner == Qt::BottomRightCorner
- ? Qt::SizeFDiagCursor : Qt::SizeBDiagCursor);
-#endif
-}
-
-/*!
- \reimp
-*/
-void QSizeGrip::showEvent(QShowEvent *showEvent)
-{
-#ifdef Q_WS_MAC
- d_func()->updateMacSizer(false);
-#endif
- QWidget::showEvent(showEvent);
-}
-
-/*!
- \reimp
-*/
-void QSizeGrip::hideEvent(QHideEvent *hideEvent)
-{
-#ifdef Q_WS_MAC
- d_func()->updateMacSizer(true);
-#endif
- QWidget::hideEvent(hideEvent);
-}
-
-/*!
- \reimp
-*/
-void QSizeGrip::setVisible(bool visible)
-{
- QWidget::setVisible(visible);
-}
-
-/*! \reimp */
-bool QSizeGrip::eventFilter(QObject *o, QEvent *e)
-{
- Q_D(QSizeGrip);
- if ((isHidden() && testAttribute(Qt::WA_WState_ExplicitShowHide))
- || e->type() != QEvent::WindowStateChange
- || o != d->tlw) {
- return QWidget::eventFilter(o, e);
- }
- Qt::WindowStates sizeGripNotVisibleState = Qt::WindowFullScreen;
-#ifndef Q_WS_MAC
- sizeGripNotVisibleState |= Qt::WindowMaximized;
-#endif
- // Don't show the size grip if the tlw is maximized or in full screen mode.
- setVisible(!(d->tlw->windowState() & sizeGripNotVisibleState));
- setAttribute(Qt::WA_WState_ExplicitShowHide, false);
- return QWidget::eventFilter(o, e);
-}
-
-/*!
- \reimp
-*/
-bool QSizeGrip::event(QEvent *event)
-{
- return QWidget::event(event);
-}
-
-#ifdef Q_WS_WIN
-/*! \reimp */
-bool QSizeGrip::winEvent( MSG *m, long *result )
-{
- return QWidget::winEvent(m, result);
-}
-#endif
-
-QT_END_NAMESPACE
-
-#include "moc_qsizegrip.cpp"
-
-#endif //QT_NO_SIZEGRIP
diff --git a/src/gui/widgets/qsizegrip.h b/src/gui/widgets/qsizegrip.h
deleted file mode 100644
index 3d2dcce60e..0000000000
--- a/src/gui/widgets/qsizegrip.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSIZEGRIP_H
-#define QSIZEGRIP_H
-
-#include <QtGui/qwidget.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_SIZEGRIP
-class QSizeGripPrivate;
-class Q_GUI_EXPORT QSizeGrip : public QWidget
-{
- Q_OBJECT
-public:
- explicit QSizeGrip(QWidget *parent);
- ~QSizeGrip();
-
- QSize sizeHint() const;
- void setVisible(bool);
-
-protected:
- void paintEvent(QPaintEvent *);
- void mousePressEvent(QMouseEvent *);
- void mouseMoveEvent(QMouseEvent *);
- void mouseReleaseEvent(QMouseEvent *mouseEvent);
- void moveEvent(QMoveEvent *moveEvent);
- void showEvent(QShowEvent *showEvent);
- void hideEvent(QHideEvent *hideEvent);
- bool eventFilter(QObject *, QEvent *);
- bool event(QEvent *);
-#ifdef Q_WS_WIN
- bool winEvent(MSG *m, long *result);
-#endif
-
-public:
-#ifdef QT3_SUPPORT
- QT3_SUPPORT_CONSTRUCTOR QSizeGrip(QWidget *parent, const char *name);
-#endif
-
-private:
- Q_DECLARE_PRIVATE(QSizeGrip)
- Q_DISABLE_COPY(QSizeGrip)
- Q_PRIVATE_SLOT(d_func(), void _q_showIfNotHidden())
-};
-#endif // QT_NO_SIZEGRIP
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QSIZEGRIP_H
diff --git a/src/gui/widgets/qslider.cpp b/src/gui/widgets/qslider.cpp
deleted file mode 100644
index 026926a8a3..0000000000
--- a/src/gui/widgets/qslider.cpp
+++ /dev/null
@@ -1,652 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qslider.h"
-#ifndef QT_NO_SLIDER
-#ifndef QT_NO_ACCESSIBILITY
-#include "qaccessible.h"
-#endif
-#include "qapplication.h"
-#include "qevent.h"
-#include "qpainter.h"
-#include "qstyle.h"
-#include "qstyleoption.h"
-#include "private/qabstractslider_p.h"
-#include "qdebug.h"
-
-QT_BEGIN_NAMESPACE
-
-class QSliderPrivate : public QAbstractSliderPrivate
-{
- Q_DECLARE_PUBLIC(QSlider)
-public:
- QStyle::SubControl pressedControl;
- int tickInterval;
- QSlider::TickPosition tickPosition;
- int clickOffset;
- void init();
- void resetLayoutItemMargins();
- int pixelPosToRangeValue(int pos) const;
- inline int pick(const QPoint &pt) const;
-
- QStyle::SubControl newHoverControl(const QPoint &pos);
- bool updateHoverControl(const QPoint &pos);
- QStyle::SubControl hoverControl;
- QRect hoverRect;
-};
-
-void QSliderPrivate::init()
-{
- Q_Q(QSlider);
- pressedControl = QStyle::SC_None;
- tickInterval = 0;
- tickPosition = QSlider::NoTicks;
- hoverControl = QStyle::SC_None;
- q->setFocusPolicy(Qt::FocusPolicy(q->style()->styleHint(QStyle::SH_Button_FocusPolicy)));
- QSizePolicy sp(QSizePolicy::Expanding, QSizePolicy::Fixed, QSizePolicy::Slider);
- if (orientation == Qt::Vertical)
- sp.transpose();
- q->setSizePolicy(sp);
- q->setAttribute(Qt::WA_WState_OwnSizePolicy, false);
- resetLayoutItemMargins();
-}
-
-void QSliderPrivate::resetLayoutItemMargins()
-{
- Q_Q(QSlider);
- QStyleOptionSlider opt;
- q->initStyleOption(&opt);
- setLayoutItemMargins(QStyle::SE_SliderLayoutItem, &opt);
-}
-
-int QSliderPrivate::pixelPosToRangeValue(int pos) const
-{
- Q_Q(const QSlider);
- QStyleOptionSlider opt;
- q->initStyleOption(&opt);
- QRect gr = q->style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderGroove, q);
- QRect sr = q->style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, q);
- int sliderMin, sliderMax, sliderLength;
-
- if (orientation == Qt::Horizontal) {
- sliderLength = sr.width();
- sliderMin = gr.x();
- sliderMax = gr.right() - sliderLength + 1;
- } else {
- sliderLength = sr.height();
- sliderMin = gr.y();
- sliderMax = gr.bottom() - sliderLength + 1;
- }
- return QStyle::sliderValueFromPosition(minimum, maximum, pos - sliderMin,
- sliderMax - sliderMin, opt.upsideDown);
-}
-
-inline int QSliderPrivate::pick(const QPoint &pt) const
-{
- return orientation == Qt::Horizontal ? pt.x() : pt.y();
-}
-
-/*!
- Initialize \a option with the values from this QSlider. This method
- is useful for subclasses when they need a QStyleOptionSlider, but don't want
- to fill in all the information themselves.
-
- \sa QStyleOption::initFrom()
-*/
-void QSlider::initStyleOption(QStyleOptionSlider *option) const
-{
- if (!option)
- return;
-
- Q_D(const QSlider);
- option->initFrom(this);
- option->subControls = QStyle::SC_None;
- option->activeSubControls = QStyle::SC_None;
- option->orientation = d->orientation;
- option->maximum = d->maximum;
- option->minimum = d->minimum;
- option->tickPosition = (QSlider::TickPosition)d->tickPosition;
- option->tickInterval = d->tickInterval;
- option->upsideDown = (d->orientation == Qt::Horizontal) ?
- (d->invertedAppearance != (option->direction == Qt::RightToLeft))
- : (!d->invertedAppearance);
- option->direction = Qt::LeftToRight; // we use the upsideDown option instead
- option->sliderPosition = d->position;
- option->sliderValue = d->value;
- option->singleStep = d->singleStep;
- option->pageStep = d->pageStep;
- if (d->orientation == Qt::Horizontal)
- option->state |= QStyle::State_Horizontal;
-}
-
-bool QSliderPrivate::updateHoverControl(const QPoint &pos)
-{
- Q_Q(QSlider);
- QRect lastHoverRect = hoverRect;
- QStyle::SubControl lastHoverControl = hoverControl;
- bool doesHover = q->testAttribute(Qt::WA_Hover);
- if (lastHoverControl != newHoverControl(pos) && doesHover) {
- q->update(lastHoverRect);
- q->update(hoverRect);
- return true;
- }
- return !doesHover;
-}
-
-QStyle::SubControl QSliderPrivate::newHoverControl(const QPoint &pos)
-{
- Q_Q(QSlider);
- QStyleOptionSlider opt;
- q->initStyleOption(&opt);
- opt.subControls = QStyle::SC_All;
- QRect handleRect = q->style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, q);
- QRect grooveRect = q->style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderGroove, q);
- QRect tickmarksRect = q->style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderTickmarks, q);
-
- if (handleRect.contains(pos)) {
- hoverRect = handleRect;
- hoverControl = QStyle::SC_SliderHandle;
- } else if (grooveRect.contains(pos)) {
- hoverRect = grooveRect;
- hoverControl = QStyle::SC_SliderGroove;
- } else if (tickmarksRect.contains(pos)) {
- hoverRect = tickmarksRect;
- hoverControl = QStyle::SC_SliderTickmarks;
- } else {
- hoverRect = QRect();
- hoverControl = QStyle::SC_None;
- }
-
- return hoverControl;
-}
-
-/*!
- \class QSlider
- \brief The QSlider widget provides a vertical or horizontal slider.
-
- \ingroup basicwidgets
-
-
- The slider is the classic widget for controlling a bounded value.
- It lets the user move a slider handle along a horizontal or vertical
- groove and translates the handle's position into an integer value
- within the legal range.
-
- QSlider has very few of its own functions; most of the functionality is in
- QAbstractSlider. The most useful functions are setValue() to set
- the slider directly to some value; triggerAction() to simulate
- the effects of clicking (useful for shortcut keys);
- setSingleStep(), setPageStep() to set the steps; and setMinimum()
- and setMaximum() to define the range of the scroll bar.
-
- QSlider provides methods for controlling tickmarks. You can use
- setTickPosition() to indicate where you want the tickmarks to be,
- setTickInterval() to indicate how many of them you want. the
- currently set tick position and interval can be queried using the
- tickPosition() and tickInterval() functions, respectively.
-
- QSlider inherits a comprehensive set of signals:
- \table
- \header \o Signal \o Description
- \row \o \l valueChanged()
- \o Emitted when the slider's value has changed. The tracking()
- determines whether this signal is emitted during user
- interaction.
- \row \o \l sliderPressed()
- \o Emitted when the user starts to drag the slider.
- \row \o \l sliderMoved()
- \o Emitted when the user drags the slider.
- \row \o \l sliderReleased()
- \o Emitted when the user releases the slider.
- \endtable
-
- QSlider only provides integer ranges. Note that although
- QSlider handles very large numbers, it becomes difficult for users
- to use a slider accurately for very large ranges.
-
- A slider accepts focus on Tab and provides both a mouse wheel and a
- keyboard interface. The keyboard interface is the following:
-
- \list
- \o Left/Right move a horizontal slider by one single step.
- \o Up/Down move a vertical slider by one single step.
- \o PageUp moves up one page.
- \o PageDown moves down one page.
- \o Home moves to the start (mininum).
- \o End moves to the end (maximum).
- \endlist
-
- \table 100%
- \row \o \inlineimage macintosh-slider.png Screenshot of a Macintosh slider
- \o A slider shown in the \l{Macintosh Style Widget Gallery}{Macintosh widget style}.
- \row \o \inlineimage windows-slider.png Screenshot of a Windows XP slider
- \o A slider shown in the \l{Windows XP Style Widget Gallery}{Windows XP widget style}.
- \row \o \inlineimage plastique-slider.png Screenshot of a Plastique slider
- \o A slider shown in the \l{Plastique Style Widget Gallery}{Plastique widget style}.
- \endtable
-
- \sa QScrollBar, QSpinBox, QDial, {fowler}{GUI Design Handbook: Slider}, {Sliders Example}
-*/
-
-
-/*!
- \enum QSlider::TickPosition
-
- This enum specifies where the tick marks are to be drawn relative
- to the slider's groove and the handle the user moves.
-
- \value NoTicks Do not draw any tick marks.
- \value TicksBothSides Draw tick marks on both sides of the groove.
- \value TicksAbove Draw tick marks above the (horizontal) slider
- \value TicksBelow Draw tick marks below the (horizontal) slider
- \value TicksLeft Draw tick marks to the left of the (vertical) slider
- \value TicksRight Draw tick marks to the right of the (vertical) slider
-
- \omitvalue NoMarks
- \omitvalue Above
- \omitvalue Left
- \omitvalue Below
- \omitvalue Right
- \omitvalue Both
-*/
-
-
-/*!
- Constructs a vertical slider with the given \a parent.
-*/
-QSlider::QSlider(QWidget *parent)
- : QAbstractSlider(*new QSliderPrivate, parent)
-{
- d_func()->orientation = Qt::Vertical;
- d_func()->init();
-}
-
-/*!
- Constructs a slider with the given \a parent. The \a orientation
- parameter determines whether the slider is horizontal or vertical;
- the valid values are Qt::Vertical and Qt::Horizontal.
-*/
-
-QSlider::QSlider(Qt::Orientation orientation, QWidget *parent)
- : QAbstractSlider(*new QSliderPrivate, parent)
-{
- d_func()->orientation = orientation;
- d_func()->init();
-}
-
-#ifdef QT3_SUPPORT
-/*!
- Use QSlider() and QObject::setObjectName() instead.
-
- \oldcode
- QSlider *mySlider = new QSlider(parent, name);
- \newcode
- QSlider *mySlider = new QSlider(parent);
- mySlider->setObjectName(name);
- \endcode
-*/
-QSlider::QSlider(QWidget *parent, const char *name)
- : QAbstractSlider(*new QSliderPrivate, parent)
-{
- setObjectName(QString::fromAscii(name));
- d_func()->orientation = Qt::Vertical;
- d_func()->init();
-}
-
-/*!
- Use QSlider() and QObject::setObjectName() instead.
-
- \oldcode
- QSlider *mySlider = new QSlider(orientation, parent, name);
- \newcode
- QSlider *mySlider = new QSlider(orientation, parent);
- mySlider->setObjectName(name);
- \endcode
-*/
-QSlider::QSlider(Qt::Orientation orientation, QWidget *parent, const char *name)
- : QAbstractSlider(*new QSliderPrivate, parent)
-{
- setObjectName(QString::fromAscii(name));
- d_func()->orientation = orientation;
- d_func()->init();
-}
-
-/*!
- Use QSlider(), QObject::setObjectName() and the functionality
- inherited from QAbstractSlider instead.
-
- \oldcode
- QSlider *mySlider = new QSlider(minValue, maxValue, pageStep,
- value, orientation, parent, name);
- \newcode
- QSlider *mySlider = new QSlider(orientation, parent);
- mySlider->setObjectName(name);
- mySlider->setMinimum(minValue);
- mySlider->setMaximum(maxValue);
- mySlider->setPageStep(pageStep);
- mySlider->setValue(value);
- \endcode
-*/
-QSlider::QSlider(int minValue, int maxValue, int pageStep, int value, Qt::Orientation orientation,
- QWidget *parent, const char *name)
- : QAbstractSlider(*new QSliderPrivate, parent)
-{
- Q_D(QSlider);
- setObjectName(QString::fromAscii(name));
- d->minimum = minValue;
- d->maximum = maxValue;
- d->pageStep = pageStep;
- d->position = d->value = value;
- d->orientation = orientation;
- d->init();
-}
-#endif
-
-/*!
- Destroys this slider.
-*/
-QSlider::~QSlider()
-{
-}
-
-/*!
- \reimp
-*/
-void QSlider::paintEvent(QPaintEvent *)
-{
- Q_D(QSlider);
- QPainter p(this);
- QStyleOptionSlider opt;
- initStyleOption(&opt);
-
- opt.subControls = QStyle::SC_SliderGroove | QStyle::SC_SliderHandle;
- if (d->tickPosition != NoTicks)
- opt.subControls |= QStyle::SC_SliderTickmarks;
- if (d->pressedControl) {
- opt.activeSubControls = d->pressedControl;
- opt.state |= QStyle::State_Sunken;
- } else {
- opt.activeSubControls = d->hoverControl;
- }
-
- style()->drawComplexControl(QStyle::CC_Slider, &opt, &p, this);
-}
-
-/*!
- \reimp
-*/
-
-bool QSlider::event(QEvent *event)
-{
- Q_D(QSlider);
-
- switch(event->type()) {
- case QEvent::HoverEnter:
- case QEvent::HoverLeave:
- case QEvent::HoverMove:
- if (const QHoverEvent *he = static_cast<const QHoverEvent *>(event))
- d->updateHoverControl(he->pos());
- break;
- case QEvent::StyleChange:
- case QEvent::MacSizeChange:
- d->resetLayoutItemMargins();
- break;
- default:
- break;
- }
- return QAbstractSlider::event(event);
-}
-
-/*!
- \reimp
-*/
-void QSlider::mousePressEvent(QMouseEvent *ev)
-{
- Q_D(QSlider);
- if (d->maximum == d->minimum || (ev->buttons() ^ ev->button())) {
- ev->ignore();
- return;
- }
-#ifdef QT_KEYPAD_NAVIGATION
- if (QApplication::keypadNavigationEnabled())
- setEditFocus(true);
-#endif
- ev->accept();
- if ((ev->button() & style()->styleHint(QStyle::SH_Slider_AbsoluteSetButtons)) == ev->button()) {
- QStyleOptionSlider opt;
- initStyleOption(&opt);
- const QRect sliderRect = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this);
- const QPoint center = sliderRect.center() - sliderRect.topLeft();
- // to take half of the slider off for the setSliderPosition call we use the center - topLeft
-
- setSliderPosition(d->pixelPosToRangeValue(d->pick(ev->pos() - center)));
- triggerAction(SliderMove);
- setRepeatAction(SliderNoAction);
- d->pressedControl = QStyle::SC_SliderHandle;
- update();
- } else if ((ev->button() & style()->styleHint(QStyle::SH_Slider_PageSetButtons)) == ev->button()) {
- QStyleOptionSlider opt;
- initStyleOption(&opt);
- d->pressedControl = style()->hitTestComplexControl(QStyle::CC_Slider,
- &opt, ev->pos(), this);
- SliderAction action = SliderNoAction;
- if (d->pressedControl == QStyle::SC_SliderGroove) {
- const QRect sliderRect = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this);
- int pressValue = d->pixelPosToRangeValue(d->pick(ev->pos() - sliderRect.center() + sliderRect.topLeft()));
- d->pressValue = pressValue;
- if (pressValue > d->value)
- action = SliderPageStepAdd;
- else if (pressValue < d->value)
- action = SliderPageStepSub;
- if (action) {
- triggerAction(action);
- setRepeatAction(action);
- }
- }
- } else {
- ev->ignore();
- return;
- }
-
- if (d->pressedControl == QStyle::SC_SliderHandle) {
- QStyleOptionSlider opt;
- initStyleOption(&opt);
- setRepeatAction(SliderNoAction);
- QRect sr = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this);
- d->clickOffset = d->pick(ev->pos() - sr.topLeft());
- update(sr);
- setSliderDown(true);
- }
-}
-
-/*!
- \reimp
-*/
-void QSlider::mouseMoveEvent(QMouseEvent *ev)
-{
- Q_D(QSlider);
- if (d->pressedControl != QStyle::SC_SliderHandle) {
- ev->ignore();
- return;
- }
- ev->accept();
- int newPosition = d->pixelPosToRangeValue(d->pick(ev->pos()) - d->clickOffset);
- QStyleOptionSlider opt;
- initStyleOption(&opt);
- setSliderPosition(newPosition);
-}
-
-
-/*!
- \reimp
-*/
-void QSlider::mouseReleaseEvent(QMouseEvent *ev)
-{
- Q_D(QSlider);
- if (d->pressedControl == QStyle::SC_None || ev->buttons()) {
- ev->ignore();
- return;
- }
- ev->accept();
- QStyle::SubControl oldPressed = QStyle::SubControl(d->pressedControl);
- d->pressedControl = QStyle::SC_None;
- setRepeatAction(SliderNoAction);
- if (oldPressed == QStyle::SC_SliderHandle)
- setSliderDown(false);
- QStyleOptionSlider opt;
- initStyleOption(&opt);
- opt.subControls = oldPressed;
- update(style()->subControlRect(QStyle::CC_Slider, &opt, oldPressed, this));
-}
-
-/*!
- \reimp
-*/
-QSize QSlider::sizeHint() const
-{
- Q_D(const QSlider);
- ensurePolished();
- const int SliderLength = 84, TickSpace = 5;
- QStyleOptionSlider opt;
- initStyleOption(&opt);
- int thick = style()->pixelMetric(QStyle::PM_SliderThickness, &opt, this);
- if (d->tickPosition & TicksAbove)
- thick += TickSpace;
- if (d->tickPosition & TicksBelow)
- thick += TickSpace;
- int w = thick, h = SliderLength;
- if (d->orientation == Qt::Horizontal) {
- w = SliderLength;
- h = thick;
- }
- return style()->sizeFromContents(QStyle::CT_Slider, &opt, QSize(w, h), this).expandedTo(QApplication::globalStrut());
-}
-
-/*!
- \reimp
-*/
-QSize QSlider::minimumSizeHint() const
-{
- Q_D(const QSlider);
- QSize s = sizeHint();
- QStyleOptionSlider opt;
- initStyleOption(&opt);
- int length = style()->pixelMetric(QStyle::PM_SliderLength, &opt, this);
- if (d->orientation == Qt::Horizontal)
- s.setWidth(length);
- else
- s.setHeight(length);
- return s;
-}
-
-/*!
- \property QSlider::tickPosition
- \brief the tickmark position for this slider
-
- The valid values are described by the QSlider::TickPosition enum.
-
- The default value is \l QSlider::NoTicks.
-
- \sa tickInterval
-*/
-
-void QSlider::setTickPosition(TickPosition position)
-{
- Q_D(QSlider);
- d->tickPosition = position;
- d->resetLayoutItemMargins();
- update();
- updateGeometry();
-}
-
-QSlider::TickPosition QSlider::tickPosition() const
-{
- return d_func()->tickPosition;
-}
-
-/*!
- \property QSlider::tickInterval
- \brief the interval between tickmarks
-
- This is a value interval, not a pixel interval. If it is 0, the
- slider will choose between singleStep() and pageStep().
-
- The default value is 0.
-
- \sa tickPosition, lineStep(), pageStep()
-*/
-
-void QSlider::setTickInterval(int ts)
-{
- d_func()->tickInterval = qMax(0, ts);
- update();
-}
-
-int QSlider::tickInterval() const
-{
- return d_func()->tickInterval;
-}
-
-/*!
- \fn void QSlider::addStep()
-
- Use setValue() instead.
-*/
-
-/*!
- \fn void QSlider::subtractStep()
-
- Use setValue() instead.
-*/
-
-/*! \internal
- Returns the style option for slider.
-*/
-Q_GUI_EXPORT QStyleOptionSlider qt_qsliderStyleOption(QSlider *slider)
-{
- QStyleOptionSlider sliderOption;
- slider->initStyleOption(&sliderOption);
- return sliderOption;
-}
-
-#endif
-
-QT_END_NAMESPACE
diff --git a/src/gui/widgets/qslider.h b/src/gui/widgets/qslider.h
deleted file mode 100644
index 4e746ea0dd..0000000000
--- a/src/gui/widgets/qslider.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSLIDER_H
-#define QSLIDER_H
-
-#include <QtGui/qabstractslider.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_SLIDER
-
-class QSliderPrivate;
-class QStyleOptionSlider;
-class Q_GUI_EXPORT QSlider : public QAbstractSlider
-{
- Q_OBJECT
-
- Q_ENUMS(TickPosition)
- Q_PROPERTY(TickPosition tickPosition READ tickPosition WRITE setTickPosition)
- Q_PROPERTY(int tickInterval READ tickInterval WRITE setTickInterval)
-
-public:
- enum TickPosition {
- NoTicks = 0,
- TicksAbove = 1,
- TicksLeft = TicksAbove,
- TicksBelow = 2,
- TicksRight = TicksBelow,
- TicksBothSides = 3
-
-#if defined(QT3_SUPPORT) && !defined(Q_MOC_RUN)
- ,NoMarks = NoTicks,
- Above = TicksAbove,
- Left = TicksAbove,
- Below = TicksBelow,
- Right = TicksRight,
- Both = TicksBothSides
-#endif
- };
-
- explicit QSlider(QWidget *parent = 0);
- explicit QSlider(Qt::Orientation orientation, QWidget *parent = 0);
-
- ~QSlider();
-
- QSize sizeHint() const;
- QSize minimumSizeHint() const;
-
- void setTickPosition(TickPosition position);
- TickPosition tickPosition() const;
-
- void setTickInterval(int ti);
- int tickInterval() const;
-
- bool event(QEvent *event);
-
-protected:
- void paintEvent(QPaintEvent *ev);
- void mousePressEvent(QMouseEvent *ev);
- void mouseReleaseEvent(QMouseEvent *ev);
- void mouseMoveEvent(QMouseEvent *ev);
- void initStyleOption(QStyleOptionSlider *option) const;
-
-#ifdef QT3_SUPPORT
-public:
- QT3_SUPPORT_CONSTRUCTOR QSlider(QWidget *parent, const char *name);
- QT3_SUPPORT_CONSTRUCTOR QSlider(Qt::Orientation, QWidget *parent, const char *name);
- QT3_SUPPORT_CONSTRUCTOR QSlider(int minValue, int maxValue, int pageStep, int value,
- Qt::Orientation orientation,
- QWidget *parent = 0, const char *name = 0);
- inline QT3_SUPPORT void setTickmarks(TickPosition position) { setTickPosition(position); }
- inline QT3_SUPPORT TickPosition tickmarks() const { return tickPosition(); }
-public Q_SLOTS:
- inline QT_MOC_COMPAT void addStep() { triggerAction(SliderSingleStepAdd); }
- inline QT_MOC_COMPAT void subtractStep() { triggerAction(SliderSingleStepSub); }
-#endif
-
-private:
- friend Q_GUI_EXPORT QStyleOptionSlider qt_qsliderStyleOption(QSlider *slider);
-
- Q_DISABLE_COPY(QSlider)
- Q_DECLARE_PRIVATE(QSlider)
-};
-
-#endif // QT_NO_SLIDER
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QSLIDER_H
diff --git a/src/gui/widgets/qspinbox.h b/src/gui/widgets/qspinbox.h
deleted file mode 100644
index 9f054da224..0000000000
--- a/src/gui/widgets/qspinbox.h
+++ /dev/null
@@ -1,188 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSPINBOX_H
-#define QSPINBOX_H
-
-#include <QtGui/qabstractspinbox.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_SPINBOX
-
-class QSpinBoxPrivate;
-class Q_GUI_EXPORT QSpinBox : public QAbstractSpinBox
-{
- Q_OBJECT
-
- Q_PROPERTY(QString suffix READ suffix WRITE setSuffix)
- Q_PROPERTY(QString prefix READ prefix WRITE setPrefix)
- Q_PROPERTY(QString cleanText READ cleanText)
- Q_PROPERTY(int minimum READ minimum WRITE setMinimum)
- Q_PROPERTY(int maximum READ maximum WRITE setMaximum)
- Q_PROPERTY(int singleStep READ singleStep WRITE setSingleStep)
- Q_PROPERTY(int value READ value WRITE setValue NOTIFY valueChanged USER true)
-
-public:
- explicit QSpinBox(QWidget *parent = 0);
-#ifdef QT3_SUPPORT
- QT3_SUPPORT_CONSTRUCTOR QSpinBox(QWidget *parent, const char *name);
- QT3_SUPPORT_CONSTRUCTOR QSpinBox(int min, int max, int step, QWidget *parent,
- const char *name = 0);
-#endif
-
- int value() const;
-
- QString prefix() const;
- void setPrefix(const QString &prefix);
-
- QString suffix() const;
- void setSuffix(const QString &suffix);
-
- QString cleanText() const;
-
- int singleStep() const;
- void setSingleStep(int val);
-
- int minimum() const;
- void setMinimum(int min);
-
- int maximum() const;
- void setMaximum(int max);
-
- void setRange(int min, int max);
-
-#ifdef QT3_SUPPORT
- inline QT3_SUPPORT void setLineStep(int step) { setSingleStep(step); }
- inline QT3_SUPPORT void setMaxValue(int val) { setMaximum(val); }
- inline QT3_SUPPORT void setMinValue(int val) { setMinimum(val); }
- inline QT3_SUPPORT int maxValue() const { return maximum(); }
- inline QT3_SUPPORT int minValue() const { return minimum(); }
-#endif
-
-protected:
- bool event(QEvent *event);
- virtual QValidator::State validate(QString &input, int &pos) const;
- virtual int valueFromText(const QString &text) const;
- virtual QString textFromValue(int val) const;
- virtual void fixup(QString &str) const;
-
-
-public Q_SLOTS:
- void setValue(int val);
-
-Q_SIGNALS:
- void valueChanged(int);
- void valueChanged(const QString &);
-
-private:
- Q_DISABLE_COPY(QSpinBox)
- Q_DECLARE_PRIVATE(QSpinBox)
-};
-
-class QDoubleSpinBoxPrivate;
-class Q_GUI_EXPORT QDoubleSpinBox : public QAbstractSpinBox
-{
- Q_OBJECT
-
- Q_PROPERTY(QString prefix READ prefix WRITE setPrefix)
- Q_PROPERTY(QString suffix READ suffix WRITE setSuffix)
- Q_PROPERTY(QString cleanText READ cleanText)
- Q_PROPERTY(int decimals READ decimals WRITE setDecimals)
- Q_PROPERTY(double minimum READ minimum WRITE setMinimum)
- Q_PROPERTY(double maximum READ maximum WRITE setMaximum)
- Q_PROPERTY(double singleStep READ singleStep WRITE setSingleStep)
- Q_PROPERTY(double value READ value WRITE setValue NOTIFY valueChanged USER true)
-public:
- explicit QDoubleSpinBox(QWidget *parent = 0);
-
- double value() const;
-
- QString prefix() const;
- void setPrefix(const QString &prefix);
-
- QString suffix() const;
- void setSuffix(const QString &suffix);
-
- QString cleanText() const;
-
- double singleStep() const;
- void setSingleStep(double val);
-
- double minimum() const;
- void setMinimum(double min);
-
- double maximum() const;
- void setMaximum(double max);
-
- void setRange(double min, double max);
-
- int decimals() const;
- void setDecimals(int prec);
-
- virtual QValidator::State validate(QString &input, int &pos) const;
- virtual double valueFromText(const QString &text) const;
- virtual QString textFromValue(double val) const;
- virtual void fixup(QString &str) const;
-
-public Q_SLOTS:
- void setValue(double val);
-
-Q_SIGNALS:
- void valueChanged(double);
- void valueChanged(const QString &);
-
-private:
- Q_DISABLE_COPY(QDoubleSpinBox)
- Q_DECLARE_PRIVATE(QDoubleSpinBox)
-};
-
-#endif // QT_NO_SPINBOX
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QSPINBOX_H
diff --git a/src/gui/widgets/qsplashscreen.h b/src/gui/widgets/qsplashscreen.h
deleted file mode 100644
index 31b24859bf..0000000000
--- a/src/gui/widgets/qsplashscreen.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSPLASHSCREEN_H
-#define QSPLASHSCREEN_H
-
-#include <QtGui/qpixmap.h>
-#include <QtGui/qwidget.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_SPLASHSCREEN
-class QSplashScreenPrivate;
-
-class Q_GUI_EXPORT QSplashScreen : public QWidget
-{
- Q_OBJECT
-public:
- explicit QSplashScreen(const QPixmap &pixmap = QPixmap(), Qt::WindowFlags f = 0);
- QSplashScreen(QWidget *parent, const QPixmap &pixmap = QPixmap(), Qt::WindowFlags f = 0);
- virtual ~QSplashScreen();
-
- void setPixmap(const QPixmap &pixmap);
- const QPixmap pixmap() const;
- void finish(QWidget *w);
- void repaint();
-
-public Q_SLOTS:
- void showMessage(const QString &message, int alignment = Qt::AlignLeft,
- const QColor &color = Qt::black);
- void clearMessage();
-#ifdef QT3_SUPPORT
- inline QT_MOC_COMPAT void message(const QString &str, int alignment = Qt::AlignLeft,
- const QColor &color = Qt::black) { showMessage(str, alignment, color); }
- inline QT_MOC_COMPAT void clear() { clearMessage(); }
-#endif
-
-Q_SIGNALS:
- void messageChanged(const QString &message);
-
-protected:
- bool event(QEvent *e);
- virtual void drawContents(QPainter *painter);
- void mousePressEvent(QMouseEvent *);
-
-private:
- Q_DISABLE_COPY(QSplashScreen)
- Q_DECLARE_PRIVATE(QSplashScreen)
-};
-
-#endif // QT_NO_SPLASHSCREEN
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QSPLASHSCREEN_H
diff --git a/src/gui/widgets/qsplitter.h b/src/gui/widgets/qsplitter.h
deleted file mode 100644
index df748cc5fa..0000000000
--- a/src/gui/widgets/qsplitter.h
+++ /dev/null
@@ -1,192 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSPLITTER_H
-#define QSPLITTER_H
-
-#include <QtGui/qframe.h>
-#include <QtGui/qsizepolicy.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_SPLITTER
-
-class QSplitterPrivate;
-class QTextStream;
-template <typename T> class QList;
-
-class QSplitterHandle;
-
-class Q_GUI_EXPORT QSplitter : public QFrame
-{
- Q_OBJECT
-
- Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation)
- Q_PROPERTY(bool opaqueResize READ opaqueResize WRITE setOpaqueResize)
- Q_PROPERTY(int handleWidth READ handleWidth WRITE setHandleWidth)
- Q_PROPERTY(bool childrenCollapsible READ childrenCollapsible WRITE setChildrenCollapsible)
-
-public:
- explicit QSplitter(QWidget* parent = 0);
- explicit QSplitter(Qt::Orientation, QWidget* parent = 0);
- ~QSplitter();
-
- void addWidget(QWidget *widget);
- void insertWidget(int index, QWidget *widget);
-
- void setOrientation(Qt::Orientation);
- Qt::Orientation orientation() const;
-
- void setChildrenCollapsible(bool);
- bool childrenCollapsible() const;
-
- void setCollapsible(int index, bool);
- bool isCollapsible(int index) const;
- void setOpaqueResize(bool opaque = true);
- bool opaqueResize() const;
- void refresh();
-
- QSize sizeHint() const;
- QSize minimumSizeHint() const;
-
- QList<int> sizes() const;
- void setSizes(const QList<int> &list);
-
- QByteArray saveState() const;
- bool restoreState(const QByteArray &state);
-
- int handleWidth() const;
- void setHandleWidth(int);
-
- int indexOf(QWidget *w) const;
- QWidget *widget(int index) const;
- int count() const;
-
- void getRange(int index, int *, int *) const;
- QSplitterHandle *handle(int index) const;
-
- void setStretchFactor(int index, int stretch);
-
-Q_SIGNALS:
- void splitterMoved(int pos, int index);
-
-protected:
- virtual QSplitterHandle *createHandle();
-
- void childEvent(QChildEvent *);
-
- bool event(QEvent *);
- void resizeEvent(QResizeEvent *);
-
- void changeEvent(QEvent *);
- void moveSplitter(int pos, int index);
- void setRubberBand(int position);
- int closestLegalPosition(int, int);
-
-#ifdef QT3_SUPPORT
-public:
- QT3_SUPPORT_CONSTRUCTOR QSplitter(QWidget* parent, const char* name);
- QT3_SUPPORT_CONSTRUCTOR QSplitter(Qt::Orientation, QWidget* parent, const char* name);
- enum ResizeMode { Stretch, KeepSize, FollowSizeHint, Auto };
- QT3_SUPPORT void setResizeMode(QWidget *w, ResizeMode mode);
- inline QT3_SUPPORT void moveToFirst(QWidget *w) { insertWidget(0,w); }
- inline QT3_SUPPORT void moveToLast(QWidget *w) { addWidget(w); }
- inline QT3_SUPPORT void setCollapsible(QWidget *w, bool collapse)
- { setCollapsible(indexOf(w), collapse); }
- QT3_SUPPORT void setMargin(int margin) { setContentsMargins(margin, margin, margin, margin); }
- QT3_SUPPORT int margin() const
- { int margin; int dummy; getContentsMargins(&margin, &dummy, &dummy, &dummy); return margin; }
-#endif
-
-private:
- Q_DISABLE_COPY(QSplitter)
- Q_DECLARE_PRIVATE(QSplitter)
-private:
- friend class QSplitterHandle;
-};
-
-//#ifdef QT3_SUPPORT
-#ifndef QT_NO_TEXTSTREAM
-Q_GUI_EXPORT QTextStream& operator<<(QTextStream&, const QSplitter&);
-Q_GUI_EXPORT QTextStream& operator>>(QTextStream&, QSplitter&);
-#endif
-//#endif
-
-class QSplitterHandlePrivate;
-class Q_GUI_EXPORT QSplitterHandle : public QWidget
-{
- Q_OBJECT
-public:
- QSplitterHandle(Qt::Orientation o, QSplitter *parent);
- void setOrientation(Qt::Orientation o);
- Qt::Orientation orientation() const;
- bool opaqueResize() const;
- QSplitter *splitter() const;
-
- QSize sizeHint() const;
-
-protected:
- void paintEvent(QPaintEvent *);
- void mouseMoveEvent(QMouseEvent *);
- void mousePressEvent(QMouseEvent *);
- void mouseReleaseEvent(QMouseEvent *);
- void resizeEvent(QResizeEvent *);
- bool event(QEvent *);
-
- void moveSplitter(int p);
- int closestLegalPosition(int p);
-
-private:
- Q_DISABLE_COPY(QSplitterHandle)
- Q_DECLARE_PRIVATE(QSplitterHandle)
-};
-
-#endif // QT_NO_SPLITTER
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QSPLITTER_H
diff --git a/src/gui/widgets/qstackedwidget.h b/src/gui/widgets/qstackedwidget.h
deleted file mode 100644
index 63aabcc416..0000000000
--- a/src/gui/widgets/qstackedwidget.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSTACKEDWIDGET_H
-#define QSTACKEDWIDGET_H
-
-#include <QtGui/qframe.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_STACKEDWIDGET
-
-class QStackedWidgetPrivate;
-
-class Q_GUI_EXPORT QStackedWidget : public QFrame
-{
- Q_OBJECT
-
- Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentChanged)
- Q_PROPERTY(int count READ count)
-public:
- explicit QStackedWidget(QWidget *parent=0);
- ~QStackedWidget();
-
- int addWidget(QWidget *w);
- int insertWidget(int index, QWidget *w);
- void removeWidget(QWidget *w);
-
- QWidget *currentWidget() const;
- int currentIndex() const;
-
- int indexOf(QWidget *) const;
- QWidget *widget(int) const;
- int count() const;
-
-public Q_SLOTS:
- void setCurrentIndex(int index);
- void setCurrentWidget(QWidget *w);
-
-Q_SIGNALS:
- void currentChanged(int);
- void widgetRemoved(int index);
-
-protected:
- bool event(QEvent *e);
-
-private:
- Q_DISABLE_COPY(QStackedWidget)
- Q_DECLARE_PRIVATE(QStackedWidget)
-};
-
-#endif // QT_NO_STACKEDWIDGET
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QSTACKEDWIDGET_H
diff --git a/src/gui/widgets/qstatusbar.h b/src/gui/widgets/qstatusbar.h
deleted file mode 100644
index ad5473ddaa..0000000000
--- a/src/gui/widgets/qstatusbar.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSTATUSBAR_H
-#define QSTATUSBAR_H
-
-#include <QtGui/qwidget.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_STATUSBAR
-
-class QStatusBarPrivate;
-
-class Q_GUI_EXPORT QStatusBar: public QWidget
-{
- Q_OBJECT
-
- Q_PROPERTY(bool sizeGripEnabled READ isSizeGripEnabled WRITE setSizeGripEnabled)
-
-public:
- explicit QStatusBar(QWidget* parent=0);
- virtual ~QStatusBar();
-
- void addWidget(QWidget *widget, int stretch = 0);
- int insertWidget(int index, QWidget *widget, int stretch = 0);
- void addPermanentWidget(QWidget *widget, int stretch = 0);
- int insertPermanentWidget(int index, QWidget *widget, int stretch = 0);
- void removeWidget(QWidget *widget);
-
- void setSizeGripEnabled(bool);
- bool isSizeGripEnabled() const;
-
- QString currentMessage() const;
-
-public Q_SLOTS:
- void showMessage(const QString &text, int timeout = 0);
- void clearMessage();
-
-#ifdef QT3_SUPPORT
-public:
- QT3_SUPPORT_CONSTRUCTOR QStatusBar(QWidget* parent, const char* name);
- QT3_SUPPORT void addWidget(QWidget *w, int stretch, bool permanent)
- { if (permanent) addPermanentWidget(w, stretch); else addWidget(w, stretch); }
-public Q_SLOTS:
- inline QT_MOC_COMPAT void message(const QString &text, int timeout = 0) { showMessage(text, timeout); }
- inline QT_MOC_COMPAT void clear() { clearMessage(); }
-#endif
-
-Q_SIGNALS:
- void messageChanged(const QString &text);
-
-protected:
- void showEvent(QShowEvent *);
- void paintEvent(QPaintEvent *);
- void resizeEvent(QResizeEvent *);
-
- // ### Qt 5: consider making reformat() and hideOrShow() private
- void reformat();
- void hideOrShow();
- bool event(QEvent *);
-
-private:
- Q_DISABLE_COPY(QStatusBar)
- Q_DECLARE_PRIVATE(QStatusBar)
-};
-
-#endif // QT_NO_STATUSBAR
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QSTATUSBAR_H
diff --git a/src/gui/widgets/qtabbar.h b/src/gui/widgets/qtabbar.h
deleted file mode 100644
index fd69d625d8..0000000000
--- a/src/gui/widgets/qtabbar.h
+++ /dev/null
@@ -1,226 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QTABBAR_H
-#define QTABBAR_H
-
-#include <QtGui/qwidget.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_TABBAR
-
-class QIcon;
-class QTabBarPrivate;
-class QStyleOptionTab;
-
-class Q_GUI_EXPORT QTabBar: public QWidget
-{
- Q_OBJECT
-
- Q_ENUMS(Shape)
- Q_PROPERTY(Shape shape READ shape WRITE setShape)
- Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentChanged)
- Q_PROPERTY(int count READ count)
- Q_PROPERTY(bool drawBase READ drawBase WRITE setDrawBase)
- Q_PROPERTY(QSize iconSize READ iconSize WRITE setIconSize)
- Q_PROPERTY(Qt::TextElideMode elideMode READ elideMode WRITE setElideMode)
- Q_PROPERTY(bool usesScrollButtons READ usesScrollButtons WRITE setUsesScrollButtons)
- Q_PROPERTY(bool tabsClosable READ tabsClosable WRITE setTabsClosable)
- Q_PROPERTY(SelectionBehavior selectionBehaviorOnRemove READ selectionBehaviorOnRemove WRITE setSelectionBehaviorOnRemove)
- Q_PROPERTY(bool expanding READ expanding WRITE setExpanding)
- Q_PROPERTY(bool movable READ isMovable WRITE setMovable)
- Q_PROPERTY(bool documentMode READ documentMode WRITE setDocumentMode)
-
-public:
- explicit QTabBar(QWidget* parent=0);
- ~QTabBar();
-
- enum Shape { RoundedNorth, RoundedSouth, RoundedWest, RoundedEast,
- TriangularNorth, TriangularSouth, TriangularWest, TriangularEast
-#if defined(QT3_SUPPORT) && !defined(Q_MOC_RUN)
- , RoundedAbove = RoundedNorth, RoundedBelow = RoundedSouth,
- TriangularAbove = TriangularNorth, TriangularBelow = TriangularSouth
-#endif
- };
-
- enum ButtonPosition {
- LeftSide,
- RightSide
- };
-
- enum SelectionBehavior {
- SelectLeftTab,
- SelectRightTab,
- SelectPreviousTab
- };
-
- Shape shape() const;
- void setShape(Shape shape);
-
- int addTab(const QString &text);
- int addTab(const QIcon &icon, const QString &text);
-
- int insertTab(int index, const QString &text);
- int insertTab(int index, const QIcon&icon, const QString &text);
-
- void removeTab(int index);
- void moveTab(int from, int to);
-
- bool isTabEnabled(int index) const;
- void setTabEnabled(int index, bool);
-
- QString tabText(int index) const;
- void setTabText(int index, const QString &text);
-
- QColor tabTextColor(int index) const;
- void setTabTextColor(int index, const QColor &color);
-
- QIcon tabIcon(int index) const;
- void setTabIcon(int index, const QIcon &icon);
-
- Qt::TextElideMode elideMode() const;
- void setElideMode(Qt::TextElideMode);
-
-#ifndef QT_NO_TOOLTIP
- void setTabToolTip(int index, const QString &tip);
- QString tabToolTip(int index) const;
-#endif
-
-#ifndef QT_NO_WHATSTHIS
- void setTabWhatsThis(int index, const QString &text);
- QString tabWhatsThis(int index) const;
-#endif
-
- void setTabData(int index, const QVariant &data);
- QVariant tabData(int index) const;
-
- QRect tabRect(int index) const;
- int tabAt(const QPoint &pos) const;
-
- int currentIndex() const;
- int count() const;
-
- QSize sizeHint() const;
- QSize minimumSizeHint() const;
-
- void setDrawBase(bool drawTheBase);
- bool drawBase() const;
-
- QSize iconSize() const;
- void setIconSize(const QSize &size);
-
- bool usesScrollButtons() const;
- void setUsesScrollButtons(bool useButtons);
-
- bool tabsClosable() const;
- void setTabsClosable(bool closable);
-
- void setTabButton(int index, ButtonPosition position, QWidget *widget);
- QWidget *tabButton(int index, ButtonPosition position) const;
-
- SelectionBehavior selectionBehaviorOnRemove() const;
- void setSelectionBehaviorOnRemove(SelectionBehavior behavior);
-
- bool expanding() const;
- void setExpanding(bool enabled);
-
- bool isMovable() const;
- void setMovable(bool movable);
-
- bool documentMode() const;
- void setDocumentMode(bool set);
-
-public Q_SLOTS:
- void setCurrentIndex(int index);
-
-Q_SIGNALS:
- void currentChanged(int index);
- void tabCloseRequested(int index);
- void tabMoved(int from, int to);
-
-protected:
- virtual QSize tabSizeHint(int index) const;
- virtual void tabInserted(int index);
- virtual void tabRemoved(int index);
- virtual void tabLayoutChange();
-
- bool event(QEvent *);
- void resizeEvent(QResizeEvent *);
- void showEvent(QShowEvent *);
- void hideEvent(QHideEvent *);
- void paintEvent(QPaintEvent *);
- void mousePressEvent (QMouseEvent *);
- void mouseMoveEvent (QMouseEvent *);
- void mouseReleaseEvent (QMouseEvent *);
-#ifndef QT_NO_WHEELEVENT
- void wheelEvent(QWheelEvent *event);
-#endif
- void keyPressEvent(QKeyEvent *);
- void changeEvent(QEvent *);
- void initStyleOption(QStyleOptionTab *option, int tabIndex) const;
-
-#ifdef QT3_SUPPORT
-public Q_SLOTS:
- QT_MOC_COMPAT void setCurrentTab(int index) { setCurrentIndex(index); }
-Q_SIGNALS:
- QT_MOC_COMPAT void selected(int);
-#endif
-
- friend class QAccessibleTabBar;
-private:
- Q_DISABLE_COPY(QTabBar)
- Q_DECLARE_PRIVATE(QTabBar)
- Q_PRIVATE_SLOT(d_func(), void _q_scrollTabs())
- Q_PRIVATE_SLOT(d_func(), void _q_closeTab())
-};
-
-#endif // QT_NO_TABBAR
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QTABBAR_H
diff --git a/src/gui/widgets/qtabwidget.h b/src/gui/widgets/qtabwidget.h
deleted file mode 100644
index 524767ecbb..0000000000
--- a/src/gui/widgets/qtabwidget.h
+++ /dev/null
@@ -1,254 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QTABWIDGET_H
-#define QTABWIDGET_H
-
-#include <QtGui/qwidget.h>
-#include <QtGui/qicon.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_TABWIDGET
-
-class QTabBar;
-class QTabWidgetPrivate;
-class QStyleOptionTabWidgetFrame;
-
-class Q_GUI_EXPORT QTabWidget : public QWidget
-{
- Q_OBJECT
- Q_ENUMS(TabPosition TabShape)
- Q_PROPERTY(TabPosition tabPosition READ tabPosition WRITE setTabPosition)
- Q_PROPERTY(TabShape tabShape READ tabShape WRITE setTabShape)
- Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentChanged)
- Q_PROPERTY(int count READ count)
- Q_PROPERTY(QSize iconSize READ iconSize WRITE setIconSize)
- Q_PROPERTY(Qt::TextElideMode elideMode READ elideMode WRITE setElideMode)
- Q_PROPERTY(bool usesScrollButtons READ usesScrollButtons WRITE setUsesScrollButtons)
- Q_PROPERTY(bool documentMode READ documentMode WRITE setDocumentMode)
- Q_PROPERTY(bool tabsClosable READ tabsClosable WRITE setTabsClosable)
- Q_PROPERTY(bool movable READ isMovable WRITE setMovable)
-
-public:
- explicit QTabWidget(QWidget *parent = 0);
- ~QTabWidget();
-
- int addTab(QWidget *widget, const QString &);
- int addTab(QWidget *widget, const QIcon& icon, const QString &label);
-
- int insertTab(int index, QWidget *widget, const QString &);
- int insertTab(int index, QWidget *widget, const QIcon& icon, const QString &label);
-
- void removeTab(int index);
-
- bool isTabEnabled(int index) const;
- void setTabEnabled(int index, bool);
-
- QString tabText(int index) const;
- void setTabText(int index, const QString &);
-
- QIcon tabIcon(int index) const;
- void setTabIcon(int index, const QIcon & icon);
-
-#ifndef QT_NO_TOOLTIP
- void setTabToolTip(int index, const QString & tip);
- QString tabToolTip(int index) const;
-#endif
-
-#ifndef QT_NO_WHATSTHIS
- void setTabWhatsThis(int index, const QString &text);
- QString tabWhatsThis(int index) const;
-#endif
-
- int currentIndex() const;
- QWidget *currentWidget() const;
- QWidget *widget(int index) const;
- int indexOf(QWidget *widget) const;
- int count() const;
-
- enum TabPosition { North, South, West, East
-#if defined(QT3_SUPPORT) && !defined(Q_MOC_RUN)
- , Top = North, Bottom = South
-#endif
- };
- TabPosition tabPosition() const;
- void setTabPosition(TabPosition);
-
- bool tabsClosable() const;
- void setTabsClosable(bool closeable);
-
- bool isMovable() const;
- void setMovable(bool movable);
-
- enum TabShape { Rounded, Triangular };
- TabShape tabShape() const;
- void setTabShape(TabShape s);
-
- QSize sizeHint() const;
- QSize minimumSizeHint() const;
- int heightForWidth(int width) const;
-
- void setCornerWidget(QWidget * w, Qt::Corner corner = Qt::TopRightCorner);
- QWidget * cornerWidget(Qt::Corner corner = Qt::TopRightCorner) const;
-
- Qt::TextElideMode elideMode() const;
- void setElideMode(Qt::TextElideMode);
-
- QSize iconSize() const;
- void setIconSize(const QSize &size);
-
- bool usesScrollButtons() const;
- void setUsesScrollButtons(bool useButtons);
-
- bool documentMode() const;
- void setDocumentMode(bool set);
-
- void clear();
-
- QTabBar* tabBar() const;
-
-public Q_SLOTS:
- void setCurrentIndex(int index);
- void setCurrentWidget(QWidget *widget);
-
-Q_SIGNALS:
- void currentChanged(int index);
- void tabCloseRequested(int index);
-
-protected:
- virtual void tabInserted(int index);
- virtual void tabRemoved(int index);
-
- void showEvent(QShowEvent *);
- void resizeEvent(QResizeEvent *);
- void keyPressEvent(QKeyEvent *);
- void paintEvent(QPaintEvent *);
- void setTabBar(QTabBar *);
- void changeEvent(QEvent *);
- bool event(QEvent *);
- void initStyleOption(QStyleOptionTabWidgetFrame *option) const;
-
-#ifdef QT3_SUPPORT
-public:
- QT3_SUPPORT_CONSTRUCTOR QTabWidget(QWidget *parent, const char *name, Qt::WindowFlags f = 0);
-
- inline QT3_SUPPORT void insertTab(QWidget * w, const QString &s, int index = -1) { insertTab(index, w, s); }
- inline QT3_SUPPORT void insertTab(QWidget *child, const QIcon& icon,
- const QString &label, int index = -1) { insertTab(index, child, icon, label); }
-
- inline QT3_SUPPORT void changeTab(QWidget *w, const QString &s) {setTabText(indexOf(w), s); }
- inline QT3_SUPPORT void changeTab(QWidget *w, const QIcon& icon,
- const QString &label) { int idx = indexOf(w); setTabText(idx, label); setTabIcon(idx, icon); }
-
- inline QT3_SUPPORT bool isTabEnabled( QWidget *w) const {return isTabEnabled(indexOf(w)); }
- inline QT3_SUPPORT void setTabEnabled(QWidget *w, bool b) { setTabEnabled(indexOf(w), b); }
-
- inline QT3_SUPPORT QString tabLabel(QWidget *w) const {return tabText(indexOf(w)); }
- inline QT3_SUPPORT void setTabLabel(QWidget *w, const QString &l) { setTabText(indexOf(w), l); }
-
- inline QT3_SUPPORT QIcon tabIconSet(QWidget * w) const {return tabIcon(indexOf(w)); }
- inline QT3_SUPPORT void setTabIconSet(QWidget * w, const QIcon & icon) { setTabIcon(indexOf(w), icon); }
-
- inline QT3_SUPPORT void removeTabToolTip(QWidget * w) {
-#ifndef QT_NO_TOOLTIP
- setTabToolTip(indexOf(w), QString());
-#else
- Q_UNUSED(w);
-#endif
- }
- inline QT3_SUPPORT void setTabToolTip(QWidget * w, const QString & tip) {
-#ifndef QT_NO_TOOLTIP
- setTabToolTip(indexOf(w), tip);
-#else
- Q_UNUSED(w);
- Q_UNUSED(tip);
-#endif
- }
-
- inline QT3_SUPPORT QString tabToolTip(QWidget * w) const {
-#ifndef QT_NO_TOOLTIP
- return tabToolTip(indexOf(w));
-#else
- Q_UNUSED(w);
- return QString();
-#endif
- }
-
- inline QT3_SUPPORT QWidget * currentPage() const { return currentWidget(); }
- inline QT3_SUPPORT QWidget *page(int index) const { return widget(index); }
- inline QT3_SUPPORT QString label(int index) const { return tabText(index); }
- inline QT3_SUPPORT int currentPageIndex() const { return currentIndex(); }
-
- inline QT3_SUPPORT int margin() const { return 0; }
- inline QT3_SUPPORT void setMargin(int) {}
-
-public Q_SLOTS:
- inline QT_MOC_COMPAT void setCurrentPage(int index) { setCurrentIndex(index); }
- inline QT_MOC_COMPAT void showPage(QWidget *w) { setCurrentIndex(indexOf(w)); }
- inline QT_MOC_COMPAT void removePage(QWidget *w) { removeTab(indexOf(w)); }
-
-Q_SIGNALS:
- QT_MOC_COMPAT void currentChanged(QWidget *);
- QT_MOC_COMPAT void selected(const QString&);
-#endif // QT3_SUPPORT
-
-private:
- Q_DECLARE_PRIVATE(QTabWidget)
- Q_DISABLE_COPY(QTabWidget)
- Q_PRIVATE_SLOT(d_func(), void _q_showTab(int))
- Q_PRIVATE_SLOT(d_func(), void _q_removeTab(int))
- Q_PRIVATE_SLOT(d_func(), void _q_tabMoved(int, int))
- void setUpLayout(bool = false);
- friend class Q3TabDialog;
-};
-
-#endif // QT_NO_TABWIDGET
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QTABWIDGET_H
diff --git a/src/gui/widgets/qtextbrowser.h b/src/gui/widgets/qtextbrowser.h
deleted file mode 100644
index 46c471bb7e..0000000000
--- a/src/gui/widgets/qtextbrowser.h
+++ /dev/null
@@ -1,140 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QTEXTBROWSER_H
-#define QTEXTBROWSER_H
-
-#include <QtGui/qtextedit.h>
-#include <QtCore/qurl.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_TEXTBROWSER
-
-class QTextBrowserPrivate;
-
-class Q_GUI_EXPORT QTextBrowser : public QTextEdit
-{
- Q_OBJECT
-
- Q_PROPERTY(QUrl source READ source WRITE setSource)
- Q_OVERRIDE(bool modified SCRIPTABLE false)
- Q_OVERRIDE(bool readOnly DESIGNABLE false SCRIPTABLE false)
- Q_OVERRIDE(bool undoRedoEnabled DESIGNABLE false SCRIPTABLE false)
- Q_PROPERTY(QStringList searchPaths READ searchPaths WRITE setSearchPaths)
- Q_PROPERTY(bool openExternalLinks READ openExternalLinks WRITE setOpenExternalLinks)
- Q_PROPERTY(bool openLinks READ openLinks WRITE setOpenLinks)
-
-public:
- explicit QTextBrowser(QWidget* parent = 0);
- virtual ~QTextBrowser();
-
- QUrl source() const;
-
- QStringList searchPaths() const;
- void setSearchPaths(const QStringList &paths);
-
- virtual QVariant loadResource(int type, const QUrl &name);
-
- bool isBackwardAvailable() const;
- bool isForwardAvailable() const;
- void clearHistory();
- QString historyTitle(int) const;
- QUrl historyUrl(int) const;
- int backwardHistoryCount() const;
- int forwardHistoryCount() const;
-
- bool openExternalLinks() const;
- void setOpenExternalLinks(bool open);
-
- bool openLinks() const;
- void setOpenLinks(bool open);
-
-public Q_SLOTS:
- virtual void setSource(const QUrl &name);
- virtual void backward();
- virtual void forward();
- virtual void home();
- virtual void reload();
-
-Q_SIGNALS:
- void backwardAvailable(bool);
- void forwardAvailable(bool);
- void historyChanged();
- void sourceChanged(const QUrl &);
- void highlighted(const QUrl &);
- void highlighted(const QString &);
- void anchorClicked(const QUrl &);
-
-protected:
- bool event(QEvent *e);
- virtual void keyPressEvent(QKeyEvent *ev);
- virtual void mouseMoveEvent(QMouseEvent *ev);
- virtual void mousePressEvent(QMouseEvent *ev);
- virtual void mouseReleaseEvent(QMouseEvent *ev);
- virtual void focusOutEvent(QFocusEvent *ev);
- virtual bool focusNextPrevChild(bool next);
- virtual void paintEvent(QPaintEvent *e);
-
-#if defined(QT3_SUPPORT)
-public:
- QT3_SUPPORT_CONSTRUCTOR QTextBrowser(QWidget *parent, const char *name);
-#endif
-
-private:
- Q_DISABLE_COPY(QTextBrowser)
- Q_DECLARE_PRIVATE(QTextBrowser)
- Q_PRIVATE_SLOT(d_func(), void _q_documentModified())
- Q_PRIVATE_SLOT(d_func(), void _q_activateAnchor(const QString &))
- Q_PRIVATE_SLOT(d_func(), void _q_highlightLink(const QString &))
-};
-
-#endif // QT_NO_TEXTBROWSER
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QTEXTBROWSER_H
diff --git a/src/gui/widgets/qtextedit.cpp b/src/gui/widgets/qtextedit.cpp
deleted file mode 100644
index 2670089133..0000000000
--- a/src/gui/widgets/qtextedit.cpp
+++ /dev/null
@@ -1,2810 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qtextedit_p.h"
-#include "qlineedit.h"
-#include "qtextbrowser.h"
-
-#ifndef QT_NO_TEXTEDIT
-#include <qfont.h>
-#include <qpainter.h>
-#include <qevent.h>
-#include <qdebug.h>
-#include <qmime.h>
-#include <qdrag.h>
-#include <qclipboard.h>
-#include <qmenu.h>
-#include <qstyle.h>
-#include <qtimer.h>
-#include "private/qtextdocumentlayout_p.h"
-#include "qtextdocument.h"
-#include "private/qtextdocument_p.h"
-#include "qtextlist.h"
-#include "private/qtextcontrol_p.h"
-
-#include <qtextformat.h>
-#include <qdatetime.h>
-#include <qapplication.h>
-#include <limits.h>
-#include <qtexttable.h>
-#include <qvariant.h>
-
-#include <qinputcontext.h>
-#endif
-
-QT_BEGIN_NAMESPACE
-
-
-#ifndef QT_NO_TEXTEDIT
-static inline bool shouldEnableInputMethod(QTextEdit *textedit)
-{
- return !textedit->isReadOnly();
-}
-
-class QTextEditControl : public QTextControl
-{
-public:
- inline QTextEditControl(QObject *parent) : QTextControl(parent) {}
-
- virtual QMimeData *createMimeDataFromSelection() const {
- QTextEdit *ed = qobject_cast<QTextEdit *>(parent());
- if (!ed)
- return QTextControl::createMimeDataFromSelection();
- return ed->createMimeDataFromSelection();
- }
- virtual bool canInsertFromMimeData(const QMimeData *source) const {
- QTextEdit *ed = qobject_cast<QTextEdit *>(parent());
- if (!ed)
- return QTextControl::canInsertFromMimeData(source);
- return ed->canInsertFromMimeData(source);
- }
- virtual void insertFromMimeData(const QMimeData *source) {
- QTextEdit *ed = qobject_cast<QTextEdit *>(parent());
- if (!ed)
- QTextControl::insertFromMimeData(source);
- else
- ed->insertFromMimeData(source);
- }
-};
-
-QTextEditPrivate::QTextEditPrivate()
- : control(0),
- autoFormatting(QTextEdit::AutoNone), tabChangesFocus(false),
- lineWrap(QTextEdit::WidgetWidth), lineWrapColumnOrWidth(0),
- wordWrap(QTextOption::WrapAtWordBoundaryOrAnywhere), clickCausedFocus(0),
- textFormat(Qt::AutoText)
-{
- ignoreAutomaticScrollbarAdjustment = false;
- preferRichText = false;
- showCursorOnInitialShow = true;
- inDrag = false;
-}
-
-void QTextEditPrivate::createAutoBulletList()
-{
- QTextCursor cursor = control->textCursor();
- cursor.beginEditBlock();
-
- QTextBlockFormat blockFmt = cursor.blockFormat();
-
- QTextListFormat listFmt;
- listFmt.setStyle(QTextListFormat::ListDisc);
- listFmt.setIndent(blockFmt.indent() + 1);
-
- blockFmt.setIndent(0);
- cursor.setBlockFormat(blockFmt);
-
- cursor.createList(listFmt);
-
- cursor.endEditBlock();
- control->setTextCursor(cursor);
-}
-
-void QTextEditPrivate::init(const QString &html)
-{
- Q_Q(QTextEdit);
- control = new QTextEditControl(q);
- control->setPalette(q->palette());
-
- QObject::connect(control, SIGNAL(microFocusChanged()), q, SLOT(updateMicroFocus()));
- QObject::connect(control, SIGNAL(documentSizeChanged(QSizeF)), q, SLOT(_q_adjustScrollbars()));
- QObject::connect(control, SIGNAL(updateRequest(QRectF)), q, SLOT(_q_repaintContents(QRectF)));
- QObject::connect(control, SIGNAL(visibilityRequest(QRectF)), q, SLOT(_q_ensureVisible(QRectF)));
- QObject::connect(control, SIGNAL(currentCharFormatChanged(QTextCharFormat)),
- q, SLOT(_q_currentCharFormatChanged(QTextCharFormat)));
-
- QObject::connect(control, SIGNAL(textChanged()), q, SIGNAL(textChanged()));
- QObject::connect(control, SIGNAL(undoAvailable(bool)), q, SIGNAL(undoAvailable(bool)));
- QObject::connect(control, SIGNAL(redoAvailable(bool)), q, SIGNAL(redoAvailable(bool)));
- QObject::connect(control, SIGNAL(copyAvailable(bool)), q, SIGNAL(copyAvailable(bool)));
- QObject::connect(control, SIGNAL(selectionChanged()), q, SIGNAL(selectionChanged()));
- QObject::connect(control, SIGNAL(cursorPositionChanged()), q, SIGNAL(cursorPositionChanged()));
-
- QObject::connect(control, SIGNAL(textChanged()), q, SLOT(updateMicroFocus()));
-
- QTextDocument *doc = control->document();
- // set a null page size initially to avoid any relayouting until the textedit
- // is shown. relayoutDocument() will take care of setting the page size to the
- // viewport dimensions later.
- doc->setPageSize(QSize(0, 0));
- doc->documentLayout()->setPaintDevice(viewport);
- doc->setDefaultFont(q->font());
- doc->setUndoRedoEnabled(false); // flush undo buffer.
- doc->setUndoRedoEnabled(true);
-
- if (!html.isEmpty())
- control->setHtml(html);
-
- hbar->setSingleStep(20);
- vbar->setSingleStep(20);
-
- viewport->setBackgroundRole(QPalette::Base);
- q->setAcceptDrops(true);
- q->setFocusPolicy(Qt::WheelFocus);
- q->setAttribute(Qt::WA_KeyCompression);
- q->setAttribute(Qt::WA_InputMethodEnabled);
-
-#ifndef QT_NO_CURSOR
- viewport->setCursor(Qt::IBeamCursor);
-#endif
-#ifdef Q_WS_WIN
- setSingleFingerPanEnabled(true);
-#endif
-}
-
-void QTextEditPrivate::_q_repaintContents(const QRectF &contentsRect)
-{
- if (!contentsRect.isValid()) {
- viewport->update();
- return;
- }
- const int xOffset = horizontalOffset();
- const int yOffset = verticalOffset();
- const QRectF visibleRect(xOffset, yOffset, viewport->width(), viewport->height());
-
- QRect r = contentsRect.intersected(visibleRect).toAlignedRect();
- if (r.isEmpty())
- return;
-
- r.translate(-xOffset, -yOffset);
- viewport->update(r);
-}
-
-void QTextEditPrivate::pageUpDown(QTextCursor::MoveOperation op, QTextCursor::MoveMode moveMode)
-{
- QTextCursor cursor = control->textCursor();
- bool moved = false;
- qreal lastY = control->cursorRect(cursor).top();
- qreal distance = 0;
- // move using movePosition to keep the cursor's x
- do {
- qreal y = control->cursorRect(cursor).top();
- distance += qAbs(y - lastY);
- lastY = y;
- moved = cursor.movePosition(op, moveMode);
- } while (moved && distance < viewport->height());
-
- if (moved) {
- if (op == QTextCursor::Up) {
- cursor.movePosition(QTextCursor::Down, moveMode);
- vbar->triggerAction(QAbstractSlider::SliderPageStepSub);
- } else {
- cursor.movePosition(QTextCursor::Up, moveMode);
- vbar->triggerAction(QAbstractSlider::SliderPageStepAdd);
- }
- }
- control->setTextCursor(cursor);
-}
-
-#ifndef QT_NO_SCROLLBAR
-static QSize documentSize(QTextControl *control)
-{
- QTextDocument *doc = control->document();
- QAbstractTextDocumentLayout *layout = doc->documentLayout();
-
- QSize docSize;
-
- if (QTextDocumentLayout *tlayout = qobject_cast<QTextDocumentLayout *>(layout)) {
- docSize = tlayout->dynamicDocumentSize().toSize();
- int percentageDone = tlayout->layoutStatus();
- // extrapolate height
- if (percentageDone > 0)
- docSize.setHeight(docSize.height() * 100 / percentageDone);
- } else {
- docSize = layout->documentSize().toSize();
- }
-
- return docSize;
-}
-
-void QTextEditPrivate::_q_adjustScrollbars()
-{
- if (ignoreAutomaticScrollbarAdjustment)
- return;
- ignoreAutomaticScrollbarAdjustment = true; // avoid recursion, #106108
-
- QSize viewportSize = viewport->size();
- QSize docSize = documentSize(control);
-
- // due to the recursion guard we have to repeat this step a few times,
- // as adding/removing a scroll bar will cause the document or viewport
- // size to change
- // ideally we should loop until the viewport size and doc size stabilize,
- // but in corner cases they might fluctuate, so we need to limit the
- // number of iterations
- for (int i = 0; i < 4; ++i) {
- hbar->setRange(0, docSize.width() - viewportSize.width());
- hbar->setPageStep(viewportSize.width());
-
- vbar->setRange(0, docSize.height() - viewportSize.height());
- vbar->setPageStep(viewportSize.height());
-
- // if we are in left-to-right mode widening the document due to
- // lazy layouting does not require a repaint. If in right-to-left
- // the scroll bar has the value zero and it visually has the maximum
- // value (it is visually at the right), then widening the document
- // keeps it at value zero but visually adjusts it to the new maximum
- // on the right, hence we need an update.
- if (q_func()->isRightToLeft())
- viewport->update();
-
- _q_showOrHideScrollBars();
-
- const QSize oldViewportSize = viewportSize;
- const QSize oldDocSize = docSize;
-
- // make sure the document is layouted if the viewport width changes
- viewportSize = viewport->size();
- if (viewportSize.width() != oldViewportSize.width())
- relayoutDocument();
-
- docSize = documentSize(control);
- if (viewportSize == oldViewportSize && docSize == oldDocSize)
- break;
- }
- ignoreAutomaticScrollbarAdjustment = false;
-}
-#endif
-
-// rect is in content coordinates
-void QTextEditPrivate::_q_ensureVisible(const QRectF &_rect)
-{
- const QRect rect = _rect.toRect();
- if ((vbar->isVisible() && vbar->maximum() < rect.bottom())
- || (hbar->isVisible() && hbar->maximum() < rect.right()))
- _q_adjustScrollbars();
- const int visibleWidth = viewport->width();
- const int visibleHeight = viewport->height();
- const bool rtl = q_func()->isRightToLeft();
-
- if (rect.x() < horizontalOffset()) {
- if (rtl)
- hbar->setValue(hbar->maximum() - rect.x());
- else
- hbar->setValue(rect.x());
- } else if (rect.x() + rect.width() > horizontalOffset() + visibleWidth) {
- if (rtl)
- hbar->setValue(hbar->maximum() - (rect.x() + rect.width() - visibleWidth));
- else
- hbar->setValue(rect.x() + rect.width() - visibleWidth);
- }
-
- if (rect.y() < verticalOffset())
- vbar->setValue(rect.y());
- else if (rect.y() + rect.height() > verticalOffset() + visibleHeight)
- vbar->setValue(rect.y() + rect.height() - visibleHeight);
-}
-
-/*!
- \class QTextEdit
- \brief The QTextEdit class provides a widget that is used to edit and display
- both plain and rich text.
-
- \ingroup richtext-processing
-
-
- \tableofcontents
-
- \section1 Introduction and Concepts
-
- QTextEdit is an advanced WYSIWYG viewer/editor supporting rich
- text formatting using HTML-style tags. It is optimized to handle
- large documents and to respond quickly to user input.
-
- QTextEdit works on paragraphs and characters. A paragraph is a
- formatted string which is word-wrapped to fit into the width of
- the widget. By default when reading plain text, one newline
- signifies a paragraph. A document consists of zero or more
- paragraphs. The words in the paragraph are aligned in accordance
- with the paragraph's alignment. Paragraphs are separated by hard
- line breaks. Each character within a paragraph has its own
- attributes, for example, font and color.
-
- QTextEdit can display images, lists and tables. If the text is
- too large to view within the text edit's viewport, scroll bars will
- appear. The text edit can load both plain text and HTML files (a
- subset of HTML 3.2 and 4).
-
- If you just need to display a small piece of rich text use QLabel.
-
- The rich text support in Qt is designed to provide a fast, portable and
- efficient way to add reasonable online help facilities to
- applications, and to provide a basis for rich text editors. If
- you find the HTML support insufficient for your needs you may consider
- the use of QtWebKit, which provides a full-featured web browser
- widget.
-
- The shape of the mouse cursor on a QTextEdit is Qt::IBeamCursor by default.
- It can be changed through the viewport()'s cursor property.
-
- \section1 Using QTextEdit as a Display Widget
-
- QTextEdit can display a large HTML subset, including tables and
- images.
-
- The text is set or replaced using setHtml() which deletes any
- existing text and replaces it with the text passed in the
- setHtml() call. If you call setHtml() with legacy HTML, and then
- call toHtml(), the text that is returned may have different markup,
- but will render the same. The entire text can be deleted with clear().
-
- Text itself can be inserted using the QTextCursor class or using the
- convenience functions insertHtml(), insertPlainText(), append() or
- paste(). QTextCursor is also able to insert complex objects like tables
- or lists into the document, and it deals with creating selections
- and applying changes to selected text.
-
- By default the text edit wraps words at whitespace to fit within
- the text edit widget. The setLineWrapMode() function is used to
- specify the kind of line wrap you want, or \l NoWrap if you don't
- want any wrapping. Call setLineWrapMode() to set a fixed pixel width
- \l FixedPixelWidth, or character column (e.g. 80 column) \l
- FixedColumnWidth with the pixels or columns specified with
- setLineWrapColumnOrWidth(). If you use word wrap to the widget's width
- \l WidgetWidth, you can specify whether to break on whitespace or
- anywhere with setWordWrapMode().
-
- The find() function can be used to find and select a given string
- within the text.
-
- If you want to limit the total number of paragraphs in a QTextEdit,
- as it is for example open useful in a log viewer, then you can use
- QTextDocument's maximumBlockCount property for that.
-
- \section2 Read-only Key Bindings
-
- When QTextEdit is used read-only the key bindings are limited to
- navigation, and text may only be selected with the mouse:
- \table
- \header \i Keypresses \i Action
- \row \i Up \i Moves one line up.
- \row \i Down \i Moves one line down.
- \row \i Left \i Moves one character to the left.
- \row \i Right \i Moves one character to the right.
- \row \i PageUp \i Moves one (viewport) page up.
- \row \i PageDown \i Moves one (viewport) page down.
- \row \i Home \i Moves to the beginning of the text.
- \row \i End \i Moves to the end of the text.
- \row \i Alt+Wheel
- \i Scrolls the page horizontally (the Wheel is the mouse wheel).
- \row \i Ctrl+Wheel \i Zooms the text.
- \row \i Ctrl+A \i Selects all text.
- \endtable
-
- The text edit may be able to provide some meta-information. For
- example, the documentTitle() function will return the text from
- within HTML \c{<title>} tags.
-
- \section1 Using QTextEdit as an Editor
-
- All the information about using QTextEdit as a display widget also
- applies here.
-
- The current char format's attributes are set with setFontItalic(),
- setFontWeight(), setFontUnderline(), setFontFamily(),
- setFontPointSize(), setTextColor() and setCurrentFont(). The current
- paragraph's alignment is set with setAlignment().
-
- Selection of text is handled by the QTextCursor class, which provides
- functionality for creating selections, retrieving the text contents or
- deleting selections. You can retrieve the object that corresponds with
- the user-visible cursor using the textCursor() method. If you want to set
- a selection in QTextEdit just create one on a QTextCursor object and
- then make that cursor the visible cursor using setTextCursor(). The selection
- can be copied to the clipboard with copy(), or cut to the clipboard with
- cut(). The entire text can be selected using selectAll().
-
- When the cursor is moved and the underlying formatting attributes change,
- the currentCharFormatChanged() signal is emitted to reflect the new attributes
- at the new cursor position.
-
- QTextEdit holds a QTextDocument object which can be retrieved using the
- document() method. You can also set your own document object using setDocument().
- QTextDocument emits a textChanged() signal if the text changes and it also
- provides a isModified() function which will return true if the text has been
- modified since it was either loaded or since the last call to setModified
- with false as argument. In addition it provides methods for undo and redo.
-
- \section2 Drag and Drop
-
- QTextEdit also supports custom drag and drop behavior. By default,
- QTextEdit will insert plain text, HTML and rich text when the user drops
- data of these MIME types onto a document. Reimplement
- canInsertFromMimeData() and insertFromMimeData() to add support for
- additional MIME types.
-
- For example, to allow the user to drag and drop an image onto a QTextEdit,
- you could the implement these functions in the following way:
-
- \snippet doc/src/snippets/textdocument-imagedrop/textedit.cpp 0
-
- We add support for image MIME types by returning true. For all other
- MIME types, we use the default implementation.
-
- \snippet doc/src/snippets/textdocument-imagedrop/textedit.cpp 1
-
- We unpack the image from the QVariant held by the MIME source and insert
- it into the document as a resource.
-
- \section2 Editing Key Bindings
-
- The list of key bindings which are implemented for editing:
- \table
- \header \i Keypresses \i Action
- \row \i Backspace \i Deletes the character to the left of the cursor.
- \row \i Delete \i Deletes the character to the right of the cursor.
- \row \i Ctrl+C \i Copy the selected text to the clipboard.
- \row \i Ctrl+Insert \i Copy the selected text to the clipboard.
- \row \i Ctrl+K \i Deletes to the end of the line.
- \row \i Ctrl+V \i Pastes the clipboard text into text edit.
- \row \i Shift+Insert \i Pastes the clipboard text into text edit.
- \row \i Ctrl+X \i Deletes the selected text and copies it to the clipboard.
- \row \i Shift+Delete \i Deletes the selected text and copies it to the clipboard.
- \row \i Ctrl+Z \i Undoes the last operation.
- \row \i Ctrl+Y \i Redoes the last operation.
- \row \i Left \i Moves the cursor one character to the left.
- \row \i Ctrl+Left \i Moves the cursor one word to the left.
- \row \i Right \i Moves the cursor one character to the right.
- \row \i Ctrl+Right \i Moves the cursor one word to the right.
- \row \i Up \i Moves the cursor one line up.
- \row \i Down \i Moves the cursor one line down.
- \row \i PageUp \i Moves the cursor one page up.
- \row \i PageDown \i Moves the cursor one page down.
- \row \i Home \i Moves the cursor to the beginning of the line.
- \row \i Ctrl+Home \i Moves the cursor to the beginning of the text.
- \row \i End \i Moves the cursor to the end of the line.
- \row \i Ctrl+End \i Moves the cursor to the end of the text.
- \row \i Alt+Wheel \i Scrolls the page horizontally (the Wheel is the mouse wheel).
- \endtable
-
- To select (mark) text hold down the Shift key whilst pressing one
- of the movement keystrokes, for example, \e{Shift+Right}
- will select the character to the right, and \e{Shift+Ctrl+Right} will select the word to the right, etc.
-
- \sa QTextDocument, QTextCursor, {Application Example},
- {Syntax Highlighter Example}, {Rich Text Processing}
-*/
-
-/*!
- \property QTextEdit::plainText
- \since 4.3
-
- This property gets and sets the text editor's contents as plain
- text. Previous contents are removed and undo/redo history is reset
- when the property is set.
-
- If the text edit has another content type, it will not be replaced
- by plain text if you call toPlainText(). The only exception to this
- is the non-break space, \e{nbsp;}, that will be converted into
- standard space.
-
- By default, for an editor with no contents, this property contains
- an empty string.
-
- \sa html
-*/
-
-/*!
- \property QTextEdit::undoRedoEnabled
- \brief whether undo and redo are enabled
-
- Users are only able to undo or redo actions if this property is
- true, and if there is an action that can be undone (or redone).
-*/
-
-/*!
- \enum QTextEdit::LineWrapMode
-
- \value NoWrap
- \value WidgetWidth
- \value FixedPixelWidth
- \value FixedColumnWidth
-*/
-
-/*!
- \enum QTextEdit::AutoFormattingFlag
-
- \value AutoNone Don't do any automatic formatting.
- \value AutoBulletList Automatically create bullet lists (e.g. when
- the user enters an asterisk ('*') in the left most column, or
- presses Enter in an existing list item.
- \value AutoAll Apply all automatic formatting. Currently only
- automatic bullet lists are supported.
-*/
-
-#ifdef QT3_SUPPORT
-/*!
- \enum QTextEdit::CursorAction
- \compat
-
- \value MoveBackward
- \value MoveForward
- \value MoveWordBackward
- \value MoveWordForward
- \value MoveUp
- \value MoveDown
- \value MoveLineStart
- \value MoveLineEnd
- \value MoveHome
- \value MoveEnd
- \value MovePageUp
- \value MovePageDown
-
- \omitvalue MovePgUp
- \omitvalue MovePgDown
-*/
-#endif
-
-/*!
- Constructs an empty QTextEdit with parent \a
- parent.
-*/
-QTextEdit::QTextEdit(QWidget *parent)
- : QAbstractScrollArea(*new QTextEditPrivate, parent)
-{
- Q_D(QTextEdit);
- d->init();
-}
-
-/*!
- \internal
-*/
-QTextEdit::QTextEdit(QTextEditPrivate &dd, QWidget *parent)
- : QAbstractScrollArea(dd, parent)
-{
- Q_D(QTextEdit);
- d->init();
-}
-
-/*!
- Constructs a QTextEdit with parent \a parent. The text edit will display
- the text \a text. The text is interpreted as html.
-*/
-QTextEdit::QTextEdit(const QString &text, QWidget *parent)
- : QAbstractScrollArea(*new QTextEditPrivate, parent)
-{
- Q_D(QTextEdit);
- d->init(text);
-}
-
-#ifdef QT3_SUPPORT
-/*!
- Use one of the constructors that doesn't take the \a name
- argument and then use setObjectName() instead.
-*/
-QTextEdit::QTextEdit(QWidget *parent, const char *name)
- : QAbstractScrollArea(*new QTextEditPrivate, parent)
-{
- Q_D(QTextEdit);
- d->init();
- setObjectName(QString::fromAscii(name));
-}
-#endif
-
-
-/*!
- Destructor.
-*/
-QTextEdit::~QTextEdit()
-{
-}
-
-/*!
- Returns the point size of the font of the current format.
-
- \sa setFontFamily() setCurrentFont() setFontPointSize()
-*/
-qreal QTextEdit::fontPointSize() const
-{
- Q_D(const QTextEdit);
- return d->control->textCursor().charFormat().fontPointSize();
-}
-
-/*!
- Returns the font family of the current format.
-
- \sa setFontFamily() setCurrentFont() setFontPointSize()
-*/
-QString QTextEdit::fontFamily() const
-{
- Q_D(const QTextEdit);
- return d->control->textCursor().charFormat().fontFamily();
-}
-
-/*!
- Returns the font weight of the current format.
-
- \sa setFontWeight() setCurrentFont() setFontPointSize() QFont::Weight
-*/
-int QTextEdit::fontWeight() const
-{
- Q_D(const QTextEdit);
- return d->control->textCursor().charFormat().fontWeight();
-}
-
-/*!
- Returns true if the font of the current format is underlined; otherwise returns
- false.
-
- \sa setFontUnderline()
-*/
-bool QTextEdit::fontUnderline() const
-{
- Q_D(const QTextEdit);
- return d->control->textCursor().charFormat().fontUnderline();
-}
-
-/*!
- Returns true if the font of the current format is italic; otherwise returns
- false.
-
- \sa setFontItalic()
-*/
-bool QTextEdit::fontItalic() const
-{
- Q_D(const QTextEdit);
- return d->control->textCursor().charFormat().fontItalic();
-}
-
-/*!
- Returns the text color of the current format.
-
- \sa setTextColor()
-*/
-QColor QTextEdit::textColor() const
-{
- Q_D(const QTextEdit);
- return d->control->textCursor().charFormat().foreground().color();
-}
-
-/*!
- \since 4.4
-
- Returns the text background color of the current format.
-
- \sa setTextBackgroundColor()
-*/
-QColor QTextEdit::textBackgroundColor() const
-{
- Q_D(const QTextEdit);
- return d->control->textCursor().charFormat().background().color();
-}
-
-/*!
- Returns the font of the current format.
-
- \sa setCurrentFont() setFontFamily() setFontPointSize()
-*/
-QFont QTextEdit::currentFont() const
-{
- Q_D(const QTextEdit);
- return d->control->textCursor().charFormat().font();
-}
-
-/*!
- Sets the alignment of the current paragraph to \a a. Valid
- alignments are Qt::AlignLeft, Qt::AlignRight,
- Qt::AlignJustify and Qt::AlignCenter (which centers
- horizontally).
-*/
-void QTextEdit::setAlignment(Qt::Alignment a)
-{
- Q_D(QTextEdit);
- QTextBlockFormat fmt;
- fmt.setAlignment(a);
- QTextCursor cursor = d->control->textCursor();
- cursor.mergeBlockFormat(fmt);
- d->control->setTextCursor(cursor);
-}
-
-/*!
- Returns the alignment of the current paragraph.
-
- \sa setAlignment()
-*/
-Qt::Alignment QTextEdit::alignment() const
-{
- Q_D(const QTextEdit);
- return d->control->textCursor().blockFormat().alignment();
-}
-
-/*!
- Makes \a document the new document of the text editor.
-
- \note The editor \e{does not take ownership of the document} unless it
- is the document's parent object. The parent object of the provided document
- remains the owner of the object.
-
- The editor does not delete the current document, even if it is a child of the editor.
-
- \sa document()
-*/
-void QTextEdit::setDocument(QTextDocument *document)
-{
- Q_D(QTextEdit);
- d->control->setDocument(document);
- d->updateDefaultTextOption();
- d->relayoutDocument();
-}
-
-/*!
- Returns a pointer to the underlying document.
-
- \sa setDocument()
-*/
-QTextDocument *QTextEdit::document() const
-{
- Q_D(const QTextEdit);
- return d->control->document();
-}
-
-/*!
- Sets the visible \a cursor.
-*/
-void QTextEdit::setTextCursor(const QTextCursor &cursor)
-{
- Q_D(QTextEdit);
- d->control->setTextCursor(cursor);
-}
-
-/*!
- Returns a copy of the QTextCursor that represents the currently visible cursor.
- Note that changes on the returned cursor do not affect QTextEdit's cursor; use
- setTextCursor() to update the visible cursor.
- */
-QTextCursor QTextEdit::textCursor() const
-{
- Q_D(const QTextEdit);
- return d->control->textCursor();
-}
-
-/*!
- Sets the font family of the current format to \a fontFamily.
-
- \sa fontFamily() setCurrentFont()
-*/
-void QTextEdit::setFontFamily(const QString &fontFamily)
-{
- QTextCharFormat fmt;
- fmt.setFontFamily(fontFamily);
- mergeCurrentCharFormat(fmt);
-}
-
-/*!
- Sets the point size of the current format to \a s.
-
- Note that if \a s is zero or negative, the behavior of this
- function is not defined.
-
- \sa fontPointSize() setCurrentFont() setFontFamily()
-*/
-void QTextEdit::setFontPointSize(qreal s)
-{
- QTextCharFormat fmt;
- fmt.setFontPointSize(s);
- mergeCurrentCharFormat(fmt);
-}
-
-/*!
- \fn void QTextEdit::setFontWeight(int weight)
-
- Sets the font weight of the current format to the given \a weight,
- where the value used is in the range defined by the QFont::Weight
- enum.
-
- \sa fontWeight(), setCurrentFont(), setFontFamily()
-*/
-void QTextEdit::setFontWeight(int w)
-{
- QTextCharFormat fmt;
- fmt.setFontWeight(w);
- mergeCurrentCharFormat(fmt);
-}
-
-/*!
- If \a underline is true, sets the current format to underline;
- otherwise sets the current format to non-underline.
-
- \sa fontUnderline()
-*/
-void QTextEdit::setFontUnderline(bool underline)
-{
- QTextCharFormat fmt;
- fmt.setFontUnderline(underline);
- mergeCurrentCharFormat(fmt);
-}
-
-/*!
- If \a italic is true, sets the current format to italic;
- otherwise sets the current format to non-italic.
-
- \sa fontItalic()
-*/
-void QTextEdit::setFontItalic(bool italic)
-{
- QTextCharFormat fmt;
- fmt.setFontItalic(italic);
- mergeCurrentCharFormat(fmt);
-}
-
-/*!
- Sets the text color of the current format to \a c.
-
- \sa textColor()
-*/
-void QTextEdit::setTextColor(const QColor &c)
-{
- QTextCharFormat fmt;
- fmt.setForeground(QBrush(c));
- mergeCurrentCharFormat(fmt);
-}
-
-/*!
- \since 4.4
-
- Sets the text background color of the current format to \a c.
-
- \sa textBackgroundColor()
-*/
-void QTextEdit::setTextBackgroundColor(const QColor &c)
-{
- QTextCharFormat fmt;
- fmt.setBackground(QBrush(c));
- mergeCurrentCharFormat(fmt);
-}
-
-/*!
- Sets the font of the current format to \a f.
-
- \sa currentFont() setFontPointSize() setFontFamily()
-*/
-void QTextEdit::setCurrentFont(const QFont &f)
-{
- QTextCharFormat fmt;
- fmt.setFont(f);
- mergeCurrentCharFormat(fmt);
-}
-
-/*!
- \since 4.2
-
- Undoes the last operation.
-
- If there is no operation to undo, i.e. there is no undo step in
- the undo/redo history, nothing happens.
-
- \sa redo()
-*/
-void QTextEdit::undo()
-{
- Q_D(QTextEdit);
- d->control->undo();
-}
-
-void QTextEdit::redo()
-{
- Q_D(QTextEdit);
- d->control->redo();
-}
-
-/*!
- \fn void QTextEdit::undo() const
- \fn void QTextEdit::redo() const
- \overload
-
- Use the non-const overload instead.
-*/
-
-/*!
- \fn void QTextEdit::redo()
- \since 4.2
-
- Redoes the last operation.
-
- If there is no operation to redo, i.e. there is no redo step in
- the undo/redo history, nothing happens.
-
- \sa undo()
-*/
-
-#ifndef QT_NO_CLIPBOARD
-/*!
- Copies the selected text to the clipboard and deletes it from
- the text edit.
-
- If there is no selected text nothing happens.
-
- \sa copy() paste()
-*/
-
-void QTextEdit::cut()
-{
- Q_D(QTextEdit);
- d->control->cut();
-}
-
-/*!
- Copies any selected text to the clipboard.
-
- \sa copyAvailable()
-*/
-
-void QTextEdit::copy()
-{
- Q_D(QTextEdit);
- d->control->copy();
-}
-
-/*!
- Pastes the text from the clipboard into the text edit at the
- current cursor position.
-
- If there is no text in the clipboard nothing happens.
-
- To change the behavior of this function, i.e. to modify what
- QTextEdit can paste and how it is being pasted, reimplement the
- virtual canInsertFromMimeData() and insertFromMimeData()
- functions.
-
- \sa cut() copy()
-*/
-
-void QTextEdit::paste()
-{
- Q_D(QTextEdit);
- d->control->paste();
-}
-#endif
-
-/*!
- Deletes all the text in the text edit.
-
- Note that the undo/redo history is cleared by this function.
-
- \sa cut() setPlainText() setHtml()
-*/
-void QTextEdit::clear()
-{
- Q_D(QTextEdit);
- // clears and sets empty content
- d->control->clear();
-}
-
-
-/*!
- Selects all text.
-
- \sa copy() cut() textCursor()
- */
-void QTextEdit::selectAll()
-{
- Q_D(QTextEdit);
- d->control->selectAll();
-}
-
-/*! \internal
-*/
-bool QTextEdit::event(QEvent *e)
-{
- Q_D(QTextEdit);
-#ifndef QT_NO_CONTEXTMENU
- if (e->type() == QEvent::ContextMenu
- && static_cast<QContextMenuEvent *>(e)->reason() == QContextMenuEvent::Keyboard) {
- Q_D(QTextEdit);
- ensureCursorVisible();
- const QPoint cursorPos = cursorRect().center();
- QContextMenuEvent ce(QContextMenuEvent::Keyboard, cursorPos, d->viewport->mapToGlobal(cursorPos));
- ce.setAccepted(e->isAccepted());
- const bool result = QAbstractScrollArea::event(&ce);
- e->setAccepted(ce.isAccepted());
- return result;
- } else if (e->type() == QEvent::ShortcutOverride
- || e->type() == QEvent::ToolTip) {
- d->sendControlEvent(e);
- }
-#endif // QT_NO_CONTEXTMENU
-#ifdef QT_KEYPAD_NAVIGATION
- if (e->type() == QEvent::EnterEditFocus || e->type() == QEvent::LeaveEditFocus) {
- if (QApplication::keypadNavigationEnabled())
- d->sendControlEvent(e);
- }
-#endif
- return QAbstractScrollArea::event(e);
-}
-
-/*! \internal
-*/
-
-void QTextEdit::timerEvent(QTimerEvent *e)
-{
- Q_D(QTextEdit);
- if (e->timerId() == d->autoScrollTimer.timerId()) {
- QRect visible = d->viewport->rect();
- QPoint pos;
- if (d->inDrag) {
- pos = d->autoScrollDragPos;
- visible.adjust(qMin(visible.width()/3,20), qMin(visible.height()/3,20),
- -qMin(visible.width()/3,20), -qMin(visible.height()/3,20));
- } else {
- const QPoint globalPos = QCursor::pos();
- pos = d->viewport->mapFromGlobal(globalPos);
- QMouseEvent ev(QEvent::MouseMove, pos, globalPos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
- mouseMoveEvent(&ev);
- }
- int deltaY = qMax(pos.y() - visible.top(), visible.bottom() - pos.y()) - visible.height();
- int deltaX = qMax(pos.x() - visible.left(), visible.right() - pos.x()) - visible.width();
- int delta = qMax(deltaX, deltaY);
- if (delta >= 0) {
- if (delta < 7)
- delta = 7;
- int timeout = 4900 / (delta * delta);
- d->autoScrollTimer.start(timeout, this);
-
- if (deltaY > 0)
- d->vbar->triggerAction(pos.y() < visible.center().y() ?
- QAbstractSlider::SliderSingleStepSub
- : QAbstractSlider::SliderSingleStepAdd);
- if (deltaX > 0)
- d->hbar->triggerAction(pos.x() < visible.center().x() ?
- QAbstractSlider::SliderSingleStepSub
- : QAbstractSlider::SliderSingleStepAdd);
- }
- }
-#ifdef QT_KEYPAD_NAVIGATION
- else if (e->timerId() == d->deleteAllTimer.timerId()) {
- d->deleteAllTimer.stop();
- clear();
- }
-#endif
-}
-
-/*!
- Changes the text of the text edit to the string \a text.
- Any previous text is removed.
-
- \a text is interpreted as plain text.
-
- Note that the undo/redo history is cleared by this function.
-
- \sa toPlainText()
-*/
-
-void QTextEdit::setPlainText(const QString &text)
-{
- Q_D(QTextEdit);
- d->control->setPlainText(text);
- d->preferRichText = false;
-}
-
-/*!
- \fn QString QTextEdit::toPlainText() const
-
- Returns the text of the text edit as plain text.
-
- \sa QTextEdit::setPlainText()
- */
-
-
-/*!
- \property QTextEdit::html
-
- This property provides an HTML interface to the text of the text edit.
-
- toHtml() returns the text of the text edit as html.
-
- setHtml() changes the text of the text edit. Any previous text is
- removed and the undo/redo history is cleared. The input text is
- interpreted as rich text in html format.
-
- \note It is the responsibility of the caller to make sure that the
- text is correctly decoded when a QString containing HTML is created
- and passed to setHtml().
-
- By default, for a newly-created, empty document, this property contains
- text to describe an HTML 4.0 document with no body text.
-
- \sa {Supported HTML Subset}, plainText
-*/
-
-#ifndef QT_NO_TEXTHTMLPARSER
-void QTextEdit::setHtml(const QString &text)
-{
- Q_D(QTextEdit);
- d->control->setHtml(text);
- d->preferRichText = true;
-}
-#endif
-
-/*! \reimp
-*/
-void QTextEdit::keyPressEvent(QKeyEvent *e)
-{
- Q_D(QTextEdit);
-
-#ifdef QT_KEYPAD_NAVIGATION
- switch (e->key()) {
- case Qt::Key_Select:
- if (QApplication::keypadNavigationEnabled()) {
- // code assumes linksaccessible + editable isn't meaningful
- if (d->control->textInteractionFlags() & Qt::TextEditable) {
- setEditFocus(!hasEditFocus());
- } else {
- if (!hasEditFocus())
- setEditFocus(true);
- else {
- QTextCursor cursor = d->control->textCursor();
- QTextCharFormat charFmt = cursor.charFormat();
- if (!(d->control->textInteractionFlags() & Qt::LinksAccessibleByKeyboard)
- || !cursor.hasSelection() || charFmt.anchorHref().isEmpty()) {
- e->accept();
- return;
- }
- }
- }
- }
- break;
- case Qt::Key_Back:
- case Qt::Key_No:
- if (!QApplication::keypadNavigationEnabled()
- || (QApplication::keypadNavigationEnabled() && !hasEditFocus())) {
- e->ignore();
- return;
- }
- break;
- default:
- if (QApplication::keypadNavigationEnabled()) {
- if (!hasEditFocus() && !(e->modifiers() & Qt::ControlModifier)) {
- if (e->text()[0].isPrint())
- setEditFocus(true);
- else {
- e->ignore();
- return;
- }
- }
- }
- break;
- }
-#endif
-#ifndef QT_NO_SHORTCUT
-
- Qt::TextInteractionFlags tif = d->control->textInteractionFlags();
-
- if (tif & Qt::TextSelectableByKeyboard){
- if (e == QKeySequence::SelectPreviousPage) {
- e->accept();
- d->pageUpDown(QTextCursor::Up, QTextCursor::KeepAnchor);
- return;
- } else if (e ==QKeySequence::SelectNextPage) {
- e->accept();
- d->pageUpDown(QTextCursor::Down, QTextCursor::KeepAnchor);
- return;
- }
- }
- if (tif & (Qt::TextSelectableByKeyboard | Qt::TextEditable)) {
- if (e == QKeySequence::MoveToPreviousPage) {
- e->accept();
- d->pageUpDown(QTextCursor::Up, QTextCursor::MoveAnchor);
- return;
- } else if (e == QKeySequence::MoveToNextPage) {
- e->accept();
- d->pageUpDown(QTextCursor::Down, QTextCursor::MoveAnchor);
- return;
- }
- }
-
- if (!(tif & Qt::TextEditable)) {
- switch (e->key()) {
- case Qt::Key_Space:
- e->accept();
- if (e->modifiers() & Qt::ShiftModifier)
- d->vbar->triggerAction(QAbstractSlider::SliderPageStepSub);
- else
- d->vbar->triggerAction(QAbstractSlider::SliderPageStepAdd);
- break;
- default:
- d->sendControlEvent(e);
- if (!e->isAccepted() && e->modifiers() == Qt::NoModifier) {
- if (e->key() == Qt::Key_Home) {
- d->vbar->triggerAction(QAbstractSlider::SliderToMinimum);
- e->accept();
- } else if (e->key() == Qt::Key_End) {
- d->vbar->triggerAction(QAbstractSlider::SliderToMaximum);
- e->accept();
- }
- }
- if (!e->isAccepted()) {
- QAbstractScrollArea::keyPressEvent(e);
- }
- }
- return;
- }
-#endif // QT_NO_SHORTCUT
-
- {
- QTextCursor cursor = d->control->textCursor();
- const QString text = e->text();
- if (cursor.atBlockStart()
- && (d->autoFormatting & AutoBulletList)
- && (text.length() == 1)
- && (text.at(0) == QLatin1Char('-') || text.at(0) == QLatin1Char('*'))
- && (!cursor.currentList())) {
-
- d->createAutoBulletList();
- e->accept();
- return;
- }
- }
-
- d->sendControlEvent(e);
-#ifdef QT_KEYPAD_NAVIGATION
- if (!e->isAccepted()) {
- switch (e->key()) {
- case Qt::Key_Up:
- case Qt::Key_Down:
- if (QApplication::keypadNavigationEnabled()) {
- // Cursor position didn't change, so we want to leave
- // these keys to change focus.
- e->ignore();
- return;
- }
- break;
- case Qt::Key_Back:
- if (!e->isAutoRepeat()) {
- if (QApplication::keypadNavigationEnabled()) {
- if (document()->isEmpty() || !(d->control->textInteractionFlags() & Qt::TextEditable)) {
- setEditFocus(false);
- e->accept();
- } else if (!d->deleteAllTimer.isActive()) {
- e->accept();
- d->deleteAllTimer.start(750, this);
- }
- } else {
- e->ignore();
- return;
- }
- }
- break;
- default: break;
- }
- }
-#endif
-}
-
-/*! \reimp
-*/
-void QTextEdit::keyReleaseEvent(QKeyEvent *e)
-{
-#ifdef QT_KEYPAD_NAVIGATION
- Q_D(QTextEdit);
- if (QApplication::keypadNavigationEnabled()) {
- if (!e->isAutoRepeat() && e->key() == Qt::Key_Back
- && d->deleteAllTimer.isActive()) {
- d->deleteAllTimer.stop();
- QTextCursor cursor = d->control->textCursor();
- QTextBlockFormat blockFmt = cursor.blockFormat();
-
- QTextList *list = cursor.currentList();
- if (list && cursor.atBlockStart()) {
- list->remove(cursor.block());
- } else if (cursor.atBlockStart() && blockFmt.indent() > 0) {
- blockFmt.setIndent(blockFmt.indent() - 1);
- cursor.setBlockFormat(blockFmt);
- } else {
- cursor.deletePreviousChar();
- }
- setTextCursor(cursor);
- e->accept();
- return;
- }
- }
-#endif
- e->ignore();
-}
-
-/*!
- Loads the resource specified by the given \a type and \a name.
-
- This function is an extension of QTextDocument::loadResource().
-
- \sa QTextDocument::loadResource()
-*/
-QVariant QTextEdit::loadResource(int type, const QUrl &name)
-{
- Q_UNUSED(type);
- Q_UNUSED(name);
- return QVariant();
-}
-
-/*! \reimp
-*/
-void QTextEdit::resizeEvent(QResizeEvent *e)
-{
- Q_D(QTextEdit);
-
- if (d->lineWrap == NoWrap) {
- QTextDocument *doc = d->control->document();
- QVariant alignmentProperty = doc->documentLayout()->property("contentHasAlignment");
-
- if (!doc->pageSize().isNull()
- && alignmentProperty.type() == QVariant::Bool
- && !alignmentProperty.toBool()) {
-
- d->_q_adjustScrollbars();
- return;
- }
- }
-
- if (d->lineWrap != FixedPixelWidth
- && e->oldSize().width() != e->size().width())
- d->relayoutDocument();
- else
- d->_q_adjustScrollbars();
-}
-
-void QTextEditPrivate::relayoutDocument()
-{
- QTextDocument *doc = control->document();
- QAbstractTextDocumentLayout *layout = doc->documentLayout();
-
- if (QTextDocumentLayout *tlayout = qobject_cast<QTextDocumentLayout *>(layout)) {
- if (lineWrap == QTextEdit::FixedColumnWidth)
- tlayout->setFixedColumnWidth(lineWrapColumnOrWidth);
- else
- tlayout->setFixedColumnWidth(-1);
- }
-
- QTextDocumentLayout *tlayout = qobject_cast<QTextDocumentLayout *>(layout);
- QSize lastUsedSize;
- if (tlayout)
- lastUsedSize = tlayout->dynamicDocumentSize().toSize();
- else
- lastUsedSize = layout->documentSize().toSize();
-
- // ignore calls to _q_adjustScrollbars caused by an emission of the
- // usedSizeChanged() signal in the layout, as we're calling it
- // later on our own anyway (or deliberately not) .
- const bool oldIgnoreScrollbarAdjustment = ignoreAutomaticScrollbarAdjustment;
- ignoreAutomaticScrollbarAdjustment = true;
-
- int width = viewport->width();
- if (lineWrap == QTextEdit::FixedPixelWidth)
- width = lineWrapColumnOrWidth;
- else if (lineWrap == QTextEdit::NoWrap) {
- QVariant alignmentProperty = doc->documentLayout()->property("contentHasAlignment");
- if (alignmentProperty.type() == QVariant::Bool && !alignmentProperty.toBool()) {
-
- width = 0;
- }
- }
-
- doc->setPageSize(QSize(width, -1));
- if (tlayout)
- tlayout->ensureLayouted(verticalOffset() + viewport->height());
-
- ignoreAutomaticScrollbarAdjustment = oldIgnoreScrollbarAdjustment;
-
- QSize usedSize;
- if (tlayout)
- usedSize = tlayout->dynamicDocumentSize().toSize();
- else
- usedSize = layout->documentSize().toSize();
-
- // this is an obscure situation in the layout that can happen:
- // if a character at the end of a line is the tallest one and therefore
- // influencing the total height of the line and the line right below it
- // is always taller though, then it can happen that if due to line breaking
- // that tall character wraps into the lower line the document not only shrinks
- // horizontally (causing the character to wrap in the first place) but also
- // vertically, because the original line is now smaller and the one below kept
- // its size. So a layout with less width _can_ take up less vertical space, too.
- // If the wider case causes a vertical scroll bar to appear and the narrower one
- // (narrower because the vertical scroll bar takes up horizontal space)) to disappear
- // again then we have an endless loop, as _q_adjustScrollBars sets new ranges on the
- // scroll bars, the QAbstractScrollArea will find out about it and try to show/hide
- // the scroll bars again. That's why we try to detect this case here and break out.
- //
- // (if you change this please also check the layoutingLoop() testcase in
- // QTextEdit's autotests)
- if (lastUsedSize.isValid()
- && !vbar->isHidden()
- && viewport->width() < lastUsedSize.width()
- && usedSize.height() < lastUsedSize.height()
- && usedSize.height() <= viewport->height())
- return;
-
- _q_adjustScrollbars();
-}
-
-void QTextEditPrivate::paint(QPainter *p, QPaintEvent *e)
-{
- const int xOffset = horizontalOffset();
- const int yOffset = verticalOffset();
-
- QRect r = e->rect();
- p->translate(-xOffset, -yOffset);
- r.translate(xOffset, yOffset);
-
- QTextDocument *doc = control->document();
- QTextDocumentLayout *layout = qobject_cast<QTextDocumentLayout *>(doc->documentLayout());
-
- // the layout might need to expand the root frame to
- // the viewport if NoWrap is set
- if (layout)
- layout->setViewport(viewport->rect());
-
- control->drawContents(p, r, q_func());
-
- if (layout)
- layout->setViewport(QRect());
-}
-
-/*! \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)
-{
- Q_D(QTextEdit);
- QPainter p(d->viewport);
- d->paint(&p, e);
-}
-
-void QTextEditPrivate::_q_currentCharFormatChanged(const QTextCharFormat &fmt)
-{
- Q_Q(QTextEdit);
- emit q->currentCharFormatChanged(fmt);
-#ifdef QT3_SUPPORT
- // compat signals
- emit q->currentFontChanged(fmt.font());
- emit q->currentColorChanged(fmt.foreground().color());
-#endif
-}
-
-void QTextEditPrivate::updateDefaultTextOption()
-{
- QTextDocument *doc = control->document();
-
- QTextOption opt = doc->defaultTextOption();
- QTextOption::WrapMode oldWrapMode = opt.wrapMode();
-
- if (lineWrap == QTextEdit::NoWrap)
- opt.setWrapMode(QTextOption::NoWrap);
- else
- opt.setWrapMode(wordWrap);
-
- if (opt.wrapMode() != oldWrapMode)
- doc->setDefaultTextOption(opt);
-}
-
-/*! \reimp
-*/
-void QTextEdit::mousePressEvent(QMouseEvent *e)
-{
- Q_D(QTextEdit);
-#ifdef QT_KEYPAD_NAVIGATION
- if (QApplication::keypadNavigationEnabled() && !hasEditFocus())
- setEditFocus(true);
-#endif
- d->sendControlEvent(e);
-}
-
-/*! \reimp
-*/
-void QTextEdit::mouseMoveEvent(QMouseEvent *e)
-{
- Q_D(QTextEdit);
- d->inDrag = false; // paranoia
- const QPoint pos = e->pos();
- d->sendControlEvent(e);
- if (!(e->buttons() & Qt::LeftButton))
- return;
- QRect visible = d->viewport->rect();
- if (visible.contains(pos))
- d->autoScrollTimer.stop();
- else if (!d->autoScrollTimer.isActive())
- d->autoScrollTimer.start(100, this);
-}
-
-/*! \reimp
-*/
-void QTextEdit::mouseReleaseEvent(QMouseEvent *e)
-{
- Q_D(QTextEdit);
- d->sendControlEvent(e);
- if (d->autoScrollTimer.isActive()) {
- d->autoScrollTimer.stop();
- ensureCursorVisible();
- }
- if (!isReadOnly() && rect().contains(e->pos()))
- d->handleSoftwareInputPanel(e->button(), d->clickCausedFocus);
- d->clickCausedFocus = 0;
-}
-
-/*! \reimp
-*/
-void QTextEdit::mouseDoubleClickEvent(QMouseEvent *e)
-{
- Q_D(QTextEdit);
- d->sendControlEvent(e);
-}
-
-/*! \reimp
-*/
-bool QTextEdit::focusNextPrevChild(bool next)
-{
- Q_D(const QTextEdit);
- if (!d->tabChangesFocus && d->control->textInteractionFlags() & Qt::TextEditable)
- return false;
- return QAbstractScrollArea::focusNextPrevChild(next);
-}
-
-#ifndef QT_NO_CONTEXTMENU
-/*!
- \fn void QTextEdit::contextMenuEvent(QContextMenuEvent *event)
-
- Shows the standard context menu created with createStandardContextMenu().
-
- If you do not want the text edit to have a context menu, you can set
- its \l contextMenuPolicy to Qt::NoContextMenu. If you want to
- customize the context menu, reimplement this function. If you want
- to extend the standard context menu, reimplement this function, call
- createStandardContextMenu() and extend the menu returned.
-
- Information about the event is passed in the \a event object.
-
- \snippet doc/src/snippets/code/src_gui_widgets_qtextedit.cpp 0
-*/
-void QTextEdit::contextMenuEvent(QContextMenuEvent *e)
-{
- Q_D(QTextEdit);
- d->sendControlEvent(e);
-}
-#endif // QT_NO_CONTEXTMENU
-
-#ifndef QT_NO_DRAGANDDROP
-/*! \reimp
-*/
-void QTextEdit::dragEnterEvent(QDragEnterEvent *e)
-{
- Q_D(QTextEdit);
- d->inDrag = true;
- d->sendControlEvent(e);
-}
-
-/*! \reimp
-*/
-void QTextEdit::dragLeaveEvent(QDragLeaveEvent *e)
-{
- Q_D(QTextEdit);
- d->inDrag = false;
- d->autoScrollTimer.stop();
- d->sendControlEvent(e);
-}
-
-/*! \reimp
-*/
-void QTextEdit::dragMoveEvent(QDragMoveEvent *e)
-{
- Q_D(QTextEdit);
- d->autoScrollDragPos = e->pos();
- if (!d->autoScrollTimer.isActive())
- d->autoScrollTimer.start(100, this);
- d->sendControlEvent(e);
-}
-
-/*! \reimp
-*/
-void QTextEdit::dropEvent(QDropEvent *e)
-{
- Q_D(QTextEdit);
- d->inDrag = false;
- d->autoScrollTimer.stop();
- d->sendControlEvent(e);
-}
-
-#endif // QT_NO_DRAGANDDROP
-
-/*! \reimp
- */
-void QTextEdit::inputMethodEvent(QInputMethodEvent *e)
-{
- Q_D(QTextEdit);
-#ifdef QT_KEYPAD_NAVIGATION
- if (d->control->textInteractionFlags() & Qt::TextEditable
- && QApplication::keypadNavigationEnabled()
- && !hasEditFocus())
- setEditFocus(true);
-#endif
- d->sendControlEvent(e);
- ensureCursorVisible();
-}
-
-/*!\reimp
-*/
-void QTextEdit::scrollContentsBy(int dx, int dy)
-{
- Q_D(QTextEdit);
- if (isRightToLeft())
- dx = -dx;
- d->viewport->scroll(dx, dy);
-}
-
-/*!\reimp
-*/
-QVariant QTextEdit::inputMethodQuery(Qt::InputMethodQuery property) const
-{
- Q_D(const QTextEdit);
- QVariant v = d->control->inputMethodQuery(property);
- const QPoint offset(-d->horizontalOffset(), -d->verticalOffset());
- if (v.type() == QVariant::RectF)
- v = v.toRectF().toRect().translated(offset);
- else if (v.type() == QVariant::PointF)
- v = v.toPointF().toPoint() + offset;
- else if (v.type() == QVariant::Rect)
- v = v.toRect().translated(offset);
- else if (v.type() == QVariant::Point)
- v = v.toPoint() + offset;
- return v;
-}
-
-/*! \reimp
-*/
-void QTextEdit::focusInEvent(QFocusEvent *e)
-{
- Q_D(QTextEdit);
- if (e->reason() == Qt::MouseFocusReason) {
- d->clickCausedFocus = 1;
- }
- QAbstractScrollArea::focusInEvent(e);
- d->sendControlEvent(e);
-}
-
-/*! \reimp
-*/
-void QTextEdit::focusOutEvent(QFocusEvent *e)
-{
- Q_D(QTextEdit);
- QAbstractScrollArea::focusOutEvent(e);
- d->sendControlEvent(e);
-}
-
-/*! \reimp
-*/
-void QTextEdit::showEvent(QShowEvent *)
-{
- Q_D(QTextEdit);
- if (!d->anchorToScrollToWhenVisible.isEmpty()) {
- scrollToAnchor(d->anchorToScrollToWhenVisible);
- d->anchorToScrollToWhenVisible.clear();
- d->showCursorOnInitialShow = false;
- } else if (d->showCursorOnInitialShow) {
- d->showCursorOnInitialShow = false;
- ensureCursorVisible();
- }
-}
-
-/*! \reimp
-*/
-void QTextEdit::changeEvent(QEvent *e)
-{
- Q_D(QTextEdit);
- QAbstractScrollArea::changeEvent(e);
- if (e->type() == QEvent::ApplicationFontChange
- || e->type() == QEvent::FontChange) {
- d->control->document()->setDefaultFont(font());
- } else if(e->type() == QEvent::ActivationChange) {
- if (!isActiveWindow())
- d->autoScrollTimer.stop();
- } else if (e->type() == QEvent::EnabledChange) {
- e->setAccepted(isEnabled());
- d->control->setPalette(palette());
- d->sendControlEvent(e);
- } else if (e->type() == QEvent::PaletteChange) {
- d->control->setPalette(palette());
- } else if (e->type() == QEvent::LayoutDirectionChange) {
- d->sendControlEvent(e);
- }
-}
-
-/*! \reimp
-*/
-#ifndef QT_NO_WHEELEVENT
-void QTextEdit::wheelEvent(QWheelEvent *e)
-{
- Q_D(QTextEdit);
- if (!(d->control->textInteractionFlags() & Qt::TextEditable)) {
- if (e->modifiers() & Qt::ControlModifier) {
- const int delta = e->delta();
- if (delta < 0)
- zoomOut();
- else if (delta > 0)
- zoomIn();
- return;
- }
- }
- QAbstractScrollArea::wheelEvent(e);
- updateMicroFocus();
-}
-#endif
-
-#ifndef QT_NO_CONTEXTMENU
-/*! This function creates the standard context menu which is shown
- when the user clicks on the text edit with the right mouse
- button. It is called from the default contextMenuEvent() handler.
- The popup menu's ownership is transferred to the caller.
-
- We recommend that you use the createStandardContextMenu(QPoint) version instead
- which will enable the actions that are sensitive to where the user clicked.
-*/
-
-QMenu *QTextEdit::createStandardContextMenu()
-{
- Q_D(QTextEdit);
- return d->control->createStandardContextMenu(QPointF(), this);
-}
-
-/*!
- \since 4.4
- This function creates the standard context menu which is shown
- when the user clicks on the text edit with the right mouse
- button. It is called from the default contextMenuEvent() handler
- and it takes the \a position of where the mouse click was.
- This can enable actions that are sensitive to the position where the user clicked.
- The popup menu's ownership is transferred to the caller.
-*/
-
-QMenu *QTextEdit::createStandardContextMenu(const QPoint &position)
-{
- Q_D(QTextEdit);
- return d->control->createStandardContextMenu(position, this);
-}
-#endif // QT_NO_CONTEXTMENU
-
-/*!
- returns a QTextCursor at position \a pos (in viewport coordinates).
-*/
-QTextCursor QTextEdit::cursorForPosition(const QPoint &pos) const
-{
- Q_D(const QTextEdit);
- return d->control->cursorForPosition(d->mapToContents(pos));
-}
-
-/*!
- returns a rectangle (in viewport coordinates) that includes the
- \a cursor.
- */
-QRect QTextEdit::cursorRect(const QTextCursor &cursor) const
-{
- Q_D(const QTextEdit);
- if (cursor.isNull())
- return QRect();
-
- QRect r = d->control->cursorRect(cursor).toRect();
- r.translate(-d->horizontalOffset(),-d->verticalOffset());
- return r;
-}
-
-/*!
- returns a rectangle (in viewport coordinates) that includes the
- cursor of the text edit.
- */
-QRect QTextEdit::cursorRect() const
-{
- Q_D(const QTextEdit);
- QRect r = d->control->cursorRect().toRect();
- r.translate(-d->horizontalOffset(),-d->verticalOffset());
- return r;
-}
-
-
-/*!
- Returns the reference of the anchor at position \a pos, or an
- empty string if no anchor exists at that point.
-*/
-QString QTextEdit::anchorAt(const QPoint& pos) const
-{
- Q_D(const QTextEdit);
- return d->control->anchorAt(d->mapToContents(pos));
-}
-
-/*!
- \property QTextEdit::overwriteMode
- \since 4.1
- \brief whether text entered by the user will overwrite existing text
-
- As with many text editors, the text editor widget can be configured
- to insert or overwrite existing text with new text entered by the user.
-
- If this property is true, existing text is overwritten, character-for-character
- by new text; otherwise, text is inserted at the cursor position, displacing
- existing text.
-
- By default, this property is false (new text does not overwrite existing text).
-*/
-
-bool QTextEdit::overwriteMode() const
-{
- Q_D(const QTextEdit);
- return d->control->overwriteMode();
-}
-
-void QTextEdit::setOverwriteMode(bool overwrite)
-{
- Q_D(QTextEdit);
- d->control->setOverwriteMode(overwrite);
-}
-
-/*!
- \property QTextEdit::tabStopWidth
- \brief the tab stop width in pixels
- \since 4.1
-
- By default, this property contains a value of 80 pixels.
-*/
-
-int QTextEdit::tabStopWidth() const
-{
- Q_D(const QTextEdit);
- return qRound(d->control->document()->defaultTextOption().tabStop());
-}
-
-void QTextEdit::setTabStopWidth(int width)
-{
- Q_D(QTextEdit);
- QTextOption opt = d->control->document()->defaultTextOption();
- if (opt.tabStop() == width || width < 0)
- return;
- opt.setTabStop(width);
- d->control->document()->setDefaultTextOption(opt);
-}
-
-/*!
- \since 4.2
- \property QTextEdit::cursorWidth
-
- This property specifies the width of the cursor in pixels. The default value is 1.
-*/
-int QTextEdit::cursorWidth() const
-{
- Q_D(const QTextEdit);
- return d->control->cursorWidth();
-}
-
-void QTextEdit::setCursorWidth(int width)
-{
- Q_D(QTextEdit);
- d->control->setCursorWidth(width);
-}
-
-/*!
- \property QTextEdit::acceptRichText
- \brief whether the text edit accepts rich text insertions by the user
- \since 4.1
-
- When this propery is set to false text edit will accept only
- plain text input from the user. For example through clipboard or drag and drop.
-
- This property's default is true.
-*/
-
-bool QTextEdit::acceptRichText() const
-{
- Q_D(const QTextEdit);
- return d->control->acceptRichText();
-}
-
-void QTextEdit::setAcceptRichText(bool accept)
-{
- Q_D(QTextEdit);
- d->control->setAcceptRichText(accept);
-}
-
-/*!
- \class QTextEdit::ExtraSelection
- \since 4.2
- \brief The QTextEdit::ExtraSelection structure provides a way of specifying a
- character format for a given selection in a document
-*/
-
-/*!
- \variable QTextEdit::ExtraSelection::cursor
- A cursor that contains a selection in a QTextDocument
-*/
-
-/*!
- \variable QTextEdit::ExtraSelection::format
- A format that is used to specify a foreground or background brush/color
- for the selection.
-*/
-
-/*!
- \since 4.2
- This function allows temporarily marking certain regions in the document
- with a given color, specified as \a selections. This can be useful for
- example in a programming editor to mark a whole line of text with a given
- background color to indicate the existence of a breakpoint.
-
- \sa QTextEdit::ExtraSelection, extraSelections()
-*/
-void QTextEdit::setExtraSelections(const QList<ExtraSelection> &selections)
-{
- Q_D(QTextEdit);
- d->control->setExtraSelections(selections);
-}
-
-/*!
- \since 4.2
- Returns previously set extra selections.
-
- \sa setExtraSelections()
-*/
-QList<QTextEdit::ExtraSelection> QTextEdit::extraSelections() const
-{
- Q_D(const QTextEdit);
- return d->control->extraSelections();
-}
-
-/*!
- This function returns a new MIME data object to represent the contents
- of the text edit's current selection. It is called when the selection needs
- to be encapsulated into a new QMimeData object; for example, when a drag
- and drop operation is started, or when data is copyied to the clipboard.
-
- If you reimplement this function, note that the ownership of the returned
- QMimeData object is passed to the caller. The selection can be retrieved
- by using the textCursor() function.
-*/
-QMimeData *QTextEdit::createMimeDataFromSelection() const
-{
- Q_D(const QTextEdit);
- return d->control->QTextControl::createMimeDataFromSelection();
-}
-
-/*!
- This function returns true if the contents of the MIME data object, specified
- by \a source, can be decoded and inserted into the document. It is called
- for example when during a drag operation the mouse enters this widget and it
- is necessary to determine whether it is possible to accept the drag and drop
- operation.
-
- Reimplement this function to enable drag and drop support for additional MIME types.
- */
-bool QTextEdit::canInsertFromMimeData(const QMimeData *source) const
-{
- Q_D(const QTextEdit);
- return d->control->QTextControl::canInsertFromMimeData(source);
-}
-
-/*!
- This function inserts the contents of the MIME data object, specified
- by \a source, into the text edit at the current cursor position. It is
- called whenever text is inserted as the result of a clipboard paste
- operation, or when the text edit accepts data from a drag and drop
- operation.
-
- Reimplement this function to enable drag and drop support for additional MIME types.
- */
-void QTextEdit::insertFromMimeData(const QMimeData *source)
-{
- Q_D(QTextEdit);
- d->control->QTextControl::insertFromMimeData(source);
-}
-
-/*!
- \property QTextEdit::readOnly
- \brief whether the text edit is read-only
-
- In a read-only text edit the user can only navigate through the
- text and select text; modifying the text is not possible.
-
- This property's default is false.
-*/
-
-bool QTextEdit::isReadOnly() const
-{
- Q_D(const QTextEdit);
- return !(d->control->textInteractionFlags() & Qt::TextEditable);
-}
-
-void QTextEdit::setReadOnly(bool ro)
-{
- Q_D(QTextEdit);
- Qt::TextInteractionFlags flags = Qt::NoTextInteraction;
- if (ro) {
- flags = Qt::TextSelectableByMouse;
-#ifndef QT_NO_TEXTBROWSER
- if (qobject_cast<QTextBrowser *>(this))
- flags |= Qt::TextBrowserInteraction;
-#endif
- } else {
- flags = Qt::TextEditorInteraction;
- }
- d->control->setTextInteractionFlags(flags);
- setAttribute(Qt::WA_InputMethodEnabled, shouldEnableInputMethod(this));
-}
-
-/*!
- \property QTextEdit::textInteractionFlags
- \since 4.2
-
- Specifies how the widget should interact with user input.
-
- The default value depends on whether the QTextEdit is read-only
- or editable, and whether it is a QTextBrowser or not.
-*/
-
-void QTextEdit::setTextInteractionFlags(Qt::TextInteractionFlags flags)
-{
- Q_D(QTextEdit);
- d->control->setTextInteractionFlags(flags);
-}
-
-Qt::TextInteractionFlags QTextEdit::textInteractionFlags() const
-{
- Q_D(const QTextEdit);
- return d->control->textInteractionFlags();
-}
-
-/*!
- Merges the properties specified in \a modifier into the current character
- format by calling QTextCursor::mergeCharFormat on the editor's cursor.
- If the editor has a selection then the properties of \a modifier are
- directly applied to the selection.
-
- \sa QTextCursor::mergeCharFormat()
- */
-void QTextEdit::mergeCurrentCharFormat(const QTextCharFormat &modifier)
-{
- Q_D(QTextEdit);
- d->control->mergeCurrentCharFormat(modifier);
-}
-
-/*!
- Sets the char format that is be used when inserting new text to \a
- format by calling QTextCursor::setCharFormat() on the editor's
- cursor. If the editor has a selection then the char format is
- directly applied to the selection.
- */
-void QTextEdit::setCurrentCharFormat(const QTextCharFormat &format)
-{
- Q_D(QTextEdit);
- d->control->setCurrentCharFormat(format);
-}
-
-/*!
- Returns the char format that is used when inserting new text.
- */
-QTextCharFormat QTextEdit::currentCharFormat() const
-{
- Q_D(const QTextEdit);
- return d->control->currentCharFormat();
-}
-
-/*!
- \property QTextEdit::autoFormatting
- \brief the enabled set of auto formatting features
-
- The value can be any combination of the values in the
- AutoFormattingFlag enum. The default is AutoNone. Choose
- AutoAll to enable all automatic formatting.
-
- Currently, the only automatic formatting feature provided is
- AutoBulletList; future versions of Qt may offer more.
-*/
-
-QTextEdit::AutoFormatting QTextEdit::autoFormatting() const
-{
- Q_D(const QTextEdit);
- return d->autoFormatting;
-}
-
-void QTextEdit::setAutoFormatting(AutoFormatting features)
-{
- Q_D(QTextEdit);
- d->autoFormatting = features;
-}
-
-/*!
- Convenience slot that inserts \a text at the current
- cursor position.
-
- It is equivalent to
-
- \snippet doc/src/snippets/code/src_gui_widgets_qtextedit.cpp 1
- */
-void QTextEdit::insertPlainText(const QString &text)
-{
- Q_D(QTextEdit);
- d->control->insertPlainText(text);
-}
-
-/*!
- Convenience slot that inserts \a text which is assumed to be of
- html formatting at the current cursor position.
-
- It is equivalent to:
-
- \snippet doc/src/snippets/code/src_gui_widgets_qtextedit.cpp 2
-
- \note When using this function with a style sheet, the style sheet will
- only apply to the current block in the document. In order to apply a style
- sheet throughout a document, use QTextDocument::setDefaultStyleSheet()
- instead.
- */
-#ifndef QT_NO_TEXTHTMLPARSER
-void QTextEdit::insertHtml(const QString &text)
-{
- Q_D(QTextEdit);
- d->control->insertHtml(text);
-}
-#endif // QT_NO_TEXTHTMLPARSER
-
-/*!
- Scrolls the text edit so that the anchor with the given \a name is
- visible; does nothing if the \a name is empty, or is already
- visible, or isn't found.
-*/
-void QTextEdit::scrollToAnchor(const QString &name)
-{
- Q_D(QTextEdit);
- if (name.isEmpty())
- return;
-
- if (!isVisible()) {
- d->anchorToScrollToWhenVisible = name;
- return;
- }
-
- QPointF p = d->control->anchorPosition(name);
- const int newPosition = qRound(p.y());
- if ( d->vbar->maximum() < newPosition )
- d->_q_adjustScrollbars();
- d->vbar->setValue(newPosition);
-}
-
-/*!
- \fn QTextEdit::zoomIn(int range)
-
- Zooms in on the text by making the base font size \a range
- points larger and recalculating all font sizes to be the new size.
- This does not change the size of any images.
-
- \sa zoomOut()
-*/
-void QTextEdit::zoomIn(int range)
-{
- QFont f = font();
- const int newSize = f.pointSize() + range;
- if (newSize <= 0)
- return;
- f.setPointSize(newSize);
- setFont(f);
-}
-
-/*!
- \fn QTextEdit::zoomOut(int range)
-
- \overload
-
- Zooms out on the text by making the base font size \a range points
- smaller and recalculating all font sizes to be the new size. This
- does not change the size of any images.
-
- \sa zoomIn()
-*/
-void QTextEdit::zoomOut(int range)
-{
- zoomIn(-range);
-}
-
-/*!
- \since 4.2
- Moves the cursor by performing the given \a operation.
-
- If \a mode is QTextCursor::KeepAnchor, the cursor selects the text it moves over.
- This is the same effect that the user achieves when they hold down the Shift key
- and move the cursor with the cursor keys.
-
- \sa QTextCursor::movePosition()
-*/
-void QTextEdit::moveCursor(QTextCursor::MoveOperation operation, QTextCursor::MoveMode mode)
-{
- Q_D(QTextEdit);
- d->control->moveCursor(operation, mode);
-}
-
-/*!
- \since 4.2
- Returns whether text can be pasted from the clipboard into the textedit.
-*/
-bool QTextEdit::canPaste() const
-{
- Q_D(const QTextEdit);
- return d->control->canPaste();
-}
-
-#ifndef QT_NO_PRINTER
-/*!
- \since 4.3
- Convenience function to print the text edit's document to the given \a printer. This
- is equivalent to calling the print method on the document directly except that this
- function also supports QPrinter::Selection as print range.
-
- \sa QTextDocument::print()
-*/
-void QTextEdit::print(QPrinter *printer) const
-{
- Q_D(const QTextEdit);
- d->control->print(printer);
-}
-#endif // QT _NO_PRINTER
-
-/*! \property QTextEdit::tabChangesFocus
- \brief whether \gui Tab changes focus or is accepted as input
-
- In some occasions text edits should not allow the user to input
- tabulators or change indentation using the \gui Tab key, as this breaks
- the focus chain. The default is false.
-
-*/
-
-bool QTextEdit::tabChangesFocus() const
-{
- Q_D(const QTextEdit);
- return d->tabChangesFocus;
-}
-
-void QTextEdit::setTabChangesFocus(bool b)
-{
- Q_D(QTextEdit);
- d->tabChangesFocus = b;
-}
-
-/*!
- \property QTextEdit::documentTitle
- \brief the title of the document parsed from the text.
-
- By default, for a newly-created, empty document, this property contains
- an empty string.
-*/
-
-/*!
- \property QTextEdit::lineWrapMode
- \brief the line wrap mode
-
- The default mode is WidgetWidth which causes words to be
- wrapped at the right edge of the text edit. Wrapping occurs at
- whitespace, keeping whole words intact. If you want wrapping to
- occur within words use setWordWrapMode(). If you set a wrap mode of
- FixedPixelWidth or FixedColumnWidth you should also call
- setLineWrapColumnOrWidth() with the width you want.
-
- \sa lineWrapColumnOrWidth
-*/
-
-QTextEdit::LineWrapMode QTextEdit::lineWrapMode() const
-{
- Q_D(const QTextEdit);
- return d->lineWrap;
-}
-
-void QTextEdit::setLineWrapMode(LineWrapMode wrap)
-{
- Q_D(QTextEdit);
- if (d->lineWrap == wrap)
- return;
- d->lineWrap = wrap;
- d->updateDefaultTextOption();
- d->relayoutDocument();
-}
-
-/*!
- \property QTextEdit::lineWrapColumnOrWidth
- \brief the position (in pixels or columns depending on the wrap mode) where text will be wrapped
-
- If the wrap mode is FixedPixelWidth, the value is the number of
- pixels from the left edge of the text edit at which text should be
- wrapped. If the wrap mode is FixedColumnWidth, the value is the
- column number (in character columns) from the left edge of the
- text edit at which text should be wrapped.
-
- By default, this property contains a value of 0.
-
- \sa lineWrapMode
-*/
-
-int QTextEdit::lineWrapColumnOrWidth() const
-{
- Q_D(const QTextEdit);
- return d->lineWrapColumnOrWidth;
-}
-
-void QTextEdit::setLineWrapColumnOrWidth(int w)
-{
- Q_D(QTextEdit);
- d->lineWrapColumnOrWidth = w;
- d->relayoutDocument();
-}
-
-/*!
- \property QTextEdit::wordWrapMode
- \brief the mode QTextEdit will use when wrapping text by words
-
- By default, this property is set to QTextOption::WrapAtWordBoundaryOrAnywhere.
-
- \sa QTextOption::WrapMode
-*/
-
-QTextOption::WrapMode QTextEdit::wordWrapMode() const
-{
- Q_D(const QTextEdit);
- return d->wordWrap;
-}
-
-void QTextEdit::setWordWrapMode(QTextOption::WrapMode mode)
-{
- Q_D(QTextEdit);
- if (mode == d->wordWrap)
- return;
- d->wordWrap = mode;
- d->updateDefaultTextOption();
-}
-
-/*!
- Finds the next occurrence of the string, \a exp, using the given
- \a options. Returns true if \a exp was found and changes the
- cursor to select the match; otherwise returns false.
-*/
-bool QTextEdit::find(const QString &exp, QTextDocument::FindFlags options)
-{
- Q_D(QTextEdit);
- return d->control->find(exp, options);
-}
-
-/*!
- \fn void QTextEdit::copyAvailable(bool yes)
-
- This signal is emitted when text is selected or de-selected in the
- text edit.
-
- When text is selected this signal will be emitted with \a yes set
- to true. If no text has been selected or if the selected text is
- de-selected this signal is emitted with \a yes set to false.
-
- If \a yes is true then copy() can be used to copy the selection to
- the clipboard. If \a yes is false then copy() does nothing.
-
- \sa selectionChanged()
-*/
-
-/*!
- \fn void QTextEdit::currentCharFormatChanged(const QTextCharFormat &f)
-
- This signal is emitted if the current character format has changed, for
- example caused by a change of the cursor position.
-
- The new format is \a f.
-
- \sa setCurrentCharFormat()
-*/
-
-/*!
- \fn void QTextEdit::selectionChanged()
-
- This signal is emitted whenever the selection changes.
-
- \sa copyAvailable()
-*/
-
-/*!
- \fn void QTextEdit::cursorPositionChanged()
-
- This signal is emitted whenever the position of the
- cursor changed.
-*/
-
-/*!
- \since 4.2
-
- Sets the text edit's \a text. The text can be plain text or HTML
- and the text edit will try to guess the right format.
-
- Use setHtml() or setPlainText() directly to avoid text edit's guessing.
-*/
-void QTextEdit::setText(const QString &text)
-{
- Q_D(QTextEdit);
- Qt::TextFormat format = d->textFormat;
- if (d->textFormat == Qt::AutoText)
- format = Qt::mightBeRichText(text) ? Qt::RichText : Qt::PlainText;
-#ifndef QT_NO_TEXTHTMLPARSER
- if (format == Qt::RichText || format == Qt::LogText)
- setHtml(text);
- else
-#endif
- setPlainText(text);
-}
-
-#ifdef QT3_SUPPORT
-/*!
- Use the QTextCursor class instead.
-*/
-void QTextEdit::moveCursor(CursorAction action, QTextCursor::MoveMode mode)
-{
- Q_D(QTextEdit);
- if (action == MovePageUp) {
- d->pageUpDown(QTextCursor::Up, mode);
- return;
- } else if (action == MovePageDown) {
- d->pageUpDown(QTextCursor::Down, mode);
- return;
- }
-
- QTextCursor cursor = d->control->textCursor();
- QTextCursor::MoveOperation op = QTextCursor::NoMove;
- switch (action) {
- case MoveBackward: op = QTextCursor::Left; break;
- case MoveForward: op = QTextCursor::Right; break;
- case MoveWordBackward: op = QTextCursor::WordLeft; break;
- case MoveWordForward: op = QTextCursor::WordRight; break;
- case MoveUp: op = QTextCursor::Up; break;
- case MoveDown: op = QTextCursor::Down; break;
- case MoveLineStart: op = QTextCursor::StartOfLine; break;
- case MoveLineEnd: op = QTextCursor::EndOfLine; break;
- case MoveHome: op = QTextCursor::Start; break;
- case MoveEnd: op = QTextCursor::End; break;
- default: return;
- }
- cursor.movePosition(op, mode);
- d->control->setTextCursor(cursor);
-}
-
-/*!
- Use the QTextCursor class instead.
-*/
-void QTextEdit::moveCursor(CursorAction action, bool select)
-{
- moveCursor(action, select ? QTextCursor::KeepAnchor : QTextCursor::MoveAnchor);
-}
-
-/*!
- Executes keyboard action \a action.
-
- Use the QTextCursor class instead.
-
- \sa textCursor()
-*/
-void QTextEdit::doKeyboardAction(KeyboardAction action)
-{
- Q_D(QTextEdit);
- QTextCursor cursor = d->control->textCursor();
- switch (action) {
- case ActionBackspace: cursor.deletePreviousChar(); break;
- case ActionDelete: cursor.deleteChar(); break;
- case ActionReturn: cursor.insertBlock(); break;
- case ActionKill: {
- QTextBlock block = cursor.block();
- if (cursor.position() == block.position() + block.length() - 2)
- cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor);
- else
- cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
- cursor.deleteChar();
- break;
- }
- case ActionWordBackspace:
- cursor.movePosition(QTextCursor::PreviousWord, QTextCursor::KeepAnchor);
- cursor.deletePreviousChar();
- break;
- case ActionWordDelete:
- cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);
- cursor.deleteChar();
- break;
- }
- d->control->setTextCursor(cursor);
-}
-
-/*!
- Returns all the text in the text edit as plain text.
-*/
-QString QTextEdit::text() const
-{
- Q_D(const QTextEdit);
- if (d->textFormat == Qt::RichText || d->textFormat == Qt::LogText || (d->textFormat == Qt::AutoText && d->preferRichText))
- return d->control->toHtml();
- else
- return d->control->toPlainText();
-}
-
-
-/*!
- Sets the text format to format \a f.
-
- \sa textFormat()
-*/
-void QTextEdit::setTextFormat(Qt::TextFormat f)
-{
- Q_D(QTextEdit);
- d->textFormat = f;
-}
-
-/*!
- Returns the text format.
-
- \sa setTextFormat()
-*/
-Qt::TextFormat QTextEdit::textFormat() const
-{
- Q_D(const QTextEdit);
- return d->textFormat;
-}
-
-#endif // QT3_SUPPORT
-
-/*!
- Appends a new paragraph with \a text to the end of the text edit.
-
- \note The new paragraph appended will have the same character format and
- block format as the current paragraph, determined by the position of the cursor.
-
- \sa currentCharFormat(), QTextCursor::blockFormat()
-*/
-
-void QTextEdit::append(const QString &text)
-{
- Q_D(QTextEdit);
- const bool atBottom = isReadOnly() ? d->verticalOffset() >= d->vbar->maximum() :
- d->control->textCursor().atEnd();
- d->control->append(text);
- if (atBottom)
- d->vbar->setValue(d->vbar->maximum());
-}
-
-/*!
- Ensures that the cursor is visible by scrolling the text edit if
- necessary.
-*/
-void QTextEdit::ensureCursorVisible()
-{
- Q_D(QTextEdit);
- d->control->ensureCursorVisible();
-}
-
-/*!
- \enum QTextEdit::KeyboardAction
-
- \compat
-
- \value ActionBackspace
- \value ActionDelete
- \value ActionReturn
- \value ActionKill
- \value ActionWordBackspace
- \value ActionWordDelete
-*/
-
-/*!
- \fn bool QTextEdit::find(const QString &exp, bool cs, bool wo)
-
- Use the find() overload that takes a QTextDocument::FindFlags
- argument.
-*/
-
-/*!
- \fn void QTextEdit::sync()
-
- Does nothing.
-*/
-
-/*!
- \fn void QTextEdit::setBold(bool b)
-
- Use setFontWeight() instead.
-*/
-
-/*!
- \fn void QTextEdit::setUnderline(bool b)
-
- Use setFontUnderline() instead.
-*/
-
-/*!
- \fn void QTextEdit::setItalic(bool i)
-
- Use setFontItalic() instead.
-*/
-
-/*!
- \fn void QTextEdit::setFamily(const QString &family)
-
- Use setFontFamily() instead.
-*/
-
-/*!
- \fn void QTextEdit::setPointSize(int size)
-
- Use setFontPointSize() instead.
-*/
-
-/*!
- \fn bool QTextEdit::italic() const
-
- Use fontItalic() instead.
-*/
-
-/*!
- \fn bool QTextEdit::bold() const
-
- Use fontWeight() >= QFont::Bold instead.
-*/
-
-/*!
- \fn bool QTextEdit::underline() const
-
- Use fontUnderline() instead.
-*/
-
-/*!
- \fn QString QTextEdit::family() const
-
- Use fontFamily() instead.
-*/
-
-/*!
- \fn int QTextEdit::pointSize() const
-
- Use int(fontPointSize()+0.5) instead.
-*/
-
-/*!
- \fn bool QTextEdit::hasSelectedText() const
-
- Use textCursor().hasSelection() instead.
-*/
-
-/*!
- \fn QString QTextEdit::selectedText() const
-
- Use textCursor().selectedText() instead.
-*/
-
-/*!
- \fn bool QTextEdit::isUndoAvailable() const
-
- Use document()->isUndoAvailable() instead.
-*/
-
-/*!
- \fn bool QTextEdit::isRedoAvailable() const
-
- Use document()->isRedoAvailable() instead.
-*/
-
-/*!
- \fn void QTextEdit::insert(const QString &text)
-
- Use insertPlainText() instead.
-*/
-
-/*!
- \fn bool QTextEdit::isModified() const
-
- Use document()->isModified() instead.
-*/
-
-/*!
- \fn QColor QTextEdit::color() const
-
- Use textColor() instead.
-*/
-
-/*!
- \fn void QTextEdit::textChanged()
-
- This signal is emitted whenever the document's content changes; for
- example, when text is inserted or deleted, or when formatting is applied.
-*/
-
-/*!
- \fn void QTextEdit::undoAvailable(bool available)
-
- This signal is emitted whenever undo operations become available
- (\a available is true) or unavailable (\a available is false).
-*/
-
-/*!
- \fn void QTextEdit::redoAvailable(bool available)
-
- This signal is emitted whenever redo operations become available
- (\a available is true) or unavailable (\a available is false).
-*/
-
-/*!
- \fn void QTextEdit::currentFontChanged(const QFont &font)
-
- Use currentCharFormatChanged() instead.
-*/
-
-/*!
- \fn void QTextEdit::currentColorChanged(const QColor &color)
-
- Use currentCharFormatChanged() instead.
-*/
-
-/*!
- \fn void QTextEdit::setModified(bool m)
-
- Use document->setModified() instead.
-*/
-
-/*!
- \fn void QTextEdit::setColor(const QColor &color)
-
- Use setTextColor() instead.
-*/
-#endif // QT_NO_TEXTEDIT
-
-QT_END_NAMESPACE
-
-#include "moc_qtextedit.cpp"
diff --git a/src/gui/widgets/qtextedit.h b/src/gui/widgets/qtextedit.h
deleted file mode 100644
index 3c56ef1cd3..0000000000
--- a/src/gui/widgets/qtextedit.h
+++ /dev/null
@@ -1,430 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QTEXTEDIT_H
-#define QTEXTEDIT_H
-
-#include <QtGui/qabstractscrollarea.h>
-#include <QtGui/qtextdocument.h>
-#include <QtGui/qtextoption.h>
-#include <QtGui/qtextcursor.h>
-#include <QtGui/qtextformat.h>
-
-#ifndef QT_NO_TEXTEDIT
-
-#ifdef QT3_SUPPORT
-#include <QtGui/qtextobject.h>
-#include <QtGui/qtextlayout.h>
-#endif
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QStyleSheet;
-class QTextDocument;
-class QMenu;
-class QTextEditPrivate;
-class QMimeData;
-
-class Q_GUI_EXPORT QTextEdit : public QAbstractScrollArea
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QTextEdit)
- Q_FLAGS(AutoFormatting)
- Q_ENUMS(LineWrapMode)
- Q_PROPERTY(AutoFormatting autoFormatting READ autoFormatting WRITE setAutoFormatting)
- Q_PROPERTY(bool tabChangesFocus READ tabChangesFocus WRITE setTabChangesFocus)
- Q_PROPERTY(QString documentTitle READ documentTitle WRITE setDocumentTitle)
- Q_PROPERTY(bool undoRedoEnabled READ isUndoRedoEnabled WRITE setUndoRedoEnabled)
- Q_PROPERTY(LineWrapMode lineWrapMode READ lineWrapMode WRITE setLineWrapMode)
- QDOC_PROPERTY(QTextOption::WrapMode wordWrapMode READ wordWrapMode WRITE setWordWrapMode)
- Q_PROPERTY(int lineWrapColumnOrWidth READ lineWrapColumnOrWidth WRITE setLineWrapColumnOrWidth)
- Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly)
-#ifndef QT_NO_TEXTHTMLPARSER
- Q_PROPERTY(QString html READ toHtml WRITE setHtml NOTIFY textChanged USER true)
-#endif
- Q_PROPERTY(QString plainText READ toPlainText WRITE setPlainText DESIGNABLE false)
- Q_PROPERTY(bool overwriteMode READ overwriteMode WRITE setOverwriteMode)
- Q_PROPERTY(int tabStopWidth READ tabStopWidth WRITE setTabStopWidth)
- Q_PROPERTY(bool acceptRichText READ acceptRichText WRITE setAcceptRichText)
- Q_PROPERTY(int cursorWidth READ cursorWidth WRITE setCursorWidth)
- Q_PROPERTY(Qt::TextInteractionFlags textInteractionFlags READ textInteractionFlags WRITE setTextInteractionFlags)
-public:
- enum LineWrapMode {
- NoWrap,
- WidgetWidth,
- FixedPixelWidth,
- FixedColumnWidth
- };
-
- enum AutoFormattingFlag {
- AutoNone = 0,
- AutoBulletList = 0x00000001,
- AutoAll = 0xffffffff
- };
-
- Q_DECLARE_FLAGS(AutoFormatting, AutoFormattingFlag)
-
-#if defined(QT3_SUPPORT)
- enum CursorAction {
- MoveBackward,
- MoveForward,
- MoveWordBackward,
- MoveWordForward,
- MoveUp,
- MoveDown,
- MoveLineStart,
- MoveLineEnd,
- MoveHome,
- MoveEnd,
- MovePageUp,
- MovePageDown
-#if !defined(Q_MOC_RUN)
- ,
- MovePgUp = MovePageUp,
- MovePgDown = MovePageDown
-#endif
- };
-#endif
-
- explicit QTextEdit(QWidget *parent = 0);
- explicit QTextEdit(const QString &text, QWidget *parent = 0);
- virtual ~QTextEdit();
-
- void setDocument(QTextDocument *document);
- QTextDocument *document() const;
-
- void setTextCursor(const QTextCursor &cursor);
- QTextCursor textCursor() const;
-
- bool isReadOnly() const;
- void setReadOnly(bool ro);
-
- void setTextInteractionFlags(Qt::TextInteractionFlags flags);
- Qt::TextInteractionFlags textInteractionFlags() const;
-
- qreal fontPointSize() const;
- QString fontFamily() const;
- int fontWeight() const;
- bool fontUnderline() const;
- bool fontItalic() const;
- QColor textColor() const;
- QColor textBackgroundColor() const;
- QFont currentFont() const;
- Qt::Alignment alignment() const;
-
- void mergeCurrentCharFormat(const QTextCharFormat &modifier);
-
- void setCurrentCharFormat(const QTextCharFormat &format);
- QTextCharFormat currentCharFormat() const;
-
- AutoFormatting autoFormatting() const;
- void setAutoFormatting(AutoFormatting features);
-
- bool tabChangesFocus() const;
- void setTabChangesFocus(bool b);
-
- inline void setDocumentTitle(const QString &title)
- { document()->setMetaInformation(QTextDocument::DocumentTitle, title); }
- inline QString documentTitle() const
- { return document()->metaInformation(QTextDocument::DocumentTitle); }
-
- inline bool isUndoRedoEnabled() const
- { return document()->isUndoRedoEnabled(); }
- inline void setUndoRedoEnabled(bool enable)
- { document()->setUndoRedoEnabled(enable); }
-
- LineWrapMode lineWrapMode() const;
- void setLineWrapMode(LineWrapMode mode);
-
- int lineWrapColumnOrWidth() const;
- void setLineWrapColumnOrWidth(int w);
-
- QTextOption::WrapMode wordWrapMode() const;
- void setWordWrapMode(QTextOption::WrapMode policy);
-
- bool find(const QString &exp, QTextDocument::FindFlags options = 0);
-
- inline QString toPlainText() const
- { return document()->toPlainText(); }
-#ifndef QT_NO_TEXTHTMLPARSER
- inline QString toHtml() const
- { return document()->toHtml(); }
-#endif
-
- void ensureCursorVisible();
-
- virtual QVariant loadResource(int type, const QUrl &name);
-#ifndef QT_NO_CONTEXTMENU
- QMenu *createStandardContextMenu();
- QMenu *createStandardContextMenu(const QPoint &position);
-#endif
-
- QTextCursor cursorForPosition(const QPoint &pos) const;
- QRect cursorRect(const QTextCursor &cursor) const;
- QRect cursorRect() const;
-
- QString anchorAt(const QPoint& pos) const;
-
- bool overwriteMode() const;
- void setOverwriteMode(bool overwrite);
-
- int tabStopWidth() const;
- void setTabStopWidth(int width);
-
- int cursorWidth() const;
- void setCursorWidth(int width);
-
- bool acceptRichText() const;
- void setAcceptRichText(bool accept);
-
- struct ExtraSelection
- {
- QTextCursor cursor;
- QTextCharFormat format;
- };
- void setExtraSelections(const QList<ExtraSelection> &selections);
- QList<ExtraSelection> extraSelections() const;
-
- void moveCursor(QTextCursor::MoveOperation operation, QTextCursor::MoveMode mode = QTextCursor::MoveAnchor);
-
- bool canPaste() const;
-
-#ifndef QT_NO_PRINTER
- void print(QPrinter *printer) const;
-#endif
-
-public Q_SLOTS:
- void setFontPointSize(qreal s);
- void setFontFamily(const QString &fontFamily);
- void setFontWeight(int w);
- void setFontUnderline(bool b);
- void setFontItalic(bool b);
- void setTextColor(const QColor &c);
- void setTextBackgroundColor(const QColor &c);
- void setCurrentFont(const QFont &f);
- void setAlignment(Qt::Alignment a);
-
- void setPlainText(const QString &text);
-#ifndef QT_NO_TEXTHTMLPARSER
- void setHtml(const QString &text);
-#endif
- void setText(const QString &text);
-
-#ifndef QT_NO_CLIPBOARD
- void cut();
- void copy();
- void paste();
-#endif
-
- void undo();
- void redo();
-
- void clear();
- void selectAll();
-
- void insertPlainText(const QString &text);
-#ifndef QT_NO_TEXTHTMLPARSER
- void insertHtml(const QString &text);
-#endif // QT_NO_TEXTHTMLPARSER
-
- void append(const QString &text);
-
- void scrollToAnchor(const QString &name);
-
- void zoomIn(int range = 1);
- void zoomOut(int range = 1);
-
-Q_SIGNALS:
- void textChanged();
- void undoAvailable(bool b);
- void redoAvailable(bool b);
- void currentCharFormatChanged(const QTextCharFormat &format);
- void copyAvailable(bool b);
- void selectionChanged();
- void cursorPositionChanged();
-
-protected:
- virtual bool event(QEvent *e);
- virtual void timerEvent(QTimerEvent *e);
- virtual void keyPressEvent(QKeyEvent *e);
- virtual void keyReleaseEvent(QKeyEvent *e);
- virtual void resizeEvent(QResizeEvent *e);
- virtual void paintEvent(QPaintEvent *e);
- virtual void mousePressEvent(QMouseEvent *e);
- virtual void mouseMoveEvent(QMouseEvent *e);
- virtual void mouseReleaseEvent(QMouseEvent *e);
- virtual void mouseDoubleClickEvent(QMouseEvent *e);
- virtual bool focusNextPrevChild(bool next);
-#ifndef QT_NO_CONTEXTMENU
- virtual void contextMenuEvent(QContextMenuEvent *e);
-#endif
-#ifndef QT_NO_DRAGANDDROP
- virtual void dragEnterEvent(QDragEnterEvent *e);
- virtual void dragLeaveEvent(QDragLeaveEvent *e);
- virtual void dragMoveEvent(QDragMoveEvent *e);
- virtual void dropEvent(QDropEvent *e);
-#endif
- virtual void focusInEvent(QFocusEvent *e);
- virtual void focusOutEvent(QFocusEvent *e);
- virtual void showEvent(QShowEvent *);
- virtual void changeEvent(QEvent *e);
-#ifndef QT_NO_WHEELEVENT
- virtual void wheelEvent(QWheelEvent *e);
-#endif
-
- virtual QMimeData *createMimeDataFromSelection() const;
- virtual bool canInsertFromMimeData(const QMimeData *source) const;
- virtual void insertFromMimeData(const QMimeData *source);
-
- virtual void inputMethodEvent(QInputMethodEvent *);
- QVariant inputMethodQuery(Qt::InputMethodQuery property) const;
-
- QTextEdit(QTextEditPrivate &dd, QWidget *parent);
-
- virtual void scrollContentsBy(int dx, int dy);
-
-#ifdef QT3_SUPPORT
-Q_SIGNALS:
- QT_MOC_COMPAT void currentFontChanged(const QFont &f);
- QT_MOC_COMPAT void currentColorChanged(const QColor &c);
-
-public:
- QT3_SUPPORT_CONSTRUCTOR QTextEdit(QWidget *parent, const char *name);
- inline QT3_SUPPORT bool find(const QString &exp, bool cs, bool wo)
- {
- QTextDocument::FindFlags flags = 0;
- if (cs)
- flags |= QTextDocument::FindCaseSensitively;
- if (wo)
- flags |= QTextDocument::FindWholeWords;
- return find(exp, flags);
- }
-
- inline QT3_SUPPORT void sync() {}
-
- QT3_SUPPORT void moveCursor(CursorAction action, QTextCursor::MoveMode mode = QTextCursor::MoveAnchor);
- QT3_SUPPORT void moveCursor(CursorAction action, bool select);
-
- enum KeyboardAction {
- ActionBackspace,
- ActionDelete,
- ActionReturn,
- ActionKill,
- ActionWordBackspace,
- ActionWordDelete
- };
-
- QT3_SUPPORT void doKeyboardAction(KeyboardAction action);
-
- QT3_SUPPORT QString text() const;
- QT3_SUPPORT void setTextFormat(Qt::TextFormat);
- QT3_SUPPORT Qt::TextFormat textFormat() const;
-
- inline QT3_SUPPORT void setBold(bool b) { setFontWeight(b ? QFont::Bold : QFont::Normal); }
- inline QT3_SUPPORT void setUnderline(bool b) { setFontUnderline(b); }
- inline QT3_SUPPORT void setItalic(bool i) { setFontItalic(i); }
- inline QT3_SUPPORT void setFamily(const QString &family) { setFontFamily(family); }
- inline QT3_SUPPORT void setPointSize(int size) { setFontPointSize(size); }
-
- inline QT3_SUPPORT bool italic() const { return fontItalic(); }
- inline QT3_SUPPORT bool bold() const { return fontWeight() >= QFont::Bold; }
- inline QT3_SUPPORT bool underline() const { return fontUnderline(); }
- inline QT3_SUPPORT QString family() const { return fontFamily(); }
- inline QT3_SUPPORT int pointSize() const { return (int)(fontPointSize()+0.5); }
-
- inline QT3_SUPPORT bool hasSelectedText() const
- { return textCursor().hasSelection(); }
- inline QT3_SUPPORT QString selectedText() const
- { return textCursor().selectedText(); }
-
- inline QT3_SUPPORT bool isUndoAvailable() const
- { return document()->isUndoAvailable(); }
- inline QT3_SUPPORT bool isRedoAvailable() const
- { return document()->isRedoAvailable(); }
-
- inline QT3_SUPPORT void insert(const QString &text)
- { insertPlainText(text); }
-
- inline QT3_SUPPORT bool isModified() const
- { return document()->isModified(); }
-
- inline QT3_SUPPORT QColor color() const
- { return textColor(); }
-
-public Q_SLOTS:
- inline QT_MOC_COMPAT void setModified(bool m = true)
- { document()->setModified(m); }
-public:
- inline QT3_SUPPORT void undo() const
- { document()->undo(); }
- inline QT3_SUPPORT void redo() const
- { document()->redo(); }
-
-public Q_SLOTS:
- inline QT_MOC_COMPAT void setColor(const QColor &c)
- { setTextColor(c); }
-
-#endif
-
-private:
- Q_DISABLE_COPY(QTextEdit)
- Q_PRIVATE_SLOT(d_func(), void _q_repaintContents(const QRectF &r))
- Q_PRIVATE_SLOT(d_func(), void _q_currentCharFormatChanged(const QTextCharFormat &))
- Q_PRIVATE_SLOT(d_func(), void _q_adjustScrollbars())
- Q_PRIVATE_SLOT(d_func(), void _q_ensureVisible(const QRectF &))
- friend class QTextEditControl;
- friend class QTextDocument;
- friend class QTextControl;
-};
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QTextEdit::AutoFormatting)
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QT_NO_TEXTEDIT
-
-#endif // QTEXTEDIT_H
diff --git a/src/gui/widgets/qtextedit_p.h b/src/gui/widgets/qtextedit_p.h
deleted file mode 100644
index 98431f87ba..0000000000
--- a/src/gui/widgets/qtextedit_p.h
+++ /dev/null
@@ -1,141 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QTEXTEDIT_P_H
-#define QTEXTEDIT_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "private/qabstractscrollarea_p.h"
-#include "QtGui/qtextdocumentfragment.h"
-#include "QtGui/qscrollbar.h"
-#include "QtGui/qtextcursor.h"
-#include "QtGui/qtextformat.h"
-#include "QtGui/qmenu.h"
-#include "QtGui/qabstracttextdocumentlayout.h"
-#include "QtCore/qbasictimer.h"
-#include "QtCore/qurl.h"
-#include "private/qtextcontrol_p.h"
-#include "qtextedit.h"
-
-QT_BEGIN_NAMESPACE
-
-#ifndef QT_NO_TEXTEDIT
-
-class QMimeData;
-class QTextEditPrivate : public QAbstractScrollAreaPrivate
-{
- Q_DECLARE_PUBLIC(QTextEdit)
-public:
- QTextEditPrivate();
-
- void init(const QString &html = QString());
- void paint(QPainter *p, QPaintEvent *e);
- void _q_repaintContents(const QRectF &contentsRect);
-
- inline QPoint mapToContents(const QPoint &point) const
- { return QPoint(point.x() + horizontalOffset(), point.y() + verticalOffset()); }
-
- void _q_adjustScrollbars();
- void _q_ensureVisible(const QRectF &rect);
- void relayoutDocument();
-
- void createAutoBulletList();
- void pageUpDown(QTextCursor::MoveOperation op, QTextCursor::MoveMode moveMode);
-
- inline int horizontalOffset() const
- { return q_func()->isRightToLeft() ? (hbar->maximum() - hbar->value()) : hbar->value(); }
- inline int verticalOffset() const
- { return vbar->value(); }
-
- inline void sendControlEvent(QEvent *e)
- { control->processEvent(e, QPointF(horizontalOffset(), verticalOffset()), viewport); }
-
- void _q_currentCharFormatChanged(const QTextCharFormat &format);
-
- void updateDefaultTextOption();
-
- // re-implemented by QTextBrowser, called by QTextDocument::loadResource
- virtual QUrl resolveUrl(const QUrl &url) const
- { return url; }
-
- QTextControl *control;
-
- QTextEdit::AutoFormatting autoFormatting;
- bool tabChangesFocus;
-
- QBasicTimer autoScrollTimer;
- QPoint autoScrollDragPos;
-
- QTextEdit::LineWrapMode lineWrap;
- int lineWrapColumnOrWidth;
- QTextOption::WrapMode wordWrap;
-
- uint ignoreAutomaticScrollbarAdjustment : 1;
- uint preferRichText : 1;
- uint showCursorOnInitialShow : 1;
- uint inDrag : 1;
- uint clickCausedFocus : 1;
-
- // Qt3 COMPAT only, for setText
- Qt::TextFormat textFormat;
-
- QString anchorToScrollToWhenVisible;
-
-#ifdef QT_KEYPAD_NAVIGATION
- QBasicTimer deleteAllTimer;
-#endif
-};
-#endif // QT_NO_TEXTEDIT
-
-
-QT_END_NAMESPACE
-
-#endif // QTEXTEDIT_P_H
diff --git a/src/gui/widgets/qtoolbar.cpp b/src/gui/widgets/qtoolbar.cpp
deleted file mode 100644
index e0e8ce603a..0000000000
--- a/src/gui/widgets/qtoolbar.cpp
+++ /dev/null
@@ -1,1349 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qtoolbar.h"
-
-#ifndef QT_NO_TOOLBAR
-
-#include <qapplication.h>
-#include <qcombobox.h>
-#include <qevent.h>
-#include <qlayout.h>
-#include <qmainwindow.h>
-#include <qmenu.h>
-#include <qmenubar.h>
-#include <qrubberband.h>
-#include <qsignalmapper.h>
-#include <qstylepainter.h>
-#include <qtoolbutton.h>
-#include <qwidgetaction.h>
-#include <qtimer.h>
-#include <private/qwidgetaction_p.h>
-#ifdef Q_WS_MAC
-#include <private/qt_mac_p.h>
-#include <private/qt_cocoa_helpers_mac_p.h>
-#endif
-
-#include <private/qmainwindowlayout_p.h>
-
-#include "qtoolbar_p.h"
-#include "qtoolbarseparator_p.h"
-#include "qtoolbarlayout_p.h"
-
-#include "qdebug.h"
-
-#define POPUP_TIMER_INTERVAL 500
-
-QT_BEGIN_NAMESPACE
-
-#ifdef Q_WS_MAC
-static void qt_mac_updateToolBarButtonHint(QWidget *parentWidget)
-{
- if (!(parentWidget->windowFlags() & Qt::CustomizeWindowHint))
- parentWidget->setWindowFlags(parentWidget->windowFlags() | Qt::MacWindowToolBarButtonHint);
-}
-#endif
-
-// qmainwindow.cpp
-extern QMainWindowLayout *qt_mainwindow_layout(const QMainWindow *window);
-
-/******************************************************************************
-** QToolBarPrivate
-*/
-
-void QToolBarPrivate::init()
-{
- Q_Q(QToolBar);
- q->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed));
- q->setBackgroundRole(QPalette::Button);
- q->setAttribute(Qt::WA_Hover);
- q->setAttribute(Qt::WA_X11NetWmWindowTypeToolBar);
-
- QStyle *style = q->style();
- int e = style->pixelMetric(QStyle::PM_ToolBarIconSize, 0, q);
- iconSize = QSize(e, e);
-
- layout = new QToolBarLayout(q);
- layout->updateMarginAndSpacing();
-
-#ifdef Q_WS_MAC
- if (q->parentWidget() && q->parentWidget()->isWindow()) {
- // Make sure that the window has the "toolbar" button.
- QWidget *parentWidget = q->parentWidget();
- qt_mac_updateToolBarButtonHint(parentWidget);
- reinterpret_cast<QToolBar *>(parentWidget)->d_func()->createWinId(); // Please let me create your winId...
- extern OSWindowRef qt_mac_window_for(const QWidget *); // qwidget_mac.cpp
- macWindowToolbarShow(q->parentWidget(), true);
- }
-#endif
-
- toggleViewAction = new QAction(q);
- toggleViewAction->setCheckable(true);
- q->setMovable(q->style()->styleHint(QStyle::SH_ToolBar_Movable, 0, q ));
- QObject::connect(toggleViewAction, SIGNAL(triggered(bool)), q, SLOT(_q_toggleView(bool)));
-}
-
-void QToolBarPrivate::_q_toggleView(bool b)
-{
- Q_Q(QToolBar);
- if (b == q->isHidden()) {
- if (b)
- q->show();
- else
- q->close();
- }
-}
-
-void QToolBarPrivate::_q_updateIconSize(const QSize &sz)
-{
- Q_Q(QToolBar);
- if (!explicitIconSize) {
- // iconSize not explicitly set
- q->setIconSize(sz);
- explicitIconSize = false;
- }
-}
-
-void QToolBarPrivate::_q_updateToolButtonStyle(Qt::ToolButtonStyle style)
-{
- Q_Q(QToolBar);
- if (!explicitToolButtonStyle) {
- q->setToolButtonStyle(style);
- explicitToolButtonStyle = false;
- }
-}
-
-void QToolBarPrivate::updateWindowFlags(bool floating, bool unplug)
-{
- Q_Q(QToolBar);
- Qt::WindowFlags flags = floating ? Qt::Tool : Qt::Widget;
-
- flags |= Qt::FramelessWindowHint;
-
- if (unplug) {
- flags |= Qt::X11BypassWindowManagerHint;
-#ifdef Q_WS_MAC
- flags |= Qt::WindowStaysOnTopHint;
-#endif
- }
-
- q->setWindowFlags(flags);
-}
-
-void QToolBarPrivate::setWindowState(bool floating, bool unplug, const QRect &rect)
-{
- Q_Q(QToolBar);
- bool visible = !q->isHidden();
- bool wasFloating = q->isFloating(); // ...is also currently using popup menus
-
- q->hide();
-
- updateWindowFlags(floating, unplug);
-
- if (floating != wasFloating)
- layout->checkUsePopupMenu();
-
- if (!rect.isNull())
- q->setGeometry(rect);
-
- if (visible)
- q->show();
-
- if (floating != wasFloating)
- emit q->topLevelChanged(floating);
-}
-
-void QToolBarPrivate::initDrag(const QPoint &pos)
-{
- Q_Q(QToolBar);
-
- if (state != 0)
- return;
-
- QMainWindow *win = qobject_cast<QMainWindow*>(parent);
- Q_ASSERT(win != 0);
- QMainWindowLayout *layout = qt_mainwindow_layout(win);
- Q_ASSERT(layout != 0);
- if (layout->pluggingWidget != 0) // the main window is animating a docking operation
- return;
-
- state = new DragState;
- state->pressPos = pos;
- state->dragging = false;
- state->moving = false;
- state->widgetItem = 0;
-
- if (q->isRightToLeft())
- state->pressPos = QPoint(q->width() - state->pressPos.x(), state->pressPos.y());
-}
-
-void QToolBarPrivate::startDrag(bool moving)
-{
- Q_Q(QToolBar);
-
- Q_ASSERT(state != 0);
-
- if ((moving && state->moving) || state->dragging)
- return;
-
- QMainWindow *win = qobject_cast<QMainWindow*>(parent);
- Q_ASSERT(win != 0);
- QMainWindowLayout *layout = qt_mainwindow_layout(win);
- Q_ASSERT(layout != 0);
-
- if (!moving) {
- state->widgetItem = layout->unplug(q);
-#if defined(Q_WS_MAC) && !defined(QT_MAC_USE_COCOA)
- if (q->isWindow()) {
- setWindowState(true, true); //set it to floating
- }
-#endif
- Q_ASSERT(state->widgetItem != 0);
- }
- state->dragging = !moving;
- state->moving = moving;
-}
-
-void QToolBarPrivate::endDrag()
-{
- Q_Q(QToolBar);
- Q_ASSERT(state != 0);
-
- q->releaseMouse();
-
- if (state->dragging) {
- QMainWindowLayout *layout = qt_mainwindow_layout(qobject_cast<QMainWindow *>(q->parentWidget()));
- Q_ASSERT(layout != 0);
-
- if (!layout->plug(state->widgetItem)) {
- if (q->isFloatable()) {
- layout->restore();
-#if defined(Q_WS_X11) || defined(Q_WS_MAC)
- setWindowState(true); // gets rid of the X11BypassWindowManager window flag
- // and activates the resizer
-#endif
- q->activateWindow();
- } else {
- layout->revert(state->widgetItem);
- }
- }
- }
-
- delete state;
- state = 0;
-}
-
-bool QToolBarPrivate::mousePressEvent(QMouseEvent *event)
-{
- Q_Q(QToolBar);
- QStyleOptionToolBar opt;
- q->initStyleOption(&opt);
- if (q->style()->subElementRect(QStyle::SE_ToolBarHandle, &opt, q).contains(event->pos()) == false) {
-#ifdef Q_WS_MAC
- // When using the unified toolbar on Mac OS X the user can can click and
- // drag between toolbar contents to move the window. Make this work by
- // implementing the standard mouse-dragging code and then call
- // window->move() in mouseMoveEvent below.
- if (QMainWindow *mainWindow = qobject_cast<QMainWindow *>(parent)) {
- if (mainWindow->toolBarArea(q) == Qt::TopToolBarArea
- && mainWindow->unifiedTitleAndToolBarOnMac()
- && q->childAt(event->pos()) == 0) {
- macWindowDragging = true;
- macWindowDragPressPosition = event->pos();
- return true;
- }
- }
-#endif
- return false;
- }
-
- if (event->button() != Qt::LeftButton)
- return true;
-
- if (!layout->movable())
- return true;
-
- initDrag(event->pos());
- return true;
-}
-
-bool QToolBarPrivate::mouseReleaseEvent(QMouseEvent*)
-{
- if (state != 0) {
- endDrag();
- return true;
- } else {
-#ifdef Q_WS_MAC
- if (!macWindowDragging)
- return false;
- macWindowDragging = false;
- macWindowDragPressPosition = QPoint();
- return true;
-#endif
- return false;
- }
-}
-
-bool QToolBarPrivate::mouseMoveEvent(QMouseEvent *event)
-{
- Q_Q(QToolBar);
-
- if (!state) {
-#ifdef Q_WS_MAC
- if (!macWindowDragging)
- return false;
- QWidget *w = q->window();
- const QPoint delta = event->pos() - macWindowDragPressPosition;
- w->move(w->pos() + delta);
- return true;
-#endif
- return false;
- }
-
- QMainWindow *win = qobject_cast<QMainWindow*>(parent);
- if (win == 0)
- return true;
-
- QMainWindowLayout *layout = qt_mainwindow_layout(win);
- Q_ASSERT(layout != 0);
-
- if (layout->pluggingWidget == 0
- && (event->pos() - state->pressPos).manhattanLength() > QApplication::startDragDistance()) {
- const bool wasDragging = state->dragging;
- const bool moving = !q->isWindow() && (orientation == Qt::Vertical ?
- event->x() >= 0 && event->x() < q->width() :
- event->y() >= 0 && event->y() < q->height());
-
- startDrag(moving);
- if (!moving && !wasDragging) {
-#ifdef Q_OS_WIN
- grabMouseWhileInWindow();
-#else
- q->grabMouse();
-#endif
- }
- }
-
- if (state->dragging) {
- QPoint pos = event->globalPos();
- // if we are right-to-left, we move so as to keep the right edge the same distance
- // from the mouse
- if (q->isLeftToRight())
- pos -= state->pressPos;
- else
- pos += QPoint(state->pressPos.x() - q->width(), -state->pressPos.y());
-
- q->move(pos);
- layout->hover(state->widgetItem, event->globalPos());
- } else if (state->moving) {
-
- const QPoint rtl(q->width() - state->pressPos.x(), state->pressPos.y()); //for RTL
- const QPoint globalPressPos = q->mapToGlobal(q->isRightToLeft() ? rtl : state->pressPos);
- int pos = 0;
-
- QPoint delta = event->globalPos() - globalPressPos;
- if (orientation == Qt::Vertical) {
- pos = q->y() + delta.y();
- } else {
- if (q->isRightToLeft()) {
- pos = win->width() - q->width() - q->x() - delta.x();
- } else {
- pos = q->x() + delta.x();
- }
- }
-
- layout->moveToolBar(q, pos);
- }
- return true;
-}
-
-void QToolBarPrivate::unplug(const QRect &_r)
-{
- Q_Q(QToolBar);
- QRect r = _r;
- r.moveTopLeft(q->mapToGlobal(QPoint(0, 0)));
- setWindowState(true, true, r);
- layout->setExpanded(false);
-}
-
-void QToolBarPrivate::plug(const QRect &r)
-{
- setWindowState(false, false, r);
-}
-
-/******************************************************************************
-** QToolBar
-*/
-
-/*!
- \class QToolBar
-
- \brief The QToolBar class provides a movable panel that contains a
- set of controls.
-
- \ingroup mainwindow-classes
-
-
- Toolbar buttons are added by adding \e actions, using addAction()
- or insertAction(). Groups of buttons can be separated using
- addSeparator() or insertSeparator(). If a toolbar button is not
- appropriate, a widget can be inserted instead using addWidget() or
- insertWidget(); examples of suitable widgets are QSpinBox,
- QDoubleSpinBox, and QComboBox. When a toolbar button is pressed it
- emits the actionTriggered() signal.
-
- A toolbar can be fixed in place in a particular area (e.g. at the
- top of the window), or it can be movable (isMovable()) between
- toolbar areas; see allowedAreas() and isAreaAllowed().
-
- When a toolbar is resized in such a way that it is too small to
- show all the items it contains, an extension button will appear as
- the last item in the toolbar. Pressing the extension button will
- pop up a menu containing the items that does not currently fit in
- the toolbar.
-
- When a QToolBar is not a child of a QMainWindow, it looses the ability
- to populate the extension pop up with widgets added to the toolbar using
- addWidget(). Please use widget actions created by inheriting QWidgetAction
- and implementing QWidgetAction::createWidget() instead.
-
- \sa QToolButton, QMenu, QAction, {Application Example}
-*/
-
-/*!
- \fn bool QToolBar::isAreaAllowed(Qt::ToolBarArea area) const
-
- Returns true if this toolbar is dockable in the given \a area;
- otherwise returns false.
-*/
-
-/*!
- \fn void QToolBar::addAction(QAction *action)
- \overload
-
- Appends the action \a action to the toolbar's list of actions.
-
- \sa QMenu::addAction(), QWidget::addAction()
-*/
-
-/*!
- \fn void QToolBar::actionTriggered(QAction *action)
-
- This signal is emitted when an action in this toolbar is triggered.
- This happens when the action's tool button is pressed, or when the
- action is triggered in some other way outside the tool bar. The parameter
- holds the triggered \a action.
-*/
-
-/*!
- \fn void QToolBar::allowedAreasChanged(Qt::ToolBarAreas allowedAreas)
-
- This signal is emitted when the collection of allowed areas for the
- toolbar is changed. The new areas in which the toolbar can be positioned
- are specified by \a allowedAreas.
-
- \sa allowedAreas
-*/
-
-/*!
- \fn void QToolBar::iconSizeChanged(const QSize &iconSize)
-
- This signal is emitted when the icon size is changed. The \a
- iconSize parameter holds the toolbar's new icon size.
-
- \sa iconSize QMainWindow::iconSize
-*/
-
-/*!
- \fn void QToolBar::movableChanged(bool movable)
-
- This signal is emitted when the toolbar becomes movable or fixed.
- If the toolbar can be moved, \a movable is true; otherwise it is
- false.
-
- \sa movable
-*/
-
-/*!
- \fn void QToolBar::orientationChanged(Qt::Orientation orientation)
-
- This signal is emitted when the orientation of the toolbar changes.
- The new orientation is specified by the \a orientation given.
-
- \sa orientation
-*/
-
-/*!
- \fn void QToolBar::toolButtonStyleChanged(Qt::ToolButtonStyle toolButtonStyle)
-
- This signal is emitted when the tool button style is changed. The
- \a toolButtonStyle parameter holds the toolbar's new tool button
- style.
-
- \sa toolButtonStyle QMainWindow::toolButtonStyle
-*/
-
-/*!
- \since 4.6
-
- \fn void QToolBar::topLevelChanged(bool topLevel)
-
- This signal is emitted when the \l floating property changes.
- The \a topLevel parameter is true if the toolbar is now floating;
- otherwise it is false.
-
- \sa isWindow()
-*/
-
-
-/*!
- \fn void QToolBar::visibilityChanged(bool visible)
- \since 4.7
-
- This signal is emitted when the toolbar becomes \a visible (or
- invisible). This happens when the widget is hidden or shown.
-*/
-
-/*!
- Constructs a QToolBar with the given \a parent.
-*/
-QToolBar::QToolBar(QWidget *parent)
- : QWidget(*new QToolBarPrivate, parent, 0)
-{
- Q_D(QToolBar);
- d->init();
-}
-
-/*!
- Constructs a QToolBar with the given \a parent.
-
- The given window \a title identifies the toolbar and is shown in
- the context menu provided by QMainWindow.
-
- \sa setWindowTitle()
-*/
-QToolBar::QToolBar(const QString &title, QWidget *parent)
- : QWidget(*new QToolBarPrivate, parent, 0)
-{
- Q_D(QToolBar);
- d->init();
- setWindowTitle(title);
-}
-
-#ifdef QT3_SUPPORT
-/*! \obsolete
- Constructs a QToolBar with the given \a parent and \a name.
-*/
-QToolBar::QToolBar(QWidget *parent, const char *name)
- : QWidget(*new QToolBarPrivate, parent, 0)
-{
- Q_D(QToolBar);
- d->init();
- setObjectName(QString::fromAscii(name));
-}
-#endif
-
-/*!
- Destroys the toolbar.
-*/
-QToolBar::~QToolBar()
-{
- // Remove the toolbar button if there is nothing left.
- QMainWindow *mainwindow = qobject_cast<QMainWindow *>(parentWidget());
- if (mainwindow) {
-#ifdef Q_WS_MAC
- QMainWindowLayout *mainwin_layout = qt_mainwindow_layout(mainwindow);
- if (mainwin_layout && mainwin_layout->layoutState.toolBarAreaLayout.isEmpty()
- && mainwindow->testAttribute(Qt::WA_WState_Created))
- macWindowToolbarShow(mainwindow, false);
-#endif
- }
-}
-
-/*! \property QToolBar::movable
- \brief whether the user can move the toolbar within the toolbar area,
- or between toolbar areas
-
- By default, this property is true.
-
- This property only makes sense if the toolbar is in a
- QMainWindow.
-
- \sa allowedAreas
-*/
-
-void QToolBar::setMovable(bool movable)
-{
- Q_D(QToolBar);
- if (!movable == !d->movable)
- return;
- d->movable = movable;
- d->layout->invalidate();
- emit movableChanged(d->movable);
-}
-
-bool QToolBar::isMovable() const
-{
- Q_D(const QToolBar);
- return d->movable;
-}
-
-/*!
- \property QToolBar::floatable
- \brief whether the toolbar can be dragged and dropped as an independent window.
-
- The default is true.
-*/
-bool QToolBar::isFloatable() const
-{
- Q_D(const QToolBar);
- return d->floatable;
-}
-
-void QToolBar::setFloatable(bool floatable)
-{
- Q_D(QToolBar);
- d->floatable = floatable;
-}
-
-/*!
- \property QToolBar::floating
- \brief whether the toolbar is an independent window.
-
- By default, this property is true.
-
- \sa QWidget::isWindow()
-*/
-bool QToolBar::isFloating() const
-{
- return isWindow();
-}
-
-/*!
- \property QToolBar::allowedAreas
- \brief areas where the toolbar may be placed
-
- The default is Qt::AllToolBarAreas.
-
- This property only makes sense if the toolbar is in a
- QMainWindow.
-
- \sa movable
-*/
-
-void QToolBar::setAllowedAreas(Qt::ToolBarAreas areas)
-{
- Q_D(QToolBar);
- areas &= Qt::ToolBarArea_Mask;
- if (areas == d->allowedAreas)
- return;
- d->allowedAreas = areas;
- emit allowedAreasChanged(d->allowedAreas);
-}
-
-Qt::ToolBarAreas QToolBar::allowedAreas() const
-{
- Q_D(const QToolBar);
-#ifdef Q_WS_MAC
- if (QMainWindow *window = qobject_cast<QMainWindow *>(parentWidget())) {
- if (window->unifiedTitleAndToolBarOnMac()) // Don't allow drags to the top (for now).
- return (d->allowedAreas & ~Qt::TopToolBarArea);
- }
-#endif
- return d->allowedAreas;
-}
-
-/*! \property QToolBar::orientation
- \brief orientation of the toolbar
-
- The default is Qt::Horizontal.
-
- This function should not be used when the toolbar is managed
- by QMainWindow. You can use QMainWindow::addToolBar() or
- QMainWindow::insertToolBar() if you wish to move a toolbar (that
- is already added to a main window) to another Qt::ToolBarArea.
-*/
-
-void QToolBar::setOrientation(Qt::Orientation orientation)
-{
- Q_D(QToolBar);
- if (orientation == d->orientation)
- return;
-
- d->orientation = orientation;
-
- if (orientation == Qt::Vertical)
- setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred));
- else
- setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed));
-
- d->layout->invalidate();
- d->layout->activate();
-
- emit orientationChanged(d->orientation);
-}
-
-Qt::Orientation QToolBar::orientation() const
-{ Q_D(const QToolBar); return d->orientation; }
-
-/*!
- \property QToolBar::iconSize
- \brief size of icons in the toolbar.
-
- The default size is determined by the application's style and is
- derived from the QStyle::PM_ToolBarIconSize pixel metric. It is
- the maximum size an icon can have. Icons of smaller size will not
- be scaled up.
-*/
-
-QSize QToolBar::iconSize() const
-{ Q_D(const QToolBar); return d->iconSize; }
-
-void QToolBar::setIconSize(const QSize &iconSize)
-{
- Q_D(QToolBar);
- QSize sz = iconSize;
- if (!sz.isValid()) {
- QMainWindow *mw = qobject_cast<QMainWindow *>(parentWidget());
- if (mw && mw->layout()) {
- QLayout *layout = mw->layout();
- int i = 0;
- QLayoutItem *item = 0;
- do {
- item = layout->itemAt(i++);
- if (item && (item->widget() == this))
- sz = mw->iconSize();
- } while (!sz.isValid() && item != 0);
- }
- }
- if (!sz.isValid()) {
- const int metric = style()->pixelMetric(QStyle::PM_ToolBarIconSize, 0, this);
- sz = QSize(metric, metric);
- }
- if (d->iconSize != sz) {
- d->iconSize = sz;
- setMinimumSize(0, 0);
- emit iconSizeChanged(d->iconSize);
- }
- d->explicitIconSize = iconSize.isValid();
-
- d->layout->invalidate();
-}
-
-/*!
- \property QToolBar::toolButtonStyle
- \brief the style of toolbar buttons
-
- This property defines the style of all tool buttons that are added
- as \l{QAction}s. Note that if you add a QToolButton with the
- addWidget() method, it will not get this button style.
-
- The default is Qt::ToolButtonIconOnly.
-*/
-
-Qt::ToolButtonStyle QToolBar::toolButtonStyle() const
-{ Q_D(const QToolBar); return d->toolButtonStyle; }
-
-void QToolBar::setToolButtonStyle(Qt::ToolButtonStyle toolButtonStyle)
-{
- Q_D(QToolBar);
- d->explicitToolButtonStyle = true;
- if (d->toolButtonStyle == toolButtonStyle)
- return;
- d->toolButtonStyle = toolButtonStyle;
- setMinimumSize(0, 0);
- emit toolButtonStyleChanged(d->toolButtonStyle);
-}
-
-/*!
- Removes all actions from the toolbar.
-
- \sa removeAction()
-*/
-void QToolBar::clear()
-{
- QList<QAction *> actions = this->actions();
- for(int i = 0; i < actions.size(); i++)
- removeAction(actions.at(i));
-}
-
-/*!
- \overload
-
- Creates a new action with the given \a text. This action is added to
- the end of the toolbar.
-*/
-QAction *QToolBar::addAction(const QString &text)
-{
- QAction *action = new QAction(text, this);
- addAction(action);
- return action;
-}
-
-/*!
- \overload
-
- Creates a new action with the given \a icon and \a text. This
- action is added to the end of the toolbar.
-*/
-QAction *QToolBar::addAction(const QIcon &icon, const QString &text)
-{
- QAction *action = new QAction(icon, text, this);
- addAction(action);
- return action;
-}
-
-/*!
- \overload
-
- Creates a new action with the given \a text. This action is added to
- the end of the toolbar. The action's \link QAction::triggered()
- triggered()\endlink signal is connected to \a member in \a
- receiver.
-*/
-QAction *QToolBar::addAction(const QString &text,
- const QObject *receiver, const char* member)
-{
- QAction *action = new QAction(text, this);
- QObject::connect(action, SIGNAL(triggered(bool)), receiver, member);
- addAction(action);
- return action;
-}
-
-/*!
- \overload
-
- Creates a new action with the icon \a icon and text \a text. This
- action is added to the end of the toolbar. The action's \link
- QAction::triggered() triggered()\endlink signal is connected to \a
- member in \a receiver.
-*/
-QAction *QToolBar::addAction(const QIcon &icon, const QString &text,
- const QObject *receiver, const char* member)
-{
- QAction *action = new QAction(icon, text, this);
- QObject::connect(action, SIGNAL(triggered(bool)), receiver, member);
- addAction(action);
- return action;
-}
-
-/*!
- Adds a separator to the end of the toolbar.
-
- \sa insertSeparator()
-*/
-QAction *QToolBar::addSeparator()
-{
- QAction *action = new QAction(this);
- action->setSeparator(true);
- addAction(action);
- return action;
-}
-
-/*!
- Inserts a separator into the toolbar in front of the toolbar
- item associated with the \a before action.
-
- \sa addSeparator()
-*/
-QAction *QToolBar::insertSeparator(QAction *before)
-{
- QAction *action = new QAction(this);
- action->setSeparator(true);
- insertAction(before, action);
- return action;
-}
-
-/*!
- Adds the given \a widget to the toolbar as the toolbar's last
- item.
-
- The toolbar takes ownership of \a widget.
-
- If you add a QToolButton with this method, the tools bar's
- Qt::ToolButtonStyle will not be respected.
-
- \note You should use QAction::setVisible() to change the
- visibility of the widget. Using QWidget::setVisible(),
- QWidget::show() and QWidget::hide() does not work.
-
- \sa insertWidget()
-*/
-QAction *QToolBar::addWidget(QWidget *widget)
-{
- QWidgetAction *action = new QWidgetAction(this);
- action->setDefaultWidget(widget);
- action->d_func()->autoCreated = true;
- addAction(action);
- return action;
-}
-
-/*!
- Inserts the given \a widget in front of the toolbar item
- associated with the \a before action.
-
- Note: You should use QAction::setVisible() to change the
- visibility of the widget. Using QWidget::setVisible(),
- QWidget::show() and QWidget::hide() does not work.
-
- \sa addWidget()
-*/
-QAction *QToolBar::insertWidget(QAction *before, QWidget *widget)
-{
- QWidgetAction *action = new QWidgetAction(this);
- action->setDefaultWidget(widget);
- action->d_func()->autoCreated = true;
- insertAction(before, action);
- return action;
-}
-
-/*!
- \internal
-
- Returns the geometry of the toolbar item associated with the given
- \a action, or an invalid QRect if no matching item is found.
-*/
-QRect QToolBar::actionGeometry(QAction *action) const
-{
- Q_D(const QToolBar);
-
- int index = d->layout->indexOf(action);
- if (index == -1)
- return QRect();
- return d->layout->itemAt(index)->widget()->geometry();
-}
-
-/*!
- Returns the action at point \a p. This function returns zero if no
- action was found.
-
- \sa QWidget::childAt()
-*/
-QAction *QToolBar::actionAt(const QPoint &p) const
-{
- Q_D(const QToolBar);
- QWidget *widget = childAt(p);
- int index = d->layout->indexOf(widget);
- if (index == -1)
- return 0;
- QLayoutItem *item = d->layout->itemAt(index);
- return static_cast<QToolBarItem*>(item)->action;
-}
-
-/*! \fn QAction *QToolBar::actionAt(int x, int y) const
- \overload
-
- Returns the action at the point \a x, \a y. This function returns
- zero if no action was found.
-*/
-
-/*! \reimp */
-void QToolBar::actionEvent(QActionEvent *event)
-{
- Q_D(QToolBar);
- QAction *action = event->action();
- QWidgetAction *widgetAction = qobject_cast<QWidgetAction *>(action);
-
- switch (event->type()) {
- case QEvent::ActionAdded: {
- Q_ASSERT_X(widgetAction == 0 || d->layout->indexOf(widgetAction) == -1,
- "QToolBar", "widgets cannot be inserted multiple times");
-
- // reparent the action to this toolbar if it has been created
- // using the addAction(text) etc. convenience functions, to
- // preserve Qt 4.1.x behavior. The widget is already
- // reparented to us due to the createWidget call inside
- // createItem()
- if (widgetAction != 0 && widgetAction->d_func()->autoCreated)
- widgetAction->setParent(this);
-
- int index = d->layout->count();
- if (event->before()) {
- index = d->layout->indexOf(event->before());
- Q_ASSERT_X(index != -1, "QToolBar::insertAction", "internal error");
- }
- d->layout->insertAction(index, action);
- break;
- }
-
- case QEvent::ActionChanged:
- d->layout->invalidate();
- break;
-
- case QEvent::ActionRemoved: {
- int index = d->layout->indexOf(action);
- if (index != -1) {
- delete d->layout->takeAt(index);
- }
- break;
- }
-
- default:
- Q_ASSERT_X(false, "QToolBar::actionEvent", "internal error");
- }
-}
-
-/*! \reimp */
-void QToolBar::changeEvent(QEvent *event)
-{
- Q_D(QToolBar);
- switch (event->type()) {
- case QEvent::WindowTitleChange:
- d->toggleViewAction->setText(windowTitle());
- break;
- case QEvent::StyleChange:
- d->layout->invalidate();
- if (!d->explicitIconSize)
- setIconSize(QSize());
- d->layout->updateMarginAndSpacing();
- break;
- case QEvent::LayoutDirectionChange:
- d->layout->invalidate();
- break;
- default:
- break;
- }
- QWidget::changeEvent(event);
-}
-
-/*! \reimp */
-void QToolBar::paintEvent(QPaintEvent *)
-{
- Q_D(QToolBar);
-
- QPainter p(this);
- QStyle *style = this->style();
- QStyleOptionToolBar opt;
- initStyleOption(&opt);
-
- if (d->layout->expanded || d->layout->animating || isWindow()) {
- //if the toolbar is expended, we need to fill the background with the window color
- //because some styles may expects that.
- p.fillRect(opt.rect, palette().background());
- style->drawControl(QStyle::CE_ToolBar, &opt, &p, this);
- style->drawPrimitive(QStyle::PE_FrameMenu, &opt, &p, this);
- } else {
- style->drawControl(QStyle::CE_ToolBar, &opt, &p, this);
- }
-
- opt.rect = style->subElementRect(QStyle::SE_ToolBarHandle, &opt, this);
- if (opt.rect.isValid())
- style->drawPrimitive(QStyle::PE_IndicatorToolBarHandle, &opt, &p, this);
-}
-
-/*
- Checks if an expanded toolbar has to wait for this popup to close before
- the toolbar collapses. This is true if
- 1) the popup has the toolbar in its parent chain,
- 2) the popup is a menu whose menuAction is somewhere in the toolbar.
-*/
-static bool waitForPopup(QToolBar *tb, QWidget *popup)
-{
- if (popup == 0 || popup->isHidden())
- return false;
-
- QWidget *w = popup;
- while (w != 0) {
- if (w == tb)
- return true;
- w = w->parentWidget();
- }
-
- QMenu *menu = qobject_cast<QMenu*>(popup);
- if (menu == 0)
- return false;
-
- QAction *action = menu->menuAction();
- QList<QWidget*> widgets = action->associatedWidgets();
- for (int i = 0; i < widgets.count(); ++i) {
- if (waitForPopup(tb, widgets.at(i)))
- return true;
- }
-
- return false;
-}
-
-#if defined(Q_WS_MAC)
-static bool toolbarInUnifiedToolBar(QToolBar *toolbar)
-{
- const QMainWindow *mainWindow = qobject_cast<const QMainWindow *>(toolbar->parentWidget());
- return mainWindow && mainWindow->unifiedTitleAndToolBarOnMac()
- && mainWindow->toolBarArea(toolbar) == Qt::TopToolBarArea;
-}
-#endif
-
-/*! \reimp */
-bool QToolBar::event(QEvent *event)
-{
- Q_D(QToolBar);
-
- switch (event->type()) {
- case QEvent::Timer:
- if (d->waitForPopupTimer.timerId() == static_cast<QTimerEvent*>(event)->timerId()) {
- QWidget *w = QApplication::activePopupWidget();
- if (!waitForPopup(this, w)) {
- d->waitForPopupTimer.stop();
- if (!this->underMouse())
- d->layout->setExpanded(false);
- }
- }
- break;
- case QEvent::Hide:
- if (!isHidden())
- break;
- // fallthrough intended
- case QEvent::Show:
- d->toggleViewAction->setChecked(event->type() == QEvent::Show);
- emit visibilityChanged(event->type() == QEvent::Show);
-#if defined(Q_WS_MAC)
- if (toolbarInUnifiedToolBar(this)) {
- // I can static_cast because I did the qobject_cast in the if above, therefore
- // we must have a QMainWindowLayout here.
- QMainWindowLayout *mwLayout = qt_mainwindow_layout(qobject_cast<QMainWindow *>(parentWidget()));
- mwLayout->fixSizeInUnifiedToolbar(this);
- mwLayout->syncUnifiedToolbarVisibility();
- }
-# if !defined(QT_MAC_USE_COCOA)
- // Fall through
- case QEvent::LayoutRequest: {
- // There's currently no way to invalidate the size and let
- // HIToolbar know about it. This forces a re-check.
- int earlyResult = -1;
- if (QMainWindow *mainWindow = qobject_cast<QMainWindow *>(parentWidget())) {
- bool needUpdate = true;
- if (event->type() == QEvent::LayoutRequest) {
- QSize oldSizeHint = sizeHint();
- earlyResult = QWidget::event(event) ? 1 : 0;
- needUpdate = oldSizeHint != sizeHint();
- }
-
- if (needUpdate) {
- OSWindowRef windowRef = qt_mac_window_for(mainWindow);
- if (toolbarInUnifiedToolBar(this)
- && macWindowToolbarIsVisible(windowRef)) {
- DisableScreenUpdates();
- macWindowToolbarShow(this, false);
- macWindowToolbarShow(this, true);
- EnableScreenUpdates();
- }
- }
-
- if (earlyResult != -1)
- return earlyResult;
- }
- }
-# endif // !QT_MAC_USE_COCOA
-#endif // Q_WS_MAC
- break;
- case QEvent::ParentChange:
- d->layout->checkUsePopupMenu();
-#if defined(Q_WS_MAC)
- if (parentWidget() && parentWidget()->isWindow())
- qt_mac_updateToolBarButtonHint(parentWidget());
-#endif
- break;
-
- case QEvent::MouseButtonPress: {
- if (d->mousePressEvent(static_cast<QMouseEvent*>(event)))
- return true;
- break;
- }
- case QEvent::MouseButtonRelease:
- if (d->mouseReleaseEvent(static_cast<QMouseEvent*>(event)))
- return true;
- break;
- case QEvent::HoverEnter:
- case QEvent::HoverLeave:
- // there's nothing special to do here and we don't want to update the whole widget
- return true;
- case QEvent::HoverMove: {
-#ifndef QT_NO_CURSOR
- QHoverEvent *e = static_cast<QHoverEvent*>(event);
- QStyleOptionToolBar opt;
- initStyleOption(&opt);
- if (style()->subElementRect(QStyle::SE_ToolBarHandle, &opt, this).contains(e->pos()))
- setCursor(Qt::SizeAllCursor);
- else
- unsetCursor();
-#endif
- break;
- }
- case QEvent::MouseMove:
- if (d->mouseMoveEvent(static_cast<QMouseEvent*>(event)))
- return true;
- break;
-#ifdef Q_WS_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
- // This is a workaround for loosing the mouse on Vista.
- QPoint pos = QCursor::pos();
- QMouseEvent fake(QEvent::MouseMove, mapFromGlobal(pos), pos, Qt::NoButton,
- QApplication::mouseButtons(), QApplication::keyboardModifiers());
- d->mouseMoveEvent(&fake);
-#endif
- } else {
- if (!d->layout->expanded)
- break;
-
- QWidget *w = QApplication::activePopupWidget();
- if (waitForPopup(this, w)) {
- d->waitForPopupTimer.start(POPUP_TIMER_INTERVAL, this);
- break;
- }
-
- d->waitForPopupTimer.stop();
- d->layout->setExpanded(false);
- break;
- }
- default:
- break;
- }
- return QWidget::event(event);
-}
-
-/*!
- Returns a checkable action that can be used to show or hide this
- toolbar.
-
- The action's text is set to the toolbar's window title.
-
- \sa QAction::text QWidget::windowTitle
-*/
-QAction *QToolBar::toggleViewAction() const
-{ Q_D(const QToolBar); return d->toggleViewAction; }
-
-/*!
- \fn void QToolBar::setLabel(const QString &label)
-
- Use setWindowTitle() instead.
-*/
-
-/*!
- \fn QString QToolBar::label() const
-
- Use windowTitle() instead.
-*/
-
-/*!
- \since 4.2
-
- Returns the widget associated with the specified \a action.
-
- \sa addWidget()
-*/
-QWidget *QToolBar::widgetForAction(QAction *action) const
-{
- Q_D(const QToolBar);
-
- int index = d->layout->indexOf(action);
- if (index == -1)
- return 0;
-
- return d->layout->itemAt(index)->widget();
-}
-
-extern QMainWindowLayout *qt_mainwindow_layout(const QMainWindow *window);
-
-/*!
- \internal
-*/
-void QToolBar::initStyleOption(QStyleOptionToolBar *option) const
-{
- Q_D(const QToolBar);
-
- if (!option)
- return;
-
- option->initFrom(this);
- if (orientation() == Qt::Horizontal)
- option->state |= QStyle::State_Horizontal;
- option->lineWidth = style()->pixelMetric(QStyle::PM_ToolBarFrameWidth, 0, this);
- option->features = d->layout->movable()
- ? QStyleOptionToolBar::Movable
- : QStyleOptionToolBar::None;
- // if the tool bar is not in a QMainWindow, this will make the painting right
- option->toolBarArea = Qt::NoToolBarArea;
-
- // Add more styleoptions if the toolbar has been added to a mainwindow.
- QMainWindow *mainWindow = qobject_cast<QMainWindow *>(parentWidget());
-
- if (!mainWindow)
- return;
-
- QMainWindowLayout *layout = qt_mainwindow_layout(mainWindow);
- Q_ASSERT_X(layout != 0, "QToolBar::initStyleOption()",
- "QMainWindow->layout() != QMainWindowLayout");
-
- layout->getStyleOptionInfo(option, const_cast<QToolBar *>(this));
-}
-
-/*!
- \reimp
-*/
-void QToolBar::childEvent(QChildEvent *event) // ### remove me in 5.0
-{
- QWidget::childEvent(event);
-}
-
-/*!
- \reimp
-*/
-void QToolBar::resizeEvent(QResizeEvent *event) // ### remove me in 5.0
-{
- QWidget::resizeEvent(event);
-}
-
-QT_END_NAMESPACE
-
-#include "moc_qtoolbar.cpp"
-
-#endif // QT_NO_TOOLBAR
diff --git a/src/gui/widgets/qtoolbar.h b/src/gui/widgets/qtoolbar.h
deleted file mode 100644
index a39ff3c121..0000000000
--- a/src/gui/widgets/qtoolbar.h
+++ /dev/null
@@ -1,188 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDYNAMICTOOLBAR_H
-#define QDYNAMICTOOLBAR_H
-
-#include <QtGui/qwidget.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_TOOLBAR
-
-class QToolBarPrivate;
-
-class QAction;
-class QIcon;
-class QMainWindow;
-class QStyleOptionToolBar;
-
-class Q_GUI_EXPORT QToolBar : public QWidget
-{
- Q_OBJECT
-
- Q_PROPERTY(bool movable READ isMovable WRITE setMovable
- DESIGNABLE (qobject_cast<QMainWindow *>(parentWidget()) != 0)
- NOTIFY movableChanged)
- Q_PROPERTY(Qt::ToolBarAreas allowedAreas READ allowedAreas WRITE setAllowedAreas
- DESIGNABLE (qobject_cast<QMainWindow *>(parentWidget()) != 0)
- NOTIFY allowedAreasChanged)
- Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation
- DESIGNABLE (qobject_cast<QMainWindow *>(parentWidget()) == 0)
- NOTIFY orientationChanged)
- Q_PROPERTY(QSize iconSize READ iconSize WRITE setIconSize NOTIFY iconSizeChanged)
- Q_PROPERTY(Qt::ToolButtonStyle toolButtonStyle READ toolButtonStyle WRITE setToolButtonStyle
- NOTIFY toolButtonStyleChanged)
- Q_PROPERTY(bool floating READ isFloating)
- Q_PROPERTY(bool floatable READ isFloatable WRITE setFloatable)
-
-public:
- explicit QToolBar(const QString &title, QWidget *parent = 0);
- explicit QToolBar(QWidget *parent = 0);
- ~QToolBar();
-
- void setMovable(bool movable);
- bool isMovable() const;
-
- void setAllowedAreas(Qt::ToolBarAreas areas);
- Qt::ToolBarAreas allowedAreas() const;
-
- inline bool isAreaAllowed(Qt::ToolBarArea area) const
- { return (allowedAreas() & area) == area; }
-
- void setOrientation(Qt::Orientation orientation);
- Qt::Orientation orientation() const;
-
- void clear();
-
-#ifdef Q_NO_USING_KEYWORD
- inline void addAction(QAction *action)
- { QWidget::addAction(action); }
-#else
- using QWidget::addAction;
-#endif
-
- QAction *addAction(const QString &text);
- QAction *addAction(const QIcon &icon, const QString &text);
- QAction *addAction(const QString &text, const QObject *receiver, const char* member);
- QAction *addAction(const QIcon &icon, const QString &text,
- const QObject *receiver, const char* member);
-
- QAction *addSeparator();
- QAction *insertSeparator(QAction *before);
-
- QAction *addWidget(QWidget *widget);
- QAction *insertWidget(QAction *before, QWidget *widget);
-
- QRect actionGeometry(QAction *action) const;
- QAction *actionAt(const QPoint &p) const;
- inline QAction *actionAt(int x, int y) const;
-
- QAction *toggleViewAction() const;
-
- QSize iconSize() const;
- Qt::ToolButtonStyle toolButtonStyle() const;
-
- QWidget *widgetForAction(QAction *action) const;
-
- bool isFloatable() const;
- void setFloatable(bool floatable);
- bool isFloating() const;
-
-public Q_SLOTS:
- void setIconSize(const QSize &iconSize);
- void setToolButtonStyle(Qt::ToolButtonStyle toolButtonStyle);
-
-Q_SIGNALS:
- void actionTriggered(QAction *action);
- void movableChanged(bool movable);
- void allowedAreasChanged(Qt::ToolBarAreas allowedAreas);
- void orientationChanged(Qt::Orientation orientation);
- void iconSizeChanged(const QSize &iconSize);
- void toolButtonStyleChanged(Qt::ToolButtonStyle toolButtonStyle);
- void topLevelChanged(bool topLevel);
- void visibilityChanged(bool visible);
-
-protected:
- void actionEvent(QActionEvent *event);
- void changeEvent(QEvent *event);
- void childEvent(QChildEvent *event);
- void paintEvent(QPaintEvent *event);
- void resizeEvent(QResizeEvent *event);
- bool event(QEvent *event);
- void initStyleOption(QStyleOptionToolBar *option) const;
-
-#ifdef QT3_SUPPORT
-public:
- QT3_SUPPORT_CONSTRUCTOR QToolBar(QWidget *parent, const char *name);
- inline QT3_SUPPORT void setLabel(const QString &label)
- { setWindowTitle(label); }
- inline QT3_SUPPORT QString label() const
- { return windowTitle(); }
-#endif
-
-private:
- Q_DECLARE_PRIVATE(QToolBar)
- Q_DISABLE_COPY(QToolBar)
- Q_PRIVATE_SLOT(d_func(), void _q_toggleView(bool))
- Q_PRIVATE_SLOT(d_func(), void _q_updateIconSize(const QSize &))
- Q_PRIVATE_SLOT(d_func(), void _q_updateToolButtonStyle(Qt::ToolButtonStyle))
-
- friend class QMainWindow;
- friend class QMainWindowLayout;
- friend class QToolBarLayout;
- friend class QToolBarAreaLayout;
-};
-
-inline QAction *QToolBar::actionAt(int ax, int ay) const
-{ return actionAt(QPoint(ax, ay)); }
-
-#endif // QT_NO_TOOLBAR
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QDYNAMICTOOLBAR_H
diff --git a/src/gui/widgets/qtoolbar_p.h b/src/gui/widgets/qtoolbar_p.h
deleted file mode 100644
index cd278cfea0..0000000000
--- a/src/gui/widgets/qtoolbar_p.h
+++ /dev/null
@@ -1,135 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDYNAMICTOOLBAR_P_H
-#define QDYNAMICTOOLBAR_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qtoolbar.h"
-#include "QtGui/qaction.h"
-#include "private/qwidget_p.h"
-#include <QtCore/qbasictimer.h>
-
-QT_BEGIN_NAMESPACE
-
-#ifndef QT_NO_TOOLBAR
-
-class QToolBarLayout;
-class QTimer;
-
-class QToolBarPrivate : public QWidgetPrivate
-{
- Q_DECLARE_PUBLIC(QToolBar)
-
-public:
- inline QToolBarPrivate()
- : explicitIconSize(false), explicitToolButtonStyle(false), movable(true), floatable(true),
- allowedAreas(Qt::AllToolBarAreas), orientation(Qt::Horizontal),
- toolButtonStyle(Qt::ToolButtonIconOnly),
- layout(0), state(0)
-#ifdef Q_WS_MAC
- , macWindowDragging(false)
-#endif
- { }
-
- void init();
- void actionTriggered();
- void _q_toggleView(bool b);
- void _q_updateIconSize(const QSize &sz);
- void _q_updateToolButtonStyle(Qt::ToolButtonStyle style);
-
- bool explicitIconSize;
- bool explicitToolButtonStyle;
- bool movable;
- bool floatable;
- Qt::ToolBarAreas allowedAreas;
- Qt::Orientation orientation;
- Qt::ToolButtonStyle toolButtonStyle;
- QSize iconSize;
-
- QAction *toggleViewAction;
-
- QToolBarLayout *layout;
-
- struct DragState {
- QPoint pressPos;
- bool dragging;
- bool moving;
- QLayoutItem *widgetItem;
- };
- DragState *state;
-
-#ifdef Q_WS_MAC
- bool macWindowDragging;
- QPoint macWindowDragPressPosition;
-#endif
-
- bool mousePressEvent(QMouseEvent *e);
- bool mouseReleaseEvent(QMouseEvent *e);
- bool mouseMoveEvent(QMouseEvent *e);
-
- void updateWindowFlags(bool floating, bool unplug = false);
- void setWindowState(bool floating, bool unplug = false, const QRect &rect = QRect());
- void initDrag(const QPoint &pos);
- void startDrag(bool moving = false);
- void endDrag();
-
- void unplug(const QRect &r);
- void plug(const QRect &r);
-
- QBasicTimer waitForPopupTimer;
-};
-
-#endif // QT_NO_TOOLBAR
-
-QT_END_NAMESPACE
-
-#endif // QDYNAMICTOOLBAR_P_H
diff --git a/src/gui/widgets/qtoolbarextension_p.h b/src/gui/widgets/qtoolbarextension_p.h
deleted file mode 100644
index b986d36efd..0000000000
--- a/src/gui/widgets/qtoolbarextension_p.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDYNAMICTOOLBAREXTENSION_P_H
-#define QDYNAMICTOOLBAREXTENSION_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "QtGui/qtoolbutton.h"
-
-QT_BEGIN_NAMESPACE
-
-#ifndef QT_NO_TOOLBUTTON
-
-class Q_AUTOTEST_EXPORT QToolBarExtension : public QToolButton
-{
- Q_OBJECT
- Qt::Orientation orientation;
-
-public:
- explicit QToolBarExtension(QWidget *parent);
- void paintEvent(QPaintEvent *);
- QSize sizeHint() const;
-
-public Q_SLOTS:
- void setOrientation(Qt::Orientation o);
-};
-
-#endif // QT_NO_TOOLBUTTON
-
-QT_END_NAMESPACE
-
-#endif // QDYNAMICTOOLBAREXTENSION_P_H
diff --git a/src/gui/widgets/qtoolbarlayout_p.h b/src/gui/widgets/qtoolbarlayout_p.h
deleted file mode 100644
index e6e4670610..0000000000
--- a/src/gui/widgets/qtoolbarlayout_p.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QTOOLBARLAYOUT_P_H
-#define QTOOLBARLAYOUT_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtGui/qlayout.h>
-#include <private/qlayoutengine_p.h>
-#include <QVector>
-
-QT_BEGIN_NAMESPACE
-
-#ifndef QT_NO_TOOLBAR
-
-class QAction;
-class QToolBarExtension;
-class QMenu;
-
-class QToolBarItem : public QWidgetItem
-{
-public:
- QToolBarItem(QWidget *widget);
- bool isEmpty() const;
-
- QAction *action;
- bool customWidget;
-};
-
-class QToolBarLayout : public QLayout
-{
- Q_OBJECT
-
-public:
- QToolBarLayout(QWidget *parent = 0);
- ~QToolBarLayout();
-
- void addItem(QLayoutItem *item);
- QLayoutItem *itemAt(int index) const;
- QLayoutItem *takeAt(int index);
- int count() const;
-
- bool isEmpty() const;
- void invalidate();
- Qt::Orientations expandingDirections() const;
-
- void setGeometry(const QRect &r);
- QSize minimumSize() const;
- QSize sizeHint() const;
-
- void insertAction(int index, QAction *action);
- int indexOf(QAction *action) const;
- int indexOf(QWidget *widget) const { return QLayout::indexOf(widget); }
-
- bool layoutActions(const QSize &size);
- QSize expandedSize(const QSize &size) const;
- bool expanded, animating;
-
- void setUsePopupMenu(bool set); // Yeah, there's no getter, but it's internal.
- void checkUsePopupMenu();
-
- bool movable() const;
- void updateMarginAndSpacing();
- bool hasExpandFlag() const;
-
-public Q_SLOTS:
- void setExpanded(bool b);
-
-private:
- QList<QToolBarItem*> items;
- QSize hint, minSize;
- bool dirty, expanding, empty, expandFlag;
- QVector<QLayoutStruct> geomArray;
- QRect handRect;
- QToolBarExtension *extension;
-
- void updateGeomArray() const;
- QToolBarItem *createItem(QAction *action);
- QMenu *popupMenu;
-};
-
-#endif // QT_NO_TOOLBAR
-
-QT_END_NAMESPACE
-
-#endif // QTOOLBARLAYOUT_P_H
diff --git a/src/gui/widgets/qtoolbarseparator_p.h b/src/gui/widgets/qtoolbarseparator_p.h
deleted file mode 100644
index a14f6a2104..0000000000
--- a/src/gui/widgets/qtoolbarseparator_p.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDYNAMICTOOLBARSEPARATOR_P_H
-#define QDYNAMICTOOLBARSEPARATOR_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "QtGui/qwidget.h"
-
-QT_BEGIN_NAMESPACE
-
-#ifndef QT_NO_TOOLBAR
-
-class QStyleOption;
-class QToolBar;
-
-class QToolBarSeparator : public QWidget
-{
- Q_OBJECT
- Qt::Orientation orient;
-
-public:
- explicit QToolBarSeparator(QToolBar *parent);
-
- Qt::Orientation orientation() const;
-
- QSize sizeHint() const;
-
- void paintEvent(QPaintEvent *);
- void initStyleOption(QStyleOption *option) const;
-
-public Q_SLOTS:
- void setOrientation(Qt::Orientation orientation);
-};
-
-#endif // QT_NO_TOOLBAR
-
-QT_END_NAMESPACE
-
-#endif // QDYNAMICTOOLBARSEPARATOR_P_H
diff --git a/src/gui/widgets/qtoolbox.h b/src/gui/widgets/qtoolbox.h
deleted file mode 100644
index f451793a95..0000000000
--- a/src/gui/widgets/qtoolbox.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QTOOLBOX_H
-#define QTOOLBOX_H
-
-#include <QtGui/qframe.h>
-#include <QtGui/qicon.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_TOOLBOX
-
-class QToolBoxPrivate;
-
-class Q_GUI_EXPORT QToolBox : public QFrame
-{
- Q_OBJECT
- Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentChanged)
- Q_PROPERTY(int count READ count)
-
-public:
- explicit QToolBox(QWidget *parent = 0, Qt::WindowFlags f = 0);
- ~QToolBox();
-
- int addItem(QWidget *widget, const QString &text);
- int addItem(QWidget *widget, const QIcon &icon, const QString &text);
- int insertItem(int index, QWidget *widget, const QString &text);
- int insertItem(int index, QWidget *widget, const QIcon &icon, const QString &text);
-
- void removeItem(int index);
-
- void setItemEnabled(int index, bool enabled);
- bool isItemEnabled(int index) const;
-
- void setItemText(int index, const QString &text);
- QString itemText(int index) const;
-
- void setItemIcon(int index, const QIcon &icon);
- QIcon itemIcon(int index) const;
-
-#ifndef QT_NO_TOOLTIP
- void setItemToolTip(int index, const QString &toolTip);
- QString itemToolTip(int index) const;
-#endif
-
- int currentIndex() const;
- QWidget *currentWidget() const;
- QWidget *widget(int index) const;
- int indexOf(QWidget *widget) const;
- int count() const;
-
-public Q_SLOTS:
- void setCurrentIndex(int index);
- void setCurrentWidget(QWidget *widget);
-
-Q_SIGNALS:
- void currentChanged(int index);
-
-protected:
- bool event(QEvent *e);
- virtual void itemInserted(int index);
- virtual void itemRemoved(int index);
- void showEvent(QShowEvent *e);
- void changeEvent(QEvent *);
-
-#ifdef QT3_SUPPORT
-public:
- QT3_SUPPORT_CONSTRUCTOR QToolBox(QWidget *parent, const char *name, Qt::WindowFlags f = 0);
- inline QT3_SUPPORT void setItemLabel(int index, const QString &text) { setItemText(index, text); }
- inline QT3_SUPPORT QString itemLabel(int index) const { return itemText(index); }
- inline QT3_SUPPORT QWidget *currentItem() const { return widget(currentIndex()); }
- inline QT3_SUPPORT void setCurrentItem(QWidget *item) { setCurrentIndex(indexOf(item)); }
- inline QT3_SUPPORT void setItemIconSet(int index, const QIcon &icon) { setItemIcon(index, icon); }
- inline QT3_SUPPORT QIcon itemIconSet(int index) const { return itemIcon(index); }
- inline QT3_SUPPORT int removeItem(QWidget *item)
- { int i = indexOf(item); removeItem(i); return i; }
- inline QT3_SUPPORT QWidget *item(int index) const { return widget(index); }
- QT3_SUPPORT void setMargin(int margin) { setContentsMargins(margin, margin, margin, margin); }
- QT3_SUPPORT int margin() const
- { int margin; int dummy; getContentsMargins(&margin, &dummy, &dummy, &dummy); return margin; }
-#endif
-
-private:
- Q_DECLARE_PRIVATE(QToolBox)
- Q_DISABLE_COPY(QToolBox)
- Q_PRIVATE_SLOT(d_func(), void _q_buttonClicked())
- Q_PRIVATE_SLOT(d_func(), void _q_widgetDestroyed(QObject*))
-};
-
-
-inline int QToolBox::addItem(QWidget *item, const QString &text)
-{ return insertItem(-1, item, QIcon(), text); }
-inline int QToolBox::addItem(QWidget *item, const QIcon &iconSet,
- const QString &text)
-{ return insertItem(-1, item, iconSet, text); }
-inline int QToolBox::insertItem(int index, QWidget *item, const QString &text)
-{ return insertItem(index, item, QIcon(), text); }
-
-#endif // QT_NO_TOOLBOX
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QTOOLBOX_H
diff --git a/src/gui/widgets/qtoolbutton.h b/src/gui/widgets/qtoolbutton.h
deleted file mode 100644
index f6ac37069d..0000000000
--- a/src/gui/widgets/qtoolbutton.h
+++ /dev/null
@@ -1,199 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QTOOLBUTTON_H
-#define QTOOLBUTTON_H
-
-#include <QtGui/qabstractbutton.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_TOOLBUTTON
-
-class QToolButtonPrivate;
-class QMenu;
-class QStyleOptionToolButton;
-
-class Q_GUI_EXPORT QToolButton : public QAbstractButton
-{
- Q_OBJECT
- Q_ENUMS(Qt::ToolButtonStyle Qt::ArrowType ToolButtonPopupMode)
-#ifndef QT_NO_MENU
- Q_PROPERTY(ToolButtonPopupMode popupMode READ popupMode WRITE setPopupMode)
-#endif
- Q_PROPERTY(Qt::ToolButtonStyle toolButtonStyle READ toolButtonStyle WRITE setToolButtonStyle)
- Q_PROPERTY(bool autoRaise READ autoRaise WRITE setAutoRaise)
- Q_PROPERTY(Qt::ArrowType arrowType READ arrowType WRITE setArrowType)
-
-public:
- enum ToolButtonPopupMode {
- DelayedPopup,
- MenuButtonPopup,
- InstantPopup
- };
-
- explicit QToolButton(QWidget * parent=0);
- ~QToolButton();
-
- QSize sizeHint() const;
- QSize minimumSizeHint() const;
-
- Qt::ToolButtonStyle toolButtonStyle() const;
-
- Qt::ArrowType arrowType() const;
- void setArrowType(Qt::ArrowType type);
-
-#ifndef QT_NO_MENU
- void setMenu(QMenu* menu);
- QMenu* menu() const;
-
- void setPopupMode(ToolButtonPopupMode mode);
- ToolButtonPopupMode popupMode() const;
-#endif
-
- QAction *defaultAction() const;
-
- void setAutoRaise(bool enable);
- bool autoRaise() const;
-
-public Q_SLOTS:
-#ifndef QT_NO_MENU
- void showMenu();
-#endif
- void setToolButtonStyle(Qt::ToolButtonStyle style);
- void setDefaultAction(QAction *);
-
-Q_SIGNALS:
- void triggered(QAction *);
-
-protected:
- QToolButton(QToolButtonPrivate &, QWidget* parent);
- bool event(QEvent *e);
- void mousePressEvent(QMouseEvent *);
- void mouseReleaseEvent(QMouseEvent *);
- void paintEvent(QPaintEvent *);
- void actionEvent(QActionEvent *);
-
- void enterEvent(QEvent *);
- void leaveEvent(QEvent *);
- void timerEvent(QTimerEvent *);
- void changeEvent(QEvent *);
-
- bool hitButton(const QPoint &pos) const;
- void nextCheckState();
- void initStyleOption(QStyleOptionToolButton *option) const;
-
-private:
- Q_DISABLE_COPY(QToolButton)
- Q_DECLARE_PRIVATE(QToolButton)
-#ifndef QT_NO_MENU
- Q_PRIVATE_SLOT(d_func(), void _q_buttonPressed())
- Q_PRIVATE_SLOT(d_func(), void _q_updateButtonDown())
- Q_PRIVATE_SLOT(d_func(), void _q_menuTriggered(QAction*))
-#endif
- Q_PRIVATE_SLOT(d_func(), void _q_actionTriggered())
-
-#ifdef QT3_SUPPORT
-public:
- enum TextPosition {
- BesideIcon,
- BelowIcon
- , Right = BesideIcon,
- Under = BelowIcon
- };
-
- QT3_SUPPORT_CONSTRUCTOR QToolButton(QWidget * parent, const char* name);
- QT3_SUPPORT_CONSTRUCTOR QToolButton(Qt::ArrowType type, QWidget *parent, const char* name);
- QT3_SUPPORT_CONSTRUCTOR QToolButton( const QIcon& s, const QString &textLabel,
- const QString& grouptext,
- QObject * receiver, const char* slot,
- QWidget * parent, const char* name=0 );
- inline QT3_SUPPORT void setPixmap(const QPixmap &pixmap) { setIcon(static_cast<QIcon>(pixmap)); }
- QT3_SUPPORT void setOnIconSet(const QIcon&);
- QT3_SUPPORT void setOffIconSet(const QIcon&);
- inline QT3_SUPPORT void setIconSet(const QIcon &icon){setIcon(icon);}
- QT3_SUPPORT void setIconSet(const QIcon &, bool on);
- inline QT3_SUPPORT void setTextLabel(const QString &text, bool tooltip = true) {
- setText(text);
-#ifndef QT_NO_TOOLTIP
- if (tooltip)
- setToolTip(text);
-#else
- Q_UNUSED(tooltip);
-#endif
- }
- inline QT3_SUPPORT QString textLabel() const { return text(); }
- QT3_SUPPORT QIcon onIconSet() const;
- QT3_SUPPORT QIcon offIconSet() const;
- QT3_SUPPORT QIcon iconSet(bool on) const;
- inline QT3_SUPPORT QIcon iconSet() const { return icon(); }
- inline QT3_SUPPORT void openPopup() { showMenu(); }
- inline QT3_SUPPORT void setPopup(QMenu* popup) {setMenu(popup); }
- inline QT3_SUPPORT QMenu* popup() const { return menu(); }
- inline QT3_SUPPORT bool usesBigPixmap() const { return iconSize().height() > 22; }
- inline QT3_SUPPORT bool usesTextLabel() const { return toolButtonStyle() != Qt::ToolButtonIconOnly; }
- inline QT3_SUPPORT TextPosition textPosition() const
- { return toolButtonStyle() == Qt::ToolButtonTextUnderIcon ? BelowIcon : BesideIcon; }
- QT3_SUPPORT void setPopupDelay(int delay);
- QT3_SUPPORT int popupDelay() const;
-
-public Q_SLOTS:
- QT_MOC_COMPAT void setUsesBigPixmap(bool enable)
- { setIconSize(enable?QSize(32,32):QSize(22,22)); }
- QT_MOC_COMPAT void setUsesTextLabel(bool enable)
- { setToolButtonStyle(enable?Qt::ToolButtonTextUnderIcon : Qt::ToolButtonIconOnly); }
- QT_MOC_COMPAT void setTextPosition(QToolButton::TextPosition pos)
- { setToolButtonStyle(pos == BesideIcon ? Qt::ToolButtonTextBesideIcon : Qt::ToolButtonTextUnderIcon); }
-
-#endif
-};
-
-#endif // QT_NO_TOOLBUTTON
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QTOOLBUTTON_H
diff --git a/src/gui/widgets/qwidgetanimator.cpp b/src/gui/widgets/qwidgetanimator.cpp
deleted file mode 100644
index 56e8a1ede8..0000000000
--- a/src/gui/widgets/qwidgetanimator.cpp
+++ /dev/null
@@ -1,117 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtCore/qpropertyanimation.h>
-#include <QtGui/qwidget.h>
-#include <QtGui/private/qmainwindowlayout_p.h>
-
-#include "qwidgetanimator_p.h"
-
-QT_BEGIN_NAMESPACE
-
-QWidgetAnimator::QWidgetAnimator(QMainWindowLayout *layout) : m_mainWindowLayout(layout)
-{
-}
-
-void QWidgetAnimator::abort(QWidget *w)
-{
-#ifndef QT_NO_ANIMATION
- AnimationMap::iterator it = m_animation_map.find(w);
- if (it == m_animation_map.end())
- return;
- QPropertyAnimation *anim = *it;
- m_animation_map.erase(it);
- anim->stop();
-#ifndef QT_NO_MAINWINDOW
- m_mainWindowLayout->animationFinished(w);
-#endif
-#else
- Q_UNUSED(w); //there is no animation to abort
-#endif //QT_NO_ANIMATION
-}
-
-#ifndef QT_NO_ANIMATION
-void QWidgetAnimator::animationFinished()
-{
- QPropertyAnimation *anim = qobject_cast<QPropertyAnimation*>(sender());
- abort(static_cast<QWidget*>(anim->targetObject()));
-}
-#endif //QT_NO_ANIMATION
-
-void QWidgetAnimator::animate(QWidget *widget, const QRect &_final_geometry, bool animate)
-{
- QRect r = widget->geometry();
- if (r.right() < 0 || r.bottom() < 0)
- r = QRect();
-
- animate = animate && !r.isNull() && !_final_geometry.isNull();
-
- // might make the wigdet go away by sending it to negative space
- const QRect final_geometry = _final_geometry.isValid() || widget->isWindow() ? _final_geometry :
- QRect(QPoint(-500 - widget->width(), -500 - widget->height()), widget->size());
-
-#ifndef QT_NO_ANIMATION
- AnimationMap::const_iterator it = m_animation_map.constFind(widget);
- if (it != m_animation_map.constEnd() && (*it)->endValue().toRect() == final_geometry)
- return;
-
- QPropertyAnimation *anim = new QPropertyAnimation(widget, "geometry", widget);
- anim->setDuration(animate ? 200 : 0);
- anim->setEasingCurve(QEasingCurve::InOutQuad);
- anim->setEndValue(final_geometry);
- m_animation_map[widget] = anim;
- connect(anim, SIGNAL(finished()), SLOT(animationFinished()));
- anim->start(QPropertyAnimation::DeleteWhenStopped);
-#else
- //we do it in one shot
- widget->setGeometry(final_geometry);
-#ifndef QT_NO_MAINWINDOW
- m_mainWindowLayout->animationFinished(widget);
-#endif //QT_NO_MAINWINDOW
-#endif //QT_NO_ANIMATION
-}
-
-bool QWidgetAnimator::animating() const
-{
- return !m_animation_map.isEmpty();
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/widgets/qwidgetresizehandler_p.h b/src/gui/widgets/qwidgetresizehandler_p.h
deleted file mode 100644
index 6d63572058..0000000000
--- a/src/gui/widgets/qwidgetresizehandler_p.h
+++ /dev/null
@@ -1,141 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWIDGETRESIZEHANDLER_P_H
-#define QWIDGETRESIZEHANDLER_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. This header file may
-// change from version to version without notice, or even be
-// removed.
-//
-// We mean it.
-//
-
-#include "QtCore/qobject.h"
-#include "QtCore/qpoint.h"
-
-#ifndef QT_NO_RESIZEHANDLER
-
-QT_BEGIN_NAMESPACE
-
-class QMouseEvent;
-class QKeyEvent;
-
-class Q_GUI_EXPORT QWidgetResizeHandler : public QObject
-{
- Q_OBJECT
-
-public:
- enum Action {
- Move = 0x01,
- Resize = 0x02,
- Any = Move|Resize
- };
-
- explicit QWidgetResizeHandler(QWidget *parent, QWidget *cw = 0);
- void setActive(bool b) { setActive(Any, b); }
- void setActive(Action ac, bool b);
- bool isActive() const { return isActive(Any); }
- bool isActive(Action ac) const;
- void setMovingEnabled(bool b) { movingEnabled = b; }
- bool isMovingEnabled() const { return movingEnabled; }
-
- bool isButtonDown() const { return buttonDown; }
-
- void setExtraHeight(int h) { extrahei = h; }
- void setSizeProtection(bool b) { sizeprotect = b; }
-
- void setFrameWidth(int w) { fw = w; }
-
- void doResize();
- void doMove();
-
-Q_SIGNALS:
- void activate();
-
-protected:
- bool eventFilter(QObject *o, QEvent *e);
- void mouseMoveEvent(QMouseEvent *e);
- void keyPressEvent(QKeyEvent *e);
-
-private:
- Q_DISABLE_COPY(QWidgetResizeHandler)
-
- enum MousePosition {
- Nowhere,
- TopLeft, BottomRight, BottomLeft, TopRight,
- Top, Bottom, Left, Right,
- Center
- };
-
- QWidget *widget;
- QWidget *childWidget;
- QPoint moveOffset;
- QPoint invertedMoveOffset;
- MousePosition mode;
- int fw;
- int extrahei;
- int range;
- uint buttonDown :1;
- uint moveResizeMode :1;
- uint activeForResize :1;
- uint sizeprotect :1;
- uint movingEnabled :1;
- uint activeForMove :1;
-
- void setMouseCursor(MousePosition m);
- bool isMove() const {
- return moveResizeMode && mode == Center;
- }
- bool isResize() const {
- return moveResizeMode && !isMove();
- }
-};
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_RESIZEHANDLER
-
-#endif // QWIDGETRESIZEHANDLER_P_H
diff --git a/src/gui/widgets/qworkspace.h b/src/gui/widgets/qworkspace.h
deleted file mode 100644
index 6f6f8c7cee..0000000000
--- a/src/gui/widgets/qworkspace.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWORKSPACE_H
-#define QWORKSPACE_H
-
-#include <QtGui/qwidget.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#ifndef QT_NO_WORKSPACE
-
-class QAction;
-class QWorkspaceChild;
-class QShowEvent;
-class QWorkspacePrivate;
-
-class Q_GUI_EXPORT QWorkspace : public QWidget
-{
- Q_OBJECT
- Q_PROPERTY(bool scrollBarsEnabled READ scrollBarsEnabled WRITE setScrollBarsEnabled)
- Q_PROPERTY(QBrush background READ background WRITE setBackground)
-
-public:
- explicit QWorkspace(QWidget* parent=0);
- ~QWorkspace();
-
- enum WindowOrder { CreationOrder, StackingOrder };
-
- QWidget* activeWindow() const;
- QWidgetList windowList(WindowOrder order = CreationOrder) const;
-
- QWidget * addWindow(QWidget *w, Qt::WindowFlags flags = 0);
-
- QSize sizeHint() const;
-
- bool scrollBarsEnabled() const;
- void setScrollBarsEnabled(bool enable);
-
-#ifdef QT3_SUPPORT
- QT3_SUPPORT_CONSTRUCTOR QWorkspace(QWidget* parent, const char* name);
- QT3_SUPPORT void setPaletteBackgroundColor(const QColor &);
- QT3_SUPPORT void setPaletteBackgroundPixmap(const QPixmap &);
-#endif
-
- void setBackground(const QBrush &background);
- QBrush background() const;
-
-Q_SIGNALS:
- void windowActivated(QWidget* w);
-
-public Q_SLOTS:
- void setActiveWindow(QWidget *w);
- void cascade();
- void tile();
- void arrangeIcons();
- void closeActiveWindow();
- void closeAllWindows();
- void activateNextWindow();
- void activatePreviousWindow();
-
-protected:
- bool event(QEvent *e);
- void paintEvent(QPaintEvent *e);
- void changeEvent(QEvent *);
- void childEvent(QChildEvent *);
- void resizeEvent(QResizeEvent *);
- bool eventFilter(QObject *, QEvent *);
- void showEvent(QShowEvent *e);
- void hideEvent(QHideEvent *e);
-#ifndef QT_NO_WHEELEVENT
- void wheelEvent(QWheelEvent *e);
-#endif
-
-private:
- Q_DECLARE_PRIVATE(QWorkspace)
- Q_DISABLE_COPY(QWorkspace)
- Q_PRIVATE_SLOT(d_func(), void _q_normalizeActiveWindow())
- Q_PRIVATE_SLOT(d_func(), void _q_minimizeActiveWindow())
- Q_PRIVATE_SLOT(d_func(), void _q_showOperationMenu())
- Q_PRIVATE_SLOT(d_func(), void _q_popupOperationMenu(const QPoint&))
- Q_PRIVATE_SLOT(d_func(), void _q_operationMenuActivated(QAction *))
- Q_PRIVATE_SLOT(d_func(), void _q_updateActions())
- Q_PRIVATE_SLOT(d_func(), void _q_scrollBarChanged())
-
- friend class QWorkspaceChild;
-};
-
-#endif // QT_NO_WORKSPACE
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QWORKSPACE_H
diff --git a/src/gui/widgets/widgets.pri b/src/gui/widgets/widgets.pri
deleted file mode 100644
index 6b3d6a984a..0000000000
--- a/src/gui/widgets/widgets.pri
+++ /dev/null
@@ -1,177 +0,0 @@
-# Qt widgets module
-
-HEADERS += \
- widgets/qbuttongroup.h \
- widgets/qabstractbutton.h \
- widgets/qabstractbutton_p.h \
- widgets/qabstractslider.h \
- widgets/qabstractslider_p.h \
- widgets/qabstractspinbox.h \
- widgets/qabstractspinbox_p.h \
- widgets/qcalendartextnavigator_p.h \
- widgets/qcalendarwidget.h \
- widgets/qcheckbox.h \
- widgets/qcombobox.h \
- widgets/qcombobox_p.h \
- widgets/qcommandlinkbutton.h \
- widgets/qdatetimeedit.h \
- widgets/qdatetimeedit_p.h \
- widgets/qdial.h \
- widgets/qdialogbuttonbox.h \
- widgets/qdockwidget.h \
- widgets/qdockwidget_p.h \
- widgets/qdockarealayout_p.h \
- widgets/qfontcombobox.h \
- widgets/qframe.h \
- widgets/qframe_p.h \
- widgets/qgroupbox.h \
- widgets/qlabel.h \
- widgets/qlabel_p.h \
- widgets/qlcdnumber.h \
- widgets/qlineedit.h \
- widgets/qlineedit_p.h \
- widgets/qlinecontrol_p.h \
- widgets/qmainwindow.h \
- widgets/qmainwindowlayout_p.h \
- widgets/qmdiarea.h \
- widgets/qmdiarea_p.h \
- widgets/qmdisubwindow.h \
- widgets/qmdisubwindow_p.h \
- widgets/qmenu.h \
- widgets/qmenu_p.h \
- widgets/qmenubar.h \
- widgets/qmenubar_p.h \
- widgets/qmenudata.h \
- widgets/qprogressbar.h \
- widgets/qpushbutton.h \
- widgets/qpushbutton_p.h \
- widgets/qradiobutton.h \
- widgets/qrubberband.h \
- widgets/qscrollbar.h \
- widgets/qscrollarea_p.h \
- widgets/qsizegrip.h \
- widgets/qslider.h \
- widgets/qspinbox.h \
- widgets/qsplashscreen.h \
- widgets/qsplitter.h \
- widgets/qsplitter_p.h \
- widgets/qstackedwidget.h \
- widgets/qstatusbar.h \
- widgets/qtabbar.h \
- widgets/qtabbar_p.h \
- widgets/qtabwidget.h \
- widgets/qtextedit.h \
- widgets/qtextedit_p.h \
- widgets/qtextbrowser.h \
- widgets/qtoolbar.h \
- widgets/qtoolbar_p.h \
- widgets/qtoolbarlayout_p.h \
- widgets/qtoolbarextension_p.h \
- widgets/qtoolbarseparator_p.h \
- widgets/qtoolbox.h \
- widgets/qtoolbutton.h \
- widgets/qvalidator.h \
- widgets/qabstractscrollarea.h \
- widgets/qabstractscrollarea_p.h \
- widgets/qwidgetresizehandler_p.h \
- widgets/qfocusframe.h \
- widgets/qscrollarea.h \
- widgets/qworkspace.h \
- widgets/qwidgetanimator_p.h \
- widgets/qtoolbararealayout_p.h \
- widgets/qplaintextedit.h \
- widgets/qplaintextedit_p.h \
- widgets/qprintpreviewwidget.h
-SOURCES += \
- widgets/qabstractbutton.cpp \
- widgets/qabstractslider.cpp \
- widgets/qabstractspinbox.cpp \
- widgets/qcalendarwidget.cpp \
- widgets/qcheckbox.cpp \
- widgets/qcombobox.cpp \
- widgets/qcommandlinkbutton.cpp \
- widgets/qdatetimeedit.cpp \
- widgets/qdial.cpp \
- widgets/qdialogbuttonbox.cpp \
- widgets/qdockwidget.cpp \
- widgets/qdockarealayout.cpp \
- widgets/qeffects.cpp \
- widgets/qfontcombobox.cpp \
- widgets/qframe.cpp \
- widgets/qgroupbox.cpp \
- widgets/qlabel.cpp \
- widgets/qlcdnumber.cpp \
- widgets/qlineedit_p.cpp \
- widgets/qlineedit.cpp \
- widgets/qlinecontrol.cpp \
- widgets/qmainwindow.cpp \
- widgets/qmainwindowlayout.cpp \
- widgets/qmdiarea.cpp \
- widgets/qmdisubwindow.cpp \
- widgets/qmenu.cpp \
- widgets/qmenubar.cpp \
- widgets/qmenudata.cpp \
- widgets/qprogressbar.cpp \
- widgets/qpushbutton.cpp \
- widgets/qradiobutton.cpp \
- widgets/qrubberband.cpp \
- widgets/qscrollbar.cpp \
- widgets/qsizegrip.cpp \
- widgets/qslider.cpp \
- widgets/qspinbox.cpp \
- widgets/qsplashscreen.cpp \
- widgets/qsplitter.cpp \
- widgets/qstackedwidget.cpp \
- widgets/qstatusbar.cpp \
- widgets/qtabbar.cpp \
- widgets/qtabwidget.cpp \
- widgets/qtextedit.cpp \
- widgets/qtextbrowser.cpp \
- widgets/qtoolbar.cpp \
- widgets/qtoolbarlayout.cpp \
- widgets/qtoolbarextension.cpp \
- widgets/qtoolbarseparator.cpp \
- widgets/qtoolbox.cpp \
- widgets/qtoolbutton.cpp \
- widgets/qvalidator.cpp \
- widgets/qabstractscrollarea.cpp \
- widgets/qwidgetresizehandler.cpp \
- widgets/qfocusframe.cpp \
- widgets/qscrollarea.cpp \
- widgets/qworkspace.cpp \
- widgets/qwidgetanimator.cpp \
- widgets/qtoolbararealayout.cpp \
- widgets/qplaintextedit.cpp \
- widgets/qprintpreviewwidget.cpp
-
-x11: {
- HEADERS += \
- widgets/qabstractplatformmenubar_p.h
-
- SOURCES += \
- widgets/qmenubar_x11.cpp
-}
-
-!embedded:!qpa:mac {
- HEADERS += widgets/qmacnativewidget_mac.h \
- widgets/qmaccocoaviewcontainer_mac.h
- OBJECTIVE_HEADERS += widgets/qcocoatoolbardelegate_mac_p.h \
- widgets/qcocoamenu_mac_p.h
- OBJECTIVE_SOURCES += widgets/qmenu_mac.mm \
- widgets/qmaccocoaviewcontainer_mac.mm \
- widgets/qcocoatoolbardelegate_mac.mm \
- widgets/qmainwindowlayout_mac.mm \
- widgets/qmacnativewidget_mac.mm \
- widgets/qcocoamenu_mac.mm
-}
-
-wince*: {
- SOURCES += widgets/qmenu_wince.cpp
- HEADERS += widgets/qmenu_wince_resource_p.h
- RC_FILE = widgets/qmenu_wince.rc
- !static: QMAKE_WRITE_DEFAULT_RC = 1
-}
-
-symbian: {
- SOURCES += widgets/qmenu_symbian.cpp
-}
diff --git a/src/modules/qt_gui.pri b/src/modules/qt_gui.pri
index 0d1b2109f8..2dfbb4a604 100644
--- a/src/modules/qt_gui.pri
+++ b/src/modules/qt_gui.pri
@@ -10,5 +10,6 @@ QT.gui.sources = $$QT_MODULE_BASE/src/gui
QT.gui.libs = $$QT_MODULE_LIB_BASE
QT.gui.plugins = $$QT_MODULE_PLUGIN_BASE
QT.gui.imports = $$QT_MODULE_IMPORT_BASE
-QT.gui.depends = core network
+QT.gui.depends = core
+QT.gui.CONFIG = opengl
QT.gui.DEFINES = QT_GUI_LIB
diff --git a/src/modules/qt_opengl.pri b/src/modules/qt_opengl.pri
index 2cc9b8682c..22476cf949 100644
--- a/src/modules/qt_opengl.pri
+++ b/src/modules/qt_opengl.pri
@@ -11,6 +11,6 @@ QT.opengl.sources = $$QT_MODULE_BASE/src/opengl
QT.opengl.libs = $$QT_MODULE_LIB_BASE
QT.opengl.plugins = $$QT_MODULE_PLUGIN_BASE
QT.opengl.imports = $$QT_MODULE_IMPORT_BASE
-QT.opengl.depends = core gui
+QT.opengl.depends = core gui widgets
QT.opengl.CONFIG = opengl
QT.opengl.DEFINES = QT_OPENGL_LIB
diff --git a/src/modules/qt_openvg.pri b/src/modules/qt_openvg.pri
deleted file mode 100644
index a773eb0cca..0000000000
--- a/src/modules/qt_openvg.pri
+++ /dev/null
@@ -1,16 +0,0 @@
-QT.openvg.VERSION = 5.0.0
-QT.openvg.MAJOR_VERSION = 5
-QT.openvg.MINOR_VERSION = 0
-QT.openvg.PATCH_VERSION = 0
-
-QT.openvg.name = QtOpenVG
-QT.openvg.bins = $$QT_MODULE_BIN_BASE
-QT.openvg.includes = $$QT_MODULE_INCLUDE_BASE/QtOpenVG
-QT.openvg.private_includes = $$QT_MODULE_INCLUDE_BASE/QtOpenVG/$$QT.openvg.VERSION
-QT.openvg.sources = $$QT_MODULE_BASE/src/openvg
-QT.openvg.libs = $$QT_MODULE_LIB_BASE
-QT.openvg.plugins = $$QT_MODULE_PLUGIN_BASE
-QT.openvg.imports = $$QT_MODULE_IMPORT_BASE
-QT.openvg.depends = core gui
-QT.openvg.CONFIG = openvg
-QT.openvg.DEFINES = QT_OPENVG_LIB
diff --git a/src/modules/qt_platformsupport.pri b/src/modules/qt_platformsupport.pri
new file mode 100644
index 0000000000..152f69b3e9
--- /dev/null
+++ b/src/modules/qt_platformsupport.pri
@@ -0,0 +1,15 @@
+QT.platformsupport.VERSION = 5.0.0
+QT.platformsupport.MAJOR_VERSION = 5
+QT.platformsupport.MINOR_VERSION = 0
+QT.platformsupport.PATCH_VERSION = 0
+
+QT.platformsupport.name = QtPlatformSupport
+QT.platformsupport.bins = $$QT_MODULE_BIN_BASE
+QT.platformsupport.includes = $$QT_MODULE_INCLUDE_BASE/QtPlatformSupport
+QT.platformsupport.private_includes = $$QT_MODULE_INCLUDE_BASE/QtPlatformSupport/$$QT.platformsupport.VERSION
+QT.platformsupport.sources = $$QT_MODULE_BASE/src/platformsupport
+QT.platformsupport.libs = $$QT_MODULE_LIB_BASE
+QT.platformsupport.plugins = $$QT_MODULE_PLUGIN_BASE
+QT.platformsupport.imports = $$QT_MODULE_IMPORT_BASE
+QT.platformsupport.depends = core gui
+QT.platformsupport.DEFINES =
diff --git a/src/modules/qt_printsupport.pri b/src/modules/qt_printsupport.pri
new file mode 100644
index 0000000000..898f8b82b6
--- /dev/null
+++ b/src/modules/qt_printsupport.pri
@@ -0,0 +1,16 @@
+QT.printsupport.VERSION = 5.0.0
+QT.printsupport.MAJOR_VERSION = 5
+QT.printsupport.MINOR_VERSION = 0
+QT.printsupport.PATCH_VERSION = 0
+
+QT.printsupport.name = QtPrintSupport
+QT.printsupport.includes = $$QT_MODULE_INCLUDE_BASE/QtPrintSupport
+QT.printsupport.private_includes = $$QT_MODULE_INCLUDE_BASE/QtPrintSupport/$$QT.printsupport.VERSION
+QT.printsupport.sources = $$QT_MODULE_BASE/src/printsupport
+QT.printsupport.libs = $$QT_MODULE_LIB_BASE
+QT.printsupport.plugins = $$QT_MODULE_PLUGIN_BASE
+QT.printsupport.imports = $$QT_MODULE_IMPORT_BASE
+QT.printsupport.depends = core gui widgets
+QT.printsupport.DEFINES = QT_PRINTSUPPORT_LIB
+# To be implemented:
+win32: QT.printsupport.DEFINES *= QT_NO_PRINTER
diff --git a/src/modules/qt_widgets.pri b/src/modules/qt_widgets.pri
new file mode 100644
index 0000000000..95d2489cf9
--- /dev/null
+++ b/src/modules/qt_widgets.pri
@@ -0,0 +1,14 @@
+QT.widgets.VERSION = 5.0.0
+QT.widgets.MAJOR_VERSION = 5
+QT.widgets.MINOR_VERSION = 0
+QT.widgets.PATCH_VERSION = 0
+
+QT.widgets.name = QtWidgets
+QT.widgets.includes = $$QT_MODULE_INCLUDE_BASE/QtWidgets
+QT.widgets.private_includes = $$QT_MODULE_INCLUDE_BASE/QtWidgets/$$QT.widgets.VERSION
+QT.widgets.sources = $$QT_MODULE_BASE/src/widgets
+QT.widgets.libs = $$QT_MODULE_LIB_BASE
+QT.widgets.plugins = $$QT_MODULE_PLUGIN_BASE
+QT.widgets.imports = $$QT_MODULE_IMPORT_BASE
+QT.widgets.depends = core network gui
+QT.widgets.DEFINES = QT_WIDGETS_LIB
diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
index 4c50089f6d..aebdce6e01 100644
--- a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
+++ b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
@@ -44,6 +44,8 @@
#include "qpaintengineex_opengl2_p.h"
#include "qglshadercache_p.h"
+#include <QtGui/private/qopenglcontext_p.h>
+
#if defined(QT_DEBUG)
#include <QMetaEnum>
#endif
@@ -52,18 +54,50 @@
QT_BEGIN_NAMESPACE
+class QGLEngineSharedShadersResource : public QOpenGLSharedResource
+{
+public:
+ QGLEngineSharedShadersResource(QOpenGLContext *ctx)
+ : QOpenGLSharedResource(ctx->shareGroup())
+ , m_shaders(new QGLEngineSharedShaders(QGLContext::fromOpenGLContext(ctx)))
+ {
+ }
+
+ ~QGLEngineSharedShadersResource()
+ {
+ delete m_shaders;
+ }
+
+ void invalidateResource()
+ {
+ delete m_shaders;
+ m_shaders = 0;
+ }
+
+ void freeResource(QOpenGLContext *)
+ {
+ }
+
+ QGLEngineSharedShaders *shaders() const { return m_shaders; }
+
+private:
+ QGLEngineSharedShaders *m_shaders;
+};
+
class QGLShaderStorage
{
public:
QGLEngineSharedShaders *shadersForThread(const QGLContext *context) {
- QGLContextGroupResource<QGLEngineSharedShaders> *&shaders = m_storage.localData();
+ QOpenGLMultiGroupSharedResource *&shaders = m_storage.localData();
if (!shaders)
- shaders = new QGLContextGroupResource<QGLEngineSharedShaders>();
- return shaders->value(context);
+ shaders = new QOpenGLMultiGroupSharedResource;
+ QGLEngineSharedShadersResource *resource =
+ shaders->value<QGLEngineSharedShadersResource>(context->contextHandle());
+ return resource ? resource->shaders() : 0;
}
private:
- QThreadStorage<QGLContextGroupResource<QGLEngineSharedShaders> *> m_storage;
+ QThreadStorage<QOpenGLMultiGroupSharedResource *> m_storage;
};
Q_GLOBAL_STATIC(QGLShaderStorage, qt_shader_storage);
@@ -81,8 +115,7 @@ const char* QGLEngineSharedShaders::qShaderSnippets[] = {
};
QGLEngineSharedShaders::QGLEngineSharedShaders(const QGLContext* context)
- : ctxGuard(context)
- , blitShaderProg(0)
+ : blitShaderProg(0)
, simpleShaderProg(0)
{
@@ -327,14 +360,14 @@ QGLEngineShaderProg *QGLEngineSharedShaders::findProgramInCache(const QGLEngineS
vertexSource.append(qShaderSnippets[prog.mainVertexShader]);
vertexSource.append(qShaderSnippets[prog.positionVertexShader]);
- QScopedPointer<QGLShaderProgram> shaderProgram(new QGLShaderProgram(ctxGuard.context(), 0));
+ QScopedPointer<QGLShaderProgram> shaderProgram(new QGLShaderProgram);
CachedShader shaderCache(fragSource, vertexSource);
- bool inCache = shaderCache.load(shaderProgram.data(), ctxGuard.context());
+ bool inCache = shaderCache.load(shaderProgram.data(), QGLContext::currentContext());
if (!inCache) {
- QScopedPointer<QGLShader> fragShader(new QGLShader(QGLShader::Fragment, ctxGuard.context(), 0));
+ QScopedPointer<QGLShader> fragShader(new QGLShader(QGLShader::Fragment));
QByteArray description;
#if defined(QT_DEBUG)
// Name the shader for easier debugging
@@ -357,7 +390,7 @@ QGLEngineShaderProg *QGLEngineSharedShaders::findProgramInCache(const QGLEngineS
break;
}
- QScopedPointer<QGLShader> vertexShader(new QGLShader(QGLShader::Vertex, ctxGuard.context(), 0));
+ QScopedPointer<QGLShader> vertexShader(new QGLShader(QGLShader::Vertex));
#if defined(QT_DEBUG)
// Name the shader for easier debugging
description.clear();
@@ -396,7 +429,7 @@ QGLEngineShaderProg *QGLEngineSharedShaders::findProgramInCache(const QGLEngineS
newProg->program->link();
if (newProg->program->isLinked()) {
if (!inCache)
- shaderCache.store(newProg->program, ctxGuard.context());
+ shaderCache.store(newProg->program, QGLContext::currentContext());
} else {
QLatin1String none("none");
QLatin1String br("\n");
diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h
index 921df369f4..58c761df43 100644
--- a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h
+++ b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h
@@ -365,7 +365,6 @@ public:
void cleanupCustomStage(QGLCustomShaderStage* stage);
private:
- QGLSharedResourceGuard ctxGuard;
QGLShaderProgram *blitShaderProg;
QGLShaderProgram *simpleShaderProg;
QList<QGLEngineShaderProg*> cachedPrograms;
diff --git a/src/opengl/gl2paintengineex/qglgradientcache.cpp b/src/opengl/gl2paintengineex/qglgradientcache.cpp
index 9e6b801c40..6ca09ba140 100644
--- a/src/opengl/gl2paintengineex/qglgradientcache.cpp
+++ b/src/opengl/gl2paintengineex/qglgradientcache.cpp
@@ -51,21 +51,42 @@ class QGL2GradientCacheWrapper
public:
QGL2GradientCache *cacheForContext(const QGLContext *context) {
QMutexLocker lock(&m_mutex);
- return m_resource.value(context);
+ return m_resource.value<QGL2GradientCache>(context->contextHandle());
}
private:
- QGLContextGroupResource<QGL2GradientCache> m_resource;
+ QOpenGLMultiGroupSharedResource m_resource;
QMutex m_mutex;
};
Q_GLOBAL_STATIC(QGL2GradientCacheWrapper, qt_gradient_caches)
+QGL2GradientCache::QGL2GradientCache(QOpenGLContext *ctx)
+ : QOpenGLSharedResource(ctx->shareGroup())
+{
+}
+
+QGL2GradientCache::~QGL2GradientCache()
+{
+ cache.clear();
+}
+
QGL2GradientCache *QGL2GradientCache::cacheForContext(const QGLContext *context)
{
return qt_gradient_caches()->cacheForContext(context);
}
+void QGL2GradientCache::invalidateResource()
+{
+ QMutexLocker lock(&m_mutex);
+ cache.clear();
+}
+
+void QGL2GradientCache::freeResource(QOpenGLContext *)
+{
+ cleanCache();
+}
+
void QGL2GradientCache::cleanCache()
{
QMutexLocker lock(&m_mutex);
diff --git a/src/opengl/gl2paintengineex/qglgradientcache_p.h b/src/opengl/gl2paintengineex/qglgradientcache_p.h
index 1c2d0a029a..600085a75f 100644
--- a/src/opengl/gl2paintengineex/qglgradientcache_p.h
+++ b/src/opengl/gl2paintengineex/qglgradientcache_p.h
@@ -58,7 +58,7 @@
QT_BEGIN_NAMESPACE
-class QGL2GradientCache
+class QGL2GradientCache : public QOpenGLSharedResource
{
struct CacheInfo
{
@@ -76,12 +76,15 @@ class QGL2GradientCache
public:
static QGL2GradientCache *cacheForContext(const QGLContext *context);
- QGL2GradientCache(const QGLContext *) {}
- ~QGL2GradientCache() { cleanCache(); }
+ QGL2GradientCache(QOpenGLContext *);
+ ~QGL2GradientCache();
GLuint getBuffer(const QGradient &gradient, qreal opacity);
inline int paletteSize() const { return 1024; }
+ void invalidateResource();
+ void freeResource(QOpenGLContext *ctx);
+
private:
inline int maxCacheSize() const { return 60; }
inline void generateGradientColorTable(const QGradient& gradient,
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index d2c63ddc10..e6a12cd40c 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -76,10 +76,9 @@
#include <QPaintEngine>
#include <private/qpainter_p.h>
#include <private/qfontengine_p.h>
-#include <private/qpixmapdata_gl_p.h>
#include <private/qdatabuffer_p.h>
#include <private/qstatictext_p.h>
-#include <private/qtriangulator_p.h>
+#include <QtGui/private/qtriangulator_p.h>
#include "qglengineshadermanager_p.h"
#include "qgl2pexvertexarray_p.h"
@@ -668,6 +667,7 @@ struct QGL2PEVectorPathCache
int indexCount;
GLenum primitiveType;
qreal iscale;
+ QVertexIndexVector::Type indexType;
};
void QGL2PaintEngineExPrivate::cleanupVectorPath(QPaintEngineEx *engine, void *data)
@@ -825,13 +825,14 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path)
cache->indexCount = polys.indices.size();
cache->primitiveType = GL_TRIANGLES;
cache->iscale = inverseScale;
+ cache->indexType = polys.indices.type();
#ifdef QT_OPENGL_CACHE_AS_VBOS
glGenBuffers(1, &cache->vbo);
glGenBuffers(1, &cache->ibo);
glBindBuffer(GL_ARRAY_BUFFER, cache->vbo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cache->ibo);
- if (QGLExtensions::glExtensions() & QGLExtensions::ElementIndexUint)
+ if (polys.indices.type() == QVertexIndexVector::UnsignedInt)
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(quint32) * polys.indices.size(), polys.indices.data(), GL_STATIC_DRAW);
else
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(quint16) * polys.indices.size(), polys.indices.data(), GL_STATIC_DRAW);
@@ -842,7 +843,7 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path)
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * vertices.size(), vertices.data(), GL_STATIC_DRAW);
#else
cache->vertices = (float *) qMalloc(sizeof(float) * polys.vertices.size());
- if (QGLExtensions::glExtensions() & QGLExtensions::ElementIndexUint) {
+ if (polys.indices.type() == QVertexIndexVector::UnsignedInt) {
cache->indices = (quint32 *) qMalloc(sizeof(quint32) * polys.indices.size());
memcpy(cache->indices, polys.indices.data(), sizeof(quint32) * polys.indices.size());
} else {
@@ -859,7 +860,7 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path)
glBindBuffer(GL_ARRAY_BUFFER, cache->vbo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cache->ibo);
setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, 0);
- if (QGLExtensions::glExtensions() & QGLExtensions::ElementIndexUint)
+ if (cache->indexType == QVertexIndexVector::UnsignedInt)
glDrawElements(cache->primitiveType, cache->indexCount, GL_UNSIGNED_INT, 0);
else
glDrawElements(cache->primitiveType, cache->indexCount, GL_UNSIGNED_SHORT, 0);
@@ -867,7 +868,7 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path)
glBindBuffer(GL_ARRAY_BUFFER, 0);
#else
setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, cache->vertices);
- if (QGLExtensions::glExtensions() & QGLExtensions::ElementIndexUint)
+ if (cache->indexType == QVertexIndexVector::UnsignedInt)
glDrawElements(cache->primitiveType, cache->indexCount, GL_UNSIGNED_INT, (qint32 *)cache->indices);
else
glDrawElements(cache->primitiveType, cache->indexCount, GL_UNSIGNED_SHORT, (qint16 *)cache->indices);
@@ -896,7 +897,7 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path)
prepareForDraw(currentBrush.isOpaque());
setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, vertices.constData());
- if (QGLExtensions::glExtensions() & QGLExtensions::ElementIndexUint)
+ if (polys.indices.type() == QVertexIndexVector::UnsignedInt)
glDrawElements(GL_TRIANGLES, polys.indices.size(), GL_UNSIGNED_INT, polys.indices.data());
else
glDrawElements(GL_TRIANGLES, polys.indices.size(), GL_UNSIGNED_SHORT, polys.indices.data());
@@ -1581,10 +1582,9 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyp
QGLTextureGlyphCache *cache =
(QGLTextureGlyphCache *) staticTextItem->fontEngine()->glyphCache(cacheKey, glyphType, QTransform());
- if (!cache || cache->cacheType() != glyphType || cache->context() == 0) {
- cache = new QGLTextureGlyphCache(ctx, glyphType, QTransform());
+ if (!cache || cache->cacheType() != glyphType || cache->contextGroup() == 0) {
+ cache = new QGLTextureGlyphCache(glyphType, QTransform());
staticTextItem->fontEngine()->setGlyphCache(cacheKey, cache);
- cache->insert(ctx, cache);
recreateVertexArrays = true;
}
@@ -2048,21 +2048,13 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev)
bool QGL2PaintEngineEx::end()
{
Q_D(QGL2PaintEngineEx);
- QGLContext *ctx = d->ctx;
+ QGLContext *ctx = d->ctx;
glUseProgram(0);
d->transferMode(BrushDrawingMode);
d->device->endPaint();
-#if defined(Q_WS_X11)
- // On some (probably all) drivers, deleting an X pixmap which has been bound to a texture
- // before calling glFinish/swapBuffers renders garbage. Presumably this is because X deletes
- // the pixmap behind the driver's back before it's had a chance to use it. To fix this, we
- // reference all QPixmaps which have been bound to stop them being deleted and only deref
- // them here, after swapBuffers, where they can be safely deleted.
- ctx->d_func()->boundPixmaps.clear();
-#endif
- d->ctx->d_ptr->active_engine = 0;
+ ctx->d_ptr->active_engine = 0;
d->resetGLState();
@@ -2335,8 +2327,8 @@ void QGL2PaintEngineExPrivate::systemStateChanged()
if (systemClip.isEmpty()) {
useSystemClip = false;
} else {
- if (q->paintDevice()->devType() == QInternal::Widget && currentClipWidget) {
- QWidgetPrivate *widgetPrivate = qt_widget_private(currentClipWidget->window());
+ if (q->paintDevice()->devType() == QInternal::Widget && currentClipDevice) {
+ QWidgetPrivate *widgetPrivate = qt_widget_private(static_cast<QWidget *>(currentClipDevice)->window());
useSystemClip = widgetPrivate->extra && widgetPrivate->extra->inRenderWithPainter;
} else {
useSystemClip = true;
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
index 2895d5a9b0..dbf760929c 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
@@ -59,7 +59,6 @@
#include <private/qglengineshadermanager_p.h>
#include <private/qgl2pexvertexarray_p.h>
#include <private/qglpaintdevice_p.h>
-#include <private/qglpixmapfilter_p.h>
#include <private/qfontengine_p.h>
#include <private/qdatabuffer_p.h>
#include <private/qtriangulatingstroker_p.h>
@@ -153,8 +152,6 @@ public:
void invalidateState();
- QPixmapFilter *pixmapFilter(int type, const QPixmapFilter *prototype);
-
void setRenderTextActive(bool);
bool isNativePaintingActive() const;
@@ -302,11 +299,6 @@ public:
QTriangulatingStroker stroker;
QDashedStrokeProcessor dasher;
- QScopedPointer<QPixmapFilter> convolutionFilter;
- QScopedPointer<QPixmapFilter> colorizeFilter;
- QScopedPointer<QPixmapFilter> blurFilter;
- QScopedPointer<QPixmapFilter> dropShadowFilter;
-
QSet<QVectorPath::CacheEntry *> pathCaches;
QVector<GLuint> unusedVBOSToClean;
QVector<GLuint> unusedIBOSToClean;
diff --git a/src/opengl/gl2paintengineex/qrbtree_p.h b/src/opengl/gl2paintengineex/qrbtree_p.h
deleted file mode 100644
index 09ef81cdbb..0000000000
--- a/src/opengl/gl2paintengineex/qrbtree_p.h
+++ /dev/null
@@ -1,573 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QRBTREE_P_H
-#define QRBTREE_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/qglobal.h>
-
-QT_BEGIN_NAMESPACE
-
-template <class T>
-struct QRBTree
-{
- struct Node
- {
- inline Node() : parent(0), left(0), right(0), red(true) { }
- inline ~Node() {if (left) delete left; if (right) delete right;}
- T data;
- Node *parent;
- Node *left;
- Node *right;
- bool red;
- };
-
- inline QRBTree() : root(0), freeList(0) { }
- inline ~QRBTree();
-
- inline void clear();
-
- void attachBefore(Node *parent, Node *child);
- void attachAfter(Node *parent, Node *child);
-
- inline Node *front(Node *node) const;
- inline Node *back(Node *node) const;
- Node *next(Node *node) const;
- Node *previous(Node *node) const;
-
- inline void deleteNode(Node *&node);
- inline Node *newNode();
-
- // Return 1 if 'left' comes after 'right', 0 if equal, and -1 otherwise.
- // 'left' and 'right' cannot be null.
- int order(Node *left, Node *right);
- inline bool validate() const;
-
-private:
- void rotateLeft(Node *node);
- void rotateRight(Node *node);
- void update(Node *node);
-
- inline void attachLeft(Node *parent, Node *child);
- inline void attachRight(Node *parent, Node *child);
-
- int blackDepth(Node *top) const;
- bool checkRedBlackProperty(Node *top) const;
-
- void swapNodes(Node *n1, Node *n2);
- void detach(Node *node);
-
- // 'node' must be black. rebalance will reduce the depth of black nodes by one in the sibling tree.
- void rebalance(Node *node);
-
-public:
- Node *root;
-private:
- Node *freeList;
-};
-
-template <class T>
-inline QRBTree<T>::~QRBTree()
-{
- clear();
- while (freeList) {
- // Avoid recursively calling the destructor, as this list may become large.
- Node *next = freeList->right;
- freeList->right = 0;
- delete freeList;
- freeList = next;
- }
-}
-
-template <class T>
-inline void QRBTree<T>::clear()
-{
- if (root)
- delete root;
- root = 0;
-}
-
-template <class T>
-void QRBTree<T>::rotateLeft(Node *node)
-{
- // | | //
- // N B //
- // / \ / \ //
- // A B ---> N D //
- // / \ / \ //
- // C D A C //
-
- Node *&ref = (node->parent ? (node == node->parent->left ? node->parent->left : node->parent->right) : root);
- ref = node->right;
- node->right->parent = node->parent;
-
- // : //
- // N //
- // / :| //
- // A B //
- // / \ //
- // C D //
-
- node->right = ref->left;
- if (ref->left)
- ref->left->parent = node;
-
- // : | //
- // N B //
- // / \ : \ //
- // A C D //
-
- ref->left = node;
- node->parent = ref;
-
- // | //
- // B //
- // / \ //
- // N D //
- // / \ //
- // A C //
-}
-
-template <class T>
-void QRBTree<T>::rotateRight(Node *node)
-{
- // | | //
- // N A //
- // / \ / \ //
- // A B ---> C N //
- // / \ / \ //
- // C D D B //
-
- Node *&ref = (node->parent ? (node == node->parent->left ? node->parent->left : node->parent->right) : root);
- ref = node->left;
- node->left->parent = node->parent;
-
- node->left = ref->right;
- if (ref->right)
- ref->right->parent = node;
-
- ref->right = node;
- node->parent = ref;
-}
-
-template <class T>
-void QRBTree<T>::update(Node *node) // call this after inserting a node
-{
- for (;;) {
- Node *parent = node->parent;
-
- // if the node is the root, color it black
- if (!parent) {
- node->red = false;
- return;
- }
-
- // if the parent is black, the node can be left red
- if (!parent->red)
- return;
-
- // at this point, the parent is red and cannot be the root
- Node *grandpa = parent->parent;
- Q_ASSERT(grandpa);
-
- Node *uncle = (parent == grandpa->left ? grandpa->right : grandpa->left);
- if (uncle && uncle->red) {
- // grandpa's black, parent and uncle are red.
- // let parent and uncle be black, grandpa red and recursively update grandpa.
- Q_ASSERT(!grandpa->red);
- parent->red = false;
- uncle->red = false;
- grandpa->red = true;
- node = grandpa;
- continue;
- }
-
- // at this point, uncle is black
- if (node == parent->right && parent == grandpa->left)
- rotateLeft(node = parent);
- else if (node == parent->left && parent == grandpa->right)
- rotateRight(node = parent);
- parent = node->parent;
-
- if (parent == grandpa->left) {
- rotateRight(grandpa);
- parent->red = false;
- grandpa->red = true;
- } else {
- rotateLeft(grandpa);
- parent->red = false;
- grandpa->red = true;
- }
- return;
- }
-}
-
-template <class T>
-inline void QRBTree<T>::attachLeft(Node *parent, Node *child)
-{
- Q_ASSERT(!parent->left);
- parent->left = child;
- child->parent = parent;
- update(child);
-}
-
-template <class T>
-inline void QRBTree<T>::attachRight(Node *parent, Node *child)
-{
- Q_ASSERT(!parent->right);
- parent->right = child;
- child->parent = parent;
- update(child);
-}
-
-template <class T>
-void QRBTree<T>::attachBefore(Node *parent, Node *child)
-{
- if (!root)
- update(root = child);
- else if (!parent)
- attachRight(back(root), child);
- else if (parent->left)
- attachRight(back(parent->left), child);
- else
- attachLeft(parent, child);
-}
-
-template <class T>
-void QRBTree<T>::attachAfter(Node *parent, Node *child)
-{
- if (!root)
- update(root = child);
- else if (!parent)
- attachLeft(front(root), child);
- else if (parent->right)
- attachLeft(front(parent->right), child);
- else
- attachRight(parent, child);
-}
-
-template <class T>
-void QRBTree<T>::swapNodes(Node *n1, Node *n2)
-{
- // Since iterators must not be invalidated, it is not sufficient to only swap the data.
- if (n1->parent == n2) {
- n1->parent = n2->parent;
- n2->parent = n1;
- } else if (n2->parent == n1) {
- n2->parent = n1->parent;
- n1->parent = n2;
- } else {
- qSwap(n1->parent, n2->parent);
- }
-
- qSwap(n1->left, n2->left);
- qSwap(n1->right, n2->right);
- qSwap(n1->red, n2->red);
-
- if (n1->parent) {
- if (n1->parent->left == n2)
- n1->parent->left = n1;
- else
- n1->parent->right = n1;
- } else {
- root = n1;
- }
-
- if (n2->parent) {
- if (n2->parent->left == n1)
- n2->parent->left = n2;
- else
- n2->parent->right = n2;
- } else {
- root = n2;
- }
-
- if (n1->left)
- n1->left->parent = n1;
- if (n1->right)
- n1->right->parent = n1;
-
- if (n2->left)
- n2->left->parent = n2;
- if (n2->right)
- n2->right->parent = n2;
-}
-
-template <class T>
-void QRBTree<T>::detach(Node *node) // call this before removing a node.
-{
- if (node->right)
- swapNodes(node, front(node->right));
-
- Node *child = (node->left ? node->left : node->right);
-
- if (!node->red) {
- if (child && child->red)
- child->red = false;
- else
- rebalance(node);
- }
-
- Node *&ref = (node->parent ? (node == node->parent->left ? node->parent->left : node->parent->right) : root);
- ref = child;
- if (child)
- child->parent = node->parent;
- node->left = node->right = node->parent = 0;
-}
-
-// 'node' must be black. rebalance will reduce the depth of black nodes by one in the sibling tree.
-template <class T>
-void QRBTree<T>::rebalance(Node *node)
-{
- Q_ASSERT(!node->red);
- for (;;) {
- if (!node->parent)
- return;
-
- // at this point, node is not a parent, it is black, thus it must have a sibling.
- Node *sibling = (node == node->parent->left ? node->parent->right : node->parent->left);
- Q_ASSERT(sibling);
-
- if (sibling->red) {
- sibling->red = false;
- node->parent->red = true;
- if (node == node->parent->left)
- rotateLeft(node->parent);
- else
- rotateRight(node->parent);
- sibling = (node == node->parent->left ? node->parent->right : node->parent->left);
- Q_ASSERT(sibling);
- }
-
- // at this point, the sibling is black.
- Q_ASSERT(!sibling->red);
-
- if ((!sibling->left || !sibling->left->red) && (!sibling->right || !sibling->right->red)) {
- bool parentWasRed = node->parent->red;
- sibling->red = true;
- node->parent->red = false;
- if (parentWasRed)
- return;
- node = node->parent;
- continue;
- }
-
- // at this point, at least one of the sibling's children is red.
-
- if (node == node->parent->left) {
- if (!sibling->right || !sibling->right->red) {
- Q_ASSERT(sibling->left);
- sibling->red = true;
- sibling->left->red = false;
- rotateRight(sibling);
-
- sibling = sibling->parent;
- Q_ASSERT(sibling);
- }
- sibling->red = node->parent->red;
- node->parent->red = false;
-
- Q_ASSERT(sibling->right->red);
- sibling->right->red = false;
- rotateLeft(node->parent);
- } else {
- if (!sibling->left || !sibling->left->red) {
- Q_ASSERT(sibling->right);
- sibling->red = true;
- sibling->right->red = false;
- rotateLeft(sibling);
-
- sibling = sibling->parent;
- Q_ASSERT(sibling);
- }
- sibling->red = node->parent->red;
- node->parent->red = false;
-
- Q_ASSERT(sibling->left->red);
- sibling->left->red = false;
- rotateRight(node->parent);
- }
- return;
- }
-}
-
-template <class T>
-inline typename QRBTree<T>::Node *QRBTree<T>::front(Node *node) const
-{
- while (node->left)
- node = node->left;
- return node;
-}
-
-template <class T>
-inline typename QRBTree<T>::Node *QRBTree<T>::back(Node *node) const
-{
- while (node->right)
- node = node->right;
- return node;
-}
-
-template <class T>
-typename QRBTree<T>::Node *QRBTree<T>::next(Node *node) const
-{
- if (node->right)
- return front(node->right);
- while (node->parent && node == node->parent->right)
- node = node->parent;
- return node->parent;
-}
-
-template <class T>
-typename QRBTree<T>::Node *QRBTree<T>::previous(Node *node) const
-{
- if (node->left)
- return back(node->left);
- while (node->parent && node == node->parent->left)
- node = node->parent;
- return node->parent;
-}
-
-template <class T>
-int QRBTree<T>::blackDepth(Node *top) const
-{
- if (!top)
- return 0;
- int leftDepth = blackDepth(top->left);
- int rightDepth = blackDepth(top->right);
- if (leftDepth != rightDepth)
- return -1;
- if (!top->red)
- ++leftDepth;
- return leftDepth;
-}
-
-template <class T>
-bool QRBTree<T>::checkRedBlackProperty(Node *top) const
-{
- if (!top)
- return true;
- if (top->left && !checkRedBlackProperty(top->left))
- return false;
- if (top->right && !checkRedBlackProperty(top->right))
- return false;
- return !(top->red && ((top->left && top->left->red) || (top->right && top->right->red)));
-}
-
-template <class T>
-inline bool QRBTree<T>::validate() const
-{
- return checkRedBlackProperty(root) && blackDepth(root) != -1;
-}
-
-template <class T>
-inline void QRBTree<T>::deleteNode(Node *&node)
-{
- Q_ASSERT(node);
- detach(node);
- node->right = freeList;
- freeList = node;
- node = 0;
-}
-
-template <class T>
-inline typename QRBTree<T>::Node *QRBTree<T>::newNode()
-{
- if (freeList) {
- Node *node = freeList;
- freeList = freeList->right;
- node->parent = node->left = node->right = 0;
- node->red = true;
- return node;
- }
- return new Node;
-}
-
-// Return 1 if 'left' comes after 'right', 0 if equal, and -1 otherwise.
-// 'left' and 'right' cannot be null.
-template <class T>
-int QRBTree<T>::order(Node *left, Node *right)
-{
- Q_ASSERT(left && right);
- if (left == right)
- return 0;
-
- QVector<Node *> leftAncestors;
- QVector<Node *> rightAncestors;
- while (left) {
- leftAncestors.push_back(left);
- left = left->parent;
- }
- while (right) {
- rightAncestors.push_back(right);
- right = right->parent;
- }
- Q_ASSERT(leftAncestors.back() == root && rightAncestors.back() == root);
-
- while (!leftAncestors.empty() && !rightAncestors.empty() && leftAncestors.back() == rightAncestors.back()) {
- leftAncestors.pop_back();
- rightAncestors.pop_back();
- }
-
- if (!leftAncestors.empty())
- return (leftAncestors.back() == leftAncestors.back()->parent->left ? -1 : 1);
-
- if (!rightAncestors.empty())
- return (rightAncestors.back() == rightAncestors.back()->parent->right ? -1 : 1);
-
- // The code should never reach this point.
- Q_ASSERT(!leftAncestors.empty() || !rightAncestors.empty());
- return 0;
-}
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp
index dbed354dfb..af6cb53a3a 100644
--- a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp
+++ b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp
@@ -43,10 +43,6 @@
#include "qpaintengineex_opengl2_p.h"
#include "private/qglengineshadersource_p.h"
-#if defined QT_OPENGL_ES_2 && !defined(QT_NO_EGL)
-#include "private/qeglcontext_p.h"
-#endif
-
QT_BEGIN_NAMESPACE
#ifdef Q_WS_WIN
@@ -55,19 +51,16 @@ extern Q_GUI_EXPORT bool qt_cleartype_enabled;
QBasicAtomicInt qgltextureglyphcache_serial_number = Q_BASIC_ATOMIC_INITIALIZER(1);
-QGLTextureGlyphCache::QGLTextureGlyphCache(const QGLContext *context, QFontEngineGlyphCache::Type type, const QTransform &matrix)
- : QImageTextureGlyphCache(type, matrix), QGLContextGroupResourceBase()
- , ctx(0)
+QGLTextureGlyphCache::QGLTextureGlyphCache(QFontEngineGlyphCache::Type type, const QTransform &matrix)
+ : QImageTextureGlyphCache(type, matrix)
, pex(0)
, m_blitProgram(0)
, m_filterMode(Nearest)
, m_serialNumber(qgltextureglyphcache_serial_number.fetchAndAddRelaxed(1))
{
#ifdef QT_GL_TEXTURE_GLYPH_CACHE_DEBUG
- qDebug(" -> QGLTextureGlyphCache() %p for context %p.", this, ctx);
+ qDebug(" -> QGLTextureGlyphCache() %p for context %p.", this, QOpenGLContext::currentContext());
#endif
- setContext(context);
-
m_vertexCoordinateArray[0] = -1.0f;
m_vertexCoordinateArray[1] = -1.0f;
m_vertexCoordinateArray[2] = 1.0f;
@@ -95,14 +88,9 @@ QGLTextureGlyphCache::~QGLTextureGlyphCache()
delete m_blitProgram;
}
-void QGLTextureGlyphCache::setContext(const QGLContext *context)
-{
- ctx = context;
- m_h = 0;
-}
-
void QGLTextureGlyphCache::createTextureData(int width, int height)
{
+ QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext());
if (ctx == 0) {
qWarning("QGLTextureGlyphCache::createTextureData: Called with no context");
return;
@@ -120,12 +108,17 @@ void QGLTextureGlyphCache::createTextureData(int width, int height)
if (height < 16)
height = 16;
- QGLGlyphTexture *glyphTexture = m_textureResource.value(ctx);
- glGenTextures(1, &glyphTexture->m_texture);
- glBindTexture(GL_TEXTURE_2D, glyphTexture->m_texture);
+ if (m_textureResource && !m_textureResource->m_texture)
+ delete m_textureResource;
+
+ if (!m_textureResource)
+ m_textureResource = new QGLGlyphTexture(ctx);
+
+ glGenTextures(1, &m_textureResource->m_texture);
+ glBindTexture(GL_TEXTURE_2D, m_textureResource->m_texture);
- glyphTexture->m_width = width;
- glyphTexture->m_height = height;
+ m_textureResource->m_width = width;
+ m_textureResource->m_height = height;
if (m_type == QFontEngineGlyphCache::Raster_RGBMask) {
QVarLengthArray<uchar> data(width * height * 4);
@@ -148,14 +141,14 @@ void QGLTextureGlyphCache::createTextureData(int width, int height)
void QGLTextureGlyphCache::resizeTextureData(int width, int height)
{
+ QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext());
if (ctx == 0) {
qWarning("QGLTextureGlyphCache::resizeTextureData: Called with no context");
return;
}
- QGLGlyphTexture *glyphTexture = m_textureResource.value(ctx);
- int oldWidth = glyphTexture->m_width;
- int oldHeight = glyphTexture->m_height;
+ int oldWidth = m_textureResource->m_width;
+ int oldHeight = m_textureResource->m_height;
// Make the lower glyph texture size 16 x 16.
if (width < 16)
@@ -163,7 +156,7 @@ void QGLTextureGlyphCache::resizeTextureData(int width, int height)
if (height < 16)
height = 16;
- GLuint oldTexture = glyphTexture->m_texture;
+ GLuint oldTexture = m_textureResource->m_texture;
createTextureData(width, height);
if (ctx->d_ptr->workaround_brokenFBOReadBack) {
@@ -177,7 +170,7 @@ void QGLTextureGlyphCache::resizeTextureData(int width, int height)
// ### the QTextureGlyphCache API needs to be reworked to allow
// ### resizeTextureData to fail
- glBindFramebuffer(GL_FRAMEBUFFER_EXT, glyphTexture->m_fbo);
+ glBindFramebuffer(GL_FRAMEBUFFER_EXT, m_textureResource->m_fbo);
GLuint tmp_texture;
glGenTextures(1, &tmp_texture);
@@ -261,7 +254,7 @@ void QGLTextureGlyphCache::resizeTextureData(int width, int height)
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- glBindTexture(GL_TEXTURE_2D, glyphTexture->m_texture);
+ glBindTexture(GL_TEXTURE_2D, m_textureResource->m_texture);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, oldWidth, oldHeight);
@@ -280,16 +273,16 @@ void QGLTextureGlyphCache::resizeTextureData(int width, int height)
void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed subPixelPosition)
{
+ QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext());
if (ctx == 0) {
qWarning("QGLTextureGlyphCache::fillTexture: Called with no context");
return;
}
- QGLGlyphTexture *glyphTexture = m_textureResource.value(ctx);
if (ctx->d_ptr->workaround_brokenFBOReadBack) {
QImageTextureGlyphCache::fillTexture(c, glyph, subPixelPosition);
- glBindTexture(GL_TEXTURE_2D, glyphTexture->m_texture);
+ glBindTexture(GL_TEXTURE_2D, m_textureResource->m_texture);
const QImage &texture = image();
const uchar *bits = texture.constBits();
bits += c.y * texture.bytesPerLine() + c.x;
@@ -326,7 +319,7 @@ void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed sub
}
}
- glBindTexture(GL_TEXTURE_2D, glyphTexture->m_texture);
+ glBindTexture(GL_TEXTURE_2D, m_textureResource->m_texture);
if (mask.format() == QImage::Format_RGB32) {
glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, GL_BGRA, GL_UNSIGNED_BYTE, mask.bits());
} else {
@@ -362,6 +355,7 @@ int QGLTextureGlyphCache::glyphPadding() const
int QGLTextureGlyphCache::maxTextureWidth() const
{
+ QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext());
if (ctx == 0)
return QImageTextureGlyphCache::maxTextureWidth();
else
@@ -370,6 +364,7 @@ int QGLTextureGlyphCache::maxTextureWidth() const
int QGLTextureGlyphCache::maxTextureHeight() const
{
+ QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext());
if (ctx == 0)
return QImageTextureGlyphCache::maxTextureHeight();
@@ -381,16 +376,15 @@ int QGLTextureGlyphCache::maxTextureHeight() const
void QGLTextureGlyphCache::clear()
{
- if (ctx != 0) {
- m_textureResource.cleanup(ctx);
-
- m_w = 0;
- m_h = 0;
- m_cx = 0;
- m_cy = 0;
- m_currentRowHeight = 0;
- coords.clear();
- }
+ m_textureResource->free();
+ m_textureResource = 0;
+
+ m_w = 0;
+ m_h = 0;
+ m_cx = 0;
+ m_cy = 0;
+ m_currentRowHeight = 0;
+ coords.clear();
}
QT_END_NAMESPACE
diff --git a/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h b/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h
index 83ca06d040..7b7da9d8e8 100644
--- a/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h
+++ b/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h
@@ -63,10 +63,11 @@ QT_BEGIN_NAMESPACE
class QGL2PaintEngineExPrivate;
-struct QGLGlyphTexture
+struct QGLGlyphTexture : public QOpenGLSharedResource
{
QGLGlyphTexture(const QGLContext *ctx)
- : m_width(0)
+ : QOpenGLSharedResource(ctx->contextHandle()->shareGroup())
+ , m_width(0)
, m_height(0)
{
if (ctx && !ctx->d_ptr->workaround_brokenFBOReadBack)
@@ -77,19 +78,24 @@ struct QGLGlyphTexture
#endif
}
- ~QGLGlyphTexture() {
- const QGLContext *ctx = QGLContext::currentContext();
+ void freeResource(QOpenGLContext *context)
+ {
+ const QGLContext *ctx = QGLContext::fromOpenGLContext(context);
#ifdef QT_GL_TEXTURE_GLYPH_CACHE_DEBUG
qDebug("~QGLGlyphTexture() %p for context %p.", this, ctx);
#endif
- // At this point, the context group is made current, so it's safe to
- // release resources without a makeCurrent() call
- if (ctx) {
- if (!ctx->d_ptr->workaround_brokenFBOReadBack)
- glDeleteFramebuffers(1, &m_fbo);
- if (m_width || m_height)
- glDeleteTextures(1, &m_texture);
- }
+ if (!ctx->d_ptr->workaround_brokenFBOReadBack)
+ glDeleteFramebuffers(1, &m_fbo);
+ if (m_width || m_height)
+ glDeleteTextures(1, &m_texture);
+ }
+
+ void invalidateResource()
+ {
+ m_texture = 0;
+ m_fbo = 0;
+ m_width = 0;
+ m_height = 0;
}
GLuint m_texture;
@@ -98,10 +104,10 @@ struct QGLGlyphTexture
int m_height;
};
-class Q_OPENGL_EXPORT QGLTextureGlyphCache : public QImageTextureGlyphCache, public QGLContextGroupResourceBase
+class Q_OPENGL_EXPORT QGLTextureGlyphCache : public QImageTextureGlyphCache
{
public:
- QGLTextureGlyphCache(const QGLContext *context, QFontEngineGlyphCache::Type type, const QTransform &matrix);
+ QGLTextureGlyphCache(QFontEngineGlyphCache::Type type, const QTransform &matrix);
~QGLTextureGlyphCache();
virtual void createTextureData(int width, int height);
@@ -113,25 +119,24 @@ public:
inline GLuint texture() const {
QGLTextureGlyphCache *that = const_cast<QGLTextureGlyphCache *>(this);
- QGLGlyphTexture *glyphTexture = that->m_textureResource.value(ctx);
+ QGLGlyphTexture *glyphTexture = that->m_textureResource;
return glyphTexture ? glyphTexture->m_texture : 0;
}
inline int width() const {
QGLTextureGlyphCache *that = const_cast<QGLTextureGlyphCache *>(this);
- QGLGlyphTexture *glyphTexture = that->m_textureResource.value(ctx);
+ QGLGlyphTexture *glyphTexture = that->m_textureResource;
return glyphTexture ? glyphTexture->m_width : 0;
}
inline int height() const {
QGLTextureGlyphCache *that = const_cast<QGLTextureGlyphCache *>(this);
- QGLGlyphTexture *glyphTexture = that->m_textureResource.value(ctx);
+ QGLGlyphTexture *glyphTexture = that->m_textureResource;
return glyphTexture ? glyphTexture->m_height : 0;
}
inline void setPaintEnginePrivate(QGL2PaintEngineExPrivate *p) { pex = p; }
- void setContext(const QGLContext *context);
- inline const QGLContext *context() const { return ctx; }
+ inline const QOpenGLContextGroup *contextGroup() const { return m_textureResource ? m_textureResource->group() : 0; }
inline int serialNumber() const { return m_serialNumber; }
@@ -144,12 +149,9 @@ public:
void clear();
- void freeResource(void *) { ctx = 0; }
-
private:
- QGLContextGroupResource<QGLGlyphTexture> m_textureResource;
+ QGLGlyphTexture *m_textureResource;
- const QGLContext *ctx;
QGL2PaintEngineExPrivate *pex;
QGLShaderProgram *m_blitProgram;
FilterMode m_filterMode;
diff --git a/src/opengl/gl2paintengineex/qtriangulator.cpp b/src/opengl/gl2paintengineex/qtriangulator.cpp
deleted file mode 100644
index d4b7131794..0000000000
--- a/src/opengl/gl2paintengineex/qtriangulator.cpp
+++ /dev/null
@@ -1,2612 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qtriangulator_p.h"
-
-#include <QtGui/qdialog.h>
-#include <QtGui/qevent.h>
-#include <QtGui/qpainter.h>
-#include <QtGui/qpainterpath.h>
-#include <QtGui/private/qbezier_p.h>
-#include <QtGui/private/qdatabuffer_p.h>
-#include <QtCore/qbitarray.h>
-#include <QtCore/qvarlengtharray.h>
-#include <QtCore/qqueue.h>
-#include <QtCore/qglobal.h>
-#include <QtCore/qpoint.h>
-#include <QtCore/qalgorithms.h>
-
-#include <private/qgl_p.h>
-#include <private/qrbtree_p.h>
-
-#include <math.h>
-
-QT_BEGIN_NAMESPACE
-
-//#define Q_TRIANGULATOR_DEBUG
-
-#define Q_FIXED_POINT_SCALE 32
-
-// Quick sort.
-template <class T, class LessThan>
-#ifdef Q_CC_RVCT // RVCT 2.2 doesn't see recursive _static_ template function
-void sort(T *array, int count, LessThan lessThan)
-#else
-static void sort(T *array, int count, LessThan lessThan)
-#endif
-{
- // If the number of elements fall below some threshold, use insertion sort.
- const int INSERTION_SORT_LIMIT = 7; // About 7 is fastest on my computer...
- if (count <= INSERTION_SORT_LIMIT) {
- for (int i = 1; i < count; ++i) {
- T temp = array[i];
- int j = i;
- while (j > 0 && lessThan(temp, array[j - 1])) {
- array[j] = array[j - 1];
- --j;
- }
- array[j] = temp;
- }
- return;
- }
-
- int high = count - 1;
- int low = 0;
- int mid = high / 2;
- if (lessThan(array[mid], array[low]))
- qSwap(array[mid], array[low]);
- if (lessThan(array[high], array[mid]))
- qSwap(array[high], array[mid]);
- if (lessThan(array[mid], array[low]))
- qSwap(array[mid], array[low]);
-
- --high;
- ++low;
- qSwap(array[mid], array[high]);
- int pivot = high;
- --high;
-
- while (low <= high) {
- while (!lessThan(array[pivot], array[low])) {
- ++low;
- if (low > high)
- goto sort_loop_end;
- }
- while (!lessThan(array[high], array[pivot])) {
- --high;
- if (low > high)
- goto sort_loop_end;
- }
- qSwap(array[low], array[high]);
- ++low;
- --high;
- }
-sort_loop_end:
- if (low != pivot)
- qSwap(array[pivot], array[low]);
- sort(array, low, lessThan);
- sort(array + low + 1, count - low - 1, lessThan);
-}
-
-// Quick sort.
-template <class T>
-#ifdef Q_CC_RVCT
-void sort(T *array, int count) // RVCT 2.2 doesn't see recursive _static_ template function
-#else
-static void sort(T *array, int count)
-#endif
-{
- // If the number of elements fall below some threshold, use insertion sort.
- const int INSERTION_SORT_LIMIT = 25; // About 25 is fastest on my computer...
- if (count <= INSERTION_SORT_LIMIT) {
- for (int i = 1; i < count; ++i) {
- T temp = array[i];
- int j = i;
- while (j > 0 && (temp < array[j - 1])) {
- array[j] = array[j - 1];
- --j;
- }
- array[j] = temp;
- }
- return;
- }
-
- int high = count - 1;
- int low = 0;
- int mid = high / 2;
- if ((array[mid] < array[low]))
- qSwap(array[mid], array[low]);
- if ((array[high] < array[mid]))
- qSwap(array[high], array[mid]);
- if ((array[mid] < array[low]))
- qSwap(array[mid], array[low]);
-
- --high;
- ++low;
- qSwap(array[mid], array[high]);
- int pivot = high;
- --high;
-
- while (low <= high) {
- while (!(array[pivot] < array[low])) {
- ++low;
- if (low > high)
- goto sort_loop_end;
- }
- while (!(array[high] < array[pivot])) {
- --high;
- if (low > high)
- goto sort_loop_end;
- }
- qSwap(array[low], array[high]);
- ++low;
- --high;
- }
-sort_loop_end:
- if (low != pivot)
- qSwap(array[pivot], array[low]);
- sort(array, low);
- sort(array + low + 1, count - low - 1);
-}
-
-template<typename T>
-struct QVertexSet
-{
- inline QVertexSet() { }
- inline QVertexSet(const QVertexSet<T> &other) : vertices(other.vertices), indices(other.indices) { }
- QVertexSet<T> &operator = (const QVertexSet<T> &other) {vertices = other.vertices; indices = other.indices; return *this;}
-
- // The vertices of a triangle are given by: (x[i[n]], y[i[n]]), (x[j[n]], y[j[n]]), (x[k[n]], y[k[n]]), n = 0, 1, ...
- QVector<qreal> vertices; // [x[0], y[0], x[1], y[1], x[2], ...]
- QVector<T> indices; // [i[0], j[0], k[0], i[1], j[1], k[1], i[2], ...]
-};
-
-//============================================================================//
-// QFraction //
-//============================================================================//
-
-// Fraction must be in the range [0, 1)
-struct QFraction
-{
- // Comparison operators must not be called on invalid fractions.
- inline bool operator < (const QFraction &other) const;
- inline bool operator == (const QFraction &other) const;
- inline bool operator != (const QFraction &other) const {return !(*this == other);}
- inline bool operator > (const QFraction &other) const {return other < *this;}
- inline bool operator >= (const QFraction &other) const {return !(*this < other);}
- inline bool operator <= (const QFraction &other) const {return !(*this > other);}
-
- inline bool isValid() const {return denominator != 0;}
-
- // numerator and denominator must not have common denominators.
- quint64 numerator, denominator;
-};
-
-static inline quint64 gcd(quint64 x, quint64 y)
-{
- while (y != 0) {
- quint64 z = y;
- y = x % y;
- x = z;
- }
- return x;
-}
-
-static inline int compare(quint64 a, quint64 b)
-{
- return (a > b) - (a < b);
-}
-
-// Compare a/b with c/d.
-// Return negative if less, 0 if equal, positive if greater.
-// a < b, c < d
-static int qCompareFractions(quint64 a, quint64 b, quint64 c, quint64 d)
-{
- const quint64 LIMIT = Q_UINT64_C(0x100000000);
- for (;;) {
- // If the products 'ad' and 'bc' fit into 64 bits, they can be directly compared.
- if (b < LIMIT && d < LIMIT)
- return compare(a * d, b * c);
-
- if (a == 0 || c == 0)
- return compare(a, c);
-
- // a/b < c/d <=> d/c < b/a
- quint64 b_div_a = b / a;
- quint64 d_div_c = d / c;
- if (b_div_a != d_div_c)
- return compare(d_div_c, b_div_a);
-
- // floor(d/c) == floor(b/a)
- // frac(d/c) < frac(b/a) ?
- // frac(x/y) = (x%y)/y
- d -= d_div_c * c; //d %= c;
- b -= b_div_a * a; //b %= a;
- qSwap(a, d);
- qSwap(b, c);
- }
-}
-
-// Fraction must be in the range [0, 1)
-// Assume input is valid.
-static QFraction qFraction(quint64 n, quint64 d) {
- QFraction result;
- if (n == 0) {
- result.numerator = 0;
- result.denominator = 1;
- } else {
- quint64 g = gcd(n, d);
- result.numerator = n / g;
- result.denominator = d / g;
- }
- return result;
-}
-
-inline bool QFraction::operator < (const QFraction &other) const
-{
- return qCompareFractions(numerator, denominator, other.numerator, other.denominator) < 0;
-}
-
-inline bool QFraction::operator == (const QFraction &other) const
-{
- return numerator == other.numerator && denominator == other.denominator;
-}
-
-//============================================================================//
-// QPodPoint //
-//============================================================================//
-
-struct QPodPoint
-{
- inline bool operator < (const QPodPoint &other) const
- {
- if (y != other.y)
- return y < other.y;
- return x < other.x;
- }
-
- inline bool operator > (const QPodPoint &other) const {return other < *this;}
- inline bool operator <= (const QPodPoint &other) const {return !(*this > other);}
- inline bool operator >= (const QPodPoint &other) const {return !(*this < other);}
- inline bool operator == (const QPodPoint &other) const {return x == other.x && y == other.y;}
- inline bool operator != (const QPodPoint &other) const {return x != other.x || y != other.y;}
-
- inline QPodPoint &operator += (const QPodPoint &other) {x += other.x; y += other.y; return *this;}
- inline QPodPoint &operator -= (const QPodPoint &other) {x -= other.x; y -= other.y; return *this;}
- inline QPodPoint operator + (const QPodPoint &other) const {QPodPoint result = {x + other.x, y + other.y}; return result;}
- inline QPodPoint operator - (const QPodPoint &other) const {QPodPoint result = {x - other.x, y - other.y}; return result;}
-
- int x;
- int y;
-};
-
-static inline qint64 qCross(const QPodPoint &u, const QPodPoint &v)
-{
- return qint64(u.x) * qint64(v.y) - qint64(u.y) * qint64(v.x);
-}
-
-static inline qint64 qDot(const QPodPoint &u, const QPodPoint &v)
-{
- return qint64(u.x) * qint64(v.x) + qint64(u.y) * qint64(v.y);
-}
-
-// Return positive value if 'p' is to the right of the line 'v1'->'v2', negative if left of the
-// line and zero if exactly on the line.
-// The returned value is the z-component of the qCross product between 'v2-v1' and 'p-v1',
-// which is twice the signed area of the triangle 'p'->'v1'->'v2' (positive for CW order).
-static inline qint64 qPointDistanceFromLine(const QPodPoint &p, const QPodPoint &v1, const QPodPoint &v2)
-{
- return qCross(v2 - v1, p - v1);
-}
-
-static inline bool qPointIsLeftOfLine(const QPodPoint &p, const QPodPoint &v1, const QPodPoint &v2)
-{
- return QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(p, v1, v2) < 0;
-}
-
-// Return:
-// -1 if u < v
-// 0 if u == v
-// 1 if u > v
-static int comparePoints(const QPodPoint &u, const QPodPoint &v)
-{
- if (u.y < v.y)
- return -1;
- if (u.y > v.y)
- return 1;
- if (u.x < v.x)
- return -1;
- if (u.x > v.x)
- return 1;
- return 0;
-}
-
-//============================================================================//
-// QIntersectionPoint //
-//============================================================================//
-
-struct QIntersectionPoint
-{
- inline bool isValid() const {return xOffset.isValid() && yOffset.isValid();}
- QPodPoint round() const;
- inline bool isAccurate() const {return xOffset.numerator == 0 && yOffset.numerator == 0;}
- bool operator < (const QIntersectionPoint &other) const;
- bool operator == (const QIntersectionPoint &other) const;
- inline bool operator != (const QIntersectionPoint &other) const {return !(*this == other);}
- inline bool operator > (const QIntersectionPoint &other) const {return other < *this;}
- inline bool operator >= (const QIntersectionPoint &other) const {return !(*this < other);}
- inline bool operator <= (const QIntersectionPoint &other) const {return !(*this > other);}
- bool isOnLine(const QPodPoint &u, const QPodPoint &v) const;
-
- QPodPoint upperLeft;
- QFraction xOffset;
- QFraction yOffset;
-};
-
-static inline QIntersectionPoint qIntersectionPoint(const QPodPoint &point)
-{
- // upperLeft = point, xOffset = 0/1, yOffset = 0/1.
- QIntersectionPoint p = {{point.x, point.y}, {0, 1}, {0, 1}};
- return p;
-}
-
-static inline QIntersectionPoint qIntersectionPoint(int x, int y)
-{
- // upperLeft = (x, y), xOffset = 0/1, yOffset = 0/1.
- QIntersectionPoint p = {{x, y}, {0, 1}, {0, 1}};
- return p;
-}
-
-static QIntersectionPoint qIntersectionPoint(const QPodPoint &u1, const QPodPoint &u2, const QPodPoint &v1, const QPodPoint &v2)
-{
- QIntersectionPoint result = {{0, 0}, {0, 0}, {0, 0}};
-
- QPodPoint u = u2 - u1;
- QPodPoint v = v2 - v1;
- qint64 d1 = qCross(u, v1 - u1);
- qint64 d2 = qCross(u, v2 - u1);
- qint64 det = d2 - d1;
- qint64 d3 = qCross(v, u1 - v1);
- qint64 d4 = d3 - det; //qCross(v, u2 - v1);
-
- // Check that the math is correct.
- Q_ASSERT(d4 == qCross(v, u2 - v1));
-
- // The intersection point can be expressed as:
- // v1 - v * d1/det
- // v2 - v * d2/det
- // u1 + u * d3/det
- // u2 + u * d4/det
-
- // I'm only interested in lines that are crossing, so ignore parallel lines even if they overlap.
- if (det == 0)
- return result;
-
- if (det < 0) {
- det = -det;
- d1 = -d1;
- d2 = -d2;
- d3 = -d3;
- d4 = -d4;
- }
-
- // I'm only interested in lines intersecting at their interior, not at their end points.
- // The lines intersect at their interior if and only if 'd1 < 0', 'd2 > 0', 'd3 < 0' and 'd4 > 0'.
- if (d1 >= 0 || d2 <= 0 || d3 <= 0 || d4 >= 0)
- return result;
-
- // Calculate the intersection point as follows:
- // v1 - v * d1/det | v1 <= v2 (component-wise)
- // v2 - v * d2/det | v2 < v1 (component-wise)
-
- // Assuming 21 bits per vector component.
- // TODO: Make code path for 31 bits per vector component.
- if (v.x >= 0) {
- result.upperLeft.x = v1.x + (-v.x * d1) / det;
- result.xOffset = qFraction(quint64(-v.x * d1) % quint64(det), quint64(det));
- } else {
- result.upperLeft.x = v2.x + (-v.x * d2) / det;
- result.xOffset = qFraction(quint64(-v.x * d2) % quint64(det), quint64(det));
- }
-
- if (v.y >= 0) {
- result.upperLeft.y = v1.y + (-v.y * d1) / det;
- result.yOffset = qFraction(quint64(-v.y * d1) % quint64(det), quint64(det));
- } else {
- result.upperLeft.y = v2.y + (-v.y * d2) / det;
- result.yOffset = qFraction(quint64(-v.y * d2) % quint64(det), quint64(det));
- }
-
- Q_ASSERT(result.xOffset.isValid());
- Q_ASSERT(result.yOffset.isValid());
- return result;
-}
-
-QPodPoint QIntersectionPoint::round() const
-{
- QPodPoint result = upperLeft;
- if (2 * xOffset.numerator >= xOffset.denominator)
- ++result.x;
- if (2 * yOffset.numerator >= yOffset.denominator)
- ++result.y;
- return result;
-}
-
-bool QIntersectionPoint::operator < (const QIntersectionPoint &other) const
-{
- if (upperLeft.y != other.upperLeft.y)
- return upperLeft.y < other.upperLeft.y;
- if (yOffset != other.yOffset)
- return yOffset < other.yOffset;
- if (upperLeft.x != other.upperLeft.x)
- return upperLeft.x < other.upperLeft.x;
- return xOffset < other.xOffset;
-}
-
-bool QIntersectionPoint::operator == (const QIntersectionPoint &other) const
-{
- return upperLeft == other.upperLeft && xOffset == other.xOffset && yOffset == other.yOffset;
-}
-
-// Returns true if this point is on the infinite line passing through 'u' and 'v'.
-bool QIntersectionPoint::isOnLine(const QPodPoint &u, const QPodPoint &v) const
-{
- // TODO: Make code path for coordinates with more than 21 bits.
- const QPodPoint p = upperLeft - u;
- const QPodPoint q = v - u;
- bool isHorizontal = p.y == 0 && yOffset.numerator == 0;
- bool isVertical = p.x == 0 && xOffset.numerator == 0;
- if (isHorizontal && isVertical)
- return true;
- if (isHorizontal)
- return q.y == 0;
- if (q.y == 0)
- return false;
- if (isVertical)
- return q.x == 0;
- if (q.x == 0)
- return false;
-
- // At this point, 'p+offset' and 'q' cannot lie on the x or y axis.
-
- if (((q.x < 0) == (q.y < 0)) != ((p.x < 0) == (p.y < 0)))
- return false; // 'p + offset' and 'q' pass through different quadrants.
-
- // Move all coordinates into the first quadrant.
- quint64 nx, ny;
- if (p.x < 0)
- nx = quint64(-p.x) * xOffset.denominator - xOffset.numerator;
- else
- nx = quint64(p.x) * xOffset.denominator + xOffset.numerator;
- if (p.y < 0)
- ny = quint64(-p.y) * yOffset.denominator - yOffset.numerator;
- else
- ny = quint64(p.y) * yOffset.denominator + yOffset.numerator;
-
- return qFraction(quint64(qAbs(q.x)) * xOffset.denominator, quint64(qAbs(q.y)) * yOffset.denominator) == qFraction(nx, ny);
-}
-
-//============================================================================//
-// QMaxHeap //
-//============================================================================//
-
-template <class T>
-class QMaxHeap
-{
-public:
- QMaxHeap() : m_data(0) {}
- inline int size() const {return m_data.size();}
- inline bool empty() const {return m_data.isEmpty();}
- inline bool isEmpty() const {return m_data.isEmpty();}
- void push(const T &x);
- T pop();
- inline const T &top() const {return m_data.first();}
-private:
- static inline int parent(int i) {return (i - 1) / 2;}
- static inline int left(int i) {return 2 * i + 1;}
- static inline int right(int i) {return 2 * i + 2;}
-
- QDataBuffer<T> m_data;
-};
-
-template <class T>
-void QMaxHeap<T>::push(const T &x)
-{
- int current = m_data.size();
- int parent = QMaxHeap::parent(current);
- m_data.add(x);
- while (current != 0 && m_data.at(parent) < x) {
- m_data.at(current) = m_data.at(parent);
- current = parent;
- parent = QMaxHeap::parent(current);
- }
- m_data.at(current) = x;
-}
-
-template <class T>
-T QMaxHeap<T>::pop()
-{
- T result = m_data.first();
- T back = m_data.last();
- m_data.pop_back();
- if (!m_data.isEmpty()) {
- int current = 0;
- for (;;) {
- int left = QMaxHeap::left(current);
- int right = QMaxHeap::right(current);
- if (left >= m_data.size())
- break;
- int greater = left;
- if (right < m_data.size() && m_data.at(left) < m_data.at(right))
- greater = right;
- if (m_data.at(greater) < back)
- break;
- m_data.at(current) = m_data.at(greater);
- current = greater;
- }
- m_data.at(current) = back;
- }
- return result;
-}
-
-//============================================================================//
-// QInt64Hash //
-//============================================================================//
-
-// Copied from qhash.cpp
-static const uchar prime_deltas[] = {
- 0, 0, 1, 3, 1, 5, 3, 3, 1, 9, 7, 5, 3, 9, 25, 3,
- 1, 21, 3, 21, 7, 15, 9, 5, 3, 29, 15, 0, 0, 0, 0, 0
-};
-
-// Copied from qhash.cpp
-static inline int primeForNumBits(int numBits)
-{
- return (1 << numBits) + prime_deltas[numBits];
-}
-
-static inline int primeForCount(int count)
-{
- int low = 0;
- int high = 32;
- for (int i = 0; i < 5; ++i) {
- int mid = (high + low) / 2;
- if (count >= 1 << mid)
- low = mid;
- else
- high = mid;
- }
- return primeForNumBits(high);
-}
-
-// Hash set of quint64s. Elements cannot be removed without clearing the
-// entire set. A value of -1 is used to mark unused entries.
-class QInt64Set
-{
-public:
- inline QInt64Set(int capacity = 64);
- inline ~QInt64Set() {if (m_array) delete[] m_array;}
- inline bool isValid() const {return m_array;}
- void insert(quint64 key);
- bool contains(quint64 key) const;
- inline void clear();
-private:
- bool rehash(int capacity);
-
- static const quint64 UNUSED;
-
- quint64 *m_array;
- int m_capacity;
- int m_count;
-};
-
-const quint64 QInt64Set::UNUSED = quint64(-1);
-
-inline QInt64Set::QInt64Set(int capacity)
-{
- m_capacity = primeForCount(capacity);
- m_array = new quint64[m_capacity];
- if (m_array)
- clear();
- else
- m_capacity = 0;
-}
-
-bool QInt64Set::rehash(int capacity)
-{
- quint64 *oldArray = m_array;
- int oldCapacity = m_capacity;
-
- m_capacity = capacity;
- m_array = new quint64[m_capacity];
- if (m_array) {
- clear();
- if (oldArray) {
- for (int i = 0; i < oldCapacity; ++i) {
- if (oldArray[i] != UNUSED)
- insert(oldArray[i]);
- }
- delete[] oldArray;
- }
- return true;
- } else {
- m_capacity = oldCapacity;
- m_array = oldArray;
- return false;
- }
-}
-
-void QInt64Set::insert(quint64 key)
-{
- if (m_count > 3 * m_capacity / 4)
- rehash(primeForCount(2 * m_capacity));
- Q_ASSERT_X(m_array, "QInt64Hash<T>::insert", "Hash set not allocated.");
- int index = int(key % m_capacity);
- for (int i = 0; i < m_capacity; ++i) {
- index += i;
- if (index >= m_capacity)
- index -= m_capacity;
- if (m_array[index] == key)
- return;
- if (m_array[index] == UNUSED) {
- ++m_count;
- m_array[index] = key;
- return;
- }
- }
- Q_ASSERT_X(0, "QInt64Hash<T>::insert", "Hash set full.");
-}
-
-bool QInt64Set::contains(quint64 key) const
-{
- Q_ASSERT_X(m_array, "QInt64Hash<T>::contains", "Hash set not allocated.");
- int index = int(key % m_capacity);
- for (int i = 0; i < m_capacity; ++i) {
- index += i;
- if (index >= m_capacity)
- index -= m_capacity;
- if (m_array[index] == key)
- return true;
- if (m_array[index] == UNUSED)
- return false;
- }
- return false;
-}
-
-inline void QInt64Set::clear()
-{
- Q_ASSERT_X(m_array, "QInt64Hash<T>::clear", "Hash set not allocated.");
- for (int i = 0; i < m_capacity; ++i)
- m_array[i] = UNUSED;
- m_count = 0;
-}
-
-//============================================================================//
-// QRingBuffer //
-//============================================================================//
-
-// T must be POD.
-template <class T>
-class QRingBuffer
-{
-public:
- inline QRingBuffer() : m_array(0), m_head(0), m_size(0), m_capacity(0) { }
- inline ~QRingBuffer() {if (m_array) delete[] m_array;}
- bool reallocate(int capacity);
- inline const T &head() const {Q_ASSERT(m_size > 0); return m_array[m_head];}
- inline const T &dequeue();
- inline void enqueue(const T &x);
- inline bool isEmpty() const {return m_size == 0;}
-private:
- T *m_array;
- int m_head;
- int m_size;
- int m_capacity;
-};
-
-template <class T>
-bool QRingBuffer<T>::reallocate(int capacity)
-{
- T *oldArray = m_array;
- m_array = new T[capacity];
- if (m_array) {
- if (oldArray) {
- if (m_head + m_size > m_capacity) {
- memcpy(m_array, oldArray + m_head, (m_capacity - m_head) * sizeof(T));
- memcpy(m_array + (m_capacity - m_head), oldArray, (m_head + m_size - m_capacity) * sizeof(T));
- } else {
- memcpy(m_array, oldArray + m_head, m_size * sizeof(T));
- }
- delete[] oldArray;
- }
- m_capacity = capacity;
- m_head = 0;
- return true;
- } else {
- m_array = oldArray;
- return false;
- }
-}
-
-template <class T>
-inline const T &QRingBuffer<T>::dequeue()
-{
- Q_ASSERT(m_size > 0);
- Q_ASSERT(m_array);
- Q_ASSERT(m_capacity >= m_size);
- int index = m_head;
- if (++m_head >= m_capacity)
- m_head -= m_capacity;
- --m_size;
- return m_array[index];
-}
-
-template <class T>
-inline void QRingBuffer<T>::enqueue(const T &x)
-{
- if (m_size == m_capacity)
- reallocate(qMax(2 * m_capacity, 64));
- int index = m_head + m_size;
- if (index >= m_capacity)
- index -= m_capacity;
- m_array[index] = x;
- ++m_size;
-}
-
-//============================================================================//
-// QTriangulator //
-//============================================================================//
-template<typename T>
-class QTriangulator
-{
-public:
- typedef QVarLengthArray<int, 6> ShortArray;
-
- //================================//
- // QTriangulator::ComplexToSimple //
- //================================//
- friend class ComplexToSimple;
- class ComplexToSimple
- {
- public:
- inline ComplexToSimple(QTriangulator<T> *parent) : m_parent(parent),
- m_edges(0), m_events(0), m_splits(0) { }
- void decompose();
- private:
- struct Edge
- {
- inline int &upper() {return pointingUp ? to : from;}
- inline int &lower() {return pointingUp ? from : to;}
- inline int upper() const {return pointingUp ? to : from;}
- inline int lower() const {return pointingUp ? from : to;}
-
- QRBTree<int>::Node *node;
- int from, to; // vertex
- int next, previous; // edge
- int winding;
- bool mayIntersect;
- bool pointingUp, originallyPointingUp;
- };
-
- friend class CompareEdges;
- class CompareEdges
- {
- public:
- inline CompareEdges(ComplexToSimple *parent) : m_parent(parent) { }
- bool operator () (int i, int j) const;
- private:
- ComplexToSimple *m_parent;
- };
-
- struct Intersection
- {
- bool operator < (const Intersection &other) const {return other.intersectionPoint < intersectionPoint;}
-
- QIntersectionPoint intersectionPoint;
- int vertex;
- int leftEdge;
- int rightEdge;
- };
-
- struct Split
- {
- int vertex;
- int edge;
- bool accurate;
- };
-
- struct Event
- {
- enum Type {Upper, Lower};
- inline bool operator < (const Event &other) const;
-
- QPodPoint point;
- Type type;
- int edge;
- };
-
-#ifdef Q_TRIANGULATOR_DEBUG
- friend class DebugDialog;
- friend class QTriangulator;
- class DebugDialog : public QDialog
- {
- public:
- DebugDialog(ComplexToSimple *parent, int currentVertex);
- protected:
- void paintEvent(QPaintEvent *);
- void wheelEvent(QWheelEvent *);
- void mouseMoveEvent(QMouseEvent *);
- void mousePressEvent(QMouseEvent *);
- private:
- ComplexToSimple *m_parent;
- QRectF m_window;
- QPoint m_lastMousePos;
- int m_vertex;
- };
-#endif
-
- void initEdges();
- bool calculateIntersection(int left, int right);
- bool edgeIsLeftOfEdge(int leftEdgeIndex, int rightEdgeIndex) const;
- QRBTree<int>::Node *searchEdgeLeftOf(int edgeIndex) const;
- QRBTree<int>::Node *searchEdgeLeftOf(int edgeIndex, QRBTree<int>::Node *after) const;
- QPair<QRBTree<int>::Node *, QRBTree<int>::Node *> bounds(const QPodPoint &point) const;
- QPair<QRBTree<int>::Node *, QRBTree<int>::Node *> outerBounds(const QPodPoint &point) const;
- void splitEdgeListRange(QRBTree<int>::Node *leftmost, QRBTree<int>::Node *rightmost, int vertex, const QIntersectionPoint &intersectionPoint);
- void reorderEdgeListRange(QRBTree<int>::Node *leftmost, QRBTree<int>::Node *rightmost);
- void sortEdgeList(const QPodPoint eventPoint);
- void fillPriorityQueue();
- void calculateIntersections();
- int splitEdge(int splitIndex);
- bool splitEdgesAtIntersections();
- void insertEdgeIntoVectorIfWanted(ShortArray &orderedEdges, int i);
- void removeUnwantedEdgesAndConnect();
- void removeUnusedPoints();
-
- QTriangulator *m_parent;
- QDataBuffer<Edge> m_edges;
- QRBTree<int> m_edgeList;
- QDataBuffer<Event> m_events;
- QDataBuffer<Split> m_splits;
- QMaxHeap<Intersection> m_topIntersection;
- QInt64Set m_processedEdgePairs;
- int m_initialPointCount;
- };
-#ifdef Q_TRIANGULATOR_DEBUG
- friend class ComplexToSimple::DebugDialog;
-#endif
-
- //=================================//
- // QTriangulator::SimpleToMonotone //
- //=================================//
- friend class SimpleToMonotone;
- class SimpleToMonotone
- {
- public:
- inline SimpleToMonotone(QTriangulator<T> *parent) : m_parent(parent), m_edges(0), m_upperVertex(0) { }
- void decompose();
- private:
- enum VertexType {MergeVertex, EndVertex, RegularVertex, StartVertex, SplitVertex};
-
- struct Edge
- {
- QRBTree<int>::Node *node;
- int helper, twin, next, previous;
- T from, to;
- VertexType type;
- bool pointingUp;
- int upper() const {return (pointingUp ? to : from);}
- int lower() const {return (pointingUp ? from : to);}
- };
-
- friend class CompareVertices;
- class CompareVertices
- {
- public:
- CompareVertices(SimpleToMonotone *parent) : m_parent(parent) { }
- bool operator () (int i, int j) const;
- private:
- SimpleToMonotone *m_parent;
- };
-
- void setupDataStructures();
- void removeZeroLengthEdges();
- void fillPriorityQueue();
- bool edgeIsLeftOfEdge(int leftEdgeIndex, int rightEdgeIndex) const;
- // Returns the rightmost edge not to the right of the given edge.
- QRBTree<int>::Node *searchEdgeLeftOfEdge(int edgeIndex) const;
- // Returns the rightmost edge left of the given point.
- QRBTree<int>::Node *searchEdgeLeftOfPoint(int pointIndex) const;
- void classifyVertex(int i);
- void classifyVertices();
- bool pointIsInSector(const QPodPoint &p, const QPodPoint &v1, const QPodPoint &v2, const QPodPoint &v3);
- bool pointIsInSector(int vertex, int sector);
- int findSector(int edge, int vertex);
- void createDiagonal(int lower, int upper);
- void monotoneDecomposition();
-
- QTriangulator *m_parent;
- QRBTree<int> m_edgeList;
- QDataBuffer<Edge> m_edges;
- QDataBuffer<int> m_upperVertex;
- bool m_clockwiseOrder;
- };
-
- //====================================//
- // QTriangulator::MonotoneToTriangles //
- //====================================//
- friend class MonotoneToTriangles;
- class MonotoneToTriangles
- {
- public:
- inline MonotoneToTriangles(QTriangulator<T> *parent) : m_parent(parent) { }
- void decompose();
- private:
- inline T indices(int index) const {return m_parent->m_indices.at(index + m_first);}
- inline int next(int index) const {return (index + 1) % m_length;}
- inline int previous(int index) const {return (index + m_length - 1) % m_length;}
- inline bool less(int i, int j) const {return m_parent->m_vertices.at((qint32)indices(i)) < m_parent->m_vertices.at(indices(j));}
- inline bool leftOfEdge(int i, int j, int k) const
- {
- return qPointIsLeftOfLine(m_parent->m_vertices.at((qint32)indices(i)),
- m_parent->m_vertices.at((qint32)indices(j)), m_parent->m_vertices.at((qint32)indices(k)));
- }
-
- QTriangulator<T> *m_parent;
- int m_first;
- int m_length;
- };
-
- inline QTriangulator() : m_vertices(0) { }
-
- // Call this only once.
- void initialize(const qreal *polygon, int count, uint hint, const QTransform &matrix);
- // Call this only once.
- void initialize(const QVectorPath &path, const QTransform &matrix, qreal lod);
- // Call this only once.
- void initialize(const QPainterPath &path, const QTransform &matrix, qreal lod);
- // Call either triangulate() or polyline() only once.
- QVertexSet<T> triangulate();
- QVertexSet<T> polyline();
-private:
- QDataBuffer<QPodPoint> m_vertices;
- QVector<T> m_indices;
- uint m_hint;
-};
-
-//============================================================================//
-// QTriangulator //
-//============================================================================//
-
-template <typename T>
-QVertexSet<T> QTriangulator<T>::triangulate()
-{
- for (int i = 0; i < m_vertices.size(); ++i) {
- Q_ASSERT(qAbs(m_vertices.at(i).x) < (1 << 21));
- Q_ASSERT(qAbs(m_vertices.at(i).y) < (1 << 21));
- }
-
- if (!(m_hint & (QVectorPath::OddEvenFill | QVectorPath::WindingFill)))
- m_hint |= QVectorPath::OddEvenFill;
-
- if (m_hint & QVectorPath::NonConvexShapeMask) {
- ComplexToSimple c2s(this);
- c2s.decompose();
- SimpleToMonotone s2m(this);
- s2m.decompose();
- }
- MonotoneToTriangles m2t(this);
- m2t.decompose();
-
- QVertexSet<T> result;
- result.indices = m_indices;
- result.vertices.resize(2 * m_vertices.size());
- for (int i = 0; i < m_vertices.size(); ++i) {
- result.vertices[2 * i + 0] = qreal(m_vertices.at(i).x) / Q_FIXED_POINT_SCALE;
- result.vertices[2 * i + 1] = qreal(m_vertices.at(i).y) / Q_FIXED_POINT_SCALE;
- }
- return result;
-}
-
-template <typename T>
-QVertexSet<T> QTriangulator<T>::polyline()
-{
- for (int i = 0; i < m_vertices.size(); ++i) {
- Q_ASSERT(qAbs(m_vertices.at(i).x) < (1 << 21));
- Q_ASSERT(qAbs(m_vertices.at(i).y) < (1 << 21));
- }
-
- if (!(m_hint & (QVectorPath::OddEvenFill | QVectorPath::WindingFill)))
- m_hint |= QVectorPath::OddEvenFill;
-
- if (m_hint & QVectorPath::NonConvexShapeMask) {
- ComplexToSimple c2s(this);
- c2s.decompose();
- }
-
- QVertexSet<T> result;
- result.indices = m_indices;
- result.vertices.resize(2 * m_vertices.size());
- for (int i = 0; i < m_vertices.size(); ++i) {
- result.vertices[2 * i + 0] = qreal(m_vertices.at(i).x) / Q_FIXED_POINT_SCALE;
- result.vertices[2 * i + 1] = qreal(m_vertices.at(i).y) / Q_FIXED_POINT_SCALE;
- }
- return result;
-}
-
-template <typename T>
-void QTriangulator<T>::initialize(const qreal *polygon, int count, uint hint, const QTransform &matrix)
-{
- m_hint = hint;
- m_vertices.resize(count);
- m_indices.resize(count + 1);
- for (int i = 0; i < count; ++i) {
- qreal x, y;
- matrix.map(polygon[2 * i + 0], polygon[2 * i + 1], &x, &y);
- m_vertices.at(i).x = qRound(x * Q_FIXED_POINT_SCALE);
- m_vertices.at(i).y = qRound(y * Q_FIXED_POINT_SCALE);
- m_indices[i] = i;
- }
- m_indices[count] = T(-1); //Q_TRIANGULATE_END_OF_POLYGON
-}
-
-template <typename T>
-void QTriangulator<T>::initialize(const QVectorPath &path, const QTransform &matrix, qreal lod)
-{
- m_hint = path.hints();
- // Curved paths will be converted to complex polygons.
- m_hint &= ~QVectorPath::CurvedShapeMask;
-
- const qreal *p = path.points();
- const QPainterPath::ElementType *e = path.elements();
- if (e) {
- for (int i = 0; i < path.elementCount(); ++i, ++e, p += 2) {
- switch (*e) {
- case QPainterPath::MoveToElement:
- if (!m_indices.isEmpty())
- m_indices.push_back(T(-1)); // Q_TRIANGULATE_END_OF_POLYGON
- // Fall through.
- case QPainterPath::LineToElement:
- m_indices.push_back(T(m_vertices.size()));
- m_vertices.resize(m_vertices.size() + 1);
- qreal x, y;
- matrix.map(p[0], p[1], &x, &y);
- m_vertices.last().x = qRound(x * Q_FIXED_POINT_SCALE);
- m_vertices.last().y = qRound(y * Q_FIXED_POINT_SCALE);
- break;
- case QPainterPath::CurveToElement:
- {
- qreal pts[8];
- for (int i = 0; i < 4; ++i)
- matrix.map(p[2 * i - 2], p[2 * i - 1], &pts[2 * i + 0], &pts[2 * i + 1]);
- for (int i = 0; i < 8; ++i)
- pts[i] *= lod;
- QBezier bezier = QBezier::fromPoints(QPointF(pts[0], pts[1]), QPointF(pts[2], pts[3]), QPointF(pts[4], pts[5]), QPointF(pts[6], pts[7]));
- QPolygonF poly = bezier.toPolygon();
- // Skip first point, it already exists in 'm_vertices'.
- for (int j = 1; j < poly.size(); ++j) {
- m_indices.push_back(T(m_vertices.size()));
- m_vertices.resize(m_vertices.size() + 1);
- m_vertices.last().x = qRound(poly.at(j).x() * Q_FIXED_POINT_SCALE / lod);
- m_vertices.last().y = qRound(poly.at(j).y() * Q_FIXED_POINT_SCALE / lod);
- }
- }
- i += 2;
- e += 2;
- p += 4;
- break;
- default:
- Q_ASSERT_X(0, "QTriangulator::triangulate", "Unexpected element type.");
- break;
- }
- }
- } else {
- for (int i = 0; i < path.elementCount(); ++i, p += 2) {
- m_indices.push_back(T(m_vertices.size()));
- m_vertices.resize(m_vertices.size() + 1);
- qreal x, y;
- matrix.map(p[0], p[1], &x, &y);
- m_vertices.last().x = qRound(x * Q_FIXED_POINT_SCALE);
- m_vertices.last().y = qRound(y * Q_FIXED_POINT_SCALE);
- }
- }
- m_indices.push_back(T(-1)); // Q_TRIANGULATE_END_OF_POLYGON
-}
-
-template <typename T>
-void QTriangulator<T>::initialize(const QPainterPath &path, const QTransform &matrix, qreal lod)
-{
- initialize(qtVectorPathForPath(path), matrix, lod);
-}
-
-//============================================================================//
-// QTriangulator::ComplexToSimple //
-//============================================================================//
-template <typename T>
-void QTriangulator<T>::ComplexToSimple::decompose()
-{
- m_initialPointCount = m_parent->m_vertices.size();
- initEdges();
- do {
- calculateIntersections();
- } while (splitEdgesAtIntersections());
-
- removeUnwantedEdgesAndConnect();
- removeUnusedPoints();
-
- m_parent->m_indices.clear();
- QBitArray processed(m_edges.size(), false);
- for (int first = 0; first < m_edges.size(); ++first) {
- // If already processed, or if unused path, skip.
- if (processed.at(first) || m_edges.at(first).next == -1)
- continue;
-
- int i = first;
- do {
- Q_ASSERT(!processed.at(i));
- Q_ASSERT(m_edges.at(m_edges.at(i).next).previous == i);
- m_parent->m_indices.push_back(m_edges.at(i).from);
- processed.setBit(i);
- i = m_edges.at(i).next; // CCW order
- } while (i != first);
- m_parent->m_indices.push_back(T(-1)); // Q_TRIANGULATE_END_OF_POLYGON
- }
-}
-
-template <typename T>
-void QTriangulator<T>::ComplexToSimple::initEdges()
-{
- // Initialize edge structure.
- // 'next' and 'previous' are not being initialized at this point.
- int first = 0;
- for (int i = 0; i < m_parent->m_indices.size(); ++i) {
- if (m_parent->m_indices.at(i) == T(-1)) { // Q_TRIANGULATE_END_OF_POLYGON
- if (m_edges.size() != first)
- m_edges.last().to = m_edges.at(first).from;
- first = m_edges.size();
- } else {
- Q_ASSERT(i + 1 < m_parent->m_indices.size());
- // {node, from, to, next, previous, winding, mayIntersect, pointingUp, originallyPointingUp}
- Edge edge = {0, m_parent->m_indices.at(i), m_parent->m_indices.at(i + 1), -1, -1, 0, true, false, false};
- m_edges.add(edge);
- }
- }
- if (first != m_edges.size())
- m_edges.last().to = m_edges.at(first).from;
- for (int i = 0; i < m_edges.size(); ++i) {
- m_edges.at(i).originallyPointingUp = m_edges.at(i).pointingUp =
- m_parent->m_vertices.at(m_edges.at(i).to) < m_parent->m_vertices.at(m_edges.at(i).from);
- }
-}
-
-// Return true if new intersection was found
-template <typename T>
-bool QTriangulator<T>::ComplexToSimple::calculateIntersection(int left, int right)
-{
- const Edge &e1 = m_edges.at(left);
- const Edge &e2 = m_edges.at(right);
-
- const QPodPoint &u1 = m_parent->m_vertices.at((qint32)e1.from);
- const QPodPoint &u2 = m_parent->m_vertices.at((qint32)e1.to);
- const QPodPoint &v1 = m_parent->m_vertices.at((qint32)e2.from);
- const QPodPoint &v2 = m_parent->m_vertices.at((qint32)e2.to);
- if (qMax(u1.x, u2.x) <= qMin(v1.x, v2.x))
- return false;
-
- quint64 key = (left > right ? (quint64(right) << 32) | quint64(left) : (quint64(left) << 32) | quint64(right));
- if (m_processedEdgePairs.contains(key))
- return false;
- m_processedEdgePairs.insert(key);
-
- Intersection intersection;
- intersection.leftEdge = left;
- intersection.rightEdge = right;
- intersection.intersectionPoint = QT_PREPEND_NAMESPACE(qIntersectionPoint)(u1, u2, v1, v2);
-
- if (!intersection.intersectionPoint.isValid())
- return false;
-
- Q_ASSERT(intersection.intersectionPoint.isOnLine(u1, u2));
- Q_ASSERT(intersection.intersectionPoint.isOnLine(v1, v2));
-
- intersection.vertex = m_parent->m_vertices.size();
- m_topIntersection.push(intersection);
- m_parent->m_vertices.add(intersection.intersectionPoint.round());
- return true;
-}
-
-template <typename T>
-bool QTriangulator<T>::ComplexToSimple::edgeIsLeftOfEdge(int leftEdgeIndex, int rightEdgeIndex) const
-{
- const Edge &leftEdge = m_edges.at(leftEdgeIndex);
- const Edge &rightEdge = m_edges.at(rightEdgeIndex);
- const QPodPoint &u = m_parent->m_vertices.at(rightEdge.upper());
- const QPodPoint &l = m_parent->m_vertices.at(rightEdge.lower());
- const QPodPoint &upper = m_parent->m_vertices.at(leftEdge.upper());
- if (upper.x < qMin(l.x, u.x))
- return true;
- if (upper.x > qMax(l.x, u.x))
- return false;
- qint64 d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(upper, l, u);
- // d < 0: left, d > 0: right, d == 0: on top
- if (d == 0)
- d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(m_parent->m_vertices.at(leftEdge.lower()), l, u);
- return d < 0;
-}
-
-template <typename T>
-QRBTree<int>::Node *QTriangulator<T>::ComplexToSimple::searchEdgeLeftOf(int edgeIndex) const
-{
- QRBTree<int>::Node *current = m_edgeList.root;
- QRBTree<int>::Node *result = 0;
- while (current) {
- if (edgeIsLeftOfEdge(edgeIndex, current->data)) {
- current = current->left;
- } else {
- result = current;
- current = current->right;
- }
- }
- return result;
-}
-
-template <typename T>
-QRBTree<int>::Node *QTriangulator<T>::ComplexToSimple::searchEdgeLeftOf(int edgeIndex, QRBTree<int>::Node *after) const
-{
- if (!m_edgeList.root)
- return after;
- QRBTree<int>::Node *result = after;
- QRBTree<int>::Node *current = (after ? m_edgeList.next(after) : m_edgeList.front(m_edgeList.root));
- while (current) {
- if (edgeIsLeftOfEdge(edgeIndex, current->data))
- return result;
- result = current;
- current = m_edgeList.next(current);
- }
- return result;
-}
-
-template <typename T>
-QPair<QRBTree<int>::Node *, QRBTree<int>::Node *> QTriangulator<T>::ComplexToSimple::bounds(const QPodPoint &point) const
-{
- QRBTree<int>::Node *current = m_edgeList.root;
- QPair<QRBTree<int>::Node *, QRBTree<int>::Node *> result(0, 0);
- while (current) {
- const QPodPoint &v1 = m_parent->m_vertices.at(m_edges.at(current->data).lower());
- const QPodPoint &v2 = m_parent->m_vertices.at(m_edges.at(current->data).upper());
- qint64 d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(point, v1, v2);
- if (d == 0) {
- result.first = result.second = current;
- break;
- }
- current = (d < 0 ? current->left : current->right);
- }
- if (current == 0)
- return result;
-
- current = result.first->left;
- while (current) {
- const QPodPoint &v1 = m_parent->m_vertices.at(m_edges.at(current->data).lower());
- const QPodPoint &v2 = m_parent->m_vertices.at(m_edges.at(current->data).upper());
- qint64 d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(point, v1, v2);
- Q_ASSERT(d >= 0);
- if (d == 0) {
- result.first = current;
- current = current->left;
- } else {
- current = current->right;
- }
- }
-
- current = result.second->right;
- while (current) {
- const QPodPoint &v1 = m_parent->m_vertices.at(m_edges.at(current->data).lower());
- const QPodPoint &v2 = m_parent->m_vertices.at(m_edges.at(current->data).upper());
- qint64 d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(point, v1, v2);
- Q_ASSERT(d <= 0);
- if (d == 0) {
- result.second = current;
- current = current->right;
- } else {
- current = current->left;
- }
- }
-
- return result;
-}
-
-template <typename T>
-QPair<QRBTree<int>::Node *, QRBTree<int>::Node *> QTriangulator<T>::ComplexToSimple::outerBounds(const QPodPoint &point) const
-{
- QRBTree<int>::Node *current = m_edgeList.root;
- QPair<QRBTree<int>::Node *, QRBTree<int>::Node *> result(0, 0);
-
- while (current) {
- const QPodPoint &v1 = m_parent->m_vertices.at(m_edges.at(current->data).lower());
- const QPodPoint &v2 = m_parent->m_vertices.at(m_edges.at(current->data).upper());
- qint64 d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(point, v1, v2);
- if (d == 0)
- break;
- if (d < 0) {
- result.second = current;
- current = current->left;
- } else {
- result.first = current;
- current = current->right;
- }
- }
-
- if (!current)
- return result;
-
- QRBTree<int>::Node *mid = current;
-
- current = mid->left;
- while (current) {
- const QPodPoint &v1 = m_parent->m_vertices.at(m_edges.at(current->data).lower());
- const QPodPoint &v2 = m_parent->m_vertices.at(m_edges.at(current->data).upper());
- qint64 d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(point, v1, v2);
- Q_ASSERT(d >= 0);
- if (d == 0) {
- current = current->left;
- } else {
- result.first = current;
- current = current->right;
- }
- }
-
- current = mid->right;
- while (current) {
- const QPodPoint &v1 = m_parent->m_vertices.at(m_edges.at(current->data).lower());
- const QPodPoint &v2 = m_parent->m_vertices.at(m_edges.at(current->data).upper());
- qint64 d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(point, v1, v2);
- Q_ASSERT(d <= 0);
- if (d == 0) {
- current = current->right;
- } else {
- result.second = current;
- current = current->left;
- }
- }
-
- return result;
-}
-
-template <typename T>
-void QTriangulator<T>::ComplexToSimple::splitEdgeListRange(QRBTree<int>::Node *leftmost, QRBTree<int>::Node *rightmost, int vertex, const QIntersectionPoint &intersectionPoint)
-{
- Q_ASSERT(leftmost && rightmost);
-
- // Split.
- for (;;) {
- const QPodPoint &u = m_parent->m_vertices.at(m_edges.at(leftmost->data).from);
- const QPodPoint &v = m_parent->m_vertices.at(m_edges.at(leftmost->data).to);
- Q_ASSERT(intersectionPoint.isOnLine(u, v));
- const Split split = {vertex, leftmost->data, intersectionPoint.isAccurate()};
- if (intersectionPoint.xOffset.numerator != 0 || intersectionPoint.yOffset.numerator != 0 || (intersectionPoint.upperLeft != u && intersectionPoint.upperLeft != v))
- m_splits.add(split);
- if (leftmost == rightmost)
- break;
- leftmost = m_edgeList.next(leftmost);
- }
-}
-
-template <typename T>
-void QTriangulator<T>::ComplexToSimple::reorderEdgeListRange(QRBTree<int>::Node *leftmost, QRBTree<int>::Node *rightmost)
-{
- Q_ASSERT(leftmost && rightmost);
-
- QRBTree<int>::Node *storeLeftmost = leftmost;
- QRBTree<int>::Node *storeRightmost = rightmost;
-
- // Reorder.
- while (leftmost != rightmost) {
- Edge &left = m_edges.at(leftmost->data);
- Edge &right = m_edges.at(rightmost->data);
- qSwap(left.node, right.node);
- qSwap(leftmost->data, rightmost->data);
- leftmost = m_edgeList.next(leftmost);
- if (leftmost == rightmost)
- break;
- rightmost = m_edgeList.previous(rightmost);
- }
-
- rightmost = m_edgeList.next(storeRightmost);
- leftmost = m_edgeList.previous(storeLeftmost);
- if (leftmost)
- calculateIntersection(leftmost->data, storeLeftmost->data);
- if (rightmost)
- calculateIntersection(storeRightmost->data, rightmost->data);
-}
-
-template <typename T>
-void QTriangulator<T>::ComplexToSimple::sortEdgeList(const QPodPoint eventPoint)
-{
- QIntersectionPoint eventPoint2 = QT_PREPEND_NAMESPACE(qIntersectionPoint)(eventPoint);
- while (!m_topIntersection.isEmpty() && m_topIntersection.top().intersectionPoint < eventPoint2) {
- Intersection intersection = m_topIntersection.pop();
-
- QIntersectionPoint currentIntersectionPoint = intersection.intersectionPoint;
- int currentVertex = intersection.vertex;
-
- QRBTree<int>::Node *leftmost = m_edges.at(intersection.leftEdge).node;
- QRBTree<int>::Node *rightmost = m_edges.at(intersection.rightEdge).node;
-
- for (;;) {
- QRBTree<int>::Node *previous = m_edgeList.previous(leftmost);
- if (!previous)
- break;
- const Edge &edge = m_edges.at(previous->data);
- const QPodPoint &u = m_parent->m_vertices.at((qint32)edge.from);
- const QPodPoint &v = m_parent->m_vertices.at((qint32)edge.to);
- if (!currentIntersectionPoint.isOnLine(u, v)) {
- Q_ASSERT(!currentIntersectionPoint.isAccurate() || qCross(currentIntersectionPoint.upperLeft - u, v - u) != 0);
- break;
- }
- leftmost = previous;
- }
-
- for (;;) {
- QRBTree<int>::Node *next = m_edgeList.next(rightmost);
- if (!next)
- break;
- const Edge &edge = m_edges.at(next->data);
- const QPodPoint &u = m_parent->m_vertices.at((qint32)edge.from);
- const QPodPoint &v = m_parent->m_vertices.at((qint32)edge.to);
- if (!currentIntersectionPoint.isOnLine(u, v)) {
- Q_ASSERT(!currentIntersectionPoint.isAccurate() || qCross(currentIntersectionPoint.upperLeft - u, v - u) != 0);
- break;
- }
- rightmost = next;
- }
-
- Q_ASSERT(leftmost && rightmost);
- splitEdgeListRange(leftmost, rightmost, currentVertex, currentIntersectionPoint);
- reorderEdgeListRange(leftmost, rightmost);
-
- while (!m_topIntersection.isEmpty() && m_topIntersection.top().intersectionPoint <= currentIntersectionPoint)
- m_topIntersection.pop();
-
-#ifdef Q_TRIANGULATOR_DEBUG
- DebugDialog dialog(this, intersection.vertex);
- dialog.exec();
-#endif
-
- }
-}
-
-template <typename T>
-void QTriangulator<T>::ComplexToSimple::fillPriorityQueue()
-{
- m_events.reset();
- m_events.reserve(m_edges.size() * 2);
- for (int i = 0; i < m_edges.size(); ++i) {
- Q_ASSERT(m_edges.at(i).previous == -1 && m_edges.at(i).next == -1);
- Q_ASSERT(m_edges.at(i).node == 0);
- Q_ASSERT(m_edges.at(i).pointingUp == m_edges.at(i).originallyPointingUp);
- Q_ASSERT(m_edges.at(i).pointingUp == (m_parent->m_vertices.at(m_edges.at(i).to) < m_parent->m_vertices.at(m_edges.at(i).from)));
- // Ignore zero-length edges.
- if (m_parent->m_vertices.at(m_edges.at(i).to) != m_parent->m_vertices.at(m_edges.at(i).from)) {
- QPodPoint upper = m_parent->m_vertices.at(m_edges.at(i).upper());
- QPodPoint lower = m_parent->m_vertices.at(m_edges.at(i).lower());
- Event upperEvent = {{upper.x, upper.y}, Event::Upper, i};
- Event lowerEvent = {{lower.x, lower.y}, Event::Lower, i};
- m_events.add(upperEvent);
- m_events.add(lowerEvent);
- }
- }
- //qSort(m_events.data(), m_events.data() + m_events.size());
- sort(m_events.data(), m_events.size());
-}
-
-template <typename T>
-void QTriangulator<T>::ComplexToSimple::calculateIntersections()
-{
- fillPriorityQueue();
-
- Q_ASSERT(m_topIntersection.empty());
- Q_ASSERT(m_edgeList.root == 0);
-
- // Find all intersection points.
- while (!m_events.isEmpty()) {
- Event event = m_events.last();
- sortEdgeList(event.point);
-
- // Find all edges in the edge list that contain the current vertex and mark them to be split later.
- QPair<QRBTree<int>::Node *, QRBTree<int>::Node *> range = bounds(event.point);
- QRBTree<int>::Node *leftNode = range.first ? m_edgeList.previous(range.first) : 0;
- int vertex = (event.type == Event::Upper ? m_edges.at(event.edge).upper() : m_edges.at(event.edge).lower());
- QIntersectionPoint eventPoint = QT_PREPEND_NAMESPACE(qIntersectionPoint)(event.point);
-
- if (range.first != 0) {
- splitEdgeListRange(range.first, range.second, vertex, eventPoint);
- reorderEdgeListRange(range.first, range.second);
- }
-
- // Handle the edges with start or end point in the current vertex.
- while (!m_events.isEmpty() && m_events.last().point == event.point) {
- event = m_events.last();
- m_events.pop_back();
- int i = event.edge;
-
- if (m_edges.at(i).node) {
- // Remove edge from edge list.
- Q_ASSERT(event.type == Event::Lower);
- QRBTree<int>::Node *left = m_edgeList.previous(m_edges.at(i).node);
- QRBTree<int>::Node *right = m_edgeList.next(m_edges.at(i).node);
- m_edgeList.deleteNode(m_edges.at(i).node);
- if (!left || !right)
- continue;
- calculateIntersection(left->data, right->data);
- } else {
- // Insert edge into edge list.
- Q_ASSERT(event.type == Event::Upper);
- QRBTree<int>::Node *left = searchEdgeLeftOf(i, leftNode);
- m_edgeList.attachAfter(left, m_edges.at(i).node = m_edgeList.newNode());
- m_edges.at(i).node->data = i;
- QRBTree<int>::Node *right = m_edgeList.next(m_edges.at(i).node);
- if (left)
- calculateIntersection(left->data, i);
- if (right)
- calculateIntersection(i, right->data);
- }
- }
- while (!m_topIntersection.isEmpty() && m_topIntersection.top().intersectionPoint <= eventPoint)
- m_topIntersection.pop();
-#ifdef Q_TRIANGULATOR_DEBUG
- DebugDialog dialog(this, vertex);
- dialog.exec();
-#endif
- }
- m_processedEdgePairs.clear();
-}
-
-// Split an edge into two pieces at the given point.
-// The upper piece is pushed to the end of the 'm_edges' vector.
-// The lower piece replaces the old edge.
-// Return the edge whose 'from' is 'pointIndex'.
-template <typename T>
-int QTriangulator<T>::ComplexToSimple::splitEdge(int splitIndex)
-{
- const Split &split = m_splits.at(splitIndex);
- Edge &lowerEdge = m_edges.at(split.edge);
- Q_ASSERT(lowerEdge.node == 0);
- Q_ASSERT(lowerEdge.previous == -1 && lowerEdge.next == -1);
-
- if (lowerEdge.from == split.vertex)
- return split.edge;
- if (lowerEdge.to == split.vertex)
- return lowerEdge.next;
-
- // Check that angle >= 90 degrees.
- //Q_ASSERT(qDot(m_points.at(m_edges.at(edgeIndex).from) - m_points.at(pointIndex),
- // m_points.at(m_edges.at(edgeIndex).to) - m_points.at(pointIndex)) <= 0);
-
- Edge upperEdge = lowerEdge;
- upperEdge.mayIntersect |= !split.accurate; // The edge may have been split before at an inaccurate split point.
- lowerEdge.mayIntersect = !split.accurate;
- if (lowerEdge.pointingUp) {
- lowerEdge.to = upperEdge.from = split.vertex;
- m_edges.add(upperEdge);
- return m_edges.size() - 1;
- } else {
- lowerEdge.from = upperEdge.to = split.vertex;
- m_edges.add(upperEdge);
- return split.edge;
- }
-}
-
-template <typename T>
-bool QTriangulator<T>::ComplexToSimple::splitEdgesAtIntersections()
-{
- for (int i = 0; i < m_edges.size(); ++i)
- m_edges.at(i).mayIntersect = false;
- bool checkForNewIntersections = false;
- for (int i = 0; i < m_splits.size(); ++i) {
- splitEdge(i);
- checkForNewIntersections |= !m_splits.at(i).accurate;
- }
- for (int i = 0; i < m_edges.size(); ++i) {
- m_edges.at(i).originallyPointingUp = m_edges.at(i).pointingUp =
- m_parent->m_vertices.at(m_edges.at(i).to) < m_parent->m_vertices.at(m_edges.at(i).from);
- }
- m_splits.reset();
- return checkForNewIntersections;
-}
-
-template <typename T>
-void QTriangulator<T>::ComplexToSimple::insertEdgeIntoVectorIfWanted(ShortArray &orderedEdges, int i)
-{
- // Edges with zero length should not reach this part.
- Q_ASSERT(m_parent->m_vertices.at(m_edges.at(i).from) != m_parent->m_vertices.at(m_edges.at(i).to));
-
- // Skip edges with unwanted winding number.
- int windingNumber = m_edges.at(i).winding;
- if (m_edges.at(i).originallyPointingUp)
- ++windingNumber;
-
- // Make sure exactly one fill rule is specified.
- Q_ASSERT(((m_parent->m_hint & QVectorPath::WindingFill) != 0) != ((m_parent->m_hint & QVectorPath::OddEvenFill) != 0));
-
- if ((m_parent->m_hint & QVectorPath::WindingFill) && windingNumber != 0 && windingNumber != 1)
- return;
-
- // Skip cancelling edges.
- if (!orderedEdges.isEmpty()) {
- int j = orderedEdges[orderedEdges.size() - 1];
- // If the last edge is already connected in one end, it should not be cancelled.
- if (m_edges.at(j).next == -1 && m_edges.at(j).previous == -1
- && (m_parent->m_vertices.at(m_edges.at(i).from) == m_parent->m_vertices.at(m_edges.at(j).to))
- && (m_parent->m_vertices.at(m_edges.at(i).to) == m_parent->m_vertices.at(m_edges.at(j).from))) {
- orderedEdges.removeLast();
- return;
- }
- }
- orderedEdges.append(i);
-}
-
-template <typename T>
-void QTriangulator<T>::ComplexToSimple::removeUnwantedEdgesAndConnect()
-{
- Q_ASSERT(m_edgeList.root == 0);
- // Initialize priority queue.
- fillPriorityQueue();
-
- ShortArray orderedEdges;
-
- while (!m_events.isEmpty()) {
- Event event = m_events.last();
- int edgeIndex = event.edge;
-
- // Check that all the edges in the list crosses the current scanline
- //if (m_edgeList.root) {
- // for (QRBTree<int>::Node *node = m_edgeList.front(m_edgeList.root); node; node = m_edgeList.next(node)) {
- // Q_ASSERT(event.point <= m_points.at(m_edges.at(node->data).lower()));
- // }
- //}
-
- orderedEdges.clear();
- QPair<QRBTree<int>::Node *, QRBTree<int>::Node *> b = outerBounds(event.point);
- if (m_edgeList.root) {
- QRBTree<int>::Node *current = (b.first ? m_edgeList.next(b.first) : m_edgeList.front(m_edgeList.root));
- // Process edges that are going to be removed from the edge list at the current event point.
- while (current != b.second) {
- Q_ASSERT(current);
- Q_ASSERT(m_edges.at(current->data).node == current);
- Q_ASSERT(QT_PREPEND_NAMESPACE(qIntersectionPoint)(event.point).isOnLine(m_parent->m_vertices.at(m_edges.at(current->data).from), m_parent->m_vertices.at(m_edges.at(current->data).to)));
- Q_ASSERT(m_parent->m_vertices.at(m_edges.at(current->data).from) == event.point || m_parent->m_vertices.at(m_edges.at(current->data).to) == event.point);
- insertEdgeIntoVectorIfWanted(orderedEdges, current->data);
- current = m_edgeList.next(current);
- }
- }
-
- // Remove edges above the event point, insert edges below the event point.
- do {
- event = m_events.last();
- m_events.pop_back();
- edgeIndex = event.edge;
-
- // Edges with zero length should not reach this part.
- Q_ASSERT(m_parent->m_vertices.at(m_edges.at(edgeIndex).from) != m_parent->m_vertices.at(m_edges.at(edgeIndex).to));
-
- if (m_edges.at(edgeIndex).node) {
- Q_ASSERT(event.type == Event::Lower);
- Q_ASSERT(event.point == m_parent->m_vertices.at(m_edges.at(event.edge).lower()));
- m_edgeList.deleteNode(m_edges.at(edgeIndex).node);
- } else {
- Q_ASSERT(event.type == Event::Upper);
- Q_ASSERT(event.point == m_parent->m_vertices.at(m_edges.at(event.edge).upper()));
- QRBTree<int>::Node *left = searchEdgeLeftOf(edgeIndex, b.first);
- m_edgeList.attachAfter(left, m_edges.at(edgeIndex).node = m_edgeList.newNode());
- m_edges.at(edgeIndex).node->data = edgeIndex;
- }
- } while (!m_events.isEmpty() && m_events.last().point == event.point);
-
- if (m_edgeList.root) {
- QRBTree<int>::Node *current = (b.first ? m_edgeList.next(b.first) : m_edgeList.front(m_edgeList.root));
-
- // Calculate winding number and turn counter-clockwise.
- int currentWindingNumber = (b.first ? m_edges.at(b.first->data).winding : 0);
- while (current != b.second) {
- Q_ASSERT(current);
- //Q_ASSERT(b.second == 0 || m_edgeList.order(current, b.second) < 0);
- int i = current->data;
- Q_ASSERT(m_edges.at(i).node == current);
-
- // Winding number.
- int ccwWindingNumber = m_edges.at(i).winding = currentWindingNumber;
- if (m_edges.at(i).originallyPointingUp) {
- --m_edges.at(i).winding;
- } else {
- ++m_edges.at(i).winding;
- ++ccwWindingNumber;
- }
- currentWindingNumber = m_edges.at(i).winding;
-
- // Turn counter-clockwise.
- if ((ccwWindingNumber & 1) == 0) {
- Q_ASSERT(m_edges.at(i).previous == -1 && m_edges.at(i).next == -1);
- qSwap(m_edges.at(i).from, m_edges.at(i).to);
- m_edges.at(i).pointingUp = !m_edges.at(i).pointingUp;
- }
-
- current = m_edgeList.next(current);
- }
-
- // Process edges that were inserted into the edge list at the current event point.
- current = (b.second ? m_edgeList.previous(b.second) : m_edgeList.back(m_edgeList.root));
- while (current != b.first) {
- Q_ASSERT(current);
- Q_ASSERT(m_edges.at(current->data).node == current);
- insertEdgeIntoVectorIfWanted(orderedEdges, current->data);
- current = m_edgeList.previous(current);
- }
- }
- if (orderedEdges.isEmpty())
- continue;
-
- Q_ASSERT((orderedEdges.size() & 1) == 0);
-
- // Connect edges.
- // First make sure the first edge point towards the current point.
- int i;
- if (m_parent->m_vertices.at(m_edges.at(orderedEdges[0]).from) == event.point) {
- i = 1;
- int copy = orderedEdges[0]; // Make copy in case the append() will cause a reallocation.
- orderedEdges.append(copy);
- } else {
- Q_ASSERT(m_parent->m_vertices.at(m_edges.at(orderedEdges[0]).to) == event.point);
- i = 0;
- }
-
- // Remove references to duplicate points. First find the point with lowest index.
- int pointIndex = INT_MAX;
- for (int j = i; j < orderedEdges.size(); j += 2) {
- Q_ASSERT(j + 1 < orderedEdges.size());
- Q_ASSERT(m_parent->m_vertices.at(m_edges.at(orderedEdges[j]).to) == event.point);
- Q_ASSERT(m_parent->m_vertices.at(m_edges.at(orderedEdges[j + 1]).from) == event.point);
- if (m_edges.at(orderedEdges[j]).to < pointIndex)
- pointIndex = m_edges.at(orderedEdges[j]).to;
- if (m_edges.at(orderedEdges[j + 1]).from < pointIndex)
- pointIndex = m_edges.at(orderedEdges[j + 1]).from;
- }
-
- for (; i < orderedEdges.size(); i += 2) {
- // Remove references to duplicate points by making all edges reference one common point.
- m_edges.at(orderedEdges[i]).to = m_edges.at(orderedEdges[i + 1]).from = pointIndex;
-
- Q_ASSERT(m_edges.at(orderedEdges[i]).pointingUp || m_edges.at(orderedEdges[i]).previous != -1);
- Q_ASSERT(!m_edges.at(orderedEdges[i + 1]).pointingUp || m_edges.at(orderedEdges[i + 1]).next != -1);
-
- m_edges.at(orderedEdges[i]).next = orderedEdges[i + 1];
- m_edges.at(orderedEdges[i + 1]).previous = orderedEdges[i];
- }
- } // end while
-}
-
-template <typename T>
-void QTriangulator<T>::ComplexToSimple::removeUnusedPoints() {
- QBitArray used(m_parent->m_vertices.size(), false);
- for (int i = 0; i < m_edges.size(); ++i) {
- Q_ASSERT((m_edges.at(i).previous == -1) == (m_edges.at(i).next == -1));
- if (m_edges.at(i).next != -1)
- used.setBit(m_edges.at(i).from);
- }
- QDataBuffer<quint32> newMapping(m_parent->m_vertices.size());
- newMapping.resize(m_parent->m_vertices.size());
- int count = 0;
- for (int i = 0; i < m_parent->m_vertices.size(); ++i) {
- if (used.at(i)) {
- m_parent->m_vertices.at(count) = m_parent->m_vertices.at(i);
- newMapping.at(i) = count;
- ++count;
- }
- }
- m_parent->m_vertices.resize(count);
- for (int i = 0; i < m_edges.size(); ++i) {
- m_edges.at(i).from = newMapping.at(m_edges.at(i).from);
- m_edges.at(i).to = newMapping.at(m_edges.at(i).to);
- }
-}
-
-template <typename T>
-bool QTriangulator<T>::ComplexToSimple::CompareEdges::operator () (int i, int j) const
-{
- int cmp = comparePoints(m_parent->m_parent->m_vertices.at(m_parent->m_edges.at(i).from),
- m_parent->m_parent->m_vertices.at(m_parent->m_edges.at(j).from));
- if (cmp == 0) {
- cmp = comparePoints(m_parent->m_parent->m_vertices.at(m_parent->m_edges.at(i).to),
- m_parent->m_parent->m_vertices.at(m_parent->m_edges.at(j).to));
- }
- return cmp > 0;
-}
-
-template <typename T>
-inline bool QTriangulator<T>::ComplexToSimple::Event::operator < (const Event &other) const
-{
- if (point == other.point)
- return type < other.type; // 'Lower' has higher priority than 'Upper'.
- return other.point < point;
-}
-
-//============================================================================//
-// QTriangulator::ComplexToSimple::DebugDialog //
-//============================================================================//
-
-#ifdef Q_TRIANGULATOR_DEBUG
-template <typename T>
-QTriangulator<T>::ComplexToSimple::DebugDialog::DebugDialog(ComplexToSimple *parent, int currentVertex)
- : m_parent(parent), m_vertex(currentVertex)
-{
- QDataBuffer<QPodPoint> &vertices = m_parent->m_parent->m_vertices;
- if (vertices.isEmpty())
- return;
-
- int minX, maxX, minY, maxY;
- minX = maxX = vertices.at(0).x;
- minY = maxY = vertices.at(0).y;
- for (int i = 1; i < vertices.size(); ++i) {
- minX = qMin(minX, vertices.at(i).x);
- maxX = qMax(maxX, vertices.at(i).x);
- minY = qMin(minY, vertices.at(i).y);
- maxY = qMax(maxY, vertices.at(i).y);
- }
- int w = maxX - minX;
- int h = maxY - minY;
- qreal border = qMin(w, h) / 10.0;
- m_window = QRectF(minX - border, minY - border, (maxX - minX + 2 * border), (maxY - minY + 2 * border));
-}
-
-template <typename T>
-void QTriangulator<T>::ComplexToSimple::DebugDialog::paintEvent(QPaintEvent *)
-{
- QPainter p(this);
- p.setRenderHint(QPainter::Antialiasing, true);
- p.fillRect(rect(), Qt::black);
- QDataBuffer<QPodPoint> &vertices = m_parent->m_parent->m_vertices;
- if (vertices.isEmpty())
- return;
-
- qreal halfPointSize = qMin(m_window.width(), m_window.height()) / 300.0;
- p.setWindow(m_window.toRect());
-
- p.setPen(Qt::white);
-
- QDataBuffer<Edge> &edges = m_parent->m_edges;
- for (int i = 0; i < edges.size(); ++i) {
- QPodPoint u = vertices.at(edges.at(i).from);
- QPodPoint v = vertices.at(edges.at(i).to);
- p.drawLine(u.x, u.y, v.x, v.y);
- }
-
- for (int i = 0; i < vertices.size(); ++i) {
- QPodPoint q = vertices.at(i);
- p.fillRect(QRectF(q.x - halfPointSize, q.y - halfPointSize, 2 * halfPointSize, 2 * halfPointSize), Qt::red);
- }
-
- Qt::GlobalColor colors[6] = {Qt::red, Qt::green, Qt::blue, Qt::cyan, Qt::magenta, Qt::yellow};
- p.setOpacity(0.5);
- int count = 0;
- if (m_parent->m_edgeList.root) {
- QRBTree<int>::Node *current = m_parent->m_edgeList.front(m_parent->m_edgeList.root);
- while (current) {
- p.setPen(colors[count++ % 6]);
- QPodPoint u = vertices.at(edges.at(current->data).from);
- QPodPoint v = vertices.at(edges.at(current->data).to);
- p.drawLine(u.x, u.y, v.x, v.y);
- current = m_parent->m_edgeList.next(current);
- }
- }
-
- p.setOpacity(1.0);
- QPodPoint q = vertices.at(m_vertex);
- p.fillRect(QRectF(q.x - halfPointSize, q.y - halfPointSize, 2 * halfPointSize, 2 * halfPointSize), Qt::green);
-
- p.setPen(Qt::gray);
- QDataBuffer<Split> &splits = m_parent->m_splits;
- for (int i = 0; i < splits.size(); ++i) {
- QPodPoint q = vertices.at(splits.at(i).vertex);
- QPodPoint u = vertices.at(edges.at(splits.at(i).edge).from) - q;
- QPodPoint v = vertices.at(edges.at(splits.at(i).edge).to) - q;
- qreal uLen = sqrt(qreal(qDot(u, u)));
- qreal vLen = sqrt(qreal(qDot(v, v)));
- if (uLen) {
- u.x *= 2 * halfPointSize / uLen;
- u.y *= 2 * halfPointSize / uLen;
- }
- if (vLen) {
- v.x *= 2 * halfPointSize / vLen;
- v.y *= 2 * halfPointSize / vLen;
- }
- u += q;
- v += q;
- p.drawLine(u.x, u.y, v.x, v.y);
- }
-}
-
-template <typename T>
-void QTriangulator<T>::ComplexToSimple::DebugDialog::wheelEvent(QWheelEvent *event)
-{
- qreal scale = exp(-0.001 * event->delta());
- QPointF center = m_window.center();
- QPointF delta = scale * (m_window.bottomRight() - center);
- m_window = QRectF(center - delta, center + delta);
- event->accept();
- update();
-}
-
-template <typename T>
-void QTriangulator<T>::ComplexToSimple::DebugDialog::mouseMoveEvent(QMouseEvent *event)
-{
- if (event->buttons() & Qt::LeftButton) {
- QPointF delta = event->pos() - m_lastMousePos;
- delta.setX(delta.x() * m_window.width() / width());
- delta.setY(delta.y() * m_window.height() / height());
- m_window.translate(-delta.x(), -delta.y());
- m_lastMousePos = event->pos();
- event->accept();
- update();
- }
-}
-
-template <typename T>
-void QTriangulator<T>::ComplexToSimple::DebugDialog::mousePressEvent(QMouseEvent *event)
-{
- if (event->button() == Qt::LeftButton)
- m_lastMousePos = event->pos();
- event->accept();
-}
-
-
-#endif
-
-//============================================================================//
-// QTriangulator::SimpleToMonotone //
-//============================================================================//
-template <typename T>
-void QTriangulator<T>::SimpleToMonotone::decompose()
-{
- setupDataStructures();
- removeZeroLengthEdges();
- monotoneDecomposition();
-
- m_parent->m_indices.clear();
- QBitArray processed(m_edges.size(), false);
- for (int first = 0; first < m_edges.size(); ++first) {
- if (processed.at(first))
- continue;
- int i = first;
- do {
- Q_ASSERT(!processed.at(i));
- Q_ASSERT(m_edges.at(m_edges.at(i).next).previous == i);
- m_parent->m_indices.push_back(m_edges.at(i).from);
- processed.setBit(i);
- i = m_edges.at(i).next;
- } while (i != first);
- if (m_parent->m_indices.size() > 0 && m_parent->m_indices.back() != T(-1)) // Q_TRIANGULATE_END_OF_POLYGON
- m_parent->m_indices.push_back(T(-1)); // Q_TRIANGULATE_END_OF_POLYGON
- }
-}
-
-template <typename T>
-void QTriangulator<T>::SimpleToMonotone::setupDataStructures()
-{
- int i = 0;
- Edge e;
- e.node = 0;
- e.twin = -1;
-
- while (i + 3 <= m_parent->m_indices.size()) {
- int start = m_edges.size();
-
- do {
- e.from = m_parent->m_indices.at(i);
- e.type = RegularVertex;
- e.next = m_edges.size() + 1;
- e.previous = m_edges.size() - 1;
- m_edges.add(e);
- ++i;
- Q_ASSERT(i < m_parent->m_indices.size());
- } while (m_parent->m_indices.at(i) != T(-1)); // Q_TRIANGULATE_END_OF_POLYGON
-
- m_edges.last().next = start;
- m_edges.at(start).previous = m_edges.size() - 1;
- ++i; // Skip Q_TRIANGULATE_END_OF_POLYGON.
- }
-
- for (i = 0; i < m_edges.size(); ++i) {
- m_edges.at(i).to = m_edges.at(m_edges.at(i).next).from;
- m_edges.at(i).pointingUp = m_parent->m_vertices.at(m_edges.at(i).to) < m_parent->m_vertices.at(m_edges.at(i).from);
- m_edges.at(i).helper = -1; // Not initialized here.
- }
-}
-
-template <typename T>
-void QTriangulator<T>::SimpleToMonotone::removeZeroLengthEdges()
-{
- for (int i = 0; i < m_edges.size(); ++i) {
- if (m_parent->m_vertices.at(m_edges.at(i).from) == m_parent->m_vertices.at(m_edges.at(i).to)) {
- m_edges.at(m_edges.at(i).previous).next = m_edges.at(i).next;
- m_edges.at(m_edges.at(i).next).previous = m_edges.at(i).previous;
- m_edges.at(m_edges.at(i).next).from = m_edges.at(i).from;
- m_edges.at(i).next = -1; // Mark as removed.
- }
- }
-
- QDataBuffer<int> newMapping(m_edges.size());
- newMapping.resize(m_edges.size());
- int count = 0;
- for (int i = 0; i < m_edges.size(); ++i) {
- if (m_edges.at(i).next != -1) {
- m_edges.at(count) = m_edges.at(i);
- newMapping.at(i) = count;
- ++count;
- }
- }
- m_edges.resize(count);
- for (int i = 0; i < m_edges.size(); ++i) {
- m_edges.at(i).next = newMapping.at(m_edges.at(i).next);
- m_edges.at(i).previous = newMapping.at(m_edges.at(i).previous);
- }
-}
-
-template <typename T>
-void QTriangulator<T>::SimpleToMonotone::fillPriorityQueue()
-{
- m_upperVertex.reset();
- m_upperVertex.reserve(m_edges.size());
- for (int i = 0; i < m_edges.size(); ++i)
- m_upperVertex.add(i);
- CompareVertices cmp(this);
- //qSort(m_upperVertex.data(), m_upperVertex.data() + m_upperVertex.size(), cmp);
- sort(m_upperVertex.data(), m_upperVertex.size(), cmp);
- //for (int i = 1; i < m_upperVertex.size(); ++i) {
- // Q_ASSERT(!cmp(m_upperVertex.at(i), m_upperVertex.at(i - 1)));
- //}
-}
-
-template <typename T>
-bool QTriangulator<T>::SimpleToMonotone::edgeIsLeftOfEdge(int leftEdgeIndex, int rightEdgeIndex) const
-{
- const Edge &leftEdge = m_edges.at(leftEdgeIndex);
- const Edge &rightEdge = m_edges.at(rightEdgeIndex);
- const QPodPoint &u = m_parent->m_vertices.at(rightEdge.upper());
- const QPodPoint &l = m_parent->m_vertices.at(rightEdge.lower());
- qint64 d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(m_parent->m_vertices.at(leftEdge.upper()), l, u);
- // d < 0: left, d > 0: right, d == 0: on top
- if (d == 0)
- d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(m_parent->m_vertices.at(leftEdge.lower()), l, u);
- return d < 0;
-}
-
-// Returns the rightmost edge not to the right of the given edge.
-template <typename T>
-QRBTree<int>::Node *QTriangulator<T>::SimpleToMonotone::searchEdgeLeftOfEdge(int edgeIndex) const
-{
- QRBTree<int>::Node *current = m_edgeList.root;
- QRBTree<int>::Node *result = 0;
- while (current) {
- if (edgeIsLeftOfEdge(edgeIndex, current->data)) {
- current = current->left;
- } else {
- result = current;
- current = current->right;
- }
- }
- return result;
-}
-
-// Returns the rightmost edge left of the given point.
-template <typename T>
-QRBTree<int>::Node *QTriangulator<T>::SimpleToMonotone::searchEdgeLeftOfPoint(int pointIndex) const
-{
- QRBTree<int>::Node *current = m_edgeList.root;
- QRBTree<int>::Node *result = 0;
- while (current) {
- const QPodPoint &p1 = m_parent->m_vertices.at(m_edges.at(current->data).lower());
- const QPodPoint &p2 = m_parent->m_vertices.at(m_edges.at(current->data).upper());
- qint64 d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(m_parent->m_vertices.at(pointIndex), p1, p2);
- if (d <= 0) {
- current = current->left;
- } else {
- result = current;
- current = current->right;
- }
- }
- return result;
-}
-
-template <typename T>
-void QTriangulator<T>::SimpleToMonotone::classifyVertex(int i)
-{
- Edge &e2 = m_edges.at(i);
- const Edge &e1 = m_edges.at(e2.previous);
-
- bool startOrSplit = (e1.pointingUp && !e2.pointingUp);
- bool endOrMerge = (!e1.pointingUp && e2.pointingUp);
-
- const QPodPoint &p1 = m_parent->m_vertices.at(e1.from);
- const QPodPoint &p2 = m_parent->m_vertices.at(e2.from);
- const QPodPoint &p3 = m_parent->m_vertices.at(e2.to);
- qint64 d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(p1, p2, p3);
- Q_ASSERT(d != 0 || (!startOrSplit && !endOrMerge));
-
- e2.type = RegularVertex;
-
- if (m_clockwiseOrder) {
- if (startOrSplit)
- e2.type = (d < 0 ? SplitVertex : StartVertex);
- else if (endOrMerge)
- e2.type = (d < 0 ? MergeVertex : EndVertex);
- } else {
- if (startOrSplit)
- e2.type = (d > 0 ? SplitVertex : StartVertex);
- else if (endOrMerge)
- e2.type = (d > 0 ? MergeVertex : EndVertex);
- }
-}
-
-template <typename T>
-void QTriangulator<T>::SimpleToMonotone::classifyVertices()
-{
- for (int i = 0; i < m_edges.size(); ++i)
- classifyVertex(i);
-}
-
-template <typename T>
-bool QTriangulator<T>::SimpleToMonotone::pointIsInSector(const QPodPoint &p, const QPodPoint &v1, const QPodPoint &v2, const QPodPoint &v3)
-{
- bool leftOfPreviousEdge = !qPointIsLeftOfLine(p, v2, v1);
- bool leftOfNextEdge = !qPointIsLeftOfLine(p, v3, v2);
-
- if (qPointIsLeftOfLine(v1, v2, v3))
- return leftOfPreviousEdge && leftOfNextEdge;
- else
- return leftOfPreviousEdge || leftOfNextEdge;
-}
-
-template <typename T>
-bool QTriangulator<T>::SimpleToMonotone::pointIsInSector(int vertex, int sector)
-{
- const QPodPoint &center = m_parent->m_vertices.at(m_edges.at(sector).from);
- // Handle degenerate edges.
- while (m_parent->m_vertices.at(m_edges.at(vertex).from) == center)
- vertex = m_edges.at(vertex).next;
- int next = m_edges.at(sector).next;
- while (m_parent->m_vertices.at(m_edges.at(next).from) == center)
- next = m_edges.at(next).next;
- int previous = m_edges.at(sector).previous;
- while (m_parent->m_vertices.at(m_edges.at(previous).from) == center)
- previous = m_edges.at(previous).previous;
-
- const QPodPoint &p = m_parent->m_vertices.at(m_edges.at(vertex).from);
- const QPodPoint &v1 = m_parent->m_vertices.at(m_edges.at(previous).from);
- const QPodPoint &v3 = m_parent->m_vertices.at(m_edges.at(next).from);
- if (m_clockwiseOrder)
- return pointIsInSector(p, v3, center, v1);
- else
- return pointIsInSector(p, v1, center, v3);
-}
-
-template <typename T>
-int QTriangulator<T>::SimpleToMonotone::findSector(int edge, int vertex)
-{
- while (!pointIsInSector(vertex, edge)) {
- edge = m_edges.at(m_edges.at(edge).previous).twin;
- Q_ASSERT(edge != -1);
- }
- return edge;
-}
-
-template <typename T>
-void QTriangulator<T>::SimpleToMonotone::createDiagonal(int lower, int upper)
-{
- lower = findSector(lower, upper);
- upper = findSector(upper, lower);
-
- int prevLower = m_edges.at(lower).previous;
- int prevUpper = m_edges.at(upper).previous;
-
- Edge e;
-
- e.twin = m_edges.size() + 1;
- e.next = upper;
- e.previous = prevLower;
- e.from = m_edges.at(lower).from;
- e.to = m_edges.at(upper).from;
- m_edges.at(upper).previous = m_edges.at(prevLower).next = int(m_edges.size());
- m_edges.add(e);
-
- e.twin = m_edges.size() - 1;
- e.next = lower;
- e.previous = prevUpper;
- e.from = m_edges.at(upper).from;
- e.to = m_edges.at(lower).from;
- m_edges.at(lower).previous = m_edges.at(prevUpper).next = int(m_edges.size());
- m_edges.add(e);
-}
-
-template <typename T>
-void QTriangulator<T>::SimpleToMonotone::monotoneDecomposition()
-{
- if (m_edges.isEmpty())
- return;
-
- Q_ASSERT(!m_edgeList.root);
- QDataBuffer<QPair<int, int> > diagonals(m_upperVertex.size());
-
- int i = 0;
- for (int index = 1; index < m_edges.size(); ++index) {
- if (m_parent->m_vertices.at(m_edges.at(index).from) < m_parent->m_vertices.at(m_edges.at(i).from))
- i = index;
- }
- Q_ASSERT(i < m_edges.size());
- int j = m_edges.at(i).previous;
- Q_ASSERT(j < m_edges.size());
- m_clockwiseOrder = qPointIsLeftOfLine(m_parent->m_vertices.at((quint32)m_edges.at(i).from),
- m_parent->m_vertices.at((quint32)m_edges.at(j).from), m_parent->m_vertices.at((quint32)m_edges.at(i).to));
-
- classifyVertices();
- fillPriorityQueue();
-
- // debug: set helpers explicitly (shouldn't be necessary)
- //for (int i = 0; i < m_edges.size(); ++i)
- // m_edges.at(i).helper = m_edges.at(i).upper();
-
- while (!m_upperVertex.isEmpty()) {
- i = m_upperVertex.last();
- Q_ASSERT(i < m_edges.size());
- m_upperVertex.pop_back();
- j = m_edges.at(i).previous;
- Q_ASSERT(j < m_edges.size());
-
- QRBTree<int>::Node *leftEdgeNode = 0;
-
- switch (m_edges.at(i).type) {
- case RegularVertex:
- // If polygon interior is to the right of the vertex...
- if (m_edges.at(i).pointingUp == m_clockwiseOrder) {
- if (m_edges.at(i).node) {
- Q_ASSERT(!m_edges.at(j).node);
- if (m_edges.at(m_edges.at(i).helper).type == MergeVertex)
- diagonals.add(QPair<int, int>(i, m_edges.at(i).helper));
- m_edges.at(j).node = m_edges.at(i).node;
- m_edges.at(i).node = 0;
- m_edges.at(j).node->data = j;
- m_edges.at(j).helper = i;
- } else if (m_edges.at(j).node) {
- Q_ASSERT(!m_edges.at(i).node);
- if (m_edges.at(m_edges.at(j).helper).type == MergeVertex)
- diagonals.add(QPair<int, int>(i, m_edges.at(j).helper));
- m_edges.at(i).node = m_edges.at(j).node;
- m_edges.at(j).node = 0;
- m_edges.at(i).node->data = i;
- m_edges.at(i).helper = i;
- } else {
- qWarning("Inconsistent polygon. (#1)");
- }
- } else {
- leftEdgeNode = searchEdgeLeftOfPoint(m_edges.at(i).from);
- if (leftEdgeNode) {
- if (m_edges.at(m_edges.at(leftEdgeNode->data).helper).type == MergeVertex)
- diagonals.add(QPair<int, int>(i, m_edges.at(leftEdgeNode->data).helper));
- m_edges.at(leftEdgeNode->data).helper = i;
- } else {
- qWarning("Inconsistent polygon. (#2)");
- }
- }
- break;
- case SplitVertex:
- leftEdgeNode = searchEdgeLeftOfPoint(m_edges.at(i).from);
- if (leftEdgeNode) {
- diagonals.add(QPair<int, int>(i, m_edges.at(leftEdgeNode->data).helper));
- m_edges.at(leftEdgeNode->data).helper = i;
- } else {
- qWarning("Inconsistent polygon. (#3)");
- }
- // Fall through.
- case StartVertex:
- if (m_clockwiseOrder) {
- leftEdgeNode = searchEdgeLeftOfEdge(j);
- QRBTree<int>::Node *node = m_edgeList.newNode();
- node->data = j;
- m_edges.at(j).node = node;
- m_edges.at(j).helper = i;
- m_edgeList.attachAfter(leftEdgeNode, node);
- Q_ASSERT(m_edgeList.validate());
- } else {
- leftEdgeNode = searchEdgeLeftOfEdge(i);
- QRBTree<int>::Node *node = m_edgeList.newNode();
- node->data = i;
- m_edges.at(i).node = node;
- m_edges.at(i).helper = i;
- m_edgeList.attachAfter(leftEdgeNode, node);
- Q_ASSERT(m_edgeList.validate());
- }
- break;
- case MergeVertex:
- leftEdgeNode = searchEdgeLeftOfPoint(m_edges.at(i).from);
- if (leftEdgeNode) {
- if (m_edges.at(m_edges.at(leftEdgeNode->data).helper).type == MergeVertex)
- diagonals.add(QPair<int, int>(i, m_edges.at(leftEdgeNode->data).helper));
- m_edges.at(leftEdgeNode->data).helper = i;
- } else {
- qWarning("Inconsistent polygon. (#4)");
- }
- // Fall through.
- case EndVertex:
- if (m_clockwiseOrder) {
- if (m_edges.at(m_edges.at(i).helper).type == MergeVertex)
- diagonals.add(QPair<int, int>(i, m_edges.at(i).helper));
- if (m_edges.at(i).node) {
- m_edgeList.deleteNode(m_edges.at(i).node);
- Q_ASSERT(m_edgeList.validate());
- } else {
- qWarning("Inconsistent polygon. (#5)");
- }
- } else {
- if (m_edges.at(m_edges.at(j).helper).type == MergeVertex)
- diagonals.add(QPair<int, int>(i, m_edges.at(j).helper));
- if (m_edges.at(j).node) {
- m_edgeList.deleteNode(m_edges.at(j).node);
- Q_ASSERT(m_edgeList.validate());
- } else {
- qWarning("Inconsistent polygon. (#6)");
- }
- }
- break;
- }
- }
-
- for (int i = 0; i < diagonals.size(); ++i)
- createDiagonal(diagonals.at(i).first, diagonals.at(i).second);
-}
-
-template <typename T>
-bool QTriangulator<T>::SimpleToMonotone::CompareVertices::operator () (int i, int j) const
-{
- if (m_parent->m_edges.at(i).from == m_parent->m_edges.at(j).from)
- return m_parent->m_edges.at(i).type > m_parent->m_edges.at(j).type;
- return m_parent->m_parent->m_vertices.at(m_parent->m_edges.at(i).from) >
- m_parent->m_parent->m_vertices.at(m_parent->m_edges.at(j).from);
-}
-
-//============================================================================//
-// QTriangulator::MonotoneToTriangles //
-//============================================================================//
-template <typename T>
-void QTriangulator<T>::MonotoneToTriangles::decompose()
-{
- QVector<T> result;
- QDataBuffer<int> stack(m_parent->m_indices.size());
- m_first = 0;
- // Require at least three more indices.
- while (m_first + 3 <= m_parent->m_indices.size()) {
- m_length = 0;
- while (m_parent->m_indices.at(m_first + m_length) != T(-1)) { // Q_TRIANGULATE_END_OF_POLYGON
- ++m_length;
- Q_ASSERT(m_first + m_length < m_parent->m_indices.size());
- }
- if (m_length < 3) {
- m_first += m_length + 1;
- continue;
- }
-
- int minimum = 0;
- while (less(next(minimum), minimum))
- minimum = next(minimum);
- while (less(previous(minimum), minimum))
- minimum = previous(minimum);
-
- stack.reset();
- stack.add(minimum);
- int left = previous(minimum);
- int right = next(minimum);
- bool stackIsOnLeftSide;
- bool clockwiseOrder = leftOfEdge(minimum, left, right);
-
- if (less(left, right)) {
- stack.add(left);
- left = previous(left);
- stackIsOnLeftSide = true;
- } else {
- stack.add(right);
- right = next(right);
- stackIsOnLeftSide = false;
- }
-
- for (int count = 0; count + 2 < m_length; ++count)
- {
- Q_ASSERT(stack.size() >= 2);
- if (less(left, right)) {
- if (stackIsOnLeftSide == false) {
- for (int i = 0; i + 1 < stack.size(); ++i) {
- result.push_back(indices(stack.at(i + 1)));
- result.push_back(indices(left));
- result.push_back(indices(stack.at(i)));
- }
- stack.first() = stack.last();
- stack.resize(1);
- } else {
- while (stack.size() >= 2 && (clockwiseOrder ^ !leftOfEdge(left, stack.at(stack.size() - 2), stack.last()))) {
- result.push_back(indices(stack.at(stack.size() - 2)));
- result.push_back(indices(left));
- result.push_back(indices(stack.last()));
- stack.pop_back();
- }
- }
- stack.add(left);
- left = previous(left);
- stackIsOnLeftSide = true;
- } else {
- if (stackIsOnLeftSide == true) {
- for (int i = 0; i + 1 < stack.size(); ++i) {
- result.push_back(indices(stack.at(i)));
- result.push_back(indices(right));
- result.push_back(indices(stack.at(i + 1)));
- }
- stack.first() = stack.last();
- stack.resize(1);
- } else {
- while (stack.size() >= 2 && (clockwiseOrder ^ !leftOfEdge(right, stack.last(), stack.at(stack.size() - 2)))) {
- result.push_back(indices(stack.last()));
- result.push_back(indices(right));
- result.push_back(indices(stack.at(stack.size() - 2)));
- stack.pop_back();
- }
- }
- stack.add(right);
- right = next(right);
- stackIsOnLeftSide = false;
- }
- }
-
- m_first += m_length + 1;
- }
- m_parent->m_indices = result;
-}
-
-//============================================================================//
-// qTriangulate //
-//============================================================================//
-
-QTriangleSet qTriangulate(const qreal *polygon,
- int count, uint hint, const QTransform &matrix)
-{
- QTriangleSet triangleSet;
- if (QGLExtensions::glExtensions() & QGLExtensions::ElementIndexUint) {
- QTriangulator<quint32> triangulator;
- triangulator.initialize(polygon, count, hint, matrix);
- QVertexSet<quint32> vertexSet = triangulator.triangulate();
- triangleSet.vertices = vertexSet.vertices;
- triangleSet.indices.setDataUint(vertexSet.indices);
-
- } else {
- QTriangulator<quint16> triangulator;
- triangulator.initialize(polygon, count, hint, matrix);
- QVertexSet<quint16> vertexSet = triangulator.triangulate();
- triangleSet.vertices = vertexSet.vertices;
- triangleSet.indices.setDataUshort(vertexSet.indices);
- }
- return triangleSet;
-}
-
-QTriangleSet qTriangulate(const QVectorPath &path,
- const QTransform &matrix, qreal lod)
-{
- QTriangleSet triangleSet;
- if (QGLExtensions::glExtensions() & QGLExtensions::ElementIndexUint) {
- QTriangulator<quint32> triangulator;
- triangulator.initialize(path, matrix, lod);
- QVertexSet<quint32> vertexSet = triangulator.triangulate();
- triangleSet.vertices = vertexSet.vertices;
- triangleSet.indices.setDataUint(vertexSet.indices);
- } else {
- QTriangulator<quint16> triangulator;
- triangulator.initialize(path, matrix, lod);
- QVertexSet<quint16> vertexSet = triangulator.triangulate();
- triangleSet.vertices = vertexSet.vertices;
- triangleSet.indices.setDataUshort(vertexSet.indices);
- }
- return triangleSet;
-}
-
-QTriangleSet qTriangulate(const QPainterPath &path,
- const QTransform &matrix, qreal lod)
-{
- QTriangleSet triangleSet;
- if (QGLExtensions::glExtensions() & QGLExtensions::ElementIndexUint) {
- QTriangulator<quint32> triangulator;
- triangulator.initialize(path, matrix, lod);
- QVertexSet<quint32> vertexSet = triangulator.triangulate();
- triangleSet.vertices = vertexSet.vertices;
- triangleSet.indices.setDataUint(vertexSet.indices);
- } else {
- QTriangulator<quint16> triangulator;
- triangulator.initialize(path, matrix, lod);
- QVertexSet<quint16> vertexSet = triangulator.triangulate();
- triangleSet.vertices = vertexSet.vertices;
- triangleSet.indices.setDataUshort(vertexSet.indices);
- }
- return triangleSet;
-}
-
-QPolylineSet qPolyline(const QVectorPath &path,
- const QTransform &matrix, qreal lod)
-{
- QPolylineSet polyLineSet;
- if (QGLExtensions::glExtensions() & QGLExtensions::ElementIndexUint) {
- QTriangulator<quint32> triangulator;
- triangulator.initialize(path, matrix, lod);
- QVertexSet<quint32> vertexSet = triangulator.polyline();
- polyLineSet.vertices = vertexSet.vertices;
- polyLineSet.indices.setDataUint(vertexSet.indices);
- } else {
- QTriangulator<quint16> triangulator;
- triangulator.initialize(path, matrix, lod);
- QVertexSet<quint16> vertexSet = triangulator.polyline();
- polyLineSet.vertices = vertexSet.vertices;
- polyLineSet.indices.setDataUshort(vertexSet.indices);
- }
- return polyLineSet;
-}
-
-QPolylineSet qPolyline(const QPainterPath &path,
- const QTransform &matrix, qreal lod)
-{
- QPolylineSet polyLineSet;
- if (QGLExtensions::glExtensions() & QGLExtensions::ElementIndexUint) {
- QTriangulator<quint32> triangulator;
- triangulator.initialize(path, matrix, lod);
- QVertexSet<quint32> vertexSet = triangulator.polyline();
- polyLineSet.vertices = vertexSet.vertices;
- polyLineSet.indices.setDataUint(vertexSet.indices);
- } else {
- QTriangulator<quint16> triangulator;
- triangulator.initialize(path, matrix, lod);
- QVertexSet<quint16> vertexSet = triangulator.polyline();
- polyLineSet.vertices = vertexSet.vertices;
- polyLineSet.indices.setDataUshort(vertexSet.indices);
- }
- return polyLineSet;
-}
-
-QT_END_NAMESPACE
diff --git a/src/opengl/gl2paintengineex/qtriangulator_p.h b/src/opengl/gl2paintengineex/qtriangulator_p.h
deleted file mode 100644
index 04a219c255..0000000000
--- a/src/opengl/gl2paintengineex/qtriangulator_p.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QTRIANGULATOR_P_H
-#define QTRIANGULATOR_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/qvector.h>
-#include <QtGui/private/qvectorpath_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class Q_OPENGL_EXPORT QVertexIndexVector
-{
-public:
- enum Type {
- UnsignedInt,
- UnsignedShort
- };
-
- inline Type type() const { return t; }
-
- inline void setDataUint(const QVector<quint32> &data)
- {
- t = UnsignedInt;
- indices32 = data;
- }
-
- inline void setDataUshort(const QVector<quint16> &data)
- {
- t = UnsignedShort;
- indices16 = data;
- }
-
- inline const void* data() const
- {
- if (t == UnsignedInt)
- return indices32.data();
- return indices16.data();
- }
-
- inline int size() const
- {
- if (t == UnsignedInt)
- return indices32.size();
- return indices16.size();
- }
-
- inline QVertexIndexVector &operator = (const QVertexIndexVector &other)
- {
- if (t == UnsignedInt)
- indices32 = other.indices32;
- else
- indices16 = other.indices16;
-
- return *this;
- }
-
-private:
-
- Type t;
- QVector<quint32> indices32;
- QVector<quint16> indices16;
-};
-
-struct Q_OPENGL_EXPORT QTriangleSet
-{
- inline QTriangleSet() { }
- inline QTriangleSet(const QTriangleSet &other) : vertices(other.vertices), indices(other.indices) { }
- QTriangleSet &operator = (const QTriangleSet &other) {vertices = other.vertices; indices = other.indices; return *this;}
-
- // The vertices of a triangle are given by: (x[i[n]], y[i[n]]), (x[j[n]], y[j[n]]), (x[k[n]], y[k[n]]), n = 0, 1, ...
- QVector<qreal> vertices; // [x[0], y[0], x[1], y[1], x[2], ...]
- QVertexIndexVector indices; // [i[0], j[0], k[0], i[1], j[1], k[1], i[2], ...]
-};
-
-struct Q_OPENGL_EXPORT QPolylineSet
-{
- inline QPolylineSet() { }
- inline QPolylineSet(const QPolylineSet &other) : vertices(other.vertices), indices(other.indices) { }
- QPolylineSet &operator = (const QPolylineSet &other) {vertices = other.vertices; indices = other.indices; return *this;}
-
- QVector<qreal> vertices; // [x[0], y[0], x[1], y[1], x[2], ...]
- QVertexIndexVector indices; // End of polyline is marked with -1.
-};
-
-// The vertex coordinates of the returned triangle set will be rounded to a grid with a mesh size
-// of 1/32. The polygon is first transformed, then scaled by 32, the coordinates are rounded to
-// integers, the polygon is triangulated, and then scaled back by 1/32.
-// 'hint' should be a combination of QVectorPath::Hints.
-// 'lod' is the level of detail. Default is 1. Curves are split into more lines when 'lod' is higher.
-QTriangleSet qTriangulate(const qreal *polygon, int count, uint hint = QVectorPath::PolygonHint | QVectorPath::OddEvenFill, const QTransform &matrix = QTransform());
-QTriangleSet qTriangulate(const QVectorPath &path, const QTransform &matrix = QTransform(), qreal lod = 1);
-QTriangleSet Q_OPENGL_EXPORT qTriangulate(const QPainterPath &path, const QTransform &matrix = QTransform(), qreal lod = 1);
-QPolylineSet qPolyline(const QVectorPath &path, const QTransform &matrix = QTransform(), qreal lod = 1);
-QPolylineSet Q_OPENGL_EXPORT qPolyline(const QPainterPath &path, const QTransform &matrix = QTransform(), qreal lod = 1);
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/opengl/opengl.pro b/src/opengl/opengl.pro
index e2dc011532..658cdd5eb4 100644
--- a/src/opengl/opengl.pro
+++ b/src/opengl/opengl.pro
@@ -2,7 +2,7 @@ load(qt_module)
TARGET = QtOpenGL
QPRO_PWD = $$PWD
-QT = core-private gui-private
+QT = core-private gui-private widgets-private
CONFIG += module
MODULE_PRI = ../modules/qt_opengl.pri
@@ -19,7 +19,7 @@ load(qt_module_config)
HEADERS += $$QT_SOURCE_TREE/src/opengl/qtopenglversion.h
-!win32:!embedded:!mac:!symbian:!qpa:CONFIG += x11
+!win32:!embedded:!mac:!qpa:CONFIG += x11
contains(QT_CONFIG, opengl):CONFIG += opengl
contains(QT_CONFIG, opengles1):CONFIG += opengles1
contains(QT_CONFIG, opengles2):CONFIG += opengles2
@@ -47,144 +47,32 @@ SOURCES += qgl.cpp \
qglpaintdevice.cpp \
qglbuffer.cpp \
-
-!contains(QT_CONFIG, opengles2) {
- HEADERS += qpaintengine_opengl_p.h
- SOURCES += qpaintengine_opengl.cpp
-}
-
-!contains(QT_CONFIG, opengles1) {
- HEADERS += qglshaderprogram.h \
- qglpixmapfilter_p.h \
- qgraphicsshadereffect_p.h \
- qgraphicssystem_gl_p.h \
- qwindowsurface_gl_p.h \
- qpixmapdata_gl_p.h \
- gl2paintengineex/qglgradientcache_p.h \
- gl2paintengineex/qglengineshadermanager_p.h \
- gl2paintengineex/qgl2pexvertexarray_p.h \
- gl2paintengineex/qpaintengineex_opengl2_p.h \
- gl2paintengineex/qglengineshadersource_p.h \
- gl2paintengineex/qglcustomshaderstage_p.h \
- gl2paintengineex/qtriangulatingstroker_p.h \
- gl2paintengineex/qtriangulator_p.h \
- gl2paintengineex/qrbtree_p.h \
- gl2paintengineex/qtextureglyphcache_gl_p.h \
- gl2paintengineex/qglshadercache_p.h \
- gl2paintengineex/qglshadercache_meego_p.h
-
- SOURCES += qglshaderprogram.cpp \
- qglpixmapfilter.cpp \
- qgraphicsshadereffect.cpp \
- qgraphicssystem_gl.cpp \
- qwindowsurface_gl.cpp \
- qpixmapdata_gl.cpp \
- gl2paintengineex/qglgradientcache.cpp \
- gl2paintengineex/qglengineshadermanager.cpp \
- gl2paintengineex/qgl2pexvertexarray.cpp \
- gl2paintengineex/qpaintengineex_opengl2.cpp \
- gl2paintengineex/qglcustomshaderstage.cpp \
- gl2paintengineex/qtriangulatingstroker.cpp \
- gl2paintengineex/qtriangulator.cpp \
- gl2paintengineex/qtextureglyphcache_gl.cpp
-
-}
-
-qpa {
- SOURCES += qgl_qpa.cpp \
- qglpixelbuffer_stub.cpp
-}
-
-x11 {
- contains(QT_CONFIG, egl) {
- SOURCES += qgl_x11egl.cpp \
- qglpixelbuffer_egl.cpp \
- qgl_egl.cpp \
- qpixmapdata_x11gl_egl.cpp \
- qwindowsurface_x11gl.cpp
-
- HEADERS += qgl_egl_p.h \
- qpixmapdata_x11gl_p.h \
- qwindowsurface_x11gl_p.h
-
- } else {
- SOURCES += qgl_x11.cpp \
- qglpixelbuffer_x11.cpp
- }
-
- contains(QT_CONFIG, fontconfig) {
- contains(QT_CONFIG, system-freetype) {
- embedded:CONFIG += opentype
- # pull in the proper freetype2 include directory
- include($$QT_SOURCE_TREE/config.tests/unix/freetype/freetype.pri)
- LIBS_PRIVATE += -lfreetype
- } else {
- ### Note: how does this compile with a non-system freetype?
- # This probably does not compile
- }
- } else {
- DEFINES *= QT_NO_FREETYPE
- }
-
- LIBS_PRIVATE += $$QMAKE_LIBS_DYNLOAD
-}
-
-mac:!qpa {
- OBJECTIVE_SOURCES += qgl_mac.mm \
- qglpixelbuffer_mac.mm
- LIBS_PRIVATE += -framework AppKit -framework Carbon
-}
-win32:!wince*: {
- DEFINES += QT_NO_EGL
- SOURCES += qgl_win.cpp \
- qglpixelbuffer_win.cpp
-}
-wince*: {
- SOURCES += qgl_wince.cpp \
- qglpixelbuffer_egl.cpp \
- qgl_egl.cpp
-
- HEADERS += qgl_egl_p.h
-}
-
-embedded {
- SOURCES += qgl_qws.cpp \
- qglpixelbuffer_egl.cpp \
- qglscreen_qws.cpp \
- qglwindowsurface_qws.cpp \
- qgl_egl.cpp
-
- HEADERS += qglscreen_qws.h \
- qglwindowsurface_qws_p.h \
- qgl_egl_p.h
-
- contains(QT_CONFIG, fontconfig) {
- include($$QT_SOURCE_TREE/config.tests/unix/freetype/freetype.pri)
- } else {
- DEFINES *= QT_NO_FREETYPE
- }
-}
-
-symbian {
- DEFINES += QGL_USE_TEXTURE_POOL QGL_NO_PRESERVED_SWAP
- SOURCES -= qpixmapdata_gl.cpp
- SOURCES += qgl_symbian.cpp \
- qpixmapdata_poolgl.cpp \
- qglpixelbuffer_egl.cpp \
- qgl_egl.cpp \
- qgltexturepool.cpp
-
- HEADERS += qgl_egl_p.h \
- qgltexturepool_p.h
-
- contains(QT_CONFIG, freetype) {
- DEFINES += QT_NO_FONTCONFIG
- INCLUDEPATH += \
- ../3rdparty/freetype/src \
- ../3rdparty/freetype/include
- }
-
- symbian:TARGET.UID3 = 0x2002131A
-}
+HEADERS += qglshaderprogram.h \
+ qgraphicsshadereffect_p.h \
+ gl2paintengineex/qglgradientcache_p.h \
+ gl2paintengineex/qglengineshadermanager_p.h \
+ gl2paintengineex/qgl2pexvertexarray_p.h \
+ gl2paintengineex/qpaintengineex_opengl2_p.h \
+ gl2paintengineex/qglengineshadersource_p.h \
+ gl2paintengineex/qglcustomshaderstage_p.h \
+ gl2paintengineex/qtriangulatingstroker_p.h \
+ gl2paintengineex/qtextureglyphcache_gl_p.h \
+ gl2paintengineex/qglshadercache_p.h \
+ gl2paintengineex/qglshadercache_meego_p.h
+
+SOURCES += qglshaderprogram.cpp \
+ qgraphicsshadereffect.cpp \
+ gl2paintengineex/qglgradientcache.cpp \
+ gl2paintengineex/qglengineshadermanager.cpp \
+ gl2paintengineex/qgl2pexvertexarray.cpp \
+ gl2paintengineex/qpaintengineex_opengl2.cpp \
+ gl2paintengineex/qglcustomshaderstage.cpp \
+ gl2paintengineex/qtriangulatingstroker.cpp \
+ gl2paintengineex/qtextureglyphcache_gl.cpp
+
+SOURCES += qgl_qpa.cpp \
+ qglpixelbuffer_stub.cpp
+
+DEFINES += QT_NO_EGL
INCLUDEPATH += ../3rdparty/harfbuzz/src
diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp
index f1fb2b4e7f..ad53b20098 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -45,21 +45,6 @@
#include <qdebug.h>
#include <qglfunctions.h>
-#if defined(Q_WS_X11)
-#include "private/qt_x11_p.h"
-#include "private/qpixmap_x11_p.h"
-#define INT32 dummy_INT32
-#define INT8 dummy_INT8
-#ifdef QT_NO_EGL
-# include <GL/glx.h>
-#endif
-#undef INT32
-#undef INT8
-#include "qx11info_x11.h"
-#elif defined(Q_WS_MAC)
-# include <private/qt_mac_p.h>
-#endif
-
#include <qdatetime.h>
#include <stdlib.h> // malloc
@@ -68,29 +53,15 @@
#include "qimage.h"
#include "qgl_p.h"
-#if !defined(QT_OPENGL_ES_1)
#include "gl2paintengineex/qpaintengineex_opengl2_p.h"
-#include <private/qwindowsurface_gl_p.h>
-#endif
-
-#ifndef QT_OPENGL_ES_2
-#include <private/qpaintengine_opengl_p.h>
-#endif
-#ifdef Q_WS_QWS
-#include <private/qglwindowsurface_qws_p.h>
-#endif
-
-#ifdef Q_WS_QPA
-#include <QtGui/QPlatformGLContext>
-#endif
+#include <QtGui/QPlatformOpenGLContext>
#include <qglpixelbuffer.h>
#include <qglframebufferobject.h>
#include <private/qimage_p.h>
-#include <private/qpixmapdata_p.h>
-#include <private/qpixmapdata_gl_p.h>
+#include <qplatformpixmap_qpa.h>
#include <private/qglpixelbuffer_p.h>
#include <private/qimagepixmapcleanuphooks_p.h>
#include "qcolormap.h"
@@ -98,24 +69,11 @@
#include "qlibrary.h"
#include <qmutex.h>
-#if defined(QT_OPENGL_ES) && !defined(QT_NO_EGL)
-#include <EGL/egl.h>
-#endif
-#ifdef QGL_USE_TEXTURE_POOL
-#include <private/qgltexturepool_p.h>
-#endif
-
// #define QT_GL_CONTEXT_RESOURCE_DEBUG
QT_BEGIN_NAMESPACE
-#if defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QWS) || defined(Q_WS_QPA) || defined(Q_OS_SYMBIAN)
QGLExtensionFuncs QGLContextPrivate::qt_extensionFuncs;
-#endif
-
-#ifdef Q_WS_X11
-extern const QX11Info *qt_x11Info(const QPaintDevice *pd);
-#endif
struct QGLThreadContext {
~QGLThreadContext() {
@@ -125,10 +83,6 @@ struct QGLThreadContext {
QGLContext *context;
};
-#ifndef Q_WS_QPA
-static QThreadStorage<QGLThreadContext *> qgl_context_storage;
-#endif
-
Q_GLOBAL_STATIC(QGLFormat, qgl_default_format)
class QGLDefaultOverlayFormat: public QGLFormat
@@ -155,71 +109,6 @@ QGLSignalProxy *QGLSignalProxy::instance()
}
-class QGLEngineSelector
-{
-public:
- QGLEngineSelector() : engineType(QPaintEngine::MaxUser)
- {
- }
-
- void setPreferredPaintEngine(QPaintEngine::Type type) {
- if (type == QPaintEngine::OpenGL || type == QPaintEngine::OpenGL2)
- engineType = type;
- }
-
- QPaintEngine::Type preferredPaintEngine() {
-#ifdef Q_WS_MAC
- // The ATI X1600 driver for Mac OS X does not support return
- // values from functions in GLSL. Since working around this in
- // the GL2 engine would require a big, ugly rewrite, we're
- // falling back to the GL 1 engine..
- static bool mac_x1600_check_done = false;
- if (!mac_x1600_check_done) {
- QGLTemporaryContext *tmp = 0;
- if (!QGLContext::currentContext())
- tmp = new QGLTemporaryContext();
- if (strstr((char *) glGetString(GL_RENDERER), "X1600"))
- engineType = QPaintEngine::OpenGL;
- if (tmp)
- delete tmp;
- mac_x1600_check_done = true;
- }
-#endif
- if (engineType == QPaintEngine::MaxUser) {
- // No user-set engine - use the defaults
-#if defined(QT_OPENGL_ES_2)
- engineType = QPaintEngine::OpenGL2;
-#else
- // We can't do this in the constructor for this object because it
- // needs to be called *before* the QApplication constructor.
- // Also check for the FragmentShader extension in conjunction with
- // the 2.0 version flag, to cover the case where we export the display
- // from an old GL 1.1 server to a GL 2.x client. In that case we can't
- // use GL 2.0.
- if ((QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_2_0)
- && (QGLExtensions::glExtensions() & QGLExtensions::FragmentShader)
- && qgetenv("QT_GL_USE_OPENGL1ENGINE").isEmpty())
- engineType = QPaintEngine::OpenGL2;
- else
- engineType = QPaintEngine::OpenGL;
-#endif
- }
- return engineType;
- }
-
-private:
- QPaintEngine::Type engineType;
-};
-
-Q_GLOBAL_STATIC(QGLEngineSelector, qgl_engine_selector)
-
-
-bool qt_gl_preferGL2Engine()
-{
- return qgl_engine_selector()->preferredPaintEngine() == QPaintEngine::OpenGL2;
-}
-
-
/*!
\namespace QGL
\inmodule QtOpenGL
@@ -266,32 +155,6 @@ bool qt_gl_preferGL2Engine()
\sa {Sample Buffers Example}
*/
-/*!
- \fn void QGL::setPreferredPaintEngine(QPaintEngine::Type engineType)
-
- \since 4.6
-
- Sets the preferred OpenGL paint engine that is used to draw onto
- QGLWidget, QGLPixelBuffer and QGLFramebufferObject targets with QPainter
- in Qt.
-
- The \a engineType parameter specifies which of the GL engines to
- use. Only \c QPaintEngine::OpenGL and \c QPaintEngine::OpenGL2 are
- valid parameters to this function. All other values are ignored.
-
- By default, the \c QPaintEngine::OpenGL2 engine is used if GL/GLES
- version 2.0 is available, otherwise \c QPaintEngine::OpenGL is
- used.
-
- \warning This function must be called before the QApplication
- constructor is called.
-*/
-void QGL::setPreferredPaintEngine(QPaintEngine::Type engineType)
-{
- qgl_engine_selector()->setPreferredPaintEngine(engineType);
-}
-
-
/*****************************************************************************
QGLFormat implementation
*****************************************************************************/
@@ -1613,42 +1476,16 @@ Q_GLOBAL_STATIC(QGLContextGroupList, qt_context_groups)
*****************************************************************************/
QGLContextGroup::QGLContextGroup(const QGLContext *context)
- : m_context(context), m_guards(0), m_refs(1)
+ : m_context(context), m_refs(1)
{
qt_context_groups()->append(this);
}
QGLContextGroup::~QGLContextGroup()
{
- // Clear any remaining QGLSharedResourceGuard objects on the group.
- QGLSharedResourceGuard *guard = m_guards;
- while (guard != 0) {
- guard->m_group = 0;
- guard->m_id = 0;
- guard = guard->m_next;
- }
qt_context_groups()->remove(this);
}
-void QGLContextGroup::addGuard(QGLSharedResourceGuard *guard)
-{
- if (m_guards)
- m_guards->m_prev = guard;
- guard->m_next = m_guards;
- guard->m_prev = 0;
- m_guards = guard;
-}
-
-void QGLContextGroup::removeGuard(QGLSharedResourceGuard *guard)
-{
- if (guard->m_next)
- guard->m_next->m_prev = guard->m_prev;
- if (guard->m_prev)
- guard->m_prev->m_next = guard->m_next;
- else
- m_guards = guard->m_next;
-}
-
const QGLContext *qt_gl_transfer_context(const QGLContext *ctx)
{
if (!ctx)
@@ -1664,11 +1501,15 @@ const QGLContext *qt_gl_transfer_context(const QGLContext *ctx)
QGLContextPrivate::QGLContextPrivate(QGLContext *context)
: internal_context(false)
, q_ptr(context)
+ , texture_destroyer(0)
, functions(0)
{
group = new QGLContextGroup(context);
- texture_destroyer = new QGLTextureDestroyer;
- texture_destroyer->moveToThread(qApp->thread());
+
+ if (qApp) {
+ texture_destroyer = new QGLTextureDestroyer;
+ texture_destroyer->moveToThread(qApp->thread());
+ }
}
QGLContextPrivate::~QGLContextPrivate()
@@ -1689,35 +1530,9 @@ void QGLContextPrivate::init(QPaintDevice *dev, const QGLFormat &format)
glFormat = reqFormat = format;
valid = false;
q->setDevice(dev);
-#if defined(Q_WS_X11)
- pbuf = 0;
- gpm = 0;
- vi = 0;
- screen = QX11Info::appScreen();
-#endif
-#if defined(Q_WS_WIN)
- dc = 0;
- win = 0;
- threadId = 0;
- pixelFormatId = 0;
- cmap = 0;
- hbitmap = 0;
- hbitmap_hdc = 0;
-#endif
-#if defined(Q_WS_MAC)
-# ifndef QT_MAC_USE_COCOA
- update = false;
-# endif
- vi = 0;
-#endif
-#if defined(Q_WS_QPA)
- platformContext = 0;
-#endif
-#if !defined(QT_NO_EGL)
- ownsEglContext = false;
- eglContext = 0;
- eglSurface = EGL_NO_SURFACE;
-#endif
+
+ guiGlContext = 0;
+ ownContext = false;
fbo = 0;
crWin = false;
initDone = false;
@@ -1795,7 +1610,7 @@ static void convertFromGLImage(QImage &img, int w, int h, bool alpha_format, boo
img = img.mirrored();
}
-Q_OPENGL_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include_alpha)
+QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include_alpha)
{
QImage img(size, (alpha_format && include_alpha) ? QImage::Format_ARGB32_Premultiplied
: QImage::Format_RGB32);
@@ -1811,7 +1626,7 @@ QImage qt_gl_read_texture(const QSize &size, bool alpha_format, bool include_alp
QImage img(size, alpha_format ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32);
int w = size.width();
int h = size.height();
-#if !defined(QT_OPENGL_ES_2) && !defined(QT_OPENGL_ES_1)
+#if !defined(QT_OPENGL_ES_2)
//### glGetTexImage not in GL ES 2.0, need to do something else here!
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, img.bits());
#endif
@@ -1845,15 +1660,15 @@ Q_GLOBAL_STATIC(QGLTextureCache, qt_gl_texture_cache)
QGLTextureCache::QGLTextureCache()
: m_cache(64*1024) // cache ~64 MB worth of textures - this is not accurate though
{
- QImagePixmapCleanupHooks::instance()->addPixmapDataModificationHook(cleanupTexturesForPixampData);
- QImagePixmapCleanupHooks::instance()->addPixmapDataDestructionHook(cleanupBeforePixmapDestruction);
+ QImagePixmapCleanupHooks::instance()->addPlatformPixmapModificationHook(cleanupTexturesForPixampData);
+ QImagePixmapCleanupHooks::instance()->addPlatformPixmapDestructionHook(cleanupBeforePixmapDestruction);
QImagePixmapCleanupHooks::instance()->addImageHook(cleanupTexturesForCacheKey);
}
QGLTextureCache::~QGLTextureCache()
{
- QImagePixmapCleanupHooks::instance()->removePixmapDataModificationHook(cleanupTexturesForPixampData);
- QImagePixmapCleanupHooks::instance()->removePixmapDataDestructionHook(cleanupBeforePixmapDestruction);
+ QImagePixmapCleanupHooks::instance()->removePlatformPixmapModificationHook(cleanupTexturesForPixampData);
+ QImagePixmapCleanupHooks::instance()->removePlatformPixmapDestructionHook(cleanupBeforePixmapDestruction);
QImagePixmapCleanupHooks::instance()->removeImageHook(cleanupTexturesForCacheKey);
}
@@ -1912,22 +1727,15 @@ void QGLTextureCache::cleanupTexturesForCacheKey(qint64 cacheKey)
}
-void QGLTextureCache::cleanupTexturesForPixampData(QPixmapData* pmd)
+void QGLTextureCache::cleanupTexturesForPixampData(QPlatformPixmap* pmd)
{
cleanupTexturesForCacheKey(pmd->cacheKey());
}
-void QGLTextureCache::cleanupBeforePixmapDestruction(QPixmapData* pmd)
+void QGLTextureCache::cleanupBeforePixmapDestruction(QPlatformPixmap* pmd)
{
// Remove any bound textures first:
cleanupTexturesForPixampData(pmd);
-
-#if defined(Q_WS_X11)
- if (pmd->classId() == QPixmapData::X11Class) {
- Q_ASSERT(pmd->ref == 0); // Make sure reference counting isn't broken
- QGLContextPrivate::destroyGlSurfaceForPixmap(pmd);
- }
-#endif
}
QGLTextureCache *QGLTextureCache::instance()
@@ -2105,8 +1913,6 @@ QGLContext::~QGLContext()
// clean up resources specific to this context
d_ptr->cleanup();
- // clean up resources belonging to this context's group
- d_ptr->group->cleanupResources(this);
QGLSignalProxy::instance()->emitAboutToDestroyContext(this);
reset();
@@ -2114,10 +1920,6 @@ QGLContext::~QGLContext()
void QGLContextPrivate::cleanup()
{
- QHash<QGLContextResourceBase *, void *>::ConstIterator it;
- for (it = m_resources.begin(); it != m_resources.end(); ++it)
- it.key()->freeResource(it.value());
- m_resources.clear();
}
#define ctx q_ptr
@@ -2152,13 +1954,11 @@ void QGLContextPrivate::syncGlState()
}
#undef ctx
-#ifdef QT_NO_EGL
void QGLContextPrivate::swapRegion(const QRegion &)
{
Q_Q(QGLContext);
q->swapBuffers();
}
-#endif
/*!
\overload
@@ -2303,12 +2103,10 @@ static void convertToGLFormatHelper(QImage &dst, const QImage &img, GLenum textu
}
}
-#if defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QWS) || defined(Q_WS_QPA) || defined(Q_OS_SYMBIAN)
QGLExtensionFuncs& QGLContextPrivate::extensionFuncs(const QGLContext *)
{
return qt_extensionFuncs;
}
-#endif
QImage QGLContextPrivate::convertToGLFormat(const QImage &image, bool force_premul,
GLenum texture_format)
@@ -2547,18 +2345,8 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G
#endif
const QImage &constRef = img; // to avoid detach in bits()...
-#ifdef QGL_USE_TEXTURE_POOL
- QGLTexturePool::instance()->createPermanentTexture(tx_id,
- target,
- 0, internalFormat,
- img.width(), img.height(),
- externalFormat,
- pixel_type,
- constRef.bits());
-#else
glTexImage2D(target, 0, internalFormat, img.width(), img.height(), 0, externalFormat,
pixel_type, constRef.bits());
-#endif
#if defined(QT_OPENGL_ES_2)
if (genMipmap)
glGenerateMipmap(target);
@@ -2601,19 +2389,8 @@ QGLTexture *QGLContextPrivate::textureCacheLookup(const qint64 key, GLenum targe
QGLTexture *QGLContextPrivate::bindTexture(const QPixmap &pixmap, GLenum target, GLint format, QGLContext::BindOptions options)
{
Q_Q(QGLContext);
- QPixmapData *pd = pixmap.pixmapData();
-#if !defined(QT_OPENGL_ES_1)
- if (target == GL_TEXTURE_2D && pd->classId() == QPixmapData::OpenGLClass) {
- const QGLPixmapData *data = static_cast<const QGLPixmapData *>(pd);
-
- if (data->isValidContext(q)) {
- data->bind();
- return data->texture();
- }
- }
-#else
+ QPlatformPixmap *pd = pixmap.handle();
Q_UNUSED(pd);
-#endif
const qint64 key = pixmap.cacheKey();
QGLTexture *texture = textureCacheLookup(key, target);
@@ -2628,39 +2405,6 @@ QGLTexture *QGLContextPrivate::bindTexture(const QPixmap &pixmap, GLenum target,
}
}
-#if defined(Q_WS_X11)
- // Try to use texture_from_pixmap
- const QX11Info *xinfo = qt_x11Info(paintDevice);
- if (pd->classId() == QPixmapData::X11Class && pd->pixelType() == QPixmapData::PixmapType
- && xinfo && xinfo->screen() == pixmap.x11Info().screen()
- && target == GL_TEXTURE_2D
- && QApplication::instance()->thread() == QThread::currentThread())
- {
- if (!workaround_brokenTextureFromPixmap_init) {
- workaround_brokenTextureFromPixmap_init = true;
-
- const QByteArray versionString(reinterpret_cast<const char*>(glGetString(GL_VERSION)));
- const int pos = versionString.indexOf("NVIDIA ");
-
- if (pos >= 0) {
- const QByteArray nvidiaVersionString = versionString.mid(pos + strlen("NVIDIA "));
-
- if (nvidiaVersionString.startsWith("195") || nvidiaVersionString.startsWith("256"))
- workaround_brokenTextureFromPixmap = true;
- }
- }
-
- if (!workaround_brokenTextureFromPixmap) {
- texture = bindTextureFromNativePixmap(const_cast<QPixmap*>(&pixmap), key, options);
- if (texture) {
- texture->options |= QGLContext::MemoryManagedBindOption;
- texture->boundPixmap = pd;
- boundPixmaps.insert(pd, QPixmap(pixmap));
- }
- }
- }
-#endif
-
if (!texture) {
QImage image = pixmap.toImage();
// If the system depth is 16 and the pixmap doesn't have an alpha channel
@@ -2779,31 +2523,6 @@ GLuint QGLContext::bindTexture(const QImage &image, GLenum target, GLint format,
return texture->id;
}
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
-/*! \internal */
-GLuint QGLContext::bindTexture(const QImage &image, QMacCompatGLenum target, QMacCompatGLint format)
-{
- if (image.isNull())
- return 0;
-
- Q_D(QGLContext);
- QGLTexture *texture = d->bindTexture(image, GLenum(target), GLint(format), DefaultBindOption);
- return texture->id;
-}
-
-/*! \internal */
-GLuint QGLContext::bindTexture(const QImage &image, QMacCompatGLenum target, QMacCompatGLint format,
- BindOptions options)
-{
- if (image.isNull())
- return 0;
-
- Q_D(QGLContext);
- QGLTexture *texture = d->bindTexture(image, GLenum(target), GLint(format), options);
- return texture->id;
-}
-#endif
-
/*! \overload
Generates and binds a 2D GL texture based on \a pixmap.
@@ -2835,30 +2554,6 @@ GLuint QGLContext::bindTexture(const QPixmap &pixmap, GLenum target, GLint forma
return texture->id;
}
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
-/*! \internal */
-GLuint QGLContext::bindTexture(const QPixmap &pixmap, QMacCompatGLenum target, QMacCompatGLint format)
-{
- if (pixmap.isNull())
- return 0;
-
- Q_D(QGLContext);
- QGLTexture *texture = d->bindTexture(pixmap, GLenum(target), GLint(format), DefaultBindOption);
- return texture->id;
-}
-/*! \internal */
-GLuint QGLContext::bindTexture(const QPixmap &pixmap, QMacCompatGLenum target, QMacCompatGLint format,
- BindOptions options)
-{
- if (pixmap.isNull())
- return 0;
-
- Q_D(QGLContext);
- QGLTexture *texture = d->bindTexture(pixmap, GLenum(target), GLint(format), options);
- return texture->id;
-}
-#endif
-
/*!
Removes the texture identified by \a id from the texture cache,
and calls glDeleteTextures() to delete the texture from the
@@ -2873,14 +2568,6 @@ void QGLContext::deleteTexture(GLuint id)
glDeleteTextures(1, &id);
}
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
-/*! \internal */
-void QGLContext::deleteTexture(QMacCompatGLuint id)
-{
- return deleteTexture(GLuint(id));
-}
-#endif
-
void qt_add_rect_to_array(const QRectF &r, GLfloat *array)
{
qreal left = r.left();
@@ -3020,14 +2707,6 @@ void QGLContext::drawTexture(const QRectF &target, GLuint textureId, GLenum text
#endif
}
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
-/*! \internal */
-void QGLContext::drawTexture(const QRectF &target, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget)
-{
- drawTexture(target, GLuint(textureId), GLenum(textureTarget));
-}
-#endif
-
/*!
\since 4.4
@@ -3091,15 +2770,6 @@ void QGLContext::drawTexture(const QPointF &point, GLuint textureId, GLenum text
#endif
}
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
-/*! \internal */
-void QGLContext::drawTexture(const QPointF &point, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget)
-{
- drawTexture(point, GLuint(textureId), GLenum(textureTarget));
-}
-#endif
-
-
/*!
This function sets the limit for the texture cache to \a size,
expressed in kilobytes.
@@ -3329,11 +2999,7 @@ bool QGLContext::areSharing(const QGLContext *context1, const QGLContext *contex
bool QGLContext::create(const QGLContext* shareContext)
{
Q_D(QGLContext);
-#ifdef Q_WS_QPA
- if (!d->paintDevice && !d->platformContext)
-#else
- if (!d->paintDevice)
-#endif
+ if (!d->paintDevice && !d->guiGlContext)
return false;
reset();
@@ -3342,10 +3008,6 @@ bool QGLContext::create(const QGLContext* shareContext)
QWidgetPrivate *wd = qt_widget_private(static_cast<QWidget *>(d->paintDevice));
wd->usesDoubleBufferedGLContext = d->glFormat.doubleBuffer();
}
-#ifndef Q_WS_QPA //We do this in choose context->setupSharing()
- if (d->sharing) // ok, we managed to share
- QGLContextGroup::addShare(this, shareContext);
-#endif
return d->valid;
}
@@ -3419,37 +3081,15 @@ void QGLContext::setInitialized(bool on)
const QGLContext* QGLContext::currentContext()
{
-#ifdef Q_WS_QPA
- if (const QPlatformGLContext *threadContext = QPlatformGLContext::currentContext()) {
- return QGLContext::fromPlatformGLContext(const_cast<QPlatformGLContext *>(threadContext));
+ if (const QOpenGLContext *threadContext = QOpenGLContext::currentContext()) {
+ return QGLContext::fromOpenGLContext(const_cast<QOpenGLContext *>(threadContext));
}
return 0;
-#else
- QGLThreadContext *threadContext = qgl_context_storage.localData();
- if (threadContext)
- return threadContext->context;
- return 0;
-#endif //Q_WS_QPA
}
void QGLContextPrivate::setCurrentContext(QGLContext *context)
{
-#ifdef Q_WS_QPA
Q_UNUSED(context);
-#else
- QGLThreadContext *threadContext = qgl_context_storage.localData();
- if (!threadContext) {
- if (!QThread::currentThread()) {
- // We don't have a current QThread, so just set the static.
- QGLContext::currentCtx = context;
- return;
- }
- threadContext = new QGLThreadContext;
- qgl_context_storage.setLocalData(threadContext);
- }
- threadContext->context = context;
- QGLContext::currentCtx = context; // XXX: backwards-compat, not thread-safe
-#endif
}
/*!
@@ -3761,11 +3401,6 @@ void QGLContextPrivate::setCurrentContext(QGLContext *context)
on a QGLWidget and the widget's rendering context is current in
another thread, it will fail.
- Note that under X11 it is necessary to set the
- Qt::AA_X11InitThreads application attribute to make the X11
- library and GLX calls thread safe, otherwise the above scenarios
- will fail.
-
In addition to this, rendering using raw GL calls in a separate
thread is supported.
@@ -3906,30 +3541,9 @@ QGLWidget::QGLWidget(QGLContext *context, QWidget *parent, const QGLWidget *shar
QGLWidget::~QGLWidget()
{
Q_D(QGLWidget);
-#if defined(GLX_MESA_release_buffers) && defined(QGL_USE_MESA_EXT)
- bool doRelease = (glcx && glcx->windowCreated());
-#endif
delete d->glcx;
d->glcx = 0;
-#if defined(Q_WS_WIN)
- delete d->olcx;
- d->olcx = 0;
-#endif
-#if defined(GLX_MESA_release_buffers) && defined(QGL_USE_MESA_EXT)
- if (doRelease)
- glXReleaseBuffersMESA(x11Display(), winId());
-#endif
d->cleanupColormaps();
-
-#ifdef Q_WS_MAC
- QWidget *current = parentWidget();
- while (current) {
- qt_widget_private(current)->glWidgets.removeAll(QWidgetPrivate::GlWidgetInfo(this));
- if (current->isWindow())
- break;
- current = current->parentWidget();
- };
-#endif
}
/*!
@@ -4275,125 +3889,6 @@ void QGLWidget::resizeOverlayGL(int, int)
{
}
-/*! \fn bool QGLWidget::event(QEvent *e)
- \reimp
-*/
-#if !defined(Q_OS_WINCE) && !defined(Q_WS_QWS) && !defined(Q_WS_QPA)
-bool QGLWidget::event(QEvent *e)
-{
- Q_D(QGLWidget);
-
- if (e->type() == QEvent::Paint) {
- QPoint offset;
- QPaintDevice *redirectedDevice = d->redirected(&offset);
- if (redirectedDevice && redirectedDevice->devType() == QInternal::Pixmap) {
- d->restoreRedirected();
- QPixmap pixmap = renderPixmap();
- d->setRedirected(redirectedDevice, offset);
- QPainter p(redirectedDevice);
- p.drawPixmap(-offset, pixmap);
- return true;
- }
- }
-
-#if defined(Q_WS_X11)
- if (e->type() == QEvent::ParentChange) {
- // if we've reparented a window that has the current context
- // bound, we need to rebind that context to the new window id
- if (d->glcx == QGLContext::currentContext())
- makeCurrent();
-
- if (d->glcx->d_func()->screen != d->xinfo.screen() || testAttribute(Qt::WA_TranslucentBackground)) {
- setContext(new QGLContext(d->glcx->requestedFormat(), this));
- // ### recreating the overlay isn't supported atm
- }
- }
-
-#ifndef QT_NO_EGL
- // A re-parent is likely to destroy the X11 window and re-create it. It is important
- // that we free the EGL surface _before_ the winID changes - otherwise we can leak.
- if (e->type() == QEvent::ParentAboutToChange)
- d->glcx->d_func()->destroyEglSurfaceForDevice();
-
- if ((e->type() == QEvent::ParentChange) || (e->type() == QEvent::WindowStateChange)) {
- // The window may have been re-created during re-parent or state change - if so, the EGL
- // surface will need to be re-created.
- d->recreateEglSurface();
- }
-#endif
-#elif defined(Q_WS_WIN)
- if (e->type() == QEvent::ParentChange) {
- QGLContext *newContext = new QGLContext(d->glcx->requestedFormat(), this);
- setContext(newContext, d->glcx);
-
- // the overlay needs to be recreated as well
- delete d->olcx;
- if (isValid() && context()->format().hasOverlay()) {
- d->olcx = new QGLContext(QGLFormat::defaultOverlayFormat(), this);
- if (!d->olcx->create(isSharing() ? d->glcx : 0)) {
- delete d->olcx;
- d->olcx = 0;
- d->glcx->d_func()->glFormat.setOverlay(false);
- }
- } else {
- d->olcx = 0;
- }
- } else if (e->type() == QEvent::Show) {
- if (!format().rgba())
- d->updateColormap();
- }
-#elif defined(Q_WS_MAC)
- if (e->type() == QEvent::MacGLWindowChange
-#if 0 //(MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
- && ((QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5 && isWindow())
- || QSysInfo::MacintoshVersion <= QSysInfo::MV_10_4)
-#endif
- ) {
- if (d->needWindowChange) {
- d->needWindowChange = false;
- d->glcx->updatePaintDevice();
- update();
- }
- return true;
-# if defined(QT_MAC_USE_COCOA)
- } else if (e->type() == QEvent::MacGLClearDrawable) {
- d->glcx->d_ptr->clearDrawable();
-# endif
- }
-#elif defined(Q_OS_SYMBIAN)
- // prevents errors on some systems, where we get a flush to a
- // hidden widget
- if (e->type() == QEvent::Hide) {
- makeCurrent();
- glFinish();
- doneCurrent();
- } else if (e->type() == QEvent::ParentChange) {
- // if we've reparented a window that has the current context
- // bound, we need to rebind that context to the new window id
- if (d->glcx == QGLContext::currentContext())
- makeCurrent();
-
- if (testAttribute(Qt::WA_TranslucentBackground))
- setContext(new QGLContext(d->glcx->requestedFormat(), this));
- }
-
- // A re-parent is likely to destroy the Symbian window and re-create it. It is important
- // that we free the EGL surface _before_ the winID changes - otherwise we can leak.
- if (e->type() == QEvent::ParentAboutToChange)
- d->glcx->d_func()->destroyEglSurfaceForDevice();
-
- if ((e->type() == QEvent::ParentChange) || (e->type() == QEvent::WindowStateChange)) {
- // The window may have been re-created during re-parent or state change - if so, the EGL
- // surface will need to be re-created.
- d->recreateEglSurface();
- }
-
-#endif
-
- return QWidget::event(e);
-}
-#endif
-
/*!
\fn void QGLWidget::paintEvent(QPaintEvent *event)
@@ -4467,28 +3962,7 @@ QPixmap QGLWidget::renderPixmap(int w, int h, bool useContext)
if ((w > 0) && (h > 0))
sz = QSize(w, h);
-#if defined(Q_WS_X11)
- extern int qt_x11_preferred_pixmap_depth;
- int old_depth = qt_x11_preferred_pixmap_depth;
- qt_x11_preferred_pixmap_depth = x11Info().depth();
-
- QPixmapData *data = new QX11PixmapData(QPixmapData::PixmapType);
- data->resize(sz.width(), sz.height());
- QPixmap pm(data);
- qt_x11_preferred_pixmap_depth = old_depth;
- QX11Info xinfo = x11Info();
-
- // make sure we use a pixmap with the same depth/visual as the widget
- if (xinfo.visual() != QX11Info::appVisual()) {
- QX11InfoData* xd = pm.x11Info().getX11Data(true);
- xd->depth = xinfo.depth();
- xd->visual = static_cast<Visual *>(xinfo.visual());
- const_cast<QX11Info &>(pm.x11Info()).setX11Data(xd);
- }
-
-#else
QPixmap pm(sz);
-#endif
d->glcx->doneCurrent();
@@ -4500,9 +3974,6 @@ QPixmap QGLWidget::renderPixmap(int w, int h, bool useContext)
QGLFormat fmt = d->glcx->requestedFormat();
fmt.setDirectRendering(false); // Direct is unlikely to work
fmt.setDoubleBuffer(false); // We don't need dbl buf
-#ifdef Q_WS_MAC // crash prevention on the Mac - it's unlikely to work anyway
- fmt.setSampleBuffers(false);
-#endif
QGLContext* ocx = d->glcx;
ocx->doneCurrent();
@@ -4520,13 +3991,6 @@ QPixmap QGLWidget::renderPixmap(int w, int h, bool useContext)
ocx->makeCurrent();
if (success) {
-#if defined(Q_WS_X11)
- if (xinfo.visual() != QX11Info::appVisual()) {
- QImage image = pm.toImage();
- QPixmap p = QPixmap::fromImage(image);
- return p;
- }
-#endif
return pm;
}
return QPixmap();
@@ -4546,21 +4010,8 @@ QImage QGLWidget::grabFrameBuffer(bool withAlpha)
QImage res;
int w = width();
int h = height();
- if (format().rgba()) {
+ if (format().rgba())
res = qt_gl_read_framebuffer(QSize(w, h), format().alpha(), withAlpha);
- } else {
-#if defined (Q_WS_WIN) && !defined(QT_OPENGL_ES)
- res = QImage(w, h, QImage::Format_Indexed8);
- glReadPixels(0, 0, w, h, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, res.bits());
- const QVector<QColor> pal = QColormap::instance().colormap();
- if (pal.size()) {
- res.setColorCount(pal.size());
- for (int i = 0; i < pal.size(); i++)
- res.setColor(i, pal.at(i).rgb());
- }
- res = res.mirrored();
-#endif
- }
return res;
}
@@ -4595,11 +4046,6 @@ void QGLWidget::glDraw()
Q_D(QGLWidget);
if (!isValid())
return;
-#ifdef Q_OS_SYMBIAN
- // Crashes on Symbian if trying to render to invisible surfaces
- if (!isVisible() && d->glcx->device()->devType() == QInternal::Widget)
- return;
-#endif
makeCurrent();
#ifndef QT_OPENGL_ES
if (d->glcx->deviceIsPixmap())
@@ -4918,18 +4364,13 @@ void QGLWidget::renderText(int x, int y, const QString &str, const QFont &font,
int height = d->glcx->device()->height();
bool auto_swap = autoBufferSwap();
- QPaintEngine::Type oldEngineType = qgl_engine_selector()->preferredPaintEngine();
-
QPaintEngine *engine = paintEngine();
- if (engine && (oldEngineType == QPaintEngine::OpenGL2) && engine->isActive()) {
+ if (engine && engine->isActive()) {
qWarning("QGLWidget::renderText(): Calling renderText() while a GL 2 paint engine is"
" active on the same device is not allowed.");
return;
}
- // this changes what paintEngine() returns
- qgl_engine_selector()->setPreferredPaintEngine(QPaintEngine::OpenGL);
- engine = paintEngine();
QPainter *p;
bool reuse_painter = false;
if (engine->isActive()) {
@@ -4973,7 +4414,6 @@ void QGLWidget::renderText(int x, int y, const QString &str, const QFont &font,
setAutoBufferSwap(auto_swap);
d->disable_clear_on_painter_begin = false;
}
- qgl_engine_selector()->setPreferredPaintEngine(oldEngineType);
#else // QT_OPENGL_ES
Q_UNUSED(x);
Q_UNUSED(y);
@@ -5021,18 +4461,14 @@ void QGLWidget::renderText(double x, double y, double z, const QString &str, con
&win_x, &win_y, &win_z);
win_y = height - win_y; // y is inverted
- QPaintEngine::Type oldEngineType = qgl_engine_selector()->preferredPaintEngine();
QPaintEngine *engine = paintEngine();
- if (engine && (oldEngineType == QPaintEngine::OpenGL2) && engine->isActive()) {
+ if (engine && engine->isActive()) {
qWarning("QGLWidget::renderText(): Calling renderText() while a GL 2 paint engine is"
" active on the same device is not allowed.");
return;
}
- // this changes what paintEngine() returns
- qgl_engine_selector()->setPreferredPaintEngine(QPaintEngine::OpenGL);
- engine = paintEngine();
QPainter *p;
bool reuse_painter = false;
bool use_depth_testing = glIsEnabled(GL_DEPTH_TEST);
@@ -5077,7 +4513,6 @@ void QGLWidget::renderText(double x, double y, double z, const QString &str, con
setAutoBufferSwap(auto_swap);
d->disable_clear_on_painter_begin = false;
}
- qgl_engine_selector()->setPreferredPaintEngine(oldEngineType);
#else // QT_OPENGL_ES
Q_UNUSED(x);
Q_UNUSED(y);
@@ -5150,28 +4585,6 @@ GLuint QGLWidget::bindTexture(const QImage &image, GLenum target, GLint format,
}
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
-/*! \internal */
-GLuint QGLWidget::bindTexture(const QImage &image, QMacCompatGLenum target, QMacCompatGLint format)
-{
- if (image.isNull())
- return 0;
-
- Q_D(QGLWidget);
- return d->glcx->bindTexture(image, GLenum(target), GLint(format), QGLContext::DefaultBindOption);
-}
-
-GLuint QGLWidget::bindTexture(const QImage &image, QMacCompatGLenum target, QMacCompatGLint format,
- QGLContext::BindOptions options)
-{
- if (image.isNull())
- return 0;
-
- Q_D(QGLWidget);
- return d->glcx->bindTexture(image, GLenum(target), GLint(format), options);
-}
-#endif
-
/*!
Calls QGLContext:::bindTexture(\a pixmap, \a target, \a format) on the currently
set context.
@@ -5204,23 +4617,6 @@ GLuint QGLWidget::bindTexture(const QPixmap &pixmap, GLenum target, GLint format
return d->glcx->bindTexture(pixmap, target, format, options);
}
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
-/*! \internal */
-GLuint QGLWidget::bindTexture(const QPixmap &pixmap, QMacCompatGLenum target, QMacCompatGLint format)
-{
- Q_D(QGLWidget);
- return d->glcx->bindTexture(pixmap, target, format, QGLContext::DefaultBindOption);
-}
-
-GLuint QGLWidget::bindTexture(const QPixmap &pixmap, QMacCompatGLenum target, QMacCompatGLint format,
- QGLContext::BindOptions options)
-{
- Q_D(QGLWidget);
- return d->glcx->bindTexture(pixmap, target, format, options);
-}
-#endif
-
-
/*! \overload
Calls QGLContext::bindTexture(\a fileName) on the currently set context.
@@ -5245,15 +4641,6 @@ void QGLWidget::deleteTexture(GLuint id)
d->glcx->deleteTexture(id);
}
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
-/*! \internal */
-void QGLWidget::deleteTexture(QMacCompatGLuint id)
-{
- Q_D(QGLWidget);
- d->glcx->deleteTexture(GLuint(id));
-}
-#endif
-
/*!
\since 4.4
@@ -5267,15 +4654,6 @@ void QGLWidget::drawTexture(const QRectF &target, GLuint textureId, GLenum textu
d->glcx->drawTexture(target, textureId, textureTarget);
}
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
-/*! \internal */
-void QGLWidget::drawTexture(const QRectF &target, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget)
-{
- Q_D(QGLWidget);
- d->glcx->drawTexture(target, GLint(textureId), GLenum(textureTarget));
-}
-#endif
-
/*!
\since 4.4
@@ -5289,42 +4667,17 @@ void QGLWidget::drawTexture(const QPointF &point, GLuint textureId, GLenum textu
d->glcx->drawTexture(point, textureId, textureTarget);
}
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
-/*! \internal */
-void QGLWidget::drawTexture(const QPointF &point, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget)
-{
- Q_D(QGLWidget);
- d->glcx->drawTexture(point, GLuint(textureId), GLenum(textureTarget));
-}
-#endif
-
-#ifndef QT_OPENGL_ES_1
Q_GLOBAL_STATIC(QGLEngineThreadStorage<QGL2PaintEngineEx>, qt_gl_2_engine)
-#endif
-
-#ifndef QT_OPENGL_ES_2
-Q_GLOBAL_STATIC(QGLEngineThreadStorage<QOpenGLPaintEngine>, qt_gl_engine)
-#endif
-Q_OPENGL_EXPORT QPaintEngine* qt_qgl_paint_engine()
+QPaintEngine* qt_qgl_paint_engine()
{
-#if defined(QT_OPENGL_ES_1)
- return qt_gl_engine()->engine();
-#elif defined(QT_OPENGL_ES_2)
return qt_gl_2_engine()->engine();
-#else
- if (qt_gl_preferGL2Engine())
- return qt_gl_2_engine()->engine();
- else
- return qt_gl_engine()->engine();
-#endif
}
/*!
\internal
- Returns the GL widget's paint engine. This is normally a
- QOpenGLPaintEngine.
+ Returns the GL widget's paint engine.
*/
QPaintEngine *QGLWidget::paintEngine() const
{
@@ -5492,10 +4845,6 @@ QGLExtensions::Extensions QGLExtensions::currentContextExtensions()
glExtensions |= GenerateMipmap;
glExtensions |= FragmentShader;
#endif
-#if defined(QT_OPENGL_ES_1)
- if (extensions.match("GL_OES_framebuffer_object"))
- glExtensions |= FramebufferObject;
-#endif
#if defined(QT_OPENGL_ES)
if (extensions.match("GL_OES_packed_depth_stencil"))
glExtensions |= PackedDepthStencil;
@@ -5588,32 +4937,24 @@ void QGLWidgetPrivate::initContext(QGLContext *context, const QGLWidget* shareWi
glcx = new QGLContext(QGLFormat::defaultFormat(), q);
}
-#if defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QWS) || defined(Q_WS_QPA)
Q_GLOBAL_STATIC(QString, qt_gl_lib_name)
-Q_OPENGL_EXPORT void qt_set_gl_library_name(const QString& name)
+void qt_set_gl_library_name(const QString& name)
{
qt_gl_lib_name()->operator=(name);
}
-Q_OPENGL_EXPORT const QString qt_gl_library_name()
+const QString qt_gl_library_name()
{
if (qt_gl_lib_name()->isNull()) {
-#ifdef Q_WS_MAC
- return QLatin1String("/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib");
-#else
-# if defined(QT_OPENGL_ES_1)
- return QLatin1String("GLES_CM");
-# elif defined(QT_OPENGL_ES_2)
+# if defined(QT_OPENGL_ES_2)
return QLatin1String("GLESv2");
# else
return QLatin1String("GL");
# endif
-#endif // defined Q_WS_MAC
}
return *qt_gl_lib_name();
}
-#endif
void QGLContextGroup::addShare(const QGLContext *context, const QGLContext *share) {
Q_ASSERT(context && share);
@@ -5653,108 +4994,6 @@ void QGLContextGroup::removeShare(const QGLContext *context) {
group->m_shares.clear();
}
-QGLContextGroupResourceBase::QGLContextGroupResourceBase()
- : active(0)
-{
-#ifdef QT_GL_CONTEXT_RESOURCE_DEBUG
- qDebug("Creating context group resource object %p.", this);
-#endif
-}
-
-QGLContextGroupResourceBase::~QGLContextGroupResourceBase()
-{
-#ifdef QT_GL_CONTEXT_RESOURCE_DEBUG
- qDebug("Deleting context group resource %p. Group size: %d.", this, m_groups.size());
-#endif
- for (int i = 0; i < m_groups.size(); ++i) {
- m_groups.at(i)->m_resources.remove(this);
- active.deref();
- }
-#ifndef QT_NO_DEBUG
- if (active != 0) {
- qWarning("QtOpenGL: Resources are still available at program shutdown.\n"
- " This is possibly caused by a leaked QGLWidget, \n"
- " QGLFramebufferObject or QGLPixelBuffer.");
- }
-#endif
-}
-
-void QGLContextGroupResourceBase::insert(const QGLContext *context, void *value)
-{
-#ifdef QT_GL_CONTEXT_RESOURCE_DEBUG
- qDebug("Inserting context group resource %p for context %p, managed by %p.", value, context, this);
-#endif
- QGLContextGroup *group = QGLContextPrivate::contextGroup(context);
- Q_ASSERT(!group->m_resources.contains(this));
- group->m_resources.insert(this, value);
- m_groups.append(group);
- active.ref();
-}
-
-void *QGLContextGroupResourceBase::value(const QGLContext *context)
-{
- QGLContextGroup *group = QGLContextPrivate::contextGroup(context);
- return group->m_resources.value(this, 0);
-}
-
-void QGLContextGroupResourceBase::cleanup(const QGLContext *ctx)
-{
- void *resource = value(ctx);
-
- if (resource != 0) {
- QGLShareContextScope scope(ctx);
- freeResource(resource);
-
- QGLContextGroup *group = QGLContextPrivate::contextGroup(ctx);
- group->m_resources.remove(this);
- m_groups.removeOne(group);
- active.deref();
- }
-}
-
-void QGLContextGroupResourceBase::cleanup(const QGLContext *ctx, void *value)
-{
-#ifdef QT_GL_CONTEXT_RESOURCE_DEBUG
- qDebug("Cleaning up context group resource %p, for context %p in thread %p.", this, ctx, QThread::currentThread());
-#endif
- QGLShareContextScope scope(ctx);
- freeResource(value);
- active.deref();
-
- QGLContextGroup *group = QGLContextPrivate::contextGroup(ctx);
- m_groups.removeOne(group);
-}
-
-void QGLContextGroup::cleanupResources(const QGLContext *context)
-{
- // If there are still shares, then no cleanup to be done yet.
- if (m_shares.size() > 1)
- return;
-
- // Iterate over all resources and free each in turn.
- QHash<QGLContextGroupResourceBase *, void *>::ConstIterator it;
- for (it = m_resources.begin(); it != m_resources.end(); ++it)
- it.key()->cleanup(context, it.value());
-}
-
-QGLSharedResourceGuard::~QGLSharedResourceGuard()
-{
- if (m_group)
- m_group->removeGuard(this);
-}
-
-void QGLSharedResourceGuard::setContext(const QGLContext *context)
-{
- if (m_group)
- m_group->removeGuard(this);
- if (context) {
- m_group = QGLContextPrivate::contextGroup(context);
- m_group->addGuard(this);
- } else {
- m_group = 0;
- }
-}
-
QSize QGLTexture::bindCompressedTexture
(const QString& fileName, const char *format)
{
diff --git a/src/opengl/qgl.h b/src/opengl/qgl.h
index f7685ed8b4..665dcac412 100644
--- a/src/opengl/qgl.h
+++ b/src/opengl/qgl.h
@@ -42,34 +42,22 @@
#ifndef QGL_H
#define QGL_H
-#include <QtGui/qwidget.h>
+#include <QtWidgets/qwidget.h>
#include <QtGui/qpaintengine.h>
#include <QtOpenGL/qglcolormap.h>
#include <QtCore/qmap.h>
#include <QtCore/qscopedpointer.h>
-#ifdef Q_WS_QPA
-#include <QtGui/QPlatformWindowFormat>
-#endif
+#include <QtGui/QSurfaceFormat>
QT_BEGIN_HEADER
-#if defined(Q_WS_WIN)
+#if defined(Q_OS_WIN)
# include <QtCore/qt_windows.h>
#endif
-#if defined(QT_OPENGL_ES_1)
-# if defined(Q_OS_MAC)
-# include <OpenGLES/ES1/gl.h>
-# else
-# include <GLES/gl.h>
-# endif
-# ifndef GL_DOUBLE
-# define GL_DOUBLE GL_FLOAT
-# endif
-# ifndef GLdouble
-typedef GLfloat GLdouble;
-# endif
+#if defined(Q_OS_MAC)
+# include <OpenGL/gl.h>
#elif defined(QT_OPENGL_ES_2)
# if defined(Q_OS_MAC)
# include <OpenGLES/ES2/gl.h>
@@ -94,31 +82,6 @@ QT_BEGIN_NAMESPACE
QT_MODULE(OpenGL)
-#if defined(Q_WS_MAC) && defined (QT_BUILD_OPENGL_LIB) && !defined(QT_MAC_USE_COCOA) && !defined(QDOC)
-#define Q_MAC_COMPAT_GL_FUNCTIONS
-
-template <typename T>
-struct QMacGLCompatTypes
-{
- typedef long CompatGLint;
- typedef unsigned long CompatGLuint;
- typedef unsigned long CompatGLenum;
-};
-
-template <>
-struct QMacGLCompatTypes<long>
-{
- typedef int CompatGLint;
- typedef unsigned int CompatGLuint;
- typedef unsigned int CompatGLenum;
-};
-
-typedef QMacGLCompatTypes<GLint>::CompatGLint QMacCompatGLint;
-typedef QMacGLCompatTypes<GLint>::CompatGLuint QMacCompatGLuint;
-typedef QMacGLCompatTypes<GLint>::CompatGLenum QMacCompatGLenum;
-
-#endif
-
#ifdef QT3_SUPPORT
#define QGL_VERSION 460
#define QGL_VERSION_STR "4.6"
@@ -132,17 +95,12 @@ class QGLCmap;
#endif
class QPixmap;
-#if defined(Q_WS_X11) && !defined(QT_OPENGL_ES)
-class QGLOverlayWidget;
-#endif
class QGLWidgetPrivate;
class QGLContextPrivate;
// Namespace class:
namespace QGL
{
- Q_OPENGL_EXPORT void setPreferredPaintEngine(QPaintEngine::Type engineType);
-
enum FormatOption {
DoubleBuffer = 0x0001,
DepthBuffer = 0x0002,
@@ -284,10 +242,8 @@ public:
static OpenGLVersionFlags openGLVersionFlags();
-#if defined(Q_WS_QPA)
- static QGLFormat fromPlatformWindowFormat(const QPlatformWindowFormat &format);
- static QPlatformWindowFormat toPlatformWindowFormat(const QGLFormat &format);
-#endif
+ static QGLFormat fromSurfaceFormat(const QSurfaceFormat &format);
+ static QSurfaceFormat toSurfaceFormat(const QGLFormat &format);
private:
QGLFormatPrivate *d;
@@ -373,22 +329,6 @@ public:
void drawTexture(const QRectF &target, GLuint textureId, GLenum textureTarget = GL_TEXTURE_2D);
void drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget = GL_TEXTURE_2D);
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
- GLuint bindTexture(const QImage &image, QMacCompatGLenum = GL_TEXTURE_2D,
- QMacCompatGLint format = GL_RGBA);
- GLuint bindTexture(const QPixmap &pixmap, QMacCompatGLenum = GL_TEXTURE_2D,
- QMacCompatGLint format = GL_RGBA);
- GLuint bindTexture(const QImage &image, QMacCompatGLenum, QMacCompatGLint format,
- BindOptions);
- GLuint bindTexture(const QPixmap &pixmap, QMacCompatGLenum, QMacCompatGLint format,
- BindOptions);
-
- void deleteTexture(QMacCompatGLuint tx_id);
-
- void drawTexture(const QRectF &target, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget = GL_TEXTURE_2D);
- void drawTexture(const QPointF &point, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget = GL_TEXTURE_2D);
-#endif
-
static void setTextureCacheLimit(int size);
static int textureCacheLimit();
@@ -398,23 +338,12 @@ public:
static const QGLContext* currentContext();
-#ifdef Q_WS_QPA
- static QGLContext *fromPlatformGLContext(QPlatformGLContext *platformContext);
-#endif
+ static QGLContext *fromOpenGLContext(QOpenGLContext *platformContext);
+ QOpenGLContext *contextHandle() const;
+
protected:
virtual bool chooseContext(const QGLContext* shareContext = 0);
-#if defined(Q_WS_WIN)
- virtual int choosePixelFormat(void* pfd, HDC pdc);
-#endif
-#if defined(Q_WS_X11)
- virtual void* tryVisual(const QGLFormat& f, int bufDepth = 1);
- virtual void* chooseVisual();
-#endif
-#if defined(Q_WS_MAC)
- virtual void* chooseMacVisual(GDHandle);
-#endif
-
bool deviceIsPixmap() const;
bool windowCreated() const;
void setWindowCreated(bool on);
@@ -430,9 +359,7 @@ protected:
static QGLContext* currentCtx;
private:
-#ifdef Q_WS_QPA
- QGLContext(QPlatformGLContext *platformContext);
-#endif
+ QGLContext(QOpenGLContext *windowContext);
QScopedPointer<QGLContextPrivate> d_ptr;
@@ -441,18 +368,12 @@ private:
friend class QGLWidget;
friend class QGLWidgetPrivate;
friend class QGLGlyphCache;
- friend class QOpenGLPaintEngine;
- friend class QOpenGLPaintEnginePrivate;
friend class QGL2PaintEngineEx;
friend class QGL2PaintEngineExPrivate;
friend class QGLEngineShaderManager;
- friend class QGLWindowSurface;
- friend class QGLPixmapData;
- friend class QGLPixmapFilterBase;
friend class QGLTextureGlyphCache;
friend struct QGLGlyphTexture;
friend class QGLContextGroup;
- friend class QGLSharedResourceGuard;
friend class QGLPixmapBlurFilter;
friend class QGLExtensions;
friend class QGLTexture;
@@ -469,7 +390,6 @@ private:
friend class QGLFBOGLPaintDevice;
friend class QGLPaintDevice;
friend class QGLWidgetGLPaintDevice;
- friend class QX11GLPixmapData;
friend class QX11GLSharedContexts;
friend class QGLContextResourceBase;
friend class QSGDistanceFieldGlyphCache;
@@ -556,22 +476,6 @@ public:
void drawTexture(const QRectF &target, GLuint textureId, GLenum textureTarget = GL_TEXTURE_2D);
void drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget = GL_TEXTURE_2D);
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
- GLuint bindTexture(const QImage &image, QMacCompatGLenum = GL_TEXTURE_2D,
- QMacCompatGLint format = GL_RGBA);
- GLuint bindTexture(const QPixmap &pixmap, QMacCompatGLenum = GL_TEXTURE_2D,
- QMacCompatGLint format = GL_RGBA);
- GLuint bindTexture(const QImage &image, QMacCompatGLenum, QMacCompatGLint format,
- QGLContext::BindOptions);
- GLuint bindTexture(const QPixmap &pixmap, QMacCompatGLenum, QMacCompatGLint format,
- QGLContext::BindOptions);
-
- void deleteTexture(QMacCompatGLuint tx_id);
-
- void drawTexture(const QRectF &target, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget = GL_TEXTURE_2D);
- void drawTexture(const QPointF &point, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget = GL_TEXTURE_2D);
-#endif
-
public Q_SLOTS:
virtual void updateGL();
virtual void updateOverlayGL();
@@ -613,7 +517,6 @@ private:
friend class QGLContext;
friend class QGLContextPrivate;
friend class QGLOverlayWidget;
- friend class QOpenGLPaintEngine;
friend class QGLPaintDevice;
friend class QGLWidgetGLPaintDevice;
};
diff --git a/src/opengl/qgl_egl.cpp b/src/opengl/qgl_egl.cpp
deleted file mode 100644
index 4de5122a86..0000000000
--- a/src/opengl/qgl_egl.cpp
+++ /dev/null
@@ -1,351 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtCore/qdebug.h>
-#include <QtOpenGL/qgl.h>
-#include <QtOpenGL/qglpixelbuffer.h>
-#include "qgl_p.h"
-#include "qgl_egl_p.h"
-#include "qglpixelbuffer_p.h"
-
-#ifdef Q_WS_X11
-#include <QtGui/private/qpixmap_x11_p.h>
-#endif
-
-QT_BEGIN_NAMESPACE
-
-QEglProperties *QGLContextPrivate::extraWindowSurfaceCreationProps = NULL;
-
-void qt_eglproperties_set_glformat(QEglProperties& eglProperties, const QGLFormat& glFormat)
-{
- int redSize = glFormat.redBufferSize();
- int greenSize = glFormat.greenBufferSize();
- int blueSize = glFormat.blueBufferSize();
- int alphaSize = glFormat.alphaBufferSize();
- int depthSize = glFormat.depthBufferSize();
- int stencilSize = glFormat.stencilBufferSize();
- int sampleCount = glFormat.samples();
-
- // QGLFormat uses a magic value of -1 to indicate "don't care", even when a buffer of that
- // type has been requested. So we must check QGLFormat's booleans too if size is -1:
- if (glFormat.alpha() && alphaSize <= 0)
- alphaSize = 1;
- if (glFormat.depth() && depthSize <= 0)
- depthSize = 1;
- if (glFormat.stencil() && stencilSize <= 0)
- stencilSize = 1;
- if (glFormat.sampleBuffers() && sampleCount <= 0)
- sampleCount = 1;
-
- // We want to make sure 16-bit configs are chosen over 32-bit configs as they will provide
- // the best performance. The EGL config selection algorithm is a bit stange in this regard:
- // The selection criteria for EGL_BUFFER_SIZE is "AtLeast", so we can't use it to discard
- // 32-bit configs completely from the selection. So it then comes to the sorting algorithm.
- // The red/green/blue sizes have a sort priority of 3, so they are sorted by first. The sort
- // order is special and described as "by larger _total_ number of color bits.". So EGL will
- // put 32-bit configs in the list before the 16-bit configs. However, the spec also goes on
- // to say "If the requested number of bits in attrib_list for a particular component is 0,
- // then the number of bits for that component is not considered". This part of the spec also
- // seems to imply that setting the red/green/blue bits to zero means none of the components
- // are considered and EGL disregards the entire sorting rule. It then looks to the next
- // highest priority rule, which is EGL_BUFFER_SIZE. Despite the selection criteria being
- // "AtLeast" for EGL_BUFFER_SIZE, it's sort order is "smaller" meaning 16-bit configs are
- // put in the list before 32-bit configs. So, to make sure 16-bit is preffered over 32-bit,
- // we must set the red/green/blue sizes to zero. This has an unfortunate consequence that
- // if the application sets the red/green/blue size to 5/6/5 on the QGLFormat, they will
- // probably get a 32-bit config, even when there's an RGB565 config available. Oh well.
-
- // Now normalize the values so -1 becomes 0
- redSize = redSize > 0 ? redSize : 0;
- greenSize = greenSize > 0 ? greenSize : 0;
- blueSize = blueSize > 0 ? blueSize : 0;
- alphaSize = alphaSize > 0 ? alphaSize : 0;
- depthSize = depthSize > 0 ? depthSize : 0;
- stencilSize = stencilSize > 0 ? stencilSize : 0;
- sampleCount = sampleCount > 0 ? sampleCount : 0;
-
- eglProperties.setValue(EGL_RED_SIZE, redSize);
- eglProperties.setValue(EGL_GREEN_SIZE, greenSize);
- eglProperties.setValue(EGL_BLUE_SIZE, blueSize);
- eglProperties.setValue(EGL_ALPHA_SIZE, alphaSize);
- eglProperties.setValue(EGL_DEPTH_SIZE, depthSize);
- eglProperties.setValue(EGL_STENCIL_SIZE, stencilSize);
- eglProperties.setValue(EGL_SAMPLES, sampleCount);
- eglProperties.setValue(EGL_SAMPLE_BUFFERS, sampleCount ? 1 : 0);
-}
-
-// Updates "format" with the parameters of the selected configuration.
-void qt_glformat_from_eglconfig(QGLFormat& format, const EGLConfig config)
-{
- EGLint redSize = 0;
- EGLint greenSize = 0;
- EGLint blueSize = 0;
- EGLint alphaSize = 0;
- EGLint depthSize = 0;
- EGLint stencilSize = 0;
- EGLint sampleCount = 0;
- EGLint level = 0;
-
- EGLDisplay display = QEgl::display();
- eglGetConfigAttrib(display, config, EGL_RED_SIZE, &redSize);
- eglGetConfigAttrib(display, config, EGL_GREEN_SIZE, &greenSize);
- eglGetConfigAttrib(display, config, EGL_BLUE_SIZE, &blueSize);
- eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &alphaSize);
- eglGetConfigAttrib(display, config, EGL_DEPTH_SIZE, &depthSize);
- eglGetConfigAttrib(display, config, EGL_STENCIL_SIZE, &stencilSize);
- eglGetConfigAttrib(display, config, EGL_SAMPLES, &sampleCount);
- eglGetConfigAttrib(display, config, EGL_LEVEL, &level);
-
- format.setRedBufferSize(redSize);
- format.setGreenBufferSize(greenSize);
- format.setBlueBufferSize(blueSize);
- format.setAlphaBufferSize(alphaSize);
- format.setDepthBufferSize(depthSize);
- format.setStencilBufferSize(stencilSize);
- format.setSamples(sampleCount);
- format.setPlane(level);
- format.setDirectRendering(true); // All EGL contexts are direct-rendered
- format.setRgba(true); // EGL doesn't support colour index rendering
- format.setStereo(false); // EGL doesn't support stereo buffers
- format.setAccumBufferSize(0); // EGL doesn't support accululation buffers
- format.setDoubleBuffer(true); // We don't support single buffered EGL contexts
-
- // Clear the EGL error state because some of the above may
- // have errored out because the attribute is not applicable
- // to the surface type. Such errors don't matter.
- eglGetError();
-}
-
-bool QGLFormat::hasOpenGL()
-{
- return true;
-}
-
-void QGLContext::reset()
-{
- Q_D(QGLContext);
- if (!d->valid)
- return;
- d->cleanup();
- doneCurrent();
- if (d->eglContext && d->ownsEglContext) {
- d->destroyEglSurfaceForDevice();
- delete d->eglContext;
- }
- d->ownsEglContext = false;
- d->eglContext = 0;
- d->eglSurface = EGL_NO_SURFACE;
- d->crWin = false;
- d->sharing = false;
- d->valid = false;
- d->transpColor = QColor();
- d->initDone = false;
- QGLContextGroup::removeShare(this);
-}
-
-void QGLContext::makeCurrent()
-{
- Q_D(QGLContext);
- if (!d->valid || !d->eglContext || d->eglSurfaceForDevice() == EGL_NO_SURFACE) {
- qWarning("QGLContext::makeCurrent(): Cannot make invalid context current");
- return;
- }
-
- if (d->eglContext->makeCurrent(d->eglSurfaceForDevice())) {
- QGLContextPrivate::setCurrentContext(this);
- if (!d->workaroundsCached) {
- d->workaroundsCached = true;
- const char *renderer = reinterpret_cast<const char *>(glGetString(GL_RENDERER));
- if (renderer && (strstr(renderer, "SGX") || strstr(renderer, "MBX"))) {
- // PowerVR MBX/SGX chips needs to clear all buffers when starting to render
- // a new frame, otherwise there will be a performance penalty to pay for
- // each frame.
- qDebug() << "Found SGX/MBX driver, enabling FullClearOnEveryFrame";
- d->workaround_needsFullClearOnEveryFrame = true;
-
- // Older PowerVR SGX drivers (like the one in the N900) have a
- // bug which prevents glCopyTexSubImage2D() to work with a POT
- // or GL_ALPHA texture bound to an FBO. The only way to
- // identify that driver is to check the EGL version number for it.
- const char *egl_version = eglQueryString(d->eglContext->display(), EGL_VERSION);
-
- if (egl_version && strstr(egl_version, "1.3")) {
- qDebug() << "Found v1.3 driver, enabling brokenFBOReadBack";
- d->workaround_brokenFBOReadBack = true;
- } else if (egl_version && strstr(egl_version, "1.4")) {
- qDebug() << "Found v1.4 driver, enabling brokenTexSubImage";
- d->workaround_brokenTexSubImage = true;
-
- // this is a bit complicated; 1.4 version SGX drivers from
- // Nokia have fixed the brokenFBOReadBack problem, but
- // official drivers from TI haven't, meaning that things
- // like the beagleboard are broken unless we hack around it
- // - but at the same time, we want to not reduce performance
- // by not enabling this elsewhere.
- //
- // so, let's check for a Nokia-specific addon, and only
- // enable if it isn't present.
- // (see MeeGo bug #5616)
- if (!QEgl::hasExtension("EGL_NOK_image_shared")) {
- // no Nokia extension, this is probably a standard SGX
- // driver, so enable the workaround
- qDebug() << "Found non-Nokia v1.4 driver, enabling brokenFBOReadBack";
- d->workaround_brokenFBOReadBack = true;
- }
- }
- }
- }
- }
-}
-
-void QGLContext::doneCurrent()
-{
- Q_D(QGLContext);
- if (d->eglContext)
- d->eglContext->doneCurrent();
-
- QGLContextPrivate::setCurrentContext(0);
-}
-
-
-void QGLContext::swapBuffers() const
-{
- Q_D(const QGLContext);
- if (!d->valid || !d->eglContext)
- return;
-
- d->eglContext->swapBuffers(d->eglSurfaceForDevice());
-}
-
-void QGLContextPrivate::destroyEglSurfaceForDevice()
-{
- if (eglSurface != EGL_NO_SURFACE) {
-#if defined(Q_WS_X11) || defined(Q_OS_SYMBIAN)
- // Make sure we don't call eglDestroySurface on a surface which
- // was created for a different winId. This applies only to QGLWidget
- // paint device, so make sure this is the one we're operating on
- // (as opposed to a QGLWindowSurface use case).
- if (paintDevice && paintDevice->devType() == QInternal::Widget) {
- QWidget *w = static_cast<QWidget *>(paintDevice);
- if (QGLWidget *wgl = qobject_cast<QGLWidget *>(w)) {
- if (wgl->d_func()->eglSurfaceWindowId != wgl->winId()) {
- qWarning("WARNING: Potential EGL surface leak! Not destroying surface.");
- eglSurface = EGL_NO_SURFACE;
- return;
- }
- }
- }
-#endif
- eglDestroySurface(eglContext->display(), eglSurface);
- eglSurface = EGL_NO_SURFACE;
- }
-}
-
-EGLSurface QGLContextPrivate::eglSurfaceForDevice() const
-{
- // If a QPixmapData had to create the QGLContext, we don't have a paintDevice
- if (!paintDevice)
- return eglSurface;
-
-#ifdef Q_WS_X11
- if (paintDevice->devType() == QInternal::Pixmap) {
- QPixmapData *pmd = static_cast<QPixmap*>(paintDevice)->data_ptr().data();
- if (pmd->classId() == QPixmapData::X11Class) {
- QX11PixmapData* x11PixmapData = static_cast<QX11PixmapData*>(pmd);
- return (EGLSurface)x11PixmapData->gl_surface;
- }
- }
-#endif
-
- if (paintDevice->devType() == QInternal::Pbuffer) {
- QGLPixelBuffer* pbuf = static_cast<QGLPixelBuffer*>(paintDevice);
- return pbuf->d_func()->pbuf;
- }
-
- return eglSurface;
-}
-
-void QGLContextPrivate::swapRegion(const QRegion &region)
-{
- if (!valid || !eglContext)
- return;
-
- eglContext->swapBuffersRegion2NOK(eglSurfaceForDevice(), &region);
-}
-
-void QGLContextPrivate::setExtraWindowSurfaceCreationProps(QEglProperties *props)
-{
- extraWindowSurfaceCreationProps = props;
-}
-
-void QGLWidget::setMouseTracking(bool enable)
-{
- QWidget::setMouseTracking(enable);
-}
-
-QColor QGLContext::overlayTransparentColor() const
-{
- return d_func()->transpColor;
-}
-
-uint QGLContext::colorIndex(const QColor &c) const
-{
- Q_UNUSED(c);
- return 0;
-}
-
-void QGLContext::generateFontDisplayLists(const QFont & fnt, int listBase)
-{
- Q_UNUSED(fnt);
- Q_UNUSED(listBase);
-}
-
-void *QGLContext::getProcAddress(const QString &proc) const
-{
- return (void*)eglGetProcAddress(reinterpret_cast<const char *>(proc.toLatin1().data()));
-}
-
-bool QGLWidgetPrivate::renderCxPm(QPixmap*)
-{
- return false;
-}
-
-QT_END_NAMESPACE
diff --git a/src/opengl/qgl_egl_p.h b/src/opengl/qgl_egl_p.h
deleted file mode 100644
index 2522fca822..0000000000
--- a/src/opengl/qgl_egl_p.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGL_EGL_P_H
-#define QGL_EGL_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of the QGLWidget class. This header file may change from
-// version to version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtGui/private/qegl_p.h>
-#include <QtGui/private/qeglcontext_p.h>
-#include <QtGui/private/qeglproperties_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QGLFormat;
-
-void qt_eglproperties_set_glformat(QEglProperties& props, const QGLFormat& format);
-void qt_glformat_from_eglconfig(QGLFormat& format, const EGLConfig config);
-
-QT_END_NAMESPACE
-
-#endif // QGL_EGL_P_H
diff --git a/src/opengl/qgl_mac.mm b/src/opengl/qgl_mac.mm
deleted file mode 100644
index d4b2a40e93..0000000000
--- a/src/opengl/qgl_mac.mm
+++ /dev/null
@@ -1,996 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qgl.h"
-
-// There are functions that are deprecated in 10.5, but really there's no way around them
-// for Carbon, so just undefine them.
-#undef DEPRECATED_ATTRIBUTE
-#define DEPRECATED_ATTRIBUTE
-#if defined(Q_WS_MAC)
-#ifndef QT_MAC_USE_COCOA
-#ifdef qDebug
-# undef qDebug
-# include <AGL/agl.h>
-# include <AGL/aglRenderers.h>
-# include <OpenGL/gl.h>
-# ifdef QT_NO_DEBUG
-# define qDebug qt_noop(),1?(void)0:qDebug
-# endif
-#else
-# include <AGL/agl.h>
-# include <AGL/aglRenderers.h>
-# include <OpenGL/gl.h>
-#endif
-#else
-#include <private/qcocoaview_mac_p.h>
-#endif
-
-
-#include <OpenGL/gl.h>
-#include <CoreServices/CoreServices.h>
-#include <private/qfont_p.h>
-#include <private/qfontengine_p.h>
-#include <private/qgl_p.h>
-#include <private/qpaintengine_opengl_p.h>
-#include <private/qt_mac_p.h>
-#include <qpixmap.h>
-#include <qtimer.h>
-#include <qapplication.h>
-#include <qstack.h>
-#include <qdesktopwidget.h>
-#include <qdebug.h>
-
-QT_BEGIN_NAMESPACE
-#ifdef QT_MAC_USE_COCOA
-QT_END_NAMESPACE
-
-QT_FORWARD_DECLARE_CLASS(QWidget)
-QT_FORWARD_DECLARE_CLASS(QWidgetPrivate)
-QT_FORWARD_DECLARE_CLASS(QGLWidgetPrivate)
-
-QT_BEGIN_NAMESPACE
-
-void *qt_current_nsopengl_context()
-{
- return [NSOpenGLContext currentContext];
-}
-
-static GLint attribValue(NSOpenGLPixelFormat *fmt, NSOpenGLPixelFormatAttribute attrib)
-{
- GLint res;
- [fmt getValues:&res forAttribute:attrib forVirtualScreen:0];
- return res;
-}
-
-static int def(int val, int defVal)
-{
- return val != -1 ? val : defVal;
-}
-#else
-QRegion qt_mac_get_widget_rgn(const QWidget *widget);
-#endif
-
-extern quint32 *qt_mac_pixmap_get_base(const QPixmap *);
-extern int qt_mac_pixmap_get_bytes_per_line(const QPixmap *);
-extern RgnHandle qt_mac_get_rgn(); //qregion_mac.cpp
-extern void qt_mac_dispose_rgn(RgnHandle); //qregion_mac.cpp
-extern QRegion qt_mac_convert_mac_region(RgnHandle); //qregion_mac.cpp
-extern void qt_mac_to_pascal_string(QString s, Str255 str, TextEncoding encoding=0, int len=-1); //qglobal.cpp
-
-/*
- QGLTemporaryContext implementation
-*/
-
-class QGLTemporaryContextPrivate
-{
-public:
-#ifndef QT_MAC_USE_COCOA
- AGLContext ctx;
-#else
- NSOpenGLContext *ctx;
-#endif
-};
-
-QGLTemporaryContext::QGLTemporaryContext(bool, QWidget *)
- : d(new QGLTemporaryContextPrivate)
-{
- d->ctx = 0;
-#ifndef QT_MAC_USE_COCOA
- GLint attribs[] = {AGL_RGBA, AGL_NONE};
- AGLPixelFormat fmt = aglChoosePixelFormat(0, 0, attribs);
- if (!fmt) {
- qDebug("QGLTemporaryContext: Couldn't find any RGB visuals");
- return;
- }
- d->ctx = aglCreateContext(fmt, 0);
- if (!d->ctx)
- qDebug("QGLTemporaryContext: Unable to create context");
- else
- aglSetCurrentContext(d->ctx);
- aglDestroyPixelFormat(fmt);
-#else
- QMacCocoaAutoReleasePool pool;
- NSOpenGLPixelFormatAttribute attribs[] = { 0 };
- NSOpenGLPixelFormat *fmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];
- if (!fmt) {
- qWarning("QGLTemporaryContext: Cannot find any visuals");
- return;
- }
-
- d->ctx = [[NSOpenGLContext alloc] initWithFormat:fmt shareContext:0];
- if (!d->ctx)
- qWarning("QGLTemporaryContext: Cannot create context");
- else
- [d->ctx makeCurrentContext];
- [fmt release];
-#endif
-}
-
-QGLTemporaryContext::~QGLTemporaryContext()
-{
- if (d->ctx) {
-#ifndef QT_MAC_USE_COCOA
- aglSetCurrentContext(0);
- aglDestroyContext(d->ctx);
-#else
- [NSOpenGLContext clearCurrentContext];
- [d->ctx release];
-#endif
- }
-}
-
-bool QGLFormat::hasOpenGL()
-{
- return true;
-}
-
-bool QGLFormat::hasOpenGLOverlays()
-{
- return false;
-}
-
-bool QGLContext::chooseContext(const QGLContext *shareContext)
-{
- QMacCocoaAutoReleasePool pool;
- Q_D(QGLContext);
- d->cx = 0;
- d->vi = chooseMacVisual(0);
- if (!d->vi)
- return false;
-
-#ifndef QT_MAC_USE_COCOA
- AGLPixelFormat fmt = (AGLPixelFormat)d->vi;
- GLint res;
- aglDescribePixelFormat(fmt, AGL_LEVEL, &res);
- d->glFormat.setPlane(res);
- if (deviceIsPixmap())
- res = 0;
- else
- aglDescribePixelFormat(fmt, AGL_DOUBLEBUFFER, &res);
- d->glFormat.setDoubleBuffer(res);
- aglDescribePixelFormat(fmt, AGL_DEPTH_SIZE, &res);
- d->glFormat.setDepth(res);
- if (d->glFormat.depth())
- d->glFormat.setDepthBufferSize(res);
- aglDescribePixelFormat(fmt, AGL_RGBA, &res);
- d->glFormat.setRgba(res);
- aglDescribePixelFormat(fmt, AGL_RED_SIZE, &res);
- d->glFormat.setRedBufferSize(res);
- aglDescribePixelFormat(fmt, AGL_GREEN_SIZE, &res);
- d->glFormat.setGreenBufferSize(res);
- aglDescribePixelFormat(fmt, AGL_BLUE_SIZE, &res);
- d->glFormat.setBlueBufferSize(res);
- aglDescribePixelFormat(fmt, AGL_ALPHA_SIZE, &res);
- d->glFormat.setAlpha(res);
- if (d->glFormat.alpha())
- d->glFormat.setAlphaBufferSize(res);
- aglDescribePixelFormat(fmt, AGL_ACCUM_RED_SIZE, &res);
- // Bug in Apple OpenGL (rdr://5015603), when we don't have an accumulation
- // buffer, it still claims that we have a 16-bit one (which is pretty rare).
- // So, we just assume we can never have a buffer that small.
- d->glFormat.setAccum(res > 5);
- if (d->glFormat.accum())
- d->glFormat.setAccumBufferSize(res);
- aglDescribePixelFormat(fmt, AGL_STENCIL_SIZE, &res);
- d->glFormat.setStencil(res);
- if (d->glFormat.stencil())
- d->glFormat.setStencilBufferSize(res);
- aglDescribePixelFormat(fmt, AGL_STEREO, &res);
- d->glFormat.setStereo(res);
- aglDescribePixelFormat(fmt, AGL_SAMPLE_BUFFERS_ARB, &res);
- d->glFormat.setSampleBuffers(res);
- if (d->glFormat.sampleBuffers()) {
- aglDescribePixelFormat(fmt, AGL_SAMPLES_ARB, &res);
- d->glFormat.setSamples(res);
- }
-#else
- NSOpenGLPixelFormat *fmt = static_cast<NSOpenGLPixelFormat *>(d->vi);
-
- d->glFormat = QGLFormat();
-
- // ### make sure to reset other options
- d->glFormat.setDoubleBuffer(attribValue(fmt, NSOpenGLPFADoubleBuffer));
-
- int depthSize = attribValue(fmt, NSOpenGLPFADepthSize);
- d->glFormat.setDepth(depthSize > 0);
- if (depthSize > 0)
- d->glFormat.setDepthBufferSize(depthSize);
-
- int alphaSize = attribValue(fmt, NSOpenGLPFAAlphaSize);
- d->glFormat.setAlpha(alphaSize > 0);
- if (alphaSize > 0)
- d->glFormat.setAlphaBufferSize(alphaSize);
-
- int accumSize = attribValue(fmt, NSOpenGLPFAAccumSize);
- d->glFormat.setAccum(accumSize > 0);
- if (accumSize > 0)
- d->glFormat.setAccumBufferSize(accumSize);
-
- int stencilSize = attribValue(fmt, NSOpenGLPFAStencilSize);
- d->glFormat.setStencil(stencilSize > 0);
- if (stencilSize > 0)
- d->glFormat.setStencilBufferSize(stencilSize);
-
- d->glFormat.setStereo(attribValue(fmt, NSOpenGLPFAStereo));
-
- int sampleBuffers = attribValue(fmt, NSOpenGLPFASampleBuffers);
- d->glFormat.setSampleBuffers(sampleBuffers);
- if (sampleBuffers > 0)
- d->glFormat.setSamples(attribValue(fmt, NSOpenGLPFASamples));
-#endif
- if (shareContext && (!shareContext->isValid() || !shareContext->d_func()->cx)) {
- qWarning("QGLContext::chooseContext: Cannot share with invalid context");
- shareContext = 0;
- }
-
- // sharing between rgba and color-index will give wrong colors
- if (shareContext && (format().rgba() != shareContext->format().rgba()))
- shareContext = 0;
-
-#ifndef QT_MAC_USE_COCOA
- AGLContext ctx = aglCreateContext(fmt, (AGLContext) (shareContext ? shareContext->d_func()->cx : 0));
-#else
- NSOpenGLContext *ctx = [[NSOpenGLContext alloc] initWithFormat:fmt
- shareContext:(shareContext ? static_cast<NSOpenGLContext *>(shareContext->d_func()->cx)
- : 0)];
-#endif
- if (!ctx) {
-#ifndef QT_MAC_USE_COCOA
- GLenum err = aglGetError();
- if (err == AGL_BAD_MATCH || err == AGL_BAD_CONTEXT) {
- if (shareContext && shareContext->d_func()->cx) {
- qWarning("QGLContext::chooseContext(): Context sharing mismatch!");
- if (!(ctx = aglCreateContext(fmt, 0)))
- return false;
- shareContext = 0;
- }
- }
-#else
- if (shareContext) {
- ctx = [[NSOpenGLContext alloc] initWithFormat:fmt shareContext:0];
- if (ctx) {
- qWarning("QGLContext::chooseContext: Context sharing mismatch");
- shareContext = 0;
- }
- }
-#endif
- if (!ctx) {
- qWarning("QGLContext::chooseContext: Unable to create QGLContext");
- return false;
- }
- }
- d->cx = ctx;
- if (shareContext && shareContext->d_func()->cx) {
- QGLContext *share = const_cast<QGLContext *>(shareContext);
- d->sharing = true;
- share->d_func()->sharing = true;
- }
- if (deviceIsPixmap())
- updatePaintDevice();
-
- // vblank syncing
- GLint interval = d->reqFormat.swapInterval();
- if (interval != -1) {
-#ifndef QT_MAC_USE_COCOA
- aglSetInteger((AGLContext)d->cx, AGL_SWAP_INTERVAL, &interval);
- if (interval != 0)
- aglEnable((AGLContext)d->cx, AGL_SWAP_INTERVAL);
- else
- aglDisable((AGLContext)d->cx, AGL_SWAP_INTERVAL);
-#else
- [ctx setValues:&interval forParameter:NSOpenGLCPSwapInterval];
-#endif
- }
-#ifndef QT_MAC_USE_COCOA
- aglGetInteger((AGLContext)d->cx, AGL_SWAP_INTERVAL, &interval);
-#else
- [ctx getValues:&interval forParameter:NSOpenGLCPSwapInterval];
-#endif
- d->glFormat.setSwapInterval(interval);
- return true;
-}
-
-void *QGLContextPrivate::tryFormat(const QGLFormat &format)
-{
- static const int Max = 40;
-#ifndef QT_MAC_USE_COCOA
- GLint attribs[Max], cnt = 0;
- bool device_is_pixmap = (paintDevice->devType() == QInternal::Pixmap);
-
- attribs[cnt++] = AGL_RGBA;
- attribs[cnt++] = AGL_BUFFER_SIZE;
- attribs[cnt++] = device_is_pixmap ? static_cast<QPixmap *>(paintDevice)->depth() : 32;
- attribs[cnt++] = AGL_LEVEL;
- attribs[cnt++] = format.plane();
-
- if (format.redBufferSize() != -1) {
- attribs[cnt++] = AGL_RED_SIZE;
- attribs[cnt++] = format.redBufferSize();
- }
- if (format.greenBufferSize() != -1) {
- attribs[cnt++] = AGL_GREEN_SIZE;
- attribs[cnt++] = format.greenBufferSize();
- }
- if (format.blueBufferSize() != -1) {
- attribs[cnt++] = AGL_BLUE_SIZE;
- attribs[cnt++] = format.blueBufferSize();
- }
- if (device_is_pixmap) {
- attribs[cnt++] = AGL_PIXEL_SIZE;
- attribs[cnt++] = static_cast<QPixmap *>(paintDevice)->depth();
- attribs[cnt++] = AGL_OFFSCREEN;
- if (!format.alpha()) {
- attribs[cnt++] = AGL_ALPHA_SIZE;
- attribs[cnt++] = 8;
- }
- } else {
- if (format.doubleBuffer())
- attribs[cnt++] = AGL_DOUBLEBUFFER;
- }
-
- if (format.stereo())
- attribs[cnt++] = AGL_STEREO;
- if (format.alpha()) {
- attribs[cnt++] = AGL_ALPHA_SIZE;
- attribs[cnt++] = format.alphaBufferSize() == -1 ? 8 : format.alphaBufferSize();
- }
- if (format.stencil()) {
- attribs[cnt++] = AGL_STENCIL_SIZE;
- attribs[cnt++] = format.stencilBufferSize() == -1 ? 8 : format.stencilBufferSize();
- }
- if (format.depth()) {
- attribs[cnt++] = AGL_DEPTH_SIZE;
- attribs[cnt++] = format.depthBufferSize() == -1 ? 32 : format.depthBufferSize();
- }
- if (format.accum()) {
- attribs[cnt++] = AGL_ACCUM_RED_SIZE;
- attribs[cnt++] = format.accumBufferSize() == -1 ? 1 : format.accumBufferSize();
- attribs[cnt++] = AGL_ACCUM_BLUE_SIZE;
- attribs[cnt++] = format.accumBufferSize() == -1 ? 1 : format.accumBufferSize();
- attribs[cnt++] = AGL_ACCUM_GREEN_SIZE;
- attribs[cnt++] = format.accumBufferSize() == -1 ? 1 : format.accumBufferSize();
- attribs[cnt++] = AGL_ACCUM_ALPHA_SIZE;
- attribs[cnt++] = format.accumBufferSize() == -1 ? 1 : format.accumBufferSize();
- }
- if (format.sampleBuffers()) {
- attribs[cnt++] = AGL_SAMPLE_BUFFERS_ARB;
- attribs[cnt++] = 1;
- attribs[cnt++] = AGL_SAMPLES_ARB;
- attribs[cnt++] = format.samples() == -1 ? 4 : format.samples();
- }
-
- attribs[cnt] = AGL_NONE;
- Q_ASSERT(cnt < Max);
- return aglChoosePixelFormat(0, 0, attribs);
-#else
- NSOpenGLPixelFormatAttribute attribs[Max];
- int cnt = 0;
- int devType = paintDevice->devType();
- bool device_is_pixmap = (devType == QInternal::Pixmap);
- int depth = device_is_pixmap ? static_cast<QPixmap *>(paintDevice)->depth() : 32;
-
- attribs[cnt++] = NSOpenGLPFAColorSize;
- attribs[cnt++] = depth;
-
- if (device_is_pixmap) {
- attribs[cnt++] = NSOpenGLPFAOffScreen;
- } else {
- if (format.doubleBuffer())
- attribs[cnt++] = NSOpenGLPFADoubleBuffer;
- }
- if (glFormat.stereo())
- attribs[cnt++] = NSOpenGLPFAStereo;
- if (device_is_pixmap || format.alpha()) {
- attribs[cnt++] = NSOpenGLPFAAlphaSize;
- attribs[cnt++] = def(format.alphaBufferSize(), 8);
- }
- if (format.stencil()) {
- attribs[cnt++] = NSOpenGLPFAStencilSize;
- attribs[cnt++] = def(format.stencilBufferSize(), 8);
- }
- if (format.depth()) {
- attribs[cnt++] = NSOpenGLPFADepthSize;
- attribs[cnt++] = def(format.depthBufferSize(), 32);
- }
- if (format.accum()) {
- attribs[cnt++] = NSOpenGLPFAAccumSize;
- attribs[cnt++] = def(format.accumBufferSize(), 1);
- }
- if (format.sampleBuffers()) {
- attribs[cnt++] = NSOpenGLPFASampleBuffers;
- attribs[cnt++] = 1;
- attribs[cnt++] = NSOpenGLPFASamples;
- attribs[cnt++] = def(format.samples(), 4);
- }
-
- if (format.directRendering())
- attribs[cnt++] = NSOpenGLPFAAccelerated;
-
- if (devType == QInternal::Pbuffer)
- attribs[cnt++] = NSOpenGLPFAPixelBuffer;
-
- attribs[cnt] = 0;
- Q_ASSERT(cnt < Max);
- return [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];
-#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
- cannot be met.
-
- The algorithm for reducing the demands of the format is quite
- simple-minded, so override this method in your subclass if your
- application has spcific requirements on visual selection.
-
- The \a handle argument is always zero and is not used
-
- \sa chooseContext()
-*/
-
-void *QGLContext::chooseMacVisual(GDHandle /* handle */)
-{
- Q_D(QGLContext);
-
- void *fmt = d->tryFormat(d->glFormat);
- if (!fmt && d->glFormat.stereo()) {
- d->glFormat.setStereo(false);
- fmt = d->tryFormat(d->glFormat);
- }
- if (!fmt && d->glFormat.sampleBuffers()) {
- d->glFormat.setSampleBuffers(false);
- fmt = d->tryFormat(d->glFormat);
- }
- if (!fmt)
- qWarning("QGLContext::chooseMacVisual: Unable to choose a pixel format");
- return fmt;
-}
-
-void QGLContext::reset()
-{
- Q_D(QGLContext);
- if (!d->valid)
- return;
- d->cleanup();
- doneCurrent();
-#ifndef QT_MAC_USE_COCOA
- if (d->cx)
- aglDestroyContext((AGLContext)d->cx);
-#else
- QMacCocoaAutoReleasePool pool;
- [static_cast<NSOpenGLContext *>(d->cx) release];
-#endif
- d->cx = 0;
-#ifndef QT_MAC_USE_COCOA
- if (d->vi)
- aglDestroyPixelFormat((AGLPixelFormat)d->vi);
-#else
- [static_cast<NSOpenGLPixelFormat *>(d->vi) release];
-#endif
- d->vi = 0;
- d->crWin = false;
- d->sharing = false;
- d->valid = false;
- d->transpColor = QColor();
- d->initDone = false;
- QGLContextGroup::removeShare(this);
-}
-
-void QGLContext::makeCurrent()
-{
- Q_D(QGLContext);
-
- if (!d->valid) {
- qWarning("QGLContext::makeCurrent: Cannot make invalid context current");
- return;
- }
-#ifndef QT_MAC_USE_COCOA
- aglSetCurrentContext((AGLContext)d->cx);
- if (d->update)
- updatePaintDevice();
-#else
- [static_cast<NSOpenGLContext *>(d->cx) makeCurrentContext];
-#endif
- QGLContextPrivate::setCurrentContext(this);
-}
-
-#ifndef QT_MAC_USE_COCOA
-/*
- Returns the effective scale factor for a widget. For this value to be
- different than 1, the following must be true:
- - The system scale factor must be greater than 1.
- - The widget window must have WA_MacFrameworkScaled set.
-*/
-float qt_mac_get_scale_factor(QWidget *widget)
-{
- if (!widget | !widget->window())
- return 1;
-
- if (widget->window()->testAttribute(Qt::WA_MacFrameworkScaled) == false)
- return 1;
-
- float systemScale = QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4 ? HIGetScaleFactor() : 1;
- if (systemScale == float(1))
- return 1;
-
- return systemScale;
-}
-#endif
-
-/*! \internal
-*/
-void QGLContext::updatePaintDevice()
-{
- Q_D(QGLContext);
-#ifndef QT_MAC_USE_COCOA
- d->update = false;
- if (d->paintDevice->devType() == QInternal::Widget) {
- //get control information
- QWidget *w = (QWidget *)d->paintDevice;
- HIViewRef hiview = (HIViewRef)w->winId();
- WindowRef window = HIViewGetWindow(hiview);
-#ifdef DEBUG_OPENGL_REGION_UPDATE
- static int serial_no_gl = 0;
- qDebug("[%d] %p setting on %s::%s %p/%p [%s]", ++serial_no_gl, w,
- w->metaObject()->className(), w->objectName().toLatin1().constData(),
- hiview, window, w->handle() ? "Inside" : "Outside");
-#endif
-
- //update drawable
- if (0 && w->isWindow() && w->isFullScreen()) {
- aglSetDrawable((AGLContext)d->cx, 0);
- aglSetFullScreen((AGLContext)d->cx, w->width(), w->height(), 0, QApplication::desktop()->screenNumber(w));
- w->hide();
- } else {
- AGLDrawable old_draw = aglGetDrawable((AGLContext)d->cx), new_draw = GetWindowPort(window);
- if (old_draw != new_draw)
- aglSetDrawable((AGLContext)d->cx, new_draw);
- }
-
- float scale = qt_mac_get_scale_factor(w);
-
- if (!w->isWindow()) {
- QRegion clp = qt_mac_get_widget_rgn(w); //get drawable area
-
-#ifdef DEBUG_OPENGL_REGION_UPDATE
- if (clp.isEmpty()) {
- qDebug(" Empty area!");
- } else {
- QVector<QRect> rs = clp.rects();
- for(int i = 0; i < rs.count(); i++)
- qDebug(" %d %d %d %d", rs[i].x(), rs[i].y(), rs[i].width(), rs[i].height());
- }
-#endif
- //update the clip
- if (!aglIsEnabled((AGLContext)d->cx, AGL_BUFFER_RECT))
- aglEnable((AGLContext)d->cx, AGL_BUFFER_RECT);
- if (clp.isEmpty()) {
- GLint offs[4] = { 0, 0, 0, 0 };
- aglSetInteger((AGLContext)d->cx, AGL_BUFFER_RECT, offs);
- if (aglIsEnabled((AGLContext)d->cx, AGL_CLIP_REGION))
- aglDisable((AGLContext)d->cx, AGL_CLIP_REGION);
- } else {
- HIPoint origin = { 0., 0. };
- HIViewConvertPoint(&origin, HIViewRef(w->winId()), 0);
- const GLint offs[4] = { qRound(origin.x),
- w->window()->frameGeometry().height() * scale
- - (qRound(origin.y) + w->height() * scale),
- w->width() * scale, w->height() * scale};
-
- RgnHandle region = clp.handle(true);
-
- if (scale != float(1)) {
- // Sacle the clip region by the scale factor
- Rect regionBounds;
- GetRegionBounds(region, &regionBounds);
- Rect regionBoundsDest = regionBounds;
- regionBoundsDest.bottom *= scale;
- regionBoundsDest.right *= scale;
- MapRgn(region, &regionBounds, &regionBoundsDest);
- }
-
- aglSetInteger((AGLContext)d->cx, AGL_BUFFER_RECT, offs);
- aglSetInteger((AGLContext)d->cx, AGL_CLIP_REGION, (const GLint *)region);
- if (!aglIsEnabled((AGLContext)d->cx, AGL_CLIP_REGION))
- aglEnable((AGLContext)d->cx, AGL_CLIP_REGION);
- }
- } else {
- // Set the buffer rect for top-level gl contexts when scaled.
- if (scale != float(1)) {
- aglEnable((AGLContext)d->cx, AGL_BUFFER_RECT);
- const GLint offs[4] = { 0, 0, w->width() * scale , w->height() * scale};
- aglSetInteger((AGLContext)d->cx, AGL_BUFFER_RECT, offs);
- }
- }
- } else if (d->paintDevice->devType() == QInternal::Pixmap) {
- QPixmap *pm = reinterpret_cast<QPixmap *>(d->paintDevice);
-
- unsigned long qdformat = k32ARGBPixelFormat;
- if (QSysInfo::ByteOrder == QSysInfo::LittleEndian)
- qdformat = k32BGRAPixelFormat;
- Rect rect;
- SetRect(&rect, 0, 0, pm->width(), pm->height());
-
- GWorldPtr gworld;
- NewGWorldFromPtr(&gworld, qdformat, &rect, 0, 0, 0,
- reinterpret_cast<char *>(qt_mac_pixmap_get_base(pm)),
- qt_mac_pixmap_get_bytes_per_line(pm));
-
- PixMapHandle pixmapHandle = GetGWorldPixMap(gworld);
- aglSetOffScreen(reinterpret_cast<AGLContext>(d->cx), pm->width(), pm->height(),
- GetPixRowBytes(pixmapHandle), GetPixBaseAddr(pixmapHandle));
- } else {
- qWarning("QGLContext::updatePaintDevice(): Not sure how to render OpenGL on this device!");
- }
- aglUpdateContext((AGLContext)d->cx);
-
-#else
- QMacCocoaAutoReleasePool pool;
-
- if (d->paintDevice->devType() == QInternal::Widget) {
- //get control information
- QWidget *w = (QWidget *)d->paintDevice;
- NSView *view = qt_mac_nativeview_for(w);
-
- // Trying to attach the GL context to the NSView will fail with
- // "invalid drawable" if done too soon, but we have to make sure
- // the connection is made before the first paint event. Using
- // the NSView do to this check fails as the NSView is visible
- // before it's safe to connect, and using the NSWindow fails as
- // the NSWindow will become visible after the first paint event.
- // This leaves us with the QWidget, who's visible state seems
- // to match the point in time when it's safe to connect.
- if (!w || !w->isVisible())
- return; // Not safe to attach GL context to view yet
-
- 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);
- [static_cast<NSOpenGLContext *>(d->cx) setOffScreen:qt_mac_pixmap_get_base(pm)
- width:pm->width()
- height:pm->height()
- rowbytes:qt_mac_pixmap_get_bytes_per_line(pm)];
- } else {
- qWarning("QGLContext::updatePaintDevice: Not sure how to render OpenGL on this device");
- }
- [static_cast<NSOpenGLContext *>(d->cx) update];
-#endif
-}
-
-void QGLContext::doneCurrent()
-{
-
- if (
-#ifndef QT_MAC_USE_COCOA
- aglGetCurrentContext() != (AGLContext) d_func()->cx
-#else
- [NSOpenGLContext currentContext] != d_func()->cx
-#endif
- )
- return;
-
- QGLContextPrivate::setCurrentContext(0);
-#ifndef QT_MAC_USE_COCOA
- aglSetCurrentContext(0);
-#else
- [NSOpenGLContext clearCurrentContext];
-#endif
-}
-
-void QGLContext::swapBuffers() const
-{
- Q_D(const QGLContext);
- if (!d->valid)
- return;
-#ifndef QT_MAC_USE_COCOA
- aglSwapBuffers((AGLContext)d->cx);
-#else
- [static_cast<NSOpenGLContext *>(d->cx) flushBuffer];
-#endif
-}
-
-QColor QGLContext::overlayTransparentColor() const
-{
- return QColor(0, 0, 0); // Invalid color
-}
-
-#ifndef QT_MAC_USE_COCOA
-static QColor cmap[256];
-static bool cmap_init = false;
-#endif
-uint QGLContext::colorIndex(const QColor &c) const
-{
-#ifndef QT_MAC_USE_COCOA
- int ret = -1;
- if(!cmap_init) {
- cmap_init = true;
- for(int i = 0; i < 256; i++)
- cmap[i] = QColor();
- } else {
- for(int i = 0; i < 256; i++) {
- if(cmap[i].isValid() && cmap[i] == c) {
- ret = i;
- break;
- }
- }
- }
- if(ret == -1) {
- for(ret = 0; ret < 256; ret++)
- if(!cmap[ret].isValid())
- break;
- if(ret == 256) {
- ret = -1;
- qWarning("QGLContext::colorIndex(): Internal error!");
- } else {
- cmap[ret] = c;
-
- GLint vals[4];
- vals[0] = ret;
- vals[1] = c.red();
- vals[2] = c.green();
- vals[3] = c.blue();
- aglSetInteger((AGLContext)d_func()->cx, AGL_COLORMAP_ENTRY, vals);
- }
- }
- return (uint)(ret == -1 ? 0 : ret);
-#else
- Q_UNUSED(c);
- return 0;
-#endif
-}
-
-void QGLContext::generateFontDisplayLists(const QFont & /* fnt */, int /* listBase */)
-{
-}
-
-static CFBundleRef qt_getOpenGLBundle()
-{
- CFBundleRef bundle = 0;
- CFStringRef urlString = QCFString::toCFStringRef(QLatin1String("/System/Library/Frameworks/OpenGL.framework"));
- QCFType<CFURLRef> url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
- urlString, kCFURLPOSIXPathStyle, false);
- if (url)
- bundle = CFBundleCreate(kCFAllocatorDefault, url);
- CFRelease(urlString);
- return bundle;
-}
-
-void *QGLContext::getProcAddress(const QString &proc) const
-{
- CFStringRef procName = QCFString(proc).toCFStringRef(proc);
- void *result = CFBundleGetFunctionPointerForName(QCFType<CFBundleRef>(qt_getOpenGLBundle()),
- procName);
- CFRelease(procName);
- return result;
-}
-#ifndef QT_MAC_USE_COCOA
-/*****************************************************************************
- QGLWidget AGL-specific code
- *****************************************************************************/
-
-/****************************************************************************
- Hacks to glue AGL to an HIView
- ***************************************************************************/
-QRegion qt_mac_get_widget_rgn(const QWidget *widget)
-{
- if(!widget->isVisible() || widget->isMinimized())
- return QRegion();
- const QRect wrect = QRect(qt_mac_posInWindow(widget), widget->size());
- if(!wrect.isValid())
- return QRegion();
-
- RgnHandle macr = qt_mac_get_rgn();
- GetControlRegion((HIViewRef)widget->winId(), kControlStructureMetaPart, macr);
- OffsetRgn(macr, wrect.x(), wrect.y());
- QRegion ret = qt_mac_convert_mac_region(macr);
-
- QPoint clip_pos = wrect.topLeft();
- for(const QWidget *last_clip = 0, *clip = widget; clip; last_clip = clip, clip = clip->parentWidget()) {
- if(clip != widget) {
- GetControlRegion((HIViewRef)clip->winId(), kControlStructureMetaPart, macr);
- OffsetRgn(macr, clip_pos.x(), clip_pos.y());
- ret &= qt_mac_convert_mac_region(macr);
- }
- const QObjectList &children = clip->children();
- for(int i = children.size()-1; i >= 0; --i) {
- if(QWidget *child = qobject_cast<QWidget*>(children.at(i))) {
- if(child == last_clip)
- break;
-
- // This check may seem weird, but when we are using a unified toolbar
- // The widget is actually being owned by that toolbar and not by Qt.
- // This means that the geometry it reports will be wrong
- // and will accidentally cause problems when calculating the region
- // So, it is better to skip these widgets since they aren't the hierarchy
- // anyway.
- if (HIViewGetSuperview(HIViewRef(child->winId())) != HIViewRef(clip->winId()))
- continue;
-
- if(child->isVisible() && !child->isMinimized() && !child->isTopLevel()) {
- const QRect childRect = QRect(clip_pos+child->pos(), child->size());
- if(childRect.isValid() && wrect.intersects(childRect)) {
- GetControlRegion((HIViewRef)child->winId(), kControlStructureMetaPart, macr);
- OffsetRgn(macr, childRect.x(), childRect.y());
- ret -= qt_mac_convert_mac_region(macr);
- }
- }
- }
- }
- if(clip->isWindow())
- break;
- clip_pos -= clip->pos();
- }
- qt_mac_dispose_rgn(macr);
- return ret;
-}
-
-#endif
-
-void QGLWidget::setMouseTracking(bool enable)
-{
- QWidget::setMouseTracking(enable);
-}
-
-void QGLWidget::resizeEvent(QResizeEvent *)
-{
- Q_D(QGLWidget);
- if (!isValid())
- return;
-#ifndef QT_MAC_USE_COCOA
- if (!isWindow())
- d->glcx->d_func()->update = true;
-#endif
- makeCurrent();
- if (!d->glcx->initialized())
- glInit();
-#ifdef QT_MAC_USE_COCOA
- d->glcx->updatePaintDevice();
-#endif
-#ifndef QT_MAC_USE_COCOA
- float scale = qt_mac_get_scale_factor(this);
- resizeGL(width() * scale, height() * scale);
-#else
- resizeGL(width(), height());
-#endif
-}
-
-const QGLContext* QGLWidget::overlayContext() const
-{
- return 0;
-}
-
-void QGLWidget::makeOverlayCurrent()
-{
-}
-
-void QGLWidget::updateOverlayGL()
-{
-}
-
-void QGLWidget::setContext(QGLContext *context, const QGLContext* shareContext, bool deleteOldContext)
-{
- Q_D(QGLWidget);
- if (context == 0) {
- qWarning("QGLWidget::setContext: Cannot set null context");
- return;
- }
-
- if (d->glcx)
- d->glcx->doneCurrent();
- QGLContext* oldcx = d->glcx;
- d->glcx = context;
- if (!d->glcx->isValid())
- d->glcx->create(shareContext ? shareContext : oldcx);
- if (deleteOldContext && oldcx)
- delete oldcx;
-}
-
-void QGLWidgetPrivate::init(QGLContext *context, const QGLWidget *shareWidget)
-{
- Q_Q(QGLWidget);
-
- initContext(context, shareWidget);
-
- QWidget *current = q;
- while (current) {
- qt_widget_private(current)->glWidgets.append(QWidgetPrivate::GlWidgetInfo(q));
- if (current->isWindow())
- break;
- current = current->parentWidget();
- }
-}
-
-bool QGLWidgetPrivate::renderCxPm(QPixmap*)
-{
- return false;
-}
-
-void QGLWidgetPrivate::cleanupColormaps()
-{
-}
-
-const QGLColormap & QGLWidget::colormap() const
-{
- return d_func()->cmap;
-}
-
-void QGLWidget::setColormap(const QGLColormap &)
-{
-}
-
-void QGLWidgetPrivate::updatePaintDevice()
-{
- Q_Q(QGLWidget);
- glcx->updatePaintDevice();
- q->update();
-}
-
-#endif
-
-QT_END_NAMESPACE
diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h
index 4c22f0f3d7..668728be20 100644
--- a/src/opengl/qgl_p.h
+++ b/src/opengl/qgl_p.h
@@ -60,24 +60,18 @@
#include "QtCore/qthreadstorage.h"
#include "QtCore/qhash.h"
#include "QtCore/qatomic.h"
-#include "private/qwidget_p.h"
+#include "QtWidgets/private/qwidget_p.h"
+#include "QtGui/private/qopenglcontext_p.h"
#include "qcache.h"
#include "qglpaintdevice_p.h"
-#ifndef QT_NO_EGL
-#include <QtGui/private/qegl_p.h>
-#endif
-
-#if defined(Q_WS_QPA)
-#include <QtGui/QPlatformGLContext>
-#endif
+#include <QtGui/QOpenGLContext>
QT_BEGIN_NAMESPACE
class QGLContext;
class QGLOverlayWidget;
class QPixmap;
-class QPixmapFilter;
#ifdef Q_WS_MAC
# ifdef qDebug
# define old_qDebug qDebug
@@ -96,14 +90,6 @@ QT_END_INCLUDE_NAMESPACE
class QMacWindowChangeEvent;
#endif
-#ifdef Q_WS_QWS
-class QWSGLWindowSurface;
-#endif
-
-#ifndef QT_NO_EGL
-class QEglContext;
-#endif
-
QT_BEGIN_INCLUDE_NAMESPACE
#include <QtOpenGL/private/qglextensions_p.h>
QT_END_INCLUDE_NAMESPACE
@@ -165,15 +151,6 @@ class Q_OPENGL_EXPORT QGLWidgetPrivate : public QWidgetPrivate
public:
QGLWidgetPrivate() : QWidgetPrivate()
, disable_clear_on_painter_begin(false)
-#if defined(Q_WS_QWS)
- , wsurf(0)
-#endif
-#if defined(Q_WS_X11) && !defined(QT_NO_EGL)
- , eglSurfaceWindowId(0)
-#endif
-#if defined(Q_OS_SYMBIAN)
- , eglSurfaceWindowId(0)
-#endif
{
isGLWidget = 1;
}
@@ -199,31 +176,8 @@ public:
#endif
bool disable_clear_on_painter_begin;
-
-#if defined(Q_WS_WIN)
- void updateColormap();
- QGLContext *olcx;
-#elif defined(Q_WS_X11)
- QGLOverlayWidget *olw;
-#ifndef QT_NO_EGL
- void recreateEglSurface();
- WId eglSurfaceWindowId;
-#endif
-#elif defined(Q_WS_MAC)
- QGLContext *olcx;
- void updatePaintDevice();
-#elif defined(Q_WS_QWS)
- QWSGLWindowSurface *wsurf;
-#endif
-#ifdef Q_OS_SYMBIAN
- void recreateEglSurface();
- WId eglSurfaceWindowId;
-#endif
};
-class QGLContextGroupResourceBase;
-class QGLSharedResourceGuard;
-
// QGLContextPrivate has the responsibility of creating context groups.
// QGLContextPrivate maintains the reference counter and destroys
// context groups when needed.
@@ -237,9 +191,6 @@ public:
bool isSharing() const { return m_shares.size() >= 2; }
QList<const QGLContext *> shares() const { return m_shares; }
- void addGuard(QGLSharedResourceGuard *guard);
- void removeGuard(QGLSharedResourceGuard *guard);
-
static void addShare(const QGLContext *context, const QGLContext *share);
static void removeShare(const QGLContext *context);
@@ -249,12 +200,8 @@ private:
QGLExtensionFuncs m_extensionFuncs;
const QGLContext *m_context; // context group's representative
QList<const QGLContext *> m_shares;
- QHash<QGLContextGroupResourceBase *, void *> m_resources;
- QGLSharedResourceGuard *m_guards; // double-linked list of active guards.
QAtomicInt m_refs;
- void cleanupResources(const QGLContext *ctx);
-
friend class QGLContext;
friend class QGLContextPrivate;
friend class QGLContextGroupResourceBase;
@@ -262,7 +209,7 @@ private:
// Get the context that resources for "ctx" will transfer to once
// "ctx" is destroyed. Returns null if nothing is sharing with ctx.
-Q_OPENGL_EXPORT const QGLContext *qt_gl_transfer_context(const QGLContext *);
+const QGLContext *qt_gl_transfer_context(const QGLContext *);
// GL extension definitions
class QGLExtensions {
@@ -351,54 +298,11 @@ public:
void syncGlState(); // Makes sure the GL context's state is what we think it is
void swapRegion(const QRegion &region);
-#if defined(Q_WS_WIN)
- void updateFormatVersion();
-#endif
+ QOpenGLContext *guiGlContext;
+ bool ownContext;
-#if defined(Q_WS_WIN)
- HGLRC rc;
- HDC dc;
- WId win;
- int pixelFormatId;
- QGLCmap* cmap;
- HBITMAP hbitmap;
- HDC hbitmap_hdc;
- Qt::HANDLE threadId;
-#endif
-#ifndef QT_NO_EGL
- QEglContext *eglContext;
- EGLSurface eglSurface;
- void destroyEglSurfaceForDevice();
- EGLSurface eglSurfaceForDevice() const;
- static QEglProperties *extraWindowSurfaceCreationProps;
- static void setExtraWindowSurfaceCreationProps(QEglProperties *props);
-#endif
-
-#if defined(Q_WS_QPA)
- QPlatformGLContext *platformContext;
void setupSharing();
-#elif defined(Q_WS_X11) || defined(Q_WS_MAC)
- void* cx;
-#endif
-#if defined(Q_WS_X11) || defined(Q_WS_MAC)
- void* vi;
-#endif
-#if defined(Q_WS_X11)
- void* pbuf;
- quint32 gpm;
- int screen;
- QHash<QPixmapData*, QPixmap> boundPixmaps;
- QGLTexture *bindTextureFromNativePixmap(QPixmap*, const qint64 key,
- QGLContext::BindOptions options);
- static void destroyGlSurfaceForPixmap(QPixmapData*);
- static void unbindPixmapFromTexture(QPixmapData*);
-#endif
-#if defined(Q_WS_MAC)
- bool update;
- void *tryFormat(const QGLFormat &format);
- void clearDrawable();
-#endif
QGLFormat glFormat;
QGLFormat reqFormat;
GLuint fbo;
@@ -423,10 +327,6 @@ public:
uint workaround_brokenAlphaTexSubImage : 1;
uint workaround_brokenAlphaTexSubImage_init : 1;
-#ifndef QT_NO_EGL
- uint ownsEglContext : 1;
-#endif
-
QPaintDevice *paintDevice;
QColor transpColor;
QGLContext *q_ptr;
@@ -439,7 +339,6 @@ public:
GLuint current_fbo;
GLuint default_fbo;
QPaintEngine *active_engine;
- QHash<QGLContextResourceBase *, void *> m_resources;
QGLTextureDestroyer *texture_destroyer;
QGLFunctions *functions;
@@ -448,14 +347,8 @@ public:
static inline QGLContextGroup *contextGroup(const QGLContext *ctx) { return ctx->d_ptr->group; }
-#ifdef Q_WS_WIN
- static inline QGLExtensionFuncs& extensionFuncs(const QGLContext *ctx) { return ctx->d_ptr->group->extensionFuncs(); }
-#endif
-
-#if defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QWS) || defined(Q_WS_QPA) || defined(Q_OS_SYMBIAN)
static Q_OPENGL_EXPORT QGLExtensionFuncs qt_extensionFuncs;
static Q_OPENGL_EXPORT QGLExtensionFuncs& extensionFuncs(const QGLContext *);
-#endif
static void setCurrentContext(QGLContext *context);
};
@@ -508,34 +401,19 @@ class Q_OPENGL_EXPORT QGLTextureDestroyer : public QObject
public:
QGLTextureDestroyer() : QObject() {
qRegisterMetaType<GLuint>("GLuint");
- connect(this, SIGNAL(freeTexture(QGLContext *, QPixmapData *, GLuint)),
- this, SLOT(freeTexture_slot(QGLContext *, QPixmapData *, GLuint)));
+ connect(this, SIGNAL(freeTexture(QGLContext *, QPlatformPixmap *, GLuint)),
+ this, SLOT(freeTexture_slot(QGLContext *, QPlatformPixmap *, GLuint)));
}
- void emitFreeTexture(QGLContext *context, QPixmapData *boundPixmap, GLuint id) {
+ void emitFreeTexture(QGLContext *context, QPlatformPixmap *boundPixmap, GLuint id) {
emit freeTexture(context, boundPixmap, id);
}
Q_SIGNALS:
- void freeTexture(QGLContext *context, QPixmapData *boundPixmap, GLuint id);
+ void freeTexture(QGLContext *context, QPlatformPixmap *boundPixmap, GLuint id);
private slots:
- void freeTexture_slot(QGLContext *context, QPixmapData *boundPixmap, GLuint id) {
+ void freeTexture_slot(QGLContext *context, QPlatformPixmap *boundPixmap, GLuint id) {
Q_UNUSED(boundPixmap);
-#if defined(Q_WS_X11)
- if (boundPixmap) {
- QGLContext *oldContext = const_cast<QGLContext *>(QGLContext::currentContext());
- context->makeCurrent();
- // Although glXReleaseTexImage is a glX call, it must be called while there
- // is a current context - the context the pixmap was bound to a texture in.
- // Otherwise the release doesn't do anything and you get BadDrawable errors
- // when you come to delete the context.
- QGLContextPrivate::unbindPixmapFromTexture(boundPixmap);
- glDeleteTextures(1, &id);
- if (oldContext)
- oldContext->makeCurrent();
- return;
- }
-#endif
QGLShareContextScope scope(context);
glDeleteTextures(1, &id);
}
@@ -562,17 +440,12 @@ public:
id(tx_id),
target(tx_target),
options(opt)
-#if defined(Q_WS_X11)
- , boundPixmap(0)
-#endif
{}
~QGLTexture() {
if (options & QGLContext::MemoryManagedBindOption) {
Q_ASSERT(context);
-#if !defined(Q_WS_X11)
- QPixmapData *boundPixmap = 0;
-#endif
+ QPlatformPixmap *boundPixmap = 0;
context->d_ptr->texture_destroyer->emitFreeTexture(context, boundPixmap, id);
}
}
@@ -583,10 +456,6 @@ public:
QGLContext::BindOptions options;
-#if defined(Q_WS_X11)
- QPixmapData* boundPixmap;
-#endif
-
bool canBindCompressedTexture
(const char *buf, int len, const char *format, bool *hasAlpha);
QSize bindCompressedTexture
@@ -629,8 +498,8 @@ public:
void removeContextTextures(QGLContext *ctx);
static QGLTextureCache *instance();
static void cleanupTexturesForCacheKey(qint64 cacheKey);
- static void cleanupTexturesForPixampData(QPixmapData* pixmap);
- static void cleanupBeforePixmapDestruction(QPixmapData* pixmap);
+ static void cleanupTexturesForPixampData(QPlatformPixmap* pixmap);
+ static void cleanupBeforePixmapDestruction(QPlatformPixmap* pixmap);
private:
QCache<QGLTextureCacheKey, QGLTexture> m_cache;
@@ -661,199 +530,71 @@ QGLTexture* QGLTextureCache::getTexture(QGLContext *ctx, qint64 key)
return m_cache.object(cacheKey);
}
-extern Q_OPENGL_EXPORT QPaintEngine* qt_qgl_paint_engine();
-
-bool qt_gl_preferGL2Engine();
-
-inline GLenum qt_gl_preferredTextureFormat()
-{
- return (QGLExtensions::glExtensions() & QGLExtensions::BGRATextureFormat) && QSysInfo::ByteOrder == QSysInfo::LittleEndian
- ? GL_BGRA : GL_RGBA;
-}
-
-inline GLenum qt_gl_preferredTextureTarget()
-{
-#if defined(QT_OPENGL_ES_2)
- return GL_TEXTURE_2D;
-#else
- return (QGLExtensions::glExtensions() & QGLExtensions::TextureRectangle)
- && !qt_gl_preferGL2Engine()
- ? GL_TEXTURE_RECTANGLE_NV
- : GL_TEXTURE_2D;
-#endif
-}
+extern QPaintEngine* qt_qgl_paint_engine();
-/*
- Base for resources that are shared in a context group.
-*/
-class Q_OPENGL_EXPORT QGLContextGroupResourceBase
-{
-public:
- QGLContextGroupResourceBase();
- virtual ~QGLContextGroupResourceBase();
- void insert(const QGLContext *context, void *value);
- void *value(const QGLContext *context);
- void cleanup(const QGLContext *context);
- void cleanup(const QGLContext *context, void *value);
- virtual void freeResource(void *value) = 0;
-
-protected:
- QList<QGLContextGroup *> m_groups;
-
-private:
- QAtomicInt active;
-};
-
-/*
- The QGLContextGroupResource template is used to manage a resource
- for a group of sharing GL contexts. When the last context in the
- group is destroyed, or when the QGLContextGroupResource object
- itself is destroyed (implies potential context switches), the
- resource will be freed.
-
- The class used as the template class type needs to have a
- constructor with the following signature:
- T(const QGLContext *);
-*/
-template <class T>
-class QGLContextGroupResource : public QGLContextGroupResourceBase
+// Put a guard around a GL object identifier and its context.
+// When the context goes away, a shared context will be used
+// in its place. If there are no more shared contexts, then
+// the identifier is returned as zero - it is assumed that the
+// context destruction cleaned up the identifier in this case.
+class QGLSharedResourceGuardBase : public QOpenGLSharedResource
{
public:
- ~QGLContextGroupResource() {
- for (int i = 0; i < m_groups.size(); ++i) {
- const QGLContext *context = m_groups.at(i)->context();
- T *resource = reinterpret_cast<T *>(QGLContextGroupResourceBase::value(context));
- if (resource) {
- QGLShareContextScope scope(context);
- delete resource;
- }
- }
+ QGLSharedResourceGuardBase(QGLContext *context, GLuint id)
+ : QOpenGLSharedResource(context->contextHandle()->shareGroup())
+ , m_id(id)
+ {
}
- T *value(const QGLContext *context) {
- T *resource = reinterpret_cast<T *>(QGLContextGroupResourceBase::value(context));
- if (!resource) {
- resource = new T(context);
- insert(context, resource);
- }
- return resource;
+ GLuint id() const
+ {
+ return m_id;
}
protected:
- void freeResource(void *resource) {
- delete reinterpret_cast<T *>(resource);
- }
-};
-
-/*
- Base for resources that are context specific.
-*/
-class Q_OPENGL_EXPORT QGLContextResourceBase
-{
-public:
- virtual ~QGLContextResourceBase() {
- for (int i = 0; i < m_contexts.size(); ++i)
- m_contexts.at(i)->d_ptr->m_resources.remove(this);
- }
-
- void insert(const QGLContext *context, void *value) {
- context->d_ptr->m_resources.insert(this, value);
- }
-
- void *value(const QGLContext *context) {
- return context->d_ptr->m_resources.value(this, 0);
+ void invalidateResource()
+ {
+ m_id = 0;
}
- virtual void freeResource(void *value) = 0;
-protected:
- QList<const QGLContext *> m_contexts;
-};
-
-/*
- The QGLContextResource template is used to manage a resource for a
- single GL context. Just before the context is destroyed (while it's
- still the current context), or when the QGLContextResource object
- itself is destroyed (implies potential context switches), the
- resource will be freed. The class used as the template class type
- needs to have a constructor with the following signature: T(const
- QGLContext *);
-*/
-template <class T>
-class QGLContextResource : public QGLContextResourceBase
-{
-public:
- ~QGLContextResource() {
- for (int i = 0; i < m_contexts.size(); ++i) {
- const QGLContext *context = m_contexts.at(i);
- T *resource = reinterpret_cast<T *>(QGLContextResourceBase::value(context));
- if (resource) {
- QGLShareContextScope scope(context);
- delete resource;
- }
+ void freeResource(QOpenGLContext *context)
+ {
+ if (m_id) {
+ freeResource(QGLContext::fromOpenGLContext(context), m_id);
}
}
- T *value(const QGLContext *context) {
- T *resource = reinterpret_cast<T *>(QGLContextResourceBase::value(context));
- if (!resource) {
- resource = new T(context);
- insert(context, resource);
- }
- return resource;
- }
+ virtual void freeResource(QGLContext *ctx, GLuint id) = 0;
-protected:
- void freeResource(void *resource) {
- delete reinterpret_cast<T *>(resource);
- }
+private:
+ GLuint m_id;
};
-// Put a guard around a GL object identifier and its context.
-// When the context goes away, a shared context will be used
-// in its place. If there are no more shared contexts, then
-// the identifier is returned as zero - it is assumed that the
-// context destruction cleaned up the identifier in this case.
-class Q_OPENGL_EXPORT QGLSharedResourceGuard
+template <typename Func>
+class QGLSharedResourceGuard : public QGLSharedResourceGuardBase
{
public:
- QGLSharedResourceGuard(const QGLContext *context)
- : m_group(0), m_id(0), m_next(0), m_prev(0)
- {
- setContext(context);
- }
- QGLSharedResourceGuard(const QGLContext *context, GLuint id)
- : m_group(0), m_id(id), m_next(0), m_prev(0)
+ QGLSharedResourceGuard(QGLContext *context, GLuint id, Func func)
+ : QGLSharedResourceGuardBase(context, id)
+ , m_func(func)
{
- setContext(context);
}
- ~QGLSharedResourceGuard();
- const QGLContext *context() const
- {
- return m_group ? m_group->context() : 0;
- }
-
- void setContext(const QGLContext *context);
-
- GLuint id() const
- {
- return m_id;
- }
-
- void setId(GLuint id)
+protected:
+ void freeResource(QGLContext *ctx, GLuint id)
{
- m_id = id;
+ m_func(ctx, id);
}
private:
- QGLContextGroup *m_group;
- GLuint m_id;
- QGLSharedResourceGuard *m_next;
- QGLSharedResourceGuard *m_prev;
-
- friend class QGLContextGroup;
+ Func m_func;
};
+template <typename Func>
+QGLSharedResourceGuardBase *createSharedResourceGuard(QGLContext *context, GLuint id, Func cleanupFunc)
+{
+ return new QGLSharedResourceGuard<Func>(context, id, cleanupFunc);
+}
class QGLExtensionMatcher
{
diff --git a/src/opengl/qgl_qpa.cpp b/src/opengl/qgl_qpa.cpp
index 9ba8b75362..afa2772a6f 100644
--- a/src/opengl/qgl_qpa.cpp
+++ b/src/opengl/qgl_qpa.cpp
@@ -40,12 +40,14 @@
****************************************************************************/
#include <QApplication>
-#include <QtGui/private/qapplication_p.h>
+#include <private/qapplication_p.h>
#include <QPixmap>
#include <QDebug>
-#include <QtGui/private/qapplication_p.h>
+#include <private/qapplication_p.h>
+#include <QtGui/QPlatformOpenGLContext>
#include <QtGui/QPlatformWindow>
+#include <QtGui/QSurfaceFormat>
#include "qgl.h"
#include "qgl_p.h"
@@ -53,81 +55,66 @@
QT_BEGIN_NAMESPACE
/*!
- Returns an OpenGL format for the platform window format specified by \a format.
+ Returns an OpenGL format for the window format specified by \a format.
*/
-QGLFormat QGLFormat::fromPlatformWindowFormat(const QPlatformWindowFormat &format)
+QGLFormat QGLFormat::fromSurfaceFormat(const QSurfaceFormat &format)
{
QGLFormat retFormat;
- retFormat.setAccum(format.accum());
- if (format.accumBufferSize() >= 0)
- retFormat.setAccumBufferSize(format.accumBufferSize());
- retFormat.setAlpha(format.alpha());
if (format.alphaBufferSize() >= 0)
retFormat.setAlphaBufferSize(format.alphaBufferSize());
if (format.blueBufferSize() >= 0)
retFormat.setBlueBufferSize(format.blueBufferSize());
- retFormat.setDepth(format.depth());
- if (format.depthBufferSize() >= 0)
- retFormat.setDepthBufferSize(format.depthBufferSize());
- retFormat.setDirectRendering(format.directRendering());
- retFormat.setDoubleBuffer(format.doubleBuffer());
if (format.greenBufferSize() >= 0)
retFormat.setGreenBufferSize(format.greenBufferSize());
if (format.redBufferSize() >= 0)
retFormat.setRedBufferSize(format.redBufferSize());
- retFormat.setRgba(format.rgba());
- retFormat.setSampleBuffers(format.sampleBuffers());
- retFormat.setSamples(format.sampleBuffers());
- retFormat.setStencil(format.stencil());
- if (format.stencilBufferSize() >= 0)
+ if (format.depthBufferSize() >= 0)
+ retFormat.setDepthBufferSize(format.depthBufferSize());
+ if (format.samples() > 1) {
+ retFormat.setSampleBuffers(format.samples());
+ retFormat.setSamples(true);
+ }
+ if (format.stencilBufferSize() > 0) {
+ retFormat.setStencil(true);
retFormat.setStencilBufferSize(format.stencilBufferSize());
+ }
+ retFormat.setDoubleBuffer(format.swapBehavior() != QSurfaceFormat::SingleBuffer);
retFormat.setStereo(format.stereo());
- retFormat.setSwapInterval(format.swapInterval());
return retFormat;
}
/*!
- Returns a platform window format for the OpenGL format specified by \a format.
+ Returns a window format for the OpenGL format specified by \a format.
*/
-QPlatformWindowFormat QGLFormat::toPlatformWindowFormat(const QGLFormat &format)
+QSurfaceFormat QGLFormat::toSurfaceFormat(const QGLFormat &format)
{
- QPlatformWindowFormat retFormat;
- retFormat.setAccum(format.accum());
- if (format.accumBufferSize() >= 0)
- retFormat.setAccumBufferSize(format.accumBufferSize());
- retFormat.setAlpha(format.alpha());
- if (format.alphaBufferSize() >= 0)
- retFormat.setAlphaBufferSize(format.alphaBufferSize());
+ QSurfaceFormat retFormat;
+ if (format.alpha())
+ retFormat.setAlphaBufferSize(format.alphaBufferSize() == -1 ? 1 : format.alphaBufferSize());
if (format.blueBufferSize() >= 0)
retFormat.setBlueBufferSize(format.blueBufferSize());
- retFormat.setDepth(format.depth());
- if (format.depthBufferSize() >= 0)
- retFormat.setDepthBufferSize(format.depthBufferSize());
- retFormat.setDirectRendering(format.directRendering());
- retFormat.setDoubleBuffer(format.doubleBuffer());
if (format.greenBufferSize() >= 0)
retFormat.setGreenBufferSize(format.greenBufferSize());
if (format.redBufferSize() >= 0)
retFormat.setRedBufferSize(format.redBufferSize());
- retFormat.setRgba(format.rgba());
- retFormat.setSampleBuffers(format.sampleBuffers());
- if (format.samples() >= 0)
- retFormat.setSamples(format.samples());
- retFormat.setStencil(format.stencil());
- if (format.stencilBufferSize() >= 0)
- retFormat.setStencilBufferSize(format.stencilBufferSize());
+ if (format.depth())
+ retFormat.setDepthBufferSize(format.depthBufferSize() == -1 ? 1 : format.depthBufferSize());
+ retFormat.setSwapBehavior(format.doubleBuffer() ? QSurfaceFormat::DoubleBuffer : QSurfaceFormat::DefaultSwapBehavior);
+ if (format.sampleBuffers())
+ retFormat.setSamples(format.samples() == -1 ? 4 : format.samples());
+ if (format.stencil())
+ retFormat.setStencilBufferSize(format.stencilBufferSize() == -1 ? 1 : format.stencilBufferSize());
retFormat.setStereo(format.stereo());
- retFormat.setSwapInterval(format.swapInterval());
return retFormat;
}
void QGLContextPrivate::setupSharing() {
Q_Q(QGLContext);
- QPlatformGLContext *sharedPlatformGLContext = platformContext->platformWindowFormat().sharedGLContext();
- if (sharedPlatformGLContext) {
- QGLContext *actualSharedContext = QGLContext::fromPlatformGLContext(sharedPlatformGLContext);
+ QOpenGLContext *sharedContext = guiGlContext->shareContext();
+ if (sharedContext) {
+ QGLContext *actualSharedContext = QGLContext::fromOpenGLContext(sharedContext);
sharing = true;
- QGLContextGroup::addShare(q,actualSharedContext);
+ QGLContextGroup::addShare(q, actualSharedContext);
}
}
@@ -150,26 +137,30 @@ bool QGLContext::chooseContext(const QGLContext* shareContext)
d->valid = false;
}else {
QWidget *widget = static_cast<QWidget *>(d->paintDevice);
- if (!widget->platformWindow()){
- QGLFormat glformat = format();
- QPlatformWindowFormat winFormat = QGLFormat::toPlatformWindowFormat(glformat);
- if (shareContext) {
- winFormat.setSharedContext(shareContext->d_func()->platformContext);
- }
- if (widget->testAttribute(Qt::WA_TranslucentBackground))
- winFormat.setAlpha(true);
- winFormat.setWindowApi(QPlatformWindowFormat::OpenGL);
- winFormat.setWindowSurface(false);
- widget->setPlatformWindowFormat(winFormat);
+ QGLFormat glformat = format();
+ QSurfaceFormat winFormat = QGLFormat::toSurfaceFormat(glformat);
+ if (widget->testAttribute(Qt::WA_TranslucentBackground))
+ winFormat.setAlphaBufferSize(qMax(winFormat.alphaBufferSize(), 8));
+
+ if (!widget->windowHandle()->handle()) {
+ widget->windowHandle()->setSurfaceType(QWindow::OpenGLSurface);
+ widget->windowHandle()->setFormat(winFormat);
widget->winId();//make window
}
- d->platformContext = widget->platformWindow()->glContext();
- Q_ASSERT(d->platformContext);
- d->glFormat = QGLFormat::fromPlatformWindowFormat(d->platformContext->platformWindowFormat());
- d->valid =(bool) d->platformContext;
- if (d->valid) {
- d->platformContext->setQGLContextHandle(this,qDeleteQGLContext);
- }
+
+ if (d->ownContext)
+ delete d->guiGlContext;
+ d->ownContext = true;
+ QOpenGLContext *shareGlContext = shareContext ? shareContext->d_func()->guiGlContext : 0;
+ d->guiGlContext = new QOpenGLContext;
+ d->guiGlContext->setFormat(winFormat);
+ d->guiGlContext->setShareContext(shareGlContext);
+ d->valid = d->guiGlContext->create();
+
+ if (d->valid)
+ d->guiGlContext->setQGLContextHandle(this,qDeleteQGLContext);
+
+ d->glFormat = QGLFormat::fromSurfaceFormat(d->guiGlContext->format());
d->setupSharing();
}
@@ -190,42 +181,60 @@ void QGLContext::reset()
d->transpColor = QColor();
d->initDone = false;
QGLContextGroup::removeShare(this);
- if (d->platformContext) {
- d->platformContext->setQGLContextHandle(0,0);
+ if (d->guiGlContext) {
+ if (d->ownContext)
+ delete d->guiGlContext;
+ else
+ d->guiGlContext->setQGLContextHandle(0,0);
+ d->guiGlContext = 0;
}
+ d->ownContext = false;
}
void QGLContext::makeCurrent()
{
Q_D(QGLContext);
- d->platformContext->makeCurrent();
+ if (!d->paintDevice || d->paintDevice->devType() != QInternal::Widget)
+ return;
+
+ QWidget *widget = static_cast<QWidget *>(d->paintDevice);
+ if (!widget->windowHandle())
+ return;
- if (!d->workaroundsCached) {
- d->workaroundsCached = true;
- const char *renderer = reinterpret_cast<const char *>(glGetString(GL_RENDERER));
- if (renderer && strstr(renderer, "Mali")) {
- d->workaround_brokenFBOReadBack = true;
+ if (d->guiGlContext->makeCurrent(widget->windowHandle())) {
+ if (!d->workaroundsCached) {
+ d->workaroundsCached = true;
+ const char *renderer = reinterpret_cast<const char *>(glGetString(GL_RENDERER));
+ if (renderer && strstr(renderer, "Mali")) {
+ d->workaround_brokenFBOReadBack = true;
+ }
}
}
-
}
void QGLContext::doneCurrent()
{
Q_D(QGLContext);
- d->platformContext->doneCurrent();
+ d->guiGlContext->doneCurrent();
}
void QGLContext::swapBuffers() const
{
Q_D(const QGLContext);
- d->platformContext->swapBuffers();
+ if (!d->paintDevice || d->paintDevice->devType() != QInternal::Widget)
+ return;
+
+ QWidget *widget = static_cast<QWidget *>(d->paintDevice);
+ if (!widget->windowHandle())
+ return;
+
+ d->guiGlContext->swapBuffers(widget->windowHandle());
}
void *QGLContext::getProcAddress(const QString &procName) const
{
Q_D(const QGLContext);
- return d->platformContext->getProcAddress(procName);
+ return (void *)d->guiGlContext->getProcAddress(procName.toAscii());
}
void QGLWidget::setContext(QGLContext *context,
@@ -283,33 +292,34 @@ void QGLContext::generateFontDisplayLists(const QFont & fnt, int listBase)
class QGLTemporaryContextPrivate
{
public:
- QWidget *widget;
- QPlatformGLContext *context;
+ QWindow *window;
+ QOpenGLContext *context;
+
+ QGLContext *oldContext;
};
QGLTemporaryContext::QGLTemporaryContext(bool, QWidget *)
: d(new QGLTemporaryContextPrivate)
{
- d->context = const_cast<QPlatformGLContext *>(QPlatformGLContext::currentContext());
- if (d->context)
- d->context->doneCurrent();
- d->widget = new QWidget;
- d->widget->setGeometry(0,0,3,3);
- QPlatformWindowFormat format = d->widget->platformWindowFormat();
- format.setWindowApi(QPlatformWindowFormat::OpenGL);
- format.setWindowSurface(false);
- d->widget->setPlatformWindowFormat(format);
- d->widget->winId();
+ d->oldContext = const_cast<QGLContext *>(QGLContext::currentContext());
- d->widget->platformWindow()->glContext()->makeCurrent();
+ d->window = new QWindow;
+ d->window->setSurfaceType(QWindow::OpenGLSurface);
+ d->window->setGeometry(QRect(0, 0, 3, 3));
+ d->window->create();
+
+ d->context = new QOpenGLContext;
+ d->context->create();
+ d->context->makeCurrent(d->window);
}
QGLTemporaryContext::~QGLTemporaryContext()
{
- d->widget->platformWindow()->glContext()->doneCurrent();
- if (d->context)
- d->context->makeCurrent();
- delete d->widget;
+ if (d->oldContext)
+ d->oldContext->makeCurrent();
+
+ delete d->context;
+ delete d->window;
}
@@ -375,29 +385,35 @@ void QGLWidget::setColormap(const QGLColormap & c)
Q_UNUSED(c);
}
-QGLContext::QGLContext(QPlatformGLContext *platformContext)
+QGLContext::QGLContext(QOpenGLContext *context)
: d_ptr(new QGLContextPrivate(this))
{
Q_D(QGLContext);
- d->init(0,QGLFormat::fromPlatformWindowFormat(platformContext->platformWindowFormat()));
- d->platformContext = platformContext;
- d->platformContext->setQGLContextHandle(this,qDeleteQGLContext);
- d->valid = true;
+ d->init(0, QGLFormat::fromSurfaceFormat(context->format()));
+ d->guiGlContext = context;
+ d->guiGlContext->setQGLContextHandle(this,qDeleteQGLContext);
+ d->ownContext = false;
+ d->valid = context->isValid();
d->setupSharing();
}
+QOpenGLContext *QGLContext::contextHandle() const
+{
+ Q_D(const QGLContext);
+ return d->guiGlContext;
+}
+
/*!
- Returns a OpenGL context for the platform-specific OpenGL context given by
- \a platformContext.
+ Returns a OpenGL context for the window context specified by \a windowContext
*/
-QGLContext *QGLContext::fromPlatformGLContext(QPlatformGLContext *platformContext)
+QGLContext *QGLContext::fromOpenGLContext(QOpenGLContext *context)
{
- if (!platformContext)
+ if (!context)
return 0;
- if (platformContext->qGLContextHandle()) {
- return reinterpret_cast<QGLContext *>(platformContext->qGLContextHandle());
+ if (context->qGLContextHandle()) {
+ return reinterpret_cast<QGLContext *>(context->qGLContextHandle());
}
- QGLContext *glContext = new QGLContext(platformContext);
+ QGLContext *glContext = new QGLContext(context);
//Dont call create on context. This can cause the platformFormat to be set on the widget, which
//will cause the platformWindow to be recreated.
return glContext;
diff --git a/src/opengl/qgl_qws.cpp b/src/opengl/qgl_qws.cpp
deleted file mode 100644
index c0844786e2..0000000000
--- a/src/opengl/qgl_qws.cpp
+++ /dev/null
@@ -1,318 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qgl.h"
-#include "qgl_egl_p.h"
-#include "qglpixelbuffer.h"
-
-#include <qglscreen_qws.h>
-#include <qscreenproxy_qws.h>
-#include <private/qglwindowsurface_qws_p.h>
-
-#include <private/qbackingstore_p.h>
-#include <private/qfont_p.h>
-#include <private/qfontengine_p.h>
-#include <private/qgl_p.h>
-#include <private/qpaintengine_opengl_p.h>
-#include <qpixmap.h>
-#include <qtimer.h>
-#include <qapplication.h>
-#include <qstack.h>
-#include <qdesktopwidget.h>
-#include <qdebug.h>
-#include <qvarlengtharray.h>
-
-QT_BEGIN_NAMESPACE
-
-static QGLScreen *glScreenForDevice(QPaintDevice *device)
-{
- QScreen *screen = qt_screen;
- if (screen->classId() == QScreen::MultiClass) {
- int screenNumber;
- if (device && device->devType() == QInternal::Widget)
- screenNumber = qApp->desktop()->screenNumber(static_cast<QWidget *>(device));
- else
- screenNumber = 0;
- screen = screen->subScreens()[screenNumber];
- }
- while (screen->classId() == QScreen::ProxyClass ||
- screen->classId() == QScreen::TransformedClass) {
- screen = static_cast<QProxyScreen *>(screen)->screen();
- }
- if (screen->classId() == QScreen::GLClass)
- return static_cast<QGLScreen *>(screen);
- else
- return 0;
-}
-
-/*
- QGLTemporaryContext implementation
-*/
-
-class QGLTemporaryContextPrivate
-{
-public:
- QGLWidget *widget;
-};
-
-QGLTemporaryContext::QGLTemporaryContext(bool, QWidget *)
- : d(new QGLTemporaryContextPrivate)
-{
- d->widget = new QGLWidget;
- d->widget->makeCurrent();
-}
-
-QGLTemporaryContext::~QGLTemporaryContext()
-{
- delete d->widget;
-}
-
-/*****************************************************************************
- QOpenGL debug facilities
- *****************************************************************************/
-//#define DEBUG_OPENGL_REGION_UPDATE
-
-bool QGLFormat::hasOpenGLOverlays()
-{
- QGLScreen *glScreen = glScreenForDevice(0);
- if (glScreen)
- return (glScreen->options() & QGLScreen::Overlays);
- else
- return false;
-}
-
-static EGLSurface qt_egl_create_surface
- (QEglContext *context, QPaintDevice *device,
- const QEglProperties *properties = 0)
-{
- // Get the screen surface functions, which are used to create native ids.
- QGLScreen *glScreen = glScreenForDevice(device);
- if (!glScreen)
- return EGL_NO_SURFACE;
- QGLScreenSurfaceFunctions *funcs = glScreen->surfaceFunctions();
- if (!funcs)
- return EGL_NO_SURFACE;
-
- // Create the native drawable for the paint device.
- int devType = device->devType();
- EGLNativePixmapType pixmapDrawable = 0;
- EGLNativeWindowType windowDrawable = 0;
- bool ok;
- if (devType == QInternal::Pixmap) {
- ok = funcs->createNativePixmap(static_cast<QPixmap *>(device), &pixmapDrawable);
- } else if (devType == QInternal::Image) {
- ok = funcs->createNativeImage(static_cast<QImage *>(device), &pixmapDrawable);
- } else {
- ok = funcs->createNativeWindow(static_cast<QWidget *>(device), &windowDrawable);
- }
- if (!ok) {
- qWarning("QEglContext::createSurface(): Cannot create the native EGL drawable");
- return EGL_NO_SURFACE;
- }
-
- // Create the EGL surface to draw into, based on the native drawable.
- const int *props;
- if (properties)
- props = properties->properties();
- else
- props = 0;
- EGLSurface surf;
- if (devType == QInternal::Widget) {
- surf = eglCreateWindowSurface
- (context->display(), context->config(), windowDrawable, props);
- } else {
- surf = eglCreatePixmapSurface
- (context->display(), context->config(), pixmapDrawable, props);
- }
- if (surf == EGL_NO_SURFACE)
- qWarning("QEglContext::createSurface(): Unable to create EGL surface, error = 0x%x", eglGetError());
- return surf;
-}
-
-bool QGLContext::chooseContext(const QGLContext* shareContext)
-{
- Q_D(QGLContext);
-
- // Validate the device.
- if (!device())
- return false;
- int devType = device()->devType();
- if (devType != QInternal::Pixmap && devType != QInternal::Image && devType != QInternal::Widget) {
- qWarning("QGLContext::chooseContext(): Cannot create QGLContext's for paint device type %d", devType);
- return false;
- }
-
- // Get the display and initialize it.
- d->eglContext = new QEglContext();
- d->ownsEglContext = true;
- d->eglContext->setApi(QEgl::OpenGL);
-
- // Construct the configuration we need for this surface.
- QEglProperties configProps;
- qt_eglproperties_set_glformat(configProps, d->glFormat);
- configProps.setDeviceType(devType);
- configProps.setPaintDeviceFormat(device());
- configProps.setRenderableType(QEgl::OpenGL);
-
- // Search for a matching configuration, reducing the complexity
- // each time until we get something that matches.
- if (!d->eglContext->chooseConfig(configProps)) {
- delete d->eglContext;
- d->eglContext = 0;
- return false;
- }
-
- // Inform the higher layers about the actual format properties.
- qt_glformat_from_eglconfig(d->glFormat, d->eglContext->config());
-
- // Create a new context for the configuration.
- if (!d->eglContext->createContext
- (shareContext ? shareContext->d_func()->eglContext : 0)) {
- delete d->eglContext;
- d->eglContext = 0;
- return false;
- }
- d->sharing = d->eglContext->isSharing();
- if (d->sharing && shareContext)
- const_cast<QGLContext *>(shareContext)->d_func()->sharing = true;
-
-#if defined(EGL_VERSION_1_1)
- if (d->glFormat.swapInterval() != -1 && devType == QInternal::Widget)
- eglSwapInterval(d->eglContext->display(), d->glFormat.swapInterval());
-#endif
-
- // Create the EGL surface to draw into. We cannot use
- // QEglContext::createSurface() because it does not have
- // access to the QGLScreen.
- d->eglSurface = qt_egl_create_surface(d->eglContext, device());
- if (d->eglSurface == EGL_NO_SURFACE) {
- delete d->eglContext;
- d->eglContext = 0;
- return false;
- }
-
- return true;
-}
-
-
-bool QGLWidget::event(QEvent *e)
-{
- return QWidget::event(e);
-}
-
-
-void QGLWidget::resizeEvent(QResizeEvent *)
-{
- Q_D(QGLWidget);
- if (!isValid())
- return;
- makeCurrent();
- if (!d->glcx->initialized())
- glInit();
- resizeGL(width(), height());
- //handle overlay
-}
-
-const QGLContext* QGLWidget::overlayContext() const
-{
- return 0;
-}
-
-void QGLWidget::makeOverlayCurrent()
-{
- //handle overlay
-}
-
-void QGLWidget::updateOverlayGL()
-{
- //handle overlay
-}
-
-void QGLWidget::setContext(QGLContext *context, const QGLContext* shareContext, bool deleteOldContext)
-{
- Q_D(QGLWidget);
- if(context == 0) {
- qWarning("QGLWidget::setContext: Cannot set null context");
- return;
- }
-
- if(d->glcx)
- d->glcx->doneCurrent();
- QGLContext* oldcx = d->glcx;
- d->glcx = context;
- if(!d->glcx->isValid())
- d->glcx->create(shareContext ? shareContext : oldcx);
- if(deleteOldContext)
- delete oldcx;
-}
-
-void QGLWidgetPrivate::init(QGLContext *context, const QGLWidget* shareWidget)
-{
- Q_Q(QGLWidget);
-
- QGLScreen *glScreen = glScreenForDevice(q);
- if (glScreen) {
- wsurf = static_cast<QWSGLWindowSurface*>(glScreen->createSurface(q));
- q->setWindowSurface(wsurf);
- }
-
- initContext(context, shareWidget);
-
- if(q->isValid() && glcx->format().hasOverlay()) {
- //no overlay
- qWarning("QtOpenGL ES doesn't currently support overlays");
- }
-}
-
-void QGLWidgetPrivate::cleanupColormaps()
-{
-}
-
-const QGLColormap & QGLWidget::colormap() const
-{
- return d_func()->cmap;
-}
-
-void QGLWidget::setColormap(const QGLColormap &)
-{
-}
-
-QT_END_NAMESPACE
diff --git a/src/opengl/qgl_symbian.cpp b/src/opengl/qgl_symbian.cpp
deleted file mode 100644
index bc65bcd44a..0000000000
--- a/src/opengl/qgl_symbian.cpp
+++ /dev/null
@@ -1,472 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#include "qgl.h"
-#include <fbs.h>
-#include <private/qt_s60_p.h>
-#include <private/qpixmap_s60_p.h>
-#include <private/qimagepixmapcleanuphooks_p.h>
-#include <private/qgl_p.h>
-#include <private/qpaintengine_opengl_p.h>
-#include <private/qwidget_p.h> // to access QWExtra
-#include <private/qnativeimagehandleprovider_p.h>
-#include "qgl_egl_p.h"
-#include "qpixmapdata_gl_p.h"
-#include "qgltexturepool_p.h"
-#include "qcolormap.h"
-#include <QDebug>
-
-QT_BEGIN_NAMESPACE
-
-// Turn off "direct to window" rendering if EGL cannot support it.
-#if !defined(EGL_RENDER_BUFFER) || !defined(EGL_SINGLE_BUFFER)
-#if defined(QGL_DIRECT_TO_WINDOW)
-#undef QGL_DIRECT_TO_WINDOW
-#endif
-#endif
-
-// Determine if preserved window contents should be used.
-#if !defined(EGL_SWAP_BEHAVIOR) || !defined(EGL_BUFFER_PRESERVED)
-#if !defined(QGL_NO_PRESERVED_SWAP)
-#define QGL_NO_PRESERVED_SWAP 1
-#endif
-#endif
-
-extern int qt_gl_pixmap_serial;
-
-/*
- QGLTemporaryContext implementation
-*/
-
-
-class QGLTemporaryContextPrivate
-{
-public:
- bool initialized;
- RWindow *window;
- EGLContext context;
- EGLSurface surface;
- EGLDisplay display;
-};
-
-QGLTemporaryContext::QGLTemporaryContext(bool, QWidget *)
- : d(new QGLTemporaryContextPrivate)
-{
- d->initialized = false;
- d->window = 0;
- d->context = 0;
- d->surface = 0;
-
- d->display = d->display = QEgl::display();
-
- EGLConfig config;
- int numConfigs = 0;
- EGLint attribs[] = {
- EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
-#ifdef QT_OPENGL_ES_2
- EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
-#endif
- EGL_NONE
- };
-
- eglChooseConfig(d->display, attribs, &config, 1, &numConfigs);
- if (!numConfigs) {
- qWarning("QGLTemporaryContext: No EGL configurations available.");
- return;
- }
-
- d->window = new RWindow(CCoeEnv::Static()->WsSession());
- d->window->Construct(CCoeEnv::Static()->RootWin(),(uint)this);
-
- d->surface = eglCreateWindowSurface(d->display, config, (EGLNativeWindowType) d->window, NULL);
-
- if (d->surface == EGL_NO_SURFACE) {
- qWarning("QGLTemporaryContext: Error creating EGL surface.");
- delete d->window;
- d->window = 0;
- return;
- }
-
- EGLint contextAttribs[] = {
-#ifdef QT_OPENGL_ES_2
- EGL_CONTEXT_CLIENT_VERSION, 2,
-#endif
- EGL_NONE
- };
- d->context = eglCreateContext(d->display, config, 0, contextAttribs);
- if (d->context != EGL_NO_CONTEXT
- && eglMakeCurrent(d->display, d->surface, d->surface, d->context))
- {
- d->initialized = true;
- } else {
- qWarning("QGLTemporaryContext: Error creating EGL context.");
- d->window = 0;
- return;
- }
-}
-
-QGLTemporaryContext::~QGLTemporaryContext()
-{
- if (d->initialized) {
- eglMakeCurrent(d->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
- eglDestroyContext(d->display, d->context);
- eglDestroySurface(d->display, d->surface);
- delete d->window;
- }
-}
-
-bool QGLFormat::hasOpenGLOverlays()
-{
- return false;
-}
-
-// Chooses the EGL config and creates the EGL context
-bool QGLContext::chooseContext(const QGLContext* shareContext) // almost same as in qgl_x11egl.cpp
-{
- Q_D(QGLContext);
-
- if (!device())
- return false;
-
- int devType = device()->devType();
-
- if ((devType != QInternal::Widget) && (devType != QInternal::Pbuffer)) {
- qWarning("WARNING: Creating a QGLContext not supported on device type %d", devType);
- return false;
- }
-
- // Get the display and initialize it.
- if (d->eglContext == 0) {
- d->eglContext = new QEglContext();
- d->ownsEglContext = true;
- d->eglContext->setApi(QEgl::OpenGL);
-
- // If the device is a widget with WA_TranslucentBackground set, make sure the glFormat
- // has the alpha channel option set:
- if (devType == QInternal::Widget) {
- QWidget* widget = static_cast<QWidget*>(device());
- if (widget->testAttribute(Qt::WA_TranslucentBackground))
- d->glFormat.setAlpha(true);
- }
-
- // Construct the configuration we need for this surface.
- QEglProperties configProps;
- configProps.setDeviceType(devType);
- configProps.setPaintDeviceFormat(device());
- configProps.setRenderableType(QEgl::OpenGL);
- configProps.setValue(EGL_SURFACE_TYPE, EGL_WINDOW_BIT|EGL_SWAP_BEHAVIOR_PRESERVED_BIT);
-
- qt_eglproperties_set_glformat(configProps, d->glFormat);
-
- if (!d->eglContext->chooseConfig(configProps, QEgl::BestPixelFormat)) {
- delete d->eglContext;
- d->eglContext = 0;
- return false;
- }
-
- // Create a new context for the configuration.
- QEglContext* eglSharedContext = shareContext ? shareContext->d_func()->eglContext : 0;
- if (!d->eglContext->createContext(eglSharedContext)) {
- delete d->eglContext;
- d->eglContext = 0;
- return false;
- }
- d->sharing = d->eglContext->isSharing();
- if (d->sharing && shareContext)
- const_cast<QGLContext *>(shareContext)->d_func()->sharing = true;
- }
-
- // Inform the higher layers about the actual format properties
- qt_glformat_from_eglconfig(d->glFormat, d->eglContext->config());
-
- // Do don't create the EGLSurface for everything.
- // QWidget - yes, create the EGLSurface and store it in QGLContextPrivate::eglSurface
- // QGLWidget - yes, create the EGLSurface and store it in QGLContextPrivate::eglSurface
- // QGLPixelBuffer - no, it creates the surface itself and stores it in QGLPixelBufferPrivate::pbuf
-
- if (devType == QInternal::Widget) {
- if (d->eglSurface != EGL_NO_SURFACE)
- eglDestroySurface(d->eglContext->display(), d->eglSurface);
-
- d->eglSurface = QEgl::createSurface(device(), d->eglContext->config());
-
- eglGetError(); // Clear error state first.
-
-#ifdef QGL_NO_PRESERVED_SWAP
- eglSurfaceAttrib(QEgl::display(), d->eglSurface,
- EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED);
-
- if (eglGetError() != EGL_SUCCESS)
- qWarning("QGLContext: could not enable destroyed swap behaviour");
-#else
- eglSurfaceAttrib(QEgl::display(), d->eglSurface,
- EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED);
-
- if (eglGetError() != EGL_SUCCESS)
- qWarning("QGLContext: could not enable preserved swap behaviour");
-#endif
-
- setWindowCreated(true);
- }
-
- return true;
-}
-
-void QGLWidget::resizeEvent(QResizeEvent *)
-{
- Q_D(QGLWidget);
- if (!isValid())
- return;
-
- if (QGLContext::currentContext())
- doneCurrent();
-
- // Symbian needs to recreate the surface on resize.
- d->recreateEglSurface();
-
- makeCurrent();
- if (!d->glcx->initialized())
- glInit();
- resizeGL(width(), height());
- //handle overlay
-}
-
-const QGLContext* QGLWidget::overlayContext() const
-{
- return 0;
-}
-
-void QGLWidget::makeOverlayCurrent()
-{
- //handle overlay
-}
-
-void QGLWidget::updateOverlayGL()
-{
- //handle overlay
-}
-
-void QGLWidget::setContext(QGLContext *context, const QGLContext* shareContext, bool deleteOldContext)
-{
- Q_D(QGLWidget);
- if (context == 0) {
- qWarning("QGLWidget::setContext: Cannot set null context");
- return;
- }
- if (!context->deviceIsPixmap() && context->device() != this) {
- qWarning("QGLWidget::setContext: Context must refer to this widget");
- return;
- }
-
- if (d->glcx)
- d->glcx->doneCurrent();
- QGLContext* oldcx = d->glcx;
- d->glcx = context;
-
- bool createFailed = false;
- if (!d->glcx->isValid()) {
- // Create the QGLContext here, which in turn chooses the EGL config
- // and creates the EGL context:
- if (!d->glcx->create(shareContext ? shareContext : oldcx))
- createFailed = true;
- }
- if (createFailed) {
- if (deleteOldContext)
- delete oldcx;
- return;
- }
-
- d->eglSurfaceWindowId = winId(); // Remember the window id we created the surface for
-}
-
-void QGLWidgetPrivate::init(QGLContext *context, const QGLWidget* shareWidget)
-{
- Q_Q(QGLWidget);
-
- initContext(context, shareWidget);
-
- if(q->isValid() && glcx->format().hasOverlay()) {
- //no overlay
- qWarning("QtOpenGL ES doesn't currently support overlays");
- }
-}
-
-void QGLWidgetPrivate::cleanupColormaps()
-{
-}
-
-const QGLColormap & QGLWidget::colormap() const
-{
- return d_func()->cmap;
-}
-
-void QGLWidget::setColormap(const QGLColormap &)
-{
-}
-
-void QGLWidgetPrivate::recreateEglSurface()
-{
- Q_Q(QGLWidget);
-
- WId currentId = q->winId();
-
- if (glcx->d_func()->eglSurface != EGL_NO_SURFACE) {
- eglDestroySurface(glcx->d_func()->eglContext->display(),
- glcx->d_func()->eglSurface);
- }
-
- glcx->d_func()->eglSurface = QEgl::createSurface(glcx->device(),
- glcx->d_func()->eglContext->config());
-
-#if !defined(QGL_NO_PRESERVED_SWAP)
- eglGetError(); // Clear error state first.
- eglSurfaceAttrib(QEgl::display(), glcx->d_func()->eglSurface,
- EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED);
- if (eglGetError() != EGL_SUCCESS) {
- qWarning("QGLContext: could not enable preserved swap");
- }
-#endif
-
- eglSurfaceWindowId = currentId;
-}
-
-static inline bool knownGoodFormat(QImage::Format format)
-{
- switch (format) {
- case QImage::Format_RGB16: // EColor64K
- case QImage::Format_RGB32: // EColor16MU
- case QImage::Format_ARGB32_Premultiplied: // EColor16MAP
- return true;
- default:
- return false;
- }
-}
-
-void QGLPixmapData::fromNativeType(void* pixmap, NativeType type)
-{
- if (type == QPixmapData::FbsBitmap) {
- CFbsBitmap *bitmap = reinterpret_cast<CFbsBitmap *>(pixmap);
- QSize size(bitmap->SizeInPixels().iWidth, bitmap->SizeInPixels().iHeight);
- if (size.width() == w && size.height() == h)
- setSerialNumber(++qt_gl_pixmap_serial);
- resize(size.width(), size.height());
- m_source = QVolatileImage(bitmap);
- if (pixelType() == BitmapType) {
- m_source.ensureFormat(QImage::Format_MonoLSB);
- } else if (!knownGoodFormat(m_source.format())) {
- m_source.beginDataAccess();
- QImage::Format format = idealFormat(m_source.imageRef(), Qt::AutoColor);
- m_source.endDataAccess(true);
- m_source.ensureFormat(format);
- }
- m_hasAlpha = m_source.hasAlphaChannel();
- m_hasFillColor = false;
- m_dirty = true;
-
- } else if (type == QPixmapData::VolatileImage && pixmap) {
- // Support QS60Style in more efficient skin graphics retrieval.
- QVolatileImage *img = static_cast<QVolatileImage *>(pixmap);
- if (img->width() == w && img->height() == h)
- setSerialNumber(++qt_gl_pixmap_serial);
- resize(img->width(), img->height());
- m_source = *img;
- m_hasAlpha = m_source.hasAlphaChannel();
- m_hasFillColor = false;
- m_dirty = true;
- } else if (type == QPixmapData::NativeImageHandleProvider && pixmap) {
- destroyTexture();
- nativeImageHandleProvider = static_cast<QNativeImageHandleProvider *>(pixmap);
- // Cannot defer the retrieval, we need at least the size right away.
- createFromNativeImageHandleProvider();
- }
-}
-
-void* QGLPixmapData::toNativeType(NativeType type)
-{
- if (type == QPixmapData::FbsBitmap) {
- if (m_source.isNull())
- m_source = QVolatileImage(w, h, QImage::Format_ARGB32_Premultiplied);
- return m_source.duplicateNativeImage();
- }
-
- return 0;
-}
-
-bool QGLPixmapData::initFromNativeImageHandle(void *handle, const QString &type)
-{
- if (type == QLatin1String("RSgImage")) {
- fromNativeType(handle, QPixmapData::SgImage);
- return true;
- } else if (type == QLatin1String("CFbsBitmap")) {
- fromNativeType(handle, QPixmapData::FbsBitmap);
- return true;
- }
- return false;
-}
-
-void QGLPixmapData::createFromNativeImageHandleProvider()
-{
- void *handle = 0;
- QString type;
- nativeImageHandleProvider->get(&handle, &type);
- if (handle) {
- if (initFromNativeImageHandle(handle, type)) {
- nativeImageHandle = handle;
- nativeImageType = type;
- } else {
- qWarning("QGLPixmapData: Unknown native image type '%s'", qPrintable(type));
- }
- } else {
- qWarning("QGLPixmapData: Native handle is null");
- }
-}
-
-void QGLPixmapData::releaseNativeImageHandle()
-{
- if (nativeImageHandleProvider && nativeImageHandle) {
- nativeImageHandleProvider->release(nativeImageHandle, nativeImageType);
- nativeImageHandle = 0;
- nativeImageType = QString();
- }
-}
-
-QT_END_NAMESPACE
diff --git a/src/opengl/qgl_win.cpp b/src/opengl/qgl_win.cpp
deleted file mode 100644
index 3b1643f4c2..0000000000
--- a/src/opengl/qgl_win.cpp
+++ /dev/null
@@ -1,1601 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#include <qgl.h>
-#include <qlist.h>
-#include <qmap.h>
-#include <qpixmap.h>
-#include <qevent.h>
-#include <private/qgl_p.h>
-#include <qcolormap.h>
-#include <qvarlengtharray.h>
-#include <qdebug.h>
-#include <qcolor.h>
-
-#include <qt_windows.h>
-
-typedef bool (APIENTRY *PFNWGLGETPIXELFORMATATTRIBIVARB)(HDC hdc,
- int iPixelFormat,
- int iLayerPlane,
- uint nAttributes,
- const int *piAttributes,
- int *piValues);
-typedef bool (APIENTRY *PFNWGLCHOOSEPIXELFORMATARB)(HDC hdc,
- const int *piAttribList,
- const float *pfAttribFList,
- uint nMaxFormats,
- int *piFormats,
- UINT *nNumFormats);
-#ifndef WGL_ARB_multisample
-#define WGL_SAMPLE_BUFFERS_ARB 0x2041
-#define WGL_SAMPLES_ARB 0x2042
-#endif
-
-#ifndef WGL_ARB_pixel_format
-#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
-#define WGL_DRAW_TO_WINDOW_ARB 0x2001
-#define WGL_DRAW_TO_BITMAP_ARB 0x2002
-#define WGL_ACCELERATION_ARB 0x2003
-#define WGL_NEED_PALETTE_ARB 0x2004
-#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005
-#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006
-#define WGL_SWAP_METHOD_ARB 0x2007
-#define WGL_NUMBER_OVERLAYS_ARB 0x2008
-#define WGL_NUMBER_UNDERLAYS_ARB 0x2009
-#define WGL_TRANSPARENT_ARB 0x200A
-#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037
-#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038
-#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039
-#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A
-#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B
-#define WGL_SHARE_DEPTH_ARB 0x200C
-#define WGL_SHARE_STENCIL_ARB 0x200D
-#define WGL_SHARE_ACCUM_ARB 0x200E
-#define WGL_SUPPORT_GDI_ARB 0x200F
-#define WGL_SUPPORT_OPENGL_ARB 0x2010
-#define WGL_DOUBLE_BUFFER_ARB 0x2011
-#define WGL_STEREO_ARB 0x2012
-#define WGL_PIXEL_TYPE_ARB 0x2013
-#define WGL_COLOR_BITS_ARB 0x2014
-#define WGL_RED_BITS_ARB 0x2015
-#define WGL_RED_SHIFT_ARB 0x2016
-#define WGL_GREEN_BITS_ARB 0x2017
-#define WGL_GREEN_SHIFT_ARB 0x2018
-#define WGL_BLUE_BITS_ARB 0x2019
-#define WGL_BLUE_SHIFT_ARB 0x201A
-#define WGL_ALPHA_BITS_ARB 0x201B
-#define WGL_ALPHA_SHIFT_ARB 0x201C
-#define WGL_ACCUM_BITS_ARB 0x201D
-#define WGL_ACCUM_RED_BITS_ARB 0x201E
-#define WGL_ACCUM_GREEN_BITS_ARB 0x201F
-#define WGL_ACCUM_BLUE_BITS_ARB 0x2020
-#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
-#define WGL_DEPTH_BITS_ARB 0x2022
-#define WGL_STENCIL_BITS_ARB 0x2023
-#define WGL_AUX_BUFFERS_ARB 0x2024
-#define WGL_NO_ACCELERATION_ARB 0x2025
-#define WGL_GENERIC_ACCELERATION_ARB 0x2026
-#define WGL_FULL_ACCELERATION_ARB 0x2027
-#define WGL_SWAP_EXCHANGE_ARB 0x2028
-#define WGL_SWAP_COPY_ARB 0x2029
-#define WGL_SWAP_UNDEFINED_ARB 0x202A
-#define WGL_TYPE_RGBA_ARB 0x202B
-#define WGL_TYPE_COLORINDEX_ARB 0x202C
-#endif
-
-#ifndef WGL_ARB_create_context
-#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
-#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
-#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093
-#define WGL_CONTEXT_FLAGS_ARB 0x2094
-#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
-#define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001
-#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002
-#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x0001
-#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x0002
-// Error codes returned by GetLastError().
-#define ERROR_INVALID_VERSION_ARB 0x2095
-#define ERROR_INVALID_PROFILE_ARB 0x2096
-#endif
-
-#ifndef GL_VERSION_3_2
-#define GL_CONTEXT_PROFILE_MASK 0x9126
-#define GL_MAJOR_VERSION 0x821B
-#define GL_MINOR_VERSION 0x821C
-#define GL_NUM_EXTENSIONS 0x821D
-#define GL_CONTEXT_FLAGS 0x821E
-#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x0001
-#endif
-
-QT_BEGIN_NAMESPACE
-
-class QGLCmapPrivate
-{
-public:
- QGLCmapPrivate() : count(1) { }
- void ref() { ++count; }
- bool deref() { return !--count; }
- uint count;
-
- enum AllocState{ UnAllocated = 0, Allocated = 0x01, Reserved = 0x02 };
-
- int maxSize;
- QVector<uint> colorArray;
- QVector<quint8> allocArray;
- QVector<quint8> contextArray;
- QMap<uint,int> colorMap;
-};
-
-/*****************************************************************************
- QColorMap class - temporarily here, until it is ready for prime time
- *****************************************************************************/
-
-/****************************************************************************
-**
-** Definition of QColorMap class
-**
-****************************************************************************/
-
-class QGLCmapPrivate;
-
-class /*Q_EXPORT*/ QGLCmap
-{
-public:
- enum Flags { Reserved = 0x01 };
-
- QGLCmap(int maxSize = 256);
- QGLCmap(const QGLCmap& map);
- ~QGLCmap();
-
- QGLCmap& operator=(const QGLCmap& map);
-
- // isEmpty and/or isNull ?
- int size() const;
- int maxSize() const;
-
- void resize(int newSize);
-
- int find(QRgb color) const;
- int findNearest(QRgb color) const;
- int allocate(QRgb color, uint flags = 0, quint8 context = 0);
-
- void setEntry(int idx, QRgb color, uint flags = 0, quint8 context = 0);
-
- const QRgb* colors() const;
-
-private:
- void detach();
- QGLCmapPrivate* d;
-};
-
-
-QGLCmap::QGLCmap(int maxSize) // add a bool prealloc?
-{
- d = new QGLCmapPrivate;
- d->maxSize = maxSize;
-}
-
-
-QGLCmap::QGLCmap(const QGLCmap& map)
-{
- d = map.d;
- d->ref();
-}
-
-
-QGLCmap::~QGLCmap()
-{
- if (d && d->deref())
- delete d;
- d = 0;
-}
-
-
-QGLCmap& QGLCmap::operator=(const QGLCmap& map)
-{
- map.d->ref();
- if (d->deref())
- delete d;
- d = map.d;
- return *this;
-}
-
-
-int QGLCmap::size() const
-{
- return d->colorArray.size();
-}
-
-
-int QGLCmap::maxSize() const
-{
- return d->maxSize;
-}
-
-
-void QGLCmap::detach()
-{
- if (d->count != 1) {
- d->deref();
- QGLCmapPrivate* newd = new QGLCmapPrivate;
- newd->maxSize = d->maxSize;
- newd->colorArray = d->colorArray;
- newd->allocArray = d->allocArray;
- newd->contextArray = d->contextArray;
- newd->colorArray.detach();
- newd->allocArray.detach();
- newd->contextArray.detach();
- newd->colorMap = d->colorMap;
- d = newd;
- }
-}
-
-
-void QGLCmap::resize(int newSize)
-{
- if (newSize < 0 || newSize > d->maxSize) {
- qWarning("QGLCmap::resize(): size out of range");
- return;
- }
- int oldSize = size();
- detach();
- //if shrinking; remove the lost elems from colorMap
- d->colorArray.resize(newSize);
- d->allocArray.resize(newSize);
- d->contextArray.resize(newSize);
- if (newSize > oldSize) {
- memset(d->allocArray.data() + oldSize, 0, newSize - oldSize);
- memset(d->contextArray.data() + oldSize, 0, newSize - oldSize);
- }
-}
-
-
-int QGLCmap::find(QRgb color) const
-{
- QMap<uint,int>::ConstIterator it = d->colorMap.find(color);
- if (it != d->colorMap.end())
- return *it;
- return -1;
-}
-
-
-int QGLCmap::findNearest(QRgb color) const
-{
- int idx = find(color);
- if (idx >= 0)
- return idx;
- int mapSize = size();
- int mindist = 200000;
- int r = qRed(color);
- int g = qGreen(color);
- int b = qBlue(color);
- int rx, gx, bx, dist;
- for (int i=0; i < mapSize; i++) {
- if (!(d->allocArray[i] & QGLCmapPrivate::Allocated))
- continue;
- QRgb ci = d->colorArray[i];
- rx = r - qRed(ci);
- gx = g - qGreen(ci);
- bx = b - qBlue(ci);
- dist = rx*rx + gx*gx + bx*bx; // calculate distance
- if (dist < mindist) { // minimal?
- mindist = dist;
- idx = i;
- }
- }
- return idx;
-}
-
-
-
-
-// Does not always allocate; returns existing c idx if found
-
-int QGLCmap::allocate(QRgb color, uint flags, quint8 context)
-{
- int idx = find(color);
- if (idx >= 0)
- return idx;
-
- int mapSize = d->colorArray.size();
- int newIdx = d->allocArray.indexOf(QGLCmapPrivate::UnAllocated);
-
- if (newIdx < 0) { // Must allocate more room
- if (mapSize < d->maxSize) {
- newIdx = mapSize;
- mapSize++;
- resize(mapSize);
- }
- else {
- //# add a bool param that says what to do in case no more room -
- // fail (-1) or return nearest?
- return -1;
- }
- }
-
- d->colorArray[newIdx] = color;
- if (flags & QGLCmap::Reserved) {
- d->allocArray[newIdx] = QGLCmapPrivate::Reserved;
- }
- else {
- d->allocArray[newIdx] = QGLCmapPrivate::Allocated;
- d->colorMap.insert(color, newIdx);
- }
- d->contextArray[newIdx] = context;
- return newIdx;
-}
-
-
-void QGLCmap::setEntry(int idx, QRgb color, uint flags, quint8 context)
-{
- if (idx < 0 || idx >= d->maxSize) {
- qWarning("QGLCmap::set(): Index out of range");
- return;
- }
- detach();
- int mapSize = size();
- if (idx >= mapSize) {
- mapSize = idx + 1;
- resize(mapSize);
- }
- d->colorArray[idx] = color;
- if (flags & QGLCmap::Reserved) {
- d->allocArray[idx] = QGLCmapPrivate::Reserved;
- }
- else {
- d->allocArray[idx] = QGLCmapPrivate::Allocated;
- d->colorMap.insert(color, idx);
- }
- d->contextArray[idx] = context;
-}
-
-
-const QRgb* QGLCmap::colors() const
-{
- return d->colorArray.data();
-}
-
-
-
-/*****************************************************************************
- QGLFormat Win32/WGL-specific code
- *****************************************************************************/
-
-
-void qwglError(const char* method, const char* func)
-{
-#ifndef QT_NO_DEBUG
- char* lpMsgBuf;
- FormatMessageA(
- FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
- 0, GetLastError(),
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- (char*) &lpMsgBuf, 0, 0);
- qWarning("%s : %s failed: %s", method, func, lpMsgBuf);
- LocalFree(lpMsgBuf);
-#else
- Q_UNUSED(method);
- Q_UNUSED(func);
-#endif
-}
-
-
-
-bool QGLFormat::hasOpenGL()
-{
- return true;
-}
-
-static bool opengl32dll = false;
-
-bool QGLFormat::hasOpenGLOverlays()
-{
- // workaround for matrox driver:
- // make a cheap call to opengl to force loading of DLL
- if (!opengl32dll) {
- GLint params;
- glGetIntegerv(GL_DEPTH_BITS, &params);
- opengl32dll = true;
- }
-
- static bool checkDone = false;
- static bool hasOl = false;
-
- if (!checkDone) {
- checkDone = true;
- HDC display_dc = GetDC(0);
- int pfiMax = DescribePixelFormat(display_dc, 0, 0, NULL);
- PIXELFORMATDESCRIPTOR pfd;
- for (int pfi = 1; pfi <= pfiMax; pfi++) {
- DescribePixelFormat(display_dc, pfi, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
- if ((pfd.bReserved & 0x0f) && (pfd.dwFlags & PFD_SUPPORT_OPENGL)) {
- // This format has overlays/underlays
- LAYERPLANEDESCRIPTOR lpd;
- wglDescribeLayerPlane(display_dc, pfi, 1,
- sizeof(LAYERPLANEDESCRIPTOR), &lpd);
- if (lpd.dwFlags & LPD_SUPPORT_OPENGL) {
- hasOl = true;
- break;
- }
- }
- }
- ReleaseDC(0, display_dc);
- }
- return hasOl;
-}
-
-
-/*****************************************************************************
- QGLContext Win32/WGL-specific code
- *****************************************************************************/
-
-static uchar qgl_rgb_palette_comp(int idx, uint nbits, uint shift)
-{
- const uchar map_3_to_8[8] = {
- 0, 0111>>1, 0222>>1, 0333>>1, 0444>>1, 0555>>1, 0666>>1, 0377
- };
- const uchar map_2_to_8[4] = {
- 0, 0x55, 0xaa, 0xff
- };
- const uchar map_1_to_8[2] = {
- 0, 255
- };
-
- uchar val = (uchar) (idx >> shift);
- uchar res = 0;
- switch (nbits) {
- case 1:
- val &= 0x1;
- res = map_1_to_8[val];
- break;
- case 2:
- val &= 0x3;
- res = map_2_to_8[val];
- break;
- case 3:
- val &= 0x7;
- res = map_3_to_8[val];
- break;
- default:
- res = 0;
- }
- return res;
-}
-
-
-static QRgb* qgl_create_rgb_palette(const PIXELFORMATDESCRIPTOR* pfd)
-{
- if ((pfd->iPixelType != PFD_TYPE_RGBA) ||
- !(pfd->dwFlags & PFD_NEED_PALETTE) ||
- (pfd->cColorBits != 8))
- return 0;
- int numEntries = 1 << pfd->cColorBits;
- QRgb* pal = new QRgb[numEntries];
- for (int i = 0; i < numEntries; i++) {
- int r = qgl_rgb_palette_comp(i, pfd->cRedBits, pfd->cRedShift);
- int g = qgl_rgb_palette_comp(i, pfd->cGreenBits, pfd->cGreenShift);
- int b = qgl_rgb_palette_comp(i, pfd->cBlueBits, pfd->cBlueShift);
- pal[i] = qRgb(r, g, b);
- }
-
- const int syscol_indices[12] = {
- 3, 24, 27, 64, 67, 88, 173, 181, 236, 247, 164, 91
- };
-
- const uint syscols[20] = {
- 0x000000, 0x800000, 0x008000, 0x808000, 0x000080, 0x800080,
- 0x008080, 0xc0c0c0, 0xc0dcc0, 0xa6caf0, 0xfffbf0, 0xa0a0a4,
- 0x808080, 0xff0000, 0x00ff00, 0xffff00, 0x0000ff, 0xff00ff,
- 0x00ffff, 0xffffff
- }; // colors #1 - #12 are not present in pal; gets added below
-
- if ((pfd->cColorBits == 8) &&
- (pfd->cRedBits == 3) && (pfd->cRedShift == 0) &&
- (pfd->cGreenBits == 3) && (pfd->cGreenShift == 3) &&
- (pfd->cBlueBits == 2) && (pfd->cBlueShift == 6)) {
- for (int j = 0 ; j < 12 ; j++)
- pal[syscol_indices[j]] = QRgb(syscols[j+1]);
- }
-
- return pal;
-}
-
-static QGLFormat pfdToQGLFormat(const PIXELFORMATDESCRIPTOR* pfd)
-{
- QGLFormat fmt;
- fmt.setDoubleBuffer(pfd->dwFlags & PFD_DOUBLEBUFFER);
- fmt.setDepth(pfd->cDepthBits);
- if (fmt.depth())
- fmt.setDepthBufferSize(pfd->cDepthBits);
- fmt.setRgba(pfd->iPixelType == PFD_TYPE_RGBA);
- fmt.setRedBufferSize(pfd->cRedBits);
- fmt.setGreenBufferSize(pfd->cGreenBits);
- fmt.setBlueBufferSize(pfd->cBlueBits);
- fmt.setAlpha(pfd->cAlphaBits);
- if (fmt.alpha())
- fmt.setAlphaBufferSize(pfd->cAlphaBits);
- fmt.setAccum(pfd->cAccumBits);
- if (fmt.accum())
- fmt.setAccumBufferSize(pfd->cAccumRedBits);
- fmt.setStencil(pfd->cStencilBits);
- if (fmt.stencil())
- fmt.setStencilBufferSize(pfd->cStencilBits);
- fmt.setStereo(pfd->dwFlags & PFD_STEREO);
- fmt.setDirectRendering((pfd->dwFlags & PFD_GENERIC_ACCELERATED) ||
- !(pfd->dwFlags & PFD_GENERIC_FORMAT));
- fmt.setOverlay((pfd->bReserved & 0x0f) != 0);
- return fmt;
-}
-
-/*
- NB! requires a current GL context to work
-*/
-QGLFormat pfiToQGLFormat(HDC hdc, int pfi)
-{
- QGLFormat fmt;
- QVarLengthArray<int> iAttributes(40);
- QVarLengthArray<int> iValues(40);
- int i = 0;
- bool has_sample_buffers = QGLExtensions::glExtensions() & QGLExtensions::SampleBuffers;
-
- iAttributes[i++] = WGL_DOUBLE_BUFFER_ARB; // 0
- iAttributes[i++] = WGL_DEPTH_BITS_ARB; // 1
- iAttributes[i++] = WGL_PIXEL_TYPE_ARB; // 2
- iAttributes[i++] = WGL_RED_BITS_ARB; // 3
- iAttributes[i++] = WGL_GREEN_BITS_ARB; // 4
- iAttributes[i++] = WGL_BLUE_BITS_ARB; // 5
- iAttributes[i++] = WGL_ALPHA_BITS_ARB; // 6
- iAttributes[i++] = WGL_ACCUM_BITS_ARB; // 7
- iAttributes[i++] = WGL_STENCIL_BITS_ARB; // 8
- iAttributes[i++] = WGL_STEREO_ARB; // 9
- iAttributes[i++] = WGL_ACCELERATION_ARB; // 10
- iAttributes[i++] = WGL_NUMBER_OVERLAYS_ARB; // 11
- if (has_sample_buffers) {
- iAttributes[i++] = WGL_SAMPLE_BUFFERS_ARB; // 12
- iAttributes[i++] = WGL_SAMPLES_ARB; // 13
- }
- PFNWGLGETPIXELFORMATATTRIBIVARB wglGetPixelFormatAttribivARB =
- (PFNWGLGETPIXELFORMATATTRIBIVARB) wglGetProcAddress("wglGetPixelFormatAttribivARB");
-
- if (wglGetPixelFormatAttribivARB
- && wglGetPixelFormatAttribivARB(hdc, pfi, 0, i,
- iAttributes.constData(),
- iValues.data()))
- {
- fmt.setDoubleBuffer(iValues[0]);
- fmt.setDepth(iValues[1]);
- if (fmt.depth())
- fmt.setDepthBufferSize(iValues[1]);
- fmt.setRgba(iValues[2] == WGL_TYPE_RGBA_ARB);
- fmt.setRedBufferSize(iValues[3]);
- fmt.setGreenBufferSize(iValues[4]);
- fmt.setBlueBufferSize(iValues[5]);
- fmt.setAlpha(iValues[6]);
- if (fmt.alpha())
- fmt.setAlphaBufferSize(iValues[6]);
- fmt.setAccum(iValues[7]);
- if (fmt.accum())
- fmt.setAccumBufferSize(iValues[7]);
- fmt.setStencil(iValues[8]);
- if (fmt.stencil())
- fmt.setStencilBufferSize(iValues[8]);
- fmt.setStereo(iValues[9]);
- if (iValues[10] == WGL_FULL_ACCELERATION_ARB)
- fmt.setDirectRendering(true);
- else
- fmt.setDirectRendering(false);
- fmt.setOverlay(iValues[11]);
- if (has_sample_buffers) {
- fmt.setSampleBuffers(iValues[12]);
- if (fmt.sampleBuffers())
- fmt.setSamples(iValues[13]);
- }
- }
-#if 0
- qDebug() << "values for pfi:" << pfi;
- qDebug() << "doublebuffer 0:" << fmt.doubleBuffer();
- qDebug() << "depthbuffer 1:" << fmt.depthBufferSize();
- qDebug() << "rgba 2:" << fmt.rgba();
- qDebug() << "red size 3:" << fmt.redBufferSize();
- qDebug() << "green size 4:" << fmt.greenBufferSize();
- qDebug() << "blue size 5:" << fmt.blueBufferSize();
- qDebug() << "alpha size 6:" << fmt.alphaBufferSize();
- qDebug() << "accum size 7:" << fmt.accumBufferSize();
- qDebug() << "stencil size 8:" << fmt.stencilBufferSize();
- qDebug() << "stereo 9:" << fmt.stereo();
- qDebug() << "direct 10:" << fmt.directRendering();
- qDebug() << "has overlays 11:" << fmt.hasOverlay();
- qDebug() << "sample buff 12:" << fmt.sampleBuffers();
- qDebug() << "num samples 13:" << fmt.samples();
-#endif
- return fmt;
-}
-
-
-/*
- QGLTemporaryContext implementation
-*/
-
-Q_GUI_EXPORT const QString qt_getRegisteredWndClass();
-
-class QGLTemporaryContextPrivate
-{
-public:
- HDC dmy_pdc;
- HGLRC dmy_rc;
- HDC old_dc;
- HGLRC old_context;
- WId dmy_id;
-};
-
-QGLTemporaryContext::QGLTemporaryContext(bool directRendering, QWidget *parent)
- : d(new QGLTemporaryContextPrivate)
-{
- QString windowClassName = qt_getRegisteredWndClass();
- if (parent && !parent->internalWinId())
- parent = parent->nativeParentWidget();
-
- d->dmy_id = CreateWindow((const wchar_t *)windowClassName.utf16(),
- 0, 0, 0, 0, 1, 1,
- parent ? parent->winId() : 0, 0, qWinAppInst(), 0);
-
- d->dmy_pdc = GetDC(d->dmy_id);
- PIXELFORMATDESCRIPTOR dmy_pfd;
- memset(&dmy_pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
- dmy_pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
- dmy_pfd.nVersion = 1;
- dmy_pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW;
- dmy_pfd.iPixelType = PFD_TYPE_RGBA;
- if (!directRendering)
- dmy_pfd.dwFlags |= PFD_GENERIC_FORMAT;
-
- int dmy_pf = ChoosePixelFormat(d->dmy_pdc, &dmy_pfd);
- SetPixelFormat(d->dmy_pdc, dmy_pf, &dmy_pfd);
- d->dmy_rc = wglCreateContext(d->dmy_pdc);
- d->old_dc = wglGetCurrentDC();
- d->old_context = wglGetCurrentContext();
- wglMakeCurrent(d->dmy_pdc, d->dmy_rc);
-}
-
-QGLTemporaryContext::~QGLTemporaryContext()
-{
- wglMakeCurrent(d->dmy_pdc, 0);
- wglDeleteContext(d->dmy_rc);
- ReleaseDC(d->dmy_id, d->dmy_pdc);
- DestroyWindow(d->dmy_id);
- if (d->old_dc && d->old_context)
- wglMakeCurrent(d->old_dc, d->old_context);
-}
-
-static bool qgl_create_context(HDC hdc, QGLContextPrivate *d, QGLContextPrivate *shareContext)
-{
- d->rc = 0;
-
- typedef HGLRC (APIENTRYP PFNWGLCREATECONTEXTATTRIBSARB)(HDC, HGLRC, const int *);
- PFNWGLCREATECONTEXTATTRIBSARB wglCreateContextAttribsARB =
- (PFNWGLCREATECONTEXTATTRIBSARB) wglGetProcAddress("wglCreateContextAttribsARB");
- if (wglCreateContextAttribsARB) {
- int attributes[11];
- int attribIndex = 0;
- const int major = d->reqFormat.majorVersion();
- const int minor = d->reqFormat.minorVersion();
- attributes[attribIndex++] = WGL_CONTEXT_MAJOR_VERSION_ARB;
- attributes[attribIndex++] = major;
- attributes[attribIndex++] = WGL_CONTEXT_MINOR_VERSION_ARB;
- attributes[attribIndex++] = minor;
-
- if (major >= 3 && !d->reqFormat.testOption(QGL::DeprecatedFunctions)) {
- attributes[attribIndex++] = WGL_CONTEXT_FLAGS_ARB;
- attributes[attribIndex++] = WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
- }
-
- if ((major == 3 && minor >= 2) || major > 3) {
- switch (d->reqFormat.profile()) {
- case QGLFormat::NoProfile:
- break;
- case QGLFormat::CoreProfile:
- attributes[attribIndex++] = WGL_CONTEXT_PROFILE_MASK_ARB;
- attributes[attribIndex++] = WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
- break;
- case QGLFormat::CompatibilityProfile:
- attributes[attribIndex++] = WGL_CONTEXT_PROFILE_MASK_ARB;
- attributes[attribIndex++] = WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
- break;
- default:
- qWarning("QGLContext::chooseContext(): Context profile not supported.");
- return false;
- }
- }
-
- if (d->reqFormat.plane() != 0) {
- attributes[attribIndex++] = WGL_CONTEXT_LAYER_PLANE_ARB;
- attributes[attribIndex++] = d->reqFormat.plane();
- }
-
- attributes[attribIndex++] = 0; // Terminate list.
- d->rc = wglCreateContextAttribsARB(hdc, shareContext && shareContext->valid
- ? shareContext->rc : 0, attributes);
- if (d->rc) {
- if (shareContext)
- shareContext->sharing = d->sharing = true;
- return true;
- }
- }
-
- d->rc = wglCreateLayerContext(hdc, d->reqFormat.plane());
- if (d->rc && shareContext && shareContext->valid)
- shareContext->sharing = d->sharing = wglShareLists(shareContext->rc, d->rc);
- return d->rc != 0;
-}
-
-void QGLContextPrivate::updateFormatVersion()
-{
- const GLubyte *s = glGetString(GL_VERSION);
-
- if (!(s && s[0] >= '0' && s[0] <= '9' && s[1] == '.' && s[2] >= '0' && s[2] <= '9')) {
- if (!s)
- qWarning("QGLContext::chooseContext(): OpenGL version string is null.");
- else
- qWarning("QGLContext::chooseContext(): Unexpected OpenGL version string format.");
- glFormat.setVersion(0, 0);
- glFormat.setProfile(QGLFormat::NoProfile);
- glFormat.setOption(QGL::DeprecatedFunctions);
- return;
- }
-
- int major = s[0] - '0';
- int minor = s[2] - '0';
- glFormat.setVersion(major, minor);
-
- if (major < 3) {
- glFormat.setProfile(QGLFormat::NoProfile);
- glFormat.setOption(QGL::DeprecatedFunctions);
- } else {
- GLint value = 0;
- if (major > 3 || minor >= 2)
- glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &value);
-
- switch (value) {
- case WGL_CONTEXT_CORE_PROFILE_BIT_ARB:
- glFormat.setProfile(QGLFormat::CoreProfile);
- break;
- case WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB:
- glFormat.setProfile(QGLFormat::CompatibilityProfile);
- break;
- default:
- glFormat.setProfile(QGLFormat::NoProfile);
- break;
- }
-
- glGetIntegerv(GL_CONTEXT_FLAGS, &value);
- if (value & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT)
- glFormat.setOption(QGL::NoDeprecatedFunctions);
- else
- glFormat.setOption(QGL::DeprecatedFunctions);
- }
-}
-
-bool QGLContext::chooseContext(const QGLContext* shareContext)
-{
- QGLContextPrivate *share = shareContext ? const_cast<QGLContext *>(shareContext)->d_func() : 0;
-
- Q_D(QGLContext);
- // workaround for matrox driver:
- // make a cheap call to opengl to force loading of DLL
- if (!opengl32dll) {
- GLint params;
- glGetIntegerv(GL_DEPTH_BITS, &params);
- opengl32dll = true;
- }
-
- bool result = true;
- HDC myDc;
- QWidget *widget = 0;
-
- if (deviceIsPixmap()) {
- if (d->glFormat.plane())
- return false; // Pixmaps can't have overlay
- d->win = 0;
- HDC display_dc = GetDC(0);
- myDc = d->hbitmap_hdc = CreateCompatibleDC(display_dc);
- QPixmap *px = static_cast<QPixmap *>(d->paintDevice);
-
- BITMAPINFO bmi;
- memset(&bmi, 0, sizeof(bmi));
- bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- bmi.bmiHeader.biWidth = px->width();
- bmi.bmiHeader.biHeight = px->height();
- bmi.bmiHeader.biPlanes = 1;
- bmi.bmiHeader.biBitCount = 32;
- bmi.bmiHeader.biCompression = BI_RGB;
- d->hbitmap = CreateDIBSection(display_dc, &bmi, DIB_RGB_COLORS, 0, 0, 0);
- SelectObject(myDc, d->hbitmap);
- ReleaseDC(0, display_dc);
- } else {
- widget = static_cast<QWidget *>(d->paintDevice);
- d->win = widget->winId();
- myDc = GetDC(d->win);
- }
-
- // NB! the QGLTemporaryContext object is needed for the
- // wglGetProcAddress() calls to succeed and are absolutely
- // necessary - don't remove!
- QGLTemporaryContext tmp_ctx(d->glFormat.directRendering(), widget);
-
- if (!myDc) {
- qWarning("QGLContext::chooseContext(): Paint device cannot be null");
- result = false;
- goto end;
- }
-
- if (d->glFormat.plane()) {
- d->pixelFormatId = ((QGLWidget*)d->paintDevice)->context()->d_func()->pixelFormatId;
- if (!d->pixelFormatId) { // I.e. the glwidget is invalid
- qWarning("QGLContext::chooseContext(): Cannot create overlay context for invalid widget");
- result = false;
- goto end;
- }
-
- if (!qgl_create_context(myDc, d, share)) {
- qwglError("QGLContext::chooseContext()", "CreateLayerContext");
- result = false;
- goto end;
- }
-
- LAYERPLANEDESCRIPTOR lpfd;
- wglDescribeLayerPlane(myDc, d->pixelFormatId, d->glFormat.plane(), sizeof(LAYERPLANEDESCRIPTOR), &lpfd);
- d->glFormat.setDoubleBuffer(lpfd.dwFlags & LPD_DOUBLEBUFFER);
- d->glFormat.setDepth(lpfd.cDepthBits);
- d->glFormat.setRgba(lpfd.iPixelType == PFD_TYPE_RGBA);
- if (d->glFormat.rgba()) {
- if (d->glFormat.redBufferSize() != -1)
- d->glFormat.setRedBufferSize(lpfd.cRedBits);
- if (d->glFormat.greenBufferSize() != -1)
- d->glFormat.setGreenBufferSize(lpfd.cGreenBits);
- if (d->glFormat.blueBufferSize() != -1)
- d->glFormat.setBlueBufferSize(lpfd.cBlueBits);
- }
- d->glFormat.setAlpha(lpfd.cAlphaBits);
- d->glFormat.setAccum(lpfd.cAccumBits);
- d->glFormat.setStencil(lpfd.cStencilBits);
- d->glFormat.setStereo(lpfd.dwFlags & LPD_STEREO);
- d->glFormat.setDirectRendering(false);
- if (d->glFormat.depth())
- d->glFormat.setDepthBufferSize(lpfd.cDepthBits);
- if (d->glFormat.alpha())
- d->glFormat.setAlphaBufferSize(lpfd.cAlphaBits);
- if (d->glFormat.accum())
- d->glFormat.setAccumBufferSize(lpfd.cAccumRedBits);
- if (d->glFormat.stencil())
- d->glFormat.setStencilBufferSize(lpfd.cStencilBits);
-
- if (d->glFormat.rgba()) {
- if (lpfd.dwFlags & LPD_TRANSPARENT)
- d->transpColor = QColor(lpfd.crTransparent & 0xff,
- (lpfd.crTransparent >> 8) & 0xff,
- (lpfd.crTransparent >> 16) & 0xff);
- else
- d->transpColor = QColor(0, 0, 0);
- }
- else {
- if (lpfd.dwFlags & LPD_TRANSPARENT)
- d->transpColor = QColor(qRgb(1, 2, 3));//, lpfd.crTransparent);
- else
- d->transpColor = QColor(qRgb(1, 2, 3));//, 0);
-
- d->cmap = new QGLCmap(1 << lpfd.cColorBits);
- d->cmap->setEntry(lpfd.crTransparent, qRgb(1, 2, 3));//, QGLCmap::Reserved);
- }
- } else {
- PIXELFORMATDESCRIPTOR pfd;
- PIXELFORMATDESCRIPTOR realPfd;
- d->pixelFormatId = choosePixelFormat(&pfd, myDc);
- if (d->pixelFormatId == 0) {
- qwglError("QGLContext::chooseContext()", "ChoosePixelFormat");
- result = false;
- goto end;
- }
-
- bool overlayRequested = d->glFormat.hasOverlay();
- DescribePixelFormat(myDc, d->pixelFormatId, sizeof(PIXELFORMATDESCRIPTOR), &realPfd);
-
- if (!deviceIsPixmap() && wglGetProcAddress("wglGetPixelFormatAttribivARB"))
- d->glFormat = pfiToQGLFormat(myDc, d->pixelFormatId);
- else
- d->glFormat = pfdToQGLFormat(&realPfd);
-
- d->glFormat.setOverlay(d->glFormat.hasOverlay() && overlayRequested);
-
- if (deviceIsPixmap() && !(realPfd.dwFlags & PFD_DRAW_TO_BITMAP)) {
- qWarning("QGLContext::chooseContext(): Failed to get pixmap rendering context.");
- result = false;
- goto end;
- }
-
- if (deviceIsPixmap() &&
- (((QPixmap*)d->paintDevice)->depth() != realPfd.cColorBits)) {
- qWarning("QGLContext::chooseContext(): Failed to get pixmap rendering context of suitable depth.");
- result = false;
- goto end;
- }
-
- if (!SetPixelFormat(myDc, d->pixelFormatId, &realPfd)) {
- qwglError("QGLContext::chooseContext()", "SetPixelFormat");
- result = false;
- goto end;
- }
-
- if (!qgl_create_context(myDc, d, share)) {
- qwglError("QGLContext::chooseContext()", "wglCreateContext");
- result = false;
- goto end;
- }
-
- if(!deviceIsPixmap()) {
- QRgb* pal = qgl_create_rgb_palette(&realPfd);
- if (pal) {
- QGLColormap cmap;
- cmap.setEntries(256, pal);
- ((QGLWidget*)d->paintDevice)->setColormap(cmap);
- delete[] pal;
- }
- }
- }
-
-end:
- // vblanking
- wglMakeCurrent(myDc, d->rc);
- if (d->rc)
- d->updateFormatVersion();
-
- typedef BOOL (APIENTRYP PFNWGLSWAPINTERVALEXT) (int interval);
- typedef int (APIENTRYP PFNWGLGETSWAPINTERVALEXT) (void);
- PFNWGLSWAPINTERVALEXT wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXT) wglGetProcAddress("wglSwapIntervalEXT");
- PFNWGLGETSWAPINTERVALEXT wglGetSwapIntervalEXT = (PFNWGLGETSWAPINTERVALEXT) wglGetProcAddress("wglGetSwapIntervalEXT");
- if (wglSwapIntervalEXT && wglGetSwapIntervalEXT) {
- if (d->reqFormat.swapInterval() != -1)
- wglSwapIntervalEXT(d->reqFormat.swapInterval());
- d->glFormat.setSwapInterval(wglGetSwapIntervalEXT());
- }
-
- if (d->win)
- ReleaseDC(d->win, myDc);
- return result;
-}
-
-
-
-static bool qLogEq(bool a, bool b)
-{
- return (((!a) && (!b)) || (a && b));
-}
-
-/*
- See qgl.cpp for qdoc comment.
- */
-int QGLContext::choosePixelFormat(void* dummyPfd, HDC pdc)
-{
- Q_D(QGLContext);
- // workaround for matrox driver:
- // make a cheap call to opengl to force loading of DLL
- if (!opengl32dll) {
- GLint params;
- glGetIntegerv(GL_DEPTH_BITS, &params);
- opengl32dll = true;
- }
-
- PFNWGLCHOOSEPIXELFORMATARB wglChoosePixelFormatARB =
- (PFNWGLCHOOSEPIXELFORMATARB) wglGetProcAddress("wglChoosePixelFormatARB");
- int chosenPfi = 0;
- if (!deviceIsPixmap() && wglChoosePixelFormatARB) {
- bool valid;
- int pixelFormat = 0;
- uint numFormats = 0;
- QVarLengthArray<int> iAttributes(40);
- int i = 0;
- iAttributes[i++] = WGL_ACCELERATION_ARB;
- if (d->glFormat.directRendering())
- iAttributes[i++] = WGL_FULL_ACCELERATION_ARB;
- else
- iAttributes[i++] = WGL_NO_ACCELERATION_ARB;
- iAttributes[i++] = WGL_SUPPORT_OPENGL_ARB;
- iAttributes[i++] = TRUE;
- iAttributes[i++] = WGL_DRAW_TO_WINDOW_ARB;
- iAttributes[i++] = TRUE;
- iAttributes[i++] = WGL_COLOR_BITS_ARB;
- iAttributes[i++] = 24;
- iAttributes[i++] = WGL_DOUBLE_BUFFER_ARB;
- iAttributes[i++] = d->glFormat.doubleBuffer();
- if (d->glFormat.stereo()) {
- iAttributes[i++] = WGL_STEREO_ARB;
- iAttributes[i++] = TRUE;
- }
- if (d->glFormat.depth()) {
- iAttributes[i++] = WGL_DEPTH_BITS_ARB;
- iAttributes[i++] = d->glFormat.depthBufferSize() == -1 ? 24 : d->glFormat.depthBufferSize();
- }
- iAttributes[i++] = WGL_PIXEL_TYPE_ARB;
- if (d->glFormat.rgba()) {
- iAttributes[i++] = WGL_TYPE_RGBA_ARB;
- if (d->glFormat.redBufferSize() != -1) {
- iAttributes[i++] = WGL_RED_BITS_ARB;
- iAttributes[i++] = d->glFormat.redBufferSize();
- }
- if (d->glFormat.greenBufferSize() != -1) {
- iAttributes[i++] = WGL_GREEN_BITS_ARB;
- iAttributes[i++] = d->glFormat.greenBufferSize();
- }
- if (d->glFormat.blueBufferSize() != -1) {
- iAttributes[i++] = WGL_BLUE_BITS_ARB;
- iAttributes[i++] = d->glFormat.blueBufferSize();
- }
- } else {
- iAttributes[i++] = WGL_TYPE_COLORINDEX_ARB;
- }
- if (d->glFormat.alpha()) {
- iAttributes[i++] = WGL_ALPHA_BITS_ARB;
- iAttributes[i++] = d->glFormat.alphaBufferSize() == -1 ? 8 : d->glFormat.alphaBufferSize();
- }
- if (d->glFormat.accum()) {
- iAttributes[i++] = WGL_ACCUM_BITS_ARB;
- iAttributes[i++] = d->glFormat.accumBufferSize() == -1 ? 16 : d->glFormat.accumBufferSize();
- }
- if (d->glFormat.stencil()) {
- iAttributes[i++] = WGL_STENCIL_BITS_ARB;
- iAttributes[i++] = d->glFormat.stencilBufferSize() == -1 ? 8 : d->glFormat.stencilBufferSize();
- }
- if (d->glFormat.hasOverlay()) {
- iAttributes[i++] = WGL_NUMBER_OVERLAYS_ARB;
- iAttributes[i++] = 1;
- }
- int si = 0;
- bool trySampleBuffers = QGLExtensions::glExtensions() & QGLExtensions::SampleBuffers;
- if (trySampleBuffers && d->glFormat.sampleBuffers()) {
- iAttributes[i++] = WGL_SAMPLE_BUFFERS_ARB;
- iAttributes[i++] = TRUE;
- iAttributes[i++] = WGL_SAMPLES_ARB;
- si = i;
- iAttributes[i++] = d->glFormat.samples() == -1 ? 4 : d->glFormat.samples();
- }
- iAttributes[i] = 0;
-
- do {
- valid = wglChoosePixelFormatARB(pdc, iAttributes.constData(), 0, 1,
- &pixelFormat, &numFormats);
- if (trySampleBuffers && (!valid || numFormats < 1) && d->glFormat.sampleBuffers())
- iAttributes[si] /= 2; // try different no. samples - we aim for the best one
- else
- break;
- } while ((!valid || numFormats < 1) && iAttributes[si] > 1);
- chosenPfi = pixelFormat;
- }
-
- if (!chosenPfi) { // fallback if wglChoosePixelFormatARB() failed
- int pmDepth = deviceIsPixmap() ? ((QPixmap*)d->paintDevice)->depth() : 0;
- PIXELFORMATDESCRIPTOR* p = (PIXELFORMATDESCRIPTOR*)dummyPfd;
- memset(p, 0, sizeof(PIXELFORMATDESCRIPTOR));
- p->nSize = sizeof(PIXELFORMATDESCRIPTOR);
- p->nVersion = 1;
- p->dwFlags = PFD_SUPPORT_OPENGL;
- if (deviceIsPixmap())
- p->dwFlags |= PFD_DRAW_TO_BITMAP;
- else
- p->dwFlags |= PFD_DRAW_TO_WINDOW;
- if (!d->glFormat.directRendering())
- p->dwFlags |= PFD_GENERIC_FORMAT;
- if (d->glFormat.doubleBuffer() && !deviceIsPixmap())
- p->dwFlags |= PFD_DOUBLEBUFFER;
- if (d->glFormat.stereo())
- p->dwFlags |= PFD_STEREO;
- if (d->glFormat.depth())
- p->cDepthBits = d->glFormat.depthBufferSize() == -1 ? 32 : d->glFormat.depthBufferSize();
- else
- p->dwFlags |= PFD_DEPTH_DONTCARE;
- if (d->glFormat.rgba()) {
- p->iPixelType = PFD_TYPE_RGBA;
- if (d->glFormat.redBufferSize() != -1)
- p->cRedBits = d->glFormat.redBufferSize();
- if (d->glFormat.greenBufferSize() != -1)
- p->cGreenBits = d->glFormat.greenBufferSize();
- if (d->glFormat.blueBufferSize() != -1)
- p->cBlueBits = d->glFormat.blueBufferSize();
- if (deviceIsPixmap())
- p->cColorBits = pmDepth;
- else
- p->cColorBits = 32;
- } else {
- p->iPixelType = PFD_TYPE_COLORINDEX;
- p->cColorBits = 8;
- }
- if (d->glFormat.alpha())
- p->cAlphaBits = d->glFormat.alphaBufferSize() == -1 ? 8 : d->glFormat.alphaBufferSize();
- if (d->glFormat.accum()) {
- p->cAccumRedBits = p->cAccumGreenBits = p->cAccumBlueBits = p->cAccumAlphaBits =
- d->glFormat.accumBufferSize() == -1 ? 16 : d->glFormat.accumBufferSize();
- }
- if (d->glFormat.stencil())
- p->cStencilBits = d->glFormat.stencilBufferSize() == -1 ? 8 : d->glFormat.stencilBufferSize();
- p->iLayerType = PFD_MAIN_PLANE;
- chosenPfi = ChoosePixelFormat(pdc, p);
-
- if (!chosenPfi)
- qErrnoWarning("QGLContext: ChoosePixelFormat failed");
-
- // Since the GDI function ChoosePixelFormat() does not handle
- // overlay and direct-rendering requests, we must roll our own here
-
- bool doSearch = chosenPfi <= 0;
- PIXELFORMATDESCRIPTOR pfd;
- QGLFormat fmt;
- if (!doSearch) {
- DescribePixelFormat(pdc, chosenPfi, sizeof(PIXELFORMATDESCRIPTOR),
- &pfd);
- fmt = pfdToQGLFormat(&pfd);
- if (d->glFormat.hasOverlay() && !fmt.hasOverlay())
- doSearch = true;
- else if (!qLogEq(d->glFormat.directRendering(), fmt.directRendering()))
- doSearch = true;
- else if (deviceIsPixmap() && (!(pfd.dwFlags & PFD_DRAW_TO_BITMAP) ||
- pfd.cColorBits != pmDepth))
- doSearch = true;
- else if (!deviceIsPixmap() && !(pfd.dwFlags & PFD_DRAW_TO_WINDOW))
- doSearch = true;
- else if (!qLogEq(d->glFormat.rgba(), fmt.rgba()))
- doSearch = true;
- }
-
- if (doSearch) {
- int pfiMax = DescribePixelFormat(pdc, 0, 0, NULL);
- int bestScore = -1;
- int bestPfi = -1;
- for (int pfi = 1; pfi <= pfiMax; pfi++) {
- DescribePixelFormat(pdc, pfi, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
- if (!(pfd.dwFlags & PFD_SUPPORT_OPENGL))
- continue;
- if (deviceIsPixmap() && (!(pfd.dwFlags & PFD_DRAW_TO_BITMAP) ||
- pfd.cColorBits != pmDepth))
- continue;
- if (!deviceIsPixmap() && !(pfd.dwFlags & PFD_DRAW_TO_WINDOW))
- continue;
-
- fmt = pfdToQGLFormat(&pfd);
- if (d->glFormat.hasOverlay() && !fmt.hasOverlay())
- continue;
-
- int score = pfd.cColorBits;
- if (qLogEq(d->glFormat.depth(), fmt.depth()))
- score += pfd.cDepthBits;
- if (qLogEq(d->glFormat.alpha(), fmt.alpha()))
- score += pfd.cAlphaBits;
- if (qLogEq(d->glFormat.accum(), fmt.accum()))
- score += pfd.cAccumBits;
- if (qLogEq(d->glFormat.stencil(), fmt.stencil()))
- score += pfd.cStencilBits;
- if (qLogEq(d->glFormat.doubleBuffer(), fmt.doubleBuffer()))
- score += 1000;
- if (qLogEq(d->glFormat.stereo(), fmt.stereo()))
- score += 2000;
- if (qLogEq(d->glFormat.directRendering(), fmt.directRendering()))
- score += 4000;
- if (qLogEq(d->glFormat.rgba(), fmt.rgba()))
- score += 8000;
- if (score > bestScore) {
- bestScore = score;
- bestPfi = pfi;
- }
- }
-
- if (bestPfi > 0)
- chosenPfi = bestPfi;
- }
- }
- return chosenPfi;
-}
-
-
-
-void QGLContext::reset()
-{
- Q_D(QGLContext);
- // workaround for matrox driver:
- // make a cheap call to opengl to force loading of DLL
- if (!opengl32dll) {
- GLint params;
- glGetIntegerv(GL_DEPTH_BITS, &params);
- opengl32dll = true;
- }
-
- if (!d->valid)
- return;
- d->cleanup();
- doneCurrent();
- if (d->rc)
- wglDeleteContext(d->rc);
- d->rc = 0;
- if (d->win && d->dc)
- ReleaseDC(d->win, d->dc);
- if (deviceIsPixmap()) {
- DeleteDC(d->hbitmap_hdc);
- DeleteObject(d->hbitmap);
- d->hbitmap_hdc = 0;
- d->hbitmap = 0;
- }
- d->dc = 0;
- d->win = 0;
- d->threadId = 0;
- d->pixelFormatId = 0;
- d->sharing = false;
- d->valid = false;
- d->transpColor = QColor();
- delete d->cmap;
- d->cmap = 0;
- d->initDone = false;
- QGLContextGroup::removeShare(this);
-}
-
-//
-// NOTE: In a multi-threaded environment, each thread has a current
-// context. If we want to make this code thread-safe, we probably
-// have to use TLS (thread local storage) for keeping current contexts.
-//
-
-void QGLContext::makeCurrent()
-{
- Q_D(QGLContext);
- if (d->rc == wglGetCurrentContext() || !d->valid) // already current
- return;
-
- if (d->win && (!d->dc || d->threadId != QThread::currentThreadId())) {
- d->dc = GetDC(d->win);
- d->threadId = QThread::currentThreadId();
- if (!d->dc) {
- qwglError("QGLContext::makeCurrent()", "GetDC()");
- return;
- }
- } else if (deviceIsPixmap()) {
- d->dc = d->hbitmap_hdc;
- }
-
- HPALETTE hpal = QColormap::hPal();
- if (hpal) {
- SelectPalette(d->dc, hpal, FALSE);
- RealizePalette(d->dc);
- }
- if (d->glFormat.plane()) {
- wglRealizeLayerPalette(d->dc, d->glFormat.plane(), TRUE);
- }
-
- if (wglMakeCurrent(d->dc, d->rc)) {
- QGLContextPrivate::setCurrentContext(this);
- } else {
- qwglError("QGLContext::makeCurrent()", "wglMakeCurrent");
- }
-}
-
-
-void QGLContext::doneCurrent()
-{
- Q_D(QGLContext);
- wglMakeCurrent(0, 0);
- QGLContextPrivate::setCurrentContext(0);
- if (deviceIsPixmap() && d->hbitmap) {
- QPixmap *pm = static_cast<QPixmap *>(d->paintDevice);
- *pm = QPixmap::fromWinHBITMAP(d->hbitmap);
- }
- if (d->win && d->dc) {
- ReleaseDC(d->win, d->dc);
- d->dc = 0;
- d->threadId = 0;
- }
-}
-
-void QGLContext::swapBuffers() const
-{
- Q_D(const QGLContext);
- if (d->dc && d->glFormat.doubleBuffer() && !deviceIsPixmap()) {
- if (d->glFormat.plane())
- wglSwapLayerBuffers(d->dc, WGL_SWAP_OVERLAY1);
- else {
- if (d->glFormat.hasOverlay())
- wglSwapLayerBuffers(d->dc, WGL_SWAP_MAIN_PLANE);
- else
- SwapBuffers(d->dc);
- }
- }
-}
-
-
-QColor QGLContext::overlayTransparentColor() const
-{
- return d_func()->transpColor;
-}
-
-
-uint QGLContext::colorIndex(const QColor& c) const
-{
- Q_D(const QGLContext);
- if (!isValid())
- return 0;
- if (d->cmap) {
- int idx = d->cmap->find(c.rgb());
- if (idx >= 0)
- return idx;
- if (d->dc && d->glFormat.plane()) {
- idx = d->cmap->allocate(c.rgb());
- if (idx >= 0) {
- COLORREF r = RGB(qRed(c.rgb()),qGreen(c.rgb()),qBlue(c.rgb()));
- wglSetLayerPaletteEntries(d->dc, d->glFormat.plane(), idx, 1, &r);
- wglRealizeLayerPalette(d->dc, d->glFormat.plane(), TRUE);
- return idx;
- }
- }
- return d->cmap->findNearest(c.rgb());
- }
- QColormap cmap = QColormap::instance();
- return cmap.pixel(c) & 0x00ffffff; // Assumes standard palette
-}
-
-void QGLContext::generateFontDisplayLists(const QFont & fnt, int listBase)
-{
- if (!isValid())
- return;
-
- HDC display_dc = GetDC(0);
- HDC tmp_dc = CreateCompatibleDC(display_dc);
- HGDIOBJ old_font = SelectObject(tmp_dc, fnt.handle());
-
- ReleaseDC(0, display_dc);
-
- if (!wglUseFontBitmaps(tmp_dc, 0, 256, listBase))
- qWarning("QGLContext::generateFontDisplayLists: Could not generate display lists for font '%s'", fnt.family().toLatin1().data());
-
- SelectObject(tmp_dc, old_font);
- DeleteDC(tmp_dc);
-}
-
-void *QGLContext::getProcAddress(const QString &proc) const
-{
- return (void *)wglGetProcAddress(proc.toLatin1());
-}
-
-/*****************************************************************************
- QGLWidget Win32/WGL-specific code
- *****************************************************************************/
-
-void QGLWidgetPrivate::init(QGLContext *ctx, const QGLWidget* shareWidget)
-{
- Q_Q(QGLWidget);
- olcx = 0;
- initContext(ctx, shareWidget);
-
- if (q->isValid() && q->context()->format().hasOverlay()) {
- olcx = new QGLContext(QGLFormat::defaultOverlayFormat(), q);
- if (!olcx->create(shareWidget ? shareWidget->overlayContext() : 0)) {
- delete olcx;
- olcx = 0;
- glcx->d_func()->glFormat.setOverlay(false);
- }
- } else {
- olcx = 0;
- }
-}
-
-/*\internal
- Store color values in the given colormap.
-*/
-static void qStoreColors(HPALETTE cmap, const QGLColormap & cols)
-{
- QRgb color;
- PALETTEENTRY pe;
-
- for (int i = 0; i < cols.size(); i++) {
- color = cols.entryRgb(i);
- pe.peRed = qRed(color);
- pe.peGreen = qGreen(color);
- pe.peBlue = qBlue(color);
- pe.peFlags = 0;
-
- SetPaletteEntries(cmap, i, 1, &pe);
- }
-}
-
-void QGLWidgetPrivate::updateColormap()
-{
- Q_Q(QGLWidget);
- if (!cmap.handle())
- return;
- HDC hdc = GetDC(q->winId());
- SelectPalette(hdc, (HPALETTE) cmap.handle(), TRUE);
- qStoreColors((HPALETTE) cmap.handle(), cmap);
- RealizePalette(hdc);
- ReleaseDC(q->winId(), hdc);
-}
-
-void QGLWidget::setMouseTracking(bool enable)
-{
- QWidget::setMouseTracking(enable);
-}
-
-
-void QGLWidget::resizeEvent(QResizeEvent *)
-{
- Q_D(QGLWidget);
- if (!isValid())
- return;
- makeCurrent();
- if (!d->glcx->initialized())
- glInit();
- resizeGL(width(), height());
- if (d->olcx) {
- makeOverlayCurrent();
- resizeOverlayGL(width(), height());
- }
-}
-
-
-const QGLContext* QGLWidget::overlayContext() const
-{
- return d_func()->olcx;
-}
-
-
-void QGLWidget::makeOverlayCurrent()
-{
- Q_D(QGLWidget);
- if (d->olcx) {
- d->olcx->makeCurrent();
- if (!d->olcx->initialized()) {
- initializeOverlayGL();
- d->olcx->setInitialized(true);
- }
- }
-}
-
-
-void QGLWidget::updateOverlayGL()
-{
- Q_D(QGLWidget);
- if (d->olcx) {
- makeOverlayCurrent();
- paintOverlayGL();
- if (d->olcx->format().doubleBuffer()) {
- if (d->autoSwap)
- d->olcx->swapBuffers();
- }
- else {
- glFlush();
- }
- }
-}
-
-
-void QGLWidget::setContext(QGLContext *context,
- const QGLContext* shareContext,
- bool deleteOldContext)
-{
- Q_D(QGLWidget);
- if (context == 0) {
- qWarning("QGLWidget::setContext: Cannot set null context");
- return;
- }
- if (!context->deviceIsPixmap() && context->device() != this) {
- qWarning("QGLWidget::setContext: Context must refer to this widget");
- return;
- }
-
- if (d->glcx)
- d->glcx->doneCurrent();
- QGLContext* oldcx = d->glcx;
- d->glcx = context;
-
- bool doShow = false;
- if (oldcx && oldcx->d_func()->win == winId() && !d->glcx->deviceIsPixmap()) {
- // We already have a context and must therefore create a new
- // window since Windows does not permit setting a new OpenGL
- // context for a window that already has one set.
- doShow = isVisible();
- QWidget *pW = static_cast<QWidget *>(parent());
- QPoint pos = geometry().topLeft();
- setParent(pW, windowFlags());
- move(pos);
- }
-
- if (!d->glcx->isValid()) {
- bool wasSharing = shareContext || (oldcx && oldcx->isSharing());
- d->glcx->create(shareContext ? shareContext : oldcx);
- // the above is a trick to keep disp lists etc when a
- // QGLWidget has been reparented, so remove the sharing
- // flag if we don't actually have a sharing context.
- if (!wasSharing)
- d->glcx->d_ptr->sharing = false;
- }
-
- if (deleteOldContext)
- delete oldcx;
-
- if (doShow)
- show();
-}
-
-
-bool QGLWidgetPrivate::renderCxPm(QPixmap*)
-{
- return false;
-}
-
-void QGLWidgetPrivate::cleanupColormaps()
-{
- Q_Q(QGLWidget);
- if (cmap.handle()) {
- HDC hdc = GetDC(q->winId());
- SelectPalette(hdc, (HPALETTE) GetStockObject(DEFAULT_PALETTE), FALSE);
- DeleteObject((HPALETTE) cmap.handle());
- ReleaseDC(q->winId(), hdc);
- cmap.setHandle(0);
- }
- return;
-}
-
-const QGLColormap & QGLWidget::colormap() const
-{
- return d_func()->cmap;
-}
-
-void QGLWidget::setColormap(const QGLColormap & c)
-{
- Q_D(QGLWidget);
- d->cmap = c;
-
- if (d->cmap.handle()) { // already have an allocated cmap
- d->updateColormap();
- } else {
- LOGPALETTE *lpal = (LOGPALETTE *) malloc(sizeof(LOGPALETTE)
- +c.size()*sizeof(PALETTEENTRY));
- lpal->palVersion = 0x300;
- lpal->palNumEntries = c.size();
- d->cmap.setHandle(CreatePalette(lpal));
- free(lpal);
- d->updateColormap();
- }
-}
-
-QT_END_NAMESPACE
diff --git a/src/opengl/qgl_wince.cpp b/src/opengl/qgl_wince.cpp
deleted file mode 100644
index d6d8f24bfa..0000000000
--- a/src/opengl/qgl_wince.cpp
+++ /dev/null
@@ -1,636 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#include <qgl.h>
-#include <qlist.h>
-#include <qmap.h>
-#include <qpixmap.h>
-#include <qevent.h>
-#include <private/qgl_p.h>
-#include <qcolormap.h>
-#include <qvarlengtharray.h>
-#include <qdebug.h>
-#include <qapplication.h>
-#include <qdesktopwidget>
-
-#include <windows.h>
-
-#include <private/qeglproperties_p.h>
-#include <private/qeglcontext_p.h>
-#include <private/qgl_egl_p.h>
-
-
-QT_BEGIN_NAMESPACE
-
-
-
-class QGLCmapPrivate
-{
-public:
- QGLCmapPrivate() : count(1) { }
- void ref() { ++count; }
- bool deref() { return !--count; }
- uint count;
-
- enum AllocState{ UnAllocated = 0, Allocated = 0x01, Reserved = 0x02 };
-
- int maxSize;
- QVector<uint> colorArray;
- QVector<quint8> allocArray;
- QVector<quint8> contextArray;
- QMap<uint,int> colorMap;
-};
-
-/*****************************************************************************
- QColorMap class - temporarily here, until it is ready for prime time
- *****************************************************************************/
-
-/****************************************************************************
-**
-** Definition of QColorMap class
-**
-****************************************************************************/
-
-#ifndef QGLCMAP_H
-#define QGLCMAP_H
-
-#include <qcolor.h>
-
-/*
- QGLTemporaryContext implementation
-*/
-
-class QGLTemporaryContextPrivate
-{
-public:
- QGLWidget *widget;
-};
-
-QGLTemporaryContext::QGLTemporaryContext(bool, QWidget *)
- : d(new QGLTemporaryContextPrivate)
-{
- d->widget = new QGLWidget;
- d->widget->makeCurrent();
-}
-
-QGLTemporaryContext::~QGLTemporaryContext()
-{
- delete d->widget;
-}
-
-/*****************************************************************************
- QGLFormat Win32/WGL-specific code
- *****************************************************************************/
-
-static bool opengl32dll = false;
-
-bool QGLFormat::hasOpenGLOverlays()
-{
- return false; // ###
-}
-
-
-bool QGLContext::chooseContext(const QGLContext* shareContext)
-{
- Q_D(QGLContext);
-
- // Validate the device.
- if (!device())
- return false;
- int devType = device()->devType();
- if (devType != QInternal::Pixmap && devType != QInternal::Image && devType != QInternal::Widget) {
- qWarning("QGLContext::chooseContext(): Cannot create QGLContext's for paint device type %d", devType);
- return false;
- }
-
- // Get the display and initialize it.
- d->eglContext = new QEglContext();
- d->ownsEglContext = true;
- d->eglContext->setApi(QEgl::OpenGL);
-
- // Construct the configuration we need for this surface.
- QEglProperties configProps;
- qt_eglproperties_set_glformat(configProps, d->glFormat);
- configProps.setDeviceType(devType);
- configProps.setPaintDeviceFormat(device());
- configProps.setRenderableType(QEgl::OpenGL);
-
- // Search for a matching configuration, reducing the complexity
- // each time until we get something that matches.
- if (!d->eglContext->chooseConfig(configProps)) {
- delete d->eglContext;
- d->eglContext = 0;
- return false;
- }
-
- // Inform the higher layers about the actual format properties.
- qt_glformat_from_eglconfig(d->glFormat, d->eglContext->config());
-
- // Create a new context for the configuration.
- if (!d->eglContext->createContext
- (shareContext ? shareContext->d_func()->eglContext : 0)) {
- delete d->eglContext;
- d->eglContext = 0;
- return false;
- }
- d->sharing = d->eglContext->isSharing();
- if (d->sharing && shareContext)
- const_cast<QGLContext *>(shareContext)->d_func()->sharing = true;
-
-#if defined(EGL_VERSION_1_1)
- if (d->glFormat.swapInterval() != -1 && devType == QInternal::Widget)
- eglSwapInterval(d->eglContext->display(), d->glFormat.swapInterval());
-#endif
-
- // Create the EGL surface to draw into.
- d->eglSurface = d->eglContext->createSurface(device());
- if (d->eglSurface == EGL_NO_SURFACE) {
- delete d->eglContext;
- d->eglContext = 0;
- return false;
- }
-
- return true;
-
-}
-
-
-
-static bool qLogEq(bool a, bool b)
-{
- return (((!a) && (!b)) || (a && b));
-}
-
-int QGLContext::choosePixelFormat(void* , HDC )
-{
-
- return 0;
-}
-
-class QGLCmapPrivate;
-
-class /*Q_EXPORT*/ QGLCmap
-{
-public:
- enum Flags { Reserved = 0x01 };
-
- QGLCmap(int maxSize = 256);
- QGLCmap(const QGLCmap& map);
- ~QGLCmap();
-
- QGLCmap& operator=(const QGLCmap& map);
-
- // isEmpty and/or isNull ?
- int size() const;
- int maxSize() const;
-
- void resize(int newSize);
-
- int find(QRgb color) const;
- int findNearest(QRgb color) const;
- int allocate(QRgb color, uint flags = 0, quint8 context = 0);
-
- void setEntry(int idx, QRgb color, uint flags = 0, quint8 context = 0);
-
- const QRgb* colors() const;
-
-private:
- void detach();
- QGLCmapPrivate* d;
-};
-
-#endif
-
-
-QGLCmap::QGLCmap(int maxSize) // add a bool prealloc?
-{
- d = new QGLCmapPrivate;
- d->maxSize = maxSize;
-}
-
-QGLCmap::QGLCmap(const QGLCmap& map)
-{
- d = map.d;
- d->ref();
-}
-
-QGLCmap::~QGLCmap()
-{
- if (d && d->deref())
- delete d;
- d = 0;
-}
-
-QGLCmap& QGLCmap::operator=(const QGLCmap& map)
-{
- map.d->ref();
- if (d->deref())
- delete d;
- d = map.d;
- return *this;
-}
-
-int QGLCmap::size() const
-{
- return d->colorArray.size();
-}
-
-int QGLCmap::maxSize() const
-{
- return d->maxSize;
-}
-
-void QGLCmap::detach()
-{
- if (d->count != 1) {
- d->deref();
- QGLCmapPrivate* newd = new QGLCmapPrivate;
- newd->maxSize = d->maxSize;
- newd->colorArray = d->colorArray;
- newd->allocArray = d->allocArray;
- newd->contextArray = d->contextArray;
- newd->colorArray.detach();
- newd->allocArray.detach();
- newd->contextArray.detach();
- newd->colorMap = d->colorMap;
- d = newd;
- }
-}
-
-
-void QGLCmap::resize(int newSize)
-{
- if (newSize < 0 || newSize > d->maxSize) {
- qWarning("QGLCmap::resize(): size out of range");
- return;
- }
- int oldSize = size();
- detach();
- //if shrinking; remove the lost elems from colorMap
- d->colorArray.resize(newSize);
- d->allocArray.resize(newSize);
- d->contextArray.resize(newSize);
- if (newSize > oldSize) {
- memset(d->allocArray.data() + oldSize, 0, newSize - oldSize);
- memset(d->contextArray.data() + oldSize, 0, newSize - oldSize);
- }
-}
-
-
-int QGLCmap::find(QRgb color) const
-{
- QMap<uint,int>::ConstIterator it = d->colorMap.find(color);
- if (it != d->colorMap.end())
- return *it;
- return -1;
-}
-
-
-int QGLCmap::findNearest(QRgb color) const
-{
- int idx = find(color);
- if (idx >= 0)
- return idx;
- int mapSize = size();
- int mindist = 200000;
- int r = qRed(color);
- int g = qGreen(color);
- int b = qBlue(color);
- int rx, gx, bx, dist;
- for (int i=0; i < mapSize; i++) {
- if (!(d->allocArray[i] & QGLCmapPrivate::Allocated))
- continue;
- QRgb ci = d->colorArray[i];
- rx = r - qRed(ci);
- gx = g - qGreen(ci);
- bx = b - qBlue(ci);
- dist = rx*rx + gx*gx + bx*bx; // calculate distance
- if (dist < mindist) { // minimal?
- mindist = dist;
- idx = i;
- }
- }
- return idx;
-}
-
-
-// Does not always allocate; returns existing c idx if found
-
-int QGLCmap::allocate(QRgb color, uint flags, quint8 context)
-{
- int idx = find(color);
- if (idx >= 0)
- return idx;
-
- int mapSize = d->colorArray.size();
- int newIdx = d->allocArray.indexOf(QGLCmapPrivate::UnAllocated);
-
- if (newIdx < 0) { // Must allocate more room
- if (mapSize < d->maxSize) {
- newIdx = mapSize;
- mapSize++;
- resize(mapSize);
- }
- else {
- //# add a bool param that says what to do in case no more room -
- // fail (-1) or return nearest?
- return -1;
- }
- }
-
- d->colorArray[newIdx] = color;
- if (flags & QGLCmap::Reserved) {
- d->allocArray[newIdx] = QGLCmapPrivate::Reserved;
- }
- else {
- d->allocArray[newIdx] = QGLCmapPrivate::Allocated;
- d->colorMap.insert(color, newIdx);
- }
- d->contextArray[newIdx] = context;
- return newIdx;
-}
-
-
-void QGLCmap::setEntry(int idx, QRgb color, uint flags, quint8 context)
-{
- if (idx < 0 || idx >= d->maxSize) {
- qWarning("QGLCmap::set(): Index out of range");
- return;
- }
- detach();
- int mapSize = size();
- if (idx >= mapSize) {
- mapSize = idx + 1;
- resize(mapSize);
- }
- d->colorArray[idx] = color;
- if (flags & QGLCmap::Reserved) {
- d->allocArray[idx] = QGLCmapPrivate::Reserved;
- }
- else {
- d->allocArray[idx] = QGLCmapPrivate::Allocated;
- d->colorMap.insert(color, idx);
- }
- d->contextArray[idx] = context;
-}
-
-
-const QRgb* QGLCmap::colors() const
-{
- return d->colorArray.data();
-}
-
-
-/*****************************************************************************
- QGLWidget Win32/WGL-specific code
- *****************************************************************************/
-
-void QGLWidgetPrivate::init(QGLContext *ctx, const QGLWidget* shareWidget)
-{
- Q_Q(QGLWidget);
- olcx = 0;
- initContext(ctx, shareWidget);
-
- if (q->isValid() && q->context()->format().hasOverlay()) {
- olcx = new QGLContext(QGLFormat::defaultOverlayFormat(), q);
- if (!olcx->create(shareWidget ? shareWidget->overlayContext() : 0)) {
- delete olcx;
- olcx = 0;
- glcx->d_func()->glFormat.setOverlay(false);
- }
- } else {
- olcx = 0;
- }
-}
-
-/*\internal
- Store color values in the given colormap.
-*/
-static void qStoreColors(HPALETTE cmap, const QGLColormap & cols)
-{
- QRgb color;
- PALETTEENTRY pe;
-
- for (int i = 0; i < cols.size(); i++) {
- color = cols.entryRgb(i);
- pe.peRed = qRed(color);
- pe.peGreen = qGreen(color);
- pe.peBlue = qBlue(color);
- pe.peFlags = 0;
-
- SetPaletteEntries(cmap, i, 1, &pe);
- }
-}
-
-void QGLWidgetPrivate::updateColormap()
-{
- Q_Q(QGLWidget);
- if (!cmap.handle())
- return;
- HDC hdc = GetDC(q->winId());
- SelectPalette(hdc, (HPALETTE) cmap.handle(), TRUE);
- qStoreColors((HPALETTE) cmap.handle(), cmap);
- RealizePalette(hdc);
- ReleaseDC(q->winId(), hdc);
-}
-
-bool QGLWidget::event(QEvent *e)
-{
- Q_D(QGLWidget);
- if (e->type() == QEvent::ParentChange) {
- setContext(new QGLContext(d->glcx->requestedFormat(), this));
- // the overlay needs to be recreated as well
- delete d->olcx;
- if (isValid() && context()->format().hasOverlay()) {
- d->olcx = new QGLContext(QGLFormat::defaultOverlayFormat(), this);
- if (!d->olcx->create(isSharing() ? d->glcx : 0)) {
- delete d->olcx;
- d->olcx = 0;
- d->glcx->d_func()->glFormat.setOverlay(false);
- }
- } else {
- d->olcx = 0;
- }
- } else if (e->type() == QEvent::Show && !format().rgba()) {
- d->updateColormap();
- }
-
- return QWidget::event(e);
-}
-
-
-void QGLWidget::resizeEvent(QResizeEvent *)
-{
- Q_D(QGLWidget);
- if (!isValid())
- return;
- makeCurrent();
- if (!d->glcx->initialized())
- glInit();
- resizeGL(width(), height());
- if (d->olcx) {
- makeOverlayCurrent();
- resizeOverlayGL(width(), height());
- }
-}
-
-
-const QGLContext* QGLWidget::overlayContext() const
-{
- return d_func()->olcx;
-}
-
-
-void QGLWidget::makeOverlayCurrent()
-{
- Q_D(QGLWidget);
- if (d->olcx) {
- d->olcx->makeCurrent();
- if (!d->olcx->initialized()) {
- initializeOverlayGL();
- d->olcx->setInitialized(true);
- }
- }
-}
-
-
-void QGLWidget::updateOverlayGL()
-{
- Q_D(QGLWidget);
- if (d->olcx) {
- makeOverlayCurrent();
- paintOverlayGL();
- if (d->olcx->format().doubleBuffer()) {
- if (d->autoSwap)
- d->olcx->swapBuffers();
- }
- else {
- glFlush();
- }
- }
-}
-
-void QGLWidget::setContext(QGLContext *context,
- const QGLContext* shareContext,
- bool deleteOldContext)
-{
- Q_D(QGLWidget);
- if (context == 0) {
- qWarning("QGLWidget::setContext: Cannot set null context");
- return;
- }
- if (!context->deviceIsPixmap() && context->device() != this) {
- qWarning("QGLWidget::setContext: Context must refer to this widget");
- return;
- }
-
- if (d->glcx)
- d->glcx->doneCurrent();
- QGLContext* oldcx = d->glcx;
- d->glcx = context;
-
- bool doShow = false;
- if (oldcx && oldcx->d_func()->win == winId() && !d->glcx->deviceIsPixmap()) {
- // We already have a context and must therefore create a new
- // window since Windows does not permit setting a new OpenGL
- // context for a window that already has one set.
- doShow = isVisible();
- QWidget *pW = static_cast<QWidget *>(parent());
- QPoint pos = geometry().topLeft();
- setParent(pW, windowFlags());
- move(pos);
- }
-
- if (!d->glcx->isValid()) {
- d->glcx->create(shareContext ? shareContext : oldcx);
- // the above is a trick to keep disp lists etc when a
- // QGLWidget has been reparented, so remove the sharing
- // flag if we don't actually have a sharing context.
- if (!shareContext)
- d->glcx->d_ptr->sharing = false;
- }
-
- if (deleteOldContext)
- delete oldcx;
-
- if (doShow)
- show();
-}
-
-
-void QGLWidgetPrivate::cleanupColormaps()
-{
- Q_Q(QGLWidget);
- if (cmap.handle()) {
- HDC hdc = GetDC(q->winId());
- SelectPalette(hdc, (HPALETTE) GetStockObject(DEFAULT_PALETTE), FALSE);
- DeleteObject((HPALETTE) cmap.handle());
- ReleaseDC(q->winId(), hdc);
- cmap.setHandle(0);
- }
- return;
-}
-
-const QGLColormap & QGLWidget::colormap() const
-{
- return d_func()->cmap;
-}
-
-void QGLWidget::setColormap(const QGLColormap & c)
-{
- Q_D(QGLWidget);
- d->cmap = c;
-
- if (d->cmap.handle()) { // already have an allocated cmap
- d->updateColormap();
- } else {
- LOGPALETTE *lpal = (LOGPALETTE *) malloc(sizeof(LOGPALETTE)
- +c.size()*sizeof(PALETTEENTRY));
- lpal->palVersion = 0x300;
- lpal->palNumEntries = c.size();
- d->cmap.setHandle(CreatePalette(lpal));
- free(lpal);
- d->updateColormap();
- }
-}
-
-QT_END_NAMESPACE
diff --git a/src/opengl/qgl_x11.cpp b/src/opengl/qgl_x11.cpp
deleted file mode 100644
index 22a222eb1b..0000000000
--- a/src/opengl/qgl_x11.cpp
+++ /dev/null
@@ -1,1904 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qgl.h"
-#include "qgl_p.h"
-
-#include "qmap.h"
-#include "qapplication.h"
-#include "qcolormap.h"
-#include "qdesktopwidget.h"
-#include "qpixmap.h"
-#include "qhash.h"
-#include "qlibrary.h"
-#include "qdebug.h"
-#include <private/qfontengine_ft_p.h>
-#include <private/qt_x11_p.h>
-#include <private/qpixmap_x11_p.h>
-#include <private/qimagepixmapcleanuphooks_p.h>
-#include <private/qunicodetables_p.h>
-#ifdef Q_OS_HPUX
-// for GLXPBuffer
-#include <private/qglpixelbuffer_p.h>
-#endif
-
-// We always define GLX_EXT_texture_from_pixmap ourselves because
-// we can't trust system headers to do it properly
-#define GLX_EXT_texture_from_pixmap 1
-
-#define INT8 dummy_INT8
-#define INT32 dummy_INT32
-#include <GL/glx.h>
-#undef INT8
-#undef INT32
-
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <X11/Xos.h>
-#ifdef Q_OS_VXWORS
-# ifdef open
-# undef open
-# endif
-# ifdef getpid
-# undef getpid
-# endif
-#endif // Q_OS_VXWORKS
-#include <X11/Xatom.h>
-
-#if defined(Q_OS_LINUX) || defined(Q_OS_BSD4)
-#include <dlfcn.h>
-#endif
-
-QT_BEGIN_NAMESPACE
-
-extern Drawable qt_x11Handle(const QPaintDevice *pd);
-extern const QX11Info *qt_x11Info(const QPaintDevice *pd);
-
-#ifndef GLX_ARB_multisample
-#define GLX_SAMPLE_BUFFERS_ARB 100000
-#define GLX_SAMPLES_ARB 100001
-#endif
-
-#ifndef GLX_TEXTURE_2D_BIT_EXT
-#define GLX_TEXTURE_2D_BIT_EXT 0x00000002
-#define GLX_TEXTURE_RECTANGLE_BIT_EXT 0x00000004
-#define GLX_BIND_TO_TEXTURE_RGB_EXT 0x20D0
-#define GLX_BIND_TO_TEXTURE_RGBA_EXT 0x20D1
-#define GLX_BIND_TO_MIPMAP_TEXTURE_EXT 0x20D2
-#define GLX_BIND_TO_TEXTURE_TARGETS_EXT 0x20D3
-#define GLX_Y_INVERTED_EXT 0x20D4
-#define GLX_TEXTURE_FORMAT_EXT 0x20D5
-#define GLX_TEXTURE_TARGET_EXT 0x20D6
-#define GLX_MIPMAP_TEXTURE_EXT 0x20D7
-#define GLX_TEXTURE_FORMAT_NONE_EXT 0x20D8
-#define GLX_TEXTURE_FORMAT_RGB_EXT 0x20D9
-#define GLX_TEXTURE_FORMAT_RGBA_EXT 0x20DA
-#define GLX_TEXTURE_2D_EXT 0x20DC
-#define GLX_TEXTURE_RECTANGLE_EXT 0x20DD
-#define GLX_FRONT_LEFT_EXT 0x20DE
-#endif
-
-#ifndef GLX_ARB_create_context
-#define GLX_CONTEXT_DEBUG_BIT_ARB 0x00000001
-#define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002
-#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091
-#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092
-#define GLX_CONTEXT_FLAGS_ARB 0x2094
-#endif
-
-#ifndef GLX_ARB_create_context_profile
-#define GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
-#define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
-#define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126
-#endif
-
-/*
- The qt_gl_choose_cmap function is internal and used by QGLWidget::setContext()
- and GLX (not Windows). If the application can't find any sharable
- colormaps, it must at least create as few colormaps as possible. The
- dictionary solution below ensures only one colormap is created per visual.
- Colormaps are also deleted when the application terminates.
-*/
-
-struct QCMapEntry {
- QCMapEntry();
- ~QCMapEntry();
-
- Colormap cmap;
- bool alloc;
- XStandardColormap scmap;
-};
-
-QCMapEntry::QCMapEntry()
-{
- cmap = 0;
- alloc = false;
- scmap.colormap = 0;
-}
-
-QCMapEntry::~QCMapEntry()
-{
- if (alloc)
- XFreeColormap(X11->display, cmap);
-}
-typedef QHash<int, QCMapEntry *> CMapEntryHash;
-typedef QHash<int, QMap<int, QRgb> > GLCMapHash;
-static bool mesa_gl = false;
-static bool first_time = true;
-
-static void cleanup_cmaps();
-
-struct QGLCMapCleanupHandler {
- QGLCMapCleanupHandler() {
- cmap_hash = new CMapEntryHash;
- qglcmap_hash = new GLCMapHash;
- }
- ~QGLCMapCleanupHandler() {
- delete cmap_hash;
- delete qglcmap_hash;
- }
- CMapEntryHash *cmap_hash;
- GLCMapHash *qglcmap_hash;
-};
-Q_GLOBAL_STATIC(QGLCMapCleanupHandler, cmap_handler)
-
-static void cleanup_cmaps()
-{
- CMapEntryHash *hash = cmap_handler()->cmap_hash;
- QHash<int, QCMapEntry *>::ConstIterator it = hash->constBegin();
- while (it != hash->constEnd()) {
- delete it.value();
- ++it;
- }
-
- hash->clear();
- cmap_handler()->qglcmap_hash->clear();
-}
-
-Colormap qt_gl_choose_cmap(Display *dpy, XVisualInfo *vi)
-{
- if (first_time) {
- const char *v = glXQueryServerString(dpy, vi->screen, GLX_VERSION);
- if (v)
- mesa_gl = (strstr(v, "Mesa") != 0);
- first_time = false;
- }
-
- CMapEntryHash *hash = cmap_handler()->cmap_hash;
- CMapEntryHash::ConstIterator it = hash->constFind((long) vi->visualid + (vi->screen * 256));
- if (it != hash->constEnd())
- return it.value()->cmap; // found colormap for visual
-
- if (vi->visualid ==
- XVisualIDFromVisual((Visual *) QX11Info::appVisual(vi->screen))) {
- // qDebug("Using x11AppColormap");
- return QX11Info::appColormap(vi->screen);
- }
-
- QCMapEntry *x = new QCMapEntry();
-
- XStandardColormap *c;
- int n, i;
-
- // qDebug("Choosing cmap for vID %0x", vi->visualid);
-
- if (mesa_gl) { // we're using MesaGL
- Atom hp_cmaps = XInternAtom(dpy, "_HP_RGB_SMOOTH_MAP_LIST", true);
- if (hp_cmaps && vi->visual->c_class == TrueColor && vi->depth == 8) {
- if (XGetRGBColormaps(dpy,RootWindow(dpy,vi->screen),&c,&n,
- hp_cmaps)) {
- i = 0;
- while (i < n && x->cmap == 0) {
- if (c[i].visualid == vi->visual->visualid) {
- x->cmap = c[i].colormap;
- x->scmap = c[i];
- //qDebug("Using HP_RGB scmap");
-
- }
- i++;
- }
- XFree((char *)c);
- }
- }
- }
- if (!x->cmap) {
- if (XGetRGBColormaps(dpy,RootWindow(dpy,vi->screen),&c,&n,
- XA_RGB_DEFAULT_MAP)) {
- for (int i = 0; i < n && x->cmap == 0; ++i) {
- if (!c[i].red_max ||
- !c[i].green_max ||
- !c[i].blue_max ||
- !c[i].red_mult ||
- !c[i].green_mult ||
- !c[i].blue_mult)
- continue; // invalid stdcmap
- if (c[i].visualid == vi->visualid) {
- x->cmap = c[i].colormap;
- x->scmap = c[i];
- //qDebug("Using RGB_DEFAULT scmap");
- }
- }
- XFree((char *)c);
- }
- }
- if (!x->cmap) { // no shared cmap found
- x->cmap = XCreateColormap(dpy, RootWindow(dpy,vi->screen), vi->visual,
- AllocNone);
- x->alloc = true;
- // qDebug("Allocating cmap");
- }
-
- // colormap hash should be cleanup only when the QApplication dtor is called
- if (hash->isEmpty())
- qAddPostRoutine(cleanup_cmaps);
-
- // associate cmap with visualid
- hash->insert((long) vi->visualid + (vi->screen * 256), x);
- return x->cmap;
-}
-
-struct QTransColor
-{
- VisualID vis;
- int screen;
- long color;
-};
-
-static QVector<QTransColor> trans_colors;
-static int trans_colors_init = false;
-
-static void find_trans_colors()
-{
- struct OverlayProp {
- long visual;
- long type;
- long value;
- long layer;
- };
-
- trans_colors_init = true;
-
- Display* appDisplay = X11->display;
-
- int scr;
- int lastsize = 0;
- for (scr = 0; scr < ScreenCount(appDisplay); scr++) {
- QWidget* rootWin = QApplication::desktop()->screen(scr);
- if (!rootWin)
- return; // Should not happen
- Atom overlayVisualsAtom = XInternAtom(appDisplay,
- "SERVER_OVERLAY_VISUALS", True);
- if (overlayVisualsAtom == XNone)
- return; // Server has no overlays
-
- Atom actualType;
- int actualFormat;
- ulong nItems;
- ulong bytesAfter;
- unsigned char *retval = 0;
- int res = XGetWindowProperty(appDisplay, rootWin->winId(),
- overlayVisualsAtom, 0, 10000, False,
- overlayVisualsAtom, &actualType,
- &actualFormat, &nItems, &bytesAfter,
- &retval);
-
- if (res != Success || actualType != overlayVisualsAtom
- || actualFormat != 32 || nItems < 4 || !retval)
- return; // Error reading property
-
- OverlayProp *overlayProps = (OverlayProp *)retval;
-
- int numProps = nItems / 4;
- trans_colors.resize(lastsize + numProps);
- int j = lastsize;
- for (int i = 0; i < numProps; i++) {
- if (overlayProps[i].type == 1) {
- trans_colors[j].vis = (VisualID)overlayProps[i].visual;
- trans_colors[j].screen = scr;
- trans_colors[j].color = (int)overlayProps[i].value;
- j++;
- }
- }
- XFree(overlayProps);
- lastsize = j;
- trans_colors.resize(lastsize);
- }
-}
-
-/*****************************************************************************
- QGLFormat UNIX/GLX-specific code
- *****************************************************************************/
-
-void (*qglx_getProcAddress(const char* procName))()
-{
- // On systems where the GL driver is pluggable (like Mesa), we have to use
- // the glXGetProcAddressARB extension to resolve other function pointers as
- // the symbols wont be in the GL library, but rather in a plugin loaded by
- // the GL library.
- typedef void (*(*qt_glXGetProcAddressARB)(const char *))();
- static qt_glXGetProcAddressARB glXGetProcAddressARB = 0;
- static bool triedResolvingGlxGetProcAddress = false;
- if (!triedResolvingGlxGetProcAddress) {
- triedResolvingGlxGetProcAddress = true;
- QGLExtensionMatcher extensions(glXGetClientString(QX11Info::display(), GLX_EXTENSIONS));
- if (extensions.match("GLX_ARB_get_proc_address")) {
-#if defined(Q_OS_LINUX) || defined(Q_OS_BSD4)
- void *handle = dlopen(NULL, RTLD_LAZY);
- if (handle) {
- glXGetProcAddressARB = (qt_glXGetProcAddressARB) dlsym(handle, "glXGetProcAddressARB");
- dlclose(handle);
- }
- if (!glXGetProcAddressARB)
-#endif
- {
-#if !defined(QT_NO_LIBRARY)
- extern const QString qt_gl_library_name();
- QLibrary lib(qt_gl_library_name());
- glXGetProcAddressARB = (qt_glXGetProcAddressARB) lib.resolve("glXGetProcAddressARB");
-#endif
- }
- }
- }
-
- void (*procAddress)() = 0;
- if (glXGetProcAddressARB)
- procAddress = glXGetProcAddressARB(procName);
-
- // If glXGetProcAddress didn't work, try looking the symbol up in the GL library
-#if defined(Q_OS_LINUX) || defined(Q_OS_BSD4)
- if (!procAddress) {
- void *handle = dlopen(NULL, RTLD_LAZY);
- if (handle) {
- procAddress = (void (*)())dlsym(handle, procName);
- dlclose(handle);
- }
- }
-#endif
-#if !defined(QT_NO_LIBRARY)
- if (!procAddress) {
- extern const QString qt_gl_library_name();
- QLibrary lib(qt_gl_library_name());
- procAddress = lib.resolve(procName);
- }
-#endif
-
- return procAddress;
-}
-
-bool QGLFormat::hasOpenGL()
-{
- return glXQueryExtension(X11->display, 0, 0) != 0;
-}
-
-
-bool QGLFormat::hasOpenGLOverlays()
-{
- if (!trans_colors_init)
- find_trans_colors();
- return trans_colors.size() > 0;
-}
-
-static bool buildSpec(int* spec, const QGLFormat& f, QPaintDevice* paintDevice,
- int bufDepth, bool onlyFBConfig = false)
-{
- int i = 0;
- spec[i++] = GLX_LEVEL;
- spec[i++] = f.plane();
- const QX11Info *xinfo = qt_x11Info(paintDevice);
- bool useFBConfig = onlyFBConfig;
-
-#if defined(GLX_VERSION_1_3) && !defined(QT_NO_XRENDER) && !defined(Q_OS_HPUX)
- /*
- HPUX defines GLX_VERSION_1_3 but does not implement the corresponding functions.
- Specifically glXChooseFBConfig and glXGetVisualFromFBConfig are not implemented.
- */
- QWidget* widget = 0;
- if (paintDevice->devType() == QInternal::Widget)
- widget = static_cast<QWidget*>(paintDevice);
-
- // Only use glXChooseFBConfig for widgets if we're trying to get an ARGB visual
- if (widget && widget->testAttribute(Qt::WA_TranslucentBackground) && X11->use_xrender)
- useFBConfig = true;
-#endif
-
-#if defined(GLX_VERSION_1_1) && defined(GLX_EXT_visual_info)
- static bool useTranspExt = false;
- static bool useTranspExtChecked = false;
- if (f.plane() && !useTranspExtChecked && paintDevice) {
- QGLExtensionMatcher extensions(glXQueryExtensionsString(xinfo->display(), xinfo->screen()));
- useTranspExt = extensions.match("GLX_EXT_visual_info");
- //# (A bit simplistic; that could theoretically be a substring)
- if (useTranspExt) {
- QByteArray cstr(glXGetClientString(xinfo->display(), GLX_VENDOR));
- useTranspExt = !cstr.contains("Xi Graphics"); // bug workaround
- if (useTranspExt) {
- // bug workaround - some systems (eg. FireGL) refuses to return an overlay
- // visual if the GLX_TRANSPARENT_TYPE_EXT attribute is specified, even if
- // the implementation supports transparent overlays
- int tmpSpec[] = { GLX_LEVEL, f.plane(), GLX_TRANSPARENT_TYPE_EXT,
- f.rgba() ? GLX_TRANSPARENT_RGB_EXT : GLX_TRANSPARENT_INDEX_EXT,
- XNone };
- XVisualInfo * vinf = glXChooseVisual(xinfo->display(), xinfo->screen(), tmpSpec);
- if (!vinf) {
- useTranspExt = false;
- }
- }
- }
-
- useTranspExtChecked = true;
- }
- if (f.plane() && useTranspExt && !useFBConfig) {
- // Required to avoid non-transparent overlay visual(!) on some systems
- spec[i++] = GLX_TRANSPARENT_TYPE_EXT;
- spec[i++] = f.rgba() ? GLX_TRANSPARENT_RGB_EXT : GLX_TRANSPARENT_INDEX_EXT;
- }
-#endif
-
-#if defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX)
- // GLX_RENDER_TYPE is only in glx >=1.3
- if (useFBConfig) {
- spec[i++] = GLX_RENDER_TYPE;
- spec[i++] = f.rgba() ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT;
- }
-#endif
-
- if (f.doubleBuffer())
- spec[i++] = GLX_DOUBLEBUFFER;
- if (useFBConfig)
- spec[i++] = True;
- if (f.depth()) {
- spec[i++] = GLX_DEPTH_SIZE;
- spec[i++] = f.depthBufferSize() == -1 ? 1 : f.depthBufferSize();
- }
- if (f.stereo()) {
- spec[i++] = GLX_STEREO;
- if (useFBConfig)
- spec[i++] = True;
- }
- if (f.stencil()) {
- spec[i++] = GLX_STENCIL_SIZE;
- spec[i++] = f.stencilBufferSize() == -1 ? 1 : f.stencilBufferSize();
- }
- if (f.rgba()) {
- if (!useFBConfig)
- spec[i++] = GLX_RGBA;
- spec[i++] = GLX_RED_SIZE;
- spec[i++] = f.redBufferSize() == -1 ? 1 : f.redBufferSize();
- spec[i++] = GLX_GREEN_SIZE;
- spec[i++] = f.greenBufferSize() == -1 ? 1 : f.greenBufferSize();
- spec[i++] = GLX_BLUE_SIZE;
- spec[i++] = f.blueBufferSize() == -1 ? 1 : f.blueBufferSize();
- if (f.alpha()) {
- spec[i++] = GLX_ALPHA_SIZE;
- spec[i++] = f.alphaBufferSize() == -1 ? 1 : f.alphaBufferSize();
- }
- if (f.accum()) {
- spec[i++] = GLX_ACCUM_RED_SIZE;
- spec[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize();
- spec[i++] = GLX_ACCUM_GREEN_SIZE;
- spec[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize();
- spec[i++] = GLX_ACCUM_BLUE_SIZE;
- spec[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize();
- if (f.alpha()) {
- spec[i++] = GLX_ACCUM_ALPHA_SIZE;
- spec[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize();
- }
- }
- } else {
- spec[i++] = GLX_BUFFER_SIZE;
- spec[i++] = bufDepth;
- }
-
- if (f.sampleBuffers()) {
- spec[i++] = GLX_SAMPLE_BUFFERS_ARB;
- spec[i++] = 1;
- spec[i++] = GLX_SAMPLES_ARB;
- spec[i++] = f.samples() == -1 ? 4 : f.samples();
- }
-
-#if defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX)
- if (useFBConfig) {
- spec[i++] = GLX_DRAWABLE_TYPE;
- switch(paintDevice->devType()) {
- case QInternal::Pixmap:
- spec[i++] = GLX_PIXMAP_BIT;
- break;
- case QInternal::Pbuffer:
- spec[i++] = GLX_PBUFFER_BIT;
- break;
- default:
- qWarning("QGLContext: Unknown paint device type %d", paintDevice->devType());
- // Fall-through & assume it's a window
- case QInternal::Widget:
- spec[i++] = GLX_WINDOW_BIT;
- break;
- };
- }
-#endif
-
- spec[i] = XNone;
- return useFBConfig;
-}
-
-/*****************************************************************************
- QGLContext UNIX/GLX-specific code
- *****************************************************************************/
-
-bool QGLContext::chooseContext(const QGLContext* shareContext)
-{
- Q_D(QGLContext);
- const QX11Info *xinfo = qt_x11Info(d->paintDevice);
-
- Display* disp = xinfo->display();
- d->vi = chooseVisual();
- if (!d->vi)
- return false;
-
- if (deviceIsPixmap() &&
- (((XVisualInfo*)d->vi)->depth != xinfo->depth() ||
- ((XVisualInfo*)d->vi)->screen != xinfo->screen()))
- {
- XFree(d->vi);
- XVisualInfo appVisInfo;
- memset(&appVisInfo, 0, sizeof(XVisualInfo));
- appVisInfo.visualid = XVisualIDFromVisual((Visual *) xinfo->visual());
- appVisInfo.screen = xinfo->screen();
- int nvis;
- d->vi = XGetVisualInfo(disp, VisualIDMask | VisualScreenMask, &appVisInfo, &nvis);
- if (!d->vi)
- return false;
-
- int useGL;
- glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_USE_GL, &useGL);
- if (!useGL)
- return false; //# Chickening out already...
- }
- int res;
- glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_LEVEL, &res);
- d->glFormat.setPlane(res);
- glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_DOUBLEBUFFER, &res);
- d->glFormat.setDoubleBuffer(res);
- glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_DEPTH_SIZE, &res);
- d->glFormat.setDepth(res);
- if (d->glFormat.depth())
- d->glFormat.setDepthBufferSize(res);
- glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_RGBA, &res);
- d->glFormat.setRgba(res);
- glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_RED_SIZE, &res);
- d->glFormat.setRedBufferSize(res);
- glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_GREEN_SIZE, &res);
- d->glFormat.setGreenBufferSize(res);
- glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_BLUE_SIZE, &res);
- d->glFormat.setBlueBufferSize(res);
- glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_ALPHA_SIZE, &res);
- d->glFormat.setAlpha(res);
- if (d->glFormat.alpha())
- d->glFormat.setAlphaBufferSize(res);
- glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_ACCUM_RED_SIZE, &res);
- d->glFormat.setAccum(res);
- if (d->glFormat.accum())
- d->glFormat.setAccumBufferSize(res);
- glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_STENCIL_SIZE, &res);
- d->glFormat.setStencil(res);
- if (d->glFormat.stencil())
- d->glFormat.setStencilBufferSize(res);
- glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_STEREO, &res);
- d->glFormat.setStereo(res);
- glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_SAMPLE_BUFFERS_ARB, &res);
- d->glFormat.setSampleBuffers(res);
- if (d->glFormat.sampleBuffers()) {
- glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_SAMPLES_ARB, &res);
- d->glFormat.setSamples(res);
- }
-
- Bool direct = format().directRendering() ? True : False;
-
- if (shareContext &&
- (!shareContext->isValid() || !shareContext->d_func()->cx)) {
- qWarning("QGLContext::chooseContext(): Cannot share with invalid context");
- shareContext = 0;
- }
-
- // 1. Sharing between rgba and color-index will give wrong colors.
- // 2. Contexts cannot be shared btw. direct/non-direct renderers.
- // 3. Pixmaps cannot share contexts that are set up for direct rendering.
- // 4. If the contexts are not created on the same screen, they can't be shared
-
- if (shareContext
- && (format().rgba() != shareContext->format().rgba()
- || (deviceIsPixmap() && glXIsDirect(disp, (GLXContext)shareContext->d_func()->cx))
- || (shareContext->d_func()->screen != xinfo->screen())))
- {
- shareContext = 0;
- }
-
- const int major = d->reqFormat.majorVersion();
- const int minor = d->reqFormat.minorVersion();
- const int profile = d->reqFormat.profile() == QGLFormat::CompatibilityProfile
- ? GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB
- : GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
-
- d->cx = 0;
-
-#if defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX)
- /*
- HPUX defines GLX_VERSION_1_3 but does not implement the corresponding functions.
- Specifically glXChooseFBConfig and glXGetVisualFromFBConfig are not implemented.
- */
- if ((major == 3 && minor >= 2) || major > 3) {
- QGLTemporaryContext *tmpContext = 0;
- if (!QGLContext::currentContext())
- tmpContext = new QGLTemporaryContext;
-
- int attributes[] = { GLX_CONTEXT_MAJOR_VERSION_ARB, major,
- GLX_CONTEXT_MINOR_VERSION_ARB, minor,
- GLX_CONTEXT_PROFILE_MASK_ARB, profile,
- 0 };
-
- typedef GLXContext ( * Q_PFNGLXCREATECONTEXTATTRIBSARBPROC)
- (Display* dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int *attrib_list);
-
-
- Q_PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribs =
- (Q_PFNGLXCREATECONTEXTATTRIBSARBPROC) qglx_getProcAddress("glXCreateContextAttribsARB");
-
- if (glXCreateContextAttribs) {
- int spec[45];
- glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_BUFFER_SIZE, &res);
- buildSpec(spec, format(), d->paintDevice, res, true);
-
- GLXFBConfig *configs;
- int configCount = 0;
- configs = glXChooseFBConfig(disp, xinfo->screen(), spec, &configCount);
-
- if (configs && configCount > 0) {
- d->cx = glXCreateContextAttribs(disp, configs[0],
- shareContext ? (GLXContext)shareContext->d_func()->cx : 0, direct, attributes);
- if (!d->cx && shareContext) {
- shareContext = 0;
- d->cx = glXCreateContextAttribs(disp, configs[0], 0, direct, attributes);
- }
- d->screen = ((XVisualInfo*)d->vi)->screen;
- }
- XFree(configs);
- } else {
- qWarning("QGLContext::chooseContext(): OpenGL %d.%d is not supported", major, minor);
- }
-
- if (tmpContext)
- delete tmpContext;
- }
-#else
- Q_UNUSED(major);
- Q_UNUSED(minor);
- Q_UNUSED(profile);
-#endif
-
- if (!d->cx && shareContext) {
- d->cx = glXCreateContext(disp, (XVisualInfo *)d->vi,
- (GLXContext)shareContext->d_func()->cx, direct);
- d->screen = ((XVisualInfo*)d->vi)->screen;
- }
- if (!d->cx) {
- d->cx = glXCreateContext(disp, (XVisualInfo *)d->vi, NULL, direct);
- d->screen = ((XVisualInfo*)d->vi)->screen;
- shareContext = 0;
- }
-
- if (shareContext && d->cx) {
- QGLContext *share = const_cast<QGLContext *>(shareContext);
- d->sharing = true;
- share->d_func()->sharing = true;
- }
-
- if (!d->cx)
- return false;
- d->glFormat.setDirectRendering(glXIsDirect(disp, (GLXContext)d->cx));
- if (deviceIsPixmap()) {
-#if defined(GLX_MESA_pixmap_colormap) && defined(QGL_USE_MESA_EXT)
- d->gpm = glXCreateGLXPixmapMESA(disp, (XVisualInfo *)d->vi,
- qt_x11Handle(d->paintDevice),
- qt_gl_choose_cmap(disp, (XVisualInfo *)d->vi));
-#else
- d->gpm = (quint32)glXCreateGLXPixmap(disp, (XVisualInfo *)d->vi,
- qt_x11Handle(d->paintDevice));
-#endif
- if (!d->gpm)
- return false;
- }
- QGLExtensionMatcher extensions(glXQueryExtensionsString(xinfo->display(), xinfo->screen()));
- if (extensions.match("GLX_SGI_video_sync")) {
- if (d->glFormat.swapInterval() == -1)
- d->glFormat.setSwapInterval(0);
- } else {
- d->glFormat.setSwapInterval(-1);
- }
- return true;
-}
-
-/*
- See qgl.cpp for qdoc comment.
- */
-void *QGLContext::chooseVisual()
-{
- Q_D(QGLContext);
- static const int bufDepths[] = { 8, 4, 2, 1 }; // Try 16, 12 also?
- //todo: if pixmap, also make sure that vi->depth == pixmap->depth
- void* vis = 0;
- int i = 0;
- bool fail = false;
- QGLFormat fmt = format();
- bool tryDouble = !fmt.doubleBuffer(); // Some GL impl's only have double
- bool triedDouble = false;
- bool triedSample = false;
- if (fmt.sampleBuffers())
- fmt.setSampleBuffers(QGLExtensions::glExtensions() & QGLExtensions::SampleBuffers);
- while(!fail && !(vis = tryVisual(fmt, bufDepths[i]))) {
- if (!fmt.rgba() && bufDepths[i] > 1) {
- i++;
- continue;
- }
- if (tryDouble) {
- fmt.setDoubleBuffer(true);
- tryDouble = false;
- triedDouble = true;
- continue;
- } else if (triedDouble) {
- fmt.setDoubleBuffer(false);
- triedDouble = false;
- }
- if (!triedSample && fmt.sampleBuffers()) {
- fmt.setSampleBuffers(false);
- triedSample = true;
- continue;
- }
- if (fmt.stereo()) {
- fmt.setStereo(false);
- continue;
- }
- if (fmt.accum()) {
- fmt.setAccum(false);
- continue;
- }
- if (fmt.stencil()) {
- fmt.setStencil(false);
- continue;
- }
- if (fmt.alpha()) {
- fmt.setAlpha(false);
- continue;
- }
- if (fmt.depth()) {
- fmt.setDepth(false);
- continue;
- }
- if (fmt.doubleBuffer()) {
- fmt.setDoubleBuffer(false);
- continue;
- }
- fail = true;
- }
- d->glFormat = fmt;
- return vis;
-}
-
-/*
- See qgl.cpp for qdoc comment.
- */
-void *QGLContext::tryVisual(const QGLFormat& f, int bufDepth)
-{
- Q_D(QGLContext);
- int spec[45];
- const QX11Info *xinfo = qt_x11Info(d->paintDevice);
- bool useFBConfig = buildSpec(spec, f, d->paintDevice, bufDepth, false);
-
- XVisualInfo* chosenVisualInfo = 0;
-
-#if defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX)
- while (useFBConfig) {
- GLXFBConfig *configs;
- int configCount = 0;
- configs = glXChooseFBConfig(xinfo->display(), xinfo->screen(), spec, &configCount);
-
- if (!configs)
- break; // fallback to trying glXChooseVisual
-
- for (int i = 0; i < configCount; ++i) {
- XVisualInfo* vi;
- vi = glXGetVisualFromFBConfig(xinfo->display(), configs[i]);
- if (!vi)
- continue;
-
-#if !defined(QT_NO_XRENDER)
- QWidget* w = 0;
- if (d->paintDevice->devType() == QInternal::Widget)
- w = static_cast<QWidget*>(d->paintDevice);
-
- if (w && w->testAttribute(Qt::WA_TranslucentBackground) && f.alpha()) {
- // Attempt to find a config who's visual has a proper alpha channel
- XRenderPictFormat *pictFormat;
- pictFormat = XRenderFindVisualFormat(xinfo->display(), vi->visual);
-
- if (pictFormat && (pictFormat->type == PictTypeDirect) && pictFormat->direct.alphaMask) {
- // The pict format for the visual matching the FBConfig indicates ARGB
- if (chosenVisualInfo)
- XFree(chosenVisualInfo);
- chosenVisualInfo = vi;
- break;
- }
- } else
-#endif //QT_NO_XRENDER
- if (chosenVisualInfo) {
- // If we've got a visual we can use and we're not trying to find one with a
- // real alpha channel, we might as well just use the one we've got
- break;
- }
-
- if (!chosenVisualInfo)
- chosenVisualInfo = vi; // Have something to fall back to
- else
- XFree(vi);
- }
-
- XFree(configs);
- break;
- }
-#endif // defined(GLX_VERSION_1_3)
-
- if (!chosenVisualInfo)
- chosenVisualInfo = glXChooseVisual(xinfo->display(), xinfo->screen(), spec);
-
- return chosenVisualInfo;
-}
-
-
-void QGLContext::reset()
-{
- Q_D(QGLContext);
- if (!d->valid)
- return;
- d->cleanup();
- const QX11Info *xinfo = qt_x11Info(d->paintDevice);
- doneCurrent();
- if (d->gpm)
- glXDestroyGLXPixmap(xinfo->display(), (GLXPixmap)d->gpm);
- d->gpm = 0;
- glXDestroyContext(xinfo->display(), (GLXContext)d->cx);
- if (d->vi)
- XFree(d->vi);
- d->vi = 0;
- d->cx = 0;
- d->crWin = false;
- d->sharing = false;
- d->valid = false;
- d->transpColor = QColor();
- d->initDone = false;
- QGLContextGroup::removeShare(this);
-}
-
-
-void QGLContext::makeCurrent()
-{
- Q_D(QGLContext);
- if (!d->valid) {
- qWarning("QGLContext::makeCurrent(): Cannot make invalid context current.");
- return;
- }
- const QX11Info *xinfo = qt_x11Info(d->paintDevice);
- bool ok = true;
- if (d->paintDevice->devType() == QInternal::Pixmap) {
- ok = glXMakeCurrent(xinfo->display(), (GLXPixmap)d->gpm, (GLXContext)d->cx);
- } else if (d->paintDevice->devType() == QInternal::Pbuffer) {
- ok = glXMakeCurrent(xinfo->display(), (GLXPbuffer)d->pbuf, (GLXContext)d->cx);
- } else if (d->paintDevice->devType() == QInternal::Widget) {
- ok = glXMakeCurrent(xinfo->display(), ((QWidget *)d->paintDevice)->internalWinId(), (GLXContext)d->cx);
- }
- if (!ok)
- qWarning("QGLContext::makeCurrent(): Failed.");
-
- if (ok)
- QGLContextPrivate::setCurrentContext(this);
-}
-
-void QGLContext::doneCurrent()
-{
- Q_D(QGLContext);
- glXMakeCurrent(qt_x11Info(d->paintDevice)->display(), 0, 0);
- QGLContextPrivate::setCurrentContext(0);
-}
-
-
-void QGLContext::swapBuffers() const
-{
- Q_D(const QGLContext);
- if (!d->valid)
- return;
- if (!deviceIsPixmap()) {
- int interval = d->glFormat.swapInterval();
- if (interval > 0) {
- typedef int (*qt_glXGetVideoSyncSGI)(uint *);
- typedef int (*qt_glXWaitVideoSyncSGI)(int, int, uint *);
- static qt_glXGetVideoSyncSGI glXGetVideoSyncSGI = 0;
- static qt_glXWaitVideoSyncSGI glXWaitVideoSyncSGI = 0;
- static bool resolved = false;
- if (!resolved) {
- const QX11Info *xinfo = qt_x11Info(d->paintDevice);
- QGLExtensionMatcher extensions(glXQueryExtensionsString(xinfo->display(), xinfo->screen()));
- if (extensions.match("GLX_SGI_video_sync")) {
- glXGetVideoSyncSGI = (qt_glXGetVideoSyncSGI)qglx_getProcAddress("glXGetVideoSyncSGI");
- glXWaitVideoSyncSGI = (qt_glXWaitVideoSyncSGI)qglx_getProcAddress("glXWaitVideoSyncSGI");
- }
- resolved = true;
- }
- if (glXGetVideoSyncSGI && glXWaitVideoSyncSGI) {
- uint counter;
- if (!glXGetVideoSyncSGI(&counter))
- glXWaitVideoSyncSGI(interval + 1, (counter + interval) % (interval + 1), &counter);
- }
- }
- glXSwapBuffers(qt_x11Info(d->paintDevice)->display(),
- static_cast<QWidget *>(d->paintDevice)->winId());
- }
-}
-
-QColor QGLContext::overlayTransparentColor() const
-{
- if (isValid())
- return Qt::transparent;
- return QColor(); // Invalid color
-}
-
-static uint qt_transparent_pixel(VisualID id, int screen)
-{
- for (int i = 0; i < trans_colors.size(); i++) {
- if (trans_colors[i].vis == id && trans_colors[i].screen == screen)
- return trans_colors[i].color;
- }
- return 0;
-}
-
-uint QGLContext::colorIndex(const QColor& c) const
-{
- Q_D(const QGLContext);
- int screen = ((XVisualInfo *)d->vi)->screen;
- QColormap colmap = QColormap::instance(screen);
- if (isValid()) {
- if (format().plane() && c == Qt::transparent) {
- return qt_transparent_pixel(((XVisualInfo *)d->vi)->visualid,
- ((XVisualInfo *)d->vi)->screen);
- }
- if (((XVisualInfo*)d->vi)->visualid ==
- XVisualIDFromVisual((Visual *) QX11Info::appVisual(screen)))
- return colmap.pixel(c); // We're using QColor's cmap
-
- XVisualInfo *info = (XVisualInfo *) d->vi;
- CMapEntryHash *hash = cmap_handler()->cmap_hash;
- CMapEntryHash::ConstIterator it = hash->constFind(long(info->visualid)
- + (info->screen * 256));
- QCMapEntry *x = 0;
- if (it != hash->constEnd())
- x = it.value();
- if (x && !x->alloc) { // It's a standard colormap
- int rf = (int)(((float)c.red() * (x->scmap.red_max+1))/256.0);
- int gf = (int)(((float)c.green() * (x->scmap.green_max+1))/256.0);
- int bf = (int)(((float)c.blue() * (x->scmap.blue_max+1))/256.0);
- uint p = x->scmap.base_pixel
- + (rf * x->scmap.red_mult)
- + (gf * x->scmap.green_mult)
- + (bf * x->scmap.blue_mult);
- return p;
- } else {
- QMap<int, QRgb> &cmap = (*cmap_handler()->qglcmap_hash)[(long)info->visualid];
-
- // already in the map?
- QRgb target = c.rgb();
- QMap<int, QRgb>::Iterator it = cmap.begin();
- for (; it != cmap.end(); ++it) {
- if ((*it) == target)
- return it.key();
- }
-
- // need to alloc color
- unsigned long plane_mask[2];
- unsigned long color_map_entry;
- if (!XAllocColorCells (QX11Info::display(), x->cmap, true, plane_mask, 0,
- &color_map_entry, 1))
- return colmap.pixel(c);
-
- XColor col;
- col.flags = DoRed | DoGreen | DoBlue;
- col.pixel = color_map_entry;
- col.red = (ushort)((qRed(c.rgb()) / 255.0) * 65535.0 + 0.5);
- col.green = (ushort)((qGreen(c.rgb()) / 255.0) * 65535.0 + 0.5);
- col.blue = (ushort)((qBlue(c.rgb()) / 255.0) * 65535.0 + 0.5);
- XStoreColor(QX11Info::display(), x->cmap, &col);
-
- cmap.insert(color_map_entry, target);
- return color_map_entry;
- }
- }
- return 0;
-}
-
-#ifndef QT_NO_FONTCONFIG
-/*! \internal
- This is basically a substitute for glxUseXFont() which can only
- handle XLFD fonts. This version relies on freetype to render the
- glyphs, but it works with all fonts that fontconfig provides - both
- antialiased and aliased bitmap and outline fonts.
-*/
-static void qgl_use_font(QFontEngineFT *engine, int first, int count, int listBase)
-{
- GLfloat color[4];
- glGetFloatv(GL_CURRENT_COLOR, color);
-
- // save the pixel unpack state
- GLint gl_swapbytes, gl_lsbfirst, gl_rowlength, gl_skiprows, gl_skippixels, gl_alignment;
- glGetIntegerv (GL_UNPACK_SWAP_BYTES, &gl_swapbytes);
- glGetIntegerv (GL_UNPACK_LSB_FIRST, &gl_lsbfirst);
- glGetIntegerv (GL_UNPACK_ROW_LENGTH, &gl_rowlength);
- glGetIntegerv (GL_UNPACK_SKIP_ROWS, &gl_skiprows);
- glGetIntegerv (GL_UNPACK_SKIP_PIXELS, &gl_skippixels);
- glGetIntegerv (GL_UNPACK_ALIGNMENT, &gl_alignment);
-
- glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
- glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
- glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
- glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-
- const bool antialiased = engine->drawAntialiased();
- FT_Face face = engine->lockFace();
-
- // start generating font glyphs
- for (int i = first; i < count; ++i) {
- int list = listBase + i;
- GLfloat x0, y0, dx, dy;
-
- FT_Error err;
-
- err = FT_Load_Glyph(face, FT_Get_Char_Index(face, i), FT_LOAD_DEFAULT);
- if (err) {
- qDebug("failed loading glyph %d from font", i);
- Q_ASSERT(!err);
- }
- err = FT_Render_Glyph(face->glyph, (antialiased ? FT_RENDER_MODE_NORMAL
- : FT_RENDER_MODE_MONO));
- if (err) {
- qDebug("failed rendering glyph %d from font", i);
- Q_ASSERT(!err);
- }
-
- FT_Bitmap bm = face->glyph->bitmap;
- x0 = face->glyph->metrics.horiBearingX >> 6;
- y0 = (face->glyph->metrics.height - face->glyph->metrics.horiBearingY) >> 6;
- dx = face->glyph->metrics.horiAdvance >> 6;
- dy = 0;
- int sz = bm.pitch * bm.rows;
- uint *aa_glyph = 0;
- uchar *ua_glyph = 0;
-
- if (antialiased)
- aa_glyph = new uint[sz];
- else
- ua_glyph = new uchar[sz];
-
- // convert to GL format
- for (int y = 0; y < bm.rows; ++y) {
- for (int x = 0; x < bm.pitch; ++x) {
- int c1 = y*bm.pitch + x;
- int c2 = (bm.rows - y - 1) > 0 ? (bm.rows-y-1)*bm.pitch + x : x;
- if (antialiased) {
- aa_glyph[c1] = (int(color[0]*255) << 24)
- | (int(color[1]*255) << 16)
- | (int(color[2]*255) << 8) | bm.buffer[c2];
- } else {
- ua_glyph[c1] = bm.buffer[c2];
- }
- }
- }
-
- glNewList(list, GL_COMPILE);
- if (antialiased) {
- // calling glBitmap() is just a trick to move the current
- // raster pos, since glGet*() won't work in display lists
- glBitmap(0, 0, 0, 0, x0, -y0, 0);
- glDrawPixels(bm.pitch, bm.rows, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, aa_glyph);
- glBitmap(0, 0, 0, 0, dx-x0, y0, 0);
- } else {
- glBitmap(bm.pitch*8, bm.rows, -x0, y0, dx, dy, ua_glyph);
- }
- glEndList();
- antialiased ? delete[] aa_glyph : delete[] ua_glyph;
- }
-
- engine->unlockFace();
-
- // restore pixel unpack settings
- glPixelStorei(GL_UNPACK_SWAP_BYTES, gl_swapbytes);
- glPixelStorei(GL_UNPACK_LSB_FIRST, gl_lsbfirst);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, gl_rowlength);
- glPixelStorei(GL_UNPACK_SKIP_ROWS, gl_skiprows);
- glPixelStorei(GL_UNPACK_SKIP_PIXELS, gl_skippixels);
- glPixelStorei(GL_UNPACK_ALIGNMENT, gl_alignment);
-}
-#endif
-
-#undef d
-void QGLContext::generateFontDisplayLists(const QFont & fnt, int listBase)
-{
- QFont f(fnt);
- QFontEngine *engine = f.d->engineForScript(QUnicodeTables::Common);
-
- if (engine->type() == QFontEngine::Multi)
- engine = static_cast<QFontEngineMulti *>(engine)->engine(0);
-#ifndef QT_NO_FONTCONFIG
- if(engine->type() == QFontEngine::Freetype) {
- qgl_use_font(static_cast<QFontEngineFT *>(engine), 0, 256, listBase);
- return;
- }
-#endif
- // glXUseXFont() only works with XLFD font structures and a few GL
- // drivers crash if 0 is passed as the font handle
- f.setStyleStrategy(QFont::OpenGLCompatible);
- if (f.handle() && engine->type() == QFontEngine::XLFD)
- glXUseXFont(static_cast<Font>(f.handle()), 0, 256, listBase);
-}
-
-void *QGLContext::getProcAddress(const QString &proc) const
-{
- typedef void *(*qt_glXGetProcAddressARB)(const GLubyte *);
- static qt_glXGetProcAddressARB glXGetProcAddressARB = 0;
- static bool resolved = false;
-
- if (resolved && !glXGetProcAddressARB)
- return 0;
- if (!glXGetProcAddressARB) {
- QGLExtensionMatcher extensions(glXGetClientString(QX11Info::display(), GLX_EXTENSIONS));
- if (extensions.match("GLX_ARB_get_proc_address")) {
-#if defined(Q_OS_LINUX) || defined(Q_OS_BSD4)
- void *handle = dlopen(NULL, RTLD_LAZY);
- if (handle) {
- glXGetProcAddressARB = (qt_glXGetProcAddressARB) dlsym(handle, "glXGetProcAddressARB");
- dlclose(handle);
- }
- if (!glXGetProcAddressARB)
-#endif
- {
-#if !defined(QT_NO_LIBRARY)
- extern const QString qt_gl_library_name();
- QLibrary lib(qt_gl_library_name());
- glXGetProcAddressARB = (qt_glXGetProcAddressARB) lib.resolve("glXGetProcAddressARB");
-#endif
- }
- }
- resolved = true;
- }
- if (!glXGetProcAddressARB)
- return 0;
- return glXGetProcAddressARB(reinterpret_cast<const GLubyte *>(proc.toLatin1().data()));
-}
-
-/*
- QGLTemporaryContext implementation
-*/
-
-class QGLTemporaryContextPrivate {
-public:
- bool initialized;
- Window drawable;
- GLXContext context;
- GLXDrawable oldDrawable;
- GLXContext oldContext;
-};
-
-QGLTemporaryContext::QGLTemporaryContext(bool, QWidget *)
- : d(new QGLTemporaryContextPrivate)
-{
- d->initialized = false;
- d->oldDrawable = 0;
- d->oldContext = 0;
- int screen = 0;
-
- int attribs[] = {GLX_RGBA, XNone};
- XVisualInfo *vi = glXChooseVisual(X11->display, screen, attribs);
- if (!vi) {
- qWarning("QGLTempContext: No GL capable X visuals available.");
- return;
- }
-
- int useGL;
- glXGetConfig(X11->display, vi, GLX_USE_GL, &useGL);
- if (!useGL) {
- XFree(vi);
- return;
- }
-
- d->oldDrawable = glXGetCurrentDrawable();
- d->oldContext = glXGetCurrentContext();
-
- XSetWindowAttributes a;
- a.colormap = qt_gl_choose_cmap(X11->display, vi);
- d->drawable = XCreateWindow(X11->display, RootWindow(X11->display, screen),
- 0, 0, 1, 1, 0,
- vi->depth, InputOutput, vi->visual,
- CWColormap, &a);
- d->context = glXCreateContext(X11->display, vi, 0, True);
- if (d->context && glXMakeCurrent(X11->display, d->drawable, d->context)) {
- d->initialized = true;
- } else {
- qWarning("QGLTempContext: Unable to create GL context.");
- XDestroyWindow(X11->display, d->drawable);
- }
- XFree(vi);
-}
-
-QGLTemporaryContext::~QGLTemporaryContext()
-{
- if (d->initialized) {
- glXMakeCurrent(X11->display, 0, 0);
- glXDestroyContext(X11->display, d->context);
- XDestroyWindow(X11->display, d->drawable);
- }
- if (d->oldDrawable && d->oldContext)
- glXMakeCurrent(X11->display, d->oldDrawable, d->oldContext);
-}
-
-/*****************************************************************************
- QGLOverlayWidget (Internal overlay class for X11)
- *****************************************************************************/
-
-class QGLOverlayWidget : public QGLWidget
-{
- Q_OBJECT
-public:
- QGLOverlayWidget(const QGLFormat& format, QGLWidget* parent, const QGLWidget* shareWidget=0);
-
-protected:
- void initializeGL();
- void paintGL();
- void resizeGL(int w, int h);
- bool x11Event(XEvent *e) { return realWidget->x11Event(e); }
-
-private:
- QGLWidget* realWidget;
-
-private:
- Q_DISABLE_COPY(QGLOverlayWidget)
-};
-
-
-QGLOverlayWidget::QGLOverlayWidget(const QGLFormat& format, QGLWidget* parent,
- const QGLWidget* shareWidget)
- : QGLWidget(format, parent, shareWidget ? shareWidget->d_func()->olw : 0)
-{
- setAttribute(Qt::WA_X11OpenGLOverlay);
- realWidget = parent;
-}
-
-
-
-void QGLOverlayWidget::initializeGL()
-{
- QColor transparentColor = context()->overlayTransparentColor();
- if (transparentColor.isValid())
- qglClearColor(transparentColor);
- else
- qWarning("QGLOverlayWidget::initializeGL(): Could not get transparent color");
- realWidget->initializeOverlayGL();
-}
-
-
-void QGLOverlayWidget::resizeGL(int w, int h)
-{
- glViewport(0, 0, w, h);
- realWidget->resizeOverlayGL(w, h);
-}
-
-
-void QGLOverlayWidget::paintGL()
-{
- realWidget->paintOverlayGL();
-}
-
-#undef Bool
-QT_BEGIN_INCLUDE_NAMESPACE
-#include "qgl_x11.moc"
-QT_END_INCLUDE_NAMESPACE
-
-/*****************************************************************************
- QGLWidget UNIX/GLX-specific code
- *****************************************************************************/
-void QGLWidgetPrivate::init(QGLContext *context, const QGLWidget *shareWidget)
-{
- Q_Q(QGLWidget);
- initContext(context, shareWidget);
- olw = 0;
-
- if (q->isValid() && context->format().hasOverlay()) {
- QString olwName = q->objectName();
- olwName += QLatin1String("-QGL_internal_overlay_widget");
- olw = new QGLOverlayWidget(QGLFormat::defaultOverlayFormat(), q, shareWidget);
- olw->setObjectName(olwName);
- if (olw->isValid()) {
- olw->setAutoBufferSwap(false);
- olw->setFocusProxy(q);
- }
- else {
- delete olw;
- olw = 0;
- glcx->d_func()->glFormat.setOverlay(false);
- }
- }
-}
-
-bool QGLWidgetPrivate::renderCxPm(QPixmap* pm)
-{
- Q_Q(QGLWidget);
- if (((XVisualInfo*)glcx->d_func()->vi)->depth != pm->depth())
- return false;
-
- GLXPixmap glPm;
-#if defined(GLX_MESA_pixmap_colormap) && defined(QGL_USE_MESA_EXT)
- glPm = glXCreateGLXPixmapMESA(X11->display,
- (XVisualInfo*)glcx->vi,
- (Pixmap)pm->handle(),
- qt_gl_choose_cmap(pm->X11->display,
- (XVisualInfo*)glcx->vi));
-#else
- glPm = (quint32)glXCreateGLXPixmap(X11->display,
- (XVisualInfo*)glcx->d_func()->vi,
- (Pixmap)pm->handle());
-#endif
-
- if (!glXMakeCurrent(X11->display, glPm, (GLXContext)glcx->d_func()->cx)) {
- glXDestroyGLXPixmap(X11->display, glPm);
- return false;
- }
-
- glDrawBuffer(GL_FRONT);
- if (!glcx->initialized())
- q->glInit();
- q->resizeGL(pm->width(), pm->height());
- q->paintGL();
- glFlush();
- q->makeCurrent();
- glXDestroyGLXPixmap(X11->display, glPm);
- q->resizeGL(q->width(), q->height());
- return true;
-}
-
-void QGLWidgetPrivate::cleanupColormaps()
-{
- if (!cmap.handle()) {
- return;
- } else {
- XFreeColormap(X11->display, (Colormap) cmap.handle());
- cmap.setHandle(0);
- }
-}
-
-void QGLWidget::setMouseTracking(bool enable)
-{
- Q_D(QGLWidget);
- if (d->olw)
- d->olw->setMouseTracking(enable);
- QWidget::setMouseTracking(enable);
-}
-
-
-void QGLWidget::resizeEvent(QResizeEvent *)
-{
- Q_D(QGLWidget);
- if (!isValid())
- return;
- makeCurrent();
- if (!d->glcx->initialized())
- glInit();
- glXWaitX();
- resizeGL(width(), height());
- if (d->olw)
- d->olw->setGeometry(rect());
-}
-
-const QGLContext* QGLWidget::overlayContext() const
-{
- Q_D(const QGLWidget);
- if (d->olw)
- return d->olw->context();
- else
- return 0;
-}
-
-
-void QGLWidget::makeOverlayCurrent()
-{
- Q_D(QGLWidget);
- if (d->olw)
- d->olw->makeCurrent();
-}
-
-
-void QGLWidget::updateOverlayGL()
-{
- Q_D(QGLWidget);
- if (d->olw)
- d->olw->updateGL();
-}
-
-/*!
- \internal
-
- Sets a new QGLContext, \a context, for this QGLWidget, using the
- shared context, \a shareContext. If \a deleteOldContext is true,
- the original context is deleted; otherwise it is overridden.
-*/
-void QGLWidget::setContext(QGLContext *context,
- const QGLContext* shareContext,
- bool deleteOldContext)
-{
- Q_D(QGLWidget);
- if (context == 0) {
- qWarning("QGLWidget::setContext: Cannot set null context");
- return;
- }
- if (!context->deviceIsPixmap() && context->device() != this) {
- qWarning("QGLWidget::setContext: Context must refer to this widget");
- return;
- }
-
- if (d->glcx)
- d->glcx->doneCurrent();
- QGLContext* oldcx = d->glcx;
- d->glcx = context;
-
- if (parentWidget()) {
- // force creation of delay-created widgets
- parentWidget()->winId();
- if (parentWidget()->x11Info().screen() != x11Info().screen())
- d_func()->xinfo = parentWidget()->d_func()->xinfo;
- }
-
- // If the application has set WA_TranslucentBackground and not explicitly set
- // the alpha buffer size to zero, modify the format so it have an alpha channel
- QGLFormat& fmt = d->glcx->d_func()->glFormat;
- if (testAttribute(Qt::WA_TranslucentBackground) && fmt.alphaBufferSize() == -1)
- fmt.setAlphaBufferSize(1);
-
- bool createFailed = false;
- if (!d->glcx->isValid()) {
- if (!d->glcx->create(shareContext ? shareContext : oldcx))
- createFailed = true;
- }
- if (createFailed) {
- if (deleteOldContext)
- delete oldcx;
- return;
- }
-
- if (d->glcx->windowCreated() || d->glcx->deviceIsPixmap()) {
- if (deleteOldContext)
- delete oldcx;
- return;
- }
-
- bool visible = isVisible();
- if (visible)
- hide();
-
- XVisualInfo *vi = (XVisualInfo*)d->glcx->d_func()->vi;
- XSetWindowAttributes a;
-
- QColormap colmap = QColormap::instance(vi->screen);
- a.colormap = qt_gl_choose_cmap(QX11Info::display(), vi); // find best colormap
- a.background_pixel = colmap.pixel(palette().color(backgroundRole()));
- a.border_pixel = colmap.pixel(Qt::black);
- Window p = RootWindow(X11->display, vi->screen);
- if (parentWidget())
- p = parentWidget()->winId();
-
- Window w = XCreateWindow(X11->display, p, x(), y(), width(), height(),
- 0, vi->depth, InputOutput, vi->visual,
- CWBackPixel|CWBorderPixel|CWColormap, &a);
- Window *cmw;
- Window *cmwret;
- int count;
- if (XGetWMColormapWindows(X11->display, window()->winId(),
- &cmwret, &count)) {
- cmw = new Window[count+1];
- memcpy((char *)cmw, (char *)cmwret, sizeof(Window)*count);
- XFree((char *)cmwret);
- int i;
- for (i=0; i<count; i++) {
- if (cmw[i] == winId()) { // replace old window
- cmw[i] = w;
- break;
- }
- }
- if (i >= count) // append new window
- cmw[count++] = w;
- } else {
- count = 1;
- cmw = new Window[count];
- cmw[0] = w;
- }
-
-#if defined(GLX_MESA_release_buffers) && defined(QGL_USE_MESA_EXT)
- if (oldcx && oldcx->windowCreated())
- glXReleaseBuffersMESA(X11->display, winId());
-#endif
- if (deleteOldContext)
- delete oldcx;
- oldcx = 0;
-
- if (testAttribute(Qt::WA_WState_Created))
- create(w);
- else
- d->createWinId(w);
- XSetWMColormapWindows(X11->display, window()->winId(), cmw, count);
- delete [] cmw;
-
- // calling QWidget::create() will always result in a new paint
- // engine being created - get rid of it and replace it with our
- // own
-
- if (visible)
- show();
- XFlush(X11->display);
- d->glcx->setWindowCreated(true);
-}
-
-const QGLColormap & QGLWidget::colormap() const
-{
- Q_D(const QGLWidget);
- return d->cmap;
-}
-
-/*\internal
- Store color values in the given colormap.
-*/
-static void qStoreColors(QWidget * tlw, Colormap cmap,
- const QGLColormap & cols)
-{
- Q_UNUSED(tlw);
- XColor c;
- QRgb color;
-
- for (int i = 0; i < cols.size(); i++) {
- color = cols.entryRgb(i);
- c.pixel = i;
- c.red = (ushort)((qRed(color) / 255.0) * 65535.0 + 0.5);
- c.green = (ushort)((qGreen(color) / 255.0) * 65535.0 + 0.5);
- c.blue = (ushort)((qBlue(color) / 255.0) * 65535.0 + 0.5);
- c.flags = DoRed | DoGreen | DoBlue;
- XStoreColor(X11->display, cmap, &c);
- }
-}
-
-/*\internal
- Check whether the given visual supports dynamic colormaps or not.
-*/
-static bool qCanAllocColors(QWidget * w)
-{
- bool validVisual = false;
- int numVisuals;
- long mask;
- XVisualInfo templ;
- XVisualInfo * visuals;
- VisualID id = XVisualIDFromVisual((Visual *) w->window()->x11Info().visual());
-
- mask = VisualScreenMask;
- templ.screen = w->x11Info().screen();
- visuals = XGetVisualInfo(X11->display, mask, &templ, &numVisuals);
-
- for (int i = 0; i < numVisuals; i++) {
- if (visuals[i].visualid == id) {
- switch (visuals[i].c_class) {
- case TrueColor:
- case StaticColor:
- case StaticGray:
- case XGrayScale:
- validVisual = false;
- break;
- case DirectColor:
- case PseudoColor:
- validVisual = true;
- break;
- }
- break;
- }
- }
- XFree(visuals);
-
- if (!validVisual)
- return false;
- return true;
-}
-
-
-void QGLWidget::setColormap(const QGLColormap & c)
-{
- Q_D(QGLWidget);
- QWidget * tlw = window(); // must return a valid widget
-
- d->cmap = c;
- if (!d->cmap.handle())
- return;
-
- if (!qCanAllocColors(this)) {
- qWarning("QGLWidget::setColormap: Cannot create a read/write "
- "colormap for this visual");
- return;
- }
-
- // If the child GL widget is not of the same visual class as the
- // toplevel widget we will get in trouble..
- Window wid = tlw->winId();
- Visual * vis = (Visual *) tlw->x11Info().visual();;
- VisualID cvId = XVisualIDFromVisual((Visual *) x11Info().visual());
- VisualID tvId = XVisualIDFromVisual((Visual *) tlw->x11Info().visual());
- if (cvId != tvId) {
- wid = winId();
- vis = (Visual *) x11Info().visual();
- }
-
- if (!d->cmap.handle()) // allocate a cmap if necessary
- d->cmap.setHandle(XCreateColormap(X11->display, wid, vis, AllocAll));
-
- qStoreColors(this, (Colormap) d->cmap.handle(), c);
- XSetWindowColormap(X11->display, wid, (Colormap) d->cmap.handle());
-
- // tell the wm that this window has a special colormap
- Window * cmw;
- Window * cmwret;
- int count;
- if (XGetWMColormapWindows(X11->display, tlw->winId(), &cmwret, &count))
- {
- cmw = new Window[count+1];
- memcpy((char *) cmw, (char *) cmwret, sizeof(Window) * count);
- XFree((char *) cmwret);
- int i;
- for (i = 0; i < count; i++) {
- if (cmw[i] == winId()) {
- break;
- }
- }
- if (i >= count) // append new window only if not in the list
- cmw[count++] = winId();
- } else {
- count = 1;
- cmw = new Window[count];
- cmw[0] = winId();
- }
- XSetWMColormapWindows(X11->display, tlw->winId(), cmw, count);
- delete [] cmw;
-}
-
-// Solaris defines glXBindTexImageEXT as part of the GL library
-#if defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX)
-typedef void (*qt_glXBindTexImageEXT)(Display*, GLXDrawable, int, const int*);
-typedef void (*qt_glXReleaseTexImageEXT)(Display*, GLXDrawable, int);
-static qt_glXBindTexImageEXT glXBindTexImageEXT = 0;
-static qt_glXReleaseTexImageEXT glXReleaseTexImageEXT = 0;
-
-static bool qt_resolveTextureFromPixmap(QPaintDevice *paintDevice)
-{
- static bool resolvedTextureFromPixmap = false;
-
- if (!resolvedTextureFromPixmap) {
- resolvedTextureFromPixmap = true;
-
- // Check to see if we have NPOT texture support
- if ( !(QGLExtensions::glExtensions() & QGLExtensions::NPOTTextures) &&
- !(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_2_0))
- {
- return false; // Can't use TFP without NPOT
- }
-
- const QX11Info *xinfo = qt_x11Info(paintDevice);
- Display *display = xinfo ? xinfo->display() : X11->display;
- int screen = xinfo ? xinfo->screen() : X11->defaultScreen;
-
- QGLExtensionMatcher serverExtensions(glXQueryExtensionsString(display, screen));
- QGLExtensionMatcher clientExtensions(glXGetClientString(display, GLX_EXTENSIONS));
- if (serverExtensions.match("GLX_EXT_texture_from_pixmap")
- && clientExtensions.match("GLX_EXT_texture_from_pixmap"))
- {
- glXBindTexImageEXT = (qt_glXBindTexImageEXT) qglx_getProcAddress("glXBindTexImageEXT");
- glXReleaseTexImageEXT = (qt_glXReleaseTexImageEXT) qglx_getProcAddress("glXReleaseTexImageEXT");
- }
- }
-
- return glXBindTexImageEXT && glXReleaseTexImageEXT;
-}
-#endif //defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX)
-
-
-QGLTexture *QGLContextPrivate::bindTextureFromNativePixmap(QPixmap *pixmap, const qint64 key,
- QGLContext::BindOptions options)
-{
-#if !defined(GLX_VERSION_1_3) || defined(Q_OS_HPUX)
- return 0;
-#else
-
- // Check we have GLX 1.3, as it is needed for glXCreatePixmap & glXDestroyPixmap
- int majorVersion = 0;
- int minorVersion = 0;
- glXQueryVersion(X11->display, &majorVersion, &minorVersion);
- if (majorVersion < 1 || (majorVersion == 1 && minorVersion < 3))
- return 0;
-
- Q_Q(QGLContext);
-
- QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(pixmap->data_ptr().data());
- Q_ASSERT(pixmapData->classId() == QPixmapData::X11Class);
-
- // We can't use TFP if the pixmap has a separate X11 mask
- if (pixmapData->x11_mask)
- return 0;
-
- if (!qt_resolveTextureFromPixmap(paintDevice))
- return 0;
-
- const QX11Info &x11Info = pixmapData->xinfo;
-
- // Store the configs (Can be static because configs aren't dependent on current context)
- static GLXFBConfig glxRGBPixmapConfig = 0;
- static bool RGBConfigInverted = false;
- static GLXFBConfig glxRGBAPixmapConfig = 0;
- static bool RGBAConfigInverted = false;
-
- bool hasAlpha = pixmapData->hasAlphaChannel();
-
- // Check to see if we need a config
- if ( (hasAlpha && !glxRGBAPixmapConfig) || (!hasAlpha && !glxRGBPixmapConfig) ) {
- GLXFBConfig *configList = 0;
- int configCount = 0;
-
- int configAttribs[] = {
- hasAlpha ? GLX_BIND_TO_TEXTURE_RGBA_EXT : GLX_BIND_TO_TEXTURE_RGB_EXT, True,
- GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT,
- GLX_BIND_TO_TEXTURE_TARGETS_EXT, GLX_TEXTURE_2D_BIT_EXT,
- // QGLContext::bindTexture() can't return an inverted texture, but QPainter::drawPixmap() can:
- GLX_Y_INVERTED_EXT, options & QGLContext::CanFlipNativePixmapBindOption ? GLX_DONT_CARE : False,
- XNone
- };
- configList = glXChooseFBConfig(x11Info.display(), x11Info.screen(), configAttribs, &configCount);
- if (!configList)
- return 0;
-
- int yInv;
- glXGetFBConfigAttrib(x11Info.display(), configList[0], GLX_Y_INVERTED_EXT, &yInv);
-
- if (hasAlpha) {
- glxRGBAPixmapConfig = configList[0];
- RGBAConfigInverted = yInv;
- }
- else {
- glxRGBPixmapConfig = configList[0];
- RGBConfigInverted = yInv;
- }
-
- XFree(configList);
- }
-
- // Check to see if the surface is still valid
- if (pixmapData->gl_surface &&
- hasAlpha != (pixmapData->flags & QX11PixmapData::GlSurfaceCreatedWithAlpha))
- {
- // Surface is invalid!
- destroyGlSurfaceForPixmap(pixmapData);
- }
-
- // Check to see if we need a surface
- if (!pixmapData->gl_surface) {
- GLXPixmap glxPixmap;
- int pixmapAttribs[] = {
- GLX_TEXTURE_FORMAT_EXT, hasAlpha ? GLX_TEXTURE_FORMAT_RGBA_EXT : GLX_TEXTURE_FORMAT_RGB_EXT,
- GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT,
- GLX_MIPMAP_TEXTURE_EXT, False, // Maybe needs to be don't care
- XNone
- };
-
- // Wrap the X Pixmap into a GLXPixmap:
- glxPixmap = glXCreatePixmap(x11Info.display(),
- hasAlpha ? glxRGBAPixmapConfig : glxRGBPixmapConfig,
- pixmapData->handle(), pixmapAttribs);
-
- if (!glxPixmap)
- return 0;
-
- pixmapData->gl_surface = (void*)glxPixmap;
-
- // Make sure the cleanup hook gets called so we can delete the glx pixmap
- QImagePixmapCleanupHooks::enableCleanupHooks(pixmapData);
- }
-
- GLuint textureId;
- glGenTextures(1, &textureId);
- glBindTexture(GL_TEXTURE_2D, textureId);
- glXBindTexImageEXT(x11Info.display(), (GLXPixmap)pixmapData->gl_surface, GLX_FRONT_LEFT_EXT, 0);
-
- glBindTexture(GL_TEXTURE_2D, textureId);
- GLuint filtering = (options & QGLContext::LinearFilteringBindOption) ? GL_LINEAR : GL_NEAREST;
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering);
-
- if (!((hasAlpha && RGBAConfigInverted) || (!hasAlpha && RGBConfigInverted)))
- options &= ~QGLContext::InvertedYBindOption;
-
- QGLTexture *texture = new QGLTexture(q, textureId, GL_TEXTURE_2D, options);
- if (texture->options & QGLContext::InvertedYBindOption)
- pixmapData->flags |= QX11PixmapData::InvertedWhenBoundToTexture;
-
- // We assume the cost of bound pixmaps is zero
- QGLTextureCache::instance()->insert(q, key, texture, 0);
-
- return texture;
-#endif //!defined(GLX_VERSION_1_3) || defined(Q_OS_HPUX)
-}
-
-
-void QGLContextPrivate::destroyGlSurfaceForPixmap(QPixmapData* pmd)
-{
-#if defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX)
- Q_ASSERT(pmd->classId() == QPixmapData::X11Class);
- QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(pmd);
- if (pixmapData->gl_surface) {
- glXDestroyPixmap(QX11Info::display(), (GLXPixmap)pixmapData->gl_surface);
- pixmapData->gl_surface = 0;
- }
-#endif
-}
-
-void QGLContextPrivate::unbindPixmapFromTexture(QPixmapData* pmd)
-{
-#if defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX)
- Q_ASSERT(pmd->classId() == QPixmapData::X11Class);
- Q_ASSERT(QGLContext::currentContext());
- QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(pmd);
- if (pixmapData->gl_surface)
- glXReleaseTexImageEXT(QX11Info::display(), (GLXPixmap)pixmapData->gl_surface, GLX_FRONT_LEFT_EXT);
-#endif
-}
-
-QT_END_NAMESPACE
diff --git a/src/opengl/qgl_x11egl.cpp b/src/opengl/qgl_x11egl.cpp
deleted file mode 100644
index 4dd7fc2f5d..0000000000
--- a/src/opengl/qgl_x11egl.cpp
+++ /dev/null
@@ -1,562 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qgl.h"
-#include <private/qt_x11_p.h>
-#include <private/qpixmap_x11_p.h>
-#include <private/qgl_p.h>
-#include <private/qpaintengine_opengl_p.h>
-#include "qgl_egl_p.h"
-#include "qcolormap.h"
-#include <QDebug>
-#include <QPixmap>
-
-
-QT_BEGIN_NAMESPACE
-
-
-/*
- QGLTemporaryContext implementation
-*/
-
-class QGLTemporaryContextPrivate
-{
-public:
- bool initialized;
- Window window;
- EGLContext context;
- EGLSurface surface;
- EGLDisplay display;
-};
-
-QGLTemporaryContext::QGLTemporaryContext(bool, QWidget *)
- : d(new QGLTemporaryContextPrivate)
-{
- d->initialized = false;
- d->window = 0;
- d->context = 0;
- d->surface = 0;
- int screen = 0;
-
- d->display = QEgl::display();
-
- EGLConfig config;
- int numConfigs = 0;
- EGLint attribs[] = {
- EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
-#ifdef QT_OPENGL_ES_2
- EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
-#endif
- EGL_NONE
- };
-
- eglChooseConfig(d->display, attribs, &config, 1, &numConfigs);
- if (!numConfigs) {
- qWarning("QGLTemporaryContext: No EGL configurations available.");
- return;
- }
-
- XVisualInfo visualInfo;
- XVisualInfo *vi;
- int numVisuals;
-
- visualInfo.visualid = QEgl::getCompatibleVisualId(config);
- vi = XGetVisualInfo(X11->display, VisualIDMask, &visualInfo, &numVisuals);
- if (!vi || numVisuals < 1) {
- qWarning("QGLTemporaryContext: Unable to get X11 visual info id.");
- return;
- }
-
- XSetWindowAttributes attr;
- unsigned long mask;
- attr.background_pixel = 0;
- attr.border_pixel = 0;
- attr.colormap = XCreateColormap(X11->display, DefaultRootWindow(X11->display), vi->visual, AllocNone);
- attr.event_mask = StructureNotifyMask | ExposureMask;
- mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
-
- d->window = XCreateWindow(X11->display, RootWindow(X11->display, screen),
- 0, 0, 1, 1, 0,
- vi->depth, InputOutput, vi->visual,
- mask, &attr);
-
- d->surface = eglCreateWindowSurface(d->display, config, (EGLNativeWindowType) d->window, NULL);
-
- if (d->surface == EGL_NO_SURFACE) {
- qWarning("QGLTemporaryContext: Error creating EGL surface.");
- XFree(vi);
- XDestroyWindow(X11->display, d->window);
- return;
- }
-
- EGLint contextAttribs[] = {
-#ifdef QT_OPENGL_ES_2
- EGL_CONTEXT_CLIENT_VERSION, 2,
-#endif
- EGL_NONE
- };
- d->context = eglCreateContext(d->display, config, 0, contextAttribs);
- if (d->context != EGL_NO_CONTEXT
- && eglMakeCurrent(d->display, d->surface, d->surface, d->context))
- {
- d->initialized = true;
- } else {
- qWarning("QGLTemporaryContext: Error creating EGL context.");
- eglDestroySurface(d->display, d->surface);
- XDestroyWindow(X11->display, d->window);
- }
- XFree(vi);
-}
-
-QGLTemporaryContext::~QGLTemporaryContext()
-{
- if (d->initialized) {
- eglMakeCurrent(d->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
- eglDestroyContext(d->display, d->context);
- eglDestroySurface(d->display, d->surface);
- XDestroyWindow(X11->display, d->window);
- }
-}
-
-bool QGLFormat::hasOpenGLOverlays()
-{
- return false;
-}
-
-// Chooses the EGL config and creates the EGL context
-bool QGLContext::chooseContext(const QGLContext* shareContext)
-{
- Q_D(QGLContext);
-
- if (!device())
- return false;
-
- int devType = device()->devType();
-
- QX11PixmapData *x11PixmapData = 0;
- if (devType == QInternal::Pixmap) {
- QPixmapData *pmd = static_cast<QPixmap*>(device())->data_ptr().data();
- if (pmd->classId() == QPixmapData::X11Class)
- x11PixmapData = static_cast<QX11PixmapData*>(pmd);
- else {
- // TODO: Replace the pixmap's data with a new QX11PixmapData
- qWarning("WARNING: Creating a QGLContext on a QPixmap is only supported for X11 pixmap backend");
- return false;
- }
- } else if ((devType != QInternal::Widget) && (devType != QInternal::Pbuffer)) {
- qWarning("WARNING: Creating a QGLContext not supported on device type %d", devType);
- return false;
- }
-
- // Only create the eglContext if we don't already have one:
- if (d->eglContext == 0) {
- d->eglContext = new QEglContext();
- d->ownsEglContext = true;
- d->eglContext->setApi(QEgl::OpenGL);
-
- // If the device is a widget with WA_TranslucentBackground set, make sure the glFormat
- // has the alpha channel option set:
- if (devType == QInternal::Widget) {
- QWidget* widget = static_cast<QWidget*>(device());
- if (widget->testAttribute(Qt::WA_TranslucentBackground))
- d->glFormat.setAlpha(true);
- }
-
- // Construct the configuration we need for this surface.
- QEglProperties configProps;
- configProps.setDeviceType(devType);
- configProps.setRenderableType(QEgl::OpenGL);
- qt_eglproperties_set_glformat(configProps, d->glFormat);
-
- // Set buffer preserved for regular QWidgets, QGLWidgets are ok with either preserved or destroyed:
- if ((devType == QInternal::Widget) && qobject_cast<QGLWidget*>(static_cast<QWidget*>(device())) == 0)
- configProps.setValue(EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED);
-
- if (!d->eglContext->chooseConfig(configProps, QEgl::BestPixelFormat)) {
- delete d->eglContext;
- d->eglContext = 0;
- return false;
- }
-
- // Create a new context for the configuration.
- QEglContext* eglSharedContext = shareContext ? shareContext->d_func()->eglContext : 0;
- if (!d->eglContext->createContext(eglSharedContext)) {
- delete d->eglContext;
- d->eglContext = 0;
- return false;
- }
- d->sharing = d->eglContext->isSharing();
- if (d->sharing && shareContext)
- const_cast<QGLContext *>(shareContext)->d_func()->sharing = true;
- }
-
- // Inform the higher layers about the actual format properties
- qt_glformat_from_eglconfig(d->glFormat, d->eglContext->config());
-
- // Do don't create the EGLSurface for everything.
- // QWidget - yes, create the EGLSurface and store it in QGLContextPrivate::eglSurface
- // QGLWidget - yes, create the EGLSurface and store it in QGLContextPrivate::eglSurface
- // QPixmap - yes, create the EGLSurface but store it in QX11PixmapData::gl_surface
- // QGLPixelBuffer - no, it creates the surface itself and stores it in QGLPixelBufferPrivate::pbuf
-
- if (devType == QInternal::Widget) {
- if (d->eglSurface != EGL_NO_SURFACE)
- eglDestroySurface(d->eglContext->display(), d->eglSurface);
- // extraWindowSurfaceCreationProps default to NULL unless were specifically set before
- d->eglSurface = QEgl::createSurface(device(), d->eglContext->config(), d->extraWindowSurfaceCreationProps);
- XFlush(X11->display);
- setWindowCreated(true);
- }
-
- if (x11PixmapData) {
- // TODO: Actually check to see if the existing surface can be re-used
- if (x11PixmapData->gl_surface)
- eglDestroySurface(d->eglContext->display(), (EGLSurface)x11PixmapData->gl_surface);
-
- x11PixmapData->gl_surface = (void*)QEgl::createSurface(device(), d->eglContext->config());
- }
-
- return true;
-}
-
-void *QGLContext::chooseVisual()
-{
- qFatal("QGLContext::chooseVisual - this method must not be called as Qt is built with EGL support");
- return 0;
-}
-
-void *QGLContext::tryVisual(const QGLFormat& f, int bufDepth)
-{
- Q_UNUSED(f);
- Q_UNUSED(bufDepth);
- qFatal("QGLContext::tryVisual - this method must not be called as Qt is built with EGL support");
- return 0;
-}
-
-void QGLWidget::resizeEvent(QResizeEvent *)
-{
- Q_D(QGLWidget);
- if (!isValid())
- return;
- makeCurrent();
- if (!d->glcx->initialized())
- glInit();
- resizeGL(width(), height());
- //handle overlay
-}
-
-const QGLContext* QGLWidget::overlayContext() const
-{
- return 0;
-}
-
-void QGLWidget::makeOverlayCurrent()
-{
- //handle overlay
-}
-
-void QGLWidget::updateOverlayGL()
-{
- //handle overlay
-}
-
-void QGLWidget::setContext(QGLContext *context, const QGLContext* shareContext, bool deleteOldContext)
-{
- Q_D(QGLWidget);
- if (context == 0) {
- qWarning("QGLWidget::setContext: Cannot set null context");
- return;
- }
- if (!context->deviceIsPixmap() && context->device() != this) {
- qWarning("QGLWidget::setContext: Context must refer to this widget");
- return;
- }
-
- if (d->glcx)
- d->glcx->doneCurrent();
- QGLContext* oldcx = d->glcx;
- d->glcx = context;
-
- bool createFailed = false;
- if (!d->glcx->isValid()) {
- // Create the QGLContext here, which in turn chooses the EGL config
- // and creates the EGL context:
- if (!d->glcx->create(shareContext ? shareContext : oldcx))
- createFailed = true;
- }
- if (createFailed) {
- if (deleteOldContext)
- delete oldcx;
- return;
- }
-
-
- d->eglSurfaceWindowId = winId(); // Remember the window id we created the surface for
-}
-
-void QGLWidgetPrivate::init(QGLContext *context, const QGLWidget* shareWidget)
-{
- Q_Q(QGLWidget);
-
- initContext(context, shareWidget);
-
- if (q->isValid() && glcx->format().hasOverlay()) {
- //no overlay
- qWarning("QtOpenGL ES doesn't currently support overlays");
- }
-}
-
-void QGLWidgetPrivate::cleanupColormaps()
-{
-}
-
-const QGLColormap & QGLWidget::colormap() const
-{
- return d_func()->cmap;
-}
-
-void QGLWidget::setColormap(const QGLColormap &)
-{
-}
-
-// Re-creates the EGL surface if the window ID has changed or if there isn't a surface
-void QGLWidgetPrivate::recreateEglSurface()
-{
- Q_Q(QGLWidget);
-
- Window currentId = q->winId();
-
- // If the window ID has changed since the surface was created, we need to delete the
- // old surface before re-creating a new one. Note: This should not be the case as the
- // surface should be deleted before the old window id.
- if (glcx->d_func()->eglSurface != EGL_NO_SURFACE && (currentId != eglSurfaceWindowId)) {
- qWarning("EGL surface for deleted window %lx was not destroyed", uint(eglSurfaceWindowId));
- glcx->d_func()->destroyEglSurfaceForDevice();
- }
-
- if (glcx->d_func()->eglSurface == EGL_NO_SURFACE) {
- glcx->d_func()->eglSurface = glcx->d_func()->eglContext->createSurface(q);
- eglSurfaceWindowId = currentId;
- }
-}
-
-
-QGLTexture *QGLContextPrivate::bindTextureFromNativePixmap(QPixmap *pixmap, const qint64 key,
- QGLContext::BindOptions options)
-{
- Q_Q(QGLContext);
-
- // The EGL texture_from_pixmap has no facility to invert the y coordinate
- if (!(options & QGLContext::CanFlipNativePixmapBindOption))
- return 0;
-
-
- static bool checkedForTFP = false;
- static bool haveTFP = false;
- static bool checkedForEglImageTFP = false;
- static bool haveEglImageTFP = false;
-
-
- if (!checkedForEglImageTFP) {
- checkedForEglImageTFP = true;
-
- // We need to be able to create an EGLImage from a native pixmap, which was split
- // into a separate EGL extension, EGL_KHR_image_pixmap. It is possible to have
- // eglCreateImageKHR & eglDestroyImageKHR without support for pixmaps, so we must
- // check we have the EGLImage from pixmap functionality.
- if (QEgl::hasExtension("EGL_KHR_image") || QEgl::hasExtension("EGL_KHR_image_pixmap")) {
-
- // Being able to create an EGLImage from a native pixmap is also pretty useless
- // without the ability to bind that EGLImage as a texture, which is provided by
- // the GL_OES_EGL_image extension, which we try to resolve here:
- haveEglImageTFP = qt_resolve_eglimage_gl_extensions(q);
-
- if (haveEglImageTFP)
- qDebug("Found EGL_KHR_image_pixmap & GL_OES_EGL_image extensions (preferred method)!");
- }
- }
-
- if (!checkedForTFP) {
- // Check for texture_from_pixmap egl extension
- checkedForTFP = true;
- if (QEgl::hasExtension("EGL_NOKIA_texture_from_pixmap") ||
- QEgl::hasExtension("EGL_EXT_texture_from_pixmap"))
- {
- qDebug("Found texture_from_pixmap EGL extension!");
- haveTFP = true;
- }
- }
-
- if (!haveTFP && !haveEglImageTFP)
- return 0;
-
-
- QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(pixmap->data_ptr().data());
- Q_ASSERT(pixmapData->classId() == QPixmapData::X11Class);
- bool hasAlpha = pixmapData->hasAlphaChannel();
- bool pixmapHasValidSurface = false;
- bool textureIsBound = false;
- GLuint textureId;
- glGenTextures(1, &textureId);
- glBindTexture(GL_TEXTURE_2D, textureId);
-
- if (haveTFP && pixmapData->gl_surface &&
- hasAlpha == (pixmapData->flags & QX11PixmapData::GlSurfaceCreatedWithAlpha))
- {
- pixmapHasValidSurface = true;
- }
-
- // If we already have a valid EGL surface for the pixmap, we should use it
- if (pixmapHasValidSurface) {
- EGLBoolean success;
- success = eglBindTexImage(QEgl::display(), (EGLSurface)pixmapData->gl_surface, EGL_BACK_BUFFER);
- if (success == EGL_FALSE) {
- qWarning() << "eglBindTexImage() failed:" << QEgl::errorString();
- eglDestroySurface(QEgl::display(), (EGLSurface)pixmapData->gl_surface);
- pixmapData->gl_surface = (void*)EGL_NO_SURFACE;
- } else
- textureIsBound = true;
- }
-
- // If the pixmap doesn't already have a valid surface, try binding it via EGLImage
- // first, as going through EGLImage should be faster and better supported:
- if (!textureIsBound && haveEglImageTFP) {
- EGLImageKHR eglImage;
-
- EGLint attribs[] = {
- EGL_IMAGE_PRESERVED_KHR, EGL_TRUE,
- EGL_NONE
- };
- eglImage = QEgl::eglCreateImageKHR(QEgl::display(), EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR,
- (EGLClientBuffer)QEgl::nativePixmap(pixmap), attribs);
-
- QGLContext* ctx = q;
- glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, eglImage);
-
- GLint err = glGetError();
- if (err == GL_NO_ERROR)
- textureIsBound = true;
-
- // Once the egl image is bound, the texture becomes a new sibling image and we can safely
- // destroy the EGLImage we created for the pixmap:
- if (eglImage != EGL_NO_IMAGE_KHR)
- QEgl::eglDestroyImageKHR(QEgl::display(), eglImage);
- }
-
- if (!textureIsBound && haveTFP) {
- // Check to see if the surface is still valid
- if (pixmapData->gl_surface &&
- hasAlpha != (pixmapData->flags & QX11PixmapData::GlSurfaceCreatedWithAlpha))
- {
- // Surface is invalid!
- destroyGlSurfaceForPixmap(pixmapData);
- }
-
- if (pixmapData->gl_surface == 0) {
- EGLConfig config = QEgl::defaultConfig(QInternal::Pixmap,
- QEgl::OpenGL,
- hasAlpha ? QEgl::Translucent : QEgl::NoOptions);
-
- pixmapData->gl_surface = (void*)QEgl::createSurface(pixmap, config);
- if (pixmapData->gl_surface == (void*)EGL_NO_SURFACE)
- return false;
- }
-
- EGLBoolean success;
- success = eglBindTexImage(QEgl::display(), (EGLSurface)pixmapData->gl_surface, EGL_BACK_BUFFER);
- if (success == EGL_FALSE) {
- qWarning() << "eglBindTexImage() failed:" << QEgl::errorString();
- eglDestroySurface(QEgl::display(), (EGLSurface)pixmapData->gl_surface);
- pixmapData->gl_surface = (void*)EGL_NO_SURFACE;
- haveTFP = false; // If TFP isn't working, disable it's use
- } else
- textureIsBound = true;
- }
-
- QGLTexture *texture = 0;
-
- if (textureIsBound) {
- texture = new QGLTexture(q, textureId, GL_TEXTURE_2D, options);
- pixmapData->flags |= QX11PixmapData::InvertedWhenBoundToTexture;
-
- // We assume the cost of bound pixmaps is zero
- QGLTextureCache::instance()->insert(q, key, texture, 0);
-
- glBindTexture(GL_TEXTURE_2D, textureId);
- } else
- glDeleteTextures(1, &textureId);
-
- return texture;
-}
-
-
-void QGLContextPrivate::destroyGlSurfaceForPixmap(QPixmapData* pmd)
-{
- Q_ASSERT(pmd->classId() == QPixmapData::X11Class);
- QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(pmd);
- if (pixmapData->gl_surface) {
- EGLBoolean success;
- success = eglDestroySurface(QEgl::display(), (EGLSurface)pixmapData->gl_surface);
- if (success == EGL_FALSE) {
- qWarning() << "destroyGlSurfaceForPixmap() - Error deleting surface: "
- << QEgl::errorString();
- }
- pixmapData->gl_surface = 0;
- }
-}
-
-void QGLContextPrivate::unbindPixmapFromTexture(QPixmapData* pmd)
-{
- Q_ASSERT(pmd->classId() == QPixmapData::X11Class);
- QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(pmd);
- if (pixmapData->gl_surface) {
- EGLBoolean success;
- success = eglReleaseTexImage(QEgl::display(),
- (EGLSurface)pixmapData->gl_surface,
- EGL_BACK_BUFFER);
- if (success == EGL_FALSE) {
- qWarning() << "unbindPixmapFromTexture() - Unable to release bound texture: "
- << QEgl::errorString();
- }
- }
-}
-
-QT_END_NAMESPACE
diff --git a/src/opengl/qglbuffer.cpp b/src/opengl/qglbuffer.cpp
index a1ec3ef8e0..c1128a0ebd 100644
--- a/src/opengl/qglbuffer.cpp
+++ b/src/opengl/qglbuffer.cpp
@@ -141,7 +141,7 @@ public:
QAtomicInt ref;
QGLBuffer::Type type;
- QGLSharedResourceGuard guard;
+ QGLSharedResourceGuardBase *guard;
QGLBuffer::UsagePattern usagePattern;
QGLBuffer::UsagePattern actualUsagePattern;
};
@@ -184,7 +184,7 @@ QGLBuffer::QGLBuffer(const QGLBuffer &other)
d_ptr->ref.ref();
}
-#define ctx d->guard.context()
+#define ctx QGLContext::currentContext();
/*!
Destroys this buffer object, including the storage being
@@ -245,21 +245,19 @@ QGLBuffer::UsagePattern QGLBuffer::usagePattern() const
void QGLBuffer::setUsagePattern(QGLBuffer::UsagePattern value)
{
Q_D(QGLBuffer);
-#if defined(QT_OPENGL_ES_1)
- // OpenGL/ES 1.1 does not support GL_STREAM_DRAW, so use GL_STATIC_DRAW.
- // OpenGL/ES 2.0 does support GL_STREAM_DRAW.
- d->usagePattern = value;
- if (value == StreamDraw)
- d->actualUsagePattern = StaticDraw;
- else
- d->actualUsagePattern = value;
-#else
d->usagePattern = d->actualUsagePattern = value;
-#endif
}
#undef ctx
+namespace {
+ void freeBufferFunc(QGLContext *ctx, GLuint id)
+ {
+ Q_UNUSED(ctx);
+ glDeleteBuffers(1, &id);
+ }
+}
+
/*!
Creates the buffer object in the GL server. Returns true if
the object was created; false otherwise.
@@ -276,24 +274,26 @@ void QGLBuffer::setUsagePattern(QGLBuffer::UsagePattern value)
bool QGLBuffer::create()
{
Q_D(QGLBuffer);
- if (d->guard.id())
+ if (d->guard && d->guard->id())
return true;
- const QGLContext *ctx = QGLContext::currentContext();
+ QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext());
if (ctx) {
- if (!qt_resolve_buffer_extensions(const_cast<QGLContext *>(ctx)))
+ if (!qt_resolve_buffer_extensions(ctx))
return false;
GLuint bufferId = 0;
glGenBuffers(1, &bufferId);
if (bufferId) {
- d->guard.setContext(ctx);
- d->guard.setId(bufferId);
+ if (d->guard)
+ d->guard->free();
+
+ d->guard = createSharedResourceGuard(ctx, bufferId, freeBufferFunc);
return true;
}
}
return false;
}
-#define ctx d->guard.context()
+#define ctx QGLContext::currentContext()
/*!
Returns true if this buffer has been created; false otherwise.
@@ -303,7 +303,7 @@ bool QGLBuffer::create()
bool QGLBuffer::isCreated() const
{
Q_D(const QGLBuffer);
- return d->guard.id() != 0;
+ return d->guard && d->guard->id();
}
/*!
@@ -314,14 +314,10 @@ bool QGLBuffer::isCreated() const
void QGLBuffer::destroy()
{
Q_D(QGLBuffer);
- GLuint bufferId = d->guard.id();
- if (bufferId) {
- // Switch to the original creating context to destroy it.
- QGLShareContextScope scope(d->guard.context());
- glDeleteBuffers(1, &bufferId);
+ if (d->guard) {
+ d->guard->free();
+ d->guard = 0;
}
- d->guard.setId(0);
- d->guard.setContext(0);
}
/*!
@@ -338,7 +334,7 @@ bool QGLBuffer::read(int offset, void *data, int count)
{
#if !defined(QT_OPENGL_ES)
Q_D(QGLBuffer);
- if (!glGetBufferSubData || !d->guard.id())
+ if (!glGetBufferSubData || !d->guard->id())
return false;
while (glGetError() != GL_NO_ERROR) ; // Clear error state.
glGetBufferSubData(d->type, offset, count, data);
@@ -368,7 +364,7 @@ void QGLBuffer::write(int offset, const void *data, int count)
qWarning("QGLBuffer::allocate(): buffer not created");
#endif
Q_D(QGLBuffer);
- if (d->guard.id())
+ if (d->guard && d->guard->id())
glBufferSubData(d->type, offset, count, data);
}
@@ -388,7 +384,7 @@ void QGLBuffer::allocate(const void *data, int count)
qWarning("QGLBuffer::allocate(): buffer not created");
#endif
Q_D(QGLBuffer);
- if (d->guard.id())
+ if (d->guard && d->guard->id())
glBufferData(d->type, count, data, d->actualUsagePattern);
}
@@ -423,10 +419,9 @@ bool QGLBuffer::bind()
qWarning("QGLBuffer::bind(): buffer not created");
#endif
Q_D(const QGLBuffer);
- GLuint bufferId = d->guard.id();
+ GLuint bufferId = d->guard ? d->guard->id() : 0;
if (bufferId) {
- if (!QGLContext::areSharing(QGLContext::currentContext(),
- d->guard.context())) {
+ if (d->guard->group() != QOpenGLContextGroup::currentContextGroup()) {
#ifndef QT_NO_DEBUG
qWarning("QGLBuffer::bind: buffer is not valid in the current context");
#endif
@@ -455,7 +450,7 @@ void QGLBuffer::release()
qWarning("QGLBuffer::release(): buffer not created");
#endif
Q_D(const QGLBuffer);
- if (d->guard.id())
+ if (d->guard && d->guard->id())
glBindBuffer(d->type, 0);
}
@@ -481,7 +476,7 @@ void QGLBuffer::release(QGLBuffer::Type type)
glBindBuffer(GLenum(type), 0);
}
-#define ctx d->guard.context()
+#define ctx QGLContext::currentContext()
/*!
Returns the GL identifier associated with this buffer; zero if
@@ -492,7 +487,7 @@ void QGLBuffer::release(QGLBuffer::Type type)
GLuint QGLBuffer::bufferId() const
{
Q_D(const QGLBuffer);
- return d->guard.id();
+ return d->guard ? d->guard->id() : 0;
}
#ifndef GL_BUFFER_SIZE
@@ -511,7 +506,7 @@ GLuint QGLBuffer::bufferId() const
int QGLBuffer::size() const
{
Q_D(const QGLBuffer);
- if (!d->guard.id())
+ if (!d->guard || !d->guard->id())
return -1;
GLint value = -1;
glGetBufferParameteriv(d->type, GL_BUFFER_SIZE, &value);
@@ -539,7 +534,7 @@ void *QGLBuffer::map(QGLBuffer::Access access)
if (!isCreated())
qWarning("QGLBuffer::map(): buffer not created");
#endif
- if (!d->guard.id())
+ if (!d->guard || !d->guard->id())
return 0;
if (!glMapBufferARB)
return 0;
@@ -566,7 +561,7 @@ bool QGLBuffer::unmap()
if (!isCreated())
qWarning("QGLBuffer::unmap(): buffer not created");
#endif
- if (!d->guard.id())
+ if (!d->guard || !d->guard->id())
return false;
if (!glUnmapBufferARB)
return false;
diff --git a/src/opengl/qglextensions.cpp b/src/opengl/qglextensions.cpp
index 98d2960e1b..0734f713c6 100644
--- a/src/opengl/qglextensions.cpp
+++ b/src/opengl/qglextensions.cpp
@@ -222,17 +222,6 @@ bool qt_resolve_buffer_extensions(QGLContext *ctx)
#endif
}
-#ifndef QT_NO_EGL
-bool qt_resolve_eglimage_gl_extensions(QGLContext *ctx)
-{
- if (glEGLImageTargetTexture2DOES || glEGLImageTargetRenderbufferStorageOES)
- return true;
- glEGLImageTargetTexture2DOES = (_glEGLImageTargetTexture2DOES) ctx->getProcAddress(QLatin1String("glEGLImageTargetTexture2DOES"));
- glEGLImageTargetRenderbufferStorageOES = (_glEGLImageTargetRenderbufferStorageOES) ctx->getProcAddress(QLatin1String("glEGLImageTargetRenderbufferStorageOES"));
- return glEGLImageTargetTexture2DOES && glEGLImageTargetRenderbufferStorageOES;
-}
-#endif
-
bool qt_resolve_glsl_extensions(QGLContext *ctx)
{
diff --git a/src/opengl/qglextensions_p.h b/src/opengl/qglextensions_p.h
index 98433c366d..991fbba8c7 100644
--- a/src/opengl/qglextensions_p.h
+++ b/src/opengl/qglextensions_p.h
@@ -68,11 +68,6 @@
# define APIENTRYP *
#endif
-#ifndef QT_NO_EGL
-// Needed for EGLImageKHR definition:
-#include <QtGui/private/qegl_p.h>
-#endif
-
#include <QtCore/qglobal.h>
#ifndef GL_ARB_vertex_buffer_object
@@ -214,15 +209,6 @@ typedef void (APIENTRY *_glFramebufferTextureFaceEXT)(GLenum target, GLenum atta
// ARB_texture_compression
typedef void (APIENTRY *_glCompressedTexImage2DARB) (GLenum, GLint, GLenum, GLsizei,
GLsizei, GLint, GLsizei, const GLvoid *);
-
-#ifndef QT_NO_EGL
-// OES_EGL_image
-// Note: We define these to take EGLImage whereas spec says they take a new GLeglImageOES
-// type, which the EGL image should be cast to.
-typedef void (APIENTRY *_glEGLImageTargetTexture2DOES) (GLenum, EGLImageKHR);
-typedef void (APIENTRY *_glEGLImageTargetRenderbufferStorageOES) (GLenum, EGLImageKHR);
-#endif
-
QT_BEGIN_NAMESPACE
struct QGLExtensionFuncs
@@ -340,12 +326,6 @@ struct QGLExtensionFuncs
// Texture compression
qt_glCompressedTexImage2DARB = 0;
#endif
-
-#ifndef QT_NO_EGL
- // OES_EGL_image
- qt_glEGLImageTargetTexture2DOES = 0;
- qt_glEGLImageTargetRenderbufferStorageOES = 0;
-#endif
}
@@ -466,12 +446,6 @@ struct QGLExtensionFuncs
// Texture compression
_glCompressedTexImage2DARB qt_glCompressedTexImage2DARB;
#endif
-
-#ifndef QT_NO_EGL
- // OES_EGL_image
- _glEGLImageTargetTexture2DOES qt_glEGLImageTargetTexture2DOES;
- _glEGLImageTargetRenderbufferStorageOES qt_glEGLImageTargetRenderbufferStorageOES;
-#endif
};
@@ -880,26 +854,16 @@ struct QGLExtensionFuncs
#define glCompressedTexImage2D QGLContextPrivate::extensionFuncs(ctx).qt_glCompressedTexImage2DARB
#endif
-#ifndef QT_NO_EGL
-// OES_EGL_image
-#define glEGLImageTargetTexture2DOES QGLContextPrivate::extensionFuncs(ctx).qt_glEGLImageTargetTexture2DOES
-#define glEGLImageTargetRenderbufferStorageOES QGLContextPrivate::extensionFuncs(ctx).qt_glEGLImageTargetRenderbufferStorageOES
-#endif
-
extern bool qt_resolve_framebufferobject_extensions(QGLContext *ctx);
-bool Q_OPENGL_EXPORT qt_resolve_buffer_extensions(QGLContext *ctx);
+bool qt_resolve_buffer_extensions(QGLContext *ctx);
bool qt_resolve_version_1_3_functions(QGLContext *ctx);
-bool Q_OPENGL_EXPORT qt_resolve_version_2_0_functions(QGLContext *ctx);
+bool qt_resolve_version_2_0_functions(QGLContext *ctx);
bool qt_resolve_stencil_face_extension(QGLContext *ctx);
bool qt_resolve_frag_program_extensions(QGLContext *ctx);
bool qt_resolve_glsl_extensions(QGLContext *ctx);
-#ifndef QT_NO_EGL
-Q_OPENGL_EXPORT bool qt_resolve_eglimage_gl_extensions(QGLContext *ctx);
-#endif
-
QT_END_NAMESPACE
#endif // QGL_EXTENSIONS_P_H
diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp
index 682c26255d..5e140ab9da 100644
--- a/src/opengl/qglframebufferobject.cpp
+++ b/src/opengl/qglframebufferobject.cpp
@@ -45,24 +45,17 @@
#include <qdebug.h>
#include <private/qgl_p.h>
#include <private/qfont_p.h>
-#if !defined(QT_OPENGL_ES_1)
-#include <private/qpaintengineex_opengl2_p.h>
-#endif
-
-#ifndef QT_OPENGL_ES_2
-#include <private/qpaintengine_opengl_p.h>
-#endif
+#include "gl2paintengineex/qpaintengineex_opengl2_p.h"
-#include <qglframebufferobject.h>
#include <qlibrary.h>
#include <qimage.h>
QT_BEGIN_NAMESPACE
-extern Q_OPENGL_EXPORT QImage qt_gl_read_framebuffer(const QSize&, bool, bool);
+extern QImage qt_gl_read_framebuffer(const QSize&, bool, bool);
-#define QGL_FUNC_CONTEXT const QGLContext *ctx = d_ptr->fbo_guard.context();
-#define QGL_FUNCP_CONTEXT const QGLContext *ctx = fbo_guard.context();
+#define QGL_FUNC_CONTEXT const QGLContext *ctx = QGLContext::currentContext();
+#define QGL_FUNCP_CONTEXT const QGLContext *ctx = QGLContext::currentContext();
#ifndef QT_NO_DEBUG
#define QT_RESET_GLERROR() \
@@ -306,22 +299,6 @@ GLenum QGLFramebufferObjectFormat::internalTextureFormat() const
return d->internal_format;
}
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
-/*! \internal */
-void QGLFramebufferObjectFormat::setTextureTarget(QMacCompatGLenum target)
-{
- detach();
- d->target = target;
-}
-
-/*! \internal */
-void QGLFramebufferObjectFormat::setInternalTextureFormat(QMacCompatGLenum internalTextureFormat)
-{
- detach();
- d->internal_format = internalTextureFormat;
-}
-#endif
-
/*!
Returns true if all the options of this framebuffer object format
are the same as \a other; otherwise returns false.
@@ -373,13 +350,7 @@ void QGLFBOGLPaintDevice::setFBO(QGLFramebufferObject* f,
QGLContext *QGLFBOGLPaintDevice::context() const
{
- QGLContext *fboContext = const_cast<QGLContext *>(fbo->d_ptr->fbo_guard.context());
- QGLContext *currentContext = const_cast<QGLContext *>(QGLContext::currentContext());
-
- if (QGLContextPrivate::contextGroup(fboContext) == QGLContextPrivate::contextGroup(currentContext))
- return currentContext;
- else
- return fboContext;
+ return const_cast<QGLContext *>(QGLContext::currentContext());
}
bool QGLFramebufferObjectPrivate::checkFramebufferStatus() const
@@ -429,13 +400,33 @@ bool QGLFramebufferObjectPrivate::checkFramebufferStatus() const
return false;
}
+namespace
+{
+ void freeFramebufferFunc(QGLContext *ctx, GLuint id)
+ {
+ Q_UNUSED(ctx);
+ glDeleteFramebuffers(1, &id);
+ }
+
+ void freeRenderbufferFunc(QGLContext *ctx, GLuint id)
+ {
+ Q_UNUSED(ctx);
+ glDeleteRenderbuffers(1, &id);
+ }
+
+ void freeTextureFunc(QGLContext *ctx, GLuint id)
+ {
+ Q_UNUSED(ctx);
+ glDeleteTextures(1, &id);
+ }
+}
+
void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz,
QGLFramebufferObject::Attachment attachment,
GLenum texture_target, GLenum internal_format,
GLint samples, bool mipmap)
{
QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext());
- fbo_guard.setContext(ctx);
bool ext_detected = (QGLExtensions::glExtensions() & QGLExtensions::FramebufferObject);
if (!ext_detected || (ext_detected && !qt_resolve_framebufferobject_extensions(ctx)))
@@ -449,9 +440,11 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz,
GLuint fbo = 0;
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER_EXT, fbo);
- fbo_guard.setId(fbo);
- glDevice.setFBO(q, attachment);
+ GLuint texture = 0;
+ GLuint color_buffer = 0;
+ GLuint depth_buffer = 0;
+ GLuint stencil_buffer = 0;
QT_CHECK_GLERROR();
// init texture
@@ -625,7 +618,21 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz,
}
glBindFramebuffer(GL_FRAMEBUFFER_EXT, ctx->d_ptr->current_fbo);
- if (!valid) {
+ if (valid) {
+ fbo_guard = createSharedResourceGuard(ctx, fbo, freeFramebufferFunc);
+ if (color_buffer)
+ color_buffer_guard = createSharedResourceGuard(ctx, color_buffer, freeRenderbufferFunc);
+ else
+ texture_guard = createSharedResourceGuard(ctx, texture, freeTextureFunc);
+ if (depth_buffer)
+ depth_buffer_guard = createSharedResourceGuard(ctx, depth_buffer, freeRenderbufferFunc);
+ if (stencil_buffer) {
+ if (stencil_buffer == depth_buffer)
+ stencil_buffer_guard = depth_buffer_guard;
+ else
+ stencil_buffer_guard = createSharedResourceGuard(ctx, stencil_buffer, freeRenderbufferFunc);
+ }
+ } else {
if (color_buffer)
glDeleteRenderbuffers(1, &color_buffer);
else
@@ -635,7 +642,6 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz,
if (stencil_buffer && depth_buffer != stencil_buffer)
glDeleteRenderbuffers(1, &stencil_buffer);
glDeleteFramebuffers(1, &fbo);
- fbo_guard.setId(0);
}
QT_CHECK_GLERROR();
@@ -644,6 +650,8 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz,
format.setAttachment(fbo_attachment);
format.setInternalTextureFormat(internal_format);
format.setMipmap(mipmap);
+
+ glDevice.setFBO(q, attachment);
}
/*!
@@ -720,8 +728,7 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz,
As of Qt 4.8, it's possible to draw into a QGLFramebufferObject
using a QPainter in a separate thread. Note that OpenGL 2.0 or
- OpenGL ES 2.0 is required for this to work. Also, under X11, it's
- necessary to set the Qt::AA_X11InitThreads application attribute.
+ OpenGL ES 2.0 is required for this to work.
\sa {Framebuffer Object Example}
*/
@@ -780,16 +787,6 @@ QGLFramebufferObject::QGLFramebufferObject(const QSize &size, GLenum target)
d->init(this, size, NoAttachment, target, DEFAULT_FORMAT);
}
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
-/*! \internal */
-QGLFramebufferObject::QGLFramebufferObject(const QSize &size, QMacCompatGLenum target)
- : d_ptr(new QGLFramebufferObjectPrivate)
-{
- Q_D(QGLFramebufferObject);
- d->init(this, size, NoAttachment, target, DEFAULT_FORMAT);
-}
-#endif
-
/*! \overload
Constructs an OpenGL framebuffer object and binds a 2D GL texture
@@ -832,16 +829,6 @@ QGLFramebufferObject::QGLFramebufferObject(int width, int height, const QGLFrame
format.internalTextureFormat(), format.samples(), format.mipmap());
}
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
-/*! \internal */
-QGLFramebufferObject::QGLFramebufferObject(int width, int height, QMacCompatGLenum target)
- : d_ptr(new QGLFramebufferObjectPrivate)
-{
- Q_D(QGLFramebufferObject);
- d->init(this, QSize(width, height), NoAttachment, target, DEFAULT_FORMAT);
-}
-#endif
-
/*! \overload
Constructs an OpenGL framebuffer object and binds a texture to the
@@ -863,17 +850,6 @@ QGLFramebufferObject::QGLFramebufferObject(int width, int height, Attachment att
d->init(this, QSize(width, height), attachment, target, internal_format);
}
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
-/*! \internal */
-QGLFramebufferObject::QGLFramebufferObject(int width, int height, Attachment attachment,
- QMacCompatGLenum target, QMacCompatGLenum internal_format)
- : d_ptr(new QGLFramebufferObjectPrivate)
-{
- Q_D(QGLFramebufferObject);
- d->init(this, QSize(width, height), attachment, target, internal_format);
-}
-#endif
-
/*! \overload
Constructs an OpenGL framebuffer object and binds a texture to the
@@ -895,17 +871,6 @@ QGLFramebufferObject::QGLFramebufferObject(const QSize &size, Attachment attachm
d->init(this, size, attachment, target, internal_format);
}
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
-/*! \internal */
-QGLFramebufferObject::QGLFramebufferObject(const QSize &size, Attachment attachment,
- QMacCompatGLenum target, QMacCompatGLenum internal_format)
- : d_ptr(new QGLFramebufferObjectPrivate)
-{
- Q_D(QGLFramebufferObject);
- d->init(this, size, attachment, target, internal_format);
-}
-#endif
-
/*!
\fn QGLFramebufferObject::~QGLFramebufferObject()
@@ -914,23 +879,19 @@ QGLFramebufferObject::QGLFramebufferObject(const QSize &size, Attachment attachm
QGLFramebufferObject::~QGLFramebufferObject()
{
Q_D(QGLFramebufferObject);
- QGL_FUNC_CONTEXT;
delete d->engine;
- if (isValid() && ctx) {
- QGLShareContextScope scope(ctx);
- if (d->texture)
- glDeleteTextures(1, &d->texture);
- if (d->color_buffer)
- glDeleteRenderbuffers(1, &d->color_buffer);
- if (d->depth_buffer)
- glDeleteRenderbuffers(1, &d->depth_buffer);
- if (d->stencil_buffer && d->stencil_buffer != d->depth_buffer)
- glDeleteRenderbuffers(1, &d->stencil_buffer);
- GLuint fbo = d->fbo();
- glDeleteFramebuffers(1, &fbo);
- }
+ if (d->texture_guard)
+ d->texture_guard->free();
+ if (d->color_buffer_guard)
+ d->color_buffer_guard->free();
+ if (d->depth_buffer_guard)
+ d->depth_buffer_guard->free();
+ if (d->stencil_buffer_guard && d->stencil_buffer_guard != d->depth_buffer_guard)
+ d->stencil_buffer_guard->free();
+ if (d->fbo_guard)
+ d->fbo_guard->free();
}
/*!
@@ -954,7 +915,7 @@ QGLFramebufferObject::~QGLFramebufferObject()
bool QGLFramebufferObject::isValid() const
{
Q_D(const QGLFramebufferObject);
- return d->valid && d->fbo_guard.context();
+ return d->valid && d->fbo_guard && d->fbo_guard->id();
}
/*!
@@ -1037,7 +998,7 @@ bool QGLFramebufferObject::release()
GLuint QGLFramebufferObject::texture() const
{
Q_D(const QGLFramebufferObject);
- return d->texture;
+ return d->texture_guard ? d->texture_guard->id() : 0;
}
/*!
@@ -1092,13 +1053,7 @@ QImage QGLFramebufferObject::toImage() const
return image;
}
-#if !defined(QT_OPENGL_ES_1)
Q_GLOBAL_STATIC(QGLEngineThreadStorage<QGL2PaintEngineEx>, qt_buffer_2_engine)
-#endif
-
-#ifndef QT_OPENGL_ES_2
-Q_GLOBAL_STATIC(QGLEngineThreadStorage<QOpenGLPaintEngine>, qt_buffer_engine)
-#endif
/*! \reimp */
QPaintEngine *QGLFramebufferObject::paintEngine() const
@@ -1107,29 +1062,12 @@ QPaintEngine *QGLFramebufferObject::paintEngine() const
if (d->engine)
return d->engine;
-#if !defined(QT_OPENGL_ES_1)
-#if !defined (QT_OPENGL_ES_2)
- if (qt_gl_preferGL2Engine()) {
-#endif
- QPaintEngine *engine = qt_buffer_2_engine()->engine();
- if (engine->isActive() && engine->paintDevice() != this) {
- d->engine = new QGL2PaintEngineEx;
- return d->engine;
- }
- return engine;
-#if !defined (QT_OPENGL_ES_2)
- }
-#endif
-#endif
-
-#if !defined(QT_OPENGL_ES_2)
- QPaintEngine *engine = qt_buffer_engine()->engine();
+ QPaintEngine *engine = qt_buffer_2_engine()->engine();
if (engine->isActive() && engine->paintDevice() != this) {
- d->engine = new QOpenGLPaintEngine;
+ d->engine = new QGL2PaintEngineEx;
return d->engine;
}
return engine;
-#endif
}
/*!
@@ -1189,14 +1127,6 @@ void QGLFramebufferObject::drawTexture(const QRectF &target, GLuint textureId, G
const_cast<QGLContext *>(QGLContext::currentContext())->drawTexture(target, textureId, textureTarget);
}
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
-/*! \internal */
-void QGLFramebufferObject::drawTexture(const QRectF &target, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget)
-{
- const_cast<QGLContext *>(QGLContext::currentContext())->drawTexture(target, textureId, textureTarget);
-}
-#endif
-
/*!
\since 4.4
@@ -1212,14 +1142,6 @@ void QGLFramebufferObject::drawTexture(const QPointF &point, GLuint textureId, G
const_cast<QGLContext *>(QGLContext::currentContext())->drawTexture(point, textureId, textureTarget);
}
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
-/*! \internal */
-void QGLFramebufferObject::drawTexture(const QPointF &point, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget)
-{
- const_cast<QGLContext *>(QGLContext::currentContext())->drawTexture(point, textureId, textureTarget);
-}
-#endif
-
/*! \reimp */
int QGLFramebufferObject::metric(PaintDeviceMetric metric) const
{
@@ -1370,10 +1292,12 @@ void QGLFramebufferObject::blitFramebuffer(QGLFramebufferObject *target, const Q
return;
const QGLContext *ctx = QGLContext::currentContext();
- if (!ctx)
+ if (!ctx || !ctx->contextHandle())
return;
- const int height = ctx->device()->height();
+ QSurface *surface = ctx->contextHandle()->surface();
+
+ const int height = static_cast<QWindow *>(surface)->height();
const int sh = source ? source->height() : height;
const int th = target ? target->height() : height;
diff --git a/src/opengl/qglframebufferobject.h b/src/opengl/qglframebufferobject.h
index d5e5c482fb..817aecd9b7 100644
--- a/src/opengl/qglframebufferobject.h
+++ b/src/opengl/qglframebufferobject.h
@@ -81,16 +81,6 @@ public:
QGLFramebufferObject(const QSize &size, const QGLFramebufferObjectFormat &format);
QGLFramebufferObject(int width, int height, const QGLFramebufferObjectFormat &format);
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
- QGLFramebufferObject(const QSize &size, QMacCompatGLenum target = GL_TEXTURE_2D);
- QGLFramebufferObject(int width, int height, QMacCompatGLenum target = GL_TEXTURE_2D);
-
- QGLFramebufferObject(const QSize &size, Attachment attachment,
- QMacCompatGLenum target = GL_TEXTURE_2D, QMacCompatGLenum internal_format = GL_RGBA8);
- QGLFramebufferObject(int width, int height, Attachment attachment,
- QMacCompatGLenum target = GL_TEXTURE_2D, QMacCompatGLenum internal_format = GL_RGBA8);
-#endif
-
virtual ~QGLFramebufferObject();
QGLFramebufferObjectFormat format() const;
@@ -114,10 +104,6 @@ public:
void drawTexture(const QRectF &target, GLuint textureId, GLenum textureTarget = GL_TEXTURE_2D);
void drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget = GL_TEXTURE_2D);
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
- void drawTexture(const QRectF &target, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget = GL_TEXTURE_2D);
- void drawTexture(const QPointF &point, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget = GL_TEXTURE_2D);
-#endif
static bool hasOpenGLFramebufferBlit();
static void blitFramebuffer(QGLFramebufferObject *target, const QRect &targetRect,
@@ -160,11 +146,6 @@ public:
void setInternalTextureFormat(GLenum internalTextureFormat);
GLenum internalTextureFormat() const;
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
- void setTextureTarget(QMacCompatGLenum target);
- void setInternalTextureFormat(QMacCompatGLenum internalTextureFormat);
-#endif
-
bool operator==(const QGLFramebufferObjectFormat& other) const;
bool operator!=(const QGLFramebufferObjectFormat& other) const;
diff --git a/src/opengl/qglframebufferobject_p.h b/src/opengl/qglframebufferobject_p.h
index f82361279d..61d39c6a07 100644
--- a/src/opengl/qglframebufferobject_p.h
+++ b/src/opengl/qglframebufferobject_p.h
@@ -130,8 +130,9 @@ private:
class QGLFramebufferObjectPrivate
{
public:
- QGLFramebufferObjectPrivate() : fbo_guard(0), texture(0), depth_buffer(0), stencil_buffer(0)
- , color_buffer(0), valid(false), engine(0) {}
+ QGLFramebufferObjectPrivate() : fbo_guard(0), texture_guard(0), depth_buffer_guard(0)
+ , stencil_buffer_guard(0), color_buffer_guard(0)
+ , valid(false), engine(0) {}
~QGLFramebufferObjectPrivate() {}
void init(QGLFramebufferObject *q, const QSize& sz,
@@ -139,11 +140,11 @@ public:
GLenum internal_format, GLenum texture_target,
GLint samples = 0, bool mipmap = false);
bool checkFramebufferStatus() const;
- QGLSharedResourceGuard fbo_guard;
- GLuint texture;
- GLuint depth_buffer;
- GLuint stencil_buffer;
- GLuint color_buffer;
+ QGLSharedResourceGuardBase *fbo_guard;
+ QGLSharedResourceGuardBase *texture_guard;
+ QGLSharedResourceGuardBase *depth_buffer_guard;
+ QGLSharedResourceGuardBase *stencil_buffer_guard;
+ QGLSharedResourceGuardBase *color_buffer_guard;
GLenum target;
QSize size;
QGLFramebufferObjectFormat format;
@@ -152,7 +153,7 @@ public:
mutable QPaintEngine *engine;
QGLFBOGLPaintDevice glDevice;
- inline GLuint fbo() const { return fbo_guard.id(); }
+ inline GLuint fbo() const { return fbo_guard ? fbo_guard->id() : 0; }
};
diff --git a/src/opengl/qglfunctions.cpp b/src/opengl/qglfunctions.cpp
index 02e7091c9e..227e6cc176 100644
--- a/src/opengl/qglfunctions.cpp
+++ b/src/opengl/qglfunctions.cpp
@@ -41,6 +41,7 @@
#include "qglfunctions.h"
#include "qgl_p.h"
+#include "QtGui/private/qopenglcontext_p.h"
QT_BEGIN_NAMESPACE
@@ -139,25 +140,28 @@ QT_BEGIN_NAMESPACE
*/
// Hidden private fields for additional extension data.
-struct QGLFunctionsPrivateEx : public QGLFunctionsPrivate
+struct QGLFunctionsPrivateEx : public QGLFunctionsPrivate, public QOpenGLSharedResource
{
- QGLFunctionsPrivateEx(const QGLContext *context = 0)
- : QGLFunctionsPrivate(context)
+ QGLFunctionsPrivateEx(QOpenGLContext *context)
+ : QGLFunctionsPrivate(QGLContext::fromOpenGLContext(context))
+ , QOpenGLSharedResource(context->shareGroup())
, m_features(-1) {}
+ void invalidateResource()
+ {
+ m_features = -1;
+ }
+
+ void freeResource(QOpenGLContext *)
+ {
+ // no gl resources to free
+ }
+
int m_features;
};
-#if QT_VERSION >= 0x040800
-Q_GLOBAL_STATIC(QGLContextGroupResource<QGLFunctionsPrivateEx>, qt_gl_functions_resource)
-#else
-static void qt_gl_functions_free(void *data)
-{
- delete reinterpret_cast<QGLFunctionsPrivateEx *>(data);
-}
+Q_GLOBAL_STATIC(QOpenGLMultiGroupSharedResource, qt_gl_functions_resource)
-Q_GLOBAL_STATIC_WITH_ARGS(QGLContextResource, qt_gl_functions_resource, (qt_gl_functions_free))
-#endif
static QGLFunctionsPrivateEx *qt_gl_functions(const QGLContext *context = 0)
{
if (!context)
@@ -165,13 +169,7 @@ static QGLFunctionsPrivateEx *qt_gl_functions(const QGLContext *context = 0)
Q_ASSERT(context);
QGLFunctionsPrivateEx *funcs =
reinterpret_cast<QGLFunctionsPrivateEx *>
- (qt_gl_functions_resource()->value(context));
-#if QT_VERSION < 0x040800
- if (!funcs) {
- funcs = new QGLFunctionsPrivateEx();
- qt_gl_functions_resource()->insert(context, funcs);
- }
-#endif
+ (qt_gl_functions_resource()->value<QGLFunctionsPrivateEx>(context->contextHandle()));
return funcs;
}
diff --git a/src/opengl/qglfunctions.h b/src/opengl/qglfunctions.h
index 2bb6119b29..e789d4020d 100644
--- a/src/opengl/qglfunctions.h
+++ b/src/opengl/qglfunctions.h
@@ -419,7 +419,7 @@ struct QGLFunctionsPrivate
inline void QGLFunctions::glActiveTexture(GLenum texture)
{
-#if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_2)
+#if defined(QT_OPENGL_ES_2)
::glActiveTexture(texture);
#else
Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
@@ -449,7 +449,7 @@ inline void QGLFunctions::glBindAttribLocation(GLuint program, GLuint index, con
inline void QGLFunctions::glBindBuffer(GLenum target, GLuint buffer)
{
-#if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_2)
+#if defined(QT_OPENGL_ES_2)
::glBindBuffer(target, buffer);
#else
Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
@@ -519,7 +519,7 @@ inline void QGLFunctions::glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLen
inline void QGLFunctions::glBufferData(GLenum target, qgl_GLsizeiptr size, const void* data, GLenum usage)
{
-#if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_2)
+#if defined(QT_OPENGL_ES_2)
::glBufferData(target, size, data, usage);
#else
Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
@@ -529,7 +529,7 @@ inline void QGLFunctions::glBufferData(GLenum target, qgl_GLsizeiptr size, const
inline void QGLFunctions::glBufferSubData(GLenum target, qgl_GLintptr offset, qgl_GLsizeiptr size, const void* data)
{
-#if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_2)
+#if defined(QT_OPENGL_ES_2)
::glBufferSubData(target, offset, size, data);
#else
Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
@@ -568,7 +568,7 @@ inline void QGLFunctions::glCompileShader(GLuint shader)
inline void QGLFunctions::glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data)
{
-#if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_2)
+#if defined(QT_OPENGL_ES_2)
::glCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data);
#else
Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
@@ -578,7 +578,7 @@ inline void QGLFunctions::glCompressedTexImage2D(GLenum target, GLint level, GLe
inline void QGLFunctions::glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data)
{
-#if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_2)
+#if defined(QT_OPENGL_ES_2)
::glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data);
#else
Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
@@ -608,7 +608,7 @@ inline GLuint QGLFunctions::glCreateShader(GLenum type)
inline void QGLFunctions::glDeleteBuffers(GLsizei n, const GLuint* buffers)
{
-#if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_2)
+#if defined(QT_OPENGL_ES_2)
::glDeleteBuffers(n, buffers);
#else
Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
@@ -717,7 +717,7 @@ inline void QGLFunctions::glFramebufferTexture2D(GLenum target, GLenum attachmen
inline void QGLFunctions::glGenBuffers(GLsizei n, GLuint* buffers)
{
-#if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_2)
+#if defined(QT_OPENGL_ES_2)
::glGenBuffers(n, buffers);
#else
Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
@@ -947,7 +947,7 @@ inline void QGLFunctions::glGetVertexAttribPointerv(GLuint index, GLenum pname,
inline GLboolean QGLFunctions::glIsBuffer(GLuint buffer)
{
-#if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_2)
+#if defined(QT_OPENGL_ES_2)
return ::glIsBuffer(buffer);
#else
Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
@@ -1027,7 +1027,7 @@ inline void QGLFunctions::glRenderbufferStorage(GLenum target, GLenum internalfo
inline void QGLFunctions::glSampleCoverage(GLclampf value, GLboolean invert)
{
-#if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_2)
+#if defined(QT_OPENGL_ES_2)
::glSampleCoverage(value, invert);
#else
Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
diff --git a/src/opengl/qglpaintdevice.cpp b/src/opengl/qglpaintdevice.cpp
index b4e12d8b7e..08807bdd49 100644
--- a/src/opengl/qglpaintdevice.cpp
+++ b/src/opengl/qglpaintdevice.cpp
@@ -43,14 +43,6 @@
#include <private/qgl_p.h>
#include <private/qglpixelbuffer_p.h>
#include <private/qglframebufferobject_p.h>
-#ifdef Q_WS_X11
-#include <private/qpixmapdata_x11gl_p.h>
-#endif
-
-#if !defined(QT_OPENGL_ES_1)
-#include <private/qpixmapdata_gl_p.h>
-#include <private/qwindowsurface_gl_p.h>
-#endif
QT_BEGIN_NAMESPACE
@@ -220,19 +212,7 @@ QGLPaintDevice* QGLPaintDevice::getDevice(QPaintDevice* pd)
glpd = &(static_cast<QGLFramebufferObject*>(pd)->d_func()->glDevice);
break;
case QInternal::Pixmap: {
-#if !defined(QT_OPENGL_ES_1)
- QPixmapData* pmd = static_cast<QPixmap*>(pd)->pixmapData();
- if (pmd->classId() == QPixmapData::OpenGLClass)
- glpd = static_cast<QGLPixmapData*>(pmd)->glDevice();
-#ifdef Q_WS_X11
- else if (pmd->classId() == QPixmapData::X11Class)
- glpd = static_cast<QX11GLPixmapData*>(pmd);
-#endif
- else
- qWarning("Pixmap type not supported for GL rendering");
-#else
- qWarning("Pixmap render targets not supported on OpenGL ES 1.x");
-#endif
+ qWarning("Pixmap type not supported for GL rendering");
break;
}
default:
diff --git a/src/opengl/qglpaintdevice_p.h b/src/opengl/qglpaintdevice_p.h
index c5390645e2..32ae85dc90 100644
--- a/src/opengl/qglpaintdevice_p.h
+++ b/src/opengl/qglpaintdevice_p.h
@@ -55,7 +55,7 @@
#include <qpaintdevice.h>
-#include <qgl.h>
+#include <QtOpenGL/qgl.h>
QT_BEGIN_NAMESPACE
diff --git a/src/opengl/qglpixelbuffer.cpp b/src/opengl/qglpixelbuffer.cpp
index 45e7cdd875..ddabbef0b2 100644
--- a/src/opengl/qglpixelbuffer.cpp
+++ b/src/opengl/qglpixelbuffer.cpp
@@ -81,8 +81,7 @@
As of Qt 4.8, it's possible to render into a QGLPixelBuffer using
a QPainter in a separate thread. Note that OpenGL 2.0 or OpenGL ES
- 2.0 is required for this to work. Also, under X11, it's necessary
- to set the Qt::AA_X11InitThreads application attribute.
+ 2.0 is required for this to work.
Pbuffers are provided by the OpenGL \c pbuffer extension; call
hasOpenGLPbuffer() to find out if the system provides pbuffers.
@@ -92,28 +91,16 @@
#include <QtCore/qglobal.h>
-#if !defined(QT_OPENGL_ES_1)
-#include <private/qpaintengineex_opengl2_p.h>
-#endif
+#include "gl2paintengineex/qpaintengineex_opengl2_p.h"
#include <qglpixelbuffer.h>
#include <private/qglpixelbuffer_p.h>
#include <private/qfont_p.h>
#include <qimage.h>
-#ifndef QT_OPENGL_ES_2
-#include <private/qpaintengine_opengl_p.h>
-#endif
-
QT_BEGIN_NAMESPACE
-#if !defined(QT_OPENGL_ES_2)
-extern void qgl_cleanup_glyph_cache(QGLContext *);
-#else
-void qgl_cleanup_glyph_cache(QGLContext *) {}
-#endif
-
-extern Q_OPENGL_EXPORT QImage qt_gl_read_framebuffer(const QSize&, bool, bool);
+extern QImage qt_gl_read_framebuffer(const QSize&, bool, bool);
QGLContext* QGLPBufferGLPaintDevice::context() const
@@ -149,20 +136,6 @@ void QGLPixelBufferPrivate::common_init(const QSize &size, const QGLFormat &form
glDevice.setPBuffer(q);
qctx->d_func()->paintDevice = q;
qctx->d_func()->valid = true;
-#if defined(Q_WS_WIN) && !defined(QT_OPENGL_ES)
- qctx->d_func()->dc = dc;
- qctx->d_func()->rc = ctx;
-#elif (defined(Q_WS_X11) && defined(QT_NO_EGL))
- qctx->d_func()->cx = ctx;
- qctx->d_func()->pbuf = (void *) pbuf;
- qctx->d_func()->vi = 0;
-#elif defined(Q_WS_MAC)
- qctx->d_func()->cx = ctx;
- qctx->d_func()->vi = 0;
-#elif !defined(QT_NO_EGL)
- qctx->d_func()->eglContext = ctx;
- qctx->d_func()->eglSurface = pbuf;
-#endif
}
}
@@ -221,7 +194,6 @@ QGLPixelBuffer::~QGLPixelBuffer()
QGLContext *current = const_cast<QGLContext *>(QGLContext::currentContext());
if (current != d->qctx)
makeCurrent();
- qgl_cleanup_glyph_cache(d->qctx);
d->cleanup();
delete d->qctx;
if (current && current != d->qctx)
@@ -261,6 +233,8 @@ bool QGLPixelBuffer::doneCurrent()
}
/*!
+ \fn GLuint QGLPixelBuffer::generateDynamicTexture() const
+
Generates and binds a 2D GL texture that is the same size as the
pbuffer, and returns the texture's ID. This can be used in
conjunction with bindToDynamicTexture() and
@@ -269,20 +243,6 @@ bool QGLPixelBuffer::doneCurrent()
\sa size()
*/
-#if (defined(Q_WS_X11) || defined(Q_WS_WIN)) && defined(QT_NO_EGL)
-GLuint QGLPixelBuffer::generateDynamicTexture() const
-{
- Q_D(const QGLPixelBuffer);
- GLuint texture;
- glGenTextures(1, &texture);
- glBindTexture(GL_TEXTURE_2D, texture);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, d->req_size.width(), d->req_size.height(), 0, GL_RGBA, GL_FLOAT, 0);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- return texture;
-}
-#endif
-
/*! \fn bool QGLPixelBuffer::bindToDynamicTexture(GLuint texture_id)
Binds the texture specified by \a texture_id to this pbuffer.
@@ -353,13 +313,6 @@ void QGLPixelBuffer::updateDynamicTexture(GLuint texture_id) const
#endif
}
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
-void QGLPixelBuffer::updateDynamicTexture(QMacCompatGLuint texture_id) const
-{
- updateDynamicTexture(GLuint(texture_id));
-}
-#endif
-
/*!
Returns the size of the pbuffer.
*/
@@ -402,27 +355,12 @@ bool QGLPixelBuffer::isValid() const
return !d->invalid;
}
-#if !defined(QT_OPENGL_ES_1)
Q_GLOBAL_STATIC(QGLEngineThreadStorage<QGL2PaintEngineEx>, qt_buffer_2_engine)
-#endif
-
-#ifndef QT_OPENGL_ES_2
-Q_GLOBAL_STATIC(QGLEngineThreadStorage<QOpenGLPaintEngine>, qt_buffer_engine)
-#endif
/*! \reimp */
QPaintEngine *QGLPixelBuffer::paintEngine() const
{
-#if defined(QT_OPENGL_ES_1)
- return qt_buffer_engine()->engine();
-#elif defined(QT_OPENGL_ES_2)
return qt_buffer_2_engine()->engine();
-#else
- if (qt_gl_preferGL2Engine())
- return qt_buffer_2_engine()->engine();
- else
- return qt_buffer_engine()->engine();
-#endif
}
/*! \reimp */
@@ -493,15 +431,6 @@ GLuint QGLPixelBuffer::bindTexture(const QImage &image, GLenum target)
#endif
}
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
-/*! \internal */
-GLuint QGLPixelBuffer::bindTexture(const QImage &image, QMacCompatGLenum target)
-{
- Q_D(QGLPixelBuffer);
- return d->qctx->bindTexture(image, target, QMacCompatGLint(GL_RGBA8));
-}
-#endif
-
/*! \overload
Generates and binds a 2D GL texture based on \a pixmap.
@@ -520,15 +449,6 @@ GLuint QGLPixelBuffer::bindTexture(const QPixmap &pixmap, GLenum target)
#endif
}
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
-/*! \internal */
-GLuint QGLPixelBuffer::bindTexture(const QPixmap &pixmap, QMacCompatGLenum target)
-{
- Q_D(QGLPixelBuffer);
- return d->qctx->bindTexture(pixmap, target, QMacCompatGLint(GL_RGBA8));
-}
-#endif
-
/*! \overload
Reads the DirectDrawSurface (DDS) compressed file \a fileName and
@@ -555,15 +475,6 @@ void QGLPixelBuffer::deleteTexture(GLuint texture_id)
d->qctx->deleteTexture(texture_id);
}
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
-/*! \internal */
-void QGLPixelBuffer::deleteTexture(QMacCompatGLuint texture_id)
-{
- Q_D(QGLPixelBuffer);
- d->qctx->deleteTexture(texture_id);
-}
-#endif
-
/*!
\since 4.4
@@ -579,15 +490,6 @@ void QGLPixelBuffer::drawTexture(const QRectF &target, GLuint textureId, GLenum
d->qctx->drawTexture(target, textureId, textureTarget);
}
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
-/*! \internal */
-void QGLPixelBuffer::drawTexture(const QRectF &target, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget)
-{
- Q_D(QGLPixelBuffer);
- d->qctx->drawTexture(target, textureId, textureTarget);
-}
-#endif
-
/*!
\since 4.4
@@ -602,15 +504,6 @@ void QGLPixelBuffer::drawTexture(const QPointF &point, GLuint textureId, GLenum
d->qctx->drawTexture(point, textureId, textureTarget);
}
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
-/*! \internal */
-void QGLPixelBuffer::drawTexture(const QPointF &point, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget)
-{
- Q_D(QGLPixelBuffer);
- d->qctx->drawTexture(point, textureId, textureTarget);
-}
-#endif
-
/*!
Returns the format of the pbuffer. The format may be different
from the one that was requested.
diff --git a/src/opengl/qglpixelbuffer.h b/src/opengl/qglpixelbuffer.h
index dcd1a6ca71..0c7ad38237 100644
--- a/src/opengl/qglpixelbuffer.h
+++ b/src/opengl/qglpixelbuffer.h
@@ -80,18 +80,6 @@ public:
void drawTexture(const QRectF &target, GLuint textureId, GLenum textureTarget = GL_TEXTURE_2D);
void drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget = GL_TEXTURE_2D);
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
- bool bindToDynamicTexture(QMacCompatGLuint texture);
- void updateDynamicTexture(QMacCompatGLuint texture_id) const;
- GLuint bindTexture(const QImage &image, QMacCompatGLenum target = GL_TEXTURE_2D);
- GLuint bindTexture(const QPixmap &pixmap, QMacCompatGLenum target = GL_TEXTURE_2D);
-
- void drawTexture(const QRectF &target, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget = GL_TEXTURE_2D);
- void drawTexture(const QPointF &point, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget = GL_TEXTURE_2D);
-
- void deleteTexture(QMacCompatGLuint texture_id);
-#endif
-
QSize size() const;
Qt::HANDLE handle() const;
QImage toImage() const;
@@ -109,7 +97,6 @@ private:
Q_DISABLE_COPY(QGLPixelBuffer)
QScopedPointer<QGLPixelBufferPrivate> d_ptr;
friend class QGLDrawable;
- friend class QGLWindowSurface;
friend class QGLPaintDevice;
friend class QGLPBufferGLPaintDevice;
friend class QGLContextPrivate;
diff --git a/src/opengl/qglpixelbuffer_egl.cpp b/src/opengl/qglpixelbuffer_egl.cpp
deleted file mode 100644
index 64d032799a..0000000000
--- a/src/opengl/qglpixelbuffer_egl.cpp
+++ /dev/null
@@ -1,224 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qdebug.h>
-#include "qglpixelbuffer.h"
-#include "qglpixelbuffer_p.h"
-#include "qgl_egl_p.h"
-
-#include <qimage.h>
-#include <private/qgl_p.h>
-
-QT_BEGIN_NAMESPACE
-
-#ifdef EGL_BIND_TO_TEXTURE_RGBA
-#define QGL_RENDER_TEXTURE 1
-#else
-#define QGL_RENDER_TEXTURE 0
-#endif
-
-bool QGLPixelBufferPrivate::init(const QSize &size, const QGLFormat &f, QGLWidget *shareWidget)
-{
- // Create the EGL context.
- ctx = new QEglContext();
- ctx->setApi(QEgl::OpenGL);
-
- // Find the shared context.
- QEglContext *shareContext = 0;
- if (shareWidget && shareWidget->d_func()->glcx)
- shareContext = shareWidget->d_func()->glcx->d_func()->eglContext;
-
- // Choose an appropriate configuration. We use the best format
- // we can find, even if it is greater than the requested format.
- // We try for a pbuffer that is capable of texture rendering if possible.
- textureFormat = EGL_NONE;
- if (shareContext) {
- // Use the same configuration as the widget we are sharing with.
- ctx->setConfig(shareContext->config());
-#if QGL_RENDER_TEXTURE
- if (ctx->configAttrib(EGL_BIND_TO_TEXTURE_RGBA) == EGL_TRUE)
- textureFormat = EGL_TEXTURE_RGBA;
- else if (ctx->configAttrib(EGL_BIND_TO_TEXTURE_RGB) == EGL_TRUE)
- textureFormat = EGL_TEXTURE_RGB;
-#endif
- } else {
- QEglProperties configProps;
- qt_eglproperties_set_glformat(configProps, f);
- configProps.setDeviceType(QInternal::Pbuffer);
- configProps.setRenderableType(ctx->api());
- bool ok = false;
-#if QGL_RENDER_TEXTURE
- textureFormat = EGL_TEXTURE_RGBA;
- configProps.setValue(EGL_BIND_TO_TEXTURE_RGBA, EGL_TRUE);
- ok = ctx->chooseConfig(configProps, QEgl::BestPixelFormat);
- if (!ok) {
- // Try again with RGB texture rendering.
- textureFormat = EGL_TEXTURE_RGB;
- configProps.removeValue(EGL_BIND_TO_TEXTURE_RGBA);
- configProps.setValue(EGL_BIND_TO_TEXTURE_RGB, EGL_TRUE);
- ok = ctx->chooseConfig(configProps, QEgl::BestPixelFormat);
- if (!ok) {
- // One last try for a pbuffer with no texture rendering.
- configProps.removeValue(EGL_BIND_TO_TEXTURE_RGB);
- textureFormat = EGL_NONE;
- }
- }
-#endif
- if (!ok) {
- if (!ctx->chooseConfig(configProps, QEgl::BestPixelFormat)) {
- delete ctx;
- ctx = 0;
- return false;
- }
- }
- }
-
- // Retrieve the actual format properties.
- qt_glformat_from_eglconfig(format, ctx->config());
-
- // Create the attributes needed for the pbuffer.
- QEglProperties attribs;
- attribs.setValue(EGL_WIDTH, size.width());
- attribs.setValue(EGL_HEIGHT, size.height());
-#if QGL_RENDER_TEXTURE
- if (textureFormat != EGL_NONE) {
- attribs.setValue(EGL_TEXTURE_FORMAT, textureFormat);
- attribs.setValue(EGL_TEXTURE_TARGET, EGL_TEXTURE_2D);
- }
-#endif
-
- // Create the pbuffer surface.
- pbuf = eglCreatePbufferSurface(ctx->display(), ctx->config(), attribs.properties());
-#if QGL_RENDER_TEXTURE
- if (pbuf == EGL_NO_SURFACE && textureFormat != EGL_NONE) {
- // Try again with texture rendering disabled.
- textureFormat = EGL_NONE;
- attribs.removeValue(EGL_TEXTURE_FORMAT);
- attribs.removeValue(EGL_TEXTURE_TARGET);
- pbuf = eglCreatePbufferSurface(ctx->display(), ctx->config(), attribs.properties());
- }
-#endif
- if (pbuf == EGL_NO_SURFACE) {
- qWarning() << "QGLPixelBufferPrivate::init(): Unable to create EGL pbuffer surface:" << QEgl::errorString();
- return false;
- }
-
- // Create a new context for the configuration.
- if (!ctx->createContext(shareContext)) {
- delete ctx;
- ctx = 0;
- return false;
- }
-
- return true;
-}
-
-bool QGLPixelBufferPrivate::cleanup()
-{
- // No need to destroy "pbuf" here - it is done in QGLContext::reset().
- return true;
-}
-
-bool QGLPixelBuffer::bindToDynamicTexture(GLuint texture_id)
-{
-#if QGL_RENDER_TEXTURE
- Q_D(QGLPixelBuffer);
- if (d->invalid || d->textureFormat == EGL_NONE || !d->ctx)
- return false;
- glBindTexture(GL_TEXTURE_2D, texture_id);
- return eglBindTexImage(d->ctx->display(), d->pbuf, EGL_BACK_BUFFER);
-#else
- Q_UNUSED(texture_id);
- return false;
-#endif
-}
-
-void QGLPixelBuffer::releaseFromDynamicTexture()
-{
-#if QGL_RENDER_TEXTURE
- Q_D(QGLPixelBuffer);
- if (d->invalid || d->textureFormat == EGL_NONE || !d->ctx)
- return;
- eglReleaseTexImage(d->ctx->display(), d->pbuf, EGL_BACK_BUFFER);
-#endif
-}
-
-
-GLuint QGLPixelBuffer::generateDynamicTexture() const
-{
-#if QGL_RENDER_TEXTURE
- Q_D(const QGLPixelBuffer);
- GLuint texture;
- glGenTextures(1, &texture);
- glBindTexture(GL_TEXTURE_2D, texture);
- if (d->textureFormat == EGL_TEXTURE_RGB)
- 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);
- 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;
-#endif
-}
-
-bool QGLPixelBuffer::hasOpenGLPbuffers()
-{
- // See if we have at least 1 configuration that matches the default format.
- EGLDisplay dpy = QEgl::display();
- if (dpy == EGL_NO_DISPLAY)
- return false;
- QEglProperties configProps;
- qt_eglproperties_set_glformat(configProps, QGLFormat::defaultFormat());
- configProps.setDeviceType(QInternal::Pbuffer);
- configProps.setRenderableType(QEgl::OpenGL);
- do {
- EGLConfig cfg = 0;
- EGLint matching = 0;
- if (eglChooseConfig(dpy, configProps.properties(),
- &cfg, 1, &matching) && matching > 0)
- return true;
- } while (configProps.reduceConfiguration());
- return false;
-}
-
-QT_END_NAMESPACE
diff --git a/src/opengl/qglpixelbuffer_mac.mm b/src/opengl/qglpixelbuffer_mac.mm
deleted file mode 100644
index b364209b95..0000000000
--- a/src/opengl/qglpixelbuffer_mac.mm
+++ /dev/null
@@ -1,331 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qglpixelbuffer.h"
-#include "qglpixelbuffer_p.h"
-
-#ifndef QT_MAC_USE_COCOA
-#include <AGL/agl.h>
-#endif
-
-#include <qimage.h>
-#include <private/qgl_p.h>
-#include <qdebug.h>
-
-QT_BEGIN_NAMESPACE
-
-#ifndef GL_TEXTURE_RECTANGLE_EXT
-#define GL_TEXTURE_RECTANGLE_EXT 0x84F5
-#endif
-
-static int nearest_gl_texture_size(int v)
-{
- int n = 0, last = 0;
- for (int s = 0; s < 32; ++s) {
- if (((v>>s) & 1) == 1) {
- ++n;
- last = s;
- }
- }
- if (n > 1)
- return 1 << (last+1);
- return 1 << last;
-}
-
-bool QGLPixelBufferPrivate::init(const QSize &size, const QGLFormat &f, QGLWidget *shareWidget)
-{
-#ifdef QT_MAC_USE_COCOA
- Q_Q(QGLPixelBuffer);
- // create a dummy context
- QGLContext context(f, q);
- context.create(shareWidget ? shareWidget->context() : 0);
-
- if (context.isSharing())
- share_ctx = shareWidget->context()->d_func()->cx;
-
- // steal the NSOpenGLContext and update the format
- ctx = context.d_func()->cx;
- context.d_func()->cx = 0;
- // d->cx will be set to ctx later in
- // QGLPixelBufferPrivate::common_init, so we need to retain it:
- [static_cast<NSOpenGLContext *>(ctx) retain];
-
- format = context.format();
-
- GLenum target = GL_TEXTURE_2D;
-
- if ((QGLExtensions::glExtensions() & QGLExtensions::TextureRectangle)
- && (size.width() != nearest_gl_texture_size(size.width())
- || size.height() != nearest_gl_texture_size(size.height())))
- {
- target = GL_TEXTURE_RECTANGLE_EXT;
- }
-
- pbuf = [[NSOpenGLPixelBuffer alloc] initWithTextureTarget:target
- textureInternalFormat:GL_RGBA
- textureMaxMipMapLevel:0
- pixelsWide:size.width()
- pixelsHigh:size.height()];
- if (!pbuf) {
- qWarning("QGLPixelBuffer: Cannot create a pbuffer");
- return false;
- }
-
- [static_cast<NSOpenGLContext *>(ctx) setPixelBuffer:static_cast<NSOpenGLPixelBuffer *>(pbuf)
- cubeMapFace:0
- mipMapLevel:0
- currentVirtualScreen:0];
- return true;
-#else
- GLint attribs[40], i=0;
- attribs[i++] = AGL_RGBA;
- attribs[i++] = AGL_BUFFER_SIZE;
- attribs[i++] = 32;
- attribs[i++] = AGL_LEVEL;
- attribs[i++] = f.plane();
- if (f.redBufferSize() != -1) {
- attribs[i++] = AGL_RED_SIZE;
- attribs[i++] = f.redBufferSize();
- }
- if (f.greenBufferSize() != -1) {
- attribs[i++] = AGL_GREEN_SIZE;
- attribs[i++] = f.greenBufferSize();
- }
- if (f.blueBufferSize() != -1) {
- attribs[i++] = AGL_BLUE_SIZE;
- attribs[i++] = f.blueBufferSize();
- }
- if (f.stereo())
- attribs[i++] = AGL_STEREO;
- if (f.alpha()) {
- attribs[i++] = AGL_ALPHA_SIZE;
- attribs[i++] = f.alphaBufferSize() == -1 ? 8 : f.alphaBufferSize();
- }
- if (f.stencil()) {
- attribs[i++] = AGL_STENCIL_SIZE;
- attribs[i++] = f.stencilBufferSize() == -1 ? 8 : f.stencilBufferSize();
- }
- if (f.depth()) {
- attribs[i++] = AGL_DEPTH_SIZE;
- attribs[i++] = f.depthBufferSize() == -1 ? 32 : f.depthBufferSize();
- }
- if (f.accum()) {
- attribs[i++] = AGL_ACCUM_RED_SIZE;
- attribs[i++] = f.accumBufferSize() == -1 ? 16 : f.accumBufferSize();
- attribs[i++] = AGL_ACCUM_BLUE_SIZE;
- attribs[i++] = f.accumBufferSize() == -1 ? 16 : f.accumBufferSize();
- attribs[i++] = AGL_ACCUM_GREEN_SIZE;
- attribs[i++] = f.accumBufferSize() == -1 ? 16 : f.accumBufferSize();
- attribs[i++] = AGL_ACCUM_ALPHA_SIZE;
- attribs[i++] = f.accumBufferSize() == -1 ? 16 : f.accumBufferSize();
- }
-
- if (f.sampleBuffers()) {
- attribs[i++] = AGL_SAMPLE_BUFFERS_ARB;
- attribs[i++] = 1;
- attribs[i++] = AGL_SAMPLES_ARB;
- attribs[i++] = f.samples() == -1 ? 4 : f.samples();
- }
- attribs[i] = AGL_NONE;
-
- AGLPixelFormat format = aglChoosePixelFormat(0, 0, attribs);
- if (!format) {
- qWarning("QGLPixelBuffer: Unable to find a pixel format (AGL error %d).",
- (int) aglGetError());
- return false;
- }
-
- GLint res;
- aglDescribePixelFormat(format, AGL_LEVEL, &res);
- this->format.setPlane(res);
- aglDescribePixelFormat(format, AGL_DOUBLEBUFFER, &res);
- this->format.setDoubleBuffer(res);
- aglDescribePixelFormat(format, AGL_DEPTH_SIZE, &res);
- this->format.setDepth(res);
- if (this->format.depth())
- this->format.setDepthBufferSize(res);
- aglDescribePixelFormat(format, AGL_RGBA, &res);
- this->format.setRgba(res);
- aglDescribePixelFormat(format, AGL_RED_SIZE, &res);
- this->format.setRedBufferSize(res);
- aglDescribePixelFormat(format, AGL_GREEN_SIZE, &res);
- this->format.setGreenBufferSize(res);
- aglDescribePixelFormat(format, AGL_BLUE_SIZE, &res);
- this->format.setBlueBufferSize(res);
- aglDescribePixelFormat(format, AGL_ALPHA_SIZE, &res);
- this->format.setAlpha(res);
- if (this->format.alpha())
- this->format.setAlphaBufferSize(res);
- aglDescribePixelFormat(format, AGL_ACCUM_RED_SIZE, &res);
- this->format.setAccum(res);
- if (this->format.accum())
- this->format.setAccumBufferSize(res);
- aglDescribePixelFormat(format, AGL_STENCIL_SIZE, &res);
- this->format.setStencil(res);
- if (this->format.stencil())
- this->format.setStencilBufferSize(res);
- aglDescribePixelFormat(format, AGL_STEREO, &res);
- this->format.setStereo(res);
- aglDescribePixelFormat(format, AGL_SAMPLE_BUFFERS_ARB, &res);
- this->format.setSampleBuffers(res);
- if (this->format.sampleBuffers()) {
- aglDescribePixelFormat(format, AGL_SAMPLES_ARB, &res);
- this->format.setSamples(res);
- }
-
- AGLContext share = 0;
- if (shareWidget)
- share = share_ctx = static_cast<AGLContext>(shareWidget->d_func()->glcx->d_func()->cx);
- ctx = aglCreateContext(format, share);
- if (!ctx) {
- qWarning("QGLPixelBuffer: Unable to create a context (AGL error %d).",
- (int) aglGetError());
- return false;
- }
-
- GLenum target = GL_TEXTURE_2D;
-
- if ((QGLExtensions::glExtensions() & QGLExtensions::TextureRectangle)
- && (size.width() != nearest_gl_texture_size(size.width())
- || size.height() != nearest_gl_texture_size(size.height())))
- {
- target = GL_TEXTURE_RECTANGLE_EXT;
- }
-
- if (!aglCreatePBuffer(size.width(), size.height(), target, GL_RGBA, 0, &pbuf)) {
- qWarning("QGLPixelBuffer: Unable to create a pbuffer (AGL error %d).",
- (int) aglGetError());
- return false;
- }
-
- if (!aglSetPBuffer(ctx, pbuf, 0, 0, 0)) {
- qWarning("QGLPixelBuffer: Unable to set pbuffer (AGL error %d).",
- (int) aglGetError());
- return false;
- }
-
- aglDestroyPixelFormat(format);
- return true;
-
-#endif
-}
-
-bool QGLPixelBufferPrivate::cleanup()
-{
-#ifdef QT_MAC_USE_COCOA
- [static_cast<NSOpenGLPixelBuffer *>(pbuf) release];
- pbuf = 0;
- [static_cast<NSOpenGLContext *>(ctx) release];
- ctx = 0;
-#else
- aglDestroyPBuffer(pbuf);
-#endif
- return true;
-}
-
-bool QGLPixelBuffer::bindToDynamicTexture(GLuint texture_id)
-{
- Q_D(QGLPixelBuffer);
- if (d->invalid || !d->share_ctx)
- return false;
-
-#ifdef QT_MAC_USE_COCOA
- NSOpenGLContext *oldContext = [NSOpenGLContext currentContext];
- if (d->share_ctx != oldContext)
- [static_cast<NSOpenGLContext *>(d->share_ctx) makeCurrentContext];
- glBindTexture(GL_TEXTURE_2D, texture_id);
- [static_cast<NSOpenGLContext *>(d->share_ctx)
- setTextureImageToPixelBuffer:static_cast<NSOpenGLPixelBuffer *>(d->pbuf)
- colorBuffer:GL_FRONT];
- if (oldContext && oldContext != d->share_ctx)
- [oldContext makeCurrentContext];
- return true;
-#else
- aglSetCurrentContext(d->share_ctx);
- glBindTexture(GL_TEXTURE_2D, texture_id);
- aglTexImagePBuffer(d->share_ctx, d->pbuf, GL_FRONT);
- return true;
-#endif
-}
-
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
-bool QGLPixelBuffer::bindToDynamicTexture(QMacCompatGLuint texture_id)
-{
- return bindToDynamicTexture(GLuint(texture_id));
-}
-#endif
-
-void QGLPixelBuffer::releaseFromDynamicTexture()
-{
-}
-
-GLuint QGLPixelBuffer::generateDynamicTexture() const
-{
-#ifdef QT_MAC_USE_COCOA
- Q_D(const QGLPixelBuffer);
- NSOpenGLContext *oldContext = [NSOpenGLContext currentContext];
- if (d->share_ctx != oldContext)
- [static_cast<NSOpenGLContext *>(d->share_ctx) makeCurrentContext];
- GLuint texture;
- glGenTextures(1, &texture);
- glBindTexture(GL_TEXTURE_2D, texture);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-
- if (oldContext && oldContext != d->share_ctx)
- [oldContext makeCurrentContext];
- return texture;
-#else
- GLuint texture;
- glGenTextures(1, &texture);
- glBindTexture(GL_TEXTURE_2D, texture);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- return texture;
-#endif
-}
-
-bool QGLPixelBuffer::hasOpenGLPbuffers()
-{
- return true;
-}
-
-QT_END_NAMESPACE
diff --git a/src/opengl/qglpixelbuffer_p.h b/src/opengl/qglpixelbuffer_p.h
index eb761047e7..05e161b7ef 100644
--- a/src/opengl/qglpixelbuffer_p.h
+++ b/src/opengl/qglpixelbuffer_p.h
@@ -59,77 +59,6 @@ QT_BEGIN_INCLUDE_NAMESPACE
#include "QtOpenGL/qglpixelbuffer.h"
#include <private/qgl_p.h>
#include <private/qglpaintdevice_p.h>
-
-#if defined(Q_WS_X11) && defined(QT_NO_EGL)
-#include <GL/glx.h>
-
-// The below is needed to for compilation on HPUX, due to broken GLX
-// headers. Some of the systems define GLX_VERSION_1_3 without
-// defining the GLXFBConfig structure, which is wrong.
-#if defined (Q_OS_HPUX) && defined(QT_DEFINE_GLXFBCONFIG_STRUCT)
-typedef unsigned long GLXPbuffer;
-
-struct GLXFBConfig {
- int visualType;
- int transparentType;
- /* colors are floats scaled to ints */
- int transparentRed, transparentGreen, transparentBlue, transparentAlpha;
- int transparentIndex;
-
- int visualCaveat;
-
- int associatedVisualId;
- int screen;
-
- int drawableType;
- int renderType;
-
- int maxPbufferWidth, maxPbufferHeight, maxPbufferPixels;
- int optimalPbufferWidth, optimalPbufferHeight; /* for SGIX_pbuffer */
-
- int visualSelectGroup; /* visuals grouped by select priority */
-
- unsigned int id;
-
- GLboolean rgbMode;
- GLboolean colorIndexMode;
- GLboolean doubleBufferMode;
- GLboolean stereoMode;
- GLboolean haveAccumBuffer;
- GLboolean haveDepthBuffer;
- GLboolean haveStencilBuffer;
-
- /* The number of bits present in various buffers */
- GLint accumRedBits, accumGreenBits, accumBlueBits, accumAlphaBits;
- GLint depthBits;
- GLint stencilBits;
- GLint indexBits;
- GLint redBits, greenBits, blueBits, alphaBits;
- GLuint redMask, greenMask, blueMask, alphaMask;
-
- GLuint multiSampleSize; /* Number of samples per pixel (0 if no ms) */
-
- GLuint nMultiSampleBuffers; /* Number of available ms buffers */
- GLint maxAuxBuffers;
-
- /* frame buffer level */
- GLint level;
-
- /* color ranges (for SGI_color_range) */
- GLboolean extendedRange;
- GLdouble minRed, maxRed;
- GLdouble minGreen, maxGreen;
- GLdouble minBlue, maxBlue;
- GLdouble minAlpha, maxAlpha;
-};
-
-#endif // Q_OS_HPUX
-
-#elif defined(Q_WS_WIN)
-DECLARE_HANDLE(HPBUFFERARB);
-#elif !defined(QT_NO_EGL)
-#include <QtGui/private/qegl_p.h>
-#endif
QT_END_INCLUDE_NAMESPACE
class QEglContext;
@@ -152,11 +81,6 @@ class QGLPixelBufferPrivate {
public:
QGLPixelBufferPrivate(QGLPixelBuffer *q) : q_ptr(q), invalid(true), qctx(0), pbuf(0), ctx(0)
{
-#ifdef Q_WS_WIN
- dc = 0;
-#elif defined(Q_WS_MACX)
- share_ctx = 0;
-#endif
}
bool init(const QSize &size, const QGLFormat &f, QGLWidget *shareWidget);
void common_init(const QSize &size, const QGLFormat &f, QGLWidget *shareWidget);
@@ -172,36 +96,9 @@ public:
QPointer<QGLWidget> req_shareWidget;
QSize req_size;
-#if defined(Q_WS_X11) && defined(QT_NO_EGL)
- GLXPbuffer pbuf;
- GLXContext ctx;
-#elif defined(Q_WS_WIN)
- HDC dc;
- bool has_render_texture :1;
-#if !defined(QT_OPENGL_ES)
- HPBUFFERARB pbuf;
- HGLRC ctx;
-#endif
-#elif defined(Q_WS_MACX)
-# ifdef QT_MAC_USE_COCOA
- void *pbuf;
- void *ctx;
- void *share_ctx;
-# else
- AGLPbuffer pbuf;
- AGLContext ctx;
- AGLContext share_ctx;
-# endif
-#endif
-#ifndef QT_NO_EGL
- EGLSurface pbuf;
- QEglContext *ctx;
- int textureFormat;
-#elif defined(Q_WS_QPA)
//stubs
void *pbuf;
void *ctx;
-#endif
};
QT_END_NAMESPACE
diff --git a/src/opengl/qglpixelbuffer_win.cpp b/src/opengl/qglpixelbuffer_win.cpp
deleted file mode 100644
index 80ce99219e..0000000000
--- a/src/opengl/qglpixelbuffer_win.cpp
+++ /dev/null
@@ -1,403 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qglpixelbuffer.h>
-#include <qgl.h>
-#include <private/qgl_p.h>
-
-#include <private/qglpixelbuffer_p.h>
-
-#include <qimage.h>
-#include <qdebug.h>
-
-QT_BEGIN_NAMESPACE
-
-/* WGL_WGLEXT_PROTOTYPES */
-typedef const char * (WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc);
-typedef HPBUFFERARB (WINAPI * PFNWGLCREATEPBUFFERARBPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
-typedef HDC (WINAPI * PFNWGLGETPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer);
-typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer, HDC hDC);
-typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFERARBPROC) (HPBUFFERARB hPbuffer);
-typedef BOOL (WINAPI * PFNWGLQUERYPBUFFERARBPROC) (HPBUFFERARB hPbuffer, int iAttribute, int *piValue);
-typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues);
-typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues);
-typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
-typedef BOOL (WINAPI * PFNWGLBINDTEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer);
-typedef BOOL (WINAPI * PFNWGLRELEASETEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer);
-typedef BOOL (WINAPI * PFNWGLSETPBUFFERATTRIBARBPROC) (HPBUFFERARB hPbuffer, const int * piAttribList);
-
-#ifndef WGL_ARB_pbuffer
-#define WGL_DRAW_TO_PBUFFER_ARB 0x202D
-#define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E
-#define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F
-#define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030
-#define WGL_PBUFFER_LARGEST_ARB 0x2033
-#define WGL_PBUFFER_WIDTH_ARB 0x2034
-#define WGL_PBUFFER_HEIGHT_ARB 0x2035
-#define WGL_PBUFFER_LOST_ARB 0x2036
-#endif
-
-#ifndef WGL_ARB_pixel_format
-#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
-#define WGL_DRAW_TO_WINDOW_ARB 0x2001
-#define WGL_DRAW_TO_BITMAP_ARB 0x2002
-#define WGL_ACCELERATION_ARB 0x2003
-#define WGL_NEED_PALETTE_ARB 0x2004
-#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005
-#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006
-#define WGL_SWAP_METHOD_ARB 0x2007
-#define WGL_NUMBER_OVERLAYS_ARB 0x2008
-#define WGL_NUMBER_UNDERLAYS_ARB 0x2009
-#define WGL_TRANSPARENT_ARB 0x200A
-#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037
-#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038
-#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039
-#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A
-#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B
-#define WGL_SHARE_DEPTH_ARB 0x200C
-#define WGL_SHARE_STENCIL_ARB 0x200D
-#define WGL_SHARE_ACCUM_ARB 0x200E
-#define WGL_SUPPORT_GDI_ARB 0x200F
-#define WGL_SUPPORT_OPENGL_ARB 0x2010
-#define WGL_DOUBLE_BUFFER_ARB 0x2011
-#define WGL_STEREO_ARB 0x2012
-#define WGL_PIXEL_TYPE_ARB 0x2013
-#define WGL_COLOR_BITS_ARB 0x2014
-#define WGL_RED_BITS_ARB 0x2015
-#define WGL_RED_SHIFT_ARB 0x2016
-#define WGL_GREEN_BITS_ARB 0x2017
-#define WGL_GREEN_SHIFT_ARB 0x2018
-#define WGL_BLUE_BITS_ARB 0x2019
-#define WGL_BLUE_SHIFT_ARB 0x201A
-#define WGL_ALPHA_BITS_ARB 0x201B
-#define WGL_ALPHA_SHIFT_ARB 0x201C
-#define WGL_ACCUM_BITS_ARB 0x201D
-#define WGL_ACCUM_RED_BITS_ARB 0x201E
-#define WGL_ACCUM_GREEN_BITS_ARB 0x201F
-#define WGL_ACCUM_BLUE_BITS_ARB 0x2020
-#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
-#define WGL_DEPTH_BITS_ARB 0x2022
-#define WGL_STENCIL_BITS_ARB 0x2023
-#define WGL_AUX_BUFFERS_ARB 0x2024
-#define WGL_NO_ACCELERATION_ARB 0x2025
-#define WGL_GENERIC_ACCELERATION_ARB 0x2026
-#define WGL_FULL_ACCELERATION_ARB 0x2027
-#define WGL_SWAP_EXCHANGE_ARB 0x2028
-#define WGL_SWAP_COPY_ARB 0x2029
-#define WGL_SWAP_UNDEFINED_ARB 0x202A
-#define WGL_TYPE_RGBA_ARB 0x202B
-#define WGL_TYPE_COLORINDEX_ARB 0x202C
-#endif
-
-#ifndef WGL_ARB_render_texture
-#define WGL_BIND_TO_TEXTURE_RGB_ARB 0x2070
-#define WGL_BIND_TO_TEXTURE_RGBA_ARB 0x2071
-#define WGL_TEXTURE_FORMAT_ARB 0x2072
-#define WGL_TEXTURE_TARGET_ARB 0x2073
-#define WGL_MIPMAP_TEXTURE_ARB 0x2074
-#define WGL_TEXTURE_RGB_ARB 0x2075
-#define WGL_TEXTURE_RGBA_ARB 0x2076
-#define WGL_NO_TEXTURE_ARB 0x2077
-#define WGL_TEXTURE_CUBE_MAP_ARB 0x2078
-#define WGL_TEXTURE_1D_ARB 0x2079
-#define WGL_TEXTURE_2D_ARB 0x207A
-#define WGL_MIPMAP_LEVEL_ARB 0x207B
-#define WGL_CUBE_MAP_FACE_ARB 0x207C
-#define WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x207D
-#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x207E
-#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x207F
-#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x2080
-#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x2081
-#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x2082
-#define WGL_FRONT_LEFT_ARB 0x2083
-#define WGL_FRONT_RIGHT_ARB 0x2084
-#define WGL_BACK_LEFT_ARB 0x2085
-#define WGL_BACK_RIGHT_ARB 0x2086
-#define WGL_AUX0_ARB 0x2087
-#define WGL_AUX1_ARB 0x2088
-#define WGL_AUX2_ARB 0x2089
-#define WGL_AUX3_ARB 0x208A
-#define WGL_AUX4_ARB 0x208B
-#define WGL_AUX5_ARB 0x208C
-#define WGL_AUX6_ARB 0x208D
-#define WGL_AUX7_ARB 0x208E
-#define WGL_AUX8_ARB 0x208F
-#define WGL_AUX9_ARB 0x2090
-#endif
-
-#ifndef WGL_FLOAT_COMPONENTS_NV
-#define WGL_FLOAT_COMPONENTS_NV 0x20B0
-#endif
-
-#ifndef WGL_ARB_multisample
-#define WGL_SAMPLE_BUFFERS_ARB 0x2041
-#define WGL_SAMPLES_ARB 0x2042
-#endif
-
-#ifndef GL_SAMPLES_ARB
-#define GL_SAMPLES_ARB 0x80A9
-#endif
-
-QGLFormat pfiToQGLFormat(HDC hdc, int pfi);
-
-static void qt_format_to_attrib_list(bool has_render_texture, const QGLFormat &f, int attribs[])
-{
- int i = 0;
- attribs[i++] = WGL_SUPPORT_OPENGL_ARB;
- attribs[i++] = TRUE;
- attribs[i++] = WGL_DRAW_TO_PBUFFER_ARB;
- attribs[i++] = TRUE;
-
- if (has_render_texture) {
- attribs[i++] = WGL_BIND_TO_TEXTURE_RGBA_ARB;
- attribs[i++] = TRUE;
- }
-
- attribs[i++] = WGL_COLOR_BITS_ARB;
- attribs[i++] = 32;
- attribs[i++] = WGL_DOUBLE_BUFFER_ARB;
- attribs[i++] = FALSE;
-
- if (f.stereo()) {
- attribs[i++] = WGL_STEREO_ARB;
- attribs[i++] = TRUE;
- }
- if (f.depth()) {
- attribs[i++] = WGL_DEPTH_BITS_ARB;
- attribs[i++] = f.depthBufferSize() == -1 ? 24 : f.depthBufferSize();
- }
- if (f.redBufferSize() != -1) {
- attribs[i++] = WGL_RED_BITS_ARB;
- attribs[i++] = f.redBufferSize();
- }
- if (f.greenBufferSize() != -1) {
- attribs[i++] = WGL_GREEN_BITS_ARB;
- attribs[i++] = f.greenBufferSize();
- }
- if (f.blueBufferSize() != -1) {
- attribs[i++] = WGL_BLUE_BITS_ARB;
- attribs[i++] = f.blueBufferSize();
- }
- if (f.alpha()) {
- attribs[i++] = WGL_ALPHA_BITS_ARB;
- attribs[i++] = f.alphaBufferSize() == -1 ? 8 : f.alphaBufferSize();
- }
- if (f.accum()) {
- attribs[i++] = WGL_ACCUM_BITS_ARB;
- attribs[i++] = f.accumBufferSize() == -1 ? 16 : f.accumBufferSize();
- }
- if (f.stencil()) {
- attribs[i++] = WGL_STENCIL_BITS_ARB;
- attribs[i++] = f.stencilBufferSize() == -1 ? 8 : f.stencilBufferSize();
- }
- if ((f.redBufferSize() > 8 || f.greenBufferSize() > 8
- || f.blueBufferSize() > 8 || f.alphaBufferSize() > 8)
- && (QGLExtensions::glExtensions() & QGLExtensions::NVFloatBuffer))
- {
- attribs[i++] = WGL_FLOAT_COMPONENTS_NV;
- attribs[i++] = TRUE;
- }
- if (f.sampleBuffers()) {
- attribs[i++] = WGL_SAMPLE_BUFFERS_ARB;
- attribs[i++] = 1;
- attribs[i++] = WGL_SAMPLES_ARB;
- attribs[i++] = f.samples() == -1 ? 16 : f.samples();
- }
- attribs[i] = 0;
-}
-
-bool QGLPixelBufferPrivate::init(const QSize &size, const QGLFormat &f, QGLWidget *shareWidget)
-{
- QGLTemporaryContext tempContext;
-
- PFNWGLCREATEPBUFFERARBPROC wglCreatePbufferARB =
- (PFNWGLCREATEPBUFFERARBPROC) wglGetProcAddress("wglCreatePbufferARB");
- PFNWGLGETPBUFFERDCARBPROC wglGetPbufferDCARB =
- (PFNWGLGETPBUFFERDCARBPROC) wglGetProcAddress("wglGetPbufferDCARB");
- PFNWGLQUERYPBUFFERARBPROC wglQueryPbufferARB =
- (PFNWGLQUERYPBUFFERARBPROC) wglGetProcAddress("wglQueryPbufferARB");
- PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB =
- (PFNWGLCHOOSEPIXELFORMATARBPROC) wglGetProcAddress("wglChoosePixelFormatARB");
-
- if (!wglCreatePbufferARB) // assumes that if one can be resolved, all of them can
- return false;
-
- dc = wglGetCurrentDC();
- Q_ASSERT(dc);
- has_render_texture = false;
-
- // sample buffers doesn't work in conjunction with the render_texture extension
- if (!f.sampleBuffers()) {
- PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB =
- (PFNWGLGETEXTENSIONSSTRINGARBPROC) wglGetProcAddress("wglGetExtensionsStringARB");
-
- if (wglGetExtensionsStringARB) {
- QString extensions(QLatin1String(wglGetExtensionsStringARB(dc)));
- has_render_texture = extensions.contains(QLatin1String("WGL_ARB_render_texture"));
- }
- }
-
- int attribs[40];
- qt_format_to_attrib_list(has_render_texture, f, attribs);
-
- // Find pbuffer capable pixel format.
- unsigned int num_formats = 0;
- int pixel_format;
- wglChoosePixelFormatARB(dc, attribs, 0, 1, &pixel_format, &num_formats);
-
- // some GL implementations don't support pbuffers with accum
- // buffers, so try that before we give up
- if (num_formats == 0 && f.accum()) {
- QGLFormat tmp = f;
- tmp.setAccum(false);
- qt_format_to_attrib_list(has_render_texture, tmp, attribs);
- wglChoosePixelFormatARB(dc, attribs, 0, 1, &pixel_format, &num_formats);
- }
-
- if (num_formats == 0) {
- qWarning("QGLPixelBuffer: Unable to find a pixel format with pbuffer - giving up.");
- return false;
- }
- format = pfiToQGLFormat(dc, pixel_format);
-
- // NB! The below ONLY works if the width/height are powers of 2.
- // Set some pBuffer attributes so that we can use this pBuffer as
- // a 2D RGBA texture target.
- int pb_attribs[] = {WGL_TEXTURE_FORMAT_ARB, WGL_TEXTURE_RGBA_ARB,
- WGL_TEXTURE_TARGET_ARB, WGL_TEXTURE_2D_ARB, 0};
-
- pbuf = wglCreatePbufferARB(dc, pixel_format, size.width(), size.height(),
- has_render_texture ? pb_attribs : 0);
- if (!pbuf) {
- // try again without the render_texture extension
- pbuf = wglCreatePbufferARB(dc, pixel_format, size.width(), size.height(), 0);
- has_render_texture = false;
- if (!pbuf) {
- qWarning("QGLPixelBuffer: Unable to create pbuffer [w=%d, h=%d] - giving up.", size.width(), size.height());
- return false;
- }
- }
-
- dc = wglGetPbufferDCARB(pbuf);
- ctx = wglCreateContext(dc);
- if (!dc || !ctx) {
- qWarning("QGLPixelBuffer: Unable to create pbuffer context - giving up.");
- return false;
- }
-
- // Explicitly disable the render_texture extension if we have a
- // multi-sampled pbuffer context. This seems to be a problem only with
- // ATI cards if multi-sampling is forced globally in the driver.
- wglMakeCurrent(dc, ctx);
- GLint samples = 0;
- glGetIntegerv(GL_SAMPLES_ARB, &samples);
- if (has_render_texture && samples != 0)
- has_render_texture = false;
-
- HGLRC share_ctx = shareWidget ? shareWidget->d_func()->glcx->d_func()->rc : 0;
- if (share_ctx && !wglShareLists(share_ctx, ctx))
- qWarning("QGLPixelBuffer: Unable to share display lists - with share widget.");
-
- int width, height;
- wglQueryPbufferARB(pbuf, WGL_PBUFFER_WIDTH_ARB, &width);
- wglQueryPbufferARB(pbuf, WGL_PBUFFER_HEIGHT_ARB, &height);
- return true;
-}
-
-bool QGLPixelBufferPrivate::cleanup()
-{
- PFNWGLRELEASEPBUFFERDCARBPROC wglReleasePbufferDCARB =
- (PFNWGLRELEASEPBUFFERDCARBPROC) wglGetProcAddress("wglReleasePbufferDCARB");
- PFNWGLDESTROYPBUFFERARBPROC wglDestroyPbufferARB =
- (PFNWGLDESTROYPBUFFERARBPROC) wglGetProcAddress("wglDestroyPbufferARB");
- if (!invalid && wglReleasePbufferDCARB && wglDestroyPbufferARB) {
- wglReleasePbufferDCARB(pbuf, dc);
- wglDestroyPbufferARB(pbuf);
- }
- return true;
-}
-
-bool QGLPixelBuffer::bindToDynamicTexture(GLuint texture_id)
-{
- Q_D(QGLPixelBuffer);
- if (d->invalid || !d->has_render_texture)
- return false;
- PFNWGLBINDTEXIMAGEARBPROC wglBindTexImageARB =
- (PFNWGLBINDTEXIMAGEARBPROC) wglGetProcAddress("wglBindTexImageARB");
- if (wglBindTexImageARB) {
- glBindTexture(GL_TEXTURE_2D, texture_id);
- return wglBindTexImageARB(d->pbuf, WGL_FRONT_LEFT_ARB);
- }
- return false;
-}
-
-void QGLPixelBuffer::releaseFromDynamicTexture()
-{
- Q_D(QGLPixelBuffer);
- if (d->invalid || !d->has_render_texture)
- return;
- PFNWGLRELEASETEXIMAGEARBPROC wglReleaseTexImageARB =
- (PFNWGLRELEASETEXIMAGEARBPROC) wglGetProcAddress("wglReleaseTexImageARB");
- if (wglReleaseTexImageARB)
- wglReleaseTexImageARB(d->pbuf, WGL_FRONT_LEFT_ARB);
-}
-
-bool QGLPixelBuffer::hasOpenGLPbuffers()
-{
- bool ret = false;
- QGLTemporaryContext *tmpContext = 0;
- if (!QGLContext::currentContext())
- tmpContext = new QGLTemporaryContext;
- PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB =
- (PFNWGLGETEXTENSIONSSTRINGARBPROC) wglGetProcAddress("wglGetExtensionsStringARB");
- if (wglGetExtensionsStringARB) {
- QString extensions(QLatin1String(wglGetExtensionsStringARB(wglGetCurrentDC())));
- if (extensions.contains(QLatin1String("WGL_ARB_pbuffer"))
- && extensions.contains(QLatin1String("WGL_ARB_pixel_format"))) {
- ret = true;
- }
- }
- if (tmpContext)
- delete tmpContext;
- return ret;
-}
-
-QT_END_NAMESPACE
diff --git a/src/opengl/qglpixelbuffer_x11.cpp b/src/opengl/qglpixelbuffer_x11.cpp
deleted file mode 100644
index fcd7b521bb..0000000000
--- a/src/opengl/qglpixelbuffer_x11.cpp
+++ /dev/null
@@ -1,290 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#include <qlibrary.h>
-#include <qdebug.h>
-#include <private/qgl_p.h>
-#include <private/qt_x11_p.h>
-#include <private/qpaintengine_opengl_p.h>
-
-#include <qx11info_x11.h>
-#include <GL/glx.h>
-#include <qimage.h>
-
-#include "qglpixelbuffer.h"
-#include "qglpixelbuffer_p.h"
-
-#if defined(Q_OS_LINUX) || defined(Q_OS_BSD4)
-#include <dlfcn.h>
-#endif
-
-QT_BEGIN_NAMESPACE
-
-#ifndef GLX_VERSION_1_3
-#define GLX_RGBA_BIT 0x00000002
-#define GLX_PBUFFER_BIT 0x00000004
-#define GLX_DRAWABLE_TYPE 0x8010
-#define GLX_RENDER_TYPE 0x8011
-#define GLX_RGBA_TYPE 0x8014
-#define GLX_PBUFFER_HEIGHT 0x8040
-#define GLX_PBUFFER_WIDTH 0x8041
-#endif
-
-#ifndef GLX_ARB_multisample
-#define GLX_SAMPLE_BUFFERS_ARB 100000
-#define GLX_SAMPLES_ARB 100001
-#endif
-
-typedef GLXFBConfig* (*_glXChooseFBConfig) (Display *dpy, int screen, const int *attrib_list, int *nelements);
-typedef int (*_glXGetFBConfigAttrib) (Display *dpy, GLXFBConfig config, int attribute, int *value);
-typedef GLXPbuffer (*_glXCreatePbuffer) (Display *dpy, GLXFBConfig config, const int *attrib_list);
-typedef void (*_glXDestroyPbuffer) (Display *dpy, GLXPbuffer pbuf);
-typedef GLXContext (*_glXCreateNewContext) (Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct);
-typedef Bool (*_glXMakeContextCurrent) (Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx);
-
-static _glXChooseFBConfig qt_glXChooseFBConfig = 0;
-static _glXCreateNewContext qt_glXCreateNewContext = 0;
-static _glXCreatePbuffer qt_glXCreatePbuffer = 0;
-static _glXDestroyPbuffer qt_glXDestroyPbuffer = 0;
-static _glXGetFBConfigAttrib qt_glXGetFBConfigAttrib = 0;
-static _glXMakeContextCurrent qt_glXMakeContextCurrent = 0;
-
-#define glXChooseFBConfig qt_glXChooseFBConfig
-#define glXCreateNewContext qt_glXCreateNewContext
-#define glXCreatePbuffer qt_glXCreatePbuffer
-#define glXDestroyPbuffer qt_glXDestroyPbuffer
-#define glXGetFBConfigAttrib qt_glXGetFBConfigAttrib
-#define glXMakeContextCurrent qt_glXMakeContextCurrent
-
-extern void (*qglx_getProcAddress(const char* procName))(); // in qgl_x11.cpp
-
-static bool qt_resolve_pbuffer_extensions()
-{
- static int resolved = false;
- if (resolved && qt_glXMakeContextCurrent)
- return true;
- else if (resolved)
- return false;
-
- qt_glXChooseFBConfig = (_glXChooseFBConfig) qglx_getProcAddress("glXChooseFBConfig");
- qt_glXCreateNewContext = (_glXCreateNewContext) qglx_getProcAddress("glXCreateNewContext");
- qt_glXCreatePbuffer = (_glXCreatePbuffer) qglx_getProcAddress("glXCreatePbuffer");
- qt_glXDestroyPbuffer = (_glXDestroyPbuffer) qglx_getProcAddress("glXDestroyPbuffer");
- qt_glXGetFBConfigAttrib = (_glXGetFBConfigAttrib) qglx_getProcAddress("glXGetFBConfigAttrib");
- qt_glXMakeContextCurrent = (_glXMakeContextCurrent) qglx_getProcAddress("glXMakeContextCurrent");
-
- resolved = qt_glXMakeContextCurrent ? true : false;
- return resolved;
-}
-
-static void qt_format_to_attrib_list(const QGLFormat &f, int attribs[])
-{
- int i = 0;
- attribs[i++] = GLX_RENDER_TYPE;
- attribs[i++] = GLX_RGBA_BIT;
- attribs[i++] = GLX_DRAWABLE_TYPE;
- attribs[i++] = GLX_PBUFFER_BIT;
- attribs[i++] = GLX_RED_SIZE;
- attribs[i++] = f.redBufferSize() == -1 ? 1 : f.redBufferSize();
- attribs[i++] = GLX_GREEN_SIZE;
- attribs[i++] = f.greenBufferSize() == -1 ? 1 : f.greenBufferSize();
- attribs[i++] = GLX_BLUE_SIZE;
- attribs[i++] = f.blueBufferSize() == -1 ? 1 : f.blueBufferSize();
- if (f.doubleBuffer()) {
- attribs[i++] = GLX_DOUBLEBUFFER;
- attribs[i++] = true;
- }
- if (f.depth()) {
- attribs[i++] = GLX_DEPTH_SIZE;
- attribs[i++] = f.depthBufferSize() == -1 ? 1 : f.depthBufferSize();
- }
- if (f.stereo()) {
- attribs[i++] = GLX_STEREO;
- attribs[i++] = true;
- }
- if (f.stencil()) {
- attribs[i++] = GLX_STENCIL_SIZE;
- attribs[i++] = f.stencilBufferSize() == -1 ? 1 : f.stencilBufferSize();
- }
- if (f.alpha()) {
- attribs[i++] = GLX_ALPHA_SIZE;
- attribs[i++] = f.alphaBufferSize() == -1 ? 1 : f.alphaBufferSize();
- }
- if (f.accum()) {
- attribs[i++] = GLX_ACCUM_RED_SIZE;
- attribs[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize();
- attribs[i++] = GLX_ACCUM_GREEN_SIZE;
- attribs[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize();
- attribs[i++] = GLX_ACCUM_BLUE_SIZE;
- attribs[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize();
- if (f.alpha()) {
- attribs[i++] = GLX_ACCUM_ALPHA_SIZE;
- attribs[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize();
- }
- }
- if (f.sampleBuffers()) {
- attribs[i++] = GLX_SAMPLE_BUFFERS_ARB;
- attribs[i++] = 1;
- attribs[i++] = GLX_SAMPLES_ARB;
- attribs[i++] = f.samples() == -1 ? 4 : f.samples();
- }
-
- attribs[i] = XNone;
-}
-
-bool QGLPixelBufferPrivate::init(const QSize &size, const QGLFormat &f, QGLWidget *shareWidget)
-{
- if (!qt_resolve_pbuffer_extensions()) {
- qWarning("QGLPixelBuffer: pbuffers are not supported on this system.");
- return false;
- }
-
- int attribs[40];
- int num_configs = 0;
-
- qt_format_to_attrib_list(f, attribs);
-
- int screen = X11->defaultScreen;
- if (shareWidget)
- screen = shareWidget->x11Info().screen();
-
- GLXFBConfig *configs = glXChooseFBConfig(X11->display, screen, attribs, &num_configs);
- if (configs && num_configs) {
- int res;
- glXGetFBConfigAttrib(X11->display, configs[0], GLX_LEVEL, &res);
- format.setPlane(res);
- glXGetFBConfigAttrib(X11->display, configs[0], GLX_DOUBLEBUFFER, &res);
- format.setDoubleBuffer(res);
- glXGetFBConfigAttrib(X11->display, configs[0], GLX_DEPTH_SIZE, &res);
- format.setDepth(res);
- if (format.depth())
- format.setDepthBufferSize(res);
- glXGetFBConfigAttrib(X11->display, configs[0], GLX_RGBA, &res);
- format.setRgba(res);
- glXGetFBConfigAttrib(X11->display, configs[0], GLX_RED_SIZE, &res);
- format.setRedBufferSize(res);
- glXGetFBConfigAttrib(X11->display, configs[0], GLX_GREEN_SIZE, &res);
- format.setGreenBufferSize(res);
- glXGetFBConfigAttrib(X11->display, configs[0], GLX_BLUE_SIZE, &res);
- format.setBlueBufferSize(res);
- glXGetFBConfigAttrib(X11->display, configs[0], GLX_ALPHA_SIZE, &res);
- format.setAlpha(res);
- if (format.alpha())
- format.setAlphaBufferSize(res);
- glXGetFBConfigAttrib(X11->display, configs[0], GLX_ACCUM_RED_SIZE, &res);
- format.setAccum(res);
- if (format.accum())
- format.setAccumBufferSize(res);
- glXGetFBConfigAttrib(X11->display, configs[0], GLX_STENCIL_SIZE, &res);
- format.setStencil(res);
- if (format.stencil())
- format.setStencilBufferSize(res);
- glXGetFBConfigAttrib(X11->display, configs[0], GLX_STEREO, &res);
- format.setStereo(res);
- glXGetFBConfigAttrib(X11->display, configs[0], GLX_SAMPLE_BUFFERS_ARB, &res);
- format.setSampleBuffers(res);
- if (format.sampleBuffers()) {
- glXGetFBConfigAttrib(X11->display, configs[0], GLX_SAMPLES_ARB, &res);
- format.setSamples(res);
- }
-
- int pb_attribs[] = {GLX_PBUFFER_WIDTH, size.width(), GLX_PBUFFER_HEIGHT, size.height(), XNone};
- GLXContext shareContext = 0;
- if (shareWidget && shareWidget->d_func()->glcx)
- shareContext = (GLXContext) shareWidget->d_func()->glcx->d_func()->cx;
-
- pbuf = glXCreatePbuffer(QX11Info::display(), configs[0], pb_attribs);
- ctx = glXCreateNewContext(QX11Info::display(), configs[0], GLX_RGBA_TYPE, shareContext, true);
-
- XFree(configs);
- if (!pbuf || !ctx) {
- qWarning("QGLPixelBuffer: Unable to create a pbuffer/context - giving up.");
- return false;
- }
- return true;
- } else {
- qWarning("QGLPixelBuffer: Unable to find a context/format match - giving up.");
- return false;
- }
-}
-
-bool QGLPixelBufferPrivate::cleanup()
-{
- glXDestroyPbuffer(QX11Info::display(), pbuf);
- return true;
-}
-
-bool QGLPixelBuffer::bindToDynamicTexture(GLuint)
-{
- return false;
-}
-
-void QGLPixelBuffer::releaseFromDynamicTexture()
-{
-}
-
-bool QGLPixelBuffer::hasOpenGLPbuffers()
-{
- bool ret = qt_resolve_pbuffer_extensions();
-
- if (!ret)
- return false;
-
- int attribs[40];
- int num_configs = 0;
-
- qt_format_to_attrib_list(QGLFormat::defaultFormat(), attribs);
-
- GLXFBConfig *configs = glXChooseFBConfig(X11->display, X11->defaultScreen, attribs, &num_configs);
- GLXPbuffer pbuf = 0;
- GLXContext ctx = 0;
-
- if (configs && num_configs) {
- int pb_attribs[] = {GLX_PBUFFER_WIDTH, 128, GLX_PBUFFER_HEIGHT, 128, XNone};
- pbuf = glXCreatePbuffer(X11->display, configs[0], pb_attribs);
- ctx = glXCreateNewContext(X11->display, configs[0], GLX_RGBA_TYPE, 0, true);
- XFree(configs);
- glXDestroyContext(X11->display, ctx);
- glXDestroyPbuffer(X11->display, pbuf);
- }
- return pbuf && ctx;
-}
-
-QT_END_NAMESPACE
diff --git a/src/opengl/qglpixmapfilter.cpp b/src/opengl/qglpixmapfilter.cpp
deleted file mode 100644
index 7546d84064..0000000000
--- a/src/opengl/qglpixmapfilter.cpp
+++ /dev/null
@@ -1,621 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "private/qpixmapfilter_p.h"
-#include "private/qpixmapdata_gl_p.h"
-#include "private/qpaintengineex_opengl2_p.h"
-#include "private/qglengineshadermanager_p.h"
-#include "private/qpixmapdata_p.h"
-#include "private/qimagepixmapcleanuphooks_p.h"
-#include "qglpixmapfilter_p.h"
-#include "qgraphicssystem_gl_p.h"
-#include "qpaintengine_opengl_p.h"
-#include "qcache.h"
-
-#include "qglframebufferobject.h"
-#include "qglshaderprogram.h"
-#include "qgl_p.h"
-
-#include "private/qapplication_p.h"
-#include "private/qdrawhelper_p.h"
-#include "private/qmemrotate_p.h"
-#include "private/qmath_p.h"
-#include "qmath.h"
-
-QT_BEGIN_NAMESPACE
-
-// qpixmapfilter.cpp
-Q_GUI_EXPORT void qt_blurImage(QImage &blurImage, qreal radius, bool quality, int transposed = 0);
-Q_GUI_EXPORT QImage qt_halfScaled(const QImage &source);
-
-void QGLPixmapFilterBase::bindTexture(const QPixmap &src) const
-{
- const_cast<QGLContext *>(QGLContext::currentContext())->d_func()->bindTexture(src, GL_TEXTURE_2D, GL_RGBA, QGLContext::BindOptions(QGLContext::DefaultBindOption | QGLContext::MemoryManagedBindOption));
-}
-
-void QGLPixmapFilterBase::drawImpl(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF& source) const
-{
- processGL(painter, pos, src, source);
-}
-
-class QGLPixmapColorizeFilter: public QGLCustomShaderStage, public QGLPixmapFilter<QPixmapColorizeFilter>
-{
-public:
- QGLPixmapColorizeFilter();
-
- void setUniforms(QGLShaderProgram *program);
-
-protected:
- bool processGL(QPainter *painter, const QPointF &pos, const QPixmap &pixmap, const QRectF &srcRect) const;
-};
-
-class QGLPixmapConvolutionFilter: public QGLCustomShaderStage, public QGLPixmapFilter<QPixmapConvolutionFilter>
-{
-public:
- QGLPixmapConvolutionFilter();
- ~QGLPixmapConvolutionFilter();
-
- void setUniforms(QGLShaderProgram *program);
-
-protected:
- bool processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &srcRect) const;
-
-private:
- QByteArray generateConvolutionShader() const;
-
- mutable QSize m_srcSize;
- mutable int m_prevKernelSize;
-};
-
-class QGLPixmapBlurFilter : public QGLCustomShaderStage, public QGLPixmapFilter<QPixmapBlurFilter>
-{
-public:
- QGLPixmapBlurFilter();
-
-protected:
- bool processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &srcRect) const;
-};
-
-class QGLPixmapDropShadowFilter : public QGLCustomShaderStage, public QGLPixmapFilter<QPixmapDropShadowFilter>
-{
-public:
- QGLPixmapDropShadowFilter();
-
- void setUniforms(QGLShaderProgram *program);
-
-protected:
- bool processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &srcRect) const;
-};
-
-extern const QGLContext *qt_gl_share_context();
-
-QPixmapFilter *QGL2PaintEngineEx::pixmapFilter(int type, const QPixmapFilter *prototype)
-{
- Q_D(QGL2PaintEngineEx);
- switch (type) {
- case QPixmapFilter::ColorizeFilter:
- if (!d->colorizeFilter)
- d->colorizeFilter.reset(new QGLPixmapColorizeFilter);
- return d->colorizeFilter.data();
-
- case QPixmapFilter::BlurFilter: {
- if (!d->blurFilter)
- d->blurFilter.reset(new QGLPixmapBlurFilter());
- return d->blurFilter.data();
- }
-
- case QPixmapFilter::DropShadowFilter: {
- if (!d->dropShadowFilter)
- d->dropShadowFilter.reset(new QGLPixmapDropShadowFilter());
- return d->dropShadowFilter.data();
- }
-
- case QPixmapFilter::ConvolutionFilter:
- if (!d->convolutionFilter)
- d->convolutionFilter.reset(new QGLPixmapConvolutionFilter);
- return d->convolutionFilter.data();
-
- default: break;
- }
- return QPaintEngineEx::pixmapFilter(type, prototype);
-}
-
-static const char *qt_gl_colorize_filter =
- "uniform lowp vec4 colorizeColor;"
- "uniform lowp float colorizeStrength;"
- "lowp vec4 customShader(lowp sampler2D src, highp vec2 srcCoords)"
- "{"
- " lowp vec4 srcPixel = texture2D(src, srcCoords);"
- " lowp float gray = dot(srcPixel.rgb, vec3(0.212671, 0.715160, 0.072169));"
- " lowp vec3 colorized = 1.0-((1.0-gray)*(1.0-colorizeColor.rgb));"
- " return vec4(mix(srcPixel.rgb, colorized * srcPixel.a, colorizeStrength), srcPixel.a);"
- "}";
-
-QGLPixmapColorizeFilter::QGLPixmapColorizeFilter()
-{
- setSource(qt_gl_colorize_filter);
-}
-
-bool QGLPixmapColorizeFilter::processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &) const
-{
- QGLPixmapColorizeFilter *filter = const_cast<QGLPixmapColorizeFilter *>(this);
-
- filter->setOnPainter(painter);
- painter->drawPixmap(pos, src);
- filter->removeFromPainter(painter);
-
- return true;
-}
-
-void QGLPixmapColorizeFilter::setUniforms(QGLShaderProgram *program)
-{
- program->setUniformValue("colorizeColor", color());
- program->setUniformValue("colorizeStrength", float(strength()));
-}
-
-void QGLPixmapConvolutionFilter::setUniforms(QGLShaderProgram *program)
-{
- const qreal *kernel = convolutionKernel();
- int kernelWidth = columns();
- int kernelHeight = rows();
- int kernelSize = kernelWidth * kernelHeight;
-
- QVarLengthArray<GLfloat> matrix(kernelSize);
- QVarLengthArray<GLfloat> offset(kernelSize * 2);
-
- for(int i = 0; i < kernelSize; ++i)
- matrix[i] = kernel[i];
-
- for(int y = 0; y < kernelHeight; ++y) {
- for(int x = 0; x < kernelWidth; ++x) {
- offset[(y * kernelWidth + x) * 2] = x - (kernelWidth / 2);
- offset[(y * kernelWidth + x) * 2 + 1] = (kernelHeight / 2) - y;
- }
- }
-
- const qreal iw = 1.0 / m_srcSize.width();
- const qreal ih = 1.0 / m_srcSize.height();
- program->setUniformValue("inv_texture_size", iw, ih);
- program->setUniformValueArray("matrix", matrix.constData(), kernelSize, 1);
- program->setUniformValueArray("offset", offset.constData(), kernelSize, 2);
-}
-
-// generates convolution filter code for arbitrary sized kernel
-QByteArray QGLPixmapConvolutionFilter::generateConvolutionShader() const {
- QByteArray code;
- int kernelWidth = columns();
- int kernelHeight = rows();
- int kernelSize = kernelWidth * kernelHeight;
- code.append("uniform highp vec2 inv_texture_size;\n"
- "uniform mediump float matrix[");
- code.append(QByteArray::number(kernelSize));
- code.append("];\n"
- "uniform highp vec2 offset[");
- code.append(QByteArray::number(kernelSize));
- code.append("];\n");
- code.append("lowp vec4 customShader(lowp sampler2D src, highp vec2 srcCoords) {\n");
-
- code.append(" int i = 0;\n"
- " lowp vec4 sum = vec4(0.0);\n"
- " for (i = 0; i < ");
- code.append(QByteArray::number(kernelSize));
- code.append("; i++) {\n"
- " sum += matrix[i] * texture2D(src,srcCoords+inv_texture_size*offset[i]);\n"
- " }\n"
- " return sum;\n"
- "}");
- return code;
-}
-
-QGLPixmapConvolutionFilter::QGLPixmapConvolutionFilter()
- : m_prevKernelSize(-1)
-{
-}
-
-QGLPixmapConvolutionFilter::~QGLPixmapConvolutionFilter()
-{
-}
-
-bool QGLPixmapConvolutionFilter::processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &srcRect) const
-{
- QGLPixmapConvolutionFilter *filter = const_cast<QGLPixmapConvolutionFilter *>(this);
-
- m_srcSize = src.size();
-
- int kernelSize = rows() * columns();
- if (m_prevKernelSize == -1 || m_prevKernelSize != kernelSize) {
- filter->setSource(generateConvolutionShader());
- m_prevKernelSize = kernelSize;
- }
-
- filter->setOnPainter(painter);
- painter->drawPixmap(pos, src, srcRect);
- filter->removeFromPainter(painter);
-
- return true;
-}
-
-QGLPixmapBlurFilter::QGLPixmapBlurFilter()
-{
-}
-
-class QGLBlurTextureInfo
-{
-public:
- QGLBlurTextureInfo(const QImage &image, GLuint tex, qreal r)
- : m_texture(tex)
- , m_radius(r)
- {
- m_paddedImage << image;
- }
-
- ~QGLBlurTextureInfo()
- {
- glDeleteTextures(1, &m_texture);
- }
-
- QImage paddedImage(int scaleLevel = 0) const;
- GLuint texture() const { return m_texture; }
- qreal radius() const { return m_radius; }
-
-private:
- mutable QList<QImage> m_paddedImage;
- GLuint m_texture;
- qreal m_radius;
-};
-
-QImage QGLBlurTextureInfo::paddedImage(int scaleLevel) const
-{
- for (int i = m_paddedImage.size() - 1; i <= scaleLevel; ++i)
- m_paddedImage << qt_halfScaled(m_paddedImage.at(i));
-
- return m_paddedImage.at(scaleLevel);
-}
-
-class QGLBlurTextureCache : public QObject
-{
-public:
- static QGLBlurTextureCache *cacheForContext(const QGLContext *context);
-
- QGLBlurTextureCache(const QGLContext *);
- ~QGLBlurTextureCache();
-
- QGLBlurTextureInfo *takeBlurTextureInfo(const QPixmap &pixmap);
- bool hasBlurTextureInfo(quint64 cacheKey) const;
- void insertBlurTextureInfo(const QPixmap &pixmap, QGLBlurTextureInfo *info);
- void clearBlurTextureInfo(quint64 cacheKey);
-
- void timerEvent(QTimerEvent *event);
-
-private:
- static void pixmapDestroyed(QPixmapData *pixmap);
-
- QCache<quint64, QGLBlurTextureInfo > cache;
-
- static QList<QGLBlurTextureCache *> blurTextureCaches;
-
- int timerId;
-};
-
-QList<QGLBlurTextureCache *> QGLBlurTextureCache::blurTextureCaches;
-Q_GLOBAL_STATIC(QGLContextGroupResource<QGLBlurTextureCache>, qt_blur_texture_caches)
-
-QGLBlurTextureCache::QGLBlurTextureCache(const QGLContext *)
- : timerId(0)
-{
- cache.setMaxCost(4 * 1024 * 1024);
- blurTextureCaches.append(this);
-}
-
-QGLBlurTextureCache::~QGLBlurTextureCache()
-{
- blurTextureCaches.removeAt(blurTextureCaches.indexOf(this));
-}
-
-void QGLBlurTextureCache::timerEvent(QTimerEvent *)
-{
- killTimer(timerId);
- timerId = 0;
-
- cache.clear();
-}
-
-QGLBlurTextureCache *QGLBlurTextureCache::cacheForContext(const QGLContext *context)
-{
- return qt_blur_texture_caches()->value(context);
-}
-
-QGLBlurTextureInfo *QGLBlurTextureCache::takeBlurTextureInfo(const QPixmap &pixmap)
-{
- return cache.take(pixmap.cacheKey());
-}
-
-void QGLBlurTextureCache::clearBlurTextureInfo(quint64 cacheKey)
-{
- cache.remove(cacheKey);
-}
-
-bool QGLBlurTextureCache::hasBlurTextureInfo(quint64 cacheKey) const
-{
- return cache.contains(cacheKey);
-}
-
-void QGLBlurTextureCache::insertBlurTextureInfo(const QPixmap &pixmap, QGLBlurTextureInfo *info)
-{
- static bool hookAdded = false;
- if (!hookAdded) {
- QImagePixmapCleanupHooks::instance()->addPixmapDataDestructionHook(pixmapDestroyed);
- QImagePixmapCleanupHooks::instance()->addPixmapDataModificationHook(pixmapDestroyed);
- hookAdded = true;
- }
-
- QImagePixmapCleanupHooks::enableCleanupHooks(pixmap);
- cache.insert(pixmap.cacheKey(), info, pixmap.width() * pixmap.height());
-
- if (timerId)
- killTimer(timerId);
-
- timerId = startTimer(8000);
-}
-
-void QGLBlurTextureCache::pixmapDestroyed(QPixmapData *pmd)
-{
- foreach (QGLBlurTextureCache *cache, blurTextureCaches) {
- if (cache->hasBlurTextureInfo(pmd->cacheKey()))
- cache->clearBlurTextureInfo(pmd->cacheKey());
- }
-}
-
-static const int qAnimatedBlurLevelIncrement = 16;
-static const int qMaxBlurHalfScaleLevel = 1;
-
-static GLuint generateBlurTexture(const QSize &size, GLenum format = GL_RGBA)
-{
- GLuint texture;
- glGenTextures(1, &texture);
- glBindTexture(GL_TEXTURE_2D, texture);
- glTexImage2D(GL_TEXTURE_2D, 0, format, size.width(), size.height(), 0, format,
- GL_UNSIGNED_BYTE, 0);
- return texture;
-}
-
-static inline uint nextMultiple(uint x, uint multiplier)
-{
- uint mod = x % multiplier;
- if (mod == 0)
- return x;
- return x + multiplier - mod;
-}
-
-Q_GUI_EXPORT void qt_memrotate90_gl(const quint32 *src, int srcWidth, int srcHeight, int srcStride,
- quint32 *dest, int dstStride);
-
-bool QGLPixmapBlurFilter::processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &) const
-{
- if (radius() < 1) {
- painter->drawPixmap(pos, src);
- return true;
- }
-
- qreal actualRadius = radius();
-
- QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext());
-
- QGLBlurTextureCache *blurTextureCache = QGLBlurTextureCache::cacheForContext(ctx);
- QGLBlurTextureInfo *info = 0;
- int padding = nextMultiple(qCeil(actualRadius), qAnimatedBlurLevelIncrement);
- QRect targetRect = src.rect().adjusted(-padding, -padding, padding, padding);
-
- // pad so that we'll be able to half-scale qMaxBlurHalfScaleLevel times
- targetRect.setWidth((targetRect.width() + (qMaxBlurHalfScaleLevel-1)) & ~(qMaxBlurHalfScaleLevel-1));
- targetRect.setHeight((targetRect.height() + (qMaxBlurHalfScaleLevel-1)) & ~(qMaxBlurHalfScaleLevel-1));
-
- QSize textureSize;
-
- info = blurTextureCache->takeBlurTextureInfo(src);
- if (!info || info->radius() < actualRadius) {
- QSize paddedSize = targetRect.size() / 2;
-
- QImage padded(paddedSize.height(), paddedSize.width(), QImage::Format_ARGB32_Premultiplied);
- padded.fill(0);
-
- if (info) {
- int oldPadding = qRound(info->radius());
-
- QPainter p(&padded);
- p.setCompositionMode(QPainter::CompositionMode_Source);
- p.drawImage((padding - oldPadding) / 2, (padding - oldPadding) / 2, info->paddedImage());
- p.end();
- } else {
- // TODO: combine byteswapping and memrotating into one by declaring
- // custom GL_RGBA pixel type and qt_colorConvert template for it
- QImage prepadded = qt_halfScaled(src.toImage()).convertToFormat(QImage::Format_ARGB32_Premultiplied);
-
- // byte-swap and memrotates in one go
- qt_memrotate90_gl(reinterpret_cast<const quint32*>(prepadded.bits()),
- prepadded.width(), prepadded.height(), prepadded.bytesPerLine(),
- reinterpret_cast<quint32*>(padded.scanLine(padding / 2)) + padding / 2,
- padded.bytesPerLine());
- }
-
- delete info;
- info = new QGLBlurTextureInfo(padded, generateBlurTexture(paddedSize), padding);
-
- textureSize = paddedSize;
- } else {
- textureSize = QSize(info->paddedImage().height(), info->paddedImage().width());
- }
-
- actualRadius *= qreal(0.5);
- int level = 1;
- for (; level < qMaxBlurHalfScaleLevel; ++level) {
- if (actualRadius <= 16)
- break;
- actualRadius *= qreal(0.5);
- }
-
- const int s = (1 << level);
-
- int prepadding = qRound(info->radius());
- padding = qMin(prepadding, qCeil(actualRadius) << level);
- targetRect = src.rect().adjusted(-padding, -padding, padding, padding);
-
- targetRect.setWidth(targetRect.width() & ~(s-1));
- targetRect.setHeight(targetRect.height() & ~(s-1));
-
- int paddingDelta = (prepadding - padding) >> level;
-
- QRect subRect(paddingDelta, paddingDelta, targetRect.width() >> level, targetRect.height() >> level);
- QImage sourceImage = info->paddedImage(level-1);
-
- QImage subImage(subRect.height(), subRect.width(), QImage::Format_ARGB32_Premultiplied);
- qt_rectcopy((QRgb *)subImage.bits(), ((QRgb *)sourceImage.scanLine(paddingDelta)) + paddingDelta,
- 0, 0, subRect.height(), subRect.width(), subImage.bytesPerLine(), sourceImage.bytesPerLine());
-
- GLuint texture = info->texture();
-
- qt_blurImage(subImage, actualRadius, blurHints() & QGraphicsBlurEffect::QualityHint, 1);
-
- // subtract one pixel off the end to prevent the bilinear sampling from sampling uninitialized data
- QRect textureSubRect = subImage.rect().adjusted(0, 0, -1, -1);
- QRectF targetRectF = QRectF(targetRect).adjusted(0, 0, -targetRect.width() / qreal(textureSize.width()), -targetRect.height() / qreal(textureSize.height()));
-
- glBindTexture(GL_TEXTURE_2D, texture);
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, subImage.width(), subImage.height(), GL_RGBA,
- GL_UNSIGNED_BYTE, const_cast<const QImage &>(subImage).bits());
-
- QGL2PaintEngineEx *engine = static_cast<QGL2PaintEngineEx *>(painter->paintEngine());
- painter->setRenderHint(QPainter::SmoothPixmapTransform);
-
- // texture is flipped on the y-axis
- targetRectF = QRectF(targetRectF.x(), targetRectF.bottom(), targetRectF.width(), -targetRectF.height());
- engine->drawTexture(targetRectF.translated(pos), texture, textureSize, textureSubRect);
-
- blurTextureCache->insertBlurTextureInfo(src, info);
-
- return true;
-}
-
-static const char *qt_gl_drop_shadow_filter =
- "uniform lowp vec4 shadowColor;"
- "lowp vec4 customShader(lowp sampler2D src, highp vec2 srcCoords)"
- "{"
- " return shadowColor * texture2D(src, srcCoords.yx).a;"
- "}";
-
-
-QGLPixmapDropShadowFilter::QGLPixmapDropShadowFilter()
-{
- setSource(qt_gl_drop_shadow_filter);
-}
-
-bool QGLPixmapDropShadowFilter::processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &srcRect) const
-{
- QGLPixmapDropShadowFilter *filter = const_cast<QGLPixmapDropShadowFilter *>(this);
-
- qreal r = blurRadius();
- QRectF targetRectUnaligned = QRectF(src.rect()).translated(pos + offset()).adjusted(-r, -r, r, r);
- QRect targetRect = targetRectUnaligned.toAlignedRect();
-
- // ensure even dimensions (going to divide by two)
- targetRect.setWidth((targetRect.width() + 1) & ~1);
- targetRect.setHeight((targetRect.height() + 1) & ~1);
-
- QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext());
- QGLBlurTextureCache *blurTextureCache = QGLBlurTextureCache::cacheForContext(ctx);
-
- QGLBlurTextureInfo *info = blurTextureCache->takeBlurTextureInfo(src);
- if (!info || info->radius() != r) {
- QImage half = qt_halfScaled(src.toImage().alphaChannel());
-
- qreal rx = r + targetRect.left() - targetRectUnaligned.left();
- qreal ry = r + targetRect.top() - targetRectUnaligned.top();
-
- QImage image = QImage(targetRect.size() / 2, QImage::Format_Indexed8);
- image.setColorTable(half.colorTable());
- image.fill(0);
- int dx = qRound(rx * qreal(0.5));
- int dy = qRound(ry * qreal(0.5));
- qt_rectcopy(image.bits(), half.bits(), dx, dy,
- half.width(), half.height(),
- image.bytesPerLine(), half.bytesPerLine());
-
- qt_blurImage(image, r * qreal(0.5), false, 1);
-
- GLuint texture;
- glGenTextures(1, &texture);
- glBindTexture(GL_TEXTURE_2D, texture);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, image.width(), image.height(),
- 0, GL_ALPHA, GL_UNSIGNED_BYTE, image.bits());
-
- info = new QGLBlurTextureInfo(image, texture, r);
- }
-
- GLuint texture = info->texture();
-
- filter->setOnPainter(painter);
-
- QGL2PaintEngineEx *engine = static_cast<QGL2PaintEngineEx *>(painter->paintEngine());
- painter->setRenderHint(QPainter::SmoothPixmapTransform);
-
- engine->drawTexture(targetRect, texture, info->paddedImage().size(), info->paddedImage().rect());
-
- filter->removeFromPainter(painter);
-
- // Now draw the actual pixmap over the top.
- painter->drawPixmap(pos, src, srcRect);
-
- blurTextureCache->insertBlurTextureInfo(src, info);
-
- return true;
-}
-
-void QGLPixmapDropShadowFilter::setUniforms(QGLShaderProgram *program)
-{
- QColor col = color();
- qreal alpha = col.alphaF();
- program->setUniformValue("shadowColor", col.redF() * alpha,
- col.greenF() * alpha,
- col.blueF() * alpha,
- alpha);
-}
-
-QT_END_NAMESPACE
diff --git a/src/opengl/qglpixmapfilter_p.h b/src/opengl/qglpixmapfilter_p.h
deleted file mode 100644
index 1aa234a25b..0000000000
--- a/src/opengl/qglpixmapfilter_p.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGLPIXMAPFILTER_P_H
-#define QGLPIXMAPFILTER_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <private/qpixmapfilter_p.h>
-
-#include <QtOpenGL/qgl.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-class QGLPixelBuffer;
-
-QT_MODULE(OpenGL)
-
-class QGLPixmapFilterBase
-{
-public:
- virtual ~QGLPixmapFilterBase() {}
-protected:
- void bindTexture(const QPixmap &src) const;
- void drawImpl(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &srcRect = QRectF()) const;
-
- virtual bool processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &srcRect) const = 0;
-};
-
-template <typename Filter>
-class QGLPixmapFilter : public Filter, public QGLPixmapFilterBase
-{
-public:
- void draw(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &srcRect = QRectF()) const {
- const QRectF source = srcRect.isNull() ? QRectF(src.rect()) : srcRect;
- if (painter)
- drawImpl(painter, pos, src, source);
- }
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QGLPIXMAPFILTER_P_H
diff --git a/src/opengl/qglscreen_qws.cpp b/src/opengl/qglscreen_qws.cpp
deleted file mode 100644
index 517813e628..0000000000
--- a/src/opengl/qglscreen_qws.cpp
+++ /dev/null
@@ -1,242 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QGLScreen>
-#include <QGLContext>
-#include <QGLWidget>
-#include "private/qglwindowsurface_qws_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class QGLScreenPrivate
-{
-public:
- QGLScreen::Options options;
- QGLScreenSurfaceFunctions *functions;
-};
-
-/*!
- \internal
- \preliminary
- \class QGLScreen
-
- \brief This class encapsulates an OpenGL screen driver.
-*/
-
-QGLScreen::QGLScreen(int displayId)
- : QScreen(displayId, GLClass), d_ptr(new QGLScreenPrivate)
-{
- d_ptr->options = NoOptions;
- d_ptr->functions = new QGLScreenSurfaceFunctions();
-}
-
-QGLScreen::~QGLScreen()
-{
- delete d_ptr->functions;
- delete d_ptr;
-}
-
-/*!
- \since 4.3
- \obsolete
-
- Initializes the \a context and sets up the QGLWindowSurface of the
- QWidget of \a context based on the parameters of \a context and
- based on its own requirements. The format() of \a context needs
- to be updated with the actual parameters of the OpenGLES drawable
- that was set up.
-
- \a shareContext is used in the same way as for QGLContext. It is
- the context with which \a context shares display lists and texture
- ids etc. The window surface must be set up so that this sharing
- works.
-
- Returns true in case of success and false if it is not possible to
- create the necessary OpenGLES drawable/context.
-
- Since 4.4.2, this function will be not be called if options()
- indicates that a native window or pixmap drawable can be created
- via the functions in the surfaceFunctions() object.
-
- This function is obsolete in Qt 4.5 and higher. Use surfaceFunctions()
- instead.
-
- \sa options(), surfaceFunctions()
-*/
-bool
-QGLScreen::chooseContext(QGLContext *context, const QGLContext *shareContext)
-{
- Q_UNUSED(context);
- Q_UNUSED(shareContext);
- return false;
-}
-
-/*!
- \enum QGLScreen::Option
- This enum defines options that can be set on QGLScreen instances.
-
- \value NoOptions There are no special options on the screen. This is the default.
- \value NativeWindows Native windows can be created with QGLScreenSurfaceFunctions::createNativeWindow().
- \value NativePixmaps Native pixmaps can be created with QGLScreenSurfaceFunctions::createNativePixmap().
- \value NativeImages Native images can be created with QGLScreenSurfaceFunctions::createNativeImage().
- \value Overlays The screen supports GL overlays.
-*/
-
-/*!
- \since 4.4.2
-
- Returns the options associated with this QGLScreen.
-
- \sa setOptions()
-*/
-QGLScreen::Options QGLScreen::options() const
-{
- return d_ptr->options;
-}
-
-/*!
- \since 4.4.2
-
- Sets the options associated with this QGLScreen to \a value.
-
- \sa options()
-*/
-void QGLScreen::setOptions(QGLScreen::Options value)
-{
- d_ptr->options = value;
-}
-
-/*!
- \since 4.4.2
-
- Returns the surface functions object for this QGLScreen.
-
- \sa setSurfaceFunctions()
-*/
-QGLScreenSurfaceFunctions *QGLScreen::surfaceFunctions() const
-{
- return d_ptr->functions;
-}
-
-/*!
- \since 4.4.2
-
- Sets the surface functions object for this QGLScreen to \a functions.
- The QGLScreen will take over ownership of \a functions and delete
- it when the QGLScreen is deleted.
-
- \sa setSurfaceFunctions()
-*/
-void QGLScreen::setSurfaceFunctions(QGLScreenSurfaceFunctions *functions)
-{
- if (functions && functions != d_ptr->functions) {
- delete d_ptr->functions;
- d_ptr->functions = functions;
- }
-}
-
-/*!
- \internal
- \preliminary
- \class QGLScreenSurfaceFunctions
- \brief The QGLScreenSurfaceFunctions class encapsulates the functions for creating native windows and pixmaps for OpenGL ES.
-*/
-
-/*!
- \since 4.4.2
-
- Creates a native OpenGLES drawable for the surface of \a widget and
- returns it in \a native. Returns true if the OpenGLES drawable could
- be created, or false if windows are not supported.
-
- This function will be called if the NativeWindows option is set on
- the screen.
-
- \sa createNativePixmap(), createNativeImage(), QGLScreen::options()
-*/
-bool QGLScreenSurfaceFunctions::createNativeWindow(QWidget *widget, EGLNativeWindowType *native)
-{
- Q_UNUSED(widget);
- Q_UNUSED(native);
- return false;
-}
-
-/*!
- \since 4.4.2
-
- Creates a native OpenGLES drawable for directly rendering into
- \a pixmap and returns it in \a native. Returns true if the OpenGLES
- drawable could be created, or false if direct rendering into pixmaps
- is not supported.
-
- This function will be called if the NativePixmaps option is set on
- the screen.
-
- \sa createNativeWindow(), createNativeImage(), QGLScreen::options()
-*/
-bool QGLScreenSurfaceFunctions::createNativePixmap(QPixmap *pixmap, EGLNativePixmapType *native)
-{
- Q_UNUSED(pixmap);
- Q_UNUSED(native);
- return false;
-}
-
-/*!
- \since 4.4.2
-
- Creates a native OpenGLES drawable for directly rendering into
- \a image and returns it in \a native. Returns true if the OpenGLES
- drawable could be created, or false if direct rendering into images
- is not supported.
-
- This function will be called if the NativeImages option is set on
- the screen.
-
- \sa createNativeWindow(), createNativePixmap(), QGLScreen::options()
-*/
-bool QGLScreenSurfaceFunctions::createNativeImage(QImage *image, EGLNativePixmapType *native)
-{
- Q_UNUSED(image);
- Q_UNUSED(native);
- return false;
-}
-
-QT_END_NAMESPACE
diff --git a/src/opengl/qglscreen_qws.h b/src/opengl/qglscreen_qws.h
deleted file mode 100644
index a033b6badb..0000000000
--- a/src/opengl/qglscreen_qws.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSCREENEGL_P_H
-#define QSCREENEGL_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of the QScreenEGL class. This header file may change from
-// version to version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtGui/QScreen>
-#include <QtOpenGL/qgl.h>
-#if defined(QT_OPENGL_ES_2)
-#include <EGL/egl.h>
-#else
-#include <GLES/egl.h>
-#endif
-#if !defined(EGL_VERSION_1_3) && !defined(QEGL_NATIVE_TYPES_DEFINED)
-#undef EGLNativeWindowType
-#undef EGLNativePixmapType
-#undef EGLNativeDisplayType
-typedef NativeWindowType EGLNativeWindowType;
-typedef NativePixmapType EGLNativePixmapType;
-typedef NativeDisplayType EGLNativeDisplayType;
-#define QEGL_NATIVE_TYPES_DEFINED 1
-#endif
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(OpenGL)
-
-class QGLScreenPrivate;
-
-class Q_OPENGL_EXPORT QGLScreenSurfaceFunctions
-{
-public:
- virtual bool createNativeWindow(QWidget *widget, EGLNativeWindowType *native);
- virtual bool createNativePixmap(QPixmap *pixmap, EGLNativePixmapType *native);
- virtual bool createNativeImage(QImage *image, EGLNativePixmapType *native);
-};
-
-class Q_OPENGL_EXPORT QGLScreen : public QScreen
-{
- Q_DECLARE_PRIVATE(QGLScreen)
-public:
- QGLScreen(int displayId);
- virtual ~QGLScreen();
-
- enum Option
- {
- NoOptions = 0,
- NativeWindows = 1,
- NativePixmaps = 2,
- NativeImages = 4,
- Overlays = 8
- };
- Q_DECLARE_FLAGS(Options, Option)
-
- QGLScreen::Options options() const;
-
- virtual bool chooseContext(QGLContext *context, const QGLContext *shareContext);
- virtual bool hasOpenGL() = 0;
-
- QGLScreenSurfaceFunctions *surfaceFunctions() const;
-
-protected:
- void setOptions(QGLScreen::Options value);
- void setSurfaceFunctions(QGLScreenSurfaceFunctions *functions);
-
-private:
- QGLScreenPrivate *d_ptr;
-};
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QGLScreen::Options)
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QSCREENEGL_P_H
diff --git a/src/opengl/qglshaderprogram.cpp b/src/opengl/qglshaderprogram.cpp
index e9cae44662..0163d60f0c 100644
--- a/src/opengl/qglshaderprogram.cpp
+++ b/src/opengl/qglshaderprogram.cpp
@@ -50,8 +50,6 @@
QT_BEGIN_NAMESPACE
-#if !defined(QT_OPENGL_ES_1)
-
/*!
\class QGLShaderProgram
\brief The QGLShaderProgram class allows OpenGL shader programs to be linked and used.
@@ -191,15 +189,15 @@ class QGLShaderPrivate : public QObjectPrivate
{
Q_DECLARE_PUBLIC(QGLShader)
public:
- QGLShaderPrivate(const QGLContext *context, QGLShader::ShaderType type)
- : shaderGuard(context)
+ QGLShaderPrivate(const QGLContext *, QGLShader::ShaderType type)
+ : shaderGuard(0)
, shaderType(type)
, compiled(false)
{
}
~QGLShaderPrivate();
- QGLSharedResourceGuard shaderGuard;
+ QGLSharedResourceGuardBase *shaderGuard;
QGLShader::ShaderType shaderType;
bool compiled;
QString log;
@@ -209,22 +207,28 @@ public:
void deleteShader();
};
-#define ctx shaderGuard.context()
+namespace {
+ void freeShaderFunc(QGLContext *ctx, GLuint id)
+ {
+ Q_UNUSED(ctx);
+ glDeleteShader(id);
+ }
+}
+
+#define ctx QGLContext::currentContext()
QGLShaderPrivate::~QGLShaderPrivate()
{
- if (shaderGuard.id()) {
- QGLShareContextScope scope(shaderGuard.context());
- glDeleteShader(shaderGuard.id());
- }
+ if (shaderGuard)
+ shaderGuard->free();
}
bool QGLShaderPrivate::create()
{
- const QGLContext *context = shaderGuard.context();
+ QGLContext *context = const_cast<QGLContext *>(QGLContext::currentContext());
if (!context)
return false;
- if (qt_resolve_glsl_extensions(const_cast<QGLContext *>(context))) {
+ if (qt_resolve_glsl_extensions(context)) {
GLuint shader;
if (shaderType == QGLShader::Vertex)
shader = glCreateShader(GL_VERTEX_SHADER);
@@ -236,7 +240,7 @@ bool QGLShaderPrivate::create()
qWarning() << "QGLShader: could not create shader";
return false;
}
- shaderGuard.setId(shader);
+ shaderGuard = createSharedResourceGuard(context, shader, freeShaderFunc);
return true;
} else {
return false;
@@ -245,7 +249,7 @@ bool QGLShaderPrivate::create()
bool QGLShaderPrivate::compile(QGLShader *q)
{
- GLuint shader = shaderGuard.id();
+ GLuint shader = shaderGuard ? shaderGuard->id() : 0;
if (!shader)
return false;
glCompileShader(shader);
@@ -288,15 +292,12 @@ bool QGLShaderPrivate::compile(QGLShader *q)
void QGLShaderPrivate::deleteShader()
{
- if (shaderGuard.id()) {
- glDeleteShader(shaderGuard.id());
- shaderGuard.setId(0);
+ if (shaderGuard) {
+ shaderGuard->free();
+ shaderGuard = 0;
}
}
-#undef ctx
-#define ctx d->shaderGuard.context()
-
/*!
Constructs a new QGLShader object of the specified \a type
and attaches it to \a parent. If shader programs are not supported,
@@ -389,7 +390,7 @@ static const char redefineHighp[] =
bool QGLShader::compileSourceCode(const char *source)
{
Q_D(QGLShader);
- if (d->shaderGuard.id()) {
+ if (d->shaderGuard && d->shaderGuard->id()) {
QVarLengthArray<const char *, 4> src;
QVarLengthArray<GLint, 4> srclen;
int headerLen = 0;
@@ -422,7 +423,7 @@ bool QGLShader::compileSourceCode(const char *source)
#endif
src.append(source + headerLen);
srclen.append(GLint(qstrlen(source + headerLen)));
- glShaderSource(d->shaderGuard.id(), src.size(), src.data(), srclen.data());
+ glShaderSource(d->shaderGuard->id(), src.size(), src.data(), srclen.data());
return d->compile(this);
} else {
return false;
@@ -482,7 +483,7 @@ bool QGLShader::compileSourceFile(const QString& fileName)
QByteArray QGLShader::sourceCode() const
{
Q_D(const QGLShader);
- GLuint shader = d->shaderGuard.id();
+ GLuint shader = d->shaderGuard ? d->shaderGuard->id() : 0;
if (!shader)
return QByteArray();
GLint size = 0;
@@ -527,22 +528,17 @@ QString QGLShader::log() const
GLuint QGLShader::shaderId() const
{
Q_D(const QGLShader);
- return d->shaderGuard.id();
+ return d->shaderGuard ? d->shaderGuard->id() : 0;
}
-
-
-
-
#undef ctx
-#define ctx programGuard.context()
class QGLShaderProgramPrivate : public QObjectPrivate
{
Q_DECLARE_PUBLIC(QGLShaderProgram)
public:
- QGLShaderProgramPrivate(const QGLContext *context)
- : programGuard(context)
+ QGLShaderProgramPrivate(const QGLContext *)
+ : programGuard(0)
, linked(false)
, inited(false)
, removingShaders(false)
@@ -553,7 +549,7 @@ public:
}
~QGLShaderProgramPrivate();
- QGLSharedResourceGuard programGuard;
+ QGLSharedResourceGuardBase *programGuard;
bool linked;
bool inited;
bool removingShaders;
@@ -569,12 +565,19 @@ public:
bool hasShader(QGLShader::ShaderType type) const;
};
+namespace {
+ void freeProgramFunc(QGLContext *ctx, GLuint id)
+ {
+ Q_UNUSED(ctx);
+ glDeleteProgram(id);
+ }
+}
+
+
QGLShaderProgramPrivate::~QGLShaderProgramPrivate()
{
- if (programGuard.id()) {
- QGLShareContextScope scope(programGuard.context());
- glDeleteProgram(programGuard.id());
- }
+ if (programGuard)
+ programGuard->free();
}
bool QGLShaderProgramPrivate::hasShader(QGLShader::ShaderType type) const
@@ -586,8 +589,7 @@ bool QGLShaderProgramPrivate::hasShader(QGLShader::ShaderType type) const
return false;
}
-#undef ctx
-#define ctx d->programGuard.context()
+#define ctx QGLContext::currentContext()
/*!
Constructs a new shader program and attaches it to \a parent.
@@ -625,24 +627,21 @@ QGLShaderProgram::~QGLShaderProgram()
bool QGLShaderProgram::init()
{
Q_D(QGLShaderProgram);
- if (d->programGuard.id() || d->inited)
+ if ((d->programGuard && d->programGuard->id()) || d->inited)
return true;
d->inited = true;
- const QGLContext *context = d->programGuard.context();
- if (!context) {
- context = QGLContext::currentContext();
- d->programGuard.setContext(context);
- }
-
+ QGLContext *context = const_cast<QGLContext *>(QGLContext::currentContext());
if (!context)
return false;
- if (qt_resolve_glsl_extensions(const_cast<QGLContext *>(context))) {
+ if (qt_resolve_glsl_extensions(context)) {
GLuint program = glCreateProgram();
if (!program) {
qWarning() << "QGLShaderProgram: could not create shader program";
return false;
}
- d->programGuard.setId(program);
+ if (d->programGuard)
+ delete d->programGuard;
+ d->programGuard = createSharedResourceGuard(context, program, freeProgramFunc);
return true;
} else {
qWarning() << "QGLShaderProgram: shader programs are not supported";
@@ -669,15 +668,14 @@ bool QGLShaderProgram::addShader(QGLShader *shader)
return false;
if (d->shaders.contains(shader))
return true; // Already added to this shader program.
- if (d->programGuard.id() && shader) {
- if (!QGLContext::areSharing(shader->d_func()->shaderGuard.context(),
- d->programGuard.context())) {
+ if (d->programGuard && d->programGuard->id() && shader) {
+ if (!shader->d_func()->shaderGuard || !shader->d_func()->shaderGuard->id())
+ return false;
+ if (d->programGuard->group() != shader->d_func()->shaderGuard->group()) {
qWarning("QGLShaderProgram::addShader: Program and shader are not associated with same context.");
return false;
}
- if (!shader->d_func()->shaderGuard.id())
- return false;
- glAttachShader(d->programGuard.id(), shader->d_func()->shaderGuard.id());
+ glAttachShader(d->programGuard->id(), shader->d_func()->shaderGuard->id());
d->linked = false; // Program needs to be relinked.
d->shaders.append(shader);
connect(shader, SIGNAL(destroyed()), this, SLOT(shaderDestroyed()));
@@ -786,14 +784,17 @@ bool QGLShaderProgram::addShaderFromSourceFile
/*!
Removes \a shader from this shader program. The object is not deleted.
+ The shader program must be valid in the current QGLContext.
+
\sa addShader(), link(), removeAllShaders()
*/
void QGLShaderProgram::removeShader(QGLShader *shader)
{
Q_D(QGLShaderProgram);
- if (d->programGuard.id() && shader && shader->d_func()->shaderGuard.id()) {
- QGLShareContextScope scope(d->programGuard.context());
- glDetachShader(d->programGuard.id(), shader->d_func()->shaderGuard.id());
+ if (d->programGuard && d->programGuard->id()
+ && shader && shader->d_func()->shaderGuard)
+ {
+ glDetachShader(d->programGuard->id(), shader->d_func()->shaderGuard->id());
}
d->linked = false; // Program needs to be relinked.
if (shader) {
@@ -828,8 +829,11 @@ void QGLShaderProgram::removeAllShaders()
Q_D(QGLShaderProgram);
d->removingShaders = true;
foreach (QGLShader *shader, d->shaders) {
- if (d->programGuard.id() && shader && shader->d_func()->shaderGuard.id())
- glDetachShader(d->programGuard.id(), shader->d_func()->shaderGuard.id());
+ if (d->programGuard && d->programGuard->id()
+ && shader && shader->d_func()->shaderGuard)
+ {
+ glDetachShader(d->programGuard->id(), shader->d_func()->shaderGuard->id());
+ }
}
foreach (QGLShader *shader, d->anonShaders) {
// Delete shader objects that were created anonymously.
@@ -858,7 +862,7 @@ void QGLShaderProgram::removeAllShaders()
bool QGLShaderProgram::link()
{
Q_D(QGLShaderProgram);
- GLuint program = d->programGuard.id();
+ GLuint program = d->programGuard ? d->programGuard->id() : 0;
if (!program)
return false;
@@ -948,13 +952,13 @@ QString QGLShaderProgram::log() const
bool QGLShaderProgram::bind()
{
Q_D(QGLShaderProgram);
- GLuint program = d->programGuard.id();
+ GLuint program = d->programGuard ? d->programGuard->id() : 0;
if (!program)
return false;
if (!d->linked && !link())
return false;
#ifndef QT_NO_DEBUG
- if (!QGLContext::areSharing(d->programGuard.context(), QGLContext::currentContext())) {
+ if (d->programGuard->group() != QOpenGLContextGroup::currentContextGroup()) {
qWarning("QGLShaderProgram::bind: program is not valid in the current context.");
return false;
}
@@ -976,7 +980,7 @@ void QGLShaderProgram::release()
{
#ifndef QT_NO_DEBUG
Q_D(QGLShaderProgram);
- if (!QGLContext::areSharing(d->programGuard.context(), QGLContext::currentContext()))
+ if (d->programGuard->group() != QOpenGLContextGroup::currentContextGroup())
qWarning("QGLShaderProgram::release: program is not valid in the current context.");
#endif
#if defined(QT_OPENGL_ES_2)
@@ -987,9 +991,6 @@ void QGLShaderProgram::release()
#endif
}
-#undef ctx
-#define ctx d->programGuard.context()
-
/*!
Returns the OpenGL identifier associated with this shader program.
@@ -998,7 +999,7 @@ void QGLShaderProgram::release()
GLuint QGLShaderProgram::programId() const
{
Q_D(const QGLShaderProgram);
- GLuint id = d->programGuard.id();
+ GLuint id = d->programGuard ? d->programGuard->id() : 0;
if (id)
return id;
@@ -1007,7 +1008,7 @@ GLuint QGLShaderProgram::programId() const
// themselves, particularly those using program binaries.
if (!const_cast<QGLShaderProgram *>(this)->init())
return 0;
- return d->programGuard.id();
+ return d->programGuard ? d->programGuard->id() : 0;
}
/*!
@@ -1024,9 +1025,9 @@ GLuint QGLShaderProgram::programId() const
void QGLShaderProgram::bindAttributeLocation(const char *name, int location)
{
Q_D(QGLShaderProgram);
- if (!init())
+ if (!init() || !d->programGuard || !d->programGuard->id())
return;
- glBindAttribLocation(d->programGuard.id(), location, name);
+ glBindAttribLocation(d->programGuard->id(), location, name);
d->linked = false; // Program needs to be relinked.
}
@@ -1076,8 +1077,8 @@ void QGLShaderProgram::bindAttributeLocation(const QString& name, int location)
int QGLShaderProgram::attributeLocation(const char *name) const
{
Q_D(const QGLShaderProgram);
- if (d->linked) {
- return glGetAttribLocation(d->programGuard.id(), name);
+ if (d->linked && d->programGuard && d->programGuard->id()) {
+ return glGetAttribLocation(d->programGuard->id(), name);
} else {
qWarning() << "QGLShaderProgram::attributeLocation(" << name
<< "): shader program is not linked";
@@ -1754,8 +1755,8 @@ int QGLShaderProgram::uniformLocation(const char *name) const
{
Q_D(const QGLShaderProgram);
Q_UNUSED(d);
- if (d->linked) {
- return glGetUniformLocation(d->programGuard.id(), name);
+ if (d->linked && d->programGuard && d->programGuard->id()) {
+ return glGetUniformLocation(d->programGuard->id(), name);
} else {
qWarning() << "QGLShaderProgram::uniformLocation(" << name
<< "): shader program is not linked";
@@ -3269,86 +3270,4 @@ bool QGLShader::hasOpenGLShaders(ShaderType type, const QGLContext *context)
return true;
}
-
-
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
-/*! \internal */
-void QGLShaderProgram::setAttributeArray
- (int location, QMacCompatGLenum type, const void *values, int tupleSize, int stride)
-{
- setAttributeArray(location, GLenum(type), values, tupleSize, stride);
-}
-
-/*! \internal */
-void QGLShaderProgram::setAttributeArray
- (const char *name, QMacCompatGLenum type, const void *values, int tupleSize, int stride)
-{
- setAttributeArray(name, GLenum(type), values, tupleSize, stride);
-}
-
-/*! \internal */
-void QGLShaderProgram::setAttributeBuffer
- (int location, QMacCompatGLenum type, int offset, int tupleSize, int stride)
-{
- setAttributeBuffer(location, GLenum(type), offset, tupleSize, stride);
-}
-
-/*! \internal */
-void QGLShaderProgram::setAttributeBuffer
- (const char *name, QMacCompatGLenum type, int offset, int tupleSize, int stride)
-{
- setAttributeBuffer(name, GLenum(type), offset, tupleSize, stride);
-}
-
-/*! \internal */
-void QGLShaderProgram::setUniformValue(int location, QMacCompatGLint value)
-{
- setUniformValue(location, GLint(value));
-}
-
-/*! \internal */
-void QGLShaderProgram::setUniformValue(int location, QMacCompatGLuint value)
-{
- setUniformValue(location, GLuint(value));
-}
-
-/*! \internal */
-void QGLShaderProgram::setUniformValue(const char *name, QMacCompatGLint value)
-{
- setUniformValue(name, GLint(value));
-}
-
-/*! \internal */
-void QGLShaderProgram::setUniformValue(const char *name, QMacCompatGLuint value)
-{
- setUniformValue(name, GLuint(value));
-}
-
-/*! \internal */
-void QGLShaderProgram::setUniformValueArray(int location, const QMacCompatGLint *values, int count)
-{
- setUniformValueArray(location, (const GLint *)values, count);
-}
-
-/*! \internal */
-void QGLShaderProgram::setUniformValueArray(int location, const QMacCompatGLuint *values, int count)
-{
- setUniformValueArray(location, (const GLuint *)values, count);
-}
-
-/*! \internal */
-void QGLShaderProgram::setUniformValueArray(const char *name, const QMacCompatGLint *values, int count)
-{
- setUniformValueArray(name, (const GLint *)values, count);
-}
-
-/*! \internal */
-void QGLShaderProgram::setUniformValueArray(const char *name, const QMacCompatGLuint *values, int count)
-{
- setUniformValueArray(name, (const GLuint *)values, count);
-}
-#endif
-
-#endif // !defined(QT_OPENGL_ES_1)
-
QT_END_NAMESPACE
diff --git a/src/opengl/qglshaderprogram.h b/src/opengl/qglshaderprogram.h
index 09b6184bcb..591aab27cd 100644
--- a/src/opengl/qglshaderprogram.h
+++ b/src/opengl/qglshaderprogram.h
@@ -54,8 +54,6 @@ QT_BEGIN_NAMESPACE
QT_MODULE(OpenGL)
-#if !defined(QT_OPENGL_ES_1)
-
class QGLShaderProgram;
class QGLShaderPrivate;
@@ -204,17 +202,6 @@ public:
void setAttributeBuffer
(const char *name, GLenum type, int offset, int tupleSize, int stride = 0);
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
- void setAttributeArray
- (int location, QMacCompatGLenum type, const void *values, int tupleSize, int stride = 0);
- void setAttributeArray
- (const char *name, QMacCompatGLenum type, const void *values, int tupleSize, int stride = 0);
- void setAttributeBuffer
- (int location, QMacCompatGLenum type, int offset, int tupleSize, int stride = 0);
- void setAttributeBuffer
- (const char *name, QMacCompatGLenum type, int offset, int tupleSize, int stride = 0);
-#endif
-
void enableAttributeArray(int location);
void enableAttributeArray(const char *name);
void disableAttributeArray(int location);
@@ -224,17 +211,6 @@ public:
int uniformLocation(const QByteArray& name) const;
int uniformLocation(const QString& name) const;
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
- void setUniformValue(int location, QMacCompatGLint value);
- void setUniformValue(int location, QMacCompatGLuint value);
- void setUniformValue(const char *name, QMacCompatGLint value);
- void setUniformValue(const char *name, QMacCompatGLuint value);
- void setUniformValueArray(int location, const QMacCompatGLint *values, int count);
- void setUniformValueArray(int location, const QMacCompatGLuint *values, int count);
- void setUniformValueArray(const char *name, const QMacCompatGLint *values, int count);
- void setUniformValueArray(const char *name, const QMacCompatGLuint *values, int count);
-#endif
-
void setUniformValue(int location, GLfloat value);
void setUniformValue(int location, GLint value);
void setUniformValue(int location, GLuint value);
@@ -335,8 +311,6 @@ private:
bool init();
};
-#endif
-
QT_END_NAMESPACE
QT_END_HEADER
diff --git a/src/opengl/qgltexturepool.cpp b/src/opengl/qgltexturepool.cpp
deleted file mode 100644
index d809328725..0000000000
--- a/src/opengl/qgltexturepool.cpp
+++ /dev/null
@@ -1,244 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenVG module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qgltexturepool_p.h"
-#include "qpixmapdata_gl_p.h"
-
-QT_BEGIN_NAMESPACE
-
-Q_OPENGL_EXPORT extern QGLWidget* qt_gl_share_widget();
-
-static QGLTexturePool *qt_gl_texture_pool = 0;
-
-class QGLTexturePoolPrivate
-{
-public:
- QGLTexturePoolPrivate() : lruFirst(0), lruLast(0) {}
-
- QGLPixmapData *lruFirst;
- QGLPixmapData *lruLast;
-};
-
-QGLTexturePool::QGLTexturePool()
- : d_ptr(new QGLTexturePoolPrivate())
-{
-}
-
-QGLTexturePool::~QGLTexturePool()
-{
-}
-
-QGLTexturePool *QGLTexturePool::instance()
-{
- if (!qt_gl_texture_pool)
- qt_gl_texture_pool = new QGLTexturePool();
- return qt_gl_texture_pool;
-}
-
-GLuint QGLTexturePool::createTextureForPixmap(GLenum target,
- GLint level,
- GLint internalformat,
- GLsizei width,
- GLsizei height,
- GLenum format,
- GLenum type,
- QGLPixmapData *data)
-{
- GLuint texture;
- glGenTextures(1, &texture);
- glBindTexture(target, texture);
- do {
- glTexImage2D(target, level, internalformat, width, height, 0, format, type, 0);
- GLenum error = glGetError();
- if (error == GL_NO_ERROR) {
- if (data)
- moveToHeadOfLRU(data);
- return texture;
- } else if (error != GL_OUT_OF_MEMORY) {
- qWarning("QGLTexturePool: cannot create temporary texture because of invalid params");
- return 0;
- }
- } while (reclaimSpace(internalformat, width, height, format, type, data));
- qWarning("QGLTexturePool: cannot reclaim sufficient space for a %dx%d pixmap",
- width, height);
- return 0;
-}
-
-bool QGLTexturePool::createPermanentTexture(GLuint texture,
- GLenum target,
- GLint level,
- GLint internalformat,
- GLsizei width,
- GLsizei height,
- GLenum format,
- GLenum type,
- const GLvoid *data)
-{
- glBindTexture(target, texture);
- do {
- glTexImage2D(target, level, internalformat, width, height, 0, format, type, data);
-
- GLenum error = glGetError();
- if (error == GL_NO_ERROR) {
- return true;
- } else if (error != GL_OUT_OF_MEMORY) {
- qWarning("QGLTexturePool: cannot create permanent texture because of invalid params");
- return false;
- }
- } while (reclaimSpace(internalformat, width, height, format, type, 0));
- qWarning("QGLTexturePool: cannot reclaim sufficient space for a %dx%d pixmap",
- width, height);
- return 0;
-}
-
-void QGLTexturePool::releaseTexture(QGLPixmapData *data, GLuint texture)
-{
- // Very simple strategy at the moment: just destroy the texture.
- if (data)
- removeFromLRU(data);
-
- QGLWidget *shareWidget = qt_gl_share_widget();
- if (shareWidget) {
- QGLShareContextScope ctx(shareWidget->context());
- glDeleteTextures(1, &texture);
- }
-}
-
-void QGLTexturePool::useTexture(QGLPixmapData *data)
-{
- moveToHeadOfLRU(data);
-}
-
-void QGLTexturePool::detachTexture(QGLPixmapData *data)
-{
- removeFromLRU(data);
-}
-
-bool QGLTexturePool::reclaimSpace(GLint internalformat,
- GLsizei width,
- GLsizei height,
- GLenum format,
- GLenum type,
- QGLPixmapData *data)
-{
- Q_UNUSED(internalformat); // For future use in picking the best texture to eject.
- Q_UNUSED(width);
- Q_UNUSED(height);
- Q_UNUSED(format);
- Q_UNUSED(type);
-
- bool succeeded = false;
- bool wasInLRU = false;
- if (data) {
- wasInLRU = data->inLRU;
- moveToHeadOfLRU(data);
- }
-
- QGLPixmapData *lrudata = pixmapLRU();
- if (lrudata && lrudata != data) {
- lrudata->reclaimTexture();
- succeeded = true;
- }
-
- if (data && !wasInLRU)
- removeFromLRU(data);
-
- return succeeded;
-}
-
-void QGLTexturePool::hibernate()
-{
- Q_D(QGLTexturePool);
- QGLPixmapData *pd = d->lruLast;
- while (pd) {
- QGLPixmapData *prevLRU = pd->prevLRU;
- pd->inTexturePool = false;
- pd->inLRU = false;
- pd->nextLRU = 0;
- pd->prevLRU = 0;
- pd->hibernate();
- pd = prevLRU;
- }
- d->lruFirst = 0;
- d->lruLast = 0;
-}
-
-void QGLTexturePool::moveToHeadOfLRU(QGLPixmapData *data)
-{
- Q_D(QGLTexturePool);
- if (data->inLRU) {
- if (!data->prevLRU)
- return; // Already at the head of the list.
- removeFromLRU(data);
- }
- data->inLRU = true;
- data->nextLRU = d->lruFirst;
- data->prevLRU = 0;
- if (d->lruFirst)
- d->lruFirst->prevLRU = data;
- else
- d->lruLast = data;
- d->lruFirst = data;
-}
-
-void QGLTexturePool::removeFromLRU(QGLPixmapData *data)
-{
- Q_D(QGLTexturePool);
- if (!data->inLRU)
- return;
- if (data->nextLRU)
- data->nextLRU->prevLRU = data->prevLRU;
- else
- d->lruLast = data->prevLRU;
- if (data->prevLRU)
- data->prevLRU->nextLRU = data->nextLRU;
- else
- d->lruFirst = data->nextLRU;
- data->inLRU = false;
-}
-
-QGLPixmapData *QGLTexturePool::pixmapLRU()
-{
- Q_D(QGLTexturePool);
- return d->lruLast;
-}
-
-QT_END_NAMESPACE
diff --git a/src/opengl/qgltexturepool_p.h b/src/opengl/qgltexturepool_p.h
deleted file mode 100644
index 27b730cbb9..0000000000
--- a/src/opengl/qgltexturepool_p.h
+++ /dev/null
@@ -1,147 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenVG module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGLTEXTUREPOOL_P_H
-#define QGLTEXTUREPOOL_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qgl.h"
-#include <QtCore/qscopedpointer.h>
-
-QT_BEGIN_NAMESPACE
-
-class QGLPixmapData;
-class QGLTexturePoolPrivate;
-
-class QGLTexturePool
-{
-public:
- QGLTexturePool();
- virtual ~QGLTexturePool();
-
- static QGLTexturePool *instance();
-
- // Create a new texture with the specified parameters and associate
- // it with "data". The QGLPixmapData will be notified when the
- // texture needs to be reclaimed by the pool.
- //
- // This function will call reclaimSpace() when texture creation fails.
- GLuint createTextureForPixmap(GLenum target,
- GLint level,
- GLint internalformat,
- GLsizei width,
- GLsizei height,
- GLenum format,
- GLenum type,
- QGLPixmapData *data);
-
- // Create a permanent texture with the specified parameters.
- // If there is insufficient space for the texture,
- // then this function will call reclaimSpace() and try again.
- //
- // The caller is responsible for calling glDeleteTextures()
- // when it no longer needs the texture, as the texture is not
- // recorded in the texture pool.
- bool createPermanentTexture(GLuint texture,
- GLenum target,
- GLint level,
- GLint internalformat,
- GLsizei width,
- GLsizei height,
- GLenum format,
- GLenum type,
- const GLvoid *data);
-
- // Release a texture that is no longer required.
- void releaseTexture(QGLPixmapData *data, GLuint texture);
-
- // Notify the pool that a QGLPixmapData object is using
- // an texture again. This allows the pool to move the texture
- // within a least-recently-used list of QGLPixmapData objects.
- void useTexture(QGLPixmapData *data);
-
- // Notify the pool that the texture associated with a
- // QGLPixmapData is being detached from the pool. The caller
- // will become responsible for calling glDeleteTextures().
- void detachTexture(QGLPixmapData *data);
-
- // Reclaim space for an image allocation with the specified parameters.
- // Returns true if space was reclaimed, or false if there is no
- // further space that can be reclaimed. The "data" parameter
- // indicates the pixmap that is trying to obtain space which should
- // not itself be reclaimed.
- bool reclaimSpace(GLint internalformat,
- GLsizei width,
- GLsizei height,
- GLenum format,
- GLenum type,
- QGLPixmapData *data);
-
- // Hibernate the image pool because the context is about to be
- // destroyed. All textures left in the pool should be released.
- void hibernate();
-
-protected:
- // Helper functions for managing the LRU list of QGLPixmapData objects.
- void moveToHeadOfLRU(QGLPixmapData *data);
- void removeFromLRU(QGLPixmapData *data);
- QGLPixmapData *pixmapLRU();
-
-private:
- QScopedPointer<QGLTexturePoolPrivate> d_ptr;
-
- Q_DECLARE_PRIVATE(QGLTexturePool)
- Q_DISABLE_COPY(QGLTexturePool)
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/opengl/qglwindowsurface_qws.cpp b/src/opengl/qglwindowsurface_qws.cpp
deleted file mode 100644
index b3ad45185e..0000000000
--- a/src/opengl/qglwindowsurface_qws.cpp
+++ /dev/null
@@ -1,133 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtGui/QPaintDevice>
-#include <QtGui/QWidget>
-#include <QtOpenGL/QGLWidget>
-#include "private/qglwindowsurface_qws_p.h"
-#include "private/qpaintengine_opengl_p.h"
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \class QWSGLWindowSurface
- \since 4.3
- \ingroup qws
- \preliminary
-
- \brief The QWSGLWindowSurface class provides the drawing area for top-level
- windows with Qt for Embedded Linux on EGL/OpenGL ES. It also provides the
- drawing area for \l{QGLWidget}s whether they are top-level windows or
- children of another QWidget.
-
- Note that this class is only available in Qt for Embedded Linux and only
- available if Qt is configured with OpenGL support.
-*/
-
-class QWSGLWindowSurfacePrivate
-{
-public:
- QWSGLWindowSurfacePrivate() :
- qglContext(0), ownsContext(false) {}
-
- QGLContext *qglContext;
- bool ownsContext;
-};
-
-/*!
- Constructs an empty QWSGLWindowSurface for the given top-level \a window.
- The window surface is later initialized from chooseContext() and resources for it
- is typically allocated in setGeometry().
-*/
-QWSGLWindowSurface::QWSGLWindowSurface(QWidget *window)
- : QWSWindowSurface(window),
- d_ptr(new QWSGLWindowSurfacePrivate)
-{
-}
-
-/*!
- Constructs an empty QWSGLWindowSurface.
-*/
-QWSGLWindowSurface::QWSGLWindowSurface()
- : d_ptr(new QWSGLWindowSurfacePrivate)
-{
-}
-
-/*!
- Destroys the QWSGLWindowSurface object and frees any
- allocated resources.
- */
-QWSGLWindowSurface::~QWSGLWindowSurface()
-{
- Q_D(QWSGLWindowSurface);
- if (d->ownsContext)
- delete d->qglContext;
- delete d;
-}
-
-/*!
- Returns the QGLContext of the window surface.
-*/
-QGLContext *QWSGLWindowSurface::context() const
-{
- Q_D(const QWSGLWindowSurface);
- if (!d->qglContext) {
- QWSGLWindowSurface *that = const_cast<QWSGLWindowSurface*>(this);
- that->setContext(new QGLContext(QGLFormat::defaultFormat()));
- that->d_func()->ownsContext = true;
- }
- return d->qglContext;
-}
-
-/*!
- Sets the QGLContext for this window surface to \a context.
-*/
-void QWSGLWindowSurface::setContext(QGLContext *context)
-{
- Q_D(QWSGLWindowSurface);
- if (d->ownsContext) {
- delete d->qglContext;
- d->ownsContext = false;
- }
- d->qglContext = context;
-}
-
-QT_END_NAMESPACE
diff --git a/src/opengl/qglwindowsurface_qws_p.h b/src/opengl/qglwindowsurface_qws_p.h
deleted file mode 100644
index 07362b1b88..0000000000
--- a/src/opengl/qglwindowsurface_qws_p.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGLWINDOWSURFACE_QWS_P_H
-#define QGLWINDOWSURFACE_QWS_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of the QWSGLWindowSurface class. This header file may change from
-// version to version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/qglobal.h>
-#include <QPaintDevice>
-#include "private/qwindowsurface_qws_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class QPaintDevice;
-class QPoint;
-class QRegion;
-class QSize;
-class QWidget;
-class QGLContext;
-
-class QWSGLWindowSurfacePrivate;
-
-class Q_OPENGL_EXPORT QWSGLWindowSurface : public QWSWindowSurface
-{
- Q_DECLARE_PRIVATE(QWSGLWindowSurface)
-
-public:
- QWSGLWindowSurface(QWidget *widget);
- QWSGLWindowSurface();
- ~QWSGLWindowSurface();
-
- QGLContext *context() const;
- void setContext(QGLContext *context);
-
-private:
- QWSGLWindowSurfacePrivate *d_ptr;
-};
-
-
-QT_END_NAMESPACE
-
-#endif // QGLWINDOWSURFACE_QWS_P_H
diff --git a/src/opengl/qgraphicsshadereffect.cpp b/src/opengl/qgraphicsshadereffect.cpp
index c7a058e9ef..c785fb29ad 100644
--- a/src/opengl/qgraphicsshadereffect.cpp
+++ b/src/opengl/qgraphicsshadereffect.cpp
@@ -40,14 +40,12 @@
****************************************************************************/
#include "qgraphicsshadereffect_p.h"
-#if !defined(QT_OPENGL_ES_1)
#include "qglshaderprogram.h"
#include "gl2paintengineex/qglcustomshaderstage_p.h"
#define QGL_HAVE_CUSTOM_SHADERS 1
-#endif
#include <QtGui/qpainter.h>
-#include <QtGui/qgraphicsitem.h>
-#include <QtGui/private/qgraphicseffect_p.h>
+#include <QtWidgets/qgraphicsitem.h>
+#include <private/qgraphicseffect_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/opengl/qgraphicsshadereffect_p.h b/src/opengl/qgraphicsshadereffect_p.h
index 12d716524b..7ae5f53d7e 100644
--- a/src/opengl/qgraphicsshadereffect_p.h
+++ b/src/opengl/qgraphicsshadereffect_p.h
@@ -53,7 +53,7 @@
// We mean it.
//
-#include <QtGui/qgraphicseffect.h>
+#include <QtWidgets/qgraphicseffect.h>
QT_BEGIN_HEADER
diff --git a/src/opengl/qgraphicssystem_gl.cpp b/src/opengl/qgraphicssystem_gl.cpp
deleted file mode 100644
index 01a2864ecc..0000000000
--- a/src/opengl/qgraphicssystem_gl.cpp
+++ /dev/null
@@ -1,114 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qgraphicssystem_gl_p.h"
-#include <QGraphicsView>
-
-#include "private/qpixmap_raster_p.h"
-#include "private/qpixmapdata_gl_p.h"
-#include "private/qwindowsurface_gl_p.h"
-#include "private/qgl_p.h"
-#include <private/qwindowsurface_raster_p.h>
-
-#if defined(Q_WS_X11) && !defined(QT_NO_EGL)
-#include "private/qpixmapdata_x11gl_p.h"
-#include "private/qwindowsurface_x11gl_p.h"
-#endif
-
-#if defined(Q_OS_SYMBIAN)
-#include <QtGui/private/qapplication_p.h>
-#endif
-
-#ifdef QGL_USE_TEXTURE_POOL
-#include "private/qgltexturepool_p.h"
-#endif
-
-QT_BEGIN_NAMESPACE
-
-extern QGLWidget *qt_gl_getShareWidget();
-
-QPixmapData *QGLGraphicsSystem::createPixmapData(QPixmapData::PixelType type) const
-{
- return new QGLPixmapData(type);
-}
-
-QWindowSurface *QGLGraphicsSystem::createWindowSurface(QWidget *widget) const
-{
-#ifdef Q_WS_WIN
- // On Windows the QGLWindowSurface class can't handle
- // drop shadows and native effects, e.g. fading a menu in/out using
- // top level window opacity.
- if (widget->windowType() == Qt::Popup)
- return new QRasterWindowSurface(widget);
-#endif
-
-#if defined(Q_WS_X11) && !defined(QT_NO_EGL)
- if (m_useX11GL && QX11GLPixmapData::hasX11GLPixmaps()) {
- // If the widget is a QGraphicsView which will be re-drawing the entire
- // scene each frame anyway, we should use QGLWindowSurface as this may
- // provide proper buffer flipping, which should be faster than QX11GL's
- // blitting approach:
- QGraphicsView* qgv = qobject_cast<QGraphicsView*>(widget);
- if (qgv && qgv->viewportUpdateMode() == QGraphicsView::FullViewportUpdate)
- return new QGLWindowSurface(widget);
- else
- return new QX11GLWindowSurface(widget);
- }
-#endif
-
-#if defined(Q_OS_SYMBIAN)
- if (!QApplicationPrivate::instance()->useTranslucentEGLSurfaces) {
- QWidgetPrivate *d = qt_widget_private(widget);
- if (!d->isOpaque && widget->testAttribute(Qt::WA_TranslucentBackground))
- return d->createDefaultWindowSurface_sys();
- }
-#endif
-
- return new QGLWindowSurface(widget);
-}
-#ifdef QGL_USE_TEXTURE_POOL
-void QGLGraphicsSystem::releaseCachedResources()
-{
- QGLTexturePool::instance()->hibernate();
-}
-#endif
-QT_END_NAMESPACE
-
diff --git a/src/opengl/qgraphicssystem_gl_p.h b/src/opengl/qgraphicssystem_gl_p.h
deleted file mode 100644
index 6e8e9a8966..0000000000
--- a/src/opengl/qgraphicssystem_gl_p.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGRAPHICSSYSTEM_RASTER_P_H
-#define QGRAPHICSSYSTEM_RASTER_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "private/qgraphicssystem_p.h"
-
-#include <QMap>
-
-QT_BEGIN_NAMESPACE
-
-class Q_OPENGL_EXPORT QGLGraphicsSystem : public QGraphicsSystem
-{
-public:
- QGLGraphicsSystem(bool useX11GL);
-
- QPixmapData *createPixmapData(QPixmapData::PixelType type) const;
- QWindowSurface *createWindowSurface(QWidget *widget) const;
-
-#ifdef QGL_USE_TEXTURE_POOL
- void releaseCachedResources();
-#endif
-private:
- bool m_useX11GL;
-};
-
-QT_END_NAMESPACE
-
-#endif
-
diff --git a/src/opengl/qpaintengine_opengl.cpp b/src/opengl/qpaintengine_opengl.cpp
deleted file mode 100644
index 56a6af1cfe..0000000000
--- a/src/opengl/qpaintengine_opengl.cpp
+++ /dev/null
@@ -1,5635 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qdebug.h>
-#include <private/qfontengine_p.h>
-#include <qmath.h>
-#include <private/qmath_p.h>
-#include <private/qdrawhelper_p.h>
-#include <private/qpaintengine_p.h>
-#include "qapplication.h"
-#include "qbrush.h"
-#include "qgl.h"
-#include <private/qgl_p.h>
-#include <private/qglpaintdevice_p.h>
-#include <private/qpainter_p.h>
-#include "qmap.h"
-#include <private/qpaintengine_opengl_p.h>
-#include <private/qdatabuffer_p.h>
-#include "qpen.h"
-#include "qvarlengtharray.h"
-#include <private/qpainter_p.h>
-#include <private/qglpixelbuffer_p.h>
-#include <private/qbezier_p.h>
-#include <qglframebufferobject.h>
-#include <private/qstatictext_p.h>
-
-#include "private/qtessellator_p.h"
-
-#include "util/fragmentprograms_p.h"
-
-#ifdef Q_WS_QWS
-#include "private/qglwindowsurface_qws_p.h"
-#include "qwsmanager_qws.h"
-#include "private/qwsmanager_p.h"
-#endif
-
-#define QGL_FUNC_CONTEXT QGLContext *ctx = const_cast<QGLContext *>(device->context());
-
-#include <stdlib.h>
-#include "qpaintengine_opengl_p.h"
-
-QT_BEGIN_NAMESPACE
-
-Q_GUI_EXPORT QImage qt_imageForBrush(int brushStyle, bool invert); //in qbrush.cpp
-#ifdef QT_MAC_USE_COCOA
-extern void *qt_current_nsopengl_context(); // qgl_mac.mm
-#endif
-
-#define QREAL_MAX 9e100
-#define QREAL_MIN -9e100
-
-extern int qt_next_power_of_two(int v);
-
-#define DISABLE_DEBUG_ONCE
-
-//#define DEBUG_DISPLAY_MASK_TEXTURE
-
-#ifdef DISABLE_DEBUG_ONCE
-#define DEBUG_OVERRIDE(state) ;
-#define DEBUG_ONCE_STR(str) ;
-#define DEBUG_ONCE if (0)
-#else
-static int DEBUG_OVERRIDE_FLAG = 0;
-static bool DEBUG_TEMP_FLAG;
-#define DEBUG_OVERRIDE(state) { state ? ++DEBUG_OVERRIDE_FLAG : --DEBUG_OVERRIDE_FLAG; }
-#define DEBUG_ONCE if ((DEBUG_TEMP_FLAG = DEBUG_OVERRIDE_FLAG) && 0) ; else for (static int DEBUG_ONCE_FLAG = false; !DEBUG_ONCE_FLAG || DEBUG_TEMP_FLAG; DEBUG_ONCE_FLAG = true, DEBUG_TEMP_FLAG = false)
-#define DEBUG_ONCE_STR(str) DEBUG_ONCE qDebug() << (str);
-#endif
-
-#ifdef Q_WS_X11
-static bool qt_nvidiaFboNeedsFinish = false;
-#endif
-
-static inline void qt_glColor4ubv(unsigned char *col)
-{
- glColor4f(col[0]/255.0f, col[1]/255.0f, col[2]/255.0f, col[3]/255.0f);
-}
-
-struct QT_PointF {
- qreal x;
- qreal y;
-};
-
-struct QGLTrapezoid
-{
- QGLTrapezoid()
- {}
-
- QGLTrapezoid(qreal top_, qreal bottom_, qreal topLeftX_, qreal topRightX_, qreal bottomLeftX_, qreal bottomRightX_)
- : top(top_),
- bottom(bottom_),
- topLeftX(topLeftX_),
- topRightX(topRightX_),
- bottomLeftX(bottomLeftX_),
- bottomRightX(bottomRightX_)
- {}
-
- const QGLTrapezoid translated(const QPointF &delta) const;
-
- qreal top;
- qreal bottom;
- qreal topLeftX;
- qreal topRightX;
- qreal bottomLeftX;
- qreal bottomRightX;
-};
-
-const QGLTrapezoid QGLTrapezoid::translated(const QPointF &delta) const
-{
- QGLTrapezoid trap(*this);
- trap.top += delta.y();
- trap.bottom += delta.y();
- trap.topLeftX += delta.x();
- trap.topRightX += delta.x();
- trap.bottomLeftX += delta.x();
- trap.bottomRightX += delta.x();
- return trap;
-}
-
-
-class QOpenGLImmediateModeTessellator;
-class QGLMaskGenerator;
-class QGLOffscreen;
-
-class QGLMaskTextureCache
-{
-public:
- void setOffscreenSize(const QSize &offscreenSize);
- void setDrawableSize(const QSize &drawableSize);
-
- struct CacheLocation {
- QRect rect;
- int channel;
-
- QRect screen_rect;
- };
-
- struct CacheInfo {
- inline CacheInfo(const QPainterPath &p, const QTransform &m, qreal w = -1) :
- path(p), matrix(m), stroke_width(w), age(0) {}
-
- QPainterPath path;
- QTransform matrix;
- qreal stroke_width;
-
- CacheLocation loc;
-
- int age;
- };
-
- struct QuadTreeNode {
- quint64 key;
-
- int largest_available_block;
- int largest_used_block;
- };
-
- CacheLocation getMask(QGLMaskGenerator &maskGenerator, QOpenGLPaintEnginePrivate *engine);
-
- typedef QMultiHash<quint64, CacheInfo> QGLTextureCacheHash;
-
- enum {block_size = 64};
-
- // throw out keys that are too old
- void maintainCache();
- void clearCache();
-
-private:
- quint64 hash(const QPainterPath &p, const QTransform &m, qreal w);
-
- void createMask(quint64 key, CacheInfo &info, QGLMaskGenerator &maskGenerator);
-
- QSize offscreenSize;
- QSize drawableSize;
-
- QGLTextureCacheHash cache;
-
- QVector<QuadTreeNode> occupied_quadtree[4];
-
- void quadtreeUpdate(int channel, int node, int current_block_size);
- void quadtreeAllocate(quint64 key, const QSize &size, QRect *rect, int *channel);
-
- bool quadtreeFindAvailableLocation(const QSize &size, QRect *rect, int *channel);
- void quadtreeFindExistingLocation(const QSize &size, QRect *rect, int *channel);
-
- void quadtreeInsert(int channel, quint64 key, const QRect &rect, int node = 0);
- void quadtreeClear(int channel, const QRect &rect, int node = 0);
-
- int quadtreeBlocksize(int node);
- QPoint quadtreeLocation(int node);
-
- QOpenGLPaintEnginePrivate *engine;
-};
-
-Q_GLOBAL_STATIC(QGLMaskTextureCache, qt_mask_texture_cache)
-
-class QGLOffscreen : public QObject
-{
- Q_OBJECT
-public:
- QGLOffscreen()
- : QObject(),
- offscreen(0),
- ctx(0),
- mask_dim(0),
- activated(false),
- bound(false)
- {
- connect(QGLSignalProxy::instance(),
- SIGNAL(aboutToDestroyContext(const QGLContext*)),
- SLOT(cleanupGLContextRefs(const QGLContext*)));
- }
-
- inline void setDevice(QPaintDevice *pdev);
-
- void begin();
- void end();
-
- inline void bind();
- inline void release();
-
- inline bool isBound() const;
-
- inline QSize drawableSize() const;
- inline QSize offscreenSize() const;
-
- inline GLuint offscreenTexture() const;
-
- QGLContext *context() const;
-
- static bool isSupported();
-
- inline void initialize();
-
- inline bool isValid() const;
-
-public Q_SLOTS:
- void cleanupGLContextRefs(const QGLContext *context) {
- if (context == ctx) {
- delete offscreen;
- ctx = 0;
- offscreen = 0;
- mask_dim = 0;
- }
- }
-
-private:
- QGLPaintDevice* device;
-
- QGLFramebufferObject *offscreen;
- QGLContext *ctx;
-
- // dimensions of mask texture (square)
- int mask_dim;
- QSize last_failed_size;
-
- bool drawable_fbo;
-
- bool activated;
- bool initialized;
-
- bool bound;
-};
-
-inline void QGLOffscreen::setDevice(QPaintDevice *pdev)
-{
- if (pdev->devType() == QInternal::OpenGL)
- device = static_cast<QGLPaintDevice*>(pdev);
- else
- device = QGLPaintDevice::getDevice(pdev);
-
- if (!device)
- return;
-
- drawable_fbo = (pdev->devType() == QInternal::FramebufferObject);
-}
-
-void QGLOffscreen::begin()
-{
-#ifndef QT_OPENGL_ES
- initialized = false;
-
- if (activated)
- initialize();
-#endif
-}
-
-void QGLOffscreen::initialize()
-{
-#ifndef QT_OPENGL_ES
- if (initialized)
- return;
-
- activated = true;
- initialized = true;
-
- int dim = qMax(2048, static_cast<int>(qt_next_power_of_two(qMax(device->size().width(), device->size().height()))));
-
- bool shared_context = QGLContext::areSharing(device->context(), ctx);
- bool would_fail = last_failed_size.isValid() &&
- (device->size().width() >= last_failed_size.width() ||
- device->size().height() >= last_failed_size.height());
- bool needs_refresh = dim > mask_dim || !shared_context;
-
- if (needs_refresh && !would_fail) {
- DEBUG_ONCE qDebug() << "QGLOffscreen::initialize(): creating offscreen of size" << dim;
- delete offscreen;
- offscreen = new QGLFramebufferObject(dim, dim, GLenum(GL_TEXTURE_2D));
- mask_dim = dim;
-
- if (!offscreen->isValid()) {
- qWarning("QGLOffscreen: Invalid offscreen fbo (size %dx%d)", mask_dim, mask_dim);
- delete offscreen;
- offscreen = 0;
- mask_dim = 0;
- last_failed_size = device->size();
- }
- }
-
- qt_mask_texture_cache()->setOffscreenSize(offscreenSize());
- qt_mask_texture_cache()->setDrawableSize(device->size());
- ctx = device->context();
-#endif
-}
-
-inline bool QGLOffscreen::isValid() const
-{
- return offscreen;
-}
-
-void QGLOffscreen::end()
-{
- if (bound)
- release();
-#ifdef DEBUG_DISPLAY_MASK_TEXTURE
- glReadBuffer(GL_BACK);
- glDrawBuffer(GL_BACK);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- glColor4f(1, 1, 1, 1);
- glDisable(GL_DEPTH_TEST);
- glBlendFunc(GL_ONE, GL_ZERO);
- glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
- glEnable(GL_TEXTURE_2D);
- glBindTexture(GL_TEXTURE_2D, offscreen->texture());
-
- glBegin(GL_QUADS);
- glTexCoord2f(0.0, 1.0); glVertex2f(0.0, 0.0);
- glTexCoord2f(1.0, 1.0); glVertex2f(drawable.size().width(), 0.0);
- glTexCoord2f(1.0, 0.0); glVertex2f(drawable.size().width(), drawable.size().height());
- glTexCoord2f(0.0, 0.0); glVertex2f(0.0, drawable.size().height());
- glEnd();
-
- glBindTexture(GL_TEXTURE_2D, 0);
- glDisable(GL_TEXTURE_2D);
-#endif
-}
-
-inline void QGLOffscreen::bind()
-{
-#ifndef QT_OPENGL_ES
- Q_ASSERT(initialized);
-
- if (!offscreen || bound)
- return;
-
- DEBUG_ONCE qDebug() << "QGLOffscreen: binding offscreen";
- offscreen->bind();
-
- bound = true;
-
- glViewport(0, 0, offscreenSize().width(), offscreenSize().height());
-
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(0, offscreenSize().width(), offscreenSize().height(), 0, -999999, 999999);
- glMatrixMode(GL_MODELVIEW);
-#endif
-}
-
-inline void QGLOffscreen::release()
-{
-#ifndef QT_OPENGL_ES
- if (!offscreen || !bound)
- return;
-
-#ifdef Q_WS_X11
- // workaround for bug in nvidia driver versions 9x.xx
- if (qt_nvidiaFboNeedsFinish)
- glFinish();
-#endif
-
- DEBUG_ONCE_STR("QGLOffscreen: releasing offscreen");
-
- if (drawable_fbo)
- device->ensureActiveTarget(); //###
- else
- offscreen->release();
-
- QSize sz(device->size());
- glViewport(0, 0, sz.width(), sz.height());
-
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
-#ifndef QT_OPENGL_ES
- glOrtho(0, sz.width(), sz.height(), 0, -999999, 999999);
-#else
- glOrthof(0, sz.width(), sz.height(), 0, -999999, 999999);
-#endif
- glMatrixMode(GL_MODELVIEW);
-
- bound = false;
-#endif
-}
-
-inline bool QGLOffscreen::isBound() const
-{
- return bound;
-}
-
-inline QSize QGLOffscreen::drawableSize() const
-{
- return device->size();
-}
-
-inline QSize QGLOffscreen::offscreenSize() const
-{
- return QSize(mask_dim, mask_dim);
-}
-
-inline GLuint QGLOffscreen::offscreenTexture() const
-{
- return offscreen ? offscreen->texture() : 0;
-}
-
-inline QGLContext *QGLOffscreen::context() const
-{
- return ctx;
-}
-
-bool QGLOffscreen::isSupported()
-{
- return (QGLExtensions::glExtensions() & QGLExtensions::FramebufferObject); // for fbo
-}
-
-struct QDrawQueueItem
-{
- QDrawQueueItem(qreal _opacity,
- QBrush _brush,
- const QPointF &_brush_origion,
- QPainter::CompositionMode _composition_mode,
- const QTransform &_matrix,
- QGLMaskTextureCache::CacheLocation _location)
- : opacity(_opacity),
- brush(_brush),
- brush_origin(_brush_origion),
- composition_mode(_composition_mode),
- matrix(_matrix),
- location(_location) {}
- qreal opacity;
- QBrush brush;
- QPointF brush_origin;
- QPainter::CompositionMode composition_mode;
-
- QTransform matrix;
- QGLMaskTextureCache::CacheLocation location;
-};
-
-////////// GL program cache: start
-
-struct GLProgram {
- int brush; // brush index or mask index
- int mode; // composition mode index
- bool mask;
- GLuint program;
-};
-
-typedef QMultiHash<const QGLContext *, GLProgram> QGLProgramHash;
-
-class QGLProgramCache : public QObject
-{
- Q_OBJECT
-public:
- QGLProgramCache() {
- // we have to know when a context is deleted so we can free
- // any program handles it holds
- connect(QGLSignalProxy::instance(), SIGNAL(aboutToDestroyContext(const QGLContext*)),
- SLOT(cleanupPrograms(const QGLContext*)));
-
- }
- ~QGLProgramCache() {
- // at this point the cache should contain 0 elements
- // Q_ASSERT(program.size() == 0);
- }
-
- GLuint getProgram(const QGLContext *ctx, int brush, int mode, bool mask_mode)
- {
- // 1. see if we have an entry for the ctx context
- QList<GLProgram> progs = programs.values(ctx);
- for (int i=0; i<progs.size(); ++i) {
- const GLProgram &prg = progs.at(i);
- if (mask_mode) {
- if (prg.mask && prg.brush == brush)
- return prg.program;
- } else {
- if (!prg.mask && prg.brush == brush && prg.mode == mode)
- return prg.program;
- }
- }
-
- // 2. try to find a match in a shared context, and update the
- // hash with the entry found
- QList<const QGLContext *> contexts = programs.uniqueKeys();
- for (int i=0; i<contexts.size(); ++i) {
- const QGLContext *cx = contexts.at(i);
- if (cx != ctx && QGLContext::areSharing(cx, ctx)) {
- QList<GLProgram> progs = programs.values(cx);
- for (int k=0; k<progs.size(); ++k) {
- const GLProgram &prg = progs.at(k);
- if (mask_mode) {
- if (prg.mask && prg.brush == brush) {
- programs.insert(ctx, prg);
- return prg.program;
- }
- } else {
- if (!prg.mask && prg.brush == brush && prg.mode == mode) {
- programs.insert(ctx, prg);
- return prg.program;
- }
- }
- }
- }
- }
-
- // 3. compile a new program and place it into the cache
- // NB! assumes ctx is the current GL context
- GLProgram prg;
- prg.brush = brush;
- prg.mode = mode;
- prg.mask = mask_mode;
- glGenProgramsARB(1, &prg.program);
- glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, prg.program);
- const char *src = mask_mode
- ? mask_fragment_program_sources[brush]
- : painter_fragment_program_sources[brush][mode];
- // necessary for .NET 2002, apparently
- const GLbyte *gl_src = reinterpret_cast<const GLbyte *>(src);
-
- while (glGetError() != GL_NO_ERROR) {} // reset error state
- glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
- int(strlen(src)), gl_src);
- if (glGetError() != GL_NO_ERROR) {
-// qDebug() << "QGLProgramCache: Unable to compile fragment program.";
- glDeleteProgramsARB(1, &prg.program);
- return 0;
- }
-
-// qDebug() << "QGLProgramCache: Creating GL program:" << prg.program << hex << ctx;
- programs.insert(ctx, prg);
- return prg.program;
- }
-
-public Q_SLOTS:
- void cleanupPrograms(const QGLContext *context)
- {
- QGLProgramHash::iterator it = programs.begin();
- while (it != programs.end()) {
- if (it.key() == context) {
- if (!context->isSharing()) {
- // the ctx variable below is needed for the glDeleteProgramARB call
- // since it is resolved from our extension system
- // NB! assumes context is the current GL context
- const QGLContext *ctx = context;
- // qDebug() << "QGLProgramHash: Deleting GL program:" << it.value().program << hex << it.key();
- glDeleteProgramsARB(1, &it.value().program);
- }
- it = programs.erase(it);
- } else {
- ++it;
- }
- }
- }
-
-private:
- QGLProgramHash programs;
-};
-
-Q_GLOBAL_STATIC(QGLProgramCache, qt_gl_program_cache)
-
-////////// GL program cache: end
-
-class QOpenGLPaintEnginePrivate;
-class QGLPrivateCleanup : public QObject
-{
- Q_OBJECT
-public:
- QGLPrivateCleanup(QOpenGLPaintEnginePrivate *priv)
- : p(priv)
- {
- connect(QGLSignalProxy::instance(),
- SIGNAL(aboutToDestroyContext(const QGLContext*)),
- SLOT(cleanupGLContextRefs(const QGLContext*)));
- }
-
-public Q_SLOTS:
- void cleanupGLContextRefs(const QGLContext *context);
-
-private:
- QOpenGLPaintEnginePrivate *p;
-};
-
-class QOpenGLPaintEnginePrivate : public QPaintEngineExPrivate
-{
- Q_DECLARE_PUBLIC(QOpenGLPaintEngine)
-public:
- QOpenGLPaintEnginePrivate()
- : opacity(1)
- , composition_mode(QPainter::CompositionMode_SourceOver)
- , has_fast_pen(false)
- , use_stencil_method(false)
- , dirty_drawable_texture(false)
- , has_stencil_face_ext(false)
- , use_fragment_programs(false)
- , high_quality_antialiasing(false)
- , use_smooth_pixmap_transform(false)
- , use_emulation(false)
- , txop(QTransform::TxNone)
- , inverseScale(1)
- , moveToCount(0)
- , last_created_state(0)
- , shader_ctx(0)
- , grad_palette(0)
- , tess_points(0)
- , drawable_texture(0)
- , ref_cleaner(this)
- {}
-
- inline void setGLPen(const QColor &c) {
- uint alpha = qRound(c.alpha() * opacity);
- pen_color[0] = qt_div_255(c.red() * alpha);
- pen_color[1] = qt_div_255(c.green() * alpha);
- pen_color[2] = qt_div_255(c.blue() * alpha);
- pen_color[3] = alpha;
- }
-
- inline void setGLBrush(const QColor &c) {
- uint alpha = qRound(c.alpha() * opacity);
- brush_color[0] = qt_div_255(c.red() * alpha);
- brush_color[1] = qt_div_255(c.green() * alpha);
- brush_color[2] = qt_div_255(c.blue() * alpha);
- brush_color[3] = alpha;
- }
-
- inline void setGradientOps(const QBrush &brush, const QRectF &bounds);
- void createGradientPaletteTexture(const QGradient& g);
-
- void updateGradient(const QBrush &brush, const QRectF &bounds);
-
- inline void lineToStencil(qreal x, qreal y);
- inline void curveToStencil(const QPointF &cp1, const QPointF &cp2, const QPointF &ep);
- void pathToVertexArrays(const QPainterPath &path);
- void fillVertexArray(Qt::FillRule fillRule);
- void drawVertexArrays();
- void fillPath(const QPainterPath &path);
- void fillPolygon_dev(const QPointF *polygonPoints, int pointCount,
- Qt::FillRule fill);
-
- void drawFastRect(const QRectF &rect);
- void strokePath(const QPainterPath &path, bool use_cache);
- void strokePathFastPen(const QPainterPath &path, bool needsResolving);
- void strokeLines(const QPainterPath &path);
-
- void updateDepthClip();
- void systemStateChanged();
-
- void cleanupGLContextRefs(const QGLContext *context) {
- if (context == shader_ctx)
- shader_ctx = 0;
- }
-
- inline void updateFastPen() {
- qreal pen_width = cpen.widthF();
- has_fast_pen =
- ((pen_width == 0 || (pen_width <= 1 && matrix.type() <= QTransform::TxTranslate))
- || cpen.isCosmetic())
- && cpen.style() == Qt::SolidLine
- && cpen.isSolid();
-
- }
-
- void disableClipping();
- void enableClipping();
- void ensureDrawableTexture();
-
- QPen cpen;
- QBrush cbrush;
- Qt::BrushStyle brush_style;
- QPointF brush_origin;
- Qt::BrushStyle pen_brush_style;
- qreal opacity;
- QPainter::CompositionMode composition_mode;
-
- Qt::BrushStyle current_style;
-
- uint has_pen : 1;
- uint has_brush : 1;
- uint has_fast_pen : 1;
- uint use_stencil_method : 1;
- uint dirty_drawable_texture : 1;
- uint has_stencil_face_ext : 1;
- uint use_fragment_programs : 1;
- uint high_quality_antialiasing : 1;
- uint has_antialiasing : 1;
- uint has_fast_composition_mode : 1;
- uint use_smooth_pixmap_transform : 1;
- uint use_system_clip : 1;
- uint use_emulation : 1;
-
- QRegion dirty_stencil;
-
- void updateUseEmulation();
-
- QTransform matrix;
- GLubyte pen_color[4];
- GLubyte brush_color[4];
- QTransform::TransformationType txop;
- QGLPaintDevice* device;
- QGLOffscreen offscreen;
-
- qreal inverseScale;
-
- int moveToCount;
- QPointF path_start;
-
- bool isFastRect(const QRectF &r);
-
- void drawImageAsPath(const QRectF &r, const QImage &img, const QRectF &sr);
- void drawTiledImageAsPath(const QRectF &r, const QImage &img, qreal sx, qreal sy, const QPointF &offset);
-
- void drawOffscreenPath(const QPainterPath &path);
-
- void composite(const QRectF &rect, const QPoint &maskOffset = QPoint());
- void composite(GLuint primitive, const GLfloat *vertexArray, int vertexCount, const QPoint &maskOffset = QPoint());
-
- bool createFragmentPrograms();
- void deleteFragmentPrograms();
- void updateFragmentProgramData(int locations[]);
-
- void cacheItemErased(int channel, const QRect &rect);
-
- void addItem(const QGLMaskTextureCache::CacheLocation &location);
- void drawItem(const QDrawQueueItem &item);
- void flushDrawQueue();
-
- void copyDrawable(const QRectF &rect);
-
- void updateGLMatrix() const;
-
- mutable QPainterState *last_created_state;
-
- QGLContext *shader_ctx;
- GLuint grad_palette;
-
- GLuint painter_fragment_programs[num_fragment_brushes][num_fragment_composition_modes];
- GLuint mask_fragment_programs[num_fragment_masks];
-
- float inv_matrix_data[3][4];
- float fmp_data[4];
- float fmp2_m_radius2_data[4];
- float angle_data[4];
- float linear_data[4];
-
- float porterduff_ab_data[4];
- float porterduff_xyz_data[4];
-
- float mask_offset_data[4];
- float mask_channel_data[4];
-
- FragmentBrushType fragment_brush;
- FragmentCompositionModeType fragment_composition_mode;
-
- void setPorterDuffData(float a, float b, float x, float y, float z);
- void setInvMatrixData(const QTransform &inv_matrix);
-
- qreal max_x;
- qreal max_y;
- qreal min_x;
- qreal min_y;
-
- QDataBuffer<QPointF> tess_points;
- QVector<int> tess_points_stops;
-
- GLdouble projection_matrix[4][4];
-
-#if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_2)
- GLfloat mv_matrix[4][4];
-#else
- GLdouble mv_matrix[4][4];
-#endif
-
- QList<QDrawQueueItem> drawQueue;
-
- GLuint drawable_texture;
- QSize drawable_texture_size;
-
- int max_texture_size;
-
- QGLPrivateCleanup ref_cleaner;
- friend class QGLMaskTextureCache;
-};
-
-class QOpenGLCoordinateOffset
-{
-public:
- QOpenGLCoordinateOffset(QOpenGLPaintEnginePrivate *d);
- ~QOpenGLCoordinateOffset();
-
- static void enableOffset(QOpenGLPaintEnginePrivate *d);
- static void disableOffset(QOpenGLPaintEnginePrivate *d);
-
-private:
- QOpenGLPaintEnginePrivate *d;
-};
-
-QOpenGLCoordinateOffset::QOpenGLCoordinateOffset(QOpenGLPaintEnginePrivate *d_)
- : d(d_)
-{
- enableOffset(d);
-}
-
-void QOpenGLCoordinateOffset::enableOffset(QOpenGLPaintEnginePrivate *d)
-{
- if (!d->has_antialiasing) {
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- d->mv_matrix[3][0] += 0.5;
- d->mv_matrix[3][1] += 0.5;
- d->updateGLMatrix();
- }
-}
-
-QOpenGLCoordinateOffset::~QOpenGLCoordinateOffset()
-{
- disableOffset(d);
-}
-
-void QOpenGLCoordinateOffset::disableOffset(QOpenGLPaintEnginePrivate *d)
-{
- if (!d->has_antialiasing) {
- glMatrixMode(GL_MODELVIEW);
- glPopMatrix();
- d->mv_matrix[3][0] -= 0.5;
- d->mv_matrix[3][1] -= 0.5;
- }
-}
-
-void QGLPrivateCleanup::cleanupGLContextRefs(const QGLContext *context)
-{
- p->cleanupGLContextRefs(context);
-}
-
-
-static inline void updateTextureFilter(GLenum target, GLenum wrapMode, bool smoothPixmapTransform)
-{
- if (smoothPixmapTransform) {
- glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- } else {
- glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- }
- glTexParameterf(target, GL_TEXTURE_WRAP_S, wrapMode);
- glTexParameterf(target, GL_TEXTURE_WRAP_T, wrapMode);
-}
-
-static inline QPainterPath strokeForPath(const QPainterPath &path, const QPen &cpen) {
- QPainterPathStroker stroker;
- if (cpen.style() == Qt::CustomDashLine)
- stroker.setDashPattern(cpen.dashPattern());
- else
- stroker.setDashPattern(cpen.style());
-
- stroker.setCapStyle(cpen.capStyle());
- stroker.setJoinStyle(cpen.joinStyle());
- stroker.setMiterLimit(cpen.miterLimit());
- stroker.setDashOffset(cpen.dashOffset());
-
- qreal width = cpen.widthF();
- if (width == 0)
- stroker.setWidth(1);
- else
- stroker.setWidth(width);
-
- QPainterPath stroke = stroker.createStroke(path);
- stroke.setFillRule(Qt::WindingFill);
- return stroke;
-}
-
-class QGLStrokeCache
-{
- struct CacheInfo
- {
- inline CacheInfo(QPainterPath p, QPainterPath sp, QPen stroke_pen) :
- path(p), stroked_path(sp), pen(stroke_pen) {}
- QPainterPath path;
- QPainterPath stroked_path;
- QPen pen;
- };
-
- typedef QMultiHash<quint64, CacheInfo> QGLStrokeTableHash;
-
-public:
- inline QPainterPath getStrokedPath(const QPainterPath &path, const QPen &pen) {
- quint64 hash_val = 0;
-
- for (int i = 0; i < path.elementCount() && i <= 2; i++) {
- hash_val += quint64(path.elementAt(i).x);
- hash_val += quint64(path.elementAt(i).y);
- }
-
- QGLStrokeTableHash::const_iterator it = cache.constFind(hash_val);
-
- if (it == cache.constEnd())
- return addCacheElement(hash_val, path, pen);
- else {
- do {
- const CacheInfo &cache_info = it.value();
- if (cache_info.path == path && cache_info.pen == pen)
- return cache_info.stroked_path;
- ++it;
- } while (it != cache.constEnd() && it.key() == hash_val);
- // an exact match for this path was not found, create new cache element
- return addCacheElement(hash_val, path, pen);
- }
- }
-
-protected:
- inline int maxCacheSize() const { return 500; }
- QPainterPath addCacheElement(quint64 hash_val, QPainterPath path, const QPen &pen) {
- if (cache.size() == maxCacheSize()) {
- int elem_to_remove = qrand() % maxCacheSize();
- cache.remove(cache.keys()[elem_to_remove]); // may remove more than 1, but OK
- }
- QPainterPath stroke = strokeForPath(path, pen);
- CacheInfo cache_entry(path, stroke, pen);
- return cache.insert(hash_val, cache_entry).value().stroked_path;
- }
-
- QGLStrokeTableHash cache;
-};
-
-Q_GLOBAL_STATIC(QGLStrokeCache, qt_opengl_stroke_cache)
-
-class QGLGradientCache : public QObject
-{
- Q_OBJECT
- struct CacheInfo
- {
- inline CacheInfo(QGradientStops s, qreal op, QGradient::InterpolationMode mode) :
- stops(s), opacity(op), interpolationMode(mode) {}
-
- GLuint texId;
- QGradientStops stops;
- qreal opacity;
- QGradient::InterpolationMode interpolationMode;
- };
-
- typedef QMultiHash<quint64, CacheInfo> QGLGradientColorTableHash;
-
-public:
- QGLGradientCache() : QObject(), buffer_ctx(0)
- {
- connect(QGLSignalProxy::instance(),
- SIGNAL(aboutToDestroyContext(const QGLContext*)),
- SLOT(cleanupGLContextRefs(const QGLContext*)));
- }
-
- inline GLuint getBuffer(const QGradient &gradient, qreal opacity, QGLContext *ctx) {
- if (buffer_ctx && !QGLContext::areSharing(buffer_ctx, ctx))
- cleanCache();
-
- buffer_ctx = ctx;
-
- quint64 hash_val = 0;
-
- QGradientStops stops = gradient.stops();
- for (int i = 0; i < stops.size() && i <= 2; i++)
- hash_val += stops[i].second.rgba();
-
- QGLGradientColorTableHash::const_iterator it = cache.constFind(hash_val);
-
- if (it == cache.constEnd())
- return addCacheElement(hash_val, gradient, opacity);
- else {
- do {
- const CacheInfo &cache_info = it.value();
- if (cache_info.stops == stops && cache_info.opacity == opacity && cache_info.interpolationMode == gradient.interpolationMode()) {
- return cache_info.texId;
- }
- ++it;
- } while (it != cache.constEnd() && it.key() == hash_val);
- // an exact match for these stops and opacity was not found, create new cache
- return addCacheElement(hash_val, gradient, opacity);
- }
- }
-
- inline int paletteSize() const { return 1024; }
-
-protected:
- inline int maxCacheSize() const { return 60; }
- inline void generateGradientColorTable(const QGradient& g,
- uint *colorTable,
- int size, qreal opacity) const;
- GLuint addCacheElement(quint64 hash_val, const QGradient &gradient, qreal opacity) {
- if (cache.size() == maxCacheSize()) {
- int elem_to_remove = qrand() % maxCacheSize();
- quint64 key = cache.keys()[elem_to_remove];
-
- // need to call glDeleteTextures on each removed cache entry:
- QGLGradientColorTableHash::const_iterator it = cache.constFind(key);
- do {
- glDeleteTextures(1, &it.value().texId);
- } while (++it != cache.constEnd() && it.key() == key);
- cache.remove(key); // may remove more than 1, but OK
- }
- CacheInfo cache_entry(gradient.stops(), opacity, gradient.interpolationMode());
- uint buffer[1024];
- generateGradientColorTable(gradient, buffer, paletteSize(), opacity);
- glGenTextures(1, &cache_entry.texId);
-#ifndef QT_OPENGL_ES
- glBindTexture(GL_TEXTURE_1D, cache_entry.texId);
- glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA, paletteSize(),
- 0, GL_BGRA, GL_UNSIGNED_BYTE, buffer);
-#else
- // create 2D one-line texture instead. This requires an impl of manual GL_TEXGEN for all primitives
-#endif
- return cache.insert(hash_val, cache_entry).value().texId;
- }
-
- void cleanCache() {
- QGLShareContextScope scope(buffer_ctx);
- QGLGradientColorTableHash::const_iterator it = cache.constBegin();
- for (; it != cache.constEnd(); ++it) {
- const CacheInfo &cache_info = it.value();
- glDeleteTextures(1, &cache_info.texId);
- }
- cache.clear();
- }
-
- QGLGradientColorTableHash cache;
-
- QGLContext *buffer_ctx;
-
-public Q_SLOTS:
- void cleanupGLContextRefs(const QGLContext *context) {
- if (context == buffer_ctx) {
- cleanCache();
- buffer_ctx = 0;
- }
- }
-};
-
-static inline uint endianColor(uint c)
-{
-#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
- return c;
-#else
- return ( (c << 24) & 0xff000000)
- | ((c >> 24) & 0x000000ff)
- | ((c << 8) & 0x00ff0000)
- | ((c >> 8) & 0x0000ff00);
-#endif // Q_BYTE_ORDER
-}
-
-void QGLGradientCache::generateGradientColorTable(const QGradient& gradient, uint *colorTable, int size, qreal opacity) const
-{
- int pos = 0;
- QGradientStops s = gradient.stops();
- QVector<uint> colors(s.size());
-
- for (int i = 0; i < s.size(); ++i)
- colors[i] = s[i].second.rgba();
-
- bool colorInterpolation = (gradient.interpolationMode() == QGradient::ColorInterpolation);
-
- uint alpha = qRound(opacity * 256);
- uint current_color = ARGB_COMBINE_ALPHA(colors[0], alpha);
- qreal incr = 1.0 / qreal(size);
- qreal fpos = 1.5 * incr;
- colorTable[pos++] = endianColor(PREMUL(current_color));
-
- while (fpos <= s.first().first) {
- colorTable[pos] = colorTable[pos - 1];
- pos++;
- fpos += incr;
- }
-
- if (colorInterpolation)
- current_color = PREMUL(current_color);
-
- for (int i = 0; i < s.size() - 1; ++i) {
- qreal delta = 1/(s[i+1].first - s[i].first);
- uint next_color = ARGB_COMBINE_ALPHA(colors[i+1], alpha);
- if (colorInterpolation)
- next_color = PREMUL(next_color);
-
- while (fpos < s[i+1].first && pos < size) {
- int dist = int(256 * ((fpos - s[i].first) * delta));
- int idist = 256 - dist;
- if (colorInterpolation)
- colorTable[pos] = endianColor(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist));
- else
- colorTable[pos] = endianColor(PREMUL(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist)));
- ++pos;
- fpos += incr;
- }
- current_color = next_color;
- }
-
- Q_ASSERT(s.size() > 0);
-
- uint last_color = endianColor(PREMUL(ARGB_COMBINE_ALPHA(colors[s.size() - 1], alpha)));
- for (;pos < size; ++pos)
- colorTable[pos] = last_color;
-
- // Make sure the last color stop is represented at the end of the table
- colorTable[size-1] = last_color;
-}
-
-#ifndef Q_WS_QWS
-Q_GLOBAL_STATIC(QGLGradientCache, qt_opengl_gradient_cache)
-#endif
-
-void QOpenGLPaintEnginePrivate::createGradientPaletteTexture(const QGradient& g)
-{
-#ifdef QT_OPENGL_ES //###
- Q_UNUSED(g);
-#else
- GLuint texId = qt_opengl_gradient_cache()->getBuffer(g, opacity, device->context());
- glBindTexture(GL_TEXTURE_1D, texId);
- grad_palette = texId;
- if (g.spread() == QGradient::RepeatSpread || g.type() == QGradient::ConicalGradient)
- glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- else if (g.spread() == QGradient::ReflectSpread)
- glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT_IBM);
- else
- glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-
- glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-
-#endif
-}
-
-
-inline void QOpenGLPaintEnginePrivate::setGradientOps(const QBrush &brush, const QRectF &bounds)
-{
- current_style = brush.style();
-
- if (current_style < Qt::LinearGradientPattern || current_style > Qt::ConicalGradientPattern) {
- setGLBrush(brush.color());
- qt_glColor4ubv(brush_color);
- }
-
- updateGradient(brush, bounds);
-
-#ifndef QT_OPENGL_ES //### GLES does not have GL_TEXTURE_GEN_ so we are falling back for gradients
- glDisable(GL_TEXTURE_GEN_S);
- glDisable(GL_TEXTURE_1D);
-
- if (current_style == Qt::LinearGradientPattern) {
- if (high_quality_antialiasing || !has_fast_composition_mode) {
- fragment_brush = FRAGMENT_PROGRAM_BRUSH_LINEAR;
- } else {
- glEnable(GL_TEXTURE_GEN_S);
- glEnable(GL_TEXTURE_1D);
- }
- } else {
- if (use_fragment_programs) {
- if (current_style == Qt::RadialGradientPattern)
- fragment_brush = FRAGMENT_PROGRAM_BRUSH_RADIAL;
- else if (current_style == Qt::ConicalGradientPattern)
- fragment_brush = FRAGMENT_PROGRAM_BRUSH_CONICAL;
- else if (current_style == Qt::SolidPattern)
- fragment_brush = FRAGMENT_PROGRAM_BRUSH_SOLID;
- else if (current_style == Qt::TexturePattern && !brush.texture().isQBitmap())
- fragment_brush = FRAGMENT_PROGRAM_BRUSH_TEXTURE;
- else
- fragment_brush = FRAGMENT_PROGRAM_BRUSH_PATTERN;
- }
- }
-#endif
-}
-
-QOpenGLPaintEngine::QOpenGLPaintEngine()
- : QPaintEngineEx(*(new QOpenGLPaintEnginePrivate))
-{
-}
-
-QOpenGLPaintEngine::~QOpenGLPaintEngine()
-{
-}
-
-bool QOpenGLPaintEngine::begin(QPaintDevice *pdev)
-{
- Q_D(QOpenGLPaintEngine);
-
- if (pdev->devType() == QInternal::OpenGL)
- d->device = static_cast<QGLPaintDevice*>(pdev);
- else
- d->device = QGLPaintDevice::getDevice(pdev);
-
- if (!d->device)
- return false;
-
- d->offscreen.setDevice(pdev);
- d->has_fast_pen = false;
- d->inverseScale = 1;
- d->opacity = 1;
- d->device->beginPaint();
- d->matrix = QTransform();
- d->has_antialiasing = false;
- d->high_quality_antialiasing = false;
-
- QSize sz(d->device->size());
- d->dirty_stencil = QRect(0, 0, sz.width(), sz.height());
-
- d->use_emulation = false;
-
- for (int i = 0; i < 4; ++i)
- for (int j = 0; j < 4; ++j)
- d->mv_matrix[i][j] = (i == j ? qreal(1) : qreal(0));
-
- bool has_frag_program = (QGLExtensions::glExtensions() & QGLExtensions::FragmentProgram)
- && (pdev->devType() != QInternal::Pixmap);
-
- QGLContext *ctx = const_cast<QGLContext *>(d->device->context());
- if (!ctx) {
- qWarning() << "QOpenGLPaintEngine: paint device doesn't have a valid GL context.";
- return false;
- }
-
- if (has_frag_program)
- has_frag_program = qt_resolve_frag_program_extensions(ctx) && qt_resolve_version_1_3_functions(ctx);
-
- d->use_stencil_method = d->device->format().stencil()
- && (QGLExtensions::glExtensions() & QGLExtensions::StencilWrap);
- if (d->device->format().directRendering()
- && (d->use_stencil_method && QGLExtensions::glExtensions() & QGLExtensions::StencilTwoSide))
- d->has_stencil_face_ext = qt_resolve_stencil_face_extension(ctx);
-
-#ifdef Q_WS_X11
- static bool nvidia_workaround_needs_init = true;
- if (nvidia_workaround_needs_init) {
- // nvidia 9x.xx unix drivers contain a bug which requires us to
- // call glFinish before releasing an fbo to avoid painting
- // artifacts
- const QByteArray versionString(reinterpret_cast<const char*>(glGetString(GL_VERSION)));
- const int pos = versionString.indexOf("NVIDIA");
- if (pos >= 0) {
- const float nvidiaDriverVersion = versionString.mid(pos + strlen("NVIDIA")).toFloat();
- qt_nvidiaFboNeedsFinish = nvidiaDriverVersion >= 90.0 && nvidiaDriverVersion < 100.0;
- }
- nvidia_workaround_needs_init = false;
- }
-#endif
-
-#ifndef QT_OPENGL_ES
- if (!ctx->d_ptr->internal_context) {
- glGetDoublev(GL_PROJECTION_MATRIX, &d->projection_matrix[0][0]);
- glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS);
- glPushAttrib(GL_ALL_ATTRIB_BITS);
-
- glDisableClientState(GL_EDGE_FLAG_ARRAY);
- glDisableClientState(GL_INDEX_ARRAY);
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- glDisable(GL_TEXTURE_1D);
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- glPixelTransferi(GL_MAP_COLOR, false);
- glPixelTransferi(GL_MAP_STENCIL, false);
- glDisable(GL_TEXTURE_GEN_S);
-
- glPixelStorei(GL_PACK_SWAP_BYTES, false);
- glPixelStorei(GL_PACK_LSB_FIRST, false);
- glPixelStorei(GL_PACK_ROW_LENGTH, 0);
- glPixelStorei(GL_PACK_SKIP_ROWS, 0);
- glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
- glPixelStorei(GL_PACK_ALIGNMENT, 4);
-
- glPixelStorei(GL_UNPACK_SWAP_BYTES, false);
- glPixelStorei(GL_UNPACK_LSB_FIRST, false);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
- glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
- glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
- glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
-
- if (QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_1_2) {
- glPixelStorei(GL_PACK_IMAGE_HEIGHT, 0);
- glPixelStorei(GL_PACK_SKIP_IMAGES, 0);
- glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0);
- glPixelStorei(GL_UNPACK_SKIP_IMAGES, 0);
- }
- }
-#endif
-
- if (!ctx->d_ptr->internal_context) {
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- glMatrixMode(GL_TEXTURE);
- glPushMatrix();
- glLoadIdentity();
- glDisableClientState(GL_COLOR_ARRAY);
- glDisableClientState(GL_NORMAL_ARRAY);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- glDisableClientState(GL_VERTEX_ARRAY);
-
- if (QGLExtensions::glExtensions() & QGLExtensions::SampleBuffers)
- glDisable(GL_MULTISAMPLE);
- glDisable(GL_TEXTURE_2D);
- if (QGLExtensions::glExtensions() & QGLExtensions::TextureRectangle)
- glDisable(GL_TEXTURE_RECTANGLE_NV);
- glDisable(GL_STENCIL_TEST);
- glDisable(GL_CULL_FACE);
- glDisable(GL_LIGHTING);
- glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
- }
-
- d->offscreen.begin();
-
- glViewport(0, 0, sz.width(), sz.height()); // XXX (Embedded): We need a solution for GLWidgets that draw in a part or a bigger surface...
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
-#ifdef QT_OPENGL_ES
- glOrthof(0, sz.width(), sz.height(), 0, -999999, 999999);
-#else
- glOrtho(0, sz.width(), sz.height(), 0, -999999, 999999);
-#endif
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- glEnable(GL_BLEND);
- d->composition_mode = QPainter::CompositionMode_SourceOver;
-
-#ifdef QT_OPENGL_ES
- d->max_texture_size = ctx->d_func()->maxTextureSize();
-#else
- bool shared_ctx = QGLContext::areSharing(d->device->context(), d->shader_ctx);
-
- if (shared_ctx) {
- d->max_texture_size = d->shader_ctx->d_func()->maxTextureSize();
- } else {
- d->max_texture_size = ctx->d_func()->maxTextureSize();
-
- if (d->shader_ctx) {
- d->shader_ctx->makeCurrent();
- glBindTexture(GL_TEXTURE_1D, 0);
- glDeleteTextures(1, &d->grad_palette);
-
- if (has_frag_program && d->use_fragment_programs)
- glDeleteTextures(1, &d->drawable_texture);
- ctx->makeCurrent();
- }
- d->shader_ctx = d->device->context();
- glGenTextures(1, &d->grad_palette);
-
- qt_mask_texture_cache()->clearCache();
- d->use_fragment_programs = has_frag_program;
- }
-
- if (d->use_fragment_programs && (!shared_ctx || sz.width() > d->drawable_texture_size.width()
- || sz.height() > d->drawable_texture_size.height()))
- {
- // delete old texture if size has increased, otherwise it was deleted earlier
- if (shared_ctx)
- glDeleteTextures(1, &d->drawable_texture);
-
- d->dirty_drawable_texture = true;
- d->drawable_texture_size = QSize(qt_next_power_of_two(sz.width()),
- qt_next_power_of_two(sz.height()));
- }
-#endif
-
- updateClipRegion(QRegion(), Qt::NoClip);
- penChanged();
- brushChanged();
- opacityChanged();
- compositionModeChanged();
- renderHintsChanged();
- transformChanged();
- return true;
-}
-
-bool QOpenGLPaintEngine::end()
-{
- Q_D(QOpenGLPaintEngine);
- d->flushDrawQueue();
- d->offscreen.end();
- QGLContext *ctx = const_cast<QGLContext *>(d->device->context());
- if (!ctx->d_ptr->internal_context) {
- glMatrixMode(GL_TEXTURE);
- glPopMatrix();
- glMatrixMode(GL_MODELVIEW);
- glPopMatrix();
- }
-#ifndef QT_OPENGL_ES
- if (ctx->d_ptr->internal_context) {
- glDisable(GL_SCISSOR_TEST);
- } else {
- glMatrixMode(GL_PROJECTION);
- glLoadMatrixd(&d->projection_matrix[0][0]);
- glPopAttrib();
- glPopClientAttrib();
- }
-#endif
- d->device->endPaint();
- qt_mask_texture_cache()->maintainCache();
-
-#if defined(Q_WS_X11)
- // clear out the references we hold for textures bound with the
- // texture_from_pixmap extension
- ctx->d_func()->boundPixmaps.clear();
-#endif
- return true;
-}
-
-void QOpenGLPaintEngine::updateState(const QPaintEngineState &state)
-{
- Q_D(QOpenGLPaintEngine);
- QPaintEngine::DirtyFlags flags = state.state();
-
- bool update_fast_pen = false;
-
- if (flags & DirtyOpacity) {
- update_fast_pen = true;
- d->opacity = state.opacity();
- if (d->opacity > 1.0f)
- d->opacity = 1.0f;
- if (d->opacity < 0.f)
- d->opacity = 0.f;
- // force update
- flags |= DirtyPen;
- flags |= DirtyBrush;
- }
-
- if (flags & DirtyTransform) {
- update_fast_pen = true;
- updateMatrix(state.transform());
- // brush setup depends on transform state
- if (state.brush().style() != Qt::NoBrush)
- flags |= DirtyBrush;
- }
-
- if (flags & DirtyPen) {
- update_fast_pen = true;
- updatePen(state.pen());
- }
-
- if (flags & (DirtyBrush | DirtyBrushOrigin)) {
- updateBrush(state.brush(), state.brushOrigin());
- }
-
- if (flags & DirtyFont) {
- updateFont(state.font());
- }
-
- if (state.state() & DirtyClipEnabled) {
- if (state.isClipEnabled())
- updateClipRegion(painter()->clipRegion(), Qt::ReplaceClip);
- else
- updateClipRegion(QRegion(), Qt::NoClip);
- }
-
- if (flags & DirtyClipPath) {
- updateClipRegion(QRegion(state.clipPath().toFillPolygon().toPolygon(),
- state.clipPath().fillRule()),
- state.clipOperation());
- }
-
- if (flags & DirtyClipRegion) {
- updateClipRegion(state.clipRegion(), state.clipOperation());
- }
-
- if (flags & DirtyHints) {
- updateRenderHints(state.renderHints());
- }
-
- if (flags & DirtyCompositionMode) {
- updateCompositionMode(state.compositionMode());
- }
-
- if (update_fast_pen) {
- Q_D(QOpenGLPaintEngine);
- qreal pen_width = d->cpen.widthF();
- d->has_fast_pen =
- ((pen_width == 0 || (pen_width <= 1 && d->txop <= QTransform::TxTranslate))
- || d->cpen.isCosmetic())
- && d->cpen.style() == Qt::SolidLine
- && d->cpen.isSolid();
- }
-}
-
-
-void QOpenGLPaintEnginePrivate::setInvMatrixData(const QTransform &inv_matrix)
-{
- inv_matrix_data[0][0] = inv_matrix.m11();
- inv_matrix_data[1][0] = inv_matrix.m21();
- inv_matrix_data[2][0] = inv_matrix.m31();
-
- inv_matrix_data[0][1] = inv_matrix.m12();
- inv_matrix_data[1][1] = inv_matrix.m22();
- inv_matrix_data[2][1] = inv_matrix.m32();
-
- inv_matrix_data[0][2] = inv_matrix.m13();
- inv_matrix_data[1][2] = inv_matrix.m23();
- inv_matrix_data[2][2] = inv_matrix.m33();
-}
-
-
-void QOpenGLPaintEnginePrivate::updateGradient(const QBrush &brush, const QRectF &)
-{
-#ifdef QT_OPENGL_ES
- Q_UNUSED(brush);
-#else
- bool has_mirrored_repeat = QGLExtensions::glExtensions() & QGLExtensions::MirroredRepeat;
- Qt::BrushStyle style = brush.style();
-
- QTransform m = brush.transform();
-
- if (has_mirrored_repeat && style == Qt::LinearGradientPattern) {
- const QLinearGradient *g = static_cast<const QLinearGradient *>(brush.gradient());
- QTransform m = brush.transform();
- QPointF realStart = g->start();
- QPointF realFinal = g->finalStop();
- QPointF start = m.map(realStart);
- QPointF stop;
-
- if (qFuzzyCompare(m.m11(), m.m22()) && m.m12() == 0.0 && m.m21() == 0.0) {
- // It is a simple uniform scale and/or translation
- stop = m.map(realFinal);
- } else {
- // It is not enough to just transform the endpoints.
- // We have to make sure the _pattern_ is transformed correctly.
-
- qreal odx = realFinal.x() - realStart.x();
- qreal ody = realFinal.y() - realStart.y();
-
- // nx, ny and dx, dy are normal and gradient direction after transform:
- qreal nx = m.m11()*ody - m.m21()*odx;
- qreal ny = m.m12()*ody - m.m22()*odx;
-
- qreal dx = m.m11()*odx + m.m21()*ody;
- qreal dy = m.m12()*odx + m.m22()*ody;
-
- qreal lx = 1 / (dx - dy*nx/ny);
- qreal ly = 1 / (dy - dx*ny/nx);
- qreal l = 1 / qSqrt(lx*lx+ly*ly);
-
- stop = start + QPointF(-ny, nx) * l/qSqrt(nx*nx+ny*ny);
- }
-
- float tr[4], f;
- tr[0] = stop.x() - start.x();
- tr[1] = stop.y() - start.y();
- f = 1.0 / (tr[0]*tr[0] + tr[1]*tr[1]);
- tr[0] *= f;
- tr[1] *= f;
- tr[2] = 0;
- tr[3] = -(start.x()*tr[0] + start.y()*tr[1]);
- brush_color[0] = brush_color[1] = brush_color[2] = brush_color[3] = 255;
- qt_glColor4ubv(brush_color);
- glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
- glTexGenfv(GL_S, GL_OBJECT_PLANE, tr);
- }
-
- if (use_fragment_programs) {
- if (style == Qt::RadialGradientPattern) {
- const QRadialGradient *g = static_cast<const QRadialGradient *>(brush.gradient());
- QPointF realCenter = g->center();
- QPointF realFocal = g->focalPoint();
- qreal realRadius = g->radius();
- QTransform translate(1, 0, 0, 1, -realFocal.x(), -realFocal.y());
- QTransform gl_to_qt(1, 0, 0, -1, 0, pdev->height());
- QTransform m = QTransform(matrix).translate(brush_origin.x(), brush_origin.y());
- QTransform inv_matrix = gl_to_qt * (brush.transform() * m).inverted() * translate;
-
- setInvMatrixData(inv_matrix);
-
- fmp_data[0] = realCenter.x() - realFocal.x();
- fmp_data[1] = realCenter.y() - realFocal.y();
-
- fmp2_m_radius2_data[0] = -fmp_data[0] * fmp_data[0] - fmp_data[1] * fmp_data[1] + realRadius * realRadius;
- } else if (style == Qt::ConicalGradientPattern) {
- const QConicalGradient *g = static_cast<const QConicalGradient *>(brush.gradient());
- QPointF realCenter = g->center();
- QTransform translate(1, 0, 0, 1, -realCenter.x(), -realCenter.y());
- QTransform gl_to_qt(1, 0, 0, -1, 0, pdev->height());
- QTransform m = QTransform(matrix).translate(brush_origin.x(), brush_origin.y());
- QTransform inv_matrix = gl_to_qt * (brush.transform() * m).inverted() * translate;
-
- setInvMatrixData(inv_matrix);
-
- angle_data[0] = -(g->angle() * 2 * Q_PI) / 360.0;
- } else if (style == Qt::LinearGradientPattern) {
- const QLinearGradient *g = static_cast<const QLinearGradient *>(brush.gradient());
-
- QPointF realStart = g->start();
- QPointF realFinal = g->finalStop();
- QTransform translate(1, 0, 0, 1, -realStart.x(), -realStart.y());
- QTransform gl_to_qt(1, 0, 0, -1, 0, pdev->height());
- QTransform m = QTransform(matrix).translate(brush_origin.x(), brush_origin.y());
- QTransform inv_matrix = gl_to_qt * (brush.transform() * m).inverted() * translate;
-
- setInvMatrixData(inv_matrix);
-
- QPointF l = realFinal - realStart;
-
- linear_data[0] = l.x();
- linear_data[1] = l.y();
-
- linear_data[2] = 1.0f / (l.x() * l.x() + l.y() * l.y());
- } else if (style != Qt::SolidPattern) {
- QTransform gl_to_qt(1, 0, 0, -1, 0, pdev->height());
- QTransform m = QTransform(matrix).translate(brush_origin.x(), brush_origin.y());
- QTransform inv_matrix = gl_to_qt * (brush.transform() * m).inverted();
-
- setInvMatrixData(inv_matrix);
- }
- }
-
- if (style >= Qt::LinearGradientPattern && style <= Qt::ConicalGradientPattern) {
- createGradientPaletteTexture(*brush.gradient());
- }
-#endif
-}
-
-
-class QOpenGLTessellator : public QTessellator
-{
-public:
- QOpenGLTessellator() {}
- ~QOpenGLTessellator() { }
- QGLTrapezoid toGLTrapezoid(const Trapezoid &trap);
-};
-
-QGLTrapezoid QOpenGLTessellator::toGLTrapezoid(const Trapezoid &trap)
-{
- QGLTrapezoid t;
-
- t.top = Q27Dot5ToDouble(trap.top);
- t.bottom = Q27Dot5ToDouble(trap.bottom);
-
- Q27Dot5 y = trap.topLeft->y - trap.bottomLeft->y;
-
- qreal topLeftY = Q27Dot5ToDouble(trap.topLeft->y);
-
- qreal tx = Q27Dot5ToDouble(trap.topLeft->x);
- qreal m = (-tx + Q27Dot5ToDouble(trap.bottomLeft->x)) / Q27Dot5ToDouble(y);
- t.topLeftX = tx + m * (topLeftY - t.top);
- t.bottomLeftX = tx + m * (topLeftY - t.bottom);
-
- y = trap.topRight->y - trap.bottomRight->y;
-
- qreal topRightY = Q27Dot5ToDouble(trap.topRight->y);
-
- tx = Q27Dot5ToDouble(trap.topRight->x);
- m = (-tx + Q27Dot5ToDouble(trap.bottomRight->x)) / Q27Dot5ToDouble(y);
-
- t.topRightX = tx + m * (topRightY - Q27Dot5ToDouble(trap.top));
- t.bottomRightX = tx + m * (topRightY - Q27Dot5ToDouble(trap.bottom));
-
- return t;
-}
-
-class QOpenGLImmediateModeTessellator : public QOpenGLTessellator
-{
-public:
- void addTrap(const Trapezoid &trap);
- void tessellate(const QPointF *points, int nPoints, bool winding) {
- trapezoids.reserve(trapezoids.size() + nPoints);
- setWinding(winding);
- QTessellator::tessellate(points, nPoints);
- }
-
- QVector<QGLTrapezoid> trapezoids;
-};
-
-void QOpenGLImmediateModeTessellator::addTrap(const Trapezoid &trap)
-{
- trapezoids.append(toGLTrapezoid(trap));
-}
-
-#ifndef QT_OPENGL_ES
-static void drawTrapezoid(const QGLTrapezoid &trap, const qreal offscreenHeight, QGLContext *ctx)
-{
- qreal minX = qMin(trap.topLeftX, trap.bottomLeftX);
- qreal maxX = qMax(trap.topRightX, trap.bottomRightX);
-
- if (qFuzzyCompare(trap.top, trap.bottom) || qFuzzyCompare(minX, maxX) ||
- (qFuzzyCompare(trap.topLeftX, trap.topRightX) && qFuzzyCompare(trap.bottomLeftX, trap.bottomRightX)))
- return;
-
- const qreal xpadding = 1.0;
- const qreal ypadding = 1.0;
-
- qreal topDist = offscreenHeight - trap.top;
- qreal bottomDist = offscreenHeight - trap.bottom;
-
- qreal reciprocal = bottomDist / (bottomDist - topDist);
-
- qreal leftB = trap.bottomLeftX + (trap.topLeftX - trap.bottomLeftX) * reciprocal;
- qreal rightB = trap.bottomRightX + (trap.topRightX - trap.bottomRightX) * reciprocal;
-
- const bool topZero = qFuzzyIsNull(topDist);
-
- reciprocal = topZero ? 1.0 / bottomDist : 1.0 / topDist;
-
- qreal leftA = topZero ? (trap.bottomLeftX - leftB) * reciprocal : (trap.topLeftX - leftB) * reciprocal;
- qreal rightA = topZero ? (trap.bottomRightX - rightB) * reciprocal : (trap.topRightX - rightB) * reciprocal;
-
- qreal invLeftA = qFuzzyIsNull(leftA) ? 0.0 : 1.0 / leftA;
- qreal invRightA = qFuzzyIsNull(rightA) ? 0.0 : 1.0 / rightA;
-
- // fragment program needs the negative of invRightA as it mirrors the line
- glTexCoord4f(topDist, bottomDist, invLeftA, -invRightA);
- glMultiTexCoord4f(GL_TEXTURE1, leftA, leftB, rightA, rightB);
-
- qreal topY = trap.top - ypadding;
- qreal bottomY = trap.bottom + ypadding;
-
- qreal bounds_bottomLeftX = leftA * (offscreenHeight - bottomY) + leftB;
- qreal bounds_bottomRightX = rightA * (offscreenHeight - bottomY) + rightB;
- qreal bounds_topLeftX = leftA * (offscreenHeight - topY) + leftB;
- qreal bounds_topRightX = rightA * (offscreenHeight - topY) + rightB;
-
- QPointF leftNormal(1, -leftA);
- leftNormal /= qSqrt(leftNormal.x() * leftNormal.x() + leftNormal.y() * leftNormal.y());
- QPointF rightNormal(1, -rightA);
- rightNormal /= qSqrt(rightNormal.x() * rightNormal.x() + rightNormal.y() * rightNormal.y());
-
- qreal left_padding = xpadding / qAbs(leftNormal.x());
- qreal right_padding = xpadding / qAbs(rightNormal.x());
-
- glVertex2d(bounds_topLeftX - left_padding, topY);
- glVertex2d(bounds_topRightX + right_padding, topY);
- glVertex2d(bounds_bottomRightX + right_padding, bottomY);
- glVertex2d(bounds_bottomLeftX - left_padding, bottomY);
-
- glTexCoord4f(0.0f, 0.0f, 0.0f, 1.0f);
-}
-#endif // !Q_WS_QWS
-
-class QOpenGLTrapezoidToArrayTessellator : public QOpenGLTessellator
-{
-public:
- QOpenGLTrapezoidToArrayTessellator() : vertices(0), allocated(0), size(0) {}
- ~QOpenGLTrapezoidToArrayTessellator() { free(vertices); }
- GLfloat *vertices;
- int allocated;
- int size;
- QRectF bounds;
- void addTrap(const Trapezoid &trap);
- void tessellate(const QPointF *points, int nPoints, bool winding) {
- size = 0;
- setWinding(winding);
- bounds = QTessellator::tessellate(points, nPoints);
- }
-};
-
-void QOpenGLTrapezoidToArrayTessellator::addTrap(const Trapezoid &trap)
-{
- // On OpenGL ES we convert the trap to 2 triangles
-#ifndef QT_OPENGL_ES
- if (size > allocated - 8) {
-#else
- if (size > allocated - 12) {
-#endif
- allocated = qMax(2*allocated, 512);
- vertices = (GLfloat *)realloc(vertices, allocated * sizeof(GLfloat));
- }
-
- QGLTrapezoid t = toGLTrapezoid(trap);
-
-#ifndef QT_OPENGL_ES
- 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;
-#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;
-
- // 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;
-#endif
-}
-
-
-void QOpenGLPaintEnginePrivate::fillPolygon_dev(const QPointF *polygonPoints, int pointCount,
- Qt::FillRule fill)
-{
- QOpenGLTrapezoidToArrayTessellator tessellator;
- tessellator.tessellate(polygonPoints, pointCount, fill == Qt::WindingFill);
-
- DEBUG_ONCE qDebug() << "QOpenGLPaintEnginePrivate: Drawing polygon with" << pointCount << "points using fillPolygon_dev";
-
- setGradientOps(cbrush, tessellator.bounds);
-
- bool fast_style = current_style == Qt::LinearGradientPattern
- || current_style == Qt::SolidPattern;
-
-#ifndef QT_OPENGL_ES
- GLenum geometry_mode = GL_QUADS;
-#else
- GLenum geometry_mode = GL_TRIANGLES;
-#endif
-
- if (use_fragment_programs && !(fast_style && has_fast_composition_mode)) {
- composite(geometry_mode, tessellator.vertices, tessellator.size / 2);
- } else {
- glVertexPointer(2, GL_FLOAT, 0, tessellator.vertices);
- glEnableClientState(GL_VERTEX_ARRAY);
- glDrawArrays(geometry_mode, 0, tessellator.size/2);
- glDisableClientState(GL_VERTEX_ARRAY);
- }
-}
-
-
-inline void QOpenGLPaintEnginePrivate::lineToStencil(qreal x, qreal y)
-{
- tess_points.add(QPointF(x, y));
-
- if (x > max_x)
- max_x = x;
- else if (x < min_x)
- min_x = x;
- if (y > max_y)
- max_y = y;
- else if (y < min_y)
- min_y = y;
-}
-
-inline void QOpenGLPaintEnginePrivate::curveToStencil(const QPointF &cp1, const QPointF &cp2, const QPointF &ep)
-{
- qreal inverseScaleHalf = inverseScale / 2;
-
- QBezier beziers[32];
- beziers[0] = QBezier::fromPoints(tess_points.last(), cp1, cp2, ep);
- QBezier *b = beziers;
- while (b >= beziers) {
- // check if we can pop the top bezier curve from the stack
- qreal l = qAbs(b->x4 - b->x1) + qAbs(b->y4 - b->y1);
- qreal d;
- if (l > inverseScale) {
- d = qAbs( (b->x4 - b->x1)*(b->y1 - b->y2) - (b->y4 - b->y1)*(b->x1 - b->x2) )
- + qAbs( (b->x4 - b->x1)*(b->y1 - b->y3) - (b->y4 - b->y1)*(b->x1 - b->x3) );
- d /= l;
- } else {
- d = qAbs(b->x1 - b->x2) + qAbs(b->y1 - b->y2) +
- qAbs(b->x1 - b->x3) + qAbs(b->y1 - b->y3);
- }
- if (d < inverseScaleHalf || b == beziers + 31) {
- // good enough, we pop it off and add the endpoint
- lineToStencil(b->x4, b->y4);
- --b;
- } else {
- // split, second half of the polygon goes lower into the stack
- b->split(b+1, b);
- ++b;
- }
- }
-}
-
-
-void QOpenGLPaintEnginePrivate::pathToVertexArrays(const QPainterPath &path)
-{
- const QPainterPath::Element &first = path.elementAt(0);
- min_x = max_x = first.x;
- min_y = max_y = first.y;
-
- tess_points.reset();
- tess_points_stops.clear();
- lineToStencil(first.x, first.y);
-
- for (int i=1; i<path.elementCount(); ++i) {
- const QPainterPath::Element &e = path.elementAt(i);
- switch (e.type) {
- case QPainterPath::MoveToElement:
- tess_points_stops.append(tess_points.size());
- lineToStencil(e.x, e.y);
- break;
- case QPainterPath::LineToElement:
- lineToStencil(e.x, e.y);
- break;
- case QPainterPath::CurveToElement:
- curveToStencil(e, path.elementAt(i+1), path.elementAt(i+2));
- i+=2;
- break;
- default:
- break;
- }
- }
- lineToStencil(first.x, first.y);
- tess_points_stops.append(tess_points.size());
-}
-
-
-void QOpenGLPaintEnginePrivate::drawVertexArrays()
-{
- if (tess_points_stops.count() == 0)
- return;
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(2, GL_DOUBLE, 0, tess_points.data());
- int previous_stop = 0;
- foreach(int stop, tess_points_stops) {
- glDrawArrays(GL_TRIANGLE_FAN, previous_stop, stop-previous_stop);
- previous_stop = stop;
- }
- glDisableClientState(GL_VERTEX_ARRAY);
-}
-
-void QOpenGLPaintEnginePrivate::fillVertexArray(Qt::FillRule fillRule)
-{
- Q_Q(QOpenGLPaintEngine);
-
- QRect rect = dirty_stencil.boundingRect();
-
- if (use_system_clip)
- rect = q->systemClip().intersected(dirty_stencil).boundingRect();
-
- glStencilMask(~0);
-
- if (!rect.isEmpty()) {
- disableClipping();
-
- glEnable(GL_SCISSOR_TEST);
-
- const int left = rect.left();
- const int width = rect.width();
- const int bottom = device->size().height() - (rect.bottom() + 1);
- const int height = rect.height();
-
- glScissor(left, bottom, width, height);
-
- glClearStencil(0);
- glClear(GL_STENCIL_BUFFER_BIT);
- dirty_stencil -= rect;
-
- glDisable(GL_SCISSOR_TEST);
-
- enableClipping();
- }
-
- // Enable stencil.
- glEnable(GL_STENCIL_TEST);
-
- // Disable color writes.
- glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
-
- GLuint stencilMask = 0;
-
- if (fillRule == Qt::OddEvenFill) {
- stencilMask = 1;
-
- // Enable stencil writes.
- glStencilMask(stencilMask);
-
- // Set stencil xor mode.
- glStencilOp(GL_KEEP, GL_KEEP, GL_INVERT);
-
- // Disable stencil func.
- glStencilFunc(GL_ALWAYS, 0, ~0);
-
- drawVertexArrays();
- } else if (fillRule == Qt::WindingFill) {
- stencilMask = ~0;
-
- if (has_stencil_face_ext) {
- QGL_FUNC_CONTEXT;
- glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);
-
- glActiveStencilFaceEXT(GL_BACK);
- glStencilOp(GL_KEEP, GL_KEEP, GL_DECR_WRAP_EXT);
- glStencilFunc(GL_ALWAYS, 0, ~0);
-
- glActiveStencilFaceEXT(GL_FRONT);
- glStencilOp(GL_KEEP, GL_KEEP, GL_INCR_WRAP_EXT);
- glStencilFunc(GL_ALWAYS, 0, ~0);
-
- drawVertexArrays();
-
- glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);
- } else {
- glStencilFunc(GL_ALWAYS, 0, ~0);
- glEnable(GL_CULL_FACE);
-
- glCullFace(GL_BACK);
- glStencilOp(GL_KEEP, GL_KEEP, GL_INCR_WRAP_EXT);
- drawVertexArrays();
-
- glCullFace(GL_FRONT);
- glStencilOp(GL_KEEP, GL_KEEP, GL_DECR_WRAP_EXT);
- drawVertexArrays();
-
- glDisable(GL_CULL_FACE);
- }
- }
-
- // Enable color writes.
- glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
- glStencilMask(stencilMask);
-
- setGradientOps(cbrush, QRectF(QPointF(min_x, min_y), QSizeF(max_x - min_x, max_y - min_y)));
-
- bool fast_fill = has_fast_composition_mode && (current_style == Qt::LinearGradientPattern || current_style == Qt::SolidPattern);
-
- if (use_fragment_programs && !fast_fill) {
- DEBUG_ONCE qDebug() << "QOpenGLPaintEnginePrivate: Drawing polygon using stencil method (fragment programs)";
- QRectF rect(QPointF(min_x, min_y), QSizeF(max_x - min_x, max_y - min_y));
-
- // Enable stencil func.
- glStencilFunc(GL_NOTEQUAL, 0, stencilMask);
- glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
- composite(rect);
- } else {
- DEBUG_ONCE qDebug() << "QOpenGLPaintEnginePrivate: Drawing polygon using stencil method (no fragment programs)";
-
- // Enable stencil func.
- glStencilFunc(GL_NOTEQUAL, 0, stencilMask);
- glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
-#ifndef QT_OPENGL_ES
- glBegin(GL_QUADS);
- glVertex2f(min_x, min_y);
- glVertex2f(max_x, min_y);
- glVertex2f(max_x, max_y);
- glVertex2f(min_x, max_y);
- glEnd();
-#endif
- }
-
- // Disable stencil writes.
- glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
- glStencilMask(0);
- glDisable(GL_STENCIL_TEST);
-}
-
-void QOpenGLPaintEnginePrivate::fillPath(const QPainterPath &path)
-{
- if (path.isEmpty())
- return;
-
- if (use_stencil_method && !high_quality_antialiasing) {
- pathToVertexArrays(path);
- fillVertexArray(path.fillRule());
- return;
- }
-
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
-
- if (high_quality_antialiasing)
- drawOffscreenPath(path);
- else {
- QPolygonF poly = path.toFillPolygon(matrix);
- fillPolygon_dev(poly.data(), poly.count(),
- path.fillRule());
- }
-
- updateGLMatrix();
-}
-
-extern bool qt_isExtendedRadialGradient(const QBrush &brush);
-
-static inline bool needsEmulation(Qt::BrushStyle style)
-{
- return !(style == Qt::SolidPattern
- || (style == Qt::LinearGradientPattern
- && (QGLExtensions::glExtensions() & QGLExtensions::MirroredRepeat)));
-}
-
-void QOpenGLPaintEnginePrivate::updateUseEmulation()
-{
- use_emulation = (!use_fragment_programs
- && ((has_pen && needsEmulation(pen_brush_style))
- || (has_brush && needsEmulation(brush_style))))
- || (has_pen && qt_isExtendedRadialGradient(cpen.brush()))
- || (has_brush && qt_isExtendedRadialGradient(cbrush));
-}
-
-void QOpenGLPaintEngine::updatePen(const QPen &pen)
-{
- Q_D(QOpenGLPaintEngine);
- Qt::PenStyle pen_style = pen.style();
- d->pen_brush_style = pen.brush().style();
- d->cpen = pen;
- d->has_pen = (pen_style != Qt::NoPen) && (d->pen_brush_style != Qt::NoBrush);
- d->updateUseEmulation();
-
- if (pen.isCosmetic()) {
- GLfloat width = pen.widthF() == 0.0f ? 1.0f : pen.widthF();
- glLineWidth(width);
- glPointSize(width);
- }
-
- if (d->pen_brush_style >= Qt::LinearGradientPattern
- && d->pen_brush_style <= Qt::ConicalGradientPattern)
- {
- d->setGLPen(Qt::white);
- } else {
- d->setGLPen(pen.color());
- }
-
- d->updateFastPen();
-}
-
-void QOpenGLPaintEngine::updateBrush(const QBrush &brush, const QPointF &origin)
-{
- Q_D(QOpenGLPaintEngine);
- d->cbrush = brush;
- d->brush_style = brush.style();
- d->brush_origin = origin;
- d->has_brush = (d->brush_style != Qt::NoBrush);
- d->updateUseEmulation();
-}
-
-void QOpenGLPaintEngine::updateFont(const QFont &)
-{
-}
-
-void QOpenGLPaintEngine::updateMatrix(const QTransform &mtx)
-{
- Q_D(QOpenGLPaintEngine);
-
- d->matrix = mtx;
-
- d->mv_matrix[0][0] = mtx.m11();
- d->mv_matrix[0][1] = mtx.m12();
- d->mv_matrix[0][2] = 0;
- d->mv_matrix[0][3] = mtx.m13();
-
- d->mv_matrix[1][0] = mtx.m21();
- d->mv_matrix[1][1] = mtx.m22();
- d->mv_matrix[1][2] = 0;
- d->mv_matrix[1][3] = mtx.m23();
-
- d->mv_matrix[2][0] = 0;
- d->mv_matrix[2][1] = 0;
- d->mv_matrix[2][2] = 1;
- d->mv_matrix[2][3] = 0;
-
- d->mv_matrix[3][0] = mtx.dx();
- d->mv_matrix[3][1] = mtx.dy();
- d->mv_matrix[3][2] = 0;
- d->mv_matrix[3][3] = mtx.m33();
-
- d->txop = mtx.type();
-
- // 1/10000 == 0.0001, so we have good enough res to cover curves
- // that span the entire widget...
- d->inverseScale = qMax(1 / qMax( qMax(qAbs(mtx.m11()), qAbs(mtx.m22())),
- qMax(qAbs(mtx.m12()), qAbs(mtx.m21())) ),
- qreal(0.0001));
-
- d->updateGLMatrix();
- d->updateFastPen();
-}
-
-void QOpenGLPaintEnginePrivate::updateGLMatrix() const
-{
- glMatrixMode(GL_MODELVIEW);
-#ifndef QT_OPENGL_ES
- glLoadMatrixd(&mv_matrix[0][0]);
-#else
- glLoadMatrixf(&mv_matrix[0][0]);
-#endif
-}
-
-void QOpenGLPaintEnginePrivate::disableClipping()
-{
- glDisable(GL_DEPTH_TEST);
- glDisable(GL_SCISSOR_TEST);
-}
-
-void QOpenGLPaintEnginePrivate::enableClipping()
-{
- Q_Q(QOpenGLPaintEngine);
- if (!q->state()->hasClipping)
- return;
-
- if (q->state()->fastClip.isEmpty())
- glEnable(GL_DEPTH_TEST);
- else
- updateDepthClip(); // this will enable the scissor test
-}
-
-void QOpenGLPaintEnginePrivate::updateDepthClip()
-{
- Q_Q(QOpenGLPaintEngine);
-
- ++q->state()->depthClipId;
-
- glDisable(GL_DEPTH_TEST);
- glDisable(GL_SCISSOR_TEST);
-
- if (!q->state()->hasClipping)
- return;
-
- QRect fastClip;
- if (q->state()->clipEnabled) {
- fastClip = q->state()->fastClip;
- } else if (use_system_clip && q->systemClip().rects().count() == 1) {
- fastClip = q->systemClip().rects().at(0);
- }
-
- if (!fastClip.isEmpty()) {
- glEnable(GL_SCISSOR_TEST);
-
- const int left = fastClip.left();
- const int width = fastClip.width();
- const int bottom = device->size().height() - (fastClip.bottom() + 1);
- const int height = fastClip.height();
-
- glScissor(left, bottom, width, height);
- return;
- }
-
-#if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_2)
- glClearDepthf(0.0f);
-#else
- glClearDepth(0.0f);
-#endif
-
- glEnable(GL_DEPTH_TEST);
- glDepthMask(GL_TRUE);
- glClear(GL_DEPTH_BUFFER_BIT);
-
- glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
- glDepthFunc(GL_ALWAYS);
-
- const QVector<QRect> rects = q->state()->clipEnabled ? q->state()->clipRegion.rects() : q->systemClip().rects();
-
- // rectangle count * 2 (triangles) * vertex count * component count (Z omitted)
- QDataBuffer<GLfloat> clipVertex(rects.size()*2*3*2);
- for (int i = 0; i < rects.size(); ++i) {
- GLfloat x = GLfloat(rects.at(i).left());
- GLfloat w = GLfloat(rects.at(i).width());
- GLfloat h = GLfloat(rects.at(i).height());
- GLfloat y = GLfloat(rects.at(i).top());
-
- // First triangle
- clipVertex.add(x);
- clipVertex.add(y);
-
- clipVertex.add(x);
- clipVertex.add(y + h);
-
- clipVertex.add(x + w);
- clipVertex.add(y);
-
- // Second triangle
- clipVertex.add(x);
- clipVertex.add(y + h);
-
- clipVertex.add(x + w);
- clipVertex.add(y + h);
-
- clipVertex.add (x + w);
- clipVertex.add(y);
- }
-
- if (rects.size()) {
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
-
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(2, GL_FLOAT, 0, clipVertex.data());
-
- glDrawArrays(GL_TRIANGLES, 0, rects.size()*2*3);
- glDisableClientState(GL_VERTEX_ARRAY);
- updateGLMatrix();
- }
-
- glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
- glDepthMask(GL_FALSE);
- glDepthFunc(GL_LEQUAL);
-}
-
-void QOpenGLPaintEnginePrivate::systemStateChanged()
-{
- Q_Q(QOpenGLPaintEngine);
- if (q->painter()->hasClipping())
- q->updateClipRegion(q->painter()->clipRegion(), Qt::ReplaceClip);
- else
- q->updateClipRegion(QRegion(), Qt::NoClip);
-}
-
-void QOpenGLPaintEngine::updateClipRegion(const QRegion &clipRegion, Qt::ClipOperation op)
-{
- Q_D(QOpenGLPaintEngine);
-
- // clipping is only supported when a stencil or depth buffer is
- // available
- if (!d->device->format().depth())
- return;
-
- d->use_system_clip = false;
- QRegion sysClip = systemClip();
- if (!sysClip.isEmpty()) {
- if (d->pdev->devType() != QInternal::Widget) {
- d->use_system_clip = true;
- } else {
-#ifndef Q_WS_QWS
- // Only use the system clip if we're currently rendering a widget with a GL painter.
- if (d->currentClipWidget) {
- QWidgetPrivate *widgetPrivate = qt_widget_private(d->currentClipWidget->window());
- d->use_system_clip = widgetPrivate->extra && widgetPrivate->extra->inRenderWithPainter;
- }
-#endif
- }
- }
-
- d->flushDrawQueue();
-
- if (op == Qt::NoClip && !d->use_system_clip) {
- state()->hasClipping = false;
- state()->clipRegion = QRegion();
- d->updateDepthClip();
- return;
- }
-
- bool isScreenClip = false;
- if (!d->use_system_clip) {
- QVector<QRect> untransformedRects = clipRegion.rects();
-
- if (untransformedRects.size() == 1) {
- QPainterPath path;
- path.addRect(untransformedRects[0]);
- path = d->matrix.map(path);
-
- if (path.contains(QRectF(QPointF(), d->device->size())))
- isScreenClip = true;
- }
- }
-
- QRegion region = isScreenClip ? QRegion() : clipRegion * d->matrix;
- switch (op) {
- case Qt::NoClip:
- if (!d->use_system_clip)
- break;
- state()->clipRegion = sysClip;
- break;
- case Qt::IntersectClip:
- if (isScreenClip)
- return;
- if (state()->hasClipping) {
- state()->clipRegion &= region;
- break;
- }
- // fall through
- case Qt::ReplaceClip:
- if (d->use_system_clip)
- state()->clipRegion = region & sysClip;
- else
- state()->clipRegion = region;
- break;
- default:
- break;
- }
-
- if (isScreenClip) {
- state()->hasClipping = false;
- state()->clipRegion = QRegion();
- } else {
- state()->hasClipping = op != Qt::NoClip || d->use_system_clip;
- }
-
- if (state()->hasClipping && state()->clipRegion.rects().size() == 1)
- state()->fastClip = state()->clipRegion.rects().at(0);
- else
- state()->fastClip = QRect();
-
- d->updateDepthClip();
-}
-
-void QOpenGLPaintEngine::updateRenderHints(QPainter::RenderHints hints)
-{
- Q_D(QOpenGLPaintEngine);
-
- d->flushDrawQueue();
- d->use_smooth_pixmap_transform = bool(hints & QPainter::SmoothPixmapTransform);
- if ((hints & QPainter::Antialiasing) || (hints & QPainter::HighQualityAntialiasing)) {
- if (d->use_fragment_programs && QGLOffscreen::isSupported()
- && (hints & QPainter::HighQualityAntialiasing)) {
- d->high_quality_antialiasing = true;
- } else {
- d->high_quality_antialiasing = false;
- if (QGLExtensions::glExtensions() & QGLExtensions::SampleBuffers)
- glEnable(GL_MULTISAMPLE);
- }
- } else {
- d->high_quality_antialiasing = false;
- if (QGLExtensions::glExtensions() & QGLExtensions::SampleBuffers)
- glDisable(GL_MULTISAMPLE);
- }
-
- if (d->high_quality_antialiasing) {
- d->offscreen.initialize();
-
- if (!d->offscreen.isValid()) {
- DEBUG_ONCE_STR("Unable to initialize offscreen, disabling high quality antialiasing");
- d->high_quality_antialiasing = false;
- if (QGLExtensions::glExtensions() & QGLExtensions::SampleBuffers)
- glEnable(GL_MULTISAMPLE);
- }
- }
-
- d->has_antialiasing = d->high_quality_antialiasing
- || ((hints & QPainter::Antialiasing)
- && (QGLExtensions::glExtensions() & QGLExtensions::SampleBuffers));
-}
-
-
-void QOpenGLPaintEnginePrivate::setPorterDuffData(float a, float b, float x, float y, float z)
-{
- porterduff_ab_data[0] = a;
- porterduff_ab_data[1] = b;
-
- porterduff_xyz_data[0] = x;
- porterduff_xyz_data[1] = y;
- porterduff_xyz_data[2] = z;
-}
-
-
-void QOpenGLPaintEngine::updateCompositionMode(QPainter::CompositionMode composition_mode)
-{
- Q_D(QOpenGLPaintEngine);
-
- if (!d->use_fragment_programs && composition_mode > QPainter::CompositionMode_Plus)
- composition_mode = QPainter::CompositionMode_SourceOver;
-
- d->composition_mode = composition_mode;
-
- d->has_fast_composition_mode = (!d->high_quality_antialiasing && composition_mode <= QPainter::CompositionMode_Plus)
- || composition_mode == QPainter::CompositionMode_SourceOver
- || composition_mode == QPainter::CompositionMode_Destination
- || composition_mode == QPainter::CompositionMode_DestinationOver
- || composition_mode == QPainter::CompositionMode_DestinationOut
- || composition_mode == QPainter::CompositionMode_SourceAtop
- || composition_mode == QPainter::CompositionMode_Xor
- || composition_mode == QPainter::CompositionMode_Plus;
-
- if (d->has_fast_composition_mode)
- d->fragment_composition_mode = d->high_quality_antialiasing ? COMPOSITION_MODE_BLEND_MODE_MASK : COMPOSITION_MODE_BLEND_MODE_NOMASK;
- else if (composition_mode <= QPainter::CompositionMode_Plus)
- d->fragment_composition_mode = d->high_quality_antialiasing ? COMPOSITION_MODES_SIMPLE_PORTER_DUFF : COMPOSITION_MODES_SIMPLE_PORTER_DUFF_NOMASK;
- else
- switch (composition_mode) {
- case QPainter::CompositionMode_Multiply:
- d->fragment_composition_mode = d->high_quality_antialiasing ? COMPOSITION_MODES_MULTIPLY : COMPOSITION_MODES_MULTIPLY_NOMASK;
- break;
- case QPainter::CompositionMode_Screen:
- d->fragment_composition_mode = d->high_quality_antialiasing ? COMPOSITION_MODES_SCREEN : COMPOSITION_MODES_SCREEN_NOMASK;
- break;
- case QPainter::CompositionMode_Overlay:
- d->fragment_composition_mode = d->high_quality_antialiasing ? COMPOSITION_MODES_OVERLAY : COMPOSITION_MODES_OVERLAY_NOMASK;
- break;
- case QPainter::CompositionMode_Darken:
- d->fragment_composition_mode = d->high_quality_antialiasing ? COMPOSITION_MODES_DARKEN : COMPOSITION_MODES_DARKEN_NOMASK;
- break;
- case QPainter::CompositionMode_Lighten:
- d->fragment_composition_mode = d->high_quality_antialiasing ? COMPOSITION_MODES_LIGHTEN : COMPOSITION_MODES_LIGHTEN_NOMASK;
- break;
- case QPainter::CompositionMode_ColorDodge:
- d->fragment_composition_mode = d->high_quality_antialiasing ? COMPOSITION_MODES_COLORDODGE : COMPOSITION_MODES_COLORDODGE_NOMASK;
- break;
- case QPainter::CompositionMode_ColorBurn:
- d->fragment_composition_mode = d->high_quality_antialiasing ? COMPOSITION_MODES_COLORBURN : COMPOSITION_MODES_COLORBURN_NOMASK;
- break;
- case QPainter::CompositionMode_HardLight:
- d->fragment_composition_mode = d->high_quality_antialiasing ? COMPOSITION_MODES_HARDLIGHT : COMPOSITION_MODES_HARDLIGHT_NOMASK;
- break;
- case QPainter::CompositionMode_SoftLight:
- d->fragment_composition_mode = d->high_quality_antialiasing ? COMPOSITION_MODES_SOFTLIGHT : COMPOSITION_MODES_SOFTLIGHT_NOMASK;
- break;
- case QPainter::CompositionMode_Difference:
- d->fragment_composition_mode = d->high_quality_antialiasing ? COMPOSITION_MODES_DIFFERENCE : COMPOSITION_MODES_DIFFERENCE_NOMASK;
- break;
- case QPainter::CompositionMode_Exclusion:
- d->fragment_composition_mode = d->high_quality_antialiasing ? COMPOSITION_MODES_EXCLUSION : COMPOSITION_MODES_EXCLUSION_NOMASK;
- break;
- default:
- Q_ASSERT(false);
- }
-
- switch(composition_mode) {
- case QPainter::CompositionMode_DestinationOver:
- glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ONE);
- d->setPorterDuffData(0, 1, 1, 1, 1);
- break;
- case QPainter::CompositionMode_Clear:
- glBlendFunc(GL_ZERO, GL_ZERO);
- d->setPorterDuffData(0, 0, 0, 0, 0);
- break;
- case QPainter::CompositionMode_Source:
- glBlendFunc(GL_ONE, GL_ZERO);
- d->setPorterDuffData(1, 0, 1, 1, 0);
- break;
- case QPainter::CompositionMode_Destination:
- glBlendFunc(GL_ZERO, GL_ONE);
- d->setPorterDuffData(0, 1, 1, 0, 1);
- break;
- case QPainter::CompositionMode_SourceIn:
- glBlendFunc(GL_DST_ALPHA, GL_ZERO);
- d->setPorterDuffData(1, 0, 1, 0, 0);
- break;
- case QPainter::CompositionMode_DestinationIn:
- glBlendFunc(GL_ZERO, GL_SRC_ALPHA);
- d->setPorterDuffData(0, 1, 1, 0, 0);
- break;
- case QPainter::CompositionMode_SourceOut:
- glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ZERO);
- d->setPorterDuffData(0, 0, 0, 1, 0);
- break;
- case QPainter::CompositionMode_DestinationOut:
- glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_ALPHA);
- d->setPorterDuffData(0, 0, 0, 0, 1);
- break;
- case QPainter::CompositionMode_SourceAtop:
- glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- d->setPorterDuffData(1, 0, 1, 0, 1);
- break;
- case QPainter::CompositionMode_DestinationAtop:
- glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_SRC_ALPHA);
- d->setPorterDuffData(0, 1, 1, 1, 0);
- break;
- case QPainter::CompositionMode_Xor:
- glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- d->setPorterDuffData(0, 0, 0, 1, 1);
- break;
- case QPainter::CompositionMode_SourceOver:
- glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
- d->setPorterDuffData(1, 0, 1, 1, 1);
- break;
- case QPainter::CompositionMode_Plus:
- glBlendFunc(GL_ONE, GL_ONE);
- d->setPorterDuffData(1, 1, 1, 1, 1);
- break;
- default:
- break;
- }
-}
-
-class QGLMaskGenerator
-{
-public:
- QGLMaskGenerator(const QPainterPath &path, const QTransform &matrix, qreal stroke_width = -1)
- : p(path),
- m(matrix),
- w(stroke_width)
- {
- }
-
- virtual QRect screenRect() = 0;
- virtual void drawMask(const QRect &rect) = 0;
-
- QPainterPath path() const { return p; }
- QTransform matrix() const { return m; }
- qreal strokeWidth() const { return w; }
-
- virtual ~QGLMaskGenerator() {}
-
-private:
- QPainterPath p;
- QTransform m;
- qreal w;
-};
-
-void QGLMaskTextureCache::setOffscreenSize(const QSize &sz)
-{
- Q_ASSERT(sz.width() == sz.height());
-
- if (offscreenSize != sz) {
- offscreenSize = sz;
- clearCache();
- }
-}
-
-void QGLMaskTextureCache::clearCache()
-{
- cache.clear();
-
- int quad_tree_size = 1;
-
- for (int i = block_size; i < offscreenSize.width(); i *= 2)
- quad_tree_size += quad_tree_size * 4;
-
- for (int i = 0; i < 4; ++i) {
- occupied_quadtree[i].resize(quad_tree_size);
-
- occupied_quadtree[i][0].key = 0;
- occupied_quadtree[i][0].largest_available_block = offscreenSize.width();
- occupied_quadtree[i][0].largest_used_block = 0;
-
- DEBUG_ONCE qDebug() << "QGLMaskTextureCache:: created quad tree of size" << quad_tree_size;
- }
-}
-
-void QGLMaskTextureCache::setDrawableSize(const QSize &sz)
-{
- drawableSize = sz;
-}
-
-void QGLMaskTextureCache::maintainCache()
-{
- QGLTextureCacheHash::iterator it = cache.begin();
- QGLTextureCacheHash::iterator end = cache.end();
-
- while (it != end) {
- CacheInfo &cache_info = it.value();
- ++cache_info.age;
-
- if (cache_info.age > 1) {
- quadtreeInsert(cache_info.loc.channel, 0, cache_info.loc.rect);
- it = cache.erase(it);
- } else {
- ++it;
- }
- }
-}
-
-//#define DISABLE_MASK_CACHE
-
-QGLMaskTextureCache::CacheLocation QGLMaskTextureCache::getMask(QGLMaskGenerator &maskGenerator, QOpenGLPaintEnginePrivate *e)
-{
-#ifndef DISABLE_MASK_CACHE
- engine = e;
-
- quint64 key = hash(maskGenerator.path(), maskGenerator.matrix(), maskGenerator.strokeWidth());
-
- if (key == 0)
- key = 1;
-
- CacheInfo info(maskGenerator.path(), maskGenerator.matrix(), maskGenerator.strokeWidth());
-
- QGLTextureCacheHash::iterator it = cache.find(key);
-
- while (it != cache.end() && it.key() == key) {
- CacheInfo &cache_info = it.value();
- if (info.stroke_width == cache_info.stroke_width && info.matrix == cache_info.matrix && info.path == cache_info.path) {
- DEBUG_ONCE_STR("QGLMaskTextureCache::getMask(): Using cached mask");
-
- cache_info.age = 0;
- return cache_info.loc;
- }
- ++it;
- }
-
- // mask was not found, create new mask
-
- DEBUG_ONCE_STR("QGLMaskTextureCache::getMask(): Creating new mask...");
-
- createMask(key, info, maskGenerator);
-
- cache.insert(key, info);
-
- return info.loc;
-#else
- CacheInfo info(maskGenerator.path(), maskGenerator.matrix());
- createMask(0, info, maskGenerator);
- return info.loc;
-#endif
-}
-
-#ifndef FloatToQuint64
-#define FloatToQuint64(i) (quint64)((i) * 32)
-#endif
-
-quint64 QGLMaskTextureCache::hash(const QPainterPath &p, const QTransform &m, qreal w)
-{
- Q_ASSERT(sizeof(quint64) == 8);
-
- quint64 h = 0;
-
- for (int i = 0; i < p.elementCount(); ++i) {
- h += FloatToQuint64(p.elementAt(i).x) << 32;
- h += FloatToQuint64(p.elementAt(i).y);
- h += p.elementAt(i).type;
- }
-
- h += FloatToQuint64(m.m11());
-#ifndef Q_OS_WINCE // ###
- //Compiler crashes for arm on WinCE
- h += FloatToQuint64(m.m12()) << 4;
- h += FloatToQuint64(m.m13()) << 8;
- h += FloatToQuint64(m.m21()) << 12;
- h += FloatToQuint64(m.m22()) << 16;
- h += FloatToQuint64(m.m23()) << 20;
- h += FloatToQuint64(m.m31()) << 24;
- h += FloatToQuint64(m.m32()) << 28;
-#endif
- h += FloatToQuint64(m.m33()) << 32;
-
- h += FloatToQuint64(w);
-
- return h;
-}
-
-void QGLMaskTextureCache::createMask(quint64 key, CacheInfo &info, QGLMaskGenerator &maskGenerator)
-{
- info.loc.screen_rect = maskGenerator.screenRect();
-
- if (info.loc.screen_rect.isEmpty()) {
- info.loc.channel = 0;
- info.loc.rect = QRect();
- return;
- }
-
- quadtreeAllocate(key, info.loc.screen_rect.size(), &info.loc.rect, &info.loc.channel);
-
- int ch = info.loc.channel;
- glColorMask(ch == 0, ch == 1, ch == 2, ch == 3);
-
- maskGenerator.drawMask(info.loc.rect);
-
- glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
-}
-
-int QGLMaskTextureCache::quadtreeBlocksize(int node)
-{
- DEBUG_ONCE qDebug() << "Offscreen size:" << offscreenSize.width();
-
- int blocksize = offscreenSize.width();
-
- while (node) {
- node = (node - 1) / 4;
- blocksize /= 2;
- }
-
- return blocksize;
-}
-
-QPoint QGLMaskTextureCache::quadtreeLocation(int node)
-{
- QPoint location;
- int blocksize = quadtreeBlocksize(node);
-
- while (node) {
- --node;
-
- if (node & 1)
- location.setX(location.x() + blocksize);
-
- if (node & 2)
- location.setY(location.y() + blocksize);
-
- node /= 4;
- blocksize *= 2;
- }
-
- return location;
-}
-
-void QGLMaskTextureCache::quadtreeUpdate(int channel, int node, int current_block_size)
-{
- while (node) {
- node = (node - 1) / 4;
-
- int first_child = node * 4 + 1;
-
- int largest_available = 0;
- int largest_used = 0;
-
- bool all_empty = true;
-
- for (int i = 0; i < 4; ++i) {
- largest_available = qMax(largest_available, occupied_quadtree[channel][first_child + i].largest_available_block);
- largest_used = qMax(largest_used, occupied_quadtree[channel][first_child + i].largest_used_block);
-
- if (occupied_quadtree[channel][first_child + i].largest_available_block < current_block_size)
- all_empty = false;
- }
-
- current_block_size *= 2;
-
- if (all_empty) {
- occupied_quadtree[channel][node].largest_available_block = current_block_size;
- occupied_quadtree[channel][node].largest_used_block = 0;
- } else {
- occupied_quadtree[channel][node].largest_available_block = largest_available;
- occupied_quadtree[channel][node].largest_used_block = largest_used;
- }
- }
-}
-
-void QGLMaskTextureCache::quadtreeInsert(int channel, quint64 key, const QRect &rect, int node)
-{
- int current_block_size = quadtreeBlocksize(node);
- QPoint location = quadtreeLocation(node);
- QRect relative = rect.translated(-location);
-
- if (relative.left() >= current_block_size || relative.top() >= current_block_size
- || relative.right() < 0 || relative.bottom() < 0)
- return;
-
- if (current_block_size == block_size // no more refining possible
- || (relative.top() < block_size && relative.bottom() >= (current_block_size - block_size)
- && relative.left() < block_size && relative.right() >= (current_block_size - block_size)))
- {
- if (key != 0) {
- occupied_quadtree[channel][node].largest_available_block = 0;
- occupied_quadtree[channel][node].largest_used_block = rect.width() * rect.height();
- } else {
- occupied_quadtree[channel][node].largest_available_block = current_block_size;
- occupied_quadtree[channel][node].largest_used_block = 0;
- }
-
- occupied_quadtree[channel][node].key = key;
-
- quadtreeUpdate(channel, node, current_block_size);
- } else {
- if (key && occupied_quadtree[channel][node].largest_available_block == current_block_size) {
- // refining the quad tree, initialize child nodes
- int half_block_size = current_block_size / 2;
-
- int temp = node * 4 + 1;
- for (int sibling = 0; sibling < 4; ++sibling) {
- occupied_quadtree[channel][temp + sibling].largest_available_block = half_block_size;
- occupied_quadtree[channel][temp + sibling].largest_used_block = 0;
- occupied_quadtree[channel][temp + sibling].key = 0;
- }
- }
-
- node = node * 4 + 1;
-
- for (int sibling = 0; sibling < 4; ++sibling)
- quadtreeInsert(channel, key, rect, node + sibling);
- }
-}
-
-void QGLMaskTextureCache::quadtreeClear(int channel, const QRect &rect, int node)
-{
- const quint64 &key = occupied_quadtree[channel][node].key;
-
- int current_block_size = quadtreeBlocksize(node);
- QPoint location = quadtreeLocation(node);
-
- QRect relative = rect.translated(-location);
-
- if (relative.left() >= current_block_size || relative.top() >= current_block_size
- || relative.right() < 0 || relative.bottom() < 0)
- return;
-
- if (key != 0) {
- QGLTextureCacheHash::iterator it = cache.find(key);
-
- Q_ASSERT(it != cache.end());
-
- while (it != cache.end() && it.key() == key) {
- const CacheInfo &cache_info = it.value();
-
- if (cache_info.loc.channel == channel
- && cache_info.loc.rect.left() <= location.x()
- && cache_info.loc.rect.top() <= location.y()
- && cache_info.loc.rect.right() >= location.x()
- && cache_info.loc.rect.bottom() >= location.y())
- {
- quadtreeInsert(channel, 0, cache_info.loc.rect);
- engine->cacheItemErased(channel, cache_info.loc.rect);
- cache.erase(it);
- goto found;
- } else {
- ++it;
- }
- }
-
- // if we don't find the key there's an error in the quadtree
- Q_ASSERT(false);
-found:
- Q_ASSERT(occupied_quadtree[channel][node].key == 0);
- } else if (occupied_quadtree[channel][node].largest_available_block < current_block_size) {
- Q_ASSERT(current_block_size >= block_size);
-
- node = node * 4 + 1;
-
- for (int sibling = 0; sibling < 4; ++sibling)
- quadtreeClear(channel, rect, node + sibling);
- }
-}
-
-bool QGLMaskTextureCache::quadtreeFindAvailableLocation(const QSize &size, QRect *rect, int *channel)
-{
- int needed_block_size = qMax(1, qMax(size.width(), size.height()));
-
- for (int i = 0; i < 4; ++i) {
- int current_block_size = offscreenSize.width();
-
- if (occupied_quadtree[i][0].largest_available_block >= needed_block_size) {
- int node = 0;
-
- while (current_block_size != occupied_quadtree[i][node].largest_available_block) {
- Q_ASSERT(current_block_size > block_size);
- Q_ASSERT(current_block_size > occupied_quadtree[i][node].largest_available_block);
-
- node = node * 4 + 1;
- current_block_size /= 2;
-
- int sibling = 0;
-
- while (occupied_quadtree[i][node + sibling].largest_available_block < needed_block_size)
- ++sibling;
-
- Q_ASSERT(sibling < 4);
- node += sibling;
- }
-
- *channel = i;
- *rect = QRect(quadtreeLocation(node), size);
-
- return true;
- }
- }
-
- return false;
-}
-
-void QGLMaskTextureCache::quadtreeFindExistingLocation(const QSize &size, QRect *rect, int *channel)
-{
- // try to pick small masks to throw out, as large masks are more expensive to recompute
- *channel = qrand() % 4;
- for (int i = 0; i < 4; ++i)
- if (occupied_quadtree[i][0].largest_used_block < occupied_quadtree[*channel][0].largest_used_block)
- *channel = i;
-
- int needed_block_size = qt_next_power_of_two(qMax(1, qMax(size.width(), size.height())));
-
- int node = 0;
- int current_block_size = offscreenSize.width();
-
- while (current_block_size > block_size
- && current_block_size >= needed_block_size * 2
- && occupied_quadtree[*channel][node].key == 0)
- {
- node = node * 4 + 1;
-
- int sibling = 0;
-
- for (int i = 1; i < 4; ++i) {
- if (occupied_quadtree[*channel][node + i].largest_used_block
- <= occupied_quadtree[*channel][node + sibling].largest_used_block)
- {
- sibling = i;
- }
- }
-
- node += sibling;
- current_block_size /= 2;
- }
-
- *rect = QRect(quadtreeLocation(node), size);
-}
-
-void QGLMaskTextureCache::quadtreeAllocate(quint64 key, const QSize &size, QRect *rect, int *channel)
-{
-#ifndef DISABLE_MASK_CACHE
- if (!quadtreeFindAvailableLocation(size, rect, channel)) {
- quadtreeFindExistingLocation(size, rect, channel);
- quadtreeClear(*channel, *rect);
- }
-
- quadtreeInsert(*channel, key, *rect);
-#else
- *channel = 0;
- *rect = QRect(QPoint(), size);
-#endif
-}
-
-class QGLTrapezoidMaskGenerator : public QGLMaskGenerator
-{
-public:
- QGLTrapezoidMaskGenerator(const QPainterPath &path, const QTransform &matrix, QGLOffscreen &offscreen, GLuint maskFragmentProgram, qreal strokeWidth = -1.0);
-
- QRect screenRect();
- void drawMask(const QRect &rect);
-
-private:
- QRect screen_rect;
- bool has_screen_rect;
-
- QGLOffscreen *offscreen;
-
- GLuint maskFragmentProgram;
-
- virtual QVector<QGLTrapezoid> generateTrapezoids() = 0;
- virtual QRect computeScreenRect() = 0;
-};
-
-class QGLPathMaskGenerator : public QGLTrapezoidMaskGenerator
-{
-public:
- QGLPathMaskGenerator(const QPainterPath &path, const QTransform &matrix, QGLOffscreen &offscreen, GLuint maskFragmentProgram);
-
-private:
- QVector<QGLTrapezoid> generateTrapezoids();
- QRect computeScreenRect();
-
- QPolygonF poly;
-};
-
-class QGLLineMaskGenerator : public QGLTrapezoidMaskGenerator
-{
-public:
- QGLLineMaskGenerator(const QPainterPath &path, const QTransform &matrix, qreal width, QGLOffscreen &offscreen, GLuint maskFragmentProgram);
-
-private:
- QVector<QGLTrapezoid> generateTrapezoids();
- QRect computeScreenRect();
-
- QPainterPath transformedPath;
-};
-
-class QGLRectMaskGenerator : public QGLTrapezoidMaskGenerator
-{
-public:
- QGLRectMaskGenerator(const QPainterPath &path, const QTransform &matrix, QGLOffscreen &offscreen, GLuint maskFragmentProgram);
-
-private:
- QVector<QGLTrapezoid> generateTrapezoids();
- QRect computeScreenRect();
-
- QPainterPath transformedPath;
-};
-
-class QGLEllipseMaskGenerator : public QGLMaskGenerator
-{
-public:
- QGLEllipseMaskGenerator(const QRectF &rect, const QTransform &matrix, QGLOffscreen &offscreen, GLuint maskFragmentProgram, int *maskVariableLocations);
-
- QRect screenRect();
- void drawMask(const QRect &rect);
-
-private:
- QRect screen_rect;
-
- QRectF ellipseRect;
-
- QGLOffscreen *offscreen;
-
- GLuint maskFragmentProgram;
-
- int *maskVariableLocations;
-
- float vertexArray[4 * 2];
-};
-
-QGLTrapezoidMaskGenerator::QGLTrapezoidMaskGenerator(const QPainterPath &path, const QTransform &matrix, QGLOffscreen &offs, GLuint program, qreal stroke_width)
- : QGLMaskGenerator(path, matrix, stroke_width)
- , has_screen_rect(false)
- , offscreen(&offs)
- , maskFragmentProgram(program)
-{
-}
-
-extern void qt_add_rect_to_array(const QRectF &r, GLfloat *array);
-extern void qt_add_texcoords_to_array(qreal x1, qreal y1, qreal x2, qreal y2, GLfloat *array);
-
-void QGLTrapezoidMaskGenerator::drawMask(const QRect &rect)
-{
-#ifdef QT_OPENGL_ES
- Q_UNUSED(rect);
-#else
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- glLoadIdentity();
-
- QGLContext *ctx = offscreen->context();
- offscreen->bind();
-
- glDisable(GL_TEXTURE_GEN_S);
- glDisable(GL_TEXTURE_1D);
-
- GLfloat vertexArray[4 * 2];
- qt_add_rect_to_array(rect, vertexArray);
-
- bool needs_scissor = rect != screen_rect;
-
- if (needs_scissor) {
- glEnable(GL_SCISSOR_TEST);
- glScissor(rect.left(), offscreen->offscreenSize().height() - rect.bottom() - 1, rect.width(), rect.height());
- }
-
- QVector<QGLTrapezoid> trapezoids = generateTrapezoids();
-
- // clear mask
- glBlendFunc(GL_ZERO, GL_ZERO); // clear
- glVertexPointer(2, GL_FLOAT, 0, vertexArray);
- glEnableClientState(GL_VERTEX_ARRAY);
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- glDisableClientState(GL_VERTEX_ARRAY);
-
- glBlendFunc(GL_ONE, GL_ONE); // add mask
- glEnable(GL_FRAGMENT_PROGRAM_ARB);
- glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, maskFragmentProgram);
-
- QPoint delta = rect.topLeft() - screen_rect.topLeft();
- glBegin(GL_QUADS);
- for (int i = 0; i < trapezoids.size(); ++i)
- drawTrapezoid(trapezoids[i].translated(delta), offscreen->offscreenSize().height(), ctx);
- glEnd();
-
- if (needs_scissor)
- glDisable(GL_SCISSOR_TEST);
-
- glDisable(GL_FRAGMENT_PROGRAM_ARB);
-
- glMatrixMode(GL_MODELVIEW);
- glPopMatrix();
-#endif
-}
-
-QRect QGLTrapezoidMaskGenerator::screenRect()
-{
- if (!has_screen_rect) {
- screen_rect = computeScreenRect();
- has_screen_rect = true;
- }
-
- screen_rect = screen_rect.intersected(QRect(QPoint(), offscreen->drawableSize()));
-
- return screen_rect;
-}
-
-QGLPathMaskGenerator::QGLPathMaskGenerator(const QPainterPath &path, const QTransform &matrix, QGLOffscreen &offs, GLuint program)
- : QGLTrapezoidMaskGenerator(path, matrix, offs, program)
-{
-}
-
-QRect QGLPathMaskGenerator::computeScreenRect()
-{
- poly = path().toFillPolygon(matrix());
- return poly.boundingRect().toAlignedRect();
-}
-
-QVector<QGLTrapezoid> QGLPathMaskGenerator::generateTrapezoids()
-{
- QOpenGLImmediateModeTessellator tessellator;
- tessellator.tessellate(poly.data(), poly.count(), path().fillRule() == Qt::WindingFill);
- return tessellator.trapezoids;
-}
-
-QGLRectMaskGenerator::QGLRectMaskGenerator(const QPainterPath &path, const QTransform &matrix, QGLOffscreen &offs, GLuint program)
- : QGLTrapezoidMaskGenerator(path, matrix, offs, program)
-{
-}
-
-QGLLineMaskGenerator::QGLLineMaskGenerator(const QPainterPath &path, const QTransform &matrix, qreal width, QGLOffscreen &offs, GLuint program)
- : QGLTrapezoidMaskGenerator(path, matrix, offs, program, width)
-{
-}
-
-QRect QGLRectMaskGenerator::computeScreenRect()
-{
- transformedPath = matrix().map(path());
-
- return transformedPath.controlPointRect().adjusted(-1, -1, 1, 1).toAlignedRect();
-}
-
-QRect QGLLineMaskGenerator::computeScreenRect()
-{
- transformedPath = matrix().map(path());
-
- return transformedPath.controlPointRect().adjusted(-1, -1, 1, 1).toAlignedRect();
-}
-
-QVector<QGLTrapezoid> QGLLineMaskGenerator::generateTrapezoids()
-{
- QOpenGLImmediateModeTessellator tessellator;
- QPointF last;
- for (int i = 0; i < transformedPath.elementCount(); ++i) {
- QPainterPath::Element element = transformedPath.elementAt(i);
-
- Q_ASSERT(!element.isCurveTo());
-
- if (element.isLineTo())
- tessellator.tessellateRect(last, element, strokeWidth());
-
- last = element;
- }
-
- return tessellator.trapezoids;
-}
-
-QVector<QGLTrapezoid> QGLRectMaskGenerator::generateTrapezoids()
-{
- Q_ASSERT(transformedPath.elementCount() == 5);
-
- QOpenGLImmediateModeTessellator tessellator;
- if (matrix().type() <= QTransform::TxScale) {
- QPointF a = transformedPath.elementAt(0);
- QPointF b = transformedPath.elementAt(1);
- QPointF c = transformedPath.elementAt(2);
- QPointF d = transformedPath.elementAt(3);
-
- QPointF first = (a + d) * 0.5;
- QPointF last = (b + c) * 0.5;
-
- QPointF delta = a - d;
-
- // manhattan distance (no rotation)
- qreal width = qAbs(delta.x()) + qAbs(delta.y());
-
- Q_ASSERT(qFuzzyIsNull(delta.x()) || qFuzzyIsNull(delta.y()));
-
- tessellator.tessellateRect(first, last, width);
- } else {
- QPointF points[5];
-
- for (int i = 0; i < 5; ++i)
- points[i] = transformedPath.elementAt(i);
-
- tessellator.tessellateConvex(points, 5);
- }
- return tessellator.trapezoids;
-}
-
-static QPainterPath ellipseRectToPath(const QRectF &rect)
-{
- QPainterPath path;
- path.addEllipse(rect);
- return path;
-}
-
-QGLEllipseMaskGenerator::QGLEllipseMaskGenerator(const QRectF &rect, const QTransform &matrix, QGLOffscreen &offs, GLuint program, int *locations)
- : QGLMaskGenerator(ellipseRectToPath(rect), matrix),
- ellipseRect(rect),
- offscreen(&offs),
- maskFragmentProgram(program),
- maskVariableLocations(locations)
-{
-}
-
-QRect QGLEllipseMaskGenerator::screenRect()
-{
- QPointF center = ellipseRect.center();
-
- QPointF points[] = {
- QPointF(ellipseRect.left(), center.y()),
- QPointF(ellipseRect.right(), center.y()),
- QPointF(center.x(), ellipseRect.top()),
- QPointF(center.x(), ellipseRect.bottom())
- };
-
- qreal min_screen_delta_len = QREAL_MAX;
-
- for (int i = 0; i < 4; ++i) {
- QPointF delta = points[i] - center;
-
- // normalize
- delta /= qSqrt(delta.x() * delta.x() + delta.y() * delta.y());
-
- QPointF screen_delta(matrix().m11() * delta.x() + matrix().m21() * delta.y(),
- matrix().m12() * delta.x() + matrix().m22() * delta.y());
-
- min_screen_delta_len = qMin(min_screen_delta_len,
- qreal(qSqrt(screen_delta.x() * screen_delta.x() + screen_delta.y() * screen_delta.y())));
- }
-
- const qreal padding = 2.0f;
-
- qreal grow = padding / min_screen_delta_len;
-
- QRectF boundingRect = ellipseRect.adjusted(-grow, -grow, grow, grow);
-
- boundingRect = matrix().mapRect(boundingRect);
-
- QPointF p(0.5, 0.5);
-
- screen_rect = QRect((boundingRect.topLeft() - p).toPoint(),
- (boundingRect.bottomRight() + p).toPoint());
-
- return screen_rect;
-}
-
-void QGLEllipseMaskGenerator::drawMask(const QRect &rect)
-{
-#ifdef QT_OPENGL_ES
- Q_UNUSED(rect);
-#else
- QGLContext *ctx = offscreen->context();
- offscreen->bind();
-
- glDisable(GL_TEXTURE_GEN_S);
- glDisable(GL_TEXTURE_1D);
-
- // fragment program needs the inverse radii of the ellipse
- glTexCoord2f(1.0f / (ellipseRect.width() * 0.5f),
- 1.0f / (ellipseRect.height() * 0.5f));
-
- QTransform translate(1, 0, 0, 1, -ellipseRect.center().x(), -ellipseRect.center().y());
- QTransform gl_to_qt(1, 0, 0, -1, 0, offscreen->drawableSize().height());
- QTransform inv_matrix = gl_to_qt * matrix().inverted() * translate;
-
- float m[3][4] = { { float(inv_matrix.m11()), float(inv_matrix.m12()), float(inv_matrix.m13()) },
- { float(inv_matrix.m21()), float(inv_matrix.m22()), float(inv_matrix.m23()) },
- { float(inv_matrix.m31()), float(inv_matrix.m32()), float(inv_matrix.m33()) } };
-
- QPoint offs(screen_rect.left() - rect.left(), (offscreen->drawableSize().height() - screen_rect.top())
- - (offscreen->offscreenSize().height() - rect.top()));
-
- // last component needs to be 1.0f to avoid Nvidia bug on linux
- float ellipse_offset[4] = { float(offs.x()), float(offs.y()), 0.0f, 1.0f };
-
- GLfloat vertexArray[4 * 2];
- qt_add_rect_to_array(rect, vertexArray);
-
- glBlendFunc(GL_ONE, GL_ZERO); // set mask
- glEnable(GL_FRAGMENT_PROGRAM_ARB);
- glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, maskFragmentProgram);
-
- glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, maskVariableLocations[VAR_INV_MATRIX_M0], m[0]);
- glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, maskVariableLocations[VAR_INV_MATRIX_M1], m[1]);
- glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, maskVariableLocations[VAR_INV_MATRIX_M2], m[2]);
-
- glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, maskVariableLocations[VAR_ELLIPSE_OFFSET], ellipse_offset);
-
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(2, GL_FLOAT, 0, vertexArray);
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisable(GL_FRAGMENT_PROGRAM_ARB);
-#endif
-}
-
-void QOpenGLPaintEnginePrivate::drawOffscreenPath(const QPainterPath &path)
-{
-#ifdef Q_WS_QWS
- Q_UNUSED(path);
-#else
- DEBUG_ONCE_STR("QOpenGLPaintEnginePrivate::drawOffscreenPath()");
-
- disableClipping();
-
- GLuint program = qt_gl_program_cache()->getProgram(device->context(),
- FRAGMENT_PROGRAM_MASK_TRAPEZOID_AA, 0, true);
- QGLPathMaskGenerator maskGenerator(path, matrix, offscreen, program);
- addItem(qt_mask_texture_cache()->getMask(maskGenerator, this));
-
- enableClipping();
-#endif
-}
-
-void QOpenGLPaintEnginePrivate::drawFastRect(const QRectF &r)
-{
- Q_Q(QOpenGLPaintEngine);
- DEBUG_ONCE_STR("QOpenGLPaintEngine::drawRects(): drawing fast rect");
-
- GLfloat vertexArray[10];
- qt_add_rect_to_array(r, vertexArray);
-
- if (has_pen)
- QOpenGLCoordinateOffset::enableOffset(this);
-
- if (has_brush) {
- flushDrawQueue();
-
- bool temp = high_quality_antialiasing;
- high_quality_antialiasing = false;
-
- q->updateCompositionMode(composition_mode);
-
- setGradientOps(cbrush, r);
-
- bool fast_style = current_style == Qt::LinearGradientPattern
- || current_style == Qt::SolidPattern;
-
- if (fast_style && has_fast_composition_mode) {
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(2, GL_FLOAT, 0, vertexArray);
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- glDisableClientState(GL_VERTEX_ARRAY);
- } else {
- composite(r);
- }
-
- high_quality_antialiasing = temp;
-
- q->updateCompositionMode(composition_mode);
- }
-
- if (has_pen) {
- if (has_fast_pen && !high_quality_antialiasing) {
- setGradientOps(cpen.brush(), r);
-
- vertexArray[8] = vertexArray[0];
- vertexArray[9] = vertexArray[1];
-
- glVertexPointer(2, GL_FLOAT, 0, vertexArray);
- glEnableClientState(GL_VERTEX_ARRAY);
- glDrawArrays(GL_LINE_STRIP, 0, 5);
- glDisableClientState(GL_VERTEX_ARRAY);
- } else {
- QPainterPath path;
- path.setFillRule(Qt::WindingFill);
-
- qreal left = r.left();
- qreal right = r.right();
- qreal top = r.top();
- qreal bottom = r.bottom();
-
- path.moveTo(left, top);
- path.lineTo(right, top);
- path.lineTo(right, bottom);
- path.lineTo(left, bottom);
- path.lineTo(left, top);
-
- strokePath(path, false);
- }
-
- QOpenGLCoordinateOffset::disableOffset(this);
- }
-}
-
-bool QOpenGLPaintEnginePrivate::isFastRect(const QRectF &rect)
-{
- if (matrix.type() < QTransform::TxRotate) {
- QRectF r = matrix.mapRect(rect);
- return r.topLeft().toPoint() == r.topLeft()
- && r.bottomRight().toPoint() == r.bottomRight();
- }
-
- return false;
-}
-
-void QOpenGLPaintEngine::drawRects(const QRect *rects, int rectCount)
-{
- struct RectF {
- qreal x;
- qreal y;
- qreal w;
- qreal h;
- };
- Q_ASSERT(sizeof(RectF) == sizeof(QRectF));
- RectF fr[256];
- while (rectCount) {
- int i = 0;
- while (i < rectCount && i < 256) {
- fr[i].x = rects[i].x();
- fr[i].y = rects[i].y();
- fr[i].w = rects[i].width();
- fr[i].h = rects[i].height();
- ++i;
- }
- drawRects((QRectF *)(void *)fr, i);
- rects += i;
- rectCount -= i;
- }
-}
-
-void QOpenGLPaintEngine::drawRects(const QRectF *rects, int rectCount)
-{
- Q_D(QOpenGLPaintEngine);
-
- if (d->use_emulation) {
- QPaintEngineEx::drawRects(rects, rectCount);
- return;
- }
-
- for (int i=0; i<rectCount; ++i) {
- const QRectF &r = rects[i];
-
- // optimization for rects which can be drawn aliased
- if (!d->high_quality_antialiasing || d->isFastRect(r)) {
- d->drawFastRect(r);
- } else {
- QPainterPath path;
- path.addRect(r);
-
- if (d->has_brush) {
- d->disableClipping();
- GLuint program = qt_gl_program_cache()->getProgram(d->device->context(),
- FRAGMENT_PROGRAM_MASK_TRAPEZOID_AA, 0, true);
-
- if (d->matrix.type() >= QTransform::TxProject) {
- QGLPathMaskGenerator maskGenerator(path, d->matrix, d->offscreen, program);
- d->addItem(qt_mask_texture_cache()->getMask(maskGenerator, d));
- } else {
- QGLRectMaskGenerator maskGenerator(path, d->matrix, d->offscreen, program);
- d->addItem(qt_mask_texture_cache()->getMask(maskGenerator, d));
- }
-
- d->enableClipping();
- }
-
- if (d->has_pen) {
- if (d->has_fast_pen)
- d->strokeLines(path);
- else
- d->strokePath(path, false);
- }
- }
- }
-}
-
-static void addQuadAsTriangle(GLfloat *quad, GLfloat *triangle)
-{
- triangle[0] = quad[0];
- triangle[1] = quad[1];
-
- triangle[2] = quad[2];
- triangle[3] = quad[3];
-
- triangle[4] = quad[4];
- triangle[5] = quad[5];
-
- triangle[6] = quad[4];
- triangle[7] = quad[5];
-
- triangle[8] = quad[6];
- triangle[9] = quad[7];
-
- triangle[10] = quad[0];
- triangle[11] = quad[1];
-}
-
-void QOpenGLPaintEngine::drawPoints(const QPoint *points, int pointCount)
-{
- Q_ASSERT(sizeof(QT_PointF) == sizeof(QPointF));
- QT_PointF fp[256];
- while (pointCount) {
- int i = 0;
- while (i < pointCount && i < 256) {
- fp[i].x = points[i].x();
- fp[i].y = points[i].y();
- ++i;
- }
- drawPoints((QPointF *)(void *)fp, i);
- points += i;
- pointCount -= i;
- }
-}
-
-void QOpenGLPaintEngine::drawPoints(const QPointF *points, int pointCount)
-{
- Q_D(QOpenGLPaintEngine);
-
- if (d->use_emulation) {
- QPaintEngineEx::drawPoints(points, pointCount);
- return;
- }
-
- d->setGradientOps(d->cpen.brush(), QRectF());
-
- if (!d->cpen.isCosmetic() || d->high_quality_antialiasing) {
- Qt::PenCapStyle capStyle = d->cpen.capStyle();
- if (capStyle == Qt::FlatCap)
- d->cpen.setCapStyle(Qt::SquareCap);
- QPaintEngine::drawPoints(points, pointCount);
- d->cpen.setCapStyle(capStyle);
- return;
- }
-
- d->flushDrawQueue();
-
- if (d->has_fast_pen) {
- QVarLengthArray<GLfloat> vertexArray(6 * pointCount);
-
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- glLoadIdentity();
-
- int j = 0;
- for (int i = 0; i < pointCount; ++i) {
- QPointF mapped = d->matrix.map(points[i]);
-
- GLfloat x = GLfloat(qRound(mapped.x()));
- GLfloat y = GLfloat(qRound(mapped.y()));
-
- vertexArray[j++] = x;
- vertexArray[j++] = y - 0.5f;
-
- vertexArray[j++] = x + 1.5f;
- vertexArray[j++] = y + 1.0f;
-
- vertexArray[j++] = x;
- vertexArray[j++] = y + 1.0f;
- }
-
- glEnableClientState(GL_VERTEX_ARRAY);
-
- glVertexPointer(2, GL_FLOAT, 0, vertexArray.constData());
- glDrawArrays(GL_TRIANGLES, 0, pointCount*3);
-
- glDisableClientState(GL_VERTEX_ARRAY);
-
- glPopMatrix();
- return;
- }
-
- const qreal *vertexArray = reinterpret_cast<const qreal*>(&points[0]);
-
- if (sizeof(qreal) == sizeof(double)) {
- Q_ASSERT(sizeof(QPointF) == 16);
- glVertexPointer(2, GL_DOUBLE, 0, vertexArray);
- }
- else {
- Q_ASSERT(sizeof(QPointF) == 8);
- glVertexPointer(2, GL_FLOAT, 0, vertexArray);
- }
-
- glEnableClientState(GL_VERTEX_ARRAY);
- glDrawArrays(GL_POINTS, 0, pointCount);
- glDisableClientState(GL_VERTEX_ARRAY);
-}
-
-void QOpenGLPaintEngine::drawLines(const QLine *lines, int lineCount)
-{
- struct PointF {
- qreal x;
- qreal y;
- };
- struct LineF {
- PointF p1;
- PointF p2;
- };
- Q_ASSERT(sizeof(PointF) == sizeof(QPointF));
- Q_ASSERT(sizeof(LineF) == sizeof(QLineF));
- LineF fl[256];
- while (lineCount) {
- int i = 0;
- while (i < lineCount && i < 256) {
- fl[i].p1.x = lines[i].x1();
- fl[i].p1.y = lines[i].y1();
- fl[i].p2.x = lines[i].x2();
- fl[i].p2.y = lines[i].y2();
- ++i;
- }
- drawLines((QLineF *)(void *)fl, i);
- lines += i;
- lineCount -= i;
- }
-}
-
-void QOpenGLPaintEngine::drawLines(const QLineF *lines, int lineCount)
-{
- Q_D(QOpenGLPaintEngine);
-
- if (d->use_emulation) {
- QPaintEngineEx::drawLines(lines, lineCount);
- return;
- }
-
- if (d->has_pen) {
- QOpenGLCoordinateOffset offset(d);
- if (d->has_fast_pen && !d->high_quality_antialiasing) {
- //### gradient resolving on lines isn't correct
- d->setGradientOps(d->cpen.brush(), QRectF());
-
- bool useRects = false;
- // scale or 90 degree rotation?
- if (d->matrix.type() <= QTransform::TxTranslate
- || (!d->cpen.isCosmetic()
- && (d->matrix.type() <= QTransform::TxScale
- || (d->matrix.type() == QTransform::TxRotate
- && d->matrix.m11() == 0 && d->matrix.m22() == 0)))) {
- useRects = true;
- for (int i = 0; i < lineCount; ++i) {
- if (lines[i].p1().x() != lines[i].p2().x()
- && lines[i].p1().y() != lines[i].p2().y()) {
- useRects = false;
- break;
- }
- }
- }
-
- GLfloat endCap = d->cpen.capStyle() == Qt::FlatCap ? 0.0f : 0.5f;
- if (useRects) {
- QVarLengthArray<GLfloat> vertexArray(12 * lineCount);
-
- GLfloat quad[8];
- for (int i = 0; i < lineCount; ++i) {
- GLfloat x1 = lines[i].x1();
- GLfloat x2 = lines[i].x2();
- GLfloat y1 = lines[i].y1();
- GLfloat y2 = lines[i].y2();
-
- if (x1 == x2) {
- if (y1 > y2)
- qSwap(y1, y2);
-
- quad[0] = x1 - 0.5f;
- quad[1] = y1 - endCap;
-
- quad[2] = x1 + 0.5f;
- quad[3] = y1 - endCap;
-
- quad[4] = x1 + 0.5f;
- quad[5] = y2 + endCap;
-
- quad[6] = x1 - 0.5f;
- quad[7] = y2 + endCap;
- } else {
- if (x1 > x2)
- qSwap(x1, x2);
-
- quad[0] = x1 - endCap;
- quad[1] = y1 + 0.5f;
-
- quad[2] = x1 - endCap;
- quad[3] = y1 - 0.5f;
-
- quad[4] = x2 + endCap;
- quad[5] = y1 - 0.5f;
-
- quad[6] = x2 + endCap;
- quad[7] = y1 + 0.5f;
- }
-
- addQuadAsTriangle(quad, &vertexArray[12*i]);
- }
-
- glEnableClientState(GL_VERTEX_ARRAY);
-
- glVertexPointer(2, GL_FLOAT, 0, vertexArray.constData());
- glDrawArrays(GL_TRIANGLES, 0, lineCount*6);
-
- glDisableClientState(GL_VERTEX_ARRAY);
- } else {
- QVarLengthArray<GLfloat> vertexArray(4 * lineCount);
- for (int i = 0; i < lineCount; ++i) {
- const QPointF a = lines[i].p1();
- vertexArray[4*i] = lines[i].x1();
- vertexArray[4*i+1] = lines[i].y1();
- vertexArray[4*i+2] = lines[i].x2();
- vertexArray[4*i+3] = lines[i].y2();
- }
-
- glEnableClientState(GL_VERTEX_ARRAY);
-
- glVertexPointer(2, GL_FLOAT, 0, vertexArray.constData());
- glDrawArrays(GL_LINES, 0, lineCount*2);
-
- glVertexPointer(2, GL_FLOAT, 4*sizeof(GLfloat), vertexArray.constData() + 2);
- glDrawArrays(GL_POINTS, 0, lineCount);
-
- glDisableClientState(GL_VERTEX_ARRAY);
- }
- } else {
- QPainterPath path;
- path.setFillRule(Qt::WindingFill);
- for (int i=0; i<lineCount; ++i) {
- const QLineF &l = lines[i];
-
- if (l.p1() == l.p2()) {
- if (d->cpen.capStyle() != Qt::FlatCap) {
- QPointF p = l.p1();
- drawPoints(&p, 1);
- }
- continue;
- }
-
- path.moveTo(l.x1(), l.y1());
- path.lineTo(l.x2(), l.y2());
- }
-
- if (d->has_fast_pen && d->high_quality_antialiasing)
- d->strokeLines(path);
- else
- d->strokePath(path, false);
- }
- }
-}
-
-void QOpenGLPaintEngine::drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode)
-{
- Q_ASSERT(sizeof(QT_PointF) == sizeof(QPointF));
- QVarLengthArray<QT_PointF> p(pointCount);
- for (int i=0; i<pointCount; ++i) {
- p[i].x = points[i].x();
- p[i].y = points[i].y();
- }
- drawPolygon((QPointF *)p.data(), pointCount, mode);
-}
-
-void QOpenGLPaintEngine::drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode)
-{
- Q_D(QOpenGLPaintEngine);
- if(pointCount < 2)
- return;
-
- if (d->use_emulation) {
- QPaintEngineEx::drawPolygon(points, pointCount, mode);
- return;
- }
-
- QRectF bounds;
- if ((mode == ConvexMode && !d->high_quality_antialiasing && state()->brushNeedsResolving()) ||
- ((d->has_fast_pen && !d->high_quality_antialiasing) && state()->penNeedsResolving())) {
- qreal minx = points[0].x(), miny = points[0].y(),
- maxx = points[0].x(), maxy = points[0].y();
- for (int i = 1; i < pointCount; ++i) {
- const QPointF &pt = points[i];
- if (minx > pt.x())
- minx = pt.x();
- if (miny > pt.y())
- miny = pt.y();
- if (maxx < pt.x())
- maxx = pt.x();
- if (maxy < pt.y())
- maxy = pt.y();
- }
- bounds = QRectF(minx, maxx, maxx-minx, maxy-miny);
- }
-
- QOpenGLCoordinateOffset offset(d);
-
- if (d->has_brush && mode != PolylineMode) {
- if (mode == ConvexMode && !d->high_quality_antialiasing) {
- //### resolving on polygon from points isn't correct
- d->setGradientOps(d->cbrush, bounds);
-
- const qreal *vertexArray = reinterpret_cast<const qreal*>(&points[0]);
-
- if (sizeof(qreal) == sizeof(double)) {
- Q_ASSERT(sizeof(QPointF) == 16);
- glVertexPointer(2, GL_DOUBLE, 0, vertexArray);
- }
- else {
- Q_ASSERT(sizeof(QPointF) == 8);
- glVertexPointer(2, GL_FLOAT, 0, vertexArray);
- }
-
- glEnableClientState(GL_VERTEX_ARRAY);
- glDrawArrays(GL_TRIANGLE_FAN, 0, pointCount);
- glDisableClientState(GL_VERTEX_ARRAY);
- } else {
- QPainterPath path;
- path.setFillRule(mode == WindingMode ? Qt::WindingFill : Qt::OddEvenFill);
- path.moveTo(points[0]);
- for (int i=1; i<pointCount; ++i)
- path.lineTo(points[i]);
- d->fillPath(path);
- }
- }
-
- if (d->has_pen) {
- if (d->has_fast_pen && !d->high_quality_antialiasing) {
- d->setGradientOps(d->cpen.brush(), bounds);
- QVarLengthArray<GLfloat> vertexArray(pointCount*2 + 2);
- glVertexPointer(2, GL_FLOAT, 0, vertexArray.constData());
- int i;
- for (i=0; i<pointCount; ++i) {
- vertexArray[i*2] = points[i].x();
- vertexArray[i*2+1] = points[i].y();
- }
-
- glEnableClientState(GL_VERTEX_ARRAY);
- if (mode != PolylineMode) {
- vertexArray[i*2] = vertexArray[0];
- vertexArray[i*2+1] = vertexArray[1];
- glDrawArrays(GL_LINE_STRIP, 0, pointCount+1);
- } else {
- glDrawArrays(GL_LINE_STRIP, 0, pointCount);
- glDrawArrays(GL_POINTS, pointCount-1, 1);
- }
- glDisableClientState(GL_VERTEX_ARRAY);
- } else {
- QPainterPath path(points[0]);
- for (int i = 1; i < pointCount; ++i)
- path.lineTo(points[i]);
- if (mode != PolylineMode)
- path.lineTo(points[0]);
-
- if (d->has_fast_pen)
- d->strokeLines(path);
- else
- d->strokePath(path, true);
- }
- }
-}
-
-void QOpenGLPaintEnginePrivate::strokeLines(const QPainterPath &path)
-{
- DEBUG_ONCE_STR("QOpenGLPaintEnginePrivate::strokeLines()");
-
- qreal penWidth = cpen.widthF();
-
- GLuint program = qt_gl_program_cache()->getProgram(device->context(),
- FRAGMENT_PROGRAM_MASK_TRAPEZOID_AA, 0, true);
- QGLLineMaskGenerator maskGenerator(path, matrix, penWidth == 0 ? 1.0 : penWidth,
- offscreen, program);
-
- disableClipping();
-
- QBrush temp = cbrush;
- QPointF origin = brush_origin;
-
- cbrush = cpen.brush();
- brush_origin = QPointF();
-
- addItem(qt_mask_texture_cache()->getMask(maskGenerator, this));
-
- cbrush = temp;
- brush_origin = origin;
-
- enableClipping();
-}
-
-Q_GUI_EXPORT 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();
-
- qreal txscale = 1;
- if (cpen.isCosmetic() || (qt_scaleForTransform(matrix, &txscale) && txscale != 1)) {
- QTransform temp = matrix;
- matrix = QTransform();
- glPushMatrix();
-
- if (has_antialiasing) {
- glLoadIdentity();
- } else {
- float offs_matrix[] =
- { 1, 0, 0, 0,
- 0, 1, 0, 0,
- 0, 0, 1, 0,
- 0.5, 0.5, 0, 1 };
- glLoadMatrixf(offs_matrix);
- }
-
- QPen pen = cpen;
- if (txscale != 1)
- pen.setWidthF(pen.widthF() * txscale);
- if (use_cache)
- fillPath(qt_opengl_stroke_cache()->getStrokedPath(temp.map(path), pen));
- else
- fillPath(strokeForPath(temp.map(path), pen));
-
- glPopMatrix();
- matrix = temp;
- } else if (use_cache) {
- fillPath(qt_opengl_stroke_cache()->getStrokedPath(path, cpen));
- } else {
- fillPath(strokeForPath(path, cpen));
- }
-
- cbrush = old_brush;
-}
-
-void QOpenGLPaintEnginePrivate::strokePathFastPen(const QPainterPath &path, bool needsResolving)
-{
-#ifndef QT_OPENGL_ES
- QRectF bounds;
- if (needsResolving)
- bounds = path.controlPointRect();
- setGradientOps(cpen.brush(), bounds);
-
- QBezier beziers[32];
- for (int i=0; i<path.elementCount(); ++i) {
- const QPainterPath::Element &e = path.elementAt(i);
- switch (e.type) {
- case QPainterPath::MoveToElement:
- if (i != 0)
- glEnd(); // GL_LINE_STRIP
- glBegin(GL_LINE_STRIP);
- glVertex2d(e.x, e.y);
-
- break;
- case QPainterPath::LineToElement:
- glVertex2d(e.x, e.y);
- break;
-
- case QPainterPath::CurveToElement:
- {
- QPointF sp = path.elementAt(i-1);
- QPointF cp2 = path.elementAt(i+1);
- QPointF ep = path.elementAt(i+2);
- i+=2;
-
- qreal inverseScaleHalf = inverseScale / 2;
- beziers[0] = QBezier::fromPoints(sp, e, cp2, ep);
- QBezier *b = beziers;
- while (b >= beziers) {
- // check if we can pop the top bezier curve from the stack
- qreal l = qAbs(b->x4 - b->x1) + qAbs(b->y4 - b->y1);
- qreal d;
- if (l > inverseScale) {
- d = qAbs( (b->x4 - b->x1)*(b->y1 - b->y2)
- - (b->y4 - b->y1)*(b->x1 - b->x2) )
- + qAbs( (b->x4 - b->x1)*(b->y1 - b->y3)
- - (b->y4 - b->y1)*(b->x1 - b->x3) );
- d /= l;
- } else {
- d = qAbs(b->x1 - b->x2) + qAbs(b->y1 - b->y2) +
- qAbs(b->x1 - b->x3) + qAbs(b->y1 - b->y3);
- }
- if (d < inverseScaleHalf || b == beziers + 31) {
- // good enough, we pop it off and add the endpoint
- glVertex2d(b->x4, b->y4);
- --b;
- } else {
- // split, second half of the polygon goes lower into the stack
- b->split(b+1, b);
- ++b;
- }
- }
- } // case CurveToElement
- default:
- break;
- } // end of switch
- }
- glEnd(); // GL_LINE_STRIP
-#else
- // have to use vertex arrays on embedded
- QRectF bounds;
- if (needsResolving)
- bounds = path.controlPointRect();
- setGradientOps(cpen.brush(), bounds);
-
- glEnableClientState(GL_VERTEX_ARRAY);
- tess_points.reset();
- QBezier beziers[32];
- for (int i=0; i<path.elementCount(); ++i) {
- const QPainterPath::Element &e = path.elementAt(i);
- switch (e.type) {
- case QPainterPath::MoveToElement:
- if (i != 0) {
- glVertexPointer(2, GL_FLOAT, 0, tess_points.data());
- glDrawArrays(GL_LINE_STRIP, 0, tess_points.size());
- tess_points.reset();
- }
- tess_points.add(QPointF(e.x, e.y));
-
- break;
- case QPainterPath::LineToElement:
- tess_points.add(QPointF(e.x, e.y));
- break;
-
- case QPainterPath::CurveToElement:
- {
- QPointF sp = path.elementAt(i-1);
- QPointF cp2 = path.elementAt(i+1);
- QPointF ep = path.elementAt(i+2);
- i+=2;
-
- qreal inverseScaleHalf = inverseScale / 2;
- beziers[0] = QBezier::fromPoints(sp, e, cp2, ep);
- QBezier *b = beziers;
- while (b >= beziers) {
- // check if we can pop the top bezier curve from the stack
- qreal l = qAbs(b->x4 - b->x1) + qAbs(b->y4 - b->y1);
- qreal d;
- if (l > inverseScale) {
- d = qAbs( (b->x4 - b->x1)*(b->y1 - b->y2)
- - (b->y4 - b->y1)*(b->x1 - b->x2) )
- + qAbs( (b->x4 - b->x1)*(b->y1 - b->y3)
- - (b->y4 - b->y1)*(b->x1 - b->x3) );
- d /= l;
- } else {
- d = qAbs(b->x1 - b->x2) + qAbs(b->y1 - b->y2) +
- qAbs(b->x1 - b->x3) + qAbs(b->y1 - b->y3);
- }
- if (d < inverseScaleHalf || b == beziers + 31) {
- // good enough, we pop it off and add the endpoint
- tess_points.add(QPointF(b->x4, b->y4));
- --b;
- } else {
- // split, second half of the polygon goes lower into the stack
- b->split(b+1, b);
- ++b;
- }
- }
- } // case CurveToElement
- default:
- break;
- } // end of switch
- }
- glVertexPointer(2, GL_FLOAT, 0, tess_points.data());
- glDrawArrays(GL_LINE_STRIP, 0, tess_points.size());
- glDisableClientState(GL_VERTEX_ARRAY);
-#endif
-}
-
-static bool pathClosed(const QPainterPath &path)
-{
- QPointF lastMoveTo = path.elementAt(0);
- QPointF lastPoint = lastMoveTo;
-
- for (int i = 1; i < path.elementCount(); ++i) {
- const QPainterPath::Element &e = path.elementAt(i);
- switch (e.type) {
- case QPainterPath::MoveToElement:
- if (lastMoveTo != lastPoint)
- return false;
- lastMoveTo = lastPoint = e;
- break;
- case QPainterPath::LineToElement:
- lastPoint = e;
- break;
- case QPainterPath::CurveToElement:
- lastPoint = path.elementAt(i + 2);
- i+=2;
- break;
- default:
- break;
- }
- }
-
- return lastMoveTo == lastPoint;
-}
-
-void QOpenGLPaintEngine::drawPath(const QPainterPath &path)
-{
- Q_D(QOpenGLPaintEngine);
-
- if (path.isEmpty())
- return;
-
- if (d->use_emulation) {
- QPaintEngineEx::drawPath(path);
- return;
- }
-
- QOpenGLCoordinateOffset offset(d);
-
- if (d->has_brush) {
- bool path_closed = pathClosed(path);
-
- bool has_thick_pen =
- path_closed
- && d->has_pen
- && d->cpen.style() == Qt::SolidLine
- && d->cpen.isSolid()
- && d->cpen.color().alpha() == 255
- && d->txop < QTransform::TxProject
- && d->cpen.widthF() >= 2 / qSqrt(qMin(d->matrix.m11() * d->matrix.m11()
- + d->matrix.m21() * d->matrix.m21(),
- d->matrix.m12() * d->matrix.m12()
- + d->matrix.m22() * d->matrix.m22()));
-
- if (has_thick_pen) {
- DEBUG_ONCE qDebug() << "QOpenGLPaintEngine::drawPath(): Using thick pen optimization, style:" << d->cbrush.style();
-
- d->flushDrawQueue();
-
- bool temp = d->high_quality_antialiasing;
- d->high_quality_antialiasing = false;
-
- updateCompositionMode(d->composition_mode);
-
- d->fillPath(path);
-
- d->high_quality_antialiasing = temp;
- updateCompositionMode(d->composition_mode);
- } else {
- d->fillPath(path);
- }
- }
-
- if (d->has_pen) {
- if (d->has_fast_pen && !d->high_quality_antialiasing)
- d->strokePathFastPen(path, state()->penNeedsResolving());
- else
- d->strokePath(path, true);
- }
-}
-
-void QOpenGLPaintEnginePrivate::drawImageAsPath(const QRectF &r, const QImage &img, const QRectF &sr)
-{
- QBrush old_brush = cbrush;
- QPointF old_brush_origin = brush_origin;
-
- qreal scaleX = r.width() / sr.width();
- qreal scaleY = r.height() / sr.height();
-
- QTransform brush_matrix = QTransform::fromTranslate(r.left(), r.top());
- brush_matrix.scale(scaleX, scaleY);
- brush_matrix.translate(-sr.left(), -sr.top());
-
- cbrush = QBrush(img);
- cbrush.setTransform(brush_matrix);
- brush_origin = QPointF();
-
- QPainterPath p;
- p.addRect(r);
- fillPath(p);
-
- cbrush = old_brush;
- brush_origin = old_brush_origin;
-}
-
-void QOpenGLPaintEnginePrivate::drawTiledImageAsPath(const QRectF &r, const QImage &img, qreal sx, qreal sy,
- const QPointF &offset)
-{
- QBrush old_brush = cbrush;
- QPointF old_brush_origin = brush_origin;
-
- QTransform brush_matrix = QTransform::fromTranslate(r.left(), r.top());
- brush_matrix.scale(sx, sy);
- brush_matrix.translate(-offset.x(), -offset.y());
-
- cbrush = QBrush(img);
- cbrush.setTransform(brush_matrix);
- brush_origin = QPointF();
-
- QPainterPath p;
- p.addRect(r);
- fillPath(p);
-
- cbrush = old_brush;
- brush_origin = old_brush_origin;
-}
-
-static const QRectF scaleRect(const QRectF &r, qreal sx, qreal sy)
-{
- return QRectF(r.x() * sx, r.y() * sy, r.width() * sx, r.height() * sy);
-}
-
-template <typename T>
-static const T qSubImage(const T &image, const QRectF &src, QRectF *srcNew)
-{
- const int sx1 = qMax(0, qFloor(src.left()));
- const int sy1 = qMax(0, qFloor(src.top()));
- const int sx2 = qMin(image.width(), qCeil(src.right()));
- const int sy2 = qMin(image.height(), qCeil(src.bottom()));
-
- const T sub = image.copy(sx1, sy1, sx2 - sx1, sy2 - sy1);
-
- if (srcNew)
- *srcNew = src.translated(-sx1, -sy1);
-
- return sub;
-}
-
-void QOpenGLPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr)
-{
- Q_D(QOpenGLPaintEngine);
- if (pm.depth() == 1) {
- QPixmap tpx(pm.size());
- tpx.fill(Qt::transparent);
- QPainter p(&tpx);
- p.setPen(d->cpen);
- p.drawPixmap(0, 0, pm);
- p.end();
- drawPixmap(r, tpx, sr);
- return;
- }
-
- const int sz = d->max_texture_size;
- if (pm.width() > sz || pm.height() > sz) {
- QRectF subsr;
- const QPixmap sub = qSubImage(pm, sr, &subsr);
-
- if (sub.width() <= sz && sub.height() <= sz) {
- drawPixmap(r, sub, subsr);
- } else {
- const QPixmap scaled = sub.scaled(sz, sz, Qt::KeepAspectRatio);
- const qreal sx = scaled.width() / qreal(sub.width());
- const qreal sy = scaled.height() / qreal(sub.height());
-
- drawPixmap(r, scaled, scaleRect(subsr, sx, sy));
- }
- return;
- }
-
-
- if (d->composition_mode > QPainter::CompositionMode_Plus || (d->high_quality_antialiasing && !d->isFastRect(r)))
- d->drawImageAsPath(r, pm.toImage(), sr);
- else {
- GLenum target = qt_gl_preferredTextureTarget();
- d->flushDrawQueue();
- QGLTexture *tex =
- d->device->context()->d_func()->bindTexture(pm, target, GL_RGBA,
- QGLContext::InternalBindOption);
- drawTextureRect(pm.width(), pm.height(), r, sr, target, tex);
- }
-}
-
-void QOpenGLPaintEngine::drawTiledPixmap(const QRectF &r, const QPixmap &pm, const QPointF &offset)
-{
- Q_D(QOpenGLPaintEngine);
- if (pm.depth() == 1) {
- QPixmap tpx(pm.size());
- tpx.fill(Qt::transparent);
- QPainter p(&tpx);
- p.setPen(d->cpen);
- p.drawPixmap(0, 0, pm);
- p.end();
- drawTiledPixmap(r, tpx, offset);
- return;
- }
-
- QImage scaled;
- const int sz = d->max_texture_size;
- if (pm.width() > sz || pm.height() > sz) {
- int rw = qCeil(r.width());
- int rh = qCeil(r.height());
- if (rw < pm.width() && rh < pm.height()) {
- drawTiledPixmap(r, pm.copy(0, 0, rw, rh), offset);
- return;
- }
-
- scaled = pm.toImage().scaled(sz, sz, Qt::KeepAspectRatio);
- }
-
- if (d->composition_mode > QPainter::CompositionMode_Plus || (d->high_quality_antialiasing && !d->isFastRect(r))) {
- if (scaled.isNull())
- d->drawTiledImageAsPath(r, pm.toImage(), 1, 1, offset);
- else {
- const qreal sx = pm.width() / qreal(scaled.width());
- const qreal sy = pm.height() / qreal(scaled.height());
- d->drawTiledImageAsPath(r, scaled, sx, sy, offset);
- }
- } else {
- d->flushDrawQueue();
-
- QGLTexture *tex;
- if (scaled.isNull())
- tex = d->device->context()->d_func()->bindTexture(pm, GL_TEXTURE_2D, GL_RGBA,
- QGLContext::InternalBindOption);
- else
- tex = d->device->context()->d_func()->bindTexture(scaled, GL_TEXTURE_2D, GL_RGBA,
- QGLContext::InternalBindOption);
- updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, d->use_smooth_pixmap_transform);
-
-#ifndef QT_OPENGL_ES
- glPushAttrib(GL_CURRENT_BIT);
- glDisable(GL_TEXTURE_GEN_S);
-#endif
- glColor4f(d->opacity, d->opacity, d->opacity, d->opacity);
- glEnable(GL_TEXTURE_2D);
-
- GLdouble tc_w = r.width()/pm.width();
- GLdouble tc_h = r.height()/pm.height();
-
- // Rotate the texture so that it is aligned correctly and the
- // wrapping is done correctly
- if (tex->options & QGLContext::InvertedYBindOption) {
- glMatrixMode(GL_TEXTURE);
- glPushMatrix();
- glRotatef(180.0, 0.0, 1.0, 0.0);
- glRotatef(180.0, 0.0, 0.0, 1.0);
- }
-
- GLfloat vertexArray[4*2];
- GLfloat texCoordArray[4*2];
-
- double offset_x = offset.x() / pm.width();
- double offset_y = offset.y() / pm.height();
-
- qt_add_rect_to_array(r, vertexArray);
- qt_add_texcoords_to_array(offset_x, offset_y,
- tc_w + offset_x, tc_h + offset_y, texCoordArray);
-
- glVertexPointer(2, GL_FLOAT, 0, vertexArray);
- glTexCoordPointer(2, GL_FLOAT, 0, texCoordArray);
-
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- glDisableClientState(GL_VERTEX_ARRAY);
- if (tex->options & QGLContext::InvertedYBindOption)
- glPopMatrix();
-
- glDisable(GL_TEXTURE_2D);
-#ifndef QT_OPENGL_ES
- glPopAttrib();
-#endif
- }
-}
-
-void QOpenGLPaintEngine::drawImage(const QRectF &r, const QImage &image, const QRectF &sr,
- Qt::ImageConversionFlags)
-{
- Q_D(QOpenGLPaintEngine);
-
- const int sz = d->max_texture_size;
- if (image.width() > sz || image.height() > sz) {
- QRectF subsr;
- const QImage sub = qSubImage(image, sr, &subsr);
-
- if (sub.width() <= sz && sub.height() <= sz) {
- drawImage(r, sub, subsr, 0);
- } else {
- const QImage scaled = sub.scaled(sz, sz, Qt::KeepAspectRatio);
- const qreal sx = scaled.width() / qreal(sub.width());
- const qreal sy = scaled.height() / qreal(sub.height());
-
- drawImage(r, scaled, scaleRect(subsr, sx, sy), 0);
- }
- return;
- }
-
- if (d->composition_mode > QPainter::CompositionMode_Plus || (d->high_quality_antialiasing && !d->isFastRect(r)))
- d->drawImageAsPath(r, image, sr);
- else {
- GLenum target = qt_gl_preferredTextureTarget();
- d->flushDrawQueue();
- QGLTexture *tex =
- d->device->context()->d_func()->bindTexture(image, target, GL_RGBA,
- QGLContext::InternalBindOption);
- drawTextureRect(image.width(), image.height(), r, sr, target, tex);
- }
-}
-
-void QOpenGLPaintEngine::drawTextureRect(int tx_width, int tx_height, const QRectF &r,
- const QRectF &sr, GLenum target, QGLTexture *tex)
-{
- Q_D(QOpenGLPaintEngine);
-#ifndef QT_OPENGL_ES
- glPushAttrib(GL_CURRENT_BIT);
- glDisable(GL_TEXTURE_GEN_S);
-#endif
- glColor4f(d->opacity, d->opacity, d->opacity, d->opacity);
- glEnable(target);
- updateTextureFilter(target, GL_CLAMP_TO_EDGE, d->use_smooth_pixmap_transform);
-
- qreal x1, x2, y1, y2;
- if (target == GL_TEXTURE_2D) {
- x1 = sr.x() / tx_width;
- x2 = x1 + sr.width() / tx_width;
- if (tex->options & QGLContext::InvertedYBindOption) {
- y1 = 1 - (sr.bottom() / tx_height);
- y2 = 1 - (sr.y() / tx_height);
- } else {
- y1 = sr.bottom() / tx_height;
- y2 = sr.y() / tx_height;
- }
- } else {
- x1 = sr.x();
- x2 = sr.right();
- y1 = sr.bottom();
- y2 = sr.y();
- }
-
- GLfloat vertexArray[4*2];
- GLfloat texCoordArray[4*2];
-
- qt_add_rect_to_array(r, vertexArray);
- qt_add_texcoords_to_array(x1, y2, x2, y1, texCoordArray);
-
- glVertexPointer(2, GL_FLOAT, 0, vertexArray);
- glTexCoordPointer(2, GL_FLOAT, 0, texCoordArray);
-
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- glDisableClientState(GL_VERTEX_ARRAY);
-
- glDisable(target);
-#ifndef QT_OPENGL_ES
- glPopAttrib();
-#endif
-}
-
-#ifdef Q_WS_WIN
-HDC
-#else
-Qt::HANDLE
-#endif
-QOpenGLPaintEngine::handle() const
-{
- return 0;
-}
-
-static const int x_margin = 1;
-static const int y_margin = 0;
-
-struct QGLGlyphCoord {
- // stores the offset and size of a glyph texture
- qreal x;
- qreal y;
- qreal width;
- qreal height;
- qreal log_width;
- qreal log_height;
- QFixed x_offset;
- QFixed y_offset;
-};
-
-struct QGLFontTexture {
- int x_offset; // glyph offset within the
- int y_offset;
- GLuint texture;
- int width;
- int height;
-};
-
-typedef QHash<glyph_t, QGLGlyphCoord*> QGLGlyphHash;
-typedef QHash<QFontEngine*, QGLGlyphHash*> QGLFontGlyphHash;
-typedef QHash<quint64, QGLFontTexture*> QGLFontTexHash;
-typedef QHash<const QGLContext*, QGLFontGlyphHash*> QGLContextHash;
-
-static inline void qt_delete_glyph_hash(QGLGlyphHash *hash)
-{
- qDeleteAll(*hash);
- delete hash;
-}
-
-class QGLGlyphCache : public QObject
-{
- Q_OBJECT
-public:
- QGLGlyphCache() : QObject(0) { current_cache = 0; }
- ~QGLGlyphCache();
- QGLGlyphCoord *lookup(QFontEngine *, glyph_t);
- void cacheGlyphs(QGLContext *, QFontEngine *, glyph_t *glyphs, int numGlyphs);
- void cleanCache();
- void allocTexture(int width, int height, GLuint texture);
-
-public slots:
- void cleanupContext(const QGLContext *);
- void fontEngineDestroyed(QObject *);
- void widgetDestroyed(QObject *);
-
-protected:
- QGLGlyphHash *current_cache;
- QGLFontTexHash qt_font_textures;
- QGLContextHash qt_context_cache;
-};
-
-QGLGlyphCache::~QGLGlyphCache()
-{
-// qDebug() << "cleaning out the QGLGlyphCache";
- cleanCache();
-}
-
-void QGLGlyphCache::fontEngineDestroyed(QObject *o)
-{
-// qDebug() << "fontEngineDestroyed()";
- QFontEngine *fe = static_cast<QFontEngine *>(o); // safe, since only the type is used
- QList<const QGLContext *> keys = qt_context_cache.keys();
- const QGLContext *ctx = 0;
-
- for (int i=0; i < keys.size(); ++i) {
- QGLFontGlyphHash *font_cache = qt_context_cache.value(keys.at(i));
- if (font_cache->find(fe) != font_cache->end()) {
- ctx = keys.at(i);
- QGLGlyphHash *cache = font_cache->take(fe);
- qt_delete_glyph_hash(cache);
- break;
- }
- }
-
- quint64 font_key = (reinterpret_cast<quint64>(ctx) << 32) | reinterpret_cast<quint64>(fe);
- QGLFontTexture *tex = qt_font_textures.take(font_key);
- if (tex) {
-#ifdef Q_WS_MAC
- if (
-# ifndef QT_MAC_USE_COCOA
- aglGetCurrentContext() != 0
-# else
- qt_current_nsopengl_context() != 0
-# endif
- )
-#endif
- glDeleteTextures(1, &tex->texture);
- delete tex;
- }
-}
-
-void QGLGlyphCache::widgetDestroyed(QObject *)
-{
-// qDebug() << "widget destroyed";
- cleanCache(); // ###
-}
-
-void QGLGlyphCache::cleanupContext(const QGLContext *ctx)
-{
-// qDebug() << "==> cleaning for: " << hex << ctx;
- QGLFontGlyphHash *font_cache = qt_context_cache.take(ctx);
-
- if (font_cache) {
- QList<QFontEngine *> keys = font_cache->keys();
- for (int i=0; i < keys.size(); ++i) {
- QFontEngine *fe = keys.at(i);
- qt_delete_glyph_hash(font_cache->take(fe));
- quint64 font_key = (reinterpret_cast<quint64>(ctx) << 32) | reinterpret_cast<quint64>(fe);
- QGLFontTexture *font_tex = qt_font_textures.take(font_key);
- if (font_tex) {
-#ifdef Q_WS_MAC
- if (
-# ifndef QT_MAC_USE_COCOA
- aglGetCurrentContext() == 0
-# else
- qt_current_nsopengl_context() != 0
-# endif
- )
-#endif
- glDeleteTextures(1, &font_tex->texture);
- delete font_tex;
- }
- }
- delete font_cache;
- }
-// qDebug() << "<=== done cleaning, num tex:" << qt_font_textures.size() << "num ctx:" << qt_context_cache.size();
-}
-
-void QGLGlyphCache::cleanCache()
-{
- QGLFontTexHash::const_iterator it = qt_font_textures.constBegin();
- if (QGLContext::currentContext()) {
- while (it != qt_font_textures.constEnd()) {
-#if defined(Q_WS_MAC) && defined(QT_MAC_USE_COCOA)
- if (qt_current_nsopengl_context() == 0)
- break;
-#endif
- glDeleteTextures(1, &it.value()->texture);
- ++it;
- }
- }
- qDeleteAll(qt_font_textures);
- qt_font_textures.clear();
-
- QList<const QGLContext *> keys = qt_context_cache.keys();
- for (int i=0; i < keys.size(); ++i) {
- QGLFontGlyphHash *font_cache = qt_context_cache.value(keys.at(i));
- QGLFontGlyphHash::Iterator it = font_cache->begin();
- for (; it != font_cache->end(); ++it)
- qt_delete_glyph_hash(it.value());
- font_cache->clear();
- }
- qDeleteAll(qt_context_cache);
- qt_context_cache.clear();
-}
-
-void QGLGlyphCache::allocTexture(int width, int height, GLuint texture)
-{
- uchar *tex_data = (uchar *) malloc(width*height*2);
- memset(tex_data, 0, width*height*2);
- glBindTexture(GL_TEXTURE_2D, texture);
-#ifndef QT_OPENGL_ES
- glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE8_ALPHA8,
- width, height, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, tex_data);
-#else
- glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA,
- width, height, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, tex_data);
-#endif
- free(tex_data);
-}
-
-#if 0
-// useful for debugging the glyph cache
-static QImage getCurrentTexture(const QColor &color, QGLFontTexture *font_tex)
-{
- ushort *old_tex_data = (ushort *) malloc(font_tex->width*font_tex->height*2);
- glGetTexImage(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, old_tex_data);
- QImage im(font_tex->width, font_tex->height, QImage::Format_ARGB32);
- for (int y=0; y<font_tex->height; ++y) {
- for (int x=0; x<font_tex->width; ++x) {
- im.setPixel(x, y, ((*(old_tex_data+x+y*font_tex->width)) << 24) | (0x00ffffff & color.rgb()));
- }
- }
- delete old_tex_data;
- return im;
-}
-#endif
-
-void QGLGlyphCache::cacheGlyphs(QGLContext *context, QFontEngine *fontEngine,
- glyph_t *glyphs, int numGlyphs)
-{
- QGLContextHash::const_iterator dev_it = qt_context_cache.constFind(context);
- QGLFontGlyphHash *font_cache = 0;
- const QGLContext *context_key = 0;
-
- if (dev_it == qt_context_cache.constEnd()) {
- // check for shared contexts
- QList<const QGLContext *> contexts = qt_context_cache.keys();
- for (int i=0; i<contexts.size(); ++i) {
- const QGLContext *ctx = contexts.at(i);
- if (ctx != context && QGLContext::areSharing(context, ctx)) {
- context_key = ctx;
- dev_it = qt_context_cache.constFind(context_key);
- break;
- }
- }
- }
-
- if (dev_it == qt_context_cache.constEnd()) {
- // no shared contexts either - create a new entry
- font_cache = new QGLFontGlyphHash;
-// qDebug() << "new context" << context << font_cache;
- qt_context_cache.insert(context, font_cache);
- if (context->isValid()) {
- if (context->device() && context->device()->devType() == QInternal::Widget) {
- QWidget *widget = static_cast<QWidget *>(context->device());
- connect(widget, SIGNAL(destroyed(QObject*)), SLOT(widgetDestroyed(QObject*)));
- }
- connect(QGLSignalProxy::instance(),
- SIGNAL(aboutToDestroyContext(const QGLContext*)),
- SLOT(cleanupContext(const QGLContext*)));
- }
- } else {
- font_cache = dev_it.value();
- }
- Q_ASSERT(font_cache != 0);
-
- QGLFontGlyphHash::const_iterator cache_it = font_cache->constFind(fontEngine);
- QGLGlyphHash *cache = 0;
- if (cache_it == font_cache->constEnd()) {
- cache = new QGLGlyphHash;
- font_cache->insert(fontEngine, cache);
- connect(fontEngine, SIGNAL(destroyed(QObject*)), SLOT(fontEngineDestroyed(QObject*)));
- } else {
- cache = cache_it.value();
- }
- current_cache = cache;
-
- quint64 font_key = (reinterpret_cast<quint64>(context_key ? context_key : context) << 32)
- | reinterpret_cast<quint64>(fontEngine);
- QGLFontTexHash::const_iterator it = qt_font_textures.constFind(font_key);
- QGLFontTexture *font_tex;
- if (it == qt_font_textures.constEnd()) {
- GLuint font_texture;
- glGenTextures(1, &font_texture);
- GLint tex_height = qt_next_power_of_two(qRound(fontEngine->ascent().toReal() + fontEngine->descent().toReal())+2);
- GLint tex_width = qt_next_power_of_two(tex_height*30); // ###
- GLint max_tex_size;
- glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_tex_size);
- Q_ASSERT(max_tex_size > 0);
- if (tex_width > max_tex_size)
- tex_width = max_tex_size;
- allocTexture(tex_width, tex_height, font_texture);
- font_tex = new QGLFontTexture;
- font_tex->texture = font_texture;
- font_tex->x_offset = x_margin;
- font_tex->y_offset = y_margin;
- font_tex->width = tex_width;
- font_tex->height = tex_height;
-// qDebug() << "new font tex - width:" << tex_width << "height:"<< tex_height
-// << hex << "tex id:" << font_tex->texture << "key:" << font_key << "num cached:" << qt_font_textures.size();
- qt_font_textures.insert(font_key, font_tex);
- } else {
- font_tex = it.value();
- glBindTexture(GL_TEXTURE_2D, font_tex->texture);
- }
-
- for (int i=0; i< numGlyphs; ++i) {
- QGLGlyphHash::const_iterator it = cache->constFind(glyphs[i]);
- if (it == cache->constEnd()) {
- // render new glyph and put it in the cache
- glyph_metrics_t metrics = fontEngine->boundingBox(glyphs[i]);
- int glyph_width = qRound(metrics.width.toReal())+2;
- int glyph_height = qRound(fontEngine->ascent().toReal() + fontEngine->descent().toReal())+2;
-
- if (font_tex->x_offset + glyph_width + x_margin > font_tex->width) {
- int strip_height = qt_next_power_of_two(qRound(fontEngine->ascent().toReal() + fontEngine->descent().toReal())+2);
- font_tex->x_offset = x_margin;
- font_tex->y_offset += strip_height;
- if (font_tex->y_offset >= font_tex->height) {
- // get hold of the old font texture
- uchar *old_tex_data = (uchar *) malloc(font_tex->width*font_tex->height*2);
- int old_tex_height = font_tex->height;
-#ifndef QT_OPENGL_ES
- glGetTexImage(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, old_tex_data);
-#endif
-
- // realloc a larger texture
- glDeleteTextures(1, &font_tex->texture);
- glGenTextures(1, &font_tex->texture);
- font_tex->height = qt_next_power_of_two(font_tex->height + strip_height);
- allocTexture(font_tex->width, font_tex->height, font_tex->texture);
-
- // write back the old texture data
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, font_tex->width, old_tex_height,
- GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, old_tex_data);
- free(old_tex_data);
-
- // update the texture coords and the y offset for the existing glyphs in
- // the cache, because of the texture size change
- QGLGlyphHash::iterator it = cache->begin();
- while (it != cache->end()) {
- it.value()->height = (it.value()->height * old_tex_height) / font_tex->height;
- it.value()->y = (it.value()->y * old_tex_height) / font_tex->height;
- ++it;
- }
- }
- }
-
- QImage glyph_im(fontEngine->alphaMapForGlyph(glyphs[i]));
- glyph_width = glyph_im.width();
- Q_ASSERT(glyph_width >= 0);
- // pad the glyph width to an even number
- if (glyph_width%2 != 0)
- ++glyph_width;
-
- QGLGlyphCoord *qgl_glyph = new QGLGlyphCoord;
- qgl_glyph->x = qreal(font_tex->x_offset) / font_tex->width;
- qgl_glyph->y = qreal(font_tex->y_offset) / font_tex->height;
- qgl_glyph->width = qreal(glyph_width) / font_tex->width;
- qgl_glyph->height = qreal(glyph_height) / font_tex->height;
- qgl_glyph->log_width = qreal(glyph_width);
- qgl_glyph->log_height = qgl_glyph->height * font_tex->height;
-#ifdef Q_WS_MAC
- qgl_glyph->x_offset = -metrics.x + 1;
- qgl_glyph->y_offset = metrics.y - 2;
-#else
- qgl_glyph->x_offset = -metrics.x;
- qgl_glyph->y_offset = metrics.y;
-#endif
-
- if (!glyph_im.isNull()) {
- int idx = 0;
- uchar *tex_data = (uchar *) malloc(glyph_width*glyph_im.height()*2);
- memset(tex_data, 0, glyph_width*glyph_im.height()*2);
-
- bool is8BitGray = false;
-#ifdef Q_WS_QPA
- if (glyph_im.format() == QImage::Format_Indexed8) {
- is8BitGray = true;
- }
-#endif
- glyph_im = glyph_im.convertToFormat(QImage::Format_Indexed8);
- for (int y=0; y<glyph_im.height(); ++y) {
- uchar *s = (uchar *) glyph_im.scanLine(y);
- for (int x=0; x<glyph_im.width(); ++x) {
- uchar alpha = is8BitGray ? *s : qAlpha(glyph_im.color(*s));
- tex_data[idx] = alpha;
- tex_data[idx+1] = alpha;
- ++s;
- idx += 2;
- }
- if (glyph_im.width()%2 != 0)
- idx += 2;
- }
- glTexSubImage2D(GL_TEXTURE_2D, 0, font_tex->x_offset, font_tex->y_offset,
- glyph_width, glyph_im.height(),
- GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, tex_data);
- free(tex_data);
- }
- if (font_tex->x_offset + glyph_width + x_margin > font_tex->width) {
- font_tex->x_offset = x_margin;
- font_tex->y_offset += glyph_height + y_margin;
- } else {
- font_tex->x_offset += glyph_width + x_margin;
- }
-
- cache->insert(glyphs[i], qgl_glyph);
- }
- }
-}
-
-QGLGlyphCoord *QGLGlyphCache::lookup(QFontEngine *, glyph_t g)
-{
- Q_ASSERT(current_cache != 0);
- // ### careful here
- QGLGlyphHash::const_iterator it = current_cache->constFind(g);
- if (it == current_cache->constEnd())
- return 0;
- else
- return it.value();
-}
-
-Q_GLOBAL_STATIC(QGLGlyphCache, qt_glyph_cache)
-
-//
-// assumption: the context that this is called for has to be the
-// current context
-//
-void qgl_cleanup_glyph_cache(QGLContext *ctx)
-{
- qt_glyph_cache()->cleanupContext(ctx);
-}
-
-void QOpenGLPaintEngine::drawStaticTextItem(QStaticTextItem *textItem)
-{
- Q_D(QOpenGLPaintEngine);
-
- d->flushDrawQueue();
-
- // make sure the glyphs we want to draw are in the cache
- qt_glyph_cache()->cacheGlyphs(d->device->context(), textItem->fontEngine(), textItem->glyphs,
- textItem->numGlyphs);
-
- d->setGradientOps(Qt::SolidPattern, QRectF()); // turns off gradient ops
- qt_glColor4ubv(d->pen_color);
- glEnable(GL_TEXTURE_2D);
-
-#ifdef Q_WS_QWS
- // XXX: it is necessary to disable alpha writes on GLES/embedded because we don't want
- // text rendering to update the alpha in the window surface.
- // XXX: This may not be needed as this behavior does seem to be caused by driver bug
- glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
-#endif
-
- // do the actual drawing
- GLfloat vertexArray[4*2];
- GLfloat texCoordArray[4*2];
-
- glVertexPointer(2, GL_FLOAT, 0, vertexArray);
- glTexCoordPointer(2, GL_FLOAT, 0, texCoordArray);
-
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- bool antialias = !(textItem->fontEngine()->fontDef.styleStrategy & QFont::NoAntialias)
- && (d->matrix.type() > QTransform::TxTranslate);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, antialias ? GL_LINEAR : GL_NEAREST);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, antialias ? GL_LINEAR : GL_NEAREST);
-
- for (int i=0; i< textItem->numGlyphs; ++i) {
- QGLGlyphCoord *g = qt_glyph_cache()->lookup(textItem->fontEngine(), textItem->glyphs[i]);
-
- // we don't cache glyphs with no width/height
- if (!g)
- continue;
-
- qreal x1, x2, y1, y2;
- x1 = g->x;
- y1 = g->y;
- x2 = x1 + g->width;
- y2 = y1 + g->height;
-
- QPointF logical_pos((textItem->glyphPositions[i].x - g->x_offset).toReal(),
- (textItem->glyphPositions[i].y + g->y_offset).toReal());
-
- qt_add_rect_to_array(QRectF(logical_pos, QSizeF(g->log_width, g->log_height)), vertexArray);
- qt_add_texcoords_to_array(x1, y1, x2, y2, texCoordArray);
-
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- }
-
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- glDisableClientState(GL_VERTEX_ARRAY);
-
- glDisable(GL_TEXTURE_2D);
-
-#ifdef Q_WS_QWS
- // XXX: This may not be needed as this behavior does seem to be caused by driver bug
- glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
-#endif
-
-}
-
-void QOpenGLPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem)
-{
- Q_D(QOpenGLPaintEngine);
-
- const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem);
-
- // fall back to drawing a polygon if the scale factor is large, or
- // we use a gradient pen
- if ((d->matrix.det() > 1) || (d->pen_brush_style >= Qt::LinearGradientPattern
- && d->pen_brush_style <= Qt::ConicalGradientPattern)) {
- QPaintEngine::drawTextItem(p, textItem);
- return;
- }
-
- // add the glyphs used to the glyph texture cache
- QVarLengthArray<QFixedPoint> positions;
- QVarLengthArray<glyph_t> glyphs;
- QTransform matrix = QTransform::fromTranslate(qRound(p.x()), qRound(p.y()));
- ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions);
-
- {
- QStaticTextItem staticTextItem;
- staticTextItem.chars = const_cast<QChar *>(ti.chars);
- staticTextItem.setFontEngine(ti.fontEngine);
- staticTextItem.glyphs = glyphs.data();
- staticTextItem.numChars = ti.num_chars;
- staticTextItem.numGlyphs = glyphs.size();
- staticTextItem.glyphPositions = positions.data();
- drawStaticTextItem(&staticTextItem);
- }
-
-}
-
-
-void QOpenGLPaintEngine::drawEllipse(const QRectF &rect)
-{
-#ifndef Q_WS_QWS
- Q_D(QOpenGLPaintEngine);
-
- if (d->use_emulation) {
- QPaintEngineEx::drawEllipse(rect);
- return;
- }
-
- if (d->high_quality_antialiasing) {
- if (d->has_brush) {
- d->disableClipping();
-
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- glLoadIdentity();
-
- GLuint program = qt_gl_program_cache()->getProgram(d->device->context(),
- FRAGMENT_PROGRAM_MASK_ELLIPSE_AA, 0, true);
- QGLEllipseMaskGenerator maskGenerator(rect,
- d->matrix,
- d->offscreen,
- program,
- mask_variable_locations[FRAGMENT_PROGRAM_MASK_ELLIPSE_AA]);
-
- d->addItem(qt_mask_texture_cache()->getMask(maskGenerator, d));
-
- d->enableClipping();
-
- glMatrixMode(GL_MODELVIEW);
- glPopMatrix();
- }
-
- if (d->has_pen) {
- QPainterPath path;
- path.addEllipse(rect);
-
- d->strokePath(path, false);
- }
- } else {
- DEBUG_ONCE_STR("QOpenGLPaintEngine::drawEllipse(): falling back to drawPath()");
-
- QPainterPath path;
- path.addEllipse(rect);
- drawPath(path);
- }
-#else
- QPaintEngineEx::drawEllipse(rect);
-#endif
-}
-
-
-void QOpenGLPaintEnginePrivate::updateFragmentProgramData(int locations[])
-{
-#ifdef Q_WS_QWS
- Q_UNUSED(locations);
-#else
- QGL_FUNC_CONTEXT;
-
- QSize sz = offscreen.offscreenSize();
-
- float inv_mask_size_data[4] = { 1.0f / sz.width(), 1.0f / sz.height(), 0.0f, 0.0f };
-
- sz = drawable_texture_size;
-
- float inv_dst_size_data[4] = { 1.0f / sz.width(), 1.0f / sz.height(), 0.0f, 0.0f };
-
- // default inv size 0.125f == 1.0f / 8.0f for pattern brushes
- float inv_brush_texture_size_data[4] = { 0.125f, 0.125f };
-
- // texture patterns have their own size
- if (current_style == Qt::TexturePattern) {
- QSize sz = cbrush.texture().size();
-
- inv_brush_texture_size_data[0] = 1.0f / sz.width();
- inv_brush_texture_size_data[1] = 1.0f / sz.height();
- }
-
- for (unsigned int i = 0; i < num_fragment_variables; ++i) {
- int location = locations[i];
-
- if (location < 0)
- continue;
-
- switch (i) {
- case VAR_ANGLE:
- glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, location, angle_data);
- break;
- case VAR_LINEAR:
- glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, location, linear_data);
- break;
- case VAR_FMP:
- glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, location, fmp_data);
- break;
- case VAR_FMP2_M_RADIUS2:
- glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, location, fmp2_m_radius2_data);
- break;
- case VAR_INV_MASK_SIZE:
- glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, location, inv_mask_size_data);
- break;
- case VAR_INV_DST_SIZE:
- glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, location, inv_dst_size_data);
- break;
- case VAR_INV_MATRIX_M0:
- glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, location, inv_matrix_data[0]);
- break;
- case VAR_INV_MATRIX_M1:
- glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, location, inv_matrix_data[1]);
- break;
- case VAR_INV_MATRIX_M2:
- glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, location, inv_matrix_data[2]);
- break;
- case VAR_PORTERDUFF_AB:
- glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, location, porterduff_ab_data);
- break;
- case VAR_PORTERDUFF_XYZ:
- glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, location, porterduff_xyz_data);
- break;
- case VAR_INV_BRUSH_TEXTURE_SIZE:
- glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, location, inv_brush_texture_size_data);
- break;
- case VAR_MASK_OFFSET:
- glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, location, mask_offset_data);
- break;
- case VAR_MASK_CHANNEL:
- glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, location, mask_channel_data);
- break;
- case VAR_DST_TEXTURE:
- case VAR_MASK_TEXTURE:
- case VAR_PALETTE:
- case VAR_BRUSH_TEXTURE:
- // texture variables, not handled here
- break;
- default:
- qDebug() << "QOpenGLPaintEnginePrivate: Unhandled fragment variable:" << i;
- }
- }
-#endif
-}
-
-
-void QOpenGLPaintEnginePrivate::copyDrawable(const QRectF &rect)
-{
-#ifdef Q_WS_QWS
- Q_UNUSED(rect);
-#else
- ensureDrawableTexture();
-
- DEBUG_ONCE qDebug() << "Refreshing drawable_texture for rectangle" << rect;
- QRectF screen_rect = rect.adjusted(-1, -1, 1, 1);
-
- int left = qMax(0, static_cast<int>(screen_rect.left()));
- int width = qMin(device->size().width() - left, static_cast<int>(screen_rect.width()) + 1);
-
- int bottom = qMax(0, static_cast<int>(device->size().height() - screen_rect.bottom()));
- int height = qMin(device->size().height() - bottom, static_cast<int>(screen_rect.height()) + 1);
-
- glBindTexture(GL_TEXTURE_2D, drawable_texture);
- glCopyTexSubImage2D(GL_TEXTURE_2D, 0, left, bottom, left, bottom, width, height);
-#endif
-}
-
-
-void QOpenGLPaintEnginePrivate::composite(const QRectF &rect, const QPoint &maskOffset)
-{
-#ifdef Q_WS_QWS
- Q_UNUSED(rect);
- Q_UNUSED(maskOffset);
-#else
- GLfloat vertexArray[8];
- qt_add_rect_to_array(rect, vertexArray);
-
- composite(GL_TRIANGLE_FAN, vertexArray, 4, maskOffset);
-#endif
-}
-
-
-void QOpenGLPaintEnginePrivate::composite(GLuint primitive, const GLfloat *vertexArray, int vertexCount, const QPoint &maskOffset)
-{
-#ifdef QT_OPENGL_ES
- Q_UNUSED(primitive);
- Q_UNUSED(vertexArray);
- Q_UNUSED(vertexCount);
- Q_UNUSED(maskOffset);
-#else
- 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;
-
- if (has_fast_composition_mode)
- q->updateCompositionMode(composition_mode);
- else {
- qreal minX = 1e9, minY = 1e9, maxX = -1e9, maxY = -1e9;
-
- for (int i = 0; i < vertexCount; ++i) {
- qreal x = vertexArray[2 * i];
- qreal y = vertexArray[2 * i + 1];
-
- qreal tx, ty;
- matrix.map(x, y, &tx, &ty);
-
- minX = qMin(minX, tx);
- minY = qMin(minY, ty);
- maxX = qMax(maxX, tx);
- maxY = qMax(maxY, ty);
- }
-
- QRectF r(minX, minY, maxX - minX, maxY - minY);
- copyDrawable(r);
-
- glBlendFunc(GL_ONE, GL_ZERO);
- }
-
- int *locations = painter_variable_locations[fragment_brush][fragment_composition_mode];
-
- int texture_locations[] = { locations[VAR_DST_TEXTURE],
- locations[VAR_MASK_TEXTURE],
- locations[VAR_PALETTE] };
-
- int brush_texture_location = locations[VAR_BRUSH_TEXTURE];
-
- GLuint texture_targets[] = { GL_TEXTURE_2D,
- GL_TEXTURE_2D,
- GL_TEXTURE_1D };
-
- GLuint textures[] = { drawable_texture,
- offscreen.offscreenTexture(),
- grad_palette };
-
- const int num_textures = sizeof(textures) / sizeof(*textures);
-
- Q_ASSERT(num_textures == sizeof(texture_locations) / sizeof(*texture_locations));
- Q_ASSERT(num_textures == sizeof(texture_targets) / sizeof(*texture_targets));
-
- for (int i = 0; i < num_textures; ++i)
- if (texture_locations[i] >= 0) {
- glActiveTexture(GL_TEXTURE0 + texture_locations[i]);
- glBindTexture(texture_targets[i], textures[i]);
- }
-
- if (brush_texture_location >= 0) {
- glActiveTexture(GL_TEXTURE0 + brush_texture_location);
-
- if (current_style == Qt::TexturePattern)
- device->context()->d_func()->bindTexture(cbrush.textureImage(), GL_TEXTURE_2D, GL_RGBA,
- QGLContext::InternalBindOption);
- else
- device->context()->d_func()->bindTexture(qt_imageForBrush(current_style, false),
- GL_TEXTURE_2D, GL_RGBA,
- QGLContext::InternalBindOption);
-
- updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, use_smooth_pixmap_transform);
- }
-
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(2, GL_FLOAT, 0, vertexArray);
- glEnable(GL_FRAGMENT_PROGRAM_ARB);
- GLuint program = qt_gl_program_cache()->getProgram(device->context(),
- fragment_brush,
- fragment_composition_mode, false);
- glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, program);
-
- mask_offset_data[0] = maskOffset.x();
- mask_offset_data[1] = -maskOffset.y();
-
- updateFragmentProgramData(locations);
-
- glDrawArrays(primitive, 0, vertexCount);
-
- glDisable(GL_FRAGMENT_PROGRAM_ARB);
- glDisableClientState(GL_VERTEX_ARRAY);
-
- for (int i = 0; i < num_textures; ++i)
- if (texture_locations[i] >= 0) {
- glActiveTexture(GL_TEXTURE0 + texture_locations[i]);
- glBindTexture(texture_targets[i], 0);
- }
-
- if (brush_texture_location >= 0) {
- glActiveTexture(GL_TEXTURE0 + brush_texture_location);
- glBindTexture(GL_TEXTURE_2D, 0);
- }
-
- glActiveTexture(GL_TEXTURE0);
-
- if (!has_fast_composition_mode)
- q->updateCompositionMode(composition_mode);
-#endif
-}
-
-void QOpenGLPaintEnginePrivate::cacheItemErased(int channel, const QRect &rect)
-{
- bool isInDrawQueue = false;
-
- foreach (const QDrawQueueItem &item, drawQueue) {
- if (item.location.channel == channel && item.location.rect == rect) {
- isInDrawQueue = true;
- break;
- }
- }
-
- if (isInDrawQueue)
- flushDrawQueue();
-}
-
-void QOpenGLPaintEnginePrivate::addItem(const QGLMaskTextureCache::CacheLocation &location)
-{
- drawQueue << QDrawQueueItem(opacity, cbrush, brush_origin, composition_mode, matrix, location);
-}
-
-void QOpenGLPaintEnginePrivate::drawItem(const QDrawQueueItem &item)
-{
- Q_Q(QOpenGLPaintEngine);
-
- opacity = item.opacity;
- brush_origin = item.brush_origin;
- q->updateCompositionMode(item.composition_mode);
- matrix = item.matrix;
- cbrush = item.brush;
- brush_style = item.brush.style();
-
- mask_channel_data[0] = item.location.channel == 0;
- mask_channel_data[1] = item.location.channel == 1;
- mask_channel_data[2] = item.location.channel == 2;
- mask_channel_data[3] = item.location.channel == 3;
-
- setGradientOps(item.brush, item.location.screen_rect);
-
- composite(item.location.screen_rect, item.location.rect.topLeft() - item.location.screen_rect.topLeft()
- - QPoint(0, offscreen.offscreenSize().height() - device->size().height()));
-}
-
-void QOpenGLPaintEnginePrivate::flushDrawQueue()
-{
-#ifndef QT_OPENGL_ES
- Q_Q(QOpenGLPaintEngine);
-
- offscreen.release();
-
- if (!drawQueue.isEmpty()) {
- DEBUG_ONCE qDebug() << "QOpenGLPaintEngine::flushDrawQueue():" << drawQueue.size() << "items";
-
- glPushMatrix();
- glLoadIdentity();
- qreal old_opacity = opacity;
- QPointF old_brush_origin = brush_origin;
- QPainter::CompositionMode old_composition_mode = composition_mode;
- QTransform old_matrix = matrix;
- QBrush old_brush = cbrush;
-
- bool hqaa_old = high_quality_antialiasing;
-
- high_quality_antialiasing = true;
-
- foreach (const QDrawQueueItem &item, drawQueue)
- drawItem(item);
-
- opacity = old_opacity;
- brush_origin = old_brush_origin;
- q->updateCompositionMode(old_composition_mode);
- matrix = old_matrix;
- cbrush = old_brush;
- brush_style = old_brush.style();
-
- high_quality_antialiasing = hqaa_old;
-
- setGLBrush(old_brush.color());
- qt_glColor4ubv(brush_color);
-
- drawQueue.clear();
-
- glPopMatrix();
- }
-#endif
-}
-
-void QOpenGLPaintEngine::clipEnabledChanged()
-{
- Q_D(QOpenGLPaintEngine);
-
- d->updateDepthClip();
-}
-
-void QOpenGLPaintEngine::penChanged()
-{
- updatePen(state()->pen);
-}
-
-void QOpenGLPaintEngine::brushChanged()
-{
- updateBrush(state()->brush, state()->brushOrigin);
-}
-
-void QOpenGLPaintEngine::brushOriginChanged()
-{
- updateBrush(state()->brush, state()->brushOrigin);
-}
-
-void QOpenGLPaintEngine::opacityChanged()
-{
- Q_D(QOpenGLPaintEngine);
- QPainterState *s = state();
- d->opacity = s->opacity;
- updateBrush(s->brush, s->brushOrigin);
- updatePen(s->pen);
-}
-
-void QOpenGLPaintEngine::compositionModeChanged()
-{
- updateCompositionMode(state()->composition_mode);
-}
-
-void QOpenGLPaintEngine::renderHintsChanged()
-{
- updateRenderHints(state()->renderHints);
-}
-
-void QOpenGLPaintEngine::transformChanged()
-{
- updateMatrix(state()->matrix);
-}
-
-extern QPainterPath qt_painterPathFromVectorPath(const QVectorPath &path);
-
-void QOpenGLPaintEngine::fill(const QVectorPath &path, const QBrush &brush)
-{
- Q_D(QOpenGLPaintEngine);
-
- if (brush.style() == Qt::NoBrush)
- return;
-
- if ((!d->use_fragment_programs && needsEmulation(brush.style())) || qt_isExtendedRadialGradient(brush)) {
- QPainter *p = painter();
- QBrush oldBrush = p->brush();
- p->setBrush(brush);
- qt_draw_helper(p->d_ptr.data(), qt_painterPathFromVectorPath(path), QPainterPrivate::FillDraw);
- p->setBrush(oldBrush);
- return;
- }
-
- QBrush old_brush = state()->brush;
- updateBrush(brush, state()->brushOrigin);
-
- const qreal *points = path.points();
- const QPainterPath::ElementType *types = path.elements();
- if (!types && path.shape() == QVectorPath::RectangleHint) {
- QRectF r(points[0], points[1], points[4]-points[0], points[5]-points[1]);
- QPen old_pen = state()->pen;
- updatePen(Qt::NoPen);
- drawRects(&r, 1);
- updatePen(old_pen);
- } else {
- d->fillPath(qt_painterPathFromVectorPath(path));
- }
-
- updateBrush(old_brush, state()->brushOrigin);
-}
-
-template <typename T> static inline bool isRect(const T *pts, int elementCount) {
- return (elementCount == 5 // 5-point polygon, check for closed rect
- && pts[0] == pts[8] && pts[1] == pts[9] // last point == first point
- && pts[0] == pts[6] && pts[2] == pts[4] // x values equal
- && pts[1] == pts[3] && pts[5] == pts[7] // y values equal...
- ) ||
- (elementCount == 4 // 4-point polygon, check for unclosed rect
- && pts[0] == pts[6] && pts[2] == pts[4] // x values equal
- && pts[1] == pts[3] && pts[5] == pts[7] // y values equal...
- );
-}
-
-void QOpenGLPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op)
-{
- const qreal *points = path.points();
- const QPainterPath::ElementType *types = path.elements();
- if (!types && path.shape() == QVectorPath::RectangleHint) {
- QRectF r(points[0], points[1], points[4]-points[0], points[5]-points[1]);
- updateClipRegion(QRegion(r.toRect()), op);
- return;
- }
-
- QPainterPath p;
- if (types) {
- int id = 0;
- for (int i=0; i<path.elementCount(); ++i) {
- switch(types[i]) {
- case QPainterPath::MoveToElement:
- p.moveTo(QPointF(points[id], points[id+1]));
- id+=2;
- break;
- case QPainterPath::LineToElement:
- p.lineTo(QPointF(points[id], points[id+1]));
- id+=2;
- break;
- case QPainterPath::CurveToElement: {
- QPointF p1(points[id], points[id+1]);
- QPointF p2(points[id+2], points[id+3]);
- QPointF p3(points[id+4], points[id+5]);
- p.cubicTo(p1, p2, p3);
- id+=6;
- break;
- }
- case QPainterPath::CurveToDataElement:
- ;
- break;
- }
- }
- } else if (!path.isEmpty()) {
- p.moveTo(QPointF(points[0], points[1]));
- int id = 2;
- for (int i=1; i<path.elementCount(); ++i) {
- p.lineTo(QPointF(points[id], points[id+1]));
- id+=2;
- }
- }
- if (path.hints() & QVectorPath::WindingFill)
- p.setFillRule(Qt::WindingFill);
-
- updateClipRegion(QRegion(p.toFillPolygon().toPolygon(), p.fillRule()), op);
- return;
-}
-
-void QOpenGLPaintEngine::setState(QPainterState *s)
-{
- Q_D(QOpenGLPaintEngine);
- QOpenGLPaintEngineState *new_state = static_cast<QOpenGLPaintEngineState *>(s);
- QOpenGLPaintEngineState *old_state = state();
-
- QPaintEngineEx::setState(s);
-
- // are we in a save() ?
- if (s == d->last_created_state) {
- d->last_created_state = 0;
- return;
- }
-
- if (isActive()) {
- if (old_state->depthClipId != new_state->depthClipId)
- d->updateDepthClip();
- penChanged();
- brushChanged();
- opacityChanged();
- compositionModeChanged();
- renderHintsChanged();
- transformChanged();
- }
-}
-
-QPainterState *QOpenGLPaintEngine::createState(QPainterState *orig) const
-{
- const Q_D(QOpenGLPaintEngine);
-
- QOpenGLPaintEngineState *s;
- if (!orig)
- s = new QOpenGLPaintEngineState();
- else
- s = new QOpenGLPaintEngineState(*static_cast<QOpenGLPaintEngineState *>(orig));
-
- d->last_created_state = s;
- return s;
-}
-
-//
-// QOpenGLPaintEngineState
-//
-
-QOpenGLPaintEngineState::QOpenGLPaintEngineState(QOpenGLPaintEngineState &other)
- : QPainterState(other)
-{
- clipRegion = other.clipRegion;
- hasClipping = other.hasClipping;
- fastClip = other.fastClip;
- depthClipId = other.depthClipId;
-}
-
-QOpenGLPaintEngineState::QOpenGLPaintEngineState()
-{
- hasClipping = false;
- depthClipId = 0;
-}
-
-QOpenGLPaintEngineState::~QOpenGLPaintEngineState()
-{
-}
-
-void QOpenGLPaintEnginePrivate::ensureDrawableTexture()
-{
- if (!dirty_drawable_texture)
- return;
-
- dirty_drawable_texture = false;
-
-#ifndef QT_OPENGL_ES
- glGenTextures(1, &drawable_texture);
- glBindTexture(GL_TEXTURE_2D, drawable_texture);
-
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8,
- drawable_texture_size.width(),
- drawable_texture_size.height(), 0,
- GL_RGBA, GL_UNSIGNED_BYTE, NULL);
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-#endif
-}
-
-QT_END_NAMESPACE
-
-#include "qpaintengine_opengl.moc"
diff --git a/src/opengl/qpaintengine_opengl_p.h b/src/opengl/qpaintengine_opengl_p.h
deleted file mode 100644
index 8d0ea83a47..0000000000
--- a/src/opengl/qpaintengine_opengl_p.h
+++ /dev/null
@@ -1,158 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPAINTENGINE_OPENGL_P_H
-#define QPAINTENGINE_OPENGL_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of the QLibrary class. This header file may change from
-// version to version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <private/qpaintengineex_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QOpenGLPaintEnginePrivate;
-class QGLTexture;
-
-class QOpenGLPaintEngineState : public QPainterState
-{
-public:
- QOpenGLPaintEngineState(QOpenGLPaintEngineState &other);
- QOpenGLPaintEngineState();
- ~QOpenGLPaintEngineState();
-
- QRegion clipRegion;
- bool hasClipping;
- QRect fastClip;
- uint depthClipId;
-};
-
-class QOpenGLPaintEngine : public QPaintEngineEx
-{
- Q_DECLARE_PRIVATE(QOpenGLPaintEngine)
-public:
- QOpenGLPaintEngine();
- ~QOpenGLPaintEngine();
-
- bool begin(QPaintDevice *pdev);
- bool end();
-
- // new stuff
- void clipEnabledChanged();
- void penChanged();
- void brushChanged();
- void brushOriginChanged();
- void opacityChanged();
- void compositionModeChanged();
- void renderHintsChanged();
- void transformChanged();
-
- void fill(const QVectorPath &path, const QBrush &brush);
- void clip(const QVectorPath &path, Qt::ClipOperation op);
-
- void setState(QPainterState *s);
- QPainterState *createState(QPainterState *orig) const;
- inline QOpenGLPaintEngineState *state() {
- return static_cast<QOpenGLPaintEngineState *>(QPaintEngineEx::state());
- }
- inline const QOpenGLPaintEngineState *state() const {
- return static_cast<const QOpenGLPaintEngineState *>(QPaintEngineEx::state());
- }
-
-
- // old stuff
- void updateState(const QPaintEngineState &state);
-
- void updatePen(const QPen &pen);
- void updateBrush(const QBrush &brush, const QPointF &pt);
- void updateFont(const QFont &font);
- void updateMatrix(const QTransform &matrix);
- void updateClipRegion(const QRegion &region, Qt::ClipOperation op);
- void updateRenderHints(QPainter::RenderHints hints);
- void updateCompositionMode(QPainter::CompositionMode composition_mode);
-
- void drawRects(const QRectF *r, int rectCount);
- void drawLines(const QLineF *lines, int lineCount);
- void drawPoints(const QPointF *p, int pointCount);
- void drawRects(const QRect *r, int rectCount);
- void drawLines(const QLine *lines, int lineCount);
- void drawPoints(const QPoint *p, int pointCount);
-
- void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr);
-
- void drawPath(const QPainterPath &path);
- void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode);
- void drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode);
- void drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s);
- void drawImage(const QRectF &r, const QImage &image, const QRectF &sr,
- Qt::ImageConversionFlags conversionFlags);
- void drawTextItem(const QPointF &p, const QTextItem &ti);
- void drawStaticTextItem(QStaticTextItem *staticTextItem);
-
- void drawEllipse(const QRectF &rect);
-
-#ifdef Q_WS_WIN
- HDC handle() const;
-#else
- Qt::HANDLE handle() const;
-#endif
- inline Type type() const { return QPaintEngine::OpenGL; }
- bool supportsTransformations(qreal, const QTransform &) const { return true; }
-
-private:
- void drawPolyInternal(const QPolygonF &pa, bool close = true);
- void drawTextureRect(int tx_width, int tx_height, const QRectF &r, const QRectF &sr,
- GLenum target, QGLTexture *tex);
- Q_DISABLE_COPY(QOpenGLPaintEngine)
-};
-
-
-QT_END_NAMESPACE
-
-#endif // QPAINTENGINE_OPENGL_P_H
diff --git a/src/opengl/qpixmapdata_gl.cpp b/src/opengl/qpixmapdata_gl.cpp
deleted file mode 100644
index e909ff30b9..0000000000
--- a/src/opengl/qpixmapdata_gl.cpp
+++ /dev/null
@@ -1,829 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qpixmap.h"
-#include "qglframebufferobject.h"
-
-#include <private/qpaintengine_raster_p.h>
-
-#include "qpixmapdata_gl_p.h"
-
-#include <private/qgl_p.h>
-#include <private/qdrawhelper_p.h>
-#include <private/qimage_p.h>
-#include <private/qfont_p.h>
-
-#include <private/qpaintengineex_opengl2_p.h>
-
-#include <qdesktopwidget.h>
-#include <qfile.h>
-#include <qimagereader.h>
-#include <qbuffer.h>
-
-QT_BEGIN_NAMESPACE
-
-Q_OPENGL_EXPORT extern const QGLContext* qt_gl_share_context();
-
-/*!
- \class QGLFramebufferObjectPool
- \since 4.6
-
- \brief The QGLFramebufferObject class provides a pool of framebuffer
- objects for offscreen rendering purposes.
-
- When requesting an FBO of a given size and format, an FBO of the same
- format and a size at least as big as the requested size will be returned.
-
- \internal
-*/
-
-static inline int areaDiff(const QSize &size, const QGLFramebufferObject *fbo)
-{
- return qAbs(size.width() * size.height() - fbo->width() * fbo->height());
-}
-
-extern int qt_next_power_of_two(int v);
-
-static inline QSize maybeRoundToNextPowerOfTwo(const QSize &sz)
-{
-#ifdef QT_OPENGL_ES_2
- QSize rounded(qt_next_power_of_two(sz.width()), qt_next_power_of_two(sz.height()));
- if (rounded.width() * rounded.height() < 1.20 * sz.width() * sz.height())
- return rounded;
-#endif
- return sz;
-}
-
-
-QGLFramebufferObject *QGLFramebufferObjectPool::acquire(const QSize &requestSize, const QGLFramebufferObjectFormat &requestFormat, bool strictSize)
-{
- QGLFramebufferObject *chosen = 0;
- QGLFramebufferObject *candidate = 0;
- for (int i = 0; !chosen && i < m_fbos.size(); ++i) {
- QGLFramebufferObject *fbo = m_fbos.at(i);
-
- if (strictSize) {
- if (fbo->size() == requestSize && fbo->format() == requestFormat) {
- chosen = fbo;
- break;
- } else {
- continue;
- }
- }
-
- if (fbo->format() == requestFormat) {
- // choose the fbo with a matching format and the closest size
- if (!candidate || areaDiff(requestSize, candidate) > areaDiff(requestSize, fbo))
- candidate = fbo;
- }
-
- if (candidate) {
- m_fbos.removeOne(candidate);
-
- const QSize fboSize = candidate->size();
- QSize sz = fboSize;
-
- if (sz.width() < requestSize.width())
- sz.setWidth(qMax(requestSize.width(), qRound(sz.width() * 1.5)));
- if (sz.height() < requestSize.height())
- sz.setHeight(qMax(requestSize.height(), qRound(sz.height() * 1.5)));
-
- // wasting too much space?
- if (sz.width() * sz.height() > requestSize.width() * requestSize.height() * 4)
- sz = requestSize;
-
- if (sz != fboSize) {
- delete candidate;
- candidate = new QGLFramebufferObject(maybeRoundToNextPowerOfTwo(sz), requestFormat);
- }
-
- chosen = candidate;
- }
- }
-
- if (!chosen) {
- if (strictSize)
- chosen = new QGLFramebufferObject(requestSize, requestFormat);
- else
- chosen = new QGLFramebufferObject(maybeRoundToNextPowerOfTwo(requestSize), requestFormat);
- }
-
- if (!chosen->isValid()) {
- delete chosen;
- chosen = 0;
- }
-
- return chosen;
-}
-
-void QGLFramebufferObjectPool::release(QGLFramebufferObject *fbo)
-{
- if (fbo)
- m_fbos << fbo;
-}
-
-
-QPaintEngine* QGLPixmapGLPaintDevice::paintEngine() const
-{
- return data->paintEngine();
-}
-
-void QGLPixmapGLPaintDevice::beginPaint()
-{
- if (!data->isValid())
- return;
-
- // QGLPaintDevice::beginPaint will store the current binding and replace
- // it with m_thisFBO:
- m_thisFBO = data->m_renderFbo->handle();
- QGLPaintDevice::beginPaint();
-
- Q_ASSERT(data->paintEngine()->type() == QPaintEngine::OpenGL2);
-
- // QPixmap::fill() is deferred until now, where we actually need to do the fill:
- if (data->needsFill()) {
- const QColor &c = data->fillColor();
- float alpha = c.alphaF();
- glDisable(GL_SCISSOR_TEST);
- glClearColor(c.redF() * alpha, c.greenF() * alpha, c.blueF() * alpha, alpha);
- glClear(GL_COLOR_BUFFER_BIT);
- }
- else if (!data->isUninitialized()) {
- // If the pixmap (GL Texture) has valid content (it has been
- // uploaded from an image or rendered into before), we need to
- // copy it from the texture to the render FBO.
-
- glDisable(GL_DEPTH_TEST);
- glDisable(GL_SCISSOR_TEST);
- glDisable(GL_BLEND);
-
-#if !defined(QT_OPENGL_ES_2)
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
-
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(0, data->width(), data->height(), 0, -999999, 999999);
-#endif
-
- glViewport(0, 0, data->width(), data->height());
-
- // Pass false to bind so it doesn't copy the FBO into the texture!
- context()->drawTexture(QRect(0, 0, data->width(), data->height()), data->bind(false));
- }
-}
-
-void QGLPixmapGLPaintDevice::endPaint()
-{
- if (!data->isValid())
- return;
-
- data->copyBackFromRenderFbo(false);
-
- // Base's endPaint will restore the previous FBO binding
- QGLPaintDevice::endPaint();
-
- qgl_fbo_pool()->release(data->m_renderFbo);
- data->m_renderFbo = 0;
-}
-
-QGLContext* QGLPixmapGLPaintDevice::context() const
-{
- data->ensureCreated();
- return data->m_ctx;
-}
-
-QSize QGLPixmapGLPaintDevice::size() const
-{
- return data->size();
-}
-
-bool QGLPixmapGLPaintDevice::alphaRequested() const
-{
- return data->m_hasAlpha;
-}
-
-void QGLPixmapGLPaintDevice::setPixmapData(QGLPixmapData* d)
-{
- data = d;
-}
-
-static int qt_gl_pixmap_serial = 0;
-
-QGLPixmapData::QGLPixmapData(PixelType type)
- : QPixmapData(type, OpenGLClass)
- , m_renderFbo(0)
- , m_engine(0)
- , m_ctx(0)
- , m_dirty(false)
- , m_hasFillColor(false)
- , m_hasAlpha(false)
-{
- setSerialNumber(++qt_gl_pixmap_serial);
- m_glDevice.setPixmapData(this);
-}
-
-QGLPixmapData::~QGLPixmapData()
-{
- const QGLContext *shareContext = qt_gl_share_context();
- if (!shareContext)
- return;
-
- delete m_engine;
-
- if (m_texture.id) {
- QGLShareContextScope ctx(shareContext);
- glDeleteTextures(1, &m_texture.id);
- }
-}
-
-QPixmapData *QGLPixmapData::createCompatiblePixmapData() const
-{
- return new QGLPixmapData(pixelType());
-}
-
-bool QGLPixmapData::isValid() const
-{
- return w > 0 && h > 0;
-}
-
-bool QGLPixmapData::isValidContext(const QGLContext *ctx) const
-{
- if (ctx == m_ctx)
- return true;
-
- const QGLContext *share_ctx = qt_gl_share_context();
- return ctx == share_ctx || QGLContext::areSharing(ctx, share_ctx);
-}
-
-void QGLPixmapData::resize(int width, int height)
-{
- if (width == w && height == h)
- return;
-
- if (width <= 0 || height <= 0) {
- width = 0;
- height = 0;
- }
-
- w = width;
- h = height;
- is_null = (w <= 0 || h <= 0);
- d = pixelType() == QPixmapData::PixmapType ? 32 : 1;
-
- if (m_texture.id) {
- QGLShareContextScope ctx(qt_gl_share_context());
- glDeleteTextures(1, &m_texture.id);
- m_texture.id = 0;
- }
-
- m_source = QImage();
- m_dirty = isValid();
- setSerialNumber(++qt_gl_pixmap_serial);
-}
-
-void QGLPixmapData::ensureCreated() const
-{
- if (!m_dirty)
- return;
-
- m_dirty = false;
-
- QGLShareContextScope ctx(qt_gl_share_context());
- m_ctx = ctx;
-
- const GLenum internal_format = m_hasAlpha ? GL_RGBA : GL_RGB;
-#ifdef QT_OPENGL_ES_2
- const GLenum external_format = internal_format;
-#else
- const GLenum external_format = qt_gl_preferredTextureFormat();
-#endif
- const GLenum target = GL_TEXTURE_2D;
-
- if (!m_texture.id) {
- glGenTextures(1, &m_texture.id);
- glBindTexture(target, m_texture.id);
- glTexImage2D(target, 0, internal_format, w, h, 0, external_format, GL_UNSIGNED_BYTE, 0);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- }
-
- if (!m_source.isNull()) {
- if (external_format == GL_RGB) {
- const QImage tx = m_source.convertToFormat(QImage::Format_RGB888).mirrored(false, true);
-
- glBindTexture(target, m_texture.id);
- glTexSubImage2D(target, 0, 0, 0, w, h, external_format,
- GL_UNSIGNED_BYTE, tx.bits());
- } else {
- const QImage tx = ctx->d_func()->convertToGLFormat(m_source, true, external_format);
-
- glBindTexture(target, m_texture.id);
- glTexSubImage2D(target, 0, 0, 0, w, h, external_format,
- GL_UNSIGNED_BYTE, tx.bits());
- }
-
- if (useFramebufferObjects())
- m_source = QImage();
- }
-
- m_texture.options &= ~QGLContext::MemoryManagedBindOption;
-}
-
-void QGLPixmapData::fromImage(const QImage &image,
- Qt::ImageConversionFlags flags)
-{
- QImage img = image;
- createPixmapForImage(img, flags, false);
-}
-
-void QGLPixmapData::fromImageReader(QImageReader *imageReader,
- Qt::ImageConversionFlags flags)
-{
- QImage image = imageReader->read();
- if (image.isNull())
- return;
-
- createPixmapForImage(image, flags, true);
-}
-
-bool QGLPixmapData::fromFile(const QString &filename, const char *format,
- Qt::ImageConversionFlags flags)
-{
- if (pixelType() == QPixmapData::BitmapType)
- return QPixmapData::fromFile(filename, format, flags);
- QFile file(filename);
- if (file.open(QIODevice::ReadOnly)) {
- QByteArray data = file.peek(64);
- bool alpha;
- if (m_texture.canBindCompressedTexture
- (data.constData(), data.size(), format, &alpha)) {
- resize(0, 0);
- data = file.readAll();
- file.close();
- QGLShareContextScope ctx(qt_gl_share_context());
- QSize size = m_texture.bindCompressedTexture
- (data.constData(), data.size(), format);
- if (!size.isEmpty()) {
- w = size.width();
- h = size.height();
- is_null = false;
- d = 32;
- m_hasAlpha = alpha;
- m_source = QImage();
- m_dirty = isValid();
- return true;
- }
- return false;
- }
- }
-
- QImage image = QImageReader(filename, format).read();
- if (image.isNull())
- return false;
-
- createPixmapForImage(image, flags, true);
-
- return !isNull();
-}
-
-bool QGLPixmapData::fromData(const uchar *buffer, uint len, const char *format,
- Qt::ImageConversionFlags flags)
-{
- bool alpha;
- const char *buf = reinterpret_cast<const char *>(buffer);
- if (m_texture.canBindCompressedTexture(buf, int(len), format, &alpha)) {
- resize(0, 0);
- QGLShareContextScope ctx(qt_gl_share_context());
- QSize size = m_texture.bindCompressedTexture(buf, int(len), format);
- if (!size.isEmpty()) {
- w = size.width();
- h = size.height();
- is_null = false;
- d = 32;
- m_hasAlpha = alpha;
- m_source = QImage();
- m_dirty = isValid();
- return true;
- }
- }
-
- QByteArray a = QByteArray::fromRawData(reinterpret_cast<const char *>(buffer), len);
- QBuffer b(&a);
- b.open(QIODevice::ReadOnly);
- QImage image = QImageReader(&b, format).read();
- if (image.isNull())
- return false;
-
- createPixmapForImage(image, flags, true);
-
- return !isNull();
-}
-
-/*!
- out-of-place conversion (inPlace == false) will always detach()
- */
-void QGLPixmapData::createPixmapForImage(QImage &image, Qt::ImageConversionFlags flags, bool inPlace)
-{
- if (image.size() == QSize(w, h))
- setSerialNumber(++qt_gl_pixmap_serial);
-
- resize(image.width(), image.height());
-
- if (pixelType() == BitmapType) {
- m_source = image.convertToFormat(QImage::Format_MonoLSB);
-
- } else {
- QImage::Format format = QImage::Format_RGB32;
- if (qApp->desktop()->depth() == 16)
- format = QImage::Format_RGB16;
-
- if (image.hasAlphaChannel()
- && ((flags & Qt::NoOpaqueDetection)
- || const_cast<QImage &>(image).data_ptr()->checkForAlphaPixels()))
- format = QImage::Format_ARGB32_Premultiplied;;
-
- if (inPlace && image.data_ptr()->convertInPlace(format, flags)) {
- m_source = image;
- } else {
- m_source = image.convertToFormat(format);
-
- // convertToFormat won't detach the image if format stays the same.
- if (image.format() == format)
- m_source.detach();
- }
- }
-
- m_dirty = true;
- m_hasFillColor = false;
-
- m_hasAlpha = m_source.hasAlphaChannel();
- w = image.width();
- h = image.height();
- is_null = (w <= 0 || h <= 0);
- d = m_source.depth();
-
- if (m_texture.id) {
- QGLShareContextScope ctx(qt_gl_share_context());
- glDeleteTextures(1, &m_texture.id);
- m_texture.id = 0;
- }
-}
-
-bool QGLPixmapData::scroll(int dx, int dy, const QRect &rect)
-{
- Q_UNUSED(dx);
- Q_UNUSED(dy);
- Q_UNUSED(rect);
- return false;
-}
-
-void QGLPixmapData::copy(const QPixmapData *data, const QRect &rect)
-{
- if (data->classId() != QPixmapData::OpenGLClass || !static_cast<const QGLPixmapData *>(data)->useFramebufferObjects()) {
- QPixmapData::copy(data, rect);
- return;
- }
-
- const QGLPixmapData *other = static_cast<const QGLPixmapData *>(data);
- if (other->m_renderFbo) {
- QGLShareContextScope ctx(qt_gl_share_context());
-
- resize(rect.width(), rect.height());
- m_hasAlpha = other->m_hasAlpha;
- ensureCreated();
-
- if (!ctx->d_ptr->fbo)
- glGenFramebuffers(1, &ctx->d_ptr->fbo);
-
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, ctx->d_ptr->fbo);
- glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
- GL_TEXTURE_2D, m_texture.id, 0);
-
- if (!other->m_renderFbo->isBound())
- glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, other->m_renderFbo->handle());
-
- glDisable(GL_SCISSOR_TEST);
- if (ctx->d_ptr->active_engine && ctx->d_ptr->active_engine->type() == QPaintEngine::OpenGL2)
- static_cast<QGL2PaintEngineEx *>(ctx->d_ptr->active_engine)->invalidateState();
-
- glBlitFramebufferEXT(rect.x(), rect.y(), rect.x() + rect.width(), rect.y() + rect.height(),
- 0, 0, w, h,
- GL_COLOR_BUFFER_BIT,
- GL_NEAREST);
-
- glBindFramebuffer(GL_FRAMEBUFFER_EXT, ctx->d_ptr->current_fbo);
- } else {
- QPixmapData::copy(data, rect);
- }
-}
-
-void QGLPixmapData::fill(const QColor &color)
-{
- if (!isValid())
- return;
-
- bool hasAlpha = color.alpha() != 255;
- if (hasAlpha && !m_hasAlpha) {
- if (m_texture.id) {
- glDeleteTextures(1, &m_texture.id);
- m_texture.id = 0;
- m_dirty = true;
- }
- m_hasAlpha = color.alpha() != 255;
- }
-
- if (useFramebufferObjects()) {
- m_source = QImage();
- m_hasFillColor = true;
- m_fillColor = color;
- } else {
-
- if (m_source.isNull()) {
- m_fillColor = color;
- m_hasFillColor = true;
-
- } else if (m_source.depth() == 32) {
- m_source.fill(PREMUL(color.rgba()));
-
- } else if (m_source.depth() == 1) {
- if (color == Qt::color1)
- m_source.fill(1);
- else
- m_source.fill(0);
- }
- }
-}
-
-bool QGLPixmapData::hasAlphaChannel() const
-{
- return m_hasAlpha;
-}
-
-QImage QGLPixmapData::fillImage(const QColor &color) const
-{
- QImage img;
- if (pixelType() == BitmapType) {
- img = QImage(w, h, QImage::Format_MonoLSB);
-
- img.setColorCount(2);
- img.setColor(0, QColor(Qt::color0).rgba());
- img.setColor(1, QColor(Qt::color1).rgba());
-
- if (color == Qt::color1)
- img.fill(1);
- else
- img.fill(0);
- } else {
- img = QImage(w, h,
- m_hasAlpha
- ? QImage::Format_ARGB32_Premultiplied
- : QImage::Format_RGB32);
- img.fill(PREMUL(color.rgba()));
- }
- return img;
-}
-
-extern QImage qt_gl_read_texture(const QSize &size, bool alpha_format, bool include_alpha);
-
-QImage QGLPixmapData::toImage() const
-{
- if (!isValid())
- return QImage();
-
- if (m_renderFbo) {
- copyBackFromRenderFbo(true);
- } else if (!m_source.isNull()) {
- QImageData *data = const_cast<QImage &>(m_source).data_ptr();
- if (data->paintEngine && data->paintEngine->isActive()
- && data->paintEngine->paintDevice() == &m_source)
- {
- return m_source.copy();
- }
- return m_source;
- } else if (m_dirty || m_hasFillColor) {
- return fillImage(m_fillColor);
- } else {
- ensureCreated();
- }
-
- QGLShareContextScope ctx(qt_gl_share_context());
- glBindTexture(GL_TEXTURE_2D, m_texture.id);
- return qt_gl_read_texture(QSize(w, h), true, true);
-}
-
-struct TextureBuffer
-{
- QGLFramebufferObject *fbo;
- QGL2PaintEngineEx *engine;
-};
-
-Q_GLOBAL_STATIC(QGLFramebufferObjectPool, _qgl_fbo_pool)
-QGLFramebufferObjectPool* qgl_fbo_pool()
-{
- return _qgl_fbo_pool();
-}
-
-void QGLPixmapData::copyBackFromRenderFbo(bool keepCurrentFboBound) const
-{
- if (!isValid())
- return;
-
- m_hasFillColor = false;
-
- const QGLContext *share_ctx = qt_gl_share_context();
- QGLShareContextScope ctx(share_ctx);
-
- ensureCreated();
-
- if (!ctx->d_ptr->fbo)
- glGenFramebuffers(1, &ctx->d_ptr->fbo);
-
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, ctx->d_ptr->fbo);
- glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
- GL_TEXTURE_2D, m_texture.id, 0);
-
- const int x0 = 0;
- const int x1 = w;
- const int y0 = 0;
- const int y1 = h;
-
- if (!m_renderFbo->isBound())
- glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, m_renderFbo->handle());
-
- glDisable(GL_SCISSOR_TEST);
-
- glBlitFramebufferEXT(x0, y0, x1, y1,
- x0, y0, x1, y1,
- GL_COLOR_BUFFER_BIT,
- GL_NEAREST);
-
- if (keepCurrentFboBound) {
- glBindFramebuffer(GL_FRAMEBUFFER_EXT, ctx->d_ptr->current_fbo);
- } else {
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, m_renderFbo->handle());
- ctx->d_ptr->current_fbo = m_renderFbo->handle();
- }
-}
-
-bool QGLPixmapData::useFramebufferObjects() const
-{
- return QGLFramebufferObject::hasOpenGLFramebufferObjects()
- && QGLFramebufferObject::hasOpenGLFramebufferBlit()
- && qt_gl_preferGL2Engine()
- && (w * h > 32*32); // avoid overhead of FBOs for small pixmaps
-}
-
-QPaintEngine* QGLPixmapData::paintEngine() const
-{
- if (!isValid())
- return 0;
-
- if (m_renderFbo)
- return m_engine;
-
- if (useFramebufferObjects()) {
- extern QGLWidget* qt_gl_share_widget();
-
- if (!QGLContext::currentContext())
- const_cast<QGLContext *>(qt_gl_share_context())->makeCurrent();
- QGLShareContextScope ctx(qt_gl_share_context());
-
- QGLFramebufferObjectFormat format;
- format.setAttachment(QGLFramebufferObject::CombinedDepthStencil);
- format.setSamples(4);
- format.setInternalTextureFormat(GLenum(m_hasAlpha ? GL_RGBA : GL_RGB));
-
- m_renderFbo = qgl_fbo_pool()->acquire(size(), format);
-
- if (m_renderFbo) {
- if (!m_engine)
- m_engine = new QGL2PaintEngineEx;
- return m_engine;
- }
-
- qWarning() << "Failed to create pixmap texture buffer of size " << size() << ", falling back to raster paint engine";
- }
-
- m_dirty = true;
- if (m_source.size() != size())
- m_source = QImage(size(), QImage::Format_ARGB32_Premultiplied);
- if (m_hasFillColor) {
- m_source.fill(PREMUL(m_fillColor.rgba()));
- m_hasFillColor = false;
- }
- return m_source.paintEngine();
-}
-
-extern QRgb qt_gl_convertToGLFormat(QRgb src_pixel, GLenum texture_format);
-
-// If copyBack is true, bind will copy the contents of the render
-// FBO to the texture (which is not bound to the texture, as it's
-// a multisample FBO).
-GLuint QGLPixmapData::bind(bool copyBack) const
-{
- if (m_renderFbo && copyBack) {
- copyBackFromRenderFbo(true);
- } else {
- ensureCreated();
- }
-
- GLuint id = m_texture.id;
- glBindTexture(GL_TEXTURE_2D, id);
-
- if (m_hasFillColor) {
- if (!useFramebufferObjects()) {
- m_source = QImage(w, h, QImage::Format_ARGB32_Premultiplied);
- m_source.fill(PREMUL(m_fillColor.rgba()));
- }
-
- m_hasFillColor = false;
-
- GLenum format = qt_gl_preferredTextureFormat();
- QImage tx(w, h, QImage::Format_ARGB32_Premultiplied);
- tx.fill(qt_gl_convertToGLFormat(m_fillColor.rgba(), format));
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, format, GL_UNSIGNED_BYTE, tx.bits());
- }
-
- return id;
-}
-
-QGLTexture* QGLPixmapData::texture() const
-{
- return &m_texture;
-}
-
-int QGLPixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const
-{
- if (w == 0)
- return 0;
-
- switch (metric) {
- case QPaintDevice::PdmWidth:
- return w;
- case QPaintDevice::PdmHeight:
- return h;
- case QPaintDevice::PdmNumColors:
- return 0;
- case QPaintDevice::PdmDepth:
- return d;
- case QPaintDevice::PdmWidthMM:
- return qRound(w * 25.4 / qt_defaultDpiX());
- case QPaintDevice::PdmHeightMM:
- return qRound(h * 25.4 / qt_defaultDpiY());
- case QPaintDevice::PdmDpiX:
- case QPaintDevice::PdmPhysicalDpiX:
- return qt_defaultDpiX();
- case QPaintDevice::PdmDpiY:
- case QPaintDevice::PdmPhysicalDpiY:
- return qt_defaultDpiY();
- default:
- qWarning("QGLPixmapData::metric(): Invalid metric");
- return 0;
- }
-}
-
-QGLPaintDevice *QGLPixmapData::glDevice() const
-{
- return &m_glDevice;
-}
-
-QT_END_NAMESPACE
diff --git a/src/opengl/qpixmapdata_gl_p.h b/src/opengl/qpixmapdata_gl_p.h
deleted file mode 100644
index 909f264d05..0000000000
--- a/src/opengl/qpixmapdata_gl_p.h
+++ /dev/null
@@ -1,247 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPIXMAPDATA_GL_P_H
-#define QPIXMAPDATA_GL_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qgl_p.h"
-#include "qgl.h"
-
-#include "private/qpixmapdata_p.h"
-#include "private/qglpaintdevice_p.h"
-
-#ifdef Q_OS_SYMBIAN
-#include "private/qvolatileimage_p.h"
-#endif
-
-QT_BEGIN_NAMESPACE
-
-class QPaintEngine;
-class QGLFramebufferObject;
-class QGLFramebufferObjectFormat;
-class QGLPixmapData;
-
-#ifdef QGL_USE_TEXTURE_POOL
-void qt_gl_register_pixmap(QGLPixmapData *pd);
-void qt_gl_unregister_pixmap(QGLPixmapData *pd);
-void qt_gl_hibernate_pixmaps();
-#endif
-
-#ifdef Q_OS_SYMBIAN
-class QNativeImageHandleProvider;
-#endif
-
-class QGLFramebufferObjectPool
-{
-public:
- QGLFramebufferObject *acquire(const QSize &size, const QGLFramebufferObjectFormat &format, bool strictSize = false);
- void release(QGLFramebufferObject *fbo);
-
-private:
- QList<QGLFramebufferObject *> m_fbos;
-};
-
-QGLFramebufferObjectPool* qgl_fbo_pool();
-
-
-class QGLPixmapGLPaintDevice : public QGLPaintDevice
-{
-public:
- QPaintEngine* paintEngine() const;
-
- void beginPaint();
- void endPaint();
- QGLContext* context() const;
- QSize size() const;
- bool alphaRequested() const;
-
- void setPixmapData(QGLPixmapData*);
-private:
- QGLPixmapData *data;
-};
-
-
-class Q_OPENGL_EXPORT QGLPixmapData : public QPixmapData
-{
-public:
- QGLPixmapData(PixelType type);
- ~QGLPixmapData();
-
- QPixmapData *createCompatiblePixmapData() const;
-
- // Re-implemented from QPixmapData:
- void resize(int width, int height);
- void fromImage(const QImage &image, Qt::ImageConversionFlags flags);
- void fromImageReader(QImageReader *imageReader,
- Qt::ImageConversionFlags flags);
- bool fromFile(const QString &filename, const char *format,
- Qt::ImageConversionFlags flags);
- bool fromData(const uchar *buffer, uint len, const char *format,
- Qt::ImageConversionFlags flags);
- void copy(const QPixmapData *data, const QRect &rect);
- bool scroll(int dx, int dy, const QRect &rect);
- void fill(const QColor &color);
- bool hasAlphaChannel() const;
- QImage toImage() const;
- QPaintEngine *paintEngine() const;
- int metric(QPaintDevice::PaintDeviceMetric metric) const;
-
- // For accessing as a target:
- QGLPaintDevice *glDevice() const;
-
- // For accessing as a source:
- bool isValidContext(const QGLContext *ctx) const;
- GLuint bind(bool copyBack = true) const;
- QGLTexture *texture() const;
-
-#ifdef QGL_USE_TEXTURE_POOL
- void destroyTexture();
- // Detach this image from the image pool.
- void detachTextureFromPool();
- // Release the GL resources associated with this pixmap and copy
- // the pixmap's contents out of the GPU back into main memory.
- // The GL resource will be automatically recreated the next time
- // ensureCreated() is called. Does nothing if the pixmap cannot be
- // hibernated for some reason (e.g. texture is shared with another
- // process via a SgImage).
- void hibernate();
- // Called when the QGLTexturePool wants to reclaim this pixmap's
- // texture objects to reuse storage.
- void reclaimTexture();
- void forceToImage();
-#endif
-
-#ifdef Q_OS_SYMBIAN
- QImage::Format idealFormat(QImage &image, Qt::ImageConversionFlags flags);
- void* toNativeType(NativeType type);
- void fromNativeType(void* pixmap, NativeType type);
- bool initFromNativeImageHandle(void *handle, const QString &type);
- void createFromNativeImageHandleProvider();
- void releaseNativeImageHandle();
-#endif
-
-private:
- bool isValid() const;
-
- void ensureCreated() const;
-
- bool isUninitialized() const { return m_dirty && m_source.isNull(); }
-
- bool needsFill() const { return m_hasFillColor; }
- QColor fillColor() const { return m_fillColor; }
-
-
-
- QGLPixmapData(const QGLPixmapData &other);
- QGLPixmapData &operator=(const QGLPixmapData &other);
-
- void copyBackFromRenderFbo(bool keepCurrentFboBound) const;
- QSize size() const { return QSize(w, h); }
-
- bool useFramebufferObjects() const;
-
- QImage fillImage(const QColor &color) const;
-
- void createPixmapForImage(QImage &image, Qt::ImageConversionFlags flags, bool inPlace);
-
- mutable QGLFramebufferObject *m_renderFbo;
- mutable QPaintEngine *m_engine;
- mutable QGLContext *m_ctx;
-#ifdef Q_OS_SYMBIAN
- mutable QVolatileImage m_source;
- mutable QNativeImageHandleProvider *nativeImageHandleProvider;
- void *nativeImageHandle;
- QString nativeImageType;
-#else
- mutable QImage m_source;
-#endif
- mutable QGLTexture m_texture;
-
- // the texture is not in sync with the source image
- mutable bool m_dirty;
-
- // fill has been called and no painting has been done, so the pixmap is
- // represented by a single fill color
- mutable QColor m_fillColor;
- mutable bool m_hasFillColor;
-
- mutable bool m_hasAlpha;
-
- mutable QGLPixmapGLPaintDevice m_glDevice;
-
-#ifdef QGL_USE_TEXTURE_POOL
- QGLPixmapData *nextLRU;
- QGLPixmapData *prevLRU;
- mutable bool inLRU;
- mutable bool failedToAlloc;
- mutable bool inTexturePool;
-
- QGLPixmapData *next;
- QGLPixmapData *prev;
-
- friend class QGLTexturePool;
-
- friend void qt_gl_register_pixmap(QGLPixmapData *pd);
- friend void qt_gl_unregister_pixmap(QGLPixmapData *pd);
- friend void qt_gl_hibernate_pixmaps();
-#endif
-
- friend class QGLPixmapGLPaintDevice;
- friend class QMeeGoPixmapData;
- friend class QMeeGoLivePixmapData;
-};
-
-QT_END_NAMESPACE
-
-#endif // QPIXMAPDATA_GL_P_H
-
-
diff --git a/src/opengl/qpixmapdata_poolgl.cpp b/src/opengl/qpixmapdata_poolgl.cpp
deleted file mode 100644
index 5dd7b09c64..0000000000
--- a/src/opengl/qpixmapdata_poolgl.cpp
+++ /dev/null
@@ -1,934 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qpixmap.h"
-#include "qglframebufferobject.h"
-
-#include <private/qpaintengine_raster_p.h>
-
-#include "qpixmapdata_gl_p.h"
-
-#include <private/qgl_p.h>
-#include <private/qdrawhelper_p.h>
-#include <private/qimage_p.h>
-#include <private/qnativeimagehandleprovider_p.h>
-#include <private/qfont_p.h>
-
-#include <private/qpaintengineex_opengl2_p.h>
-
-#include <qdesktopwidget.h>
-#include <qfile.h>
-#include <qimagereader.h>
-#include <qbuffer.h>
-
-#include "qgltexturepool_p.h"
-
-QT_BEGIN_NAMESPACE
-
-Q_OPENGL_EXPORT extern QGLWidget* qt_gl_share_widget();
-
-static inline int areaDiff(const QSize &size, const QGLFramebufferObject *fbo)
-{
- return qAbs(size.width() * size.height() - fbo->width() * fbo->height());
-}
-
-extern int qt_next_power_of_two(int v);
-
-static inline QSize maybeRoundToNextPowerOfTwo(const QSize &sz)
-{
-#ifdef QT_OPENGL_ES_2
- QSize rounded(qt_next_power_of_two(sz.width()), qt_next_power_of_two(sz.height()));
- if (rounded.width() * rounded.height() < 1.20 * sz.width() * sz.height())
- return rounded;
-#endif
- return sz;
-}
-
-
-QGLFramebufferObject *QGLFramebufferObjectPool::acquire(const QSize &requestSize, const QGLFramebufferObjectFormat &requestFormat, bool strictSize)
-{
- QGLFramebufferObject *chosen = 0;
- QGLFramebufferObject *candidate = 0;
- for (int i = 0; !chosen && i < m_fbos.size(); ++i) {
- QGLFramebufferObject *fbo = m_fbos.at(i);
-
- if (strictSize) {
- if (fbo->size() == requestSize && fbo->format() == requestFormat) {
- chosen = fbo;
- break;
- } else {
- continue;
- }
- }
-
- if (fbo->format() == requestFormat) {
- // choose the fbo with a matching format and the closest size
- if (!candidate || areaDiff(requestSize, candidate) > areaDiff(requestSize, fbo))
- candidate = fbo;
- }
-
- if (candidate) {
- m_fbos.removeOne(candidate);
-
- const QSize fboSize = candidate->size();
- QSize sz = fboSize;
-
- if (sz.width() < requestSize.width())
- sz.setWidth(qMax(requestSize.width(), qRound(sz.width() * 1.5)));
- if (sz.height() < requestSize.height())
- sz.setHeight(qMax(requestSize.height(), qRound(sz.height() * 1.5)));
-
- // wasting too much space?
- if (sz.width() * sz.height() > requestSize.width() * requestSize.height() * 4)
- sz = requestSize;
-
- if (sz != fboSize) {
- delete candidate;
- candidate = new QGLFramebufferObject(maybeRoundToNextPowerOfTwo(sz), requestFormat);
- }
-
- chosen = candidate;
- }
- }
-
- if (!chosen) {
- if (strictSize)
- chosen = new QGLFramebufferObject(requestSize, requestFormat);
- else
- chosen = new QGLFramebufferObject(maybeRoundToNextPowerOfTwo(requestSize), requestFormat);
- }
-
- if (!chosen->isValid()) {
- delete chosen;
- chosen = 0;
- }
-
- return chosen;
-}
-
-void QGLFramebufferObjectPool::release(QGLFramebufferObject *fbo)
-{
- if (fbo)
- m_fbos << fbo;
-}
-
-
-QPaintEngine* QGLPixmapGLPaintDevice::paintEngine() const
-{
- return data->paintEngine();
-}
-
-void QGLPixmapGLPaintDevice::beginPaint()
-{
- if (!data->isValid())
- return;
-
- // QGLPaintDevice::beginPaint will store the current binding and replace
- // it with m_thisFBO:
- m_thisFBO = data->m_renderFbo->handle();
- QGLPaintDevice::beginPaint();
-
- Q_ASSERT(data->paintEngine()->type() == QPaintEngine::OpenGL2);
-
- // QPixmap::fill() is deferred until now, where we actually need to do the fill:
- if (data->needsFill()) {
- const QColor &c = data->fillColor();
- float alpha = c.alphaF();
- glDisable(GL_SCISSOR_TEST);
- glClearColor(c.redF() * alpha, c.greenF() * alpha, c.blueF() * alpha, alpha);
- glClear(GL_COLOR_BUFFER_BIT);
- }
- else if (!data->isUninitialized()) {
- // If the pixmap (GL Texture) has valid content (it has been
- // uploaded from an image or rendered into before), we need to
- // copy it from the texture to the render FBO.
-
- glDisable(GL_DEPTH_TEST);
- glDisable(GL_SCISSOR_TEST);
- glDisable(GL_BLEND);
-
-#if !defined(QT_OPENGL_ES_2)
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
-
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(0, data->width(), data->height(), 0, -999999, 999999);
-#endif
-
- glViewport(0, 0, data->width(), data->height());
-
- // Pass false to bind so it doesn't copy the FBO into the texture!
- context()->drawTexture(QRect(0, 0, data->width(), data->height()), data->bind(false));
- }
-}
-
-void QGLPixmapGLPaintDevice::endPaint()
-{
- if (!data->isValid())
- return;
-
- data->copyBackFromRenderFbo(false);
-
- // Base's endPaint will restore the previous FBO binding
- QGLPaintDevice::endPaint();
-
- qgl_fbo_pool()->release(data->m_renderFbo);
- data->m_renderFbo = 0;
-}
-
-QGLContext* QGLPixmapGLPaintDevice::context() const
-{
- data->ensureCreated();
- return data->m_ctx;
-}
-
-QSize QGLPixmapGLPaintDevice::size() const
-{
- return data->size();
-}
-
-bool QGLPixmapGLPaintDevice::alphaRequested() const
-{
- return data->m_hasAlpha;
-}
-
-void QGLPixmapGLPaintDevice::setPixmapData(QGLPixmapData* d)
-{
- data = d;
-}
-
-int qt_gl_pixmap_serial = 0;
-
-QGLPixmapData::QGLPixmapData(PixelType type)
- : QPixmapData(type, OpenGLClass)
- , m_renderFbo(0)
- , m_engine(0)
- , m_ctx(0)
- , nativeImageHandleProvider(0)
- , nativeImageHandle(0)
- , m_dirty(false)
- , m_hasFillColor(false)
- , m_hasAlpha(false)
- , inLRU(false)
- , failedToAlloc(false)
- , inTexturePool(false)
-{
- setSerialNumber(++qt_gl_pixmap_serial);
- m_glDevice.setPixmapData(this);
-
- qt_gl_register_pixmap(this);
-}
-
-QGLPixmapData::~QGLPixmapData()
-{
- delete m_engine;
-
- destroyTexture();
- qt_gl_unregister_pixmap(this);
-}
-
-void QGLPixmapData::destroyTexture()
-{
- if (inTexturePool) {
- QGLTexturePool *pool = QGLTexturePool::instance();
- if (m_texture.id)
- pool->releaseTexture(this, m_texture.id);
- } else {
- if (m_texture.id) {
- QGLWidget *shareWidget = qt_gl_share_widget();
- if (shareWidget) {
- QGLShareContextScope ctx(shareWidget->context());
- glDeleteTextures(1, &m_texture.id);
- }
- }
- }
- m_texture.id = 0;
- inTexturePool = false;
-
- releaseNativeImageHandle();
-}
-
-QPixmapData *QGLPixmapData::createCompatiblePixmapData() const
-{
- return new QGLPixmapData(pixelType());
-}
-
-bool QGLPixmapData::isValid() const
-{
- return w > 0 && h > 0;
-}
-
-bool QGLPixmapData::isValidContext(const QGLContext *ctx) const
-{
- if (ctx == m_ctx)
- return true;
-
- const QGLContext *share_ctx = qt_gl_share_widget()->context();
- return ctx == share_ctx || QGLContext::areSharing(ctx, share_ctx);
-}
-
-void QGLPixmapData::resize(int width, int height)
-{
- if (width == w && height == h)
- return;
-
- if (width <= 0 || height <= 0) {
- width = 0;
- height = 0;
- }
-
- w = width;
- h = height;
- is_null = (w <= 0 || h <= 0);
- d = pixelType() == QPixmapData::PixmapType ? 32 : 1;
-
- destroyTexture();
-
- m_source = QVolatileImage();
- m_dirty = isValid();
- setSerialNumber(++qt_gl_pixmap_serial);
-}
-
-void QGLPixmapData::ensureCreated() const
-{
- if (!m_dirty)
- return;
-
- m_dirty = false;
-
- if (nativeImageHandleProvider && !nativeImageHandle)
- const_cast<QGLPixmapData *>(this)->createFromNativeImageHandleProvider();
-
- QGLShareContextScope ctx(qt_gl_share_widget()->context());
- m_ctx = ctx;
-
- const GLenum internal_format = m_hasAlpha ? GL_RGBA : GL_RGB;
-#ifdef QT_OPENGL_ES_2
- const GLenum external_format = internal_format;
-#else
- const GLenum external_format = qt_gl_preferredTextureFormat();
-#endif
- const GLenum target = GL_TEXTURE_2D;
-
- GLenum type = GL_UNSIGNED_BYTE;
- // Avoid conversion when pixmap is created from CFbsBitmap of EColor64K.
- if (!m_source.isNull() && m_source.format() == QImage::Format_RGB16)
- type = GL_UNSIGNED_SHORT_5_6_5;
-
- m_texture.options &= ~QGLContext::MemoryManagedBindOption;
-
- if (!m_texture.id) {
- m_texture.id = QGLTexturePool::instance()->createTextureForPixmap(
- target,
- 0, internal_format,
- w, h,
- external_format,
- type,
- const_cast<QGLPixmapData*>(this));
- if (!m_texture.id) {
- failedToAlloc = true;
- return;
- }
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-
- inTexturePool = true;
- } else if (inTexturePool) {
- glBindTexture(target, m_texture.id);
- QGLTexturePool::instance()->useTexture(const_cast<QGLPixmapData*>(this));
- }
-
- if (!m_source.isNull() && m_texture.id) {
- if (external_format == GL_RGB) {
- m_source.beginDataAccess();
- QImage tx;
- if (type == GL_UNSIGNED_BYTE)
- tx = m_source.imageRef().convertToFormat(QImage::Format_RGB888).mirrored(false, true);
- else if (type == GL_UNSIGNED_SHORT_5_6_5)
- tx = m_source.imageRef().mirrored(false, true);
- m_source.endDataAccess(true);
-
- glBindTexture(target, m_texture.id);
- if (!tx.isNull())
- glTexSubImage2D(target, 0, 0, 0, w, h, external_format,
- type, tx.constBits());
- else
- qWarning("QGLPixmapData: Failed to create GL_RGB image of size %dx%d", w, h);
- } else {
- // do byte swizzling ARGB -> RGBA
- m_source.beginDataAccess();
- const QImage tx = ctx->d_func()->convertToGLFormat(m_source.imageRef(), true, external_format);
- m_source.endDataAccess(true);
- glBindTexture(target, m_texture.id);
- if (!tx.isNull())
- glTexSubImage2D(target, 0, 0, 0, w, h, external_format,
- type, tx.constBits());
- else
- qWarning("QGLPixmapData: Failed to create GL_RGBA image of size %dx%d", w, h);
- }
-
- if (useFramebufferObjects())
- m_source = QVolatileImage();
- }
-}
-
-
-void QGLPixmapData::fromImage(const QImage &image,
- Qt::ImageConversionFlags flags)
-{
- QImage img = image;
- createPixmapForImage(img, flags, false);
-}
-
-void QGLPixmapData::fromImageReader(QImageReader *imageReader,
- Qt::ImageConversionFlags flags)
-{
- QImage image = imageReader->read();
- if (image.isNull())
- return;
-
- createPixmapForImage(image, flags, true);
-}
-
-bool QGLPixmapData::fromFile(const QString &filename, const char *format,
- Qt::ImageConversionFlags flags)
-{
- if (pixelType() == QPixmapData::BitmapType)
- return QPixmapData::fromFile(filename, format, flags);
- QFile file(filename);
- if (file.open(QIODevice::ReadOnly)) {
- QByteArray data = file.peek(64);
- bool alpha;
- if (m_texture.canBindCompressedTexture
- (data.constData(), data.size(), format, &alpha)) {
- resize(0, 0);
- data = file.readAll();
- file.close();
- QGLShareContextScope ctx(qt_gl_share_widget()->context());
- QSize size = m_texture.bindCompressedTexture
- (data.constData(), data.size(), format);
- if (!size.isEmpty()) {
- w = size.width();
- h = size.height();
- is_null = false;
- d = 32;
- m_hasAlpha = alpha;
- m_source = QVolatileImage();
- m_dirty = isValid();
- return true;
- }
- return false;
- }
- }
-
- QImage image = QImageReader(filename, format).read();
- if (image.isNull())
- return false;
-
- createPixmapForImage(image, flags, true);
-
- return !isNull();
-}
-
-bool QGLPixmapData::fromData(const uchar *buffer, uint len, const char *format,
- Qt::ImageConversionFlags flags)
-{
- bool alpha;
- const char *buf = reinterpret_cast<const char *>(buffer);
- if (m_texture.canBindCompressedTexture(buf, int(len), format, &alpha)) {
- resize(0, 0);
- QGLShareContextScope ctx(qt_gl_share_widget()->context());
- QSize size = m_texture.bindCompressedTexture(buf, int(len), format);
- if (!size.isEmpty()) {
- w = size.width();
- h = size.height();
- is_null = false;
- d = 32;
- m_hasAlpha = alpha;
- m_source = QVolatileImage();
- m_dirty = isValid();
- return true;
- }
- }
-
- QByteArray a = QByteArray::fromRawData(reinterpret_cast<const char *>(buffer), len);
- QBuffer b(&a);
- b.open(QIODevice::ReadOnly);
- QImage image = QImageReader(&b, format).read();
- if (image.isNull())
- return false;
-
- createPixmapForImage(image, flags, true);
-
- return !isNull();
-}
-
-QImage::Format QGLPixmapData::idealFormat(QImage &image, Qt::ImageConversionFlags flags)
-{
- QImage::Format format = QImage::Format_RGB32;
- if (qApp->desktop()->depth() == 16)
- format = QImage::Format_RGB16;
-
- if (image.hasAlphaChannel()
- && ((flags & Qt::NoOpaqueDetection)
- || const_cast<QImage &>(image).data_ptr()->checkForAlphaPixels()))
- format = QImage::Format_ARGB32_Premultiplied;
-
- return format;
-}
-
-void QGLPixmapData::createPixmapForImage(QImage &image, Qt::ImageConversionFlags flags, bool inPlace)
-{
- if (image.size() == QSize(w, h))
- setSerialNumber(++qt_gl_pixmap_serial);
-
- resize(image.width(), image.height());
-
- if (pixelType() == BitmapType) {
- QImage convertedImage = image.convertToFormat(QImage::Format_MonoLSB);
- if (image.format() == QImage::Format_MonoLSB)
- convertedImage.detach();
-
- m_source = QVolatileImage(convertedImage);
-
- } else {
- QImage::Format format = idealFormat(image, flags);
-
- if (inPlace && image.data_ptr()->convertInPlace(format, flags)) {
- m_source = QVolatileImage(image);
- } else {
- QImage convertedImage = image.convertToFormat(format);
-
- // convertToFormat won't detach the image if format stays the same.
- if (image.format() == format)
- convertedImage.detach();
-
- m_source = QVolatileImage(convertedImage);
- }
- }
-
- m_dirty = true;
- m_hasFillColor = false;
-
- m_hasAlpha = m_source.hasAlphaChannel();
- w = image.width();
- h = image.height();
- is_null = (w <= 0 || h <= 0);
- d = m_source.depth();
-
- destroyTexture();
-}
-
-bool QGLPixmapData::scroll(int dx, int dy, const QRect &rect)
-{
- Q_UNUSED(dx);
- Q_UNUSED(dy);
- Q_UNUSED(rect);
- return false;
-}
-
-void QGLPixmapData::copy(const QPixmapData *data, const QRect &rect)
-{
- if (data->classId() != QPixmapData::OpenGLClass || !static_cast<const QGLPixmapData *>(data)->useFramebufferObjects()) {
- QPixmapData::copy(data, rect);
- return;
- }
-
- const QGLPixmapData *other = static_cast<const QGLPixmapData *>(data);
- if (other->m_renderFbo) {
- QGLShareContextScope ctx(qt_gl_share_widget()->context());
-
- resize(rect.width(), rect.height());
- m_hasAlpha = other->m_hasAlpha;
- ensureCreated();
-
- if (!ctx->d_ptr->fbo)
- glGenFramebuffers(1, &ctx->d_ptr->fbo);
-
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, ctx->d_ptr->fbo);
- glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
- GL_TEXTURE_2D, m_texture.id, 0);
-
- if (!other->m_renderFbo->isBound())
- glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, other->m_renderFbo->handle());
-
- glDisable(GL_SCISSOR_TEST);
- if (ctx->d_ptr->active_engine && ctx->d_ptr->active_engine->type() == QPaintEngine::OpenGL2)
- static_cast<QGL2PaintEngineEx *>(ctx->d_ptr->active_engine)->invalidateState();
-
- glBlitFramebufferEXT(rect.x(), rect.y(), rect.x() + rect.width(), rect.y() + rect.height(),
- 0, 0, w, h,
- GL_COLOR_BUFFER_BIT,
- GL_NEAREST);
-
- glBindFramebuffer(GL_FRAMEBUFFER_EXT, ctx->d_ptr->current_fbo);
- } else {
- QPixmapData::copy(data, rect);
- }
-}
-
-void QGLPixmapData::fill(const QColor &color)
-{
- if (!isValid())
- return;
-
- bool hasAlpha = color.alpha() != 255;
- if (hasAlpha && !m_hasAlpha) {
- if (m_texture.id) {
- destroyTexture();
- m_dirty = true;
- }
- m_hasAlpha = color.alpha() != 255;
- }
-
- if (useFramebufferObjects()) {
- m_source = QVolatileImage();
- m_hasFillColor = true;
- m_fillColor = color;
- } else {
- forceToImage();
-
- if (m_source.depth() == 32) {
- m_source.fill(PREMUL(color.rgba()));
-
- } else if (m_source.depth() == 1) {
- if (color == Qt::color1)
- m_source.fill(1);
- else
- m_source.fill(0);
- }
- }
-}
-
-bool QGLPixmapData::hasAlphaChannel() const
-{
- return m_hasAlpha;
-}
-
-QImage QGLPixmapData::fillImage(const QColor &color) const
-{
- QImage img;
- if (pixelType() == BitmapType) {
- img = QImage(w, h, QImage::Format_MonoLSB);
-
- img.setColorCount(2);
- img.setColor(0, QColor(Qt::color0).rgba());
- img.setColor(1, QColor(Qt::color1).rgba());
-
- if (color == Qt::color1)
- img.fill(1);
- else
- img.fill(0);
- } else {
- img = QImage(w, h,
- m_hasAlpha
- ? QImage::Format_ARGB32_Premultiplied
- : QImage::Format_RGB32);
- img.fill(PREMUL(color.rgba()));
- }
- return img;
-}
-
-extern QImage qt_gl_read_texture(const QSize &size, bool alpha_format, bool include_alpha);
-
-QImage QGLPixmapData::toImage() const
-{
- if (!isValid())
- return QImage();
-
- if (m_renderFbo) {
- copyBackFromRenderFbo(true);
- } else if (!m_source.isNull()) {
- // QVolatileImage::toImage() will make a copy always so no check
- // for active painting is needed.
- QImage img = m_source.toImage();
- if (img.format() == QImage::Format_MonoLSB) {
- img.setColorCount(2);
- img.setColor(0, QColor(Qt::color0).rgba());
- img.setColor(1, QColor(Qt::color1).rgba());
- }
- return img;
- } else if (m_dirty || m_hasFillColor) {
- return fillImage(m_fillColor);
- } else {
- ensureCreated();
- }
-
- QGLShareContextScope ctx(qt_gl_share_widget()->context());
- glBindTexture(GL_TEXTURE_2D, m_texture.id);
- return qt_gl_read_texture(QSize(w, h), true, true);
-}
-
-struct TextureBuffer
-{
- QGLFramebufferObject *fbo;
- QGL2PaintEngineEx *engine;
-};
-
-Q_GLOBAL_STATIC(QGLFramebufferObjectPool, _qgl_fbo_pool)
-QGLFramebufferObjectPool* qgl_fbo_pool()
-{
- return _qgl_fbo_pool();
-}
-
-void QGLPixmapData::copyBackFromRenderFbo(bool keepCurrentFboBound) const
-{
- if (!isValid())
- return;
-
- m_hasFillColor = false;
-
- const QGLContext *share_ctx = qt_gl_share_widget()->context();
- QGLShareContextScope ctx(share_ctx);
-
- ensureCreated();
-
- if (!ctx->d_ptr->fbo)
- glGenFramebuffers(1, &ctx->d_ptr->fbo);
-
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, ctx->d_ptr->fbo);
- glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
- GL_TEXTURE_2D, m_texture.id, 0);
-
- const int x0 = 0;
- const int x1 = w;
- const int y0 = 0;
- const int y1 = h;
-
- if (!m_renderFbo->isBound())
- glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, m_renderFbo->handle());
-
- glDisable(GL_SCISSOR_TEST);
-
- glBlitFramebufferEXT(x0, y0, x1, y1,
- x0, y0, x1, y1,
- GL_COLOR_BUFFER_BIT,
- GL_NEAREST);
-
- if (keepCurrentFboBound) {
- glBindFramebuffer(GL_FRAMEBUFFER_EXT, ctx->d_ptr->current_fbo);
- } else {
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, m_renderFbo->handle());
- ctx->d_ptr->current_fbo = m_renderFbo->handle();
- }
-}
-
-bool QGLPixmapData::useFramebufferObjects() const
-{
-#ifdef Q_OS_SYMBIAN
- // We don't want to use FBOs on Symbian
- return false;
-#else
- return QGLFramebufferObject::hasOpenGLFramebufferObjects()
- && QGLFramebufferObject::hasOpenGLFramebufferBlit()
- && qt_gl_preferGL2Engine()
- && (w * h > 32*32); // avoid overhead of FBOs for small pixmaps
-#endif
-}
-
-QPaintEngine* QGLPixmapData::paintEngine() const
-{
- if (!isValid())
- return 0;
-
- if (m_renderFbo)
- return m_engine;
-
- if (useFramebufferObjects()) {
- extern QGLWidget* qt_gl_share_widget();
-
- if (!QGLContext::currentContext())
- qt_gl_share_widget()->makeCurrent();
- QGLShareContextScope ctx(qt_gl_share_widget()->context());
-
- QGLFramebufferObjectFormat format;
- format.setAttachment(QGLFramebufferObject::CombinedDepthStencil);
- format.setSamples(4);
- format.setInternalTextureFormat(GLenum(m_hasAlpha ? GL_RGBA : GL_RGB));
-
- m_renderFbo = qgl_fbo_pool()->acquire(size(), format);
-
- if (m_renderFbo) {
- if (!m_engine)
- m_engine = new QGL2PaintEngineEx;
- return m_engine;
- }
-
- qWarning() << "Failed to create pixmap texture buffer of size " << size() << ", falling back to raster paint engine";
- }
-
- // If the application wants to paint into the QPixmap, we first
- // force it to QImage format and then paint into that.
- // This is simpler than juggling multiple GL contexts.
- const_cast<QGLPixmapData *>(this)->forceToImage();
-
- if (m_hasFillColor) {
- m_source.fill(PREMUL(m_fillColor.rgba()));
- m_hasFillColor = false;
- }
- return m_source.paintEngine();
-}
-
-extern QRgb qt_gl_convertToGLFormat(QRgb src_pixel, GLenum texture_format);
-
-// If copyBack is true, bind will copy the contents of the render
-// FBO to the texture (which is not bound to the texture, as it's
-// a multisample FBO).
-GLuint QGLPixmapData::bind(bool copyBack) const
-{
- if (m_renderFbo && copyBack) {
- copyBackFromRenderFbo(true);
- } else {
- ensureCreated();
- }
-
- GLuint id = m_texture.id;
- glBindTexture(GL_TEXTURE_2D, id);
-
- if (m_hasFillColor) {
- if (!useFramebufferObjects()) {
- m_source = QVolatileImage(w, h, QImage::Format_ARGB32_Premultiplied);
- m_source.fill(PREMUL(m_fillColor.rgba()));
- }
-
- m_hasFillColor = false;
-
- GLenum format = qt_gl_preferredTextureFormat();
- QImage tx(w, h, QImage::Format_ARGB32_Premultiplied);
- tx.fill(qt_gl_convertToGLFormat(m_fillColor.rgba(), format));
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, format, GL_UNSIGNED_BYTE, tx.constBits());
- }
-
- return id;
-}
-
-QGLTexture* QGLPixmapData::texture() const
-{
- return &m_texture;
-}
-
-void QGLPixmapData::detachTextureFromPool()
-{
- if (inTexturePool) {
- QGLTexturePool::instance()->detachTexture(this);
- inTexturePool = false;
- }
-}
-
-void QGLPixmapData::hibernate()
-{
- // If the image was imported (e.g, from an SgImage under Symbian), then
- // skip the hibernation, there is no sense in copying it back to main
- // memory because the data is most likely shared between several processes.
- bool skipHibernate = (m_texture.id && m_source.isNull());
-#if defined(Q_OS_SYMBIAN)
- // However we have to proceed normally if the image was retrieved via
- // a handle provider.
- skipHibernate &= !nativeImageHandleProvider;
-#endif
- if (skipHibernate)
- return;
-
- forceToImage();
- destroyTexture();
-}
-
-void QGLPixmapData::reclaimTexture()
-{
- if (!inTexturePool)
- return;
- forceToImage();
- destroyTexture();
-}
-
-int QGLPixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const
-{
- if (w == 0)
- return 0;
-
- switch (metric) {
- case QPaintDevice::PdmWidth:
- return w;
- case QPaintDevice::PdmHeight:
- return h;
- case QPaintDevice::PdmNumColors:
- return 0;
- case QPaintDevice::PdmDepth:
- return d;
- case QPaintDevice::PdmWidthMM:
- return qRound(w * 25.4 / qt_defaultDpiX());
- case QPaintDevice::PdmHeightMM:
- return qRound(h * 25.4 / qt_defaultDpiY());
- case QPaintDevice::PdmDpiX:
- case QPaintDevice::PdmPhysicalDpiX:
- return qt_defaultDpiX();
- case QPaintDevice::PdmDpiY:
- case QPaintDevice::PdmPhysicalDpiY:
- return qt_defaultDpiY();
- default:
- qWarning("QGLPixmapData::metric(): Invalid metric");
- return 0;
- }
-}
-
-// Force the pixmap data to be backed by some valid data.
-void QGLPixmapData::forceToImage()
-{
- if (!isValid())
- return;
-
- if (m_source.isNull()) {
- QImage::Format format = QImage::Format_ARGB32_Premultiplied;
- if (pixelType() == BitmapType)
- format = QImage::Format_MonoLSB;
- m_source = QVolatileImage(w, h, format);
- }
-
- m_dirty = true;
-}
-
-QGLPaintDevice *QGLPixmapData::glDevice() const
-{
- return &m_glDevice;
-}
-
-QT_END_NAMESPACE
diff --git a/src/opengl/qpixmapdata_x11gl_egl.cpp b/src/opengl/qpixmapdata_x11gl_egl.cpp
deleted file mode 100644
index 8a8eb38b7c..0000000000
--- a/src/opengl/qpixmapdata_x11gl_egl.cpp
+++ /dev/null
@@ -1,403 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QDebug>
-
-#include <QtGui/private/qt_x11_p.h>
-#include <QtGui/private/qegl_p.h>
-#include <QtGui/private/qeglproperties_p.h>
-#include <QtGui/private/qeglcontext_p.h>
-
-#if !defined(QT_OPENGL_ES_1)
-#include <QtOpenGL/private/qpaintengineex_opengl2_p.h>
-#endif
-
-#ifndef QT_OPENGL_ES_2
-#include <QtOpenGL/private/qpaintengine_opengl_p.h>
-#endif
-
-#include <QtOpenGL/private/qgl_p.h>
-#include <QtOpenGL/private/qgl_egl_p.h>
-
-#include "qpixmapdata_x11gl_p.h"
-
-QT_BEGIN_NAMESPACE
-
-
-class QX11GLSharedContexts
-{
-public:
- QX11GLSharedContexts()
- : rgbContext(0)
- , argbContext(0)
- , sharedQGLContext(0)
- , sharePixmap(0)
- {
- EGLint rgbConfigId;
- EGLint argbConfigId;
-
- do {
- EGLConfig rgbConfig = QEgl::defaultConfig(QInternal::Pixmap, QEgl::OpenGL, QEgl::Renderable);
- EGLConfig argbConfig = QEgl::defaultConfig(QInternal::Pixmap, QEgl::OpenGL,
- QEgl::Renderable | QEgl::Translucent);
-
- eglGetConfigAttrib(QEgl::display(), rgbConfig, EGL_CONFIG_ID, &rgbConfigId);
- eglGetConfigAttrib(QEgl::display(), argbConfig, EGL_CONFIG_ID, &argbConfigId);
-
- rgbContext = new QEglContext;
- rgbContext->setConfig(rgbConfig);
- rgbContext->createContext();
-
- if (!rgbContext->isValid())
- break;
-
- // If the RGB & ARGB configs are the same, use the same egl context for both:
- if (rgbConfig == argbConfig)
- argbContext = rgbContext;
-
- // Otherwise, create a separate context to be used for ARGB pixmaps:
- if (!argbContext) {
- argbContext = new QEglContext;
- argbContext->setConfig(argbConfig);
- bool success = argbContext->createContext(rgbContext);
- if (!success) {
- qWarning("QX11GLPixmapData - RGB & ARGB contexts aren't shared");
- success = argbContext->createContext();
- if (!success)
- argbContext = rgbContext; // Might work, worth a shot at least.
- }
- }
-
- if (!argbContext->isValid())
- break;
-
- // Create the pixmap which will be used to create the egl surface for the share QGLContext
- QX11PixmapData *rgbPixmapData = new QX11PixmapData(QPixmapData::PixmapType);
- rgbPixmapData->resize(8, 8);
- rgbPixmapData->fill(Qt::red);
- sharePixmap = new QPixmap(rgbPixmapData);
- EGLSurface sharePixmapSurface = QEgl::createSurface(sharePixmap, rgbConfig);
- rgbPixmapData->gl_surface = (void*)sharePixmapSurface;
-
- // Create the actual QGLContext which will be used for sharing
- sharedQGLContext = new QGLContext(QX11GLPixmapData::glFormat());
- sharedQGLContext->d_func()->eglContext = rgbContext;
- sharedQGLContext->d_func()->eglSurface = sharePixmapSurface;
- sharedQGLContext->d_func()->valid = true;
- qt_glformat_from_eglconfig(sharedQGLContext->d_func()->glFormat, rgbConfig);
-
-
- valid = rgbContext->makeCurrent(sharePixmapSurface);
-
- // If the ARGB & RGB configs are different, check ARGB works too:
- if (argbConfig != rgbConfig) {
- QX11PixmapData *argbPixmapData = new QX11PixmapData(QPixmapData::PixmapType);
- argbPixmapData->resize(8, 8);
- argbPixmapData->fill(Qt::transparent); // Force ARGB
- QPixmap argbPixmap(argbPixmapData); // destroys pixmap data when goes out of scope
- EGLSurface argbPixmapSurface = QEgl::createSurface(&argbPixmap, argbConfig);
- valid = argbContext->makeCurrent(argbPixmapSurface);
- argbContext->doneCurrent();
- eglDestroySurface(QEgl::display(), argbPixmapSurface);
- argbPixmapData->gl_surface = 0;
- }
-
- if (!valid) {
- qWarning() << "Unable to make pixmap surface current:" << QEgl::errorString();
- break;
- }
-
- // The pixmap surface destruction hooks are installed by QGLTextureCache, so we
- // must make sure this is instanciated:
- QGLTextureCache::instance();
- } while(0);
-
- if (!valid)
- cleanup();
- else
- qDebug("Using QX11GLPixmapData with EGL config %d for ARGB and config %d for RGB", argbConfigId, rgbConfigId);
-
- }
-
- ~QX11GLSharedContexts() {
- cleanup();
- }
-
- void cleanup() {
- if (sharedQGLContext) {
- delete sharedQGLContext;
- sharedQGLContext = 0;
- }
- if (argbContext && argbContext != rgbContext)
- delete argbContext;
- argbContext = 0;
-
- if (rgbContext) {
- delete rgbContext;
- rgbContext = 0;
- }
-
- // Deleting the QPixmap will fire the pixmap destruction cleanup hooks which in turn
- // will destroy the egl surface:
- if (sharePixmap) {
- delete sharePixmap;
- sharePixmap = 0;
- }
- }
-
- bool isValid() { return valid;}
-
- // On 16bpp systems, RGB & ARGB pixmaps are different bit-depths and therefore need
- // different contexts:
- QEglContext *rgbContext;
- QEglContext *argbContext;
-
- // The share context wraps the rgbContext and is used as the master of the context share
- // group. As all other contexts will have the same egl context (or a shared one if rgb != argb)
- // all QGLContexts will actually be sharing and can be in the same context group.
- QGLContext *sharedQGLContext;
-private:
- QPixmap *sharePixmap;
- bool valid;
-};
-
-static void qt_cleanup_x11gl_share_contexts();
-
-Q_GLOBAL_STATIC_WITH_INITIALIZER(QX11GLSharedContexts, qt_x11gl_share_contexts,
- {
- qAddPostRoutine(qt_cleanup_x11gl_share_contexts);
- })
-
-static void qt_cleanup_x11gl_share_contexts()
-{
- qt_x11gl_share_contexts()->cleanup();
-}
-
-
-QX11GLSharedContexts* QX11GLPixmapData::sharedContexts()
-{
- return qt_x11gl_share_contexts();
-}
-
-bool QX11GLPixmapData::hasX11GLPixmaps()
-{
- static bool checkedForX11GLPixmaps = false;
- static bool haveX11GLPixmaps = false;
-
- if (checkedForX11GLPixmaps)
- return haveX11GLPixmaps;
-
- haveX11GLPixmaps = qt_x11gl_share_contexts()->isValid();
- checkedForX11GLPixmaps = true;
-
- return haveX11GLPixmaps;
-}
-
-QX11GLPixmapData::QX11GLPixmapData()
- : QX11PixmapData(QPixmapData::PixmapType),
- ctx(0)
-{
-}
-
-QX11GLPixmapData::~QX11GLPixmapData()
-{
- if (ctx)
- delete ctx;
-}
-
-
-void QX11GLPixmapData::fill(const QColor &color)
-{
- if (ctx) {
- ctx->makeCurrent();
- glFinish();
- eglWaitClient();
- }
-
- QX11PixmapData::fill(color);
- XSync(X11->display, False);
-
- if (ctx) {
- ctx->makeCurrent();
- eglWaitNative(EGL_CORE_NATIVE_ENGINE);
- }
-}
-
-void QX11GLPixmapData::copy(const QPixmapData *data, const QRect &rect)
-{
- if (ctx) {
- ctx->makeCurrent();
- glFinish();
- eglWaitClient();
- }
-
- QX11PixmapData::copy(data, rect);
- XSync(X11->display, False);
-
- if (ctx) {
- ctx->makeCurrent();
- eglWaitNative(EGL_CORE_NATIVE_ENGINE);
- }
-}
-
-bool QX11GLPixmapData::scroll(int dx, int dy, const QRect &rect)
-{
- if (ctx) {
- ctx->makeCurrent();
- glFinish();
- eglWaitClient();
- }
-
- bool success = QX11PixmapData::scroll(dx, dy, rect);
- XSync(X11->display, False);
-
- if (ctx) {
- ctx->makeCurrent();
- eglWaitNative(EGL_CORE_NATIVE_ENGINE);
- }
-
- return success;
-}
-
-#if !defined(QT_OPENGL_ES_1)
-Q_GLOBAL_STATIC(QGL2PaintEngineEx, qt_gl_pixmap_2_engine)
-#endif
-
-#ifndef QT_OPENGL_ES_2
-Q_GLOBAL_STATIC(QOpenGLPaintEngine, qt_gl_pixmap_engine)
-#endif
-
-
-QPaintEngine* QX11GLPixmapData::paintEngine() const
-{
- // We need to create the context before beginPaint - do it here:
- if (!ctx) {
- ctx = new QGLContext(glFormat());
- Q_ASSERT(ctx->d_func()->eglContext == 0);
- ctx->d_func()->eglContext = hasAlphaChannel() ? sharedContexts()->argbContext : sharedContexts()->rgbContext;
-
- // While we use a separate QGLContext for each pixmap, the underlying QEglContext is
- // the same. So we must use a "fake" QGLContext and fool the texture cache into thinking
- // each pixmap's QGLContext is sharing with this central one. The only place this is
- // going to fail is where we the underlying EGL RGB and ARGB contexts aren't sharing.
- ctx->d_func()->sharing = true;
- QGLContextGroup::addShare(ctx, sharedContexts()->sharedQGLContext);
-
- // Update the glFormat for the QGLContext:
- qt_glformat_from_eglconfig(ctx->d_func()->glFormat, ctx->d_func()->eglContext->config());
- }
-
- QPaintEngine* engine;
-
-#if defined(QT_OPENGL_ES_1)
- engine = qt_gl_pixmap_engine();
-#elif defined(QT_OPENGL_ES_2)
- engine = qt_gl_pixmap_2_engine();
-#else
- if (qt_gl_preferGL2Engine())
- engine = qt_gl_pixmap_2_engine();
- else
- engine = qt_gl_pixmap_engine();
-#endif
-
-
-
- // Support multiple painters on multiple pixmaps simultaniously
- if (engine->isActive()) {
- qWarning("Pixmap paint engine already active");
-
-#if defined(QT_OPENGL_ES_1)
- engine = new QOpenGLPaintEngine;
-#elif defined(QT_OPENGL_ES_2)
- engine = new QGL2PaintEngineEx;
-#else
- if (qt_gl_preferGL2Engine())
- engine = new QGL2PaintEngineEx;
- else
- engine = new QOpenGLPaintEngine;
-#endif
-
- engine->setAutoDestruct(true);
- return engine;
- }
-
- return engine;
-}
-
-void QX11GLPixmapData::beginPaint()
-{
-// qDebug("QX11GLPixmapData::beginPaint()");
- // TODO: Check to see if the surface is renderable
- if ((EGLSurface)gl_surface == EGL_NO_SURFACE) {
- QPixmap tmpPixmap(this);
- EGLConfig cfg = ctx->d_func()->eglContext->config();
- Q_ASSERT(cfg != QEGL_NO_CONFIG);
-
-// qDebug("QX11GLPixmapData - using EGL Config ID %d", ctx->d_func()->eglContext->configAttrib(EGL_CONFIG_ID));
- EGLSurface surface = QEgl::createSurface(&tmpPixmap, cfg);
- if (surface == EGL_NO_SURFACE) {
- qWarning() << "Error creating EGL surface for pixmap:" << QEgl::errorString();
- return;
- }
- gl_surface = (void*)surface;
- ctx->d_func()->eglSurface = surface;
- ctx->d_func()->valid = true;
- }
- QGLPaintDevice::beginPaint();
-}
-
-QGLContext* QX11GLPixmapData::context() const
-{
- return ctx;
-}
-
-QSize QX11GLPixmapData::size() const
-{
- return QSize(w, h);
-}
-
-
-QGLFormat QX11GLPixmapData::glFormat()
-{
- return QGLFormat::defaultFormat(); //###
-}
-
-QT_END_NAMESPACE
diff --git a/src/opengl/qpixmapdata_x11gl_p.h b/src/opengl/qpixmapdata_x11gl_p.h
deleted file mode 100644
index 0a6c4e8f2f..0000000000
--- a/src/opengl/qpixmapdata_x11gl_p.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPIXMAPDATA_X11GL_P_H
-#define QPIXMAPDATA_X11GL_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <private/qpixmapdata_p.h>
-#include <private/qpixmap_x11_p.h>
-#include <private/qglpaintdevice_p.h>
-
-#include <qgl.h>
-
-#ifndef QT_NO_EGL
-#include <QtGui/private/qeglcontext_p.h>
-#endif
-
-QT_BEGIN_NAMESPACE
-
-class QX11GLSharedContexts;
-
-class QX11GLPixmapData : public QX11PixmapData, public QGLPaintDevice
-{
-public:
- QX11GLPixmapData();
- virtual ~QX11GLPixmapData();
-
- // Re-implemented from QX11PixmapData:
- void fill(const QColor &color);
- void copy(const QPixmapData *data, const QRect &rect);
- bool scroll(int dx, int dy, const QRect &rect);
-
- // Re-implemented from QGLPaintDevice
- QPaintEngine* paintEngine() const; // Also re-implements QX11PixmapData::paintEngine
- void beginPaint();
- QGLContext* context() const;
- QSize size() const;
-
- static bool hasX11GLPixmaps();
- static QGLFormat glFormat();
- static QX11GLSharedContexts* sharedContexts();
-
-private:
- mutable QGLContext* ctx;
-};
-
-
-QT_END_NAMESPACE
-
-#endif // QPIXMAPDATA_X11GL_P_H
diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp
deleted file mode 100644
index 4f00908b9d..0000000000
--- a/src/opengl/qwindowsurface_gl.cpp
+++ /dev/null
@@ -1,1174 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtGui/QApplication>
-#include <QtGui/QColormap>
-#include <QtGui/QDesktopWidget>
-#include <QtGui/QPaintDevice>
-#include <QtGui/QWidget>
-
-#include <qglframebufferobject.h>
-#include <qglpixelbuffer.h>
-#include <qcolormap.h>
-#include <qdesktopwidget.h>
-#include <private/qwidget_p.h>
-#include "qdebug.h"
-
-#ifdef Q_WS_X11
-#include <private/qt_x11_p.h>
-#include <qx11info_x11.h>
-
-#ifndef QT_OPENGL_ES
-#include <GL/glx.h>
-#include <X11/Xlib.h>
-#endif
-#endif //Q_WS_X11
-
-#include <private/qglextensions_p.h>
-#include <private/qwindowsurface_gl_p.h>
-
-#include <private/qgl_p.h>
-
-#include <private/qglpixelbuffer_p.h>
-#include <private/qgraphicssystem_gl_p.h>
-
-#include <private/qpaintengineex_opengl2_p.h>
-#include <private/qpixmapdata_gl_p.h>
-
-#ifndef QT_OPENGL_ES_2
-#include <private/qpaintengine_opengl_p.h>
-#endif
-
-#ifndef GLX_ARB_multisample
-#define GLX_SAMPLE_BUFFERS_ARB 100000
-#define GLX_SAMPLES_ARB 100001
-#endif
-
-#ifndef QT_NO_EGL
-#include <private/qeglcontext_p.h>
-#endif
-
-QT_BEGIN_NAMESPACE
-
-//
-// QGLGraphicsSystem
-//
-#ifdef Q_WS_WIN
-extern Q_GUI_EXPORT bool qt_win_owndc_required;
-#endif
-QGLGraphicsSystem::QGLGraphicsSystem(bool useX11GL)
- : QGraphicsSystem(), m_useX11GL(useX11GL)
-{
-#if defined(Q_WS_X11) && !defined(QT_OPENGL_ES)
- // only override the system defaults if the user hasn't already
- // picked a visual
- if (X11->visual == 0 && X11->visual_id == -1 && X11->visual_class == -1) {
- // find a double buffered, RGBA visual that supports OpenGL
- // and set that as the default visual for windows in Qt
- int i = 0;
- int spec[16];
- spec[i++] = GLX_RGBA;
- spec[i++] = GLX_DOUBLEBUFFER;
-
- if (!qgetenv("QT_GL_SWAPBUFFER_PRESERVE").isNull()) {
- spec[i++] = GLX_DEPTH_SIZE;
- spec[i++] = 8;
- spec[i++] = GLX_STENCIL_SIZE;
- spec[i++] = 8;
- spec[i++] = GLX_SAMPLE_BUFFERS_ARB;
- spec[i++] = 1;
- spec[i++] = GLX_SAMPLES_ARB;
- spec[i++] = 4;
- }
-
- spec[i++] = XNone;
-
- XVisualInfo *vi = glXChooseVisual(X11->display, X11->defaultScreen, spec);
- if (vi) {
- X11->visual_id = vi->visualid;
- X11->visual_class = vi->c_class;
-
- QGLFormat format;
- int res;
- glXGetConfig(X11->display, vi, GLX_LEVEL, &res);
- format.setPlane(res);
- glXGetConfig(X11->display, vi, GLX_DOUBLEBUFFER, &res);
- format.setDoubleBuffer(res);
- glXGetConfig(X11->display, vi, GLX_DEPTH_SIZE, &res);
- format.setDepth(res);
- if (format.depth())
- format.setDepthBufferSize(res);
- glXGetConfig(X11->display, vi, GLX_RGBA, &res);
- format.setRgba(res);
- glXGetConfig(X11->display, vi, GLX_RED_SIZE, &res);
- format.setRedBufferSize(res);
- glXGetConfig(X11->display, vi, GLX_GREEN_SIZE, &res);
- format.setGreenBufferSize(res);
- glXGetConfig(X11->display, vi, GLX_BLUE_SIZE, &res);
- format.setBlueBufferSize(res);
- glXGetConfig(X11->display, vi, GLX_ALPHA_SIZE, &res);
- format.setAlpha(res);
- if (format.alpha())
- format.setAlphaBufferSize(res);
- glXGetConfig(X11->display, vi, GLX_ACCUM_RED_SIZE, &res);
- format.setAccum(res);
- if (format.accum())
- format.setAccumBufferSize(res);
- glXGetConfig(X11->display, vi, GLX_STENCIL_SIZE, &res);
- format.setStencil(res);
- if (format.stencil())
- format.setStencilBufferSize(res);
- glXGetConfig(X11->display, vi, GLX_STEREO, &res);
- format.setStereo(res);
- glXGetConfig(X11->display, vi, GLX_SAMPLE_BUFFERS_ARB, &res);
- format.setSampleBuffers(res);
- if (format.sampleBuffers()) {
- glXGetConfig(X11->display, vi, GLX_SAMPLES_ARB, &res);
- format.setSamples(res);
- }
-
- QGLWindowSurface::surfaceFormat = format;
- XFree(vi);
-
- printf("using visual class %x, id %x\n", X11->visual_class, X11->visual_id);
- }
- }
-#elif defined(Q_WS_WIN)
- QGLWindowSurface::surfaceFormat.setDoubleBuffer(true);
-
- qt_win_owndc_required = true;
-#endif
-}
-
-static void qt_cleanup_gl_share_widget();
-
-//
-// QGLWindowSurface
-//
-class QGLGlobalShareWidget
-{
-public:
- QGLGlobalShareWidget() : firstPixmap(0), widgetRefCount(0), widget(0), initializing(false) {
- // ### FIXME - readd the post routine if the qApp is recreated
- qAddPostRoutine(qt_cleanup_gl_share_widget);
- created = true;
- }
-
- QGLWidget *shareWidget() {
- if (!initializing && !widget && !cleanedUp) {
- initializing = true;
- widget = new QGLWidget(QGLFormat(QGL::SingleBuffer | QGL::NoDepthBuffer | QGL::NoStencilBuffer));
- widget->resize(1, 1);
-
- // We don't need this internal widget to appear in QApplication::topLevelWidgets()
- if (QWidgetPrivate::allWidgets)
- QWidgetPrivate::allWidgets->remove(widget);
- initializing = false;
- }
- return widget;
- }
-
- // destroys the share widget and prevents recreation
- void cleanup() {
- QGLWidget *w = widget;
- cleanedUp = true;
- widget = 0;
- delete w;
- }
-
- // destroys the share widget, but allows it to be recreated later on
- void destroy() {
- if (cleanedUp)
- return;
-
- QGLWidget *w = widget;
-
- // prevent potential recursions
- cleanedUp = true;
- widget = 0;
- delete w;
- cleanedUp = false;
- }
-
- static bool cleanedUp;
- static bool created;
-
- QGLPixmapData *firstPixmap;
- int widgetRefCount;
-
-private:
- QGLWidget *widget;
- bool initializing;
-};
-
-bool QGLGlobalShareWidget::cleanedUp = false;
-bool QGLGlobalShareWidget::created = false;
-
-Q_GLOBAL_STATIC(QGLGlobalShareWidget, _qt_gl_share_widget)
-
-static void qt_cleanup_gl_share_widget()
-{
- if (QGLGlobalShareWidget::created)
- _qt_gl_share_widget()->cleanup();
-}
-
-QGLWidget* qt_gl_share_widget()
-{
- if (QGLGlobalShareWidget::cleanedUp)
- return 0;
- return _qt_gl_share_widget()->shareWidget();
-}
-
-void qt_destroy_gl_share_widget()
-{
- if (QGLGlobalShareWidget::created)
- _qt_gl_share_widget()->destroy();
-}
-
-const QGLContext *qt_gl_share_context()
-{
- QGLWidget *widget = qt_gl_share_widget();
- if (widget)
- return widget->context();
- return 0;
-}
-
-#ifdef QGL_USE_TEXTURE_POOL
-void qt_gl_register_pixmap(QGLPixmapData *pd)
-{
- QGLGlobalShareWidget *shared = _qt_gl_share_widget();
- pd->next = shared->firstPixmap;
- pd->prev = 0;
- if (shared->firstPixmap)
- shared->firstPixmap->prev = pd;
- shared->firstPixmap = pd;
-}
-
-void qt_gl_unregister_pixmap(QGLPixmapData *pd)
-{
- if (pd->next)
- pd->next->prev = pd->prev;
- if (pd->prev) {
- pd->prev->next = pd->next;
- } else {
- QGLGlobalShareWidget *shared = _qt_gl_share_widget();
- if (shared)
- shared->firstPixmap = pd->next;
- }
-}
-
-void qt_gl_hibernate_pixmaps()
-{
- QGLGlobalShareWidget *shared = _qt_gl_share_widget();
-
- // Scan all QGLPixmapData objects in the system and hibernate them.
- QGLPixmapData *pd = shared->firstPixmap;
- while (pd != 0) {
- pd->hibernate();
- pd = pd->next;
- }
-}
-#endif
-
-struct QGLWindowSurfacePrivate
-{
- QGLFramebufferObject *fbo;
- QGLPixelBuffer *pb;
- GLuint tex_id;
- GLuint pb_tex_id;
-
- int tried_fbo : 1;
- int tried_pb : 1;
- int destructive_swap_buffers : 1;
- int geometry_updated : 1;
- int did_paint : 1;
-
- QGLContext *ctx;
-
- QList<QGLContext **> contexts;
-
- QRegion paintedRegion;
- QSize size;
-
- QSize textureSize;
-
- QList<QImage> buffers;
- QGLWindowSurfaceGLPaintDevice glDevice;
- QGLWindowSurface* q_ptr;
-
- bool swap_region_support;
-};
-
-QGLFormat QGLWindowSurface::surfaceFormat;
-QGLWindowSurface::SwapMode QGLWindowSurface::swapBehavior = QGLWindowSurface::AutomaticSwap;
-
-void QGLWindowSurfaceGLPaintDevice::endPaint()
-{
- glFlush();
- QGLPaintDevice::endPaint();
-}
-
-QSize QGLWindowSurfaceGLPaintDevice::size() const
-{
- return d->size;
-}
-
-QGLContext* QGLWindowSurfaceGLPaintDevice::context() const
-{
- return d->ctx;
-}
-
-
-int QGLWindowSurfaceGLPaintDevice::metric(PaintDeviceMetric m) const
-{
- return qt_paint_device_metric(d->q_ptr->window(), m);
-}
-
-QPaintEngine *QGLWindowSurfaceGLPaintDevice::paintEngine() const
-{
- return qt_qgl_paint_engine();
-}
-
-QGLWindowSurface::QGLWindowSurface(QWidget *window)
- : QWindowSurface(window), d_ptr(new QGLWindowSurfacePrivate)
-{
-// Q_ASSERT(window->isTopLevel());
- d_ptr->pb = 0;
- d_ptr->fbo = 0;
- d_ptr->ctx = 0;
- d_ptr->tex_id = 0;
-#if defined (QT_OPENGL_ES_2)
- d_ptr->tried_fbo = true;
- d_ptr->tried_pb = true;
-#else
- d_ptr->tried_fbo = false;
- d_ptr->tried_pb = false;
-#endif
- d_ptr->destructive_swap_buffers = qgetenv("QT_GL_SWAPBUFFER_PRESERVE").isNull();
- d_ptr->glDevice.d = d_ptr;
- d_ptr->q_ptr = this;
- d_ptr->geometry_updated = false;
- d_ptr->did_paint = false;
- d_ptr->swap_region_support = false;
-}
-
-QGLWindowSurface::~QGLWindowSurface()
-{
- if (d_ptr->ctx)
- glDeleteTextures(1, &d_ptr->tex_id);
-#ifndef Q_WS_QPA // Dont delete the contexts. Destroying the window does that for us
- foreach(QGLContext **ctx, d_ptr->contexts) {
- delete *ctx;
- *ctx = 0;
- }
-#endif
- delete d_ptr->pb;
- delete d_ptr->fbo;
- delete d_ptr;
-
- if (QGLGlobalShareWidget::cleanedUp)
- return;
-
- --(_qt_gl_share_widget()->widgetRefCount);
-
-#ifdef QGL_USE_TEXTURE_POOL
- if (_qt_gl_share_widget()->widgetRefCount <= 0) {
- // All of the widget window surfaces have been destroyed
- // but we still have GL pixmaps active. Ask them to hibernate
- // to free up GPU resources until a widget is shown again.
- // This may eventually cause the EGLContext to be destroyed
- // because nothing in the system needs a context, which will
- // free up even more GPU resources.
- qt_gl_hibernate_pixmaps();
-
- // Destroy the context if necessary.
- if (!qt_gl_share_widget()->context()->isSharing())
- qt_destroy_gl_share_widget();
- }
-#endif // QGL_USE_TEXTURE_POOL
-}
-
-void QGLWindowSurface::deleted(QObject *object)
-{
- QWidget *widget = qobject_cast<QWidget *>(object);
- if (widget) {
- if (widget == window()) {
- // Make sure that the fbo is destroyed before destroying its context.
- delete d_ptr->fbo;
- d_ptr->fbo = 0;
- }
-
-#ifndef Q_WS_QPA //no need to specifically delete the QGLContext as it will be deleted by QWidget
- QWidgetPrivate *widgetPrivate = widget->d_func();
- if (widgetPrivate->extraData()) {
- union { QGLContext **ctxPtrPtr; void **voidPtrPtr; };
- voidPtrPtr = &widgetPrivate->extraData()->glContext;
- int index = d_ptr->contexts.indexOf(ctxPtrPtr);
- if (index != -1) {
- delete *ctxPtrPtr;
- *ctxPtrPtr = 0;
- d_ptr->contexts.removeAt(index);
- }
- }
-#endif
- }
-}
-
-void QGLWindowSurface::hijackWindow(QWidget *widget)
-{
- QWidgetPrivate *widgetPrivate = widget->d_func();
- widgetPrivate->createExtra();
- if (widgetPrivate->extraData()->glContext)
- return;
-
- QGLContext *ctx = NULL;
-
- // For translucent top-level widgets we need alpha in the format.
- if (widget->testAttribute(Qt::WA_TranslucentBackground)) {
- QGLFormat modFormat(surfaceFormat);
- modFormat.setSampleBuffers(false);
- modFormat.setSamples(0);
- modFormat.setAlpha(true);
- ctx = new QGLContext(modFormat, widget);
- } else
- ctx = new QGLContext(surfaceFormat, widget);
-
- ctx->create(qt_gl_share_context());
-
- if (widget != qt_gl_share_widget())
- ++(_qt_gl_share_widget()->widgetRefCount);
-
-#ifndef QT_NO_EGL
- static bool checkedForNOKSwapRegion = false;
- static bool haveNOKSwapRegion = false;
-
- if (!checkedForNOKSwapRegion) {
- haveNOKSwapRegion = QEgl::hasExtension("EGL_NOK_swap_region2");
- checkedForNOKSwapRegion = true;
-
- if (haveNOKSwapRegion)
- qDebug() << "Found EGL_NOK_swap_region2 extension. Using partial updates.";
- }
-
- d_ptr->destructive_swap_buffers = true;
- if (ctx->d_func()->eglContext->configAttrib(EGL_SURFACE_TYPE)&EGL_SWAP_BEHAVIOR_PRESERVED_BIT) {
- EGLint swapBehavior;
- if (eglQuerySurface(ctx->d_func()->eglContext->display(), ctx->d_func()->eglSurface
- , EGL_SWAP_BEHAVIOR, &swapBehavior)) {
- d_ptr->destructive_swap_buffers = (swapBehavior != EGL_BUFFER_PRESERVED);
- }
- }
-
- d_ptr->swap_region_support = haveNOKSwapRegion;
-#endif
-
- widgetPrivate->extraData()->glContext = ctx;
-
- union { QGLContext **ctxPtrPtr; void **voidPtrPtr; };
-
- connect(widget, SIGNAL(destroyed(QObject*)), this, SLOT(deleted(QObject*)));
-
- voidPtrPtr = &widgetPrivate->extraData()->glContext;
- d_ptr->contexts << ctxPtrPtr;
-#ifndef Q_OS_SYMBIAN
- qDebug() << "hijackWindow() context created for" << widget << d_ptr->contexts.size();
-#endif
-}
-
-QGLContext *QGLWindowSurface::context() const
-{
- return d_ptr->ctx;
-}
-
-QPaintDevice *QGLWindowSurface::paintDevice()
-{
- updateGeometry();
-
- if (d_ptr->pb)
- return d_ptr->pb;
-
- if (d_ptr->ctx)
- return &d_ptr->glDevice;
-
- QGLContext *ctx = reinterpret_cast<QGLContext *>(window()->d_func()->extraData()->glContext);
- ctx->makeCurrent();
-
- Q_ASSERT(d_ptr->fbo);
- return d_ptr->fbo;
-}
-
-static void drawTexture(const QRectF &rect, GLuint tex_id, const QSize &texSize, const QRectF &src = QRectF());
-
-void QGLWindowSurface::beginPaint(const QRegion &)
-{
- d_ptr->did_paint = true;
- updateGeometry();
-
- int clearFlags = 0;
-
- QGLContext *ctx = reinterpret_cast<QGLContext *>(window()->d_func()->extraData()->glContext);
-
- if (!ctx)
- return;
-
- if (ctx->d_func()->workaround_needsFullClearOnEveryFrame)
- clearFlags = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
- else if (ctx->format().alpha())
- clearFlags = GL_COLOR_BUFFER_BIT;
-
- if (clearFlags) {
- if (d_ptr->fbo)
- d_ptr->fbo->bind();
-
- glClearColor(0.0, 0.0, 0.0, 0.0);
- glClear(clearFlags);
-
- if (d_ptr->fbo)
- d_ptr->fbo->release();
- }
-}
-
-void QGLWindowSurface::endPaint(const QRegion &rgn)
-{
- if (context())
- d_ptr->paintedRegion |= rgn;
-
- d_ptr->buffers.clear();
-}
-
-static void blitTexture(QGLContext *ctx, GLuint texture, const QSize &viewport, const QSize &texSize, const QRect &targetRect, const QRect &sourceRect)
-{
- glDisable(GL_DEPTH_TEST);
- glDisable(GL_SCISSOR_TEST);
- glDisable(GL_BLEND);
-
- glViewport(0, 0, viewport.width(), viewport.height());
-
- QGLShaderProgram *blitProgram =
- QGLEngineSharedShaders::shadersForContext(ctx)->blitProgram();
- blitProgram->bind();
- blitProgram->setUniformValue("imageTexture", 0 /*QT_IMAGE_TEXTURE_UNIT*/);
-
- // The shader manager's blit program does not multiply the
- // vertices by the pmv matrix, so we need to do the effect
- // of the orthographic projection here ourselves.
- QRectF r;
- qreal w = viewport.width();
- qreal h = viewport.height();
- r.setLeft((targetRect.left() / w) * 2.0f - 1.0f);
- if (targetRect.right() == (viewport.width() - 1))
- r.setRight(1.0f);
- else
- r.setRight((targetRect.right() / w) * 2.0f - 1.0f);
- r.setBottom((targetRect.top() / h) * 2.0f - 1.0f);
- if (targetRect.bottom() == (viewport.height() - 1))
- r.setTop(1.0f);
- else
- r.setTop((targetRect.bottom() / w) * 2.0f - 1.0f);
-
- drawTexture(r, texture, texSize, sourceRect);
-}
-
-
-void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint &offset)
-{
- //### Find out why d_ptr->geometry_updated isn't always false.
- // flush() should not be called when d_ptr->geometry_updated is true. It assumes that either
- // d_ptr->fbo or d_ptr->pb is allocated and has the correct size.
- if (d_ptr->geometry_updated)
- return;
-
- // did_paint is set to true in ::beginPaint. ::beginPaint means that we
- // at least cleared the background (= painted something). In EGL API it's a
- // mistake to call swapBuffers if nothing was painted unless
- // EGL_BUFFER_PRESERVED is set. This check protects the flush func from
- // being executed if it's for nothing.
- if (!d_ptr->destructive_swap_buffers && !d_ptr->did_paint)
- return;
-
-#ifdef Q_OS_SYMBIAN
- if (window() != widget) {
- // For performance reasons we don't support
- // flushing native child widgets on Symbian.
- // It breaks overlapping native child widget
- // rendering in some cases but we prefer performance.
- return;
- }
-#endif
-
-
- QWidget *parent = widget->internalWinId() ? widget : widget->nativeParentWidget();
- Q_ASSERT(parent);
-
-#if !defined(Q_WS_QPA)
- if (!geometry().isValid())
- return;
-#else
- if (!size().isValid())
- return;
-#endif
-
- // Needed to support native child-widgets...
- hijackWindow(parent);
-
- QRect br = rgn.boundingRect().translated(offset);
- br = br.intersected(window()->rect());
- QPoint wOffset = qt_qwidget_data(parent)->wrect.topLeft();
- QRect rect = br.translated(-offset - wOffset);
-
- const GLenum target = GL_TEXTURE_2D;
- Q_UNUSED(target);
-
- if (QGLWindowSurface::swapBehavior == QGLWindowSurface::KillSwap)
- return;
-
- if (context()) {
- context()->makeCurrent();
-
- if (context()->format().doubleBuffer()) {
-#if !defined(QT_OPENGL_ES_2)
- if (d_ptr->destructive_swap_buffers) {
- glBindTexture(target, d_ptr->tex_id);
-
- QVector<QRect> rects = d_ptr->paintedRegion.rects();
- for (int i = 0; i < rects.size(); ++i) {
- QRect br = rects.at(i);
- if (br.isEmpty())
- continue;
-
- const uint bottom = window()->height() - (br.y() + br.height());
- glCopyTexSubImage2D(target, 0, br.x(), bottom, br.x(), bottom, br.width(), br.height());
- }
-
- glBindTexture(target, 0);
-
- QRegion dirtyRegion = QRegion(window()->rect()) - d_ptr->paintedRegion;
-
- if (!dirtyRegion.isEmpty()) {
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
-
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
-#ifndef QT_OPENGL_ES
- glOrtho(0, window()->width(), window()->height(), 0, -999999, 999999);
-#else
- glOrthof(0, window()->width(), window()->height(), 0, -999999, 999999);
-#endif
- glViewport(0, 0, window()->width(), window()->height());
-
- QVector<QRect> rects = dirtyRegion.rects();
- glColor4f(1, 1, 1, 1);
- for (int i = 0; i < rects.size(); ++i) {
- QRect rect = rects.at(i);
- if (rect.isEmpty())
- continue;
-
- drawTexture(rect, d_ptr->tex_id, window()->size(), rect);
- }
- }
- }
-#endif
- bool doingPartialUpdate = false;
- if (d_ptr->swap_region_support) {
- if (QGLWindowSurface::swapBehavior == QGLWindowSurface::AutomaticSwap)
- doingPartialUpdate = br.width() * br.height() < parent->geometry().width() * parent->geometry().height() * 0.2;
- else if (QGLWindowSurface::swapBehavior == QGLWindowSurface::AlwaysPartialSwap)
- doingPartialUpdate = true;
- }
-
- QGLContext *ctx = reinterpret_cast<QGLContext *>(parent->d_func()->extraData()->glContext);
- if (widget != window()) {
- if (initializeOffscreenTexture(window()->size()))
- qWarning() << "QGLWindowSurface: Flushing to native child widget, may lead to significant performance loss";
- glBindTexture(target, d_ptr->tex_id);
-
- const uint bottom = window()->height() - (br.y() + br.height());
- glCopyTexSubImage2D(target, 0, br.x(), bottom, br.x(), bottom, br.width(), br.height());
-
- glBindTexture(target, 0);
-
- ctx->makeCurrent();
- if (doingPartialUpdate)
- blitTexture(ctx, d_ptr->tex_id, parent->size(), window()->size(), rect, br);
- else
- blitTexture(ctx, d_ptr->tex_id, parent->size(), window()->size(), parent->rect(), parent->rect().translated(offset + wOffset));
- }
-
- if (doingPartialUpdate)
- ctx->d_func()->swapRegion(br);
- else
- ctx->swapBuffers();
-
- d_ptr->paintedRegion = QRegion();
- } else {
- glFlush();
- }
- return;
- }
-
- QGLContext *previous_ctx = const_cast<QGLContext *>(QGLContext::currentContext());
- QGLContext *ctx = reinterpret_cast<QGLContext *>(parent->d_func()->extraData()->glContext);
-
- // QPainter::end() should have unbound the fbo, otherwise something is very wrong...
- Q_ASSERT(!d_ptr->fbo || !d_ptr->fbo->isBound());
-
- if (ctx != previous_ctx) {
- ctx->makeCurrent();
- }
-
- QSize size = widget->rect().size();
- if (d_ptr->destructive_swap_buffers && ctx->format().doubleBuffer()) {
- rect = parent->rect();
- br = rect.translated(wOffset + offset);
- size = parent->size();
- }
-
- glDisable(GL_SCISSOR_TEST);
-
- if (d_ptr->fbo && (QGLExtensions::glExtensions() & QGLExtensions::FramebufferBlit)) {
- const int h = d_ptr->fbo->height();
-
- const int sx0 = br.left();
- const int sx1 = br.left() + br.width();
- const int sy0 = h - (br.top() + br.height());
- const int sy1 = h - br.top();
-
- const int tx0 = rect.left();
- const int tx1 = rect.left() + rect.width();
- const int ty0 = parent->height() - (rect.top() + rect.height());
- const int ty1 = parent->height() - rect.top();
-
- if (window() == parent || d_ptr->fbo->format().samples() <= 1) {
- if (ctx->d_ptr->current_fbo != 0)
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, 0);
-
- glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, d_ptr->fbo->handle());
-
- glBlitFramebufferEXT(sx0, sy0, sx1, sy1,
- tx0, ty0, tx1, ty1,
- GL_COLOR_BUFFER_BIT,
- GL_NEAREST);
-
- glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, 0);
- } else {
- // can't do sub-region blits with multisample FBOs
- QGLFramebufferObject *temp = qgl_fbo_pool()->acquire(d_ptr->fbo->size(), QGLFramebufferObjectFormat());
-
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, temp->handle());
- glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, d_ptr->fbo->handle());
-
- glBlitFramebufferEXT(0, 0, d_ptr->fbo->width(), d_ptr->fbo->height(),
- 0, 0, d_ptr->fbo->width(), d_ptr->fbo->height(),
- GL_COLOR_BUFFER_BIT,
- GL_NEAREST);
-
- glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, temp->handle());
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, 0);
-
- glBlitFramebufferEXT(sx0, sy0, sx1, sy1,
- tx0, ty0, tx1, ty1,
- GL_COLOR_BUFFER_BIT,
- GL_NEAREST);
-
- glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, 0);
-
- qgl_fbo_pool()->release(temp);
- }
-
- ctx->d_ptr->current_fbo = 0;
- }
-#if !defined(QT_OPENGL_ES_2)
- else {
- GLuint texture;
- if (d_ptr->fbo) {
- texture = d_ptr->fbo->texture();
- } else {
- d_ptr->pb->makeCurrent();
- glBindTexture(target, d_ptr->pb_tex_id);
- const uint bottom = window()->height() - (br.y() + br.height());
- glCopyTexSubImage2D(target, 0, br.x(), bottom, br.x(), bottom, br.width(), br.height());
- texture = d_ptr->pb_tex_id;
- glBindTexture(target, 0);
- }
-
- glDisable(GL_DEPTH_TEST);
-
- if (d_ptr->fbo) {
- d_ptr->fbo->release();
- } else {
- ctx->makeCurrent();
- }
-
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
-
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
-#ifndef QT_OPENGL_ES
- glOrtho(0, size.width(), size.height(), 0, -999999, 999999);
-#else
- glOrthof(0, size.width(), size.height(), 0, -999999, 999999);
-#endif
- glViewport(0, 0, size.width(), size.height());
-
- glColor4f(1, 1, 1, 1);
- drawTexture(rect, texture, window()->size(), br);
-
- if (d_ptr->fbo)
- d_ptr->fbo->bind();
- }
-#else
- // OpenGL/ES 2.0 version of the fbo blit.
- else if (d_ptr->fbo) {
- Q_UNUSED(target);
-
- if (d_ptr->fbo->isBound())
- d_ptr->fbo->release();
-
- blitTexture(ctx, d_ptr->fbo->texture(), size, window()->size(), rect, br);
- }
-#endif
-
- if (ctx->format().doubleBuffer())
- ctx->swapBuffers();
- else
- glFlush();
-
- d_ptr->did_paint = false;
-}
-
-
-#if !defined(Q_WS_QPA)
-void QGLWindowSurface::setGeometry(const QRect &rect)
-{
- QWindowSurface::setGeometry(rect);
- d_ptr->geometry_updated = true;
-}
-#else
-void QGLWindowSurface::resize(const QSize &size)
-{
- QWindowSurface::resize(size);
- d_ptr->geometry_updated = true;
-}
-#endif
-
-void QGLWindowSurface::updateGeometry() {
- if (!d_ptr->geometry_updated)
- return;
- d_ptr->geometry_updated = false;
-
- bool hijack(true);
- QWidgetPrivate *wd = window()->d_func();
- if (wd->extraData() && wd->extraData()->glContext) {
-#ifdef Q_OS_SYMBIAN // Symbian needs to recreate the context when native window size changes
- if (d_ptr->size != geometry().size()) {
- if (window() != qt_gl_share_widget())
- --(_qt_gl_share_widget()->widgetRefCount);
-
- delete wd->extraData()->glContext;
- wd->extraData()->glContext = 0;
- d_ptr->ctx = 0;
- }
- else
-#endif
- {
- hijack = false; // we already have gl context for widget
- }
- }
-
- if (hijack)
- hijackWindow(window());
-
- QGLContext *ctx = reinterpret_cast<QGLContext *>(wd->extraData()->glContext);
-
-#ifdef Q_WS_MAC
- ctx->updatePaintDevice();
-#endif
-
- QSize surfSize = geometry().size();
-
- if (surfSize.width() <= 0 || surfSize.height() <= 0)
- return;
-
- if (d_ptr->size == surfSize)
- return;
-
- d_ptr->size = surfSize;
-
- if (d_ptr->ctx) {
-#ifndef QT_OPENGL_ES_2
- if (d_ptr->destructive_swap_buffers)
- initializeOffscreenTexture(surfSize);
-#endif
- return;
- }
-
- const GLenum target = GL_TEXTURE_2D;
- if (d_ptr->destructive_swap_buffers
- && (QGLExtensions::glExtensions() & QGLExtensions::FramebufferObject)
- && (d_ptr->fbo || !d_ptr->tried_fbo)
- && qt_gl_preferGL2Engine())
- {
- d_ptr->tried_fbo = true;
- ctx->d_ptr->internal_context = true;
- ctx->makeCurrent();
- delete d_ptr->fbo;
-
- QGLFramebufferObjectFormat format;
- format.setAttachment(QGLFramebufferObject::CombinedDepthStencil);
- format.setInternalTextureFormat(GLenum(GL_RGBA));
- format.setTextureTarget(target);
-
- if (QGLExtensions::glExtensions() & QGLExtensions::FramebufferBlit)
- format.setSamples(8);
-
- d_ptr->fbo = new QGLFramebufferObject(surfSize, format);
-
- if (d_ptr->fbo->isValid()) {
- qDebug() << "Created Window Surface FBO" << surfSize
- << "with samples" << d_ptr->fbo->format().samples();
- return;
- } else {
- qDebug() << "QGLWindowSurface: Failed to create valid FBO, falling back";
- delete d_ptr->fbo;
- d_ptr->fbo = 0;
- }
- }
-
-#if !defined(QT_OPENGL_ES_2) && !defined(Q_WS_QPA) //QPA doesn't support pixelbuffers
- if (d_ptr->destructive_swap_buffers && (d_ptr->pb || !d_ptr->tried_pb)) {
- d_ptr->tried_pb = true;
-
- if (d_ptr->pb) {
- d_ptr->pb->makeCurrent();
- glDeleteTextures(1, &d_ptr->pb_tex_id);
- }
-
- delete d_ptr->pb;
-
- d_ptr->pb = new QGLPixelBuffer(surfSize.width(), surfSize.height(),
- QGLFormat(QGL::SampleBuffers | QGL::StencilBuffer | QGL::DepthBuffer),
- qt_gl_share_widget());
-
- if (d_ptr->pb->isValid()) {
- qDebug() << "Created Window Surface Pixelbuffer, Sample buffers:" << d_ptr->pb->format().sampleBuffers();
- d_ptr->pb->makeCurrent();
-
- glGenTextures(1, &d_ptr->pb_tex_id);
- glBindTexture(target, d_ptr->pb_tex_id);
- glTexImage2D(target, 0, GL_RGBA, surfSize.width(), surfSize.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
-
- glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glBindTexture(target, 0);
-
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(0, d_ptr->pb->width(), d_ptr->pb->height(), 0, -999999, 999999);
-
- d_ptr->pb->d_ptr->qctx->d_func()->internal_context = true;
- return;
- } else {
- qDebug() << "QGLWindowSurface: Failed to create valid pixelbuffer, falling back";
- delete d_ptr->pb;
- d_ptr->pb = 0;
- }
- }
-#endif // !defined(QT_OPENGL_ES_2) !defined(Q_WS_QPA)
-
- ctx->makeCurrent();
-
-#ifndef QT_OPENGL_ES_2
- if (d_ptr->destructive_swap_buffers)
- initializeOffscreenTexture(surfSize);
-#endif
-#ifndef Q_OS_SYMBIAN
- qDebug() << "QGLWindowSurface: Using plain widget as window surface" << this;
-#endif
- d_ptr->ctx = ctx;
- d_ptr->ctx->d_ptr->internal_context = true;
-}
-
-bool QGLWindowSurface::initializeOffscreenTexture(const QSize &size)
-{
- if (size == d_ptr->textureSize)
- return false;
-
- glGenTextures(1, &d_ptr->tex_id);
- glBindTexture(GL_TEXTURE_2D, d_ptr->tex_id);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, size.width(), size.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
-
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glBindTexture(GL_TEXTURE_2D, 0);
-
- d_ptr->textureSize = size;
- return true;
-}
-
-bool QGLWindowSurface::scroll(const QRegion &area, int dx, int dy)
-{
- // this code randomly fails currently for unknown reasons
- return false;
-
- if (!d_ptr->pb)
- return false;
-
- d_ptr->pb->makeCurrent();
-
- QRect br = area.boundingRect();
-
-#if 0
- // ## workaround driver issue (scrolling by these deltas is unbearably slow for some reason)
- // ## maybe we should use glCopyTexSubImage insteadk
- if (dx == 1 || dx == -1 || dy == 1 || dy == -1 || dy == 2)
- return false;
-
- glRasterPos2i(br.x() + dx, br.y() + br.height() + dy);
- glCopyPixels(br.x(), d_ptr->pb->height() - (br.y() + br.height()), br.width(), br.height(), GL_COLOR);
- return true;
-#endif
-
- const GLenum target = GL_TEXTURE_2D;
-
- glBindTexture(target, d_ptr->tex_id);
- glCopyTexImage2D(target, 0, GL_RGBA, br.x(), d_ptr->pb->height() - (br.y() + br.height()), br.width(), br.height(), 0);
- glBindTexture(target, 0);
-
- drawTexture(br.translated(dx, dy), d_ptr->tex_id, window()->size());
-
- return true;
-}
-
-static void drawTexture(const QRectF &rect, GLuint tex_id, const QSize &texSize, const QRectF &br)
-{
- const GLenum target = GL_TEXTURE_2D;
- QRectF src = br.isEmpty()
- ? QRectF(QPointF(), texSize)
- : QRectF(QPointF(br.x(), texSize.height() - br.bottom()), br.size());
-
- if (target == GL_TEXTURE_2D) {
- qreal width = texSize.width();
- qreal height = texSize.height();
-
- src.setLeft(src.left() / width);
- src.setRight(src.right() / width);
- src.setTop(src.top() / height);
- src.setBottom(src.bottom() / height);
- }
-
- const GLfloat tx1 = src.left();
- const GLfloat tx2 = src.right();
- const GLfloat ty1 = src.top();
- const GLfloat ty2 = src.bottom();
-
- GLfloat texCoordArray[4*2] = {
- tx1, ty2, tx2, ty2, tx2, ty1, tx1, ty1
- };
-
- GLfloat vertexArray[4*2];
- extern void qt_add_rect_to_array(const QRectF &r, GLfloat *array); // qpaintengine_opengl.cpp
- qt_add_rect_to_array(rect, vertexArray);
-
-#if !defined(QT_OPENGL_ES_2)
- glVertexPointer(2, GL_FLOAT, 0, vertexArray);
- glTexCoordPointer(2, GL_FLOAT, 0, texCoordArray);
-
- glBindTexture(target, tex_id);
- glEnable(target);
-
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-
- glDisable(target);
- glBindTexture(target, 0);
-#else
- glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, vertexArray);
- glVertexAttribPointer(QT_TEXTURE_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, texCoordArray);
-
- glBindTexture(target, tex_id);
-
- glEnableVertexAttribArray(QT_VERTEX_COORDS_ATTR);
- glEnableVertexAttribArray(QT_TEXTURE_COORDS_ATTR);
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- glDisableVertexAttribArray(QT_VERTEX_COORDS_ATTR);
- glDisableVertexAttribArray(QT_TEXTURE_COORDS_ATTR);
-
- glBindTexture(target, 0);
-#endif
-}
-
-QImage *QGLWindowSurface::buffer(const QWidget *widget)
-{
- QImage image;
-
- if (d_ptr->pb)
- image = d_ptr->pb->toImage();
- else if (d_ptr->fbo)
- image = d_ptr->fbo->toImage();
-
- if (image.isNull())
- return 0;
-
- QRect rect = widget->rect();
- rect.translate(widget->mapTo(widget->window(), QPoint()));
-
- QImage subImage = image.copy(rect);
- d_ptr->buffers << subImage;
- return &d_ptr->buffers.last();
-}
-
-QWindowSurface::WindowSurfaceFeatures QGLWindowSurface::features() const
-{
- WindowSurfaceFeatures features = 0;
- if (!d_ptr->destructive_swap_buffers || d_ptr->swap_region_support)
- features |= PartialUpdates;
- if (!d_ptr->destructive_swap_buffers)
- features |= PreservedContents;
- return features;
-}
-
-QT_END_NAMESPACE
-
diff --git a/src/opengl/qwindowsurface_gl_p.h b/src/opengl/qwindowsurface_gl_p.h
deleted file mode 100644
index 91d1f9e245..0000000000
--- a/src/opengl/qwindowsurface_gl_p.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWINDOWSURFACE_GL_P_H
-#define QWINDOWSURFACE_GL_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of the QLibrary class. This header file may change from
-// version to version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <qglobal.h>
-#include <qgl.h>
-#include <private/qwindowsurface_p.h>
-#include <private/qglpaintdevice_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QPaintDevice;
-class QPoint;
-class QRegion;
-class QWidget;
-struct QGLWindowSurfacePrivate;
-
-Q_OPENGL_EXPORT QGLWidget* qt_gl_share_widget();
-Q_OPENGL_EXPORT void qt_destroy_gl_share_widget();
-
-class QGLWindowSurfaceGLPaintDevice : public QGLPaintDevice
-{
-public:
- QPaintEngine* paintEngine() const;
- void endPaint();
- QSize size() const;
- int metric(PaintDeviceMetric m) const;
- QGLContext* context() const;
- QGLWindowSurfacePrivate* d;
-};
-
-class Q_OPENGL_EXPORT QGLWindowSurface : public QObject, public QWindowSurface // , public QPaintDevice
-{
- Q_OBJECT
-public:
- QGLWindowSurface(QWidget *window);
- ~QGLWindowSurface();
-
- QPaintDevice *paintDevice();
- void flush(QWidget *widget, const QRegion &region, const QPoint &offset);
-
-#if !defined(Q_WS_QPA)
- void setGeometry(const QRect &rect);
-#else
- virtual void resize(const QSize &size);
-#endif
-
- void updateGeometry();
- bool scroll(const QRegion &area, int dx, int dy);
-
- void beginPaint(const QRegion &region);
- void endPaint(const QRegion &region);
-
- QImage *buffer(const QWidget *widget);
-
- WindowSurfaceFeatures features() const;
-
- QGLContext *context() const;
-
- static QGLFormat surfaceFormat;
-
- enum SwapMode { AutomaticSwap, AlwaysFullSwap, AlwaysPartialSwap, KillSwap };
- static SwapMode swapBehavior;
-
-private slots:
- void deleted(QObject *object);
-
-private:
- void hijackWindow(QWidget *widget);
- bool initializeOffscreenTexture(const QSize &size);
-
- QGLWindowSurfacePrivate *d_ptr;
-};
-
-QT_END_NAMESPACE
-
-#endif // QWINDOWSURFACE_GL_P_H
-
diff --git a/src/opengl/qwindowsurface_x11gl.cpp b/src/opengl/qwindowsurface_x11gl.cpp
deleted file mode 100644
index bec0ea7587..0000000000
--- a/src/opengl/qwindowsurface_x11gl.cpp
+++ /dev/null
@@ -1,213 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QTime>
-#include <QDebug>
-
-#include <private/qt_x11_p.h>
-#include <private/qimagepixmapcleanuphooks_p.h>
-
-#include "qwindowsurface_x11gl_p.h"
-#include "qpixmapdata_x11gl_p.h"
-
-QT_BEGIN_NAMESPACE
-
-QX11GLWindowSurface::QX11GLWindowSurface(QWidget* window)
- : QWindowSurface(window), m_windowGC(0), m_pixmapGC(0), m_window(window)
-{
-}
-
-QX11GLWindowSurface::~QX11GLWindowSurface()
-{
- if (m_windowGC)
- XFree(m_windowGC);
- if (m_pixmapGC)
- XFree(m_pixmapGC);
-}
-
-QPaintDevice *QX11GLWindowSurface::paintDevice()
-{
- return &m_backBuffer;
-}
-
-extern void *qt_getClipRects(const QRegion &r, int &num); // in qpaintengine_x11.cpp
-
-void QX11GLWindowSurface::flush(QWidget *widget, const QRegion &widgetRegion, const QPoint &offset)
-{
- // We don't need to know the widget which initiated the flush. Instead we just use the offset
- // to translate the widgetRegion:
- Q_UNUSED(widget);
-
- if (m_backBuffer.isNull()) {
- qDebug("QX11GLWindowSurface::flush() - backBuffer is null, not flushing anything");
- return;
- }
-
- Q_ASSERT(window()->size() != m_backBuffer.size());
-
- // Wait for all GL rendering to the back buffer pixmap to complete before trying to
- // copy it to the window. We do this by making sure the pixmap's context is current
- // and then call eglWaitClient. The EGL 1.4 spec says eglWaitClient doesn't have to
- // block, just that "All rendering calls...are guaranteed to be executed before native
- // rendering calls". This makes it potentially less expensive than glFinish.
- QGLContext* ctx = static_cast<QX11GLPixmapData*>(m_backBuffer.data_ptr().data())->context();
- if (QGLContext::currentContext() != ctx && ctx && ctx->isValid())
- ctx->makeCurrent();
- eglWaitClient();
-
- if (m_windowGC == 0) {
- XGCValues attribs;
- attribs.graphics_exposures = False;
- m_windowGC = XCreateGC(X11->display, m_window->handle(), GCGraphicsExposures, &attribs);
- }
-
- int rectCount;
- XRectangle *rects = (XRectangle *)qt_getClipRects(widgetRegion, rectCount);
- if (rectCount <= 0)
- return;
-
- XSetClipRectangles(X11->display, m_windowGC, 0, 0, rects, rectCount, YXBanded);
-
- QRect dirtyRect = widgetRegion.boundingRect().translated(-offset);
- XCopyArea(X11->display, m_backBuffer.handle(), m_window->handle(), m_windowGC,
- dirtyRect.x(), dirtyRect.y(), dirtyRect.width(), dirtyRect.height(),
- dirtyRect.x(), dirtyRect.y());
-
- // Make sure the blit of the update from the back buffer to the window completes
- // before allowing rendering to start again to the back buffer. Otherwise the GPU
- // might start rendering to the back buffer again while the blit takes place.
- eglWaitNative(EGL_CORE_NATIVE_ENGINE);
-}
-
-void QX11GLWindowSurface::setGeometry(const QRect &rect)
-{
- if (rect.width() > m_backBuffer.size().width() || rect.height() > m_backBuffer.size().height()) {
- QX11GLPixmapData *pd = new QX11GLPixmapData;
- QSize newSize = rect.size();
- pd->resize(newSize.width(), newSize.height());
- m_backBuffer = QPixmap(pd);
- if (window()->testAttribute(Qt::WA_TranslucentBackground))
- m_backBuffer.fill(Qt::transparent);
- if (m_pixmapGC) {
- XFreeGC(X11->display, m_pixmapGC);
- m_pixmapGC = 0;
- }
- }
-
- QWindowSurface::setGeometry(rect);
-}
-
-bool QX11GLWindowSurface::scroll(const QRegion &area, int dx, int dy)
-{
- if (m_backBuffer.isNull())
- return false;
-
- Q_ASSERT(m_backBuffer.data_ptr()->classId() == QPixmapData::X11Class);
-
- // Make sure all GL rendering is complete before starting the scroll operation:
- QGLContext* ctx = static_cast<QX11GLPixmapData*>(m_backBuffer.data_ptr().data())->context();
- if (QGLContext::currentContext() != ctx && ctx && ctx->isValid())
- ctx->makeCurrent();
- eglWaitClient();
-
- if (!m_pixmapGC)
- m_pixmapGC = XCreateGC(X11->display, m_backBuffer.handle(), 0, 0);
-
- foreach (const QRect& rect, area.rects()) {
- XCopyArea(X11->display, m_backBuffer.handle(), m_backBuffer.handle(), m_pixmapGC,
- rect.x(), rect.y(), rect.width(), rect.height(),
- rect.x()+dx, rect.y()+dy);
- }
-
- // Make sure the scroll operation is complete before allowing GL rendering to resume
- eglWaitNative(EGL_CORE_NATIVE_ENGINE);
-
- return true;
-}
-
-
-QPixmap QX11GLWindowSurface::grabWidget(const QWidget *widget, const QRect& rect) const
-{
- if (!widget || m_backBuffer.isNull())
- return QPixmap();
-
- QRect srcRect;
-
- // make sure the rect is inside the widget & clip to widget's rect
- if (!rect.isEmpty())
- srcRect = rect & widget->rect();
- else
- srcRect = widget->rect();
-
- if (srcRect.isEmpty())
- return QPixmap();
-
- // If it's a child widget we have to translate the coordinates
- if (widget != window())
- srcRect.translate(widget->mapTo(window(), QPoint(0, 0)));
-
- QPixmap::x11SetDefaultScreen(widget->x11Info().screen());
-
- QX11PixmapData *pmd = new QX11PixmapData(QPixmapData::PixmapType);
- pmd->resize(srcRect.width(), srcRect.height());
- QPixmap px(pmd);
-
- GC tmpGc = XCreateGC(X11->display, m_backBuffer.handle(), 0, 0);
-
- // Make sure all GL rendering is complete before copying the window
- QGLContext* ctx = static_cast<QX11GLPixmapData*>(m_backBuffer.pixmapData())->context();
- if (QGLContext::currentContext() != ctx && ctx && ctx->isValid())
- ctx->makeCurrent();
- eglWaitClient();
-
- // Copy srcRect from the backing store to the new pixmap
- XSetGraphicsExposures(X11->display, tmpGc, False);
- XCopyArea(X11->display, m_backBuffer.handle(), px.handle(), tmpGc,
- srcRect.x(), srcRect.y(), srcRect.width(), srcRect.height(), 0, 0);
- XFreeGC(X11->display, tmpGc);
-
- // Wait until the copy has finised before allowing more rendering into the back buffer
- eglWaitNative(EGL_CORE_NATIVE_ENGINE);
-
- return px;
-}
-
-QT_END_NAMESPACE
diff --git a/src/opengl/qwindowsurface_x11gl_p.h b/src/opengl/qwindowsurface_x11gl_p.h
deleted file mode 100644
index 737997b879..0000000000
--- a/src/opengl/qwindowsurface_x11gl_p.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWINDOWSURFACE_X11GL_P_H
-#define QWINDOWSURFACE_X11GL_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <private/qwindowsurface_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QX11GLWindowSurface : public QWindowSurface
-{
-public:
- QX11GLWindowSurface(QWidget* window);
- virtual ~QX11GLWindowSurface();
-
- // Inherreted from QWindowSurface
- QPaintDevice *paintDevice();
- void flush(QWidget *widget, const QRegion &region, const QPoint &offset);
- void setGeometry(const QRect &rect);
- bool scroll(const QRegion &area, int dx, int dy);
- QPixmap grabWidget(const QWidget *widget, const QRect& rectangle = QRect()) const;
-
-private:
- GC m_windowGC;
- GC m_pixmapGC;
- QPixmap m_backBuffer;
- QWidget *m_window;
-};
-
-
-QT_END_NAMESPACE
-
-#endif // QWINDOWSURFACE_X11GL_P_H
diff --git a/src/opengl/util/README-GLSL b/src/opengl/util/README-GLSL
deleted file mode 100644
index ff20eb45b2..0000000000
--- a/src/opengl/util/README-GLSL
+++ /dev/null
@@ -1,18 +0,0 @@
-Use of GLSL for vertex and fragment programs in Qt
----------------------------------------------------
-
-We don't compile the *.glsl files because we don't want the build process of
-Qt to require cgc from nVidia to build the fragment programs.
-
-The script src/opengl/util/glsl_to_include.sh will compile a GLSL program to a file
-that can be included in a C(++) program. The file is the output from cgc
-quoted as a string.
-
-This can be done manually by:
-
-./glsl_to_include.sh radial.glsl
-./glsl_to_include.sh conical.glsl
-
-This will produce the files radial.frag and radial.glsl_quoted.
-(and also conical.frag and conical.glsl_quoted)
-These files are included by qpaintengine_opengl.cpp
diff --git a/src/opengl/util/brush_painter.glsl b/src/opengl/util/brush_painter.glsl
deleted file mode 100644
index 6c4acdf924..0000000000
--- a/src/opengl/util/brush_painter.glsl
+++ /dev/null
@@ -1,7 +0,0 @@
-// fast brush painter for composition modes which can be implemented with blendfuncs
-// no mask, used for fast filling of aliased primitives (or multisampled)
-
-void main()
-{
- gl_FragColor = brush();
-}
diff --git a/src/opengl/util/brushes.conf b/src/opengl/util/brushes.conf
deleted file mode 100644
index 93e2b3b295..0000000000
--- a/src/opengl/util/brushes.conf
+++ /dev/null
@@ -1,6 +0,0 @@
-FRAGMENT_PROGRAM_BRUSH_SOLID solid_brush.glsl
-FRAGMENT_PROGRAM_BRUSH_RADIAL radial_brush.glsl
-FRAGMENT_PROGRAM_BRUSH_CONICAL conical_brush.glsl
-FRAGMENT_PROGRAM_BRUSH_LINEAR linear_brush.glsl
-FRAGMENT_PROGRAM_BRUSH_TEXTURE texture_brush.glsl
-FRAGMENT_PROGRAM_BRUSH_PATTERN pattern_brush.glsl
diff --git a/src/opengl/util/composition_mode_colorburn.glsl b/src/opengl/util/composition_mode_colorburn.glsl
deleted file mode 100644
index c913b9737f..0000000000
--- a/src/opengl/util/composition_mode_colorburn.glsl
+++ /dev/null
@@ -1,13 +0,0 @@
-// Dca' = Sca.Da + Dca.Sa <= Sa.Da ?
-// Sca.(1 - Da) + Dca.(1 - Sa)
-// Sa.(Sca.Da + Dca.Sa - Sa.Da)/Sca + Sca.(1 - Da) + Dca.(1 - Sa)
-// Da' = Sa + Da - Sa.Da
-vec4 composite(vec4 src, vec4 dst)
-{
- vec4 result;
- result.rgb = mix(src.rgb * (1.0 - dst.a) + dst.rgb * (1.0 - src.a),
- src.a * (src.rgb * dst.a + dst.rgb * src.a - src.a * dst.a) / max(src.rgb, 0.00001) + src.rgb * (1.0 - dst.a) + dst.rgb * (1.0 - src.a),
- step(src.a * dst.a, src.rgb * dst.a + dst.rgb * src.a));
- result.a = src.a + dst.a - src.a * dst.a;
- return result;
-}
diff --git a/src/opengl/util/composition_mode_colordodge.glsl b/src/opengl/util/composition_mode_colordodge.glsl
deleted file mode 100644
index b75e83cf4e..0000000000
--- a/src/opengl/util/composition_mode_colordodge.glsl
+++ /dev/null
@@ -1,15 +0,0 @@
-// Dca' = Sca.Da + Dca.Sa <= Sa.Da ?
-// Dca.Sa/(1 - Sca/Sa) + Sca.(1 - Da) + Dca.(1 - Sa) :
-// Sa.Da + Sca.(1 - Da) + Dca.(1 - Sa)
-// Da' = Sa + Da - Sa.Da
-vec4 composite(vec4 src, vec4 dst)
-{
- vec4 result;
- vec3 temp = src.rgb * (1.0 - dst.a) + dst.rgb * (1.0 - src.a);
- result.rgb = mix(dst.rgb * src.a / max(1.0 - src.rgb / max(src.a, 0.000001), 0.000001) + temp,
- src.a * dst.a + temp,
- step(src.a * dst.a, src.rgb * dst.a + dst.rgb * src.a));
-
- result.a = src.a + dst.a - src.a * dst.a;
- return result;
-}
diff --git a/src/opengl/util/composition_mode_darken.glsl b/src/opengl/util/composition_mode_darken.glsl
deleted file mode 100644
index 8bbb82b3ce..0000000000
--- a/src/opengl/util/composition_mode_darken.glsl
+++ /dev/null
@@ -1,9 +0,0 @@
-// Dca' = min(Sca.Da, Dca.Sa) + Sca.(1 - Da) + Dca.(1 - Sa)
-// Da' = Sa + Da - Sa.Da
-vec4 composite(vec4 src, vec4 dst)
-{
- vec4 result;
- result.rgb = min(src.rgb * dst.a, dst.rgb * src.a) + src.rgb * (1.0 - dst.a) + dst.rgb * (1.0 - src.a);
- result.a = src.a + dst.a - src.a * dst.a;
- return result;
-}
diff --git a/src/opengl/util/composition_mode_difference.glsl b/src/opengl/util/composition_mode_difference.glsl
deleted file mode 100644
index 3c46ec71f2..0000000000
--- a/src/opengl/util/composition_mode_difference.glsl
+++ /dev/null
@@ -1,9 +0,0 @@
-// Dca' = Sca + Dca - 2.min(Sca.Da, Dca.Sa)
-// Da' = Sa + Da - Sa.Da
-vec4 composite(vec4 src, vec4 dst)
-{
- vec4 result;
- result.rgb = src.rgb + dst.rgb - 2.0 * min(src.rgb * dst.a, dst.rgb * src.a);
- result.a = src.a + dst.a - src.a * dst.a;
- return result;
-}
diff --git a/src/opengl/util/composition_mode_exclusion.glsl b/src/opengl/util/composition_mode_exclusion.glsl
deleted file mode 100644
index 59c2da99ea..0000000000
--- a/src/opengl/util/composition_mode_exclusion.glsl
+++ /dev/null
@@ -1,9 +0,0 @@
-// Dca' = (Sca.Da + Dca.Sa - 2.Sca.Dca) + Sca.(1 - Da) + Dca.(1 - Sa)
-// Da' = Sa + Da - Sa.Da
-vec4 composite(vec4 src, vec4 dst)
-{
- vec4 result;
- result.rgb = (src.rgb * dst.a + dst.rgb * src.a - 2.0 * src.rgb * dst.rgb) + src.rgb * (1.0 - dst.a) + dst.rgb * (1.0 - src.a);
- result.a = src.a + dst.a - src.a * dst.a;
- return result;
-}
diff --git a/src/opengl/util/composition_mode_hardlight.glsl b/src/opengl/util/composition_mode_hardlight.glsl
deleted file mode 100644
index 4ea355029d..0000000000
--- a/src/opengl/util/composition_mode_hardlight.glsl
+++ /dev/null
@@ -1,14 +0,0 @@
-// Dca' = 2.Sca < Sa ?
-// 2.Sca.Dca + Sca.(1 - Da) + Dca.(1 - Sa) :
-// Sa.Da - 2.(Da - Dca).(Sa - Sca) + Sca.(1 - Da) + Dca.(1 - Sa)
-// Da' = Sa + Da - Sa.Da
-vec4 composite(vec4 src, vec4 dst)
-{
- vec4 result;
- result.rgb = mix(2.0 * src.rgb * dst.rgb + src.rgb * (1.0 - dst.a) + dst.rgb * (1.0 - src.a),
- src.a * dst.a - 2.0 * (dst.a - dst.rgb) * (src.a - src.rgb) + src.rgb * (1.0 - dst.a) + dst.rgb * (1.0 - src.a),
- step(src.a, 2.0 * src.rgb));
- result.a = src.a + dst.a - src.a * dst.a;
-
- return result;
-}
diff --git a/src/opengl/util/composition_mode_lighten.glsl b/src/opengl/util/composition_mode_lighten.glsl
deleted file mode 100644
index 13ef507a4c..0000000000
--- a/src/opengl/util/composition_mode_lighten.glsl
+++ /dev/null
@@ -1,9 +0,0 @@
-// Dca' = max(Sca.Da, Dca.Sa) + Sca.(1 - Da) + Dca.(1 - Sa)
-// Da' = Sa + Da - Sa.Da
-vec4 composite(vec4 src, vec4 dst)
-{
- vec4 result;
- result.rgb = max(src.rgb * dst.a, dst.rgb * src.a) + src.rgb * (1.0 - dst.a) + dst.rgb * (1.0 - src.a);
- result.a = src.a + dst.a - src.a * dst.a;
- return result;
-}
diff --git a/src/opengl/util/composition_mode_multiply.glsl b/src/opengl/util/composition_mode_multiply.glsl
deleted file mode 100644
index f90b7f00ad..0000000000
--- a/src/opengl/util/composition_mode_multiply.glsl
+++ /dev/null
@@ -1,9 +0,0 @@
-// Dca' = Sca.Dca + Sca.(1 - Da) + Dca.(1 - Sa)
-// Da' = Sa + Da - Sa.Da
-vec4 composite(vec4 src, vec4 dst)
-{
- vec4 result;
- result.rgb = src.rgb * dst.rgb + src.rgb * (1.0 - dst.a) + dst.rgb * (1.0 - src.a);
- result.a = src.a + dst.a - src.a * dst.a;
- return result;
-}
diff --git a/src/opengl/util/composition_mode_overlay.glsl b/src/opengl/util/composition_mode_overlay.glsl
deleted file mode 100644
index f621bdee96..0000000000
--- a/src/opengl/util/composition_mode_overlay.glsl
+++ /dev/null
@@ -1,13 +0,0 @@
-// Dca' = 2.Dca < Da ?
-// 2.Sca.Dca + Sca.(1 - Da) + Dca.(1 - Sa)
-// Sa.Da - 2.(Da - Dca).(Sa - Sca) + Sca.(1 - Da) + Dca.(1 - Sa)
-// Da' = Sa + Da - Sa.Da
-vec4 composite(vec4 src, vec4 dst)
-{
- vec4 result;
- result.rgb = mix(2.0 * src.rgb * dst.rgb + src.rgb * (1.0 - dst.a) + dst.rgb * (1.0 - src.a),
- src.a * dst.a - 2.0 * (dst.a - dst.rgb) * (src.a - src.rgb) + src.rgb * (1.0 - dst.a) + dst.rgb * (1.0 - src.a),
- step(dst.a, 2.0 * dst.rgb));
- result.a = src.a + dst.a - src.a * dst.a;
- return result;
-}
diff --git a/src/opengl/util/composition_mode_screen.glsl b/src/opengl/util/composition_mode_screen.glsl
deleted file mode 100644
index 8f4f010032..0000000000
--- a/src/opengl/util/composition_mode_screen.glsl
+++ /dev/null
@@ -1,6 +0,0 @@
-// Dca' = Sca + Dca - Sca.Dca
-// Da' = Sa + Da - Sa.Da
-vec4 composite(vec4 src, vec4 dst)
-{
- return src + dst - src * dst;
-}
diff --git a/src/opengl/util/composition_mode_softlight.glsl b/src/opengl/util/composition_mode_softlight.glsl
deleted file mode 100644
index e4c1f89156..0000000000
--- a/src/opengl/util/composition_mode_softlight.glsl
+++ /dev/null
@@ -1,22 +0,0 @@
-// if 2.Sca <= Sa
-// Dca' = Dca.(Sa + (2.Sca - Sa).(1 - Dca/Da)) + Sca.(1 - Da) + Dca.(1 - Sa)
-// otherwise if 2.Sca > Sa and 4.Dca <= Da
-// Dca' = Dca.Sa + Da.(2.Sca - Sa).(4.Dca/Da.(4.Dca/Da + 1).(Dca/Da - 1) + 7.Dca/Da) + Sca.(1 - Da) + Dca.(1 - Sa)
-// otherwise if 2.Sca > Sa and 4.Dca > Da
-// Dca' = Dca.Sa + Da.(2.Sca - Sa).((Dca/Da)^0.5 - Dca/Da) + Sca.(1 - Da) + Dca.(1 - Sa)
-// Da' = Sa + Da - Sa.Da
-
-vec4 composite(vec4 src, vec4 dst)
-{
- vec4 result;
- float da = max(dst.a, 0.00001);
- vec3 dst_np = dst.rgb / da;
- result.rgb = mix(dst.rgb * (src.a + (2.0 * src.rgb - src.a) * (1.0 - dst_np)),
- mix(dst.rgb * src.a + dst.a * (2.0 * src.rgb - src.a) * ((16.0 * dst_np - 12.0) * dst_np + 3.0) * dst_np,
- dst.rgb * src.a + dst.a * (2.0 * src.rgb - src.a) * (sqrt(dst_np) - dst_np),
- step(dst.a, 4.0 * dst.rgb)),
- step(src.a, 2.0 * src.rgb))
- + src.rgb * (1.0 - dst.a) + dst.rgb * (1.0 - src.a);
- result.a = src.a + dst.a - src.a * dst.a;
- return result;
-}
diff --git a/src/opengl/util/composition_modes.conf b/src/opengl/util/composition_modes.conf
deleted file mode 100644
index df52830b99..0000000000
--- a/src/opengl/util/composition_modes.conf
+++ /dev/null
@@ -1,12 +0,0 @@
-COMPOSITION_MODES_SIMPLE_PORTER_DUFF simple_porter_duff.glsl
-COMPOSITION_MODES_MULTIPLY composition_mode_multiply.glsl
-COMPOSITION_MODES_SCREEN composition_mode_screen.glsl
-COMPOSITION_MODES_OVERLAY composition_mode_overlay.glsl
-COMPOSITION_MODES_DARKEN composition_mode_darken.glsl
-COMPOSITION_MODES_LIGHTEN composition_mode_lighten.glsl
-COMPOSITION_MODES_COLORDODGE composition_mode_colordodge.glsl
-COMPOSITION_MODES_COLORBURN composition_mode_colorburn.glsl
-COMPOSITION_MODES_HARDLIGHT composition_mode_hardlight.glsl
-COMPOSITION_MODES_SOFTLIGHT composition_mode_softlight.glsl
-COMPOSITION_MODES_DIFFERENCE composition_mode_difference.glsl
-COMPOSITION_MODES_EXCLUSION composition_mode_exclusion.glsl
diff --git a/src/opengl/util/conical_brush.glsl b/src/opengl/util/conical_brush.glsl
deleted file mode 100644
index b3ec1d7efe..0000000000
--- a/src/opengl/util/conical_brush.glsl
+++ /dev/null
@@ -1,27 +0,0 @@
-// conical gradient shader
-#define M_PI 3.14159265358979323846
-uniform sampler1D palette;
-uniform float angle;
-uniform vec3 inv_matrix_m0;
-uniform vec3 inv_matrix_m1;
-uniform vec3 inv_matrix_m2;
-
-vec4 brush()
-{
- mat3 mat;
-
- mat[0] = inv_matrix_m0;
- mat[1] = inv_matrix_m1;
- mat[2] = inv_matrix_m2;
-
- vec3 hcoords = mat * vec3(gl_FragCoord.xy, 1);
- vec2 A = hcoords.xy / hcoords.z;
-
-/* float val = fmod((atan2(-A.y, A.x) + angle) / (2.0 * M_PI), 1); */
- if (abs(A.y) == abs(A.x))
- A.y += 0.002;
- float t = (atan(-A.y, A.x) + angle) / (2.0 * M_PI);
- float val = t - floor(t);
- return texture1D(palette, val);
-}
-
diff --git a/src/opengl/util/ellipse_aa.glsl b/src/opengl/util/ellipse_aa.glsl
deleted file mode 100644
index 257e3bbd47..0000000000
--- a/src/opengl/util/ellipse_aa.glsl
+++ /dev/null
@@ -1,58 +0,0 @@
-uniform vec3 inv_matrix_m0;
-uniform vec3 inv_matrix_m1;
-uniform vec3 inv_matrix_m2;
-
-uniform vec2 ellipse_offset;
-
-// ellipse equation
-
-// s^2/a^2 + t^2/b^2 = 1
-//
-// implicit equation:
-// g(s,t) = 1 - s^2/r_s^2 - t^2/r_t^2
-
-// distance from ellipse:
-// grad = [dg/dx dg/dy]
-// d(s, t) ~= g(s, t) / |grad|
-
-// dg/dx = dg/ds * ds/dx + dg/dt * dt/dx
-// dg/dy = dg/ds * ds/dy + dg/dt * dt/dy
-
-float ellipse_aa()
-{
- mat3 mat;
-
- mat[0] = inv_matrix_m0;
- mat[1] = inv_matrix_m1;
- mat[2] = inv_matrix_m2;
-
- vec3 hcoords = mat * vec3(gl_FragCoord.xy + ellipse_offset, 1);
- float inv_w = 1.0 / hcoords.z;
- vec2 st = hcoords.xy * inv_w;
-
- vec4 xy = vec4(mat[0].xy, mat[1].xy);
- vec2 h = vec2(mat[0].z, mat[1].z);
-
- vec4 dstdxy = (xy.xzyw - h.xyxy * st.xxyy) * inv_w;
-
- //dstdxy.x = (mat[0].x - mat[0].z * st.x) * inv_w; // ds/dx
- //dstdxy.y = (mat[1].x - mat[1].z * st.x) * inv_w; // ds/dy
- //dstdxy.z = (mat[0].y - mat[0].z * st.y) * inv_w; // dt/dx
- //dstdxy.w = (mat[1].y - mat[1].z * st.y) * inv_w; // dt/dy
-
- vec2 inv_r = gl_TexCoord[0].xy;
- vec2 n = st * inv_r;
- float g = 1.0 - dot(n, n);
-
- vec2 dgdst = -2.0 * n * inv_r;
-
- vec2 grad = vec2(dot(dgdst, dstdxy.xz),
- dot(dgdst, dstdxy.yw));
-
- return smoothstep(-0.5, 0.5, g * inversesqrt(dot(grad, grad)));
-}
-
-void main()
-{
- gl_FragColor = ellipse_aa().xxxx;
-}
diff --git a/src/opengl/util/fast_painter.glsl b/src/opengl/util/fast_painter.glsl
deleted file mode 100644
index 63f5e5f3be..0000000000
--- a/src/opengl/util/fast_painter.glsl
+++ /dev/null
@@ -1,19 +0,0 @@
-// fast painter for composition modes which can be implemented with blendfuncs
-
-uniform sampler2D mask_texture;
-uniform vec2 inv_mask_size;
-uniform vec2 mask_offset;
-uniform vec4 mask_channel;
-
-float mask()
-{
- return dot(mask_channel, texture2D(mask_texture, (gl_FragCoord.xy + mask_offset) * inv_mask_size));
-}
-
-void main()
-{
- // combine clip and coverage channels
- float mask_alpha = mask();
-
- gl_FragColor = brush() * mask_alpha;
-}
diff --git a/src/opengl/util/fragmentprograms_p.h b/src/opengl/util/fragmentprograms_p.h
deleted file mode 100644
index b1a47e3d5f..0000000000
--- a/src/opengl/util/fragmentprograms_p.h
+++ /dev/null
@@ -1,7287 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef FRAGMENTPROGRAMS_P_H
-#define FRAGMENTPROGRAMS_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-enum FragmentVariable {
- VAR_BRUSH_TEXTURE,
- VAR_LINEAR,
- VAR_INV_MATRIX_M1,
- VAR_INV_MASK_SIZE,
- VAR_INV_MATRIX_M2,
- VAR_PORTERDUFF_AB,
- VAR_MASK_CHANNEL,
- VAR_ELLIPSE_OFFSET,
- VAR_PORTERDUFF_XYZ,
- VAR_INV_DST_SIZE,
- VAR_MASK_TEXTURE,
- VAR_DST_TEXTURE,
- VAR_PALETTE,
- VAR_MASK_OFFSET,
- VAR_INV_BRUSH_TEXTURE_SIZE,
- VAR_FMP2_M_RADIUS2,
- VAR_FMP,
- VAR_INV_MATRIX_M0,
- VAR_ANGLE
-};
-
-enum FragmentBrushType {
- FRAGMENT_PROGRAM_BRUSH_SOLID,
- FRAGMENT_PROGRAM_BRUSH_RADIAL,
- FRAGMENT_PROGRAM_BRUSH_CONICAL,
- FRAGMENT_PROGRAM_BRUSH_LINEAR,
- FRAGMENT_PROGRAM_BRUSH_TEXTURE,
- FRAGMENT_PROGRAM_BRUSH_PATTERN
-};
-
-enum FragmentCompositionModeType {
- COMPOSITION_MODES_SIMPLE_PORTER_DUFF,
- COMPOSITION_MODES_MULTIPLY,
- COMPOSITION_MODES_SCREEN,
- COMPOSITION_MODES_OVERLAY,
- COMPOSITION_MODES_DARKEN,
- COMPOSITION_MODES_LIGHTEN,
- COMPOSITION_MODES_COLORDODGE,
- COMPOSITION_MODES_COLORBURN,
- COMPOSITION_MODES_HARDLIGHT,
- COMPOSITION_MODES_SOFTLIGHT,
- COMPOSITION_MODES_DIFFERENCE,
- COMPOSITION_MODES_EXCLUSION,
- COMPOSITION_MODES_SIMPLE_PORTER_DUFF_NOMASK,
- COMPOSITION_MODES_MULTIPLY_NOMASK,
- COMPOSITION_MODES_SCREEN_NOMASK,
- COMPOSITION_MODES_OVERLAY_NOMASK,
- COMPOSITION_MODES_DARKEN_NOMASK,
- COMPOSITION_MODES_LIGHTEN_NOMASK,
- COMPOSITION_MODES_COLORDODGE_NOMASK,
- COMPOSITION_MODES_COLORBURN_NOMASK,
- COMPOSITION_MODES_HARDLIGHT_NOMASK,
- COMPOSITION_MODES_SOFTLIGHT_NOMASK,
- COMPOSITION_MODES_DIFFERENCE_NOMASK,
- COMPOSITION_MODES_EXCLUSION_NOMASK,
- COMPOSITION_MODE_BLEND_MODE_MASK,
- COMPOSITION_MODE_BLEND_MODE_NOMASK
-};
-
-enum FragmentMaskType {
- FRAGMENT_PROGRAM_MASK_TRAPEZOID_AA,
- FRAGMENT_PROGRAM_MASK_ELLIPSE_AA
-};
-
-static const unsigned int num_fragment_variables = 19;
-
-static const unsigned int num_fragment_brushes = 6;
-static const unsigned int num_fragment_composition_modes = 26;
-static const unsigned int num_fragment_masks = 2;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_MASK_TRAPEZOID_AA =
- "!!ARBfp1.0\n"
- "PARAM c[1] = { { 0.5, 2 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "ADD R3.z, fragment.position.x, c[0].x;\n"
- "ADD R0.y, fragment.position, -c[0].x;\n"
- "MAX R4.x, fragment.texcoord[0].y, R0.y;\n"
- "ADD R0.x, fragment.position.y, c[0];\n"
- "MIN R3.w, R0.x, fragment.texcoord[0].x;\n"
- "ADD R2.z, fragment.position.x, -c[0].x;\n"
- "MOV R2.w, R3.z;\n"
- "MOV R0.yw, R4.x;\n"
- "MOV R0.xz, R3.w;\n"
- "MAD R0, fragment.texcoord[1].xxzz, R0, fragment.texcoord[1].yyww;\n"
- "MAD R0.zw, fragment.position.x, c[0].y, -R0;\n"
- "MOV R2.x, R0;\n"
- "MOV R2.y, R0.z;\n"
- "MOV R1.w, R0;\n"
- "MOV R1.z, R0.y;\n"
- "MIN R1.xy, R2, R1.zwzw;\n"
- "SGE R0.xy, R1.zwzw, R2;\n"
- "ADD R0.zw, -fragment.texcoord[0], -fragment.texcoord[0];\n"
- "MAD R3.xy, R0, R0.zwzw, fragment.texcoord[0].zwzw;\n"
- "ADD R0, -R1.xxyy, R2.zwzw;\n"
- "MAD R0, R0, R3.xxyy, R4.x;\n"
- "ADD R3.xy, R0.ywzw, R0.xzzw;\n"
- "ADD R4.zw, R3.w, -R0.xyxz;\n"
- "ADD R0.zw, -R4.x, R0.xyyw;\n"
- "ADD R0.xy, R3.z, -R1;\n"
- "MAX R1.zw, R2.xyxy, R1;\n"
- "MUL R0.xy, R0, R0.zwzw;\n"
- "MAD R3.xy, -R3, c[0].x, R3.w;\n"
- "ADD R2.w, R3.z, -R2.z;\n"
- "MUL R2.xy, R3, R2.w;\n"
- "ADD R2.w, R3, -R4.x;\n"
- "ADD R3.xy, -R2.z, R1.zwzw;\n"
- "MUL R3.xy, R4.zwzw, R3;\n"
- "ADD R4.zw, R1.xyxy, R1;\n"
- "MAD R0.zw, R4, c[0].x, -R2.z;\n"
- "MAD R0.xy, -R0, c[0].x, R2.w;\n"
- "MAD R4.zw, R0, R2.w, -R0.xyxy;\n"
- "SGE R0.zw, R3.z, R1;\n"
- "MAD R0.xy, R0.zwzw, R4.zwzw, R0;\n"
- "MAD R3.xy, R3, c[0].x, -R2;\n"
- "MAD R0.zw, R0, R3.xyxy, R2.xyxy;\n"
- "ADD R2.xy, R0.zwzw, -R0;\n"
- "SGE R0.zw, R2.z, R1.xyxy;\n"
- "MAD R0.xy, R0.zwzw, R2, R0;\n"
- "SGE R0.zw, R1, R2.z;\n"
- "ADD R0.xy, R0, -R2.w;\n"
- "SGE R1.xy, R3.z, R1;\n"
- "MAD R0.xy, R1, R0, R2.w;\n"
- "MAD R0.x, -R0, R0.z, R2.w;\n"
- "SGE R0.z, R3.w, R4.x;\n"
- "MAD R0.x, -R0.y, R0.w, R0;\n"
- "MUL result.color, R0.x, R0.z;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_MASK_ELLIPSE_AA =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..3],\n"
- " { -2, 1, -0.5, 2 },\n"
- " { 3 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "ADD R0.xy, fragment.position, c[3];\n"
- "MUL R1.xyz, R0.y, c[1];\n"
- "MAD R0.xyz, R0.x, c[0], R1;\n"
- "ADD R0.xyz, R0, c[2];\n"
- "RCP R2.z, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R2.z;\n"
- "MUL R2.xy, R0.zwzw, fragment.texcoord[0];\n"
- "MOV R1.xy, c[0];\n"
- "MOV R1.zw, c[1].xyxy;\n"
- "MOV R0.x, c[0].z;\n"
- "MOV R0.y, c[1].z;\n"
- "MAD R0, R0.zzww, -R0.xyxy, R1.xzyw;\n"
- "MUL R1.xy, R2, fragment.texcoord[0];\n"
- "MUL R0, R2.z, R0;\n"
- "MUL R1.xy, R1, c[4].x;\n"
- "MUL R1.zw, R1.xyxy, R0.xyxz;\n"
- "MUL R0.zw, R1.xyxy, R0.xyyw;\n"
- "ADD R0.y, R0.z, R0.w;\n"
- "ADD R0.x, R1.z, R1.w;\n"
- "MUL R0.xy, R0, R0;\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.zw, R2.xyxy, R2.xyxy;\n"
- "ADD R0.z, R0, R0.w;\n"
- "ADD R0.y, -R0.z, c[4];\n"
- "RSQ R0.x, R0.x;\n"
- "MAD_SAT R0.x, R0, R0.y, -c[4].z;\n"
- "MUL R0.y, -R0.x, c[4].w;\n"
- "ADD R0.y, R0, c[5].x;\n"
- "MUL R0.x, R0, R0;\n"
- "MUL result.color, R0.x, R0.y;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_SIMPLE_PORTER_DUFF =
- "!!ARBfp1.0\n"
- "PARAM c[7] = { program.local[0..5],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xy, fragment.position, c[3];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "MUL R1.xyz, R0, c[0].y;\n"
- "MUL R2.xyz, fragment.color.primary.w, R1;\n"
- "MUL R1.xyz, fragment.color.primary, c[0].x;\n"
- "MAD R2.xyz, R0.w, R1, R2;\n"
- "ADD R3.xy, fragment.position, c[4];\n"
- "ADD R1.w, -R0, c[6].x;\n"
- "MUL R1.xyz, fragment.color.primary, c[1].y;\n"
- "MAD R2.xyz, R1.w, R1, R2;\n"
- "MUL R1.xyz, R0, c[1].z;\n"
- "ADD R2.w, -fragment.color.primary, c[6].x;\n"
- "MAD R2.xyz, R2.w, R1, R2;\n"
- "MUL R1.z, R0.w, R2.w;\n"
- "MUL R1.x, fragment.color.primary.w, R0.w;\n"
- "MUL R1.y, fragment.color.primary.w, R1.w;\n"
- "DP3 R2.w, R1, c[1];\n"
- "MUL R3.xy, R3, c[2];\n"
- "TEX R1, R3, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[5];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_MULTIPLY =
- "!!ARBfp1.0\n"
- "PARAM c[5] = { program.local[0..3],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "MUL R0.xy, fragment.position, c[1];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "ADD R1.x, -R0.w, c[4];\n"
- "MUL R1.xyz, fragment.color.primary, R1.x;\n"
- "MAD R1.xyz, fragment.color.primary, R0, R1;\n"
- "ADD R1.w, -fragment.color.primary, c[4].x;\n"
- "MAD R2.xyz, R0, R1.w, R1;\n"
- "ADD R1.z, fragment.color.primary.w, R0.w;\n"
- "MAD R2.w, -fragment.color.primary, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[2];\n"
- "MUL R1.xy, R1, c[0];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[3];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_SCREEN =
- "!!ARBfp1.0\n"
- "PARAM c[4] = { program.local[0..3] };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "MUL R0.xy, fragment.position, c[1];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "ADD R1.xy, fragment.position, c[2];\n"
- "ADD R2, fragment.color.primary, R0;\n"
- "MUL R1.xy, R1, c[0];\n"
- "MAD R2, -fragment.color.primary, R0, R2;\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[3];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_OVERLAY =
- "!!ARBfp1.0\n"
- "PARAM c[5] = { program.local[0..3],\n"
- " { 2, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xy, fragment.position, c[1];\n"
- "TEX R1, R0, texture[0], 2D;\n"
- "ADD R0.w, -R1, c[4].y;\n"
- "MUL R3.xyz, fragment.color.primary, R0.w;\n"
- "ADD R2.xyz, fragment.color.primary.w, -fragment.color.primary;\n"
- "ADD R0.xyz, R1.w, -R1;\n"
- "MUL R0.xyz, R0, R2;\n"
- "MUL R0.xyz, R0, c[4].x;\n"
- "MAD R0.xyz, fragment.color.primary.w, R1.w, -R0;\n"
- "MAD R0.xyz, fragment.color.primary, R0.w, R0;\n"
- "MUL R2.xyz, fragment.color.primary, R1;\n"
- "MAD R2.xyz, R2, c[4].x, R3;\n"
- "ADD R0.w, -fragment.color.primary, c[4].y;\n"
- "MAD R3.xyz, R1, R0.w, R0;\n"
- "MAD R2.xyz, R1, R0.w, R2;\n"
- "MUL R0.xyz, R1, c[4].x;\n"
- "SGE R0.xyz, R0, R1.w;\n"
- "ADD R3.xyz, R3, -R2;\n"
- "MAD R2.xyz, R0, R3, R2;\n"
- "ADD R0.z, fragment.color.primary.w, R1.w;\n"
- "MAD R2.w, -fragment.color.primary, R1, R0.z;\n"
- "ADD R0.xy, fragment.position, c[2];\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "ADD R2, R2, -R1;\n"
- "DP4 R0.x, R0, c[3];\n"
- "MAD result.color, R0.x, R2, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_DARKEN =
- "!!ARBfp1.0\n"
- "PARAM c[5] = { program.local[0..3],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "MUL R0.xy, fragment.position, c[1];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "MUL R2.xyz, fragment.color.primary.w, R0;\n"
- "MUL R1.xyz, fragment.color.primary, R0.w;\n"
- "MIN R1.xyz, R1, R2;\n"
- "ADD R1.w, -R0, c[4].x;\n"
- "MAD R1.xyz, fragment.color.primary, R1.w, R1;\n"
- "ADD R1.w, -fragment.color.primary, c[4].x;\n"
- "MAD R2.xyz, R0, R1.w, R1;\n"
- "ADD R1.z, fragment.color.primary.w, R0.w;\n"
- "MAD R2.w, -fragment.color.primary, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[2];\n"
- "MUL R1.xy, R1, c[0];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[3];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_LIGHTEN =
- "!!ARBfp1.0\n"
- "PARAM c[5] = { program.local[0..3],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "MUL R0.xy, fragment.position, c[1];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "MUL R2.xyz, fragment.color.primary.w, R0;\n"
- "MUL R1.xyz, fragment.color.primary, R0.w;\n"
- "MAX R1.xyz, R1, R2;\n"
- "ADD R1.w, -R0, c[4].x;\n"
- "MAD R1.xyz, fragment.color.primary, R1.w, R1;\n"
- "ADD R1.w, -fragment.color.primary, c[4].x;\n"
- "MAD R2.xyz, R0, R1.w, R1;\n"
- "ADD R1.z, fragment.color.primary.w, R0.w;\n"
- "MAD R2.w, -fragment.color.primary, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[2];\n"
- "MUL R1.xy, R1, c[0];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[3];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_COLORDODGE =
- "!!ARBfp1.0\n"
- "PARAM c[5] = { program.local[0..3],\n"
- " { 1, 1e-006 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xy, fragment.position, c[1];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "ADD R1.x, -fragment.color.primary.w, c[4];\n"
- "MAX R1.y, fragment.color.primary.w, c[4];\n"
- "MUL R2.xyz, R0, R1.x;\n"
- "ADD R1.w, -R0, c[4].x;\n"
- "MAD R3.xyz, fragment.color.primary, R1.w, R2;\n"
- "RCP R1.y, R1.y;\n"
- "MAD R1.xyz, -fragment.color.primary, R1.y, c[4].x;\n"
- "MAX R1.xyz, R1, c[4].y;\n"
- "MUL R2.xyz, fragment.color.primary.w, R0;\n"
- "MUL R1.w, fragment.color.primary, R0;\n"
- "RCP R1.x, R1.x;\n"
- "RCP R1.y, R1.y;\n"
- "RCP R1.z, R1.z;\n"
- "MAD R1.xyz, R2, R1, R3;\n"
- "MAD R3.xyz, fragment.color.primary.w, R0.w, R3;\n"
- "MAD R2.xyz, fragment.color.primary, R0.w, R2;\n"
- "ADD R3.xyz, R3, -R1;\n"
- "SGE R2.xyz, R2, R1.w;\n"
- "MAD R2.xyz, R2, R3, R1;\n"
- "ADD R1.z, fragment.color.primary.w, R0.w;\n"
- "MAD R2.w, -fragment.color.primary, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[2];\n"
- "MUL R1.xy, R1, c[0];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[3];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_COLORBURN =
- "!!ARBfp1.0\n"
- "PARAM c[5] = { program.local[0..3],\n"
- " { 1, 9.9999997e-006 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "MUL R0.xy, fragment.position, c[1];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "ADD R1.w, -R0, c[4].x;\n"
- "MUL R1.xyz, fragment.color.primary.w, R0;\n"
- "MAD R2.xyz, fragment.color.primary, R0.w, R1;\n"
- "MAD R1.xyz, -fragment.color.primary.w, R0.w, R2;\n"
- "MUL R3.xyz, fragment.color.primary.w, R1;\n"
- "MAX R1.xyz, fragment.color.primary, c[4].y;\n"
- "ADD R2.w, -fragment.color.primary, c[4].x;\n"
- "MUL R4.xyz, fragment.color.primary, R1.w;\n"
- "RCP R1.x, R1.x;\n"
- "RCP R1.y, R1.y;\n"
- "RCP R1.z, R1.z;\n"
- "MAD R3.xyz, R3, R1, R4;\n"
- "MUL R1.xyz, R0, R2.w;\n"
- "MAD R1.xyz, fragment.color.primary, R1.w, R1;\n"
- "MAD R3.xyz, R0, R2.w, R3;\n"
- "MUL R1.w, fragment.color.primary, R0;\n"
- "ADD R3.xyz, R3, -R1;\n"
- "SGE R2.xyz, R2, R1.w;\n"
- "MAD R2.xyz, R2, R3, R1;\n"
- "ADD R1.z, fragment.color.primary.w, R0.w;\n"
- "MAD R2.w, -fragment.color.primary, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[2];\n"
- "MUL R1.xy, R1, c[0];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[3];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_HARDLIGHT =
- "!!ARBfp1.0\n"
- "PARAM c[5] = { program.local[0..3],\n"
- " { 2, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xy, fragment.position, c[1];\n"
- "TEX R1, R0, texture[0], 2D;\n"
- "ADD R0.w, -R1, c[4].y;\n"
- "MUL R3.xyz, fragment.color.primary, R0.w;\n"
- "ADD R2.xyz, fragment.color.primary.w, -fragment.color.primary;\n"
- "ADD R0.xyz, R1.w, -R1;\n"
- "MUL R0.xyz, R0, R2;\n"
- "MUL R0.xyz, R0, c[4].x;\n"
- "MAD R0.xyz, fragment.color.primary.w, R1.w, -R0;\n"
- "MAD R0.xyz, fragment.color.primary, R0.w, R0;\n"
- "MUL R2.xyz, fragment.color.primary, R1;\n"
- "MAD R2.xyz, R2, c[4].x, R3;\n"
- "ADD R0.w, -fragment.color.primary, c[4].y;\n"
- "MAD R3.xyz, R1, R0.w, R0;\n"
- "MAD R2.xyz, R1, R0.w, R2;\n"
- "MUL R0.xyz, fragment.color.primary, c[4].x;\n"
- "SGE R0.xyz, R0, fragment.color.primary.w;\n"
- "ADD R3.xyz, R3, -R2;\n"
- "MAD R2.xyz, R0, R3, R2;\n"
- "ADD R0.z, fragment.color.primary.w, R1.w;\n"
- "MAD R2.w, -fragment.color.primary, R1, R0.z;\n"
- "ADD R0.xy, fragment.position, c[2];\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "ADD R2, R2, -R1;\n"
- "DP4 R0.x, R0, c[3];\n"
- "MAD result.color, R0.x, R2, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_SOFTLIGHT =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..3],\n"
- " { 1, 2, 9.9999997e-006, 4 },\n"
- " { 16, 12, 3 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "TEMP R5;\n"
- "MUL R0.xy, fragment.position, c[1];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "MAX R1.x, R0.w, c[4].z;\n"
- "RCP R1.x, R1.x;\n"
- "MUL R2.xyz, R0, R1.x;\n"
- "MAD R1.xyz, R2, c[5].x, -c[5].y;\n"
- "MAD R3.xyz, R2, R1, c[5].z;\n"
- "MAD R1.xyz, fragment.color.primary, c[4].y, -fragment.color.primary.w;\n"
- "MUL R4.xyz, R0.w, R1;\n"
- "MUL R5.xyz, R4, R3;\n"
- "RSQ R1.w, R2.x;\n"
- "RSQ R2.w, R2.z;\n"
- "RCP R3.x, R1.w;\n"
- "RSQ R1.w, R2.y;\n"
- "MUL R5.xyz, R2, R5;\n"
- "RCP R3.z, R2.w;\n"
- "RCP R3.y, R1.w;\n"
- "ADD R3.xyz, -R2, R3;\n"
- "MUL R3.xyz, R4, R3;\n"
- "ADD R2.xyz, -R2, c[4].x;\n"
- "MAD R1.xyz, R1, R2, fragment.color.primary.w;\n"
- "MUL R2.xyz, fragment.color.primary, c[4].y;\n"
- "MAD R4.xyz, fragment.color.primary.w, R0, R5;\n"
- "MAD R3.xyz, fragment.color.primary.w, R0, R3;\n"
- "ADD R5.xyz, R3, -R4;\n"
- "MUL R3.xyz, R0, c[4].w;\n"
- "SGE R3.xyz, R3, R0.w;\n"
- "MAD R3.xyz, R3, R5, R4;\n"
- "MAD R3.xyz, -R0, R1, R3;\n"
- "MUL R1.xyz, R0, R1;\n"
- "SGE R2.xyz, R2, fragment.color.primary.w;\n"
- "MAD R2.xyz, R2, R3, R1;\n"
- "ADD R1.x, -R0.w, c[4];\n"
- "MAD R2.xyz, fragment.color.primary, R1.x, R2;\n"
- "ADD R1.x, -fragment.color.primary.w, c[4];\n"
- "MAD R2.xyz, R0, R1.x, R2;\n"
- "ADD R1.z, fragment.color.primary.w, R0.w;\n"
- "MAD R2.w, -fragment.color.primary, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[2];\n"
- "MUL R1.xy, R1, c[0];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[3];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_DIFFERENCE =
- "!!ARBfp1.0\n"
- "PARAM c[5] = { program.local[0..3],\n"
- " { 2 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xy, fragment.position, c[1];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "ADD R1.xyz, fragment.color.primary, R0;\n"
- "MUL R3.xyz, fragment.color.primary.w, R0;\n"
- "MUL R2.xyz, fragment.color.primary, R0.w;\n"
- "MIN R2.xyz, R2, R3;\n"
- "MAD R2.xyz, -R2, c[4].x, R1;\n"
- "ADD R1.z, fragment.color.primary.w, R0.w;\n"
- "MAD R2.w, -fragment.color.primary, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[2];\n"
- "MUL R1.xy, R1, c[0];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[3];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_EXCLUSION =
- "!!ARBfp1.0\n"
- "PARAM c[5] = { program.local[0..3],\n"
- " { 2, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "MUL R0.xy, fragment.position, c[1];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "MUL R1.xyz, fragment.color.primary.w, R0;\n"
- "MAD R2.xyz, fragment.color.primary, R0.w, R1;\n"
- "MUL R1.xyz, fragment.color.primary, R0;\n"
- "MAD R1.xyz, -R1, c[4].x, R2;\n"
- "ADD R1.w, -R0, c[4].y;\n"
- "MAD R1.xyz, fragment.color.primary, R1.w, R1;\n"
- "ADD R1.w, -fragment.color.primary, c[4].y;\n"
- "MAD R2.xyz, R0, R1.w, R1;\n"
- "ADD R1.z, fragment.color.primary.w, R0.w;\n"
- "MAD R2.w, -fragment.color.primary, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[2];\n"
- "MUL R1.xy, R1, c[0];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[3];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_SIMPLE_PORTER_DUFF_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[4] = { program.local[0..2],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "MUL R0.xy, fragment.position, c[2];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "MUL R1.xyz, R0, c[0].y;\n"
- "MUL R2.xyz, fragment.color.primary.w, R1;\n"
- "MUL R1.xyz, fragment.color.primary, c[0].x;\n"
- "MAD R2.xyz, R0.w, R1, R2;\n"
- "MUL R0.xyz, R0, c[1].z;\n"
- "ADD R1.w, -R0, c[3].x;\n"
- "MUL R1.xyz, fragment.color.primary, c[1].y;\n"
- "MAD R1.xyz, R1.w, R1, R2;\n"
- "ADD R2.x, -fragment.color.primary.w, c[3];\n"
- "MAD result.color.xyz, R2.x, R0, R1;\n"
- "MUL R0.x, fragment.color.primary.w, R0.w;\n"
- "MUL R0.z, R0.w, R2.x;\n"
- "MUL R0.y, fragment.color.primary.w, R1.w;\n"
- "DP3 result.color.w, R0, c[1];\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_MULTIPLY_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[2] = { program.local[0],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "MUL R0.xy, fragment.position, c[0];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "ADD R1.x, -R0.w, c[1];\n"
- "MUL R1.xyz, fragment.color.primary, R1.x;\n"
- "ADD R1.w, fragment.color.primary, R0;\n"
- "MAD R1.xyz, fragment.color.primary, R0, R1;\n"
- "ADD R2.x, -fragment.color.primary.w, c[1];\n"
- "MAD result.color.xyz, R0, R2.x, R1;\n"
- "MAD result.color.w, -fragment.color.primary, R0, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_SCREEN_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[1] = { program.local[0] };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "MUL R0.xy, fragment.position, c[0];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "ADD R1, fragment.color.primary, R0;\n"
- "MAD result.color, -fragment.color.primary, R0, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_OVERLAY_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[2] = { program.local[0],\n"
- " { 2, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xy, fragment.position, c[0];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "ADD R1.w, -R0, c[1].y;\n"
- "ADD R2.xyz, fragment.color.primary.w, -fragment.color.primary;\n"
- "ADD R1.xyz, R0.w, -R0;\n"
- "MUL R1.xyz, R1, R2;\n"
- "MUL R1.xyz, R1, c[1].x;\n"
- "MAD R1.xyz, fragment.color.primary.w, R0.w, -R1;\n"
- "MUL R3.xyz, fragment.color.primary, R1.w;\n"
- "MUL R2.xyz, fragment.color.primary, R0;\n"
- "MAD R1.xyz, fragment.color.primary, R1.w, R1;\n"
- "ADD R1.w, -fragment.color.primary, c[1].y;\n"
- "MAD R2.xyz, R2, c[1].x, R3;\n"
- "MAD R2.xyz, R0, R1.w, R2;\n"
- "MAD R1.xyz, R0, R1.w, R1;\n"
- "MUL R0.xyz, R0, c[1].x;\n"
- "ADD R1.w, fragment.color.primary, R0;\n"
- "ADD R1.xyz, R1, -R2;\n"
- "SGE R0.xyz, R0, R0.w;\n"
- "MAD result.color.xyz, R0, R1, R2;\n"
- "MAD result.color.w, -fragment.color.primary, R0, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_DARKEN_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[2] = { program.local[0],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "MUL R0.xy, fragment.position, c[0];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "MUL R2.xyz, fragment.color.primary.w, R0;\n"
- "MUL R1.xyz, fragment.color.primary, R0.w;\n"
- "MIN R1.xyz, R1, R2;\n"
- "ADD R1.w, -R0, c[1].x;\n"
- "MAD R1.xyz, fragment.color.primary, R1.w, R1;\n"
- "ADD R1.w, fragment.color.primary, R0;\n"
- "ADD R2.x, -fragment.color.primary.w, c[1];\n"
- "MAD result.color.xyz, R0, R2.x, R1;\n"
- "MAD result.color.w, -fragment.color.primary, R0, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_LIGHTEN_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[2] = { program.local[0],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "MUL R0.xy, fragment.position, c[0];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "MUL R2.xyz, fragment.color.primary.w, R0;\n"
- "MUL R1.xyz, fragment.color.primary, R0.w;\n"
- "MAX R1.xyz, R1, R2;\n"
- "ADD R1.w, -R0, c[1].x;\n"
- "MAD R1.xyz, fragment.color.primary, R1.w, R1;\n"
- "ADD R1.w, fragment.color.primary, R0;\n"
- "ADD R2.x, -fragment.color.primary.w, c[1];\n"
- "MAD result.color.xyz, R0, R2.x, R1;\n"
- "MAD result.color.w, -fragment.color.primary, R0, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_COLORDODGE_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[2] = { program.local[0],\n"
- " { 1, 1e-006 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "MAX R1.y, fragment.color.primary.w, c[1];\n"
- "RCP R2.x, R1.y;\n"
- "MUL R0.xy, fragment.position, c[0];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "ADD R1.x, -fragment.color.primary.w, c[1];\n"
- "MUL R1.xyz, R0, R1.x;\n"
- "ADD R1.w, -R0, c[1].x;\n"
- "MAD R1.xyz, fragment.color.primary, R1.w, R1;\n"
- "MAD R2.xyz, -fragment.color.primary, R2.x, c[1].x;\n"
- "MAX R2.xyz, R2, c[1].y;\n"
- "MUL R0.xyz, fragment.color.primary.w, R0;\n"
- "MUL R1.w, fragment.color.primary, R0;\n"
- "RCP R2.x, R2.x;\n"
- "RCP R2.y, R2.y;\n"
- "RCP R2.z, R2.z;\n"
- "MAD R2.xyz, R0, R2, R1;\n"
- "MAD R1.xyz, fragment.color.primary.w, R0.w, R1;\n"
- "MAD R0.xyz, fragment.color.primary, R0.w, R0;\n"
- "SGE R0.xyz, R0, R1.w;\n"
- "ADD R1.xyz, R1, -R2;\n"
- "ADD R1.w, fragment.color.primary, R0;\n"
- "MAD result.color.xyz, R0, R1, R2;\n"
- "MAD result.color.w, -fragment.color.primary, R0, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_COLORBURN_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[2] = { program.local[0],\n"
- " { 1, 9.9999997e-006 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "MUL R0.xy, fragment.position, c[0];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "MUL R1.xyz, fragment.color.primary.w, R0;\n"
- "MAD R2.xyz, fragment.color.primary, R0.w, R1;\n"
- "MAD R1.xyz, -fragment.color.primary.w, R0.w, R2;\n"
- "MUL R3.xyz, fragment.color.primary.w, R1;\n"
- "MAX R1.xyz, fragment.color.primary, c[1].y;\n"
- "ADD R1.w, -R0, c[1].x;\n"
- "MUL R4.xyz, fragment.color.primary, R1.w;\n"
- "ADD R2.w, -fragment.color.primary, c[1].x;\n"
- "RCP R1.x, R1.x;\n"
- "RCP R1.y, R1.y;\n"
- "RCP R1.z, R1.z;\n"
- "MAD R1.xyz, R3, R1, R4;\n"
- "MUL R3.xyz, R0, R2.w;\n"
- "MAD R0.xyz, R0, R2.w, R1;\n"
- "MAD R1.xyz, fragment.color.primary, R1.w, R3;\n"
- "MUL R1.w, fragment.color.primary, R0;\n"
- "SGE R2.xyz, R2, R1.w;\n"
- "ADD R0.xyz, R0, -R1;\n"
- "ADD R1.w, fragment.color.primary, R0;\n"
- "MAD result.color.xyz, R2, R0, R1;\n"
- "MAD result.color.w, -fragment.color.primary, R0, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_HARDLIGHT_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[2] = { program.local[0],\n"
- " { 2, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xy, fragment.position, c[0];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "ADD R1.w, -R0, c[1].y;\n"
- "ADD R2.xyz, fragment.color.primary.w, -fragment.color.primary;\n"
- "ADD R1.xyz, R0.w, -R0;\n"
- "MUL R1.xyz, R1, R2;\n"
- "MUL R1.xyz, R1, c[1].x;\n"
- "MAD R1.xyz, fragment.color.primary.w, R0.w, -R1;\n"
- "MAD R1.xyz, fragment.color.primary, R1.w, R1;\n"
- "MUL R3.xyz, fragment.color.primary, R1.w;\n"
- "MUL R2.xyz, fragment.color.primary, R0;\n"
- "ADD R1.w, -fragment.color.primary, c[1].y;\n"
- "MAD R2.xyz, R2, c[1].x, R3;\n"
- "MAD R2.xyz, R0, R1.w, R2;\n"
- "MAD R0.xyz, R0, R1.w, R1;\n"
- "ADD R1.xyz, R0, -R2;\n"
- "MUL R0.xyz, fragment.color.primary, c[1].x;\n"
- "ADD R1.w, fragment.color.primary, R0;\n"
- "SGE R0.xyz, R0, fragment.color.primary.w;\n"
- "MAD result.color.xyz, R0, R1, R2;\n"
- "MAD result.color.w, -fragment.color.primary, R0, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_SOFTLIGHT_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[3] = { program.local[0],\n"
- " { 1, 2, 9.9999997e-006, 4 },\n"
- " { 16, 12, 3 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "TEMP R5;\n"
- "MUL R0.xy, fragment.position, c[0];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "MAX R1.x, R0.w, c[1].z;\n"
- "RCP R1.x, R1.x;\n"
- "MUL R2.xyz, R0, R1.x;\n"
- "MAD R1.xyz, R2, c[2].x, -c[2].y;\n"
- "MAD R3.xyz, R2, R1, c[2].z;\n"
- "MAD R1.xyz, fragment.color.primary, c[1].y, -fragment.color.primary.w;\n"
- "MUL R4.xyz, R0.w, R1;\n"
- "MUL R5.xyz, R4, R3;\n"
- "RSQ R1.w, R2.x;\n"
- "RCP R3.x, R1.w;\n"
- "RSQ R2.w, R2.z;\n"
- "RSQ R1.w, R2.y;\n"
- "MUL R5.xyz, R2, R5;\n"
- "RCP R3.z, R2.w;\n"
- "RCP R3.y, R1.w;\n"
- "ADD R3.xyz, -R2, R3;\n"
- "MUL R3.xyz, R4, R3;\n"
- "ADD R2.xyz, -R2, c[1].x;\n"
- "MAD R1.xyz, R1, R2, fragment.color.primary.w;\n"
- "MUL R2.xyz, fragment.color.primary, c[1].y;\n"
- "MAD R4.xyz, fragment.color.primary.w, R0, R5;\n"
- "MAD R3.xyz, fragment.color.primary.w, R0, R3;\n"
- "ADD R5.xyz, R3, -R4;\n"
- "MUL R3.xyz, R0, c[1].w;\n"
- "SGE R3.xyz, R3, R0.w;\n"
- "MAD R3.xyz, R3, R5, R4;\n"
- "MAD R3.xyz, -R0, R1, R3;\n"
- "MUL R1.xyz, R0, R1;\n"
- "SGE R2.xyz, R2, fragment.color.primary.w;\n"
- "MAD R2.xyz, R2, R3, R1;\n"
- "ADD R1.x, -R0.w, c[1];\n"
- "MAD R2.xyz, fragment.color.primary, R1.x, R2;\n"
- "ADD R1.x, fragment.color.primary.w, R0.w;\n"
- "ADD R1.y, -fragment.color.primary.w, c[1].x;\n"
- "MAD result.color.xyz, R0, R1.y, R2;\n"
- "MAD result.color.w, -fragment.color.primary, R0, R1.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_DIFFERENCE_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[2] = { program.local[0],\n"
- " { 2 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "MUL R0.xy, fragment.position, c[0];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "MUL R2.xyz, fragment.color.primary.w, R0;\n"
- "MUL R1.xyz, fragment.color.primary, R0.w;\n"
- "ADD R1.w, fragment.color.primary, R0;\n"
- "MIN R1.xyz, R1, R2;\n"
- "ADD R0.xyz, fragment.color.primary, R0;\n"
- "MAD result.color.xyz, -R1, c[1].x, R0;\n"
- "MAD result.color.w, -fragment.color.primary, R0, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_EXCLUSION_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[2] = { program.local[0],\n"
- " { 2, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "MUL R0.xy, fragment.position, c[0];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "MUL R1.xyz, fragment.color.primary.w, R0;\n"
- "MAD R2.xyz, fragment.color.primary, R0.w, R1;\n"
- "MUL R1.xyz, fragment.color.primary, R0;\n"
- "MAD R1.xyz, -R1, c[1].x, R2;\n"
- "ADD R1.w, -R0, c[1].y;\n"
- "MAD R1.xyz, fragment.color.primary, R1.w, R1;\n"
- "ADD R1.w, fragment.color.primary, R0;\n"
- "ADD R2.x, -fragment.color.primary.w, c[1].y;\n"
- "MAD result.color.xyz, R0, R2.x, R1;\n"
- "MAD result.color.w, -fragment.color.primary, R0, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODE_BLEND_MODE_MASK =
- "!!ARBfp1.0\n"
- "PARAM c[3] = { program.local[0..2] };\n"
- "TEMP R0;\n"
- "ADD R0.xy, fragment.position, c[1];\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "DP4 R0.x, R0, c[2];\n"
- "MUL result.color, fragment.color.primary, R0.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODE_BLEND_MODE_NOMASK =
- "!!ARBfp1.0\n"
- "MOV result.color, fragment.color.primary;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_SIMPLE_PORTER_DUFF =
- "!!ARBfp1.0\n"
- "PARAM c[12] = { program.local[0..10],\n"
- " { 2, 4, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[3];\n"
- "MAD R0.xyz, fragment.position.x, c[2], R0;\n"
- "ADD R0.xyz, R0, c[4];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.xyxy;\n"
- "ADD R0.z, R0, R0.w;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.z, -R0, c[1].x;\n"
- "MUL R0.y, R0.x, c[11].x;\n"
- "MUL R0.z, R0, c[11].y;\n"
- "MAD R0.x, R0.y, R0.y, -R0.z;\n"
- "RSQ R0.x, R0.x;\n"
- "RCP R0.z, R0.x;\n"
- "ADD R1.x, -R0.y, R0.z;\n"
- "MOV R0.x, c[11];\n"
- "MUL R0.z, R0.x, c[1].x;\n"
- "RCP R1.y, R0.z;\n"
- "MUL R0.xy, fragment.position, c[8];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "MUL R1.x, R1, R1.y;\n"
- "TEX R1, R1, texture[2], 1D;\n"
- "MUL R2.xyz, R0, c[5].y;\n"
- "MUL R3.xyz, R1.w, R2;\n"
- "MUL R2.xyz, R1, c[5].x;\n"
- "MAD R2.xyz, R0.w, R2, R3;\n"
- "ADD R3.xy, fragment.position, c[9];\n"
- "ADD R2.w, -R0, c[11].z;\n"
- "MUL R1.xyz, R1, c[6].y;\n"
- "MAD R2.xyz, R2.w, R1, R2;\n"
- "MUL R1.xyz, R0, c[6].z;\n"
- "ADD R3.z, -R1.w, c[11];\n"
- "MAD R2.xyz, R3.z, R1, R2;\n"
- "MUL R1.y, R1.w, R2.w;\n"
- "MUL R1.x, R1.w, R0.w;\n"
- "MUL R1.z, R0.w, R3;\n"
- "DP3 R2.w, R1, c[6];\n"
- "MUL R3.xy, R3, c[7];\n"
- "TEX R1, R3, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[10];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_MULTIPLY =
- "!!ARBfp1.0\n"
- "PARAM c[10] = { program.local[0..8],\n"
- " { 2, 4, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "MUL R0.xyz, fragment.position.y, c[3];\n"
- "MAD R0.xyz, fragment.position.x, c[2], R0;\n"
- "ADD R0.xyz, R0, c[4];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.xyxy;\n"
- "ADD R0.z, R0, R0.w;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.z, -R0, c[1].x;\n"
- "MUL R0.y, R0.x, c[9].x;\n"
- "MUL R0.z, R0, c[9].y;\n"
- "MAD R0.x, R0.y, R0.y, -R0.z;\n"
- "RSQ R0.x, R0.x;\n"
- "RCP R0.z, R0.x;\n"
- "ADD R1.x, -R0.y, R0.z;\n"
- "MOV R0.x, c[9];\n"
- "MUL R0.z, R0.x, c[1].x;\n"
- "RCP R1.y, R0.z;\n"
- "MUL R0.xy, fragment.position, c[6];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "MUL R1.x, R1, R1.y;\n"
- "TEX R1, R1, texture[2], 1D;\n"
- "ADD R2.x, -R0.w, c[9].z;\n"
- "MUL R2.xyz, R1, R2.x;\n"
- "MAD R1.xyz, R1, R0, R2;\n"
- "ADD R2.x, -R1.w, c[9].z;\n"
- "MAD R2.xyz, R0, R2.x, R1;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[7];\n"
- "MUL R1.xy, R1, c[5];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[8];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_SCREEN =
- "!!ARBfp1.0\n"
- "PARAM c[10] = { program.local[0..8],\n"
- " { 2, 4 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[3];\n"
- "MAD R0.xyz, fragment.position.x, c[2], R0;\n"
- "ADD R0.xyz, R0, c[4];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.xyxy;\n"
- "ADD R0.z, R0, R0.w;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.y, R0.x, c[9].x;\n"
- "MOV R0.x, c[9];\n"
- "MUL R0.z, -R0, c[1].x;\n"
- "MUL R0.z, R0, c[9].y;\n"
- "MAD R0.z, R0.y, R0.y, -R0;\n"
- "ADD R3.xy, fragment.position, c[7];\n"
- "MUL R0.w, R0.x, c[1].x;\n"
- "RSQ R0.z, R0.z;\n"
- "RCP R0.x, R0.z;\n"
- "RCP R0.z, R0.w;\n"
- "ADD R0.x, -R0.y, R0;\n"
- "MUL R0.z, R0.x, R0;\n"
- "TEX R1, R0.z, texture[2], 1D;\n"
- "MUL R0.xy, fragment.position, c[6];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "ADD R2, R1, R0;\n"
- "MAD R2, -R1, R0, R2;\n"
- "MUL R3.xy, R3, c[5];\n"
- "TEX R1, R3, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[8];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_OVERLAY =
- "!!ARBfp1.0\n"
- "PARAM c[10] = { program.local[0..8],\n"
- " { 2, 4, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "MUL R0.xyz, fragment.position.y, c[3];\n"
- "MAD R0.xyz, fragment.position.x, c[2], R0;\n"
- "ADD R0.xyz, R0, c[4];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.xyxy;\n"
- "ADD R0.z, R0, R0.w;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.y, R0.x, c[9].x;\n"
- "MOV R0.x, c[9];\n"
- "MUL R0.z, -R0, c[1].x;\n"
- "MUL R0.z, R0, c[9].y;\n"
- "MAD R0.z, R0.y, R0.y, -R0;\n"
- "MUL R1.xy, fragment.position, c[6];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "MUL R0.w, R0.x, c[1].x;\n"
- "RSQ R0.z, R0.z;\n"
- "RCP R0.x, R0.z;\n"
- "ADD R2.w, -R1, c[9].z;\n"
- "RCP R0.z, R0.w;\n"
- "ADD R0.x, -R0.y, R0;\n"
- "MUL R0.x, R0, R0.z;\n"
- "TEX R0, R0, texture[2], 1D;\n"
- "ADD R3.xyz, R0.w, -R0;\n"
- "ADD R2.xyz, R1.w, -R1;\n"
- "MUL R2.xyz, R2, R3;\n"
- "MUL R2.xyz, R2, c[9].x;\n"
- "MAD R2.xyz, R0.w, R1.w, -R2;\n"
- "MUL R4.xyz, R0, R2.w;\n"
- "MUL R3.xyz, R0, R1;\n"
- "MAD R0.xyz, R0, R2.w, R2;\n"
- "ADD R2.x, -R0.w, c[9].z;\n"
- "MAD R3.xyz, R3, c[9].x, R4;\n"
- "MAD R3.xyz, R1, R2.x, R3;\n"
- "MAD R0.xyz, R1, R2.x, R0;\n"
- "MUL R2.xyz, R1, c[9].x;\n"
- "ADD R0.xyz, R0, -R3;\n"
- "SGE R2.xyz, R2, R1.w;\n"
- "MAD R2.xyz, R2, R0, R3;\n"
- "ADD R0.z, R0.w, R1.w;\n"
- "MAD R2.w, -R0, R1, R0.z;\n"
- "ADD R0.xy, fragment.position, c[7];\n"
- "MUL R0.xy, R0, c[5];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "ADD R2, R2, -R1;\n"
- "DP4 R0.x, R0, c[8];\n"
- "MAD result.color, R0.x, R2, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_DARKEN =
- "!!ARBfp1.0\n"
- "PARAM c[10] = { program.local[0..8],\n"
- " { 2, 4, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[3];\n"
- "MAD R0.xyz, fragment.position.x, c[2], R0;\n"
- "ADD R0.xyz, R0, c[4];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.xyxy;\n"
- "ADD R0.z, R0, R0.w;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.z, -R0, c[1].x;\n"
- "MUL R0.y, R0.x, c[9].x;\n"
- "MUL R0.z, R0, c[9].y;\n"
- "MAD R0.x, R0.y, R0.y, -R0.z;\n"
- "RSQ R0.z, R0.x;\n"
- "MOV R0.x, c[9];\n"
- "MUL R0.x, R0, c[1];\n"
- "RCP R0.z, R0.z;\n"
- "ADD R0.z, -R0.y, R0;\n"
- "RCP R0.w, R0.x;\n"
- "MUL R1.x, R0.z, R0.w;\n"
- "MUL R0.xy, fragment.position, c[6];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "TEX R1, R1, texture[2], 1D;\n"
- "MUL R3.xyz, R1.w, R0;\n"
- "MUL R2.xyz, R1, R0.w;\n"
- "MIN R2.xyz, R2, R3;\n"
- "ADD R2.w, -R0, c[9].z;\n"
- "MAD R1.xyz, R1, R2.w, R2;\n"
- "ADD R2.x, -R1.w, c[9].z;\n"
- "MAD R2.xyz, R0, R2.x, R1;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[7];\n"
- "MUL R1.xy, R1, c[5];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[8];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_LIGHTEN =
- "!!ARBfp1.0\n"
- "PARAM c[10] = { program.local[0..8],\n"
- " { 2, 4, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[3];\n"
- "MAD R0.xyz, fragment.position.x, c[2], R0;\n"
- "ADD R0.xyz, R0, c[4];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.xyxy;\n"
- "ADD R0.z, R0, R0.w;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.z, -R0, c[1].x;\n"
- "MUL R0.y, R0.x, c[9].x;\n"
- "MUL R0.z, R0, c[9].y;\n"
- "MAD R0.x, R0.y, R0.y, -R0.z;\n"
- "RSQ R0.z, R0.x;\n"
- "MOV R0.x, c[9];\n"
- "MUL R0.x, R0, c[1];\n"
- "RCP R0.z, R0.z;\n"
- "ADD R0.z, -R0.y, R0;\n"
- "RCP R0.w, R0.x;\n"
- "MUL R1.x, R0.z, R0.w;\n"
- "MUL R0.xy, fragment.position, c[6];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "TEX R1, R1, texture[2], 1D;\n"
- "MUL R3.xyz, R1.w, R0;\n"
- "MUL R2.xyz, R1, R0.w;\n"
- "MAX R2.xyz, R2, R3;\n"
- "ADD R2.w, -R0, c[9].z;\n"
- "MAD R1.xyz, R1, R2.w, R2;\n"
- "ADD R2.x, -R1.w, c[9].z;\n"
- "MAD R2.xyz, R0, R2.x, R1;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[7];\n"
- "MUL R1.xy, R1, c[5];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[8];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_COLORDODGE =
- "!!ARBfp1.0\n"
- "PARAM c[10] = { program.local[0..8],\n"
- " { 2, 4, 1, 1e-006 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "MUL R0.xyz, fragment.position.y, c[3];\n"
- "MAD R0.xyz, fragment.position.x, c[2], R0;\n"
- "ADD R0.xyz, R0, c[4];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.xyxy;\n"
- "ADD R0.z, R0, R0.w;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.y, R0.x, c[9].x;\n"
- "MOV R0.x, c[9];\n"
- "MUL R0.z, -R0, c[1].x;\n"
- "MUL R0.z, R0, c[9].y;\n"
- "MAD R0.z, R0.y, R0.y, -R0;\n"
- "MUL R0.w, R0.x, c[1].x;\n"
- "RSQ R0.z, R0.z;\n"
- "RCP R0.x, R0.z;\n"
- "RCP R0.z, R0.w;\n"
- "ADD R0.x, -R0.y, R0;\n"
- "MUL R0.x, R0, R0.z;\n"
- "TEX R0, R0, texture[2], 1D;\n"
- "MAX R1.x, R0.w, c[9].w;\n"
- "RCP R1.x, R1.x;\n"
- "MAD R1.xyz, -R0, R1.x, c[9].z;\n"
- "MAX R2.xyz, R1, c[9].w;\n"
- "MUL R1.xy, fragment.position, c[6];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "ADD R2.w, -R0, c[9].z;\n"
- "MUL R3.xyz, R1, R2.w;\n"
- "ADD R2.w, -R1, c[9].z;\n"
- "MAD R4.xyz, R0, R2.w, R3;\n"
- "MUL R3.xyz, R0.w, R1;\n"
- "MUL R2.w, R0, R1;\n"
- "MAD R0.xyz, R0, R1.w, R3;\n"
- "SGE R0.xyz, R0, R2.w;\n"
- "RCP R2.x, R2.x;\n"
- "RCP R2.y, R2.y;\n"
- "RCP R2.z, R2.z;\n"
- "MAD R2.xyz, R3, R2, R4;\n"
- "MAD R4.xyz, R0.w, R1.w, R4;\n"
- "ADD R4.xyz, R4, -R2;\n"
- "MAD R2.xyz, R0, R4, R2;\n"
- "ADD R0.z, R0.w, R1.w;\n"
- "MAD R2.w, -R0, R1, R0.z;\n"
- "ADD R0.xy, fragment.position, c[7];\n"
- "MUL R0.xy, R0, c[5];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "ADD R2, R2, -R1;\n"
- "DP4 R0.x, R0, c[8];\n"
- "MAD result.color, R0.x, R2, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_COLORBURN =
- "!!ARBfp1.0\n"
- "PARAM c[10] = { program.local[0..8],\n"
- " { 2, 4, 1, 9.9999997e-006 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "TEMP R5;\n"
- "MUL R0.xyz, fragment.position.y, c[3];\n"
- "MAD R0.xyz, fragment.position.x, c[2], R0;\n"
- "ADD R0.xyz, R0, c[4];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.xyxy;\n"
- "ADD R0.z, R0, R0.w;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.z, -R0, c[1].x;\n"
- "MUL R0.y, R0.x, c[9].x;\n"
- "MUL R0.z, R0, c[9].y;\n"
- "MAD R0.x, R0.y, R0.y, -R0.z;\n"
- "RSQ R0.z, R0.x;\n"
- "MOV R0.x, c[9];\n"
- "MUL R0.w, R0.x, c[1].x;\n"
- "RCP R0.z, R0.z;\n"
- "ADD R0.x, -R0.y, R0.z;\n"
- "RCP R0.y, R0.w;\n"
- "MUL R0.zw, fragment.position.xyxy, c[6].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "MUL R0.x, R0, R0.y;\n"
- "TEX R0, R0, texture[2], 1D;\n"
- "MUL R2.xyz, R0.w, R1;\n"
- "MAD R3.xyz, R0, R1.w, R2;\n"
- "MAD R2.xyz, -R0.w, R1.w, R3;\n"
- "MUL R4.xyz, R0.w, R2;\n"
- "MAX R2.xyz, R0, c[9].w;\n"
- "ADD R2.w, -R1, c[9].z;\n"
- "MUL R5.xyz, R0, R2.w;\n"
- "ADD R3.w, -R0, c[9].z;\n"
- "RCP R2.x, R2.x;\n"
- "RCP R2.y, R2.y;\n"
- "RCP R2.z, R2.z;\n"
- "MAD R2.xyz, R4, R2, R5;\n"
- "MUL R4.xyz, R1, R3.w;\n"
- "MAD R0.xyz, R0, R2.w, R4;\n"
- "MUL R2.w, R0, R1;\n"
- "MAD R2.xyz, R1, R3.w, R2;\n"
- "ADD R2.xyz, R2, -R0;\n"
- "SGE R3.xyz, R3, R2.w;\n"
- "MAD R2.xyz, R3, R2, R0;\n"
- "ADD R0.z, R0.w, R1.w;\n"
- "MAD R2.w, -R0, R1, R0.z;\n"
- "ADD R0.xy, fragment.position, c[7];\n"
- "MUL R0.xy, R0, c[5];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "ADD R2, R2, -R1;\n"
- "DP4 R0.x, R0, c[8];\n"
- "MAD result.color, R0.x, R2, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_HARDLIGHT =
- "!!ARBfp1.0\n"
- "PARAM c[10] = { program.local[0..8],\n"
- " { 2, 4, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "MUL R0.xyz, fragment.position.y, c[3];\n"
- "MAD R0.xyz, fragment.position.x, c[2], R0;\n"
- "ADD R0.xyz, R0, c[4];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.xyxy;\n"
- "ADD R0.z, R0, R0.w;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.y, R0.x, c[9].x;\n"
- "MOV R0.x, c[9];\n"
- "MUL R0.z, -R0, c[1].x;\n"
- "MUL R0.z, R0, c[9].y;\n"
- "MAD R0.z, R0.y, R0.y, -R0;\n"
- "MUL R1.xy, fragment.position, c[6];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "MUL R0.w, R0.x, c[1].x;\n"
- "RSQ R0.z, R0.z;\n"
- "RCP R0.x, R0.z;\n"
- "ADD R2.w, -R1, c[9].z;\n"
- "RCP R0.z, R0.w;\n"
- "ADD R0.x, -R0.y, R0;\n"
- "MUL R0.x, R0, R0.z;\n"
- "TEX R0, R0, texture[2], 1D;\n"
- "ADD R3.xyz, R0.w, -R0;\n"
- "ADD R2.xyz, R1.w, -R1;\n"
- "MUL R2.xyz, R2, R3;\n"
- "MUL R2.xyz, R2, c[9].x;\n"
- "MAD R2.xyz, R0.w, R1.w, -R2;\n"
- "MUL R4.xyz, R0, R2.w;\n"
- "MAD R2.xyz, R0, R2.w, R2;\n"
- "MUL R3.xyz, R0, R1;\n"
- "ADD R2.w, -R0, c[9].z;\n"
- "MAD R3.xyz, R3, c[9].x, R4;\n"
- "MUL R0.xyz, R0, c[9].x;\n"
- "SGE R0.xyz, R0, R0.w;\n"
- "MAD R3.xyz, R1, R2.w, R3;\n"
- "MAD R2.xyz, R1, R2.w, R2;\n"
- "ADD R2.xyz, R2, -R3;\n"
- "MAD R2.xyz, R0, R2, R3;\n"
- "ADD R0.z, R0.w, R1.w;\n"
- "MAD R2.w, -R0, R1, R0.z;\n"
- "ADD R0.xy, fragment.position, c[7];\n"
- "MUL R0.xy, R0, c[5];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "ADD R2, R2, -R1;\n"
- "DP4 R0.x, R0, c[8];\n"
- "MAD result.color, R0.x, R2, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_SOFTLIGHT =
- "!!ARBfp1.0\n"
- "PARAM c[11] = { program.local[0..8],\n"
- " { 2, 4, 1, 9.9999997e-006 },\n"
- " { 16, 12, 3 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "TEMP R5;\n"
- "TEMP R6;\n"
- "MUL R0.xyz, fragment.position.y, c[3];\n"
- "MAD R0.xyz, fragment.position.x, c[2], R0;\n"
- "ADD R0.xyz, R0, c[4];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.xyxy;\n"
- "ADD R0.z, R0, R0.w;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.z, -R0, c[1].x;\n"
- "MUL R0.y, R0.z, c[9];\n"
- "MUL R0.x, R0, c[9];\n"
- "MUL R0.zw, fragment.position.xyxy, c[6].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "MAD R0.y, R0.x, R0.x, -R0;\n"
- "RSQ R0.y, R0.y;\n"
- "RCP R0.y, R0.y;\n"
- "ADD R0.y, -R0.x, R0;\n"
- "MOV R0.x, c[9];\n"
- "MUL R0.x, R0, c[1];\n"
- "MAX R0.z, R1.w, c[9].w;\n"
- "RCP R0.z, R0.z;\n"
- "MUL R3.xyz, R1, R0.z;\n"
- "MAD R4.xyz, R3, c[10].x, -c[10].y;\n"
- "RCP R0.x, R0.x;\n"
- "MUL R0.x, R0.y, R0;\n"
- "TEX R0, R0, texture[2], 1D;\n"
- "MAD R2.xyz, R0, c[9].x, -R0.w;\n"
- "MAD R4.xyz, R3, R4, c[10].z;\n"
- "MUL R5.xyz, R1.w, R2;\n"
- "MUL R6.xyz, R5, R4;\n"
- "RSQ R2.w, R3.x;\n"
- "RCP R4.x, R2.w;\n"
- "RSQ R2.w, R3.y;\n"
- "RSQ R3.w, R3.z;\n"
- "RCP R4.y, R2.w;\n"
- "RCP R4.z, R3.w;\n"
- "ADD R4.xyz, -R3, R4;\n"
- "MUL R6.xyz, R3, R6;\n"
- "MUL R4.xyz, R5, R4;\n"
- "ADD R3.xyz, -R3, c[9].z;\n"
- "MAD R2.xyz, R2, R3, R0.w;\n"
- "MUL R3.xyz, R0, c[9].x;\n"
- "MAD R5.xyz, R0.w, R1, R6;\n"
- "MAD R4.xyz, R0.w, R1, R4;\n"
- "ADD R6.xyz, R4, -R5;\n"
- "MUL R4.xyz, R1, c[9].y;\n"
- "SGE R4.xyz, R4, R1.w;\n"
- "MAD R4.xyz, R4, R6, R5;\n"
- "MAD R4.xyz, -R1, R2, R4;\n"
- "SGE R3.xyz, R3, R0.w;\n"
- "MUL R2.xyz, R1, R2;\n"
- "ADD R2.w, -R1, c[9].z;\n"
- "MAD R2.xyz, R3, R4, R2;\n"
- "MAD R2.xyz, R0, R2.w, R2;\n"
- "ADD R0.x, -R0.w, c[9].z;\n"
- "MAD R2.xyz, R1, R0.x, R2;\n"
- "ADD R0.z, R0.w, R1.w;\n"
- "MAD R2.w, -R0, R1, R0.z;\n"
- "ADD R0.xy, fragment.position, c[7];\n"
- "MUL R0.xy, R0, c[5];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "ADD R2, R2, -R1;\n"
- "DP4 R0.x, R0, c[8];\n"
- "MAD result.color, R0.x, R2, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_DIFFERENCE =
- "!!ARBfp1.0\n"
- "PARAM c[10] = { program.local[0..8],\n"
- " { 2, 4 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[3];\n"
- "MAD R0.xyz, fragment.position.x, c[2], R0;\n"
- "ADD R0.xyz, R0, c[4];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.xyxy;\n"
- "ADD R0.z, R0, R0.w;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.z, -R0, c[1].x;\n"
- "MUL R0.y, R0.x, c[9].x;\n"
- "MUL R0.z, R0, c[9].y;\n"
- "MAD R0.x, R0.y, R0.y, -R0.z;\n"
- "RSQ R0.z, R0.x;\n"
- "MOV R0.x, c[9];\n"
- "MUL R0.x, R0, c[1];\n"
- "RCP R0.z, R0.z;\n"
- "ADD R0.z, -R0.y, R0;\n"
- "RCP R0.w, R0.x;\n"
- "MUL R1.x, R0.z, R0.w;\n"
- "MUL R0.xy, fragment.position, c[6];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "TEX R1, R1, texture[2], 1D;\n"
- "ADD R2.xyz, R1, R0;\n"
- "MUL R3.xyz, R1.w, R0;\n"
- "MUL R1.xyz, R1, R0.w;\n"
- "MIN R1.xyz, R1, R3;\n"
- "MAD R2.xyz, -R1, c[9].x, R2;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[7];\n"
- "MUL R1.xy, R1, c[5];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[8];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_EXCLUSION =
- "!!ARBfp1.0\n"
- "PARAM c[10] = { program.local[0..8],\n"
- " { 2, 4, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[3];\n"
- "MAD R0.xyz, fragment.position.x, c[2], R0;\n"
- "ADD R0.xyz, R0, c[4];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.xyxy;\n"
- "ADD R0.z, R0, R0.w;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.z, -R0, c[1].x;\n"
- "MUL R0.y, R0.x, c[9].x;\n"
- "MUL R0.z, R0, c[9].y;\n"
- "MAD R0.x, R0.y, R0.y, -R0.z;\n"
- "RSQ R0.z, R0.x;\n"
- "MOV R0.x, c[9];\n"
- "MUL R0.x, R0, c[1];\n"
- "RCP R0.z, R0.z;\n"
- "ADD R0.z, -R0.y, R0;\n"
- "RCP R0.w, R0.x;\n"
- "MUL R1.x, R0.z, R0.w;\n"
- "MUL R0.xy, fragment.position, c[6];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "TEX R1, R1, texture[2], 1D;\n"
- "MUL R2.xyz, R1.w, R0;\n"
- "MAD R3.xyz, R1, R0.w, R2;\n"
- "MUL R2.xyz, R1, R0;\n"
- "MAD R2.xyz, -R2, c[9].x, R3;\n"
- "ADD R2.w, -R0, c[9].z;\n"
- "MAD R1.xyz, R1, R2.w, R2;\n"
- "ADD R2.x, -R1.w, c[9].z;\n"
- "MAD R2.xyz, R0, R2.x, R1;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[7];\n"
- "MUL R1.xy, R1, c[5];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[8];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_SIMPLE_PORTER_DUFF_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 2, 4, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[3];\n"
- "MAD R0.xyz, fragment.position.x, c[2], R0;\n"
- "ADD R0.xyz, R0, c[4];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.xyxy;\n"
- "ADD R0.z, R0, R0.w;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.z, -R0, c[1].x;\n"
- "MUL R0.y, R0.x, c[8].x;\n"
- "MUL R0.z, R0, c[8].y;\n"
- "MAD R0.x, R0.y, R0.y, -R0.z;\n"
- "RSQ R0.x, R0.x;\n"
- "RCP R0.z, R0.x;\n"
- "ADD R0.y, -R0, R0.z;\n"
- "MUL R0.zw, fragment.position.xyxy, c[7].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "MUL R2.xyz, R1, c[5].y;\n"
- "MOV R0.x, c[8];\n"
- "MUL R0.x, R0, c[1];\n"
- "RCP R0.x, R0.x;\n"
- "MUL R0.x, R0.y, R0;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "MUL R3.xyz, R0.w, R2;\n"
- "MUL R2.xyz, R0, c[5].x;\n"
- "MAD R2.xyz, R1.w, R2, R3;\n"
- "ADD R2.w, -R1, c[8].z;\n"
- "MUL R0.xyz, R0, c[6].y;\n"
- "MAD R0.xyz, R2.w, R0, R2;\n"
- "ADD R2.x, -R0.w, c[8].z;\n"
- "MUL R1.xyz, R1, c[6].z;\n"
- "MAD result.color.xyz, R2.x, R1, R0;\n"
- "MUL R0.x, R0.w, R1.w;\n"
- "MUL R0.z, R1.w, R2.x;\n"
- "MUL R0.y, R0.w, R2.w;\n"
- "DP3 result.color.w, R0, c[6];\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_MULTIPLY_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[7] = { program.local[0..5],\n"
- " { 2, 4, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "MUL R0.xyz, fragment.position.y, c[3];\n"
- "MAD R0.xyz, fragment.position.x, c[2], R0;\n"
- "ADD R0.xyz, R0, c[4];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.xyxy;\n"
- "ADD R0.z, R0, R0.w;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.z, -R0, c[1].x;\n"
- "MUL R0.y, R0.x, c[6].x;\n"
- "MUL R0.z, R0, c[6].y;\n"
- "MAD R0.x, R0.y, R0.y, -R0.z;\n"
- "RSQ R0.x, R0.x;\n"
- "RCP R0.z, R0.x;\n"
- "ADD R0.y, -R0, R0.z;\n"
- "MUL R0.zw, fragment.position.xyxy, c[5].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "MOV R0.x, c[6];\n"
- "MUL R0.x, R0, c[1];\n"
- "RCP R0.x, R0.x;\n"
- "MUL R0.x, R0.y, R0;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "ADD R2.x, -R1.w, c[6].z;\n"
- "MUL R2.xyz, R0, R2.x;\n"
- "MAD R0.xyz, R0, R1, R2;\n"
- "ADD R2.x, R0.w, R1.w;\n"
- "ADD R2.y, -R0.w, c[6].z;\n"
- "MAD result.color.xyz, R1, R2.y, R0;\n"
- "MAD result.color.w, -R0, R1, R2.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_SCREEN_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[7] = { program.local[0..5],\n"
- " { 2, 4 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "MUL R0.xyz, fragment.position.y, c[3];\n"
- "MAD R0.xyz, fragment.position.x, c[2], R0;\n"
- "ADD R0.xyz, R0, c[4];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.xyxy;\n"
- "ADD R0.z, R0, R0.w;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.z, -R0, c[1].x;\n"
- "MUL R0.y, R0.x, c[6].x;\n"
- "MUL R0.z, R0, c[6].y;\n"
- "MAD R0.x, R0.y, R0.y, -R0.z;\n"
- "RSQ R0.z, R0.x;\n"
- "MOV R0.x, c[6];\n"
- "MUL R0.w, R0.x, c[1].x;\n"
- "RCP R0.z, R0.z;\n"
- "ADD R0.x, -R0.y, R0.z;\n"
- "RCP R0.y, R0.w;\n"
- "MUL R0.zw, fragment.position.xyxy, c[5].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "MUL R0.x, R0, R0.y;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "ADD R2, R0, R1;\n"
- "MAD result.color, -R0, R1, R2;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_OVERLAY_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[7] = { program.local[0..5],\n"
- " { 2, 4, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[3];\n"
- "MAD R0.xyz, fragment.position.x, c[2], R0;\n"
- "ADD R0.xyz, R0, c[4];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.xyxy;\n"
- "ADD R0.z, R0, R0.w;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.y, R0.x, c[6].x;\n"
- "MOV R0.x, c[6];\n"
- "MUL R0.z, -R0, c[1].x;\n"
- "MUL R0.z, R0, c[6].y;\n"
- "MAD R0.z, R0.y, R0.y, -R0;\n"
- "MUL R1.xy, fragment.position, c[5];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "MUL R0.w, R0.x, c[1].x;\n"
- "RSQ R0.z, R0.z;\n"
- "RCP R0.x, R0.z;\n"
- "ADD R2.w, -R1, c[6].z;\n"
- "RCP R0.z, R0.w;\n"
- "ADD R0.x, -R0.y, R0;\n"
- "MUL R0.x, R0, R0.z;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "ADD R3.xyz, R0.w, -R0;\n"
- "ADD R2.xyz, R1.w, -R1;\n"
- "MUL R2.xyz, R2, R3;\n"
- "MUL R2.xyz, R2, c[6].x;\n"
- "MAD R2.xyz, R0.w, R1.w, -R2;\n"
- "MAD R2.xyz, R0, R2.w, R2;\n"
- "MUL R3.xyz, R0, R2.w;\n"
- "MUL R0.xyz, R0, R1;\n"
- "ADD R2.w, -R0, c[6].z;\n"
- "MAD R0.xyz, R0, c[6].x, R3;\n"
- "MAD R0.xyz, R1, R2.w, R0;\n"
- "MAD R2.xyz, R1, R2.w, R2;\n"
- "MUL R1.xyz, R1, c[6].x;\n"
- "ADD R2.w, R0, R1;\n"
- "ADD R2.xyz, R2, -R0;\n"
- "SGE R1.xyz, R1, R1.w;\n"
- "MAD result.color.xyz, R1, R2, R0;\n"
- "MAD result.color.w, -R0, R1, R2;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_DARKEN_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[7] = { program.local[0..5],\n"
- " { 2, 4, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[3];\n"
- "MAD R0.xyz, fragment.position.x, c[2], R0;\n"
- "ADD R0.xyz, R0, c[4];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.xyxy;\n"
- "ADD R0.z, R0, R0.w;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.z, -R0, c[1].x;\n"
- "MUL R0.y, R0.x, c[6].x;\n"
- "MUL R0.z, R0, c[6].y;\n"
- "MAD R0.x, R0.y, R0.y, -R0.z;\n"
- "RSQ R0.z, R0.x;\n"
- "MOV R0.x, c[6];\n"
- "MUL R0.w, R0.x, c[1].x;\n"
- "RCP R0.z, R0.z;\n"
- "ADD R0.x, -R0.y, R0.z;\n"
- "RCP R0.y, R0.w;\n"
- "MUL R0.zw, fragment.position.xyxy, c[5].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "MUL R0.x, R0, R0.y;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "MUL R2.xyz, R0, R1.w;\n"
- "MUL R3.xyz, R0.w, R1;\n"
- "MIN R2.xyz, R2, R3;\n"
- "ADD R2.w, -R1, c[6].z;\n"
- "MAD R0.xyz, R0, R2.w, R2;\n"
- "ADD R2.x, R0.w, R1.w;\n"
- "ADD R2.y, -R0.w, c[6].z;\n"
- "MAD result.color.xyz, R1, R2.y, R0;\n"
- "MAD result.color.w, -R0, R1, R2.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_LIGHTEN_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[7] = { program.local[0..5],\n"
- " { 2, 4, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[3];\n"
- "MAD R0.xyz, fragment.position.x, c[2], R0;\n"
- "ADD R0.xyz, R0, c[4];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.xyxy;\n"
- "ADD R0.z, R0, R0.w;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.z, -R0, c[1].x;\n"
- "MUL R0.y, R0.x, c[6].x;\n"
- "MUL R0.z, R0, c[6].y;\n"
- "MAD R0.x, R0.y, R0.y, -R0.z;\n"
- "RSQ R0.z, R0.x;\n"
- "MOV R0.x, c[6];\n"
- "MUL R0.w, R0.x, c[1].x;\n"
- "RCP R0.z, R0.z;\n"
- "ADD R0.x, -R0.y, R0.z;\n"
- "RCP R0.y, R0.w;\n"
- "MUL R0.zw, fragment.position.xyxy, c[5].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "MUL R0.x, R0, R0.y;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "MUL R2.xyz, R0, R1.w;\n"
- "MUL R3.xyz, R0.w, R1;\n"
- "MAX R2.xyz, R2, R3;\n"
- "ADD R2.w, -R1, c[6].z;\n"
- "MAD R0.xyz, R0, R2.w, R2;\n"
- "ADD R2.x, R0.w, R1.w;\n"
- "ADD R2.y, -R0.w, c[6].z;\n"
- "MAD result.color.xyz, R1, R2.y, R0;\n"
- "MAD result.color.w, -R0, R1, R2.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_COLORDODGE_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[7] = { program.local[0..5],\n"
- " { 2, 4, 1, 1e-006 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[3];\n"
- "MAD R0.xyz, fragment.position.x, c[2], R0;\n"
- "ADD R0.xyz, R0, c[4];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.xyxy;\n"
- "ADD R0.z, R0, R0.w;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.y, R0.x, c[6].x;\n"
- "MOV R0.x, c[6];\n"
- "MUL R0.z, -R0, c[1].x;\n"
- "MUL R0.z, R0, c[6].y;\n"
- "MAD R0.z, R0.y, R0.y, -R0;\n"
- "MUL R0.w, R0.x, c[1].x;\n"
- "RSQ R0.z, R0.z;\n"
- "RCP R0.x, R0.z;\n"
- "RCP R0.z, R0.w;\n"
- "ADD R0.x, -R0.y, R0;\n"
- "MUL R0.x, R0, R0.z;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "MAX R1.x, R0.w, c[6].w;\n"
- "RCP R1.x, R1.x;\n"
- "MAD R1.xyz, -R0, R1.x, c[6].z;\n"
- "MAX R2.xyz, R1, c[6].w;\n"
- "MUL R1.xy, fragment.position, c[5];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "ADD R2.w, -R0, c[6].z;\n"
- "MUL R3.xyz, R1, R2.w;\n"
- "ADD R2.w, -R1, c[6].z;\n"
- "MAD R3.xyz, R0, R2.w, R3;\n"
- "MUL R1.xyz, R0.w, R1;\n"
- "MAD R0.xyz, R0, R1.w, R1;\n"
- "MUL R2.w, R0, R1;\n"
- "RCP R2.x, R2.x;\n"
- "RCP R2.y, R2.y;\n"
- "RCP R2.z, R2.z;\n"
- "MAD R2.xyz, R1, R2, R3;\n"
- "MAD R3.xyz, R0.w, R1.w, R3;\n"
- "ADD R1.x, R0.w, R1.w;\n"
- "ADD R3.xyz, R3, -R2;\n"
- "SGE R0.xyz, R0, R2.w;\n"
- "MAD result.color.xyz, R0, R3, R2;\n"
- "MAD result.color.w, -R0, R1, R1.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_COLORBURN_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[7] = { program.local[0..5],\n"
- " { 2, 4, 1, 9.9999997e-006 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "TEMP R5;\n"
- "MUL R0.xyz, fragment.position.y, c[3];\n"
- "MAD R0.xyz, fragment.position.x, c[2], R0;\n"
- "ADD R0.xyz, R0, c[4];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.xyxy;\n"
- "ADD R0.z, R0, R0.w;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.z, -R0, c[1].x;\n"
- "MUL R0.y, R0.x, c[6].x;\n"
- "MUL R0.z, R0, c[6].y;\n"
- "MAD R0.x, R0.y, R0.y, -R0.z;\n"
- "RSQ R0.z, R0.x;\n"
- "MOV R0.x, c[6];\n"
- "MUL R0.w, R0.x, c[1].x;\n"
- "RCP R0.z, R0.z;\n"
- "ADD R0.x, -R0.y, R0.z;\n"
- "RCP R0.y, R0.w;\n"
- "MUL R0.zw, fragment.position.xyxy, c[5].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "MUL R0.x, R0, R0.y;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "MUL R2.xyz, R0.w, R1;\n"
- "MAD R3.xyz, R0, R1.w, R2;\n"
- "ADD R2.w, -R1, c[6].z;\n"
- "MAD R2.xyz, -R0.w, R1.w, R3;\n"
- "MUL R4.xyz, R0.w, R2;\n"
- "MAX R2.xyz, R0, c[6].w;\n"
- "MUL R5.xyz, R0, R2.w;\n"
- "ADD R3.w, -R0, c[6].z;\n"
- "RCP R2.x, R2.x;\n"
- "RCP R2.y, R2.y;\n"
- "RCP R2.z, R2.z;\n"
- "MAD R2.xyz, R4, R2, R5;\n"
- "MUL R4.xyz, R1, R3.w;\n"
- "MAD R1.xyz, R1, R3.w, R2;\n"
- "MAD R0.xyz, R0, R2.w, R4;\n"
- "MUL R2.x, R0.w, R1.w;\n"
- "ADD R2.w, R0, R1;\n"
- "ADD R1.xyz, R1, -R0;\n"
- "SGE R2.xyz, R3, R2.x;\n"
- "MAD result.color.xyz, R2, R1, R0;\n"
- "MAD result.color.w, -R0, R1, R2;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_HARDLIGHT_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[7] = { program.local[0..5],\n"
- " { 2, 4, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "MUL R0.xyz, fragment.position.y, c[3];\n"
- "MAD R0.xyz, fragment.position.x, c[2], R0;\n"
- "ADD R0.xyz, R0, c[4];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.xyxy;\n"
- "ADD R0.z, R0, R0.w;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.y, R0.x, c[6].x;\n"
- "MOV R0.x, c[6];\n"
- "MUL R0.z, -R0, c[1].x;\n"
- "MUL R0.z, R0, c[6].y;\n"
- "MAD R0.z, R0.y, R0.y, -R0;\n"
- "MUL R1.xy, fragment.position, c[5];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "MUL R0.w, R0.x, c[1].x;\n"
- "RSQ R0.z, R0.z;\n"
- "RCP R0.x, R0.z;\n"
- "ADD R2.w, -R1, c[6].z;\n"
- "RCP R0.z, R0.w;\n"
- "ADD R0.x, -R0.y, R0;\n"
- "MUL R0.x, R0, R0.z;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "ADD R3.xyz, R0.w, -R0;\n"
- "ADD R2.xyz, R1.w, -R1;\n"
- "MUL R2.xyz, R2, R3;\n"
- "MUL R2.xyz, R2, c[6].x;\n"
- "MAD R2.xyz, R0.w, R1.w, -R2;\n"
- "MUL R4.xyz, R0, R2.w;\n"
- "MUL R3.xyz, R0, R1;\n"
- "MAD R2.xyz, R0, R2.w, R2;\n"
- "ADD R2.w, -R0, c[6].z;\n"
- "MUL R0.xyz, R0, c[6].x;\n"
- "MAD R2.xyz, R1, R2.w, R2;\n"
- "MAD R3.xyz, R3, c[6].x, R4;\n"
- "MAD R1.xyz, R1, R2.w, R3;\n"
- "ADD R2.w, R0, R1;\n"
- "ADD R2.xyz, R2, -R1;\n"
- "SGE R0.xyz, R0, R0.w;\n"
- "MAD result.color.xyz, R0, R2, R1;\n"
- "MAD result.color.w, -R0, R1, R2;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_SOFTLIGHT_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[8] = { program.local[0..5],\n"
- " { 2, 4, 1, 9.9999997e-006 },\n"
- " { 16, 12, 3 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "TEMP R5;\n"
- "TEMP R6;\n"
- "MUL R0.xyz, fragment.position.y, c[3];\n"
- "MAD R0.xyz, fragment.position.x, c[2], R0;\n"
- "ADD R0.xyz, R0, c[4];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.xyxy;\n"
- "ADD R0.z, R0, R0.w;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.z, -R0, c[1].x;\n"
- "MUL R0.y, R0.z, c[6];\n"
- "MUL R0.x, R0, c[6];\n"
- "MUL R0.zw, fragment.position.xyxy, c[5].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "MAD R0.y, R0.x, R0.x, -R0;\n"
- "RSQ R0.y, R0.y;\n"
- "RCP R0.y, R0.y;\n"
- "ADD R0.y, -R0.x, R0;\n"
- "MOV R0.x, c[6];\n"
- "MUL R0.x, R0, c[1];\n"
- "MAX R0.z, R1.w, c[6].w;\n"
- "RCP R0.z, R0.z;\n"
- "MUL R3.xyz, R1, R0.z;\n"
- "MAD R4.xyz, R3, c[7].x, -c[7].y;\n"
- "RCP R0.x, R0.x;\n"
- "MUL R0.x, R0.y, R0;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "MAD R2.xyz, R0, c[6].x, -R0.w;\n"
- "MAD R4.xyz, R3, R4, c[7].z;\n"
- "MUL R5.xyz, R1.w, R2;\n"
- "MUL R6.xyz, R5, R4;\n"
- "RSQ R2.w, R3.x;\n"
- "RCP R4.x, R2.w;\n"
- "RSQ R2.w, R3.y;\n"
- "RSQ R3.w, R3.z;\n"
- "RCP R4.y, R2.w;\n"
- "RCP R4.z, R3.w;\n"
- "ADD R4.xyz, -R3, R4;\n"
- "MUL R6.xyz, R3, R6;\n"
- "MUL R4.xyz, R5, R4;\n"
- "ADD R3.xyz, -R3, c[6].z;\n"
- "MAD R2.xyz, R2, R3, R0.w;\n"
- "MUL R3.xyz, R0, c[6].x;\n"
- "MAD R5.xyz, R0.w, R1, R6;\n"
- "MAD R4.xyz, R0.w, R1, R4;\n"
- "ADD R6.xyz, R4, -R5;\n"
- "MUL R4.xyz, R1, c[6].y;\n"
- "SGE R4.xyz, R4, R1.w;\n"
- "MAD R4.xyz, R4, R6, R5;\n"
- "MAD R4.xyz, -R1, R2, R4;\n"
- "MUL R2.xyz, R1, R2;\n"
- "SGE R3.xyz, R3, R0.w;\n"
- "MAD R2.xyz, R3, R4, R2;\n"
- "ADD R2.w, -R1, c[6].z;\n"
- "MAD R2.xyz, R0, R2.w, R2;\n"
- "ADD R0.x, R0.w, R1.w;\n"
- "ADD R0.y, -R0.w, c[6].z;\n"
- "MAD result.color.xyz, R1, R0.y, R2;\n"
- "MAD result.color.w, -R0, R1, R0.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_DIFFERENCE_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[7] = { program.local[0..5],\n"
- " { 2, 4 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[3];\n"
- "MAD R0.xyz, fragment.position.x, c[2], R0;\n"
- "ADD R0.xyz, R0, c[4];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.xyxy;\n"
- "ADD R0.z, R0, R0.w;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.z, -R0, c[1].x;\n"
- "MUL R0.y, R0.x, c[6].x;\n"
- "MUL R0.z, R0, c[6].y;\n"
- "MAD R0.x, R0.y, R0.y, -R0.z;\n"
- "RSQ R0.z, R0.x;\n"
- "MOV R0.x, c[6];\n"
- "MUL R0.w, R0.x, c[1].x;\n"
- "RCP R0.z, R0.z;\n"
- "ADD R0.x, -R0.y, R0.z;\n"
- "RCP R0.y, R0.w;\n"
- "MUL R0.zw, fragment.position.xyxy, c[5].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "MUL R0.x, R0, R0.y;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "MUL R2.xyz, R0, R1.w;\n"
- "MUL R3.xyz, R0.w, R1;\n"
- "ADD R0.xyz, R0, R1;\n"
- "MIN R2.xyz, R2, R3;\n"
- "ADD R1.x, R0.w, R1.w;\n"
- "MAD result.color.xyz, -R2, c[6].x, R0;\n"
- "MAD result.color.w, -R0, R1, R1.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_EXCLUSION_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[7] = { program.local[0..5],\n"
- " { 2, 4, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[3];\n"
- "MAD R0.xyz, fragment.position.x, c[2], R0;\n"
- "ADD R0.xyz, R0, c[4];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.xyxy;\n"
- "ADD R0.z, R0, R0.w;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.z, -R0, c[1].x;\n"
- "MUL R0.y, R0.x, c[6].x;\n"
- "MUL R0.z, R0, c[6].y;\n"
- "MAD R0.x, R0.y, R0.y, -R0.z;\n"
- "RSQ R0.z, R0.x;\n"
- "MOV R0.x, c[6];\n"
- "MUL R0.w, R0.x, c[1].x;\n"
- "RCP R0.z, R0.z;\n"
- "ADD R0.x, -R0.y, R0.z;\n"
- "RCP R0.y, R0.w;\n"
- "MUL R0.zw, fragment.position.xyxy, c[5].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "MUL R0.x, R0, R0.y;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "MUL R2.xyz, R0.w, R1;\n"
- "MAD R3.xyz, R0, R1.w, R2;\n"
- "MUL R2.xyz, R0, R1;\n"
- "MAD R2.xyz, -R2, c[6].x, R3;\n"
- "ADD R2.w, -R1, c[6].z;\n"
- "MAD R0.xyz, R0, R2.w, R2;\n"
- "ADD R2.x, R0.w, R1.w;\n"
- "ADD R2.y, -R0.w, c[6].z;\n"
- "MAD result.color.xyz, R1, R2.y, R0;\n"
- "MAD result.color.w, -R0, R1, R2.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODE_BLEND_MODE_MASK =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 2, 4 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "MUL R0.xyz, fragment.position.y, c[3];\n"
- "MAD R0.xyz, fragment.position.x, c[2], R0;\n"
- "ADD R0.xyz, R0, c[4];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.xyxy;\n"
- "ADD R0.z, R0, R0.w;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.z, -R0, c[1].x;\n"
- "MUL R0.y, R0.z, c[8];\n"
- "MUL R0.x, R0, c[8];\n"
- "MAD R0.y, R0.x, R0.x, -R0;\n"
- "RSQ R0.y, R0.y;\n"
- "RCP R0.y, R0.y;\n"
- "ADD R1.x, -R0, R0.y;\n"
- "MOV R0.x, c[8];\n"
- "MUL R0.x, R0, c[1];\n"
- "RCP R1.y, R0.x;\n"
- "ADD R0.zw, fragment.position.xyxy, c[6].xyxy;\n"
- "MUL R0.zw, R0, c[5].xyxy;\n"
- "TEX R0, R0.zwzw, texture[0], 2D;\n"
- "MUL R1.x, R1, R1.y;\n"
- "DP4 R1.y, R0, c[7];\n"
- "TEX R0, R1, texture[1], 1D;\n"
- "MUL result.color, R0, R1.y;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODE_BLEND_MODE_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 2, 4 } };\n"
- "TEMP R0;\n"
- "MUL R0.xyz, fragment.position.y, c[3];\n"
- "MAD R0.xyz, fragment.position.x, c[2], R0;\n"
- "ADD R0.xyz, R0, c[4];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.xyxy;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.z, R0, R0.w;\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.z, -R0, c[1].x;\n"
- "MUL R0.y, R0.z, c[5];\n"
- "MUL R0.x, R0, c[5];\n"
- "MAD R0.z, R0.x, R0.x, -R0.y;\n"
- "MOV R0.y, c[5].x;\n"
- "RSQ R0.z, R0.z;\n"
- "MUL R0.w, R0.y, c[1].x;\n"
- "RCP R0.y, R0.z;\n"
- "RCP R0.z, R0.w;\n"
- "ADD R0.x, -R0, R0.y;\n"
- "MUL R0.x, R0, R0.z;\n"
- "TEX result.color, R0, texture[0], 1D;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_SIMPLE_PORTER_DUFF =
- "!!ARBfp1.0\n"
- "PARAM c[13] = { program.local[0..9],\n"
- " { 0.15915494, 0.0020000001, 3.141593, 1.570796 },\n"
- " { -0.01348047, 0.05747731, 0.1212391, 0.1956359 },\n"
- " { 0.33299461, 0.99999559, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "ABS R0.z, R0.x;\n"
- "ABS R0.w, R0.y;\n"
- "ADD R0.w, R0, -R0.z;\n"
- "ADD R1.x, R0.y, c[10].y;\n"
- "ABS R0.w, R0;\n"
- "CMP R0.y, -R0.w, R0, R1.x;\n"
- "ABS R0.w, -R0.y;\n"
- "MAX R1.x, R0.z, R0.w;\n"
- "RCP R1.y, R1.x;\n"
- "MIN R1.x, R0.z, R0.w;\n"
- "MUL R1.x, R1, R1.y;\n"
- "MUL R1.y, R1.x, R1.x;\n"
- "MAD R1.z, R1.y, c[11].x, c[11].y;\n"
- "MAD R1.z, R1, R1.y, -c[11];\n"
- "MAD R1.z, R1, R1.y, c[11].w;\n"
- "MAD R1.z, R1, R1.y, -c[12].x;\n"
- "MAD R1.y, R1.z, R1, c[12];\n"
- "MUL R1.x, R1.y, R1;\n"
- "ADD R1.y, -R1.x, c[10].w;\n"
- "ADD R0.z, -R0, R0.w;\n"
- "CMP R0.z, -R0, R1.y, R1.x;\n"
- "ADD R0.w, -R0.z, c[10].z;\n"
- "CMP R0.x, R0, R0.w, R0.z;\n"
- "CMP R0.x, -R0.y, -R0, R0;\n"
- "ADD R0.x, R0, c[0];\n"
- "MUL R1.x, R0, c[10];\n"
- "FLR R1.y, R1.x;\n"
- "MUL R0.xy, fragment.position, c[7];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "ADD R1.x, R1, -R1.y;\n"
- "TEX R1, R1, texture[2], 1D;\n"
- "MUL R2.xyz, R0, c[4].y;\n"
- "MUL R3.xyz, R1.w, R2;\n"
- "MUL R2.xyz, R1, c[4].x;\n"
- "MAD R2.xyz, R0.w, R2, R3;\n"
- "ADD R3.xy, fragment.position, c[8];\n"
- "ADD R2.w, -R0, c[12].z;\n"
- "MUL R1.xyz, R1, c[5].y;\n"
- "MAD R2.xyz, R2.w, R1, R2;\n"
- "MUL R1.xyz, R0, c[5].z;\n"
- "ADD R3.z, -R1.w, c[12];\n"
- "MAD R2.xyz, R3.z, R1, R2;\n"
- "MUL R1.y, R1.w, R2.w;\n"
- "MUL R1.x, R1.w, R0.w;\n"
- "MUL R1.z, R0.w, R3;\n"
- "DP3 R2.w, R1, c[5];\n"
- "MUL R3.xy, R3, c[6];\n"
- "TEX R1, R3, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[9];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_MULTIPLY =
- "!!ARBfp1.0\n"
- "PARAM c[11] = { program.local[0..7],\n"
- " { 0.15915494, 0.0020000001, 3.141593, 1.570796 },\n"
- " { -0.01348047, 0.05747731, 0.1212391, 0.1956359 },\n"
- " { 0.33299461, 0.99999559, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "ABS R0.z, R0.x;\n"
- "ABS R0.w, R0.y;\n"
- "ADD R0.w, R0, -R0.z;\n"
- "ADD R1.x, R0.y, c[8].y;\n"
- "ABS R0.w, R0;\n"
- "CMP R0.y, -R0.w, R0, R1.x;\n"
- "ABS R0.w, -R0.y;\n"
- "MAX R1.x, R0.z, R0.w;\n"
- "RCP R1.y, R1.x;\n"
- "MIN R1.x, R0.z, R0.w;\n"
- "MUL R1.x, R1, R1.y;\n"
- "MUL R1.y, R1.x, R1.x;\n"
- "MAD R1.z, R1.y, c[9].x, c[9].y;\n"
- "MAD R1.z, R1, R1.y, -c[9];\n"
- "MAD R1.z, R1, R1.y, c[9].w;\n"
- "MAD R1.z, R1, R1.y, -c[10].x;\n"
- "MAD R1.y, R1.z, R1, c[10];\n"
- "MUL R1.x, R1.y, R1;\n"
- "ADD R1.y, -R1.x, c[8].w;\n"
- "ADD R0.z, -R0, R0.w;\n"
- "CMP R0.z, -R0, R1.y, R1.x;\n"
- "ADD R0.w, -R0.z, c[8].z;\n"
- "CMP R0.x, R0, R0.w, R0.z;\n"
- "CMP R0.x, -R0.y, -R0, R0;\n"
- "ADD R0.x, R0, c[0];\n"
- "MUL R1.x, R0, c[8];\n"
- "FLR R1.y, R1.x;\n"
- "MUL R0.xy, fragment.position, c[5];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "ADD R1.x, R1, -R1.y;\n"
- "TEX R1, R1, texture[2], 1D;\n"
- "ADD R2.x, -R0.w, c[10].z;\n"
- "MUL R2.xyz, R1, R2.x;\n"
- "MAD R1.xyz, R1, R0, R2;\n"
- "ADD R2.x, -R1.w, c[10].z;\n"
- "MAD R2.xyz, R0, R2.x, R1;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[6];\n"
- "MUL R1.xy, R1, c[4];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_SCREEN =
- "!!ARBfp1.0\n"
- "PARAM c[11] = { program.local[0..7],\n"
- " { 0.15915494, 0.0020000001, 3.141593, 1.570796 },\n"
- " { -0.01348047, 0.05747731, 0.1212391, 0.1956359 },\n"
- " { 0.33299461, 0.99999559 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "ADD R3.xy, fragment.position, c[6];\n"
- "ABS R0.z, R0.x;\n"
- "ABS R0.w, R0.y;\n"
- "ADD R0.w, R0, -R0.z;\n"
- "ADD R1.x, R0.y, c[8].y;\n"
- "ABS R0.w, R0;\n"
- "CMP R0.y, -R0.w, R0, R1.x;\n"
- "ABS R0.w, -R0.y;\n"
- "MAX R1.x, R0.z, R0.w;\n"
- "RCP R1.y, R1.x;\n"
- "MIN R1.x, R0.z, R0.w;\n"
- "MUL R1.x, R1, R1.y;\n"
- "MUL R1.y, R1.x, R1.x;\n"
- "MAD R1.z, R1.y, c[9].x, c[9].y;\n"
- "MAD R1.z, R1, R1.y, -c[9];\n"
- "MAD R1.z, R1, R1.y, c[9].w;\n"
- "MAD R1.z, R1, R1.y, -c[10].x;\n"
- "MAD R1.y, R1.z, R1, c[10];\n"
- "MUL R1.x, R1.y, R1;\n"
- "ADD R0.z, -R0, R0.w;\n"
- "ADD R1.y, -R1.x, c[8].w;\n"
- "CMP R0.z, -R0, R1.y, R1.x;\n"
- "ADD R0.w, -R0.z, c[8].z;\n"
- "CMP R0.x, R0, R0.w, R0.z;\n"
- "CMP R0.x, -R0.y, -R0, R0;\n"
- "ADD R0.x, R0, c[0];\n"
- "MUL R0.x, R0, c[8];\n"
- "FLR R0.y, R0.x;\n"
- "ADD R0.z, R0.x, -R0.y;\n"
- "TEX R1, R0.z, texture[2], 1D;\n"
- "MUL R0.xy, fragment.position, c[5];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "ADD R2, R1, R0;\n"
- "MAD R2, -R1, R0, R2;\n"
- "MUL R3.xy, R3, c[4];\n"
- "TEX R1, R3, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_OVERLAY =
- "!!ARBfp1.0\n"
- "PARAM c[11] = { program.local[0..7],\n"
- " { 0.0020000001, -0.01348047, 0.05747731, 0.1212391 },\n"
- " { 0.1956359, 0.33299461, 0.99999559, 1.570796 },\n"
- " { 3.141593, 0.15915494, 2, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "ABS R0.z, R0.x;\n"
- "ABS R0.w, R0.y;\n"
- "ADD R0.w, R0, -R0.z;\n"
- "ADD R1.x, R0.y, c[8];\n"
- "ABS R0.w, R0;\n"
- "CMP R0.y, -R0.w, R0, R1.x;\n"
- "ABS R0.w, -R0.y;\n"
- "MAX R1.x, R0.z, R0.w;\n"
- "RCP R1.y, R1.x;\n"
- "MIN R1.x, R0.z, R0.w;\n"
- "MUL R1.x, R1, R1.y;\n"
- "MUL R1.y, R1.x, R1.x;\n"
- "MAD R1.z, R1.y, c[8].y, c[8];\n"
- "MAD R1.z, R1, R1.y, -c[8].w;\n"
- "MAD R1.z, R1, R1.y, c[9].x;\n"
- "MAD R1.z, R1, R1.y, -c[9].y;\n"
- "MAD R1.y, R1.z, R1, c[9].z;\n"
- "MUL R1.x, R1.y, R1;\n"
- "ADD R0.z, -R0, R0.w;\n"
- "ADD R1.y, -R1.x, c[9].w;\n"
- "CMP R0.z, -R0, R1.y, R1.x;\n"
- "ADD R0.w, -R0.z, c[10].x;\n"
- "CMP R0.x, R0, R0.w, R0.z;\n"
- "CMP R0.x, -R0.y, -R0, R0;\n"
- "ADD R0.x, R0, c[0];\n"
- "MUL R0.x, R0, c[10].y;\n"
- "FLR R0.y, R0.x;\n"
- "ADD R0.x, R0, -R0.y;\n"
- "TEX R0, R0, texture[2], 1D;\n"
- "MUL R1.xy, fragment.position, c[5];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "ADD R2.w, -R1, c[10];\n"
- "ADD R3.xyz, R0.w, -R0;\n"
- "ADD R2.xyz, R1.w, -R1;\n"
- "MUL R2.xyz, R2, R3;\n"
- "MUL R2.xyz, R2, c[10].z;\n"
- "MAD R2.xyz, R0.w, R1.w, -R2;\n"
- "MUL R4.xyz, R0, R2.w;\n"
- "MUL R3.xyz, R0, R1;\n"
- "MAD R0.xyz, R0, R2.w, R2;\n"
- "ADD R2.x, -R0.w, c[10].w;\n"
- "MAD R3.xyz, R3, c[10].z, R4;\n"
- "MAD R3.xyz, R1, R2.x, R3;\n"
- "MAD R0.xyz, R1, R2.x, R0;\n"
- "MUL R2.xyz, R1, c[10].z;\n"
- "ADD R0.xyz, R0, -R3;\n"
- "SGE R2.xyz, R2, R1.w;\n"
- "MAD R2.xyz, R2, R0, R3;\n"
- "ADD R0.z, R0.w, R1.w;\n"
- "MAD R2.w, -R0, R1, R0.z;\n"
- "ADD R0.xy, fragment.position, c[6];\n"
- "MUL R0.xy, R0, c[4];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "ADD R2, R2, -R1;\n"
- "DP4 R0.x, R0, c[7];\n"
- "MAD result.color, R0.x, R2, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_DARKEN =
- "!!ARBfp1.0\n"
- "PARAM c[11] = { program.local[0..7],\n"
- " { 0.15915494, 0.0020000001, 3.141593, 1.570796 },\n"
- " { -0.01348047, 0.05747731, 0.1212391, 0.1956359 },\n"
- " { 0.33299461, 0.99999559, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "ABS R0.z, R0.x;\n"
- "ABS R0.w, R0.y;\n"
- "ADD R0.w, R0, -R0.z;\n"
- "ADD R1.x, R0.y, c[8].y;\n"
- "ABS R0.w, R0;\n"
- "CMP R0.y, -R0.w, R0, R1.x;\n"
- "ABS R0.w, -R0.y;\n"
- "MAX R1.x, R0.z, R0.w;\n"
- "RCP R1.y, R1.x;\n"
- "MIN R1.x, R0.z, R0.w;\n"
- "MUL R1.x, R1, R1.y;\n"
- "MUL R1.y, R1.x, R1.x;\n"
- "MAD R1.z, R1.y, c[9].x, c[9].y;\n"
- "MAD R1.z, R1, R1.y, -c[9];\n"
- "MAD R1.z, R1, R1.y, c[9].w;\n"
- "MAD R1.z, R1, R1.y, -c[10].x;\n"
- "MAD R1.y, R1.z, R1, c[10];\n"
- "MUL R1.x, R1.y, R1;\n"
- "ADD R1.y, -R1.x, c[8].w;\n"
- "ADD R0.z, -R0, R0.w;\n"
- "CMP R0.z, -R0, R1.y, R1.x;\n"
- "ADD R0.w, -R0.z, c[8].z;\n"
- "CMP R0.x, R0, R0.w, R0.z;\n"
- "CMP R0.x, -R0.y, -R0, R0;\n"
- "ADD R0.x, R0, c[0];\n"
- "MUL R0.z, R0.x, c[8].x;\n"
- "FLR R0.w, R0.z;\n"
- "ADD R1.x, R0.z, -R0.w;\n"
- "MUL R0.xy, fragment.position, c[5];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "TEX R1, R1, texture[2], 1D;\n"
- "MUL R3.xyz, R1.w, R0;\n"
- "MUL R2.xyz, R1, R0.w;\n"
- "MIN R2.xyz, R2, R3;\n"
- "ADD R2.w, -R0, c[10].z;\n"
- "MAD R1.xyz, R1, R2.w, R2;\n"
- "ADD R2.x, -R1.w, c[10].z;\n"
- "MAD R2.xyz, R0, R2.x, R1;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[6];\n"
- "MUL R1.xy, R1, c[4];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_LIGHTEN =
- "!!ARBfp1.0\n"
- "PARAM c[11] = { program.local[0..7],\n"
- " { 0.15915494, 0.0020000001, 3.141593, 1.570796 },\n"
- " { -0.01348047, 0.05747731, 0.1212391, 0.1956359 },\n"
- " { 0.33299461, 0.99999559, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "ABS R0.z, R0.x;\n"
- "ABS R0.w, R0.y;\n"
- "ADD R0.w, R0, -R0.z;\n"
- "ADD R1.x, R0.y, c[8].y;\n"
- "ABS R0.w, R0;\n"
- "CMP R0.y, -R0.w, R0, R1.x;\n"
- "ABS R0.w, -R0.y;\n"
- "MAX R1.x, R0.z, R0.w;\n"
- "RCP R1.y, R1.x;\n"
- "MIN R1.x, R0.z, R0.w;\n"
- "MUL R1.x, R1, R1.y;\n"
- "MUL R1.y, R1.x, R1.x;\n"
- "MAD R1.z, R1.y, c[9].x, c[9].y;\n"
- "MAD R1.z, R1, R1.y, -c[9];\n"
- "MAD R1.z, R1, R1.y, c[9].w;\n"
- "MAD R1.z, R1, R1.y, -c[10].x;\n"
- "MAD R1.y, R1.z, R1, c[10];\n"
- "MUL R1.x, R1.y, R1;\n"
- "ADD R1.y, -R1.x, c[8].w;\n"
- "ADD R0.z, -R0, R0.w;\n"
- "CMP R0.z, -R0, R1.y, R1.x;\n"
- "ADD R0.w, -R0.z, c[8].z;\n"
- "CMP R0.x, R0, R0.w, R0.z;\n"
- "CMP R0.x, -R0.y, -R0, R0;\n"
- "ADD R0.x, R0, c[0];\n"
- "MUL R0.z, R0.x, c[8].x;\n"
- "FLR R0.w, R0.z;\n"
- "ADD R1.x, R0.z, -R0.w;\n"
- "MUL R0.xy, fragment.position, c[5];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "TEX R1, R1, texture[2], 1D;\n"
- "MUL R3.xyz, R1.w, R0;\n"
- "MUL R2.xyz, R1, R0.w;\n"
- "MAX R2.xyz, R2, R3;\n"
- "ADD R2.w, -R0, c[10].z;\n"
- "MAD R1.xyz, R1, R2.w, R2;\n"
- "ADD R2.x, -R1.w, c[10].z;\n"
- "MAD R2.xyz, R0, R2.x, R1;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[6];\n"
- "MUL R1.xy, R1, c[4];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_COLORDODGE =
- "!!ARBfp1.0\n"
- "PARAM c[11] = { program.local[0..7],\n"
- " { 0.0020000001, -0.01348047, 0.05747731, 0.1212391 },\n"
- " { 0.1956359, 0.33299461, 0.99999559, 1.570796 },\n"
- " { 3.141593, 0.15915494, 1, 1e-006 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "ABS R0.z, R0.x;\n"
- "ABS R0.w, R0.y;\n"
- "ADD R0.w, R0, -R0.z;\n"
- "ADD R1.x, R0.y, c[8];\n"
- "ABS R0.w, R0;\n"
- "CMP R0.y, -R0.w, R0, R1.x;\n"
- "ABS R0.w, -R0.y;\n"
- "MAX R1.x, R0.z, R0.w;\n"
- "RCP R1.y, R1.x;\n"
- "MIN R1.x, R0.z, R0.w;\n"
- "MUL R1.x, R1, R1.y;\n"
- "MUL R1.y, R1.x, R1.x;\n"
- "MAD R1.z, R1.y, c[8].y, c[8];\n"
- "MAD R1.z, R1, R1.y, -c[8].w;\n"
- "MAD R1.z, R1, R1.y, c[9].x;\n"
- "MAD R1.z, R1, R1.y, -c[9].y;\n"
- "MAD R1.y, R1.z, R1, c[9].z;\n"
- "MUL R1.x, R1.y, R1;\n"
- "ADD R1.y, -R1.x, c[9].w;\n"
- "ADD R0.z, -R0, R0.w;\n"
- "CMP R0.z, -R0, R1.y, R1.x;\n"
- "ADD R0.w, -R0.z, c[10].x;\n"
- "CMP R0.x, R0, R0.w, R0.z;\n"
- "CMP R0.x, -R0.y, -R0, R0;\n"
- "ADD R0.x, R0, c[0];\n"
- "MUL R0.x, R0, c[10].y;\n"
- "FLR R0.y, R0.x;\n"
- "ADD R0.x, R0, -R0.y;\n"
- "TEX R0, R0, texture[2], 1D;\n"
- "MAX R1.x, R0.w, c[10].w;\n"
- "RCP R1.x, R1.x;\n"
- "MAD R1.xyz, -R0, R1.x, c[10].z;\n"
- "MAX R2.xyz, R1, c[10].w;\n"
- "MUL R1.xy, fragment.position, c[5];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "ADD R2.w, -R0, c[10].z;\n"
- "MUL R3.xyz, R1, R2.w;\n"
- "ADD R2.w, -R1, c[10].z;\n"
- "MAD R4.xyz, R0, R2.w, R3;\n"
- "MUL R3.xyz, R0.w, R1;\n"
- "MUL R2.w, R0, R1;\n"
- "MAD R0.xyz, R0, R1.w, R3;\n"
- "SGE R0.xyz, R0, R2.w;\n"
- "RCP R2.x, R2.x;\n"
- "RCP R2.y, R2.y;\n"
- "RCP R2.z, R2.z;\n"
- "MAD R2.xyz, R3, R2, R4;\n"
- "MAD R4.xyz, R0.w, R1.w, R4;\n"
- "ADD R4.xyz, R4, -R2;\n"
- "MAD R2.xyz, R0, R4, R2;\n"
- "ADD R0.z, R0.w, R1.w;\n"
- "MAD R2.w, -R0, R1, R0.z;\n"
- "ADD R0.xy, fragment.position, c[6];\n"
- "MUL R0.xy, R0, c[4];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "ADD R2, R2, -R1;\n"
- "DP4 R0.x, R0, c[7];\n"
- "MAD result.color, R0.x, R2, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_COLORBURN =
- "!!ARBfp1.0\n"
- "PARAM c[11] = { program.local[0..7],\n"
- " { 0.0020000001, -0.01348047, 0.05747731, 0.1212391 },\n"
- " { 0.1956359, 0.33299461, 0.99999559, 1.570796 },\n"
- " { 3.141593, 0.15915494, 1, 9.9999997e-006 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "TEMP R5;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "ABS R0.w, R0.x;\n"
- "ABS R0.z, R0.y;\n"
- "ADD R0.z, R0, -R0.w;\n"
- "ADD R1.x, R0.y, c[8];\n"
- "ABS R0.z, R0;\n"
- "CMP R0.y, -R0.z, R0, R1.x;\n"
- "ABS R0.z, -R0.y;\n"
- "MAX R1.x, R0.w, R0.z;\n"
- "RCP R1.y, R1.x;\n"
- "MIN R1.x, R0.w, R0.z;\n"
- "MUL R1.x, R1, R1.y;\n"
- "MUL R1.y, R1.x, R1.x;\n"
- "MAD R1.z, R1.y, c[8].y, c[8];\n"
- "MAD R1.z, R1, R1.y, -c[8].w;\n"
- "MAD R1.z, R1, R1.y, c[9].x;\n"
- "MAD R1.z, R1, R1.y, -c[9].y;\n"
- "MAD R1.y, R1.z, R1, c[9].z;\n"
- "MUL R1.x, R1.y, R1;\n"
- "ADD R1.y, -R1.x, c[9].w;\n"
- "ADD R0.z, -R0.w, R0;\n"
- "CMP R0.z, -R0, R1.y, R1.x;\n"
- "ADD R0.w, -R0.z, c[10].x;\n"
- "CMP R0.x, R0, R0.w, R0.z;\n"
- "CMP R0.x, -R0.y, -R0, R0;\n"
- "MUL R0.zw, fragment.position.xyxy, c[5].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "ADD R0.x, R0, c[0];\n"
- "MUL R0.x, R0, c[10].y;\n"
- "FLR R0.y, R0.x;\n"
- "ADD R0.x, R0, -R0.y;\n"
- "TEX R0, R0, texture[2], 1D;\n"
- "MUL R2.xyz, R0.w, R1;\n"
- "MAD R3.xyz, R0, R1.w, R2;\n"
- "MAD R2.xyz, -R0.w, R1.w, R3;\n"
- "MUL R4.xyz, R0.w, R2;\n"
- "MAX R2.xyz, R0, c[10].w;\n"
- "ADD R2.w, -R1, c[10].z;\n"
- "ADD R3.w, -R0, c[10].z;\n"
- "MUL R5.xyz, R0, R2.w;\n"
- "RCP R2.x, R2.x;\n"
- "RCP R2.y, R2.y;\n"
- "RCP R2.z, R2.z;\n"
- "MAD R2.xyz, R4, R2, R5;\n"
- "MUL R4.xyz, R1, R3.w;\n"
- "MAD R0.xyz, R0, R2.w, R4;\n"
- "MUL R2.w, R0, R1;\n"
- "MAD R2.xyz, R1, R3.w, R2;\n"
- "ADD R2.xyz, R2, -R0;\n"
- "SGE R3.xyz, R3, R2.w;\n"
- "MAD R2.xyz, R3, R2, R0;\n"
- "ADD R0.z, R0.w, R1.w;\n"
- "MAD R2.w, -R0, R1, R0.z;\n"
- "ADD R0.xy, fragment.position, c[6];\n"
- "MUL R0.xy, R0, c[4];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "ADD R2, R2, -R1;\n"
- "DP4 R0.x, R0, c[7];\n"
- "MAD result.color, R0.x, R2, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_HARDLIGHT =
- "!!ARBfp1.0\n"
- "PARAM c[11] = { program.local[0..7],\n"
- " { 0.0020000001, -0.01348047, 0.05747731, 0.1212391 },\n"
- " { 0.1956359, 0.33299461, 0.99999559, 1.570796 },\n"
- " { 3.141593, 0.15915494, 2, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "ABS R0.z, R0.x;\n"
- "ABS R0.w, R0.y;\n"
- "ADD R0.w, R0, -R0.z;\n"
- "ADD R1.x, R0.y, c[8];\n"
- "ABS R0.w, R0;\n"
- "CMP R0.y, -R0.w, R0, R1.x;\n"
- "ABS R0.w, -R0.y;\n"
- "MAX R1.x, R0.z, R0.w;\n"
- "RCP R1.y, R1.x;\n"
- "MIN R1.x, R0.z, R0.w;\n"
- "MUL R1.x, R1, R1.y;\n"
- "MUL R1.y, R1.x, R1.x;\n"
- "MAD R1.z, R1.y, c[8].y, c[8];\n"
- "MAD R1.z, R1, R1.y, -c[8].w;\n"
- "MAD R1.z, R1, R1.y, c[9].x;\n"
- "MAD R1.z, R1, R1.y, -c[9].y;\n"
- "MAD R1.y, R1.z, R1, c[9].z;\n"
- "MUL R1.x, R1.y, R1;\n"
- "ADD R0.z, -R0, R0.w;\n"
- "ADD R1.y, -R1.x, c[9].w;\n"
- "CMP R0.z, -R0, R1.y, R1.x;\n"
- "ADD R0.w, -R0.z, c[10].x;\n"
- "CMP R0.x, R0, R0.w, R0.z;\n"
- "CMP R0.x, -R0.y, -R0, R0;\n"
- "ADD R0.x, R0, c[0];\n"
- "MUL R0.x, R0, c[10].y;\n"
- "FLR R0.y, R0.x;\n"
- "ADD R0.x, R0, -R0.y;\n"
- "TEX R0, R0, texture[2], 1D;\n"
- "MUL R1.xy, fragment.position, c[5];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "ADD R2.w, -R1, c[10];\n"
- "ADD R3.xyz, R0.w, -R0;\n"
- "ADD R2.xyz, R1.w, -R1;\n"
- "MUL R2.xyz, R2, R3;\n"
- "MUL R2.xyz, R2, c[10].z;\n"
- "MAD R2.xyz, R0.w, R1.w, -R2;\n"
- "MUL R4.xyz, R0, R2.w;\n"
- "MAD R2.xyz, R0, R2.w, R2;\n"
- "MUL R3.xyz, R0, R1;\n"
- "ADD R2.w, -R0, c[10];\n"
- "MAD R3.xyz, R3, c[10].z, R4;\n"
- "MUL R0.xyz, R0, c[10].z;\n"
- "SGE R0.xyz, R0, R0.w;\n"
- "MAD R3.xyz, R1, R2.w, R3;\n"
- "MAD R2.xyz, R1, R2.w, R2;\n"
- "ADD R2.xyz, R2, -R3;\n"
- "MAD R2.xyz, R0, R2, R3;\n"
- "ADD R0.z, R0.w, R1.w;\n"
- "MAD R2.w, -R0, R1, R0.z;\n"
- "ADD R0.xy, fragment.position, c[6];\n"
- "MUL R0.xy, R0, c[4];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "ADD R2, R2, -R1;\n"
- "DP4 R0.x, R0, c[7];\n"
- "MAD result.color, R0.x, R2, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_SOFTLIGHT =
- "!!ARBfp1.0\n"
- "PARAM c[13] = { program.local[0..7],\n"
- " { 0.0020000001, -0.01348047, 0.05747731, 0.1212391 },\n"
- " { 0.1956359, 0.33299461, 0.99999559, 1.570796 },\n"
- " { 3.141593, 0.15915494, 1, 2 },\n"
- " { 9.9999997e-006, 4, 16, 12 },\n"
- " { 3 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "TEMP R5;\n"
- "TEMP R6;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "ABS R0.w, R0.x;\n"
- "ABS R0.z, R0.y;\n"
- "ADD R0.z, R0, -R0.w;\n"
- "ADD R1.x, R0.y, c[8];\n"
- "ABS R0.z, R0;\n"
- "CMP R0.y, -R0.z, R0, R1.x;\n"
- "ABS R0.z, -R0.y;\n"
- "MAX R1.x, R0.w, R0.z;\n"
- "RCP R1.y, R1.x;\n"
- "MIN R1.x, R0.w, R0.z;\n"
- "MUL R1.x, R1, R1.y;\n"
- "MUL R1.y, R1.x, R1.x;\n"
- "MAD R1.z, R1.y, c[8].y, c[8];\n"
- "MAD R1.z, R1, R1.y, -c[8].w;\n"
- "MAD R1.z, R1, R1.y, c[9].x;\n"
- "MAD R1.z, R1, R1.y, -c[9].y;\n"
- "MAD R1.y, R1.z, R1, c[9].z;\n"
- "MUL R1.x, R1.y, R1;\n"
- "ADD R1.y, -R1.x, c[9].w;\n"
- "ADD R0.z, -R0.w, R0;\n"
- "CMP R0.z, -R0, R1.y, R1.x;\n"
- "ADD R0.w, -R0.z, c[10].x;\n"
- "CMP R0.x, R0, R0.w, R0.z;\n"
- "MUL R0.zw, fragment.position.xyxy, c[5].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "CMP R0.x, -R0.y, -R0, R0;\n"
- "MAX R0.z, R1.w, c[11].x;\n"
- "RCP R2.x, R0.z;\n"
- "MUL R3.xyz, R1, R2.x;\n"
- "MAD R4.xyz, R3, c[11].z, -c[11].w;\n"
- "ADD R0.x, R0, c[0];\n"
- "MUL R0.x, R0, c[10].y;\n"
- "FLR R0.y, R0.x;\n"
- "ADD R0.x, R0, -R0.y;\n"
- "TEX R0, R0, texture[2], 1D;\n"
- "MAD R2.xyz, R0, c[10].w, -R0.w;\n"
- "MAD R4.xyz, R3, R4, c[12].x;\n"
- "MUL R5.xyz, R1.w, R2;\n"
- "MUL R6.xyz, R5, R4;\n"
- "RSQ R2.w, R3.x;\n"
- "RCP R4.x, R2.w;\n"
- "RSQ R2.w, R3.y;\n"
- "RSQ R3.w, R3.z;\n"
- "RCP R4.y, R2.w;\n"
- "RCP R4.z, R3.w;\n"
- "ADD R4.xyz, -R3, R4;\n"
- "MUL R6.xyz, R3, R6;\n"
- "MUL R4.xyz, R5, R4;\n"
- "ADD R3.xyz, -R3, c[10].z;\n"
- "MAD R2.xyz, R2, R3, R0.w;\n"
- "MUL R3.xyz, R0, c[10].w;\n"
- "MAD R5.xyz, R0.w, R1, R6;\n"
- "MAD R4.xyz, R0.w, R1, R4;\n"
- "ADD R6.xyz, R4, -R5;\n"
- "MUL R4.xyz, R1, c[11].y;\n"
- "SGE R4.xyz, R4, R1.w;\n"
- "MAD R4.xyz, R4, R6, R5;\n"
- "MAD R4.xyz, -R1, R2, R4;\n"
- "SGE R3.xyz, R3, R0.w;\n"
- "MUL R2.xyz, R1, R2;\n"
- "ADD R2.w, -R1, c[10].z;\n"
- "MAD R2.xyz, R3, R4, R2;\n"
- "MAD R2.xyz, R0, R2.w, R2;\n"
- "ADD R0.x, -R0.w, c[10].z;\n"
- "MAD R2.xyz, R1, R0.x, R2;\n"
- "ADD R0.z, R0.w, R1.w;\n"
- "MAD R2.w, -R0, R1, R0.z;\n"
- "ADD R0.xy, fragment.position, c[6];\n"
- "MUL R0.xy, R0, c[4];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "ADD R2, R2, -R1;\n"
- "DP4 R0.x, R0, c[7];\n"
- "MAD result.color, R0.x, R2, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_DIFFERENCE =
- "!!ARBfp1.0\n"
- "PARAM c[11] = { program.local[0..7],\n"
- " { 0.15915494, 0.0020000001, 3.141593, 1.570796 },\n"
- " { -0.01348047, 0.05747731, 0.1212391, 0.1956359 },\n"
- " { 0.33299461, 0.99999559, 2 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "ABS R0.z, R0.x;\n"
- "ABS R0.w, R0.y;\n"
- "ADD R0.w, R0, -R0.z;\n"
- "ADD R1.x, R0.y, c[8].y;\n"
- "ABS R0.w, R0;\n"
- "CMP R0.y, -R0.w, R0, R1.x;\n"
- "ABS R0.w, -R0.y;\n"
- "MAX R1.x, R0.z, R0.w;\n"
- "RCP R1.y, R1.x;\n"
- "MIN R1.x, R0.z, R0.w;\n"
- "MUL R1.x, R1, R1.y;\n"
- "MUL R1.y, R1.x, R1.x;\n"
- "MAD R1.z, R1.y, c[9].x, c[9].y;\n"
- "MAD R1.z, R1, R1.y, -c[9];\n"
- "MAD R1.z, R1, R1.y, c[9].w;\n"
- "MAD R1.z, R1, R1.y, -c[10].x;\n"
- "MAD R1.y, R1.z, R1, c[10];\n"
- "MUL R1.x, R1.y, R1;\n"
- "ADD R1.y, -R1.x, c[8].w;\n"
- "ADD R0.z, -R0, R0.w;\n"
- "CMP R0.z, -R0, R1.y, R1.x;\n"
- "ADD R0.w, -R0.z, c[8].z;\n"
- "CMP R0.x, R0, R0.w, R0.z;\n"
- "CMP R0.x, -R0.y, -R0, R0;\n"
- "ADD R0.x, R0, c[0];\n"
- "MUL R0.z, R0.x, c[8].x;\n"
- "FLR R0.w, R0.z;\n"
- "ADD R1.x, R0.z, -R0.w;\n"
- "MUL R0.xy, fragment.position, c[5];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "TEX R1, R1, texture[2], 1D;\n"
- "ADD R2.xyz, R1, R0;\n"
- "MUL R3.xyz, R1.w, R0;\n"
- "MUL R1.xyz, R1, R0.w;\n"
- "MIN R1.xyz, R1, R3;\n"
- "MAD R2.xyz, -R1, c[10].z, R2;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[6];\n"
- "MUL R1.xy, R1, c[4];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_EXCLUSION =
- "!!ARBfp1.0\n"
- "PARAM c[11] = { program.local[0..7],\n"
- " { 0.15915494, 0.0020000001, 3.141593, 1.570796 },\n"
- " { -0.01348047, 0.05747731, 0.1212391, 0.1956359 },\n"
- " { 0.33299461, 0.99999559, 2, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "ABS R0.z, R0.x;\n"
- "ABS R0.w, R0.y;\n"
- "ADD R0.w, R0, -R0.z;\n"
- "ADD R1.x, R0.y, c[8].y;\n"
- "ABS R0.w, R0;\n"
- "CMP R0.y, -R0.w, R0, R1.x;\n"
- "ABS R0.w, -R0.y;\n"
- "MAX R1.x, R0.z, R0.w;\n"
- "RCP R1.y, R1.x;\n"
- "MIN R1.x, R0.z, R0.w;\n"
- "MUL R1.x, R1, R1.y;\n"
- "MUL R1.y, R1.x, R1.x;\n"
- "MAD R1.z, R1.y, c[9].x, c[9].y;\n"
- "MAD R1.z, R1, R1.y, -c[9];\n"
- "MAD R1.z, R1, R1.y, c[9].w;\n"
- "MAD R1.z, R1, R1.y, -c[10].x;\n"
- "MAD R1.y, R1.z, R1, c[10];\n"
- "MUL R1.x, R1.y, R1;\n"
- "ADD R1.y, -R1.x, c[8].w;\n"
- "ADD R0.z, -R0, R0.w;\n"
- "CMP R0.z, -R0, R1.y, R1.x;\n"
- "ADD R0.w, -R0.z, c[8].z;\n"
- "CMP R0.x, R0, R0.w, R0.z;\n"
- "CMP R0.x, -R0.y, -R0, R0;\n"
- "ADD R0.x, R0, c[0];\n"
- "MUL R0.z, R0.x, c[8].x;\n"
- "FLR R0.w, R0.z;\n"
- "ADD R1.x, R0.z, -R0.w;\n"
- "MUL R0.xy, fragment.position, c[5];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "TEX R1, R1, texture[2], 1D;\n"
- "MUL R2.xyz, R1.w, R0;\n"
- "MAD R3.xyz, R1, R0.w, R2;\n"
- "MUL R2.xyz, R1, R0;\n"
- "MAD R2.xyz, -R2, c[10].z, R3;\n"
- "ADD R2.w, -R0, c[10];\n"
- "MAD R1.xyz, R1, R2.w, R2;\n"
- "ADD R2.x, -R1.w, c[10].w;\n"
- "MAD R2.xyz, R0, R2.x, R1;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[6];\n"
- "MUL R1.xy, R1, c[4];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_SIMPLE_PORTER_DUFF_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[10] = { program.local[0..6],\n"
- " { 0.15915494, 0.0020000001, 3.141593, 1.570796 },\n"
- " { -0.01348047, 0.05747731, 0.1212391, 0.1956359 },\n"
- " { 0.33299461, 0.99999559, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "ABS R0.z, R0.x;\n"
- "ABS R0.w, R0.y;\n"
- "ADD R0.w, R0, -R0.z;\n"
- "ADD R1.x, R0.y, c[7].y;\n"
- "ABS R0.w, R0;\n"
- "CMP R0.y, -R0.w, R0, R1.x;\n"
- "ABS R0.w, -R0.y;\n"
- "MAX R1.x, R0.z, R0.w;\n"
- "RCP R1.y, R1.x;\n"
- "MIN R1.x, R0.z, R0.w;\n"
- "MUL R1.x, R1, R1.y;\n"
- "MUL R1.y, R1.x, R1.x;\n"
- "MAD R1.z, R1.y, c[8].x, c[8].y;\n"
- "MAD R1.z, R1, R1.y, -c[8];\n"
- "MAD R1.z, R1, R1.y, c[8].w;\n"
- "MAD R1.z, R1, R1.y, -c[9].x;\n"
- "MAD R1.y, R1.z, R1, c[9];\n"
- "MUL R1.x, R1.y, R1;\n"
- "ADD R0.z, -R0, R0.w;\n"
- "ADD R1.y, -R1.x, c[7].w;\n"
- "CMP R0.z, -R0, R1.y, R1.x;\n"
- "ADD R0.w, -R0.z, c[7].z;\n"
- "CMP R0.x, R0, R0.w, R0.z;\n"
- "CMP R0.x, -R0.y, -R0, R0;\n"
- "MUL R0.zw, fragment.position.xyxy, c[6].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "MUL R2.xyz, R1, c[4].y;\n"
- "ADD R0.x, R0, c[0];\n"
- "MUL R0.x, R0, c[7];\n"
- "FLR R0.y, R0.x;\n"
- "ADD R0.x, R0, -R0.y;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "MUL R3.xyz, R0.w, R2;\n"
- "MUL R2.xyz, R0, c[4].x;\n"
- "MAD R2.xyz, R1.w, R2, R3;\n"
- "ADD R2.w, -R1, c[9].z;\n"
- "MUL R0.xyz, R0, c[5].y;\n"
- "MAD R0.xyz, R2.w, R0, R2;\n"
- "ADD R2.x, -R0.w, c[9].z;\n"
- "MUL R1.xyz, R1, c[5].z;\n"
- "MAD result.color.xyz, R2.x, R1, R0;\n"
- "MUL R0.x, R0.w, R1.w;\n"
- "MUL R0.z, R1.w, R2.x;\n"
- "MUL R0.y, R0.w, R2.w;\n"
- "DP3 result.color.w, R0, c[5];\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_MULTIPLY_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[8] = { program.local[0..4],\n"
- " { 0.15915494, 0.0020000001, 3.141593, 1.570796 },\n"
- " { -0.01348047, 0.05747731, 0.1212391, 0.1956359 },\n"
- " { 0.33299461, 0.99999559, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "ABS R0.z, R0.x;\n"
- "ABS R0.w, R0.y;\n"
- "ADD R0.w, R0, -R0.z;\n"
- "ADD R1.x, R0.y, c[5].y;\n"
- "ABS R0.w, R0;\n"
- "CMP R0.y, -R0.w, R0, R1.x;\n"
- "ABS R0.w, -R0.y;\n"
- "MAX R1.x, R0.z, R0.w;\n"
- "RCP R1.y, R1.x;\n"
- "MIN R1.x, R0.z, R0.w;\n"
- "MUL R1.x, R1, R1.y;\n"
- "MUL R1.y, R1.x, R1.x;\n"
- "MAD R1.z, R1.y, c[6].x, c[6].y;\n"
- "MAD R1.z, R1, R1.y, -c[6];\n"
- "MAD R1.z, R1, R1.y, c[6].w;\n"
- "MAD R1.z, R1, R1.y, -c[7].x;\n"
- "MAD R1.y, R1.z, R1, c[7];\n"
- "MUL R1.x, R1.y, R1;\n"
- "ADD R0.z, -R0, R0.w;\n"
- "ADD R1.y, -R1.x, c[5].w;\n"
- "CMP R0.z, -R0, R1.y, R1.x;\n"
- "ADD R0.w, -R0.z, c[5].z;\n"
- "CMP R0.x, R0, R0.w, R0.z;\n"
- "CMP R0.x, -R0.y, -R0, R0;\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "ADD R0.x, R0, c[0];\n"
- "MUL R0.x, R0, c[5];\n"
- "FLR R0.y, R0.x;\n"
- "ADD R0.x, R0, -R0.y;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "ADD R2.x, -R1.w, c[7].z;\n"
- "MUL R2.xyz, R0, R2.x;\n"
- "MAD R0.xyz, R0, R1, R2;\n"
- "ADD R2.x, R0.w, R1.w;\n"
- "ADD R2.y, -R0.w, c[7].z;\n"
- "MAD result.color.xyz, R1, R2.y, R0;\n"
- "MAD result.color.w, -R0, R1, R2.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_SCREEN_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[8] = { program.local[0..4],\n"
- " { 0.15915494, 0.0020000001, 3.141593, 1.570796 },\n"
- " { -0.01348047, 0.05747731, 0.1212391, 0.1956359 },\n"
- " { 0.33299461, 0.99999559 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "ABS R0.z, R0.x;\n"
- "ABS R0.w, R0.y;\n"
- "ADD R0.w, R0, -R0.z;\n"
- "ADD R1.x, R0.y, c[5].y;\n"
- "ABS R0.w, R0;\n"
- "CMP R0.y, -R0.w, R0, R1.x;\n"
- "ABS R0.w, -R0.y;\n"
- "MAX R1.x, R0.z, R0.w;\n"
- "RCP R1.y, R1.x;\n"
- "MIN R1.x, R0.z, R0.w;\n"
- "MUL R1.x, R1, R1.y;\n"
- "MUL R1.y, R1.x, R1.x;\n"
- "MAD R1.z, R1.y, c[6].x, c[6].y;\n"
- "MAD R1.z, R1, R1.y, -c[6];\n"
- "MAD R1.z, R1, R1.y, c[6].w;\n"
- "MAD R1.z, R1, R1.y, -c[7].x;\n"
- "MAD R1.y, R1.z, R1, c[7];\n"
- "MUL R1.x, R1.y, R1;\n"
- "ADD R0.z, -R0, R0.w;\n"
- "ADD R1.y, -R1.x, c[5].w;\n"
- "CMP R0.z, -R0, R1.y, R1.x;\n"
- "ADD R0.w, -R0.z, c[5].z;\n"
- "CMP R0.x, R0, R0.w, R0.z;\n"
- "CMP R0.x, -R0.y, -R0, R0;\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "ADD R0.x, R0, c[0];\n"
- "MUL R0.x, R0, c[5];\n"
- "FLR R0.y, R0.x;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "ADD R0.x, R0, -R0.y;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "ADD R2, R0, R1;\n"
- "MAD result.color, -R0, R1, R2;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_OVERLAY_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[8] = { program.local[0..4],\n"
- " { 0.0020000001, -0.01348047, 0.05747731, 0.1212391 },\n"
- " { 0.1956359, 0.33299461, 0.99999559, 1.570796 },\n"
- " { 3.141593, 0.15915494, 2, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "ABS R0.z, R0.x;\n"
- "ABS R0.w, R0.y;\n"
- "ADD R0.w, R0, -R0.z;\n"
- "ADD R1.x, R0.y, c[5];\n"
- "ABS R0.w, R0;\n"
- "CMP R0.y, -R0.w, R0, R1.x;\n"
- "ABS R0.w, -R0.y;\n"
- "MAX R1.x, R0.z, R0.w;\n"
- "RCP R1.y, R1.x;\n"
- "MIN R1.x, R0.z, R0.w;\n"
- "MUL R1.x, R1, R1.y;\n"
- "MUL R1.y, R1.x, R1.x;\n"
- "MAD R1.z, R1.y, c[5].y, c[5];\n"
- "MAD R1.z, R1, R1.y, -c[5].w;\n"
- "MAD R1.z, R1, R1.y, c[6].x;\n"
- "MAD R1.z, R1, R1.y, -c[6].y;\n"
- "MAD R1.y, R1.z, R1, c[6].z;\n"
- "MUL R1.x, R1.y, R1;\n"
- "ADD R0.z, -R0, R0.w;\n"
- "ADD R1.y, -R1.x, c[6].w;\n"
- "CMP R0.z, -R0, R1.y, R1.x;\n"
- "ADD R0.w, -R0.z, c[7].x;\n"
- "CMP R0.x, R0, R0.w, R0.z;\n"
- "CMP R0.x, -R0.y, -R0, R0;\n"
- "ADD R0.x, R0, c[0];\n"
- "MUL R0.x, R0, c[7].y;\n"
- "FLR R0.y, R0.x;\n"
- "ADD R0.x, R0, -R0.y;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "MUL R1.xy, fragment.position, c[4];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "ADD R3.xyz, R0.w, -R0;\n"
- "ADD R2.xyz, R1.w, -R1;\n"
- "MUL R2.xyz, R2, R3;\n"
- "ADD R2.w, -R1, c[7];\n"
- "MUL R2.xyz, R2, c[7].z;\n"
- "MAD R2.xyz, R0.w, R1.w, -R2;\n"
- "MAD R2.xyz, R0, R2.w, R2;\n"
- "MUL R3.xyz, R0, R2.w;\n"
- "MUL R0.xyz, R0, R1;\n"
- "ADD R2.w, -R0, c[7];\n"
- "MAD R0.xyz, R0, c[7].z, R3;\n"
- "MAD R0.xyz, R1, R2.w, R0;\n"
- "MAD R2.xyz, R1, R2.w, R2;\n"
- "MUL R1.xyz, R1, c[7].z;\n"
- "ADD R2.w, R0, R1;\n"
- "ADD R2.xyz, R2, -R0;\n"
- "SGE R1.xyz, R1, R1.w;\n"
- "MAD result.color.xyz, R1, R2, R0;\n"
- "MAD result.color.w, -R0, R1, R2;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_DARKEN_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[8] = { program.local[0..4],\n"
- " { 0.15915494, 0.0020000001, 3.141593, 1.570796 },\n"
- " { -0.01348047, 0.05747731, 0.1212391, 0.1956359 },\n"
- " { 0.33299461, 0.99999559, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "ABS R0.z, R0.x;\n"
- "ABS R0.w, R0.y;\n"
- "ADD R0.w, R0, -R0.z;\n"
- "ADD R1.x, R0.y, c[5].y;\n"
- "ABS R0.w, R0;\n"
- "CMP R0.y, -R0.w, R0, R1.x;\n"
- "ABS R0.w, -R0.y;\n"
- "MAX R1.x, R0.z, R0.w;\n"
- "RCP R1.y, R1.x;\n"
- "MIN R1.x, R0.z, R0.w;\n"
- "MUL R1.x, R1, R1.y;\n"
- "MUL R1.y, R1.x, R1.x;\n"
- "MAD R1.z, R1.y, c[6].x, c[6].y;\n"
- "MAD R1.z, R1, R1.y, -c[6];\n"
- "MAD R1.z, R1, R1.y, c[6].w;\n"
- "MAD R1.z, R1, R1.y, -c[7].x;\n"
- "MAD R1.y, R1.z, R1, c[7];\n"
- "MUL R1.x, R1.y, R1;\n"
- "ADD R0.z, -R0, R0.w;\n"
- "ADD R1.y, -R1.x, c[5].w;\n"
- "CMP R0.z, -R0, R1.y, R1.x;\n"
- "ADD R0.w, -R0.z, c[5].z;\n"
- "CMP R0.x, R0, R0.w, R0.z;\n"
- "CMP R0.x, -R0.y, -R0, R0;\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "ADD R0.x, R0, c[0];\n"
- "MUL R0.x, R0, c[5];\n"
- "FLR R0.y, R0.x;\n"
- "ADD R0.x, R0, -R0.y;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "MUL R2.xyz, R0, R1.w;\n"
- "MUL R3.xyz, R0.w, R1;\n"
- "MIN R2.xyz, R2, R3;\n"
- "ADD R2.w, -R1, c[7].z;\n"
- "MAD R0.xyz, R0, R2.w, R2;\n"
- "ADD R2.x, R0.w, R1.w;\n"
- "ADD R2.y, -R0.w, c[7].z;\n"
- "MAD result.color.xyz, R1, R2.y, R0;\n"
- "MAD result.color.w, -R0, R1, R2.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_LIGHTEN_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[8] = { program.local[0..4],\n"
- " { 0.15915494, 0.0020000001, 3.141593, 1.570796 },\n"
- " { -0.01348047, 0.05747731, 0.1212391, 0.1956359 },\n"
- " { 0.33299461, 0.99999559, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "ABS R0.z, R0.x;\n"
- "ABS R0.w, R0.y;\n"
- "ADD R0.w, R0, -R0.z;\n"
- "ADD R1.x, R0.y, c[5].y;\n"
- "ABS R0.w, R0;\n"
- "CMP R0.y, -R0.w, R0, R1.x;\n"
- "ABS R0.w, -R0.y;\n"
- "MAX R1.x, R0.z, R0.w;\n"
- "RCP R1.y, R1.x;\n"
- "MIN R1.x, R0.z, R0.w;\n"
- "MUL R1.x, R1, R1.y;\n"
- "MUL R1.y, R1.x, R1.x;\n"
- "MAD R1.z, R1.y, c[6].x, c[6].y;\n"
- "MAD R1.z, R1, R1.y, -c[6];\n"
- "MAD R1.z, R1, R1.y, c[6].w;\n"
- "MAD R1.z, R1, R1.y, -c[7].x;\n"
- "MAD R1.y, R1.z, R1, c[7];\n"
- "MUL R1.x, R1.y, R1;\n"
- "ADD R0.z, -R0, R0.w;\n"
- "ADD R1.y, -R1.x, c[5].w;\n"
- "CMP R0.z, -R0, R1.y, R1.x;\n"
- "ADD R0.w, -R0.z, c[5].z;\n"
- "CMP R0.x, R0, R0.w, R0.z;\n"
- "CMP R0.x, -R0.y, -R0, R0;\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "ADD R0.x, R0, c[0];\n"
- "MUL R0.x, R0, c[5];\n"
- "FLR R0.y, R0.x;\n"
- "ADD R0.x, R0, -R0.y;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "MUL R2.xyz, R0, R1.w;\n"
- "MUL R3.xyz, R0.w, R1;\n"
- "MAX R2.xyz, R2, R3;\n"
- "ADD R2.w, -R1, c[7].z;\n"
- "MAD R0.xyz, R0, R2.w, R2;\n"
- "ADD R2.x, R0.w, R1.w;\n"
- "ADD R2.y, -R0.w, c[7].z;\n"
- "MAD result.color.xyz, R1, R2.y, R0;\n"
- "MAD result.color.w, -R0, R1, R2.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_COLORDODGE_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[8] = { program.local[0..4],\n"
- " { 0.0020000001, -0.01348047, 0.05747731, 0.1212391 },\n"
- " { 0.1956359, 0.33299461, 0.99999559, 1.570796 },\n"
- " { 3.141593, 0.15915494, 1, 1e-006 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "ABS R0.z, R0.x;\n"
- "ABS R0.w, R0.y;\n"
- "ADD R0.w, R0, -R0.z;\n"
- "ADD R1.x, R0.y, c[5];\n"
- "ABS R0.w, R0;\n"
- "CMP R0.y, -R0.w, R0, R1.x;\n"
- "ABS R0.w, -R0.y;\n"
- "MAX R1.x, R0.z, R0.w;\n"
- "RCP R1.y, R1.x;\n"
- "MIN R1.x, R0.z, R0.w;\n"
- "MUL R1.x, R1, R1.y;\n"
- "MUL R1.y, R1.x, R1.x;\n"
- "MAD R1.z, R1.y, c[5].y, c[5];\n"
- "MAD R1.z, R1, R1.y, -c[5].w;\n"
- "MAD R1.z, R1, R1.y, c[6].x;\n"
- "MAD R1.z, R1, R1.y, -c[6].y;\n"
- "MAD R1.y, R1.z, R1, c[6].z;\n"
- "MUL R1.x, R1.y, R1;\n"
- "ADD R1.y, -R1.x, c[6].w;\n"
- "ADD R0.z, -R0, R0.w;\n"
- "CMP R0.z, -R0, R1.y, R1.x;\n"
- "ADD R0.w, -R0.z, c[7].x;\n"
- "CMP R0.x, R0, R0.w, R0.z;\n"
- "CMP R0.x, -R0.y, -R0, R0;\n"
- "ADD R0.x, R0, c[0];\n"
- "MUL R0.x, R0, c[7].y;\n"
- "FLR R0.y, R0.x;\n"
- "ADD R0.x, R0, -R0.y;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "MAX R1.x, R0.w, c[7].w;\n"
- "RCP R1.x, R1.x;\n"
- "MAD R1.xyz, -R0, R1.x, c[7].z;\n"
- "MAX R2.xyz, R1, c[7].w;\n"
- "MUL R1.xy, fragment.position, c[4];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "ADD R2.w, -R0, c[7].z;\n"
- "MUL R3.xyz, R1, R2.w;\n"
- "ADD R2.w, -R1, c[7].z;\n"
- "MAD R3.xyz, R0, R2.w, R3;\n"
- "MUL R1.xyz, R0.w, R1;\n"
- "MAD R0.xyz, R0, R1.w, R1;\n"
- "MUL R2.w, R0, R1;\n"
- "RCP R2.x, R2.x;\n"
- "RCP R2.y, R2.y;\n"
- "RCP R2.z, R2.z;\n"
- "MAD R2.xyz, R1, R2, R3;\n"
- "MAD R3.xyz, R0.w, R1.w, R3;\n"
- "ADD R1.x, R0.w, R1.w;\n"
- "ADD R3.xyz, R3, -R2;\n"
- "SGE R0.xyz, R0, R2.w;\n"
- "MAD result.color.xyz, R0, R3, R2;\n"
- "MAD result.color.w, -R0, R1, R1.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_COLORBURN_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[8] = { program.local[0..4],\n"
- " { 0.0020000001, -0.01348047, 0.05747731, 0.1212391 },\n"
- " { 0.1956359, 0.33299461, 0.99999559, 1.570796 },\n"
- " { 3.141593, 0.15915494, 1, 9.9999997e-006 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "TEMP R5;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "ABS R0.w, R0.x;\n"
- "ABS R0.z, R0.y;\n"
- "ADD R0.z, R0, -R0.w;\n"
- "ADD R1.x, R0.y, c[5];\n"
- "ABS R0.z, R0;\n"
- "CMP R0.y, -R0.z, R0, R1.x;\n"
- "ABS R0.z, -R0.y;\n"
- "MAX R1.x, R0.w, R0.z;\n"
- "RCP R1.y, R1.x;\n"
- "MIN R1.x, R0.w, R0.z;\n"
- "MUL R1.x, R1, R1.y;\n"
- "MUL R1.y, R1.x, R1.x;\n"
- "MAD R1.z, R1.y, c[5].y, c[5];\n"
- "MAD R1.z, R1, R1.y, -c[5].w;\n"
- "MAD R1.z, R1, R1.y, c[6].x;\n"
- "MAD R1.z, R1, R1.y, -c[6].y;\n"
- "MAD R1.y, R1.z, R1, c[6].z;\n"
- "MUL R1.x, R1.y, R1;\n"
- "ADD R1.y, -R1.x, c[6].w;\n"
- "ADD R0.z, -R0.w, R0;\n"
- "CMP R0.z, -R0, R1.y, R1.x;\n"
- "ADD R0.w, -R0.z, c[7].x;\n"
- "CMP R0.x, R0, R0.w, R0.z;\n"
- "CMP R0.x, -R0.y, -R0, R0;\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "ADD R0.x, R0, c[0];\n"
- "MUL R0.x, R0, c[7].y;\n"
- "FLR R0.y, R0.x;\n"
- "ADD R0.x, R0, -R0.y;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "MUL R2.xyz, R0.w, R1;\n"
- "MAD R3.xyz, R0, R1.w, R2;\n"
- "ADD R2.w, -R1, c[7].z;\n"
- "MAD R2.xyz, -R0.w, R1.w, R3;\n"
- "MUL R4.xyz, R0.w, R2;\n"
- "MAX R2.xyz, R0, c[7].w;\n"
- "MUL R5.xyz, R0, R2.w;\n"
- "ADD R3.w, -R0, c[7].z;\n"
- "RCP R2.x, R2.x;\n"
- "RCP R2.y, R2.y;\n"
- "RCP R2.z, R2.z;\n"
- "MAD R2.xyz, R4, R2, R5;\n"
- "MUL R4.xyz, R1, R3.w;\n"
- "MAD R1.xyz, R1, R3.w, R2;\n"
- "MAD R0.xyz, R0, R2.w, R4;\n"
- "MUL R2.x, R0.w, R1.w;\n"
- "ADD R2.w, R0, R1;\n"
- "ADD R1.xyz, R1, -R0;\n"
- "SGE R2.xyz, R3, R2.x;\n"
- "MAD result.color.xyz, R2, R1, R0;\n"
- "MAD result.color.w, -R0, R1, R2;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_HARDLIGHT_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[8] = { program.local[0..4],\n"
- " { 0.0020000001, -0.01348047, 0.05747731, 0.1212391 },\n"
- " { 0.1956359, 0.33299461, 0.99999559, 1.570796 },\n"
- " { 3.141593, 0.15915494, 2, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "ABS R0.z, R0.x;\n"
- "ABS R0.w, R0.y;\n"
- "ADD R0.w, R0, -R0.z;\n"
- "ADD R1.x, R0.y, c[5];\n"
- "ABS R0.w, R0;\n"
- "CMP R0.y, -R0.w, R0, R1.x;\n"
- "ABS R0.w, -R0.y;\n"
- "MAX R1.x, R0.z, R0.w;\n"
- "RCP R1.y, R1.x;\n"
- "MIN R1.x, R0.z, R0.w;\n"
- "MUL R1.x, R1, R1.y;\n"
- "MUL R1.y, R1.x, R1.x;\n"
- "MAD R1.z, R1.y, c[5].y, c[5];\n"
- "MAD R1.z, R1, R1.y, -c[5].w;\n"
- "MAD R1.z, R1, R1.y, c[6].x;\n"
- "MAD R1.z, R1, R1.y, -c[6].y;\n"
- "MAD R1.y, R1.z, R1, c[6].z;\n"
- "MUL R1.x, R1.y, R1;\n"
- "ADD R0.z, -R0, R0.w;\n"
- "ADD R1.y, -R1.x, c[6].w;\n"
- "CMP R0.z, -R0, R1.y, R1.x;\n"
- "ADD R0.w, -R0.z, c[7].x;\n"
- "CMP R0.x, R0, R0.w, R0.z;\n"
- "CMP R0.x, -R0.y, -R0, R0;\n"
- "ADD R0.x, R0, c[0];\n"
- "MUL R0.x, R0, c[7].y;\n"
- "FLR R0.y, R0.x;\n"
- "ADD R0.x, R0, -R0.y;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "MUL R1.xy, fragment.position, c[4];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "ADD R2.w, -R1, c[7];\n"
- "ADD R3.xyz, R0.w, -R0;\n"
- "ADD R2.xyz, R1.w, -R1;\n"
- "MUL R2.xyz, R2, R3;\n"
- "MUL R2.xyz, R2, c[7].z;\n"
- "MAD R2.xyz, R0.w, R1.w, -R2;\n"
- "MUL R4.xyz, R0, R2.w;\n"
- "MUL R3.xyz, R0, R1;\n"
- "MAD R2.xyz, R0, R2.w, R2;\n"
- "ADD R2.w, -R0, c[7];\n"
- "MUL R0.xyz, R0, c[7].z;\n"
- "MAD R2.xyz, R1, R2.w, R2;\n"
- "MAD R3.xyz, R3, c[7].z, R4;\n"
- "MAD R1.xyz, R1, R2.w, R3;\n"
- "ADD R2.w, R0, R1;\n"
- "ADD R2.xyz, R2, -R1;\n"
- "SGE R0.xyz, R0, R0.w;\n"
- "MAD result.color.xyz, R0, R2, R1;\n"
- "MAD result.color.w, -R0, R1, R2;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_SOFTLIGHT_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[10] = { program.local[0..4],\n"
- " { 0.0020000001, -0.01348047, 0.05747731, 0.1212391 },\n"
- " { 0.1956359, 0.33299461, 0.99999559, 1.570796 },\n"
- " { 3.141593, 0.15915494, 1, 2 },\n"
- " { 9.9999997e-006, 4, 16, 12 },\n"
- " { 3 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "TEMP R5;\n"
- "TEMP R6;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "ABS R0.w, R0.x;\n"
- "ABS R0.z, R0.y;\n"
- "ADD R0.z, R0, -R0.w;\n"
- "ADD R1.x, R0.y, c[5];\n"
- "ABS R0.z, R0;\n"
- "CMP R0.y, -R0.z, R0, R1.x;\n"
- "ABS R0.z, -R0.y;\n"
- "MAX R1.x, R0.w, R0.z;\n"
- "RCP R1.y, R1.x;\n"
- "MIN R1.x, R0.w, R0.z;\n"
- "MUL R1.x, R1, R1.y;\n"
- "MUL R1.y, R1.x, R1.x;\n"
- "MAD R1.z, R1.y, c[5].y, c[5];\n"
- "MAD R1.z, R1, R1.y, -c[5].w;\n"
- "MAD R1.z, R1, R1.y, c[6].x;\n"
- "MAD R1.z, R1, R1.y, -c[6].y;\n"
- "MAD R1.y, R1.z, R1, c[6].z;\n"
- "MUL R1.x, R1.y, R1;\n"
- "ADD R1.y, -R1.x, c[6].w;\n"
- "ADD R0.z, -R0.w, R0;\n"
- "CMP R0.z, -R0, R1.y, R1.x;\n"
- "ADD R0.w, -R0.z, c[7].x;\n"
- "CMP R0.x, R0, R0.w, R0.z;\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "CMP R0.x, -R0.y, -R0, R0;\n"
- "MAX R0.z, R1.w, c[8].x;\n"
- "RCP R2.x, R0.z;\n"
- "MUL R3.xyz, R1, R2.x;\n"
- "MAD R4.xyz, R3, c[8].z, -c[8].w;\n"
- "ADD R0.x, R0, c[0];\n"
- "MUL R0.x, R0, c[7].y;\n"
- "FLR R0.y, R0.x;\n"
- "ADD R0.x, R0, -R0.y;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "MAD R2.xyz, R0, c[7].w, -R0.w;\n"
- "MAD R4.xyz, R3, R4, c[9].x;\n"
- "MUL R5.xyz, R1.w, R2;\n"
- "MUL R6.xyz, R5, R4;\n"
- "RSQ R2.w, R3.x;\n"
- "RCP R4.x, R2.w;\n"
- "RSQ R2.w, R3.y;\n"
- "RSQ R3.w, R3.z;\n"
- "RCP R4.y, R2.w;\n"
- "RCP R4.z, R3.w;\n"
- "ADD R4.xyz, -R3, R4;\n"
- "MUL R6.xyz, R3, R6;\n"
- "MUL R4.xyz, R5, R4;\n"
- "ADD R3.xyz, -R3, c[7].z;\n"
- "MAD R2.xyz, R2, R3, R0.w;\n"
- "MUL R3.xyz, R0, c[7].w;\n"
- "MAD R5.xyz, R0.w, R1, R6;\n"
- "MAD R4.xyz, R0.w, R1, R4;\n"
- "ADD R6.xyz, R4, -R5;\n"
- "MUL R4.xyz, R1, c[8].y;\n"
- "SGE R4.xyz, R4, R1.w;\n"
- "MAD R4.xyz, R4, R6, R5;\n"
- "MAD R4.xyz, -R1, R2, R4;\n"
- "MUL R2.xyz, R1, R2;\n"
- "SGE R3.xyz, R3, R0.w;\n"
- "MAD R2.xyz, R3, R4, R2;\n"
- "ADD R2.w, -R1, c[7].z;\n"
- "MAD R2.xyz, R0, R2.w, R2;\n"
- "ADD R0.x, R0.w, R1.w;\n"
- "ADD R0.y, -R0.w, c[7].z;\n"
- "MAD result.color.xyz, R1, R0.y, R2;\n"
- "MAD result.color.w, -R0, R1, R0.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_DIFFERENCE_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[8] = { program.local[0..4],\n"
- " { 0.15915494, 0.0020000001, 3.141593, 1.570796 },\n"
- " { -0.01348047, 0.05747731, 0.1212391, 0.1956359 },\n"
- " { 0.33299461, 0.99999559, 2 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "ABS R0.z, R0.x;\n"
- "ABS R0.w, R0.y;\n"
- "ADD R0.w, R0, -R0.z;\n"
- "ADD R1.x, R0.y, c[5].y;\n"
- "ABS R0.w, R0;\n"
- "CMP R0.y, -R0.w, R0, R1.x;\n"
- "ABS R0.w, -R0.y;\n"
- "MAX R1.x, R0.z, R0.w;\n"
- "RCP R1.y, R1.x;\n"
- "MIN R1.x, R0.z, R0.w;\n"
- "MUL R1.x, R1, R1.y;\n"
- "MUL R1.y, R1.x, R1.x;\n"
- "MAD R1.z, R1.y, c[6].x, c[6].y;\n"
- "MAD R1.z, R1, R1.y, -c[6];\n"
- "MAD R1.z, R1, R1.y, c[6].w;\n"
- "MAD R1.z, R1, R1.y, -c[7].x;\n"
- "MAD R1.y, R1.z, R1, c[7];\n"
- "MUL R1.x, R1.y, R1;\n"
- "ADD R0.z, -R0, R0.w;\n"
- "ADD R1.y, -R1.x, c[5].w;\n"
- "CMP R0.z, -R0, R1.y, R1.x;\n"
- "ADD R0.w, -R0.z, c[5].z;\n"
- "CMP R0.x, R0, R0.w, R0.z;\n"
- "CMP R0.x, -R0.y, -R0, R0;\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "ADD R0.x, R0, c[0];\n"
- "MUL R0.x, R0, c[5];\n"
- "FLR R0.y, R0.x;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "ADD R0.x, R0, -R0.y;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "MUL R2.xyz, R0, R1.w;\n"
- "MUL R3.xyz, R0.w, R1;\n"
- "ADD R0.xyz, R0, R1;\n"
- "MIN R2.xyz, R2, R3;\n"
- "ADD R1.x, R0.w, R1.w;\n"
- "MAD result.color.xyz, -R2, c[7].z, R0;\n"
- "MAD result.color.w, -R0, R1, R1.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_EXCLUSION_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[8] = { program.local[0..4],\n"
- " { 0.15915494, 0.0020000001, 3.141593, 1.570796 },\n"
- " { -0.01348047, 0.05747731, 0.1212391, 0.1956359 },\n"
- " { 0.33299461, 0.99999559, 2, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "ABS R0.z, R0.x;\n"
- "ABS R0.w, R0.y;\n"
- "ADD R0.w, R0, -R0.z;\n"
- "ADD R1.x, R0.y, c[5].y;\n"
- "ABS R0.w, R0;\n"
- "CMP R0.y, -R0.w, R0, R1.x;\n"
- "ABS R0.w, -R0.y;\n"
- "MAX R1.x, R0.z, R0.w;\n"
- "RCP R1.y, R1.x;\n"
- "MIN R1.x, R0.z, R0.w;\n"
- "MUL R1.x, R1, R1.y;\n"
- "MUL R1.y, R1.x, R1.x;\n"
- "MAD R1.z, R1.y, c[6].x, c[6].y;\n"
- "MAD R1.z, R1, R1.y, -c[6];\n"
- "MAD R1.z, R1, R1.y, c[6].w;\n"
- "MAD R1.z, R1, R1.y, -c[7].x;\n"
- "MAD R1.y, R1.z, R1, c[7];\n"
- "MUL R1.x, R1.y, R1;\n"
- "ADD R0.z, -R0, R0.w;\n"
- "ADD R1.y, -R1.x, c[5].w;\n"
- "CMP R0.z, -R0, R1.y, R1.x;\n"
- "ADD R0.w, -R0.z, c[5].z;\n"
- "CMP R0.x, R0, R0.w, R0.z;\n"
- "CMP R0.x, -R0.y, -R0, R0;\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "ADD R0.x, R0, c[0];\n"
- "MUL R0.x, R0, c[5];\n"
- "FLR R0.y, R0.x;\n"
- "ADD R0.x, R0, -R0.y;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "MUL R2.xyz, R0.w, R1;\n"
- "MAD R3.xyz, R0, R1.w, R2;\n"
- "MUL R2.xyz, R0, R1;\n"
- "MAD R2.xyz, -R2, c[7].z, R3;\n"
- "ADD R2.w, -R1, c[7];\n"
- "MAD R0.xyz, R0, R2.w, R2;\n"
- "ADD R2.x, R0.w, R1.w;\n"
- "ADD R2.y, -R0.w, c[7].w;\n"
- "MAD result.color.xyz, R1, R2.y, R0;\n"
- "MAD result.color.w, -R0, R1, R2.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODE_BLEND_MODE_MASK =
- "!!ARBfp1.0\n"
- "PARAM c[10] = { program.local[0..6],\n"
- " { 0.15915494, 0.0020000001, 3.141593, 1.570796 },\n"
- " { -0.01348047, 0.05747731, 0.1212391, 0.1956359 },\n"
- " { 0.33299461, 0.99999559 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "ABS R0.z, R0.x;\n"
- "ABS R0.w, R0.y;\n"
- "ADD R0.w, R0, -R0.z;\n"
- "ADD R1.x, R0.y, c[7].y;\n"
- "ABS R0.w, R0;\n"
- "CMP R0.y, -R0.w, R0, R1.x;\n"
- "ABS R0.w, -R0.y;\n"
- "MAX R1.x, R0.z, R0.w;\n"
- "RCP R1.y, R1.x;\n"
- "MIN R1.x, R0.z, R0.w;\n"
- "MUL R1.x, R1, R1.y;\n"
- "MUL R1.y, R1.x, R1.x;\n"
- "MAD R1.z, R1.y, c[8].x, c[8].y;\n"
- "MAD R1.z, R1, R1.y, -c[8];\n"
- "MAD R1.z, R1, R1.y, c[8].w;\n"
- "MAD R1.z, R1, R1.y, -c[9].x;\n"
- "MAD R1.y, R1.z, R1, c[9];\n"
- "MUL R1.x, R1.y, R1;\n"
- "ADD R1.y, -R1.x, c[7].w;\n"
- "ADD R0.z, -R0, R0.w;\n"
- "CMP R0.z, -R0, R1.y, R1.x;\n"
- "ADD R0.w, -R0.z, c[7].z;\n"
- "CMP R0.x, R0, R0.w, R0.z;\n"
- "CMP R0.x, -R0.y, -R0, R0;\n"
- "ADD R0.x, R0, c[0];\n"
- "MUL R1.x, R0, c[7];\n"
- "FLR R1.y, R1.x;\n"
- "ADD R0.zw, fragment.position.xyxy, c[5].xyxy;\n"
- "MUL R0.xy, R0.zwzw, c[4];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "ADD R1.x, R1, -R1.y;\n"
- "DP4 R1.y, R0, c[6];\n"
- "TEX R0, R1, texture[1], 1D;\n"
- "MUL result.color, R0, R1.y;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODE_BLEND_MODE_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[7] = { program.local[0..3],\n"
- " { 0.15915494, 0.0020000001, 3.141593, 1.570796 },\n"
- " { -0.01348047, 0.05747731, 0.1212391, 0.1956359 },\n"
- " { 0.33299461, 0.99999559 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "ABS R0.z, R0.x;\n"
- "ABS R0.w, R0.y;\n"
- "ADD R0.w, R0, -R0.z;\n"
- "ADD R1.x, R0.y, c[4].y;\n"
- "ABS R0.w, R0;\n"
- "CMP R0.y, -R0.w, R0, R1.x;\n"
- "ABS R0.w, -R0.y;\n"
- "MAX R1.x, R0.z, R0.w;\n"
- "RCP R1.y, R1.x;\n"
- "MIN R1.x, R0.z, R0.w;\n"
- "MUL R1.x, R1, R1.y;\n"
- "MUL R1.y, R1.x, R1.x;\n"
- "MAD R1.z, R1.y, c[5].x, c[5].y;\n"
- "MAD R1.z, R1, R1.y, -c[5];\n"
- "MAD R1.z, R1, R1.y, c[5].w;\n"
- "MAD R1.z, R1, R1.y, -c[6].x;\n"
- "MAD R1.y, R1.z, R1, c[6];\n"
- "MUL R1.x, R1.y, R1;\n"
- "ADD R0.z, -R0, R0.w;\n"
- "ADD R1.y, -R1.x, c[4].w;\n"
- "CMP R0.z, -R0, R1.y, R1.x;\n"
- "ADD R0.w, -R0.z, c[4].z;\n"
- "CMP R0.x, R0, R0.w, R0.z;\n"
- "CMP R0.x, -R0.y, -R0, R0;\n"
- "ADD R0.x, R0, c[0];\n"
- "MUL R0.x, R0, c[4];\n"
- "FLR R0.y, R0.x;\n"
- "ADD R0.x, R0, -R0.y;\n"
- "TEX result.color, R0, texture[0], 1D;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_SIMPLE_PORTER_DUFF =
- "!!ARBfp1.0\n"
- "PARAM c[11] = { program.local[0..9],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, c[0].xyxy;\n"
- "ADD R1.x, R0.z, R0.w;\n"
- "MUL R0.xy, fragment.position, c[7];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "MUL R1.x, R1, c[0].z;\n"
- "TEX R1, R1, texture[2], 1D;\n"
- "MUL R2.xyz, R0, c[4].y;\n"
- "MUL R3.xyz, R1.w, R2;\n"
- "MUL R2.xyz, R1, c[4].x;\n"
- "MAD R2.xyz, R0.w, R2, R3;\n"
- "ADD R3.xy, fragment.position, c[8];\n"
- "ADD R2.w, -R0, c[10].x;\n"
- "MUL R1.xyz, R1, c[5].y;\n"
- "MAD R2.xyz, R2.w, R1, R2;\n"
- "MUL R1.xyz, R0, c[5].z;\n"
- "ADD R3.z, -R1.w, c[10].x;\n"
- "MAD R2.xyz, R3.z, R1, R2;\n"
- "MUL R1.y, R1.w, R2.w;\n"
- "MUL R1.x, R1.w, R0.w;\n"
- "MUL R1.z, R0.w, R3;\n"
- "DP3 R2.w, R1, c[5];\n"
- "MUL R3.xy, R3, c[6];\n"
- "TEX R1, R3, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[9];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_MULTIPLY =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, c[0].xyxy;\n"
- "ADD R1.x, R0.z, R0.w;\n"
- "MUL R0.xy, fragment.position, c[5];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "MUL R1.x, R1, c[0].z;\n"
- "TEX R1, R1, texture[2], 1D;\n"
- "ADD R2.x, -R0.w, c[8];\n"
- "MUL R2.xyz, R1, R2.x;\n"
- "MAD R1.xyz, R1, R0, R2;\n"
- "ADD R2.x, -R1.w, c[8];\n"
- "MAD R2.xyz, R0, R2.x, R1;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[6];\n"
- "MUL R1.xy, R1, c[4];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_SCREEN =
- "!!ARBfp1.0\n"
- "PARAM c[8] = { program.local[0..7] };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.z, R0.x, c[0];\n"
- "ADD R3.xy, fragment.position, c[6];\n"
- "TEX R1, R0.z, texture[2], 1D;\n"
- "MUL R0.xy, fragment.position, c[5];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "ADD R2, R1, R0;\n"
- "MAD R2, -R1, R0, R2;\n"
- "MUL R3.xy, R3, c[4];\n"
- "TEX R1, R3, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_OVERLAY =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 2, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.x, R0, c[0].z;\n"
- "TEX R0, R0, texture[2], 1D;\n"
- "MUL R1.xy, fragment.position, c[5];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "ADD R2.w, -R1, c[8].y;\n"
- "ADD R3.xyz, R0.w, -R0;\n"
- "ADD R2.xyz, R1.w, -R1;\n"
- "MUL R2.xyz, R2, R3;\n"
- "MUL R2.xyz, R2, c[8].x;\n"
- "MAD R2.xyz, R0.w, R1.w, -R2;\n"
- "MUL R4.xyz, R0, R2.w;\n"
- "MUL R3.xyz, R0, R1;\n"
- "MAD R0.xyz, R0, R2.w, R2;\n"
- "ADD R2.x, -R0.w, c[8].y;\n"
- "MAD R3.xyz, R3, c[8].x, R4;\n"
- "MAD R3.xyz, R1, R2.x, R3;\n"
- "MAD R0.xyz, R1, R2.x, R0;\n"
- "MUL R2.xyz, R1, c[8].x;\n"
- "ADD R0.xyz, R0, -R3;\n"
- "SGE R2.xyz, R2, R1.w;\n"
- "MAD R2.xyz, R2, R0, R3;\n"
- "ADD R0.z, R0.w, R1.w;\n"
- "MAD R2.w, -R0, R1, R0.z;\n"
- "ADD R0.xy, fragment.position, c[6];\n"
- "MUL R0.xy, R0, c[4];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "ADD R2, R2, -R1;\n"
- "DP4 R0.x, R0, c[7];\n"
- "MAD result.color, R0.x, R2, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_DARKEN =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.z, R0.x, R0.y;\n"
- "MUL R1.x, R0.z, c[0].z;\n"
- "MUL R0.xy, fragment.position, c[5];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "TEX R1, R1, texture[2], 1D;\n"
- "MUL R3.xyz, R1.w, R0;\n"
- "MUL R2.xyz, R1, R0.w;\n"
- "MIN R2.xyz, R2, R3;\n"
- "ADD R2.w, -R0, c[8].x;\n"
- "MAD R1.xyz, R1, R2.w, R2;\n"
- "ADD R2.x, -R1.w, c[8];\n"
- "MAD R2.xyz, R0, R2.x, R1;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[6];\n"
- "MUL R1.xy, R1, c[4];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_LIGHTEN =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.z, R0.x, R0.y;\n"
- "MUL R1.x, R0.z, c[0].z;\n"
- "MUL R0.xy, fragment.position, c[5];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "TEX R1, R1, texture[2], 1D;\n"
- "MUL R3.xyz, R1.w, R0;\n"
- "MUL R2.xyz, R1, R0.w;\n"
- "MAX R2.xyz, R2, R3;\n"
- "ADD R2.w, -R0, c[8].x;\n"
- "MAD R1.xyz, R1, R2.w, R2;\n"
- "ADD R2.x, -R1.w, c[8];\n"
- "MAD R2.xyz, R0, R2.x, R1;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[6];\n"
- "MUL R1.xy, R1, c[4];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_COLORDODGE =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 1, 1e-006 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.x, R0, c[0].z;\n"
- "TEX R0, R0, texture[2], 1D;\n"
- "MAX R1.x, R0.w, c[8].y;\n"
- "RCP R1.x, R1.x;\n"
- "MAD R2.xyz, -R0, R1.x, c[8].x;\n"
- "MAX R2.xyz, R2, c[8].y;\n"
- "MUL R1.xy, fragment.position, c[5];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "ADD R2.w, -R0, c[8].x;\n"
- "MUL R3.xyz, R1, R2.w;\n"
- "ADD R2.w, -R1, c[8].x;\n"
- "MAD R4.xyz, R0, R2.w, R3;\n"
- "MUL R3.xyz, R0.w, R1;\n"
- "MUL R2.w, R0, R1;\n"
- "MAD R0.xyz, R0, R1.w, R3;\n"
- "SGE R0.xyz, R0, R2.w;\n"
- "RCP R2.x, R2.x;\n"
- "RCP R2.y, R2.y;\n"
- "RCP R2.z, R2.z;\n"
- "MAD R2.xyz, R3, R2, R4;\n"
- "MAD R4.xyz, R0.w, R1.w, R4;\n"
- "ADD R4.xyz, R4, -R2;\n"
- "MAD R2.xyz, R0, R4, R2;\n"
- "ADD R0.z, R0.w, R1.w;\n"
- "MAD R2.w, -R0, R1, R0.z;\n"
- "ADD R0.xy, fragment.position, c[6];\n"
- "MUL R0.xy, R0, c[4];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "ADD R2, R2, -R1;\n"
- "DP4 R0.x, R0, c[7];\n"
- "MAD result.color, R0.x, R2, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_COLORBURN =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 1, 9.9999997e-006 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "TEMP R5;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.zw, fragment.position.xyxy, c[5].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "MUL R0.x, R0, c[0].z;\n"
- "TEX R0, R0, texture[2], 1D;\n"
- "MUL R2.xyz, R0.w, R1;\n"
- "MAD R3.xyz, R0, R1.w, R2;\n"
- "MAD R2.xyz, -R0.w, R1.w, R3;\n"
- "MUL R4.xyz, R0.w, R2;\n"
- "MAX R2.xyz, R0, c[8].y;\n"
- "ADD R2.w, -R1, c[8].x;\n"
- "MUL R5.xyz, R0, R2.w;\n"
- "ADD R3.w, -R0, c[8].x;\n"
- "RCP R2.x, R2.x;\n"
- "RCP R2.y, R2.y;\n"
- "RCP R2.z, R2.z;\n"
- "MAD R2.xyz, R4, R2, R5;\n"
- "MUL R4.xyz, R1, R3.w;\n"
- "MAD R0.xyz, R0, R2.w, R4;\n"
- "MUL R2.w, R0, R1;\n"
- "MAD R2.xyz, R1, R3.w, R2;\n"
- "ADD R2.xyz, R2, -R0;\n"
- "SGE R3.xyz, R3, R2.w;\n"
- "MAD R2.xyz, R3, R2, R0;\n"
- "ADD R0.z, R0.w, R1.w;\n"
- "MAD R2.w, -R0, R1, R0.z;\n"
- "ADD R0.xy, fragment.position, c[6];\n"
- "MUL R0.xy, R0, c[4];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "ADD R2, R2, -R1;\n"
- "DP4 R0.x, R0, c[7];\n"
- "MAD result.color, R0.x, R2, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_HARDLIGHT =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 2, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.x, R0, c[0].z;\n"
- "TEX R0, R0, texture[2], 1D;\n"
- "MUL R1.xy, fragment.position, c[5];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "ADD R2.w, -R1, c[8].y;\n"
- "ADD R3.xyz, R0.w, -R0;\n"
- "ADD R2.xyz, R1.w, -R1;\n"
- "MUL R2.xyz, R2, R3;\n"
- "MUL R2.xyz, R2, c[8].x;\n"
- "MAD R2.xyz, R0.w, R1.w, -R2;\n"
- "MUL R4.xyz, R0, R2.w;\n"
- "MAD R2.xyz, R0, R2.w, R2;\n"
- "MUL R3.xyz, R0, R1;\n"
- "ADD R2.w, -R0, c[8].y;\n"
- "MAD R3.xyz, R3, c[8].x, R4;\n"
- "MUL R0.xyz, R0, c[8].x;\n"
- "SGE R0.xyz, R0, R0.w;\n"
- "MAD R3.xyz, R1, R2.w, R3;\n"
- "MAD R2.xyz, R1, R2.w, R2;\n"
- "ADD R2.xyz, R2, -R3;\n"
- "MAD R2.xyz, R0, R2, R3;\n"
- "ADD R0.z, R0.w, R1.w;\n"
- "MAD R2.w, -R0, R1, R0.z;\n"
- "ADD R0.xy, fragment.position, c[6];\n"
- "MUL R0.xy, R0, c[4];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "ADD R2, R2, -R1;\n"
- "DP4 R0.x, R0, c[7];\n"
- "MAD result.color, R0.x, R2, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_SOFTLIGHT =
- "!!ARBfp1.0\n"
- "PARAM c[10] = { program.local[0..7],\n"
- " { 1, 2, 9.9999997e-006, 4 },\n"
- " { 16, 12, 3 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "TEMP R5;\n"
- "TEMP R6;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R1.xy, fragment.position, c[5];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "MAX R0.z, R1.w, c[8];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R3.xyz, R1, R0.z;\n"
- "MAD R2.xyz, R3, c[9].x, -c[9].y;\n"
- "MUL R0.x, R0, c[0].z;\n"
- "TEX R0, R0, texture[2], 1D;\n"
- "MAD R4.xyz, R3, R2, c[9].z;\n"
- "MAD R2.xyz, R0, c[8].y, -R0.w;\n"
- "MUL R5.xyz, R1.w, R2;\n"
- "MUL R6.xyz, R5, R4;\n"
- "RSQ R2.w, R3.x;\n"
- "RCP R4.x, R2.w;\n"
- "RSQ R2.w, R3.y;\n"
- "RSQ R3.w, R3.z;\n"
- "RCP R4.y, R2.w;\n"
- "RCP R4.z, R3.w;\n"
- "ADD R4.xyz, -R3, R4;\n"
- "MUL R6.xyz, R3, R6;\n"
- "MUL R4.xyz, R5, R4;\n"
- "ADD R3.xyz, -R3, c[8].x;\n"
- "MAD R2.xyz, R2, R3, R0.w;\n"
- "MUL R3.xyz, R0, c[8].y;\n"
- "MAD R5.xyz, R0.w, R1, R6;\n"
- "MAD R4.xyz, R0.w, R1, R4;\n"
- "ADD R6.xyz, R4, -R5;\n"
- "MUL R4.xyz, R1, c[8].w;\n"
- "SGE R4.xyz, R4, R1.w;\n"
- "MAD R4.xyz, R4, R6, R5;\n"
- "MAD R4.xyz, -R1, R2, R4;\n"
- "SGE R3.xyz, R3, R0.w;\n"
- "MUL R2.xyz, R1, R2;\n"
- "ADD R2.w, -R1, c[8].x;\n"
- "MAD R2.xyz, R3, R4, R2;\n"
- "MAD R2.xyz, R0, R2.w, R2;\n"
- "ADD R0.x, -R0.w, c[8];\n"
- "MAD R2.xyz, R1, R0.x, R2;\n"
- "ADD R0.z, R0.w, R1.w;\n"
- "MAD R2.w, -R0, R1, R0.z;\n"
- "ADD R0.xy, fragment.position, c[6];\n"
- "MUL R0.xy, R0, c[4];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "ADD R2, R2, -R1;\n"
- "DP4 R0.x, R0, c[7];\n"
- "MAD result.color, R0.x, R2, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_DIFFERENCE =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 2 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.z, R0.x, R0.y;\n"
- "MUL R1.x, R0.z, c[0].z;\n"
- "MUL R0.xy, fragment.position, c[5];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "TEX R1, R1, texture[2], 1D;\n"
- "ADD R2.xyz, R1, R0;\n"
- "MUL R3.xyz, R1.w, R0;\n"
- "MUL R1.xyz, R1, R0.w;\n"
- "MIN R1.xyz, R1, R3;\n"
- "MAD R2.xyz, -R1, c[8].x, R2;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[6];\n"
- "MUL R1.xy, R1, c[4];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_EXCLUSION =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 2, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.z, R0.x, R0.y;\n"
- "MUL R1.x, R0.z, c[0].z;\n"
- "MUL R0.xy, fragment.position, c[5];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "TEX R1, R1, texture[2], 1D;\n"
- "MUL R2.xyz, R1.w, R0;\n"
- "MAD R3.xyz, R1, R0.w, R2;\n"
- "MUL R2.xyz, R1, R0;\n"
- "MAD R2.xyz, -R2, c[8].x, R3;\n"
- "ADD R2.w, -R0, c[8].y;\n"
- "MAD R1.xyz, R1, R2.w, R2;\n"
- "ADD R2.x, -R1.w, c[8].y;\n"
- "MAD R2.xyz, R0, R2.x, R1;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[6];\n"
- "MUL R1.xy, R1, c[4];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_SIMPLE_PORTER_DUFF_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[8] = { program.local[0..6],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.zw, fragment.position.xyxy, c[6].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "MUL R2.xyz, R1, c[4].y;\n"
- "MUL R0.x, R0, c[0].z;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "MUL R3.xyz, R0.w, R2;\n"
- "MUL R2.xyz, R0, c[4].x;\n"
- "MAD R2.xyz, R1.w, R2, R3;\n"
- "ADD R2.w, -R1, c[7].x;\n"
- "MUL R0.xyz, R0, c[5].y;\n"
- "MAD R0.xyz, R2.w, R0, R2;\n"
- "ADD R2.x, -R0.w, c[7];\n"
- "MUL R1.xyz, R1, c[5].z;\n"
- "MAD result.color.xyz, R2.x, R1, R0;\n"
- "MUL R0.x, R0.w, R1.w;\n"
- "MUL R0.z, R1.w, R2.x;\n"
- "MUL R0.y, R0.w, R2.w;\n"
- "DP3 result.color.w, R0, c[5];\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_MULTIPLY_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "MUL R0.x, R0, c[0].z;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "ADD R2.x, -R1.w, c[5];\n"
- "MUL R2.xyz, R0, R2.x;\n"
- "MAD R0.xyz, R0, R1, R2;\n"
- "ADD R2.x, R0.w, R1.w;\n"
- "ADD R2.y, -R0.w, c[5].x;\n"
- "MAD result.color.xyz, R1, R2.y, R0;\n"
- "MAD result.color.w, -R0, R1, R2.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_SCREEN_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[5] = { program.local[0..4] };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "MUL R0.x, R0, c[0].z;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "ADD R2, R0, R1;\n"
- "MAD result.color, -R0, R1, R2;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_OVERLAY_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 2, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.x, R0, c[0].z;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "MUL R1.xy, fragment.position, c[4];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "ADD R3.xyz, R0.w, -R0;\n"
- "ADD R2.xyz, R1.w, -R1;\n"
- "MUL R2.xyz, R2, R3;\n"
- "ADD R2.w, -R1, c[5].y;\n"
- "MUL R2.xyz, R2, c[5].x;\n"
- "MAD R2.xyz, R0.w, R1.w, -R2;\n"
- "MAD R2.xyz, R0, R2.w, R2;\n"
- "MUL R3.xyz, R0, R2.w;\n"
- "MUL R0.xyz, R0, R1;\n"
- "ADD R2.w, -R0, c[5].y;\n"
- "MAD R0.xyz, R0, c[5].x, R3;\n"
- "MAD R0.xyz, R1, R2.w, R0;\n"
- "MAD R2.xyz, R1, R2.w, R2;\n"
- "MUL R1.xyz, R1, c[5].x;\n"
- "ADD R2.w, R0, R1;\n"
- "ADD R2.xyz, R2, -R0;\n"
- "SGE R1.xyz, R1, R1.w;\n"
- "MAD result.color.xyz, R1, R2, R0;\n"
- "MAD result.color.w, -R0, R1, R2;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_DARKEN_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "MUL R0.x, R0, c[0].z;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "MUL R2.xyz, R0, R1.w;\n"
- "MUL R3.xyz, R0.w, R1;\n"
- "MIN R2.xyz, R2, R3;\n"
- "ADD R2.w, -R1, c[5].x;\n"
- "MAD R0.xyz, R0, R2.w, R2;\n"
- "ADD R2.x, R0.w, R1.w;\n"
- "ADD R2.y, -R0.w, c[5].x;\n"
- "MAD result.color.xyz, R1, R2.y, R0;\n"
- "MAD result.color.w, -R0, R1, R2.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_LIGHTEN_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "MUL R0.x, R0, c[0].z;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "MUL R2.xyz, R0, R1.w;\n"
- "MUL R3.xyz, R0.w, R1;\n"
- "MAX R2.xyz, R2, R3;\n"
- "ADD R2.w, -R1, c[5].x;\n"
- "MAD R0.xyz, R0, R2.w, R2;\n"
- "ADD R2.x, R0.w, R1.w;\n"
- "ADD R2.y, -R0.w, c[5].x;\n"
- "MAD result.color.xyz, R1, R2.y, R0;\n"
- "MAD result.color.w, -R0, R1, R2.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_COLORDODGE_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 1, 1e-006 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.x, R0, c[0].z;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "MAX R1.x, R0.w, c[5].y;\n"
- "RCP R1.x, R1.x;\n"
- "MAD R3.xyz, -R0, R1.x, c[5].x;\n"
- "MAX R3.xyz, R3, c[5].y;\n"
- "MUL R1.xy, fragment.position, c[4];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "ADD R2.x, -R0.w, c[5];\n"
- "MUL R2.xyz, R1, R2.x;\n"
- "ADD R2.w, -R1, c[5].x;\n"
- "MAD R2.xyz, R0, R2.w, R2;\n"
- "MUL R1.xyz, R0.w, R1;\n"
- "MAD R0.xyz, R0, R1.w, R1;\n"
- "MUL R2.w, R0, R1;\n"
- "RCP R3.x, R3.x;\n"
- "RCP R3.y, R3.y;\n"
- "RCP R3.z, R3.z;\n"
- "MAD R3.xyz, R1, R3, R2;\n"
- "MAD R2.xyz, R0.w, R1.w, R2;\n"
- "ADD R1.x, R0.w, R1.w;\n"
- "ADD R2.xyz, R2, -R3;\n"
- "SGE R0.xyz, R0, R2.w;\n"
- "MAD result.color.xyz, R0, R2, R3;\n"
- "MAD result.color.w, -R0, R1, R1.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_COLORBURN_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 1, 9.9999997e-006 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "TEMP R5;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "MUL R0.x, R0, c[0].z;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "MUL R2.xyz, R0.w, R1;\n"
- "MAD R3.xyz, R0, R1.w, R2;\n"
- "ADD R2.w, -R1, c[5].x;\n"
- "MAD R2.xyz, -R0.w, R1.w, R3;\n"
- "MUL R4.xyz, R0.w, R2;\n"
- "MAX R2.xyz, R0, c[5].y;\n"
- "MUL R5.xyz, R0, R2.w;\n"
- "ADD R3.w, -R0, c[5].x;\n"
- "RCP R2.x, R2.x;\n"
- "RCP R2.y, R2.y;\n"
- "RCP R2.z, R2.z;\n"
- "MAD R2.xyz, R4, R2, R5;\n"
- "MUL R4.xyz, R1, R3.w;\n"
- "MAD R1.xyz, R1, R3.w, R2;\n"
- "MAD R0.xyz, R0, R2.w, R4;\n"
- "MUL R2.x, R0.w, R1.w;\n"
- "ADD R2.w, R0, R1;\n"
- "ADD R1.xyz, R1, -R0;\n"
- "SGE R2.xyz, R3, R2.x;\n"
- "MAD result.color.xyz, R2, R1, R0;\n"
- "MAD result.color.w, -R0, R1, R2;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_HARDLIGHT_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 2, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.x, R0, c[0].z;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "MUL R1.xy, fragment.position, c[4];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "ADD R2.w, -R1, c[5].y;\n"
- "ADD R3.xyz, R0.w, -R0;\n"
- "ADD R2.xyz, R1.w, -R1;\n"
- "MUL R2.xyz, R2, R3;\n"
- "MUL R2.xyz, R2, c[5].x;\n"
- "MAD R2.xyz, R0.w, R1.w, -R2;\n"
- "MAD R2.xyz, R0, R2.w, R2;\n"
- "MUL R4.xyz, R0, R2.w;\n"
- "MUL R3.xyz, R0, R1;\n"
- "MUL R0.xyz, R0, c[5].x;\n"
- "ADD R2.w, -R0, c[5].y;\n"
- "MAD R3.xyz, R3, c[5].x, R4;\n"
- "MAD R3.xyz, R1, R2.w, R3;\n"
- "MAD R1.xyz, R1, R2.w, R2;\n"
- "ADD R2.x, R0.w, R1.w;\n"
- "ADD R1.xyz, R1, -R3;\n"
- "SGE R0.xyz, R0, R0.w;\n"
- "MAD result.color.xyz, R0, R1, R3;\n"
- "MAD result.color.w, -R0, R1, R2.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_SOFTLIGHT_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[7] = { program.local[0..4],\n"
- " { 1, 2, 9.9999997e-006, 4 },\n"
- " { 16, 12, 3 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "TEMP R5;\n"
- "TEMP R6;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R1.xy, fragment.position, c[4];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "MAX R0.z, R1.w, c[5];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R3.xyz, R1, R0.z;\n"
- "MAD R2.xyz, R3, c[6].x, -c[6].y;\n"
- "MUL R0.x, R0, c[0].z;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "MAD R4.xyz, R3, R2, c[6].z;\n"
- "MAD R2.xyz, R0, c[5].y, -R0.w;\n"
- "MUL R5.xyz, R1.w, R2;\n"
- "MUL R6.xyz, R5, R4;\n"
- "RSQ R2.w, R3.x;\n"
- "RCP R4.x, R2.w;\n"
- "RSQ R2.w, R3.y;\n"
- "RSQ R3.w, R3.z;\n"
- "RCP R4.y, R2.w;\n"
- "RCP R4.z, R3.w;\n"
- "ADD R4.xyz, -R3, R4;\n"
- "MUL R6.xyz, R3, R6;\n"
- "MUL R4.xyz, R5, R4;\n"
- "ADD R3.xyz, -R3, c[5].x;\n"
- "MAD R2.xyz, R2, R3, R0.w;\n"
- "MUL R3.xyz, R0, c[5].y;\n"
- "MAD R5.xyz, R0.w, R1, R6;\n"
- "MAD R4.xyz, R0.w, R1, R4;\n"
- "ADD R6.xyz, R4, -R5;\n"
- "MUL R4.xyz, R1, c[5].w;\n"
- "SGE R4.xyz, R4, R1.w;\n"
- "MAD R4.xyz, R4, R6, R5;\n"
- "MAD R4.xyz, -R1, R2, R4;\n"
- "MUL R2.xyz, R1, R2;\n"
- "SGE R3.xyz, R3, R0.w;\n"
- "MAD R2.xyz, R3, R4, R2;\n"
- "ADD R2.w, -R1, c[5].x;\n"
- "MAD R2.xyz, R0, R2.w, R2;\n"
- "ADD R0.x, R0.w, R1.w;\n"
- "ADD R0.y, -R0.w, c[5].x;\n"
- "MAD result.color.xyz, R1, R0.y, R2;\n"
- "MAD result.color.w, -R0, R1, R0.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_DIFFERENCE_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 2 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "MUL R0.x, R0, c[0].z;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "MUL R2.xyz, R0, R1.w;\n"
- "MUL R3.xyz, R0.w, R1;\n"
- "ADD R0.xyz, R0, R1;\n"
- "MIN R2.xyz, R2, R3;\n"
- "ADD R1.x, R0.w, R1.w;\n"
- "MAD result.color.xyz, -R2, c[5].x, R0;\n"
- "MAD result.color.w, -R0, R1, R1.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_EXCLUSION_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 2, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "MUL R0.x, R0, c[0].z;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "MUL R2.xyz, R0.w, R1;\n"
- "MAD R3.xyz, R0, R1.w, R2;\n"
- "MUL R2.xyz, R0, R1;\n"
- "MAD R2.xyz, -R2, c[5].x, R3;\n"
- "ADD R2.w, -R1, c[5].y;\n"
- "MAD R0.xyz, R0, R2.w, R2;\n"
- "ADD R2.x, R0.w, R1.w;\n"
- "ADD R2.y, -R0.w, c[5];\n"
- "MAD result.color.xyz, R1, R2.y, R0;\n"
- "MAD result.color.w, -R0, R1, R2.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODE_BLEND_MODE_MASK =
- "!!ARBfp1.0\n"
- "PARAM c[7] = { program.local[0..6] };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.z;\n"
- "MUL R0.zw, R0, c[0].xyxy;\n"
- "ADD R1.x, R0.z, R0.w;\n"
- "ADD R0.xy, fragment.position, c[5];\n"
- "MUL R0.xy, R0, c[4];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "DP4 R1.y, R0, c[6];\n"
- "MUL R1.x, R1, c[0].z;\n"
- "TEX R0, R1, texture[1], 1D;\n"
- "MUL result.color, R0, R1.y;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODE_BLEND_MODE_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[4] = { program.local[0..3] };\n"
- "TEMP R0;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.x, R0, c[0].z;\n"
- "TEX result.color, R0, texture[0], 1D;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_SIMPLE_PORTER_DUFF =
- "!!ARBfp1.0\n"
- "PARAM c[11] = { program.local[0..9],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R1.xyz, R0, c[3];\n"
- "RCP R0.z, R1.z;\n"
- "MUL R1.xy, R1, R0.z;\n"
- "MUL R0.xy, fragment.position, c[7];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "MUL R1.xy, R1, c[0];\n"
- "TEX R1, R1, texture[2], 2D;\n"
- "MUL R2.xyz, R0, c[4].y;\n"
- "MUL R3.xyz, R1.w, R2;\n"
- "MUL R2.xyz, R1, c[4].x;\n"
- "MAD R2.xyz, R0.w, R2, R3;\n"
- "ADD R3.xy, fragment.position, c[8];\n"
- "ADD R2.w, -R0, c[10].x;\n"
- "MUL R1.xyz, R1, c[5].y;\n"
- "MAD R2.xyz, R2.w, R1, R2;\n"
- "MUL R1.xyz, R0, c[5].z;\n"
- "ADD R3.z, -R1.w, c[10].x;\n"
- "MAD R2.xyz, R3.z, R1, R2;\n"
- "MUL R1.y, R1.w, R2.w;\n"
- "MUL R1.x, R1.w, R0.w;\n"
- "MUL R1.z, R0.w, R3;\n"
- "DP3 R2.w, R1, c[5];\n"
- "MUL R3.xy, R3, c[6];\n"
- "TEX R1, R3, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[9];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_MULTIPLY =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R1.xyz, R0, c[3];\n"
- "RCP R0.z, R1.z;\n"
- "MUL R1.xy, R1, R0.z;\n"
- "MUL R0.xy, fragment.position, c[5];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "MUL R1.xy, R1, c[0];\n"
- "TEX R1, R1, texture[2], 2D;\n"
- "ADD R2.x, -R0.w, c[8];\n"
- "MUL R2.xyz, R1, R2.x;\n"
- "MAD R1.xyz, R1, R0, R2;\n"
- "ADD R2.x, -R1.w, c[8];\n"
- "MAD R2.xyz, R0, R2.x, R1;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[6];\n"
- "MUL R1.xy, R1, c[4];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_SCREEN =
- "!!ARBfp1.0\n"
- "PARAM c[8] = { program.local[0..7] };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, c[0].xyxy;\n"
- "ADD R3.xy, fragment.position, c[6];\n"
- "TEX R1, R0.zwzw, texture[2], 2D;\n"
- "MUL R0.xy, fragment.position, c[5];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "ADD R2, R1, R0;\n"
- "MAD R2, -R1, R0, R2;\n"
- "MUL R3.xy, R3, c[4];\n"
- "TEX R1, R3, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_OVERLAY =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 2, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0, R0, texture[2], 2D;\n"
- "MUL R1.xy, fragment.position, c[5];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "ADD R2.w, -R1, c[8].y;\n"
- "ADD R3.xyz, R0.w, -R0;\n"
- "ADD R2.xyz, R1.w, -R1;\n"
- "MUL R2.xyz, R2, R3;\n"
- "MUL R2.xyz, R2, c[8].x;\n"
- "MAD R2.xyz, R0.w, R1.w, -R2;\n"
- "MUL R4.xyz, R0, R2.w;\n"
- "MUL R3.xyz, R0, R1;\n"
- "MAD R0.xyz, R0, R2.w, R2;\n"
- "ADD R2.x, -R0.w, c[8].y;\n"
- "MAD R3.xyz, R3, c[8].x, R4;\n"
- "MAD R3.xyz, R1, R2.x, R3;\n"
- "MAD R0.xyz, R1, R2.x, R0;\n"
- "MUL R2.xyz, R1, c[8].x;\n"
- "ADD R0.xyz, R0, -R3;\n"
- "SGE R2.xyz, R2, R1.w;\n"
- "MAD R2.xyz, R2, R0, R3;\n"
- "ADD R0.z, R0.w, R1.w;\n"
- "MAD R2.w, -R0, R1, R0.z;\n"
- "ADD R0.xy, fragment.position, c[6];\n"
- "MUL R0.xy, R0, c[4];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "ADD R2, R2, -R1;\n"
- "DP4 R0.x, R0, c[7];\n"
- "MAD result.color, R0.x, R2, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_DARKEN =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.z;\n"
- "MUL R1.xy, R0.zwzw, c[0];\n"
- "MUL R0.xy, fragment.position, c[5];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "TEX R1, R1, texture[2], 2D;\n"
- "MUL R3.xyz, R1.w, R0;\n"
- "MUL R2.xyz, R1, R0.w;\n"
- "MIN R2.xyz, R2, R3;\n"
- "ADD R2.w, -R0, c[8].x;\n"
- "MAD R1.xyz, R1, R2.w, R2;\n"
- "ADD R2.x, -R1.w, c[8];\n"
- "MAD R2.xyz, R0, R2.x, R1;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[6];\n"
- "MUL R1.xy, R1, c[4];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_LIGHTEN =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.z;\n"
- "MUL R1.xy, R0.zwzw, c[0];\n"
- "MUL R0.xy, fragment.position, c[5];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "TEX R1, R1, texture[2], 2D;\n"
- "MUL R3.xyz, R1.w, R0;\n"
- "MUL R2.xyz, R1, R0.w;\n"
- "MAX R2.xyz, R2, R3;\n"
- "ADD R2.w, -R0, c[8].x;\n"
- "MAD R1.xyz, R1, R2.w, R2;\n"
- "ADD R2.x, -R1.w, c[8];\n"
- "MAD R2.xyz, R0, R2.x, R1;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[6];\n"
- "MUL R1.xy, R1, c[4];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_COLORDODGE =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 1, 1e-006 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0, R0, texture[2], 2D;\n"
- "MAX R1.x, R0.w, c[8].y;\n"
- "RCP R1.x, R1.x;\n"
- "MAD R2.xyz, -R0, R1.x, c[8].x;\n"
- "MAX R2.xyz, R2, c[8].y;\n"
- "MUL R1.xy, fragment.position, c[5];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "ADD R2.w, -R0, c[8].x;\n"
- "MUL R3.xyz, R1, R2.w;\n"
- "ADD R2.w, -R1, c[8].x;\n"
- "MAD R4.xyz, R0, R2.w, R3;\n"
- "MUL R3.xyz, R0.w, R1;\n"
- "MUL R2.w, R0, R1;\n"
- "MAD R0.xyz, R0, R1.w, R3;\n"
- "SGE R0.xyz, R0, R2.w;\n"
- "RCP R2.x, R2.x;\n"
- "RCP R2.y, R2.y;\n"
- "RCP R2.z, R2.z;\n"
- "MAD R2.xyz, R3, R2, R4;\n"
- "MAD R4.xyz, R0.w, R1.w, R4;\n"
- "ADD R4.xyz, R4, -R2;\n"
- "MAD R2.xyz, R0, R4, R2;\n"
- "ADD R0.z, R0.w, R1.w;\n"
- "MAD R2.w, -R0, R1, R0.z;\n"
- "ADD R0.xy, fragment.position, c[6];\n"
- "MUL R0.xy, R0, c[4];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "ADD R2, R2, -R1;\n"
- "DP4 R0.x, R0, c[7];\n"
- "MAD result.color, R0.x, R2, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_COLORBURN =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 1, 9.9999997e-006 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "TEMP R5;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, fragment.position.xyxy, c[5].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0, R0, texture[2], 2D;\n"
- "MUL R2.xyz, R0.w, R1;\n"
- "MAD R3.xyz, R0, R1.w, R2;\n"
- "MAD R2.xyz, -R0.w, R1.w, R3;\n"
- "MUL R4.xyz, R0.w, R2;\n"
- "MAX R2.xyz, R0, c[8].y;\n"
- "ADD R2.w, -R1, c[8].x;\n"
- "MUL R5.xyz, R0, R2.w;\n"
- "ADD R3.w, -R0, c[8].x;\n"
- "RCP R2.x, R2.x;\n"
- "RCP R2.y, R2.y;\n"
- "RCP R2.z, R2.z;\n"
- "MAD R2.xyz, R4, R2, R5;\n"
- "MUL R4.xyz, R1, R3.w;\n"
- "MAD R0.xyz, R0, R2.w, R4;\n"
- "MUL R2.w, R0, R1;\n"
- "MAD R2.xyz, R1, R3.w, R2;\n"
- "ADD R2.xyz, R2, -R0;\n"
- "SGE R3.xyz, R3, R2.w;\n"
- "MAD R2.xyz, R3, R2, R0;\n"
- "ADD R0.z, R0.w, R1.w;\n"
- "MAD R2.w, -R0, R1, R0.z;\n"
- "ADD R0.xy, fragment.position, c[6];\n"
- "MUL R0.xy, R0, c[4];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "ADD R2, R2, -R1;\n"
- "DP4 R0.x, R0, c[7];\n"
- "MAD result.color, R0.x, R2, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_HARDLIGHT =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 2, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0, R0, texture[2], 2D;\n"
- "MUL R1.xy, fragment.position, c[5];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "ADD R2.w, -R1, c[8].y;\n"
- "ADD R3.xyz, R0.w, -R0;\n"
- "ADD R2.xyz, R1.w, -R1;\n"
- "MUL R2.xyz, R2, R3;\n"
- "MUL R2.xyz, R2, c[8].x;\n"
- "MAD R2.xyz, R0.w, R1.w, -R2;\n"
- "MUL R4.xyz, R0, R2.w;\n"
- "MAD R2.xyz, R0, R2.w, R2;\n"
- "MUL R3.xyz, R0, R1;\n"
- "ADD R2.w, -R0, c[8].y;\n"
- "MAD R3.xyz, R3, c[8].x, R4;\n"
- "MUL R0.xyz, R0, c[8].x;\n"
- "SGE R0.xyz, R0, R0.w;\n"
- "MAD R3.xyz, R1, R2.w, R3;\n"
- "MAD R2.xyz, R1, R2.w, R2;\n"
- "ADD R2.xyz, R2, -R3;\n"
- "MAD R2.xyz, R0, R2, R3;\n"
- "ADD R0.z, R0.w, R1.w;\n"
- "MAD R2.w, -R0, R1, R0.z;\n"
- "ADD R0.xy, fragment.position, c[6];\n"
- "MUL R0.xy, R0, c[4];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "ADD R2, R2, -R1;\n"
- "DP4 R0.x, R0, c[7];\n"
- "MAD result.color, R0.x, R2, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_SOFTLIGHT =
- "!!ARBfp1.0\n"
- "PARAM c[10] = { program.local[0..7],\n"
- " { 1, 2, 9.9999997e-006, 4 },\n"
- " { 16, 12, 3 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "TEMP R5;\n"
- "TEMP R6;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MUL R1.xy, fragment.position, c[5];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MAX R0.w, R1, c[8].z;\n"
- "RCP R0.w, R0.w;\n"
- "MUL R3.xyz, R1, R0.w;\n"
- "MAD R2.xyz, R3, c[9].x, -c[9].y;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0, R0, texture[2], 2D;\n"
- "MAD R4.xyz, R3, R2, c[9].z;\n"
- "MAD R2.xyz, R0, c[8].y, -R0.w;\n"
- "MUL R5.xyz, R1.w, R2;\n"
- "MUL R6.xyz, R5, R4;\n"
- "RSQ R2.w, R3.x;\n"
- "RCP R4.x, R2.w;\n"
- "RSQ R2.w, R3.y;\n"
- "RSQ R3.w, R3.z;\n"
- "RCP R4.y, R2.w;\n"
- "RCP R4.z, R3.w;\n"
- "ADD R4.xyz, -R3, R4;\n"
- "MUL R6.xyz, R3, R6;\n"
- "MUL R4.xyz, R5, R4;\n"
- "ADD R3.xyz, -R3, c[8].x;\n"
- "MAD R2.xyz, R2, R3, R0.w;\n"
- "MUL R3.xyz, R0, c[8].y;\n"
- "MAD R5.xyz, R0.w, R1, R6;\n"
- "MAD R4.xyz, R0.w, R1, R4;\n"
- "ADD R6.xyz, R4, -R5;\n"
- "MUL R4.xyz, R1, c[8].w;\n"
- "SGE R4.xyz, R4, R1.w;\n"
- "MAD R4.xyz, R4, R6, R5;\n"
- "MAD R4.xyz, -R1, R2, R4;\n"
- "SGE R3.xyz, R3, R0.w;\n"
- "MUL R2.xyz, R1, R2;\n"
- "ADD R2.w, -R1, c[8].x;\n"
- "MAD R2.xyz, R3, R4, R2;\n"
- "MAD R2.xyz, R0, R2.w, R2;\n"
- "ADD R0.x, -R0.w, c[8];\n"
- "MAD R2.xyz, R1, R0.x, R2;\n"
- "ADD R0.z, R0.w, R1.w;\n"
- "MAD R2.w, -R0, R1, R0.z;\n"
- "ADD R0.xy, fragment.position, c[6];\n"
- "MUL R0.xy, R0, c[4];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "ADD R2, R2, -R1;\n"
- "DP4 R0.x, R0, c[7];\n"
- "MAD result.color, R0.x, R2, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_DIFFERENCE =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 2 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.z;\n"
- "MUL R1.xy, R0.zwzw, c[0];\n"
- "MUL R0.xy, fragment.position, c[5];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "TEX R1, R1, texture[2], 2D;\n"
- "ADD R2.xyz, R1, R0;\n"
- "MUL R3.xyz, R1.w, R0;\n"
- "MUL R1.xyz, R1, R0.w;\n"
- "MIN R1.xyz, R1, R3;\n"
- "MAD R2.xyz, -R1, c[8].x, R2;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[6];\n"
- "MUL R1.xy, R1, c[4];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_EXCLUSION =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 2, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.z;\n"
- "MUL R1.xy, R0.zwzw, c[0];\n"
- "MUL R0.xy, fragment.position, c[5];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "TEX R1, R1, texture[2], 2D;\n"
- "MUL R2.xyz, R1.w, R0;\n"
- "MAD R3.xyz, R1, R0.w, R2;\n"
- "MUL R2.xyz, R1, R0;\n"
- "MAD R2.xyz, -R2, c[8].x, R3;\n"
- "ADD R2.w, -R0, c[8].y;\n"
- "MAD R1.xyz, R1, R2.w, R2;\n"
- "ADD R2.x, -R1.w, c[8].y;\n"
- "MAD R2.xyz, R0, R2.x, R1;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[6];\n"
- "MUL R1.xy, R1, c[4];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_SIMPLE_PORTER_DUFF_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[8] = { program.local[0..6],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R1.xy, fragment.position, c[6];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "MUL R2.xyz, R1, c[4].y;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "MUL R3.xyz, R0.w, R2;\n"
- "MUL R2.xyz, R0, c[4].x;\n"
- "MAD R2.xyz, R1.w, R2, R3;\n"
- "ADD R2.w, -R1, c[7].x;\n"
- "MUL R0.xyz, R0, c[5].y;\n"
- "MAD R0.xyz, R2.w, R0, R2;\n"
- "ADD R2.x, -R0.w, c[7];\n"
- "MUL R1.xyz, R1, c[5].z;\n"
- "MAD result.color.xyz, R2.x, R1, R0;\n"
- "MUL R0.x, R0.w, R1.w;\n"
- "MUL R0.z, R1.w, R2.x;\n"
- "MUL R0.y, R0.w, R2.w;\n"
- "DP3 result.color.w, R0, c[5];\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_MULTIPLY_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R1.xy, fragment.position, c[4];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "ADD R2.x, -R1.w, c[5];\n"
- "MUL R2.xyz, R0, R2.x;\n"
- "MAD R0.xyz, R0, R1, R2;\n"
- "ADD R2.x, R0.w, R1.w;\n"
- "ADD R2.y, -R0.w, c[5].x;\n"
- "MAD result.color.xyz, R1, R2.y, R0;\n"
- "MAD result.color.w, -R0, R1, R2.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_SCREEN_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[5] = { program.local[0..4] };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "ADD R2, R0, R1;\n"
- "MAD result.color, -R0, R1, R2;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_OVERLAY_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 2, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "MUL R1.xy, fragment.position, c[4];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "ADD R3.xyz, R0.w, -R0;\n"
- "ADD R2.xyz, R1.w, -R1;\n"
- "MUL R2.xyz, R2, R3;\n"
- "ADD R2.w, -R1, c[5].y;\n"
- "MUL R2.xyz, R2, c[5].x;\n"
- "MAD R2.xyz, R0.w, R1.w, -R2;\n"
- "MAD R2.xyz, R0, R2.w, R2;\n"
- "MUL R3.xyz, R0, R2.w;\n"
- "MUL R0.xyz, R0, R1;\n"
- "ADD R2.w, -R0, c[5].y;\n"
- "MAD R0.xyz, R0, c[5].x, R3;\n"
- "MAD R0.xyz, R1, R2.w, R0;\n"
- "MAD R2.xyz, R1, R2.w, R2;\n"
- "MUL R1.xyz, R1, c[5].x;\n"
- "ADD R2.w, R0, R1;\n"
- "ADD R2.xyz, R2, -R0;\n"
- "SGE R1.xyz, R1, R1.w;\n"
- "MAD result.color.xyz, R1, R2, R0;\n"
- "MAD result.color.w, -R0, R1, R2;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_DARKEN_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "MUL R2.xyz, R0, R1.w;\n"
- "MUL R3.xyz, R0.w, R1;\n"
- "MIN R2.xyz, R2, R3;\n"
- "ADD R2.w, -R1, c[5].x;\n"
- "MAD R0.xyz, R0, R2.w, R2;\n"
- "ADD R2.x, R0.w, R1.w;\n"
- "ADD R2.y, -R0.w, c[5].x;\n"
- "MAD result.color.xyz, R1, R2.y, R0;\n"
- "MAD result.color.w, -R0, R1, R2.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_LIGHTEN_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "MUL R2.xyz, R0, R1.w;\n"
- "MUL R3.xyz, R0.w, R1;\n"
- "MAX R2.xyz, R2, R3;\n"
- "ADD R2.w, -R1, c[5].x;\n"
- "MAD R0.xyz, R0, R2.w, R2;\n"
- "ADD R2.x, R0.w, R1.w;\n"
- "ADD R2.y, -R0.w, c[5].x;\n"
- "MAD result.color.xyz, R1, R2.y, R0;\n"
- "MAD result.color.w, -R0, R1, R2.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_COLORDODGE_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 1, 1e-006 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "MAX R1.x, R0.w, c[5].y;\n"
- "RCP R1.x, R1.x;\n"
- "MAD R3.xyz, -R0, R1.x, c[5].x;\n"
- "MAX R3.xyz, R3, c[5].y;\n"
- "MUL R1.xy, fragment.position, c[4];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "ADD R2.x, -R0.w, c[5];\n"
- "MUL R2.xyz, R1, R2.x;\n"
- "ADD R2.w, -R1, c[5].x;\n"
- "MAD R2.xyz, R0, R2.w, R2;\n"
- "MUL R1.xyz, R0.w, R1;\n"
- "MAD R0.xyz, R0, R1.w, R1;\n"
- "MUL R2.w, R0, R1;\n"
- "RCP R3.x, R3.x;\n"
- "RCP R3.y, R3.y;\n"
- "RCP R3.z, R3.z;\n"
- "MAD R3.xyz, R1, R3, R2;\n"
- "MAD R2.xyz, R0.w, R1.w, R2;\n"
- "ADD R1.x, R0.w, R1.w;\n"
- "ADD R2.xyz, R2, -R3;\n"
- "SGE R0.xyz, R0, R2.w;\n"
- "MAD result.color.xyz, R0, R2, R3;\n"
- "MAD result.color.w, -R0, R1, R1.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_COLORBURN_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 1, 9.9999997e-006 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "TEMP R5;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "MUL R2.xyz, R0.w, R1;\n"
- "MAD R3.xyz, R0, R1.w, R2;\n"
- "ADD R2.w, -R1, c[5].x;\n"
- "MAD R2.xyz, -R0.w, R1.w, R3;\n"
- "MUL R4.xyz, R0.w, R2;\n"
- "MAX R2.xyz, R0, c[5].y;\n"
- "MUL R5.xyz, R0, R2.w;\n"
- "ADD R3.w, -R0, c[5].x;\n"
- "RCP R2.x, R2.x;\n"
- "RCP R2.y, R2.y;\n"
- "RCP R2.z, R2.z;\n"
- "MAD R2.xyz, R4, R2, R5;\n"
- "MUL R4.xyz, R1, R3.w;\n"
- "MAD R1.xyz, R1, R3.w, R2;\n"
- "MAD R0.xyz, R0, R2.w, R4;\n"
- "MUL R2.x, R0.w, R1.w;\n"
- "ADD R2.w, R0, R1;\n"
- "ADD R1.xyz, R1, -R0;\n"
- "SGE R2.xyz, R3, R2.x;\n"
- "MAD result.color.xyz, R2, R1, R0;\n"
- "MAD result.color.w, -R0, R1, R2;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_HARDLIGHT_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 2, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "MUL R1.xy, fragment.position, c[4];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "ADD R2.w, -R1, c[5].y;\n"
- "ADD R3.xyz, R0.w, -R0;\n"
- "ADD R2.xyz, R1.w, -R1;\n"
- "MUL R2.xyz, R2, R3;\n"
- "MUL R2.xyz, R2, c[5].x;\n"
- "MAD R2.xyz, R0.w, R1.w, -R2;\n"
- "MAD R2.xyz, R0, R2.w, R2;\n"
- "MUL R4.xyz, R0, R2.w;\n"
- "MUL R3.xyz, R0, R1;\n"
- "MUL R0.xyz, R0, c[5].x;\n"
- "ADD R2.w, -R0, c[5].y;\n"
- "MAD R3.xyz, R3, c[5].x, R4;\n"
- "MAD R3.xyz, R1, R2.w, R3;\n"
- "MAD R1.xyz, R1, R2.w, R2;\n"
- "ADD R2.x, R0.w, R1.w;\n"
- "ADD R1.xyz, R1, -R3;\n"
- "SGE R0.xyz, R0, R0.w;\n"
- "MAD result.color.xyz, R0, R1, R3;\n"
- "MAD result.color.w, -R0, R1, R2.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_SOFTLIGHT_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[7] = { program.local[0..4],\n"
- " { 1, 2, 9.9999997e-006, 4 },\n"
- " { 16, 12, 3 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "TEMP R5;\n"
- "TEMP R6;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MUL R1.xy, fragment.position, c[4];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MAX R0.w, R1, c[5].z;\n"
- "RCP R0.w, R0.w;\n"
- "MUL R3.xyz, R1, R0.w;\n"
- "MAD R2.xyz, R3, c[6].x, -c[6].y;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "MAD R4.xyz, R3, R2, c[6].z;\n"
- "MAD R2.xyz, R0, c[5].y, -R0.w;\n"
- "MUL R5.xyz, R1.w, R2;\n"
- "MUL R6.xyz, R5, R4;\n"
- "RSQ R2.w, R3.x;\n"
- "RCP R4.x, R2.w;\n"
- "RSQ R2.w, R3.y;\n"
- "RSQ R3.w, R3.z;\n"
- "RCP R4.y, R2.w;\n"
- "RCP R4.z, R3.w;\n"
- "ADD R4.xyz, -R3, R4;\n"
- "MUL R6.xyz, R3, R6;\n"
- "MUL R4.xyz, R5, R4;\n"
- "ADD R3.xyz, -R3, c[5].x;\n"
- "MAD R2.xyz, R2, R3, R0.w;\n"
- "MUL R3.xyz, R0, c[5].y;\n"
- "MAD R5.xyz, R0.w, R1, R6;\n"
- "MAD R4.xyz, R0.w, R1, R4;\n"
- "ADD R6.xyz, R4, -R5;\n"
- "MUL R4.xyz, R1, c[5].w;\n"
- "SGE R4.xyz, R4, R1.w;\n"
- "MAD R4.xyz, R4, R6, R5;\n"
- "MAD R4.xyz, -R1, R2, R4;\n"
- "MUL R2.xyz, R1, R2;\n"
- "SGE R3.xyz, R3, R0.w;\n"
- "MAD R2.xyz, R3, R4, R2;\n"
- "ADD R2.w, -R1, c[5].x;\n"
- "MAD R2.xyz, R0, R2.w, R2;\n"
- "ADD R0.x, R0.w, R1.w;\n"
- "ADD R0.y, -R0.w, c[5].x;\n"
- "MAD result.color.xyz, R1, R0.y, R2;\n"
- "MAD result.color.w, -R0, R1, R0.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_DIFFERENCE_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 2 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "MUL R2.xyz, R0, R1.w;\n"
- "MUL R3.xyz, R0.w, R1;\n"
- "ADD R0.xyz, R0, R1;\n"
- "MIN R2.xyz, R2, R3;\n"
- "ADD R1.x, R0.w, R1.w;\n"
- "MAD result.color.xyz, -R2, c[5].x, R0;\n"
- "MAD result.color.w, -R0, R1, R1.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_EXCLUSION_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 2, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "MUL R2.xyz, R0.w, R1;\n"
- "MAD R3.xyz, R0, R1.w, R2;\n"
- "MUL R2.xyz, R0, R1;\n"
- "MAD R2.xyz, -R2, c[5].x, R3;\n"
- "ADD R2.w, -R1, c[5].y;\n"
- "MAD R0.xyz, R0, R2.w, R2;\n"
- "ADD R2.x, R0.w, R1.w;\n"
- "ADD R2.y, -R0.w, c[5];\n"
- "MAD result.color.xyz, R1, R2.y, R0;\n"
- "MAD result.color.w, -R0, R1, R2.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODE_BLEND_MODE_MASK =
- "!!ARBfp1.0\n"
- "PARAM c[7] = { program.local[0..6] };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R1.xyz, R0, c[3];\n"
- "RCP R0.z, R1.z;\n"
- "MUL R1.xy, R1, R0.z;\n"
- "ADD R0.xy, fragment.position, c[5];\n"
- "MUL R0.xy, R0, c[4];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "DP4 R1.z, R0, c[6];\n"
- "MUL R1.xy, R1, c[0];\n"
- "TEX R0, R1, texture[1], 2D;\n"
- "MUL result.color, R0, R1.z;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODE_BLEND_MODE_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[4] = { program.local[0..3] };\n"
- "TEMP R0;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX result.color, R0, texture[0], 2D;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_SIMPLE_PORTER_DUFF =
- "!!ARBfp1.0\n"
- "PARAM c[11] = { program.local[0..9],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, c[0].xyxy;\n"
- "TEX R1.x, R0.zwzw, texture[2], 2D;\n"
- "MUL R0.xy, fragment.position, c[7];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "ADD R1.x, -R1, c[10];\n"
- "MUL R1, fragment.color.primary, R1.x;\n"
- "MUL R2.xyz, R0, c[4].y;\n"
- "MUL R3.xyz, R1.w, R2;\n"
- "MUL R2.xyz, R1, c[4].x;\n"
- "MAD R2.xyz, R0.w, R2, R3;\n"
- "ADD R3.xy, fragment.position, c[8];\n"
- "ADD R2.w, -R0, c[10].x;\n"
- "MUL R1.xyz, R1, c[5].y;\n"
- "MAD R2.xyz, R2.w, R1, R2;\n"
- "MUL R1.xyz, R0, c[5].z;\n"
- "ADD R3.z, -R1.w, c[10].x;\n"
- "MAD R2.xyz, R3.z, R1, R2;\n"
- "MUL R1.y, R1.w, R2.w;\n"
- "MUL R1.x, R1.w, R0.w;\n"
- "MUL R1.z, R0.w, R3;\n"
- "DP3 R2.w, R1, c[5];\n"
- "MUL R3.xy, R3, c[6];\n"
- "TEX R1, R3, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[9];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_MULTIPLY =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, c[0].xyxy;\n"
- "TEX R1.x, R0.zwzw, texture[2], 2D;\n"
- "MUL R0.xy, fragment.position, c[5];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "ADD R1.x, -R1, c[8];\n"
- "MUL R1, fragment.color.primary, R1.x;\n"
- "ADD R2.x, -R0.w, c[8];\n"
- "MUL R2.xyz, R1, R2.x;\n"
- "MAD R1.xyz, R1, R0, R2;\n"
- "ADD R2.x, -R1.w, c[8];\n"
- "MAD R2.xyz, R0, R2.x, R1;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[6];\n"
- "MUL R1.xy, R1, c[4];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_SCREEN =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0.x, R0, texture[2], 2D;\n"
- "ADD R0.z, -R0.x, c[8].x;\n"
- "ADD R3.xy, fragment.position, c[6];\n"
- "MUL R1, fragment.color.primary, R0.z;\n"
- "MUL R0.xy, fragment.position, c[5];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "ADD R2, R1, R0;\n"
- "MAD R2, -R1, R0, R2;\n"
- "MUL R3.xy, R3, c[4];\n"
- "TEX R1, R3, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_OVERLAY =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 1, 2 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0.x, R0, texture[2], 2D;\n"
- "ADD R0.x, -R0, c[8];\n"
- "MUL R1, fragment.color.primary, R0.x;\n"
- "MUL R0.zw, fragment.position.xyxy, c[5].xyxy;\n"
- "TEX R0, R0.zwzw, texture[0], 2D;\n"
- "ADD R2.w, -R0, c[8].x;\n"
- "ADD R3.xyz, R1.w, -R1;\n"
- "ADD R2.xyz, R0.w, -R0;\n"
- "MUL R2.xyz, R2, R3;\n"
- "MUL R2.xyz, R2, c[8].y;\n"
- "MAD R2.xyz, R1.w, R0.w, -R2;\n"
- "MUL R4.xyz, R1, R2.w;\n"
- "MUL R3.xyz, R1, R0;\n"
- "MAD R1.xyz, R1, R2.w, R2;\n"
- "ADD R2.x, -R1.w, c[8];\n"
- "MAD R3.xyz, R3, c[8].y, R4;\n"
- "MAD R3.xyz, R0, R2.x, R3;\n"
- "MAD R1.xyz, R0, R2.x, R1;\n"
- "MUL R2.xyz, R0, c[8].y;\n"
- "ADD R1.xyz, R1, -R3;\n"
- "SGE R2.xyz, R2, R0.w;\n"
- "MAD R2.xyz, R2, R1, R3;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[6];\n"
- "MUL R1.xy, R1, c[4];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_DARKEN =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R1.x, R0, texture[2], 2D;\n"
- "MUL R0.xy, fragment.position, c[5];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "ADD R1.x, -R1, c[8];\n"
- "MUL R1, fragment.color.primary, R1.x;\n"
- "MUL R3.xyz, R1.w, R0;\n"
- "MUL R2.xyz, R1, R0.w;\n"
- "MIN R2.xyz, R2, R3;\n"
- "ADD R2.w, -R0, c[8].x;\n"
- "MAD R1.xyz, R1, R2.w, R2;\n"
- "ADD R2.x, -R1.w, c[8];\n"
- "MAD R2.xyz, R0, R2.x, R1;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[6];\n"
- "MUL R1.xy, R1, c[4];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_LIGHTEN =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R1.x, R0, texture[2], 2D;\n"
- "MUL R0.xy, fragment.position, c[5];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "ADD R1.x, -R1, c[8];\n"
- "MUL R1, fragment.color.primary, R1.x;\n"
- "MUL R3.xyz, R1.w, R0;\n"
- "MUL R2.xyz, R1, R0.w;\n"
- "MAX R2.xyz, R2, R3;\n"
- "ADD R2.w, -R0, c[8].x;\n"
- "MAD R1.xyz, R1, R2.w, R2;\n"
- "ADD R2.x, -R1.w, c[8];\n"
- "MAD R2.xyz, R0, R2.x, R1;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[6];\n"
- "MUL R1.xy, R1, c[4];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_COLORDODGE =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 1, 1e-006 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0.x, R0, texture[2], 2D;\n"
- "ADD R0.x, -R0, c[8];\n"
- "MUL R1, fragment.color.primary, R0.x;\n"
- "MAX R0.x, R1.w, c[8].y;\n"
- "RCP R0.x, R0.x;\n"
- "MAD R2.xyz, -R1, R0.x, c[8].x;\n"
- "MAX R2.xyz, R2, c[8].y;\n"
- "MUL R0.xy, fragment.position, c[5];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "ADD R2.w, -R1, c[8].x;\n"
- "MUL R3.xyz, R0, R2.w;\n"
- "ADD R2.w, -R0, c[8].x;\n"
- "MAD R4.xyz, R1, R2.w, R3;\n"
- "MUL R3.xyz, R1.w, R0;\n"
- "MUL R2.w, R1, R0;\n"
- "MAD R1.xyz, R1, R0.w, R3;\n"
- "SGE R1.xyz, R1, R2.w;\n"
- "RCP R2.x, R2.x;\n"
- "RCP R2.y, R2.y;\n"
- "RCP R2.z, R2.z;\n"
- "MAD R2.xyz, R3, R2, R4;\n"
- "MAD R4.xyz, R1.w, R0.w, R4;\n"
- "ADD R4.xyz, R4, -R2;\n"
- "MAD R2.xyz, R1, R4, R2;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[6];\n"
- "MUL R1.xy, R1, c[4];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_COLORBURN =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 1, 9.9999997e-006 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "TEMP R5;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0.x, R0, texture[2], 2D;\n"
- "ADD R1.x, -R0, c[8];\n"
- "MUL R1, fragment.color.primary, R1.x;\n"
- "MUL R0.zw, fragment.position.xyxy, c[5].xyxy;\n"
- "TEX R0, R0.zwzw, texture[0], 2D;\n"
- "MUL R2.xyz, R1.w, R0;\n"
- "MAD R3.xyz, R1, R0.w, R2;\n"
- "MAD R2.xyz, -R1.w, R0.w, R3;\n"
- "MUL R4.xyz, R1.w, R2;\n"
- "MAX R2.xyz, R1, c[8].y;\n"
- "ADD R2.w, -R0, c[8].x;\n"
- "MUL R5.xyz, R1, R2.w;\n"
- "ADD R3.w, -R1, c[8].x;\n"
- "RCP R2.x, R2.x;\n"
- "RCP R2.y, R2.y;\n"
- "RCP R2.z, R2.z;\n"
- "MAD R2.xyz, R4, R2, R5;\n"
- "MUL R4.xyz, R0, R3.w;\n"
- "MAD R1.xyz, R1, R2.w, R4;\n"
- "MUL R2.w, R1, R0;\n"
- "MAD R2.xyz, R0, R3.w, R2;\n"
- "ADD R2.xyz, R2, -R1;\n"
- "SGE R3.xyz, R3, R2.w;\n"
- "MAD R2.xyz, R3, R2, R1;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[6];\n"
- "MUL R1.xy, R1, c[4];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_HARDLIGHT =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 1, 2 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0.x, R0, texture[2], 2D;\n"
- "ADD R0.x, -R0, c[8];\n"
- "MUL R1, fragment.color.primary, R0.x;\n"
- "MUL R0.zw, fragment.position.xyxy, c[5].xyxy;\n"
- "TEX R0, R0.zwzw, texture[0], 2D;\n"
- "ADD R2.w, -R0, c[8].x;\n"
- "ADD R3.xyz, R1.w, -R1;\n"
- "ADD R2.xyz, R0.w, -R0;\n"
- "MUL R2.xyz, R2, R3;\n"
- "MUL R2.xyz, R2, c[8].y;\n"
- "MAD R2.xyz, R1.w, R0.w, -R2;\n"
- "MUL R4.xyz, R1, R2.w;\n"
- "MAD R2.xyz, R1, R2.w, R2;\n"
- "MUL R3.xyz, R1, R0;\n"
- "ADD R2.w, -R1, c[8].x;\n"
- "MAD R3.xyz, R3, c[8].y, R4;\n"
- "MUL R1.xyz, R1, c[8].y;\n"
- "SGE R1.xyz, R1, R1.w;\n"
- "MAD R3.xyz, R0, R2.w, R3;\n"
- "MAD R2.xyz, R0, R2.w, R2;\n"
- "ADD R2.xyz, R2, -R3;\n"
- "MAD R2.xyz, R1, R2, R3;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[6];\n"
- "MUL R1.xy, R1, c[4];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_SOFTLIGHT =
- "!!ARBfp1.0\n"
- "PARAM c[10] = { program.local[0..7],\n"
- " { 1, 2, 9.9999997e-006, 4 },\n"
- " { 16, 12, 3 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "TEMP R5;\n"
- "TEMP R6;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R1.xyz, R0, c[3];\n"
- "RCP R1.z, R1.z;\n"
- "MUL R1.xy, R1, R1.z;\n"
- "MUL R1.xy, R1, c[0];\n"
- "TEX R1.x, R1, texture[2], 2D;\n"
- "MUL R0.xy, fragment.position, c[5];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "MAX R1.z, R0.w, c[8];\n"
- "RCP R1.z, R1.z;\n"
- "MUL R3.xyz, R0, R1.z;\n"
- "MAD R2.xyz, R3, c[9].x, -c[9].y;\n"
- "ADD R1.x, -R1, c[8];\n"
- "MUL R1, fragment.color.primary, R1.x;\n"
- "MAD R4.xyz, R3, R2, c[9].z;\n"
- "MAD R2.xyz, R1, c[8].y, -R1.w;\n"
- "MUL R5.xyz, R0.w, R2;\n"
- "MUL R6.xyz, R5, R4;\n"
- "RSQ R2.w, R3.x;\n"
- "RCP R4.x, R2.w;\n"
- "RSQ R2.w, R3.y;\n"
- "RSQ R3.w, R3.z;\n"
- "RCP R4.y, R2.w;\n"
- "RCP R4.z, R3.w;\n"
- "ADD R4.xyz, -R3, R4;\n"
- "MUL R6.xyz, R3, R6;\n"
- "MUL R4.xyz, R5, R4;\n"
- "ADD R3.xyz, -R3, c[8].x;\n"
- "MAD R2.xyz, R2, R3, R1.w;\n"
- "MUL R3.xyz, R1, c[8].y;\n"
- "MAD R5.xyz, R1.w, R0, R6;\n"
- "MAD R4.xyz, R1.w, R0, R4;\n"
- "ADD R6.xyz, R4, -R5;\n"
- "MUL R4.xyz, R0, c[8].w;\n"
- "SGE R4.xyz, R4, R0.w;\n"
- "MAD R4.xyz, R4, R6, R5;\n"
- "MAD R4.xyz, -R0, R2, R4;\n"
- "SGE R3.xyz, R3, R1.w;\n"
- "MUL R2.xyz, R0, R2;\n"
- "ADD R2.w, -R0, c[8].x;\n"
- "MAD R2.xyz, R3, R4, R2;\n"
- "MAD R2.xyz, R1, R2.w, R2;\n"
- "ADD R1.x, -R1.w, c[8];\n"
- "MAD R2.xyz, R0, R1.x, R2;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[6];\n"
- "MUL R1.xy, R1, c[4];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_DIFFERENCE =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 1, 2 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R1.x, R0, texture[2], 2D;\n"
- "MUL R0.xy, fragment.position, c[5];\n"
- "ADD R1.x, -R1, c[8];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "MUL R1, fragment.color.primary, R1.x;\n"
- "ADD R2.xyz, R1, R0;\n"
- "MUL R3.xyz, R1.w, R0;\n"
- "MUL R1.xyz, R1, R0.w;\n"
- "MIN R1.xyz, R1, R3;\n"
- "MAD R2.xyz, -R1, c[8].y, R2;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[6];\n"
- "MUL R1.xy, R1, c[4];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_EXCLUSION =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 1, 2 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R1.x, R0, texture[2], 2D;\n"
- "MUL R0.xy, fragment.position, c[5];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "ADD R1.x, -R1, c[8];\n"
- "MUL R1, fragment.color.primary, R1.x;\n"
- "MUL R2.xyz, R1.w, R0;\n"
- "MAD R3.xyz, R1, R0.w, R2;\n"
- "MUL R2.xyz, R1, R0;\n"
- "MAD R2.xyz, -R2, c[8].y, R3;\n"
- "ADD R2.w, -R0, c[8].x;\n"
- "MAD R1.xyz, R1, R2.w, R2;\n"
- "ADD R2.x, -R1.w, c[8];\n"
- "MAD R2.xyz, R0, R2.x, R1;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[6];\n"
- "MUL R1.xy, R1, c[4];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_SIMPLE_PORTER_DUFF_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[8] = { program.local[0..6],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R1.x, R0, texture[1], 2D;\n"
- "MUL R0.zw, fragment.position.xyxy, c[6].xyxy;\n"
- "TEX R0, R0.zwzw, texture[0], 2D;\n"
- "MUL R2.xyz, R0, c[4].y;\n"
- "ADD R1.x, -R1, c[7];\n"
- "MUL R1, fragment.color.primary, R1.x;\n"
- "MUL R3.xyz, R1.w, R2;\n"
- "MUL R2.xyz, R1, c[4].x;\n"
- "MUL R0.xyz, R0, c[5].z;\n"
- "MAD R2.xyz, R0.w, R2, R3;\n"
- "ADD R2.w, -R0, c[7].x;\n"
- "MUL R1.xyz, R1, c[5].y;\n"
- "MAD R1.xyz, R2.w, R1, R2;\n"
- "ADD R2.x, -R1.w, c[7];\n"
- "MAD result.color.xyz, R2.x, R0, R1;\n"
- "MUL R0.x, R1.w, R0.w;\n"
- "MUL R0.z, R0.w, R2.x;\n"
- "MUL R0.y, R1.w, R2.w;\n"
- "DP3 result.color.w, R0, c[5];\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_MULTIPLY_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R1.x, R0, texture[1], 2D;\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "TEX R0, R0.zwzw, texture[0], 2D;\n"
- "ADD R1.x, -R1, c[5];\n"
- "MUL R1, fragment.color.primary, R1.x;\n"
- "ADD R2.x, -R0.w, c[5];\n"
- "MUL R2.xyz, R1, R2.x;\n"
- "MAD R1.xyz, R1, R0, R2;\n"
- "ADD R2.x, R1.w, R0.w;\n"
- "ADD R2.y, -R1.w, c[5].x;\n"
- "MAD result.color.xyz, R0, R2.y, R1;\n"
- "MAD result.color.w, -R1, R0, R2.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_SCREEN_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0.x, R0, texture[1], 2D;\n"
- "ADD R1.x, -R0, c[5];\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "TEX R0, R0.zwzw, texture[0], 2D;\n"
- "MUL R1, fragment.color.primary, R1.x;\n"
- "ADD R2, R1, R0;\n"
- "MAD result.color, -R1, R0, R2;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_OVERLAY_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 1, 2 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0.x, R0, texture[1], 2D;\n"
- "ADD R0.x, -R0, c[5];\n"
- "MUL R1, fragment.color.primary, R0.x;\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "TEX R0, R0.zwzw, texture[0], 2D;\n"
- "ADD R3.xyz, R1.w, -R1;\n"
- "ADD R2.xyz, R0.w, -R0;\n"
- "MUL R2.xyz, R2, R3;\n"
- "ADD R2.w, -R0, c[5].x;\n"
- "MUL R2.xyz, R2, c[5].y;\n"
- "MAD R2.xyz, R1.w, R0.w, -R2;\n"
- "MAD R2.xyz, R1, R2.w, R2;\n"
- "MUL R3.xyz, R1, R2.w;\n"
- "MUL R1.xyz, R1, R0;\n"
- "ADD R2.w, -R1, c[5].x;\n"
- "MAD R1.xyz, R1, c[5].y, R3;\n"
- "MAD R1.xyz, R0, R2.w, R1;\n"
- "MAD R2.xyz, R0, R2.w, R2;\n"
- "MUL R0.xyz, R0, c[5].y;\n"
- "ADD R2.w, R1, R0;\n"
- "ADD R2.xyz, R2, -R1;\n"
- "SGE R0.xyz, R0, R0.w;\n"
- "MAD result.color.xyz, R0, R2, R1;\n"
- "MAD result.color.w, -R1, R0, R2;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_DARKEN_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0.x, R0, texture[1], 2D;\n"
- "ADD R1.x, -R0, c[5];\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "TEX R0, R0.zwzw, texture[0], 2D;\n"
- "MUL R1, fragment.color.primary, R1.x;\n"
- "MUL R2.xyz, R1, R0.w;\n"
- "MUL R3.xyz, R1.w, R0;\n"
- "MIN R2.xyz, R2, R3;\n"
- "ADD R2.w, -R0, c[5].x;\n"
- "MAD R1.xyz, R1, R2.w, R2;\n"
- "ADD R2.x, R1.w, R0.w;\n"
- "ADD R2.y, -R1.w, c[5].x;\n"
- "MAD result.color.xyz, R0, R2.y, R1;\n"
- "MAD result.color.w, -R1, R0, R2.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_LIGHTEN_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0.x, R0, texture[1], 2D;\n"
- "ADD R1.x, -R0, c[5];\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "TEX R0, R0.zwzw, texture[0], 2D;\n"
- "MUL R1, fragment.color.primary, R1.x;\n"
- "MUL R2.xyz, R1, R0.w;\n"
- "MUL R3.xyz, R1.w, R0;\n"
- "MAX R2.xyz, R2, R3;\n"
- "ADD R2.w, -R0, c[5].x;\n"
- "MAD R1.xyz, R1, R2.w, R2;\n"
- "ADD R2.x, R1.w, R0.w;\n"
- "ADD R2.y, -R1.w, c[5].x;\n"
- "MAD result.color.xyz, R0, R2.y, R1;\n"
- "MAD result.color.w, -R1, R0, R2.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_COLORDODGE_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 1, 1e-006 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0.x, R0, texture[1], 2D;\n"
- "ADD R0.x, -R0, c[5];\n"
- "MUL R1, fragment.color.primary, R0.x;\n"
- "MAX R0.x, R1.w, c[5].y;\n"
- "RCP R0.x, R0.x;\n"
- "MAD R3.xyz, -R1, R0.x, c[5].x;\n"
- "MAX R3.xyz, R3, c[5].y;\n"
- "MUL R0.xy, fragment.position, c[4];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "ADD R2.x, -R1.w, c[5];\n"
- "MUL R2.xyz, R0, R2.x;\n"
- "ADD R2.w, -R0, c[5].x;\n"
- "MAD R2.xyz, R1, R2.w, R2;\n"
- "MUL R0.xyz, R1.w, R0;\n"
- "RCP R3.x, R3.x;\n"
- "RCP R3.y, R3.y;\n"
- "RCP R3.z, R3.z;\n"
- "MAD R3.xyz, R0, R3, R2;\n"
- "MAD R0.xyz, R1, R0.w, R0;\n"
- "MAD R2.xyz, R1.w, R0.w, R2;\n"
- "MUL R2.w, R1, R0;\n"
- "ADD R1.x, R1.w, R0.w;\n"
- "ADD R2.xyz, R2, -R3;\n"
- "SGE R0.xyz, R0, R2.w;\n"
- "MAD result.color.xyz, R0, R2, R3;\n"
- "MAD result.color.w, -R1, R0, R1.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_COLORBURN_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 1, 9.9999997e-006 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "TEMP R5;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0.x, R0, texture[1], 2D;\n"
- "ADD R1.x, -R0, c[5];\n"
- "MUL R1, fragment.color.primary, R1.x;\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "TEX R0, R0.zwzw, texture[0], 2D;\n"
- "MUL R2.xyz, R1.w, R0;\n"
- "MAD R3.xyz, R1, R0.w, R2;\n"
- "ADD R2.w, -R0, c[5].x;\n"
- "MAD R2.xyz, -R1.w, R0.w, R3;\n"
- "MUL R4.xyz, R1.w, R2;\n"
- "MAX R2.xyz, R1, c[5].y;\n"
- "MUL R5.xyz, R1, R2.w;\n"
- "ADD R3.w, -R1, c[5].x;\n"
- "RCP R2.x, R2.x;\n"
- "RCP R2.y, R2.y;\n"
- "RCP R2.z, R2.z;\n"
- "MAD R2.xyz, R4, R2, R5;\n"
- "MUL R4.xyz, R0, R3.w;\n"
- "MAD R0.xyz, R0, R3.w, R2;\n"
- "MAD R1.xyz, R1, R2.w, R4;\n"
- "MUL R2.x, R1.w, R0.w;\n"
- "ADD R2.w, R1, R0;\n"
- "ADD R0.xyz, R0, -R1;\n"
- "SGE R2.xyz, R3, R2.x;\n"
- "MAD result.color.xyz, R2, R0, R1;\n"
- "MAD result.color.w, -R1, R0, R2;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_HARDLIGHT_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 1, 2 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0.x, R0, texture[1], 2D;\n"
- "ADD R0.x, -R0, c[5];\n"
- "MUL R1, fragment.color.primary, R0.x;\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "TEX R0, R0.zwzw, texture[0], 2D;\n"
- "ADD R2.w, -R0, c[5].x;\n"
- "ADD R3.xyz, R1.w, -R1;\n"
- "ADD R2.xyz, R0.w, -R0;\n"
- "MUL R2.xyz, R2, R3;\n"
- "MUL R2.xyz, R2, c[5].y;\n"
- "MAD R2.xyz, R1.w, R0.w, -R2;\n"
- "MAD R2.xyz, R1, R2.w, R2;\n"
- "MUL R4.xyz, R1, R2.w;\n"
- "MUL R3.xyz, R1, R0;\n"
- "MUL R1.xyz, R1, c[5].y;\n"
- "ADD R2.w, -R1, c[5].x;\n"
- "MAD R3.xyz, R3, c[5].y, R4;\n"
- "MAD R3.xyz, R0, R2.w, R3;\n"
- "MAD R0.xyz, R0, R2.w, R2;\n"
- "ADD R2.x, R1.w, R0.w;\n"
- "ADD R0.xyz, R0, -R3;\n"
- "SGE R1.xyz, R1, R1.w;\n"
- "MAD result.color.xyz, R1, R0, R3;\n"
- "MAD result.color.w, -R1, R0, R2.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_SOFTLIGHT_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[7] = { program.local[0..4],\n"
- " { 1, 2, 9.9999997e-006, 4 },\n"
- " { 16, 12, 3 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "TEMP R5;\n"
- "TEMP R6;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R1.xyz, R0, c[3];\n"
- "RCP R1.z, R1.z;\n"
- "MUL R1.xy, R1, R1.z;\n"
- "MUL R1.xy, R1, c[0];\n"
- "TEX R1.x, R1, texture[1], 2D;\n"
- "MUL R0.xy, fragment.position, c[4];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "MAX R1.z, R0.w, c[5];\n"
- "RCP R1.z, R1.z;\n"
- "MUL R3.xyz, R0, R1.z;\n"
- "MAD R2.xyz, R3, c[6].x, -c[6].y;\n"
- "ADD R1.x, -R1, c[5];\n"
- "MUL R1, fragment.color.primary, R1.x;\n"
- "MAD R4.xyz, R3, R2, c[6].z;\n"
- "MAD R2.xyz, R1, c[5].y, -R1.w;\n"
- "MUL R5.xyz, R0.w, R2;\n"
- "MUL R6.xyz, R5, R4;\n"
- "RSQ R2.w, R3.x;\n"
- "RCP R4.x, R2.w;\n"
- "RSQ R2.w, R3.y;\n"
- "RSQ R3.w, R3.z;\n"
- "RCP R4.y, R2.w;\n"
- "RCP R4.z, R3.w;\n"
- "ADD R4.xyz, -R3, R4;\n"
- "MUL R6.xyz, R3, R6;\n"
- "MUL R4.xyz, R5, R4;\n"
- "ADD R3.xyz, -R3, c[5].x;\n"
- "MAD R2.xyz, R2, R3, R1.w;\n"
- "MUL R3.xyz, R1, c[5].y;\n"
- "MAD R5.xyz, R1.w, R0, R6;\n"
- "MAD R4.xyz, R1.w, R0, R4;\n"
- "ADD R6.xyz, R4, -R5;\n"
- "MUL R4.xyz, R0, c[5].w;\n"
- "SGE R4.xyz, R4, R0.w;\n"
- "MAD R4.xyz, R4, R6, R5;\n"
- "MAD R4.xyz, -R0, R2, R4;\n"
- "MUL R2.xyz, R0, R2;\n"
- "SGE R3.xyz, R3, R1.w;\n"
- "MAD R2.xyz, R3, R4, R2;\n"
- "ADD R2.w, -R0, c[5].x;\n"
- "MAD R2.xyz, R1, R2.w, R2;\n"
- "ADD R1.x, R1.w, R0.w;\n"
- "ADD R1.y, -R1.w, c[5].x;\n"
- "MAD result.color.xyz, R0, R1.y, R2;\n"
- "MAD result.color.w, -R1, R0, R1.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_DIFFERENCE_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 1, 2 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0.x, R0, texture[1], 2D;\n"
- "ADD R1.x, -R0, c[5];\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "TEX R0, R0.zwzw, texture[0], 2D;\n"
- "MUL R1, fragment.color.primary, R1.x;\n"
- "MUL R3.xyz, R1.w, R0;\n"
- "MUL R2.xyz, R1, R0.w;\n"
- "ADD R0.xyz, R1, R0;\n"
- "MIN R2.xyz, R2, R3;\n"
- "ADD R1.x, R1.w, R0.w;\n"
- "MAD result.color.xyz, -R2, c[5].y, R0;\n"
- "MAD result.color.w, -R1, R0, R1.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_EXCLUSION_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 1, 2 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0.x, R0, texture[1], 2D;\n"
- "ADD R1.x, -R0, c[5];\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "TEX R0, R0.zwzw, texture[0], 2D;\n"
- "MUL R1, fragment.color.primary, R1.x;\n"
- "MUL R2.xyz, R1.w, R0;\n"
- "MAD R3.xyz, R1, R0.w, R2;\n"
- "MUL R2.xyz, R1, R0;\n"
- "MAD R2.xyz, -R2, c[5].y, R3;\n"
- "ADD R2.w, -R0, c[5].x;\n"
- "MAD R1.xyz, R1, R2.w, R2;\n"
- "ADD R2.x, R1.w, R0.w;\n"
- "ADD R2.y, -R1.w, c[5].x;\n"
- "MAD result.color.xyz, R0, R2.y, R1;\n"
- "MAD result.color.w, -R1, R0, R2.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODE_BLEND_MODE_MASK =
- "!!ARBfp1.0\n"
- "PARAM c[8] = { program.local[0..6],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.z;\n"
- "MUL R0.zw, R0, c[0].xyxy;\n"
- "TEX R1.x, R0.zwzw, texture[1], 2D;\n"
- "ADD R0.xy, fragment.position, c[5];\n"
- "MUL R0.xy, R0, c[4];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "DP4 R1.y, R0, c[6];\n"
- "ADD R1.x, -R1, c[7];\n"
- "MUL R0, fragment.color.primary, R1.x;\n"
- "MUL result.color, R0, R1.y;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODE_BLEND_MODE_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[5] = { program.local[0..3],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0.x, R0, texture[0], 2D;\n"
- "ADD R0.x, -R0, c[4];\n"
- "MUL result.color, fragment.color.primary, R0.x;\n"
- "END\n"
- ;
-
-static const char *mask_fragment_program_sources[num_fragment_masks] = {
- FragmentProgram_FRAGMENT_PROGRAM_MASK_TRAPEZOID_AA,
- FragmentProgram_FRAGMENT_PROGRAM_MASK_ELLIPSE_AA,
-};
-
-static const char *painter_fragment_program_sources[num_fragment_brushes][num_fragment_composition_modes] = {
- {
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_SIMPLE_PORTER_DUFF,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_MULTIPLY,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_SCREEN,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_OVERLAY,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_DARKEN,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_LIGHTEN,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_COLORDODGE,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_COLORBURN,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_HARDLIGHT,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_SOFTLIGHT,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_DIFFERENCE,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_EXCLUSION,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_SIMPLE_PORTER_DUFF_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_MULTIPLY_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_SCREEN_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_OVERLAY_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_DARKEN_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_LIGHTEN_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_COLORDODGE_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_COLORBURN_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_HARDLIGHT_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_SOFTLIGHT_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_DIFFERENCE_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_EXCLUSION_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODE_BLEND_MODE_MASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODE_BLEND_MODE_NOMASK,
- },
- {
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_SIMPLE_PORTER_DUFF,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_MULTIPLY,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_SCREEN,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_OVERLAY,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_DARKEN,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_LIGHTEN,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_COLORDODGE,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_COLORBURN,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_HARDLIGHT,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_SOFTLIGHT,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_DIFFERENCE,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_EXCLUSION,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_SIMPLE_PORTER_DUFF_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_MULTIPLY_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_SCREEN_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_OVERLAY_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_DARKEN_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_LIGHTEN_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_COLORDODGE_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_COLORBURN_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_HARDLIGHT_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_SOFTLIGHT_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_DIFFERENCE_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_EXCLUSION_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODE_BLEND_MODE_MASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODE_BLEND_MODE_NOMASK,
- },
- {
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_SIMPLE_PORTER_DUFF,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_MULTIPLY,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_SCREEN,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_OVERLAY,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_DARKEN,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_LIGHTEN,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_COLORDODGE,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_COLORBURN,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_HARDLIGHT,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_SOFTLIGHT,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_DIFFERENCE,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_EXCLUSION,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_SIMPLE_PORTER_DUFF_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_MULTIPLY_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_SCREEN_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_OVERLAY_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_DARKEN_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_LIGHTEN_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_COLORDODGE_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_COLORBURN_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_HARDLIGHT_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_SOFTLIGHT_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_DIFFERENCE_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_EXCLUSION_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODE_BLEND_MODE_MASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODE_BLEND_MODE_NOMASK,
- },
- {
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_SIMPLE_PORTER_DUFF,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_MULTIPLY,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_SCREEN,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_OVERLAY,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_DARKEN,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_LIGHTEN,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_COLORDODGE,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_COLORBURN,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_HARDLIGHT,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_SOFTLIGHT,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_DIFFERENCE,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_EXCLUSION,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_SIMPLE_PORTER_DUFF_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_MULTIPLY_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_SCREEN_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_OVERLAY_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_DARKEN_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_LIGHTEN_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_COLORDODGE_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_COLORBURN_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_HARDLIGHT_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_SOFTLIGHT_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_DIFFERENCE_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_EXCLUSION_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODE_BLEND_MODE_MASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODE_BLEND_MODE_NOMASK,
- },
- {
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_SIMPLE_PORTER_DUFF,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_MULTIPLY,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_SCREEN,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_OVERLAY,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_DARKEN,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_LIGHTEN,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_COLORDODGE,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_COLORBURN,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_HARDLIGHT,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_SOFTLIGHT,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_DIFFERENCE,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_EXCLUSION,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_SIMPLE_PORTER_DUFF_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_MULTIPLY_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_SCREEN_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_OVERLAY_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_DARKEN_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_LIGHTEN_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_COLORDODGE_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_COLORBURN_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_HARDLIGHT_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_SOFTLIGHT_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_DIFFERENCE_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_EXCLUSION_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODE_BLEND_MODE_MASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODE_BLEND_MODE_NOMASK,
- },
- {
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_SIMPLE_PORTER_DUFF,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_MULTIPLY,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_SCREEN,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_OVERLAY,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_DARKEN,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_LIGHTEN,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_COLORDODGE,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_COLORBURN,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_HARDLIGHT,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_SOFTLIGHT,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_DIFFERENCE,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_EXCLUSION,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_SIMPLE_PORTER_DUFF_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_MULTIPLY_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_SCREEN_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_OVERLAY_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_DARKEN_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_LIGHTEN_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_COLORDODGE_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_COLORBURN_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_HARDLIGHT_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_SOFTLIGHT_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_DIFFERENCE_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_EXCLUSION_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODE_BLEND_MODE_MASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODE_BLEND_MODE_NOMASK,
- },
-};
-
-static int painter_variable_locations[num_fragment_brushes][num_fragment_composition_modes][num_fragment_variables] = {
- {
- { -1, -1, -1, 2, -1, 0, 5, -1, 1, 3, 1, 0, -1, 4, -1, -1, -1, -1, -1, },
- { -1, -1, -1, 0, -1, -1, 3, -1, -1, 1, 1, 0, -1, 2, -1, -1, -1, -1, -1, },
- { -1, -1, -1, 0, -1, -1, 3, -1, -1, 1, 1, 0, -1, 2, -1, -1, -1, -1, -1, },
- { -1, -1, -1, 0, -1, -1, 3, -1, -1, 1, 1, 0, -1, 2, -1, -1, -1, -1, -1, },
- { -1, -1, -1, 0, -1, -1, 3, -1, -1, 1, 1, 0, -1, 2, -1, -1, -1, -1, -1, },
- { -1, -1, -1, 0, -1, -1, 3, -1, -1, 1, 1, 0, -1, 2, -1, -1, -1, -1, -1, },
- { -1, -1, -1, 0, -1, -1, 3, -1, -1, 1, 1, 0, -1, 2, -1, -1, -1, -1, -1, },
- { -1, -1, -1, 0, -1, -1, 3, -1, -1, 1, 1, 0, -1, 2, -1, -1, -1, -1, -1, },
- { -1, -1, -1, 0, -1, -1, 3, -1, -1, 1, 1, 0, -1, 2, -1, -1, -1, -1, -1, },
- { -1, -1, -1, 0, -1, -1, 3, -1, -1, 1, 1, 0, -1, 2, -1, -1, -1, -1, -1, },
- { -1, -1, -1, 0, -1, -1, 3, -1, -1, 1, 1, 0, -1, 2, -1, -1, -1, -1, -1, },
- { -1, -1, -1, 0, -1, -1, 3, -1, -1, 1, 1, 0, -1, 2, -1, -1, -1, -1, -1, },
- { -1, -1, -1, -1, -1, 0, -1, -1, 1, 2, -1, 0, -1, -1, -1, -1, -1, -1, -1, },
- { -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, -1, -1, -1, -1, -1, -1, },
- { -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, -1, -1, -1, -1, -1, -1, },
- { -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, -1, -1, -1, -1, -1, -1, },
- { -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, -1, -1, -1, -1, -1, -1, },
- { -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, -1, -1, -1, -1, -1, -1, },
- { -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, -1, -1, -1, -1, -1, -1, },
- { -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, -1, -1, -1, -1, -1, -1, },
- { -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, -1, -1, -1, -1, -1, -1, },
- { -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, -1, -1, -1, -1, -1, -1, },
- { -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, -1, -1, -1, -1, -1, -1, },
- { -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, -1, -1, -1, -1, -1, -1, },
- { -1, -1, -1, 0, -1, -1, 2, -1, -1, -1, 0, -1, -1, 1, -1, -1, -1, -1, -1, },
- { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
- },
- {
- { -1, -1, 3, 7, 4, 5, 10, -1, 6, 8, 1, 0, 2, 9, -1, 1, 0, 2, -1, },
- { -1, -1, 3, 5, 4, -1, 8, -1, -1, 6, 1, 0, 2, 7, -1, 1, 0, 2, -1, },
- { -1, -1, 3, 5, 4, -1, 8, -1, -1, 6, 1, 0, 2, 7, -1, 1, 0, 2, -1, },
- { -1, -1, 3, 5, 4, -1, 8, -1, -1, 6, 1, 0, 2, 7, -1, 1, 0, 2, -1, },
- { -1, -1, 3, 5, 4, -1, 8, -1, -1, 6, 1, 0, 2, 7, -1, 1, 0, 2, -1, },
- { -1, -1, 3, 5, 4, -1, 8, -1, -1, 6, 1, 0, 2, 7, -1, 1, 0, 2, -1, },
- { -1, -1, 3, 5, 4, -1, 8, -1, -1, 6, 1, 0, 2, 7, -1, 1, 0, 2, -1, },
- { -1, -1, 3, 5, 4, -1, 8, -1, -1, 6, 1, 0, 2, 7, -1, 1, 0, 2, -1, },
- { -1, -1, 3, 5, 4, -1, 8, -1, -1, 6, 1, 0, 2, 7, -1, 1, 0, 2, -1, },
- { -1, -1, 3, 5, 4, -1, 8, -1, -1, 6, 1, 0, 2, 7, -1, 1, 0, 2, -1, },
- { -1, -1, 3, 5, 4, -1, 8, -1, -1, 6, 1, 0, 2, 7, -1, 1, 0, 2, -1, },
- { -1, -1, 3, 5, 4, -1, 8, -1, -1, 6, 1, 0, 2, 7, -1, 1, 0, 2, -1, },
- { -1, -1, 3, -1, 4, 5, -1, -1, 6, 7, -1, 0, 1, -1, -1, 1, 0, 2, -1, },
- { -1, -1, 3, -1, 4, -1, -1, -1, -1, 5, -1, 0, 1, -1, -1, 1, 0, 2, -1, },
- { -1, -1, 3, -1, 4, -1, -1, -1, -1, 5, -1, 0, 1, -1, -1, 1, 0, 2, -1, },
- { -1, -1, 3, -1, 4, -1, -1, -1, -1, 5, -1, 0, 1, -1, -1, 1, 0, 2, -1, },
- { -1, -1, 3, -1, 4, -1, -1, -1, -1, 5, -1, 0, 1, -1, -1, 1, 0, 2, -1, },
- { -1, -1, 3, -1, 4, -1, -1, -1, -1, 5, -1, 0, 1, -1, -1, 1, 0, 2, -1, },
- { -1, -1, 3, -1, 4, -1, -1, -1, -1, 5, -1, 0, 1, -1, -1, 1, 0, 2, -1, },
- { -1, -1, 3, -1, 4, -1, -1, -1, -1, 5, -1, 0, 1, -1, -1, 1, 0, 2, -1, },
- { -1, -1, 3, -1, 4, -1, -1, -1, -1, 5, -1, 0, 1, -1, -1, 1, 0, 2, -1, },
- { -1, -1, 3, -1, 4, -1, -1, -1, -1, 5, -1, 0, 1, -1, -1, 1, 0, 2, -1, },
- { -1, -1, 3, -1, 4, -1, -1, -1, -1, 5, -1, 0, 1, -1, -1, 1, 0, 2, -1, },
- { -1, -1, 3, -1, 4, -1, -1, -1, -1, 5, -1, 0, 1, -1, -1, 1, 0, 2, -1, },
- { -1, -1, 3, 5, 4, -1, 7, -1, -1, -1, 0, -1, 1, 6, -1, 1, 0, 2, -1, },
- { -1, -1, 3, -1, 4, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, 1, 0, 2, -1, },
- },
- {
- { -1, -1, 2, 6, 3, 4, 9, -1, 5, 7, 1, 0, 2, 8, -1, -1, -1, 1, 0, },
- { -1, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, 2, 6, -1, -1, -1, 1, 0, },
- { -1, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, 2, 6, -1, -1, -1, 1, 0, },
- { -1, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, 2, 6, -1, -1, -1, 1, 0, },
- { -1, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, 2, 6, -1, -1, -1, 1, 0, },
- { -1, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, 2, 6, -1, -1, -1, 1, 0, },
- { -1, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, 2, 6, -1, -1, -1, 1, 0, },
- { -1, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, 2, 6, -1, -1, -1, 1, 0, },
- { -1, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, 2, 6, -1, -1, -1, 1, 0, },
- { -1, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, 2, 6, -1, -1, -1, 1, 0, },
- { -1, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, 2, 6, -1, -1, -1, 1, 0, },
- { -1, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, 2, 6, -1, -1, -1, 1, 0, },
- { -1, -1, 2, -1, 3, 4, -1, -1, 5, 6, -1, 0, 1, -1, -1, -1, -1, 1, 0, },
- { -1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, 1, -1, -1, -1, -1, 1, 0, },
- { -1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, 1, -1, -1, -1, -1, 1, 0, },
- { -1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, 1, -1, -1, -1, -1, 1, 0, },
- { -1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, 1, -1, -1, -1, -1, 1, 0, },
- { -1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, 1, -1, -1, -1, -1, 1, 0, },
- { -1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, 1, -1, -1, -1, -1, 1, 0, },
- { -1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, 1, -1, -1, -1, -1, 1, 0, },
- { -1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, 1, -1, -1, -1, -1, 1, 0, },
- { -1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, 1, -1, -1, -1, -1, 1, 0, },
- { -1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, 1, -1, -1, -1, -1, 1, 0, },
- { -1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, 1, -1, -1, -1, -1, 1, 0, },
- { -1, -1, 2, 4, 3, -1, 6, -1, -1, -1, 0, -1, 1, 5, -1, -1, -1, 1, 0, },
- { -1, -1, 2, -1, 3, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, 1, 0, },
- },
- {
- { -1, 0, 2, 6, 3, 4, 9, -1, 5, 7, 1, 0, 2, 8, -1, -1, -1, 1, -1, },
- { -1, 0, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, 2, 6, -1, -1, -1, 1, -1, },
- { -1, 0, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, 2, 6, -1, -1, -1, 1, -1, },
- { -1, 0, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, 2, 6, -1, -1, -1, 1, -1, },
- { -1, 0, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, 2, 6, -1, -1, -1, 1, -1, },
- { -1, 0, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, 2, 6, -1, -1, -1, 1, -1, },
- { -1, 0, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, 2, 6, -1, -1, -1, 1, -1, },
- { -1, 0, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, 2, 6, -1, -1, -1, 1, -1, },
- { -1, 0, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, 2, 6, -1, -1, -1, 1, -1, },
- { -1, 0, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, 2, 6, -1, -1, -1, 1, -1, },
- { -1, 0, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, 2, 6, -1, -1, -1, 1, -1, },
- { -1, 0, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, 2, 6, -1, -1, -1, 1, -1, },
- { -1, 0, 2, -1, 3, 4, -1, -1, 5, 6, -1, 0, 1, -1, -1, -1, -1, 1, -1, },
- { -1, 0, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, 1, -1, -1, -1, -1, 1, -1, },
- { -1, 0, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, 1, -1, -1, -1, -1, 1, -1, },
- { -1, 0, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, 1, -1, -1, -1, -1, 1, -1, },
- { -1, 0, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, 1, -1, -1, -1, -1, 1, -1, },
- { -1, 0, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, 1, -1, -1, -1, -1, 1, -1, },
- { -1, 0, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, 1, -1, -1, -1, -1, 1, -1, },
- { -1, 0, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, 1, -1, -1, -1, -1, 1, -1, },
- { -1, 0, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, 1, -1, -1, -1, -1, 1, -1, },
- { -1, 0, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, 1, -1, -1, -1, -1, 1, -1, },
- { -1, 0, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, 1, -1, -1, -1, -1, 1, -1, },
- { -1, 0, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, 1, -1, -1, -1, -1, 1, -1, },
- { -1, 0, 2, 4, 3, -1, 6, -1, -1, -1, 0, -1, 1, 5, -1, -1, -1, 1, -1, },
- { -1, 0, 2, -1, 3, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, 1, -1, },
- },
- {
- { 2, -1, 2, 6, 3, 4, 9, -1, 5, 7, 1, 0, -1, 8, 0, -1, -1, 1, -1, },
- { 2, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, -1, 6, 0, -1, -1, 1, -1, },
- { 2, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, -1, 6, 0, -1, -1, 1, -1, },
- { 2, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, -1, 6, 0, -1, -1, 1, -1, },
- { 2, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, -1, 6, 0, -1, -1, 1, -1, },
- { 2, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, -1, 6, 0, -1, -1, 1, -1, },
- { 2, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, -1, 6, 0, -1, -1, 1, -1, },
- { 2, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, -1, 6, 0, -1, -1, 1, -1, },
- { 2, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, -1, 6, 0, -1, -1, 1, -1, },
- { 2, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, -1, 6, 0, -1, -1, 1, -1, },
- { 2, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, -1, 6, 0, -1, -1, 1, -1, },
- { 2, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, -1, 6, 0, -1, -1, 1, -1, },
- { 1, -1, 2, -1, 3, 4, -1, -1, 5, 6, -1, 0, -1, -1, 0, -1, -1, 1, -1, },
- { 1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, -1, -1, 0, -1, -1, 1, -1, },
- { 1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, -1, -1, 0, -1, -1, 1, -1, },
- { 1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, -1, -1, 0, -1, -1, 1, -1, },
- { 1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, -1, -1, 0, -1, -1, 1, -1, },
- { 1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, -1, -1, 0, -1, -1, 1, -1, },
- { 1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, -1, -1, 0, -1, -1, 1, -1, },
- { 1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, -1, -1, 0, -1, -1, 1, -1, },
- { 1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, -1, -1, 0, -1, -1, 1, -1, },
- { 1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, -1, -1, 0, -1, -1, 1, -1, },
- { 1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, -1, -1, 0, -1, -1, 1, -1, },
- { 1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, -1, -1, 0, -1, -1, 1, -1, },
- { 1, -1, 2, 4, 3, -1, 6, -1, -1, -1, 0, -1, -1, 5, 0, -1, -1, 1, -1, },
- { 0, -1, 2, -1, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, 1, -1, },
- },
- {
- { 2, -1, 2, 6, 3, 4, 9, -1, 5, 7, 1, 0, -1, 8, 0, -1, -1, 1, -1, },
- { 2, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, -1, 6, 0, -1, -1, 1, -1, },
- { 2, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, -1, 6, 0, -1, -1, 1, -1, },
- { 2, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, -1, 6, 0, -1, -1, 1, -1, },
- { 2, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, -1, 6, 0, -1, -1, 1, -1, },
- { 2, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, -1, 6, 0, -1, -1, 1, -1, },
- { 2, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, -1, 6, 0, -1, -1, 1, -1, },
- { 2, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, -1, 6, 0, -1, -1, 1, -1, },
- { 2, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, -1, 6, 0, -1, -1, 1, -1, },
- { 2, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, -1, 6, 0, -1, -1, 1, -1, },
- { 2, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, -1, 6, 0, -1, -1, 1, -1, },
- { 2, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, -1, 6, 0, -1, -1, 1, -1, },
- { 1, -1, 2, -1, 3, 4, -1, -1, 5, 6, -1, 0, -1, -1, 0, -1, -1, 1, -1, },
- { 1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, -1, -1, 0, -1, -1, 1, -1, },
- { 1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, -1, -1, 0, -1, -1, 1, -1, },
- { 1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, -1, -1, 0, -1, -1, 1, -1, },
- { 1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, -1, -1, 0, -1, -1, 1, -1, },
- { 1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, -1, -1, 0, -1, -1, 1, -1, },
- { 1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, -1, -1, 0, -1, -1, 1, -1, },
- { 1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, -1, -1, 0, -1, -1, 1, -1, },
- { 1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, -1, -1, 0, -1, -1, 1, -1, },
- { 1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, -1, -1, 0, -1, -1, 1, -1, },
- { 1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, -1, -1, 0, -1, -1, 1, -1, },
- { 1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, -1, -1, 0, -1, -1, 1, -1, },
- { 1, -1, 2, 4, 3, -1, 6, -1, -1, -1, 0, -1, -1, 5, 0, -1, -1, 1, -1, },
- { 0, -1, 2, -1, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, 1, -1, },
- },
-};
-
-static int mask_variable_locations[num_fragment_masks][num_fragment_variables] = {
- { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
- { -1, -1, 1, -1, 2, -1, -1, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, },
-};
-
-#endif
diff --git a/src/opengl/util/generator.cpp b/src/opengl/util/generator.cpp
deleted file mode 100644
index 3d12446842..0000000000
--- a/src/opengl/util/generator.cpp
+++ /dev/null
@@ -1,500 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QFile>
-#include <QList>
-#include <QMap>
-#include <QPair>
-#include <QSet>
-#include <QString>
-#include <QTextStream>
-
-#include <QtDebug>
-#include <cstdlib>
-
-QT_BEGIN_NAMESPACE
-
-QT_USE_NAMESPACE
-
-#define TAB " "
-
-typedef QPair<QString, QString> QStringPair;
-
-QString readSourceFile(const QString &sourceFile, bool fragmentProgram = false)
-{
- QFile file(sourceFile);
-
- if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
- qDebug() << "Missing source file" << sourceFile;
- exit(0);
- }
-
- QString source;
-
- QTextStream in(&file);
- while (!in.atEnd()) {
- QString line = in.readLine();
-
- if (fragmentProgram && line[0] == '#' && !line.startsWith("#var"))
- continue;
-
- if (fragmentProgram)
- source.append(" \"");
-
- source.append(line);
-
- if (fragmentProgram)
- source.append("\\n\"");
-
- source.append('\n');
- }
-
- if (fragmentProgram)
- source.append(" ;\n");
-
- return source;
-}
-
-QList<QStringPair> readConf(const QString &confFile)
-{
- QFile file(confFile);
-
- if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
- qDebug() << "Missing file" << confFile;
- exit(0);
- }
-
- QList<QStringPair> result;
-
- QTextStream in(&file);
- while (!in.atEnd()) {
- QString line = in.readLine();
-
- if (line.startsWith('#'))
- continue;
-
- QTextStream lineStream(&line);
-
- QString enumerator;
- QString sourceFile;
-
- lineStream >> enumerator;
-
- if (lineStream.atEnd()) {
- qDebug() << "Error in file" << confFile << '(' << enumerator << ')';
- exit(0);
- }
-
- lineStream >> sourceFile;
-
- result << QStringPair(enumerator, readSourceFile(sourceFile));
- }
-
- return result;
-}
-
-QString compileSource(const QString &source)
-{
- {
- QFile tempSourceFile("__tmp__.glsl");
- if (!tempSourceFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
- qDebug() << "Failed opening __tmp__.glsl";
- exit(0);
- }
-
- QTextStream out(&tempSourceFile);
- out << source;
- }
-
- if (std::system("cgc -quiet -oglsl -profile arbfp1 __tmp__.glsl >__tmp__.frag") == -1) {
- qDebug() << "Failed running cgc";
- exit(0);
- }
-
- return readSourceFile("__tmp__.frag", true);
-}
-
-QString getWord(QString line, int word)
-{
- QTextStream in(&line);
-
- QString result;
-
- for (int i = 0; i < word; ++i)
- in >> result;
-
- return result;
-}
-
-static int toInt(const QByteArray &str)
-{
- int value = 0;
-
- for (int i = 0; i < str.size(); ++i) {
- if (str[i] < '0' || str[i] > '9')
- break;
-
- value *= 10;
- value += (str[i] - '0');
- }
-
- return value;
-}
-QList<int> getLocations(const QSet<QString> &variables, QString source)
-{
- QTextStream in(&source);
-
- QMap<QString, int> locations;
-
- foreach (QString variable, variables)
- locations[variable] = -1;
-
- while (!in.atEnd()) {
- QString line = in.readLine().trimmed();
-
- line = line.right(line.size() - 1);
-
- if (line.startsWith("#var")) {
- QByteArray temp;
- QByteArray name;
-
- QTextStream lineStream(&line);
-
- lineStream >> temp >> temp >> name;
-
- int location = -1;
-
- while (!lineStream.atEnd()) {
- lineStream >> temp;
-
- if (temp.startsWith("c[")) {
- location = toInt(temp.right(temp.size() - 2));
- break;
- }
-
- if (temp == "texunit") {
- lineStream >> temp;
- location = toInt(temp);
- break;
- }
- }
-
- locations[name] = location;
- }
- }
-
- QList<int> result;
-
- foreach (QString variable, variables)
- result << locations[variable];
-
- return result;
-}
-
-// remove #var statements
-QString trimmed(QString source)
-{
- QTextStream in(&source);
-
- QString result;
-
- while (!in.atEnd()) {
- QString line = in.readLine();
- if (!line.trimmed().startsWith("\"#"))
- result += line + '\n';
- }
-
- return result;
-}
-
-void writeVariablesEnum(QTextStream &out, const char *name, const QSet<QString> &s)
-{
- out << "enum " << name << " {";
- QSet<QString>::const_iterator it = s.begin();
- if (it != s.end()) {
- out << "\n" TAB "VAR_" << it->toUpper();
- for (++it; it != s.end(); ++it)
- out << ",\n" TAB "VAR_" << it->toUpper();
- }
- out << "\n};\n\n";
-}
-
-void writeTypesEnum(QTextStream &out, const char *name, const QList<QStringPair> &s)
-{
- out << "enum " << name << " {";
- QList<QStringPair>::const_iterator it = s.begin();
- if (it != s.end()) {
- out << "\n" TAB << it->first;
- for (++it; it != s.end(); ++it)
- out << ",\n" TAB << it->first;
- }
- out << "\n};\n\n";
-}
-
-void writeIncludeFile(const QSet<QString> &variables,
- const QList<QStringPair> &brushes,
- const QList<QStringPair> &compositionModes,
- const QList<QStringPair> &masks,
- const QMap<QString, QMap<QString, QString> > &compiled)
-{
- QFile includeFile("fragmentprograms_p.h");
- if (!includeFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
- qDebug() << "Failed opening fragmentprograms_p.h";
- exit(0);
- }
-
- QTextStream out(&includeFile);
-
- QLatin1String tab(TAB);
-
- out << "/****************************************************************************\n"
- "**\n"
- "** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).\n"
- "** All rights reserved.\n"
- "** Contact: Nokia Corporation (qt-info@nokia.com)\n"
- "**\n"
- "** This file is part of the QtOpenGL module of the Qt Toolkit.\n"
- "**\n"
- "** $QT_BEGIN_LICENSE:LGPL$\n"
- "** GNU Lesser General Public License Usage\n"
- "** This file may be used under the terms of the GNU Lesser General Public\n"
- "** License version 2.1 as published by the Free Software Foundation and\n"
- "** appearing in the file LICENSE.LGPL included in the packaging of this\n"
- "** file. Please review the following information to ensure the GNU Lesser\n"
- "** General Public License version 2.1 requirements will be met:\n"
- "** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.\n"
- "**\n"
- "** In addition, as a special exception, Nokia gives you certain additional\n"
- "** rights. These rights are described in the Nokia Qt LGPL Exception\n"
- "** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.\n"
- "**\n"
- "** GNU General Public License Usage\n"
- "** Alternatively, this file may be used under the terms of the GNU General\n"
- "** Public License version 3.0 as published by the Free Software Foundation\n"
- "** and appearing in the file LICENSE.GPL included in the packaging of this\n"
- "** file. Please review the following information to ensure the GNU General\n"
- "** Public License version 3.0 requirements will be met:\n"
- "** http://www.gnu.org/copyleft/gpl.html.\n"
- "**\n"
- "** Other Usage\n"
- "** Alternatively, this file may be used in accordance with the terms and\n"
- "** conditions contained in a signed written agreement between you and Nokia.\n"
- "**\n"
- "**\n"
- "**\n"
- "**\n"
- "**\n"
- "** $QT_END_LICENSE$\n"
- "**\n"
- "****************************************************************************/\n"
- "\n"
- "#ifndef FRAGMENTPROGRAMS_P_H\n"
- "#define FRAGMENTPROGRAMS_P_H\n"
- "\n"
- "//\n"
- "// W A R N I N G\n"
- "// -------------\n"
- "//\n"
- "// This file is not part of the Qt API. It exists purely as an\n"
- "// implementation detail. This header file may change from version to\n"
- "// version without notice, or even be removed.\n"
- "//\n"
- "// We mean it.\n"
- "//\n"
- "\n";
-
- writeVariablesEnum(out, "FragmentVariable", variables);
- writeTypesEnum(out, "FragmentBrushType", brushes);
- writeTypesEnum(out, "FragmentCompositionModeType", compositionModes);
- writeTypesEnum(out, "FragmentMaskType", masks);
-
- out << "static const unsigned int num_fragment_variables = " << variables.size() << ";\n\n";
- out << "static const unsigned int num_fragment_brushes = " << brushes.size() << ";\n";
- out << "static const unsigned int num_fragment_composition_modes = " << compositionModes.size() << ";\n";
- out << "static const unsigned int num_fragment_masks = " << masks.size() << ";\n\n";
-
- foreach (QStringPair mask, masks) {
- const QString compiledSource = compiled[mask.first]["MASK__"];
-
- out << "static const char *FragmentProgram_" << mask.first << " =\n"
- << trimmed(compiledSource)
- << '\n';
- }
-
- foreach (QStringPair brush, brushes) {
- foreach (QStringPair mode, compositionModes) {
- const QString compiledSource = compiled[brush.first][mode.first];
-
- out << "static const char *FragmentProgram_" << brush.first << '_' << mode.first << " =\n"
- << trimmed(compiledSource)
- << '\n';
- }
- }
-
- out << "static const char *mask_fragment_program_sources[num_fragment_masks] = {\n";
- foreach (QStringPair mask, masks)
- out << tab << "FragmentProgram_" << mask.first << ",\n";
- out << "};\n\n";
-
- out << "static const char *painter_fragment_program_sources[num_fragment_brushes][num_fragment_composition_modes] = {\n";
- foreach (QStringPair brush, brushes) {
- out << tab << "{\n";
-
- foreach (QStringPair mode, compositionModes)
- out << tab << tab << "FragmentProgram_" << brush.first << '_' << mode.first << ",\n";
-
- out << tab << "},\n";
- }
- out << "};\n\n";
-
- out << "static int painter_variable_locations[num_fragment_brushes][num_fragment_composition_modes][num_fragment_variables] = {\n";
- foreach (QStringPair brush, brushes) {
- out << tab << "{\n";
-
- foreach (QStringPair mode, compositionModes) {
- out << tab << tab << "{ ";
-
- QList<int> locations = getLocations(variables, compiled[brush.first][mode.first]);
-
- foreach (int location, locations)
- out << location << ", ";
-
- out << "},\n";
- }
-
- out << tab << "},\n";
- }
- out << "};\n\n";
-
- out << "static int mask_variable_locations[num_fragment_masks][num_fragment_variables] = {\n";
- foreach (QStringPair mask, masks) {
- out << tab << "{ ";
-
- QList<int> locations = getLocations(variables, compiled[mask.first]["MASK__"]);
-
- foreach (int location, locations)
- out << location << ", ";
-
- out << "},\n";
- }
- out << "};\n\n";
- out << "#endif\n";
-}
-
-QList<QString> getVariables(QString program)
-{
- QList<QString> result;
-
- QTextStream in(&program);
- while (!in.atEnd()) {
- QString line = in.readLine();
-
- if (line.startsWith("uniform")) {
- QString word = getWord(line, 3);
- result << word.left(word.size() - 1);
- } else if (line.startsWith("#include")) {
- QString file = getWord(line, 2);
- result << getVariables(readSourceFile(file.mid(1, file.size() - 2)));
- }
- }
-
- return result;
-}
-
-int main()
-{
- QList<QStringPair> brushes = readConf(QLatin1String("brushes.conf"));
- QList<QStringPair> compositionModes = readConf(QLatin1String("composition_modes.conf"));
- QList<QStringPair> masks = readConf(QLatin1String("masks.conf"));
-
- QString painterSource = readSourceFile("painter.glsl");
- QString painterNoMaskSource = readSourceFile("painter_nomask.glsl");
- QString fastPainterSource = readSourceFile("fast_painter.glsl");
- QString brushPainterSource = readSourceFile("brush_painter.glsl");
-
- QSet<QString> variables;
-
- QList<QStringPair> programs[3] = { brushes, compositionModes, masks };
-
- for (int i = 0; i < 3; ++i)
- foreach (QStringPair value, programs[i])
- variables += QSet<QString>::fromList(getVariables(value.second));
-
- variables += QSet<QString>::fromList(getVariables(painterSource));
- variables += QSet<QString>::fromList(getVariables(fastPainterSource));
-
- QMap<QString, QMap<QString, QString> > compiled;
-
- foreach (QStringPair brush, brushes) {
- foreach (QStringPair mode, compositionModes) {
- QString combinedSource = brush.second + mode.second + painterSource;
- compiled[brush.first][mode.first] = compileSource(combinedSource);
-
- combinedSource = brush.second + mode.second + painterNoMaskSource;
- compiled[brush.first][mode.first + "_NOMASK"] = compileSource(combinedSource);
- }
-
- QString fastSource = brush.second + fastPainterSource;
- QString brushSource = brush.second + brushPainterSource;
-
- compiled[brush.first]["COMPOSITION_MODE_BLEND_MODE_MASK"] = compileSource(fastSource);
- compiled[brush.first]["COMPOSITION_MODE_BLEND_MODE_NOMASK"] = compileSource(brushSource);
- }
-
- QList<QStringPair> temp;
-
- foreach (QStringPair mode, compositionModes)
- temp << QStringPair(mode.first + "_NOMASK", mode.second);
-
- compositionModes += temp;
-
- compositionModes << QStringPair("COMPOSITION_MODE_BLEND_MODE_MASK", "")
- << QStringPair("COMPOSITION_MODE_BLEND_MODE_NOMASK", "");
-
- foreach (QStringPair mask, masks)
- compiled[mask.first]["MASK__"] = compileSource(mask.second);
-
- writeIncludeFile(variables, brushes, compositionModes, masks, compiled);
-
- return 0;
-}
-
-QT_END_NAMESPACE
diff --git a/src/opengl/util/generator.pro b/src/opengl/util/generator.pro
deleted file mode 100644
index ac71934ecf..0000000000
--- a/src/opengl/util/generator.pro
+++ /dev/null
@@ -1,13 +0,0 @@
-######################################################################
-# Automatically generated by qmake (2.01a) Thu Oct 19 11:03:24 2006
-######################################################################
-
-TEMPLATE = app
-TARGET = generator
-DEPENDPATH += .
-INCLUDEPATH += .
-
-# Input
-SOURCES += generator.cpp
-
-CONFIG += console
diff --git a/src/opengl/util/glsl_to_include.sh b/src/opengl/util/glsl_to_include.sh
deleted file mode 100755
index c97239bfdd..0000000000
--- a/src/opengl/util/glsl_to_include.sh
+++ /dev/null
@@ -1,73 +0,0 @@
-#! /bin/sh
-#############################################################################
-##
-## Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-## All rights reserved.
-## Contact: Nokia Corporation (qt-info@nokia.com)
-##
-## This file is the build configuration utility of the Qt Toolkit.
-##
-## $QT_BEGIN_LICENSE:LGPL$
-## GNU Lesser General Public License Usage
-## This file may be used under the terms of the GNU Lesser General Public
-## License version 2.1 as published by the Free Software Foundation and
-## appearing in the file LICENSE.LGPL included in the packaging of this
-## file. Please review the following information to ensure the GNU Lesser
-## General Public License version 2.1 requirements will be met:
-## http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-##
-## In addition, as a special exception, Nokia gives you certain additional
-## rights. These rights are described in the Nokia Qt LGPL Exception
-## version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-##
-## 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.
-##
-## Other Usage
-## Alternatively, this file may be used in accordance with the terms and
-## conditions contained in a signed written agreement between you and Nokia.
-##
-##
-##
-##
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
-
-# Compile a .glsl file to a file that can be included in a C++ program
-USAGE="Usage: $0 <file.glsl>"
-CGC=cgc
-CGC_PROFILE=arbfp1
-
-if test $# -ne 1
-then
- echo $USAGE
- exit 1
-fi
-
-GLSL_FILE=$1
-FRAG_FILE=`basename $1 .glsl`.frag
-#GLSL_INC_FILE=`basename $1 .glsl`.glsl_quoted
-
-echo "// Generated by src/opengl/util/$0 from $1" > $FRAG_FILE
-$CGC -quiet -oglsl -profile $CGC_PROFILE $GLSL_FILE | while read line
-do
- if test `echo $line | cut -c1` != "#"
- then
- echo -e \"$line\" >> $FRAG_FILE
- fi
-done
-echo "; // Generated by src/opengl/util/$0 from $1" >> $FRAG_FILE
-
-#echo "// Generated by src/opengl/util/$0 from $1" > $GLSL_INC_FILE
-#cat $GLSL_FILE | while read line
-#do
-# printf \"%s\\\\n\"\\n "$line" >> $GLSL_INC_FILE
-#done
-#echo "; // Generated by src/opengl/util/$0 from $1" >> $GLSL_INC_FILE
diff --git a/src/opengl/util/linear_brush.glsl b/src/opengl/util/linear_brush.glsl
deleted file mode 100644
index 90a4440a99..0000000000
--- a/src/opengl/util/linear_brush.glsl
+++ /dev/null
@@ -1,22 +0,0 @@
-uniform sampler1D palette;
-uniform vec3 linear;
-uniform vec3 inv_matrix_m0;
-uniform vec3 inv_matrix_m1;
-uniform vec3 inv_matrix_m2;
-
-vec4 brush()
-{
- mat3 mat;
-
- mat[0] = inv_matrix_m0;
- mat[1] = inv_matrix_m1;
- mat[2] = inv_matrix_m2;
-
- vec3 hcoords = mat * vec3(gl_FragCoord.xy, 1);
- vec2 A = hcoords.xy / hcoords.z;
-
- float val = dot(linear.xy, A) * linear.z;
-
- return texture1D(palette, val);
-}
-
diff --git a/src/opengl/util/masks.conf b/src/opengl/util/masks.conf
deleted file mode 100644
index d853d0b6e9..0000000000
--- a/src/opengl/util/masks.conf
+++ /dev/null
@@ -1,2 +0,0 @@
-FRAGMENT_PROGRAM_MASK_TRAPEZOID_AA trap_exact_aa.glsl
-FRAGMENT_PROGRAM_MASK_ELLIPSE_AA ellipse_aa.glsl
diff --git a/src/opengl/util/meego/main.cpp b/src/opengl/util/meego/main.cpp
deleted file mode 100644
index 21ac5fd629..0000000000
--- a/src/opengl/util/meego/main.cpp
+++ /dev/null
@@ -1,89 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtCore/qdebug.h>
-
-#define QT_DEBUG_SHADER_CACHE
-#define QT_MEEGO_EXPERIMENTAL_SHADERCACHE
-#define QT_OPENGL_ES_2
-#define QT_BOOTSTRAPPED
-
-typedef int GLsizei;
-typedef unsigned int GLenum;
-
-#include "../../gl2paintengineex/qglshadercache_meego_p.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-
-int main()
-{
- ShaderCacheSharedMemory shm;
-
- if (!shm.isAttached()) {
- fprintf(stderr, "Unable to attach to shared memory\n");
- return EXIT_FAILURE;
- }
-
- ShaderCacheLocker locker(&shm);
- if (!locker.isLocked()) {
- fprintf(stderr, "Unable to lock shared memory\n");
- return EXIT_FAILURE;
- }
-
- void *data = shm.data();
- Q_ASSERT(data);
-
- CachedShaders *cache = reinterpret_cast<CachedShaders *>(data);
-
- for (int i = 0; i < cache->shaderCount; ++i) {
- printf("Shader %d: %d bytes\n", i, cache->headers[i].size);
- }
-
- printf("\nSummary:\n\n"
- " Amount of cached shaders: %d\n"
- " Bytes used: %d\n"
- " Bytes available: %d\n",
- cache->shaderCount, cache->dataSize, cache->availableSize());
-
- return EXIT_SUCCESS;
-}
-
diff --git a/src/opengl/util/meego/shader-cache-introspector.pro b/src/opengl/util/meego/shader-cache-introspector.pro
deleted file mode 100644
index 520e9a5108..0000000000
--- a/src/opengl/util/meego/shader-cache-introspector.pro
+++ /dev/null
@@ -1,7 +0,0 @@
-TEMPLATE = app
-
-SOURCES += main.cpp
-
-TARGET = shader-cache-introspector
-
-QT = core
diff --git a/src/opengl/util/painter.glsl b/src/opengl/util/painter.glsl
deleted file mode 100644
index b990234778..0000000000
--- a/src/opengl/util/painter.glsl
+++ /dev/null
@@ -1,21 +0,0 @@
-uniform sampler2D dst_texture;
-uniform sampler2D mask_texture;
-uniform vec2 inv_mask_size;
-uniform vec2 inv_dst_size;
-uniform vec2 mask_offset;
-uniform vec4 mask_channel;
-
-float mask()
-{
- return dot(mask_channel, texture2D(mask_texture, (gl_FragCoord.xy + mask_offset) * inv_mask_size));
-}
-
-void main()
-{
- vec4 dst = texture2D(dst_texture, gl_FragCoord.xy * inv_dst_size);
-
- // combine clip and coverage channels
- float mask_alpha = mask();
-
- gl_FragColor = mix(dst, composite(brush(), dst), mask_alpha);
-}
diff --git a/src/opengl/util/painter_nomask.glsl b/src/opengl/util/painter_nomask.glsl
deleted file mode 100644
index af5ad6505f..0000000000
--- a/src/opengl/util/painter_nomask.glsl
+++ /dev/null
@@ -1,9 +0,0 @@
-uniform sampler2D dst_texture;
-uniform vec2 inv_dst_size;
-
-void main()
-{
- vec4 dst = texture2D(dst_texture, gl_FragCoord.xy * inv_dst_size);
-
- gl_FragColor = composite(brush(), dst);
-}
diff --git a/src/opengl/util/pattern_brush.glsl b/src/opengl/util/pattern_brush.glsl
deleted file mode 100644
index 31702b887c..0000000000
--- a/src/opengl/util/pattern_brush.glsl
+++ /dev/null
@@ -1,23 +0,0 @@
-uniform sampler2D brush_texture;
-uniform vec2 inv_brush_texture_size;
-uniform vec3 inv_matrix_m0;
-uniform vec3 inv_matrix_m1;
-uniform vec3 inv_matrix_m2;
-
-vec4 brush()
-{
- mat3 mat;
-
- mat[0] = inv_matrix_m0;
- mat[1] = inv_matrix_m1;
- mat[2] = inv_matrix_m2;
-
- vec3 hcoords = mat * vec3(gl_FragCoord.xy, 1);
- vec2 coords = hcoords.xy / hcoords.z;
-
- coords *= inv_brush_texture_size;
-
- float alpha = 1.0 - texture2D(brush_texture, coords).r;
-
- return gl_Color * alpha;
-}
diff --git a/src/opengl/util/radial_brush.glsl b/src/opengl/util/radial_brush.glsl
deleted file mode 100644
index 84bec62e65..0000000000
--- a/src/opengl/util/radial_brush.glsl
+++ /dev/null
@@ -1,28 +0,0 @@
-uniform sampler1D palette;
-uniform vec2 fmp;
-uniform float fmp2_m_radius2;
-uniform vec3 inv_matrix_m0;
-uniform vec3 inv_matrix_m1;
-uniform vec3 inv_matrix_m2;
-
-vec4 brush()
-{
- mat3 mat;
-
- mat[0] = inv_matrix_m0;
- mat[1] = inv_matrix_m1;
- mat[2] = inv_matrix_m2;
-
- vec3 hcoords = mat * vec3(gl_FragCoord.xy, 1);
- vec2 A = hcoords.xy / hcoords.z;
- vec2 B = fmp;
-
- float a = fmp2_m_radius2;
- float b = 2.0*dot(A, B);
- float c = -dot(A, A);
-
- float val = (-b + sqrt(b*b - 4.0*a*c)) / (2.0*a);
-
- return texture1D(palette, val);
-}
-
diff --git a/src/opengl/util/simple_porter_duff.glsl b/src/opengl/util/simple_porter_duff.glsl
deleted file mode 100644
index 4cb0599ac5..0000000000
--- a/src/opengl/util/simple_porter_duff.glsl
+++ /dev/null
@@ -1,16 +0,0 @@
-uniform vec2 porterduff_ab;
-uniform vec3 porterduff_xyz;
-
-vec4 composite(vec4 src, vec4 dst)
-{
- vec4 result;
-
- result.xyz = porterduff_ab.x * src.xyz * dst.a
- + porterduff_ab.y * dst.xyz * src.a
- + porterduff_xyz.y * src.xyz * (1.0 - dst.a)
- + porterduff_xyz.z * dst.xyz * (1.0 - src.a);
-
- result.a = dot(porterduff_xyz, vec3(src.a * dst.a, src.a * (1.0 - dst.a), dst.a * (1.0 - src.a)));
-
- return result;
-}
diff --git a/src/opengl/util/solid_brush.glsl b/src/opengl/util/solid_brush.glsl
deleted file mode 100644
index 760afd1a72..0000000000
--- a/src/opengl/util/solid_brush.glsl
+++ /dev/null
@@ -1,4 +0,0 @@
-vec4 brush()
-{
- return gl_Color;
-}
diff --git a/src/opengl/util/texture_brush.glsl b/src/opengl/util/texture_brush.glsl
deleted file mode 100644
index 949825583f..0000000000
--- a/src/opengl/util/texture_brush.glsl
+++ /dev/null
@@ -1,21 +0,0 @@
-uniform sampler2D brush_texture;
-uniform vec2 inv_brush_texture_size;
-uniform vec3 inv_matrix_m0;
-uniform vec3 inv_matrix_m1;
-uniform vec3 inv_matrix_m2;
-
-vec4 brush()
-{
- mat3 mat;
-
- mat[0] = inv_matrix_m0;
- mat[1] = inv_matrix_m1;
- mat[2] = inv_matrix_m2;
-
- vec3 hcoords = mat * vec3(gl_FragCoord.xy, 1);
- vec2 coords = hcoords.xy / hcoords.z;
-
- coords *= inv_brush_texture_size;
-
- return texture2D(brush_texture, coords);
-}
diff --git a/src/opengl/util/trap_exact_aa.glsl b/src/opengl/util/trap_exact_aa.glsl
deleted file mode 100644
index 1637f430b5..0000000000
--- a/src/opengl/util/trap_exact_aa.glsl
+++ /dev/null
@@ -1,58 +0,0 @@
-float quad_aa()
-{
- float top = min(gl_FragCoord.y + 0.5, gl_TexCoord[0].x);
- float bottom = max(gl_FragCoord.y - 0.5, gl_TexCoord[0].y);
-
- float area = top - bottom;
-
- float left = gl_FragCoord.x - 0.5;
- float right = gl_FragCoord.x + 0.5;
-
- // use line equations to compute intersections of left/right edges with top/bottom of truncated pixel
- vec4 vecX = gl_TexCoord[1].xxzz * vec2(top, bottom).xyxy + gl_TexCoord[1].yyww;
-
- vec2 invA = gl_TexCoord[0].zw;
-
- // transform right line to left to be able to use same calculations for both
- vecX.zw = 2.0 * gl_FragCoord.x - vecX.zw;
-
- vec2 topX = vec2(vecX.x, vecX.z);
- vec2 bottomX = vec2(vecX.y, vecX.w);
-
- // transform lines such that top intersection is to the right of bottom intersection
- vec2 topXTemp = max(topX, bottomX);
- vec2 bottomXTemp = min(topX, bottomX);
-
- // make sure line slope reflects mirrored lines
- invA = mix(invA, -invA, step(topX, bottomX));
-
- vec2 vecLeftRight = vec2(left, right);
-
- // compute the intersections of the lines with the left and right edges of the pixel
- vec4 intersectY = bottom + (vecLeftRight.xyxy - bottomXTemp.xxyy) * invA.xxyy;
-
- vec2 temp = mix(area - 0.5 * (right - bottomXTemp) * (intersectY.yw - bottom), // left < bottom < right < top
- (0.5 * (topXTemp + bottomXTemp) - left) * area, // left < bottom < top < right
- step(topXTemp, right.xx));
-
- vec2 excluded = 0.5 * (top - intersectY.xz) * (topXTemp - left); // bottom < left < top < right
-
- excluded = mix((top - 0.5 * (intersectY.yw + intersectY.xz)) * (right - left), // bottom < left < right < top
- excluded, step(topXTemp, right.xx));
-
- excluded = mix(temp, // left < bottom < right (see calculation of temp)
- excluded, step(bottomXTemp, left.xx));
-
- excluded = mix(vec2(area, area), // right < bottom < top
- excluded, step(bottomXTemp, right.xx));
-
- excluded *= step(left, topXTemp);
-
- return (area - excluded.x - excluded.y) * step(bottom, top);
-}
-
-void main()
-{
- gl_FragColor = quad_aa().xxxx;
-}
-
diff --git a/src/openvg/openvg.pro b/src/openvg/openvg.pro
deleted file mode 100644
index bd9aa1a732..0000000000
--- a/src/openvg/openvg.pro
+++ /dev/null
@@ -1,76 +0,0 @@
-TARGET = QtOpenVG
-QT += core-private \
- gui-private
-
-CONFIG += module
-MODULE_PRI = ../modules/qt_openvg.pri
-
-DEFINES+=QT_BUILD_OPENVG_LIB
-
-contains(QT_CONFIG, shivavg) {
- DEFINES += QVG_NO_DRAW_GLYPHS
- DEFINES += QVG_NO_RENDER_TO_MASK
- DEFINES += QVG_SCISSOR_CLIP
-}
-
-HEADERS += \
- qvg.h \
- qvg_p.h \
- qpaintengine_vg_p.h \
- qpixmapdata_vg_p.h \
- qpixmapfilter_vg_p.h \
- qvgcompositionhelper_p.h \
- qvgimagepool_p.h \
- qvgfontglyphcache_p.h
-SOURCES += \
- qpaintengine_vg.cpp \
- qpixmapdata_vg.cpp \
- qpixmapfilter_vg.cpp \
- qvgimagepool.cpp
-
-contains(QT_CONFIG, egl) {
- HEADERS += \
- qwindowsurface_vgegl_p.h \
- qwindowsurface_vg_p.h
- SOURCES += \
- qwindowsurface_vg.cpp \
- qwindowsurface_vgegl.cpp
-}
-
-symbian {
- DEFINES += QVG_RECREATE_ON_SIZE_CHANGE QVG_BUFFER_SCROLLING QVG_SCISSOR_CLIP
- SOURCES += \
- qvg_symbian.cpp
-
- contains(QT_CONFIG, freetype) {
- DEFINES += QT_NO_FONTCONFIG
- INCLUDEPATH += \
- ../3rdparty/freetype/src \
- ../3rdparty/freetype/include
- }
-}
-
-load(qt_module_config)
-
-HEADERS += $$QT_SOURCE_TREE/src/openvg/qtopenvgversion.h
-
-unix|win32-g++*:QMAKE_PKGCONFIG_REQUIRES = QtCore QtGui
-symbian:TARGET.UID3 = 0x2001E62F
-
-!isEmpty(QMAKE_INCDIR_OPENVG): INCLUDEPATH += $$QMAKE_INCDIR_OPENVG
-!isEmpty(QMAKE_LIBDIR_OPENVG): LIBS_PRIVATE += -L$$QMAKE_LIBDIR_OPENVG
-!isEmpty(QMAKE_LIBS_OPENVG): LIBS_PRIVATE += $$QMAKE_LIBS_OPENVG
-
-contains(QT_CONFIG, egl) {
- !isEmpty(QMAKE_INCDIR_EGL): INCLUDEPATH += $$QMAKE_INCDIR_EGL
- !isEmpty(QMAKE_LIBDIR_EGL): LIBS_PRIVATE += -L$$QMAKE_LIBDIR_EGL
- !isEmpty(QMAKE_LIBS_EGL): LIBS_PRIVATE += $$QMAKE_LIBS_EGL
-}
-
-contains(QT_CONFIG, openvg_on_opengl) {
- !isEmpty(QMAKE_INCDIR_OPENGL): INCLUDEPATH += $$QMAKE_INCDIR_OPENGL
- !isEmpty(QMAKE_LIBDIR_OPENGL): LIBS_PRIVATE += -L$$QMAKE_LIBDIR_OPENGL
- !isEmpty(QMAKE_LIBS_OPENGL): LIBS_PRIVATE += $$QMAKE_LIBS_OPENGL
-}
-
-INCLUDEPATH += ../3rdparty/harfbuzz/src
diff --git a/src/openvg/qpaintengine_vg.cpp b/src/openvg/qpaintengine_vg.cpp
deleted file mode 100644
index b919b087cf..0000000000
--- a/src/openvg/qpaintengine_vg.cpp
+++ /dev/null
@@ -1,4225 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenVG module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qpaintengine_vg_p.h"
-#include "qpixmapdata_vg_p.h"
-#include "qpixmapfilter_vg_p.h"
-#include "qvgcompositionhelper_p.h"
-#include "qvgimagepool_p.h"
-#include "qvgfontglyphcache_p.h"
-#if !defined(QT_NO_EGL)
-#include <QtGui/private/qeglcontext_p.h>
-#include "qwindowsurface_vgegl_p.h"
-#endif
-#include <QtCore/qvarlengtharray.h>
-#include <QtGui/private/qdrawhelper_p.h>
-#include <QtGui/private/qtextengine_p.h>
-#include <QtGui/private/qfontengine_p.h>
-#include <QtGui/private/qpainterpath_p.h>
-#include <QtGui/private/qstatictext_p.h>
-#include <QtGui/QApplication>
-#include <QtGui/QDesktopWidget>
-#include <QtCore/qmath.h>
-#include <QDebug>
-#include <QSet>
-
-QT_BEGIN_NAMESPACE
-
-// vgRenderToMask() only exists in OpenVG 1.1 and higher.
-// Also, disable masking completely if we are using the scissor to clip.
-#if !defined(OPENVG_VERSION_1_1) && !defined(QVG_NO_RENDER_TO_MASK)
-#define QVG_NO_RENDER_TO_MASK 1
-#endif
-#if defined(QVG_SCISSOR_CLIP) && !defined(QVG_NO_RENDER_TO_MASK)
-#define QVG_NO_RENDER_TO_MASK 1
-#endif
-
-// use the same rounding as in qrasterizer.cpp (6 bit fixed point)
-static const qreal aliasedCoordinateDelta = 0.5 - 0.015625;
-
-#if !defined(QVG_NO_DRAW_GLYPHS)
-
-class QVGPaintEnginePrivate;
-
-typedef QHash<QFontEngine*, QVGFontGlyphCache*> QVGFontCache;
-
-#endif
-
-class QVGFontEngineCleaner : public QObject
-{
- Q_OBJECT
-public:
- QVGFontEngineCleaner(QVGPaintEnginePrivate *d);
- ~QVGFontEngineCleaner();
-
-public slots:
- void fontEngineDestroyed();
-
-private:
- QVGPaintEnginePrivate *d_ptr;
-};
-
-class QVGPaintEnginePrivate : public QPaintEngineExPrivate
-{
- Q_DECLARE_PUBLIC(QVGPaintEngine)
-public:
- // Extra blending modes from VG_KHR_advanced_blending extension.
- // Use the QT_VG prefix to avoid conflicts with any definitions
- // that may come in via <VG/vgext.h>.
- enum AdvancedBlending {
- QT_VG_BLEND_OVERLAY_KHR = 0x2010,
- QT_VG_BLEND_HARDLIGHT_KHR = 0x2011,
- QT_VG_BLEND_SOFTLIGHT_SVG_KHR = 0x2012,
- QT_VG_BLEND_SOFTLIGHT_KHR = 0x2013,
- QT_VG_BLEND_COLORDODGE_KHR = 0x2014,
- QT_VG_BLEND_COLORBURN_KHR = 0x2015,
- QT_VG_BLEND_DIFFERENCE_KHR = 0x2016,
- QT_VG_BLEND_SUBTRACT_KHR = 0x2017,
- QT_VG_BLEND_INVERT_KHR = 0x2018,
- QT_VG_BLEND_EXCLUSION_KHR = 0x2019,
- QT_VG_BLEND_LINEARDODGE_KHR = 0x201a,
- QT_VG_BLEND_LINEARBURN_KHR = 0x201b,
- QT_VG_BLEND_VIVIDLIGHT_KHR = 0x201c,
- QT_VG_BLEND_LINEARLIGHT_KHR = 0x201d,
- QT_VG_BLEND_PINLIGHT_KHR = 0x201e,
- QT_VG_BLEND_HARDMIX_KHR = 0x201f,
- QT_VG_BLEND_CLEAR_KHR = 0x2020,
- QT_VG_BLEND_DST_KHR = 0x2021,
- QT_VG_BLEND_SRC_OUT_KHR = 0x2022,
- QT_VG_BLEND_DST_OUT_KHR = 0x2023,
- QT_VG_BLEND_SRC_ATOP_KHR = 0x2024,
- QT_VG_BLEND_DST_ATOP_KHR = 0x2025,
- QT_VG_BLEND_XOR_KHR = 0x2026
- };
-
- QVGPaintEnginePrivate(QVGPaintEngine *q_ptr);
- ~QVGPaintEnginePrivate();
-
- void init();
- void initObjects();
- void destroy();
- void setTransform(VGMatrixMode mode, const QTransform& transform);
- void updateTransform(QPaintDevice *pdev);
- void draw(VGPath path, const QPen& pen, const QBrush& brush, VGint rule = VG_EVEN_ODD);
- void stroke(VGPath path, const QPen& pen);
- void fill(VGPath path, const QBrush& brush, VGint rule = VG_EVEN_ODD);
- VGPath vectorPathToVGPath(const QVectorPath& path);
- VGPath painterPathToVGPath(const QPainterPath& path);
- VGPath roundedRectPath(const QRectF &rect, qreal xRadius, qreal yRadius, Qt::SizeMode mode);
- VGPaintType setBrush
- (VGPaint paint, const QBrush& brush, VGMatrixMode mode,
- VGPaintType prevPaintType);
- void setPenParams(const QPen& pen);
- void setBrushTransform(const QBrush& brush, VGMatrixMode mode);
- void setupColorRamp(const QGradient *grad, VGPaint paint);
- void setImageOptions();
- void systemStateChanged();
-#if !defined(QVG_SCISSOR_CLIP)
- void ensureMask(QVGPaintEngine *engine, int width, int height);
- void modifyMask
- (QVGPaintEngine *engine, VGMaskOperation op, const QRegion& region);
- void modifyMask
- (QVGPaintEngine *engine, VGMaskOperation op, const QRect& rect);
-#endif
-
- VGint maxScissorRects; // Maximum scissor rectangles for clipping.
-
- VGPaint penPaint; // Paint for currently active pen.
- VGPaint brushPaint; // Paint for currently active brush.
- VGPaint opacityPaint; // Paint for drawing images with opacity.
- VGPaint fillPaint; // Current fill paint that is active.
-
- QPen currentPen; // Current pen set in "penPaint".
- QBrush currentBrush; // Current brush set in "brushPaint".
-
- bool forcePenChange; // Force a pen change, even if the same.
- bool forceBrushChange; // Force a brush change, even if the same.
-
- bool hasExtendedRadialGradientPen; // Current pen's brush is extended radial gradient.
- bool hasExtendedRadialGradientBrush; // Current brush is extended radial gradient.
-
- VGPaintType penType; // Type of the last pen that was set.
- VGPaintType brushType; // Type of the last brush that was set.
-
- QPointF brushOrigin; // Current brush origin.
-
- VGint fillRule; // Last fill rule that was set.
-
- qreal opacity; // Current drawing opacity.
- qreal paintOpacity; // Opacity in opacityPaint.
-
-#if !defined(QVG_NO_MODIFY_PATH)
- VGPath rectPath; // Cached path for quick drawing of rectangles.
- VGPath linePath; // Cached path for quick drawing of lines.
- VGPath roundRectPath; // Cached path for quick drawing of rounded rects.
-#endif
-
- QTransform transform; // Currently active transform.
- bool simpleTransform; // True if the transform is simple (non-projective).
- qreal penScale; // Pen scaling factor from "transform".
-
- QTransform pathTransform; // Calculated VG path transformation.
- QTransform imageTransform; // Calculated VG image transformation.
- bool pathTransformSet; // True if path transform set in the VG context.
-
- bool maskValid; // True if vgMask() contains valid data.
- bool maskIsSet; // True if mask would be fully set if it was valid.
- bool scissorMask; // True if scissor is used in place of the mask.
- bool rawVG; // True if processing a raw VG escape.
-
- QRect maskRect; // Rectangle version of mask if it is simple.
-
- QTransform penTransform; // Transform for the pen.
- QTransform brushTransform; // Transform for the brush.
-
- VGMatrixMode matrixMode; // Last matrix mode that was set.
- VGImageMode imageMode; // Last image mode that was set.
-
- QRegion scissorRegion; // Currently active scissor region.
- bool scissorActive; // True if scissor region is active.
- bool scissorDirty; // True if scissor is dirty after native painting.
-
- QPaintEngine::DirtyFlags dirty;
-
- QColor clearColor; // Last clear color that was set.
- VGfloat clearOpacity; // Opacity during the last clear.
-
- VGBlendMode blendMode; // Active blend mode.
- VGRenderingQuality renderingQuality; // Active rendering quality.
- VGImageQuality imageQuality; // Active image quality.
-
-#if !defined(QVG_NO_DRAW_GLYPHS)
- QVGFontCache fontCache;
- QVGFontEngineCleaner *fontEngineCleaner;
-#endif
-
- bool hasAdvancedBlending;
-
- QScopedPointer<QPixmapFilter> convolutionFilter;
- QScopedPointer<QPixmapFilter> colorizeFilter;
- QScopedPointer<QPixmapFilter> dropShadowFilter;
- QScopedPointer<QPixmapFilter> blurFilter;
-
- // Ensure that the path transform is properly set in the VG context
- // before we perform a vgDrawPath() operation.
- inline void ensurePathTransform()
- {
- if (!pathTransformSet) {
- QTransform aliasedTransform = pathTransform;
- if (renderingQuality == VG_RENDERING_QUALITY_NONANTIALIASED && currentPen != Qt::NoPen)
- aliasedTransform = aliasedTransform
- * QTransform::fromTranslate(aliasedCoordinateDelta, -aliasedCoordinateDelta);
- setTransform(VG_MATRIX_PATH_USER_TO_SURFACE, aliasedTransform);
- pathTransformSet = true;
- }
- }
-
- // Ensure that a specific pen has been set into penPaint.
- inline void ensurePen(const QPen& pen) {
- if (forcePenChange || pen != currentPen) {
- currentPen = pen;
- forcePenChange = false;
- penType = setBrush
- (penPaint, pen.brush(),
- VG_MATRIX_STROKE_PAINT_TO_USER, penType);
- setPenParams(pen);
- }
- }
-
- // Ensure that a specific brush has been set into brushPaint.
- inline void ensureBrush(const QBrush& brush) {
- if (forceBrushChange || brush != currentBrush) {
- currentBrush = brush;
- forceBrushChange = false;
- brushType = setBrush
- (brushPaint, brush, VG_MATRIX_FILL_PAINT_TO_USER, brushType);
- }
- if (fillPaint != brushPaint) {
- vgSetPaint(brushPaint, VG_FILL_PATH);
- fillPaint = brushPaint;
- }
- }
-
- inline bool needsEmulation(const QBrush &brush) const
- {
- extern bool qt_isExtendedRadialGradient(const QBrush &brush);
- return qt_isExtendedRadialGradient(brush);
- }
-
- inline bool needsEmulation() const
- {
- return hasExtendedRadialGradientPen || hasExtendedRadialGradientBrush;
- }
-
- inline bool needsPenEmulation() const
- {
- return hasExtendedRadialGradientPen;
- }
-
- inline bool needsBrushEmulation() const
- {
- return hasExtendedRadialGradientBrush;
- }
-
- // Set various modes, but only if different.
- inline void setImageMode(VGImageMode mode);
- inline void setRenderingQuality(VGRenderingQuality mode);
- inline void setImageQuality(VGImageQuality mode);
- inline void setBlendMode(VGBlendMode mode);
- inline void setFillRule(VGint mode);
-
- // Clear all lazily-set modes.
- void clearModes();
-
-private:
- QVGPaintEngine *q;
-};
-
-inline void QVGPaintEnginePrivate::setImageMode(VGImageMode mode)
-{
- if (imageMode != mode) {
- imageMode = mode;
- vgSeti(VG_IMAGE_MODE, mode);
- }
-}
-
-inline void QVGPaintEnginePrivate::setRenderingQuality(VGRenderingQuality mode)
-{
- if (renderingQuality != mode) {
- vgSeti(VG_RENDERING_QUALITY, mode);
- renderingQuality = mode;
- pathTransformSet = false; // need to tweak transform for aliased stroking
- }
-}
-
-inline void QVGPaintEnginePrivate::setImageQuality(VGImageQuality mode)
-{
- if (imageQuality != mode) {
- vgSeti(VG_IMAGE_QUALITY, mode);
- imageQuality = mode;
- }
-}
-
-inline void QVGPaintEnginePrivate::setBlendMode(VGBlendMode mode)
-{
- if (blendMode != mode) {
- vgSeti(VG_BLEND_MODE, mode);
- blendMode = mode;
- }
-}
-
-inline void QVGPaintEnginePrivate::setFillRule(VGint mode)
-{
- if (fillRule != mode) {
- fillRule = mode;
- vgSeti(VG_FILL_RULE, mode);
- }
-}
-
-void QVGPaintEnginePrivate::clearModes()
-{
- matrixMode = (VGMatrixMode)0;
- imageMode = (VGImageMode)0;
- blendMode = (VGBlendMode)0;
- renderingQuality = (VGRenderingQuality)0;
- imageQuality = (VGImageQuality)0;
-}
-
-QVGPaintEnginePrivate::QVGPaintEnginePrivate(QVGPaintEngine *q_ptr) : q(q_ptr)
-{
- init();
-}
-
-void QVGPaintEnginePrivate::init()
-{
- maxScissorRects = 0;
-
- penPaint = 0;
- brushPaint = 0;
- opacityPaint = 0;
- fillPaint = 0;
-
- forcePenChange = true;
- forceBrushChange = true;
-
- hasExtendedRadialGradientPen = false;
- hasExtendedRadialGradientBrush = false;
-
- penType = (VGPaintType)0;
- brushType = (VGPaintType)0;
-
- brushOrigin = QPointF(0.0f, 0.0f);
-
- fillRule = 0;
-
- opacity = 1.0;
- paintOpacity = 1.0f;
-
-#if !defined(QVG_NO_MODIFY_PATH)
- rectPath = 0;
- linePath = 0;
- roundRectPath = 0;
-#endif
-
- simpleTransform = true;
- pathTransformSet = false;
- penScale = 1.0;
-
- maskValid = false;
- maskIsSet = false;
- scissorMask = false;
- rawVG = false;
-
- scissorActive = false;
- scissorDirty = false;
-
- dirty = 0;
-
- clearOpacity = 1.0f;
-
-#if !defined(QVG_NO_DRAW_GLYPHS)
- fontEngineCleaner = 0;
-#endif
-
- hasAdvancedBlending = false;
-
- clearModes();
-}
-
-QVGPaintEnginePrivate::~QVGPaintEnginePrivate()
-{
- destroy();
-}
-
-void QVGPaintEnginePrivate::initObjects()
-{
- maxScissorRects = vgGeti(VG_MAX_SCISSOR_RECTS);
-
- penPaint = vgCreatePaint();
- vgSetParameteri(penPaint, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR);
- vgSetPaint(penPaint, VG_STROKE_PATH);
-
- vgSeti(VG_MATRIX_MODE, VG_MATRIX_STROKE_PAINT_TO_USER);
- vgLoadIdentity();
-
- brushPaint = vgCreatePaint();
- vgSetParameteri(brushPaint, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR);
- vgSetPaint(brushPaint, VG_FILL_PATH);
- fillPaint = brushPaint;
-
- vgSeti(VG_MATRIX_MODE, VG_MATRIX_FILL_PAINT_TO_USER);
- vgLoadIdentity();
- matrixMode = VG_MATRIX_FILL_PAINT_TO_USER;
-
- opacityPaint = vgCreatePaint();
- vgSetParameteri(opacityPaint, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR);
- VGfloat values[4];
- values[0] = 1.0f;
- values[1] = 1.0f;
- values[2] = 1.0f;
- values[3] = paintOpacity;
- vgSetParameterfv(opacityPaint, VG_PAINT_COLOR, 4, values);
-
-#if !defined(QVG_NO_MODIFY_PATH)
- // Create a dummy path for rectangle drawing, which we can
- // modify later with vgModifyPathCoords(). This should be
- // faster than constantly creating and destroying paths.
- rectPath = vgCreatePath(VG_PATH_FORMAT_STANDARD,
- VG_PATH_DATATYPE_F,
- 1.0f, // scale
- 0.0f, // bias
- 5, // segmentCapacityHint
- 8, // coordCapacityHint
- VG_PATH_CAPABILITY_ALL);
- static VGubyte const segments[5] = {
- VG_MOVE_TO_ABS,
- VG_LINE_TO_ABS,
- VG_LINE_TO_ABS,
- VG_LINE_TO_ABS,
- VG_CLOSE_PATH
- };
- VGfloat coords[8];
- coords[0] = 0.0f;
- coords[1] = 0.0f;
- coords[2] = 100.0f;
- coords[3] = coords[1];
- coords[4] = coords[2];
- coords[5] = 100.0f;
- coords[6] = coords[0];
- coords[7] = coords[5];
- vgAppendPathData(rectPath, 5, segments, coords);
-
- // Create a dummy line drawing path as well.
- linePath = vgCreatePath(VG_PATH_FORMAT_STANDARD,
- VG_PATH_DATATYPE_F,
- 1.0f, // scale
- 0.0f, // bias
- 2, // segmentCapacityHint
- 4, // coordCapacityHint
- VG_PATH_CAPABILITY_ALL);
- vgAppendPathData(linePath, 2, segments, coords);
-#endif
-
- const char *extensions = reinterpret_cast<const char *>(vgGetString(VG_EXTENSIONS));
- if (extensions)
- hasAdvancedBlending = strstr(extensions, "VG_KHR_advanced_blending") != 0;
-}
-
-void QVGPaintEnginePrivate::destroy()
-{
- if (penPaint)
- vgDestroyPaint(penPaint);
- if (brushPaint)
- vgDestroyPaint(brushPaint);
- if (opacityPaint)
- vgDestroyPaint(opacityPaint);
-
-#if !defined(QVG_NO_MODIFY_PATH)
- if (rectPath)
- vgDestroyPath(rectPath);
- if (linePath)
- vgDestroyPath(linePath);
- if (roundRectPath)
- vgDestroyPath(roundRectPath);
-#endif
-
-#if !defined(QVG_NO_DRAW_GLYPHS)
- QVGFontCache::Iterator it;
- for (it = fontCache.begin(); it != fontCache.end(); ++it)
- delete it.value();
- fontCache.clear();
- delete fontEngineCleaner;
-#endif
-}
-
-// Set a specific VG transformation matrix in the current VG context.
-void QVGPaintEnginePrivate::setTransform
- (VGMatrixMode mode, const QTransform& transform)
-{
- VGfloat mat[9];
- if (mode != matrixMode) {
- vgSeti(VG_MATRIX_MODE, mode);
- matrixMode = mode;
- }
- mat[0] = transform.m11();
- mat[1] = transform.m12();
- mat[2] = transform.m13();
- mat[3] = transform.m21();
- mat[4] = transform.m22();
- mat[5] = transform.m23();
- mat[6] = transform.m31();
- mat[7] = transform.m32();
- mat[8] = transform.m33();
- vgLoadMatrix(mat);
-}
-
-Q_GUI_EXPORT bool qt_scaleForTransform(const QTransform &transform, qreal *scale);
-
-void QVGPaintEnginePrivate::updateTransform(QPaintDevice *pdev)
-{
- VGfloat devh = pdev->height();
-
- // Construct the VG transform by combining the Qt transform with
- // the following viewport transformation:
- // | 1 0 0 |
- // | 0 -1 devh |
- // | 0 0 1 |
- // The full VG transform is effectively:
- // 1. Apply the user's transformation matrix.
- // 2. Flip the co-ordinate system upside down.
- QTransform viewport(1.0f, 0.0f, 0.0f,
- 0.0f, -1.0f, 0.0f,
- 0.0f, devh, 1.0f);
-
- // Compute the path transform and determine if it is projective.
- pathTransform = transform * viewport;
- bool projective = (pathTransform.m13() != 0.0f ||
- pathTransform.m23() != 0.0f ||
- pathTransform.m33() != 1.0f);
- if (projective) {
- // The engine cannot do projective path transforms for us,
- // so we will have to convert the co-ordinates ourselves.
- // Change the matrix to just the viewport transformation.
- pathTransform = viewport;
- simpleTransform = false;
- } else {
- simpleTransform = true;
- }
- pathTransformSet = false;
-
- // The image transform is always the full transformation,
- imageTransform = transform * viewport;
-
- // Calculate the scaling factor to use for turning cosmetic pens
- // into ordinary non-cosmetic pens.
- qt_scaleForTransform(transform, &penScale);
-}
-
-VGPath QVGPaintEnginePrivate::vectorPathToVGPath(const QVectorPath& path)
-{
- int count = path.elementCount();
- const qreal *points = path.points();
- const QPainterPath::ElementType *elements = path.elements();
-
- VGPath vgpath = vgCreatePath(VG_PATH_FORMAT_STANDARD,
- VG_PATH_DATATYPE_F,
- 1.0f, // scale
- 0.0f, // bias
- count + 1, // segmentCapacityHint
- count * 2, // coordCapacityHint
- VG_PATH_CAPABILITY_ALL);
-
- // Size is sufficient segments for drawRoundedRect() paths.
- QVarLengthArray<VGubyte, 20> segments;
-
- if (sizeof(qreal) == sizeof(VGfloat) && elements && simpleTransform) {
- // If Qt was compiled with qreal the same size as VGfloat,
- // then convert the segment types and use the incoming
- // points array directly.
- for (int i = 0; i < count; ++i) {
- switch (elements[i]) {
-
- case QPainterPath::MoveToElement:
- segments.append(VG_MOVE_TO_ABS); break;
-
- case QPainterPath::LineToElement:
- segments.append(VG_LINE_TO_ABS); break;
-
- case QPainterPath::CurveToElement:
- segments.append(VG_CUBIC_TO_ABS); break;
-
- case QPainterPath::CurveToDataElement: break;
-
- }
- }
- if (path.hasImplicitClose())
- segments.append(VG_CLOSE_PATH);
-
- vgAppendPathData(vgpath, segments.count(), segments.constData(),
- reinterpret_cast<const VGfloat *>(points));
-
- return vgpath;
- }
-
- // Sizes chosen so that drawRoundedRect() paths fit in these arrays.
- QVarLengthArray<VGfloat, 48> coords;
-
- int curvePos = 0;
- QPointF temp;
-
- if (elements && simpleTransform) {
- // Convert the members of the element array.
- for (int i = 0; i < count; ++i) {
- switch (elements[i]) {
-
- case QPainterPath::MoveToElement:
- {
- coords.append(points[0]);
- coords.append(points[1]);
- segments.append(VG_MOVE_TO_ABS);
- }
- break;
-
- case QPainterPath::LineToElement:
- {
- coords.append(points[0]);
- coords.append(points[1]);
- segments.append(VG_LINE_TO_ABS);
- }
- break;
-
- case QPainterPath::CurveToElement:
- {
- coords.append(points[0]);
- coords.append(points[1]);
- curvePos = 2;
- }
- break;
-
- case QPainterPath::CurveToDataElement:
- {
- coords.append(points[0]);
- coords.append(points[1]);
- curvePos += 2;
- if (curvePos == 6) {
- curvePos = 0;
- segments.append(VG_CUBIC_TO_ABS);
- }
- }
- break;
-
- }
- points += 2;
- }
- } else if (elements && !simpleTransform) {
- // Convert the members of the element array after applying the
- // current transform to the path locally.
- for (int i = 0; i < count; ++i) {
- switch (elements[i]) {
-
- case QPainterPath::MoveToElement:
- {
- temp = transform.map(QPointF(points[0], points[1]));
- coords.append(temp.x());
- coords.append(temp.y());
- segments.append(VG_MOVE_TO_ABS);
- }
- break;
-
- case QPainterPath::LineToElement:
- {
- temp = transform.map(QPointF(points[0], points[1]));
- coords.append(temp.x());
- coords.append(temp.y());
- segments.append(VG_LINE_TO_ABS);
- }
- break;
-
- case QPainterPath::CurveToElement:
- {
- temp = transform.map(QPointF(points[0], points[1]));
- coords.append(temp.x());
- coords.append(temp.y());
- curvePos = 2;
- }
- break;
-
- case QPainterPath::CurveToDataElement:
- {
- temp = transform.map(QPointF(points[0], points[1]));
- coords.append(temp.x());
- coords.append(temp.y());
- curvePos += 2;
- if (curvePos == 6) {
- curvePos = 0;
- segments.append(VG_CUBIC_TO_ABS);
- }
- }
- break;
-
- }
- points += 2;
- }
- } else if (count > 0 && simpleTransform) {
- // If there is no element array, then the path is assumed
- // to be a MoveTo followed by several LineTo's.
- coords.append(points[0]);
- coords.append(points[1]);
- segments.append(VG_MOVE_TO_ABS);
- while (count > 1) {
- points += 2;
- coords.append(points[0]);
- coords.append(points[1]);
- segments.append(VG_LINE_TO_ABS);
- --count;
- }
- } else if (count > 0 && !simpleTransform) {
- // Convert a simple path, and apply the transform locally.
- temp = transform.map(QPointF(points[0], points[1]));
- coords.append(temp.x());
- coords.append(temp.y());
- segments.append(VG_MOVE_TO_ABS);
- while (count > 1) {
- points += 2;
- temp = transform.map(QPointF(points[0], points[1]));
- coords.append(temp.x());
- coords.append(temp.y());
- segments.append(VG_LINE_TO_ABS);
- --count;
- }
- }
-
- // Close the path if specified.
- if (path.hasImplicitClose())
- segments.append(VG_CLOSE_PATH);
-
- vgAppendPathData(vgpath, segments.count(),
- segments.constData(), coords.constData());
-
- return vgpath;
-}
-
-VGPath QVGPaintEnginePrivate::painterPathToVGPath(const QPainterPath& path)
-{
- int count = path.elementCount();
-
- VGPath vgpath = vgCreatePath(VG_PATH_FORMAT_STANDARD,
- VG_PATH_DATATYPE_F,
- 1.0f, // scale
- 0.0f, // bias
- count + 1, // segmentCapacityHint
- count * 2, // coordCapacityHint
- VG_PATH_CAPABILITY_ALL);
-
- if (count == 0)
- return vgpath;
-
- const QPainterPath::Element *elements = &(path.elementAt(0));
-
- // Sizes chosen so that drawRoundedRect() paths fit in these arrays.
- QVarLengthArray<VGfloat, 48> coords;
- QVarLengthArray<VGubyte, 20> segments;
-
- int curvePos = 0;
- QPointF temp;
-
- // Keep track of the start and end of each sub-path. QPainterPath
- // does not have an "implicit close" flag like QVectorPath does.
- // We therefore have to detect closed paths by looking for a LineTo
- // element that connects back to the initial MoveTo element.
- qreal startx = 0.0;
- qreal starty = 0.0;
- qreal endx = 0.0;
- qreal endy = 0.0;
- bool haveStart = false;
- bool haveEnd = false;
-
- if (simpleTransform) {
- // Convert the members of the element array.
- for (int i = 0; i < count; ++i) {
- switch (elements[i].type) {
-
- case QPainterPath::MoveToElement:
- {
- if (haveStart && haveEnd && startx == endx && starty == endy) {
- // Implicitly close the previous sub-path.
- segments.append(VG_CLOSE_PATH);
- }
- startx = elements[i].x;
- starty = elements[i].y;
- coords.append(startx);
- coords.append(starty);
- haveStart = true;
- haveEnd = false;
- segments.append(VG_MOVE_TO_ABS);
- }
- break;
-
- case QPainterPath::LineToElement:
- {
- endx = elements[i].x;
- endy = elements[i].y;
- coords.append(endx);
- coords.append(endy);
- haveEnd = true;
- segments.append(VG_LINE_TO_ABS);
- }
- break;
-
- case QPainterPath::CurveToElement:
- {
- coords.append(elements[i].x);
- coords.append(elements[i].y);
- haveEnd = false;
- curvePos = 2;
- }
- break;
-
- case QPainterPath::CurveToDataElement:
- {
- coords.append(elements[i].x);
- coords.append(elements[i].y);
- haveEnd = false;
- curvePos += 2;
- if (curvePos == 6) {
- curvePos = 0;
- segments.append(VG_CUBIC_TO_ABS);
- }
- }
- break;
-
- }
- }
- } else {
- // Convert the members of the element array after applying the
- // current transform to the path locally.
- for (int i = 0; i < count; ++i) {
- switch (elements[i].type) {
-
- case QPainterPath::MoveToElement:
- {
- if (haveStart && haveEnd && startx == endx && starty == endy) {
- // Implicitly close the previous sub-path.
- segments.append(VG_CLOSE_PATH);
- }
- temp = transform.map(QPointF(elements[i].x, elements[i].y));
- startx = temp.x();
- starty = temp.y();
- coords.append(startx);
- coords.append(starty);
- haveStart = true;
- haveEnd = false;
- segments.append(VG_MOVE_TO_ABS);
- }
- break;
-
- case QPainterPath::LineToElement:
- {
- temp = transform.map(QPointF(elements[i].x, elements[i].y));
- endx = temp.x();
- endy = temp.y();
- coords.append(endx);
- coords.append(endy);
- haveEnd = true;
- segments.append(VG_LINE_TO_ABS);
- }
- break;
-
- case QPainterPath::CurveToElement:
- {
- temp = transform.map(QPointF(elements[i].x, elements[i].y));
- coords.append(temp.x());
- coords.append(temp.y());
- haveEnd = false;
- curvePos = 2;
- }
- break;
-
- case QPainterPath::CurveToDataElement:
- {
- temp = transform.map(QPointF(elements[i].x, elements[i].y));
- coords.append(temp.x());
- coords.append(temp.y());
- haveEnd = false;
- curvePos += 2;
- if (curvePos == 6) {
- curvePos = 0;
- segments.append(VG_CUBIC_TO_ABS);
- }
- }
- break;
-
- }
- }
- }
-
- if (haveStart && haveEnd && startx == endx && starty == endy) {
- // Implicitly close the last sub-path.
- segments.append(VG_CLOSE_PATH);
- }
-
- vgAppendPathData(vgpath, segments.count(),
- segments.constData(), coords.constData());
-
- return vgpath;
-}
-
-VGPath QVGPaintEnginePrivate::roundedRectPath(const QRectF &rect, qreal xRadius, qreal yRadius, Qt::SizeMode mode)
-{
- static VGubyte roundedrect_types[] = {
- VG_MOVE_TO_ABS,
- VG_LINE_TO_ABS,
- VG_CUBIC_TO_ABS,
- VG_LINE_TO_ABS,
- VG_CUBIC_TO_ABS,
- VG_LINE_TO_ABS,
- VG_CUBIC_TO_ABS,
- VG_LINE_TO_ABS,
- VG_CUBIC_TO_ABS,
- VG_CLOSE_PATH
- };
-
- qreal x1 = rect.left();
- qreal x2 = rect.right();
- qreal y1 = rect.top();
- qreal y2 = rect.bottom();
-
- if (mode == Qt::RelativeSize) {
- xRadius = xRadius * rect.width() / 200.;
- yRadius = yRadius * rect.height() / 200.;
- }
-
- xRadius = qMin(xRadius, rect.width() / 2);
- yRadius = qMin(yRadius, rect.height() / 2);
-
- VGfloat pts[] = {
- x1 + xRadius, y1, // MoveTo
- x2 - xRadius, y1, // LineTo
- x2 - (1 - KAPPA) * xRadius, y1, // CurveTo
- x2, y1 + (1 - KAPPA) * yRadius,
- x2, y1 + yRadius,
- x2, y2 - yRadius, // LineTo
- x2, y2 - (1 - KAPPA) * yRadius, // CurveTo
- x2 - (1 - KAPPA) * xRadius, y2,
- x2 - xRadius, y2,
- x1 + xRadius, y2, // LineTo
- x1 + (1 - KAPPA) * xRadius, y2, // CurveTo
- x1, y2 - (1 - KAPPA) * yRadius,
- x1, y2 - yRadius,
- x1, y1 + yRadius, // LineTo
- x1, y1 + (1 - KAPPA) * yRadius, // CurveTo
- x1 + (1 - KAPPA) * xRadius, y1,
- x1 + xRadius, y1
- };
-
-#if !defined(QVG_NO_MODIFY_PATH)
- VGPath vgpath = roundRectPath;
- if (!vgpath) {
- vgpath = vgCreatePath(VG_PATH_FORMAT_STANDARD,
- VG_PATH_DATATYPE_F,
- 1.0f, // scale
- 0.0f, // bias
- 10, // segmentCapacityHint
- 17 * 2, // coordCapacityHint
- VG_PATH_CAPABILITY_ALL);
- vgAppendPathData(vgpath, 10, roundedrect_types, pts);
- roundRectPath = vgpath;
- } else {
- vgModifyPathCoords(vgpath, 0, 9, pts);
- }
-#else
- VGPath vgpath = vgCreatePath(VG_PATH_FORMAT_STANDARD,
- VG_PATH_DATATYPE_F,
- 1.0f, // scale
- 0.0f, // bias
- 10, // segmentCapacityHint
- 17 * 2, // coordCapacityHint
- VG_PATH_CAPABILITY_ALL);
- vgAppendPathData(vgpath, 10, roundedrect_types, pts);
-#endif
-
- return vgpath;
-}
-
-Q_GUI_EXPORT QImage qt_imageForBrush(int style, bool invert);
-
-static QImage colorizeBitmap(const QImage &image, const QColor &color)
-{
- QImage sourceImage = image.convertToFormat(QImage::Format_MonoLSB);
- QImage dest = QImage(sourceImage.size(), QImage::Format_ARGB32_Premultiplied);
-
- QRgb fg = PREMUL(color.rgba());
- QRgb bg = 0;
-
- int height = sourceImage.height();
- int width = sourceImage.width();
- for (int y=0; y<height; ++y) {
- const uchar *source = sourceImage.constScanLine(y);
- QRgb *target = reinterpret_cast<QRgb *>(dest.scanLine(y));
- for (int x=0; x < width; ++x)
- target[x] = (source[x>>3] >> (x&7)) & 1 ? fg : bg;
- }
- return dest;
-}
-
-static VGImage toVGImage
- (const QImage & image, Qt::ImageConversionFlags flags = Qt::AutoColor)
-{
- QImage img(image);
-
- VGImageFormat format;
- switch (img.format()) {
- case QImage::Format_Mono:
- img = image.convertToFormat(QImage::Format_MonoLSB, flags);
- img.invertPixels();
- format = VG_BW_1;
- break;
- case QImage::Format_MonoLSB:
- img.invertPixels();
- format = VG_BW_1;
- break;
- case QImage::Format_RGB32:
- format = VG_sXRGB_8888;
- break;
- case QImage::Format_ARGB32:
- format = VG_sARGB_8888;
- break;
- case QImage::Format_ARGB32_Premultiplied:
- format = VG_sARGB_8888_PRE;
- break;
- case QImage::Format_RGB16:
- format = VG_sRGB_565;
- break;
- default:
- // Convert everything else into ARGB32_Premultiplied.
- img = image.convertToFormat(QImage::Format_ARGB32_Premultiplied, flags);
- format = VG_sARGB_8888_PRE;
- break;
- }
-
- const uchar *pixels = img.constBits();
-
- VGImage vgImg = QVGImagePool::instance()->createPermanentImage
- (format, img.width(), img.height(), VG_IMAGE_QUALITY_FASTER);
- vgImageSubData
- (vgImg, pixels, img.bytesPerLine(), format, 0, 0,
- img.width(), img.height());
-
- return vgImg;
-}
-
-static VGImage toVGImageSubRect
- (const QImage & image, const QRect& sr,
- Qt::ImageConversionFlags flags = Qt::AutoColor)
-{
- QImage img(image);
-
- VGImageFormat format;
- int bpp = 4;
-
- switch (img.format()) {
- case QImage::Format_Mono:
- case QImage::Format_MonoLSB:
- return VG_INVALID_HANDLE;
- case QImage::Format_RGB32:
- format = VG_sXRGB_8888;
- break;
- case QImage::Format_ARGB32:
- format = VG_sARGB_8888;
- break;
- case QImage::Format_ARGB32_Premultiplied:
- format = VG_sARGB_8888_PRE;
- break;
- case QImage::Format_RGB16:
- format = VG_sRGB_565;
- bpp = 2;
- break;
- default:
- // Convert everything else into ARGB32_Premultiplied.
- img = image.convertToFormat(QImage::Format_ARGB32_Premultiplied, flags);
- format = VG_sARGB_8888_PRE;
- break;
- }
-
- const uchar *pixels = img.constBits() + bpp * sr.x() +
- img.bytesPerLine() * sr.y();
-
- VGImage vgImg = QVGImagePool::instance()->createPermanentImage
- (format, sr.width(), sr.height(), VG_IMAGE_QUALITY_FASTER);
- vgImageSubData
- (vgImg, pixels, img.bytesPerLine(), format, 0, 0,
- sr.width(), sr.height());
-
- return vgImg;
-}
-
-static VGImage toVGImageWithOpacity(const QImage & image, qreal opacity)
-{
- QImage img(image.size(), QImage::Format_ARGB32_Premultiplied);
- img.fill(0);
- QPainter painter;
- painter.begin(&img);
- painter.setOpacity(opacity);
- painter.drawImage(0, 0, image);
- painter.end();
-
- const uchar *pixels = img.constBits();
-
- VGImage vgImg = QVGImagePool::instance()->createPermanentImage
- (VG_sARGB_8888_PRE, img.width(), img.height(), VG_IMAGE_QUALITY_FASTER);
- vgImageSubData
- (vgImg, pixels, img.bytesPerLine(), VG_sARGB_8888_PRE, 0, 0,
- img.width(), img.height());
-
- return vgImg;
-}
-
-static VGImage toVGImageWithOpacitySubRect
- (const QImage & image, qreal opacity, const QRect& sr)
-{
- QImage img(sr.size(), QImage::Format_ARGB32_Premultiplied);
- img.fill(0);
- QPainter painter;
- painter.begin(&img);
- painter.setOpacity(opacity);
- painter.drawImage(QPoint(0, 0), image, sr);
- painter.end();
-
- const uchar *pixels = img.constBits();
-
- VGImage vgImg = QVGImagePool::instance()->createPermanentImage
- (VG_sARGB_8888_PRE, img.width(), img.height(), VG_IMAGE_QUALITY_FASTER);
- vgImageSubData
- (vgImg, pixels, img.bytesPerLine(), VG_sARGB_8888_PRE, 0, 0,
- img.width(), img.height());
-
- return vgImg;
-}
-
-VGPaintType QVGPaintEnginePrivate::setBrush
- (VGPaint paint, const QBrush& brush, VGMatrixMode mode,
- VGPaintType prevType)
-{
- VGfloat values[5];
- setBrushTransform(brush, mode);
-
- // Reset the paint pattern on the brush, which will discard
- // the previous VGImage if one was set.
- if (prevType == VG_PAINT_TYPE_PATTERN || prevType == (VGPaintType)0)
- vgPaintPattern(paint, VG_INVALID_HANDLE);
-
- switch (brush.style()) {
-
- case Qt::SolidPattern: {
- // The brush is a solid color.
- QColor color(brush.color());
- values[0] = color.redF();
- values[1] = color.greenF();
- values[2] = color.blueF();
- values[3] = color.alphaF() * opacity;
- if (prevType != VG_PAINT_TYPE_COLOR)
- vgSetParameteri(paint, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR);
- vgSetParameterfv(paint, VG_PAINT_COLOR, 4, values);
- return VG_PAINT_TYPE_COLOR;
- }
-
- case Qt::LinearGradientPattern: {
- // The brush is a linear gradient.
- Q_ASSERT(brush.gradient()->type() == QGradient::LinearGradient);
- const QLinearGradient *grad =
- static_cast<const QLinearGradient*>(brush.gradient());
- values[0] = grad->start().x();
- values[1] = grad->start().y();
- values[2] = grad->finalStop().x();
- values[3] = grad->finalStop().y();
- if (prevType != VG_PAINT_TYPE_LINEAR_GRADIENT)
- vgSetParameteri(paint, VG_PAINT_TYPE, VG_PAINT_TYPE_LINEAR_GRADIENT);
- vgSetParameterfv(paint, VG_PAINT_LINEAR_GRADIENT, 4, values);
- setupColorRamp(grad, paint);
- return VG_PAINT_TYPE_LINEAR_GRADIENT;
- }
-
- case Qt::RadialGradientPattern: {
- // The brush is a radial gradient.
- Q_ASSERT(brush.gradient()->type() == QGradient::RadialGradient);
- const QRadialGradient *grad =
- static_cast<const QRadialGradient*>(brush.gradient());
- values[0] = grad->center().x();
- values[1] = grad->center().y();
- values[2] = grad->focalPoint().x();
- values[3] = grad->focalPoint().y();
- values[4] = grad->radius();
- if (prevType != VG_PAINT_TYPE_RADIAL_GRADIENT)
- vgSetParameteri(paint, VG_PAINT_TYPE, VG_PAINT_TYPE_RADIAL_GRADIENT);
- vgSetParameterfv(paint, VG_PAINT_RADIAL_GRADIENT, 5, values);
- setupColorRamp(grad, paint);
- return VG_PAINT_TYPE_RADIAL_GRADIENT;
- }
-
- case Qt::TexturePattern: {
- // The brush is a texture specified by a QPixmap/QImage.
- QPixmapData *pd = brush.texture().pixmapData();
- if (!pd)
- break; // null QPixmap
- VGImage vgImg;
- bool deref = false;
- if (pd->pixelType() == QPixmapData::BitmapType) {
- // Colorize bitmaps using the brush color and opacity.
- QColor color = brush.color();
- if (opacity != 1.0)
- color.setAlphaF(color.alphaF() * opacity);
- QImage image = colorizeBitmap(*(pd->buffer()), color);
- vgImg = toVGImage(image);
- deref = true;
- } else if (opacity == 1.0) {
- if (pd->classId() == QPixmapData::OpenVGClass) {
- QVGPixmapData *vgpd = static_cast<QVGPixmapData *>(pd);
- vgImg = vgpd->toVGImage();
-
- // We don't want the pool to reclaim this image
- // because we cannot predict when the paint object
- // will stop using it. Replacing the image with
- // new data will make the paint object invalid.
- vgpd->detachImageFromPool();
- } else {
- vgImg = toVGImage(*(pd->buffer()));
- deref = true;
- }
- } else if (pd->classId() == QPixmapData::OpenVGClass) {
- QVGPixmapData *vgpd = static_cast<QVGPixmapData *>(pd);
- vgImg = vgpd->toVGImage(opacity);
- vgpd->detachImageFromPool();
- } else {
- vgImg = toVGImageWithOpacity(*(pd->buffer()), opacity);
- deref = true;
- }
- if (vgImg == VG_INVALID_HANDLE)
- break;
- if (prevType != VG_PAINT_TYPE_PATTERN)
- vgSetParameteri(paint, VG_PAINT_TYPE, VG_PAINT_TYPE_PATTERN);
- vgSetParameteri(paint, VG_PAINT_PATTERN_TILING_MODE, VG_TILE_REPEAT);
- vgPaintPattern(paint, vgImg);
- if (deref)
- vgDestroyImage(vgImg); // Will be valid until pattern is destroyed.
- return VG_PAINT_TYPE_PATTERN;
- }
-
- case Qt::ConicalGradientPattern: {
- // Convert conical gradients into the first stop color.
- qWarning() << "QVGPaintEnginePrivate::setBrush: conical gradients are not supported by OpenVG";
- Q_ASSERT(brush.gradient()->type() == QGradient::ConicalGradient);
- const QConicalGradient *grad =
- static_cast<const QConicalGradient*>(brush.gradient());
- const QGradientStops stops = grad->stops();
- QColor color;
- if (stops.size() > 0)
- color = stops[0].second;
- values[0] = color.redF();
- values[1] = color.greenF();
- values[2] = color.blueF();
- values[3] = color.alphaF() * opacity;
- if (prevType != VG_PAINT_TYPE_COLOR)
- vgSetParameteri(paint, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR);
- vgSetParameterfv(paint, VG_PAINT_COLOR, 4, values);
- return VG_PAINT_TYPE_COLOR;
- }
-
- case Qt::Dense1Pattern:
- case Qt::Dense2Pattern:
- case Qt::Dense3Pattern:
- case Qt::Dense4Pattern:
- case Qt::Dense5Pattern:
- case Qt::Dense6Pattern:
- case Qt::Dense7Pattern:
- case Qt::HorPattern:
- case Qt::VerPattern:
- case Qt::CrossPattern:
- case Qt::BDiagPattern:
- case Qt::FDiagPattern:
- case Qt::DiagCrossPattern: {
- // The brush is a traditional dotted or cross-hatched pattern brush.
- QColor color = brush.color();
- if (opacity != 1.0)
- color.setAlphaF(color.alphaF() * opacity);
- QImage image = colorizeBitmap
- (qt_imageForBrush(brush.style(), true), color);
- VGImage vgImg = toVGImage(image);
- if (prevType != VG_PAINT_TYPE_PATTERN)
- vgSetParameteri(paint, VG_PAINT_TYPE, VG_PAINT_TYPE_PATTERN);
- vgSetParameteri(paint, VG_PAINT_PATTERN_TILING_MODE, VG_TILE_REPEAT);
- vgPaintPattern(paint, vgImg);
- vgDestroyImage(vgImg); // Will stay valid until pattern is destroyed.
- return VG_PAINT_TYPE_PATTERN;
- }
-
- default: break;
- }
- return (VGPaintType)0;
-}
-
-void QVGPaintEnginePrivate::setPenParams(const QPen& pen)
-{
- // Note: OpenVG does not support zero-width or cosmetic pens,
- // so we have to simulate cosmetic pens by reversing the scale.
- VGfloat width = pen.widthF();
- if (width <= 0.0f)
- width = 1.0f;
- if (pen.isCosmetic()) {
- if (penScale != 1.0 && penScale != 0.0)
- width /= penScale;
- }
- vgSetf(VG_STROKE_LINE_WIDTH, width);
-
- if (pen.capStyle() == Qt::FlatCap)
- vgSetf(VG_STROKE_CAP_STYLE, VG_CAP_BUTT);
- else if (pen.capStyle() == Qt::SquareCap)
- vgSetf(VG_STROKE_CAP_STYLE, VG_CAP_SQUARE);
- else
- vgSetf(VG_STROKE_CAP_STYLE, VG_CAP_ROUND);
-
- if (pen.joinStyle() == Qt::MiterJoin) {
- vgSetf(VG_STROKE_JOIN_STYLE, VG_JOIN_MITER);
- vgSetf(VG_STROKE_MITER_LIMIT, pen.miterLimit());
- } else if (pen.joinStyle() == Qt::BevelJoin) {
- vgSetf(VG_STROKE_JOIN_STYLE, VG_JOIN_BEVEL);
- } else {
- vgSetf(VG_STROKE_JOIN_STYLE, VG_JOIN_ROUND);
- }
-
- if (pen.style() == Qt::SolidLine) {
- vgSetfv(VG_STROKE_DASH_PATTERN, 0, NULL);
- } else {
- const QVector<qreal> dashPattern = pen.dashPattern();
- QVector<VGfloat> currentDashPattern(dashPattern.count());
- for (int i = 0; i < dashPattern.count(); ++i)
- currentDashPattern[i] = dashPattern[i] * width;
- vgSetfv(VG_STROKE_DASH_PATTERN, currentDashPattern.count(), currentDashPattern.data());
- vgSetf(VG_STROKE_DASH_PHASE, pen.dashOffset());
- vgSetf(VG_STROKE_DASH_PHASE_RESET, VG_FALSE);
- }
-}
-
-void QVGPaintEnginePrivate::setBrushTransform
- (const QBrush& brush, VGMatrixMode mode)
-{
- // Compute the new brush transformation matrix.
- QTransform transform(brush.transform());
- if (brushOrigin.x() != 0.0f || brushOrigin.y() != 0.0f)
- transform.translate(brushOrigin.x(), brushOrigin.y());
-
- // Bail out if the matrix is the same as last time, to avoid
- // updating the VG context state unless absolutely necessary.
- // Most applications won't have a brush transformation set,
- // which will leave the VG setting at its default of identity.
- // Always change the transform if coming out of raw VG mode.
- if (mode == VG_MATRIX_FILL_PAINT_TO_USER) {
- if (!rawVG && transform == brushTransform)
- return;
- brushTransform = transform;
- } else {
- if (!rawVG && transform == penTransform)
- return;
- penTransform = transform;
- }
-
- // Set the brush transformation matrix.
- if (mode != matrixMode) {
- vgSeti(VG_MATRIX_MODE, mode);
- matrixMode = mode;
- }
- if (transform.isIdentity()) {
- vgLoadIdentity();
- } else {
- VGfloat mat[9];
- mat[0] = transform.m11();
- mat[1] = transform.m12();
- mat[2] = transform.m13();
- mat[3] = transform.m21();
- mat[4] = transform.m22();
- mat[5] = transform.m23();
- mat[6] = transform.m31();
- mat[7] = transform.m32();
- mat[8] = transform.m33();
- vgLoadMatrix(mat);
- }
-}
-
-void QVGPaintEnginePrivate::setupColorRamp(const QGradient *grad, VGPaint paint)
-{
- QGradient::Spread spread = grad->spread();
- VGColorRampSpreadMode spreadMode;
- if (spread == QGradient::ReflectSpread)
- spreadMode = VG_COLOR_RAMP_SPREAD_REFLECT;
- else if (spread == QGradient::RepeatSpread)
- spreadMode = VG_COLOR_RAMP_SPREAD_REPEAT;
- else
- spreadMode = VG_COLOR_RAMP_SPREAD_PAD;
-
- const QGradientStops stops = grad->stops();
- int n = 5*stops.size();
- QVector<VGfloat> fill_stops(n);
-
- for (int i = 0; i < stops.size(); ++i ) {
- QColor col = stops[i].second;
- fill_stops[i*5] = stops[i].first;
- fill_stops[i*5 + 1] = col.redF();
- fill_stops[i*5 + 2] = col.greenF();
- fill_stops[i*5 + 3] = col.blueF();
- fill_stops[i*5 + 4] = col.alphaF() * opacity;
- }
-
- vgSetParameteri(paint, VG_PAINT_COLOR_RAMP_SPREAD_MODE, spreadMode);
- vgSetParameteri(paint, VG_PAINT_COLOR_RAMP_PREMULTIPLIED, VG_FALSE);
- vgSetParameterfv(paint, VG_PAINT_COLOR_RAMP_STOPS, n, fill_stops.data());
-}
-
-QVGPainterState::QVGPainterState(QVGPainterState& other)
- : QPainterState(other),
- isNew(true), clipRegion(other.clipRegion),
- savedDirty(0)
-{
-}
-
-QVGPainterState::QVGPainterState()
- : isNew(true), savedDirty(0)
-{
-}
-
-QVGPainterState::~QVGPainterState()
-{
-}
-
-QVGPaintEngine::QVGPaintEngine()
- : QPaintEngineEx(*new QVGPaintEnginePrivate(this))
-{
-}
-
-QVGPaintEngine::QVGPaintEngine(QVGPaintEnginePrivate &data)
- : QPaintEngineEx(data)
-{
-}
-
-QVGPaintEngine::~QVGPaintEngine()
-{
-}
-
-QPainterState *QVGPaintEngine::createState(QPainterState *orig) const
-{
- if (!orig) {
- return new QVGPainterState();
- } else {
- Q_D(const QVGPaintEngine);
- QVGPaintEnginePrivate *d2 = const_cast<QVGPaintEnginePrivate*>(d);
- QVGPainterState *origState = static_cast<QVGPainterState *>(orig);
- origState->savedDirty = d2->dirty;
- d2->dirty = 0;
- return new QVGPainterState(*origState);
- }
-}
-
-void QVGPaintEnginePrivate::draw
- (VGPath path, const QPen& pen, const QBrush& brush, VGint rule)
-{
- VGbitfield mode = 0;
- if (qpen_style(pen) != Qt::NoPen && qbrush_style(qpen_brush(pen)) != Qt::NoBrush) {
- ensurePen(pen);
- mode |= VG_STROKE_PATH;
- }
- if (brush.style() != Qt::NoBrush) {
- ensureBrush(brush);
- setFillRule(rule);
- mode |= VG_FILL_PATH;
- }
- if (mode != 0) {
- ensurePathTransform();
- vgDrawPath(path, mode);
- }
-}
-
-void QVGPaintEnginePrivate::stroke(VGPath path, const QPen& pen)
-{
- if (pen.style() == Qt::NoPen)
- return;
- ensurePen(pen);
- ensurePathTransform();
- vgDrawPath(path, VG_STROKE_PATH);
-}
-
-void QVGPaintEnginePrivate::fill(VGPath path, const QBrush& brush, VGint rule)
-{
- if (brush.style() == Qt::NoBrush)
- return;
- ensureBrush(brush);
- setFillRule(rule);
- QPen savedPen = currentPen;
- currentPen = Qt::NoPen;
- ensurePathTransform();
- currentPen = savedPen;
- vgDrawPath(path, VG_FILL_PATH);
-}
-
-bool QVGPaintEngine::begin(QPaintDevice *pdev)
-{
- Q_UNUSED(pdev);
- Q_D(QVGPaintEngine);
-
- // Initialize the VG painting objects if we haven't done it yet.
- if (!d->penPaint)
- d->initObjects();
-
- // The initial clip region is the entire device area.
- QVGPainterState *s = state();
- s->clipRegion = defaultClipRegion();
-
- // Initialize the VG state for this paint operation.
- restoreState(QPaintEngine::AllDirty);
- d->dirty = 0;
- d->rawVG = false;
- return true;
-}
-
-bool QVGPaintEngine::end()
-{
- vgSeti(VG_SCISSORING, VG_FALSE);
- vgSeti(VG_MASKING, VG_FALSE);
- return true;
-}
-
-void QVGPaintEngine::draw(const QVectorPath &path)
-{
- Q_D(QVGPaintEngine);
- if (d->needsEmulation()) {
- QPaintEngineEx::draw(path);
- return;
- }
- QVGPainterState *s = state();
- VGPath vgpath = d->vectorPathToVGPath(path);
- if (!path.hasWindingFill())
- d->draw(vgpath, s->pen, s->brush, VG_EVEN_ODD);
- else
- d->draw(vgpath, s->pen, s->brush, VG_NON_ZERO);
- vgDestroyPath(vgpath);
-}
-
-extern QPainterPath qt_painterPathFromVectorPath(const QVectorPath &path);
-
-void QVGPaintEngine::fill(const QVectorPath &path, const QBrush &brush)
-{
- Q_D(QVGPaintEngine);
- if (d->needsEmulation(brush)) {
- QPainter *p = painter();
- QBrush oldBrush = p->brush();
- p->setBrush(brush);
- qt_draw_helper(p->d_ptr.data(), qt_painterPathFromVectorPath(path), QPainterPrivate::FillDraw);
- p->setBrush(oldBrush);
- return;
- }
- VGPath vgpath = d->vectorPathToVGPath(path);
- if (!path.hasWindingFill())
- d->fill(vgpath, brush, VG_EVEN_ODD);
- else
- d->fill(vgpath, brush, VG_NON_ZERO);
- vgDestroyPath(vgpath);
-}
-
-void QVGPaintEngine::stroke(const QVectorPath &path, const QPen &pen)
-{
- Q_D(QVGPaintEngine);
- if (d->needsEmulation(pen.brush())) {
- QPaintEngineEx::stroke(path, pen);
- return;
- }
- VGPath vgpath = d->vectorPathToVGPath(path);
- d->stroke(vgpath, pen);
- vgDestroyPath(vgpath);
-}
-
-// Determine if a co-ordinate transform is simple enough to allow
-// rectangle-based clipping with vgMask(). Simple transforms most
-// often result from origin translations.
-static inline bool clipTransformIsSimple(const QTransform& transform)
-{
- QTransform::TransformationType type = transform.type();
- if (type == QTransform::TxNone || type == QTransform::TxTranslate)
- return true;
- if (type == QTransform::TxRotate) {
- // Check for 0, 90, 180, and 270 degree rotations.
- // (0 might happen after 4 rotations of 90 degrees).
- qreal m11 = transform.m11();
- qreal m12 = transform.m12();
- qreal m21 = transform.m21();
- qreal m22 = transform.m22();
- if (m11 == 0.0f && m22 == 0.0f) {
- if (m12 == 1.0f && m21 == -1.0f)
- return true; // 90 degrees.
- else if (m12 == -1.0f && m21 == 1.0f)
- return true; // 270 degrees.
- } else if (m12 == 0.0f && m21 == 0.0f) {
- if (m11 == -1.0f && m22 == -1.0f)
- return true; // 180 degrees.
- else if (m11 == 1.0f && m22 == 1.0f)
- return true; // 0 degrees.
- }
- }
- return false;
-}
-
-#if defined(QVG_SCISSOR_CLIP)
-
-void QVGPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op)
-{
- Q_D(QVGPaintEngine);
- QVGPainterState *s = state();
-
- d->dirty |= QPaintEngine::DirtyClipRegion;
-
- if (op == Qt::NoClip) {
- s->clipRegion = defaultClipRegion();
- updateScissor();
- return;
- }
-
- // We aren't using masking, so handle simple QRectF's only.
- if (path.shape() == QVectorPath::RectangleHint &&
- path.elementCount() == 4 && clipTransformIsSimple(d->transform)) {
- // Clipping region that resulted from QPainter::setClipRect(QRectF).
- // Convert it into a QRect and apply.
- const qreal *points = path.points();
- QRectF rect(points[0], points[1], points[2] - points[0],
- points[5] - points[1]);
- clip(rect.toRect(), op);
- return;
- }
-
- // Try converting the path into a QRegion that tightly follows
- // the outline of the path we want to clip with.
- QRegion region;
- if (!path.isEmpty())
- region = QRegion(path.convertToPainterPath().toFillPolygon(QTransform()).toPolygon());
-
- switch (op) {
- case Qt::NoClip:
- {
- region = defaultClipRegion();
- }
- break;
-
- case Qt::ReplaceClip:
- {
- region = d->transform.map(region);
- }
- break;
-
- case Qt::IntersectClip:
- {
- region = s->clipRegion.intersect(d->transform.map(region));
- }
- break;
- }
- if (region.numRects() <= d->maxScissorRects) {
- // We haven't reached the maximum scissor count yet, so we can
- // still make use of this region.
- s->clipRegion = region;
- updateScissor();
- return;
- }
-
- // The best we can do is clip to the bounding rectangle
- // of all control points.
- clip(path.controlPointRect().toRect(), op);
-}
-
-void QVGPaintEngine::clip(const QRect &rect, Qt::ClipOperation op)
-{
- Q_D(QVGPaintEngine);
- QVGPainterState *s = state();
-
- d->dirty |= QPaintEngine::DirtyClipRegion;
-
- switch (op) {
- case Qt::NoClip:
- {
- s->clipRegion = defaultClipRegion();
- }
- break;
-
- case Qt::ReplaceClip:
- {
- s->clipRegion = d->transform.map(QRegion(rect));
- }
- break;
-
- case Qt::IntersectClip:
- {
- s->clipRegion = s->clipRegion.intersect(d->transform.map(QRegion(rect)));
- }
- break;
- }
-
- updateScissor();
-}
-
-void QVGPaintEngine::clip(const QRegion &region, Qt::ClipOperation op)
-{
- Q_D(QVGPaintEngine);
- QVGPainterState *s = state();
-
- d->dirty |= QPaintEngine::DirtyClipRegion;
-
- switch (op) {
- case Qt::NoClip:
- {
- s->clipRegion = defaultClipRegion();
- }
- break;
-
- case Qt::ReplaceClip:
- {
- s->clipRegion = d->transform.map(region);
- }
- break;
-
- case Qt::IntersectClip:
- {
- s->clipRegion = s->clipRegion.intersect(d->transform.map(region));
- }
- break;
- }
-
- updateScissor();
-}
-
-void QVGPaintEngine::clip(const QPainterPath &path, Qt::ClipOperation op)
-{
- QPaintEngineEx::clip(path, op);
-}
-
-#else // !QVG_SCISSOR_CLIP
-
-void QVGPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op)
-{
- Q_D(QVGPaintEngine);
-
- d->dirty |= QPaintEngine::DirtyClipRegion;
-
- if (op == Qt::NoClip) {
- d->maskValid = false;
- d->maskIsSet = true;
- d->scissorMask = false;
- d->maskRect = QRect();
- vgSeti(VG_MASKING, VG_FALSE);
- return;
- }
-
- // We don't have vgRenderToMask(), so handle simple QRectF's only.
- if (path.shape() == QVectorPath::RectangleHint &&
- path.elementCount() == 4 && clipTransformIsSimple(d->transform)) {
- // Clipping region that resulted from QPainter::setClipRect(QRectF).
- // Convert it into a QRect and apply.
- const qreal *points = path.points();
- QRectF rect(points[0], points[1], points[2] - points[0],
- points[5] - points[1]);
- clip(rect.toRect(), op);
- return;
- }
-
-#if !defined(QVG_NO_RENDER_TO_MASK)
- QPaintDevice *pdev = paintDevice();
- int width = pdev->width();
- int height = pdev->height();
-
- if (op == Qt::ReplaceClip) {
- vgMask(VG_INVALID_HANDLE, VG_CLEAR_MASK, 0, 0, width, height);
- d->maskRect = QRect();
- } else if (!d->maskValid) {
- d->ensureMask(this, width, height);
- }
-
- d->ensurePathTransform();
- VGPath vgpath = d->vectorPathToVGPath(path);
- switch (op) {
- case Qt::ReplaceClip:
- case Qt::IntersectClip:
- vgRenderToMask(vgpath, VG_FILL_PATH, VG_INTERSECT_MASK);
- break;
-
- default: break;
- }
- vgDestroyPath(vgpath);
-
- vgSeti(VG_MASKING, VG_TRUE);
- d->maskValid = true;
- d->maskIsSet = false;
- d->scissorMask = false;
-#endif
-}
-
-void QVGPaintEngine::clip(const QRect &rect, Qt::ClipOperation op)
-{
- Q_D(QVGPaintEngine);
-
- d->dirty |= QPaintEngine::DirtyClipRegion;
-
- // If we have a non-simple transform, then use path-based clipping.
- if (op != Qt::NoClip && !clipTransformIsSimple(d->transform)) {
- QPaintEngineEx::clip(rect, op);
- return;
- }
-
- switch (op) {
- case Qt::NoClip:
- {
- d->maskValid = false;
- d->maskIsSet = true;
- d->scissorMask = false;
- d->maskRect = QRect();
- vgSeti(VG_MASKING, VG_FALSE);
- }
- break;
-
- case Qt::ReplaceClip:
- {
- QRect r = d->transform.mapRect(rect);
- if (isDefaultClipRect(r)) {
- // Replacing the clip with a full-window region is the
- // same as turning off clipping.
- if (d->maskValid)
- vgSeti(VG_MASKING, VG_FALSE);
- d->maskValid = false;
- d->maskIsSet = true;
- d->scissorMask = false;
- d->maskRect = QRect();
- } else {
- // Special case: if the intersection of the system
- // clip and "r" is a single rectangle, then use the
- // scissor for clipping. We try to avoid allocating a
- // QRegion copy on the heap for the test if we can.
- QRegion clip = d->systemClip; // Reference-counted, no alloc.
- QRect clipRect;
- if (clip.rectCount() == 1) {
- clipRect = clip.boundingRect().intersected(r);
- } else if (clip.isEmpty()) {
- clipRect = r;
- } else {
- clip = clip.intersect(r);
- if (clip.rectCount() != 1) {
- d->maskValid = false;
- d->maskIsSet = false;
- d->scissorMask = false;
- d->maskRect = QRect();
- d->modifyMask(this, VG_FILL_MASK, r);
- break;
- }
- clipRect = clip.boundingRect();
- }
- d->maskValid = false;
- d->maskIsSet = false;
- d->scissorMask = true;
- d->maskRect = clipRect;
- vgSeti(VG_MASKING, VG_FALSE);
- updateScissor();
- }
- }
- break;
-
- case Qt::IntersectClip:
- {
- QRect r = d->transform.mapRect(rect);
- if (!d->maskValid) {
- // Mask has not been used yet, so intersect with
- // the previous scissor-based region in maskRect.
- if (d->scissorMask)
- r = r.intersect(d->maskRect);
- if (isDefaultClipRect(r)) {
- // The clip is the full window, so turn off clipping.
- d->maskIsSet = true;
- d->maskRect = QRect();
- } else {
- // Activate the scissor on a smaller maskRect.
- d->maskIsSet = false;
- d->maskRect = r;
- }
- d->scissorMask = true;
- updateScissor();
- } else if (d->maskIsSet && isDefaultClipRect(r)) {
- // Intersecting a full-window clip with a full-window
- // region is the same as turning off clipping.
- if (d->maskValid)
- vgSeti(VG_MASKING, VG_FALSE);
- d->maskValid = false;
- d->maskIsSet = true;
- d->scissorMask = false;
- d->maskRect = QRect();
- } else {
- d->modifyMask(this, VG_INTERSECT_MASK, r);
- }
- }
- break;
- }
-}
-
-void QVGPaintEngine::clip(const QRegion &region, Qt::ClipOperation op)
-{
- Q_D(QVGPaintEngine);
-
- // Use the QRect case if the region consists of a single rectangle.
- if (region.rectCount() == 1) {
- clip(region.boundingRect(), op);
- return;
- }
-
- d->dirty |= QPaintEngine::DirtyClipRegion;
-
- // If we have a non-simple transform, then use path-based clipping.
- if (op != Qt::NoClip && !clipTransformIsSimple(d->transform)) {
- QPaintEngineEx::clip(region, op);
- return;
- }
-
- switch (op) {
- case Qt::NoClip:
- {
- d->maskValid = false;
- d->maskIsSet = true;
- d->scissorMask = false;
- d->maskRect = QRect();
- vgSeti(VG_MASKING, VG_FALSE);
- }
- break;
-
- case Qt::ReplaceClip:
- {
- QRegion r = d->transform.map(region);
- if (isDefaultClipRegion(r)) {
- // Replacing the clip with a full-window region is the
- // same as turning off clipping.
- if (d->maskValid)
- vgSeti(VG_MASKING, VG_FALSE);
- d->maskValid = false;
- d->maskIsSet = true;
- d->scissorMask = false;
- d->maskRect = QRect();
- } else {
- // Special case: if the intersection of the system
- // clip and the region is a single rectangle, then
- // use the scissor for clipping.
- QRegion clip = d->systemClip;
- if (clip.isEmpty())
- clip = r;
- else
- clip = clip.intersect(r);
- if (clip.rectCount() == 1) {
- d->maskValid = false;
- d->maskIsSet = false;
- d->scissorMask = true;
- d->maskRect = clip.boundingRect();
- vgSeti(VG_MASKING, VG_FALSE);
- updateScissor();
- } else {
- d->maskValid = false;
- d->maskIsSet = false;
- d->scissorMask = false;
- d->maskRect = QRect();
- d->modifyMask(this, VG_FILL_MASK, r);
- }
- }
- }
- break;
-
- case Qt::IntersectClip:
- {
- if (region.rectCount() != 1) {
- // If there is more than one rectangle, then intersecting
- // the rectangles one by one in modifyMask() will not give
- // the desired result. So fall back to path-based clipping.
- QPaintEngineEx::clip(region, op);
- return;
- }
- QRegion r = d->transform.map(region);
- if (d->maskIsSet && isDefaultClipRegion(r)) {
- // Intersecting a full-window clip with a full-window
- // region is the same as turning off clipping.
- if (d->maskValid)
- vgSeti(VG_MASKING, VG_FALSE);
- d->maskValid = false;
- d->maskIsSet = true;
- d->scissorMask = false;
- d->maskRect = QRect();
- } else {
- d->modifyMask(this, VG_INTERSECT_MASK, r);
- }
- }
- break;
- }
-}
-
-#if !defined(QVG_NO_RENDER_TO_MASK)
-
-// Copied from qpathclipper.cpp.
-static bool qt_vg_pathToRect(const QPainterPath &path, QRectF *rect)
-{
- if (path.elementCount() != 5)
- return false;
-
- const bool mightBeRect = path.elementAt(0).isMoveTo()
- && path.elementAt(1).isLineTo()
- && path.elementAt(2).isLineTo()
- && path.elementAt(3).isLineTo()
- && path.elementAt(4).isLineTo();
-
- if (!mightBeRect)
- return false;
-
- const qreal x1 = path.elementAt(0).x;
- const qreal y1 = path.elementAt(0).y;
-
- const qreal x2 = path.elementAt(1).x;
- const qreal y2 = path.elementAt(2).y;
-
- if (path.elementAt(1).y != y1)
- return false;
-
- if (path.elementAt(2).x != x2)
- return false;
-
- if (path.elementAt(3).x != x1 || path.elementAt(3).y != y2)
- return false;
-
- if (path.elementAt(4).x != x1 || path.elementAt(4).y != y1)
- return false;
-
- if (rect)
- *rect = QRectF(QPointF(x1, y1), QPointF(x2, y2));
-
- return true;
-}
-
-#endif
-
-void QVGPaintEngine::clip(const QPainterPath &path, Qt::ClipOperation op)
-{
-#if !defined(QVG_NO_RENDER_TO_MASK)
- Q_D(QVGPaintEngine);
-
- // If the path is a simple rectangle, then use clip(QRect) instead.
- QRectF simpleRect;
- if (qt_vg_pathToRect(path, &simpleRect)) {
- clip(simpleRect.toRect(), op);
- return;
- }
-
- d->dirty |= QPaintEngine::DirtyClipRegion;
-
- if (op == Qt::NoClip) {
- d->maskValid = false;
- d->maskIsSet = true;
- d->scissorMask = false;
- d->maskRect = QRect();
- vgSeti(VG_MASKING, VG_FALSE);
- return;
- }
-
- QPaintDevice *pdev = paintDevice();
- int width = pdev->width();
- int height = pdev->height();
-
- if (op == Qt::ReplaceClip) {
- vgMask(VG_INVALID_HANDLE, VG_CLEAR_MASK, 0, 0, width, height);
- d->maskRect = QRect();
- } else if (!d->maskValid) {
- d->ensureMask(this, width, height);
- }
-
- d->ensurePathTransform();
- VGPath vgpath = d->painterPathToVGPath(path);
- switch (op) {
- case Qt::ReplaceClip:
- case Qt::IntersectClip:
- vgRenderToMask(vgpath, VG_FILL_PATH, VG_INTERSECT_MASK);
- break;
-
- default: break;
- }
- vgDestroyPath(vgpath);
-
- vgSeti(VG_MASKING, VG_TRUE);
- d->maskValid = true;
- d->maskIsSet = false;
- d->scissorMask = false;
-#else
- QPaintEngineEx::clip(path, op);
-#endif
-}
-
-void QVGPaintEnginePrivate::ensureMask
- (QVGPaintEngine *engine, int width, int height)
-{
- scissorMask = false;
- if (maskIsSet) {
- vgMask(VG_INVALID_HANDLE, VG_FILL_MASK, 0, 0, width, height);
- maskRect = QRect();
- } else {
- vgMask(VG_INVALID_HANDLE, VG_CLEAR_MASK, 0, 0, width, height);
- if (maskRect.isValid()) {
- vgMask(VG_INVALID_HANDLE, VG_FILL_MASK,
- maskRect.x(), height - maskRect.y() - maskRect.height(),
- maskRect.width(), maskRect.height());
- maskRect = QRect();
- engine->updateScissor();
- }
- }
-}
-
-void QVGPaintEnginePrivate::modifyMask
- (QVGPaintEngine *engine, VGMaskOperation op, const QRegion& region)
-{
- QPaintDevice *pdev = engine->paintDevice();
- int width = pdev->width();
- int height = pdev->height();
-
- if (!maskValid)
- ensureMask(engine, width, height);
-
- QVector<QRect> rects = region.rects();
- for (int i = 0; i < rects.size(); ++i) {
- vgMask(VG_INVALID_HANDLE, op,
- rects[i].x(), height - rects[i].y() - rects[i].height(),
- rects[i].width(), rects[i].height());
- }
-
- vgSeti(VG_MASKING, VG_TRUE);
- maskValid = true;
- maskIsSet = false;
- scissorMask = false;
-}
-
-void QVGPaintEnginePrivate::modifyMask
- (QVGPaintEngine *engine, VGMaskOperation op, const QRect& rect)
-{
- QPaintDevice *pdev = engine->paintDevice();
- int width = pdev->width();
- int height = pdev->height();
-
- if (!maskValid)
- ensureMask(engine, width, height);
-
- if (rect.isValid()) {
- vgMask(VG_INVALID_HANDLE, op,
- rect.x(), height - rect.y() - rect.height(),
- rect.width(), rect.height());
- }
-
- vgSeti(VG_MASKING, VG_TRUE);
- maskValid = true;
- maskIsSet = false;
- scissorMask = false;
-}
-
-#endif // !QVG_SCISSOR_CLIP
-
-void QVGPaintEngine::updateScissor()
-{
- Q_D(QVGPaintEngine);
-
- QRegion region = d->systemClip;
-
-#if defined(QVG_SCISSOR_CLIP)
- // Using the scissor to do clipping, so combine the systemClip
- // with the current painting clipRegion.
-
- if (d->maskValid) {
- vgSeti(VG_MASKING, VG_FALSE);
- d->maskValid = false;
- }
-
- QVGPainterState *s = state();
- if (s->clipEnabled) {
- if (region.isEmpty())
- region = s->clipRegion;
- else
- region = region.intersect(s->clipRegion);
- if (isDefaultClipRegion(region)) {
- // The scissor region is the entire drawing surface,
- // so there is no point doing any scissoring.
- vgSeti(VG_SCISSORING, VG_FALSE);
- d->scissorActive = false;
- d->scissorDirty = false;
- return;
- }
- } else
-#endif
- {
-#if !defined(QVG_SCISSOR_CLIP)
- // Combine the system clip with the simple mask rectangle.
- if (d->scissorMask) {
- if (region.isEmpty())
- region = d->maskRect;
- else
- region = region.intersect(d->maskRect);
- if (isDefaultClipRegion(region)) {
- // The scissor region is the entire drawing surface,
- // so there is no point doing any scissoring.
- vgSeti(VG_SCISSORING, VG_FALSE);
- d->scissorActive = false;
- d->scissorDirty = false;
- return;
- }
- } else
-#endif
-
- // Disable the scissor completely if the system clip is empty.
- if (region.isEmpty()) {
- vgSeti(VG_SCISSORING, VG_FALSE);
- d->scissorActive = false;
- d->scissorDirty = false;
- return;
- }
- }
-
- if (d->scissorActive && region == d->scissorRegion && !d->scissorDirty)
- return;
-
- QVector<QRect> rects = region.rects();
- int count = rects.count();
- if (count > d->maxScissorRects) {
-#if !defined(QVG_SCISSOR_CLIP)
- count = d->maxScissorRects;
-#else
- // Use masking
- int width = paintDevice()->width();
- int height = paintDevice()->height();
- vgMask(VG_INVALID_HANDLE, VG_CLEAR_MASK,
- 0, 0, width, height);
- for (int i = 0; i < rects.size(); ++i) {
- vgMask(VG_INVALID_HANDLE, VG_FILL_MASK,
- rects[i].x(), height - rects[i].y() - rects[i].height(),
- rects[i].width(), rects[i].height());
- }
-
- vgSeti(VG_SCISSORING, VG_FALSE);
- vgSeti(VG_MASKING, VG_TRUE);
- d->maskValid = true;
- d->maskIsSet = false;
- d->scissorMask = false;
- d->scissorActive = false;
- d->scissorDirty = false;
- d->scissorRegion = region;
- return;
-#endif
- }
-
- QVarLengthArray<VGint> params(count * 4);
- int height = paintDevice()->height();
- for (int i = 0; i < count; ++i) {
- params[i * 4 + 0] = rects[i].x();
- params[i * 4 + 1] = height - rects[i].y() - rects[i].height();
- params[i * 4 + 2] = rects[i].width();
- params[i * 4 + 3] = rects[i].height();
- }
-
- vgSetiv(VG_SCISSOR_RECTS, count * 4, params.data());
- vgSeti(VG_SCISSORING, VG_TRUE);
- d->scissorDirty = false;
- d->scissorActive = true;
- d->scissorRegion = region;
-}
-
-QRegion QVGPaintEngine::defaultClipRegion()
-{
- // The default clip region for a paint device is the whole drawing area.
- QPaintDevice *pdev = paintDevice();
- return QRegion(0, 0, pdev->width(), pdev->height());
-}
-
-bool QVGPaintEngine::isDefaultClipRegion(const QRegion& region)
-{
- if (region.rectCount() != 1)
- return false;
-
- QPaintDevice *pdev = paintDevice();
- int width = pdev->width();
- int height = pdev->height();
-
- QRect rect = region.boundingRect();
- return (rect.x() == 0 && rect.y() == 0 &&
- rect.width() == width && rect.height() == height);
-}
-
-bool QVGPaintEngine::isDefaultClipRect(const QRect& rect)
-{
- QPaintDevice *pdev = paintDevice();
- int width = pdev->width();
- int height = pdev->height();
-
- return (rect.x() == 0 && rect.y() == 0 &&
- rect.width() == width && rect.height() == height);
-}
-
-void QVGPaintEngine::clipEnabledChanged()
-{
-#if defined(QVG_SCISSOR_CLIP)
- vgSeti(VG_MASKING, VG_FALSE); // disable mask fallback
- updateScissor();
-#else
- Q_D(QVGPaintEngine);
- QVGPainterState *s = state();
- d->dirty |= QPaintEngine::DirtyClipEnabled;
- if (s->clipEnabled && s->clipOperation != Qt::NoClip) {
- // Replay the entire clip stack to put the mask into the right state.
- d->maskValid = false;
- d->maskIsSet = true;
- d->scissorMask = false;
- d->maskRect = QRect();
- s->clipRegion = defaultClipRegion();
- d->replayClipOperations();
- d->transform = s->transform();
- d->updateTransform(paintDevice());
- } else {
- vgSeti(VG_MASKING, VG_FALSE);
- d->maskValid = false;
- d->maskIsSet = false;
- d->scissorMask = false;
- d->maskRect = QRect();
- }
-#endif
-}
-
-void QVGPaintEngine::penChanged()
-{
- Q_D(QVGPaintEngine);
- d->dirty |= QPaintEngine::DirtyPen;
-
- d->hasExtendedRadialGradientPen =
- state()->pen.style() != Qt::NoPen && d->needsEmulation(state()->pen.brush());
-}
-
-void QVGPaintEngine::brushChanged()
-{
- Q_D(QVGPaintEngine);
- d->dirty |= QPaintEngine::DirtyBrush;
-
- d->hasExtendedRadialGradientPen = d->needsEmulation(state()->brush);
-}
-
-void QVGPaintEngine::brushOriginChanged()
-{
- Q_D(QVGPaintEngine);
- d->dirty |= QPaintEngine::DirtyBrushOrigin;
- d->brushOrigin = state()->brushOrigin;
- d->forcePenChange = true;
- d->forceBrushChange = true;
-}
-
-void QVGPaintEngine::opacityChanged()
-{
- Q_D(QVGPaintEngine);
- d->dirty |= QPaintEngine::DirtyOpacity;
- d->opacity = state()->opacity;
- d->forcePenChange = true;
- d->forceBrushChange = true;
-}
-
-void QVGPaintEngine::compositionModeChanged()
-{
- Q_D(QVGPaintEngine);
- d->dirty |= QPaintEngine::DirtyCompositionMode;
-
- VGint vgMode = VG_BLEND_SRC_OVER;
-
- switch (state()->composition_mode) {
- case QPainter::CompositionMode_SourceOver:
- vgMode = VG_BLEND_SRC_OVER;
- break;
- case QPainter::CompositionMode_DestinationOver:
- vgMode = VG_BLEND_DST_OVER;
- break;
- case QPainter::CompositionMode_Source:
- vgMode = VG_BLEND_SRC;
- break;
- case QPainter::CompositionMode_SourceIn:
- vgMode = VG_BLEND_SRC_IN;
- break;
- case QPainter::CompositionMode_DestinationIn:
- vgMode = VG_BLEND_DST_IN;
- break;
- case QPainter::CompositionMode_Plus:
- vgMode = VG_BLEND_ADDITIVE;
- break;
- case QPainter::CompositionMode_Multiply:
- vgMode = VG_BLEND_MULTIPLY;
- break;
- case QPainter::CompositionMode_Screen:
- vgMode = VG_BLEND_SCREEN;
- break;
- case QPainter::CompositionMode_Darken:
- vgMode = VG_BLEND_DARKEN;
- break;
- case QPainter::CompositionMode_Lighten:
- vgMode = VG_BLEND_LIGHTEN;
- break;
- default:
- if (d->hasAdvancedBlending) {
- switch (state()->composition_mode) {
- case QPainter::CompositionMode_Overlay:
- vgMode = QVGPaintEnginePrivate::QT_VG_BLEND_OVERLAY_KHR;
- break;
- case QPainter::CompositionMode_ColorDodge:
- vgMode = QVGPaintEnginePrivate::QT_VG_BLEND_COLORDODGE_KHR;
- break;
- case QPainter::CompositionMode_ColorBurn:
- vgMode = QVGPaintEnginePrivate::QT_VG_BLEND_COLORBURN_KHR;
- break;
- case QPainter::CompositionMode_HardLight:
- vgMode = QVGPaintEnginePrivate::QT_VG_BLEND_HARDLIGHT_KHR;
- break;
- case QPainter::CompositionMode_SoftLight:
- vgMode = QVGPaintEnginePrivate::QT_VG_BLEND_SOFTLIGHT_KHR;
- break;
- case QPainter::CompositionMode_Difference:
- vgMode = QVGPaintEnginePrivate::QT_VG_BLEND_DIFFERENCE_KHR;
- break;
- case QPainter::CompositionMode_Exclusion:
- vgMode = QVGPaintEnginePrivate::QT_VG_BLEND_EXCLUSION_KHR;
- break;
- case QPainter::CompositionMode_SourceOut:
- vgMode = QVGPaintEnginePrivate::QT_VG_BLEND_SRC_OUT_KHR;
- break;
- case QPainter::CompositionMode_DestinationOut:
- vgMode = QVGPaintEnginePrivate::QT_VG_BLEND_DST_OUT_KHR;
- break;
- case QPainter::CompositionMode_SourceAtop:
- vgMode = QVGPaintEnginePrivate::QT_VG_BLEND_SRC_ATOP_KHR;
- break;
- case QPainter::CompositionMode_DestinationAtop:
- vgMode = QVGPaintEnginePrivate::QT_VG_BLEND_DST_ATOP_KHR;
- break;
- case QPainter::CompositionMode_Xor:
- vgMode = QVGPaintEnginePrivate::QT_VG_BLEND_XOR_KHR;
- break;
- default: break; // Fall back to VG_BLEND_SRC_OVER.
- }
- }
- if (vgMode == VG_BLEND_SRC_OVER)
- qWarning() << "QVGPaintEngine::compositionModeChanged unsupported mode" << state()->composition_mode;
- break;
- }
-
- d->setBlendMode(VGBlendMode(vgMode));
-}
-
-void QVGPaintEngine::renderHintsChanged()
-{
- Q_D(QVGPaintEngine);
- d->dirty |= QPaintEngine::DirtyHints;
-
- QPainter::RenderHints hints = state()->renderHints;
-
- VGRenderingQuality rq =
- (hints & QPainter::Antialiasing)
- ? VG_RENDERING_QUALITY_BETTER
- : VG_RENDERING_QUALITY_NONANTIALIASED;
- VGImageQuality iq =
- (hints & QPainter::SmoothPixmapTransform)
- ? VG_IMAGE_QUALITY_BETTER
- : VG_IMAGE_QUALITY_NONANTIALIASED;
-
- d->setRenderingQuality(rq);
- d->setImageQuality(iq);
-}
-
-void QVGPaintEngine::transformChanged()
-{
- Q_D(QVGPaintEngine);
- QVGPainterState *s = state();
- d->dirty |= QPaintEngine::DirtyTransform;
- d->transform = s->transform();
- qreal oldPenScale = d->penScale;
- d->updateTransform(paintDevice());
- if (d->penScale != oldPenScale)
- d->forcePenChange = true;
-}
-
-bool QVGPaintEngine::clearRect(const QRectF &rect, const QColor &color)
-{
- Q_D(QVGPaintEngine);
- QVGPainterState *s = state();
- if (!s->clipEnabled || s->clipOperation == Qt::NoClip) {
- QRect r = d->transform.mapRect(rect).toRect();
- int height = paintDevice()->height();
- if (d->clearColor != color || d->clearOpacity != s->opacity) {
- VGfloat values[4];
- values[0] = color.redF();
- values[1] = color.greenF();
- values[2] = color.blueF();
- values[3] = color.alphaF() * s->opacity;
- vgSetfv(VG_CLEAR_COLOR, 4, values);
- d->clearColor = color;
- d->clearOpacity = s->opacity;
- }
- vgClear(r.x(), height - r.y() - r.height(),
- r.width(), r.height());
- return true;
- }
- return false;
-}
-
-void QVGPaintEngine::fillRect(const QRectF &rect, const QBrush &brush)
-{
- Q_D(QVGPaintEngine);
-
- if (brush.style() == Qt::NoBrush)
- return;
-
- // Check to see if we can use vgClear() for faster filling.
- if (brush.style() == Qt::SolidPattern && brush.isOpaque() &&
- clipTransformIsSimple(d->transform) && d->opacity == 1.0f &&
- clearRect(rect, brush.color())) {
- return;
- }
-
- if (d->needsEmulation(brush)) {
- QPaintEngineEx::fillRect(rect, brush);
- return;
- }
-
-#if !defined(QVG_NO_MODIFY_PATH)
- VGfloat coords[8];
- if (d->simpleTransform) {
- coords[0] = rect.x();
- coords[1] = rect.y();
- coords[2] = rect.x() + rect.width();
- coords[3] = coords[1];
- coords[4] = coords[2];
- coords[5] = rect.y() + rect.height();
- coords[6] = coords[0];
- coords[7] = coords[5];
- } else {
- QPointF tl = d->transform.map(rect.topLeft());
- QPointF tr = d->transform.map(rect.topRight());
- QPointF bl = d->transform.map(rect.bottomLeft());
- QPointF br = d->transform.map(rect.bottomRight());
- coords[0] = tl.x();
- coords[1] = tl.y();
- coords[2] = tr.x();
- coords[3] = tr.y();
- coords[4] = br.x();
- coords[5] = br.y();
- coords[6] = bl.x();
- coords[7] = bl.y();
- }
- vgModifyPathCoords(d->rectPath, 0, 4, coords);
- d->fill(d->rectPath, brush);
-#else
- QPaintEngineEx::fillRect(rect, brush);
-#endif
-}
-
-void QVGPaintEngine::fillRect(const QRectF &rect, const QColor &color)
-{
- Q_D(QVGPaintEngine);
-
- // Check to see if we can use vgClear() for faster filling.
- if (clipTransformIsSimple(d->transform) && d->opacity == 1.0f && color.alpha() == 255 &&
- clearRect(rect, color)) {
- return;
- }
-
-#if !defined(QVG_NO_MODIFY_PATH)
- VGfloat coords[8];
- if (d->simpleTransform) {
- coords[0] = rect.x();
- coords[1] = rect.y();
- coords[2] = rect.x() + rect.width();
- coords[3] = coords[1];
- coords[4] = coords[2];
- coords[5] = rect.y() + rect.height();
- coords[6] = coords[0];
- coords[7] = coords[5];
- } else {
- QPointF tl = d->transform.map(rect.topLeft());
- QPointF tr = d->transform.map(rect.topRight());
- QPointF bl = d->transform.map(rect.bottomLeft());
- QPointF br = d->transform.map(rect.bottomRight());
- coords[0] = tl.x();
- coords[1] = tl.y();
- coords[2] = tr.x();
- coords[3] = tr.y();
- coords[4] = br.x();
- coords[5] = br.y();
- coords[6] = bl.x();
- coords[7] = bl.y();
- }
- vgModifyPathCoords(d->rectPath, 0, 4, coords);
- d->fill(d->rectPath, QBrush(color));
-#else
- QPaintEngineEx::fillRect(rect, QBrush(color));
-#endif
-}
-
-void QVGPaintEngine::drawRoundedRect(const QRectF &rect, qreal xrad, qreal yrad, Qt::SizeMode mode)
-{
- Q_D(QVGPaintEngine);
- if (d->needsEmulation()) {
- QPaintEngineEx::drawRoundedRect(rect, xrad, yrad, mode);
- return;
- }
- if (d->simpleTransform) {
- QVGPainterState *s = state();
- VGPath vgpath = d->roundedRectPath(rect, xrad, yrad, mode);
- d->draw(vgpath, s->pen, s->brush);
-#if defined(QVG_NO_MODIFY_PATH)
- vgDestroyPath(vgpath);
-#endif
- } else {
- QPaintEngineEx::drawRoundedRect(rect, xrad, yrad, mode);
- }
-}
-
-void QVGPaintEngine::drawRects(const QRect *rects, int rectCount)
-{
-#if !defined(QVG_NO_MODIFY_PATH)
- Q_D(QVGPaintEngine);
- if (d->needsEmulation()) {
- QPaintEngineEx::drawRects(rects, rectCount);
- return;
- }
- QVGPainterState *s = state();
- for (int i = 0; i < rectCount; ++i, ++rects) {
- VGfloat coords[8];
- if (d->simpleTransform) {
- coords[0] = rects->x();
- coords[1] = rects->y();
- coords[2] = rects->x() + rects->width();
- coords[3] = coords[1];
- coords[4] = coords[2];
- coords[5] = rects->y() + rects->height();
- coords[6] = coords[0];
- coords[7] = coords[5];
- } else {
- QPointF tl = d->transform.map(QPointF(rects->x(), rects->y()));
- QPointF tr = d->transform.map(QPointF(rects->x() + rects->width(),
- rects->y()));
- QPointF bl = d->transform.map(QPointF(rects->x(),
- rects->y() + rects->height()));
- QPointF br = d->transform.map(QPointF(rects->x() + rects->width(),
- rects->y() + rects->height()));
- coords[0] = tl.x();
- coords[1] = tl.y();
- coords[2] = tr.x();
- coords[3] = tr.y();
- coords[4] = br.x();
- coords[5] = br.y();
- coords[6] = bl.x();
- coords[7] = bl.y();
- }
- vgModifyPathCoords(d->rectPath, 0, 4, coords);
- d->draw(d->rectPath, s->pen, s->brush);
- }
-#else
- QPaintEngineEx::drawRects(rects, rectCount);
-#endif
-}
-
-void QVGPaintEngine::drawRects(const QRectF *rects, int rectCount)
-{
-#if !defined(QVG_NO_MODIFY_PATH)
- Q_D(QVGPaintEngine);
- if (d->needsEmulation()) {
- QPaintEngineEx::drawRects(rects, rectCount);
- return;
- }
- QVGPainterState *s = state();
- for (int i = 0; i < rectCount; ++i, ++rects) {
- VGfloat coords[8];
- if (d->simpleTransform) {
- coords[0] = rects->x();
- coords[1] = rects->y();
- coords[2] = rects->x() + rects->width();
- coords[3] = coords[1];
- coords[4] = coords[2];
- coords[5] = rects->y() + rects->height();
- coords[6] = coords[0];
- coords[7] = coords[5];
- } else {
- QPointF tl = d->transform.map(rects->topLeft());
- QPointF tr = d->transform.map(rects->topRight());
- QPointF bl = d->transform.map(rects->bottomLeft());
- QPointF br = d->transform.map(rects->bottomRight());
- coords[0] = tl.x();
- coords[1] = tl.y();
- coords[2] = tr.x();
- coords[3] = tr.y();
- coords[4] = br.x();
- coords[5] = br.y();
- coords[6] = bl.x();
- coords[7] = bl.y();
- }
- vgModifyPathCoords(d->rectPath, 0, 4, coords);
- d->draw(d->rectPath, s->pen, s->brush);
- }
-#else
- QPaintEngineEx::drawRects(rects, rectCount);
-#endif
-}
-
-void QVGPaintEngine::drawLines(const QLine *lines, int lineCount)
-{
-#if !defined(QVG_NO_MODIFY_PATH)
- Q_D(QVGPaintEngine);
- if (d->needsEmulation()) {
- QPaintEngineEx::drawLines(lines, lineCount);
- return;
- }
- QVGPainterState *s = state();
- for (int i = 0; i < lineCount; ++i, ++lines) {
- VGfloat coords[4];
- if (d->simpleTransform) {
- coords[0] = lines->x1();
- coords[1] = lines->y1();
- coords[2] = lines->x2();
- coords[3] = lines->y2();
- } else {
- QPointF p1 = d->transform.map(QPointF(lines->x1(), lines->y1()));
- QPointF p2 = d->transform.map(QPointF(lines->x2(), lines->y2()));
- coords[0] = p1.x();
- coords[1] = p1.y();
- coords[2] = p2.x();
- coords[3] = p2.y();
- }
- vgModifyPathCoords(d->linePath, 0, 2, coords);
- d->stroke(d->linePath, s->pen);
- }
-#else
- QPaintEngineEx::drawLines(lines, lineCount);
-#endif
-}
-
-void QVGPaintEngine::drawLines(const QLineF *lines, int lineCount)
-{
-#if !defined(QVG_NO_MODIFY_PATH)
- Q_D(QVGPaintEngine);
- if (d->needsEmulation()) {
- QPaintEngineEx::drawLines(lines, lineCount);
- return;
- }
- QVGPainterState *s = state();
- for (int i = 0; i < lineCount; ++i, ++lines) {
- VGfloat coords[4];
- if (d->simpleTransform) {
- coords[0] = lines->x1();
- coords[1] = lines->y1();
- coords[2] = lines->x2();
- coords[3] = lines->y2();
- } else {
- QPointF p1 = d->transform.map(lines->p1());
- QPointF p2 = d->transform.map(lines->p2());
- coords[0] = p1.x();
- coords[1] = p1.y();
- coords[2] = p2.x();
- coords[3] = p2.y();
- }
- vgModifyPathCoords(d->linePath, 0, 2, coords);
- d->stroke(d->linePath, s->pen);
- }
-#else
- QPaintEngineEx::drawLines(lines, lineCount);
-#endif
-}
-
-void QVGPaintEngine::drawEllipse(const QRectF &r)
-{
- // Based on the description of vguEllipse() in the OpenVG specification.
- // We don't use vguEllipse(), to avoid unnecessary library dependencies.
- Q_D(QVGPaintEngine);
- if (d->needsEmulation()) {
- QPaintEngineEx::drawEllipse(r);
- return;
- }
- if (d->simpleTransform) {
- QVGPainterState *s = state();
- VGPath path = vgCreatePath(VG_PATH_FORMAT_STANDARD,
- VG_PATH_DATATYPE_F,
- 1.0f, // scale
- 0.0f, // bias
- 4, // segmentCapacityHint
- 12, // coordCapacityHint
- VG_PATH_CAPABILITY_ALL);
- static VGubyte segments[4] = {
- VG_MOVE_TO_ABS,
- VG_SCCWARC_TO_REL,
- VG_SCCWARC_TO_REL,
- VG_CLOSE_PATH
- };
- VGfloat coords[12];
- VGfloat halfwid = r.width() / 2;
- VGfloat halfht = r.height() / 2;
- coords[0] = r.x() + r.width();
- coords[1] = r.y() + halfht;
- coords[2] = halfwid;
- coords[3] = halfht;
- coords[4] = 0.0f;
- coords[5] = -r.width();
- coords[6] = 0.0f;
- coords[7] = halfwid;
- coords[8] = halfht;
- coords[9] = 0.0f;
- coords[10] = r.width();
- coords[11] = 0.0f;
- vgAppendPathData(path, 4, segments, coords);
- d->draw(path, s->pen, s->brush);
- vgDestroyPath(path);
- } else {
- // The projective transform version of an ellipse is difficult.
- // Generate a QVectorPath containing cubic curves and transform that.
- QPaintEngineEx::drawEllipse(r);
- }
-}
-
-void QVGPaintEngine::drawEllipse(const QRect &r)
-{
- drawEllipse(QRectF(r));
-}
-
-void QVGPaintEngine::drawPath(const QPainterPath &path)
-{
- // Shortcut past the QPainterPath -> QVectorPath conversion,
- // converting the QPainterPath directly into a VGPath.
- Q_D(QVGPaintEngine);
- if (d->needsEmulation()) {
- QPaintEngineEx::drawPath(path);
- return;
- }
- QVGPainterState *s = state();
- VGPath vgpath = d->painterPathToVGPath(path);
- if (path.fillRule() == Qt::OddEvenFill)
- d->draw(vgpath, s->pen, s->brush, VG_EVEN_ODD);
- else
- d->draw(vgpath, s->pen, s->brush, VG_NON_ZERO);
- vgDestroyPath(vgpath);
-}
-
-void QVGPaintEngine::drawPoints(const QPointF *points, int pointCount)
-{
-#if !defined(QVG_NO_MODIFY_PATH)
- Q_D(QVGPaintEngine);
-
- if (d->needsPenEmulation()) {
- QPaintEngineEx::drawPoints(points, pointCount);
- return;
- }
-
- // Set up a new pen if necessary.
- QPen pen = state()->pen;
- if (pen.style() == Qt::NoPen)
- return;
- if (pen.capStyle() == Qt::FlatCap)
- pen.setCapStyle(Qt::SquareCap);
-
- for (int i = 0; i < pointCount; ++i, ++points) {
- VGfloat coords[4];
- if (d->simpleTransform) {
- coords[0] = points->x();
- coords[1] = points->y();
- coords[2] = coords[0];
- coords[3] = coords[1];
- } else {
- QPointF p = d->transform.map(*points);
- coords[0] = p.x();
- coords[1] = p.y();
- coords[2] = coords[0];
- coords[3] = coords[1];
- }
- vgModifyPathCoords(d->linePath, 0, 2, coords);
- d->stroke(d->linePath, pen);
- }
-#else
- QPaintEngineEx::drawPoints(points, pointCount);
-#endif
-}
-
-void QVGPaintEngine::drawPoints(const QPoint *points, int pointCount)
-{
-#if !defined(QVG_NO_MODIFY_PATH)
- Q_D(QVGPaintEngine);
-
- if (d->needsEmulation()) {
- QPaintEngineEx::drawPoints(points, pointCount);
- return;
- }
-
- // Set up a new pen if necessary.
- QPen pen = state()->pen;
- if (pen.style() == Qt::NoPen)
- return;
- if (pen.capStyle() == Qt::FlatCap)
- pen.setCapStyle(Qt::SquareCap);
-
- for (int i = 0; i < pointCount; ++i, ++points) {
- VGfloat coords[4];
- if (d->simpleTransform) {
- coords[0] = points->x();
- coords[1] = points->y();
- coords[2] = coords[0];
- coords[3] = coords[1];
- } else {
- QPointF p = d->transform.map(QPointF(*points));
- coords[0] = p.x();
- coords[1] = p.y();
- coords[2] = coords[0];
- coords[3] = coords[1];
- }
- vgModifyPathCoords(d->linePath, 0, 2, coords);
- d->stroke(d->linePath, pen);
- }
-#else
- QPaintEngineEx::drawPoints(points, pointCount);
-#endif
-}
-
-void QVGPaintEngine::drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode)
-{
- Q_D(QVGPaintEngine);
-
- if (d->needsEmulation()) {
- QPaintEngineEx::drawPolygon(points, pointCount, mode);
- return;
- }
-
- QVGPainterState *s = state();
- VGPath path = vgCreatePath(VG_PATH_FORMAT_STANDARD,
- VG_PATH_DATATYPE_F,
- 1.0f, // scale
- 0.0f, // bias
- pointCount + 1, // segmentCapacityHint
- pointCount * 2, // coordCapacityHint
- VG_PATH_CAPABILITY_ALL);
- QVarLengthArray<VGfloat, 16> coords;
- QVarLengthArray<VGubyte, 10> segments;
- for (int i = 0; i < pointCount; ++i, ++points) {
- if (d->simpleTransform) {
- coords.append(points->x());
- coords.append(points->y());
- } else {
- QPointF temp = d->transform.map(*points);
- coords.append(temp.x());
- coords.append(temp.y());
- }
- if (i == 0)
- segments.append(VG_MOVE_TO_ABS);
- else
- segments.append(VG_LINE_TO_ABS);
- }
- if (mode != QPaintEngine::PolylineMode)
- segments.append(VG_CLOSE_PATH);
- vgAppendPathData(path, segments.count(),
- segments.constData(), coords.constData());
- switch (mode) {
- case QPaintEngine::WindingMode:
- d->draw(path, s->pen, s->brush, VG_NON_ZERO);
- break;
-
- case QPaintEngine::PolylineMode:
- d->stroke(path, s->pen);
- break;
-
- default:
- d->draw(path, s->pen, s->brush, VG_EVEN_ODD);
- break;
- }
- vgDestroyPath(path);
-}
-
-void QVGPaintEngine::drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode)
-{
- Q_D(QVGPaintEngine);
-
- if (d->needsEmulation()) {
- QPaintEngineEx::drawPolygon(points, pointCount, mode);
- return;
- }
-
- QVGPainterState *s = state();
- VGPath path = vgCreatePath(VG_PATH_FORMAT_STANDARD,
- VG_PATH_DATATYPE_F,
- 1.0f, // scale
- 0.0f, // bias
- pointCount + 1, // segmentCapacityHint
- pointCount * 2, // coordCapacityHint
- VG_PATH_CAPABILITY_ALL);
- QVarLengthArray<VGfloat, 16> coords;
- QVarLengthArray<VGubyte, 10> segments;
- for (int i = 0; i < pointCount; ++i, ++points) {
- if (d->simpleTransform) {
- coords.append(points->x());
- coords.append(points->y());
- } else {
- QPointF temp = d->transform.map(QPointF(*points));
- coords.append(temp.x());
- coords.append(temp.y());
- }
- if (i == 0)
- segments.append(VG_MOVE_TO_ABS);
- else
- segments.append(VG_LINE_TO_ABS);
- }
- if (mode != QPaintEngine::PolylineMode)
- segments.append(VG_CLOSE_PATH);
- vgAppendPathData(path, segments.count(),
- segments.constData(), coords.constData());
- switch (mode) {
- case QPaintEngine::WindingMode:
- d->draw(path, s->pen, s->brush, VG_NON_ZERO);
- break;
-
- case QPaintEngine::PolylineMode:
- d->stroke(path, s->pen);
- break;
-
- default:
- d->draw(path, s->pen, s->brush, VG_EVEN_ODD);
- break;
- }
- vgDestroyPath(path);
-}
-
-void QVGPaintEnginePrivate::setImageOptions()
-{
- if (opacity != 1.0f && simpleTransform) {
- if (opacity != paintOpacity) {
- VGfloat values[4];
- values[0] = 1.0f;
- values[1] = 1.0f;
- values[2] = 1.0f;
- values[3] = opacity;
- vgSetParameterfv(opacityPaint, VG_PAINT_COLOR, 4, values);
- paintOpacity = opacity;
- }
- if (fillPaint != opacityPaint) {
- vgSetPaint(opacityPaint, VG_FILL_PATH);
- fillPaint = opacityPaint;
- }
- setImageMode(VG_DRAW_IMAGE_MULTIPLY);
- } else {
- setImageMode(VG_DRAW_IMAGE_NORMAL);
- }
-}
-
-void QVGPaintEnginePrivate::systemStateChanged()
-{
- q->updateScissor();
-}
-
-static void drawVGImage(QVGPaintEnginePrivate *d,
- const QRectF& r, VGImage vgImg,
- const QSize& imageSize, const QRectF& sr)
-{
- if (vgImg == VG_INVALID_HANDLE)
- return;
- VGImage child = VG_INVALID_HANDLE;
-
- if (sr.topLeft().isNull() && sr.size() == imageSize) {
- child = vgImg;
- } else {
- QRect src = sr.toRect();
-#if !defined(QT_SHIVAVG)
- child = vgChildImage(vgImg, src.x(), src.y(), src.width(), src.height());
-#else
- child = vgImg; // XXX: ShivaVG doesn't have vgChildImage().
-#endif
- }
-
- QTransform transform(d->imageTransform);
- VGfloat scaleX = sr.width() == 0.0f ? 0.0f : r.width() / sr.width();
- VGfloat scaleY = sr.height() == 0.0f ? 0.0f : r.height() / sr.height();
- transform.translate(r.x(), r.y());
- transform.scale(scaleX, scaleY);
- d->setTransform(VG_MATRIX_IMAGE_USER_TO_SURFACE, transform);
-
- d->setImageOptions();
- vgDrawImage(child);
-
- if(child != vgImg)
- vgDestroyImage(child);
-}
-
-static void drawVGImage(QVGPaintEnginePrivate *d,
- const QPointF& pos, VGImage vgImg)
-{
- if (vgImg == VG_INVALID_HANDLE)
- return;
-
- QTransform transform(d->imageTransform);
- transform.translate(pos.x(), pos.y());
- d->setTransform(VG_MATRIX_IMAGE_USER_TO_SURFACE, transform);
-
- d->setImageOptions();
- vgDrawImage(vgImg);
-}
-
-static void drawImageTiled(QVGPaintEnginePrivate *d,
- const QRectF &r,
- const QImage &image,
- const QRectF &sr = QRectF())
-{
- const int minTileSize = 16;
- int tileWidth = 512;
- int tileHeight = tileWidth;
-
- VGImageFormat tileFormat = qt_vg_image_to_vg_format(image.format());
- VGImage tile = VG_INVALID_HANDLE;
- QVGImagePool *pool = QVGImagePool::instance();
- while (tile == VG_INVALID_HANDLE && tileWidth >= minTileSize) {
- tile = pool->createPermanentImage(tileFormat, tileWidth, tileHeight,
- VG_IMAGE_QUALITY_FASTER);
- if (tile == VG_INVALID_HANDLE) {
- tileWidth /= 2;
- tileHeight /= 2;
- }
- }
- if (tile == VG_INVALID_HANDLE) {
- qWarning("drawImageTiled: Failed to create %dx%d tile, giving up", tileWidth, tileHeight);
- return;
- }
-
- VGfloat opacityMatrix[20] = {
- 1.0f, 0.0f, 0.0f, 0.0f,
- 0.0f, 1.0f, 0.0f, 0.0f,
- 0.0f, 0.0f, 1.0f, 0.0f,
- 0.0f, 0.0f, 0.0f, d->opacity,
- 0.0f, 0.0f, 0.0f, 0.0f
- };
- VGImage tileWithOpacity = VG_INVALID_HANDLE;
- if (d->opacity != 1) {
- tileWithOpacity = pool->createPermanentImage(VG_sARGB_8888_PRE,
- tileWidth, tileHeight, VG_IMAGE_QUALITY_FASTER);
- if (tileWithOpacity == VG_INVALID_HANDLE)
- qWarning("drawImageTiled: Failed to create extra tile, ignoring opacity");
- }
-
- QRect sourceRect = sr.toRect();
- if (sourceRect.isNull())
- sourceRect = QRect(0, 0, image.width(), image.height());
-
- VGfloat scaleX = r.width() / sourceRect.width();
- VGfloat scaleY = r.height() / sourceRect.height();
-
- d->setImageOptions();
-
- for (int y = sourceRect.y(); y < sourceRect.height(); y += tileHeight) {
- int h = qMin(tileHeight, sourceRect.height() - y);
- if (h < 1)
- break;
- for (int x = sourceRect.x(); x < sourceRect.width(); x += tileWidth) {
- int w = qMin(tileWidth, sourceRect.width() - x);
- if (w < 1)
- break;
-
- int bytesPerPixel = image.depth() / 8;
- const uchar *sptr = image.constBits() + x * bytesPerPixel + y * image.bytesPerLine();
- vgImageSubData(tile, sptr, image.bytesPerLine(), tileFormat, 0, 0, w, h);
-
- QTransform transform(d->imageTransform);
- transform.translate(r.x() + x, r.y() + y);
- transform.scale(scaleX, scaleY);
- d->setTransform(VG_MATRIX_IMAGE_USER_TO_SURFACE, transform);
-
- VGImage actualTile = tile;
- if (tileWithOpacity != VG_INVALID_HANDLE) {
- vgColorMatrix(tileWithOpacity, actualTile, opacityMatrix);
- if (w < tileWidth || h < tileHeight)
- actualTile = vgChildImage(tileWithOpacity, 0, 0, w, h);
- else
- actualTile = tileWithOpacity;
- } else if (w < tileWidth || h < tileHeight) {
- actualTile = vgChildImage(tile, 0, 0, w, h);
- }
- vgDrawImage(actualTile);
-
- if (actualTile != tile && actualTile != tileWithOpacity)
- vgDestroyImage(actualTile);
- }
- }
-
- vgDestroyImage(tile);
- if (tileWithOpacity != VG_INVALID_HANDLE)
- vgDestroyImage(tileWithOpacity);
-}
-
-// Used by qpixmapfilter_vg.cpp to draw filtered VGImage's.
-void qt_vg_drawVGImage(QPainter *painter, const QPointF& pos, VGImage vgImg)
-{
- QVGPaintEngine *engine =
- static_cast<QVGPaintEngine *>(painter->paintEngine());
- drawVGImage(engine->vgPrivate(), pos, vgImg);
-}
-
-// Used by qpixmapfilter_vg.cpp to draw filtered VGImage's as a stencil.
-void qt_vg_drawVGImageStencil
- (QPainter *painter, const QPointF& pos, VGImage vgImg, const QBrush& brush)
-{
- QVGPaintEngine *engine =
- static_cast<QVGPaintEngine *>(painter->paintEngine());
-
- QVGPaintEnginePrivate *d = engine->vgPrivate();
-
- QTransform transform(d->imageTransform);
- transform.translate(pos.x(), pos.y());
- d->setTransform(VG_MATRIX_IMAGE_USER_TO_SURFACE, transform);
-
- d->ensureBrush(brush);
- d->setImageMode(VG_DRAW_IMAGE_STENCIL);
- vgDrawImage(vgImg);
-}
-
-bool QVGPaintEngine::canVgWritePixels(const QImage &image) const
-{
- Q_D(const QVGPaintEngine);
-
- // qt_vg_image_to_vg_format returns VG_sARGB_8888 as
- // fallback case if no matching VG format is found.
- // If given image format is not Format_ARGB32 and returned
- // format is VG_sARGB_8888, it means that no match was
- // found. In that case vgWritePixels cannot be used.
- // Also 1-bit formats cannot be used directly either.
- if ((image.format() != QImage::Format_ARGB32
- && qt_vg_image_to_vg_format(image.format()) == VG_sARGB_8888)
- || image.depth() == 1) {
- return false;
- }
-
- // vgWritePixels ignores masking, blending and xforms so we can only use it if
- // ALL of the following conditions are true:
- // - It is a simple translate, or a scale of -1 on the y-axis (inverted)
- // - The opacity is totally opaque
- // - The composition mode is "source" OR "source over" provided the image is opaque
- return ( d->imageTransform.type() <= QTransform::TxScale
- && d->imageTransform.m11() == 1.0 && qAbs(d->imageTransform.m22()) == 1.0)
- && d->opacity == 1.0f
- && (d->blendMode == VG_BLEND_SRC || (d->blendMode == VG_BLEND_SRC_OVER &&
- !image.hasAlphaChannel()));
-}
-
-void QVGPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr)
-{
- QPixmapData *pd = pm.pixmapData();
- if (!pd)
- return; // null QPixmap
- if (pd->classId() == QPixmapData::OpenVGClass) {
- Q_D(QVGPaintEngine);
- QVGPixmapData *vgpd = static_cast<QVGPixmapData *>(pd);
- if (!vgpd->isValid())
- return;
- if (d->simpleTransform)
- drawVGImage(d, r, vgpd->toVGImage(), vgpd->size(), sr);
- else
- drawVGImage(d, r, vgpd->toVGImage(d->opacity), vgpd->size(), sr);
-
- if(!vgpd->failedToAlloc)
- return;
-
- // try to reallocate next time if reasonable small pixmap
- QSize screenSize = QApplication::desktop()->screenGeometry().size();
- if (pm.size().width() <= screenSize.width()
- && pm.size().height() <= screenSize.height())
- vgpd->failedToAlloc = false;
-
- vgpd->source.beginDataAccess();
- drawImage(r, vgpd->source.imageRef(), sr, Qt::AutoColor);
- vgpd->source.endDataAccess(true);
- } else {
- drawImage(r, *(pd->buffer()), sr, Qt::AutoColor);
- }
-}
-
-void QVGPaintEngine::drawPixmap(const QPointF &pos, const QPixmap &pm)
-{
- QPixmapData *pd = pm.pixmapData();
- if (!pd)
- return; // null QPixmap
- if (pd->classId() == QPixmapData::OpenVGClass) {
- Q_D(QVGPaintEngine);
- QVGPixmapData *vgpd = static_cast<QVGPixmapData *>(pd);
- if (!vgpd->isValid())
- return;
- if (d->simpleTransform)
- drawVGImage(d, pos, vgpd->toVGImage());
- else
- drawVGImage(d, pos, vgpd->toVGImage(d->opacity));
-
- if (!vgpd->failedToAlloc)
- return;
-
- // try to reallocate next time if reasonable small pixmap
- QSize screenSize = QApplication::desktop()->screenGeometry().size();
- if (pm.size().width() <= screenSize.width()
- && pm.size().height() <= screenSize.height())
- vgpd->failedToAlloc = false;
-
- vgpd->source.beginDataAccess();
- drawImage(pos, vgpd->source.imageRef());
- vgpd->source.endDataAccess(true);
- } else {
- drawImage(pos, *(pd->buffer()));
- }
-}
-
-void QVGPaintEngine::drawImage
- (const QRectF &r, const QImage &image, const QRectF &sr,
- Qt::ImageConversionFlags flags)
-{
- Q_D(QVGPaintEngine);
- if (image.isNull())
- return;
- VGImage vgImg;
- if (d->simpleTransform || d->opacity == 1.0f)
- vgImg = toVGImageSubRect(image, sr.toRect(), flags);
- else
- vgImg = toVGImageWithOpacitySubRect(image, d->opacity, sr.toRect());
- if (vgImg != VG_INVALID_HANDLE) {
- if (r.size() == sr.size()) {
- drawVGImage(d, r.topLeft(), vgImg);
- } else {
- drawVGImage(d, r, vgImg, sr.size().toSize(),
- QRectF(QPointF(0, 0), sr.size()));
- }
- } else {
- if (canVgWritePixels(image) && (r.size() == sr.size()) && !flags) {
- // Optimization for straight blits, no blending
- int x = sr.x();
- int y = sr.y();
- int bpp = image.depth() >> 3; // bytes
- int offset = 0;
- int bpl = image.bytesPerLine();
- if (d->imageTransform.m22() < 0) {
- // inverted
- offset = ((y + sr.height()) * bpl) - ((image.width() - x) * bpp);
- bpl = -bpl;
- } else {
- offset = (y * bpl) + (x * bpp);
- }
- const uchar *bits = image.constBits() + offset;
-
- QPointF mapped = d->imageTransform.map(r.topLeft());
- vgWritePixels(bits, bpl, qt_vg_image_to_vg_format(image.format()),
- mapped.x(), mapped.y() - sr.height(), r.width(), r.height());
- return;
- } else {
- // Monochrome images need to use the vgChildImage() path.
- vgImg = toVGImage(image, flags);
- if (vgImg == VG_INVALID_HANDLE)
- drawImageTiled(d, r, image, sr);
- else
- drawVGImage(d, r, vgImg, image.size(), sr);
- }
- }
- vgDestroyImage(vgImg);
-}
-
-void QVGPaintEngine::drawImage(const QPointF &pos, const QImage &image)
-{
- Q_D(QVGPaintEngine);
- if (image.isNull())
- return;
- VGImage vgImg;
- if (canVgWritePixels(image)) {
- // Optimization for straight blits, no blending
- bool inverted = (d->imageTransform.m22() < 0);
- const uchar *bits = inverted ? image.constBits() + image.byteCount() : image.constBits();
- int bpl = inverted ? -image.bytesPerLine() : image.bytesPerLine();
-
- QPointF mapped = d->imageTransform.map(pos);
- vgWritePixels(bits, bpl, qt_vg_image_to_vg_format(image.format()),
- mapped.x(), mapped.y() - image.height(), image.width(), image.height());
- return;
- } else if (d->simpleTransform || d->opacity == 1.0f) {
- vgImg = toVGImage(image);
- } else {
- vgImg = toVGImageWithOpacity(image, d->opacity);
- }
- if (vgImg == VG_INVALID_HANDLE)
- drawImageTiled(d, QRectF(pos, image.size()), image);
- else
- drawVGImage(d, pos, vgImg);
- vgDestroyImage(vgImg);
-}
-
-void QVGPaintEngine::drawTiledPixmap
- (const QRectF &r, const QPixmap &pixmap, const QPointF &s)
-{
- QBrush brush(state()->pen.color(), pixmap);
- QTransform xform = QTransform::fromTranslate(r.x() - s.x(), r.y() - s.y());
- brush.setTransform(xform);
- fillRect(r, brush);
-}
-
-// Best performance will be achieved with QDrawPixmaps::OpaqueHint
-// (i.e. no opacity), no rotation or scaling, and drawing the full
-// pixmap rather than parts of the pixmap. Even having just one of
-// these conditions will improve performance.
-void QVGPaintEngine::drawPixmapFragments(const QPainter::PixmapFragment *drawingData, int dataCount,
- const QPixmap &pixmap, QFlags<QPainter::PixmapFragmentHint> hints)
-{
-#if !defined(QT_SHIVAVG)
- Q_D(QVGPaintEngine);
-
- // If the pixmap is not VG, or the transformation is projective,
- // then fall back to the default implementation.
- QPixmapData *pd = pixmap.pixmapData();
- if (!pd)
- return; // null QPixmap
- if (pd->classId() != QPixmapData::OpenVGClass || !d->simpleTransform) {
- QPaintEngineEx::drawPixmapFragments(drawingData, dataCount, pixmap, hints);
- return;
- }
-
- // Bail out if nothing to do.
- if (dataCount <= 0)
- return;
-
- // Bail out if we don't have a usable VGImage for the pixmap.
- QVGPixmapData *vgpd = static_cast<QVGPixmapData *>(pd);
- if (!vgpd->isValid())
- return;
- VGImage vgImg = vgpd->toVGImage();
- if (vgImg == VG_INVALID_HANDLE)
- return;
-
- // We cache the results of any vgChildImage() calls because the
- // same child is very likely to be used over and over in particle
- // systems. However, performance is even better if vgChildImage()
- // isn't needed at all, so use full source rects where possible.
- QVarLengthArray<VGImage> cachedImages;
- QVarLengthArray<QRect> cachedSources;
-
- // Select the opacity paint object.
- if ((hints & QPainter::OpaqueHint) != 0 && d->opacity == 1.0f) {
- d->setImageMode(VG_DRAW_IMAGE_NORMAL);
- } else {
- hints = 0;
- if (d->fillPaint != d->opacityPaint) {
- vgSetPaint(d->opacityPaint, VG_FILL_PATH);
- d->fillPaint = d->opacityPaint;
- }
- }
-
- for (int i = 0; i < dataCount; ++i) {
- QTransform transform(d->imageTransform);
- transform.translate(drawingData[i].x, drawingData[i].y);
- transform.rotate(drawingData[i].rotation);
-
- VGImage child;
- QSize imageSize = vgpd->size();
- QRectF sr(drawingData[i].sourceLeft, drawingData[i].sourceTop,
- drawingData[i].width, drawingData[i].height);
- if (sr.topLeft().isNull() && sr.size() == imageSize) {
- child = vgImg;
- } else {
- // Look for a previous child with the same source rectangle
- // to avoid constantly calling vgChildImage()/vgDestroyImage().
- QRect src = sr.toRect();
- int j;
- for (j = 0; j < cachedSources.size(); ++j) {
- if (cachedSources[j] == src)
- break;
- }
- if (j < cachedSources.size()) {
- child = cachedImages[j];
- } else {
- child = vgChildImage
- (vgImg, src.x(), src.y(), src.width(), src.height());
- cachedImages.append(child);
- cachedSources.append(src);
- }
- }
-
- VGfloat scaleX = drawingData[i].scaleX;
- VGfloat scaleY = drawingData[i].scaleY;
- transform.translate(-0.5 * scaleX * sr.width(),
- -0.5 * scaleY * sr.height());
- transform.scale(scaleX, scaleY);
- d->setTransform(VG_MATRIX_IMAGE_USER_TO_SURFACE, transform);
-
- if ((hints & QPainter::OpaqueHint) == 0) {
- qreal opacity = d->opacity * drawingData[i].opacity;
- if (opacity != 1.0f) {
- if (d->paintOpacity != opacity) {
- VGfloat values[4];
- values[0] = 1.0f;
- values[1] = 1.0f;
- values[2] = 1.0f;
- values[3] = opacity;
- d->paintOpacity = opacity;
- vgSetParameterfv
- (d->opacityPaint, VG_PAINT_COLOR, 4, values);
- }
- d->setImageMode(VG_DRAW_IMAGE_MULTIPLY);
- } else {
- d->setImageMode(VG_DRAW_IMAGE_NORMAL);
- }
- }
-
- vgDrawImage(child);
- }
-
- // Destroy the cached child sub-images.
- for (int i = 0; i < cachedImages.size(); ++i)
- vgDestroyImage(cachedImages[i]);
-#else
- QPaintEngineEx::drawPixmapFragments(drawingData, dataCount, pixmap, hints);
-#endif
-}
-
-QVGFontEngineCleaner::QVGFontEngineCleaner(QVGPaintEnginePrivate *d)
- : QObject(), d_ptr(d)
-{
-}
-
-QVGFontEngineCleaner::~QVGFontEngineCleaner()
-{
-}
-
-void QVGFontEngineCleaner::fontEngineDestroyed()
-{
-#if !defined(QVG_NO_DRAW_GLYPHS)
- QFontEngine *engine = static_cast<QFontEngine *>(sender());
- QVGFontCache::Iterator it = d_ptr->fontCache.find(engine);
- if (it != d_ptr->fontCache.end()) {
- delete it.value();
- d_ptr->fontCache.erase(it);
- }
-#endif
-}
-
-#if !defined(QVG_NO_DRAW_GLYPHS)
-
-QVGFontGlyphCache::QVGFontGlyphCache()
-{
- font = vgCreateFont(0);
- scaleX = scaleY = 0.0;
- invertedGlyphs = false;
- memset(cachedGlyphsMask, 0, sizeof(cachedGlyphsMask));
-}
-
-QVGFontGlyphCache::~QVGFontGlyphCache()
-{
- if (font != VG_INVALID_HANDLE)
- vgDestroyFont(font);
-}
-
-void QVGFontGlyphCache::setScaleFromText(const QFont &font, QFontEngine *fontEngine)
-{
- QFontInfo fi(font);
- qreal pixelSize = fi.pixelSize();
- qreal emSquare = fontEngine->properties().emSquare.toReal();
- scaleX = scaleY = static_cast<VGfloat>(pixelSize / emSquare);
-}
-
-void QVGFontGlyphCache::cacheGlyphs(QVGPaintEnginePrivate *d,
- QFontEngine *fontEngine,
- const glyph_t *g, int count)
-{
- VGfloat origin[2];
- VGfloat escapement[2];
- glyph_metrics_t metrics;
- // Some Qt font engines don't set yoff in getUnscaledGlyph().
- // Zero the metric structure so that everything has a default value.
- memset(&metrics, 0, sizeof(metrics));
- while (count-- > 0) {
- // Skip this glyph if we have already cached it before.
- glyph_t glyph = *g++;
- if (glyph < 256) {
- if ((cachedGlyphsMask[glyph / 32] & (1 << (glyph % 32))) != 0)
- continue;
- cachedGlyphsMask[glyph / 32] |= (1 << (glyph % 32));
- } else if (cachedGlyphs.contains(glyph)) {
- continue;
- } else {
- cachedGlyphs.insert(glyph);
- }
-#if !defined(QVG_NO_IMAGE_GLYPHS)
- Q_UNUSED(d);
- QImage scaledImage = fontEngine->alphaMapForGlyph(glyph);
- VGImage vgImage = VG_INVALID_HANDLE;
- metrics = fontEngine->boundingBox(glyph);
- if (!scaledImage.isNull()) { // Not a space character
- if (scaledImage.format() == QImage::Format_Indexed8) {
- vgImage = vgCreateImage(VG_A_8, scaledImage.width(), scaledImage.height(), VG_IMAGE_QUALITY_FASTER);
- vgImageSubData(vgImage, scaledImage.constBits(), scaledImage.bytesPerLine(), VG_A_8, 0, 0, scaledImage.width(), scaledImage.height());
- } else if (scaledImage.format() == QImage::Format_Mono) {
- QImage img = scaledImage.convertToFormat(QImage::Format_Indexed8);
- vgImage = vgCreateImage(VG_A_8, img.width(), img.height(), VG_IMAGE_QUALITY_FASTER);
- vgImageSubData(vgImage, img.constBits(), img.bytesPerLine(), VG_A_8, 0, 0, img.width(), img.height());
- } else {
- QImage img = scaledImage.convertToFormat(QImage::Format_ARGB32_Premultiplied);
- vgImage = vgCreateImage(VG_sARGB_8888_PRE, img.width(), img.height(), VG_IMAGE_QUALITY_FASTER);
- vgImageSubData(vgImage, img.constBits(), img.bytesPerLine(), VG_sARGB_8888_PRE, 0, 0, img.width(), img.height());
- }
- }
- origin[0] = -metrics.x.toReal();
- origin[1] = -metrics.y.toReal();
- escapement[0] = 0;
- escapement[1] = 0;
- vgSetGlyphToImage(font, glyph, vgImage, origin, escapement);
- vgDestroyImage(vgImage); // Reduce reference count.
-#else
- // Calculate the path for the glyph and cache it.
- QPainterPath path;
- fontEngine->getUnscaledGlyph(glyph, &path, &metrics);
- VGPath vgPath;
- if (!path.isEmpty()) {
- vgPath = d->painterPathToVGPath(path);
- } else {
- // Probably a "space" character with no visible outline.
- vgPath = VG_INVALID_HANDLE;
- }
- origin[0] = 0;
- origin[1] = 0;
- escapement[0] = 0;
- escapement[1] = 0;
- vgSetGlyphToPath(font, glyph, vgPath, VG_FALSE, origin, escapement);
- vgDestroyPath(vgPath); // Reduce reference count.
-#endif // !defined(QVG_NO_IMAGE_GLYPHS)
- }
-}
-
-#endif // !defined(QVG_NO_DRAW_GLYPHS)
-
-void QVGPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem)
-{
-#if !defined(QVG_NO_DRAW_GLYPHS)
- Q_D(QVGPaintEngine);
- const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem);
-
- // If we are not using a simple transform, then fall back
- // to the default Qt path stroking algorithm.
- if (!d->simpleTransform) {
- QPaintEngineEx::drawTextItem(p, textItem);
- return;
- }
-
- if (d->needsPenEmulation()) {
- QPaintEngineEx::drawTextItem(p, textItem);
- return;
- }
-
- // Get the glyphs and positions associated with the text item.
- QVarLengthArray<QFixedPoint> positions;
- QVarLengthArray<glyph_t> glyphs;
- QTransform matrix;
- ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions);
-
- if (!drawCachedGlyphs(glyphs.size(), glyphs.data(), ti.font(), ti.fontEngine, p, positions.data()))
- QPaintEngineEx::drawTextItem(p, textItem);
-#else
- // OpenGL 1.0 does not have support for VGFont and glyphs,
- // so fall back to the default Qt path stroking algorithm.
- QPaintEngineEx::drawTextItem(p, textItem);
-#endif
-}
-
-void QVGPaintEngine::drawStaticTextItem(QStaticTextItem *textItem)
-{
- drawCachedGlyphs(textItem->numGlyphs, textItem->glyphs, textItem->font, textItem->fontEngine(),
- QPointF(0, 0), textItem->glyphPositions);
-}
-
- bool QVGPaintEngine::drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs, const QFont &font,
- QFontEngine *fontEngine, const QPointF &p,
- const QFixedPoint *positions)
- {
-#if !defined(QVG_NO_DRAW_GLYPHS)
- Q_D(QVGPaintEngine);
-
- // Find the glyph cache for this font.
- QVGFontCache::ConstIterator it = d->fontCache.constFind(fontEngine);
- QVGFontGlyphCache *glyphCache;
- if (it != d->fontCache.constEnd()) {
- glyphCache = it.value();
- } else {
-#ifdef Q_OS_SYMBIAN
- glyphCache = new QSymbianVGFontGlyphCache();
-#else
- glyphCache = new QVGFontGlyphCache();
-#endif
- if (glyphCache->font == VG_INVALID_HANDLE) {
- qWarning("QVGPaintEngine::drawTextItem: OpenVG fonts are not supported by the OpenVG engine");
- delete glyphCache;
- return false;
- }
- glyphCache->setScaleFromText(font, fontEngine);
- d->fontCache.insert(fontEngine, glyphCache);
- if (!d->fontEngineCleaner)
- d->fontEngineCleaner = new QVGFontEngineCleaner(d);
- QObject::connect(fontEngine, SIGNAL(destroyed()),
- d->fontEngineCleaner, SLOT(fontEngineDestroyed()));
- }
-
- // Set the transformation to use for drawing the current glyphs.
- QTransform glyphTransform(d->pathTransform);
- if (d->transform.type() <= QTransform::TxTranslate) {
- // Prevent blurriness of unscaled, unrotated text by forcing integer coordinates.
- glyphTransform.translate(
- floor(p.x() + glyphTransform.dx() + aliasedCoordinateDelta) - glyphTransform.dx(),
- floor(p.y() - glyphTransform.dy() + aliasedCoordinateDelta) + glyphTransform.dy());
- } else {
- glyphTransform.translate(p.x(), p.y());
- }
-#if defined(QVG_NO_IMAGE_GLYPHS)
- glyphTransform.scale(glyphCache->scaleX, glyphCache->scaleY);
-#endif
-
- // Some glyph caches can create the VGImage upright
- if (glyphCache->invertedGlyphs)
- glyphTransform.scale(1, -1);
-
- d->setTransform(VG_MATRIX_GLYPH_USER_TO_SURFACE, glyphTransform);
-
- // Add the glyphs from the text item into the glyph cache.
- glyphCache->cacheGlyphs(d, fontEngine, glyphs, numGlyphs);
-
- // Create the array of adjustments between glyphs
- QVarLengthArray<VGfloat> adjustments_x(numGlyphs);
- QVarLengthArray<VGfloat> adjustments_y(numGlyphs);
- for (int i = 1; i < numGlyphs; ++i) {
- adjustments_x[i-1] = (positions[i].x - positions[i-1].x).round().toReal();
- adjustments_y[i-1] = (positions[i].y - positions[i-1].y).round().toReal();
- }
-
- // Set the glyph drawing origin.
- VGfloat origin[2];
- origin[0] = positions[0].x.round().toReal();
- origin[1] = positions[0].y.round().toReal();
- vgSetfv(VG_GLYPH_ORIGIN, 2, origin);
-
- // Fast anti-aliasing for paths, better for images.
-#if !defined(QVG_NO_IMAGE_GLYPHS)
- d->setImageQuality(VG_IMAGE_QUALITY_BETTER);
- d->setImageMode(VG_DRAW_IMAGE_STENCIL);
-#else
- d->setRenderingQuality(VG_RENDERING_QUALITY_FASTER);
-#endif
-
- // Draw the glyphs. We need to fill with the brush associated with
- // the Qt pen, not the Qt brush.
- d->ensureBrush(state()->pen.brush());
- vgDrawGlyphs(glyphCache->font, numGlyphs, (VGuint*)glyphs,
- adjustments_x.data(), adjustments_y.data(), VG_FILL_PATH, VG_TRUE);
- return true;
-#else
- Q_UNUSED(numGlyphs);
- Q_UNUSED(glyphs);
- Q_UNUSED(font);
- Q_UNUSED(fontEngine);
- Q_UNUSED(p);
- Q_UNUSED(positions);
- return false;
-#endif
-}
-
-void QVGPaintEngine::setState(QPainterState *s)
-{
- Q_D(QVGPaintEngine);
- QPaintEngineEx::setState(s);
- QVGPainterState *ps = static_cast<QVGPainterState *>(s);
- if (ps->isNew) {
- // Newly created state object. The call to setState()
- // will either be followed by a call to begin(), or we are
- // setting the state as part of a save().
- ps->isNew = false;
- } else {
- // This state object was set as part of a restore().
- restoreState(d->dirty);
- d->dirty = ps->savedDirty;
- }
-}
-
-void QVGPaintEngine::beginNativePainting()
-{
- Q_D(QVGPaintEngine);
-
- // About to enter raw VG mode: flush pending changes and make
- // sure that all matrices are set to the current transformation.
- QVGPainterState *s = this->state();
- d->ensurePen(s->pen);
- d->ensureBrush(s->brush);
- d->ensurePathTransform();
- d->setTransform(VG_MATRIX_IMAGE_USER_TO_SURFACE, d->imageTransform);
-#if !defined(QVG_NO_DRAW_GLYPHS)
- d->setTransform(VG_MATRIX_GLYPH_USER_TO_SURFACE, d->pathTransform);
-#endif
- vgSeti(VG_SCISSORING, VG_FALSE);
- vgSeti(VG_MASKING, VG_FALSE);
- d->rawVG = true;
-}
-
-void QVGPaintEngine::endNativePainting()
-{
- Q_D(QVGPaintEngine);
- // Exiting raw VG mode: force all state values to be
- // explicitly set on the VG engine to undo any changes
- // that were made by the raw VG function calls.
- QPaintEngine::DirtyFlags dirty = d->dirty;
- d->clearModes();
- d->forcePenChange = true;
- d->forceBrushChange = true;
- d->penType = (VGPaintType)0;
- d->brushType = (VGPaintType)0;
- d->clearColor = QColor();
- d->fillPaint = d->brushPaint;
- d->scissorDirty = true;
- restoreState(QPaintEngine::AllDirty);
- d->dirty = dirty;
- d->rawVG = false;
- vgSetPaint(d->penPaint, VG_STROKE_PATH);
- vgSetPaint(d->brushPaint, VG_FILL_PATH);
-}
-
-QPixmapFilter *QVGPaintEngine::pixmapFilter(int type, const QPixmapFilter *prototype)
-{
-#if !defined(QT_SHIVAVG)
- Q_D(QVGPaintEngine);
- switch (type) {
- case QPixmapFilter::ConvolutionFilter:
- if (!d->convolutionFilter)
- d->convolutionFilter.reset(new QVGPixmapConvolutionFilter);
- return d->convolutionFilter.data();
- case QPixmapFilter::ColorizeFilter:
- if (!d->colorizeFilter)
- d->colorizeFilter.reset(new QVGPixmapColorizeFilter);
- return d->colorizeFilter.data();
- case QPixmapFilter::DropShadowFilter:
- if (!d->dropShadowFilter)
- d->dropShadowFilter.reset(new QVGPixmapDropShadowFilter);
- return d->dropShadowFilter.data();
- case QPixmapFilter::BlurFilter:
- if (!d->blurFilter)
- d->blurFilter.reset(new QVGPixmapBlurFilter);
- return d->blurFilter.data();
- default: break;
- }
-#endif
- return QPaintEngineEx::pixmapFilter(type, prototype);
-}
-
-void QVGPaintEngine::restoreState(QPaintEngine::DirtyFlags dirty)
-{
- Q_D(QVGPaintEngine);
-
- // Restore the pen, brush, and other settings.
- if ((dirty & QPaintEngine::DirtyBrushOrigin) != 0)
- brushOriginChanged();
- d->fillRule = 0;
- d->clearColor = QColor();
- if ((dirty & QPaintEngine::DirtyOpacity) != 0)
- opacityChanged();
- if ((dirty & QPaintEngine::DirtyTransform) != 0)
- transformChanged();
- if ((dirty & QPaintEngine::DirtyCompositionMode) != 0)
- compositionModeChanged();
- if ((dirty & QPaintEngine::DirtyHints) != 0)
- renderHintsChanged();
- if ((dirty & (QPaintEngine::DirtyClipRegion |
- QPaintEngine::DirtyClipPath |
- QPaintEngine::DirtyClipEnabled)) != 0) {
- d->maskValid = false;
- d->maskIsSet = false;
- d->scissorMask = false;
- d->maskRect = QRect();
- d->scissorDirty = true;
- clipEnabledChanged();
- }
-
-#if defined(QVG_SCISSOR_CLIP)
- if ((dirty & (QPaintEngine::DirtyClipRegion |
- QPaintEngine::DirtyClipPath |
- QPaintEngine::DirtyClipEnabled)) == 0) {
- updateScissor();
- }
-#else
- updateScissor();
-#endif
-}
-
-void QVGPaintEngine::fillRegion
- (const QRegion& region, const QColor& color, const QSize& surfaceSize)
-{
- Q_D(QVGPaintEngine);
- if (d->clearColor != color || d->clearOpacity != 1.0f) {
- VGfloat values[4];
- values[0] = color.redF();
- values[1] = color.greenF();
- values[2] = color.blueF();
- values[3] = color.alphaF();
- vgSetfv(VG_CLEAR_COLOR, 4, values);
- d->clearColor = color;
- d->clearOpacity = 1.0f;
- }
- if (region.rectCount() == 1) {
- QRect r = region.boundingRect();
- vgClear(r.x(), surfaceSize.height() - r.y() - r.height(),
- r.width(), r.height());
- } else {
- const QVector<QRect> rects = region.rects();
- for (int i = 0; i < rects.size(); ++i) {
- QRect r = rects.at(i);
- vgClear(r.x(), surfaceSize.height() - r.y() - r.height(),
- r.width(), r.height());
- }
- }
-}
-
-#if !defined(QVG_NO_SINGLE_CONTEXT) && !defined(QT_NO_EGL)
-
-QVGCompositionHelper::QVGCompositionHelper()
-{
- d = qt_vg_create_paint_engine()->vgPrivate();
-}
-
-QVGCompositionHelper::~QVGCompositionHelper()
-{
-}
-
-void QVGCompositionHelper::startCompositing(const QSize& screenSize)
-{
- this->screenSize = screenSize;
- clearScissor();
- d->setBlendMode(VG_BLEND_SRC_OVER);
-}
-
-void QVGCompositionHelper::endCompositing()
-{
- clearScissor();
-}
-
-void QVGCompositionHelper::blitWindow
- (VGImage image, const QSize& imageSize,
- const QRect& rect, const QPoint& topLeft, int opacity)
-{
- if (image == VG_INVALID_HANDLE)
- return;
-
- // Determine which sub rectangle of the window to draw.
- QRect sr = rect.translated(-topLeft);
-
- if (opacity >= 255) {
- // Fully opaque: use vgSetPixels() to directly copy the sub-region.
- int y = screenSize.height() - (rect.bottom() + 1);
- vgSetPixels(rect.x(), y, image, sr.x(),
- imageSize.height() - (sr.y() + sr.height()),
- sr.width(), sr.height());
- } else {
- // Extract the child image that we want to draw.
- VGImage child;
- if (sr.topLeft().isNull() && sr.size() == imageSize)
- child = image;
- else {
- child = vgChildImage
- (image, sr.x(), imageSize.height() - (sr.y() + sr.height()),
- sr.width(), sr.height());
- }
-
- // Set the image transform.
- QTransform transform;
- int y = screenSize.height() - (rect.bottom() + 1);
- transform.translate(rect.x() - 0.5f, y - 0.5f);
- d->setTransform(VG_MATRIX_IMAGE_USER_TO_SURFACE, transform);
-
- // Enable opacity for image drawing if necessary.
- if (opacity != d->paintOpacity) {
- VGfloat values[4];
- values[0] = 1.0f;
- values[1] = 1.0f;
- values[2] = 1.0f;
- values[3] = ((VGfloat)opacity) / 255.0f;
- vgSetParameterfv(d->opacityPaint, VG_PAINT_COLOR, 4, values);
- d->paintOpacity = values[3];
- }
- if (d->fillPaint != d->opacityPaint) {
- vgSetPaint(d->opacityPaint, VG_FILL_PATH);
- d->fillPaint = d->opacityPaint;
- }
- d->setImageMode(VG_DRAW_IMAGE_MULTIPLY);
-
- // Draw the child image.
- vgDrawImage(child);
-
- // Destroy the child image.
- if(child != image)
- vgDestroyImage(child);
- }
-}
-
-static void fillBackgroundRect(const QRect& rect, QVGPaintEnginePrivate *d)
-{
- VGfloat coords[8];
- coords[0] = rect.x();
- coords[1] = rect.y();
- coords[2] = rect.x() + rect.width();
- coords[3] = coords[1];
- coords[4] = coords[2];
- coords[5] = rect.y() + rect.height();
- coords[6] = coords[0];
- coords[7] = coords[5];
-#if !defined(QVG_NO_MODIFY_PATH)
- vgModifyPathCoords(d->rectPath, 0, 4, coords);
- vgDrawPath(d->rectPath, VG_FILL_PATH);
-#else
- Q_UNUSED(d);
- VGPath rectPath = vgCreatePath
- (VG_PATH_FORMAT_STANDARD,
- VG_PATH_DATATYPE_F,
- 1.0f, // scale
- 0.0f, // bias
- 5, // segmentCapacityHint
- 8, // coordCapacityHint
- VG_PATH_CAPABILITY_ALL);
- static VGubyte const segments[5] = {
- VG_MOVE_TO_ABS,
- VG_LINE_TO_ABS,
- VG_LINE_TO_ABS,
- VG_LINE_TO_ABS,
- VG_CLOSE_PATH
- };
- vgAppendPathData(rectPath, 5, segments, coords);
- vgDrawPath(rectPath, VG_FILL_PATH);
- vgDestroyPath(rectPath);
-#endif
-}
-
-void QVGCompositionHelper::fillBackground
- (const QRegion& region, const QBrush& brush)
-{
- if (brush.style() == Qt::SolidPattern) {
- // Use vgClear() to quickly fill the background.
- QColor color = brush.color();
- if (d->clearColor != color || d->clearOpacity != 1.0f) {
- VGfloat values[4];
- values[0] = color.redF();
- values[1] = color.greenF();
- values[2] = color.blueF();
- values[3] = color.alphaF();
- vgSetfv(VG_CLEAR_COLOR, 4, values);
- d->clearColor = color;
- d->clearOpacity = 1.0f;
- }
- if (region.rectCount() == 1) {
- QRect r = region.boundingRect();
- vgClear(r.x(), screenSize.height() - r.y() - r.height(),
- r.width(), r.height());
- } else {
- const QVector<QRect> rects = region.rects();
- for (int i = 0; i < rects.size(); ++i) {
- QRect r = rects.at(i);
- vgClear(r.x(), screenSize.height() - r.y() - r.height(),
- r.width(), r.height());
- }
- }
-
- } else {
- // Set the path transform to the default viewport transformation.
- VGfloat devh = screenSize.height();
- QTransform viewport(1.0f, 0.0f, 0.0f,
- 0.0f, -1.0f, 0.0f,
- 0.0f, devh, 1.0f);
- d->setTransform(VG_MATRIX_PATH_USER_TO_SURFACE, viewport);
-
- // Set the brush to use to fill the background.
- d->ensureBrush(brush);
- d->setFillRule(VG_EVEN_ODD);
-
- if (region.rectCount() == 1) {
- fillBackgroundRect(region.boundingRect(), d);
- } else {
- const QVector<QRect> rects = region.rects();
- for (int i = 0; i < rects.size(); ++i)
- fillBackgroundRect(rects.at(i), d);
- }
-
- // We will need to reset the path transform during the next paint.
- d->pathTransformSet = false;
- }
-}
-
-void QVGCompositionHelper::drawCursorPixmap
- (const QPixmap& pixmap, const QPoint& offset)
-{
- VGImage vgImage = VG_INVALID_HANDLE;
-
- // Fetch the VGImage from the pixmap if possible.
- QPixmapData *pd = pixmap.pixmapData();
- if (!pd)
- return; // null QPixmap
- if (pd->classId() == QPixmapData::OpenVGClass) {
- QVGPixmapData *vgpd = static_cast<QVGPixmapData *>(pd);
- if (vgpd->isValid())
- vgImage = vgpd->toVGImage();
- }
-
- // Set the image transformation and modes.
- VGfloat devh = screenSize.height();
- QTransform transform(1.0f, 0.0f, 0.0f,
- 0.0f, -1.0f, 0.0f,
- 0.0f, devh, 1.0f);
- transform.translate(offset.x(), offset.y());
- d->setTransform(VG_MATRIX_IMAGE_USER_TO_SURFACE, transform);
- d->setImageMode(VG_DRAW_IMAGE_NORMAL);
-
- // Draw the VGImage.
- if (vgImage != VG_INVALID_HANDLE) {
- vgDrawImage(vgImage);
- } else {
- QImage img = pixmap.toImage().convertToFormat
- (QImage::Format_ARGB32_Premultiplied);
-
- vgImage = vgCreateImage
- (VG_sARGB_8888_PRE, img.width(), img.height(),
- VG_IMAGE_QUALITY_FASTER);
- if (vgImage == VG_INVALID_HANDLE)
- return;
- vgImageSubData
- (vgImage, img.constBits() + img.bytesPerLine() * (img.height() - 1),
- -(img.bytesPerLine()), VG_sARGB_8888_PRE, 0, 0,
- img.width(), img.height());
-
- vgDrawImage(vgImage);
- vgDestroyImage(vgImage);
- }
-}
-
-void QVGCompositionHelper::setScissor(const QRegion& region)
-{
- QVector<QRect> rects = region.rects();
- int count = rects.count();
- if (count > d->maxScissorRects)
- count = d->maxScissorRects;
- QVarLengthArray<VGint> params(count * 4);
- int height = screenSize.height();
- for (int i = 0; i < count; ++i) {
- params[i * 4 + 0] = rects[i].x();
- params[i * 4 + 1] = height - rects[i].y() - rects[i].height();
- params[i * 4 + 2] = rects[i].width();
- params[i * 4 + 3] = rects[i].height();
- }
-
- vgSetiv(VG_SCISSOR_RECTS, count * 4, params.data());
- vgSeti(VG_SCISSORING, VG_TRUE);
- d->scissorDirty = false;
- d->scissorActive = true;
- d->scissorRegion = region;
-}
-
-void QVGCompositionHelper::clearScissor()
-{
- if (d->scissorActive || d->scissorDirty) {
- vgSeti(VG_SCISSORING, VG_FALSE);
- d->scissorActive = false;
- d->scissorDirty = false;
- }
-}
-
-#endif // !QVG_NO_SINGLE_CONTEXT && !QT_NO_EGL
-
-VGImageFormat qt_vg_image_to_vg_format(QImage::Format format)
-{
- switch (format) {
- case QImage::Format_MonoLSB:
- return VG_BW_1;
- case QImage::Format_Indexed8:
- return VG_sL_8;
- case QImage::Format_ARGB32_Premultiplied:
- return VG_sARGB_8888_PRE;
- case QImage::Format_RGB32:
- return VG_sXRGB_8888;
- case QImage::Format_ARGB32:
- return VG_sARGB_8888;
- case QImage::Format_RGB16:
- return VG_sRGB_565;
- case QImage::Format_ARGB4444_Premultiplied:
- return VG_sARGB_4444;
- default:
- break;
- }
- return VG_sARGB_8888; // XXX
-}
-
-QT_END_NAMESPACE
-
-#include "qpaintengine_vg.moc"
diff --git a/src/openvg/qpaintengine_vg_p.h b/src/openvg/qpaintengine_vg_p.h
deleted file mode 100644
index 267ecd443f..0000000000
--- a/src/openvg/qpaintengine_vg_p.h
+++ /dev/null
@@ -1,179 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenVG module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPAINTENGINE_VG_P_H
-#define QPAINTENGINE_VG_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtGui/private/qpaintengineex_p.h>
-#include <QtGui/private/qtextureglyphcache_p.h>
-
-QT_BEGIN_NAMESPACE
-
-struct QFixedPoint;
-class QVGPaintEnginePrivate;
-class QPixmapData;
-class QVGEGLWindowSurfacePrivate;
-
-class Q_OPENVG_EXPORT QVGPainterState : public QPainterState
-{
-public:
- QVGPainterState(QVGPainterState& other);
- QVGPainterState();
- ~QVGPainterState();
-
- bool isNew;
- QRegion clipRegion;
- QPaintEngine::DirtyFlags savedDirty;
-};
-
-class Q_OPENVG_EXPORT QVGPaintEngine : public QPaintEngineEx
-{
- Q_DECLARE_PRIVATE(QVGPaintEngine)
-public:
- QVGPaintEngine();
- ~QVGPaintEngine();
-
- Type type() const { return OpenVG; }
-
- QPainterState *createState(QPainterState *orig) const;
-
- bool begin(QPaintDevice *pdev);
- bool end();
-
- void draw(const QVectorPath &path);
- void fill(const QVectorPath &path, const QBrush &brush);
- void stroke(const QVectorPath &path, const QPen &pen);
-
- void clip(const QVectorPath &path, Qt::ClipOperation op);
- void clip(const QRect &rect, Qt::ClipOperation op);
- void clip(const QRegion &region, Qt::ClipOperation op);
- void clip(const QPainterPath &path, Qt::ClipOperation op);
-
- void clipEnabledChanged();
- void penChanged();
- void brushChanged();
- void brushOriginChanged();
- void opacityChanged();
- void compositionModeChanged();
- void renderHintsChanged();
- void transformChanged();
-
- void fillRect(const QRectF &rect, const QBrush &brush);
- void fillRect(const QRectF &rect, const QColor &color);
-
- void drawRoundedRect(const QRectF &rect, qreal xrad, qreal yrad, Qt::SizeMode mode);
-
- void drawRects(const QRect *rects, int rectCount);
- void drawRects(const QRectF *rects, int rectCount);
-
- void drawLines(const QLine *lines, int lineCount);
- void drawLines(const QLineF *lines, int lineCount);
-
- void drawEllipse(const QRectF &r);
- void drawEllipse(const QRect &r);
-
- void drawPath(const QPainterPath &path);
-
- void drawPoints(const QPointF *points, int pointCount);
- void drawPoints(const QPoint *points, int pointCount);
-
- void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode);
- void drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode);
-
- void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr);
- void drawPixmap(const QPointF &pos, const QPixmap &pm);
-
- void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr,
- Qt::ImageConversionFlags flags = Qt::AutoColor);
- void drawImage(const QPointF &pos, const QImage &image);
-
- void drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s);
-
- void drawPixmapFragments(const QPainter::PixmapFragment *drawingData, int dataCount, const QPixmap &pixmap,
- QFlags<QPainter::PixmapFragmentHint> hints);
-
- void drawTextItem(const QPointF &p, const QTextItem &textItem);
- void drawStaticTextItem(QStaticTextItem *staticTextItem);
- bool drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs, const QFont &font,
- QFontEngine *fontEngine, const QPointF &p,
- const QFixedPoint *positions);
-
- void setState(QPainterState *s);
- QVGPainterState *state() { return static_cast<QVGPainterState *>(QPaintEngineEx::state()); }
- const QVGPainterState *state() const { return static_cast<const QVGPainterState *>(QPaintEngineEx::state()); }
-
- void beginNativePainting();
- void endNativePainting();
-
- QPixmapFilter *pixmapFilter(int type, const QPixmapFilter *prototype);
-
- QVGPaintEnginePrivate *vgPrivate() { Q_D(QVGPaintEngine); return d; }
-
- void fillRegion(const QRegion& region, const QColor& color, const QSize& surfaceSize);
- bool supportsTransformations(qreal, const QTransform &) const { return true; }
-
-protected:
- QVGPaintEngine(QVGPaintEnginePrivate &data);
-
-private:
- void restoreState(QPaintEngine::DirtyFlags dirty);
- void updateScissor();
- QRegion defaultClipRegion();
- bool isDefaultClipRegion(const QRegion& region);
- bool isDefaultClipRect(const QRect& rect);
- bool clearRect(const QRectF &rect, const QColor &color);
- bool canVgWritePixels(const QImage &image) const;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/openvg/qpixmapdata_vg.cpp b/src/openvg/qpixmapdata_vg.cpp
deleted file mode 100644
index de22db8fa9..0000000000
--- a/src/openvg/qpixmapdata_vg.cpp
+++ /dev/null
@@ -1,575 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenVG module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qpixmapdata_vg_p.h"
-#include "qpaintengine_vg_p.h"
-#include <QtGui/private/qdrawhelper_p.h>
-#if !defined(QT_NO_EGL)
-#include <QtGui/private/qegl_p.h>
-#endif
-#include "qvg_p.h"
-#include "qvgimagepool_p.h"
-#include <QBuffer>
-#include <QImageReader>
-#include <QtGui/private/qimage_p.h>
-#include <QtGui/private/qnativeimagehandleprovider_p.h>
-#include <QtGui/private/qfont_p.h>
-
-QT_BEGIN_NAMESPACE
-
-static int qt_vg_pixmap_serial = 0;
-
-QVGPixmapData::QVGPixmapData(PixelType type)
- : QPixmapData(type, OpenVGClass)
-{
- Q_ASSERT(type == QPixmapData::PixmapType);
- vgImage = VG_INVALID_HANDLE;
- vgImageOpacity = VG_INVALID_HANDLE;
- cachedOpacity = 1.0f;
- recreate = true;
- inImagePool = false;
- inLRU = false;
- failedToAlloc = false;
-#if defined(Q_OS_SYMBIAN)
- nativeImageHandleProvider = 0;
- nativeImageHandle = 0;
-#endif
-#if !defined(QT_NO_EGL)
- context = 0;
- qt_vg_register_pixmap(this);
-#endif
- updateSerial();
-}
-
-QVGPixmapData::~QVGPixmapData()
-{
- destroyImageAndContext();
-#if !defined(QT_NO_EGL)
- qt_vg_unregister_pixmap(this);
-#endif
-}
-
-void QVGPixmapData::destroyImages()
-{
- if (inImagePool) {
- QVGImagePool *pool = QVGImagePool::instance();
- if (vgImage != VG_INVALID_HANDLE)
- pool->releaseImage(this, vgImage);
- if (vgImageOpacity != VG_INVALID_HANDLE)
- pool->releaseImage(this, vgImageOpacity);
- } else {
- if (vgImage != VG_INVALID_HANDLE)
- vgDestroyImage(vgImage);
- if (vgImageOpacity != VG_INVALID_HANDLE)
- vgDestroyImage(vgImageOpacity);
- }
- vgImage = VG_INVALID_HANDLE;
- vgImageOpacity = VG_INVALID_HANDLE;
- inImagePool = false;
-
-#if defined(Q_OS_SYMBIAN)
- releaseNativeImageHandle();
-#endif
-}
-
-void QVGPixmapData::destroyImageAndContext()
-{
- if (vgImage != VG_INVALID_HANDLE) {
- // We need to have a context current to destroy the image.
-#if !defined(QT_NO_EGL)
- if (!context)
- context = qt_vg_create_context(0, QInternal::Pixmap);
- if (context->isCurrent()) {
- destroyImages();
- } else {
- // We don't currently have a widget surface active, but we
- // need a surface to make the context current. So use the
- // shared pbuffer surface instead.
- context->makeCurrent(qt_vg_shared_surface());
- destroyImages();
- context->lazyDoneCurrent();
- }
-#else
- destroyImages();
-#endif
- } else {
-#if defined(Q_OS_SYMBIAN)
- releaseNativeImageHandle();
-#endif
- }
-#if !defined(QT_NO_EGL)
- if (context) {
- qt_vg_destroy_context(context, QInternal::Pixmap);
- context = 0;
- }
-#endif
- recreate = true;
-}
-
-QPixmapData *QVGPixmapData::createCompatiblePixmapData() const
-{
- return new QVGPixmapData(pixelType());
-}
-
-bool QVGPixmapData::isValid() const
-{
- return (w > 0 && h > 0);
-}
-
-void QVGPixmapData::updateSerial()
-{
- setSerialNumber(++qt_vg_pixmap_serial);
-}
-
-void QVGPixmapData::resize(int wid, int ht)
-{
- if (w == wid && h == ht) {
- updateSerial();
- return;
- }
-
- w = wid;
- h = ht;
- d = 32; // We always use ARGB_Premultiplied for VG pixmaps.
- is_null = (w <= 0 || h <= 0);
- source = QVolatileImage();
- recreate = true;
-
- updateSerial();
-}
-
-void QVGPixmapData::fromImage(const QImage &image, Qt::ImageConversionFlags flags)
-{
- if (image.isNull())
- return;
-
- QImage img = image;
- createPixmapForImage(img, flags, false);
-}
-
-void QVGPixmapData::fromImageReader(QImageReader *imageReader,
- Qt::ImageConversionFlags flags)
-{
- QImage image = imageReader->read();
- if (image.isNull())
- return;
-
- createPixmapForImage(image, flags, true);
-}
-
-bool QVGPixmapData::fromFile(const QString &filename, const char *format,
- Qt::ImageConversionFlags flags)
-{
- QImage image = QImageReader(filename, format).read();
- if (image.isNull())
- return false;
-
- createPixmapForImage(image, flags, true);
-
- return !isNull();
-}
-
-bool QVGPixmapData::fromData(const uchar *buffer, uint len, const char *format,
- Qt::ImageConversionFlags flags)
-{
- QByteArray a = QByteArray::fromRawData(reinterpret_cast<const char *>(buffer), len);
- QBuffer b(&a);
- b.open(QIODevice::ReadOnly);
- QImage image = QImageReader(&b, format).read();
- if (image.isNull())
- return false;
-
- createPixmapForImage(image, flags, true);
-
- return !isNull();
-}
-
-QImage::Format QVGPixmapData::idealFormat(QImage *image, Qt::ImageConversionFlags flags) const
-{
- QImage::Format format = sourceFormat();
- int d = image->depth();
- if (d == 1 || d == 16 || d == 24 || (d == 32 && !image->hasAlphaChannel()))
- format = QImage::Format_RGB32;
- else if (!(flags & Qt::NoOpaqueDetection) && image->data_ptr()->checkForAlphaPixels())
- format = sourceFormat();
- else
- format = image->hasAlphaChannel() ? sourceFormat() : QImage::Format_RGB32;
- return format;
-}
-
-void QVGPixmapData::createPixmapForImage(QImage &image, Qt::ImageConversionFlags flags, bool inPlace)
-{
- resize(image.width(), image.height());
-
- QImage::Format format = idealFormat(&image, flags);
-
- if (inPlace && image.data_ptr()->convertInPlace(format, flags)) {
- source = QVolatileImage(image);
- } else {
- QImage convertedImage = image.convertToFormat(format);
- // convertToFormat won't detach the image if format stays the
- // same. Detaching is needed to prevent issues with painting
- // onto this QPixmap later on.
- convertedImage.detach();
- source = QVolatileImage(convertedImage);
- }
-
- recreate = true;
-}
-
-void QVGPixmapData::fill(const QColor &color)
-{
- if (!isValid())
- return;
- forceToImage();
- if (source.depth() == 1) {
- // Pick the best approximate color in the image's colortable.
- int gray = qGray(color.rgba());
- if (qAbs(qGray(source.imageRef().color(0)) - gray)
- < qAbs(qGray(source.imageRef().color(1)) - gray))
- source.fill(0);
- else
- source.fill(1);
- } else {
- source.fill(PREMUL(color.rgba()));
- }
-}
-
-bool QVGPixmapData::hasAlphaChannel() const
-{
- ensureReadback(true);
- if (!source.isNull())
- return source.hasAlphaChannel();
- else
- return isValid();
-}
-
-void QVGPixmapData::setAlphaChannel(const QPixmap &alphaChannel)
-{
- if (!isValid())
- return;
- forceToImage();
- source.setAlphaChannel(alphaChannel);
-}
-
-QImage QVGPixmapData::toImage() const
-{
- if (!isValid())
- return QImage();
- ensureReadback(true);
- if (source.isNull()) {
- source = QVolatileImage(w, h, sourceFormat());
- recreate = true;
- }
- return source.toImage();
-}
-
-void QVGPixmapData::copy(const QPixmapData *data, const QRect &rect)
-{
- // toImage() is potentially expensive with QVolatileImage so provide a
- // more efficient implementation of copy() that does not rely on it.
- if (!data) {
- return;
- }
- if (data->classId() != OpenVGClass) {
- fromImage(data->toImage(rect), Qt::NoOpaqueDetection);
- return;
- }
- const QVGPixmapData *pd = static_cast<const QVGPixmapData *>(data);
- QRect r = rect;
- if (r.isNull() || r.contains(QRect(0, 0, pd->w, pd->h))) {
- r = QRect(0, 0, pd->w, pd->h);
- }
- resize(r.width(), r.height());
- recreate = true;
- if (!pd->source.isNull()) {
- source = QVolatileImage(r.width(), r.height(), pd->source.format());
- source.copyFrom(&pd->source, r);
- }
-}
-
-QImage *QVGPixmapData::buffer()
-{
- // Cannot be safely implemented and QVGPixmapData is not (must not be) RasterClass anyway.
- return 0;
-}
-
-QPaintEngine* QVGPixmapData::paintEngine() const
-{
- // If the application wants to paint into the QPixmap, we first
- // force it to QImage format and then paint into that.
- // This is simpler than juggling multiple VG contexts.
- const_cast<QVGPixmapData *>(this)->forceToImage();
- return source.paintEngine();
-}
-
-VGImage QVGPixmapData::toVGImage()
-{
- if (!isValid() || failedToAlloc)
- return VG_INVALID_HANDLE;
-
-#if !defined(QT_NO_EGL)
- // Increase the reference count on the shared context.
- if (!context)
- context = qt_vg_create_context(0, QInternal::Pixmap);
-#endif
-
- if (recreate && prevSize != QSize(w, h))
- destroyImages();
- else if (recreate)
- cachedOpacity = -1.0f; // Force opacity image to be refreshed later.
-
-#if defined(Q_OS_SYMBIAN)
- if (recreate && nativeImageHandleProvider && !nativeImageHandle) {
- createFromNativeImageHandleProvider();
- }
-#endif
-
- if (vgImage == VG_INVALID_HANDLE) {
- vgImage = QVGImagePool::instance()->createImageForPixmap
- (qt_vg_image_to_vg_format(source.format()), w, h, VG_IMAGE_QUALITY_FASTER, this);
-
- // Bail out if we run out of GPU memory - try again next time.
- if (vgImage == VG_INVALID_HANDLE) {
- failedToAlloc = true;
- return VG_INVALID_HANDLE;
- }
-
- inImagePool = true;
- } else if (inImagePool) {
- QVGImagePool::instance()->useImage(this);
- }
-
- if (!source.isNull() && recreate) {
- source.beginDataAccess();
- vgImageSubData
- (vgImage,
- source.constBits(), source.bytesPerLine(),
- qt_vg_image_to_vg_format(source.format()), 0, 0, w, h);
- source.endDataAccess(true);
- }
-
- recreate = false;
- prevSize = QSize(w, h);
-
- return vgImage;
-}
-
-VGImage QVGPixmapData::toVGImage(qreal opacity)
-{
-#if !defined(QT_SHIVAVG)
- // Force the primary VG image to be recreated if necessary.
- if (toVGImage() == VG_INVALID_HANDLE)
- return VG_INVALID_HANDLE;
-
- if (opacity == 1.0f)
- return vgImage;
-
- // Create an alternative image for the selected opacity.
- if (vgImageOpacity == VG_INVALID_HANDLE || cachedOpacity != opacity) {
- if (vgImageOpacity == VG_INVALID_HANDLE) {
- if (inImagePool) {
- vgImageOpacity = QVGImagePool::instance()->createImageForPixmap
- (VG_sARGB_8888_PRE, w, h, VG_IMAGE_QUALITY_FASTER, this);
- } else {
- vgImageOpacity = vgCreateImage
- (VG_sARGB_8888_PRE, w, h, VG_IMAGE_QUALITY_FASTER);
- }
-
- // Bail out if we run out of GPU memory - try again next time.
- if (vgImageOpacity == VG_INVALID_HANDLE)
- return VG_INVALID_HANDLE;
- }
- VGfloat matrix[20] = {
- 1.0f, 0.0f, 0.0f, 0.0f,
- 0.0f, 1.0f, 0.0f, 0.0f,
- 0.0f, 0.0f, 1.0f, 0.0f,
- 0.0f, 0.0f, 0.0f, opacity,
- 0.0f, 0.0f, 0.0f, 0.0f
- };
- vgColorMatrix(vgImageOpacity, vgImage, matrix);
- cachedOpacity = opacity;
- }
-
- return vgImageOpacity;
-#else
- // vgColorMatrix() doesn't work with ShivaVG, so ignore the opacity.
- Q_UNUSED(opacity);
- return toVGImage();
-#endif
-}
-
-void QVGPixmapData::detachImageFromPool()
-{
- if (inImagePool) {
- QVGImagePool::instance()->detachImage(this);
- inImagePool = false;
- }
-}
-
-void QVGPixmapData::hibernate()
-{
- // If the image was imported (e.g, from an SgImage under Symbian), then
- // skip the hibernation, there is no sense in copying it back to main
- // memory because the data is most likely shared between several processes.
- bool skipHibernate = (vgImage != VG_INVALID_HANDLE && source.isNull());
-#if defined(Q_OS_SYMBIAN)
- // However we have to proceed normally if the image was retrieved via
- // a handle provider.
- skipHibernate &= !nativeImageHandleProvider;
-#endif
- if (skipHibernate)
- return;
-
- forceToImage(false); // no readback allowed here
- destroyImageAndContext();
-}
-
-void QVGPixmapData::reclaimImages()
-{
- if (!inImagePool)
- return;
- forceToImage();
- destroyImages();
-}
-
-int QVGPixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const
-{
- switch (metric) {
- case QPaintDevice::PdmWidth:
- return w;
- case QPaintDevice::PdmHeight:
- return h;
- case QPaintDevice::PdmNumColors:
- return 0;
- case QPaintDevice::PdmDepth:
- return d;
- case QPaintDevice::PdmWidthMM:
- return qRound(w * 25.4 / qt_defaultDpiX());
- case QPaintDevice::PdmHeightMM:
- return qRound(h * 25.4 / qt_defaultDpiY());
- case QPaintDevice::PdmDpiX:
- case QPaintDevice::PdmPhysicalDpiX:
- return qt_defaultDpiX();
- case QPaintDevice::PdmDpiY:
- case QPaintDevice::PdmPhysicalDpiY:
- return qt_defaultDpiY();
- default:
- qWarning("QVGPixmapData::metric(): Invalid metric");
- return 0;
- }
-}
-
-// Ensures that the pixmap is backed by some valid data and forces the data to
-// be re-uploaded to the VGImage when toVGImage() is called next time.
-void QVGPixmapData::forceToImage(bool allowReadback)
-{
- if (!isValid())
- return;
-
- if (allowReadback)
- ensureReadback(false);
-
- if (source.isNull())
- source = QVolatileImage(w, h, sourceFormat());
-
- recreate = true;
-}
-
-void QVGPixmapData::ensureReadback(bool readOnly) const
-{
- if (vgImage != VG_INVALID_HANDLE && source.isNull()) {
- source = QVolatileImage(w, h, sourceFormat());
- source.beginDataAccess();
- vgGetImageSubData(vgImage, source.bits(), source.bytesPerLine(),
- qt_vg_image_to_vg_format(source.format()),
- 0, 0, w, h);
- source.endDataAccess();
- if (readOnly) {
- recreate = false;
- } else {
- // Once we did a readback, the original VGImage must be destroyed
- // because it may be shared (e.g. created via SgImage) and a subsequent
- // upload of the image data may produce unexpected results.
- const_cast<QVGPixmapData *>(this)->destroyImages();
-#if defined(Q_OS_SYMBIAN)
- // There is now an own copy of the data so drop the handle provider,
- // otherwise toVGImage() would request the handle again, which is wrong.
- nativeImageHandleProvider = 0;
-#endif
- recreate = true;
- }
- }
-}
-
-QImage::Format QVGPixmapData::sourceFormat() const
-{
- return QImage::Format_ARGB32_Premultiplied;
-}
-
-/*
- \internal
-
- Returns the VGImage that is storing the contents of \a pixmap.
- Returns VG_INVALID_HANDLE if \a pixmap is not owned by the OpenVG
- graphics system or \a pixmap is invalid.
-
- This function is typically used to access the backing store
- for a pixmap when executing raw OpenVG calls. It must only
- be used when a QPainter is active and the OpenVG paint engine
- is in use by the QPainter.
-
- \sa {QtOpenVG Module}
-*/
-Q_OPENVG_EXPORT VGImage qPixmapToVGImage(const QPixmap& pixmap)
-{
- QPixmapData *pd = pixmap.pixmapData();
- if (!pd)
- return VG_INVALID_HANDLE; // null QPixmap
- if (pd->classId() == QPixmapData::OpenVGClass) {
- QVGPixmapData *vgpd = static_cast<QVGPixmapData *>(pd);
- if (vgpd->isValid())
- return vgpd->toVGImage();
- }
- return VG_INVALID_HANDLE;
-}
-
-QT_END_NAMESPACE
diff --git a/src/openvg/qpixmapdata_vg_p.h b/src/openvg/qpixmapdata_vg_p.h
deleted file mode 100644
index 901bad9864..0000000000
--- a/src/openvg/qpixmapdata_vg_p.h
+++ /dev/null
@@ -1,202 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenVG module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPIXMAPDATA_VG_P_H
-#define QPIXMAPDATA_VG_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtGui/private/qpixmap_raster_p.h>
-#include <QtGui/private/qvolatileimage_p.h>
-#include "qvg_p.h"
-
-#if defined(Q_OS_SYMBIAN)
-class RSGImage;
-#endif
-
-QT_BEGIN_NAMESPACE
-
-class QEglContext;
-class QVGImagePool;
-class QImageReader;
-
-#if !defined(QT_NO_EGL)
-class QVGPixmapData;
-class QVGSharedContext;
-
-void qt_vg_register_pixmap(QVGPixmapData *pd);
-void qt_vg_unregister_pixmap(QVGPixmapData *pd);
-void qt_vg_hibernate_pixmaps(QVGSharedContext *context);
-#endif
-
-class QNativeImageHandleProvider;
-
-class Q_OPENVG_EXPORT QVGPixmapData : public QPixmapData
-{
-public:
- QVGPixmapData(PixelType type);
- ~QVGPixmapData();
-
- QPixmapData *createCompatiblePixmapData() const;
-
- // Is this pixmap valid (i.e. non-zero in size)?
- bool isValid() const;
-
- void resize(int width, int height);
- void fromImage(const QImage &image, Qt::ImageConversionFlags flags);
- void fromImageReader(QImageReader *imageReader,
- Qt::ImageConversionFlags flags);
- bool fromFile(const QString &filename, const char *format,
- Qt::ImageConversionFlags flags);
- bool fromData(const uchar *buffer, uint len, const char *format,
- Qt::ImageConversionFlags flags);
-
- void fill(const QColor &color);
- bool hasAlphaChannel() const;
- void setAlphaChannel(const QPixmap &alphaChannel);
- QImage toImage() const;
- void copy(const QPixmapData *data, const QRect &rect);
- QImage *buffer();
- QPaintEngine* paintEngine() const;
-
- // Return the VGImage form of this pixmap, creating it if necessary.
- // This assumes that there is a VG context current.
- virtual VGImage toVGImage();
-
- // Return the VGImage form for a specific opacity setting.
- virtual VGImage toVGImage(qreal opacity);
-
- // Detach this image from the image pool.
- virtual void detachImageFromPool();
-
- // Release the VG resources associated with this pixmap and copy
- // the pixmap's contents out of the GPU back into main memory.
- // The VG resource will be automatically recreated the next time
- // toVGImage() is called. Does nothing if the pixmap cannot be
- // hibernated for some reason (e.g. VGImage is shared with another
- // process via a SgImage).
- virtual void hibernate();
-
- // Called when the QVGImagePool wants to reclaim this pixmap's
- // VGImage objects to reuse storage.
- virtual void reclaimImages();
-
- // If vgImage is valid but source is null, copies pixel data from GPU back
- // into main memory and destroys vgImage. For a normal pixmap this function
- // does nothing, however if the pixmap was created directly from a VGImage
- // (e.g. via SgImage on Symbian) then by doing the readback this ensures
- // that QImage-based functions can operate too.
- virtual void ensureReadback(bool readOnly) const;
-
- QSize size() const { return QSize(w, h); }
-
-#if defined(Q_OS_SYMBIAN)
- void* toNativeType(NativeType type);
- void fromNativeType(void* pixmap, NativeType type);
- bool initFromNativeImageHandle(void *handle, const QString &type);
- void createFromNativeImageHandleProvider();
- void releaseNativeImageHandle();
-#endif
-
-protected:
- int metric(QPaintDevice::PaintDeviceMetric metric) const;
- void createPixmapForImage(QImage &image, Qt::ImageConversionFlags flags, bool inPlace);
-
-#if defined(Q_OS_SYMBIAN)
- void cleanup();
-#endif
-
-private:
- QVGPixmapData *nextLRU;
- QVGPixmapData *prevLRU;
- bool inLRU;
- bool failedToAlloc;
- friend class QVGImagePool;
- friend class QVGPaintEngine;
-
-#if !defined(QT_NO_EGL)
- QVGPixmapData *next;
- QVGPixmapData *prev;
-
- friend void qt_vg_register_pixmap(QVGPixmapData *pd);
- friend void qt_vg_unregister_pixmap(QVGPixmapData *pd);
- friend void qt_vg_hibernate_pixmaps(QVGSharedContext *context);
-#endif
-
-protected:
- QSize prevSize;
- VGImage vgImage;
- VGImage vgImageOpacity;
- qreal cachedOpacity;
- mutable QVolatileImage source;
- mutable bool recreate;
- bool inImagePool;
-#if !defined(QT_NO_EGL)
- mutable QEglContext *context;
-#endif
-
-#if defined(Q_OS_SYMBIAN)
- mutable QNativeImageHandleProvider *nativeImageHandleProvider;
- void *nativeImageHandle;
- QString nativeImageType;
-#endif
-
- void forceToImage(bool allowReadback = true);
- QImage::Format sourceFormat() const;
- QImage::Format idealFormat(QImage *image, Qt::ImageConversionFlags flags) const;
- void updateSerial();
-
- void destroyImageAndContext();
- void destroyImages();
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/openvg/qpixmapfilter_vg.cpp b/src/openvg/qpixmapfilter_vg.cpp
deleted file mode 100644
index 52dcca3706..0000000000
--- a/src/openvg/qpixmapfilter_vg.cpp
+++ /dev/null
@@ -1,356 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenVG module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qpixmapfilter_vg_p.h"
-#include "qvgimagepool_p.h"
-#include <QtCore/qvarlengtharray.h>
-#include <QtGui/qpainter.h>
-
-QT_BEGIN_NAMESPACE
-
-#if !defined(QT_SHIVAVG)
-
-QVGPixmapConvolutionFilter::QVGPixmapConvolutionFilter()
- : QPixmapConvolutionFilter()
-{
-}
-
-QVGPixmapConvolutionFilter::~QVGPixmapConvolutionFilter()
-{
-}
-
-extern void qt_vg_drawVGImage
- (QPainter *painter, const QPointF& pos, VGImage vgImg);
-extern void qt_vg_drawVGImageStencil
- (QPainter *painter, const QPointF& pos, VGImage vgImg, const QBrush& brush);
-
-void QVGPixmapConvolutionFilter::draw
- (QPainter *painter, const QPointF &dest,
- const QPixmap &src, const QRectF &srcRect) const
-{
- if (src.isNull())
- return;
-
- if (src.pixmapData()->classId() != QPixmapData::OpenVGClass) {
- // The pixmap data is not an instance of QVGPixmapData, so fall
- // back to the default convolution filter implementation.
- QPixmapConvolutionFilter::draw(painter, dest, src, srcRect);
- return;
- }
-
- QVGPixmapData *pd = static_cast<QVGPixmapData *>(src.pixmapData());
-
- VGImage srcImage = pd->toVGImage();
- if (srcImage == VG_INVALID_HANDLE)
- return;
-
- QSize size = pd->size();
- VGImage dstImage = QVGImagePool::instance()->createTemporaryImage
- (VG_sARGB_8888_PRE, size.width(), size.height(),
- VG_IMAGE_QUALITY_FASTER, pd);
- if (dstImage == VG_INVALID_HANDLE)
- return;
-
- int kernelWidth = rows();
- int kernelHeight = columns();
- const qreal *kern = convolutionKernel();
- QVarLengthArray<VGshort> kernel;
- for (int i = 0; i < kernelWidth; ++i) {
- for (int j = 0; j < kernelHeight; ++j) {
- kernel.append((VGshort)(kern[j * kernelWidth + i] * 1024.0f));
- }
- }
-
- VGfloat values[4];
- values[0] = 0.0f;
- values[1] = 0.0f;
- values[2] = 0.0f;
- values[3] = 0.0f;
- vgSetfv(VG_TILE_FILL_COLOR, 4, values);
-
- vgConvolve(dstImage, srcImage,
- kernelWidth, kernelHeight, 0, 0,
- kernel.constData(), 1.0f / 1024.0f, 0.0f,
- VG_TILE_FILL);
-
- VGImage child = VG_INVALID_HANDLE;
-
- if (srcRect.isNull() ||
- (srcRect.topLeft().isNull() && srcRect.size() == size)) {
- child = dstImage;
- } else {
- QRect src = srcRect.toRect();
- child = vgChildImage(dstImage, src.x(), src.y(), src.width(), src.height());
- }
-
- qt_vg_drawVGImage(painter, dest, child);
-
- if(child != dstImage)
- vgDestroyImage(child);
- QVGImagePool::instance()->releaseImage(0, dstImage);
-}
-
-QVGPixmapColorizeFilter::QVGPixmapColorizeFilter()
- : QPixmapColorizeFilter()
-{
-}
-
-QVGPixmapColorizeFilter::~QVGPixmapColorizeFilter()
-{
-}
-
-void QVGPixmapColorizeFilter::draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect) const
-{
- if (src.isNull())
- return;
-
- if (src.pixmapData()->classId() != QPixmapData::OpenVGClass) {
- // The pixmap data is not an instance of QVGPixmapData, so fall
- // back to the default colorize filter implementation.
- QPixmapColorizeFilter::draw(painter, dest, src, srcRect);
- return;
- }
-
- QVGPixmapData *pd = static_cast<QVGPixmapData *>(src.pixmapData());
-
- VGImage srcImage = pd->toVGImage();
- if (srcImage == VG_INVALID_HANDLE)
- return;
-
- QSize size = pd->size();
- VGImage dstImage = QVGImagePool::instance()->createTemporaryImage
- (VG_sARGB_8888_PRE, size.width(), size.height(),
- VG_IMAGE_QUALITY_FASTER, pd);
- if (dstImage == VG_INVALID_HANDLE)
- return;
-
- // Determine the weights for the matrix from the color and strength.
- QColor c = color();
- VGfloat strength = this->strength();
- VGfloat weights[3];
- VGfloat invweights[3];
- VGfloat alpha = c.alphaF();
- weights[0] = c.redF() * alpha;
- weights[1] = c.greenF() * alpha;
- weights[2] = c.blueF() * alpha;
- invweights[0] = (1.0f - weights[0]) * strength;
- invweights[1] = (1.0f - weights[1]) * strength;
- invweights[2] = (1.0f - weights[2]) * strength;
-
- // Grayscale weights.
- static const VGfloat redGray = 11.0f / 32.0f;
- static const VGfloat greenGray = 16.0f / 32.0f;
- static const VGfloat blueGray = 1.0f - (redGray + greenGray);
-
- VGfloat matrix[5][4];
- matrix[0][0] = redGray * invweights[0] + (1.0f - strength);
- matrix[0][1] = redGray * invweights[1];
- matrix[0][2] = redGray * invweights[2];
- matrix[0][3] = 0.0f;
- matrix[1][0] = greenGray * invweights[0];
- matrix[1][1] = greenGray * invweights[1] + (1.0f - strength);
- matrix[1][2] = greenGray * invweights[2];
- matrix[1][3] = 0.0f;
- matrix[2][0] = blueGray * invweights[0];
- matrix[2][1] = blueGray * invweights[1];
- matrix[2][2] = blueGray * invweights[2] + (1.0f - strength);
- matrix[2][3] = 0.0f;
- matrix[3][0] = 0.0f;
- matrix[3][1] = 0.0f;
- matrix[3][2] = 0.0f;
- matrix[3][3] = 1.0f;
- matrix[4][0] = weights[0] * strength;
- matrix[4][1] = weights[1] * strength;
- matrix[4][2] = weights[2] * strength;
- matrix[4][3] = 0.0f;
-
- vgColorMatrix(dstImage, srcImage, matrix[0]);
-
- VGImage child = VG_INVALID_HANDLE;
-
- if (srcRect.isNull() ||
- (srcRect.topLeft().isNull() && srcRect.size() == size)) {
- child = dstImage;
- } else {
- QRect src = srcRect.toRect();
- child = vgChildImage(dstImage, src.x(), src.y(), src.width(), src.height());
- }
-
- qt_vg_drawVGImage(painter, dest, child);
-
- if(child != dstImage)
- vgDestroyImage(child);
- QVGImagePool::instance()->releaseImage(0, dstImage);
-}
-
-QVGPixmapDropShadowFilter::QVGPixmapDropShadowFilter()
- : QPixmapDropShadowFilter()
-{
-}
-
-QVGPixmapDropShadowFilter::~QVGPixmapDropShadowFilter()
-{
-}
-
-void QVGPixmapDropShadowFilter::draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect) const
-{
- if (src.isNull())
- return;
-
- if (src.pixmapData()->classId() != QPixmapData::OpenVGClass) {
- // The pixmap data is not an instance of QVGPixmapData, so fall
- // back to the default drop shadow filter implementation.
- QPixmapDropShadowFilter::draw(painter, dest, src, srcRect);
- return;
- }
-
- QVGPixmapData *pd = static_cast<QVGPixmapData *>(src.pixmapData());
-
- VGImage srcImage = pd->toVGImage();
- if (srcImage == VG_INVALID_HANDLE)
- return;
-
- QSize size = pd->size();
- VGImage dstImage = QVGImagePool::instance()->createTemporaryImage
- (VG_A_8, size.width(), size.height(),
- VG_IMAGE_QUALITY_FASTER, pd);
- if (dstImage == VG_INVALID_HANDLE)
- return;
-
- // Clamp the radius range. We divide by 2 because the OpenVG blur
- // is "too blurry" compared to the default raster implementation.
- VGfloat maxRadius = VGfloat(vgGeti(VG_MAX_GAUSSIAN_STD_DEVIATION));
- VGfloat radiusF = VGfloat(blurRadius()) / 2.0f;
- if (radiusF < 0.001f)
- radiusF = 0.001f;
- else if (radiusF > maxRadius)
- radiusF = maxRadius;
-
- // Blur the blackened source image.
- vgGaussianBlur(dstImage, srcImage, radiusF, radiusF, VG_TILE_PAD);
-
- VGImage child = VG_INVALID_HANDLE;
-
- QRect srect;
- if (srcRect.isNull() ||
- (srcRect.topLeft().isNull() && srcRect.size() == size)) {
- child = dstImage;
- srect = QRect(0, 0, size.width(), size.height());
- } else {
- srect = srcRect.toRect();
- child = vgChildImage(dstImage, srect.x(), srect.y(), srect.width(), srect.height());
- }
-
- qt_vg_drawVGImageStencil(painter, dest + offset(), child, color());
-
- if(child != dstImage)
- vgDestroyImage(child);
- QVGImagePool::instance()->releaseImage(0, dstImage);
-
- // Now draw the actual pixmap over the top.
- painter->drawPixmap(dest, src, srect);
-}
-
-QVGPixmapBlurFilter::QVGPixmapBlurFilter(QObject *parent)
- : QPixmapBlurFilter(parent)
-{
-}
-
-QVGPixmapBlurFilter::~QVGPixmapBlurFilter()
-{
-}
-
-void QVGPixmapBlurFilter::draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect) const
-{
- if (src.isNull())
- return;
-
- if (src.pixmapData()->classId() != QPixmapData::OpenVGClass) {
- // The pixmap data is not an instance of QVGPixmapData, so fall
- // back to the default blur filter implementation.
- QPixmapBlurFilter::draw(painter, dest, src, srcRect);
- return;
- }
-
- QVGPixmapData *pd = static_cast<QVGPixmapData *>(src.pixmapData());
-
- VGImage srcImage = pd->toVGImage();
- if (srcImage == VG_INVALID_HANDLE)
- return;
-
- QSize size = pd->size();
- VGImage dstImage = QVGImagePool::instance()->createTemporaryImage
- (VG_sARGB_8888_PRE, size.width(), size.height(),
- VG_IMAGE_QUALITY_FASTER, pd);
- if (dstImage == VG_INVALID_HANDLE)
- return;
-
- // Clamp the radius range. We divide by 2 because the OpenVG blur
- // is "too blurry" compared to the default raster implementation.
- VGfloat maxRadius = VGfloat(vgGeti(VG_MAX_GAUSSIAN_STD_DEVIATION));
- VGfloat radiusF = VGfloat(radius()) / 2.0f;
- if (radiusF < 0.001f)
- radiusF = 0.001f;
- else if (radiusF > maxRadius)
- radiusF = maxRadius;
-
- vgGaussianBlur(dstImage, srcImage, radiusF, radiusF, VG_TILE_PAD);
-
- VGImage child = VG_INVALID_HANDLE;
-
- if (srcRect.isNull() ||
- (srcRect.topLeft().isNull() && srcRect.size() == size)) {
- child = dstImage;
- } else {
- QRect src = srcRect.toRect();
- child = vgChildImage(dstImage, src.x(), src.y(), src.width(), src.height());
- }
-
- qt_vg_drawVGImage(painter, dest, child);
-
- if(child != dstImage)
- vgDestroyImage(child);
- QVGImagePool::instance()->releaseImage(0, dstImage);
-}
-
-#endif
-
-QT_END_NAMESPACE
diff --git a/src/openvg/qpixmapfilter_vg_p.h b/src/openvg/qpixmapfilter_vg_p.h
deleted file mode 100644
index 710bd8b266..0000000000
--- a/src/openvg/qpixmapfilter_vg_p.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenVG module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPIXMAPFILTER_VG_P_H
-#define QPIXMAPFILTER_VG_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qpixmapdata_vg_p.h"
-#include <QtGui/private/qpixmapfilter_p.h>
-#include <QtCore/qvarlengtharray.h>
-
-QT_BEGIN_NAMESPACE
-
-#if !defined(QT_SHIVAVG)
-
-class QVGPixmapConvolutionFilter : public QPixmapConvolutionFilter
-{
- Q_OBJECT
-public:
- QVGPixmapConvolutionFilter();
- ~QVGPixmapConvolutionFilter();
-
- void draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect) const;
-};
-
-class QVGPixmapColorizeFilter : public QPixmapColorizeFilter
-{
- Q_OBJECT
-public:
- QVGPixmapColorizeFilter();
- ~QVGPixmapColorizeFilter();
-
- void draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect) const;
-};
-
-class QVGPixmapDropShadowFilter : public QPixmapDropShadowFilter
-{
- Q_OBJECT
-public:
- QVGPixmapDropShadowFilter();
- ~QVGPixmapDropShadowFilter();
-
- void draw(QPainter *p, const QPointF &pos, const QPixmap &px, const QRectF &src) const;
-};
-
-class QVGPixmapBlurFilter : public QPixmapBlurFilter
-{
- Q_OBJECT
-public:
- QVGPixmapBlurFilter(QObject *parent = 0);
- ~QVGPixmapBlurFilter();
-
- void draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect = QRectF()) const;
-};
-
-#endif
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/openvg/qvg.h b/src/openvg/qvg.h
deleted file mode 100644
index fa1f099fb9..0000000000
--- a/src/openvg/qvg.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenVG module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QVG_H
-#define QVG_H
-
-#include <QtCore/qglobal.h>
-
-// Include the OpenVG headers for use in applications that
-// issue raw OpenVG function calls.
-#if defined(QT_LOWER_CASE_VG_INCLUDES)
-#include <vg/openvg.h>
-#else
-#include <VG/openvg.h>
-#endif
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(OpenVG)
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif
diff --git a/src/openvg/qvg_p.h b/src/openvg/qvg_p.h
deleted file mode 100644
index 2e313b08ed..0000000000
--- a/src/openvg/qvg_p.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenVG module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QVG_P_H
-#define QVG_P_H
-
-#include "qvg.h"
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-// vgDrawGlyphs() only exists in OpenVG 1.1 and higher.
-#if !defined(OPENVG_VERSION_1_1) && !defined(QVG_NO_DRAW_GLYPHS)
-#define QVG_NO_DRAW_GLYPHS 1
-#endif
-
-#include <QtGui/qimage.h>
-
-#if !defined(QT_NO_EGL)
-#include <QtGui/private/qeglcontext_p.h>
-#endif
-
-QT_BEGIN_NAMESPACE
-
-class QVGPaintEngine;
-
-#if !defined(QT_NO_EGL)
-
-class QEglContext;
-
-// Create an EGL context, but don't bind it to a surface. If single-context
-// mode is enabled, this will return the previously-created context.
-// "devType" indicates the type of device using the context, usually
-// QInternal::Widget or QInternal::Pixmap.
-Q_OPENVG_EXPORT QEglContext *qt_vg_create_context
- (QPaintDevice *device, int devType);
-
-// Destroy an EGL context that was created by qt_vg_create_context().
-// If single-context mode is enabled, this will decrease the reference count.
-// "devType" indicates the type of device destroying the context, usually
-// QInternal::Widget or QInternal::Pixmap.
-Q_OPENVG_EXPORT void qt_vg_destroy_context
- (QEglContext *context, int devType);
-
-// Return the shared pbuffer surface that can be made current to
-// destroy VGImage objects when there is no other surface available.
-Q_OPENVG_EXPORT EGLSurface qt_vg_shared_surface(void);
-
-// Convert the configuration format in a context to a VG or QImage format.
-Q_OPENVG_EXPORT VGImageFormat qt_vg_config_to_vg_format(QEglContext *context);
-Q_OPENVG_EXPORT QImage::Format qt_vg_config_to_image_format(QEglContext *context);
-
-#endif
-
-// Create a paint engine. Returns the common engine in single-context mode.
-Q_OPENVG_EXPORT QVGPaintEngine *qt_vg_create_paint_engine(void);
-
-// Destroy a paint engine. Does nothing in single-context mode.
-Q_OPENVG_EXPORT void qt_vg_destroy_paint_engine(QVGPaintEngine *engine);
-
-// Convert between QImage and VGImage format values.
-Q_OPENVG_EXPORT VGImageFormat qt_vg_image_to_vg_format(QImage::Format format);
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/openvg/qvg_symbian.cpp b/src/openvg/qvg_symbian.cpp
deleted file mode 100644
index 249b05387a..0000000000
--- a/src/openvg/qvg_symbian.cpp
+++ /dev/null
@@ -1,366 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qpixmapdata_vg_p.h"
-#include "qvgfontglyphcache_p.h"
-#include <QtGui/private/qnativeimagehandleprovider_p.h>
-#include <private/qt_s60_p.h>
-
-#include <fbs.h>
-
-#ifdef QT_SYMBIAN_SUPPORTS_SGIMAGE
-# include <sgresource/sgimage.h>
-# ifdef SYMBIAN_FBSERV_GLYPHDATA // defined in fbs.h
-# define QT_SYMBIAN_HARDWARE_GLYPH_CACHE
-# include <graphics/fbsglyphdataiterator.h>
-# include <private/qfontengine_s60_p.h>
-# endif
-#endif
-
-QT_BEGIN_NAMESPACE
-
-typedef VGImage (*_vgCreateEGLImageTargetKHR)(VGeglImageKHR);
-static _vgCreateEGLImageTargetKHR qt_vgCreateEGLImageTargetKHR = 0;
-
-namespace QVG
-{
- VGImage vgCreateEGLImageTargetKHR(VGeglImageKHR eglImage);
-}
-
-VGImage QVG::vgCreateEGLImageTargetKHR(VGeglImageKHR eglImage)
-{
- if (!qt_vgCreateEGLImageTargetKHR && QEgl::hasExtension("EGL_KHR_image"))
- qt_vgCreateEGLImageTargetKHR = (_vgCreateEGLImageTargetKHR) eglGetProcAddress("vgCreateEGLImageTargetKHR");
-
- return qt_vgCreateEGLImageTargetKHR ? qt_vgCreateEGLImageTargetKHR(eglImage) : 0;
-}
-
-extern int qt_vg_pixmap_serial;
-
-#ifdef QT_SYMBIAN_SUPPORTS_SGIMAGE
-static VGImage sgImageToVGImage(QEglContext *context, const RSgImage &sgImage)
-{
- // when "0" used as argument then
- // default display, context are used
- if (!context)
- context = qt_vg_create_context(0, QInternal::Pixmap);
-
- VGImage vgImage = VG_INVALID_HANDLE;
-
- if (sgImage.IsNull())
- return vgImage;
-
- const EGLint KEglImageAttribs[] = {EGL_IMAGE_PRESERVED_SYMBIAN, EGL_TRUE, EGL_NONE};
- EGLImageKHR eglImage = QEgl::eglCreateImageKHR(QEgl::display(),
- EGL_NO_CONTEXT,
- EGL_NATIVE_PIXMAP_KHR,
- (EGLClientBuffer)&sgImage,
- (EGLint*)KEglImageAttribs);
-
- if (!eglImage)
- return vgImage;
-
- vgImage = QVG::vgCreateEGLImageTargetKHR(eglImage);
-
- QEgl::eglDestroyImageKHR(QEgl::display(), eglImage);
- return vgImage;
-}
-#endif
-
-void QVGPixmapData::cleanup()
-{
- is_null = w = h = 0;
- recreate = false;
- source = QVolatileImage();
-}
-
-bool QVGPixmapData::initFromNativeImageHandle(void *handle, const QString &type)
-{
- if (type == QLatin1String("RSgImage")) {
- fromNativeType(handle, QPixmapData::SgImage);
- return true;
- } else if (type == QLatin1String("CFbsBitmap")) {
- fromNativeType(handle, QPixmapData::FbsBitmap);
- return true;
- }
- return false;
-}
-
-void QVGPixmapData::createFromNativeImageHandleProvider()
-{
- void *handle = 0;
- QString type;
- nativeImageHandleProvider->get(&handle, &type);
- if (handle) {
- if (initFromNativeImageHandle(handle, type)) {
- nativeImageHandle = handle;
- nativeImageType = type;
- } else {
- qWarning("QVGPixmapData: Unknown native image type '%s'", qPrintable(type));
- }
- } else {
- qWarning("QVGPixmapData: Native handle is null");
- }
-}
-
-void QVGPixmapData::releaseNativeImageHandle()
-{
- if (nativeImageHandleProvider && nativeImageHandle) {
- nativeImageHandleProvider->release(nativeImageHandle, nativeImageType);
- nativeImageHandle = 0;
- nativeImageType = QString();
- }
-}
-
-static inline bool conversionLessFormat(QImage::Format format)
-{
- switch (format) {
- case QImage::Format_RGB16: // EColor64K
- case QImage::Format_RGB32: // EColor16MU
- case QImage::Format_ARGB32: // EColor16MA
- case QImage::Format_ARGB32_Premultiplied: // EColor16MAP
- case QImage::Format_Indexed8: // EGray256, EColor256
- return true;
- default:
- return false;
- }
-}
-
-void QVGPixmapData::fromNativeType(void* pixmap, NativeType type)
-{
- if (type == QPixmapData::SgImage && pixmap) {
-#if defined(QT_SYMBIAN_SUPPORTS_SGIMAGE) && !defined(QT_NO_EGL)
- RSgImage *sgImage = reinterpret_cast<RSgImage*>(pixmap);
- destroyImages();
- prevSize = QSize();
-
- vgImage = sgImageToVGImage(context, *sgImage);
- if (vgImage != VG_INVALID_HANDLE) {
- w = vgGetParameteri(vgImage, VG_IMAGE_WIDTH);
- h = vgGetParameteri(vgImage, VG_IMAGE_HEIGHT);
- d = 32; // We always use ARGB_Premultiplied for VG pixmaps.
- }
-
- is_null = (w <= 0 || h <= 0);
- source = QVolatileImage(); // readback will be done later, only when needed
- recreate = false;
- prevSize = QSize(w, h);
- updateSerial();
-#endif
- } else if (type == QPixmapData::FbsBitmap && pixmap) {
- CFbsBitmap *bitmap = reinterpret_cast<CFbsBitmap *>(pixmap);
- QSize size(bitmap->SizeInPixels().iWidth, bitmap->SizeInPixels().iHeight);
- resize(size.width(), size.height());
- source = QVolatileImage(bitmap); // duplicates only, if possible
- if (source.isNull())
- return;
- if (!conversionLessFormat(source.format())) {
- // Here we may need to copy if the formats do not match.
- // (e.g. for display modes other than EColor16MAP and EColor16MU)
- source.beginDataAccess();
- QImage::Format format = idealFormat(&source.imageRef(), Qt::AutoColor);
- source.endDataAccess(true);
- source.ensureFormat(format);
- }
- recreate = true;
- } else if (type == QPixmapData::VolatileImage && pixmap) {
- QVolatileImage *img = static_cast<QVolatileImage *>(pixmap);
- resize(img->width(), img->height());
- source = *img;
- recreate = true;
- } else if (type == QPixmapData::NativeImageHandleProvider && pixmap) {
- destroyImages();
- nativeImageHandleProvider = static_cast<QNativeImageHandleProvider *>(pixmap);
- // Cannot defer the retrieval, we need at least the size right away.
- createFromNativeImageHandleProvider();
- }
-}
-
-void* QVGPixmapData::toNativeType(NativeType type)
-{
- if (type == QPixmapData::SgImage) {
-#if defined(QT_SYMBIAN_SUPPORTS_SGIMAGE) && !defined(QT_NO_EGL)
- toVGImage();
-
- if (!isValid() || vgImage == VG_INVALID_HANDLE)
- return 0;
-
- TInt err = 0;
-
- RSgDriver driver;
- err = driver.Open();
- if (err != KErrNone)
- return 0;
-
- TSgImageInfo sgInfo;
- sgInfo.iPixelFormat = EUidPixelFormatARGB_8888_PRE;
- sgInfo.iSizeInPixels.SetSize(w, h);
- sgInfo.iUsage = ESgUsageBitOpenVgImage | ESgUsageBitOpenVgSurface;
-
- QScopedPointer<RSgImage> sgImage(new RSgImage());
- err = sgImage->Create(sgInfo, NULL, NULL);
- if (err != KErrNone) {
- driver.Close();
- return 0;
- }
-
- const EGLint KEglImageAttribs[] = {EGL_IMAGE_PRESERVED_SYMBIAN, EGL_TRUE, EGL_NONE};
- EGLImageKHR eglImage = QEgl::eglCreateImageKHR(QEgl::display(),
- EGL_NO_CONTEXT,
- EGL_NATIVE_PIXMAP_KHR,
- (EGLClientBuffer)sgImage.data(),
- (EGLint*)KEglImageAttribs);
- if (!eglImage || eglGetError() != EGL_SUCCESS) {
- sgImage->Close();
- driver.Close();
- return 0;
- }
-
- VGImage dstVgImage = QVG::vgCreateEGLImageTargetKHR(eglImage);
- if (!dstVgImage || vgGetError() != VG_NO_ERROR) {
- QEgl::eglDestroyImageKHR(QEgl::display(), eglImage);
- sgImage->Close();
- driver.Close();
- return 0;
- }
-
- vgCopyImage(dstVgImage, 0, 0,
- vgImage, 0, 0,
- w, h, VG_FALSE);
-
- if (vgGetError() != VG_NO_ERROR) {
- sgImage->Close();
- sgImage.reset();
- }
-
- // release stuff
- vgDestroyImage(dstVgImage);
- QEgl::eglDestroyImageKHR(QEgl::display(), eglImage);
- driver.Close();
- return reinterpret_cast<void*>(sgImage.take());
-#endif
- } else if (type == QPixmapData::FbsBitmap && isValid()) {
- ensureReadback(true);
- if (source.isNull()) {
- source = QVolatileImage(w, h, sourceFormat());
- }
- // Just duplicate the bitmap handle, no data copying happens.
- return source.duplicateNativeImage();
- }
- return 0;
-}
-
-QSymbianVGFontGlyphCache::QSymbianVGFontGlyphCache() : QVGFontGlyphCache()
-{
-#ifdef QT_SYMBIAN_HARDWARE_GLYPH_CACHE
- invertedGlyphs = true;
-#endif
-}
-
-void QSymbianVGFontGlyphCache::cacheGlyphs(QVGPaintEnginePrivate *d,
- QFontEngine *fontEngine,
- const glyph_t *g, int count)
-{
-#ifdef QT_SYMBIAN_HARDWARE_GLYPH_CACHE
- QFontEngineS60 *s60fontEngine = static_cast<QFontEngineS60*>(fontEngine);
- if (s60fontEngine->m_activeFont->TypeUid() != KCFbsFontUid)
- return QVGFontGlyphCache::cacheGlyphs(d, fontEngine, g, count);
-
- QVector<glyph_t> uncachedGlyphs;
- while (count-- > 0) {
- // Skip this glyph if we have already cached it before.
- glyph_t glyph = *g++;
- if (((glyph < 256) && ((cachedGlyphsMask[glyph / 32] & (1 << (glyph % 32))) != 0))
- || cachedGlyphs.contains(glyph))
- continue;
- if (!uncachedGlyphs.contains(glyph))
- uncachedGlyphs.append(glyph);
- }
-
- if (!uncachedGlyphs.isEmpty()) {
- CFbsFont *cfbsFont = static_cast<CFbsFont *>(s60fontEngine->m_activeFont);
- RFbsGlyphDataIterator iter;
-
- int err = iter.Open(*cfbsFont, (const unsigned int*)uncachedGlyphs.constData(), uncachedGlyphs.count());
-
- if (err == KErrNotSupported || err == KErrInUse) { // Fallback in possibly supported error cases
- iter.Close();
- qWarning("Falling back to default QVGFontGlyphCache");
- return QVGFontGlyphCache::cacheGlyphs(d, fontEngine, g, count);
- }
-
- for (; err == KErrNone; err = iter.Next()) {
- const unsigned int glyph = iter.GlyphCode();
-
- const RSgImage& image = iter.Image();
- const TOpenFontCharMetrics& metrics = iter.Metrics();
-
- TRect glyphBounds;
- metrics.GetHorizBounds(glyphBounds);
- VGImage vgImage = sgImageToVGImage(0, image);
- VGfloat origin[2];
- VGfloat escapement[2];
- origin[0] = -glyphBounds.iTl.iX;
- origin[1] = glyphBounds.iBr.iY;
- escapement[0] = 0;
- escapement[1] = 0;
- vgSetGlyphToImage(font, glyph, vgImage, origin, escapement);
- vgDestroyImage(vgImage);
-
- // Add to cache
- if (glyph < 256)
- cachedGlyphsMask[glyph / 32] |= (1 << (glyph % 32));
- else
- cachedGlyphs.insert(glyph);
- }
- iter.Close();
-
- if (err == KErrNoMemory || err == KErrNoGraphicsMemory)
- qWarning("Not enough memory to cache glyph");
- else if (err != KErrNotFound)
- qWarning("Received error %d from glyph cache", err);
- }
-#else
- QVGFontGlyphCache::cacheGlyphs(d, fontEngine, g, count);
-#endif
-}
-
-QT_END_NAMESPACE
diff --git a/src/openvg/qvgcompositionhelper_p.h b/src/openvg/qvgcompositionhelper_p.h
deleted file mode 100644
index b776b7692a..0000000000
--- a/src/openvg/qvgcompositionhelper_p.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenVG module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QVGCOMPOSITIONHELPER_H
-#define QVGCOMPOSITIONHELPER_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qwindowsurface_vgegl_p.h"
-
-QT_BEGIN_NAMESPACE
-
-#if !defined(QVG_NO_SINGLE_CONTEXT) && !defined(QT_NO_EGL)
-
-class QVGPaintEnginePrivate;
-class QVGEGLWindowSurfacePrivate;
-
-class Q_OPENVG_EXPORT QVGCompositionHelper
-{
-public:
- QVGCompositionHelper();
- virtual ~QVGCompositionHelper();
-
- void startCompositing(const QSize& screenSize);
- void endCompositing();
-
- void blitWindow(VGImage image, const QSize& imageSize,
- const QRect& rect, const QPoint& topLeft, int opacity);
- void fillBackground(const QRegion& region, const QBrush& brush);
- void drawCursorPixmap(const QPixmap& pixmap, const QPoint& offset);
- void setScissor(const QRegion& region);
- void clearScissor();
-
-private:
- QVGPaintEnginePrivate *d;
- QSize screenSize;
-};
-
-#endif
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/openvg/qvgfontglyphcache_p.h b/src/openvg/qvgfontglyphcache_p.h
deleted file mode 100644
index cf33d0139f..0000000000
--- a/src/openvg/qvgfontglyphcache_p.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenVG module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QVGFONTGLYPHCACHE_H
-#define QVGFONTGLYPHCACHE_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/qvarlengtharray.h>
-#include <QtGui/private/qfontengine_p.h>
-
-#include "qvg_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class QVGPaintEnginePrivate;
-
-#ifndef QVG_NO_DRAW_GLYPHS
-
-class QVGFontGlyphCache
-{
-public:
- QVGFontGlyphCache();
- virtual ~QVGFontGlyphCache();
-
- virtual void cacheGlyphs(QVGPaintEnginePrivate *d,
- QFontEngine *fontEngine,
- const glyph_t *g, int count);
- void setScaleFromText(const QFont &font, QFontEngine *fontEngine);
-
- VGFont font;
- VGfloat scaleX;
- VGfloat scaleY;
- bool invertedGlyphs;
- uint cachedGlyphsMask[256 / 32];
- QSet<glyph_t> cachedGlyphs;
-};
-
-#if defined(Q_OS_SYMBIAN)
-class QSymbianVGFontGlyphCache : public QVGFontGlyphCache
-{
-public:
- QSymbianVGFontGlyphCache();
- void cacheGlyphs(QVGPaintEnginePrivate *d,
- QFontEngine *fontEngine,
- const glyph_t *g, int count);
-};
-#endif
-
-#endif
-
-QT_END_NAMESPACE
-
-#endif // QVGFONTGLYPHCACHE_H
diff --git a/src/openvg/qvgimagepool.cpp b/src/openvg/qvgimagepool.cpp
deleted file mode 100644
index 3a187b0112..0000000000
--- a/src/openvg/qvgimagepool.cpp
+++ /dev/null
@@ -1,233 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenVG module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qvgimagepool_p.h"
-#include "qpixmapdata_vg_p.h"
-
-QT_BEGIN_NAMESPACE
-
-static QVGImagePool *qt_vg_image_pool = 0;
-
-class QVGImagePoolPrivate
-{
-public:
- QVGImagePoolPrivate() : lruFirst(0), lruLast(0) {}
-
- QVGPixmapData *lruFirst;
- QVGPixmapData *lruLast;
-};
-
-QVGImagePool::QVGImagePool()
- : d_ptr(new QVGImagePoolPrivate())
-{
-}
-
-QVGImagePool::~QVGImagePool()
-{
-}
-
-QVGImagePool *QVGImagePool::instance()
-{
- if (!qt_vg_image_pool)
- qt_vg_image_pool = new QVGImagePool();
- return qt_vg_image_pool;
-}
-
-void QVGImagePool::setImagePool(QVGImagePool *pool)
-{
- if (qt_vg_image_pool != pool)
- delete qt_vg_image_pool;
- qt_vg_image_pool = pool;
-}
-
-VGImage QVGImagePool::createTemporaryImage(VGImageFormat format,
- VGint width, VGint height,
- VGbitfield allowedQuality,
- QVGPixmapData *keepData)
-{
- VGImage image;
- do {
- image = vgCreateImage(format, width, height, allowedQuality);
- if (image != VG_INVALID_HANDLE)
- return image;
- } while (reclaimSpace(format, width, height, keepData));
- qWarning("QVGImagePool: cannot reclaim sufficient space for a %dx%d temporary image",
- width, height);
- return VG_INVALID_HANDLE;
-}
-
-VGImage QVGImagePool::createImageForPixmap(VGImageFormat format,
- VGint width, VGint height,
- VGbitfield allowedQuality,
- QVGPixmapData *data)
-{
- VGImage image;
- do {
- image = vgCreateImage(format, width, height, allowedQuality);
- if (image != VG_INVALID_HANDLE) {
- if (data)
- moveToHeadOfLRU(data);
- return image;
- }
- } while (reclaimSpace(format, width, height, data));
- qWarning("QVGImagePool: cannot reclaim sufficient space for a %dx%d pixmap",
- width, height);
- return VG_INVALID_HANDLE;
-}
-
-VGImage QVGImagePool::createPermanentImage(VGImageFormat format,
- VGint width, VGint height,
- VGbitfield allowedQuality)
-{
- VGImage image;
- do {
- image = vgCreateImage(format, width, height, allowedQuality);
- if (image != VG_INVALID_HANDLE)
- return image;
- } while (reclaimSpace(format, width, height, 0));
- qWarning("QVGImagePool: cannot reclaim sufficient space for a %dx%d image",
- width, height);
- return VG_INVALID_HANDLE;
-}
-
-void QVGImagePool::releaseImage(QVGPixmapData *data, VGImage image)
-{
- // Very simple strategy at the moment: just destroy the image.
- if (data)
- removeFromLRU(data);
- vgDestroyImage(image);
-}
-
-void QVGImagePool::useImage(QVGPixmapData *data)
-{
- moveToHeadOfLRU(data);
-}
-
-void QVGImagePool::detachImage(QVGPixmapData *data)
-{
- removeFromLRU(data);
-}
-
-bool QVGImagePool::reclaimSpace(VGImageFormat format,
- VGint width, VGint height,
- QVGPixmapData *data)
-{
- Q_UNUSED(format); // For future use in picking the best image to eject.
- Q_UNUSED(width);
- Q_UNUSED(height);
-
- bool succeeded = false;
- bool wasInLRU = false;
- if (data) {
- wasInLRU = data->inLRU;
- moveToHeadOfLRU(data);
- }
-
- QVGPixmapData *lrudata = pixmapLRU();
- if (lrudata && lrudata != data) {
- lrudata->reclaimImages();
- succeeded = true;
- }
-
- if (data && !wasInLRU)
- removeFromLRU(data);
-
- return succeeded;
-}
-
-void QVGImagePool::hibernate()
-{
- Q_D(QVGImagePool);
- QVGPixmapData *pd = d->lruLast;
- while (pd) {
- QVGPixmapData *prevLRU = pd->prevLRU;
- pd->inImagePool = false;
- pd->inLRU = false;
- pd->nextLRU = 0;
- pd->prevLRU = 0;
- pd->hibernate();
- pd = prevLRU;
- }
- d->lruFirst = 0;
- d->lruLast = 0;
-}
-
-void QVGImagePool::moveToHeadOfLRU(QVGPixmapData *data)
-{
- Q_D(QVGImagePool);
- if (data->inLRU) {
- if (!data->prevLRU)
- return; // Already at the head of the list.
- removeFromLRU(data);
- }
- data->inLRU = true;
- data->nextLRU = d->lruFirst;
- data->prevLRU = 0;
- if (d->lruFirst)
- d->lruFirst->prevLRU = data;
- else
- d->lruLast = data;
- d->lruFirst = data;
-}
-
-void QVGImagePool::removeFromLRU(QVGPixmapData *data)
-{
- Q_D(QVGImagePool);
- if (!data->inLRU)
- return;
- if (data->nextLRU)
- data->nextLRU->prevLRU = data->prevLRU;
- else
- d->lruLast = data->prevLRU;
- if (data->prevLRU)
- data->prevLRU->nextLRU = data->nextLRU;
- else
- d->lruFirst = data->nextLRU;
- data->inLRU = false;
-}
-
-QVGPixmapData *QVGImagePool::pixmapLRU()
-{
- Q_D(QVGImagePool);
- return d->lruLast;
-}
-
-QT_END_NAMESPACE
diff --git a/src/openvg/qvgimagepool_p.h b/src/openvg/qvgimagepool_p.h
deleted file mode 100644
index 07c57bf44a..0000000000
--- a/src/openvg/qvgimagepool_p.h
+++ /dev/null
@@ -1,157 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenVG module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QVGIMAGEPOOL_P_H
-#define QVGIMAGEPOOL_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qvg.h"
-#include <QtCore/qscopedpointer.h>
-
-QT_BEGIN_NAMESPACE
-
-class QVGPixmapData;
-class QVGImagePoolPrivate;
-
-class Q_OPENVG_EXPORT QVGImagePool
-{
-public:
- QVGImagePool();
- virtual ~QVGImagePool();
-
- static QVGImagePool *instance();
-
- // This function can be used from system-specific graphics system
- // plugins to alter the image allocation strategy.
- static void setImagePool(QVGImagePool *pool);
-
- // Create a new VGImage from the pool with the specified parameters
- // that is not associated with a pixmap. The VGImage is returned to
- // the pool when releaseImage() is called.
- //
- // This function will call reclaimSpace() when vgCreateImage() fails.
- //
- // This function is typically called when allocating temporary
- // VGImage's for pixmap filters. The "keepData" object will not
- // be reclaimed if reclaimSpace() needs to be called.
- virtual VGImage createTemporaryImage(VGImageFormat format,
- VGint width, VGint height,
- VGbitfield allowedQuality,
- QVGPixmapData *keepData = 0);
-
- // Create a new VGImage with the specified parameters and associate
- // it with "data". The QVGPixmapData will be notified when the
- // VGImage needs to be reclaimed by the pool.
- //
- // This function will call reclaimSpace() when vgCreateImage() fails.
- virtual VGImage createImageForPixmap(VGImageFormat format,
- VGint width, VGint height,
- VGbitfield allowedQuality,
- QVGPixmapData *data);
-
- // Create a permanent VGImage with the specified parameters.
- // If there is insufficient space for the vgCreateImage call,
- // then this function will call reclaimSpace() and try again.
- //
- // The caller is responsible for calling vgDestroyImage()
- // when it no longer needs the VGImage, as the image is not
- // recorded in the image pool.
- //
- // This function is typically used for pattern brushes where
- // the OpenVG engine is responsible for managing the lifetime
- // of the VGImage, destroying it automatically when the brush
- // is no longer in use.
- virtual VGImage createPermanentImage(VGImageFormat format,
- VGint width, VGint height,
- VGbitfield allowedQuality);
-
- // Release a VGImage that is no longer required.
- virtual void releaseImage(QVGPixmapData *data, VGImage image);
-
- // Notify the pool that a QVGPixmapData object is using
- // an image again. This allows the pool to move the image
- // within a least-recently-used list of QVGPixmapData objects.
- virtual void useImage(QVGPixmapData *data);
-
- // Notify the pool that the VGImage's associated with a
- // QVGPixmapData are being detached from the pool. The caller
- // will become responsible for calling vgDestroyImage().
- virtual void detachImage(QVGPixmapData *data);
-
- // Reclaim space for an image allocation with the specified parameters.
- // Returns true if space was reclaimed, or false if there is no
- // further space that can be reclaimed. The "data" parameter
- // indicates the pixmap that is trying to obtain space which should
- // not itself be reclaimed.
- virtual bool reclaimSpace(VGImageFormat format,
- VGint width, VGint height,
- QVGPixmapData *data);
-
- // Hibernate the image pool because the context is about to be
- // destroyed. All VGImage's left in the pool should be released.
- virtual void hibernate();
-
-protected:
- // Helper functions for managing the LRU list of QVGPixmapData objects.
- void moveToHeadOfLRU(QVGPixmapData *data);
- void removeFromLRU(QVGPixmapData *data);
- QVGPixmapData *pixmapLRU();
-
-private:
- QScopedPointer<QVGImagePoolPrivate> d_ptr;
-
- Q_DECLARE_PRIVATE(QVGImagePool)
- Q_DISABLE_COPY(QVGImagePool)
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/openvg/qwindowsurface_vg.cpp b/src/openvg/qwindowsurface_vg.cpp
deleted file mode 100644
index 778e14c097..0000000000
--- a/src/openvg/qwindowsurface_vg.cpp
+++ /dev/null
@@ -1,148 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenVG module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qwindowsurface_vg_p.h"
-#include "qwindowsurface_vgegl_p.h"
-#include "qpaintengine_vg_p.h"
-#include "qpixmapdata_vg_p.h"
-#include "qvg_p.h"
-
-#if !defined(QT_NO_EGL)
-
-#include <QtGui/private/qeglcontext_p.h>
-#include <QtGui/private/qwidget_p.h>
-
-QT_BEGIN_NAMESPACE
-
-QVGWindowSurface::QVGWindowSurface(QWidget *window)
- : QWindowSurface(window)
-{
- // Create the default type of EGL window surface for windows.
- d_ptr = new QVGEGLWindowSurfaceDirect(this);
-}
-
-QVGWindowSurface::QVGWindowSurface
- (QWidget *window, QVGEGLWindowSurfacePrivate *d)
- : QWindowSurface(window), d_ptr(d)
-{
-}
-
-QVGWindowSurface::~QVGWindowSurface()
-{
- delete d_ptr;
-}
-
-QPaintDevice *QVGWindowSurface::paintDevice()
-{
- return this;
-}
-
-void QVGWindowSurface::flush(QWidget *widget, const QRegion &region, const QPoint &offset)
-{
- Q_UNUSED(offset);
-
-#ifdef Q_OS_SYMBIAN
- if (window() != widget) {
- // For performance reasons we don't support
- // flushing native child widgets on Symbian.
- // It breaks overlapping native child widget
- // rendering in some cases but we prefer performance.
- return;
- }
-#endif
-
- QWidget *parent = widget->internalWinId() ? widget : widget->nativeParentWidget();
- d_ptr->endPaint(parent, region);
-}
-
-void QVGWindowSurface::setGeometry(const QRect &rect)
-{
- QWindowSurface::setGeometry(rect);
-}
-
-bool QVGWindowSurface::scroll(const QRegion &area, int dx, int dy)
-{
- if (!d_ptr->scroll(window(), area, dx, dy))
- return QWindowSurface::scroll(area, dx, dy);
- return true;
-}
-
-void QVGWindowSurface::beginPaint(const QRegion &region)
-{
- d_ptr->beginPaint(window());
-
- // If the window is not opaque, then fill the region we are about
- // to paint with the transparent color.
- if (!qt_widget_private(window())->isOpaque &&
- window()->testAttribute(Qt::WA_TranslucentBackground)) {
- QVGPaintEngine *engine = static_cast<QVGPaintEngine *>
- (d_ptr->paintEngine());
- engine->fillRegion(region, Qt::transparent, d_ptr->surfaceSize());
- }
-}
-
-void QVGWindowSurface::endPaint(const QRegion &region)
-{
- // Nothing to do here.
- Q_UNUSED(region);
-}
-
-QPaintEngine *QVGWindowSurface::paintEngine() const
-{
- return d_ptr->paintEngine();
-}
-
-QWindowSurface::WindowSurfaceFeatures QVGWindowSurface::features() const
-{
- WindowSurfaceFeatures features = PartialUpdates | PreservedContents;
- if (d_ptr->supportsStaticContents())
- features |= StaticContents;
- return features;
-}
-
-int QVGWindowSurface::metric(PaintDeviceMetric met) const
-{
- return qt_paint_device_metric(window(), met);
-}
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/openvg/qwindowsurface_vg_p.h b/src/openvg/qwindowsurface_vg_p.h
deleted file mode 100644
index 4ce73eb99a..0000000000
--- a/src/openvg/qwindowsurface_vg_p.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenVG module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWINDOWSURFACE_VG_P_H
-#define QWINDOWSURFACE_VG_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtGui/private/qwindowsurface_p.h>
-
-QT_BEGIN_NAMESPACE
-
-#if !defined(QT_NO_EGL)
-
-class QVGEGLWindowSurfacePrivate;
-
-class Q_OPENVG_EXPORT QVGWindowSurface : public QWindowSurface, public QPaintDevice
-{
-public:
- QVGWindowSurface(QWidget *window);
- QVGWindowSurface(QWidget *window, QVGEGLWindowSurfacePrivate *d);
- ~QVGWindowSurface();
-
- QPaintDevice *paintDevice();
- void flush(QWidget *widget, const QRegion &region, const QPoint &offset);
- void setGeometry(const QRect &rect);
- bool scroll(const QRegion &area, int dx, int dy);
-
- void beginPaint(const QRegion &region);
- void endPaint(const QRegion &region);
-
- QPaintEngine *paintEngine() const;
-
- WindowSurfaceFeatures features() const;
-
-protected:
- int metric(PaintDeviceMetric metric) const;
-
-private:
- QVGEGLWindowSurfacePrivate *d_ptr;
-};
-
-#endif
-
-QT_END_NAMESPACE
-
-#endif // QWINDOWSURFACE_VG_P_H
diff --git a/src/openvg/qwindowsurface_vgegl.cpp b/src/openvg/qwindowsurface_vgegl.cpp
deleted file mode 100644
index f7961b4a7d..0000000000
--- a/src/openvg/qwindowsurface_vgegl.cpp
+++ /dev/null
@@ -1,783 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenVG module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qwindowsurface_vgegl_p.h"
-#include "qpaintengine_vg_p.h"
-#include "qpixmapdata_vg_p.h"
-#include "qvgimagepool_p.h"
-#include "qvg_p.h"
-
-#if !defined(QT_NO_EGL)
-
-QT_BEGIN_NAMESPACE
-
-// Turn off "direct to window" rendering if EGL cannot support it.
-#if !defined(EGL_RENDER_BUFFER) || !defined(EGL_SINGLE_BUFFER)
-#if defined(QVG_DIRECT_TO_WINDOW)
-#undef QVG_DIRECT_TO_WINDOW
-#endif
-#endif
-
-// Determine if preserved window contents should be used.
-#if !defined(EGL_SWAP_BEHAVIOR) || !defined(EGL_BUFFER_PRESERVED)
-#if !defined(QVG_NO_PRESERVED_SWAP)
-#define QVG_NO_PRESERVED_SWAP 1
-#endif
-#endif
-
-VGImageFormat qt_vg_config_to_vg_format(QEglContext *context)
-{
- return qt_vg_image_to_vg_format
- (qt_vg_config_to_image_format(context));
-}
-
-QImage::Format qt_vg_config_to_image_format(QEglContext *context)
-{
- EGLint red = context->configAttrib(EGL_RED_SIZE);
- EGLint green = context->configAttrib(EGL_GREEN_SIZE);
- EGLint blue = context->configAttrib(EGL_BLUE_SIZE);
- EGLint alpha = context->configAttrib(EGL_ALPHA_SIZE);
- QImage::Format argbFormat;
-#ifdef EGL_VG_ALPHA_FORMAT_PRE_BIT
- EGLint type = context->configAttrib(EGL_SURFACE_TYPE);
- if ((type & EGL_VG_ALPHA_FORMAT_PRE_BIT) != 0)
- argbFormat = QImage::Format_ARGB32_Premultiplied;
- else
- argbFormat = QImage::Format_ARGB32;
-#else
- argbFormat = QImage::Format_ARGB32;
-#endif
- if (red == 8 && green == 8 && blue == 8 && alpha == 8)
- return argbFormat;
- else if (red == 8 && green == 8 && blue == 8 && alpha == 0)
- return QImage::Format_RGB32;
- else if (red == 5 && green == 6 && blue == 5 && alpha == 0)
- return QImage::Format_RGB16;
- else if (red == 4 && green == 4 && blue == 4 && alpha == 4)
- return QImage::Format_ARGB4444_Premultiplied;
- else
- return argbFormat; // XXX
-}
-
-#if !defined(QVG_NO_SINGLE_CONTEXT)
-
-class QVGSharedContext
-{
-public:
- QVGSharedContext();
- ~QVGSharedContext();
-
- QEglContext *context;
- int refCount;
- int widgetRefCount;
- QVGPaintEngine *engine;
- EGLSurface surface;
- QVGPixmapData *firstPixmap;
-};
-
-QVGSharedContext::QVGSharedContext()
- : context(0)
- , refCount(0)
- , widgetRefCount(0)
- , engine(0)
- , surface(EGL_NO_SURFACE)
- , firstPixmap(0)
-{
-}
-
-QVGSharedContext::~QVGSharedContext()
-{
- // Don't accidentally destroy the QEglContext if the reference
- // count falls to zero while deleting the paint engine.
- ++refCount;
-
- if (context)
- context->makeCurrent(qt_vg_shared_surface());
- delete engine;
- if (context)
- context->doneCurrent();
- if (context && surface != EGL_NO_SURFACE)
- context->destroySurface(surface);
- delete context;
-}
-
-Q_GLOBAL_STATIC(QVGSharedContext, sharedContext);
-
-QVGPaintEngine *qt_vg_create_paint_engine(void)
-{
- QVGSharedContext *shared = sharedContext();
- if (!shared->engine)
- shared->engine = new QVGPaintEngine();
- return shared->engine;
-}
-
-void qt_vg_destroy_paint_engine(QVGPaintEngine *engine)
-{
- Q_UNUSED(engine);
-}
-
-void qt_vg_register_pixmap(QVGPixmapData *pd)
-{
- QVGSharedContext *shared = sharedContext();
- pd->next = shared->firstPixmap;
- pd->prev = 0;
- if (shared->firstPixmap)
- shared->firstPixmap->prev = pd;
- shared->firstPixmap = pd;
-}
-
-void qt_vg_unregister_pixmap(QVGPixmapData *pd)
-{
- if (pd->next)
- pd->next->prev = pd->prev;
- if (pd->prev) {
- pd->prev->next = pd->next;
- } else {
- QVGSharedContext *shared = sharedContext();
- if (shared)
- shared->firstPixmap = pd->next;
- }
-}
-
-#else
-
-QVGPaintEngine *qt_vg_create_paint_engine(void)
-{
- return new QVGPaintEngine();
-}
-
-void qt_vg_destroy_paint_engine(QVGPaintEngine *engine)
-{
- delete engine;
-}
-
-void qt_vg_register_pixmap(QVGPixmapData *pd)
-{
- Q_UNUSED(pd);
-}
-
-void qt_vg_unregister_pixmap(QVGPixmapData *pd)
-{
- Q_UNUSED(pd);
-}
-
-#endif
-
-#ifdef EGL_VG_ALPHA_FORMAT_PRE_BIT
-
-static bool isPremultipliedContext(const QEglContext *context)
-{
- return context->configAttrib(EGL_SURFACE_TYPE) & EGL_VG_ALPHA_FORMAT_PRE_BIT;
-}
-
-#endif
-
-static QEglContext *createContext(QPaintDevice *device)
-{
- QEglContext *context;
-
- // Create the context object and open the display.
- context = new QEglContext();
- context->setApi(QEgl::OpenVG);
-
- // Set the swap interval for the display.
- QByteArray interval = qgetenv("QT_VG_SWAP_INTERVAL");
- if (!interval.isEmpty())
- eglSwapInterval(QEgl::display(), interval.toInt());
- else
- eglSwapInterval(QEgl::display(), 1);
-
-#ifdef EGL_RENDERABLE_TYPE
- // Has the user specified an explicit EGL configuration to use?
- QByteArray configId = qgetenv("QT_VG_EGL_CONFIG");
- if (!configId.isEmpty()) {
- EGLint cfgId = configId.toInt();
- EGLint properties[] = {
- EGL_CONFIG_ID, cfgId,
- EGL_NONE
- };
- EGLint matching = 0;
- EGLConfig cfg;
- if (eglChooseConfig
- (QEgl::display(), properties, &cfg, 1, &matching) &&
- matching > 0) {
- // Check that the selected configuration actually supports OpenVG
- // and then create the context with it.
- EGLint id = 0;
- EGLint type = 0;
- eglGetConfigAttrib
- (QEgl::display(), cfg, EGL_CONFIG_ID, &id);
- eglGetConfigAttrib
- (QEgl::display(), cfg, EGL_RENDERABLE_TYPE, &type);
- if (cfgId == id && (type & EGL_OPENVG_BIT) != 0) {
- context->setConfig(cfg);
- if (!context->createContext()) {
- delete context;
- return 0;
- }
- return context;
- } else {
- qWarning("QT_VG_EGL_CONFIG: %d is not a valid OpenVG configuration", int(cfgId));
- }
- }
- }
-#endif
-
- // Choose an appropriate configuration for rendering into the device.
- QEglProperties configProps;
- configProps.setPaintDeviceFormat(device);
- int redSize = configProps.value(EGL_RED_SIZE);
- if (redSize == EGL_DONT_CARE || redSize == 0)
- configProps.setPixelFormat(QImage::Format_ARGB32); // XXX
- configProps.setValue(EGL_ALPHA_MASK_SIZE, 1);
-#ifdef EGL_VG_ALPHA_FORMAT_PRE_BIT
- configProps.setValue(EGL_SURFACE_TYPE, EGL_WINDOW_BIT
- | EGL_SWAP_BEHAVIOR_PRESERVED_BIT
- | EGL_VG_ALPHA_FORMAT_PRE_BIT);
- configProps.setRenderableType(QEgl::OpenVG);
- if (!context->chooseConfig(configProps)) {
- // Try again without the "pre" bit.
- configProps.setValue(EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_SWAP_BEHAVIOR_PRESERVED_BIT);
- if (!context->chooseConfig(configProps)) {
- delete context;
- return 0;
- }
- }
-#else
- configProps.setValue(EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_SWAP_BEHAVIOR_PRESERVED_BIT);
- configProps.setRenderableType(QEgl::OpenVG);
- if (!context->chooseConfig(configProps)) {
- delete context;
- return 0;
- }
-#endif
-
- // Construct a new EGL context for the selected configuration.
- if (!context->createContext()) {
- delete context;
- return 0;
- }
-
- return context;
-}
-
-#if !defined(QVG_NO_SINGLE_CONTEXT)
-
-QEglContext *qt_vg_create_context(QPaintDevice *device, int devType)
-{
- QVGSharedContext *shared = sharedContext();
- if (devType == QInternal::Widget)
- ++(shared->widgetRefCount);
- if (shared->context) {
- ++(shared->refCount);
- return shared->context;
- } else {
- shared->context = createContext(device);
- shared->refCount = 1;
- return shared->context;
- }
-}
-
-static void qt_vg_destroy_shared_context(QVGSharedContext *shared)
-{
- shared->context->makeCurrent(qt_vg_shared_surface());
- delete shared->engine;
- shared->engine = 0;
- shared->context->doneCurrent();
- if (shared->surface != EGL_NO_SURFACE) {
- eglDestroySurface(QEgl::display(), shared->surface);
- shared->surface = EGL_NO_SURFACE;
- }
- delete shared->context;
- shared->context = 0;
-}
-
-void qt_vg_hibernate_pixmaps(QVGSharedContext *shared)
-{
- // Artificially increase the reference count to prevent the
- // context from being destroyed until after we have finished
- // the hibernation process.
- ++(shared->refCount);
-
- // We need a context current to hibernate the VGImage objects.
- shared->context->makeCurrent(qt_vg_shared_surface());
-
- // Scan all QVGPixmapData objects in the system and hibernate them.
- QVGPixmapData *pd = shared->firstPixmap;
- while (pd != 0) {
- pd->hibernate();
- pd = pd->next;
- }
-
- // Hibernate any remaining VGImage's in the image pool.
- QVGImagePool::instance()->hibernate();
-
- // Don't need the current context any more.
- shared->context->lazyDoneCurrent();
-
- // Decrease the reference count and destroy the context if necessary.
- if (--(shared->refCount) <= 0)
- qt_vg_destroy_shared_context(shared);
-}
-
-void qt_vg_destroy_context(QEglContext *context, int devType)
-{
- QVGSharedContext *shared = sharedContext();
- if (shared->context != context) {
- // This is not the shared context. Shouldn't happen!
- delete context;
- return;
- }
- if (devType == QInternal::Widget)
- --(shared->widgetRefCount);
- if (--(shared->refCount) <= 0) {
- qt_vg_destroy_shared_context(shared);
- } else if (shared->widgetRefCount <= 0 && devType == QInternal::Widget) {
- // All of the widget window surfaces have been destroyed
- // but we still have VG pixmaps active. Ask them to hibernate
- // to free up GPU resources until a widget is shown again.
- // This may eventually cause the EGLContext to be destroyed
- // because nothing in the system needs a context, which will
- // free up even more GPU resources.
- qt_vg_hibernate_pixmaps(shared);
- }
-}
-
-EGLSurface qt_vg_shared_surface(void)
-{
- QVGSharedContext *shared = sharedContext();
- if (shared->surface == EGL_NO_SURFACE) {
- EGLint attribs[7];
- attribs[0] = EGL_WIDTH;
- attribs[1] = 16;
- attribs[2] = EGL_HEIGHT;
- attribs[3] = 16;
-#ifdef EGL_VG_ALPHA_FORMAT_PRE_BIT
- if (isPremultipliedContext(shared->context)) {
- attribs[4] = EGL_VG_ALPHA_FORMAT;
- attribs[5] = EGL_VG_ALPHA_FORMAT_PRE;
- attribs[6] = EGL_NONE;
- } else
-#endif
- {
- attribs[4] = EGL_NONE;
- }
- shared->surface = eglCreatePbufferSurface
- (QEgl::display(), shared->context->config(), attribs);
- }
- return shared->surface;
-}
-
-#else
-
-QEglContext *qt_vg_create_context(QPaintDevice *device, int devType)
-{
- Q_UNUSED(devType);
- return createContext(device);
-}
-
-void qt_vg_destroy_context(QEglContext *context, int devType)
-{
- Q_UNUSED(devType);
- delete context;
-}
-
-EGLSurface qt_vg_shared_surface(void)
-{
- return EGL_NO_SURFACE;
-}
-
-#endif
-
-QVGEGLWindowSurfacePrivate::QVGEGLWindowSurfacePrivate(QWindowSurface *win)
-{
- winSurface = win;
- engine = 0;
-}
-
-QVGEGLWindowSurfacePrivate::~QVGEGLWindowSurfacePrivate()
-{
- // Destroy the paint engine if it hasn't been destroyed already.
- destroyPaintEngine();
-}
-
-QVGPaintEngine *QVGEGLWindowSurfacePrivate::paintEngine()
-{
- if (!engine)
- engine = qt_vg_create_paint_engine();
- return engine;
-}
-
-VGImage QVGEGLWindowSurfacePrivate::surfaceImage() const
-{
- return VG_INVALID_HANDLE;
-}
-
-void QVGEGLWindowSurfacePrivate::destroyPaintEngine()
-{
- if (engine) {
- qt_vg_destroy_paint_engine(engine);
- engine = 0;
- }
-}
-
-QSize QVGEGLWindowSurfacePrivate::windowSurfaceSize(QWidget *widget) const
-{
- Q_UNUSED(widget);
-
- QRect rect = winSurface->geometry();
- QSize newSize = rect.size();
-
-#if defined(Q_WS_QWS)
- // Account for the widget mask, if any.
- if (widget && !widget->mask().isEmpty()) {
- const QRegion region = widget->mask()
- & rect.translated(-widget->geometry().topLeft());
- newSize = region.boundingRect().size();
- }
-#endif
-
- return newSize;
-}
-
-#if defined(QVG_VGIMAGE_BACKBUFFERS)
-
-QVGEGLWindowSurfaceVGImage::QVGEGLWindowSurfaceVGImage(QWindowSurface *win)
- : QVGEGLWindowSurfacePrivate(win)
- , context(0)
- , backBuffer(VG_INVALID_HANDLE)
- , backBufferSurface(EGL_NO_SURFACE)
- , recreateBackBuffer(false)
- , isPaintingActive(false)
- , windowSurface(EGL_NO_SURFACE)
-{
-}
-
-QVGEGLWindowSurfaceVGImage::~QVGEGLWindowSurfaceVGImage()
-{
- destroyPaintEngine();
- if (context) {
- if (backBufferSurface != EGL_NO_SURFACE) {
- // We need a current context to be able to destroy the image.
- // We use the shared surface because the native window handle
- // associated with "windowSurface" may have been destroyed already.
- context->makeCurrent(qt_vg_shared_surface());
- context->destroySurface(backBufferSurface);
- vgDestroyImage(backBuffer);
- context->doneCurrent();
- }
- if (windowSurface != EGL_NO_SURFACE)
- context->destroySurface(windowSurface);
- qt_vg_destroy_context(context, QInternal::Widget);
- }
-}
-
-QEglContext *QVGEGLWindowSurfaceVGImage::ensureContext(QWidget *widget)
-{
- QSize newSize = windowSurfaceSize(widget);
- if (context && size != newSize) {
- // The surface size has changed, so we need to recreate
- // the back buffer. Keep the same context and paint engine.
- size = newSize;
- if (isPaintingActive)
- context->doneCurrent();
- isPaintingActive = false;
- recreateBackBuffer = true;
- }
- if (!context) {
- // Create a new EGL context. We create the surface in beginPaint().
- size = newSize;
- context = qt_vg_create_context(widget, QInternal::Widget);
- if (!context)
- return 0;
- isPaintingActive = false;
- }
- return context;
-}
-
-void QVGEGLWindowSurfaceVGImage::beginPaint(QWidget *widget)
-{
- QEglContext *context = ensureContext(widget);
- if (context) {
- if (recreateBackBuffer || backBufferSurface == EGL_NO_SURFACE) {
- // Create a VGImage object to act as the back buffer
- // for this window. We have to create the VGImage with a
- // current context, so activate the main surface for the window.
- context->makeCurrent(mainSurface());
- recreateBackBuffer = false;
- if (backBufferSurface != EGL_NO_SURFACE) {
- eglDestroySurface(QEgl::display(), backBufferSurface);
- backBufferSurface = EGL_NO_SURFACE;
- }
- if (backBuffer != VG_INVALID_HANDLE) {
- vgDestroyImage(backBuffer);
- }
- VGImageFormat format = qt_vg_config_to_vg_format(context);
- backBuffer = vgCreateImage
- (format, size.width(), size.height(),
- VG_IMAGE_QUALITY_FASTER);
- if (backBuffer != VG_INVALID_HANDLE) {
- // Create an EGL surface for rendering into the VGImage.
- backBufferSurface = eglCreatePbufferFromClientBuffer
- (QEgl::display(), EGL_OPENVG_IMAGE,
- (EGLClientBuffer)(backBuffer),
- context->config(), NULL);
- if (backBufferSurface == EGL_NO_SURFACE) {
- vgDestroyImage(backBuffer);
- backBuffer = VG_INVALID_HANDLE;
- }
- }
- }
- if (backBufferSurface != EGL_NO_SURFACE)
- context->makeCurrent(backBufferSurface);
- else
- context->makeCurrent(mainSurface());
- isPaintingActive = true;
- }
-}
-
-void QVGEGLWindowSurfaceVGImage::endPaint
- (QWidget *widget, const QRegion& region, QImage *image)
-{
- Q_UNUSED(region);
- Q_UNUSED(image);
- QEglContext *context = ensureContext(widget);
- if (context) {
- if (backBufferSurface != EGL_NO_SURFACE) {
- if (isPaintingActive)
- vgFlush();
- context->lazyDoneCurrent();
- }
- isPaintingActive = false;
- }
-}
-
-VGImage QVGEGLWindowSurfaceVGImage::surfaceImage() const
-{
- return backBuffer;
-}
-
-EGLSurface QVGEGLWindowSurfaceVGImage::mainSurface() const
-{
- if (windowSurface != EGL_NO_SURFACE)
- return windowSurface;
- else
- return qt_vg_shared_surface();
-}
-
-#endif // QVG_VGIMAGE_BACKBUFFERS
-
-QVGEGLWindowSurfaceDirect::QVGEGLWindowSurfaceDirect(QWindowSurface *win)
- : QVGEGLWindowSurfacePrivate(win)
- , context(0)
- , isPaintingActive(false)
- , needToSwap(false)
- , windowSurface(EGL_NO_SURFACE)
-{
-}
-
-QVGEGLWindowSurfaceDirect::~QVGEGLWindowSurfaceDirect()
-{
- destroyPaintEngine();
- if (context) {
- if (windowSurface != EGL_NO_SURFACE)
- context->destroySurface(windowSurface);
- qt_vg_destroy_context(context, QInternal::Widget);
- }
-}
-
-QEglContext *QVGEGLWindowSurfaceDirect::ensureContext(QWidget *widget)
-{
- QSize newSize = windowSurfaceSize(widget);
- QEglProperties surfaceProps;
-
-#if defined(QVG_RECREATE_ON_SIZE_CHANGE)
-#if !defined(QVG_NO_SINGLE_CONTEXT)
- if (context && size != newSize) {
- // The surface size has changed, so we need to recreate it.
- // We can keep the same context and paint engine.
- size = newSize;
- if (isPaintingActive)
- context->doneCurrent();
- context->destroySurface(windowSurface);
-#if defined(EGL_VG_ALPHA_FORMAT_PRE_BIT)
- if (isPremultipliedContext(context)) {
- surfaceProps.setValue
- (EGL_VG_ALPHA_FORMAT, EGL_VG_ALPHA_FORMAT_PRE);
- } else {
- surfaceProps.removeValue(EGL_VG_ALPHA_FORMAT);
- }
-#endif
- windowSurface = context->createSurface(widget, &surfaceProps);
- isPaintingActive = false;
- needToSwap = true;
- }
-#else
- if (context && size != newSize) {
- // The surface size has changed, so we need to recreate
- // the EGL context for the widget. We also need to recreate
- // the surface's paint engine if context sharing is not
- // enabled because we cannot reuse the existing paint objects
- // in the new context.
- qt_vg_destroy_paint_engine(engine);
- engine = 0;
- context->destroySurface(windowSurface);
- qt_vg_destroy_context(context, QInternal::Widget);
- context = 0;
- windowSurface = EGL_NO_SURFACE;
- }
-#endif
-#endif
- if (!context) {
- // Create a new EGL context and bind it to the widget surface.
- size = newSize;
- context = qt_vg_create_context(widget, QInternal::Widget);
- if (!context)
- return 0;
- // We want a direct to window rendering surface if possible.
-#if defined(QVG_DIRECT_TO_WINDOW)
- surfaceProps.setValue(EGL_RENDER_BUFFER, EGL_SINGLE_BUFFER);
-#endif
-#if defined(EGL_VG_ALPHA_FORMAT_PRE_BIT)
- if (isPremultipliedContext(context)) {
- surfaceProps.setValue
- (EGL_VG_ALPHA_FORMAT, EGL_VG_ALPHA_FORMAT_PRE);
- } else {
- surfaceProps.removeValue(EGL_VG_ALPHA_FORMAT);
- }
-#endif
- EGLSurface surface = context->createSurface(widget, &surfaceProps);
- if (surface == EGL_NO_SURFACE) {
- qt_vg_destroy_context(context, QInternal::Widget);
- context = 0;
- return 0;
- }
- needToSwap = true;
-#if defined(QVG_DIRECT_TO_WINDOW)
- // Did we get a direct to window rendering surface?
- EGLint buffer = 0;
- if (eglQueryContext(QEgl::display(), context->context(),
- EGL_RENDER_BUFFER, &buffer) &&
- buffer == EGL_SINGLE_BUFFER) {
- needToSwap = false;
- }
-#endif
- windowSurface = surface;
- isPaintingActive = false;
- }
-
-#if !defined(QVG_NO_PRESERVED_SWAP)
- // Try to force the surface back buffer to preserve its contents.
- if (needToSwap) {
- bool succeeded = eglSurfaceAttrib(QEgl::display(), windowSurface,
- EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED);
- if (!succeeded && eglGetError() != EGL_SUCCESS) {
- qWarning("QVG: could not enable preserved swap");
- }
- }
-#endif
- return context;
-}
-
-void QVGEGLWindowSurfaceDirect::beginPaint(QWidget *widget)
-{
- QEglContext *context = ensureContext(widget);
- if (context) {
- context->makeCurrent(windowSurface);
- isPaintingActive = true;
- }
-}
-
-void QVGEGLWindowSurfaceDirect::endPaint
- (QWidget *widget, const QRegion& region, QImage *image)
-{
- Q_UNUSED(region);
- Q_UNUSED(image);
- QEglContext *context = ensureContext(widget);
- if (context) {
- if (needToSwap) {
- if (!isPaintingActive)
- context->makeCurrent(windowSurface);
- context->swapBuffers(windowSurface);
- context->lazyDoneCurrent();
- } else if (isPaintingActive) {
- vgFlush();
- context->lazyDoneCurrent();
- }
- isPaintingActive = false;
- }
-}
-
-bool QVGEGLWindowSurfaceDirect::supportsStaticContents() const
-{
-#if defined(QVG_BUFFER_SCROLLING) && !defined(QVG_NO_PRESERVED_SWAP)
- return true;
-#else
- return QVGEGLWindowSurfacePrivate::supportsStaticContents();
-#endif
-}
-
-bool QVGEGLWindowSurfaceDirect::scroll(QWidget *widget, const QRegion& area, int dx, int dy)
-{
-#ifdef QVG_BUFFER_SCROLLING
- QEglContext *context = ensureContext(widget);
- if (context) {
- context->makeCurrent(windowSurface);
- QRect scrollRect = area.boundingRect();
- int sx = scrollRect.x();
- int sy = size.height() - scrollRect.y() - scrollRect.height();
- vgSeti(VG_SCISSORING, VG_FALSE);
- vgCopyPixels(sx + dx, sy - dy, sx, sy, scrollRect.width(), scrollRect.height());
- context->lazyDoneCurrent();
- return true;
- }
-#else
- Q_UNUSED(widget);
- Q_UNUSED(area);
- Q_UNUSED(dx);
- Q_UNUSED(dy);
-#endif
- return false;
-}
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/openvg/qwindowsurface_vgegl_p.h b/src/openvg/qwindowsurface_vgegl_p.h
deleted file mode 100644
index 231c5488a9..0000000000
--- a/src/openvg/qwindowsurface_vgegl_p.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenVG module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWINDOWSURFACE_VGEGL_P_H
-#define QWINDOWSURFACE_VGEGL_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of the QLibrary class. This header file may change from
-// version to version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtGui/private/qwindowsurface_p.h>
-#include "qvg_p.h"
-
-#if !defined(QT_NO_EGL)
-
-#include <QtGui/private/qeglcontext_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QWindowSurface;
-
-class Q_OPENVG_EXPORT QVGEGLWindowSurfacePrivate
-{
-public:
- QVGEGLWindowSurfacePrivate(QWindowSurface *win);
- virtual ~QVGEGLWindowSurfacePrivate();
-
- QVGPaintEngine *paintEngine();
- virtual QEglContext *ensureContext(QWidget *widget) = 0;
- virtual void beginPaint(QWidget *widget) = 0;
- virtual void endPaint
- (QWidget *widget, const QRegion& region, QImage *image = 0) = 0;
- virtual VGImage surfaceImage() const;
- virtual QSize surfaceSize() const = 0;
- virtual bool supportsStaticContents() const { return false; }
- virtual bool scroll(QWidget *, const QRegion&, int, int) { return false; }
-
-private:
- QVGPaintEngine *engine;
-
-protected:
- QWindowSurface *winSurface;
-
- void destroyPaintEngine();
- QSize windowSurfaceSize(QWidget *widget) const;
-};
-
-#if defined(EGL_OPENVG_IMAGE) && !defined(QVG_NO_SINGLE_CONTEXT)
-
-#define QVG_VGIMAGE_BACKBUFFERS 1
-
-class Q_OPENVG_EXPORT QVGEGLWindowSurfaceVGImage : public QVGEGLWindowSurfacePrivate
-{
-public:
- QVGEGLWindowSurfaceVGImage(QWindowSurface *win);
- virtual ~QVGEGLWindowSurfaceVGImage();
-
- QEglContext *ensureContext(QWidget *widget);
- void beginPaint(QWidget *widget);
- void endPaint(QWidget *widget, const QRegion& region, QImage *image);
- VGImage surfaceImage() const;
- QSize surfaceSize() const { return size; }
-
-protected:
- QEglContext *context;
- VGImage backBuffer;
- EGLSurface backBufferSurface;
- bool recreateBackBuffer;
- bool isPaintingActive;
- QSize size;
- EGLSurface windowSurface;
-
- EGLSurface mainSurface() const;
-};
-
-#endif // EGL_OPENVG_IMAGE
-
-class Q_OPENVG_EXPORT QVGEGLWindowSurfaceDirect : public QVGEGLWindowSurfacePrivate
-{
-public:
- QVGEGLWindowSurfaceDirect(QWindowSurface *win);
- virtual ~QVGEGLWindowSurfaceDirect();
-
- QEglContext *ensureContext(QWidget *widget);
- void beginPaint(QWidget *widget);
- void endPaint(QWidget *widget, const QRegion& region, QImage *image);
- QSize surfaceSize() const { return size; }
- bool supportsStaticContents() const;
- bool scroll(QWidget *widget, const QRegion& area, int dx, int dy);
-
-protected:
- QEglContext *context;
- QSize size;
- bool isPaintingActive;
- bool needToSwap;
- EGLSurface windowSurface;
-};
-
-QT_END_NAMESPACE
-
-#endif // !QT_NO_EGL
-
-#endif // QWINDOWSURFACE_VGEGL_P_H
diff --git a/src/platformsupport/cglconvenience/cglconvenience.mm b/src/platformsupport/cglconvenience/cglconvenience.mm
new file mode 100644
index 0000000000..6b0354834d
--- /dev/null
+++ b/src/platformsupport/cglconvenience/cglconvenience.mm
@@ -0,0 +1,108 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "cglconvenience_p.h"
+#include <QtCore/private/qcore_mac_p.h>
+#include <Cocoa/Cocoa.h>
+
+void (*qcgl_getProcAddress(const QByteArray &procName))()
+{
+ CFURLRef url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
+ CFSTR("/System/Library/Frameworks/OpenGL.framework"), kCFURLPOSIXPathStyle, false);
+ CFBundleRef bundle = CFBundleCreate(kCFAllocatorDefault, url);
+ CFStringRef procNameCF = QCFString::toCFStringRef(QString::fromAscii(procName.constData()));
+ void *proc = CFBundleGetFunctionPointerForName(bundle, procNameCF);
+ CFRelease(url);
+ CFRelease(bundle);
+ CFRelease(procNameCF);
+ return (void (*) ())proc;
+}
+
+// Match up with createNSOpenGLPixelFormat below!
+QSurfaceFormat qcgl_surfaceFormat()
+{
+ QSurfaceFormat format;
+ format.setRedBufferSize(8);
+ format.setGreenBufferSize(8);
+ format.setBlueBufferSize(8);
+ format.setAlphaBufferSize(8);
+/*
+ format.setDepthBufferSize(24);
+ format.setAccumBufferSize(0);
+ format.setStencilBufferSize(8);
+ format.setSampleBuffers(false);
+ format.setSamples(1);
+ format.setDepth(true);
+ format.setRgba(true);
+ format.setAlpha(true);
+ format.setAccum(false);
+ format.setStencil(true);
+ format.setStereo(false);
+ format.setDirectRendering(false);
+*/
+ return format;
+}
+
+void *qcgl_createNSOpenGLPixelFormat()
+{
+ NSOpenGLPixelFormatAttribute attrs[] =
+ {
+ NSOpenGLPFADoubleBuffer,
+ NSOpenGLPFADepthSize, 32,
+ NSOpenGLPFAMultisample,
+ NSOpenGLPFASampleBuffers, (NSOpenGLPixelFormatAttribute)1,
+ NSOpenGLPFASamples, (NSOpenGLPixelFormatAttribute) 8,
+ 0
+ };
+
+ NSOpenGLPixelFormat* pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs];
+ return pixelFormat;
+}
+
+CGLContextObj qcgl_createGlContext()
+{
+ CGLContextObj context;
+ NSOpenGLPixelFormat *format = reinterpret_cast<NSOpenGLPixelFormat *>(qcgl_createNSOpenGLPixelFormat());
+ CGLPixelFormatObj cglFormat = static_cast<CGLPixelFormatObj>([format CGLPixelFormatObj]);
+ CGLCreateContext(cglFormat ,NULL, &context);
+ return context;
+}
+
diff --git a/src/platformsupport/cglconvenience/cglconvenience.pri b/src/platformsupport/cglconvenience/cglconvenience.pri
new file mode 100644
index 0000000000..fef3b50ea3
--- /dev/null
+++ b/src/platformsupport/cglconvenience/cglconvenience.pri
@@ -0,0 +1,11 @@
+mac {
+ INCLUDEPATH += $$PWD
+
+ HEADERS += \
+ $$PWD/cglconvenience_p.h
+
+ OBJECTIVE_SOURCES += \
+ $$PWD/cglconvenience.mm
+
+ LIBS += -framework Cocoa -framework OpenGl
+}
diff --git a/src/platformsupport/cglconvenience/cglconvenience_p.h b/src/platformsupport/cglconvenience/cglconvenience_p.h
new file mode 100644
index 0000000000..96433b69d0
--- /dev/null
+++ b/src/platformsupport/cglconvenience/cglconvenience_p.h
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMACGLCONVENIENCE_H
+#define QMACGLCONVENIENCE_H
+
+#include <QSurfaceFormat>
+#include <QString>
+#include <OpenGL/OpenGL.h>
+
+void (*qcgl_getProcAddress(const QByteArray &procName))();
+QSurfaceFormat qcgl_surfaceFormat();
+void *qcgl_createNSOpenGLPixelFormat();
+CGLContextObj qcgl_createGlContext();
+
+#endif // QMACGLCONVENIENCE_H
diff --git a/src/platformsupport/dnd/dnd.pri b/src/platformsupport/dnd/dnd.pri
new file mode 100644
index 0000000000..e100dd10cb
--- /dev/null
+++ b/src/platformsupport/dnd/dnd.pri
@@ -0,0 +1,4 @@
+HEADERS += \
+ $$PWD/qsimpledrag_p.h
+SOURCES += \
+ $$PWD/qsimpledrag.cpp
diff --git a/src/platformsupport/dnd/qsimpledrag.cpp b/src/platformsupport/dnd/qsimpledrag.cpp
new file mode 100644
index 0000000000..72da29c063
--- /dev/null
+++ b/src/platformsupport/dnd/qsimpledrag.cpp
@@ -0,0 +1,202 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qsimpledrag_p.h"
+
+#include "qbitmap.h"
+#include "qdrag.h"
+#include "qpixmap.h"
+#include "qevent.h"
+#include "qfile.h"
+#include "qtextcodec.h"
+#include "qguiapplication.h"
+#include "qpoint.h"
+#include "qbuffer.h"
+#include "qimage.h"
+#include "qregexp.h"
+#include "qdir.h"
+#include "qimagereader.h"
+#include "qimagewriter.h"
+
+#include <private/qguiapplication_p.h>
+#include <private/qdnd_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QDropData : public QInternalMimeData
+{
+public:
+ QDropData();
+ ~QDropData();
+
+protected:
+ bool hasFormat_sys(const QString &mimeType) const;
+ QStringList formats_sys() const;
+ QVariant retrieveData_sys(const QString &mimeType, QVariant::Type type) const;
+};
+
+QSimpleDrag::QSimpleDrag()
+{
+ m_dropData = new QDropData();
+ currentWindow = 0;
+}
+
+QSimpleDrag::~QSimpleDrag()
+{
+ delete m_dropData;
+}
+
+QMimeData *QSimpleDrag::platformDropData()
+{
+ return m_dropData;
+}
+
+void QSimpleDrag::cancel()
+{
+ QDragManager *m = QDragManager::self();
+// qDebug("QDragManager::cancel");
+ if (m->object->target()) {
+ QDragLeaveEvent dle;
+ QCoreApplication::sendEvent(m->object->target(), &dle);
+ }
+
+}
+
+void QSimpleDrag::move(const QMouseEvent *me)
+{
+ QWindow *window = QGuiApplication::topLevelAt(me->globalPos());
+ QPoint pos;
+ if (window)
+ pos = me->globalPos() - window->geometry().topLeft();
+
+ QDragManager *m = QDragManager::self();
+
+ if (me->buttons()) {
+ Qt::DropAction prevAction = m->global_accepted_action;
+
+ if (currentWindow != window) {
+ if (currentWindow) {
+ QDragLeaveEvent dle;
+ QCoreApplication::sendEvent(currentWindow, &dle);
+ m->willDrop = false;
+ m->global_accepted_action = Qt::IgnoreAction;
+ }
+ currentWindow = window;
+ if (currentWindow) {
+ QDragEnterEvent dee(pos, m->possible_actions, m->dropData(), me->buttons(), me->modifiers());
+ QCoreApplication::sendEvent(currentWindow, &dee);
+ m->willDrop = dee.isAccepted() && dee.dropAction() != Qt::IgnoreAction;
+ m->global_accepted_action = m->willDrop ? dee.dropAction() : Qt::IgnoreAction;
+ }
+ m->updateCursor();
+ } else if (window) {
+ Q_ASSERT(currentWindow);
+ QDragMoveEvent dme(pos, m->possible_actions, m->dropData(), me->buttons(), me->modifiers());
+ if (m->global_accepted_action != Qt::IgnoreAction) {
+ dme.setDropAction(m->global_accepted_action);
+ dme.accept();
+ }
+ QCoreApplication::sendEvent(currentWindow, &dme);
+ m->willDrop = dme.isAccepted();
+ m->global_accepted_action = m->willDrop ? dme.dropAction() : Qt::IgnoreAction;
+ m->updatePixmap();
+ m->updateCursor();
+ }
+ if (m->global_accepted_action != prevAction)
+ m->emitActionChanged(m->global_accepted_action);
+ }
+}
+
+void QSimpleDrag::drop(const QMouseEvent *me)
+{
+ QDragManager *m = QDragManager::self();
+
+ QWindow *window = QGuiApplication::topLevelAt(me->globalPos());
+
+ if (window) {
+ QPoint pos = me->globalPos() - window->geometry().topLeft();
+
+ QDropEvent de(pos, m->possible_actions, m->dropData(), me->buttons(), me->modifiers());
+ QCoreApplication::sendEvent(window, &de);
+ if (de.isAccepted())
+ m->global_accepted_action = de.dropAction();
+ else
+ m->global_accepted_action = Qt::IgnoreAction;
+ }
+ currentWindow = 0;
+}
+
+
+
+QDropData::QDropData()
+ : QInternalMimeData()
+{
+}
+
+QDropData::~QDropData()
+{
+}
+
+QVariant QDropData::retrieveData_sys(const QString &mimetype, QVariant::Type type) const
+{
+ QDrag *object = QDragManager::self()->object;
+ if (!object)
+ return QVariant();
+ QByteArray data = object->mimeData()->data(mimetype);
+ if (type == QVariant::String)
+ return QString::fromUtf8(data);
+ return data;
+}
+
+bool QDropData::hasFormat_sys(const QString &format) const
+{
+ return formats().contains(format);
+}
+
+QStringList QDropData::formats_sys() const
+{
+ QDrag *object = QDragManager::self()->object;
+ if (object)
+ return object->mimeData()->formats();
+ return QStringList();
+}
+
+QT_END_NAMESPACE
diff --git a/src/platformsupport/dnd/qsimpledrag_p.h b/src/platformsupport/dnd/qsimpledrag_p.h
new file mode 100644
index 0000000000..82668a68c9
--- /dev/null
+++ b/src/platformsupport/dnd/qsimpledrag_p.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSIMPLEDRAG_H
+#define QSIMPLEDRAG_H
+
+#include <qplatformdrag_qpa.h>
+
+QT_BEGIN_NAMESPACE
+
+class QMouseEvent;
+class QWindow;
+
+class QDropData;
+
+class QSimpleDrag : public QPlatformDrag
+{
+public:
+ QSimpleDrag();
+ ~QSimpleDrag();
+
+ virtual QMimeData *platformDropData();
+
+// virtual Qt::DropAction drag(QDrag *);
+
+ virtual void cancel();
+ virtual void move(const QMouseEvent *me);
+ virtual void drop(const QMouseEvent *me);
+private:
+ QDropData *m_dropData;
+
+ QWindow *currentWindow;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/platformsupport/eglconvenience/eglconvenience.pri b/src/platformsupport/eglconvenience/eglconvenience.pri
new file mode 100644
index 0000000000..868e12c02d
--- /dev/null
+++ b/src/platformsupport/eglconvenience/eglconvenience.pri
@@ -0,0 +1,16 @@
+contains(QT_CONFIG,opengles2) {
+ CONFIG += opengl
+ HEADERS += \
+ $$PWD/qeglconvenience_p.h \
+ $$PWD/qeglplatformcontext_p.h
+ SOURCES += \
+ $$PWD/qeglconvenience.cpp \
+ $$PWD/qeglplatformcontext.cpp
+
+ contains(QT_CONFIG,xlib) {
+ HEADERS += \
+ $$PWD/qxlibeglintegration_p.h
+ SOURCES += \
+ $$PWD/qxlibeglintegration.cpp
+ }
+}
diff --git a/src/platformsupport/eglconvenience/qeglconvenience.cpp b/src/platformsupport/eglconvenience/qeglconvenience.cpp
new file mode 100644
index 0000000000..bb2613e05b
--- /dev/null
+++ b/src/platformsupport/eglconvenience/qeglconvenience.cpp
@@ -0,0 +1,313 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QByteArray>
+
+#include "qeglconvenience_p.h"
+
+QT_BEGIN_NAMESPACE
+
+QVector<EGLint> q_createConfigAttributesFromFormat(const QSurfaceFormat &format)
+{
+ int redSize = format.redBufferSize();
+ int greenSize = format.greenBufferSize();
+ int blueSize = format.blueBufferSize();
+ int alphaSize = format.alphaBufferSize();
+ int depthSize = format.depthBufferSize();
+ int stencilSize = format.stencilBufferSize();
+ int sampleCount = format.samples();
+
+ // We want to make sure 16-bit configs are chosen over 32-bit configs as they will provide
+ // the best performance. The EGL config selection algorithm is a bit stange in this regard:
+ // The selection criteria for EGL_BUFFER_SIZE is "AtLeast", so we can't use it to discard
+ // 32-bit configs completely from the selection. So it then comes to the sorting algorithm.
+ // The red/green/blue sizes have a sort priority of 3, so they are sorted by first. The sort
+ // order is special and described as "by larger _total_ number of color bits.". So EGL will
+ // put 32-bit configs in the list before the 16-bit configs. However, the spec also goes on
+ // to say "If the requested number of bits in attrib_list for a particular component is 0,
+ // then the number of bits for that component is not considered". This part of the spec also
+ // seems to imply that setting the red/green/blue bits to zero means none of the components
+ // are considered and EGL disregards the entire sorting rule. It then looks to the next
+ // highest priority rule, which is EGL_BUFFER_SIZE. Despite the selection criteria being
+ // "AtLeast" for EGL_BUFFER_SIZE, it's sort order is "smaller" meaning 16-bit configs are
+ // put in the list before 32-bit configs. So, to make sure 16-bit is preffered over 32-bit,
+ // we must set the red/green/blue sizes to zero. This has an unfortunate consequence that
+ // if the application sets the red/green/blue size to 5/6/5 on the QSurfaceFormat,
+ // they will probably get a 32-bit config, even when there's an RGB565 config available.
+
+// // Now normalize the values so -1 becomes 0
+// redSize = redSize > 0 ? redSize : 0;
+// greenSize = greenSize > 0 ? greenSize : 0;
+// blueSize = blueSize > 0 ? blueSize : 0;
+// alphaSize = alphaSize > 0 ? alphaSize : 0;
+// depthSize = depthSize > 0 ? depthSize : 0;
+// stencilSize = stencilSize > 0 ? stencilSize : 0;
+// sampleCount = sampleCount > 0 ? sampleCount : 0;
+
+ QVector<EGLint> configAttributes;
+
+ configAttributes.append(EGL_RED_SIZE);
+ configAttributes.append(redSize > 0 ? redSize : 0);
+
+ configAttributes.append(EGL_GREEN_SIZE);
+ configAttributes.append(greenSize > 0 ? greenSize : 0);
+
+ configAttributes.append(EGL_BLUE_SIZE);
+ configAttributes.append(blueSize > 0 ? blueSize : 0);
+
+ configAttributes.append(EGL_ALPHA_SIZE);
+ configAttributes.append(alphaSize > 0 ? alphaSize : 0);
+
+ configAttributes.append(EGL_DEPTH_SIZE);
+ configAttributes.append(depthSize > 0 ? depthSize : 0);
+
+ configAttributes.append(EGL_STENCIL_SIZE);
+ configAttributes.append(stencilSize > 0 ? stencilSize : 0);
+
+ configAttributes.append(EGL_SAMPLES);
+ configAttributes.append(sampleCount > 0 ? sampleCount : 0);
+
+ configAttributes.append(EGL_SAMPLE_BUFFERS);
+ configAttributes.append(sampleCount > 0);
+
+ return configAttributes;
+}
+
+bool q_reduceConfigAttributes(QVector<EGLint> *configAttributes)
+{
+ int i = -1;
+ // Reduce the complexity of a configuration request to ask for less
+ // because the previous request did not result in success. Returns
+ // true if the complexity was reduced, or false if no further
+ // reductions in complexity are possible.
+
+ i = configAttributes->indexOf(EGL_SWAP_BEHAVIOR);
+ if (i >= 0) {
+ configAttributes->remove(i,2);
+ }
+
+#ifdef EGL_VG_ALPHA_FORMAT_PRE_BIT
+ // For OpenVG, we sometimes try to create a surface using a pre-multiplied format. If we can't
+ // find a config which supports pre-multiplied formats, remove the flag on the surface type:
+
+ i = configAttributes->indexOf(EGL_SURFACE_TYPE);
+ if (i >= 0) {
+ EGLint surfaceType = configAttributes->at(i +1);
+ if (surfaceType & EGL_VG_ALPHA_FORMAT_PRE_BIT) {
+ surfaceType ^= EGL_VG_ALPHA_FORMAT_PRE_BIT;
+ configAttributes->replace(i+1,surfaceType);
+ return true;
+ }
+ }
+#endif
+
+ // EGL chooses configs with the highest color depth over
+ // those with smaller (but faster) lower color depths. One
+ // way around this is to set EGL_BUFFER_SIZE to 16, which
+ // trumps the others. Of course, there may not be a 16-bit
+ // config available, so it's the first restraint we remove.
+ i = configAttributes->indexOf(EGL_BUFFER_SIZE);
+ if (i >= 0) {
+ if (configAttributes->at(i+1) == 16) {
+ configAttributes->remove(i,2);
+ return true;
+ }
+ }
+
+ i = configAttributes->indexOf(EGL_SAMPLE_BUFFERS);
+ if (i >= 0) {
+ configAttributes->remove(i,2);
+ i = configAttributes->indexOf(EGL_SAMPLES);
+ if (i >= 0) {
+ configAttributes->remove(i,2);
+ }
+ return true;
+ }
+
+ i = configAttributes->indexOf(EGL_ALPHA_SIZE);
+ if (i >= 0) {
+ configAttributes->remove(i,2);
+#if defined(EGL_BIND_TO_TEXTURE_RGBA) && defined(EGL_BIND_TO_TEXTURE_RGB)
+ i = configAttributes->indexOf(EGL_BIND_TO_TEXTURE_RGBA);
+ if (i >= 0) {
+ configAttributes->replace(i,EGL_BIND_TO_TEXTURE_RGB);
+ configAttributes->replace(i+1,TRUE);
+
+ }
+#endif
+ return true;
+ }
+
+ i = configAttributes->indexOf(EGL_STENCIL_SIZE);
+ if (i >= 0) {
+ if (configAttributes->at(i + 1) > 1)
+ configAttributes->replace(i + 1, 1);
+ else
+ configAttributes->remove(i, 2);
+ return true;
+ }
+
+ i = configAttributes->indexOf(EGL_DEPTH_SIZE);
+ if (i >= 0) {
+ if (configAttributes->at(i + 1) > 1)
+ configAttributes->replace(i + 1, 1);
+ else
+ configAttributes->remove(i, 2);
+ return true;
+ }
+#ifdef EGL_BIND_TO_TEXTURE_RGB
+ i = configAttributes->indexOf(EGL_BIND_TO_TEXTURE_RGB);
+ if (i >= 0) {
+ configAttributes->remove(i,2);
+ return true;
+ }
+#endif
+
+ return false;
+}
+
+EGLConfig q_configFromGLFormat(EGLDisplay display, const QSurfaceFormat &format, bool highestPixelFormat, int surfaceType)
+{
+ EGLConfig cfg = 0;
+ QVector<EGLint> configureAttributes = q_createConfigAttributesFromFormat(format);
+ configureAttributes.append(EGL_SURFACE_TYPE); //we only support eglconfigs for windows for now
+ configureAttributes.append(surfaceType);
+
+ configureAttributes.append(EGL_RENDERABLE_TYPE);
+ configureAttributes.append(EGL_OPENGL_ES2_BIT);
+ configureAttributes.append(EGL_NONE);
+
+ do {
+ // Get the number of matching configurations for this set of properties.
+ EGLint matching = 0;
+ if (!eglChooseConfig(display, configureAttributes.constData(), 0, 0, &matching) || !matching)
+ continue;
+
+ // If we want the best pixel format, then return the first
+ // matching configuration.
+ if (highestPixelFormat) {
+ eglChooseConfig(display, configureAttributes.constData(), &cfg, 1, &matching);
+ if (matching < 1)
+ continue;
+ return cfg;
+ }
+
+ // Fetch all of the matching configurations and find the
+ // first that matches the pixel format we wanted.
+ int i = configureAttributes.indexOf(EGL_RED_SIZE);
+ int confAttrRed = configureAttributes.at(i+1);
+ i = configureAttributes.indexOf(EGL_GREEN_SIZE);
+ int confAttrGreen = configureAttributes.at(i+1);
+ i = configureAttributes.indexOf(EGL_BLUE_SIZE);
+ int confAttrBlue = configureAttributes.at(i+1);
+ i = configureAttributes.indexOf(EGL_ALPHA_SIZE);
+ int confAttrAlpha = i == -1 ? 0 : configureAttributes.at(i+1);
+
+ EGLint size = matching;
+ EGLConfig *configs = new EGLConfig [size];
+ eglChooseConfig(display, configureAttributes.constData(), configs, size, &matching);
+ for (EGLint index = 0; index < size; ++index) {
+ EGLint red, green, blue, alpha;
+ eglGetConfigAttrib(display, configs[index], EGL_RED_SIZE, &red);
+ eglGetConfigAttrib(display, configs[index], EGL_GREEN_SIZE, &green);
+ eglGetConfigAttrib(display, configs[index], EGL_BLUE_SIZE, &blue);
+ eglGetConfigAttrib(display, configs[index], EGL_ALPHA_SIZE, &alpha);
+ if (red == confAttrRed &&
+ green == confAttrGreen &&
+ blue == confAttrBlue &&
+ (confAttrAlpha == 0 ||
+ alpha == confAttrAlpha)) {
+ cfg = configs[index];
+ delete [] configs;
+ return cfg;
+ }
+ }
+ delete [] configs;
+ } while (q_reduceConfigAttributes(&configureAttributes));
+ qWarning("Cant find EGLConfig, returning null config");
+ return 0;
+}
+
+QSurfaceFormat q_glFormatFromConfig(EGLDisplay display, const EGLConfig config)
+{
+ QSurfaceFormat format;
+ EGLint redSize = 0;
+ EGLint greenSize = 0;
+ EGLint blueSize = 0;
+ EGLint alphaSize = 0;
+ EGLint depthSize = 0;
+ EGLint stencilSize = 0;
+ EGLint sampleCount = 0;
+
+ eglGetConfigAttrib(display, config, EGL_RED_SIZE, &redSize);
+ eglGetConfigAttrib(display, config, EGL_GREEN_SIZE, &greenSize);
+ eglGetConfigAttrib(display, config, EGL_BLUE_SIZE, &blueSize);
+ eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &alphaSize);
+ eglGetConfigAttrib(display, config, EGL_DEPTH_SIZE, &depthSize);
+ eglGetConfigAttrib(display, config, EGL_STENCIL_SIZE, &stencilSize);
+ eglGetConfigAttrib(display, config, EGL_SAMPLES, &sampleCount);
+
+ format.setRedBufferSize(redSize);
+ format.setGreenBufferSize(greenSize);
+ format.setBlueBufferSize(blueSize);
+ format.setAlphaBufferSize(alphaSize);
+ format.setDepthBufferSize(depthSize);
+ format.setStencilBufferSize(stencilSize);
+ format.setSamples(sampleCount);
+ format.setStereo(false); // EGL doesn't support stereo buffers
+
+ // Clear the EGL error state because some of the above may
+ // have errored out because the attribute is not applicable
+ // to the surface type. Such errors don't matter.
+ eglGetError();
+
+ return format;
+}
+
+bool q_hasEglExtension(EGLDisplay display, const char* extensionName)
+{
+ QList<QByteArray> extensions =
+ QByteArray(reinterpret_cast<const char *>
+ (eglQueryString(display, EGL_EXTENSIONS))).split(' ');
+ return extensions.contains(extensionName);
+}
+
+QT_END_NAMESPACE
diff --git a/src/platformsupport/eglconvenience/qeglconvenience_p.h b/src/platformsupport/eglconvenience/qeglconvenience_p.h
new file mode 100644
index 0000000000..7b5b970415
--- /dev/null
+++ b/src/platformsupport/eglconvenience/qeglconvenience_p.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QEGLCONVENIENCE_H
+#define QEGLCONVENIENCE_H
+
+
+#include <QtGui/QSurfaceFormat>
+#include <QtCore/QVector>
+
+#include <EGL/egl.h>
+QT_BEGIN_NAMESPACE
+
+QVector<EGLint> q_createConfigAttributesFromFormat(const QSurfaceFormat &format);
+bool q_reduceConfigAttributes(QVector<EGLint> *configAttributes);
+EGLConfig q_configFromGLFormat(EGLDisplay display, const QSurfaceFormat &format, bool highestPixelFormat = false, int surfaceType = EGL_WINDOW_BIT);
+QSurfaceFormat q_glFormatFromConfig(EGLDisplay display, const EGLConfig config);
+bool q_hasEglExtension(EGLDisplay display,const char* extensionName);
+
+QT_END_NAMESPACE
+
+#endif //QEGLCONVENIENCE_H
diff --git a/src/platformsupport/eglconvenience/qeglplatformcontext.cpp b/src/platformsupport/eglconvenience/qeglplatformcontext.cpp
new file mode 100644
index 0000000000..58debb8ba8
--- /dev/null
+++ b/src/platformsupport/eglconvenience/qeglplatformcontext.cpp
@@ -0,0 +1,160 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qeglplatformcontext_p.h"
+
+#include "qeglconvenience_p.h"
+
+#include <QtGui/QPlatformWindow>
+
+#include <EGL/egl.h>
+
+QEGLPlatformContext::QEGLPlatformContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display,
+ EGLint eglClientVersion, EGLenum eglApi)
+ : m_eglDisplay(display)
+ , m_eglApi(eglApi)
+ , m_format(format)
+{
+ EGLConfig config = q_configFromGLFormat(display, format, true);
+ m_format = q_glFormatFromConfig(display, config);
+
+ EGLContext shareContext = share ? static_cast<QEGLPlatformContext *>(share)->m_eglContext : 0;
+
+ QVector<EGLint> contextAttrs;
+ contextAttrs.append(EGL_CONTEXT_CLIENT_VERSION);
+ contextAttrs.append(eglClientVersion);
+ contextAttrs.append(EGL_NONE);
+
+ eglBindAPI(m_eglApi);
+ m_eglContext = eglCreateContext(m_eglDisplay, config, shareContext, contextAttrs.constData());
+ if (m_eglContext == EGL_NO_CONTEXT) {
+ qWarning("Could not create the egl context\n");
+ eglTerminate(m_eglDisplay);
+ qFatal("EGL error");
+ }
+}
+
+bool QEGLPlatformContext::makeCurrent(QPlatformSurface *surface)
+{
+#ifdef QEGL_EXTRA_DEBUG
+ qWarning("QEglContext::makeCurrent: %p\n",this);
+#endif
+ eglBindAPI(m_eglApi);
+
+ EGLSurface eglSurface = eglSurfaceForPlatformSurface(surface);
+
+ bool ok = eglMakeCurrent(m_eglDisplay, eglSurface, eglSurface, m_eglContext);
+ if (!ok)
+ qWarning("QEGLPlatformContext::makeCurrent: eglError: %x, this: %p \n", eglGetError(), this);
+#ifdef QEGL_EXTRA_DEBUG
+ static bool showDebug = true;
+ if (showDebug) {
+ showDebug = false;
+ const char *str = (const char*)glGetString(GL_VENDOR);
+ qWarning("Vendor %s\n", str);
+ str = (const char*)glGetString(GL_RENDERER);
+ qWarning("Renderer %s\n", str);
+ str = (const char*)glGetString(GL_VERSION);
+ qWarning("Version %s\n", str);
+
+ str = (const char*)glGetString(GL_SHADING_LANGUAGE_VERSION);
+ qWarning("Extensions %s\n",str);
+
+ str = (const char*)glGetString(GL_EXTENSIONS);
+ qWarning("Extensions %s\n", str);
+
+ }
+#endif
+ return ok;
+}
+
+QEGLPlatformContext::~QEGLPlatformContext()
+{
+#ifdef QEGL_EXTRA_DEBUG
+ qWarning("QEglContext::~QEglContext(): %p\n",this);
+#endif
+ if (m_eglContext != EGL_NO_CONTEXT) {
+ eglDestroyContext(m_eglDisplay, m_eglContext);
+ m_eglContext = EGL_NO_CONTEXT;
+ }
+}
+
+void QEGLPlatformContext::doneCurrent()
+{
+#ifdef QEGL_EXTRA_DEBUG
+ qWarning("QEglContext::doneCurrent:%p\n",this);
+#endif
+ eglBindAPI(m_eglApi);
+ bool ok = eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ if (!ok)
+ qWarning("QEGLPlatformContext::doneCurrent(): eglError: %d, this: %p \n", eglGetError(), this);
+}
+
+void QEGLPlatformContext::swapBuffers(QPlatformSurface *surface)
+{
+#ifdef QEGL_EXTRA_DEBUG
+ qWarning("QEglContext::swapBuffers:%p\n",this);
+#endif
+ eglBindAPI(m_eglApi);
+ EGLSurface eglSurface = eglSurfaceForPlatformSurface(surface);
+ bool ok = eglSwapBuffers(m_eglDisplay, eglSurface);
+ if (!ok)
+ qWarning("QEGLPlatformContext::swapBuffers(): eglError: %d, this: %p \n", eglGetError(), this);
+}
+
+void (*QEGLPlatformContext::getProcAddress(const QByteArray &procName)) ()
+{
+#ifdef QEGL_EXTRA_DEBUG
+ qWarning("QEglContext::getProcAddress%p\n",this);
+#endif
+ eglBindAPI(m_eglApi);
+ return eglGetProcAddress(procName.constData());
+}
+
+QSurfaceFormat QEGLPlatformContext::format() const
+{
+ return m_format;
+}
+
+EGLContext QEGLPlatformContext::eglContext() const
+{
+ return m_eglContext;
+}
diff --git a/src/platformsupport/eglconvenience/qeglplatformcontext_p.h b/src/platformsupport/eglconvenience/qeglplatformcontext_p.h
new file mode 100644
index 0000000000..2fe0e04388
--- /dev/null
+++ b/src/platformsupport/eglconvenience/qeglplatformcontext_p.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QEGLPLATFORMCONTEXT_H
+#define QEGLPLATFORMCONTEXT_H
+
+#include <QtGui/QPlatformWindow>
+#include <QtGui/QPlatformOpenGLContext>
+#include <EGL/egl.h>
+
+class QEGLPlatformContext : public QPlatformOpenGLContext
+{
+public:
+ QEGLPlatformContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display,
+ EGLint eglClientVersion = 2, EGLenum eglApi = EGL_OPENGL_ES_API);
+ ~QEGLPlatformContext();
+
+ bool makeCurrent(QPlatformSurface *surface);
+ void doneCurrent();
+ void swapBuffers(QPlatformSurface *surface);
+ void (*getProcAddress(const QByteArray &procName)) ();
+
+ QSurfaceFormat format() const;
+
+ EGLContext eglContext() const;
+
+protected:
+ virtual EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface) = 0;
+
+private:
+ EGLContext m_eglContext;
+ EGLDisplay m_eglDisplay;
+ EGLenum m_eglApi;
+
+ QSurfaceFormat m_format;
+};
+
+#endif //QEGLPLATFORMCONTEXT_H
diff --git a/src/platformsupport/eglconvenience/qxlibeglintegration.cpp b/src/platformsupport/eglconvenience/qxlibeglintegration.cpp
new file mode 100644
index 0000000000..aeebd35d21
--- /dev/null
+++ b/src/platformsupport/eglconvenience/qxlibeglintegration.cpp
@@ -0,0 +1,184 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxlibeglintegration_p.h"
+
+static int countBits(unsigned long mask)
+{
+ int count = 0;
+ while (mask != 0) {
+ if (mask & 1)
+ ++count;
+ mask >>= 1;
+ }
+ return count;
+}
+
+VisualID QXlibEglIntegration::getCompatibleVisualId(Display *display, EGLDisplay eglDisplay, EGLConfig config)
+{
+ VisualID visualId = 0;
+ EGLint eglValue = 0;
+
+ EGLint configRedSize = 0;
+ eglGetConfigAttrib(eglDisplay, config, EGL_RED_SIZE, &configRedSize);
+
+ EGLint configGreenSize = 0;
+ eglGetConfigAttrib(eglDisplay, config, EGL_GREEN_SIZE, &configGreenSize);
+
+ EGLint configBlueSize = 0;
+ eglGetConfigAttrib(eglDisplay, config, EGL_BLUE_SIZE, &configBlueSize);
+
+ EGLint configAlphaSize = 0;
+ eglGetConfigAttrib(eglDisplay, config, EGL_ALPHA_SIZE, &configAlphaSize);
+
+ eglGetConfigAttrib(eglDisplay, config, EGL_CONFIG_ID, &eglValue);
+ int configId = eglValue;
+
+ // See if EGL provided a valid VisualID:
+ eglGetConfigAttrib(eglDisplay, config, EGL_NATIVE_VISUAL_ID, &eglValue);
+ visualId = (VisualID)eglValue;
+ if (visualId) {
+ // EGL has suggested a visual id, so get the rest of the visual info for that id:
+ XVisualInfo visualInfoTemplate;
+ memset(&visualInfoTemplate, 0, sizeof(XVisualInfo));
+ visualInfoTemplate.visualid = visualId;
+
+ XVisualInfo *chosenVisualInfo;
+ int matchingCount = 0;
+ chosenVisualInfo = XGetVisualInfo(display, VisualIDMask, &visualInfoTemplate, &matchingCount);
+ if (chosenVisualInfo) {
+ // Skip size checks if implementation supports non-matching visual
+ // and config (http://bugreports.qt.nokia.com/browse/QTBUG-9444).
+ if (q_hasEglExtension(eglDisplay,"EGL_NV_post_convert_rounding")) {
+ XFree(chosenVisualInfo);
+ return visualId;
+ }
+
+ int visualRedSize = countBits(chosenVisualInfo->red_mask);
+ int visualGreenSize = countBits(chosenVisualInfo->green_mask);
+ int visualBlueSize = countBits(chosenVisualInfo->blue_mask);
+ int visualAlphaSize = -1; // Need XRender to tell us the alpha channel size
+
+ bool visualMatchesConfig = false;
+ if ( visualRedSize == configRedSize &&
+ visualGreenSize == configGreenSize &&
+ visualBlueSize == configBlueSize )
+ {
+ // We need XRender to check the alpha channel size of the visual. If we don't have
+ // the alpha size, we don't check it against the EGL config's alpha size.
+ if (visualAlphaSize >= 0)
+ visualMatchesConfig = visualAlphaSize == configAlphaSize;
+ else
+ visualMatchesConfig = true;
+ }
+
+ if (!visualMatchesConfig) {
+ if (visualAlphaSize >= 0) {
+ qWarning("Warning: EGL suggested using X Visual ID %d (ARGB%d%d%d%d) for EGL config %d (ARGB%d%d%d%d), but this is incompatable",
+ (int)visualId, visualAlphaSize, visualRedSize, visualGreenSize, visualBlueSize,
+ configId, configAlphaSize, configRedSize, configGreenSize, configBlueSize);
+ } else {
+ qWarning("Warning: EGL suggested using X Visual ID %d (RGB%d%d%d) for EGL config %d (RGB%d%d%d), but this is incompatable",
+ (int)visualId, visualRedSize, visualGreenSize, visualBlueSize,
+ configId, configRedSize, configGreenSize, configBlueSize);
+ }
+ visualId = 0;
+ }
+ } else {
+ qWarning("Warning: EGL suggested using X Visual ID %d for EGL config %d, but that isn't a valid ID",
+ (int)visualId, configId);
+ visualId = 0;
+ }
+ XFree(chosenVisualInfo);
+ }
+#ifdef QT_DEBUG_X11_VISUAL_SELECTION
+ else
+ qDebug("EGL did not suggest a VisualID (EGL_NATIVE_VISUAL_ID was zero) for EGLConfig %d", configId);
+#endif
+
+ if (visualId) {
+#ifdef QT_DEBUG_X11_VISUAL_SELECTION
+ if (configAlphaSize > 0)
+ qDebug("Using ARGB Visual ID %d provided by EGL for config %d", (int)visualId, configId);
+ else
+ qDebug("Using Opaque Visual ID %d provided by EGL for config %d", (int)visualId, configId);
+#endif
+ return visualId;
+ }
+
+ // Finally, try to
+ // use XGetVisualInfo and only use the bit depths to match on:
+ if (!visualId) {
+ XVisualInfo visualInfoTemplate;
+ memset(&visualInfoTemplate, 0, sizeof(XVisualInfo));
+ XVisualInfo *matchingVisuals;
+ int matchingCount = 0;
+
+ visualInfoTemplate.depth = configRedSize + configGreenSize + configBlueSize + configAlphaSize;
+ matchingVisuals = XGetVisualInfo(display,
+ VisualDepthMask,
+ &visualInfoTemplate,
+ &matchingCount);
+ if (!matchingVisuals) {
+ // Try again without taking the alpha channel into account:
+ visualInfoTemplate.depth = configRedSize + configGreenSize + configBlueSize;
+ matchingVisuals = XGetVisualInfo(display,
+ VisualDepthMask,
+ &visualInfoTemplate,
+ &matchingCount);
+ }
+
+ if (matchingVisuals) {
+ visualId = matchingVisuals[0].visualid;
+ XFree(matchingVisuals);
+ }
+ }
+
+ if (visualId) {
+#ifdef QT_DEBUG_X11_VISUAL_SELECTION
+ qDebug("Using Visual ID %d provided by XGetVisualInfo for EGL config %d", (int)visualId, configId);
+#endif
+ return visualId;
+ }
+
+ qWarning("Unable to find an X11 visual which matches EGL config %d", configId);
+ return (VisualID)0;
+}
diff --git a/src/platformsupport/eglconvenience/qxlibeglintegration_p.h b/src/platformsupport/eglconvenience/qxlibeglintegration_p.h
new file mode 100644
index 0000000000..cce394758d
--- /dev/null
+++ b/src/platformsupport/eglconvenience/qxlibeglintegration_p.h
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTESTLITEEGLINTEGRATION_H
+#define QTESTLITEEGLINTEGRATION_H
+
+#include "qeglconvenience_p.h"
+
+class QXlibEglIntegration
+{
+public:
+ static VisualID getCompatibleVisualId(Display *display, EGLDisplay eglDisplay, EGLConfig config);
+};
+
+#endif // QTESTLITEEGLINTEGRATION_H
diff --git a/src/platformsupport/eventdispatchers/eventdispatchers.pri b/src/platformsupport/eventdispatchers/eventdispatchers.pri
new file mode 100644
index 0000000000..38aca26b42
--- /dev/null
+++ b/src/platformsupport/eventdispatchers/eventdispatchers.pri
@@ -0,0 +1,16 @@
+unix {
+SOURCES +=\
+ $$PWD/qeventdispatcher_qpa.cpp\
+ $$PWD/qgenericunixeventdispatcher.cpp\
+
+HEADERS +=\
+ $$PWD/qeventdispatcher_qpa_p.h\
+ $$PWD/qgenericunixeventdispatcher_p.h\
+}
+
+contains(QT_CONFIG, glib) {
+ SOURCES +=$$PWD/qeventdispatcher_glib.cpp
+ HEADERS +=$$PWD/qeventdispatcher_glib_p.h
+ QMAKE_CXXFLAGS += $$QT_CFLAGS_GLIB
+ LIBS_PRIVATE += $$QT_LIBS_GLIB
+}
diff --git a/src/platformsupport/eventdispatchers/qeventdispatcher_glib.cpp b/src/platformsupport/eventdispatchers/qeventdispatcher_glib.cpp
new file mode 100644
index 0000000000..005c44a034
--- /dev/null
+++ b/src/platformsupport/eventdispatchers/qeventdispatcher_glib.cpp
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qeventdispatcher_glib_p.h"
+
+#include "qguiapplication.h"
+
+#include "qplatformdefs.h"
+
+#include <glib.h>
+#include "private/qguiapplication_p.h"
+
+#include <qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+struct GUserEventSource
+{
+ GSource source;
+ QPAEventDispatcherGlib *q;
+};
+
+static gboolean userEventSourcePrepare(GSource *s, gint *timeout)
+{
+ Q_UNUSED(s)
+ Q_UNUSED(timeout)
+
+ return QWindowSystemInterface::windowSystemEventsQueued() > 0;
+}
+
+static gboolean userEventSourceCheck(GSource *source)
+{
+ return userEventSourcePrepare(source, 0);
+}
+
+static gboolean userEventSourceDispatch(GSource *s, GSourceFunc, gpointer)
+{
+ GUserEventSource * source = reinterpret_cast<GUserEventSource *>(s);
+ QWindowSystemInterface::sendWindowSystemEvents(source->q, QEventLoop::AllEvents);
+ return true;
+}
+
+static GSourceFuncs userEventSourceFuncs = {
+ userEventSourcePrepare,
+ userEventSourceCheck,
+ userEventSourceDispatch,
+ NULL,
+ NULL,
+ NULL
+};
+
+QPAEventDispatcherGlibPrivate::QPAEventDispatcherGlibPrivate(GMainContext *context)
+ : QEventDispatcherGlibPrivate(context)
+{
+ userEventSource = reinterpret_cast<GUserEventSource *>(g_source_new(&userEventSourceFuncs,
+ sizeof(GUserEventSource)));
+ userEventSource->q = 0;
+ g_source_set_can_recurse(&userEventSource->source, true);
+ g_source_attach(&userEventSource->source, mainContext);
+}
+
+
+QPAEventDispatcherGlib::QPAEventDispatcherGlib(QObject *parent)
+ : QEventDispatcherGlib(*new QPAEventDispatcherGlibPrivate, parent)
+{
+ Q_D(QPAEventDispatcherGlib);
+ d->userEventSource->q = this;
+}
+
+QPAEventDispatcherGlib::~QPAEventDispatcherGlib()
+{
+ Q_D(QPAEventDispatcherGlib);
+
+ g_source_destroy(&d->userEventSource->source);
+ g_source_unref(&d->userEventSource->source);
+ d->userEventSource = 0;
+}
+
+QT_END_NAMESPACE
diff --git a/src/platformsupport/eventdispatchers/qeventdispatcher_glib_p.h b/src/platformsupport/eventdispatchers/qeventdispatcher_glib_p.h
new file mode 100644
index 0000000000..8a34e78357
--- /dev/null
+++ b/src/platformsupport/eventdispatchers/qeventdispatcher_glib_p.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QEVENTDISPATCHER_GLIB_QPA_P_H
+#define QEVENTDISPATCHER_GLIB_QPA_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the QLibrary class. This header file may change from
+// version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/private/qeventdispatcher_glib_p.h>
+
+typedef struct _GMainContext GMainContext;
+
+QT_BEGIN_NAMESPACE
+class QPAEventDispatcherGlibPrivate;
+
+class QPAEventDispatcherGlib : public QEventDispatcherGlib
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QPAEventDispatcherGlib)
+
+public:
+ explicit QPAEventDispatcherGlib(QObject *parent = 0);
+ ~QPAEventDispatcherGlib();
+};
+
+struct GUserEventSource;
+
+class QPAEventDispatcherGlibPrivate : public QEventDispatcherGlibPrivate
+{
+ Q_DECLARE_PUBLIC(QPAEventDispatcherGlib)
+public:
+ QPAEventDispatcherGlibPrivate(GMainContext *context = 0);
+ GUserEventSource *userEventSource;
+};
+
+
+QT_END_NAMESPACE
+
+#endif // QEVENTDISPATCHER_GLIB_QPA_P_H
diff --git a/src/platformsupport/eventdispatchers/qeventdispatcher_qpa.cpp b/src/platformsupport/eventdispatchers/qeventdispatcher_qpa.cpp
new file mode 100644
index 0000000000..d39aae7e1f
--- /dev/null
+++ b/src/platformsupport/eventdispatchers/qeventdispatcher_qpa.cpp
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qplatformdefs.h"
+#include "qcoreapplication.h"
+#include "qeventdispatcher_qpa_p.h"
+#include "private/qguiapplication_p.h"
+
+#include <QWindowSystemInterface>
+#include <QtCore/QElapsedTimer>
+#include <QtCore/QAtomicInt>
+#include <QtCore/QSemaphore>
+
+#include <QtCore/QDebug>
+
+#include <errno.h>
+
+QT_BEGIN_NAMESPACE
+
+QT_USE_NAMESPACE
+
+
+QEventDispatcherQPA::QEventDispatcherQPA(QObject *parent)
+ : QEventDispatcherUNIX(parent)
+{ }
+
+QEventDispatcherQPA::~QEventDispatcherQPA()
+{ }
+
+bool QEventDispatcherQPA::processEvents(QEventLoop::ProcessEventsFlags flags)
+{
+ bool didSendEvents = QWindowSystemInterface::sendWindowSystemEvents(this, flags);
+
+ if (QEventDispatcherUNIX::processEvents(flags)) {
+ QEventDispatcherUNIX::processEvents(flags);
+ return true;
+ }
+
+ return didSendEvents;
+}
+
+bool QEventDispatcherQPA::hasPendingEvents()
+{
+ extern uint qGlobalPostedEventsCount(); // from qapplication.cpp
+ return qGlobalPostedEventsCount() || QWindowSystemInterface::windowSystemEventsQueued();
+}
+
+void QEventDispatcherQPA::flush()
+{
+ if(qApp)
+ qApp->sendPostedEvents();
+}
+
+QT_END_NAMESPACE
diff --git a/src/platformsupport/eventdispatchers/qeventdispatcher_qpa_p.h b/src/platformsupport/eventdispatchers/qeventdispatcher_qpa_p.h
new file mode 100644
index 0000000000..cb67701750
--- /dev/null
+++ b/src/platformsupport/eventdispatchers/qeventdispatcher_qpa_p.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QEVENTDISPATCHER_QPA_H
+#define QEVENTDISPATCHER_QPA_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qglobal.h>
+#include <QtCore/private/qeventdispatcher_unix_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QEventDispatcherQPAPrivate;
+
+class Q_GUI_EXPORT QEventDispatcherQPA : public QEventDispatcherUNIX
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QEventDispatcherQPA)
+
+public:
+ explicit QEventDispatcherQPA(QObject *parent = 0);
+ ~QEventDispatcherQPA();
+
+ bool processEvents(QEventLoop::ProcessEventsFlags flags);
+ bool hasPendingEvents();
+
+ void flush();
+};
+
+QT_END_NAMESPACE
+
+#endif // QEVENTDISPATCHER_QPA_H
diff --git a/src/platformsupport/eventdispatchers/qgenericunixeventdispatcher.cpp b/src/platformsupport/eventdispatchers/qgenericunixeventdispatcher.cpp
new file mode 100644
index 0000000000..12981c5721
--- /dev/null
+++ b/src/platformsupport/eventdispatchers/qgenericunixeventdispatcher.cpp
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qgenericunixeventdispatcher_p.h"
+#include "qeventdispatcher_qpa_p.h"
+#include "qeventdispatcher_glib_p.h"
+#include <qglobal.h>
+
+class QAbstractEventDispatcher *createUnixEventDispatcher()
+{
+#if !defined(QT_NO_GLIB) && !defined(Q_OS_WIN)
+ if (qgetenv("QT_NO_GLIB").isEmpty() && QEventDispatcherGlib::versionSupported())
+ return new QPAEventDispatcherGlib();
+ else
+#endif
+ return new QEventDispatcherQPA();
+}
diff --git a/src/platformsupport/eventdispatchers/qgenericunixeventdispatcher_p.h b/src/platformsupport/eventdispatchers/qgenericunixeventdispatcher_p.h
new file mode 100644
index 0000000000..0d9f5b7db0
--- /dev/null
+++ b/src/platformsupport/eventdispatchers/qgenericunixeventdispatcher_p.h
@@ -0,0 +1,43 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+class QAbstractEventDispatcher;
+QAbstractEventDispatcher* createUnixEventDispatcher();
diff --git a/src/platformsupport/fb_base/fb_base.cpp b/src/platformsupport/fb_base/fb_base.cpp
new file mode 100644
index 0000000000..aa395fec29
--- /dev/null
+++ b/src/platformsupport/fb_base/fb_base.cpp
@@ -0,0 +1,507 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "fb_base_p.h"
+#include <qpainter.h>
+#include <qdebug.h>
+#include <qbitmap.h>
+#include <QPlatformCursor>
+#include <QWindowSystemInterface>
+
+QPlatformSoftwareCursor::QPlatformSoftwareCursor(QPlatformScreen *scr)
+ : QPlatformCursor(scr), currentRect(QRect()), prevRect(QRect())
+{
+ graphic = new QPlatformCursorImage(0, 0, 0, 0, 0, 0);
+ setCursor(Qt::ArrowCursor);
+}
+
+QRect QPlatformSoftwareCursor::getCurrentRect()
+{
+ QRect rect = graphic->image()->rect().translated(-graphic->hotspot().x(),
+ -graphic->hotspot().y());
+ rect.translate(QCursor::pos());
+ QPoint screenOffset = screen->geometry().topLeft();
+ rect.translate(-screenOffset); // global to local translation
+ return rect;
+}
+
+
+void QPlatformSoftwareCursor::pointerEvent(const QMouseEvent & e)
+{
+ Q_UNUSED(e);
+ QPoint screenOffset = screen->geometry().topLeft();
+ currentRect = getCurrentRect();
+ // global to local translation
+ if (onScreen || screen->geometry().intersects(currentRect.translated(screenOffset))) {
+ setDirty();
+ }
+}
+
+QRect QPlatformSoftwareCursor::drawCursor(QPainter & painter)
+{
+ dirty = false;
+ if (currentRect.isNull())
+ return QRect();
+
+ // We need this because the cursor might be dirty due to moving off screen
+ QPoint screenOffset = screen->geometry().topLeft();
+ // global to local translation
+ if (!currentRect.translated(screenOffset).intersects(screen->geometry()))
+ return QRect();
+
+ prevRect = currentRect;
+ painter.drawImage(prevRect, *graphic->image());
+ onScreen = true;
+ return prevRect;
+}
+
+QRect QPlatformSoftwareCursor::dirtyRect()
+{
+ if (onScreen) {
+ onScreen = false;
+ return prevRect;
+ }
+ return QRect();
+}
+
+void QPlatformSoftwareCursor::setCursor(Qt::CursorShape shape)
+{
+ graphic->set(shape);
+}
+
+void QPlatformSoftwareCursor::setCursor(const QImage &image, int hotx, int hoty)
+{
+ graphic->set(image, hotx, hoty);
+}
+
+void QPlatformSoftwareCursor::setCursor(const uchar *data, const uchar *mask, int width, int height, int hotX, int hotY)
+{
+ graphic->set(data, mask, width, height, hotX, hotY);
+}
+
+void QPlatformSoftwareCursor::changeCursor(QCursor * widgetCursor, QWidget * widget)
+{
+ Q_UNUSED(widget);
+ Qt::CursorShape shape = widgetCursor->shape();
+
+ if (shape == Qt::BitmapCursor) {
+ // application supplied cursor
+ QPoint spot = widgetCursor->hotSpot();
+ setCursor(widgetCursor->pixmap().toImage(), spot.x(), spot.y());
+ } else {
+ // system cursor
+ setCursor(shape);
+ }
+ currentRect = getCurrentRect();
+ QPoint screenOffset = screen->geometry().topLeft(); // global to local translation
+ if (onScreen || screen->geometry().intersects(currentRect.translated(screenOffset)))
+ setDirty();
+}
+
+QFbScreen::QFbScreen() : cursor(0), mGeometry(), mDepth(16), mFormat(QImage::Format_RGB16), mScreenImage(0), compositePainter(0), isUpToDate(false)
+{
+ mScreenImage = new QImage(mGeometry.size(), mFormat);
+ redrawTimer.setSingleShot(true);
+ redrawTimer.setInterval(0);
+ QObject::connect(&redrawTimer, SIGNAL(timeout()), this, SLOT(doRedraw()));
+}
+
+void QFbScreen::setGeometry(QRect rect)
+{
+ delete mScreenImage;
+ mGeometry = rect;
+ mScreenImage = new QImage(mGeometry.size(), mFormat);
+ delete compositePainter;
+ compositePainter = 0;
+ invalidateRectCache();
+}
+
+void QFbScreen::setDepth(int depth)
+{
+ mDepth = depth;
+}
+
+void QFbScreen::setPhysicalSize(QSize size)
+{
+ mPhysicalSize = size;
+}
+
+void QFbScreen::setFormat(QImage::Format format)
+{
+ mFormat = format;
+ delete mScreenImage;
+ mScreenImage = new QImage(mGeometry.size(), mFormat);
+ delete compositePainter;
+ compositePainter = 0;
+}
+
+QFbScreen::~QFbScreen()
+{
+ delete compositePainter;
+ delete mScreenImage;
+}
+
+void QFbScreen::setDirty(const QRect &rect)
+{
+ QRect intersection = rect.intersected(mGeometry);
+ QPoint screenOffset = mGeometry.topLeft();
+ repaintRegion += intersection.translated(-screenOffset); // global to local translation
+ if (!redrawTimer.isActive()) {
+ redrawTimer.start();
+ }
+}
+
+void QFbScreen::generateRects()
+{
+ cachedRects.clear();
+ QPoint screenOffset = mGeometry.topLeft();
+ QRegion remainingScreen(mGeometry.translated(-screenOffset)); // global to local translation
+
+ for (int i = 0; i < windowStack.length(); i++) {
+ if (remainingScreen.isEmpty())
+ break;
+ if (!windowStack[i]->visible())
+ continue;
+ if (windowStack[i]->widget()->isMinimized())
+ continue;
+
+ if (!windowStack[i]->widget()->testAttribute(Qt::WA_TranslucentBackground)) {
+ QRect localGeometry = windowStack.at(i)->geometry().translated(-screenOffset); // global to local translation
+ remainingScreen -= localGeometry;
+ QRegion windowRegion(localGeometry);
+ windowRegion -= remainingScreen;
+ foreach(QRect rect, windowRegion.rects()) {
+ cachedRects += QPair<QRect, int>(rect, i);
+ }
+ }
+ }
+ foreach (QRect rect, remainingScreen.rects())
+ cachedRects += QPair<QRect, int>(rect, -1);
+ isUpToDate = true;
+ return;
+}
+
+
+
+QRegion QFbScreen::doRedraw()
+{
+ QPoint screenOffset = mGeometry.topLeft();
+
+ QRegion touchedRegion;
+ if (cursor && cursor->isDirty() && cursor->isOnScreen()) {
+ QRect lastCursor = cursor->dirtyRect();
+ repaintRegion += lastCursor;
+ }
+ if (repaintRegion.isEmpty() && (!cursor || !cursor->isDirty())) {
+ return touchedRegion;
+ }
+
+ QVector<QRect> rects = repaintRegion.rects();
+
+ if (!isUpToDate)
+ generateRects();
+
+ if (!compositePainter)
+ compositePainter = new QPainter(mScreenImage);
+ for (int rectIndex = 0; rectIndex < repaintRegion.numRects(); rectIndex++) {
+ QRegion rectRegion = rects[rectIndex];
+
+ for(int i = 0; i < cachedRects.length(); i++) {
+ QRect screenSubRect = cachedRects[i].first;
+ int layer = cachedRects[i].second;
+ QRegion intersect = rectRegion.intersected(screenSubRect);
+
+ if (intersect.isEmpty())
+ continue;
+
+ rectRegion -= intersect;
+
+ // we only expect one rectangle, but defensive coding...
+ foreach (QRect rect, intersect.rects()) {
+ bool firstLayer = true;
+ if (layer == -1) {
+ compositePainter->fillRect(rect, Qt::black);
+ firstLayer = false;
+ layer = windowStack.size() - 1;
+ }
+
+ for (int layerIndex = layer; layerIndex != -1; layerIndex--) {
+ if (!windowStack[layerIndex]->visible())
+ continue;
+ if (windowStack[layerIndex]->widget()->isMinimized())
+ continue;
+ QRect windowRect = windowStack[layerIndex]->geometry().translated(-screenOffset);
+ QRect windowIntersect = rect.translated(-windowRect.left(),
+ -windowRect.top());
+ compositePainter->drawImage(rect, windowStack[layerIndex]->surface->image(),
+ windowIntersect);
+ if (firstLayer) {
+ firstLayer = false;
+ }
+ }
+ }
+ }
+ }
+
+ QRect cursorRect;
+ if (cursor && (cursor->isDirty() || repaintRegion.intersects(cursor->lastPainted()))) {
+ cursorRect = cursor->drawCursor(*compositePainter);
+ touchedRegion += cursorRect;
+ }
+ touchedRegion += repaintRegion;
+ repaintRegion = QRegion();
+
+
+
+// qDebug() << "QFbScreen::doRedraw" << windowStack.size() << mScreenImage->size() << touchedRegion;
+
+
+ return touchedRegion;
+}
+
+void QFbScreen::addWindow(QFbWindow *surface)
+{
+ windowStack.prepend(surface);
+ surface->mScreens.append(this);
+ invalidateRectCache();
+ setDirty(surface->geometry());
+}
+
+void QFbScreen::removeWindow(QFbWindow * surface)
+{
+ windowStack.removeOne(surface);
+ surface->mScreens.removeOne(this);
+ invalidateRectCache();
+ setDirty(surface->geometry());
+}
+
+void QFbWindow::raise()
+{
+ QList<QFbScreen *>::const_iterator i = mScreens.constBegin();
+ QList<QFbScreen *>::const_iterator end = mScreens.constEnd();
+ while (i != end) {
+ (*i)->raise(this);
+ ++i;
+ }
+}
+
+void QFbScreen::raise(QPlatformWindow * surface)
+{
+ QFbWindow *s = static_cast<QFbWindow *>(surface);
+ int index = windowStack.indexOf(s);
+ if (index <= 0)
+ return;
+ windowStack.move(index, 0);
+ invalidateRectCache();
+ setDirty(s->geometry());
+}
+
+void QFbWindow::lower()
+{
+ QList<QFbScreen *>::const_iterator i = mScreens.constBegin();
+ QList<QFbScreen *>::const_iterator end = mScreens.constEnd();
+ while (i != end) {
+ (*i)->lower(this);
+ ++i;
+ }
+}
+
+void QFbScreen::lower(QPlatformWindow * surface)
+{
+ QFbWindow *s = static_cast<QFbWindow *>(surface);
+ int index = windowStack.indexOf(s);
+ if (index == -1 || index == (windowStack.size() - 1))
+ return;
+ windowStack.move(index, windowStack.size() - 1);
+ invalidateRectCache();
+ setDirty(s->geometry());
+}
+
+QWidget * QFbScreen::topLevelAt(const QPoint & p) const
+{
+ for(int i = 0; i < windowStack.size(); i++) {
+ if (windowStack[i]->geometry().contains(p, false) &&
+ windowStack[i]->visible() &&
+ !windowStack[i]->widget()->isMinimized()) {
+ return windowStack[i]->widget();
+ }
+ }
+ return 0;
+}
+
+QFbWindow::QFbWindow(QWidget *window)
+ :QPlatformWindow(window),
+ visibleFlag(false)
+{
+ static QAtomicInt winIdGenerator(1);
+ windowId = winIdGenerator.fetchAndAddRelaxed(1);
+}
+
+
+QFbWindow::~QFbWindow()
+{
+ QList<QFbScreen *>::const_iterator i = mScreens.constBegin();
+ QList<QFbScreen *>::const_iterator end = mScreens.constEnd();
+ while (i != end) {
+ (*i)->removeWindow(this);
+ ++i;
+ }
+}
+
+
+QFbWindowSurface::QFbWindowSurface(QFbScreen *screen, QWidget *window)
+ : QWindowSurface(window),
+ mScreen(screen)
+{
+ mImage = QImage(window->size(), mScreen->format());
+
+ platformWindow = static_cast<QFbWindow*>(window->platformWindow());
+ platformWindow->surface = this;
+}
+
+QFbWindowSurface::~QFbWindowSurface()
+{
+}
+
+void QFbWindowSurface::flush(QWidget *widget, const QRegion &region, const QPoint &offset)
+{
+ Q_UNUSED(widget);
+ Q_UNUSED(offset);
+
+
+// qDebug() << "QFbWindowSurface::flush" << region;
+
+
+ platformWindow->repaint(region);
+}
+
+
+void QFbWindow::repaint(const QRegion &region)
+{
+ QRect currentGeometry = geometry();
+
+ QRect dirtyClient = region.boundingRect();
+ QRect dirtyRegion(currentGeometry.left() + dirtyClient.left(),
+ currentGeometry.top() + dirtyClient.top(),
+ dirtyClient.width(),
+ dirtyClient.height());
+ QList<QFbScreen *>::const_iterator i = mScreens.constBegin();
+ QList<QFbScreen *>::const_iterator end = mScreens.constEnd();
+ QRect oldGeometryLocal = oldGeometry;
+ oldGeometry = currentGeometry;
+ while (i != end) {
+ // If this is a move, redraw the previous location
+ if (oldGeometryLocal != currentGeometry) {
+ (*i)->setDirty(oldGeometryLocal);
+ }
+ (*i)->setDirty(dirtyRegion);
+ ++i;
+ }
+}
+
+void QFbWindowSurface::resize(const QSize &size)
+{
+ // change the widget's QImage if this is a resize
+ if (mImage.size() != size)
+ mImage = QImage(size, mScreen->format());
+ QWindowSurface::resize(size);
+}
+
+void QFbWindow::setGeometry(const QRect &rect)
+{
+// store previous geometry for screen update
+ oldGeometry = geometry();
+
+
+ QList<QFbScreen *>::const_iterator i = mScreens.constBegin();
+ QList<QFbScreen *>::const_iterator end = mScreens.constEnd();
+ while (i != end) {
+ (*i)->invalidateRectCache();
+ ++i;
+ }
+//### QWindowSystemInterface::handleGeometryChange(window(), rect);
+
+ QPlatformWindow::setGeometry(rect);
+}
+
+bool QFbWindowSurface::scroll(const QRegion &area, int dx, int dy)
+{
+ return QWindowSurface::scroll(area, dx, dy);
+}
+
+void QFbWindowSurface::beginPaint(const QRegion &region)
+{
+ Q_UNUSED(region);
+}
+
+void QFbWindowSurface::endPaint(const QRegion &region)
+{
+ Q_UNUSED(region);
+}
+
+void QFbWindow::setVisible(bool visible)
+{
+ visibleFlag = visible;
+ QList<QFbScreen *>::const_iterator i = mScreens.constBegin();
+ QList<QFbScreen *>::const_iterator end = mScreens.constEnd();
+ while (i != end) {
+ (*i)->invalidateRectCache();
+ (*i)->setDirty(geometry());
+ ++i;
+ }
+}
+
+Qt::WindowFlags QFbWindow::setWindowFlags(Qt::WindowFlags type)
+{
+ flags = type;
+ QList<QFbScreen *>::const_iterator i = mScreens.constBegin();
+ QList<QFbScreen *>::const_iterator end = mScreens.constEnd();
+ while (i != end) {
+ (*i)->invalidateRectCache();
+ ++i;
+ }
+ return flags;
+}
+
+Qt::WindowFlags QFbWindow::windowFlags() const
+{
+ return flags;
+}
diff --git a/src/platformsupport/fb_base/fb_base.pri b/src/platformsupport/fb_base/fb_base.pri
new file mode 100644
index 0000000000..e80125d54e
--- /dev/null
+++ b/src/platformsupport/fb_base/fb_base.pri
@@ -0,0 +1,4 @@
+do_not_compile_untill_ported_to_qt5 {
+ SOURCES += $$PWD/fb_base.cpp
+ HEADERS += $$PWD/fb_base_p.h
+}
diff --git a/src/plugins/platforms/fb_base/fb_base.h b/src/platformsupport/fb_base/fb_base_p.h
index 6b0b152482..6b0b152482 100644
--- a/src/plugins/platforms/fb_base/fb_base.h
+++ b/src/platformsupport/fb_base/fb_base_p.h
diff --git a/src/platformsupport/fontdatabases/basicunix/basicunix.pri b/src/platformsupport/fontdatabases/basicunix/basicunix.pri
new file mode 100644
index 0000000000..f83b89063b
--- /dev/null
+++ b/src/platformsupport/fontdatabases/basicunix/basicunix.pri
@@ -0,0 +1,84 @@
+DEFINES += QT_NO_FONTCONFIG
+QT += gui-private core-private
+
+HEADERS += \
+ $$PWD/qbasicunixfontdatabase_p.h \
+ $$QT_SOURCE_TREE/src/gui/text/qfontengine_ft_p.h
+
+SOURCES += \
+ $$PWD/qbasicunixfontdatabase.cpp \
+ $$QT_SOURCE_TREE/src/gui/text/qfontengine_ft.cpp
+
+CONFIG += opentype
+
+contains(QT_CONFIG, freetype) {
+ QT_FREETYPE_DIR = $$QT_SOURCE_TREE/src/3rdparty/freetype
+ SOURCES += \
+ $$QT_FREETYPE_DIR/src/base/ftbase.c \
+ $$QT_FREETYPE_DIR/src/base/ftbbox.c \
+ $$QT_FREETYPE_DIR/src/base/ftdebug.c \
+ $$QT_FREETYPE_DIR/src/base/ftglyph.c \
+ $$QT_FREETYPE_DIR/src/base/ftinit.c \
+ $$QT_FREETYPE_DIR/src/base/ftmm.c \
+ $$QT_FREETYPE_DIR/src/base/fttype1.c \
+ $$QT_FREETYPE_DIR/src/base/ftsynth.c \
+ $$QT_FREETYPE_DIR/src/base/ftbitmap.c \
+ $$QT_FREETYPE_DIR/src/bdf/bdf.c \
+ $$QT_FREETYPE_DIR/src/cache/ftcache.c \
+ $$QT_FREETYPE_DIR/src/cff/cff.c \
+ $$QT_FREETYPE_DIR/src/cid/type1cid.c \
+ $$QT_FREETYPE_DIR/src/gzip/ftgzip.c \
+ $$QT_FREETYPE_DIR/src/pcf/pcf.c \
+ $$QT_FREETYPE_DIR/src/pfr/pfr.c \
+ $$QT_FREETYPE_DIR/src/psaux/psaux.c \
+ $$QT_FREETYPE_DIR/src/pshinter/pshinter.c \
+ $$QT_FREETYPE_DIR/src/psnames/psmodule.c \
+ $$QT_FREETYPE_DIR/src/raster/raster.c \
+ $$QT_FREETYPE_DIR/src/sfnt/sfnt.c \
+ $$QT_FREETYPE_DIR/src/smooth/smooth.c \
+ $$QT_FREETYPE_DIR/src/truetype/truetype.c \
+ $$QT_FREETYPE_DIR/src/type1/type1.c \
+ $$QT_FREETYPE_DIR/src/type42/type42.c \
+ $$QT_FREETYPE_DIR/src/winfonts/winfnt.c \
+ $$QT_FREETYPE_DIR/src/lzw/ftlzw.c\
+ $$QT_FREETYPE_DIR/src/otvalid/otvalid.c\
+ $$QT_FREETYPE_DIR/src/otvalid/otvbase.c\
+ $$QT_FREETYPE_DIR/src/otvalid/otvgdef.c\
+ $$QT_FREETYPE_DIR/src/otvalid/otvjstf.c\
+ $$QT_FREETYPE_DIR/src/otvalid/otvcommn.c\
+ $$QT_FREETYPE_DIR/src/otvalid/otvgpos.c\
+ $$QT_FREETYPE_DIR/src/otvalid/otvgsub.c\
+ $$QT_FREETYPE_DIR/src/otvalid/otvmod.c\
+ $$QT_FREETYPE_DIR/src/autofit/afangles.c\
+ $$QT_FREETYPE_DIR/src/autofit/afglobal.c\
+ $$QT_FREETYPE_DIR/src/autofit/aflatin.c\
+ $$QT_FREETYPE_DIR/src/autofit/afmodule.c\
+ $$QT_FREETYPE_DIR/src/autofit/afdummy.c\
+ $$QT_FREETYPE_DIR/src/autofit/afhints.c\
+ $$QT_FREETYPE_DIR/src/autofit/afloader.c\
+ $$QT_FREETYPE_DIR/src/autofit/autofit.c
+
+ symbian {
+ SOURCES += \
+ $$QT_FREETYPE_DIR/src/base/ftsystem.c
+ } else {
+ SOURCES += \
+ $$QT_FREETYPE_DIR/builds/unix/ftsystem.c
+ INCLUDEPATH += \
+ $$QT_FREETYPE_DIR/builds/unix
+ }
+
+ INCLUDEPATH += \
+ $$QT_FREETYPE_DIR/src \
+ $$QT_FREETYPE_DIR/include
+
+ DEFINES += FT2_BUILD_LIBRARY
+ contains(QT_CONFIG, system-zlib) {
+ DEFINES += FT_CONFIG_OPTION_SYSTEM_ZLIB
+ }
+
+} else:contains(QT_CONFIG, system-freetype) {
+ # pull in the proper freetype2 include directory
+ include($$QT_SOURCE_TREE/config.tests/unix/freetype/freetype.pri)
+}
+
diff --git a/src/platformsupport/fontdatabases/basicunix/qbasicunixfontdatabase.cpp b/src/platformsupport/fontdatabases/basicunix/qbasicunixfontdatabase.cpp
new file mode 100644
index 0000000000..8012f84797
--- /dev/null
+++ b/src/platformsupport/fontdatabases/basicunix/qbasicunixfontdatabase.cpp
@@ -0,0 +1,422 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbasicunixfontdatabase_p.h"
+
+#include <QtGui/private/qguiapplication_p.h>
+#include <QtGui/QPlatformScreen>
+
+#include <QtCore/QFile>
+#include <QtCore/QLibraryInfo>
+#include <QtCore/QDir>
+#include <QtCore/QUuid>
+
+#undef QT_NO_FREETYPE
+#include <QtGui/private/qfontengine_ft_p.h>
+#include <QtGui/private/qfontengine_p.h>
+
+#include <ft2build.h>
+#include FT_TRUETYPE_TABLES_H
+
+#define SimplifiedChineseCsbBit 18
+#define TraditionalChineseCsbBit 20
+#define JapaneseCsbBit 17
+#define KoreanCsbBit 21
+
+static int requiredUnicodeBits[QFontDatabase::WritingSystemsCount][2] = {
+ // Any,
+ { 127, 127 },
+ // Latin,
+ { 0, 127 },
+ // Greek,
+ { 7, 127 },
+ // Cyrillic,
+ { 9, 127 },
+ // Armenian,
+ { 10, 127 },
+ // Hebrew,
+ { 11, 127 },
+ // Arabic,
+ { 13, 127 },
+ // Syriac,
+ { 71, 127 },
+ //Thaana,
+ { 72, 127 },
+ //Devanagari,
+ { 15, 127 },
+ //Bengali,
+ { 16, 127 },
+ //Gurmukhi,
+ { 17, 127 },
+ //Gujarati,
+ { 18, 127 },
+ //Oriya,
+ { 19, 127 },
+ //Tamil,
+ { 20, 127 },
+ //Telugu,
+ { 21, 127 },
+ //Kannada,
+ { 22, 127 },
+ //Malayalam,
+ { 23, 127 },
+ //Sinhala,
+ { 73, 127 },
+ //Thai,
+ { 24, 127 },
+ //Lao,
+ { 25, 127 },
+ //Tibetan,
+ { 70, 127 },
+ //Myanmar,
+ { 74, 127 },
+ // Georgian,
+ { 26, 127 },
+ // Khmer,
+ { 80, 127 },
+ // SimplifiedChinese,
+ { 126, 127 },
+ // TraditionalChinese,
+ { 126, 127 },
+ // Japanese,
+ { 126, 127 },
+ // Korean,
+ { 56, 127 },
+ // Vietnamese,
+ { 0, 127 }, // same as latin1
+ // Other,
+ { 126, 127 },
+ // Ogham,
+ { 78, 127 },
+ // Runic,
+ { 79, 127 },
+ // Nko,
+ { 14, 127 },
+};
+
+static QSupportedWritingSystems determineWritingSystemsFromTrueTypeBits(quint32 unicodeRange[4], quint32 codePageRange[2])
+{
+ QSupportedWritingSystems writingSystems;
+ bool hasScript = false;
+
+ int i;
+ for(i = 0; i < QFontDatabase::WritingSystemsCount; i++) {
+ int bit = requiredUnicodeBits[i][0];
+ int index = bit/32;
+ int flag = 1 << (bit&31);
+ if (bit != 126 && unicodeRange[index] & flag) {
+ bit = requiredUnicodeBits[i][1];
+ index = bit/32;
+
+ flag = 1 << (bit&31);
+ if (bit == 127 || unicodeRange[index] & flag) {
+ writingSystems.setSupported(QFontDatabase::WritingSystem(i));
+ hasScript = true;
+ // qDebug("font %s: index=%d, flag=%8x supports script %d", familyName.latin1(), index, flag, i);
+ }
+ }
+ }
+ if(codePageRange[0] & (1 << SimplifiedChineseCsbBit)) {
+ writingSystems.setSupported(QFontDatabase::SimplifiedChinese);
+ hasScript = true;
+ //qDebug("font %s supports Simplified Chinese", familyName.latin1());
+ }
+ if(codePageRange[0] & (1 << TraditionalChineseCsbBit)) {
+ writingSystems.setSupported(QFontDatabase::TraditionalChinese);
+ hasScript = true;
+ //qDebug("font %s supports Traditional Chinese", familyName.latin1());
+ }
+ if(codePageRange[0] & (1 << JapaneseCsbBit)) {
+ writingSystems.setSupported(QFontDatabase::Japanese);
+ hasScript = true;
+ //qDebug("font %s supports Japanese", familyName.latin1());
+ }
+ if(codePageRange[0] & (1 << KoreanCsbBit)) {
+ writingSystems.setSupported(QFontDatabase::Korean);
+ hasScript = true;
+ //qDebug("font %s supports Korean", familyName.latin1());
+ }
+ if (!hasScript)
+ writingSystems.setSupported(QFontDatabase::Symbol);
+
+ return writingSystems;
+}
+
+static inline bool scriptRequiresOpenType(int script)
+{
+ return ((script >= QUnicodeTables::Syriac && script <= QUnicodeTables::Sinhala)
+ || script == QUnicodeTables::Khmer || script == QUnicodeTables::Nko);
+}
+
+void QBasicUnixFontDatabase::populateFontDatabase()
+{
+ QPlatformFontDatabase::populateFontDatabase();
+ QString fontpath = fontDir();
+
+ if(!QFile::exists(fontpath)) {
+ qFatal("QFontDatabase: Cannot find font directory %s - is Qt installed correctly?",
+ qPrintable(fontpath));
+ }
+
+ QDir dir(fontpath);
+ dir.setNameFilters(QStringList() << QLatin1String("*.ttf")
+ << QLatin1String("*.ttc") << QLatin1String("*.pfa")
+ << QLatin1String("*.pfb"));
+ dir.refresh();
+ for (int i = 0; i < int(dir.count()); ++i) {
+ const QByteArray file = QFile::encodeName(dir.absoluteFilePath(dir[i]));
+// qDebug() << "looking at" << file;
+ addTTFile(QByteArray(), file);
+ }
+}
+
+QFontEngine *QBasicUnixFontDatabase::fontEngine(const QFontDef &fontDef, QUnicodeTables::Script script, void *usrPtr)
+{
+ QFontEngineFT *engine;
+ FontFile *fontfile = static_cast<FontFile *> (usrPtr);
+ QFontEngine::FaceId fid;
+ fid.filename = fontfile->fileName.toLocal8Bit();
+ fid.index = fontfile->indexValue;
+ engine = new QFontEngineFT(fontDef);
+
+ bool antialias = !(fontDef.styleStrategy & QFont::NoAntialias);
+ QFontEngineFT::GlyphFormat format = antialias? QFontEngineFT::Format_A8 : QFontEngineFT::Format_Mono;
+ if (!engine->init(fid,antialias,format)) {
+ delete engine;
+ engine = 0;
+ return engine;
+ }
+ if (engine->invalid()) {
+ delete engine;
+ engine = 0;
+ } else if (scriptRequiresOpenType(script)) {
+ HB_Face hbFace = engine->harfbuzzFace();
+ if (!hbFace || !hbFace->supported_scripts[script]) {
+ delete engine;
+ engine = 0;
+ }
+ }
+
+ return engine;
+}
+
+namespace {
+
+ class QFontEngineFTRawData: public QFontEngineFT
+ {
+ public:
+ QFontEngineFTRawData(const QFontDef &fontDef) : QFontEngineFT(fontDef)
+ {
+ }
+
+ void updateFamilyNameAndStyle()
+ {
+ fontDef.family = QString::fromAscii(freetype->face->family_name);
+
+ if (freetype->face->style_flags & FT_STYLE_FLAG_ITALIC)
+ fontDef.style = QFont::StyleItalic;
+
+ if (freetype->face->style_flags & FT_STYLE_FLAG_BOLD)
+ fontDef.weight = QFont::Bold;
+ }
+
+ bool initFromData(const QByteArray &fontData)
+ {
+ FaceId faceId;
+ faceId.filename = "";
+ faceId.index = 0;
+ faceId.uuid = QUuid::createUuid().toByteArray();
+
+ return init(faceId, true, Format_None, fontData);
+ }
+ };
+
+}
+
+QFontEngine *QBasicUnixFontDatabase::fontEngine(const QByteArray &fontData, qreal pixelSize,
+ QFont::HintingPreference hintingPreference)
+{
+ QFontDef fontDef;
+ fontDef.pixelSize = pixelSize;
+
+ QFontEngineFTRawData *fe = new QFontEngineFTRawData(fontDef);
+ if (!fe->initFromData(fontData)) {
+ delete fe;
+ return 0;
+ }
+
+ fe->updateFamilyNameAndStyle();
+
+ switch (hintingPreference) {
+ case QFont::PreferNoHinting:
+ fe->setDefaultHintStyle(QFontEngineFT::HintNone);
+ break;
+ case QFont::PreferFullHinting:
+ fe->setDefaultHintStyle(QFontEngineFT::HintFull);
+ break;
+ case QFont::PreferVerticalHinting:
+ fe->setDefaultHintStyle(QFontEngineFT::HintLight);
+ break;
+ default:
+ // Leave it as it is
+ break;
+ }
+
+ return fe;
+}
+
+QStringList QBasicUnixFontDatabase::fallbacksForFamily(const QString family, const QFont::Style &style, const QFont::StyleHint &styleHint, const QUnicodeTables::Script &script) const
+{
+ Q_UNUSED(family);
+ Q_UNUSED(style);
+ Q_UNUSED(script);
+ Q_UNUSED(styleHint);
+ return QStringList();
+}
+
+QStringList QBasicUnixFontDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName)
+{
+ return addTTFile(fontData,fileName.toLocal8Bit());
+}
+
+void QBasicUnixFontDatabase::releaseHandle(void *handle)
+{
+ FontFile *file = static_cast<FontFile *>(handle);
+ delete file;
+}
+
+QStringList QBasicUnixFontDatabase::addTTFile(const QByteArray &fontData, const QByteArray &file)
+{
+ extern FT_Library qt_getFreetype();
+ FT_Library library = qt_getFreetype();
+
+ int index = 0;
+ int numFaces = 0;
+ QStringList families;
+ do {
+ FT_Face face;
+ FT_Error error;
+ if (!fontData.isEmpty()) {
+ error = FT_New_Memory_Face(library, (const FT_Byte *)fontData.constData(), fontData.size(), index, &face);
+ } else {
+ error = FT_New_Face(library, file.constData(), index, &face);
+ }
+ if (error != FT_Err_Ok) {
+ qDebug() << "FT_New_Face failed with index" << index << ":" << hex << error;
+ break;
+ }
+ numFaces = face->num_faces;
+
+ QFont::Weight weight = QFont::Normal;
+
+ QFont::Style style = QFont::StyleNormal;
+ if (face->style_flags & FT_STYLE_FLAG_ITALIC)
+ style = QFont::StyleItalic;
+
+ if (face->style_flags & FT_STYLE_FLAG_BOLD)
+ weight = QFont::Bold;
+
+ QSupportedWritingSystems writingSystems;
+ // detect symbol fonts
+ for (int i = 0; i < face->num_charmaps; ++i) {
+ FT_CharMap cm = face->charmaps[i];
+ if (cm->encoding == ft_encoding_adobe_custom
+ || cm->encoding == ft_encoding_symbol) {
+ writingSystems.setSupported(QFontDatabase::Symbol);
+ break;
+ }
+ }
+
+ TT_OS2 *os2 = (TT_OS2 *)FT_Get_Sfnt_Table(face, ft_sfnt_os2);
+ if (os2) {
+ quint32 unicodeRange[4] = {
+ os2->ulUnicodeRange1, os2->ulUnicodeRange2, os2->ulUnicodeRange3, os2->ulUnicodeRange4
+ };
+ quint32 codePageRange[2] = {
+ os2->ulCodePageRange1, os2->ulCodePageRange2
+ };
+
+ writingSystems = determineWritingSystemsFromTrueTypeBits(unicodeRange, codePageRange);
+
+ if (os2->usWeightClass == 0)
+ ;
+ else if (os2->usWeightClass < 350)
+ weight = QFont::Light;
+ else if (os2->usWeightClass < 450)
+ weight = QFont::Normal;
+ else if (os2->usWeightClass < 650)
+ weight = QFont::DemiBold;
+ else if (os2->usWeightClass < 750)
+ weight = QFont::Bold;
+ else if (os2->usWeightClass < 1000)
+ weight = QFont::Black;
+
+ if (os2->panose[2] >= 2) {
+ int w = os2->panose[2];
+ if (w <= 3)
+ weight = QFont::Light;
+ else if (w <= 5)
+ weight = QFont::Normal;
+ else if (w <= 7)
+ weight = QFont::DemiBold;
+ else if (w <= 8)
+ weight = QFont::Bold;
+ else if (w <= 10)
+ weight = QFont::Black;
+ }
+ }
+
+ QString family = QString::fromAscii(face->family_name);
+ FontFile *fontFile = new FontFile;
+ fontFile->fileName = QString::fromAscii(file);
+ fontFile->indexValue = index;
+
+ QFont::Stretch stretch = QFont::Unstretched;
+
+ registerFont(family,QString(),weight,style,stretch,true,true,0,writingSystems,fontFile);
+
+ families.append(family);
+
+ FT_Done_Face(face);
+ ++index;
+ } while (index < numFaces);
+ return families;
+}
diff --git a/src/platformsupport/fontdatabases/basicunix/qbasicunixfontdatabase_p.h b/src/platformsupport/fontdatabases/basicunix/qbasicunixfontdatabase_p.h
new file mode 100644
index 0000000000..fa5fce0e20
--- /dev/null
+++ b/src/platformsupport/fontdatabases/basicunix/qbasicunixfontdatabase_p.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QBASICUNIXFONTDATABASE_H
+#define QBASICUNIXFONTDATABASE_H
+
+#include <QPlatformFontDatabase>
+#include <QtCore/QByteArray>
+#include <QtCore/QString>
+
+struct FontFile
+{
+ QString fileName;
+ int indexValue;
+};
+
+class QBasicUnixFontDatabase : public QPlatformFontDatabase
+{
+public:
+ void populateFontDatabase();
+ QFontEngine *fontEngine(const QFontDef &fontDef, QUnicodeTables::Script script, void *handle);
+ QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference);
+ QStringList fallbacksForFamily(const QString family, const QFont::Style &style, const QFont::StyleHint &styleHint, const QUnicodeTables::Script &script) const;
+ QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName);
+ void releaseHandle(void *handle);
+
+ static QStringList addTTFile(const QByteArray &fontData, const QByteArray &file);
+};
+
+#endif // QBASICUNIXFONTDATABASE_H
diff --git a/src/platformsupport/fontdatabases/fontconfig/fontconfig.pri b/src/platformsupport/fontdatabases/fontconfig/fontconfig.pri
new file mode 100644
index 0000000000..2efcb4d4dc
--- /dev/null
+++ b/src/platformsupport/fontdatabases/fontconfig/fontconfig.pri
@@ -0,0 +1,2 @@
+HEADERS += $$PWD/qfontconfigdatabase_p.h
+SOURCES += $$PWD/qfontconfigdatabase.cpp
diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
new file mode 100644
index 0000000000..9726ad8119
--- /dev/null
+++ b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
@@ -0,0 +1,604 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qfontconfigdatabase_p.h"
+
+#include <QtCore/QList>
+#include <QtGui/private/qfont_p.h>
+
+#include <QtCore/QElapsedTimer>
+
+#include <QtGui/QPlatformScreen>
+
+#include <QtGui/private/qfontengine_ft_p.h>
+#include <QtGui/private/qfontengine_p.h>
+
+
+
+#include <ft2build.h>
+#include FT_TRUETYPE_TABLES_H
+
+#include <fontconfig/fontconfig.h>
+
+#define SimplifiedChineseCsbBit 18
+#define TraditionalChineseCsbBit 20
+#define JapaneseCsbBit 17
+#define KoreanCsbBit 21
+
+static inline bool requiresOpenType(int writingSystem)
+{
+ return ((writingSystem >= QFontDatabase::Syriac && writingSystem <= QFontDatabase::Sinhala)
+ || writingSystem == QFontDatabase::Khmer || writingSystem == QFontDatabase::Nko);
+}
+static inline bool scriptRequiresOpenType(int script)
+{
+ return ((script >= QUnicodeTables::Syriac && script <= QUnicodeTables::Sinhala)
+ || script == QUnicodeTables::Khmer || script == QUnicodeTables::Nko);
+}
+
+static int getFCWeight(int fc_weight)
+{
+ int qtweight = QFont::Black;
+ if (fc_weight <= (FC_WEIGHT_LIGHT + FC_WEIGHT_MEDIUM) / 2)
+ qtweight = QFont::Light;
+ else if (fc_weight <= (FC_WEIGHT_MEDIUM + FC_WEIGHT_DEMIBOLD) / 2)
+ qtweight = QFont::Normal;
+ else if (fc_weight <= (FC_WEIGHT_DEMIBOLD + FC_WEIGHT_BOLD) / 2)
+ qtweight = QFont::DemiBold;
+ else if (fc_weight <= (FC_WEIGHT_BOLD + FC_WEIGHT_BLACK) / 2)
+ qtweight = QFont::Bold;
+
+ return qtweight;
+}
+
+static const char *specialLanguages[] = {
+ "en", // Common
+ "el", // Greek
+ "ru", // Cyrillic
+ "hy", // Armenian
+ "he", // Hebrew
+ "ar", // Arabic
+ "syr", // Syriac
+ "div", // Thaana
+ "hi", // Devanagari
+ "bn", // Bengali
+ "pa", // Gurmukhi
+ "gu", // Gujarati
+ "or", // Oriya
+ "ta", // Tamil
+ "te", // Telugu
+ "kn", // Kannada
+ "ml", // Malayalam
+ "si", // Sinhala
+ "th", // Thai
+ "lo", // Lao
+ "bo", // Tibetan
+ "my", // Myanmar
+ "ka", // Georgian
+ "ko", // Hangul
+ "", // Ogham
+ "", // Runic
+ "km", // Khmer
+ "" // N'Ko
+};
+enum { SpecialLanguageCount = sizeof(specialLanguages) / sizeof(const char *) };
+
+static const ushort specialChars[] = {
+ 0, // English
+ 0, // Greek
+ 0, // Cyrillic
+ 0, // Armenian
+ 0, // Hebrew
+ 0, // Arabic
+ 0, // Syriac
+ 0, // Thaana
+ 0, // Devanagari
+ 0, // Bengali
+ 0, // Gurmukhi
+ 0, // Gujarati
+ 0, // Oriya
+ 0, // Tamil
+ 0xc15, // Telugu
+ 0xc95, // Kannada
+ 0xd15, // Malayalam
+ 0xd9a, // Sinhala
+ 0, // Thai
+ 0, // Lao
+ 0, // Tibetan
+ 0x1000, // Myanmar
+ 0, // Georgian
+ 0, // Hangul
+ 0x1681, // Ogham
+ 0x16a0, // Runic
+ 0, // Khmer
+ 0x7ca // N'Ko
+};
+enum { SpecialCharCount = sizeof(specialChars) / sizeof(ushort) };
+
+// this could become a list of all languages used for each writing
+// system, instead of using the single most common language.
+static const char *languageForWritingSystem[] = {
+ 0, // Any
+ "en", // Latin
+ "el", // Greek
+ "ru", // Cyrillic
+ "hy", // Armenian
+ "he", // Hebrew
+ "ar", // Arabic
+ "syr", // Syriac
+ "div", // Thaana
+ "hi", // Devanagari
+ "bn", // Bengali
+ "pa", // Gurmukhi
+ "gu", // Gujarati
+ "or", // Oriya
+ "ta", // Tamil
+ "te", // Telugu
+ "kn", // Kannada
+ "ml", // Malayalam
+ "si", // Sinhala
+ "th", // Thai
+ "lo", // Lao
+ "bo", // Tibetan
+ "my", // Myanmar
+ "ka", // Georgian
+ "km", // Khmer
+ "zh-cn", // SimplifiedChinese
+ "zh-tw", // TraditionalChinese
+ "ja", // Japanese
+ "ko", // Korean
+ "vi", // Vietnamese
+ 0, // Symbol
+ 0, // Ogham
+ 0, // Runic
+ 0 // N'Ko
+};
+enum { LanguageCount = sizeof(languageForWritingSystem) / sizeof(const char *) };
+
+// Unfortunately FontConfig doesn't know about some languages. We have to test these through the
+// charset. The lists below contain the systems where we need to do this.
+static const ushort sampleCharForWritingSystem[] = {
+ 0, // Any
+ 0, // Latin
+ 0, // Greek
+ 0, // Cyrillic
+ 0, // Armenian
+ 0, // Hebrew
+ 0, // Arabic
+ 0, // Syriac
+ 0, // Thaana
+ 0, // Devanagari
+ 0, // Bengali
+ 0, // Gurmukhi
+ 0, // Gujarati
+ 0, // Oriya
+ 0, // Tamil
+ 0xc15, // Telugu
+ 0xc95, // Kannada
+ 0xd15, // Malayalam
+ 0xd9a, // Sinhala
+ 0, // Thai
+ 0, // Lao
+ 0, // Tibetan
+ 0x1000, // Myanmar
+ 0, // Georgian
+ 0, // Khmer
+ 0, // SimplifiedChinese
+ 0, // TraditionalChinese
+ 0, // Japanese
+ 0, // Korean
+ 0, // Vietnamese
+ 0, // Symbol
+ 0x1681, // Ogham
+ 0x16a0, // Runic
+ 0x7ca // N'Ko
+};
+enum { SampleCharCount = sizeof(sampleCharForWritingSystem) / sizeof(ushort) };
+
+// Newer FontConfig let's us sort out fonts that contain certain glyphs, but no
+// open type tables for is directly. Do this so we don't pick some strange
+// pseudo unicode font
+static const char *openType[] = {
+ 0, // Any
+ 0, // Latin
+ 0, // Greek
+ 0, // Cyrillic
+ 0, // Armenian
+ 0, // Hebrew
+ 0, // Arabic
+ "syrc", // Syriac
+ "thaa", // Thaana
+ "deva", // Devanagari
+ "beng", // Bengali
+ "guru", // Gurmukhi
+ "gurj", // Gujarati
+ "orya", // Oriya
+ "taml", // Tamil
+ "telu", // Telugu
+ "knda", // Kannada
+ "mlym", // Malayalam
+ "sinh", // Sinhala
+ 0, // Thai
+ 0, // Lao
+ "tibt", // Tibetan
+ "mymr", // Myanmar
+ 0, // Georgian
+ "khmr", // Khmer
+ 0, // SimplifiedChinese
+ 0, // TraditionalChinese
+ 0, // Japanese
+ 0, // Korean
+ 0, // Vietnamese
+ 0, // Symbol
+ 0, // Ogham
+ 0, // Runic
+ "nko " // N'Ko
+};
+
+static const char *getFcFamilyForStyleHint(const QFont::StyleHint style)
+{
+ const char *stylehint = 0;
+ switch (style) {
+ case QFont::SansSerif:
+ stylehint = "sans-serif";
+ break;
+ case QFont::Serif:
+ stylehint = "serif";
+ break;
+ case QFont::TypeWriter:
+ stylehint = "monospace";
+ break;
+ default:
+ break;
+ }
+ return stylehint;
+}
+
+void QFontconfigDatabase::populateFontDatabase()
+{
+ FcFontSet *fonts;
+
+ QString familyName;
+ FcChar8 *value = 0;
+ int weight_value;
+ int slant_value;
+ int spacing_value;
+ FcChar8 *file_value;
+ int indexValue;
+ FcChar8 *foundry_value;
+ FcBool scalable;
+ FcBool antialias;
+
+ {
+ FcObjectSet *os = FcObjectSetCreate();
+ FcPattern *pattern = FcPatternCreate();
+ const char *properties [] = {
+ FC_FAMILY, FC_WEIGHT, FC_SLANT,
+ FC_SPACING, FC_FILE, FC_INDEX,
+ FC_LANG, FC_CHARSET, FC_FOUNDRY, FC_SCALABLE, FC_PIXEL_SIZE, FC_WEIGHT,
+ FC_WIDTH,
+#if FC_VERSION >= 20297
+ FC_CAPABILITY,
+#endif
+ (const char *)0
+ };
+ const char **p = properties;
+ while (*p) {
+ FcObjectSetAdd(os, *p);
+ ++p;
+ }
+ fonts = FcFontList(0, pattern, os);
+ FcObjectSetDestroy(os);
+ FcPatternDestroy(pattern);
+ }
+
+ for (int i = 0; i < fonts->nfont; i++) {
+ if (FcPatternGetString(fonts->fonts[i], FC_FAMILY, 0, &value) != FcResultMatch)
+ continue;
+ // capitalize(value);
+ familyName = QString::fromUtf8((const char *)value);
+ slant_value = FC_SLANT_ROMAN;
+ weight_value = FC_WEIGHT_MEDIUM;
+ spacing_value = FC_PROPORTIONAL;
+ file_value = 0;
+ indexValue = 0;
+ scalable = FcTrue;
+
+
+ if (FcPatternGetInteger (fonts->fonts[i], FC_SLANT, 0, &slant_value) != FcResultMatch)
+ slant_value = FC_SLANT_ROMAN;
+ if (FcPatternGetInteger (fonts->fonts[i], FC_WEIGHT, 0, &weight_value) != FcResultMatch)
+ weight_value = FC_WEIGHT_MEDIUM;
+ if (FcPatternGetInteger (fonts->fonts[i], FC_SPACING, 0, &spacing_value) != FcResultMatch)
+ spacing_value = FC_PROPORTIONAL;
+ if (FcPatternGetString (fonts->fonts[i], FC_FILE, 0, &file_value) != FcResultMatch)
+ file_value = 0;
+ if (FcPatternGetInteger (fonts->fonts[i], FC_INDEX, 0, &indexValue) != FcResultMatch)
+ indexValue = 0;
+ if (FcPatternGetBool(fonts->fonts[i], FC_SCALABLE, 0, &scalable) != FcResultMatch)
+ scalable = FcTrue;
+ if (FcPatternGetString(fonts->fonts[i], FC_FOUNDRY, 0, &foundry_value) != FcResultMatch)
+ foundry_value = 0;
+ if(FcPatternGetBool(fonts->fonts[i],FC_ANTIALIAS,0,&antialias) != FcResultMatch)
+ antialias = true;
+
+ QSupportedWritingSystems writingSystems;
+ FcLangSet *langset = 0;
+ FcResult res = FcPatternGetLangSet(fonts->fonts[i], FC_LANG, 0, &langset);
+ if (res == FcResultMatch) {
+ for (int i = 1; i < LanguageCount; ++i) {
+ const FcChar8 *lang = (const FcChar8*) languageForWritingSystem[i];
+ if (lang) {
+ FcLangResult langRes = FcLangSetHasLang(langset, lang);
+ if (langRes != FcLangDifferentLang)
+ writingSystems.setSupported(QFontDatabase::WritingSystem(i));
+ }
+ }
+ } else {
+ // we set Other to supported for symbol fonts. It makes no
+ // sense to merge these with other ones, as they are
+ // special in a way.
+ writingSystems.setSupported(QFontDatabase::Other);
+ }
+
+ FcCharSet *cs = 0;
+ res = FcPatternGetCharSet(fonts->fonts[i], FC_CHARSET, 0, &cs);
+ if (res == FcResultMatch) {
+ // some languages are not supported by FontConfig, we rather check the
+ // charset to detect these
+ for (int i = 1; i < SampleCharCount; ++i) {
+ if (!sampleCharForWritingSystem[i])
+ continue;
+ if (FcCharSetHasChar(cs, sampleCharForWritingSystem[i]))
+ writingSystems.setSupported(QFontDatabase::WritingSystem(i));
+ }
+ }
+
+#if FC_VERSION >= 20297
+ for (int j = 1; j < LanguageCount; ++j) {
+ if (writingSystems.supported(QFontDatabase::WritingSystem(j))
+ && requiresOpenType(j) && openType[j]) {
+ FcChar8 *cap;
+ res = FcPatternGetString (fonts->fonts[i], FC_CAPABILITY, 0, &cap);
+ if (res != FcResultMatch || !strstr((const char *)cap, openType[j]))
+ writingSystems.setSupported(QFontDatabase::WritingSystem(j),false);
+ }
+ }
+#endif
+
+ FontFile *fontFile = new FontFile;
+ fontFile->fileName = QLatin1String((const char *)file_value);
+ fontFile->indexValue = indexValue;
+
+ QFont::Style style = (slant_value == FC_SLANT_ITALIC)
+ ? QFont::StyleItalic
+ : ((slant_value == FC_SLANT_OBLIQUE)
+ ? QFont::StyleOblique
+ : QFont::StyleNormal);
+ QFont::Weight weight = QFont::Weight(getFCWeight(weight_value));
+
+ double pixel_size = 0;
+ if (!scalable) {
+ int width = 100;
+ FcPatternGetInteger (fonts->fonts[i], FC_WIDTH, 0, &width);
+ FcPatternGetDouble (fonts->fonts[i], FC_PIXEL_SIZE, 0, &pixel_size);
+ }
+
+ QFont::Stretch stretch = QFont::Unstretched;
+ QPlatformFontDatabase::registerFont(familyName,QLatin1String((const char *)foundry_value),weight,style,stretch,antialias,scalable,pixel_size,writingSystems,fontFile);
+// qDebug() << familyName << (const char *)foundry_value << weight << style << &writingSystems << scalable << true << pixel_size;
+ }
+
+ FcFontSetDestroy (fonts);
+
+ struct FcDefaultFont {
+ const char *qtname;
+ const char *rawname;
+ bool fixed;
+ };
+ const FcDefaultFont defaults[] = {
+ { "Serif", "serif", false },
+ { "Sans Serif", "sans-serif", false },
+ { "Monospace", "monospace", true },
+ { 0, 0, false }
+ };
+ const FcDefaultFont *f = defaults;
+ // aliases only make sense for 'common', not for any of the specials
+ QSupportedWritingSystems ws;
+ ws.setSupported(QFontDatabase::Latin);
+
+
+ QString familyQtName = QString::fromLatin1(f->qtname);
+ while (f->qtname) {
+ registerFont(familyQtName,QString(),QFont::Normal,QFont::StyleNormal,QFont::Unstretched,true,true,0,ws,0);
+ registerFont(familyQtName,QString(),QFont::Normal,QFont::StyleItalic,QFont::Unstretched,true,true,0,ws,0);
+ registerFont(familyQtName,QString(),QFont::Normal,QFont::StyleOblique,QFont::Unstretched,true,true,0,ws,0);
+ ++f;
+ }
+
+ //Lighthouse has very lazy population of the font db. We want it to be initialized when
+ //QApplication is constructed, so that the population procedure can do something like this to
+ //set the default font
+// const FcDefaultFont *s = defaults;
+// QFont font("Sans Serif");
+// font.setPointSize(9);
+// QApplication::setFont(font);
+}
+
+QFontEngine *QFontconfigDatabase::fontEngine(const QFontDef &f, QUnicodeTables::Script script, void *usrPtr)
+{
+ if (!usrPtr)
+ return 0;
+ QFontDef fontDef = f;
+
+ QFontEngineFT *engine;
+ FontFile *fontfile = static_cast<FontFile *> (usrPtr);
+ QFontEngine::FaceId fid;
+ fid.filename = fontfile->fileName.toLocal8Bit();
+ fid.index = fontfile->indexValue;
+
+ bool antialias = !(fontDef.styleStrategy & QFont::NoAntialias);
+ QFontEngineFT::GlyphFormat format = antialias? QFontEngineFT::Format_A8 : QFontEngineFT::Format_Mono;
+
+ engine = new QFontEngineFT(fontDef);
+
+ // try and get the pattern
+ FcPattern *pattern = FcPatternCreate();
+
+ FcValue value;
+ value.type = FcTypeString;
+ QByteArray cs = fontDef.family.toUtf8();
+ value.u.s = (const FcChar8 *)cs.data();
+ FcPatternAdd(pattern,FC_FAMILY,value,true);
+
+
+ value.u.s = (const FcChar8 *)fid.filename.data();
+ FcPatternAdd(pattern,FC_FILE,value,true);
+
+ value.type = FcTypeInteger;
+ value.u.i = fid.index;
+ FcPatternAdd(pattern,FC_INDEX,value,true);
+
+ if (FcConfigSubstitute(0,pattern,FcMatchPattern)) {
+ QFontEngineFT::HintStyle default_hint_style;
+
+ //hinting
+ int hint_style = 0;
+ if (FcPatternGetInteger (pattern, FC_HINT_STYLE, 0, &hint_style) == FcResultNoMatch)
+ hint_style = QFontEngineFT::HintFull;
+ switch (hint_style) {
+ case FC_HINT_NONE:
+ default_hint_style = QFontEngineFT::HintNone;
+ break;
+ case FC_HINT_SLIGHT:
+ default_hint_style = QFontEngineFT::HintLight;
+ break;
+ case FC_HINT_MEDIUM:
+ default_hint_style = QFontEngineFT::HintMedium;
+ break;
+ default:
+ default_hint_style = QFontEngineFT::HintFull;
+ break;
+ }
+ engine->setDefaultHintStyle(default_hint_style);
+ }
+ FcPatternDestroy(pattern);
+
+ if (!engine->init(fid,antialias,format)) {
+ delete engine;
+ engine = 0;
+ return engine;
+ }
+ if (engine->invalid()) {
+ delete engine;
+ engine = 0;
+ } else if (scriptRequiresOpenType(script)) {
+ HB_Face hbFace = engine->harfbuzzFace();
+ if (!hbFace || !hbFace->supported_scripts[script]) {
+ delete engine;
+ engine = 0;
+ }
+ }
+
+ return engine;
+}
+
+QStringList QFontconfigDatabase::fallbacksForFamily(const QString family, const QFont::Style &style, const QFont::StyleHint &styleHint, const QUnicodeTables::Script &script) const
+{
+ QStringList fallbackFamilies;
+ FcPattern *pattern = FcPatternCreate();
+ if (!pattern)
+ return fallbackFamilies;
+
+ FcValue value;
+ value.type = FcTypeString;
+ QByteArray cs = family.toUtf8();
+ value.u.s = (const FcChar8 *)cs.data();
+ FcPatternAdd(pattern,FC_FAMILY,value,true);
+
+ int slant_value = FC_SLANT_ROMAN;
+ if (style == QFont::StyleItalic)
+ slant_value = FC_SLANT_ITALIC;
+ else if (style == QFont::StyleOblique)
+ slant_value = FC_SLANT_OBLIQUE;
+ FcPatternAddInteger(pattern, FC_SLANT, slant_value);
+
+ if (script != QUnicodeTables::Common && *specialLanguages[script] != '\0') {
+ Q_ASSERT(script < QUnicodeTables::ScriptCount);
+ FcLangSet *ls = FcLangSetCreate();
+ FcLangSetAdd(ls, (const FcChar8*)specialLanguages[script]);
+ FcPatternAddLangSet(pattern, FC_LANG, ls);
+ FcLangSetDestroy(ls);
+ }
+
+ const char *stylehint = getFcFamilyForStyleHint(styleHint);
+ if (stylehint) {
+ value.u.s = (const FcChar8 *)stylehint;
+ FcPatternAddWeak(pattern, FC_FAMILY, value, FcTrue);
+ }
+
+ FcConfigSubstitute(0, pattern, FcMatchPattern);
+ FcDefaultSubstitute(pattern);
+
+ FcResult result = FcResultMatch;
+ FcFontSet *fontSet = FcFontSort(0,pattern,FcFalse,0,&result);
+ FcPatternDestroy(pattern);
+
+ if (fontSet) {
+ if (result == FcResultMatch) {
+ for (int i = 0; i < fontSet->nfont; i++) {
+ FcChar8 *value = 0;
+ if (FcPatternGetString(fontSet->fonts[i], FC_FAMILY, 0, &value) != FcResultMatch)
+ continue;
+ // capitalize(value);
+ QString familyName = QString::fromUtf8((const char *)value);
+ if (!fallbackFamilies.contains(familyName,Qt::CaseInsensitive) &&
+ familyName.compare(family, Qt::CaseInsensitive)) {
+ fallbackFamilies << familyName;
+ }
+ }
+ }
+ FcFontSetDestroy(fontSet);
+ }
+// qDebug() << "fallbackFamilies for:" << family << style << styleHint << script << fallbackFamilies;
+
+ return fallbackFamilies;
+}
diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h
new file mode 100644
index 0000000000..5a5e4b670f
--- /dev/null
+++ b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QFONTCONFIGDATABASE_H
+#define QFONTCONFIGDATABASE_H
+
+#include <QPlatformFontDatabase>
+#include <QtPlatformSupport/private/qbasicunixfontdatabase_p.h>
+
+class QFontconfigDatabase : public QBasicUnixFontDatabase
+{
+public:
+ void populateFontDatabase();
+ QFontEngine *fontEngine(const QFontDef &fontDef, QUnicodeTables::Script script, void *handle);
+ QStringList fallbacksForFamily(const QString family, const QFont::Style &style, const QFont::StyleHint &styleHint, const QUnicodeTables::Script &script) const;
+};
+
+#endif // QFONTCONFIGDATABASE_H
diff --git a/src/platformsupport/fontdatabases/fontdatabases.pri b/src/platformsupport/fontdatabases/fontdatabases.pri
new file mode 100644
index 0000000000..0e282d97dd
--- /dev/null
+++ b/src/platformsupport/fontdatabases/fontdatabases.pri
@@ -0,0 +1,10 @@
+DEFINES += QT_COMPILES_IN_HARFBUZZ
+INCLUDEPATH += $$QT_SOURCE_TREE/src/3rdparty/harfbuzz/src
+
+unix {
+ include($$PWD/basicunix/basicunix.pri)
+ include($$PWD/genericunix/genericunix.pri)
+ contains(QT_CONFIG,fontconfig) {
+ include($$PWD/fontconfig/fontconfig.pri)
+ }
+}
diff --git a/src/platformsupport/fontdatabases/genericunix/genericunix.pri b/src/platformsupport/fontdatabases/genericunix/genericunix.pri
new file mode 100644
index 0000000000..e9db6c07e2
--- /dev/null
+++ b/src/platformsupport/fontdatabases/genericunix/genericunix.pri
@@ -0,0 +1 @@
+HEADERS += $$PWD/qgenericunixfontdatabase_p.h
diff --git a/src/platformsupport/fontdatabases/genericunix/qgenericunixfontdatabase_p.h b/src/platformsupport/fontdatabases/genericunix/qgenericunixfontdatabase_p.h
new file mode 100644
index 0000000000..63f214df54
--- /dev/null
+++ b/src/platformsupport/fontdatabases/genericunix/qgenericunixfontdatabase_p.h
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGENERICUNIXFONTDATABASE_H
+#define QGENERICUNIXFONTDATABASE_H
+
+#ifdef Q_FONTCONFIGDATABASE
+#include <QtPlatformSupport/private/qfontconfigdatabase_p.h>
+typedef QFontconfigDatabase QGenericUnixFontDatabase;
+#else
+#include <QtPlatformSupport/private/qbasicunixfontdatabase_p.h>
+typedef QBasicUnixFontDatabase QGenericUnixFontDatabase;
+#endif //Q_FONTCONFIGDATABASE
+
+#endif // QGENERICUNIXFONTDATABASE_H
diff --git a/src/platformsupport/glxconvenience/glxconvenience.pri b/src/platformsupport/glxconvenience/glxconvenience.pri
new file mode 100644
index 0000000000..5b65e13306
--- /dev/null
+++ b/src/platformsupport/glxconvenience/glxconvenience.pri
@@ -0,0 +1,6 @@
+contains(QT_CONFIG,xlib) {
+ contains(QT_CONFIG,opengl):!contains(QT_CONFIG,opengles2) {
+ HEADERS += $$PWD/qglxconvenience_p.h
+ SOURCES += $$PWD/qglxconvenience.cpp
+ }
+}
diff --git a/src/platformsupport/glxconvenience/qglxconvenience.cpp b/src/platformsupport/glxconvenience/qglxconvenience.cpp
new file mode 100644
index 0000000000..ce0c49d93f
--- /dev/null
+++ b/src/platformsupport/glxconvenience/qglxconvenience.cpp
@@ -0,0 +1,225 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qglxconvenience_p.h"
+
+#include <QtCore/QVector>
+
+#ifndef QT_NO_XRENDER
+#include <X11/extensions/Xrender.h>
+#endif
+
+enum {
+ XFocusOut = FocusOut,
+ XFocusIn = FocusIn,
+ XKeyPress = KeyPress,
+ XKeyRelease = KeyRelease,
+ XNone = None,
+ XRevertToParent = RevertToParent,
+ XGrayScale = GrayScale,
+ XCursorShape = CursorShape
+};
+#undef FocusOut
+#undef FocusIn
+#undef KeyPress
+#undef KeyRelease
+#undef None
+#undef RevertToParent
+#undef GrayScale
+#undef CursorShape
+
+#ifdef FontChange
+#undef FontChange
+#endif
+
+QVector<int> qglx_buildSpec(const QSurfaceFormat &format, int drawableBit)
+{
+ QVector<int> spec(48);
+ int i = 0;
+
+ spec[i++] = GLX_LEVEL;
+ spec[i++] = 0;
+ spec[i++] = GLX_DRAWABLE_TYPE; spec[i++] = drawableBit;
+
+ spec[i++] = GLX_RENDER_TYPE; spec[i++] = GLX_RGBA_BIT;
+
+ spec[i++] = GLX_RED_SIZE; spec[i++] = (format.redBufferSize() == -1) ? 1 : format.redBufferSize();
+ spec[i++] = GLX_GREEN_SIZE; spec[i++] = (format.greenBufferSize() == -1) ? 1 : format.greenBufferSize();
+ spec[i++] = GLX_BLUE_SIZE; spec[i++] = (format.blueBufferSize() == -1) ? 1 : format.blueBufferSize();
+ if (format.hasAlpha()) {
+ spec[i++] = GLX_ALPHA_SIZE; spec[i++] = format.alphaBufferSize();
+ }
+
+ spec[i++] = GLX_DOUBLEBUFFER; spec[i++] = format.swapBehavior() != QSurfaceFormat::SingleBuffer ? True : False;
+
+ spec[i++] = GLX_STEREO; spec[i++] = format.stereo() ? True : False;
+
+ if (format.depthBufferSize() > 0) {
+ spec[i++] = GLX_DEPTH_SIZE; spec[i++] = format.depthBufferSize();
+ }
+
+ if (format.stencilBufferSize() > 0) {
+ spec[i++] = GLX_STENCIL_SIZE; spec[i++] = (format.stencilBufferSize() == -1) ? 1 : format.stencilBufferSize();
+ }
+
+ if (format.samples() > 1) {
+ spec[i++] = GLX_SAMPLE_BUFFERS_ARB;
+ spec[i++] = 1;
+ spec[i++] = GLX_SAMPLES_ARB;
+ spec[i++] = format.samples();
+ }
+
+ spec[i++] = XNone;
+ return spec;
+}
+
+GLXFBConfig qglx_findConfig(Display *display, int screen , const QSurfaceFormat &format, int drawableBit)
+{
+ bool reduced = true;
+ GLXFBConfig chosenConfig = 0;
+ QSurfaceFormat reducedFormat = format;
+ while (!chosenConfig && reduced) {
+ QVector<int> spec = qglx_buildSpec(reducedFormat, drawableBit);
+ int confcount = 0;
+ GLXFBConfig *configs;
+ configs = glXChooseFBConfig(display, screen,spec.constData(),&confcount);
+ if (confcount)
+ {
+ for (int i = 0; i < confcount; i++) {
+ chosenConfig = configs[i];
+ // Make sure we try to get an ARGB visual if the format asked for an alpha:
+ if (reducedFormat.hasAlpha()) {
+ int alphaSize;
+ glXGetFBConfigAttrib(display,configs[i],GLX_ALPHA_SIZE,&alphaSize);
+ if (alphaSize > 0) {
+ XVisualInfo *visual = glXGetVisualFromFBConfig(display, chosenConfig);
+#if !defined(QT_NO_XRENDER)
+ XRenderPictFormat *pictFormat = XRenderFindVisualFormat(display, visual->visual);
+ if (pictFormat->direct.alphaMask > 0)
+ break;
+#else
+ if (visual->depth == 32)
+ break;
+#endif
+ }
+ } else {
+ break; // Just choose the first in the list if there's no alpha requested
+ }
+ }
+
+ XFree(configs);
+ }
+ reducedFormat = qglx_reduceSurfaceFormat(reducedFormat,&reduced);
+ }
+
+ if (!chosenConfig)
+ qWarning("Warning: no suitable glx confiuration found");
+
+ return chosenConfig;
+}
+
+XVisualInfo *qglx_findVisualInfo(Display *display, int screen, const QSurfaceFormat &format)
+{
+ GLXFBConfig config = qglx_findConfig(display,screen,format);
+ XVisualInfo *visualInfo = glXGetVisualFromFBConfig(display,config);
+ return visualInfo;
+}
+
+QSurfaceFormat qglx_surfaceFormatFromGLXFBConfig(Display *display, GLXFBConfig config, GLXContext)
+{
+ QSurfaceFormat format;
+ int redSize = 0;
+ int greenSize = 0;
+ int blueSize = 0;
+ int alphaSize = 0;
+ int depthSize = 0;
+ int stencilSize = 0;
+ int sampleBuffers = 0;
+ int sampleCount = 0;
+ int stereo = 0;
+
+ XVisualInfo *vi = glXGetVisualFromFBConfig(display,config);
+ XFree(vi);
+ glXGetFBConfigAttrib(display, config, GLX_RED_SIZE, &redSize);
+ glXGetFBConfigAttrib(display, config, GLX_GREEN_SIZE, &greenSize);
+ glXGetFBConfigAttrib(display, config, GLX_BLUE_SIZE, &blueSize);
+ glXGetFBConfigAttrib(display, config, GLX_ALPHA_SIZE, &alphaSize);
+ glXGetFBConfigAttrib(display, config, GLX_DEPTH_SIZE, &depthSize);
+ glXGetFBConfigAttrib(display, config, GLX_STENCIL_SIZE, &stencilSize);
+ glXGetFBConfigAttrib(display, config, GLX_SAMPLES, &sampleBuffers);
+ glXGetFBConfigAttrib(display, config, GLX_STEREO, &stereo);
+
+ format.setRedBufferSize(redSize);
+ format.setGreenBufferSize(greenSize);
+ format.setBlueBufferSize(blueSize);
+ format.setAlphaBufferSize(alphaSize);
+ format.setDepthBufferSize(depthSize);
+ format.setStencilBufferSize(stencilSize);
+ if (sampleBuffers) {
+ glXGetFBConfigAttrib(display, config, GLX_SAMPLES_ARB, &sampleCount);
+ format.setSamples(sampleCount);
+ }
+
+ format.setStereo(stereo);
+
+ return format;
+}
+
+QSurfaceFormat qglx_reduceSurfaceFormat(const QSurfaceFormat &format, bool *reduced)
+{
+ QSurfaceFormat retFormat = format;
+ *reduced = true;
+
+ if (retFormat.samples() > 1) {
+ retFormat.setSamples(0);
+ } else if (retFormat.stereo()) {
+ retFormat.setStereo(false);
+ }else if (retFormat.stencilBufferSize() > 0) {
+ retFormat.setStencilBufferSize(0);
+ }else if (retFormat.hasAlpha()) {
+ retFormat.setAlphaBufferSize(0);
+ }else if (retFormat.depthBufferSize() > 0) {
+ retFormat.setDepthBufferSize(0);
+ }else{
+ *reduced = false;
+ }
+ return retFormat;
+}
diff --git a/src/platformsupport/glxconvenience/qglxconvenience_p.h b/src/platformsupport/glxconvenience/qglxconvenience_p.h
new file mode 100644
index 0000000000..4892b07729
--- /dev/null
+++ b/src/platformsupport/glxconvenience/qglxconvenience_p.h
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGLXCONVENIENCE_H
+#define QGLXCONVENIENCE_H
+
+#include <QSurfaceFormat>
+#include <QVector>
+
+#include <X11/Xlib.h>
+#include <GL/glx.h>
+
+XVisualInfo *qglx_findVisualInfo(Display *display, int screen, const QSurfaceFormat &format);
+GLXFBConfig qglx_findConfig(Display *display, int screen, const QSurfaceFormat &format, int drawableBit = GLX_WINDOW_BIT);
+QSurfaceFormat qglx_surfaceFormatFromGLXFBConfig(Display *display, GLXFBConfig config, GLXContext context);
+QVector<int> qglx_buildSpec(const QSurfaceFormat &format, int drawableBit = GLX_WINDOW_BIT);
+QSurfaceFormat qglx_reduceSurfaceFormat(const QSurfaceFormat &format, bool *reduced);
+
+#endif // QGLXCONVENIENCE_H
diff --git a/src/platformsupport/inputcontext/inputcontext.pri b/src/platformsupport/inputcontext/inputcontext.pri
new file mode 100644
index 0000000000..e1a44684ba
--- /dev/null
+++ b/src/platformsupport/inputcontext/inputcontext.pri
@@ -0,0 +1,6 @@
+HEADERS += \
+ $$PWD/qplatforminputcontextplugin_qpa_p.h \
+ $$PWD/qplatforminputcontextfactory_qpa_p.h
+SOURCES += \
+ $$PWD/qplatforminputcontextplugin_qpa.cpp \
+ $$PWD/qplatforminputcontextfactory_qpa.cpp
diff --git a/src/platformsupport/inputcontext/qplatforminputcontextfactory_qpa.cpp b/src/platformsupport/inputcontext/qplatforminputcontextfactory_qpa.cpp
new file mode 100644
index 0000000000..fa16fea628
--- /dev/null
+++ b/src/platformsupport/inputcontext/qplatforminputcontextfactory_qpa.cpp
@@ -0,0 +1,110 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qplatforminputcontextfactory_qpa_p.h"
+#include "qplatforminputcontextplugin_qpa_p.h"
+#include <QPlatformInputContext>
+#include "private/qfactoryloader_p.h"
+
+#include "qguiapplication.h"
+#include "qdebug.h"
+#include <stdlib.h>
+
+QT_BEGIN_NAMESPACE
+
+#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
+ (QPlatformInputContextFactoryInterface_iid, QLatin1String("/platforminputcontexts"), Qt::CaseInsensitive))
+#endif
+
+QStringList QPlatformInputContextFactory::keys()
+{
+#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+ QStringList list = loader()->keys();
+#else
+ QStringList list;
+#endif
+ return list;
+}
+
+QPlatformInputContext *QPlatformInputContextFactory::create(const QString& key)
+{
+ QPlatformInputContext *ret = 0;
+ QStringList paramList = key.split(QLatin1Char(':'));
+ QString platform = paramList.takeFirst().toLower();
+
+#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+ if (QPlatformInputContextFactoryInterface *factory = qobject_cast<QPlatformInputContextFactoryInterface*>(loader()->instance(platform)))
+ ret = factory->create(platform, paramList);
+#endif
+ return ret;
+}
+
+QPlatformInputContext *QPlatformInputContextFactory::create()
+{
+ QPlatformInputContext *ic = 0;
+
+ QString icString = QString::fromLatin1(getenv("QT_IM_MODULE"));
+ ic = create(icString);
+
+ if (ic && ic->isValid())
+ return ic;
+
+ delete ic;
+ ic = 0;
+
+ QStringList k = keys();
+ for (int i = 0; i < k.size(); ++i) {
+ if (k.at(i) == icString)
+ continue;
+ ic = create(k.at(i));
+ if (ic && ic->isValid())
+ return ic;
+ delete ic;
+ ic = 0;
+ }
+
+ return 0;
+}
+
+
+QT_END_NAMESPACE
+
diff --git a/src/platformsupport/inputcontext/qplatforminputcontextfactory_qpa_p.h b/src/platformsupport/inputcontext/qplatforminputcontextfactory_qpa_p.h
new file mode 100644
index 0000000000..5c42931357
--- /dev/null
+++ b/src/platformsupport/inputcontext/qplatforminputcontextfactory_qpa_p.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPLATFORMINPUTCONTEXTFACTORY_H
+#define QPLATFORMINPUTCONTEXTFACTORY_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qstringlist.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QPlatformInputContext;
+
+class QPlatformInputContextFactory
+{
+public:
+ static QStringList keys();
+ static QPlatformInputContext *create(const QString &key);
+ static QPlatformInputContext *create();
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QPLATFORMINPUTCONTEXTFACTORY_H
+
diff --git a/src/platformsupport/inputcontext/qplatforminputcontextplugin_qpa.cpp b/src/platformsupport/inputcontext/qplatforminputcontextplugin_qpa.cpp
new file mode 100644
index 0000000000..380ab06d9c
--- /dev/null
+++ b/src/platformsupport/inputcontext/qplatforminputcontextplugin_qpa.cpp
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qplatforminputcontextplugin_qpa_p.h"
+
+QT_BEGIN_NAMESPACE
+
+QPlatformInputContextPlugin::QPlatformInputContextPlugin(QObject *parent)
+ : QObject(parent)
+{
+}
+
+QPlatformInputContextPlugin::~QPlatformInputContextPlugin()
+{
+}
+
+QT_END_NAMESPACE
diff --git a/src/platformsupport/inputcontext/qplatforminputcontextplugin_qpa_p.h b/src/platformsupport/inputcontext/qplatforminputcontextplugin_qpa_p.h
new file mode 100644
index 0000000000..1dfb759682
--- /dev/null
+++ b/src/platformsupport/inputcontext/qplatforminputcontextplugin_qpa_p.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPLATFORMINPUTCONTEXTPLUGIN_H
+#define QPLATFORMINPUTCONTEXTPLUGIN_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qplugin.h>
+#include <QtCore/qfactoryinterface.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QPlatformInputContext;
+
+ struct QPlatformInputContextFactoryInterface : public QFactoryInterface
+{
+ virtual QPlatformInputContext *create(const QString &key, const QStringList &paramList) = 0;
+};
+
+#define QPlatformInputContextFactoryInterface_iid "com.nokia.Qt.QPlatformInputContextFactoryInterface"
+
+Q_DECLARE_INTERFACE(QPlatformInputContextFactoryInterface, QPlatformInputContextFactoryInterface_iid)
+
+class Q_GUI_EXPORT QPlatformInputContextPlugin : public QObject, public QPlatformInputContextFactoryInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QPlatformInputContextFactoryInterface:QFactoryInterface)
+public:
+ explicit QPlatformInputContextPlugin(QObject *parent = 0);
+ ~QPlatformInputContextPlugin();
+
+ virtual QStringList keys() const = 0;
+ virtual QPlatformInputContext *create(const QString &key, const QStringList &paramList) = 0;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QPLATFORMINPUTCONTEXTPLUGIN_H
diff --git a/src/platformsupport/platformsupport.pro b/src/platformsupport/platformsupport.pro
new file mode 100644
index 0000000000..9d6f8dcd41
--- /dev/null
+++ b/src/platformsupport/platformsupport.pro
@@ -0,0 +1,33 @@
+load(qt_module)
+TARGET = QtPlatformSupport
+QPRO_PWD = $$PWD
+QT += core-private gui-private
+TEMPLATE = lib
+DESTDIR = $$QMAKE_LIBDIR_QT
+
+CONFIG += module
+CONFIG += staticlib
+mac:LIBS += -lz -framework CoreFoundation -framework Carbon
+
+MODULE_PRI = ../modules/qt_platformsupport.pri
+
+load(qt_module_config)
+
+unix|win32-g++*:QMAKE_PKGCONFIG_REQUIRES = QtCore QtGui
+
+include(../qbase.pri)
+
+HEADERS += $$PWD/qtplatformsupportversion.h
+
+DEFINES += QT_NO_CAST_FROM_ASCII
+PRECOMPILED_HEADER = ../corelib/global/qt_pch.h
+
+include(cglconvenience/cglconvenience.pri)
+include(dnd/dnd.pri)
+include(eglconvenience/eglconvenience.pri)
+include(eventdispatchers/eventdispatchers.pri)
+include(fb_base/fb_base.pri)
+include(fontdatabases/fontdatabases.pri)
+include(glxconvenience/glxconvenience.pri)
+include(printersupport/printersupport.pri)
+include(inputcontext/inputcontext.pri)
diff --git a/src/platformsupport/printersupport/genericunix/genericunix.pri b/src/platformsupport/printersupport/genericunix/genericunix.pri
new file mode 100644
index 0000000000..55534c098e
--- /dev/null
+++ b/src/platformsupport/printersupport/genericunix/genericunix.pri
@@ -0,0 +1,4 @@
+QT += printsupport printsupport-private
+
+HEADERS += $$PWD/qgenericunixprintersupport_p.h
+SOURCES += $$PWD/qgenericunixprintersupport.cpp
diff --git a/src/platformsupport/printersupport/genericunix/qgenericunixprintersupport.cpp b/src/platformsupport/printersupport/genericunix/qgenericunixprintersupport.cpp
new file mode 100644
index 0000000000..bac5ba20f0
--- /dev/null
+++ b/src/platformsupport/printersupport/genericunix/qgenericunixprintersupport.cpp
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qgenericunixprintersupport_p.h"
+
+#include <QtPrintSupport/QPrinterInfo>
+#include <private/qcups_p.h>
+
+QT_BEGIN_NAMESPACE
+
+QList<QPrinter::PaperSize> QGenericUnixPrinterSupport::supportedPaperSizes(const QPrinterInfo &printerInfo) const
+{
+#ifndef QT_NO_CUPS
+ return QCUPSSupport::getCupsPrinterPaperSizes(QPlatformPrinterSupport::printerInfoCupsPrinterIndex(printerInfo));
+#else
+ return QList<QPrinter::PaperSize>();
+#endif
+}
+
+QList<QPrinterInfo> QGenericUnixPrinterSupport::availablePrinters()
+{
+ QList<QPrinterInfo> printers;
+#ifndef QT_NO_CUPS
+ foreach (const QCUPSSupport::Printer &p, QCUPSSupport::availableUnixPrinters()) {
+ QPrinterInfo printer(QPlatformPrinterSupport::printerInfo(p.name, p.isDefault));
+ QPlatformPrinterSupport::setPrinterInfoCupsPrinterIndex(&printer, p.cupsPrinterIndex);
+ printers.append(printer);
+ }
+#endif
+ return printers;
+}
+
+QT_END_NAMESPACE
diff --git a/src/platformsupport/printersupport/genericunix/qgenericunixprintersupport_p.h b/src/platformsupport/printersupport/genericunix/qgenericunixprintersupport_p.h
new file mode 100644
index 0000000000..bcfc36799f
--- /dev/null
+++ b/src/platformsupport/printersupport/genericunix/qgenericunixprintersupport_p.h
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGENERICUNIXPRINTINGSUPPORT_H
+#define QGENERICUNIXPRINTINGSUPPORT_H
+
+#include <QtPrintSupport/QPlatformPrinterSupport>
+
+QT_BEGIN_NAMESPACE
+
+class QGenericUnixPrinterSupport : public QPlatformPrinterSupport
+{
+public:
+ virtual QList<QPrinter::PaperSize> supportedPaperSizes(const QPrinterInfo &) const;
+
+ virtual QList<QPrinterInfo> availablePrinters();
+};
+
+QT_END_NAMESPACE
+
+#endif // QGENERICUNIXPRINTINGSUPPORT_H
diff --git a/src/platformsupport/printersupport/printersupport.pri b/src/platformsupport/printersupport/printersupport.pri
new file mode 100644
index 0000000000..797ac771e7
--- /dev/null
+++ b/src/platformsupport/printersupport/printersupport.pri
@@ -0,0 +1,3 @@
+unix {
+ include($$PWD/genericunix/genericunix.pri)
+}
diff --git a/src/plugins/accessible/widgets/complexwidgets.h b/src/plugins/accessible/widgets/complexwidgets.h
index c6453f19c4..3c01445091 100644
--- a/src/plugins/accessible/widgets/complexwidgets.h
+++ b/src/plugins/accessible/widgets/complexwidgets.h
@@ -43,9 +43,9 @@
#define COMPLEXWIDGETS_H
#include <QtCore/qpointer.h>
-#include <QtGui/qaccessiblewidget.h>
-#include <QtGui/qabstractitemview.h>
-#include <QtGui/qaccessible2.h>
+#include <QtWidgets/qaccessiblewidget.h>
+#include <QtWidgets/qabstractitemview.h>
+#include <QtWidgets/qaccessible2.h>
QT_BEGIN_NAMESPACE
diff --git a/src/plugins/accessible/widgets/itemviews.h b/src/plugins/accessible/widgets/itemviews.h
index c8492e3c89..2c981ef0e8 100644
--- a/src/plugins/accessible/widgets/itemviews.h
+++ b/src/plugins/accessible/widgets/itemviews.h
@@ -42,11 +42,11 @@
#ifndef ACCESSIBLE_ITEMVIEWS_H
#define ACCESSIBLE_ITEMVIEWS_H
-#include <QtGui/qabstractitemview.h>
-#include <QtGui/qheaderview.h>
-#include <QtGui/qaccessible.h>
-#include <QtGui/qaccessible2.h>
-#include <QtGui/qaccessiblewidget.h>
+#include <QtWidgets/qabstractitemview.h>
+#include <QtWidgets/qheaderview.h>
+#include <QtWidgets/qaccessible.h>
+#include <QtWidgets/qaccessible2.h>
+#include <QtWidgets/qaccessiblewidget.h>
QT_BEGIN_NAMESPACE
diff --git a/src/plugins/accessible/widgets/qaccessiblemenu.cpp b/src/plugins/accessible/widgets/qaccessiblemenu.cpp
index 1454c7c80b..8e72910b45 100644
--- a/src/plugins/accessible/widgets/qaccessiblemenu.cpp
+++ b/src/plugins/accessible/widgets/qaccessiblemenu.cpp
@@ -43,7 +43,7 @@
#include <qmenu.h>
#include <qmenubar.h>
-#include <QtGui/QAction>
+#include <QtWidgets/QAction>
#include <qstyle.h>
#ifndef QT_NO_ACCESSIBILITY
diff --git a/src/plugins/accessible/widgets/qaccessiblemenu.h b/src/plugins/accessible/widgets/qaccessiblemenu.h
index 680594d667..1ee6d5436f 100644
--- a/src/plugins/accessible/widgets/qaccessiblemenu.h
+++ b/src/plugins/accessible/widgets/qaccessiblemenu.h
@@ -42,7 +42,7 @@
#ifndef QACCESSIBLEMENU_H
#define QACCESSIBLEMENU_H
-#include <QtGui/qaccessiblewidget.h>
+#include <QtWidgets/qaccessiblewidget.h>
QT_BEGIN_NAMESPACE
diff --git a/src/plugins/accessible/widgets/qaccessiblewidgets.cpp b/src/plugins/accessible/widgets/qaccessiblewidgets.cpp
index a0dde37ed6..a8f38b61a3 100644
--- a/src/plugins/accessible/widgets/qaccessiblewidgets.cpp
+++ b/src/plugins/accessible/widgets/qaccessiblewidgets.cpp
@@ -65,7 +65,7 @@
#include <QMainWindow>
#include <QAbstractButton>
#include <private/qdockwidget_p.h>
-#include <QtGui/QFocusFrame>
+#include <QFocusFrame>
#ifndef QT_NO_ACCESSIBILITY
diff --git a/src/plugins/accessible/widgets/qaccessiblewidgets.h b/src/plugins/accessible/widgets/qaccessiblewidgets.h
index 242f8c1610..942012896b 100644
--- a/src/plugins/accessible/widgets/qaccessiblewidgets.h
+++ b/src/plugins/accessible/widgets/qaccessiblewidgets.h
@@ -42,8 +42,8 @@
#ifndef QACCESSIBLEWIDGETS_H
#define QACCESSIBLEWIDGETS_H
-#include <QtGui/qaccessible2.h>
-#include <QtGui/qaccessiblewidget.h>
+#include <QtWidgets/qaccessible2.h>
+#include <QtWidgets/qaccessiblewidget.h>
#ifndef QT_NO_ACCESSIBILITY
diff --git a/src/plugins/accessible/widgets/rangecontrols.h b/src/plugins/accessible/widgets/rangecontrols.h
index 0f21a5a119..529a331c94 100644
--- a/src/plugins/accessible/widgets/rangecontrols.h
+++ b/src/plugins/accessible/widgets/rangecontrols.h
@@ -42,8 +42,8 @@
#ifndef RANGECONTROLS_H
#define RANGECONTROLS_H
-#include <QtGui/qaccessiblewidget.h>
-#include <QtGui/qaccessible2.h>
+#include <QtWidgets/qaccessiblewidget.h>
+#include <QtWidgets/qaccessible2.h>
QT_BEGIN_NAMESPACE
diff --git a/src/plugins/accessible/widgets/simplewidgets.h b/src/plugins/accessible/widgets/simplewidgets.h
index d5144caebd..7cc14410cf 100644
--- a/src/plugins/accessible/widgets/simplewidgets.h
+++ b/src/plugins/accessible/widgets/simplewidgets.h
@@ -43,8 +43,8 @@
#define SIMPLEWIDGETS_H
#include <QtCore/qcoreapplication.h>
-#include <QtGui/qaccessible2.h>
-#include <QtGui/qaccessiblewidget.h>
+#include <QtWidgets/qaccessible2.h>
+#include <QtWidgets/qaccessiblewidget.h>
QT_BEGIN_NAMESPACE
diff --git a/src/plugins/accessible/widgets/widgets.pro b/src/plugins/accessible/widgets/widgets.pro
index d1a121ec94..3bf7dede56 100644
--- a/src/plugins/accessible/widgets/widgets.pro
+++ b/src/plugins/accessible/widgets/widgets.pro
@@ -2,7 +2,7 @@ TARGET = qtaccessiblewidgets
load(qt_plugin)
include (../qaccessiblebase.pri)
-QT += core-private gui-private
+QT += core-private gui-private widgets-private
DESTDIR = $$QT.gui.plugins/accessible
QTDIR_build:REQUIRES += "contains(QT_CONFIG, accessibility)"
diff --git a/src/plugins/decorations/decorations.pro b/src/plugins/decorations/decorations.pro
deleted file mode 100644
index 3d6912e77c..0000000000
--- a/src/plugins/decorations/decorations.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-TEMPLATE = subdirs
-contains(decoration-plugins, default) :SUBDIRS += default
-contains(decoration-plugins, styled) :SUBDIRS += styled
-contains(decoration-plugins, windows) :SUBDIRS += windows
diff --git a/src/plugins/decorations/default/default.pro b/src/plugins/decorations/default/default.pro
deleted file mode 100644
index c323d10930..0000000000
--- a/src/plugins/decorations/default/default.pro
+++ /dev/null
@@ -1,10 +0,0 @@
-TARGET = qdecorationdefault
-load(qt_plugin)
-
-HEADERS = $$QT_SOURCE_TREE/src/gui/embedded/qdecorationdefault_qws.h
-SOURCES = main.cpp \
- $$QT_SOURCE_TREE/src/gui/embedded/qdecorationdefault_qws.cpp
-
-DESTDIR = $$QT.gui.plugins/decorations
-target.path += $$[QT_INSTALL_PLUGINS]/decorations
-INSTALLS += target
diff --git a/src/plugins/decorations/default/main.cpp b/src/plugins/decorations/default/main.cpp
deleted file mode 100644
index b93b6f8b0e..0000000000
--- a/src/plugins/decorations/default/main.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qdecorationplugin_qws.h>
-#include <qdecorationdefault_qws.h>
-
-QT_BEGIN_NAMESPACE
-
-class DecorationDefault : public QDecorationPlugin
-{
-public:
- DecorationDefault();
-
- QStringList keys() const;
- QDecoration *create(const QString&);
-};
-
-DecorationDefault::DecorationDefault()
- : QDecorationPlugin()
-{
-}
-
-QStringList DecorationDefault::keys() const
-{
- return (QStringList() << QLatin1String("Default"));
-}
-
-QDecoration* DecorationDefault::create(const QString& s)
-{
- if (s.toLower() == QLatin1String("default"))
- return new QDecorationDefault();
-
- return 0;
-}
-
-Q_EXPORT_PLUGIN2(qdecorationdefault, DecorationDefault)
-
-QT_END_NAMESPACE
diff --git a/src/plugins/decorations/styled/main.cpp b/src/plugins/decorations/styled/main.cpp
deleted file mode 100644
index 69c339843a..0000000000
--- a/src/plugins/decorations/styled/main.cpp
+++ /dev/null
@@ -1,77 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qdecorationplugin_qws.h>
-#include <qdecorationstyled_qws.h>
-
-QT_BEGIN_NAMESPACE
-
-class DecorationStyled : public QDecorationPlugin
-{
-public:
- DecorationStyled();
-
- QStringList keys() const;
- QDecoration *create(const QString&);
-};
-
-DecorationStyled::DecorationStyled() : QDecorationPlugin()
-{
-}
-
-QStringList DecorationStyled::keys() const
-{
- return (QStringList() << QLatin1String("Styled"));
-}
-
-QDecoration* DecorationStyled::create(const QString& s)
-{
- if (s.toLower() != QLatin1String("styled"))
- return 0;
-
- qDebug("creatign styled decoration");
-
- return new QDecorationStyled;
-}
-
-Q_EXPORT_PLUGIN2(qdecorationstyled, DecorationStyled)
-
-QT_END_NAMESPACE
diff --git a/src/plugins/decorations/styled/styled.pro b/src/plugins/decorations/styled/styled.pro
deleted file mode 100644
index c5329aea29..0000000000
--- a/src/plugins/decorations/styled/styled.pro
+++ /dev/null
@@ -1,13 +0,0 @@
-TARGET = qdecorationstyled
-load(qt_plugin)
-
-DESTDIR = $$QT.gui.plugins/decorations
-target.path += $$[QT_INSTALL_PLUGINS]/decorations
-INSTALLS += target
-
-DEFINES += QT_QWS_DECORATION_STYLED
-
-HEADERS = $$QT_SOURCE_TREE/src/gui/embedded/qdecorationstyled_qws.h
-SOURCES = main.cpp \
- $$QT_SOURCE_TREE/src/gui/embedded/qdecorationstyled_qws.cpp
-
diff --git a/src/plugins/decorations/windows/main.cpp b/src/plugins/decorations/windows/main.cpp
deleted file mode 100644
index 8ee8a156e8..0000000000
--- a/src/plugins/decorations/windows/main.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qdecorationplugin_qws.h>
-#include <qdecorationwindows_qws.h>
-
-QT_BEGIN_NAMESPACE
-
-class DecorationWindows : public QDecorationPlugin
-{
-public:
- DecorationWindows();
-
- QStringList keys() const;
- QDecoration *create(const QString&);
-};
-
-DecorationWindows::DecorationWindows()
- : QDecorationPlugin()
-{
-}
-
-QStringList DecorationWindows::keys() const
-{
- return (QStringList() << QLatin1String("Windows"));
-}
-
-QDecoration* DecorationWindows::create(const QString& s)
-{
- if (s.toLower() == QLatin1String("windows"))
- return new QDecorationWindows();
-
- return 0;
-}
-
-Q_EXPORT_PLUGIN2(qdecorationwindows, DecorationWindows)
-
-QT_END_NAMESPACE
diff --git a/src/plugins/decorations/windows/windows.pro b/src/plugins/decorations/windows/windows.pro
deleted file mode 100644
index f27adb908b..0000000000
--- a/src/plugins/decorations/windows/windows.pro
+++ /dev/null
@@ -1,10 +0,0 @@
-TARGET = qdecorationwindows
-load(qt_plugin)
-
-HEADERS = $$QT_SOURCE_TREE/src/gui/embedded/qdecorationwindows_qws.h
-SOURCES = main.cpp \
- $$QT_SOURCE_TREE/src/gui/embedded/qdecorationwindows_qws.cpp
-
-DESTDIR = $$QT.gui.plugins/decorations
-target.path += $$[QT_INSTALL_PLUGINS]/decorations
-INSTALLS += target
diff --git a/src/plugins/generic/linuxinput/linuxinput.pro b/src/plugins/generic/linuxinput/linuxinput.pro
index 18cb04e973..6ef5f0fb3a 100644
--- a/src/plugins/generic/linuxinput/linuxinput.pro
+++ b/src/plugins/generic/linuxinput/linuxinput.pro
@@ -5,8 +5,6 @@ DESTDIR = $$QT.gui.plugins/generic
target.path = $$[QT_INSTALL_PLUGINS]/generic
INSTALLS += target
-DEFINES += QT_QWS_KBD_LINUXINPUT
-
HEADERS = qlinuxinput.h
QT += core-private
@@ -14,7 +12,3 @@ QT += core-private
SOURCES = main.cpp \
qlinuxinput.cpp
-HEADERS += $$QT_SOURCE_TREE/src/gui/embedded/qkbd_qws.h \
- $$QT_SOURCE_TREE/src/gui/embedded/qkbd_qws_p.h
-
-SOURCES += $$QT_SOURCE_TREE/src/gui/embedded/qkbd_qws.cpp
diff --git a/src/plugins/generic/linuxinput/main.cpp b/src/plugins/generic/linuxinput/main.cpp
index 9c38dba199..20391901bf 100644
--- a/src/plugins/generic/linuxinput/main.cpp
+++ b/src/plugins/generic/linuxinput/main.cpp
@@ -61,8 +61,7 @@ QLinuxInputPlugin::QLinuxInputPlugin()
QStringList QLinuxInputPlugin::keys() const
{
return (QStringList()
- << QLatin1String("LinuxInputMouse")
- << QLatin1String("LinuxInputKeyboard"));
+ << QLatin1String("LinuxInputMouse"));
}
QObject* QLinuxInputPlugin::create(const QString &key,
@@ -70,8 +69,6 @@ QObject* QLinuxInputPlugin::create(const QString &key,
{
if (!key.compare(QLatin1String("LinuxInputMouse"), Qt::CaseInsensitive))
return new QLinuxInputMouseHandler(key, specification);
- if (!key.compare(QLatin1String("LinuxInputKeyboard"), Qt::CaseInsensitive))
- return new QLinuxInputKeyboardHandler(key, specification);
return 0;
}
diff --git a/src/plugins/generic/linuxinput/qlinuxinput.cpp b/src/plugins/generic/linuxinput/qlinuxinput.cpp
index 2316f089cc..943b213ce0 100644
--- a/src/plugins/generic/linuxinput/qlinuxinput.cpp
+++ b/src/plugins/generic/linuxinput/qlinuxinput.cpp
@@ -48,9 +48,6 @@
#include <QPoint>
#include <QWindowSystemInterface>
-#include <qkbd_qws.h>
-
-
#include <qplatformdefs.h>
#include <private/qcore_unix_p.h> // overrides QT_OPEN
@@ -361,195 +358,6 @@ void QLinuxInputMouseHandler::readMouseData()
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-//Keyboard handler
-
-
-
-
-class QWSLinuxInputKeyboardHandler : public QWSKeyboardHandler
-{
-public:
- QWSLinuxInputKeyboardHandler(const QString&);
- ~QWSLinuxInputKeyboardHandler();
-
- virtual bool filterInputEvent(quint16 &input_code, qint32 &input_value);
-
-//private:
-// QWSLinuxInputKbPrivate *d;
-};
-
-
-QWSLinuxInputKeyboardHandler::QWSLinuxInputKeyboardHandler(const QString &device)
- : QWSKeyboardHandler(device)
-{
-}
-
-QWSLinuxInputKeyboardHandler::~QWSLinuxInputKeyboardHandler()
-{
-}
-
-bool QWSLinuxInputKeyboardHandler::filterInputEvent(quint16 &, qint32 &)
-{
- return false;
-}
-
-
-QLinuxInputKeyboardHandler::QLinuxInputKeyboardHandler(const QString &key, const QString &specification)
- : m_handler(0), m_fd(-1), m_tty_fd(-1), m_orig_kbmode(K_XLATE)
-{
- setObjectName(QLatin1String("LinuxInputSubsystem Keyboard Handler"));
-
- QString dev = QLatin1String("/dev/input/event1");
- int repeat_delay = -1;
- int repeat_rate = -1;
-
- bool ttymode = false;
-
- QStringList args = specification.split(QLatin1Char(':'));
- foreach (const QString &arg, args) {
- if (arg.startsWith(QLatin1String("repeat-delay=")))
- repeat_delay = arg.mid(13).toInt();
- else if (arg.startsWith(QLatin1String("repeat-rate=")))
- repeat_rate = arg.mid(12).toInt();
- else if (arg.startsWith(QLatin1String("ttymode")))
- ttymode = true;
- else if (arg.startsWith(QLatin1String("/dev/")))
- dev = arg;
- }
-
- m_handler = new QWSLinuxInputKeyboardHandler(dev); //This is a hack to avoid copying all the QWS code
-
- m_fd = QT_OPEN(dev.toLocal8Bit().constData(), O_RDWR, 0);
- if (m_fd >= 0) {
- if (repeat_delay > 0 && repeat_rate > 0) {
- int kbdrep[2] = { repeat_delay, repeat_rate };
- ::ioctl(m_fd, EVIOCSREP, kbdrep);
- }
-
- QSocketNotifier *notifier;
- notifier = new QSocketNotifier(m_fd, QSocketNotifier::Read, this);
- connect(notifier, SIGNAL(activated(int)), this, SLOT(readKeycode()));
-
- if (ttymode) {
- // play nice in case we are started from a shell (e.g. for debugging)
- m_tty_fd = isatty(0) ? 0 : -1;
-
- if (m_tty_fd >= 0) {
- // save tty config for restore.
- tcgetattr(m_tty_fd, &m_tty_attr);
-
- struct ::termios termdata;
- tcgetattr(m_tty_fd, &termdata);
-
- // record the original mode so we can restore it again in the destructor.
- ::ioctl(m_tty_fd, KDGKBMODE, &m_orig_kbmode);
-
- // setting this translation mode is even needed in INPUT mode to prevent
- // the shell from also interpreting codes, if the process has a tty
- // attached: e.g. Ctrl+C wouldn't copy, but kill the application.
- ::ioctl(m_tty_fd, KDSKBMODE, K_MEDIUMRAW);
-
- // set the tty layer to pass-through
- termdata.c_iflag = (IGNPAR | IGNBRK) & (~PARMRK) & (~ISTRIP);
- termdata.c_oflag = 0;
- termdata.c_cflag = CREAD | CS8;
- termdata.c_lflag = 0;
- termdata.c_cc[VTIME]=0;
- termdata.c_cc[VMIN]=1;
- cfsetispeed(&termdata, 9600);
- cfsetospeed(&termdata, 9600);
- tcsetattr(m_tty_fd, TCSANOW, &termdata);
- }
- }
- } else {
- qWarning("Cannot open keyboard input device '%s': %s", qPrintable(dev), strerror(errno));
- return;
- }
-}
-
-QLinuxInputKeyboardHandler::~QLinuxInputKeyboardHandler()
-{
- if (m_tty_fd >= 0) {
- ::ioctl(m_tty_fd, KDSKBMODE, m_orig_kbmode);
- tcsetattr(m_tty_fd, TCSANOW, &m_tty_attr);
- }
- if (m_fd >= 0)
- QT_CLOSE(m_fd);
- delete m_handler;
-}
-
-void QLinuxInputKeyboardHandler::switchLed(int led, bool state)
-{
- struct ::input_event led_ie;
- ::gettimeofday(&led_ie.time, 0);
- led_ie.type = EV_LED;
- led_ie.code = led;
- led_ie.value = state;
-
- QT_WRITE(m_fd, &led_ie, sizeof(led_ie));
-}
-
-
-
-void QLinuxInputKeyboardHandler::readKeycode()
-{
- struct ::input_event buffer[32];
- int n = 0;
-
- forever {
- n = QT_READ(m_fd, reinterpret_cast<char *>(buffer) + n, sizeof(buffer) - n);
-
- if (n == 0) {
- qWarning("Got EOF from the input device.");
- return;
- } else if (n < 0 && (errno != EINTR && errno != EAGAIN)) {
- qWarning("Could not read from input device: %s", strerror(errno));
- return;
- } else if (n % sizeof(buffer[0]) == 0) {
- break;
- }
- }
-
- n /= sizeof(buffer[0]);
-
- for (int i = 0; i < n; ++i) {
- if (buffer[i].type != EV_KEY)
- continue;
-
- quint16 code = buffer[i].code;
- qint32 value = buffer[i].value;
-
- if (m_handler->filterInputEvent(code, value))
- continue;
-
- QWSKeyboardHandler::KeycodeAction ka;
- ka = m_handler->processKeycode(code, value != 0, value == 2);
-
- switch (ka) {
- case QWSKeyboardHandler::CapsLockOn:
- case QWSKeyboardHandler::CapsLockOff:
- switchLed(LED_CAPSL, ka == QWSKeyboardHandler::CapsLockOn);
- break;
-
- case QWSKeyboardHandler::NumLockOn:
- case QWSKeyboardHandler::NumLockOff:
- switchLed(LED_NUML, ka == QWSKeyboardHandler::NumLockOn);
- break;
-
- case QWSKeyboardHandler::ScrollLockOn:
- case QWSKeyboardHandler::ScrollLockOff:
- switchLed(LED_SCROLLL, ka == QWSKeyboardHandler::ScrollLockOn);
- break;
-
- default:
- // ignore console switching and reboot
- break;
- }
- }
-}
-
-
diff --git a/src/plugins/generic/linuxinput/qlinuxinput.h b/src/plugins/generic/linuxinput/qlinuxinput.h
index 83b91d095d..b9475a1bf5 100644
--- a/src/plugins/generic/linuxinput/qlinuxinput.h
+++ b/src/plugins/generic/linuxinput/qlinuxinput.h
@@ -79,31 +79,6 @@ private:
QLinuxInputMouseHandlerData *d;
};
-
-class QWSLinuxInputKeyboardHandler;
-
-class QLinuxInputKeyboardHandler : public QObject
-{
- Q_OBJECT
-public:
- QLinuxInputKeyboardHandler(const QString &key, const QString &specification);
- ~QLinuxInputKeyboardHandler();
-
-
-private:
- void switchLed(int, bool);
-
-private slots:
- void readKeycode();
-
-private:
- QWSLinuxInputKeyboardHandler *m_handler;
- int m_fd;
- int m_tty_fd;
- struct termios m_tty_attr;
- int m_orig_kbmode;
-};
-
QT_END_NAMESPACE
QT_END_HEADER
diff --git a/src/plugins/gfxdrivers/ahi/ahi.pro b/src/plugins/gfxdrivers/ahi/ahi.pro
deleted file mode 100644
index fd078421f9..0000000000
--- a/src/plugins/gfxdrivers/ahi/ahi.pro
+++ /dev/null
@@ -1,14 +0,0 @@
-TARGET = qahiscreen
-load(qt_plugin)
-
-DESTDIR = $$QT.gui.plugins/gfxdrivers
-
-target.path = $$[QT_INSTALL_PLUGINS]/gfxdrivers
-INSTALLS += target
-
-HEADERS = qscreenahi_qws.h
-
-SOURCES = qscreenahi_qws.cpp \
- qscreenahiplugin.cpp
-
-LIBS += -lahi
diff --git a/src/plugins/gfxdrivers/ahi/qscreenahi_qws.cpp b/src/plugins/gfxdrivers/ahi/qscreenahi_qws.cpp
deleted file mode 100644
index 320aff9811..0000000000
--- a/src/plugins/gfxdrivers/ahi/qscreenahi_qws.cpp
+++ /dev/null
@@ -1,598 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qscreenahi_qws.h"
-
-#ifndef QT_NO_QWS_AHI
-
-#include <QtGui/qcolor.h>
-#include <QtGui/qapplication.h>
-#include <QtCore/qvector.h>
-#include <QtCore/qvarlengtharray.h>
-#include <private/qwssignalhandler_p.h>
-
-#include <ahi.h>
-
-//#define QAHISCREEN_DEBUG
-
-static int depthForPixelFormat(const AhiPixelFormat_t format)
-{
- switch (format) {
- case AhiPix1bpp:
- return 1;
- case AhiPix2bpp:
- return 2;
- case AhiPix4bpp:
- return 4;
- case AhiPix8bpp_332RGB:
- case AhiPix8bpp:
- return 8;
- case AhiPix16bpp_444RGB:
- return 12;
- case AhiPix16bpp_555RGB:
- return 15;
- case AhiPix16bpp_565RGB:
- return 16;
- case AhiPix32bpp_8888ARGB:
- case AhiPix32bpp_8888BGRA:
- return 32;
- default:
- return 0;
- }
-}
-
-static AhiPixelFormat_t pixelFormatForImageFormat(const QImage::Format format)
-{
- switch (format) {
- case QImage::Format_Mono:
- case QImage::Format_MonoLSB:
- return AhiPix1bpp;
- case QImage::Format_Indexed8:
- return AhiPix8bpp;
- case QImage::Format_RGB32:
- case QImage::Format_ARGB32:
- case QImage::Format_ARGB32_Premultiplied:
- return AhiPix32bpp_8888ARGB;
- case QImage::Format_RGB16:
- return AhiPix16bpp_565RGB;
- case QImage::Format_RGB555:
- return AhiPix16bpp_555RGB;
- case QImage::Format_ARGB4444_Premultiplied:
- case QImage::Format_RGB444:
- return AhiPix16bpp_444RGB;
- default:
- return AhiPixelFormatMax;
- }
-}
-
-class QAhiScreenCursor : public QScreenCursor
-{
-public:
- QAhiScreenCursor(QScreen *screen, AhiDevCtx_t context);
-
- void set(const QImage &image, int hotx, int hoty);
- void move(int x, int y);
- void show();
- void hide();
-
-private:
- QScreen *screen;
- AhiDevCtx_t context;
-};
-
-QAhiScreenCursor::QAhiScreenCursor(QScreen *s, AhiDevCtx_t c)
- : QScreenCursor(), screen(s), context(c)
-{
- hwaccel = true;
- supportsAlpha = true;
-
- if (enable)
- show();
- else
- hide();
-}
-
-void QAhiScreenCursor::set(const QImage &image, int hotx, int hoty)
-{
- if (image.isNull()) {
- QScreenCursor::set(image, hotx, hoty);
- return;
- }
-
- if (image.format() != QImage::Format_MonoLSB) {
- set(image.convertToFormat(QImage::Format_MonoLSB), hotx, hoty);
- return;
- }
-
- AhiPixelFormat_t pixFmt = pixelFormatForImageFormat(image.format());
-
- if (pixFmt >= AhiPixelFormatMax) { // generic fallback
- QImage::Format toFormat = screen->pixelFormat();
- if (toFormat == QImage::Format_Invalid)
- toFormat = QImage::Format_ARGB32;
- set(image.convertToFormat(toFormat), hotx, hoty);
- return;
- }
-
- AhiPoint_t hotSpot = { hotx, hoty };
- AhiSize_t bitmapSize = { image.width(), image.height() };
- AhiBitmap_t bitmap = { bitmapSize, (void*)(image.bits()),
- image.bytesPerLine(), pixFmt };
-
- AhiSts_t status;
- status = AhiDispCursorSet(context, AhiCursor1, &bitmap, &hotSpot,
- image.serialNumber(), 0);
- if (status != AhiStsOk)
- qWarning("QAhiScreenCursor::set(): AhiDispCursorSet failed: %x",
- status);
-
- QScreenCursor::set(image, hotx, hoty);
-}
-
-void QAhiScreenCursor::move(int x, int y)
-{
- AhiPoint_t pos = { x, y };
- AhiSts_t status = AhiDispCursorPos(context, AhiCursor1, &pos, 0);
- if (status != AhiStsOk)
- qWarning("QAhiScreenCursor::move(): error setting mouse position: %x",
- status);
- QScreenCursor::move(x, y);
-}
-
-void QAhiScreenCursor::show()
-{
- AhiSts_t status;
- status = AhiDispCursorState(context, AhiCursor1, AhiCursorStateOn, 0);
- if (status != AhiStsOk)
- qWarning("QAhiScreenCursor::show(): error setting state: %x", status);
- QScreenCursor::show();
-}
-
-void QAhiScreenCursor::hide()
-{
- AhiDispCursorState(context, AhiCursor1, AhiCursorStateOff, 0);
- QScreenCursor::hide();
-}
-
-class QAhiScreenPrivate : public QObject
-{
-public:
- QAhiScreenPrivate();
- ~QAhiScreenPrivate();
-
- bool setMode(AhiDispMode_t mode);
-
- AhiDevCtx_t context;
- AhiSurf_t surface;
- QAhiScreenCursor *cursor;
-};
-
-QT_BEGIN_NAMESPACE
-
-QAhiScreenPrivate::QAhiScreenPrivate()
- : context(0), surface(0), cursor(0)
-{
-#ifndef QT_NO_QWS_SIGNALHANDLER
- QWSSignalHandler::instance()->addObject(this);
-#endif
-}
-
-QAhiScreenPrivate::~QAhiScreenPrivate()
-{
- delete cursor;
-
- if (surface) {
- AhiSurfFree(context, surface);
- surface = 0;
- }
- if (context) {
- AhiDevClose(context);
- context = 0;
- }
- AhiTerm();
-}
-
-bool QAhiScreenPrivate::setMode(AhiDispMode_t mode)
-{
- AhiSts_t status;
-
- status = AhiDispModeSet(context, &mode, 0);
- if (status != AhiStsOk) {
- qCritical("QAhiScreenPrivate::setMode(): AhiDispModeSet failed: %x",
- status);
- return false;
- }
-
- if (surface) {
- AhiSurfFree(context, surface);
- surface = 0;
- }
- status = AhiSurfAlloc(context, &surface, &mode.size, mode.pixFmt,
- AHIFLAG_SURFFIXED);
- if (status != AhiStsOk) {
- qCritical("QAhiScreenPrivate::setMode(): AhisurfAlloc failed: %x",
- status);
- return false;
- }
-
- status = AhiDispSurfSet(context, surface, 0);
- if (status != AhiStsOk) {
- qCritical("QAhiScreenPrivate::setMode(): AhiDispSurfSet failed: %x",
- status);
- return false;
- }
-
- return true;
-}
-
-QAhiScreen::QAhiScreen(int displayId)
- : QScreen(displayId), d_ptr(new QAhiScreenPrivate)
-{
-}
-
-QAhiScreen::~QAhiScreen()
-{
- delete d_ptr;
-}
-
-bool QAhiScreen::configure()
-{
- AhiSurfInfo_t surfaceInfo;
- AhiSts_t status;
-
- status = AhiSurfInfo(d_ptr->context, d_ptr->surface, &surfaceInfo);
- if (status != AhiStsOk) {
- qCritical("QAhiScreen::configure(): AhiSurfInfo failed: %x", status);
- return false;
- }
-
- QScreen::data = 0;
- QScreen::w = QScreen::dw = surfaceInfo.size.cx;
- QScreen::h = QScreen::dh = surfaceInfo.size.cy;
- QScreen::lstep = surfaceInfo.stride;
- QScreen::size = surfaceInfo.sizeInBytes;
-
- switch (surfaceInfo.pixFmt) {
- case AhiPix1bpp:
- setPixelFormat(QImage::Format_Mono);
- QScreen::d = 1;
- break;
- case AhiPix4bpp:
- QScreen::d = 4;
- break;
- case AhiPix8bpp_332RGB:
- case AhiPix8bpp:
- QScreen::d = 8;
- break;
- case AhiPix16bpp_444RGB:
- setPixelFormat(QImage::Format_RGB444);
- QScreen::d = 12;
- break;
- case AhiPix16bpp_555RGB:
- setPixelFormat(QImage::Format_RGB555);
- QScreen::d = 15;
- break;
- case AhiPix16bpp_565RGB:
- setPixelFormat(QImage::Format_RGB16);
- QScreen::d = 16;
- break;
- case AhiPix2bpp:
- QScreen::d = 2;
- break;
- case AhiPix32bpp_8888ARGB:
- setPixelFormat(QImage::Format_ARGB32);
- // fallthrough
- case AhiPix32bpp_8888BGRA:
- QScreen::d = 32;
- break;
- default:
- qCritical("QAhiScreen::configure(): Unknown pixel format: %x",
- surfaceInfo.pixFmt);
- return false;
- }
-
- const int dpi = 72;
- QScreen::physWidth = qRound(QScreen::dw * 25.4 / dpi);
- QScreen::physHeight = qRound(QScreen::dh * 25.4 / dpi);
-
- return true;
-}
-
-bool QAhiScreen::connect(const QString &displaySpec)
-{
- Q_UNUSED(displaySpec);
-
- AhiSts_t status;
-
- status = AhiInit(0);
- if (status != AhiStsOk) {
- qCritical("QAhiScreen::connect(): AhiInit failed: %x", status);
- return false;
- }
-
- AhiDev_t device;
- AhiDevInfo_t info;
-
- status = AhiDevEnum(&device, &info, 0);
- if (status != AhiStsOk) {
- qCritical("QAhiScreen::connect(): AhiDevEnum failed: %x", status);
- return false;
- }
-#ifdef QAHISCREEN_DEBUG
- {
- int displayNo = 0;
- AhiDevInfo_t dispInfo = info;
- qDebug("AHI supported devices:");
- do {
- qDebug(" %2i: %s, sw version: %s (rev %u)\n"
- " chip: 0x%x (rev %u), mem: %i (%i/%i), bus: 0x%x",
- displayNo, dispInfo.name,
- dispInfo.swVersion, uint(dispInfo.swRevision),
- uint(dispInfo.chipId), uint(dispInfo.revisionId),
- uint(dispInfo.totalMemory),
- uint(dispInfo.internalMemSize),
- uint(dispInfo.externalMemSize),
- uint(dispInfo.cpuBusInterfaceMode));
- status = AhiDevEnum(&device, &info, ++displayNo);
- } while (status == AhiStsOk);
- }
-#endif
-
- status = AhiDevOpen(&d_ptr->context, device, "qscreenahi",
- AHIFLAG_USERLEVEL);
- if (status != AhiStsOk) {
- qCritical("QAhiScreen::connect(): AhiDevOpen failed: %x", status);
- return false;
- }
-
- AhiDispMode_t mode;
-
- status = AhiDispModeEnum(d_ptr->context, &mode, 0);
- if (status != AhiStsOk) {
- qCritical("QAhiScreen::connect(): AhiDispModeEnum failed: %x", status);
- return false;
- }
-
-#ifdef QAHISCREEN_DEBUG
- {
- int modeNo = 0;
- AhiDispMode_t modeInfo = mode;
- qDebug("AHI supported modes:");
- do {
- qDebug(" %2i: %ux%u, fmt: %i, %u Hz, rot: %i, mirror: %i",
- modeNo, uint(modeInfo.size.cx), uint(modeInfo.size.cy),
- modeInfo.pixFmt, uint(modeInfo.frequency),
- modeInfo.rotation, modeInfo.mirror);
- status = AhiDispModeEnum(d_ptr->context, &modeInfo, ++modeNo);
- } while (status == AhiStsOk);
- }
-#endif
-
- if (QApplication::type() == QApplication::GuiServer) {
- if (!d_ptr->setMode(mode))
- return false;
- } else {
- status = AhiDispSurfGet(d_ptr->context, &d_ptr->surface);
- if (status != AhiStsOk) {
- qCritical("QAhiScreen::connect(): AhiDispSurfGet failed: %x",
- status);
- return false;
- }
-
- status = AhiDispModeGet(d_ptr->context, &mode);
- if (status != AhiStsOk) {
- qCritical("QAhiScreen::context(): AhiDispModeGet failed: %x",
- status);
- return false;
- }
- }
-
- return configure();
-}
-
-void QAhiScreen::disconnect()
-{
- AhiSurfFree(d_ptr->context, d_ptr->surface);
- d_ptr->surface = 0;
- AhiDevClose(d_ptr->context);
- d_ptr->context = 0;
- AhiTerm();
-}
-
-bool QAhiScreen::initDevice()
-{
- QScreenCursor::initSoftwareCursor();
-
- AhiSts_t status = AhiDispState(d_ptr->context, AhiDispStateOn, 0);
- if (status != AhiStsOk) {
- qCritical("QAhiScreen::connect(): AhiDispState failed: %x", status);
- return false;
- }
-
- return true;
-}
-
-void QAhiScreen::shutdownDevice()
-{
- AhiDispState(d_ptr->context, AhiDispStateOff, 0);
-}
-
-void QAhiScreen::setMode(int width, int height, int depth)
-{
- int modeNo = 0;
- AhiDispMode_t mode;
- AhiSts_t status = AhiStsOk;
-
- while (status == AhiStsOk) {
- status = AhiDispModeEnum(d_ptr->context, &mode, modeNo);
- if (mode.size.cx == uint(width) &&
- mode.size.cy == uint(height) &&
- depthForPixelFormat(mode.pixFmt) == depth)
- {
- d_ptr->setMode(mode);
- configure();
- return;
- }
- }
-}
-
-void QAhiScreen::blit(const QImage &image, const QPoint &topLeft,
- const QRegion &reg)
-{
- AhiPixelFormat_t pixFmt = pixelFormatForImageFormat(image.format());
-
- if (pixFmt >= AhiPixelFormatMax) { // generic fallback
- QImage::Format toFormat = pixelFormat();
- if (toFormat == QImage::Format_Invalid)
- toFormat = QImage::Format_ARGB32;
- blit(image.convertToFormat(toFormat), topLeft, reg);
- return;
- }
-
- AhiSts_t status;
-
- status = AhiDrawSurfDstSet(d_ptr->context, d_ptr->surface, 0);
- if (status != AhiStsOk) {
- qWarning("QAhiScreen::blit(): AhiDrawSurfDstSet failed: %x", status);
- return;
- }
-
- const QVector<QRect> rects = (reg & region()).rects();
- const int numRects = rects.size();
- QVarLengthArray<AhiPoint_t, 8> src(numRects);
- QVarLengthArray<AhiRect_t, 8> dest(numRects);
-
- for (int i = 0; i < numRects; ++i) {
- const QRect rect = rects.at(i);
-
- src[i].x = rect.x() - topLeft.x();
- src[i].y = rect.y() - topLeft.y();
- dest[i].left = rect.left();
- dest[i].top = rect.top();
- dest[i].right = rect.x() + rect.width();
- dest[i].bottom = rect.y() + rect.height();
- }
-
- AhiSize_t bitmapSize = { image.width(), image.height() };
- AhiBitmap_t bitmap = { bitmapSize, (void*)(image.bits()),
- image.bytesPerLine(), pixFmt };
-
- status = AhiDrawRopSet(d_ptr->context, AHIMAKEROP3(AHIROPSRCCOPY));
- if (status != AhiStsOk) {
- qWarning("QAhiScreen::blit(): AhiDrawRopSet failed: %x", status);
- return;
- }
-
- for (int i = 0; i < numRects; ++i) {
- status = AhiDrawBitmapBlt(d_ptr->context, &dest[i], &src[i],
- &bitmap, 0, 0);
- if (status != AhiStsOk) {
- qWarning("QAhiScreen::blit(): AhiDrawBitmapBlt failed: %x",
- status);
- break;
- }
- }
-}
-
-void QAhiScreen::solidFill(const QColor &color, const QRegion &reg)
-{
- AhiSts_t status = AhiStsOk;
-
- switch (pixelFormat()) {
- case QImage::Format_ARGB32_Premultiplied:
- case QImage::Format_ARGB32:
- case QImage::Format_RGB32:
- status = AhiDrawBrushFgColorSet(d_ptr->context, color.rgba());
- break;
- case QImage::Format_RGB16:
- status = AhiDrawBrushFgColorSet(d_ptr->context, qt_convRgbTo16(color.rgb()));
- break;
- default:
- qFatal("QAhiScreen::solidFill(): Not implemented for pixel format %d",
- int(pixelFormat()));
- break;
- }
-
- if (status != AhiStsOk) {
- qWarning("QAhiScreen::solidFill(): AhiDrawBrushFgColorSet failed: %x",
- status);
- return;
- }
-
- status = AhiDrawBrushSet(d_ptr->context, 0, 0, 0, AHIFLAG_BRUSHSOLID);
- if (status != AhiStsOk) {
- qWarning("QAhiScreen::solidFill(): AhiDrawBrushSet failed: %x",
- status);
- return;
- }
-
- status = AhiDrawRopSet(d_ptr->context, AHIMAKEROP3(AHIROPPATCOPY));
- if (status != AhiStsOk) {
- qWarning("QAhiScreen::solidFill(): AhiDrawRopSet failed: %x", status);
- return;
- }
-
- status = AhiDrawSurfDstSet(d_ptr->context, d_ptr->surface, 0);
- if (status != AhiStsOk) {
- qWarning("QAhiScreen::solidFill(): AhiDrawSurfDst failed: %x", status);
- return;
- }
-
- const QVector<QRect> rects = (reg & region()).rects();
- QVarLengthArray<AhiRect_t> ahiRects(rects.size());
-
- for (int i = 0; i < rects.size(); ++i) {
- const QRect rect = rects.at(i);
- ahiRects[i].left = rect.left();
- ahiRects[i].top = rect.top();
- ahiRects[i].right = rect.x() + rect.width();
- ahiRects[i].bottom = rect.y() + rect.height();
- }
-
- status = AhiDrawBitBltMulti(d_ptr->context, ahiRects.data(),
- 0, ahiRects.size());
- if (status != AhiStsOk)
- qWarning("QAhiScreen::solidFill(): AhiDrawBitBlt failed: %x", status);
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_QWS_AHI
diff --git a/src/plugins/gfxdrivers/ahi/qscreenahi_qws.h b/src/plugins/gfxdrivers/ahi/qscreenahi_qws.h
deleted file mode 100644
index a00cf77abf..0000000000
--- a/src/plugins/gfxdrivers/ahi/qscreenahi_qws.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QAHISCREEN_H
-#define QAHISCREEN_H
-
-#include <QtGui/qscreenlinuxfb_qws.h>
-
-#ifndef QT_NO_QWS_AHI
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QAhiScreenPrivate;
-
-class QAhiScreen : public QScreen
-{
-public:
- QAhiScreen(int displayId);
- ~QAhiScreen();
-
- bool connect(const QString &displaySpec);
- void disconnect();
- bool initDevice();
- void shutdownDevice();
- void setMode(int width, int height, int depth);
-
- void blit(const QImage &image, const QPoint &topLeft,
- const QRegion &region);
- void solidFill(const QColor &color, const QRegion &region);
-
-private:
- bool configure();
-
- QAhiScreenPrivate *d_ptr;
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QT_NO_QWS_AHI
-#endif // QAHISCREEN_H
diff --git a/src/plugins/gfxdrivers/ahi/qscreenahiplugin.cpp b/src/plugins/gfxdrivers/ahi/qscreenahiplugin.cpp
deleted file mode 100644
index 8cbc0447e5..0000000000
--- a/src/plugins/gfxdrivers/ahi/qscreenahiplugin.cpp
+++ /dev/null
@@ -1,74 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qscreenahi_qws.h"
-
-#include <QScreenDriverPlugin>
-#include <QStringList>
-
-class QAhiScreenPlugin : public QScreenDriverPlugin
-{
-public:
- QAhiScreenPlugin();
-
- QStringList keys() const;
- QScreen *create(const QString&, int displayId);
-};
-
-QAhiScreenPlugin::QAhiScreenPlugin()
- : QScreenDriverPlugin()
-{
-}
-
-QStringList QAhiScreenPlugin::keys() const
-{
- return (QStringList() << "ahi");
-}
-
-QScreen* QAhiScreenPlugin::create(const QString& driver, int displayId)
-{
- if (driver.toLower() != "ahi")
- return 0;
-
- return new QAhiScreen(displayId);
-}
-
-Q_EXPORT_PLUGIN2(qahiscreen, QAhiScreenPlugin)
diff --git a/src/plugins/gfxdrivers/directfb/directfb.pro b/src/plugins/gfxdrivers/directfb/directfb.pro
deleted file mode 100644
index 6fb2a0f9aa..0000000000
--- a/src/plugins/gfxdrivers/directfb/directfb.pro
+++ /dev/null
@@ -1,15 +0,0 @@
-TARGET = qdirectfbscreen
-load(qt_plugin)
-include($$QT_SOURCE_TREE/src/gui/embedded/directfb.pri)
-
-DESTDIR = $$QT.gui.plugins/gfxdrivers
-
-target.path = $$[QT_INSTALL_PLUGINS]/gfxdrivers
-INSTALLS += target
-
-SOURCES += qdirectfbscreenplugin.cpp
-
-QMAKE_CXXFLAGS += $$QT_CFLAGS_DIRECTFB
-LIBS += $$QT_LIBS_DIRECTFB
-DEFINES += $$QT_DEFINES_DIRECTFB
-contains(gfx-plugins, directfb):DEFINES += QT_QWS_DIRECTFB
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbkeyboard.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbkeyboard.cpp
deleted file mode 100644
index 9ec3f71c7c..0000000000
--- a/src/plugins/gfxdrivers/directfb/qdirectfbkeyboard.cpp
+++ /dev/null
@@ -1,436 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qdirectfbkeyboard.h"
-
-#ifndef QT_NO_QWS_DIRECTFB
-
-#include "qdirectfbscreen.h"
-#include <qobject.h>
-#include <qsocketnotifier.h>
-#include <qhash.h>
-
-#include <directfb.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-
-QT_BEGIN_NAMESPACE
-
-class KeyMap : public QHash<DFBInputDeviceKeySymbol, Qt::Key>
-{
-public:
- KeyMap();
-};
-
-Q_GLOBAL_STATIC(KeyMap, keymap);
-
-class QDirectFBKeyboardHandlerPrivate : public QObject
-{
- Q_OBJECT
-public:
- QDirectFBKeyboardHandlerPrivate(QDirectFBKeyboardHandler *handler);
- ~QDirectFBKeyboardHandlerPrivate();
-
- void suspend();
- void resume();
-
-private:
- QDirectFBKeyboardHandler *handler;
- IDirectFBEventBuffer *eventBuffer;
- QSocketNotifier *keyboardNotifier;
- DFBEvent event;
- int bytesRead;
- int lastUnicode, lastKeycode;
- Qt::KeyboardModifiers lastModifiers;
-private Q_SLOTS:
- void readKeyboardData();
-};
-
-QDirectFBKeyboardHandlerPrivate::QDirectFBKeyboardHandlerPrivate(QDirectFBKeyboardHandler *h)
- : handler(h), eventBuffer(0), keyboardNotifier(0), bytesRead(0),
- lastUnicode(0), lastKeycode(0), lastModifiers(0)
-{
- Q_ASSERT(qt_screen);
-
- IDirectFB *fb = QDirectFBScreen::instance()->dfb();
- if (!fb) {
- qCritical("QDirectFBKeyboardHandler: DirectFB not initialized");
- return;
- }
-
- DFBResult result;
- result = fb->CreateInputEventBuffer(fb, DICAPS_KEYS, DFB_TRUE,
- &eventBuffer);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBKeyboardHandler: "
- "Unable to create input event buffer", result);
- return;
- }
-
- int fd;
- result = eventBuffer->CreateFileDescriptor(eventBuffer, &fd);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBKeyboardHandler: "
- "Unable to create file descriptor", result);
- return;
- }
-
- int flags = ::fcntl(fd, F_GETFL, 0);
- ::fcntl(fd, F_SETFL, flags | O_NONBLOCK);
-
- memset(&event, 0, sizeof(event));
-
- keyboardNotifier = new QSocketNotifier(fd, QSocketNotifier::Read, this);
- connect(keyboardNotifier, SIGNAL(activated(int)),
- this, SLOT(readKeyboardData()));
- resume();
-}
-
-void QDirectFBKeyboardHandlerPrivate::suspend()
-{
- keyboardNotifier->setEnabled(false);
-}
-
-void QDirectFBKeyboardHandlerPrivate::resume()
-{
- eventBuffer->Reset(eventBuffer);
- keyboardNotifier->setEnabled(true);
-}
-
-QDirectFBKeyboardHandlerPrivate::~QDirectFBKeyboardHandlerPrivate()
-{
- if (eventBuffer)
- eventBuffer->Release(eventBuffer);
-}
-
-void QDirectFBKeyboardHandlerPrivate::readKeyboardData()
-{
- if(!qt_screen)
- return;
-
- for (;;) {
- // GetEvent returns DFB_UNSUPPORTED after CreateFileDescriptor().
- // This seems stupid and I really hope it's a bug which will be fixed.
-
- // DFBResult ret = eventBuffer->GetEvent(eventBuffer, &event);
-
- char *buf = reinterpret_cast<char*>(&event);
- int ret = ::read(keyboardNotifier->socket(),
- buf + bytesRead, sizeof(DFBEvent) - bytesRead);
- if (ret == -1) {
- if (errno != EAGAIN)
- qWarning("QDirectFBKeyboardHandlerPrivate::readKeyboardData(): %s",
- strerror(errno));
- return;
- }
-
- Q_ASSERT(ret >= 0);
- bytesRead += ret;
- if (bytesRead < int(sizeof(DFBEvent)))
- break;
- bytesRead = 0;
-
- Q_ASSERT(event.clazz == DFEC_INPUT);
-
- const DFBInputEvent input = event.input;
-
- Qt::KeyboardModifiers modifiers = Qt::NoModifier;
-
- // Not implemented:
- // if (input.modifiers & DIMM_SUPER)
- // if (input.modifiers & DIMM_HYPER)
-
- if (!(input.flags & DIEF_KEYSYMBOL) ||
- !(input.flags & DIEF_KEYID) ||
- !(input.type & (DIET_KEYPRESS|DIET_KEYRELEASE)))
- {
- static bool first = true;
- if (first) {
- qWarning("QDirectFBKeyboardHandler - Getting unexpected non-keyboard related events");
- first = false;
- }
- break;
- }
-
- if (input.flags & DIEF_MODIFIERS) {
- if (input.modifiers & DIMM_SHIFT)
- modifiers |= Qt::ShiftModifier;
- if (input.modifiers & DIMM_CONTROL)
- modifiers |= Qt::ControlModifier;
- if (input.modifiers & DIMM_ALT)
- modifiers |= Qt::AltModifier;
- if (input.modifiers & DIMM_ALTGR)
- modifiers |= Qt::AltModifier;
- if (input.modifiers & DIMM_META)
- modifiers |= Qt::MetaModifier;
- }
-
-
- const bool press = input.type & DIET_KEYPRESS;
- DFBInputDeviceKeySymbol symbol = input.key_symbol;
- int unicode = -1;
- int keycode = 0;
-
- keycode = keymap()->value(symbol);
- if (DFB_KEY_TYPE(symbol) == DIKT_UNICODE)
- unicode = symbol;
-
- if (unicode != -1 || keycode != 0) {
- bool autoRepeat = false;
- if (press) {
- if (unicode == lastUnicode && keycode == lastKeycode && modifiers == lastModifiers) {
- autoRepeat = true;
- } else {
- lastUnicode = unicode;
- lastKeycode = keycode;
- lastModifiers = modifiers;
- }
- } else {
- lastUnicode = lastKeycode = -1;
- lastModifiers = 0;
- }
- if (autoRepeat) {
- handler->processKeyEvent(unicode, keycode,
- modifiers, false, autoRepeat);
-
- }
-
- handler->processKeyEvent(unicode, keycode,
- modifiers, press, autoRepeat);
- }
- }
-}
-
-QDirectFBKeyboardHandler::QDirectFBKeyboardHandler(const QString &device)
- : QWSKeyboardHandler()
-{
- Q_UNUSED(device);
- d = new QDirectFBKeyboardHandlerPrivate(this);
-}
-
-QDirectFBKeyboardHandler::~QDirectFBKeyboardHandler()
-{
- delete d;
-}
-
-KeyMap::KeyMap()
-{
- insert(DIKS_BACKSPACE , Qt::Key_Backspace);
- insert(DIKS_TAB , Qt::Key_Tab);
- insert(DIKS_RETURN , Qt::Key_Return);
- insert(DIKS_ESCAPE , Qt::Key_Escape);
- insert(DIKS_DELETE , Qt::Key_Delete);
-
- insert(DIKS_CURSOR_LEFT , Qt::Key_Left);
- insert(DIKS_CURSOR_RIGHT , Qt::Key_Right);
- insert(DIKS_CURSOR_UP , Qt::Key_Up);
- insert(DIKS_CURSOR_DOWN , Qt::Key_Down);
- insert(DIKS_INSERT , Qt::Key_Insert);
- insert(DIKS_HOME , Qt::Key_Home);
- insert(DIKS_END , Qt::Key_End);
- insert(DIKS_PAGE_UP , Qt::Key_PageUp);
- insert(DIKS_PAGE_DOWN , Qt::Key_PageDown);
- insert(DIKS_PRINT , Qt::Key_Print);
- insert(DIKS_PAUSE , Qt::Key_Pause);
- insert(DIKS_SELECT , Qt::Key_Select);
- insert(DIKS_GOTO , Qt::Key_OpenUrl);
- insert(DIKS_CLEAR , Qt::Key_Clear);
- insert(DIKS_MENU , Qt::Key_Menu);
- insert(DIKS_HELP , Qt::Key_Help);
-
- insert(DIKS_INTERNET , Qt::Key_HomePage);
- insert(DIKS_MAIL , Qt::Key_LaunchMail);
- insert(DIKS_FAVORITES , Qt::Key_Favorites);
-
- insert(DIKS_BACK , Qt::Key_Back);
- insert(DIKS_FORWARD , Qt::Key_Forward);
- insert(DIKS_VOLUME_UP , Qt::Key_VolumeUp);
- insert(DIKS_VOLUME_DOWN , Qt::Key_VolumeDown);
- insert(DIKS_MUTE , Qt::Key_VolumeMute);
- insert(DIKS_PLAYPAUSE , Qt::Key_Pause);
- insert(DIKS_PLAY , Qt::Key_MediaPlay);
- insert(DIKS_STOP , Qt::Key_MediaStop);
- insert(DIKS_RECORD , Qt::Key_MediaRecord);
- insert(DIKS_PREVIOUS , Qt::Key_MediaPrevious);
- insert(DIKS_NEXT , Qt::Key_MediaNext);
-
- insert(DIKS_F1 , Qt::Key_F1);
- insert(DIKS_F2 , Qt::Key_F2);
- insert(DIKS_F3 , Qt::Key_F3);
- insert(DIKS_F4 , Qt::Key_F4);
- insert(DIKS_F5 , Qt::Key_F5);
- insert(DIKS_F6 , Qt::Key_F6);
- insert(DIKS_F7 , Qt::Key_F7);
- insert(DIKS_F8 , Qt::Key_F8);
- insert(DIKS_F9 , Qt::Key_F9);
- insert(DIKS_F10 , Qt::Key_F10);
- insert(DIKS_F11 , Qt::Key_F11);
- insert(DIKS_F12 , Qt::Key_F12);
-
- insert(DIKS_SHIFT , Qt::Key_Shift);
- insert(DIKS_CONTROL , Qt::Key_Control);
- insert(DIKS_ALT , Qt::Key_Alt);
- insert(DIKS_ALTGR , Qt::Key_AltGr);
-
- insert(DIKS_META , Qt::Key_Meta);
- insert(DIKS_SUPER , Qt::Key_Super_L); // ???
- insert(DIKS_HYPER , Qt::Key_Hyper_L); // ???
-
- insert(DIKS_CAPS_LOCK , Qt::Key_CapsLock);
- insert(DIKS_NUM_LOCK , Qt::Key_NumLock);
- insert(DIKS_SCROLL_LOCK , Qt::Key_ScrollLock);
-
- insert(DIKS_DEAD_ABOVEDOT , Qt::Key_Dead_Abovedot);
- insert(DIKS_DEAD_ABOVERING , Qt::Key_Dead_Abovering);
- insert(DIKS_DEAD_ACUTE , Qt::Key_Dead_Acute);
- insert(DIKS_DEAD_BREVE , Qt::Key_Dead_Breve);
- insert(DIKS_DEAD_CARON , Qt::Key_Dead_Caron);
- insert(DIKS_DEAD_CEDILLA , Qt::Key_Dead_Cedilla);
- insert(DIKS_DEAD_CIRCUMFLEX , Qt::Key_Dead_Circumflex);
- insert(DIKS_DEAD_DIAERESIS , Qt::Key_Dead_Diaeresis);
- insert(DIKS_DEAD_DOUBLEACUTE , Qt::Key_Dead_Doubleacute);
- insert(DIKS_DEAD_GRAVE , Qt::Key_Dead_Grave);
- insert(DIKS_DEAD_IOTA , Qt::Key_Dead_Iota);
- insert(DIKS_DEAD_MACRON , Qt::Key_Dead_Macron);
- insert(DIKS_DEAD_OGONEK , Qt::Key_Dead_Ogonek);
- insert(DIKS_DEAD_SEMIVOICED_SOUND , Qt::Key_Dead_Semivoiced_Sound);
- insert(DIKS_DEAD_TILDE , Qt::Key_Dead_Tilde);
- insert(DIKS_DEAD_VOICED_SOUND , Qt::Key_Dead_Voiced_Sound);
- insert(DIKS_SPACE , Qt::Key_Space);
- insert(DIKS_EXCLAMATION_MARK , Qt::Key_Exclam);
- insert(DIKS_QUOTATION , Qt::Key_QuoteDbl);
- insert(DIKS_NUMBER_SIGN , Qt::Key_NumberSign);
- insert(DIKS_DOLLAR_SIGN , Qt::Key_Dollar);
- insert(DIKS_PERCENT_SIGN , Qt::Key_Percent);
- insert(DIKS_AMPERSAND , Qt::Key_Ampersand);
- insert(DIKS_APOSTROPHE , Qt::Key_Apostrophe);
- insert(DIKS_PARENTHESIS_LEFT , Qt::Key_ParenLeft);
- insert(DIKS_PARENTHESIS_RIGHT , Qt::Key_ParenRight);
- insert(DIKS_ASTERISK , Qt::Key_Asterisk);
- insert(DIKS_PLUS_SIGN , Qt::Key_Plus);
- insert(DIKS_COMMA , Qt::Key_Comma);
- insert(DIKS_MINUS_SIGN , Qt::Key_Minus);
- insert(DIKS_PERIOD , Qt::Key_Period);
- insert(DIKS_SLASH , Qt::Key_Slash);
- insert(DIKS_0 , Qt::Key_0);
- insert(DIKS_1 , Qt::Key_1);
- insert(DIKS_2 , Qt::Key_2);
- insert(DIKS_3 , Qt::Key_3);
- insert(DIKS_4 , Qt::Key_4);
- insert(DIKS_5 , Qt::Key_5);
- insert(DIKS_6 , Qt::Key_6);
- insert(DIKS_7 , Qt::Key_7);
- insert(DIKS_8 , Qt::Key_8);
- insert(DIKS_9 , Qt::Key_9);
- insert(DIKS_COLON , Qt::Key_Colon);
- insert(DIKS_SEMICOLON , Qt::Key_Semicolon);
- insert(DIKS_LESS_THAN_SIGN , Qt::Key_Less);
- insert(DIKS_EQUALS_SIGN , Qt::Key_Equal);
- insert(DIKS_GREATER_THAN_SIGN , Qt::Key_Greater);
- insert(DIKS_QUESTION_MARK , Qt::Key_Question);
- insert(DIKS_AT , Qt::Key_At);
- insert(DIKS_CAPITAL_A , Qt::Key_A);
- insert(DIKS_CAPITAL_B , Qt::Key_B);
- insert(DIKS_CAPITAL_C , Qt::Key_C);
- insert(DIKS_CAPITAL_D , Qt::Key_D);
- insert(DIKS_CAPITAL_E , Qt::Key_E);
- insert(DIKS_CAPITAL_F , Qt::Key_F);
- insert(DIKS_CAPITAL_G , Qt::Key_G);
- insert(DIKS_CAPITAL_H , Qt::Key_H);
- insert(DIKS_CAPITAL_I , Qt::Key_I);
- insert(DIKS_CAPITAL_J , Qt::Key_J);
- insert(DIKS_CAPITAL_K , Qt::Key_K);
- insert(DIKS_CAPITAL_L , Qt::Key_L);
- insert(DIKS_CAPITAL_M , Qt::Key_M);
- insert(DIKS_CAPITAL_N , Qt::Key_N);
- insert(DIKS_CAPITAL_O , Qt::Key_O);
- insert(DIKS_CAPITAL_P , Qt::Key_P);
- insert(DIKS_CAPITAL_Q , Qt::Key_Q);
- insert(DIKS_CAPITAL_R , Qt::Key_R);
- insert(DIKS_CAPITAL_S , Qt::Key_S);
- insert(DIKS_CAPITAL_T , Qt::Key_T);
- insert(DIKS_CAPITAL_U , Qt::Key_U);
- insert(DIKS_CAPITAL_V , Qt::Key_V);
- insert(DIKS_CAPITAL_W , Qt::Key_W);
- insert(DIKS_CAPITAL_X , Qt::Key_X);
- insert(DIKS_CAPITAL_Y , Qt::Key_Y);
- insert(DIKS_CAPITAL_Z , Qt::Key_Z);
- insert(DIKS_SQUARE_BRACKET_LEFT , Qt::Key_BracketLeft);
- insert(DIKS_BACKSLASH , Qt::Key_Backslash);
- insert(DIKS_SQUARE_BRACKET_RIGHT , Qt::Key_BracketRight);
- insert(DIKS_CIRCUMFLEX_ACCENT , Qt::Key_AsciiCircum);
- insert(DIKS_UNDERSCORE , Qt::Key_Underscore);
- insert(DIKS_SMALL_A , Qt::Key_A);
- insert(DIKS_SMALL_B , Qt::Key_B);
- insert(DIKS_SMALL_C , Qt::Key_C);
- insert(DIKS_SMALL_D , Qt::Key_D);
- insert(DIKS_SMALL_E , Qt::Key_E);
- insert(DIKS_SMALL_F , Qt::Key_F);
- insert(DIKS_SMALL_G , Qt::Key_G);
- insert(DIKS_SMALL_H , Qt::Key_H);
- insert(DIKS_SMALL_I , Qt::Key_I);
- insert(DIKS_SMALL_J , Qt::Key_J);
- insert(DIKS_SMALL_K , Qt::Key_K);
- insert(DIKS_SMALL_L , Qt::Key_L);
- insert(DIKS_SMALL_M , Qt::Key_M);
- insert(DIKS_SMALL_N , Qt::Key_N);
- insert(DIKS_SMALL_O , Qt::Key_O);
- insert(DIKS_SMALL_P , Qt::Key_P);
- insert(DIKS_SMALL_Q , Qt::Key_Q);
- insert(DIKS_SMALL_R , Qt::Key_R);
- insert(DIKS_SMALL_S , Qt::Key_S);
- insert(DIKS_SMALL_T , Qt::Key_T);
- insert(DIKS_SMALL_U , Qt::Key_U);
- insert(DIKS_SMALL_V , Qt::Key_V);
- insert(DIKS_SMALL_W , Qt::Key_W);
- insert(DIKS_SMALL_X , Qt::Key_X);
- insert(DIKS_SMALL_Y , Qt::Key_Y);
- insert(DIKS_SMALL_Z , Qt::Key_Z);
- insert(DIKS_CURLY_BRACKET_LEFT , Qt::Key_BraceLeft);
- insert(DIKS_VERTICAL_BAR , Qt::Key_Bar);
- insert(DIKS_CURLY_BRACKET_RIGHT , Qt::Key_BraceRight);
- insert(DIKS_TILDE , Qt::Key_AsciiTilde);
-}
-
-QT_END_NAMESPACE
-#include "qdirectfbkeyboard.moc"
-#endif // QT_NO_QWS_DIRECTFB
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbkeyboard.h b/src/plugins/gfxdrivers/directfb/qdirectfbkeyboard.h
deleted file mode 100644
index 6641379261..0000000000
--- a/src/plugins/gfxdrivers/directfb/qdirectfbkeyboard.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDIRECTFBKEYBOARD_H
-#define QDIRECTFBKEYBOARD_H
-
-#include <qglobal.h>
-#include <QtGui/qkbd_qws.h>
-
-#ifndef QT_NO_QWS_DIRECTFB
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QDirectFBKeyboardHandlerPrivate;
-
-class QDirectFBKeyboardHandler : public QWSKeyboardHandler
-{
-public:
- QDirectFBKeyboardHandler(const QString &device);
- ~QDirectFBKeyboardHandler();
-
-private:
- QDirectFBKeyboardHandlerPrivate *d;
-};
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_QWS_DIRECTFB
-
-QT_END_HEADER
-
-#endif // QDIRECTFBKEYBOARD_H
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbmouse.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbmouse.cpp
deleted file mode 100644
index f5f03e72eb..0000000000
--- a/src/plugins/gfxdrivers/directfb/qdirectfbmouse.cpp
+++ /dev/null
@@ -1,294 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qdirectfbmouse.h"
-
-#ifndef QT_NO_QWS_DIRECTFB
-
-#include "qdirectfbscreen.h"
-#include <qsocketnotifier.h>
-
-#include <directfb.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-
-QT_BEGIN_NAMESPACE
-
-class QDirectFBMouseHandlerPrivate : public QObject
-{
- Q_OBJECT
-public:
- QDirectFBMouseHandlerPrivate(QDirectFBMouseHandler *h);
- ~QDirectFBMouseHandlerPrivate();
-
- void setEnabled(bool on);
-private:
- QDirectFBMouseHandler *handler;
- IDirectFBEventBuffer *eventBuffer;
-#ifndef QT_NO_DIRECTFB_LAYER
- IDirectFBDisplayLayer *layer;
-#endif
- QSocketNotifier *mouseNotifier;
-
- QPoint prevPoint;
- Qt::MouseButtons prevbuttons;
-
- DFBEvent event;
- uint bytesRead;
-
-private Q_SLOTS:
- void readMouseData();
-};
-
-QDirectFBMouseHandlerPrivate::QDirectFBMouseHandlerPrivate(QDirectFBMouseHandler *h)
- : handler(h), eventBuffer(0)
-{
- DFBResult result;
-
- QScreen *screen = QScreen::instance();
- if (!screen) {
- qCritical("QDirectFBMouseHandler: no screen instance found");
- return;
- }
-
- IDirectFB *fb = QDirectFBScreen::instance()->dfb();
- if (!fb) {
- qCritical("QDirectFBMouseHandler: DirectFB not initialized");
- return;
- }
-
-#ifndef QT_NO_DIRECTFB_LAYER
- layer = QDirectFBScreen::instance()->dfbDisplayLayer();
- if (!layer) {
- qCritical("QDirectFBMouseHandler: Unable to get primary display layer");
- return;
- }
-#endif
-
- DFBInputDeviceCapabilities caps;
- caps = DICAPS_BUTTONS | DICAPS_AXES;
- result = fb->CreateInputEventBuffer(fb, caps, DFB_TRUE, &eventBuffer);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBMouseHandler: "
- "Unable to create input event buffer", result);
- return;
- }
-
- int fd;
- result = eventBuffer->CreateFileDescriptor(eventBuffer, &fd);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBMouseHandler: "
- "Unable to create file descriptor", result);
- return;
- }
-
- int flags = fcntl(fd, F_GETFL, 0);
- fcntl(fd, F_SETFL, flags | O_NONBLOCK);
-
- // DirectFB seems to assume that the mouse always starts centered
- prevPoint = QPoint(screen->deviceWidth() / 2, screen->deviceHeight() / 2);
- prevbuttons = Qt::NoButton;
- memset(&event, 0, sizeof(event));
- bytesRead = 0;
-
- mouseNotifier = new QSocketNotifier(fd, QSocketNotifier::Read, this);
- connect(mouseNotifier, SIGNAL(activated(int)),this, SLOT(readMouseData()));
- setEnabled(true);
-}
-
-QDirectFBMouseHandlerPrivate::~QDirectFBMouseHandlerPrivate()
-{
- if (eventBuffer)
- eventBuffer->Release(eventBuffer);
-}
-
-void QDirectFBMouseHandlerPrivate::setEnabled(bool on)
-{
- if (mouseNotifier->isEnabled() != on) {
-#ifndef QT_NO_DIRECTFB_LAYER
- DFBResult result;
- result = layer->SetCooperativeLevel(layer, DLSCL_ADMINISTRATIVE);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::QDirectFBScreenCursor: "
- "Unable to set cooperative level", result);
- }
- result = layer->EnableCursor(layer, on ? 1 : 0);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::QDirectFBScreenCursor: "
- "Unable to enable cursor", result);
- }
-
- result = layer->SetCooperativeLevel(layer, DLSCL_SHARED);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::show: "
- "Unable to set cooperative level", result);
- }
-
- layer->SetCooperativeLevel(layer, DLSCL_SHARED);
-#endif
- mouseNotifier->setEnabled(on);
- }
-}
-
-void QDirectFBMouseHandlerPrivate::readMouseData()
-{
- if (!QScreen::instance())
- return;
-
- for (;;) {
- // GetEvent returns DFB_UNSUPPORTED after CreateFileDescriptor().
- // This seems stupid and I really hope it's a bug which will be fixed.
-
- // DFBResult ret = eventBuffer->GetEvent(eventBuffer, &event);
-
- char *buf = reinterpret_cast<char*>(&event);
- int ret = ::read(mouseNotifier->socket(),
- buf + bytesRead, sizeof(DFBEvent) - bytesRead);
- if (ret == -1) {
- if (errno == EINTR)
- continue;
- if (errno == EAGAIN)
- return;
- qWarning("QDirectFBMouseHandlerPrivate::readMouseData(): %s",
- strerror(errno));
- return;
- }
-
- Q_ASSERT(ret >= 0);
- bytesRead += ret;
- if (bytesRead < sizeof(DFBEvent))
- break;
- bytesRead = 0;
-
- Q_ASSERT(event.clazz == DFEC_INPUT);
-
- const DFBInputEvent input = event.input;
- int x = prevPoint.x();
- int y = prevPoint.y();
- int wheel = 0;
-
- if (input.type == DIET_AXISMOTION) {
-#if defined(QT_NO_DIRECTFB_LAYER) || defined(QT_DIRECTFB_WINDOW_AS_CURSOR)
- if (input.flags & DIEF_AXISABS) {
- switch (input.axis) {
- case DIAI_X: x = input.axisabs; break;
- case DIAI_Y: y = input.axisabs; break;
- default:
- qWarning("QDirectFBMouseHandlerPrivate::readMouseData: "
- "unknown axis (absolute) %d", input.axis);
- break;
- }
- } else if (input.flags & DIEF_AXISREL) {
- switch (input.axis) {
- case DIAI_X: x += input.axisrel; break;
- case DIAI_Y: y += input.axisrel; break;
- case DIAI_Z: wheel = -120 * input.axisrel; break;
- default:
- qWarning("QDirectFBMouseHandlerPrivate::readMouseData: "
- "unknown axis (releative) %d", input.axis);
- }
- }
-#else
- if (input.axis == DIAI_X || input.axis == DIAI_Y) {
- DFBResult result = layer->GetCursorPosition(layer, &x, &y);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBMouseHandler::readMouseData",
- result);
- }
- } else if (input.axis == DIAI_Z) {
- Q_ASSERT(input.flags & DIEF_AXISREL);
- wheel = input.axisrel;
- wheel *= -120;
- }
-#endif
- }
-
- Qt::MouseButtons buttons = Qt::NoButton;
- if (input.flags & DIEF_BUTTONS) {
- if (input.buttons & DIBM_LEFT)
- buttons |= Qt::LeftButton;
- if (input.buttons & DIBM_MIDDLE)
- buttons |= Qt::MidButton;
- if (input.buttons & DIBM_RIGHT)
- buttons |= Qt::RightButton;
- }
-
- QPoint p = QPoint(x, y);
- handler->limitToScreen(p);
-
- if (p == prevPoint && wheel == 0 && buttons == prevbuttons)
- continue;
-
- prevPoint = p;
- prevbuttons = buttons;
-
- handler->mouseChanged(p, buttons, wheel);
- }
-}
-
-QDirectFBMouseHandler::QDirectFBMouseHandler(const QString &driver,
- const QString &device)
- : QWSMouseHandler(driver, device)
-{
- d = new QDirectFBMouseHandlerPrivate(this);
-}
-
-QDirectFBMouseHandler::~QDirectFBMouseHandler()
-{
- delete d;
-}
-
-void QDirectFBMouseHandler::suspend()
-{
- d->setEnabled(false);
-}
-
-void QDirectFBMouseHandler::resume()
-{
- d->setEnabled(true);
-}
-
-QT_END_NAMESPACE
-#include "qdirectfbmouse.moc"
-#endif // QT_NO_QWS_DIRECTFB
-
-
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbmouse.h b/src/plugins/gfxdrivers/directfb/qdirectfbmouse.h
deleted file mode 100644
index 12004571cb..0000000000
--- a/src/plugins/gfxdrivers/directfb/qdirectfbmouse.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDIRECTFBMOUSE_H
-#define QDIRECTFBMOUSE_H
-
-#include <qglobal.h>
-#include <QtGui/qmouse_qws.h>
-
-#ifndef QT_NO_QWS_DIRECTFB
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QDirectFBMouseHandlerPrivate;
-
-class QDirectFBMouseHandler : public QWSMouseHandler
-{
-public:
- explicit QDirectFBMouseHandler(const QString &driver = QString(),
- const QString &device = QString());
- ~QDirectFBMouseHandler();
-
- void suspend();
- void resume();
-protected:
- QDirectFBMouseHandlerPrivate *d;
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-#endif // QT_NO_QWS_DIRECTFB
-#endif // QDIRECTFBMOUSE_H
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp
deleted file mode 100644
index 90d0090790..0000000000
--- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp
+++ /dev/null
@@ -1,221 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qdirectfbscreen.h"
-#include "qdirectfbpaintdevice.h"
-#include "qdirectfbpaintengine.h"
-
-#ifndef QT_NO_QWS_DIRECTFB
-
-QT_BEGIN_NAMESPACE
-
-QDirectFBPaintDevice::QDirectFBPaintDevice(QDirectFBScreen *scr)
- : QCustomRasterPaintDevice(0), dfbSurface(0), screen(scr),
- bpl(-1), lockFlgs(DFBSurfaceLockFlags(0)), mem(0), engine(0), imageFormat(QImage::Format_Invalid)
-{
-#ifdef QT_DIRECTFB_SUBSURFACE
- subSurface = 0;
- syncPending = false;
-#endif
-}
-
-QDirectFBPaintDevice::~QDirectFBPaintDevice()
-{
- if (QDirectFBScreen::instance()) {
- unlockSurface();
-#ifdef QT_DIRECTFB_SUBSURFACE
- releaseSubSurface();
-#endif
- if (dfbSurface) {
- screen->releaseDFBSurface(dfbSurface);
- }
- }
- delete engine;
-}
-
-IDirectFBSurface *QDirectFBPaintDevice::directFBSurface() const
-{
- return dfbSurface;
-}
-
-bool QDirectFBPaintDevice::lockSurface(DFBSurfaceLockFlags lockFlags)
-{
- if (lockFlgs && (lockFlags & ~lockFlgs))
- unlockSurface();
- if (!mem) {
- Q_ASSERT(dfbSurface);
-#ifdef QT_DIRECTFB_SUBSURFACE
- if (!subSurface) {
- DFBResult result;
- subSurface = screen->getSubSurface(dfbSurface, QRect(), QDirectFBScreen::TrackSurface, &result);
- if (result != DFB_OK || !subSurface) {
- DirectFBError("Couldn't create sub surface", result);
- return false;
- }
- }
- IDirectFBSurface *surface = subSurface;
-#else
- IDirectFBSurface *surface = dfbSurface;
-#endif
- Q_ASSERT(surface);
- mem = QDirectFBScreen::lockSurface(surface, lockFlags, &bpl);
- lockFlgs = lockFlags;
- Q_ASSERT(mem);
- Q_ASSERT(bpl > 0);
- const QSize s = size();
- lockedImage = QImage(mem, s.width(), s.height(), bpl,
- QDirectFBScreen::getImageFormat(dfbSurface));
- return true;
- }
-#ifdef QT_DIRECTFB_SUBSURFACE
- if (syncPending) {
- syncPending = false;
- screen->waitIdle();
- }
-#endif
- return false;
-}
-
-void QDirectFBPaintDevice::unlockSurface()
-{
- if (QDirectFBScreen::instance() && lockFlgs) {
-#ifdef QT_DIRECTFB_SUBSURFACE
- IDirectFBSurface *surface = subSurface;
-#else
- IDirectFBSurface *surface = dfbSurface;
-#endif
- if (surface) {
- surface->Unlock(surface);
- lockFlgs = static_cast<DFBSurfaceLockFlags>(0);
- mem = 0;
- }
- }
-}
-
-void *QDirectFBPaintDevice::memory() const
-{
- return mem;
-}
-
-QImage::Format QDirectFBPaintDevice::format() const
-{
- return imageFormat;
-}
-
-int QDirectFBPaintDevice::bytesPerLine() const
-{
- Q_ASSERT(!mem || bpl != -1);
- return bpl;
-}
-
-QSize QDirectFBPaintDevice::size() const
-{
- int w, h;
- dfbSurface->GetSize(dfbSurface, &w, &h);
- return QSize(w, h);
-}
-
-int QDirectFBPaintDevice::metric(QPaintDevice::PaintDeviceMetric metric) const
-{
- if (!dfbSurface)
- return 0;
-
- switch (metric) {
- case QPaintDevice::PdmWidth:
- case QPaintDevice::PdmHeight:
- return (metric == PdmWidth ? size().width() : size().height());
- case QPaintDevice::PdmWidthMM:
- return (size().width() * 1000) / dotsPerMeterX();
- case QPaintDevice::PdmHeightMM:
- return (size().height() * 1000) / dotsPerMeterY();
- case QPaintDevice::PdmPhysicalDpiX:
- case QPaintDevice::PdmDpiX:
- return (dotsPerMeterX() * 254) / 10000; // 0.0254 meters-per-inch
- case QPaintDevice::PdmPhysicalDpiY:
- case QPaintDevice::PdmDpiY:
- return (dotsPerMeterY() * 254) / 10000; // 0.0254 meters-per-inch
- case QPaintDevice::PdmDepth:
- return QDirectFBScreen::depth(imageFormat);
- case QPaintDevice::PdmNumColors: {
- if (!lockedImage.isNull())
- return lockedImage.colorCount();
-
- DFBResult result;
- IDirectFBPalette *palette = 0;
- unsigned int numColors = 0;
-
- result = dfbSurface->GetPalette(dfbSurface, &palette);
- if ((result != DFB_OK) || !palette)
- return 0;
-
- result = palette->GetSize(palette, &numColors);
- palette->Release(palette);
- if (result != DFB_OK)
- return 0;
-
- return numColors;
- }
- default:
- qCritical("QDirectFBPaintDevice::metric(): Unhandled metric!");
- return 0;
- }
-}
-
-QPaintEngine *QDirectFBPaintDevice::paintEngine() const
-{
- return engine;
-}
-
-#ifdef QT_DIRECTFB_SUBSURFACE
-void QDirectFBPaintDevice::releaseSubSurface()
-{
- Q_ASSERT(QDirectFBScreen::instance());
- if (subSurface) {
- unlockSurface();
- screen->releaseDFBSurface(subSurface);
- subSurface = 0;
- }
-}
-#endif
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_QWS_DIRECTFB
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h b/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h
deleted file mode 100644
index 975954a496..0000000000
--- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDIRECTFBPAINTDEVICE_H
-#define QDIRECTFBPAINTDEVICE_H
-
-#include <private/qpaintengine_raster_p.h>
-#include "qdirectfbscreen.h"
-
-#ifndef QT_NO_QWS_DIRECTFB
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-// Inherited by both window surface and pixmap
-class QDirectFBPaintEngine;
-class QDirectFBPaintDevice : public QCustomRasterPaintDevice
-{
-public:
- ~QDirectFBPaintDevice();
-
- virtual IDirectFBSurface *directFBSurface() const;
-
- bool lockSurface(DFBSurfaceLockFlags lockFlags);
- void unlockSurface();
-
- // Reimplemented from QCustomRasterPaintDevice:
- void *memory() const;
- QImage::Format format() const;
- int bytesPerLine() const;
- QSize size() const;
- int metric(QPaintDevice::PaintDeviceMetric metric) const;
- DFBSurfaceLockFlags lockFlags() const { return lockFlgs; }
- QPaintEngine *paintEngine() const;
-protected:
- QDirectFBPaintDevice(QDirectFBScreen *scr);
- inline int dotsPerMeterX() const
- {
- return (screen->deviceWidth() * 1000) / screen->physicalWidth();
- }
- inline int dotsPerMeterY() const
- {
- return (screen->deviceHeight() * 1000) / screen->physicalHeight();
- }
-
- IDirectFBSurface *dfbSurface;
-#ifdef QT_DIRECTFB_SUBSURFACE
- void releaseSubSurface();
- IDirectFBSurface *subSurface;
- friend class QDirectFBPaintEnginePrivate;
- bool syncPending;
-#endif
- QImage lockedImage;
- QDirectFBScreen *screen;
- int bpl;
- DFBSurfaceLockFlags lockFlgs;
- uchar *mem;
- QDirectFBPaintEngine *engine;
- QImage::Format imageFormat;
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QT_NO_QWS_DIRECTFB
-#endif //QDIRECTFBPAINTDEVICE_H
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp
deleted file mode 100644
index 18861cfac1..0000000000
--- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp
+++ /dev/null
@@ -1,1430 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qdirectfbpaintengine.h"
-
-#ifndef QT_NO_QWS_DIRECTFB
-
-#include "qdirectfbwindowsurface.h"
-#include "qdirectfbscreen.h"
-#include "qdirectfbpixmap.h"
-#include <directfb.h>
-#include <qtransform.h>
-#include <qvarlengtharray.h>
-#include <qcache.h>
-#include <qmath.h>
-#include <private/qpixmapdata_p.h>
-#include <private/qpixmap_raster_p.h>
-#include <private/qimagepixmapcleanuphooks_p.h>
-
-
-QT_BEGIN_NAMESPACE
-
-class SurfaceCache;
-class QDirectFBPaintEnginePrivate : public QRasterPaintEnginePrivate
-{
-public:
- enum TransformationTypeFlags {
- Matrix_NegativeScale = 0x100,
- Matrix_RectsUnsupported = (QTransform::TxRotate|QTransform::TxShear|QTransform::TxProject),
- Matrix_BlitsUnsupported = (Matrix_NegativeScale|Matrix_RectsUnsupported)
- };
-
- inline static uint getTransformationType(const QTransform &transform)
- {
- int ret = transform.type();
- if (qMin(transform.m11(), transform.m22()) < 0) {
- ret |= QDirectFBPaintEnginePrivate::Matrix_NegativeScale;
- }
- return ret;
- }
-
- enum CompositionModeStatus {
- PorterDuff_None = 0x0,
- PorterDuff_Supported = 0x1,
- PorterDuff_PremultiplyColors = 0x2,
- PorterDuff_AlwaysBlend = 0x4
- };
-
- enum ClipType {
- ClipUnset,
- NoClip,
- RectClip,
- RegionClip,
- ComplexClip
- };
-
- QDirectFBPaintEnginePrivate(QDirectFBPaintEngine *p);
- ~QDirectFBPaintEnginePrivate();
-
- inline void setTransform(const QTransform &transforma);
- inline void setPen(const QPen &pen);
- inline void setCompositionMode(QPainter::CompositionMode mode);
- inline void setRenderHints(QPainter::RenderHints hints);
-
- inline void setDFBColor(const QColor &color);
-
- inline void lock();
- inline void unlock();
- static inline void unlock(QDirectFBPaintDevice *device);
-
- inline bool isSimpleBrush(const QBrush &brush) const;
-
- void drawTiledPixmap(const QRectF &dest, const QPixmap &pixmap, const QPointF &pos, const QTransform &pixmapTransform);
- void blit(const QRectF &dest, IDirectFBSurface *surface, const QRectF &src);
-
- inline bool supportsStretchBlit() const;
-
- inline void updateClip();
- virtual void systemStateChanged();
-
- static IDirectFBSurface *getSurface(const QImage &img, bool *release);
-
-#ifdef QT_DIRECTFB_IMAGECACHE
- static inline int cacheCost(const QImage &img) { return img.width() * img.height() * img.depth() / 8; }
-#endif
-
- enum BlitFlag {
- HasAlpha = 0x1,
- Premultiplied = 0x2
- };
- void prepareForBlit(uint blitFlags);
-
- IDirectFBSurface *surface;
-
- bool antialiased;
- bool simplePen;
-
- uint transformationType; // this is QTransform::type() + Matrix_NegativeScale if qMin(transform.m11(), transform.m22()) < 0
-
- SurfaceCache *surfaceCache;
- IDirectFB *fb;
- quint8 opacity;
-
- ClipType clipType;
- QDirectFBPaintDevice *dfbDevice;
- uint compositionModeStatus;
- bool isPremultiplied;
-
- bool inClip;
- QRect currentClip;
-
- QDirectFBPaintEngine *q;
-};
-
-class SurfaceCache
-{
-public:
- SurfaceCache() : surface(0), buffer(0), bufsize(0) {}
- ~SurfaceCache() { clear(); }
- IDirectFBSurface *getSurface(const uint *buf, int size);
- void clear();
-private:
- IDirectFBSurface *surface;
- uint *buffer;
- int bufsize;
-};
-
-
-#ifdef QT_DIRECTFB_IMAGECACHE
-QT_BEGIN_INCLUDE_NAMESPACE
-#include <private/qimage_p.h>
-QT_END_INCLUDE_NAMESPACE
-struct CachedImage
-{
- IDirectFBSurface *surface;
- ~CachedImage()
- {
- if (surface && QDirectFBScreen::instance()) {
- QDirectFBScreen::instance()->releaseDFBSurface(surface);
- }
- }
-};
-static QCache<qint64, CachedImage> imageCache(4*1024*1024); // 4 MB
-#endif
-
-#define VOID_ARG() static_cast<bool>(false)
-enum PaintOperation {
- DRAW_RECTS = 0x0001, DRAW_LINES = 0x0002, DRAW_IMAGE = 0x0004,
- DRAW_PIXMAP = 0x0008, DRAW_TILED_PIXMAP = 0x0010, STROKE_PATH = 0x0020,
- DRAW_PATH = 0x0040, DRAW_POINTS = 0x0080, DRAW_ELLIPSE = 0x0100,
- DRAW_POLYGON = 0x0200, DRAW_TEXT = 0x0400, FILL_PATH = 0x0800,
- FILL_RECT = 0x1000, DRAW_COLORSPANS = 0x2000, DRAW_ROUNDED_RECT = 0x4000,
- DRAW_STATICTEXT = 0x8000, ALL = 0xffff
-};
-
-enum { RasterWarn = 1, RasterDisable = 2 };
-static inline uint rasterFallbacksMask(PaintOperation op)
-{
- uint ret = 0;
-#ifdef QT_DIRECTFB_WARN_ON_RASTERFALLBACKS
- if (op & QT_DIRECTFB_WARN_ON_RASTERFALLBACKS)
- ret |= RasterWarn;
-#endif
-#ifdef QT_DIRECTFB_DISABLE_RASTERFALLBACKS
- if (op & QT_DIRECTFB_DISABLE_RASTERFALLBACKS)
- ret |= RasterDisable;
-#endif
- static int warningMask = -1;
- static int disableMask = -1;
- if (warningMask < 0) {
- struct {
- const char *name;
- PaintOperation operation;
- } const operations[] = {
- { "DRAW_RECTS", DRAW_RECTS },
- { "DRAW_LINES", DRAW_LINES },
- { "DRAW_IMAGE", DRAW_IMAGE },
- { "DRAW_PIXMAP", DRAW_PIXMAP },
- { "DRAW_TILED_PIXMAP", DRAW_TILED_PIXMAP },
- { "STROKE_PATH", STROKE_PATH },
- { "DRAW_PATH", DRAW_PATH },
- { "DRAW_POINTS", DRAW_POINTS },
- { "DRAW_ELLIPSE", DRAW_ELLIPSE },
- { "DRAW_POLYGON", DRAW_POLYGON },
- { "DRAW_TEXT", DRAW_TEXT },
- { "FILL_PATH", FILL_PATH },
- { "FILL_RECT", FILL_RECT },
- { "DRAW_COLORSPANS", DRAW_COLORSPANS },
- { "DRAW_ROUNDED_RECT", DRAW_ROUNDED_RECT },
- { "ALL", ALL },
- { 0, ALL }
- };
-
- QStringList warning = QString::fromLatin1(qgetenv("QT_DIRECTFB_WARN_ON_RASTERFALLBACKS")).toUpper().split(QLatin1Char('|'),
- QString::SkipEmptyParts);
- QStringList disable = QString::fromLatin1(qgetenv("QT_DIRECTFB_DISABLE_RASTERFALLBACKS")).toUpper().split(QLatin1Char('|'),
- QString::SkipEmptyParts);
- warningMask = 0;
- disableMask = 0;
- if (!warning.isEmpty() || !disable.isEmpty()) {
- for (int i=0; operations[i].name; ++i) {
- const QString name = QString::fromLatin1(operations[i].name);
- int idx = warning.indexOf(name);
- if (idx != -1) {
- warningMask |= operations[i].operation;
- warning.erase(warning.begin() + idx);
- }
- idx = disable.indexOf(name);
- if (idx != -1) {
- disableMask |= operations[i].operation;
- disable.erase(disable.begin() + idx);
- }
- }
- }
- if (!warning.isEmpty()) {
- qWarning("QDirectFBPaintEngine QT_DIRECTFB_WARN_ON_RASTERFALLBACKS Unknown operation(s): %s",
- qPrintable(warning.join(QLatin1String("|"))));
- }
- if (!disable.isEmpty()) {
- qWarning("QDirectFBPaintEngine QT_DIRECTFB_DISABLE_RASTERFALLBACKS Unknown operation(s): %s",
- qPrintable(disable.join(QLatin1String("|"))));
- }
- }
- if (op & warningMask)
- ret |= RasterWarn;
- if (op & disableMask)
- ret |= RasterDisable;
- return ret;
-}
-
-template <typename device, typename T1, typename T2, typename T3>
-static void rasterFallbackWarn(const char *msg, const char *func, const device *dev,
- uint transformationType, bool simplePen,
- uint clipType, uint compositionModeStatus,
- const char *nameOne, const T1 &one,
- const char *nameTwo, const T2 &two,
- const char *nameThree, const T3 &three);
-
-#define RASTERFALLBACK(op, one, two, three) \
- { \
- static const uint rasterFallbacks = rasterFallbacksMask(op); \
- switch (rasterFallbacks) { \
- case 0: break; \
- case RasterWarn: \
- rasterFallbackWarn("Falling back to raster engine for", \
- __FUNCTION__, \
- state()->painter->device(), \
- d_func()->transformationType, \
- d_func()->simplePen, \
- d_func()->clipType, \
- d_func()->compositionModeStatus, \
- #one, one, #two, two, #three, three); \
- break; \
- case RasterDisable|RasterWarn: \
- rasterFallbackWarn("Disabled raster engine operation", \
- __FUNCTION__, \
- state()->painter->device(), \
- d_func()->transformationType, \
- d_func()->simplePen, \
- d_func()->clipType, \
- d_func()->compositionModeStatus, \
- #one, one, #two, two, #three, three); \
- case RasterDisable: \
- return; \
- } \
- }
-
-template <class T>
-static inline void drawLines(const T *lines, int n, const QTransform &transform, IDirectFBSurface *surface);
-template <class T>
-static inline void fillRects(const T *rects, int n, const QTransform &transform, IDirectFBSurface *surface);
-template <class T>
-static inline void drawRects(const T *rects, int n, const QTransform &transform, IDirectFBSurface *surface);
-
-#define CLIPPED_PAINT(operation) { \
- d->unlock(); \
- DFBRegion clipRegion; \
- switch (d->clipType) { \
- case QDirectFBPaintEnginePrivate::NoClip: \
- case QDirectFBPaintEnginePrivate::RectClip: \
- operation; \
- break; \
- case QDirectFBPaintEnginePrivate::RegionClip: { \
- Q_ASSERT(d->clip()); \
- const QVector<QRect> cr = d->clip()->clipRegion.rects(); \
- const int size = cr.size(); \
- for (int i=0; i<size; ++i) { \
- d->currentClip = cr.at(i); \
- clipRegion.x1 = d->currentClip.x(); \
- clipRegion.y1 = d->currentClip.y(); \
- clipRegion.x2 = d->currentClip.right(); \
- clipRegion.y2 = d->currentClip.bottom(); \
- d->surface->SetClip(d->surface, &clipRegion); \
- operation; \
- } \
- d->updateClip(); \
- break; } \
- case QDirectFBPaintEnginePrivate::ComplexClip: \
- case QDirectFBPaintEnginePrivate::ClipUnset: \
- qFatal("CLIPPED_PAINT internal error %d", d->clipType); \
- break; \
- } \
- }
-
-
-QDirectFBPaintEngine::QDirectFBPaintEngine(QPaintDevice *device)
- : QRasterPaintEngine(*(new QDirectFBPaintEnginePrivate(this)), device)
-{
-}
-
-QDirectFBPaintEngine::~QDirectFBPaintEngine()
-{
-}
-
-bool QDirectFBPaintEngine::begin(QPaintDevice *device)
-{
- Q_D(QDirectFBPaintEngine);
- if (device->devType() == QInternal::CustomRaster) {
- d->dfbDevice = static_cast<QDirectFBPaintDevice*>(device);
- } else if (device->devType() == QInternal::Pixmap) {
- QPixmapData *data = static_cast<QPixmap*>(device)->pixmapData();
- Q_ASSERT(data->classId() == QPixmapData::DirectFBClass);
- QDirectFBPixmapData *dfbPixmapData = static_cast<QDirectFBPixmapData*>(data);
- QDirectFBPaintEnginePrivate::unlock(dfbPixmapData);
- d->dfbDevice = static_cast<QDirectFBPaintDevice*>(dfbPixmapData);
- }
-
- if (d->dfbDevice)
- d->surface = d->dfbDevice->directFBSurface();
-
- if (!d->surface) {
- qFatal("QDirectFBPaintEngine used on an invalid device: 0x%x",
- device->devType());
- }
- d->isPremultiplied = QDirectFBScreen::isPremultiplied(d->dfbDevice->format());
-
- d->prepare(d->dfbDevice);
- gccaps = AllFeatures;
- d->setCompositionMode(state()->composition_mode);
-
- return QRasterPaintEngine::begin(device);
-}
-
-bool QDirectFBPaintEngine::end()
-{
- Q_D(QDirectFBPaintEngine);
- d->unlock();
- d->dfbDevice = 0;
-#if (Q_DIRECTFB_VERSION >= 0x010000)
- d->surface->ReleaseSource(d->surface);
-#endif
- d->currentClip = QRect();
- d->surface->SetClip(d->surface, NULL);
- d->surface = 0;
- return QRasterPaintEngine::end();
-}
-
-void QDirectFBPaintEngine::clipEnabledChanged()
-{
- Q_D(QDirectFBPaintEngine);
- QRasterPaintEngine::clipEnabledChanged();
- d->updateClip();
-}
-
-void QDirectFBPaintEngine::penChanged()
-{
- Q_D(QDirectFBPaintEngine);
- d->setPen(state()->pen);
-
- QRasterPaintEngine::penChanged();
-}
-
-void QDirectFBPaintEngine::opacityChanged()
-{
- Q_D(QDirectFBPaintEngine);
- d->opacity = quint8(state()->opacity * 255);
- QRasterPaintEngine::opacityChanged();
-}
-
-void QDirectFBPaintEngine::compositionModeChanged()
-{
- Q_D(QDirectFBPaintEngine);
- d->setCompositionMode(state()->compositionMode());
- QRasterPaintEngine::compositionModeChanged();
-}
-
-void QDirectFBPaintEngine::renderHintsChanged()
-{
- Q_D(QDirectFBPaintEngine);
- d->setRenderHints(state()->renderHints);
- QRasterPaintEngine::renderHintsChanged();
-}
-
-void QDirectFBPaintEngine::transformChanged()
-{
- Q_D(QDirectFBPaintEngine);
- d->setTransform(state()->matrix);
- QRasterPaintEngine::transformChanged();
-}
-
-void QDirectFBPaintEngine::setState(QPainterState *state)
-{
- Q_D(QDirectFBPaintEngine);
- QRasterPaintEngine::setState(state);
- d->setPen(state->pen);
- d->opacity = quint8(state->opacity * 255);
- d->setCompositionMode(state->compositionMode());
- d->setTransform(state->transform());
- d->setRenderHints(state->renderHints);
- if (d->surface)
- d->updateClip();
-}
-
-void QDirectFBPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op)
-{
- Q_D(QDirectFBPaintEngine);
- const bool wasInClip = d->inClip;
- d->inClip = true;
- QRasterPaintEngine::clip(path, op);
- if (!wasInClip) {
- d->inClip = false;
- d->updateClip();
- }
-}
-
-void QDirectFBPaintEngine::clip(const QRegion &region, Qt::ClipOperation op)
-{
- Q_D(QDirectFBPaintEngine);
- const bool wasInClip = d->inClip;
- d->inClip = true;
- QRasterPaintEngine::clip(region, op);
- if (!wasInClip) {
- d->inClip = false;
- d->updateClip();
- }
-}
-
-void QDirectFBPaintEngine::clip(const QRect &rect, Qt::ClipOperation op)
-{
- Q_D(QDirectFBPaintEngine);
- const bool wasInClip = d->inClip;
- d->inClip = true;
- QRasterPaintEngine::clip(rect, op);
- if (!wasInClip) {
- d->inClip = false;
- d->updateClip();
- }
-}
-
-void QDirectFBPaintEngine::drawRects(const QRect *rects, int rectCount)
-{
- Q_D(QDirectFBPaintEngine);
- const QPen &pen = state()->pen;
- const QBrush &brush = state()->brush;
- if (brush.style() == Qt::NoBrush && pen.style() == Qt::NoPen)
- return;
-
- if ((d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported)
- || !d->simplePen
- || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip
- || !d->isSimpleBrush(brush)
- || !(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_Supported)) {
- RASTERFALLBACK(DRAW_RECTS, rectCount, VOID_ARG(), VOID_ARG());
- d->lock();
- QRasterPaintEngine::drawRects(rects, rectCount);
- return;
- }
-
- if (brush.style() != Qt::NoBrush) {
- d->setDFBColor(brush.color());
- CLIPPED_PAINT(QT_PREPEND_NAMESPACE(fillRects<QRect>)(rects, rectCount, state()->matrix, d->surface));
- }
-
- if (pen.style() != Qt::NoPen) {
- d->setDFBColor(pen.color());
- CLIPPED_PAINT(QT_PREPEND_NAMESPACE(drawRects<QRect>)(rects, rectCount, state()->matrix, d->surface));
- }
-}
-
-void QDirectFBPaintEngine::drawRects(const QRectF *rects, int rectCount)
-{
- Q_D(QDirectFBPaintEngine);
- const QPen &pen = state()->pen;
- const QBrush &brush = state()->brush;
- if (brush.style() == Qt::NoBrush && pen.style() == Qt::NoPen)
- return;
-
- if ((d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported)
- || !d->simplePen
- || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip
- || !d->isSimpleBrush(brush)
- || !(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_Supported)) {
- RASTERFALLBACK(DRAW_RECTS, rectCount, VOID_ARG(), VOID_ARG());
- d->lock();
- QRasterPaintEngine::drawRects(rects, rectCount);
- return;
- }
-
- if (brush.style() != Qt::NoBrush) {
- d->setDFBColor(brush.color());
- CLIPPED_PAINT(fillRects<QRectF>(rects, rectCount, state()->matrix, d->surface));
- }
-
- if (pen.style() != Qt::NoPen) {
- d->setDFBColor(pen.color());
- CLIPPED_PAINT(QT_PREPEND_NAMESPACE(drawRects<QRectF>)(rects, rectCount, state()->matrix, d->surface));
- }
-}
-
-void QDirectFBPaintEngine::drawLines(const QLine *lines, int lineCount)
-{
- Q_D(QDirectFBPaintEngine);
-
- const QPen &pen = state()->pen;
- if (!d->simplePen
- || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip
- || !(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_Supported)) {
- RASTERFALLBACK(DRAW_LINES, lineCount, VOID_ARG(), VOID_ARG());
- d->lock();
- QRasterPaintEngine::drawLines(lines, lineCount);
- return;
- }
-
- if (pen.style() != Qt::NoPen) {
- d->setDFBColor(pen.color());
- CLIPPED_PAINT(QT_PREPEND_NAMESPACE(drawLines<QLine>)(lines, lineCount, state()->matrix, d->surface));
- }
-}
-
-void QDirectFBPaintEngine::drawLines(const QLineF *lines, int lineCount)
-{
- Q_D(QDirectFBPaintEngine);
-
- const QPen &pen = state()->pen;
- if (!d->simplePen
- || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip
- || !(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_Supported)) {
- RASTERFALLBACK(DRAW_LINES, lineCount, VOID_ARG(), VOID_ARG());
- d->lock();
- QRasterPaintEngine::drawLines(lines, lineCount);
- return;
- }
-
- if (pen.style() != Qt::NoPen) {
- d->setDFBColor(pen.color());
- CLIPPED_PAINT(QT_PREPEND_NAMESPACE(drawLines<QLineF>)(lines, lineCount, state()->matrix, d->surface));
- }
-}
-
-void QDirectFBPaintEngine::drawImage(const QRectF &r, const QImage &image,
- const QRectF &sr,
- Qt::ImageConversionFlags flags)
-{
- Q_D(QDirectFBPaintEngine);
- Q_UNUSED(flags);
-
- /* This is hard to read. The way it works is like this:
-
- - If you do not have support for preallocated surfaces and do not use an
- image cache we always fall back to raster engine.
-
- - If it's rotated/sheared/mirrored (negative scale) or we can't
- clip it we fall back to raster engine.
-
- - If we don't cache the image, but we do have support for
- preallocated surfaces we fall back to the raster engine if the
- image is in a format DirectFB can't handle.
-
- - If we do cache the image but don't have support for preallocated
- images and the cost of caching the image (bytes used) is higher
- than the max image cache size we fall back to raster engine.
- */
-
-#if !defined QT_NO_DIRECTFB_PREALLOCATED || defined QT_DIRECTFB_IMAGECACHE
- if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_Supported)
- || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_BlitsUnsupported)
- || (d->clipType == QDirectFBPaintEnginePrivate::ComplexClip)
- || (!d->supportsStretchBlit() && state()->matrix.mapRect(r).size() != sr.size())
-#ifndef QT_DIRECTFB_IMAGECACHE
- || (QDirectFBScreen::getSurfacePixelFormat(image.format()) == DSPF_UNKNOWN)
-#elif defined QT_NO_DIRECTFB_PREALLOCATED
- || (QDirectFBPaintEnginePrivate::cacheCost(image) > imageCache.maxCost())
-#endif
- )
-#endif
- {
- RASTERFALLBACK(DRAW_IMAGE, r, image.size(), sr);
- d->lock();
- QRasterPaintEngine::drawImage(r, image, sr, flags);
- return;
- }
-#if !defined QT_NO_DIRECTFB_PREALLOCATED || defined QT_DIRECTFB_IMAGECACHE
- bool release;
- IDirectFBSurface *imgSurface = d->getSurface(image, &release);
- uint blitFlags = 0;
- if (image.hasAlphaChannel())
- blitFlags |= QDirectFBPaintEnginePrivate::HasAlpha;
- if (QDirectFBScreen::isPremultiplied(image.format()))
- blitFlags |= QDirectFBPaintEnginePrivate::Premultiplied;
- d->prepareForBlit(blitFlags);
- CLIPPED_PAINT(d->blit(r, imgSurface, sr));
- if (release) {
-#if (Q_DIRECTFB_VERSION >= 0x010000)
- d->surface->ReleaseSource(d->surface);
-#endif
- imgSurface->Release(imgSurface);
- }
-#endif
-}
-
-void QDirectFBPaintEngine::drawImage(const QPointF &p, const QImage &img)
-{
- drawImage(QRectF(p, img.size()), img, img.rect());
-}
-
-void QDirectFBPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pixmap,
- const QRectF &sr)
-{
- Q_D(QDirectFBPaintEngine);
-
- if (pixmap.pixmapData()->classId() != QPixmapData::DirectFBClass) {
- RASTERFALLBACK(DRAW_PIXMAP, r, pixmap.size(), sr);
- d->lock();
- QRasterPaintEngine::drawPixmap(r, pixmap, sr);
- } else {
- QPixmapData *data = pixmap.pixmapData();
- Q_ASSERT(data->classId() == QPixmapData::DirectFBClass);
- QDirectFBPixmapData *dfbData = static_cast<QDirectFBPixmapData*>(data);
- if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_Supported)
- || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_BlitsUnsupported)
- || (d->clipType == QDirectFBPaintEnginePrivate::ComplexClip)
- || (!d->supportsStretchBlit() && state()->matrix.mapRect(r).size() != sr.size())) {
- RASTERFALLBACK(DRAW_PIXMAP, r, pixmap.size(), sr);
- const QImage *img = dfbData->buffer();
- d->lock();
- QRasterPaintEngine::drawImage(r, *img, sr);
- } else {
- QDirectFBPaintEnginePrivate::unlock(dfbData);
- IDirectFBSurface *s = dfbData->directFBSurface();
- uint blitFlags = 0;
- if (pixmap.hasAlphaChannel())
- blitFlags |= QDirectFBPaintEnginePrivate::HasAlpha;
- if (QDirectFBScreen::isPremultiplied(dfbData->pixelFormat()))
- blitFlags |= QDirectFBPaintEnginePrivate::Premultiplied;
-
- d->prepareForBlit(blitFlags);
- CLIPPED_PAINT(d->blit(r, s, sr));
- }
- }
-}
-
-void QDirectFBPaintEngine::drawPixmap(const QPointF &p, const QPixmap &pm)
-{
- drawPixmap(QRectF(p, pm.size()), pm, pm.rect());
-}
-
-void QDirectFBPaintEngine::drawTiledPixmap(const QRectF &r,
- const QPixmap &pixmap,
- const QPointF &offset)
-{
- Q_D(QDirectFBPaintEngine);
- if (pixmap.pixmapData()->classId() != QPixmapData::DirectFBClass) {
- RASTERFALLBACK(DRAW_TILED_PIXMAP, r, pixmap.size(), offset);
- d->lock();
- QRasterPaintEngine::drawTiledPixmap(r, pixmap, offset);
- } else if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_Supported)
- || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_BlitsUnsupported)
- || (d->clipType == QDirectFBPaintEnginePrivate::ComplexClip)
- || (!d->supportsStretchBlit() && state()->matrix.isScaling())) {
- RASTERFALLBACK(DRAW_TILED_PIXMAP, r, pixmap.size(), offset);
- QPixmapData *pixmapData = pixmap.pixmapData();
- Q_ASSERT(pixmapData->classId() == QPixmapData::DirectFBClass);
- QDirectFBPixmapData *dfbData = static_cast<QDirectFBPixmapData*>(pixmapData);
- const QImage *img = dfbData->buffer();
- d->lock();
- QRasterPixmapData *data = new QRasterPixmapData(QPixmapData::PixmapType);
- data->fromImage(*img, Qt::AutoColor);
- const QPixmap pix(data);
- QRasterPaintEngine::drawTiledPixmap(r, pix, offset);
- } else {
- QTransform transform(state()->matrix);
- CLIPPED_PAINT(d->drawTiledPixmap(r, pixmap, offset, transform));
- }
-}
-
-
-void QDirectFBPaintEngine::stroke(const QVectorPath &path, const QPen &pen)
-{
- RASTERFALLBACK(STROKE_PATH, path, VOID_ARG(), VOID_ARG());
- Q_D(QDirectFBPaintEngine);
- d->lock();
- QRasterPaintEngine::stroke(path, pen);
-}
-
-void QDirectFBPaintEngine::drawPath(const QPainterPath &path)
-{
- RASTERFALLBACK(DRAW_PATH, path, VOID_ARG(), VOID_ARG());
- Q_D(QDirectFBPaintEngine);
- d->lock();
- QRasterPaintEngine::drawPath(path);
-}
-
-void QDirectFBPaintEngine::drawPoints(const QPointF *points, int pointCount)
-{
- RASTERFALLBACK(DRAW_POINTS, pointCount, VOID_ARG(), VOID_ARG());
- Q_D(QDirectFBPaintEngine);
- d->lock();
- QRasterPaintEngine::drawPoints(points, pointCount);
-}
-
-void QDirectFBPaintEngine::drawPoints(const QPoint *points, int pointCount)
-{
- RASTERFALLBACK(DRAW_POINTS, pointCount, VOID_ARG(), VOID_ARG());
- Q_D(QDirectFBPaintEngine);
- d->lock();
- QRasterPaintEngine::drawPoints(points, pointCount);
-}
-
-void QDirectFBPaintEngine::drawEllipse(const QRectF &rect)
-{
- RASTERFALLBACK(DRAW_ELLIPSE, rect, VOID_ARG(), VOID_ARG());
- Q_D(QDirectFBPaintEngine);
- d->lock();
- QRasterPaintEngine::drawEllipse(rect);
-}
-
-void QDirectFBPaintEngine::drawPolygon(const QPointF *points, int pointCount,
- PolygonDrawMode mode)
-{
- RASTERFALLBACK(DRAW_POLYGON, pointCount, mode, VOID_ARG());
- Q_D(QDirectFBPaintEngine);
- d->lock();
- QRasterPaintEngine::drawPolygon(points, pointCount, mode);
-}
-
-void QDirectFBPaintEngine::drawPolygon(const QPoint *points, int pointCount,
- PolygonDrawMode mode)
-{
- RASTERFALLBACK(DRAW_POLYGON, pointCount, mode, VOID_ARG());
- Q_D(QDirectFBPaintEngine);
- d->lock();
- QRasterPaintEngine::drawPolygon(points, pointCount, mode);
-}
-
-void QDirectFBPaintEngine::drawTextItem(const QPointF &p,
- const QTextItem &textItem)
-{
- RASTERFALLBACK(DRAW_TEXT, p, textItem.text(), VOID_ARG());
- Q_D(QDirectFBPaintEngine);
- d->lock();
- QRasterPaintEngine::drawTextItem(p, textItem);
-}
-
-void QDirectFBPaintEngine::fill(const QVectorPath &path, const QBrush &brush)
-{
- if (brush.style() == Qt::NoBrush)
- return;
- RASTERFALLBACK(FILL_PATH, path, brush, VOID_ARG());
- Q_D(QDirectFBPaintEngine);
- d->lock();
- QRasterPaintEngine::fill(path, brush);
-}
-
-void QDirectFBPaintEngine::drawRoundedRect(const QRectF &rect, qreal xrad, qreal yrad, Qt::SizeMode mode)
-{
- RASTERFALLBACK(DRAW_ROUNDED_RECT, rect, xrad, yrad);
- Q_D(QDirectFBPaintEngine);
- d->lock();
- QRasterPaintEngine::drawRoundedRect(rect, xrad, yrad, mode);
-}
-
-void QDirectFBPaintEngine::drawStaticTextItem(QStaticTextItem *item)
-{
- RASTERFALLBACK(DRAW_STATICTEXT, item, VOID_ARG(), VOID_ARG());
- Q_D(QDirectFBPaintEngine);
- d->lock();
- QRasterPaintEngine::drawStaticTextItem(item);
-}
-
-void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QBrush &brush)
-{
- Q_D(QDirectFBPaintEngine);
- if (brush.style() == Qt::NoBrush)
- return;
- if (d->clipType != QDirectFBPaintEnginePrivate::ComplexClip) {
- switch (brush.style()) {
- case Qt::SolidPattern: {
- const QColor color = brush.color();
- if (!color.isValid())
- return;
-
- if (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported
- || !(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_Supported)) {
- break;
- }
- d->setDFBColor(color);
- const QRect r = state()->matrix.mapRect(rect).toRect();
- CLIPPED_PAINT(d->surface->FillRectangle(d->surface, r.x(), r.y(), r.width(), r.height()));
- return; }
-
- case Qt::TexturePattern: {
- const QPointF &brushOrigin = state()->brushOrigin;
- const QTransform stateTransform = state()->matrix;
- QTransform transform(stateTransform);
- transform.translate(brushOrigin.x(), brushOrigin.y());
- transform = brush.transform() * transform;
- if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_Supported)
- || (QDirectFBPaintEnginePrivate::getTransformationType(transform) & QDirectFBPaintEnginePrivate::Matrix_BlitsUnsupported)
- || (!d->supportsStretchBlit() && transform.isScaling())) {
- break;
- }
-
- const QPixmap texture = brush.texture();
- if (texture.pixmapData()->classId() != QPixmapData::DirectFBClass)
- break;
-
- CLIPPED_PAINT(d->drawTiledPixmap(stateTransform.mapRect(rect), texture, rect.topLeft() - brushOrigin, transform));
- return; }
- default:
- break;
- }
- }
- RASTERFALLBACK(FILL_RECT, rect, brush, VOID_ARG());
- d->lock();
- QRasterPaintEngine::fillRect(rect, brush);
-}
-
-void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QColor &color)
-{
- if (!color.isValid())
- return;
- Q_D(QDirectFBPaintEngine);
- if ((d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported)
- || (d->clipType == QDirectFBPaintEnginePrivate::ComplexClip)
- || !(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_Supported)) {
- RASTERFALLBACK(FILL_RECT, rect, color, VOID_ARG());
- d->lock();
- QRasterPaintEngine::fillRect(rect, color);
- } else {
- d->setDFBColor(color);
- const QRect r = state()->matrix.mapRect(rect).toRect();
- CLIPPED_PAINT(d->surface->FillRectangle(d->surface, r.x(), r.y(), r.width(), r.height()));
- }
-}
-
-void QDirectFBPaintEngine::drawBufferSpan(const uint *buffer, int bufsize,
- int x, int y, int length,
- uint const_alpha)
-{
- 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);
-}
-
-#ifdef QT_DIRECTFB_IMAGECACHE
-static void cachedImageCleanupHook(qint64 key)
-{
- delete imageCache.take(key);
-}
-void QDirectFBPaintEngine::initImageCache(int size)
-{
- Q_ASSERT(size >= 0);
- imageCache.setMaxCost(size);
- QImagePixmapCleanupHooks::instance()->addImageHook(cachedImageCleanupHook);
-}
-
-#endif // QT_DIRECTFB_IMAGECACHE
-
-// ---- QDirectFBPaintEnginePrivate ----
-
-
-QDirectFBPaintEnginePrivate::QDirectFBPaintEnginePrivate(QDirectFBPaintEngine *p)
- : surface(0), antialiased(false), simplePen(false),
- transformationType(0), opacity(255),
- clipType(ClipUnset), dfbDevice(0),
- compositionModeStatus(0), isPremultiplied(false), inClip(false), q(p)
-{
- fb = QDirectFBScreen::instance()->dfb();
- surfaceCache = new SurfaceCache;
-}
-
-QDirectFBPaintEnginePrivate::~QDirectFBPaintEnginePrivate()
-{
- delete surfaceCache;
-}
-
-bool QDirectFBPaintEnginePrivate::isSimpleBrush(const QBrush &brush) const
-{
- return (brush.style() == Qt::NoBrush) || (brush.style() == Qt::SolidPattern && !antialiased);
-}
-
-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.
- Q_ASSERT(dfbDevice);
- if (dfbDevice->lockSurface(DSLF_READ|DSLF_WRITE)) {
- prepare(dfbDevice);
- }
-}
-
-void QDirectFBPaintEnginePrivate::unlock()
-{
- Q_ASSERT(dfbDevice);
-#ifdef QT_DIRECTFB_SUBSURFACE
- dfbDevice->syncPending = true;
-#else
- QDirectFBPaintEnginePrivate::unlock(dfbDevice);
-#endif
-}
-
-void QDirectFBPaintEnginePrivate::unlock(QDirectFBPaintDevice *device)
-{
-#ifdef QT_NO_DIRECTFB_SUBSURFACE
- Q_ASSERT(device);
- device->unlockSurface();
-#else
- Q_UNUSED(device);
-#endif
-}
-
-void QDirectFBPaintEnginePrivate::setTransform(const QTransform &transform)
-{
- transformationType = getTransformationType(transform);
- setPen(q->state()->pen);
-}
-
-void QDirectFBPaintEnginePrivate::setPen(const QPen &pen)
-{
- if (pen.style() == Qt::NoPen) {
- simplePen = true;
- } else if (pen.style() == Qt::SolidLine
- && !antialiased
- && pen.brush().style() == Qt::SolidPattern
- && pen.widthF() <= 1.0
- && (transformationType < QTransform::TxScale || pen.isCosmetic())) {
- simplePen = true;
- } else {
- simplePen = false;
- }
-}
-
-void QDirectFBPaintEnginePrivate::setCompositionMode(QPainter::CompositionMode mode)
-{
- if (!surface)
- return;
-
- static const bool forceRasterFallBack = qgetenv("QT_DIRECTFB_FORCE_RASTER").toInt() > 0;
- if (forceRasterFallBack) {
- compositionModeStatus = PorterDuff_None;
- return;
- }
-
- compositionModeStatus = PorterDuff_Supported|PorterDuff_PremultiplyColors|PorterDuff_AlwaysBlend;
- switch (mode) {
- case QPainter::CompositionMode_Clear:
- surface->SetPorterDuff(surface, DSPD_CLEAR);
- break;
- case QPainter::CompositionMode_Source:
- surface->SetPorterDuff(surface, DSPD_SRC);
- compositionModeStatus &= ~PorterDuff_AlwaysBlend;
- if (!isPremultiplied)
- compositionModeStatus &= ~PorterDuff_PremultiplyColors;
- break;
- case QPainter::CompositionMode_SourceOver:
- compositionModeStatus &= ~PorterDuff_AlwaysBlend;
- surface->SetPorterDuff(surface, DSPD_SRC_OVER);
- break;
- case QPainter::CompositionMode_DestinationOver:
- surface->SetPorterDuff(surface, DSPD_DST_OVER);
- break;
- case QPainter::CompositionMode_SourceIn:
- surface->SetPorterDuff(surface, DSPD_SRC_IN);
- if (!isPremultiplied)
- compositionModeStatus &= ~PorterDuff_PremultiplyColors;
- break;
- case QPainter::CompositionMode_DestinationIn:
- surface->SetPorterDuff(surface, DSPD_DST_IN);
- break;
- case QPainter::CompositionMode_SourceOut:
- surface->SetPorterDuff(surface, DSPD_SRC_OUT);
- break;
- case QPainter::CompositionMode_DestinationOut:
- surface->SetPorterDuff(surface, DSPD_DST_OUT);
- break;
- case QPainter::CompositionMode_Destination:
- surface->SetSrcBlendFunction(surface, DSBF_ZERO);
- surface->SetDstBlendFunction(surface, DSBF_ONE);
- break;
-#if (Q_DIRECTFB_VERSION >= 0x010000)
- case QPainter::CompositionMode_SourceAtop:
- surface->SetPorterDuff(surface, DSPD_SRC_ATOP);
- break;
- case QPainter::CompositionMode_DestinationAtop:
- surface->SetPorterDuff(surface, DSPD_DST_ATOP);
- break;
- case QPainter::CompositionMode_Plus:
- surface->SetPorterDuff(surface, DSPD_ADD);
- break;
- case QPainter::CompositionMode_Xor:
- surface->SetPorterDuff(surface, DSPD_XOR);
- break;
-#endif
- default:
- compositionModeStatus = PorterDuff_None;
- break;
- }
-}
-
-void QDirectFBPaintEnginePrivate::setRenderHints(QPainter::RenderHints hints)
-{
- const bool old = antialiased;
- antialiased = bool(hints & QPainter::Antialiasing);
- if (old != antialiased) {
- setPen(q->state()->pen);
- }
-}
-
-void QDirectFBPaintEnginePrivate::prepareForBlit(uint flags)
-{
- DFBSurfaceBlittingFlags blittingFlags = DSBLIT_NOFX;
- if (flags & Premultiplied)
- blittingFlags |= DSBLIT_SRC_PREMULTIPLY;
- if (flags & HasAlpha)
- blittingFlags |= DSBLIT_BLEND_ALPHACHANNEL;
- if (opacity != 255) {
- blittingFlags |= DSBLIT_BLEND_COLORALPHA;
- surface->SetColor(surface, 0xff, 0xff, 0xff, opacity);
- }
-
- surface->SetBlittingFlags(surface, blittingFlags);
-}
-
-static inline uint ALPHA_MUL(uint x, uint a)
-{
- uint t = x * a;
- t = ((t + (t >> 8) + 0x80) >> 8) & 0xff;
- return t;
-}
-
-void QDirectFBPaintEnginePrivate::setDFBColor(const QColor &color)
-{
- Q_ASSERT(surface);
- Q_ASSERT(compositionModeStatus & PorterDuff_Supported);
- const quint8 alpha = (opacity == 255 ?
- color.alpha() : ALPHA_MUL(color.alpha(), opacity));
- QColor col;
- if (compositionModeStatus & PorterDuff_PremultiplyColors) {
- col = QColor(ALPHA_MUL(color.red(), alpha),
- ALPHA_MUL(color.green(), alpha),
- ALPHA_MUL(color.blue(), alpha),
- alpha);
- } else {
- col = QColor(color.red(), color.green(), color.blue(), alpha);
- }
- surface->SetColor(surface, col.red(), col.green(), col.blue(), col.alpha());
- surface->SetDrawingFlags(surface, alpha == 255 && !(compositionModeStatus & PorterDuff_AlwaysBlend) ? DSDRAW_NOFX : DSDRAW_BLEND);
-}
-
-IDirectFBSurface *QDirectFBPaintEnginePrivate::getSurface(const QImage &img, bool *release)
-{
-#ifdef QT_NO_DIRECTFB_IMAGECACHE
- *release = true;
- return QDirectFBScreen::instance()->createDFBSurface(img, img.format(), QDirectFBScreen::DontTrackSurface);
-#else
- const qint64 key = img.cacheKey();
- *release = false;
- if (imageCache.contains(key)) {
- return imageCache[key]->surface;
- }
-
- const int cost = cacheCost(img);
- const bool cache = cost <= imageCache.maxCost();
- QDirectFBScreen *screen = QDirectFBScreen::instance();
- const QImage::Format format = (img.format() == screen->alphaPixmapFormat() || QDirectFBPixmapData::hasAlphaChannel(img)
- ? screen->alphaPixmapFormat() : screen->pixelFormat());
-
- IDirectFBSurface *surface = screen->createDFBSurface(img, format,
- cache
- ? QDirectFBScreen::TrackSurface
- : QDirectFBScreen::DontTrackSurface);
- if (cache) {
- CachedImage *cachedImage = new CachedImage;
- const_cast<QImage&>(img).data_ptr()->is_cached = true;
- cachedImage->surface = surface;
- imageCache.insert(key, cachedImage, cost);
- } else {
- *release = true;
- }
- return surface;
-#endif
-}
-
-
-void QDirectFBPaintEnginePrivate::blit(const QRectF &dest, IDirectFBSurface *s, const QRectF &src)
-{
- const QRect sr = src.toRect();
- const QRect dr = q->state()->matrix.mapRect(dest).toRect();
- if (dr.isEmpty())
- return;
- const DFBRectangle sRect = { sr.x(), sr.y(), sr.width(), sr.height() };
- DFBResult result;
-
- if (dr.size() == sr.size()) {
- result = surface->Blit(surface, s, &sRect, dr.x(), dr.y());
- } else {
- Q_ASSERT(supportsStretchBlit());
- const DFBRectangle dRect = { dr.x(), dr.y(), dr.width(), dr.height() };
- result = surface->StretchBlit(surface, s, &sRect, &dRect);
- }
- if (result != DFB_OK)
- DirectFBError("QDirectFBPaintEngine::drawPixmap()", result);
-}
-
-static inline qreal fixCoord(qreal rect_pos, qreal pixmapSize, qreal offset)
-{
- qreal pos = rect_pos - offset;
- while (pos > rect_pos)
- pos -= pixmapSize;
- while (pos + pixmapSize < rect_pos)
- pos += pixmapSize;
- return pos;
-}
-
-void QDirectFBPaintEnginePrivate::drawTiledPixmap(const QRectF &dest, const QPixmap &pixmap,
- const QPointF &off, const QTransform &pixmapTransform)
-{
- const QTransform &transform = q->state()->matrix;
- Q_ASSERT(!(getTransformationType(transform) & Matrix_BlitsUnsupported) &&
- !(getTransformationType(pixmapTransform) & Matrix_BlitsUnsupported));
- const QRect destinationRect = transform.mapRect(dest).toRect().normalized();
- QRect newClip = destinationRect;
- if (!currentClip.isEmpty())
- newClip &= currentClip;
-
- if (newClip.isNull())
- return;
-
- const DFBRegion clip = {
- newClip.x(),
- newClip.y(),
- newClip.right(),
- newClip.bottom()
- };
- surface->SetClip(surface, &clip);
-
- QPointF offset = pixmapTransform.inverted().map(off);
- Q_ASSERT(transform.type() <= QTransform::TxScale);
- QPixmapData *data = pixmap.pixmapData();
- Q_ASSERT(data->classId() == QPixmapData::DirectFBClass);
- QDirectFBPixmapData *dfbData = static_cast<QDirectFBPixmapData*>(data);
- IDirectFBSurface *sourceSurface = dfbData->directFBSurface();
- uint blitFlags = 0;
- if (dfbData->hasAlphaChannel())
- blitFlags |= HasAlpha;
- if (QDirectFBScreen::isPremultiplied(dfbData->pixelFormat()))
- blitFlags |= Premultiplied;
- prepareForBlit(blitFlags);
- QDirectFBPaintEnginePrivate::unlock(dfbData);
- const QSize pixmapSize = dfbData->size();
- if (transform.isScaling() || pixmapTransform.isScaling()) {
- Q_ASSERT(supportsStretchBlit());
- Q_ASSERT(qMin(transform.m11(), transform.m22()) >= 0);
- offset.rx() *= transform.m11();
- offset.ry() *= transform.m22();
-
- const QSizeF mappedSize(pixmapSize.width() * pixmapTransform.m11(), pixmapSize.height() * pixmapTransform.m22());
- qreal y = fixCoord(destinationRect.y(), mappedSize.height(), offset.y());
- const qreal startX = fixCoord(destinationRect.x(), mappedSize.width(), offset.x());
- while (y <= destinationRect.bottom()) {
- qreal x = startX;
- while (x <= destinationRect.right()) {
- const DFBRectangle destination = { qRound(x), qRound(y), mappedSize.width(), mappedSize.height() };
- surface->StretchBlit(surface, sourceSurface, 0, &destination);
- x += mappedSize.width();
- }
- y += mappedSize.height();
- }
- } else {
- qreal y = fixCoord(destinationRect.y(), pixmapSize.height(), offset.y());
- const qreal startX = fixCoord(destinationRect.x(), pixmapSize.width(), offset.x());
- int horizontal = qMax(1, destinationRect.width() / pixmapSize.width()) + 1;
- if (startX != destinationRect.x())
- ++horizontal;
- int vertical = qMax(1, destinationRect.height() / pixmapSize.height()) + 1;
- if (y != destinationRect.y())
- ++vertical;
-
- const int maxCount = (vertical * horizontal);
- QVarLengthArray<DFBRectangle, 16> sourceRects(maxCount);
- QVarLengthArray<DFBPoint, 16> points(maxCount);
-
- int i = 0;
- while (y <= destinationRect.bottom()) {
- Q_ASSERT(i < maxCount);
- qreal x = startX;
- while (x <= destinationRect.right()) {
- points[i].x = qRound(x);
- points[i].y = qRound(y);
- sourceRects[i].x = 0;
- sourceRects[i].y = 0;
- sourceRects[i].w = int(pixmapSize.width());
- sourceRects[i].h = int(pixmapSize.height());
- x += pixmapSize.width();
- ++i;
- }
- y += pixmapSize.height();
- }
- surface->BatchBlit(surface, sourceSurface, sourceRects.constData(), points.constData(), i);
- }
-
- if (currentClip.isEmpty()) {
- surface->SetClip(surface, 0);
- } else {
- const DFBRegion clip = {
- currentClip.x(),
- currentClip.y(),
- currentClip.right(),
- currentClip.bottom()
- };
- surface->SetClip(surface, &clip);
- }
-}
-
-void QDirectFBPaintEnginePrivate::updateClip()
-{
- Q_ASSERT(surface);
- currentClip = QRect();
- const QClipData *clipData = clip();
- if (!clipData || !clipData->enabled) {
- surface->SetClip(surface, NULL);
- clipType = NoClip;
- } else if (clipData->hasRectClip) {
- const DFBRegion r = {
- clipData->clipRect.x(),
- clipData->clipRect.y(),
- clipData->clipRect.right(),
- clipData->clipRect.bottom()
- };
- surface->SetClip(surface, &r);
- currentClip = clipData->clipRect.normalized();
- // ### is this guaranteed to always be normalized?
- clipType = RectClip;
- } else if (clipData->hasRegionClip) {
- clipType = RegionClip;
- } else {
- clipType = ComplexClip;
- }
-}
-
-bool QDirectFBPaintEnginePrivate::supportsStretchBlit() const
-{
-#ifdef QT_DIRECTFB_STRETCHBLIT
- return !(q->state()->renderHints & QPainter::SmoothPixmapTransform);
-#else
- return false;
-#endif
-}
-
-
-void QDirectFBPaintEnginePrivate::systemStateChanged()
-{
- QRasterPaintEnginePrivate::systemStateChanged();
- updateClip();
-}
-
-IDirectFBSurface *SurfaceCache::getSurface(const uint *buf, int size)
-{
- if (buffer == buf && bufsize == size)
- return surface;
-
- clear();
-
- const DFBSurfaceDescription description = QDirectFBScreen::getSurfaceDescription(buf, size);
- surface = QDirectFBScreen::instance()->createDFBSurface(description, QDirectFBScreen::TrackSurface, 0);
- if (!surface)
- qWarning("QDirectFBPaintEngine: SurfaceCache: Unable to create surface");
-
- buffer = const_cast<uint*>(buf);
- bufsize = size;
-
- return surface;
-}
-
-void SurfaceCache::clear()
-{
- if (surface && QDirectFBScreen::instance())
- QDirectFBScreen::instance()->releaseDFBSurface(surface);
- surface = 0;
- buffer = 0;
- bufsize = 0;
-}
-
-
-static inline QRect mapRect(const QTransform &transform, const QRect &rect) { return transform.mapRect(rect); }
-static inline QRect mapRect(const QTransform &transform, const QRectF &rect) { return transform.mapRect(rect).toRect(); }
-static inline QLine map(const QTransform &transform, const QLine &line) { return transform.map(line); }
-static inline QLine map(const QTransform &transform, const QLineF &line) { return transform.map(line).toLine(); }
-template <class T>
-static inline void drawLines(const T *lines, int n, const QTransform &transform, IDirectFBSurface *surface)
-{
- if (n == 1) {
- const QLine l = map(transform, lines[0]);
- surface->DrawLine(surface, l.x1(), l.y1(), l.x2(), l.y2());
- } else {
- QVarLengthArray<DFBRegion, 32> lineArray(n);
- for (int i=0; i<n; ++i) {
- const QLine l = map(transform, lines[i]);
- lineArray[i].x1 = l.x1();
- lineArray[i].y1 = l.y1();
- lineArray[i].x2 = l.x2();
- lineArray[i].y2 = l.y2();
- }
- surface->DrawLines(surface, lineArray.constData(), n);
- }
-}
-
-template <class T>
-static inline void fillRects(const T *rects, int n, const QTransform &transform, IDirectFBSurface *surface)
-{
- if (n == 1) {
- const QRect r = mapRect(transform, rects[0]);
- surface->FillRectangle(surface, r.x(), r.y(), r.width(), r.height());
- } else {
- QVarLengthArray<DFBRectangle, 32> rectArray(n);
- for (int i=0; i<n; ++i) {
- const QRect r = mapRect(transform, rects[i]);
- rectArray[i].x = r.x();
- rectArray[i].y = r.y();
- rectArray[i].w = r.width();
- rectArray[i].h = r.height();
- }
- surface->FillRectangles(surface, rectArray.constData(), n);
- }
-}
-
-template <class T>
-static inline void drawRects(const T *rects, int n, const QTransform &transform, IDirectFBSurface *surface)
-{
- for (int i=0; i<n; ++i) {
- const QRect r = mapRect(transform, rects[i]);
- surface->DrawRectangle(surface, r.x(), r.y(), r.width(), r.height());
- }
-}
-
-template <typename T> inline const T *ptr(const T &t) { return &t; }
-template <> inline const bool* ptr<bool>(const bool &) { return 0; }
-template <typename device, typename T1, typename T2, typename T3>
-static void rasterFallbackWarn(const char *msg, const char *func, const device *dev,
- uint transformationType, bool simplePen,
- uint clipType, uint compositionModeStatus,
- const char *nameOne, const T1 &one,
- const char *nameTwo, const T2 &two,
- const char *nameThree, const T3 &three)
-{
- QString out;
- QDebug dbg(&out);
- dbg << msg << (QByteArray(func) + "()") << "painting on";
- if (dev->devType() == QInternal::Widget) {
- dbg << static_cast<const QWidget*>(dev);
- } else {
- dbg << dev << "of type" << dev->devType();
- }
-
- dbg << QString::fromLatin1("transformationType 0x%1").arg(transformationType, 3, 16, QLatin1Char('0'))
- << "simplePen" << simplePen
- << "clipType" << clipType
- << "compositionModeStatus" << compositionModeStatus;
-
- const T1 *t1 = ptr(one);
- const T2 *t2 = ptr(two);
- const T3 *t3 = ptr(three);
-
- if (t1) {
- dbg << nameOne << *t1;
- if (t2) {
- dbg << nameTwo << *t2;
- if (t3) {
- dbg << nameThree << *t3;
- }
- }
- }
- qWarning("%s", qPrintable(out));
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_QWS_DIRECTFB
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.h b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.h
deleted file mode 100644
index a3217d0f32..0000000000
--- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPAINTENGINE_DIRECTFB_P_H
-#define QPAINTENGINE_DIRECTFB_P_H
-
-#include <QtGui/qpaintengine.h>
-#include <private/qpaintengine_raster_p.h>
-
-#ifndef QT_NO_QWS_DIRECTFB
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QDirectFBPaintEnginePrivate;
-
-class QDirectFBPaintEngine : public QRasterPaintEngine
-{
- Q_DECLARE_PRIVATE(QDirectFBPaintEngine)
-public:
- QDirectFBPaintEngine(QPaintDevice *device);
- virtual ~QDirectFBPaintEngine();
-
- virtual bool begin(QPaintDevice *device);
- virtual bool end();
-
- virtual void drawRects(const QRect *rects, int rectCount);
- virtual void drawRects(const QRectF *rects, int rectCount);
-
- virtual void fillRect(const QRectF &r, const QBrush &brush);
- virtual void fillRect(const QRectF &r, const QColor &color);
-
- virtual void drawLines(const QLine *line, int lineCount);
- virtual void drawLines(const QLineF *line, int lineCount);
-
- virtual void drawImage(const QPointF &p, const QImage &img);
- virtual void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr,
- Qt::ImageConversionFlags falgs = Qt::AutoColor);
-
- virtual void drawPixmap(const QPointF &p, const QPixmap &pm);
- virtual void drawPixmap(const QRectF &r, const QPixmap &pixmap, const QRectF &sr);
- virtual void drawTiledPixmap(const QRectF &r, const QPixmap &pm, const QPointF &sr);
-
- virtual void drawBufferSpan(const uint *buffer, int bufsize,
- int x, int y, int length, uint const_alpha);
-
- virtual void stroke(const QVectorPath &path, const QPen &pen);
- virtual void drawPath(const QPainterPath &path);
- virtual void drawPoints(const QPointF *points, int pointCount);
- virtual void drawPoints(const QPoint *points, int pointCount);
- virtual void drawEllipse(const QRectF &rect);
- virtual void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode);
- virtual void drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode);
- virtual void drawTextItem(const QPointF &p, const QTextItem &textItem);
- virtual void fill(const QVectorPath &path, const QBrush &brush);
- virtual void drawRoundedRect(const QRectF &rect, qreal xrad, qreal yrad, Qt::SizeMode mode);
-
- virtual void clipEnabledChanged();
- virtual void penChanged();
- virtual void opacityChanged();
- virtual void compositionModeChanged();
- virtual void renderHintsChanged();
- virtual void transformChanged();
-
- virtual void setState(QPainterState *state);
-
- virtual void clip(const QVectorPath &path, Qt::ClipOperation op);
- virtual void clip(const QRegion &region, Qt::ClipOperation op);
- virtual void clip(const QRect &rect, Qt::ClipOperation op);
-
- virtual void drawStaticTextItem(QStaticTextItem *item);
-
- static void initImageCache(int size);
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QT_NO_QWS_DIRECTFB
-
-#endif // QPAINTENGINE_DIRECTFB_P_H
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp
deleted file mode 100644
index 5259a93698..0000000000
--- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp
+++ /dev/null
@@ -1,588 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qdirectfbpixmap.h"
-
-#ifndef QT_NO_QWS_DIRECTFB
-
-#include "qdirectfbscreen.h"
-#include "qdirectfbpaintengine.h"
-
-#include <QtGui/qbitmap.h>
-#include <QtCore/qfile.h>
-#include <directfb.h>
-
-
-QT_BEGIN_NAMESPACE
-
-static int global_ser_no = 0;
-
-QDirectFBPixmapData::QDirectFBPixmapData(QDirectFBScreen *screen, PixelType pixelType)
- : QPixmapData(pixelType, DirectFBClass), QDirectFBPaintDevice(screen),
- alpha(false)
-{
- setSerialNumber(0);
-}
-
-QDirectFBPixmapData::~QDirectFBPixmapData()
-{
-}
-
-void QDirectFBPixmapData::resize(int width, int height)
-{
- if (width <= 0 || height <= 0) {
- invalidate();
- return;
- }
-
- imageFormat = screen->pixelFormat();
- dfbSurface = screen->createDFBSurface(QSize(width, height),
- imageFormat,
- QDirectFBScreen::TrackSurface);
- d = QDirectFBScreen::depth(imageFormat);
- alpha = false;
- if (!dfbSurface) {
- invalidate();
- qWarning("QDirectFBPixmapData::resize(): Unable to allocate surface");
- return;
- }
-
- w = width;
- h = height;
- is_null = (w <= 0 || h <= 0);
- setSerialNumber(++global_ser_no);
-}
-
-#ifdef QT_DIRECTFB_OPAQUE_DETECTION
-// 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;
-
- default:
- break;
- }
-
- return false;
-}
-#endif // QT_DIRECTFB_OPAQUE_DETECTION
-
-bool QDirectFBPixmapData::hasAlphaChannel(const QImage &img, Qt::ImageConversionFlags flags)
-{
- if (img.depth() == 1)
- return true;
-#ifdef QT_DIRECTFB_OPAQUE_DETECTION
- return ((flags & Qt::NoOpaqueDetection) ? img.hasAlphaChannel() : checkForAlphaPixels(img));
-#else
- Q_UNUSED(flags);
- return img.hasAlphaChannel();
-#endif
-}
-
-#ifdef QT_DIRECTFB_IMAGEPROVIDER
-bool QDirectFBPixmapData::fromFile(const QString &filename, const char *format,
- Qt::ImageConversionFlags flags)
-{
- if (!QFile::exists(filename))
- return false;
- if (flags == Qt::AutoColor) {
- if (filename.startsWith(QLatin1Char(':'))) { // resource
- QFile file(filename);
- if (!file.open(QIODevice::ReadOnly))
- return false;
- const QByteArray data = file.readAll();
- file.close();
- return fromData(reinterpret_cast<const uchar*>(data.constData()), data.size(), format, flags);
- } else {
- DFBDataBufferDescription description;
- description.flags = DBDESC_FILE;
- const QByteArray fileNameData = filename.toLocal8Bit();
- description.file = fileNameData.constData();
- if (fromDataBufferDescription(description)) {
- return true;
- }
- // fall back to Qt
- }
- }
- return QPixmapData::fromFile(filename, format, flags);
-}
-
-bool QDirectFBPixmapData::fromData(const uchar *buffer, uint len, const char *format,
- Qt::ImageConversionFlags flags)
-{
- if (flags == Qt::AutoColor) {
- DFBDataBufferDescription description;
- description.flags = DBDESC_MEMORY;
- description.memory.data = buffer;
- description.memory.length = len;
- if (fromDataBufferDescription(description))
- return true;
- // fall back to Qt
- }
- return QPixmapData::fromData(buffer, len, format, flags);
-}
-
-template <typename T> struct QDirectFBInterfaceCleanupHandler
-{
- static void cleanup(T *t) { if (t) t->Release(t); }
-};
-
-template <typename T>
-class QDirectFBPointer : public QScopedPointer<T, QDirectFBInterfaceCleanupHandler<T> >
-{
-public:
- QDirectFBPointer(T *t = 0)
- : QScopedPointer<T, QDirectFBInterfaceCleanupHandler<T> >(t)
- {}
-};
-
-bool QDirectFBPixmapData::fromDataBufferDescription(const DFBDataBufferDescription &dataBufferDescription)
-{
- IDirectFB *dfb = screen->dfb();
- Q_ASSERT(dfb);
- DFBResult result = DFB_OK;
- IDirectFBDataBuffer *dataBufferPtr;
- if ((result = dfb->CreateDataBuffer(dfb, &dataBufferDescription, &dataBufferPtr)) != DFB_OK) {
- DirectFBError("QDirectFBPixmapData::fromDataBufferDescription()", result);
- return false;
- }
- QDirectFBPointer<IDirectFBDataBuffer> dataBuffer(dataBufferPtr);
-
- IDirectFBImageProvider *providerPtr;
- if ((result = dataBuffer->CreateImageProvider(dataBuffer.data(), &providerPtr)) != DFB_OK)
- return false;
-
- QDirectFBPointer<IDirectFBImageProvider> provider(providerPtr);
-
- DFBImageDescription imageDescription;
- result = provider->GetImageDescription(provider.data(), &imageDescription);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBPixmapData::fromSurfaceDescription(): Can't get image description", result);
- return false;
- }
-
- if (imageDescription.caps & DICAPS_COLORKEY) {
- return false;
- }
-
- DFBSurfaceDescription surfaceDescription;
- if ((result = provider->GetSurfaceDescription(provider.data(), &surfaceDescription)) != DFB_OK) {
- DirectFBError("QDirectFBPixmapData::fromDataBufferDescription(): Can't get surface description", result);
- return false;
- }
-
- alpha = imageDescription.caps & DICAPS_ALPHACHANNEL;
- imageFormat = alpha ? screen->alphaPixmapFormat() : screen->pixelFormat();
-
- dfbSurface = screen->createDFBSurface(QSize(surfaceDescription.width, surfaceDescription.height),
- imageFormat, QDirectFBScreen::TrackSurface);
-
- result = provider->RenderTo(provider.data(), dfbSurface, 0);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBPixmapData::fromSurfaceDescription(): Can't render to surface", result);
- return false;
- }
-
- w = surfaceDescription.width;
- h = surfaceDescription.height;
- is_null = (w <= 0 || h <= 0);
- d = QDirectFBScreen::depth(imageFormat);
- setSerialNumber(++global_ser_no);
-
-#if defined QT_DIRECTFB_IMAGEPROVIDER_KEEPALIVE
- screen->setDirectFBImageProvider(providerPtr);
- provider.take();
-#endif
-
- return true;
-}
-
-#endif
-
-void QDirectFBPixmapData::fromImage(const QImage &img, Qt::ImageConversionFlags flags)
-{
- alpha = QDirectFBPixmapData::hasAlphaChannel(img, flags);
- imageFormat = alpha ? screen->alphaPixmapFormat() : screen->pixelFormat();
-
- QImage image;
- if ((flags & ~Qt::NoOpaqueDetection) != Qt::AutoColor) {
- image = img.convertToFormat(imageFormat, flags);
- flags = Qt::AutoColor;
- } else if (img.format() == QImage::Format_RGB32 || img.depth() == 1) {
- image = img.convertToFormat(imageFormat, flags);
- } else if (img.format() != imageFormat) {
- image = img.convertToFormat(imageFormat, flags);
- } else {
- image = img;
- }
-
- dfbSurface = screen->createDFBSurface(image, image.format(), QDirectFBScreen::NoPreallocated | QDirectFBScreen::TrackSurface);
- if (!dfbSurface) {
- qWarning("QDirectFBPixmapData::fromImage()");
- invalidate();
- return;
- }
-
- w = image.width();
- h = image.height();
- is_null = (w <= 0 || h <= 0);
- d = QDirectFBScreen::depth(imageFormat);
- setSerialNumber(++global_ser_no);
-#ifdef QT_NO_DIRECTFB_OPAQUE_DETECTION
- Q_UNUSED(flags);
-#endif
-}
-
-void QDirectFBPixmapData::copy(const QPixmapData *data, const QRect &rect)
-{
- if (data->classId() != DirectFBClass) {
- QPixmapData::copy(data, rect);
- return;
- }
-
- const QDirectFBPixmapData *otherData = static_cast<const QDirectFBPixmapData*>(data);
-#ifdef QT_NO_DIRECTFB_SUBSURFACE
- if (otherData->lockFlags()) {
- const_cast<QDirectFBPixmapData*>(otherData)->unlockSurface();
- }
-#endif
- IDirectFBSurface *src = otherData->directFBSurface();
- alpha = data->hasAlphaChannel();
- imageFormat = (alpha
- ? QDirectFBScreen::instance()->alphaPixmapFormat()
- : QDirectFBScreen::instance()->pixelFormat());
-
-
- dfbSurface = screen->createDFBSurface(rect.size(), imageFormat,
- QDirectFBScreen::TrackSurface);
- if (!dfbSurface) {
- qWarning("QDirectFBPixmapData::copy()");
- invalidate();
- return;
- }
-
- if (alpha) {
- dfbSurface->Clear(dfbSurface, 0, 0, 0, 0);
- dfbSurface->SetBlittingFlags(dfbSurface, DSBLIT_BLEND_ALPHACHANNEL);
- } else {
- dfbSurface->SetBlittingFlags(dfbSurface, DSBLIT_NOFX);
- }
- const DFBRectangle blitRect = { rect.x(), rect.y(),
- rect.width(), rect.height() };
- w = rect.width();
- h = rect.height();
- d = otherData->d;
- is_null = (w <= 0 || h <= 0);
- unlockSurface();
- DFBResult result = dfbSurface->Blit(dfbSurface, src, &blitRect, 0, 0);
-#if (Q_DIRECTFB_VERSION >= 0x010000)
- dfbSurface->ReleaseSource(dfbSurface);
-#endif
- 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)
-{
- if (!serialNumber())
- return;
-
- Q_ASSERT(dfbSurface);
-
- alpha |= (color.alpha() < 255);
-
- if (alpha && isOpaqueFormat(imageFormat)) {
- QSize size;
- dfbSurface->GetSize(dfbSurface, &size.rwidth(), &size.rheight());
- screen->releaseDFBSurface(dfbSurface);
- imageFormat = screen->alphaPixmapFormat();
- d = QDirectFBScreen::depth(imageFormat);
- dfbSurface = screen->createDFBSurface(size, screen->alphaPixmapFormat(), QDirectFBScreen::TrackSurface);
- setSerialNumber(++global_ser_no);
- if (!dfbSurface) {
- qWarning("QDirectFBPixmapData::fill()");
- invalidate();
- return;
- }
- }
-
- dfbSurface->Clear(dfbSurface, color.red(), color.green(), color.blue(), color.alpha());
-}
-
-QPixmap QDirectFBPixmapData::transformed(const QTransform &transform,
- Qt::TransformationMode mode) const
-{
- QDirectFBPixmapData *that = const_cast<QDirectFBPixmapData*>(this);
-#ifdef QT_NO_DIRECTFB_SUBSURFACE
- if (lockFlags())
- that->unlockSurface();
-#endif
-
- if (!dfbSurface || transform.type() != QTransform::TxScale
- || mode != Qt::FastTransformation)
- {
- const QImage *image = that->buffer();
- Q_ASSERT(image);
- const QImage transformed = image->transformed(transform, mode);
- QDirectFBPixmapData *data = new QDirectFBPixmapData(screen, QPixmapData::PixmapType);
- data->fromImage(transformed, Qt::AutoColor);
- return QPixmap(data);
- }
-
- const QSize size = transform.mapRect(QRect(0, 0, w, h)).size();
- if (size.isEmpty())
- return QPixmap();
-
- QDirectFBPixmapData *data = new QDirectFBPixmapData(screen, QPixmapData::PixmapType);
- data->setSerialNumber(++global_ser_no);
- DFBSurfaceBlittingFlags flags = DSBLIT_NOFX;
- data->alpha = alpha;
- if (alpha) {
- flags = DSBLIT_BLEND_ALPHACHANNEL;
- }
- data->dfbSurface = screen->createDFBSurface(size,
- imageFormat,
- QDirectFBScreen::TrackSurface);
- if (flags & DSBLIT_BLEND_ALPHACHANNEL) {
- data->dfbSurface->Clear(data->dfbSurface, 0, 0, 0, 0);
- }
- data->dfbSurface->SetBlittingFlags(data->dfbSurface, flags);
-
- const DFBRectangle destRect = { 0, 0, size.width(), size.height() };
- data->dfbSurface->StretchBlit(data->dfbSurface, dfbSurface, 0, &destRect);
- data->w = size.width();
- data->h = size.height();
- data->is_null = (data->w <= 0 || data->h <= 0);
-
-#if (Q_DIRECTFB_VERSION >= 0x010000)
- data->dfbSurface->ReleaseSource(data->dfbSurface);
-#endif
- return QPixmap(data);
-}
-
-QImage QDirectFBPixmapData::toImage() const
-{
- if (!dfbSurface)
- return QImage();
-
-#if 0
- // In later versions of DirectFB one can set a flag to tell
- // DirectFB not to move the surface to videomemory. When that
- // happens we can use this (hopefully faster) codepath
-#ifndef QT_NO_DIRECTFB_PREALLOCATED
- QImage ret(w, h, 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);
-#if (Q_DIRECTFB_VERSION >= 0x010000)
- imgSurface->ReleaseSource(imgSurface);
-#endif
- imgSurface->Release(imgSurface);
- return ret;
- }
-#endif
-#endif
-
- QDirectFBPixmapData *that = const_cast<QDirectFBPixmapData*>(this);
- const QImage *img = that->buffer();
- return img->copy();
-}
-
-/* This is QPixmapData::paintEngine(), not QPaintDevice::paintEngine() */
-
-QPaintEngine *QDirectFBPixmapData::paintEngine() const
-{
- if (!engine) {
- // QDirectFBPixmapData is also a QCustomRasterPaintDevice, so pass
- // that to the paint engine:
- QDirectFBPixmapData *that = const_cast<QDirectFBPixmapData*>(this);
- that->engine = new QDirectFBPaintEngine(that);
- }
- return engine;
-}
-
-QImage *QDirectFBPixmapData::buffer()
-{
- if (!lockFlgs) {
- lockSurface(DSLF_READ|DSLF_WRITE);
- }
- Q_ASSERT(lockFlgs);
- Q_ASSERT(!lockedImage.isNull());
- return &lockedImage;
-}
-
-
-bool QDirectFBPixmapData::scroll(int dx, int dy, const QRect &rect)
-{
- if (!dfbSurface) {
- return false;
- }
- unlockSurface();
- DFBResult result = dfbSurface->SetBlittingFlags(dfbSurface, DSBLIT_NOFX);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBPixmapData::scroll", result);
- return false;
- }
- result = dfbSurface->SetPorterDuff(dfbSurface, DSPD_NONE);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBPixmapData::scroll", result);
- return false;
- }
-
- const DFBRectangle source = { rect.x(), rect.y(), rect.width(), rect.height() };
- result = dfbSurface->Blit(dfbSurface, dfbSurface, &source, source.x + dx, source.y + dy);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBPixmapData::scroll", result);
- return false;
- }
-
- return true;
-}
-
-void QDirectFBPixmapData::invalidate()
-{
- if (dfbSurface) {
- screen->releaseDFBSurface(dfbSurface);
- dfbSurface = 0;
- }
- setSerialNumber(0);
- alpha = false;
- d = w = h = 0;
- is_null = true;
- imageFormat = QImage::Format_Invalid;
-}
-
-Q_GUI_EXPORT IDirectFBSurface *qt_directfb_surface_for_pixmap(const QPixmap &pixmap)
-{
- const QPixmapData *data = pixmap.pixmapData();
- if (!data || data->classId() != QPixmapData::DirectFBClass)
- return 0;
- const QDirectFBPixmapData *dfbData = static_cast<const QDirectFBPixmapData*>(data);
- return dfbData->directFBSurface();
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_QWS_DIRECTFB
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h
deleted file mode 100644
index bc94b42638..0000000000
--- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDIRECTFBPIXMAP_H
-#define QDIRECTFBPIXMAP_H
-
-#include <qglobal.h>
-
-#ifndef QT_NO_QWS_DIRECTFB
-
-#include <QtGui/private/qpixmapdata_p.h>
-#include <QtGui/private/qpaintengine_raster_p.h>
-#include "qdirectfbpaintdevice.h"
-#include <directfb.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QDirectFBPaintEngine;
-
-class QDirectFBPixmapData : public QPixmapData, public QDirectFBPaintDevice
-{
-public:
- QDirectFBPixmapData(QDirectFBScreen *screen, PixelType pixelType);
- ~QDirectFBPixmapData();
-
- // Re-implemented from QPixmapData:
- virtual void resize(int width, int height);
- virtual void fromImage(const QImage &image, Qt::ImageConversionFlags flags);
-#ifdef QT_DIRECTFB_IMAGEPROVIDER
- virtual bool fromFile(const QString &filename, const char *format,
- Qt::ImageConversionFlags flags);
- virtual bool fromData(const uchar *buffer, uint len, const char *format,
- Qt::ImageConversionFlags flags);
-#endif
- virtual void copy(const QPixmapData *data, const QRect &rect);
- virtual void fill(const QColor &color);
- virtual QPixmap transformed(const QTransform &matrix,
- Qt::TransformationMode mode) const;
- virtual QImage toImage() const;
- virtual QPaintEngine *paintEngine() const;
- virtual QImage *buffer();
- virtual bool scroll(int dx, int dy, const QRect &rect);
- // Pure virtual in QPixmapData, so re-implement here and delegate to QDirectFBPaintDevice
- virtual int metric(QPaintDevice::PaintDeviceMetric m) const { return QDirectFBPaintDevice::metric(m); }
-
- inline QImage::Format pixelFormat() const { return imageFormat; }
- inline bool hasAlphaChannel() const { return alpha; }
- static bool hasAlphaChannel(const QImage &img, Qt::ImageConversionFlags flags = Qt::AutoColor);
-private:
-#ifdef QT_DIRECTFB_IMAGEPROVIDER
- bool fromDataBufferDescription(const DFBDataBufferDescription &dataBuffer);
-#endif
- void invalidate();
- bool alpha;
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QT_NO_QWS_DIRECTFB
-
-#endif // QDIRECTFBPIXMAP_H
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp
deleted file mode 100644
index 7b1538bb49..0000000000
--- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp
+++ /dev/null
@@ -1,1819 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qdirectfbscreen.h"
-#include "qdirectfbwindowsurface.h"
-#include "qdirectfbpixmap.h"
-#include "qdirectfbmouse.h"
-#include "qdirectfbkeyboard.h"
-#include <QtGui/qwsdisplay_qws.h>
-#include <QtGui/qcolor.h>
-#include <QtGui/qapplication.h>
-#include <QtGui/qwindowsystem_qws.h>
-#include <QtGui/private/qgraphicssystem_qws_p.h>
-#include <QtGui/private/qwssignalhandler_p.h>
-#include <QtCore/qvarlengtharray.h>
-#include <QtCore/qvector.h>
-#include <QtCore/qrect.h>
-
-#ifndef QT_NO_QWS_DIRECTFB
-
-QT_BEGIN_NAMESPACE
-
-class QDirectFBScreenPrivate : public QObject, public QWSGraphicsSystem
-{
- Q_OBJECT
-public:
- QDirectFBScreenPrivate(QDirectFBScreen *qptr);
- ~QDirectFBScreenPrivate();
-
- void setFlipFlags(const QStringList &args);
- QPixmapData *createPixmapData(QPixmapData::PixelType type) const;
-public slots:
-#ifdef QT_DIRECTFB_WM
- void onWindowEvent(QWSWindow *window, QWSServer::WindowEvent event);
-#endif
-public:
- IDirectFB *dfb;
- DFBSurfaceFlipFlags flipFlags;
- QDirectFBScreen::DirectFBFlags directFBFlags;
- QImage::Format alphaPixmapFormat;
- IDirectFBScreen *dfbScreen;
-#ifdef QT_NO_DIRECTFB_WM
- IDirectFBSurface *primarySurface;
- QColor backgroundColor;
-#endif
-#ifndef QT_NO_DIRECTFB_LAYER
- IDirectFBDisplayLayer *dfbLayer;
-#endif
- QSet<IDirectFBSurface*> allocatedSurfaces;
-
-#ifndef QT_NO_DIRECTFB_MOUSE
- QDirectFBMouseHandler *mouse;
-#endif
-#ifndef QT_NO_DIRECTFB_KEYBOARD
- QDirectFBKeyboardHandler *keyboard;
-#endif
-#if defined QT_DIRECTFB_IMAGEPROVIDER && defined QT_DIRECTFB_IMAGEPROVIDER_KEEPALIVE
- IDirectFBImageProvider *imageProvider;
-#endif
- IDirectFBSurface *cursorSurface;
- qint64 cursorImageKey;
-
- QDirectFBScreen *q;
- static QDirectFBScreen *instance;
-};
-
-QDirectFBScreen *QDirectFBScreenPrivate::instance = 0;
-
-QDirectFBScreenPrivate::QDirectFBScreenPrivate(QDirectFBScreen *qptr)
- : QWSGraphicsSystem(qptr), dfb(0), flipFlags(DSFLIP_NONE),
- directFBFlags(QDirectFBScreen::NoFlags), alphaPixmapFormat(QImage::Format_Invalid),
- dfbScreen(0)
-#ifdef QT_NO_DIRECTFB_WM
- , primarySurface(0)
-#endif
-#ifndef QT_NO_DIRECTFB_LAYER
- , dfbLayer(0)
-#endif
-#ifndef QT_NO_DIRECTFB_MOUSE
- , mouse(0)
-#endif
-#ifndef QT_NO_DIRECTFB_KEYBOARD
- , keyboard(0)
-#endif
-#if defined QT_DIRECTFB_IMAGEPROVIDER && defined QT_DIRECTFB_IMAGEPROVIDER_KEEPALIVE
- , imageProvider(0)
-#endif
- , cursorSurface(0)
- , cursorImageKey(0)
- , q(qptr)
-{
-#ifndef QT_NO_QWS_SIGNALHANDLER
- QWSSignalHandler::instance()->addObject(this);
-#endif
-#ifdef QT_DIRECTFB_WM
- connect(QWSServer::instance(), SIGNAL(windowEvent(QWSWindow*,QWSServer::WindowEvent)),
- this, SLOT(onWindowEvent(QWSWindow*,QWSServer::WindowEvent)));
-#endif
-}
-
-QDirectFBScreenPrivate::~QDirectFBScreenPrivate()
-{
-#ifndef QT_NO_DIRECTFB_MOUSE
- delete mouse;
-#endif
-#ifndef QT_NO_DIRECTFB_KEYBOARD
- delete keyboard;
-#endif
-#if defined QT_DIRECTFB_IMAGEPROVIDER_KEEPALIVE
- if (imageProvider)
- imageProvider->Release(imageProvider);
-#endif
-
- for (QSet<IDirectFBSurface*>::const_iterator it = allocatedSurfaces.begin(); it != allocatedSurfaces.end(); ++it) {
- (*it)->Release(*it);
- }
-
-#ifdef QT_NO_DIRECTFB_WM
- if (primarySurface)
- primarySurface->Release(primarySurface);
-#endif
-
-#ifndef QT_NO_DIRECTFB_LAYER
- if (dfbLayer)
- dfbLayer->Release(dfbLayer);
-#endif
-
- if (dfbScreen)
- dfbScreen->Release(dfbScreen);
-
- if (dfb)
- dfb->Release(dfb);
-}
-
-IDirectFBSurface *QDirectFBScreen::createDFBSurface(const QImage &image, QImage::Format format, SurfaceCreationOptions options, DFBResult *resultPtr)
-{
- if (image.isNull()) // assert?
- return 0;
-
- if (QDirectFBScreen::getSurfacePixelFormat(format) == DSPF_UNKNOWN) {
- format = QDirectFBPixmapData::hasAlphaChannel(image) ? d_ptr->alphaPixmapFormat : pixelFormat();
- }
- if (image.format() != format) {
- return createDFBSurface(image.convertToFormat(format), format, options | NoPreallocated, resultPtr);
- }
-
- DFBSurfaceDescription description;
- memset(&description, 0, sizeof(DFBSurfaceDescription));
- description.width = image.width();
- description.height = image.height();
- description.flags = DSDESC_WIDTH|DSDESC_HEIGHT|DSDESC_PIXELFORMAT;
- initSurfaceDescriptionPixelFormat(&description, format);
- bool doMemCopy = true;
-#ifdef QT_DIRECTFB_PREALLOCATED
- if (!(options & NoPreallocated)) {
- doMemCopy = false;
- description.flags |= DSDESC_PREALLOCATED;
- description.preallocated[0].data = const_cast<uchar*>(image.bits());
- description.preallocated[0].pitch = image.bytesPerLine();
- description.preallocated[1].data = 0;
- description.preallocated[1].pitch = 0;
- }
-#endif
- DFBResult result;
- IDirectFBSurface *surface = createDFBSurface(description, options, &result);
- if (resultPtr)
- *resultPtr = result;
- if (!surface) {
- DirectFBError("Couldn't create surface createDFBSurface(QImage, QImage::Format, SurfaceCreationOptions)", result);
- return 0;
- }
- if (doMemCopy) {
- int bplDFB;
- uchar *mem = QDirectFBScreen::lockSurface(surface, DSLF_WRITE, &bplDFB);
- if (mem) {
- const int height = image.height();
- const int bplQt = image.bytesPerLine();
- if (bplQt == bplDFB && bplQt == (image.width() * image.depth() / 8)) {
- memcpy(mem, image.bits(), image.byteCount());
- } else {
- for (int i=0; i<height; ++i) {
- memcpy(mem, image.scanLine(i), bplQt);
- mem += bplDFB;
- }
- }
- surface->Unlock(surface);
- }
- }
-#ifdef QT_DIRECTFB_PALETTE
- if (image.colorCount() != 0 && surface)
- QDirectFBScreen::setSurfaceColorTable(surface, image);
-#endif
- return surface;
-}
-
-IDirectFBSurface *QDirectFBScreen::copyDFBSurface(IDirectFBSurface *src,
- QImage::Format format,
- SurfaceCreationOptions options,
- DFBResult *result)
-{
- Q_ASSERT(src);
- QSize size;
- src->GetSize(src, &size.rwidth(), &size.rheight());
- IDirectFBSurface *surface = createDFBSurface(size, format, options, result);
- DFBSurfaceBlittingFlags flags = QDirectFBScreen::hasAlphaChannel(surface)
- ? 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);
-#if (Q_DIRECTFB_VERSION >= 0x010000)
- surface->ReleaseSource(surface);
-#endif
- return surface;
-}
-
-IDirectFBSurface *QDirectFBScreen::createDFBSurface(const QSize &size,
- QImage::Format format,
- SurfaceCreationOptions options,
- DFBResult *result)
-{
- DFBSurfaceDescription desc;
- memset(&desc, 0, sizeof(DFBSurfaceDescription));
- desc.flags |= DSDESC_WIDTH|DSDESC_HEIGHT;
- if (!QDirectFBScreen::initSurfaceDescriptionPixelFormat(&desc, format))
- return 0;
- desc.width = size.width();
- desc.height = size.height();
- return createDFBSurface(desc, options, result);
-}
-
-IDirectFBSurface *QDirectFBScreen::createDFBSurface(DFBSurfaceDescription desc, SurfaceCreationOptions options, DFBResult *resultPtr)
-{
- DFBResult tmp;
- DFBResult &result = (resultPtr ? *resultPtr : tmp);
- result = DFB_OK;
- IDirectFBSurface *newSurface = 0;
-
- if (!d_ptr->dfb) {
- qWarning("QDirectFBScreen::createDFBSurface() - not connected");
- return 0;
- }
-
- if (d_ptr->directFBFlags & VideoOnly
- && !(desc.flags & DSDESC_PREALLOCATED)
- && (!(desc.flags & DSDESC_CAPS) || !(desc.caps & DSCAPS_SYSTEMONLY))) {
- // Add the video only capability. This means the surface will be created in video ram
- if (!(desc.flags & DSDESC_CAPS)) {
- desc.caps = DSCAPS_VIDEOONLY;
- desc.flags |= DSDESC_CAPS;
- } else {
- desc.caps |= DSCAPS_VIDEOONLY;
- }
- result = d_ptr->dfb->CreateSurface(d_ptr->dfb, &desc, &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));
- }
- desc.caps &= ~DSCAPS_VIDEOONLY;
- }
-
- if (d_ptr->directFBFlags & SystemOnly)
- desc.caps |= DSCAPS_SYSTEMONLY;
-
- if (!newSurface)
- result = d_ptr->dfb->CreateSurface(d_ptr->dfb, &desc, &newSurface);
-
- if (result != DFB_OK) {
- 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 (options & TrackSurface) {
- d_ptr->allocatedSurfaces.insert(newSurface);
- }
-
- return newSurface;
-}
-
-#ifdef QT_DIRECTFB_SUBSURFACE
-IDirectFBSurface *QDirectFBScreen::getSubSurface(IDirectFBSurface *surface,
- const QRect &rect,
- SurfaceCreationOptions options,
- DFBResult *resultPtr)
-{
- Q_ASSERT(!(options & NoPreallocated));
- Q_ASSERT(surface);
- DFBResult res;
- DFBResult &result = (resultPtr ? *resultPtr : res);
- IDirectFBSurface *subSurface = 0;
- if (rect.isNull()) {
- result = surface->GetSubSurface(surface, 0, &subSurface);
- } else {
- const DFBRectangle subRect = { rect.x(), rect.y(), rect.width(), rect.height() };
- result = surface->GetSubSurface(surface, &subRect, &subSurface);
- }
- if (result != DFB_OK) {
- DirectFBError("Can't get sub surface", result);
- } else if (options & TrackSurface) {
- d_ptr->allocatedSurfaces.insert(subSurface);
- }
- return subSurface;
-}
-#endif
-
-
-void QDirectFBScreen::releaseDFBSurface(IDirectFBSurface *surface)
-{
- Q_ASSERT(QDirectFBScreen::instance());
- Q_ASSERT(surface);
- surface->Release(surface);
- if (!d_ptr->allocatedSurfaces.remove(surface))
- qWarning("QDirectFBScreen::releaseDFBSurface() - %p not in list", surface);
-
- //qDebug("Released surface at %p. New count = %d", surface, d_ptr->allocatedSurfaces.count());
-}
-
-QDirectFBScreen::DirectFBFlags QDirectFBScreen::directFBFlags() const
-{
- return d_ptr->directFBFlags;
-}
-
-IDirectFB *QDirectFBScreen::dfb()
-{
- return d_ptr->dfb;
-}
-
-#ifdef QT_NO_DIRECTFB_WM
-IDirectFBSurface *QDirectFBScreen::primarySurface()
-{
- return d_ptr->primarySurface;
-}
-#endif
-
-#ifndef QT_NO_DIRECTFB_LAYER
-IDirectFBDisplayLayer *QDirectFBScreen::dfbDisplayLayer()
-{
- return d_ptr->dfbLayer;
-}
-#endif
-
-DFBSurfacePixelFormat QDirectFBScreen::getSurfacePixelFormat(QImage::Format format)
-{
- switch (format) {
-#ifndef QT_NO_DIRECTFB_PALETTE
- case QImage::Format_Indexed8:
- return DSPF_LUT8;
-#endif
- case QImage::Format_RGB888:
- return DSPF_RGB24;
- case QImage::Format_ARGB4444_Premultiplied:
- return DSPF_ARGB4444;
-#if (Q_DIRECTFB_VERSION >= 0x010100)
- case QImage::Format_RGB444:
- return DSPF_RGB444;
- case QImage::Format_RGB555:
- return DSPF_RGB555;
-#endif
- case QImage::Format_RGB16:
- return DSPF_RGB16;
-#if (Q_DIRECTFB_VERSION >= 0x010000)
- case QImage::Format_ARGB6666_Premultiplied:
- return DSPF_ARGB6666;
- case QImage::Format_RGB666:
- return DSPF_RGB18;
-#endif
- case QImage::Format_RGB32:
- return DSPF_RGB32;
- case QImage::Format_ARGB32_Premultiplied:
- case QImage::Format_ARGB32:
- return DSPF_ARGB;
- default:
- return DSPF_UNKNOWN;
- };
-}
-
-QImage::Format QDirectFBScreen::getImageFormat(IDirectFBSurface *surface)
-{
- DFBSurfacePixelFormat format;
- surface->GetPixelFormat(surface, &format);
-
- switch (format) {
- case DSPF_LUT8:
- return QImage::Format_Indexed8;
- case DSPF_RGB24:
- return QImage::Format_RGB888;
- case DSPF_ARGB4444:
- return QImage::Format_ARGB4444_Premultiplied;
-#if (Q_DIRECTFB_VERSION >= 0x010100)
- case DSPF_RGB444:
- return QImage::Format_RGB444;
- case DSPF_RGB555:
-#endif
- case DSPF_ARGB1555:
- return QImage::Format_RGB555;
- case DSPF_RGB16:
- return QImage::Format_RGB16;
-#if (Q_DIRECTFB_VERSION >= 0x010000)
- case DSPF_ARGB6666:
- return QImage::Format_ARGB6666_Premultiplied;
- case DSPF_RGB18:
- return QImage::Format_RGB666;
-#endif
- case DSPF_RGB32:
- return QImage::Format_RGB32;
- 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;
- }
- return QImage::Format_Invalid;
-}
-
-DFBSurfaceDescription QDirectFBScreen::getSurfaceDescription(const uint *buffer,
- int length)
-{
- DFBSurfaceDescription description;
- memset(&description, 0, sizeof(DFBSurfaceDescription));
-
- description.flags = DSDESC_CAPS|DSDESC_WIDTH|DSDESC_HEIGHT|DSDESC_PIXELFORMAT|DSDESC_PREALLOCATED;
- description.caps = DSCAPS_PREMULTIPLIED;
- description.width = length;
- description.height = 1;
- description.pixelformat = DSPF_ARGB;
- description.preallocated[0].data = (void*)buffer;
- description.preallocated[0].pitch = length * sizeof(uint);
- description.preallocated[1].data = 0;
- description.preallocated[1].pitch = 0;
- return description;
-}
-
-#ifndef QT_NO_DIRECTFB_PALETTE
-void QDirectFBScreen::setSurfaceColorTable(IDirectFBSurface *surface,
- const QImage &image)
-{
- if (!surface)
- return;
-
- const int numColors = image.colorCount();
- if (numColors == 0)
- return;
-
- QVarLengthArray<DFBColor, 256> colors(numColors);
- for (int i = 0; i < numColors; ++i) {
- QRgb c = image.color(i);
- colors[i].a = qAlpha(c);
- colors[i].r = qRed(c);
- colors[i].g = qGreen(c);
- colors[i].b = qBlue(c);
- }
-
- IDirectFBPalette *palette;
- DFBResult result;
- result = surface->GetPalette(surface, &palette);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreen::setSurfaceColorTable GetPalette",
- result);
- return;
- }
- result = palette->SetEntries(palette, colors.data(), numColors, 0);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreen::setSurfaceColorTable SetEntries",
- result);
- }
- palette->Release(palette);
-}
-
-#endif // QT_NO_DIRECTFB_PALETTE
-
-#if defined QT_DIRECTFB_CURSOR
-class Q_GUI_EXPORT QDirectFBScreenCursor : public QScreenCursor
-{
-public:
- QDirectFBScreenCursor();
- virtual void set(const QImage &image, int hotx, int hoty);
- virtual void move(int x, int y);
- virtual void show();
- virtual void hide();
-private:
-#ifdef QT_DIRECTFB_WINDOW_AS_CURSOR
- ~QDirectFBScreenCursor();
- bool createWindow();
- IDirectFBWindow *window;
-#endif
- IDirectFBDisplayLayer *layer;
-};
-
-QDirectFBScreenCursor::QDirectFBScreenCursor()
-{
- IDirectFB *fb = QDirectFBScreen::instance()->dfb();
- if (!fb)
- qFatal("QDirectFBScreenCursor: DirectFB not initialized");
-
- layer = QDirectFBScreen::instance()->dfbDisplayLayer();
- Q_ASSERT(layer);
-
- enable = false;
- hwaccel = true;
- supportsAlpha = true;
-#ifdef QT_DIRECTFB_WINDOW_AS_CURSOR
- window = 0;
- DFBResult result = layer->SetCooperativeLevel(layer, DLSCL_ADMINISTRATIVE);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::hide: "
- "Unable to set cooperative level", result);
- }
- result = layer->SetCursorOpacity(layer, 0);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::hide: "
- "Unable to set cursor opacity", result);
- }
-
- result = layer->SetCooperativeLevel(layer, DLSCL_SHARED);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::hide: "
- "Unable to set cooperative level", result);
- }
-#endif
-}
-
-#ifdef QT_DIRECTFB_WINDOW_AS_CURSOR
-QDirectFBScreenCursor::~QDirectFBScreenCursor()
-{
- if (window) {
- window->Release(window);
- window = 0;
- }
-}
-
-bool QDirectFBScreenCursor::createWindow()
-{
- Q_ASSERT(!window);
- Q_ASSERT(!cursor.isNull());
- DFBWindowDescription description;
- memset(&description, 0, sizeof(DFBWindowDescription));
- description.flags = DWDESC_POSX|DWDESC_POSY|DWDESC_WIDTH|DWDESC_HEIGHT|DWDESC_CAPS|DWDESC_PIXELFORMAT|DWDESC_SURFACE_CAPS;
- description.width = cursor.width();
- description.height = cursor.height();
- description.posx = pos.x() - hotspot.x();
- description.posy = pos.y() - hotspot.y();
-#if (Q_DIRECTFB_VERSION >= 0x010100)
- description.flags |= DWDESC_OPTIONS;
- description.options = DWOP_GHOST|DWOP_ALPHACHANNEL;
-#endif
- description.caps = DWCAPS_NODECORATION|DWCAPS_DOUBLEBUFFER;
- const QImage::Format format = QDirectFBScreen::instance()->alphaPixmapFormat();
- description.pixelformat = QDirectFBScreen::getSurfacePixelFormat(format);
- if (QDirectFBScreen::isPremultiplied(format))
- description.surface_caps = DSCAPS_PREMULTIPLIED;
-
- DFBResult result = layer->CreateWindow(layer, &description, &window);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::createWindow: Unable to create window", result);
- return false;
- }
- result = window->SetOpacity(window, 255);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::createWindow: Unable to set opacity ", result);
- return false;
- }
-
- result = window->SetStackingClass(window, DWSC_UPPER);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::createWindow: Unable to set stacking class ", result);
- return false;
- }
-
- result = window->RaiseToTop(window);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::createWindow: Unable to raise window ", result);
- return false;
- }
-
- return true;
-}
-#endif
-
-void QDirectFBScreenCursor::move(int x, int y)
-{
- pos = QPoint(x, y);
-#ifdef QT_DIRECTFB_WINDOW_AS_CURSOR
- if (window) {
- const QPoint p = pos - hotspot;
- DFBResult result = window->MoveTo(window, p.x(), p.y());
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::move: Unable to move window", result);
- }
- }
-#else
- layer->WarpCursor(layer, x, y);
-#endif
-}
-
-void QDirectFBScreenCursor::hide()
-{
- if (enable) {
- enable = false;
- DFBResult result;
-#ifndef QT_DIRECTFB_WINDOW_AS_CURSOR
- result = layer->SetCooperativeLevel(layer, DLSCL_ADMINISTRATIVE);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::hide: "
- "Unable to set cooperative level", result);
- }
- result = layer->SetCursorOpacity(layer, 0);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::hide: "
- "Unable to set cursor opacity", result);
- }
- result = layer->SetCooperativeLevel(layer, DLSCL_SHARED);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::hide: "
- "Unable to set cooperative level", result);
- }
-#else
- if (window) {
- result = window->SetOpacity(window, 0);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::hide: "
- "Unable to set window opacity", result);
- }
- }
-#endif
- }
-}
-
-void QDirectFBScreenCursor::show()
-{
- if (!enable) {
- enable = true;
- DFBResult result;
- result = layer->SetCooperativeLevel(layer, DLSCL_ADMINISTRATIVE);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::show: "
- "Unable to set cooperative level", result);
- }
- result = layer->SetCursorOpacity(layer,
-#ifdef QT_DIRECTFB_WINDOW_AS_CURSOR
- 0
-#else
- 255
-#endif
- );
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::show: "
- "Unable to set cursor shape", result);
- }
- result = layer->SetCooperativeLevel(layer, DLSCL_SHARED);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::show: "
- "Unable to set cooperative level", result);
- }
-#ifdef QT_DIRECTFB_WINDOW_AS_CURSOR
- if (window) {
- DFBResult result = window->SetOpacity(window, 255);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::show: "
- "Unable to set window opacity", result);
- }
- }
-#endif
- }
-}
-
-void QDirectFBScreenCursor::set(const QImage &image, int hotx, int hoty)
-{
- QDirectFBScreen *screen = QDirectFBScreen::instance();
- if (!screen)
- return;
-
- if (image.isNull()) {
- cursor = QImage();
- hide();
- } else {
- cursor = image.convertToFormat(screen->alphaPixmapFormat());
- size = cursor.size();
- hotspot = QPoint(hotx, hoty);
- DFBResult result = DFB_OK;
- IDirectFBSurface *surface = screen->createDFBSurface(cursor, screen->alphaPixmapFormat(),
- QDirectFBScreen::DontTrackSurface, &result);
- if (!surface) {
- DirectFBError("QDirectFBScreenCursor::set: Unable to create surface", result);
- return;
- }
-#ifndef QT_DIRECTFB_WINDOW_AS_CURSOR
- result = layer->SetCooperativeLevel(layer, DLSCL_ADMINISTRATIVE);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::show: "
- "Unable to set cooperative level", result);
- }
- result = layer->SetCursorShape(layer, surface, hotx, hoty);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::show: "
- "Unable to set cursor shape", result);
- }
- result = layer->SetCooperativeLevel(layer, DLSCL_SHARED);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::show: "
- "Unable to set cooperative level", result);
- }
-#else
- if (window || createWindow()) {
- QSize windowSize;
- result = window->GetSize(window, &windowSize.rwidth(), &windowSize.rheight());
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::set: "
- "Unable to get window size", result);
- }
- result = window->Resize(window, size.width(), size.height());
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::set: Unable to resize window", result);
- }
-
- IDirectFBSurface *windowSurface;
- result = window->GetSurface(window, &windowSurface);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::set: Unable to get window surface", result);
- } else {
- result = windowSurface->Clear(windowSurface, 0, 0, 0, 0);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::set: Unable to clear surface", result);
- }
-
- result = windowSurface->Blit(windowSurface, surface, 0, 0, 0);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::set: Unable to blit to surface", result);
- }
- }
- result = windowSurface->Flip(windowSurface, 0, DSFLIP_NONE);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::set: Unable to flip window", result);
- }
-
- windowSurface->Release(windowSurface);
- }
-#endif
- surface->Release(surface);
- show();
- }
-
-}
-#endif // QT_DIRECTFB_CURSOR
-
-QDirectFBScreen::QDirectFBScreen(int display_id)
- : QScreen(display_id, DirectFBClass), d_ptr(new QDirectFBScreenPrivate(this))
-{
- QDirectFBScreenPrivate::instance = this;
-}
-
-QDirectFBScreen::~QDirectFBScreen()
-{
- if (QDirectFBScreenPrivate::instance == this)
- QDirectFBScreenPrivate::instance = 0;
- delete d_ptr;
-}
-
-QDirectFBScreen *QDirectFBScreen::instance()
-{
- return QDirectFBScreenPrivate::instance;
-}
-
-int QDirectFBScreen::depth(DFBSurfacePixelFormat format)
-{
- switch (format) {
- case DSPF_A1:
- return 1;
- case DSPF_A8:
- case DSPF_RGB332:
- case DSPF_LUT8:
- case DSPF_ALUT44:
- return 8;
- case DSPF_I420:
- case DSPF_YV12:
- case DSPF_NV12:
- case DSPF_NV21:
-#if (Q_DIRECTFB_VERSION >= 0x010100)
- case DSPF_RGB444:
-#endif
- return 12;
-#if (Q_DIRECTFB_VERSION >= 0x010100)
- case DSPF_RGB555:
- return 15;
-#endif
- case DSPF_ARGB1555:
- case DSPF_RGB16:
- case DSPF_YUY2:
- case DSPF_UYVY:
- case DSPF_NV16:
- case DSPF_ARGB2554:
- case DSPF_ARGB4444:
- return 16;
- case DSPF_RGB24:
- return 24;
- case DSPF_RGB32:
- case DSPF_ARGB:
- case DSPF_AiRGB:
- return 32;
- case DSPF_UNKNOWN:
- default:
- return 0;
- };
- return 0;
-}
-
-int QDirectFBScreen::depth(QImage::Format format)
-{
- int depth = 0;
- switch(format) {
- case QImage::Format_Invalid:
- case QImage::NImageFormats:
- Q_ASSERT(false);
- case QImage::Format_Mono:
- case QImage::Format_MonoLSB:
- depth = 1;
- break;
- case QImage::Format_Indexed8:
- depth = 8;
- break;
- case QImage::Format_RGB32:
- case QImage::Format_ARGB32:
- case QImage::Format_ARGB32_Premultiplied:
- depth = 32;
- break;
- case QImage::Format_RGB555:
- case QImage::Format_RGB16:
- case QImage::Format_RGB444:
- case QImage::Format_ARGB4444_Premultiplied:
- depth = 16;
- break;
- case QImage::Format_RGB666:
- case QImage::Format_ARGB6666_Premultiplied:
- case QImage::Format_ARGB8565_Premultiplied:
- case QImage::Format_ARGB8555_Premultiplied:
- case QImage::Format_RGB888:
- depth = 24;
- break;
- }
- return depth;
-}
-
-void QDirectFBScreenPrivate::setFlipFlags(const QStringList &args)
-{
- QRegExp flipRegexp(QLatin1String("^flip=([\\w,]*)$"));
- int index = args.indexOf(flipRegexp);
- if (index >= 0) {
- const QStringList flips = flipRegexp.cap(1).split(QLatin1Char(','),
- QString::SkipEmptyParts);
- flipFlags = DSFLIP_NONE;
- foreach(const QString &flip, flips) {
- if (flip == QLatin1String("wait"))
- flipFlags |= DSFLIP_WAIT;
- else if (flip == QLatin1String("blit"))
- flipFlags |= DSFLIP_BLIT;
- else if (flip == QLatin1String("onsync"))
- flipFlags |= DSFLIP_ONSYNC;
- else if (flip == QLatin1String("pipeline"))
- flipFlags |= DSFLIP_PIPELINE;
- else
- qWarning("QDirectFBScreen: Unknown flip argument: %s",
- qPrintable(flip));
- }
- } else {
- flipFlags = DSFLIP_BLIT|DSFLIP_ONSYNC;
- }
-}
-
-#ifdef QT_DIRECTFB_WM
-void QDirectFBScreenPrivate::onWindowEvent(QWSWindow *window, QWSServer::WindowEvent event)
-{
- if (event == QWSServer::Raise) {
- QWSWindowSurface *windowSurface = window->windowSurface();
- if (windowSurface && windowSurface->key() == QLatin1String("directfb")) {
- static_cast<QDirectFBWindowSurface*>(windowSurface)->raise();
- }
- }
-}
-#endif
-
-QPixmapData *QDirectFBScreenPrivate::createPixmapData(QPixmapData::PixelType type) const
-{
- if (type == QPixmapData::BitmapType)
- return QWSGraphicsSystem::createPixmapData(type);
-
- return new QDirectFBPixmapData(q, type);
-}
-
-#if (Q_DIRECTFB_VERSION >= 0x000923)
-#ifdef QT_NO_DEBUG
-struct FlagDescription;
-static const FlagDescription *accelerationDescriptions = 0;
-static const FlagDescription *blitDescriptions = 0;
-static const FlagDescription *drawDescriptions = 0;
-#else
-struct FlagDescription {
- const char *name;
- uint flag;
-};
-
-static const FlagDescription accelerationDescriptions[] = {
- { "DFXL_NONE", DFXL_NONE },
- { "DFXL_FILLRECTANGLE", DFXL_FILLRECTANGLE },
- { "DFXL_DRAWRECTANGLE", DFXL_DRAWRECTANGLE },
- { "DFXL_DRAWLINE", DFXL_DRAWLINE },
- { "DFXL_FILLTRIANGLE", DFXL_FILLTRIANGLE },
- { "DFXL_BLIT", DFXL_BLIT },
- { "DFXL_STRETCHBLIT", DFXL_STRETCHBLIT },
- { "DFXL_TEXTRIANGLES", DFXL_TEXTRIANGLES },
- { "DFXL_DRAWSTRING", DFXL_DRAWSTRING },
- { 0, 0 }
-};
-
-static const FlagDescription blitDescriptions[] = {
- { "DSBLIT_NOFX", DSBLIT_NOFX },
- { "DSBLIT_BLEND_ALPHACHANNEL", DSBLIT_BLEND_ALPHACHANNEL },
- { "DSBLIT_BLEND_COLORALPHA", DSBLIT_BLEND_COLORALPHA },
- { "DSBLIT_COLORIZE", DSBLIT_COLORIZE },
- { "DSBLIT_SRC_COLORKEY", DSBLIT_SRC_COLORKEY },
- { "DSBLIT_DST_COLORKEY", DSBLIT_DST_COLORKEY },
- { "DSBLIT_SRC_PREMULTIPLY", DSBLIT_SRC_PREMULTIPLY },
- { "DSBLIT_DST_PREMULTIPLY", DSBLIT_DST_PREMULTIPLY },
- { "DSBLIT_DEMULTIPLY", DSBLIT_DEMULTIPLY },
- { "DSBLIT_DEINTERLACE", DSBLIT_DEINTERLACE },
-#if (Q_DIRECTFB_VERSION >= 0x000923)
- { "DSBLIT_SRC_PREMULTCOLOR", DSBLIT_SRC_PREMULTCOLOR },
- { "DSBLIT_XOR", DSBLIT_XOR },
-#endif
-#if (Q_DIRECTFB_VERSION >= 0x010000)
- { "DSBLIT_INDEX_TRANSLATION", DSBLIT_INDEX_TRANSLATION },
-#endif
- { 0, 0 }
-};
-
-static const FlagDescription drawDescriptions[] = {
- { "DSDRAW_NOFX", DSDRAW_NOFX },
- { "DSDRAW_BLEND", DSDRAW_BLEND },
- { "DSDRAW_DST_COLORKEY", DSDRAW_DST_COLORKEY },
- { "DSDRAW_SRC_PREMULTIPLY", DSDRAW_SRC_PREMULTIPLY },
- { "DSDRAW_DST_PREMULTIPLY", DSDRAW_DST_PREMULTIPLY },
- { "DSDRAW_DEMULTIPLY", DSDRAW_DEMULTIPLY },
- { "DSDRAW_XOR", DSDRAW_XOR },
- { 0, 0 }
-};
-#endif
-
-static const QByteArray flagDescriptions(uint mask, const FlagDescription *flags)
-{
-#ifdef QT_NO_DEBUG
- Q_UNUSED(mask);
- Q_UNUSED(flags);
- return QByteArray("");
-#else
- if (!mask)
- return flags[0].name;
-
- QStringList list;
- for (int i=1; flags[i].name; ++i) {
- if (mask & flags[i].flag) {
- list.append(QString::fromLatin1(flags[i].name));
- }
- }
- Q_ASSERT(!list.isEmpty());
- return (QLatin1Char(' ') + list.join(QLatin1String("|"))).toLatin1();
-#endif
-}
-static void printDirectFBInfo(IDirectFB *fb, IDirectFBSurface *primarySurface)
-{
- DFBResult result;
- DFBGraphicsDeviceDescription dev;
-
- result = fb->GetDeviceDescription(fb, &dev);
- if (result != DFB_OK) {
- DirectFBError("Error reading graphics device description", result);
- return;
- }
-
- DFBSurfacePixelFormat pixelFormat;
- primarySurface->GetPixelFormat(primarySurface, &pixelFormat);
-
- qDebug("Device: %s (%s), Driver: %s v%i.%i (%s) Pixelformat: %d (%d)\n"
- "acceleration: 0x%x%s\nblit: 0x%x%s\ndraw: 0x%0x%s\nvideo: %iKB\n",
- dev.name, dev.vendor, dev.driver.name, dev.driver.major,
- dev.driver.minor, dev.driver.vendor, DFB_PIXELFORMAT_INDEX(pixelFormat),
- QDirectFBScreen::getImageFormat(primarySurface), dev.acceleration_mask,
- flagDescriptions(dev.acceleration_mask, accelerationDescriptions).constData(),
- dev.blitting_flags, flagDescriptions(dev.blitting_flags, blitDescriptions).constData(),
- dev.drawing_flags, flagDescriptions(dev.drawing_flags, drawDescriptions).constData(),
- (dev.video_memory >> 10));
-}
-#endif
-
-static inline bool setIntOption(const QStringList &arguments, const QString &variable, int *value)
-{
- Q_ASSERT(value);
- QRegExp rx(QString::fromLatin1("%1=?(\\d+)").arg(variable));
- rx.setCaseSensitivity(Qt::CaseInsensitive);
- if (arguments.indexOf(rx) != -1) {
- *value = rx.cap(1).toInt();
- return true;
- }
- return false;
-}
-
-static inline QColor colorFromName(const QString &name)
-{
- QRegExp rx(QLatin1String("#([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])"));
- rx.setCaseSensitivity(Qt::CaseInsensitive);
- if (rx.exactMatch(name)) {
- Q_ASSERT(rx.captureCount() == 4);
- int ints[4];
- int i;
- for (i=0; i<4; ++i) {
- bool ok;
- ints[i] = rx.cap(i + 1).toUInt(&ok, 16);
- if (!ok || ints[i] > 255)
- break;
- }
- if (i == 4)
- return QColor(ints[0], ints[1], ints[2], ints[3]);
- }
- return QColor(name);
-}
-
-bool QDirectFBScreen::connect(const QString &displaySpec)
-{
- DFBResult result = DFB_OK;
-
- { // pass command line arguments to DirectFB
- const QStringList args = QCoreApplication::arguments();
- int argc = args.size();
- char **argv = new char*[argc];
-
- for (int i = 0; i < argc; ++i)
- argv[i] = qstrdup(args.at(i).toLocal8Bit().constData());
-
- result = DirectFBInit(&argc, &argv);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreen: error initializing DirectFB",
- result);
- }
- delete[] argv;
- }
-
- const QStringList displayArgs = displaySpec.split(QLatin1Char(':'),
- QString::SkipEmptyParts);
-
- d_ptr->setFlipFlags(displayArgs);
-
- result = DirectFBCreate(&d_ptr->dfb);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreen: error creating DirectFB interface",
- result);
- return false;
- }
-
- if (displayArgs.contains(QLatin1String("videoonly"), Qt::CaseInsensitive))
- d_ptr->directFBFlags |= VideoOnly;
-
- if (displayArgs.contains(QLatin1String("systemonly"), Qt::CaseInsensitive)) {
- if (d_ptr->directFBFlags & VideoOnly) {
- qWarning("QDirectFBScreen: error. videoonly and systemonly are mutually exclusive");
- } else {
- d_ptr->directFBFlags |= SystemOnly;
- }
- }
-
- if (displayArgs.contains(QLatin1String("boundingrectflip"), Qt::CaseInsensitive)) {
- d_ptr->directFBFlags |= BoundingRectFlip;
- } else if (displayArgs.contains(QLatin1String("nopartialflip"), Qt::CaseInsensitive)) {
- d_ptr->directFBFlags |= NoPartialFlip;
- }
-
-#ifdef QT_DIRECTFB_IMAGECACHE
- int imageCacheSize = 4 * 1024 * 1024; // 4 MB
- setIntOption(displayArgs, QLatin1String("imagecachesize"), &imageCacheSize);
- QDirectFBPaintEngine::initImageCache(imageCacheSize);
-#endif
-
-#ifndef QT_NO_DIRECTFB_WM
- if (displayArgs.contains(QLatin1String("fullscreen")))
-#endif
- d_ptr->dfb->SetCooperativeLevel(d_ptr->dfb, DFSCL_FULLSCREEN);
-
- const bool forcePremultiplied = displayArgs.contains(QLatin1String("forcepremultiplied"), Qt::CaseInsensitive);
-
- DFBSurfaceDescription description;
- memset(&description, 0, sizeof(DFBSurfaceDescription));
- IDirectFBSurface *surface;
-
-#ifdef QT_NO_DIRECTFB_WM
- description.flags = DSDESC_CAPS;
- if (::setIntOption(displayArgs, QLatin1String("width"), &description.width))
- description.flags |= DSDESC_WIDTH;
- if (::setIntOption(displayArgs, QLatin1String("height"), &description.height))
- description.flags |= DSDESC_HEIGHT;
-
- description.caps = DSCAPS_PRIMARY|DSCAPS_DOUBLE;
- struct {
- const char *name;
- const DFBSurfaceCapabilities cap;
- } const capabilities[] = {
- { "static_alloc", DSCAPS_STATIC_ALLOC },
- { "triplebuffer", DSCAPS_TRIPLE },
- { "interlaced", DSCAPS_INTERLACED },
- { "separated", DSCAPS_SEPARATED },
-// { "depthbuffer", DSCAPS_DEPTH }, // only makes sense with TextureTriangles which are not supported
- { 0, DSCAPS_NONE }
- };
- for (int i=0; capabilities[i].name; ++i) {
- if (displayArgs.contains(QString::fromLatin1(capabilities[i].name), Qt::CaseInsensitive))
- description.caps |= capabilities[i].cap;
- }
-
- if (forcePremultiplied) {
- description.caps |= DSCAPS_PREMULTIPLIED;
- }
-
- // We don't track the primary surface as it's released in disconnect
- d_ptr->primarySurface = createDFBSurface(description, DontTrackSurface, &result);
- if (!d_ptr->primarySurface) {
- DirectFBError("QDirectFBScreen: error creating primary surface",
- result);
- return false;
- }
-
- surface = d_ptr->primarySurface;
-#else
- description.flags = DSDESC_WIDTH|DSDESC_HEIGHT;
- description.width = description.height = 1;
- surface = createDFBSurface(description, DontTrackSurface, &result);
- if (!surface) {
- DirectFBError("QDirectFBScreen: error creating surface", result);
- return false;
- }
-#endif
- // Work out what format we're going to use for surfaces with an alpha channel
- QImage::Format pixelFormat = QDirectFBScreen::getImageFormat(surface);
- d_ptr->alphaPixmapFormat = pixelFormat;
-
- switch (pixelFormat) {
- 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::Format_RGB32:
- pixelFormat = d_ptr->alphaPixmapFormat = QImage::Format_ARGB32_Premultiplied;
- // ### Format_RGB32 doesn't work so well with Qt. Force ARGB32 for windows/pixmaps
- break;
- case QImage::Format_Indexed8:
- qWarning("QDirectFBScreen::connect(). Qt/DirectFB does not work with the LUT8 pixelformat.");
- return false;
- case QImage::NImageFormats:
- case QImage::Format_Invalid:
- case QImage::Format_Mono:
- case QImage::Format_MonoLSB:
- case QImage::Format_RGB888:
- case QImage::Format_RGB16:
- case QImage::Format_RGB555:
- d_ptr->alphaPixmapFormat = QImage::Format_ARGB32_Premultiplied;
- break;
- case QImage::Format_ARGB32:
- if (forcePremultiplied)
- d_ptr->alphaPixmapFormat = pixelFormat = QImage::Format_ARGB32_Premultiplied;
- 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;
- }
- setPixelFormat(pixelFormat);
- QScreen::d = QDirectFBScreen::depth(pixelFormat);
- data = 0;
- lstep = 0;
- size = 0;
-
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreen::connect: "
- "Unable to get screen!", result);
- return false;
- }
- const QString qws_size = QString::fromLatin1(qgetenv("QWS_SIZE"));
- if (!qws_size.isEmpty()) {
- QRegExp rx(QLatin1String("(\\d+)x(\\d+)"));
- if (!rx.exactMatch(qws_size)) {
- qWarning("QDirectFBScreen::connect: Can't parse QWS_SIZE=\"%s\"", qPrintable(qws_size));
- } else {
- int *ints[2] = { &w, &h };
- for (int i=0; i<2; ++i) {
- *ints[i] = rx.cap(i + 1).toInt();
- if (*ints[i] <= 0) {
- qWarning("QDirectFBScreen::connect: %s is not a positive integer",
- qPrintable(rx.cap(i + 1)));
- w = h = 0;
- break;
- }
- }
- }
- }
-
- setIntOption(displayArgs, QLatin1String("width"), &w);
- setIntOption(displayArgs, QLatin1String("height"), &h);
-
-#ifndef QT_NO_DIRECTFB_LAYER
- int layerId = DLID_PRIMARY;
- setIntOption(displayArgs, QLatin1String("layerid"), &layerId);
-
- result = d_ptr->dfb->GetDisplayLayer(d_ptr->dfb, static_cast<DFBDisplayLayerID>(layerId),
- &d_ptr->dfbLayer);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreen::connect: "
- "Unable to get display layer!", result);
- return false;
- }
- result = d_ptr->dfbLayer->GetScreen(d_ptr->dfbLayer, &d_ptr->dfbScreen);
-#else
- result = d_ptr->dfb->GetScreen(d_ptr->dfb, 0, &d_ptr->dfbScreen);
-#endif
-
- if (w <= 0 || h <= 0) {
-#ifdef QT_NO_DIRECTFB_WM
- result = d_ptr->primarySurface->GetSize(d_ptr->primarySurface, &w, &h);
-#elif (Q_DIRECTFB_VERSION >= 0x010000)
- IDirectFBSurface *layerSurface;
- if (d_ptr->dfbLayer->GetSurface(d_ptr->dfbLayer, &layerSurface) == DFB_OK) {
- result = layerSurface->GetSize(layerSurface, &w, &h);
- layerSurface->Release(layerSurface);
- }
- if (w <= 0 || h <= 0) {
- result = d_ptr->dfbScreen->GetSize(d_ptr->dfbScreen, &w, &h);
- }
-#else
- qWarning("QDirectFBScreen::connect: DirectFB versions prior to 1.0 do not offer a way\n"
- "query the size of the primary surface in windowed mode. You have to specify\n"
- "the size of the display using QWS_SIZE=[0-9]x[0-9] or\n"
- "QWS_DISPLAY=directfb:width=[0-9]:height=[0-9]");
- return false;
-#endif
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreen::connect: "
- "Unable to get screen size!", result);
- return false;
- }
- }
-
-
- dw = w;
- dh = h;
-
- Q_ASSERT(dw != 0 && dh != 0);
-
- physWidth = physHeight = -1;
- setIntOption(displayArgs, QLatin1String("mmWidth"), &physWidth);
- setIntOption(displayArgs, QLatin1String("mmHeight"), &physHeight);
- const int dpi = 72;
- if (physWidth < 0)
- physWidth = qRound(dw * 25.4 / dpi);
- if (physHeight < 0)
- physHeight = qRound(dh * 25.4 / dpi);
-
- setGraphicsSystem(d_ptr);
-
-#if (Q_DIRECTFB_VERSION >= 0x000923)
- if (displayArgs.contains(QLatin1String("debug"), Qt::CaseInsensitive))
- printDirectFBInfo(d_ptr->dfb, surface);
-#endif
-#ifdef QT_DIRECTFB_WM
- surface->Release(surface);
- QColor backgroundColor;
-#else
- QColor &backgroundColor = d_ptr->backgroundColor;
-#endif
-
- QRegExp backgroundColorRegExp(QLatin1String("bgcolor=(.+)"));
- backgroundColorRegExp.setCaseSensitivity(Qt::CaseInsensitive);
- if (displayArgs.indexOf(backgroundColorRegExp) != -1) {
- backgroundColor = colorFromName(backgroundColorRegExp.cap(1));
- }
-#ifdef QT_NO_DIRECTFB_WM
- if (!backgroundColor.isValid())
- backgroundColor = Qt::green;
- d_ptr->primarySurface->Clear(d_ptr->primarySurface, backgroundColor.red(),
- backgroundColor.green(), backgroundColor.blue(),
- backgroundColor.alpha());
- d_ptr->primarySurface->Flip(d_ptr->primarySurface, 0, d_ptr->flipFlags);
-#else
- if (backgroundColor.isValid()) {
- DFBResult result = d_ptr->dfbLayer->SetCooperativeLevel(d_ptr->dfbLayer, DLSCL_ADMINISTRATIVE);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreen::connect "
- "Unable to set cooperative level", result);
- }
- result = d_ptr->dfbLayer->SetBackgroundColor(d_ptr->dfbLayer, backgroundColor.red(), backgroundColor.green(),
- backgroundColor.blue(), backgroundColor.alpha());
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::connect: "
- "Unable to set background color", result);
- }
-
- result = d_ptr->dfbLayer->SetBackgroundMode(d_ptr->dfbLayer, DLBM_COLOR);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreenCursor::connect: "
- "Unable to set background mode", result);
- }
-
- result = d_ptr->dfbLayer->SetCooperativeLevel(d_ptr->dfbLayer, DLSCL_SHARED);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreen::connect "
- "Unable to set cooperative level", result);
- }
-
- }
-#endif
-
- return true;
-}
-
-void QDirectFBScreen::disconnect()
-{
-#if defined QT_DIRECTFB_IMAGEPROVIDER_KEEPALIVE
- if (d_ptr->imageProvider)
- d_ptr->imageProvider->Release(d_ptr->imageProvider);
-#endif
-#ifdef QT_NO_DIRECTFB_WM
- d_ptr->primarySurface->Release(d_ptr->primarySurface);
- d_ptr->primarySurface = 0;
-#endif
-
- foreach (IDirectFBSurface *surf, d_ptr->allocatedSurfaces)
- surf->Release(surf);
- d_ptr->allocatedSurfaces.clear();
-
-#ifndef QT_NO_DIRECTFB_LAYER
- d_ptr->dfbLayer->Release(d_ptr->dfbLayer);
- d_ptr->dfbLayer = 0;
-#endif
-
- d_ptr->dfbScreen->Release(d_ptr->dfbScreen);
- d_ptr->dfbScreen = 0;
-
- d_ptr->dfb->Release(d_ptr->dfb);
- d_ptr->dfb = 0;
-}
-
-bool QDirectFBScreen::initDevice()
-{
-#ifndef QT_NO_DIRECTFB_MOUSE
- if (qgetenv("QWS_MOUSE_PROTO").isEmpty()) {
- QWSServer::instance()->setDefaultMouse("None");
- d_ptr->mouse = new QDirectFBMouseHandler;
- }
-#endif
-#ifndef QT_NO_DIRECTFB_KEYBOARD
- if (qgetenv("QWS_KEYBOARD").isEmpty()) {
- QWSServer::instance()->setDefaultKeyboard("None");
- d_ptr->keyboard = new QDirectFBKeyboardHandler(QString());
- }
-#endif
-
-#ifdef QT_DIRECTFB_CURSOR
- qt_screencursor = new QDirectFBScreenCursor;
-#elif !defined QT_NO_QWS_CURSOR
- QScreenCursor::initSoftwareCursor();
-#endif
- return true;
-}
-
-void QDirectFBScreen::shutdownDevice()
-{
-#ifndef QT_NO_DIRECTFB_MOUSE
- delete d_ptr->mouse;
- d_ptr->mouse = 0;
-#endif
-#ifndef QT_NO_DIRECTFB_KEYBOARD
- delete d_ptr->keyboard;
- d_ptr->keyboard = 0;
-#endif
-
-#ifndef QT_NO_QWS_CURSOR
- delete qt_screencursor;
- qt_screencursor = 0;
-#endif
-}
-
-void QDirectFBScreen::setMode(int width, int height, int depth)
-{
- d_ptr->dfb->SetVideoMode(d_ptr->dfb, width, height, depth);
-}
-
-void QDirectFBScreen::blank(bool on)
-{
- d_ptr->dfbScreen->SetPowerMode(d_ptr->dfbScreen,
- (on ? DSPM_ON : DSPM_SUSPEND));
-}
-
-QWSWindowSurface *QDirectFBScreen::createSurface(QWidget *widget) const
-{
-#ifdef QT_NO_DIRECTFB_WM
- if (QApplication::type() == QApplication::GuiServer) {
- return new QDirectFBWindowSurface(d_ptr->flipFlags, const_cast<QDirectFBScreen*>(this), widget);
- } else {
- return QScreen::createSurface(widget);
- }
-#else
- return new QDirectFBWindowSurface(d_ptr->flipFlags, const_cast<QDirectFBScreen*>(this), widget);
-#endif
-}
-
-QWSWindowSurface *QDirectFBScreen::createSurface(const QString &key) const
-{
- if (key == QLatin1String("directfb")) {
- return new QDirectFBWindowSurface(d_ptr->flipFlags, const_cast<QDirectFBScreen*>(this));
- }
- return QScreen::createSurface(key);
-}
-
-#if defined QT_NO_DIRECTFB_WM
-struct PaintCommand {
- PaintCommand() : dfbSurface(0), windowOpacity(255), blittingFlags(DSBLIT_NOFX) {}
- IDirectFBSurface *dfbSurface;
- QImage image;
- QPoint windowPosition;
- QRegion source;
- quint8 windowOpacity;
- DFBSurfaceBlittingFlags blittingFlags;
-};
-
-static inline void initParameters(DFBRectangle &source, const QRect &sourceGlobal, const QPoint &pos)
-{
- source.x = sourceGlobal.x() - pos.x();
- source.y = sourceGlobal.y() - pos.y();
- source.w = sourceGlobal.width();
- source.h = sourceGlobal.height();
-}
-#endif
-
-void QDirectFBScreen::exposeRegion(QRegion r, int)
-{
- Q_UNUSED(r);
-#if defined QT_NO_DIRECTFB_WM
-
- r &= region();
- if (r.isEmpty()) {
- return;
- }
- r = r.boundingRect();
-
- IDirectFBSurface *primary = d_ptr->primarySurface;
- const QList<QWSWindow*> windows = QWSServer::instance()->clientWindows();
- QVarLengthArray<PaintCommand, 4> commands(windows.size());
- QRegion region = r;
- int idx = 0;
- for (int i=0; i<windows.size(); ++i) {
- QWSWindowSurface *surface = windows.at(i)->windowSurface();
- if (!surface)
- continue;
-
- const QRect windowGeometry = surface->geometry();
- const QRegion intersection = region & windowGeometry;
- if (intersection.isEmpty()) {
- continue;
- }
-
- PaintCommand &cmd = commands[idx];
-
- if (surface->key() == QLatin1String("directfb")) {
- const QDirectFBWindowSurface *ws = static_cast<QDirectFBWindowSurface*>(surface);
- cmd.dfbSurface = ws->directFBSurface();
-
- if (!cmd.dfbSurface) {
- continue;
- }
- } else {
- cmd.image = surface->image();
- if (cmd.image.isNull()) {
- continue;
- }
- }
- ++idx;
-
- cmd.windowPosition = windowGeometry.topLeft();
- cmd.source = intersection;
- if (windows.at(i)->isOpaque()) {
- region -= intersection;
- if (region.isEmpty())
- break;
- } else {
- cmd.windowOpacity = windows.at(i)->opacity();
- cmd.blittingFlags = cmd.windowOpacity == 255
- ? DSBLIT_BLEND_ALPHACHANNEL
- : (DSBLIT_BLEND_ALPHACHANNEL|DSBLIT_BLEND_COLORALPHA);
- }
- }
-
- solidFill(d_ptr->backgroundColor, region);
-
- while (idx > 0) {
- const PaintCommand &cmd = commands[--idx];
- Q_ASSERT(cmd.dfbSurface || !cmd.image.isNull());
- IDirectFBSurface *surface;
- if (cmd.dfbSurface) {
- surface = cmd.dfbSurface;
- } else {
- Q_ASSERT(!cmd.image.isNull());
- DFBResult result;
- surface = createDFBSurface(cmd.image, cmd.image.format(), DontTrackSurface, &result);
- Q_ASSERT((result != DFB_OK) == !surface);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreen::exposeRegion: Can't create surface from image", result);
- continue;
- }
- }
-
- primary->SetBlittingFlags(primary, cmd.blittingFlags);
- if (cmd.blittingFlags & DSBLIT_BLEND_COLORALPHA) {
- primary->SetColor(primary, 0xff, 0xff, 0xff, cmd.windowOpacity);
- }
- const QRegion &region = cmd.source;
- const int rectCount = region.rectCount();
- DFBRectangle source;
- if (rectCount == 1) {
- ::initParameters(source, region.boundingRect(), cmd.windowPosition);
- primary->Blit(primary, surface, &source, cmd.windowPosition.x() + source.x, cmd.windowPosition.y() + source.y);
- } else {
- const QVector<QRect> rects = region.rects();
- for (int i=0; i<rectCount; ++i) {
- ::initParameters(source, rects.at(i), cmd.windowPosition);
- primary->Blit(primary, surface, &source, cmd.windowPosition.x() + source.x, cmd.windowPosition.y() + source.y);
- }
- }
- if (surface != cmd.dfbSurface) {
- surface->Release(surface);
- }
- }
-
- primary->SetColor(primary, 0xff, 0xff, 0xff, 0xff);
-
-#if defined QT_NO_DIRECTFB_CURSOR and !defined QT_NO_QWS_CURSOR
- if (QScreenCursor *cursor = QScreenCursor::instance()) {
- const QRect cursorRectangle = cursor->boundingRect();
- if (cursor->isVisible() && !cursor->isAccelerated() && r.intersects(cursorRectangle)) {
- const QImage image = cursor->image();
- if (image.cacheKey() != d_ptr->cursorImageKey) {
- if (d_ptr->cursorSurface) {
- releaseDFBSurface(d_ptr->cursorSurface);
- }
- d_ptr->cursorSurface = createDFBSurface(image, image.format(), QDirectFBScreen::TrackSurface);
- d_ptr->cursorImageKey = image.cacheKey();
- }
-
- Q_ASSERT(d_ptr->cursorSurface);
- primary->SetBlittingFlags(primary, DSBLIT_BLEND_ALPHACHANNEL);
- primary->Blit(primary, d_ptr->cursorSurface, 0, cursorRectangle.x(), cursorRectangle.y());
- }
- }
-#endif
- flipSurface(primary, d_ptr->flipFlags, r, QPoint());
- primary->SetBlittingFlags(primary, DSBLIT_NOFX);
-#endif
-}
-
-void QDirectFBScreen::solidFill(const QColor &color, const QRegion &region)
-{
-#ifdef QT_DIRECTFB_WM
- Q_UNUSED(color);
- Q_UNUSED(region);
-#else
- QDirectFBScreen::solidFill(d_ptr->primarySurface, color, region);
-#endif
-}
-
-static inline void clearRect(IDirectFBSurface *surface, const QColor &color, const QRect &rect)
-{
- Q_ASSERT(surface);
- const DFBRegion region = { rect.left(), rect.top(), rect.right(), rect.bottom() };
- // could just reinterpret_cast this to a DFBRegion
- surface->SetClip(surface, &region);
- surface->Clear(surface, color.red(), color.green(), color.blue(), color.alpha());
-}
-
-void QDirectFBScreen::solidFill(IDirectFBSurface *surface, const QColor &color, const QRegion &region)
-{
- if (region.isEmpty())
- return;
-
- const int n = region.rectCount();
- if (n == 1) {
- clearRect(surface, color, region.boundingRect());
- } else {
- const QVector<QRect> rects = region.rects();
- for (int i=0; i<n; ++i) {
- clearRect(surface, color, rects.at(i));
- }
- }
- surface->SetClip(surface, 0);
-}
-
-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 |= DSDESC_PIXELFORMAT;
- description->pixelformat = pixelformat;
- if (QDirectFBScreen::isPremultiplied(format)) {
- if (!(description->flags & DSDESC_CAPS)) {
- description->caps = DSCAPS_PREMULTIPLIED;
- description->flags |= DSDESC_CAPS;
- } else {
- description->caps |= DSCAPS_PREMULTIPLIED;
- }
- }
- return true;
-}
-
-uchar *QDirectFBScreen::lockSurface(IDirectFBSurface *surface, DFBSurfaceLockFlags flags, int *bpl)
-{
- void *mem = 0;
- const DFBResult result = surface->Lock(surface, flags, &mem, bpl);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreen::lockSurface()", result);
- }
-
- return reinterpret_cast<uchar*>(mem);
-}
-
-static inline bool isFullUpdate(IDirectFBSurface *surface, const QRegion &region, const QPoint &offset)
-{
- if (offset == QPoint(0, 0) && region.rectCount() == 1) {
- QSize size;
- surface->GetSize(surface, &size.rwidth(), &size.rheight());
- if (region.boundingRect().size() == size)
- return true;
- }
- return false;
-}
-
-void QDirectFBScreen::flipSurface(IDirectFBSurface *surface, DFBSurfaceFlipFlags flipFlags,
- const QRegion &region, const QPoint &offset)
-{
- if (d_ptr->directFBFlags & NoPartialFlip
- || (!(flipFlags & DSFLIP_BLIT) && QT_PREPEND_NAMESPACE(isFullUpdate(surface, region, offset)))) {
- surface->Flip(surface, 0, flipFlags);
- } else {
- if (!(d_ptr->directFBFlags & BoundingRectFlip) && region.rectCount() > 1) {
- const QVector<QRect> rects = region.rects();
- const DFBSurfaceFlipFlags nonWaitFlags = 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.right() + offset.x(),
- r.bottom() + offset.y() };
- surface->Flip(surface, &dfbReg, i + 1 < rects.size() ? nonWaitFlags : flipFlags);
- }
- } else {
- const QRect r = region.boundingRect();
- const DFBRegion dfbReg = { r.x() + offset.x(), r.y() + offset.y(),
- r.right() + offset.x(),
- r.bottom() + offset.y() };
- surface->Flip(surface, &dfbReg, flipFlags);
- }
- }
-}
-
-#if defined QT_DIRECTFB_IMAGEPROVIDER_KEEPALIVE
-void QDirectFBScreen::setDirectFBImageProvider(IDirectFBImageProvider *provider)
-{
- Q_ASSERT(provider);
- if (d_ptr->imageProvider)
- d_ptr->imageProvider->Release(d_ptr->imageProvider);
- d_ptr->imageProvider = provider;
-}
-#endif
-
-void QDirectFBScreen::waitIdle()
-{
- d_ptr->dfb->WaitIdle(d_ptr->dfb);
-}
-
-#ifdef QT_DIRECTFB_WM
-IDirectFBWindow *QDirectFBScreen::windowForWidget(const QWidget *widget) const
-{
- if (widget) {
- const QWSWindowSurface *surface = static_cast<const QWSWindowSurface*>(widget->windowSurface());
- if (surface && surface->key() == QLatin1String("directfb")) {
- return static_cast<const QDirectFBWindowSurface*>(surface)->directFBWindow();
- }
- }
- return 0;
-}
-#endif
-
-IDirectFBSurface * QDirectFBScreen::surfaceForWidget(const QWidget *widget, QRect *rect) const
-{
- Q_ASSERT(widget);
- if (!widget->isVisible() || widget->size().isNull())
- return 0;
-
- const QWSWindowSurface *surface = static_cast<const QWSWindowSurface*>(widget->windowSurface());
- if (surface && surface->key() == QLatin1String("directfb")) {
- return static_cast<const QDirectFBWindowSurface*>(surface)->surfaceForWidget(widget, rect);
- }
- return 0;
-}
-
-#ifdef QT_DIRECTFB_SUBSURFACE
-IDirectFBSurface *QDirectFBScreen::subSurfaceForWidget(const QWidget *widget, const QRect &area) const
-{
- Q_ASSERT(widget);
- QRect rect;
- IDirectFBSurface *surface = surfaceForWidget(widget, &rect);
- IDirectFBSurface *subSurface = 0;
- if (surface) {
- if (!area.isNull())
- rect &= area.translated(widget->mapTo(widget->window(), QPoint(0, 0)));
- if (!rect.isNull()) {
- const DFBRectangle subRect = { rect.x(), rect.y(), rect.width(), rect.height() };
- const DFBResult result = surface->GetSubSurface(surface, &subRect, &subSurface);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBScreen::subSurface(): Can't get sub surface", result);
- }
- }
- }
- return subSurface;
-}
-#endif
-
-Q_GUI_EXPORT IDirectFBSurface *qt_directfb_surface_for_widget(const QWidget *widget, QRect *rect)
-{
- return QDirectFBScreen::instance() ? QDirectFBScreen::instance()->surfaceForWidget(widget, rect) : 0;
-}
-#ifdef QT_DIRECTFB_SUBSURFACE
-Q_GUI_EXPORT IDirectFBSurface *qt_directfb_subsurface_for_widget(const QWidget *widget, const QRect &area)
-{
- return QDirectFBScreen::instance() ? QDirectFBScreen::instance()->subSurfaceForWidget(widget, area) : 0;
-}
-#endif
-#ifdef QT_DIRECTFB_WM
-Q_GUI_EXPORT IDirectFBWindow *qt_directfb_window_for_widget(const QWidget *widget)
-{
- return QDirectFBScreen::instance() ? QDirectFBScreen::instance()->windowForWidget(widget) : 0;
-}
-
-#endif
-
-QT_END_NAMESPACE
-
-#include "qdirectfbscreen.moc"
-#endif // QT_NO_QWS_DIRECTFB
-
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h
deleted file mode 100644
index afc153bab2..0000000000
--- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h
+++ /dev/null
@@ -1,303 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDIRECTFBSCREEN_H
-#define QDIRECTFBSCREEN_H
-
-#include <qglobal.h>
-#ifndef QT_NO_QWS_DIRECTFB
-#include <QtGui/qscreen_qws.h>
-#include <directfb.h>
-#include <directfb_version.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-#if !defined QT_DIRECTFB_SUBSURFACE && !defined QT_NO_DIRECTFB_SUBSURFACE
-#define QT_NO_DIRECTFB_SUBSURFACE
-#endif
-#if !defined QT_NO_DIRECTFB_LAYER && !defined QT_DIRECTFB_LAYER
-#define QT_DIRECTFB_LAYER
-#endif
-#if !defined QT_NO_DIRECTFB_WM && !defined QT_DIRECTFB_WM
-#define QT_DIRECTFB_WM
-#endif
-#if !defined QT_DIRECTFB_IMAGECACHE && !defined QT_NO_DIRECTFB_IMAGECACHE
-#define QT_NO_DIRECTFB_IMAGECACHE
-#endif
-#if !defined QT_NO_DIRECTFB_IMAGEPROVIDER && !defined QT_DIRECTFB_IMAGEPROVIDER
-#define QT_DIRECTFB_IMAGEPROVIDER
-#endif
-#if !defined QT_NO_DIRECTFB_STRETCHBLIT && !defined QT_DIRECTFB_STRETCHBLIT
-#define QT_DIRECTFB_STRETCHBLIT
-#endif
-#if !defined QT_DIRECTFB_IMAGEPROVIDER_KEEPALIVE && !defined QT_NO_DIRECTFB_IMAGEPROVIDER_KEEPALIVE
-#define QT_NO_DIRECTFB_IMAGEPROVIDER_KEEPALIVE
-#endif
-#if !defined QT_DIRECTFB_WINDOW_AS_CURSOR && !defined QT_NO_DIRECTFB_WINDOW_AS_CURSOR
-#define QT_NO_DIRECTFB_WINDOW_AS_CURSOR
-#endif
-#if !defined QT_DIRECTFB_PALETTE && !defined QT_NO_DIRECTFB_PALETTE
-#define QT_NO_DIRECTFB_PALETTE
-#endif
-#if !defined QT_NO_DIRECTFB_PREALLOCATED && !defined QT_DIRECTFB_PREALLOCATED
-#define QT_DIRECTFB_PREALLOCATED
-#endif
-#if !defined QT_NO_DIRECTFB_MOUSE && !defined QT_DIRECTFB_MOUSE
-#define QT_DIRECTFB_MOUSE
-#endif
-#if !defined QT_NO_DIRECTFB_KEYBOARD && !defined QT_DIRECTFB_KEYBOARD
-#define QT_DIRECTFB_KEYBOARD
-#endif
-#if !defined QT_NO_DIRECTFB_OPAQUE_DETECTION && !defined QT_DIRECTFB_OPAQUE_DETECTION
-#define QT_DIRECTFB_OPAQUE_DETECTION
-#endif
-#ifndef QT_NO_QWS_CURSOR
-#if defined QT_DIRECTFB_WM && defined QT_DIRECTFB_WINDOW_AS_CURSOR
-#define QT_DIRECTFB_CURSOR
-#elif defined QT_DIRECTFB_LAYER
-#define QT_DIRECTFB_CURSOR
-#endif
-#endif
-#ifndef QT_DIRECTFB_CURSOR
-#define QT_NO_DIRECTFB_CURSOR
-#endif
-#if defined QT_NO_DIRECTFB_LAYER && defined QT_DIRECTFB_WM
-#error QT_NO_DIRECTFB_LAYER requires QT_NO_DIRECTFB_WM
-#endif
-#if defined QT_DIRECTFB_IMAGEPROVIDER_KEEPALIVE && defined QT_NO_DIRECTFB_IMAGEPROVIDER
-#error QT_DIRECTFB_IMAGEPROVIDER_KEEPALIVE requires QT_DIRECTFB_IMAGEPROVIDER to be defined
-#endif
-#if defined QT_DIRECTFB_WINDOW_AS_CURSOR && defined QT_NO_DIRECTFB_WM
-#error QT_DIRECTFB_WINDOW_AS_CURSOR requires QT_DIRECTFB_WM to be defined
-#endif
-
-#define Q_DIRECTFB_VERSION ((DIRECTFB_MAJOR_VERSION << 16) | (DIRECTFB_MINOR_VERSION << 8) | DIRECTFB_MICRO_VERSION)
-
-#define DIRECTFB_DECLARE_OPERATORS_FOR_FLAGS(F) \
- static inline F operator~(F f) { return F(~int(f)); } \
- static inline F operator&(F left, F right) { return F(int(left) & int(right)); } \
- static inline F operator|(F left, F right) { return F(int(left) | int(right)); } \
- static inline F &operator|=(F &left, F right) { left = (left | right); return left; } \
- static inline F &operator&=(F &left, F right) { left = (left & right); return left; }
-
-DIRECTFB_DECLARE_OPERATORS_FOR_FLAGS(DFBInputDeviceCapabilities);
-DIRECTFB_DECLARE_OPERATORS_FOR_FLAGS(DFBWindowDescriptionFlags);
-DIRECTFB_DECLARE_OPERATORS_FOR_FLAGS(DFBWindowCapabilities);
-DIRECTFB_DECLARE_OPERATORS_FOR_FLAGS(DFBWindowOptions);
-DIRECTFB_DECLARE_OPERATORS_FOR_FLAGS(DFBSurfaceDescriptionFlags);
-DIRECTFB_DECLARE_OPERATORS_FOR_FLAGS(DFBSurfaceCapabilities);
-DIRECTFB_DECLARE_OPERATORS_FOR_FLAGS(DFBSurfaceLockFlags);
-DIRECTFB_DECLARE_OPERATORS_FOR_FLAGS(DFBSurfaceBlittingFlags);
-DIRECTFB_DECLARE_OPERATORS_FOR_FLAGS(DFBSurfaceDrawingFlags);
-DIRECTFB_DECLARE_OPERATORS_FOR_FLAGS(DFBSurfaceFlipFlags);
-
-class QDirectFBScreenPrivate;
-class Q_GUI_EXPORT QDirectFBScreen : public QScreen
-{
-public:
- QDirectFBScreen(int display_id);
- ~QDirectFBScreen();
-
- enum DirectFBFlag {
- NoFlags = 0x00,
- VideoOnly = 0x01,
- SystemOnly = 0x02,
- BoundingRectFlip = 0x04,
- NoPartialFlip = 0x08
- };
-
- Q_DECLARE_FLAGS(DirectFBFlags, DirectFBFlag);
-
- DirectFBFlags directFBFlags() const;
-
- bool connect(const QString &displaySpec);
- void disconnect();
- bool initDevice();
- void shutdownDevice();
-
- void exposeRegion(QRegion r, int changing);
- void solidFill(const QColor &color, const QRegion &region);
- static void solidFill(IDirectFBSurface *surface, const QColor &color, const QRegion &region);
-
- void setMode(int width, int height, int depth);
- void blank(bool on);
-
- QWSWindowSurface *createSurface(QWidget *widget) const;
- QWSWindowSurface *createSurface(const QString &key) const;
-
- static QDirectFBScreen *instance();
- void waitIdle();
- IDirectFBSurface *surfaceForWidget(const QWidget *widget, QRect *rect) const;
-#ifdef QT_DIRECTFB_SUBSURFACE
- IDirectFBSurface *subSurfaceForWidget(const QWidget *widget, const QRect &area = QRect()) const;
-#endif
- IDirectFB *dfb();
-#ifdef QT_DIRECTFB_WM
- IDirectFBWindow *windowForWidget(const QWidget *widget) const;
-#else
- IDirectFBSurface *primarySurface();
-#endif
-#ifndef QT_NO_DIRECTFB_LAYER
- IDirectFBDisplayLayer *dfbDisplayLayer();
-#endif
-
- // Track surface creation/release so we can release all on exit
- enum SurfaceCreationOption {
- DontTrackSurface = 0x1,
- TrackSurface = 0x2,
- NoPreallocated = 0x4
- };
- Q_DECLARE_FLAGS(SurfaceCreationOptions, SurfaceCreationOption);
- IDirectFBSurface *createDFBSurface(const QImage &image,
- QImage::Format format,
- SurfaceCreationOptions options,
- DFBResult *result = 0);
- IDirectFBSurface *createDFBSurface(const QSize &size,
- QImage::Format format,
- SurfaceCreationOptions options,
- DFBResult *result = 0);
- IDirectFBSurface *copyDFBSurface(IDirectFBSurface *src,
- QImage::Format format,
- SurfaceCreationOptions options,
- DFBResult *result = 0);
- IDirectFBSurface *createDFBSurface(DFBSurfaceDescription desc,
- SurfaceCreationOptions options,
- DFBResult *result);
-#ifdef QT_DIRECTFB_SUBSURFACE
- IDirectFBSurface *getSubSurface(IDirectFBSurface *surface,
- const QRect &rect,
- SurfaceCreationOptions options,
- DFBResult *result);
-#endif
-
- void flipSurface(IDirectFBSurface *surface, DFBSurfaceFlipFlags flipFlags,
- const QRegion &region, const QPoint &offset);
- void releaseDFBSurface(IDirectFBSurface *surface);
-
- using QScreen::depth;
- static int depth(DFBSurfacePixelFormat format);
- static int depth(QImage::Format format);
-
- static DFBSurfacePixelFormat getSurfacePixelFormat(QImage::Format format);
- static DFBSurfaceDescription getSurfaceDescription(const uint *buffer,
- int length);
- static QImage::Format getImageFormat(IDirectFBSurface *surface);
- static bool initSurfaceDescriptionPixelFormat(DFBSurfaceDescription *description, QImage::Format format);
- static inline bool isPremultiplied(QImage::Format format);
- static inline bool hasAlphaChannel(DFBSurfacePixelFormat format);
- static inline bool hasAlphaChannel(IDirectFBSurface *surface);
- QImage::Format alphaPixmapFormat() const;
-
-#ifndef QT_NO_DIRECTFB_PALETTE
- static void setSurfaceColorTable(IDirectFBSurface *surface,
- const QImage &image);
-#endif
-
- static uchar *lockSurface(IDirectFBSurface *surface, DFBSurfaceLockFlags flags, int *bpl = 0);
-#if defined QT_DIRECTFB_IMAGEPROVIDER && defined QT_DIRECTFB_IMAGEPROVIDER_KEEPALIVE
- void setDirectFBImageProvider(IDirectFBImageProvider *provider);
-#endif
-private:
- QDirectFBScreenPrivate *d_ptr;
-};
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QDirectFBScreen::SurfaceCreationOptions);
-Q_DECLARE_OPERATORS_FOR_FLAGS(QDirectFBScreen::DirectFBFlags);
-
-inline bool QDirectFBScreen::isPremultiplied(QImage::Format format)
-{
- switch (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:
- return true;
- default:
- break;
- }
- return false;
-}
-
-inline bool QDirectFBScreen::hasAlphaChannel(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:
-#if (Q_DIRECTFB_VERSION >= 0x000923)
- case DSPF_AYUV:
-#endif
-#if (Q_DIRECTFB_VERSION >= 0x010000)
- case DSPF_A4:
- case DSPF_ARGB1666:
- case DSPF_ARGB6666:
- case DSPF_LUT2:
-#endif
- return true;
- default:
- return false;
- }
-}
-
-inline bool QDirectFBScreen::hasAlphaChannel(IDirectFBSurface *surface)
-{
- Q_ASSERT(surface);
- DFBSurfacePixelFormat format;
- surface->GetPixelFormat(surface, &format);
- return QDirectFBScreen::hasAlphaChannel(format);
-}
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QT_NO_QWS_DIRECTFB
-#endif // QDIRECTFBSCREEN_H
-
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreenplugin.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreenplugin.cpp
deleted file mode 100644
index 228e7b8dea..0000000000
--- a/src/plugins/gfxdrivers/directfb/qdirectfbscreenplugin.cpp
+++ /dev/null
@@ -1,78 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qdirectfbscreen.h"
-
-#include <QtGui/qscreendriverplugin_qws.h>
-#include <QtCore/qstringlist.h>
-#ifndef QT_NO_QWS_DIRECTFB
-
-class DirectFBScreenDriverPlugin : public QScreenDriverPlugin
-{
-public:
- DirectFBScreenDriverPlugin();
-
- QStringList keys() const;
- QScreen *create(const QString&, int displayId);
-};
-
-DirectFBScreenDriverPlugin::DirectFBScreenDriverPlugin()
- : QScreenDriverPlugin()
-{
-}
-
-QStringList DirectFBScreenDriverPlugin::keys() const
-{
- return (QStringList() << "directfb");
-}
-
-QScreen* DirectFBScreenDriverPlugin::create(const QString& driver,
- int displayId)
-{
- if (driver.toLower() != "directfb")
- return 0;
-
- return new QDirectFBScreen(displayId);
-}
-
-Q_EXPORT_PLUGIN2(qdirectfbscreen, DirectFBScreenDriverPlugin)
-
-#endif
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp
deleted file mode 100644
index b8fc811e4d..0000000000
--- a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp
+++ /dev/null
@@ -1,506 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qdirectfbwindowsurface.h"
-#include "qdirectfbscreen.h"
-#include "qdirectfbpaintengine.h"
-
-#include <private/qwidget_p.h>
-#include <qwidget.h>
-#include <qwindowsystem_qws.h>
-#include <qpaintdevice.h>
-#include <qvarlengtharray.h>
-
-#ifndef QT_NO_QWS_DIRECTFB
-
-QT_BEGIN_NAMESPACE
-
-QDirectFBWindowSurface::QDirectFBWindowSurface(DFBSurfaceFlipFlags flip, QDirectFBScreen *scr)
- : QDirectFBPaintDevice(scr)
-#ifndef QT_NO_DIRECTFB_WM
- , dfbWindow(0)
-#endif
- , flipFlags(flip)
- , boundingRectFlip(scr->directFBFlags() & QDirectFBScreen::BoundingRectFlip)
- , flushPending(false)
-{
-#ifdef QT_NO_DIRECTFB_WM
- mode = Offscreen;
-#endif
- setSurfaceFlags(Opaque | Buffered);
-#ifdef QT_DIRECTFB_TIMING
- frames = 0;
- timer.start();
-#endif
-}
-
-QDirectFBWindowSurface::QDirectFBWindowSurface(DFBSurfaceFlipFlags flip, QDirectFBScreen *scr, QWidget *widget)
- : QWSWindowSurface(widget), QDirectFBPaintDevice(scr)
-#ifndef QT_NO_DIRECTFB_WM
- , dfbWindow(0)
-#endif
- , flipFlags(flip)
- , boundingRectFlip(scr->directFBFlags() & QDirectFBScreen::BoundingRectFlip)
- , flushPending(false)
-{
- SurfaceFlags flags = 0;
- if (!widget || widget->window()->windowOpacity() == 0xff)
- flags |= Opaque;
-#ifdef QT_NO_DIRECTFB_WM
- if (widget && widget->testAttribute(Qt::WA_PaintOnScreen)) {
- flags = RegionReserved;
- mode = Primary;
- } else {
- mode = Offscreen;
- flags = Buffered;
- }
-#endif
- setSurfaceFlags(flags);
-#ifdef QT_DIRECTFB_TIMING
- frames = 0;
- timer.start();
-#endif
-}
-
-QDirectFBWindowSurface::~QDirectFBWindowSurface()
-{
- releaseSurface();
- // these are not tracked by QDirectFBScreen so we don't want QDirectFBPaintDevice to release it
-}
-
-bool QDirectFBWindowSurface::isValid() const
-{
- return true;
-}
-
-#ifdef QT_DIRECTFB_WM
-void QDirectFBWindowSurface::raise()
-{
- if (IDirectFBWindow *window = directFBWindow()) {
- window->RaiseToTop(window);
- }
-}
-
-IDirectFBWindow *QDirectFBWindowSurface::directFBWindow() const
-{
- return dfbWindow;
-}
-
-void QDirectFBWindowSurface::createWindow(const QRect &rect)
-{
- IDirectFBDisplayLayer *layer = screen->dfbDisplayLayer();
- if (!layer)
- qFatal("QDirectFBWindowSurface: Unable to get primary display layer!");
-
- updateIsOpaque();
-
- DFBWindowDescription description;
- memset(&description, 0, sizeof(DFBWindowDescription));
-
- description.flags = DWDESC_CAPS|DWDESC_HEIGHT|DWDESC_WIDTH|DWDESC_POSX|DWDESC_POSY|DWDESC_SURFACE_CAPS|DWDESC_PIXELFORMAT;
- description.caps = DWCAPS_NODECORATION;
- description.surface_caps = DSCAPS_NONE;
- imageFormat = screen->pixelFormat();
-
- if (!(surfaceFlags() & Opaque)) {
- imageFormat = screen->alphaPixmapFormat();
- description.caps |= DWCAPS_ALPHACHANNEL;
-#if (Q_DIRECTFB_VERSION >= 0x010200)
- description.flags |= DWDESC_OPTIONS;
- description.options |= DWOP_ALPHACHANNEL;
-#endif
- }
- description.pixelformat = QDirectFBScreen::getSurfacePixelFormat(imageFormat);
- description.posx = rect.x();
- description.posy = rect.y();
- description.width = rect.width();
- description.height = rect.height();
-
- if (QDirectFBScreen::isPremultiplied(imageFormat))
- description.surface_caps = DSCAPS_PREMULTIPLIED;
-
- if (screen->directFBFlags() & QDirectFBScreen::VideoOnly)
- description.surface_caps |= DSCAPS_VIDEOONLY;
-
- DFBResult result = layer->CreateWindow(layer, &description, &dfbWindow);
-
- if (result != DFB_OK)
- DirectFBErrorFatal("QDirectFBWindowSurface::createWindow", result);
-
- if (window()) {
- if (window()->windowFlags() & Qt::WindowStaysOnTopHint) {
- dfbWindow->SetStackingClass(dfbWindow, DWSC_UPPER);
- }
- DFBWindowID winid;
- result = dfbWindow->GetID(dfbWindow, &winid);
- if (result != DFB_OK) {
- DirectFBError("QDirectFBWindowSurface::createWindow. Can't get ID", result);
- } else {
- window()->setProperty("_q_DirectFBWindowID", winid);
- }
- }
-
- Q_ASSERT(!dfbSurface);
- dfbWindow->GetSurface(dfbWindow, &dfbSurface);
-}
-
-static DFBResult setWindowGeometry(IDirectFBWindow *dfbWindow, const QRect &old, const QRect &rect)
-{
- DFBResult result = DFB_OK;
- const bool isMove = old.isEmpty() || rect.topLeft() != old.topLeft();
- const bool isResize = rect.size() != old.size();
-
-#if (Q_DIRECTFB_VERSION >= 0x010000)
- if (isResize && isMove) {
- result = dfbWindow->SetBounds(dfbWindow, rect.x(), rect.y(),
- rect.width(), rect.height());
- } else if (isResize) {
- result = dfbWindow->Resize(dfbWindow,
- rect.width(), rect.height());
- } else if (isMove) {
- result = dfbWindow->MoveTo(dfbWindow, rect.x(), rect.y());
- }
-#else
- if (isResize) {
- result = dfbWindow->Resize(dfbWindow,
- rect.width(), rect.height());
- }
- if (isMove) {
- result = dfbWindow->MoveTo(dfbWindow, rect.x(), rect.y());
- }
-#endif
- return result;
-}
-#endif // QT_NO_DIRECTFB_WM
-
-void QDirectFBWindowSurface::setGeometry(const QRect &rect)
-{
- const QRect oldRect = geometry();
- if (oldRect == rect)
- return;
-
- IDirectFBSurface *oldSurface = dfbSurface;
- const bool sizeChanged = oldRect.size() != rect.size();
- if (sizeChanged) {
- delete engine;
- engine = 0;
- releaseSurface();
- Q_ASSERT(!dfbSurface);
- }
-
- if (rect.isNull()) {
-#ifndef QT_NO_DIRECTFB_WM
- if (dfbWindow) {
- if (window())
- window()->setProperty("_q_DirectFBWindowID", QVariant());
-
- dfbWindow->Release(dfbWindow);
- dfbWindow = 0;
- }
-#endif
- Q_ASSERT(!dfbSurface);
-#ifdef QT_DIRECTFB_SUBSURFACE
- Q_ASSERT(!subSurface);
-#endif
- } else {
-#ifdef QT_DIRECTFB_WM
- if (!dfbWindow) {
- createWindow(rect);
- } else {
- setWindowGeometry(dfbWindow, oldRect, rect);
- Q_ASSERT(!sizeChanged || !dfbSurface);
- if (sizeChanged)
- dfbWindow->GetSurface(dfbWindow, &dfbSurface);
- }
-#else
- IDirectFBSurface *primarySurface = screen->primarySurface();
- DFBResult result = DFB_OK;
- if (mode == Primary) {
- Q_ASSERT(primarySurface);
- 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);
- }
- } else { // mode == Offscreen
- if (!dfbSurface) {
- dfbSurface = screen->createDFBSurface(rect.size(), surfaceFlags() & Opaque ? screen->pixelFormat() : screen->alphaPixmapFormat(),
- QDirectFBScreen::DontTrackSurface);
- }
- }
- if (result != DFB_OK)
- DirectFBErrorFatal("QDirectFBWindowSurface::setGeometry()", result);
-#endif
- }
- if (oldSurface != dfbSurface) {
- imageFormat = dfbSurface ? QDirectFBScreen::getImageFormat(dfbSurface) : QImage::Format_Invalid;
- }
-
- if (oldRect.size() != rect.size()) {
- QWSWindowSurface::setGeometry(rect);
- } else {
- QWindowSurface::setGeometry(rect);
- }
-}
-
-QByteArray QDirectFBWindowSurface::permanentState() const
-{
- QByteArray state(sizeof(SurfaceFlags) + sizeof(DFBWindowID), 0);
- char *ptr = state.data();
- SurfaceFlags flags = surfaceFlags();
- memcpy(ptr, &flags, sizeof(SurfaceFlags));
- ptr += sizeof(SurfaceFlags);
- DFBWindowID did = (DFBWindowID)(-1);
- if (dfbWindow)
- dfbWindow->GetID(dfbWindow, &did);
- memcpy(ptr, &did, sizeof(DFBWindowID));
- return state;
-}
-
-void QDirectFBWindowSurface::setPermanentState(const QByteArray &state)
-{
- const char *ptr = state.constData();
- IDirectFBDisplayLayer *layer = screen->dfbDisplayLayer();
- SurfaceFlags flags;
- memcpy(&flags, ptr, sizeof(SurfaceFlags));
-
- setSurfaceFlags(flags);
- ptr += sizeof(SurfaceFlags);
- DFBWindowID id;
- memcpy(&id, ptr, sizeof(DFBWindowID));
- if (dfbSurface)
- dfbSurface->Release(dfbSurface);
- if (id != (DFBWindowID)-1) {
- IDirectFBWindow *dw;
- layer->GetWindow(layer, id, &dw);
- if (dw->GetSurface(dw, &dfbSurface) != DFB_OK)
- dfbSurface = 0;
- dw->Release(dw);
- }
- else {
- dfbSurface = 0;
- }
-}
-
-bool QDirectFBWindowSurface::scroll(const QRegion &region, int dx, int dy)
-{
- if (!dfbSurface || !(flipFlags & DSFLIP_BLIT) || region.rectCount() != 1)
- return false;
- if (flushPending) {
- dfbSurface->Flip(dfbSurface, 0, DSFLIP_BLIT);
- } else {
- flushPending = true;
- }
- dfbSurface->SetBlittingFlags(dfbSurface, DSBLIT_NOFX);
- const QRect r = region.boundingRect();
- const DFBRectangle rect = { r.x(), r.y(), r.width(), r.height() };
- dfbSurface->Blit(dfbSurface, dfbSurface, &rect, r.x() + dx, r.y() + dy);
- return true;
-}
-
-bool QDirectFBWindowSurface::move(const QPoint &moveBy)
-{
- setGeometry(geometry().translated(moveBy));
- return true;
-}
-
-void QDirectFBWindowSurface::setOpaque(bool opaque)
-{
- SurfaceFlags flags = surfaceFlags();
- if (opaque != (flags & Opaque)) {
- if (opaque) {
- flags |= Opaque;
- } else {
- flags &= ~Opaque;
- }
- setSurfaceFlags(flags);
- }
-}
-
-
-void QDirectFBWindowSurface::flush(QWidget *widget, const QRegion &region,
- const QPoint &offset)
-{
- QWidget *win = window();
- if (!win)
- return;
-
-#if !defined(QT_NO_QWS_PROXYSCREEN) && !defined(QT_NO_GRAPHICSVIEW)
- QWExtra *extra = qt_widget_private(widget)->extraData();
- if (extra && extra->proxyWidget)
- return;
-#else
- Q_UNUSED(widget);
-#endif
-
- const quint8 windowOpacity = quint8(win->windowOpacity() * 0xff);
- const QRect windowGeometry = geometry();
-#ifdef QT_DIRECTFB_WM
- quint8 currentOpacity;
- Q_ASSERT(dfbWindow);
- dfbWindow->GetOpacity(dfbWindow, &currentOpacity);
- if (currentOpacity != windowOpacity) {
- dfbWindow->SetOpacity(dfbWindow, windowOpacity);
- }
-
- screen->flipSurface(dfbSurface, flipFlags, region, offset);
-#else
- setOpaque(windowOpacity == 0xff);
- if (mode == Offscreen) {
- screen->exposeRegion(region.translated(offset + geometry().topLeft()), 0);
- } else {
- screen->flipSurface(dfbSurface, flipFlags, region, offset);
- }
-#endif
-
-#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
- flushPending = false;
-}
-
-void QDirectFBWindowSurface::beginPaint(const QRegion &region)
-{
- if (!engine) {
- engine = new QDirectFBPaintEngine(this);
- }
-
- if (dfbSurface) {
- const QWidget *win = window();
- if (win && win->testAttribute(Qt::WA_NoSystemBackground)) {
- QDirectFBScreen::solidFill(dfbSurface, Qt::transparent, region);
- }
- }
- flushPending = true;
-}
-
-void QDirectFBWindowSurface::endPaint(const QRegion &)
-{
-#ifdef QT_NO_DIRECTFB_SUBSURFACE
- unlockSurface();
-#endif
-}
-
-IDirectFBSurface *QDirectFBWindowSurface::directFBSurface() const
-{
- return dfbSurface;
-}
-
-
-IDirectFBSurface *QDirectFBWindowSurface::surfaceForWidget(const QWidget *widget, QRect *rect) const
-{
- Q_ASSERT(widget);
- if (!dfbSurface)
- return 0;
- QWidget *win = window();
- Q_ASSERT(win);
- if (rect) {
- if (win == widget) {
- *rect = widget->rect();
- } else {
- *rect = QRect(widget->mapTo(win, QPoint(0, 0)), widget->size());
- }
- }
-
- Q_ASSERT(win == widget || win->isAncestorOf(widget));
- return dfbSurface;
-}
-
-void QDirectFBWindowSurface::releaseSurface()
-{
- if (dfbSurface) {
-#ifdef QT_DIRECTFB_SUBSURFACE
- releaseSubSurface();
-#else
- unlockSurface();
-#endif
-#ifdef QT_NO_DIRECTFB_WM
- Q_ASSERT(screen->primarySurface());
- if (dfbSurface != screen->primarySurface())
-#endif
-
- dfbSurface->Release(dfbSurface);
- dfbSurface = 0;
- }
-}
-
-void QDirectFBWindowSurface::updateIsOpaque()
-{
- const QWidget *win = window();
- Q_ASSERT(win);
- if (win->testAttribute(Qt::WA_OpaquePaintEvent) || win->testAttribute(Qt::WA_PaintOnScreen)) {
- setOpaque(true);
- return;
- }
-
- if (qFuzzyCompare(static_cast<float>(win->windowOpacity()), 1.0f)) {
- const QPalette &pal = win->palette();
-
- if (win->autoFillBackground()) {
- const QBrush &autoFillBrush = pal.brush(win->backgroundRole());
- if (autoFillBrush.style() != Qt::NoBrush && autoFillBrush.isOpaque()) {
- setOpaque(true);
- return;
- }
- }
-
- if (win->isWindow() && !win->testAttribute(Qt::WA_NoSystemBackground)) {
- const QBrush &windowBrush = win->palette().brush(QPalette::Window);
- if (windowBrush.style() != Qt::NoBrush && windowBrush.isOpaque()) {
- setOpaque(true);
- return;
- }
- }
- }
- setOpaque(false);
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_QWS_DIRECTFB
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h
deleted file mode 100644
index df9baa1ff2..0000000000
--- a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDIRECFBWINDOWSURFACE_H
-#define QDIRECFBWINDOWSURFACE_H
-
-#include "qdirectfbpaintengine.h"
-#include "qdirectfbpaintdevice.h"
-#include "qdirectfbscreen.h"
-
-#ifndef QT_NO_QWS_DIRECTFB
-
-#include <private/qpaintengine_raster_p.h>
-#include <private/qwindowsurface_qws_p.h>
-
-#ifdef QT_DIRECTFB_TIMING
-#include <qdatetime.h>
-#endif
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QDirectFBWindowSurface : public QWSWindowSurface, public QDirectFBPaintDevice
-{
-public:
- QDirectFBWindowSurface(DFBSurfaceFlipFlags flipFlags, QDirectFBScreen *scr);
- QDirectFBWindowSurface(DFBSurfaceFlipFlags flipFlags, QDirectFBScreen *scr, QWidget *widget);
- ~QDirectFBWindowSurface();
-
-#ifdef QT_DIRECTFB_WM
- void raise();
-#endif
- bool isValid() const;
-
- void setGeometry(const QRect &rect);
-
- QString key() const { return QLatin1String("directfb"); }
- QByteArray permanentState() const;
- void setPermanentState(const QByteArray &state);
-
- bool scroll(const QRegion &area, int dx, int dy);
-
- bool move(const QPoint &offset);
-
- QImage image() const { return QImage(); }
- QPaintDevice *paintDevice() { return this; }
-
- void flush(QWidget *widget, const QRegion &region, const QPoint &offset);
-
- void beginPaint(const QRegion &);
- void endPaint(const QRegion &);
-
- IDirectFBSurface *surfaceForWidget(const QWidget *widget, QRect *rect) const;
- IDirectFBSurface *directFBSurface() const;
-#ifdef QT_DIRECTFB_WM
- IDirectFBWindow *directFBWindow() const;
-#endif
-private:
- void updateIsOpaque();
- void setOpaque(bool opaque);
- void releaseSurface();
-
-#ifdef QT_DIRECTFB_WM
- void createWindow(const QRect &rect);
- IDirectFBWindow *dfbWindow;
-#else
- enum Mode {
- Primary,
- Offscreen
- } mode;
-#endif
-
- DFBSurfaceFlipFlags flipFlags;
- bool boundingRectFlip;
- bool flushPending;
-#ifdef QT_DIRECTFB_TIMING
- int frames;
- QTime timer;
-#endif
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QT_NO_QWS_DIRECTFB
-
-#endif // QDIRECFBWINDOWSURFACE_H
diff --git a/src/plugins/gfxdrivers/eglnullws/README b/src/plugins/gfxdrivers/eglnullws/README
deleted file mode 100644
index 80b88c7e01..0000000000
--- a/src/plugins/gfxdrivers/eglnullws/README
+++ /dev/null
@@ -1,48 +0,0 @@
-EGL NullWS QScreen Driver
-=========================
-
-If your application draws everything within a single full-screen QGLWidget then
-you may wish to use this QScreen plugin driver. This driver simply returns 0
-(as a EGLNativeWindowType value) when asked by the QtOpenGl module to create a
-native window. Some OpenGL ES implementations (including PowerVR) interpret this
-to mean that a full-screen OpenGL context is desired without any windowing
-support (NullWS).
-
-To tell a Qt/Embedded application to use this driver use the -display command
-line option or the QWS_DISPLAY environment variable. The following driver
-options are supported:
-
-size=WIDTHxHEIGHT Screen size reported by the driver
-format=FORMAT Screen format
-
-Run with '-display eglnullws:help' to get a full list of options (including a
-list of supported format strings).
-
-If you choose a screen format that is not supported by the hardware then the
-QtOpenGl module will write out a list of supported EGL configurations. Use
-one of the supported screen formats from this list.
-
-Using this driver with PowerVR hardware
----------------------------------------
-
-Using this plugin with PowerVR hardware should give a significant speedup
-compared to running with the Qt powervr driver (with a full-screen QGLWidget).
-This is because sacrificing the window system allows less work to be done in
-order to get graphics on the screen. Using this driver also avoids the memory
-fragmentation issues present in the powervr driver and avoids any direct
-dependencies on the deprecated PVR2D API from Imagination Technologies.
-
-To use this driver ensure you have /etc/powervr.ini with contents similar to
-this:
-
-[default]
-WindowSystem=libpvrPVR2D_FLIPWSEGL.so
-
-This driver will also function with libpvrPVR2D_FRONTWSEGL.so, but that draws
-straight into the framebuffer and will therefore cause flickering (it can be
-useful for performance testing though). The flip plugin uses triple buffering,
-so you will need to set the virtual vertical resolution of your framebuffer to
-be three times the physical vertical resolution of your screen. This can be
-done with 'fbset -vyres'. Failure to do this can cause system crashes. You
-should also ensure that the plugin you choose in powervr.ini is in your library
-path (it may just silently default to the flip plugin if not).
diff --git a/src/plugins/gfxdrivers/eglnullws/eglnullws.pro b/src/plugins/gfxdrivers/eglnullws/eglnullws.pro
deleted file mode 100644
index cb65c2b627..0000000000
--- a/src/plugins/gfxdrivers/eglnullws/eglnullws.pro
+++ /dev/null
@@ -1,18 +0,0 @@
-TARGET = qeglnullws
-load(qt_plugin)
-
-CONFIG += warn_on
-QT += opengl
-
-DESTDIR = $$QT.gui.plugins/gfxdrivers
-
-target.path = $$[QT_INSTALL_PLUGINS]/gfxdrivers
-INSTALLS += target
-
-HEADERS = eglnullwsscreen.h \
- eglnullwsscreenplugin.h \
- eglnullwswindowsurface.h
-
-SOURCES = eglnullwsscreen.cpp \
- eglnullwsscreenplugin.cpp \
- eglnullwswindowsurface.cpp
diff --git a/src/plugins/gfxdrivers/eglnullws/eglnullwsscreen.cpp b/src/plugins/gfxdrivers/eglnullws/eglnullwsscreen.cpp
deleted file mode 100644
index e8c73cf31d..0000000000
--- a/src/plugins/gfxdrivers/eglnullws/eglnullwsscreen.cpp
+++ /dev/null
@@ -1,181 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "eglnullwsscreen.h"
-#include "eglnullwswindowsurface.h"
-#include "eglnullwsscreenplugin.h"
-
-#include <QHash>
-#include <QDebug>
-
-namespace
-{
- class EGLNullWSScreenSurfaceFunctions : public QGLScreenSurfaceFunctions
- {
- public:
- virtual bool createNativeWindow(QWidget *, EGLNativeWindowType *native)
- { *native = 0; return true; }
- };
-}
-
-EGLNullWSScreen::EGLNullWSScreen(int displayId) : QGLScreen(displayId) {}
-
-EGLNullWSScreen::~EGLNullWSScreen() {}
-
-bool EGLNullWSScreen::initDevice()
-{
- setSurfaceFunctions(new EGLNullWSScreenSurfaceFunctions);
- return true;
-}
-
-static const QHash<QString, QImage::Format> formatDictionary()
-{
- QHash<QString, QImage::Format> dictionary;
- dictionary["rgb32"] = QImage::Format_RGB32;
- dictionary["argb32"] = QImage::Format_ARGB32;
- dictionary["rgb16"] = QImage::Format_RGB16;
- dictionary["rgb666"] = QImage::Format_RGB666;
- dictionary["rgb555"] = QImage::Format_RGB555;
- dictionary["rgb888"] = QImage::Format_RGB888;
- dictionary["rgb444"] = QImage::Format_RGB444;
- return dictionary;
-}
-
-static int depthForFormat(QImage::Format format)
-{
- switch (format) {
- case QImage::Format_RGB32: return 32;
- case QImage::Format_ARGB32: return 32;
- case QImage::Format_RGB16: return 16;
- case QImage::Format_RGB666: return 24;
- case QImage::Format_RGB555: return 16;
- case QImage::Format_RGB888: return 24;
- case QImage::Format_RGB444: return 16;
- default:
- Q_ASSERT_X(false, "EGLNullWSScreen", "Unknown format");
- return -1;
- }
-}
-
-static void printHelp(const QHash<QString, QImage::Format> &formatDictionary)
-{
- QByteArray formatsBuf;
- QTextStream(&formatsBuf) << QStringList(formatDictionary.keys()).join(", ");
- qWarning(
- "%s: Valid options are:\n"
- "size=WIDTHxHEIGHT Screen size reported by this driver\n"
- "format=FORMAT Screen format, where FORMAT is one of the following:\n"
- " %s\n",
- PluginName,
- formatsBuf.constData());
-}
-
-bool EGLNullWSScreen::connect(const QString &displaySpec)
-{
- const QStringList args = displaySpec.section(':', 1).split(':', QString::SkipEmptyParts);
- const QHash<QString, QImage::Format> formatDict = formatDictionary();
- Q_FOREACH(const QString arg, args) {
- const QString optionName = arg.section('=', 0, 0);
- const QString optionArg = arg.section('=', 1);
- if (optionName == QLatin1String("size")) {
- w = optionArg.section('x', 0, 0).toInt();
- h = optionArg.section('x', 1, 1).toInt();
- } else if (optionName == QLatin1String("format")) {
- if (formatDict.contains(optionArg))
- setPixelFormat(formatDict.value(optionArg));
- else
- printHelp(formatDict);
- } else {
- printHelp(formatDict);
- }
- }
-
- if (w == 0 || h == 0) {
- w = 640;
- h = 480;
- qWarning("%s: Using default screen size %dx%d", PluginName, w, h);
- }
- dw = w;
- dh = h;
-
- if (pixelFormat() == QImage::Format_Invalid) {
- qWarning("%s: Using default screen format argb32", PluginName);
- setPixelFormat(QImage::Format_ARGB32);
- }
- d = depthForFormat(pixelFormat());
-
- static const int Dpi = 120;
- static const qreal ScalingFactor = static_cast<qreal>(25.4) / Dpi;
- physWidth = qRound(dw * ScalingFactor);
- physHeight = qRound(dh * ScalingFactor);
-
- return true;
-}
-
-void EGLNullWSScreen::disconnect() {}
-
-void EGLNullWSScreen::shutdownDevice() {}
-
-void EGLNullWSScreen::setMode(int /*width*/, int /*height*/, int /*depth*/) {}
-
-void EGLNullWSScreen::blank(bool /*on*/) {}
-
-void EGLNullWSScreen::exposeRegion(QRegion /*r*/, int /*changing*/) {}
-
-QWSWindowSurface* EGLNullWSScreen::createSurface(QWidget *widget) const
-{
- if (qobject_cast<QGLWidget*>(widget)) {
- return new EGLNullWSWindowSurface(widget);
- } else {
- qWarning("%s: Creating non-GL surface", PluginName);
- return QScreen::createSurface(widget);
- }
-}
-
-QWSWindowSurface* EGLNullWSScreen::createSurface(const QString &key) const
-{
- if (key == QLatin1String("eglnullws")) {
- return new EGLNullWSWindowSurface;
- } else {
- qWarning("%s: Creating non-GL surface", PluginName);
- return QScreen::createSurface(key);
- }
-}
diff --git a/src/plugins/gfxdrivers/eglnullws/eglnullwsscreen.h b/src/plugins/gfxdrivers/eglnullws/eglnullwsscreen.h
deleted file mode 100644
index 8295e5daaa..0000000000
--- a/src/plugins/gfxdrivers/eglnullws/eglnullwsscreen.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef EGLNULLWSSCREEN
-#define EGLNULLWSSCREEN
-
-#include <QGLScreen>
-
-class EGLNullWSScreen : public QGLScreen
-{
-public:
- EGLNullWSScreen(int displayId);
- ~EGLNullWSScreen();
-
- bool initDevice();
- bool connect(const QString &displaySpec);
- void disconnect();
- void shutdownDevice();
-
- void setMode(int width, int height, int depth);
- void blank(bool on);
-
- void exposeRegion(QRegion r, int changing);
-
- QWSWindowSurface* createSurface(QWidget *widget) const;
- QWSWindowSurface* createSurface(const QString &key) const;
-
- bool hasOpenGL() { return true; }
-};
-
-#endif // EGLNULLWSSCREEN
diff --git a/src/plugins/gfxdrivers/eglnullws/eglnullwsscreenplugin.cpp b/src/plugins/gfxdrivers/eglnullws/eglnullwsscreenplugin.cpp
deleted file mode 100644
index ebae53d8c4..0000000000
--- a/src/plugins/gfxdrivers/eglnullws/eglnullwsscreenplugin.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "eglnullwsscreenplugin.h"
-#include "eglnullwsscreen.h"
-
-#include <QScreenDriverPlugin>
-#include <QStringList>
-
-class EGLNullWSScreenPlugin : public QScreenDriverPlugin
-{
-public:
- virtual QStringList keys() const;
- virtual QScreen *create(const QString& driver, int displayId);
-};
-
-QStringList EGLNullWSScreenPlugin::keys() const
-{
- return QStringList() << QLatin1String(PluginName);
-}
-
-QScreen *EGLNullWSScreenPlugin::create(const QString& driver, int displayId)
-{
- return (driver.toLower() == QLatin1String(PluginName) ?
- new EGLNullWSScreen(displayId) : 0);
-}
-
-Q_EXPORT_PLUGIN2(qeglnullws, EGLNullWSScreenPlugin)
diff --git a/src/plugins/gfxdrivers/eglnullws/eglnullwsscreenplugin.h b/src/plugins/gfxdrivers/eglnullws/eglnullwsscreenplugin.h
deleted file mode 100644
index c0e5c2a524..0000000000
--- a/src/plugins/gfxdrivers/eglnullws/eglnullwsscreenplugin.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef EGLNULLWSSCREENPLUGIN_H
-#define EGLNULLWSSCREENPLUGIN_H
-
-const char *const PluginName = "eglnullws";
-
-#endif // EGLNULLWSSCREENPLUGIN_H
diff --git a/src/plugins/gfxdrivers/eglnullws/eglnullwswindowsurface.cpp b/src/plugins/gfxdrivers/eglnullws/eglnullwswindowsurface.cpp
deleted file mode 100644
index e5ac994a05..0000000000
--- a/src/plugins/gfxdrivers/eglnullws/eglnullwswindowsurface.cpp
+++ /dev/null
@@ -1,84 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "eglnullwswindowsurface.h"
-#include "eglnullwsscreenplugin.h"
-
-#include <QGLWidget>
-
-static const QWSWindowSurface::SurfaceFlags Flags
- = QWSWindowSurface::RegionReserved | QWSWindowSurface::RegionReserved;
-
-EGLNullWSWindowSurface::EGLNullWSWindowSurface(QWidget *w)
- :
- QWSGLWindowSurface(w),
- widget(w)
-{
- setSurfaceFlags(Flags);
-}
-
-EGLNullWSWindowSurface::EGLNullWSWindowSurface()
- : widget(0)
-{
- setSurfaceFlags(Flags);
-}
-
-EGLNullWSWindowSurface::~EGLNullWSWindowSurface() {}
-
-QString EGLNullWSWindowSurface::key() const
-{
- return QLatin1String(PluginName);
-}
-
-QPaintDevice *EGLNullWSWindowSurface::paintDevice()
-{
- return widget;
-}
-
-bool EGLNullWSWindowSurface::isValid() const
-{
- return qobject_cast<QGLWidget *>(window());
-}
-
-QImage EGLNullWSWindowSurface::image() const
-{
- return QImage();
-}
diff --git a/src/plugins/gfxdrivers/eglnullws/eglnullwswindowsurface.h b/src/plugins/gfxdrivers/eglnullws/eglnullwswindowsurface.h
deleted file mode 100644
index bdb1d42d7e..0000000000
--- a/src/plugins/gfxdrivers/eglnullws/eglnullwswindowsurface.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef EGLNULLWSWINDOWSURFACE_H
-#define EGLNULLWSWINDOWSURFACE_H
-
-#include <private/qglwindowsurface_qws_p.h>
-
-class EGLNullWSWindowSurface : public QWSGLWindowSurface
-{
-public:
- EGLNullWSWindowSurface(QWidget *widget);
- EGLNullWSWindowSurface();
- virtual ~EGLNullWSWindowSurface();
-
- virtual QString key() const;
- virtual QPaintDevice *paintDevice();
- virtual bool isValid() const;
- virtual QImage image() const;
-
-private:
- QWidget *widget;
-};
-
-#endif // EGLNULLWSWINDOWSURFACE_H
diff --git a/src/plugins/gfxdrivers/gfxdrivers.pro b/src/plugins/gfxdrivers/gfxdrivers.pro
deleted file mode 100644
index 1f38942a50..0000000000
--- a/src/plugins/gfxdrivers/gfxdrivers.pro
+++ /dev/null
@@ -1,10 +0,0 @@
-TEMPLATE = subdirs
-contains(gfx-plugins, ahi) :SUBDIRS += ahi
-contains(gfx-plugins, directfb) :SUBDIRS += directfb
-contains(gfx-plugins, linuxfb) :SUBDIRS += linuxfb
-contains(gfx-plugins, qvfb) :SUBDIRS += qvfb
-contains(gfx-plugins, vnc) :SUBDIRS += vnc
-contains(gfx-plugins, transformed) :SUBDIRS += transformed
-contains(gfx-plugins, svgalib) :SUBDIRS += svgalib
-contains(gfx-plugins, powervr) :SUBDIRS += powervr
-contains(gfx-plugins, eglnullws) :SUBDIRS += eglnullws
diff --git a/src/plugins/gfxdrivers/linuxfb/linuxfb.pro b/src/plugins/gfxdrivers/linuxfb/linuxfb.pro
deleted file mode 100644
index 2bbe910e63..0000000000
--- a/src/plugins/gfxdrivers/linuxfb/linuxfb.pro
+++ /dev/null
@@ -1,14 +0,0 @@
-TARGET = qscreenlinuxfb
-load(qt_plugin)
-
-DESTDIR = $$QT.gui.plugins/gfxdrivers
-
-target.path = $$[QT_INSTALL_PLUGINS]/gfxdrivers
-INSTALLS += target
-
-DEFINES += QT_QWS_LINUXFB
-
-HEADERS = $$QT_SOURCE_TREE/src/gui/embedded/qscreenlinuxfb_qws.h
-
-SOURCES = main.cpp \
- $$QT_SOURCE_TREE/src/gui/embedded/qscreenlinuxfb_qws.cpp
diff --git a/src/plugins/gfxdrivers/linuxfb/main.cpp b/src/plugins/gfxdrivers/linuxfb/main.cpp
deleted file mode 100644
index 187237f042..0000000000
--- a/src/plugins/gfxdrivers/linuxfb/main.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qscreendriverplugin_qws.h>
-#include <qscreenlinuxfb_qws.h>
-#include <qstringlist.h>
-
-QT_BEGIN_NAMESPACE
-
-class QScreenLinuxFbPlugin : public QScreenDriverPlugin
-{
-public:
- QScreenLinuxFbPlugin();
-
- QStringList keys() const;
- QScreen *create(const QString&, int displayId);
-};
-
-QScreenLinuxFbPlugin::QScreenLinuxFbPlugin()
- : QScreenDriverPlugin()
-{
-}
-
-QStringList QScreenLinuxFbPlugin::keys() const
-{
- QStringList list;
- list << QLatin1String("LinuxFb");
- return list;
-}
-
-QScreen* QScreenLinuxFbPlugin::create(const QString& driver, int displayId)
-{
- if (driver.toLower() == QLatin1String("linuxfb"))
- return new QLinuxFbScreen(displayId);
-
- return 0;
-}
-
-Q_EXPORT_PLUGIN2(qscreenlinuxfb, QScreenLinuxFbPlugin)
-
-QT_END_NAMESPACE
diff --git a/src/plugins/gfxdrivers/powervr/QWSWSEGL/QWSWSEGL.pro b/src/plugins/gfxdrivers/powervr/QWSWSEGL/QWSWSEGL.pro
deleted file mode 100644
index 595cf45301..0000000000
--- a/src/plugins/gfxdrivers/powervr/QWSWSEGL/QWSWSEGL.pro
+++ /dev/null
@@ -1,26 +0,0 @@
-TEMPLATE = lib
-TARGET = pvrQWSWSEGL
-CONFIG += dll warn_on
-CONFIG -= qt
-
-HEADERS+=\
- pvrqwsdrawable.h \
- pvrqwsdrawable_p.h
-
-SOURCES+=\
- pvrqwsdrawable.c \
- pvrqwswsegl.c
-
-INCLUDEPATH += $$QMAKE_INCDIR_EGL
-
-for(p, QMAKE_LIBDIR_EGL) {
- exists($$p):LIBS += -L$$p
-}
-
-LIBS += -lpvr2d
-
-DESTDIR = $$QMAKE_LIBDIR_QT
-target.path = $$[QT_INSTALL_LIBS]
-INSTALLS += target
-
-include(../powervr.pri) \ No newline at end of file
diff --git a/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable.c b/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable.c
deleted file mode 100644
index c453279155..0000000000
--- a/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable.c
+++ /dev/null
@@ -1,830 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "pvrqwsdrawable_p.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/mman.h>
-#include <sys/ioctl.h>
-#include <linux/fb.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-PvrQwsDisplay pvrQwsDisplay;
-
-static void pvrQwsDestroyDrawableForced(PvrQwsDrawable *drawable);
-
-/* Initialize the /dev/fbN device for a specific screen */
-static int pvrQwsInitFbScreen(int screen)
-{
- struct fb_var_screeninfo var;
- struct fb_fix_screeninfo fix;
- unsigned long start;
- unsigned long length;
- int width, height, stride;
- PVR2DFORMAT format;
- void *mapped;
- int fd, bytesPerPixel;
- char name[64];
- PVR2DMEMINFO *memInfo;
- unsigned long pageAddresses[2];
-
- /* Bail out if already initialized, or the number is incorrect */
- if (screen < 0 || screen >= PVRQWS_MAX_SCREENS)
- return 0;
- if (pvrQwsDisplay.screens[screen].initialized)
- return 1;
-
- /* Open the framebuffer and fetch its properties */
- sprintf(name, "/dev/fb%d", screen);
- fd = open(name, O_RDWR, 0);
- if (fd < 0) {
- perror(name);
- return 0;
- }
- if (ioctl(fd, FBIOGET_VSCREENINFO, &var) < 0) {
- perror("FBIOGET_VSCREENINFO");
- close(fd);
- return 0;
- }
- if (ioctl(fd, FBIOGET_FSCREENINFO, &fix) < 0) {
- perror("FBIOGET_FSCREENINFO");
- close(fd);
- return 0;
- }
- width = var.xres;
- height = var.yres;
- bytesPerPixel = var.bits_per_pixel / 8;
- stride = fix.line_length;
- format = PVR2D_1BPP;
- if (var.bits_per_pixel == 16) {
- if (var.red.length == 5 && var.green.length == 6 &&
- var.blue.length == 5 && var.red.offset == 11 &&
- var.green.offset == 5 && var.blue.offset == 0) {
- format = PVR2D_RGB565;
- }
- if (var.red.length == 4 && var.green.length == 4 &&
- var.blue.length == 4 && var.transp.length == 4 &&
- var.red.offset == 8 && var.green.offset == 4 &&
- var.blue.offset == 0 && var.transp.offset == 12) {
- format = PVR2D_ARGB4444;
- }
- } else if (var.bits_per_pixel == 32) {
- if (var.red.length == 8 && var.green.length == 8 &&
- var.blue.length == 8 && var.transp.length == 8 &&
- var.red.offset == 16 && var.green.offset == 8 &&
- var.blue.offset == 0 && var.transp.offset == 24) {
- format = PVR2D_ARGB8888;
- }
- }
- if (format == PVR2D_1BPP) {
- fprintf(stderr, "%s: could not find a suitable PVR2D pixel format\n", name);
- close(fd);
- return 0;
- }
- start = fix.smem_start;
- length = var.xres_virtual * var.yres_virtual * bytesPerPixel;
-
- if (screen == 0) {
- /* We use PVR2DGetFrameBuffer to map the first screen.
- On some chipsets it is more reliable than using PVR2DMemWrap */
- mapped = 0;
- memInfo = 0;
- } else {
- /* Other screens: map the framebuffer region into memory */
- mapped = mmap(0, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
- if (!mapped || mapped == (void *)(-1)) {
- perror("mmap");
- close(fd);
- return 0;
- }
-
- /* Allocate a PVR2D memory region for the framebuffer */
- memInfo = 0;
- if (pvrQwsDisplay.context) {
- pageAddresses[0] = start & 0xFFFFF000;
- pageAddresses[1] = 0;
- if (PVR2DMemWrap
- (pvrQwsDisplay.context, mapped, PVR2D_WRAPFLAG_CONTIGUOUS,
- length, pageAddresses, &memInfo) != PVR2D_OK) {
- munmap(mapped, length);
- close(fd);
- return 0;
- }
- }
- }
-
- /* We don't need the file descriptor any more */
- close(fd);
-
- /* The framebuffer is ready, so initialize the PvrQwsScreenInfo */
- pvrQwsDisplay.screens[screen].screenRect.x = 0;
- pvrQwsDisplay.screens[screen].screenRect.y = 0;
- pvrQwsDisplay.screens[screen].screenRect.width = width;
- pvrQwsDisplay.screens[screen].screenRect.height = height;
- pvrQwsDisplay.screens[screen].screenStride = stride;
- pvrQwsDisplay.screens[screen].pixelFormat = format;
- pvrQwsDisplay.screens[screen].bytesPerPixel = bytesPerPixel;
- pvrQwsDisplay.screens[screen].screenDrawable = 0;
- if (mapped) {
- /* Don't set these fields if mapped is 0, because PVR2DGetFrameBuffer
- may have already been called and set them */
- pvrQwsDisplay.screens[screen].frameBuffer = memInfo;
- pvrQwsDisplay.screens[screen].mapped = mapped;
- }
- pvrQwsDisplay.screens[screen].mappedLength = length;
- pvrQwsDisplay.screens[screen].screenStart = start;
- pvrQwsDisplay.screens[screen].needsUnmap = (mapped != 0);
- pvrQwsDisplay.screens[screen].initialized = 1;
- return 1;
-}
-
-/* Called when a new drawable is added to ensure that we have a
- PVR2D context and framebuffer PVR2DMEMINFO blocks */
-static int pvrQwsAddDrawable(void)
-{
- int numDevs, screen;
- PVR2DDEVICEINFO *devs;
- unsigned long devId;
- unsigned long pageAddresses[2];
- PVR2DMEMINFO *memInfo;
- PVR2DDISPLAYINFO displayInfo;
-
- /* Bail out early if this is not the first drawable */
- if (pvrQwsDisplay.numDrawables > 0) {
- ++(pvrQwsDisplay.numDrawables);
- return 1;
- }
-
- /* Find the first PVR2D device in the system and open it */
- numDevs = PVR2DEnumerateDevices(0);
- if (numDevs <= 0)
- return 0;
- devs = (PVR2DDEVICEINFO *)malloc(sizeof(PVR2DDEVICEINFO) * numDevs);
- if (!devs)
- return 0;
- if (PVR2DEnumerateDevices(devs) != PVR2D_OK) {
- free(devs);
- return 0;
- }
- devId = devs[0].ulDevID;
- free(devs);
- if (PVR2DCreateDeviceContext(devId, &pvrQwsDisplay.context, 0) != PVR2D_OK)
- return 0;
- pvrQwsDisplay.numFlipBuffers = 0;
- pvrQwsDisplay.flipChain = 0;
- if (PVR2DGetDeviceInfo(pvrQwsDisplay.context, &displayInfo) == PVR2D_OK) {
- if (displayInfo.ulMaxFlipChains > 0 && displayInfo.ulMaxBuffersInChain > 0)
- pvrQwsDisplay.numFlipBuffers = displayInfo.ulMaxBuffersInChain;
- if (pvrQwsDisplay.numFlipBuffers > PVRQWS_MAX_FLIP_BUFFERS)
- pvrQwsDisplay.numFlipBuffers = PVRQWS_MAX_FLIP_BUFFERS;
- }
-
- /* Create the PVR2DMEMINFO blocks for the active framebuffers */
- for (screen = 0; screen < PVRQWS_MAX_SCREENS; ++screen) {
- if (screen != 0 && pvrQwsDisplay.screens[screen].mapped) {
- pageAddresses[0]
- = pvrQwsDisplay.screens[screen].screenStart & 0xFFFFF000;
- pageAddresses[1] = 0;
- if (PVR2DMemWrap
- (pvrQwsDisplay.context,
- pvrQwsDisplay.screens[screen].mapped,
- PVR2D_WRAPFLAG_CONTIGUOUS,
- pvrQwsDisplay.screens[screen].mappedLength,
- pageAddresses, &memInfo) != PVR2D_OK) {
- PVR2DDestroyDeviceContext(pvrQwsDisplay.context);
- pvrQwsDisplay.context = 0;
- return 0;
- }
- pvrQwsDisplay.screens[screen].frameBuffer = memInfo;
- } else if (screen == 0) {
- if (PVR2DGetFrameBuffer
- (pvrQwsDisplay.context,
- PVR2D_FB_PRIMARY_SURFACE, &memInfo) != PVR2D_OK) {
- fprintf(stderr, "QWSWSEGL: could not get the primary framebuffer surface\n");
- PVR2DDestroyDeviceContext(pvrQwsDisplay.context);
- pvrQwsDisplay.context = 0;
- return 0;
- }
- pvrQwsDisplay.screens[screen].frameBuffer = memInfo;
- pvrQwsDisplay.screens[screen].mapped = memInfo->pBase;
- }
- }
-
- /* Create a flip chain for the screen if supported by the hardware */
- pvrQwsDisplay.usePresentBlit = 0;
- if (pvrQwsDisplay.numFlipBuffers > 0) {
- long stride = 0;
- unsigned long flipId = 0;
- unsigned long numBuffers;
- if (PVR2DCreateFlipChain(pvrQwsDisplay.context, 0,
- //PVR2D_CREATE_FLIPCHAIN_SHARED |
- //PVR2D_CREATE_FLIPCHAIN_QUERY,
- pvrQwsDisplay.numFlipBuffers,
- pvrQwsDisplay.screens[0].screenRect.width,
- pvrQwsDisplay.screens[0].screenRect.height,
- pvrQwsDisplay.screens[0].pixelFormat,
- &stride, &flipId, &(pvrQwsDisplay.flipChain))
- == PVR2D_OK) {
- pvrQwsDisplay.screens[0].screenStride = stride;
- PVR2DGetFlipChainBuffers(pvrQwsDisplay.context,
- pvrQwsDisplay.flipChain,
- &numBuffers,
- pvrQwsDisplay.flipBuffers);
- } else {
- pvrQwsDisplay.flipChain = 0;
- pvrQwsDisplay.numFlipBuffers = 0;
- }
-
- /* PVR2DPresentBlt is a little more reliable than PVR2DBlt
- when flip chains are present, even if we cannot create a
- flip chain at the moment */
- pvrQwsDisplay.usePresentBlit = 1;
- }
-
- /* The context is ready to go */
- ++(pvrQwsDisplay.numDrawables);
- return 1;
-}
-
-/* Called when the last drawable is destroyed. The PVR2D context
- will be destroyed but the raw framebuffer memory will stay mapped */
-static void pvrQwsDestroyContext(void)
-{
- int screen;
- for (screen = 0; screen < PVRQWS_MAX_SCREENS; ++screen) {
- if (pvrQwsDisplay.screens[screen].frameBuffer) {
- PVR2DMemFree
- (pvrQwsDisplay.context,
- pvrQwsDisplay.screens[screen].frameBuffer);
- pvrQwsDisplay.screens[screen].frameBuffer = 0;
- }
- }
-
- if (pvrQwsDisplay.numFlipBuffers > 0)
- PVR2DDestroyFlipChain(pvrQwsDisplay.context, pvrQwsDisplay.flipChain);
- PVR2DDestroyDeviceContext(pvrQwsDisplay.context);
- pvrQwsDisplay.context = 0;
- pvrQwsDisplay.flipChain = 0;
- pvrQwsDisplay.numFlipBuffers = 0;
- pvrQwsDisplay.usePresentBlit = 0;
-}
-
-int pvrQwsDisplayOpen(void)
-{
- int screen;
-
- /* If the display is already open, increase reference count and return */
- if (pvrQwsDisplay.refCount > 0) {
- ++(pvrQwsDisplay.refCount);
- return 1;
- }
-
- /* Open the framebuffer and map it directly */
- if (!pvrQwsInitFbScreen(0)) {
- --(pvrQwsDisplay.refCount);
- return 0;
- }
-
- /* Clear the other screens. We will create them if they are referenced */
- for (screen = 1; screen < PVRQWS_MAX_SCREENS; ++screen)
- memset(&(pvrQwsDisplay.screens[screen]), 0, sizeof(PvrQwsScreenInfo));
-
- /* The display is open and ready */
- ++(pvrQwsDisplay.refCount);
- return 1;
-}
-
-void pvrQwsDisplayClose(void)
-{
- int screen;
-
- if (pvrQwsDisplay.refCount == 0)
- return;
- if (--(pvrQwsDisplay.refCount) > 0)
- return;
-
- /* Prevent pvrQwsDestroyContext from being called for the time being */
- ++pvrQwsDisplay.numDrawables;
-
- /* Free the screens */
- for (screen = 0; screen < PVRQWS_MAX_SCREENS; ++screen) {
- PvrQwsScreenInfo *info = &(pvrQwsDisplay.screens[screen]);
- if (info->screenDrawable)
- pvrQwsDestroyDrawableForced(info->screenDrawable);
- if (info->frameBuffer)
- PVR2DMemFree(pvrQwsDisplay.context, info->frameBuffer);
- if (info->mapped && info->needsUnmap)
- munmap(info->mapped, info->mappedLength);
- }
-
- /* Now it is safe to destroy the PVR2D context */
- --pvrQwsDisplay.numDrawables;
- if (pvrQwsDisplay.context)
- PVR2DDestroyDeviceContext(pvrQwsDisplay.context);
-
- memset(&pvrQwsDisplay, 0, sizeof(pvrQwsDisplay));
-}
-
-int pvrQwsDisplayIsOpen(void)
-{
- return (pvrQwsDisplay.refCount > 0);
-}
-
-/* Ensure that a specific screen has been initialized */
-static int pvrQwsEnsureScreen(int screen)
-{
- if (screen < 0 || screen >= PVRQWS_MAX_SCREENS)
- return 0;
- if (!screen)
- return 1;
- return pvrQwsInitFbScreen(screen);
-}
-
-PvrQwsDrawable *pvrQwsScreenWindow(int screen)
-{
- PvrQwsDrawable *drawable;
-
- if (!pvrQwsEnsureScreen(screen))
- return 0;
-
- drawable = pvrQwsDisplay.screens[screen].screenDrawable;
- if (drawable)
- return drawable;
-
- drawable = (PvrQwsDrawable *)calloc(1, sizeof(PvrQwsDrawable));
- if (!drawable)
- return 0;
-
- drawable->type = PvrQwsScreen;
- drawable->screen = screen;
- drawable->pixelFormat = pvrQwsDisplay.screens[screen].pixelFormat;
- drawable->rect = pvrQwsDisplay.screens[screen].screenRect;
- drawable->visibleRects[0] = drawable->rect;
- drawable->numVisibleRects = 1;
- drawable->isFullScreen = 1;
-
- if (!pvrQwsAddDrawable()) {
- free(drawable);
- return 0;
- }
-
- pvrQwsDisplay.screens[screen].screenDrawable = drawable;
-
- return drawable;
-}
-
-PvrQwsDrawable *pvrQwsCreateWindow(int screen, long winId, const PvrQwsRect *rect)
-{
- PvrQwsDrawable *drawable;
-
- if (!pvrQwsEnsureScreen(screen))
- return 0;
-
- drawable = (PvrQwsDrawable *)calloc(1, sizeof(PvrQwsDrawable));
- if (!drawable)
- return 0;
-
- drawable->type = PvrQwsWindow;
- drawable->winId = winId;
- drawable->refCount = 1;
- drawable->screen = screen;
- drawable->pixelFormat = pvrQwsDisplay.screens[screen].pixelFormat;
- drawable->rect = *rect;
-
- if (!pvrQwsAddDrawable()) {
- free(drawable);
- return 0;
- }
-
- drawable->nextWinId = pvrQwsDisplay.firstWinId;
- pvrQwsDisplay.firstWinId = drawable;
-
- return drawable;
-}
-
-PvrQwsDrawable *pvrQwsFetchWindow(long winId)
-{
- PvrQwsDrawable *drawable = pvrQwsDisplay.firstWinId;
- while (drawable != 0 && drawable->winId != winId)
- drawable = drawable->nextWinId;
-
- if (drawable)
- ++(drawable->refCount);
- return drawable;
-}
-
-int pvrQwsReleaseWindow(PvrQwsDrawable *drawable)
-{
- if (drawable->type == PvrQwsWindow)
- return (--(drawable->refCount) <= 0);
- else
- return 0;
-}
-
-PvrQwsDrawable *pvrQwsCreatePixmap(int width, int height, int screen)
-{
- PvrQwsDrawable *drawable;
-
- if (!pvrQwsEnsureScreen(screen))
- return 0;
-
- drawable = (PvrQwsDrawable *)calloc(1, sizeof(PvrQwsDrawable));
- if (!drawable)
- return 0;
-
- drawable->type = PvrQwsPixmap;
- drawable->screen = screen;
- drawable->pixelFormat = pvrQwsDisplay.screens[screen].pixelFormat;
- drawable->rect.x = 0;
- drawable->rect.y = 0;
- drawable->rect.width = width;
- drawable->rect.height = height;
-
- if (!pvrQwsAddDrawable()) {
- free(drawable);
- return 0;
- }
-
- return drawable;
-}
-
-static void pvrQwsDestroyDrawableForced(PvrQwsDrawable *drawable)
-{
- /* Remove the drawable from the display's winId list */
- PvrQwsDrawable *current = pvrQwsDisplay.firstWinId;
- PvrQwsDrawable *prev = 0;
- while (current != 0 && current != drawable) {
- prev = current;
- current = current->nextWinId;
- }
- if (current != 0) {
- if (prev)
- prev->nextWinId = current->nextWinId;
- else
- pvrQwsDisplay.firstWinId = current->nextWinId;
- }
-
- pvrQwsFreeBuffers(drawable);
- free(drawable);
-
- --pvrQwsDisplay.numDrawables;
- if (pvrQwsDisplay.numDrawables == 0)
- pvrQwsDestroyContext();
-}
-
-void pvrQwsDestroyDrawable(PvrQwsDrawable *drawable)
-{
- if (drawable && drawable->type != PvrQwsScreen)
- pvrQwsDestroyDrawableForced(drawable);
-}
-
-PvrQwsDrawableType pvrQwsGetDrawableType(PvrQwsDrawable *drawable)
-{
- return drawable->type;
-}
-
-void pvrQwsSetVisibleRegion
- (PvrQwsDrawable *drawable, const PvrQwsRect *rects, int numRects)
-{
- int index, indexOut;
- PvrQwsRect *rect;
- PvrQwsRect *screenRect;
-
- /* Visible regions don't make sense for pixmaps */
- if (drawable->type == PvrQwsPixmap)
- return;
-
- /* Restrict the number of rectangles to prevent buffer overflow */
- if (numRects > PVRQWS_MAX_VISIBLE_RECTS)
- numRects = PVRQWS_MAX_VISIBLE_RECTS;
- if (numRects > 0)
- memcpy(drawable->visibleRects, rects, numRects * sizeof(PvrQwsRect));
-
- /* Convert the rectangles into screen-relative co-ordinates and
- then clamp them to the screen boundaries. If any of the
- clamped rectangles are empty, remove them from the list */
- screenRect = &(pvrQwsDisplay.screens[drawable->screen].screenRect);
- indexOut = 0;
- for (index = 0, rect = drawable->visibleRects; index < numRects; ++index, ++rect) {
- if (rect->x < 0) {
- rect->width += rect->x;
- rect->x = 0;
- if (rect->width < 0)
- rect->width = 0;
- } else if (rect->x >= screenRect->width) {
- rect->x = screenRect->width;
- rect->width = 0;
- }
- if ((rect->x + rect->width) > screenRect->width) {
- rect->width = screenRect->width - rect->x;
- }
- if (rect->y < 0) {
- rect->height += rect->y;
- rect->y = 0;
- if (rect->height < 0)
- rect->height = 0;
- } else if (rect->y >= screenRect->height) {
- rect->y = screenRect->height;
- rect->height = 0;
- }
- if ((rect->y + rect->height) > screenRect->height) {
- rect->height = screenRect->height - rect->y;
- }
- if (rect->width > 0 && rect->height > 0) {
- if (index != indexOut)
- drawable->visibleRects[indexOut] = *rect;
- ++indexOut;
- }
- }
- drawable->numVisibleRects = indexOut;
-}
-
-void pvrQwsClearVisibleRegion(PvrQwsDrawable *drawable)
-{
- if (drawable->type != PvrQwsPixmap)
- drawable->numVisibleRects = 0;
-}
-
-void pvrQwsSetGeometry(PvrQwsDrawable *drawable, const PvrQwsRect *rect)
-{
- /* We can only change the geometry of window drawables */
- if (drawable->type != PvrQwsWindow)
- return;
-
- /* If the position has changed, then clear the visible region */
- if (drawable->rect.x != rect->x || drawable->rect.y != rect->y) {
- drawable->rect.x = rect->x;
- drawable->rect.y = rect->y;
- drawable->numVisibleRects = 0;
- }
-
- /* If the size has changed, then clear the visible region and
- invalidate the drawable's buffers. Invalidating the buffers
- will force EGL to recreate the drawable, which will then
- allocate new buffers for the new size */
- if (drawable->rect.width != rect->width ||
- drawable->rect.height != rect->height) {
- drawable->rect.width = rect->width;
- drawable->rect.height = rect->height;
- drawable->numVisibleRects = 0;
- pvrQwsInvalidateBuffers(drawable);
- }
-}
-
-void pvrQwsGetGeometry(PvrQwsDrawable *drawable, PvrQwsRect *rect)
-{
- *rect = drawable->rect;
-}
-
-void pvrQwsSetRotation(PvrQwsDrawable *drawable, int angle)
-{
- if (drawable->rotationAngle != angle) {
- drawable->rotationAngle = angle;
-
- /* Force the buffers to be recreated if the rotation angle changes */
- pvrQwsInvalidateBuffers(drawable);
- }
-}
-
-int pvrQwsGetStride(PvrQwsDrawable *drawable)
-{
- if (drawable->backBuffersValid)
- return drawable->strideBytes;
- else
- return 0;
-}
-
-PvrQwsPixelFormat pvrQwsGetPixelFormat(PvrQwsDrawable *drawable)
-{
- return (PvrQwsPixelFormat)(drawable->pixelFormat);
-}
-
-void *pvrQwsGetRenderBuffer(PvrQwsDrawable *drawable)
-{
- if (drawable->backBuffersValid)
- return drawable->backBuffers[drawable->currentBackBuffer]->pBase;
- else
- return 0;
-}
-
-int pvrQwsAllocBuffers(PvrQwsDrawable *drawable)
-{
- int index;
- int numBuffers = PVRQWS_MAX_BACK_BUFFERS;
- if (drawable->type == PvrQwsPixmap)
- numBuffers = 1;
- if (drawable->backBuffers[0]) {
- if (drawable->backBuffersValid)
- return 1;
- if (!drawable->usingFlipBuffers) {
- for (index = 0; index < numBuffers; ++index)
- PVR2DMemFree(pvrQwsDisplay.context, drawable->backBuffers[index]);
- }
- }
- drawable->stridePixels = (drawable->rect.width + 31) & ~31;
- drawable->strideBytes =
- drawable->stridePixels *
- pvrQwsDisplay.screens[drawable->screen].bytesPerPixel;
- drawable->usingFlipBuffers =
- (pvrQwsDisplay.numFlipBuffers > 0 && drawable->isFullScreen);
- if (drawable->usingFlipBuffers) {
- if (numBuffers > (int)(pvrQwsDisplay.numFlipBuffers))
- numBuffers = pvrQwsDisplay.numFlipBuffers;
- for (index = 0; index < numBuffers; ++index)
- drawable->backBuffers[index] = pvrQwsDisplay.flipBuffers[index];
- } else {
- for (index = 0; index < numBuffers; ++index) {
- if (PVR2DMemAlloc(pvrQwsDisplay.context,
- drawable->strideBytes * drawable->rect.height,
- 128, 0,
- &(drawable->backBuffers[index])) != PVR2D_OK) {
- while (--index >= 0)
- PVR2DMemFree(pvrQwsDisplay.context, drawable->backBuffers[index]);
- memset(drawable->backBuffers, 0, sizeof(drawable->backBuffers));
- drawable->backBuffersValid = 0;
- return 0;
- }
- }
- }
- for (index = numBuffers; index < PVRQWS_MAX_BACK_BUFFERS; ++index) {
- drawable->backBuffers[index] = drawable->backBuffers[0];
- }
- drawable->backBuffersValid = 1;
- drawable->currentBackBuffer = 0;
- return 1;
-}
-
-void pvrQwsFreeBuffers(PvrQwsDrawable *drawable)
-{
- int index;
- int numBuffers = PVRQWS_MAX_BACK_BUFFERS;
- if (drawable->type == PvrQwsPixmap)
- numBuffers = 1;
- if (!drawable->usingFlipBuffers) {
- for (index = 0; index < numBuffers; ++index) {
- if (drawable->backBuffers[index])
- PVR2DMemFree(pvrQwsDisplay.context, drawable->backBuffers[index]);
- }
- }
- memset(drawable->backBuffers, 0, sizeof(drawable->backBuffers));
- drawable->backBuffersValid = 0;
- drawable->usingFlipBuffers = 0;
-}
-
-void pvrQwsInvalidateBuffers(PvrQwsDrawable *drawable)
-{
- drawable->backBuffersValid = 0;
-}
-
-int pvrQwsGetBuffers
- (PvrQwsDrawable *drawable, PVR2DMEMINFO **source, PVR2DMEMINFO **render)
-{
- if (!drawable->backBuffersValid)
- return 0;
- *render = drawable->backBuffers[drawable->currentBackBuffer];
- *source = drawable->backBuffers
- [(drawable->currentBackBuffer + PVRQWS_MAX_BACK_BUFFERS - 1) %
- PVRQWS_MAX_BACK_BUFFERS];
- return 1;
-}
-
-int pvrQwsSwapBuffers(PvrQwsDrawable *drawable, int repaintOnly)
-{
- PVR2DMEMINFO *buffer;
- PvrQwsRect *rect;
- int index;
-
- /* Bail out if the back buffers have been invalidated */
- if (!drawable->backBuffersValid)
- return 0;
-
- /* If there is a swap function, then use that instead */
- if (drawable->swapFunction) {
- (*(drawable->swapFunction))(drawable, drawable->userData, repaintOnly);
- if (!repaintOnly) {
- drawable->currentBackBuffer
- = (drawable->currentBackBuffer + 1) % PVRQWS_MAX_BACK_BUFFERS;
- }
- return 1;
- }
-
- /* Iterate through the visible rectangles and blit them to the screen */
- if (!repaintOnly) {
- index = drawable->currentBackBuffer;
- } else {
- index = (drawable->currentBackBuffer + PVRQWS_MAX_BACK_BUFFERS - 1)
- % PVRQWS_MAX_BACK_BUFFERS;
- }
- buffer = drawable->backBuffers[index];
- rect = drawable->visibleRects;
- if (drawable->usingFlipBuffers) {
- PVR2DPresentFlip(pvrQwsDisplay.context, pvrQwsDisplay.flipChain, buffer, 0);
- } else if (pvrQwsDisplay.usePresentBlit && drawable->numVisibleRects > 0) {
- PVR2DRECT pvrRects[PVRQWS_MAX_VISIBLE_RECTS];
- for (index = 0; index < drawable->numVisibleRects; ++index, ++rect) {
- pvrRects[index].left = rect->x;
- pvrRects[index].top = rect->y;
- pvrRects[index].right = rect->x + rect->width;
- pvrRects[index].bottom = rect->y + rect->height;
- }
- for (index = 0; index < drawable->numVisibleRects; index += 4) {
- int numClip = drawable->numVisibleRects - index;
- if (numClip > 4) /* No more than 4 clip rects at a time */
- numClip = 4;
- PVR2DSetPresentBltProperties
- (pvrQwsDisplay.context,
- PVR2D_PRESENT_PROPERTY_SRCSTRIDE |
- PVR2D_PRESENT_PROPERTY_DSTSIZE |
- PVR2D_PRESENT_PROPERTY_DSTPOS |
- PVR2D_PRESENT_PROPERTY_CLIPRECTS,
- drawable->strideBytes,
- drawable->rect.width, drawable->rect.height,
- drawable->rect.x, drawable->rect.y,
- numClip, pvrRects + index, 0);
- PVR2DPresentBlt(pvrQwsDisplay.context, buffer, 0);
- }
- PVR2DQueryBlitsComplete(pvrQwsDisplay.context, buffer, 1);
- } else {
- /* TODO: use PVR2DBltClipped for faster transfers of clipped windows */
- PVR2DBLTINFO blit;
- for (index = 0; index < drawable->numVisibleRects; ++index, ++rect) {
- memset(&blit, 0, sizeof(blit));
-
- blit.CopyCode = PVR2DROPcopy;
- blit.BlitFlags = PVR2D_BLIT_DISABLE_ALL;
-
- blit.pSrcMemInfo = buffer;
- blit.SrcStride = drawable->strideBytes;
- blit.SrcX = rect->x - drawable->rect.x;
- blit.SrcY = rect->y - drawable->rect.y;
- blit.SizeX = rect->width;
- blit.SizeY = rect->height;
- blit.SrcFormat = drawable->pixelFormat;
-
- blit.pDstMemInfo = pvrQwsDisplay.screens[drawable->screen].frameBuffer;
- blit.DstStride = pvrQwsDisplay.screens[drawable->screen].screenStride;
- blit.DstX = rect->x;
- blit.DstY = rect->y;
- blit.DSizeX = rect->width;
- blit.DSizeY = rect->height;
- blit.DstFormat = pvrQwsDisplay.screens[drawable->screen].pixelFormat;
-
- PVR2DBlt(pvrQwsDisplay.context, &blit);
- }
- }
-
- /* Swap the buffers */
- if (!repaintOnly) {
- drawable->currentBackBuffer
- = (drawable->currentBackBuffer + 1) % PVRQWS_MAX_BACK_BUFFERS;
- }
- return 1;
-}
-
-void pvrQwsSetSwapFunction
- (PvrQwsDrawable *drawable, PvrQwsSwapFunction func, void *userData)
-{
- drawable->swapFunction = func;
- drawable->userData = userData;
-}
diff --git a/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable.h b/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable.h
deleted file mode 100644
index 40119b0a41..0000000000
--- a/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable.h
+++ /dev/null
@@ -1,169 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef PVRQWSDRAWABLE_H
-#define PVRQWSDRAWABLE_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct {
- int x, y, width, height;
-} PvrQwsRect;
-
-typedef enum
-{
- PvrQwsScreen,
- PvrQwsWindow,
- PvrQwsPixmap
-
-} PvrQwsDrawableType;
-
-typedef enum
-{
- PvrQws_1BPP = 0,
- PvrQws_RGB565,
- PvrQws_ARGB4444,
- PvrQws_RGB888,
- PvrQws_ARGB8888,
- PvrQws_VGAEMU
-
-} PvrQwsPixelFormat;
-
-typedef struct _PvrQwsDrawable PvrQwsDrawable;
-
-typedef void (*PvrQwsSwapFunction)
- (PvrQwsDrawable *drawable, void *userData, int repaintOnly);
-
-/* Open the display and prepare for window operations. The display
- can be opened multiple times and each time is reference counted.
- The display will be finally closed when the same number of
- calls to pvrQwsDisplayClose() have been encountered */
-int pvrQwsDisplayOpen(void);
-
-/* Close the display */
-void pvrQwsDisplayClose(void);
-
-/* Determine if the display is already open */
-int pvrQwsDisplayIsOpen(void);
-
-/* Create a window that represents a particular framebuffer screen.
- Initially the visible region will be the whole screen. If the screen
- window has already been created, then will return the same value */
-PvrQwsDrawable *pvrQwsScreenWindow(int screen);
-
-/* Create a top-level window on a particular framebuffer screen.
- Initially the window will not have a visible region */
-PvrQwsDrawable *pvrQwsCreateWindow(int screen, long winId, const PvrQwsRect *rect);
-
-/* Fetch an existing window for a window id and increase its refcount */
-PvrQwsDrawable *pvrQwsFetchWindow(long winId);
-
-/* Release the refcount on a window. Returns 1 if refcount is zero */
-int pvrQwsReleaseWindow(PvrQwsDrawable *drawable);
-
-/* Create an off-screen pixmap */
-PvrQwsDrawable *pvrQwsCreatePixmap(int width, int height, int screen);
-
-/* Destroy a previously-created drawable. Will not destroy screens. */
-void pvrQwsDestroyDrawable(PvrQwsDrawable *drawable);
-
-/* Get a drawable's type */
-PvrQwsDrawableType pvrQwsGetDrawableType(PvrQwsDrawable *drawable);
-
-/* Sets the visible region for a window or screen drawable. Pixels within
- the specified rectangles will be copied to the framebuffer when the window
- or screen is swapped. The rectangles should be in global co-ordinates */
-void pvrQwsSetVisibleRegion
- (PvrQwsDrawable *drawable, const PvrQwsRect *rects, int numRects);
-
-/* Clear the visible region for a window or screen drawable,
- effectively removing it from the screen */
-void pvrQwsClearVisibleRegion(PvrQwsDrawable *drawable);
-
-/* Set the geometry for a drawable. This can only be used on windows */
-void pvrQwsSetGeometry(PvrQwsDrawable *drawable, const PvrQwsRect *rect);
-
-/* Get the current geometry for a drawable */
-void pvrQwsGetGeometry(PvrQwsDrawable *drawable, PvrQwsRect *rect);
-
-/* Set the rotation angle in degrees */
-void pvrQwsSetRotation(PvrQwsDrawable *drawable, int angle);
-
-/* Get the line stride for a drawable. Returns zero if the buffers
- are not allocated or have been invalidated */
-int pvrQwsGetStride(PvrQwsDrawable *drawable);
-
-/* Get the pixel format for a drawable */
-PvrQwsPixelFormat pvrQwsGetPixelFormat(PvrQwsDrawable *drawable);
-
-/* Get a pointer to the beginning of a drawable's current render buffer.
- Returns null if the buffers are not allocated or have been invalidated */
-void *pvrQwsGetRenderBuffer(PvrQwsDrawable *drawable);
-
-/* Allocate the buffers associated with a drawable. We allocate one buffer
- for pixmaps, and several for windows and screens */
-int pvrQwsAllocBuffers(PvrQwsDrawable *drawable);
-
-/* Free the buffers associated with a drawable */
-void pvrQwsFreeBuffers(PvrQwsDrawable *drawable);
-
-/* Invalidate the buffers associated with a drawable. The buffers will
- still be allocated but the next attempt to swap the buffers will fail */
-void pvrQwsInvalidateBuffers(PvrQwsDrawable *drawable);
-
-/* Swap the back buffers for a window or screen and copy to the framebuffer */
-int pvrQwsSwapBuffers(PvrQwsDrawable *drawable, int repaintOnly);
-
-/* Set the swap function for a drawable. When pvrQwsSwapBuffers()
- is called on the drawable, the supplied function will be called
- instead of copying the drawable contents to the screen. This allows
- higher-level compositors to know when a drawable has changed.
- The swap function can be set to null to return to normal processing */
-void pvrQwsSetSwapFunction
- (PvrQwsDrawable *drawable, PvrQwsSwapFunction func, void *userData);
-
-#ifdef __cplusplus
-};
-#endif
-
-#endif
diff --git a/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable_p.h b/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable_p.h
deleted file mode 100644
index b20dc023d6..0000000000
--- a/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable_p.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef PVRQWSDRAWABLE_P_H
-#define PVRQWSDRAWABLE_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// reasons. This header file may change from version to version
-// without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <pvr2d.h>
-#include "pvrqwsdrawable.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define PVRQWS_MAX_VISIBLE_RECTS 32
-#define PVRQWS_MAX_SCREENS 1
-#define PVRQWS_MAX_BACK_BUFFERS 2
-#define PVRQWS_MAX_FLIP_BUFFERS 2
-
-typedef struct {
-
- PvrQwsRect screenRect;
- int screenStride;
- PVR2DFORMAT pixelFormat;
- int bytesPerPixel;
- PVR2DMEMINFO *frameBuffer;
- PvrQwsDrawable *screenDrawable;
- void *mapped;
- int mappedLength;
- unsigned long screenStart;
- int needsUnmap;
- int initialized;
-
-} PvrQwsScreenInfo;
-
-typedef struct {
-
- int refCount;
- PvrQwsScreenInfo screens[PVRQWS_MAX_SCREENS];
- PVR2DCONTEXTHANDLE context;
- int numDrawables;
- unsigned long numFlipBuffers;
- PVR2DFLIPCHAINHANDLE flipChain;
- PVR2DMEMINFO *flipBuffers[PVRQWS_MAX_FLIP_BUFFERS];
- int usePresentBlit;
- PvrQwsDrawable *firstWinId;
-
-} PvrQwsDisplay;
-
-extern PvrQwsDisplay pvrQwsDisplay;
-
-struct _PvrQwsDrawable
-{
- PvrQwsDrawableType type;
- long winId;
- int refCount;
- PvrQwsRect rect;
- int screen;
- PVR2DFORMAT pixelFormat;
- PvrQwsRect visibleRects[PVRQWS_MAX_VISIBLE_RECTS];
- int numVisibleRects;
- PVR2DMEMINFO *backBuffers[PVRQWS_MAX_BACK_BUFFERS];
- int currentBackBuffer;
- int backBuffersValid;
- int usingFlipBuffers;
- int isFullScreen;
- int strideBytes;
- int stridePixels;
- int rotationAngle;
- PvrQwsSwapFunction swapFunction;
- void *userData;
- PvrQwsDrawable *nextWinId;
-
-};
-
-/* Get the current source and render buffers for a drawable */
-int pvrQwsGetBuffers
- (PvrQwsDrawable *drawable, PVR2DMEMINFO **source, PVR2DMEMINFO **render);
-
-#ifdef __cplusplus
-};
-#endif
-
-#endif
diff --git a/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwswsegl.c b/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwswsegl.c
deleted file mode 100644
index ce99e607f2..0000000000
--- a/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwswsegl.c
+++ /dev/null
@@ -1,402 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <GLES/eglplatform.h>
-#include <wsegl.h>
-#include <pvr2d.h>
-#include <string.h>
-#include <sys/mman.h>
-#include "pvrqwsdrawable_p.h"
-
-#define WSEGL_UNUSED(x) (void)x;
-
-// If the PVR2D version is not specified, then assume MBX-style headers.
-// If the version is defined, then we assume that we have SGX-style headers.
-#if !defined(PVR2D_REV_MAJOR)
-#define WSEGL_CAP_WINDOWS_USE_HW_SYNC WSEGL_CAP_WINDOWS_USE_MBX_SYNC
-#define WSEGL_CAP_PIXMAPS_USE_HW_SYNC WSEGL_CAP_PIXMAPS_USE_MBX_SYNC
-#endif
-
-/* Capability information for the display */
-static WSEGLCaps const wseglDisplayCaps[] = {
- {WSEGL_CAP_WINDOWS_USE_HW_SYNC, 1},
- {WSEGL_CAP_PIXMAPS_USE_HW_SYNC, 1},
- {WSEGL_NO_CAPS, 0}
-};
-
-/* Configuration information for the display */
-static WSEGLConfig wseglDisplayConfigs[] = {
- {WSEGL_DRAWABLE_WINDOW, WSEGL_PIXELFORMAT_565, WSEGL_FALSE,
- 0, 0, 0, WSEGL_OPAQUE, 0},
- {WSEGL_DRAWABLE_PIXMAP, WSEGL_PIXELFORMAT_565, WSEGL_FALSE,
- 0, 0, 0, WSEGL_OPAQUE, 0},
- {WSEGL_NO_DRAWABLE, 0, 0, 0, 0, 0, 0, 0}
-};
-
-/* Determine if nativeDisplay is a valid display handle */
-static WSEGLError wseglIsDisplayValid(NativeDisplayType nativeDisplay)
-{
- /* We only have the default display in this system */
- if (nativeDisplay == WSEGL_DEFAULT_DISPLAY)
- return WSEGL_SUCCESS;
- else
- return WSEGL_BAD_NATIVE_DISPLAY;
-}
-
-/* Initialize a native display for use with WSEGL */
-static WSEGLError wseglInitializeDisplay
- (NativeDisplayType nativeDisplay, WSEGLDisplayHandle *display,
- const WSEGLCaps **caps, WSEGLConfig **configs)
-{
- WSEGLPixelFormat pixelFormat;
-
- /* Bail out if the native display is incorrect */
- if (nativeDisplay != WSEGL_DEFAULT_DISPLAY)
- return WSEGL_CANNOT_INITIALISE;
-
- /* Open the PVR/QWS display, which will initialize the framebuffer */
- if (!pvrQwsDisplayOpen())
- return WSEGL_CANNOT_INITIALISE;
-
- /* Convert the PVR2D pixel format into a WSEGL pixel format */
- switch (pvrQwsDisplay.screens[0].pixelFormat) {
- case PVR2D_RGB565:
- pixelFormat = WSEGL_PIXELFORMAT_565;
- break;
-
- case PVR2D_ARGB4444:
- pixelFormat = WSEGL_PIXELFORMAT_4444;
- break;
-
- case PVR2D_ARGB8888:
- pixelFormat = WSEGL_PIXELFORMAT_8888;
- break;
-
- default:
- pvrQwsDisplayClose();
- return WSEGL_CANNOT_INITIALISE;
- }
- wseglDisplayConfigs[0].ePixelFormat = pixelFormat;
- wseglDisplayConfigs[1].ePixelFormat = pixelFormat;
-
- /* The display has been initialized */
- *display = (WSEGLDisplayHandle)&pvrQwsDisplay;
- *caps = wseglDisplayCaps;
- *configs = wseglDisplayConfigs;
- return WSEGL_SUCCESS;
-}
-
-/* Close the WSEGL display */
-static WSEGLError wseglCloseDisplay(WSEGLDisplayHandle display)
-{
- if (display == (WSEGLDisplayHandle)&pvrQwsDisplay)
- pvrQwsDisplayClose();
- return WSEGL_SUCCESS;
-}
-
-static WSEGLRotationAngle wseglRotationValue(int degrees)
-{
- switch (degrees) {
- case 90: return WSEGL_ROTATE_90;
- case 180: return WSEGL_ROTATE_180;
- case 270: return WSEGL_ROTATE_270;
- default: return WSEGL_ROTATE_0;
- }
-}
-
-/* Create the WSEGL drawable version of a native window */
-static WSEGLError wseglCreateWindowDrawable
- (WSEGLDisplayHandle display, WSEGLConfig *config,
- WSEGLDrawableHandle *drawable, NativeWindowType nativeWindow,
- WSEGLRotationAngle *rotationAngle)
-{
- PvrQwsDrawable *draw;
-
- WSEGL_UNUSED(display);
- WSEGL_UNUSED(config);
-
- /* Check for special handles that indicate framebuffer screens */
- if (nativeWindow >= (NativeWindowType)0 &&
- nativeWindow < (NativeWindowType)PVRQWS_MAX_SCREENS) {
- PvrQwsDrawable *screen = pvrQwsScreenWindow((int)nativeWindow);
- if (!screen)
- return WSEGL_OUT_OF_MEMORY;
- *drawable = (WSEGLDrawableHandle)screen;
- if (!pvrQwsAllocBuffers(screen))
- return WSEGL_OUT_OF_MEMORY;
- *rotationAngle = wseglRotationValue(screen->rotationAngle);
- return WSEGL_SUCCESS;
- }
-
- /* The native window is the winId - fetch the underlying drawable */
- draw = pvrQwsFetchWindow((long)nativeWindow);
- if (!draw)
- return WSEGL_BAD_DRAWABLE;
-
- /* The drawable is ready to go */
- *drawable = (WSEGLDrawableHandle)draw;
- *rotationAngle = wseglRotationValue(draw->rotationAngle);
- if (!pvrQwsAllocBuffers(draw))
- return WSEGL_OUT_OF_MEMORY;
- return WSEGL_SUCCESS;
-}
-
-/* Create the WSEGL drawable version of a native pixmap */
-static WSEGLError wseglCreatePixmapDrawable
- (WSEGLDisplayHandle display, WSEGLConfig *config,
- WSEGLDrawableHandle *drawable, NativePixmapType nativePixmap,
- WSEGLRotationAngle *rotationAngle)
-{
- WSEGL_UNUSED(display);
- WSEGL_UNUSED(config);
- if (!nativePixmap)
- return WSEGL_BAD_NATIVE_PIXMAP;
- if (!pvrQwsAllocBuffers((PvrQwsDrawable *)nativePixmap))
- return WSEGL_OUT_OF_MEMORY;
- *drawable = (WSEGLDrawableHandle)nativePixmap;
- *rotationAngle = WSEGL_ROTATE_0;
- return WSEGL_SUCCESS;
-}
-
-/* Delete a specific drawable */
-static WSEGLError wseglDeleteDrawable(WSEGLDrawableHandle _drawable)
-{
- PvrQwsDrawable *drawable = (PvrQwsDrawable *)_drawable;
- if (!drawable || drawable->type == PvrQwsScreen)
- return WSEGL_SUCCESS;
- if (pvrQwsDisplay.numFlipBuffers == 0)
- pvrQwsFreeBuffers(drawable);
- if (pvrQwsReleaseWindow(drawable))
- pvrQwsDestroyDrawable(drawable);
- return WSEGL_SUCCESS;
-}
-
-/* Swap the contents of a drawable to the screen */
-static WSEGLError wseglSwapDrawable
- (WSEGLDrawableHandle _drawable, unsigned long data)
-{
- WSEGL_UNUSED(data);
- PvrQwsDrawable *drawable = (PvrQwsDrawable *)_drawable;
- if (drawable->type != PvrQwsPixmap && !pvrQwsSwapBuffers(drawable, 0))
- return WSEGL_BAD_DRAWABLE;
- else
- return WSEGL_SUCCESS;
-}
-
-/* Set the swap interval of a window drawable */
-static WSEGLError wseglSwapControlInterval
- (WSEGLDrawableHandle drawable, unsigned long interval)
-{
- WSEGL_UNUSED(drawable);
- if (pvrQwsDisplay.flipChain) {
- PVR2DSetPresentFlipProperties
- (pvrQwsDisplay.context, pvrQwsDisplay.flipChain,
- PVR2D_PRESENT_PROPERTY_INTERVAL, 0, 0, 0, NULL, interval);
- }
- return WSEGL_SUCCESS;
-}
-
-/* Flush native rendering requests on a drawable */
-static WSEGLError wseglWaitNative
- (WSEGLDrawableHandle drawable, unsigned long engine)
-{
- WSEGL_UNUSED(drawable);
- if (engine == WSEGL_DEFAULT_NATIVE_ENGINE)
- return WSEGL_SUCCESS;
- else
- return WSEGL_BAD_NATIVE_ENGINE;
-}
-
-/* Copy color data from a drawable to a native pixmap */
-static WSEGLError wseglCopyFromDrawable
- (WSEGLDrawableHandle _drawable, NativePixmapType nativePixmap)
-{
- PvrQwsDrawable *drawable = (PvrQwsDrawable *)_drawable;
- PvrQwsDrawable *pixmap = (PvrQwsDrawable *)nativePixmap;
- PVR2DBLTINFO blit;
-
- if (!drawable || !drawable->backBuffersValid)
- return WSEGL_BAD_NATIVE_WINDOW;
- if (!pixmap || !pixmap->backBuffersValid)
- return WSEGL_BAD_NATIVE_PIXMAP;
-
- memset(&blit, 0, sizeof(blit));
-
- blit.CopyCode = PVR2DROPcopy;
- blit.BlitFlags = PVR2D_BLIT_DISABLE_ALL;
-
- blit.pSrcMemInfo = drawable->backBuffers[drawable->currentBackBuffer];
- blit.SrcStride = drawable->strideBytes;
- blit.SrcX = 0;
- blit.SrcY = 0;
- blit.SizeX = drawable->rect.width;
- blit.SizeY = drawable->rect.height;
- blit.SrcFormat = drawable->pixelFormat;
-
- blit.pDstMemInfo = pixmap->backBuffers[pixmap->currentBackBuffer];
- blit.DstStride = pixmap->strideBytes;
- blit.DstX = 0;
- blit.DstY = 0;
- blit.DSizeX = pixmap->rect.width;
- blit.DSizeY = pixmap->rect.height;
- blit.DstFormat = pixmap->pixelFormat;
-
- PVR2DBlt(pvrQwsDisplay.context, &blit);
- PVR2DQueryBlitsComplete
- (pvrQwsDisplay.context, pixmap->backBuffers[pixmap->currentBackBuffer], 1);
-
- return WSEGL_SUCCESS;
-}
-
-/* Copy color data from a PBuffer to a native pixmap */
-static WSEGLError wseglCopyFromPBuffer
- (void *address, unsigned long width, unsigned long height,
- unsigned long stride, WSEGLPixelFormat format,
- NativePixmapType nativePixmap)
-{
- PvrQwsDrawable *pixmap = (PvrQwsDrawable *)nativePixmap;
- PVR2DFORMAT pixelFormat;
-
- if (!pixmap)
- return WSEGL_BAD_NATIVE_PIXMAP;
-
- /* We can only copy under certain conditions */
- switch (format) {
- case WSEGL_PIXELFORMAT_565:
- pixelFormat = PVR2D_RGB565; break;
- case WSEGL_PIXELFORMAT_4444:
- pixelFormat = PVR2D_ARGB4444; break;
- case WSEGL_PIXELFORMAT_8888:
- pixelFormat = PVR2D_ARGB8888; break;
- default:
- return WSEGL_BAD_CONFIG;
- }
- if (width > (unsigned long)(pixmap->rect.width) ||
- height > (unsigned long)(pixmap->rect.height) ||
- pixelFormat != pixmap->pixelFormat) {
- return WSEGL_BAD_CONFIG;
- }
-
- /* We'd like to use PVR2DBlt to do this, but there is no easy way
- to map the virtual "address" into physical space to be able
- to use the hardware assist. Use memcpy to do the work instead.
- Note: PBuffer's are upside down, so we copy from the bottom up */
- char *srcaddr = (char *)address;
- char *dstaddr = (char *)(pixmap->backBuffers[pixmap->currentBackBuffer]->pBase);
- int dststride = pixmap->strideBytes;
- int srcwidth = ((int)width) * pvrQwsDisplay.screens[0].bytesPerPixel;
- srcaddr += height * stride;
- while (height > 0) {
- srcaddr -= (int)stride;
- memcpy(dstaddr, srcaddr, srcwidth);
- dstaddr += dststride;
- --height;
- }
- return WSEGL_SUCCESS;
-}
-
-/* Return the parameters of a drawable that are needed by the EGL layer */
-static WSEGLError wseglGetDrawableParameters
- (WSEGLDrawableHandle _drawable, WSEGLDrawableParams *sourceParams,
- WSEGLDrawableParams *renderParams)
-{
- PvrQwsDrawable *drawable = (PvrQwsDrawable *)_drawable;
- PVR2DMEMINFO *source, *render;
- WSEGLPixelFormat pixelFormat;
-
- if (!pvrQwsGetBuffers(drawable, &source, &render))
- return WSEGL_BAD_DRAWABLE;
-
- switch (drawable->pixelFormat) {
- case PVR2D_RGB565:
- default:
- pixelFormat = WSEGL_PIXELFORMAT_565;
- break;
-
- case PVR2D_ARGB4444:
- pixelFormat = WSEGL_PIXELFORMAT_4444;
- break;
-
- case PVR2D_ARGB8888:
- pixelFormat = WSEGL_PIXELFORMAT_8888;
- break;
- }
-
- sourceParams->ui32Width = drawable->rect.width;
- sourceParams->ui32Height = drawable->rect.height;
- sourceParams->ui32Stride = drawable->stridePixels;
- sourceParams->ePixelFormat = pixelFormat;
- sourceParams->pvLinearAddress = source->pBase;
- sourceParams->ui32HWAddress = source->ui32DevAddr;
- sourceParams->hPrivateData = source->hPrivateData;
-
- renderParams->ui32Width = drawable->rect.width;
- renderParams->ui32Height = drawable->rect.height;
- renderParams->ui32Stride = drawable->stridePixels;
- renderParams->ePixelFormat = pixelFormat;
- renderParams->pvLinearAddress = render->pBase;
- renderParams->ui32HWAddress = render->ui32DevAddr;
- renderParams->hPrivateData = render->hPrivateData;
-
- return WSEGL_SUCCESS;
-}
-
-static WSEGL_FunctionTable const wseglFunctions = {
- WSEGL_VERSION,
- wseglIsDisplayValid,
- wseglInitializeDisplay,
- wseglCloseDisplay,
- wseglCreateWindowDrawable,
- wseglCreatePixmapDrawable,
- wseglDeleteDrawable,
- wseglSwapDrawable,
- wseglSwapControlInterval,
- wseglWaitNative,
- wseglCopyFromDrawable,
- wseglCopyFromPBuffer,
- wseglGetDrawableParameters
-};
-
-/* Return the table of WSEGL functions to the EGL implementation */
-const WSEGL_FunctionTable *WSEGL_GetFunctionTablePointer(void)
-{
- return &wseglFunctions;
-}
diff --git a/src/plugins/gfxdrivers/powervr/README b/src/plugins/gfxdrivers/powervr/README
deleted file mode 100644
index 513e7f5e9e..0000000000
--- a/src/plugins/gfxdrivers/powervr/README
+++ /dev/null
@@ -1,66 +0,0 @@
-PowerVR QScreen Driver
-======================
-
-This QScreen plugin driver allows the QtOpenGl module to integrate with PowerVR
-hardware from Imagination Technologies. Using this plugin, applications may use
-QGLWidget & QGLPixelBuffer with OpenGL ES. The integration with PowerVR drivers
-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
-the LD library path. The PowerVR driver also needs to be told which WSEGL library
-to use. This is done by creating/modifying /etc/powervr.ini:
-
-[default]
-WindowSystem=libpvrQWSWSEGL.so
-
-Note: It is important that the /etc/powervr.ini file not contain ^M (Ctrl-M) DOS
-end of line markers at the end of its lines. If ^M markers are present, then the
-libpvrQWSWSEGL.so driver will not be loaded and the default null Linux driver
-will be loaded silently instead. Make sure that the end of line markers are
-strictly Unix-style markers.
-
-
-***************************************************************************
-* IMPORTANT: To build the QScreen plugin and the WSEGL library it depends *
-* on, the pvr2d.h, wsegl.h headers for your platform are required. You *
-* can find a copy of these headers in src/3rdparty/powervr for SGX based *
-* platforms like the TI OMAP3xxx. They probably will not work on MBX *
-* because of differences in the layout of certain PVR2D structures. *
-* You can tell Qt where to find the actual headers for your system by *
-* setting QMAKE_INCDIR_POWERVR in the mkspec. *
-***************************************************************************
-
-When you start a Qt/Embedded application, you should modify the QWS_DISPLAY
-environment variable to use the "powervr" driver instead of "LinuxFb". For
-example, if your original QWS_DISPLAY variable was:
-
- LinuxFb:mmWidth40:mmHeight54:0
-
-then it should be changed to:
-
- powervr:mmWidth40:mmHeight54:0
-
-To test the OpenGL ES integration, you can use the hellogl_es example and run it
-on the device with:
-
- hellogl_es -qws
-
-The driver also supports screen rotation if Qt is configured with the
--qt-gfx-transformed option and the QWS_DISPLAY variable is wrapped in a
-"Transformed" declaration:
-
- Transformed:powervr:mmWidth40:mmHeight54:Rot90:0
-
-Know Issues:
- * A QGLWidget may not have window decorations if it is a top-level window.
- * On some platforms, starting a QWS application after the system has been up
- for a long time may cause the driver to fail. This is due to fragmentation
- of main memory prevening older PowerVR drivers from allocating a contiguous
- region of phyical RAM for the GL surface.
diff --git a/src/plugins/gfxdrivers/powervr/powervr.pri b/src/plugins/gfxdrivers/powervr/powervr.pri
deleted file mode 100644
index 9df8c0ed5b..0000000000
--- a/src/plugins/gfxdrivers/powervr/powervr.pri
+++ /dev/null
@@ -1,2 +0,0 @@
-
-INCLUDEPATH += $$QMAKE_INCDIR_POWERVR
diff --git a/src/plugins/gfxdrivers/powervr/powervr.pro b/src/plugins/gfxdrivers/powervr/powervr.pro
deleted file mode 100644
index f31ad042d8..0000000000
--- a/src/plugins/gfxdrivers/powervr/powervr.pro
+++ /dev/null
@@ -1,3 +0,0 @@
-TEMPLATE = subdirs
-SUBDIRS = QWSWSEGL pvreglscreen
-CONFIG += ordered
diff --git a/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.cpp b/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.cpp
deleted file mode 100644
index 0171de6797..0000000000
--- a/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.cpp
+++ /dev/null
@@ -1,351 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "pvreglscreen.h"
-#include "pvreglwindowsurface.h"
-#include "pvrqwsdrawable_p.h"
-#include <QRegExp>
-#include <qwindowsystem_qws.h>
-#ifndef QT_NO_QWS_TRANSFORMED
-#include <qscreentransformed_qws.h>
-#endif
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-#include <sys/kd.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-//![0]
-PvrEglScreen::PvrEglScreen(int displayId)
- : QGLScreen(displayId)
-{
- setOptions(NativeWindows);
- setSupportsBlitInClients(true);
- setSurfaceFunctions(new PvrEglScreenSurfaceFunctions(this, displayId));
-//![0]
- fd = -1;
- ttyfd = -1;
- doGraphicsMode = true;
- oldKdMode = KD_TEXT;
- parent = 0;
-
- // Make sure that the EGL layer is initialized and the drivers loaded.
- EGLDisplay dpy = eglGetDisplay((EGLNativeDisplayType)EGL_DEFAULT_DISPLAY);
- if (!eglInitialize(dpy, 0, 0))
- qWarning("Could not initialize EGL display - are the drivers loaded?");
-
- // Make sure that screen 0 is initialized.
- pvrQwsScreenWindow(0);
-}
-
-PvrEglScreen::~PvrEglScreen()
-{
- if (fd >= 0)
- ::close(fd);
-}
-
-bool PvrEglScreen::initDevice()
-{
- openTty();
- return true;
-}
-
-bool PvrEglScreen::connect(const QString &displaySpec)
-{
- if (!pvrQwsDisplayOpen())
- return false;
-
- // Initialize the QScreen properties.
- data = (uchar *)(pvrQwsDisplay.screens[0].mapped);
- w = pvrQwsDisplay.screens[0].screenRect.width;
- h = pvrQwsDisplay.screens[0].screenRect.height;
- lstep = pvrQwsDisplay.screens[0].screenStride;
- dw = w;
- dh = h;
- size = h * lstep;
- mapsize = size;
- switch (pvrQwsDisplay.screens[0].pixelFormat) {
- case PVR2D_RGB565:
- d = 16;
- setPixelFormat(QImage::Format_RGB16);
- break;
- case PVR2D_ARGB4444:
- d = 16;
- setPixelFormat(QImage::Format_ARGB4444_Premultiplied);
- break;
- case PVR2D_ARGB8888:
- d = 32;
- setPixelFormat(QImage::Format_ARGB32_Premultiplied);
- break;
- default:
- pvrQwsDisplayClose();
- qWarning("PvrEglScreen::connect: unsupported pixel format %d", (int)(pvrQwsDisplay.screens[0].pixelFormat));
- return false;
- }
-
- // Handle display physical size spec.
- QStringList displayArgs = displaySpec.split(QLatin1Char(':'));
- QRegExp mmWidthRx(QLatin1String("mmWidth=?(\\d+)"));
- int dimIdxW = displayArgs.indexOf(mmWidthRx);
- QRegExp mmHeightRx(QLatin1String("mmHeight=?(\\d+)"));
- int dimIdxH = displayArgs.indexOf(mmHeightRx);
- if (dimIdxW >= 0) {
- mmWidthRx.exactMatch(displayArgs.at(dimIdxW));
- physWidth = mmWidthRx.cap(1).toInt();
- if (dimIdxH < 0)
- physHeight = dh*physWidth/dw;
- }
- if (dimIdxH >= 0) {
- mmHeightRx.exactMatch(displayArgs.at(dimIdxH));
- physHeight = mmHeightRx.cap(1).toInt();
- if (dimIdxW < 0)
- physWidth = dw*physHeight/dh;
- }
- if (dimIdxW < 0 && dimIdxH < 0) {
- const int dpi = 72;
- physWidth = qRound(dw * 25.4 / dpi);
- physHeight = qRound(dh * 25.4 / dpi);
- }
-
- // Find the name of the tty device to use.
- QRegExp ttyRegExp(QLatin1String("tty=(.*)"));
- if (displayArgs.indexOf(ttyRegExp) != -1)
- ttyDevice = ttyRegExp.cap(1);
- if (displayArgs.contains(QLatin1String("nographicsmodeswitch")))
- doGraphicsMode = false;
-
- // The screen is ready.
- return true;
-}
-
-void PvrEglScreen::disconnect()
-{
- pvrQwsDisplayClose();
-}
-
-void PvrEglScreen::shutdownDevice()
-{
- closeTty();
-}
-
-void PvrEglScreen::blit(const QImage &img, const QPoint &topLeft, const QRegion &region)
-{
- QGLScreen::blit(img, topLeft, region);
- sync();
-}
-
-void PvrEglScreen::solidFill(const QColor &color, const QRegion &region)
-{
- QGLScreen::solidFill(color, region);
- sync();
-}
-
-bool PvrEglScreen::chooseContext
- (QGLContext *context, const QGLContext *shareContext)
-{
- // We use PvrEglScreenSurfaceFunctions instead.
- Q_UNUSED(context);
- Q_UNUSED(shareContext);
- return false;
-}
-
-bool PvrEglScreen::hasOpenGL()
-{
- return true;
-}
-
-//![1]
-QWSWindowSurface* PvrEglScreen::createSurface(QWidget *widget) const
-{
- if (qobject_cast<QGLWidget*>(widget))
- return new PvrEglWindowSurface(widget, (PvrEglScreen *)this, displayId);
-
- return QScreen::createSurface(widget);
-}
-
-QWSWindowSurface* PvrEglScreen::createSurface(const QString &key) const
-{
- if (key == QLatin1String("PvrEgl"))
- return new PvrEglWindowSurface();
-
- return QScreen::createSurface(key);
-}
-//![1]
-
-#ifndef QT_NO_QWS_TRANSFORMED
-
-static const QScreen *parentScreen
- (const QScreen *current, const QScreen *lookingFor)
-{
- if (!current)
- return 0;
- switch (current->classId()) {
- case QScreen::ProxyClass:
- case QScreen::TransformedClass: {
- const QScreen *child =
- static_cast<const QProxyScreen *>(current)->screen();
- if (child == lookingFor)
- return current;
- else
- return parentScreen(child, lookingFor);
- }
- // Not reached.
-
- case QScreen::MultiClass: {
- QList<QScreen *> screens = current->subScreens();
- foreach (QScreen *screen, screens) {
- if (screen == lookingFor)
- return current;
- const QScreen *parent = parentScreen(screen, lookingFor);
- if (parent)
- return parent;
- }
- }
- break;
-
- default: break;
- }
- return 0;
-}
-
-int PvrEglScreen::transformation() const
-{
- // We need to search for our parent screen, which is assumed to be
- // "Transformed". If it isn't, then there is no transformation.
- // There is no direct method to get the parent screen so we need
- // to search every screen until we find ourselves.
- if (!parent && qt_screen != this)
- parent = parentScreen(qt_screen, this);
- if (!parent)
- return 0;
- if (parent->classId() != QScreen::TransformedClass)
- return 0;
- return 90 * static_cast<const QTransformedScreen *>(parent)
- ->transformOrientation();
-}
-
-#else
-
-int PvrEglScreen::transformation() const
-{
- return 0;
-}
-
-#endif
-
-void PvrEglScreen::sync()
-{
- // Put code here to synchronize 2D and 3D operations if necessary.
-}
-
-void PvrEglScreen::openTty()
-{
- const char *const devs[] = {"/dev/tty0", "/dev/tty", "/dev/console", 0};
-
- if (ttyDevice.isEmpty()) {
- for (const char * const *dev = devs; *dev; ++dev) {
- ttyfd = ::open(*dev, O_RDWR);
- if (ttyfd != -1)
- break;
- }
- } else {
- ttyfd = ::open(ttyDevice.toAscii().constData(), O_RDWR);
- }
-
- if (ttyfd == -1)
- return;
-
- ::fcntl(ttyfd, F_SETFD, FD_CLOEXEC);
-
- if (doGraphicsMode) {
- ioctl(ttyfd, KDGETMODE, &oldKdMode);
- if (oldKdMode != KD_GRAPHICS) {
- int ret = ioctl(ttyfd, KDSETMODE, KD_GRAPHICS);
- if (ret == -1)
- doGraphicsMode = false;
- }
- }
-
- // No blankin' screen, no blinkin' cursor!, no cursor!
- const char termctl[] = "\033[9;0]\033[?33l\033[?25l\033[?1c";
- ::write(ttyfd, termctl, sizeof(termctl));
-}
-
-void PvrEglScreen::closeTty()
-{
- if (ttyfd == -1)
- return;
-
- if (doGraphicsMode)
- ioctl(ttyfd, KDSETMODE, oldKdMode);
-
- // Blankin' screen, blinkin' cursor!
- const char termctl[] = "\033[9;15]\033[?33h\033[?25h\033[?0c";
- ::write(ttyfd, termctl, sizeof(termctl));
-
- ::close(ttyfd);
- ttyfd = -1;
-}
-
-//![2]
-bool PvrEglScreenSurfaceFunctions::createNativeWindow(QWidget *widget, EGLNativeWindowType *native)
-{
-//![2]
- QWSWindowSurface *surface =
- static_cast<QWSWindowSurface *>(widget->windowSurface());
- if (!surface) {
- // The widget does not have a surface yet, so give it one.
- surface = new PvrEglWindowSurface(widget, screen, displayId);
- widget->setWindowSurface(surface);
- } else if (surface->key() != QLatin1String("PvrEgl")) {
- // The application has attached a QGLContext to an ordinary QWidget.
- // Replace the widget's window surface with a new one that can do GL.
- QRect geometry = widget->frameGeometry();
- geometry.moveTo(widget->mapToGlobal(QPoint(0, 0)));
- surface = new PvrEglWindowSurface(widget, screen, displayId);
- surface->setGeometry(geometry);
- widget->setWindowSurface(surface);
- widget->setAttribute(Qt::WA_NoSystemBackground, true);
- }
- PvrEglWindowSurface *nsurface = static_cast<PvrEglWindowSurface*>(surface);
- *native = (EGLNativeWindowType)(nsurface->nativeDrawable());
- return true;
-}
diff --git a/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.h b/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.h
deleted file mode 100644
index f1893e3e96..0000000000
--- a/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef PVREGLSCREEN_H
-#define PVREGLSCREEN_H
-
-#include <QScreen>
-#include <QGLScreen>
-#include "pvrqwsdrawable.h"
-
-class PvrEglScreen;
-
-class PvrEglScreenSurfaceFunctions : public QGLScreenSurfaceFunctions
-{
-public:
- PvrEglScreenSurfaceFunctions(PvrEglScreen *s, int screenNum)
- : screen(s), displayId(screenNum) {}
-
- bool createNativeWindow(QWidget *widget, EGLNativeWindowType *native);
-
-private:
- PvrEglScreen *screen;
- int displayId;
-};
-
-class PvrEglScreen : public QGLScreen
-{
-public:
- PvrEglScreen(int displayId);
- ~PvrEglScreen();
-
- bool initDevice();
- bool connect(const QString &displaySpec);
- void disconnect();
- void shutdownDevice();
- void setMode(int, int, int) {}
-
- void blit(const QImage &img, const QPoint &topLeft, const QRegion &region);
- void solidFill(const QColor &color, const QRegion &region);
-
- bool chooseContext(QGLContext *context, const QGLContext *shareContext);
- bool hasOpenGL();
-
- QWSWindowSurface* createSurface(QWidget *widget) const;
- QWSWindowSurface* createSurface(const QString &key) const;
-
- int transformation() const;
-
-private:
- void sync();
- void openTty();
- void closeTty();
-
- int fd;
- int ttyfd, oldKdMode;
- QString ttyDevice;
- bool doGraphicsMode;
- mutable const QScreen *parent;
-};
-
-#endif
diff --git a/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.pro b/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.pro
deleted file mode 100644
index 2b5212a6b3..0000000000
--- a/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.pro
+++ /dev/null
@@ -1,27 +0,0 @@
-TEMPLATE = lib
-TARGET = qgfxpvregl
-CONFIG += qt plugin warn_on
-QT += opengl
-
-LIBS += -lpvrQWSWSEGL
-
-DEFINES += QT_QWS_CLIENTBLIT
-
-INCLUDEPATH += ../QWSWSEGL
-
-
-HEADERS = \
- pvreglscreen.h \
- pvreglwindowsurface.h
-
-SOURCES = \
- pvreglscreenplugin.cpp \
- pvreglscreen.cpp \
- pvreglwindowsurface.cpp
-
-DESTDIR = $$QT.gui.plugins/gfxdrivers
-
-target.path = $$[QT_INSTALL_PLUGINS]/gfxdrivers
-INSTALLS += target
-
-include(../powervr.pri) \ No newline at end of file
diff --git a/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreenplugin.cpp b/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreenplugin.cpp
deleted file mode 100644
index 943bf9473c..0000000000
--- a/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreenplugin.cpp
+++ /dev/null
@@ -1,74 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "pvreglscreen.h"
-
-#include <QScreenDriverPlugin>
-#include <QStringList>
-
-class PvrEglScreenPlugin : public QScreenDriverPlugin
-{
-public:
- PvrEglScreenPlugin();
-
- QStringList keys() const;
- QScreen *create(const QString&, int displayId);
-};
-
-PvrEglScreenPlugin::PvrEglScreenPlugin()
- : QScreenDriverPlugin()
-{
-}
-
-QStringList PvrEglScreenPlugin::keys() const
-{
- return (QStringList() << "powervr");
-}
-
-QScreen* PvrEglScreenPlugin::create(const QString& driver, int displayId)
-{
- if (driver.toLower() != "powervr")
- return 0;
-
- return new PvrEglScreen(displayId);
-}
-
-Q_EXPORT_PLUGIN2(qgfxpvregl, PvrEglScreenPlugin)
diff --git a/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglwindowsurface.cpp b/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglwindowsurface.cpp
deleted file mode 100644
index f23f5c1cc4..0000000000
--- a/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglwindowsurface.cpp
+++ /dev/null
@@ -1,273 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "pvreglwindowsurface.h"
-#include "pvreglscreen.h"
-#include <QScreen>
-#include <QDebug>
-#include <QWSDisplay>
-
-PvrEglWindowSurface::PvrEglWindowSurface
- (QWidget *widget, PvrEglScreen *screen, int screenNum)
- : QWSGLWindowSurface(widget)
-{
- setSurfaceFlags(QWSWindowSurface::Opaque);
-
- this->widget = widget;
- this->screen = screen;
- this->pdevice = 0;
-
- QPoint pos = offset(widget);
- QSize size = widget->size();
-
- PvrQwsRect pvrRect;
- pvrRect.x = pos.x();
- pvrRect.y = pos.y();
- pvrRect.width = size.width();
- pvrRect.height = size.height();
- transformRects(&pvrRect, 1);
-
- // Try to recover a previous PvrQwsDrawable object for the widget
- // if there is one. This can happen when a PvrEglWindowSurface
- // is created for a widget, bound to a EGLSurface, and then destroyed.
- // When a new PvrEglWindowSurface is created for the widget, it will
- // pick up the previous PvrQwsDrawable if the EGLSurface has not been
- // destroyed in the meantime.
- drawable = pvrQwsFetchWindow((long)widget);
- if (drawable)
- pvrQwsSetGeometry(drawable, &pvrRect);
- else
- drawable = pvrQwsCreateWindow(screenNum, (long)widget, &pvrRect);
- pvrQwsSetRotation(drawable, screen->transformation());
-}
-
-PvrEglWindowSurface::PvrEglWindowSurface()
- : QWSGLWindowSurface()
-{
- setSurfaceFlags(QWSWindowSurface::Opaque);
- drawable = 0;
- widget = 0;
- screen = 0;
- pdevice = 0;
-}
-
-PvrEglWindowSurface::~PvrEglWindowSurface()
-{
- // Release the PvrQwsDrawable. If it is bound to an EGLSurface,
- // then it will stay around until a new PvrEglWindowSurface is
- // created for the widget. If it is not bound to an EGLSurface,
- // it will be destroyed immediately.
- if (drawable && pvrQwsReleaseWindow(drawable))
- pvrQwsDestroyDrawable(drawable);
-
- delete pdevice;
-}
-
-bool PvrEglWindowSurface::isValid() const
-{
- return (widget != 0);
-}
-
-void PvrEglWindowSurface::setGeometry(const QRect &rect)
-{
- if (drawable) {
- // XXX: adjust for the screen offset.
- PvrQwsRect pvrRect;
- pvrRect.x = rect.x();
- pvrRect.y = rect.y();
- pvrRect.width = rect.width();
- pvrRect.height = rect.height();
- transformRects(&pvrRect, 1);
- pvrQwsSetGeometry(drawable, &pvrRect);
- pvrQwsSetRotation(drawable, screen->transformation());
- }
- QWSGLWindowSurface::setGeometry(rect);
-}
-
-bool PvrEglWindowSurface::move(const QPoint &offset)
-{
- QRect rect = geometry().translated(offset);
- if (drawable) {
- PvrQwsRect pvrRect;
- pvrRect.x = rect.x();
- pvrRect.y = rect.y();
- pvrRect.width = rect.width();
- pvrRect.height = rect.height();
- transformRects(&pvrRect, 1);
- pvrQwsSetGeometry(drawable, &pvrRect);
- pvrQwsSetRotation(drawable, screen->transformation());
- }
- return QWSGLWindowSurface::move(offset);
-}
-
-QByteArray PvrEglWindowSurface::permanentState() const
-{
- // Nothing interesting to pass to the server just yet.
- return QByteArray();
-}
-
-void PvrEglWindowSurface::setPermanentState(const QByteArray &state)
-{
- Q_UNUSED(state);
-}
-
-void PvrEglWindowSurface::flush
- (QWidget *widget, const QRegion &region, const QPoint &offset)
-{
- // The GL paint engine is responsible for the swapBuffers() call.
- // If we were to call the base class's implementation of flush()
- // then it would fetch the image() and manually blit it to the
- // screeen instead of using the fast PVR2D blit.
- Q_UNUSED(widget);
- Q_UNUSED(region);
- Q_UNUSED(offset);
-}
-
-QImage PvrEglWindowSurface::image() const
-{
- if (drawable) {
- PvrQwsRect pvrRect;
- pvrQwsGetGeometry(drawable, &pvrRect);
- void *data = pvrQwsGetRenderBuffer(drawable);
- if (data) {
- return QImage((uchar *)data, pvrRect.width, pvrRect.height,
- pvrQwsGetStride(drawable), screen->pixelFormat());
- }
- }
- return QImage(16, 16, screen->pixelFormat());
-}
-
-QPaintDevice *PvrEglWindowSurface::paintDevice()
-{
- return widget;
-}
-
-void PvrEglWindowSurface::setDirectRegion(const QRegion &r, int id)
-{
- QWSGLWindowSurface::setDirectRegion(r, id);
-
- if (!drawable)
- return;
-
- // Clip the region to the window boundaries in case the child
- // is partially outside the geometry of the parent.
- QWidget *window = widget->window();
- QRegion region = r;
- if (widget != window) {
- QRect rect = window->geometry();
- rect.moveTo(window->mapToGlobal(QPoint(0, 0)));
- region = region.intersect(rect);
- }
-
- if (region.isEmpty()) {
- pvrQwsClearVisibleRegion(drawable);
- } else if (region.rectCount() == 1) {
- QRect rect = region.boundingRect();
- PvrQwsRect pvrRect;
- pvrRect.x = rect.x();
- pvrRect.y = rect.y();
- pvrRect.width = rect.width();
- pvrRect.height = rect.height();
- transformRects(&pvrRect, 1);
- pvrQwsSetVisibleRegion(drawable, &pvrRect, 1);
- pvrQwsSetRotation(drawable, screen->transformation());
- if (!pvrQwsSwapBuffers(drawable, 1))
- screen->solidFill(QColor(0, 0, 0), region);
- } else {
- QVector<QRect> rects = region.rects();
- PvrQwsRect *pvrRects = new PvrQwsRect [rects.size()];
- for (int index = 0; index < rects.size(); ++index) {
- QRect rect = rects[index];
- pvrRects[index].x = rect.x();
- pvrRects[index].y = rect.y();
- pvrRects[index].width = rect.width();
- pvrRects[index].height = rect.height();
- }
- transformRects(pvrRects, rects.size());
- pvrQwsSetVisibleRegion(drawable, pvrRects, rects.size());
- pvrQwsSetRotation(drawable, screen->transformation());
- if (!pvrQwsSwapBuffers(drawable, 1))
- screen->solidFill(QColor(0, 0, 0), region);
- delete [] pvrRects;
- }
-}
-
-void PvrEglWindowSurface::transformRects(PvrQwsRect *rects, int count) const
-{
- switch (screen->transformation()) {
- case 0: break;
-
- case 90:
- {
- for (int index = 0; index < count; ++index) {
- int x = rects[index].y;
- int y = screen->height() - (rects[index].x + rects[index].width);
- rects[index].x = x;
- rects[index].y = y;
- qSwap(rects[index].width, rects[index].height);
- }
- }
- break;
-
- case 180:
- {
- for (int index = 0; index < count; ++index) {
- int x = screen->width() - (rects[index].x + rects[index].width);
- int y = screen->height() - (rects[index].y + rects[index].height);
- rects[index].x = x;
- rects[index].y = y;
- }
- }
- break;
-
- case 270:
- {
- for (int index = 0; index < count; ++index) {
- int x = screen->width() - (rects[index].y + rects[index].height);
- int y = rects[index].x;
- rects[index].x = x;
- rects[index].y = y;
- qSwap(rects[index].width, rects[index].height);
- }
- }
- break;
- }
-}
diff --git a/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglwindowsurface.h b/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglwindowsurface.h
deleted file mode 100644
index 365fed9170..0000000000
--- a/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglwindowsurface.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef PVREGLWINDOWSURFACE_H
-#define PVREGLWINDOWSURFACE_H
-
-#include <private/qglwindowsurface_qws_p.h>
-#include "pvrqwsdrawable.h"
-
-class PvrEglScreen;
-
-class PvrEglWindowSurface : public QWSGLWindowSurface
-{
-public:
- PvrEglWindowSurface(QWidget *widget, PvrEglScreen *screen, int screenNum);
- PvrEglWindowSurface();
- ~PvrEglWindowSurface();
-
- QString key() const { return QLatin1String("PvrEgl"); }
-
- bool isValid() const;
-
- void setGeometry(const QRect &rect);
- bool move(const QPoint &offset);
-
- QByteArray permanentState() const;
- void setPermanentState(const QByteArray &state);
-
- void flush(QWidget *widget, const QRegion &region, const QPoint &offset);
-
- QImage image() const;
- QPaintDevice *paintDevice();
-
- void setDirectRegion(const QRegion &region, int id);
-
- long nativeDrawable() const { return (long)widget; }
-
-private:
- QWidget *widget;
- PvrQwsDrawable *drawable;
- PvrEglScreen *screen;
- QPaintDevice *pdevice;
-
- void transformRects(PvrQwsRect *rects, int count) const;
-};
-
-#endif
diff --git a/src/plugins/gfxdrivers/qvfb/main.cpp b/src/plugins/gfxdrivers/qvfb/main.cpp
deleted file mode 100644
index 98661b61b9..0000000000
--- a/src/plugins/gfxdrivers/qvfb/main.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qscreendriverplugin_qws.h>
-#include <qscreenvfb_qws.h>
-#include <qstringlist.h>
-
-#ifndef QT_NO_LIBRARY
-QT_BEGIN_NAMESPACE
-
-class ScreenVfbDriver : public QScreenDriverPlugin
-{
-public:
- ScreenVfbDriver();
-
- QStringList keys() const;
- QScreen *create(const QString&, int displayId);
-};
-
-ScreenVfbDriver::ScreenVfbDriver()
-: QScreenDriverPlugin()
-{
-}
-
-QStringList ScreenVfbDriver::keys() const
-{
- QStringList list;
- list << "QVFb";
- return list;
-}
-
-QScreen* ScreenVfbDriver::create(const QString& driver, int displayId)
-{
- if (driver.toLower() == "qvfb")
- return new QVFbScreen(displayId);
-
- return 0;
-}
-
-Q_EXPORT_STATIC_PLUGIN(ScreenVfbDriver)
-Q_EXPORT_PLUGIN2(qscreenvfb, ScreenVfbDriver)
-
-QT_END_NAMESPACE
-#endif //QT_NO_LIBRARY
diff --git a/src/plugins/gfxdrivers/qvfb/qvfb.pro b/src/plugins/gfxdrivers/qvfb/qvfb.pro
deleted file mode 100644
index 99376be81c..0000000000
--- a/src/plugins/gfxdrivers/qvfb/qvfb.pro
+++ /dev/null
@@ -1,19 +0,0 @@
-TARGET = qscreenvfb
-load(qt_plugin)
-
-DEFINES += QT_QWS_QVFB QT_QWS_MOUSE_QVFB QT_QWS_KBD_QVFB
-
-DESTDIR = $$QT.gui.plugins/gfxdrivers
-
-HEADERS = \
- $$QT_SOURCE_TREE/src/gui/embedded/qscreenvfb_qws.h \
- $$QT_SOURCE_TREE/src/gui/embedded/qkbdvfb_qws.h \
- $$QT_SOURCE_TREE/src/gui/embedded/qmousevfb_qws.h
-
-SOURCES = main.cpp \
- $$QT_SOURCE_TREE/src/gui/embedded/qscreenvfb_qws.cpp \
- $$QT_SOURCE_TREE/src/gui/embedded/qkbdvfb_qws.cpp \
- $$QT_SOURCE_TREE/src/gui/embedded/qmousevfb_qws.cpp
-
-target.path += $$[QT_INSTALL_PLUGINS]/gfxdrivers
-INSTALLS += target
diff --git a/src/plugins/gfxdrivers/transformed/main.cpp b/src/plugins/gfxdrivers/transformed/main.cpp
deleted file mode 100644
index 612068e3a6..0000000000
--- a/src/plugins/gfxdrivers/transformed/main.cpp
+++ /dev/null
@@ -1,84 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qscreendriverplugin_qws.h>
-#include <qscreentransformed_qws.h>
-#include <qstringlist.h>
-#ifndef QT_NO_LIBRARY
-QT_BEGIN_NAMESPACE
-
-class GfxTransformedDriver : public QScreenDriverPlugin
-{
-public:
- GfxTransformedDriver();
-
- QStringList keys() const;
- QScreen *create(const QString&, int displayId);
-};
-
-GfxTransformedDriver::GfxTransformedDriver()
-: QScreenDriverPlugin()
-{
-}
-
-QStringList GfxTransformedDriver::keys() const
-{
- QStringList list;
- list << "Transformed";
- return list;
-}
-
-QScreen* GfxTransformedDriver::create(const QString& driver, int displayId)
-{
-#ifndef QT_NO_QWS_TRANSFORMED
- if (driver.toLower() == "transformed")
- return new QTransformedScreen(displayId);
-#else //QT_NO_QWS_TRANSFORMED
- printf("QT buildt with QT_NO_QWS_TRANSFORMED. No screen driver returned\n");
-#endif //QT_NO_QWS_TRANSFORMED
- return 0;
-}
-
-Q_EXPORT_STATIC_PLUGIN(GfxTransformedDriver)
-Q_EXPORT_PLUGIN2(qgfxtransformed, GfxTransformedDriver)
-
-QT_END_NAMESPACE
-#endif //QT_NO_LIBRARY
diff --git a/src/plugins/gfxdrivers/transformed/transformed.pro b/src/plugins/gfxdrivers/transformed/transformed.pro
deleted file mode 100644
index f97713fc38..0000000000
--- a/src/plugins/gfxdrivers/transformed/transformed.pro
+++ /dev/null
@@ -1,13 +0,0 @@
-TARGET = qgfxtransformed
-load(qt_plugin)
-
-DEFINES += QT_QWS_TRANSFORMED
-
-DESTDIR = $$QT.gui.plugins/gfxdrivers
-
-HEADERS = $$QT_SOURCE_TREE/src/gui/embedded/qscreentransformed_qws.h
-SOURCES = main.cpp \
- $$QT_SOURCE_TREE/src/gui/embedded/qscreentransformed_qws.cpp
-
-target.path=$$[QT_INSTALL_PLUGINS]/gfxdrivers
-INSTALLS += target
diff --git a/src/plugins/gfxdrivers/vnc/main.cpp b/src/plugins/gfxdrivers/vnc/main.cpp
deleted file mode 100644
index 0a7ae592e0..0000000000
--- a/src/plugins/gfxdrivers/vnc/main.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qscreendriverplugin_qws.h>
-#include <qscreenvnc_qws.h>
-#include <qstringlist.h>
-
-#ifndef QT_NO_LIBRARY
-QT_BEGIN_NAMESPACE
-
-class GfxVncDriver : public QScreenDriverPlugin
-{
-public:
- GfxVncDriver();
-
- QStringList keys() const;
- QScreen *create(const QString&, int displayId);
-};
-
-GfxVncDriver::GfxVncDriver()
-: QScreenDriverPlugin()
-{
-}
-
-QStringList GfxVncDriver::keys() const
-{
- QStringList list;
- list << "VNC";
- return list;
-}
-
-QScreen* GfxVncDriver::create(const QString& driver, int displayId)
-{
-#ifndef QT_NO_QWS_VNC
- if (driver.toLower() == "vnc")
- return new QVNCScreen(displayId);
-#else //QT_NO_QWS_VNC
- printf("QT buildt with QT_NO_QWS_VNC. No screen driver returned\n");
-#endif //QT_NO_QWS_VNC
- return 0;
-}
-
-Q_EXPORT_STATIC_PLUGIN(GfxVncDriver)
-Q_EXPORT_PLUGIN2(qgfxvnc, GfxVncDriver)
-
-QT_END_NAMESPACE
-
-#endif //QT_NO_LIBRARY
diff --git a/src/plugins/gfxdrivers/vnc/qscreenvnc_p.h b/src/plugins/gfxdrivers/vnc/qscreenvnc_p.h
deleted file mode 100644
index e64393a8c9..0000000000
--- a/src/plugins/gfxdrivers/vnc/qscreenvnc_p.h
+++ /dev/null
@@ -1,524 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSCREENVNC_P_H
-#define QSCREENVNC_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of the QLibrary class. This header file may change from version to version
-// without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qscreenvnc_qws.h"
-
-#ifndef QT_NO_QWS_VNC
-
-#include <QtCore/qvarlengtharray.h>
-#include <QtCore/qsharedmemory.h>
-#include <QtNetwork/qtcpsocket.h>
-#include <QtNetwork/qtcpserver.h>
-
-QT_BEGIN_NAMESPACE
-
-class QVNCServer;
-
-#ifndef QT_NO_QWS_CURSOR
-class QVNCCursor : public QProxyScreenCursor
-{
-public:
- QVNCCursor(QVNCScreen *s);
- ~QVNCCursor();
-
- void hide();
- void show();
- void set(const QImage &image, int hotx, int hoty);
- void move(int x, int y);
-
-private:
- void setDirty(const QRect &r) const;
- QVNCScreen *screen;
-};
-
-class QVNCClientCursor : public QProxyScreenCursor
-{
-public:
- QVNCClientCursor(QVNCServer *s);
- ~QVNCClientCursor();
-
- void set(const QImage &image, int hotx, int hoty);
- void write() const;
-
-private:
- QVNCServer *server;
-};
-#endif // QT_NO_QWS_CURSOR
-
-#define MAP_TILE_SIZE 16
-#define MAP_WIDTH 1280 / MAP_TILE_SIZE
-#define MAP_HEIGHT 1024 / MAP_TILE_SIZE
-
-class QVNCDirtyMap
-{
-public:
- QVNCDirtyMap(QScreen *screen);
- virtual ~QVNCDirtyMap();
-
- void reset();
- bool dirty(int x, int y) const;
- virtual void setDirty(int x, int y, bool force = false) = 0;
- void setClean(int x, int y);
-
- int bytesPerPixel;
-
- int numDirty;
- int mapWidth;
- int mapHeight;
-
-protected:
- uchar *map;
- QScreen *screen;
- uchar *buffer;
- int bufferWidth;
- int bufferHeight;
- int bufferStride;
- int numTiles;
-};
-
-template <class T>
-class QVNCDirtyMapOptimized : public QVNCDirtyMap
-{
-public:
- QVNCDirtyMapOptimized(QScreen *screen) : QVNCDirtyMap(screen) {}
- ~QVNCDirtyMapOptimized() {}
-
- void setDirty(int x, int y, bool force = false);
-};
-
-class QRfbRect
-{
-public:
- QRfbRect() {}
- QRfbRect(quint16 _x, quint16 _y, quint16 _w, quint16 _h) {
- x = _x; y = _y; w = _w; h = _h;
- }
-
- void read(QTcpSocket *s);
- void write(QTcpSocket *s) const;
-
- quint16 x;
- quint16 y;
- quint16 w;
- quint16 h;
-};
-
-class QRfbPixelFormat
-{
-public:
- static int size() { return 16; }
-
- void read(QTcpSocket *s);
- void write(QTcpSocket *s);
-
- int bitsPerPixel;
- int depth;
- bool bigEndian;
- bool trueColor;
- int redBits;
- int greenBits;
- int blueBits;
- int redShift;
- int greenShift;
- int blueShift;
-};
-
-class QRfbServerInit
-{
-public:
- QRfbServerInit() { name = 0; }
- ~QRfbServerInit() { delete[] name; }
-
- int size() const { return QRfbPixelFormat::size() + 8 + strlen(name); }
- void setName(const char *n);
-
- void read(QTcpSocket *s);
- void write(QTcpSocket *s);
-
- quint16 width;
- quint16 height;
- QRfbPixelFormat format;
- char *name;
-};
-
-class QRfbSetEncodings
-{
-public:
- bool read(QTcpSocket *s);
-
- quint16 count;
-};
-
-class QRfbFrameBufferUpdateRequest
-{
-public:
- bool read(QTcpSocket *s);
-
- char incremental;
- QRfbRect rect;
-};
-
-class QRfbKeyEvent
-{
-public:
- bool read(QTcpSocket *s);
-
- char down;
- int keycode;
- int unicode;
-};
-
-class QRfbPointerEvent
-{
-public:
- bool read(QTcpSocket *s);
-
- uint buttons;
- quint16 x;
- quint16 y;
-};
-
-class QRfbClientCutText
-{
-public:
- bool read(QTcpSocket *s);
-
- quint32 length;
-};
-
-class QVNCScreenPrivate : public QObject
-{
-public:
- QVNCScreenPrivate(QVNCScreen *parent);
- ~QVNCScreenPrivate();
-
- void setDirty(const QRect &rect, bool force = false);
- void configure();
-
- qreal dpiX;
- qreal dpiY;
- bool doOnScreenSurface;
- QVNCDirtyMap *dirty;
- int refreshRate;
- QVNCServer *vncServer;
-
-#if !defined(QT_NO_QWS_MULTIPROCESS) && !defined(QT_NO_SHAREDMEMORY)
- QSharedMemory shm;
-#endif
-
- QVNCScreen *q_ptr;
-
- bool noDisablePainting;
-};
-
-class QRfbEncoder
-{
-public:
- QRfbEncoder(QVNCServer *s) : server(s) {}
- virtual ~QRfbEncoder() {}
-
- virtual void write() = 0;
-
-protected:
- QVNCServer *server;
-};
-
-class QRfbRawEncoder : public QRfbEncoder
-{
-public:
- QRfbRawEncoder(QVNCServer *s) : QRfbEncoder(s) {}
-
- void write();
-
-private:
- QByteArray buffer;
-};
-
-template <class SRC> class QRfbHextileEncoder;
-
-template <class SRC>
-class QRfbSingleColorHextile
-{
-public:
- QRfbSingleColorHextile(QRfbHextileEncoder<SRC> *e) : encoder(e) {}
- bool read(const uchar *data, int width, int height, int stride);
- void write(QTcpSocket *socket) const;
-
-private:
- QRfbHextileEncoder<SRC> *encoder;
-};
-
-template <class SRC>
-class QRfbDualColorHextile
-{
-public:
- QRfbDualColorHextile(QRfbHextileEncoder<SRC> *e) : encoder(e) {}
- bool read(const uchar *data, int width, int height, int stride);
- void write(QTcpSocket *socket) const;
-
-private:
- struct Rect {
- quint8 xy;
- quint8 wh;
- } Q_PACKED rects[8 * 16];
-
- quint8 numRects;
- QRfbHextileEncoder<SRC> *encoder;
-
-private:
- inline int lastx() const { return rectx(numRects); }
- inline int lasty() const { return recty(numRects); }
- inline int rectx(int r) const { return rects[r].xy >> 4; }
- inline int recty(int r) const { return rects[r].xy & 0x0f; }
- inline int width(int r) const { return (rects[r].wh >> 4) + 1; }
- inline int height(int r) const { return (rects[r].wh & 0x0f) + 1; }
-
- inline void setX(int r, int x) {
- rects[r].xy = (x << 4) | (rects[r].xy & 0x0f);
- }
- inline void setY(int r, int y) {
- rects[r].xy = (rects[r].xy & 0xf0) | y;
- }
- inline void setWidth(int r, int width) {
- rects[r].wh = ((width - 1) << 4) | (rects[r].wh & 0x0f);
- }
- inline void setHeight(int r, int height) {
- rects[r].wh = (rects[r].wh & 0xf0) | (height - 1);
- }
-
- inline void setWidth(int width) { setWidth(numRects, width); }
- inline void setHeight(int height) { setHeight(numRects, height); }
- inline void setX(int x) { setX(numRects, x); }
- inline void setY(int y) { setY(numRects, y); }
- void next();
-};
-
-template <class SRC>
-class QRfbMultiColorHextile
-{
-public:
- QRfbMultiColorHextile(QRfbHextileEncoder<SRC> *e) : encoder(e) {}
- bool read(const uchar *data, int width, int height, int stride);
- void write(QTcpSocket *socket) const;
-
-private:
- inline quint8* rect(int r) {
- return rects.data() + r * (bpp + 2);
- }
- inline const quint8* rect(int r) const {
- return rects.constData() + r * (bpp + 2);
- }
- inline void setX(int r, int x) {
- quint8 *ptr = rect(r) + bpp;
- *ptr = (x << 4) | (*ptr & 0x0f);
- }
- inline void setY(int r, int y) {
- quint8 *ptr = rect(r) + bpp;
- *ptr = (*ptr & 0xf0) | y;
- }
- void setColor(SRC color);
- inline int rectx(int r) const {
- const quint8 *ptr = rect(r) + bpp;
- return *ptr >> 4;
- }
- inline int recty(int r) const {
- const quint8 *ptr = rect(r) + bpp;
- return *ptr & 0x0f;
- }
- inline void setWidth(int r, int width) {
- quint8 *ptr = rect(r) + bpp + 1;
- *ptr = ((width - 1) << 4) | (*ptr & 0x0f);
- }
- inline void setHeight(int r, int height) {
- quint8 *ptr = rect(r) + bpp + 1;
- *ptr = (*ptr & 0xf0) | (height - 1);
- }
-
- bool beginRect();
- void endRect();
-
- static const int maxRectsSize = 16 * 16;
- QVarLengthArray<quint8, maxRectsSize> rects;
-
- quint8 bpp;
- quint8 numRects;
- QRfbHextileEncoder<SRC> *encoder;
-};
-
-template <class SRC>
-class QRfbHextileEncoder : public QRfbEncoder
-{
-public:
- QRfbHextileEncoder(QVNCServer *s);
- void write();
-
-private:
- enum SubEncoding {
- Raw = 1,
- BackgroundSpecified = 2,
- ForegroundSpecified = 4,
- AnySubrects = 8,
- SubrectsColoured = 16
- };
-
- QByteArray buffer;
- QRfbSingleColorHextile<SRC> singleColorHextile;
- QRfbDualColorHextile<SRC> dualColorHextile;
- QRfbMultiColorHextile<SRC> multiColorHextile;
-
- SRC bg;
- SRC fg;
- bool newBg;
- bool newFg;
-
- friend class QRfbSingleColorHextile<SRC>;
- friend class QRfbDualColorHextile<SRC>;
- friend class QRfbMultiColorHextile<SRC>;
-};
-
-class QVNCServer : public QObject
-{
- Q_OBJECT
-public:
- QVNCServer(QVNCScreen *screen);
- QVNCServer(QVNCScreen *screen, int id);
- ~QVNCServer();
-
- void setDirty();
- void setDirtyCursor() { dirtyCursor = true; setDirty(); }
- inline bool isConnected() const { return state == Connected; }
- inline void setRefreshRate(int rate) { refreshRate = rate; }
-
- enum ClientMsg { SetPixelFormat = 0,
- FixColourMapEntries = 1,
- SetEncodings = 2,
- FramebufferUpdateRequest = 3,
- KeyEvent = 4,
- PointerEvent = 5,
- ClientCutText = 6 };
-
- enum ServerMsg { FramebufferUpdate = 0,
- SetColourMapEntries = 1 };
-
- void convertPixels(char *dst, const char *src, int count) const;
-
- inline int clientBytesPerPixel() const {
- return pixelFormat.bitsPerPixel / 8;
- }
-
- inline QVNCScreen* screen() const { return qvnc_screen; }
- inline QVNCDirtyMap* dirtyMap() const { return qvnc_screen->d_ptr->dirty; }
- inline QTcpSocket* clientSocket() const { return client; }
- QImage screenImage() const;
- inline bool doPixelConversion() const { return needConversion; }
-#ifndef QT_NO_QWS_CURSOR
- inline bool hasClientCursor() const { return qvnc_cursor != 0; }
-#endif
-
-private:
- void setPixelFormat();
- void setEncodings();
- void frameBufferUpdateRequest();
- void pointerEvent();
- void keyEvent();
- void clientCutText();
- bool pixelConversionNeeded() const;
-
-private slots:
- void newConnection();
- void readClient();
- void checkUpdate();
- void discardClient();
-
-private:
- void init(uint port);
- enum ClientState { Unconnected, Protocol, Init, Connected };
- QTimer *timer;
- QTcpServer *serverSocket;
- QTcpSocket *client;
- ClientState state;
- quint8 msgType;
- bool handleMsg;
- QRfbPixelFormat pixelFormat;
- Qt::KeyboardModifiers keymod;
- int encodingsPending;
- int cutTextPending;
- uint supportCopyRect : 1;
- uint supportRRE : 1;
- uint supportCoRRE : 1;
- uint supportHextile : 1;
- uint supportZRLE : 1;
- uint supportCursor : 1;
- uint supportDesktopSize : 1;
- bool wantUpdate;
- bool sameEndian;
- bool needConversion;
-#if Q_BYTE_ORDER == Q_BIG_ENDIAN
- bool swapBytes;
-#endif
- bool dirtyCursor;
- int refreshRate;
- QVNCScreen *qvnc_screen;
-#ifndef QT_NO_QWS_CURSOR
- QVNCClientCursor *qvnc_cursor;
-#endif
-
- QRfbEncoder *encoder;
-};
-
-
-QT_END_NAMESPACE
-#endif // QT_NO_QWS_VNC
-#endif // QSCREENVNC_P_H
diff --git a/src/plugins/gfxdrivers/vnc/qscreenvnc_qws.cpp b/src/plugins/gfxdrivers/vnc/qscreenvnc_qws.cpp
deleted file mode 100644
index 3ddedc63ea..0000000000
--- a/src/plugins/gfxdrivers/vnc/qscreenvnc_qws.cpp
+++ /dev/null
@@ -1,2338 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qscreenvnc_qws.h"
-
-#ifndef QT_NO_QWS_VNC
-
-#include "qscreenvnc_p.h"
-#include "qwindowsystem_qws.h"
-#include "qwsdisplay_qws.h"
-#include "qscreendriverfactory_qws.h"
-#include <QtCore/qtimer.h>
-#include <QtCore/qregexp.h>
-#include <QtGui/qwidget.h>
-#include <QtGui/qpolygon.h>
-#include <QtGui/qpainter.h>
-#include <qdebug.h>
-#include <private/qwindowsurface_qws_p.h>
-#include <private/qwssignalhandler_p.h>
-#include <private/qwidget_p.h>
-#include <private/qdrawhelper_p.h>
-
-#include <stdlib.h>
-
-QT_BEGIN_NAMESPACE
-
-//#define QT_QWS_VNC_DEBUG
-
-extern QString qws_qtePipeFilename();
-
-#ifndef QT_NO_QWS_CURSOR
-
-QVNCCursor::QVNCCursor(QVNCScreen *s)
- : screen(s)
-{
- if (qt_screencursor)
- setScreenCursor(qt_screencursor);
- else
- hwaccel = true;
-}
-
-QVNCCursor::~QVNCCursor()
-{
- if (screenCursor())
- qt_screencursor = screenCursor();
-}
-
-void QVNCCursor::setDirty(const QRect &r) const
-{
- screen->d_ptr->setDirty(r, true);
-}
-
-void QVNCCursor::hide()
-{
- QProxyScreenCursor::hide();
- if (enable)
- setDirty(boundingRect());
-}
-
-void QVNCCursor::show()
-{
- QProxyScreenCursor::show();
- if (enable)
- setDirty(boundingRect());
-}
-
-void QVNCCursor::set(const QImage &image, int hotx, int hoty)
-{
- QRegion dirty = boundingRect();
- QProxyScreenCursor::set(image, hotx, hoty);
- dirty |= boundingRect();
- if (enable && hwaccel && !screen->d_ptr->vncServer->hasClientCursor()) {
- const QVector<QRect> rects = dirty.rects();
- for (int i = 0; i < rects.size(); ++i)
- setDirty(rects.at(i));
- }
-}
-
-void QVNCCursor::move(int x, int y)
-{
- if (enable && hwaccel && !screen->d_ptr->vncServer->hasClientCursor()) {
- QRegion dirty = boundingRect();
- QProxyScreenCursor::move(x, y);
- dirty |= boundingRect();
- if (enable) {
- const QVector<QRect> rects = dirty.rects();
- for (int i = 0; i < rects.size(); ++i)
- setDirty(rects.at(i));
- }
- } else {
- QProxyScreenCursor::move(x, y);
- }
-}
-
-QVNCClientCursor::QVNCClientCursor(QVNCServer *s)
- : server(s)
-{
- setScreenCursor(qt_screencursor);
- Q_ASSERT(hwaccel);
- qt_screencursor = this; // hw: XXX
-
- set(image(), hotspot.x(), hotspot.y());
-}
-
-QVNCClientCursor::~QVNCClientCursor()
-{
- qt_screencursor = screenCursor();
-}
-
-void QVNCClientCursor::set(const QImage &image, int hotx, int hoty)
-{
- QScreenCursor::set(image, hotx, hoty);
- server->setDirtyCursor();
-}
-
-void QVNCClientCursor::write() const
-{
- QTcpSocket *socket = server->clientSocket();
-
- // FramebufferUpdate header
- {
- const quint16 tmp[6] = { htons(0),
- htons(1),
- htons(hotspot.x()), htons(hotspot.y()),
- htons(cursor.width()),
- htons(cursor.height()) };
- socket->write((char*)tmp, sizeof(tmp));
-
- const quint32 encoding = htonl(-239);
- socket->write((char*)(&encoding), sizeof(encoding));
- }
-
- if (cursor.isNull())
- return;
-
- // write pixels
- Q_ASSERT(cursor.hasAlphaChannel());
- const QImage img = cursor.convertToFormat(server->screen()->pixelFormat());
- const int n = server->clientBytesPerPixel() * img.width();
- char *buffer = new char[n];
- for (int i = 0; i < img.height(); ++i) {
- server->convertPixels(buffer, (const char*)img.scanLine(i), img.width());
- socket->write(buffer, n);
- }
- delete[] buffer;
-
- // write mask
- const QImage bitmap = cursor.createAlphaMask().convertToFormat(QImage::Format_Mono);
- Q_ASSERT(bitmap.depth() == 1);
- Q_ASSERT(bitmap.size() == img.size());
- const int width = (bitmap.width() + 7) / 8;
- for (int i = 0; i < bitmap.height(); ++i)
- socket->write((const char*)bitmap.scanLine(i), width);
-}
-
-#endif // QT_NO_QWS_CURSOR
-
-QVNCScreenPrivate::QVNCScreenPrivate(QVNCScreen *parent)
- : dpiX(72), dpiY(72), doOnScreenSurface(false), refreshRate(25),
- vncServer(0), q_ptr(parent), noDisablePainting(false)
-{
-#ifdef QT_BUILD_INTERNAL
- noDisablePainting = (qgetenv("QT_VNC_NO_DISABLEPAINTING").toInt() > 0);
-#endif
-#ifndef QT_NO_QWS_SIGNALHANDLER
- QWSSignalHandler::instance()->addObject(this);
-#endif
-}
-
-QVNCScreenPrivate::~QVNCScreenPrivate()
-{
-#if defined(QT_NO_QWS_MULTIPROCESS) || defined(QT_NO_SHAREDMEMORY)
- if (q_ptr->screen())
- return;
-
- delete[] q_ptr->data;
- q_ptr->data = 0;
-#else
- shm.detach();
-#endif
-}
-
-void QVNCScreenPrivate::configure()
-{
- if (q_ptr->screen())
- return;
-
- q_ptr->lstep = q_ptr->dw * ((q_ptr->d + 7) / 8);
- q_ptr->size = q_ptr->h * q_ptr->lstep;
- q_ptr->mapsize = q_ptr->size;
- q_ptr->physWidth = qRound(q_ptr->dw * qreal(25.4) / dpiX);
- q_ptr->physHeight = qRound(q_ptr->dh * qreal(25.4) / dpiY);
-
- switch (q_ptr->d) {
- case 1:
- q_ptr->setPixelFormat(QImage::Format_Mono); //### LSB???
- break;
- case 8:
- q_ptr->setPixelFormat(QImage::Format_Indexed8);
- break;
- case 12:
- q_ptr->setPixelFormat(QImage::Format_RGB444);
- break;
- case 15:
- q_ptr->setPixelFormat(QImage::Format_RGB555);
- break;
- case 16:
- q_ptr->setPixelFormat(QImage::Format_RGB16);
- break;
- case 18:
- q_ptr->setPixelFormat(QImage::Format_RGB666);
- break;
- case 24:
- q_ptr->setPixelFormat(QImage::Format_RGB888);
- break;
- case 32:
- q_ptr->setPixelFormat(QImage::Format_ARGB32_Premultiplied);
- break;
- }
-
-#if !defined(QT_NO_QWS_MULTIPROCESS) && !defined(QT_NO_SHAREDMEMORY)
- if (q_ptr->size != shm.size()) {
- shm.detach();
- const QString key = qws_qtePipeFilename() +
- QString().sprintf("_vnc_%d_%d",
- q_ptr->displayId, q_ptr->size);
- shm.setKey(key);
- if (QApplication::type() == QApplication::GuiServer) {
- if (!shm.create(q_ptr->size)) {
- qWarning() << "QVNCScreen could not create shared memory:"
- << shm.errorString();
- if (!shm.attach()) {
- qWarning() << "QVNCScreen could not attach to shared memory:"
- << shm.errorString();
- }
- }
- } else if (!shm.attach()) {
- qWarning() << "QVNCScreen could not attach to shared memory:"
- << shm.errorString();
- }
- q_ptr->data = reinterpret_cast<uchar*>(shm.data());
- }
-#else
- if (q_ptr->data)
- delete[] q_ptr->data;
- q_ptr->data = new uchar[q_ptr->size];
-#endif
-}
-
-//===========================================================================
-
-static const struct {
- int keysym;
- int keycode;
-} keyMap[] = {
- { 0xff08, Qt::Key_Backspace },
- { 0xff09, Qt::Key_Tab },
- { 0xff0d, Qt::Key_Return },
- { 0xff1b, Qt::Key_Escape },
- { 0xff63, Qt::Key_Insert },
- { 0xffff, Qt::Key_Delete },
- { 0xff50, Qt::Key_Home },
- { 0xff57, Qt::Key_End },
- { 0xff55, Qt::Key_PageUp },
- { 0xff56, Qt::Key_PageDown },
- { 0xff51, Qt::Key_Left },
- { 0xff52, Qt::Key_Up },
- { 0xff53, Qt::Key_Right },
- { 0xff54, Qt::Key_Down },
- { 0xffbe, Qt::Key_F1 },
- { 0xffbf, Qt::Key_F2 },
- { 0xffc0, Qt::Key_F3 },
- { 0xffc1, Qt::Key_F4 },
- { 0xffc2, Qt::Key_F5 },
- { 0xffc3, Qt::Key_F6 },
- { 0xffc4, Qt::Key_F7 },
- { 0xffc5, Qt::Key_F8 },
- { 0xffc6, Qt::Key_F9 },
- { 0xffc7, Qt::Key_F10 },
- { 0xffc8, Qt::Key_F11 },
- { 0xffc9, Qt::Key_F12 },
- { 0xffe1, Qt::Key_Shift },
- { 0xffe2, Qt::Key_Shift },
- { 0xffe3, Qt::Key_Control },
- { 0xffe4, Qt::Key_Control },
- { 0xffe7, Qt::Key_Meta },
- { 0xffe8, Qt::Key_Meta },
- { 0xffe9, Qt::Key_Alt },
- { 0xffea, Qt::Key_Alt },
-
- { 0xffb0, Qt::Key_0 },
- { 0xffb1, Qt::Key_1 },
- { 0xffb2, Qt::Key_2 },
- { 0xffb3, Qt::Key_3 },
- { 0xffb4, Qt::Key_4 },
- { 0xffb5, Qt::Key_5 },
- { 0xffb6, Qt::Key_6 },
- { 0xffb7, Qt::Key_7 },
- { 0xffb8, Qt::Key_8 },
- { 0xffb9, Qt::Key_9 },
-
- { 0xff8d, Qt::Key_Return },
- { 0xffaa, Qt::Key_Asterisk },
- { 0xffab, Qt::Key_Plus },
- { 0xffad, Qt::Key_Minus },
- { 0xffae, Qt::Key_Period },
- { 0xffaf, Qt::Key_Slash },
-
- { 0xff95, Qt::Key_Home },
- { 0xff96, Qt::Key_Left },
- { 0xff97, Qt::Key_Up },
- { 0xff98, Qt::Key_Right },
- { 0xff99, Qt::Key_Down },
- { 0xff9a, Qt::Key_PageUp },
- { 0xff9b, Qt::Key_PageDown },
- { 0xff9c, Qt::Key_End },
- { 0xff9e, Qt::Key_Insert },
- { 0xff9f, Qt::Key_Delete },
-
- { 0, 0 }
-};
-
-void QRfbRect::read(QTcpSocket *s)
-{
- quint16 buf[4];
- s->read((char*)buf, 8);
- x = ntohs(buf[0]);
- y = ntohs(buf[1]);
- w = ntohs(buf[2]);
- h = ntohs(buf[3]);
-}
-
-void QRfbRect::write(QTcpSocket *s) const
-{
- quint16 buf[4];
- buf[0] = htons(x);
- buf[1] = htons(y);
- buf[2] = htons(w);
- buf[3] = htons(h);
- s->write((char*)buf, 8);
-}
-
-void QRfbPixelFormat::read(QTcpSocket *s)
-{
- char buf[16];
- s->read(buf, 16);
- bitsPerPixel = buf[0];
- depth = buf[1];
- bigEndian = buf[2];
- trueColor = buf[3];
-
- quint16 a = ntohs(*(quint16 *)(buf + 4));
- redBits = 0;
- while (a) { a >>= 1; redBits++; }
-
- a = ntohs(*(quint16 *)(buf + 6));
- greenBits = 0;
- while (a) { a >>= 1; greenBits++; }
-
- a = ntohs(*(quint16 *)(buf + 8));
- blueBits = 0;
- while (a) { a >>= 1; blueBits++; }
-
- redShift = buf[10];
- greenShift = buf[11];
- blueShift = buf[12];
-}
-
-void QRfbPixelFormat::write(QTcpSocket *s)
-{
- char buf[16];
- buf[0] = bitsPerPixel;
- buf[1] = depth;
- buf[2] = bigEndian;
- buf[3] = trueColor;
-
- quint16 a = 0;
- for (int i = 0; i < redBits; i++) a = (a << 1) | 1;
- *(quint16 *)(buf + 4) = htons(a);
-
- a = 0;
- for (int i = 0; i < greenBits; i++) a = (a << 1) | 1;
- *(quint16 *)(buf + 6) = htons(a);
-
- a = 0;
- for (int i = 0; i < blueBits; i++) a = (a << 1) | 1;
- *(quint16 *)(buf + 8) = htons(a);
-
- buf[10] = redShift;
- buf[11] = greenShift;
- buf[12] = blueShift;
- s->write(buf, 16);
-}
-
-
-void QRfbServerInit::setName(const char *n)
-{
- delete[] name;
- name = new char [strlen(n) + 1];
- strcpy(name, n);
-}
-
-void QRfbServerInit::read(QTcpSocket *s)
-{
- s->read((char *)&width, 2);
- width = ntohs(width);
- s->read((char *)&height, 2);
- height = ntohs(height);
- format.read(s);
-
- quint32 len;
- s->read((char *)&len, 4);
- len = ntohl(len);
-
- name = new char [len + 1];
- s->read(name, len);
- name[len] = '\0';
-}
-
-void QRfbServerInit::write(QTcpSocket *s)
-{
- quint16 t = htons(width);
- s->write((char *)&t, 2);
- t = htons(height);
- s->write((char *)&t, 2);
- format.write(s);
- quint32 len = strlen(name);
- len = htonl(len);
- s->write((char *)&len, 4);
- s->write(name, strlen(name));
-}
-
-bool QRfbSetEncodings::read(QTcpSocket *s)
-{
- if (s->bytesAvailable() < 3)
- return false;
-
- char tmp;
- s->read(&tmp, 1); // padding
- s->read((char *)&count, 2);
- count = ntohs(count);
-
- return true;
-}
-
-bool QRfbFrameBufferUpdateRequest::read(QTcpSocket *s)
-{
- if (s->bytesAvailable() < 9)
- return false;
-
- s->read(&incremental, 1);
- rect.read(s);
-
- return true;
-}
-
-bool QRfbKeyEvent::read(QTcpSocket *s)
-{
- if (s->bytesAvailable() < 7)
- return false;
-
- s->read(&down, 1);
- quint16 tmp;
- s->read((char *)&tmp, 2); // padding
-
- quint32 key;
- s->read((char *)&key, 4);
- key = ntohl(key);
-
- unicode = 0;
- keycode = 0;
- int i = 0;
- while (keyMap[i].keysym && !keycode) {
- if (keyMap[i].keysym == (int)key)
- keycode = keyMap[i].keycode;
- i++;
- }
-
- if (keycode >= ' ' && keycode <= '~')
- unicode = keycode;
-
- if (!keycode) {
- if (key <= 0xff) {
- unicode = key;
- if (key >= 'a' && key <= 'z')
- keycode = Qt::Key_A + key - 'a';
- else if (key >= ' ' && key <= '~')
- keycode = Qt::Key_Space + key - ' ';
- }
- }
-
- return true;
-}
-
-bool QRfbPointerEvent::read(QTcpSocket *s)
-{
- if (s->bytesAvailable() < 5)
- return false;
-
- char buttonMask;
- s->read(&buttonMask, 1);
- buttons = 0;
- if (buttonMask & 1)
- buttons |= Qt::LeftButton;
- if (buttonMask & 2)
- buttons |= Qt::MidButton;
- if (buttonMask & 4)
- buttons |= Qt::RightButton;
-
- quint16 tmp;
- s->read((char *)&tmp, 2);
- x = ntohs(tmp);
- s->read((char *)&tmp, 2);
- y = ntohs(tmp);
-
- return true;
-}
-
-bool QRfbClientCutText::read(QTcpSocket *s)
-{
- if (s->bytesAvailable() < 7)
- return false;
-
- char tmp[3];
- s->read(tmp, 3); // padding
- s->read((char *)&length, 4);
- length = ntohl(length);
-
- return true;
-}
-
-//===========================================================================
-
-QVNCServer::QVNCServer(QVNCScreen *screen)
- : qvnc_screen(screen)
-{
- init(5900);
-}
-
-QVNCServer::QVNCServer(QVNCScreen *screen, int id)
- : qvnc_screen(screen)
-{
- init(5900 + id);
-}
-
-void QVNCServer::init(uint port)
-{
- handleMsg = false;
- client = 0;
- encodingsPending = 0;
- cutTextPending = 0;
- keymod = 0;
- state = Unconnected;
- dirtyCursor = false;
-
- refreshRate = 25;
- timer = new QTimer(this);
- timer->setSingleShot(true);
- connect(timer, SIGNAL(timeout()), this, SLOT(checkUpdate()));
-
- serverSocket = new QTcpServer(this);
- if (!serverSocket->listen(QHostAddress::Any, port))
- qDebug() << "QVNCServer could not connect:" << serverSocket->errorString();
- else
- qDebug("QVNCServer created on port %d", port);
-
- connect(serverSocket, SIGNAL(newConnection()), this, SLOT(newConnection()));
-
-#ifndef QT_NO_QWS_CURSOR
- qvnc_cursor = 0;
-#endif
- encoder = 0;
-}
-
-QVNCServer::~QVNCServer()
-{
- delete encoder;
- encoder = 0;
- delete client;
- client = 0;
-#ifndef QT_NO_QWS_CURSOR
- delete qvnc_cursor;
- qvnc_cursor = 0;
-#endif
-}
-
-void QVNCServer::setDirty()
-{
- if (state == Connected && !timer->isActive() &&
- ((dirtyMap()->numDirty > 0) || dirtyCursor)) {
- timer->start();
- }
-}
-
-void QVNCServer::newConnection()
-{
- if (client)
- delete client;
-
- client = serverSocket->nextPendingConnection();
- connect(client,SIGNAL(readyRead()),this,SLOT(readClient()));
- connect(client,SIGNAL(disconnected()),this,SLOT(discardClient()));
- handleMsg = false;
- encodingsPending = 0;
- cutTextPending = 0;
- supportHextile = false;
- wantUpdate = false;
-
- timer->start(1000 / refreshRate);
- dirtyMap()->reset();
-
- // send protocol version
- const char *proto = "RFB 003.003\n";
- client->write(proto, 12);
- state = Protocol;
-
- if (!qvnc_screen->screen() && !qvnc_screen->d_ptr->noDisablePainting)
- QWSServer::instance()->enablePainting(true);
-}
-
-void QVNCServer::readClient()
-{
- switch (state) {
- case Protocol:
- if (client->bytesAvailable() >= 12) {
- char proto[13];
- client->read(proto, 12);
- proto[12] = '\0';
- qDebug("Client protocol version %s", proto);
- // No authentication
- quint32 auth = htonl(1);
- client->write((char *) &auth, sizeof(auth));
- state = Init;
- }
- break;
-
- case Init:
- if (client->bytesAvailable() >= 1) {
- quint8 shared;
- client->read((char *) &shared, 1);
-
- // Server Init msg
- QRfbServerInit sim;
- QRfbPixelFormat &format = sim.format;
- switch (qvnc_screen->depth()) {
- case 32:
- format.bitsPerPixel = 32;
- format.depth = 32;
- format.bigEndian = 0;
- format.trueColor = true;
- format.redBits = 8;
- format.greenBits = 8;
- format.blueBits = 8;
- format.redShift = 16;
- format.greenShift = 8;
- format.blueShift = 0;
- break;
-
- case 24:
- format.bitsPerPixel = 24;
- format.depth = 24;
- format.bigEndian = 0;
- format.trueColor = true;
- format.redBits = 8;
- format.greenBits = 8;
- format.blueBits = 8;
- format.redShift = 16;
- format.greenShift = 8;
- format.blueShift = 0;
- break;
-
- case 18:
- format.bitsPerPixel = 24;
- format.depth = 18;
- format.bigEndian = 0;
- format.trueColor = true;
- format.redBits = 6;
- format.greenBits = 6;
- format.blueBits = 6;
- format.redShift = 12;
- format.greenShift = 6;
- format.blueShift = 0;
- break;
-
- case 16:
- format.bitsPerPixel = 16;
- format.depth = 16;
- format.bigEndian = 0;
- format.trueColor = true;
- format.redBits = 5;
- format.greenBits = 6;
- format.blueBits = 5;
- format.redShift = 11;
- format.greenShift = 5;
- format.blueShift = 0;
- break;
-
- case 15:
- format.bitsPerPixel = 16;
- format.depth = 15;
- format.bigEndian = 0;
- format.trueColor = true;
- format.redBits = 5;
- format.greenBits = 5;
- format.blueBits = 5;
- format.redShift = 10;
- format.greenShift = 5;
- format.blueShift = 0;
- break;
-
- case 12:
- format.bitsPerPixel = 16;
- format.depth = 12;
- format.bigEndian = 0;
- format.trueColor = true;
- format.redBits = 4;
- format.greenBits = 4;
- format.blueBits = 4;
- format.redShift = 8;
- format.greenShift = 4;
- format.blueShift = 0;
- break;
-
- case 8:
- case 4:
- format.bitsPerPixel = 8;
- format.depth = 8;
- format.bigEndian = 0;
- format.trueColor = false;
- format.redBits = 0;
- format.greenBits = 0;
- format.blueBits = 0;
- format.redShift = 0;
- format.greenShift = 0;
- format.blueShift = 0;
- break;
-
- default:
- qDebug("QVNC cannot drive depth %d", qvnc_screen->depth());
- discardClient();
- return;
- }
- sim.width = qvnc_screen->deviceWidth();
- sim.height = qvnc_screen->deviceHeight();
- sim.setName("Qt for Embedded Linux VNC Server");
- sim.write(client);
- state = Connected;
- }
- break;
-
- case Connected:
- do {
- if (!handleMsg) {
- client->read((char *)&msgType, 1);
- handleMsg = true;
- }
- if (handleMsg) {
- switch (msgType ) {
- case SetPixelFormat:
- setPixelFormat();
- break;
- case FixColourMapEntries:
- qDebug("Not supported: FixColourMapEntries");
- handleMsg = false;
- break;
- case SetEncodings:
- setEncodings();
- break;
- case FramebufferUpdateRequest:
- frameBufferUpdateRequest();
- break;
- case KeyEvent:
- keyEvent();
- break;
- case PointerEvent:
- pointerEvent();
- break;
- case ClientCutText:
- clientCutText();
- break;
- default:
- qDebug("Unknown message type: %d", (int)msgType);
- handleMsg = false;
- }
- }
- } while (!handleMsg && client->bytesAvailable());
- break;
- default:
- break;
- }
-}
-
-#if Q_BYTE_ORDER == Q_BIG_ENDIAN
-bool QVNCScreen::swapBytes() const
-{
- if (depth() != 16)
- return false;
-
- if (screen())
- return screen()->frameBufferLittleEndian();
- return frameBufferLittleEndian();
-}
-#endif
-
-void QVNCServer::setPixelFormat()
-{
- if (client->bytesAvailable() >= 19) {
- char buf[3];
- client->read(buf, 3); // just padding
- pixelFormat.read(client);
-#ifdef QT_QWS_VNC_DEBUG
- qDebug("Want format: %d %d %d %d %d %d %d %d %d %d",
- int(pixelFormat.bitsPerPixel),
- int(pixelFormat.depth),
- int(pixelFormat.bigEndian),
- int(pixelFormat.trueColor),
- int(pixelFormat.redBits),
- int(pixelFormat.greenBits),
- int(pixelFormat.blueBits),
- int(pixelFormat.redShift),
- int(pixelFormat.greenShift),
- int(pixelFormat.blueShift));
-#endif
- if (!pixelFormat.trueColor) {
- qDebug("Can only handle true color clients");
- discardClient();
- }
- handleMsg = false;
- sameEndian = (QSysInfo::ByteOrder == QSysInfo::BigEndian) == !!pixelFormat.bigEndian;
- needConversion = pixelConversionNeeded();
-#if Q_BYTE_ORDER == Q_BIG_ENDIAN
- swapBytes = qvnc_screen->swapBytes();
-#endif
- }
-}
-
-void QVNCServer::setEncodings()
-{
- QRfbSetEncodings enc;
-
- if (!encodingsPending && enc.read(client)) {
- encodingsPending = enc.count;
- if (!encodingsPending)
- handleMsg = false;
- }
-
- if (encoder) {
- delete encoder;
- encoder = 0;
- }
-
- enum Encodings {
- Raw = 0,
- CopyRect = 1,
- RRE = 2,
- CoRRE = 4,
- Hextile = 5,
- ZRLE = 16,
- Cursor = -239,
- DesktopSize = -223
- };
-
- if (encodingsPending && (unsigned)client->bytesAvailable() >=
- encodingsPending * sizeof(quint32)) {
- for (int i = 0; i < encodingsPending; ++i) {
- qint32 enc;
- client->read((char *)&enc, sizeof(qint32));
- enc = ntohl(enc);
-#ifdef QT_QWS_VNC_DEBUG
- qDebug("QVNCServer::setEncodings: %d", enc);
-#endif
- switch (enc) {
- case Raw:
- if (!encoder) {
- encoder = new QRfbRawEncoder(this);
-#ifdef QT_QWS_VNC_DEBUG
- qDebug("QVNCServer::setEncodings: using raw");
-#endif
- }
- break;
- case CopyRect:
- supportCopyRect = true;
- break;
- case RRE:
- supportRRE = true;
- break;
- case CoRRE:
- supportCoRRE = true;
- break;
- case Hextile:
- supportHextile = true;
- if (encoder)
- break;
- switch (qvnc_screen->depth()) {
-#ifdef QT_QWS_DEPTH_8
- case 8:
- encoder = new QRfbHextileEncoder<quint8>(this);
- break;
-#endif
-#ifdef QT_QWS_DEPTH_12
- case 12:
- encoder = new QRfbHextileEncoder<qrgb444>(this);
- break;
-#endif
-#ifdef QT_QWS_DEPTH_15
- case 15:
- encoder = new QRfbHextileEncoder<qrgb555>(this);
- break;
-#endif
-#ifdef QT_QWS_DEPTH_16
- case 16:
- encoder = new QRfbHextileEncoder<quint16>(this);
- break;
-#endif
-#ifdef QT_QWS_DEPTH_18
- case 18:
- encoder = new QRfbHextileEncoder<qrgb666>(this);
- break;
-#endif
-#ifdef QT_QWS_DEPTH_24
- case 24:
- encoder = new QRfbHextileEncoder<qrgb888>(this);
- break;
-#endif
-#ifdef QT_QWS_DEPTH_32
- case 32:
- encoder = new QRfbHextileEncoder<quint32>(this);
- break;
-#endif
- default:
- break;
- }
-#ifdef QT_QWS_VNC_DEBUG
- qDebug("QVNCServer::setEncodings: using hextile");
-#endif
- break;
- case ZRLE:
- supportZRLE = true;
- break;
- case Cursor:
- supportCursor = true;
-#ifndef QT_NO_QWS_CURSOR
- if (!qvnc_screen->screen() || qt_screencursor->isAccelerated()) {
- delete qvnc_cursor;
- qvnc_cursor = new QVNCClientCursor(this);
- }
-#endif
- break;
- case DesktopSize:
- supportDesktopSize = true;
- break;
- default:
- break;
- }
- }
- handleMsg = false;
- encodingsPending = 0;
- }
-
- if (!encoder) {
- encoder = new QRfbRawEncoder(this);
-#ifdef QT_QWS_VNC_DEBUG
- qDebug("QVNCServer::setEncodings: fallback using raw");
-#endif
- }
-}
-
-void QVNCServer::frameBufferUpdateRequest()
-{
- QRfbFrameBufferUpdateRequest ev;
-
- if (ev.read(client)) {
- if (!ev.incremental) {
- QRect r(ev.rect.x, ev.rect.y, ev.rect.w, ev.rect.h);
- r.translate(qvnc_screen->offset());
- qvnc_screen->d_ptr->setDirty(r, true);
- }
- wantUpdate = true;
- checkUpdate();
- handleMsg = false;
- }
-}
-
-void QVNCServer::pointerEvent()
-{
- QRfbPointerEvent ev;
- if (ev.read(client)) {
- const QPoint offset = qvnc_screen->offset();
- QWSServer::sendMouseEvent(offset + QPoint(ev.x, ev.y), ev.buttons);
- handleMsg = false;
- }
-}
-
-void QVNCServer::keyEvent()
-{
- QRfbKeyEvent ev;
-
- if (ev.read(client)) {
- if (ev.keycode == Qt::Key_Shift)
- keymod = ev.down ? keymod | Qt::ShiftModifier :
- keymod & ~Qt::ShiftModifier;
- else if (ev.keycode == Qt::Key_Control)
- keymod = ev.down ? keymod | Qt::ControlModifier :
- keymod & ~Qt::ControlModifier;
- else if (ev.keycode == Qt::Key_Alt)
- keymod = ev.down ? keymod | Qt::AltModifier :
- keymod & ~Qt::AltModifier;
- if (ev.unicode || ev.keycode)
- QWSServer::sendKeyEvent(ev.unicode, ev.keycode, keymod, ev.down, false);
- handleMsg = false;
- }
-}
-
-void QVNCServer::clientCutText()
-{
- QRfbClientCutText ev;
-
- if (cutTextPending == 0 && ev.read(client)) {
- cutTextPending = ev.length;
- if (!cutTextPending)
- handleMsg = false;
- }
-
- if (cutTextPending && client->bytesAvailable() >= cutTextPending) {
- char *text = new char [cutTextPending+1];
- client->read(text, cutTextPending);
- delete [] text;
- cutTextPending = 0;
- handleMsg = false;
- }
-}
-
-// stride in bytes
-template <class SRC>
-bool QRfbSingleColorHextile<SRC>::read(const uchar *data,
- int width, int height, int stride)
-{
- const int depth = encoder->server->screen()->depth();
- if (width % (depth / 8)) // hw: should rather fallback to simple loop
- return false;
-
- static int alwaysFalse = qgetenv("QT_VNC_NOCHECKFILL").toInt();
- if (alwaysFalse)
- return false;
-
- switch (depth) {
- case 4: {
- const quint8 *data8 = reinterpret_cast<const quint8*>(data);
- if ((data8[0] & 0xf) != (data8[0] >> 4))
- return false;
- width /= 2;
- } // fallthrough
- case 8: {
- const quint8 *data8 = reinterpret_cast<const quint8*>(data);
- if (data8[0] != data8[1])
- return false;
- width /= 2;
- } // fallthrough
- case 12:
- case 15:
- case 16: {
- const quint16 *data16 = reinterpret_cast<const quint16*>(data);
- if (data16[0] != data16[1])
- return false;
- width /= 2;
- } // fallthrough
- case 18:
- case 24:
- case 32: {
- const quint32 *data32 = reinterpret_cast<const quint32*>(data);
- const quint32 first = data32[0];
- const int linestep = (stride / sizeof(quint32)) - width;
- for (int y = 0; y < height; ++y) {
- for (int x = 0; x < width; ++x) {
- if (*(data32++) != first)
- return false;
- }
- data32 += linestep;
- }
- break;
- }
- default:
- return false;
- }
-
- SRC color = reinterpret_cast<const SRC*>(data)[0];
- encoder->newBg |= (color != encoder->bg);
- encoder->bg = color;
- return true;
-}
-
-template <class SRC>
-void QRfbSingleColorHextile<SRC>::write(QTcpSocket *socket) const
-{
- if (true || encoder->newBg) {
- const int bpp = encoder->server->clientBytesPerPixel();
- const int padding = 3;
- QVarLengthArray<char> buffer(padding + 1 + bpp);
- buffer[padding] = 2; // BackgroundSpecified
- encoder->server->convertPixels(buffer.data() + padding + 1,
- reinterpret_cast<char*>(&encoder->bg),
- 1);
- socket->write(buffer.data() + padding, bpp + 1);
-// encoder->newBg = false;
- } else {
- char subenc = 0;
- socket->write(&subenc, 1);
- }
-}
-
-template <class SRC>
-bool QRfbDualColorHextile<SRC>::read(const uchar *data,
- int width, int height, int stride)
-{
- const SRC *ptr = reinterpret_cast<const SRC*>(data);
- const int linestep = (stride / sizeof(SRC)) - width;
-
- SRC c1;
- SRC c2 = 0;
- int n1 = 0;
- int n2 = 0;
- int x = 0;
- int y = 0;
-
- c1 = *ptr;
-
- // find second color
- while (y < height) {
- while (x < width) {
- if (*ptr == c1) {
- ++n1;
- } else {
- c2 = *ptr;
- goto found_second_color;
- }
- ++ptr;
- ++x;
- }
- x = 0;
- ptr += linestep;
- ++y;
- }
-
-found_second_color:
- // finish counting
- while (y < height) {
- while (x < width) {
- if (*ptr == c1) {
- ++n1;
- } else if (*ptr == c2) {
- ++n2;
- } else {
- return false;
- }
- ++ptr;
- ++x;
- }
- x = 0;
- ptr += linestep;
- ++y;
- }
-
- if (n2 > n1) {
- const quint32 tmpC = c1;
- c1 = c2;
- c2 = tmpC;
- }
-
- encoder->newBg |= (c1 != encoder->bg);
- encoder->newFg |= (c2 != encoder->fg);
-
- encoder->bg = c1;
- encoder->fg = c2;
-
- // create map
- bool inRect = false;
- numRects = 0;
- ptr = reinterpret_cast<const SRC*>(data);
- for (y = 0; y < height; ++y) {
- for (x = 0; x < width; ++x) {
- if (inRect && *ptr == encoder->bg) {
- // rect finished
- setWidth(x - lastx());
- next();
- inRect = false;
- } else if (!inRect && *ptr == encoder->fg) {
- // rect start
- setX(x);
- setY(y);
- setHeight(1);
- inRect = true;
- }
- ++ptr;
- }
- if (inRect) {
- // finish rect
- setWidth(width - lastx());
- next();
- inRect = false;
- }
- ptr += linestep;
- }
-
- return true;
-}
-
-template <class SRC>
-void QRfbDualColorHextile<SRC>::write(QTcpSocket *socket) const
-{
- const int bpp = encoder->server->clientBytesPerPixel();
- const int padding = 3;
- QVarLengthArray<char> buffer(padding + 2 * bpp + sizeof(char) + sizeof(numRects));
- char &subenc = buffer[padding];
- int n = padding + sizeof(subenc);
-
- subenc = 0x8; // AnySubrects
-
- if (encoder->newBg) {
- subenc |= 0x2; // Background
- encoder->server->convertPixels(buffer.data() + n, (char*)&encoder->bg, 1);
- n += bpp;
-// encoder->newBg = false;
- }
-
- if (encoder->newFg) {
- subenc |= 0x4; // Foreground
- encoder->server->convertPixels(buffer.data() + n, (char*)&encoder->fg, 1);
- n += bpp;
-// encoder->newFg = false;
- }
- buffer[n] = numRects;
- n += sizeof(numRects);
-
- socket->write(buffer.data() + padding, n - padding);
- socket->write((char*)rects, numRects * sizeof(Rect));
-}
-
-template <class SRC>
-void QRfbDualColorHextile<SRC>::next()
-{
- for (int r = numRects - 1; r >= 0; --r) {
- if (recty(r) == lasty())
- continue;
- if (recty(r) < lasty() - 1) // only search previous scanline
- break;
- if (rectx(r) == lastx() && width(r) == width(numRects)) {
- ++rects[r].wh;
- return;
- }
- }
- ++numRects;
-}
-
-template <class SRC>
-inline void QRfbMultiColorHextile<SRC>::setColor(SRC color)
-{
- encoder->server->convertPixels(reinterpret_cast<char*>(rect(numRects)),
- (const char*)&color, 1);
-}
-
-template <class SRC>
-inline bool QRfbMultiColorHextile<SRC>::beginRect()
-{
- if ((rects.size() + bpp + 2) > maxRectsSize)
- return false;
- rects.resize(rects.size() + bpp + 2);
- return true;
-}
-
-template <class SRC>
-inline void QRfbMultiColorHextile<SRC>::endRect()
-{
- setHeight(numRects, 1);
- ++numRects;
-}
-
-template <class SRC>
-bool QRfbMultiColorHextile<SRC>::read(const uchar *data,
- int width, int height, int stride)
-{
- const SRC *ptr = reinterpret_cast<const SRC*>(data);
- const int linestep = (stride / sizeof(SRC)) - width;
-
- bpp = encoder->server->clientBytesPerPixel();
-
- if (encoder->newBg)
- encoder->bg = ptr[0];
-
- const SRC bg = encoder->bg;
- SRC color = bg;
- bool inRect = false;
-
- numRects = 0;
- rects.clear();
-
- for (int y = 0; y < height; ++y) {
- for (int x = 0; x < width; ++x) {
- if (inRect && *ptr != color) { // end rect
- setWidth(numRects, x - rectx(numRects));
- endRect();
- inRect = false;
- }
-
- if (!inRect && *ptr != bg) { // begin rect
- if (!beginRect())
- return false;
- inRect = true;
- color = *ptr;
- setColor(color);
- setX(numRects, x);
- setY(numRects, y);
- }
- ++ptr;
- }
- if (inRect) { // end rect
- setWidth(numRects, width - rectx(numRects));
- endRect();
- inRect = false;
- }
- ptr += linestep;
- }
-
- return true;
-}
-
-template <class SRC>
-void QRfbMultiColorHextile<SRC>::write(QTcpSocket *socket) const
-{
- const int padding = 3;
- QVarLengthArray<quint8> buffer(bpp + padding + sizeof(quint8) + sizeof(numRects));
-
- quint8 &subenc = buffer[padding];
- int n = padding + sizeof(quint8);
-
- subenc = 8 | 16; // AnySubrects | SubrectsColoured
-
- if (encoder->newBg) {
- subenc |= 0x2; // Background
- encoder->server->convertPixels(reinterpret_cast<char*>(buffer.data() + n),
- reinterpret_cast<const char*>(&encoder->bg),
- 1);
- n += bpp;
-// encoder->newBg = false;
- }
-
- buffer[n] = numRects;
- n += sizeof(numRects);
-
- socket->write(reinterpret_cast<const char*>(buffer.data() + padding),
- n - padding);
- socket->write(reinterpret_cast<const char*>(rects.constData()),
- rects.size());
-}
-
-bool QVNCServer::pixelConversionNeeded() const
-{
- if (!sameEndian)
- return true;
-
-#if Q_BYTE_ORDER == Q_BIG_ENDIAN
- if (qvnc_screen->swapBytes())
- return true;
-#endif
-
- const int screendepth = qvnc_screen->depth();
- if (screendepth != pixelFormat.bitsPerPixel)
- return true;
-
- switch (screendepth) {
- case 32:
- case 24:
- return false;
- case 18:
- return (pixelFormat.redBits == 6
- && pixelFormat.greenBits == 6
- && pixelFormat.blueBits == 6);
- case 16:
- return (pixelFormat.redBits == 5
- && pixelFormat.greenBits == 6
- && pixelFormat.blueBits == 5);
- case 15:
- return (pixelFormat.redBits == 5
- && pixelFormat.greenBits == 5
- && pixelFormat.blueBits == 5);
- case 12:
- return (pixelFormat.redBits == 4
- && pixelFormat.greenBits == 4
- && pixelFormat.blueBits == 4);
- }
- return true;
-}
-
-// count: number of pixels
-void QVNCServer::convertPixels(char *dst, const char *src, int count) const
-{
- const int screendepth = qvnc_screen->depth();
- const bool isBgr = qvnc_screen->pixelType() == QScreen::BGRPixel;
-
- // cutoffs
-#if Q_BYTE_ORDER == Q_BIG_ENDIAN
- if (!swapBytes)
-#endif
- if (sameEndian) {
- if (screendepth == pixelFormat.bitsPerPixel) { // memcpy cutoffs
-
- switch (screendepth) {
- case 32:
- memcpy(dst, src, count * sizeof(quint32));
- return;
- case 16:
- if (pixelFormat.redBits == 5
- && pixelFormat.greenBits == 6
- && pixelFormat.blueBits == 5)
- {
- memcpy(dst, src, count * sizeof(quint16));
- return;
- }
- }
- } else if (screendepth == 16 && pixelFormat.bitsPerPixel == 32) {
-#if defined(__i386__) // Currently fails on ARM if dst is not 4 byte aligned
- const quint32 *src32 = reinterpret_cast<const quint32*>(src);
- quint32 *dst32 = reinterpret_cast<quint32*>(dst);
- int count32 = count * sizeof(quint16) / sizeof(quint32);
- while (count32--) {
- const quint32 s = *src32++;
- quint32 result1;
- quint32 result2;
-
- // red
- result1 = ((s & 0xf8000000) | ((s & 0xe0000000) >> 5)) >> 8;
- result2 = ((s & 0x0000f800) | ((s & 0x0000e000) >> 5)) << 8;
-
- // green
- result1 |= ((s & 0x07e00000) | ((s & 0x06000000) >> 6)) >> 11;
- result2 |= ((s & 0x000007e0) | ((s & 0x00000600) >> 6)) << 5;
-
- // blue
- result1 |= ((s & 0x001f0000) | ((s & 0x001c0000) >> 5)) >> 13;
- result2 |= ((s & 0x0000001f) | ((s & 0x0000001c) >> 5)) << 3;
-
- *dst32++ = result2;
- *dst32++ = result1;
- }
- if (count & 0x1) {
- const quint16 *src16 = reinterpret_cast<const quint16*>(src);
- *dst32 = qt_conv16ToRgb(src16[count - 1]);
- }
- return;
-#endif
- }
- }
-
- const int bytesPerPixel = (pixelFormat.bitsPerPixel + 7) / 8;
-
-// nibble = 0;
-
- for (int i = 0; i < count; ++i) {
- int r, g, b;
-
- switch (screendepth) {
-#if 0
- case 4: {
- if (!nibble) {
- r = ((*src) & 0x0f) << 4;
- } else {
- r = (*src) & 0xf0;
- src++;
- }
- nibble = !nibble;
- g = b = r;
- break;
- }
-#endif
- case 8: {
- QRgb rgb = qvnc_screen->clut()[int(*src)];
- r = qRed(rgb);
- g = qGreen(rgb);
- b = qBlue(rgb);
- src++;
- break;
- }
-#ifdef QT_QWS_DEPTH_12
- case 12: {
- quint32 p = quint32(*reinterpret_cast<const qrgb444*>(src));
- r = qRed(p);
- g = qGreen(p);
- b = qBlue(p);
- src += sizeof(qrgb444);
- break;
- }
-#endif
-#ifdef QT_QWS_DEPTH_15
- case 15: {
- quint32 p = quint32(*reinterpret_cast<const qrgb555*>(src));
- r = qRed(p);
- g = qGreen(p);
- b = qBlue(p);
- src += sizeof(qrgb555);
- break;
- }
-#endif
- case 16: {
- quint16 p = *reinterpret_cast<const quint16*>(src);
-#if Q_BYTE_ORDER == Q_BIG_ENDIAN
- if (swapBytes)
- p = ((p & 0xff) << 8) | ((p & 0xff00) >> 8);
-#endif
- r = (p >> 11) & 0x1f;
- g = (p >> 5) & 0x3f;
- b = p & 0x1f;
- r <<= 3;
- g <<= 2;
- b <<= 3;
- src += sizeof(quint16);
- break;
- }
-#ifdef QT_QWS_DEPTH_18
- case 18: {
- quint32 p = quint32(*reinterpret_cast<const qrgb666*>(src));
- r = qRed(p);
- g = qGreen(p);
- b = qBlue(p);
- src += sizeof(qrgb666);
- break;
- }
-#endif
-#ifdef QT_QWS_DEPTH_24
- case 24: {
- quint32 p = quint32(*reinterpret_cast<const qrgb888*>(src));
- r = qRed(p);
- g = qGreen(p);
- b = qBlue(p);
- src += sizeof(qrgb888);
- break;
- }
-#endif
- case 32: {
- quint32 p = *reinterpret_cast<const quint32*>(src);
- r = (p >> 16) & 0xff;
- g = (p >> 8) & 0xff;
- b = p & 0xff;
- src += sizeof(quint32);
- break;
- }
- default: {
- r = g = b = 0;
- qDebug("QVNCServer: don't support %dbpp display", screendepth);
- return;
- }
- }
-
-#if Q_BYTE_ORDER == Q_BIG_ENDIAN
- if (swapBytes ^ isBgr)
-#else
- if (isBgr)
-#endif
- qSwap(r, b);
-
- r >>= (8 - pixelFormat.redBits);
- g >>= (8 - pixelFormat.greenBits);
- b >>= (8 - pixelFormat.blueBits);
-
- int pixel = (r << pixelFormat.redShift) |
- (g << pixelFormat.greenShift) |
- (b << pixelFormat.blueShift);
-
- if (sameEndian || pixelFormat.bitsPerPixel == 8) {
- memcpy(dst, &pixel, bytesPerPixel); // XXX: do a simple for-loop instead?
- dst += bytesPerPixel;
- continue;
- }
-
-
- if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
- switch (pixelFormat.bitsPerPixel) {
- case 16:
- pixel = (((pixel & 0x0000ff00) << 8) |
- ((pixel & 0x000000ff) << 24));
- break;
- case 32:
- pixel = (((pixel & 0xff000000) >> 24) |
- ((pixel & 0x00ff0000) >> 8) |
- ((pixel & 0x0000ff00) << 8) |
- ((pixel & 0x000000ff) << 24));
- break;
- default:
- qDebug("Cannot handle %d bpp client", pixelFormat.bitsPerPixel);
- }
- } else { // QSysInfo::ByteOrder == QSysInfo::LittleEndian
- switch (pixelFormat.bitsPerPixel) {
- case 16:
- pixel = (((pixel & 0xff000000) >> 8) |
- ((pixel & 0x00ff0000) << 8));
- break;
- case 32:
- pixel = (((pixel & 0xff000000) >> 24) |
- ((pixel & 0x00ff0000) >> 8) |
- ((pixel & 0x0000ff00) << 8) |
- ((pixel & 0x000000ff) << 24));
- break;
- default:
- qDebug("Cannot handle %d bpp client",
- pixelFormat.bitsPerPixel);
- break;
- }
- }
- memcpy(dst, &pixel, bytesPerPixel); // XXX: simple for-loop instead?
- dst += bytesPerPixel;
- }
-}
-
-#ifndef QT_NO_QWS_CURSOR
-static void blendCursor(QImage &image, const QRect &imageRect)
-{
- const QRect cursorRect = qt_screencursor->boundingRect();
- const QRect intersection = (cursorRect & imageRect);
- const QRect destRect = intersection.translated(-imageRect.topLeft());
- const QRect srcRect = intersection.translated(-cursorRect.topLeft());
-
- QPainter painter(&image);
- painter.drawImage(destRect, qt_screencursor->image(), srcRect);
- painter.end();
-}
-#endif // QT_NO_QWS_CURSOR
-
-QVNCDirtyMap::QVNCDirtyMap(QScreen *s)
- : bytesPerPixel(0), numDirty(0), screen(s)
-{
- bytesPerPixel = (screen->depth() + 7) / 8;
- bufferWidth = screen->deviceWidth();
- bufferHeight = screen->deviceHeight();
- bufferStride = bufferWidth * bytesPerPixel;
- buffer = new uchar[bufferHeight * bufferStride];
-
- mapWidth = (bufferWidth + MAP_TILE_SIZE - 1) / MAP_TILE_SIZE;
- mapHeight = (bufferHeight + MAP_TILE_SIZE - 1) / MAP_TILE_SIZE;
- numTiles = mapWidth * mapHeight;
- map = new uchar[numTiles];
-}
-
-QVNCDirtyMap::~QVNCDirtyMap()
-{
- delete[] map;
- delete[] buffer;
-}
-
-void QVNCDirtyMap::reset()
-{
- memset(map, 1, numTiles);
- memset(buffer, 0, bufferHeight * bufferStride);
- numDirty = numTiles;
-}
-
-inline bool QVNCDirtyMap::dirty(int x, int y) const
-{
- return map[y * mapWidth + x];
-}
-
-inline void QVNCDirtyMap::setClean(int x, int y)
-{
- map[y * mapWidth + x] = 0;
- --numDirty;
-}
-
-template <class T>
-void QVNCDirtyMapOptimized<T>::setDirty(int tileX, int tileY, bool force)
-{
- static bool alwaysForce = qgetenv("QT_VNC_NO_COMPAREBUFFER").toInt();
- if (alwaysForce)
- force = true;
-
- bool changed = false;
-
- if (!force) {
- const int lstep = screen->linestep();
- const int startX = tileX * MAP_TILE_SIZE;
- const int startY = tileY * MAP_TILE_SIZE;
- const uchar *scrn = screen->base()
- + startY * lstep + startX * bytesPerPixel;
- uchar *old = buffer + startY * bufferStride + startX * sizeof(T);
-
- const int tileHeight = (startY + MAP_TILE_SIZE > bufferHeight ?
- bufferHeight - startY : MAP_TILE_SIZE);
- const int tileWidth = (startX + MAP_TILE_SIZE > bufferWidth ?
- bufferWidth - startX : MAP_TILE_SIZE);
- const bool doInlines = (tileWidth == MAP_TILE_SIZE);
-
- int y = tileHeight;
-
- if (doInlines) { // hw: memcmp/memcpy is inlined when using constants
- while (y) {
- if (memcmp(old, scrn, sizeof(T) * MAP_TILE_SIZE)) {
- changed = true;
- break;
- }
- scrn += lstep;
- old += bufferStride;
- --y;
- }
-
- while (y) {
- memcpy(old, scrn, sizeof(T) * MAP_TILE_SIZE);
- scrn += lstep;
- old += bufferStride;
- --y;
- }
- } else {
- while (y) {
- if (memcmp(old, scrn, sizeof(T) * tileWidth)) {
- changed = true;
- break;
- }
- scrn += lstep;
- old += bufferStride;
- --y;
- }
-
- while (y) {
- memcpy(old, scrn, sizeof(T) * tileWidth);
- scrn += lstep;
- old += bufferStride;
- --y;
- }
- }
- }
-
- const int mapIndex = tileY * mapWidth + tileX;
- if ((force || changed) && !map[mapIndex]) {
- map[mapIndex] = 1;
- ++numDirty;
- }
-}
-
-template <class SRC>
-QRfbHextileEncoder<SRC>::QRfbHextileEncoder(QVNCServer *s)
- : QRfbEncoder(s),
- singleColorHextile(this), dualColorHextile(this), multiColorHextile(this)
-{
-}
-
-/*
- \internal
- Send dirty rects using hextile encoding.
-*/
-template <class SRC>
-void QRfbHextileEncoder<SRC>::write()
-{
- QWSDisplay::grab(true);
-
- QVNCDirtyMap *map = server->dirtyMap();
- QTcpSocket *socket = server->clientSocket();
-
- const quint32 encoding = htonl(5); // hextile encoding
- const int bytesPerPixel = server->clientBytesPerPixel();
-
- {
- const char tmp[2] = { 0, 0 }; // msg type, padding
- socket->write(tmp, sizeof(tmp));
- }
- {
- const quint16 count = htons(map->numDirty);
- socket->write((char *)&count, sizeof(count));
- }
-
- if (map->numDirty <= 0) {
- QWSDisplay::ungrab();
- return;
- }
-
- newBg = true;
- newFg = true;
-
- const QImage screenImage = server->screenImage();
- QRfbRect rect(0, 0, MAP_TILE_SIZE, MAP_TILE_SIZE);
-
- for (int y = 0; y < map->mapHeight; ++y) {
- if (rect.y + MAP_TILE_SIZE > server->screen()->height())
- rect.h = server->screen()->height() - rect.y;
- rect.w = MAP_TILE_SIZE;
- for (int x = 0; x < map->mapWidth; ++x) {
- if (!map->dirty(x, y))
- continue;
- map->setClean(x, y);
-
- rect.x = x * MAP_TILE_SIZE;
- if (rect.x + MAP_TILE_SIZE > server->screen()->deviceWidth())
- rect.w = server->screen()->deviceWidth() - rect.x;
- rect.write(socket);
-
- socket->write((char *)&encoding, sizeof(encoding));
-
- const uchar *screendata = screenImage.scanLine(rect.y)
- + rect.x * screenImage.depth() / 8;
- int linestep = screenImage.bytesPerLine();
-
-#ifndef QT_NO_QWS_CURSOR
- // hardware cursors must be blended with the screen memory
- const bool doBlendCursor = qt_screencursor
- && !server->hasClientCursor()
- && qt_screencursor->isAccelerated();
- QImage tileImage;
- if (doBlendCursor) {
- const QRect tileRect(rect.x, rect.y, rect.w, rect.h);
- const QRect cursorRect = qt_screencursor->boundingRect()
- .translated(-server->screen()->offset());
- if (tileRect.intersects(cursorRect)) {
- tileImage = screenImage.copy(tileRect);
- blendCursor(tileImage,
- tileRect.translated(server->screen()->offset()));
- screendata = tileImage.bits();
- linestep = tileImage.bytesPerLine();
- }
- }
-#endif // QT_NO_QWS_CURSOR
-
- if (singleColorHextile.read(screendata, rect.w, rect.h, linestep)) {
- singleColorHextile.write(socket);
- } else if (dualColorHextile.read(screendata, rect.w, rect.h, linestep)) {
- dualColorHextile.write(socket);
- } else if (multiColorHextile.read(screendata, rect.w, rect.h, linestep)) {
- multiColorHextile.write(socket);
- } else if (server->doPixelConversion()) {
- const int bufferSize = rect.w * rect.h * bytesPerPixel + 1;
- const int padding = sizeof(quint32) - sizeof(char);
- buffer.resize(bufferSize + padding);
-
- buffer[padding] = 1; // Raw subencoding
-
- // convert pixels
- char *b = buffer.data() + padding + 1;
- const int bstep = rect.w * bytesPerPixel;
- for (int i = 0; i < rect.h; ++i) {
- server->convertPixels(b, (const char*)screendata, rect.w);
- screendata += linestep;
- b += bstep;
- }
- socket->write(buffer.constData() + padding, bufferSize);
- } else {
- quint8 subenc = 1; // Raw subencoding
- socket->write((char *)&subenc, 1);
-
- // send pixels
- for (int i = 0; i < rect.h; ++i) {
- socket->write((const char*)screendata,
- rect.w * bytesPerPixel);
- screendata += linestep;
- }
- }
- }
- if (socket->state() == QAbstractSocket::UnconnectedState)
- break;
- rect.y += MAP_TILE_SIZE;
- }
- socket->flush();
- Q_ASSERT(map->numDirty == 0);
-
- QWSDisplay::ungrab();
-}
-
-void QRfbRawEncoder::write()
-{
- QWSDisplay::grab(false);
-
- QVNCDirtyMap *map = server->dirtyMap();
- QTcpSocket *socket = server->clientSocket();
-
- const int bytesPerPixel = server->clientBytesPerPixel();
-
- // create a region from the dirty rects and send the region's merged rects.
- QRegion rgn;
- if (map) {
- for (int y = 0; y < map->mapHeight; ++y) {
- for (int x = 0; x < map->mapWidth; ++x) {
- if (!map->dirty(x, y))
- continue;
- rgn += QRect(x * MAP_TILE_SIZE, y * MAP_TILE_SIZE,
- MAP_TILE_SIZE, MAP_TILE_SIZE);
- map->setClean(x, y);
- }
- }
-
- rgn &= QRect(0, 0, server->screen()->deviceWidth(),
- server->screen()->deviceHeight());
- }
- const QVector<QRect> rects = rgn.rects();
-
- {
- const char tmp[2] = { 0, 0 }; // msg type, padding
- socket->write(tmp, sizeof(tmp));
- }
-
- {
- const quint16 count = htons(rects.size());
- socket->write((char *)&count, sizeof(count));
- }
-
- if (rects.size() <= 0) {
- QWSDisplay::ungrab();
- return;
- }
-
- const QImage screenImage = server->screenImage();
-
- for (int i = 0; i < rects.size(); ++i) {
- const QRect tileRect = rects.at(i);
- const QRfbRect rect(tileRect.x(), tileRect.y(),
- tileRect.width(), tileRect.height());
- rect.write(socket);
-
- const quint32 encoding = htonl(0); // raw encoding
- socket->write((char *)&encoding, sizeof(encoding));
-
- int linestep = screenImage.bytesPerLine();
- const uchar *screendata = screenImage.scanLine(rect.y)
- + rect.x * screenImage.depth() / 8;
-
-#ifndef QT_NO_QWS_CURSOR
- // hardware cursors must be blended with the screen memory
- const bool doBlendCursor = qt_screencursor
- && !server->hasClientCursor()
- && qt_screencursor->isAccelerated();
- QImage tileImage;
- if (doBlendCursor) {
- const QRect cursorRect = qt_screencursor->boundingRect()
- .translated(-server->screen()->offset());
- if (tileRect.intersects(cursorRect)) {
- tileImage = screenImage.copy(tileRect);
- blendCursor(tileImage,
- tileRect.translated(server->screen()->offset()));
- screendata = tileImage.bits();
- linestep = tileImage.bytesPerLine();
- }
- }
-#endif // QT_NO_QWS_CURSOR
-
- if (server->doPixelConversion()) {
- const int bufferSize = rect.w * rect.h * bytesPerPixel;
- if (bufferSize > buffer.size())
- buffer.resize(bufferSize);
-
- // convert pixels
- char *b = buffer.data();
- const int bstep = rect.w * bytesPerPixel;
- for (int i = 0; i < rect.h; ++i) {
- server->convertPixels(b, (const char*)screendata, rect.w);
- screendata += linestep;
- b += bstep;
- }
- socket->write(buffer.constData(), bufferSize);
- } else {
- for (int i = 0; i < rect.h; ++i) {
- socket->write((const char*)screendata, rect.w * bytesPerPixel);
- screendata += linestep;
- }
- }
- if (socket->state() == QAbstractSocket::UnconnectedState)
- break;
- }
- socket->flush();
-
- QWSDisplay::ungrab();
-}
-
-inline QImage QVNCServer::screenImage() const
-{
- return QImage(qvnc_screen->base(), qvnc_screen->deviceWidth(),
- qvnc_screen->deviceHeight(), qvnc_screen->linestep(),
- qvnc_screen->pixelFormat());
-}
-
-void QVNCServer::checkUpdate()
-{
- if (!wantUpdate)
- return;
-
- if (dirtyCursor) {
-#ifndef QT_NO_QWS_CURSOR
- Q_ASSERT(qvnc_cursor);
- qvnc_cursor->write();
-#endif
- dirtyCursor = false;
- wantUpdate = false;
- return;
- }
-
- if (dirtyMap()->numDirty > 0) {
- if (encoder)
- encoder->write();
- wantUpdate = false;
- }
-}
-
-void QVNCServer::discardClient()
-{
- timer->stop();
- state = Unconnected;
- delete encoder;
- encoder = 0;
-#ifndef QT_NO_QWS_CURSOR
- delete qvnc_cursor;
- qvnc_cursor = 0;
-#endif
- if (!qvnc_screen->screen() && !qvnc_screen->d_ptr->noDisablePainting && QWSServer::instance())
- QWSServer::instance()->enablePainting(false);
-}
-
-
-//===========================================================================
-
-/*!
- \class QVNCScreen
- \internal
- \ingroup qws
-
- \brief The QVNCScreen class implements a screen driver for VNC
- servers.
-
- Note that this class is only available in \l{Qt for Embedded Linux}.
- Custom screen drivers can be added by subclassing the QScreen
- class, using the QScreenDriverFactory class to dynamically load
- the driver into the application.
-
- The VNC protocol allows you to view and interact with the
- computer's display from anywhere on the network. See the
- \l{The VNC Protocol and Qt for Embedded Linux}{VNC protocol}
- documentation for more details.
-
- The default implementation of QVNCScreen inherits QLinuxFbScreen,
- but any QScreen subclass, or QScreen itself, can serve as its base
- class. This is easily achieved by manipulating the \c
- VNCSCREEN_BASE definition in the header file.
-
- \sa QScreen, {Running Applications}
-*/
-
-/*!
- \fn QVNCScreen::QVNCScreen(int displayId)
-
- Constructs a QVNCScreen object. The \a displayId argument
- identifies the Qt for Embedded Linux server to connect to.
-*/
-QVNCScreen::QVNCScreen(int display_id)
- : QProxyScreen(display_id, VNCClass)
-{
- d_ptr = new QVNCScreenPrivate(this);
-}
-
-/*!
- Destroys this QVNCScreen object.
-*/
-QVNCScreen::~QVNCScreen()
-{
- delete d_ptr;
-}
-
-/*!
- \reimp
-*/
-void QVNCScreen::setDirty(const QRect &rect)
-{
- d_ptr->setDirty(rect);
-}
-
-void QVNCScreenPrivate::setDirty(const QRect& rect, bool force)
-{
- if (rect.isEmpty())
- return;
-
- if (q_ptr->screen())
- q_ptr->screen()->setDirty(rect);
-
- if (!vncServer || !vncServer->isConnected())
- return;
-
- const QRect r = rect.translated(-q_ptr->offset());
- const int x1 = r.x() / MAP_TILE_SIZE;
- int y = r.y() / MAP_TILE_SIZE;
- for (; (y <= r.bottom() / MAP_TILE_SIZE) && y < dirty->mapHeight; y++)
- for (int x = x1; (x <= r.right() / MAP_TILE_SIZE) && x < dirty->mapWidth; x++)
- dirty->setDirty(x, y, force);
-
- vncServer->setDirty();
-}
-
-static int getDisplayId(const QString &spec)
-{
- QRegExp regexp(QLatin1String(":(\\d+)\\b"));
- if (regexp.lastIndexIn(spec) != -1) {
- const QString capture = regexp.cap(1);
- return capture.toInt();
- }
- return 0;
-}
-
-/*!
- \reimp
-*/
-bool QVNCScreen::connect(const QString &displaySpec)
-{
- QString dspec = displaySpec;
- if (dspec.startsWith(QLatin1String("vnc:"), Qt::CaseInsensitive))
- dspec = dspec.mid(QString::fromLatin1("vnc:").size());
- else if (dspec.compare(QLatin1String("vnc"), Qt::CaseInsensitive) == 0)
- dspec = QString();
-
- const QString displayIdSpec = QString::fromLatin1(" :%1").arg(displayId);
- if (dspec.endsWith(displayIdSpec))
- dspec = dspec.left(dspec.size() - displayIdSpec.size());
-
- QStringList args = dspec.split(QLatin1Char(':'),
- QString::SkipEmptyParts);
- QRegExp refreshRegexp(QLatin1String("^refreshrate=(\\d+)$"));
- int index = args.indexOf(refreshRegexp);
- if (index >= 0) {
- d_ptr->refreshRate = refreshRegexp.cap(1).toInt();
- args.removeAt(index);
- dspec = args.join(QLatin1String(":"));
- }
-
- QString driver = dspec;
- int colon = driver.indexOf(QLatin1Char(':'));
- if (colon >= 0)
- driver.truncate(colon);
-
- if (QScreenDriverFactory::keys().contains(driver, Qt::CaseInsensitive)) {
- const int id = getDisplayId(dspec);
- QScreen *s = qt_get_screen(id, dspec.toLatin1().constData());
- if (s->pixelFormat() == QImage::Format_Indexed8
- || s->pixelFormat() == QImage::Format_Invalid && s->depth() == 8)
- qFatal("QVNCScreen: unsupported screen format");
- setScreen(s);
- } else { // create virtual screen
-#if Q_BYTE_ORDER == Q_BIG_ENDIAN
- QScreen::setFrameBufferLittleEndian(false);
-#endif
-
- d = qgetenv("QWS_DEPTH").toInt();
- if (!d)
- d = 16;
-
- QByteArray str = qgetenv("QWS_SIZE");
- if(!str.isEmpty()) {
- sscanf(str.constData(), "%dx%d", &w, &h);
- dw = w;
- dh = h;
- } else {
- dw = w = 640;
- dh = h = 480;
- }
-
- const QStringList args = displaySpec.split(QLatin1Char(':'),
- QString::SkipEmptyParts);
-
- if (args.contains(QLatin1String("paintonscreen"), Qt::CaseInsensitive))
- d_ptr->doOnScreenSurface = true;
-
- QRegExp depthRegexp(QLatin1String("^depth=(\\d+)$"));
- if (args.indexOf(depthRegexp) != -1)
- d = depthRegexp.cap(1).toInt();
-
- QRegExp sizeRegexp(QLatin1String("^size=(\\d+)x(\\d+)$"));
- if (args.indexOf(sizeRegexp) != -1) {
- dw = w = sizeRegexp.cap(1).toInt();
- dh = h = sizeRegexp.cap(2).toInt();
- }
-
- // Handle display physical size spec.
- QRegExp mmWidthRegexp(QLatin1String("^mmWidth=?(\\d+)$"));
- if (args.indexOf(mmWidthRegexp) != -1) {
- const int mmWidth = mmWidthRegexp.cap(1).toInt();
- if (mmWidth > 0)
- d_ptr->dpiX = dw * 25.4 / mmWidth;
- }
- QRegExp mmHeightRegexp(QLatin1String("^mmHeight=?(\\d+)$"));
- if (args.indexOf(mmHeightRegexp) != -1) {
- const int mmHeight = mmHeightRegexp.cap(1).toInt();
- if (mmHeight > 0)
- d_ptr->dpiY = dh * 25.4 / mmHeight;
- }
- QRegExp dpiRegexp(QLatin1String("^dpi=(\\d+)(?:,(\\d+))?$"));
- if (args.indexOf(dpiRegexp) != -1) {
- const qreal dpiX = dpiRegexp.cap(1).toFloat();
- const qreal dpiY = dpiRegexp.cap(2).toFloat();
- if (dpiX > 0)
- d_ptr->dpiX = dpiX;
- d_ptr->dpiY = (dpiY > 0 ? dpiY : dpiX);
- }
-
- if (args.contains(QLatin1String("noDisablePainting")))
- d_ptr->noDisablePainting = true;
-
- QWSServer::setDefaultMouse("None");
- QWSServer::setDefaultKeyboard("None");
-
- d_ptr->configure();
- }
-
- // XXX
- qt_screen = this;
-
- return true;
-}
-
-/*!
- \reimp
-*/
-void QVNCScreen::disconnect()
-{
- QProxyScreen::disconnect();
-#if !defined(QT_NO_QWS_MULTIPROCESS) && !defined(QT_NO_SHAREDMEMORY)
- d_ptr->shm.detach();
-#endif
-}
-
-/*!
- \reimp
-*/
-bool QVNCScreen::initDevice()
-{
- if (!QProxyScreen::screen() && d == 4) {
- screencols = 16;
- int val = 0;
- for (int idx = 0; idx < 16; idx++, val += 17) {
- screenclut[idx] = qRgb(val, val, val);
- }
- }
- d_ptr->vncServer = new QVNCServer(this, displayId);
- d_ptr->vncServer->setRefreshRate(d_ptr->refreshRate);
-
- switch (depth()) {
-#ifdef QT_QWS_DEPTH_32
- case 32:
- d_ptr->dirty = new QVNCDirtyMapOptimized<quint32>(this);
- break;
-#endif
-#ifdef QT_QWS_DEPTH_24
- case 24:
- d_ptr->dirty = new QVNCDirtyMapOptimized<qrgb888>(this);
- break;
-#endif
-#ifdef QT_QWS_DEPTH_18
- case 18:
- d_ptr->dirty = new QVNCDirtyMapOptimized<qrgb666>(this);
- break;
-#endif
-#ifdef QT_QWS_DEPTH_16
- case 16:
- d_ptr->dirty = new QVNCDirtyMapOptimized<quint16>(this);
- break;
-#endif
-#ifdef QT_QWS_DEPTH_15
- case 15:
- d_ptr->dirty = new QVNCDirtyMapOptimized<qrgb555>(this);
- break;
-#endif
-#ifdef QT_QWS_DEPTH_12
- case 12:
- d_ptr->dirty = new QVNCDirtyMapOptimized<qrgb444>(this);
- break;
-#endif
-#ifdef QT_QWS_DEPTH_8
- case 8:
- d_ptr->dirty = new QVNCDirtyMapOptimized<quint8>(this);
- break;
-#endif
- default:
- qWarning("QVNCScreen::initDevice: No support for screen depth %d",
- depth());
- d_ptr->dirty = 0;
- return false;
- }
-
-
- const bool ok = QProxyScreen::initDevice();
-#ifndef QT_NO_QWS_CURSOR
- qt_screencursor = new QVNCCursor(this);
-#endif
- if (QProxyScreen::screen())
- return ok;
-
- // Disable painting if there is only 1 display and nothing is attached to the VNC server
- if (!d_ptr->noDisablePainting)
- QWSServer::instance()->enablePainting(false);
-
- return true;
-}
-
-/*!
- \reimp
-*/
-void QVNCScreen::shutdownDevice()
-{
- QProxyScreen::shutdownDevice();
- delete d_ptr->vncServer;
- delete d_ptr->dirty;
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_QWS_VNC
diff --git a/src/plugins/gfxdrivers/vnc/qscreenvnc_qws.h b/src/plugins/gfxdrivers/vnc/qscreenvnc_qws.h
deleted file mode 100644
index 014486bdb4..0000000000
--- a/src/plugins/gfxdrivers/vnc/qscreenvnc_qws.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSCREENVNC_QWS_H
-#define QSCREENVNC_QWS_H
-
-#include <QtGui/qscreenproxy_qws.h>
-
-#ifndef QT_NO_QWS_VNC
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QVNCScreenPrivate;
-
-class QVNCScreen : public QProxyScreen
-{
-public:
- explicit QVNCScreen(int display_id);
- virtual ~QVNCScreen();
-
- bool initDevice();
- bool connect(const QString &displaySpec);
- void disconnect();
- void shutdownDevice();
-
- void setDirty(const QRect&);
-
-private:
- friend class QVNCCursor;
- friend class QVNCClientCursor;
- friend class QVNCServer;
- friend class QVNCScreenPrivate;
-
-#if Q_BYTE_ORDER == Q_BIG_ENDIAN
- bool swapBytes() const;
-#endif
-
- QVNCScreenPrivate *d_ptr;
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QT_NO_QWS_VNC
-#endif // QSCREENVNC_QWS_H
diff --git a/src/plugins/gfxdrivers/vnc/vnc.pro b/src/plugins/gfxdrivers/vnc/vnc.pro
deleted file mode 100644
index 95e2ba7cf8..0000000000
--- a/src/plugins/gfxdrivers/vnc/vnc.pro
+++ /dev/null
@@ -1,16 +0,0 @@
-TARGET = qgfxvnc
-load(qt_plugin)
-
-DEFINES += QT_QWS_VNC
-
-DESTDIR = $$QT.gui.plugins/gfxdrivers
-
-HEADERS = \
- qscreenvnc_qws.h \
- qscreenvnc_p.h
-
-SOURCES = main.cpp \
- qscreenvnc_qws.cpp
-
-target.path += $$[QT_INSTALL_PLUGINS]/gfxdrivers
-INSTALLS += target
diff --git a/src/plugins/graphicssystems/graphicssystems.pro b/src/plugins/graphicssystems/graphicssystems.pro
deleted file mode 100644
index 5c99291047..0000000000
--- a/src/plugins/graphicssystems/graphicssystems.pro
+++ /dev/null
@@ -1,15 +0,0 @@
-TEMPLATE = subdirs
-SUBDIRS += trace
-!wince*:contains(QT_CONFIG, opengl):SUBDIRS += opengl
-contains(QT_CONFIG, openvg):contains(QT_CONFIG, egl) {
- SUBDIRS += openvg
-}
-
-contains(QT_CONFIG, shivavg) {
- # Only works under X11 at present
- !win32:!embedded:!mac:SUBDIRS += shivavg
-}
-
-!win32:!embedded:!mac:!symbian:CONFIG += x11
-
-x11:contains(QT_CONFIG, opengles2):contains(QT_CONFIG, egl):SUBDIRS += meego
diff --git a/src/plugins/graphicssystems/meego/dithering.cpp b/src/plugins/graphicssystems/meego/dithering.cpp
deleted file mode 100644
index 6e4b61c754..0000000000
--- a/src/plugins/graphicssystems/meego/dithering.cpp
+++ /dev/null
@@ -1,266 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-// Implements two dithering methods:
-//
-// * convertRGBA32_to_RGB565
-//
-// This is implemented using Ordered Bayer Dithering. The code has been adapted
-// from QX11PixmapData::fromImage. This method was originally implemented using
-// Floyd-Steinberg dithering but was later changed to Ordered Dithering because
-// of the better quality of the results.
-//
-// * convertRGBA32_to_RGBA4444
-//
-// This is implemented using Floyd-Steinberg dithering.
-//
-// The alghorithm used here is not the fastest possible but it's prolly fast enough:
-// uses look-up tables, integer-only arthmetics and works in one pass on two lines
-// at a time. It's a high-quality dithering using 1/8 diffusion precission.
-// Each channel (RGBA) is diffused independently and alpha is dithered too.
-
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h>
-#include <QVarLengthArray>
-
-// Gets a component (red = 1, green = 2...) from a RGBA data structure.
-// data is unsigned char. stride is the number of bytes per line.
-#define GET_RGBA_COMPONENT(data, x, y, stride, c) (data[(y * stride) + (x << 2) + c])
-
-// Writes a new pixel with r, g, b to data in 565 16bit format. Data is a short.
-#define PUT_565(data, x, y, width, r, g, b) (data[(y * width) + x] = (r << 11) | (g << 5) | b)
-
-// Writes a new pixel with r, g, b, a to data in 4444 RGBA 16bit format. Data is a short.
-#define PUT_4444(data, x, y, width, r, g, b, a) (data[(y * width) + x] = (r << 12) | (g << 8) | (b << 4) | a)
-
-// Writes(ads) a new value to the diffusion accumulator. accumulator is a short.
-// x, y is a position in the accumulation buffer. y can be 0 or 1 -- we operate on two lines at time.
-#define ACCUMULATE(accumulator, x, y, width, v) if (x < width && x >= 0) accumulator[(y * width) + x] += v
-
-// Clamps a value to be in 0..255 range.
-#define CLAMP_256(v) if (v > 255) v = 255; if (v < 0) v = 0;
-
-// Converts incoming RGB32 (QImage::Format_RGB32) to RGB565. Returns the newly allocated data.
-unsigned short* convertRGB32_to_RGB565(const unsigned char *in, int width, int height, int stride)
-{
- static bool thresholdMapInitialized = false;
- static int thresholdMap[16][16];
-
- if (!thresholdMapInitialized) {
- int i;
- int j;
- int n;
-
- thresholdMap[0][0] = 0;
- thresholdMap[1][0] = 2;
- thresholdMap[0][1] = 3;
- thresholdMap[1][1] = 1;
-
- for (n=2; n<16; n*=2) {
- for (i=0; i<n; i++) {
- for (j=0; j<n; j++) {
- thresholdMap[i][j] *= 4;
- thresholdMap[i+n][j] = thresholdMap[i][j] + 2;
- thresholdMap[i][j+n] = thresholdMap[i][j] + 3;
- thresholdMap[i+n][j+n] = thresholdMap[i][j] + 1;
- }
- }
- }
-
- thresholdMapInitialized = true;
- }
-
- // Output line stride. Aligned to 4 bytes.
- int alignedWidth = width;
- if (alignedWidth % 2 > 0)
- alignedWidth++;
-
- // Will store output
- unsigned short *out = (unsigned short *)malloc (alignedWidth * height * 2);
-
- int x;
- int y;
- int threshold;
-
- // For each line...
- for (y = 0; y < height; y++) {
-
- // For each column....
- for (x = 0; x < width; x++) {
-
- int r = GET_RGBA_COMPONENT(in, x, y, stride, 0);
- int g = GET_RGBA_COMPONENT(in, x, y, stride, 1);
- int b = GET_RGBA_COMPONENT(in, x, y, stride, 2);
-
- threshold = thresholdMap[x%16][y%16];
-
- if (r <= (255-(1<<3)) && ((r<<5) & 255) > threshold) r += (1<<3);
- if (g <= (255-(1<<2)) && ((g<<6) & 255) > threshold) g += (1<<2);
- if (b <= (255-(1<<3)) && ((b<<5) & 255) > threshold) b += (1<<3);
-
- // Write the newly produced pixel
- PUT_565(out, x, y, alignedWidth, ((b >> 3) & 0x1f), ((g >> 2) & 0x3f), ((r >> 3) & 0x1f));
- }
- }
-
- return out;
-}
-
-// Converts incoming RGBA32 (QImage::Format_ARGB32_Premultiplied) to RGB565. Returns the newly allocated data.
-// This function is similar (yet different) to the _565 variant but it makes sense to duplicate it here for simplicity.
-// The output has each scan line aligned to 4 bytes (as expected by GL by default).
-unsigned short* convertARGB32_to_RGBA4444(const unsigned char *in, int width, int height, int stride)
-{
- // Output line stride. Aligned to 4 bytes.
- int alignedWidth = width;
- if (alignedWidth % 2 > 0)
- alignedWidth++;
-
- // Will store output
- unsigned short *out = (unsigned short *) malloc(alignedWidth * 2 * height);
-
- // Lookup tables for the 8bit => 4bit conversion
- unsigned char lookup_8bit_to_4bit[256];
- short lookup_8bit_to_4bit_diff[256];
-
- // Macros for the conversion using the lookup table.
- #define CONVERT_8BIT_TO_4BIT(v) (lookup_8bit_to_4bit[v])
- #define DIFF_8BIT_TO_4BIT(v) (lookup_8bit_to_4bit_diff[v])
-
- int i;
- int x, y, c; // Pixel we're processing. c is component number (0, 1, 2, 3 for r, b, b, a)
- short component[4]; // Stores the new components (r, g, b, a) for pixel produced during conversion
- short diff; // The difference between the converted value and the original one. To be accumulated.
- QVarLengthArray <short> accumulatorData(4 * width * 2); // Data for three acumulators for r, g, b. Each accumulator is two lines.
- short *accumulator[4]; // Helper for accessing the accumulator on a per-channel basis more easily.
- accumulator[0] = accumulatorData.data();
- accumulator[1] = accumulatorData.data() + width;
- accumulator[2] = accumulatorData.data() + (width * 2);
- accumulator[3] = accumulatorData.data() + (width * 3);
-
- // Produce the conversion lookup tables.
- for (i = 0; i < 256; i++) {
- lookup_8bit_to_4bit[i] = round(i / 16.0);
- // Before bitshifts: (i * 8) - (... * 16 * 8)
- lookup_8bit_to_4bit_diff[i] = (i << 3) - (lookup_8bit_to_4bit[i] << 7);
-
- if (lookup_8bit_to_4bit[i] > 15)
- lookup_8bit_to_4bit[i] = 15;
- }
-
- // Clear the accumulators
- memset(accumulator[0], 0, width * 4);
- memset(accumulator[1], 0, width * 4);
- memset(accumulator[2], 0, width * 4);
- memset(accumulator[3], 0, width * 4);
-
- // For each line...
- for (y = 0; y < height; y++) {
-
- // For each component (r, g, b, a)...
- memcpy(accumulator[0], accumulator[0] + width, width * 2);
- memset(accumulator[0] + width, 0, width * 2);
-
- memcpy(accumulator[1], accumulator[1] + width, width * 2);
- memset(accumulator[1] + width, 0, width * 2);
-
- memcpy(accumulator[2], accumulator[2] + width, width * 2);
- memset(accumulator[2] + width, 0, width * 2);
-
- memcpy(accumulator[3], accumulator[3] + width, width * 2);
- memset(accumulator[3] + width, 0, width * 2);
-
- // For each column....
- for (x = 0; x < width; x++) {
-
- // For each component (r, g, b, a)...
- for (c = 0; c < 4; c++) {
-
- // Get the 8bit value from the original image
- component[c] = GET_RGBA_COMPONENT(in, x, y, stride, c);
-
- // Add the diffusion for this pixel we stored in the accumulator.
- // >> 7 because the values in accumulator are stored * 128
- component[c] += accumulator[c][x] >> 7;
-
- // Make sure we're not over the boundaries.
- CLAMP_256(component[c]);
-
- // Store the difference from converting 8bit => 4bit and the orig pixel.
- // Convert 8bit => 4bit.
- diff = DIFF_8BIT_TO_4BIT(component[c]);
- component[c] = CONVERT_8BIT_TO_4BIT(component[c]);
-
- // Distribute the difference according to the matrix in the
- // accumulation bufffer.
- ACCUMULATE(accumulator[c], x + 1, 0, width, diff * 7);
- ACCUMULATE(accumulator[c], x - 1, 1, width, diff * 3);
- ACCUMULATE(accumulator[c], x, 1, width, diff * 5);
- ACCUMULATE(accumulator[c], x + 1, 1, width, diff * 1);
- }
-
- // Write the newly produced pixel
- PUT_4444(out, x, y, alignedWidth, component[0], component[1], component[2], component[3]);
- }
- }
-
- return out;
-}
-
-unsigned char* convertBGRA32_to_RGBA32(const unsigned char *in, int width, int height, int stride)
-{
- unsigned char *out = (unsigned char *) malloc(stride * height);
-
- // For each line...
- for (int y = 0; y < height; y++) {
- // For each column
- for (int x = 0; x < width; x++) {
- out[(stride * y) + (x * 4) + 0] = in[(stride * y) + (x * 4) + 2];
- out[(stride * y) + (x * 4) + 1] = in[(stride * y) + (x * 4) + 1];
- out[(stride * y) + (x * 4) + 2] = in[(stride * y) + (x * 4) + 0];
- out[(stride * y) + (x * 4) + 3] = in[(stride * y) + (x * 4) + 3];
- }
- }
-
- return out;
-}
diff --git a/src/plugins/graphicssystems/meego/meego.pro b/src/plugins/graphicssystems/meego/meego.pro
deleted file mode 100644
index 6432825888..0000000000
--- a/src/plugins/graphicssystems/meego/meego.pro
+++ /dev/null
@@ -1,13 +0,0 @@
-TARGET = qmeegographicssystem
-load(qt_plugin)
-
-QT += core-private gui-private opengl-private
-
-DESTDIR = $$QT.gui.plugins/graphicssystems
-
-HEADERS = qmeegographicssystem.h qmeegopixmapdata.h qmeegoextensions.h qmeegorasterpixmapdata.h qmeegolivepixmapdata.h
-SOURCES = qmeegographicssystem.cpp qmeegographicssystem.h qmeegographicssystemplugin.h qmeegographicssystemplugin.cpp qmeegopixmapdata.h qmeegopixmapdata.cpp qmeegoextensions.h qmeegoextensions.cpp qmeegorasterpixmapdata.h qmeegorasterpixmapdata.cpp qmeegolivepixmapdata.cpp qmeegolivepixmapdata.h dithering.cpp
-
-target.path += $$[QT_INSTALL_PLUGINS]/graphicssystems
-INSTALLS += target
-
diff --git a/src/plugins/graphicssystems/meego/qmeegoextensions.cpp b/src/plugins/graphicssystems/meego/qmeegoextensions.cpp
deleted file mode 100644
index c1a8eb7028..0000000000
--- a/src/plugins/graphicssystems/meego/qmeegoextensions.cpp
+++ /dev/null
@@ -1,213 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qmeegoextensions.h"
-#include <private/qeglcontext_p.h>
-#include <private/qpixmapdata_gl_p.h>
-
-bool QMeeGoExtensions::initialized = false;
-bool QMeeGoExtensions::hasImageShared = false;
-bool QMeeGoExtensions::hasSurfaceScaling = false;
-bool QMeeGoExtensions::hasLockSurface = false;
-bool QMeeGoExtensions::hasFenceSync = false;
-
-/* Extension funcs */
-
-typedef EGLBoolean (EGLAPIENTRY *eglQueryImageNOKFunc)(EGLDisplay, EGLImageKHR, EGLint, EGLint*);
-typedef EGLNativeSharedImageTypeNOK (EGLAPIENTRY *eglCreateSharedImageNOKFunc)(EGLDisplay, EGLImageKHR, EGLint*);
-typedef EGLBoolean (EGLAPIENTRY *eglDestroySharedImageNOKFunc)(EGLDisplay, EGLNativeSharedImageTypeNOK);
-typedef EGLBoolean (EGLAPIENTRY *eglSetSurfaceScalingNOKFunc)(EGLDisplay, EGLSurface, EGLint, EGLint, EGLint, EGLint);
-typedef EGLBoolean (EGLAPIENTRY *eglLockSurfaceKHRFunc)(EGLDisplay, EGLSurface, const EGLint*);
-typedef EGLBoolean (EGLAPIENTRY *eglUnlockSurfaceKHRFunc)(EGLDisplay, EGLSurface);
-typedef EGLSyncKHR (EGLAPIENTRY *eglCreateSyncKHRFunc)(EGLDisplay, EGLenum, const EGLint*);
-typedef EGLBoolean (EGLAPIENTRY *eglDestroySyncKHRFunc)(EGLDisplay, EGLSyncKHR);
-typedef EGLint (EGLAPIENTRY *eglClientWaitSyncKHRFunc)(EGLDisplay, EGLSyncKHR, EGLint, EGLTimeKHR);
-typedef EGLBoolean (EGLAPIENTRY *eglGetSyncAttribKHRFunc)(EGLDisplay, EGLSyncKHR, EGLint, EGLint*);
-
-static eglQueryImageNOKFunc _eglQueryImageNOK = 0;
-static eglCreateSharedImageNOKFunc _eglCreateSharedImageNOK = 0;
-static eglDestroySharedImageNOKFunc _eglDestroySharedImageNOK = 0;
-static eglSetSurfaceScalingNOKFunc _eglSetSurfaceScalingNOK = 0;
-static eglLockSurfaceKHRFunc _eglLockSurfaceKHR = 0;
-static eglUnlockSurfaceKHRFunc _eglUnlockSurfaceKHR = 0;
-static eglCreateSyncKHRFunc _eglCreateSyncKHR = 0;
-static eglDestroySyncKHRFunc _eglDestroySyncKHR = 0;
-static eglClientWaitSyncKHRFunc _eglClientWaitSyncKHR = 0;
-static eglGetSyncAttribKHRFunc _eglGetSyncAttribKHR = 0;
-
-/* Public */
-
-void QMeeGoExtensions::ensureInitialized()
-{
- if (!initialized)
- initialize();
-
- initialized = true;
-}
-
-EGLNativeSharedImageTypeNOK QMeeGoExtensions::eglCreateSharedImageNOK(EGLDisplay dpy, EGLImageKHR image, EGLint *props)
-{
- if (!hasImageShared)
- qFatal("EGL_NOK_image_shared not found but trying to use capability!");
-
- return _eglCreateSharedImageNOK(dpy, image, props);
-}
-
-bool QMeeGoExtensions::eglQueryImageNOK(EGLDisplay dpy, EGLImageKHR image, EGLint prop, EGLint *v)
-{
- if (!hasImageShared)
- qFatal("EGL_NOK_image_shared not found but trying to use capability!");
-
- return _eglQueryImageNOK(dpy, image, prop, v);
-}
-
-bool QMeeGoExtensions::eglDestroySharedImageNOK(EGLDisplay dpy, EGLNativeSharedImageTypeNOK img)
-{
- if (!hasImageShared)
- qFatal("EGL_NOK_image_shared not found but trying to use capability!");
-
- return _eglDestroySharedImageNOK(dpy, img);
-}
-
-bool QMeeGoExtensions::eglSetSurfaceScalingNOK(EGLDisplay dpy, EGLSurface surface, int x, int y, int width, int height)
-{
- if (!hasSurfaceScaling)
- qFatal("EGL_NOK_surface_scaling not found but trying to use capability!");
-
- return _eglSetSurfaceScalingNOK(dpy, surface, x, y, width, height);
-}
-
-bool QMeeGoExtensions::eglLockSurfaceKHR(EGLDisplay display, EGLSurface surface, const EGLint *attrib_list)
-{
- if (!hasLockSurface)
- qFatal("EGL_KHR_lock_surface2 not found but trying to use capability!");
-
- return _eglLockSurfaceKHR(display, surface, attrib_list);
-}
-
-bool QMeeGoExtensions::eglUnlockSurfaceKHR(EGLDisplay display, EGLSurface surface)
-{
- if (!hasLockSurface)
- qFatal("EGL_KHR_lock_surface2 not found but trying to use capability!");
-
- return _eglUnlockSurfaceKHR(display, surface);
-}
-
-EGLSyncKHR QMeeGoExtensions::eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
-{
- if (!hasFenceSync)
- qFatal("EGL_KHR_fence_sync not found but trying to use capability!");
-
- return _eglCreateSyncKHR(dpy, type, attrib_list);
-}
-
-bool QMeeGoExtensions::eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)
-{
- if (!hasFenceSync)
- qFatal("EGL_KHR_fence_sync not found but trying to use capability!");
-
- return _eglDestroySyncKHR(dpy, sync);
-}
-
-EGLint QMeeGoExtensions::eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout)
-{
- if (!hasFenceSync)
- qFatal("EGL_KHR_fence_sync not found but trying to use capability!");
-
- return _eglClientWaitSyncKHR(dpy, sync, flags, timeout);
-}
-
-EGLBoolean QMeeGoExtensions::eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value)
-{
- if (!hasFenceSync)
- qFatal("EGL_KHR_fence_sync not found but trying to use capability!");
-
- return _eglGetSyncAttribKHR(dpy, sync, attribute, value);
-}
-
-/* Private */
-
-void QMeeGoExtensions::initialize()
-{
- QGLContext *ctx = (QGLContext *) QGLContext::currentContext();
- qt_resolve_eglimage_gl_extensions(ctx);
-
- if (QEgl::hasExtension("EGL_NOK_image_shared")) {
- qDebug("MeegoGraphics: found EGL_NOK_image_shared");
- _eglQueryImageNOK = (eglQueryImageNOKFunc) eglGetProcAddress("eglQueryImageNOK");
- _eglCreateSharedImageNOK = (eglCreateSharedImageNOKFunc) eglGetProcAddress("eglCreateSharedImageNOK");
- _eglDestroySharedImageNOK = (eglDestroySharedImageNOKFunc) eglGetProcAddress("eglDestroySharedImageNOK");
- _eglLockSurfaceKHR = (eglLockSurfaceKHRFunc) eglGetProcAddress("eglLockSurfaceKHR");
- _eglUnlockSurfaceKHR = (eglUnlockSurfaceKHRFunc) eglGetProcAddress("eglUnlockSurfaceKHR");
-
- Q_ASSERT(_eglQueryImageNOK && _eglCreateSharedImageNOK && _eglDestroySharedImageNOK);
- hasImageShared = true;
- }
-
- if (QEgl::hasExtension("EGL_NOK_surface_scaling")) {
- qDebug("MeegoGraphics: found EGL_NOK_surface_scaling");
- _eglSetSurfaceScalingNOK = (eglSetSurfaceScalingNOKFunc) eglGetProcAddress("eglSetSurfaceScalingNOK");
-
- Q_ASSERT(_eglSetSurfaceScalingNOK);
- hasSurfaceScaling = true;
- }
-
- if (QEgl::hasExtension("EGL_KHR_lock_surface2")) {
- qDebug("MeegoGraphics: found EGL_KHR_lock_surface2");
- _eglLockSurfaceKHR = (eglLockSurfaceKHRFunc) eglGetProcAddress("eglLockSurfaceKHR");
- _eglUnlockSurfaceKHR = (eglUnlockSurfaceKHRFunc) eglGetProcAddress("eglUnlockSurfaceKHR");
-
- Q_ASSERT(_eglLockSurfaceKHR && _eglUnlockSurfaceKHR);
- hasLockSurface = true;
- }
-
- if (QEgl::hasExtension("EGL_KHR_fence_sync")) {
- qDebug("MeegoGraphics: found EGL_KHR_fence_sync");
- _eglCreateSyncKHR = (eglCreateSyncKHRFunc) eglGetProcAddress("eglCreateSyncKHR");
- _eglDestroySyncKHR = (eglDestroySyncKHRFunc) eglGetProcAddress("eglDestroySyncKHR");
- _eglClientWaitSyncKHR = (eglClientWaitSyncKHRFunc) eglGetProcAddress("eglClientWaitSyncKHR");
- _eglGetSyncAttribKHR = (eglGetSyncAttribKHRFunc) eglGetProcAddress("eglGetSyncAttribKHR");
-
- Q_ASSERT(_eglCreateSyncKHR && _eglDestroySyncKHR && _eglClientWaitSyncKHR && _eglGetSyncAttribKHR);
- hasFenceSync = true;
- }
-}
-
diff --git a/src/plugins/graphicssystems/meego/qmeegoextensions.h b/src/plugins/graphicssystems/meego/qmeegoextensions.h
deleted file mode 100644
index e4ceed3a31..0000000000
--- a/src/plugins/graphicssystems/meego/qmeegoextensions.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef MEXTENSIONS_H
-#define MEXTENSIONS_H
-
-#include <private/qgl_p.h>
-#include <private/qeglcontext_p.h>
-#include <private/qpixmapdata_gl_p.h>
-#include <EGL/egl.h>
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-
-/* Extensions decls */
-
-#ifndef EGL_SHARED_IMAGE_NOK
-#define EGL_SHARED_IMAGE_NOK 0x30DA
-typedef void* EGLNativeSharedImageTypeNOK;
-#endif
-
-#ifndef EGL_GL_TEXTURE_2D_KHR
-#define EGL_GL_TEXTURE_2D_KHR 0x30B1
-#endif
-
-#ifndef EGL_FIXED_WIDTH_NOK
-#define EGL_FIXED_WIDTH_NOK 0x30DB
-#define EGL_FIXED_HEIGHT_NOK 0x30DC
-#endif
-
-#ifndef EGL_BITMAP_POINTER_KHR
-#define EGL_BITMAP_POINTER_KHR 0x30C6
-#define EGL_BITMAP_PITCH_KHR 0x30C7
-#endif
-
-#ifndef EGL_MAP_PRESERVE_PIXELS_KHR
-#define EGL_MAP_PRESERVE_PIXELS_KHR 0x30C4
-#define EGL_LOCK_USAGE_HINT_KHR 0x30C5
-#define EGL_READ_SURFACE_BIT_KHR 0x0001
-#define EGL_WRITE_SURFACE_BIT_KHR 0x0002
-#endif
-
-#ifndef EGL_SYNC_FENCE_KHR
-#define EGL_SYNC_FENCE_KHR 0x30F9
-#define EGL_SYNC_TYPE_KHR 0x30F7
-#define EGL_SYNC_STATUS_KHR 0x30F1
-#define EGL_SYNC_CONDITION_KHR 0x30F8
-#define EGL_SIGNALED_KHR 0x30F2
-#define EGL_UNSIGNALED_KHR 0x30F3
-#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR 0x30F0
-#define EGL_SYNC_FLUSH_COMMANDS_BIT_KHR 0x0001
-#define EGL_FOREVER_KHR 0xFFFFFFFFFFFFFFFFull
-#define EGL_TIMEOUT_EXPIRED_KHR 0x30F5
-#define EGL_CONDITION_SATISFIED_KHR 0x30F6
-#define EGL_NO_SYNC_KHR ((EGLSyncKHR)0)
-typedef void* EGLSyncKHR;
-typedef khronos_utime_nanoseconds_t EGLTimeKHR;
-#endif
-
-/* Class */
-
-class QMeeGoExtensions
-{
-public:
- static void ensureInitialized();
-
- static EGLNativeSharedImageTypeNOK eglCreateSharedImageNOK(EGLDisplay dpy, EGLImageKHR image, EGLint *props);
- static bool eglQueryImageNOK(EGLDisplay dpy, EGLImageKHR image, EGLint prop, EGLint *v);
- static bool eglDestroySharedImageNOK(EGLDisplay dpy, EGLNativeSharedImageTypeNOK img);
- static bool eglSetSurfaceScalingNOK(EGLDisplay dpy, EGLSurface surface, int x, int y, int width, int height);
- static bool eglLockSurfaceKHR(EGLDisplay display, EGLSurface surface, const EGLint *attrib_list);
- static bool eglUnlockSurfaceKHR(EGLDisplay display, EGLSurface surface);
- static EGLSyncKHR eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list);
- static bool eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync);
- static EGLint eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout);
- static EGLBoolean eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value);
-
-private:
- static void initialize();
-
- static bool initialized;
- static bool hasImageShared;
- static bool hasSurfaceScaling;
- static bool hasLockSurface;
- static bool hasFenceSync;
-};
-
-#endif
diff --git a/src/plugins/graphicssystems/meego/qmeegographicssystem.cpp b/src/plugins/graphicssystems/meego/qmeegographicssystem.cpp
deleted file mode 100644
index ab403797df..0000000000
--- a/src/plugins/graphicssystems/meego/qmeegographicssystem.cpp
+++ /dev/null
@@ -1,534 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QDebug>
-#include <private/qpixmap_raster_p.h>
-#include <private/qwindowsurface_gl_p.h>
-#include <private/qwindowsurface_raster_p.h>
-#include <private/qegl_p.h>
-#include <private/qglextensions_p.h>
-#include <private/qgl_p.h>
-#include <private/qimagepixmapcleanuphooks_p.h>
-#include <private/qapplication_p.h>
-#include <private/qgraphicssystem_runtime_p.h>
-#include <private/qimage_p.h>
-#include <private/qeglproperties_p.h>
-#include <private/qeglcontext_p.h>
-#include <private/qpixmap_x11_p.h>
-
-#include "qmeegopixmapdata.h"
-#include "qmeegolivepixmapdata.h"
-#include "qmeegographicssystem.h"
-#include "qmeegoextensions.h"
-
-#include <QTimer>
-
-bool QMeeGoGraphicsSystem::surfaceWasCreated = false;
-
-QHash <Qt::HANDLE, QPixmap*> QMeeGoGraphicsSystem::liveTexturePixmaps;
-
-QList<QMeeGoSwitchCallback> QMeeGoGraphicsSystem::switchCallbacks;
-
-QMeeGoGraphicsSystem::SwitchPolicy QMeeGoGraphicsSystem::switchPolicy = QMeeGoGraphicsSystem::AutomaticSwitch;
-
-QMeeGoGraphicsSystem::QMeeGoGraphicsSystem()
-{
- qDebug("Using the meego graphics system");
-}
-
-QMeeGoGraphicsSystem::~QMeeGoGraphicsSystem()
-{
- qDebug("Meego graphics system destroyed");
- qt_destroy_gl_share_widget();
-}
-
-class QMeeGoGraphicsSystemSwitchHandler : public QObject
-{
- Q_OBJECT
-public:
- QMeeGoGraphicsSystemSwitchHandler();
-
- void addWidget(QWidget *widget);
- bool eventFilter(QObject *, QEvent *);
-
- void handleMapNotify();
-
-private slots:
- void removeWidget(QObject *object);
- void switchToRaster();
- void switchToMeeGo();
-
-private:
- int visibleWidgets() const;
-
-private:
- QList<QWidget *> m_widgets;
-};
-
-typedef bool(*QX11FilterFunction)(XEvent *event);
-Q_GUI_EXPORT void qt_installX11EventFilter(QX11FilterFunction func);
-
-static bool x11EventFilter(XEvent *event);
-
-QMeeGoGraphicsSystemSwitchHandler::QMeeGoGraphicsSystemSwitchHandler()
-{
- qt_installX11EventFilter(x11EventFilter);
-}
-
-void QMeeGoGraphicsSystemSwitchHandler::addWidget(QWidget *widget)
-{
- if (widget != qt_gl_share_widget() && !m_widgets.contains(widget)) {
- widget->installEventFilter(this);
- connect(widget, SIGNAL(destroyed(QObject *)), this, SLOT(removeWidget(QObject *)));
- m_widgets << widget;
- }
-}
-
-void QMeeGoGraphicsSystemSwitchHandler::handleMapNotify()
-{
- if (m_widgets.isEmpty() && QMeeGoGraphicsSystem::switchPolicy == QMeeGoGraphicsSystem::AutomaticSwitch)
- QTimer::singleShot(0, this, SLOT(switchToMeeGo()));
-}
-
-void QMeeGoGraphicsSystemSwitchHandler::removeWidget(QObject *object)
-{
- m_widgets.removeOne(static_cast<QWidget *>(object));
- if (m_widgets.isEmpty() && QMeeGoGraphicsSystem::switchPolicy == QMeeGoGraphicsSystem::AutomaticSwitch)
- QTimer::singleShot(0, this, SLOT(switchToRaster()));
-}
-
-void QMeeGoGraphicsSystemSwitchHandler::switchToRaster()
-{
- QMeeGoGraphicsSystem::switchToRaster();
-}
-
-void QMeeGoGraphicsSystemSwitchHandler::switchToMeeGo()
-{
- QMeeGoGraphicsSystem::switchToMeeGo();
-}
-
-int QMeeGoGraphicsSystemSwitchHandler::visibleWidgets() const
-{
- int count = 0;
- for (int i = 0; i < m_widgets.size(); ++i)
- count += m_widgets.at(i)->isVisible() && !(m_widgets.at(i)->windowState() & Qt::WindowMinimized);
- return count;
-}
-
-bool QMeeGoGraphicsSystemSwitchHandler::eventFilter(QObject *object, QEvent *event)
-{
- if (event->type() == QEvent::WindowStateChange
- && QMeeGoGraphicsSystem::switchPolicy == QMeeGoGraphicsSystem::AutomaticSwitch)
- {
- QWindowStateChangeEvent *change = static_cast<QWindowStateChangeEvent *>(event);
- QWidget *widget = static_cast<QWidget *>(object);
-
- Qt::WindowStates current = widget->windowState();
- Qt::WindowStates old = change->oldState();
-
- // did minimized flag change?
- if ((current ^ old) & Qt::WindowMinimized) {
- if (current & Qt::WindowMinimized) {
- if (visibleWidgets() == 0)
- QMeeGoGraphicsSystem::switchToRaster();
- } else {
- if (visibleWidgets() > 0)
- QMeeGoGraphicsSystem::switchToMeeGo();
- }
- }
- }
-
- // resume processing of event
- return false;
-}
-
-Q_GLOBAL_STATIC(QMeeGoGraphicsSystemSwitchHandler, switch_handler)
-
-bool x11EventFilter(XEvent *event)
-{
- if (event->type == MapNotify)
- switch_handler()->handleMapNotify();
- return false;
-}
-
-QWindowSurface* QMeeGoGraphicsSystem::createWindowSurface(QWidget *widget) const
-{
- QGLWidget *shareWidget = qt_gl_share_widget();
-
- if (!shareWidget)
- return new QRasterWindowSurface(widget);
-
- QGLShareContextScope ctx(shareWidget->context());
-
- if (QApplicationPrivate::instance()->graphics_system_name == QLatin1String("runtime"))
- switch_handler()->addWidget(widget);
-
- QMeeGoGraphicsSystem::surfaceWasCreated = true;
- QWindowSurface *surface = new QGLWindowSurface(widget);
- return surface;
-}
-
-QPixmapData *QMeeGoGraphicsSystem::createPixmapData(QPixmapData::PixelType type) const
-{
- return new QRasterPixmapData(type);
-}
-
-QPixmapData *QMeeGoGraphicsSystem::createPixmapData(QPixmapData *origin)
-{
- // If the pixmap is a raster type...
- // and if the pixmap pointer matches our mapping...
- // create a shared image instead with the given handle.
-
- if (!origin->isNull() && origin->classId() == QPixmapData::RasterClass) {
- QRasterPixmapData *rasterClass = static_cast <QRasterPixmapData *> (origin);
- void *rawResource = static_cast <void *> (rasterClass->buffer()->data_ptr()->data);
-
- if (QMeeGoPixmapData::sharedImagesMap.contains(rawResource))
- return new QMeeGoPixmapData();
- }
-
- return new QRasterPixmapData(origin->pixelType());
-}
-
-QPixmapData* QMeeGoGraphicsSystem::wrapPixmapData(QPixmapData *pmd)
-{
- QString name = QApplicationPrivate::instance()->graphics_system_name;
- if (name == "runtime") {
- QRuntimeGraphicsSystem *rsystem = (QRuntimeGraphicsSystem *) QApplicationPrivate::instance()->graphics_system;
- QRuntimePixmapData *rt = new QRuntimePixmapData(rsystem, pmd->pixelType());;
- rt->m_data = pmd;
- rt->readBackInfo();
- rsystem->m_pixmapDatas << rt;
- return rt;
- } else
- return pmd;
-}
-
-void QMeeGoGraphicsSystem::setSurfaceFixedSize(int /*width*/, int /*height*/)
-{
- if (QMeeGoGraphicsSystem::surfaceWasCreated) {
- qWarning("Trying to set surface fixed size but surface already created!");
- return;
- }
-
-#ifdef QT_WAS_PATCHED
- QEglProperties *properties = new QEglProperties();
- properties->setValue(EGL_FIXED_WIDTH_NOK, width);
- properties->setValue(EGL_FIXED_HEIGHT_NOK, height);
- QGLContextPrivate::setExtraWindowSurfaceCreationProps(properties);
-#endif
-}
-
-void QMeeGoGraphicsSystem::setSurfaceScaling(int x, int y, int width, int height)
-{
- QMeeGoExtensions::ensureInitialized();
- QMeeGoExtensions::eglSetSurfaceScalingNOK(QEgl::display(), QEglContext::currentContext(QEgl::OpenGL)->currentSurface, x, y, width, height);
-}
-
-void QMeeGoGraphicsSystem::setTranslucent(bool translucent)
-{
- if (QMeeGoGraphicsSystem::surfaceWasCreated) {
- qWarning("Trying to set translucency but surface already created!");
- return;
- }
-
- QGLWindowSurface::surfaceFormat.setSampleBuffers(false);
- QGLWindowSurface::surfaceFormat.setSamples(0);
- QGLWindowSurface::surfaceFormat.setAlpha(translucent);
-}
-
-QPixmapData *QMeeGoGraphicsSystem::pixmapDataFromEGLSharedImage(Qt::HANDLE handle, const QImage &softImage)
-{
- if (softImage.format() != QImage::Format_ARGB32_Premultiplied &&
- softImage.format() != QImage::Format_RGB32) {
- qFatal("For egl shared images, the soft image has to be ARGB32_Premultiplied or RGB32");
- return NULL;
- }
-
- if (QMeeGoGraphicsSystem::meeGoRunning()) {
- QMeeGoPixmapData *pmd = new QMeeGoPixmapData;
- pmd->fromEGLSharedImage(handle, softImage);
- return QMeeGoGraphicsSystem::wrapPixmapData(pmd);
- } else {
- QRasterPixmapData *pmd = new QRasterPixmapData(QPixmapData::PixmapType);
- pmd->fromImage(softImage, Qt::NoFormatConversion);
-
- // Make sure that the image was not converted in any way
- if (pmd->buffer()->data_ptr()->data !=
- const_cast<QImage &>(softImage).data_ptr()->data)
- qFatal("Iternal misalignment of raster data detected. Prolly a QImage copy fail.");
-
- QMeeGoPixmapData::registerSharedImage(handle, softImage);
- return QMeeGoGraphicsSystem::wrapPixmapData(pmd);
- }
-}
-
-void QMeeGoGraphicsSystem::updateEGLSharedImagePixmap(QPixmap *pixmap)
-{
- QMeeGoPixmapData *pmd = (QMeeGoPixmapData *) pixmap->pixmapData();
-
- // Basic sanity check to make sure this is really a QMeeGoPixmapData...
- if (pmd->classId() != QPixmapData::OpenGLClass)
- qFatal("Trying to updated EGLSharedImage pixmap but it's not really a shared image pixmap!");
-
- pmd->updateFromSoftImage();
-}
-
-QPixmapData *QMeeGoGraphicsSystem::pixmapDataWithGLTexture(int w, int h)
-{
- QGLPixmapData *pmd = new QGLPixmapData(QPixmapData::PixmapType);
- pmd->resize(w, h);
- return QMeeGoGraphicsSystem::wrapPixmapData(pmd);
-}
-
-bool QMeeGoGraphicsSystem::meeGoRunning()
-{
- return runningGraphicsSystemName() == "meego";
-}
-
-QPixmapData* QMeeGoGraphicsSystem::pixmapDataWithNewLiveTexture(int w, int h, QImage::Format format)
-{
- return new QMeeGoLivePixmapData(w, h, format);
-}
-
-QPixmapData* QMeeGoGraphicsSystem::pixmapDataFromLiveTextureHandle(Qt::HANDLE handle)
-{
- return new QMeeGoLivePixmapData(handle);
-}
-
-QImage* QMeeGoGraphicsSystem::lockLiveTexture(QPixmap* pixmap, void* fenceSync)
-{
- QMeeGoLivePixmapData *pixmapData = static_cast<QMeeGoLivePixmapData*>(pixmap->data_ptr().data());
- return pixmapData->lock(fenceSync);
-}
-
-bool QMeeGoGraphicsSystem::releaseLiveTexture(QPixmap *pixmap, QImage *image)
-{
- QMeeGoLivePixmapData *pixmapData = static_cast<QMeeGoLivePixmapData*>(pixmap->data_ptr().data());
- return pixmapData->release(image);
-}
-
-Qt::HANDLE QMeeGoGraphicsSystem::getLiveTextureHandle(QPixmap *pixmap)
-{
- QMeeGoLivePixmapData *pixmapData = static_cast<QMeeGoLivePixmapData*>(pixmap->data_ptr().data());
- return pixmapData->handle();
-}
-
-void* QMeeGoGraphicsSystem::createFenceSync()
-{
- QGLShareContextScope ctx(qt_gl_share_widget()->context());
- QMeeGoExtensions::ensureInitialized();
- return QMeeGoExtensions::eglCreateSyncKHR(QEgl::display(), EGL_SYNC_FENCE_KHR, NULL);
-}
-
-void QMeeGoGraphicsSystem::destroyFenceSync(void *fenceSync)
-{
- QGLShareContextScope ctx(qt_gl_share_widget()->context());
- QMeeGoExtensions::ensureInitialized();
- QMeeGoExtensions::eglDestroySyncKHR(QEgl::display(), fenceSync);
-}
-
-QString QMeeGoGraphicsSystem::runningGraphicsSystemName()
-{
- if (!QApplicationPrivate::instance()) {
- qWarning("Querying graphics system but application not running yet!");
- return QString();
- }
-
- QString name = QApplicationPrivate::instance()->graphics_system_name;
- if (name == QLatin1String("runtime")) {
- QRuntimeGraphicsSystem *rsystem = (QRuntimeGraphicsSystem *) QApplicationPrivate::instance()->graphics_system;
- name = rsystem->graphicsSystemName();
- }
-
- return name;
-}
-
-void QMeeGoGraphicsSystem::switchToMeeGo()
-{
- if (switchPolicy == NoSwitch || meeGoRunning())
- return;
-
- if (QApplicationPrivate::instance()->graphics_system_name != QLatin1String("runtime"))
- qWarning("Can't switch to meego - switching only supported with 'runtime' graphics system.");
- else {
- triggerSwitchCallbacks(0, "meego");
-
- QApplication *app = static_cast<QApplication *>(QCoreApplication::instance());
- app->setGraphicsSystem(QLatin1String("meego"));
-
- triggerSwitchCallbacks(1, "meego");
- }
-}
-
-void QMeeGoGraphicsSystem::switchToRaster()
-{
- if (switchPolicy == NoSwitch || runningGraphicsSystemName() == QLatin1String("raster"))
- return;
-
- if (QApplicationPrivate::instance()->graphics_system_name != QLatin1String("runtime"))
- qWarning("Can't switch to raster - switching only supported with 'runtime' graphics system.");
- else {
- triggerSwitchCallbacks(0, "raster");
-
- QApplication *app = static_cast<QApplication *>(QCoreApplication::instance());
- app->setGraphicsSystem(QLatin1String("raster"));
-
- QMeeGoLivePixmapData::invalidateSurfaces();
-
- triggerSwitchCallbacks(1, "raster");
- }
-}
-
-void QMeeGoGraphicsSystem::registerSwitchCallback(QMeeGoSwitchCallback callback)
-{
- switchCallbacks << callback;
-}
-
-void QMeeGoGraphicsSystem::triggerSwitchCallbacks(int type, const char *name)
-{
- for (int i = 0; i < switchCallbacks.size(); ++i)
- switchCallbacks.at(i)(type, name);
-}
-
-/* C API */
-
-int qt_meego_image_to_egl_shared_image(const QImage &image)
-{
- return QMeeGoPixmapData::imageToEGLSharedImage(image);
-}
-
-QPixmapData* qt_meego_pixmapdata_from_egl_shared_image(Qt::HANDLE handle, const QImage &softImage)
-{
- return QMeeGoGraphicsSystem::pixmapDataFromEGLSharedImage(handle, softImage);
-}
-
-QPixmapData* qt_meego_pixmapdata_with_gl_texture(int w, int h)
-{
- return QMeeGoGraphicsSystem::pixmapDataWithGLTexture(w, h);
-}
-
-bool qt_meego_destroy_egl_shared_image(Qt::HANDLE handle)
-{
- return QMeeGoPixmapData::destroyEGLSharedImage(handle);
-}
-
-void qt_meego_set_surface_fixed_size(int width, int height)
-{
- QMeeGoGraphicsSystem::setSurfaceFixedSize(width, height);
-}
-
-void qt_meego_set_surface_scaling(int x, int y, int width, int height)
-{
- QMeeGoGraphicsSystem::setSurfaceScaling(x, y, width, height);
-}
-
-void qt_meego_set_translucent(bool translucent)
-{
- QMeeGoGraphicsSystem::setTranslucent(translucent);
-}
-
-void qt_meego_update_egl_shared_image_pixmap(QPixmap *pixmap)
-{
- QMeeGoGraphicsSystem::updateEGLSharedImagePixmap(pixmap);
-}
-
-QPixmapData* qt_meego_pixmapdata_with_new_live_texture(int w, int h, QImage::Format format)
-{
- return QMeeGoGraphicsSystem::pixmapDataWithNewLiveTexture(w, h, format);
-}
-
-QPixmapData* qt_meego_pixmapdata_from_live_texture_handle(Qt::HANDLE handle)
-{
- return QMeeGoGraphicsSystem::pixmapDataFromLiveTextureHandle(handle);
-}
-
-QImage* qt_meego_live_texture_lock(QPixmap *pixmap, void *fenceSync)
-{
- return QMeeGoGraphicsSystem::lockLiveTexture(pixmap, fenceSync);
-}
-
-bool qt_meego_live_texture_release(QPixmap *pixmap, QImage *image)
-{
- return QMeeGoGraphicsSystem::releaseLiveTexture(pixmap, image);
-}
-
-Qt::HANDLE qt_meego_live_texture_get_handle(QPixmap *pixmap)
-{
- return QMeeGoGraphicsSystem::getLiveTextureHandle(pixmap);
-}
-
-void* qt_meego_create_fence_sync(void)
-{
- return QMeeGoGraphicsSystem::createFenceSync();
-}
-
-void qt_meego_destroy_fence_sync(void* fs)
-{
- return QMeeGoGraphicsSystem::destroyFenceSync(fs);
-}
-
-void qt_meego_invalidate_live_surfaces(void)
-{
- return QMeeGoLivePixmapData::invalidateSurfaces();
-}
-
-void qt_meego_switch_to_raster(void)
-{
- QMeeGoGraphicsSystem::switchToRaster();
-}
-
-void qt_meego_switch_to_meego(void)
-{
- QMeeGoGraphicsSystem::switchToMeeGo();
-}
-
-void qt_meego_register_switch_callback(QMeeGoSwitchCallback callback)
-{
- QMeeGoGraphicsSystem::registerSwitchCallback(callback);
-}
-
-void qt_meego_set_switch_policy(int policy)
-{
- QMeeGoGraphicsSystem::switchPolicy = QMeeGoGraphicsSystem::SwitchPolicy(policy);
-}
-
-#include "qmeegographicssystem.moc"
diff --git a/src/plugins/graphicssystems/meego/qmeegographicssystem.h b/src/plugins/graphicssystems/meego/qmeegographicssystem.h
deleted file mode 100644
index 7299af56be..0000000000
--- a/src/plugins/graphicssystems/meego/qmeegographicssystem.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef MGRAPHICSSYSTEM_H
-#define MGRAPHICSSYSTEM_H
-
-#include <private/qgraphicssystem_p.h>
-#include <EGL/egl.h>
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-
-extern "C" typedef void (*QMeeGoSwitchCallback)(int type, const char *name);
-
-class QMeeGoGraphicsSystem : public QGraphicsSystem
-{
-public:
- enum SwitchPolicy { AutomaticSwitch, ManualSwitch, NoSwitch };
-
- QMeeGoGraphicsSystem();
- ~QMeeGoGraphicsSystem();
-
- virtual QWindowSurface *createWindowSurface(QWidget *widget) const;
- virtual QPixmapData *createPixmapData(QPixmapData::PixelType) const;
- virtual QPixmapData *createPixmapData(QPixmapData *origin);
-
- static QPixmapData *wrapPixmapData(QPixmapData *pmd);
- static void setSurfaceFixedSize(int width, int height);
- static void setSurfaceScaling(int x, int y, int width, int height);
- static void setTranslucent(bool translucent);
-
- static QPixmapData *pixmapDataFromEGLSharedImage(Qt::HANDLE handle, const QImage &softImage);
- static QPixmapData *pixmapDataFromEGLImage(Qt::HANDLE handle);
- static QPixmapData *pixmapDataWithGLTexture(int w, int h);
- static void updateEGLSharedImagePixmap(QPixmap *pixmap);
-
- static QPixmapData *pixmapDataWithNewLiveTexture(int w, int h, QImage::Format format);
- static QPixmapData *pixmapDataFromLiveTextureHandle(Qt::HANDLE handle);
- static QImage *lockLiveTexture(QPixmap* pixmap, void* fenceSync);
- static bool releaseLiveTexture(QPixmap *pixmap, QImage *image);
- static Qt::HANDLE getLiveTextureHandle(QPixmap *pixmap);
-
- static void* createFenceSync();
- static void destroyFenceSync(void* fenceSync);
-
- static void switchToRaster();
- static void switchToMeeGo();
- static QString runningGraphicsSystemName();
-
- static void registerSwitchCallback(QMeeGoSwitchCallback callback);
-
- static SwitchPolicy switchPolicy;
-
-private:
- static bool meeGoRunning();
- static EGLSurface getSurfaceForLiveTexturePixmap(QPixmap *pixmap);
- static void destroySurfaceForLiveTexturePixmap(QPixmapData* pmd);
- static void triggerSwitchCallbacks(int type, const char *name);
-
- static bool surfaceWasCreated;
- static QHash<Qt::HANDLE, QPixmap*> liveTexturePixmaps;
- static QList<QMeeGoSwitchCallback> switchCallbacks;
-};
-
-/* C api */
-
-extern "C" {
- Q_DECL_EXPORT int qt_meego_image_to_egl_shared_image(const QImage &image);
- Q_DECL_EXPORT QPixmapData* qt_meego_pixmapdata_from_egl_shared_image(Qt::HANDLE handle, const QImage &softImage);
- Q_DECL_EXPORT QPixmapData* qt_meego_pixmapdata_with_gl_texture(int w, int h);
- Q_DECL_EXPORT void qt_meego_update_egl_shared_image_pixmap(QPixmap *pixmap);
- Q_DECL_EXPORT bool qt_meego_destroy_egl_shared_image(Qt::HANDLE handle);
- Q_DECL_EXPORT void qt_meego_set_surface_fixed_size(int width, int height);
- Q_DECL_EXPORT void qt_meego_set_surface_scaling(int x, int y, int width, int height);
- Q_DECL_EXPORT void qt_meego_set_translucent(bool translucent);
- Q_DECL_EXPORT QPixmapData* qt_meego_pixmapdata_with_new_live_texture(int w, int h, QImage::Format format);
- Q_DECL_EXPORT QPixmapData* qt_meego_pixmapdata_from_live_texture_handle(Qt::HANDLE handle);
- Q_DECL_EXPORT QImage* qt_meego_live_texture_lock(QPixmap *pixmap, void *fenceSync);
- Q_DECL_EXPORT bool qt_meego_live_texture_release(QPixmap *pixmap, QImage *image);
- Q_DECL_EXPORT Qt::HANDLE qt_meego_live_texture_get_handle(QPixmap *pixmap);
- Q_DECL_EXPORT void* qt_meego_create_fence_sync(void);
- Q_DECL_EXPORT void qt_meego_destroy_fence_sync(void* fs);
- Q_DECL_EXPORT void qt_meego_invalidate_live_surfaces(void);
- Q_DECL_EXPORT void qt_meego_switch_to_raster(void);
- Q_DECL_EXPORT void qt_meego_switch_to_meego(void);
- Q_DECL_EXPORT void qt_meego_register_switch_callback(QMeeGoSwitchCallback callback);
- Q_DECL_EXPORT void qt_meego_set_switch_policy(int policy);
-}
-
-#endif
diff --git a/src/plugins/graphicssystems/meego/qmeegographicssystemplugin.cpp b/src/plugins/graphicssystems/meego/qmeegographicssystemplugin.cpp
deleted file mode 100644
index 493d14e962..0000000000
--- a/src/plugins/graphicssystems/meego/qmeegographicssystemplugin.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QDebug>
-#include "qmeegographicssystemplugin.h"
-#include "qmeegographicssystem.h"
-
-QStringList QMeeGoGraphicsSystemPlugin::keys() const
-{
- QStringList list;
- list << "meego";
- return list;
-}
-
-QGraphicsSystem *QMeeGoGraphicsSystemPlugin::create(const QString&)
-{
- return new QMeeGoGraphicsSystem;
-}
-
-Q_EXPORT_PLUGIN2(meego, QMeeGoGraphicsSystemPlugin)
diff --git a/src/plugins/graphicssystems/meego/qmeegographicssystemplugin.h b/src/plugins/graphicssystems/meego/qmeegographicssystemplugin.h
deleted file mode 100644
index e38033a6cd..0000000000
--- a/src/plugins/graphicssystems/meego/qmeegographicssystemplugin.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef MGRAPHICSSYSTEMPLUGIN_H
-#define MGRAPHICSSYSTEMPLUGIN_H
-
-#include <private/qgraphicssystemplugin_p.h>
-
-class QMeeGoGraphicsSystemPlugin : public QGraphicsSystemPlugin
-{
-public:
- virtual QStringList keys() const;
- virtual QGraphicsSystem *create(const QString&);
-};
-
-#endif
diff --git a/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.cpp b/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.cpp
deleted file mode 100644
index 40421bc8f0..0000000000
--- a/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.cpp
+++ /dev/null
@@ -1,323 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qmeegolivepixmapdata.h"
-#include "qmeegorasterpixmapdata.h"
-#include <private/qimage_p.h>
-#include <private/qwindowsurface_gl_p.h>
-#include <private/qeglcontext_p.h>
-#include <private/qapplication_p.h>
-#include <private/qgraphicssystem_runtime_p.h>
-#include <private/qpixmap_x11_p.h>
-#include <stdio.h>
-
-static QMeeGoLivePixmapDataList all_live_pixmaps;
-
-static EGLint lock_attribs[] = {
- EGL_MAP_PRESERVE_PIXELS_KHR, EGL_TRUE,
- EGL_LOCK_USAGE_HINT_KHR, EGL_READ_SURFACE_BIT_KHR | EGL_WRITE_SURFACE_BIT_KHR,
- EGL_NONE
-};
-
-static EGLint preserved_attribs[] = {
- EGL_IMAGE_PRESERVED_KHR, EGL_TRUE,
- EGL_NONE
-};
-
-// as copied from qwindowsurface.cpp
-void qt_scrollRectInImage(QImage &img, const QRect &rect, const QPoint &offset)
-{
- // make sure we don't detach
- uchar *mem = const_cast<uchar*>(const_cast<const QImage &>(img).bits());
-
- int lineskip = img.bytesPerLine();
- int depth = img.depth() >> 3;
-
- 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;
-
- if (r.top() < p.y()) {
- src = mem + r.bottom() * lineskip + r.left() * depth;
- dest = mem + (p.y() + r.height() - 1) * lineskip + p.x() * depth;
- lineskip = -lineskip;
- } else {
- src = mem + r.top() * lineskip + r.left() * depth;
- dest = mem + p.y() * lineskip + p.x() * depth;
- }
-
- const int w = r.width();
- int h = r.height();
- const int bytes = w * depth;
-
- // overlapping segments?
- if (offset.y() == 0 && qAbs(offset.x()) < w) {
- do {
- ::memmove(dest, src, bytes);
- dest += lineskip;
- src += lineskip;
- } while (--h);
- } else {
- do {
- ::memcpy(dest, src, bytes);
- dest += lineskip;
- src += lineskip;
- } while (--h);
- }
-}
-
-/* Public */
-
-QMeeGoLivePixmapData::QMeeGoLivePixmapData(int w, int h, QImage::Format format) : QGLPixmapData(QPixmapData::PixmapType)
-{
- QImage image(w, h, format);
- QX11PixmapData *pmd = new QX11PixmapData(QPixmapData::PixmapType);
- pmd->fromImage(image, Qt::NoOpaqueDetection);
- backingX11Pixmap = new QPixmap(pmd);
-
- initializeThroughEGLImage();
-
- pos = all_live_pixmaps.insert(all_live_pixmaps.begin(), this);
-}
-
-QMeeGoLivePixmapData::QMeeGoLivePixmapData(Qt::HANDLE h) : QGLPixmapData(QPixmapData::PixmapType)
-{
- backingX11Pixmap = new QPixmap(QPixmap::fromX11Pixmap(h));
- initializeThroughEGLImage();
-
- pos = all_live_pixmaps.insert(all_live_pixmaps.begin(), this);
-}
-
-QMeeGoLivePixmapData::~QMeeGoLivePixmapData()
-{
- delete backingX11Pixmap;
- all_live_pixmaps.erase(pos);
-}
-
-void QMeeGoLivePixmapData::initializeThroughEGLImage()
-{
- if (texture()->id != 0)
- return;
-
- QGLShareContextScope ctx(qt_gl_share_widget()->context());
- QMeeGoExtensions::ensureInitialized();
-
- EGLImageKHR eglImage = EGL_NO_IMAGE_KHR;
- GLuint newTextureId = 0;
-
- eglImage = QEgl::eglCreateImageKHR(QEgl::display(), EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR,
- (EGLClientBuffer) backingX11Pixmap->handle(), preserved_attribs);
-
- if (eglImage == EGL_NO_IMAGE_KHR) {
- qWarning("eglCreateImageKHR failed (live texture)!");
- return;
- }
-
- glGenTextures(1, &newTextureId);
- glBindTexture(GL_TEXTURE_2D, newTextureId);
-
- glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (EGLImageKHR) eglImage);
- if (glGetError() == GL_NO_ERROR) {
- resize(backingX11Pixmap->width(), backingX11Pixmap->height());
- texture()->id = newTextureId;
- texture()->options &= ~QGLContext::InvertedYBindOption;
- m_hasAlpha = backingX11Pixmap->hasAlphaChannel();
- } else {
- qWarning("Failed to create a texture from an egl image (live texture)!");
- glDeleteTextures(1, &newTextureId);
- }
-
- QEgl::eglDestroyImageKHR(QEgl::display(), eglImage);
-}
-
-QPixmapData *QMeeGoLivePixmapData::createCompatiblePixmapData() const
-{
- qWarning("Create compatible called on live pixmap! Expect fail soon...");
- return new QMeeGoRasterPixmapData(pixelType());
-}
-
-QImage* QMeeGoLivePixmapData::lock(EGLSyncKHR fenceSync)
-{
- QGLShareContextScope ctx(qt_gl_share_widget()->context());
- QMeeGoExtensions::ensureInitialized();
-
- if (fenceSync) {
- QMeeGoExtensions::eglClientWaitSyncKHR(QEgl::display(),
- fenceSync,
- EGL_SYNC_FLUSH_COMMANDS_BIT_KHR,
- EGL_FOREVER_KHR);
- }
-
- void *data = 0;
- int pitch = 0;
- int surfaceWidth = 0;
- int surfaceHeight = 0;
- EGLSurface surface = 0;
- QImage::Format format;
- lockedImage = QImage();
-
- surface = getSurfaceForBackingPixmap();
- if (! QMeeGoExtensions::eglLockSurfaceKHR(QEgl::display(), surface, lock_attribs)) {
- qWarning("Failed to lock surface (live texture)!");
- return &lockedImage;
- }
-
- eglQuerySurface(QEgl::display(), surface, EGL_BITMAP_POINTER_KHR, (EGLint*) &data);
- eglQuerySurface(QEgl::display(), surface, EGL_BITMAP_PITCH_KHR, (EGLint*) &pitch);
- eglQuerySurface(QEgl::display(), surface, EGL_WIDTH, (EGLint*) &surfaceWidth);
- eglQuerySurface(QEgl::display(), surface, EGL_HEIGHT, (EGLint*) &surfaceHeight);
-
- // Ok, here we know we just support those two formats. Real solution would be:
- // query also the format.
- if (backingX11Pixmap->depth() > 16)
- format = QImage::Format_ARGB32_Premultiplied;
- else
- format = QImage::Format_RGB16;
-
- if (data == NULL || pitch == 0) {
- qWarning("Failed to query the live texture!");
- return &lockedImage;
- }
-
- if (width() != surfaceWidth || height() != surfaceHeight) {
- qWarning("Live texture dimensions don't match!");
- QMeeGoExtensions::eglUnlockSurfaceKHR(QEgl::display(), surface);
- return &lockedImage;
- }
-
- lockedImage = QImage((uchar *) data, width(), height(), pitch, format);
- return &lockedImage;
-}
-
-bool QMeeGoLivePixmapData::release(QImage* /*img*/)
-{
- QGLShareContextScope ctx(qt_gl_share_widget()->context());
- QMeeGoExtensions::ensureInitialized();
-
- if (QMeeGoExtensions::eglUnlockSurfaceKHR(QEgl::display(), getSurfaceForBackingPixmap())) {
- lockedImage = QImage();
- return true;
- } else {
- lockedImage = QImage();
- return false;
- }
-}
-
-Qt::HANDLE QMeeGoLivePixmapData::handle()
-{
- return backingX11Pixmap->handle();
-}
-
-bool QMeeGoLivePixmapData::scroll(int dx, int dy, const QRect &rect)
-{
- lock(NULL);
-
- if (!lockedImage.isNull())
- qt_scrollRectInImage(lockedImage, rect, QPoint(dx, dy));
-
- release(&lockedImage);
- return true;
-}
-
-EGLSurface QMeeGoLivePixmapData::getSurfaceForBackingPixmap()
-{
- initializeThroughEGLImage();
-
- // This code is a crative remix of the stuff that can be found in the
- // Qt's TFP implementation in /src/opengl/qgl_x11egl.cpp ::bindiTextureFromNativePixmap
- QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(backingX11Pixmap->data_ptr().data());
- Q_ASSERT(pixmapData->classId() == QPixmapData::X11Class);
- bool hasAlpha = pixmapData->hasAlphaChannel();
-
- if (pixmapData->gl_surface &&
- hasAlpha == (pixmapData->flags & QX11PixmapData::GlSurfaceCreatedWithAlpha))
- return pixmapData->gl_surface;
-
- // Check to see if the surface is still valid
- if (pixmapData->gl_surface &&
- hasAlpha != ((pixmapData->flags & QX11PixmapData::GlSurfaceCreatedWithAlpha) > 0)) {
- // Surface is invalid!
- destroySurfaceForPixmapData(pixmapData);
- }
-
- if (pixmapData->gl_surface == 0) {
- EGLConfig config = QEgl::defaultConfig(QInternal::Pixmap,
- QEgl::OpenGL,
- hasAlpha ? QEgl::Translucent : QEgl::NoOptions);
-
- pixmapData->gl_surface = (void*)QEgl::createSurface(backingX11Pixmap, config);
-
- if (hasAlpha)
- pixmapData->flags |= QX11PixmapData::GlSurfaceCreatedWithAlpha;
- else
- pixmapData->flags &= ~QX11PixmapData::GlSurfaceCreatedWithAlpha;
-
- if (pixmapData->gl_surface == (void*)EGL_NO_SURFACE)
- return NULL;
- }
-
- return pixmapData->gl_surface;
-}
-
-void QMeeGoLivePixmapData::destroySurfaceForPixmapData(QPixmapData* pmd)
-{
- Q_ASSERT(pmd->classId() == QPixmapData::X11Class);
- QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(pmd);
- if (pixmapData->gl_surface) {
- eglDestroySurface(QEgl::display(), (EGLSurface)pixmapData->gl_surface);
- pixmapData->gl_surface = 0;
- }
-}
-
-void QMeeGoLivePixmapData::invalidateSurfaces()
-{
- foreach (QMeeGoLivePixmapData *data, all_live_pixmaps) {
- QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(data->backingX11Pixmap->data_ptr().data());
- *data->texture() = QGLTexture();
- pixmapData->gl_surface = 0;
- }
-}
diff --git a/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.h b/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.h
deleted file mode 100644
index 73f75143e3..0000000000
--- a/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef MLIVEPIXMAPDATA_H
-#define MLIVEPIXMAPDATA_H
-
-#include <QLinkedList>
-#include <private/qpixmapdata_gl_p.h>
-#include "qmeegoextensions.h"
-
-class QMeeGoLivePixmapData;
-typedef QLinkedList<QMeeGoLivePixmapData *> QMeeGoLivePixmapDataList;
-
-class QMeeGoLivePixmapData : public QGLPixmapData
-{
-public:
- QMeeGoLivePixmapData(int w, int h, QImage::Format format);
- QMeeGoLivePixmapData(Qt::HANDLE h);
- ~QMeeGoLivePixmapData();
-
- QPixmapData *createCompatiblePixmapData() const;
- bool scroll(int dx, int dy, const QRect &rect);
-
- void initializeThroughEGLImage();
-
- QImage* lock(EGLSyncKHR fenceSync);
- bool release(QImage *img);
- Qt::HANDLE handle();
-
- EGLSurface getSurfaceForBackingPixmap();
- void destroySurfaceForPixmapData(QPixmapData* pmd);
-
- QPixmap *backingX11Pixmap;
- QImage lockedImage;
- QMeeGoLivePixmapDataList::Iterator pos;
-
- static void invalidateSurfaces();
-};
-
-#endif
diff --git a/src/plugins/graphicssystems/meego/qmeegopixmapdata.cpp b/src/plugins/graphicssystems/meego/qmeegopixmapdata.cpp
deleted file mode 100644
index ec6c33fa07..0000000000
--- a/src/plugins/graphicssystems/meego/qmeegopixmapdata.cpp
+++ /dev/null
@@ -1,224 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qmeegopixmapdata.h"
-#include "qmeegoextensions.h"
-#include "qmeegorasterpixmapdata.h"
-#include <private/qimage_p.h>
-#include <private/qwindowsurface_gl_p.h>
-#include <private/qeglcontext_p.h>
-#include <private/qapplication_p.h>
-#include <private/qgraphicssystem_runtime_p.h>
-
-// from dithering.cpp
-extern unsigned short* convertRGB32_to_RGB565(const unsigned char *in, int width, int height, int stride);
-extern unsigned short* convertARGB32_to_RGBA4444(const unsigned char *in, int width, int height, int stride);
-extern unsigned char* convertBGRA32_to_RGBA32(const unsigned char *in, int width, int height, int stride);
-
-static EGLint preserved_image_attribs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE };
-
-QHash <void*, QMeeGoImageInfo*> QMeeGoPixmapData::sharedImagesMap;
-
-/* Public */
-
-QMeeGoPixmapData::QMeeGoPixmapData() : QGLPixmapData(QPixmapData::PixmapType)
-{
-}
-
-void QMeeGoPixmapData::fromTexture(GLuint textureId, int w, int h, bool alpha)
-{
- resize(w, h);
- texture()->id = textureId;
- m_hasAlpha = alpha;
- softImage = QImage();
-}
-
-QImage QMeeGoPixmapData::toImage() const
-{
- return softImage;
-}
-
-void QMeeGoPixmapData::fromImage(const QImage &image,
- Qt::ImageConversionFlags flags)
-{
- void *rawResource = static_cast <void *> (((QImage &) image).data_ptr()->data);
-
- if (sharedImagesMap.contains(rawResource)) {
- QMeeGoImageInfo *info = sharedImagesMap.value(rawResource);
- fromEGLSharedImage(info->handle, image);
- } else {
- // This should *never* happen since the graphics system should never
- // create a QMeeGoPixmapData for an origin that doesn't contain a raster
- // image we know about. But...
- qWarning("QMeeGoPixmapData::fromImage called on non-know resource. Falling back...");
- QGLPixmapData::fromImage(image, flags);
- }
-}
-
-void QMeeGoPixmapData::fromEGLSharedImage(Qt::HANDLE handle, const QImage &si)
-{
- if (si.isNull())
- qFatal("Trying to build pixmap with an empty/null softimage!");
-
- QGLShareContextScope ctx(qt_gl_share_widget()->context());
-
- QMeeGoExtensions::ensureInitialized();
-
- bool textureIsBound = false;
- GLuint newTextureId;
- GLint newWidth, newHeight;
-
- glGenTextures(1, &newTextureId);
- glBindTexture(GL_TEXTURE_2D, newTextureId);
-
- EGLImageKHR image = QEgl::eglCreateImageKHR(QEgl::display(), EGL_NO_CONTEXT, EGL_SHARED_IMAGE_NOK,
- (EGLClientBuffer)handle, preserved_image_attribs);
-
- if (image != EGL_NO_IMAGE_KHR) {
- glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
- GLint err = glGetError();
- if (err == GL_NO_ERROR)
- textureIsBound = true;
-
- QMeeGoExtensions::eglQueryImageNOK(QEgl::display(), image, EGL_WIDTH, &newWidth);
- QMeeGoExtensions::eglQueryImageNOK(QEgl::display(), image, EGL_HEIGHT, &newHeight);
-
- QEgl::eglDestroyImageKHR(QEgl::display(), image);
- }
-
- if (textureIsBound) {
- fromTexture(newTextureId, newWidth, newHeight,
- (si.hasAlphaChannel() && const_cast<QImage &>(si).data_ptr()->checkForAlphaPixels()));
- texture()->options &= ~QGLContext::InvertedYBindOption;
- softImage = si;
- QMeeGoPixmapData::registerSharedImage(handle, softImage);
- } else {
- qWarning("Failed to create a texture from a shared image!");
- glDeleteTextures(1, &newTextureId);
- }
-}
-
-Qt::HANDLE QMeeGoPixmapData::imageToEGLSharedImage(const QImage &image)
-{
- QGLShareContextScope ctx(qt_gl_share_widget()->context());
-
- QMeeGoExtensions::ensureInitialized();
-
- GLuint textureId;
-
- glGenTextures(1, &textureId);
- glBindTexture(GL_TEXTURE_2D, textureId);
- if (image.hasAlphaChannel() && const_cast<QImage &>(image).data_ptr()->checkForAlphaPixels()) {
- void *converted = convertBGRA32_to_RGBA32(image.bits(), image.width(), image.height(), image.bytesPerLine());
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width(), image.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, converted);
- free(converted);
- } else {
- void *converted = convertRGB32_to_RGB565(image.bits(), image.width(), image.height(), image.bytesPerLine());
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image.width(), image.height(), 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, converted);
- free(converted);
- }
-
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-
- glBindTexture(GL_TEXTURE_2D, textureId);
- EGLImageKHR eglimage = QEgl::eglCreateImageKHR(QEgl::display(), QEglContext::currentContext(QEgl::OpenGL)->context(),
- EGL_GL_TEXTURE_2D_KHR,
- (EGLClientBuffer) textureId,
- preserved_image_attribs);
- glDeleteTextures(1, &textureId);
- if (eglimage) {
- EGLNativeSharedImageTypeNOK handle = QMeeGoExtensions::eglCreateSharedImageNOK(QEgl::display(), eglimage, NULL);
- QEgl::eglDestroyImageKHR(QEgl::display(), eglimage);
- return (Qt::HANDLE) handle;
- } else {
- qWarning("Failed to create shared image from pixmap/texture!");
- return 0;
- }
-}
-
-void QMeeGoPixmapData::updateFromSoftImage()
-{
- // FIXME That's broken with recent 16bit textures changes.
- m_dirty = true;
- m_source = softImage;
- ensureCreated();
-
- if (softImage.width() != w || softImage.height() != h)
- qWarning("Ooops, looks like softImage changed dimensions since last updated! Corruption ahead?!");
-}
-
-bool QMeeGoPixmapData::destroyEGLSharedImage(Qt::HANDLE h)
-{
- QGLShareContextScope ctx(qt_gl_share_widget()->context());
- QMeeGoExtensions::ensureInitialized();
-
- QMutableHashIterator <void*, QMeeGoImageInfo*> i(sharedImagesMap);
- while (i.hasNext()) {
- i.next();
- if (i.value()->handle == h)
- i.remove();
- }
-
- return QMeeGoExtensions::eglDestroySharedImageNOK(QEgl::display(), (EGLNativeSharedImageTypeNOK) h);
-}
-
-void QMeeGoPixmapData::registerSharedImage(Qt::HANDLE handle, const QImage &si)
-{
- void *raw = static_cast <void *> (((QImage) si).data_ptr()->data);
- QMeeGoImageInfo *info;
-
- if (! sharedImagesMap.contains(raw)) {
- info = new QMeeGoImageInfo;
- info->handle = handle;
- info->rawFormat = si.format();
- sharedImagesMap.insert(raw, info);
- } else {
- info = sharedImagesMap.value(raw);
- if (info->handle != handle || info->rawFormat != si.format())
- qWarning("Inconsistency detected: overwriting entry in sharedImagesMap but handle/format different");
- }
-}
-
-QPixmapData *QMeeGoPixmapData::createCompatiblePixmapData() const
-{
- return new QMeeGoRasterPixmapData(pixelType());
-}
diff --git a/src/plugins/graphicssystems/meego/qmeegopixmapdata.h b/src/plugins/graphicssystems/meego/qmeegopixmapdata.h
deleted file mode 100644
index f1ff255b08..0000000000
--- a/src/plugins/graphicssystems/meego/qmeegopixmapdata.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef MPIXMAPDATA_H
-#define MPIXMAPDATA_H
-
-#include <private/qpixmapdata_gl_p.h>
-
-struct QMeeGoImageInfo
-{
- Qt::HANDLE handle;
- QImage::Format rawFormat;
-};
-
-class QMeeGoPixmapData : public QGLPixmapData
-{
-public:
- QMeeGoPixmapData();
- void fromTexture(GLuint textureId, int w, int h, bool alpha);
- QPixmapData *createCompatiblePixmapData() const;
-
- virtual void fromEGLSharedImage(Qt::HANDLE handle, const QImage &softImage);
- virtual void fromImage (const QImage &image, Qt::ImageConversionFlags flags);
- virtual QImage toImage() const;
- virtual void updateFromSoftImage();
-
- QImage softImage;
-
- static QHash <void*, QMeeGoImageInfo*> sharedImagesMap;
-
- static Qt::HANDLE imageToEGLSharedImage(const QImage &image);
- static bool destroyEGLSharedImage(Qt::HANDLE h);
- static void registerSharedImage(Qt::HANDLE handle, const QImage &si);
-};
-
-#endif
diff --git a/src/plugins/graphicssystems/meego/qmeegorasterpixmapdata.cpp b/src/plugins/graphicssystems/meego/qmeegorasterpixmapdata.cpp
deleted file mode 100644
index 3d6545e017..0000000000
--- a/src/plugins/graphicssystems/meego/qmeegorasterpixmapdata.cpp
+++ /dev/null
@@ -1,60 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qmeegorasterpixmapdata.h"
-
-/* Public */
-
-QMeeGoRasterPixmapData::QMeeGoRasterPixmapData() : QRasterPixmapData(QPixmapData::PixmapType)
-{
-}
-
-QMeeGoRasterPixmapData::QMeeGoRasterPixmapData(QPixmapData::PixelType t) : QRasterPixmapData(t)
-{
-}
-
-void QMeeGoRasterPixmapData::copy(const QPixmapData *data, const QRect &rect)
-{
- if (data->classId() == QPixmapData::OpenGLClass)
- fromImage(data->toImage(rect).copy(), Qt::NoOpaqueDetection);
- else
- QRasterPixmapData::copy(data, rect);
-}
diff --git a/src/plugins/graphicssystems/meego/qmeegorasterpixmapdata.h b/src/plugins/graphicssystems/meego/qmeegorasterpixmapdata.h
deleted file mode 100644
index 10fa61c972..0000000000
--- a/src/plugins/graphicssystems/meego/qmeegorasterpixmapdata.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef MRASTERPIXMAPDATA_H
-#define MRASTERPIXMAPDATA_H
-
-#include <private/qpixmap_raster_p.h>
-
-class QMeeGoRasterPixmapData : public QRasterPixmapData
-{
-public:
- QMeeGoRasterPixmapData();
- QMeeGoRasterPixmapData(QPixmapData::PixelType t);
- void copy(const QPixmapData *data, const QRect &rect);
-};
-
-#endif
diff --git a/src/plugins/graphicssystems/opengl/main.cpp b/src/plugins/graphicssystems/opengl/main.cpp
deleted file mode 100644
index ee0fa802dd..0000000000
--- a/src/plugins/graphicssystems/opengl/main.cpp
+++ /dev/null
@@ -1,95 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <private/qgraphicssystemplugin_p.h>
-#include <private/qgraphicssystem_gl_p.h>
-#include <qgl.h>
-
-QT_BEGIN_NAMESPACE
-
-class QGLGraphicsSystemPlugin : public QGraphicsSystemPlugin
-{
-public:
- QStringList keys() const;
- QGraphicsSystem *create(const QString&);
-};
-
-QStringList QGLGraphicsSystemPlugin::keys() const
-{
- QStringList list;
- list << QLatin1String("OpenGL") << QLatin1String("OpenGL1");
-#if !defined(QT_OPENGL_ES_1)
- list << QLatin1String("OpenGL2");
-#endif
-#if defined(Q_WS_X11) && !defined(QT_NO_EGL)
- list << QLatin1String("X11GL");
-#endif
- return list;
-}
-
-QGraphicsSystem* QGLGraphicsSystemPlugin::create(const QString& system)
-{
- if (system.toLower() == QLatin1String("opengl1")) {
- QGL::setPreferredPaintEngine(QPaintEngine::OpenGL);
- return new QGLGraphicsSystem(false);
- }
-
-#if !defined(QT_OPENGL_ES_1)
- if (system.toLower() == QLatin1String("opengl2")) {
- QGL::setPreferredPaintEngine(QPaintEngine::OpenGL2);
- return new QGLGraphicsSystem(false);
- }
-#endif
-
-#if defined(Q_WS_X11) && !defined(QT_NO_EGL)
- if (system.toLower() == QLatin1String("x11gl"))
- return new QGLGraphicsSystem(true);
-#endif
-
- if (system.toLower() == QLatin1String("opengl"))
- return new QGLGraphicsSystem(false);
-
- return 0;
-}
-
-Q_EXPORT_PLUGIN2(opengl, QGLGraphicsSystemPlugin)
-
-QT_END_NAMESPACE
diff --git a/src/plugins/graphicssystems/opengl/opengl.pro b/src/plugins/graphicssystems/opengl/opengl.pro
deleted file mode 100644
index fd3542ecf0..0000000000
--- a/src/plugins/graphicssystems/opengl/opengl.pro
+++ /dev/null
@@ -1,13 +0,0 @@
-TARGET = qglgraphicssystem
-load(qt_plugin)
-
-QT += core-private gui-private opengl-private
-
-DESTDIR = $$QT.gui.plugins/graphicssystems
-
-SOURCES = main.cpp
-
-target.path += $$[QT_INSTALL_PLUGINS]/graphicssystems
-INSTALLS += target
-
-symbian: TARGET.UID3 = 0x2002131B
diff --git a/src/plugins/graphicssystems/openvg/main.cpp b/src/plugins/graphicssystems/openvg/main.cpp
deleted file mode 100644
index 0aa265e50b..0000000000
--- a/src/plugins/graphicssystems/openvg/main.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <private/qgraphicssystemplugin_p.h>
-#include "qgraphicssystem_vg_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class QVGGraphicsSystemPlugin : public QGraphicsSystemPlugin
-{
-public:
- QStringList keys() const;
- QGraphicsSystem *create(const QString&);
-};
-
-QStringList QVGGraphicsSystemPlugin::keys() const
-{
- QStringList list;
- list << "OpenVG";
- return list;
-}
-
-QGraphicsSystem* QVGGraphicsSystemPlugin::create(const QString& system)
-{
- if (system.toLower() == "openvg")
- return new QVGGraphicsSystem;
-
- return 0;
-}
-
-Q_EXPORT_PLUGIN2(openvg, QVGGraphicsSystemPlugin)
-
-QT_END_NAMESPACE
diff --git a/src/plugins/graphicssystems/openvg/openvg.pro b/src/plugins/graphicssystems/openvg/openvg.pro
deleted file mode 100644
index 6a737790a2..0000000000
--- a/src/plugins/graphicssystems/openvg/openvg.pro
+++ /dev/null
@@ -1,14 +0,0 @@
-TARGET = qvggraphicssystem
-load(qt_plugin)
-
-QT += openvg
-
-DESTDIR = $$QT.gui.plugins/graphicssystems
-
-SOURCES = main.cpp qgraphicssystem_vg.cpp
-HEADERS = qgraphicssystem_vg_p.h
-
-target.path += $$[QT_INSTALL_PLUGINS]/graphicssystems
-INSTALLS += target
-
-symbian: TARGET.UID3 = 0x2001E62C
diff --git a/src/plugins/graphicssystems/openvg/qgraphicssystem_vg.cpp b/src/plugins/graphicssystems/openvg/qgraphicssystem_vg.cpp
deleted file mode 100644
index 829996b0b0..0000000000
--- a/src/plugins/graphicssystems/openvg/qgraphicssystem_vg.cpp
+++ /dev/null
@@ -1,88 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qgraphicssystem_vg_p.h"
-#include <QtOpenVG/private/qpixmapdata_vg_p.h>
-#include <QtOpenVG/private/qwindowsurface_vg_p.h>
-#include <QtOpenVG/private/qvgimagepool_p.h>
-#if defined(Q_OS_SYMBIAN)
-#include <QtGui/private/qwidget_p.h>
-#endif
-#include <QtGui/private/qapplication_p.h>
-
-QT_BEGIN_NAMESPACE
-
-QVGGraphicsSystem::QVGGraphicsSystem()
-{
- QApplicationPrivate::graphics_system_name = QLatin1String("openvg");
-}
-
-QPixmapData *QVGGraphicsSystem::createPixmapData(QPixmapData::PixelType type) const
-{
-#if !defined(QVG_NO_SINGLE_CONTEXT) && !defined(QVG_NO_PIXMAP_DATA)
- // Pixmaps can use QVGPixmapData; bitmaps must use raster.
- if (type == QPixmapData::PixmapType)
- return new QVGPixmapData(type);
- else
- return new QRasterPixmapData(type);
-#else
- return new QRasterPixmapData(type);
-#endif
-}
-
-QWindowSurface *QVGGraphicsSystem::createWindowSurface(QWidget *widget) const
-{
-#if defined(Q_OS_SYMBIAN)
- if (!QApplicationPrivate::instance()->useTranslucentEGLSurfaces) {
- QWidgetPrivate *d = qt_widget_private(widget);
- if (!d->isOpaque && widget->testAttribute(Qt::WA_TranslucentBackground))
- return d->createDefaultWindowSurface_sys();
- }
-#endif
- return new QVGWindowSurface(widget);
-}
-
-void QVGGraphicsSystem::releaseCachedResources()
-{
- QVGImagePool::instance()->hibernate();
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/graphicssystems/openvg/qgraphicssystem_vg_p.h b/src/plugins/graphicssystems/openvg/qgraphicssystem_vg_p.h
deleted file mode 100644
index 6f8f8dce66..0000000000
--- a/src/plugins/graphicssystems/openvg/qgraphicssystem_vg_p.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGRAPHICSSYSTEM_VG_P_H
-#define QGRAPHICSSYSTEM_VG_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtGui/private/qgraphicssystem_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QVGGraphicsSystem : public QGraphicsSystem
-{
-public:
- QVGGraphicsSystem();
-
- QPixmapData *createPixmapData(QPixmapData::PixelType type) const;
- QWindowSurface *createWindowSurface(QWidget *widget) const;
-
- void releaseCachedResources();
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/plugins/graphicssystems/shivavg/README b/src/plugins/graphicssystems/shivavg/README
deleted file mode 100644
index 15ee7101e8..0000000000
--- a/src/plugins/graphicssystems/shivavg/README
+++ /dev/null
@@ -1,8 +0,0 @@
-
-This graphics system uses ShivaVG (http://sourceforge.net/projects/shivavg)
-to perform OpenVG rendering on X11 systems. The graphics system name for
-the "-graphicssystem" command-line option is "ShivaVG".
-
-ShivaVG support is experimental, mostly to demonstrate how to integrate
-non-EGL OpenVG engines into the system. It will probably not produce
-good output.
diff --git a/src/plugins/graphicssystems/shivavg/main.cpp b/src/plugins/graphicssystems/shivavg/main.cpp
deleted file mode 100644
index 53bc782378..0000000000
--- a/src/plugins/graphicssystems/shivavg/main.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <private/qgraphicssystemplugin_p.h>
-#include "shivavggraphicssystem.h"
-
-QT_BEGIN_NAMESPACE
-
-class ShivaVGGraphicsSystemPlugin : public QGraphicsSystemPlugin
-{
-public:
- QStringList keys() const;
- QGraphicsSystem *create(const QString&);
-};
-
-QStringList ShivaVGGraphicsSystemPlugin::keys() const
-{
- QStringList list;
- list << "ShivaVG";
- return list;
-}
-
-QGraphicsSystem* ShivaVGGraphicsSystemPlugin::create(const QString& system)
-{
- if (system.toLower() == "shivavg")
- return new ShivaVGGraphicsSystem;
-
- return 0;
-}
-
-Q_EXPORT_PLUGIN2(shivavg, ShivaVGGraphicsSystemPlugin)
-
-QT_END_NAMESPACE
diff --git a/src/plugins/graphicssystems/shivavg/shivavg.pro b/src/plugins/graphicssystems/shivavg/shivavg.pro
deleted file mode 100644
index 1d934cd685..0000000000
--- a/src/plugins/graphicssystems/shivavg/shivavg.pro
+++ /dev/null
@@ -1,12 +0,0 @@
-TARGET = qshivavggraphicssystem
-load(qt_plugin)
-
-QT += openvg
-
-DESTDIR = $$QT.gui.plugins/graphicssystems
-
-SOURCES = main.cpp shivavggraphicssystem.cpp shivavgwindowsurface.cpp
-HEADERS = shivavggraphicssystem.h shivavgwindowsurface.h
-
-target.path += $$[QT_INSTALL_PLUGINS]/graphicssystems
-INSTALLS += target
diff --git a/src/plugins/graphicssystems/shivavg/shivavggraphicssystem.cpp b/src/plugins/graphicssystems/shivavg/shivavggraphicssystem.cpp
deleted file mode 100644
index 48526538ab..0000000000
--- a/src/plugins/graphicssystems/shivavg/shivavggraphicssystem.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "shivavggraphicssystem.h"
-#include "shivavgwindowsurface.h"
-#include <QtGui/private/qpixmap_raster_p.h>
-
-QT_BEGIN_NAMESPACE
-
-ShivaVGGraphicsSystem::ShivaVGGraphicsSystem()
-{
-}
-
-QPixmapData *ShivaVGGraphicsSystem::createPixmapData(QPixmapData::PixelType type) const
-{
- return new QRasterPixmapData(type);
-}
-
-QWindowSurface *ShivaVGGraphicsSystem::createWindowSurface(QWidget *widget) const
-{
- return new ShivaVGWindowSurface(widget);
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/graphicssystems/shivavg/shivavggraphicssystem.h b/src/plugins/graphicssystems/shivavg/shivavggraphicssystem.h
deleted file mode 100644
index a4c8cd67e4..0000000000
--- a/src/plugins/graphicssystems/shivavg/shivavggraphicssystem.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef SHIVAVGGRAPHICSSYSTEM_H
-#define SHIVAVGGRAPHICSSYSTEM_H
-
-#include <QtGui/private/qgraphicssystem_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class ShivaVGGraphicsSystem : public QGraphicsSystem
-{
-public:
- ShivaVGGraphicsSystem();
-
- QPixmapData *createPixmapData(QPixmapData::PixelType type) const;
- QWindowSurface *createWindowSurface(QWidget *widget) const;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/plugins/graphicssystems/shivavg/shivavgwindowsurface.cpp b/src/plugins/graphicssystems/shivavg/shivavgwindowsurface.cpp
deleted file mode 100644
index 448532ae92..0000000000
--- a/src/plugins/graphicssystems/shivavg/shivavgwindowsurface.cpp
+++ /dev/null
@@ -1,358 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#define GL_GLEXT_PROTOTYPES
-#include "shivavgwindowsurface.h"
-#include <QtOpenVG/private/qpaintengine_vg_p.h>
-#if defined(Q_WS_X11)
-#include "private/qt_x11_p.h"
-#include "qx11info_x11.h"
-#include <GL/glx.h>
-
-extern QX11Info *qt_x11Info(const QPaintDevice *pd);
-#endif
-
-// Define this to use framebuffer objects.
-//#define QVG_USE_FBO 1
-
-#include <vg/openvg.h>
-
-QT_BEGIN_NAMESPACE
-
-class QShivaContext
-{
-public:
- QShivaContext();
- ~QShivaContext();
-
- bool makeCurrent(ShivaVGWindowSurfacePrivate *surface);
- void doneCurrent();
-
- bool initialized;
- QSize currentSize;
- ShivaVGWindowSurfacePrivate *currentSurface;
-};
-
-Q_GLOBAL_STATIC(QShivaContext, shivaContext);
-
-class ShivaVGWindowSurfacePrivate
-{
-public:
- ShivaVGWindowSurfacePrivate()
- : isCurrent(false)
- , needsResize(true)
- , engine(0)
-#if defined(QVG_USE_FBO)
- , fbo(0)
- , texture(0)
-#endif
-#if defined(Q_WS_X11)
- , drawable(0)
- , context(0)
-#endif
- {
- }
- ~ShivaVGWindowSurfacePrivate();
-
- void ensureContext(QWidget *widget);
-
- QSize size;
- bool isCurrent;
- bool needsResize;
- QVGPaintEngine *engine;
-#if defined(QVG_USE_FBO)
- GLuint fbo;
- GLuint texture;
-#endif
-#if defined(Q_WS_X11)
- GLXDrawable drawable;
- GLXContext context;
-#endif
-};
-
-QShivaContext::QShivaContext()
- : initialized(false)
- , currentSurface(0)
-{
-}
-
-QShivaContext::~QShivaContext()
-{
- if (initialized)
- vgDestroyContextSH();
-}
-
-bool QShivaContext::makeCurrent(ShivaVGWindowSurfacePrivate *surface)
-{
- if (currentSurface)
- currentSurface->isCurrent = false;
- surface->isCurrent = true;
- currentSurface = surface;
- currentSize = surface->size;
-#if defined(Q_WS_X11)
- glXMakeCurrent(X11->display, surface->drawable, surface->context);
-#endif
- if (!initialized) {
- if (!vgCreateContextSH(currentSize.width(), currentSize.height())) {
- qWarning("vgCreateContextSH(%d, %d): could not create context", currentSize.width(), currentSize.height());
- return false;
- }
- initialized = true;
- } else {
- vgResizeSurfaceSH(currentSize.width(), currentSize.height());
- }
-#if defined(QVG_USE_FBO)
- if (surface->fbo)
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, surface->fbo);
- else
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
-#endif
- return true;
-}
-
-void QShivaContext::doneCurrent()
-{
- if (currentSurface) {
- currentSurface->isCurrent = false;
- currentSurface = 0;
- }
-#if defined(Q_WS_X11)
- glXMakeCurrent(X11->display, 0, 0);
-#endif
-}
-
-ShivaVGWindowSurfacePrivate::~ShivaVGWindowSurfacePrivate()
-{
-#if defined(QVG_USE_FBO)
- if (fbo) {
- glDeleteTextures(1, &texture);
- glDeleteFramebuffersEXT(1, &fbo);
- }
-#endif
-}
-
-void ShivaVGWindowSurfacePrivate::ensureContext(QWidget *widget)
-{
-#if defined(Q_WS_X11)
- Window win = widget->winId();
- if (win != drawable) {
- if (context)
- glXDestroyContext(X11->display, context);
- drawable = win;
- }
- if (context == 0) {
- const QX11Info *xinfo = qt_x11Info(widget);
- int spec[64];
- int i = 0;
- spec[i++] = GLX_DOUBLEBUFFER;
- spec[i++] = GLX_DEPTH_SIZE;
- spec[i++] = 1;
- spec[i++] = GLX_STENCIL_SIZE;
- spec[i++] = 1;
- spec[i++] = GLX_RGBA;
- spec[i++] = GLX_RED_SIZE;
- spec[i++] = 1;
- spec[i++] = GLX_GREEN_SIZE;
- spec[i++] = 1;
- spec[i++] = GLX_BLUE_SIZE;
- spec[i++] = 1;
- spec[i++] = GLX_SAMPLE_BUFFERS_ARB;
- spec[i++] = 1;
- spec[i++] = GLX_SAMPLES_ARB;
- spec[i++] = 4;
- spec[i] = XNone;
- XVisualInfo *visual = glXChooseVisual
- (xinfo->display(), xinfo->screen(), spec);
- context = glXCreateContext(X11->display, visual, 0, True);
- if (!context)
- qWarning("glXCreateContext: could not create GL context for VG rendering");
- }
-#else
- Q_UNUSED(widget);
-#endif
-#if defined(QVG_USE_FBO)
- if (needsResize && fbo) {
-#if defined(Q_WS_X11)
- glXMakeCurrent(X11->display, drawable, context);
-#endif
- glDeleteTextures(1, &texture);
- glDeleteFramebuffersEXT(1, &fbo);
-#if defined(Q_WS_X11)
- glXMakeCurrent(X11->display, 0, 0);
-#endif
- fbo = 0;
- texture = 0;
- }
- if (!fbo) {
-#if defined(Q_WS_X11)
- glXMakeCurrent(X11->display, drawable, context);
-#endif
- glGenFramebuffersEXT(1, &fbo);
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
-
- glGenTextures(1, &texture);
- glBindTexture(GL_TEXTURE_2D, texture);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, size.width(), size.height(), 0,
- GL_RGBA, GL_UNSIGNED_BYTE, NULL);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glFramebufferTexture2DEXT
- (GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D,
- texture, 0);
-
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
-#if defined(Q_WS_X11)
- glXMakeCurrent(X11->display, 0, 0);
-#endif
- }
-#endif
- needsResize = false;
-}
-
-ShivaVGWindowSurface::ShivaVGWindowSurface(QWidget *window)
- : QWindowSurface(window), d_ptr(new ShivaVGWindowSurfacePrivate)
-{
-}
-
-ShivaVGWindowSurface::~ShivaVGWindowSurface()
-{
- if (d_ptr->isCurrent) {
- shivaContext()->doneCurrent();
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
- }
-#if defined(Q_WS_X11)
- if (d_ptr->context)
- glXDestroyContext(X11->display, d_ptr->context);
-#endif
- delete d_ptr;
-}
-
-QPaintDevice *ShivaVGWindowSurface::paintDevice()
-{
- d_ptr->ensureContext(window());
- shivaContext()->makeCurrent(d_ptr);
- glClearDepth(0.0f);
- glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
- return this;
-}
-
-void ShivaVGWindowSurface::flush(QWidget *widget, const QRegion &region, const QPoint &offset)
-{
- Q_UNUSED(region);
- Q_UNUSED(offset);
- QWidget *parent = widget->internalWinId() ? widget : widget->nativeParentWidget();
- d_ptr->ensureContext(parent);
- QShivaContext *context = shivaContext();
- if (!d_ptr->isCurrent)
- context->makeCurrent(d_ptr);
-#if defined(QVG_USE_FBO)
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
- if (d_ptr->fbo) {
- static GLfloat const vertices[][2] = {
- {-1, -1}, {1, -1}, {1, 1}, {-1, 1}
- };
- static GLfloat const texCoords[][2] = {
- {0, 0}, {1, 0}, {1, 1}, {0, 1}
- };
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- glVertexPointer(2, GL_FLOAT, 0, vertices);
- glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
- glBindTexture(GL_TEXTURE_2D, d_ptr->texture);
- glEnable(GL_TEXTURE_2D);
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisable(GL_TEXTURE_2D);
- glBindTexture(GL_TEXTURE_2D, 0);
- }
-#endif
-#if defined(Q_WS_X11)
- glXSwapBuffers(X11->display, d_ptr->drawable);
-#endif
- context->doneCurrent();
-}
-
-void ShivaVGWindowSurface::setGeometry(const QRect &rect)
-{
- QWindowSurface::setGeometry(rect);
- d_ptr->needsResize = true;
- d_ptr->size = rect.size();
-}
-
-bool ShivaVGWindowSurface::scroll(const QRegion &area, int dx, int dy)
-{
- return QWindowSurface::scroll(area, dx, dy);
-}
-
-void ShivaVGWindowSurface::beginPaint(const QRegion &region)
-{
- // Nothing to do here.
- Q_UNUSED(region);
-}
-
-void ShivaVGWindowSurface::endPaint(const QRegion &region)
-{
- // Nothing to do here.
- Q_UNUSED(region);
-}
-
-Q_GLOBAL_STATIC(QVGPaintEngine, sharedPaintEngine);
-
-QPaintEngine *ShivaVGWindowSurface::paintEngine() const
-{
- if (!d_ptr->engine)
- d_ptr->engine = sharedPaintEngine();
- return d_ptr->engine;
-}
-
-int ShivaVGWindowSurface::metric(PaintDeviceMetric met) const
-{
- return qt_paint_device_metric(window(), met);
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/graphicssystems/shivavg/shivavgwindowsurface.h b/src/plugins/graphicssystems/shivavg/shivavgwindowsurface.h
deleted file mode 100644
index a9de7f5239..0000000000
--- a/src/plugins/graphicssystems/shivavg/shivavgwindowsurface.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef SHIVAVGWINDOWSURFACE_H
-#define SHIVAVGWINDOWSURFACE_H
-
-#include <QtGui/private/qwindowsurface_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class ShivaVGWindowSurfacePrivate;
-
-class ShivaVGWindowSurface : public QWindowSurface, public QPaintDevice
-{
-public:
- ShivaVGWindowSurface(QWidget *window);
- virtual ~ShivaVGWindowSurface();
-
- QPaintDevice *paintDevice();
- void flush(QWidget *widget, const QRegion &region, const QPoint &offset);
- void setGeometry(const QRect &rect);
- bool scroll(const QRegion &area, int dx, int dy);
-
- void beginPaint(const QRegion &region);
- void endPaint(const QRegion &region);
-
- QPaintEngine *paintEngine() const;
-
-protected:
- int metric(PaintDeviceMetric metric) const;
-
-private:
- ShivaVGWindowSurfacePrivate *d_ptr;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/plugins/graphicssystems/trace/main.cpp b/src/plugins/graphicssystems/trace/main.cpp
deleted file mode 100644
index c0043a2cdd..0000000000
--- a/src/plugins/graphicssystems/trace/main.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <private/qgraphicssystemplugin_p.h>
-#include "qgraphicssystem_trace_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class QTraceGraphicsSystemPlugin : public QGraphicsSystemPlugin
-{
-public:
- QStringList keys() const;
- QGraphicsSystem *create(const QString&);
-};
-
-QStringList QTraceGraphicsSystemPlugin::keys() const
-{
- return QStringList(QLatin1String("Trace"));
-}
-
-QGraphicsSystem* QTraceGraphicsSystemPlugin::create(const QString& system)
-{
- if (system.toLower() == QLatin1String("trace"))
- return new QTraceGraphicsSystem;
-
- return 0;
-}
-
-Q_EXPORT_PLUGIN2(trace, QTraceGraphicsSystemPlugin)
-
-QT_END_NAMESPACE
diff --git a/src/plugins/graphicssystems/trace/qgraphicssystem_trace.cpp b/src/plugins/graphicssystems/trace/qgraphicssystem_trace.cpp
deleted file mode 100644
index 502a198099..0000000000
--- a/src/plugins/graphicssystems/trace/qgraphicssystem_trace.cpp
+++ /dev/null
@@ -1,153 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qgraphicssystem_trace_p.h"
-#include <private/qpixmap_raster_p.h>
-#include <private/qpaintbuffer_p.h>
-#include <private/qwindowsurface_raster_p.h>
-
-#include <QFile>
-#include <QPainter>
-#include <QtDebug>
-
-QT_BEGIN_NAMESPACE
-
-class QTraceWindowSurface : public QRasterWindowSurface
-{
-public:
- QTraceWindowSurface(QWidget *widget);
- ~QTraceWindowSurface();
-
- QPaintDevice *paintDevice();
- void beginPaint(const QRegion &rgn);
- void endPaint(const QRegion &rgn);
-
- bool scroll(const QRegion &area, int dx, int dy);
-
-private:
- QPaintBuffer *buffer;
- QList<QRegion> updates;
-
- qulonglong winId;
-};
-
-QTraceWindowSurface::QTraceWindowSurface(QWidget *widget)
- : QRasterWindowSurface(widget)
- , buffer(0)
- , winId(0)
-{
-}
-
-QTraceWindowSurface::~QTraceWindowSurface()
-{
- if (buffer) {
- QFile outputFile(QString(QLatin1String("qtgraphics-%0.trace")).arg(winId));
- if (outputFile.open(QIODevice::WriteOnly)) {
- QDataStream out(&outputFile);
- out.setFloatingPointPrecision(QDataStream::SinglePrecision);
-
- out.writeBytes("qttraceV2", 9);
-
- uint version = 1;
-
- out << version << *buffer << updates;
- }
- delete buffer;
- }
-}
-
-QPaintDevice *QTraceWindowSurface::paintDevice()
-{
- if (!buffer) {
- buffer = new QPaintBuffer;
-#ifdef Q_WS_QPA
- buffer->setBoundingRect(QRect(QPoint(), size()));
-#else
- buffer->setBoundingRect(geometry());
-#endif
- }
- return buffer;
-}
-
-void QTraceWindowSurface::beginPaint(const QRegion &rgn)
-{
- // ensure paint buffer is created
- paintDevice();
- buffer->beginNewFrame();
-
- QRasterWindowSurface::beginPaint(rgn);
-}
-
-void QTraceWindowSurface::endPaint(const QRegion &rgn)
-{
- QPainter p(QRasterWindowSurface::paintDevice());
- buffer->draw(&p, buffer->numFrames()-1);
- p.end();
-
- winId = (qulonglong)window()->winId();
-
- updates << rgn;
-
- QRasterWindowSurface::endPaint(rgn);
-}
-
-bool QTraceWindowSurface::scroll(const QRegion &, int, int)
-{
- // TODO: scrolling should also be streamed and replayed
- // to test scrolling performance
- return false;
-}
-
-QTraceGraphicsSystem::QTraceGraphicsSystem()
-{
-}
-
-QPixmapData *QTraceGraphicsSystem::createPixmapData(QPixmapData::PixelType type) const
-{
- return new QRasterPixmapData(type);
-}
-
-QWindowSurface *QTraceGraphicsSystem::createWindowSurface(QWidget *widget) const
-{
- return new QTraceWindowSurface(widget);
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/graphicssystems/trace/qgraphicssystem_trace_p.h b/src/plugins/graphicssystems/trace/qgraphicssystem_trace_p.h
deleted file mode 100644
index b6cfc60293..0000000000
--- a/src/plugins/graphicssystems/trace/qgraphicssystem_trace_p.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGRAPHICSSYSTEM_TRACE_P_H
-#define QGRAPHICSSYSTEM_TRACE_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtGui/private/qgraphicssystem_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QTraceGraphicsSystem : public QGraphicsSystem
-{
-public:
- QTraceGraphicsSystem();
-
- QPixmapData *createPixmapData(QPixmapData::PixelType type) const;
- QWindowSurface *createWindowSurface(QWidget *widget) const;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/plugins/graphicssystems/trace/trace.pro b/src/plugins/graphicssystems/trace/trace.pro
deleted file mode 100644
index f44bb3211e..0000000000
--- a/src/plugins/graphicssystems/trace/trace.pro
+++ /dev/null
@@ -1,13 +0,0 @@
-TARGET = qtracegraphicssystem
-load(qt_plugin)
-
-QT += core-private gui-private network
-
-DESTDIR = $$QT.gui.plugins/graphicssystems
-symbian:TARGET.UID3 = 0x2002130E
-
-SOURCES = main.cpp qgraphicssystem_trace.cpp
-
-target.path += $$[QT_INSTALL_PLUGINS]/graphicssystems
-INSTALLS += target
-INCLUDEPATH += ../../../3rdparty/harfbuzz/src
diff --git a/src/plugins/imageformats/ico/qicohandler.cpp b/src/plugins/imageformats/ico/qicohandler.cpp
index 5e1f16bad4..da6b8a75bc 100644
--- a/src/plugins/imageformats/ico/qicohandler.cpp
+++ b/src/plugins/imageformats/ico/qicohandler.cpp
@@ -589,7 +589,6 @@ QImage ICOReader::iconAt(int index)
mask.setColor(1, qRgba(0 ,0 ,0 ,0xff));
read1BitBMP(mask);
if (!mask.isNull()) {
- img = QImage(image.width(), image.height(), QImage::Format_ARGB32 );
img = image;
img.setAlphaChannel(mask);
// (Luckily, it seems that setAlphaChannel() does not ruin the alpha values
diff --git a/src/plugins/inputmethods/imsw-multi/imsw-multi.pro b/src/plugins/inputmethods/imsw-multi/imsw-multi.pro
deleted file mode 100644
index 4c7b9b96d8..0000000000
--- a/src/plugins/inputmethods/imsw-multi/imsw-multi.pro
+++ /dev/null
@@ -1,13 +0,0 @@
-TARGET = qimsw-multi
-load(qt_plugin)
-CONFIG += warn_on
-
-DESTDIR = $$QT.gui.plugins/inputmethods
-
-HEADERS += qmultiinputcontext.h \
- qmultiinputcontextplugin.h
-SOURCES += qmultiinputcontext.cpp \
- qmultiinputcontextplugin.cpp
-
-target.path += $$[QT_INSTALL_PLUGINS]/inputmethods
-INSTALLS += target
diff --git a/src/plugins/inputmethods/imsw-multi/qmultiinputcontext.cpp b/src/plugins/inputmethods/imsw-multi/qmultiinputcontext.cpp
deleted file mode 100644
index 258d586564..0000000000
--- a/src/plugins/inputmethods/imsw-multi/qmultiinputcontext.cpp
+++ /dev/null
@@ -1,212 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/****************************************************************************
-**
-** Implementation of QMultiInputContext class
-**
-** Copyright (C) 2004 immodule for Qt Project. All rights reserved.
-**
-** This file is written to contribute to Nokia Corporation and/or its subsidiary(-ies) under their own
-** licence. You may use this file under your Qt license. Following
-** description is copied from their original file headers. Contact
-** immodule-qt@freedesktop.org if any conditions of this licensing are
-** not clear to you.
-**
-****************************************************************************/
-
-#ifndef QT_NO_IM
-#include "qmultiinputcontext.h"
-#include <qinputcontextfactory.h>
-#include <qstringlist.h>
-#include <qaction.h>
-#include <qsettings.h>
-#include <qmenu.h>
-
-#include <stdlib.h>
-
-QT_BEGIN_NAMESPACE
-
-QMultiInputContext::QMultiInputContext()
- : QInputContext(), current(-1)
-{
- keys = QInputContextFactory::keys();
- for (int i = keys.size()-1; i >= 0; --i)
- if (keys.at(i).contains(QLatin1String("imsw")))
- keys.removeAt(i);
-
- QString def = QLatin1String(getenv("QT4_IM_MODULE"));
- if (def.isEmpty())
- def = QLatin1String(getenv("QT_IM_MODULE"));
- if (def.isEmpty()) {
- QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
- settings.beginGroup(QLatin1String("Qt"));
- def = settings.value(QLatin1String("DefaultInputMethod"), QLatin1String("xim")).toString();
- }
- current = keys.indexOf(def);
- if (current < 0)
- current = 0;
-
- menu = new QMenu(tr("Select IM"));
- separator = new QAction(this);
- separator->setSeparator(true);
-
- QActionGroup *group = new QActionGroup(this);
- for (int i = 0; i < keys.size(); ++i) {
- slaves.append(0);
- const QString key = keys.at(i);
- QAction *a = menu->addAction(QInputContextFactory::displayName(key));
- a->setData(key);
- a->setCheckable(true);
- group->addAction(a);
- if (i == current) {
- slaves.replace(current, QInputContextFactory::create(key, this));
- a->setChecked(true);
- }
- }
- connect(group, SIGNAL(triggered(QAction*)), this, SLOT(changeSlave(QAction*)));
-}
-
-QMultiInputContext::~QMultiInputContext()
-{
- delete menu;
-}
-
-
-QString QMultiInputContext::identifierName()
-{
- return (slave()) ? slave()->identifierName() : QLatin1String("");
-}
-
-QString QMultiInputContext::language()
-{
- return (slave()) ? slave()->language() : QLatin1String("");
-}
-
-
-#if defined(Q_WS_X11)
-bool QMultiInputContext::x11FilterEvent(QWidget *keywidget, XEvent *event)
-{
- return (slave()) ? slave()->x11FilterEvent(keywidget, event) : false;
-}
-#endif // Q_WS_X11
-
-
-bool QMultiInputContext::filterEvent(const QEvent *event)
-{
- return (slave()) ? slave()->filterEvent(event) : false;
-}
-
-void QMultiInputContext::reset()
-{
- if (slave())
- slave()->reset();
-}
-
-void QMultiInputContext::update()
-{
- if (slave())
- slave()->update();
-}
-
-void QMultiInputContext::mouseHandler(int x, QMouseEvent *event)
-{
- if (slave())
- slave()->mouseHandler(x, event);
-}
-
-QFont QMultiInputContext::font() const
-{
- return (slave()) ? slave()->font() : QInputContext::font();
-}
-
-void QMultiInputContext::setFocusWidget(QWidget *w)
-{
- QInputContext::setFocusWidget(w);
- if (slave())
- slave()->setFocusWidget(w);
-}
-
-QWidget *QMultiInputContext::focusWidget() const
-{
- return QInputContext::focusWidget();
-}
-
-void QMultiInputContext::widgetDestroyed(QWidget *w)
-{
- if (slave())
- slave()->widgetDestroyed(w);
-}
-
-bool QMultiInputContext::isComposing() const
-{
- return (slave()) ? slave()->isComposing() : false;
-}
-
-QList<QAction *> QMultiInputContext::actions()
-{
- QList<QAction *> a = slave()->actions();
- a.append(separator);
- a.append(menu->menuAction());
- return a;
-}
-
-void QMultiInputContext::changeSlave(QAction *a)
-{
- for (int i = 0; i < slaves.size(); ++i) {
- if (keys.at(i) == a->data().toString()) {
- if (slaves.at(i) == 0)
- slaves.replace(i, QInputContextFactory::create(keys.at(i), this));
- QInputContext *qic = slaves.at(current);
- QWidget *oldWidget = qic->focusWidget();
- qic->reset();
- qic->setFocusWidget(0);
- current = i;
- qic = slaves.at(current);
- qic->setFocusWidget(oldWidget);
- return;
- }
- }
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_IM
diff --git a/src/plugins/inputmethods/imsw-multi/qmultiinputcontext.h b/src/plugins/inputmethods/imsw-multi/qmultiinputcontext.h
deleted file mode 100644
index 5d311b3f4b..0000000000
--- a/src/plugins/inputmethods/imsw-multi/qmultiinputcontext.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/****************************************************************************
-**
-** Definition of QMultiInputContext class
-**
-** Copyright (C) 2004 immodule for Qt Project. All rights reserved.
-**
-** This file is written to contribute to Nokia Corporation and/or its subsidiary(-ies) under their own
-** licence. You may use this file under your Qt license. Following
-** description is copied from their original file headers. Contact
-** immodule-qt@freedesktop.org if any conditions of this licensing are
-** not clear to you.
-**
-****************************************************************************/
-
-#ifndef QMULTIINPUTCONTEXT_H
-#define QMULTIINPUTCONTEXT_H
-
-#ifndef QT_NO_IM
-
-#include <QtGui/qwidget.h>
-#include <QtGui/qinputcontext.h>
-#include <QtCore/qstring.h>
-#include <QtCore/qnamespace.h>
-#include <QtCore/qmap.h>
-#include <QtCore/qpointer.h>
-#include <QtCore/qlist.h>
-
-QT_BEGIN_NAMESPACE
-
-class QMultiInputContext : public QInputContext
-{
- Q_OBJECT
-public:
- QMultiInputContext();
- ~QMultiInputContext();
-
- QString identifierName();
- QString language();
-
-#if defined(Q_WS_X11)
- bool x11FilterEvent( QWidget *keywidget, XEvent *event );
-#endif // Q_WS_X11
- bool filterEvent( const QEvent *event );
-
- void reset();
- void update();
- void mouseHandler( int x, QMouseEvent *event );
- QFont font() const;
- bool isComposing() const;
-
- QList<QAction *> actions();
-
- QWidget *focusWidget() const;
- void setFocusWidget(QWidget *w);
-
- void widgetDestroyed( QWidget *w );
-
- QInputContext *slave() { return slaves.at(current); }
- const QInputContext *slave() const { return slaves.at(current); }
-
-protected Q_SLOTS:
- void changeSlave(QAction *);
-private:
- void *unused;
- int current;
- QList<QInputContext *> slaves;
- QMenu *menu;
- QAction *separator;
- QStringList keys;
-};
-
-#endif // Q_NO_IM
-
-QT_END_NAMESPACE
-
-#endif // QMULTIINPUTCONTEXT_H
diff --git a/src/plugins/inputmethods/imsw-multi/qmultiinputcontextplugin.cpp b/src/plugins/inputmethods/imsw-multi/qmultiinputcontextplugin.cpp
deleted file mode 100644
index 1f56e2350b..0000000000
--- a/src/plugins/inputmethods/imsw-multi/qmultiinputcontextplugin.cpp
+++ /dev/null
@@ -1,111 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/****************************************************************************
-**
-** Implementation of QMultiInputContextPlugin class
-**
-** Copyright (C) 2004 immodule for Qt Project. All rights reserved.
-**
-** This file is written to contribute to Nokia Corporation and/or its subsidiary(-ies) under their own
-** license. You may use this file under your Qt license. Following
-** description is copied from their original file headers. Contact
-** immodule-qt@freedesktop.org if any conditions of this licensing are
-** not clear to you.
-**
-****************************************************************************/
-
-#ifndef QT_NO_IM
-#include "qmultiinputcontext.h"
-#include "qmultiinputcontextplugin.h"
-#include <qinputcontextplugin.h>
-#include <qstringlist.h>
-
-QT_BEGIN_NAMESPACE
-
-QMultiInputContextPlugin::QMultiInputContextPlugin()
-{
-}
-
-QMultiInputContextPlugin::~QMultiInputContextPlugin()
-{
-}
-
-QStringList QMultiInputContextPlugin::keys() const
-{
- // input method switcher should named with "imsw-" prefix to
- // prevent to be listed in ordinary input method list.
- return QStringList( QLatin1String("imsw-multi") );
-}
-
-QInputContext *QMultiInputContextPlugin::create( const QString &key )
-{
- if (key != QLatin1String("imsw-multi"))
- return 0;
- return new QMultiInputContext;
-}
-
-QStringList QMultiInputContextPlugin::languages( const QString & )
-{
- return QStringList();
-}
-
-QString QMultiInputContextPlugin::displayName( const QString &key )
-{
- if (key != QLatin1String("imsw-multi"))
- return QString();
- return tr( "Multiple input method switcher" );
-}
-
-QString QMultiInputContextPlugin::description( const QString &key )
-{
- if (key != QLatin1String("imsw-multi"))
- return QString();
- return tr( "Multiple input method switcher that uses the context menu of the text widgets" );
-}
-
-
-Q_EXPORT_STATIC_PLUGIN(QMultiInputContextPlugin)
-Q_EXPORT_PLUGIN2(qimsw_multi, QMultiInputContextPlugin)
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/plugins/inputmethods/imsw-multi/qmultiinputcontextplugin.h b/src/plugins/inputmethods/imsw-multi/qmultiinputcontextplugin.h
deleted file mode 100644
index c18112ff8b..0000000000
--- a/src/plugins/inputmethods/imsw-multi/qmultiinputcontextplugin.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/****************************************************************************
-**
-** Definition of QMultiInputContextPlugin class
-**
-** Copyright (C) 2004 immodule for Qt Project. All rights reserved.
-**
-** This file is written to contribute to Nokia Corporation and/or its subsidiary(-ies) under their own
-** license. You may use this file under your Qt license. Following
-** description is copied from their original file headers. Contact
-** immodule-qt@freedesktop.org if any conditions of this licensing are
-** not clear to you.
-**
-****************************************************************************/
-
-#ifndef QMULTIINPUTCONTEXTPLUGIN_H
-#define QMULTIINPUTCONTEXTPLUGIN_H
-
-#ifndef QT_NO_IM
-
-#include "qmultiinputcontext.h"
-#include <QtGui/qinputcontextplugin.h>
-#include <QtCore/qstringlist.h>
-
-QT_BEGIN_NAMESPACE
-
-class QMultiInputContextPlugin : public QInputContextPlugin
-{
- Q_OBJECT
-public:
- QMultiInputContextPlugin();
- ~QMultiInputContextPlugin();
-
- QStringList keys() const;
- QInputContext *create( const QString &key );
- QStringList languages( const QString &key );
- QString displayName( const QString &key );
- QString description( const QString &key );
-};
-
-#endif // QT_NO_IM
-
-QT_END_NAMESPACE
-
-#endif // QMULTIINPUTCONTEXTPLUGIN_H
diff --git a/src/plugins/inputmethods/inputmethods.pro b/src/plugins/inputmethods/inputmethods.pro
deleted file mode 100644
index e1ca847519..0000000000
--- a/src/plugins/inputmethods/inputmethods.pro
+++ /dev/null
@@ -1,3 +0,0 @@
-TEMPLATE = subdirs
-
-SUBDIRS = imsw-multi
diff --git a/src/plugins/kbddrivers/kbddrivers.pro b/src/plugins/kbddrivers/kbddrivers.pro
deleted file mode 100644
index dbab47b366..0000000000
--- a/src/plugins/kbddrivers/kbddrivers.pro
+++ /dev/null
@@ -1,2 +0,0 @@
-TEMPLATE = subdirs
-contains(kbd-plugins, linuxinput): SUBDIRS += linuxinput
diff --git a/src/plugins/kbddrivers/linuxinput/linuxinput.pro b/src/plugins/kbddrivers/linuxinput/linuxinput.pro
deleted file mode 100644
index 8eaa786ce0..0000000000
--- a/src/plugins/kbddrivers/linuxinput/linuxinput.pro
+++ /dev/null
@@ -1,14 +0,0 @@
-TARGET = qlinuxinputkbddriver
-load(qt_plugin)
-
-DESTDIR = $$QT.gui.plugins/kbddrivers
-target.path = $$[QT_INSTALL_PLUGINS]/kbddrivers
-INSTALLS += target
-
-DEFINES += QT_QWS_KBD_LINUXINPUT
-
-HEADERS = $$QT_SOURCE_TREE/src/gui/embedded/qkbdlinuxinput_qws.h
-
-SOURCES = main.cpp \
- $$QT_SOURCE_TREE/src/gui/embedded/qkbdlinuxinput_qws.cpp
-
diff --git a/src/plugins/kbddrivers/linuxinput/main.cpp b/src/plugins/kbddrivers/linuxinput/main.cpp
deleted file mode 100644
index 9affaa67ea..0000000000
--- a/src/plugins/kbddrivers/linuxinput/main.cpp
+++ /dev/null
@@ -1,77 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qkbddriverplugin_qws.h>
-#include <qkbdlinuxinput_qws.h>
-
-QT_BEGIN_NAMESPACE
-
-class QLinuxInputKbdDriver : public QKbdDriverPlugin
-{
-public:
- QLinuxInputKbdDriver();
-
- QStringList keys() const;
- QWSKeyboardHandler* create(const QString &driver, const QString &device);
-};
-
-QLinuxInputKbdDriver::QLinuxInputKbdDriver()
- : QKbdDriverPlugin()
-{
-}
-
-QStringList QLinuxInputKbdDriver::keys() const
-{
- return (QStringList() << QLatin1String("LinuxInput"));
-}
-
-QWSKeyboardHandler* QLinuxInputKbdDriver::create(const QString &driver,
- const QString &device)
-{
- Q_UNUSED(device);
- if (driver.compare(QLatin1String("LinuxInput"), Qt::CaseInsensitive))
- return 0;
- return new QWSLinuxInputKeyboardHandler(device);
-}
-
-Q_EXPORT_PLUGIN2(qwslinuxinputkbddriver, QLinuxInputKbdDriver)
-
-QT_END_NAMESPACE
diff --git a/src/plugins/mousedrivers/linuxtp/linuxtp.pro b/src/plugins/mousedrivers/linuxtp/linuxtp.pro
deleted file mode 100644
index e5d274a0b7..0000000000
--- a/src/plugins/mousedrivers/linuxtp/linuxtp.pro
+++ /dev/null
@@ -1,14 +0,0 @@
-TARGET = qlinuxtpmousedriver
-load(qt_plugin)
-
-DESTDIR = $$QT.gui.plugins/mousedrivers
-target.path = $$[QT_INSTALL_PLUGINS]/mousedrivers
-INSTALLS += target
-
-DEFINES += QT_QWS_MOUSE_LINUXTP
-
-HEADERS = $$QT_SOURCE_TREE/src/gui/embedded/qmouselinuxtp_qws.h
-
-SOURCES = main.cpp \
- $$QT_SOURCE_TREE/src/gui/embedded/qmouselinuxtp_qws.cpp
-
diff --git a/src/plugins/mousedrivers/linuxtp/main.cpp b/src/plugins/mousedrivers/linuxtp/main.cpp
deleted file mode 100644
index 64a69ef7f1..0000000000
--- a/src/plugins/mousedrivers/linuxtp/main.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qmousedriverplugin_qws.h>
-#include <qmouselinuxtp_qws.h>
-
-QT_BEGIN_NAMESPACE
-
-class QLinuxTPMouseDriver : public QMouseDriverPlugin
-{
-public:
- QLinuxTPMouseDriver();
-
- QStringList keys() const;
- QWSMouseHandler* create(const QString &driver, const QString &device);
-};
-
-QLinuxTPMouseDriver::QLinuxTPMouseDriver()
- : QMouseDriverPlugin()
-{
-}
-
-QStringList QLinuxTPMouseDriver::keys() const
-{
- return (QStringList() << "LinuxTP");
-}
-
-QWSMouseHandler* QLinuxTPMouseDriver::create(const QString &driver,
- const QString &device)
-{
- if (driver.compare(QLatin1String("LinuxTP"), Qt::CaseInsensitive))
- return 0;
- return new QWSLinuxTPMouseHandler(driver, device);
-}
-
-Q_EXPORT_PLUGIN2(qwslinuxtpmousehandler, QLinuxTPMouseDriver)
-
-QT_END_NAMESPACE
diff --git a/src/plugins/mousedrivers/mousedrivers.pro b/src/plugins/mousedrivers/mousedrivers.pro
deleted file mode 100644
index f89682b880..0000000000
--- a/src/plugins/mousedrivers/mousedrivers.pro
+++ /dev/null
@@ -1,5 +0,0 @@
-TEMPLATE = subdirs
-contains(mouse-plugins, linuxtp): SUBDIRS += linuxtp
-contains(mouse-plugins, pc): SUBDIRS += pc
-contains(mouse-plugins, tslib): SUBDIRS += tslib
-contains(mouse-plugins, linuxinput): SUBDIRS += linuxinput
diff --git a/src/plugins/mousedrivers/pc/main.cpp b/src/plugins/mousedrivers/pc/main.cpp
deleted file mode 100644
index fbd23dab0f..0000000000
--- a/src/plugins/mousedrivers/pc/main.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qmousedriverplugin_qws.h>
-#include <qmousepc_qws.h>
-
-QT_BEGIN_NAMESPACE
-
-class QPcMouseDriver : public QMouseDriverPlugin
-{
-public:
- QPcMouseDriver();
-
- QStringList keys() const;
- QWSMouseHandler* create(const QString &driver, const QString &device);
-};
-
-QPcMouseDriver::QPcMouseDriver()
- : QMouseDriverPlugin()
-{
-}
-
-QStringList QPcMouseDriver::keys() const
-{
- return (QStringList()
- << QLatin1String("Auto")
- << QLatin1String("IntelliMouse")
- << QLatin1String("Microsoft")
- << QLatin1String("MouseSystems")
- << QLatin1String("MouseMan"));
-}
-
-QWSMouseHandler* QPcMouseDriver::create(const QString &driver,
- const QString &device)
-{
- if (!keys().contains(driver, Qt::CaseInsensitive))
- return 0;
- return new QWSPcMouseHandler(driver, device);
-}
-
-Q_EXPORT_PLUGIN2(qwspcmousehandler, QPcMouseDriver)
-
-QT_END_NAMESPACE
diff --git a/src/plugins/mousedrivers/pc/pc.pro b/src/plugins/mousedrivers/pc/pc.pro
deleted file mode 100644
index 04d7b0f06f..0000000000
--- a/src/plugins/mousedrivers/pc/pc.pro
+++ /dev/null
@@ -1,14 +0,0 @@
-TARGET = qpcmousedriver
-load(qt_plugin)
-
-DESTDIR = $$QT.gui.plugins/mousedrivers
-target.path = $$[QT_INSTALL_PLUGINS]/mousedrivers
-INSTALLS += target
-
-DEFINES += QT_QWS_MOUSE_PC
-
-HEADERS = $$QT_SOURCE_TREE/src/gui/embedded/qmousepc_qws.h
-
-SOURCES = main.cpp \
- $$QT_SOURCE_TREE/src/gui/embedded/qmousepc_qws.cpp
-
diff --git a/src/plugins/mousedrivers/tslib/main.cpp b/src/plugins/mousedrivers/tslib/main.cpp
deleted file mode 100644
index 1d6f8535ba..0000000000
--- a/src/plugins/mousedrivers/tslib/main.cpp
+++ /dev/null
@@ -1,77 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qmousedriverplugin_qws.h>
-#include <qmousetslib_qws.h>
-
-QT_BEGIN_NAMESPACE
-
-class TslibMouseDriver : public QMouseDriverPlugin
-{
-public:
- TslibMouseDriver();
-
- QStringList keys() const;
- QWSMouseHandler* create(const QString &driver, const QString &device);
-};
-
-TslibMouseDriver::TslibMouseDriver()
- : QMouseDriverPlugin()
-{
-}
-
-QStringList TslibMouseDriver::keys() const
-{
- return (QStringList() << "tslib");
-}
-
-QWSMouseHandler* TslibMouseDriver::create(const QString &driver,
- const QString &device)
-{
- if (driver.toLower() != "tslib")
- return 0;
- return new QWSTslibMouseHandler(driver, device);
-}
-
-Q_EXPORT_STATIC_PLUGIN(TslibMouseDriver)
-Q_EXPORT_PLUGIN2(qwstslibmousehandler, TslibMouseDriver)
-
-QT_END_NAMESPACE
diff --git a/src/plugins/mousedrivers/tslib/tslib.pro b/src/plugins/mousedrivers/tslib/tslib.pro
deleted file mode 100644
index 552a2e7173..0000000000
--- a/src/plugins/mousedrivers/tslib/tslib.pro
+++ /dev/null
@@ -1,16 +0,0 @@
-TARGET = qtslibmousedriver
-load(qt_plugin)
-
-DESTDIR = $$QT.gui.plugins/mousedrivers
-
-HEADERS = \
- $$QT_SOURCE_TREE/src/gui/embedded/qmousedriverplugin_qws.h \
- $$QT_SOURCE_TREE/src/gui/embedded/qmousetslib_qws.h
-SOURCES = main.cpp \
- $$QT_SOURCE_TREE/src/gui/embedded/qmousetslib_qws.cpp
-
-LIBS += -lts
-
-target.path += $$[QT_INSTALL_PLUGINS]/mousedrivers
-INSTALLS += target
-
diff --git a/src/plugins/platforminputcontexts/ibus/ibus.pro b/src/plugins/platforminputcontexts/ibus/ibus.pro
new file mode 100644
index 0000000000..193dad0018
--- /dev/null
+++ b/src/plugins/platforminputcontexts/ibus/ibus.pro
@@ -0,0 +1,19 @@
+TARGET = ibusplatforminputcontextplugin
+load(qt_plugin)
+
+QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/platforminputcontexts
+
+QT += dbus platformsupport-private
+SOURCES += $$PWD/qibusplatforminputcontext.cpp \
+ $$PWD/qibusproxy.cpp \
+ $$PWD/qibusinputcontextproxy.cpp \
+ $$PWD/qibustypes.cpp \
+ $$PWD/main.cpp
+
+HEADERS += $$PWD/qibusplatforminputcontext.h \
+ $$PWD/qibusproxy.h \
+ $$PWD/qibusinputcontextproxy.h \
+ $$PWD/qibustypes.h
+
+target.path += $$[QT_INSTALL_PLUGINS]/platforminputcontexts
+INSTALLS += target
diff --git a/src/plugins/platforminputcontexts/ibus/interfaces/org.freedesktop.IBus.InputContext.xml b/src/plugins/platforminputcontexts/ibus/interfaces/org.freedesktop.IBus.InputContext.xml
new file mode 100644
index 0000000000..dbc79c178b
--- /dev/null
+++ b/src/plugins/platforminputcontexts/ibus/interfaces/org.freedesktop.IBus.InputContext.xml
@@ -0,0 +1,80 @@
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
+"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+<node>
+ <interface name="org.freedesktop.IBus.InputContext">
+ <method name="ProcessKeyEvent">
+ <arg name="keyval" direction="in" type="u"/>
+ <arg name="keycode" direction="in" type="u"/>
+ <arg name="state" direction="in" type="u"/>
+ <arg name="handled" direction="out" type="b"/>
+ </method>
+ <method name="SetCursorLocation">
+ <arg name="x" direction="in" type="i"/>
+ <arg name="y" direction="in" type="i"/>
+ <arg name="w" direction="in" type="i"/>
+ <arg name="h" direction="in" type="i"/>
+ </method>
+ <method name="FocusIn"/>
+ <method name="FocusOut"/>
+ <method name="Reset"/>
+ <method name="Enable"/>
+ <method name="Disable"/>
+ <method name="IsEnabled">
+ <arg name="enable" direction="out" type="b"/>
+ </method>
+ <method name="SetCapabilities">
+ <arg name="caps" direction="in" type="u"/>
+ </method>
+ <method name="PropertyActivate">
+ <arg name="name" direction="in" type="s"/>
+ <arg name="state" direction="in" type="i"/>
+ </method>
+ <method name="SetEngine">
+ <arg name="name" direction="in" type="s"/>
+ </method>
+ <method name="GetEngine">
+ <arg name="desc" direction="out" type="v"/>
+ </method>
+ <method name="Destroy"/>
+ <signal name="CommitText">
+ <arg name="text" type="v"/>
+ </signal>
+ <signal name="Enabled"/>
+ <signal name="Disabled"/>
+ <signal name="ForwardKeyEvent">
+ <arg name="keyval" type="u"/>
+ <arg name="keycode" type="u"/>
+ <arg name="state" type="u"/>
+ </signal>
+ <signal name="UpdatePreeditText">
+ <arg name="text" type="v"/>
+ <arg name="cursor_pos" type="u"/>
+ <arg name="visible" type="b"/>
+ </signal>
+ <signal name="ShowPreeditText"/>
+ <signal name="HidePreeditText"/>
+ <signal name="UpdateAuxiliaryText">
+ <arg name="text" type="v"/>
+ <arg name="visible" type="b"/>
+ </signal>
+ <signal name="ShowAuxiliaryText"/>
+ <signal name="HideAuxiliaryText"/>
+ <signal name="UpdateLookupTable">
+ <arg name="table" type="v"/>
+ <arg name="visible" type="b"/>
+ </signal>
+ <signal name="ShowLookupTable"/>
+ <signal name="HideLookupTable"/>
+ <signal name="PageUpLookupTable"/>
+ <signal name="PageDownLookupTable"/>
+ <signal name="CursorUpLookupTable"/>
+ <signal name="CursorDownLookupTable"/>
+ <signal name="RegisterProperties">
+ <arg name="props" type="v"/>
+ </signal>
+ <signal name="UpdateProperty">
+ <arg name="prop" type="v"/>
+ </signal>
+ </interface>
+</node>
+
diff --git a/src/plugins/platforminputcontexts/ibus/interfaces/org.freedesktop.IBus.xml b/src/plugins/platforminputcontexts/ibus/interfaces/org.freedesktop.IBus.xml
new file mode 100644
index 0000000000..6ac4891771
--- /dev/null
+++ b/src/plugins/platforminputcontexts/ibus/interfaces/org.freedesktop.IBus.xml
@@ -0,0 +1,30 @@
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
+"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+<node>
+ <interface name="org.freedesktop.IBus">
+ <method name="GetAddress">
+ <arg name="address" direction="out" type="s"/>
+ </method>
+ <method name="CreateInputContext">
+ <arg name="name" direction="in" type="s"/>
+ <arg name="context" direction="out" type="o"/>
+ </method>
+ <method name="RegisterComponent">
+ <arg name="components" direction="in" type="v"/>
+ </method>
+ <method name="ListEngines">
+ <arg name="engines" direction="out" type="av"/>
+ </method>
+ <method name="ListActiveEngines">
+ <arg name="engines" direction="out" type="av"/>
+ </method>
+ <method name="Exit">
+ <arg name="restart" direction="in" type="b"/>
+ </method>
+ <method name="Ping">
+ <arg name="data" direction="in" type="v"/>
+ <arg name="data" direction="out" type="v"/>
+ </method>
+ </interface>
+</node>
+
diff --git a/src/plugins/platforminputcontexts/ibus/main.cpp b/src/plugins/platforminputcontexts/ibus/main.cpp
new file mode 100644
index 0000000000..eb773c8856
--- /dev/null
+++ b/src/plugins/platforminputcontexts/ibus/main.cpp
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <private/qplatforminputcontextplugin_qpa_p.h>
+#include <QtCore/QStringList>
+#include "qibusplatforminputcontext.h"
+
+QT_BEGIN_NAMESPACE
+
+class QIbusPlatformInputContextPlugin : public QPlatformInputContextPlugin
+{
+public:
+ QStringList keys() const;
+ QIBusPlatformInputContext *create(const QString&, const QStringList&);
+};
+
+QStringList QIbusPlatformInputContextPlugin::keys() const
+{
+ return QStringList(QStringLiteral("ibus"));
+}
+
+QIBusPlatformInputContext *QIbusPlatformInputContextPlugin::create(const QString& system, const QStringList& paramList)
+{
+ Q_UNUSED(paramList);
+
+ if (system.compare(system, QStringLiteral("ibus"), Qt::CaseInsensitive) == 0)
+ return new QIBusPlatformInputContext;
+ return 0;
+}
+
+Q_EXPORT_PLUGIN2(ibusplatforminputcontextplugin, QIbusPlatformInputContextPlugin)
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforminputcontexts/ibus/qibusinputcontextproxy.cpp b/src/plugins/platforminputcontexts/ibus/qibusinputcontextproxy.cpp
new file mode 100644
index 0000000000..7adffbc2e2
--- /dev/null
+++ b/src/plugins/platforminputcontexts/ibus/qibusinputcontextproxy.cpp
@@ -0,0 +1,26 @@
+/*
+ * This file was generated by qdbusxml2cpp version 0.7
+ * Command line was: qdbusxml2cpp -N -p qibusinputcontextproxy -c QIBusInputContextProxy interfaces/org.freedesktop.IBus.InputContext.xml
+ *
+ * qdbusxml2cpp is Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * This is an auto-generated file.
+ * This file may have been hand-edited. Look for HAND-EDIT comments
+ * before re-generating it.
+ */
+
+#include "qibusinputcontextproxy.h"
+
+/*
+ * Implementation of interface class QIBusInputContextProxy
+ */
+
+QIBusInputContextProxy::QIBusInputContextProxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)
+ : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent)
+{
+}
+
+QIBusInputContextProxy::~QIBusInputContextProxy()
+{
+}
+
diff --git a/src/plugins/platforminputcontexts/ibus/qibusinputcontextproxy.h b/src/plugins/platforminputcontexts/ibus/qibusinputcontextproxy.h
new file mode 100644
index 0000000000..9a91c4e484
--- /dev/null
+++ b/src/plugins/platforminputcontexts/ibus/qibusinputcontextproxy.h
@@ -0,0 +1,144 @@
+/*
+ * This file was generated by qdbusxml2cpp version 0.7
+ * Command line was: qdbusxml2cpp -N -p qibusinputcontextproxy -c QIBusInputContextProxy interfaces/org.freedesktop.IBus.InputContext.xml
+ *
+ * qdbusxml2cpp is Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * This is an auto-generated file.
+ * Do not edit! All changes made to it will be lost.
+ */
+
+#ifndef QIBUSINPUTCONTEXTPROXY_H_1308831153
+#define QIBUSINPUTCONTEXTPROXY_H_1308831153
+
+#include <QtCore/QObject>
+#include <QtCore/QByteArray>
+#include <QtCore/QList>
+#include <QtCore/QMap>
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+#include <QtCore/QVariant>
+#include <QtDBus/QtDBus>
+
+/*
+ * Proxy class for interface org.freedesktop.IBus.InputContext
+ */
+class QIBusInputContextProxy: public QDBusAbstractInterface
+{
+ Q_OBJECT
+public:
+ static inline const char *staticInterfaceName()
+ { return "org.freedesktop.IBus.InputContext"; }
+
+public:
+ QIBusInputContextProxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0);
+
+ ~QIBusInputContextProxy();
+
+public Q_SLOTS: // METHODS
+ inline QDBusPendingReply<> Destroy()
+ {
+ QList<QVariant> argumentList;
+ return asyncCallWithArgumentList(QLatin1String("Destroy"), argumentList);
+ }
+
+ inline QDBusPendingReply<> Disable()
+ {
+ QList<QVariant> argumentList;
+ return asyncCallWithArgumentList(QLatin1String("Disable"), argumentList);
+ }
+
+ inline QDBusPendingReply<> Enable()
+ {
+ QList<QVariant> argumentList;
+ return asyncCallWithArgumentList(QLatin1String("Enable"), argumentList);
+ }
+
+ inline QDBusPendingReply<> FocusIn()
+ {
+ QList<QVariant> argumentList;
+ return asyncCallWithArgumentList(QLatin1String("FocusIn"), argumentList);
+ }
+
+ inline QDBusPendingReply<> FocusOut()
+ {
+ QList<QVariant> argumentList;
+ return asyncCallWithArgumentList(QLatin1String("FocusOut"), argumentList);
+ }
+
+ inline QDBusPendingReply<QDBusVariant> GetEngine()
+ {
+ QList<QVariant> argumentList;
+ return asyncCallWithArgumentList(QLatin1String("GetEngine"), argumentList);
+ }
+
+ inline QDBusPendingReply<bool> IsEnabled()
+ {
+ QList<QVariant> argumentList;
+ return asyncCallWithArgumentList(QLatin1String("IsEnabled"), argumentList);
+ }
+
+ inline QDBusPendingReply<bool> ProcessKeyEvent(uint keyval, uint keycode, uint state)
+ {
+ QList<QVariant> argumentList;
+ argumentList << QVariant::fromValue(keyval) << QVariant::fromValue(keycode) << QVariant::fromValue(state);
+ return asyncCallWithArgumentList(QLatin1String("ProcessKeyEvent"), argumentList);
+ }
+
+ inline QDBusPendingReply<> PropertyActivate(const QString &name, int state)
+ {
+ QList<QVariant> argumentList;
+ argumentList << QVariant::fromValue(name) << QVariant::fromValue(state);
+ return asyncCallWithArgumentList(QLatin1String("PropertyActivate"), argumentList);
+ }
+
+ inline QDBusPendingReply<> Reset()
+ {
+ QList<QVariant> argumentList;
+ return asyncCallWithArgumentList(QLatin1String("Reset"), argumentList);
+ }
+
+ inline QDBusPendingReply<> SetCapabilities(uint caps)
+ {
+ QList<QVariant> argumentList;
+ argumentList << QVariant::fromValue(caps);
+ return asyncCallWithArgumentList(QLatin1String("SetCapabilities"), argumentList);
+ }
+
+ inline QDBusPendingReply<> SetCursorLocation(int x, int y, int w, int h)
+ {
+ QList<QVariant> argumentList;
+ argumentList << QVariant::fromValue(x) << QVariant::fromValue(y) << QVariant::fromValue(w) << QVariant::fromValue(h);
+ return asyncCallWithArgumentList(QLatin1String("SetCursorLocation"), argumentList);
+ }
+
+ inline QDBusPendingReply<> SetEngine(const QString &name)
+ {
+ QList<QVariant> argumentList;
+ argumentList << QVariant::fromValue(name);
+ return asyncCallWithArgumentList(QLatin1String("SetEngine"), argumentList);
+ }
+
+Q_SIGNALS: // SIGNALS
+ void CommitText(const QDBusVariant &text);
+ void CursorDownLookupTable();
+ void CursorUpLookupTable();
+ void Disabled();
+ void Enabled();
+ void ForwardKeyEvent(uint keyval, uint keycode, uint state);
+ void HideAuxiliaryText();
+ void HideLookupTable();
+ void HidePreeditText();
+ void PageDownLookupTable();
+ void PageUpLookupTable();
+ void RegisterProperties(const QDBusVariant &props);
+ void ShowAuxiliaryText();
+ void ShowLookupTable();
+ void ShowPreeditText();
+ void UpdateAuxiliaryText(const QDBusVariant &text, bool visible);
+ void UpdateLookupTable(const QDBusVariant &table, bool visible);
+ void UpdatePreeditText(const QDBusVariant &text, uint cursor_pos, bool visible);
+ void UpdateProperty(const QDBusVariant &prop);
+};
+
+#endif
diff --git a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp
new file mode 100644
index 0000000000..af8fd5a1f1
--- /dev/null
+++ b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp
@@ -0,0 +1,329 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "qibusplatforminputcontext.h"
+
+#include <QtDebug>
+#include <QTextCharFormat>
+#include <QGuiApplication>
+#include <qwindow.h>
+#include <qevent.h>
+
+#include "qibusproxy.h"
+#include "qibusinputcontextproxy.h"
+#include "qibustypes.h"
+
+#include <sys/types.h>
+#include <signal.h>
+
+#include <QtDBus>
+
+enum { debug = 0 };
+
+class QIBusPlatformInputContextPrivate
+{
+public:
+ QIBusPlatformInputContextPrivate();
+ ~QIBusPlatformInputContextPrivate()
+ {
+ delete context;
+ delete bus;
+ delete connection;
+ }
+
+ static QDBusConnection *createConnection();
+
+ QDBusConnection *connection;
+ QIBusProxy *bus;
+ QIBusInputContextProxy *context;
+
+ bool valid;
+};
+
+
+QIBusPlatformInputContext::QIBusPlatformInputContext ()
+ : d(new QIBusPlatformInputContextPrivate())
+{
+ if (d->context) {
+ connect(d->context, SIGNAL(CommitText(QDBusVariant)), SLOT(commitText(QDBusVariant)));
+ connect(d->context, SIGNAL(UpdatePreeditText(QDBusVariant,uint,bool)), this, SLOT(updatePreeditText(QDBusVariant,uint,bool)));
+ }
+ QInputPanel *p = qApp->inputPanel();
+ connect(p, SIGNAL(inputItemChanged()), this, SLOT(inputItemChanged()));
+ connect(p, SIGNAL(cursorRectangleChanged()), this, SLOT(cursorRectChanged()));
+}
+
+QIBusPlatformInputContext::~QIBusPlatformInputContext (void)
+{
+ delete d;
+}
+
+bool QIBusPlatformInputContext::isValid() const
+{
+ return d->valid;
+}
+
+void QIBusPlatformInputContext::invokeAction(QInputPanel::Action a, int x)
+{
+ QPlatformInputContext::invokeAction(a, x);
+
+ if (!d->valid)
+ return;
+}
+
+void QIBusPlatformInputContext::reset()
+{
+ QPlatformInputContext::reset();
+
+ if (!d->valid)
+ return;
+
+ d->context->Reset();
+}
+
+void QIBusPlatformInputContext::update(Qt::InputMethodQueries q)
+{
+ QPlatformInputContext::update(q);
+}
+
+void QIBusPlatformInputContext::cursorRectChanged()
+{
+ if (!d->valid)
+ return;
+
+ QRect r = qApp->inputPanel()->cursorRectangle().toRect();
+ if(!r.isValid())
+ return;
+
+ QWindow *inputWindow = qApp->inputPanel()->inputWindow();
+ r.moveTopLeft(inputWindow->mapToGlobal(r.topLeft()));
+ if (debug)
+ qDebug() << "microFocus" << r;
+ d->context->SetCursorLocation(r.x(), r.y(), r.width(), r.height());
+}
+
+void QIBusPlatformInputContext::inputItemChanged()
+{
+ if (!d->valid)
+ return;
+
+ QObject *input = qApp->inputPanel()->inputItem();
+ if (debug)
+ qDebug() << "setFocusObject" << input;
+ if (input)
+ d->context->FocusIn();
+ else
+ d->context->FocusOut();
+}
+
+
+void QIBusPlatformInputContext::commitText(const QDBusVariant &text)
+{
+ QObject *input = qApp->inputPanel()->inputItem();
+ if (!input)
+ return;
+
+ const QDBusArgument arg = text.variant().value<QDBusArgument>();
+
+ QIBusText t;
+ if (debug)
+ qDebug() << arg.currentSignature();
+ t.fromDBusArgument(arg);
+ if (debug)
+ qDebug() << "commit text:" << t.text;
+
+ QInputMethodEvent event;
+ event.setCommitString(t.text);
+ QCoreApplication::sendEvent(input, &event);
+}
+
+void QIBusPlatformInputContext::updatePreeditText(const QDBusVariant &text, uint cursorPos, bool visible)
+{
+ QObject *input = qApp->inputPanel()->inputItem();
+ if (!input)
+ return;
+
+ const QDBusArgument arg = text.variant().value<QDBusArgument>();
+
+ QIBusText t;
+ t.fromDBusArgument(arg);
+ if (debug)
+ qDebug() << "preedit text:" << t.text;
+
+ QList<QInputMethodEvent::Attribute> attributes = t.attributes.imAttributes();
+ attributes += QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, cursorPos, visible ? 1 : 0, QVariant());
+
+ QInputMethodEvent event(t.text, attributes);
+ QCoreApplication::sendEvent(input, &event);
+}
+
+
+/* Kernel keycode -> X keycode table */
+static const unsigned int keycode_table[256] = {
+ 0, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
+ 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
+ 72, 73, 74, 75, 76, 77, 76, 79, 80, 81, 82, 83, 84, 85, 86, 87,
+ 88, 89, 90, 91, 111, 221, 94, 95, 96, 211, 128, 127, 129, 208, 131, 126,
+ 108, 109, 112, 111, 113, 181, 97, 98, 99, 100, 102, 103, 104, 105, 106, 107,
+ 239, 160, 174, 176, 222, 157, 123, 110, 139, 134, 209, 210, 133, 115, 116, 117,
+ 232, 133, 134, 135, 140, 248, 191, 192, 122, 188, 245, 158, 161, 193, 223, 227,
+ 198, 199, 200, 147, 159, 151, 178, 201, 146, 203, 166, 236, 230, 235, 234, 233,
+ 163, 204, 253, 153, 162, 144, 164, 177, 152, 190, 208, 129, 130, 231, 209, 210,
+ 136, 220, 143, 246, 251, 137, 138, 182, 183, 184, 93, 184, 247, 132, 170, 219,
+ 249, 205, 207, 149, 150, 154, 155, 167, 168, 169, 171, 172, 173, 165, 175, 179,
+ 180, 0, 185, 186, 187, 118, 119, 120, 121, 229, 194, 195, 196, 197, 148, 202,
+ 101, 212, 237, 214, 215, 216, 217, 218, 228, 142, 213, 240, 241, 242, 243, 244,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+bool
+QIBusPlatformInputContext::x11FilterEvent(uint keyval, uint keycode, uint state, bool press)
+{
+ if (!d->valid)
+ return false;
+
+ if (!press)
+ return false;
+
+ keycode -= 8; // ###
+ QDBusReply<bool> reply = d->context->ProcessKeyEvent(keyval, keycode, state);
+
+// qDebug() << "x11FilterEvent return" << reply.value();
+
+ return reply.value();
+}
+
+QIBusPlatformInputContextPrivate::QIBusPlatformInputContextPrivate()
+ : connection(createConnection()),
+ bus(0),
+ context(0),
+ valid(false)
+{
+ if (!connection || !connection->isConnected()) {
+ qDebug("QIBusPlatformInputContext: not connected.");
+ return;
+ }
+
+ bus = new QIBusProxy(QLatin1String("org.freedesktop.IBus"),
+ QLatin1String("/org/freedesktop/IBus"),
+ *connection);
+ if (!bus->isValid()) {
+ qWarning("QIBusPlatformInputContext: invalid bus.");
+ return;
+ }
+
+ QDBusReply<QDBusObjectPath> ic = bus->CreateInputContext(QLatin1String("QIBusInputContext"));
+ if (!ic.isValid()) {
+ qWarning("QIBusPlatformInputContext: CreateInputContext failed.");
+ return;
+ }
+
+ context = new QIBusInputContextProxy(QLatin1String("org.freedesktop.IBus"), ic.value().path(), *connection);
+
+ if (!context->isValid()) {
+ qWarning("QIBusPlatformInputContext: invalid input context.");
+ return;
+ }
+
+ enum Capabilities {
+ IBUS_CAP_PREEDIT_TEXT = 1 << 0,
+ IBUS_CAP_AUXILIARY_TEXT = 1 << 1,
+ IBUS_CAP_LOOKUP_TABLE = 1 << 2,
+ IBUS_CAP_FOCUS = 1 << 3,
+ IBUS_CAP_PROPERTY = 1 << 4,
+ IBUS_CAP_SURROUNDING_TEXT = 1 << 5
+ };
+ context->SetCapabilities(IBUS_CAP_PREEDIT_TEXT|IBUS_CAP_FOCUS);
+
+ if (debug)
+ qDebug(">>>> valid!");
+ valid = true;
+}
+
+QDBusConnection *QIBusPlatformInputContextPrivate::createConnection()
+{
+ QByteArray display(getenv("DISPLAY"));
+ QByteArray host = "unix";
+ QByteArray displayNumber = "0";
+
+ int pos = display.indexOf(':');
+ if (pos > 0)
+ host = display.left(pos);
+ ++pos;
+ int pos2 = display.indexOf('.', pos);
+ if (pos2 > 0)
+ displayNumber = display.mid(pos, pos2 - pos);
+ if (debug)
+ qDebug() << "host=" << host << "displayNumber" << displayNumber;
+
+ QFile file(QDir::homePath() + QLatin1String("/.config/ibus/bus/") +
+ QLatin1String(QDBusConnection::localMachineId()) +
+ QLatin1Char('-') + QString::fromLocal8Bit(host) + QLatin1Char('-') + QString::fromLocal8Bit(displayNumber));
+
+ if (!file.exists()) {
+ qWarning("QIBusPlatformInputContext: ibus config file '%s' does not exist.", qPrintable(file.fileName()));
+ return 0;
+ }
+
+ file.open(QFile::ReadOnly);
+
+ QByteArray address;
+ int pid = -1;
+
+ while (!file.atEnd()) {
+ QByteArray line = file.readLine().trimmed();
+ if (line.startsWith('#'))
+ continue;
+
+ if (line.startsWith("IBUS_ADDRESS="))
+ address = line.mid(sizeof("IBUS_ADDRESS=") - 1);
+ if (line.startsWith("IBUS_DAEMON_PID="))
+ pid = line.mid(sizeof("IBUS_DAEMON_PID=") - 1).toInt();
+ }
+
+ if (debug)
+ qDebug() << "IBUS_ADDRESS=" << address << "PID=" << pid;
+ if (address.isEmpty() || pid < 0 || kill(pid, 0) != 0)
+ return 0;
+
+ return new QDBusConnection(QDBusConnection::connectToBus(QString::fromLatin1(address), QLatin1String("QIBusProxy")));
+}
diff --git a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h
new file mode 100644
index 0000000000..84b578db16
--- /dev/null
+++ b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QIBUSPLATFORMINPUTCONTEXT_H
+#define QIBUSPLATFORMINPUTCONTEXT_H
+
+#include <QPlatformInputContext>
+
+class QIBusPlatformInputContextPrivate;
+class QDBusVariant;
+
+class QIBusPlatformInputContext : public QPlatformInputContext
+{
+ Q_OBJECT
+public:
+ QIBusPlatformInputContext();
+ ~QIBusPlatformInputContext();
+
+ bool isValid() const;
+
+ void invokeAction(QInputPanel::Action a, int x);
+ void reset(void);
+ void update(Qt::InputMethodQueries);
+
+ Q_INVOKABLE bool x11FilterEvent(uint keyval, uint keycode, uint state, bool press);
+
+public Q_SLOTS:
+ void commitText(const QDBusVariant &text);
+ void updatePreeditText(const QDBusVariant &text, uint cursor_pos, bool visible);
+ void inputItemChanged();
+ void cursorRectChanged();
+
+private:
+ QIBusPlatformInputContextPrivate *d;
+};
+
+#endif
diff --git a/src/plugins/platforminputcontexts/ibus/qibusproxy.cpp b/src/plugins/platforminputcontexts/ibus/qibusproxy.cpp
new file mode 100644
index 0000000000..9d64b603f3
--- /dev/null
+++ b/src/plugins/platforminputcontexts/ibus/qibusproxy.cpp
@@ -0,0 +1,26 @@
+/*
+ * This file was generated by qdbusxml2cpp version 0.7
+ * Command line was: qdbusxml2cpp -N -p qibusproxy -c QIBusProxy interfaces/org.freedesktop.IBus.xml
+ *
+ * qdbusxml2cpp is Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * This is an auto-generated file.
+ * This file may have been hand-edited. Look for HAND-EDIT comments
+ * before re-generating it.
+ */
+
+#include "qibusproxy.h"
+
+/*
+ * Implementation of interface class QIBusProxy
+ */
+
+QIBusProxy::QIBusProxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)
+ : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent)
+{
+}
+
+QIBusProxy::~QIBusProxy()
+{
+}
+
diff --git a/src/plugins/platforminputcontexts/ibus/qibusproxy.h b/src/plugins/platforminputcontexts/ibus/qibusproxy.h
new file mode 100644
index 0000000000..389eec3175
--- /dev/null
+++ b/src/plugins/platforminputcontexts/ibus/qibusproxy.h
@@ -0,0 +1,88 @@
+/*
+ * This file was generated by qdbusxml2cpp version 0.7
+ * Command line was: qdbusxml2cpp -N -p qibusproxy -c QIBusProxy interfaces/org.freedesktop.IBus.xml
+ *
+ * qdbusxml2cpp is Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * This is an auto-generated file.
+ * Do not edit! All changes made to it will be lost.
+ */
+
+#ifndef QIBUSPROXY_H_1308831142
+#define QIBUSPROXY_H_1308831142
+
+#include <QtCore/QObject>
+#include <QtCore/QByteArray>
+#include <QtCore/QList>
+#include <QtCore/QMap>
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+#include <QtCore/QVariant>
+#include <QtDBus/QtDBus>
+
+/*
+ * Proxy class for interface org.freedesktop.IBus
+ */
+class QIBusProxy: public QDBusAbstractInterface
+{
+ Q_OBJECT
+public:
+ static inline const char *staticInterfaceName()
+ { return "org.freedesktop.IBus"; }
+
+public:
+ QIBusProxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0);
+
+ ~QIBusProxy();
+
+public Q_SLOTS: // METHODS
+ inline QDBusPendingReply<QDBusObjectPath> CreateInputContext(const QString &name)
+ {
+ QList<QVariant> argumentList;
+ argumentList << QVariant::fromValue(name);
+ return asyncCallWithArgumentList(QLatin1String("CreateInputContext"), argumentList);
+ }
+
+ inline QDBusPendingReply<> Exit(bool restart)
+ {
+ QList<QVariant> argumentList;
+ argumentList << QVariant::fromValue(restart);
+ return asyncCallWithArgumentList(QLatin1String("Exit"), argumentList);
+ }
+
+ inline QDBusPendingReply<QString> GetAddress()
+ {
+ QList<QVariant> argumentList;
+ return asyncCallWithArgumentList(QLatin1String("GetAddress"), argumentList);
+ }
+
+ inline QDBusPendingReply<QVariantList> ListActiveEngines()
+ {
+ QList<QVariant> argumentList;
+ return asyncCallWithArgumentList(QLatin1String("ListActiveEngines"), argumentList);
+ }
+
+ inline QDBusPendingReply<QVariantList> ListEngines()
+ {
+ QList<QVariant> argumentList;
+ return asyncCallWithArgumentList(QLatin1String("ListEngines"), argumentList);
+ }
+
+ inline QDBusPendingReply<QDBusVariant> Ping(const QDBusVariant &data)
+ {
+ QList<QVariant> argumentList;
+ argumentList << QVariant::fromValue(data);
+ return asyncCallWithArgumentList(QLatin1String("Ping"), argumentList);
+ }
+
+ inline QDBusPendingReply<> RegisterComponent(const QDBusVariant &components)
+ {
+ QList<QVariant> argumentList;
+ argumentList << QVariant::fromValue(components);
+ return asyncCallWithArgumentList(QLatin1String("RegisterComponent"), argumentList);
+ }
+
+Q_SIGNALS: // SIGNALS
+};
+
+#endif
diff --git a/src/plugins/platforminputcontexts/ibus/qibustypes.cpp b/src/plugins/platforminputcontexts/ibus/qibustypes.cpp
new file mode 100644
index 0000000000..8d8c61afb7
--- /dev/null
+++ b/src/plugins/platforminputcontexts/ibus/qibustypes.cpp
@@ -0,0 +1,209 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qibustypes.h"
+#include <qtextformat.h>
+#include <QtDBus>
+
+QIBusSerializable::QIBusSerializable()
+{
+}
+
+QIBusSerializable::~QIBusSerializable()
+{
+}
+
+void QIBusSerializable::fromDBusArgument(const QDBusArgument &arg)
+{
+ arg >> name;
+ arg.beginMap();
+ while (!arg.atEnd()) {
+ arg.beginMapEntry();
+ QString key;
+ QDBusVariant value;
+ arg >> key;
+ arg >> value;
+ arg.endMapEntry();
+ attachments[key] = value.variant().value<QDBusArgument>();
+ }
+ arg.endMap();
+}
+
+
+
+QIBusAttribute::QIBusAttribute()
+ : type(Invalid),
+ value(0),
+ start(0),
+ end(0)
+{
+}
+
+QIBusAttribute::~QIBusAttribute()
+{
+
+}
+
+void QIBusAttribute::fromDBusArgument(const QDBusArgument &arg)
+{
+// qDebug() << "QIBusAttribute::fromDBusArgument()" << arg.currentSignature();
+ arg.beginStructure();
+
+ QIBusSerializable::fromDBusArgument(arg);
+
+ quint32 t;
+ arg >> t;
+ type = (Type)t;
+ arg >> value;
+ arg >> start;
+ arg >> end;
+
+ arg.endStructure();
+}
+
+QTextFormat QIBusAttribute::format() const
+{
+ QTextCharFormat fmt;
+ switch (type) {
+ case Invalid:
+ break;
+ case Underline: {
+ QTextCharFormat::UnderlineStyle style = QTextCharFormat::NoUnderline;
+
+ switch (value) {
+ case UnderlineNone:
+ break;
+ case UnderlineSingle:
+ style = QTextCharFormat::SingleUnderline;
+ break;
+ case UnderlineDouble:
+ style = QTextCharFormat::DashUnderline;
+ break;
+ case UnderlineLow:
+ style = QTextCharFormat::DashDotLine;
+ break;
+ case UnderlineError:
+ style = QTextCharFormat::WaveUnderline;
+ fmt.setUnderlineColor(Qt::red);
+ break;
+ }
+
+ fmt.setUnderlineStyle(style);
+ break;
+ }
+ case Foreground:
+ fmt.setForeground(QColor(value));
+ break;
+ case Background:
+ fmt.setBackground(QColor(value));
+ break;
+ }
+ return fmt;
+}
+
+
+QIBusAttributeList::QIBusAttributeList()
+{
+
+}
+
+QIBusAttributeList::~QIBusAttributeList()
+{
+
+}
+
+void QIBusAttributeList::fromDBusArgument(const QDBusArgument &arg)
+{
+// qDebug() << "QIBusAttributeList::fromDBusArgument()" << arg.currentSignature();
+ arg.beginStructure();
+
+ QIBusSerializable::fromDBusArgument(arg);
+
+ arg.beginArray();
+ while(!arg.atEnd()) {
+ QDBusVariant var;
+ arg >> var;
+
+ QIBusAttribute attr;
+ attr.fromDBusArgument(var.variant().value<QDBusArgument>());
+ attributes.append(attr);
+ }
+ arg.endArray();
+
+ arg.endStructure();
+}
+
+QList<QInputMethodEvent::Attribute> QIBusAttributeList::imAttributes() const
+{
+ QList<QInputMethodEvent::Attribute> imAttrs;
+ for (int i = 0; i < attributes.size(); ++i) {
+ const QIBusAttribute &attr = attributes.at(i);
+ imAttrs += QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, attr.start, attr.end - attr.start, attr.format());
+ }
+ return imAttrs;
+}
+
+
+QIBusText::QIBusText()
+{
+
+}
+
+QIBusText::~QIBusText()
+{
+
+}
+
+void QIBusText::fromDBusArgument(const QDBusArgument &arg)
+{
+// qDebug() << "QIBusText::fromDBusArgument()" << arg.currentSignature();
+ arg.beginStructure();
+
+ QIBusSerializable::fromDBusArgument(arg);
+
+ arg >> text;
+ QDBusVariant variant;
+ arg >> variant;
+ attributes.fromDBusArgument(variant.variant().value<QDBusArgument>());
+
+ arg.endStructure();
+}
+
diff --git a/src/plugins/platforminputcontexts/ibus/qibustypes.h b/src/plugins/platforminputcontexts/ibus/qibustypes.h
new file mode 100644
index 0000000000..c426ff7eda
--- /dev/null
+++ b/src/plugins/platforminputcontexts/ibus/qibustypes.h
@@ -0,0 +1,116 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QIBUSTYPES_H
+#define QIBUSTYPES_H
+
+#include <qvector.h>
+#include <qevent.h>
+
+class QDBusArgument;
+
+class QIBusSerializable
+{
+public:
+ QIBusSerializable();
+ virtual ~QIBusSerializable();
+
+ virtual void fromDBusArgument(const QDBusArgument &arg);
+
+ QString name;
+ QHash<QString, QDBusArgument> attachments;
+};
+
+class QIBusAttribute : public QIBusSerializable
+{
+public:
+ enum Type {
+ Invalid = 0,
+ Underline = 1,
+ Foreground = 2,
+ Background = 3,
+ };
+
+ enum Underline {
+ UnderlineNone = 0,
+ UnderlineSingle = 1,
+ UnderlineDouble = 2,
+ UnderlineLow = 3,
+ UnderlineError = 4,
+ };
+
+ QIBusAttribute();
+ ~QIBusAttribute();
+
+ void fromDBusArgument(const QDBusArgument &arg);
+ QTextFormat format() const;
+
+ Type type;
+ quint32 value;
+ quint32 start;
+ quint32 end;
+};
+
+class QIBusAttributeList : public QIBusSerializable
+{
+public:
+ QIBusAttributeList();
+ ~QIBusAttributeList();
+
+ void fromDBusArgument(const QDBusArgument &arg);
+
+ QList<QInputMethodEvent::Attribute> imAttributes() const;
+
+ QVector<QIBusAttribute> attributes;
+};
+
+class QIBusText : public QIBusSerializable
+{
+public:
+ QIBusText();
+ ~QIBusText();
+
+ void fromDBusArgument(const QDBusArgument &arg);
+
+ QString text;
+ QIBusAttributeList attributes;
+};
+
+#endif
diff --git a/src/plugins/platforminputcontexts/platforminputcontexts.pro b/src/plugins/platforminputcontexts/platforminputcontexts.pro
new file mode 100644
index 0000000000..b6e2b6e775
--- /dev/null
+++ b/src/plugins/platforminputcontexts/platforminputcontexts.pro
@@ -0,0 +1,4 @@
+TEMPLATE = subdirs
+
+!macx:!win:SUBDIRS += ibus
+
diff --git a/src/plugins/platforms/cocoa/cocoa.pro b/src/plugins/platforms/cocoa/cocoa.pro
index bfa147f948..d6801e0bed 100644
--- a/src/plugins/platforms/cocoa/cocoa.pro
+++ b/src/plugins/platforms/cocoa/cocoa.pro
@@ -2,28 +2,46 @@ TARGET = qcocoa
load(qt_plugin)
DESTDIR = $$QT.gui.plugins/platforms
-OBJECTIVE_SOURCES = main.mm \
+OBJECTIVE_SOURCES += main.mm \
qcocoaintegration.mm \
- qcocoawindowsurface.mm \
+ qcocoabackingstore.mm \
qcocoawindow.mm \
qnsview.mm \
- qcocoaeventloopintegration.mm \
qcocoaautoreleasepool.mm \
- qnswindowdelegate.mm
+ qnswindowdelegate.mm \
+ qcocoaglcontext.mm \
+ qcocoanativeinterface.mm \
+ qcocoaeventdispatcher.mm \
+ qcocoamenuloader.mm \
+ qcocoaapplicationdelegate.mm \
+ qcocoaapplication.mm \
+ qcocoamenu.mm \
+ qmenu_mac.mm \
+ qcocoahelpers.mm \
-OBJECTIVE_HEADERS = qcocoaintegration.h \
- qcocoawindowsurface.h \
+HEADERS += qcocoaintegration.h \
+ qcocoabackingstore.h \
qcocoawindow.h \
qnsview.h \
- qcocoaeventloopintegration.h \
qcocoaautoreleasepool.h \
- qnswindowdelegate.h
+ qnswindowdelegate.h \
+ qcocoaglcontext.h \
+ qcocoanativeinterface.h \
+ qcocoaeventdispatcher.h \
+ qcocoamenuloader.h \
+ qcocoaapplicationdelegate.h \
+ qcocoaapplication.h \
+ qcocoamenu.h \
+ qmenu_mac.h \
+ qcocoahelpers.h \
+
+RESOURCES += qcocoaresources.qrc
#add libz for freetype.
-LIBS += -lz
-LIBS += -framework cocoa
+LIBS += -lz -framework Cocoa
+
+QT += core-private gui-private widgets-private platformsupport-private
-include(../fontdatabases/coretext/coretext.pri)
+CONFIG += qpa/basicunixfontdatabase
target.path += $$[QT_INSTALL_PLUGINS]/platforms
INSTALLS += target
-
diff --git a/src/gui/mac/images/copyarrowcursor.png b/src/plugins/platforms/cocoa/images/copyarrowcursor.png
index 13dfca95bc..13dfca95bc 100644
--- a/src/gui/mac/images/copyarrowcursor.png
+++ b/src/plugins/platforms/cocoa/images/copyarrowcursor.png
Binary files differ
diff --git a/src/gui/mac/images/forbiddencursor.png b/src/plugins/platforms/cocoa/images/forbiddencursor.png
index a9f21b4a5e..a9f21b4a5e 100644
--- a/src/gui/mac/images/forbiddencursor.png
+++ b/src/plugins/platforms/cocoa/images/forbiddencursor.png
Binary files differ
diff --git a/src/gui/mac/images/leopard-unified-toolbar-on.png b/src/plugins/platforms/cocoa/images/leopard-unified-toolbar-on.png
index 6716597046..6716597046 100644
--- a/src/gui/mac/images/leopard-unified-toolbar-on.png
+++ b/src/plugins/platforms/cocoa/images/leopard-unified-toolbar-on.png
Binary files differ
diff --git a/src/gui/mac/images/pluscursor.png b/src/plugins/platforms/cocoa/images/pluscursor.png
index c583c088c9..c583c088c9 100644
--- a/src/gui/mac/images/pluscursor.png
+++ b/src/plugins/platforms/cocoa/images/pluscursor.png
Binary files differ
diff --git a/src/gui/mac/images/spincursor.png b/src/plugins/platforms/cocoa/images/spincursor.png
index ca44ab50fd..ca44ab50fd 100644
--- a/src/gui/mac/images/spincursor.png
+++ b/src/plugins/platforms/cocoa/images/spincursor.png
Binary files differ
diff --git a/src/gui/mac/images/waitcursor.png b/src/plugins/platforms/cocoa/images/waitcursor.png
index a9abe61320..a9abe61320 100644
--- a/src/gui/mac/images/waitcursor.png
+++ b/src/plugins/platforms/cocoa/images/waitcursor.png
Binary files differ
diff --git a/src/plugins/platforms/cocoa/qcocoaapplication.h b/src/plugins/platforms/cocoa/qcocoaapplication.h
new file mode 100644
index 0000000000..5b6b2f48f2
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoaapplication.h
@@ -0,0 +1,116 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/****************************************************************************
+**
+** Copyright (c) 2007-2008, Apple, Inc.
+**
+** All rights reserved.
+**
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are met:
+**
+** * Redistributions of source code must retain the above copyright notice,
+** this list of conditions and the following disclaimer.
+**
+** * Redistributions in binary form must reproduce the above copyright notice,
+** this list of conditions and the following disclaimer in the documentation
+** and/or other materials provided with the distribution.
+**
+** * Neither the name of Apple, Inc. nor the names of its contributors
+** may be used to endorse or promote products derived from this software
+** without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of qapplication_*.cpp, qwidget*.cpp, qcolor_x11.cpp, qfiledialog.cpp
+// and many other. This header file may change from version to version
+// without notice, or even be removed.
+//
+// We mean it.
+//
+
+/*
+ Cocoa Application Categories
+*/
+#include "qglobal.h"
+
+#import <AppKit/AppKit.h>
+QT_FORWARD_DECLARE_CLASS(QApplicationPrivate)
+@class QT_MANGLE_NAMESPACE(QCocoaMenuLoader);
+
+@interface NSApplication (QT_MANGLE_NAMESPACE(QApplicationIntegration))
+- (void)QT_MANGLE_NAMESPACE(qt_setDockMenu):(NSMenu *)newMenu;
+- (QApplicationPrivate *)QT_MANGLE_NAMESPACE(qt_qappPrivate);
+- (QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *)QT_MANGLE_NAMESPACE(qt_qcocoamenuLoader);
+- (int)QT_MANGLE_NAMESPACE(qt_validModesForFontPanel):(NSFontPanel *)fontPanel;
+
+- (void)qt_sendPostedMessage:(NSEvent *)event;
+- (BOOL)qt_filterEvent:(NSEvent *)event;
+@end
+
+@interface QNSApplication : NSApplication {
+}
+@end
+
+QT_BEGIN_NAMESPACE
+
+void qt_redirectNSApplicationSendEvent();
+
+QT_END_NAMESPACE
+
diff --git a/src/plugins/platforms/cocoa/qcocoaapplication.mm b/src/plugins/platforms/cocoa/qcocoaapplication.mm
new file mode 100644
index 0000000000..2adf6a57f0
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoaapplication.mm
@@ -0,0 +1,227 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/****************************************************************************
+**
+** Copyright (c) 2007-2008, Apple, Inc.
+**
+** All rights reserved.
+**
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are met:
+**
+** * Redistributions of source code must retain the above copyright notice,
+** this list of conditions and the following disclaimer.
+**
+** * Redistributions in binary form must reproduce the above copyright notice,
+** this list of conditions and the following disclaimer in the documentation
+** and/or other materials provided with the distribution.
+**
+** * Neither the name of Apple, Inc. nor the names of its contributors
+** may be used to endorse or promote products derived from this software
+** without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+**
+****************************************************************************/
+
+#include <qcocoaapplication.h>
+
+#include <qcocoaapplicationdelegate.h>
+#include <qcocoahelpers.h>
+#include <qguiapplication.h>
+#include <qdebug.h>
+
+QT_USE_NAMESPACE
+
+@implementation NSApplication (QT_MANGLE_NAMESPACE(QApplicationIntegration))
+
+- (void)QT_MANGLE_NAMESPACE(qt_setDockMenu):(NSMenu *)newMenu
+{
+ [[QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) sharedDelegate] setDockMenu:newMenu];
+}
+
+- (QApplicationPrivate *)QT_MANGLE_NAMESPACE(qt_qappPrivate)
+{
+ return [[QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) sharedDelegate] qAppPrivate];
+}
+
+- (QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *)QT_MANGLE_NAMESPACE(qt_qcocoamenuLoader)
+{
+ return [[QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) sharedDelegate] menuLoader];
+}
+
+- (int)QT_MANGLE_NAMESPACE(qt_validModesForFontPanel):(NSFontPanel *)fontPanel
+{
+ Q_UNUSED(fontPanel);
+ // only display those things that QFont can handle
+ return NSFontPanelFaceModeMask
+ | NSFontPanelSizeModeMask
+ | NSFontPanelCollectionModeMask
+ | NSFontPanelUnderlineEffectModeMask
+ | NSFontPanelStrikethroughEffectModeMask;
+}
+
+- (void)qt_sendPostedMessage:(NSEvent *)event
+{
+/*
+ // WARNING: data1 and data2 is truncated to from 64-bit to 32-bit on OS 10.5!
+ // That is why we need to split the address in two parts:
+ quint64 lower = [event data1];
+ quint64 upper = [event data2];
+ QCocoaPostMessageArgs *args = reinterpret_cast<QCocoaPostMessageArgs *>(lower | (upper << 32));
+ // Special case for convenience: if the argument is an NSNumber, we unbox it directly.
+ // Use NSValue instead if this behaviour is unwanted.
+ id a1 = ([args->arg1 isKindOfClass:[NSNumber class]]) ? (id)[args->arg1 intValue] : args->arg1;
+ id a2 = ([args->arg2 isKindOfClass:[NSNumber class]]) ? (id)[args->arg2 intValue] : args->arg2;
+ switch (args->argCount) {
+ case 0:
+ [args->target performSelector:args->selector];
+ break;
+ case 1:
+ [args->target performSelector:args->selector withObject:a1];
+ break;
+ case 3:
+ [args->target performSelector:args->selector withObject:a1 withObject:a2];
+ break;
+ }
+
+ delete args;
+*/
+}
+
+- (BOOL)qt_filterEvent:(NSEvent *)event
+{
+/*
+ if (qApp->macEventFilter(0, reinterpret_cast<EventRef>(event)))
+ return true;
+
+ if ([event type] == NSApplicationDefined) {
+ switch ([event subtype]) {
+ case QtCocoaEventSubTypePostMessage:
+ [NSApp qt_sendPostedMessage:event];
+ return true;
+ default:
+ break;
+ }
+ }
+*/
+ return false;
+}
+
+@end
+
+@implementation QNSApplication
+
+- (void)qt_sendEvent_original:(NSEvent *)event
+{
+ Q_UNUSED(event);
+ // This method will only be used as a signature
+ // template for the method we add into NSApplication
+ // containing the original [NSApplication sendEvent:] implementation
+}
+
+- (void)qt_sendEvent_replacement:(NSEvent *)event
+{
+ // This method (or its implementation to be precise) will
+ // be called instead of sendEvent if redirection occurs.
+ // 'self' will then be an instance of NSApplication
+ // (and not QNSApplication)
+ if (![NSApp qt_filterEvent:event])
+ [self qt_sendEvent_original:event];
+}
+
+- (void)sendEvent:(NSEvent *)event
+{
+ // This method will be called if
+ // no redirection occurs
+ if (![NSApp qt_filterEvent:event])
+ [super sendEvent:event];
+}
+
+- (void)qtDispatcherToQAction:(id)sender
+{
+ // Forward actions sendt from the menu bar (e.g. quit) to the menu loader.
+ // Having this method here means that we are the last stop in the responder
+ // chain, and that we are able to handle menu actions even when no window is
+ // visible on screen. Note: If Qt is used as a plugin, Qt will not use a
+ // native menu bar. Hence, we will also not need to do any redirection etc. as
+ // we do with sendEvent.
+ [[NSApp QT_MANGLE_NAMESPACE(qt_qcocoamenuLoader)] qtDispatcherToQAction:sender];
+}
+
+@end
+
+QT_BEGIN_NAMESPACE
+
+void qt_redirectNSApplicationSendEvent()
+{
+/*
+ if ([NSApp isMemberOfClass:[QNSApplication class]]) {
+ // No need to change implementation since Qt
+ // already controls a subclass of NSApplication
+ return;
+ }
+
+ // Change the implementation of [NSApplication sendEvent] to the
+ // implementation of qt_sendEvent_replacement found in QNSApplication.
+ // And keep the old implementation that gets overwritten inside a new
+ // method 'qt_sendEvent_original' that we add to NSApplication
+ qt_cocoa_change_implementation(
+ [NSApplication class],
+ @selector(sendEvent:),
+ [QNSApplication class],
+ @selector(qt_sendEvent_replacement:),
+ @selector(qt_sendEvent_original:));
+ */
+ }
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.h b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.h
new file mode 100644
index 0000000000..7f8d1dfacd
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.h
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+/****************************************************************************
+ **
+ ** Copyright (c) 2007-2008, Apple, Inc.
+ **
+ ** All rights reserved.
+ **
+ ** Redistribution and use in source and binary forms, with or without
+ ** modification, are permitted provided that the following conditions are met:
+ **
+ ** * Redistributions of source code must retain the above copyright notice,
+ ** this list of conditions and the following disclaimer.
+ **
+ ** * Redistributions in binary form must reproduce the above copyright notice,
+ ** this list of conditions and the following disclaimer in the documentation
+ ** and/or other materials provided with the distribution.
+ **
+ ** * Neither the name of Apple, Inc. nor the names of its contributors
+ ** may be used to endorse or promote products derived from this software
+ ** without specific prior written permission.
+ **
+ ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ ** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ ** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ ** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ ** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ ** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ ** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ **
+ ****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of qapplication_*.cpp, qwidget*.cpp, qcolor_x11.cpp, qfiledialog.cpp
+// and many other. This header file may change from version to version
+// without notice, or even be removed.
+//
+// We mean it.
+//
+
+
+#import <Cocoa/Cocoa.h>
+
+#include <qglobal.h>
+
+QT_FORWARD_DECLARE_CLASS(QApplicationPrivate);
+
+@class QT_MANGLE_NAMESPACE(QCocoaMenuLoader);
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5
+
+@protocol NSApplicationDelegate <NSObject>
+- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender;
+- (void)applicationDidFinishLaunching:(NSNotification *)aNotification;
+- (void)application:(NSApplication *)sender openFiles:(NSArray *)filenames;
+- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender;
+- (void)applicationDidBecomeActive:(NSNotification *)notification;
+- (void)applicationDidResignActive:(NSNotification *)notification;
+@end
+
+#endif
+
+@interface QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) : NSObject <NSApplicationDelegate> {
+ bool startedQuit;
+ QApplicationPrivate *qtPrivate;
+ NSMenu *dockMenu;
+ QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *qtMenuLoader;
+ NSObject <NSApplicationDelegate> *reflectionDelegate;
+ bool inLaunch;
+}
++ (QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate)*)sharedDelegate;
+- (void)setDockMenu:(NSMenu *)newMenu;
+- (void)setQtPrivate:(QApplicationPrivate *)value;
+- (QApplicationPrivate *)qAppPrivate;
+- (void)setMenuLoader:(QT_MANGLE_NAMESPACE(QCocoaMenuLoader)*)menuLoader;
+- (QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *)menuLoader;
+- (void)setReflectionDelegate:(NSObject <NSApplicationDelegate> *)oldDelegate;
+- (void)getUrl:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent;
+@end
diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
new file mode 100644
index 0000000000..6a2508359b
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
@@ -0,0 +1,354 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/****************************************************************************
+ **
+ ** Copyright (c) 2007-2008, Apple, Inc.
+ **
+ ** All rights reserved.
+ **
+ ** Redistribution and use in source and binary forms, with or without
+ ** modification, are permitted provided that the following conditions are met:
+ **
+ ** * Redistributions of source code must retain the above copyright notice,
+ ** this list of conditions and the following disclaimer.
+ **
+ ** * Redistributions in binary form must reproduce the above copyright notice,
+ ** this list of conditions and the following disclaimer in the documentation
+ ** and/or other materials provided with the distribution.
+ **
+ ** * Neither the name of Apple, Inc. nor the names of its contributors
+ ** may be used to endorse or promote products derived from this software
+ ** without specific prior written permission.
+ **
+ ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ ** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ ** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ ** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ ** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ ** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ ** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ **
+ ****************************************************************************/
+
+
+#import "qcocoaapplicationdelegate.h"
+#import "qnswindowdelegate.h"
+#include <qevent.h>
+#include <qurl.h>
+#include <qdebug.h>
+#include <qguiapplication.h>
+
+QT_USE_NAMESPACE
+
+static QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) *sharedCocoaApplicationDelegate = nil;
+
+static void cleanupCocoaApplicationDelegate()
+{
+ [sharedCocoaApplicationDelegate release];
+}
+
+@implementation QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate)
+
+- (id)init
+{
+ self = [super init];
+ if (self)
+ inLaunch = true;
+ return self;
+}
+
+- (void)dealloc
+{
+ sharedCocoaApplicationDelegate = nil;
+ [dockMenu release];
+ [qtMenuLoader release];
+ if (reflectionDelegate) {
+ [NSApp setDelegate:reflectionDelegate];
+ [reflectionDelegate release];
+ }
+ [super dealloc];
+}
+
++ (id)allocWithZone:(NSZone *)zone
+{
+ @synchronized(self) {
+ if (sharedCocoaApplicationDelegate == nil) {
+ sharedCocoaApplicationDelegate = [super allocWithZone:zone];
+ return sharedCocoaApplicationDelegate;
+ qAddPostRoutine(cleanupCocoaApplicationDelegate);
+ }
+ }
+ return nil;
+}
+
++ (QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate)*)sharedDelegate
+{
+ @synchronized(self) {
+ if (sharedCocoaApplicationDelegate == nil)
+ [[self alloc] init];
+ }
+ return [[sharedCocoaApplicationDelegate retain] autorelease];
+}
+
+- (void)setDockMenu:(NSMenu*)newMenu
+{
+ [newMenu retain];
+ [dockMenu release];
+ dockMenu = newMenu;
+}
+
+- (NSMenu *)applicationDockMenu
+{
+ return [[dockMenu retain] autorelease];
+}
+
+- (QApplicationPrivate *)qAppPrivate
+{
+ return qtPrivate;
+}
+
+- (void)setQtPrivate:(QApplicationPrivate *)value
+{
+ qtPrivate = value;
+}
+
+- (void)setMenuLoader:(QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *)menuLoader
+{
+ [menuLoader retain];
+ [qtMenuLoader release];
+ qtMenuLoader = menuLoader;
+}
+
+- (QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *)menuLoader
+{
+ return [[qtMenuLoader retain] autorelease];
+}
+
+// This function will only be called when NSApp is actually running. Before
+// that, the kAEQuitApplication Apple event will be sent to
+// QApplicationPrivate::globalAppleEventProcessor in qapplication_mac.mm
+- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
+{
+/*
+ Q_UNUSED(sender);
+ // The reflection delegate gets precedence
+ if (reflectionDelegate
+ && [reflectionDelegate respondsToSelector:@selector(applicationShouldTerminate:)]) {
+ return [reflectionDelegate applicationShouldTerminate:sender];
+ }
+
+ if (qtPrivate->canQuit()) {
+ if (!startedQuit) {
+ startedQuit = true;
+ qAppInstance()->quit();
+ startedQuit = false;
+ }
+ }
+
+ if (qtPrivate->threadData->eventLoops.size() == 0) {
+ // INVARIANT: No event loop is executing. This probably
+ // means that Qt is used as a plugin, or as a part of a native
+ // Cocoa application. In any case it should be fine to
+ // terminate now:
+ return NSTerminateNow;
+ }
+
+ return NSTerminateCancel;
+*/
+ return NSTerminateNow;
+}
+
+- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
+{
+ Q_UNUSED(aNotification);
+ inLaunch = false;
+ // qt_release_apple_event_handler();
+
+
+ // Insert code here to initialize your application
+}
+
+
+
+- (void)application:(NSApplication *)sender openFiles:(NSArray *)filenames
+{
+/*
+ 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 &&
+ [reflectionDelegate respondsToSelector:@selector(application:openFiles:)])
+ [reflectionDelegate application:sender openFiles:filenames];
+*/
+}
+
+- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender
+{
+ // If we have a reflection delegate, that will get to call the shots.
+ if (reflectionDelegate
+ && [reflectionDelegate respondsToSelector:
+ @selector(applicationShouldTerminateAfterLastWindowClosed:)])
+ return [reflectionDelegate applicationShouldTerminateAfterLastWindowClosed:sender];
+ return NO; // Someday qApp->quitOnLastWindowClosed(); when QApp and NSApp work closer together.
+}
+
+
+- (void)applicationDidBecomeActive:(NSNotification *)notification
+{
+/*
+ if (reflectionDelegate
+ && [reflectionDelegate respondsToSelector:@selector(applicationDidBecomeActive:)])
+ [reflectionDelegate applicationDidBecomeActive:notification];
+
+ onApplicationChangedActivation(true);
+
+ if (!QWidget::mouseGrabber()){
+ // Update enter/leave immidiatly, don't wait for a move event. But only
+ // if no grab exists (even if the grab points to this widget, it seems, ref X11)
+ QPoint qlocal, qglobal;
+ QWidget *widgetUnderMouse = 0;
+ qt_mac_getTargetForMouseEvent(0, QEvent::Enter, qlocal, qglobal, 0, &widgetUnderMouse);
+ QApplicationPrivate::dispatchEnterLeave(widgetUnderMouse, 0);
+ qt_last_mouse_receiver = widgetUnderMouse;
+ qt_last_native_mouse_receiver = widgetUnderMouse ?
+ (widgetUnderMouse->internalWinId() ? widgetUnderMouse : widgetUnderMouse->nativeParentWidget()) : 0;
+ }
+*/
+}
+
+- (void)applicationDidResignActive:(NSNotification *)notification
+{
+/*
+ if (reflectionDelegate
+ && [reflectionDelegate respondsToSelector:@selector(applicationDidResignActive:)])
+ [reflectionDelegate applicationDidResignActive:notification];
+
+ onApplicationChangedActivation(false);
+
+ if (!QWidget::mouseGrabber())
+ QApplicationPrivate::dispatchEnterLeave(0, qt_last_mouse_receiver);
+ qt_last_mouse_receiver = 0;
+ qt_last_native_mouse_receiver = 0;
+ qt_button_down = 0;
+*/
+}
+
+- (void)applicationDidChangeScreenParameters:(NSNotification *)notification
+{
+ Q_UNUSED(notification);
+ //QDesktopWidgetImplementation::instance()->onResize();
+}
+
+- (void)setReflectionDelegate:(NSObject <NSApplicationDelegate> *)oldDelegate
+{
+ [oldDelegate retain];
+ [reflectionDelegate release];
+ reflectionDelegate = oldDelegate;
+}
+
+- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
+{
+ NSMethodSignature *result = [super methodSignatureForSelector:aSelector];
+ if (!result && reflectionDelegate) {
+ result = [reflectionDelegate methodSignatureForSelector:aSelector];
+ }
+ return result;
+}
+
+- (BOOL)respondsToSelector:(SEL)aSelector
+{
+ BOOL result = [super respondsToSelector:aSelector];
+ if (!result && reflectionDelegate)
+ result = [reflectionDelegate respondsToSelector:aSelector];
+ return result;
+}
+
+- (void)forwardInvocation:(NSInvocation *)invocation
+{
+ SEL invocationSelector = [invocation selector];
+ if (reflectionDelegate && [reflectionDelegate respondsToSelector:invocationSelector])
+ [invocation invokeWithTarget:reflectionDelegate];
+ else
+ [self doesNotRecognizeSelector:invocationSelector];
+}
+
+- (void)getUrl:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent
+{
+ Q_UNUSED(replyEvent);
+/*
+ NSString *urlString = [[event paramDescriptorForKeyword:keyDirectObject] stringValue];
+ QUrl url(qt_mac_NSStringToQString(urlString));
+ QFileOpenEvent qtEvent(url);
+ qt_sendSpontaneousEvent(qAppInstance(), &qtEvent);
+*/
+}
+
+- (void)appleEventQuit:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent
+{
+ Q_UNUSED(event);
+ Q_UNUSED(replyEvent);
+ qDebug() << "appleEventQuit";
+
+ [NSApp terminate:self];
+}
+
+- (void)qtDispatcherToQAction:(id)sender
+{
+ //[[NSApp QT_MANGLE_NAMESPACE(qt_qcocoamenuLoader)] qtDispatcherToQAction:sender];
+}
+
+@end
diff --git a/src/plugins/platforms/cocoa/qcocoaautoreleasepool.h b/src/plugins/platforms/cocoa/qcocoaautoreleasepool.h
index 862bc27f9d..359b5d34d0 100644
--- a/src/plugins/platforms/cocoa/qcocoaautoreleasepool.h
+++ b/src/plugins/platforms/cocoa/qcocoaautoreleasepool.h
@@ -42,6 +42,8 @@
#ifndef QCOCOAAUTORELEASEPOOL_H
#define QCOCOAAUTORELEASEPOOL_H
+#undef slots
+
#include <Cocoa/Cocoa.h>
class QCocoaAutoReleasePool
diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.h b/src/plugins/platforms/cocoa/qcocoabackingstore.h
new file mode 100644
index 0000000000..938e27347c
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoabackingstore.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QBACKINGSTORE_COCOA_H
+#define QBACKINGSTORE_COCOA_H
+
+#include <Cocoa/Cocoa.h>
+
+#include "qcocoawindow.h"
+#include "qnsview.h"
+
+#include <QPlatformBackingStore>
+
+QT_BEGIN_NAMESPACE
+
+class QCocoaBackingStore : public QPlatformBackingStore
+{
+public:
+ QCocoaBackingStore(QWindow *window);
+ ~QCocoaBackingStore();
+
+ QPaintDevice *paintDevice();
+ void flush(QWindow *widget, const QRegion &region, const QPoint &offset);
+ void resize (const QSize &size, const QRegion &);
+
+private:
+ QCocoaWindow *m_cocoaWindow;
+ QImage *m_image;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.mm b/src/plugins/platforms/cocoa/qcocoabackingstore.mm
new file mode 100644
index 0000000000..5a59fb5c49
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoabackingstore.mm
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcocoabackingstore.h"
+
+#include <QtCore/qdebug.h>
+#include <QtGui/QPainter>
+
+QT_BEGIN_NAMESPACE
+
+QRect flipedRect(const QRect &sourceRect,int height)
+{
+ if (!sourceRect.isValid())
+ return QRect();
+ QRect flippedRect = sourceRect;
+ flippedRect.moveTop(height - sourceRect.y());
+ return flippedRect;
+}
+
+QCocoaBackingStore::QCocoaBackingStore(QWindow *window)
+ : QPlatformBackingStore(window)
+{
+ m_cocoaWindow = static_cast<QCocoaWindow *>(window->handle());
+
+ const QRect geo = window->geometry();
+ NSRect rect = NSMakeRect(geo.x(),geo.y(),geo.width(),geo.height());
+
+ m_image = new QImage(window->geometry().size(),QImage::Format_ARGB32);
+}
+
+QCocoaBackingStore::~QCocoaBackingStore()
+{
+ delete m_image;
+}
+
+QPaintDevice *QCocoaBackingStore::paintDevice()
+{
+ return m_image;
+}
+
+void QCocoaBackingStore::flush(QWindow *widget, const QRegion &region, const QPoint &offset)
+{
+ Q_UNUSED(widget);
+ Q_UNUSED(offset);
+
+ QRect geo = region.boundingRect();
+
+ NSRect rect = NSMakeRect(geo.x(), geo.y(), geo.width(), geo.height());
+ [m_cocoaWindow->m_contentView displayRect:rect];
+}
+
+void QCocoaBackingStore::resize(const QSize &size, const QRegion &)
+{
+ delete m_image;
+ m_image = new QImage(size,QImage::Format_ARGB32_Premultiplied);
+ NSSize newSize = NSMakeSize(size.width(),size.height());
+ [static_cast<QNSView *>(m_cocoaWindow->m_contentView) setImage:m_image];
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h
new file mode 100644
index 0000000000..7184db84fa
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h
@@ -0,0 +1,220 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/****************************************************************************
+**
+** Copyright (c) 2007-2008, Apple, Inc.
+**
+** All rights reserved.
+**
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are met:
+**
+** * Redistributions of source code must retain the above copyright notice,
+** this list of conditions and the following disclaimer.
+**
+** * Redistributions in binary form must reproduce the above copyright notice,
+** this list of conditions and the following disclaimer in the documentation
+** and/or other materials provided with the distribution.
+**
+** * Neither the name of Apple, Inc. nor the names of its contributors
+** may be used to endorse or promote products derived from this software
+** without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+**
+****************************************************************************/
+
+#ifndef QEVENTDISPATCHER_MAC_P_H
+#define QEVENTDISPATCHER_MAC_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qhash.h>
+#include <QtCore/qstack.h>
+#include <QtGui/qwindowdefs.h>
+#include <QtCore/private/qeventdispatcher_unix_p.h>
+
+#include <CoreFoundation/CoreFoundation.h>
+
+QT_BEGIN_NAMESPACE
+
+typedef struct _NSModalSession *NSModalSession;
+typedef struct _QCocoaModalSessionInfo {
+ QPointer<QWindow> window;
+ NSModalSession session;
+ void *nswindow;
+} QCocoaModalSessionInfo;
+
+class QCocoaEventDispatcherPrivate;
+class QCocoaEventDispatcher : public QEventDispatcherUNIX
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QCocoaEventDispatcher)
+
+public:
+ QCocoaEventDispatcher(QAbstractEventDispatcherPrivate &priv, QObject *parent = 0);
+ explicit QCocoaEventDispatcher(QObject *parent = 0);
+ ~QCocoaEventDispatcher();
+
+
+ bool processEvents(QEventLoop::ProcessEventsFlags flags);
+ bool hasPendingEvents();
+
+ void registerSocketNotifier(QSocketNotifier *notifier);
+ void unregisterSocketNotifier(QSocketNotifier *notifier);
+
+ void registerTimer(int timerId, int interval, QObject *object);
+ bool unregisterTimer(int timerId);
+ bool unregisterTimers(QObject *object);
+ QList<TimerInfo> registeredTimers(QObject *object) const;
+
+ void wakeUp();
+ void interrupt();
+
+private:
+ //friend void qt_mac_select_timer_callbk(__EventLoopTimer*, void*);
+ friend class QApplicationPrivate;
+};
+
+struct MacTimerInfo {
+ int id;
+ int interval;
+ QObject *obj;
+ bool pending;
+ CFRunLoopTimerRef runLoopTimer;
+ bool operator==(const MacTimerInfo &other)
+ {
+ return (id == other.id);
+ }
+};
+typedef QHash<int, MacTimerInfo *> MacTimerHash;
+
+struct MacSocketInfo {
+ MacSocketInfo() : socket(0), runloop(0), readNotifier(0), writeNotifier(0) {}
+ CFSocketRef socket;
+ CFRunLoopSourceRef runloop;
+ QObject *readNotifier;
+ QObject *writeNotifier;
+};
+typedef QHash<int, MacSocketInfo *> MacSocketHash;
+
+class QCocoaEventDispatcherPrivate : public QEventDispatcherUNIXPrivate
+{
+ Q_DECLARE_PUBLIC(QCocoaEventDispatcher)
+
+public:
+ QCocoaEventDispatcherPrivate();
+
+ static MacTimerHash macTimerHash;
+ // Set 'blockSendPostedEvents' to true if you _really_ need
+ // to make sure that qt events are not posted while calling
+ // low-level cocoa functions (like beginModalForWindow). And
+ // use a QBoolBlocker to be safe:
+ static bool blockSendPostedEvents;
+ // The following variables help organizing modal sessions:
+ static QStack<QCocoaModalSessionInfo> cocoaModalSessionStack;
+ static bool currentExecIsNSAppRun;
+ static bool nsAppRunCalledByQt;
+ static bool cleanupModalSessionsNeeded;
+ static NSModalSession currentModalSessionCached;
+ static NSModalSession currentModalSession();
+ static void updateChildrenWorksWhenModal();
+ static void temporarilyStopAllModalSessions();
+ static void beginModalSession(QWindow *widget);
+ static void endModalSession(QWindow *widget);
+ static void cancelWaitForMoreEvents();
+ static void cleanupModalSessions();
+ static void ensureNSAppInitialized();
+
+ MacSocketHash macSockets;
+ QList<void *> queuedUserInputEvents; // NSEvent *
+ CFRunLoopSourceRef postedEventsSource;
+ CFRunLoopObserverRef waitingObserver;
+ CFRunLoopObserverRef firstTimeObserver;
+ QAtomicInt serialNumber;
+ int lastSerial;
+ static bool interrupt;
+private:
+ static Boolean postedEventSourceEqualCallback(const void *info1, const void *info2);
+ static void postedEventsSourcePerformCallback(void *info);
+ static void activateTimer(CFRunLoopTimerRef, void *info);
+ static void waitingObserverCallback(CFRunLoopObserverRef observer,
+ CFRunLoopActivity activity, void *info);
+ static void firstLoopEntry(CFRunLoopObserverRef ref, CFRunLoopActivity activity, void *info);
+ friend void processPostedEvents(QCocoaEventDispatcherPrivate *const d, const bool blockSendPostedEvents);
+};
+
+class QtCocoaInterruptDispatcher : public QObject
+{
+ static QtCocoaInterruptDispatcher *instance;
+ bool cancelled;
+
+ QtCocoaInterruptDispatcher();
+ ~QtCocoaInterruptDispatcher();
+
+ public:
+ static void interruptLater();
+ static void cancelInterruptLater();
+};
+
+QT_END_NAMESPACE
+
+#endif // QEVENTDISPATCHER_MAC_P_H
diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
new file mode 100644
index 0000000000..9525b47c65
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
@@ -0,0 +1,1123 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/****************************************************************************
+**
+** Copyright (c) 2007-2008, Apple, Inc.
+**
+** All rights reserved.
+**
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are met:
+**
+** * Redistributions of source code must retain the above copyright notice,
+** this list of conditions and the following disclaimer.
+**
+** * Redistributions in binary form must reproduce the above copyright notice,
+** this list of conditions and the following disclaimer in the documentation
+** and/or other materials provided with the distribution.
+**
+** * Neither the name of Apple, Inc. nor the names of its contributors
+** may be used to endorse or promote products derived from this software
+** without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+**
+****************************************************************************/
+
+#include "qcocoaeventdispatcher.h"
+#include "qcocoaautoreleasepool.h"
+
+#include "qguiapplication.h"
+#include "qevent.h"
+#include "qhash.h"
+#include "qmutex.h"
+#include "qsocketnotifier.h"
+#include <qplatformwindow_qpa.h>
+#include "private/qthread_p.h"
+#include "private/qguiapplication_p.h"
+#include <qdebug.h>
+
+#undef slots
+#include <Cocoa/Cocoa.h>
+#include <Carbon/Carbon.h>
+
+QT_BEGIN_NAMESPACE
+
+QT_USE_NAMESPACE
+
+enum {
+ QtCocoaEventSubTypeWakeup = SHRT_MAX,
+ QtCocoaEventSubTypePostMessage = SHRT_MAX-1
+};
+
+static inline CFRunLoopRef mainRunLoop()
+{
+ return CFRunLoopGetMain();
+}
+
+/*****************************************************************************
+ Timers stuff
+ *****************************************************************************/
+
+/* timer call back */
+void QCocoaEventDispatcherPrivate::activateTimer(CFRunLoopTimerRef, void *info)
+{
+ int timerID =
+#ifdef Q_OS_MAC64
+ qint64(info);
+#else
+ int(info);
+#endif
+
+ MacTimerInfo *tmr;
+ tmr = macTimerHash.value(timerID);
+ if (tmr == 0 || tmr->pending == true)
+ return; // Can't send another timer event if it's pending.
+
+
+ if (blockSendPostedEvents) {
+ QCoreApplication::postEvent(tmr->obj, new QTimerEvent(tmr->id));
+ } else {
+ tmr->pending = true;
+ QTimerEvent e(tmr->id);
+
+ QCoreApplication::sendSpontaneousEvent(tmr->obj, &e);
+ // Get the value again in case the timer gets unregistered during the sendEvent.
+ tmr = macTimerHash.value(timerID);
+ if (tmr != 0)
+ tmr->pending = false;
+ }
+
+}
+
+void QCocoaEventDispatcher::registerTimer(int timerId, int interval, QObject *obj)
+{
+#ifndef QT_NO_DEBUG
+ if (timerId < 1 || interval < 0 || !obj) {
+ qWarning("QEventDispatcherMac::registerTimer: invalid arguments");
+ return;
+ } else if (obj->thread() != thread() || thread() != QThread::currentThread()) {
+ qWarning("QObject::startTimer: timers cannot be started from another thread");
+ return;
+ }
+#endif
+
+ MacTimerInfo *t = new MacTimerInfo();
+ t->id = timerId;
+ t->interval = interval;
+ t->obj = obj;
+ t->runLoopTimer = 0;
+ t->pending = false;
+
+ CFAbsoluteTime fireDate = CFAbsoluteTimeGetCurrent();
+ CFTimeInterval cfinterval = qMax(CFTimeInterval(interval) / 1000, 0.0000001);
+ fireDate += cfinterval;
+ QCocoaEventDispatcherPrivate::macTimerHash.insert(timerId, t);
+ CFRunLoopTimerContext info = { 0, (void *)timerId, 0, 0, 0 };
+ t->runLoopTimer = CFRunLoopTimerCreate(0, fireDate, cfinterval, 0, 0,
+ QCocoaEventDispatcherPrivate::activateTimer, &info);
+ if (t->runLoopTimer == 0) {
+ qFatal("QEventDispatcherMac::registerTimer: Cannot create timer");
+ }
+ CFRunLoopAddTimer(mainRunLoop(), t->runLoopTimer, kCFRunLoopCommonModes);
+}
+
+bool QCocoaEventDispatcher::unregisterTimer(int identifier)
+{
+#ifndef QT_NO_DEBUG
+ if (identifier < 1) {
+ qWarning("QEventDispatcherMac::unregisterTimer: invalid argument");
+ return false;
+ } else if (thread() != QThread::currentThread()) {
+ qWarning("QObject::killTimer: timers cannot be stopped from another thread");
+ return false;
+ }
+#endif
+ if (identifier <= 0)
+ return false; // not init'd or invalid timer
+
+ MacTimerInfo *timerInfo = QCocoaEventDispatcherPrivate::macTimerHash.take(identifier);
+ if (timerInfo == 0)
+ return false;
+
+ if (!QObjectPrivate::get(timerInfo->obj)->inThreadChangeEvent)
+ QAbstractEventDispatcherPrivate::releaseTimerId(identifier);
+ CFRunLoopTimerInvalidate(timerInfo->runLoopTimer);
+ CFRelease(timerInfo->runLoopTimer);
+ delete timerInfo;
+
+ return true;
+}
+
+bool QCocoaEventDispatcher::unregisterTimers(QObject *obj)
+{
+#ifndef QT_NO_DEBUG
+ if (!obj) {
+ qWarning("QEventDispatcherMac::unregisterTimers: invalid argument");
+ return false;
+ } else if (obj->thread() != thread() || thread() != QThread::currentThread()) {
+ qWarning("QObject::killTimers: timers cannot be stopped from another thread");
+ return false;
+ }
+#endif
+
+ MacTimerHash::iterator it = QCocoaEventDispatcherPrivate::macTimerHash.begin();
+ while (it != QCocoaEventDispatcherPrivate::macTimerHash.end()) {
+ MacTimerInfo *timerInfo = it.value();
+ if (timerInfo->obj != obj) {
+ ++it;
+ } else {
+ if (!QObjectPrivate::get(timerInfo->obj)->inThreadChangeEvent)
+ QAbstractEventDispatcherPrivate::releaseTimerId(timerInfo->id);
+ CFRunLoopTimerInvalidate(timerInfo->runLoopTimer);
+ CFRelease(timerInfo->runLoopTimer);
+ delete timerInfo;
+ it = QCocoaEventDispatcherPrivate::macTimerHash.erase(it);
+ }
+ }
+ return true;
+}
+
+QList<QCocoaEventDispatcher::TimerInfo>
+QCocoaEventDispatcher::registeredTimers(QObject *object) const
+{
+ if (!object) {
+ qWarning("QEventDispatcherMac:registeredTimers: invalid argument");
+ return QList<TimerInfo>();
+ }
+
+ QList<TimerInfo> list;
+
+ MacTimerHash::const_iterator it = QCocoaEventDispatcherPrivate::macTimerHash.constBegin();
+ while (it != QCocoaEventDispatcherPrivate::macTimerHash.constEnd()) {
+ MacTimerInfo *t = it.value();
+ if (t->obj == object)
+ list << TimerInfo(t->id, t->interval);
+ ++it;
+ }
+ return list;
+}
+
+/**************************************************************************
+ Socket Notifiers
+ *************************************************************************/
+void qt_mac_socket_callback(CFSocketRef s, CFSocketCallBackType callbackType, CFDataRef,
+ const void *, void *info) {
+ QCocoaEventDispatcherPrivate *const eventDispatcher
+ = static_cast<QCocoaEventDispatcherPrivate *>(info);
+ int nativeSocket = CFSocketGetNative(s);
+ MacSocketInfo *socketInfo = eventDispatcher->macSockets.value(nativeSocket);
+ QEvent notifierEvent(QEvent::SockAct);
+
+ // There is a race condition that happen where we disable the notifier and
+ // the kernel still has a notification to pass on. We then get this
+ // notification after we've successfully disabled the CFSocket, but our Qt
+ // notifier is now gone. The upshot is we have to check the notifier
+ // everytime.
+ if (callbackType == kCFSocketReadCallBack) {
+ if (socketInfo->readNotifier)
+ QGuiApplication::sendEvent(socketInfo->readNotifier, &notifierEvent);
+ } else if (callbackType == kCFSocketWriteCallBack) {
+ if (socketInfo->writeNotifier)
+ QGuiApplication::sendEvent(socketInfo->writeNotifier, &notifierEvent);
+ }
+}
+
+/*
+ Adds a loop source for the given socket to the current run loop.
+*/
+CFRunLoopSourceRef qt_mac_add_socket_to_runloop(const CFSocketRef socket)
+{
+ CFRunLoopSourceRef loopSource = CFSocketCreateRunLoopSource(kCFAllocatorDefault, socket, 0);
+ if (!loopSource)
+ return 0;
+
+ CFRunLoopAddSource(mainRunLoop(), loopSource, kCFRunLoopCommonModes);
+ return loopSource;
+}
+
+/*
+ Removes the loop source for the given socket from the current run loop.
+*/
+void qt_mac_remove_socket_from_runloop(const CFSocketRef socket, CFRunLoopSourceRef runloop)
+{
+ Q_ASSERT(runloop);
+ CFRunLoopRemoveSource(mainRunLoop(), runloop, kCFRunLoopCommonModes);
+ CFSocketDisableCallBacks(socket, kCFSocketReadCallBack);
+ CFSocketDisableCallBacks(socket, kCFSocketWriteCallBack);
+ CFRunLoopSourceInvalidate(runloop);
+}
+
+/*
+ Register a QSocketNotifier with the mac event system by creating a CFSocket with
+ with a read/write callback.
+
+ Qt has separate socket notifiers for reading and writing, but on the mac there is
+ a limitation of one CFSocket object for each native socket.
+*/
+void QCocoaEventDispatcher::registerSocketNotifier(QSocketNotifier *notifier)
+{
+ Q_ASSERT(notifier);
+ int nativeSocket = notifier->socket();
+ int type = notifier->type();
+#ifndef QT_NO_DEBUG
+ if (nativeSocket < 0 || nativeSocket > FD_SETSIZE) {
+ qWarning("QSocketNotifier: Internal error");
+ return;
+ } else if (notifier->thread() != thread()
+ || thread() != QThread::currentThread()) {
+ qWarning("QSocketNotifier: socket notifiers cannot be enabled from another thread");
+ return;
+ }
+#endif
+
+ Q_D(QCocoaEventDispatcher);
+
+ if (type == QSocketNotifier::Exception) {
+ qWarning("QSocketNotifier::Exception is not supported on Mac OS X");
+ return;
+ }
+
+ // Check if we have a CFSocket for the native socket, create one if not.
+ MacSocketInfo *socketInfo = d->macSockets.value(nativeSocket);
+ if (!socketInfo) {
+ socketInfo = new MacSocketInfo();
+
+ // Create CFSocket, specify that we want both read and write callbacks (the callbacks
+ // are enabled/disabled later on).
+ const int callbackTypes = kCFSocketReadCallBack | kCFSocketWriteCallBack;
+ CFSocketContext context = {0, d, 0, 0, 0};
+ socketInfo->socket = CFSocketCreateWithNative(kCFAllocatorDefault, nativeSocket, callbackTypes, qt_mac_socket_callback, &context);
+ if (CFSocketIsValid(socketInfo->socket) == false) {
+ qWarning("QEventDispatcherMac::registerSocketNotifier: Failed to create CFSocket");
+ return;
+ }
+
+ CFOptionFlags flags = CFSocketGetSocketFlags(socketInfo->socket);
+ flags |= kCFSocketAutomaticallyReenableWriteCallBack; //QSocketNotifier stays enabled after a write
+ flags &= ~kCFSocketCloseOnInvalidate; //QSocketNotifier doesn't close the socket upon destruction/invalidation
+ CFSocketSetSocketFlags(socketInfo->socket, flags);
+
+ // Add CFSocket to runloop.
+ if(!(socketInfo->runloop = qt_mac_add_socket_to_runloop(socketInfo->socket))) {
+ qWarning("QEventDispatcherMac::registerSocketNotifier: Failed to add CFSocket to runloop");
+ CFSocketInvalidate(socketInfo->socket);
+ CFRelease(socketInfo->socket);
+ return;
+ }
+
+ // Disable both callback types by default. This must be done after
+ // we add the CFSocket to the runloop, or else these calls will have
+ // no effect.
+ CFSocketDisableCallBacks(socketInfo->socket, kCFSocketReadCallBack);
+ CFSocketDisableCallBacks(socketInfo->socket, kCFSocketWriteCallBack);
+
+ d->macSockets.insert(nativeSocket, socketInfo);
+ }
+
+ // Increment read/write counters and select enable callbacks if necessary.
+ if (type == QSocketNotifier::Read) {
+ Q_ASSERT(socketInfo->readNotifier == 0);
+ socketInfo->readNotifier = notifier;
+ CFSocketEnableCallBacks(socketInfo->socket, kCFSocketReadCallBack);
+ } else if (type == QSocketNotifier::Write) {
+ Q_ASSERT(socketInfo->writeNotifier == 0);
+ socketInfo->writeNotifier = notifier;
+ CFSocketEnableCallBacks(socketInfo->socket, kCFSocketWriteCallBack);
+ }
+}
+
+/*
+ Unregister QSocketNotifer. The CFSocket correspoding to this notifier is
+ removed from the runloop of this is the last notifier that users
+ that CFSocket.
+*/
+void QCocoaEventDispatcher::unregisterSocketNotifier(QSocketNotifier *notifier)
+{
+ Q_ASSERT(notifier);
+ int nativeSocket = notifier->socket();
+ int type = notifier->type();
+#ifndef QT_NO_DEBUG
+ if (nativeSocket < 0 || nativeSocket > FD_SETSIZE) {
+ qWarning("QSocketNotifier: Internal error");
+ return;
+ } else if (notifier->thread() != thread() || thread() != QThread::currentThread()) {
+ qWarning("QSocketNotifier: socket notifiers cannot be disabled from another thread");
+ return;
+ }
+#endif
+
+ Q_D(QCocoaEventDispatcher);
+
+ if (type == QSocketNotifier::Exception) {
+ qWarning("QSocketNotifier::Exception is not supported on Mac OS X");
+ return;
+ }
+ MacSocketInfo *socketInfo = d->macSockets.value(nativeSocket);
+ if (!socketInfo) {
+ qWarning("QEventDispatcherMac::unregisterSocketNotifier: Tried to unregister a not registered notifier");
+ return;
+ }
+
+ // Decrement read/write counters and disable callbacks if necessary.
+ if (type == QSocketNotifier::Read) {
+ Q_ASSERT(notifier == socketInfo->readNotifier);
+ socketInfo->readNotifier = 0;
+ CFSocketDisableCallBacks(socketInfo->socket, kCFSocketReadCallBack);
+ } else if (type == QSocketNotifier::Write) {
+ Q_ASSERT(notifier == socketInfo->writeNotifier);
+ socketInfo->writeNotifier = 0;
+ CFSocketDisableCallBacks(socketInfo->socket, kCFSocketWriteCallBack);
+ }
+
+ // Remove CFSocket from runloop if this was the last QSocketNotifier.
+ if (socketInfo->readNotifier == 0 && socketInfo->writeNotifier == 0) {
+ if (CFSocketIsValid(socketInfo->socket))
+ qt_mac_remove_socket_from_runloop(socketInfo->socket, socketInfo->runloop);
+ CFRunLoopSourceInvalidate(socketInfo->runloop);
+ CFRelease(socketInfo->runloop);
+ CFSocketInvalidate(socketInfo->socket);
+ CFRelease(socketInfo->socket);
+ delete socketInfo;
+ d->macSockets.remove(nativeSocket);
+ }
+}
+
+bool QCocoaEventDispatcher::hasPendingEvents()
+{
+ extern uint qGlobalPostedEventsCount();
+ extern bool qt_is_gui_used; //qapplication.cpp
+ return qGlobalPostedEventsCount() || (qt_is_gui_used && GetNumEventsInQueue(GetMainEventQueue()));
+}
+
+static bool IsMouseOrKeyEvent( NSEvent* event )
+{
+ bool result = false;
+
+ switch( [event type] )
+ {
+ case NSLeftMouseDown:
+ case NSLeftMouseUp:
+ case NSRightMouseDown:
+ case NSRightMouseUp:
+ case NSMouseMoved: // ??
+ case NSLeftMouseDragged:
+ case NSRightMouseDragged:
+ case NSMouseEntered:
+ case NSMouseExited:
+ case NSKeyDown:
+ case NSKeyUp:
+ case NSFlagsChanged: // key modifiers changed?
+ case NSCursorUpdate: // ??
+ case NSScrollWheel:
+ case NSTabletPoint:
+ case NSTabletProximity:
+ case NSOtherMouseDown:
+ case NSOtherMouseUp:
+ case NSOtherMouseDragged:
+#ifndef QT_NO_GESTURES
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
+ case NSEventTypeGesture: // touch events
+ case NSEventTypeMagnify:
+ case NSEventTypeSwipe:
+ case NSEventTypeRotate:
+ case NSEventTypeBeginGesture:
+ case NSEventTypeEndGesture:
+#endif
+#endif // QT_NO_GESTURES
+ result = true;
+ break;
+
+ default:
+ break;
+ }
+ return result;
+}
+
+static inline void qt_mac_waitForMoreEvents()
+{
+ // If no event exist in the cocoa event que, wait
+ // (and free up cpu time) until at least one event occur.
+ // This implementation is a bit on the edge, but seems to
+ // work fine:
+ NSEvent* event = [NSApp nextEventMatchingMask:NSAnyEventMask
+ untilDate:[NSDate distantFuture]
+ inMode:NSDefaultRunLoopMode
+ dequeue:YES];
+ if (event)
+ [NSApp postEvent:event atStart:YES];
+}
+
+static inline void qt_mac_waitForMoreModalSessionEvents()
+{
+ // If no event exist in the cocoa event que, wait
+ // (and free up cpu time) until at least one event occur.
+ // This implementation is a bit on the edge, but seems to
+ // work fine:
+ NSEvent* event = [NSApp nextEventMatchingMask:NSAnyEventMask
+ untilDate:[NSDate distantFuture]
+ inMode:NSModalPanelRunLoopMode
+ dequeue:YES];
+ if (event)
+ [NSApp postEvent:event atStart:YES];
+}
+
+bool QCocoaEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags)
+{
+ Q_D(QCocoaEventDispatcher);
+ d->interrupt = false;
+
+ bool interruptLater = false;
+ QtCocoaInterruptDispatcher::cancelInterruptLater();
+
+ // In case we end up recursing while we now process events, make sure
+ // that we send remaining posted Qt events before this call returns:
+ wakeUp();
+ emit awake();
+
+ bool excludeUserEvents = flags & QEventLoop::ExcludeUserInputEvents;
+ bool retVal = false;
+ forever {
+ if (d->interrupt)
+ break;
+
+ QCocoaAutoReleasePool pool;
+ NSEvent* event = 0;
+
+ // First, send all previously excluded input events, if any:
+ if (!excludeUserEvents) {
+ while (!d->queuedUserInputEvents.isEmpty()) {
+ event = static_cast<NSEvent *>(d->queuedUserInputEvents.takeFirst());
+ if (!filterEvent(event)) {
+ [NSApp sendEvent:event];
+ retVal = true;
+ }
+ [event release];
+ }
+ }
+
+ // If Qt is used as a plugin, or as an extension in a native cocoa
+ // application, we should not run or stop NSApplication; This will be
+ // done from the application itself. And if processEvents is called
+ // manually (rather than from a QEventLoop), we cannot enter a tight
+ // loop and block this call, but instead we need to return after one flush.
+ // Finally, if we are to exclude user input events, we cannot call [NSApp run]
+ // as we then loose control over which events gets dispatched:
+ const bool canExec_3rdParty = d->nsAppRunCalledByQt || ![NSApp isRunning];
+ const bool canExec_Qt = !excludeUserEvents &&
+ (flags & QEventLoop::DialogExec || flags & QEventLoop::EventLoopExec) ;
+
+ if (canExec_Qt && canExec_3rdParty) {
+ // We can use exec-mode, meaning that we can stay in a tight loop until
+ // interrupted. This is mostly an optimization, but it allow us to use
+ // [NSApp run], which is the normal code path for cocoa applications.
+ if (NSModalSession session = d->currentModalSession()) {
+ QBoolBlocker execGuard(d->currentExecIsNSAppRun, false);
+ while ([NSApp runModalSession:session] == NSRunContinuesResponse && !d->interrupt)
+ qt_mac_waitForMoreModalSessionEvents();
+
+ if (!d->interrupt && session == d->currentModalSessionCached) {
+ // Someone called [NSApp stopModal:] from outside the event
+ // dispatcher (e.g to stop a native dialog). But that call wrongly stopped
+ // 'session' as well. As a result, we need to restart all internal sessions:
+ d->temporarilyStopAllModalSessions();
+ }
+ } else {
+ d->nsAppRunCalledByQt = true;
+ QBoolBlocker execGuard(d->currentExecIsNSAppRun, true);
+ [NSApp run];
+ }
+ retVal = true;
+ } else {
+ // We cannot block the thread (and run in a tight loop).
+ // Instead we will process all current pending events and return.
+ d->ensureNSAppInitialized();
+ if (NSModalSession session = d->currentModalSession()) {
+ // INVARIANT: a modal window is executing.
+ if (!excludeUserEvents) {
+ // Since we can dispatch all kinds of events, we choose
+ // to use cocoa's native way of running modal sessions:
+ if (flags & QEventLoop::WaitForMoreEvents)
+ qt_mac_waitForMoreModalSessionEvents();
+ NSInteger status = [NSApp runModalSession:session];
+ if (status != NSRunContinuesResponse && session == d->currentModalSessionCached) {
+ // INVARIANT: Someone called [NSApp stopModal:] from outside the event
+ // dispatcher (e.g to stop a native dialog). But that call wrongly stopped
+ // 'session' as well. As a result, we need to restart all internal sessions:
+ d->temporarilyStopAllModalSessions();
+ }
+ retVal = true;
+ } else do {
+ // Dispatch all non-user events (but que non-user events up for later). In
+ // this case, we need more control over which events gets dispatched, and
+ // cannot use [NSApp runModalSession:session]:
+ event = [NSApp nextEventMatchingMask:NSAnyEventMask
+ untilDate:nil
+ inMode:NSModalPanelRunLoopMode
+ dequeue: YES];
+
+ if (event) {
+ if (IsMouseOrKeyEvent(event)) {
+ [event retain];
+ d->queuedUserInputEvents.append(event);
+ continue;
+ }
+ if (!filterEvent(event)) {
+ [NSApp sendEvent:event];
+ retVal = true;
+ }
+ }
+ } while (!d->interrupt && event != nil);
+ } else do {
+ // INVARIANT: No modal window is executing.
+ event = [NSApp nextEventMatchingMask:NSAnyEventMask
+ untilDate:nil
+ inMode:NSDefaultRunLoopMode
+ dequeue: YES];
+
+ if (event) {
+ if (flags & QEventLoop::ExcludeUserInputEvents) {
+ if (IsMouseOrKeyEvent(event)) {
+ [event retain];
+ d->queuedUserInputEvents.append(event);
+ continue;
+ }
+ }
+ if (!filterEvent(event)) {
+ [NSApp sendEvent:event];
+ retVal = true;
+ }
+ }
+ } while (!d->interrupt && event != nil);
+
+ // Be sure to flush the Qt posted events when not using exec mode
+ // (exec mode will always do this call from the event loop source):
+ if (!d->interrupt)
+ QCoreApplicationPrivate::sendPostedEvents(0, 0, d->threadData);
+
+ // Since the window that holds modality might have changed while processing
+ // events, we we need to interrupt when we return back the previous process
+ // event recursion to ensure that we spin the correct modal session.
+ // We do the interruptLater at the end of the function to ensure that we don't
+ // disturb the 'wait for more events' below (as deleteLater will post an event):
+ interruptLater = true;
+ }
+ bool canWait = (d->threadData->canWait
+ && !retVal
+ && !d->interrupt
+ && (flags & QEventLoop::WaitForMoreEvents));
+ if (canWait) {
+ // INVARIANT: We haven't processed any events yet. And we're told
+ // to stay inside this function until at least one event is processed.
+ qt_mac_waitForMoreEvents();
+ flags &= ~QEventLoop::WaitForMoreEvents;
+ } else {
+ // Done with event processing for now.
+ // Leave the function:
+ break;
+ }
+ }
+
+ // If we're interrupted, we need to interrupt the _current_
+ // recursion as well to check if it is still supposed to be
+ // executing. This way we wind down the stack until we land
+ // on a recursion that again calls processEvents (typically
+ // from QEventLoop), and set interrupt to false:
+ if (d->interrupt)
+ interrupt();
+
+ if (interruptLater)
+ QtCocoaInterruptDispatcher::interruptLater();
+
+ return retVal;
+}
+
+void QCocoaEventDispatcher::wakeUp()
+{
+ Q_D(QCocoaEventDispatcher);
+ d->serialNumber.ref();
+ CFRunLoopSourceSignal(d->postedEventsSource);
+ CFRunLoopWakeUp(mainRunLoop());
+}
+
+/*****************************************************************************
+ QEventDispatcherMac Implementation
+ *****************************************************************************/
+MacTimerHash QCocoaEventDispatcherPrivate::macTimerHash;
+bool QCocoaEventDispatcherPrivate::blockSendPostedEvents = false;
+bool QCocoaEventDispatcherPrivate::interrupt = false;
+
+
+QStack<QCocoaModalSessionInfo> QCocoaEventDispatcherPrivate::cocoaModalSessionStack;
+bool QCocoaEventDispatcherPrivate::currentExecIsNSAppRun = false;
+bool QCocoaEventDispatcherPrivate::nsAppRunCalledByQt = false;
+bool QCocoaEventDispatcherPrivate::cleanupModalSessionsNeeded = false;
+NSModalSession QCocoaEventDispatcherPrivate::currentModalSessionCached = 0;
+
+void QCocoaEventDispatcherPrivate::ensureNSAppInitialized()
+{
+ // Some elements in Cocoa require NSApplication to be running before
+ // they get fully initialized, in particular the menu bar. This
+ // function is intended for cases where a dialog is told to execute before
+ // QGuiApplication::exec is called, or the application spins the events loop
+ // manually rather than calling QGuiApplication:exec.
+ // The function makes sure that NSApplication starts running, but stops
+ // it again as soon as the send posted events callback is called. That way
+ // we let Cocoa finish the initialization it seems to need. We'll only
+ // apply this trick at most once for any application, and we avoid doing it
+ // for the common case where main just starts QGuiApplication::exec.
+ if (nsAppRunCalledByQt || [NSApp isRunning])
+ return;
+ nsAppRunCalledByQt = true;
+ QBoolBlocker block1(interrupt, true);
+ QBoolBlocker block2(currentExecIsNSAppRun, true);
+ [NSApp run];
+}
+
+void QCocoaEventDispatcherPrivate::temporarilyStopAllModalSessions()
+{
+ // Flush, and Stop, all created modal session, and as
+ // such, make them pending again. The next call to
+ // currentModalSession will recreate them again. The
+ // reason to stop all session like this is that otherwise
+ // a call [NSApp stop] would not stop NSApp, but rather
+ // the current modal session. So if we need to stop NSApp
+ // we need to stop all the modal session first. To avoid changing
+ // the stacking order of the windows while doing so, we put
+ // up a block that is used in QCocoaWindow and QCocoaPanel:
+ int stackSize = cocoaModalSessionStack.size();
+ for (int i=0; i<stackSize; ++i) {
+ QCocoaModalSessionInfo &info = cocoaModalSessionStack[i];
+ if (info.session) {
+ [NSApp endModalSession:info.session];
+ info.session = 0;
+ }
+ }
+ currentModalSessionCached = 0;
+}
+
+NSModalSession QCocoaEventDispatcherPrivate::currentModalSession()
+{
+ // If we have one or more modal windows, this function will create
+ // a session for each of those, and return the one for the top.
+ if (currentModalSessionCached)
+ return currentModalSessionCached;
+
+ if (cocoaModalSessionStack.isEmpty())
+ return 0;
+
+ int sessionCount = cocoaModalSessionStack.size();
+ for (int i=0; i<sessionCount; ++i) {
+ QCocoaModalSessionInfo &info = cocoaModalSessionStack[i];
+ if (!info.window)
+ continue;
+// ### port
+// if (info.window->testAttribute(Qt::WA_DontShowOnScreen))
+// continue;
+
+ if (!info.session) {
+ QCocoaAutoReleasePool pool;
+ NSWindow *window = reinterpret_cast<NSWindow *>(info.window->handle()->winId());
+ if (!window)
+ continue;
+
+ ensureNSAppInitialized();
+ QBoolBlocker block1(blockSendPostedEvents, true);
+ info.nswindow = window;
+ [(NSWindow*) info.nswindow retain];
+ int levelBeforeEnterModal = [window level];
+ info.session = [NSApp beginModalSessionForWindow:window];
+ // Make sure we don't stack the window lower that it was before
+ // entering modal, in case it e.g. had the stays-on-top flag set:
+ if (levelBeforeEnterModal > [window level])
+ [window setLevel:levelBeforeEnterModal];
+ }
+ currentModalSessionCached = info.session;
+ cleanupModalSessionsNeeded = false;
+ }
+ return currentModalSessionCached;
+}
+
+static void setChildrenWorksWhenModal(QWindow *window, bool worksWhenModal)
+{
+ // For NSPanels (but not NSWindows, sadly), we can set the flag
+ // worksWhenModal, so that they are active even when they are not modal.
+/*
+ ### not ported
+ QList<QDialog *> dialogs = window->findChildren<QDialog *>();
+ for (int i=0; i<dialogs.size(); ++i){
+ NSWindow *window = qt_mac_window_for(dialogs[i]);
+ if (window && [window isKindOfClass:[NSPanel class]]) {
+ [static_cast<NSPanel *>(window) setWorksWhenModal:worksWhenModal];
+ if (worksWhenModal && [window isVisible]){
+ [window orderFront:window];
+ }
+ }
+ }
+*/
+}
+
+void QCocoaEventDispatcherPrivate::updateChildrenWorksWhenModal()
+{
+ // Make the dialog children of the window
+ // active. And make the dialog children of
+ // the previous modal dialog unactive again:
+ QCocoaAutoReleasePool pool;
+ int size = cocoaModalSessionStack.size();
+ if (size > 0){
+ if (QWindow *prevModal = cocoaModalSessionStack[size-1].window)
+ setChildrenWorksWhenModal(prevModal, true);
+ if (size > 1){
+ if (QWindow *prevModal = cocoaModalSessionStack[size-2].window)
+ setChildrenWorksWhenModal(prevModal, false);
+ }
+ }
+}
+
+void QCocoaEventDispatcherPrivate::cleanupModalSessions()
+{
+ // Go through the list of modal sessions, and end those
+ // that no longer has a window assosiated; no window means
+ // the the session has logically ended. The reason we wait like
+ // this to actually end the sessions for real (rather than at the
+ // point they were marked as stopped), is that ending a session
+ // when no other session runs below it on the stack will make cocoa
+ // drop some events on the floor.
+ QCocoaAutoReleasePool pool;
+ int stackSize = cocoaModalSessionStack.size();
+
+ for (int i=stackSize-1; i>=0; --i) {
+ QCocoaModalSessionInfo &info = cocoaModalSessionStack[i];
+ if (info.window) {
+ // This session has a window, and is therefore not marked
+ // as stopped. So just make it current. There might still be other
+ // stopped sessions on the stack, but those will be stopped on
+ // a later "cleanup" call.
+ currentModalSessionCached = info.session;
+ break;
+ }
+ cocoaModalSessionStack.remove(i);
+ currentModalSessionCached = 0;
+ if (info.session) {
+ [NSApp endModalSession:info.session];
+ [(NSWindow *)info.nswindow release];
+ }
+ }
+
+ updateChildrenWorksWhenModal();
+ cleanupModalSessionsNeeded = false;
+}
+
+void QCocoaEventDispatcherPrivate::beginModalSession(QWindow *window)
+{
+ // Add a new, empty (null), NSModalSession to the stack.
+ // It will become active the next time QEventDispatcher::processEvents is called.
+ // A QCocoaModalSessionInfo is considered pending to become active if the window pointer
+ // is non-zero, and the session pointer is zero (it will become active upon a call to
+ // currentModalSession). A QCocoaModalSessionInfo is considered pending to be stopped if
+ // the window pointer is zero, and the session pointer is non-zero (it will be fully
+ // stopped in cleanupModalSessions()).
+ QCocoaModalSessionInfo info = {window, 0, 0};
+ cocoaModalSessionStack.push(info);
+ updateChildrenWorksWhenModal();
+ currentModalSessionCached = 0;
+}
+
+void QCocoaEventDispatcherPrivate::endModalSession(QWindow *window)
+{
+ // Mark all sessions attached to window as pending to be stopped. We do this
+ // by setting the window pointer to zero, but leave the session pointer.
+ // We don't tell cocoa to stop any sessions just yet, because cocoa only understands
+ // when we stop the _current_ modal session (which is the session on top of
+ // the stack, and might not belong to 'window').
+ int stackSize = cocoaModalSessionStack.size();
+ for (int i=stackSize-1; i>=0; --i) {
+ QCocoaModalSessionInfo &info = cocoaModalSessionStack[i];
+ if (info.window == window) {
+ info.window = 0;
+ if (i == stackSize-1) {
+ // The top sessions ended. Interrupt the event dispatcher
+ // to start spinning the correct session immidiatly:
+ currentModalSessionCached = 0;
+ cleanupModalSessionsNeeded = true;
+ QCocoaEventDispatcher::instance()->interrupt();
+ }
+ }
+ }
+}
+
+QCocoaEventDispatcherPrivate::QCocoaEventDispatcherPrivate()
+{
+}
+
+QCocoaEventDispatcher::QCocoaEventDispatcher(QObject *parent)
+ : QEventDispatcherUNIX(*new QCocoaEventDispatcherPrivate, parent)
+{
+ Q_D(QCocoaEventDispatcher);
+ CFRunLoopSourceContext context;
+ bzero(&context, sizeof(CFRunLoopSourceContext));
+ context.info = d;
+ context.equal = QCocoaEventDispatcherPrivate::postedEventSourceEqualCallback;
+ context.perform = QCocoaEventDispatcherPrivate::postedEventsSourcePerformCallback;
+ d->postedEventsSource = CFRunLoopSourceCreate(0, 0, &context);
+ Q_ASSERT(d->postedEventsSource);
+ CFRunLoopAddSource(mainRunLoop(), d->postedEventsSource, kCFRunLoopCommonModes);
+
+ CFRunLoopObserverContext observerContext;
+ bzero(&observerContext, sizeof(CFRunLoopObserverContext));
+ observerContext.info = this;
+ d->waitingObserver = CFRunLoopObserverCreate(kCFAllocatorDefault,
+ kCFRunLoopBeforeWaiting | kCFRunLoopAfterWaiting,
+ true, 0,
+ QCocoaEventDispatcherPrivate::waitingObserverCallback,
+ &observerContext);
+ CFRunLoopAddObserver(mainRunLoop(), d->waitingObserver, kCFRunLoopCommonModes);
+
+ /* The first cycle in the loop adds the source and the events of the source
+ are not processed.
+ We use an observer to process the posted events for the first
+ execution of the loop. */
+ CFRunLoopObserverContext firstTimeObserverContext;
+ bzero(&firstTimeObserverContext, sizeof(CFRunLoopObserverContext));
+ firstTimeObserverContext.info = d;
+ d->firstTimeObserver = CFRunLoopObserverCreate(kCFAllocatorDefault,
+ kCFRunLoopEntry,
+ /* repeats = */ false,
+ 0,
+ QCocoaEventDispatcherPrivate::firstLoopEntry,
+ &firstTimeObserverContext);
+ CFRunLoopAddObserver(mainRunLoop(), d->firstTimeObserver, kCFRunLoopCommonModes);
+}
+
+void QCocoaEventDispatcherPrivate::waitingObserverCallback(CFRunLoopObserverRef,
+ CFRunLoopActivity activity, void *info)
+{
+ if (activity == kCFRunLoopBeforeWaiting)
+ emit static_cast<QCocoaEventDispatcher*>(info)->aboutToBlock();
+ else
+ emit static_cast<QCocoaEventDispatcher*>(info)->awake();
+}
+
+Boolean QCocoaEventDispatcherPrivate::postedEventSourceEqualCallback(const void *info1, const void *info2)
+{
+ return info1 == info2;
+}
+
+void processPostedEvents(QCocoaEventDispatcherPrivate *const d, const bool blockSendPostedEvents)
+{
+ if (blockSendPostedEvents) {
+ // We're told to not send posted events (because the event dispatcher
+ // is currently working on setting up the correct session to run). But
+ // we still need to make sure that we don't fall asleep until pending events
+ // are sendt, so we just signal this need, and return:
+ CFRunLoopSourceSignal(d->postedEventsSource);
+ return;
+ }
+
+ if (d->cleanupModalSessionsNeeded)
+ d->cleanupModalSessions();
+
+ if (d->interrupt) {
+ if (d->currentExecIsNSAppRun) {
+ // The event dispatcher has been interrupted. But since
+ // [NSApplication run] is running the event loop, we
+ // delayed stopping it until now (to let cocoa process
+ // pending cocoa events first).
+ if (d->currentModalSessionCached)
+ d->temporarilyStopAllModalSessions();
+ [NSApp stop:NSApp];
+ d->cancelWaitForMoreEvents();
+ }
+ return;
+ }
+
+ if (!d->threadData->canWait || (d->serialNumber != d->lastSerial)) {
+ d->lastSerial = d->serialNumber;
+ QWindowSystemInterface::sendWindowSystemEvents(d->q_func(), QEventLoop::AllEvents);
+ }
+}
+
+void QCocoaEventDispatcherPrivate::firstLoopEntry(CFRunLoopObserverRef ref,
+ CFRunLoopActivity activity,
+ void *info)
+{
+ Q_UNUSED(ref);
+ Q_UNUSED(activity);
+/*
+ // This function is called when NSApplication has finished initialization,
+ // which appears to be just after [NSApplication run] has started to execute.
+ // By setting up our apple events handlers this late, we override the ones
+ // set up by NSApplication.
+
+ // If Qt is used as a plugin, we let the 3rd party application handle events
+ // like quit and open file events. Otherwise, if we install our own handlers, we
+ // easily end up breaking functionallity the 3rd party application depend on:
+ if (QGuiApplication::testAttribute(Qt::AA_MacPluginApplication))
+ return;
+
+ QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) *newDelegate = [QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) sharedDelegate];
+ NSAppleEventManager *eventManager = [NSAppleEventManager sharedAppleEventManager];
+ [eventManager setEventHandler:newDelegate andSelector:@selector(appleEventQuit:withReplyEvent:)
+ forEventClass:kCoreEventClass andEventID:kAEQuitApplication];
+ [eventManager setEventHandler:newDelegate andSelector:@selector(getUrl:withReplyEvent:)
+ forEventClass:kInternetEventClass andEventID:kAEGetURL];
+*/
+
+ processPostedEvents(static_cast<QCocoaEventDispatcherPrivate *>(info), blockSendPostedEvents);
+}
+
+void QCocoaEventDispatcherPrivate::postedEventsSourcePerformCallback(void *info)
+{
+ processPostedEvents(static_cast<QCocoaEventDispatcherPrivate *>(info), blockSendPostedEvents);
+}
+
+void QCocoaEventDispatcherPrivate::cancelWaitForMoreEvents()
+{
+ // In case the event dispatcher is waiting for more
+ // events somewhere, we post a dummy event to wake it up:
+ QCocoaAutoReleasePool pool;
+ [NSApp postEvent:[NSEvent otherEventWithType:NSApplicationDefined location:NSZeroPoint
+ modifierFlags:0 timestamp:0. windowNumber:0 context:0
+ subtype:QtCocoaEventSubTypeWakeup data1:0 data2:0] atStart:NO];
+}
+
+void QCocoaEventDispatcher::interrupt()
+{
+ Q_D(QCocoaEventDispatcher);
+ d->interrupt = true;
+ wakeUp();
+
+ // We do nothing more here than setting d->interrupt = true, and
+ // poke the event loop if it is sleeping. Actually stopping
+ // NSApp, or the current modal session, is done inside the send
+ // posted events callback. We do this to ensure that all current pending
+ // cocoa events gets delivered before we stop. Otherwise, if we now stop
+ // the last event loop recursion, cocoa will just drop pending posted
+ // events on the floor before we get a chance to reestablish a new session.
+ d->cancelWaitForMoreEvents();
+}
+
+QCocoaEventDispatcher::~QCocoaEventDispatcher()
+{
+ Q_D(QCocoaEventDispatcher);
+ //timer cleanup
+ MacTimerHash::iterator it = QCocoaEventDispatcherPrivate::macTimerHash.begin();
+ while (it != QCocoaEventDispatcherPrivate::macTimerHash.end()) {
+ MacTimerInfo *t = it.value();
+ if (t->runLoopTimer) {
+ CFRunLoopTimerInvalidate(t->runLoopTimer);
+ CFRelease(t->runLoopTimer);
+ }
+ delete t;
+ ++it;
+ }
+ QCocoaEventDispatcherPrivate::macTimerHash.clear();
+
+ // Remove CFSockets from the runloop.
+ for (MacSocketHash::ConstIterator it = d->macSockets.constBegin(); it != d->macSockets.constEnd(); ++it) {
+ MacSocketInfo *socketInfo = (*it);
+ if (CFSocketIsValid(socketInfo->socket)) {
+ qt_mac_remove_socket_from_runloop(socketInfo->socket, socketInfo->runloop);
+ CFRunLoopSourceInvalidate(socketInfo->runloop);
+ CFRelease(socketInfo->runloop);
+ CFSocketInvalidate(socketInfo->socket);
+ CFRelease(socketInfo->socket);
+ }
+ }
+ CFRunLoopRemoveSource(mainRunLoop(), d->postedEventsSource, kCFRunLoopCommonModes);
+ CFRelease(d->postedEventsSource);
+
+ CFRunLoopObserverInvalidate(d->waitingObserver);
+ CFRelease(d->waitingObserver);
+
+ CFRunLoopObserverInvalidate(d->firstTimeObserver);
+ CFRelease(d->firstTimeObserver);
+}
+
+QtCocoaInterruptDispatcher* QtCocoaInterruptDispatcher::instance = 0;
+
+QtCocoaInterruptDispatcher::QtCocoaInterruptDispatcher() : cancelled(false)
+{
+ // The whole point of this class is that we enable a way to interrupt
+ // the event dispatcher when returning back to a lower recursion level
+ // than where interruptLater was called. This is needed to detect if
+ // [NSApp run] should still be running at the recursion level it is at.
+ // Since the interrupt is canceled if processEvents is called before
+ // this object gets deleted, we also avoid interrupting unnecessary.
+ deleteLater();
+}
+
+QtCocoaInterruptDispatcher::~QtCocoaInterruptDispatcher()
+{
+ if (cancelled)
+ return;
+ instance = 0;
+ QCocoaEventDispatcher::instance()->interrupt();
+}
+
+void QtCocoaInterruptDispatcher::cancelInterruptLater()
+{
+ if (!instance)
+ return;
+ instance->cancelled = true;
+ delete instance;
+ instance = 0;
+}
+
+void QtCocoaInterruptDispatcher::interruptLater()
+{
+ cancelInterruptLater();
+ instance = new QtCocoaInterruptDispatcher;
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/plugins/platforms/cocoa/qcocoaeventloopintegration.h b/src/plugins/platforms/cocoa/qcocoaeventloopintegration.h
deleted file mode 100644
index 5765483fc7..0000000000
--- a/src/plugins/platforms/cocoa/qcocoaeventloopintegration.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QCOCAEVENTLOOPINTEGRATION_H
-#define QCOCAEVENTLOOPINTEGRATION_H
-
-#include <Cocoa/Cocoa.h>
-
-#include <QPlatformEventLoopIntegration>
-
-
-class QCocoaEventLoopIntegration : public QPlatformEventLoopIntegration
-{
-public:
- QCocoaEventLoopIntegration();
- void startEventLoop();
- void quitEventLoop();
- void qtNeedsToProcessEvents();
-
-private:
- CFRunLoopSourceContext m_sourceContext;
- CFRunLoopTimerContext m_timerContext;
- CFRunLoopSourceRef m_source;
-};
-
-#endif // QCOCAEVENTLOOPINTEGRATION_H
-
diff --git a/src/plugins/platforms/cocoa/qcocoaeventloopintegration.mm b/src/plugins/platforms/cocoa/qcocoaeventloopintegration.mm
deleted file mode 100644
index ac0b75e9ea..0000000000
--- a/src/plugins/platforms/cocoa/qcocoaeventloopintegration.mm
+++ /dev/null
@@ -1,112 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qcocoaeventloopintegration.h"
-
-#import <Cocoa/Cocoa.h>
-
-#include "qcocoaautoreleasepool.h"
-
-#include <QtCore/QElapsedTimer>
-
-#include <QDebug>
-#include <QApplication>
-
-void wakeupCallback ( void * ) {
- QPlatformEventLoopIntegration::processEvents();
-}
-
-void timerCallback( CFRunLoopTimerRef timer, void *info)
-{
- QPlatformEventLoopIntegration::processEvents();
- QCocoaEventLoopIntegration *eventLoopIntegration =
- static_cast<QCocoaEventLoopIntegration *>(info);
- qint64 nextTime = eventLoopIntegration->nextTimerEvent();
- CFAbsoluteTime nexttime = CFAbsoluteTimeGetCurrent();
- nexttime = nexttime + (double(nextTime)/1000);
- CFRunLoopTimerSetNextFireDate(timer,nexttime);
-}
-
-QCocoaEventLoopIntegration::QCocoaEventLoopIntegration() :
- QPlatformEventLoopIntegration()
-{
- [NSApplication sharedApplication];
- m_sourceContext.version = 0;
- m_sourceContext.info = this;
- m_sourceContext.retain = 0;
- m_sourceContext.release = 0;
- m_sourceContext.copyDescription = 0;
- m_sourceContext.equal = 0;
- m_sourceContext.hash = 0;
- m_sourceContext.schedule = 0;
- m_sourceContext.cancel = 0;
- m_sourceContext.perform = wakeupCallback;
-
- m_source = CFRunLoopSourceCreate(0,0,&m_sourceContext);
- CFRunLoopAddSource(CFRunLoopGetMain(),m_source,kCFRunLoopCommonModes);
-
- m_timerContext.version = 0;
- m_timerContext.info = this;
- m_timerContext.retain = 0;
- m_timerContext.release = 0;
- m_timerContext.copyDescription = 0;
- CFAbsoluteTime fireDate = CFAbsoluteTimeGetCurrent ();
- CFTimeInterval interval = 30;
-
- CFRunLoopTimerRef m_timerSource = CFRunLoopTimerCreate(0,fireDate,interval,0,0,timerCallback,&m_timerContext);
- CFRunLoopAddTimer(CFRunLoopGetMain(),m_timerSource,kCFRunLoopCommonModes);
-}
-
-void QCocoaEventLoopIntegration::startEventLoop()
-{
- [[NSApplication sharedApplication] run];
-}
-
-void QCocoaEventLoopIntegration::quitEventLoop()
-{
- [[NSApplication sharedApplication] terminate:nil];
-}
-
-void QCocoaEventLoopIntegration::qtNeedsToProcessEvents()
-{
- CFRunLoopSourceSignal(m_source);
-}
-
diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.h b/src/plugins/platforms/cocoa/qcocoaglcontext.h
new file mode 100644
index 0000000000..1b84e7b305
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoaglcontext.h
@@ -0,0 +1,43 @@
+#ifndef QCOCOAGLCONTEXT_H
+#define QCOCOAGLCONTEXT_H
+
+#include <QtCore/QWeakPointer>
+#include <QtGui/QPlatformOpenGLContext>
+#include <QtGui/QOpenGLContext>
+#include <QtGui/QWindow>
+
+#undef slots
+#include <Cocoa/Cocoa.h>
+
+QT_BEGIN_NAMESPACE
+
+class QCocoaGLContext : public QPlatformOpenGLContext
+{
+public:
+ QCocoaGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share);
+
+ QSurfaceFormat format() const;
+
+ void swapBuffers(QPlatformSurface *surface);
+
+ bool makeCurrent(QPlatformSurface *surface);
+ void doneCurrent();
+
+ void (*getProcAddress(const QByteArray &procName)) ();
+
+ void update();
+
+ static NSOpenGLPixelFormat *createNSOpenGLPixelFormat();
+ NSOpenGLContext *nsOpenGLContext() const;
+
+private:
+ void setActiveWindow(QWindow *window);
+
+ NSOpenGLContext *m_context;
+ QSurfaceFormat m_format;
+ QWeakPointer<QWindow> m_currentWindow;
+};
+
+QT_END_NAMESPACE
+
+#endif // QCOCOAGLCONTEXT_H
diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.mm b/src/plugins/platforms/cocoa/qcocoaglcontext.mm
new file mode 100644
index 0000000000..8b07315378
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoaglcontext.mm
@@ -0,0 +1,99 @@
+#include "qcocoaglcontext.h"
+#include "qcocoawindow.h"
+#include "qcocoaautoreleasepool.h"
+#include <qdebug.h>
+#include <QtCore/private/qcore_mac_p.h>
+#include <QtPlatformSupport/private/cglconvenience_p.h>
+
+#import <Cocoa/Cocoa.h>
+
+QCocoaGLContext::QCocoaGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share)
+ : m_format(format)
+{
+ QCocoaAutoReleasePool pool; // For the SG Canvas render thread.
+
+ NSOpenGLPixelFormat *pixelFormat = static_cast <NSOpenGLPixelFormat *>(qcgl_createNSOpenGLPixelFormat());
+ NSOpenGLContext *actualShare = share ? static_cast<QCocoaGLContext *>(share)->m_context : 0;
+
+ m_context = [NSOpenGLContext alloc];
+ [m_context initWithFormat:pixelFormat shareContext:actualShare];
+
+ const GLint interval = 1;
+ [m_context setValues:&interval forParameter:NSOpenGLCPSwapInterval];
+
+}
+
+// Match up with createNSOpenGLPixelFormat!
+QSurfaceFormat QCocoaGLContext::format() const
+{
+ return m_format;
+}
+
+void QCocoaGLContext::swapBuffers(QPlatformSurface *surface)
+{
+ QWindow *window = static_cast<QCocoaWindow *>(surface)->window();
+ setActiveWindow(window);
+
+ [m_context flushBuffer];
+}
+
+bool QCocoaGLContext::makeCurrent(QPlatformSurface *surface)
+{
+ QCocoaAutoReleasePool pool;
+
+ QWindow *window = static_cast<QCocoaWindow *>(surface)->window();
+ setActiveWindow(window);
+
+ [m_context makeCurrentContext];
+ return true;
+}
+
+void QCocoaGLContext::setActiveWindow(QWindow *window)
+{
+ if (window == m_currentWindow.data())
+ return;
+
+ if (m_currentWindow)
+ static_cast<QCocoaWindow *>(m_currentWindow.data()->handle())->setCurrentContext(0);
+
+ Q_ASSERT(window->handle());
+
+ m_currentWindow = window;
+
+ QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window->handle());
+ cocoaWindow->setCurrentContext(this);
+
+ NSView *view = cocoaWindow->contentView();
+ [m_context setView:view];
+}
+
+void QCocoaGLContext::doneCurrent()
+{
+ if (m_currentWindow)
+ static_cast<QCocoaWindow *>(m_currentWindow.data()->handle())->setCurrentContext(0);
+
+ m_currentWindow.clear();
+
+ [NSOpenGLContext clearCurrentContext];
+}
+
+void (*QCocoaGLContext::getProcAddress(const QByteArray &procName))()
+{
+ return qcgl_getProcAddress(procName);
+}
+
+void QCocoaGLContext::update()
+{
+ [m_context update];
+}
+
+NSOpenGLPixelFormat *QCocoaGLContext::createNSOpenGLPixelFormat()
+{
+ return static_cast<NSOpenGLPixelFormat *>(qcgl_createNSOpenGLPixelFormat());
+}
+
+NSOpenGLContext *QCocoaGLContext::nsOpenGLContext() const
+{
+ return m_context;
+}
+
diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.h b/src/plugins/platforms/cocoa/qcocoahelpers.h
new file mode 100644
index 0000000000..8e807cc288
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoahelpers.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+ **
+ ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ ** All rights reserved.
+ ** Contact: Nokia Corporation (qt-info@nokia.com)
+ **
+ ** This file is part of the plugins of the Qt Toolkit.
+ **
+ ** $QT_BEGIN_LICENSE:LGPL$
+ ** GNU Lesser General Public License Usage
+ ** This file may be used under the terms of the GNU Lesser General Public
+ ** License version 2.1 as published by the Free Software Foundation and
+ ** appearing in the file LICENSE.LGPL included in the packaging of this
+ ** file. Please review the following information to ensure the GNU Lesser
+ ** General Public License version 2.1 requirements will be met:
+ ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+ **
+ ** In addition, as a special exception, Nokia gives you certain additional
+ ** rights. These rights are described in the Nokia Qt LGPL Exception
+ ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+ **
+ ** 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.
+ **
+ ** Other Usage
+ ** Alternatively, this file may be used in accordance with the terms and
+ ** conditions contained in a signed written agreement between you and Nokia.
+ **
+ **
+ **
+ **
+ **
+ ** $QT_END_LICENSE$
+ **
+ ****************************************************************************/
+
+#ifndef QCOCOAHELPERS_H
+#define QCOCOAHELPERS_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It provides helper functions
+// for the Cocoa lighthouse plugin. This header file may
+// change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <private/qt_mac_p.h>
+
+class QPixmap;
+class QString;
+
+// Conversion functions
+QStringList qt_mac_NSArrayToQStringList(void *nsarray);
+void *qt_mac_QStringListToNSMutableArrayVoid(const QStringList &list);
+
+inline NSMutableArray *qt_mac_QStringListToNSMutableArray(const QStringList &qstrlist)
+{ return reinterpret_cast<NSMutableArray *>(qt_mac_QStringListToNSMutableArrayVoid(qstrlist)); }
+
+inline QString qt_mac_NSStringToQString(const NSString *nsstr)
+{ return QCFString::toQString(reinterpret_cast<const CFStringRef>(nsstr)); }
+
+inline NSString *qt_mac_QStringToNSString(const QString &qstr)
+{ return [const_cast<NSString *>(reinterpret_cast<const NSString *>(QCFString::toCFStringRef(qstr))) autorelease]; }
+
+CGImageRef qt_mac_image_to_cgimage(const QImage &image);
+NSImage *qt_mac_cgimage_to_nsimage(CGImageRef iamge);
+NSImage *qt_mac_create_nsimage(const QPixmap &pm);
+
+QChar qt_mac_qtKey2CocoaKey(Qt::Key key);
+Qt::Key qt_mac_cocoaKey2QtKey(QChar keyCode);
+
+// Misc
+void qt_mac_transformProccessToForegroundApplication();
+QString qt_mac_removeMnemonics(const QString &original);
+CGColorSpaceRef qt_mac_genericColorSpace();
+CGColorSpaceRef qt_mac_displayColorSpace(const QWidget *widget);
+QString qt_mac_applicationName();
+
+
+#endif //QCOCOAHELPERS_H
+
diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm
new file mode 100644
index 0000000000..03e83f1130
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm
@@ -0,0 +1,448 @@
+/****************************************************************************
+ **
+ ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ ** All rights reserved.
+ ** Contact: Nokia Corporation (qt-info@nokia.com)
+ **
+ ** This file is part of the plugins of the Qt Toolkit.
+ **
+ ** $QT_BEGIN_LICENSE:LGPL$
+ ** GNU Lesser General Public License Usage
+ ** This file may be used under the terms of the GNU Lesser General Public
+ ** License version 2.1 as published by the Free Software Foundation and
+ ** appearing in the file LICENSE.LGPL included in the packaging of this
+ ** file. Please review the following information to ensure the GNU Lesser
+ ** General Public License version 2.1 requirements will be met:
+ ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+ **
+ ** In addition, as a special exception, Nokia gives you certain additional
+ ** rights. These rights are described in the Nokia Qt LGPL Exception
+ ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+ **
+ ** 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.
+ **
+ ** Other Usage
+ ** Alternatively, this file may be used in accordance with the terms and
+ ** conditions contained in a signed written agreement between you and Nokia.
+ **
+ **
+ **
+ **
+ **
+ ** $QT_END_LICENSE$
+ **
+ ****************************************************************************/
+
+#include "qcocoahelpers.h"
+
+#include "qcocoaautoreleasepool.h"
+
+#include <QtCore>
+#include <QtGui>
+
+//
+// Conversion Functions
+//
+
+QStringList qt_mac_NSArrayToQStringList(void *nsarray)
+{
+ QStringList result;
+ NSArray *array = static_cast<NSArray *>(nsarray);
+ for (NSUInteger i=0; i<[array count]; ++i)
+ result << qt_mac_NSStringToQString([array objectAtIndex:i]);
+ return result;
+}
+
+void *qt_mac_QStringListToNSMutableArrayVoid(const QStringList &list)
+{
+ NSMutableArray *result = [NSMutableArray arrayWithCapacity:list.size()];
+ for (int i=0; i<list.size(); ++i){
+ [result addObject:reinterpret_cast<const NSString *>(QCFString::toCFStringRef(list[i]))];
+ }
+ return result;
+}
+
+static void drawImageReleaseData (void *info, const void *, size_t)
+{
+ delete static_cast<QImage *>(info);
+}
+
+CGImageRef qt_mac_image_to_cgimage(const QImage &img)
+{
+ QImage *image;
+ if (img.depth() != 32)
+ image = new QImage(img.convertToFormat(QImage::Format_ARGB32_Premultiplied));
+ else
+ image = new QImage(img);
+
+ uint cgflags = kCGImageAlphaNone;
+ switch (image->format()) {
+ case QImage::Format_ARGB32_Premultiplied:
+ cgflags = kCGImageAlphaPremultipliedFirst;
+ break;
+ case QImage::Format_ARGB32:
+ cgflags = kCGImageAlphaFirst;
+ break;
+ case QImage::Format_RGB32:
+ cgflags = kCGImageAlphaNoneSkipFirst;
+ default:
+ break;
+ }
+ cgflags |= kCGBitmapByteOrder32Host;
+ QCFType<CGDataProviderRef> dataProvider = CGDataProviderCreateWithData(image,
+ static_cast<const QImage *>(image)->bits(),
+ image->byteCount(),
+ drawImageReleaseData);
+
+ return CGImageCreate(image->width(), image->height(), 8, 32,
+ image->bytesPerLine(),
+ qt_mac_genericColorSpace(),
+ cgflags, dataProvider, 0, false, kCGRenderingIntentDefault);
+
+}
+
+NSImage *qt_mac_cgimage_to_nsimage(CGImageRef image)
+{
+ QCocoaAutoReleasePool pool;
+ NSImage *newImage = 0;
+ NSRect imageRect = NSMakeRect(0.0, 0.0, CGImageGetWidth(image), CGImageGetHeight(image));
+ newImage = [[NSImage alloc] initWithSize:imageRect.size];
+ [newImage lockFocus];
+ {
+ CGContextRef imageContext = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
+ CGContextDrawImage(imageContext, *(CGRect*)&imageRect, image);
+ }
+ [newImage unlockFocus];
+ return newImage;
+}
+
+NSImage *qt_mac_create_nsimage(const QPixmap &pm)
+{
+ QImage image = pm.toImage();
+ return qt_mac_cgimage_to_nsimage(qt_mac_image_to_cgimage(image));
+}
+
+
+// Use this method to keep all the information in the TextSegment. As long as it is ordered
+// we are in OK shape, and we can influence that ourselves.
+struct KeyPair
+{
+ QChar cocoaKey;
+ Qt::Key qtKey;
+};
+
+bool operator==(const KeyPair &entry, QChar qchar)
+{
+ return entry.cocoaKey == qchar;
+}
+
+bool operator<(const KeyPair &entry, QChar qchar)
+{
+ return entry.cocoaKey < qchar;
+}
+
+bool operator<(QChar qchar, const KeyPair &entry)
+{
+ return qchar < entry.cocoaKey;
+}
+
+bool operator<(const Qt::Key &key, const KeyPair &entry)
+{
+ return key < entry.qtKey;
+}
+
+bool operator<(const KeyPair &entry, const Qt::Key &key)
+{
+ return entry.qtKey < key;
+}
+
+static bool qtKey2CocoaKeySortLessThan(const KeyPair &entry1, const KeyPair &entry2)
+{
+ return entry1.qtKey < entry2.qtKey;
+}
+
+static const int NumEntries = 59;
+static const KeyPair entries[NumEntries] = {
+ { NSEnterCharacter, Qt::Key_Enter },
+ { NSBackspaceCharacter, Qt::Key_Backspace },
+ { NSTabCharacter, Qt::Key_Tab },
+ { NSNewlineCharacter, Qt::Key_Return },
+ { NSCarriageReturnCharacter, Qt::Key_Return },
+ { NSBackTabCharacter, Qt::Key_Backtab },
+ { kEscapeCharCode, Qt::Key_Escape },
+ // Cocoa sends us delete when pressing backspace!
+ // (NB when we reverse this list in qtKey2CocoaKey, there
+ // will be two indices of Qt::Key_Backspace. But is seems to work
+ // ok for menu shortcuts (which uses that function):
+ { NSDeleteCharacter, Qt::Key_Backspace },
+ { NSUpArrowFunctionKey, Qt::Key_Up },
+ { NSDownArrowFunctionKey, Qt::Key_Down },
+ { NSLeftArrowFunctionKey, Qt::Key_Left },
+ { NSRightArrowFunctionKey, Qt::Key_Right },
+ { NSF1FunctionKey, Qt::Key_F1 },
+ { NSF2FunctionKey, Qt::Key_F2 },
+ { NSF3FunctionKey, Qt::Key_F3 },
+ { NSF4FunctionKey, Qt::Key_F4 },
+ { NSF5FunctionKey, Qt::Key_F5 },
+ { NSF6FunctionKey, Qt::Key_F6 },
+ { NSF7FunctionKey, Qt::Key_F7 },
+ { NSF8FunctionKey, Qt::Key_F8 },
+ { NSF9FunctionKey, Qt::Key_F8 },
+ { NSF10FunctionKey, Qt::Key_F10 },
+ { NSF11FunctionKey, Qt::Key_F11 },
+ { NSF12FunctionKey, Qt::Key_F12 },
+ { NSF13FunctionKey, Qt::Key_F13 },
+ { NSF14FunctionKey, Qt::Key_F14 },
+ { NSF15FunctionKey, Qt::Key_F15 },
+ { NSF16FunctionKey, Qt::Key_F16 },
+ { NSF17FunctionKey, Qt::Key_F17 },
+ { NSF18FunctionKey, Qt::Key_F18 },
+ { NSF19FunctionKey, Qt::Key_F19 },
+ { NSF20FunctionKey, Qt::Key_F20 },
+ { NSF21FunctionKey, Qt::Key_F21 },
+ { NSF22FunctionKey, Qt::Key_F22 },
+ { NSF23FunctionKey, Qt::Key_F23 },
+ { NSF24FunctionKey, Qt::Key_F24 },
+ { NSF25FunctionKey, Qt::Key_F25 },
+ { NSF26FunctionKey, Qt::Key_F26 },
+ { NSF27FunctionKey, Qt::Key_F27 },
+ { NSF28FunctionKey, Qt::Key_F28 },
+ { NSF29FunctionKey, Qt::Key_F29 },
+ { NSF30FunctionKey, Qt::Key_F30 },
+ { NSF31FunctionKey, Qt::Key_F31 },
+ { NSF32FunctionKey, Qt::Key_F32 },
+ { NSF33FunctionKey, Qt::Key_F33 },
+ { NSF34FunctionKey, Qt::Key_F34 },
+ { NSF35FunctionKey, Qt::Key_F35 },
+ { NSInsertFunctionKey, Qt::Key_Insert },
+ { NSDeleteFunctionKey, Qt::Key_Delete },
+ { NSHomeFunctionKey, Qt::Key_Home },
+ { NSEndFunctionKey, Qt::Key_End },
+ { NSPageUpFunctionKey, Qt::Key_PageUp },
+ { NSPageDownFunctionKey, Qt::Key_PageDown },
+ { NSPrintScreenFunctionKey, Qt::Key_Print },
+ { NSScrollLockFunctionKey, Qt::Key_ScrollLock },
+ { NSPauseFunctionKey, Qt::Key_Pause },
+ { NSSysReqFunctionKey, Qt::Key_SysReq },
+ { NSMenuFunctionKey, Qt::Key_Menu },
+ { NSHelpFunctionKey, Qt::Key_Help },
+};
+static const KeyPair * const end = entries + NumEntries;
+
+QChar qt_mac_qtKey2CocoaKey(Qt::Key key)
+{
+ // The first time this function is called, create a reverse
+ // looup table sorted on Qt Key rather than Cocoa key:
+ static QVector<KeyPair> rev_entries(NumEntries);
+ static bool mustInit = true;
+ if (mustInit){
+ mustInit = false;
+ for (int i=0; i<NumEntries; ++i)
+ rev_entries[i] = entries[i];
+ qSort(rev_entries.begin(), rev_entries.end(), qtKey2CocoaKeySortLessThan);
+ }
+ const QVector<KeyPair>::iterator i
+ = qBinaryFind(rev_entries.begin(), rev_entries.end(), key);
+ if (i == rev_entries.end())
+ return QChar();
+ return i->cocoaKey;
+}
+
+Qt::Key qt_mac_cocoaKey2QtKey(QChar keyCode)
+{
+ const KeyPair *i = qBinaryFind(entries, end, keyCode);
+ if (i == end)
+ return Qt::Key(keyCode.unicode());
+ return i->qtKey;
+}
+
+//
+// Misc
+//
+
+// Changes the process type for this process to kProcessTransformToForegroundApplication,
+// unless either LSUIElement or LSBackgroundOnly is set in the Info.plist.
+void qt_mac_transformProccessToForegroundApplication()
+{
+ ProcessSerialNumber psn;
+ if (GetCurrentProcess(&psn) == noErr) {
+ bool forceTransform = true;
+ CFTypeRef value = CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(),
+ CFSTR("LSUIElement"));
+ if (value) {
+ CFTypeID valueType = CFGetTypeID(value);
+ // Officially it's supposed to be a string, a boolean makes sense, so we'll check.
+ // A number less so, but OK.
+ if (valueType == CFStringGetTypeID())
+ forceTransform = !(QCFString::toQString(static_cast<CFStringRef>(value)).toInt());
+ else if (valueType == CFBooleanGetTypeID())
+ forceTransform = !CFBooleanGetValue(static_cast<CFBooleanRef>(value));
+ else if (valueType == CFNumberGetTypeID()) {
+ int valueAsInt;
+ CFNumberGetValue(static_cast<CFNumberRef>(value), kCFNumberIntType, &valueAsInt);
+ forceTransform = !valueAsInt;
+ }
+ }
+
+ if (forceTransform) {
+ value = CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(),
+ CFSTR("LSBackgroundOnly"));
+ if (value) {
+ CFTypeID valueType = CFGetTypeID(value);
+ if (valueType == CFBooleanGetTypeID())
+ forceTransform = !CFBooleanGetValue(static_cast<CFBooleanRef>(value));
+ else if (valueType == CFStringGetTypeID())
+ forceTransform = !(QCFString::toQString(static_cast<CFStringRef>(value)).toInt());
+ else if (valueType == CFNumberGetTypeID()) {
+ int valueAsInt;
+ CFNumberGetValue(static_cast<CFNumberRef>(value), kCFNumberIntType, &valueAsInt);
+ forceTransform = !valueAsInt;
+ }
+ }
+ }
+
+ if (forceTransform) {
+ TransformProcessType(&psn, kProcessTransformToForegroundApplication);
+ }
+ }
+}
+
+QString qt_mac_removeMnemonics(const QString &original)
+{
+ QString returnText(original.size(), 0);
+ int finalDest = 0;
+ int currPos = 0;
+ int l = original.length();
+ while (l) {
+ if (original.at(currPos) == QLatin1Char('&')
+ && (l == 1 || original.at(currPos + 1) != QLatin1Char('&'))) {
+ ++currPos;
+ --l;
+ if (l == 0)
+ break;
+ }
+ returnText[finalDest] = original.at(currPos);
+ ++currPos;
+ ++finalDest;
+ --l;
+ }
+ returnText.truncate(finalDest);
+ return returnText;
+}
+
+
+CGColorSpaceRef m_genericColorSpace = 0;
+QHash<CGDirectDisplayID, CGColorSpaceRef> m_displayColorSpaceHash;
+bool m_postRoutineRegistered = false;
+
+CGColorSpaceRef qt_mac_genericColorSpace()
+{
+#if 0
+ if (!m_genericColorSpace) {
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
+ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4) {
+ m_genericColorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
+ } else
+#endif
+ {
+ m_genericColorSpace = CGColorSpaceCreateDeviceRGB();
+ }
+ if (!m_postRoutineRegistered) {
+ m_postRoutineRegistered = true;
+ qAddPostRoutine(QCoreGraphicsPaintEngine::cleanUpMacColorSpaces);
+ }
+ }
+ return m_genericColorSpace;
+#else
+ // Just return the main display colorspace for the moment.
+ return qt_mac_displayColorSpace(0);
+#endif
+}
+
+/*
+ Ideally, we should pass the widget in here, and use CGGetDisplaysWithRect() etc.
+ to support multiple displays correctly.
+*/
+CGColorSpaceRef qt_mac_displayColorSpace(const QWidget *widget)
+{
+ CGColorSpaceRef colorSpace;
+
+ CGDirectDisplayID displayID;
+ CMProfileRef displayProfile = 0;
+ if (widget == 0) {
+ displayID = CGMainDisplayID();
+ } else {
+ displayID = CGMainDisplayID();
+ /*
+ ### get correct display
+ const QRect &qrect = widget->window()->geometry();
+ CGRect rect = CGRectMake(qrect.x(), qrect.y(), qrect.width(), qrect.height());
+ CGDisplayCount throwAway;
+ CGDisplayErr dErr = CGGetDisplaysWithRect(rect, 1, &displayID, &throwAway);
+ if (dErr != kCGErrorSuccess)
+ return macDisplayColorSpace(0); // fall back on main display
+ */
+ }
+ if ((colorSpace = m_displayColorSpaceHash.value(displayID)))
+ return colorSpace;
+
+ CMError err = CMGetProfileByAVID((CMDisplayIDType)displayID, &displayProfile);
+ if (err == noErr) {
+ colorSpace = CGColorSpaceCreateWithPlatformColorSpace(displayProfile);
+ } else if (widget) {
+ return qt_mac_displayColorSpace(0); // fall back on main display
+ }
+
+ if (colorSpace == 0)
+ colorSpace = CGColorSpaceCreateDeviceRGB();
+
+ m_displayColorSpaceHash.insert(displayID, colorSpace);
+ CMCloseProfile(displayProfile);
+ if (!m_postRoutineRegistered) {
+ m_postRoutineRegistered = true;
+ void qt_mac_cleanUpMacColorSpaces();
+ qAddPostRoutine(qt_mac_cleanUpMacColorSpaces);
+ }
+ return colorSpace;
+}
+
+void qt_mac_cleanUpMacColorSpaces()
+{
+ if (m_genericColorSpace) {
+ CFRelease(m_genericColorSpace);
+ m_genericColorSpace = 0;
+ }
+ QHash<CGDirectDisplayID, CGColorSpaceRef>::const_iterator it = m_displayColorSpaceHash.constBegin();
+ while (it != m_displayColorSpaceHash.constEnd()) {
+ if (it.value())
+ CFRelease(it.value());
+ ++it;
+ }
+ m_displayColorSpaceHash.clear();
+}
+
+QString qt_mac_applicationName()
+{
+ QString appName;
+ CFTypeRef string = CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(), CFSTR("CFBundleName"));
+ if (string)
+ appName = QCFString::toQString(static_cast<CFStringRef>(string));
+
+ if (appName.isEmpty()) {
+ QString arg0 = qApp->arguments().at(0);
+ if (arg0.contains("/")) {
+ QStringList parts = arg0.split("/");
+ appName = parts.at(parts.count() - 1);
+ } else {
+ appName = arg0;
+ }
+ }
+ return appName;
+}
+
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.h b/src/plugins/platforms/cocoa/qcocoaintegration.h
index 120bee46b7..a253a6bea3 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.h
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.h
@@ -76,19 +76,19 @@ public:
~QCocoaIntegration();
bool hasCapability(QPlatformIntegration::Capability cap) const;
- QPixmapData *createPixmapData(QPixmapData::PixelType type) const;
- QPlatformWindow *createPlatformWindow(QWidget *widget, WId winId = 0) const;
- QWindowSurface *createWindowSurface(QWidget *widget, WId winId) const;
-
- QList<QPlatformScreen *> screens() const { return mScreens; }
+ QPlatformWindow *createPlatformWindow(QWindow *window) const;
+ QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const;
+ QPlatformBackingStore *createPlatformBackingStore(QWindow *widget) const;
+ QAbstractEventDispatcher *guiThreadEventDispatcher() const;
QPlatformFontDatabase *fontDatabase() const;
+ QPlatformMenu *createPlatformMenu(QMenu *menu = 0) const;
+ QPlatformMenuBar *createPlatformMenuBar(QMenuBar *menuBar = 0) const;
- QPlatformEventLoopIntegration *createEventLoopIntegration() const;
-
+ QPlatformNativeInterface *nativeInterface() const;
private:
- QList<QPlatformScreen *> mScreens;
QPlatformFontDatabase *mFontDb;
+ QAbstractEventDispatcher *mEventDispatcher;
QCocoaAutoReleasePool *mPool;
};
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm
index 086f7b62e9..e3e204226f 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.mm
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm
@@ -42,14 +42,18 @@
#include "qcocoaintegration.h"
#include "qcocoawindow.h"
-#include "qcocoawindowsurface.h"
-#include "qcocoaeventloopintegration.h"
+#include "qcocoabackingstore.h"
+#include "qcocoanativeinterface.h"
+#include "qcocoamenuloader.h"
+#include "qcocoaeventdispatcher.h"
+#include "qcocoahelpers.h"
+#include "qcocoaapplication.h"
+#include "qcocoaapplicationdelegate.h"
+#include "qmenu_mac.h"
-#include "qcoretextfontdatabase.h"
+#include <QtCore/qcoreapplication.h>
-#include <QtGui/QApplication>
-
-#include <private/qpixmap_raster_p.h>
+#include <QtPlatformSupport/private/qbasicunixfontdatabase_p.h>
QT_BEGIN_NAMESPACE
@@ -74,18 +78,47 @@ QCocoaScreen::~QCocoaScreen()
}
QCocoaIntegration::QCocoaIntegration()
- : mFontDb(new QCoreTextFontDatabase())
+ : mFontDb(new QBasicUnixFontDatabase())
+ , mEventDispatcher(new QCocoaEventDispatcher())
{
mPool = new QCocoaAutoReleasePool;
- //Make sure we have a nsapplication :)
- [NSApplication sharedApplication];
-// [[OurApplication alloc] init];
+ QNSApplication *cocoaApplication = [QNSApplication sharedApplication];
+
+ // Applications launched from plain executables (without an app
+ // bundle) are "background" applications that does not take keybaord
+ // focus or have a dock icon or task switcher entry. Qt Gui apps generally
+ // wants to be foreground applications so change the process type. (But
+ // see the function implementation for exceptions.)
+ qt_mac_transformProccessToForegroundApplication();
+
+ // Move the application window to front to avoid launching behind the terminal.
+ // Ignoring other apps is neccessary (we must ignore the terminal), but makes
+ // Qt apps play slightly less nice with other apps when lanching from Finder
+ // (See the activateIgnoringOtherApps docs.)
+ [cocoaApplication activateIgnoringOtherApps : YES];
+
+ // ### For AA_MacPluginApplication we don't want to load the menu nib.
+ // Qt 4 also does not set the application delegate, so that behavior
+ // is matched here.
+ if (!QCoreApplication::testAttribute(Qt::AA_MacPluginApplication)) {
+
+ // Set app delegate, link to the current delegate (if any)
+ QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) *newDelegate = [QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) sharedDelegate];
+ [newDelegate setReflectionDelegate:[cocoaApplication delegate]];
+ [cocoaApplication setDelegate:newDelegate];
+
+ // Load the application menu. This menu contains Preferences, Hide, Quit.
+ QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *qtMenuLoader = [[QT_MANGLE_NAMESPACE(QCocoaMenuLoader) alloc] init];
+ qt_mac_loadMenuNib(qtMenuLoader);
+ [cocoaApplication setMenu:[qtMenuLoader menu]];
+ [newDelegate setMenuLoader:qtMenuLoader];
+ }
NSArray *screens = [NSScreen screens];
for (uint i = 0; i < [screens count]; i++) {
QCocoaScreen *screen = new QCocoaScreen(i);
- mScreens.append(screen);
+ screenAdded(screen);
}
}
@@ -98,26 +131,32 @@ bool QCocoaIntegration::hasCapability(QPlatformIntegration::Capability cap) cons
{
switch (cap) {
case ThreadedPixmaps: return true;
+ case OpenGL : return true;
+ case ThreadedOpenGL : return true;
default: return QPlatformIntegration::hasCapability(cap);
}
}
-QPixmapData *QCocoaIntegration::createPixmapData(QPixmapData::PixelType type) const
+QPlatformWindow *QCocoaIntegration::createPlatformWindow(QWindow *window) const
+{
+ return new QCocoaWindow(window);
+}
+
+QPlatformOpenGLContext *QCocoaIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
{
- return new QRasterPixmapData(type);
+ return new QCocoaGLContext(context->format(), context->shareHandle());
}
-QPlatformWindow *QCocoaIntegration::createPlatformWindow(QWidget *widget, WId winId) const
+QPlatformBackingStore *QCocoaIntegration::createPlatformBackingStore(QWindow *window) const
{
- Q_UNUSED(winId);
- return new QCocoaWindow(widget);
+ return new QCocoaBackingStore(window);
}
-QWindowSurface *QCocoaIntegration::createWindowSurface(QWidget *widget, WId winId) const
+QAbstractEventDispatcher *QCocoaIntegration::guiThreadEventDispatcher() const
{
- return new QCocoaWindowSurface(widget,winId);
+ return mEventDispatcher;
}
QPlatformFontDatabase *QCocoaIntegration::fontDatabase() const
@@ -125,8 +164,21 @@ QPlatformFontDatabase *QCocoaIntegration::fontDatabase() const
return mFontDb;
}
-QPlatformEventLoopIntegration *QCocoaIntegration::createEventLoopIntegration() const
+QPlatformMenu *QCocoaIntegration::createPlatformMenu(QMenu *menu) const
+{
+ // return new QCocoaMenu(menu);
+ return 0;
+}
+
+QPlatformMenuBar *QCocoaIntegration::createPlatformMenuBar(QMenuBar *menuBar) const
+{
+ //return new QCocoaMenuBar(menuBar);
+ return 0;
+}
+
+QPlatformNativeInterface *QCocoaIntegration::nativeInterface() const
{
- return new QCocoaEventLoopIntegration();
+ return new QCocoaNativeInterface();
}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoamenu.h b/src/plugins/platforms/cocoa/qcocoamenu.h
new file mode 100644
index 0000000000..4e8ce20580
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoamenu.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qmacdefines_mac.h"
+#import <Cocoa/Cocoa.h>
+
+QT_FORWARD_DECLARE_CLASS(QMenu)
+QT_FORWARD_DECLARE_CLASS(QAction)
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5
+
+@protocol NSMenuDelegate <NSObject>
+- (void)menu:(NSMenu*)menu willHighlightItem:(NSMenuItem*)item;
+- (void)menuWillOpen:(NSMenu*)menu;
+- (void)menuDidClose:(NSMenu*)menu;
+- (BOOL)hasShortcut:(NSMenu *)menu forKey:(NSString *)key forModifiers:(NSUInteger)modifier
+ whichItem:(NSMenuItem**)outItem;
+@end
+
+#endif
+
+@interface QT_MANGLE_NAMESPACE(QNativeCocoaMenu) : NSMenu <NSMenuDelegate>
+{
+ QMenu *qmenu;
+ QAction *previousAction;
+}
+- (id)initWithQMenu:(QMenu*)menu;
+- (BOOL)menuHasKeyEquivalent:(NSMenu *)menu forEvent:(NSEvent *)event target:(id *)target action:(SEL *)action;
+- (NSInteger)indexOfItemWithTarget:(id)anObject andAction:(SEL)actionSelector;
+@end
+
diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm
new file mode 100644
index 0000000000..1bb5f45a94
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoamenu.mm
@@ -0,0 +1,267 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qapplication.h"
+#include "qvarlengtharray.h"
+#import "qcocoamenu.h"
+#import "qcocoamenuloader.h"
+#import "qcocoaapplication.h"
+#include "qcocoahelpers.h"
+#include <private/qapplication_p.h>
+#include <private/qaction_p.h>
+
+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 void qt_mac_menu_collapseSeparators(NSMenu *menu, bool collapse);
+void qt_mac_clear_status_text(QAction *action);
+extern void qt_mac_emit_menuSignals(QMenu *menu, bool show);
+extern void qt_mac_menu_emit_hovered(QMenu *menu, QAction *action);
+QT_END_NAMESPACE
+
+QT_USE_NAMESPACE
+
+@implementation QT_MANGLE_NAMESPACE(QNativeCocoaMenu)
+
+- (id)initWithQMenu:(QMenu*)menu
+{
+ self = [super init];
+ if (self) {
+ qmenu = menu;
+ previousAction = 0;
+ [self setAutoenablesItems:NO];
+ [self setDelegate:self];
+ }
+ return self;
+}
+
+- (void)menu:(NSMenu*)menu willHighlightItem:(NSMenuItem*)item
+{
+ Q_UNUSED(menu);
+
+ if (!item) {
+ if (previousAction) {
+ qt_mac_clear_status_text(previousAction);
+ previousAction = 0;
+ }
+ return;
+ }
+
+ if (QAction *action = reinterpret_cast<QAction *>([item tag])) {
+ QMenu *qtmenu = static_cast<QT_MANGLE_NAMESPACE(QNativeCocoaMenu) *>(menu)->qmenu;
+ previousAction = action;
+ action->activate(QAction::Hover);
+ qt_mac_menu_emit_hovered(qtmenu, action);
+ action->showStatusText(0); // 0 widget -> action's parent
+ }
+}
+
+- (void)menuWillOpen:(NSMenu*)menu
+{
+ while (QWidget *popup
+ = QApplication::activePopupWidget())
+ popup->close();
+ QMenu *qtmenu = static_cast<QT_MANGLE_NAMESPACE(QNativeCocoaMenu) *>(menu)->qmenu;
+ qt_mac_emit_menuSignals(qtmenu, true);
+ qt_mac_menu_collapseSeparators(menu, qtmenu->separatorsCollapsible());
+}
+
+- (void)menuDidClose:(NSMenu*)menu
+{
+ qt_mac_emit_menuSignals(((QT_MANGLE_NAMESPACE(QNativeCocoaMenu) *)menu)->qmenu, false);
+ if (previousAction) {
+ qt_mac_clear_status_text(previousAction);
+ previousAction = 0;
+ }
+}
+
+- (BOOL)hasShortcut:(NSMenu *)menu forKey:(NSString *)key forModifiers:(NSUInteger)modifier
+ whichItem:(NSMenuItem**)outItem
+{
+ for (NSMenuItem *item in [menu itemArray]) {
+ if (![item isEnabled] || [item isHidden] || [item isSeparatorItem])
+ continue;
+ if ([item hasSubmenu]) {
+ if ([self hasShortcut:[item submenu]
+ forKey:key
+ forModifiers:modifier whichItem:outItem]) {
+ if (outItem)
+ *outItem = item;
+ return YES;
+ }
+ }
+ NSString *menuKey = [item keyEquivalent];
+ if (menuKey && NSOrderedSame == [menuKey compare:key]
+ && (modifier == [item keyEquivalentModifierMask])) {
+ if (outItem)
+ *outItem = item;
+ return YES;
+ }
+ }
+ if (outItem)
+ *outItem = 0;
+ return NO;
+}
+
+NSString *qt_mac_removePrivateUnicode(NSString* string)
+{
+ int len = [string length];
+ if (len) {
+ QVarLengthArray <unichar, 10> characters(len);
+ bool changed = false;
+ for (int i = 0; i<len; i++) {
+ characters[i] = [string characterAtIndex:i];
+ // check if they belong to key codes in private unicode range
+ // currently we need to handle only the NSDeleteFunctionKey
+ if (characters[i] == NSDeleteFunctionKey) {
+ characters[i] = NSDeleteCharacter;
+ changed = true;
+ }
+ }
+ if (changed)
+ return [NSString stringWithCharacters:characters.data() length:len];
+ }
+ return string;
+}
+
+- (BOOL)menuHasKeyEquivalent:(NSMenu *)menu forEvent:(NSEvent *)event target:(id *)target action:(SEL *)action
+{
+ // Check if the menu actually has a keysequence defined for this key event.
+ // 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, 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;
+ // Change the private unicode keys to the ones used in setting the "Key Equivalents"
+ NSString *characters = qt_mac_removePrivateUnicode([event characters]);
+ if ([self hasShortcut:menu
+ forKey:characters
+ // Interested only in Shift, Cmd, Ctrl & Alt Keys, so ignoring masks like, Caps lock, Num Lock ...
+ forModifiers:([event modifierFlags] & (NSShiftKeyMask | NSControlKeyMask | NSCommandKeyMask | NSAlternateKeyMask))
+ whichItem:&whichItem]) {
+ QWidget *widget = 0;
+ QAction *qaction = 0;
+ if (whichItem && [whichItem tag]) {
+ qaction = reinterpret_cast<QAction *>([whichItem tag]);
+ }
+ if (qApp->activePopupWidget())
+ widget = (qApp->activePopupWidget()->focusWidget() ?
+ qApp->activePopupWidget()->focusWidget() : qApp->activePopupWidget());
+ else if (QApplicationPrivate::focus_widget)
+ widget = QApplicationPrivate::focus_widget;
+ // If we could not find any receivers, pass it to the active window
+ if (!widget)
+ widget = qApp->activeWindow();
+ if (qaction && widget) {
+ int key = qaction->shortcut();
+ QKeyEvent accel_ev(QEvent::ShortcutOverride, (key & (~Qt::KeyboardModifierMask)),
+ Qt::KeyboardModifiers(key & Qt::KeyboardModifierMask));
+ accel_ev.ignore();
+
+// ### qt_sendSpontaneousEvent(widget, &accel_ev);
+
+ if (accel_ev.isAccepted()) {
+ qWarning("Unimplemented: qt_dispatchKeyEvent");
+#if 0
+ qt_dispatchKeyEvent(event, widget);
+#endif
+ *target = nil;
+ *action = nil;
+ return YES;
+ }
+ }
+ }
+ return NO;
+}
+
+- (NSInteger)indexOfItemWithTarget:(id)anObject andAction:(SEL)actionSelector
+{
+ NSInteger index = [super indexOfItemWithTarget:anObject andAction:actionSelector];
+ static SEL selForOFCP = NSSelectorFromString(@"orderFrontCharacterPalette:");
+ if (index == -1 && selForOFCP == actionSelector) {
+ // Check if the 'orderFrontCharacterPalette' SEL exists for QNativeCocoaMenuLoader object
+ QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = [NSApp QT_MANGLE_NAMESPACE(qt_qcocoamenuLoader)];
+ return [super indexOfItemWithTarget:loader andAction:actionSelector];
+ }
+ return index;
+}
+
+@end
+
+QT_BEGIN_NAMESPACE
+extern int qt_mac_menus_open_count; // qmenu_mac.mm
+
+void qt_mac_emit_menuSignals(QMenu *menu, bool show)
+{
+ if (!menu)
+ return;
+ int delta;
+ if (show) {
+ emit menu->aboutToShow();
+ delta = 1;
+ } else {
+ emit menu->aboutToHide();
+ delta = -1;
+ }
+ qt_mac_menus_open_count += delta;
+}
+
+void qt_mac_clear_status_text(QAction *action)
+{
+ action->d_func()->showStatusText(0, QString());
+}
+
+void qt_mac_menu_emit_hovered(QMenu *menu, QAction *action)
+{
+ emit menu->hovered(action);
+}
+
+
+QT_END_NAMESPACE
+
diff --git a/src/plugins/platforms/cocoa/qcocoamenuloader.h b/src/plugins/platforms/cocoa/qcocoamenuloader.h
new file mode 100644
index 0000000000..2fcda512f0
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoamenuloader.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCOCOAMENULOADER_P_H
+#define QCOCOAMENULOADER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#import <Cocoa/Cocoa.h>
+#include <QtCore/private/qcore_mac_p.h>
+
+@interface QT_MANGLE_NAMESPACE(QCocoaMenuLoader) : NSResponder
+{
+ IBOutlet NSMenu *theMenu;
+ IBOutlet NSMenu *appMenu;
+ IBOutlet NSMenuItem *quitItem;
+ IBOutlet NSMenuItem *preferencesItem;
+ IBOutlet NSMenuItem *aboutItem;
+ IBOutlet NSMenuItem *aboutQtItem;
+ IBOutlet NSMenuItem *hideItem;
+ NSMenuItem *lastAppSpecificItem;
+ NSMenuItem *servicesItem;
+ NSMenuItem *hideAllOthersItem;
+ NSMenuItem *showAllItem;
+}
+- (void)ensureAppMenuInMenu:(NSMenu *)menu;
+- (void)removeActionsFromAppMenu;
+- (NSMenu *)applicationMenu;
+- (NSMenu *)menu;
+- (NSMenuItem *)quitMenuItem;
+- (NSMenuItem *)preferencesMenuItem;
+- (NSMenuItem *)aboutMenuItem;
+- (NSMenuItem *)aboutQtMenuItem;
+- (NSMenuItem *)hideMenuItem;
+- (NSMenuItem *)appSpecificMenuItem;
+- (IBAction)terminate:(id)sender;
+- (IBAction)orderFrontStandardAboutPanel:(id)sender;
+- (IBAction)hideOtherApplications:(id)sender;
+- (IBAction)unhideAllApplications:(id)sender;
+- (IBAction)hide:(id)sender;
+- (IBAction)qtDispatcherToQAction:(id)sender;
+- (void)qtUpdateMenubar;
+- (void)orderFrontCharacterPalette:(id)sender;
+@end
+
+void qt_mac_loadMenuNib(QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *qtMenuLoader);
+
+#endif // QCOCOAMENULOADER_P_H
diff --git a/src/plugins/platforms/cocoa/qcocoamenuloader.mm b/src/plugins/platforms/cocoa/qcocoamenuloader.mm
new file mode 100644
index 0000000000..353808655f
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoamenuloader.mm
@@ -0,0 +1,314 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcocoamenuloader.h"
+
+#include "qmenu_mac.h"
+#include "qcocoahelpers.h"
+
+#include <QtCore/private/qcore_mac_p.h>
+#include <QtCore/qcoreapplication.h>
+#include <QtCore/qdir.h>
+#include <QtCore/qstring.h>
+#include <QtCore/qdebug.h>
+
+QT_FORWARD_DECLARE_CLASS(QCFString)
+QT_FORWARD_DECLARE_CLASS(QString)
+
+#ifndef QT_NO_TRANSLATION
+ QT_BEGIN_NAMESPACE
+ extern QString qt_mac_applicationmenu_string(int type);
+ QT_END_NAMESPACE
+#endif
+
+QT_USE_NAMESPACE
+
+/*
+ Loads and instantiates the main app menu from the menu nib file(s).
+
+ The main app menu contains the Quit, Hide About, Preferences entries, and
+ The reason for having the nib file is that those can not be created
+ programmatically. To ease deployment the nib files are stored in Qt resources
+ and written to QDir::temp() before loading. (Earlier Qt versions used
+ to require having the nib file in the QtGui framework.)
+*/
+void qt_mac_loadMenuNib(QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *qtMenuLoader)
+{
+ // Create qt_menu.nib dir in temp.
+ QDir temp = QDir::temp();
+ temp.mkdir("qt_menu.nib");
+ QString nibDir = temp.canonicalPath() + QLatin1String("/") + QLatin1String("qt_menu.nib/");
+ if (!QDir(nibDir).exists()) {
+ qWarning("qt_mac_loadMenuNib: could not create nib directory in temp");
+ return;
+ }
+
+ // Copy nib files from resources to temp.
+ QDir nibResource(":/trolltech/mac/qt_menu.nib/");
+ if (!nibResource.exists()) {
+ qWarning("qt_mac_loadMenuNib: could not load nib from resources");
+ return;
+ }
+ foreach (const QFileInfo &file, nibResource.entryInfoList()) {
+ QFile::copy(file.absoluteFilePath(), nibDir + QLatin1String("/") + file.fileName());
+ }
+
+ // Load and instantiate nib file from temp
+ NSURL *nibUrl = [NSURL fileURLWithPath : const_cast<NSString *>(reinterpret_cast<const NSString *>(QCFString::toCFStringRef(nibDir)))];
+ [nibUrl autorelease];
+ NSNib *nib = [[NSNib alloc] initWithContentsOfURL : nibUrl];
+ [nib autorelease];
+ if(!nib) {
+ qWarning("qt_mac_loadMenuNib: could not load nib from temp");
+ return;
+ }
+ bool ok = [nib instantiateNibWithOwner : qtMenuLoader topLevelObjects : nil];
+ if (!ok) {
+ qWarning("qt_mac_loadMenuNib: could not instantiate nib");
+ }
+}
+
+
+
+@implementation QT_MANGLE_NAMESPACE(QCocoaMenuLoader)
+
+- (void)awakeFromNib
+{
+ servicesItem = [[appMenu itemWithTitle:@"Services"] retain];
+ hideAllOthersItem = [[appMenu itemWithTitle:@"Hide Others"] retain];
+ showAllItem = [[appMenu itemWithTitle:@"Show All"] retain];
+
+ // Get the names in the nib to match the app name set by Qt.
+ const NSString *appName = reinterpret_cast<const NSString*>(QCFString::toCFStringRef(qt_mac_applicationName()));
+ [quitItem setTitle:[[quitItem title] stringByReplacingOccurrencesOfString:@"NewApplication"
+ withString:const_cast<NSString *>(appName)]];
+ [hideItem setTitle:[[hideItem title] stringByReplacingOccurrencesOfString:@"NewApplication"
+ withString:const_cast<NSString *>(appName)]];
+ [aboutItem setTitle:[[aboutItem title] stringByReplacingOccurrencesOfString:@"NewApplication"
+ withString:const_cast<NSString *>(appName)]];
+ [appName release];
+ // Disable the items that don't do anything. If someone associates a QAction with them
+ // They should get synced back in.
+ [preferencesItem setEnabled:NO];
+ [preferencesItem setHidden:YES];
+ [aboutItem setEnabled:NO];
+ [aboutItem setHidden:YES];
+}
+
+- (void)ensureAppMenuInMenu:(NSMenu *)menu
+{
+ // The application menu is the menu in the menu bar that contains the
+ // 'Quit' item. When changing menu bar (e.g when switching between
+ // windows with different menu bars), we never recreate this menu, but
+ // instead pull it out the current menu bar and place into the new one:
+ NSMenu *mainMenu = [NSApp mainMenu];
+ if ([NSApp mainMenu] == menu)
+ return; // nothing to do (menu is the current menu bar)!
+
+#ifndef QT_NAMESPACE
+ Q_ASSERT(mainMenu);
+#endif
+ // Grab the app menu out of the current menu.
+ int numItems = [mainMenu numberOfItems];
+ NSMenuItem *oldAppMenuItem = 0;
+ for (int i = 0; i < numItems; ++i) {
+ NSMenuItem *item = [mainMenu itemAtIndex:i];
+ if ([item submenu] == appMenu) {
+ oldAppMenuItem = item;
+ [oldAppMenuItem retain];
+ [mainMenu removeItemAtIndex:i];
+ break;
+ }
+ }
+
+ if (oldAppMenuItem) {
+ [oldAppMenuItem setSubmenu:nil];
+ [oldAppMenuItem release];
+ NSMenuItem *appMenuItem = [[NSMenuItem alloc] initWithTitle:@"Apple"
+ action:nil keyEquivalent:@""];
+ [appMenuItem setSubmenu:appMenu];
+ [menu insertItem:appMenuItem atIndex:0];
+ }
+}
+
+- (void)removeActionsFromAppMenu
+{
+ for (NSMenuItem *item in [appMenu itemArray])
+ [item setTag:nil];
+}
+
+- (void)dealloc
+{
+ [servicesItem release];
+ [hideAllOthersItem release];
+ [showAllItem release];
+
+ [lastAppSpecificItem release];
+ [theMenu release];
+ [appMenu release];
+ [super dealloc];
+}
+
+- (NSMenu *)menu
+{
+ return [[theMenu retain] autorelease];
+}
+
+- (NSMenu *)applicationMenu
+{
+ return [[appMenu retain] autorelease];
+}
+
+- (NSMenuItem *)quitMenuItem
+{
+ return [[quitItem retain] autorelease];
+}
+
+- (NSMenuItem *)preferencesMenuItem
+{
+ return [[preferencesItem retain] autorelease];
+}
+
+- (NSMenuItem *)aboutMenuItem
+{
+ return [[aboutItem retain] autorelease];
+}
+
+- (NSMenuItem *)aboutQtMenuItem
+{
+ return [[aboutQtItem retain] autorelease];
+}
+
+- (NSMenuItem *)hideMenuItem
+{
+ return [[hideItem retain] autorelease];
+}
+
+- (NSMenuItem *)appSpecificMenuItem
+{
+ // Create an App-Specific menu item, insert it into the menu and return
+ // it as an autorelease item.
+ NSMenuItem *item = [[NSMenuItem alloc] init];
+
+ NSInteger location;
+ if (lastAppSpecificItem == nil) {
+ location = [appMenu indexOfItem:aboutQtItem];
+ } else {
+ location = [appMenu indexOfItem:lastAppSpecificItem];
+ [lastAppSpecificItem release];
+ }
+ lastAppSpecificItem = item; // Keep track of this for later (i.e., don't release it)
+ [appMenu insertItem:item atIndex:location + 1];
+
+ return [[item retain] autorelease];
+}
+
+- (BOOL) acceptsFirstResponder
+{
+ return YES;
+}
+
+- (void)terminate:(id)sender
+{
+ [NSApp terminate:sender];
+}
+
+- (void)orderFrontStandardAboutPanel:(id)sender
+{
+ [NSApp orderFrontStandardAboutPanel:sender];
+}
+
+- (void)hideOtherApplications:(id)sender
+{
+ [NSApp hideOtherApplications:sender];
+}
+
+- (void)unhideAllApplications:(id)sender
+{
+ [NSApp unhideAllApplications:sender];
+}
+
+- (void)hide:(id)sender
+{
+ [NSApp hide:sender];
+}
+
+- (void)qtUpdateMenubar
+{
+ QCocoaMenuBar::macUpdateMenuBarImmediatly();
+}
+
+- (void)qtTranslateApplicationMenu
+{
+
+ qDebug() << "qtTranslateApplicationMenu";
+
+#ifndef QT_NO_TRANSLATION
+ [servicesItem setTitle: qt_mac_QStringToNSString(qt_mac_applicationmenu_string(0))];
+ [hideItem setTitle: qt_mac_QStringToNSString(qt_mac_applicationmenu_string(1).arg(qt_mac_applicationName()))];
+ [hideAllOthersItem setTitle: qt_mac_QStringToNSString(qt_mac_applicationmenu_string(2))];
+ [showAllItem setTitle: qt_mac_QStringToNSString(qt_mac_applicationmenu_string(3))];
+ [preferencesItem setTitle: qt_mac_QStringToNSString(qt_mac_applicationmenu_string(4))];
+ [quitItem setTitle: qt_mac_QStringToNSString(qt_mac_applicationmenu_string(5).arg(qt_mac_applicationName()))];
+ [aboutItem setTitle: qt_mac_QStringToNSString(qt_mac_applicationmenu_string(6).arg(qt_mac_applicationName()))];
+#endif
+}
+
+- (IBAction)qtDispatcherToQAction:(id)sender
+{
+ //
+ //QScopedLoopLevelCounter loopLevelCounter(QApplicationPrivate::instance()->threadData);
+ NSMenuItem *item = static_cast<NSMenuItem *>(sender);
+ if (QAction *action = reinterpret_cast<QAction *>([item tag])) {
+ action->trigger();
+ } else if (item == quitItem) {
+ // We got here because someone was once the quitItem, but it has been
+ // abandoned (e.g., the menubar was deleted). In the meantime, just do
+ // normal QApplication::quit().
+ qApp->quit();
+ }
+}
+
+ - (void)orderFrontCharacterPalette:(id)sender
+ {
+ [NSApp orderFrontCharacterPalette:sender];
+ }
+@end
diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.h b/src/plugins/platforms/cocoa/qcocoanativeinterface.h
new file mode 100644
index 0000000000..f8216d8e61
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.h
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCOCOANATIVEINTERFACE_H
+#define QCOCOANATIVEINTERFACE_H
+
+#include <QtGui/QPlatformNativeInterface>
+
+class QWidget;
+
+class QCocoaNativeInterface : public QPlatformNativeInterface
+{
+public:
+ void *nativeResourceForWindow(const QByteArray &resourceString, QWindow *window);
+};
+
+#endif // QCOCOANATIVEINTERFACE_H
diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
new file mode 100644
index 0000000000..c6aa0d39e6
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcocoanativeinterface.h"
+#include "qcocoaglcontext.h"
+#include "qcocoawindow.h"
+#include <qbytearray.h>
+#include <qwindow.h>
+#include "qplatformwindow_qpa.h"
+#include "qsurfaceformat.h"
+#include "qplatformopenglcontext_qpa.h"
+#include "qopenglcontext.h"
+#include <qdebug.h>
+
+void *QCocoaNativeInterface::nativeResourceForWindow(const QByteArray &resourceString, QWindow *window)
+{
+ if (resourceString == "nsopenglcontext") {
+ return static_cast<QCocoaWindow *>(window->handle())->currentContext()->nsOpenGLContext();
+ }
+ return 0;
+}
diff --git a/src/plugins/platforms/cocoa/qcocoaresources.qrc b/src/plugins/platforms/cocoa/qcocoaresources.qrc
new file mode 100644
index 0000000000..de50d397c6
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoaresources.qrc
@@ -0,0 +1,17 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/trolltech/mac/cursors">
+<file>images/copyarrowcursor.png</file>
+<file>images/forbiddencursor.png</file>
+<file>images/spincursor.png</file>
+<file>images/waitcursor.png</file>
+<file>images/pluscursor.png</file>
+</qresource>
+<qresource prefix="/trolltech/mac/style">
+<file>images/leopard-unified-toolbar-on.png</file>
+</qresource>
+<qresource prefix="/trolltech/mac/">
+<file>qt_menu.nib/classes.nib</file>
+<file>qt_menu.nib/info.nib</file>
+<file>qt_menu.nib/keyedobjects.nib</file>
+</qresource>
+</RCC>
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h
index 9e7e68b7d2..ce79d3967f 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.h
+++ b/src/plugins/platforms/cocoa/qcocoawindow.h
@@ -45,28 +45,55 @@
#include <Cocoa/Cocoa.h>
#include <QPlatformWindow>
+#include <QRect>
+
+#include "qcocoaglcontext.h"
+#include "qnsview.h"
QT_BEGIN_NAMESPACE
+@interface QNSWindow : NSWindow {
+
+}
+
+@end
+
class QCocoaWindow : public QPlatformWindow
{
public:
- QCocoaWindow(QWidget *tlw);
+ QCocoaWindow(QWindow *tlw);
~QCocoaWindow();
void setGeometry(const QRect &rect);
-
void setVisible(bool visible);
+ void setWindowTitle(const QString &title);
+ void raise();
+ void lower();
WId winId() const;
-
NSView *contentView() const;
- void setContentView(NSView *contentView);
+ void windowDidMove();
void windowDidResize();
+ void windowWillClose();
+
+ void setCurrentContext(QCocoaGLContext *context);
+ QCocoaGLContext *currentContext() const;
+
+protected:
+ void determineWindowClass();
+ QNSWindow *createWindow();
+ NSRect globalGeometry(const QRect localWindowGeometry) const;
+ QRect windowGeometry() const;
+ QCocoaWindow *parentCocoaWindow() const;
private:
- NSWindow *m_nsWindow;
+ friend class QCocoaBackingStore;
+ QNSWindow *m_nsWindow;
+ QNSView *m_contentView;
+ quint32 m_windowAttributes;
+ quint32 m_windowClass;
+ QCocoaGLContext *m_glContext;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index a2fdce3520..7e4d4217ef 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -41,54 +41,116 @@
#include "qcocoawindow.h"
#include "qnswindowdelegate.h"
#include "qcocoaautoreleasepool.h"
+#include "qcocoaglcontext.h"
+#include "qnsview.h"
+#include <QtCore/private/qcore_mac_p.h>
+#include <qwindow.h>
+#include <QWindowSystemInterface>
+#include <QPlatformScreen>
-#include <QWidget>
+#include <Cocoa/Cocoa.h>
+#include <Carbon/Carbon.h>
-#include <QtGui/QApplication>
+#include <QDebug>
-#include <QWindowSystemInterface>
+@implementation QNSWindow
-#include <QDebug>
+- (BOOL)canBecomeKeyWindow
+{
+ return YES;
+}
+
+- (BOOL)canBecomeMainWindow
+{
+ return YES;
+}
+
+@end
-QCocoaWindow::QCocoaWindow(QWidget *tlw)
+QCocoaWindow::QCocoaWindow(QWindow *tlw)
: QPlatformWindow(tlw)
+ , m_windowAttributes(0)
+ , m_windowClass(0)
+ , m_glContext(0)
{
QCocoaAutoReleasePool pool;
- const QRect geo = tlw->geometry();
- NSRect frame = NSMakeRect(geo.x(), geo.y(), geo.width(), geo.height());
- m_nsWindow = [[NSWindow alloc] initWithContentRect:frame
- styleMask:NSTitledWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask|NSResizableWindowMask
- backing:NSBackingStoreBuffered
- defer:YES];
+ determineWindowClass();
+ m_nsWindow = createWindow();
QNSWindowDelegate *delegate = [[QNSWindowDelegate alloc] initWithQCocoaWindow:this];
[m_nsWindow setDelegate:delegate];
-
- [m_nsWindow makeKeyAndOrderFront:nil];
[m_nsWindow setAcceptsMouseMovedEvents:YES];
+
+ // Prevent Cocoa from releasing the window on close. Qt
+ // handles the close event asynchronously and we want to
+ // make sure that m_nsWindow stays valid until the
+ // QCocoaWindow is deleted by Qt.
+ [m_nsWindow setReleasedWhenClosed : NO];
+
+ m_contentView = [[QNSView alloc] initWithQWindow:tlw];
+
+ setGeometry(tlw->geometry());
+
+ [m_nsWindow setContentView:m_contentView];
}
QCocoaWindow::~QCocoaWindow()
{
+ [m_nsWindow release];
}
void QCocoaWindow::setGeometry(const QRect &rect)
{
QPlatformWindow::setGeometry(rect);
- NSRect bounds = NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height());
+ NSRect bounds = globalGeometry(rect);
[[m_nsWindow contentView]setFrameSize:bounds.size];
+ [m_nsWindow setContentSize : bounds.size];
+ [m_nsWindow setFrameOrigin : bounds.origin];
+
+ if (m_glContext)
+ m_glContext->update();
}
void QCocoaWindow::setVisible(bool visible)
{
- Q_UNUSED(visible);
+ if (visible) {
+ // The parent window might have moved while this window was hidden,
+ // update the window geometry if there is a parent.
+ if (window()->transientParent())
+ setGeometry(window()->geometry());
+
+ // Make sure the QWindow has a frame ready before we show the NSWindow.
+ QWindowSystemInterface::handleSynchronousExposeEvent(window(), QRect(QPoint(), geometry().size()));
+
+ [m_nsWindow makeKeyAndOrderFront:nil];
+ } else {
+ [m_nsWindow orderOut:nil];
+ }
+}
+
+void QCocoaWindow::setWindowTitle(const QString &title)
+{
+ CFStringRef windowTitle = QCFString::toCFStringRef(title);
+ [m_nsWindow setTitle: const_cast<NSString *>(reinterpret_cast<const NSString *>(windowTitle))];
+ CFRelease(windowTitle);
+}
+
+void QCocoaWindow::raise()
+{
+ // ### handle spaces (see Qt 4 raise_sys in qwidget_mac.mm)
+ [m_nsWindow orderFront: m_nsWindow];
+}
+
+void QCocoaWindow::lower()
+{
+ [m_nsWindow orderFront: m_nsWindow];
}
WId QCocoaWindow::winId() const
{
- return WId([m_nsWindow windowNumber]);
+ return WId(m_nsWindow);
}
NSView *QCocoaWindow::contentView() const
@@ -96,15 +158,231 @@ NSView *QCocoaWindow::contentView() const
return [m_nsWindow contentView];
}
-void QCocoaWindow::setContentView(NSView *contentView)
+void QCocoaWindow::windowDidMove()
{
- [m_nsWindow setContentView:contentView];
+ if (m_glContext)
+ m_glContext->update();
}
void QCocoaWindow::windowDidResize()
{
- //jlind: XXX This isn't ideal. Eventdispatcher does not run when resizing...
+ if (m_glContext)
+ m_glContext->update();
+
NSRect rect = [[m_nsWindow contentView]frame];
QRect geo(rect.origin.x,rect.origin.y,rect.size.width,rect.size.height);
- QWindowSystemInterface::handleGeometryChange(widget(),geo);
+ QWindowSystemInterface::handleSynchronousGeometryChange(window(), geo);
+}
+
+
+void QCocoaWindow::windowWillClose()
+{
+ QWindowSystemInterface::handleCloseEvent(window());
+}
+
+void QCocoaWindow::setCurrentContext(QCocoaGLContext *context)
+{
+ m_glContext = context;
+}
+
+QCocoaGLContext *QCocoaWindow::currentContext() const
+{
+ return m_glContext;
}
+
+/*
+ Determine the window class based on the window type and
+ window flags, and widget attr Sets m_windowAttributes
+ and m_windowClass.
+*/
+void QCocoaWindow::determineWindowClass()
+{
+ Qt::WindowType type = window()->windowType();
+ Qt::WindowFlags flags = window()->windowFlags();
+
+ const bool popup = (type == Qt::Popup);
+
+ if (type == Qt::ToolTip || type == Qt::SplashScreen || popup)
+ flags |= Qt::FramelessWindowHint;
+
+ m_windowClass = kSheetWindowClass;
+
+ if (popup || type == Qt::SplashScreen)
+ m_windowClass = kModalWindowClass;
+ else if (type == Qt::ToolTip)
+ m_windowClass = kHelpWindowClass;
+ else if (type == Qt::Tool)
+ m_windowClass = kFloatingWindowClass;
+ else
+ m_windowClass = kDocumentWindowClass;
+
+ m_windowAttributes = (kWindowCompositingAttribute | kWindowStandardHandlerAttribute);
+
+// if(qt_mac_is_macsheet(window())) {
+// m_windowClass = kSheetWindowClass;
+// } else
+
+ {
+ // Shift things around a bit to get the correct window class based on the presence
+ // (or lack) of the border.
+
+ bool customize = flags & Qt::CustomizeWindowHint;
+ bool framelessWindow = (flags & Qt::FramelessWindowHint || (customize && !(flags & Qt::WindowTitleHint)));
+ if (framelessWindow) {
+ if (m_windowClass == kDocumentWindowClass) {
+ m_windowAttributes |= kWindowNoTitleBarAttribute;
+ } else if (m_windowClass == kFloatingWindowClass) {
+ m_windowAttributes |= kWindowNoTitleBarAttribute;
+ } else if (m_windowClass == kMovableModalWindowClass) {
+ m_windowClass = kModalWindowClass;
+ }
+ } else {
+ m_windowAttributes |= NSTitledWindowMask;
+ if (m_windowClass != kModalWindowClass)
+ m_windowAttributes |= NSResizableWindowMask;
+ }
+
+ // Only add extra decorations (well, buttons) for widgets that can have them
+ // and have an actual border we can put them on.
+
+ if(m_windowClass != kModalWindowClass && m_windowClass != kMovableModalWindowClass
+ && m_windowClass != kSheetWindowClass && m_windowClass != kPlainWindowClass
+ && !framelessWindow && m_windowClass != kDrawerWindowClass
+ && m_windowClass != kHelpWindowClass) {
+ if (flags & Qt::WindowMinimizeButtonHint)
+ m_windowAttributes |= NSMiniaturizableWindowMask;
+ if (flags & Qt::WindowSystemMenuHint || flags & Qt::WindowCloseButtonHint)
+ m_windowAttributes |= NSClosableWindowMask;
+ } else {
+ // Clear these hints so that we aren't call them on invalid windows
+ flags &= ~(Qt::WindowMaximizeButtonHint | Qt::WindowMinimizeButtonHint
+ | Qt::WindowCloseButtonHint | Qt::WindowSystemMenuHint);
+ }
+
+ }
+
+ if((popup || type == Qt::Tool) && !window()->isModal())
+ m_windowAttributes |= kWindowHideOnSuspendAttribute;
+ m_windowAttributes |= kWindowLiveResizeAttribute;
+}
+
+/*
+
+*/
+QNSWindow * QCocoaWindow::createWindow()
+{
+ // Determine if we need to add in our "custom window" attribute. Cocoa is rather clever
+ // in deciding if we need the maximize button or not (i.e., it's resizeable, so you
+ // must need a maximize button). So, the only buttons we have control over are the
+ // close and minimize buttons. If someone wants to customize and NOT have the maximize
+ // button, then we have to do our hack. We only do it for these cases because otherwise
+ // the window looks different when activated. This "QtMacCustomizeWindow" attribute is
+ // intruding on a public space and WILL BREAK in the future.
+ // One can hope that there is a more public API available by that time.
+/*
+ Qt::WindowFlags flags = widget ? widget->windowFlags() : Qt::WindowFlags(0);
+ if ((flags & Qt::CustomizeWindowHint)) {
+ if ((flags & (Qt::WindowCloseButtonHint | Qt::WindowSystemMenuHint
+ | Qt::WindowMinimizeButtonHint | Qt::WindowTitleHint))
+ && !(flags & Qt::WindowMaximizeButtonHint))
+ wattr |= QtMacCustomizeWindow;
+ }
+*/
+ NSRect frame = globalGeometry(window()->geometry());
+ QCocoaAutoReleasePool pool;
+ QNSWindow *window;
+
+ switch (m_windowClass) {
+ case kMovableModalWindowClass:
+ case kModalWindowClass:
+ case kSheetWindowClass:
+ case kFloatingWindowClass:
+ case kOverlayWindowClass:
+ case kHelpWindowClass: {
+ NSPanel *panel;
+
+ BOOL needFloating = NO;
+ BOOL worksWhenModal = (this->window()->windowType() == Qt::Popup);
+
+ // Add in the extra flags if necessary.
+ switch (m_windowClass) {
+ case kSheetWindowClass:
+ m_windowAttributes |= NSDocModalWindowMask;
+ break;
+ case kFloatingWindowClass:
+ case kHelpWindowClass:
+ needFloating = YES;
+ m_windowAttributes |= NSUtilityWindowMask;
+ break;
+ default:
+ break;
+ }
+
+ panel = [[NSPanel alloc] initWithContentRect:frame
+ styleMask:m_windowAttributes
+ backing:NSBackingStoreBuffered
+ defer:NO]; // see window case below
+// ### crashes
+// [panel setFloatingPanel:needFloating];
+// [panel setWorksWhenModal:worksWhenModal];
+ window = static_cast<NSWindow *>(panel);
+ break;
+ }
+ default:
+ window = [[QNSWindow alloc] initWithContentRect:frame
+ styleMask:(NSResizableWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSTitledWindowMask)
+ backing:NSBackingStoreBuffered
+ defer:NO]; // Deferring window creation breaks OpenGL (the GL context is set up
+ // before the window is shown and needs a proper window.).
+ break;
+ }
+
+ //qt_syncCocoaTitleBarButtons(window, widget);
+ return window;
+}
+
+// Calculate the global screen geometry for the given local geometry, which
+// might be in the parent window coordinate system.
+NSRect QCocoaWindow::globalGeometry(const QRect localGeometry) const
+{
+ QRect finalGeometry = localGeometry;
+
+ if (QCocoaWindow *parent = parentCocoaWindow()) {
+ QRect parentGeometry = parent->windowGeometry();
+ finalGeometry.adjust(parentGeometry.x(), parentGeometry.y(), parentGeometry.x(), parentGeometry.y());
+
+ // Qt child window geometry assumes that the origin is at the
+ // top-left of the content area of the parent window. The title
+ // bar is not a part of this contet area, but is still included
+ // in the NSWindow height. Move the child window down to acccount
+ // for this if the parent window has a title bar.
+ const int titlebarHeight = 22;
+ if (!(window()->windowFlags() & Qt::FramelessWindowHint))
+ finalGeometry.adjust(0, titlebarHeight, 0, titlebarHeight);
+ }
+
+ // The final "y invert" to get OS X global geometry:
+ QPlatformScreen *onScreen = QPlatformScreen::platformScreenForWindow(window());
+ int flippedY = onScreen->geometry().height() - finalGeometry.y() - finalGeometry.height();
+ return NSMakeRect(finalGeometry.x(), flippedY, finalGeometry.width(), finalGeometry.height());
+}
+
+// Returns the current global screen geometry for the nswindow accociated with this window.
+QRect QCocoaWindow::windowGeometry() const
+{
+ NSRect rect = [m_nsWindow frame];
+ QPlatformScreen *onScreen = QPlatformScreen::platformScreenForWindow(window());
+ int flippedY = onScreen->geometry().height() - rect.origin.y - rect.size.height; // account for nswindow inverted y.
+ QRect qRect = QRect(rect.origin.x, flippedY, rect.size.width, rect.size.height);
+ return qRect;
+}
+
+// Returns a pointer to the parent QCocoaWindow for this window, or 0 if there is none.
+QCocoaWindow *QCocoaWindow::parentCocoaWindow() const
+{
+ if (window() && window()->transientParent()) {
+ return static_cast<QCocoaWindow*>(window()->transientParent()->handle());
+ }
+ return 0;
+}
+
diff --git a/src/plugins/platforms/cocoa/qcocoawindowsurface.h b/src/plugins/platforms/cocoa/qcocoawindowsurface.h
deleted file mode 100644
index 95eea2b7ea..0000000000
--- a/src/plugins/platforms/cocoa/qcocoawindowsurface.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWINDOWSURFACE_COCOA_H
-#define QWINDOWSURFACE_COCOA_H
-
-#include <Cocoa/Cocoa.h>
-
-#include "qcocoawindow.h"
-#include "qnsview.h"
-
-#include <QtGui/private/qwindowsurface_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QCocoaWindowSurface : public QWindowSurface
-{
-public:
- QCocoaWindowSurface(QWidget *window, WId wid);
- ~QCocoaWindowSurface();
-
- QPaintDevice *paintDevice();
- void flush(QWidget *widget, const QRegion &region, const QPoint &offset);
- void resize (const QSize &size);
-
-private:
-
- QCocoaWindow *m_cocoaWindow;
- QImage *m_image;
- QNSView *m_contentView;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/plugins/platforms/cocoa/qcocoawindowsurface.mm b/src/plugins/platforms/cocoa/qcocoawindowsurface.mm
deleted file mode 100644
index 16bb327196..0000000000
--- a/src/plugins/platforms/cocoa/qcocoawindowsurface.mm
+++ /dev/null
@@ -1,103 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qcocoawindowsurface.h"
-
-#include <QtCore/qdebug.h>
-
-#include <QtGui/QPainter>
-
-QT_BEGIN_NAMESPACE
-
-QRect flipedRect(const QRect &sourceRect,int height)
-{
- if (!sourceRect.isValid())
- return QRect();
- QRect flippedRect = sourceRect;
- flippedRect.moveTop(height - sourceRect.y());
- return flippedRect;
-}
-
-QCocoaWindowSurface::QCocoaWindowSurface(QWidget *window, WId wId)
- : QWindowSurface(window)
-{
- m_cocoaWindow = static_cast<QCocoaWindow *>(window->platformWindow());
-
- const QRect geo = window->geometry();
- NSRect rect = NSMakeRect(geo.x(),geo.y(),geo.width(),geo.height());
- m_contentView = [[QNSView alloc] initWithWidget:window];
- m_cocoaWindow->setContentView(m_contentView);
-
- m_image = new QImage(window->size(),QImage::Format_ARGB32);
-}
-
-QCocoaWindowSurface::~QCocoaWindowSurface()
-{
- delete m_image;
-}
-
-QPaintDevice *QCocoaWindowSurface::paintDevice()
-{
- return m_image;
-}
-
-void QCocoaWindowSurface::flush(QWidget *widget, const QRegion &region, const QPoint &offset)
-{
- Q_UNUSED(widget);
- Q_UNUSED(offset);
-
- QRect geo = region.boundingRect();
-
- NSRect rect = NSMakeRect(geo.x(), geo.y(), geo.width(), geo.height());
- [m_contentView displayRect:rect];
-}
-
-void QCocoaWindowSurface::resize(const QSize &size)
-{
- QWindowSurface::resize(size);
- delete m_image;
- m_image = new QImage(size,QImage::Format_ARGB32_Premultiplied);
- NSSize newSize = NSMakeSize(size.width(),size.height());
- [m_contentView setImage:m_image];
-
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qmenu_mac.h b/src/plugins/platforms/cocoa/qmenu_mac.h
new file mode 100644
index 0000000000..f20f82c761
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qmenu_mac.h
@@ -0,0 +1,85 @@
+
+#include <private/qt_mac_p.h>
+#include <QtCore/qpointer.h>
+#include <QtWidgets/qmenu.h>
+#include <QtWidgets/qmenubar.h>
+#include <QtWidgets/qplatformmenu_qpa.h>
+
+@class NSMenuItem;
+class QCocoaMenuAction : public QPlatformMenuAction
+{
+public:
+ QCocoaMenuAction();
+ ~QCocoaMenuAction();
+
+ NSMenuItem *menuItem;
+ uchar ignore_accel : 1;
+ uchar merged : 1;
+ OSMenuRef menu;
+ QPointer<QMenu> qtMenu;
+};
+
+struct QMenuMergeItem
+{
+ inline QMenuMergeItem(NSMenuItem *c, QCocoaMenuAction *a) : menuItem(c), action(a) { }
+ NSMenuItem *menuItem;
+ QCocoaMenuAction *action;
+};
+typedef QList<QMenuMergeItem> QMenuMergeList;
+
+class QCocoaMenu : public QPlatformMenu
+{
+public:
+ QCocoaMenu(QMenu *qtMenu);
+ ~QCocoaMenu();
+
+ OSMenuRef macMenu(OSMenuRef merge = 0);
+ void syncSeparatorsCollapsible(bool collapse);
+ void setMenuEnabled(bool enable);
+
+ void addAction(QAction *action, QAction *before);
+ void syncAction(QAction *action);
+ void removeAction(QAction *action);
+
+ void addAction(QCocoaMenuAction *action, QCocoaMenuAction *before);
+ void syncAction(QCocoaMenuAction *action);
+ void removeAction(QCocoaMenuAction *action);
+ bool merged(const QAction *action) const;
+ QCocoaMenuAction *findAction(QAction *action) const;
+
+ OSMenuRef menu;
+ static QHash<OSMenuRef, OSMenuRef> mergeMenuHash;
+ static QHash<OSMenuRef, QMenuMergeList*> mergeMenuItemsHash;
+ QList<QCocoaMenuAction*> actionItems;
+ QMenu *qtMenu;
+};
+
+class QCocoaMenuBar : public QPlatformMenuBar
+{
+public:
+ QCocoaMenuBar(QMenuBar *qtMenuBar);
+ ~QCocoaMenuBar();
+
+ void handleReparent(QWidget *newParent);
+
+ void addAction(QAction *action, QAction *before);
+ void syncAction(QAction *action);
+ void removeAction(QAction *action);
+
+ void addAction(QCocoaMenuAction *action, QCocoaMenuAction *before);
+ void syncAction(QCocoaMenuAction *action);
+ void removeAction(QCocoaMenuAction *action);
+
+ bool macWidgetHasNativeMenubar(QWidget *widget);
+ void macCreateMenuBar(QWidget *parent);
+ void macDestroyMenuBar();
+ OSMenuRef macMenu();
+ static bool macUpdateMenuBarImmediatly();
+ static void macUpdateMenuBar();
+ QCocoaMenuAction *findAction(QAction *action) const;
+
+ OSMenuRef menu;
+ OSMenuRef apple_menu;
+ QList<QCocoaMenuAction*> actionItems;
+ QMenuBar *qtMenuBar;
+};
diff --git a/src/plugins/platforms/cocoa/qmenu_mac.mm b/src/plugins/platforms/cocoa/qmenu_mac.mm
new file mode 100644
index 0000000000..7ca546dd79
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qmenu_mac.mm
@@ -0,0 +1,1274 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmenu_mac.h"
+
+#include <Cocoa/Cocoa.h>
+
+#include "qmenu.h"
+#include "qhash.h"
+#include <qdebug.h>
+#include "qapplication.h"
+#include "qregexp.h"
+#include "qtoolbar.h"
+#include "qevent.h"
+#include "qstyle.h"
+#include "qwidgetaction.h"
+
+#include <private/qmenu_p.h>
+#include <private/qmenubar_p.h>
+#include <private/qguiapplication_p.h>
+
+#include "qcocoahelpers.h"
+#include "qcocoaapplication.h"
+#include "qcocoamenuloader.h"
+#include "qcocoamenu.h"
+#include "qcocoahelpers.h"
+#include "qcocoaautoreleasepool.h"
+
+QT_BEGIN_NAMESPACE
+
+/*****************************************************************************
+ QMenu debug facilities
+ *****************************************************************************/
+
+/*****************************************************************************
+ QMenu globals
+ *****************************************************************************/
+bool qt_mac_no_menubar_merge = false;
+bool qt_mac_quit_menu_item_enabled = true;
+int qt_mac_menus_open_count = 0;
+
+static OSMenuRef qt_mac_create_menu(QWidget *w);
+
+static struct {
+ QPointer<QMenuBar> qmenubar;
+ bool modal;
+} qt_mac_current_menubar = { 0, false };
+
+
+
+
+/*****************************************************************************
+ Externals
+ *****************************************************************************/
+extern OSViewRef qt_mac_hiview_for(const QWidget *w); //qwidget_mac.cpp
+extern IconRef qt_mac_create_iconref(const QPixmap &px); //qpixmap_mac.cpp
+extern QWidget * mac_keyboard_grabber; //qwidget_mac.cpp
+extern bool qt_sendSpontaneousEvent(QObject*, QEvent*); //qapplication_xxx.cpp
+RgnHandle qt_mac_get_rgn(); //qregion_mac.cpp
+void qt_mac_dispose_rgn(RgnHandle r); //qregion_mac.cpp
+
+/*****************************************************************************
+ QMenu utility functions
+ *****************************************************************************/
+bool qt_mac_watchingAboutToShow(QMenu *menu)
+{
+ return menu; /* && menu->receivers(SIGNAL(aboutToShow()));*/
+}
+
+static int qt_mac_CountMenuItems(OSMenuRef menu)
+{
+ if (menu) {
+ return [menu numberOfItems];
+ }
+ return 0;
+}
+
+void qt_mac_menu_collapseSeparators(NSMenu * theMenu, bool collapse)
+{
+ QCocoaAutoReleasePool pool;
+ OSMenuRef menu = static_cast<OSMenuRef>(theMenu);
+ if (collapse) {
+ bool previousIsSeparator = true; // setting to true kills all the separators placed at the top.
+ NSMenuItem *previousItem = nil;
+
+ NSArray *itemArray = [menu itemArray];
+ for (unsigned int i = 0; i < [itemArray count]; ++i) {
+ NSMenuItem *item = reinterpret_cast<NSMenuItem *>([itemArray objectAtIndex:i]);
+ if ([item isSeparatorItem]) {
+ [item setHidden:previousIsSeparator];
+ }
+
+ if (![item isHidden]) {
+ previousItem = item;
+ previousIsSeparator = ([previousItem isSeparatorItem]);
+ }
+ }
+
+ // We now need to check the final item since we don't want any separators at the end of the list.
+ if (previousItem && previousIsSeparator)
+ [previousItem setHidden:YES];
+ } else {
+ NSArray *itemArray = [menu itemArray];
+ for (unsigned int i = 0; i < [itemArray count]; ++i) {
+ NSMenuItem *item = reinterpret_cast<NSMenuItem *>([itemArray objectAtIndex:i]);
+ if (QAction *action = reinterpret_cast<QAction *>([item tag]))
+ [item setHidden:!action->isVisible()];
+ }
+ }
+}
+
+#ifndef QT_NO_TRANSLATION
+static const char *application_menu_strings[] = {
+ QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Services"),
+ QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Hide %1"),
+ QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Hide Others"),
+ QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Show All"),
+ QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Preferences..."),
+ QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Quit %1"),
+ QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","About %1")
+ };
+
+QString qt_mac_applicationmenu_string(int type)
+{
+ QString menuString = QString::fromLatin1(application_menu_strings[type]);
+ QString translated = qApp->translate("QMenuBar", application_menu_strings[type]);
+ if (translated != menuString)
+ return translated;
+ else
+ return qApp->translate("MAC_APPLICATION_MENU",
+ application_menu_strings[type]);
+}
+#endif
+
+
+static quint32 constructModifierMask(quint32 accel_key)
+{
+ quint32 ret = 0;
+ const bool dontSwap = qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta);
+ if ((accel_key & Qt::CTRL) == Qt::CTRL)
+ ret |= (dontSwap ? NSControlKeyMask : NSCommandKeyMask);
+ if ((accel_key & Qt::META) == Qt::META)
+ ret |= (dontSwap ? NSCommandKeyMask : NSControlKeyMask);
+ if ((accel_key & Qt::ALT) == Qt::ALT)
+ ret |= NSAlternateKeyMask;
+ if ((accel_key & Qt::SHIFT) == Qt::SHIFT)
+ ret |= NSShiftKeyMask;
+ return ret;
+}
+
+static void cancelAllMenuTracking()
+{
+ QCocoaAutoReleasePool pool;
+ NSMenu *mainMenu = [NSApp mainMenu];
+ [mainMenu cancelTracking];
+ for (NSMenuItem *item in [mainMenu itemArray]) {
+ if ([item submenu]) {
+ [[item submenu] cancelTracking];
+ }
+ }
+}
+
+static bool actualMenuItemVisibility(const QCocoaMenuBar *mbp,
+ const QCocoaMenuAction *action)
+{
+ bool visible = action->action->isVisible();
+ if (visible && action->action->text() == QString(QChar(0x14)))
+ return false;
+
+ if (visible && action->action->menu() && !action->action->menu()->actions().isEmpty() &&
+/* ### !qt_mac_CountMenuItems(cocoaMenu->macMenu(mbp->apple_menu)) &&*/
+ !qt_mac_watchingAboutToShow(action->action->menu())) {
+ return false;
+ }
+ return visible;
+}
+
+static inline void syncNSMenuItemVisiblity(NSMenuItem *menuItem, bool actionVisibility)
+{
+ [menuItem setHidden:NO];
+ [menuItem setHidden:YES];
+ [menuItem setHidden:!actionVisibility];
+}
+
+static inline void syncNSMenuItemEnabled(NSMenuItem *menuItem, bool enabled)
+{
+ [menuItem setEnabled:NO];
+ [menuItem setEnabled:YES];
+ [menuItem setEnabled:enabled];
+}
+
+static inline void syncMenuBarItemsVisiblity(const QCocoaMenuBar *mac_menubar)
+{
+ const QList<QCocoaMenuAction *> &menubarActions = mac_menubar->actionItems;
+ for (int i = 0; i < menubarActions.size(); ++i) {
+ const QCocoaMenuAction *action = menubarActions.at(i);
+ syncNSMenuItemVisiblity(action->menuItem, actualMenuItemVisibility(mac_menubar, action));
+ }
+}
+
+static inline QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *getMenuLoader()
+{
+ return [NSApp QT_MANGLE_NAMESPACE(qt_qcocoamenuLoader)];
+}
+
+static NSMenuItem *createNSMenuItem(const QString &title)
+{
+ NSMenuItem *item = [[NSMenuItem alloc]
+ initWithTitle:qt_mac_QStringToNSString(title)
+ action:@selector(qtDispatcherToQAction:) keyEquivalent:@""];
+ [item setTarget:nil];
+ return item;
+}
+
+// helper that recurses into a menu structure and en/dis-ables them
+void qt_mac_set_modal_state_helper_recursive(OSMenuRef menu, OSMenuRef merge, bool on)
+{
+ bool modalWindowOnScreen = qApp->activeModalWidget() != 0;
+ for (NSMenuItem *item in [menu itemArray]) {
+ OSMenuRef submenu = [item submenu];
+ if (submenu != merge) {
+ if (submenu)
+ qt_mac_set_modal_state_helper_recursive(submenu, merge, on);
+ if (!on) {
+ // The item should follow what the QAction has.
+ if ([item tag]) {
+ QAction *action = reinterpret_cast<QAction *>([item tag]);
+ syncNSMenuItemEnabled(item, action->isEnabled());
+ } else {
+ syncNSMenuItemEnabled(item, YES);
+ }
+ // We sneak in some extra code here to handle a menu problem:
+ // If there is no window on screen, we cannot set 'nil' as
+ // menu item target, because then cocoa will disable the item
+ // (guess it assumes that there will be no first responder to
+ // catch the trigger anyway?) OTOH, If we have a modal window,
+ // then setting the menu loader as target will make cocoa not
+ // deliver the trigger because the loader is then seen as modally
+ // shaddowed). So either way there are shortcomings. Instead, we
+ // decide the target as late as possible:
+ [item setTarget:modalWindowOnScreen ? nil : getMenuLoader()];
+ } else {
+ syncNSMenuItemEnabled(item, NO);
+ }
+ }
+ }
+}
+
+//toggling of modal state
+static void qt_mac_set_modal_state(OSMenuRef menu, bool on)
+{
+ OSMenuRef merge = QCocoaMenu::mergeMenuHash.value(menu);
+ qt_mac_set_modal_state_helper_recursive(menu, merge, on);
+ // I'm ignoring the special items now, since they should get handled via a syncAction()
+}
+
+bool qt_mac_menubar_is_open()
+{
+ return qt_mac_menus_open_count > 0;
+}
+
+QCocoaMenuAction::~QCocoaMenuAction()
+{
+ [menu release];
+ // Update the menu item if this action still owns it. For some items
+ // (like 'Quit') ownership will be transferred between all menu bars...
+ if (action && action.data() == reinterpret_cast<QAction *>([menuItem tag])) {
+ QAction::MenuRole role = action->menuRole();
+ // Check if the item is owned by Qt, and should be hidden to keep it from causing
+ // problems. Do it for everything but the quit menu item since that should always
+ // be visible.
+ if (role > QAction::ApplicationSpecificRole && role < QAction::QuitRole) {
+ [menuItem setHidden:YES];
+ } else if (role == QAction::TextHeuristicRole
+ && menuItem != [getMenuLoader() quitMenuItem]) {
+ [menuItem setHidden:YES];
+ }
+ [menuItem setTag:nil];
+ }
+ [menuItem release];
+}
+
+static NSMenuItem *qt_mac_menu_merge_action(OSMenuRef merge, QCocoaMenuAction *action)
+{
+ if (qt_mac_no_menubar_merge || action->action->menu() || action->action->isSeparator()
+ || action->action->menuRole() == QAction::NoRole)
+ return 0;
+
+ QString t = qt_mac_removeMnemonics(action->action->text().toLower());
+ int st = t.lastIndexOf(QLatin1Char('\t'));
+ if (st != -1)
+ t.remove(st, t.length()-st);
+ t.replace(QRegExp(QString::fromLatin1("\\.*$")), QLatin1String("")); //no ellipses
+ //now the fun part
+ NSMenuItem *ret = 0;
+ QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader();
+
+ switch (action->action->menuRole()) {
+ case QAction::NoRole:
+ ret = 0;
+ break;
+ case QAction::ApplicationSpecificRole:
+ ret = [loader appSpecificMenuItem];
+ break;
+ case QAction::AboutRole:
+ ret = [loader aboutMenuItem];
+ break;
+ case QAction::AboutQtRole:
+ ret = [loader aboutQtMenuItem];
+ break;
+ case QAction::QuitRole:
+ ret = [loader quitMenuItem];
+ break;
+ case QAction::PreferencesRole:
+ ret = [loader preferencesMenuItem];
+ break;
+ case QAction::TextHeuristicRole: {
+ QString aboutString = QMenuBar::tr("About").toLower();
+ if (t.startsWith(aboutString) || t.endsWith(aboutString)) {
+ if (t.indexOf(QRegExp(QString::fromLatin1("qt$"), Qt::CaseInsensitive)) == -1) {
+ ret = [loader aboutMenuItem];
+ } else {
+ ret = [loader aboutQtMenuItem];
+ }
+ } else if (t.startsWith(QMenuBar::tr("Config").toLower())
+ || t.startsWith(QMenuBar::tr("Preference").toLower())
+ || t.startsWith(QMenuBar::tr("Options").toLower())
+ || t.startsWith(QMenuBar::tr("Setting").toLower())
+ || t.startsWith(QMenuBar::tr("Setup").toLower())) {
+ ret = [loader preferencesMenuItem];
+ } else if (t.startsWith(QMenuBar::tr("Quit").toLower())
+ || t.startsWith(QMenuBar::tr("Exit").toLower())) {
+ ret = [loader quitMenuItem];
+ }
+ }
+ break;
+ }
+
+ if (QMenuMergeList *list = QCocoaMenu::mergeMenuItemsHash.value(merge)) {
+ for(int i = 0; i < list->size(); ++i) {
+ const QMenuMergeItem &item = list->at(i);
+ if (item.menuItem == ret && item.action)
+ return 0;
+ }
+ }
+
+ return ret;
+}
+
+static QString qt_mac_menu_merge_text(QCocoaMenuAction *action)
+{
+ QString ret;
+ extern QString qt_mac_applicationmenu_string(int type);
+ QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader();
+ if (action->action->menuRole() == QAction::ApplicationSpecificRole)
+ ret = action->action->text();
+ else if (action->menuItem == [loader aboutMenuItem]) {
+ ret = qt_mac_applicationmenu_string(6).arg(qt_mac_applicationName());
+ } else if (action->menuItem == [loader aboutQtMenuItem]) {
+ if (action->action->text() == QString("About Qt"))
+ ret = QMenuBar::tr("About Qt");
+ else
+ ret = action->action->text();
+ } else if (action->menuItem == [loader preferencesMenuItem]) {
+ ret = qt_mac_applicationmenu_string(4);
+ } else if (action->menuItem == [loader quitMenuItem]) {
+ ret = qt_mac_applicationmenu_string(5).arg(qt_mac_applicationName());
+ }
+ return ret;
+}
+
+static QKeySequence qt_mac_menu_merge_accel(QCocoaMenuAction *action)
+{
+ QKeySequence ret;
+ QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader();
+ if (action->action->menuRole() == QAction::ApplicationSpecificRole)
+ ret = action->action->shortcut();
+ else if (action->menuItem == [loader preferencesMenuItem])
+ ret = QKeySequence(QKeySequence::Preferences);
+ else if (action->menuItem == [loader quitMenuItem])
+ ret = QKeySequence(QKeySequence::Quit);
+ return ret;
+}
+
+void Q_WIDGETS_EXPORT qt_mac_set_menubar_icons(bool b)
+{ QApplication::instance()->setAttribute(Qt::AA_DontShowIconsInMenus, !b); }
+void Q_WIDGETS_EXPORT qt_mac_set_native_menubar(bool b)
+{ QApplication::instance()->setAttribute(Qt::AA_DontUseNativeMenuBar, !b); }
+void Q_WIDGETS_EXPORT qt_mac_set_menubar_merge(bool b) { qt_mac_no_menubar_merge = !b; }
+
+/*****************************************************************************
+ QMenu bindings
+ *****************************************************************************/
+
+QCocoaMenuAction::QCocoaMenuAction()
+ : menuItem(0)
+ , ignore_accel(0), merged(0), menu(0)
+{
+
+}
+
+QCocoaMenu::QCocoaMenu(QMenu *a_qtMenu) : menu(0), qtMenu(a_qtMenu)
+{
+}
+
+QCocoaMenu::~QCocoaMenu()
+{
+ QCocoaAutoReleasePool pool;
+ while (actionItems.size()) {
+ QCocoaMenuAction *action = static_cast<QCocoaMenuAction *>(actionItems.takeFirst());
+ if (QMenuMergeList *list = mergeMenuItemsHash.value(action->menu)) {
+ int i = 0;
+ while (i < list->size()) {
+ const QMenuMergeItem &item = list->at(i);
+ if (item.action == action)
+ list->removeAt(i);
+ else
+ ++i;
+ }
+ }
+ delete action;
+ }
+ mergeMenuHash.remove(menu);
+ mergeMenuItemsHash.remove(menu);
+ [menu release];
+}
+
+
+void QCocoaMenu::addAction(QAction *a, QAction *before)
+{
+ QCocoaMenuAction *action = new QCocoaMenuAction;
+ action->action = a;
+ action->ignore_accel = 0;
+ action->merged = 0;
+ action->menu = 0;
+
+ QCocoaMenuAction *cocoaBefore = findAction(before);
+ addAction(action, cocoaBefore);
+}
+
+
+void QCocoaMenu::addAction(QCocoaMenuAction *action, QCocoaMenuAction *before)
+{
+ QCocoaAutoReleasePool pool;
+ if (!action)
+ return;
+ int before_index = actionItems.indexOf(before);
+ if (before_index < 0) {
+ before = 0;
+ before_index = actionItems.size();
+ }
+ actionItems.insert(before_index, action);
+
+ [menu retain];
+ [action->menu release];
+ action->menu = menu;
+
+ /* When the action is considered a mergable action it
+ will stay that way, until removed.. */
+ if (!qt_mac_no_menubar_merge) {
+ OSMenuRef merge = QCocoaMenu::mergeMenuHash.value(menu);
+ if (merge) {
+ if (NSMenuItem *cmd = qt_mac_menu_merge_action(merge, action)) {
+ action->merged = 1;
+ [merge retain];
+ [action->menu release];
+ action->menu = merge;
+ [cmd retain];
+ [cmd setAction:@selector(qtDispatcherToQAction:)];
+ [cmd setTarget:nil];
+ [action->menuItem release];
+ action->menuItem = cmd;
+ QMenuMergeList *list = QCocoaMenu::mergeMenuItemsHash.value(merge);
+ if (!list) {
+ list = new QMenuMergeList;
+ QCocoaMenu::mergeMenuItemsHash.insert(merge, list);
+ }
+ list->append(QMenuMergeItem(cmd, action));
+ }
+ }
+ }
+
+ NSMenuItem *newItem = action->menuItem;
+ if (newItem == 0) {
+ newItem = createNSMenuItem(action->action->text());
+ action->menuItem = newItem;
+ if (before) {
+ [menu insertItem:newItem atIndex:qMax(before_index, 0)];
+ } else {
+ [menu addItem:newItem];
+ }
+ } else {
+ [newItem setEnabled:YES];
+ // ###
+ //[newItem setEnabled:!QApplicationPrivate::modalState()];
+
+ }
+ [newItem setTag:long(static_cast<QAction *>(action->action))];
+ syncAction(action);
+}
+
+void QCocoaMenu::syncAction(QAction *a)
+{
+ syncAction(findAction(a));
+}
+
+void QCocoaMenu::removeAction(QAction *a)
+{
+ removeAction(findAction(a));
+}
+
+QCocoaMenuAction *QCocoaMenu::findAction(QAction *action) const
+{
+ for (int i = 0; i < actionItems.size(); i++) {
+ QCocoaMenuAction *act = actionItems[i];
+ if (action == act->action)
+ return act;
+ }
+ return 0;
+}
+
+
+// return an autoreleased string given a QKeySequence (currently only looks at the first one).
+NSString *keySequenceToKeyEqivalent(const QKeySequence &accel)
+{
+ quint32 accel_key = (accel[0] & ~(Qt::MODIFIER_MASK | Qt::UNICODE_ACCEL));
+ QChar cocoa_key = qt_mac_qtKey2CocoaKey(Qt::Key(accel_key));
+ if (cocoa_key.isNull())
+ cocoa_key = QChar(accel_key).toLower().unicode();
+ return [NSString stringWithCharacters:&cocoa_key.unicode() length:1];
+}
+
+// return the cocoa modifier mask for the QKeySequence (currently only looks at the first one).
+NSUInteger keySequenceModifierMask(const QKeySequence &accel)
+{
+ return constructModifierMask(accel[0]);
+}
+
+void QCocoaMenu::syncAction(QCocoaMenuAction *action)
+{
+ if (!action)
+ return;
+
+ NSMenuItem *item = action->menuItem;
+ if (!item)
+ return;
+
+ QCocoaAutoReleasePool pool;
+ NSMenu *menu = [item menu];
+ bool actionVisible = action->action->isVisible();
+ [item setHidden:!actionVisible];
+ if (!actionVisible)
+ return;
+
+ int itemIndex = [menu indexOfItem:item];
+ Q_ASSERT(itemIndex != -1);
+ if (action->action->isSeparator()) {
+ action->menuItem = [NSMenuItem separatorItem];
+ [action->menuItem retain];
+ [menu insertItem: action->menuItem atIndex:itemIndex];
+ [menu removeItem:item];
+ [item release];
+ item = action->menuItem;
+ return;
+ } else if ([item isSeparatorItem]) {
+ // I'm no longer a separator...
+ action->menuItem = createNSMenuItem(action->action->text());
+ [menu insertItem:action->menuItem atIndex:itemIndex];
+ [menu removeItem:item];
+ [item release];
+ item = action->menuItem;
+ }
+
+ //find text (and accel)
+ action->ignore_accel = 0;
+ QString text = action->action->text();
+ QKeySequence accel = action->action->shortcut();
+ {
+ int st = text.lastIndexOf(QLatin1Char('\t'));
+ if (st != -1) {
+ action->ignore_accel = 1;
+ accel = QKeySequence(text.right(text.length()-(st+1)));
+ text.remove(st, text.length()-st);
+ }
+ }
+ {
+ QString cmd_text = qt_mac_menu_merge_text(action);
+ if (!cmd_text.isEmpty()) {
+ text = cmd_text;
+ accel = qt_mac_menu_merge_accel(action);
+ }
+ }
+ // Show multiple key sequences as part of the menu text.
+ if (accel.count() > 1)
+ text += QLatin1String(" (") + accel.toString(QKeySequence::NativeText) + QLatin1String(")");
+
+#if 0
+ QString finalString = qt_mac_removeMnemonics(text);
+#else
+ QString finalString = qt_mac_removeMnemonics(text);
+#endif
+ // Cocoa Font and title
+ if (action->action->font().resolve()) {
+ const QFont &actionFont = action->action->font();
+ NSFont *customMenuFont = [NSFont fontWithName:qt_mac_QStringToNSString(actionFont.family())
+ size:actionFont.pointSize()];
+ NSArray *keys = [NSArray arrayWithObjects:NSFontAttributeName, nil];
+ NSArray *objects = [NSArray arrayWithObjects:customMenuFont, nil];
+ NSDictionary *attributes = [NSDictionary dictionaryWithObjects:objects forKeys:keys];
+ NSAttributedString *str = [[[NSAttributedString alloc] initWithString:qt_mac_QStringToNSString(finalString)
+ attributes:attributes] autorelease];
+ [item setAttributedTitle: str];
+ } else {
+ [item setTitle: qt_mac_QStringToNSString(finalString)];
+ }
+
+ if (action->action->menuRole() == QAction::AboutRole || action->action->menuRole() == QAction::QuitRole)
+ [item setTitle:qt_mac_QStringToNSString(text)];
+ else
+ [item setTitle:qt_mac_QStringToNSString(qt_mac_removeMnemonics(text))];
+
+ // Cocoa Enabled
+ [item setEnabled: action->action->isEnabled()];
+
+ // Cocoa icon
+ NSImage *nsimage = 0;
+ if (!action->action->icon().isNull() && action->action->isIconVisibleInMenu()) {
+ nsimage = static_cast<NSImage *>(qt_mac_create_nsimage(action->action->icon().pixmap(16, QIcon::Normal)));
+ }
+ [item setImage:nsimage];
+ [nsimage release];
+
+ if (action->action->menu()) { //submenu
+ QCocoaMenu *cocoaMenu = static_cast<QCocoaMenu *>(action->action->menu()->platformMenu());
+ NSMenu *subMenu = cocoaMenu->macMenu();
+ if ([subMenu supermenu] && [subMenu supermenu] != [item menu]) {
+ // The menu is already a sub-menu of another one. Cocoa will throw an exception,
+ // in such cases. For the time being, a new QMenu with same set of actions is the
+ // only workaround.
+ action->action->setEnabled(false);
+ } else {
+ [item setSubmenu:subMenu];
+ }
+ } else { //respect some other items
+ [item setSubmenu:0];
+ // No key equivalent set for multiple key QKeySequence.
+ if (accel.count() == 1) {
+ [item setKeyEquivalent:keySequenceToKeyEqivalent(accel)];
+ [item setKeyEquivalentModifierMask:keySequenceModifierMask(accel)];
+ } else {
+ [item setKeyEquivalent:@""];
+ [item setKeyEquivalentModifierMask:NSCommandKeyMask];
+ }
+ }
+ //mark glyph
+ [item setState:action->action->isChecked() ? NSOnState : NSOffState];
+}
+
+void QCocoaMenu::removeAction(QCocoaMenuAction *action)
+{
+ if (!action)
+ return;
+ QCocoaAutoReleasePool pool;
+ if (action->merged) {
+ if (reinterpret_cast<QAction *>([action->menuItem tag]) == action->action) {
+ QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader();
+ [action->menuItem setEnabled:false];
+ if (action->menuItem != [loader quitMenuItem]
+ && action->menuItem != [loader preferencesMenuItem]) {
+ [[action->menuItem menu] removeItem:action->menuItem];
+ }
+ }
+ } else {
+ [[action->menuItem menu] removeItem:action->menuItem];
+ }
+ actionItems.removeAll(action);
+}
+
+OSMenuRef QCocoaMenu::macMenu(OSMenuRef merge)
+{
+ if (menu)
+ return menu;
+ menu = qt_mac_create_menu(qtMenu);
+ if (merge) {
+ mergeMenuHash.insert(menu, merge);
+ }
+ QList<QAction*> items = qtMenu->actions();
+ for(int i = 0; i < items.count(); i++)
+ addAction(items[i], 0);
+ syncSeparatorsCollapsible(qtMenu->separatorsCollapsible());
+ return menu;
+}
+
+/*!
+ \internal
+*/
+void
+QCocoaMenu::syncSeparatorsCollapsible(bool collapse)
+{
+ qt_mac_menu_collapseSeparators(menu, collapse);
+}
+
+/*!
+ \internal
+*/
+void QCocoaMenu::setMenuEnabled(bool enable)
+{
+ QCocoaAutoReleasePool pool;
+ if (enable) {
+ for (int i = 0; i < actionItems.count(); ++i) {
+ QCocoaMenuAction *menuItem = static_cast<QCocoaMenuAction *>(actionItems.at(i));
+ if (menuItem && menuItem->action && menuItem->action->isEnabled()) {
+ [menuItem->menuItem setEnabled:true];
+ }
+ }
+ } else {
+ NSMenu *menu = menu;
+ for (NSMenuItem *item in [menu itemArray]) {
+ [item setEnabled:false];
+ }
+ }
+}
+
+/*!
+ \internal
+
+ This function will return the OSMenuRef used to create the native menu bar
+ bindings.
+
+ If Qt is built against Carbon, the OSMenuRef is a MenuRef that can be used
+ with Carbon's Menu Manager API.
+
+ If Qt is built against Cocoa, the OSMenuRef is a NSMenu pointer.
+
+ \warning This function is not portable.
+
+ \sa QMenuBar::macMenu()
+*/
+/// OSMenuRef QMenu::macMenu(OSMenuRef merge) { return d_func()->macMenu(merge); }
+
+/*****************************************************************************
+ QMenuBar bindings
+ *****************************************************************************/
+typedef QHash<QWidget *, QMenuBar *> MenuBarHash;
+Q_GLOBAL_STATIC(MenuBarHash, menubars)
+static QMenuBar *fallback = 0;
+
+QCocoaMenuBar::QCocoaMenuBar(QMenuBar *a_qtMenuBar) : menu(0), apple_menu(0), qtMenuBar(a_qtMenuBar)
+{
+ macCreateMenuBar(qtMenuBar->parentWidget());
+}
+
+QCocoaMenuBar::~QCocoaMenuBar()
+{
+ for(QList<QCocoaMenuAction*>::Iterator it = actionItems.begin(); it != actionItems.end(); ++it)
+ delete (*it);
+ [apple_menu release];
+ [menu release];
+}
+void QCocoaMenuBar::handleReparent(QWidget *newParent)
+{
+ if (macWidgetHasNativeMenubar(newParent)) {
+ // If the new parent got a native menubar from before, keep that
+ // menubar rather than replace it with this one (because a parents
+ // menubar has precedence over children menubars).
+ macDestroyMenuBar();
+ macCreateMenuBar(newParent);
+ }
+
+}
+
+void QCocoaMenuBar::addAction(QAction *action, QAction *beforeAction)
+{
+ if (action->isSeparator() || !menu)
+ return;
+ QCocoaMenuAction *cocoaAction = new QCocoaMenuAction;
+ cocoaAction->action = action;
+ cocoaAction->ignore_accel = 1;
+ QCocoaMenuAction *cocoaBeforeAction = findAction(beforeAction);
+ addAction(cocoaAction, cocoaBeforeAction);
+}
+
+void QCocoaMenuBar::addAction(QCocoaMenuAction *action, QCocoaMenuAction *before)
+{
+ if (!action || !menu)
+ return;
+
+ int before_index = actionItems.indexOf(before);
+ if (before_index < 0) {
+ before = 0;
+ before_index = actionItems.size();
+ }
+ actionItems.insert(before_index, action);
+
+ MenuItemIndex index = actionItems.size()-1;
+
+ action->menu = menu;
+ QCocoaAutoReleasePool pool;
+ [action->menu retain];
+ NSMenuItem *newItem = createNSMenuItem(action->action->text());
+ action->menuItem = newItem;
+
+ if (before) {
+ [menu insertItem:newItem atIndex:qMax(1, before_index + 1)];
+ index = before_index;
+ } else {
+ [menu addItem:newItem];
+ }
+ [newItem setTag:long(static_cast<QAction *>(action->action))];
+ syncAction(action);
+}
+
+
+void QCocoaMenuBar::syncAction(QCocoaMenuAction *action)
+{
+ if (!action || !menu)
+ return;
+
+ QCocoaAutoReleasePool pool;
+ NSMenuItem *item = action->menuItem;
+
+ OSMenuRef submenu = 0;
+ bool release_submenu = false;
+ if (action->action->menu()) {
+ QCocoaMenu *cocoaMenu = static_cast<QCocoaMenu *>(action->action->menu()->platformMenu());
+ if (!cocoaMenu) {
+
+ }
+
+ if ((submenu = cocoaMenu->macMenu(apple_menu))) {
+ if ([submenu supermenu] && [submenu supermenu] != [item menu])
+ return;
+ else
+ [item setSubmenu:submenu];
+ }
+ }
+
+ if (submenu) {
+ bool visible = actualMenuItemVisibility(this, action);
+ [item setSubmenu: submenu];
+ [submenu setTitle:qt_mac_QStringToNSString(qt_mac_removeMnemonics(action->action->text()))];
+ syncNSMenuItemVisiblity(item, visible);
+ if (release_submenu) { //no pointers to it
+ [submenu release];
+ }
+ } else {
+ qWarning("QMenu: No OSMenuRef created for popup menu");
+ }
+}
+
+
+void QCocoaMenuBar::removeAction(QCocoaMenuAction *action)
+{
+ if (!action || !menu)
+ return;
+ QCocoaAutoReleasePool pool;
+ [action->menu removeItem:action->menuItem];
+ actionItems.removeAll(action);
+}
+
+void QCocoaMenuBar::syncAction(QAction *a)
+{
+ syncAction(findAction(a));
+}
+
+void QCocoaMenuBar::removeAction(QAction *a)
+{
+ removeAction(findAction(a));
+}
+
+QCocoaMenuAction *QCocoaMenuBar::findAction(QAction *action) const
+{
+ for (int i = 0; i < actionItems.size(); i++) {
+ QCocoaMenuAction *act = actionItems[i];
+ if (action == act->action)
+ return act;
+ }
+ return 0;
+}
+
+bool QCocoaMenuBar::macWidgetHasNativeMenubar(QWidget *widget)
+{
+ // This function is different from q->isNativeMenuBar(), as
+ // it returns true only if a native menu bar is actually
+ // _created_.
+ if (!widget)
+ return false;
+ return menubars()->contains(widget->window());
+}
+
+void QCocoaMenuBar::macCreateMenuBar(QWidget *parent)
+{
+ static int dontUseNativeMenuBar = -1;
+ // We call the isNativeMenuBar function here
+ // because that will make sure that local overrides
+ // are dealt with correctly. q->isNativeMenuBar() will, if not
+ // overridden, depend on the attribute Qt::AA_DontUseNativeMenuBar:
+ bool qt_mac_no_native_menubar = !qtMenuBar->isNativeMenuBar();
+ if (qt_mac_no_native_menubar == false && dontUseNativeMenuBar < 0) {
+ // The menubar is set to be native. Let's check (one time only
+ // for all menubars) if this is OK with the rest of the environment.
+ // As a result, Qt::AA_DontUseNativeMenuBar is set. NB: the application
+ // might still choose to not respect, or change, this flag.
+ bool isPlugin = QApplication::testAttribute(Qt::AA_MacPluginApplication);
+ bool environmentSaysNo = !qgetenv("QT_MAC_NO_NATIVE_MENUBAR").isEmpty();
+ dontUseNativeMenuBar = isPlugin || environmentSaysNo;
+ QApplication::instance()->setAttribute(Qt::AA_DontUseNativeMenuBar, dontUseNativeMenuBar);
+ qt_mac_no_native_menubar = !qtMenuBar->isNativeMenuBar();
+ }
+ if (qt_mac_no_native_menubar == false) {
+ // INVARIANT: Use native menubar.
+ macUpdateMenuBar();
+ if (!parent && !fallback) {
+ fallback = qtMenuBar;
+ } else if (parent && parent->isWindow()) {
+ menubars()->insert(qtMenuBar->window(), qtMenuBar);
+ }
+ }
+}
+
+void QCocoaMenuBar::macDestroyMenuBar()
+{
+ QCocoaAutoReleasePool pool;
+ if (fallback == qtMenuBar)
+ fallback = 0;
+ QWidget *tlw = qtMenuBar->window();
+ menubars()->remove(tlw);
+
+ if (!qt_mac_current_menubar.qmenubar || qt_mac_current_menubar.qmenubar == qtMenuBar) {
+ QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader();
+ [loader removeActionsFromAppMenu];
+ QCocoaMenuBar::macUpdateMenuBar();
+ }
+}
+
+OSMenuRef QCocoaMenuBar::macMenu()
+{
+ if (!qtMenuBar->isNativeMenuBar()) {
+ return 0;
+ } else if (!menu) {
+ menu = qt_mac_create_menu(qtMenuBar);
+ ProcessSerialNumber mine, front;
+ if (GetCurrentProcess(&mine) == noErr && GetFrontProcess(&front) == noErr) {
+ if (!qt_mac_no_menubar_merge && !apple_menu) {
+ apple_menu = qt_mac_create_menu(qtMenuBar);
+ [apple_menu setTitle:qt_mac_QStringToNSString(QString(QChar(0x14)))];
+ NSMenuItem *apple_menuItem = [[NSMenuItem alloc] init];
+ [apple_menuItem setSubmenu:menu];
+ [apple_menu addItem:apple_menuItem];
+ [apple_menuItem release];
+ }
+ if (apple_menu) {
+ QCocoaMenu::mergeMenuHash.insert(menu, apple_menu);
+ }
+ QList<QAction*> items = qtMenuBar->actions();
+ for(int i = 0; i < items.count(); i++)
+ addAction(items[i], 0);
+ }
+ }
+ return menu;
+}
+
+/*!
+ \internal
+
+ This function will return the OSMenuRef used to create the native menu bar
+ bindings. This OSMenuRef is then set as the root menu for the Menu
+ Manager.
+
+ \warning This function is not portable.
+
+ \sa QMenu::macMenu()
+*/
+//OSMenuRef QMenuBar::macMenu() { return d_func()->macMenu(); }
+
+/* !
+ \internal
+ Ancestor function that crosses windows (QWidget::isAncestorOf
+ only considers widgets within the same window).
+*/
+static bool qt_mac_is_ancestor(QWidget* possibleAncestor, QWidget *child)
+{
+ if (!possibleAncestor)
+ return false;
+
+ QWidget * current = child->parentWidget();
+ while (current != 0) {
+ if (current == possibleAncestor)
+ return true;
+ current = current->parentWidget();
+ }
+ return false;
+}
+
+/* !
+ \internal
+ Returns true if the entries of menuBar should be disabled,
+ based on the modality type of modalWidget.
+*/
+static bool qt_mac_should_disable_menu(QMenuBar *menuBar)
+{
+ QWidget *modalWidget = qApp->activeModalWidget();
+ if (!modalWidget)
+ return false;
+
+ if (menuBar && menuBar == menubars()->value(modalWidget))
+ // The menu bar is owned by the modal widget.
+ // In that case we should enable it:
+ return false;
+
+ // When there is an application modal window on screen, the entries of
+ // the menubar should be disabled. The exception in Qt is that if the
+ // modal window is the only window on screen, then we enable the menu bar.
+ QWidget *w = modalWidget;
+ QWidgetList topLevelWidgets = QApplication::topLevelWidgets();
+ while (w) {
+ if (w->isVisible() && w->windowModality() == Qt::ApplicationModal) {
+ for (int i=0; i<topLevelWidgets.size(); ++i) {
+ QWidget *top = topLevelWidgets.at(i);
+ if (w != top && top->isVisible()) {
+ // INVARIANT: we found another visible window
+ // on screen other than our modalWidget. We therefore
+ // disable the menu bar to follow normal modality logic:
+ return true;
+ }
+ }
+ // INVARIANT: We have only one window on screen that happends
+ // to be application modal. We choose to enable the menu bar
+ // in that case to e.g. enable the quit menu item.
+ return false;
+ }
+ w = w->parentWidget();
+ }
+
+ // INVARIANT: modalWidget is window modal. Disable menu entries
+ // if the menu bar belongs to an ancestor of modalWidget. If menuBar
+ // is nil, we understand it as the default menu bar set by the nib:
+ return menuBar ? qt_mac_is_ancestor(menuBar->parentWidget(), modalWidget) : false;
+}
+
+static QWidget *findWindowThatShouldDisplayMenubar()
+{
+ QWidget *w = qApp->activeWindow();
+
+ if (!w) {
+ // We have no active window on screen. Try to
+ // find a window from the list of top levels:
+ QWidgetList tlws = QApplication::topLevelWidgets();
+ for(int i = 0; i < tlws.size(); ++i) {
+ QWidget *tlw = tlws.at(i);
+ if ((tlw->isVisible() && tlw->windowType() != Qt::Tool &&
+ tlw->windowType() != Qt::Popup)) {
+ w = tlw;
+ break;
+ }
+ }
+ }
+
+ return w;
+}
+
+static QMenuBar *findMenubarForWindow(QWidget *w)
+{
+ QMenuBar *mb = 0;
+ if (w) {
+ mb = menubars()->value(w);
+
+#if 0
+// ###
+//#ifndef QT_NO_MAINWINDOW
+ QDockWidget *dw = qobject_cast<QDockWidget *>(w);
+ if (!mb && dw) {
+ QMainWindow *mw = qobject_cast<QMainWindow *>(dw->parentWidget());
+ if (mw && (mb = menubars()->value(mw)))
+ w = mw;
+ }
+#endif
+ while(w && !mb)
+ mb = menubars()->value((w = w->parentWidget()));
+ }
+
+ if (!mb) {
+ // We could not find a menu bar for the window. Lets
+ // check if we have a global (parentless) menu bar instead:
+ mb = fallback;
+ }
+
+ return mb;
+}
+
+void qt_mac_clear_menubar()
+{
+ if (QApplication::testAttribute(Qt::AA_MacPluginApplication))
+ return;
+
+ QCocoaAutoReleasePool pool;
+ QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader();
+ NSMenu *menu = [loader menu];
+ [loader ensureAppMenuInMenu:menu];
+ [NSApp setMainMenu:menu];
+ const bool modal = qt_mac_should_disable_menu(0);
+ if (qt_mac_current_menubar.qmenubar || modal != qt_mac_current_menubar.modal)
+ qt_mac_set_modal_state(menu, modal);
+ qt_mac_current_menubar.qmenubar = 0;
+ qt_mac_current_menubar.modal = modal;
+}
+
+/*!
+ \internal
+
+ This function will update the current menu bar and set it as the
+ active menu bar in the Menu Manager.
+
+ \warning This function is not portable.
+*/
+void QCocoaMenuBar::macUpdateMenuBar()
+{
+ [getMenuLoader() performSelectorOnMainThread: @selector(qtUpdateMenubar) withObject: nil waitUntilDone: NO];
+}
+
+bool QCocoaMenuBar::macUpdateMenuBarImmediatly()
+{
+ bool ret = false;
+ cancelAllMenuTracking();
+ QWidget *w = findWindowThatShouldDisplayMenubar();
+ QMenuBar *mb = findMenubarForWindow(w);
+
+ // ### extern bool qt_mac_app_fullscreen; //qapplication_mac.mm
+ bool qt_mac_app_fullscreen = false;
+ // We need to see if we are in full screen mode, if so we need to
+ // switch the full screen mode to be able to show or hide the menubar.
+ if(w && mb) {
+ // This case means we are creating a menubar, check if full screen
+ if(w->isFullScreen()) {
+ // Ok, switch to showing the menubar when hovering over it.
+ SetSystemUIMode(kUIModeAllHidden, kUIOptionAutoShowMenuBar);
+ qt_mac_app_fullscreen = true;
+ }
+ } else if(w) {
+ // Removing a menubar
+ if(w->isFullScreen()) {
+ // Ok, switch to not showing the menubar when hovering on it
+ SetSystemUIMode(kUIModeAllHidden, 0);
+ qt_mac_app_fullscreen = true;
+ }
+ }
+
+ if (mb && mb->isNativeMenuBar()) {
+
+ // ###
+ bool modal = false;
+ //bool modal = QGuiApplicationPrivate::modalState();
+ QCocoaAutoReleasePool pool;
+ if (OSMenuRef menu = reinterpret_cast<QCocoaMenuBar *>(mb->platformMenuBar())->macMenu()) {
+ QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader();
+ [loader ensureAppMenuInMenu:menu];
+ [NSApp setMainMenu:menu];
+ syncMenuBarItemsVisiblity(reinterpret_cast<QCocoaMenuBar *>(mb->platformMenuBar()));
+
+ if (OSMenuRef tmpMerge = QCocoaMenu::mergeMenuHash.value(menu)) {
+ if (QMenuMergeList *mergeList
+ = QCocoaMenu::mergeMenuItemsHash.value(tmpMerge)) {
+ const int mergeListSize = mergeList->size();
+
+ for (int i = 0; i < mergeListSize; ++i) {
+ const QMenuMergeItem &mergeItem = mergeList->at(i);
+ // Ideally we would call QCocoaMenu::syncAction, but that requires finding
+ // the original QMen and likely doing more work than we need.
+ // For example, enabled is handled below.
+ [mergeItem.menuItem setTag:reinterpret_cast<long>(
+ static_cast<QAction *>(mergeItem.action->action))];
+ [mergeItem.menuItem setHidden:!(mergeItem.action->action->isVisible())];
+ }
+ }
+ }
+ // Check if menu is modally shaddowed and should be disabled:
+ modal = qt_mac_should_disable_menu(mb);
+ if (mb != qt_mac_current_menubar.qmenubar || modal != qt_mac_current_menubar.modal)
+ qt_mac_set_modal_state(menu, modal);
+ }
+ qt_mac_current_menubar.qmenubar = mb;
+ qt_mac_current_menubar.modal = modal;
+ ret = true;
+ } else if (qt_mac_current_menubar.qmenubar && qt_mac_current_menubar.qmenubar->isNativeMenuBar()) {
+ // INVARIANT: The currently active menu bar (if any) is not native. But we do have a
+ // native menu bar from before. So we need to decide whether or not is should be enabled:
+ const bool modal = qt_mac_should_disable_menu(qt_mac_current_menubar.qmenubar);
+ if (modal != qt_mac_current_menubar.modal) {
+ ret = true;
+ if (OSMenuRef menu = reinterpret_cast<QCocoaMenuBar *>(qt_mac_current_menubar.qmenubar->platformMenuBar())->macMenu()) {
+ QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader();
+ [loader ensureAppMenuInMenu:menu];
+ [NSApp setMainMenu:menu];
+ syncMenuBarItemsVisiblity(reinterpret_cast<QCocoaMenuBar *>(qt_mac_current_menubar.qmenubar->platformMenuBar()));
+ qt_mac_set_modal_state(menu, modal);
+ }
+ qt_mac_current_menubar.modal = modal;
+ }
+ }
+
+ if (!ret) {
+ qt_mac_clear_menubar();
+ }
+ return ret;
+}
+
+QHash<OSMenuRef, OSMenuRef> QCocoaMenu::mergeMenuHash;
+QHash<OSMenuRef, QMenuMergeList*> QCocoaMenu::mergeMenuItemsHash;
+
+bool QCocoaMenu::merged(const QAction *action) const
+{
+ if (OSMenuRef merge = mergeMenuHash.value(menu)) {
+ if (QMenuMergeList *list = mergeMenuItemsHash.value(merge)) {
+ for(int i = 0; i < list->size(); ++i) {
+ const QMenuMergeItem &item = list->at(i);
+ if (item.action->action == action)
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+//creation of the OSMenuRef
+static OSMenuRef qt_mac_create_menu(QWidget *w)
+{
+ OSMenuRef ret;
+ if (QMenu *qmenu = qobject_cast<QMenu *>(w)){
+ ret = [[QT_MANGLE_NAMESPACE(QNativeCocoaMenu) alloc] initWithQMenu:qmenu];
+ } else {
+ ret = [[NSMenu alloc] init];
+ }
+ return ret;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h
index 69a11134bd..0b96928d5b 100644
--- a/src/plugins/platforms/cocoa/qnsview.h
+++ b/src/plugins/platforms/cocoa/qnsview.h
@@ -48,17 +48,18 @@
@interface QNSView : NSView {
CGImageRef m_cgImage;
- QWidget *m_widget;
+ QWindow *m_window;
Qt::MouseButtons m_buttons;
}
- (id)init;
-- (id)initWithWidget:(QWidget *)widget;
+- (id)initWithQWindow:(QWindow *)window;
- (void)setImage:(QImage *)image;
- (void)drawRect:(NSRect)dirtyRect;
- (BOOL)isFlipped;
+- (BOOL)acceptsFirstResponder;
- (void)handleMouseEvent:(NSEvent *)theEvent;
- (void)mouseDown:(NSEvent *)theEvent;
@@ -74,6 +75,12 @@
- (void)otherMouseDragged:(NSEvent *)theEvent;
- (void)otherMouseUp:(NSEvent *)theEvent;
+- (int) convertKeyCode : (QChar)keyCode;
+- (Qt::KeyboardModifiers) convertKeyModifiers : (ulong)modifierFlags;
+- (void)handleKeyEvent:(NSEvent *)theEvent eventType:(int)eventType;
+- (void)keyDown:(NSEvent *)theEvent;
+- (void)keyUp:(NSEvent *)theEvent;
+
@end
#endif //QNSVIEW_H
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index 037cbdb5d6..f3c71d9eed 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -39,12 +39,20 @@
**
****************************************************************************/
+#include <Carbon/Carbon.h>
+
#include "qnsview.h"
+#include "qcocoahelpers.h"
#include <QtGui/QWindowSystemInterface>
-
#include <QtCore/QDebug>
+@interface NSEvent (Qt_Compile_Leopard_DeviceDelta)
+ - (CGFloat)deviceDeltaX;
+ - (CGFloat)deviceDeltaY;
+ - (CGFloat)deviceDeltaZ;
+@end
+
@implementation QNSView
- (id) init
@@ -52,16 +60,16 @@
self = [super init];
if (self) {
m_cgImage = 0;
- m_widget = 0;
+ m_window = 0;
m_buttons = Qt::NoButton;
}
return self;
}
-- (id)initWithWidget:(QWidget *)widget {
+- (id)initWithQWindow:(QWindow *)widget {
self = [self init];
if (self) {
- m_widget = widget;
+ m_window = widget;
}
return self;
}
@@ -91,7 +99,7 @@
bitDepth,
bytesPrLine,
cgColourSpaceRef,
- kCGImageAlphaNone,
+ kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst,
cgDataProviderRef,
NULL,
false,
@@ -130,82 +138,185 @@
return YES;
}
+- (BOOL)acceptsFirstResponder
+{
+ return YES;
+}
+
- (void)handleMouseEvent:(NSEvent *)theEvent;
{
- NSPoint point = [self convertPoint: [theEvent locationInWindow] fromView: nil];
- QPoint qt_localPoint(point.x,point.y);
+ NSPoint windowPoint = [self convertPoint: [theEvent locationInWindow] fromView: nil];
+ QPoint qt_windowPoint(windowPoint.x, windowPoint.y);
NSTimeInterval timestamp = [theEvent timestamp];
ulong qt_timestamp = timestamp * 1000;
- QWindowSystemInterface::handleMouseEvent(m_widget,qt_timestamp,qt_localPoint,QPoint(),m_buttons);
+ // ### Should the points be windowPoint and screenPoint?
+ QWindowSystemInterface::handleMouseEvent(m_window, qt_timestamp, qt_windowPoint, qt_windowPoint, m_buttons);
+}
+- (void)mouseDown:(NSEvent *)theEvent
+{
+ m_buttons |= Qt::LeftButton;
+ [self handleMouseEvent:theEvent];
+}
+
+- (void)mouseDragged:(NSEvent *)theEvent
+{
+ if (!(m_buttons & Qt::LeftButton))
+ qWarning("Internal Mousebutton tracking invalid(missing Qt::LeftButton");
+ [self handleMouseEvent:theEvent];
+}
+
+- (void)mouseUp:(NSEvent *)theEvent
+{
+ m_buttons &= QFlag(~int(Qt::LeftButton));
+ [self handleMouseEvent:theEvent];
}
- - (void)mouseDown:(NSEvent *)theEvent
- {
- m_buttons |= Qt::LeftButton;
- [self handleMouseEvent:theEvent];
- }
- - (void)mouseDragged:(NSEvent *)theEvent
- {
- if (!(m_buttons & Qt::LeftButton))
- qWarning("Internal Mousebutton tracking invalid(missing Qt::LeftButton");
- [self handleMouseEvent:theEvent];
- }
- - (void)mouseUp:(NSEvent *)theEvent
- {
- m_buttons &= QFlag(~int(Qt::LeftButton));
- [self handleMouseEvent:theEvent];
- }
- (void)mouseMoved:(NSEvent *)theEvent
{
- qDebug() << "mouseMove";
[self handleMouseEvent:theEvent];
}
+
- (void)mouseEntered:(NSEvent *)theEvent
{
- Q_UNUSED(theEvent);
- QWindowSystemInterface::handleEnterEvent(m_widget);
+ Q_UNUSED(theEvent);
+ QWindowSystemInterface::handleEnterEvent(m_window);
}
+
- (void)mouseExited:(NSEvent *)theEvent
{
- Q_UNUSED(theEvent);
- QWindowSystemInterface::handleLeaveEvent(m_widget);
+ Q_UNUSED(theEvent);
+ QWindowSystemInterface::handleLeaveEvent(m_window);
}
+
- (void)rightMouseDown:(NSEvent *)theEvent
{
- m_buttons |= Qt::RightButton;
+ m_buttons |= Qt::RightButton;
[self handleMouseEvent:theEvent];
}
+
- (void)rightMouseDragged:(NSEvent *)theEvent
{
- if (!(m_buttons & Qt::LeftButton))
- qWarning("Internal Mousebutton tracking invalid(missing Qt::LeftButton");
- [self handleMouseEvent:theEvent];
+ if (!(m_buttons & Qt::LeftButton))
+ qWarning("Internal Mousebutton tracking invalid(missing Qt::LeftButton");
+ [self handleMouseEvent:theEvent];
}
+
- (void)rightMouseUp:(NSEvent *)theEvent
{
- m_buttons &= QFlag(~int(Qt::RightButton));
- [self handleMouseEvent:theEvent];
+ m_buttons &= QFlag(~int(Qt::RightButton));
+ [self handleMouseEvent:theEvent];
}
+
- (void)otherMouseDown:(NSEvent *)theEvent
{
- m_buttons |= Qt::RightButton;
+ m_buttons |= Qt::RightButton;
[self handleMouseEvent:theEvent];
}
+
- (void)otherMouseDragged:(NSEvent *)theEvent
{
- if (!(m_buttons & Qt::LeftButton))
- qWarning("Internal Mousebutton tracking invalid(missing Qt::LeftButton");
- [self handleMouseEvent:theEvent];
+ if (!(m_buttons & Qt::LeftButton))
+ qWarning("Internal Mousebutton tracking invalid(missing Qt::LeftButton");
+ [self handleMouseEvent:theEvent];
}
+
- (void)otherMouseUp:(NSEvent *)theEvent
{
- m_buttons &= QFlag(~int(Qt::MiddleButton));
- [self handleMouseEvent:theEvent];
+ m_buttons &= QFlag(~int(Qt::MiddleButton));
+ [self handleMouseEvent:theEvent];
}
+#ifndef QT_NO_WHEELEVENT
+- (void)scrollWheel:(NSEvent *)theEvent
+{
+ int deltaX = 0;
+ int deltaY = 0;
+ int deltaZ = 0;
+
+ const EventRef carbonEvent = (EventRef)[theEvent eventRef];
+ const UInt32 carbonEventKind = carbonEvent ? ::GetEventKind(carbonEvent) : 0;
+ const bool scrollEvent = carbonEventKind == kEventMouseScroll;
+
+ if (scrollEvent) {
+ // The mouse device containts pixel scroll wheel support (Mighty Mouse, Trackpad).
+ // Since deviceDelta is delivered as pixels rather than degrees, we need to
+ // convert from pixels to degrees in a sensible manner.
+ // It looks like 1/4 degrees per pixel behaves most native.
+ // (NB: Qt expects the unit for delta to be 8 per degree):
+ const int pixelsToDegrees = 2; // 8 * 1/4
+ deltaX = [theEvent deviceDeltaX] * pixelsToDegrees;
+ deltaY = [theEvent deviceDeltaY] * pixelsToDegrees;
+ deltaZ = [theEvent deviceDeltaZ] * pixelsToDegrees;
+ } else {
+ // carbonEventKind == kEventMouseWheelMoved
+ // Remove acceleration, and use either -120 or 120 as delta:
+ deltaX = qBound(-120, int([theEvent deltaX] * 10000), 120);
+ deltaY = qBound(-120, int([theEvent deltaY] * 10000), 120);
+ deltaZ = qBound(-120, int([theEvent deltaZ] * 10000), 120);
+ }
+
+ NSPoint windowPoint = [self convertPoint: [theEvent locationInWindow] fromView: nil];
+ QPoint qt_windowPoint(windowPoint.x, windowPoint.y);
+ NSTimeInterval timestamp = [theEvent timestamp];
+ ulong qt_timestamp = timestamp * 1000;
+
+ if (deltaX != 0)
+ QWindowSystemInterface::handleWheelEvent(m_window, qt_timestamp, qt_windowPoint, qt_windowPoint, deltaX, Qt::Horizontal);
+
+ if (deltaY != 0)
+ QWindowSystemInterface::handleWheelEvent(m_window, qt_timestamp, qt_windowPoint, qt_windowPoint, deltaY, Qt::Vertical);
+ if (deltaZ != 0)
+ // Qt doesn't explicitly support wheels with a Z component. In a misguided attempt to
+ // try to be ahead of the pack, I'm adding this extra value.
+ QWindowSystemInterface::handleWheelEvent(m_window, qt_timestamp, qt_windowPoint, qt_windowPoint, deltaY, (Qt::Orientation)3);
+}
+#endif //QT_NO_WHEELEVENT
+
+- (int) convertKeyCode : (QChar)keyChar
+{
+ return qt_mac_cocoaKey2QtKey(keyChar);
+}
+
+- (Qt::KeyboardModifiers) convertKeyModifiers : (ulong)modifierFlags
+{
+ Qt::KeyboardModifiers qtMods =Qt::NoModifier;
+ if (modifierFlags & NSShiftKeyMask)
+ qtMods |= Qt::ShiftModifier;
+ if (modifierFlags & NSControlKeyMask)
+ qtMods |= Qt::MetaModifier;
+ if (modifierFlags & NSAlternateKeyMask)
+ qtMods |= Qt::AltModifier;
+ if (modifierFlags & NSCommandKeyMask)
+ qtMods |= Qt::ControlModifier;
+ if (modifierFlags & NSNumericPadKeyMask)
+ qtMods |= Qt::KeypadModifier;
+ return qtMods;
+}
+
+- (void)handleKeyEvent:(NSEvent *)theEvent eventType:(int)eventType
+{
+ NSTimeInterval timestamp = [theEvent timestamp];
+ ulong qt_timestamp = timestamp * 1000;
+ QString characters = QString::fromUtf8([[theEvent characters] UTF8String]);
+ Qt::KeyboardModifiers modifiers = [self convertKeyModifiers : [theEvent modifierFlags]];
+ QChar ch([[theEvent charactersIgnoringModifiers] characterAtIndex:0]);
+ int keyCode = [self convertKeyCode : ch];
+
+ QWindowSystemInterface::handleKeyEvent(m_window, qt_timestamp, QEvent::Type(eventType), keyCode, modifiers, characters);
+}
+
+- (void)keyDown:(NSEvent *)theEvent
+{
+ [self handleKeyEvent : theEvent eventType :int(QEvent::KeyPress)];
+}
+
+- (void)keyUp:(NSEvent *)theEvent
+{
+ [self handleKeyEvent : theEvent eventType :int(QEvent::KeyRelease)];
+}
@end
diff --git a/src/plugins/platforms/cocoa/qnswindowdelegate.h b/src/plugins/platforms/cocoa/qnswindowdelegate.h
index cf296c4a8b..5cd226a71d 100644
--- a/src/plugins/platforms/cocoa/qnswindowdelegate.h
+++ b/src/plugins/platforms/cocoa/qnswindowdelegate.h
@@ -46,6 +46,26 @@
#include "qcocoawindow.h"
+#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5
+@protocol NSWindowDelegate <NSObject>
+//- (NSSize)windowWillResize:(NSWindow *)window toSize:(NSSize)proposedFrameSize;
+//- (void)windowDidMiniaturize:(NSNotification*)notification;
+- (void)windowDidResize:(NSNotification *)notification;
+- (void)windowWillClose:(NSNotification *)notification;
+//- (NSRect)windowWillUseStandardFrame:(NSWindow *)window defaultFrame:(NSRect)defaultFrame;
+- (void)windowDidMove:(NSNotification *)notification;
+//- (BOOL)windowShouldClose:(id)window;
+//- (void)windowDidDeminiaturize:(NSNotification *)notification;
+//- (void)windowDidBecomeMain:(NSNotification*)notification;
+//- (void)windowDidResignMain:(NSNotification*)notification;
+//- (void)windowDidBecomeKey:(NSNotification*)notification;
+//- (void)windowDidResignKey:(NSNotification*)notification;
+//- (BOOL)window:(NSWindow *)window shouldPopUpDocumentPathMenu:(NSMenu *)menu;
+//- (BOOL)window:(NSWindow *)window shouldDragDocumentWithEvent:(NSEvent *)event from:(NSPoint)dragImageLocation withPasteboard:(NSPasteboard *)pasteboard;
+//- (BOOL)windowShouldZoom:(NSWindow *)window toFrame:(NSRect)newFrame;
+@end
+#endif
+
@interface QNSWindowDelegate : NSObject <NSWindowDelegate>
{
QCocoaWindow *m_cocoaWindow;
@@ -54,6 +74,7 @@
- (id)initWithQCocoaWindow: (QCocoaWindow *) cocoaWindow;
- (void)windowDidResize:(NSNotification *)notification;
+- (void)windowDidMove:(NSNotification *)notification;
- (void)windowWillClose:(NSNotification *)notification;
@end
diff --git a/src/plugins/platforms/cocoa/qnswindowdelegate.mm b/src/plugins/platforms/cocoa/qnswindowdelegate.mm
index 887b08f6d2..869ef7840b 100644
--- a/src/plugins/platforms/cocoa/qnswindowdelegate.mm
+++ b/src/plugins/platforms/cocoa/qnswindowdelegate.mm
@@ -64,10 +64,20 @@
}
}
+- (void)windowDidMove:(NSNotification *)notification
+{
+ Q_UNUSED(notification);
+ if (m_cocoaWindow) {
+ m_cocoaWindow->windowDidMove();
+ }
+}
+
- (void)windowWillClose:(NSNotification *)notification
{
Q_UNUSED(notification);
- QWindowSystemInterface::handleCloseEvent(m_cocoaWindow->widget());
+ if (m_cocoaWindow) {
+ m_cocoaWindow->windowWillClose();
+ }
}
@end
diff --git a/src/gui/mac/qt_menu.nib/classes.nib b/src/plugins/platforms/cocoa/qt_menu.nib/classes.nib
index 0031e0e4e5..0031e0e4e5 100644
--- a/src/gui/mac/qt_menu.nib/classes.nib
+++ b/src/plugins/platforms/cocoa/qt_menu.nib/classes.nib
diff --git a/src/gui/mac/qt_menu.nib/info.nib b/src/plugins/platforms/cocoa/qt_menu.nib/info.nib
index 02e5cca562..02e5cca562 100644
--- a/src/gui/mac/qt_menu.nib/info.nib
+++ b/src/plugins/platforms/cocoa/qt_menu.nib/info.nib
diff --git a/src/gui/mac/qt_menu.nib/keyedobjects.nib b/src/plugins/platforms/cocoa/qt_menu.nib/keyedobjects.nib
index 3edb0ed2eb..3edb0ed2eb 100644
--- a/src/gui/mac/qt_menu.nib/keyedobjects.nib
+++ b/src/plugins/platforms/cocoa/qt_menu.nib/keyedobjects.nib
Binary files differ
diff --git a/src/plugins/platforms/directfb/directfb.pro b/src/plugins/platforms/directfb/directfb.pro
index f830177dcb..e516fb11f3 100644
--- a/src/plugins/platforms/directfb/directfb.pro
+++ b/src/plugins/platforms/directfb/directfb.pro
@@ -2,6 +2,8 @@ TARGET = qdirectfb
load(qt_plugin)
DESTDIR = $$QT.gui.plugins/platforms
+QT += core-private gui-private platformsupport-private
+
isEmpty(DIRECTFB_LIBS) {
DIRECTFB_LIBS = -ldirectfb -lfusion -ldirect -lpthread
}
@@ -19,16 +21,16 @@ SOURCES = main.cpp \
qdirectfbconvenience.cpp \
qdirectfbinput.cpp \
qdirectfbcursor.cpp \
- qdirectfbwindow.cpp \
- qdirectfbglcontext.cpp
+ qdirectfbwindow.cpp
HEADERS = qdirectfbintegration.h \
qdirectfbwindowsurface.h \
qdirectfbblitter.h \
qdirectfbconvenience.h \
qdirectfbinput.h \
qdirectfbcursor.h \
- qdirectfbwindow.h \
- qdirectfbglcontext.h
+ qdirectfbwindow.h
+
+# ### port the GL context
include(../fontdatabases/genericunix/genericunix.pri)
target.path += $$[QT_INSTALL_PLUGINS]/platforms
diff --git a/src/plugins/platforms/directfb/qdirectfbblitter.cpp b/src/plugins/platforms/directfb/qdirectfbblitter.cpp
index 86a8bf7cb7..a4da2d8142 100644
--- a/src/plugins/platforms/directfb/qdirectfbblitter.cpp
+++ b/src/plugins/platforms/directfb/qdirectfbblitter.cpp
@@ -92,10 +92,10 @@ void QDirectFbBlitter::fillRect(const QRectF &rect, const QColor &color)
void QDirectFbBlitter::drawPixmap(const QRectF &rect, const QPixmap &pixmap, const QRectF &srcRect)
{
- QPixmapData *data = pixmap.pixmapData();
+ QPlatformPixmap *data = pixmap.handle();
Q_ASSERT(data->width() && data->height());
- Q_ASSERT(data->classId() == QPixmapData::BlitterClass);
- QBlittablePixmapData *blitPm = static_cast<QBlittablePixmapData*>(data);
+ Q_ASSERT(data->classId() == QPlatformPixmap::BlitterClass);
+ QBlittablePlatformPixmap *blitPm = static_cast<QBlittablePlatformPixmap*>(data);
QDirectFbBlitter *dfbBlitter = static_cast<QDirectFbBlitter *>(blitPm->blittable());
dfbBlitter->unlock();
diff --git a/src/plugins/platforms/directfb/qdirectfbblitter.h b/src/plugins/platforms/directfb/qdirectfbblitter.h
index 16d7599c83..2dcb2be07a 100644
--- a/src/plugins/platforms/directfb/qdirectfbblitter.h
+++ b/src/plugins/platforms/directfb/qdirectfbblitter.h
@@ -67,7 +67,7 @@ protected:
friend class QDirectFbConvenience;
};
-class QDirectFbBlitterPixmapData : public QBlittablePixmapData
+class QDirectFbBlitterPlatformPixmap : public QBlittablePlatformPixmap
{
public:
QBlittable *createBlittable(const QSize &size) const { return new QDirectFbBlitter(size); }
diff --git a/src/plugins/platforms/directfb/qdirectfbconvenience.cpp b/src/plugins/platforms/directfb/qdirectfbconvenience.cpp
index 37810dc461..38130c8deb 100644
--- a/src/plugins/platforms/directfb/qdirectfbconvenience.cpp
+++ b/src/plugins/platforms/directfb/qdirectfbconvenience.cpp
@@ -106,9 +106,9 @@ int QDirectFbConvenience::colorDepthForSurface(const DFBSurfacePixelFormat forma
return ((0x1f << 7) & format) >> 7;
}
-IDirectFBSurface *QDirectFbConvenience::dfbSurfaceForPixmapData(QPixmapData *pixmapData)
+IDirectFBSurface *QDirectFbConvenience::dfbSurfaceForPlatformPixmap(QPlatformPixmap *handle)
{
- QBlittablePixmapData *blittablePmData = static_cast<QBlittablePixmapData *>(pixmapData);
+ QBlittablePlatformPixmap *blittablePmData = static_cast<QBlittablePlatformPixmap *>(handle);
if (blittablePmData) {
QBlittable *blittable = blittablePmData->blittable();
QDirectFbBlitter *dfbBlitter = static_cast<QDirectFbBlitter *>(blittable);
diff --git a/src/plugins/platforms/directfb/qdirectfbconvenience.h b/src/plugins/platforms/directfb/qdirectfbconvenience.h
index c82bea84c7..93d47f3644 100644
--- a/src/plugins/platforms/directfb/qdirectfbconvenience.h
+++ b/src/plugins/platforms/directfb/qdirectfbconvenience.h
@@ -67,7 +67,7 @@ public:
static IDirectFB *dfbInterface();
static IDirectFBDisplayLayer *dfbDisplayLayer(int display = DLID_PRIMARY);
- static IDirectFBSurface *dfbSurfaceForPixmapData(QPixmapData *);
+ static IDirectFBSurface *dfbSurfaceForPlatformPixmap(QPlatformPixmap *);
static Qt::MouseButton mouseButton(DFBInputDeviceButtonIdentifier identifier);
static Qt::MouseButtons mouseButtons(DFBInputDeviceButtonMask mask);
diff --git a/src/plugins/platforms/directfb/qdirectfbcursor.cpp b/src/plugins/platforms/directfb/qdirectfbcursor.cpp
index 8a38bc4e83..b39a3f3c0a 100644
--- a/src/plugins/platforms/directfb/qdirectfbcursor.cpp
+++ b/src/plugins/platforms/directfb/qdirectfbcursor.cpp
@@ -43,25 +43,26 @@
#include "qdirectfbconvenience.h"
-QDirectFBCursor::QDirectFBCursor(QPlatformScreen* screen) :
- QPlatformCursor(screen), surface(0)
+QDirectFBCursor::QDirectFBCursor(QPlatformScreen *screen)
+ : QPlatformCursor(screen)
{
QDirectFbConvenience::dfbInterface()->GetDisplayLayer(QDirectFbConvenience::dfbInterface(),DLID_PRIMARY, &m_layer);
- image = new QPlatformCursorImage(0, 0, 0, 0, 0, 0);
+ m_image = new QPlatformCursorImage(0, 0, 0, 0, 0, 0);
}
-void QDirectFBCursor::changeCursor(QCursor * cursor, QWidget * widget)
+#warning "Memory leak?"
+
+void QDirectFBCursor::changeCursor(QCursor *cursor, QWindow *)
{
- Q_UNUSED(widget);
int xSpot;
int ySpot;
QPixmap map;
if (cursor->shape() != Qt::BitmapCursor) {
- image->set(cursor->shape());
- xSpot = image->hotspot().x();
- ySpot = image->hotspot().y();
- QImage *i = image->image();
+ m_image->set(cursor->shape());
+ xSpot = m_image->hotspot().x();
+ ySpot = m_image->hotspot().y();
+ QImage *i = m_image->image();
map = QPixmap::fromImage(*i);
} else {
QPoint point = cursor->hotSpot();
@@ -70,7 +71,7 @@ void QDirectFBCursor::changeCursor(QCursor * cursor, QWidget * widget)
map = cursor->pixmap();
}
- IDirectFBSurface *surface = QDirectFbConvenience::dfbSurfaceForPixmapData(map.pixmapData());
+ IDirectFBSurface *surface = QDirectFbConvenience::dfbSurfaceForPlatformPixmap(map.handle());
if (m_layer->SetCooperativeLevel(m_layer, DLSCL_ADMINISTRATIVE) != DFB_OK) {
return;
diff --git a/src/plugins/platforms/directfb/qdirectfbcursor.h b/src/plugins/platforms/directfb/qdirectfbcursor.h
index b148de5589..22328da402 100644
--- a/src/plugins/platforms/directfb/qdirectfbcursor.h
+++ b/src/plugins/platforms/directfb/qdirectfbcursor.h
@@ -51,13 +51,11 @@ class QDirectFBCursor : public QPlatformCursor
{
public:
QDirectFBCursor(QPlatformScreen *screem);
- void changeCursor(QCursor * cursor, QWidget * widget);
+ void changeCursor(QCursor *cursor, QWindow *window);
private:
- IDirectFBDisplayLayer * m_layer;
- IDirectFBSurface * surface;
- QPlatformCursorImage * image;
- QDirectFbBlitter *blitter;
+ IDirectFBDisplayLayer *m_layer;
+ QPlatformCursorImage *m_image;
};
#endif // QDIRECTFBCURSOR_H
diff --git a/src/plugins/platforms/directfb/qdirectfbglcontext.cpp b/src/plugins/platforms/directfb/qdirectfbglcontext.cpp
index aca28f1d62..1121a42944 100644
--- a/src/plugins/platforms/directfb/qdirectfbglcontext.cpp
+++ b/src/plugins/platforms/directfb/qdirectfbglcontext.cpp
@@ -70,13 +70,13 @@ QDirectFbGLContext::QDirectFbGLContext(IDirectFBGL *glContext)
void QDirectFbGLContext::makeCurrent()
{
- QPlatformGLContext::makeCurrent();
+ QPlatformOpenGLContext::makeCurrent();
m_dfbGlContext->Lock(m_dfbGlContext);
}
void QDirectFbGLContext::doneCurrent()
{
- QPlatformGLContext::doneCurrent();
+ QPlatformOpenGLContext::doneCurrent();
m_dfbGlContext->Unlock(m_dfbGlContext);
}
diff --git a/src/plugins/platforms/directfb/qdirectfbglcontext.h b/src/plugins/platforms/directfb/qdirectfbglcontext.h
index bff8b28d08..97bab0dcb0 100644
--- a/src/plugins/platforms/directfb/qdirectfbglcontext.h
+++ b/src/plugins/platforms/directfb/qdirectfbglcontext.h
@@ -42,11 +42,11 @@
#ifndef QDIRECTFBGLCONTEXT_H
#define QDIRECTFBGLCONTEXT_H
-#include <QPlatformGLContext>
+#include <QPlatformOpenGLContext>
#include "qdirectfbconvenience.h"
-class QDirectFbGLContext : public QPlatformGLContext
+class QDirectFbGLContext : public QPlatformOpenGLContext
{
public:
explicit QDirectFbGLContext(IDirectFBGL *glContext);
diff --git a/src/plugins/platforms/directfb/qdirectfbinput.cpp b/src/plugins/platforms/directfb/qdirectfbinput.cpp
index d35cea5ee9..d05729b992 100644
--- a/src/plugins/platforms/directfb/qdirectfbinput.cpp
+++ b/src/plugins/platforms/directfb/qdirectfbinput.cpp
@@ -47,7 +47,6 @@
#include <QWindowSystemInterface>
#include <QMouseEvent>
#include <QEvent>
-#include <QApplication>
#include <directfb.h>
@@ -82,9 +81,9 @@ void QDirectFbInput::stopInputEventLoop()
m_waitStop.acquire();
}
-void QDirectFbInput::addWindow(DFBWindowID id, QWidget *tlw)
+void QDirectFbInput::addWindow(DFBWindowID id, QWindow *qt_window)
{
- m_tlwMap.insert(id,tlw);
+ m_tlwMap.insert(id,qt_window);
IDirectFBWindow *window;
m_dfbDisplayLayer->GetWindow(m_dfbDisplayLayer,id,&window);
@@ -152,7 +151,7 @@ void QDirectFbInput::handleMouseEvents(const DFBEvent &event)
} else if (event.window.type == DWET_BUTTONUP) {
window->UngrabPointer(window);
}
- QWidget *tlw = m_tlwMap.value(event.window.window_id);
+ QWindow *tlw = m_tlwMap.value(event.window.window_id);
QWindowSystemInterface::handleMouseEvent(tlw, timestamp, p, globalPos, buttons);
}
@@ -161,7 +160,7 @@ void QDirectFbInput::handleWheelEvent(const DFBEvent &event)
QPoint p(event.window.cx, event.window.cy);
QPoint globalPos = globalPoint(event);
long timestamp = (event.window.timestamp.tv_sec*1000) + (event.window.timestamp.tv_usec/1000);
- QWidget *tlw = m_tlwMap.value(event.window.window_id);
+ QWindow *tlw = m_tlwMap.value(event.window.window_id);
QWindowSystemInterface::handleWheelEvent(tlw, timestamp, p, globalPos,
event.window.step*120,
Qt::Vertical);
@@ -178,13 +177,13 @@ void QDirectFbInput::handleKeyEvents(const DFBEvent &event)
QChar character;
if (DFB_KEY_TYPE(event.window.key_symbol) == DIKT_UNICODE)
character = QChar(event.window.key_symbol);
- QWidget *tlw = m_tlwMap.value(event.window.window_id);
+ QWindow *tlw = m_tlwMap.value(event.window.window_id);
QWindowSystemInterface::handleKeyEvent(tlw, timestamp, type, key, modifiers, character);
}
void QDirectFbInput::handleEnterLeaveEvents(const DFBEvent &event)
{
- QWidget *tlw = m_tlwMap.value(event.window.window_id);
+ QWindow *tlw = m_tlwMap.value(event.window.window_id);
switch (event.window.type) {
case DWET_ENTER:
QWindowSystemInterface::handleEnterEvent(tlw);
diff --git a/src/plugins/platforms/directfb/qdirectfbinput.h b/src/plugins/platforms/directfb/qdirectfbinput.h
index 3b8008f1fe..b0fe0c79eb 100644
--- a/src/plugins/platforms/directfb/qdirectfbinput.h
+++ b/src/plugins/platforms/directfb/qdirectfbinput.h
@@ -57,7 +57,7 @@ class QDirectFbInput : public QObject
Q_OBJECT
public:
QDirectFbInput(QObject *parent);
- void addWindow(DFBWindowID id, QWidget *tlw);
+ void addWindow(DFBWindowID id, QWindow *window);
void removeWindow(WId wId);
public slots:
@@ -80,7 +80,7 @@ private:
bool m_shouldStop;
QSemaphore m_waitStop;
- QHash<DFBWindowID,QWidget *>m_tlwMap;
+ QHash<DFBWindowID,QWindow *>m_tlwMap;
};
#endif // QDIRECTFBINPUT_H
diff --git a/src/plugins/platforms/directfb/qdirectfbintegration.cpp b/src/plugins/platforms/directfb/qdirectfbintegration.cpp
index 61f1d2513b..7bf26b433a 100644
--- a/src/plugins/platforms/directfb/qdirectfbintegration.cpp
+++ b/src/plugins/platforms/directfb/qdirectfbintegration.cpp
@@ -46,20 +46,21 @@
#include "qdirectfbcursor.h"
#include "qdirectfbwindow.h"
-#include "qgenericunixfontdatabase.h"
-
-#include <private/qwindowsurface_raster_p.h>
-#include <private/qpixmap_raster_p.h>
+#include <QtPlatformSupport/private/qgenericunixfontdatabase_p.h>
+#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
#include <QtGui/private/qpixmap_blitter_p.h>
-#include <QtGui/private/qpixmapdata_p.h>
+#include <QtGui/private/qpixmap_raster_p.h>
+#include <QtGui/private/qguiapplication_p.h>
+#include <QtGui/qplatformpixmap_qpa.h>
#include <QtCore/QCoreApplication>
#include <QtCore/QThread>
+#include <QtCore/QAbstractEventDispatcher>
QT_BEGIN_NAMESPACE
QDirectFbScreen::QDirectFbScreen(int display)
- :QPlatformScreen()
+ : QPlatformScreen()
{
m_layer = QDirectFbConvenience::dfbDisplayLayer(display);
m_layer->SetCooperativeLevel(m_layer,DLSCL_SHARED);
@@ -74,16 +75,20 @@ QDirectFbScreen::QDirectFbScreen(int display)
m_depth = QDirectFbConvenience::colorDepthForSurface(config.pixelformat);
m_physicalSize = QSize(qRound(config.width * inch / dpi), qRound(config.height *inch / dpi));
- cursor = new QDirectFBCursor(this);
+ m_cursor = new QDirectFBCursor(this);
}
QDirectFbScreen::~QDirectFbScreen()
{
+#warning "Delete the cursor?"
}
QDirectFbIntegration::QDirectFbIntegration()
- : mFontDb(new QGenericUnixFontDatabase())
+ : m_fontDb(new QGenericUnixFontDatabase())
+ , m_eventDispatcher(createUnixEventDispatcher())
{
+ QGuiApplicationPrivate::instance()->setEventDispatcher(m_eventDispatcher);
+
const QStringList args = QCoreApplication::arguments();
int argc = args.size();
char **argv = new char*[argc];
@@ -99,46 +104,51 @@ QDirectFbIntegration::QDirectFbIntegration()
delete[] argv;
+
QDirectFbScreen *primaryScreen = new QDirectFbScreen(0);
- mScreens.append(primaryScreen);
+ screenAdded(primaryScreen);
- mInputRunner = new QThread;
- mInput = new QDirectFbInput(0);
- mInput->moveToThread(mInputRunner);
- QObject::connect(mInputRunner,SIGNAL(started()),mInput,SLOT(runInputEventLoop()));
- mInputRunner->start();
+ m_inputRunner = new QThread;
+ m_input = new QDirectFbInput(0);
+ m_input->moveToThread(m_inputRunner);
+ QObject::connect(m_inputRunner,SIGNAL(started()),m_input,SLOT(runInputEventLoop()));
+ m_inputRunner->start();
}
QDirectFbIntegration::~QDirectFbIntegration()
{
- mInput->stopInputEventLoop();
- delete mInputRunner;
- delete mInput;
+ m_input->stopInputEventLoop();
+ delete m_inputRunner;
+ delete m_input;
}
-QPixmapData *QDirectFbIntegration::createPixmapData(QPixmapData::PixelType type) const
+QPlatformPixmap *QDirectFbIntegration::createPlatformPixmap(QPlatformPixmap::PixelType type) const
{
- if (type == QPixmapData::BitmapType)
- return new QRasterPixmapData(type);
+ if (type == QPlatformPixmap::BitmapType)
+ return new QRasterPlatformPixmap(type);
else
- return new QDirectFbBlitterPixmapData;
+ return new QDirectFbBlitterPlatformPixmap;
+}
+
+QPlatformWindow *QDirectFbIntegration::createPlatformWindow(QWindow *window) const
+{
+ QDirectFbInput *input = const_cast<QDirectFbInput *>(m_input);//gah
+ return new QDirectFbWindow(window,input);
}
-QPlatformWindow *QDirectFbIntegration::createPlatformWindow(QWidget *widget, WId winId) const
+QAbstractEventDispatcher *QDirectFbIntegration::guiThreadEventDispatcher() const
{
- Q_UNUSED(winId);
- QDirectFbInput *input = const_cast<QDirectFbInput *>(mInput);//gah
- return new QDirectFbWindow(widget,input);
+ return m_eventDispatcher;
}
-QWindowSurface *QDirectFbIntegration::createWindowSurface(QWidget *widget, WId winId) const
+QPlatformBackingStore *QDirectFbIntegration::createPlatformBackingStore(QWindow *window) const
{
- return new QDirectFbWindowSurface(widget,winId);
+ return new QDirectFbWindowSurface(window);
}
QPlatformFontDatabase *QDirectFbIntegration::fontDatabase() const
{
- return mFontDb;
+ return m_fontDb;
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/directfb/qdirectfbintegration.h b/src/plugins/platforms/directfb/qdirectfbintegration.h
index 0e8337a5fb..64f3b6005a 100644
--- a/src/plugins/platforms/directfb/qdirectfbintegration.h
+++ b/src/plugins/platforms/directfb/qdirectfbintegration.h
@@ -51,11 +51,11 @@
QT_BEGIN_NAMESPACE
class QThread;
+class QAbstractEventDispatcher;
class QDirectFBCursor;
class QDirectFbScreen : public QPlatformScreen
{
-Q_OBJECT
public:
QDirectFbScreen(int display);
~QDirectFbScreen();
@@ -74,8 +74,7 @@ public:
IDirectFBDisplayLayer *m_layer;
private:
- QDirectFBCursor * cursor;
-
+ QDirectFBCursor *m_cursor;
};
class QDirectFbIntegration : public QPlatformIntegration
@@ -84,19 +83,18 @@ public:
QDirectFbIntegration();
~QDirectFbIntegration();
- QPixmapData *createPixmapData(QPixmapData::PixelType type) const;
- QPlatformWindow *createPlatformWindow(QWidget *widget, WId winId = 0) const;
- QWindowSurface *createWindowSurface(QWidget *widget, WId winId) const;
-
- QList<QPlatformScreen *> screens() const { return mScreens; }
+ QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const;
+ QPlatformWindow *createPlatformWindow(QWindow *window) const;
+ QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const;
+ QAbstractEventDispatcher *guiThreadEventDispatcher() const;
QPlatformFontDatabase *fontDatabase() const;
private:
- QList<QPlatformScreen *> mScreens;
- QDirectFbInput *mInput;
- QThread *mInputRunner;
- QPlatformFontDatabase *mFontDb;
+ QDirectFbInput *m_input;
+ QThread *m_inputRunner;
+ QPlatformFontDatabase *m_fontDb;
+ QAbstractEventDispatcher *m_eventDispatcher;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/directfb/qdirectfbwindow.cpp b/src/plugins/platforms/directfb/qdirectfbwindow.cpp
index d2c411eaeb..e75291b5c1 100644
--- a/src/plugins/platforms/directfb/qdirectfbwindow.cpp
+++ b/src/plugins/platforms/directfb/qdirectfbwindow.cpp
@@ -41,16 +41,13 @@
#include "qdirectfbwindow.h"
#include "qdirectfbinput.h"
-#include "qdirectfbglcontext.h"
-
-#include <QWidget>
#include "qdirectfbwindowsurface.h"
#include <directfb.h>
-QDirectFbWindow::QDirectFbWindow(QWidget *tlw, QDirectFbInput *inputhandler)
- : QPlatformWindow(tlw), m_inputHandler(inputhandler), m_context(0)
+QDirectFbWindow::QDirectFbWindow(QWindow *tlw, QDirectFbInput *inputhandler)
+ : QPlatformWindow(tlw), m_inputHandler(inputhandler)
{
IDirectFBDisplayLayer *layer = QDirectFbConvenience::dfbDisplayLayer();
DFBDisplayLayerConfig layerConfig;
@@ -63,10 +60,10 @@ QDirectFbWindow::QDirectFbWindow(QWidget *tlw, QDirectFbInput *inputhandler)
|DWDESC_OPTIONS
#endif
|DWDESC_CAPS);
- description.width = tlw->rect().width();
- description.height = tlw->rect().height();
- description.posx = tlw->rect().x();
- description.posy = tlw->rect().y();
+ description.width = tlw->width();
+ description.height = tlw->height();
+ description.posx = tlw->x();
+ description.posy = tlw->y();
if (layerConfig.surface_caps & DSCAPS_PREMULTIPLIED)
description.surface_caps = DSCAPS_PREMULTIPLIED;
@@ -85,7 +82,7 @@ QDirectFbWindow::QDirectFbWindow(QWidget *tlw, QDirectFbInput *inputhandler)
m_dfbWindow->SetOpacity(m_dfbWindow,0xff);
- setVisible(widget()->isVisible());
+ setVisible(window()->visible());
DFBWindowID id;
m_dfbWindow->GetID(m_dfbWindow, &id);
@@ -100,17 +97,20 @@ QDirectFbWindow::~QDirectFbWindow()
void QDirectFbWindow::setGeometry(const QRect &rect)
{
- bool isMoveOnly = (rect.topLeft() != geometry().topLeft()) && (rect.size() == geometry().size());
+// bool isMoveOnly = (rect.topLeft() != geometry().topLeft()) && (rect.size() == geometry().size());
+
QPlatformWindow::setGeometry(rect);
- if (widget()->isVisible() && !(widget()->testAttribute(Qt::WA_DontShowOnScreen))) {
+ if (window()->visible()) {
m_dfbWindow->SetBounds(m_dfbWindow, rect.x(),rect.y(),
rect.width(), rect.height());
-
+// ### TODO port, verify if this is needed
+#if 0
//Hack. When moving since the WindowSurface of a window becomes invalid when moved
if (isMoveOnly) { //if resize then windowsurface is updated.
widget()->windowSurface()->resize(rect.size());
- widget()->update();
+ window()->update();
}
+#endif
}
}
@@ -169,23 +169,3 @@ WId QDirectFbWindow::winId() const
m_dfbWindow->GetID(m_dfbWindow, &id);
return WId(id);
}
-
-QPlatformGLContext *QDirectFbWindow::glContext() const
-{
- if (!m_context) {
- IDirectFBSurface *surface;
- DFBResult result = m_dfbWindow->GetSurface(m_dfbWindow,&surface);
- if (result != DFB_OK) {
- qWarning("could not retrieve surface in QDirectFbWindow::glContext()");
- return 0;
- }
- IDirectFBGL *gl;
- result = surface->GetGL(surface,&gl);
- if (result != DFB_OK) {
- qWarning("could not retrieve IDirectFBGL in QDirectFbWindow::glContext()");
- return 0;
- }
- const_cast<QDirectFbWindow *>(this)->m_context = new QDirectFbGLContext(gl);
- }
- return m_context;
-}
diff --git a/src/plugins/platforms/directfb/qdirectfbwindow.h b/src/plugins/platforms/directfb/qdirectfbwindow.h
index 4f839a05fa..4c9bbaaab5 100644
--- a/src/plugins/platforms/directfb/qdirectfbwindow.h
+++ b/src/plugins/platforms/directfb/qdirectfbwindow.h
@@ -52,7 +52,7 @@ QT_BEGIN_NAMESPACE
class QDirectFbWindow : public QPlatformWindow
{
public:
- QDirectFbWindow(QWidget *tlw, QDirectFbInput *inputhandler);
+ QDirectFbWindow(QWindow *tlw, QDirectFbInput *inputhandler);
~QDirectFbWindow();
void setGeometry(const QRect &rect);
@@ -65,13 +65,9 @@ public:
void lower();
WId winId() const;
- QPlatformGLContext *glContext() const;
-
private:
IDirectFBWindow *m_dfbWindow;
QDirectFbInput *m_inputHandler;
-
- QPlatformGLContext *m_context;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/directfb/qdirectfbwindowsurface.cpp b/src/plugins/platforms/directfb/qdirectfbwindowsurface.cpp
index 730f01fa1b..ab355c48f4 100644
--- a/src/plugins/platforms/directfb/qdirectfbwindowsurface.cpp
+++ b/src/plugins/platforms/directfb/qdirectfbwindowsurface.cpp
@@ -49,21 +49,21 @@
QT_BEGIN_NAMESPACE
-QDirectFbWindowSurface::QDirectFbWindowSurface(QWidget *window, WId wId)
- : QWindowSurface(window), m_pixmap(0), m_pmdata(0), m_dfbSurface(0)
+QDirectFbWindowSurface::QDirectFbWindowSurface(QWindow *window)
+ : QPlatformBackingStore(window), m_pixmap(0), m_pmdata(0), m_dfbSurface(0)
{
IDirectFBDisplayLayer *layer = QDirectFbConvenience::dfbDisplayLayer();
- DFBWindowID id(wId);
+ DFBWindowID id(window->winId());
IDirectFBWindow *dfbWindow;
layer->GetWindow(layer,id,&dfbWindow);
dfbWindow->GetSurface(dfbWindow,&m_dfbSurface);
//WRONGSIZE
- QDirectFbBlitter *blitter = new QDirectFbBlitter(window->rect().size(), m_dfbSurface);
- m_pmdata = new QDirectFbBlitterPixmapData;
+ QDirectFbBlitter *blitter = new QDirectFbBlitter(window->size(), m_dfbSurface);
+ m_pmdata = new QDirectFbBlitterPlatformPixmap;
m_pmdata->setBlittable(blitter);
m_pixmap = new QPixmap(m_pmdata);
}
@@ -78,9 +78,8 @@ QPaintDevice *QDirectFbWindowSurface::paintDevice()
return m_pixmap;
}
-void QDirectFbWindowSurface::flush(QWidget *widget, const QRegion &region, const QPoint &offset)
+void QDirectFbWindowSurface::flush(QWindow *, const QRegion &region, const QPoint &offset)
{
- Q_UNUSED(widget);
m_pmdata->blittable()->unlock();
QVector<QRect> rects = region.rects();
@@ -91,9 +90,9 @@ void QDirectFbWindowSurface::flush(QWidget *widget, const QRegion &region, const
}
}
-void QDirectFbWindowSurface::resize(const QSize &size)
+void QDirectFbWindowSurface::resize(const QSize &size, const QRegion& reg)
{
- QWindowSurface::resize(size);
+ QPlatformBackingStore::resize(size, reg);
//Have to add 1 ref ass it will be removed by deleting the old blitter in setBlittable
m_dfbSurface->AddRef(m_dfbSurface);
diff --git a/src/plugins/platforms/directfb/qdirectfbwindowsurface.h b/src/plugins/platforms/directfb/qdirectfbwindowsurface.h
index 7f1140d4eb..2b6cb58aef 100644
--- a/src/plugins/platforms/directfb/qdirectfbwindowsurface.h
+++ b/src/plugins/platforms/directfb/qdirectfbwindowsurface.h
@@ -42,22 +42,22 @@
#ifndef QWINDOWSURFACE_DIRECTFB_H
#define QWINDOWSURFACE_DIRECTFB_H
-#include <QtGui/private/qwindowsurface_p.h>
+#include <qplatformbackingstore_qpa.h>
#include <private/qpixmap_blitter_p.h>
#include <directfb.h>
QT_BEGIN_NAMESPACE
-class QDirectFbWindowSurface : public QWindowSurface
+class QDirectFbWindowSurface : public QPlatformBackingStore
{
public:
- QDirectFbWindowSurface(QWidget *window, WId wid);
+ QDirectFbWindowSurface(QWindow *window);
~QDirectFbWindowSurface();
QPaintDevice *paintDevice();
- void flush(QWidget *widget, const QRegion &region, const QPoint &offset);
- void resize (const QSize &size);
+ void flush(QWindow *window, const QRegion &region, const QPoint &offset);
+ void resize (const QSize &size, const QRegion &staticContents);
bool scroll(const QRegion &area, int dx, int dy);
void beginPaint(const QRegion &region);
@@ -67,7 +67,7 @@ private:
void lockSurfaceToImage();
QPixmap *m_pixmap;
- QBlittablePixmapData *m_pmdata;
+ QBlittablePlatformPixmap *m_pmdata;
IDirectFBSurface *m_dfbSurface;
};
diff --git a/src/plugins/platforms/eglconvenience/eglconvenience.pri b/src/plugins/platforms/eglconvenience/eglconvenience.pri
deleted file mode 100644
index 322d4e4633..0000000000
--- a/src/plugins/platforms/eglconvenience/eglconvenience.pri
+++ /dev/null
@@ -1,7 +0,0 @@
-INCLUDEPATH += $$PWD
-
-SOURCES += \
- $$PWD/qeglconvenience.cpp
-
-HEADERS += \
- $$PWD/qeglconvenience.h
diff --git a/src/plugins/platforms/eglconvenience/qeglconvenience.cpp b/src/plugins/platforms/eglconvenience/qeglconvenience.cpp
deleted file mode 100644
index 69747a87e8..0000000000
--- a/src/plugins/platforms/eglconvenience/qeglconvenience.cpp
+++ /dev/null
@@ -1,324 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qeglconvenience.h"
-
-QT_BEGIN_NAMESPACE
-
-QVector<EGLint> q_createConfigAttributesFromFormat(const QPlatformWindowFormat &format)
-{
- int redSize = format.redBufferSize();
- int greenSize = format.greenBufferSize();
- int blueSize = format.blueBufferSize();
- int alphaSize = format.alphaBufferSize();
- int depthSize = format.depthBufferSize();
- int stencilSize = format.stencilBufferSize();
- int sampleCount = format.samples();
-
- // QPlatformWindowFormat uses a magic value of -1 to indicate "don't care", even when a buffer of that
- // type has been requested. So we must check QPlatformWindowFormat's booleans too if size is -1:
- if (format.alpha() && alphaSize <= 0)
- alphaSize = 1;
- if (format.depth() && depthSize <= 0)
- depthSize = 1;
- if (format.stencil() && stencilSize <= 0)
- stencilSize = 1;
- if (format.sampleBuffers() && sampleCount <= 0)
- sampleCount = 1;
-
- // We want to make sure 16-bit configs are chosen over 32-bit configs as they will provide
- // the best performance. The EGL config selection algorithm is a bit stange in this regard:
- // The selection criteria for EGL_BUFFER_SIZE is "AtLeast", so we can't use it to discard
- // 32-bit configs completely from the selection. So it then comes to the sorting algorithm.
- // The red/green/blue sizes have a sort priority of 3, so they are sorted by first. The sort
- // order is special and described as "by larger _total_ number of color bits.". So EGL will
- // put 32-bit configs in the list before the 16-bit configs. However, the spec also goes on
- // to say "If the requested number of bits in attrib_list for a particular component is 0,
- // then the number of bits for that component is not considered". This part of the spec also
- // seems to imply that setting the red/green/blue bits to zero means none of the components
- // are considered and EGL disregards the entire sorting rule. It then looks to the next
- // highest priority rule, which is EGL_BUFFER_SIZE. Despite the selection criteria being
- // "AtLeast" for EGL_BUFFER_SIZE, it's sort order is "smaller" meaning 16-bit configs are
- // put in the list before 32-bit configs. So, to make sure 16-bit is preffered over 32-bit,
- // we must set the red/green/blue sizes to zero. This has an unfortunate consequence that
- // if the application sets the red/green/blue size to 5/6/5 on the QPlatformWindowFormat,
- // they will probably get a 32-bit config, even when there's an RGB565 config available.
-
- // Now normalize the values so -1 becomes 0
- redSize = redSize > 0 ? redSize : 0;
- greenSize = greenSize > 0 ? greenSize : 0;
- blueSize = blueSize > 0 ? blueSize : 0;
- alphaSize = alphaSize > 0 ? alphaSize : 0;
- depthSize = depthSize > 0 ? depthSize : 0;
- stencilSize = stencilSize > 0 ? stencilSize : 0;
- sampleCount = sampleCount > 0 ? sampleCount : 0;
-
- QVector<EGLint> configAttributes;
-
- configAttributes.append(EGL_RED_SIZE);
- configAttributes.append(redSize);
-
- configAttributes.append(EGL_GREEN_SIZE);
- configAttributes.append(greenSize);
-
- configAttributes.append(EGL_BLUE_SIZE);
- configAttributes.append(blueSize);
-
- configAttributes.append(EGL_ALPHA_SIZE);
- configAttributes.append(alphaSize);
-
- configAttributes.append(EGL_DEPTH_SIZE);
- configAttributes.append(depthSize);
-
- configAttributes.append(EGL_STENCIL_SIZE);
- configAttributes.append(stencilSize);
-
- configAttributes.append(EGL_SAMPLES);
- configAttributes.append(sampleCount);
-
- configAttributes.append(EGL_SAMPLE_BUFFERS);
- configAttributes.append(sampleCount? 1:0);
-
- return configAttributes;
-}
-
-bool q_reduceConfigAttributes(QVector<EGLint> *configAttributes)
-{
- int i = -1;
- // Reduce the complexity of a configuration request to ask for less
- // because the previous request did not result in success. Returns
- // true if the complexity was reduced, or false if no further
- // reductions in complexity are possible.
-
- i = configAttributes->indexOf(EGL_SWAP_BEHAVIOR);
- if (i >= 0) {
- configAttributes->remove(i,2);
- }
-
-#ifdef EGL_VG_ALPHA_FORMAT_PRE_BIT
- // For OpenVG, we sometimes try to create a surface using a pre-multiplied format. If we can't
- // find a config which supports pre-multiplied formats, remove the flag on the surface type:
-
- i = configAttributes->indexOf(EGL_SURFACE_TYPE);
- if (i >= 0) {
- EGLint surfaceType = configAttributes->at(i +1);
- if (surfaceType & EGL_VG_ALPHA_FORMAT_PRE_BIT) {
- surfaceType ^= EGL_VG_ALPHA_FORMAT_PRE_BIT;
- configAttributes->replace(i+1,surfaceType);
- return true;
- }
- }
-#endif
-
- // EGL chooses configs with the highest color depth over
- // those with smaller (but faster) lower color depths. One
- // way around this is to set EGL_BUFFER_SIZE to 16, which
- // trumps the others. Of course, there may not be a 16-bit
- // config available, so it's the first restraint we remove.
- i = configAttributes->indexOf(EGL_BUFFER_SIZE);
- if (i >= 0) {
- if (configAttributes->at(i+1) == 16) {
- configAttributes->remove(i,2);
- return true;
- }
- }
-
- i = configAttributes->indexOf(EGL_SAMPLE_BUFFERS);
- if (i >= 0) {
- configAttributes->remove(i,2);
- i = configAttributes->indexOf(EGL_SAMPLES);
- if (i >= 0) {
- configAttributes->remove(i,2);
- }
- return true;
- }
-
- i = configAttributes->indexOf(EGL_ALPHA_SIZE);
- if (i >= 0) {
- configAttributes->remove(i,2);
-#if defined(EGL_BIND_TO_TEXTURE_RGBA) && defined(EGL_BIND_TO_TEXTURE_RGB)
- i = configAttributes->indexOf(EGL_BIND_TO_TEXTURE_RGBA);
- if (i >= 0) {
- configAttributes->replace(i,EGL_BIND_TO_TEXTURE_RGB);
- configAttributes->replace(i+1,TRUE);
-
- }
-#endif
- return true;
- }
-
- i = configAttributes->indexOf(EGL_STENCIL_SIZE);
- if (i >= 0) {
- configAttributes->remove(i,2);
- return true;
- }
- i = configAttributes->indexOf(EGL_DEPTH_SIZE);
- if (i >= 0) {
- configAttributes->remove(i,2);
- return true;
- }
-#ifdef EGL_BIND_TO_TEXTURE_RGB
- i = configAttributes->indexOf(EGL_BIND_TO_TEXTURE_RGB);
- if (i >= 0) {
- configAttributes->remove(i,2);
- return true;
- }
-#endif
-
- return false;
-}
-
-EGLConfig q_configFromQPlatformWindowFormat(EGLDisplay display, const QPlatformWindowFormat &format, bool highestPixelFormat, int surfaceType)
-{
- EGLConfig cfg = 0;
- QVector<EGLint> configureAttributes = q_createConfigAttributesFromFormat(format);
- configureAttributes.append(EGL_SURFACE_TYPE); //we only support eglconfigs for windows for now
- configureAttributes.append(surfaceType);
-
- configureAttributes.append(EGL_RENDERABLE_TYPE);
- if (format.windowApi() == QPlatformWindowFormat::OpenVG) {
- configureAttributes.append(EGL_OPENVG_BIT);
- } else {
- configureAttributes.append(EGL_OPENGL_ES2_BIT);
- }
- configureAttributes.append(EGL_NONE);
-
- do {
- // Get the number of matching configurations for this set of properties.
- EGLint matching = 0;
- if (!eglChooseConfig(display, configureAttributes.constData(), 0, 0, &matching) || !matching)
- continue;
-
- // If we want the best pixel format, then return the first
- // matching configuration.
- if (highestPixelFormat) {
- eglChooseConfig(display, configureAttributes.constData(), &cfg, 1, &matching);
- if (matching < 1)
- continue;
- return cfg;
- }
-
- // Fetch all of the matching configurations and find the
- // first that matches the pixel format we wanted.
- int i = configureAttributes.indexOf(EGL_RED_SIZE);
- int confAttrRed = configureAttributes.at(i+1);
- i = configureAttributes.indexOf(EGL_GREEN_SIZE);
- int confAttrGreen = configureAttributes.at(i+1);
- i = configureAttributes.indexOf(EGL_BLUE_SIZE);
- int confAttrBlue = configureAttributes.at(i+1);
- i = configureAttributes.indexOf(EGL_ALPHA_SIZE);
- int confAttrAlpha = configureAttributes.at(i+1);
-
- EGLint size = matching;
- EGLConfig *configs = new EGLConfig [size];
- eglChooseConfig(display, configureAttributes.constData(), configs, size, &matching);
- for (EGLint index = 0; index < size; ++index) {
- EGLint red, green, blue, alpha;
- eglGetConfigAttrib(display, configs[index], EGL_RED_SIZE, &red);
- eglGetConfigAttrib(display, configs[index], EGL_GREEN_SIZE, &green);
- eglGetConfigAttrib(display, configs[index], EGL_BLUE_SIZE, &blue);
- eglGetConfigAttrib(display, configs[index], EGL_ALPHA_SIZE, &alpha);
- if (red == confAttrRed &&
- green == confAttrGreen &&
- blue == confAttrBlue &&
- (confAttrAlpha == 0 ||
- alpha == confAttrAlpha)) {
- cfg = configs[index];
- delete [] configs;
- return cfg;
- }
- }
- delete [] configs;
- } while (q_reduceConfigAttributes(&configureAttributes));
- qWarning("Cant find EGLConfig, returning null config");
- return 0;
-}
-
-QPlatformWindowFormat qt_qPlatformWindowFormatFromConfig(EGLDisplay display, const EGLConfig config)
-{
- QPlatformWindowFormat format;
- EGLint redSize = 0;
- EGLint greenSize = 0;
- EGLint blueSize = 0;
- EGLint alphaSize = 0;
- EGLint depthSize = 0;
- EGLint stencilSize = 0;
- EGLint sampleCount = 0;
- EGLint level = 0;
-
- eglGetConfigAttrib(display, config, EGL_RED_SIZE, &redSize);
- eglGetConfigAttrib(display, config, EGL_GREEN_SIZE, &greenSize);
- eglGetConfigAttrib(display, config, EGL_BLUE_SIZE, &blueSize);
- eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &alphaSize);
- eglGetConfigAttrib(display, config, EGL_DEPTH_SIZE, &depthSize);
- eglGetConfigAttrib(display, config, EGL_STENCIL_SIZE, &stencilSize);
- eglGetConfigAttrib(display, config, EGL_SAMPLES, &sampleCount);
- eglGetConfigAttrib(display, config, EGL_LEVEL, &level);
-
- format.setRedBufferSize(redSize);
- format.setGreenBufferSize(greenSize);
- format.setBlueBufferSize(blueSize);
- format.setAlphaBufferSize(alphaSize);
- format.setDepthBufferSize(depthSize);
- format.setStencilBufferSize(stencilSize);
- format.setSamples(sampleCount);
- format.setDirectRendering(true); // All EGL contexts are direct-rendered
- format.setRgba(true); // EGL doesn't support colour index rendering
- format.setStereo(false); // EGL doesn't support stereo buffers
- format.setAccumBufferSize(0); // EGL doesn't support accululation buffers
-
- // Clear the EGL error state because some of the above may
- // have errored out because the attribute is not applicable
- // to the surface type. Such errors don't matter.
- eglGetError();
-
- return format;
-}
-
-bool q_hasEglExtension(EGLDisplay display, const char* extensionName)
-{
- QList<QByteArray> extensions =
- QByteArray(reinterpret_cast<const char *>
- (eglQueryString(display, EGL_EXTENSIONS))).split(' ');
- return extensions.contains(extensionName);
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglconvenience/qeglconvenience.h b/src/plugins/platforms/eglconvenience/qeglconvenience.h
deleted file mode 100644
index da4a0cdded..0000000000
--- a/src/plugins/platforms/eglconvenience/qeglconvenience.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QEGLCONVENIENCE_H
-#define QEGLCONVENIENCE_H
-
-
-#include <QtGui/QPlatformWindowFormat>
-#include <QtCore/QVector>
-
-#include <EGL/egl.h>
-QT_BEGIN_NAMESPACE
-
-QVector<EGLint> q_createConfigAttributesFromFormat(const QPlatformWindowFormat &format);
-bool q_reduceConfigAttributes(QVector<EGLint> *configAttributes);
-EGLConfig q_configFromQPlatformWindowFormat(EGLDisplay display, const QPlatformWindowFormat &format, bool highestPixelFormat = false, int surfaceType = EGL_WINDOW_BIT);
-QPlatformWindowFormat qt_qPlatformWindowFormatFromConfig(EGLDisplay display, const EGLConfig config);
-bool q_hasEglExtension(EGLDisplay display,const char* extensionName);
-
-QT_END_NAMESPACE
-
-#endif //QEGLCONVENIENCE_H
diff --git a/src/plugins/platforms/eglconvenience/qeglplatformcontext.cpp b/src/plugins/platforms/eglconvenience/qeglplatformcontext.cpp
deleted file mode 100644
index 4d1d63e37f..0000000000
--- a/src/plugins/platforms/eglconvenience/qeglplatformcontext.cpp
+++ /dev/null
@@ -1,157 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qeglplatformcontext.h"
-
-
-#include <QtGui/QPlatformWindow>
-
-#include "qeglconvenience.h"
-
-#include <EGL/egl.h>
-
-QEGLPlatformContext::QEGLPlatformContext(EGLDisplay display, EGLConfig config, EGLint contextAttrs[], EGLSurface surface, EGLenum eglApi)
- : QPlatformGLContext()
- , m_eglDisplay(display)
- , m_eglSurface(surface)
- , m_eglApi(eglApi)
-{
- if (m_eglSurface == EGL_NO_SURFACE) {
- qWarning("Createing QEGLPlatformContext with no surface");
- }
-
- eglBindAPI(m_eglApi);
- m_eglContext = eglCreateContext(m_eglDisplay,config, 0,contextAttrs);
- if (m_eglContext == EGL_NO_CONTEXT) {
- qWarning("Could not create the egl context\n");
- eglTerminate(m_eglDisplay);
- qFatal("EGL error");
- }
-
- m_windowFormat = qt_qPlatformWindowFormatFromConfig(display,config);
-}
-
-QEGLPlatformContext::~QEGLPlatformContext()
-{
-#ifdef QEGL_EXTRA_DEBUG
- qWarning("QEglContext::~QEglContext(): %p\n",this);
-#endif
- if (m_eglSurface != EGL_NO_SURFACE) {
- doneCurrent();
- eglDestroySurface(m_eglDisplay, m_eglSurface);
- m_eglSurface = EGL_NO_SURFACE;
- }
-
- if (m_eglContext != EGL_NO_CONTEXT) {
- eglDestroyContext(m_eglDisplay, m_eglContext);
- m_eglContext = EGL_NO_CONTEXT;
- }
-}
-
-void QEGLPlatformContext::makeCurrent()
-{
- QPlatformGLContext::makeCurrent();
-#ifdef QEGL_EXTRA_DEBUG
- qWarning("QEglContext::makeCurrent: %p\n",this);
-#endif
- eglBindAPI(m_eglApi);
- bool ok = eglMakeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext);
- if (!ok)
- qWarning("QEGLPlatformContext::makeCurrent: eglError: %d, this: %p \n", eglGetError(), this);
-#ifdef QEGL_EXTRA_DEBUG
- static bool showDebug = true;
- if (showDebug) {
- showDebug = false;
- const char *str = (const char*)glGetString(GL_VENDOR);
- qWarning("Vendor %s\n", str);
- str = (const char*)glGetString(GL_RENDERER);
- qWarning("Renderer %s\n", str);
- str = (const char*)glGetString(GL_VERSION);
- qWarning("Version %s\n", str);
-
- str = (const char*)glGetString(GL_SHADING_LANGUAGE_VERSION);
- qWarning("Extensions %s\n",str);
-
- str = (const char*)glGetString(GL_EXTENSIONS);
- qWarning("Extensions %s\n", str);
-
- }
-#endif
-}
-void QEGLPlatformContext::doneCurrent()
-{
- QPlatformGLContext::doneCurrent();
-#ifdef QEGL_EXTRA_DEBUG
- qWarning("QEglContext::doneCurrent:%p\n",this);
-#endif
- eglBindAPI(m_eglApi);
- bool ok = eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
- if (!ok)
- qWarning("QEGLPlatformContext::doneCurrent(): eglError: %d, this: %p \n", eglGetError(), this);
-}
-void QEGLPlatformContext::swapBuffers()
-{
-#ifdef QEGL_EXTRA_DEBUG
- qWarning("QEglContext::swapBuffers:%p\n",this);
-#endif
- eglBindAPI(m_eglApi);
- bool ok = eglSwapBuffers(m_eglDisplay, m_eglSurface);
- if (!ok)
- qWarning("QEGLPlatformContext::swapBuffers(): eglError: %d, this: %p \n", eglGetError(), this);
-}
-void* QEGLPlatformContext::getProcAddress(const QString& procName)
-{
-#ifdef QEGL_EXTRA_DEBUG
- qWarning("QEglContext::getProcAddress%p\n",this);
-#endif
- eglBindAPI(m_eglApi);
- return (void *)eglGetProcAddress(qPrintable(procName));
-}
-
-QPlatformWindowFormat QEGLPlatformContext::platformWindowFormat() const
-{
- return m_windowFormat;
-}
-
-EGLContext QEGLPlatformContext::eglContext() const
-{
- return m_eglContext;
-}
diff --git a/src/plugins/platforms/eglconvenience/qeglplatformcontext.h b/src/plugins/platforms/eglconvenience/qeglplatformcontext.h
deleted file mode 100644
index 9be1480735..0000000000
--- a/src/plugins/platforms/eglconvenience/qeglplatformcontext.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QOPENKODEGLINTEGRATION_H
-#define QOPENKODEGLINTEGRATION_H
-
-#include <QtGui/QPlatformGLContext>
-#include <EGL/egl.h>
-
-class QEGLPlatformContext : public QPlatformGLContext
-{
-public:
- QEGLPlatformContext(EGLDisplay display, EGLConfig config, EGLint contextAttrs[], EGLSurface surface, EGLenum eglApi);
- ~QEGLPlatformContext();
-
- void makeCurrent();
- void doneCurrent();
- void swapBuffers();
- void* getProcAddress(const QString& procName);
-
- QPlatformWindowFormat platformWindowFormat() const;
-
- EGLContext eglContext() const;
-private:
- EGLContext m_eglContext;
- EGLDisplay m_eglDisplay;
- EGLSurface m_eglSurface;
- EGLenum m_eglApi;
-
- QPlatformWindowFormat m_windowFormat;
-};
-
-#endif //QOPENKODEGLINTEGRATION_H
diff --git a/src/plugins/platforms/eglconvenience/qxlibeglintegration.cpp b/src/plugins/platforms/eglconvenience/qxlibeglintegration.cpp
deleted file mode 100644
index cbd8f7d7c6..0000000000
--- a/src/plugins/platforms/eglconvenience/qxlibeglintegration.cpp
+++ /dev/null
@@ -1,184 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qxlibeglintegration.h"
-
-static int countBits(unsigned long mask)
-{
- int count = 0;
- while (mask != 0) {
- if (mask & 1)
- ++count;
- mask >>= 1;
- }
- return count;
-}
-
-VisualID QXlibEglIntegration::getCompatibleVisualId(Display *display, EGLDisplay eglDisplay, EGLConfig config)
-{
- VisualID visualId = 0;
- EGLint eglValue = 0;
-
- EGLint configRedSize = 0;
- eglGetConfigAttrib(eglDisplay, config, EGL_RED_SIZE, &configRedSize);
-
- EGLint configGreenSize = 0;
- eglGetConfigAttrib(eglDisplay, config, EGL_GREEN_SIZE, &configGreenSize);
-
- EGLint configBlueSize = 0;
- eglGetConfigAttrib(eglDisplay, config, EGL_BLUE_SIZE, &configBlueSize);
-
- EGLint configAlphaSize = 0;
- eglGetConfigAttrib(eglDisplay, config, EGL_ALPHA_SIZE, &configAlphaSize);
-
- eglGetConfigAttrib(eglDisplay, config, EGL_CONFIG_ID, &eglValue);
- int configId = eglValue;
-
- // See if EGL provided a valid VisualID:
- eglGetConfigAttrib(eglDisplay, config, EGL_NATIVE_VISUAL_ID, &eglValue);
- visualId = (VisualID)eglValue;
- if (visualId) {
- // EGL has suggested a visual id, so get the rest of the visual info for that id:
- XVisualInfo visualInfoTemplate;
- memset(&visualInfoTemplate, 0, sizeof(XVisualInfo));
- visualInfoTemplate.visualid = visualId;
-
- XVisualInfo *chosenVisualInfo;
- int matchingCount = 0;
- chosenVisualInfo = XGetVisualInfo(display, VisualIDMask, &visualInfoTemplate, &matchingCount);
- if (chosenVisualInfo) {
- // Skip size checks if implementation supports non-matching visual
- // and config (http://bugreports.qt.nokia.com/browse/QTBUG-9444).
- if (q_hasEglExtension(eglDisplay,"EGL_NV_post_convert_rounding")) {
- XFree(chosenVisualInfo);
- return visualId;
- }
-
- int visualRedSize = countBits(chosenVisualInfo->red_mask);
- int visualGreenSize = countBits(chosenVisualInfo->green_mask);
- int visualBlueSize = countBits(chosenVisualInfo->blue_mask);
- int visualAlphaSize = -1; // Need XRender to tell us the alpha channel size
-
- bool visualMatchesConfig = false;
- if ( visualRedSize == configRedSize &&
- visualGreenSize == configGreenSize &&
- visualBlueSize == configBlueSize )
- {
- // We need XRender to check the alpha channel size of the visual. If we don't have
- // the alpha size, we don't check it against the EGL config's alpha size.
- if (visualAlphaSize >= 0)
- visualMatchesConfig = visualAlphaSize == configAlphaSize;
- else
- visualMatchesConfig = true;
- }
-
- if (!visualMatchesConfig) {
- if (visualAlphaSize >= 0) {
- qWarning("Warning: EGL suggested using X Visual ID %d (ARGB%d%d%d%d) for EGL config %d (ARGB%d%d%d%d), but this is incompatable",
- (int)visualId, visualAlphaSize, visualRedSize, visualGreenSize, visualBlueSize,
- configId, configAlphaSize, configRedSize, configGreenSize, configBlueSize);
- } else {
- qWarning("Warning: EGL suggested using X Visual ID %d (RGB%d%d%d) for EGL config %d (RGB%d%d%d), but this is incompatable",
- (int)visualId, visualRedSize, visualGreenSize, visualBlueSize,
- configId, configRedSize, configGreenSize, configBlueSize);
- }
- visualId = 0;
- }
- } else {
- qWarning("Warning: EGL suggested using X Visual ID %d for EGL config %d, but that isn't a valid ID",
- (int)visualId, configId);
- visualId = 0;
- }
- XFree(chosenVisualInfo);
- }
-#ifdef QT_DEBUG_X11_VISUAL_SELECTION
- else
- qDebug("EGL did not suggest a VisualID (EGL_NATIVE_VISUAL_ID was zero) for EGLConfig %d", configId);
-#endif
-
- if (visualId) {
-#ifdef QT_DEBUG_X11_VISUAL_SELECTION
- if (configAlphaSize > 0)
- qDebug("Using ARGB Visual ID %d provided by EGL for config %d", (int)visualId, configId);
- else
- qDebug("Using Opaque Visual ID %d provided by EGL for config %d", (int)visualId, configId);
-#endif
- return visualId;
- }
-
- // Finally, try to
- // use XGetVisualInfo and only use the bit depths to match on:
- if (!visualId) {
- XVisualInfo visualInfoTemplate;
- memset(&visualInfoTemplate, 0, sizeof(XVisualInfo));
- XVisualInfo *matchingVisuals;
- int matchingCount = 0;
-
- visualInfoTemplate.depth = configRedSize + configGreenSize + configBlueSize + configAlphaSize;
- matchingVisuals = XGetVisualInfo(display,
- VisualDepthMask,
- &visualInfoTemplate,
- &matchingCount);
- if (!matchingVisuals) {
- // Try again without taking the alpha channel into account:
- visualInfoTemplate.depth = configRedSize + configGreenSize + configBlueSize;
- matchingVisuals = XGetVisualInfo(display,
- VisualDepthMask,
- &visualInfoTemplate,
- &matchingCount);
- }
-
- if (matchingVisuals) {
- visualId = matchingVisuals[0].visualid;
- XFree(matchingVisuals);
- }
- }
-
- if (visualId) {
-#ifdef QT_DEBUG_X11_VISUAL_SELECTION
- qDebug("Using Visual ID %d provided by XGetVisualInfo for EGL config %d", (int)visualId, configId);
-#endif
- return visualId;
- }
-
- qWarning("Unable to find an X11 visual which matches EGL config %d", configId);
- return (VisualID)0;
-}
diff --git a/src/plugins/platforms/eglconvenience/qxlibeglintegration.h b/src/plugins/platforms/eglconvenience/qxlibeglintegration.h
deleted file mode 100644
index 1d02ab8677..0000000000
--- a/src/plugins/platforms/eglconvenience/qxlibeglintegration.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QTESTLITEEGLINTEGRATION_H
-#define QTESTLITEEGLINTEGRATION_H
-
-#include "qeglconvenience.h"
-
-class QXlibEglIntegration
-{
-public:
- static VisualID getCompatibleVisualId(Display *display, EGLDisplay eglDisplay, EGLConfig config);
-};
-
-#endif // QTESTLITEEGLINTEGRATION_H
diff --git a/src/plugins/platforms/eglconvenience/xlibeglintegration.pri b/src/plugins/platforms/eglconvenience/xlibeglintegration.pri
deleted file mode 100644
index 9404a70373..0000000000
--- a/src/plugins/platforms/eglconvenience/xlibeglintegration.pri
+++ /dev/null
@@ -1,7 +0,0 @@
-INCLUDEPATH += $$PWD
-
-HEADERS += \
- $$PWD/qxlibeglintegration.h
-
-SOURCES += \
- $$PWD/qxlibeglintegration.cpp
diff --git a/src/plugins/platforms/eglfs/eglfs.pro b/src/plugins/platforms/eglfs/eglfs.pro
index 471cf63dd8..73698322dd 100644
--- a/src/plugins/platforms/eglfs/eglfs.pro
+++ b/src/plugins/platforms/eglfs/eglfs.pro
@@ -2,7 +2,7 @@ TARGET = qeglfs
TEMPLATE = lib
CONFIG += plugin
-QT += opengl core-private gui-private opengl-private
+QT += opengl core-private gui-private opengl-private platformsupport-private widgets-private
DESTDIR = $$QT.gui.plugins/platforms
@@ -12,20 +12,16 @@ DESTDIR = $$QT.gui.plugins/platforms
SOURCES = main.cpp \
qeglfsintegration.cpp \
- ../eglconvenience/qeglconvenience.cpp \
- ../eglconvenience/qeglplatformcontext.cpp \
qeglfswindow.cpp \
- qeglfswindowsurface.cpp \
+ qeglfsbackingstore.cpp \
qeglfsscreen.cpp
HEADERS = qeglfsintegration.h \
- ../eglconvenience/qeglconvenience.h \
- ../eglconvenience/qeglplatformcontext.h \
qeglfswindow.h \
- qeglfswindowsurface.h \
+ qeglfsbackingstore.h \
qeglfsscreen.h
-include(../fontdatabases/genericunix/genericunix.pri)
+include(../../../platformsupport/fontdatabases/genericunix/genericunix.pri)
target.path += $$[QT_INSTALL_PLUGINS]/platforms
INSTALLS += target
diff --git a/src/plugins/platforms/eglfs/qeglfsbackingstore.cpp b/src/plugins/platforms/eglfs/qeglfsbackingstore.cpp
new file mode 100644
index 0000000000..1d27be7fb3
--- /dev/null
+++ b/src/plugins/platforms/eglfs/qeglfsbackingstore.cpp
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtOpenGL/private/qgl_p.h>
+
+#include "qeglfsbackingstore.h"
+
+#include <QtGui/QPlatformOpenGLContext>
+#include <QtGui/QScreen>
+
+#include <QtOpenGL/private/qglpaintdevice_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QEglFSPaintDevice : public QGLPaintDevice
+{
+public:
+ QEglFSPaintDevice(QEglFSScreen *screen)
+ :QGLPaintDevice(), m_screen(screen)
+ {
+ #ifdef QEGL_EXTRA_DEBUG
+ qWarning("QEglPaintDevice %p, %p",this, screen);
+ #endif
+ }
+
+ QSize size() const { return m_screen->geometry().size(); }
+ QGLContext* context() const { return QGLContext::fromOpenGLContext(m_screen->platformContext()->context()); }
+
+ QPaintEngine *paintEngine() const { return qt_qgl_paint_engine(); }
+
+ void beginPaint(){
+ QGLPaintDevice::beginPaint();
+ }
+private:
+ QEglFSScreen *m_screen;
+ QGLContext *m_context;
+};
+
+
+QEglFSBackingStore::QEglFSBackingStore(QWindow *window)
+ : QPlatformBackingStore(window)
+{
+#ifdef QEGL_EXTRA_DEBUG
+ qWarning("QEglBackingStore %p, %p", window, screen);
+#endif
+ m_paintDevice = new QEglFSPaintDevice(static_cast<QEglFSScreen *>(window->screen()->handle()));
+}
+
+void QEglFSBackingStore::flush(QWindow *widget, const QRegion &region, const QPoint &offset)
+{
+ Q_UNUSED(widget);
+ Q_UNUSED(region);
+ Q_UNUSED(offset);
+#ifdef QEGL_EXTRA_DEBUG
+ qWarning("QEglBackingStore::flush %p",widget);
+#endif
+ static_cast<QEglFSPaintDevice *>(m_paintDevice)->context()->swapBuffers();
+}
+
+void QEglFSBackingStore::resize(const QSize &size, const QRegion &staticContents)
+{
+ Q_UNUSED(size);
+ Q_UNUSED(staticContents);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/qeglfsbackingstore.h b/src/plugins/platforms/eglfs/qeglfsbackingstore.h
new file mode 100644
index 0000000000..d6a28a7665
--- /dev/null
+++ b/src/plugins/platforms/eglfs/qeglfsbackingstore.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QEGLWINDOWSURFACE_H
+#define QEGLWINDOWSURFACE_H
+
+#include "qeglfsintegration.h"
+#include "qeglfswindow.h"
+
+#include <QtGui/qplatformbackingstore_qpa.h>
+
+QT_BEGIN_NAMESPACE
+
+class QEglFSBackingStore : public QPlatformBackingStore
+{
+public:
+ QEglFSBackingStore(QWindow *window);
+ ~QEglFSBackingStore() {}
+
+ QPaintDevice *paintDevice() { return m_paintDevice; }
+ void flush(QWindow *window, const QRegion &region, const QPoint &offset);
+ void resize(const QSize &size, const QRegion &staticContents);
+
+private:
+ QPaintDevice *m_paintDevice;
+};
+
+QT_END_NAMESPACE
+
+#endif // QEGLWINDOWSURFACE_H
diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/qeglfsintegration.cpp
index 9e8596f19e..3d3e05d351 100644
--- a/src/plugins/platforms/eglfs/qeglfsintegration.cpp
+++ b/src/plugins/platforms/eglfs/qeglfsintegration.cpp
@@ -42,13 +42,15 @@
#include "qeglfsintegration.h"
#include "qeglfswindow.h"
-#include "qeglfswindowsurface.h"
+#include "qeglfsbackingstore.h"
-#include "qgenericunixfontdatabase.h"
+#include <QtPlatformSupport/private/qgenericunixfontdatabase_p.h>
+#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
#include <QtGui/QPlatformWindow>
-#include <QtGui/QPlatformWindowFormat>
-#include <QtGui/private/qpixmap_raster_p.h>
+#include <QtGui/QSurfaceFormat>
+#include <QtGui/QOpenGLContext>
+#include <QtGui/QScreen>
#include <EGL/egl.h>
@@ -57,9 +59,8 @@ QT_BEGIN_NAMESPACE
QEglFSIntegration::QEglFSIntegration()
: mFontDb(new QGenericUnixFontDatabase())
{
- m_primaryScreen = new QEglFSScreen(EGL_DEFAULT_DISPLAY);
+ screenAdded(new QEglFSScreen(EGL_DEFAULT_DISPLAY));
- mScreens.append(m_primaryScreen);
#ifdef QEGL_EXTRA_DEBUG
qWarning("QEglIntegration\n");
#endif
@@ -69,36 +70,32 @@ bool QEglFSIntegration::hasCapability(QPlatformIntegration::Capability cap) cons
{
switch (cap) {
case ThreadedPixmaps: return true;
+ case OpenGL: return true;
+ case ThreadedOpenGL: return true;
default: return QPlatformIntegration::hasCapability(cap);
}
}
-QPixmapData *QEglFSIntegration::createPixmapData(QPixmapData::PixelType type) const
+QPlatformWindow *QEglFSIntegration::createPlatformWindow(QWindow *window) const
{
#ifdef QEGL_EXTRA_DEBUG
- qWarning("QEglIntegration::createPixmapData %d\n", type);
+ qWarning("QEglIntegration::createPlatformWindow %p\n",window);
#endif
- return new QRasterPixmapData(type);
+ return new QEglFSWindow(window);
}
-QPlatformWindow *QEglFSIntegration::createPlatformWindow(QWidget *widget, WId winId) const
+
+QPlatformBackingStore *QEglFSIntegration::createPlatformBackingStore(QWindow *window) const
{
- Q_UNUSED(winId);
#ifdef QEGL_EXTRA_DEBUG
- qWarning("QEglIntegration::createPlatformWindow %p\n",widget);
+ qWarning("QEglIntegration::createWindowSurface %p\n",widget);
#endif
- return new QEglFSWindow(widget, m_primaryScreen);
+ return new QEglFSBackingStore(window);
}
-
-QWindowSurface *QEglFSIntegration::createWindowSurface(QWidget *widget, WId winId) const
+QPlatformOpenGLContext *QEglFSIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
{
- Q_UNUSED(winId);
-
-#ifdef QEGL_EXTRA_DEBUG
- qWarning("QEglIntegration::createWindowSurface %p\n",widget);
-#endif
- return new QEglFSWindowSurface(m_primaryScreen,widget);
+ return static_cast<QEglFSScreen *>(context->screen()->handle())->platformContext();
}
QPlatformFontDatabase *QEglFSIntegration::fontDatabase() const
@@ -106,4 +103,9 @@ QPlatformFontDatabase *QEglFSIntegration::fontDatabase() const
return mFontDb;
}
+QAbstractEventDispatcher *QEglFSIntegration::guiThreadEventDispatcher() const
+{
+ return createUnixEventDispatcher();
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.h b/src/plugins/platforms/eglfs/qeglfsintegration.h
index 6252a9c0e4..9538850faf 100644
--- a/src/plugins/platforms/eglfs/qeglfsintegration.h
+++ b/src/plugins/platforms/eglfs/qeglfsintegration.h
@@ -57,18 +57,17 @@ public:
QEglFSIntegration();
bool hasCapability(QPlatformIntegration::Capability cap) const;
- QPixmapData *createPixmapData(QPixmapData::PixelType type) const;
- QPlatformWindow *createPlatformWindow(QWidget *widget, WId winId) const;
- QWindowSurface *createWindowSurface(QWidget *widget, WId winId) const;
- QList<QPlatformScreen *> screens() const { return mScreens; }
+ QPlatformWindow *createPlatformWindow(QWindow *window) const;
+ QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const;
+ QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const;
QPlatformFontDatabase *fontDatabase() const;
+ QAbstractEventDispatcher *guiThreadEventDispatcher() const;
+
private:
QPlatformFontDatabase *mFontDb;
- QList<QPlatformScreen *> mScreens;
- QEglFSScreen *m_primaryScreen;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.cpp b/src/plugins/platforms/eglfs/qeglfsscreen.cpp
index 42195364ae..6f317a375f 100644
--- a/src/plugins/platforms/eglfs/qeglfsscreen.cpp
+++ b/src/plugins/platforms/eglfs/qeglfsscreen.cpp
@@ -40,9 +40,10 @@
****************************************************************************/
#include "qeglfsscreen.h"
+#include "qeglfswindow.h"
-#include "../eglconvenience/qeglconvenience.h"
-#include "../eglconvenience/qeglplatformcontext.h"
+#include <QtPlatformSupport/private/qeglconvenience_p.h>
+#include <QtPlatformSupport/private/qeglplatformcontext_p.h>
#ifdef Q_OPENKODE
#include <KD/kd.h>
@@ -86,6 +87,23 @@ static struct AttrInfo attrs[] = {
{-1, 0}};
#endif //QEGL_EXTRA_DEBUG
+class QEglFSContext : public QEGLPlatformContext
+{
+public:
+ QEglFSContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display,
+ EGLint eglClientVersion = 2, EGLenum eglApi = EGL_OPENGL_ES_API)
+ : QEGLPlatformContext(format, share, display, eglClientVersion, eglApi)
+ {
+ }
+
+ EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface)
+ {
+ QEglFSWindow *window = static_cast<QEglFSWindow *>(surface);
+ QEglFSScreen *screen = static_cast<QEglFSScreen *>(window->screen());
+ return screen->surface();
+ }
+};
+
QEglFSScreen::QEglFSScreen(EGLNativeDisplayType display)
: m_depth(32)
, m_format(QImage::Format_Invalid)
@@ -136,32 +154,29 @@ void QEglFSScreen::createAndSetPlatformContext() const {
void QEglFSScreen::createAndSetPlatformContext()
{
- QPlatformWindowFormat platformFormat = QPlatformWindowFormat::defaultFormat();
-
- platformFormat.setWindowApi(QPlatformWindowFormat::OpenGL);
+ QSurfaceFormat platformFormat;
QByteArray depthString = qgetenv("QT_QPA_EGLFS_DEPTH");
if (depthString.toInt() == 16) {
- platformFormat.setDepth(16);
+ platformFormat.setDepthBufferSize(16);
platformFormat.setRedBufferSize(5);
platformFormat.setGreenBufferSize(6);
platformFormat.setBlueBufferSize(5);
m_depth = 16;
m_format = QImage::Format_RGB16;
} else {
- platformFormat.setDepth(32);
+ platformFormat.setDepthBufferSize(32);
platformFormat.setRedBufferSize(8);
platformFormat.setGreenBufferSize(8);
platformFormat.setBlueBufferSize(8);
m_depth = 32;
m_format = QImage::Format_RGB32;
}
- if (!qgetenv("QT_QPA_EGLFS_MULTISAMPLE").isEmpty()) {
- platformFormat.setSampleBuffers(true);
- }
+ if (!qgetenv("QT_QPA_EGLFS_MULTISAMPLE").isEmpty())
+ platformFormat.setSamples(4);
- EGLConfig config = q_configFromQPlatformWindowFormat(m_dpy, platformFormat);
+ EGLConfig config = q_configFromGLFormat(m_dpy, platformFormat);
EGLNativeWindowType eglWindow = 0;
#ifdef Q_OPENKODE
@@ -193,16 +208,7 @@ void QEglFSScreen::createAndSetPlatformContext()
qWarning("\n");
#endif
- EGLint temp;
- EGLint attribList[32];
-
- temp = 0;
-
- attribList[temp++] = EGL_CONTEXT_CLIENT_VERSION;
- attribList[temp++] = 2; // GLES version 2
- attribList[temp++] = EGL_NONE;
-
- QEGLPlatformContext *platformContext = new QEGLPlatformContext(m_dpy,config,attribList,m_surface,EGL_OPENGL_ES_API);
+ QEGLPlatformContext *platformContext = new QEglFSContext(platformFormat, 0, m_dpy);
m_platformContext = platformContext;
EGLint w,h; // screen size detection
@@ -232,7 +238,7 @@ QImage::Format QEglFSScreen::format() const
createAndSetPlatformContext();
return m_format;
}
-QPlatformGLContext *QEglFSScreen::platformContext() const
+QPlatformOpenGLContext *QEglFSScreen::platformContext() const
{
if (!m_platformContext) {
QEglFSScreen *that = const_cast<QEglFSScreen *>(this);
diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.h b/src/plugins/platforms/eglfs/qeglfsscreen.h
index 5cf1daca6f..41465d871c 100644
--- a/src/plugins/platforms/eglfs/qeglfsscreen.h
+++ b/src/plugins/platforms/eglfs/qeglfsscreen.h
@@ -50,7 +50,7 @@
QT_BEGIN_NAMESPACE
-class QPlatformGLContext;
+class QPlatformOpenGLContext;
class QEglFSScreen : public QPlatformScreen //huh: FullScreenScreen ;) just to follow namespace
{
@@ -62,7 +62,9 @@ public:
int depth() const;
QImage::Format format() const;
- QPlatformGLContext *platformContext() const;
+ QPlatformOpenGLContext *platformContext() const;
+
+ EGLSurface surface() const { return m_surface; }
private:
void createAndSetPlatformContext() const;
@@ -71,7 +73,7 @@ private:
QRect m_geometry;
int m_depth;
QImage::Format m_format;
- QPlatformGLContext *m_platformContext;
+ QPlatformOpenGLContext *m_platformContext;
EGLDisplay m_dpy;
EGLSurface m_surface;
};
diff --git a/src/plugins/platforms/eglfs/qeglfswindow.cpp b/src/plugins/platforms/eglfs/qeglfswindow.cpp
index 24b17b75e7..a6115cc829 100644
--- a/src/plugins/platforms/eglfs/qeglfswindow.cpp
+++ b/src/plugins/platforms/eglfs/qeglfswindow.cpp
@@ -45,25 +45,26 @@
QT_BEGIN_NAMESPACE
-QEglFSWindow::QEglFSWindow(QWidget *w, QEglFSScreen *screen)
- : QPlatformWindow(w), m_screen(screen)
+QEglFSWindow::QEglFSWindow(QWindow *w)
+ : QPlatformWindow(w)
{
static int serialNo = 0;
m_winid = ++serialNo;
#ifdef QEGL_EXTRA_DEBUG
- qWarning("QEglWindow %p: %p %p 0x%x\n", this, w, screen, uint(m_winid));
+ qWarning("QEglWindow %p: %p 0x%x\n", this, w, uint(m_winid));
#endif
-}
+ QRect screenGeometry(screen()->availableGeometry());
+ if (w->geometry() != screenGeometry) {
+ QWindowSystemInterface::handleGeometryChange(w, screenGeometry);
+ }
+}
void QEglFSWindow::setGeometry(const QRect &)
{
// We only support full-screen windows
- QRect rect(m_screen->availableGeometry());
- QWindowSystemInterface::handleGeometryChange(this->widget(), rect);
-
- // Since toplevels are fullscreen, propegate the screen size back to the widget
- widget()->setGeometry(rect);
+ QRect rect(screen()->availableGeometry());
+ QWindowSystemInterface::handleGeometryChange(window(), rect);
QPlatformWindow::setGeometry(rect);
}
@@ -73,15 +74,4 @@ WId QEglFSWindow::winId() const
return m_winid;
}
-
-
-QPlatformGLContext *QEglFSWindow::glContext() const
-{
-#ifdef QEGL_EXTRA_DEBUG
- qWarning("QEglWindow::glContext %p\n", m_screen->platformContext());
-#endif
- Q_ASSERT(m_screen);
- return m_screen->platformContext();
-}
-
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/qeglfswindow.h b/src/plugins/platforms/eglfs/qeglfswindow.h
index 95a9ff51b9..09f553d3b7 100644
--- a/src/plugins/platforms/eglfs/qeglfswindow.h
+++ b/src/plugins/platforms/eglfs/qeglfswindow.h
@@ -46,22 +46,19 @@
#include "qeglfsscreen.h"
#include <QPlatformWindow>
-#include <QtGui/QWidget>
+#include <QtWidgets/QWidget>
QT_BEGIN_NAMESPACE
class QEglFSWindow : public QPlatformWindow
{
public:
- QEglFSWindow(QWidget *w, QEglFSScreen *screen);
+ QEglFSWindow(QWindow *w);
void setGeometry(const QRect &);
WId winId() const;
- QPlatformGLContext *glContext() const;
-
private:
- QEglFSScreen *m_screen;
WId m_winid;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/qeglfswindowsurface.cpp b/src/plugins/platforms/eglfs/qeglfswindowsurface.cpp
deleted file mode 100644
index 970402015f..0000000000
--- a/src/plugins/platforms/eglfs/qeglfswindowsurface.cpp
+++ /dev/null
@@ -1,101 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qeglfswindowsurface.h"
-
-#include <QtGui/QPlatformGLContext>
-
-#include <QtOpenGL/private/qgl_p.h>
-#include <QtOpenGL/private/qglpaintdevice_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QEglFSPaintDevice : public QGLPaintDevice
-{
-public:
- QEglFSPaintDevice(QEglFSScreen *screen, QWidget *widget)
- :QGLPaintDevice(), m_screen(screen)
- {
- #ifdef QEGL_EXTRA_DEBUG
- qWarning("QEglPaintDevice %p, %p, %p",this, screen, widget);
- #endif
- }
-
- QSize size() const { return m_screen->geometry().size(); }
- QGLContext* context() const { return QGLContext::fromPlatformGLContext(m_screen->platformContext());}
-
- QPaintEngine *paintEngine() const { return qt_qgl_paint_engine(); }
-
- void beginPaint(){
- QGLPaintDevice::beginPaint();
- }
-private:
- QEglFSScreen *m_screen;
- QGLContext *m_context;
-};
-
-
-QEglFSWindowSurface::QEglFSWindowSurface( QEglFSScreen *screen, QWidget *window )
- :QWindowSurface(window)
-{
-#ifdef QEGL_EXTRA_DEBUG
- qWarning("QEglWindowSurface %p, %p", window, screen);
-#endif
- m_paintDevice = new QEglFSPaintDevice(screen,window);
-}
-
-void QEglFSWindowSurface::flush(QWidget *widget, const QRegion &region, const QPoint &offset)
-{
- Q_UNUSED(widget);
- Q_UNUSED(region);
- Q_UNUSED(offset);
-#ifdef QEGL_EXTRA_DEBUG
- qWarning("QEglWindowSurface::flush %p",widget);
-#endif
- widget->platformWindow()->glContext()->swapBuffers();
-}
-
-void QEglFSWindowSurface::resize(const QSize &size)
-{
- Q_UNUSED(size);
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/qeglfswindowsurface.h b/src/plugins/platforms/eglfs/qeglfswindowsurface.h
deleted file mode 100644
index 9ce8fd4f53..0000000000
--- a/src/plugins/platforms/eglfs/qeglfswindowsurface.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QEGLWINDOWSURFACE_H
-#define QEGLWINDOWSURFACE_H
-
-#include "qeglfsintegration.h"
-#include "qeglfswindow.h"
-
-#include <QtGui/private/qwindowsurface_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QEglFSWindowSurface : public QWindowSurface
-{
-public:
- QEglFSWindowSurface(QEglFSScreen *screen, QWidget *window);
- ~QEglFSWindowSurface() {}
-
- QPaintDevice *paintDevice() { return m_paintDevice; }
- void flush(QWidget *widget, const QRegion &region, const QPoint &offset);
- void resize(const QSize &size);
-private:
- QPaintDevice *m_paintDevice;
-};
-
-QT_END_NAMESPACE
-
-#endif // QEGLWINDOWSURFACE_H
diff --git a/src/plugins/platforms/externalplugin.pri b/src/plugins/platforms/externalplugin.pri
deleted file mode 100644
index 9b00acb4e9..0000000000
--- a/src/plugins/platforms/externalplugin.pri
+++ /dev/null
@@ -1,29 +0,0 @@
-#
-# Lighthouse now has preliminarily support for building and
-# loading platform plugins from outside the Qt source/build
-# tree.
-#
-# 1) Building external plugins:
-# Set QTDIR to the Qt build directory, copy this file to
-# the plugin source repository and include it at the top
-# of the plugin's pro file. Use QT_SOURCE_TREE if you
-# want to pull in source code from Qt:
-#
-# include($$QT_SOURCE_TREE/src/plugins/platforms/fontdatabases/genericunix/genericunix.pri)
-#
-# 2) Loading external plugins:
-# Specify the path to the directory containing the
-# plugin on the command line, in addition to the
-# platform name.
-#
-# ./wiggly -platformPluginPath /path/to/myPlugin -platform gullfaksA
-#
-
-!exists($$(QTDIR)/.qmake.cache) {
- error("Please set QTDIR to the Qt build directory")
-}
-
-QT_SOURCE_TREE = $$fromfile($$(QTDIR)/.qmake.cache,QT_SOURCE_TREE)
-QT_BUILD_TREE = $$fromfile($$(QTDIR)/.qmake.cache,QT_BUILD_TREE)
-
-load(qt_plugin)
diff --git a/src/plugins/platforms/fb_base/fb_base.cpp b/src/plugins/platforms/fb_base/fb_base.cpp
deleted file mode 100644
index a83d739083..0000000000
--- a/src/plugins/platforms/fb_base/fb_base.cpp
+++ /dev/null
@@ -1,507 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "fb_base.h"
-#include <qpainter.h>
-#include <qdebug.h>
-#include <qbitmap.h>
-#include <QPlatformCursor>
-#include <QWindowSystemInterface>
-
-QPlatformSoftwareCursor::QPlatformSoftwareCursor(QPlatformScreen *scr)
- : QPlatformCursor(scr), currentRect(QRect()), prevRect(QRect())
-{
- graphic = new QPlatformCursorImage(0, 0, 0, 0, 0, 0);
- setCursor(Qt::ArrowCursor);
-}
-
-QRect QPlatformSoftwareCursor::getCurrentRect()
-{
- QRect rect = graphic->image()->rect().translated(-graphic->hotspot().x(),
- -graphic->hotspot().y());
- rect.translate(QCursor::pos());
- QPoint screenOffset = screen->geometry().topLeft();
- rect.translate(-screenOffset); // global to local translation
- return rect;
-}
-
-
-void QPlatformSoftwareCursor::pointerEvent(const QMouseEvent & e)
-{
- Q_UNUSED(e);
- QPoint screenOffset = screen->geometry().topLeft();
- currentRect = getCurrentRect();
- // global to local translation
- if (onScreen || screen->geometry().intersects(currentRect.translated(screenOffset))) {
- setDirty();
- }
-}
-
-QRect QPlatformSoftwareCursor::drawCursor(QPainter & painter)
-{
- dirty = false;
- if (currentRect.isNull())
- return QRect();
-
- // We need this because the cursor might be dirty due to moving off screen
- QPoint screenOffset = screen->geometry().topLeft();
- // global to local translation
- if (!currentRect.translated(screenOffset).intersects(screen->geometry()))
- return QRect();
-
- prevRect = currentRect;
- painter.drawImage(prevRect, *graphic->image());
- onScreen = true;
- return prevRect;
-}
-
-QRect QPlatformSoftwareCursor::dirtyRect()
-{
- if (onScreen) {
- onScreen = false;
- return prevRect;
- }
- return QRect();
-}
-
-void QPlatformSoftwareCursor::setCursor(Qt::CursorShape shape)
-{
- graphic->set(shape);
-}
-
-void QPlatformSoftwareCursor::setCursor(const QImage &image, int hotx, int hoty)
-{
- graphic->set(image, hotx, hoty);
-}
-
-void QPlatformSoftwareCursor::setCursor(const uchar *data, const uchar *mask, int width, int height, int hotX, int hotY)
-{
- graphic->set(data, mask, width, height, hotX, hotY);
-}
-
-void QPlatformSoftwareCursor::changeCursor(QCursor * widgetCursor, QWidget * widget)
-{
- Q_UNUSED(widget);
- Qt::CursorShape shape = widgetCursor->shape();
-
- if (shape == Qt::BitmapCursor) {
- // application supplied cursor
- QPoint spot = widgetCursor->hotSpot();
- setCursor(widgetCursor->pixmap().toImage(), spot.x(), spot.y());
- } else {
- // system cursor
- setCursor(shape);
- }
- currentRect = getCurrentRect();
- QPoint screenOffset = screen->geometry().topLeft(); // global to local translation
- if (onScreen || screen->geometry().intersects(currentRect.translated(screenOffset)))
- setDirty();
-}
-
-QFbScreen::QFbScreen() : cursor(0), mGeometry(), mDepth(16), mFormat(QImage::Format_RGB16), mScreenImage(0), compositePainter(0), isUpToDate(false)
-{
- mScreenImage = new QImage(mGeometry.size(), mFormat);
- redrawTimer.setSingleShot(true);
- redrawTimer.setInterval(0);
- QObject::connect(&redrawTimer, SIGNAL(timeout()), this, SLOT(doRedraw()));
-}
-
-void QFbScreen::setGeometry(QRect rect)
-{
- delete mScreenImage;
- mGeometry = rect;
- mScreenImage = new QImage(mGeometry.size(), mFormat);
- delete compositePainter;
- compositePainter = 0;
- invalidateRectCache();
-}
-
-void QFbScreen::setDepth(int depth)
-{
- mDepth = depth;
-}
-
-void QFbScreen::setPhysicalSize(QSize size)
-{
- mPhysicalSize = size;
-}
-
-void QFbScreen::setFormat(QImage::Format format)
-{
- mFormat = format;
- delete mScreenImage;
- mScreenImage = new QImage(mGeometry.size(), mFormat);
- delete compositePainter;
- compositePainter = 0;
-}
-
-QFbScreen::~QFbScreen()
-{
- delete compositePainter;
- delete mScreenImage;
-}
-
-void QFbScreen::setDirty(const QRect &rect)
-{
- QRect intersection = rect.intersected(mGeometry);
- QPoint screenOffset = mGeometry.topLeft();
- repaintRegion += intersection.translated(-screenOffset); // global to local translation
- if (!redrawTimer.isActive()) {
- redrawTimer.start();
- }
-}
-
-void QFbScreen::generateRects()
-{
- cachedRects.clear();
- QPoint screenOffset = mGeometry.topLeft();
- QRegion remainingScreen(mGeometry.translated(-screenOffset)); // global to local translation
-
- for (int i = 0; i < windowStack.length(); i++) {
- if (remainingScreen.isEmpty())
- break;
- if (!windowStack[i]->visible())
- continue;
- if (windowStack[i]->widget()->isMinimized())
- continue;
-
- if (!windowStack[i]->widget()->testAttribute(Qt::WA_TranslucentBackground)) {
- QRect localGeometry = windowStack.at(i)->geometry().translated(-screenOffset); // global to local translation
- remainingScreen -= localGeometry;
- QRegion windowRegion(localGeometry);
- windowRegion -= remainingScreen;
- foreach(QRect rect, windowRegion.rects()) {
- cachedRects += QPair<QRect, int>(rect, i);
- }
- }
- }
- foreach (QRect rect, remainingScreen.rects())
- cachedRects += QPair<QRect, int>(rect, -1);
- isUpToDate = true;
- return;
-}
-
-
-
-QRegion QFbScreen::doRedraw()
-{
- QPoint screenOffset = mGeometry.topLeft();
-
- QRegion touchedRegion;
- if (cursor && cursor->isDirty() && cursor->isOnScreen()) {
- QRect lastCursor = cursor->dirtyRect();
- repaintRegion += lastCursor;
- }
- if (repaintRegion.isEmpty() && (!cursor || !cursor->isDirty())) {
- return touchedRegion;
- }
-
- QVector<QRect> rects = repaintRegion.rects();
-
- if (!isUpToDate)
- generateRects();
-
- if (!compositePainter)
- compositePainter = new QPainter(mScreenImage);
- for (int rectIndex = 0; rectIndex < repaintRegion.numRects(); rectIndex++) {
- QRegion rectRegion = rects[rectIndex];
-
- for(int i = 0; i < cachedRects.length(); i++) {
- QRect screenSubRect = cachedRects[i].first;
- int layer = cachedRects[i].second;
- QRegion intersect = rectRegion.intersected(screenSubRect);
-
- if (intersect.isEmpty())
- continue;
-
- rectRegion -= intersect;
-
- // we only expect one rectangle, but defensive coding...
- foreach (QRect rect, intersect.rects()) {
- bool firstLayer = true;
- if (layer == -1) {
- compositePainter->fillRect(rect, Qt::black);
- firstLayer = false;
- layer = windowStack.size() - 1;
- }
-
- for (int layerIndex = layer; layerIndex != -1; layerIndex--) {
- if (!windowStack[layerIndex]->visible())
- continue;
- if (windowStack[layerIndex]->widget()->isMinimized())
- continue;
- QRect windowRect = windowStack[layerIndex]->geometry().translated(-screenOffset);
- QRect windowIntersect = rect.translated(-windowRect.left(),
- -windowRect.top());
- compositePainter->drawImage(rect, windowStack[layerIndex]->surface->image(),
- windowIntersect);
- if (firstLayer) {
- firstLayer = false;
- }
- }
- }
- }
- }
-
- QRect cursorRect;
- if (cursor && (cursor->isDirty() || repaintRegion.intersects(cursor->lastPainted()))) {
- cursorRect = cursor->drawCursor(*compositePainter);
- touchedRegion += cursorRect;
- }
- touchedRegion += repaintRegion;
- repaintRegion = QRegion();
-
-
-
-// qDebug() << "QFbScreen::doRedraw" << windowStack.size() << mScreenImage->size() << touchedRegion;
-
-
- return touchedRegion;
-}
-
-void QFbScreen::addWindow(QFbWindow *surface)
-{
- windowStack.prepend(surface);
- surface->mScreens.append(this);
- invalidateRectCache();
- setDirty(surface->geometry());
-}
-
-void QFbScreen::removeWindow(QFbWindow * surface)
-{
- windowStack.removeOne(surface);
- surface->mScreens.removeOne(this);
- invalidateRectCache();
- setDirty(surface->geometry());
-}
-
-void QFbWindow::raise()
-{
- QList<QFbScreen *>::const_iterator i = mScreens.constBegin();
- QList<QFbScreen *>::const_iterator end = mScreens.constEnd();
- while (i != end) {
- (*i)->raise(this);
- ++i;
- }
-}
-
-void QFbScreen::raise(QPlatformWindow * surface)
-{
- QFbWindow *s = static_cast<QFbWindow *>(surface);
- int index = windowStack.indexOf(s);
- if (index <= 0)
- return;
- windowStack.move(index, 0);
- invalidateRectCache();
- setDirty(s->geometry());
-}
-
-void QFbWindow::lower()
-{
- QList<QFbScreen *>::const_iterator i = mScreens.constBegin();
- QList<QFbScreen *>::const_iterator end = mScreens.constEnd();
- while (i != end) {
- (*i)->lower(this);
- ++i;
- }
-}
-
-void QFbScreen::lower(QPlatformWindow * surface)
-{
- QFbWindow *s = static_cast<QFbWindow *>(surface);
- int index = windowStack.indexOf(s);
- if (index == -1 || index == (windowStack.size() - 1))
- return;
- windowStack.move(index, windowStack.size() - 1);
- invalidateRectCache();
- setDirty(s->geometry());
-}
-
-QWidget * QFbScreen::topLevelAt(const QPoint & p) const
-{
- for(int i = 0; i < windowStack.size(); i++) {
- if (windowStack[i]->geometry().contains(p, false) &&
- windowStack[i]->visible() &&
- !windowStack[i]->widget()->isMinimized()) {
- return windowStack[i]->widget();
- }
- }
- return 0;
-}
-
-QFbWindow::QFbWindow(QWidget *window)
- :QPlatformWindow(window),
- visibleFlag(false)
-{
- static QAtomicInt winIdGenerator(1);
- windowId = winIdGenerator.fetchAndAddRelaxed(1);
-}
-
-
-QFbWindow::~QFbWindow()
-{
- QList<QFbScreen *>::const_iterator i = mScreens.constBegin();
- QList<QFbScreen *>::const_iterator end = mScreens.constEnd();
- while (i != end) {
- (*i)->removeWindow(this);
- ++i;
- }
-}
-
-
-QFbWindowSurface::QFbWindowSurface(QFbScreen *screen, QWidget *window)
- : QWindowSurface(window),
- mScreen(screen)
-{
- mImage = QImage(window->size(), mScreen->format());
-
- platformWindow = static_cast<QFbWindow*>(window->platformWindow());
- platformWindow->surface = this;
-}
-
-QFbWindowSurface::~QFbWindowSurface()
-{
-}
-
-void QFbWindowSurface::flush(QWidget *widget, const QRegion &region, const QPoint &offset)
-{
- Q_UNUSED(widget);
- Q_UNUSED(offset);
-
-
-// qDebug() << "QFbWindowSurface::flush" << region;
-
-
- platformWindow->repaint(region);
-}
-
-
-void QFbWindow::repaint(const QRegion &region)
-{
- QRect currentGeometry = geometry();
-
- QRect dirtyClient = region.boundingRect();
- QRect dirtyRegion(currentGeometry.left() + dirtyClient.left(),
- currentGeometry.top() + dirtyClient.top(),
- dirtyClient.width(),
- dirtyClient.height());
- QList<QFbScreen *>::const_iterator i = mScreens.constBegin();
- QList<QFbScreen *>::const_iterator end = mScreens.constEnd();
- QRect oldGeometryLocal = oldGeometry;
- oldGeometry = currentGeometry;
- while (i != end) {
- // If this is a move, redraw the previous location
- if (oldGeometryLocal != currentGeometry) {
- (*i)->setDirty(oldGeometryLocal);
- }
- (*i)->setDirty(dirtyRegion);
- ++i;
- }
-}
-
-void QFbWindowSurface::resize(const QSize &size)
-{
- // change the widget's QImage if this is a resize
- if (mImage.size() != size)
- mImage = QImage(size, mScreen->format());
- QWindowSurface::resize(size);
-}
-
-void QFbWindow::setGeometry(const QRect &rect)
-{
-// store previous geometry for screen update
- oldGeometry = geometry();
-
-
- QList<QFbScreen *>::const_iterator i = mScreens.constBegin();
- QList<QFbScreen *>::const_iterator end = mScreens.constEnd();
- while (i != end) {
- (*i)->invalidateRectCache();
- ++i;
- }
-//### QWindowSystemInterface::handleGeometryChange(window(), rect);
-
- QPlatformWindow::setGeometry(rect);
-}
-
-bool QFbWindowSurface::scroll(const QRegion &area, int dx, int dy)
-{
- return QWindowSurface::scroll(area, dx, dy);
-}
-
-void QFbWindowSurface::beginPaint(const QRegion &region)
-{
- Q_UNUSED(region);
-}
-
-void QFbWindowSurface::endPaint(const QRegion &region)
-{
- Q_UNUSED(region);
-}
-
-void QFbWindow::setVisible(bool visible)
-{
- visibleFlag = visible;
- QList<QFbScreen *>::const_iterator i = mScreens.constBegin();
- QList<QFbScreen *>::const_iterator end = mScreens.constEnd();
- while (i != end) {
- (*i)->invalidateRectCache();
- (*i)->setDirty(geometry());
- ++i;
- }
-}
-
-Qt::WindowFlags QFbWindow::setWindowFlags(Qt::WindowFlags type)
-{
- flags = type;
- QList<QFbScreen *>::const_iterator i = mScreens.constBegin();
- QList<QFbScreen *>::const_iterator end = mScreens.constEnd();
- while (i != end) {
- (*i)->invalidateRectCache();
- ++i;
- }
- return flags;
-}
-
-Qt::WindowFlags QFbWindow::windowFlags() const
-{
- return flags;
-}
diff --git a/src/plugins/platforms/fb_base/fb_base.pri b/src/plugins/platforms/fb_base/fb_base.pri
deleted file mode 100644
index 41bd87fbca..0000000000
--- a/src/plugins/platforms/fb_base/fb_base.pri
+++ /dev/null
@@ -1,2 +0,0 @@
-SOURCES += ../fb_base/fb_base.cpp
-HEADERS += ../fb_base/fb_base.h
diff --git a/src/plugins/platforms/fb_base/fb_base.pro b/src/plugins/platforms/fb_base/fb_base.pro
deleted file mode 100644
index 4ebd53b407..0000000000
--- a/src/plugins/platforms/fb_base/fb_base.pro
+++ /dev/null
@@ -1,23 +0,0 @@
-#-------------------------------------------------
-#
-# Project created by QtCreator 2009-11-05T13:22:31
-#
-#-------------------------------------------------
-
-#QT -= core gui
-TARGET = fb_base
-#load(qt_plugin)
-
-DESTDIR = $$QT.gui.plugins/graphicssystems
-
-TEMPLATE = lib
-
-#DEFINES += STATIC_LIBRARY
-CONFIG += staticlib
-
-SOURCES += fb_base.cpp
-
-HEADERS += fb_base.h
-
-target.path += $$[QT_INSTALL_PLUGINS]/graphicssystems
-INSTALLS += target
diff --git a/src/plugins/platforms/fontdatabases/basicunix/basicunix.pri b/src/plugins/platforms/fontdatabases/basicunix/basicunix.pri
deleted file mode 100644
index c1fbf3e411..0000000000
--- a/src/plugins/platforms/fontdatabases/basicunix/basicunix.pri
+++ /dev/null
@@ -1,88 +0,0 @@
-DEFINES += QT_NO_FONTCONFIG
-HEADERS += \
- $$QT_SOURCE_TREE/src/plugins/platforms/fontdatabases/basicunix/qbasicunixfontdatabase.h \
- $$QT_SOURCE_TREE/src/gui/text/qfontengine_ft_p.h
-
-SOURCES += \
- $$QT_SOURCE_TREE/src/plugins/platforms/fontdatabases/basicunix/qbasicunixfontdatabase.cpp \
- $$QT_SOURCE_TREE/src/gui/text/qfontengine_ft.cpp
-
-DEFINES += QT_COMPILES_IN_HARFBUZZ
-
-INCLUDEPATH += $$QT_SOURCE_TREE/src/3rdparty/harfbuzz/src
-
-INCLUDEPATH += $$QT_SOURCE_TREE/src/plugins/platforms/fontdatabases/basicunix
-
-CONFIG += opentype
-
-contains(QT_CONFIG, freetype) {
- SOURCES += \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/base/ftbase.c \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/base/ftbbox.c \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/base/ftdebug.c \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/base/ftglyph.c \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/base/ftinit.c \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/base/ftmm.c \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/base/fttype1.c \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/base/ftsynth.c \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/base/ftbitmap.c \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/bdf/bdf.c \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/cache/ftcache.c \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/cff/cff.c \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/cid/type1cid.c \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/gzip/ftgzip.c \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/pcf/pcf.c \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/pfr/pfr.c \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/psaux/psaux.c \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/pshinter/pshinter.c \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/psnames/psmodule.c \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/raster/raster.c \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/sfnt/sfnt.c \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/smooth/smooth.c \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/truetype/truetype.c \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/type1/type1.c \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/type42/type42.c \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/winfonts/winfnt.c \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/lzw/ftlzw.c\
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/otvalid/otvalid.c\
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/otvalid/otvbase.c\
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/otvalid/otvgdef.c\
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/otvalid/otvjstf.c\
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/otvalid/otvcommn.c\
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/otvalid/otvgpos.c\
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/otvalid/otvgsub.c\
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/otvalid/otvmod.c\
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/autofit/afangles.c\
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/autofit/afglobal.c\
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/autofit/aflatin.c\
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/autofit/afmodule.c\
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/autofit/afdummy.c\
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/autofit/afhints.c\
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/autofit/afloader.c\
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/autofit/autofit.c
-
- symbian {
- SOURCES += \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src/base/ftsystem.c
- } else {
- SOURCES += \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/builds/unix/ftsystem.c
- INCLUDEPATH += \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/builds/unix
- }
-
- INCLUDEPATH += \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/src \
- $$QT_SOURCE_TREE/src/3rdparty/freetype/include
-
- DEFINES += FT2_BUILD_LIBRARY
- contains(QT_CONFIG, system-zlib) {
- DEFINES += FT_CONFIG_OPTION_SYSTEM_ZLIB
- }
-
- } else:contains(QT_CONFIG, system-freetype) {
- # pull in the proper freetype2 include directory
- include($$QT_SOURCE_TREE/config.tests/unix/freetype/freetype.pri)
- LIBS_PRIVATE += -lfreetype
- }
-
diff --git a/src/plugins/platforms/fontdatabases/basicunix/qbasicunixfontdatabase.cpp b/src/plugins/platforms/fontdatabases/basicunix/qbasicunixfontdatabase.cpp
deleted file mode 100644
index d91cce59a9..0000000000
--- a/src/plugins/platforms/fontdatabases/basicunix/qbasicunixfontdatabase.cpp
+++ /dev/null
@@ -1,355 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qbasicunixfontdatabase.h"
-
-#include <QtGui/private/qapplication_p.h>
-#include <QtGui/QPlatformScreen>
-
-#include <QtCore/QFile>
-#include <QtCore/QLibraryInfo>
-#include <QtCore/QDir>
-
-#undef QT_NO_FREETYPE
-#include <QtGui/private/qfontengine_ft_p.h>
-#include <QtGui/private/qfontengine_p.h>
-
-#include <ft2build.h>
-#include FT_TRUETYPE_TABLES_H
-
-#define SimplifiedChineseCsbBit 18
-#define TraditionalChineseCsbBit 20
-#define JapaneseCsbBit 17
-#define KoreanCsbBit 21
-
-static int requiredUnicodeBits[QFontDatabase::WritingSystemsCount][2] = {
- // Any,
- { 127, 127 },
- // Latin,
- { 0, 127 },
- // Greek,
- { 7, 127 },
- // Cyrillic,
- { 9, 127 },
- // Armenian,
- { 10, 127 },
- // Hebrew,
- { 11, 127 },
- // Arabic,
- { 13, 127 },
- // Syriac,
- { 71, 127 },
- //Thaana,
- { 72, 127 },
- //Devanagari,
- { 15, 127 },
- //Bengali,
- { 16, 127 },
- //Gurmukhi,
- { 17, 127 },
- //Gujarati,
- { 18, 127 },
- //Oriya,
- { 19, 127 },
- //Tamil,
- { 20, 127 },
- //Telugu,
- { 21, 127 },
- //Kannada,
- { 22, 127 },
- //Malayalam,
- { 23, 127 },
- //Sinhala,
- { 73, 127 },
- //Thai,
- { 24, 127 },
- //Lao,
- { 25, 127 },
- //Tibetan,
- { 70, 127 },
- //Myanmar,
- { 74, 127 },
- // Georgian,
- { 26, 127 },
- // Khmer,
- { 80, 127 },
- // SimplifiedChinese,
- { 126, 127 },
- // TraditionalChinese,
- { 126, 127 },
- // Japanese,
- { 126, 127 },
- // Korean,
- { 56, 127 },
- // Vietnamese,
- { 0, 127 }, // same as latin1
- // Other,
- { 126, 127 },
- // Ogham,
- { 78, 127 },
- // Runic,
- { 79, 127 },
- // Nko,
- { 14, 127 },
-};
-
-static QSupportedWritingSystems determineWritingSystemsFromTrueTypeBits(quint32 unicodeRange[4], quint32 codePageRange[2])
-{
- QSupportedWritingSystems writingSystems;
- bool hasScript = false;
-
- int i;
- for(i = 0; i < QFontDatabase::WritingSystemsCount; i++) {
- int bit = requiredUnicodeBits[i][0];
- int index = bit/32;
- int flag = 1 << (bit&31);
- if (bit != 126 && unicodeRange[index] & flag) {
- bit = requiredUnicodeBits[i][1];
- index = bit/32;
-
- flag = 1 << (bit&31);
- if (bit == 127 || unicodeRange[index] & flag) {
- writingSystems.setSupported(QFontDatabase::WritingSystem(i));
- hasScript = true;
- // qDebug("font %s: index=%d, flag=%8x supports script %d", familyName.latin1(), index, flag, i);
- }
- }
- }
- if(codePageRange[0] & (1 << SimplifiedChineseCsbBit)) {
- writingSystems.setSupported(QFontDatabase::SimplifiedChinese);
- hasScript = true;
- //qDebug("font %s supports Simplified Chinese", familyName.latin1());
- }
- if(codePageRange[0] & (1 << TraditionalChineseCsbBit)) {
- writingSystems.setSupported(QFontDatabase::TraditionalChinese);
- hasScript = true;
- //qDebug("font %s supports Traditional Chinese", familyName.latin1());
- }
- if(codePageRange[0] & (1 << JapaneseCsbBit)) {
- writingSystems.setSupported(QFontDatabase::Japanese);
- hasScript = true;
- //qDebug("font %s supports Japanese", familyName.latin1());
- }
- if(codePageRange[0] & (1 << KoreanCsbBit)) {
- writingSystems.setSupported(QFontDatabase::Korean);
- hasScript = true;
- //qDebug("font %s supports Korean", familyName.latin1());
- }
- if (!hasScript)
- writingSystems.setSupported(QFontDatabase::Symbol);
-
- return writingSystems;
-}
-
-static inline bool scriptRequiresOpenType(int script)
-{
- return ((script >= QUnicodeTables::Syriac && script <= QUnicodeTables::Sinhala)
- || script == QUnicodeTables::Khmer || script == QUnicodeTables::Nko);
-}
-
-void QBasicUnixFontDatabase::populateFontDatabase()
-{
- QPlatformFontDatabase::populateFontDatabase();
- QString fontpath = fontDir();
-
- if(!QFile::exists(fontpath)) {
- qFatal("QFontDatabase: Cannot find font directory %s - is Qt installed correctly?",
- qPrintable(fontpath));
- }
-
- QDir dir(fontpath);
- dir.setNameFilters(QStringList() << QLatin1String("*.ttf")
- << QLatin1String("*.ttc") << QLatin1String("*.pfa")
- << QLatin1String("*.pfb"));
- dir.refresh();
- for (int i = 0; i < int(dir.count()); ++i) {
- const QByteArray file = QFile::encodeName(dir.absoluteFilePath(dir[i]));
-// qDebug() << "looking at" << file;
- addTTFile(QByteArray(), file);
- }
-}
-
-QFontEngine *QBasicUnixFontDatabase::fontEngine(const QFontDef &fontDef, QUnicodeTables::Script script, void *usrPtr)
-{
- QFontEngineFT *engine;
- FontFile *fontfile = static_cast<FontFile *> (usrPtr);
- QFontEngine::FaceId fid;
- fid.filename = fontfile->fileName.toLocal8Bit();
- fid.index = fontfile->indexValue;
- engine = new QFontEngineFT(fontDef);
-
- bool antialias = !(fontDef.styleStrategy & QFont::NoAntialias);
- QFontEngineFT::GlyphFormat format = antialias? QFontEngineFT::Format_A8 : QFontEngineFT::Format_Mono;
- if (!engine->init(fid,antialias,format)) {
- delete engine;
- engine = 0;
- return engine;
- }
- if (engine->invalid()) {
- delete engine;
- engine = 0;
- } else if (scriptRequiresOpenType(script)) {
- HB_Face hbFace = engine->harfbuzzFace();
- if (!hbFace || !hbFace->supported_scripts[script]) {
- delete engine;
- engine = 0;
- }
- }
-
- return engine;
-}
-
-QStringList QBasicUnixFontDatabase::fallbacksForFamily(const QString family, const QFont::Style &style, const QFont::StyleHint &styleHint, const QUnicodeTables::Script &script) const
-{
- Q_UNUSED(family);
- Q_UNUSED(style);
- Q_UNUSED(script);
- return QStringList();
-}
-
-QStringList QBasicUnixFontDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName)
-{
- return addTTFile(fontData,fileName.toLocal8Bit());
-}
-
-void QBasicUnixFontDatabase::releaseHandle(void *handle)
-{
- FontFile *file = static_cast<FontFile *>(handle);
- delete file;
-}
-
-QStringList QBasicUnixFontDatabase::addTTFile(const QByteArray &fontData, const QByteArray &file)
-{
- extern FT_Library qt_getFreetype();
- FT_Library library = qt_getFreetype();
-
- int index = 0;
- int numFaces = 0;
- QStringList families;
- do {
- FT_Face face;
- FT_Error error;
- if (!fontData.isEmpty()) {
- error = FT_New_Memory_Face(library, (const FT_Byte *)fontData.constData(), fontData.size(), index, &face);
- } else {
- error = FT_New_Face(library, file.constData(), index, &face);
- }
- if (error != FT_Err_Ok) {
- qDebug() << "FT_New_Face failed with index" << index << ":" << hex << error;
- break;
- }
- numFaces = face->num_faces;
-
- QFont::Weight weight = QFont::Normal;
-
- QFont::Style style = QFont::StyleNormal;
- if (face->style_flags & FT_STYLE_FLAG_ITALIC)
- style = QFont::StyleItalic;
-
- if (face->style_flags & FT_STYLE_FLAG_BOLD)
- weight = QFont::Bold;
-
- QSupportedWritingSystems writingSystems;
- // detect symbol fonts
- for (int i = 0; i < face->num_charmaps; ++i) {
- FT_CharMap cm = face->charmaps[i];
- if (cm->encoding == ft_encoding_adobe_custom
- || cm->encoding == ft_encoding_symbol) {
- writingSystems.setSupported(QFontDatabase::Symbol);
- break;
- }
- }
-
- TT_OS2 *os2 = (TT_OS2 *)FT_Get_Sfnt_Table(face, ft_sfnt_os2);
- if (os2) {
- quint32 unicodeRange[4] = {
- os2->ulUnicodeRange1, os2->ulUnicodeRange2, os2->ulUnicodeRange3, os2->ulUnicodeRange4
- };
- quint32 codePageRange[2] = {
- os2->ulCodePageRange1, os2->ulCodePageRange2
- };
-
- writingSystems = determineWritingSystemsFromTrueTypeBits(unicodeRange, codePageRange);
-
- if (os2->usWeightClass == 0)
- ;
- else if (os2->usWeightClass < 350)
- weight = QFont::Light;
- else if (os2->usWeightClass < 450)
- weight = QFont::Normal;
- else if (os2->usWeightClass < 650)
- weight = QFont::DemiBold;
- else if (os2->usWeightClass < 750)
- weight = QFont::Bold;
- else if (os2->usWeightClass < 1000)
- weight = QFont::Black;
-
- if (os2->panose[2] >= 2) {
- int w = os2->panose[2];
- if (w <= 3)
- weight = QFont::Light;
- else if (w <= 5)
- weight = QFont::Normal;
- else if (w <= 7)
- weight = QFont::DemiBold;
- else if (w <= 8)
- weight = QFont::Bold;
- else if (w <= 10)
- weight = QFont::Black;
- }
- }
-
- QString family = QString::fromAscii(face->family_name);
- FontFile *fontFile = new FontFile;
- fontFile->fileName = file;
- fontFile->indexValue = index;
-
- QFont::Stretch stretch = QFont::Unstretched;
-
- registerFont(family,"",weight,style,stretch,true,true,0,writingSystems,fontFile);
-
- families.append(family);
-
- FT_Done_Face(face);
- ++index;
- } while (index < numFaces);
- return families;
-}
diff --git a/src/plugins/platforms/fontdatabases/basicunix/qbasicunixfontdatabase.h b/src/plugins/platforms/fontdatabases/basicunix/qbasicunixfontdatabase.h
deleted file mode 100644
index 0e17ed55b6..0000000000
--- a/src/plugins/platforms/fontdatabases/basicunix/qbasicunixfontdatabase.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QBASICUNIXFONTDATABASE_H
-#define QBASICUNIXFONTDATABASE_H
-
-#include <QPlatformFontDatabase>
-#include <QtCore/QByteArray>
-#include <QtCore/QString>
-
-struct FontFile
-{
- QString fileName;
- int indexValue;
-};
-
-class QBasicUnixFontDatabase : public QPlatformFontDatabase
-{
-public:
- void populateFontDatabase();
- QFontEngine *fontEngine(const QFontDef &fontDef, QUnicodeTables::Script script, void *handle);
- QStringList fallbacksForFamily(const QString family, const QFont::Style &style, const QFont::StyleHint &styleHint, const QUnicodeTables::Script &script) const;
- QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName);
- void releaseHandle(void *handle);
-
- static QStringList addTTFile(const QByteArray &fontData, const QByteArray &file);
-};
-
-#endif // QBASICUNIXFONTDATABASE_H
diff --git a/src/plugins/platforms/fontdatabases/fontconfig/fontconfig.pri b/src/plugins/platforms/fontdatabases/fontconfig/fontconfig.pri
deleted file mode 100644
index 19c74ed089..0000000000
--- a/src/plugins/platforms/fontdatabases/fontconfig/fontconfig.pri
+++ /dev/null
@@ -1,12 +0,0 @@
-include(../basicunix/basicunix.pri)
-
-HEADERS += \
- $$QT_SOURCE_TREE/src/plugins/platforms/fontdatabases/fontconfig/qfontconfigdatabase.h
-
-SOURCES += \
- $$QT_SOURCE_TREE/src/plugins/platforms/fontdatabases/fontconfig/qfontconfigdatabase.cpp
-
-INCLUDEPATH += $$QT_SOURCE_TREE/src/plugins/platforms/fontdatabases/fontconfig
-LIBS_PRIVATE += -lfontconfig
-
-
diff --git a/src/plugins/platforms/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/src/plugins/platforms/fontdatabases/fontconfig/qfontconfigdatabase.cpp
deleted file mode 100644
index 50cf4ed75a..0000000000
--- a/src/plugins/platforms/fontdatabases/fontconfig/qfontconfigdatabase.cpp
+++ /dev/null
@@ -1,604 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qfontconfigdatabase.h"
-
-#include <QtCore/QList>
-#include <QtGui/private/qfont_p.h>
-
-#include <QtCore/QElapsedTimer>
-
-#include <QtGui/private/qapplication_p.h>
-#include <QtGui/QPlatformScreen>
-
-#include <QtGui/private/qfontengine_ft_p.h>
-#include <QtGui/private/qfontengine_p.h>
-
-
-
-#include <ft2build.h>
-#include FT_TRUETYPE_TABLES_H
-
-#include <fontconfig/fontconfig.h>
-
-#define SimplifiedChineseCsbBit 18
-#define TraditionalChineseCsbBit 20
-#define JapaneseCsbBit 17
-#define KoreanCsbBit 21
-
-static inline bool requiresOpenType(int writingSystem)
-{
- return ((writingSystem >= QFontDatabase::Syriac && writingSystem <= QFontDatabase::Sinhala)
- || writingSystem == QFontDatabase::Khmer || writingSystem == QFontDatabase::Nko);
-}
-static inline bool scriptRequiresOpenType(int script)
-{
- return ((script >= QUnicodeTables::Syriac && script <= QUnicodeTables::Sinhala)
- || script == QUnicodeTables::Khmer || script == QUnicodeTables::Nko);
-}
-
-static int getFCWeight(int fc_weight)
-{
- int qtweight = QFont::Black;
- if (fc_weight <= (FC_WEIGHT_LIGHT + FC_WEIGHT_MEDIUM) / 2)
- qtweight = QFont::Light;
- else if (fc_weight <= (FC_WEIGHT_MEDIUM + FC_WEIGHT_DEMIBOLD) / 2)
- qtweight = QFont::Normal;
- else if (fc_weight <= (FC_WEIGHT_DEMIBOLD + FC_WEIGHT_BOLD) / 2)
- qtweight = QFont::DemiBold;
- else if (fc_weight <= (FC_WEIGHT_BOLD + FC_WEIGHT_BLACK) / 2)
- qtweight = QFont::Bold;
-
- return qtweight;
-}
-
-static const char *specialLanguages[] = {
- "en", // Common
- "el", // Greek
- "ru", // Cyrillic
- "hy", // Armenian
- "he", // Hebrew
- "ar", // Arabic
- "syr", // Syriac
- "div", // Thaana
- "hi", // Devanagari
- "bn", // Bengali
- "pa", // Gurmukhi
- "gu", // Gujarati
- "or", // Oriya
- "ta", // Tamil
- "te", // Telugu
- "kn", // Kannada
- "ml", // Malayalam
- "si", // Sinhala
- "th", // Thai
- "lo", // Lao
- "bo", // Tibetan
- "my", // Myanmar
- "ka", // Georgian
- "ko", // Hangul
- "", // Ogham
- "", // Runic
- "km", // Khmer
- "" // N'Ko
-};
-enum { SpecialLanguageCount = sizeof(specialLanguages) / sizeof(const char *) };
-
-static const ushort specialChars[] = {
- 0, // English
- 0, // Greek
- 0, // Cyrillic
- 0, // Armenian
- 0, // Hebrew
- 0, // Arabic
- 0, // Syriac
- 0, // Thaana
- 0, // Devanagari
- 0, // Bengali
- 0, // Gurmukhi
- 0, // Gujarati
- 0, // Oriya
- 0, // Tamil
- 0xc15, // Telugu
- 0xc95, // Kannada
- 0xd15, // Malayalam
- 0xd9a, // Sinhala
- 0, // Thai
- 0, // Lao
- 0, // Tibetan
- 0x1000, // Myanmar
- 0, // Georgian
- 0, // Hangul
- 0x1681, // Ogham
- 0x16a0, // Runic
- 0, // Khmer
- 0x7ca // N'Ko
-};
-enum { SpecialCharCount = sizeof(specialChars) / sizeof(ushort) };
-
-// this could become a list of all languages used for each writing
-// system, instead of using the single most common language.
-static const char *languageForWritingSystem[] = {
- 0, // Any
- "en", // Latin
- "el", // Greek
- "ru", // Cyrillic
- "hy", // Armenian
- "he", // Hebrew
- "ar", // Arabic
- "syr", // Syriac
- "div", // Thaana
- "hi", // Devanagari
- "bn", // Bengali
- "pa", // Gurmukhi
- "gu", // Gujarati
- "or", // Oriya
- "ta", // Tamil
- "te", // Telugu
- "kn", // Kannada
- "ml", // Malayalam
- "si", // Sinhala
- "th", // Thai
- "lo", // Lao
- "bo", // Tibetan
- "my", // Myanmar
- "ka", // Georgian
- "km", // Khmer
- "zh-cn", // SimplifiedChinese
- "zh-tw", // TraditionalChinese
- "ja", // Japanese
- "ko", // Korean
- "vi", // Vietnamese
- 0, // Symbol
- 0, // Ogham
- 0, // Runic
- 0 // N'Ko
-};
-enum { LanguageCount = sizeof(languageForWritingSystem) / sizeof(const char *) };
-
-// Unfortunately FontConfig doesn't know about some languages. We have to test these through the
-// charset. The lists below contain the systems where we need to do this.
-static const ushort sampleCharForWritingSystem[] = {
- 0, // Any
- 0, // Latin
- 0, // Greek
- 0, // Cyrillic
- 0, // Armenian
- 0, // Hebrew
- 0, // Arabic
- 0, // Syriac
- 0, // Thaana
- 0, // Devanagari
- 0, // Bengali
- 0, // Gurmukhi
- 0, // Gujarati
- 0, // Oriya
- 0, // Tamil
- 0xc15, // Telugu
- 0xc95, // Kannada
- 0xd15, // Malayalam
- 0xd9a, // Sinhala
- 0, // Thai
- 0, // Lao
- 0, // Tibetan
- 0x1000, // Myanmar
- 0, // Georgian
- 0, // Khmer
- 0, // SimplifiedChinese
- 0, // TraditionalChinese
- 0, // Japanese
- 0, // Korean
- 0, // Vietnamese
- 0, // Symbol
- 0x1681, // Ogham
- 0x16a0, // Runic
- 0x7ca // N'Ko
-};
-enum { SampleCharCount = sizeof(sampleCharForWritingSystem) / sizeof(ushort) };
-
-// Newer FontConfig let's us sort out fonts that contain certain glyphs, but no
-// open type tables for is directly. Do this so we don't pick some strange
-// pseudo unicode font
-static const char *openType[] = {
- 0, // Any
- 0, // Latin
- 0, // Greek
- 0, // Cyrillic
- 0, // Armenian
- 0, // Hebrew
- 0, // Arabic
- "syrc", // Syriac
- "thaa", // Thaana
- "deva", // Devanagari
- "beng", // Bengali
- "guru", // Gurmukhi
- "gurj", // Gujarati
- "orya", // Oriya
- "taml", // Tamil
- "telu", // Telugu
- "knda", // Kannada
- "mlym", // Malayalam
- "sinh", // Sinhala
- 0, // Thai
- 0, // Lao
- "tibt", // Tibetan
- "mymr", // Myanmar
- 0, // Georgian
- "khmr", // Khmer
- 0, // SimplifiedChinese
- 0, // TraditionalChinese
- 0, // Japanese
- 0, // Korean
- 0, // Vietnamese
- 0, // Symbol
- 0, // Ogham
- 0, // Runic
- "nko " // N'Ko
-};
-
-static const char *getFcFamilyForStyleHint(const QFont::StyleHint style)
-{
- const char *stylehint = 0;
- switch (style) {
- case QFont::SansSerif:
- stylehint = "sans-serif";
- break;
- case QFont::Serif:
- stylehint = "serif";
- break;
- case QFont::TypeWriter:
- stylehint = "monospace";
- break;
- default:
- break;
- }
- return stylehint;
-}
-
-void QFontconfigDatabase::populateFontDatabase()
-{
- FcFontSet *fonts;
-
- QString familyName;
- FcChar8 *value = 0;
- int weight_value;
- int slant_value;
- int spacing_value;
- FcChar8 *file_value;
- int indexValue;
- FcChar8 *foundry_value;
- FcBool scalable;
- FcBool antialias;
-
- {
- FcObjectSet *os = FcObjectSetCreate();
- FcPattern *pattern = FcPatternCreate();
- const char *properties [] = {
- FC_FAMILY, FC_WEIGHT, FC_SLANT,
- FC_SPACING, FC_FILE, FC_INDEX,
- FC_LANG, FC_CHARSET, FC_FOUNDRY, FC_SCALABLE, FC_PIXEL_SIZE, FC_WEIGHT,
- FC_WIDTH,
-#if FC_VERSION >= 20297
- FC_CAPABILITY,
-#endif
- (const char *)0
- };
- const char **p = properties;
- while (*p) {
- FcObjectSetAdd(os, *p);
- ++p;
- }
- fonts = FcFontList(0, pattern, os);
- FcObjectSetDestroy(os);
- FcPatternDestroy(pattern);
- }
-
- for (int i = 0; i < fonts->nfont; i++) {
- if (FcPatternGetString(fonts->fonts[i], FC_FAMILY, 0, &value) != FcResultMatch)
- continue;
- // capitalize(value);
- familyName = QString::fromUtf8((const char *)value);
- slant_value = FC_SLANT_ROMAN;
- weight_value = FC_WEIGHT_MEDIUM;
- spacing_value = FC_PROPORTIONAL;
- file_value = 0;
- indexValue = 0;
- scalable = FcTrue;
-
-
- if (FcPatternGetInteger (fonts->fonts[i], FC_SLANT, 0, &slant_value) != FcResultMatch)
- slant_value = FC_SLANT_ROMAN;
- if (FcPatternGetInteger (fonts->fonts[i], FC_WEIGHT, 0, &weight_value) != FcResultMatch)
- weight_value = FC_WEIGHT_MEDIUM;
- if (FcPatternGetInteger (fonts->fonts[i], FC_SPACING, 0, &spacing_value) != FcResultMatch)
- spacing_value = FC_PROPORTIONAL;
- if (FcPatternGetString (fonts->fonts[i], FC_FILE, 0, &file_value) != FcResultMatch)
- file_value = 0;
- if (FcPatternGetInteger (fonts->fonts[i], FC_INDEX, 0, &indexValue) != FcResultMatch)
- indexValue = 0;
- if (FcPatternGetBool(fonts->fonts[i], FC_SCALABLE, 0, &scalable) != FcResultMatch)
- scalable = FcTrue;
- if (FcPatternGetString(fonts->fonts[i], FC_FOUNDRY, 0, &foundry_value) != FcResultMatch)
- foundry_value = 0;
- if(FcPatternGetBool(fonts->fonts[i],FC_ANTIALIAS,0,&antialias) != FcResultMatch)
- antialias = true;
-
- QSupportedWritingSystems writingSystems;
- FcLangSet *langset = 0;
- FcResult res = FcPatternGetLangSet(fonts->fonts[i], FC_LANG, 0, &langset);
- if (res == FcResultMatch) {
- for (int i = 1; i < LanguageCount; ++i) {
- const FcChar8 *lang = (const FcChar8*) languageForWritingSystem[i];
- if (lang) {
- FcLangResult langRes = FcLangSetHasLang(langset, lang);
- if (langRes != FcLangDifferentLang)
- writingSystems.setSupported(QFontDatabase::WritingSystem(i));
- }
- }
- } else {
- // we set Other to supported for symbol fonts. It makes no
- // sense to merge these with other ones, as they are
- // special in a way.
- writingSystems.setSupported(QFontDatabase::Other);
- }
-
- FcCharSet *cs = 0;
- res = FcPatternGetCharSet(fonts->fonts[i], FC_CHARSET, 0, &cs);
- if (res == FcResultMatch) {
- // some languages are not supported by FontConfig, we rather check the
- // charset to detect these
- for (int i = 1; i < SampleCharCount; ++i) {
- if (!sampleCharForWritingSystem[i])
- continue;
- if (FcCharSetHasChar(cs, sampleCharForWritingSystem[i]))
- writingSystems.setSupported(QFontDatabase::WritingSystem(i));
- }
- }
-
-#if FC_VERSION >= 20297
- for (int j = 1; j < LanguageCount; ++j) {
- if (writingSystems.supported(QFontDatabase::WritingSystem(j))
- && requiresOpenType(j) && openType[j]) {
- FcChar8 *cap;
- res = FcPatternGetString (fonts->fonts[i], FC_CAPABILITY, 0, &cap);
- if (res != FcResultMatch || !strstr((const char *)cap, openType[j]))
- writingSystems.setSupported(QFontDatabase::WritingSystem(j),false);
- }
- }
-#endif
-
- FontFile *fontFile = new FontFile;
- fontFile->fileName = QLatin1String((const char *)file_value);
- fontFile->indexValue = indexValue;
-
- QFont::Style style = (slant_value == FC_SLANT_ITALIC)
- ? QFont::StyleItalic
- : ((slant_value == FC_SLANT_OBLIQUE)
- ? QFont::StyleOblique
- : QFont::StyleNormal);
- QFont::Weight weight = QFont::Weight(getFCWeight(weight_value));
-
- double pixel_size = 0;
- if (!scalable) {
- int width = 100;
- FcPatternGetInteger (fonts->fonts[i], FC_WIDTH, 0, &width);
- FcPatternGetDouble (fonts->fonts[i], FC_PIXEL_SIZE, 0, &pixel_size);
- }
-
- QFont::Stretch stretch = QFont::Unstretched;
- QPlatformFontDatabase::registerFont(familyName,QLatin1String((const char *)foundry_value),weight,style,stretch,antialias,scalable,pixel_size,writingSystems,fontFile);
-// qDebug() << familyName << (const char *)foundry_value << weight << style << &writingSystems << scalable << true << pixel_size;
- }
-
- FcFontSetDestroy (fonts);
-
- struct FcDefaultFont {
- const char *qtname;
- const char *rawname;
- bool fixed;
- };
- const FcDefaultFont defaults[] = {
- { "Serif", "serif", false },
- { "Sans Serif", "sans-serif", false },
- { "Monospace", "monospace", true },
- { 0, 0, false }
- };
- const FcDefaultFont *f = defaults;
- // aliases only make sense for 'common', not for any of the specials
- QSupportedWritingSystems ws;
- ws.setSupported(QFontDatabase::Latin);
-
-
- while (f->qtname) {
- registerFont(f->qtname,QLatin1String(""),QFont::Normal,QFont::StyleNormal,QFont::Unstretched,true,true,0,ws,0);
- registerFont(f->qtname,QLatin1String(""),QFont::Normal,QFont::StyleItalic,QFont::Unstretched,true,true,0,ws,0);
- registerFont(f->qtname,QLatin1String(""),QFont::Normal,QFont::StyleOblique,QFont::Unstretched,true,true,0,ws,0);
- ++f;
- }
-
- //Lighthouse has very lazy population of the font db. We want it to be initialized when
- //QApplication is constructed, so that the population procedure can do something like this to
- //set the default font
-// const FcDefaultFont *s = defaults;
-// QFont font("Sans Serif");
-// font.setPointSize(9);
-// QApplication::setFont(font);
-}
-
-QFontEngine *QFontconfigDatabase::fontEngine(const QFontDef &f, QUnicodeTables::Script script, void *usrPtr)
-{
- if (!usrPtr)
- return 0;
- QFontDef fontDef = f;
-
- QFontEngineFT *engine;
- FontFile *fontfile = static_cast<FontFile *> (usrPtr);
- QFontEngine::FaceId fid;
- fid.filename = fontfile->fileName.toLocal8Bit();
- fid.index = fontfile->indexValue;
-
- bool antialias = !(fontDef.styleStrategy & QFont::NoAntialias);
- QFontEngineFT::GlyphFormat format = antialias? QFontEngineFT::Format_A8 : QFontEngineFT::Format_Mono;
-
- engine = new QFontEngineFT(fontDef);
-
- // try and get the pattern
- FcPattern *pattern = FcPatternCreate();
-
- FcValue value;
- value.type = FcTypeString;
- QByteArray cs = fontDef.family.toUtf8();
- value.u.s = (const FcChar8 *)cs.data();
- FcPatternAdd(pattern,FC_FAMILY,value,true);
-
-
- value.u.s = (const FcChar8 *)fid.filename.data();
- FcPatternAdd(pattern,FC_FILE,value,true);
-
- value.type = FcTypeInteger;
- value.u.i = fid.index;
- FcPatternAdd(pattern,FC_INDEX,value,true);
-
- if (FcConfigSubstitute(0,pattern,FcMatchPattern)) {
- QFontEngineFT::HintStyle default_hint_style;
-
- //hinting
- int hint_style = 0;
- if (FcPatternGetInteger (pattern, FC_HINT_STYLE, 0, &hint_style) == FcResultNoMatch)
- hint_style = QFontEngineFT::HintFull;
- switch (hint_style) {
- case FC_HINT_NONE:
- default_hint_style = QFontEngineFT::HintNone;
- break;
- case FC_HINT_SLIGHT:
- default_hint_style = QFontEngineFT::HintLight;
- break;
- case FC_HINT_MEDIUM:
- default_hint_style = QFontEngineFT::HintMedium;
- break;
- default:
- default_hint_style = QFontEngineFT::HintFull;
- break;
- }
- engine->setDefaultHintStyle(default_hint_style);
- }
- FcPatternDestroy(pattern);
-
- if (!engine->init(fid,antialias,format)) {
- delete engine;
- engine = 0;
- return engine;
- }
- if (engine->invalid()) {
- delete engine;
- engine = 0;
- } else if (scriptRequiresOpenType(script)) {
- HB_Face hbFace = engine->harfbuzzFace();
- if (!hbFace || !hbFace->supported_scripts[script]) {
- delete engine;
- engine = 0;
- }
- }
-
- return engine;
-}
-
-QStringList QFontconfigDatabase::fallbacksForFamily(const QString family, const QFont::Style &style, const QFont::StyleHint &styleHint, const QUnicodeTables::Script &script) const
-{
- QStringList fallbackFamilies;
- FcPattern *pattern = FcPatternCreate();
- if (!pattern)
- return fallbackFamilies;
-
- FcValue value;
- value.type = FcTypeString;
- QByteArray cs = family.toUtf8();
- value.u.s = (const FcChar8 *)cs.data();
- FcPatternAdd(pattern,FC_FAMILY,value,true);
-
- int slant_value = FC_SLANT_ROMAN;
- if (style == QFont::StyleItalic)
- slant_value = FC_SLANT_ITALIC;
- else if (style == QFont::StyleOblique)
- slant_value = FC_SLANT_OBLIQUE;
- FcPatternAddInteger(pattern, FC_SLANT, slant_value);
-
- if (script != QUnicodeTables::Common && *specialLanguages[script] != '\0') {
- Q_ASSERT(script < QUnicodeTables::ScriptCount);
- FcLangSet *ls = FcLangSetCreate();
- FcLangSetAdd(ls, (const FcChar8*)specialLanguages[script]);
- FcPatternAddLangSet(pattern, FC_LANG, ls);
- FcLangSetDestroy(ls);
- }
-
- const char *stylehint = getFcFamilyForStyleHint(styleHint);
- if (stylehint) {
- value.u.s = (const FcChar8 *)stylehint;
- FcPatternAddWeak(pattern, FC_FAMILY, value, FcTrue);
- }
-
- FcConfigSubstitute(0, pattern, FcMatchPattern);
- FcDefaultSubstitute(pattern);
-
- FcResult result = FcResultMatch;
- FcFontSet *fontSet = FcFontSort(0,pattern,FcFalse,0,&result);
- FcPatternDestroy(pattern);
-
- if (fontSet) {
- if (result == FcResultMatch) {
- for (int i = 0; i < fontSet->nfont; i++) {
- FcChar8 *value = 0;
- if (FcPatternGetString(fontSet->fonts[i], FC_FAMILY, 0, &value) != FcResultMatch)
- continue;
- // capitalize(value);
- QString familyName = QString::fromUtf8((const char *)value);
- if (!fallbackFamilies.contains(familyName,Qt::CaseInsensitive) &&
- familyName.compare(family, Qt::CaseInsensitive)) {
- fallbackFamilies << familyName;
- }
- }
- }
- FcFontSetDestroy(fontSet);
- }
-// qDebug() << "fallbackFamilies for:" << family << style << styleHint << script << fallbackFamilies;
-
- return fallbackFamilies;
-}
diff --git a/src/plugins/platforms/fontdatabases/fontconfig/qfontconfigdatabase.h b/src/plugins/platforms/fontdatabases/fontconfig/qfontconfigdatabase.h
deleted file mode 100644
index 61700e391a..0000000000
--- a/src/plugins/platforms/fontdatabases/fontconfig/qfontconfigdatabase.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QFONTCONFIGDATABASE_H
-#define QFONTCONFIGDATABASE_H
-
-#include <QPlatformFontDatabase>
-#include "qbasicunixfontdatabase.h"
-
-class QFontconfigDatabase : public QBasicUnixFontDatabase
-{
-public:
- void populateFontDatabase();
- QFontEngine *fontEngine(const QFontDef &fontDef, QUnicodeTables::Script script, void *handle);
- QStringList fallbacksForFamily(const QString family, const QFont::Style &style, const QFont::StyleHint &styleHint, const QUnicodeTables::Script &script) const;
-};
-
-#endif // QFONTCONFIGDATABASE_H
diff --git a/src/plugins/platforms/fontdatabases/genericunix/genericunix.pri b/src/plugins/platforms/fontdatabases/genericunix/genericunix.pri
deleted file mode 100644
index 1153ab36b7..0000000000
--- a/src/plugins/platforms/fontdatabases/genericunix/genericunix.pri
+++ /dev/null
@@ -1,10 +0,0 @@
-contains(QT_CONFIG, fontconfig) {
- include(../fontconfig/fontconfig.pri)
- DEFINES += Q_FONTCONFIGDATABASE
-} else {
- include(../basicunix/basicunix.pri)
-}
-
-INCLUDEPATH += $$PWD
-HEADERS += \
- $$PWD/qgenericunixfontdatabase.h
diff --git a/src/plugins/platforms/fontdatabases/genericunix/qgenericunixfontdatabase.h b/src/plugins/platforms/fontdatabases/genericunix/qgenericunixfontdatabase.h
deleted file mode 100644
index 8bf542a215..0000000000
--- a/src/plugins/platforms/fontdatabases/genericunix/qgenericunixfontdatabase.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGENERICUNIXFONTDATABASE_H
-#define QGENERICUNIXFONTDATABASE_H
-
-#ifdef Q_FONTCONFIGDATABASE
-#include "qfontconfigdatabase.h"
-typedef QFontconfigDatabase QGenericUnixFontDatabase;
-#else
-#include "qbasicunixfontdatabase.h"
-typedef QBasicUnixFontDatabase QGenericUnixFontDatabase;
-#endif //Q_FONTCONFIGDATABASE
-
-#endif // QGENERICUNIXFONTDATABASE_H
diff --git a/src/plugins/platforms/glxconvenience/glxconvenience.pri b/src/plugins/platforms/glxconvenience/glxconvenience.pri
deleted file mode 100644
index b4d43a30b5..0000000000
--- a/src/plugins/platforms/glxconvenience/glxconvenience.pri
+++ /dev/null
@@ -1,15 +0,0 @@
-INCLUDEPATH += $$PWD
-
-HEADERS += \
- $$PWD/qglxconvenience.h
-
-SOURCES += \
- $$PWD/qglxconvenience.cpp
-
-CONFIG += xrender
-
-xrender {
- LIBS += -lXrender
-} else {
- DEFINES += QT_NO_XRENDER
-}
diff --git a/src/plugins/platforms/glxconvenience/qglxconvenience.cpp b/src/plugins/platforms/glxconvenience/qglxconvenience.cpp
deleted file mode 100644
index 34633d9692..0000000000
--- a/src/plugins/platforms/glxconvenience/qglxconvenience.cpp
+++ /dev/null
@@ -1,257 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qglxconvenience.h"
-
-#include <QtCore/QVector>
-
-#ifndef QT_NO_XRENDER
-#include <X11/extensions/Xrender.h>
-#endif
-
-enum {
- XFocusOut = FocusOut,
- XFocusIn = FocusIn,
- XKeyPress = KeyPress,
- XKeyRelease = KeyRelease,
- XNone = None,
- XRevertToParent = RevertToParent,
- XGrayScale = GrayScale,
- XCursorShape = CursorShape
-};
-#undef FocusOut
-#undef FocusIn
-#undef KeyPress
-#undef KeyRelease
-#undef None
-#undef RevertToParent
-#undef GrayScale
-#undef CursorShape
-
-#ifdef FontChange
-#undef FontChange
-#endif
-
-QVector<int> qglx_buildSpec(const QPlatformWindowFormat &format, int drawableBit)
-{
- QVector<int> spec(48);
- int i = 0;
-
- spec[i++] = GLX_LEVEL;
- spec[i++] = 0;
- spec[i++] = GLX_DRAWABLE_TYPE; spec[i++] = drawableBit;
-
- if (format.rgba()) {
- spec[i++] = GLX_RENDER_TYPE; spec[i++] = GLX_RGBA_BIT;
- spec[i++] = GLX_RED_SIZE; spec[i++] = (format.redBufferSize() == -1) ? 1 : format.redBufferSize();
- spec[i++] = GLX_GREEN_SIZE; spec[i++] = (format.greenBufferSize() == -1) ? 1 : format.greenBufferSize();
- spec[i++] = GLX_BLUE_SIZE; spec[i++] = (format.blueBufferSize() == -1) ? 1 : format.blueBufferSize();
- if (format.alpha()) {
- spec[i++] = GLX_ALPHA_SIZE; spec[i++] = (format.alphaBufferSize() == -1) ? 1 : format.alphaBufferSize();
- }
-
- if (format.accum()) {
- spec[i++] = GLX_ACCUM_RED_SIZE; spec[i++] = (format.accumBufferSize() == -1) ? 1 : format.accumBufferSize();
- spec[i++] = GLX_ACCUM_GREEN_SIZE; spec[i++] = (format.accumBufferSize() == -1) ? 1 : format.accumBufferSize();
- spec[i++] = GLX_ACCUM_BLUE_SIZE; spec[i++] = (format.accumBufferSize() == -1) ? 1 : format.accumBufferSize();
-
- if (format.alpha()) {
- spec[i++] = GLX_ACCUM_ALPHA_SIZE; spec[i++] = (format.accumBufferSize() == -1) ? 1 : format.accumBufferSize();
- }
- }
- } else {
- spec[i++] = GLX_RENDER_TYPE; spec[i++] = GLX_COLOR_INDEX_BIT; //I'm really not sure if this works....
- spec[i++] = GLX_BUFFER_SIZE; spec[i++] = 8;
- }
-
- spec[i++] = GLX_DOUBLEBUFFER; spec[i++] = format.doubleBuffer() ? True : False;
- spec[i++] = GLX_STEREO; spec[i++] = format.stereo() ? True : False;
-
- if (format.depth()) {
- spec[i++] = GLX_DEPTH_SIZE; spec[i++] = (format.depthBufferSize() == -1) ? 1 : format.depthBufferSize();
- }
-
- if (format.stencil()) {
- spec[i++] = GLX_STENCIL_SIZE; spec[i++] = (format.stencilBufferSize() == -1) ? 1 : format.stencilBufferSize();
- }
- if (format.sampleBuffers()) {
- spec[i++] = GLX_SAMPLE_BUFFERS_ARB;
- spec[i++] = 1;
- spec[i++] = GLX_SAMPLES_ARB;
- spec[i++] = format.samples() == -1 ? 4 : format.samples();
- }
-
- spec[i++] = XNone;
- return spec;
-}
-
-GLXFBConfig qglx_findConfig(Display *display, int screen , const QPlatformWindowFormat &format, int drawableBit)
-{
- bool reduced = true;
- GLXFBConfig chosenConfig = 0;
- QPlatformWindowFormat reducedFormat = format;
- while (!chosenConfig && reduced) {
- QVector<int> spec = qglx_buildSpec(reducedFormat, drawableBit);
- int confcount = 0;
- GLXFBConfig *configs;
- configs = glXChooseFBConfig(display, screen,spec.constData(),&confcount);
- if (confcount)
- {
- for (int i = 0; i < confcount; i++) {
- chosenConfig = configs[i];
- // Make sure we try to get an ARGB visual if the format asked for an alpha:
- if (reducedFormat.alpha()) {
- int alphaSize;
- glXGetFBConfigAttrib(display,configs[i],GLX_ALPHA_SIZE,&alphaSize);
- if (alphaSize > 0) {
- XVisualInfo *visual = glXGetVisualFromFBConfig(display, chosenConfig);
-#if !defined(QT_NO_XRENDER)
- XRenderPictFormat *pictFormat = XRenderFindVisualFormat(display, visual->visual);
- if (pictFormat->direct.alphaMask > 0)
- break;
-#else
- if (visual->depth == 32)
- break;
-#endif
- }
- } else {
- break; // Just choose the first in the list if there's no alpha requested
- }
- }
-
- XFree(configs);
- }
- reducedFormat = qglx_reducePlatformWindowFormat(reducedFormat,&reduced);
- }
-
- if (!chosenConfig)
- qWarning("Warning: no suitable glx confiuration found");
-
- return chosenConfig;
-}
-
-XVisualInfo *qglx_findVisualInfo(Display *display, int screen, const QPlatformWindowFormat &format)
-{
- GLXFBConfig config = qglx_findConfig(display,screen,format);
- XVisualInfo *visualInfo = glXGetVisualFromFBConfig(display,config);
- return visualInfo;
-}
-
-QPlatformWindowFormat qglx_platformWindowFromGLXFBConfig(Display *display, GLXFBConfig config, GLXContext ctx)
-{
- QPlatformWindowFormat format;
- int redSize = 0;
- int greenSize = 0;
- int blueSize = 0;
- int alphaSize = 0;
- int depthSize = 0;
- int stencilSize = 0;
- int sampleBuffers = 0;
- int sampleCount = 0;
- int level = 0;
- int rgba = 0;
- int stereo = 0;
- int accumSizeA = 0;
- int accumSizeR = 0;
- int accumSizeG = 0;
- int accumSizeB = 0;
-
- XVisualInfo *vi = glXGetVisualFromFBConfig(display,config);
- glXGetConfig(display,vi,GLX_RGBA,&rgba);
- XFree(vi);
- glXGetFBConfigAttrib(display, config, GLX_RED_SIZE, &redSize);
- glXGetFBConfigAttrib(display, config, GLX_GREEN_SIZE, &greenSize);
- glXGetFBConfigAttrib(display, config, GLX_BLUE_SIZE, &blueSize);
- glXGetFBConfigAttrib(display, config, GLX_ALPHA_SIZE, &alphaSize);
- glXGetFBConfigAttrib(display, config, GLX_DEPTH_SIZE, &depthSize);
- glXGetFBConfigAttrib(display, config, GLX_STENCIL_SIZE, &stencilSize);
- glXGetFBConfigAttrib(display, config, GLX_SAMPLES, &sampleBuffers);
- glXGetFBConfigAttrib(display, config, GLX_LEVEL, &level);
- glXGetFBConfigAttrib(display, config, GLX_STEREO, &stereo);
- glXGetFBConfigAttrib(display, config, GLX_ACCUM_ALPHA_SIZE, &accumSizeA);
- glXGetFBConfigAttrib(display, config, GLX_ACCUM_RED_SIZE, &accumSizeR);
- glXGetFBConfigAttrib(display, config, GLX_ACCUM_GREEN_SIZE, &accumSizeG);
- glXGetFBConfigAttrib(display, config, GLX_ACCUM_BLUE_SIZE, &accumSizeB);
-
- format.setRedBufferSize(redSize);
- format.setGreenBufferSize(greenSize);
- format.setBlueBufferSize(blueSize);
- format.setAlphaBufferSize(alphaSize);
- format.setDepthBufferSize(depthSize);
- format.setStencilBufferSize(stencilSize);
- format.setSampleBuffers(sampleBuffers);
- if (format.sampleBuffers()) {
- glXGetFBConfigAttrib(display, config, GLX_SAMPLES_ARB, &sampleCount);
- format.setSamples(sampleCount);
- }
-
- format.setDirectRendering(glXIsDirect(display, ctx));
- format.setRgba(rgba);
- format.setStereo(stereo);
- format.setAccumBufferSize(accumSizeB);
-
- return format;
-}
-
-QPlatformWindowFormat qglx_reducePlatformWindowFormat(const QPlatformWindowFormat &format, bool *reduced)
-{
- QPlatformWindowFormat retFormat = format;
- *reduced = true;
-
- if (retFormat.sampleBuffers()) {
- retFormat.setSampleBuffers(false);
- } else if (retFormat.stereo()) {
- retFormat.setStereo(false);
- } else if (retFormat.accum()) {
- retFormat.setAccum(false);
- }else if (retFormat.stencil()) {
- retFormat.setStencil(false);
- }else if (retFormat.alpha()) {
- retFormat.setAlpha(false);
- }else if (retFormat.depth()) {
- retFormat.setDepth(false);
- }else if (retFormat.doubleBuffer()) {
- retFormat.setDoubleBuffer(false);
- }else{
- *reduced = false;
- }
- return retFormat;
-}
diff --git a/src/plugins/platforms/glxconvenience/qglxconvenience.h b/src/plugins/platforms/glxconvenience/qglxconvenience.h
deleted file mode 100644
index 7478abfeba..0000000000
--- a/src/plugins/platforms/glxconvenience/qglxconvenience.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGLXCONVENIENCE_H
-#define QGLXCONVENIENCE_H
-
-#include <QPlatformWindowFormat>
-
-#include <X11/Xlib.h>
-#include <GL/glx.h>
-
-XVisualInfo *qglx_findVisualInfo(Display *display, int screen, const QPlatformWindowFormat &format);
-GLXFBConfig qglx_findConfig(Display *display, int screen, const QPlatformWindowFormat &format, int drawableBit = GLX_WINDOW_BIT);
-QPlatformWindowFormat qglx_platformWindowFromGLXFBConfig(Display *display, GLXFBConfig config, GLXContext context);
-QVector<int> qglx_buildSpec(const QPlatformWindowFormat &format, int drawableBit = GLX_WINDOW_BIT);
-QPlatformWindowFormat qglx_reducePlatformWindowFormat(const QPlatformWindowFormat &format, bool *reduced);
-
-#endif // QGLXCONVENIENCE_H
diff --git a/src/plugins/platforms/kms/kms.pro b/src/plugins/platforms/kms/kms.pro
new file mode 100644
index 0000000000..73a3fa0418
--- /dev/null
+++ b/src/plugins/platforms/kms/kms.pro
@@ -0,0 +1,42 @@
+TARGET = qkms
+
+load(qt_plugin)
+QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/platforms
+
+QT = core-private gui-private platformsupport-private opengl-private
+
+CONFIG += link_pkgconfig qpa/genericunixfontdatabase
+
+PKGCONFIG += libdrm egl gbm glesv2
+
+SOURCES = main.cpp \
+ qkmsintegration.cpp \
+ qkmsscreen.cpp \
+ qkmscontext.cpp \
+ qkmswindow.cpp \
+ qkmscursor.cpp \
+ qkmsdevice.cpp \
+ qkmsbuffermanager.cpp \
+ qkmsbackingstore.cpp
+HEADERS = qkmsintegration.h \
+ qkmsscreen.h \
+ qkmscontext.h \
+ qkmswindow.h \
+ qkmscursor.h \
+ qkmsdevice.h \
+ qkmsbuffermanager.h \
+ qkmsbackingstore.h
+
+target.path += $$[QT_INSTALL_PLUGINS]/platforms
+INSTALLS += target
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/plugins/platforms/kms/main.cpp b/src/plugins/platforms/kms/main.cpp
new file mode 100644
index 0000000000..a07f1645dc
--- /dev/null
+++ b/src/plugins/platforms/kms/main.cpp
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/QPlatformIntegrationPlugin>
+#include "qkmsintegration.h"
+
+QT_BEGIN_NAMESPACE
+
+class QKmsIntegrationPlugin : public QPlatformIntegrationPlugin
+{
+public:
+ QStringList keys() const;
+ QPlatformIntegration *create(const QString&, const QStringList&);
+};
+
+QStringList QKmsIntegrationPlugin::keys() const
+{
+ QStringList list;
+ list << "kms";
+ return list;
+}
+
+QPlatformIntegration *QKmsIntegrationPlugin::create(const QString& system, const QStringList& paramList)
+{
+ Q_UNUSED(paramList);
+ if (system.toLower() == "kms")
+ return new QKmsIntegration;
+
+ return 0;
+}
+
+Q_EXPORT_PLUGIN2(kms, QKmsIntegrationPlugin)
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/kms/qkmsbackingstore.cpp b/src/plugins/platforms/kms/qkmsbackingstore.cpp
new file mode 100644
index 0000000000..eb682e8ab3
--- /dev/null
+++ b/src/plugins/platforms/kms/qkmsbackingstore.cpp
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qkmsbackingstore.h"
+
+QT_BEGIN_NAMESPACE
+
+QKmsBackingStore::QKmsBackingStore(QWindow *window)
+ : QPlatformBackingStore(window)
+{
+}
+
+QPaintDevice *QKmsBackingStore::paintDevice()
+{
+ return &m_image;
+}
+
+void QKmsBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
+{
+ //'window' can be a child window, in which case 'region' is in child window coordinates and
+ // offset is the (child) window's offset in relation to the window surface.
+
+ Q_UNUSED(region)
+ Q_UNUSED(offset)
+ Q_UNUSED(window)
+}
+
+void QKmsBackingStore::resize(const QSize &size, const QRegion &staticContents)
+{
+ Q_UNUSED(staticContents)
+ m_image = QImage(size, QImage::Format_RGB32);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/kms/qkmsbackingstore.h b/src/plugins/platforms/kms/qkmsbackingstore.h
new file mode 100644
index 0000000000..e270d04db0
--- /dev/null
+++ b/src/plugins/platforms/kms/qkmsbackingstore.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QBACKINGSTORE_KMS_H
+#define QBACKINGSTORE_KMS_H
+
+#include <QtGui/QPlatformBackingStore>
+#include <QImage>
+
+QT_BEGIN_NAMESPACE
+
+class QKmsBackingStore : public QPlatformBackingStore
+{
+public:
+ QKmsBackingStore(QWindow *window);
+
+ QPaintDevice *paintDevice();
+ void flush(QWindow *window, const QRegion &region, const QPoint &offset);
+ void resize(const QSize &size, const QRegion &staticContents);
+
+private:
+ QImage m_image;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/platforms/kms/qkmsbuffermanager.cpp b/src/plugins/platforms/kms/qkmsbuffermanager.cpp
new file mode 100644
index 0000000000..0c2eec0f3b
--- /dev/null
+++ b/src/plugins/platforms/kms/qkmsbuffermanager.cpp
@@ -0,0 +1,198 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qkmsbuffermanager.h"
+#include "qkmsscreen.h"
+#include "qkmscontext.h"
+#include "qkmsdevice.h"
+
+QT_BEGIN_NAMESPACE
+
+QKmsBufferManager::QKmsBufferManager(QKmsScreen *screen) :
+ m_screen(screen),
+ m_frameBufferObject(0),
+ m_renderTarget(0),
+ m_displayCanidate(0),
+ m_currentDisplay(0)
+{
+}
+
+QKmsBufferManager::~QKmsBufferManager()
+{
+ clearBuffers();
+ glDeleteFramebuffers(1, &m_frameBufferObject);
+}
+
+void QKmsBufferManager::setupBuffersForMode(const drmModeModeInfo &mode, int numBuffers)
+{
+ eglMakeCurrent(m_screen->device()->eglDisplay(), EGL_NO_SURFACE, EGL_NO_SURFACE, m_screen->device()->eglContext());
+ m_screen->bindFramebuffer();
+
+
+ if (m_frameBufferObject) {
+ clearBuffers();
+ } else {
+ //Setup Framebuffer Object
+ glGenFramebuffers(1, &m_frameBufferObject);
+ glBindFramebuffer(GL_FRAMEBUFFER, m_frameBufferObject);
+ }
+
+ //Setup shared Depth/Stencil buffer
+ glGenRenderbuffers(1, &m_depthAndStencilBufferObject);
+ glBindRenderbuffer(GL_RENDERBUFFER, m_depthAndStencilBufferObject);
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES,
+ mode.hdisplay, mode.vdisplay);
+
+ //Setup "numBuffer" many rendering targets
+ for (int i = 0; i < numBuffers; i++) {
+ QKmsFramebuffer *buffer = new QKmsFramebuffer();
+
+ glGenRenderbuffers(1, &buffer->renderBuffer);
+ glBindRenderbuffer(GL_RENDERBUFFER, buffer->renderBuffer);
+
+ buffer->graphicsBufferObject = gbm_bo_create(m_screen->device()->gbmDevice(),
+ mode.hdisplay, mode.vdisplay,
+ GBM_BO_FORMAT_XRGB8888,
+ GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
+ buffer->eglImage = eglCreateImageKHR(m_screen->device()->eglDisplay(), 0, EGL_NATIVE_PIXMAP_KHR,
+ buffer->graphicsBufferObject, 0);
+ glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, buffer->eglImage);
+
+ quint32 stride = gbm_bo_get_pitch(buffer->graphicsBufferObject);
+ quint32 handle = gbm_bo_get_handle(buffer->graphicsBufferObject).u32;
+
+ int status = drmModeAddFB(m_screen->device()->fd(), mode.hdisplay, mode.vdisplay,
+ 32, 32, stride, handle, &buffer->framebufferId);
+ //Todo: IF this returns true, then this is one less buffer that we use
+ //Not so fatal, but not handled at the moment.
+ if (status)
+ qFatal("failed to add framebuffer");
+ m_framebuffers.append(buffer);
+ }
+ //Attach the Depth and Stencil buffer
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER,
+ GL_DEPTH_ATTACHMENT,
+ GL_RENDERBUFFER,
+ m_depthAndStencilBufferObject);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER,
+ GL_STENCIL_ATTACHMENT,
+ GL_RENDERBUFFER,
+ m_depthAndStencilBufferObject);
+ //Attach renderbuffer as Color Attachment.
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER,
+ GL_COLOR_ATTACHMENT0,
+ GL_RENDERBUFFER,
+ this->renderTargetBuffer());
+}
+
+void QKmsBufferManager::clearBuffers()
+{
+ //Make sure that the FBO is binded
+ glBindFramebuffer(GL_FRAMEBUFFER, m_frameBufferObject);
+ //Detach the Color/Depth/Stencil Attachments.
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER,
+ GL_COLOR_ATTACHMENT0,
+ GL_RENDERBUFFER,
+ 0);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER,
+ GL_DEPTH_ATTACHMENT,
+ GL_RENDERBUFFER,
+ 0);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER,
+ GL_STENCIL_ATTACHMENT,
+ GL_RENDERBUFFER,
+ 0);
+ glBindRenderbuffer(GL_RENDERBUFFER, 0);
+ //Delete the shared Depth/Stencil buffer
+ glDeleteRenderbuffers(1, &m_depthAndStencilBufferObject);
+
+ //Delete each renderbuffer object
+ //Delete each EGLImage
+ //Remove each drm Framebuffer
+ foreach (QKmsFramebuffer *buffer, m_framebuffers) {
+ glDeleteRenderbuffers(1, &buffer->renderBuffer);
+ eglDestroyImageKHR(m_screen->device()->eglDisplay(), buffer->eglImage);
+ drmModeRmFB(m_screen->device()->fd(), buffer->framebufferId);
+ delete buffer;
+ }
+ m_framebuffers.clear();
+}
+
+GLuint QKmsBufferManager::renderTargetBuffer()
+{
+ //TODO: Handle more senarios than assuming at least 2 buffers
+ if (!m_renderTarget) {
+ m_renderTarget = m_framebuffers.at(1);
+ }
+ return m_renderTarget->renderBuffer;
+}
+
+quint32 QKmsBufferManager::displayFramebufferId()
+{
+ if (!m_currentDisplay) {
+ m_currentDisplay = m_framebuffers.at(0);
+ m_currentDisplay->available = false;
+ return m_currentDisplay->framebufferId;
+ }
+
+ if (!m_displayCanidate)
+ return m_currentDisplay->framebufferId;
+
+ m_currentDisplay->available = true;
+ m_displayCanidate->available = false;
+ m_currentDisplay = m_displayCanidate;
+ return m_currentDisplay->framebufferId;
+
+}
+
+bool QKmsBufferManager::nextBuffer()
+{
+ m_displayCanidate = m_renderTarget;
+ foreach (QKmsFramebuffer *buffer, m_framebuffers) {
+ if (buffer->available && buffer != m_displayCanidate) {
+ m_renderTarget = buffer;
+ return true;
+ }
+ }
+ return false;
+}
+
+QT_BEGIN_NAMESPACE
diff --git a/src/plugins/platforms/kms/qkmsbuffermanager.h b/src/plugins/platforms/kms/qkmsbuffermanager.h
new file mode 100644
index 0000000000..59db7ebeb1
--- /dev/null
+++ b/src/plugins/platforms/kms/qkmsbuffermanager.h
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QKMSBUFFERMANAGER_H
+#define QKMSBUFFERMANAGER_H
+
+#include <QObject>
+#include <QList>
+
+#define EGL_EGLEXT_PROTOTYPES 1
+#define GL_GLEXT_PROTOTYPES 1
+
+extern "C" {
+#include <gbm.h>
+#include <xf86drmMode.h>
+#include <xf86drm.h>
+}
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+QT_BEGIN_NAMESPACE
+
+class QKmsScreen;
+
+class QKmsFramebuffer
+{
+public:
+ QKmsFramebuffer() : available(true) {}
+ gbm_bo *graphicsBufferObject;
+ GLuint renderBuffer;
+ EGLImageKHR eglImage;
+ quint32 framebufferId;
+ bool available;
+};
+
+
+class QKmsBufferManager
+{
+public:
+ explicit QKmsBufferManager(QKmsScreen *screen);
+ ~QKmsBufferManager();
+ void setupBuffersForMode(const drmModeModeInfo &mode, int numBuffers = 3);
+ GLuint framebufferObject() const { return m_frameBufferObject; }
+ quint32 displayFramebufferId();
+ GLuint renderTargetBuffer();
+ bool nextBuffer();
+
+private:
+ void clearBuffers();
+
+ QKmsScreen *m_screen;
+ QList<QKmsFramebuffer*> m_framebuffers;
+ GLuint m_frameBufferObject;
+ GLuint m_depthAndStencilBufferObject;
+
+ QKmsFramebuffer *m_renderTarget;
+ QKmsFramebuffer *m_displayCanidate;
+ QKmsFramebuffer *m_currentDisplay;
+
+};
+
+QT_END_NAMESPACE
+
+#endif // QKMSBUFFERMANAGER_H
diff --git a/src/plugins/platforms/kms/qkmscontext.cpp b/src/plugins/platforms/kms/qkmscontext.cpp
new file mode 100644
index 0000000000..f27673a24d
--- /dev/null
+++ b/src/plugins/platforms/kms/qkmscontext.cpp
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qkmsscreen.h"
+#include "qkmsdevice.h"
+#include "qkmscontext.h"
+#include "qkmswindow.h"
+
+
+QT_BEGIN_NAMESPACE
+
+QKmsContext::QKmsContext(QKmsDevice *device)
+ : QPlatformOpenGLContext(),
+ m_device(device)
+{
+}
+
+bool QKmsContext::makeCurrent(QPlatformSurface *surface)
+{
+ EGLDisplay display = m_device->eglDisplay();
+ EGLContext context = m_device->eglContext();
+
+ bool ok = eglMakeCurrent(display, EGL_NO_SURFACE,
+ EGL_NO_SURFACE, context);
+ if (!ok)
+ qWarning("QKmsContext::makeCurrent(): eglError: %d, this: %p",
+ eglGetError(), this);
+
+ QPlatformWindow *window = static_cast<QPlatformWindow *>(surface);
+ QKmsScreen *screen = static_cast<QKmsScreen *> (QPlatformScreen::platformScreenForWindow(window->window()));
+ screen->bindFramebuffer();
+ return true;
+}
+
+void QKmsContext::doneCurrent()
+{
+ QPlatformOpenGLContext::doneCurrent();
+ bool ok = eglMakeCurrent(m_device->eglDisplay(), EGL_NO_SURFACE, EGL_NO_SURFACE,
+ EGL_NO_CONTEXT);
+ if (!ok)
+ qWarning("QKmsContext::doneCurrent(): eglError: %d, this: %p",
+ eglGetError(), this);
+
+}
+
+void QKmsContext::swapBuffers(QPlatformSurface *surface)
+{
+ //After flush, the current render target should be moved to
+ //latest complete
+ glFlush();
+
+ //Cast context to a window surface and get the screen the context
+ //is on and call swapBuffers on that screen.
+ QPlatformWindow *window = static_cast<QPlatformWindow *>(surface);
+ QKmsScreen *screen = static_cast<QKmsScreen *> (QPlatformScreen::platformScreenForWindow(window->window()));
+ screen->swapBuffers();
+}
+
+void (*QKmsContext::getProcAddress(const QByteArray &procName)) ()
+{
+ return eglGetProcAddress(procName.data());
+}
+
+
+EGLContext QKmsContext::eglContext() const
+{
+ return m_device->eglContext();
+}
+
+QSurfaceFormat QKmsContext::format() const
+{
+ return QSurfaceFormat();
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/kms/qkmscontext.h b/src/plugins/platforms/kms/qkmscontext.h
new file mode 100644
index 0000000000..2f4f44c3d0
--- /dev/null
+++ b/src/plugins/platforms/kms/qkmscontext.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QKMSCONTEXT_H
+#define QKMSCONTEXT_H
+
+#include <QtGui/QPlatformOpenGLContext>
+
+#define EGL_EGLEXT_PROTOTYPES 1
+#include <EGL/egl.h>
+
+QT_BEGIN_NAMESPACE
+
+class QKmsDevice;
+
+class QKmsContext : public QPlatformOpenGLContext
+{
+public:
+ QKmsContext(QKmsDevice *device);
+
+ bool makeCurrent(QPlatformSurface *surface);
+ void doneCurrent();
+ void swapBuffers(QPlatformSurface *surface);
+ void (*getProcAddress(const QByteArray &procName)) ();
+
+ QSurfaceFormat format() const;
+
+ EGLContext eglContext() const;
+
+private:
+
+ QKmsDevice *m_device;
+};
+
+QT_END_NAMESPACE
+
+#endif // QKMSCONTEXT_H
diff --git a/src/plugins/platforms/kms/qkmscursor.cpp b/src/plugins/platforms/kms/qkmscursor.cpp
new file mode 100644
index 0000000000..91c23b0f1c
--- /dev/null
+++ b/src/plugins/platforms/kms/qkmscursor.cpp
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+//#include <QDebug>
+#include "qkmscursor.h"
+#include "qkmsscreen.h"
+#include "qkmsdevice.h"
+
+QT_BEGIN_NAMESPACE
+
+QKmsCursor::QKmsCursor(QKmsScreen *screen)
+ : QPlatformCursor(screen), m_screen(screen),
+ m_graphicsBufferManager(screen->device()->gbmDevice())
+{
+ gbm_bo *bo = gbm_bo_create(m_graphicsBufferManager, 64, 64,
+ GBM_BO_FORMAT_ARGB8888,
+ GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_RENDERING);
+
+ m_eglImage = eglCreateImageKHR(m_screen->device()->eglDisplay(), 0, EGL_NATIVE_PIXMAP_KHR,
+ bo, 0);
+ gbm_bo_destroy(bo);
+ m_cursorImage = new QPlatformCursorImage(0, 0, 0, 0, 0, 0);
+}
+
+void QKmsCursor::pointerEvent(const QMouseEvent &event)
+{
+ int status = drmModeMoveCursor(m_screen->device()->fd(),
+ m_screen->crtcId(),
+ event.globalX(),
+ event.globalY());
+ if (status) {
+ qWarning("failed to move cursor: %d", status);
+ }
+}
+
+void QKmsCursor::changeCursor(QCursor *widgetCursor, QWindow *window)
+{
+ Q_UNUSED(window)
+
+ if (widgetCursor->shape() != Qt::BitmapCursor) {
+ m_cursorImage->set(widgetCursor->shape());
+ } else {
+ m_cursorImage->set(widgetCursor->pixmap().toImage(),
+ widgetCursor->hotSpot().x(),
+ widgetCursor->hotSpot().y());
+ }
+
+ if ((m_cursorImage->image()->width() > 64) || (m_cursorImage->image()->width() > 64)) {
+ qWarning("failed to set hardware cursor: larger than 64x64.");
+ return;
+ }
+
+ QImage cursorImage = m_cursorImage->image()->convertToFormat(QImage::Format_RGB32);
+
+ //Load cursor image into EGLImage
+ GLuint cursorTexture;
+ glGenTextures(1, &cursorTexture);
+ glBindTexture(GL_TEXTURE_2D, cursorTexture);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+
+ //TODO: Format may be wrong here, need a color icon to test.
+ if (m_eglImage != EGL_NO_IMAGE_KHR) {
+ glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, m_eglImage);
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, cursorImage.width(),
+ cursorImage.height(), GL_RGBA,
+ GL_UNSIGNED_BYTE, cursorImage.constBits());
+ } else {
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, cursorImage.width(),
+ cursorImage.height(), 0, GL_RGBA,
+ GL_UNSIGNED_BYTE, cursorImage.constBits());
+ }
+
+ //EGLImage needs to contain sprite before calling this:
+ gbm_bo *bufferObject = gbm_bo_create_from_egl_image(m_graphicsBufferManager,
+ m_screen->device()->eglDisplay(),
+ m_eglImage, 64, 64,
+ GBM_BO_USE_CURSOR_64X64);
+ quint32 handle = gbm_bo_get_handle(bufferObject).u32;
+
+ gbm_bo_destroy(bufferObject);
+
+ int status = drmModeSetCursor(m_screen->device()->fd(),
+ m_screen->crtcId(), handle, 64, 64);
+
+ if (status) {
+ qWarning("failed to set cursor: %d", status);
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/kms/qkmscursor.h b/src/plugins/platforms/kms/qkmscursor.h
new file mode 100644
index 0000000000..96be88e991
--- /dev/null
+++ b/src/plugins/platforms/kms/qkmscursor.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QKMSCURSOR_H
+#define QKMSCURSOR_H
+
+#include <QtGui/QPlatformCursor>
+
+#define EGL_EGLEXT_PROTOTYPES 1
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+QT_BEGIN_NAMESPACE
+
+class QKmsScreen;
+class gbm_device;
+
+class QKmsCursor : public QPlatformCursor
+{
+public:
+ QKmsCursor(QKmsScreen *screen);
+
+ void pointerEvent(const QMouseEvent &event);
+ void changeCursor(QCursor *widgetCursor, QWindow *window);
+
+private:
+ QKmsScreen *m_screen;
+ gbm_device *m_graphicsBufferManager;
+ EGLImageKHR m_eglImage;
+ QPlatformCursorImage *m_cursorImage;
+};
+
+QT_END_NAMESPACE
+
+#endif // QKMSCURSOR_H
diff --git a/src/plugins/platforms/kms/qkmsdevice.cpp b/src/plugins/platforms/kms/qkmsdevice.cpp
new file mode 100644
index 0000000000..e0fac5611d
--- /dev/null
+++ b/src/plugins/platforms/kms/qkmsdevice.cpp
@@ -0,0 +1,163 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+//#include <QDebug>
+#include "qkmsscreen.h"
+#include "qkmsdevice.h"
+
+#include "qkmsintegration.h"
+
+#include <QtCore/QSocketNotifier>
+#include <QtCore/private/qcore_unix_p.h>
+
+QT_BEGIN_NAMESPACE
+
+QKmsDevice::QKmsDevice(const QString &path, QKmsIntegration *parent) :
+ QObject(0), m_integration(parent)
+{
+ m_fd = QT_OPEN(path.toAscii().constData(), O_RDWR);
+ if (m_fd < 0) {
+ qWarning("Could not open %s.", path.toAscii().constData());
+ qFatal("No DRM display device");
+ }
+
+ m_graphicsBufferManager = gbm_create_device(m_fd);
+ m_eglDisplay = eglGetDisplay(m_graphicsBufferManager);
+
+ if (m_eglDisplay == EGL_NO_DISPLAY) {
+ qWarning("Could not open EGL display");
+ qFatal("EGL error");
+ }
+
+ EGLint major;
+ EGLint minor;
+ if (!eglInitialize(m_eglDisplay, &major, &minor)) {
+ qWarning("Could not initialize EGL display");
+ qFatal("EGL error");
+ }
+
+ QString extensions = eglQueryString(m_eglDisplay, EGL_EXTENSIONS);
+ if (!extensions.contains(QString::fromLatin1("EGL_KHR_surfaceless_opengl"))) {
+ qFatal("EGL_KHR_surfaceless_opengl extension not available");
+ }
+
+ //Initialize EGLContext
+ static EGLint contextAttribs[] = {
+ EGL_CONTEXT_CLIENT_VERSION, 2,
+ EGL_NONE
+ };
+
+ eglBindAPI(EGL_OPENGL_ES_API);
+ m_eglContext = eglCreateContext(m_eglDisplay, 0, 0, contextAttribs);
+ if (m_eglContext == EGL_NO_CONTEXT) {
+ qWarning("Could not create the EGL context.");
+ eglTerminate(m_eglDisplay);
+ qFatal("EGL error");
+ }
+
+ createScreens();
+
+ QSocketNotifier *notifier = new QSocketNotifier(m_fd, QSocketNotifier::Read, this);
+ connect(notifier, SIGNAL(activated(int)), this, SLOT(handlePageFlipCompleted()));
+}
+
+QKmsDevice::~QKmsDevice()
+{
+ if (m_eglContext != EGL_NO_CONTEXT) {
+ eglDestroyContext(m_eglDisplay, m_eglContext);
+ m_eglContext = EGL_NO_CONTEXT;
+ }
+}
+
+void QKmsDevice::createScreens()
+{
+ drmModeRes *resources = 0;
+ resources = drmModeGetResources(m_fd);
+ if (!resources)
+ qFatal("drmModeGetResources failed");
+
+ //Iterate connectors and create screens on each one active
+ for (int i = 0; i < resources->count_connectors; i++) {
+ drmModeConnector *connector = 0;
+ connector = drmModeGetConnector(m_fd, resources->connectors[i]);
+ if (connector && connector->connection == DRM_MODE_CONNECTED) {
+ m_integration->addScreen(new QKmsScreen(this, connector->connector_id));
+ }
+ drmModeFreeConnector(connector);
+ }
+ drmModeFreeResources(resources);
+}
+
+void QKmsDevice::handlePageFlipCompleted()
+{
+ //qDebug() << "Display signal recieved";
+ drmEventContext eventContext;
+
+ memset(&eventContext, 0, sizeof eventContext);
+ eventContext.version = DRM_EVENT_CONTEXT_VERSION;
+ eventContext.page_flip_handler = QKmsDevice::pageFlipHandler;
+ drmHandleEvent(m_fd, &eventContext);
+
+}
+
+void QKmsDevice::pageFlipHandler(int fd, unsigned int frame, unsigned int sec, unsigned int usec, void *data)
+{
+ Q_UNUSED(fd)
+ Q_UNUSED(frame)
+ Q_UNUSED(sec)
+ Q_UNUSED(usec)
+ static unsigned int previousTime = 0;
+
+ unsigned int currentTime = sec * 1000000 + usec;
+ unsigned int refreshTime = 0;
+// qDebug() << "fd: " << fd << " frame: " << frame << " sec: "
+// << sec << " usec: " << usec << " data: " << data
+// << "msecs" << sec * 1000 + usec / 1000;
+ QKmsScreen *screen = static_cast<QKmsScreen *>(data);
+
+ if (previousTime == 0)
+ refreshTime = 16000;
+ else
+ refreshTime = currentTime - previousTime;
+
+ screen->setFlipReady(refreshTime);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/kms/qkmsdevice.h b/src/plugins/platforms/kms/qkmsdevice.h
new file mode 100644
index 0000000000..4868a72ede
--- /dev/null
+++ b/src/plugins/platforms/kms/qkmsdevice.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QKMSDEVICE_H
+#define QKMSDEVICE_H
+
+extern "C" {
+#include <gbm.h>
+}
+#include <EGL/egl.h>
+
+#include <QObject>
+
+QT_BEGIN_NAMESPACE
+
+class gbm_device;
+class QKmsIntegration;
+
+class QKmsDevice : public QObject
+{
+ Q_OBJECT
+public:
+ explicit QKmsDevice(const QString &path, QKmsIntegration *parent);
+ ~QKmsDevice();
+
+ EGLDisplay eglDisplay() { return m_eglDisplay; }
+ gbm_device *gbmDevice() { return m_graphicsBufferManager; }
+ EGLContext eglContext() { return m_eglContext; }
+ int fd() const { return m_fd; }
+
+ static void pageFlipHandler(int fd, unsigned int frame, unsigned int sec,
+ unsigned int usec, void *data);
+
+public slots:
+ void handlePageFlipCompleted();
+private:
+ void createScreens();
+
+ QKmsIntegration *m_integration;
+
+ EGLDisplay m_eglDisplay;
+ EGLContext m_eglContext;
+ gbm_device *m_graphicsBufferManager;
+ int m_fd;
+};
+
+QT_END_NAMESPACE
+
+#endif // QKMSDEVICE_H
diff --git a/src/plugins/platforms/kms/qkmsintegration.cpp b/src/plugins/platforms/kms/qkmsintegration.cpp
new file mode 100644
index 0000000000..d8e4876eee
--- /dev/null
+++ b/src/plugins/platforms/kms/qkmsintegration.cpp
@@ -0,0 +1,139 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qkmsintegration.h"
+#include "qkmsdevice.h"
+#include "qkmsscreen.h"
+#include "qkmswindow.h"
+#include "qkmsbackingstore.h"
+#include "qkmscontext.h"
+
+#include <QtPlatformSupport/private/qgenericunixprintersupport_p.h>
+#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
+#include <QtPlatformSupport/private/qgenericunixfontdatabase_p.h>
+#include <QtGui/private/qguiapplication_p.h>
+#include <QtGui/QOpenGLContext>
+#include <QtGui/QScreen>
+
+QT_BEGIN_NAMESPACE
+
+QKmsIntegration::QKmsIntegration()
+ : QPlatformIntegration(),
+ m_fontDatabase(new QGenericUnixFontDatabase()),
+ m_printerSupport(new QGenericUnixPrinterSupport()),
+ m_eventDispatcher(createUnixEventDispatcher())
+{
+ QGuiApplicationPrivate::instance()->setEventDispatcher(m_eventDispatcher);
+ setenv("EGL_PLATFORM", "drm",1);
+ QStringList drmDevices = findDrmDevices();
+ foreach (QString path, drmDevices) {
+ m_devices.append(new QKmsDevice(path, this));
+ }
+}
+
+QKmsIntegration::~QKmsIntegration()
+{
+ foreach (QKmsDevice *device, m_devices) {
+ delete device;
+ }
+ foreach (QPlatformScreen *screen, m_screens) {
+ delete screen;
+ }
+ delete m_printerSupport;
+ delete m_fontDatabase;
+}
+
+bool QKmsIntegration::hasCapability(QPlatformIntegration::Capability cap) const
+{
+ switch (cap) {
+ case ThreadedPixmaps: return true;
+ case OpenGL: return true;
+ case ThreadedOpenGL: return true;
+ default: return QPlatformIntegration::hasCapability(cap);
+ }
+}
+
+QPlatformOpenGLContext *QKmsIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
+{
+ QKmsScreen *screen = static_cast<QKmsScreen *>(context->screen()->handle());
+ return new QKmsContext(screen->device());
+}
+
+QPlatformWindow *QKmsIntegration::createPlatformWindow(QWindow *window) const
+{
+ return new QKmsWindow(window);
+}
+
+QPlatformBackingStore *QKmsIntegration::createPlatformBackingStore(QWindow *window) const
+{
+ return new QKmsBackingStore(window);
+}
+
+QPlatformFontDatabase *QKmsIntegration::fontDatabase() const
+{
+ return m_fontDatabase;
+}
+
+QStringList QKmsIntegration::findDrmDevices()
+{
+ //Return a list addresses of DRM supported devices
+ //Hardcoded now, but could use udev to return a list
+ //of multiple devices.
+ return QStringList(QString::fromLatin1("/dev/dri/card0"));
+}
+
+void QKmsIntegration::addScreen(QKmsScreen *screen)
+{
+ m_screens.append(screen);
+ screenAdded(screen);
+}
+
+QAbstractEventDispatcher *QKmsIntegration::guiThreadEventDispatcher() const
+{
+ return m_eventDispatcher;
+}
+
+QPlatformPrinterSupport *QKmsIntegration::printerSupport() const
+{
+ return m_printerSupport;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/kms/qkmsintegration.h b/src/plugins/platforms/kms/qkmsintegration.h
new file mode 100644
index 0000000000..a1f3623280
--- /dev/null
+++ b/src/plugins/platforms/kms/qkmsintegration.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPLATFORMINTEGRATION_KMS_H
+#define QPLATFORMINTEGRATION_KMS_H
+
+#include <QtGui/QPlatformIntegration>
+
+QT_BEGIN_NAMESPACE
+
+class QKmsScreen;
+class QKmsDevice;
+
+class QKmsIntegration : public QPlatformIntegration
+{
+public:
+ QKmsIntegration();
+ ~QKmsIntegration();
+
+ bool hasCapability(QPlatformIntegration::Capability cap) const;
+
+ QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const;
+ QPlatformWindow *createPlatformWindow(QWindow *window) const;
+ QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const;
+
+ QPlatformFontDatabase *fontDatabase() const;
+ QPlatformPrinterSupport *printerSupport() const;
+ QAbstractEventDispatcher *guiThreadEventDispatcher() const;
+
+ void addScreen(QKmsScreen *screen);
+
+private:
+ QStringList findDrmDevices();
+
+ QList<QPlatformScreen *> m_screens;
+ QList<QKmsDevice *> m_devices;
+ QPlatformFontDatabase *m_fontDatabase;
+ QPlatformPrinterSupport *m_printerSupport;
+ QAbstractEventDispatcher *m_eventDispatcher;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/platforms/kms/qkmsscreen.cpp b/src/plugins/platforms/kms/qkmsscreen.cpp
new file mode 100644
index 0000000000..0cd1530930
--- /dev/null
+++ b/src/plugins/platforms/kms/qkmsscreen.cpp
@@ -0,0 +1,224 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+//#include <QDebug>
+#include "qkmscursor.h"
+#include "qkmsscreen.h"
+#include "qkmsdevice.h"
+#include "qkmscontext.h"
+#include "qkmsbuffermanager.h"
+
+QT_BEGIN_NAMESPACE
+
+//Fallback mode (taken from Wayland DRM demo compositor)
+static drmModeModeInfo builtin_1024x768 = {
+ 63500, //clock
+ 1024, 1072, 1176, 1328, 0,
+ 768, 771, 775, 798, 0,
+ 59920,
+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC,
+ 0,
+ "1024x768"
+};
+
+QKmsScreen::QKmsScreen(QKmsDevice *device, int connectorId)
+ : m_device(device),
+ m_flipReady(true),
+ m_connectorId(connectorId),
+ m_depth(32),
+ m_format(QImage::Format_Invalid),
+ m_bufferManager(this),
+ m_refreshTime(16000)
+{
+ m_cursor = new QKmsCursor(this);
+ initializeScreenMode();
+}
+
+QKmsScreen::~QKmsScreen()
+{
+ delete m_cursor;
+}
+
+QRect QKmsScreen::geometry() const
+{
+ return m_geometry;
+}
+
+int QKmsScreen::depth() const
+{
+ return m_depth;
+}
+
+QImage::Format QKmsScreen::format() const
+{
+ return m_format;
+}
+
+QSize QKmsScreen::physicalSize() const
+{
+ return m_physicalSize;
+}
+
+GLuint QKmsScreen::framebufferObject() const
+{
+ return m_bufferManager.framebufferObject();
+}
+
+void QKmsScreen::initializeScreenMode()
+{
+ //Determine optimal mode for screen
+ drmModeRes *resources = drmModeGetResources(m_device->fd());
+ if (!resources)
+ qFatal("drmModeGetResources failed");
+
+ drmModeConnector *connector = drmModeGetConnector(m_device->fd(), m_connectorId);
+ drmModeModeInfo *mode = 0;
+ if (connector->count_modes > 0)
+ mode = &connector->modes[0];
+ else
+ mode = &builtin_1024x768;
+
+ drmModeEncoder *encoder = drmModeGetEncoder(m_device->fd(), connector->encoders[0]);
+ if (encoder == 0)
+ qFatal("No encoder for connector.");
+
+ int i;
+ for (i = 0; i < resources->count_crtcs; i++) {
+ if (encoder->possible_crtcs & (1 << i))
+ break;
+ }
+ if (i == resources->count_crtcs)
+ qFatal("No usable crtc for encoder.");
+
+ m_crtcId = resources->crtcs[i];
+ m_mode = *mode;
+ m_geometry = QRect(0, 0, m_mode.hdisplay, m_mode.vdisplay);
+ m_depth = 32;
+ m_format = QImage::Format_RGB32;
+ m_physicalSize = QSize(connector->mmWidth, connector->mmHeight);
+
+ //Setup three buffers for current mode
+ m_bufferManager.setupBuffersForMode(m_mode, 3);
+
+ //Set the Mode of the screen.
+ int ret = drmModeSetCrtc(m_device->fd(), m_crtcId, m_bufferManager.displayFramebufferId(),
+ 0, 0, &m_connectorId, 1, &m_mode);
+ if (ret)
+ qFatal("failed to set mode");
+
+ //Cleanup
+ drmModeFreeEncoder(encoder);
+ drmModeFreeConnector(connector);
+ drmModeFreeResources(resources);
+}
+
+void QKmsScreen::bindFramebuffer()
+{
+ if (m_bufferManager.framebufferObject()) {
+ glBindFramebuffer(GL_FRAMEBUFFER, m_bufferManager.framebufferObject());
+
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER,
+ GL_COLOR_ATTACHMENT0,
+ GL_RENDERBUFFER,
+ m_bufferManager.renderTargetBuffer());
+ }
+}
+
+void QKmsScreen::swapBuffers()
+{
+ waitForPageFlipComplete();
+
+ if ( m_flipReady )
+ performPageFlip();
+ //TODO: Do something with return value here
+ m_bufferManager.nextBuffer();
+ //qDebug() << "swapBuffers now rendering to " << m_bufferManager.renderTargetBuffer();
+ bindFramebuffer();
+}
+
+void QKmsScreen::performPageFlip()
+{
+ quint32 displayFramebufferId = m_bufferManager.displayFramebufferId();
+ //qDebug() << "Flipping to framebuffer: " << displayFramebufferId;
+
+ int pageFlipStatus = drmModePageFlip(m_device->fd(), m_crtcId,
+ displayFramebufferId,
+ DRM_MODE_PAGE_FLIP_EVENT, this);
+ if (pageFlipStatus)
+ qWarning("Pageflip status: %d", pageFlipStatus);
+
+ m_flipReady = false;
+}
+
+void QKmsScreen::setFlipReady(unsigned int time)
+{
+ m_flipReady = true;
+ m_refreshTime = time;
+ performPageFlip();
+}
+
+QKmsDevice * QKmsScreen::device() const
+{
+ return m_device;
+}
+
+void QKmsScreen::waitForPageFlipComplete()
+{
+ //Check manually if there is something to be read on the device
+ //as there are senarios where the signal is not received (starvation)
+ fd_set fdSet;
+ timeval timeValue;
+ int returnValue;
+
+ FD_ZERO(&fdSet);
+ FD_SET(m_device->fd(), &fdSet);
+ timeValue.tv_sec = 0;
+ timeValue.tv_usec = m_refreshTime;
+
+ returnValue = select(1, &fdSet, 0, 0, &timeValue);
+
+ if (returnValue) {
+ m_device->handlePageFlipCompleted();
+ }
+
+}
+
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/kms/qkmsscreen.h b/src/plugins/platforms/kms/qkmsscreen.h
new file mode 100644
index 0000000000..5c8b5ca4f5
--- /dev/null
+++ b/src/plugins/platforms/kms/qkmsscreen.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QKMSSCREEN_H
+#define QKMSSCREEN_H
+
+#include <QtGui/QPlatformScreen>
+#include "qkmsbuffermanager.h"
+
+QT_BEGIN_NAMESPACE
+
+class QKmsCursor;
+class QKmsDevice;
+class QKmsContext;
+
+class QKmsScreen : public QPlatformScreen
+{
+public:
+ QKmsScreen(QKmsDevice *device, int connectorId);
+ ~QKmsScreen();
+
+ QRect geometry() const;
+ int depth() const;
+ QImage::Format format() const;
+ QSize physicalSize() const;
+
+ GLuint framebufferObject() const;
+ quint32 crtcId() const { return m_crtcId; }
+ QKmsDevice *device() const;
+
+ //Called by context for each screen
+ void bindFramebuffer();
+ void swapBuffers();
+ void setFlipReady(unsigned int time);
+
+private:
+ void performPageFlip();
+ void initializeScreenMode();
+ void waitForPageFlipComplete();
+
+ QKmsDevice *m_device;
+ bool m_flipReady;
+ quint32 m_connectorId;
+
+ quint32 m_crtcId;
+ drmModeModeInfo m_mode;
+ QRect m_geometry;
+ QSize m_physicalSize;
+ int m_depth;
+ QImage::Format m_format;
+
+ QKmsCursor *m_cursor;
+ QKmsBufferManager m_bufferManager;
+ unsigned int m_refreshTime;
+};
+
+QT_END_NAMESPACE
+
+#endif // QKMSSCREEN_H
diff --git a/src/plugins/platforms/kms/qkmswindow.cpp b/src/plugins/platforms/kms/qkmswindow.cpp
new file mode 100644
index 0000000000..63271c4ef5
--- /dev/null
+++ b/src/plugins/platforms/kms/qkmswindow.cpp
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qkmswindow.h"
+#include "qkmsscreen.h"
+
+#include <QtGui/QWindowSystemInterface>
+QT_BEGIN_NAMESPACE
+
+QKmsWindow::QKmsWindow(QWindow *window)
+ : QPlatformWindow(window)
+{
+ m_screen = QPlatformScreen::platformScreenForWindow(window);
+}
+
+void QKmsWindow::setGeometry(const QRect &rect)
+{
+ Q_UNUSED(rect)
+ //All Windows must be fullscreen
+ QRect fullscreenRect = m_screen->availableGeometry();
+ QWindowSystemInterface::handleGeometryChange(window(), fullscreenRect);
+
+ QPlatformWindow::setGeometry(fullscreenRect);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/kms/qkmswindow.h b/src/plugins/platforms/kms/qkmswindow.h
new file mode 100644
index 0000000000..789d42e6f8
--- /dev/null
+++ b/src/plugins/platforms/kms/qkmswindow.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QKMSWINDOW_H
+#define QKMSWINDOW_H
+
+#include <QtGui/QPlatformWindow>
+
+QT_BEGIN_NAMESPACE
+
+class QKmsWindow : public QPlatformWindow
+{
+public:
+ QKmsWindow(QWindow *window);
+
+ void setGeometry(const QRect &rect);
+
+private:
+ QPlatformScreen *m_screen;
+};
+
+QT_END_NAMESPACE
+
+#endif // QKMSWINDOW_H
diff --git a/src/plugins/platforms/linuxfb/linuxfb.pro b/src/plugins/platforms/linuxfb/linuxfb.pro
index ce6814ecc1..9375486d8b 100644
--- a/src/plugins/platforms/linuxfb/linuxfb.pro
+++ b/src/plugins/platforms/linuxfb/linuxfb.pro
@@ -3,6 +3,8 @@ load(qt_plugin)
DESTDIR = $$QT.gui.plugins/platforms
+QT += core-private gui-private platformsupport-private
+
SOURCES = main.cpp qlinuxfbintegration.cpp
HEADERS = qlinuxfbintegration.h
diff --git a/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp b/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp
index 4a24d6614a..1c098a0ffc 100644
--- a/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp
+++ b/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp
@@ -42,6 +42,7 @@
#include "qlinuxfbintegration.h"
#include "../fb_base/fb_base.h"
#include "qgenericunixfontdatabase.h"
+#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
#include <QtGui/private/qpixmap_raster_p.h>
#include <private/qcore_unix_p.h> // overrides QT_OPEN
#include <qimage.h>
@@ -791,9 +792,9 @@ bool QLinuxFbIntegration::hasCapability(QPlatformIntegration::Capability cap) co
}
-QPixmapData *QLinuxFbIntegration::createPixmapData(QPixmapData::PixelType type) const
+QPlatformPixmap *QLinuxFbIntegration::createPlatformPixmap(QPlatformPixmap::PixelType type) const
{
- return new QRasterPixmapData(type);
+ return new QRasterPlatformPixmap(type);
}
QWindowSurface *QLinuxFbIntegration::createWindowSurface(QWidget *widget, WId) const
@@ -810,6 +811,11 @@ QPlatformWindow *QLinuxFbIntegration::createPlatformWindow(QWidget *widget, WId
return w;
}
+QAbstractEventDispatcher *QMinimalIntegration::createEventDispatcher() const
+{
+ return createUnixEventDispatcher();
+}
+
QPlatformFontDatabase *QLinuxFbIntegration::fontDatabase() const
{
return fontDb;
diff --git a/src/plugins/platforms/linuxfb/qlinuxfbintegration.h b/src/plugins/platforms/linuxfb/qlinuxfbintegration.h
index b96749ff03..f972a30452 100644
--- a/src/plugins/platforms/linuxfb/qlinuxfbintegration.h
+++ b/src/plugins/platforms/linuxfb/qlinuxfbintegration.h
@@ -70,6 +70,7 @@ class QLinuxFbIntegrationPrivate;
struct fb_cmap;
struct fb_var_screeninfo;
struct fb_fix_screeninfo;
+class QAbstractEventDispatcher;
class QLinuxFbIntegration : public QPlatformIntegration
{
@@ -79,9 +80,10 @@ public:
bool hasCapability(QPlatformIntegration::Capability cap) const;
- QPixmapData *createPixmapData(QPixmapData::PixelType type) const;
+ QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const;
QPlatformWindow *createPlatformWindow(QWidget *widget, WId WinId) const;
QWindowSurface *createWindowSurface(QWidget *widget, WId WinId) const;
+ QAbstractEventDispatcher *createEventDispatcher() const;
QList<QPlatformScreen *> screens() const { return mScreens; }
diff --git a/src/plugins/platforms/minimal/minimal.pro b/src/plugins/platforms/minimal/minimal.pro
index d51b6b2ed0..392d12d19a 100644
--- a/src/plugins/platforms/minimal/minimal.pro
+++ b/src/plugins/platforms/minimal/minimal.pro
@@ -1,14 +1,14 @@
TARGET = qminimal
load(qt_plugin)
-QT = core-private gui-private
+QT += core-private gui-private platformsupport-private
DESTDIR = $$QT.gui.plugins/platforms
SOURCES = main.cpp \
qminimalintegration.cpp \
- qminimalwindowsurface.cpp
+ qminimalbackingstore.cpp
HEADERS = qminimalintegration.h \
- qminimalwindowsurface.h
+ qminimalbackingstore.h
target.path += $$[QT_INSTALL_PLUGINS]/platforms
INSTALLS += target
diff --git a/src/plugins/platforms/minimal/qminimalbackingstore.cpp b/src/plugins/platforms/minimal/qminimalbackingstore.cpp
new file mode 100644
index 0000000000..08281405a4
--- /dev/null
+++ b/src/plugins/platforms/minimal/qminimalbackingstore.cpp
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "qminimalbackingstore.h"
+#include "qscreen.h"
+#include <QtCore/qdebug.h>
+#include <private/qguiapplication_p.h>
+
+QT_BEGIN_NAMESPACE
+
+QMinimalBackingStore::QMinimalBackingStore(QWindow *window)
+ : QPlatformBackingStore(window)
+{
+ //qDebug() << "QMinimalBackingStore::QMinimalBackingStore:" << (long)this;
+}
+
+QMinimalBackingStore::~QMinimalBackingStore()
+{
+}
+
+QPaintDevice *QMinimalBackingStore::paintDevice()
+{
+ //qDebug() << "QMinimalBackingStore::paintDevice";
+ return &mImage;
+}
+
+void QMinimalBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
+{
+ Q_UNUSED(window);
+ Q_UNUSED(region);
+ Q_UNUSED(offset);
+
+ static int c = 0;
+ QString filename = QString("output%1.png").arg(c++, 4, 10, QLatin1Char('0'));
+ qDebug() << "QMinimalBackingStore::flush() saving contents to" << filename.toLocal8Bit().constData();
+ mImage.save(filename);
+}
+
+void QMinimalBackingStore::resize(const QSize &size, const QRegion &)
+{
+ //qDebug() << "QMinimalBackingStore::setGeometry:" << (long)this << rect;
+ QImage::Format format = QGuiApplication::primaryScreen()->handle()->format();
+ if (mImage.size() != size)
+ mImage = QImage(size, format);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/minimal/qminimalbackingstore.h b/src/plugins/platforms/minimal/qminimalbackingstore.h
new file mode 100644
index 0000000000..9b61275e9d
--- /dev/null
+++ b/src/plugins/platforms/minimal/qminimalbackingstore.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QBACKINGSTORE_MINIMAL_H
+#define QBACKINGSTORE_MINIMAL_H
+
+#include <QtGui/QPlatformBackingStore>
+#include <QtGui/QPlatformWindow>
+#include <QtGui/QImage>
+
+QT_BEGIN_NAMESPACE
+
+class QMinimalBackingStore : public QPlatformBackingStore
+{
+public:
+ QMinimalBackingStore(QWindow *window);
+ ~QMinimalBackingStore();
+
+ QPaintDevice *paintDevice();
+ void flush(QWindow *window, const QRegion &region, const QPoint &offset);
+ void resize(const QSize &size, const QRegion &staticContents);
+
+private:
+ QImage mImage;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/platforms/minimal/qminimalintegration.cpp b/src/plugins/platforms/minimal/qminimalintegration.cpp
index b9ab528b50..2f2da6967a 100644
--- a/src/plugins/platforms/minimal/qminimalintegration.cpp
+++ b/src/plugins/platforms/minimal/qminimalintegration.cpp
@@ -40,20 +40,34 @@
****************************************************************************/
#include "qminimalintegration.h"
-#include "qminimalwindowsurface.h"
+#include "qminimalbackingstore.h"
+#ifndef Q_OS_WIN
+#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
+#else
+#include <QtCore/private/qeventdispatcher_win_p.h>
+#endif
#include <QtGui/private/qpixmap_raster_p.h>
+#include <QtGui/private/qguiapplication_p.h>
#include <QtGui/QPlatformWindow>
-QMinimalIntegration::QMinimalIntegration()
+QT_BEGIN_NAMESPACE
+
+QMinimalIntegration::QMinimalIntegration() :
+#ifdef Q_OS_WIN
+ m_eventDispatcher(new QEventDispatcherWin32())
+#else
+ m_eventDispatcher(createUnixEventDispatcher())
+#endif
{
+ QGuiApplicationPrivate::instance()->setEventDispatcher(m_eventDispatcher);
QMinimalScreen *mPrimaryScreen = new QMinimalScreen();
mPrimaryScreen->mGeometry = QRect(0, 0, 240, 320);
mPrimaryScreen->mDepth = 32;
mPrimaryScreen->mFormat = QImage::Format_ARGB32_Premultiplied;
- mScreens.append(mPrimaryScreen);
+ screenAdded(mPrimaryScreen);
}
bool QMinimalIntegration::hasCapability(QPlatformIntegration::Capability cap) const
@@ -64,19 +78,20 @@ bool QMinimalIntegration::hasCapability(QPlatformIntegration::Capability cap) co
}
}
-QPixmapData *QMinimalIntegration::createPixmapData(QPixmapData::PixelType type) const
+QPlatformWindow *QMinimalIntegration::createPlatformWindow(QWindow *window) const
{
- return new QRasterPixmapData(type);
+ Q_UNUSED(window);
+ return new QPlatformWindow(window);
}
-QPlatformWindow *QMinimalIntegration::createPlatformWindow(QWidget *widget, WId winId) const
+QPlatformBackingStore *QMinimalIntegration::createPlatformBackingStore(QWindow *window) const
{
- Q_UNUSED(winId);
- return new QPlatformWindow(widget);
+ return new QMinimalBackingStore(window);
}
-QWindowSurface *QMinimalIntegration::createWindowSurface(QWidget *widget, WId winId) const
+QAbstractEventDispatcher *QMinimalIntegration::guiThreadEventDispatcher() const
{
- Q_UNUSED(winId);
- return new QMinimalWindowSurface(widget);
+ return m_eventDispatcher;
}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/minimal/qminimalintegration.h b/src/plugins/platforms/minimal/qminimalintegration.h
index d1fcc42c68..0835c39ab6 100644
--- a/src/plugins/platforms/minimal/qminimalintegration.h
+++ b/src/plugins/platforms/minimal/qminimalintegration.h
@@ -71,14 +71,12 @@ public:
bool hasCapability(QPlatformIntegration::Capability cap) const;
- QPixmapData *createPixmapData(QPixmapData::PixelType type) const;
- QPlatformWindow *createPlatformWindow(QWidget *widget, WId winId) const;
- QWindowSurface *createWindowSurface(QWidget *widget, WId winId) const;
-
- QList<QPlatformScreen *> screens() const { return mScreens; }
+ QPlatformWindow *createPlatformWindow(QWindow *window) const;
+ QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const;
+ QAbstractEventDispatcher *guiThreadEventDispatcher() const;
private:
- QList<QPlatformScreen *> mScreens;
+ QAbstractEventDispatcher *m_eventDispatcher;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/minimal/qminimalwindowsurface.cpp b/src/plugins/platforms/minimal/qminimalwindowsurface.cpp
deleted file mode 100644
index 91c68d1d2d..0000000000
--- a/src/plugins/platforms/minimal/qminimalwindowsurface.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#include "qminimalwindowsurface.h"
-#include <QtCore/qdebug.h>
-#include <QtGui/private/qapplication_p.h>
-
-QT_BEGIN_NAMESPACE
-
-QMinimalWindowSurface::QMinimalWindowSurface(QWidget *window)
- : QWindowSurface(window)
-{
- //qDebug() << "QMinimalWindowSurface::QMinimalWindowSurface:" << (long)this;
-}
-
-QMinimalWindowSurface::~QMinimalWindowSurface()
-{
-}
-
-QPaintDevice *QMinimalWindowSurface::paintDevice()
-{
- //qDebug() << "QMinimalWindowSurface::paintDevice";
- return &mImage;
-}
-
-void QMinimalWindowSurface::flush(QWidget *widget, const QRegion &region, const QPoint &offset)
-{
- Q_UNUSED(widget);
- Q_UNUSED(region);
- Q_UNUSED(offset);
-
- static int c = 0;
- QString filename = QString("output%1.png").arg(c++, 4, 10, QLatin1Char('0'));
- qDebug() << "QMinimalWindowSurface::flush() saving contents to" << filename.toLocal8Bit().constData();
- mImage.save(filename);
-}
-
-void QMinimalWindowSurface::resize(const QSize &size)
-{
- //qDebug() << "QMinimalWindowSurface::setGeometry:" << (long)this << rect;
- QWindowSurface::resize(size);
- QImage::Format format = QApplicationPrivate::platformIntegration()->screens().first()->format();
- if (mImage.size() != size)
- mImage = QImage(size, format);
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/minimal/qminimalwindowsurface.h b/src/plugins/platforms/minimal/qminimalwindowsurface.h
deleted file mode 100644
index 2c6196a19a..0000000000
--- a/src/plugins/platforms/minimal/qminimalwindowsurface.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWINDOWSURFACE_MINIMAL_H
-#define QWINDOWSURFACE_MINIMAL_H
-
-#include <QtGui/private/qwindowsurface_p.h>
-
-#include <QtGui/QPlatformWindow>
-
-QT_BEGIN_NAMESPACE
-
-class QMinimalWindowSurface : public QWindowSurface
-{
-public:
- QMinimalWindowSurface(QWidget *window);
- ~QMinimalWindowSurface();
-
- QPaintDevice *paintDevice();
- void flush(QWidget *widget, const QRegion &region, const QPoint &offset);
- void resize(const QSize &size);
-
-private:
- QImage mImage;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/plugins/platforms/openkode/qopenkodeintegration.cpp b/src/plugins/platforms/openkode/qopenkodeintegration.cpp
index 89475db54b..38c4325bb4 100644
--- a/src/plugins/platforms/openkode/qopenkodeintegration.cpp
+++ b/src/plugins/platforms/openkode/qopenkodeintegration.cpp
@@ -43,7 +43,7 @@
#include "qopenkodewindow.h"
#include "qopenkodeeventloopintegration.h"
-#include <QtOpenGL/private/qpixmapdata_gl_p.h>
+#include <QtOpenGL/qplatformpixmap_gl_p.h>
#include <QtOpenGL/private/qwindowsurface_gl_p.h>
#include <QtGui/private/qpixmap_raster_p.h>
@@ -197,9 +197,9 @@ bool QOpenKODEIntegration::hasCapability(QPlatformIntegration::Capability cap) c
}
}
-QPixmapData *QOpenKODEIntegration::createPixmapData(QPixmapData::PixelType type) const
+QPlatformPixmap *QOpenKODEIntegration::createPlatformPixmap(QPlatformPixmap::PixelType type) const
{
- return new QGLPixmapData(type);
+ return new QGLPlatformPixmap(type);
}
QPlatformWindow *QOpenKODEIntegration::createPlatformWindow(QWidget *tlw, WId ) const
diff --git a/src/plugins/platforms/openkode/qopenkodeintegration.h b/src/plugins/platforms/openkode/qopenkodeintegration.h
index 0f001c957b..43961add6d 100644
--- a/src/plugins/platforms/openkode/qopenkodeintegration.h
+++ b/src/plugins/platforms/openkode/qopenkodeintegration.h
@@ -48,7 +48,7 @@
#include <QtGui/QPlatformIntegration>
#include <QtGui/QPlatformScreen>
-#include <QtGui/QPlatformGLContext>
+#include <QtGui/QPlatformOpenGLContext>
#include <QtGui/QPlatformFontDatabase>
#include <GLES2/gl2.h>
@@ -92,7 +92,7 @@ public:
bool hasCapability(QPlatformIntegration::Capability cap) const;
- QPixmapData *createPixmapData(QPixmapData::PixelType type) const;
+ QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const;
QPlatformWindow *createPlatformWindow(QWidget *widget, WId winId = 0) const;
QWindowSurface *createWindowSurface(QWidget *widget, WId winId) const;
diff --git a/src/plugins/platforms/openkode/qopenkodewindow.cpp b/src/plugins/platforms/openkode/qopenkodewindow.cpp
index c6fe6d0176..e20904470f 100644
--- a/src/plugins/platforms/openkode/qopenkodewindow.cpp
+++ b/src/plugins/platforms/openkode/qopenkodewindow.cpp
@@ -53,7 +53,7 @@
#include <EGL/egl.h>
-#include <QtGui/qwidget.h>
+#include <QtWidgets/qwidget.h>
#include <QtGui/private/qwidget_p.h>
#include <QtGui/private/qapplication_p.h>
@@ -235,7 +235,7 @@ WId QOpenKODEWindow::winId() const
return i++;
}
-QPlatformGLContext *QOpenKODEWindow::glContext() const
+QPlatformOpenGLContext *QOpenKODEWindow::glContext() const
{
return m_platformGlContext;
}
diff --git a/src/plugins/platforms/openkode/qopenkodewindow.h b/src/plugins/platforms/openkode/qopenkodewindow.h
index 317a6b5cd6..f48c3a2bc0 100644
--- a/src/plugins/platforms/openkode/qopenkodewindow.h
+++ b/src/plugins/platforms/openkode/qopenkodewindow.h
@@ -63,7 +63,7 @@ public:
void setVisible(bool visible);
WId winId() const;
- QPlatformGLContext *glContext() const;
+ QPlatformOpenGLContext *glContext() const;
void raise();
void lower();
diff --git a/src/plugins/platforms/openvglite/qgraphicssystem_vglite.cpp b/src/plugins/platforms/openvglite/qgraphicssystem_vglite.cpp
index 203896f489..d8e4cc984c 100644
--- a/src/plugins/platforms/openvglite/qgraphicssystem_vglite.cpp
+++ b/src/plugins/platforms/openvglite/qgraphicssystem_vglite.cpp
@@ -41,7 +41,7 @@
#include "qgraphicssystem_vglite.h"
#include "qwindowsurface_vglite.h"
-#include <QtOpenVG/private/qpixmapdata_vg_p.h>
+#include <QtOpenVG/qplatformpixmap_vg_p.h>
#include <QtGui/private/qegl_p.h>
#include <QtCore/qdebug.h>
#ifdef OPENVG_USBHP_INIT
@@ -163,16 +163,16 @@ QVGLiteGraphicsSystem::~QVGLiteGraphicsSystem()
{
}
-QPixmapData *QVGLiteGraphicsSystem::createPixmapData(QPixmapData::PixelType type) const
+QPlatformPixmap *QVGLiteGraphicsSystem::createPlatformPixmap(QPlatformPixmap::PixelType type) const
{
#if !defined(QVGLite_NO_SINGLE_CONTEXT) && !defined(QVGLite_NO_PIXMAP_DATA)
- // Pixmaps can use QVGLitePixmapData; bitmaps must use raster.
- if (type == QPixmapData::PixmapType)
- return new QVGPixmapData(type);
+ // Pixmaps can use QVGLitePlatformPixmap; bitmaps must use raster.
+ if (type == QPlatformPixmap::PixmapType)
+ return new QVGPlatformPixmap(type);
else
- return new QRasterPixmapData(type);
+ return new QRasterPlatformPixmap(type);
#else
- return new QRasterPixmapData(type);
+ return new QRasterPlatformPixmap(type);
#endif
}
diff --git a/src/plugins/platforms/openvglite/qgraphicssystem_vglite.h b/src/plugins/platforms/openvglite/qgraphicssystem_vglite.h
index 41b1d286bc..6dc6a38439 100644
--- a/src/plugins/platforms/openvglite/qgraphicssystem_vglite.h
+++ b/src/plugins/platforms/openvglite/qgraphicssystem_vglite.h
@@ -57,7 +57,7 @@ public:
QVGLiteGraphicsSystem();
~QVGLiteGraphicsSystem();
- QPixmapData *createPixmapData(QPixmapData::PixelType type) const;
+ QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const;
QWindowSurface *createWindowSurface(QWidget *widget) const;
QList<QGraphicsSystemScreen *> screens() const { return mScreens; }
diff --git a/src/plugins/platforms/openwfd/main.cpp b/src/plugins/platforms/openwfd/main.cpp
new file mode 100644
index 0000000000..c0159e7218
--- /dev/null
+++ b/src/plugins/platforms/openwfd/main.cpp
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/QPlatformIntegrationPlugin>
+#include "qopenwfdintegration.h"
+
+QT_BEGIN_NAMESPACE
+
+class QOpenWFDIntegrationPlugin : public QPlatformIntegrationPlugin
+{
+public:
+ QStringList keys() const;
+ QPlatformIntegration *create(const QString&, const QStringList&);
+};
+
+QStringList QOpenWFDIntegrationPlugin::keys() const
+{
+ QStringList list;
+ list << "OpenWFD";
+ return list;
+}
+
+QPlatformIntegration* QOpenWFDIntegrationPlugin::create(const QString& system, const QStringList& paramList)
+{
+ Q_UNUSED(paramList);
+ if (system.toLower() == "openwfd")
+ return new QOpenWFDIntegration;
+
+ return 0;
+}
+
+Q_EXPORT_PLUGIN2(openwfd, QOpenWFDIntegrationPlugin)
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/openwfd/openwf.pro b/src/plugins/platforms/openwfd/openwf.pro
new file mode 100644
index 0000000000..d913a84411
--- /dev/null
+++ b/src/plugins/platforms/openwfd/openwf.pro
@@ -0,0 +1,41 @@
+TARGET = qopenwf
+
+load(qt_plugin)
+QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/platforms
+
+QT += core-private gui-private platformsupport-private
+
+CONFIG += qpa/genericunixfontdatabase
+
+HEADERS += \
+ qopenwfddevice.h \
+ qopenwfdintegration.h \
+ qopenwfdnativeinterface.h \
+ qopenwfdscreen.h \
+ qopenwfdbackingstore.h \
+ qopenwfdevent.h \
+ qopenwfdglcontext.h \
+ qopenwfdoutputbuffer.h \
+ qopenwfdport.h \
+ qopenwfdwindow.h \
+ qopenwfdportmode.h
+
+SOURCES += \
+ main.cpp \
+ qopenwfddevice.cpp \
+ qopenwfdintegration.cpp \
+ qopenwfdnativeinterface.cpp \
+ qopenwfdscreen.cpp \
+ qopenwfdbackingstore.cpp \
+ qopenwfdevent.cpp \
+ qopenwfdglcontext.cpp \
+ qopenwfdoutputbuffer.cpp \
+ qopenwfdport.cpp \
+ qopenwfdportmode.cpp \
+ qopenwfdwindow.cpp
+
+LIBS += -lWFD -lgbm -lGLESv2 -lEGL
+
+target.path += $$[QT_INSTALL_PLUGINS]/platforms
+INSTALLS += target
+
diff --git a/src/plugins/platforms/openwfd/qopenwfdbackingstore.cpp b/src/plugins/platforms/openwfd/qopenwfdbackingstore.cpp
new file mode 100644
index 0000000000..2638d8cd5a
--- /dev/null
+++ b/src/plugins/platforms/openwfd/qopenwfdbackingstore.cpp
@@ -0,0 +1,25 @@
+#include "qopenwfdbackingstore.h"
+
+QOpenWFDBackingStore::QOpenWFDBackingStore(QWindow *window)
+ : QPlatformBackingStore(window)
+{
+}
+
+QPaintDevice * QOpenWFDBackingStore::paintDevice()
+{
+ return &mImage;
+}
+
+//we don't support flush yet :)
+void QOpenWFDBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
+{
+ Q_UNUSED(window);
+ Q_UNUSED(region);
+ Q_UNUSED(offset);
+}
+
+void QOpenWFDBackingStore::resize(const QSize &size, const QRegion &staticContents)
+{
+ Q_UNUSED(staticContents);
+ mImage = QImage(size,QImage::Format_RGB32);
+}
diff --git a/src/plugins/platforms/openwfd/qopenwfdbackingstore.h b/src/plugins/platforms/openwfd/qopenwfdbackingstore.h
new file mode 100644
index 0000000000..c173de6c19
--- /dev/null
+++ b/src/plugins/platforms/openwfd/qopenwfdbackingstore.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QOPENWFDBACKINGSTORE_H
+#define QOPENWFDBACKINGSTORE_H
+
+#include <QtGui/QPlatformBackingStore>
+#include <QtGui/QImage>
+
+class QOpenWFDBackingStore : public QPlatformBackingStore
+{
+public:
+ QOpenWFDBackingStore(QWindow *window);
+
+ QPaintDevice *paintDevice();
+
+ // 'window' can be a child window, in which case 'region' is in child window coordinates and
+ // offset is the (child) window's offset in relation to the window surface.
+ void flush(QWindow *window, const QRegion &region, const QPoint &offset);
+
+ void resize(const QSize &size, const QRegion &staticContents);
+
+private:
+ QImage mImage;
+};
+
+#endif // QOPENWFDBACKINGSTORE_H
diff --git a/src/plugins/platforms/openwfd/qopenwfddevice.cpp b/src/plugins/platforms/openwfd/qopenwfddevice.cpp
new file mode 100644
index 0000000000..d3ff6d45d8
--- /dev/null
+++ b/src/plugins/platforms/openwfd/qopenwfddevice.cpp
@@ -0,0 +1,317 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qopenwfddevice.h"
+
+#include "qopenwfdport.h"
+#include "qopenwfdscreen.h"
+
+#include <QtCore/QDebug>
+
+#include <WF/wfdext.h>
+#include <gbm.h>
+
+QOpenWFDDevice::QOpenWFDDevice(QOpenWFDIntegration *integration, WFDint device_enumeration)
+ : mIntegration(integration)
+ , mDeviceEnum(device_enumeration)
+ , mCommitedDevice(false)
+ , mWaitingForBindSourceEvent(false)
+{
+ mDevice = wfdCreateDevice(WFD_DEFAULT_DEVICE_ID,WFD_NONE);
+ if (mDevice == WFD_INVALID_HANDLE)
+ qDebug() << "failed to create device";
+
+ mEvent = wfdCreateEvent(mDevice,0);
+ if (mEvent == WFD_INVALID_HANDLE)
+ qDebug() << "failed to create event handle";
+
+ //initialize pipelines for device.
+ wfdEnumeratePipelines(mDevice,WFD_NONE,0,WFD_NONE);
+
+ initializeGbmAndEgl();
+
+ WFDint numberOfPorts = wfdEnumeratePorts(mDevice,0,0,0);
+ WFDint port_enumerations[numberOfPorts];
+ WFDint actualNumberOfPorts = wfdEnumeratePorts(mDevice,port_enumerations,numberOfPorts,WFD_NONE);
+ Q_ASSERT(actualNumberOfPorts == numberOfPorts);
+
+ for (int i = 0; i < actualNumberOfPorts; i++)
+ {
+ QOpenWFDPort *port = new QOpenWFDPort(this,port_enumerations[i]);
+ if (port->attached()) {
+ mPorts.append(port);
+ } else {
+ delete port;
+ }
+ }
+
+ int fd = wfdDeviceEventGetFD(mDevice,mEvent);
+ mEventSocketNotifier = new QSocketNotifier(fd,QSocketNotifier::Read,this);
+ connect(mEventSocketNotifier,SIGNAL(activated(int)),SLOT(readEvents()));
+
+ mCommitedDevice = true;
+ commit(WFD_COMMIT_ENTIRE_DEVICE, handle());
+}
+
+QOpenWFDDevice::~QOpenWFDDevice()
+{
+ delete mEventSocketNotifier;
+ wfdDestroyEvent(mDevice,mEvent);
+
+ for (int i = 0; i < mPorts.size(); i++) {
+ //probably don't need to remove them from the list
+ QList <WFDint> keys = mUsedPipelines.keys(mPorts.at(i));
+ for (int keyIndex = 0; keyIndex < keys.size(); keyIndex++) {
+ mUsedPipelines.remove(keys.at(keyIndex));
+ }
+ //but we have to delete them :)
+ delete mPorts[i];
+ }
+
+ eglDestroyContext(mEglDisplay,mEglContext);
+ eglTerminate(mEglDisplay);
+
+ gbm_device_destroy(mGbmDevice);
+
+ wfdDestroyDevice(mDevice);
+}
+
+WFDDevice QOpenWFDDevice::handle() const
+{
+ return mDevice;
+}
+
+QOpenWFDIntegration * QOpenWFDDevice::integration() const
+{
+ return mIntegration;
+}
+
+bool QOpenWFDDevice::isPipelineUsed(WFDint pipelineId)
+{
+ return mUsedPipelines.contains(pipelineId);
+}
+
+void QOpenWFDDevice::addToUsedPipelineSet(WFDint pipelineId,QOpenWFDPort *port)
+{
+ mUsedPipelines.insert(pipelineId,port);
+}
+
+void QOpenWFDDevice::removeFromUsedPipelineSet(WFDint pipelineId)
+{
+ mUsedPipelines.remove(pipelineId);
+}
+
+gbm_device * QOpenWFDDevice::gbmDevice() const
+
+{
+ return mGbmDevice;
+}
+
+EGLDisplay QOpenWFDDevice::eglDisplay() const
+{
+ return mEglDisplay;
+}
+
+EGLContext QOpenWFDDevice::eglContext() const
+{
+ return mEglContext;
+}
+
+void QOpenWFDDevice::commit(WFDCommitType type, WFDHandle handle)
+{
+ if (mCommitedDevice) {
+ wfdDeviceCommit(mDevice,type,handle);
+ }
+}
+
+void QOpenWFDDevice::waitForPipelineBindSourceCompleteEvent()
+{
+ mWaitingForBindSourceEvent = true;
+
+ while (mWaitingForBindSourceEvent) {
+ readEvents(WFD_FOREVER);
+ }
+}
+
+void QOpenWFDDevice::readEvents(WFDtime wait)
+{
+ WFDEventType type = wfdDeviceEventWait(mDevice,mEvent,wait);
+
+ if (type == WFD_EVENT_NONE || type == WFD_EVENT_DESTROYED) {
+ return;
+ }
+ switch (type) {
+ case WFD_EVENT_INVALID:
+ case WFD_EVENT_NONE:
+ return;
+ case WFD_EVENT_DESTROYED:
+ qDebug() << "Event or Device destoryed!";
+ return;
+ case WFD_EVENT_PORT_ATTACH_DETACH:
+ handlePortAttachDetach();
+ break;
+ case WFD_EVENT_PORT_PROTECTION_FAILURE:
+ qDebug() << "Port protection event handling not implemented";
+ break;
+ case WFD_EVENT_PIPELINE_BIND_SOURCE_COMPLETE:
+ handlePipelineBindSourceComplete();
+ break;
+ case WFD_EVENT_PIPELINE_BIND_MASK_COMPLETE:
+ qDebug() << "Pipeline bind mask event handling not implemented";
+ break;
+ default:
+ qDebug() << "Not recognised event type";
+ break;
+ }
+
+
+}
+
+void QOpenWFDDevice::initializeGbmAndEgl()
+{
+
+ qDebug() << "initializing GBM and EGL";
+ int fd = wfdGetDeviceAttribi(mDevice,WFD_DEVICE_ID);
+ if (fd < 0) {
+ qDebug() << "failed to get WFD_DEVICE_ID";
+ }
+
+ mGbmDevice = gbm_create_device(fd);
+
+ setenv("EGL_PLATFORM", "drm",1);
+
+ mEglDisplay = eglGetDisplay(mGbmDevice);
+
+ EGLint minor, major;
+
+ if (!eglInitialize(mEglDisplay,&major,&minor)) {
+ qDebug() << "failed to initialize egl";
+ }
+
+ QByteArray eglExtensions = eglQueryString(mEglDisplay, EGL_EXTENSIONS);
+ if (!eglExtensions.contains("EGL_KHR_surfaceless_opengl")) {
+ qDebug() << "This egl implementation does not have the required EGL extension EGL_KHR_surfaceless_opengl";
+ }
+
+ eglBindAPI(EGL_OPENGL_ES_API);
+
+ EGLint contextAttribs[] = {
+ EGL_CONTEXT_CLIENT_VERSION, 2,
+ EGL_NONE
+ };
+
+ mEglContext = eglCreateContext(mEglDisplay,NULL,EGL_NO_CONTEXT,contextAttribs);
+ if (mEglContext == EGL_NO_CONTEXT) {
+ qDebug() << "Failed to create EGL context";
+ }
+
+ eglCreateImage = (PFNEGLCREATEIMAGEKHRPROC) eglGetProcAddress("eglCreateImageKHR");
+ if (!eglCreateImage) {
+ qWarning("failed to load extension eglCreateImageKHR");
+ }
+
+ eglDestroyImage = (PFNEGLDESTROYIMAGEKHRPROC) eglGetProcAddress("eglDestroyImageKHR");
+ if (!eglDestroyImage) {
+ qWarning("failed to load extension eglDestoryImageKHR");
+ }
+
+ glEglImageTargetRenderBufferStorage = (PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC) eglGetProcAddress("glEGLImageTargetRenderbufferStorageOES");
+ if (!glEglImageTargetRenderBufferStorage) {
+ qWarning("failed to load extension glEGLImageTargetRenderbufferStorageOES");
+ }
+}
+
+void QOpenWFDDevice::handlePortAttachDetach()
+{
+ WFDint id = wfdGetEventAttribi(mDevice,mEvent,WFD_EVENT_PORT_ATTACH_PORT_ID);
+ if (id == WFD_INVALID_PORT_ID)
+ return;
+
+ WFDint attachState = wfdGetEventAttribi(mDevice,mEvent,WFD_EVENT_PORT_ATTACH_STATE);
+ if (attachState == WFD_TRUE) {
+ int indexToAdd = -1;
+ for (int i = 0; i < mPorts.size(); i++) {
+ if (mPorts.at(i)->portId() == id) {
+ indexToAdd = i;
+ qDebug() << "found index to attach";
+ break;
+ }
+ }
+ if (indexToAdd >= 0) {
+ mPorts[indexToAdd]->attach();
+ } else {
+ mPorts.append(new QOpenWFDPort(this,id));
+ }
+
+ } else {
+ int indexToDelete = -1;
+ for (int i = 0; i < mPorts.size(); i++) {
+ if (mPorts.at(i)->portId() == id) {
+ indexToDelete = i;
+ break;
+ }
+ }
+ if (indexToDelete >= 0) {
+ QOpenWFDPort *portToDelete = mPorts.at(indexToDelete);
+ mPorts.removeAt(indexToDelete);
+ delete portToDelete;
+ }
+ }
+}
+
+void QOpenWFDDevice::handlePipelineBindSourceComplete()
+{
+ mWaitingForBindSourceEvent = false;
+
+ WFDint overflow = wfdGetEventAttribi(mDevice,mEvent, WFD_EVENT_PIPELINE_BIND_QUEUE_OVERFLOW);
+ if (overflow == WFD_TRUE) {
+ qDebug() << "PIPELINE_BIND_QUEUE_OVERFLOW event occured";
+ }
+
+ WFDint pipelineId = wfdGetEventAttribi(mDevice,mEvent,WFD_EVENT_PIPELINE_BIND_PIPELINE_ID);
+ for (int i = 0; i < mPorts.size(); i++) {
+ if (pipelineId != WFD_INVALID_PIPELINE_ID && mUsedPipelines.contains(pipelineId)) {
+ QOpenWFDPort *port = mUsedPipelines.value(pipelineId);
+ port->screen()->pipelineBindSourceComplete();
+ break;
+ }
+ }
+}
diff --git a/src/plugins/platforms/openwfd/qopenwfddevice.h b/src/plugins/platforms/openwfd/qopenwfddevice.h
new file mode 100644
index 0000000000..83a5539124
--- /dev/null
+++ b/src/plugins/platforms/openwfd/qopenwfddevice.h
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QOPENWFDDEVICE_H
+#define QOPENWFDDEVICE_H
+
+#include "qopenwfdintegration.h"
+
+#include <QtCore/QList>
+#include <QtCore/QSet>
+#include <QtCore/QSocketNotifier>
+
+#include <WF/wfd.h>
+
+#include <gbm.h>
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+class QOpenWFDPort;
+
+class QOpenWFDDevice : public QObject
+{
+ Q_OBJECT
+public:
+ QOpenWFDDevice(QOpenWFDIntegration *integration, WFDint handle);
+ ~QOpenWFDDevice();
+ WFDDevice handle() const;
+ QOpenWFDIntegration *integration() const;
+
+
+ bool isPipelineUsed(WFDint pipelineId);
+ void addToUsedPipelineSet(WFDint pipelineId, QOpenWFDPort *port);
+ void removeFromUsedPipelineSet(WFDint pipelineId);
+
+ gbm_device *gbmDevice() const;
+ EGLDisplay eglDisplay() const;
+ EGLContext eglContext() const;
+
+ PFNEGLCREATEIMAGEKHRPROC eglCreateImage;
+ PFNEGLDESTROYIMAGEKHRPROC eglDestroyImage;
+ PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC glEglImageTargetRenderBufferStorage;
+
+ void commit(WFDCommitType type, WFDHandle handle);
+ bool isDeviceInitializedAndCommited() const { return mCommitedDevice; }
+
+ void waitForPipelineBindSourceCompleteEvent();
+
+public slots:
+ void readEvents(WFDtime wait = 0);
+private:
+ void initializeGbmAndEgl();
+ void handlePortAttachDetach();
+ void handlePipelineBindSourceComplete();
+ QOpenWFDIntegration *mIntegration;
+ WFDint mDeviceEnum;
+ WFDDevice mDevice;
+
+ WFDEvent mEvent;
+ QSocketNotifier *mEventSocketNotifier;
+
+ QList<QOpenWFDPort *> mPorts;
+
+ QMap<WFDint, QOpenWFDPort *> mUsedPipelines;
+
+ struct gbm_device *mGbmDevice;
+ EGLDisplay mEglDisplay;
+ EGLContext mEglContext;
+
+ bool mCommitedDevice;
+ bool mWaitingForBindSourceEvent;
+};
+
+#endif // QOPENWFDDEVICE_H
diff --git a/src/plugins/platforms/openwfd/qopenwfdevent.cpp b/src/plugins/platforms/openwfd/qopenwfdevent.cpp
new file mode 100644
index 0000000000..748dde65e7
--- /dev/null
+++ b/src/plugins/platforms/openwfd/qopenwfdevent.cpp
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qopenwfdevent.h"
+
+QOpenWFDEvent::QOpenWFDEvent()
+{
+}
diff --git a/src/plugins/platforms/openwfd/qopenwfdevent.h b/src/plugins/platforms/openwfd/qopenwfdevent.h
new file mode 100644
index 0000000000..3010fdb55b
--- /dev/null
+++ b/src/plugins/platforms/openwfd/qopenwfdevent.h
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QOPENWFDEVENT_H
+#define QOPENWFDEVENT_H
+
+class QOpenWFDEvent
+{
+public:
+ QOpenWFDEvent();
+};
+
+#endif // QOPENWFDEVENT_H
diff --git a/src/plugins/platforms/openwfd/qopenwfdglcontext.cpp b/src/plugins/platforms/openwfd/qopenwfdglcontext.cpp
new file mode 100644
index 0000000000..0db717c4d6
--- /dev/null
+++ b/src/plugins/platforms/openwfd/qopenwfdglcontext.cpp
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qopenwfdglcontext.h"
+
+#include "qopenwfdwindow.h"
+#include "qopenwfdscreen.h"
+
+QOpenWFDGLContext::QOpenWFDGLContext(QOpenWFDDevice *device)
+ : QPlatformOpenGLContext()
+ , mWfdDevice(device)
+{
+}
+
+QSurfaceFormat QOpenWFDGLContext::format() const
+{
+ return QSurfaceFormat();
+}
+
+bool QOpenWFDGLContext::makeCurrent(QPlatformSurface *surface)
+{
+ EGLDisplay display = mWfdDevice->eglDisplay();
+ EGLContext context = mWfdDevice->eglContext();
+ if (!eglMakeCurrent(display,EGL_NO_SURFACE,EGL_NO_SURFACE,context)) {
+ qDebug() << "GLContext: eglMakeCurrent FAILED!";
+ }
+
+ QPlatformWindow *window = static_cast<QPlatformWindow *>(surface);
+ QOpenWFDScreen *screen = static_cast<QOpenWFDScreen *>(QPlatformScreen::platformScreenForWindow(window->window()));
+ screen->bindFramebuffer();
+ return true;
+}
+
+void QOpenWFDGLContext::doneCurrent()
+{
+ //do nothing :)
+}
+
+void QOpenWFDGLContext::swapBuffers(QPlatformSurface *surface)
+{
+ glFlush();
+
+ QPlatformWindow *window = static_cast<QPlatformWindow *>(surface);
+ QOpenWFDScreen *screen = static_cast<QOpenWFDScreen *>(QPlatformScreen::platformScreenForWindow(window->window()));
+
+ screen->swapBuffers();
+}
+
+void (*QOpenWFDGLContext::getProcAddress(const QByteArray &procName)) ()
+{
+ return eglGetProcAddress(procName.data());
+}
+
+EGLContext QOpenWFDGLContext::eglContext() const
+{
+ return mWfdDevice->eglContext();
+}
+
+
diff --git a/src/plugins/platforms/openwfd/qopenwfdglcontext.h b/src/plugins/platforms/openwfd/qopenwfdglcontext.h
new file mode 100644
index 0000000000..3287a853c7
--- /dev/null
+++ b/src/plugins/platforms/openwfd/qopenwfdglcontext.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QOPENWFDGLCONTEXT_H
+#define QOPENWFDGLCONTEXT_H
+
+#include <QtGui/QPlatformOpenGLContext>
+
+#include "qopenwfddevice.h"
+
+class QOpenWFDGLContext : public QPlatformOpenGLContext
+{
+public:
+ QOpenWFDGLContext(QOpenWFDDevice *device);
+
+ QSurfaceFormat format() const;
+
+ bool makeCurrent(QPlatformSurface *surface);
+ void doneCurrent();
+
+ void swapBuffers(QPlatformSurface *surface);
+
+ void (*getProcAddress(const QByteArray &procName)) ();
+
+ EGLContext eglContext() const;
+private:
+ QOpenWFDDevice *mWfdDevice;
+};
+
+#endif // QOPENWFDGLCONTEXT_H
diff --git a/src/plugins/platforms/openwfd/qopenwfdintegration.cpp b/src/plugins/platforms/openwfd/qopenwfdintegration.cpp
new file mode 100644
index 0000000000..3d57759183
--- /dev/null
+++ b/src/plugins/platforms/openwfd/qopenwfdintegration.cpp
@@ -0,0 +1,145 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qopenwfdintegration.h"
+#include "qopenwfdscreen.h"
+#include "qopenwfdnativeinterface.h"
+#include "qopenwfddevice.h"
+#include "qopenwfdwindow.h"
+#include "qopenwfdglcontext.h"
+#include "qopenwfdbackingstore.h"
+
+#include <QtPlatformSupport/private/qgenericunixprintersupport_p.h>
+
+#include <QtGui/private/qguiapplication_p.h>
+#include <QtGui/QOpenGLContext>
+#include <QtGui/QScreen>
+
+#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
+#include <QtPlatformSupport/private/qgenericunixfontdatabase_p.h>
+
+#include <stdio.h>
+
+#include <WF/wfd.h>
+
+QOpenWFDIntegration::QOpenWFDIntegration()
+ : QPlatformIntegration()
+ , mPrinterSupport(new QGenericUnixPrinterSupport)
+ , mEventDispatcher(createUnixEventDispatcher())
+{
+ QGuiApplicationPrivate::instance()->setEventDispatcher(mEventDispatcher);
+ int numberOfDevices = wfdEnumerateDevices(0,0,0);
+
+ WFDint devices[numberOfDevices];
+ int actualNumberOfDevices = wfdEnumerateDevices(devices,numberOfDevices,0);
+ Q_ASSERT(actualNumberOfDevices == numberOfDevices);
+
+ for (int i = 0; i < actualNumberOfDevices; i++) {
+ mDevices.append(new QOpenWFDDevice(this,devices[i]));
+ }
+
+ mFontDatabase = new QGenericUnixFontDatabase();
+ mNativeInterface = new QOpenWFDNativeInterface;
+}
+
+QOpenWFDIntegration::~QOpenWFDIntegration()
+{
+ //dont delete screens since they are deleted by the devices
+ qDebug() << "deleting platform integration";
+ for (int i = 0; i < mDevices.size(); i++) {
+ delete mDevices[i];
+ }
+
+ delete mFontDatabase;
+ delete mNativeInterface;
+ delete mPrinterSupport;
+}
+
+bool QOpenWFDIntegration::hasCapability(QPlatformIntegration::Capability cap) const
+{
+ switch (cap) {
+ case ThreadedPixmaps: return true;
+ case OpenGL: return true;
+ default: return QPlatformIntegration::hasCapability(cap);
+ }
+}
+
+QPlatformWindow *QOpenWFDIntegration::createPlatformWindow(QWindow *window) const
+{
+ return new QOpenWFDWindow(window);
+}
+
+QPlatformOpenGLContext *QOpenWFDIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
+{
+ QOpenWFDScreen *screen = static_cast<QOpenWFDScreen *>(context->screen()->handle());
+
+ return new QOpenWFDGLContext(screen->port()->device());
+}
+
+QPlatformBackingStore *QOpenWFDIntegration::createPlatformBackingStore(QWindow *window) const
+{
+ return new QOpenWFDBackingStore(window);
+}
+
+QAbstractEventDispatcher *QOpenWFDIntegration::guiThreadEventDispatcher() const
+{
+ return mEventDispatcher;
+}
+
+QPlatformFontDatabase *QOpenWFDIntegration::fontDatabase() const
+{
+ return mFontDatabase;
+}
+
+QPlatformNativeInterface * QOpenWFDIntegration::nativeInterface() const
+{
+ return mNativeInterface;
+}
+
+QPlatformPrinterSupport * QOpenWFDIntegration::printerSupport() const
+{
+ return mPrinterSupport;
+}
+
+void QOpenWFDIntegration::addScreen(QOpenWFDScreen *screen)
+{
+ screenAdded(screen);
+}
diff --git a/src/plugins/platforms/openwfd/qopenwfdintegration.h b/src/plugins/platforms/openwfd/qopenwfdintegration.h
new file mode 100644
index 0000000000..b5315b31da
--- /dev/null
+++ b/src/plugins/platforms/openwfd/qopenwfdintegration.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QOPENWFDINTEGRATION_H
+#define QOPENWFDINTEGRATION_H
+
+#include <QtGui/QPlatformIntegration>
+#include <QtGui/QPlatformScreen>
+
+QT_BEGIN_NAMESPACE
+
+class QOpenWFDDevice;
+class QOpenWFDScreen;
+
+class QOpenWFDIntegration : public QPlatformIntegration
+{
+public:
+ QOpenWFDIntegration();
+ ~QOpenWFDIntegration();
+
+ bool hasCapability(Capability cap) const;
+ QPlatformWindow *createPlatformWindow(QWindow *window) const;
+ QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const;
+ QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const;
+
+ //This should not be a factory interface, but rather a accessor
+ QAbstractEventDispatcher *guiThreadEventDispatcher() const;
+
+ QPlatformFontDatabase *fontDatabase() const;
+
+ QPlatformNativeInterface *nativeInterface()const;
+
+ QPlatformPrinterSupport *printerSupport() const;
+
+ void addScreen(QOpenWFDScreen *screen);
+private:
+ QList<QPlatformScreen *> mScreens;
+ QList<QOpenWFDDevice *>mDevices;
+
+ QPlatformFontDatabase *mFontDatabase;
+ QPlatformNativeInterface *mNativeInterface;
+ QPlatformPrinterSupport *mPrinterSupport;
+ QAbstractEventDispatcher *mEventDispatcher;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/platforms/openwfd/qopenwfdnativeinterface.cpp b/src/plugins/platforms/openwfd/qopenwfdnativeinterface.cpp
new file mode 100644
index 0000000000..758e0c4398
--- /dev/null
+++ b/src/plugins/platforms/openwfd/qopenwfdnativeinterface.cpp
@@ -0,0 +1,141 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qopenwfdnativeinterface.h"
+
+#include "qopenwfdscreen.h"
+#include "qopenwfdwindow.h"
+#include "qopenwfdglcontext.h"
+
+#include <private/qguiapplication_p.h>
+#include <QtCore/QMap>
+
+#include <QtCore/QDebug>
+
+#include <QtGui/qguiglcontext_qpa.h>
+
+class QOpenWFDResourceMap : public QMap<QByteArray, QOpenWFDNativeInterface::ResourceType>
+{
+public:
+ QOpenWFDResourceMap()
+ :QMap<QByteArray, QOpenWFDNativeInterface::ResourceType>()
+ {
+ insert("wfddevice",QOpenWFDNativeInterface::WFDDevice);
+ insert("egldisplay",QOpenWFDNativeInterface::EglDisplay);
+ insert("eglcontext",QOpenWFDNativeInterface::EglContext);
+ insert("wfdport",QOpenWFDNativeInterface::WFDPort);
+ insert("wfdpipeline",QOpenWFDNativeInterface::WFDPipeline);
+ }
+};
+
+Q_GLOBAL_STATIC(QOpenWFDResourceMap, qOpenWFDResourceMap)
+
+void *QOpenWFDNativeInterface::nativeResourceForContext(const QByteArray &resourceString, QOpenGLContext *context)
+{
+ QByteArray lowerCaseResource = resourceString.toLower();
+ ResourceType resource = qOpenWFDResourceMap()->value(lowerCaseResource);
+ void *result = 0;
+ switch (resource) {
+ case EglContext:
+ result = eglContextForContext(context);
+ break;
+ default:
+ result = 0;
+ }
+ return result;
+}
+
+void *QOpenWFDNativeInterface::nativeResourceForWindow(const QByteArray &resourceString, QWindow *window)
+{
+ QByteArray lowerCaseResource = resourceString.toLower();
+ ResourceType resource = qOpenWFDResourceMap()->value(lowerCaseResource);
+ void *result = 0;
+ switch (resource) {
+ //What should we do for int wfd handles? This is clearly not the solution
+ case WFDDevice:
+ result = (void *)wfdDeviceForWindow(window);
+ break;
+ case WFDPort:
+ result = (void *)wfdPortForWindow(window);
+ break;
+ case WFDPipeline:
+ result = (void *)wfdPipelineForWindow(window);
+ break;
+ case EglDisplay:
+ result = eglDisplayForWindow(window);
+ break;
+ default:
+ result = 0;
+ }
+ return result;
+}
+
+WFDHandle QOpenWFDNativeInterface::wfdDeviceForWindow(QWindow *window)
+{
+ QOpenWFDWindow *openWFDwindow = static_cast<QOpenWFDWindow *>(window->handle());
+ return openWFDwindow->port()->device()->handle();
+}
+
+WFDHandle QOpenWFDNativeInterface::wfdPortForWindow(QWindow *window)
+{
+ QOpenWFDWindow *openWFDwindow = static_cast<QOpenWFDWindow *>(window->handle());
+ return openWFDwindow->port()->handle();
+}
+
+WFDHandle QOpenWFDNativeInterface::wfdPipelineForWindow(QWindow *window)
+
+{
+ QOpenWFDWindow *openWFDwindow = static_cast<QOpenWFDWindow *>(window->handle());
+ return openWFDwindow->port()->pipeline();
+
+}
+
+void *QOpenWFDNativeInterface::eglDisplayForWindow(QWindow *window)
+{
+ QOpenWFDWindow *openWFDwindow = static_cast<QOpenWFDWindow *>(window->handle());
+ return openWFDwindow->port()->device()->eglDisplay();
+}
+
+void * QOpenWFDNativeInterface::eglContextForContext(QOpenGLContext *context)
+{
+ QOpenWFDGLContext *openWFDContext = static_cast<QOpenWFDGLContext *>(context->handle());
+ return openWFDContext->eglContext();
+}
diff --git a/src/plugins/platforms/openwfd/qopenwfdnativeinterface.h b/src/plugins/platforms/openwfd/qopenwfdnativeinterface.h
new file mode 100644
index 0000000000..cff49dc8b0
--- /dev/null
+++ b/src/plugins/platforms/openwfd/qopenwfdnativeinterface.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QOPENWFDNATIVEINTERFACE_H
+#define QOPENWFDNATIVEINTERFACE_H
+
+#include <QtGui/QPlatformNativeInterface>
+
+#include <WF/wfdplatform.h>
+
+class QOpenWFDScreen;
+
+class QOpenWFDNativeInterface : public QPlatformNativeInterface
+{
+public:
+ enum ResourceType {
+ WFDDevice,
+ EglDisplay,
+ EglContext,
+ WFDPort,
+ WFDPipeline
+ };
+
+ void *nativeResourceForContext(const QByteArray &resourceString, QOpenGLContext *context);
+ void *nativeResourceForWindow(const QByteArray &resourceString, QWindow *window);
+
+ WFDHandle wfdDeviceForWindow(QWindow *window);
+ void *eglDisplayForWindow(QWindow *window);
+ WFDHandle wfdPortForWindow(QWindow *window);
+ WFDHandle wfdPipelineForWindow(QWindow *window);
+
+ void *eglContextForContext(QOpenGLContext *context);
+
+private:
+ static QOpenWFDScreen *qPlatformScreenForWindow(QWindow *window);
+};
+
+#endif // QOPENWFDNATIVEINTERFACE_H
diff --git a/src/plugins/platforms/openwfd/qopenwfdoutputbuffer.cpp b/src/plugins/platforms/openwfd/qopenwfdoutputbuffer.cpp
new file mode 100644
index 0000000000..fb3292c31a
--- /dev/null
+++ b/src/plugins/platforms/openwfd/qopenwfdoutputbuffer.cpp
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qopenwfdoutputbuffer.h"
+
+#include "qopenwfdport.h"
+
+QOpenWFDOutputBuffer::QOpenWFDOutputBuffer(const QSize &size, QOpenWFDPort *port)
+ : mPort(port)
+ , mAvailable(true)
+{
+ qDebug() << "creating output buffer for size" << size;
+ glGenRenderbuffers(1,&mRbo);
+ glBindRenderbuffer(GL_RENDERBUFFER, mRbo);
+
+ mGbm_buffer = gbm_bo_create(port->device()->gbmDevice(),
+ size.width(),
+ size.height(),
+ GBM_BO_FORMAT_XRGB8888,
+ GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
+
+ mEglImage = port->device()->eglCreateImage(port->device()->eglDisplay(),0, EGL_NATIVE_PIXMAP_KHR, mGbm_buffer, 0);
+
+ port->device()->glEglImageTargetRenderBufferStorage(GL_RENDERBUFFER,mEglImage);
+
+ mWfdSource = wfdCreateSourceFromImage(port->device()->handle(),port->pipeline(),mEglImage,WFD_NONE);
+ if (mWfdSource == WFD_INVALID_HANDLE) {
+ qWarning("failed to create wfdSource from image");
+ }
+}
+
+QOpenWFDOutputBuffer::~QOpenWFDOutputBuffer()
+{
+ wfdDestroySource(mPort->device()->handle(),mWfdSource);
+ if (!mPort->device()->eglDestroyImage(mPort->device()->eglDisplay(),mEglImage)) {
+ qDebug() << "could not delete eglImage";
+ }
+ gbm_bo_destroy(mGbm_buffer);
+
+ glDeleteRenderbuffers(1, &mRbo);
+}
+
+void QOpenWFDOutputBuffer::bindToCurrentFbo()
+{
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER,
+ GL_COLOR_ATTACHMENT0,
+ GL_RENDERBUFFER,
+ mRbo);
+ if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
+ qDebug() << "framebuffer not ready!";
+ }
+}
diff --git a/src/plugins/platforms/openwfd/qopenwfdoutputbuffer.h b/src/plugins/platforms/openwfd/qopenwfdoutputbuffer.h
new file mode 100644
index 0000000000..1697f076a9
--- /dev/null
+++ b/src/plugins/platforms/openwfd/qopenwfdoutputbuffer.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QOPENWFDOUTPUTBUFFER_H
+#define QOPENWFDOUTPUTBUFFER_H
+
+#include "qopenwfdport.h"
+
+#include <EGL/egl.h>
+#include <GLES2/gl2.h>
+
+class QOpenWFDOutputBuffer
+{
+public:
+ QOpenWFDOutputBuffer(const QSize &size, QOpenWFDPort *port);
+ ~QOpenWFDOutputBuffer();
+ void bindToCurrentFbo();
+ bool isAvailable() const { return mAvailable; }
+ void setAvailable(bool available) { mAvailable = available; }
+
+ WFDSource wfdSource() const { return mWfdSource; }
+private:
+ QOpenWFDPort *mPort;
+ WFDSource mWfdSource;
+ GLuint mRbo;
+ EGLImageKHR mEglImage;
+ struct gbm_bo *mGbm_buffer;
+ bool mAvailable;
+};
+
+#endif // QOPENWFDOUTPUTBUFFER_H
diff --git a/src/plugins/platforms/openwfd/qopenwfdport.cpp b/src/plugins/platforms/openwfd/qopenwfdport.cpp
new file mode 100644
index 0000000000..5f38e48eed
--- /dev/null
+++ b/src/plugins/platforms/openwfd/qopenwfdport.cpp
@@ -0,0 +1,212 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qopenwfdport.h"
+
+#include "qopenwfdportmode.h"
+#include "qopenwfdscreen.h"
+
+#include <QtCore/QDebug>
+
+QOpenWFDPort::QOpenWFDPort(QOpenWFDDevice *device, WFDint portEnumeration)
+ : mDevice(device)
+ , mPortId(portEnumeration)
+ , mAttached(false)
+ , mPipelineId(WFD_INVALID_PIPELINE_ID)
+ , mPipeline(WFD_INVALID_HANDLE)
+{
+ mPort = wfdCreatePort(device->handle(),portEnumeration,0);
+ WFDint isPortAttached = wfdGetPortAttribi(device->handle(),mPort,WFD_PORT_ATTACHED);
+ if (isPortAttached) {
+ attach();
+ }
+}
+
+QOpenWFDPort::~QOpenWFDPort()
+{
+ detach();
+
+ wfdDestroyPort(mDevice->handle(),mPort);
+}
+
+void QOpenWFDPort::attach()
+{
+ if (mAttached) {
+ return;
+ }
+
+ //just forcing port to be on
+ wfdSetPortAttribi(mDevice->handle(), mPort, WFD_PORT_POWER_MODE, WFD_POWER_MODE_ON);
+
+ int numberOfPortModes = wfdGetPortModes(mDevice->handle(),mPort,0,0);
+ WFDPortMode portModes[numberOfPortModes];
+ int actualNumberOfPortModes = wfdGetPortModes(mDevice->handle(),mPort,portModes,numberOfPortModes);
+ Q_ASSERT(actualNumberOfPortModes == numberOfPortModes);
+
+ if (!actualNumberOfPortModes) {
+ qDebug() << "didn't find any available port modes";
+ return;
+ }
+
+ for (int i = 0; i < actualNumberOfPortModes; i++) {
+ if (portModes[i] != WFD_INVALID_HANDLE) {
+ mPortModes.append(QOpenWFDPortMode(this,portModes[i]));
+ qDebug() << "PortModeAdded:" << mPortModes.at(mPortModes.size()-1);
+ }
+ }
+
+
+ mPixelSize = setNativeResolutionMode();
+ if (mPixelSize.isEmpty()) {
+ qDebug() << "Could not set native resolution mode in QOpenWFPort";
+ }
+
+ WFDfloat physicalWFDSize[2];
+ wfdGetPortAttribfv(mDevice->handle(),mPort,WFD_PORT_PHYSICAL_SIZE,2,physicalWFDSize);
+ mPhysicalSize = QSizeF(physicalWFDSize[0],physicalWFDSize[1]);
+
+ WFDint numAvailablePipelines = wfdGetPortAttribi(mDevice->handle(),mPort,WFD_PORT_PIPELINE_ID_COUNT);
+ if (!numAvailablePipelines) {
+ qFatal("Not possible to make screen that is not possible to create WFPort with no pipline");
+ }
+
+ WFDint pipeIds[numAvailablePipelines];
+ wfdGetPortAttribiv(mDevice->handle(),mPort,WFD_PORT_BINDABLE_PIPELINE_IDS,numAvailablePipelines,pipeIds);
+
+ for (int i = 0; i < numAvailablePipelines; i++) {
+ if (pipeIds[i] != WFD_INVALID_PIPELINE_ID && !mDevice->isPipelineUsed(pipeIds[i])) {
+ mPipelineId = pipeIds[i];
+ mDevice-> addToUsedPipelineSet(mPipelineId,this);
+
+ mPipeline = wfdCreatePipeline(mDevice->handle(),mPipelineId,WFD_NONE);
+ if (mPipeline == WFD_INVALID_HANDLE) {
+ qFatal("Failed to create pipeline for port %p", this);
+ }
+ break;
+ }
+ }
+
+ if (mPipeline == WFD_INVALID_HANDLE) {
+ qWarning("Failed to create pipeline and cant bind it to port");
+ }
+
+ WFDint geomerty[] = { 0, 0, mPixelSize.width(), mPixelSize.height() };
+
+ wfdSetPipelineAttribiv(mDevice->handle(),mPipeline, WFD_PIPELINE_SOURCE_RECTANGLE, 4, geomerty);
+ wfdSetPipelineAttribiv(mDevice->handle(),mPipeline, WFD_PIPELINE_DESTINATION_RECTANGLE, 4, geomerty);
+
+ wfdBindPipelineToPort(mDevice->handle(),mPort,mPipeline);
+
+ mScreen = new QOpenWFDScreen(this);
+ mDevice->integration()->addScreen(mScreen);
+ mAttached = true;
+}
+
+void QOpenWFDPort::detach()
+{
+ if (!mAttached)
+ return;
+
+ mAttached = false;
+ mOn = false;
+
+ delete mScreen;
+
+ wfdDestroyPipeline(mDevice->handle(),mPipeline);
+ mPipelineId = WFD_INVALID_PIPELINE_ID;
+ mPipeline = WFD_INVALID_HANDLE;
+}
+
+bool QOpenWFDPort::attached() const
+{
+ return mAttached;
+}
+
+QSize QOpenWFDPort::setNativeResolutionMode()
+{
+ WFDint nativePixelSize[2];
+ wfdGetPortAttribiv(device()->handle(),mPort,WFD_PORT_NATIVE_RESOLUTION,2,nativePixelSize);
+ QSize nativeSize(nativePixelSize[0],nativePixelSize[1]);
+
+ for (int i = 0; i < mPortModes.size(); i++) {
+ const QOpenWFDPortMode &mode = mPortModes.at(i);
+ if (nativeSize == mode.size()) {
+ wfdSetPortMode(device()->handle(),mPort,mode.handle());
+ return nativeSize;
+ }
+ }
+ return QSize();
+}
+
+QSize QOpenWFDPort::pixelSize() const
+{
+ return mPixelSize;
+}
+
+QSizeF QOpenWFDPort::physicalSize() const
+{
+ return mPhysicalSize;
+}
+
+QOpenWFDDevice * QOpenWFDPort::device() const
+{
+ return mDevice;
+}
+
+WFDPort QOpenWFDPort::handle() const
+{
+ return mPort;
+}
+
+WFDint QOpenWFDPort::portId() const
+{
+ return mPortId;
+}
+
+WFDPipeline QOpenWFDPort::pipeline() const
+{
+ return mPipeline;
+}
+
+QOpenWFDScreen * QOpenWFDPort::screen() const
+{
+ return mScreen;
+}
diff --git a/src/plugins/platforms/openwfd/qopenwfdport.h b/src/plugins/platforms/openwfd/qopenwfdport.h
new file mode 100644
index 0000000000..497c43749e
--- /dev/null
+++ b/src/plugins/platforms/openwfd/qopenwfdport.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QOPENWFDPORT_H
+#define QOPENWFDPORT_H
+
+#include "qopenwfddevice.h"
+#include "qopenwfdportmode.h"
+
+#include <WF/wfd.h>
+
+class QOpenWFDPort
+{
+public:
+ QOpenWFDPort(QOpenWFDDevice *device, WFDint portEnumeration);
+ ~QOpenWFDPort();
+ void attach();
+ void detach();
+ bool attached() const;
+
+ QSize setNativeResolutionMode();
+
+ QSize pixelSize() const;
+ QSizeF physicalSize() const;
+
+ QOpenWFDDevice *device() const;
+ WFDPort handle() const;
+ WFDint portId() const;
+ WFDPipeline pipeline() const;
+ QOpenWFDScreen *screen() const;
+
+private:
+ QOpenWFDDevice *mDevice;
+ WFDPort mPort;
+ WFDint mPortId;
+
+ QList<QOpenWFDPortMode> mPortModes;
+
+ bool mAttached;
+ bool mOn;
+ QSize mPixelSize;
+ QSizeF mPhysicalSize;
+
+ QOpenWFDScreen *mScreen;
+
+ WFDint mPipelineId;
+ WFDPipeline mPipeline;
+
+};
+
+#endif // QOPENWFDPORT_H
diff --git a/src/plugins/platforms/openwfd/qopenwfdportmode.cpp b/src/plugins/platforms/openwfd/qopenwfdportmode.cpp
new file mode 100644
index 0000000000..4e507a42a1
--- /dev/null
+++ b/src/plugins/platforms/openwfd/qopenwfdportmode.cpp
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qopenwfdportmode.h"
+
+#include "qopenwfdport.h"
+
+QOpenWFDPortMode::QOpenWFDPortMode(QOpenWFDPort *port, WFDPortMode portMode)
+ : mPortMode(portMode)
+{
+ int width = wfdGetPortModeAttribi(port->device()->handle(),port->handle(),portMode,WFD_PORT_MODE_WIDTH);
+ int height = wfdGetPortModeAttribi(port->device()->handle(),port->handle(),portMode,WFD_PORT_MODE_HEIGHT);
+ mSize = QSize(width,height);
+
+ mRefresh = wfdGetPortModeAttribf(port->device()->handle(),port->handle(),portMode,WFD_PORT_MODE_REFRESH_RATE);
+ mFlipMirror = wfdGetPortModeAttribi(port->device()->handle(),port->handle(),portMode,WFD_PORT_MODE_FLIP_MIRROR_SUPPORT);
+ mInterlaced = wfdGetPortModeAttribi(port->device()->handle(), port->handle(),portMode,WFD_PORT_MODE_INTERLACED);
+}
+
+QDebug operator<<(QDebug s, const QOpenWFDPortMode &portMode)
+{
+ s.nospace() << "QOpenWFPortMode( " << portMode.size() << " Refreash: " << portMode.refreshRate()
+ << " FlipMirror: " << portMode.flipMirror() << " Interlaced: " << portMode.interlaced();
+ return s;
+}
diff --git a/src/plugins/platforms/openwfd/qopenwfdportmode.h b/src/plugins/platforms/openwfd/qopenwfdportmode.h
new file mode 100644
index 0000000000..dd95339404
--- /dev/null
+++ b/src/plugins/platforms/openwfd/qopenwfdportmode.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QOPENWFDPORTMODE_H
+#define QOPENWFDPORTMODE_H
+
+#include <WF/wfd.h>
+
+#include <QtCore/QSize>
+
+#include <QtCore/QDebug>
+
+class QOpenWFDPort;
+
+class QOpenWFDPortMode
+{
+public:
+ QOpenWFDPortMode(QOpenWFDPort *port, WFDPortMode portMode);
+
+ QSize size() const {return mSize;}
+ qreal refreshRate() const { return mRefresh; }
+ bool flipMirror() const { return mFlipMirror; }
+ bool interlaced() const { return mInterlaced; }
+
+ WFDPortMode handle() const { return mPortMode; }
+private:
+ WFDPortMode mPortMode;
+
+ QSize mSize;
+ qreal mRefresh;
+ bool mFlipMirror;
+ bool mInterlaced;
+};
+
+QDebug operator<<(QDebug, const QOpenWFDPortMode &);
+#endif // QOPENWFPORTMODE_H
diff --git a/src/plugins/platforms/openwfd/qopenwfdscreen.cpp b/src/plugins/platforms/openwfd/qopenwfdscreen.cpp
new file mode 100644
index 0000000000..785bee9c55
--- /dev/null
+++ b/src/plugins/platforms/openwfd/qopenwfdscreen.cpp
@@ -0,0 +1,192 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qopenwfdscreen.h"
+
+#include "qopenwfdport.h"
+#include "qopenwfdoutputbuffer.h"
+
+#include <QtGui/QGuiApplication>
+
+QOpenWFDScreen::QOpenWFDScreen(QOpenWFDPort *port)
+ : mPort(port)
+ , mFbo(0)
+ , mOutputBuffers(BUFFER_NUM)
+ , mCurrentRenderBufferIndex(0)
+ , mStagedBackBufferIndex(-1)
+ , mCommitedBackBufferIndex(-1)
+ , mBackBufferIndex(-1)
+{
+ printf ("\n");
+ printf ("Information of screen %p:\n", this);
+ printf (" width..........: %d\n", port->pixelSize().width());
+ printf (" height.........: %d\n", port->pixelSize().height());
+ printf (" physical width.: %f\n", port->physicalSize().width());
+ printf (" physical height: %f\n", port->physicalSize().height());
+ printf ("\n");
+
+ EGLDisplay display = mPort->device()->eglDisplay();
+ EGLContext context = mPort->device()->eglContext();
+
+ if (!eglMakeCurrent(display,EGL_NO_SURFACE,EGL_NO_SURFACE,context)) {
+ qDebug() << "screen: eglMakeCurrent FAILED";
+ }
+
+ glGenFramebuffers(1,&mFbo);
+ glBindFramebuffer(GL_FRAMEBUFFER,mFbo);
+
+ for (int i = 0; i < mOutputBuffers.size(); i++) {
+ mOutputBuffers[i] = new QOpenWFDOutputBuffer(mPort->pixelSize(),mPort);
+ }
+
+ mStagedBackBufferIndex = mOutputBuffers.size()-1;
+ mOutputBuffers[mStagedBackBufferIndex]->setAvailable(false);;
+ commitStagedOutputBuffer();
+
+ mOutputBuffers.at(mCurrentRenderBufferIndex)->bindToCurrentFbo();
+
+ if (mPort->device()->isDeviceInitializedAndCommited()) {
+ mPort->device()->commit(WFD_COMMIT_ENTIRE_PORT,mPort->handle());
+ }
+
+}
+
+QOpenWFDScreen::~QOpenWFDScreen()
+{
+ for (int i = 0; i < mOutputBuffers.size(); i++) {
+ delete mOutputBuffers[i];
+ }
+ glDeleteFramebuffers(1, &mFbo);
+}
+
+QRect QOpenWFDScreen::geometry() const
+{
+ return QRect(QPoint(),mPort->pixelSize());
+}
+
+int QOpenWFDScreen::depth() const
+{
+ return 32;
+}
+
+QImage::Format QOpenWFDScreen::format() const
+{
+ return QImage::Format_RGB32;
+}
+
+QSize QOpenWFDScreen::physicalSize() const
+{
+ return mPort->physicalSize().toSize();
+}
+
+QOpenWFDPort * QOpenWFDScreen::port() const
+{
+ return mPort;
+}
+
+void QOpenWFDScreen::swapBuffers()
+{
+ glFlush();
+
+ setStagedBackBuffer(mCurrentRenderBufferIndex);
+ mCurrentRenderBufferIndex = nextAvailableRenderBuffer();
+
+ bindFramebuffer();
+ mOutputBuffers.at(mCurrentRenderBufferIndex)->bindToCurrentFbo();
+}
+
+void QOpenWFDScreen::bindFramebuffer()
+{
+ glBindFramebuffer(GL_FRAMEBUFFER,mFbo);
+}
+
+void QOpenWFDScreen::setStagedBackBuffer(int bufferIndex)
+{
+ if (mStagedBackBufferIndex >= 0) {
+ mOutputBuffers[mStagedBackBufferIndex]->setAvailable(true);
+ }
+
+ mOutputBuffers[bufferIndex]->setAvailable(false);;
+ mStagedBackBufferIndex = bufferIndex;
+
+ if (mCommitedBackBufferIndex < 0) {
+ commitStagedOutputBuffer();
+ }
+}
+
+void QOpenWFDScreen::commitStagedOutputBuffer()
+{
+ Q_ASSERT(mStagedBackBufferIndex >= 0);
+ wfdBindSourceToPipeline(mPort->device()->handle(),
+ mPort->pipeline(),
+ mOutputBuffers.at(mStagedBackBufferIndex)->wfdSource(),
+ WFD_TRANSITION_AT_VSYNC,
+ 0);
+ mPort->device()->commit(WFD_COMMIT_PIPELINE,mPort->pipeline());
+ mCommitedBackBufferIndex = mStagedBackBufferIndex;
+ mStagedBackBufferIndex = -1;
+}
+
+int QOpenWFDScreen::nextAvailableRenderBuffer() const
+{
+ while (true) {
+ for (int i = 0; i < mOutputBuffers.size(); i++) {
+ if (mOutputBuffers.at(i)->isAvailable()) {
+ return i;
+ }
+ }
+ mPort->device()->waitForPipelineBindSourceCompleteEvent();
+ }
+}
+
+void QOpenWFDScreen::pipelineBindSourceComplete()
+{
+ if (mBackBufferIndex >= 0) {
+ mOutputBuffers[mBackBufferIndex]->setAvailable(true);
+ }
+
+ mBackBufferIndex = mCommitedBackBufferIndex;
+ mCommitedBackBufferIndex = -1;
+
+ if (mStagedBackBufferIndex >= 0) {
+ commitStagedOutputBuffer();
+ }
+}
diff --git a/src/plugins/platforms/openwfd/qopenwfdscreen.h b/src/plugins/platforms/openwfd/qopenwfdscreen.h
new file mode 100644
index 0000000000..bb23744ac4
--- /dev/null
+++ b/src/plugins/platforms/openwfd/qopenwfdscreen.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QOPENWFDSCREEN_H
+#define QOPENWFDSCREEN_H
+
+#include <QtGui/QPlatformScreen>
+
+
+#include "qopenwfdoutputbuffer.h"
+
+#include <WF/wfd.h>
+
+#include <QtCore/QVarLengthArray>
+#include <QtCore/QLinkedList>
+
+#define BUFFER_NUM 4
+
+class QOpenWFDPort;
+class QOpenWFDScreen : public QPlatformScreen
+{
+public:
+ QOpenWFDScreen(QOpenWFDPort *port);
+ ~QOpenWFDScreen();
+
+ QRect geometry() const;
+ int depth() const;
+ QImage::Format format() const;
+ QSize physicalSize() const;
+
+ QOpenWFDPort *port() const;
+
+ void swapBuffers();
+ void bindFramebuffer();
+ void pipelineBindSourceComplete();
+
+private:
+ void setStagedBackBuffer(int bufferIndex);
+ void commitStagedOutputBuffer();
+ int nextAvailableRenderBuffer() const;
+
+ QOpenWFDPort *mPort;
+
+ GLuint mFbo;
+
+ QVarLengthArray<QOpenWFDOutputBuffer *, BUFFER_NUM> mOutputBuffers;
+ int mCurrentRenderBufferIndex;
+ int mStagedBackBufferIndex;
+ int mCommitedBackBufferIndex;
+ int mBackBufferIndex;
+};
+
+#endif
diff --git a/src/plugins/platforms/openwfd/qopenwfdwindow.cpp b/src/plugins/platforms/openwfd/qopenwfdwindow.cpp
new file mode 100644
index 0000000000..15dc4b11c4
--- /dev/null
+++ b/src/plugins/platforms/openwfd/qopenwfdwindow.cpp
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qopenwfdwindow.h"
+
+#include "qopenwfdscreen.h"
+#include "QtGui/QWindowSystemInterface"
+
+QOpenWFDWindow::QOpenWFDWindow(QWindow *window)
+ : QPlatformWindow(window)
+{
+
+ QPlatformScreen *platformScreen = QPlatformScreen::platformScreenForWindow(window);
+ mPort = static_cast<QOpenWFDScreen *>(platformScreen)->port();
+
+ QWindowSystemInterface::handleGeometryChange(window,QRect(QPoint(0,0),mPort->screen()->geometry().size()));
+}
+
+QOpenWFDPort *QOpenWFDWindow::port() const
+{
+ return mPort;
+}
+
diff --git a/src/plugins/platforms/openwfd/qopenwfdwindow.h b/src/plugins/platforms/openwfd/qopenwfdwindow.h
new file mode 100644
index 0000000000..3c97b014b1
--- /dev/null
+++ b/src/plugins/platforms/openwfd/qopenwfdwindow.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QOPENWFDWINDOW_H
+#define QOPENWFDWINDOW_H
+
+#include <QtGui/QPlatformWindow>
+#include <QtCore/QVarLengthArray>
+
+#include "qopenwfdport.h"
+
+class QOpenWFDWindow : public QPlatformWindow
+{
+public:
+ QOpenWFDWindow(QWindow *window);
+
+ QOpenWFDPort *port() const;
+
+private:
+ QOpenWFDPort *mPort;
+};
+
+#endif // QOPENWFWINDOW_H
diff --git a/src/plugins/platforms/platforms.pro b/src/plugins/platforms/platforms.pro
index 492569796f..ac001b665b 100644
--- a/src/plugins/platforms/platforms.pro
+++ b/src/plugins/platforms/platforms.pro
@@ -9,3 +9,9 @@ contains(QT_CONFIG, wayland) {
contains(QT_CONFIG, xcb) {
SUBDIRS += xcb
}
+
+mac {
+ SUBDIRS += cocoa
+}
+
+win32: SUBDIRS += windows
diff --git a/src/plugins/platforms/qvfb/qvfb.pro b/src/plugins/platforms/qvfb/qvfb.pro
index 5db8533264..a95b13efc7 100644
--- a/src/plugins/platforms/qvfb/qvfb.pro
+++ b/src/plugins/platforms/qvfb/qvfb.pro
@@ -3,6 +3,7 @@ load(qt_plugin)
DESTDIR = $$QT.gui.plugins/platforms
+QT += core-private gui-private platformsupport-private
SOURCES = main.cpp qvfbintegration.cpp qvfbwindowsurface.cpp
HEADERS = qvfbintegration.h qvfbwindowsurface.h
diff --git a/src/plugins/platforms/qvfb/qvfbintegration.cpp b/src/plugins/platforms/qvfb/qvfbintegration.cpp
index 6b54420402..d4d8183936 100644
--- a/src/plugins/platforms/qvfb/qvfbintegration.cpp
+++ b/src/plugins/platforms/qvfb/qvfbintegration.cpp
@@ -63,6 +63,7 @@
#include <QWindowSystemInterface>
#include "qgenericunixfontdatabase.h"
+#include "qgenericunixeventdispatcher.h"
QT_BEGIN_NAMESPACE
@@ -422,9 +423,9 @@ QVFbIntegration::QVFbIntegration(const QStringList &paramList)
mScreens.append(mPrimaryScreen);
}
-QPixmapData *QVFbIntegration::createPixmapData(QPixmapData::PixelType type) const
+QPlatformPixmap *QVFbIntegration::createPlatformPixmap(QPlatformPixmap::PixelType type) const
{
- return new QRasterPixmapData(type);
+ return new QRasterPlatformPixmap(type);
}
QWindowSurface *QVFbIntegration::createWindowSurface(QWidget *widget, WId) const
@@ -438,6 +439,11 @@ QPlatformWindow *QVFbIntegration::createPlatformWindow(QWidget *widget, WId) con
return new QVFbWindow(mPrimaryScreen, widget);
}
+QAbstractEventDispatcher *QVFbIntegration::createEventDispatcher() const
+{
+ return createUnixEventDispatcher();
+}
+
QPlatformFontDatabase *QVFbIntegration::fontDatabase() const
{
return mFontDb;
diff --git a/src/plugins/platforms/qvfb/qvfbintegration.h b/src/plugins/platforms/qvfb/qvfbintegration.h
index ae3ba7bcc3..1c736c24e0 100644
--- a/src/plugins/platforms/qvfb/qvfbintegration.h
+++ b/src/plugins/platforms/qvfb/qvfbintegration.h
@@ -49,6 +49,7 @@ QT_BEGIN_NAMESPACE
class QVFbScreenPrivate;
+class QAbstractEventDispatcher;
class QVFbScreen : public QPlatformScreen
{
@@ -78,9 +79,10 @@ class QVFbIntegration : public QPlatformIntegration
public:
QVFbIntegration(const QStringList &paramList);
- QPixmapData *createPixmapData(QPixmapData::PixelType type) const;
+ QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const;
QPlatformWindow *createPlatformWindow(QWidget *widget, WId winId) const;
QWindowSurface *createWindowSurface(QWidget *widget, WId winId) const;
+ QAbstractEventDispatcher *createEventDispatcher() const;
QList<QPlatformScreen *> screens() const { return mScreens; }
diff --git a/src/plugins/platforms/uikit/quikitintegration.h b/src/plugins/platforms/uikit/quikitintegration.h
index 92247fdff3..b8a15b3807 100644
--- a/src/plugins/platforms/uikit/quikitintegration.h
+++ b/src/plugins/platforms/uikit/quikitintegration.h
@@ -52,7 +52,7 @@ public:
QUIKitIntegration();
~QUIKitIntegration();
- QPixmapData *createPixmapData(QPixmapData::PixelType type) const;
+ QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const;
QPlatformWindow *createPlatformWindow(QWidget *widget, WId winId = 0) const;
QWindowSurface *createWindowSurface(QWidget *widget, WId winId) const;
diff --git a/src/plugins/platforms/uikit/quikitintegration.mm b/src/plugins/platforms/uikit/quikitintegration.mm
index 737fa40d05..37ba2b9a02 100644
--- a/src/plugins/platforms/uikit/quikitintegration.mm
+++ b/src/plugins/platforms/uikit/quikitintegration.mm
@@ -64,9 +64,9 @@ QUIKitIntegration::~QUIKitIntegration()
{
}
-QPixmapData *QUIKitIntegration::createPixmapData(QPixmapData::PixelType type) const
+QPlatformPixmap *QUIKitIntegration::createPlatformPixmap(QPlatformPixmap::PixelType type) const
{
- return new QRasterPixmapData(type);
+ return new QRasterPlatformPixmap(type);
}
QPlatformWindow *QUIKitIntegration::createPlatformWindow(QWidget *widget, WId winId) const
diff --git a/src/plugins/platforms/uikit/quikitwindow.h b/src/plugins/platforms/uikit/quikitwindow.h
index c482dae3d5..67f0242a48 100644
--- a/src/plugins/platforms/uikit/quikitwindow.h
+++ b/src/plugins/platforms/uikit/quikitwindow.h
@@ -117,7 +117,7 @@ public:
UIWindow *ensureNativeWindow();
- QPlatformGLContext *glContext() const;
+ QPlatformOpenGLContext *glContext() const;
private:
QUIKitScreen *mScreen;
diff --git a/src/plugins/platforms/uikit/quikitwindow.mm b/src/plugins/platforms/uikit/quikitwindow.mm
index 29ca88b75a..cc17dbcbfb 100644
--- a/src/plugins/platforms/uikit/quikitwindow.mm
+++ b/src/plugins/platforms/uikit/quikitwindow.mm
@@ -48,12 +48,12 @@
#include <QtDebug>
#include <QtGui/QApplication>
#include <QtGui/QKeyEvent>
-#include <QtGui/QPlatformGLContext>
+#include <QtGui/QPlatformOpenGLContext>
#include <QtGui/QWindowSystemInterface>
#include <QtDebug>
-class EAGLPlatformContext : public QPlatformGLContext
+class EAGLPlatformContext : public QPlatformOpenGLContext
{
public:
EAGLPlatformContext(EAGLView *view)
@@ -91,13 +91,13 @@ public:
void makeCurrent()
{
- QPlatformGLContext::makeCurrent();
+ QPlatformOpenGLContext::makeCurrent();
[mView makeCurrent];
}
void doneCurrent()
{
- QPlatformGLContext::doneCurrent();
+ QPlatformOpenGLContext::doneCurrent();
}
void swapBuffers()
@@ -381,7 +381,7 @@ UIWindow *QUIKitWindow::ensureNativeWindow()
return mWindow;
}
-QPlatformGLContext *QUIKitWindow::glContext() const
+QPlatformOpenGLContext *QUIKitWindow::glContext() const
{
if (!mContext) {
mContext = new EAGLPlatformContext(mView);
diff --git a/src/plugins/platforms/uikit/uikit.pro b/src/plugins/platforms/uikit/uikit.pro
index 45a48dc92a..5e3a0e6b7c 100644
--- a/src/plugins/platforms/uikit/uikit.pro
+++ b/src/plugins/platforms/uikit/uikit.pro
@@ -1,5 +1,5 @@
TARGET = quikit
-load(qt_plugin)
+load(qpa/plugin)
QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/platforms
QT += opengl
@@ -22,6 +22,6 @@ HEADERS = quikitsoftwareinputhandler.h
#add libz for freetype.
LIBS += -lz
-#include(../fontdatabases/basicunix/basicunix.pri)
+#load(qpa/fontdatabases/basicunix)
target.path += $$[QT_INSTALL_PLUGINS]/platforms
INSTALLS += target
diff --git a/src/plugins/platforms/vnc/qvncintegration.cpp b/src/plugins/platforms/vnc/qvncintegration.cpp
index 1e8c6c1bc5..7506bff307 100644
--- a/src/plugins/platforms/vnc/qvncintegration.cpp
+++ b/src/plugins/platforms/vnc/qvncintegration.cpp
@@ -161,9 +161,9 @@ bool QVNCIntegration::hasCapability(QPlatformIntegration::Capability cap) const
}
-QPixmapData *QVNCIntegration::createPixmapData(QPixmapData::PixelType type) const
+QPlatformPixmap *QVNCIntegration::createPlatformPixmap(QPlatformPixmap::PixelType type) const
{
- return new QRasterPixmapData(type);
+ return new QRasterPlatformPixmap(type);
}
QWindowSurface *QVNCIntegration::createWindowSurface(QWidget *widget, WId) const
@@ -173,6 +173,10 @@ QWindowSurface *QVNCIntegration::createWindowSurface(QWidget *widget, WId) const
return surface;
}
+QAbstractEventDispatcher *QVFbIntegration::createEventDispatcher() const
+{
+ return createUnixEventDispatcher();
+}
QPlatformWindow *QVNCIntegration::createPlatformWindow(QWidget *widget, WId /*winId*/) const
{
diff --git a/src/plugins/platforms/vnc/qvncintegration.h b/src/plugins/platforms/vnc/qvncintegration.h
index 3e13bc3b8d..9787a59f0f 100644
--- a/src/plugins/platforms/vnc/qvncintegration.h
+++ b/src/plugins/platforms/vnc/qvncintegration.h
@@ -74,7 +74,7 @@ private:
};
class QVNCIntegrationPrivate;
-
+class QAbstractEventDispatcher;
class QVNCIntegration : public QPlatformIntegration
{
@@ -82,9 +82,10 @@ public:
QVNCIntegration(const QStringList& paramList);
bool hasCapability(QPlatformIntegration::Capability cap) const;
- QPixmapData *createPixmapData(QPixmapData::PixelType type) const;
+ QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const;
QPlatformWindow *createPlatformWindow(QWidget *widget, WId winId) const;
QWindowSurface *createWindowSurface(QWidget *widget, WId winId) const;
+ QAbstractEventDispatcher createEventDispatcher() const;
QPixmap grabWindow(WId window, int x, int y, int width, int height) const;
diff --git a/src/plugins/platforms/vnc/qvncserver.cpp b/src/plugins/platforms/vnc/qvncserver.cpp
index 8b25e054d1..37412b6bd1 100644
--- a/src/plugins/platforms/vnc/qvncserver.cpp
+++ b/src/plugins/platforms/vnc/qvncserver.cpp
@@ -43,7 +43,7 @@
#include <QtCore/qtimer.h>
#include <QtCore/qregexp.h>
-#include <QtGui/qwidget.h>
+#include <QtWidgets/qwidget.h>
#include <QtGui/qpolygon.h>
#include <QtGui/qpainter.h>
diff --git a/src/plugins/platforms/vnc/vnc.pro b/src/plugins/platforms/vnc/vnc.pro
index 85bffb0637..321cee4790 100644
--- a/src/plugins/platforms/vnc/vnc.pro
+++ b/src/plugins/platforms/vnc/vnc.pro
@@ -1,7 +1,7 @@
TARGET = qvncgraphicssystem
load(qt_plugin)
-QT += network
+QT += network core-private gui-private platformsupport-private
DESTDIR = $$QT.gui.plugins/platforms
diff --git a/src/plugins/platforms/wayland/gl_integration/gl_integration.pri b/src/plugins/platforms/wayland/gl_integration/gl_integration.pri
index d9b5fa9bff..20c3aa0bd9 100644
--- a/src/plugins/platforms/wayland/gl_integration/gl_integration.pri
+++ b/src/plugins/platforms/wayland/gl_integration/gl_integration.pri
@@ -3,12 +3,10 @@ contains(QT_CONFIG, opengl) {
QT += opengl
HEADERS += \
- $$PWD/qwaylandglintegration.h \
- $$PWD/qwaylandglwindowsurface.h
+ $$PWD/qwaylandglintegration.h
SOURCES += \
- $$PWD/qwaylandglintegration.cpp \
- $$PWD/qwaylandglwindowsurface.cpp
+ $$PWD/qwaylandglintegration.cpp
QT_WAYLAND_GL_CONFIG = $$(QT_WAYLAND_GL_CONFIG)
contains(QT_CONFIG, opengles2) {
@@ -22,6 +20,9 @@ SOURCES += \
QT_WAYLAND_GL_INTEGRATION = xcomposite_egl
CONFIG += xcomposite_egl
}
+ } else:mac {
+ QT_WAYLAND_GL_INTEGRATION = readback_cgl
+ CONFIG += readback_cgl
} else {
isEqual(QT_WAYLAND_GL_CONFIG, readback) {
QT_WAYLAND_GL_INTEGRATION = readback_glx
@@ -48,6 +49,10 @@ readback_glx {
include ($$PWD/readback_glx/readback_glx.pri)
}
+readback_cgl {
+ include ($$PWD/readback_cgl/readback_cgl.pri)
+}
+
xcomposite_glx {
include ($$PWD/xcomposite_glx/xcomposite_glx.pri)
}
diff --git a/src/plugins/platforms/wayland/gl_integration/qwaylandglintegration.h b/src/plugins/platforms/wayland/gl_integration/qwaylandglintegration.h
index 4b50b4bd68..4f688e41d8 100644
--- a/src/plugins/platforms/wayland/gl_integration/qwaylandglintegration.h
+++ b/src/plugins/platforms/wayland/gl_integration/qwaylandglintegration.h
@@ -44,7 +44,10 @@
class QWaylandWindow;
class QWaylandDisplay;
-class QWidget;
+class QWindow;
+
+class QPlatformOpenGLContext;
+class QSurfaceFormat;
class QWaylandGLIntegration
{
@@ -54,7 +57,8 @@ public:
virtual void initialize() = 0;
- virtual QWaylandWindow *createEglWindow(QWidget *widget) = 0;
+ virtual QWaylandWindow *createEglWindow(QWindow *window) = 0;
+ virtual QPlatformOpenGLContext *createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const = 0;
static QWaylandGLIntegration *createGLIntegration(QWaylandDisplay *waylandDisplay);
};
diff --git a/src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.cpp b/src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.cpp
deleted file mode 100644
index fef07e6bf7..0000000000
--- a/src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.cpp
+++ /dev/null
@@ -1,184 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qwaylandglwindowsurface.h"
-
-#include "qwaylanddisplay.h"
-#include "qwaylandwindow.h"
-#include "qwaylandscreen.h"
-
-#include <QtOpenGL/QGLFramebufferObject>
-#include <QtOpenGL/QGLContext>
-
-#include <QtOpenGL/private/qglengineshadermanager_p.h>
-
-QT_BEGIN_NAMESPACE
-
-static void drawTexture(const QRectF &rect, GLuint tex_id, const QSize &texSize, const QRectF &br)
-{
-#if !defined(QT_OPENGL_ES_2)
- QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext());
-#endif
- const GLenum target = GL_TEXTURE_2D;
- QRectF src = br.isEmpty()
- ? QRectF(QPointF(), texSize)
- : QRectF(QPointF(br.x(), texSize.height() - br.bottom()), br.size());
-
- if (target == GL_TEXTURE_2D) {
- qreal width = texSize.width();
- qreal height = texSize.height();
-
- src.setLeft(src.left() / width);
- src.setRight(src.right() / width);
- src.setTop(src.top() / height);
- src.setBottom(src.bottom() / height);
- }
-
- const GLfloat tx1 = src.left();
- const GLfloat tx2 = src.right();
- const GLfloat ty1 = src.top();
- const GLfloat ty2 = src.bottom();
-
- GLfloat texCoordArray[4*2] = {
- tx1, ty2, tx2, ty2, tx2, ty1, tx1, ty1
- };
-
- GLfloat vertexArray[4*2];
- vertexArray[0] = rect.left(); vertexArray[1] = rect.top();
- vertexArray[2] = rect.right(); vertexArray[3] = rect.top();
- vertexArray[4] = rect.right(); vertexArray[5] = rect.bottom();
- vertexArray[6] = rect.left(); vertexArray[7] = rect.bottom();
-
- glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, vertexArray);
- glVertexAttribPointer(QT_TEXTURE_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, texCoordArray);
-
- glBindTexture(target, tex_id);
-
- glEnableVertexAttribArray(QT_VERTEX_COORDS_ATTR);
- glEnableVertexAttribArray(QT_TEXTURE_COORDS_ATTR);
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- glDisableVertexAttribArray(QT_VERTEX_COORDS_ATTR);
- glDisableVertexAttribArray(QT_TEXTURE_COORDS_ATTR);
-
- glBindTexture(target, 0);
-}
-
-static void blitTexture(QGLContext *ctx, GLuint texture, const QSize &viewport, const QSize &texSize, const QRect &targetRect, const QRect &sourceRect)
-{
- glDisable(GL_DEPTH_TEST);
- glDisable(GL_SCISSOR_TEST);
- glDisable(GL_BLEND);
- glViewport(0, 0, viewport.width(), viewport.height());
-
- QGLShaderProgram *blitProgram =
- QGLEngineSharedShaders::shadersForContext(ctx)->blitProgram();
- blitProgram->bind();
- blitProgram->setUniformValue("imageTexture", 0 /*QT_IMAGE_TEXTURE_UNIT*/);
-
- // The shader manager's blit program does not multiply the
- // vertices by the pmv matrix, so we need to do the effect
- // of the orthographic projection here ourselves.
- QRectF r;
- qreal w = viewport.width();
- qreal h = viewport.height();
- r.setLeft((targetRect.left() / w) * 2.0f - 1.0f);
- if (targetRect.right() == (viewport.width() - 1))
- r.setRight(1.0f);
- else
- r.setRight((targetRect.right() / w) * 2.0f - 1.0f);
- r.setBottom((targetRect.top() / h) * 2.0f - 1.0f);
- if (targetRect.bottom() == (viewport.height() - 1))
- r.setTop(1.0f);
- else
- r.setTop((targetRect.bottom() / w) * 2.0f - 1.0f);
-
- drawTexture(r, texture, texSize, sourceRect);
-}
-
-QWaylandGLWindowSurface::QWaylandGLWindowSurface(QWidget *window)
- : QWindowSurface(window)
- , mDisplay(QWaylandScreen::waylandScreenFromWidget(window)->display())
- , mPaintDevice(0)
-{
-
-}
-
-QWaylandGLWindowSurface::~QWaylandGLWindowSurface()
-{
- delete mPaintDevice;
-}
-
-QPaintDevice *QWaylandGLWindowSurface::paintDevice()
-{
- return mPaintDevice;
-}
-
-void QWaylandGLWindowSurface::beginPaint(const QRegion &)
-{
- window()->platformWindow()->glContext()->makeCurrent();
- glClearColor(0,0,0,0xff);
- glClear(GL_COLOR_BUFFER_BIT);
-}
-
-void QWaylandGLWindowSurface::flush(QWidget *widget, const QRegion &region, const QPoint &offset)
-{
- Q_UNUSED(offset);
- Q_UNUSED(region);
- QWaylandWindow *ww = (QWaylandWindow *) widget->platformWindow();
-
- if (mPaintDevice->isBound())
- mPaintDevice->release();
-
- QRect rect(0,0,size().width(),size().height());
- QGLContext *ctx = QGLContext::fromPlatformGLContext(ww->glContext());
- blitTexture(ctx,mPaintDevice->texture(),size(),mPaintDevice->size(),rect,rect);
- ww->glContext()->swapBuffers();
-}
-
-void QWaylandGLWindowSurface::resize(const QSize &size)
-{
- QWindowSurface::resize(size);
- window()->platformWindow()->glContext()->makeCurrent();
- delete mPaintDevice;
- mPaintDevice = new QGLFramebufferObject(size,QGLFramebufferObject::CombinedDepthStencil);
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.h b/src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.h
deleted file mode 100644
index 00da6976b8..0000000000
--- a/src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWAYLANDDRMSURFACE_H
-#define QWAYLANDDRMSURFACE_H
-
-#include "qwaylanddisplay.h"
-
-#include <QtGui/private/qwindowsurface_p.h>
-
-class QGLFramebufferObject;
-
-class QWaylandGLWindowSurface : public QWindowSurface
-{
-public:
- QWaylandGLWindowSurface(QWidget *window);
- ~QWaylandGLWindowSurface();
-
- void beginPaint(const QRegion &);
-
- QPaintDevice *paintDevice();
- void flush(QWidget *widget, const QRegion &region, const QPoint &offset);
-
- void resize(const QSize &size);
-
-private:
- QWaylandDisplay *mDisplay;
- QGLFramebufferObject *mPaintDevice;
-};
-
-#endif // QWAYLANDDRMSURFACE_H
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglcontext.cpp b/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglcontext.cpp
new file mode 100644
index 0000000000..5f7663ef55
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglcontext.cpp
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwaylandreadbackcglcontext.h"
+
+#include "qwaylandshmbackingstore.h"
+#include "qwaylandreadbackcglwindow.h"
+
+#include <QtGui/QOpenGLContext>
+#include <QtCore/QDebug>
+
+#include <OpenGL/OpenGL.h>
+#include <OpenGL/glext.h>
+#include <OpenGL/glu.h>
+
+#include <QtPlatformSupport/private/cglconvenience_p.h>
+
+QWaylandReadbackCGLContext::QWaylandReadbackCGLContext(QPlatformOpenGLContext *share)
+ : QPlatformOpenGLContext()
+{
+ Q_UNUSED(share);
+ m_glContext = qcgl_createGlContext();
+}
+
+QSurfaceFormat QWaylandReadbackCGLContext::format() const
+{
+ return qcgl_surfaceFormat();
+}
+
+bool QWaylandReadbackCGLContext::makeCurrent(QPlatformSurface *surface)
+{
+ QWaylandReadbackCGLWindow *window = static_cast<QWaylandReadbackCGLWindow *>(surface);
+ CGLSetPBuffer(m_glContext, window->pixelBuffer(), 0, 0, 0);
+ CGLSetCurrentContext(m_glContext);
+ return true;
+}
+
+void QWaylandReadbackCGLContext::doneCurrent()
+{
+ CGLSetCurrentContext(0);
+}
+
+void QWaylandReadbackCGLContext::swapBuffers(QPlatformSurface *surface)
+{
+ Q_UNUSED(surface);
+
+ if (QOpenGLContext::currentContext()->handle() != this) {
+ makeCurrent(surface);
+ }
+ CGLFlushDrawable(m_glContext);
+
+ QWaylandReadbackCGLWindow *window = static_cast<QWaylandReadbackCGLWindow *>(surface);
+ QSize size = window->geometry().size();
+
+ uchar *dstBits = const_cast<uchar *>(window->buffer());
+ glReadPixels(0,0, size.width(), size.height(), GL_BGRA,GL_UNSIGNED_BYTE, dstBits);
+
+ window->damage(QRect(QPoint(0,0),size));
+
+ // ### Should sync here but this call deadlocks with the server.
+ //window->waitForFrameSync();
+}
+
+void (*QWaylandReadbackCGLContext::getProcAddress(const QByteArray &procName)) ()
+{
+ return qcgl_getProcAddress(procName);
+}
+
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglcontext.h b/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglcontext.h
new file mode 100644
index 0000000000..eb065c3f69
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglcontext.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDREADBACKCGLCONTEXT_H
+#define QWAYLANDREADBACKCGLCONTEXT_H
+
+#include <QPlatformOpenGLContext>
+
+#include "qwaylandreadbackcglintegration.h"
+
+#include <OpenGL/OpenGL.h>
+
+class QWaylandReadbackCGLWindow;
+class QWaylandShmBuffer;
+
+class QWaylandReadbackCGLContext : public QPlatformOpenGLContext
+{
+public:
+ QWaylandReadbackCGLContext(QPlatformOpenGLContext *share);
+
+ QSurfaceFormat format() const;
+
+ bool makeCurrent(QPlatformSurface *surface);
+ void doneCurrent();
+ void swapBuffers(QPlatformSurface *surface);
+ void (*getProcAddress(const QByteArray &procName)) ();
+
+ void geometryChanged();
+
+private:
+ CGLContextObj m_glContext;
+};
+
+#endif // QWAYLANDREADBACKCGLCONTEXT_H
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglintegration.cpp b/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglintegration.cpp
new file mode 100644
index 0000000000..2878f9e292
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglintegration.cpp
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwaylandreadbackcglintegration.h"
+#include "qwaylandreadbackcglcontext.h"
+#include "qwaylandreadbackcglwindow.h"
+
+#include <QtCore/QDebug>
+
+QWaylandGLIntegration * QWaylandGLIntegration::createGLIntegration(QWaylandDisplay *waylandDisplay)
+{
+ return new QWaylandReadbackCGLIntegration(waylandDisplay);
+}
+
+QWaylandReadbackCGLIntegration::QWaylandReadbackCGLIntegration(QWaylandDisplay * waylandDispaly)
+ : QWaylandGLIntegration()
+ , mWaylandDisplay(waylandDispaly)
+{
+ qDebug() << "Using Readback-CGL";
+}
+
+QWaylandReadbackCGLIntegration::~QWaylandReadbackCGLIntegration()
+{
+
+}
+
+void QWaylandReadbackCGLIntegration::initialize()
+{
+}
+
+QWaylandWindow * QWaylandReadbackCGLIntegration::createEglWindow(QWindow *window)
+{
+ return new QWaylandReadbackCGLWindow(window,this);
+}
+
+QPlatformOpenGLContext *QWaylandReadbackCGLIntegration::createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const
+{
+ return new QWaylandReadbackCGLContext(share);
+}
+
+QWaylandDisplay * QWaylandReadbackCGLIntegration::waylandDisplay() const
+{
+ return mWaylandDisplay;
+}
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglintegration.h b/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglintegration.h
new file mode 100644
index 0000000000..34c8d00a7c
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglintegration.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDREADBACKGLXINTEGRATION_H
+#define QWAYLANDREADBACKGLXINTEGRATION_H
+
+#include "gl_integration/qwaylandglintegration.h"
+
+#include <QtCore/QTextStream>
+#include <QtCore/QDataStream>
+#include <QtCore/QMetaType>
+#include <QtCore/QVariant>
+#include <QtGui/QWindow>
+
+#include <X11/Xlib.h>
+
+class QWaylandReadbackCGLIntegration : public QWaylandGLIntegration
+{
+public:
+ QWaylandReadbackCGLIntegration(QWaylandDisplay * waylandDispaly);
+ ~QWaylandReadbackCGLIntegration();
+
+ void initialize();
+
+ QWaylandWindow *createEglWindow(QWindow *window);
+ QPlatformOpenGLContext *createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const;
+ QWaylandDisplay *waylandDisplay() const;
+
+private:
+ QWaylandDisplay *mWaylandDisplay;
+};
+
+#endif // QWAYLANDREADBACKGLXINTEGRATION_H
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglwindow.cpp b/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglwindow.cpp
new file mode 100644
index 0000000000..9e7f8520c9
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglwindow.cpp
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwaylandreadbackcglwindow.h"
+#include "qwaylandshmbackingstore.h"
+
+#include <OpenGL/OpenGL.h>
+#include <OpenGL/glext.h>
+
+QWaylandReadbackCGLWindow::QWaylandReadbackCGLWindow(QWindow *window, QWaylandReadbackCGLIntegration *cglIntegration)
+ : QWaylandShmWindow(window)
+ , m_CglIntegration(cglIntegration)
+ , mContext(0)
+ , m_buffer(0)
+ , m_pixelBuffer(0)
+{
+}
+
+QWaylandWindow::WindowType QWaylandReadbackCGLWindow::windowType() const
+{
+ //yeah. this type needs a new name
+ return QWaylandWindow::Egl;
+}
+
+
+void QWaylandReadbackCGLWindow::setGeometry(const QRect &rect)
+{
+ QWaylandShmWindow::setGeometry(rect);
+
+ if (m_buffer) {
+ delete m_buffer;
+ m_buffer = 0;
+
+ CGLDestroyPBuffer(m_pixelBuffer);
+ m_pixelBuffer = 0;
+ }
+}
+
+CGLPBufferObj QWaylandReadbackCGLWindow::pixelBuffer()
+{
+ if (!m_pixelBuffer)
+ createSurface();
+
+ return m_pixelBuffer;
+}
+
+uchar *QWaylandReadbackCGLWindow::buffer()
+{
+ return m_buffer->image()->bits();
+}
+
+void QWaylandReadbackCGLWindow::createSurface()
+{
+ QSize size(geometry().size());
+ if (size.isEmpty()) {
+ //QGLWidget wants a context for a window without geometry
+ size = QSize(1,1);
+ }
+
+ waitForFrameSync();
+
+ CGLCreatePBuffer(size.width(), size.height(), GL_TEXTURE_RECTANGLE_ARB, GL_BGRA, 0, &m_pixelBuffer);
+
+ delete m_buffer;
+ m_buffer = new QWaylandShmBuffer(m_CglIntegration->waylandDisplay(),size,QImage::Format_ARGB32);
+ attach(m_buffer);
+}
+
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglwindow.h b/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglwindow.h
new file mode 100644
index 0000000000..0598cf9037
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglwindow.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDREADBACKGLXWINDOW_H
+#define QWAYLANDREADBACKGLXWINDOW_H
+
+#include "qwaylandshmwindow.h"
+#include "qwaylandreadbackcglintegration.h"
+#include "qwaylandreadbackcglcontext.h"
+
+#include <OpenGL/OpenGL.h>
+
+class QWaylandReadbackCGLWindow : public QWaylandShmWindow
+{
+public:
+ QWaylandReadbackCGLWindow(QWindow *window, QWaylandReadbackCGLIntegration *cglIntegration);
+ WindowType windowType() const;
+
+ void setGeometry(const QRect &rect);
+ CGLPBufferObj pixelBuffer();
+ uchar *buffer();
+private:
+ void createSurface();
+
+ QWaylandReadbackCGLIntegration *m_CglIntegration;
+ QWaylandReadbackCGLContext *mContext;
+
+ QWaylandShmBuffer *m_buffer;
+ CGLPBufferObj m_pixelBuffer;
+};
+
+#endif // QWAYLANDREADBACKGLXWINDOW_H
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_cgl/readback_cgl.pri b/src/plugins/platforms/wayland/gl_integration/readback_cgl/readback_cgl.pri
new file mode 100644
index 0000000000..91cb90a30c
--- /dev/null
+++ b/src/plugins/platforms/wayland/gl_integration/readback_cgl/readback_cgl.pri
@@ -0,0 +1,10 @@
+HEADERS += \
+ $$PWD/qwaylandreadbackcglintegration.h \
+ $$PWD/qwaylandreadbackcglwindow.h \
+ $$PWD/qwaylandreadbackcglcontext.h
+
+SOURCES += \
+ $$PWD/qwaylandreadbackcglintegration.cpp \
+ $$PWD/qwaylandreadbackcglwindow.cpp \
+ $$PWD/qwaylandreadbackcglcontext.cpp
+
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.cpp b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.cpp
index f02a10a05b..c03e8a9444 100644
--- a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.cpp
+++ b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.cpp
@@ -41,14 +41,16 @@
#include "qwaylandreadbackeglcontext.h"
-#include "../../../eglconvenience/qeglconvenience.h"
+#include <QPlatformSupport/eglconvenience/qeglconvenience_p.h>
+
+#include <QtCore/QDebug>
+#include <QtGui/QWindowContext>
#include <QtOpenGL/QGLContext>
#include <QtOpenGL/private/qglextensions_p.h>
#include "qwaylandshmsurface.h"
-#include <QtCore/QDebug>
static inline void qgl_byteSwapImage(QImage &img, GLenum pixel_type)
{
@@ -77,7 +79,7 @@ QWaylandReadbackEglContext::QWaylandReadbackEglContext(QWaylandReadbackEglIntegr
, mWindow(window)
, mBuffer(0)
, mPixmap(0)
- , mConfig(q_configFromQPlatformWindowFormat(eglIntegration->eglDisplay(),window->widget()->platformWindowFormat(),true,EGL_PIXMAP_BIT))
+ , mConfig(q_configFromQWindowFormat(eglIntegration->eglDisplay(),window->window()->requestedWindowFormat(),true,EGL_PIXMAP_BIT))
, mPixmapSurface(EGL_NO_SURFACE)
{
QVector<EGLint> eglContextAttrs;
@@ -97,8 +99,6 @@ QWaylandReadbackEglContext::~QWaylandReadbackEglContext()
void QWaylandReadbackEglContext::makeCurrent()
{
- QPlatformGLContext::makeCurrent();
-
mWindow->waitForFrameSync();
eglMakeCurrent(mEglIntegration->eglDisplay(),mPixmapSurface,mPixmapSurface,mContext);
@@ -106,7 +106,7 @@ void QWaylandReadbackEglContext::makeCurrent()
void QWaylandReadbackEglContext::doneCurrent()
{
- QPlatformGLContext::doneCurrent();
+ QPlatformOpenGLContext::doneCurrent();
eglMakeCurrent(mEglIntegration->eglDisplay(),EGL_NO_SURFACE,EGL_NO_SURFACE,EGL_NO_CONTEXT);
}
@@ -114,7 +114,7 @@ void QWaylandReadbackEglContext::swapBuffers()
{
eglSwapBuffers(mEglIntegration->eglDisplay(),mPixmapSurface);
- if (QPlatformGLContext::currentContext() != this) {
+ if (QWindowContext::currentContext()->handle() != this) {
makeCurrent();
}
@@ -143,9 +143,9 @@ void * QWaylandReadbackEglContext::getProcAddress(const QString &procName)
return (void *) eglGetProcAddress(procName.toLatin1().data());
}
-QPlatformWindowFormat QWaylandReadbackEglContext::platformWindowFormat() const
+QWindowFormat QWaylandReadbackEglContext::windowFormat() const
{
- return qt_qPlatformWindowFormatFromConfig(mEglIntegration->eglDisplay(),mConfig);
+ return q_windowFormatFromConfig(mEglIntegration->eglDisplay(),mConfig);
}
void QWaylandReadbackEglContext::geometryChanged()
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.h b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.h
index f9ab3783dd..75755fbd1a 100644
--- a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.h
+++ b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.h
@@ -42,15 +42,14 @@
#ifndef QWAYLANDREADBACKEGLGLCONTEXT_H
#define QWAYLANDREADBACKEGLGLCONTEXT_H
-#include <QPlatformGLContext>
-#include <QtGui/QWidget>
+#include <QPlatformOpenGLContext>
#include "qwaylandreadbackeglintegration.h"
#include "qwaylandreadbackeglwindow.h"
class QWaylandShmBuffer;
-class QWaylandReadbackEglContext : public QPlatformGLContext
+class QWaylandReadbackEglContext : public QPlatformOpenGLContext
{
public:
QWaylandReadbackEglContext(QWaylandReadbackEglIntegration *eglIntegration, QWaylandReadbackEglWindow *window);
@@ -61,7 +60,7 @@ public:
void swapBuffers();
void* getProcAddress(const QString& procName);
- virtual QPlatformWindowFormat platformWindowFormat() const;
+ virtual QWindowFormat windowFormat() const;
void geometryChanged();
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.cpp b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.cpp
index 6bbac603cf..39fa3d589c 100644
--- a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.cpp
+++ b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.cpp
@@ -81,9 +81,14 @@ void QWaylandReadbackEglIntegration::initialize()
}
}
-QWaylandWindow * QWaylandReadbackEglIntegration::createEglWindow(QWidget *widget)
+QWaylandWindow * QWaylandReadbackEglIntegration::createEglWindow(QWindow *window)
{
- return new QWaylandReadbackEglWindow(widget,this);
+ return new QWaylandReadbackEglWindow(window, this);
+}
+
+QPlatformOpenGLContext *QWaylandReadbackEglWindow::createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const
+{
+ return new QWaylandReadbackEglContext(glFormat, share, this);
}
EGLDisplay QWaylandReadbackEglIntegration::eglDisplay()
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.h b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.h
index ae1e8e5095..0d6aa55e4e 100644
--- a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.h
+++ b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.h
@@ -48,7 +48,8 @@
#include <QtCore/QDataStream>
#include <QtCore/QMetaType>
#include <QtCore/QVariant>
-#include <QtGui/QWidget>
+#include <QtCore/QEvent>
+#include <QtGui/QCursor>
#include <X11/Xlib.h>
@@ -61,7 +62,8 @@ public:
~QWaylandReadbackEglIntegration();
void initialize();
- QWaylandWindow *createEglWindow(QWidget *widget);
+ QWaylandWindow *createEglWindow(QWindow *window);
+ QPlatformOpenGLContext *createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const;
QWaylandDisplay *waylandDisplay() const;
Display *xDisplay() const;
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.cpp b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.cpp
index 868e32e030..f4bc6379d6 100644
--- a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.cpp
+++ b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.cpp
@@ -43,7 +43,7 @@
#include "qwaylandreadbackeglcontext.h"
-QWaylandReadbackEglWindow::QWaylandReadbackEglWindow(QWidget *window, QWaylandReadbackEglIntegration *eglIntegration)
+QWaylandReadbackEglWindow::QWaylandReadbackEglWindow(QWindow *window, QWaylandReadbackEglIntegration *eglIntegration)
: QWaylandShmWindow(window)
, mEglIntegration(eglIntegration)
, mContext(0)
@@ -57,7 +57,7 @@ QWaylandWindow::WindowType QWaylandReadbackEglWindow::windowType() const
return QWaylandWindow::Egl;
}
-QPlatformGLContext *QWaylandReadbackEglWindow::glContext() const
+QPlatformOpenGLContext *QWaylandReadbackEglWindow::glContext() const
{
if (!mContext) {
QWaylandReadbackEglWindow *that = const_cast<QWaylandReadbackEglWindow *>(this);
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.h b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.h
index 1433483923..0852a8ee66 100644
--- a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.h
+++ b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.h
@@ -50,11 +50,11 @@ class QWaylandReadbackEglContext;
class QWaylandReadbackEglWindow : public QWaylandShmWindow
{
public:
- QWaylandReadbackEglWindow(QWidget *window, QWaylandReadbackEglIntegration *eglIntegration);
+ QWaylandReadbackEglWindow(QWindow *window, QWaylandReadbackEglIntegration *eglIntegration);
WindowType windowType() const;
- QPlatformGLContext *glContext() const;
+ QPlatformOpenGLContext *glContext() const;
void setGeometry(const QRect &rect);
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_egl/readback_egl.pri b/src/plugins/platforms/wayland/gl_integration/readback_egl/readback_egl.pri
index 0d8e01b6bb..3325fe8ec9 100644
--- a/src/plugins/platforms/wayland/gl_integration/readback_egl/readback_egl.pri
+++ b/src/plugins/platforms/wayland/gl_integration/readback_egl/readback_egl.pri
@@ -1,14 +1,12 @@
-
LIBS += -lX11 -lXext -lEGL
+load(qpa/egl/convenience)
HEADERS += \
$$PWD/qwaylandreadbackeglintegration.h \
$$PWD/qwaylandreadbackeglcontext.h \
$$PWD/qwaylandreadbackeglwindow.h \
- $$PWD/../../../eglconvenience/qeglconvenience.h
SOURCES += \
$$PWD/qwaylandreadbackeglintegration.cpp \
$$PWD/qwaylandreadbackeglwindow.cpp \
$$PWD/qwaylandreadbackeglcontext.cpp \
- $$PWD/../../../eglconvenience/qeglconvenience.cpp
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.cpp b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.cpp
index 857c1db6e3..850e7bb0ac 100644
--- a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.cpp
+++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.cpp
@@ -41,9 +41,10 @@
#include "qwaylandreadbackglxcontext.h"
-#include "qwaylandshmsurface.h"
+#include "qwaylandshmbackingstore.h"
#include "qwaylandreadbackglxwindow.h"
+#include <QtGui/QOpenGLContext>
#include <QtCore/QDebug>
static inline void qgl_byteSwapImage(QImage &img, GLenum pixel_type)
@@ -68,96 +69,66 @@ static inline void qgl_byteSwapImage(QImage &img, GLenum pixel_type)
}
}
-QWaylandReadbackGlxContext::QWaylandReadbackGlxContext(QWaylandReadbackGlxIntegration *glxIntegration, QWaylandReadbackGlxWindow *window)
- : QPlatformGLContext()
- , mGlxIntegration(glxIntegration)
- , mWindow(window)
- , mBuffer(0)
- , mPixmap(0)
- , mConfig(qglx_findConfig(glxIntegration->xDisplay(),glxIntegration->screen(),window->widget()->platformWindowFormat(),GLX_PIXMAP_BIT))
- , mGlxPixmap(0)
+QWaylandReadbackGlxContext::QWaylandReadbackGlxContext(const QSurfaceFormat &format,
+ QPlatformOpenGLContext *share, Display *display, int screen)
+ : m_display(display)
{
- XVisualInfo *visualInfo = glXGetVisualFromFBConfig(glxIntegration->xDisplay(),mConfig);
- mContext = glXCreateContext(glxIntegration->xDisplay(),visualInfo,0,TRUE);
+ GLXFBConfig config = qglx_findConfig(display, screen, format, GLX_PIXMAP_BIT);
- geometryChanged();
+ GLXContext shareContext = share ? static_cast<QWaylandReadbackGlxContext *>(share)->m_context : 0;
+
+ XVisualInfo *visualInfo = glXGetVisualFromFBConfig(display, config);
+ m_context = glXCreateContext(display, visualInfo, shareContext, TRUE);
+ m_format = qglx_surfaceFormatFromGLXFBConfig(display, config, m_context);
+}
+
+QSurfaceFormat QWaylandReadbackGlxContext::format() const
+{
+ return m_format;
}
-void QWaylandReadbackGlxContext::makeCurrent()
+bool QWaylandReadbackGlxContext::makeCurrent(QPlatformSurface *surface)
{
- QPlatformGLContext::makeCurrent();
+ GLXPixmap glxPixmap = static_cast<QWaylandReadbackGlxWindow *>(surface)->glxPixmap();
- glXMakeCurrent(mGlxIntegration->xDisplay(),mGlxPixmap,mContext);
+ return glXMakeCurrent(m_display, glxPixmap, m_context);
}
void QWaylandReadbackGlxContext::doneCurrent()
{
- QPlatformGLContext::doneCurrent();
+ glXMakeCurrent(m_display, 0, 0);
}
-void QWaylandReadbackGlxContext::swapBuffers()
+void QWaylandReadbackGlxContext::swapBuffers(QPlatformSurface *surface)
{
- if (QPlatformGLContext::currentContext() != this) {
- makeCurrent();
- }
+ // #### makeCurrent() directly on the platform context doesn't update QOpenGLContext::currentContext()
+ if (QOpenGLContext::currentContext()->handle() != this)
+ makeCurrent(surface);
+
+ QWaylandReadbackGlxWindow *w = static_cast<QWaylandReadbackGlxWindow *>(surface);
- QSize size = mWindow->geometry().size();
+ QSize size = w->geometry().size();
- QImage img(size,QImage::Format_ARGB32);
+ QImage img(size, QImage::Format_ARGB32);
const uchar *constBits = img.bits();
void *pixels = const_cast<uchar *>(constBits);
- glReadPixels(0,0, size.width(), size.height(), GL_RGBA,GL_UNSIGNED_BYTE, pixels);
+ glReadPixels(0, 0, size.width(), size.height(), GL_RGBA,GL_UNSIGNED_BYTE, pixels);
img = img.mirrored();
- qgl_byteSwapImage(img,GL_UNSIGNED_INT_8_8_8_8_REV);
+ qgl_byteSwapImage(img, GL_UNSIGNED_INT_8_8_8_8_REV);
constBits = img.bits();
- const uchar *constDstBits = mBuffer->image()->bits();
+ const uchar *constDstBits = w->buffer();
uchar *dstBits = const_cast<uchar *>(constDstBits);
- memcpy(dstBits,constBits,(img.width()*4) * img.height());
+ memcpy(dstBits, constBits, (img.width() * 4) * img.height());
+ w->damage(QRect(QPoint(), size));
- mWindow->damage(QRegion(QRect(QPoint(0,0),size)));
- mWindow->waitForFrameSync();
-
+ w->waitForFrameSync();
}
-void * QWaylandReadbackGlxContext::getProcAddress(const QString &procName)
+void (*QWaylandReadbackGlxContext::getProcAddress(const QByteArray &procName)) ()
{
- return (void *) glXGetProcAddress(reinterpret_cast<GLubyte *>(procName.toLatin1().data()));
-}
-
-QPlatformWindowFormat QWaylandReadbackGlxContext::platformWindowFormat() const
-{
- return qglx_platformWindowFromGLXFBConfig(mGlxIntegration->xDisplay(),mConfig,mContext);
-}
-
-void QWaylandReadbackGlxContext::geometryChanged()
-{
- QSize size(mWindow->geometry().size());
- if (size.isEmpty()) {
- //QGLWidget wants a context for a window without geometry
- size = QSize(1,1);
- }
-
- mWindow->waitForFrameSync();
-
- delete mBuffer;
- //XFreePixmap deletes the glxPixmap as well
- if (mPixmap) {
- XFreePixmap(mGlxIntegration->xDisplay(),mPixmap);
- }
-
- mBuffer = new QWaylandShmBuffer(mGlxIntegration->waylandDisplay(),size,QImage::Format_ARGB32);
- mWindow->attach(mBuffer);
- int depth = XDefaultDepth(mGlxIntegration->xDisplay(),mGlxIntegration->screen());
- mPixmap = XCreatePixmap(mGlxIntegration->xDisplay(),mGlxIntegration->rootWindow(),size.width(),size.height(),depth);
- XSync(mGlxIntegration->xDisplay(),False);
-
- mGlxPixmap = glXCreatePixmap(mGlxIntegration->xDisplay(),mConfig,mPixmap,0);
-
- if (!mGlxPixmap) {
- qDebug() << "Could not make egl surface out of pixmap :(";
- }
+ return glXGetProcAddress(reinterpret_cast<const GLubyte *>(procName.constData()));
}
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.h b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.h
index 07e0f620de..7b5eeece93 100644
--- a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.h
+++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.h
@@ -42,38 +42,35 @@
#ifndef QWAYLANDREADBACKGLXCONTEXT_H
#define QWAYLANDREADBACKGLXCONTEXT_H
-#include <QPlatformGLContext>
+#include <QPlatformOpenGLContext>
+#include <QSurfaceFormat>
#include "qwaylandreadbackglxintegration.h"
-#include "qglxconvenience.h"
+#include <QtPlatformSupport/private/qglxconvenience_p.h>
class QWaylandReadbackGlxWindow;
class QWaylandShmBuffer;
-class QWaylandReadbackGlxContext : public QPlatformGLContext
+class QWaylandReadbackGlxContext : public QPlatformOpenGLContext
{
public:
- QWaylandReadbackGlxContext(QWaylandReadbackGlxIntegration *glxIntegration, QWaylandReadbackGlxWindow *window);
+ QWaylandReadbackGlxContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, Display *display, int screen);
- void makeCurrent();
- void doneCurrent();
- void swapBuffers();
- void* getProcAddress(const QString& procName);
+ QSurfaceFormat format() const;
+
+ void swapBuffers(QPlatformSurface *surface);
- QPlatformWindowFormat platformWindowFormat() const;
+ bool makeCurrent(QPlatformSurface *surface);
+ void doneCurrent();
- void geometryChanged();
+ void (*getProcAddress(const QByteArray &procName)) ();
private:
- QWaylandReadbackGlxIntegration *mGlxIntegration;
- QWaylandReadbackGlxWindow *mWindow;
- QWaylandShmBuffer *mBuffer;
+ GLXContext m_context;
- Pixmap mPixmap;
- GLXFBConfig mConfig;
- GLXContext mContext;
- GLXPixmap mGlxPixmap;
+ Display *m_display;
+ QSurfaceFormat m_format;
};
#endif // QWAYLANDREADBACKGLXCONTEXT_H
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.cpp b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.cpp
index 37a14a9f4c..752bb06a43 100644
--- a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.cpp
+++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.cpp
@@ -66,9 +66,14 @@ void QWaylandReadbackGlxIntegration::initialize()
{
}
-QWaylandWindow * QWaylandReadbackGlxIntegration::createEglWindow(QWidget *widget)
+QWaylandWindow * QWaylandReadbackGlxIntegration::createEglWindow(QWindow *window)
{
- return new QWaylandReadbackGlxWindow(widget,this);
+ return new QWaylandReadbackGlxWindow(window,this);
+}
+
+QPlatformOpenGLContext *QWaylandReadbackGlxIntegration::createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const
+{
+ return new QWaylandReadbackGlxContext(glFormat, share, mDisplay, mScreen);
}
QWaylandGLIntegration * QWaylandGLIntegration::createGLIntegration(QWaylandDisplay *waylandDisplay)
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.h b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.h
index d267d8dffe..ee50d74ebd 100644
--- a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.h
+++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.h
@@ -48,7 +48,7 @@
#include <QtCore/QDataStream>
#include <QtCore/QMetaType>
#include <QtCore/QVariant>
-#include <QtGui/QWidget>
+#include <QtGui/QWindow>
#include <X11/Xlib.h>
@@ -60,7 +60,8 @@ public:
void initialize();
- QWaylandWindow *createEglWindow(QWidget *widget);
+ QWaylandWindow *createEglWindow(QWindow *window);
+ QPlatformOpenGLContext *createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const;
QWaylandDisplay *waylandDisplay() const;
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.cpp b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.cpp
index 98198dfa06..35c3ca3154 100644
--- a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.cpp
+++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.cpp
@@ -39,12 +39,19 @@
**
****************************************************************************/
+#include <QtDebug>
+
#include "qwaylandreadbackglxwindow.h"
+#include "qwaylandshmbackingstore.h"
-QWaylandReadbackGlxWindow::QWaylandReadbackGlxWindow(QWidget *window, QWaylandReadbackGlxIntegration *glxIntegration)
+QWaylandReadbackGlxWindow::QWaylandReadbackGlxWindow(QWindow *window, QWaylandReadbackGlxIntegration *glxIntegration)
: QWaylandShmWindow(window)
- , mGlxIntegration(glxIntegration)
- , mContext(0)
+ , m_glxIntegration(glxIntegration)
+ , m_buffer(0)
+ , m_pixmap(0)
+ , m_config(0)
+ , m_glxPixmap(0)
+ , m_window(window)
{
}
@@ -54,20 +61,54 @@ QWaylandWindow::WindowType QWaylandReadbackGlxWindow::windowType() const
return QWaylandWindow::Egl;
}
-QPlatformGLContext * QWaylandReadbackGlxWindow::glContext() const
+void QWaylandReadbackGlxWindow::setGeometry(const QRect &rect)
{
- if (!mContext) {
- QWaylandReadbackGlxWindow *that = const_cast<QWaylandReadbackGlxWindow *>(this);
- that->mContext = new QWaylandReadbackGlxContext(mGlxIntegration,that);
+ QWaylandShmWindow::setGeometry(rect);
+
+ if (m_pixmap) {
+ delete mBuffer;
+ //XFreePixmap deletes the glxPixmap as well
+ XFreePixmap(m_glxIntegration->xDisplay(), m_pixmap);
+ m_pixmap = 0;
}
- return mContext;
}
-void QWaylandReadbackGlxWindow::setGeometry(const QRect &rect)
+GLXPixmap QWaylandReadbackGlxWindow::glxPixmap() const
{
- QWaylandShmWindow::setGeometry(rect);
+ if (!m_pixmap)
+ const_cast<QWaylandReadbackGlxWindow *>(this)->createSurface();
+
+ return m_glxPixmap;
+}
- if (mContext) {
- mContext->geometryChanged();
+uchar *QWaylandReadbackGlxWindow::buffer()
+{
+ return m_buffer->image()->bits();
+}
+
+void QWaylandReadbackGlxWindow::createSurface()
+{
+ QSize size(geometry().size());
+ if (size.isEmpty()) {
+ //QGLWidget wants a context for a window without geometry
+ size = QSize(1,1);
}
+
+ waitForFrameSync();
+
+ m_buffer = new QWaylandShmBuffer(m_glxIntegration->waylandDisplay(), size, QImage::Format_ARGB32);
+ attach(m_buffer);
+
+ int depth = XDefaultDepth(m_glxIntegration->xDisplay(), m_glxIntegration->screen());
+ m_pixmap = XCreatePixmap(m_glxIntegration->xDisplay(), m_glxIntegration->rootWindow(), size.width(), size.height(), depth);
+ XSync(m_glxIntegration->xDisplay(), False);
+
+ if (!m_config)
+ m_config = qglx_findConfig(m_glxIntegration->xDisplay(), m_glxIntegration->screen(), m_window->format());
+
+ m_glxPixmap = glXCreatePixmap(m_glxIntegration->xDisplay(), m_config, m_pixmap,0);
+
+ if (!m_glxPixmap)
+ qDebug() << "Could not make glx surface out of pixmap :(";
}
+
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.h b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.h
index d478961d53..c92646c80d 100644
--- a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.h
+++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.h
@@ -49,17 +49,25 @@
class QWaylandReadbackGlxWindow : public QWaylandShmWindow
{
public:
- QWaylandReadbackGlxWindow(QWidget *window, QWaylandReadbackGlxIntegration *glxIntegration);
+ QWaylandReadbackGlxWindow(QWindow *window, QWaylandReadbackGlxIntegration *glxIntegration);
WindowType windowType() const;
- QPlatformGLContext *glContext() const;
-
void setGeometry(const QRect &rect);
+ Pixmap glxPixmap() const;
+
+ uchar *buffer();
+
private:
- QWaylandReadbackGlxIntegration *mGlxIntegration;
- QWaylandReadbackGlxContext *mContext;
+ void createSurface();
+
+ QWaylandReadbackGlxIntegration *m_glxIntegration;
+ QWaylandShmBuffer *m_buffer;
+ Pixmap m_pixmap;
+ GLXFBConfig m_config;
+ GLXPixmap m_glxPixmap;
+ QWindow *m_window;
};
#endif // QWAYLANDREADBACKGLXWINDOW_H
diff --git a/src/plugins/platforms/wayland/gl_integration/readback_glx/readback_glx.pri b/src/plugins/platforms/wayland/gl_integration/readback_glx/readback_glx.pri
index f8ea005937..746d594fa2 100644
--- a/src/plugins/platforms/wayland/gl_integration/readback_glx/readback_glx.pri
+++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/readback_glx.pri
@@ -1,4 +1,3 @@
-include (../../../glxconvenience/glxconvenience.pri)
HEADERS += \
$$PWD/qwaylandreadbackglxintegration.h \
$$PWD/qwaylandreadbackglxwindow.h \
diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.cpp b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.cpp
index d4deb01022..27f17a6153 100644
--- a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.cpp
+++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.cpp
@@ -44,11 +44,12 @@
#include "gl_integration/qwaylandglintegration.h"
#include "qwaylandeglwindow.h"
+#include "qwaylandglcontext.h"
#include <QtCore/QDebug>
QWaylandEglIntegration::QWaylandEglIntegration(struct wl_display *waylandDisplay)
- : mWaylandDisplay(waylandDisplay)
+ : m_waylandDisplay(waylandDisplay)
{
qDebug() << "Using Wayland-EGL";
}
@@ -56,31 +57,41 @@ QWaylandEglIntegration::QWaylandEglIntegration(struct wl_display *waylandDisplay
QWaylandEglIntegration::~QWaylandEglIntegration()
{
- eglTerminate(mEglDisplay);
+ eglTerminate(m_eglDisplay);
}
void QWaylandEglIntegration::initialize()
{
+ QByteArray eglPlatform = qgetenv("EGL_PLATFORM");
+ if (eglPlatform.isEmpty()) {
+ setenv("EGL_PLATFORM","wayland",true);
+ }
+
EGLint major,minor;
- mEglDisplay = eglGetDisplay(mWaylandDisplay);
- if (mEglDisplay == NULL) {
+ m_eglDisplay = eglGetDisplay(m_waylandDisplay);
+ if (m_eglDisplay == NULL) {
qWarning("EGL not available");
} else {
- if (!eglInitialize(mEglDisplay, &major, &minor)) {
+ if (!eglInitialize(m_eglDisplay, &major, &minor)) {
qWarning("failed to initialize EGL display");
return;
}
}
}
-QWaylandWindow *QWaylandEglIntegration::createEglWindow(QWidget *window)
+QWaylandWindow *QWaylandEglIntegration::createEglWindow(QWindow *window)
{
return new QWaylandEglWindow(window);
}
+QPlatformOpenGLContext *QWaylandEglIntegration::createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const
+{
+ return new QWaylandGLContext(m_eglDisplay, glFormat, share);
+}
+
EGLDisplay QWaylandEglIntegration::eglDisplay() const
{
- return mEglDisplay;
+ return m_eglDisplay;
}
QWaylandGLIntegration *QWaylandGLIntegration::createGLIntegration(QWaylandDisplay *waylandDisplay)
diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.h b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.h
index ea8b0f725c..7a26c57658 100644
--- a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.h
+++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.h
@@ -47,7 +47,7 @@
#include "qwaylandeglinclude.h"
class QWaylandWindow;
-class QWidget;
+class QWindow;
class QWaylandEglIntegration : public QWaylandGLIntegration
{
@@ -57,14 +57,15 @@ public:
void initialize();
- QWaylandWindow *createEglWindow(QWidget *window);
+ QWaylandWindow *createEglWindow(QWindow *window);
+ QPlatformOpenGLContext *createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const;
EGLDisplay eglDisplay() const;
- struct wl_egl_display *nativeDisplay() const;
+
private:
- struct wl_display *mWaylandDisplay;
+ struct wl_display *m_waylandDisplay;
- EGLDisplay mEglDisplay;
+ EGLDisplay m_eglDisplay;
};
#endif // QWAYLANDEGLINTEGRATION_H
diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.cpp b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.cpp
index cd8b5b3524..e0e1f772b9 100644
--- a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.cpp
+++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.cpp
@@ -44,19 +44,30 @@
#include "qwaylandscreen.h"
#include "qwaylandglcontext.h"
-QWaylandEglWindow::QWaylandEglWindow(QWidget *window)
+#include <QtPlatformSupport/private/qeglconvenience_p.h>
+
+#include <QtGui/QWindow>
+#include <QtGui/QWindowSystemInterface>
+
+QWaylandEglWindow::QWaylandEglWindow(QWindow *window)
: QWaylandWindow(window)
- , mGLContext(0)
- , mWaylandEglWindow(0)
+ , m_waylandEglWindow(0)
+ , m_eglSurface(0)
+ , m_eglConfig(0)
+ , m_format(window->format())
{
- mEglIntegration = static_cast<QWaylandEglIntegration *>(mDisplay->eglIntegration());
+ m_eglIntegration = static_cast<QWaylandEglIntegration *>(mDisplay->eglIntegration());
+
//super creates a new surface
newSurfaceCreated();
}
QWaylandEglWindow::~QWaylandEglWindow()
{
- delete mGLContext;
+ if (m_eglSurface) {
+ eglDestroySurface(m_eglIntegration->eglDisplay(), m_eglSurface);
+ m_eglSurface = 0;
+ }
}
QWaylandWindow::WindowType QWaylandEglWindow::windowType() const
@@ -67,46 +78,48 @@ QWaylandWindow::WindowType QWaylandEglWindow::windowType() const
void QWaylandEglWindow::setGeometry(const QRect &rect)
{
QWaylandWindow::setGeometry(rect);
- if (mWaylandEglWindow) {
- wl_egl_window_resize(mWaylandEglWindow,rect.width(),rect.height(),0,0);
+ if (m_waylandEglWindow){
+ wl_egl_window_resize(m_waylandEglWindow, rect.width(), rect.height(), 0, 0);
+ QWindowSystemInterface::handleGeometryChange(window(), rect);
}
}
-void QWaylandEglWindow::setParent(const QPlatformWindow *parent)
+void QWaylandEglWindow::newSurfaceCreated()
{
- const QWaylandWindow *wParent = static_cast<const QWaylandWindow *>(parent);
+ if (m_waylandEglWindow)
+ wl_egl_window_destroy(m_waylandEglWindow);
- mParentWindow = wParent;
-}
-
-QPlatformGLContext * QWaylandEglWindow::glContext() const
-{
- if (!mGLContext) {
- QWaylandEglWindow *that = const_cast<QWaylandEglWindow *>(this);
- that->mGLContext = new QWaylandGLContext(mEglIntegration->eglDisplay(),widget()->platformWindowFormat());
+ wl_visual *visual = QWaylandScreen::waylandScreenFromWindow(window())->visual();
+ QSize size = geometry().size();
+ if (!size.isValid())
+ size = QSize(0,0);
- EGLNativeWindowType window(reinterpret_cast<EGLNativeWindowType>(mWaylandEglWindow));
- EGLSurface surface = eglCreateWindowSurface(mEglIntegration->eglDisplay(),mGLContext->eglConfig(),window,NULL);
- that->mGLContext->setEglSurface(surface);
+ if (m_eglSurface) {
+ eglDestroySurface(m_eglIntegration->eglDisplay(), m_eglSurface);
+ m_eglSurface = 0;
}
- return mGLContext;
+ m_waylandEglWindow = wl_egl_window_create(mSurface, size.width(), size.height(), visual);
}
-void QWaylandEglWindow::newSurfaceCreated()
+QSurfaceFormat QWaylandEglWindow::format() const
{
- if (mWaylandEglWindow) {
- wl_egl_window_destroy(mWaylandEglWindow);
- }
- wl_visual *visual = QWaylandScreen::waylandScreenFromWidget(widget())->visual();
- QSize size = geometry().size();
- if (!size.isValid())
- size = QSize(0,0);
+ return m_format;
+}
- mWaylandEglWindow = wl_egl_window_create(mSurface,size.width(),size.height(),visual);
- if (mGLContext) {
- EGLNativeWindowType window(reinterpret_cast<EGLNativeWindowType>(mWaylandEglWindow));
- EGLSurface surface = eglCreateWindowSurface(mEglIntegration->eglDisplay(),mGLContext->eglConfig(),window,NULL);
- mGLContext->setEglSurface(surface);
+EGLSurface QWaylandEglWindow::eglSurface() const
+{
+ if (!m_waylandEglWindow)
+ return 0;
+
+ if (!m_eglSurface) {
+ if (!m_eglConfig)
+ m_eglConfig = q_configFromGLFormat(m_eglIntegration->eglDisplay(), window()->format(), true);
+
+ EGLNativeWindowType window = m_waylandEglWindow;
+ m_eglSurface = eglCreateWindowSurface(m_eglIntegration->eglDisplay(), m_eglConfig, window, 0);
}
+
+ return m_eglSurface;
}
+
diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.h b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.h
index 6d2038824a..d435a511c4 100644
--- a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.h
+++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.h
@@ -51,20 +51,28 @@ class QWaylandGLContext;
class QWaylandEglWindow : public QWaylandWindow
{
public:
- QWaylandEglWindow(QWidget *window);
+ QWaylandEglWindow(QWindow *window);
~QWaylandEglWindow();
WindowType windowType() const;
void setGeometry(const QRect &rect);
- void setParent(const QPlatformWindow *parent);
- QPlatformGLContext *glContext() const;
+
+ EGLSurface eglSurface() const;
+
+ QSurfaceFormat format() const;
+
protected:
void newSurfaceCreated();
+
private:
- QWaylandEglIntegration *mEglIntegration;
- QWaylandGLContext *mGLContext;
- struct wl_egl_window *mWaylandEglWindow;
+ QWaylandEglIntegration *m_eglIntegration;
+ struct wl_egl_window *m_waylandEglWindow;
+
+ const QWaylandWindow *m_parentWindow;
+
+ mutable EGLSurface m_eglSurface;
+ mutable EGLConfig m_eglConfig;
- const QWaylandWindow *mParentWindow;
+ QSurfaceFormat m_format;
};
#endif // QWAYLANDEGLWINDOW_H
diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.cpp b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.cpp
index 0f27501c71..aa61405eb6 100644
--- a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.cpp
+++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.cpp
@@ -43,26 +43,21 @@
#include "qwaylanddisplay.h"
#include "qwaylandwindow.h"
+#include "qwaylandeglwindow.h"
-#include "../../../eglconvenience/qeglconvenience.h"
+#include <QtPlatformSupport/private/qeglconvenience_p.h>
-#include <QtGui/QPlatformGLContext>
-#include <QtGui/QPlatformWindowFormat>
+#include <QtGui/QPlatformOpenGLContext>
+#include <QtGui/QSurfaceFormat>
#include <QtCore/QMutex>
-QWaylandGLContext::QWaylandGLContext(EGLDisplay eglDisplay, const QPlatformWindowFormat &format)
- : QPlatformGLContext()
- , mEglDisplay(eglDisplay)
- , mSurface(EGL_NO_SURFACE)
- , mConfig(q_configFromQPlatformWindowFormat(mEglDisplay,format,true))
- , mFormat(qt_qPlatformWindowFormatFromConfig(mEglDisplay,mConfig))
+QWaylandGLContext::QWaylandGLContext(EGLDisplay eglDisplay, const QSurfaceFormat &format, QPlatformOpenGLContext *share)
+ : QPlatformOpenGLContext()
+ , m_eglDisplay(eglDisplay)
+ , m_config(q_configFromGLFormat(m_eglDisplay, format, true))
+ , m_format(q_glFormatFromConfig(m_eglDisplay, m_config))
{
- QPlatformGLContext *sharePlatformContext = 0;
- sharePlatformContext = format.sharedGLContext();
- mFormat.setSharedContext(sharePlatformContext);
- EGLContext shareEGLContext = EGL_NO_CONTEXT;
- if (sharePlatformContext)
- shareEGLContext = static_cast<const QWaylandGLContext*>(sharePlatformContext)->mContext;
+ EGLContext shareEGLContext = share ? static_cast<QWaylandGLContext *>(share)->eglContext() : EGL_NO_CONTEXT;
eglBindAPI(EGL_OPENGL_ES_API);
@@ -71,63 +66,38 @@ QWaylandGLContext::QWaylandGLContext(EGLDisplay eglDisplay, const QPlatformWindo
eglContextAttrs.append(2);
eglContextAttrs.append(EGL_NONE);
- mContext = eglCreateContext(mEglDisplay, mConfig,
- shareEGLContext, eglContextAttrs.constData());
+ m_context = eglCreateContext(m_eglDisplay, m_config, shareEGLContext, eglContextAttrs.constData());
}
-QWaylandGLContext::QWaylandGLContext()
- : QPlatformGLContext()
- , mEglDisplay(0)
- , mContext(EGL_NO_CONTEXT)
- , mSurface(EGL_NO_SURFACE)
- , mConfig(0)
-{ }
-
QWaylandGLContext::~QWaylandGLContext()
{
- eglDestroyContext(mEglDisplay,mContext);
+ eglDestroyContext(m_eglDisplay, m_context);
}
-void QWaylandGLContext::makeCurrent()
+bool QWaylandGLContext::makeCurrent(QPlatformSurface *surface)
{
- QPlatformGLContext::makeCurrent();
- if (mSurface == EGL_NO_SURFACE) {
- qWarning("makeCurrent with EGL_NO_SURFACE");
- }
- eglMakeCurrent(mEglDisplay, mSurface, mSurface, mContext);
+ EGLSurface eglSurface = static_cast<QWaylandEglWindow *>(surface)->eglSurface();
+ return eglMakeCurrent(m_eglDisplay, eglSurface, eglSurface, m_context);
}
void QWaylandGLContext::doneCurrent()
{
- QPlatformGLContext::doneCurrent();
- eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-}
-
-void QWaylandGLContext::swapBuffers()
-{
- eglSwapBuffers(mEglDisplay,mSurface);
+ eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
}
-void *QWaylandGLContext::getProcAddress(const QString &string)
+void QWaylandGLContext::swapBuffers(QPlatformSurface *surface)
{
- return (void *) eglGetProcAddress(string.toLatin1().data());
+ EGLSurface eglSurface = static_cast<QWaylandEglWindow *>(surface)->eglSurface();
+ eglSwapBuffers(m_eglDisplay, eglSurface);
}
-void QWaylandGLContext::setEglSurface(EGLSurface surface)
+void (*QWaylandGLContext::getProcAddress(const QByteArray &procName)) ()
{
- bool wasCurrent = false;
- if (QPlatformGLContext::currentContext() == this) {
- wasCurrent = true;
- doneCurrent();
- }
- mSurface = surface;
- if (wasCurrent) {
- makeCurrent();
- }
+ return eglGetProcAddress(procName.constData());
}
EGLConfig QWaylandGLContext::eglConfig() const
{
- return mConfig;
+ return m_config;
}
diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.h b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.h
index 2c6feb498c..16d9fa4ada 100644
--- a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.h
+++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.h
@@ -44,36 +44,36 @@
#include "qwaylanddisplay.h"
-#include <QtGui/QPlatformGLContext>
+#include <QtGui/QPlatformOpenGLContext>
#include "qwaylandeglinclude.h"
class QWaylandWindow;
class QWaylandGLWindowSurface;
-class QWaylandGLContext : public QPlatformGLContext {
+class QWaylandGLContext : public QPlatformOpenGLContext {
public:
- QWaylandGLContext(EGLDisplay eglDisplay, const QPlatformWindowFormat &format);
+ QWaylandGLContext(EGLDisplay eglDisplay, const QSurfaceFormat &format, QPlatformOpenGLContext *share);
~QWaylandGLContext();
- void makeCurrent();
+
+ void swapBuffers(QPlatformSurface *surface);
+
+ bool makeCurrent(QPlatformSurface *surface);
void doneCurrent();
- void swapBuffers();
- void* getProcAddress(const QString&);
- QPlatformWindowFormat platformWindowFormat() const { return mFormat; }
+ void (*getProcAddress(const QByteArray &procName)) ();
- void setEglSurface(EGLSurface surface);
- EGLConfig eglConfig() const;
-private:
- EGLDisplay mEglDisplay;
+ QSurfaceFormat format() const { return m_format; }
- EGLContext mContext;
- EGLSurface mSurface;
- EGLConfig mConfig;
- QPlatformWindowFormat mFormat;
+ EGLConfig eglConfig() const;
+ EGLContext eglContext() const { return m_context; }
- QWaylandGLContext();
+private:
+ EGLDisplay m_eglDisplay;
+ EGLContext m_context;
+ EGLConfig m_config;
+ QSurfaceFormat m_format;
};
diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/wayland_egl.pri b/src/plugins/platforms/wayland/gl_integration/wayland_egl/wayland_egl.pri
index cd0701150f..8b4b163b03 100644
--- a/src/plugins/platforms/wayland/gl_integration/wayland_egl/wayland_egl.pri
+++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/wayland_egl.pri
@@ -1,5 +1,3 @@
-include (../../../eglconvenience/eglconvenience.pri)
-
LIBS += -lwayland-egl -lEGL
INCLUDEPATH += $$PWD
SOURCES += $$PWD/qwaylandeglintegration.cpp \
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.cpp
index 999a411397..f2f9d1ceb6 100644
--- a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.cpp
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.cpp
@@ -42,128 +42,31 @@
#include "qwaylandxcompositeeglcontext.h"
#include "qwaylandxcompositeeglwindow.h"
-#include "qwaylandxcompositebuffer.h"
-#include "wayland-xcomposite-client-protocol.h"
#include <QtCore/QDebug>
+#include <QtGui/QRegion>
-#include "qeglconvenience.h"
-#include "qxlibeglintegration.h"
+#include <QtPlatformSupport/private/qeglconvenience_p.h>
-#include <X11/extensions/Xcomposite.h>
-
-QWaylandXCompositeEGLContext::QWaylandXCompositeEGLContext(QWaylandXCompositeEGLIntegration *glxIntegration, QWaylandXCompositeEGLWindow *window)
- : QPlatformGLContext()
- , mEglIntegration(glxIntegration)
- , mWindow(window)
- , mBuffer(0)
- , mXWindow(0)
- , mConfig(q_configFromQPlatformWindowFormat(glxIntegration->eglDisplay(),window->widget()->platformWindowFormat(),true,EGL_WINDOW_BIT))
- , mWaitingForSync(false)
-{
- QVector<EGLint> eglContextAttrs;
- eglContextAttrs.append(EGL_CONTEXT_CLIENT_VERSION); eglContextAttrs.append(2);
- eglContextAttrs.append(EGL_NONE);
-
- mContext = eglCreateContext(glxIntegration->eglDisplay(),mConfig,EGL_NO_CONTEXT,eglContextAttrs.constData());
- if (mContext == EGL_NO_CONTEXT) {
- qFatal("failed to find context");
- }
-
- geometryChanged();
-}
-
-void QWaylandXCompositeEGLContext::makeCurrent()
-{
- QPlatformGLContext::makeCurrent();
-
- eglMakeCurrent(mEglIntegration->eglDisplay(),mEglWindowSurface,mEglWindowSurface,mContext);
-}
-
-void QWaylandXCompositeEGLContext::doneCurrent()
+QWaylandXCompositeEGLContext::QWaylandXCompositeEGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display)
+ : QEGLPlatformContext(format, share, display)
{
- QPlatformGLContext::doneCurrent();
- eglMakeCurrent(mEglIntegration->eglDisplay(),EGL_NO_SURFACE,EGL_NO_SURFACE,EGL_NO_CONTEXT);
}
-void QWaylandXCompositeEGLContext::swapBuffers()
+void QWaylandXCompositeEGLContext::swapBuffers(QPlatformSurface *surface)
{
- QSize size = mWindow->geometry().size();
+ QEGLPlatformContext::swapBuffers(surface);
- eglSwapBuffers(mEglIntegration->eglDisplay(),mEglWindowSurface);
- mWindow->damage(QRect(QPoint(0,0),size));
- mWindow->waitForFrameSync();
-}
+ QWaylandXCompositeEGLWindow *w =
+ static_cast<QWaylandXCompositeEGLWindow *>(surface);
-void * QWaylandXCompositeEGLContext::getProcAddress(const QString &procName)
-{
- return (void *)eglGetProcAddress(qPrintable(procName));
-}
+ QSize size = w->geometry().size();
-QPlatformWindowFormat QWaylandXCompositeEGLContext::platformWindowFormat() const
-{
- return qt_qPlatformWindowFormatFromConfig(mEglIntegration->eglDisplay(),mConfig);
+ w->damage(QRect(QPoint(), size));
+ w->waitForFrameSync();
}
-void QWaylandXCompositeEGLContext::sync_function(void *data)
+EGLSurface QWaylandXCompositeEGLContext::eglSurfaceForPlatformSurface(QPlatformSurface *surface)
{
- QWaylandXCompositeEGLContext *that = static_cast<QWaylandXCompositeEGLContext *>(data);
- that->mWaitingForSync = false;
-}
-
-void QWaylandXCompositeEGLContext::geometryChanged()
-{
- QSize size(mWindow->geometry().size());
- if (size.isEmpty()) {
- //QGLWidget wants a context for a window without geometry
- size = QSize(1,1);
- }
-
- delete mBuffer;
- //XFreePixmap deletes the glxPixmap as well
- if (mXWindow) {
- XDestroyWindow(mEglIntegration->xDisplay(),mXWindow);
- }
-
- VisualID visualId = QXlibEglIntegration::getCompatibleVisualId(mEglIntegration->xDisplay(),mEglIntegration->eglDisplay(),mConfig);
-
- XVisualInfo visualInfoTemplate;
- memset(&visualInfoTemplate, 0, sizeof(XVisualInfo));
- visualInfoTemplate.visualid = visualId;
-
- int matchingCount = 0;
- XVisualInfo *visualInfo = XGetVisualInfo(mEglIntegration->xDisplay(), VisualIDMask, &visualInfoTemplate, &matchingCount);
-
- Colormap cmap = XCreateColormap(mEglIntegration->xDisplay(),mEglIntegration->rootWindow(),visualInfo->visual,AllocNone);
-
- XSetWindowAttributes a;
- a.colormap = cmap;
- mXWindow = XCreateWindow(mEglIntegration->xDisplay(), mEglIntegration->rootWindow(),0, 0, size.width(), size.height(),
- 0, visualInfo->depth, InputOutput, visualInfo->visual,
- CWColormap, &a);
-
- XCompositeRedirectWindow(mEglIntegration->xDisplay(), mXWindow, CompositeRedirectManual);
- XMapWindow(mEglIntegration->xDisplay(), mXWindow);
-
- mEglWindowSurface = eglCreateWindowSurface(mEglIntegration->eglDisplay(),mConfig,mXWindow,0);
- if (mEglWindowSurface == EGL_NO_SURFACE) {
- qFatal("Could not make eglsurface");
- }
-
- XSync(mEglIntegration->xDisplay(),False);
- mBuffer = new QWaylandXCompositeBuffer(mEglIntegration->waylandXComposite(),
- (uint32_t)mXWindow,
- size,
- mEglIntegration->waylandDisplay()->argbVisual());
- mWindow->attach(mBuffer);
- wl_display_sync_callback(mEglIntegration->waylandDisplay()->wl_display(),
- QWaylandXCompositeEGLContext::sync_function,
- this);
-
- mWaitingForSync = true;
- wl_display_sync(mEglIntegration->waylandDisplay()->wl_display(),0);
- mEglIntegration->waylandDisplay()->flushRequests();
- while (mWaitingForSync) {
- mEglIntegration->waylandDisplay()->readEvents();
- }
+ return static_cast<QWaylandXCompositeEGLWindow *>(surface)->eglSurface();
}
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.h
index 9d9dd53e0b..8420f2be13 100644
--- a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.h
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.h
@@ -42,41 +42,23 @@
#ifndef QWAYLANDXCOMPOSITEEGLCONTEXT_H
#define QWAYLANDXCOMPOSITEEGLCONTEXT_H
-#include <QtGui/QPlatformGLContext>
+#include <QtGui/QPlatformOpenGLContext>
-#include <QtCore/QWaitCondition>
-
-#include "qwaylandbuffer.h"
#include "qwaylandxcompositeeglintegration.h"
+#include <QtPlatformSupport/private/qeglplatformcontext_p.h>
+
class QWaylandXCompositeEGLWindow;
-class QWaylandXCompositeEGLContext : public QPlatformGLContext
+class QWaylandXCompositeEGLContext : public QEGLPlatformContext
{
public:
- QWaylandXCompositeEGLContext(QWaylandXCompositeEGLIntegration *glxIntegration, QWaylandXCompositeEGLWindow *window);
-
- void makeCurrent();
- void doneCurrent();
- void swapBuffers();
- void* getProcAddress(const QString& procName);
+ QWaylandXCompositeEGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display);
- QPlatformWindowFormat platformWindowFormat() const;
-
- void geometryChanged();
+ void swapBuffers(QPlatformSurface *surface);
private:
- QWaylandXCompositeEGLIntegration *mEglIntegration;
- QWaylandXCompositeEGLWindow *mWindow;
- QWaylandBuffer *mBuffer;
-
- Window mXWindow;
- EGLConfig mConfig;
- EGLContext mContext;
- EGLSurface mEglWindowSurface;
-
- static void sync_function(void *data);
- bool mWaitingForSync;
+ EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface);
};
#endif // QWAYLANDXCOMPOSITEEGLCONTEXT_H
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.cpp
index 53199e87b8..d7e37f8e70 100644
--- a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.cpp
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.cpp
@@ -70,9 +70,14 @@ void QWaylandXCompositeEGLIntegration::initialize()
{
}
-QWaylandWindow * QWaylandXCompositeEGLIntegration::createEglWindow(QWidget *widget)
+QWaylandWindow * QWaylandXCompositeEGLIntegration::createEglWindow(QWindow *window)
{
- return new QWaylandXCompositeEGLWindow(widget,this);
+ return new QWaylandXCompositeEGLWindow(window,this);
+}
+
+QPlatformOpenGLContext *QWaylandXCompositeEGLIntegration::createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const
+{
+ return new QWaylandXCompositeEGLContext(glFormat, share, eglDisplay());
}
Display * QWaylandXCompositeEGLIntegration::xDisplay() const
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.h
index 1e8055944f..74ea930e9a 100644
--- a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.h
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.h
@@ -49,7 +49,9 @@
#include <QtCore/QDataStream>
#include <QtCore/QMetaType>
#include <QtCore/QVariant>
-#include <QtGui/QWidget>
+#include <QtGui/QWindow>
+
+#include <QPlatformOpenGLContext>
#include <QWaitCondition>
@@ -66,7 +68,8 @@ public:
void initialize();
- QWaylandWindow *createEglWindow(QWidget *widget);
+ QWaylandWindow *createEglWindow(QWindow *window);
+ QPlatformOpenGLContext *createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const;
QWaylandDisplay *waylandDisplay() const;
struct wl_xcomposite *waylandXComposite() const;
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.cpp
index 1047cb8b0a..320113f58d 100644
--- a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.cpp
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.cpp
@@ -40,17 +40,29 @@
****************************************************************************/
#include "qwaylandxcompositeeglwindow.h"
+#include "qwaylandxcompositebuffer.h"
+
+#include <QtPlatformSupport/private/qeglconvenience_p.h>
+#include <QtPlatformSupport/private/qxlibeglintegration_p.h>
+
+#include "wayland-xcomposite-client-protocol.h"
+
+#include <X11/extensions/Xcomposite.h>
#include "qwaylandxcompositeeglintegration.h"
#include "windowmanager_integration/qwaylandwindowmanagerintegration.h"
#include <QtCore/QDebug>
-QWaylandXCompositeEGLWindow::QWaylandXCompositeEGLWindow(QWidget *window, QWaylandXCompositeEGLIntegration *glxIntegration)
+QWaylandXCompositeEGLWindow::QWaylandXCompositeEGLWindow(QWindow *window, QWaylandXCompositeEGLIntegration *glxIntegration)
: QWaylandWindow(window)
- , mGlxIntegration(glxIntegration)
- , mContext(0)
+ , m_glxIntegration(glxIntegration)
+ , m_context(0)
+ , m_buffer(0)
+ , m_xWindow(0)
+ , m_config(q_configFromGLFormat(glxIntegration->eglDisplay(), window->format(), true))
+ , m_surface(0)
+ , m_waitingForSync(false)
{
-
}
QWaylandWindow::WindowType QWaylandXCompositeEGLWindow::windowType() const
@@ -59,23 +71,83 @@ QWaylandWindow::WindowType QWaylandXCompositeEGLWindow::windowType() const
return QWaylandWindow::Egl;
}
-QPlatformGLContext * QWaylandXCompositeEGLWindow::glContext() const
+void QWaylandXCompositeEGLWindow::setGeometry(const QRect &rect)
{
- if (!mContext) {
- qDebug() << "creating glcontext;";
- QWaylandXCompositeEGLWindow *that = const_cast<QWaylandXCompositeEGLWindow *>(this);
- that->mContext = new QWaylandXCompositeEGLContext(mGlxIntegration,that);
+ QWaylandWindow::setGeometry(rect);
+
+ if (m_surface) {
+ eglDestroySurface(m_glxIntegration->eglDisplay(), m_surface);
+ m_surface = 0;
}
- return mContext;
}
-void QWaylandXCompositeEGLWindow::setGeometry(const QRect &rect)
+EGLSurface QWaylandXCompositeEGLWindow::eglSurface() const
{
- QWaylandWindow::setGeometry(rect);
+ if (!m_surface)
+ const_cast<QWaylandXCompositeEGLWindow *>(this)->createEglSurface();
+ return m_surface;
+}
+
+void QWaylandXCompositeEGLWindow::createEglSurface()
+{
+ QSize size(geometry().size());
+ if (size.isEmpty()) {
+ // QGLWidget wants a context for a window without geometry
+ size = QSize(1,1);
+ }
- if (mContext) {
- mContext->geometryChanged();
+ delete m_buffer;
+ //XFreePixmap deletes the glxPixmap as well
+ if (m_xWindow) {
+ XDestroyWindow(m_glxIntegration->xDisplay(), m_xWindow);
}
+
+ VisualID visualId = QXlibEglIntegration::getCompatibleVisualId(m_glxIntegration->xDisplay(), m_glxIntegration->eglDisplay(), m_config);
+
+ XVisualInfo visualInfoTemplate;
+ memset(&visualInfoTemplate, 0, sizeof(XVisualInfo));
+ visualInfoTemplate.visualid = visualId;
+
+ int matchingCount = 0;
+ XVisualInfo *visualInfo = XGetVisualInfo(m_glxIntegration->xDisplay(), VisualIDMask, &visualInfoTemplate, &matchingCount);
+
+ Colormap cmap = XCreateColormap(m_glxIntegration->xDisplay(),m_glxIntegration->rootWindow(),visualInfo->visual,AllocNone);
+
+ XSetWindowAttributes a;
+ a.colormap = cmap;
+ m_xWindow = XCreateWindow(m_glxIntegration->xDisplay(), m_glxIntegration->rootWindow(),0, 0, size.width(), size.height(),
+ 0, visualInfo->depth, InputOutput, visualInfo->visual,
+ CWColormap, &a);
+
+ XCompositeRedirectWindow(m_glxIntegration->xDisplay(), m_xWindow, CompositeRedirectManual);
+ XMapWindow(m_glxIntegration->xDisplay(), m_xWindow);
+
+ m_surface = eglCreateWindowSurface(m_glxIntegration->eglDisplay(), m_config, m_xWindow,0);
+ if (m_surface == EGL_NO_SURFACE) {
+ qFatal("Could not make eglsurface");
+ }
+
+ XSync(m_glxIntegration->xDisplay(),False);
+ mBuffer = new QWaylandXCompositeBuffer(m_glxIntegration->waylandXComposite(),
+ (uint32_t)m_xWindow,
+ size,
+ m_glxIntegration->waylandDisplay()->argbVisual());
+ attach(m_buffer);
+ wl_display_sync_callback(m_glxIntegration->waylandDisplay()->wl_display(),
+ QWaylandXCompositeEGLWindow::sync_function,
+ this);
+
+ m_waitingForSync = true;
+ wl_display_sync(m_glxIntegration->waylandDisplay()->wl_display(),0);
+ m_glxIntegration->waylandDisplay()->flushRequests();
+ while (m_waitingForSync)
+ m_glxIntegration->waylandDisplay()->readEvents();
+}
+
+void QWaylandXCompositeEGLWindow::sync_function(void *data)
+{
+ QWaylandXCompositeEGLWindow *that = static_cast<QWaylandXCompositeEGLWindow *>(data);
+ that->m_waitingForSync = false;
}
void QWaylandXCompositeEGLWindow::requestActivateWindow()
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.h
index ea4dd2d626..b2f8fbe6c4 100644
--- a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.h
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.h
@@ -43,24 +43,36 @@
#define QWAYLANDXCOMPOSITEEGLWINDOW_H
#include "qwaylandwindow.h"
+#include "qwaylandbuffer.h"
+
#include "qwaylandxcompositeeglintegration.h"
#include "qwaylandxcompositeeglcontext.h"
class QWaylandXCompositeEGLWindow : public QWaylandWindow
{
public:
- QWaylandXCompositeEGLWindow(QWidget *window, QWaylandXCompositeEGLIntegration *glxIntegration);
+ QWaylandXCompositeEGLWindow(QWindow *window, QWaylandXCompositeEGLIntegration *glxIntegration);
WindowType windowType() const;
- QPlatformGLContext *glContext() const;
-
void setGeometry(const QRect &rect);
void requestActivateWindow();
+ EGLSurface eglSurface() const;
+
private:
- QWaylandXCompositeEGLIntegration *mGlxIntegration;
- QWaylandXCompositeEGLContext *mContext;
+ void createEglSurface();
+
+ QWaylandXCompositeEGLIntegration *m_glxIntegration;
+ QWaylandXCompositeEGLContext *m_context;
+ QWaylandBuffer *m_buffer;
+
+ Window m_xWindow;
+ EGLConfig m_config;
+ EGLSurface m_surface;
+
+ bool m_waitingForSync;
+ static void sync_function(void *data);
};
#endif // QWAYLANDXCOMPOSITEEGLWINDOW_H
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/xcomposite_egl.pri b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/xcomposite_egl.pri
index c3533f9ce3..5f86bd9588 100644
--- a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/xcomposite_egl.pri
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/xcomposite_egl.pri
@@ -1,6 +1,4 @@
include (../xcomposite_share/xcomposite_share.pri)
-include (../../../eglconvenience/eglconvenience.pri)
-include (../../../eglconvenience/xlibeglintegration.pri)
LIBS += -lXcomposite -lEGL
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.cpp
index 3d49790f3a..75881a7fdd 100644
--- a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.cpp
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.cpp
@@ -39,114 +39,56 @@
**
****************************************************************************/
+#include <QtCore/QDebug>
+
#include "qwaylandxcompositeglxcontext.h"
#include "qwaylandxcompositeglxwindow.h"
-#include "qwaylandxcompositebuffer.h"
-#include "wayland-xcomposite-client-protocol.h"
-#include <QtCore/QDebug>
+#include <QRegion>
-#include <X11/extensions/Xcomposite.h>
-
-QWaylandXCompositeGLXContext::QWaylandXCompositeGLXContext(QWaylandXCompositeGLXIntegration *glxIntegration, QWaylandXCompositeGLXWindow *window)
- : QPlatformGLContext()
- , mGlxIntegration(glxIntegration)
- , mWindow(window)
- , mBuffer(0)
- , mXWindow(0)
- , mConfig(qglx_findConfig(glxIntegration->xDisplay(),glxIntegration->screen(),window->widget()->platformWindowFormat()))
- , mWaitingForSyncCallback(false)
+QWaylandXCompositeGLXContext::QWaylandXCompositeGLXContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, Display *display, int screen)
+ : m_display(display)
{
- XVisualInfo *visualInfo = glXGetVisualFromFBConfig(glxIntegration->xDisplay(),mConfig);
- mContext = glXCreateContext(glxIntegration->xDisplay(),visualInfo,0,TRUE);
-
- geometryChanged();
+ qDebug("creating XComposite-GLX context");
+ GLXContext shareContext = share ? static_cast<QWaylandXCompositeGLXContext *>(share)->m_context : 0;
+ GLXFBConfig config = qglx_findConfig(display, screen, format);
+ XVisualInfo *visualInfo = glXGetVisualFromFBConfig(display, config);
+ m_context = glXCreateContext(display, visualInfo, shareContext, true);
+ m_format = qglx_surfaceFormatFromGLXFBConfig(display, config, m_context);
}
-void QWaylandXCompositeGLXContext::makeCurrent()
+bool QWaylandXCompositeGLXContext::makeCurrent(QPlatformSurface *surface)
{
- QPlatformGLContext::makeCurrent();
- glXMakeCurrent(mGlxIntegration->xDisplay(),mXWindow,mContext);
+ Window xWindow = static_cast<QWaylandXCompositeGLXWindow *>(surface)->xWindow();
+
+ return glXMakeCurrent(m_display, xWindow, m_context);
}
void QWaylandXCompositeGLXContext::doneCurrent()
{
- glXMakeCurrent(mGlxIntegration->xDisplay(),0,0);
- QPlatformGLContext::doneCurrent();
+ glXMakeCurrent(m_display, 0, 0);
}
-void QWaylandXCompositeGLXContext::swapBuffers()
+void QWaylandXCompositeGLXContext::swapBuffers(QPlatformSurface *surface)
{
- QSize size = mWindow->geometry().size();
+ QWaylandXCompositeGLXWindow *w = static_cast<QWaylandXCompositeGLXWindow *>(surface);
- glXSwapBuffers(mGlxIntegration->xDisplay(),mXWindow);
- mWindow->damage(QRect(QPoint(0,0),size));
- mWindow->waitForFrameSync();
-}
+ QSize size = w->geometry().size();
-void * QWaylandXCompositeGLXContext::getProcAddress(const QString &procName)
-{
- return (void *) glXGetProcAddress(reinterpret_cast<GLubyte *>(procName.toLatin1().data()));
-}
+ glXSwapBuffers(m_display, w->xWindow());
-QPlatformWindowFormat QWaylandXCompositeGLXContext::platformWindowFormat() const
-{
- return qglx_platformWindowFromGLXFBConfig(mGlxIntegration->xDisplay(),mConfig,mContext);
+ w->damage(QRect(QPoint(), size));
+ w->waitForFrameSync();
}
-void QWaylandXCompositeGLXContext::sync_function(void *data)
+void (*QWaylandXCompositeGLXContext::getProcAddress(const QByteArray &procName)) ()
{
- QWaylandXCompositeGLXContext *that = static_cast<QWaylandXCompositeGLXContext *>(data);
- that->mWaitingForSyncCallback = false;
+ return glXGetProcAddress(reinterpret_cast<const GLubyte *>(procName.constData()));
}
-void QWaylandXCompositeGLXContext::waitForSync()
+QSurfaceFormat QWaylandXCompositeGLXContext::format() const
{
- wl_display_sync_callback(mGlxIntegration->waylandDisplay()->wl_display(),
- QWaylandXCompositeGLXContext::sync_function,
- this);
- mWaitingForSyncCallback = true;
- wl_display_sync(mGlxIntegration->waylandDisplay()->wl_display(),0);
- mGlxIntegration->waylandDisplay()->flushRequests();
- while (mWaitingForSyncCallback) {
- mGlxIntegration->waylandDisplay()->readEvents();
- }
+ return m_format;
}
-void QWaylandXCompositeGLXContext::geometryChanged()
-{
- QSize size(mWindow->geometry().size());
- if (size.isEmpty()) {
- //QGLWidget wants a context for a window without geometry
- size = QSize(1,1);
- }
-
- delete mBuffer;
- //XFreePixmap deletes the glxPixmap as well
- if (mXWindow) {
- XDestroyWindow(mGlxIntegration->xDisplay(),mXWindow);
- }
-
- XVisualInfo *visualInfo = glXGetVisualFromFBConfig(mGlxIntegration->xDisplay(),mConfig);
- Colormap cmap = XCreateColormap(mGlxIntegration->xDisplay(),mGlxIntegration->rootWindow(),visualInfo->visual,AllocNone);
-
- XSetWindowAttributes a;
- a.background_pixel = WhitePixel(mGlxIntegration->xDisplay(), mGlxIntegration->screen());
- a.border_pixel = BlackPixel(mGlxIntegration->xDisplay(), mGlxIntegration->screen());
- a.colormap = cmap;
- mXWindow = XCreateWindow(mGlxIntegration->xDisplay(), mGlxIntegration->rootWindow(),0, 0, size.width(), size.height(),
- 0, visualInfo->depth, InputOutput, visualInfo->visual,
- CWBackPixel|CWBorderPixel|CWColormap, &a);
-
- XCompositeRedirectWindow(mGlxIntegration->xDisplay(), mXWindow, CompositeRedirectManual);
- XMapWindow(mGlxIntegration->xDisplay(), mXWindow);
-
- XSync(mGlxIntegration->xDisplay(),False);
- mBuffer = new QWaylandXCompositeBuffer(mGlxIntegration->waylandXComposite(),
- (uint32_t)mXWindow,
- size,
- mGlxIntegration->waylandDisplay()->argbVisual());
- mWindow->attach(mBuffer);
- waitForSync();
-}
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.h
index b6ee2bbc23..3364d88ec4 100644
--- a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.h
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.h
@@ -42,44 +42,33 @@
#ifndef QWAYLANDXCOMPOSITEGLXCONTEXT_H
#define QWAYLANDXCOMPOSITEGLXCONTEXT_H
-#include <QtGui/QPlatformGLContext>
+#include <QtGui/QPlatformOpenGLContext>
-#include <QtCore/QWaitCondition>
-
-#include "qwaylandbuffer.h"
#include "qwaylandxcompositeglxintegration.h"
-
-#include "qglxconvenience.h"
+#include <QtPlatformSupport/private/qglxconvenience_p.h>
class QWaylandXCompositeGLXWindow;
class QWaylandShmBuffer;
-class QWaylandXCompositeGLXContext : public QPlatformGLContext
+class QWaylandXCompositeGLXContext : public QPlatformOpenGLContext
{
public:
- QWaylandXCompositeGLXContext(QWaylandXCompositeGLXIntegration *glxIntegration, QWaylandXCompositeGLXWindow *window);
+ QWaylandXCompositeGLXContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, Display *display, int screen);
- void makeCurrent();
- void doneCurrent();
- void swapBuffers();
- void* getProcAddress(const QString& procName);
+ QSurfaceFormat format() const;
- QPlatformWindowFormat platformWindowFormat() const;
+ void swapBuffers(QPlatformSurface *surface);
- void geometryChanged();
+ bool makeCurrent(QPlatformSurface *surface);
+ void doneCurrent();
-private:
- QWaylandXCompositeGLXIntegration *mGlxIntegration;
- QWaylandXCompositeGLXWindow *mWindow;
- QWaylandBuffer *mBuffer;
+ void (*getProcAddress(const QByteArray &procName)) ();
- Window mXWindow;
- GLXFBConfig mConfig;
- GLXContext mContext;
+private:
+ GLXContext m_context;
- static void sync_function(void *data);
- void waitForSync();
- bool mWaitingForSyncCallback;
+ Display *m_display;
+ QSurfaceFormat m_format;
};
#endif // QWAYLANDXCOMPOSITEGLXCONTEXT_H
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.cpp
index e8dbea48c6..e1eb2e635a 100644
--- a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.cpp
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.cpp
@@ -52,12 +52,15 @@ QWaylandGLIntegration * QWaylandGLIntegration::createGLIntegration(QWaylandDispl
return new QWaylandXCompositeGLXIntegration(waylandDisplay);
}
-QWaylandXCompositeGLXIntegration::QWaylandXCompositeGLXIntegration(QWaylandDisplay * waylandDispaly)
- : QWaylandGLIntegration()
- , mWaylandDisplay(waylandDispaly)
+QWaylandXCompositeGLXIntegration::QWaylandXCompositeGLXIntegration(QWaylandDisplay *waylandDisplay)
+ : mWaylandDisplay(waylandDisplay)
+ , mWaylandComposite(0)
+ , mDisplay(0)
+ , mScreen(0)
+ , mRootWindow(0)
{
qDebug() << "Using XComposite-GLX";
- wl_display_add_global_listener(waylandDispaly->wl_display(), QWaylandXCompositeGLXIntegration::wlDisplayHandleGlobal,
+ wl_display_add_global_listener(waylandDisplay->wl_display(), QWaylandXCompositeGLXIntegration::wlDisplayHandleGlobal,
this);
}
@@ -70,9 +73,14 @@ void QWaylandXCompositeGLXIntegration::initialize()
{
}
-QWaylandWindow * QWaylandXCompositeGLXIntegration::createEglWindow(QWidget *widget)
+QWaylandWindow * QWaylandXCompositeGLXIntegration::createEglWindow(QWindow *window)
{
- return new QWaylandXCompositeGLXWindow(widget,this);
+ return new QWaylandXCompositeGLXWindow(window, this);
+}
+
+QPlatformOpenGLContext *QWaylandXCompositeGLXIntegration::createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const
+{
+ return new QWaylandXCompositeGLXContext(glFormat, share, mDisplay, mScreen);
}
Display * QWaylandXCompositeGLXIntegration::xDisplay() const
@@ -107,6 +115,7 @@ void QWaylandXCompositeGLXIntegration::wlDisplayHandleGlobal(wl_display *display
{
Q_UNUSED(version);
if (strcmp(interface, "wl_xcomposite") == 0) {
+ qDebug("XComposite-GLX: got wl_xcomposite global");
QWaylandXCompositeGLXIntegration *integration = static_cast<QWaylandXCompositeGLXIntegration *>(data);
integration->mWaylandComposite = wl_xcomposite_create(display,id,1);
wl_xcomposite_add_listener(integration->mWaylandComposite,&xcomposite_listener,integration);
@@ -119,6 +128,8 @@ void QWaylandXCompositeGLXIntegration::rootInformation(void *data, wl_xcomposite
Q_UNUSED(xcomposite);
QWaylandXCompositeGLXIntegration *integration = static_cast<QWaylandXCompositeGLXIntegration *>(data);
+ qDebug("XComposite-GLX: xcomposite listener callback");
+
integration->mDisplay = XOpenDisplay(display_name);
integration->mRootWindow = (Window) root_window;
integration->mScreen = XDefaultScreen(integration->mDisplay);
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.h
index 17f2f6d4e4..b028067d8e 100644
--- a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.h
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.h
@@ -49,7 +49,7 @@
#include <QtCore/QDataStream>
#include <QtCore/QMetaType>
#include <QtCore/QVariant>
-#include <QtGui/QWidget>
+#include <QtGui/QWindow>
#include <X11/Xlib.h>
@@ -63,7 +63,8 @@ public:
void initialize();
- QWaylandWindow *createEglWindow(QWidget *widget);
+ QWaylandWindow *createEglWindow(QWindow *window);
+ QPlatformOpenGLContext *createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const;
QWaylandDisplay *waylandDisplay() const;
struct wl_xcomposite *waylandXComposite() const;
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.cpp
index cd7ae1964c..abaf3b16a9 100644
--- a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.cpp
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.cpp
@@ -40,15 +40,24 @@
****************************************************************************/
#include "qwaylandxcompositeglxwindow.h"
+#include "qwaylandxcompositebuffer.h"
#include <QtCore/QDebug>
-QWaylandXCompositeGLXWindow::QWaylandXCompositeGLXWindow(QWidget *window, QWaylandXCompositeGLXIntegration *glxIntegration)
+#include "wayland-xcomposite-client-protocol.h"
+#include <QtGui/QRegion>
+
+#include <X11/extensions/Xcomposite.h>
+
+
+QWaylandXCompositeGLXWindow::QWaylandXCompositeGLXWindow(QWindow *window, QWaylandXCompositeGLXIntegration *glxIntegration)
: QWaylandWindow(window)
- , mGlxIntegration(glxIntegration)
- , mContext(0)
+ , m_glxIntegration(glxIntegration)
+ , m_xWindow(0)
+ , m_config(qglx_findConfig(glxIntegration->xDisplay(), glxIntegration->screen(), window->format()))
+ , m_buffer(0)
+ , m_waitingForSync(false)
{
-
}
QWaylandWindow::WindowType QWaylandXCompositeGLXWindow::windowType() const
@@ -57,21 +66,79 @@ QWaylandWindow::WindowType QWaylandXCompositeGLXWindow::windowType() const
return QWaylandWindow::Egl;
}
-QPlatformGLContext * QWaylandXCompositeGLXWindow::glContext() const
+void QWaylandXCompositeGLXWindow::setGeometry(const QRect &rect)
{
- if (!mContext) {
- qDebug() << "creating glcontext;";
- QWaylandXCompositeGLXWindow *that = const_cast<QWaylandXCompositeGLXWindow *>(this);
- that->mContext = new QWaylandXCompositeGLXContext(mGlxIntegration,that);
+ QWaylandWindow::setGeometry(rect);
+
+ if (m_xWindow) {
+ delete m_buffer;
+
+ XDestroyWindow(m_glxIntegration->xDisplay(), m_xWindow);
+ m_xWindow = 0;
}
- return mContext;
}
-void QWaylandXCompositeGLXWindow::setGeometry(const QRect &rect)
+Window QWaylandXCompositeGLXWindow::xWindow() const
{
- QWaylandWindow::setGeometry(rect);
+ if (!m_xWindow)
+ const_cast<QWaylandXCompositeGLXWindow *>(this)->createSurface();
- if (mContext) {
- mContext->geometryChanged();
+ return m_xWindow;
+}
+
+void QWaylandXCompositeGLXWindow::waitForSync()
+{
+ wl_display_sync_callback(m_glxIntegration->waylandDisplay()->wl_display(),
+ QWaylandXCompositeGLXWindow::sync_function,
+ this);
+ m_waitingForSync= true;
+ wl_display_sync(m_glxIntegration->waylandDisplay()->wl_display(), 0);
+ m_glxIntegration->waylandDisplay()->flushRequests();
+ while (m_waitingForSync)
+ m_glxIntegration->waylandDisplay()->readEvents();
+}
+
+
+void QWaylandXCompositeGLXWindow::createSurface()
+{
+ QSize size(geometry().size());
+ if (size.isEmpty()) {
+ //QGLWidget wants a context for a window without geometry
+ size = QSize(1,1);
}
+
+ if (!m_glxIntegration->xDisplay()) {
+ qWarning("XCompositeGLXWindow: X display still null?!");
+ return;
+ }
+
+ XVisualInfo *visualInfo = glXGetVisualFromFBConfig(m_glxIntegration->xDisplay(), m_config);
+ Colormap cmap = XCreateColormap(m_glxIntegration->xDisplay(), m_glxIntegration->rootWindow(),
+ visualInfo->visual, AllocNone);
+
+ XSetWindowAttributes a;
+ a.background_pixel = WhitePixel(m_glxIntegration->xDisplay(), m_glxIntegration->screen());
+ a.border_pixel = BlackPixel(m_glxIntegration->xDisplay(), m_glxIntegration->screen());
+ a.colormap = cmap;
+ m_xWindow = XCreateWindow(m_glxIntegration->xDisplay(), m_glxIntegration->rootWindow(),0, 0, size.width(), size.height(),
+ 0, visualInfo->depth, InputOutput, visualInfo->visual,
+ CWBackPixel|CWBorderPixel|CWColormap, &a);
+
+ XCompositeRedirectWindow(m_glxIntegration->xDisplay(), m_xWindow, CompositeRedirectManual);
+ XMapWindow(m_glxIntegration->xDisplay(), m_xWindow);
+
+ XSync(m_glxIntegration->xDisplay(), False);
+ m_buffer = new QWaylandXCompositeBuffer(m_glxIntegration->waylandXComposite(),
+ (uint32_t)m_xWindow,
+ size,
+ m_glxIntegration->waylandDisplay()->argbVisual());
+ attach(m_buffer);
+ waitForSync();
+}
+
+void QWaylandXCompositeGLXWindow::sync_function(void *data)
+{
+ QWaylandXCompositeGLXWindow *that = static_cast<QWaylandXCompositeGLXWindow *>(data);
+ that->m_waitingForSync = false;
}
+
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.h
index 8808f2d482..acf6c8e63e 100644
--- a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.h
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.h
@@ -46,20 +46,34 @@
#include "qwaylandxcompositeglxintegration.h"
#include "qwaylandxcompositeglxcontext.h"
+#include <QtCore/QWaitCondition>
+
+#include "qwaylandbuffer.h"
+
class QWaylandXCompositeGLXWindow : public QWaylandWindow
{
public:
- QWaylandXCompositeGLXWindow(QWidget *window, QWaylandXCompositeGLXIntegration *glxIntegration);
+ QWaylandXCompositeGLXWindow(QWindow *window, QWaylandXCompositeGLXIntegration *glxIntegration);
WindowType windowType() const;
- QPlatformGLContext *glContext() const;
-
void setGeometry(const QRect &rect);
+ Window xWindow() const;
+
private:
- QWaylandXCompositeGLXIntegration *mGlxIntegration;
- QWaylandXCompositeGLXContext *mContext;
+ void createSurface();
+
+ QWaylandXCompositeGLXIntegration *m_glxIntegration;
+
+ Window m_xWindow;
+ GLXFBConfig m_config;
+
+ QWaylandBuffer *m_buffer;
+
+ void waitForSync();
+ bool m_waitingForSync;
+ static void sync_function(void *data);
};
#endif // QWAYLANDXCOMPOSITEGLXWINDOW_H
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/xcomposite_glx.pri b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/xcomposite_glx.pri
index 43295e91e7..bbd6c12e42 100644
--- a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/xcomposite_glx.pri
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/xcomposite_glx.pri
@@ -1,5 +1,4 @@
include (../xcomposite_share/xcomposite_share.pri)
-include (../../../glxconvenience/glxconvenience.pri)
LIBS += -lXcomposite
SOURCES += \
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.cpp
index 7d309ef877..f4bacc3c1f 100644
--- a/src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.cpp
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.cpp
@@ -42,6 +42,7 @@
#include "qwaylandxcompositebuffer.h"
#include "wayland-client.h"
+#include "wayland-xcomposite-client-protocol.h"
QWaylandXCompositeBuffer::QWaylandXCompositeBuffer(wl_xcomposite *xcomposite, uint32_t window, const QSize &size, wl_visual *visual)
:mSize(size)
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.h
index cbd40ad381..02176d7850 100644
--- a/src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.h
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.h
@@ -43,8 +43,10 @@
#define QWAYLANDXCOMPOSITEBUFFER_H
#include "qwaylandbuffer.h"
+#include <stdint.h>
-#include "wayland-xcomposite-client-protocol.h"
+struct wl_xcomposite;
+struct wl_visual;
class QWaylandXCompositeBuffer : public QWaylandBuffer
{
diff --git a/src/plugins/platforms/wayland/main.cpp b/src/plugins/platforms/wayland/main.cpp
index ba365ca3a1..e4d420d68a 100644
--- a/src/plugins/platforms/wayland/main.cpp
+++ b/src/plugins/platforms/wayland/main.cpp
@@ -54,8 +54,7 @@ public:
QStringList QWaylandIntegrationPlugin::keys() const
{
QStringList list;
- list << "Wayland";
- list << "WaylandGL";
+ list << "wayland";
return list;
}
@@ -63,9 +62,7 @@ QPlatformIntegration *QWaylandIntegrationPlugin::create(const QString& system, c
{
Q_UNUSED(paramList);
if (system.toLower() == "wayland")
- return new QWaylandIntegration;
- if (system.toLower() == "waylandgl")
- return new QWaylandIntegration(true);
+ return new QWaylandIntegration();
return 0;
}
diff --git a/src/plugins/platforms/wayland/qwaylandclipboard.cpp b/src/plugins/platforms/wayland/qwaylandclipboard.cpp
index 45f0abc00a..f90d1a9802 100644
--- a/src/plugins/platforms/wayland/qwaylandclipboard.cpp
+++ b/src/plugins/platforms/wayland/qwaylandclipboard.cpp
@@ -44,7 +44,7 @@
#include "qwaylandinputdevice.h"
#include "qwaylandmime.h"
#include <QtGui/QPlatformNativeInterface>
-#include <QtGui/QApplication>
+#include <QtGui/QGuiApplication>
#include <QtCore/QMimeData>
#include <QtCore/QStringList>
#include <QtCore/QFile>
diff --git a/src/plugins/platforms/wayland/qwaylandcursor.cpp b/src/plugins/platforms/wayland/qwaylandcursor.cpp
index 87b846cefb..bbbab6dca7 100644
--- a/src/plugins/platforms/wayland/qwaylandcursor.cpp
+++ b/src/plugins/platforms/wayland/qwaylandcursor.cpp
@@ -43,10 +43,11 @@
#include "qwaylanddisplay.h"
#include "qwaylandinputdevice.h"
-#include "qwaylandshmsurface.h"
#include "qwaylandscreen.h"
+#include "qwaylandshmbackingstore.h"
#include <QtGui/QImageReader>
+#include <QDebug>
#define DATADIR "/usr/share"
@@ -108,14 +109,15 @@ QWaylandCursor::QWaylandCursor(QWaylandScreen *screen)
{
}
-void QWaylandCursor::changeCursor(QCursor *cursor, QWidget *widget)
+void QWaylandCursor::changeCursor(QCursor *cursor, QWindow *window)
{
const struct pointer_image *p;
- if (widget == NULL)
+ if (window == NULL)
return;
p = NULL;
+ bool isBitmap = false;
switch (cursor->shape()) {
case Qt::ArrowCursor:
@@ -152,32 +154,53 @@ void QWaylandCursor::changeCursor(QCursor *cursor, QWidget *widget)
p = &pointer_images[cursor->shape()];
break;
- default:
case Qt::BitmapCursor:
+ isBitmap = true;
+ break;
+
+ default:
break;
}
- if (!p) {
+ if (!p && !isBitmap) {
p = &pointer_images[0];
qWarning("unhandled cursor %d", cursor->shape());
}
- QImageReader reader(p->filename);
-
- if (!reader.canRead())
- return;
-
- if (mBuffer == NULL || mBuffer->size() != reader.size()) {
- if (mBuffer)
+ if (isBitmap && !cursor->pixmap().isNull()) {
+ setupPixmapCursor(cursor);
+ } else if (isBitmap && cursor->bitmap()) {
+ qWarning("unsupported QBitmap cursor");
+ } else {
+ QImageReader reader(p->filename);
+ if (!reader.canRead())
+ return;
+ if (mBuffer == NULL || mBuffer->size() != reader.size()) {
delete mBuffer;
+ mBuffer = new QWaylandShmBuffer(mDisplay, reader.size(),
+ QImage::Format_ARGB32);
+ }
+ reader.read(mBuffer->image());
+ mDisplay->setCursor(mBuffer, p->hotspot_x, p->hotspot_y);
+ }
+}
- mBuffer = new QWaylandShmBuffer(mDisplay, reader.size(),
+void QWaylandCursor::setupPixmapCursor(QCursor *cursor)
+{
+ if (!cursor) {
+ delete mBuffer;
+ mBuffer = 0;
+ return;
+ }
+ if (!mBuffer || mBuffer->size() != cursor->pixmap().size()) {
+ delete mBuffer;
+ mBuffer = new QWaylandShmBuffer(mDisplay, cursor->pixmap().size(),
QImage::Format_ARGB32);
}
-
- reader.read(mBuffer->image());
-
- mDisplay->setCursor(mBuffer, p->hotspot_x, p->hotspot_y);
+ QImage src = cursor->pixmap().toImage().convertToFormat(QImage::Format_ARGB32);
+ for (int y = 0; y < src.height(); ++y)
+ qMemCopy(mBuffer->image()->scanLine(y), src.scanLine(y), src.bytesPerLine());
+ mDisplay->setCursor(mBuffer, cursor->hotSpot().x(), cursor->hotSpot().y());
}
void QWaylandDisplay::setCursor(QWaylandBuffer *buffer, int32_t x, int32_t y)
@@ -189,3 +212,19 @@ void QWaylandDisplay::setCursor(QWaylandBuffer *buffer, int32_t x, int32_t y)
inputDevice->attach(buffer, x, y);
}
}
+
+void QWaylandCursor::pointerEvent(const QMouseEvent &event)
+{
+ mLastPos = event.globalPos();
+}
+
+QPoint QWaylandCursor::pos() const
+{
+ return mLastPos;
+}
+
+void QWaylandCursor::setPos(const QPoint &pos)
+{
+ Q_UNUSED(pos);
+ qWarning() << "QWaylandCursor::setPos: not implemented";
+}
diff --git a/src/plugins/platforms/wayland/qwaylandcursor.h b/src/plugins/platforms/wayland/qwaylandcursor.h
index 236bfc56ee..8753aa5698 100644
--- a/src/plugins/platforms/wayland/qwaylandcursor.h
+++ b/src/plugins/platforms/wayland/qwaylandcursor.h
@@ -48,13 +48,23 @@ class QWaylandShmBuffer;
class QWaylandDisplay;
class QWaylandScreen;
-class QWaylandCursor : QPlatformCursor {
+class QWaylandCursor : public QPlatformCursor
+{
public:
QWaylandCursor(QWaylandScreen *screen);
- void changeCursor(QCursor *cursor, QWidget *widget);
+ void changeCursor(QCursor *cursor, QWindow *window);
+ void pointerEvent(const QMouseEvent &event);
+ QPoint pos() const;
+ void setPos(const QPoint &pos);
+
+ void setupPixmapCursor(QCursor *cursor);
+
QWaylandShmBuffer *mBuffer;
QWaylandDisplay *mDisplay;
+
+private:
+ QPoint mLastPos;
};
#endif // QWAYLANDCURSOR_H
diff --git a/src/plugins/platforms/wayland/qwaylanddisplay.cpp b/src/plugins/platforms/wayland/qwaylanddisplay.cpp
index 26e0e8ebeb..588096933c 100644
--- a/src/plugins/platforms/wayland/qwaylanddisplay.cpp
+++ b/src/plugins/platforms/wayland/qwaylanddisplay.cpp
@@ -46,6 +46,7 @@
#include "qwaylandcursor.h"
#include "qwaylandinputdevice.h"
#include "qwaylandclipboard.h"
+#include "qwaylanddnd.h"
#ifdef QT_WAYLAND_GL_SUPPORT
#include "gl_integration/qwaylandglintegration.h"
@@ -56,8 +57,7 @@
#endif
#include <QtCore/QAbstractEventDispatcher>
-#include <QtGui/QApplication>
-#include <QtGui/private/qapplication_p.h>
+#include <QtGui/private/qguiapplication_p.h>
#include <unistd.h>
#include <fcntl.h>
@@ -142,6 +142,13 @@ QWaylandDisplay::QWaylandDisplay(void)
wl_display_add_global_listener(mDisplay, QWaylandDisplay::displayHandleGlobal, this);
+ mFd = wl_display_get_fd(mDisplay, sourceUpdate, this);
+ QAbstractEventDispatcher *dispatcher = QGuiApplicationPrivate::eventDispatcher;
+ connect(dispatcher, SIGNAL(aboutToBlock()), this, SLOT(flushRequests()));
+
+ mReadNotifier = new QSocketNotifier(mFd, QSocketNotifier::Read, this);
+ connect(mReadNotifier, SIGNAL(activated(int)), this, SLOT(readEvents()));
+
#ifdef QT_WAYLAND_GL_SUPPORT
mEglIntegration = QWaylandGLIntegration::createGLIntegration(this);
#endif
@@ -156,13 +163,6 @@ QWaylandDisplay::QWaylandDisplay(void)
mEglIntegration->initialize();
#endif
- connect(QAbstractEventDispatcher::instance(), SIGNAL(aboutToBlock()), this, SLOT(flushRequests()));
-
- mFd = wl_display_get_fd(mDisplay, sourceUpdate, this);
-
- mReadNotifier = new QSocketNotifier(mFd, QSocketNotifier::Read, this);
- connect(mReadNotifier, SIGNAL(activated(int)), this, SLOT(readEvents()));
-
waitForScreens();
}
@@ -313,6 +313,8 @@ void QWaylandDisplay::displayHandleGlobal(uint32_t id,
mInputDevices.append(inputDevice);
} else if (interface == "wl_selection_offer") {
QWaylandClipboard::instance(display)->createSelectionOffer(id);
+ } else if (interface == "wl_drag_offer") {
+ QWaylandDrag::instance(display)->createDragOffer(id);
}
}
diff --git a/src/plugins/platforms/wayland/qwaylanddisplay.h b/src/plugins/platforms/wayland/qwaylanddisplay.h
index 4dff24d086..2b7f33f4f6 100644
--- a/src/plugins/platforms/wayland/qwaylanddisplay.h
+++ b/src/plugins/platforms/wayland/qwaylanddisplay.h
@@ -49,6 +49,7 @@
#include <wayland-client.h>
+class QAbstractEventDispatcher;
class QWaylandInputDevice;
class QSocketNotifier;
class QWaylandBuffer;
@@ -142,6 +143,7 @@ private:
static void handleVisual(void *data,
struct wl_compositor *compositor,
uint32_t id, uint32_t token);
+
#ifdef QT_WAYLAND_GL_SUPPORT
QWaylandGLIntegration *mEglIntegration;
#endif
diff --git a/src/plugins/platforms/wayland/qwaylanddnd.cpp b/src/plugins/platforms/wayland/qwaylanddnd.cpp
new file mode 100644
index 0000000000..5368daaf63
--- /dev/null
+++ b/src/plugins/platforms/wayland/qwaylanddnd.cpp
@@ -0,0 +1,423 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwaylanddnd.h"
+#include "qwaylandinputdevice.h"
+#include <QStringList>
+#include <QFile>
+#include <QtGui/private/qdnd_p.h>
+#include <QGuiApplication>
+#include <QSocketNotifier>
+#include <sys/time.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <QDebug>
+
+#include <QPlatformCursor>
+#include "qwaylandcursor.h"
+
+class QWaylandDragWrapper
+{
+public:
+ QWaylandDragWrapper(QWaylandDisplay *display, QMimeData *data);
+ ~QWaylandDragWrapper();
+ QMimeData *mimeData() const { return mData; }
+
+private:
+ static void target(void *data, wl_drag *drag, const char *mimeType);
+ static void finish(void *data, wl_drag *drag, int fd);
+ static void reject(void *data, wl_drag *drag);
+ static const wl_drag_listener dragListener;
+
+ QWaylandDisplay *mDisplay;
+ wl_drag *mDrag;
+ QMimeData *mData;
+ QString mAcceptedType;
+};
+
+class QWaylandDragOfferWrapper
+{
+public:
+ QWaylandDragOfferWrapper(QWaylandDisplay *display, QMimeData *data, uint32_t id);
+ ~QWaylandDragOfferWrapper();
+
+private:
+ static void offer(void *data, struct wl_drag_offer *offer, const char *mimeType);
+ static void pointerFocus(void *data, struct wl_drag_offer *offer, uint32_t time,
+ wl_surface *surface,
+ int32_t x, int32_t y,
+ int32_t surfaceX, int32_t surfaceY);
+ static void motion(void *data, struct wl_drag_offer *offer, uint32_t time,
+ int32_t x, int32_t y,
+ int32_t surfaceX, int32_t surfaceY);
+ static void drop(void *data, struct wl_drag_offer *offer);
+ static const wl_drag_offer_listener dragOfferListener;
+
+ void sendEventToWindow(struct wl_drag_offer *offer, uint32_t time,
+ wl_surface *surface, const QPoint &pos);
+
+ QWaylandDisplay *mDisplay;
+ QMimeData *mData;
+ struct wl_drag_offer *mOffer;
+ QMimeData mOfferedTypes; // no data in this one, just the formats
+ wl_surface *mFocusSurface;
+ bool mAccepted;
+ QPoint mLastEventPos;
+ friend class QWaylandDrag;
+};
+
+static QWaylandDrag *dnd = 0;
+
+QWaylandDrag *QWaylandDrag::instance(QWaylandDisplay *display)
+{
+ if (!dnd)
+ dnd = new QWaylandDrag(display);
+ return dnd;
+}
+
+QWaylandDrag::QWaylandDrag(QWaylandDisplay *display)
+ : mDisplay(display), mDropData(0), mCurrentDrag(0), mCurrentOffer(0)
+{
+ mDropData = new QMimeData;
+}
+
+QWaylandDrag::~QWaylandDrag()
+{
+ delete mCurrentDrag;
+ delete mCurrentOffer;
+ delete mDropData;
+}
+
+QMimeData *QWaylandDrag::platformDropData()
+{
+ return mDropData;
+}
+
+static void showDragPixmap(bool show)
+{
+ QCursor c(QDragManager::self()->object->pixmap());
+ QList<QWeakPointer<QPlatformCursor> > cursors = QPlatformCursorPrivate::getInstances();
+ foreach (QWeakPointer<QPlatformCursor> cursor, cursors)
+ if (cursor)
+ static_cast<QWaylandCursor *>(cursor.data())->setupPixmapCursor(show ? &c : 0);
+}
+
+
+QWaylandDragWrapper::QWaylandDragWrapper(QWaylandDisplay *display, QMimeData *data)
+ : mDisplay(display), mDrag(0), mData(data)
+{
+ QWaylandWindow *w = mDisplay->inputDevices().at(0)->pointerFocus();
+ if (!w) {
+ qWarning("QWaylandDragWrapper: No window with pointer focus?!");
+ return;
+ }
+ qDebug() << "QWaylandDragWrapper" << data->formats();
+ struct wl_shell *shell = display->wl_shell();
+ mDrag = wl_shell_create_drag(shell);
+ wl_drag_add_listener(mDrag, &dragListener, this);
+ foreach (const QString &format, data->formats())
+ wl_drag_offer(mDrag, format.toLatin1().constData());
+ struct timeval tv;
+ gettimeofday(&tv, 0);
+ wl_drag_activate(mDrag,
+ w->wl_surface(),
+ display->inputDevices().at(0)->wl_input_device(),
+ tv.tv_sec * 1000 + tv.tv_usec / 1000);
+ showDragPixmap(true);
+}
+
+QWaylandDragWrapper::~QWaylandDragWrapper()
+{
+ QWaylandDrag *dragHandler = QWaylandDrag::instance(mDisplay);
+ if (dragHandler->mCurrentDrag == this)
+ dragHandler->mCurrentDrag = 0;
+ wl_drag_destroy(mDrag);
+}
+
+const wl_drag_listener QWaylandDragWrapper::dragListener = {
+ QWaylandDragWrapper::target,
+ QWaylandDragWrapper::finish,
+ QWaylandDragWrapper::reject
+};
+
+void QWaylandDragWrapper::target(void *data, wl_drag *drag, const char *mimeType)
+{
+ Q_UNUSED(drag);
+ QWaylandDragWrapper *self = static_cast<QWaylandDragWrapper *>(data);
+ self->mAcceptedType = mimeType ? QString::fromLatin1(mimeType) : QString();
+ qDebug() << "target" << self->mAcceptedType;
+ QDragManager *manager = QDragManager::self();
+ if (mimeType)
+ manager->global_accepted_action = manager->defaultAction(manager->possible_actions,
+ QGuiApplication::keyboardModifiers());
+ else
+ manager->global_accepted_action = Qt::IgnoreAction;
+}
+
+void QWaylandDragWrapper::finish(void *data, wl_drag *drag, int fd)
+{
+ Q_UNUSED(drag);
+ QWaylandDragWrapper *self = static_cast<QWaylandDragWrapper *>(data);
+ qDebug() << "finish" << self->mAcceptedType;
+ if (self->mAcceptedType.isEmpty())
+ return; // no drag target was valid when the drag finished
+ QByteArray content = self->mData->data(self->mAcceptedType);
+ if (!content.isEmpty()) {
+ QFile f;
+ if (f.open(fd, QIODevice::WriteOnly))
+ f.write(content);
+ }
+ close(fd);
+ // Drag finished on source side with drop.
+
+ QDragManager::self()->stopDrag();
+ showDragPixmap(false);
+ delete self;
+ qDebug() << " *** DRAG OVER WITH DROP";
+}
+
+void QWaylandDragWrapper::reject(void *data, wl_drag *drag)
+{
+ Q_UNUSED(drag);
+ QWaylandDragWrapper *self = static_cast<QWaylandDragWrapper *>(data);
+ self->mAcceptedType = QString();
+ qDebug() << "reject";
+ QDragManager::self()->global_accepted_action = Qt::IgnoreAction;
+}
+
+
+QWaylandDragOfferWrapper::QWaylandDragOfferWrapper(QWaylandDisplay *display,
+ QMimeData *data,
+ uint32_t id)
+ : mDisplay(display), mData(data), mOffer(0), mFocusSurface(0),
+ mAccepted(false)
+{
+ mOffer = wl_drag_offer_create(mDisplay->wl_display(), id, 1);
+ wl_drag_offer_add_listener(mOffer, &dragOfferListener, this);
+}
+
+QWaylandDragOfferWrapper::~QWaylandDragOfferWrapper()
+{
+ QWaylandDrag *dragHandler = QWaylandDrag::instance(mDisplay);
+ if (dragHandler->mCurrentOffer == this)
+ dragHandler->mCurrentOffer = 0;
+ wl_drag_offer_destroy(mOffer);
+}
+
+const wl_drag_offer_listener QWaylandDragOfferWrapper::dragOfferListener = {
+ QWaylandDragOfferWrapper::offer,
+ QWaylandDragOfferWrapper::pointerFocus,
+ QWaylandDragOfferWrapper::motion,
+ QWaylandDragOfferWrapper::drop
+};
+
+void QWaylandDragOfferWrapper::offer(void *data, struct wl_drag_offer *offer, const char *mimeType)
+{
+ // Called for each type before pointerFocus.
+ Q_UNUSED(offer);
+ QWaylandDragOfferWrapper *self = static_cast<QWaylandDragOfferWrapper *>(data);
+ self->mOfferedTypes.setData(QString::fromLatin1(mimeType), QByteArray());
+}
+
+void QWaylandDragOfferWrapper::pointerFocus(void *data, struct wl_drag_offer *offer, uint32_t time,
+ wl_surface *surface,
+ int32_t x, int32_t y,
+ int32_t surfaceX, int32_t surfaceY)
+{
+ qDebug() << "pointerFocus" << surface << x << y << surfaceX << surfaceY;
+ QWaylandDragOfferWrapper *self = static_cast<QWaylandDragOfferWrapper *>(data);
+ QWaylandDrag *mgr = QWaylandDrag::instance(self->mDisplay);
+
+ if (!surface) {
+ if (self->mFocusSurface) {
+ // This is a DragLeave.
+ QWindow *window = static_cast<QWaylandWindow *>(
+ wl_surface_get_user_data(self->mFocusSurface))->window();
+ QWindowSystemInterface::handleDrag(window, 0, QPoint());
+ if (self->mAccepted) {
+ wl_drag_offer_reject(offer);
+ self->mAccepted = false;
+ }
+ if (!mgr->mCurrentDrag) // no drag -> this is not the source side -> offer can be destroyed
+ delete mgr->mCurrentOffer;
+ } else {
+ // Drag finished on source side without drop.
+ QDragManager::self()->stopDrag();
+ showDragPixmap(false);
+ delete mgr->mCurrentDrag;
+ qDebug() << " *** DRAG OVER WITHOUT DROP";
+ }
+ }
+
+ self->mFocusSurface = surface;
+
+ // This is a DragMove or DragEnter+DragMove.
+ if (surface)
+ self->sendEventToWindow(offer, time, surface, QPoint(surfaceX, surfaceY));
+}
+
+void QWaylandDragOfferWrapper::motion(void *data, struct wl_drag_offer *offer, uint32_t time,
+ int32_t x, int32_t y,
+ int32_t surfaceX, int32_t surfaceY)
+{
+ Q_UNUSED(x);
+ Q_UNUSED(y);
+ QWaylandDragOfferWrapper *self = static_cast<QWaylandDragOfferWrapper *>(data);
+ if (!self->mFocusSurface)
+ return;
+// qDebug() << "motion" << self->mFocusSurface << x << y << surfaceX << surfaceY;
+ self->sendEventToWindow(offer, time, self->mFocusSurface, QPoint(surfaceX, surfaceY));
+}
+
+void QWaylandDragOfferWrapper::sendEventToWindow(struct wl_drag_offer *offer, uint32_t time,
+ wl_surface *surface, const QPoint &pos)
+{
+ QWindow *window = static_cast<QWaylandWindow *>(wl_surface_get_user_data(surface))->window();
+ Qt::DropAction action = QWindowSystemInterface::handleDrag(window, &mOfferedTypes, pos);
+ bool accepted = (action != Qt::IgnoreAction && !mOfferedTypes.formats().isEmpty());
+ if (accepted != mAccepted) {
+ mAccepted = accepted;
+ if (mAccepted) {
+ // What can we do, just accept the first type...
+ QByteArray ba = mOfferedTypes.formats().first().toLatin1();
+ qDebug() << "wl_drag_offer_accept" << ba;
+ wl_drag_offer_accept(offer, time, ba.constData());
+ } else {
+ qDebug() << "wl_drag_offer_reject";
+ wl_drag_offer_reject(offer);
+ }
+ }
+ mLastEventPos = pos;
+}
+
+void QWaylandDragOfferWrapper::drop(void *data, struct wl_drag_offer *offer)
+{
+ QWaylandDragOfferWrapper *self = static_cast<QWaylandDragOfferWrapper *>(data);
+ if (!self->mAccepted) {
+ wl_drag_offer_reject(offer);
+ return;
+ }
+
+ QWaylandDrag *mgr = QWaylandDrag::instance(self->mDisplay);
+ QMimeData *mimeData = QWaylandDrag::instance(self->mDisplay)->platformDropData();
+ mimeData->clear();
+ if (mgr->mCurrentDrag) { // means this offer is the client's own
+ QMimeData *localData = mgr->mCurrentDrag->mimeData();
+ foreach (const QString &format, localData->formats())
+ mimeData->setData(format, localData->data(format));
+ QWindow *window = static_cast<QWaylandWindow *>(
+ wl_surface_get_user_data(self->mFocusSurface))->window();
+ QWindowSystemInterface::handleDrop(window, mimeData, self->mLastEventPos);
+ // Drag finished with drop (source == target).
+ QDragManager::self()->stopDrag();
+ showDragPixmap(false);
+ delete mgr->mCurrentOffer;
+ qDebug() << " *** DRAG OVER WITH DROP, SOURCE == TARGET";
+ } else {
+ // ### TODO
+ // This is a bit broken: The QMimeData will only contain the data for
+ // the first type. The Wayland protocol and QDropEvents/QMimeData do not
+ // match perfectly at the moment.
+ QString format = self->mOfferedTypes.formats().first();
+ QByteArray mimeTypeBa = format.toLatin1();
+ int pipefd[2];
+ if (pipe(pipefd) == -1) {
+ qWarning("QWaylandDragOfferWrapper: pipe() failed");
+ return;
+ }
+ fcntl(pipefd[0], F_SETFL, fcntl(pipefd[0], F_GETFL, 0) | O_NONBLOCK);
+ wl_drag_offer_receive(offer, pipefd[1]);
+ mgr->mPipeData.clear();
+ mgr->mMimeFormat = format;
+ mgr->mPipeWriteEnd = pipefd[1];
+ mgr->mPipeWatcher = new QSocketNotifier(pipefd[0], QSocketNotifier::Read);
+ QObject::connect(mgr->mPipeWatcher, SIGNAL(activated(int)), mgr, SLOT(pipeReadable(int)));
+ }
+}
+
+
+void QWaylandDrag::pipeReadable(int fd)
+{
+ if (mPipeWriteEnd) {
+ close(mPipeWriteEnd);
+ mPipeWriteEnd = 0;
+ }
+ char buf[256];
+ int n;
+ while ((n = read(fd, &buf, sizeof buf)) > 0 || errno == EINTR)
+ if (n > 0)
+ mPipeData.append(buf, n);
+ if (n == -1 && (errno == EAGAIN || errno == EWOULDBLOCK))
+ return;
+ delete mPipeWatcher;
+ close(fd);
+
+ QMimeData *mimeData = platformDropData();
+ mimeData->setData(mMimeFormat, mPipeData);
+ foreach (const QString &format, mimeData->formats())
+ qDebug() << " got type" << format << "with data" << mimeData->data(format);
+
+ QWindow *window = static_cast<QWaylandWindow *>(
+ wl_surface_get_user_data(mCurrentOffer->mFocusSurface))->window();
+ QWindowSystemInterface::handleDrop(window, mimeData, mCurrentOffer->mLastEventPos);
+
+ // Drag finished on target side with drop.
+ delete mCurrentOffer;
+ qDebug() << " *** DRAG OVER ON TARGET WITH DROP";
+}
+
+void QWaylandDrag::createDragOffer(uint32_t id)
+{
+ delete mCurrentOffer;
+ mCurrentOffer = new QWaylandDragOfferWrapper(mDisplay, mDropData, id);
+}
+
+void QWaylandDrag::startDrag()
+{
+ QDragManager *manager = QDragManager::self();
+
+ // No need for the traditional desktop-oriented event handling in QDragManager.
+ manager->unmanageEvents();
+
+ delete mCurrentDrag;
+ mCurrentDrag = new QWaylandDragWrapper(mDisplay, manager->dropData());
+}
diff --git a/src/plugins/platforms/wayland/qwaylanddnd.h b/src/plugins/platforms/wayland/qwaylanddnd.h
new file mode 100644
index 0000000000..ebafd960ec
--- /dev/null
+++ b/src/plugins/platforms/wayland/qwaylanddnd.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDDND_H
+#define QWAYLANDDND_H
+
+#include <QtGui/QPlatformDrag>
+#include <QtCore/QMimeData>
+#include "qwaylanddisplay.h"
+
+class QWaylandDragWrapper;
+class QWaylandDragOfferWrapper;
+class QSocketNotifier;
+
+class QWaylandDrag : public QObject, public QPlatformDrag
+{
+ Q_OBJECT
+
+public:
+ static QWaylandDrag *instance(QWaylandDisplay *display);
+ ~QWaylandDrag();
+ void createDragOffer(uint32_t id);
+
+ QMimeData *platformDropData();
+ void startDrag();
+ void move(const QMouseEvent *) { }
+ void drop(const QMouseEvent *) { }
+ void cancel() { }
+
+private slots:
+ void pipeReadable(int fd);
+
+private:
+ QWaylandDrag(QWaylandDisplay *display);
+
+ QWaylandDisplay *mDisplay;
+ QMimeData *mDropData;
+ QWaylandDragWrapper *mCurrentDrag;
+ QWaylandDragOfferWrapper *mCurrentOffer;
+ int mPipeWriteEnd;
+ QSocketNotifier *mPipeWatcher;
+ QByteArray mPipeData;
+ QString mMimeFormat;
+ friend class QWaylandDragWrapper;
+ friend class QWaylandDragOfferWrapper;
+};
+
+#endif // QWAYLANDDND_H
diff --git a/src/plugins/platforms/wayland/qwaylandinputdevice.cpp b/src/plugins/platforms/wayland/qwaylandinputdevice.cpp
index 3c9afafada..c1e2325766 100644
--- a/src/plugins/platforms/wayland/qwaylandinputdevice.cpp
+++ b/src/plugins/platforms/wayland/qwaylandinputdevice.cpp
@@ -113,7 +113,7 @@ void QWaylandInputDevice::inputHandleMotion(void *data,
inputDevice->mSurfacePos = QPoint(surface_x, surface_y);
inputDevice->mGlobalPos = QPoint(x, y);
inputDevice->mTime = time;
- QWindowSystemInterface::handleMouseEvent(window->widget(),
+ QWindowSystemInterface::handleMouseEvent(window->window(),
time,
inputDevice->mSurfacePos,
inputDevice->mGlobalPos,
@@ -155,7 +155,7 @@ void QWaylandInputDevice::inputHandleButton(void *data,
inputDevice->mButtons &= ~qt_button;
inputDevice->mTime = time;
- QWindowSystemInterface::handleMouseEvent(window->widget(),
+ QWindowSystemInterface::handleMouseEvent(window->window(),
time,
inputDevice->mSurfacePos,
inputDevice->mGlobalPos,
@@ -272,7 +272,7 @@ void QWaylandInputDevice::inputHandleKey(void *data,
sym = translateKey(sym, s, sizeof s);
if (window) {
- QWindowSystemInterface::handleKeyEvent(window->widget(),
+ QWindowSystemInterface::handleKeyEvent(window->window(),
time, type, sym,
inputDevice->mModifiers,
QString::fromLatin1(s));
@@ -295,13 +295,13 @@ void QWaylandInputDevice::inputHandlePointerFocus(void *data,
if (inputDevice->mPointerFocus) {
window = inputDevice->mPointerFocus;
- QWindowSystemInterface::handleLeaveEvent(window->widget());
+ QWindowSystemInterface::handleLeaveEvent(window->window());
inputDevice->mPointerFocus = NULL;
}
if (surface) {
window = (QWaylandWindow *) wl_surface_get_user_data(surface);
- QWindowSystemInterface::handleEnterEvent(window->widget());
+ QWindowSystemInterface::handleEnterEvent(window->window());
inputDevice->mPointerFocus = window;
}
@@ -333,7 +333,7 @@ void QWaylandInputDevice::inputHandleKeyboardFocus(void *data,
if (surface) {
window = (QWaylandWindow *) wl_surface_get_user_data(surface);
inputDevice->mKeyboardFocus = window;
- QWindowSystemInterface::handleWindowActivated(window->widget());
+ QWindowSystemInterface::handleWindowActivated(window->window());
} else {
inputDevice->mKeyboardFocus = NULL;
QWindowSystemInterface::handleWindowActivated(0);
diff --git a/src/plugins/platforms/wayland/qwaylandinputdevice.h b/src/plugins/platforms/wayland/qwaylandinputdevice.h
index 008ecf144d..05ebe05969 100644
--- a/src/plugins/platforms/wayland/qwaylandinputdevice.h
+++ b/src/plugins/platforms/wayland/qwaylandinputdevice.h
@@ -63,6 +63,7 @@ public:
void attach(QWaylandBuffer *buffer, int x, int y);
void handleWindowDestroyed(QWaylandWindow *window);
struct wl_input_device *wl_input_device() const { return mInputDevice; }
+ QWaylandWindow *pointerFocus() const { return mPointerFocus; }
private:
QWaylandDisplay *mQDisplay;
diff --git a/src/plugins/platforms/wayland/qwaylandintegration.cpp b/src/plugins/platforms/wayland/qwaylandintegration.cpp
index 5df71dc936..e17c2f8d95 100644
--- a/src/plugins/platforms/wayland/qwaylandintegration.cpp
+++ b/src/plugins/platforms/wayland/qwaylandintegration.cpp
@@ -42,30 +42,36 @@
#include "qwaylandintegration.h"
#include "qwaylanddisplay.h"
-#include "qwaylandshmsurface.h"
+#include "qwaylandshmbackingstore.h"
#include "qwaylandshmwindow.h"
#include "qwaylandnativeinterface.h"
#include "qwaylandclipboard.h"
+#include "qwaylanddnd.h"
-#include "qgenericunixfontdatabase.h"
+#include "QtPlatformSupport/private/qgenericunixfontdatabase_p.h"
+#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
+
+#include <QtGui/private/qguiapplication_p.h>
#include <QtGui/QWindowSystemInterface>
#include <QtGui/QPlatformCursor>
-#include <QtGui/QPlatformWindowFormat>
+#include <QtGui/QSurfaceFormat>
+#include <QtGui/QOpenGLContext>
-#include <QtGui/private/qpixmap_raster_p.h>
#ifdef QT_WAYLAND_GL_SUPPORT
#include "gl_integration/qwaylandglintegration.h"
-#include "gl_integration/qwaylandglwindowsurface.h"
-#include <QtOpenGL/private/qpixmapdata_gl_p.h>
#endif
-QWaylandIntegration::QWaylandIntegration(bool useOpenGL)
+QWaylandIntegration::QWaylandIntegration()
: mFontDb(new QGenericUnixFontDatabase())
- , mDisplay(new QWaylandDisplay())
- , mUseOpenGL(useOpenGL)
+ , mEventDispatcher(createUnixEventDispatcher())
, mNativeInterface(new QWaylandNativeInterface)
{
+ QGuiApplicationPrivate::instance()->setEventDispatcher(mEventDispatcher);
+ mDisplay = new QWaylandDisplay();
+
+ foreach (QPlatformScreen *screen, mDisplay->screens())
+ screenAdded(screen);
}
QPlatformNativeInterface * QWaylandIntegration::nativeInterface() const
@@ -73,68 +79,63 @@ QPlatformNativeInterface * QWaylandIntegration::nativeInterface() const
return mNativeInterface;
}
-QList<QPlatformScreen *>
-QWaylandIntegration::screens() const
-{
- return mDisplay->screens();
-}
-
bool QWaylandIntegration::hasCapability(QPlatformIntegration::Capability cap) const
{
switch (cap) {
case ThreadedPixmaps: return true;
- case OpenGL: return hasOpenGL();
+ case OpenGL:
+#ifdef QT_WAYLAND_GL_SUPPORT
+ return true;
+#else
+ return false;
+#endif
+ case ThreadedOpenGL:
+ return hasCapability(OpenGL);
default: return QPlatformIntegration::hasCapability(cap);
}
}
-QPixmapData *QWaylandIntegration::createPixmapData(QPixmapData::PixelType type) const
+QPlatformWindow *QWaylandIntegration::createPlatformWindow(QWindow *window) const
{
#ifdef QT_WAYLAND_GL_SUPPORT
- if (mUseOpenGL)
- return new QGLPixmapData(type);
+ if (window->surfaceType() == QWindow::OpenGLSurface)
+ return mDisplay->eglIntegration()->createEglWindow(window);
#endif
- return new QRasterPixmapData(type);
+ return new QWaylandShmWindow(window);
}
-QPlatformWindow *QWaylandIntegration::createPlatformWindow(QWidget *widget, WId winId) const
+QPlatformOpenGLContext *QWaylandIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
{
- Q_UNUSED(winId);
#ifdef QT_WAYLAND_GL_SUPPORT
- bool useOpenGL = mUseOpenGL || (widget->platformWindowFormat().windowApi() == QPlatformWindowFormat::OpenGL);
- if (useOpenGL)
- return mDisplay->eglIntegration()->createEglWindow(widget);
+ return mDisplay->eglIntegration()->createPlatformOpenGLContext(context->format(), context->shareHandle());
+#else
+ Q_UNUSED(glFormat);
+ Q_UNUSED(share);
+ return 0;
#endif
- return new QWaylandShmWindow(widget);
}
-QWindowSurface *QWaylandIntegration::createWindowSurface(QWidget *widget, WId winId) const
+QPlatformBackingStore *QWaylandIntegration::createPlatformBackingStore(QWindow *window) const
{
- Q_UNUSED(winId);
- Q_UNUSED(winId);
-#ifdef QT_WAYLAND_GL_SUPPORT
- bool useOpenGL = mUseOpenGL || (widget->platformWindowFormat().windowApi() == QPlatformWindowFormat::OpenGL);
- if (useOpenGL)
- return new QWaylandGLWindowSurface(widget);
-#endif
- return new QWaylandShmWindowSurface(widget);
+ return new QWaylandShmBackingStore(window);
}
-QPlatformFontDatabase *QWaylandIntegration::fontDatabase() const
+QAbstractEventDispatcher *QWaylandIntegration::guiThreadEventDispatcher() const
{
- return mFontDb;
+ return mEventDispatcher;
}
-bool QWaylandIntegration::hasOpenGL() const
+QPlatformFontDatabase *QWaylandIntegration::fontDatabase() const
{
-#ifdef QT_WAYLAND_GL_SUPPORT
- return true;
-#else
- return false;
-#endif
+ return mFontDb;
}
QPlatformClipboard *QWaylandIntegration::clipboard() const
{
return QWaylandClipboard::instance(mDisplay);
}
+
+QPlatformDrag *QWaylandIntegration::drag() const
+{
+ return QWaylandDrag::instance(mDisplay);
+}
diff --git a/src/plugins/platforms/wayland/qwaylandintegration.h b/src/plugins/platforms/wayland/qwaylandintegration.h
index f617d9697b..61e8559a7d 100644
--- a/src/plugins/platforms/wayland/qwaylandintegration.h
+++ b/src/plugins/platforms/wayland/qwaylandintegration.h
@@ -48,18 +48,19 @@ QT_BEGIN_NAMESPACE
class QWaylandBuffer;
class QWaylandDisplay;
+class QAbstractEventDispatcher;
class QWaylandIntegration : public QPlatformIntegration
{
public:
- QWaylandIntegration(bool useOpenGL = false);
+ QWaylandIntegration();
bool hasCapability(QPlatformIntegration::Capability cap) const;
- QPixmapData *createPixmapData(QPixmapData::PixelType type) const;
- QPlatformWindow *createPlatformWindow(QWidget *widget, WId winId) const;
- QWindowSurface *createWindowSurface(QWidget *widget, WId winId) const;
+ QPlatformWindow *createPlatformWindow(QWindow *window) const;
+ QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const;
+ QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const;
- QList<QPlatformScreen *> screens() const;
+ QAbstractEventDispatcher *guiThreadEventDispatcher() const;
QPlatformFontDatabase *fontDatabase() const;
@@ -67,12 +68,12 @@ public:
QPlatformClipboard *clipboard() const;
-private:
- bool hasOpenGL() const;
+ QPlatformDrag *drag() const;
+private:
QPlatformFontDatabase *mFontDb;
+ QAbstractEventDispatcher *mEventDispatcher;
QWaylandDisplay *mDisplay;
- bool mUseOpenGL;
QPlatformNativeInterface *mNativeInterface;
};
diff --git a/src/plugins/platforms/wayland/qwaylandnativeinterface.cpp b/src/plugins/platforms/wayland/qwaylandnativeinterface.cpp
index 17736968c6..d81fa350e9 100644
--- a/src/plugins/platforms/wayland/qwaylandnativeinterface.cpp
+++ b/src/plugins/platforms/wayland/qwaylandnativeinterface.cpp
@@ -42,34 +42,33 @@
#include "qwaylandnativeinterface.h"
#include "qwaylanddisplay.h"
#include "qwaylandwindow.h"
+#include <QtGui/private/qguiapplication_p.h>
+#include <QtGui/QScreen>
#include "windowmanager_integration/qwaylandwindowmanagerintegration.h"
-#include <QtGui/private/qapplication_p.h>
-#include <QDebug>
-
-void *QWaylandNativeInterface::nativeResourceForWidget(const QByteArray &resourceString, QWidget *widget)
+void *QWaylandNativeInterface::nativeResourceForWindow(const QByteArray &resourceString, QWindow *window)
{
QByteArray lowerCaseResource = resourceString.toLower();
if (lowerCaseResource == "display")
- return qPlatformScreenForWidget(widget)->display()->wl_display();
+ return qPlatformScreenForWindow(window)->display()->wl_display();
if (lowerCaseResource == "surface") {
- return ((QWaylandWindow *) widget->platformWindow())->wl_surface();
+ return ((QWaylandWindow *) window->handle())->wl_surface();
}
return NULL;
}
-QWaylandScreen * QWaylandNativeInterface::qPlatformScreenForWidget(QWidget *widget)
+QWaylandScreen * QWaylandNativeInterface::qPlatformScreenForWindow(QWindow *window)
{
QWaylandScreen *screen;
- if (widget) {
- screen = static_cast<QWaylandScreen *>(QPlatformScreen::platformScreenForWidget(widget));
+ if (window) {
+ screen = static_cast<QWaylandScreen *>(window->screen()->handle());
} else {
- screen = static_cast<QWaylandScreen *>(QApplicationPrivate::platformIntegration()->screens()[0]);
+ screen = static_cast<QWaylandScreen *>(QGuiApplication::primaryScreen()->handle());
}
return screen;
}
diff --git a/src/plugins/platforms/wayland/qwaylandnativeinterface.h b/src/plugins/platforms/wayland/qwaylandnativeinterface.h
index c92b44eb03..9db442a265 100644
--- a/src/plugins/platforms/wayland/qwaylandnativeinterface.h
+++ b/src/plugins/platforms/wayland/qwaylandnativeinterface.h
@@ -49,8 +49,8 @@
class QWaylandNativeInterface : public QPlatformNativeInterface
{
public:
- void *nativeResourceForWidget(const QByteArray &resourceString,
- QWidget *widget);
+ void *nativeResourceForWindow(const QByteArray &resourceString,
+ QWindow *window);
QVariantMap windowProperties(QPlatformWindow *window) const;
QVariant windowProperty(QPlatformWindow *window, const QString &name) const;
@@ -58,7 +58,7 @@ public:
void setWindowProperty(QPlatformWindow *window, const QString &name, const QVariant &value);
private:
- static QWaylandScreen *qPlatformScreenForWidget(QWidget *widget);
+ static QWaylandScreen *qPlatformScreenForWindow(QWindow *window);
private:
QHash<QPlatformWindow*, QVariantMap> m_windowProperties;
diff --git a/src/plugins/platforms/wayland/qwaylandscreen.cpp b/src/plugins/platforms/wayland/qwaylandscreen.cpp
index be6dcb2e88..7b064bac40 100644
--- a/src/plugins/platforms/wayland/qwaylandscreen.cpp
+++ b/src/plugins/platforms/wayland/qwaylandscreen.cpp
@@ -53,7 +53,6 @@ QWaylandScreen::QWaylandScreen(QWaylandDisplay *waylandDisplay, struct wl_output
, mFormat(QImage::Format_ARGB32_Premultiplied)
, mWaylandCursor(new QWaylandCursor(this))
{
- moveToThread(waylandDisplay->thread());
}
QWaylandScreen::~QWaylandScreen()
@@ -81,9 +80,9 @@ QImage::Format QWaylandScreen::format() const
return mFormat;
}
-QWaylandScreen * QWaylandScreen::waylandScreenFromWidget(QWidget *widget)
+QWaylandScreen * QWaylandScreen::waylandScreenFromWindow(QWindow *window)
{
- QPlatformScreen *platformScreen = QPlatformScreen::platformScreenForWidget(widget);
+ QPlatformScreen *platformScreen = QPlatformScreen::platformScreenForWindow(window);
return static_cast<QWaylandScreen *>(platformScreen);
}
diff --git a/src/plugins/platforms/wayland/qwaylandscreen.h b/src/plugins/platforms/wayland/qwaylandscreen.h
index f2b3bcefbc..9bf4f6574a 100644
--- a/src/plugins/platforms/wayland/qwaylandscreen.h
+++ b/src/plugins/platforms/wayland/qwaylandscreen.h
@@ -62,7 +62,7 @@ public:
wl_visual *visual() const;
- static QWaylandScreen *waylandScreenFromWidget(QWidget *widget);
+ static QWaylandScreen *waylandScreenFromWindow(QWindow *window);
private:
QWaylandDisplay *mWaylandDisplay;
diff --git a/src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp b/src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp
new file mode 100644
index 0000000000..25a1b466d4
--- /dev/null
+++ b/src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp
@@ -0,0 +1,148 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "qwaylandshmbackingstore.h"
+
+#include <QtCore/qdebug.h>
+
+#include "qwaylanddisplay.h"
+#include "qwaylandshmwindow.h"
+#include "qwaylandscreen.h"
+
+#include <wayland-client.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/mman.h>
+
+QT_BEGIN_NAMESPACE
+
+QWaylandShmBuffer::QWaylandShmBuffer(QWaylandDisplay *display,
+ const QSize &size, QImage::Format format)
+{
+ int stride = size.width() * 4;
+ int alloc = stride * size.height();
+ char filename[] = "/tmp/wayland-shm-XXXXXX";
+ int fd = mkstemp(filename);
+ if (fd < 0)
+ qWarning("open %s failed: %s", filename, strerror(errno));
+ if (ftruncate(fd, alloc) < 0) {
+ qWarning("ftruncate failed: %s", strerror(errno));
+ close(fd);
+ return;
+ }
+ uchar *data = (uchar *)
+ mmap(NULL, alloc, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ unlink(filename);
+
+ if (data == (uchar *) MAP_FAILED) {
+ qWarning("mmap /dev/zero failed: %s", strerror(errno));
+ close(fd);
+ return;
+ }
+
+ mImage = QImage(data, size.width(), size.height(), stride, format);
+ mBuffer = display->createShmBuffer(fd, size.width(), size.height(),
+ stride, display->argbVisual());
+ close(fd);
+}
+
+QWaylandShmBuffer::~QWaylandShmBuffer(void)
+{
+ munmap((void *) mImage.constBits(), mImage.byteCount());
+ wl_buffer_destroy(mBuffer);
+}
+
+QWaylandShmBackingStore::QWaylandShmBackingStore(QWindow *window)
+ : QPlatformBackingStore(window)
+ , mBuffer(0)
+ , mDisplay(QWaylandScreen::waylandScreenFromWindow(window)->display())
+{
+}
+
+QWaylandShmBackingStore::~QWaylandShmBackingStore()
+{
+}
+
+QPaintDevice *QWaylandShmBackingStore::paintDevice()
+{
+ return mBuffer->image();
+}
+
+void QWaylandShmBackingStore::beginPaint(const QRegion &)
+{
+ QWaylandShmWindow *waylandWindow = static_cast<QWaylandShmWindow *>(window()->handle());
+ Q_ASSERT(waylandWindow->windowType() == QWaylandWindow::Shm);
+ waylandWindow->waitForFrameSync();
+}
+
+void QWaylandShmBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
+{
+ Q_UNUSED(window);
+ Q_UNUSED(offset);
+ QWaylandShmWindow *waylandWindow = static_cast<QWaylandShmWindow *>(window->handle());
+ Q_ASSERT(waylandWindow->windowType() == QWaylandWindow::Shm);
+ QVector<QRect> rects = region.rects();
+ for (int i = 0; i < rects.size(); i++) {
+ const QRect rect = rects.at(i);
+ wl_buffer_damage(mBuffer->buffer(),rect.x(),rect.y(),rect.width(),rect.height());
+ waylandWindow->damage(rect);
+ }
+}
+
+void QWaylandShmBackingStore::resize(const QSize &size, const QRegion &)
+{
+ QWaylandShmWindow *waylandWindow = static_cast<QWaylandShmWindow *>(window()->handle());
+ Q_ASSERT(waylandWindow->windowType() == QWaylandWindow::Shm);
+
+ QImage::Format format = QPlatformScreen::platformScreenForWindow(window())->format();
+
+ if (mBuffer != NULL && mBuffer->size() == size)
+ return;
+
+ if (mBuffer != NULL)
+ delete mBuffer;
+
+ mBuffer = new QWaylandShmBuffer(mDisplay, size, format);
+
+ waylandWindow->attach(mBuffer);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/wayland/qwaylandshmbackingstore.h b/src/plugins/platforms/wayland/qwaylandshmbackingstore.h
new file mode 100644
index 0000000000..5e6959dc2f
--- /dev/null
+++ b/src/plugins/platforms/wayland/qwaylandshmbackingstore.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDSHMBACKINGSTORE_H
+#define QWAYLANDSHMBACKINGSTORE_H
+
+#include "qwaylandbuffer.h"
+#include <QtGui/QPlatformBackingStore>
+#include <QtGui/QImage>
+#include <QtGui/QPlatformWindow>
+
+QT_BEGIN_NAMESPACE
+
+class QWaylandDisplay;
+
+class QWaylandShmBuffer : public QWaylandBuffer {
+public:
+ QWaylandShmBuffer(QWaylandDisplay *display,
+ const QSize &size, QImage::Format format);
+ ~QWaylandShmBuffer();
+ QSize size() const { return mImage.size(); }
+ QImage *image() { return &mImage; }
+private:
+ QImage mImage;
+};
+
+class QWaylandShmBackingStore : public QPlatformBackingStore
+{
+public:
+ QWaylandShmBackingStore(QWindow *window);
+ ~QWaylandShmBackingStore();
+
+ QPaintDevice *paintDevice();
+ void flush(QWindow *window, const QRegion &region, const QPoint &offset);
+ void resize(const QSize &size, const QRegion &staticContents);
+ void beginPaint(const QRegion &);
+
+private:
+ QWaylandShmBuffer *mBuffer;
+ QWaylandDisplay *mDisplay;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/platforms/wayland/qwaylandshmsurface.cpp b/src/plugins/platforms/wayland/qwaylandshmsurface.cpp
deleted file mode 100644
index b24c419424..0000000000
--- a/src/plugins/platforms/wayland/qwaylandshmsurface.cpp
+++ /dev/null
@@ -1,150 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#include "qwaylandshmsurface.h"
-
-#include <QtCore/qdebug.h>
-#include <QtGui/private/qapplication_p.h>
-
-#include "qwaylanddisplay.h"
-#include "qwaylandshmwindow.h"
-#include "qwaylandscreen.h"
-
-#include <wayland-client.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <sys/mman.h>
-
-QT_BEGIN_NAMESPACE
-
-QWaylandShmBuffer::QWaylandShmBuffer(QWaylandDisplay *display,
- const QSize &size, QImage::Format format)
-{
- int stride = size.width() * 4;
- int alloc = stride * size.height();
- char filename[] = "/tmp/wayland-shm-XXXXXX";
- int fd = mkstemp(filename);
- if (fd < 0)
- qWarning("open %s failed: %s", filename, strerror(errno));
- if (ftruncate(fd, alloc) < 0) {
- qWarning("ftruncate failed: %s", strerror(errno));
- close(fd);
- return;
- }
- uchar *data = (uchar *)
- mmap(NULL, alloc, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
- unlink(filename);
-
- if (data == (uchar *) MAP_FAILED) {
- qWarning("mmap /dev/zero failed: %s", strerror(errno));
- close(fd);
- return;
- }
-
- mImage = QImage(data, size.width(), size.height(), stride, format);
- mBuffer = display->createShmBuffer(fd, size.width(), size.height(),
- stride, display->argbVisual());
- close(fd);
-}
-
-QWaylandShmBuffer::~QWaylandShmBuffer(void)
-{
- munmap((void *) mImage.constBits(), mImage.byteCount());
- wl_buffer_destroy(mBuffer);
-}
-
-QWaylandShmWindowSurface::QWaylandShmWindowSurface(QWidget *window)
- : QWindowSurface(window)
- , mBuffer(0)
- , mDisplay(QWaylandScreen::waylandScreenFromWidget(window)->display())
-{
-}
-
-QWaylandShmWindowSurface::~QWaylandShmWindowSurface()
-{
-}
-
-QPaintDevice *QWaylandShmWindowSurface::paintDevice()
-{
- return mBuffer->image();
-}
-
-void QWaylandShmWindowSurface::beginPaint(const QRegion &)
-{
- QWaylandShmWindow *waylandWindow = static_cast<QWaylandShmWindow *>(window()->platformWindow());
- Q_ASSERT(waylandWindow->windowType() == QWaylandWindow::Shm);
- waylandWindow->waitForFrameSync();
-}
-
-void QWaylandShmWindowSurface::flush(QWidget *widget, const QRegion &region, const QPoint &offset)
-{
- Q_UNUSED(widget);
- Q_UNUSED(offset);
- QWaylandShmWindow *waylandWindow = static_cast<QWaylandShmWindow *>(window()->platformWindow());
- Q_ASSERT(waylandWindow->windowType() == QWaylandWindow::Shm);
- QVector<QRect> rects = region.rects();
- for (int i = 0; i < rects.size(); i++) {
- const QRect rect = rects.at(i);
- wl_buffer_damage(mBuffer->buffer(),rect.x(),rect.y(),rect.width(),rect.height());
- waylandWindow->damage(rect);
- }
-}
-
-void QWaylandShmWindowSurface::resize(const QSize &size)
-{
- QWaylandShmWindow *waylandWindow = static_cast<QWaylandShmWindow *>(window()->platformWindow());
- Q_ASSERT(waylandWindow->windowType() == QWaylandWindow::Shm);
-
- QWindowSurface::resize(size);
- QImage::Format format = QPlatformScreen::platformScreenForWidget(window())->format();
-
- if (mBuffer != NULL && mBuffer->size() == size)
- return;
-
- if (mBuffer != NULL)
- delete mBuffer;
-
- mBuffer = new QWaylandShmBuffer(mDisplay, size, format);
-
- waylandWindow->attach(mBuffer);
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/wayland/qwaylandshmsurface.h b/src/plugins/platforms/wayland/qwaylandshmsurface.h
deleted file mode 100644
index f3db8b86e5..0000000000
--- a/src/plugins/platforms/wayland/qwaylandshmsurface.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWINDOWSURFACE_WAYLAND_H
-#define QWINDOWSURFACE_WAYLAND_H
-
-#include "qwaylandbuffer.h"
-#include <QtGui/private/qwindowsurface_p.h>
-
-#include <QtGui/QPlatformWindow>
-
-QT_BEGIN_NAMESPACE
-
-class QWaylandDisplay;
-
-class QWaylandShmBuffer : public QWaylandBuffer {
-public:
- QWaylandShmBuffer(QWaylandDisplay *display,
- const QSize &size, QImage::Format format);
- ~QWaylandShmBuffer();
- QSize size() const { return mImage.size(); }
- QImage *image() { return &mImage; }
-private:
- QImage mImage;
-};
-
-class QWaylandShmWindowSurface : public QWindowSurface
-{
-public:
- QWaylandShmWindowSurface(QWidget *window);
- ~QWaylandShmWindowSurface();
-
- QPaintDevice *paintDevice();
- void flush(QWidget *widget, const QRegion &region, const QPoint &offset);
- void resize(const QSize &size);
- void beginPaint(const QRegion &);
-
-private:
- QWaylandShmBuffer *mBuffer;
- QWaylandDisplay *mDisplay;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/plugins/platforms/wayland/qwaylandshmwindow.cpp b/src/plugins/platforms/wayland/qwaylandshmwindow.cpp
index a6b7050f7a..ba5e46cab1 100644
--- a/src/plugins/platforms/wayland/qwaylandshmwindow.cpp
+++ b/src/plugins/platforms/wayland/qwaylandshmwindow.cpp
@@ -47,8 +47,8 @@
#include <QtCore/QDebug>
-QWaylandShmWindow::QWaylandShmWindow(QWidget *widget)
- : QWaylandWindow(widget)
+QWaylandShmWindow::QWaylandShmWindow(QWindow *window)
+ : QWaylandWindow(window)
{
newSurfaceCreated();
}
@@ -63,9 +63,3 @@ QWaylandWindow::WindowType QWaylandShmWindow::windowType() const
return QWaylandWindow::Shm;
}
-QPlatformGLContext * QWaylandShmWindow::glContext() const
-{
- qWarning("Trying to retrieve a glContext from a Raster window surface!");
- return 0;
-}
-
diff --git a/src/plugins/platforms/wayland/qwaylandshmwindow.h b/src/plugins/platforms/wayland/qwaylandshmwindow.h
index 8033703391..36f9f225b7 100644
--- a/src/plugins/platforms/wayland/qwaylandshmwindow.h
+++ b/src/plugins/platforms/wayland/qwaylandshmwindow.h
@@ -48,11 +48,11 @@
class QWaylandShmWindow : public QWaylandWindow
{
public:
- QWaylandShmWindow(QWidget *widget);
+ QWaylandShmWindow(QWindow *window);
~QWaylandShmWindow();
WindowType windowType() const;
- QPlatformGLContext *glContext() const;
+ QSurfaceFormat format() const { return QSurfaceFormat(); }
};
#endif // QWAYLANDSHMWINDOW_H
diff --git a/src/plugins/platforms/wayland/qwaylandwindow.cpp b/src/plugins/platforms/wayland/qwaylandwindow.cpp
index 099ebabb06..6011621044 100644
--- a/src/plugins/platforms/wayland/qwaylandwindow.cpp
+++ b/src/plugins/platforms/wayland/qwaylandwindow.cpp
@@ -46,20 +46,21 @@
#include "qwaylandinputdevice.h"
#include "qwaylandscreen.h"
+#include <QtGui/QWindow>
+
#ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT
#include "windowmanager_integration/qwaylandwindowmanagerintegration.h"
#endif
#include <QCoreApplication>
-#include <QtGui/QWidget>
#include <QtGui/QWindowSystemInterface>
#include <QDebug>
-QWaylandWindow::QWaylandWindow(QWidget *window)
+QWaylandWindow::QWaylandWindow(QWindow *window)
: QPlatformWindow(window)
, mSurface(0)
- , mDisplay(QWaylandScreen::waylandScreenFromWidget(window)->display())
+ , mDisplay(QWaylandScreen::waylandScreenFromWindow(window)->display())
, mBuffer(0)
, mWaitingForFrameSync(false)
{
@@ -112,11 +113,11 @@ void QWaylandWindow::configure(uint32_t time, uint32_t edges,
{
Q_UNUSED(time);
Q_UNUSED(edges);
- QRect geometry = QRect(x, y, width, height);
+ QRect geometry = QRect(x, y, width, height);
setGeometry(geometry);
- QWindowSystemInterface::handleGeometryChange(widget(), geometry);
+ QWindowSystemInterface::handleGeometryChange(window(), geometry);
}
void QWaylandWindow::attach(QWaylandBuffer *buffer)
@@ -124,6 +125,7 @@ void QWaylandWindow::attach(QWaylandBuffer *buffer)
mBuffer = buffer;
if (mSurface) {
wl_surface_attach(mSurface, buffer->buffer(),0,0);
+ QWindowSystemInterface::handleSynchronousExposeEvent(window(), QRect(QPoint(), geometry().size()));
}
}
diff --git a/src/plugins/platforms/wayland/qwaylandwindow.h b/src/plugins/platforms/wayland/qwaylandwindow.h
index b91f6b6eb8..4f1e2c8183 100644
--- a/src/plugins/platforms/wayland/qwaylandwindow.h
+++ b/src/plugins/platforms/wayland/qwaylandwindow.h
@@ -59,7 +59,7 @@ public:
Egl
};
- QWaylandWindow(QWidget *window);
+ QWaylandWindow(QWindow *window);
~QWaylandWindow();
virtual WindowType windowType() const = 0;
diff --git a/src/plugins/platforms/wayland/wayland.pro b/src/plugins/platforms/wayland/wayland.pro
index 1e0bbe6cdd..fd6ffc06de 100644
--- a/src/plugins/platforms/wayland/wayland.pro
+++ b/src/plugins/platforms/wayland/wayland.pro
@@ -1,19 +1,23 @@
TARGET = qwayland
load(qt_plugin)
-QT+=gui-private core-private opengl-private
+CONFIG += qpa/genericunixfontdatabase
DESTDIR = $$QT.gui.plugins/platforms
DEFINES += Q_PLATFORM_WAYLAND
DEFINES += $$QMAKE_DEFINES_WAYLAND
-QT += core-private gui-private opengl-private
+mac {
+ DEFINES += QT_NO_WAYLAND_XKB
+}
+
+QT += core-private gui-private opengl-private platformsupport-private
SOURCES = main.cpp \
qwaylandintegration.cpp \
qwaylandnativeinterface.cpp \
- qwaylandshmsurface.cpp \
+ qwaylandshmbackingstore.cpp \
qwaylandinputdevice.cpp \
qwaylandcursor.cpp \
qwaylanddisplay.cpp \
@@ -21,6 +25,7 @@ SOURCES = main.cpp \
qwaylandscreen.cpp \
qwaylandshmwindow.cpp \
qwaylandclipboard.cpp \
+ qwaylanddnd.cpp \
qwaylandmime.cpp
HEADERS = qwaylandintegration.h \
@@ -29,23 +34,23 @@ HEADERS = qwaylandintegration.h \
qwaylanddisplay.h \
qwaylandwindow.h \
qwaylandscreen.h \
- qwaylandshmsurface.h \
+ qwaylandshmbackingstore.h \
qwaylandbuffer.h \
qwaylandshmwindow.h \
qwaylandclipboard.h \
+ qwaylanddnd.h \
qwaylandmime.h
INCLUDEPATH += $$QMAKE_INCDIR_WAYLAND
LIBS += $$QMAKE_LIBS_WAYLAND
-QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_WAYLAND
-
-INCLUDEPATH += $$PWD
+mac {
+ LIBS += -lwayland-client
+}
-include ($$PWD/gl_integration/gl_integration.pri)
-include ($$PWD/windowmanager_integration/windowmanager_integration.pri)
-
-include (../fontdatabases/genericunix/genericunix.pri)
+QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_WAYLAND
target.path += $$[QT_INSTALL_PLUGINS]/platforms
INSTALLS += target
+include ($$PWD/gl_integration/gl_integration.pri)
+include ($$PWD/windowmanager_integration/windowmanager_integration.pri)
diff --git a/src/plugins/platforms/wayland/windowmanager_integration/qwaylandwindowmanagerintegration.cpp b/src/plugins/platforms/wayland/windowmanager_integration/qwaylandwindowmanagerintegration.cpp
index 798900bbce..7d68571c24 100644
--- a/src/plugins/platforms/wayland/windowmanager_integration/qwaylandwindowmanagerintegration.cpp
+++ b/src/plugins/platforms/wayland/windowmanager_integration/qwaylandwindowmanagerintegration.cpp
@@ -49,8 +49,7 @@
#include <QtGui/QPlatformNativeInterface>
#include <QtGui/QPlatformWindow>
#include <QtGui/QtEvents>
-#include <QtGui/QWidget>
-#include <QtGui/QApplication>
+#include <QtGui/QGuiApplication>
#include <QDebug>
@@ -237,15 +236,15 @@ void QWaylandWindowManagerIntegration::wlHandleWindowPropertyChange(void *data,
QPlatformNativeInterface *nativeInterface = qApp->platformNativeInterface();
QWaylandWindowManagerIntegration *inst = QWaylandWindowManagerIntegration::instance();
- QWidgetList widgets = qApp->topLevelWidgets();
- foreach (QWidget *widget, widgets) {
- QPlatformWindow *platformWindowForWidget = widget->platformWindow();
- if (!platformWindowForWidget)
+ QList<QWindow *> windows = qApp->topLevelWindows();
+ foreach (QWindow *window, windows) {
+ QPlatformWindow *platformWindowForWindow = window->handle();
+ if (!platformWindowForWindow)
continue;
- QWaylandWindow *window = static_cast<QWaylandWindow*>(platformWindowForWidget);
- wl_surface *windowSurface = (wl_surface*)nativeInterface->nativeResourceForWidget(QByteArray("surface"), widget);
+ QWaylandWindow *waylandWindow = static_cast<QWaylandWindow*>(platformWindowForWindow);
+ wl_surface *windowSurface = (wl_surface*)nativeInterface->nativeResourceForWindow(QByteArray("surface"), window);
if (windowSurface == surface) {
- inst->handleWindowPropertyChange(window, QString(propertyName), variantValue);
+ inst->handleWindowPropertyChange(waylandWindow, QString(propertyName), variantValue);
break;
}
}
diff --git a/src/plugins/platforms/windows/array.h b/src/plugins/platforms/windows/array.h
new file mode 100644
index 0000000000..216f1e8945
--- /dev/null
+++ b/src/plugins/platforms/windows/array.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ARRAY_H
+#define ARRAY_H
+
+#include <QtCore/QtAlgorithms>
+
+QT_BEGIN_NAMESPACE
+
+/* A simple, non-shared array. */
+
+template <class T>
+class Array
+{
+ Q_DISABLE_COPY(Array)
+public:
+ enum { initialSize = 5 };
+
+ typedef T* const_iterator;
+
+ explicit Array(size_t size= 0) : data(0), m_capacity(0), m_size(0)
+ { if (size) resize(size); }
+ ~Array() { delete [] data; }
+
+ T *data;
+ inline size_t size() const { return m_size; }
+ inline const_iterator begin() const { return data; }
+ inline const_iterator end() const { return data + m_size; }
+
+ inline void append(const T &value)
+ {
+ const size_t oldSize = m_size;
+ resize(m_size + 1);
+ data[oldSize] = value;
+ }
+
+ inline void resize(size_t size)
+ {
+ if (size > m_size)
+ reserve(size > 1 ? size + size / 2 : size_t(initialSize));
+ m_size = size;
+ }
+
+ void reserve(size_t capacity)
+ {
+ if (capacity > m_capacity) {
+ const T *oldData = data;
+ data = new T[capacity];
+ if (oldData) {
+ qCopy(oldData, oldData + m_size, data);
+ delete [] oldData;
+ }
+ m_capacity = capacity;
+ }
+ }
+
+private:
+ size_t m_capacity;
+ size_t m_size;
+};
+
+QT_END_NAMESPACE
+
+#endif // ARRAY_H
diff --git a/src/plugins/platforms/windows/main.cpp b/src/plugins/platforms/windows/main.cpp
new file mode 100644
index 0000000000..933aa76df8
--- /dev/null
+++ b/src/plugins/platforms/windows/main.cpp
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtGui/QPlatformIntegrationPlugin>
+#include <QtCore/QStringList>
+
+#include "qwindowsintegration.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \group qt-lighthouse-win
+ \title Qt Lighthouse plugin for Windows
+
+ \brief Class documentation of the Qt Lighthouse plugin for Windows.
+
+ \section1 Tips
+
+ \list
+ \o The environment variable \c QT_LIGHTHOUSE_WINDOWS_VERBOSE controls
+ the debug level. It takes the form
+ \c{<keyword1>:<level1>,<keyword2>:<level2>}, where
+ keyword is one of \c integration, \c windows, \c backingstore and
+ \c fonts. Level is an integer 0..9.
+ \endlist
+ */
+
+/*!
+ \class QWindowsIntegrationPlugin
+ \brief Plugin.
+ \ingroup qt-lighthouse-win
+ */
+
+/*!
+ \namespace QtWindows
+
+ \brief Namespace for enumerations, etc.
+ \ingroup qt-lighthouse-win
+*/
+
+/*!
+ \enum QtWindows::WindowsEventType
+
+ \brief Enumerations for WM_XX events.
+
+ With flags that should help to structure the code.
+
+ \ingroup qt-lighthouse-win
+*/
+
+class QWindowsIntegrationPlugin : public QPlatformIntegrationPlugin
+{
+public:
+ QStringList keys() const;
+ QPlatformIntegration *create(const QString&, const QStringList&);
+};
+
+QStringList QWindowsIntegrationPlugin::keys() const
+{
+ return QStringList(QStringLiteral("windows"));
+}
+
+QPlatformIntegration *QWindowsIntegrationPlugin::create(const QString& system, const QStringList& paramList)
+{
+ Q_UNUSED(paramList);
+ if (system.compare(system, QStringLiteral("windows"), Qt::CaseInsensitive) == 0)
+ return new QWindowsIntegration;
+ return 0;
+}
+
+Q_EXPORT_PLUGIN2(windows, QWindowsIntegrationPlugin)
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/pixmaputils.cpp b/src/plugins/platforms/windows/pixmaputils.cpp
new file mode 100644
index 0000000000..111df5a4b9
--- /dev/null
+++ b/src/plugins/platforms/windows/pixmaputils.cpp
@@ -0,0 +1,316 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "pixmaputils.h"
+
+#include <QtGui/QBitmap>
+#include <QtGui/QImage>
+#include <QtGui/QPlatformPixmap>
+#include <QtGui/private/qpixmap_raster_p.h>
+
+#include <QtCore/QScopedArrayPointer>
+#include <QtCore/QDebug>
+
+#include <string.h>
+
+QT_BEGIN_NAMESPACE
+
+HBITMAP createIconMask(const QBitmap &bitmap)
+{
+ QImage bm = bitmap.toImage().convertToFormat(QImage::Format_Mono);
+ const int w = bm.width();
+ const int h = bm.height();
+ const int bpl = ((w+15)/16)*2; // bpl, 16 bit alignment
+ QScopedArrayPointer<uchar> bits(new uchar[bpl * h]);
+ bm.invertPixels();
+ for (int y = 0; y < h; ++y)
+ memcpy(bits.data() + y * bpl, bm.scanLine(y), bpl);
+ HBITMAP hbm = CreateBitmap(w, h, 1, 1, bits.data());
+ return hbm;
+}
+
+HBITMAP qPixmapToWinHBITMAP(const QPixmap &p, HBitmapFormat format)
+{
+ if (p.isNull())
+ return 0;
+
+ HBITMAP bitmap = 0;
+ if (p.handle()->classId() != QPlatformPixmap::RasterClass) {
+ QRasterPlatformPixmap *data = new QRasterPlatformPixmap(p.depth() == 1 ?
+ QRasterPlatformPixmap::BitmapType : QRasterPlatformPixmap::PixmapType);
+ data->fromImage(p.toImage(), Qt::AutoColor);
+ return qPixmapToWinHBITMAP(QPixmap(data), format);
+ }
+
+ QRasterPlatformPixmap *d = static_cast<QRasterPlatformPixmap*>(p.handle());
+ const QImage *rasterImage = d->buffer();
+ const int w = rasterImage->width();
+ const int h = rasterImage->height();
+
+ HDC display_dc = GetDC(0);
+
+ // Define the header
+ BITMAPINFO bmi;
+ memset(&bmi, 0, sizeof(bmi));
+ bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bmi.bmiHeader.biWidth = w;
+ bmi.bmiHeader.biHeight = -h;
+ bmi.bmiHeader.biPlanes = 1;
+ bmi.bmiHeader.biBitCount = 32;
+ bmi.bmiHeader.biCompression = BI_RGB;
+ bmi.bmiHeader.biSizeImage = w * h * 4;
+
+ // Create the pixmap
+ uchar *pixels = 0;
+ bitmap = CreateDIBSection(display_dc, &bmi, DIB_RGB_COLORS, (void **) &pixels, 0, 0);
+ ReleaseDC(0, display_dc);
+ if (!bitmap) {
+ qErrnoWarning("%s, failed to create dibsection", __FUNCTION__);
+ return 0;
+ }
+ if (!pixels) {
+ qErrnoWarning("%s, did not allocate pixel data", __FUNCTION__);
+ return 0;
+ }
+
+ // Copy over the data
+ QImage::Format imageFormat = QImage::Format_ARGB32;
+ if (format == HBitmapAlpha)
+ imageFormat = QImage::Format_RGB32;
+ else if (format == HBitmapPremultipliedAlpha)
+ imageFormat = QImage::Format_ARGB32_Premultiplied;
+ const QImage image = rasterImage->convertToFormat(imageFormat);
+ const int bytes_per_line = w * 4;
+ for (int y=0; y < h; ++y)
+ memcpy(pixels + y * bytes_per_line, image.scanLine(y), bytes_per_line);
+
+ return bitmap;
+}
+
+QPixmap qPixmapFromWinHBITMAP(HBITMAP bitmap, HBitmapFormat format)
+{
+ // Verify size
+ BITMAP bitmap_info;
+ memset(&bitmap_info, 0, sizeof(BITMAP));
+
+ const int res = GetObject(bitmap, sizeof(BITMAP), &bitmap_info);
+ if (!res) {
+ qErrnoWarning("QPixmap::fromWinHBITMAP(), failed to get bitmap info");
+ return QPixmap();
+ }
+ const int w = bitmap_info.bmWidth;
+ const int h = bitmap_info.bmHeight;
+
+ BITMAPINFO bmi;
+ memset(&bmi, 0, sizeof(bmi));
+ bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bmi.bmiHeader.biWidth = w;
+ bmi.bmiHeader.biHeight = -h;
+ bmi.bmiHeader.biPlanes = 1;
+ bmi.bmiHeader.biBitCount = 32;
+ bmi.bmiHeader.biCompression = BI_RGB;
+ bmi.bmiHeader.biSizeImage = w * h * 4;
+
+ // Get bitmap bits
+ QScopedArrayPointer<uchar> data(new uchar[bmi.bmiHeader.biSizeImage]);
+ HDC display_dc = GetDC(0);
+ if (!GetDIBits(display_dc, bitmap, 0, h, data.data(), &bmi, DIB_RGB_COLORS)) {
+ ReleaseDC(0, display_dc);
+ qWarning("%s, failed to get bitmap bits", __FUNCTION__);
+ return QPixmap();
+ }
+
+ QImage::Format imageFormat = QImage::Format_ARGB32_Premultiplied;
+ uint mask = 0;
+ if (format == HBitmapNoAlpha) {
+ imageFormat = QImage::Format_RGB32;
+ mask = 0xff000000;
+ }
+
+ // Create image and copy data into image.
+ QImage image(w, h, imageFormat);
+ if (image.isNull()) { // failed to alloc?
+ ReleaseDC(0, display_dc);
+ qWarning("%s, failed create image of %dx%d", __FUNCTION__, w, h);
+ return QPixmap();
+ }
+ const int bytes_per_line = w * sizeof(QRgb);
+ for (int y = 0; y < h; ++y) {
+ QRgb *dest = (QRgb *) image.scanLine(y);
+ const QRgb *src = (const QRgb *) (data.data() + y * bytes_per_line);
+ for (int x = 0; x < w; ++x) {
+ const uint pixel = src[x];
+ if ((pixel & 0xff000000) == 0 && (pixel & 0x00ffffff) != 0)
+ dest[x] = pixel | 0xff000000;
+ else
+ dest[x] = pixel | mask;
+ }
+ }
+ ReleaseDC(0, display_dc);
+ return QPixmap::fromImage(image);
+}
+
+HICON qPixmapToWinHICON(const QPixmap &p)
+{
+ QBitmap maskBitmap = p.mask();
+ if (maskBitmap.isNull()) {
+ maskBitmap = QBitmap(p.size());
+ maskBitmap.fill(Qt::color1);
+ }
+
+ ICONINFO ii;
+ ii.fIcon = true;
+ ii.hbmMask = createIconMask(maskBitmap);
+ ii.hbmColor = qPixmapToWinHBITMAP(p, HBitmapAlpha);
+ ii.xHotspot = 0;
+ ii.yHotspot = 0;
+
+ HICON hIcon = CreateIconIndirect(&ii);
+
+ DeleteObject(ii.hbmColor);
+ DeleteObject(ii.hbmMask);
+
+ return hIcon;
+}
+
+static QImage qImageFromWinHBITMAP(HDC hdc, HBITMAP bitmap, int w, int h)
+{
+ BITMAPINFO bmi;
+ memset(&bmi, 0, sizeof(bmi));
+ bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bmi.bmiHeader.biWidth = w;
+ bmi.bmiHeader.biHeight = -h;
+ bmi.bmiHeader.biPlanes = 1;
+ bmi.bmiHeader.biBitCount = 32;
+ bmi.bmiHeader.biCompression = BI_RGB;
+ bmi.bmiHeader.biSizeImage = w * h * 4;
+
+ QImage image(w, h, QImage::Format_ARGB32_Premultiplied);
+ if (image.isNull())
+ return image;
+
+ // Get bitmap bits
+ QScopedPointer<uchar> data(new uchar [bmi.bmiHeader.biSizeImage]);
+ if (!GetDIBits(hdc, bitmap, 0, h, data.data(), &bmi, DIB_RGB_COLORS)) {
+ qErrnoWarning("%s: failed to get bitmap bits", __FUNCTION__);
+ return QImage();
+ }
+ // Create image and copy data into image.
+ for (int y = 0; y < h; ++y) {
+ void *dest = (void *) image.scanLine(y);
+ void *src = data.data() + y * image.bytesPerLine();
+ memcpy(dest, src, image.bytesPerLine());
+ }
+ return image;
+}
+
+QPixmap qPixmapFromWinHICON(HICON icon)
+{
+ bool foundAlpha = false;
+ HDC screenDevice = GetDC(0);
+ HDC hdc = CreateCompatibleDC(screenDevice);
+ ReleaseDC(0, screenDevice);
+
+ ICONINFO iconinfo;
+ const bool result = GetIconInfo(icon, &iconinfo); //x and y Hotspot describes the icon center
+ if (!result) {
+ qErrnoWarning("QPixmap::fromWinHICON(), failed to GetIconInfo()");
+ return QPixmap();
+ }
+
+ const int w = iconinfo.xHotspot * 2;
+ const int h = iconinfo.yHotspot * 2;
+
+ BITMAPINFOHEADER bitmapInfo;
+ bitmapInfo.biSize = sizeof(BITMAPINFOHEADER);
+ bitmapInfo.biWidth = w;
+ bitmapInfo.biHeight = h;
+ bitmapInfo.biPlanes = 1;
+ bitmapInfo.biBitCount = 32;
+ bitmapInfo.biCompression = BI_RGB;
+ bitmapInfo.biSizeImage = 0;
+ bitmapInfo.biXPelsPerMeter = 0;
+ bitmapInfo.biYPelsPerMeter = 0;
+ bitmapInfo.biClrUsed = 0;
+ bitmapInfo.biClrImportant = 0;
+ DWORD* bits;
+
+ HBITMAP winBitmap = CreateDIBSection(hdc, (BITMAPINFO*)&bitmapInfo, DIB_RGB_COLORS, (VOID**)&bits, NULL, 0);
+ HGDIOBJ oldhdc = (HBITMAP)SelectObject(hdc, winBitmap);
+ DrawIconEx( hdc, 0, 0, icon, iconinfo.xHotspot * 2, iconinfo.yHotspot * 2, 0, 0, DI_NORMAL);
+ QImage image = qImageFromWinHBITMAP(hdc, winBitmap, w, h);
+
+ for (int y = 0 ; y < h && !foundAlpha ; y++) {
+ const QRgb *scanLine= reinterpret_cast<const QRgb *>(image.scanLine(y));
+ for (int x = 0; x < w ; x++) {
+ if (qAlpha(scanLine[x]) != 0) {
+ foundAlpha = true;
+ break;
+ }
+ }
+ }
+ if (!foundAlpha) {
+ //If no alpha was found, we use the mask to set alpha values
+ DrawIconEx( hdc, 0, 0, icon, w, h, 0, 0, DI_MASK);
+ const QImage mask = qImageFromWinHBITMAP(hdc, winBitmap, w, h);
+
+ for (int y = 0 ; y < h ; y++){
+ QRgb *scanlineImage = reinterpret_cast<QRgb *>(image.scanLine(y));
+ const QRgb *scanlineMask = mask.isNull() ? 0 : reinterpret_cast<const QRgb *>(mask.scanLine(y));
+ for (int x = 0; x < w ; x++){
+ if (scanlineMask && qRed(scanlineMask[x]) != 0)
+ scanlineImage[x] = 0; //mask out this pixel
+ else
+ scanlineImage[x] |= 0xff000000; // set the alpha channel to 255
+ }
+ }
+ }
+ //dispose resources created by iconinfo call
+ DeleteObject(iconinfo.hbmMask);
+ DeleteObject(iconinfo.hbmColor);
+
+ SelectObject(hdc, oldhdc); //restore state
+ DeleteObject(winBitmap);
+ DeleteDC(hdc);
+ return QPixmap::fromImage(image);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/pixmaputils.h b/src/plugins/platforms/windows/pixmaputils.h
new file mode 100644
index 0000000000..bf94a2695c
--- /dev/null
+++ b/src/plugins/platforms/windows/pixmaputils.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PIXMAPUTILS_H
+#define PIXMAPUTILS_H
+
+#include "qtwindows_additional.h"
+
+#include <QtCore/QtGlobal>
+
+QT_BEGIN_NAMESPACE
+
+class QBitmap;
+class QPixmap;
+
+enum HBitmapFormat
+{
+ HBitmapNoAlpha,
+ HBitmapPremultipliedAlpha,
+ HBitmapAlpha
+};
+
+HBITMAP createIconMask(const QBitmap &bitmap);
+
+HBITMAP qPixmapToWinHBITMAP(const QPixmap &p, HBitmapFormat format);
+HICON qPixmapToWinHICON(const QPixmap &p);
+
+QPixmap qPixmapFromWinHBITMAP(HBITMAP bitmap, HBitmapFormat format);
+QPixmap qPixmapFromWinHICON(HICON icon);
+
+QT_END_NAMESPACE
+
+#endif // PIXMAPUTILS_H
diff --git a/src/plugins/platforms/windows/qtwindows_additional.h b/src/plugins/platforms/windows/qtwindows_additional.h
new file mode 100644
index 0000000000..e262159b7b
--- /dev/null
+++ b/src/plugins/platforms/windows/qtwindows_additional.h
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTWINDOWS_ADDITIONAL_H
+#define QTWINDOWS_ADDITIONAL_H
+
+#include <QtCore/QtGlobal> // get compiler define
+#include <QtCore/qt_windows.h>
+
+/* Complement the definitions and declarations missing
+ * when using MinGW or older Windows SDKs. */
+
+#if defined(Q_CC_MINGW)
+# if !defined(ULW_ALPHA)
+# define ULW_ALPHA 0x00000002
+# define LWA_ALPHA 0x00000002
+# endif // !defined(ULW_ALPHA)
+# define SPI_GETFONTSMOOTHINGTYPE 0x200A
+# define FE_FONTSMOOTHINGCLEARTYPE 0x0002
+# define CLEARTYPE_QUALITY 5
+
+# define CF_DIBV5 17
+
+#define CO_E_NOT_SUPPORTED _HRESULT_TYPEDEF_(0x80004021L)
+
+typedef struct tagUPDATELAYEREDWINDOWINFO {
+ DWORD cbSize;
+ HDC hdcDst;
+ const POINT *pptDst;
+ const SIZE *psize;
+ HDC hdcSrc;
+ const POINT *pptSrc;
+ COLORREF crKey;
+ const BLENDFUNCTION *pblend;
+ DWORD dwFlags;
+ const RECT *prcDirty;
+} UPDATELAYEREDWINDOWINFO, *PUPDATELAYEREDWINDOWINFO;
+
+// OpenGL Pixelformat flags.
+#define PFD_SUPPORT_DIRECTDRAW 0x00002000
+#define PFD_DIRECT3D_ACCELERATED 0x00004000
+#define PFD_SUPPORT_COMPOSITION 0x00008000
+
+// IME.
+#define IMR_CONFIRMRECONVERTSTRING 0x0005
+
+#endif // if defined(Q_CC_MINGW)
+
+/* Touch is supported from Windows 7 onwards and data structures
+ * are present in the Windows SDK's, but not in older MSVC Express
+ * versions. */
+
+#if defined(Q_CC_MINGW) || !defined(TOUCHEVENTF_MOVE)
+
+#define WM_TOUCH 0x0240
+
+typedef struct tagTOUCHINPUT {
+ LONG x;
+ LONG y;
+ HANDLE hSource;
+ DWORD dwID;
+ DWORD dwFlags;
+ DWORD dwMask;
+ DWORD dwTime;
+ ULONG_PTR dwExtraInfo;
+ DWORD cxContact;
+ DWORD cyContact;
+} TOUCHINPUT, *PTOUCHINPUT;
+typedef TOUCHINPUT const * PCTOUCHINPUT;
+
+# define TOUCHEVENTF_MOVE 0x0001
+# define TOUCHEVENTF_DOWN 0x0002
+# define TOUCHEVENTF_UP 0x0004
+# define TOUCHEVENTF_INRANGE 0x0008
+# define TOUCHEVENTF_PRIMARY 0x0010
+# define TOUCHEVENTF_NOCOALESCE 0x0020
+# define TOUCHEVENTF_PALM 0x0080
+# define TOUCHINPUTMASKF_CONTACTAREA 0x0004
+# define TOUCHINPUTMASKF_EXTRAINFO 0x0002
+
+#endif // if defined(Q_CC_MINGW) || !defined(TOUCHEVENTF_MOVE)
+
+#endif // QTWINDOWS_ADDITIONAL_H
diff --git a/src/plugins/platforms/windows/qtwindowsglobal.h b/src/plugins/platforms/windows/qtwindowsglobal.h
new file mode 100644
index 0000000000..692489dfc6
--- /dev/null
+++ b/src/plugins/platforms/windows/qtwindowsglobal.h
@@ -0,0 +1,182 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTWINDOWSGLOBAL_H
+#define QTWINDOWSGLOBAL_H
+
+#include "qtwindows_additional.h"
+#include <QtCore/qnamespace.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace QtWindows
+{
+
+enum
+{
+ WindowEventFlag = 0x10000,
+ MouseEventFlag = 0x20000,
+ NonClientEventFlag = 0x40000,
+ InputMethodEventFlag = 0x80000,
+ KeyEventFlag = 0x100000,
+ KeyDownEventFlag = 0x200000,
+ TouchEventFlag = 0x400000,
+ ClipboardEventFlag = 0x800000,
+ ApplicationEventFlag = 0x1000000
+};
+
+enum WindowsEventType // Simplify event types
+{
+ ExposeEvent = WindowEventFlag + 1,
+ ActivateWindowEvent = WindowEventFlag + 2,
+ DeactivateWindowEvent = WindowEventFlag + 3,
+ LeaveEvent = WindowEventFlag + 5,
+ CloseEvent = WindowEventFlag + 6,
+ ShowEvent = WindowEventFlag + 7,
+ HideEvent = WindowEventFlag + 8,
+ DestroyEvent = WindowEventFlag + 9,
+ MoveEvent = WindowEventFlag + 10,
+ ResizeEvent = WindowEventFlag + 12,
+ QuerySizeHints = WindowEventFlag + 15,
+ CalculateSize = WindowEventFlag + 16,
+ MouseEvent = MouseEventFlag + 1,
+ MouseWheelEvent = MouseEventFlag + 2,
+ TouchEvent = TouchEventFlag + 1,
+ NonClientMouseEvent = NonClientEventFlag + MouseEventFlag + 1,
+ KeyEvent = KeyEventFlag + 1,
+ KeyDownEvent = KeyEventFlag + KeyDownEventFlag + 1,
+ InputMethodKeyEvent = InputMethodEventFlag + KeyEventFlag + 1,
+ InputMethodKeyDownEvent = InputMethodEventFlag + KeyEventFlag + KeyDownEventFlag + 1,
+ ClipboardEvent = ClipboardEventFlag + 1,
+ ActivateApplicationEvent = ApplicationEventFlag + 1,
+ DeactivateApplicationEvent = ApplicationEventFlag + 2,
+ InputMethodStartCompositionEvent = InputMethodEventFlag + 1,
+ InputMethodCompositionEvent = InputMethodEventFlag + 2,
+ InputMethodEndCompositionEvent = InputMethodEventFlag + 3,
+ InputMethodOpenCandidateWindowEvent = InputMethodEventFlag + 4,
+ InputMethodCloseCandidateWindowEvent = InputMethodEventFlag + 5,
+ InputMethodRequest = InputMethodEventFlag + 6,
+ UnknownEvent = 542
+};
+
+} // namespace QtWindows
+
+inline QtWindows::WindowsEventType windowsEventType(UINT message, WPARAM wParamIn)
+{
+ switch (message) {
+ case WM_PAINT:
+ case WM_ERASEBKGND:
+ return QtWindows::ExposeEvent;
+ case WM_CLOSE:
+ return QtWindows::CloseEvent;
+ case WM_DESTROY:
+ return QtWindows::DestroyEvent;
+ case WM_ACTIVATEAPP:
+ return (int)wParamIn ?
+ QtWindows::ActivateApplicationEvent : QtWindows::DeactivateApplicationEvent;
+ case WM_ACTIVATE:
+ return LOWORD(wParamIn) == WA_INACTIVE ?
+ QtWindows::DeactivateWindowEvent : QtWindows::ActivateWindowEvent;
+ case WM_MOUSELEAVE:
+ return QtWindows::MouseEvent;
+ case WM_MOUSEWHEEL:
+ case WM_MOUSEHWHEEL:
+ return QtWindows::MouseWheelEvent;
+ case WM_MOVE:
+ return QtWindows::MoveEvent;
+ case WM_SHOWWINDOW:
+ return wParamIn ? QtWindows::ShowEvent : QtWindows::HideEvent;
+ case WM_SIZE:
+ return QtWindows::ResizeEvent;
+ case WM_NCCALCSIZE:
+ return QtWindows::CalculateSize;
+ case WM_GETMINMAXINFO:
+ return QtWindows::QuerySizeHints;
+ case WM_KEYDOWN: // keyboard event
+ case WM_SYSKEYDOWN:
+ return QtWindows::KeyDownEvent;
+ case WM_KEYUP:
+ case WM_SYSKEYUP:
+ case WM_CHAR:
+ return QtWindows::KeyEvent;
+ case WM_IME_CHAR:
+ return QtWindows::InputMethodKeyEvent;
+ case WM_IME_KEYDOWN:
+ return QtWindows::InputMethodKeyDownEvent;
+ case WM_TOUCH:
+ return QtWindows::TouchEvent;
+ case WM_CHANGECBCHAIN:
+ case WM_DRAWCLIPBOARD:
+ case WM_RENDERFORMAT:
+ case WM_RENDERALLFORMATS:
+ case WM_DESTROYCLIPBOARD:
+ return QtWindows::ClipboardEvent;
+ case WM_IME_STARTCOMPOSITION:
+ return QtWindows::InputMethodStartCompositionEvent;
+ case WM_IME_ENDCOMPOSITION:
+ return QtWindows::InputMethodEndCompositionEvent;
+ case WM_IME_COMPOSITION:
+ return QtWindows::InputMethodCompositionEvent;
+ case WM_IME_REQUEST:
+ return QtWindows::InputMethodRequest;
+ case WM_IME_NOTIFY:
+ switch (int(wParamIn)) {
+ case IMN_OPENCANDIDATE:
+ return QtWindows::InputMethodOpenCandidateWindowEvent;
+ case IMN_CLOSECANDIDATE:
+ return QtWindows::InputMethodCloseCandidateWindowEvent;
+ default:
+ break;
+ }
+ default:
+ break;
+ }
+ if (message >= WM_NCMOUSEMOVE && message <= WM_NCMBUTTONDBLCLK)
+ return QtWindows::NonClientMouseEvent; //
+ if ((message >= WM_MOUSEFIRST && message <= WM_MOUSELAST)
+ || (message >= WM_XBUTTONDOWN && message <= WM_XBUTTONDBLCLK))
+ return QtWindows::MouseEvent;
+ return QtWindows::UnknownEvent;
+}
+
+QT_END_NAMESPACE
+
+#endif // QTWINDOWSGLOBAL_H
diff --git a/src/plugins/platforms/windows/qwindows.qdocconf b/src/plugins/platforms/windows/qwindows.qdocconf
new file mode 100644
index 0000000000..c5a1ee904a
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindows.qdocconf
@@ -0,0 +1,27 @@
+project = "Qt Windows Lighthouse Plugin"
+description = "Documentation of the Qt Windows Lighthouse Plugin"
+
+language = Cpp
+
+headerdirs = .
+
+sourcedirs = .
+
+showinternal = true
+
+headers.fileextensions = "*.h"
+sources.fileextensions = "*.cpp *.qdoc"
+
+outputdir = doc
+
+qhp.projects = QtLighthouseWindows
+qhp.QtLighthouseWindowsDev.file = qtlighthousewindows-dev.qhp
+qhp.QtLighthouseWindowsDev.namespace = com.nokia.qt.developer.lighthouse
+qhp.QtLighthouseWindowsDev.virtualFolder = doc
+qhp.QtLighthouseWindowsDev.indexTitle = Qt Windows Lighthouse Plugin
+qhp.QtLighthouseWindowsDev.indexRoot =
+
+# Doxygen compatibility commands
+
+macro.see = "\\sa"
+macro.function = "\\fn"
diff --git a/src/plugins/platforms/windows/qwindowsbackingstore.cpp b/src/plugins/platforms/windows/qwindowsbackingstore.cpp
new file mode 100644
index 0000000000..a3698c4a7c
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsbackingstore.cpp
@@ -0,0 +1,143 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsbackingstore.h"
+#include "qwindowswindow.h"
+#include "qwindowsnativeimage.h"
+#include "qwindowscontext.h"
+
+#include <QtGui/QWindow>
+
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QWindowsBackingStore
+ \brief Backing store for windows.
+ \ingroup qt-lighthouse-win
+*/
+
+QWindowsBackingStore::QWindowsBackingStore(QWindow *window) :
+ QPlatformBackingStore(window)
+{
+ if (QWindowsContext::verboseBackingStore)
+ qDebug() << __FUNCTION__ << this << window;
+}
+
+QWindowsBackingStore::~QWindowsBackingStore()
+{
+ if (QWindowsContext::verboseBackingStore)
+ qDebug() << __FUNCTION__ << this;
+}
+
+QPaintDevice *QWindowsBackingStore::paintDevice()
+{
+ Q_ASSERT(!m_image.isNull());
+ return &m_image->image();
+}
+
+void QWindowsBackingStore::flush(QWindow *window, const QRegion &region,
+ const QPoint &offset)
+{
+ // TODO: Prepare paint for translucent windows.
+ const QRect br = region.boundingRect();
+ if (QWindowsContext::verboseBackingStore > 1)
+ qDebug() << __FUNCTION__ << window << offset << br;
+ QWindowsWindow *rw = rasterWindow();
+ const HDC dc = rw->getDC();
+ if (!dc) {
+ qErrnoWarning("%s: GetDC failed", __FUNCTION__);
+ return;
+ }
+
+ if (!BitBlt(dc, br.x(), br.y(), br.width(), br.height(),
+ m_image->hdc(), br.x() + offset.x(), br.y() + offset.y(), SRCCOPY))
+ qErrnoWarning("%s: BitBlt failed", __FUNCTION__);
+ rw->releaseDC();
+ // Write image for debug purposes.
+ if (QWindowsContext::verboseBackingStore > 2) {
+ static int n = 0;
+ const QString fileName = QString::fromAscii("win%1_%2.png").
+ arg(rw->winId()).arg(n++);
+ m_image->image().save(fileName);
+ qDebug() << "Wrote " << m_image->image().size() << fileName;
+ }
+}
+
+void QWindowsBackingStore::resize(const QSize &size, const QRegion &region)
+{
+ if (m_image.isNull() || m_image->image().size() != size) {
+ if (QWindowsContext::verboseBackingStore) {
+ QDebug nsp = qDebug().nospace();
+ nsp << __FUNCTION__ << ' ' << rasterWindow()->window()
+ << ' ' << size << ' ' << region;
+ if (!m_image.isNull())
+ nsp << " from: " << m_image->image().size();
+ }
+ m_image.reset(new QWindowsNativeImage(size.width(), size.height(),
+ QWindowsNativeImage::systemFormat()));
+ }
+}
+
+void QWindowsBackingStore::beginPaint(const QRegion &region)
+{
+ Q_UNUSED(region);
+ if (QWindowsContext::verboseBackingStore > 1)
+ qDebug() << __FUNCTION__;
+}
+
+QWindowsWindow *QWindowsBackingStore::rasterWindow() const
+{
+ if (const QWindow *w = window())
+ if (QPlatformWindow *pw = w->handle())
+ return static_cast<QWindowsWindow *>(pw);
+ return 0;
+}
+
+HDC QWindowsBackingStore::getDC() const
+{
+ if (!m_image.isNull())
+ return m_image->hdc();
+ return 0;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsbackingstore.h b/src/plugins/platforms/windows/qwindowsbackingstore.h
new file mode 100644
index 0000000000..53f033d14b
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsbackingstore.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSBACKINGSTORE_H
+#define QWINDOWSBACKINGSTORE_H
+
+#include "qtwindows_additional.h"
+
+#include <QtGui/QPlatformBackingStore>
+#include <QtCore/QScopedPointer>
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsWindow;
+class QWindowsNativeImage;
+
+class QWindowsBackingStore : public QPlatformBackingStore
+{
+ Q_DISABLE_COPY(QWindowsBackingStore)
+public:
+ QWindowsBackingStore(QWindow *window);
+ ~QWindowsBackingStore();
+
+ virtual QPaintDevice *paintDevice();
+ virtual void flush(QWindow *window, const QRegion &region, const QPoint &offset);
+ virtual void resize(const QSize &size, const QRegion &r);
+ virtual void beginPaint(const QRegion &);
+
+ HDC getDC() const;
+
+private:
+ QWindowsWindow *rasterWindow() const;
+
+ QScopedPointer<QWindowsNativeImage> m_image;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSBACKINGSTORE_H
diff --git a/src/plugins/platforms/windows/qwindowsclipboard.cpp b/src/plugins/platforms/windows/qwindowsclipboard.cpp
new file mode 100644
index 0000000000..93063441ba
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsclipboard.cpp
@@ -0,0 +1,366 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsclipboard.h"
+#include "qwindowscontext.h"
+#include "qwindowsole.h"
+#include "qwindowsmime.h"
+#include "qwindowsguieventdispatcher.h"
+
+#include <QtGui/QGuiApplication>
+#include <QtGui/QClipboard>
+#include <QtGui/QColor>
+#include <QtGui/QImage>
+
+#include <QtCore/QDebug>
+#include <QtCore/QMimeData>
+#include <QtCore/QStringList>
+#include <QtCore/QVariant>
+#include <QtCore/QUrl>
+
+QT_BEGIN_NAMESPACE
+
+static const char formatTextPlainC[] = "text/plain";
+static const char formatTextHtmlC[] = "text/html";
+
+/*!
+ \class QWindowsClipboard
+ \brief Clipboard implementation.
+
+ Registers a non-visible clipboard viewer window that
+ receives clipboard events in its own window procedure to be
+ able to receive clipboard-changed events, which
+ QPlatformClipboard needs to emit. That requires housekeeping
+ of the next in the viewer chain.
+
+ \note The OLE-functions used in this class require OleInitialize().
+
+ \ingroup qt-lighthouse-win
+*/
+
+QDebug operator<<(QDebug d, const QMimeData &m)
+{
+ QDebug nospace = d.nospace();
+ const QStringList formats = m.formats();
+ nospace << "QMimeData: " << formats.join(QStringLiteral(", ")) << '\n'
+ << " Text=" << m.hasText() << " HTML=" << m.hasHtml()
+ << " Color=" << m.hasColor() << " Image=" << m.hasImage()
+ << " URLs=" << m.hasUrls() << '\n';
+ if (m.hasText())
+ nospace << " Text: '" << m.text() << "'\n";
+ if (m.hasHtml())
+ nospace << " HTML: '" << m.html() << "'\n";
+ if (m.hasColor())
+ nospace << " Color: " << qvariant_cast<QColor>(m.colorData()) << '\n';
+ if (m.hasImage())
+ nospace << " Image: " << qvariant_cast<QImage>(m.imageData()).size() << '\n';
+ if (m.hasUrls())
+ nospace << " URLs: " << m.urls() << '\n';
+ return d;
+}
+
+/*!
+ \class QWindowsInternalMimeDataBase
+ \brief Base for implementations of QInternalMimeData using a IDataObject COM object.
+
+ In clipboard handling and Drag and drop, static instances
+ of QInternalMimeData implementations are kept and passed to the client.
+
+ QInternalMimeData provides virtuals that query the formats and retrieve
+ mime data on demand when the client invokes functions like QMimeData::hasHtml(),
+ QMimeData::html() on the instance returned. Otherwise, expensive
+ construction of a new QMimeData object containing all possible
+ formats would have to be done in each call to mimeData().
+
+ The base class introduces new virtuals to obtain and release
+ the instances IDataObject from the clipboard or Drag and Drop and
+ does conversion using QWindowsMime classes.
+
+ \sa QInternalMimeData, QWindowsMime, QWindowsMimeConverter
+ \ingroup qt-lighthouse-win
+*/
+
+bool QWindowsInternalMimeData::hasFormat_sys(const QString &mime) const
+{
+ IDataObject *pDataObj = retrieveDataObject();
+ if (!pDataObj)
+ return false;
+
+ const QWindowsMimeConverter &mc = QWindowsContext::instance()->mimeConverter();
+ const bool has = mc.converterToMime(mime, pDataObj) != 0;
+ releaseDataObject(pDataObj);
+ if (QWindowsContext::verboseOLE)
+ qDebug() << __FUNCTION__ << mime << has;
+ return has;
+}
+
+QStringList QWindowsInternalMimeData::formats_sys() const
+{
+ IDataObject *pDataObj = retrieveDataObject();
+ if (!pDataObj)
+ return QStringList();
+
+ const QWindowsMimeConverter &mc = QWindowsContext::instance()->mimeConverter();
+ const QStringList fmts = mc.allMimesForFormats(pDataObj);
+ releaseDataObject(pDataObj);
+ if (QWindowsContext::verboseOLE)
+ qDebug() << __FUNCTION__ << fmts;
+ return fmts;
+}
+
+QVariant QWindowsInternalMimeData::retrieveData_sys(const QString &mimeType,
+ QVariant::Type type) const
+{
+ IDataObject *pDataObj = retrieveDataObject();
+ if (!pDataObj)
+ return QVariant();
+
+ QVariant result;
+ const QWindowsMimeConverter &mc = QWindowsContext::instance()->mimeConverter();
+ if (const QWindowsMime *converter = mc.converterToMime(mimeType, pDataObj))
+ result = converter->convertToMime(mimeType, pDataObj, type);
+ releaseDataObject(pDataObj);
+ if (QWindowsContext::verboseOLE) {
+ QDebug nospace = qDebug().nospace();
+ nospace << __FUNCTION__ << ' ' << mimeType << ' ' << type
+ << " returns " << result.type();
+ if (result.type() != QVariant::ByteArray)
+ nospace << ' ' << result;
+ }
+ return result;
+}
+
+/*!
+ \class QWindowsClipboardRetrievalMimeData
+ \brief Special mime data class managing delayed retrieval of clipboard data.
+
+ Implementation of QWindowsInternalMimeDataBase that obtains the
+ IDataObject from the clipboard.
+
+ \sa QWindowsInternalMimeDataBase, QWindowsClipboard
+ \ingroup qt-lighthouse-win
+*/
+
+IDataObject *QWindowsClipboardRetrievalMimeData::retrieveDataObject() const
+{
+ IDataObject * pDataObj = 0;
+ if (OleGetClipboard(&pDataObj) == S_OK)
+ return pDataObj;
+ return 0;
+}
+
+void QWindowsClipboardRetrievalMimeData::releaseDataObject(IDataObject *dataObject) const
+{
+ dataObject->Release();
+}
+
+extern "C" LRESULT QT_WIN_CALLBACK qClipboardViewerWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ LRESULT result = 0;
+ if (QWindowsClipboard::instance()
+ && QWindowsClipboard::instance()->clipboardViewerWndProc(hwnd, message, wParam, lParam, &result))
+ return result;
+ return DefWindowProc(hwnd, message, wParam, lParam);
+}
+
+QWindowsClipboard *QWindowsClipboard::m_instance = 0;
+
+QWindowsClipboard::QWindowsClipboard() :
+ m_data(0), m_clipboardViewer(0), m_nextClipboardViewer(0)
+{
+ QWindowsClipboard::m_instance = this;
+}
+
+QWindowsClipboard::~QWindowsClipboard()
+{
+ unregisterViewer(); // Should release data if owner.
+ releaseIData();
+ QWindowsClipboard::m_instance = 0;
+}
+
+void QWindowsClipboard::releaseIData()
+{
+ if (m_data) {
+ delete m_data->mimeData();
+ m_data->releaseQt();
+ m_data->Release();
+ m_data = 0;
+ }
+}
+
+void QWindowsClipboard::registerViewer()
+{
+ m_clipboardViewer = QWindowsContext::instance()->
+ createDummyWindow(QStringLiteral("Qt5ClipboardView"), L"Qt5ClipboardView",
+ qClipboardViewerWndProc, WS_OVERLAPPED);
+ m_nextClipboardViewer = SetClipboardViewer(m_clipboardViewer);
+
+ if (QWindowsContext::verboseOLE)
+ qDebug("%s m_clipboardViewer: %p next=%p", __FUNCTION__,
+ m_clipboardViewer, m_nextClipboardViewer);
+}
+
+void QWindowsClipboard::unregisterViewer()
+{
+ if (m_clipboardViewer) {
+ ChangeClipboardChain(m_clipboardViewer, m_nextClipboardViewer);
+ DestroyWindow(m_clipboardViewer);
+ m_clipboardViewer = m_nextClipboardViewer = 0;
+ }
+}
+
+void QWindowsClipboard::propagateClipboardMessage(UINT message, WPARAM wParam, LPARAM lParam) const
+{
+ if (!m_nextClipboardViewer)
+ return;
+ // In rare cases, a clipboard viewer can hang (application crashed,
+ // suspended by a shell prompt 'Select' or debugger).
+ if (QWindowsContext::user32dll.isHungAppWindow
+ && QWindowsContext::user32dll.isHungAppWindow(m_nextClipboardViewer)) {
+ qWarning("%s: Cowardly refusing to send clipboard message to hung application...", Q_FUNC_INFO);
+ return;
+ }
+ SendMessage(m_nextClipboardViewer, message, wParam, lParam);
+}
+
+/*!
+ \brief Windows procedure of the clipboard viewer. Emits changed and does
+ housekeeping of the viewer chain.
+*/
+
+bool QWindowsClipboard::clipboardViewerWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result)
+{
+ *result = 0;
+ if (QWindowsContext::verboseOLE)
+ qDebug("%s HWND=%p 0x%x %s", __FUNCTION__, hwnd, message,
+ QWindowsGuiEventDispatcher::windowsMessageName(message));
+
+ switch (message) {
+ case WM_CHANGECBCHAIN: {
+ const HWND toBeRemoved = (HWND)wParam;
+ if (toBeRemoved == m_nextClipboardViewer) {
+ m_nextClipboardViewer = (HWND)lParam;
+ } else {
+ propagateClipboardMessage(message, wParam, lParam);
+ }
+ }
+ return true;
+ case WM_DRAWCLIPBOARD:
+ if (QWindowsContext::verboseOLE)
+ qDebug("Clipboard changed");
+ emitChanged(QClipboard::Clipboard);
+ // clean up the clipboard object if we no longer own the clipboard
+ if (!ownsClipboard() && m_data)
+ releaseIData();
+ propagateClipboardMessage(message, wParam, lParam);
+ return true;
+ case WM_DESTROY:
+ // Recommended shutdown
+ if (ownsClipboard()) {
+ if (QWindowsContext::verboseOLE)
+ qDebug("Clipboard owner on shutdown, releasing.");
+ OleFlushClipboard();
+ releaseIData();
+ }
+ return true;
+ } // switch (message)
+ return false;
+}
+
+QMimeData *QWindowsClipboard::mimeData(QClipboard::Mode mode)
+{
+ if (QWindowsContext::verboseOLE)
+ qDebug() << __FUNCTION__ << mode;
+ if (mode != QClipboard::Clipboard)
+ return 0;
+ return &m_retrievalData;
+}
+
+void QWindowsClipboard::setMimeData(QMimeData *mimeData, QClipboard::Mode mode)
+{
+ if (QWindowsContext::verboseOLE)
+ qDebug() << __FUNCTION__ << mode << *mimeData;
+ if (mode != QClipboard::Clipboard)
+ return;
+
+ const bool newData = !m_data || m_data->mimeData() != mimeData;
+ if (newData) {
+ releaseIData();
+ m_data = new QWindowsOleDataObject(mimeData);
+ }
+
+ const HRESULT src = OleSetClipboard(m_data);
+ if (src != S_OK) {
+ qErrnoWarning("OleSetClipboard: Failed to set data on clipboard: %s",
+ QWindowsContext::comErrorString(src).constData());
+ releaseIData();
+ return;
+ }
+}
+
+void QWindowsClipboard::clear()
+{
+ const HRESULT src = OleSetClipboard(0);
+ if (src != S_OK)
+ qErrnoWarning("OleSetClipboard: Failed to clear the clipboard: 0x%lx", src);
+}
+
+bool QWindowsClipboard::supportsMode(QClipboard::Mode mode) const
+{
+ return mode == QClipboard::Clipboard;
+}
+
+// Need a non-virtual in destructor.
+bool QWindowsClipboard::ownsClipboard() const
+{
+ return m_data && OleIsCurrentClipboard(m_data) == S_OK;
+}
+
+bool QWindowsClipboard::ownsMode(QClipboard::Mode mode) const
+{
+ const bool result = mode == QClipboard::Clipboard ?
+ ownsClipboard() : false;
+ if (QWindowsContext::verboseOLE)
+ qDebug("%s %d returns %d", __FUNCTION__, mode, result);
+ return result;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsclipboard.h b/src/plugins/platforms/windows/qwindowsclipboard.h
new file mode 100644
index 0000000000..fab6871012
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsclipboard.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSCLIPBOARD_H
+#define QWINDOWSCLIPBOARD_H
+
+#include "qwindowsinternalmimedata.h"
+
+#include <QtGui/QPlatformClipboard>
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsOleDataObject;
+
+class QWindowsClipboardRetrievalMimeData : public QWindowsInternalMimeData {
+public:
+
+protected:
+ virtual IDataObject *retrieveDataObject() const;
+ virtual void releaseDataObject(IDataObject *) const;
+};
+
+class QWindowsClipboard : public QPlatformClipboard
+{
+public:
+ QWindowsClipboard();
+ ~QWindowsClipboard();
+ void registerViewer(); // Call in initialization, when context is up.
+
+ virtual QMimeData *mimeData(QClipboard::Mode mode = QClipboard::Clipboard);
+ virtual void setMimeData(QMimeData *data, QClipboard::Mode mode = QClipboard::Clipboard);
+ virtual bool supportsMode(QClipboard::Mode mode) const;
+ virtual bool ownsMode(QClipboard::Mode mode) const;
+
+ inline bool clipboardViewerWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result);
+
+ static QWindowsClipboard *instance() { return m_instance; }
+
+private:
+ void clear();
+ void releaseIData();
+ inline void propagateClipboardMessage(UINT message, WPARAM wParam, LPARAM lParam) const;
+ inline void unregisterViewer();
+ inline bool ownsClipboard() const;
+
+ static QWindowsClipboard *m_instance;
+
+ QWindowsClipboardRetrievalMimeData m_retrievalData;
+ QWindowsOleDataObject *m_data;
+ HWND m_clipboardViewer;
+ HWND m_nextClipboardViewer;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSCLIPBOARD_H
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
new file mode 100644
index 0000000000..c77a111490
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -0,0 +1,750 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowscontext.h"
+#include "qwindowswindow.h"
+#include "qwindowskeymapper.h"
+#include "qwindowsguieventdispatcher.h"
+#include "qwindowsmousehandler.h"
+#include "qtwindowsglobal.h"
+#include "qwindowsmime.h"
+#include "qwindowsinputcontext.h"
+
+#include <QtGui/QWindow>
+#include <QtGui/QWindowSystemInterface>
+
+#include <QtCore/QSet>
+#include <QtCore/QHash>
+#include <QtCore/QStringList>
+#include <QtCore/QDebug>
+#include <QtCore/QSysInfo>
+#include <QtCore/QScopedArrayPointer>
+#include <QtCore/private/qsystemlibrary_p.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <windowsx.h>
+
+QT_BEGIN_NAMESPACE
+
+// Verbosity of components
+int QWindowsContext::verboseIntegration = 0;
+int QWindowsContext::verboseWindows = 0;
+int QWindowsContext::verboseEvents = 0;
+int QWindowsContext::verboseBackingStore = 0;
+int QWindowsContext::verboseFonts = 0;
+int QWindowsContext::verboseGL = 0;
+int QWindowsContext::verboseOLE = 0;
+int QWindowsContext::verboseInputMethods = 0;
+
+// Get verbosity of components from "foo:2,bar:3"
+static inline int componentVerbose(const char *v, const char *keyWord)
+{
+ if (const char *k = strstr(v, keyWord)) {
+ k += qstrlen(keyWord);
+ if (*k == ':') {
+ ++k;
+ if (isdigit(*k))
+ return *k - '0';
+ }
+ }
+ return 0;
+}
+
+static inline bool hasTouchSupport(QSysInfo::WinVersion wv)
+{
+ enum { QT_SM_DIGITIZER = 94, QT_NID_INTEGRATED_TOUCH = 0x1,
+ QT_NID_EXTERNAL_TOUCH = 0x02, QT_NID_MULTI_INPUT = 0x40 };
+
+ return wv < QSysInfo::WV_WINDOWS7 ? false :
+ (GetSystemMetrics(QT_SM_DIGITIZER) & (QT_NID_INTEGRATED_TOUCH | QT_NID_EXTERNAL_TOUCH | QT_NID_MULTI_INPUT)) != 0;
+}
+
+#if !defined(LANG_SYRIAC)
+# define LANG_SYRIAC 0x5a
+#endif
+
+static inline bool useRTL_Extensions(QSysInfo::WinVersion ver)
+{
+ if ((ver & QSysInfo::WV_NT_based) && (ver >= QSysInfo::WV_VISTA)) {
+ // Since the IsValidLanguageGroup/IsValidLocale functions always return true on
+ // Vista, check the Keyboard Layouts for enabling RTL.
+ if (const UINT nLayouts = GetKeyboardLayoutList(0, 0)) {
+ QScopedArrayPointer<HKL> lpList(new HKL[nLayouts]);
+ GetKeyboardLayoutList(nLayouts, lpList.data());
+ for (UINT i = 0; i < nLayouts; ++i) {
+ switch (PRIMARYLANGID((quintptr)lpList[i])) {
+ case LANG_ARABIC:
+ case LANG_HEBREW:
+ case LANG_FARSI:
+ case LANG_SYRIAC:
+ return true;
+ default:
+ break;
+ }
+ }
+ }
+ return false;
+ } // NT/Vista
+ // Pre-NT: figure out whether a RTL language is installed
+ return IsValidLanguageGroup(LGRPID_ARABIC, LGRPID_INSTALLED)
+ || IsValidLanguageGroup(LGRPID_HEBREW, LGRPID_INSTALLED)
+ || IsValidLocale(MAKELCID(MAKELANGID(LANG_ARABIC, SUBLANG_DEFAULT), SORT_DEFAULT), LCID_INSTALLED)
+ || IsValidLocale(MAKELCID(MAKELANGID(LANG_HEBREW, SUBLANG_DEFAULT), SORT_DEFAULT), LCID_INSTALLED)
+ || IsValidLocale(MAKELCID(MAKELANGID(LANG_SYRIAC, SUBLANG_DEFAULT), SORT_DEFAULT), LCID_INSTALLED)
+ || IsValidLocale(MAKELCID(MAKELANGID(LANG_FARSI, SUBLANG_DEFAULT), SORT_DEFAULT), LCID_INSTALLED);
+}
+
+/*!
+ \class QWindowsUser32DLL
+ \brief Struct that contains dynamically resolved symbols of User32.dll.
+
+ The stub libraries shipped with the MinGW compiler miss some of the
+ functions. They need to be retrieved dynamically.
+
+ In addition, touch-related functions are available only from Windows onwards.
+ These need to resolved dynamically for Q_CC_MSVC as well.
+
+ \ingroup qt-lighthouse-win
+*/
+
+QWindowsUser32DLL::QWindowsUser32DLL() :
+ setLayeredWindowAttributes(0), updateLayeredWindow(0),
+ updateLayeredWindowIndirect(0),
+ isHungAppWindow(0),
+ registerTouchWindow(0), getTouchInputInfo(0), closeTouchInputHandle(0)
+{
+}
+
+void QWindowsUser32DLL::init()
+{
+ QSystemLibrary library(QStringLiteral("user32"));
+ // MinGW (g++ 3.4.5) accepts only C casts.
+ setLayeredWindowAttributes = (SetLayeredWindowAttributes)(library.resolve("SetLayeredWindowAttributes"));
+ updateLayeredWindow = (UpdateLayeredWindow)(library.resolve("UpdateLayeredWindow"));
+ updateLayeredWindowIndirect = (UpdateLayeredWindowIndirect)(library.resolve("UpdateLayeredWindowIndirect"));
+
+ Q_ASSERT(setLayeredWindowAttributes && updateLayeredWindow
+ && updateLayeredWindowIndirect);
+
+ isHungAppWindow = (IsHungAppWindow)library.resolve("IsHungAppWindow");
+}
+
+bool QWindowsUser32DLL::initTouch()
+{
+ QSystemLibrary library(QStringLiteral("user32"));
+ registerTouchWindow = (RegisterTouchWindow)(library.resolve("RegisterTouchWindow"));
+ getTouchInputInfo = (GetTouchInputInfo)(library.resolve("GetTouchInputInfo"));
+ closeTouchInputHandle = (CloseTouchInputHandle)(library.resolve("CloseTouchInputHandle"));
+ return registerTouchWindow && getTouchInputInfo && getTouchInputInfo;
+}
+
+QWindowsUser32DLL QWindowsContext::user32dll;
+
+QWindowsContext *QWindowsContext::m_instance = 0;
+
+/*!
+ \class QWindowsContext
+ \brief Singleton container for all relevant information.
+
+ Holds state information formerly stored in \c qapplication_win.cpp.
+ \ingroup qt-lighthouse-win
+*/
+
+typedef QHash<HWND, QWindowsWindow *> HandleBaseWindowHash;
+
+struct QWindowsContextPrivate {
+ explicit QWindowsContextPrivate(bool isOpenGL);
+
+ const bool m_isOpenGL;
+ unsigned m_systemInfo;
+ QSet<QString> m_registeredWindowClassNames;
+ HandleBaseWindowHash m_windows;
+ HDC m_displayContext;
+ const int m_defaultDPI;
+ QWindowsKeyMapper m_keyMapper;
+ QWindowsMouseHandler m_mouseHandler;
+ QWindowsMimeConverter m_mimeConverter;
+ QSharedPointer<QWindowCreationContext> m_creationContext;
+ const HRESULT m_oleInitializeResult;
+};
+
+QWindowsContextPrivate::QWindowsContextPrivate(bool isOpenGL) :
+ m_isOpenGL(isOpenGL),
+ m_systemInfo(0),
+ m_displayContext(GetDC(0)),
+ m_defaultDPI(GetDeviceCaps(m_displayContext,LOGPIXELSY)),
+ m_oleInitializeResult(OleInitialize(NULL))
+{
+ QWindowsContext::user32dll.init();
+
+ const QSysInfo::WinVersion ver = QSysInfo::windowsVersion();
+
+ if (hasTouchSupport(ver) && QWindowsContext::user32dll.initTouch())
+ m_systemInfo |= QWindowsContext::SI_SupportsTouch;
+
+ if (useRTL_Extensions(ver)) {
+ m_systemInfo |= QWindowsContext::SI_RTL_Extensions;
+ m_keyMapper.setUseRTLExtensions(true);
+ }
+}
+
+QWindowsContext::QWindowsContext(bool isOpenGL) :
+ d(new QWindowsContextPrivate(isOpenGL))
+{
+#ifdef Q_CC_MSVC
+# pragma warning( disable : 4996 )
+#endif
+ m_instance = this;
+ if (const char *v = getenv("QT_LIGHTHOUSE_WINDOWS_VERBOSE")) {
+ QWindowsContext::verboseIntegration = componentVerbose(v, "integration");
+ QWindowsContext::verboseWindows = componentVerbose(v, "windows");
+ QWindowsContext::verboseEvents = componentVerbose(v, "events");
+ QWindowsContext::verboseBackingStore = componentVerbose(v, "backingstore");
+ QWindowsContext::verboseFonts = componentVerbose(v, "fonts");
+ QWindowsContext::verboseGL = componentVerbose(v, "gl");
+ QWindowsContext::verboseOLE = componentVerbose(v, "ole");
+ QWindowsContext::verboseInputMethods = componentVerbose(v, "im");
+ }
+}
+
+QWindowsContext::~QWindowsContext()
+{
+ unregisterWindowClasses();
+ if (d->m_oleInitializeResult == S_OK || d->m_oleInitializeResult == S_FALSE)
+ OleUninitialize();
+
+ m_instance = 0;
+}
+
+QWindowsContext *QWindowsContext::instance()
+{
+ return m_instance;
+}
+
+unsigned QWindowsContext::systemInfo() const
+{
+ return d->m_systemInfo;
+}
+
+void QWindowsContext::setWindowCreationContext(const QSharedPointer<QWindowCreationContext> &ctx)
+{
+ d->m_creationContext = ctx;
+}
+
+bool QWindowsContext::isOpenGL() const
+{
+ return d->m_isOpenGL;
+}
+
+int QWindowsContext::defaultDPI() const
+{
+ return d->m_defaultDPI;
+}
+
+HDC QWindowsContext::displayContext() const
+{
+ return d->m_displayContext;
+}
+
+QWindow *QWindowsContext::keyGrabber() const
+{
+ return d->m_keyMapper.keyGrabber();
+}
+
+void QWindowsContext::setKeyGrabber(QWindow *w)
+{
+ d->m_keyMapper.setKeyGrabber(w);
+}
+
+// Window class registering code (from qapplication_win.cpp)
+// If 0 is passed as the widget pointer, register a window class
+// for QWidget as default. This is used in QGLTemporaryContext
+// during GL initialization, where we don't want to use temporary
+// QWidgets or QGLWidgets, neither do we want to have separate code
+// to register window classes.
+
+QString QWindowsContext::registerWindowClass(const QWindow *w, bool isGL)
+{
+ const Qt::WindowFlags flags = w ? w->windowFlags() : (Qt::WindowFlags)0;
+ const Qt::WindowFlags type = flags & Qt::WindowType_Mask;
+
+ uint style = 0;
+ bool icon = false;
+ QString cname = "Qt5";
+ if (w && isGL) {
+ cname += QStringLiteral("QGLWindow");
+ style = CS_DBLCLKS|CS_OWNDC;
+ icon = true;
+ } else if (w && (flags & Qt::MSWindowsOwnDC)) {
+ cname += QStringLiteral("QWindowOwnDC");
+ style = CS_DBLCLKS|CS_OWNDC;
+ icon = true;
+ } else if (w && (type == Qt::Tool || type == Qt::ToolTip)) {
+ style = CS_DBLCLKS;
+ if (w->inherits("QTipLabel") || w->inherits("QAlphaWidget")) {
+ if ((QSysInfo::WindowsVersion >= QSysInfo::WV_XP
+ && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)) {
+ style |= CS_DROPSHADOW;
+ }
+ cname += QStringLiteral("QToolTip");
+ } else {
+ cname += QStringLiteral("QTool");
+ }
+ style |= CS_SAVEBITS;
+ icon = false;
+ } else if (w && (type == Qt::Popup)) {
+ cname += QStringLiteral("QPopup");
+ style = CS_DBLCLKS|CS_SAVEBITS;
+ if ((QSysInfo::WindowsVersion >= QSysInfo::WV_XP
+ && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based))
+ style |= CS_DROPSHADOW;
+ icon = false;
+ } else {
+ cname += QStringLiteral("QWindow");
+ style = CS_DBLCLKS;
+ icon = true;
+ }
+
+ // force CS_OWNDC when the GL graphics system is
+ // used as the default renderer
+ if (d->m_isOpenGL)
+ style |= CS_OWNDC;
+
+ HBRUSH brush = 0;
+ if (w && !isGL)
+ brush = GetSysColorBrush(COLOR_WINDOW);
+ return registerWindowClass(cname, qWindowsWndProc, style, brush, icon);
+}
+
+QString QWindowsContext::registerWindowClass(QString cname,
+ WNDPROC proc,
+ unsigned style,
+ HBRUSH brush,
+ bool icon)
+{
+ // since multiple Qt versions can be used in one process
+ // each one has to have window class names with a unique name
+ // The first instance gets the unmodified name; if the class
+ // has already been registered by another instance of Qt then
+ // add an instance-specific ID, the address of the window proc.
+ static int classExists = -1;
+
+ const HINSTANCE appInstance = (HINSTANCE)GetModuleHandle(0);
+ if (classExists == -1) {
+ WNDCLASS wcinfo;
+ classExists = GetClassInfo(appInstance, (wchar_t*)cname.utf16(), &wcinfo);
+ classExists = classExists && wcinfo.lpfnWndProc != proc;
+ }
+
+ if (classExists)
+ cname += QString::number((quintptr)proc);
+
+ if (d->m_registeredWindowClassNames.contains(cname)) // already registered in our list
+ return cname;
+
+ WNDCLASSEX wc;
+ wc.cbSize = sizeof(WNDCLASSEX);
+ wc.style = style;
+ wc.lpfnWndProc = proc;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = 0;
+ wc.hInstance = appInstance;
+ if (icon) {
+ wc.hIcon = (HICON)LoadImage(appInstance, L"IDI_ICON1", IMAGE_ICON, 0, 0, LR_DEFAULTSIZE);
+ if (wc.hIcon) {
+ int sw = GetSystemMetrics(SM_CXSMICON);
+ int sh = GetSystemMetrics(SM_CYSMICON);
+ wc.hIconSm = (HICON)LoadImage(appInstance, L"IDI_ICON1", IMAGE_ICON, sw, sh, 0);
+ } else {
+ wc.hIcon = (HICON)LoadImage(0, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
+ wc.hIconSm = 0;
+ }
+ } else {
+ wc.hIcon = 0;
+ wc.hIconSm = 0;
+ }
+ wc.hCursor = 0;
+ wc.hbrBackground = brush;
+ wc.lpszMenuName = 0;
+ wc.lpszClassName = (wchar_t*)cname.utf16();
+ ATOM atom = RegisterClassEx(&wc);
+
+ if (!atom)
+ qErrnoWarning("QApplication::regClass: Registering window class '%s' failed.",
+ qPrintable(cname));
+
+ d->m_registeredWindowClassNames.insert(cname);
+ if (QWindowsContext::verboseIntegration || QWindowsContext::verboseWindows)
+ qDebug().nospace() << __FUNCTION__ << ' ' << cname
+ << " style=0x" << QString::number(style, 16)
+ << " brush=" << brush << " icon=" << icon << " atom=" << atom;
+ return cname;
+}
+
+void QWindowsContext::unregisterWindowClasses()
+{
+ const HINSTANCE appInstance = (HINSTANCE)GetModuleHandle(0);
+
+ foreach (const QString &name, d->m_registeredWindowClassNames) {
+ if (QWindowsContext::verboseIntegration)
+ qDebug() << __FUNCTION__ << name;
+ UnregisterClass((wchar_t*)name.utf16(), appInstance);
+ }
+ d->m_registeredWindowClassNames.clear();
+}
+
+int QWindowsContext::screenDepth() const
+{
+ return GetDeviceCaps(d->m_displayContext, BITSPIXEL);
+}
+
+QString QWindowsContext::windowsErrorMessage(unsigned long errorCode)
+{
+ QString rc = QString::fromLatin1("#%1: ").arg(errorCode);
+ ushort *lpMsgBuf;
+
+ const int len = FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, errorCode, 0, (LPTSTR)&lpMsgBuf, 0, NULL);
+ if (len) {
+ rc = QString::fromUtf16(lpMsgBuf, len);
+ LocalFree(lpMsgBuf);
+ } else {
+ rc += QString::fromLatin1("<unknown error>");
+ }
+ return rc;
+}
+
+void QWindowsContext::addWindow(HWND hwnd, QWindowsWindow *w)
+{
+ d->m_windows.insert(hwnd, w);
+}
+
+void QWindowsContext::removeWindow(HWND hwnd)
+{
+ const HandleBaseWindowHash::iterator it = d->m_windows.find(hwnd);
+ if (it != d->m_windows.end()) {
+ if (d->m_keyMapper.keyGrabber() == it.value()->window())
+ d->m_keyMapper.setKeyGrabber(0);
+ d->m_windows.erase(it);
+ }
+}
+
+QWindowsWindow *QWindowsContext::findPlatformWindow(HWND hwnd) const
+{
+ return d->m_windows.value(hwnd);
+}
+
+QWindow *QWindowsContext::findWindow(HWND hwnd) const
+{
+ if (const QWindowsWindow *bw = findPlatformWindow(hwnd))
+ return bw->window();
+ return 0;
+}
+
+QWindow *QWindowsContext::windowUnderMouse() const
+{
+ return d->m_mouseHandler.windowUnderMouse();
+}
+
+/*!
+ \brief Find a child window at a screen point.
+
+ Deep search for a QWindow at global point, skipping non-owned
+ windows (accessibility?). Implemented using ChildWindowFromPointEx()
+ instead of (historically used) WindowFromPoint() to get a well-defined
+ behaviour for hidden/transparent windows.
+
+ \a cwex_flags are flags of ChildWindowFromPointEx().
+ \a parent is the parent window, pass GetDesktopWindow() for top levels.
+*/
+
+QWindowsWindow *QWindowsContext::findPlatformWindowAt(HWND parent,
+ const QPoint &screenPointIn,
+ unsigned cwex_flags) const
+{
+ QWindowsWindow *result = 0;
+ const POINT screenPoint = { screenPointIn.x(), screenPointIn.y() };
+ while (true) {
+ POINT point = screenPoint;
+ ScreenToClient(parent, &point);
+ // Returns parent if inside & none matched.
+ const HWND child = ChildWindowFromPointEx(parent, point, cwex_flags);
+ if (child && child != parent) {
+ if (QWindowsWindow *window = findPlatformWindow(child))
+ result = window;
+ parent = child;
+ } else {
+ break;
+ }
+ }
+ return result;
+}
+
+QWindowsMimeConverter &QWindowsContext::mimeConverter() const
+{
+ return d->m_mimeConverter;
+}
+
+/*!
+ \brief Convenience to create a non-visible dummy window
+ for example used as clipboard watcher or for GL.
+*/
+
+HWND QWindowsContext::createDummyWindow(const QString &classNameIn,
+ const wchar_t *windowName,
+ WNDPROC wndProc, DWORD style)
+{
+ if (!wndProc)
+ wndProc = DefWindowProc;
+ QString className = registerWindowClass(classNameIn, wndProc);
+ return CreateWindowEx(0, (wchar_t*)className.utf16(),
+ windowName, style,
+ CW_USEDEFAULT, CW_USEDEFAULT,
+ CW_USEDEFAULT, CW_USEDEFAULT,
+ 0, NULL, (HINSTANCE)GetModuleHandle(0), NULL);
+}
+
+/*!
+ \brief Common COM error strings.
+*/
+
+QByteArray QWindowsContext::comErrorString(HRESULT hr)
+{
+ switch (hr) {
+ case S_OK:
+ return QByteArray("S_OK");
+ case S_FALSE:
+ return QByteArray("S_FALSE");
+ case E_UNEXPECTED:
+ return QByteArray("E_UNEXPECTED");
+ case CO_E_ALREADYINITIALIZED:
+ return QByteArray("CO_E_ALREADYINITIALIZED");
+ case CO_E_NOTINITIALIZED:
+ return QByteArray("CO_E_NOTINITIALIZED");
+ case RPC_E_CHANGED_MODE:
+ return QByteArray("RPC_E_CHANGED_MODE");
+ case OLE_E_WRONGCOMPOBJ:
+ return QByteArray("OLE_E_WRONGCOMPOBJ");
+ case CO_E_NOT_SUPPORTED:
+ return QByteArray("CO_E_NOT_SUPPORTED");
+ case E_NOTIMPL:
+ return QByteArray("E_NOTIMPL");
+ case E_INVALIDARG:
+ return QByteArray("");
+ case E_NOINTERFACE:
+ return QByteArray("");
+ case E_POINTER:
+ return QByteArray("");
+ case E_HANDLE:
+ return QByteArray("");
+ case E_ABORT:
+ return QByteArray("");
+ case E_FAIL:
+ return QByteArray("");
+ case E_ACCESSDENIED:
+ return QByteArray("");
+ default:
+ break;
+ }
+ return "Unknown error 0x" + QByteArray::number(quint64(hr), 16);
+}
+
+/*!
+ \brief Main windows procedure registered for windows.
+
+ \sa QWindowsGuiEventDispatcher
+*/
+
+bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
+ QtWindows::WindowsEventType et,
+ WPARAM wParam, LPARAM lParam, LRESULT *result)
+{
+ *result = 0;
+ // Events without an associated QWindow or events we are not interested in.
+ switch (et) {
+ case QtWindows::DeactivateApplicationEvent:
+ case QtWindows::DeactivateWindowEvent:
+ QWindowSystemInterface::handleWindowActivated(0);
+ return true;
+ case QtWindows::InputMethodStartCompositionEvent:
+ return QWindowsInputContext::instance()->startComposition(hwnd);
+ case QtWindows::InputMethodCompositionEvent:
+ return QWindowsInputContext::instance()->composition(hwnd, lParam);
+ case QtWindows::InputMethodEndCompositionEvent:
+ return QWindowsInputContext::instance()->endComposition(hwnd);
+ case QtWindows::InputMethodRequest:
+ return QWindowsInputContext::instance()->handleIME_Request(wParam, lParam, result);
+ case QtWindows::InputMethodOpenCandidateWindowEvent:
+ case QtWindows::InputMethodCloseCandidateWindowEvent:
+ // TODO: Release/regrab mouse if a popup has mouse grab.
+ return false;
+ case QtWindows::ClipboardEvent:
+ case QtWindows::DestroyEvent:
+
+ case QtWindows::UnknownEvent:
+ return false;
+ default:
+ break;
+ }
+
+ QWindowsWindow *platformWindow = findPlatformWindow(hwnd);
+ // Before CreateWindowEx() returns, some events are sent,
+ // for example WM_GETMINMAXINFO asking for size constraints for top levels.
+ // Pass on to current creation context
+ if (!platformWindow && !d->m_creationContext.isNull()) {
+ switch (et) {
+ case QtWindows::QuerySizeHints:
+ d->m_creationContext->applyToMinMaxInfo(reinterpret_cast<MINMAXINFO *>(lParam));
+ return true;
+ case QtWindows::ResizeEvent:
+ d->m_creationContext->obtainedGeometry.setSize(QSize(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)));
+ return true;
+ case QtWindows::MoveEvent:
+ d->m_creationContext->obtainedGeometry.moveTo(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
+ return true;
+ case QtWindows::CalculateSize:
+ return false;
+ default:
+ break;
+ }
+ }
+ if (platformWindow) {
+ if (QWindowsContext::verboseEvents > 1)
+ qDebug().nospace() << "Event window: " << platformWindow->window();
+ } else {
+ qWarning("%s: No Qt Window found for event 0x%x (%s), hwnd=0x%p.",
+ __FUNCTION__, message,
+ QWindowsGuiEventDispatcher::windowsMessageName(message), hwnd);
+ return false;
+ }
+
+ MSG msg;
+ msg.hwnd = hwnd; // re-create MSG structure
+ msg.message = message; // time and pt fields ignored
+ msg.wParam = wParam;
+ msg.lParam = lParam;
+ msg.pt.x = GET_X_LPARAM(lParam);
+ msg.pt.y = GET_Y_LPARAM(lParam);
+
+ switch (et) {
+ case QtWindows::KeyDownEvent:
+ case QtWindows::KeyEvent:
+ case QtWindows::InputMethodKeyEvent:
+ case QtWindows::InputMethodKeyDownEvent:
+ return d->m_keyMapper.translateKeyEvent(platformWindow->window(), hwnd, msg, result);
+ case QtWindows::MoveEvent:
+ platformWindow->handleMoved();
+ return true;
+ case QtWindows::ResizeEvent:
+ platformWindow->handleResized((int)wParam);
+ return true;
+ case QtWindows::QuerySizeHints:
+ platformWindow->getSizeHints(reinterpret_cast<MINMAXINFO *>(lParam));
+ return true;
+ case QtWindows::CalculateSize:
+ // NCCALCSIZE_PARAMS structure if wParam==TRUE
+ if (wParam && QWindowsContext::verboseWindows) {
+ const NCCALCSIZE_PARAMS *ncp = reinterpret_cast<NCCALCSIZE_PARAMS *>(lParam);
+ qDebug() << platformWindow->window() << *ncp;
+ }
+ break;
+ case QtWindows::ExposeEvent:
+ platformWindow->handleWmPaint(hwnd, message, wParam, lParam);
+ return true;
+ case QtWindows::MouseWheelEvent:
+ case QtWindows::MouseEvent:
+ case QtWindows::NonClientMouseEvent:
+ case QtWindows::LeaveEvent:
+ return d->m_mouseHandler.translateMouseEvent(platformWindow->window(), hwnd, et, msg, result);
+ case QtWindows::TouchEvent:
+ return d->m_mouseHandler.translateTouchEvent(platformWindow->window(), hwnd, et, msg, result);
+ case QtWindows::ActivateWindowEvent:
+ QWindowSystemInterface::handleWindowActivated(platformWindow->window());
+ return true;
+ case QtWindows::ShowEvent:
+ platformWindow->handleShown();
+ return true;
+ case QtWindows::HideEvent:
+ platformWindow->handleHidden();
+ return true;
+ case QtWindows::CloseEvent:
+ QWindowSystemInterface::handleCloseEvent(platformWindow->window());
+ return true;
+ default:
+ break;
+ }
+ return false;
+}
+
+/*!
+ \brief Windows functions for actual windows.
+
+ There is another one for timers, sockets, etc in
+ QEventDispatcherWin32.
+
+ \ingroup qt-lighthouse-win
+*/
+
+extern "C" LRESULT QT_WIN_CALLBACK qWindowsWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ LRESULT result;
+ const QtWindows::WindowsEventType et = windowsEventType(message, wParam);
+ const bool handled = QWindowsContext::instance()->windowsProc(hwnd, message, et, wParam, lParam, &result);
+ const bool guiEventsQueued = QWindowSystemInterface::windowSystemEventsQueued();
+ if (QWindowsContext::verboseEvents > 1)
+ if (const char *eventName = QWindowsGuiEventDispatcher::windowsMessageName(message))
+ qDebug("EVENT: hwd=%p %s msg=0x%x et=0x%x wp=%d at %d,%d handled=%d gui=%d",
+ hwnd, eventName, message, et, int(wParam),
+ GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), handled, guiEventsQueued);
+ if (guiEventsQueued) {
+ const QWindowsGuiEventDispatcher::DispatchContext dispatchContext =
+ QWindowsGuiEventDispatcher::currentDispatchContext();
+ if (dispatchContext.first)
+ QWindowSystemInterface::sendWindowSystemEvents(dispatchContext.first, dispatchContext.second);
+ }
+ if (!handled)
+ result = DefWindowProc(hwnd, message, wParam, lParam);
+ return result;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowscontext.h b/src/plugins/platforms/windows/qwindowscontext.h
new file mode 100644
index 0000000000..93662384c0
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowscontext.h
@@ -0,0 +1,172 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSCONTEXT_H
+#define QWINDOWSCONTEXT_H
+
+#include "qtwindowsglobal.h"
+#include "qtwindows_additional.h"
+
+#include <QtCore/QScopedPointer>
+#include <QtCore/QSharedPointer>
+
+QT_BEGIN_NAMESPACE
+
+class QWindow;
+class QPlatformScreen;
+class QWindowsWindow;
+class QWindowsMimeConverter;
+struct QWindowCreationContext;
+struct QWindowsContextPrivate;
+class QPoint;
+
+struct QWindowsUser32DLL
+{
+ QWindowsUser32DLL();
+ inline void init();
+ inline bool initTouch();
+
+ typedef BOOL (WINAPI *RegisterTouchWindow)(HWND, ULONG);
+ typedef BOOL (WINAPI *GetTouchInputInfo)(HANDLE, UINT, PVOID, int);
+ typedef BOOL (WINAPI *CloseTouchInputHandle)(HANDLE);
+ typedef BOOL (WINAPI *SetLayeredWindowAttributes)(HWND, COLORREF, BYTE, DWORD);
+ typedef BOOL (WINAPI *UpdateLayeredWindow)(HWND, HDC , const POINT *,
+ const SIZE *, HDC, const POINT *, COLORREF,
+ const BLENDFUNCTION *, DWORD);
+ typedef BOOL (WINAPI *UpdateLayeredWindowIndirect)(HWND, const UPDATELAYEREDWINDOWINFO *);
+ typedef BOOL (WINAPI *IsHungAppWindow)(HWND);
+
+ // Functions missing in Q_CC_GNU stub libraries.
+ SetLayeredWindowAttributes setLayeredWindowAttributes;
+ UpdateLayeredWindow updateLayeredWindow;
+ UpdateLayeredWindowIndirect updateLayeredWindowIndirect;
+
+ // Functions missing in older versions of Windows
+ IsHungAppWindow isHungAppWindow;
+
+ // Touch functions from Windows 7 onwards (also for use with Q_CC_MSVC).
+ RegisterTouchWindow registerTouchWindow;
+ GetTouchInputInfo getTouchInputInfo;
+ CloseTouchInputHandle closeTouchInputHandle;
+};
+
+class QWindowsContext
+{
+ Q_DISABLE_COPY(QWindowsContext)
+public:
+ enum SystemInfoFlags
+ {
+ SI_RTL_Extensions = 0x1,
+ SI_SupportsTouch = 0x2
+ };
+
+ // Verbose flag set by environment variable QT_LIGHTHOUSE_WINDOWS_VERBOSE
+ static int verboseIntegration;
+ static int verboseWindows;
+ static int verboseBackingStore;
+ static int verboseEvents;
+ static int verboseFonts;
+ static int verboseGL;
+ static int verboseOLE;
+ static int verboseInputMethods;
+
+ explicit QWindowsContext(bool isOpenGL);
+ ~QWindowsContext();
+
+ bool isOpenGL() const;
+
+ int defaultDPI() const;
+
+ QString registerWindowClass(const QWindow *w, bool isGL);
+ QString registerWindowClass(QString cname, WNDPROC proc,
+ unsigned style = 0, HBRUSH brush = 0,
+ bool icon = false);
+ HWND createDummyWindow(const QString &classNameIn,
+ const wchar_t *windowName,
+ WNDPROC wndProc = 0, DWORD style = WS_OVERLAPPED);
+
+ HDC displayContext() const;
+ int screenDepth() const;
+
+ static QWindowsContext *instance();
+
+ static QString windowsErrorMessage(unsigned long errorCode);
+
+ void addWindow(HWND, QWindowsWindow *w);
+ void removeWindow(HWND);
+
+ QWindowsWindow *findPlatformWindow(HWND) const;
+ QWindow *findWindow(HWND) const;
+ QWindowsWindow *findPlatformWindowAt(HWND parent, const QPoint &screenPoint,
+ unsigned cwex_flags) const;
+
+ QWindow *windowUnderMouse() const;
+
+ inline bool windowsProc(HWND hwnd, UINT message,
+ QtWindows::WindowsEventType et,
+ WPARAM wParam, LPARAM lParam, LRESULT *result);
+
+ QWindow *keyGrabber() const;
+ void setKeyGrabber(QWindow *hwnd);
+
+ void setWindowCreationContext(const QSharedPointer<QWindowCreationContext> &ctx);
+
+ // Returns a combination of SystemInfoFlags
+ unsigned systemInfo() const;
+
+ QWindowsMimeConverter &mimeConverter() const;
+
+ static QWindowsUser32DLL user32dll;
+
+ static QByteArray comErrorString(HRESULT hr);
+
+private:
+ void unregisterWindowClasses();
+
+ QScopedPointer<QWindowsContextPrivate> d;
+ static QWindowsContext *m_instance;
+};
+
+extern "C" LRESULT QT_WIN_CALLBACK qWindowsWndProc(HWND, UINT, WPARAM, LPARAM);
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSCONTEXT_H
diff --git a/src/plugins/platforms/windows/qwindowscursor.cpp b/src/plugins/platforms/windows/qwindowscursor.cpp
new file mode 100644
index 0000000000..1ad2079962
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowscursor.cpp
@@ -0,0 +1,451 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowscursor.h"
+#include "qwindowscontext.h"
+#include "qwindowswindow.h"
+#include "qwindowsscreen.h"
+#include "pixmaputils.h"
+
+#include <QtGui/QPixmap>
+#include <QtGui/QImage>
+#include <QtGui/QBitmap>
+#include <QtGui/QGuiApplication>
+#include <QtGui/QScreen>
+#include <QtGui/private/qguiapplication_p.h> // getPixmapCursor()
+
+#include <QtCore/QDebug>
+#include <QtCore/QScopedArrayPointer>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QWindowsCursor
+ \brief Platform cursor implementation
+
+ Note that whereas under X11, a cursor can be set as a property of
+ a window, there is only a global SetCursor() function on Windows.
+ Each Window sets on the global cursor on receiving a Enter-event
+ as do the Window manager frames (resize/move handles).
+
+ \ingroup qt-lighthouse-win
+ \sa QWindowsWindowCursor
+*/
+
+QWindowsCursor::QWindowsCursor(QPlatformScreen *s) :
+ QPlatformCursor(s)
+{
+}
+
+HCURSOR QWindowsCursor::createPixmapCursor(const QPixmap &pixmap, int hotX, int hotY)
+{
+ HCURSOR cur = 0;
+ QBitmap mask = pixmap.mask();
+ if (mask.isNull()) {
+ mask = QBitmap(pixmap.size());
+ mask.fill(Qt::color1);
+ }
+
+ HBITMAP ic = qPixmapToWinHBITMAP(pixmap, HBitmapAlpha);
+ const HBITMAP im = createIconMask(mask);
+
+ ICONINFO ii;
+ ii.fIcon = 0;
+ ii.xHotspot = hotX;
+ ii.yHotspot = hotY;
+ ii.hbmMask = im;
+ ii.hbmColor = ic;
+
+ cur = CreateIconIndirect(&ii);
+
+ DeleteObject(ic);
+ DeleteObject(im);
+ return cur;
+}
+
+HCURSOR QWindowsCursor::createSystemCursor(const QCursor &c)
+{
+ int hx = c.hotSpot().x();
+ int hy = c.hotSpot().y();
+ const Qt::CursorShape cshape = c.shape();
+ if (cshape == Qt::BitmapCursor) {
+ const QPixmap pixmap = c.pixmap();
+ if (!pixmap.isNull())
+ if (const HCURSOR hc = createPixmapCursor(pixmap, hx, hy))
+ return hc;
+ }
+
+ // Non-standard Windows cursors are created from bitmaps
+
+ static const uchar vsplit_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xe0, 0x03, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xff, 0x7f, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x7f, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00,
+ 0x00, 0xc0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ static const uchar vsplitm_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0xc0, 0x01, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x00, 0xf0, 0x07, 0x00,
+ 0x00, 0xf8, 0x0f, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00,
+ 0x00, 0xc0, 0x01, 0x00, 0x80, 0xff, 0xff, 0x00, 0x80, 0xff, 0xff, 0x00,
+ 0x80, 0xff, 0xff, 0x00, 0x80, 0xff, 0xff, 0x00, 0x80, 0xff, 0xff, 0x00,
+ 0x80, 0xff, 0xff, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00,
+ 0x00, 0xc0, 0x01, 0x00, 0x00, 0xf8, 0x0f, 0x00, 0x00, 0xf0, 0x07, 0x00,
+ 0x00, 0xe0, 0x03, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ static const uchar hsplit_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00,
+ 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00,
+ 0x00, 0x41, 0x82, 0x00, 0x80, 0x41, 0x82, 0x01, 0xc0, 0x7f, 0xfe, 0x03,
+ 0x80, 0x41, 0x82, 0x01, 0x00, 0x41, 0x82, 0x00, 0x00, 0x40, 0x02, 0x00,
+ 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00,
+ 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ static const uchar hsplitm_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00,
+ 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe2, 0x47, 0x00, 0x00, 0xe3, 0xc7, 0x00,
+ 0x80, 0xe3, 0xc7, 0x01, 0xc0, 0xff, 0xff, 0x03, 0xe0, 0xff, 0xff, 0x07,
+ 0xc0, 0xff, 0xff, 0x03, 0x80, 0xe3, 0xc7, 0x01, 0x00, 0xe3, 0xc7, 0x00,
+ 0x00, 0xe2, 0x47, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00,
+ 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ static const uchar phand_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x80, 0x04, 0x00, 0x00,
+ 0x80, 0x04, 0x00, 0x00, 0x80, 0x04, 0x00, 0x00, 0x80, 0x04, 0x00, 0x00,
+ 0x80, 0x1c, 0x00, 0x00, 0x80, 0xe4, 0x00, 0x00, 0x80, 0x24, 0x03, 0x00,
+ 0x80, 0x24, 0x05, 0x00, 0xb8, 0x24, 0x09, 0x00, 0xc8, 0x00, 0x09, 0x00,
+ 0x88, 0x00, 0x08, 0x00, 0x90, 0x00, 0x08, 0x00, 0xa0, 0x00, 0x08, 0x00,
+ 0x20, 0x00, 0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 0x04, 0x00,
+ 0x80, 0x00, 0x04, 0x00, 0x80, 0x00, 0x04, 0x00, 0x00, 0x01, 0x02, 0x00,
+ 0x00, 0x01, 0x02, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+ static const uchar phandm_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00,
+ 0x80, 0x07, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00,
+ 0x80, 0x1f, 0x00, 0x00, 0x80, 0xff, 0x00, 0x00, 0x80, 0xff, 0x03, 0x00,
+ 0x80, 0xff, 0x07, 0x00, 0xb8, 0xff, 0x0f, 0x00, 0xf8, 0xff, 0x0f, 0x00,
+ 0xf8, 0xff, 0x0f, 0x00, 0xf0, 0xff, 0x0f, 0x00, 0xe0, 0xff, 0x0f, 0x00,
+ 0xe0, 0xff, 0x0f, 0x00, 0xc0, 0xff, 0x0f, 0x00, 0xc0, 0xff, 0x07, 0x00,
+ 0x80, 0xff, 0x07, 0x00, 0x80, 0xff, 0x07, 0x00, 0x00, 0xff, 0x03, 0x00,
+ 0x00, 0xff, 0x03, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+ static const uchar openhand_bits[] = {
+ 0x80,0x01,0x58,0x0e,0x64,0x12,0x64,0x52,0x48,0xb2,0x48,0x92,
+ 0x16,0x90,0x19,0x80,0x11,0x40,0x02,0x40,0x04,0x40,0x04,0x20,
+ 0x08,0x20,0x10,0x10,0x20,0x10,0x00,0x00};
+ static const uchar openhandm_bits[] = {
+ 0x80,0x01,0xd8,0x0f,0xfc,0x1f,0xfc,0x5f,0xf8,0xff,0xf8,0xff,
+ 0xf6,0xff,0xff,0xff,0xff,0x7f,0xfe,0x7f,0xfc,0x7f,0xfc,0x3f,
+ 0xf8,0x3f,0xf0,0x1f,0xe0,0x1f,0x00,0x00};
+ static const uchar closedhand_bits[] = {
+ 0x00,0x00,0x00,0x00,0x00,0x00,0xb0,0x0d,0x48,0x32,0x08,0x50,
+ 0x10,0x40,0x18,0x40,0x04,0x40,0x04,0x20,0x08,0x20,0x10,0x10,
+ 0x20,0x10,0x20,0x10,0x00,0x00,0x00,0x00};
+ static const uchar closedhandm_bits[] = {
+ 0x00,0x00,0x00,0x00,0x00,0x00,0xb0,0x0d,0xf8,0x3f,0xf8,0x7f,
+ 0xf0,0x7f,0xf8,0x7f,0xfc,0x7f,0xfc,0x3f,0xf8,0x3f,0xf0,0x1f,
+ 0xe0,0x1f,0xe0,0x1f,0x00,0x00,0x00,0x00};
+
+ static const uchar * const cursor_bits32[] = {
+ vsplit_bits, vsplitm_bits, hsplit_bits, hsplitm_bits,
+ phand_bits, phandm_bits
+ };
+
+ wchar_t *sh = 0;
+ switch (c.shape()) { // map to windows cursor
+ case Qt::ArrowCursor:
+ sh = IDC_ARROW;
+ break;
+ case Qt::UpArrowCursor:
+ sh = IDC_UPARROW;
+ break;
+ case Qt::CrossCursor:
+ sh = IDC_CROSS;
+ break;
+ case Qt::WaitCursor:
+ sh = IDC_WAIT;
+ break;
+ case Qt::IBeamCursor:
+ sh = IDC_IBEAM;
+ break;
+ case Qt::SizeVerCursor:
+ sh = IDC_SIZENS;
+ break;
+ case Qt::SizeHorCursor:
+ sh = IDC_SIZEWE;
+ break;
+ case Qt::SizeBDiagCursor:
+ sh = IDC_SIZENESW;
+ break;
+ case Qt::SizeFDiagCursor:
+ sh = IDC_SIZENWSE;
+ break;
+ case Qt::SizeAllCursor:
+ sh = IDC_SIZEALL;
+ break;
+ case Qt::ForbiddenCursor:
+ sh = IDC_NO;
+ break;
+ case Qt::WhatsThisCursor:
+ sh = IDC_HELP;
+ break;
+ case Qt::BusyCursor:
+ sh = IDC_APPSTARTING;
+ break;
+ case Qt::PointingHandCursor:
+ sh = IDC_HAND;
+ break;
+ case Qt::BlankCursor:
+ case Qt::SplitVCursor:
+ case Qt::SplitHCursor:
+ case Qt::OpenHandCursor:
+ case Qt::ClosedHandCursor:
+ case Qt::BitmapCursor: {
+ QImage bbits, mbits;
+ bool invb, invm;
+ if (cshape == Qt::BlankCursor) {
+ bbits = QImage(32, 32, QImage::Format_Mono);
+ bbits.fill(0); // ignore color table
+ mbits = bbits.copy();
+ hx = hy = 16;
+ invb = invm = false;
+ } else if (cshape == Qt::OpenHandCursor || cshape == Qt::ClosedHandCursor) {
+ bool open = cshape == Qt::OpenHandCursor;
+ QBitmap cb = QBitmap::fromData(QSize(16, 16), open ? openhand_bits : closedhand_bits);
+ QBitmap cm = QBitmap::fromData(QSize(16, 16), open ? openhandm_bits : closedhandm_bits);
+ bbits = cb.toImage().convertToFormat(QImage::Format_Mono);
+ mbits = cm.toImage().convertToFormat(QImage::Format_Mono);
+ hx = hy = 8;
+ invb = invm = false;
+ } else if (cshape != Qt::BitmapCursor) {
+ int i = cshape - Qt::SplitVCursor;
+ QBitmap cb = QBitmap::fromData(QSize(32, 32), cursor_bits32[i * 2]);
+ QBitmap cm = QBitmap::fromData(QSize(32, 32), cursor_bits32[i * 2 + 1]);
+ bbits = cb.toImage().convertToFormat(QImage::Format_Mono);
+ mbits = cm.toImage().convertToFormat(QImage::Format_Mono);
+ if (cshape == Qt::PointingHandCursor) {
+ hx = 7;
+ hy = 0;
+ } else
+ hx = hy = 16;
+ invb = invm = false;
+ } else {
+ bbits = c.bitmap()->toImage().convertToFormat(QImage::Format_Mono);
+ mbits = c.mask()->toImage().convertToFormat(QImage::Format_Mono);
+ invb = bbits.colorCount() > 1 && qGray(bbits.color(0)) < qGray(bbits.color(1));
+ invm = mbits.colorCount() > 1 && qGray(mbits.color(0)) < qGray(mbits.color(1));
+ }
+ const int n = qMax(1, bbits.width() / 8);
+ const int h = bbits.height();
+ QScopedArrayPointer<uchar> xBits(new uchar[h * n]);
+ QScopedArrayPointer<uchar> xMask(new uchar[h * n]);
+ int x = 0;
+ for (int i = 0; i < h; ++i) {
+ uchar *bits = bbits.scanLine(i);
+ uchar *mask = mbits.scanLine(i);
+ for (int j = 0; j < n; ++j) {
+ uchar b = bits[j];
+ uchar m = mask[j];
+ if (invb)
+ b ^= 0xff;
+ if (invm)
+ m ^= 0xff;
+ xBits[x] = ~m;
+ xMask[x] = b ^ m;
+ ++x;
+ }
+ }
+ return CreateCursor(GetModuleHandle(0), hx, hy, bbits.width(), bbits.height(),
+ xBits.data(), xMask.data());
+ }
+ case Qt::DragCopyCursor:
+ case Qt::DragMoveCursor:
+ case Qt::DragLinkCursor: {
+ const QPixmap pixmap = QGuiApplicationPrivate::instance()->getPixmapCursor(cshape);
+ return createPixmapCursor(pixmap, hx, hy);
+ }
+ default:
+ qWarning("%s: Invalid cursor shape %d", __FUNCTION__, cshape);
+ return 0;
+ }
+ return (HCURSOR)LoadImage(0, sh, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
+}
+
+/*!
+ \brief Return cached standard cursor resources or create new ones.
+*/
+
+QWindowsWindowCursor QWindowsCursor::standardWindowCursor(Qt::CursorShape shape)
+{
+ StandardCursorCache::iterator it = m_standardCursorCache.find(shape);
+ if (it == m_standardCursorCache.end())
+ it = m_standardCursorCache.insert(shape, QWindowsWindowCursor(QCursor(shape)));
+ return it.value();
+}
+
+/*!
+ \brief Set a cursor on a window.
+
+ This is called frequently as the mouse moves over widgets in the window
+ (QLineEdits, etc).
+*/
+
+void QWindowsCursor::changeCursor(QCursor *cursorIn, QWindow *window)
+{
+
+ if (QWindowsContext::verboseWindows)
+ qDebug() << __FUNCTION__ << cursorIn << window;
+ if (!cursorIn || !window)
+ return;
+ const QWindowsWindowCursor wcursor =
+ cursorIn->shape() == Qt::BitmapCursor ?
+ QWindowsWindowCursor(*cursorIn) : standardWindowCursor(cursorIn->shape());
+ if (wcursor.handle()) {
+ QWindowsWindow::baseWindowOf(window)->setCursor(wcursor);
+ } else {
+ qWarning("%s: Unable to obtain system cursor for %d",
+ __FUNCTION__, cursorIn->shape());
+ }
+}
+
+QPoint QWindowsCursor::mousePosition()
+{
+ POINT p;
+ GetCursorPos(&p);
+ if (QWindowsContext::verboseWindows)
+ qDebug("%s %ld,%ld", __FUNCTION__, p.x, p.y);
+ return QPoint(p.x, p.y);
+}
+
+void QWindowsCursor::setPos(const QPoint &pos)
+{
+ if (QWindowsContext::verboseWindows)
+ qDebug("%s %d,%d", __FUNCTION__, pos.x(), pos.y());
+ SetCursorPos(pos.x(), pos.y());
+}
+
+/*!
+ \class QWindowsWindowCursor
+ \brief Per-Window cursor. Contains a QCursor and manages its associated system
+ cursor handle resource.
+
+ Based on QSharedDataPointer, so that it can be passed around and
+ used as a property of QWindowsBaseWindow.
+
+ \ingroup qt-lighthouse-win
+ \sa QWindowsCursor
+*/
+
+class QWindowsWindowCursorData : public QSharedData
+{
+public:
+ explicit QWindowsWindowCursorData(const QCursor &c);
+ ~QWindowsWindowCursorData();
+
+ const QCursor m_cursor;
+ const HCURSOR m_handle;
+};
+
+QWindowsWindowCursorData::QWindowsWindowCursorData(const QCursor &c) :
+ m_cursor(c),
+ m_handle(QWindowsCursor::createSystemCursor(c))
+{
+}
+
+QWindowsWindowCursorData::~QWindowsWindowCursorData()
+{
+ DestroyCursor(m_handle);
+}
+
+QWindowsWindowCursor::QWindowsWindowCursor(const QCursor &c) :
+ m_data(new QWindowsWindowCursorData(c))
+{
+}
+
+QWindowsWindowCursor::~QWindowsWindowCursor()
+{
+}
+
+QWindowsWindowCursor::QWindowsWindowCursor(const QWindowsWindowCursor &rhs) :
+ m_data(rhs.m_data)
+{
+}
+
+QWindowsWindowCursor & QWindowsWindowCursor::operator =(const QWindowsWindowCursor &rhs)
+{
+ if (this != &rhs)
+ m_data.operator =(rhs.m_data);
+ return *this;
+}
+
+QCursor QWindowsWindowCursor::cursor() const
+{
+ return m_data->m_cursor;
+}
+
+HCURSOR QWindowsWindowCursor::handle() const
+{
+ return m_data->m_handle;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowscursor.h b/src/plugins/platforms/windows/qwindowscursor.h
new file mode 100644
index 0000000000..bf8cb837d9
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowscursor.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSCURSOR_H
+#define QWINDOWSCURSOR_H
+
+#include "qtwindows_additional.h"
+
+#include <QtGui/QPlatformCursor>
+#include <QtCore/QSharedDataPointer>
+#include <QtCore/QHash>
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsWindowCursorData;
+
+class QWindowsWindowCursor
+{
+public:
+ explicit QWindowsWindowCursor(const QCursor &c);
+ ~QWindowsWindowCursor();
+ QWindowsWindowCursor(const QWindowsWindowCursor &c);
+ QWindowsWindowCursor &operator=(const QWindowsWindowCursor &c);
+
+ QCursor cursor() const;
+ HCURSOR handle() const;
+
+private:
+ QSharedDataPointer<QWindowsWindowCursorData> m_data;
+};
+
+class QWindowsCursor : public QPlatformCursor
+{
+public:
+ explicit QWindowsCursor(QPlatformScreen *);
+
+ virtual void changeCursor(QCursor * widgetCursor, QWindow * widget);
+ virtual QPoint pos() const { return mousePosition(); }
+ virtual void setPos(const QPoint &pos);
+
+ static HCURSOR createPixmapCursor(const QPixmap &pixmap, int hotX, int hotY);
+ static HCURSOR createSystemCursor(const QCursor &c);
+ static QPoint mousePosition();
+
+ QWindowsWindowCursor standardWindowCursor(Qt::CursorShape s = Qt::ArrowCursor);
+
+private:
+ typedef QHash<Qt::CursorShape, QWindowsWindowCursor> StandardCursorCache;
+
+ StandardCursorCache m_standardCursorCache;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSCURSOR_H
diff --git a/src/plugins/platforms/windows/qwindowsdrag.cpp b/src/plugins/platforms/windows/qwindowsdrag.cpp
new file mode 100644
index 0000000000..1535437a32
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsdrag.cpp
@@ -0,0 +1,721 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsdrag.h"
+#include "qwindowscontext.h"
+#include "qwindowsclipboard.h"
+#include "qwindowsintegration.h"
+#include "qwindowsole.h"
+#include "qtwindows_additional.h"
+#include "qwindowswindow.h"
+#include "qwindowsmousehandler.h"
+#include "qwindowscursor.h"
+
+#include <QtGui/QMouseEvent>
+#include <QtGui/QPixmap>
+#include <QtGui/QPainter>
+#include <QtGui/QGuiApplication>
+
+#include <QtCore/QDebug>
+#include <QtCore/QPoint>
+
+#include <shlobj.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QWindowsDropMimeData
+ \brief Special mime data class for data retrieval from Drag operations.
+
+ Implementation of QWindowsInternalMimeDataBase which retrieves the
+ current drop data object from QWindowsDrag.
+
+ \sa QWindowsDrag
+ \ingroup qt-lighthouse-win
+*/
+
+IDataObject *QWindowsDropMimeData::retrieveDataObject() const
+{
+ return QWindowsDrag::instance()->dropDataObject();
+}
+
+static inline Qt::DropActions translateToQDragDropActions(DWORD pdwEffects)
+{
+ Qt::DropActions actions = Qt::IgnoreAction;
+ if (pdwEffects & DROPEFFECT_LINK)
+ actions |= Qt::LinkAction;
+ if (pdwEffects & DROPEFFECT_COPY)
+ actions |= Qt::CopyAction;
+ if (pdwEffects & DROPEFFECT_MOVE)
+ actions |= Qt::MoveAction;
+ return actions;
+}
+
+static inline Qt::DropAction translateToQDragDropAction(DWORD pdwEffect)
+{
+ if (pdwEffect & DROPEFFECT_LINK)
+ return Qt::LinkAction;
+ if (pdwEffect & DROPEFFECT_COPY)
+ return Qt::CopyAction;
+ if (pdwEffect & DROPEFFECT_MOVE)
+ return Qt::MoveAction;
+ return Qt::IgnoreAction;
+}
+
+static inline DWORD translateToWinDragEffects(Qt::DropActions action)
+{
+ DWORD effect = DROPEFFECT_NONE;
+ if (action & Qt::LinkAction)
+ effect |= DROPEFFECT_LINK;
+ if (action & Qt::CopyAction)
+ effect |= DROPEFFECT_COPY;
+ if (action & Qt::MoveAction)
+ effect |= DROPEFFECT_MOVE;
+ return effect;
+}
+
+static inline Qt::KeyboardModifiers toQtKeyboardModifiers(DWORD keyState)
+{
+ Qt::KeyboardModifiers modifiers = Qt::NoModifier;
+
+ if (keyState & MK_SHIFT)
+ modifiers |= Qt::ShiftModifier;
+ if (keyState & MK_CONTROL)
+ modifiers |= Qt::ControlModifier;
+ if (keyState & MK_ALT)
+ modifiers |= Qt::AltModifier;
+
+ return modifiers;
+}
+
+/*!
+ \class QWindowsOleDropSource
+ \brief Implementation of IDropSource
+
+ Used for drag operations.
+
+ \sa QWindowsDrag
+ \ingroup qt-lighthouse-win
+*/
+
+class QWindowsOleDropSource : public IDropSource
+{
+public:
+ QWindowsOleDropSource();
+ virtual ~QWindowsOleDropSource();
+
+ void createCursors();
+
+ // IUnknown methods
+ STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObj);
+ STDMETHOD_(ULONG,AddRef)(void);
+ STDMETHOD_(ULONG,Release)(void);
+
+ // IDropSource methods
+ STDMETHOD(QueryContinueDrag)(BOOL fEscapePressed, DWORD grfKeyState);
+ STDMETHOD(GiveFeedback)(DWORD dwEffect);
+
+private:
+ typedef QMap <Qt::DropAction, HCURSOR> ActionCursorMap;
+
+ inline void clearCursors();
+
+ Qt::MouseButtons m_currentButtons;
+ Qt::DropAction m_currentAction;
+ ActionCursorMap m_cursors;
+
+ ULONG m_refs;
+};
+
+QWindowsOleDropSource::QWindowsOleDropSource() :
+ m_currentButtons(Qt::NoButton), m_currentAction(Qt::IgnoreAction),
+ m_refs(1)
+{
+ if (QWindowsContext::verboseOLE)
+ qDebug("%s", __FUNCTION__);
+}
+
+QWindowsOleDropSource::~QWindowsOleDropSource()
+{
+ clearCursors();
+ if (QWindowsContext::verboseOLE)
+ qDebug("%s", __FUNCTION__);
+}
+
+void QWindowsOleDropSource::createCursors()
+{
+ QDragManager *manager = QDragManager::self();
+ if (!manager || !manager->object)
+ return;
+ const QPixmap pixmap = manager->object->pixmap();
+ const bool hasPixmap = !pixmap.isNull();
+ if (!hasPixmap && manager->dragPrivate()->customCursors.isEmpty())
+ return;
+
+ QList<Qt::DropAction> actions;
+ actions << Qt::MoveAction << Qt::CopyAction << Qt::LinkAction;
+ if (hasPixmap)
+ actions << Qt::IgnoreAction;
+ const QPoint hotSpot = manager->object->hotSpot();
+ for (int cnum = 0; cnum < actions.size(); ++cnum) {
+ const QPixmap cpm = manager->dragCursor(actions.at(cnum));
+ int w = cpm.width();
+ int h = cpm.height();
+
+ if (hasPixmap) {
+ const int x1 = qMin(-hotSpot.x(), 0);
+ const int x2 = qMax(pixmap.width() - hotSpot.x(), cpm.width());
+ const int y1 = qMin(-hotSpot.y(), 0);
+ const int y2 = qMax(pixmap.height() - hotSpot.y(), cpm.height());
+
+ w = x2 - x1 + 1;
+ h = y2 - y1 + 1;
+ }
+
+ const QRect srcRect = pixmap.rect();
+ const QPoint pmDest = QPoint(qMax(0, -hotSpot.x()), qMax(0, -hotSpot.y()));
+ const QPoint newHotSpot = hotSpot;
+ QPixmap newCursor(w, h);
+ if (hasPixmap) {
+ newCursor.fill(QColor(0, 0, 0, 0));
+ QPainter p(&newCursor);
+ p.drawPixmap(pmDest, pixmap, srcRect);
+ p.drawPixmap(qMax(0,newHotSpot.x()),qMax(0,newHotSpot.y()),cpm);
+ } else {
+ newCursor = cpm;
+ }
+
+ const int hotX = hasPixmap ? qMax(0,newHotSpot.x()) : 0;
+ const int hotY = hasPixmap ? qMax(0,newHotSpot.y()) : 0;
+
+ if (const HCURSOR sysCursor = QWindowsCursor::createPixmapCursor(newCursor, hotX, hotY))
+ m_cursors.insert(actions.at(cnum), sysCursor);
+ }
+ if (QWindowsContext::verboseOLE)
+ qDebug("%s %d cursors", __FUNCTION__, m_cursors.size());
+}
+
+void QWindowsOleDropSource::clearCursors()
+{
+ if (!m_cursors.isEmpty()) {
+ const ActionCursorMap::const_iterator cend = m_cursors.constEnd();
+ for (ActionCursorMap::const_iterator it = m_cursors.constBegin(); it != cend; ++it)
+ DestroyCursor(it.value());
+ m_cursors.clear();
+ }
+}
+
+//---------------------------------------------------------------------
+// IUnknown Methods
+//---------------------------------------------------------------------
+
+STDMETHODIMP
+QWindowsOleDropSource::QueryInterface(REFIID iid, void FAR* FAR* ppv)
+{
+ if (iid == IID_IUnknown || iid == IID_IDropSource) {
+ *ppv = this;
+ ++m_refs;
+ return NOERROR;
+ }
+ *ppv = NULL;
+ return ResultFromScode(E_NOINTERFACE);
+}
+
+STDMETHODIMP_(ULONG)
+QWindowsOleDropSource::AddRef(void)
+{
+ return ++m_refs;
+}
+
+STDMETHODIMP_(ULONG)
+QWindowsOleDropSource::Release(void)
+{
+ if (--m_refs == 0) {
+ delete this;
+ return 0;
+ }
+ return m_refs;
+}
+
+/*!
+ \brief Check for cancel.
+*/
+
+QT_ENSURE_STACK_ALIGNED_FOR_SSE STDMETHODIMP
+QWindowsOleDropSource::QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState)
+{
+ HRESULT hr = S_OK;
+ do {
+ if (fEscapePressed || QWindowsDrag::instance()->dragBeingCancelled()) {
+ hr = ResultFromScode(DRAGDROP_S_CANCEL);
+ break;
+ }
+
+ // grfKeyState is broken on CE & some Windows XP versions,
+ // therefore we need to check the state manually
+ if ((GetAsyncKeyState(VK_LBUTTON) == 0)
+ && (GetAsyncKeyState(VK_MBUTTON) == 0)
+ && (GetAsyncKeyState(VK_RBUTTON) == 0)) {
+ hr = ResultFromScode(DRAGDROP_S_DROP);
+ break;
+ }
+
+ const Qt::MouseButtons buttons = QWindowsMouseHandler::keyStateToMouseButtons(grfKeyState);
+ if (m_currentButtons == Qt::NoButton) {
+ m_currentButtons = buttons;
+ } else {
+ // Button changed: Complete Drop operation.
+ if (!(m_currentButtons & buttons)) {
+ hr = ResultFromScode(DRAGDROP_S_DROP);
+ break;
+ }
+ }
+
+ QGuiApplication::processEvents();
+
+ } while (false);
+
+ QDragManager::self()->willDrop = hr == DRAGDROP_S_DROP;
+
+ if (QWindowsContext::verboseOLE
+ && (QWindowsContext::verboseOLE > 1 || hr != S_OK))
+ qDebug("%s fEscapePressed=%d, grfKeyState=%lu buttons=%d willDrop = %d returns 0x%x",
+ __FUNCTION__, fEscapePressed,grfKeyState, int(m_currentButtons),
+ QDragManager::self()->willDrop, int(hr));
+ return hr;
+}
+
+/*!
+ \brief Give feedback: Change cursor accoding to action.
+*/
+
+QT_ENSURE_STACK_ALIGNED_FOR_SSE STDMETHODIMP
+QWindowsOleDropSource::GiveFeedback(DWORD dwEffect)
+{
+ const Qt::DropAction action = translateToQDragDropAction(dwEffect);
+
+ if (QWindowsContext::verboseOLE > 2)
+ qDebug("%s dwEffect=%lu, action=%d", __FUNCTION__, dwEffect, action);
+
+ if (m_currentAction != action) {
+ m_currentAction = action;
+ QDragManager::self()->emitActionChanged(m_currentAction);
+ }
+
+ const ActionCursorMap::const_iterator it = m_cursors.constFind(m_currentAction);
+ if (it != m_cursors.constEnd()) {
+ SetCursor(it.value());
+ return ResultFromScode(S_OK);
+ }
+
+ return ResultFromScode(DRAGDROP_S_USEDEFAULTCURSORS);
+}
+
+/*!
+ \class QWindowsOleDropTarget
+ \brief Implementation of IDropTarget
+
+ To be registered for each window. Currently, drop sites
+ are enabled for top levels. The child window handling
+ (sending DragEnter/Leave, etc) is handled in here.
+
+ \sa QWindowsDrag
+ \ingroup qt-lighthouse-win
+*/
+
+QWindowsOleDropTarget::QWindowsOleDropTarget(QWindow *w) :
+ m_refs(1), m_window(w), m_currentWindow(0), m_chosenEffect(0), m_lastKeyState(0)
+{
+ if (QWindowsContext::verboseOLE)
+ qDebug() << __FUNCTION__ << this << w;
+}
+
+QWindowsOleDropTarget::~QWindowsOleDropTarget()
+{
+ if (QWindowsContext::verboseOLE)
+ qDebug("%s %p", __FUNCTION__, this);
+}
+
+STDMETHODIMP
+QWindowsOleDropTarget::QueryInterface(REFIID iid, void FAR* FAR* ppv)
+{
+ if (iid == IID_IUnknown || iid == IID_IDropTarget) {
+ *ppv = this;
+ AddRef();
+ return NOERROR;
+ }
+ *ppv = NULL;
+ return ResultFromScode(E_NOINTERFACE);
+}
+
+STDMETHODIMP_(ULONG)
+QWindowsOleDropTarget::AddRef(void)
+{
+ return ++m_refs;
+}
+
+STDMETHODIMP_(ULONG)
+QWindowsOleDropTarget::Release(void)
+{
+ if (--m_refs == 0) {
+ delete this;
+ return 0;
+ }
+ return m_refs;
+}
+
+QWindow *QWindowsOleDropTarget::findDragOverWindow(const POINTL &pt) const
+{
+ if (QWindowsWindow *child =
+ QWindowsWindow::baseWindowOf(m_window)->childAtScreenPoint(QPoint(pt.x, pt.y)))
+ return child->window();
+ return m_window;
+}
+
+QT_ENSURE_STACK_ALIGNED_FOR_SSE STDMETHODIMP
+QWindowsOleDropTarget::DragEnter(LPDATAOBJECT pDataObj, DWORD grfKeyState,
+ POINTL pt, LPDWORD pdwEffect)
+{
+ if (QWindowsContext::verboseOLE)
+ qDebug("%s widget=%p key=%lu, pt=%ld,%ld", __FUNCTION__, m_window, grfKeyState, pt.x, pt.y);
+
+ QWindowsDrag::instance()->setDropDataObject(pDataObj);
+ pDataObj->AddRef();
+ m_currentWindow = m_window;
+ sendDragEnterEvent(m_window, grfKeyState, pt, pdwEffect);
+ *pdwEffect = m_chosenEffect;
+ return NOERROR;
+}
+
+void QWindowsOleDropTarget::sendDragEnterEvent(QWindow *dragEnterWidget,
+ DWORD grfKeyState,
+ POINTL pt, LPDWORD pdwEffect)
+{
+ Q_ASSERT(dragEnterWidget);
+
+ m_lastPoint = QWindowsGeometryHint::mapFromGlobal(dragEnterWidget, QPoint(pt.x,pt.y));
+ m_lastKeyState = grfKeyState;
+
+ m_chosenEffect = DROPEFFECT_NONE;
+
+ QDragManager *manager = QDragManager::self();
+ QMimeData *md = manager->dropData();
+ const Qt::MouseButtons mouseButtons
+ = QWindowsMouseHandler::keyStateToMouseButtons(grfKeyState);
+ const Qt::DropActions actions = translateToQDragDropActions(*pdwEffect);
+ const Qt::KeyboardModifiers keyMods = toQtKeyboardModifiers(grfKeyState);
+ QDragEnterEvent enterEvent(m_lastPoint, actions, md, mouseButtons, keyMods);
+ QGuiApplication::sendEvent(m_currentWindow, &enterEvent);
+ m_answerRect = enterEvent.answerRect();
+ if (QWindowsContext::verboseOLE)
+ qDebug() << __FUNCTION__ << " sent drag enter to " << m_window
+ << *md << " actions=" << actions
+ << " mods=" << keyMods << " accepted: "
+ << enterEvent.isAccepted();
+
+ if (enterEvent.isAccepted())
+ m_chosenEffect = translateToWinDragEffects(enterEvent.dropAction());
+ // Documentation states that a drag move event is sent immediately after
+ // a drag enter event. This will honor widgets overriding dragMoveEvent only:
+ if (enterEvent.isAccepted()) {
+ QDragMoveEvent moveEvent(m_lastPoint, actions, md, mouseButtons, keyMods);
+ m_answerRect = enterEvent.answerRect();
+ moveEvent.setDropAction(enterEvent.dropAction());
+ moveEvent.accept(); // accept by default, since enter event was accepted.
+
+ QGuiApplication::sendEvent(dragEnterWidget, &moveEvent);
+ if (moveEvent.isAccepted()) {
+ m_answerRect = moveEvent.answerRect();
+ m_chosenEffect = translateToWinDragEffects(moveEvent.dropAction());
+ } else {
+ m_chosenEffect = DROPEFFECT_NONE;
+ }
+ }
+}
+
+QT_ENSURE_STACK_ALIGNED_FOR_SSE STDMETHODIMP
+QWindowsOleDropTarget::DragOver(DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect)
+{
+ QWindow *dragOverWindow = findDragOverWindow(pt);
+
+ const QPoint tmpPoint = QWindowsGeometryHint::mapFromGlobal(dragOverWindow, QPoint(pt.x,pt.y));
+ // see if we should compress this event
+ if ((tmpPoint == m_lastPoint || m_answerRect.contains(tmpPoint))
+ && m_lastKeyState == grfKeyState) {
+ *pdwEffect = m_chosenEffect;
+ return NOERROR;
+ }
+
+ if (QWindowsContext::verboseOLE > 1)
+ qDebug().nospace() << '>' << __FUNCTION__ << ' ' << m_window << " current "
+ << dragOverWindow << " key=" << grfKeyState
+ << " pt=" <<pt.x << ',' << pt.y;
+
+ if (dragOverWindow != m_currentWindow) {
+ QPointer<QWindow> dragOverWindowGuard(dragOverWindow);
+ // Send drag leave event to the previous drag widget.
+ // Drag-Over widget might be deleted in DragLeave,
+ // (tasktracker 218353).
+ QDragLeaveEvent dragLeave;
+ if (m_currentWindow)
+ QGuiApplication::sendEvent(m_currentWindow, &dragLeave);
+ if (!dragOverWindowGuard) {
+ dragOverWindow = findDragOverWindow(pt);
+ }
+ // Send drag enter event to the current drag widget.
+ m_currentWindow = dragOverWindow;
+ sendDragEnterEvent(dragOverWindow, grfKeyState, pt, pdwEffect);
+ }
+
+ QDragManager *manager = QDragManager::self();
+ QMimeData *md = manager->dropData();
+
+ const Qt::DropActions actions = translateToQDragDropActions(*pdwEffect);
+
+ QDragMoveEvent oldEvent(m_lastPoint, actions, md,
+ QWindowsMouseHandler::keyStateToMouseButtons(m_lastKeyState),
+ toQtKeyboardModifiers(m_lastKeyState));
+
+ m_lastPoint = tmpPoint;
+ m_lastKeyState = grfKeyState;
+
+ QDragMoveEvent e(tmpPoint, actions, md,
+ QWindowsMouseHandler::keyStateToMouseButtons(grfKeyState),
+ toQtKeyboardModifiers(grfKeyState));
+ if (m_chosenEffect != DROPEFFECT_NONE) {
+ if (oldEvent.dropAction() == e.dropAction() &&
+ oldEvent.keyboardModifiers() == e.keyboardModifiers())
+ e.setDropAction(translateToQDragDropAction(m_chosenEffect));
+ e.accept();
+ }
+ QGuiApplication::sendEvent(dragOverWindow, &e);
+
+ m_answerRect = e.answerRect();
+ if (e.isAccepted())
+ m_chosenEffect = translateToWinDragEffects(e.dropAction());
+ else
+ m_chosenEffect = DROPEFFECT_NONE;
+ *pdwEffect = m_chosenEffect;
+
+ if (QWindowsContext::verboseOLE > 1)
+ qDebug("<%s effect=0x%lx", __FUNCTION__, m_chosenEffect);
+ return NOERROR;
+}
+
+QT_ENSURE_STACK_ALIGNED_FOR_SSE STDMETHODIMP
+QWindowsOleDropTarget::DragLeave()
+{
+ if (QWindowsContext::verboseOLE)
+ qDebug().nospace() <<__FUNCTION__ << ' ' << m_window;
+
+ m_currentWindow = 0;
+ QDragLeaveEvent e;
+ QGuiApplication::sendEvent(m_window, &e);
+ QWindowsDrag::instance()->releaseDropDataObject();
+
+ return NOERROR;
+}
+
+#define KEY_STATE_BUTTON_MASK (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON)
+
+QT_ENSURE_STACK_ALIGNED_FOR_SSE STDMETHODIMP
+QWindowsOleDropTarget::Drop(LPDATAOBJECT /*pDataObj*/, DWORD grfKeyState,
+ POINTL pt, LPDWORD pdwEffect)
+{
+ QWindow *dropWindow = findDragOverWindow(pt);
+
+ if (QWindowsContext::verboseOLE)
+ qDebug().nospace() << __FUNCTION__ << ' ' << m_window
+ << " on " << dropWindow
+ << " keys=" << grfKeyState << " pt="
+ << pt.x << ',' << pt.y;
+
+ m_lastPoint = QWindowsGeometryHint::mapFromGlobal(dropWindow, QPoint(pt.x,pt.y));
+ // grfKeyState does not all ways contain button state in the drop so if
+ // it doesn't then use the last known button state;
+ if ((grfKeyState & KEY_STATE_BUTTON_MASK) == 0)
+ grfKeyState |= m_lastKeyState & KEY_STATE_BUTTON_MASK;
+ m_lastKeyState = grfKeyState;
+
+ QWindowsDrag *windowsDrag = QWindowsDrag::instance();
+ QDragManager *manager = QDragManager::self();
+ QMimeData *md = manager->dropData();
+ QDropEvent e(m_lastPoint, translateToQDragDropActions(*pdwEffect), md,
+ QWindowsMouseHandler::keyStateToMouseButtons(grfKeyState),
+ toQtKeyboardModifiers(grfKeyState));
+ if (m_chosenEffect != DROPEFFECT_NONE)
+ e.setDropAction(translateToQDragDropAction(m_chosenEffect));
+
+ QGuiApplication::sendEvent(dropWindow, &e);
+ if (m_chosenEffect != DROPEFFECT_NONE)
+ e.accept();
+
+ if (e.isAccepted()) {
+ if (e.dropAction() == Qt::MoveAction || e.dropAction() == Qt::TargetMoveAction) {
+ if (e.dropAction() == Qt::MoveAction)
+ m_chosenEffect = DROPEFFECT_MOVE;
+ else
+ m_chosenEffect = DROPEFFECT_COPY;
+ HGLOBAL hData = GlobalAlloc(0, sizeof(DWORD));
+ if (hData) {
+ DWORD *moveEffect = (DWORD *)GlobalLock(hData);;
+ *moveEffect = DROPEFFECT_MOVE;
+ GlobalUnlock(hData);
+ STGMEDIUM medium;
+ memset(&medium, 0, sizeof(STGMEDIUM));
+ medium.tymed = TYMED_HGLOBAL;
+ medium.hGlobal = hData;
+ FORMATETC format;
+ format.cfFormat = RegisterClipboardFormat(CFSTR_PERFORMEDDROPEFFECT);
+ format.tymed = TYMED_HGLOBAL;
+ format.ptd = 0;
+ format.dwAspect = 1;
+ format.lindex = -1;
+ windowsDrag->dropDataObject()->SetData(&format, &medium, true);
+ }
+ } else {
+ m_chosenEffect = translateToWinDragEffects(e.dropAction());
+ }
+ } else {
+ m_chosenEffect = DROPEFFECT_NONE;
+ }
+ *pdwEffect = m_chosenEffect;
+
+ windowsDrag->releaseDropDataObject();
+ return NOERROR;
+}
+
+/*!
+ \class QWindowsDrag
+ \brief Windows drag implementation.
+
+ \ingroup qt-lighthouse-win
+*/
+
+QWindowsDrag::QWindowsDrag() : m_dropDataObject(0), m_dragBeingCancelled(false)
+{
+}
+
+QWindowsDrag::~QWindowsDrag()
+{
+}
+
+void QWindowsDrag::startDrag()
+{
+ // TODO: Accessibility handling?
+ QDragManager *dragManager = QDragManager::self();
+ QMimeData *dropData = dragManager->dropData();
+ m_dragBeingCancelled = false;
+
+ DWORD resultEffect;
+ QWindowsOleDropSource *windowDropSource = new QWindowsOleDropSource();
+ windowDropSource->createCursors();
+ QWindowsOleDataObject *dropDataObject = new QWindowsOleDataObject(dropData);
+ const Qt::DropActions possibleActions = dragManager->possible_actions;
+ const DWORD allowedEffects = translateToWinDragEffects(possibleActions);
+ if (QWindowsContext::verboseOLE)
+ qDebug(">%s possible Actions=%x, effects=0x%lx", __FUNCTION__,
+ int(possibleActions), allowedEffects);
+ const HRESULT r = DoDragDrop(dropDataObject, windowDropSource, allowedEffects, &resultEffect);
+ const DWORD reportedPerformedEffect = dropDataObject->reportedPerformedEffect();
+ Qt::DropAction ret = Qt::IgnoreAction;
+ if (r == DRAGDROP_S_DROP) {
+ if (reportedPerformedEffect == DROPEFFECT_MOVE && resultEffect != DROPEFFECT_MOVE) {
+ ret = Qt::TargetMoveAction;
+ resultEffect = DROPEFFECT_MOVE;
+ } else {
+ ret = translateToQDragDropAction(resultEffect);
+ }
+ // Force it to be a copy if an unsupported operation occurred.
+ // This indicates a bug in the drop target.
+ if (resultEffect != DROPEFFECT_NONE && !(resultEffect & allowedEffects))
+ ret = Qt::CopyAction;
+ } else {
+ dragManager->setCurrentTarget(0);
+ }
+
+ // clean up
+ dropDataObject->releaseQt();
+ dropDataObject->Release(); // Will delete obj if refcount becomes 0
+ windowDropSource->Release(); // Will delete src if refcount becomes 0
+ if (QWindowsContext::verboseOLE)
+ qDebug("<%s allowedEffects=0x%lx, reportedPerformedEffect=0x%lx, resultEffect=0x%lx, hr=0x%x, dropAction=%d",
+ __FUNCTION__, allowedEffects, reportedPerformedEffect, resultEffect, int(r), ret);
+}
+
+void QWindowsDrag::move(const QMouseEvent *me)
+{
+ const QPoint pos = me->pos();
+ if (QWindowsContext::verboseOLE)
+ qDebug("%s %d %d", __FUNCTION__, pos.x(), pos.y());
+}
+
+void QWindowsDrag::drop(const QMouseEvent *me)
+{
+ const QPoint pos = me->pos();
+ if (QWindowsContext::verboseOLE)
+ qDebug("%s %d %d", __FUNCTION__, pos.x(), pos.y());
+}
+
+void QWindowsDrag::cancel()
+{
+ // TODO: Accessibility handling?
+ if (QWindowsContext::verboseOLE)
+ qDebug("%s", __FUNCTION__);
+ m_dragBeingCancelled = true;
+}
+
+QWindowsDrag *QWindowsDrag::instance()
+{
+ return static_cast<QWindowsDrag *>(QWindowsIntegration::instance()->drag());
+}
+
+void QWindowsDrag::releaseDropDataObject()
+{
+ if (QWindowsContext::verboseOLE)
+ qDebug("%s %p", __FUNCTION__, m_dropDataObject);
+ if (m_dropDataObject) {
+ m_dropDataObject->Release();
+ m_dropDataObject = 0;
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsdrag.h b/src/plugins/platforms/windows/qwindowsdrag.h
new file mode 100644
index 0000000000..6e6ebe0424
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsdrag.h
@@ -0,0 +1,116 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSDRAG_H
+#define QWINDOWSDRAG_H
+
+#include "qwindowsinternalmimedata.h"
+
+#include <QtGui/QPlatformDrag>
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsDropMimeData : public QWindowsInternalMimeData {
+public:
+ QWindowsDropMimeData() {}
+ virtual IDataObject *retrieveDataObject() const;
+};
+
+class QWindowsOleDropTarget : public IDropTarget
+{
+public:
+ explicit QWindowsOleDropTarget(QWindow *w);
+ virtual ~QWindowsOleDropTarget();
+
+ // IUnknown methods
+ STDMETHOD(QueryInterface)(REFIID riid, void FAR* FAR* ppvObj);
+ STDMETHOD_(ULONG, AddRef)(void);
+ STDMETHOD_(ULONG, Release)(void);
+
+ // IDropTarget methods
+ STDMETHOD(DragEnter)(LPDATAOBJECT pDataObj, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect);
+ STDMETHOD(DragOver)(DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect);
+ STDMETHOD(DragLeave)();
+ STDMETHOD(Drop)(LPDATAOBJECT pDataObj, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect);
+
+private:
+ inline QWindow *findDragOverWindow(const POINTL &pt) const;
+ void sendDragEnterEvent(QWindow *to, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect);
+
+ ULONG m_refs;
+ QWindow *const m_window;
+ QWindow *m_currentWindow;
+ QRect m_answerRect;
+ QPoint m_lastPoint;
+ DWORD m_chosenEffect;
+ DWORD m_lastKeyState;
+};
+
+class QWindowsDrag : public QPlatformDrag
+{
+public:
+ QWindowsDrag();
+ virtual ~QWindowsDrag();
+
+ virtual QMimeData *platformDropData() { return &m_dropData; }
+
+ virtual void startDrag();
+ virtual void move(const QMouseEvent *me);
+ virtual void drop(const QMouseEvent *me);
+ virtual void cancel();
+
+ static QWindowsDrag *instance();
+
+ IDataObject *dropDataObject() const { return m_dropDataObject; }
+ void setDropDataObject(IDataObject *dataObject) { m_dropDataObject = dataObject; }
+ void releaseDropDataObject();
+
+ bool dragBeingCancelled() const { return m_dragBeingCancelled; }
+
+private:
+ QWindowsDropMimeData m_dropData;
+ IDataObject *m_dropDataObject;
+ bool m_dragBeingCancelled;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSDRAG_H
diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
new file mode 100644
index 0000000000..ea35ab5f9f
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
@@ -0,0 +1,950 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsfontdatabase.h"
+#include "qwindowscontext.h"
+#include "qwindowsfontengine.h"
+#include "qwindowsfontenginedirectwrite.h"
+#include "qtwindows_additional.h"
+
+#include <QtGui/QFont>
+#include <QtGui/QGuiApplication>
+
+#include <QtCore/qmath.h>
+#include <QtCore/QDebug>
+
+#if !defined(QT_NO_DIRECTWRITE)
+# include <dwrite.h>
+# include <d2d1.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \struct QWindowsFontEngineData
+ \brief Static constant data shared by the font engines.
+ \ingroup qt-lighthouse-win
+*/
+
+QWindowsFontEngineData::QWindowsFontEngineData()
+#if !defined(QT_NO_DIRECTWRITE)
+ : directWriteFactory(0)
+ , directWriteGdiInterop(0)
+#endif
+{
+ // from qapplication_win.cpp
+ UINT result = 0;
+ if (SystemParametersInfo(SPI_GETFONTSMOOTHINGTYPE, 0, &result, 0))
+ clearTypeEnabled = (result == FE_FONTSMOOTHINGCLEARTYPE);
+
+ int winSmooth;
+ if (SystemParametersInfo(0x200C /* SPI_GETFONTSMOOTHINGCONTRAST */, 0, &winSmooth, 0)) {
+ fontSmoothingGamma = winSmooth / qreal(1000.0);
+ } else {
+ fontSmoothingGamma = 1.0;
+ }
+
+ // Safeguard ourselves against corrupt registry values...
+ if (fontSmoothingGamma > 5 || fontSmoothingGamma < 1)
+ fontSmoothingGamma = qreal(1.4);
+
+ const qreal gray_gamma = 2.31;
+ for (int i=0; i<256; ++i)
+ pow_gamma[i] = uint(qRound(qPow(i / qreal(255.), gray_gamma) * 2047));
+
+ HDC displayDC = GetDC(0);
+ hdc = CreateCompatibleDC(displayDC);
+ ReleaseDC(0, displayDC);
+}
+
+QWindowsFontEngineData::~QWindowsFontEngineData()
+{
+ if (hdc)
+ ReleaseDC(0, hdc);
+#if !defined(QT_NO_DIRECTWRITE)
+ if (directWriteGdiInterop)
+ directWriteGdiInterop->Release();
+ if (directWriteFactory)
+ directWriteFactory->Release();
+#endif
+}
+
+#if !defined(QT_NO_DIRECTWRITE)
+static inline bool initDirectWrite(QWindowsFontEngineData *d)
+{
+ if (!d->directWriteFactory) {
+ const HRESULT hr = DWriteCreateFactory(
+ DWRITE_FACTORY_TYPE_SHARED,
+ __uuidof(IDWriteFactory),
+ reinterpret_cast<IUnknown **>(&d->directWriteFactory)
+ );
+ if (FAILED(hr)) {
+ qErrnoWarning("%s: DWriteCreateFactory failed", __FUNCTION__);
+ return false;
+ }
+ }
+ if (!d->directWriteGdiInterop) {
+ const HRESULT hr = d->directWriteFactory->GetGdiInterop(&d->directWriteGdiInterop);
+ if (FAILED(hr)) {
+ qErrnoWarning("%s: GetGdiInterop failed", __FUNCTION__);
+ return false;
+ }
+ }
+ return true;
+}
+
+#endif // !defined(QT_NO_DIRECTWRITE)
+
+/*!
+ \class QWindowsFontDatabase
+ \brief Font database for Windows
+
+ \note The Qt 4.8 WIndows font database employed a mechanism of
+ delayed population of the database again passing a font name
+ to EnumFontFamiliesEx(), working around the fact that
+ EnumFontFamiliesEx() does not list all fonts by default.
+ This should be introduced to Lighthouse as well?
+
+ \ingroup qt-lighthouse-win
+*/
+
+QDebug operator<<(QDebug d, const QFontDef &def)
+{
+ d.nospace() << "Family=" << def.family << " Stylename=" << def.styleName
+ << " pointsize=" << def.pointSize << " pixelsize=" << def.pixelSize
+ << " styleHint=" << def.styleHint << " weight=" << def.weight
+ << " stretch=" << def.stretch << " hintingPreference="
+ << def.hintingPreference << ' ';
+ return d;
+}
+
+/* From QFontDatabase.cpp, qt_determine_writing_systems_from_truetype_bits().
+ * Fixme: Make public? */
+
+// see the Unicode subset bitfields in the MSDN docs
+static int requiredUnicodeBits[QFontDatabase::WritingSystemsCount][2] = {
+ // Any,
+ { 127, 127 },
+ // Latin,
+ { 0, 127 },
+ // Greek,
+ { 7, 127 },
+ // Cyrillic,
+ { 9, 127 },
+ // Armenian,
+ { 10, 127 },
+ // Hebrew,
+ { 11, 127 },
+ // Arabic,
+ { 13, 127 },
+ // Syriac,
+ { 71, 127 },
+ //Thaana,
+ { 72, 127 },
+ //Devanagari,
+ { 15, 127 },
+ //Bengali,
+ { 16, 127 },
+ //Gurmukhi,
+ { 17, 127 },
+ //Gujarati,
+ { 18, 127 },
+ //Oriya,
+ { 19, 127 },
+ //Tamil,
+ { 20, 127 },
+ //Telugu,
+ { 21, 127 },
+ //Kannada,
+ { 22, 127 },
+ //Malayalam,
+ { 23, 127 },
+ //Sinhala,
+ { 73, 127 },
+ //Thai,
+ { 24, 127 },
+ //Lao,
+ { 25, 127 },
+ //Tibetan,
+ { 70, 127 },
+ //Myanmar,
+ { 74, 127 },
+ // Georgian,
+ { 26, 127 },
+ // Khmer,
+ { 80, 127 },
+ // SimplifiedChinese,
+ { 126, 127 },
+ // TraditionalChinese,
+ { 126, 127 },
+ // Japanese,
+ { 126, 127 },
+ // Korean,
+ { 56, 127 },
+ // Vietnamese,
+ { 0, 127 }, // same as latin1
+ // Other,
+ { 126, 127 },
+ // Ogham,
+ { 78, 127 },
+ // Runic,
+ { 79, 127 },
+ // Nko,
+ { 14, 127 },
+};
+
+enum
+{
+ SimplifiedChineseCsbBit = 18,
+ TraditionalChineseCsbBit = 20,
+ JapaneseCsbBit = 17,
+ KoreanCsbBit = 21
+};
+
+static inline void writingSystemsFromTrueTypeBits(quint32 unicodeRange[4],
+ quint32 codePageRange[2],
+ QSupportedWritingSystems *ws)
+{
+ bool hasScript = false;
+ for(int i = 0; i < QFontDatabase::WritingSystemsCount; i++) {
+ int bit = requiredUnicodeBits[i][0];
+ int index = bit/32;
+ int flag = 1 << (bit&31);
+ if (bit != 126 && unicodeRange[index] & flag) {
+ bit = requiredUnicodeBits[i][1];
+ index = bit/32;
+
+ flag = 1 << (bit&31);
+ if (bit == 127 || unicodeRange[index] & flag) {
+ ws->setSupported(QFontDatabase::WritingSystem(i), true);
+ hasScript = true;
+ }
+ }
+ }
+ if(codePageRange[0] & (1 << SimplifiedChineseCsbBit)) {
+ ws->setSupported(QFontDatabase::SimplifiedChinese, true);
+ hasScript = true;
+ }
+ if(codePageRange[0] & (1 << TraditionalChineseCsbBit)) {
+ ws->setSupported(QFontDatabase::TraditionalChinese, true);
+ hasScript = true;
+ }
+ if(codePageRange[0] & (1 << JapaneseCsbBit)) {
+ ws->setSupported(QFontDatabase::Japanese, true);
+ hasScript = true;
+ //qDebug("font %s supports Japanese", familyName.latin1());
+ }
+ if(codePageRange[0] & (1 << KoreanCsbBit)) {
+ ws->setSupported(QFontDatabase::Korean, true);
+ hasScript = true;
+ }
+ if (!hasScript)
+ ws->setSupported(QFontDatabase::Symbol, true);
+}
+
+// convert 0 ~ 1000 integer to QFont::Weight
+static inline QFont::Weight weightFromInteger(long weight)
+{
+ if (weight < 400)
+ return QFont::Light;
+ if (weight < 600)
+ return QFont::Normal;
+ if (weight < 700)
+ return QFont::DemiBold;
+ if (weight < 800)
+ return QFont::Bold;
+ return QFont::Black;
+}
+
+static inline QFontDatabase::WritingSystem writingSystemFromScript(const QString &scriptName)
+{
+ if (scriptName == QStringLiteral("Western")
+ || scriptName == QStringLiteral("Baltic")
+ || scriptName == QStringLiteral("Central European")
+ || scriptName == QStringLiteral("Turkish")
+ || scriptName == QStringLiteral("Vietnamese")
+ || scriptName == QStringLiteral("OEM/Dos"))
+ return QFontDatabase::Latin;
+ if (scriptName == QStringLiteral("Thai"))
+ return QFontDatabase::Thai;
+ if (scriptName == QStringLiteral("Symbol")
+ || scriptName == QStringLiteral("Other"))
+ return QFontDatabase::Symbol;
+ if (scriptName == QStringLiteral("CHINESE_GB2312"))
+ return QFontDatabase::SimplifiedChinese;
+ if (scriptName == QStringLiteral("CHINESE_BIG5"))
+ return QFontDatabase::TraditionalChinese;
+ if (scriptName == QStringLiteral("Cyrillic"))
+ return QFontDatabase::Cyrillic;
+ if (scriptName == QStringLiteral("Hangul"))
+ return QFontDatabase::Korean;
+ if (scriptName == QStringLiteral("Hebrew"))
+ return QFontDatabase::Hebrew;
+ if (scriptName == QStringLiteral("Greek"))
+ return QFontDatabase::Greek;
+ if (scriptName == QStringLiteral("Japanese"))
+ return QFontDatabase::Japanese;
+ if (scriptName == QStringLiteral("Arabic"))
+ return QFontDatabase::Arabic;
+ return QFontDatabase::Any;
+}
+
+static bool addFontToDatabase(QString familyName, const QString &scriptName,
+ const TEXTMETRIC *textmetric,
+ const FONTSIGNATURE *signature,
+ int type)
+{
+ // the "@family" fonts are just the same as "family". Ignore them.
+ if (familyName.at(0) == QLatin1Char('@') || familyName.startsWith(QStringLiteral("WST_")))
+ return false;
+
+ static const int SMOOTH_SCALABLE = 0xffff;
+ const QString foundryName; // No such concept.
+ const NEWTEXTMETRIC *tm = (NEWTEXTMETRIC *)textmetric;
+ const bool fixed = !(tm->tmPitchAndFamily & TMPF_FIXED_PITCH);
+ const bool ttf = (tm->tmPitchAndFamily & TMPF_TRUETYPE);
+ const bool scalable = tm->tmPitchAndFamily & (TMPF_VECTOR|TMPF_TRUETYPE);
+ const int size = scalable ? SMOOTH_SCALABLE : tm->tmHeight;
+ const QFont::Style style = tm->tmItalic ? QFont::StyleItalic : QFont::StyleNormal;
+ const bool antialias = false;
+ const QFont::Weight weight = weightFromInteger(tm->tmWeight);
+ const QFont::Stretch stretch = QFont::Unstretched;
+
+ Q_UNUSED(fixed)
+
+ if (QWindowsContext::verboseFonts > 2) {
+ QDebug nospace = qDebug().nospace();
+ nospace << __FUNCTION__ << familyName << scriptName
+ << "TTF=" << ttf;
+ if (type & DEVICE_FONTTYPE)
+ nospace << " DEVICE";
+ if (type & RASTER_FONTTYPE)
+ nospace << " RASTER";
+ if (type & TRUETYPE_FONTTYPE)
+ nospace << " TRUETYPE";
+ nospace << " scalable=" << scalable << " Size=" << size
+ << " Style=" << style << " Weight=" << weight
+ << " stretch=" << stretch;
+ }
+
+/* Fixme: omitted for the moment
+ if(ttf && localizedName(familyName) && family->english_name.isEmpty())
+ family->english_name = getEnglishName(familyName);
+*/
+ QSupportedWritingSystems writingSystems;
+ if (type & TRUETYPE_FONTTYPE) {
+ quint32 unicodeRange[4] = {
+ signature->fsUsb[0], signature->fsUsb[1],
+ signature->fsUsb[2], signature->fsUsb[3]
+ };
+ quint32 codePageRange[2] = {
+ signature->fsCsb[0], signature->fsCsb[1]
+ };
+ writingSystemsFromTrueTypeBits(unicodeRange, codePageRange, &writingSystems);
+ // ### Hack to work around problem with Thai text on Windows 7. Segoe UI contains
+ // the symbol for Baht, and Windows thus reports that it supports the Thai script.
+ // Since it's the default UI font on this platform, most widgets will be unable to
+ // display Thai text by default. As a temporary work around, we special case Segoe UI
+ // and remove the Thai script from its list of supported writing systems.
+ if (writingSystems.supported(QFontDatabase::Thai) &&
+ familyName == QStringLiteral("Segoe UI"))
+ writingSystems.setSupported(QFontDatabase::Thai, false);
+ } else {
+ const QFontDatabase::WritingSystem ws = writingSystemFromScript(scriptName);
+ if (ws != QFontDatabase::Any)
+ writingSystems.setSupported(ws);
+ }
+
+ QPlatformFontDatabase::registerFont(familyName, foundryName, weight,
+ style, stretch, antialias, scalable, size, writingSystems, 0);
+ // add fonts windows can generate for us:
+ if (weight <= QFont::DemiBold)
+ QPlatformFontDatabase::registerFont(familyName, foundryName, QFont::Bold,
+ style, stretch, antialias, scalable, size, writingSystems, 0);
+ if (style != QFont::StyleItalic)
+ QPlatformFontDatabase::registerFont(familyName, foundryName, weight,
+ QFont::StyleItalic, stretch, antialias, scalable, size, writingSystems, 0);
+ if (weight <= QFont::DemiBold && style != QFont::StyleItalic)
+ QPlatformFontDatabase::registerFont(familyName, foundryName, QFont::Bold,
+ QFont::StyleItalic, stretch, antialias, scalable, size, writingSystems, 0);
+ return true;
+}
+
+static int CALLBACK storeFont(ENUMLOGFONTEX* f, NEWTEXTMETRICEX *textmetric,
+ int type, LPARAM namesSetIn)
+{
+ typedef QSet<QString> StringSet;
+ const QString familyName = QString::fromWCharArray(f->elfLogFont.lfFaceName);
+ const QString script = QString::fromWCharArray(f->elfScript);
+
+ const FONTSIGNATURE signature = textmetric->ntmFontSig;
+
+ // NEWTEXTMETRICEX is a NEWTEXTMETRIC, which according to the documentation is
+ // identical to a TEXTMETRIC except for the last four members, which we don't use
+ // anyway
+ if (addFontToDatabase(familyName, script, (TEXTMETRIC *)textmetric, &signature, type))
+ reinterpret_cast<StringSet *>(namesSetIn)->insert(familyName);
+
+ // keep on enumerating
+ return 1;
+}
+
+void QWindowsFontDatabase::populateFontDatabase()
+{
+ if (m_families.isEmpty()) {
+ QPlatformFontDatabase::populateFontDatabase();
+ populate(); // Called multiple times.
+ // Work around EnumFontFamiliesEx() not listing the system font, see below.
+ const QString sysFontFamily = QGuiApplication::font().family();
+ if (!m_families.contains(sysFontFamily))
+ populate(sysFontFamily);
+ }
+}
+
+/*!
+ \brief Populate font database using EnumFontFamiliesEx().
+
+ Normally, leaving the name empty should enumerate
+ all fonts, however, system fonts like "MS Shell Dlg 2"
+ are only found when specifying the name explicitly.
+*/
+
+void QWindowsFontDatabase::populate(const QString &family)
+ {
+
+ if (QWindowsContext::verboseFonts)
+ qDebug() << __FUNCTION__ << m_families.size() << family;
+
+ HDC dummy = GetDC(0);
+ LOGFONT lf;
+ lf.lfCharSet = DEFAULT_CHARSET;
+ if (family.size() >= LF_FACESIZE) {
+ qWarning("%s: Unable to enumerate family '%s'.",
+ __FUNCTION__, qPrintable(family));
+ return;
+ }
+ wmemcpy(lf.lfFaceName, reinterpret_cast<const wchar_t*>(family.utf16()),
+ family.size() + 1);
+ lf.lfPitchAndFamily = 0;
+ EnumFontFamiliesEx(dummy, &lf, (FONTENUMPROC)storeFont,
+ (LPARAM)&m_families, 0);
+ ReleaseDC(0, dummy);
+}
+
+QWindowsFontDatabase::QWindowsFontDatabase() :
+ m_fontEngineData(new QWindowsFontEngineData)
+{
+ if (QWindowsContext::verboseFonts)
+ qDebug() << __FUNCTION__ << "Clear type: "
+ << m_fontEngineData->clearTypeEnabled << "gamma: "
+ << m_fontEngineData->fontSmoothingGamma;
+}
+
+QWindowsFontDatabase::~QWindowsFontDatabase()
+{
+}
+
+QFontEngine * QWindowsFontDatabase::fontEngine(const QFontDef &fontDef,
+ QUnicodeTables::Script script,
+ void *handle)
+{
+ QFontEngine *fe = QWindowsFontDatabase::createEngine(script, fontDef,
+ 0, QWindowsContext::instance()->defaultDPI(), false,
+ QStringList(), m_fontEngineData);
+ if (QWindowsContext::verboseFonts)
+ qDebug() << __FUNCTION__ << "FONTDEF" << fontDef << script << fe << handle;
+ return fe;
+}
+
+QFontEngine *QWindowsFontDatabase::fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference)
+{
+ QFontEngine *fe = QPlatformFontDatabase::fontEngine(fontData, pixelSize, hintingPreference);
+ if (QWindowsContext::verboseFonts)
+ qDebug() << __FUNCTION__ << "FONTDATA" << fontData << pixelSize << hintingPreference << fe;
+ return fe;
+}
+
+QStringList QWindowsFontDatabase::fallbacksForFamily(const QString family, const QFont::Style &style, const QFont::StyleHint &styleHint, const QUnicodeTables::Script &script) const
+{
+ QStringList result = QPlatformFontDatabase::fallbacksForFamily(family, style, styleHint, script);
+ if (!result.isEmpty())
+ return result;
+ if (QWindowsContext::verboseFonts)
+ qDebug() << __FUNCTION__ << family << style << styleHint
+ << script << result << m_families.size();
+ return result;
+}
+
+QStringList QWindowsFontDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName)
+{
+ const QStringList result = QPlatformFontDatabase::addApplicationFont(fontData, fileName);
+ Q_UNIMPLEMENTED();
+ return result;
+}
+
+void QWindowsFontDatabase::releaseHandle(void *handle)
+{
+ if (handle && QWindowsContext::verboseFonts)
+ qDebug() << __FUNCTION__ << handle;
+}
+
+QString QWindowsFontDatabase::fontDir() const
+{
+ const QString result = QPlatformFontDatabase::fontDir();
+ if (QWindowsContext::verboseFonts)
+ qDebug() << __FUNCTION__ << result;
+ return result;
+}
+
+HFONT QWindowsFontDatabase::systemFont()
+{
+ static const HFONT stock_sysfont = (HFONT)GetStockObject(SYSTEM_FONT);
+ return stock_sysfont;
+}
+
+// Creation functions
+
+static inline bool scriptRequiresOpenType(int script)
+{
+ return ((script >= QUnicodeTables::Syriac && script <= QUnicodeTables::Sinhala)
+ || script == QUnicodeTables::Khmer || script == QUnicodeTables::Nko);
+}
+
+static const char *other_tryFonts[] = {
+ "Arial",
+ "MS UI Gothic",
+ "Gulim",
+ "SimSun",
+ "PMingLiU",
+ "Arial Unicode MS",
+ 0
+};
+
+static const char *jp_tryFonts [] = {
+ "MS UI Gothic",
+ "Arial",
+ "Gulim",
+ "SimSun",
+ "PMingLiU",
+ "Arial Unicode MS",
+ 0
+};
+
+static const char *ch_CN_tryFonts [] = {
+ "SimSun",
+ "Arial",
+ "PMingLiU",
+ "Gulim",
+ "MS UI Gothic",
+ "Arial Unicode MS",
+ 0
+};
+
+static const char *ch_TW_tryFonts [] = {
+ "PMingLiU",
+ "Arial",
+ "SimSun",
+ "Gulim",
+ "MS UI Gothic",
+ "Arial Unicode MS",
+ 0
+};
+
+static const char *kr_tryFonts[] = {
+ "Gulim",
+ "Arial",
+ "PMingLiU",
+ "SimSun",
+ "MS UI Gothic",
+ "Arial Unicode MS",
+ 0
+};
+
+static const char **tryFonts = 0;
+
+QFontEngine *QWindowsFontDatabase::createEngine(int script, const QFontDef &request,
+ HDC fontHdc, int dpi, bool rawMode,
+ const QStringList &family_list,
+ const QSharedPointer<QWindowsFontEngineData> &data)
+{
+ LOGFONT lf;
+ memset(&lf, 0, sizeof(LOGFONT));
+
+ const bool useDevice = (request.styleStrategy & QFont::PreferDevice) && fontHdc;
+
+ const HDC hdc = useDevice ? fontHdc : data->hdc;
+
+ bool stockFont = false;
+ bool preferClearTypeAA = false;
+
+ HFONT hfont = 0;
+
+#if !defined(QT_NO_DIRECTWRITE)
+ bool useDirectWrite = (request.hintingPreference == QFont::PreferNoHinting)
+ || (request.hintingPreference == QFont::PreferVerticalHinting);
+ IDWriteFont *directWriteFont = 0;
+#else
+ bool useDirectWrite = false;
+#endif
+
+ if (rawMode) { // will choose a stock font
+ int f = SYSTEM_FONT;
+ const QString fam = request.family.toLower();
+ if (fam == QStringLiteral("default") || fam == QStringLiteral("system"))
+ f = SYSTEM_FONT;
+ else if (fam == QStringLiteral("system_fixed"))
+ f = SYSTEM_FIXED_FONT;
+ else if (fam == QStringLiteral("ansi_fixed"))
+ f = ANSI_FIXED_FONT;
+ else if (fam == QStringLiteral("ansi_var"))
+ f = ANSI_VAR_FONT;
+ else if (fam == QStringLiteral("device_default"))
+ f = DEVICE_DEFAULT_FONT;
+ else if (fam == QStringLiteral("oem_fixed"))
+ f = OEM_FIXED_FONT;
+ else if (fam.at(0) == QLatin1Char('#'))
+ f = fam.right(fam.length()-1).toInt();
+ hfont = (HFONT)GetStockObject(f);
+ if (!hfont) {
+ qErrnoWarning("%s: GetStockObject failed", __FUNCTION__);
+ hfont = QWindowsFontDatabase::systemFont();
+ }
+ stockFont = true;
+ } else {
+ int hint = FF_DONTCARE;
+ switch (request.styleHint) {
+ case QFont::Helvetica:
+ hint = FF_SWISS;
+ break;
+ case QFont::Times:
+ hint = FF_ROMAN;
+ break;
+ case QFont::Courier:
+ hint = FF_MODERN;
+ break;
+ case QFont::OldEnglish:
+ hint = FF_DECORATIVE;
+ break;
+ case QFont::System:
+ hint = FF_MODERN;
+ break;
+ default:
+ break;
+ }
+
+ lf.lfHeight = -qRound(request.pixelSize);
+ lf.lfWidth = 0;
+ lf.lfEscapement = 0;
+ lf.lfOrientation = 0;
+ if (request.weight == 50)
+ lf.lfWeight = FW_DONTCARE;
+ else
+ lf.lfWeight = (request.weight*900)/99;
+ lf.lfItalic = request.style != QFont::StyleNormal;
+ lf.lfCharSet = DEFAULT_CHARSET;
+
+ int strat = OUT_DEFAULT_PRECIS;
+ if (request.styleStrategy & QFont::PreferBitmap) {
+ strat = OUT_RASTER_PRECIS;
+ } else if (request.styleStrategy & QFont::PreferDevice) {
+ strat = OUT_DEVICE_PRECIS;
+ } else if (request.styleStrategy & QFont::PreferOutline) {
+ strat = OUT_OUTLINE_PRECIS;
+ } else if (request.styleStrategy & QFont::ForceOutline) {
+ strat = OUT_TT_ONLY_PRECIS;
+ }
+
+ lf.lfOutPrecision = strat;
+
+ int qual = DEFAULT_QUALITY;
+
+ if (request.styleStrategy & QFont::PreferMatch)
+ qual = DRAFT_QUALITY;
+ else if (request.styleStrategy & QFont::PreferQuality)
+ qual = PROOF_QUALITY;
+
+ if (request.styleStrategy & QFont::PreferAntialias) {
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_XP) {
+ qual = CLEARTYPE_QUALITY;
+ preferClearTypeAA = true;
+ } else {
+ qual = ANTIALIASED_QUALITY;
+ }
+ } else if (request.styleStrategy & QFont::NoAntialias) {
+ qual = NONANTIALIASED_QUALITY;
+ }
+
+ lf.lfQuality = qual;
+
+ lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
+ lf.lfPitchAndFamily = DEFAULT_PITCH | hint;
+
+ QString fam = request.family;
+
+ if(fam.isEmpty())
+ fam = QStringLiteral("MS Sans Serif");
+
+ if ((fam == QStringLiteral("MS Sans Serif"))
+ && (request.style == QFont::StyleItalic || (-lf.lfHeight > 18 && -lf.lfHeight != 24))) {
+ fam = QStringLiteral("Arial"); // MS Sans Serif has bearing problems in italic, and does not scale
+ }
+ if (fam == QStringLiteral("Courier") && !(request.styleStrategy & QFont::PreferBitmap))
+ fam = QStringLiteral("Courier New");
+
+ memcpy(lf.lfFaceName, fam.utf16(), sizeof(wchar_t) * qMin(fam.length() + 1, 32)); // 32 = Windows hard-coded
+
+ hfont = CreateFontIndirect(&lf);
+ if (!hfont)
+ qErrnoWarning("%s: CreateFontIndirect failed", __FUNCTION__);
+
+ stockFont = (hfont == 0);
+ bool ttf = false;
+ int avWidth = 0;
+ BOOL res;
+ HGDIOBJ oldObj = SelectObject(hdc, hfont);
+
+ TEXTMETRIC tm;
+ res = GetTextMetrics(hdc, &tm);
+ avWidth = tm.tmAveCharWidth;
+ ttf = tm.tmPitchAndFamily & TMPF_TRUETYPE;
+ SelectObject(hdc, oldObj);
+
+ if (!ttf || !useDirectWrite) {
+ useDirectWrite = false;
+
+ if (hfont && (!ttf || request.stretch != 100)) {
+ DeleteObject(hfont);
+ if (!res)
+ qErrnoWarning("QFontEngine::loadEngine: GetTextMetrics failed");
+ lf.lfWidth = avWidth * request.stretch/100;
+ hfont = CreateFontIndirect(&lf);
+ if (!hfont)
+ qErrnoWarning("%s: CreateFontIndirect with stretch failed", __FUNCTION__);
+ }
+
+ if (hfont == 0) {
+ hfont = (HFONT)GetStockObject(ANSI_VAR_FONT);
+ stockFont = true;
+ }
+ }
+
+#if !defined(QT_NO_DIRECTWRITE)
+ else {
+ // Default to false for DirectWrite (and re-enable once/if everything
+ // turns out okay)
+ useDirectWrite = false;
+ if (initDirectWrite(data.data())) {
+ const QString nameSubstitute = QWindowsFontEngineDirectWrite::fontNameSubstitute(QString::fromWCharArray(lf.lfFaceName));
+ memcpy(lf.lfFaceName, nameSubstitute.utf16(),
+ sizeof(wchar_t) * qMin(nameSubstitute.length() + 1, LF_FACESIZE));
+
+ HRESULT hr = data->directWriteGdiInterop->CreateFontFromLOGFONT(
+ &lf,
+ &directWriteFont);
+ if (FAILED(hr)) {
+ qErrnoWarning("%s: CreateFontFromLOGFONT failed", __FUNCTION__);
+ } else {
+ DeleteObject(hfont);
+ useDirectWrite = true;
+ }
+ }
+ }
+#endif
+ }
+
+ QFontEngine *fe = 0;
+ if (!useDirectWrite) {
+ QWindowsFontEngine *few = new QWindowsFontEngine(request.family, hfont, stockFont, lf, data);
+ few->setObjectName(QStringLiteral("QWindowsFontEngine_") + request.family);
+ if (preferClearTypeAA)
+ few->glyphFormat = QFontEngineGlyphCache::Raster_RGBMask;
+
+ // Also check for OpenType tables when using complex scripts
+ // ### TODO: This only works for scripts that require OpenType. More generally
+ // for scripts that do not require OpenType we should just look at the list of
+ // supported writing systems in the font's OS/2 table.
+ if (scriptRequiresOpenType(script)) {
+ HB_Face hbFace = few->harfbuzzFace();
+ if (!hbFace || !hbFace->supported_scripts[script]) {
+ qWarning(" OpenType support missing for script\n");
+ delete few;
+ return 0;
+ }
+ }
+
+ few->initFontInfo(request, fontHdc, dpi);
+ fe = few;
+ }
+
+#if !defined(QT_NO_DIRECTWRITE)
+ else {
+ IDWriteFontFace *directWriteFontFace = NULL;
+ HRESULT hr = directWriteFont->CreateFontFace(&directWriteFontFace);
+ if (SUCCEEDED(hr)) {
+ QWindowsFontEngineDirectWrite *fedw = new QWindowsFontEngineDirectWrite(directWriteFontFace,
+ request.pixelSize,
+ data);
+ fedw->initFontInfo(request, dpi, directWriteFont);
+ fedw->setObjectName(QStringLiteral("QWindowsFontEngineDirectWrite_") + request.family);
+ fe = fedw;
+ } else {
+ qErrnoWarning("%s: CreateFontFace failed", __FUNCTION__);
+ }
+ }
+
+ if (directWriteFont != 0)
+ directWriteFont->Release();
+#endif
+
+ if(script == QUnicodeTables::Common
+ && !(request.styleStrategy & QFont::NoFontMerging)) {
+ QFontDatabase db;
+ if (!db.writingSystems(request.family).contains(QFontDatabase::Symbol)) {
+ if(!tryFonts) {
+ LANGID lid = GetUserDefaultLangID();
+ switch( lid&0xff ) {
+ case LANG_CHINESE: // Chinese (Taiwan)
+ if ( lid == 0x0804 ) // Taiwan
+ tryFonts = ch_TW_tryFonts;
+ else
+ tryFonts = ch_CN_tryFonts;
+ break;
+ case LANG_JAPANESE:
+ tryFonts = jp_tryFonts;
+ break;
+ case LANG_KOREAN:
+ tryFonts = kr_tryFonts;
+ break;
+ default:
+ tryFonts = other_tryFonts;
+ break;
+ }
+ }
+ QStringList fm = QFontDatabase().families();
+ QStringList list = family_list;
+ const char **tf = tryFonts;
+ while(tf && *tf) {
+ if(fm.contains(QLatin1String(*tf)))
+ list << QLatin1String(*tf);
+ ++tf;
+ }
+ QFontEngine *mfe = new QWindowsMultiFontEngine(fe, list);
+ mfe->setObjectName(QStringLiteral("QWindowsMultiFontEngine_") + request.family);
+ mfe->fontDef = fe->fontDef;
+ fe = mfe;
+ }
+ }
+ return fe;
+}
+
+static inline int verticalDPI()
+{
+ return GetDeviceCaps(QWindowsContext::instance()->displayContext(), LOGPIXELSY);
+}
+
+QFont QWindowsFontDatabase::defaultFont() const
+{
+ LOGFONT lf;
+ GetObject(GetStockObject(DEFAULT_GUI_FONT), sizeof(lf), &lf);
+ QFont systemFont = QWindowsFontDatabase::LOGFONT_to_QFont(lf);
+ // "MS Shell Dlg 2" is the correct system font >= Win2k
+ if (systemFont.family() == QStringLiteral("MS Shell Dlg"))
+ systemFont.setFamily(QStringLiteral("MS Shell Dlg 2"));
+ if (QWindowsContext::verboseFonts)
+ qDebug() << __FUNCTION__ << systemFont;
+ return systemFont;
+}
+
+QHash<QByteArray, QFont> QWindowsFontDatabase::defaultFonts() const
+{
+ QHash<QByteArray, QFont> result;
+ NONCLIENTMETRICS ncm;
+ ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICS, lfMessageFont) + sizeof(LOGFONT);
+ SystemParametersInfo(SPI_GETNONCLIENTMETRICS, ncm.cbSize , &ncm, 0);
+
+ const int verticalRes = verticalDPI();
+
+ const QFont menuFont = LOGFONT_to_QFont(ncm.lfMenuFont, verticalRes);
+ const QFont messageFont = LOGFONT_to_QFont(ncm.lfMessageFont, verticalRes);
+ const QFont statusFont = LOGFONT_to_QFont(ncm.lfStatusFont, verticalRes);
+ const QFont titleFont = LOGFONT_to_QFont(ncm.lfCaptionFont, verticalRes);
+
+ LOGFONT lfIconTitleFont;
+ SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lfIconTitleFont), &lfIconTitleFont, 0);
+ const QFont iconTitleFont = LOGFONT_to_QFont(lfIconTitleFont, verticalRes);
+
+ result.insert(QByteArray("QMenu"), menuFont);
+ result.insert(QByteArray("QMenuBar"), menuFont);
+ result.insert(QByteArray("QMessageBox"), messageFont);
+ result.insert(QByteArray("QTipLabel"), statusFont);
+ result.insert(QByteArray("QStatusBar"), statusFont);
+ result.insert(QByteArray("Q3TitleBar"), titleFont);
+ result.insert(QByteArray("QWorkspaceTitleBar"), titleFont);
+ result.insert(QByteArray("QAbstractItemView"), iconTitleFont);
+ result.insert(QByteArray("QDockWidgetTitle"), iconTitleFont);
+ if (QWindowsContext::verboseFonts) {
+ typedef QHash<QByteArray, QFont>::const_iterator CIT;
+ QDebug nsp = qDebug().nospace();
+ nsp << __FUNCTION__ << " DPI=" << verticalRes << "\n";
+ const CIT cend = result.constEnd();
+ for (CIT it = result.constBegin(); it != cend; ++it)
+ nsp << it.key() << ' ' << it.value() << '\n';
+ }
+ return result;
+}
+
+QFont QWindowsFontDatabase::LOGFONT_to_QFont(const LOGFONT& logFont, int verticalDPI_In)
+{
+ if (verticalDPI_In <= 0)
+ verticalDPI_In = verticalDPI();
+ QFont qFont(QString::fromWCharArray(logFont.lfFaceName));
+ qFont.setItalic(logFont.lfItalic);
+ if (logFont.lfWeight != FW_DONTCARE)
+ qFont.setWeight(weightFromInteger(logFont.lfWeight));
+ const qreal logFontHeight = qAbs(logFont.lfHeight);
+ qFont.setPointSizeF(logFontHeight * 72.0 / qreal(verticalDPI_In));
+ qFont.setUnderline(false);
+ qFont.setOverline(false);
+ qFont.setStrikeOut(false);
+ return qFont;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.h b/src/plugins/platforms/windows/qwindowsfontdatabase.h
new file mode 100644
index 0000000000..a80482f6e2
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsfontdatabase.h
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSFONTDATABASE_H
+#define QWINDOWSFONTDATABASE_H
+
+#include <QtGui/QPlatformFontDatabase>
+#include <QtCore/QSharedPointer>
+#include "qtwindows_additional.h"
+
+QT_BEGIN_NAMESPACE
+
+#if !defined(QT_NO_DIRECTWRITE)
+ struct IDWriteFactory;
+ struct IDWriteGdiInterop;
+#endif
+
+class QWindowsFontEngineData
+{
+ Q_DISABLE_COPY(QWindowsFontEngineData)
+public:
+ QWindowsFontEngineData();
+ ~QWindowsFontEngineData();
+
+ uint pow_gamma[256];
+
+ bool clearTypeEnabled;
+ qreal fontSmoothingGamma;
+ HDC hdc;
+#if !defined(QT_NO_DIRECTWRITE)
+ IDWriteFactory *directWriteFactory;
+ IDWriteGdiInterop *directWriteGdiInterop;
+#endif
+};
+
+class QWindowsFontDatabase : public QPlatformFontDatabase
+{
+public:
+ QWindowsFontDatabase();
+ ~QWindowsFontDatabase();
+
+ virtual void populateFontDatabase();
+ virtual QFontEngine *fontEngine(const QFontDef &fontDef, QUnicodeTables::Script script, void *handle);
+ virtual QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference);
+ virtual QStringList fallbacksForFamily(const QString family, const QFont::Style &style, const QFont::StyleHint &styleHint, const QUnicodeTables::Script &script) const;
+ virtual QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName);
+ virtual void releaseHandle(void *handle);
+ virtual QString fontDir() const;
+
+ virtual QFont defaultFont() const;
+ virtual QHash<QByteArray, QFont> defaultFonts() const;
+
+ static QFontEngine *createEngine(int script, const QFontDef &request,
+ HDC fontHdc, int dpi, bool rawMode,
+ const QStringList &family_list,
+ const QSharedPointer<QWindowsFontEngineData> &data);
+
+ static HFONT systemFont();
+ static QFont LOGFONT_to_QFont(const LOGFONT& lf, int verticalDPI = 0);
+
+private:
+ void populate(const QString &family = QString());
+ QSharedPointer<QWindowsFontEngineData> m_fontEngineData;
+ QSet<QString> m_families;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSFONTDATABASE_H
diff --git a/src/plugins/platforms/windows/qwindowsfontengine.cpp b/src/plugins/platforms/windows/qwindowsfontengine.cpp
new file mode 100644
index 0000000000..80d9ed4686
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsfontengine.cpp
@@ -0,0 +1,1223 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#if _WIN32_WINNT < 0x0500
+#undef _WIN32_WINNT
+#define _WIN32_WINNT 0x0500
+#endif
+
+#include "qwindowsfontengine.h"
+#include "qwindowsnativeimage.h"
+#include "qwindowscontext.h"
+#include "qwindowsfontdatabase.h"
+#include "qtwindows_additional.h"
+
+#include <QtGui/private/qtextengine_p.h> // glyph_metrics_t
+#include <QtGui/private/qguiapplication_p.h>
+#include <QtGui/QPaintDevice>
+#include <QtGui/QBitmap>
+#include <QtGui/QPainter>
+#include <QtGui/private/qpainter_p.h>
+#include <QtGui/QPaintEngine>
+#include <QtGui/private/qpaintengine_raster_p.h>
+
+#include <QtCore/QtEndian>
+#include <QtCore/qmath.h>
+#include <QtCore/QThreadStorage>
+#include <QtCore/private/qsystemlibrary_p.h>
+
+#include <QtCore/private/qunicodetables_p.h>
+#include <QtCore/QDebug>
+
+#include <limits.h>
+
+QT_BEGIN_NAMESPACE
+
+//### mingw needed define
+#ifndef TT_PRIM_CSPLINE
+#define TT_PRIM_CSPLINE 3
+#endif
+
+#ifdef MAKE_TAG
+#undef MAKE_TAG
+#endif
+// GetFontData expects the tags in little endian ;(
+#define MAKE_TAG(ch1, ch2, ch3, ch4) (\
+ (((quint32)(ch4)) << 24) | \
+ (((quint32)(ch3)) << 16) | \
+ (((quint32)(ch2)) << 8) | \
+ ((quint32)(ch1)) \
+ )
+
+// common DC for all fonts
+
+QT_BEGIN_NAMESPACE
+
+typedef BOOL (WINAPI *PtrGetCharWidthI)(HDC, UINT, UINT, LPWORD, LPINT);
+static PtrGetCharWidthI ptrGetCharWidthI = 0;
+static bool resolvedGetCharWidthI = false;
+
+static void resolveGetCharWidthI()
+{
+ if (resolvedGetCharWidthI)
+ return;
+ resolvedGetCharWidthI = true;
+ ptrGetCharWidthI = (PtrGetCharWidthI)QSystemLibrary::resolve(QStringLiteral("gdi32"), "GetCharWidthI");
+}
+
+// defined in qtextengine_win.cpp
+typedef void *SCRIPT_CACHE;
+typedef HRESULT (WINAPI *fScriptFreeCache)(SCRIPT_CACHE *);
+extern fScriptFreeCache ScriptFreeCache;
+
+static inline quint32 getUInt(unsigned char *p)
+{
+ quint32 val;
+ val = *p++ << 24;
+ val |= *p++ << 16;
+ val |= *p++ << 8;
+ val |= *p;
+
+ return val;
+}
+
+static inline quint16 getUShort(unsigned char *p)
+{
+ quint16 val;
+ val = *p++ << 8;
+ val |= *p;
+
+ return val;
+}
+
+// general font engine
+
+QFixed QWindowsFontEngine::lineThickness() const
+{
+ if(lineWidth > 0)
+ return lineWidth;
+
+ return QFontEngine::lineThickness();
+}
+
+static OUTLINETEXTMETRIC *getOutlineTextMetric(HDC hdc)
+{
+ int size;
+ size = GetOutlineTextMetrics(hdc, 0, 0);
+ OUTLINETEXTMETRIC *otm = (OUTLINETEXTMETRIC *)malloc(size);
+ GetOutlineTextMetrics(hdc, size, otm);
+ return otm;
+}
+
+void QWindowsFontEngine::getCMap()
+{
+ ttf = (bool)(tm.tmPitchAndFamily & TMPF_TRUETYPE);
+ HDC hdc = m_fontEngineData->hdc;
+ SelectObject(hdc, hfont);
+ bool symb = false;
+ if (ttf) {
+ cmapTable = getSfntTable(qbswap<quint32>(MAKE_TAG('c', 'm', 'a', 'p')));
+ int size = 0;
+ cmap = QFontEngine::getCMap(reinterpret_cast<const uchar *>(cmapTable.constData()),
+ cmapTable.size(), &symb, &size);
+ }
+ if (!cmap) {
+ ttf = false;
+ symb = false;
+ }
+ symbol = symb;
+ designToDevice = 1;
+ _faceId.index = 0;
+ if(cmap) {
+ OUTLINETEXTMETRIC *otm = getOutlineTextMetric(hdc);
+ designToDevice = QFixed((int)otm->otmEMSquare)/int(otm->otmTextMetrics.tmHeight);
+ unitsPerEm = otm->otmEMSquare;
+ x_height = (int)otm->otmsXHeight;
+ loadKerningPairs(designToDevice);
+ _faceId.filename = QString::fromWCharArray((wchar_t *)((char *)otm + (quintptr)otm->otmpFullName)).toLatin1();
+ lineWidth = otm->otmsUnderscoreSize;
+ fsType = otm->otmfsType;
+ free(otm);
+ } else {
+ unitsPerEm = tm.tmHeight;
+ }
+}
+
+
+inline unsigned int getChar(const QChar *str, int &i, const int len)
+{
+ unsigned int uc = str[i].unicode();
+ if (uc >= 0xd800 && uc < 0xdc00 && i < len-1) {
+ uint low = str[i+1].unicode();
+ if (low >= 0xdc00 && low < 0xe000) {
+ uc = (uc - 0xd800)*0x400 + (low - 0xdc00) + 0x10000;
+ ++i;
+ }
+ }
+ return uc;
+}
+
+int QWindowsFontEngine::getGlyphIndexes(const QChar *str, int numChars, QGlyphLayout *glyphs, bool mirrored) const
+{
+ int i = 0;
+ int glyph_pos = 0;
+ if (mirrored) {
+ if (symbol) {
+ for (; i < numChars; ++i, ++glyph_pos) {
+ unsigned int uc = getChar(str, i, numChars);
+ glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc);
+ if (!glyphs->glyphs[glyph_pos] && uc < 0x100)
+ glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc + 0xf000);
+ }
+ } else if (ttf) {
+ for (; i < numChars; ++i, ++glyph_pos) {
+ unsigned int uc = getChar(str, i, numChars);
+ glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, QChar::mirroredChar(uc));
+ }
+ } else {
+ wchar_t first = tm.tmFirstChar;
+ wchar_t last = tm.tmLastChar;
+
+ for (; i < numChars; ++i, ++glyph_pos) {
+ uint ucs = QChar::mirroredChar(getChar(str, i, numChars));
+ if (ucs >= first && ucs <= last)
+ glyphs->glyphs[glyph_pos] = ucs;
+ else
+ glyphs->glyphs[glyph_pos] = 0;
+ }
+ }
+ } else {
+ if (symbol) {
+ for (; i < numChars; ++i, ++glyph_pos) {
+ unsigned int uc = getChar(str, i, numChars);
+ glyphs->glyphs[i] = getTrueTypeGlyphIndex(cmap, uc);
+ if(!glyphs->glyphs[glyph_pos] && uc < 0x100)
+ glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc + 0xf000);
+ }
+ } else if (ttf) {
+ for (; i < numChars; ++i, ++glyph_pos) {
+ unsigned int uc = getChar(str, i, numChars);
+ glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc);
+ }
+ } else {
+ wchar_t first = tm.tmFirstChar;
+ wchar_t last = tm.tmLastChar;
+
+ for (; i < numChars; ++i, ++glyph_pos) {
+ uint uc = getChar(str, i, numChars);
+ if (uc >= first && uc <= last)
+ glyphs->glyphs[glyph_pos] = uc;
+ else
+ glyphs->glyphs[glyph_pos] = 0;
+ }
+ }
+ }
+ glyphs->numGlyphs = glyph_pos;
+ return glyph_pos;
+}
+
+/*!
+ \class QWindowsFontEngine
+ \brief Standard Windows font engine.
+ \ingroup qt-lighthouse-win
+
+ Will probably be superseded by a common Free Type font engine in Qt 5.X.
+*/
+
+QWindowsFontEngine::QWindowsFontEngine(const QString &name,
+ HFONT _hfont, bool stockFontIn, LOGFONT lf,
+ QSharedPointer<QWindowsFontEngineData> fontEngineData) :
+ m_fontEngineData(fontEngineData),
+ _name(name),
+ hfont(_hfont),
+ m_logfont(lf),
+ stockFont(stockFontIn),
+ ttf(0),
+ hasOutline(0),
+ lw(0),
+ cmap(0),
+ lbearing(SHRT_MIN),
+ rbearing(SHRT_MIN),
+ x_height(-1),
+ synthesized_flags(-1),
+ lineWidth(-1),
+ widthCache(0),
+ widthCacheSize(0),
+ designAdvances(0),
+ designAdvancesSize(0)
+{
+ if (QWindowsContext::verboseFonts)
+ qDebug("%s: font='%s', size=%ld", __FUNCTION__, qPrintable(name), lf.lfHeight);
+ HDC hdc = m_fontEngineData->hdc;
+ SelectObject(hdc, hfont);
+ fontDef.pixelSize = -lf.lfHeight;
+ const BOOL res = GetTextMetrics(hdc, &tm);
+ fontDef.fixedPitch = !(tm.tmPitchAndFamily & TMPF_FIXED_PITCH);
+ if (!res) {
+ qErrnoWarning("%s: GetTextMetrics failed", __FUNCTION__);
+ ZeroMemory(&tm, sizeof(TEXTMETRIC));
+ }
+
+ cache_cost = tm.tmHeight * tm.tmAveCharWidth * 2000;
+ getCMap();
+
+ if (!resolvedGetCharWidthI)
+ resolveGetCharWidthI();
+}
+
+QWindowsFontEngine::~QWindowsFontEngine()
+{
+ if (designAdvances)
+ free(designAdvances);
+
+ if (widthCache)
+ free(widthCache);
+
+ // make sure we aren't by accident still selected
+ SelectObject(m_fontEngineData->hdc, (HFONT)GetStockObject(SYSTEM_FONT));
+
+ if (!stockFont) {
+ if (!DeleteObject(hfont))
+ qErrnoWarning("%s: QFontEngineWin: failed to delete non-stock font... failed", __FUNCTION__);
+ }
+ if (QWindowsContext::verboseFonts)
+ if (QWindowsContext::verboseFonts)
+ qDebug("%s: font='%s", __FUNCTION__, qPrintable(_name));
+}
+
+HGDIOBJ QWindowsFontEngine::selectDesignFont() const
+{
+ LOGFONT f = m_logfont;
+ f.lfHeight = unitsPerEm;
+ HFONT designFont = CreateFontIndirect(&f);
+ return SelectObject(m_fontEngineData->hdc, designFont);
+}
+
+bool QWindowsFontEngine::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const
+{
+ if (*nglyphs < len) {
+ *nglyphs = len;
+ return false;
+ }
+
+ *nglyphs = getGlyphIndexes(str, len, glyphs, flags & QTextEngine::RightToLeft);
+
+ if (flags & QTextEngine::GlyphIndicesOnly)
+ return true;
+
+ recalcAdvances(glyphs, flags);
+ return true;
+}
+
+inline void calculateTTFGlyphWidth(HDC hdc, UINT glyph, int &width)
+{
+ if (ptrGetCharWidthI)
+ ptrGetCharWidthI(hdc, glyph, 1, 0, &width);
+}
+
+void QWindowsFontEngine::recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFlags flags) const
+{
+ HGDIOBJ oldFont = 0;
+ HDC hdc = m_fontEngineData->hdc;
+ if (ttf && (flags & QTextEngine::DesignMetrics)) {
+ for(int i = 0; i < glyphs->numGlyphs; i++) {
+ unsigned int glyph = glyphs->glyphs[i];
+ if(int(glyph) >= designAdvancesSize) {
+ int newSize = (glyph + 256) >> 8 << 8;
+ designAdvances = q_check_ptr((QFixed *)realloc(designAdvances,
+ newSize*sizeof(QFixed)));
+ for(int i = designAdvancesSize; i < newSize; ++i)
+ designAdvances[i] = -1000000;
+ designAdvancesSize = newSize;
+ }
+ if (designAdvances[glyph] < -999999) {
+ if (!oldFont)
+ oldFont = selectDesignFont();
+
+ int width = 0;
+ calculateTTFGlyphWidth(hdc, glyph, width);
+ designAdvances[glyph] = QFixed(width) / designToDevice;
+ }
+ glyphs->advances_x[i] = designAdvances[glyph];
+ glyphs->advances_y[i] = 0;
+ }
+ if(oldFont)
+ DeleteObject(SelectObject(hdc, oldFont));
+ } else {
+ for(int i = 0; i < glyphs->numGlyphs; i++) {
+ unsigned int glyph = glyphs->glyphs[i];
+
+ glyphs->advances_y[i] = 0;
+
+ if (glyph >= widthCacheSize) {
+ int newSize = (glyph + 256) >> 8 << 8;
+ widthCache = q_check_ptr((unsigned char *)realloc(widthCache,
+ newSize*sizeof(QFixed)));
+ memset(widthCache + widthCacheSize, 0, newSize - widthCacheSize);
+ widthCacheSize = newSize;
+ }
+ glyphs->advances_x[i] = widthCache[glyph];
+ // font-width cache failed
+ if (glyphs->advances_x[i] == 0) {
+ int width = 0;
+ if (!oldFont)
+ oldFont = SelectObject(hdc, hfont);
+
+ if (!ttf) {
+ QChar ch[2] = { ushort(glyph), 0 };
+ int chrLen = 1;
+ if (glyph > 0xffff) {
+ ch[0] = QChar::highSurrogate(glyph);
+ ch[1] = QChar::lowSurrogate(glyph);
+ ++chrLen;
+ }
+ SIZE size = {0, 0};
+ GetTextExtentPoint32(hdc, (wchar_t *)ch, chrLen, &size);
+ width = size.cx;
+ } else {
+ calculateTTFGlyphWidth(hdc, glyph, width);
+ }
+ glyphs->advances_x[i] = width;
+ // if glyph's within cache range, store it for later
+ if (width > 0 && width < 0x100)
+ widthCache[glyph] = width;
+ }
+ }
+
+ if (oldFont)
+ SelectObject(hdc, oldFont);
+ }
+}
+
+glyph_metrics_t QWindowsFontEngine::boundingBox(const QGlyphLayout &glyphs)
+{
+ if (glyphs.numGlyphs == 0)
+ return glyph_metrics_t();
+
+ QFixed w = 0;
+ for (int i = 0; i < glyphs.numGlyphs; ++i)
+ w += glyphs.effectiveAdvance(i);
+
+ return glyph_metrics_t(0, -tm.tmAscent, w - lastRightBearing(glyphs), tm.tmHeight, w, 0);
+}
+
+bool QWindowsFontEngine::getOutlineMetrics(glyph_t glyph, const QTransform &t, glyph_metrics_t *metrics) const
+{
+ Q_ASSERT(metrics != 0);
+
+ HDC hdc = m_fontEngineData->hdc;
+
+ GLYPHMETRICS gm;
+ DWORD res = 0;
+ MAT2 mat;
+ mat.eM11.value = mat.eM22.value = 1;
+ mat.eM11.fract = mat.eM22.fract = 0;
+ mat.eM21.value = mat.eM12.value = 0;
+ mat.eM21.fract = mat.eM12.fract = 0;
+
+ if (t.type() > QTransform::TxTranslate) {
+ // We need to set the transform using the HDC's world
+ // matrix rather than using the MAT2 above, because the
+ // results provided when transforming via MAT2 does not
+ // match the glyphs that are drawn using a WorldTransform
+ XFORM xform;
+ xform.eM11 = t.m11();
+ xform.eM12 = t.m12();
+ xform.eM21 = t.m21();
+ xform.eM22 = t.m22();
+ xform.eDx = 0;
+ xform.eDy = 0;
+ SetGraphicsMode(hdc, GM_ADVANCED);
+ SetWorldTransform(hdc, &xform);
+ }
+
+ uint format = GGO_METRICS;
+ if (ttf)
+ format |= GGO_GLYPH_INDEX;
+ res = GetGlyphOutline(hdc, glyph, format, &gm, 0, 0, &mat);
+
+ if (t.type() > QTransform::TxTranslate) {
+ XFORM xform;
+ xform.eM11 = xform.eM22 = 1;
+ xform.eM12 = xform.eM21 = xform.eDx = xform.eDy = 0;
+ SetWorldTransform(hdc, &xform);
+ SetGraphicsMode(hdc, GM_COMPATIBLE);
+ }
+
+ if (res != GDI_ERROR) {
+ *metrics = glyph_metrics_t(gm.gmptGlyphOrigin.x, -gm.gmptGlyphOrigin.y,
+ (int)gm.gmBlackBoxX, (int)gm.gmBlackBoxY, gm.gmCellIncX, gm.gmCellIncY);
+ return true;
+ } else {
+ return false;
+ }
+}
+
+glyph_metrics_t QWindowsFontEngine::boundingBox(glyph_t glyph, const QTransform &t)
+{
+ HDC hdc = m_fontEngineData->hdc;
+ SelectObject(hdc, hfont);
+
+ glyph_metrics_t glyphMetrics;
+ bool success = getOutlineMetrics(glyph, t, &glyphMetrics);
+
+ if (!ttf && !success) {
+ // Bitmap fonts
+ wchar_t ch = glyph;
+ ABCFLOAT abc;
+ GetCharABCWidthsFloat(hdc, ch, ch, &abc);
+ int width = qRound(abc.abcfB);
+
+ return glyph_metrics_t(QFixed::fromReal(abc.abcfA), -tm.tmAscent, width, tm.tmHeight, width, 0).transformed(t);
+ }
+
+ return glyphMetrics;
+}
+
+QFixed QWindowsFontEngine::ascent() const
+{
+ return tm.tmAscent;
+}
+
+QFixed QWindowsFontEngine::descent() const
+{
+ // ### we subtract 1 to even out the historical +1 in QFontMetrics'
+ // ### height=asc+desc+1 equation. Fix in Qt5.
+ return tm.tmDescent - 1;
+}
+
+QFixed QWindowsFontEngine::leading() const
+{
+ return tm.tmExternalLeading;
+}
+
+
+QFixed QWindowsFontEngine::xHeight() const
+{
+ if(x_height >= 0)
+ return x_height;
+ return QFontEngine::xHeight();
+}
+
+QFixed QWindowsFontEngine::averageCharWidth() const
+{
+ return tm.tmAveCharWidth;
+}
+
+qreal QWindowsFontEngine::maxCharWidth() const
+{
+ return tm.tmMaxCharWidth;
+}
+
+enum { max_font_count = 256 };
+static const ushort char_table[] = {
+ 40,
+ 67,
+ 70,
+ 75,
+ 86,
+ 88,
+ 89,
+ 91,
+ 102,
+ 114,
+ 124,
+ 127,
+ 205,
+ 645,
+ 884,
+ 922,
+ 1070,
+ 12386,
+ 0
+};
+
+static const int char_table_entries = sizeof(char_table)/sizeof(ushort);
+
+#ifndef Q_CC_MINGW
+void QWindowsFontEngine::getGlyphBearings(glyph_t glyph, qreal *leftBearing, qreal *rightBearing)
+{
+ HDC hdc = m_fontEngineData->hdc;
+ SelectObject(hdc, hfont);
+
+ if (ttf)
+ {
+ ABC abcWidths;
+ GetCharABCWidthsI(hdc, glyph, 1, 0, &abcWidths);
+ if (leftBearing)
+ *leftBearing = abcWidths.abcA;
+ if (rightBearing)
+ *rightBearing = abcWidths.abcC;
+ } else {
+ QFontEngine::getGlyphBearings(glyph, leftBearing, rightBearing);
+ }
+}
+#endif // Q_CC_MINGW
+
+qreal QWindowsFontEngine::minLeftBearing() const
+{
+ if (lbearing == SHRT_MIN)
+ minRightBearing(); // calculates both
+
+ return lbearing;
+}
+
+qreal QWindowsFontEngine::minRightBearing() const
+{
+ if (rbearing == SHRT_MIN) {
+ int ml = 0;
+ int mr = 0;
+ HDC hdc = m_fontEngineData->hdc;
+ SelectObject(hdc, hfont);
+ if (ttf) {
+ ABC *abc = 0;
+ int n = tm.tmLastChar - tm.tmFirstChar;
+ if (n <= max_font_count) {
+ abc = new ABC[n+1];
+ GetCharABCWidths(hdc, tm.tmFirstChar, tm.tmLastChar, abc);
+ } else {
+ abc = new ABC[char_table_entries+1];
+ for(int i = 0; i < char_table_entries; i++)
+ GetCharABCWidths(hdc, char_table[i], char_table[i], abc + i);
+ n = char_table_entries;
+ }
+ ml = abc[0].abcA;
+ mr = abc[0].abcC;
+ for (int i = 1; i < n; i++) {
+ if (abc[i].abcA + abc[i].abcB + abc[i].abcC != 0) {
+ ml = qMin(ml,abc[i].abcA);
+ mr = qMin(mr,abc[i].abcC);
+ }
+ }
+ delete [] abc;
+ } else {
+ ABCFLOAT *abc = 0;
+ int n = tm.tmLastChar - tm.tmFirstChar+1;
+ if (n <= max_font_count) {
+ abc = new ABCFLOAT[n];
+ GetCharABCWidthsFloat(hdc, tm.tmFirstChar, tm.tmLastChar, abc);
+ } else {
+ abc = new ABCFLOAT[char_table_entries];
+ for(int i = 0; i < char_table_entries; i++)
+ GetCharABCWidthsFloat(hdc, char_table[i], char_table[i], abc+i);
+ n = char_table_entries;
+ }
+ float fml = abc[0].abcfA;
+ float fmr = abc[0].abcfC;
+ for (int i=1; i<n; i++) {
+ if (abc[i].abcfA + abc[i].abcfB + abc[i].abcfC != 0) {
+ fml = qMin(fml,abc[i].abcfA);
+ fmr = qMin(fmr,abc[i].abcfC);
+ }
+ }
+ ml = int(fml - 0.9999);
+ mr = int(fmr - 0.9999);
+ delete [] abc;
+ }
+ lbearing = ml;
+ rbearing = mr;
+ }
+
+ return rbearing;
+}
+
+
+const char *QWindowsFontEngine::name() const
+{
+ return 0;
+}
+
+bool QWindowsFontEngine::canRender(const QChar *string, int len)
+{
+ if (symbol) {
+ for (int i = 0; i < len; ++i) {
+ unsigned int uc = getChar(string, i, len);
+ if (getTrueTypeGlyphIndex(cmap, uc) == 0) {
+ if (uc < 0x100) {
+ if (getTrueTypeGlyphIndex(cmap, uc + 0xf000) == 0)
+ return false;
+ } else {
+ return false;
+ }
+ }
+ }
+ } else if (ttf) {
+ for (int i = 0; i < len; ++i) {
+ unsigned int uc = getChar(string, i, len);
+ if (getTrueTypeGlyphIndex(cmap, uc) == 0)
+ return false;
+ }
+ } else {
+ while(len--) {
+ if (tm.tmFirstChar > string->unicode() || tm.tmLastChar < string->unicode())
+ return false;
+ }
+ }
+ return true;
+}
+
+QFontEngine::Type QWindowsFontEngine::type() const
+{
+ return QFontEngine::Win;
+}
+
+static inline double qt_fixed_to_double(const FIXED &p) {
+ return ((p.value << 16) + p.fract) / 65536.0;
+}
+
+static inline QPointF qt_to_qpointf(const POINTFX &pt, qreal scale) {
+ return QPointF(qt_fixed_to_double(pt.x) * scale, -qt_fixed_to_double(pt.y) * scale);
+}
+
+#ifndef GGO_UNHINTED
+#define GGO_UNHINTED 0x0100
+#endif
+
+static bool addGlyphToPath(glyph_t glyph, const QFixedPoint &position, HDC hdc,
+ QPainterPath *path, bool ttf, glyph_metrics_t *metric = 0, qreal scale = 1)
+{
+ MAT2 mat;
+ mat.eM11.value = mat.eM22.value = 1;
+ mat.eM11.fract = mat.eM22.fract = 0;
+ mat.eM21.value = mat.eM12.value = 0;
+ mat.eM21.fract = mat.eM12.fract = 0;
+ uint glyphFormat = GGO_NATIVE;
+
+ if (ttf)
+ glyphFormat |= GGO_GLYPH_INDEX;
+
+ GLYPHMETRICS gMetric;
+ memset(&gMetric, 0, sizeof(GLYPHMETRICS));
+ int bufferSize = GDI_ERROR;
+ bufferSize = GetGlyphOutline(hdc, glyph, glyphFormat, &gMetric, 0, 0, &mat);
+ if ((DWORD)bufferSize == GDI_ERROR) {
+ return false;
+ }
+
+ void *dataBuffer = new char[bufferSize];
+ DWORD ret = GDI_ERROR;
+ ret = GetGlyphOutline(hdc, glyph, glyphFormat, &gMetric, bufferSize, dataBuffer, &mat);
+ if (ret == GDI_ERROR) {
+ delete [](char *)dataBuffer;
+ return false;
+ }
+
+ if(metric) {
+ // #### obey scale
+ *metric = glyph_metrics_t(gMetric.gmptGlyphOrigin.x, -gMetric.gmptGlyphOrigin.y,
+ (int)gMetric.gmBlackBoxX, (int)gMetric.gmBlackBoxY,
+ gMetric.gmCellIncX, gMetric.gmCellIncY);
+ }
+
+ int offset = 0;
+ int headerOffset = 0;
+ TTPOLYGONHEADER *ttph = 0;
+
+ QPointF oset = position.toPointF();
+ while (headerOffset < bufferSize) {
+ ttph = (TTPOLYGONHEADER*)((char *)dataBuffer + headerOffset);
+
+ QPointF lastPoint(qt_to_qpointf(ttph->pfxStart, scale));
+ path->moveTo(lastPoint + oset);
+ offset += sizeof(TTPOLYGONHEADER);
+ TTPOLYCURVE *curve;
+ while (offset<int(headerOffset + ttph->cb)) {
+ curve = (TTPOLYCURVE*)((char*)(dataBuffer) + offset);
+ switch (curve->wType) {
+ case TT_PRIM_LINE: {
+ for (int i=0; i<curve->cpfx; ++i) {
+ QPointF p = qt_to_qpointf(curve->apfx[i], scale) + oset;
+ path->lineTo(p);
+ }
+ break;
+ }
+ case TT_PRIM_QSPLINE: {
+ const QPainterPath::Element &elm = path->elementAt(path->elementCount()-1);
+ QPointF prev(elm.x, elm.y);
+ QPointF endPoint;
+ for (int i=0; i<curve->cpfx - 1; ++i) {
+ QPointF p1 = qt_to_qpointf(curve->apfx[i], scale) + oset;
+ QPointF p2 = qt_to_qpointf(curve->apfx[i+1], scale) + oset;
+ if (i < curve->cpfx - 2) {
+ endPoint = QPointF((p1.x() + p2.x()) / 2, (p1.y() + p2.y()) / 2);
+ } else {
+ endPoint = p2;
+ }
+
+ path->quadTo(p1, endPoint);
+ prev = endPoint;
+ }
+
+ break;
+ }
+ case TT_PRIM_CSPLINE: {
+ for (int i=0; i<curve->cpfx; ) {
+ QPointF p2 = qt_to_qpointf(curve->apfx[i++], scale) + oset;
+ QPointF p3 = qt_to_qpointf(curve->apfx[i++], scale) + oset;
+ QPointF p4 = qt_to_qpointf(curve->apfx[i++], scale) + oset;
+ path->cubicTo(p2, p3, p4);
+ }
+ break;
+ }
+ default:
+ qWarning("QFontEngineWin::addOutlineToPath, unhandled switch case");
+ }
+ offset += sizeof(TTPOLYCURVE) + (curve->cpfx-1) * sizeof(POINTFX);
+ }
+ path->closeSubpath();
+ headerOffset += ttph->cb;
+ }
+ delete [] (char*)dataBuffer;
+
+ return true;
+}
+
+void QWindowsFontEngine::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nglyphs,
+ QPainterPath *path, QTextItem::RenderFlags)
+{
+ LOGFONT lf = m_logfont;
+ // The sign must be negative here to make sure we match against character height instead of
+ // hinted cell height. This ensures that we get linear matching, and we need this for
+ // paths since we later on apply a scaling transform to the glyph outline to get the
+ // font at the correct pixel size.
+ lf.lfHeight = -unitsPerEm;
+ lf.lfWidth = 0;
+ HFONT hf = CreateFontIndirect(&lf);
+ HDC hdc = m_fontEngineData->hdc;
+ HGDIOBJ oldfont = SelectObject(hdc, hf);
+
+ for(int i = 0; i < nglyphs; ++i) {
+ if (!addGlyphToPath(glyphs[i], positions[i], hdc, path, ttf, /*metric*/0,
+ qreal(fontDef.pixelSize) / unitsPerEm)) {
+ // Some windows fonts, like "Modern", are vector stroke
+ // fonts, which are reported as TMPF_VECTOR but do not
+ // support GetGlyphOutline, and thus we set this bit so
+ // that addOutLineToPath can check it and return safely...
+ hasOutline = false;
+ break;
+ }
+ }
+ DeleteObject(SelectObject(hdc, oldfont));
+}
+
+void QWindowsFontEngine::addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs,
+ QPainterPath *path, QTextItem::RenderFlags flags)
+{
+ if(tm.tmPitchAndFamily & (TMPF_TRUETYPE | TMPF_VECTOR)) {
+ hasOutline = true;
+ QFontEngine::addOutlineToPath(x, y, glyphs, path, flags);
+ if (hasOutline) {
+ // has_outline is set to false if addGlyphToPath gets
+ // false from GetGlyphOutline, meaning its not an outline
+ // font.
+ return;
+ }
+ }
+ QFontEngine::addBitmapFontToPath(x, y, glyphs, path, flags);
+}
+
+QFontEngine::FaceId QWindowsFontEngine::faceId() const
+{
+ return _faceId;
+}
+
+QT_BEGIN_INCLUDE_NAMESPACE
+#include <qdebug.h>
+QT_END_INCLUDE_NAMESPACE
+
+int QWindowsFontEngine::synthesized() const
+{
+ if(synthesized_flags == -1) {
+ synthesized_flags = 0;
+ if(ttf) {
+ const DWORD HEAD = MAKE_TAG('h', 'e', 'a', 'd');
+ HDC hdc = m_fontEngineData->hdc;
+ SelectObject(hdc, hfont);
+ uchar data[4];
+ GetFontData(hdc, HEAD, 44, &data, 4);
+ USHORT macStyle = getUShort(data);
+ if (tm.tmItalic && !(macStyle & 2))
+ synthesized_flags = SynthesizedItalic;
+ if (fontDef.stretch != 100 && ttf)
+ synthesized_flags |= SynthesizedStretch;
+ if (tm.tmWeight >= 500 && !(macStyle & 1))
+ synthesized_flags |= SynthesizedBold;
+ //qDebug() << "font is" << _name <<
+ // "it=" << (macStyle & 2) << fontDef.style << "flags=" << synthesized_flags;
+ }
+ }
+ return synthesized_flags;
+}
+
+QFixed QWindowsFontEngine::emSquareSize() const
+{
+ return unitsPerEm;
+}
+
+QFontEngine::Properties QWindowsFontEngine::properties() const
+{
+ LOGFONT lf = m_logfont;
+ lf.lfHeight = unitsPerEm;
+ HFONT hf = CreateFontIndirect(&lf);
+ HDC hdc = m_fontEngineData->hdc;
+ HGDIOBJ oldfont = SelectObject(hdc, hf);
+ OUTLINETEXTMETRIC *otm = getOutlineTextMetric(hdc);
+ Properties p;
+ p.emSquare = unitsPerEm;
+ p.italicAngle = otm->otmItalicAngle;
+ p.postscriptName = QString::fromWCharArray((wchar_t *)((char *)otm + (quintptr)otm->otmpFamilyName)).toLatin1();
+ p.postscriptName += QString::fromWCharArray((wchar_t *)((char *)otm + (quintptr)otm->otmpStyleName)).toLatin1();
+ p.postscriptName = QFontEngine::convertToPostscriptFontFamilyName(p.postscriptName);
+ p.boundingBox = QRectF(otm->otmrcFontBox.left, -otm->otmrcFontBox.top,
+ otm->otmrcFontBox.right - otm->otmrcFontBox.left,
+ otm->otmrcFontBox.top - otm->otmrcFontBox.bottom);
+ p.ascent = otm->otmAscent;
+ p.descent = -otm->otmDescent;
+ p.leading = (int)otm->otmLineGap;
+ p.capHeight = 0;
+ p.lineWidth = otm->otmsUnderscoreSize;
+ free(otm);
+ DeleteObject(SelectObject(hdc, oldfont));
+ return p;
+}
+
+void QWindowsFontEngine::getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics)
+{
+ LOGFONT lf = m_logfont;
+ lf.lfHeight = unitsPerEm;
+ int flags = synthesized();
+ if(flags & SynthesizedItalic)
+ lf.lfItalic = false;
+ lf.lfWidth = 0;
+ HFONT hf = CreateFontIndirect(&lf);
+ HDC hdc = m_fontEngineData->hdc;
+ HGDIOBJ oldfont = SelectObject(hdc, hf);
+ QFixedPoint p;
+ p.x = 0;
+ p.y = 0;
+ addGlyphToPath(glyph, p, hdc, path, ttf, metrics);
+ DeleteObject(SelectObject(hdc, oldfont));
+}
+
+bool QWindowsFontEngine::getSfntTableData(uint tag, uchar *buffer, uint *length) const
+{
+ if (!ttf)
+ return false;
+ HDC hdc = m_fontEngineData->hdc;
+ SelectObject(hdc, hfont);
+ DWORD t = qbswap<quint32>(tag);
+ *length = GetFontData(hdc, t, 0, buffer, *length);
+ return *length != GDI_ERROR;
+}
+
+#if !defined(CLEARTYPE_QUALITY)
+# define CLEARTYPE_QUALITY 5
+#endif
+
+QWindowsNativeImage *QWindowsFontEngine::drawGDIGlyph(HFONT font, glyph_t glyph, int margin,
+ const QTransform &t,
+ QImage::Format mask_format)
+{
+ Q_UNUSED(mask_format)
+ glyph_metrics_t gm = boundingBox(glyph);
+
+// printf(" -> for glyph %4x\n", glyph);
+
+ int gx = gm.x.toInt();
+ int gy = gm.y.toInt();
+ int iw = gm.width.toInt();
+ int ih = gm.height.toInt();
+
+ if (iw <= 0 || iw <= 0)
+ return 0;
+
+ bool has_transformation = t.type() > QTransform::TxTranslate;
+
+ unsigned int options = ttf ? ETO_GLYPH_INDEX : 0;
+ XFORM xform;
+
+ if (has_transformation) {
+ xform.eM11 = t.m11();
+ xform.eM12 = t.m12();
+ xform.eM21 = t.m21();
+ xform.eM22 = t.m22();
+ xform.eDx = margin;
+ xform.eDy = margin;
+
+ HDC hdc = CreateCompatibleDC(QWindowsContext::instance()->displayContext());
+
+ SetGraphicsMode(hdc, GM_ADVANCED);
+ SetWorldTransform(hdc, &xform);
+ HGDIOBJ old_font = SelectObject(hdc, font);
+
+ int ggo_options = GGO_METRICS | (ttf ? GGO_GLYPH_INDEX : 0);
+ GLYPHMETRICS tgm;
+ MAT2 mat;
+ memset(&mat, 0, sizeof(mat));
+ mat.eM11.value = mat.eM22.value = 1;
+
+ if (GetGlyphOutline(hdc, glyph, ggo_options, &tgm, 0, 0, &mat) == GDI_ERROR) {
+ qWarning("QWinFontEngine: unable to query transformed glyph metrics...");
+ return 0;
+ }
+
+ iw = tgm.gmBlackBoxX;
+ ih = tgm.gmBlackBoxY;
+
+ xform.eDx -= tgm.gmptGlyphOrigin.x;
+ xform.eDy += tgm.gmptGlyphOrigin.y;
+
+ SetGraphicsMode(hdc, GM_COMPATIBLE);
+ SelectObject(hdc, old_font);
+ ReleaseDC(0, hdc);
+ }
+ QWindowsNativeImage *ni = new QWindowsNativeImage(iw + 2 * margin + 4,
+ ih + 2 * margin + 4,
+ QWindowsNativeImage::systemFormat());
+
+ /*If cleartype is enabled we use the standard system format even on Windows CE
+ and not the special textbuffer format we have to use if cleartype is disabled*/
+
+ ni->image().fill(0xffffffff);
+
+ HDC hdc = ni->hdc();
+
+ SelectObject(hdc, GetStockObject(NULL_BRUSH));
+ SelectObject(hdc, GetStockObject(BLACK_PEN));
+ SetTextColor(hdc, RGB(0,0,0));
+ SetBkMode(hdc, TRANSPARENT);
+ SetTextAlign(hdc, TA_BASELINE);
+
+ HGDIOBJ old_font = SelectObject(hdc, font);
+
+ if (has_transformation) {
+ SetGraphicsMode(hdc, GM_ADVANCED);
+ SetWorldTransform(hdc, &xform);
+ ExtTextOut(hdc, 0, 0, options, 0, (LPCWSTR) &glyph, 1, 0);
+ } else
+ {
+ ExtTextOut(hdc, -gx + margin, -gy + margin, options, 0, (LPCWSTR) &glyph, 1, 0);
+ }
+
+ SelectObject(hdc, old_font);
+ return ni;
+}
+
+QImage QWindowsFontEngine::alphaMapForGlyph(glyph_t glyph, const QTransform &xform)
+{
+ HFONT font = hfont;
+ if (m_fontEngineData->clearTypeEnabled) {
+ LOGFONT lf = m_logfont;
+ lf.lfQuality = ANTIALIASED_QUALITY;
+ font = CreateFontIndirect(&lf);
+ }
+ QImage::Format mask_format = QWindowsNativeImage::systemFormat();
+ mask_format = QImage::Format_RGB32;
+
+ QWindowsNativeImage *mask = drawGDIGlyph(font, glyph, 0, xform, mask_format);
+ if (mask == 0)
+ return QImage();
+
+ QImage indexed(mask->width(), mask->height(), QImage::Format_Indexed8);
+
+ // ### This part is kinda pointless, but we'll crash later if we don't because some
+ // code paths expects there to be colortables for index8-bit...
+ QVector<QRgb> colors(256);
+ for (int i=0; i<256; ++i)
+ colors[i] = qRgba(0, 0, 0, i);
+ indexed.setColorTable(colors);
+
+ // 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) {
+ uchar *dest = indexed.scanLine(y);
+ if (mask->image().format() == QImage::Format_RGB16) {
+ const qint16 *src = (qint16 *) ((const QImage &) mask->image()).scanLine(y);
+ for (int x=0; x<mask->width(); ++x)
+ dest[x] = 255 - qGray(src[x]);
+ } else {
+ const uint *src = (uint *) ((const QImage &) mask->image()).scanLine(y);
+ for (int x=0; x<mask->width(); ++x) {
+ if (QWindowsNativeImage::systemFormat() == QImage::Format_RGB16)
+ dest[x] = 255 - qGray(src[x]);
+ else
+ dest[x] = 255 - (m_fontEngineData->pow_gamma[qGray(src[x])] * 255. / 2047.);
+ }
+ }
+ }
+
+ // Cleanup...
+ delete mask;
+ if (m_fontEngineData->clearTypeEnabled) {
+ DeleteObject(font);
+ }
+
+ return indexed;
+}
+
+#define SPI_GETFONTSMOOTHINGCONTRAST 0x200C
+#define SPI_SETFONTSMOOTHINGCONTRAST 0x200D
+
+QImage QWindowsFontEngine::alphaRGBMapForGlyph(glyph_t glyph, QFixed, int margin, const QTransform &t)
+{
+ HFONT font = hfont;
+
+ int contrast;
+ SystemParametersInfo(SPI_GETFONTSMOOTHINGCONTRAST, 0, &contrast, 0);
+ SystemParametersInfo(SPI_SETFONTSMOOTHINGCONTRAST, 0, (void *) 1000, 0);
+
+ QWindowsNativeImage *mask = drawGDIGlyph(font, glyph, margin, t, QImage::Format_RGB32);
+ SystemParametersInfo(SPI_SETFONTSMOOTHINGCONTRAST, 0, (void *) contrast, 0);
+
+ if (mask == 0)
+ return QImage();
+
+ // Gracefully handle the odd case when the display is 16-bit
+ const QImage source = mask->image().depth() == 32
+ ? mask->image()
+ : mask->image().convertToFormat(QImage::Format_RGB32);
+
+ QImage rgbMask(mask->width(), mask->height(), QImage::Format_RGB32);
+ for (int y=0; y<mask->height(); ++y) {
+ uint *dest = (uint *) rgbMask.scanLine(y);
+ const uint *src = (uint *) source.scanLine(y);
+ for (int x=0; x<mask->width(); ++x) {
+ dest[x] = 0xffffffff - (0x00ffffff & src[x]);
+ }
+ }
+
+ delete mask;
+
+ return rgbMask;
+}
+
+QFontEngine *QWindowsFontEngine::cloneWithSize(qreal pixelSize) const
+{
+ QFontDef request = fontDef;
+ QString actualFontName = request.family;
+ if (!uniqueFamilyName.isEmpty())
+ request.family = uniqueFamilyName;
+ request.pixelSize = pixelSize;
+
+ QFontEngine *fontEngine =
+ QWindowsFontDatabase::createEngine(QUnicodeTables::Common, request, 0,
+ QWindowsContext::instance()->defaultDPI(),
+ false,
+ QStringList(), m_fontEngineData);
+ if (fontEngine)
+ fontEngine->fontDef.family = actualFontName;
+ return fontEngine;
+}
+
+void QWindowsFontEngine::initFontInfo(const QFontDef &request,
+ HDC fontHdc,
+ int dpi)
+{
+ fontDef = request; // most settings are equal
+ HDC dc = ((request.styleStrategy & QFont::PreferDevice) && fontHdc) ? fontHdc : m_fontEngineData->hdc;
+ SelectObject(dc, hfont);
+ wchar_t n[64];
+ GetTextFace(dc, 64, n);
+ fontDef.family = QString::fromWCharArray(n);
+ fontDef.fixedPitch = !(tm.tmPitchAndFamily & TMPF_FIXED_PITCH);
+ if (fontDef.pointSize < 0) {
+ fontDef.pointSize = fontDef.pixelSize * 72. / dpi;
+ } else if (fontDef.pixelSize == -1) {
+ fontDef.pixelSize = qRound(fontDef.pointSize * dpi / 72.);
+ }
+}
+
+/*!
+ \class QWindowsMultiFontEngine
+ \brief Standard Windows Multi font engine.
+ \ingroup qt-lighthouse-win
+
+ "Merges" several font engines that have gaps in the
+ supported writing systems.
+
+ Will probably be superseded by a common Free Type font engine in Qt 5.X.
+*/
+
+QWindowsMultiFontEngine::QWindowsMultiFontEngine(QFontEngine *first, const QStringList &fallbacks)
+ : QFontEngineMulti(fallbacks.size()+1),
+ fallbacks(fallbacks)
+{
+ if (QWindowsContext::verboseFonts)
+ qDebug() << __FUNCTION__ << engines.size() << first << first->fontDef.family << fallbacks;
+ engines[0] = first;
+ first->ref.ref();
+ fontDef = engines[0]->fontDef;
+ cache_cost = first->cache_cost;
+}
+
+QWindowsMultiFontEngine::~QWindowsMultiFontEngine()
+{
+ if (QWindowsContext::verboseFonts)
+ qDebug("%s", __FUNCTION__);
+}
+
+void QWindowsMultiFontEngine::loadEngine(int at)
+{
+ Q_ASSERT(at < engines.size());
+ Q_ASSERT(engines.at(at) == 0);
+
+ const QString fam = fallbacks.at(at-1);
+ QWindowsFontEngine *fe = static_cast<QWindowsFontEngine*>(engines.at(0));
+ LOGFONT lf = fe->logfont();
+ memcpy(lf.lfFaceName, fam.utf16(), sizeof(wchar_t) * qMin(fam.length() + 1, 32)); // 32 = Windows hard-coded
+ HFONT hfont = CreateFontIndirect(&lf);
+
+ bool stockFont = false;
+ if (hfont == 0) {
+ hfont = (HFONT)GetStockObject(ANSI_VAR_FONT);
+ stockFont = true;
+ }
+ engines[at] = new QWindowsFontEngine(fam, hfont, stockFont, lf, fe->fontEngineData());
+ engines[at]->ref.ref();
+ engines[at]->fontDef = fontDef;
+ if (QWindowsContext::verboseFonts)
+ qDebug("%s %d %s", __FUNCTION__, at, qPrintable(fam));
+
+
+ // TODO: increase cost in QFontCache for the font engine loaded here
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsfontengine.h b/src/plugins/platforms/windows/qwindowsfontengine.h
new file mode 100644
index 0000000000..bed5ecffbd
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsfontengine.h
@@ -0,0 +1,186 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSFONTENGINE_H
+#define QWINDOWSFONTENGINE_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+// Enable access to HB_Face in harfbuzz includes included by qfontengine_p.h.
+#define QT_BUILD_GUI_LIB
+#include <QtGui/private/qfontengine_p.h>
+#undef QT_BUILD_GUI_LIB
+
+#include <QtGui/QImage>
+#include <QtCore/QSharedPointer>
+
+#include "qtwindows_additional.h"
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsNativeImage;
+class QWindowsFontEngineData;
+
+class QWindowsFontEngine : public QFontEngine
+{
+ Q_DISABLE_COPY(QWindowsFontEngine)
+public:
+ QWindowsFontEngine(const QString &name, HFONT, bool, LOGFONT,
+ QSharedPointer<QWindowsFontEngineData> fontEngineData);
+
+ ~QWindowsFontEngine();
+ void initFontInfo(const QFontDef &request,
+ HDC fontHdc, int dpi);
+
+ virtual QFixed lineThickness() const;
+ virtual Properties properties() const;
+ virtual void getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics);
+ virtual FaceId faceId() const;
+ virtual bool getSfntTableData(uint tag, uchar *buffer, uint *length) const;
+ virtual int synthesized() const;
+ virtual QFixed emSquareSize() const;
+
+ virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const;
+ virtual void recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFlags) const;
+
+ virtual void addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs, QPainterPath *path, QTextItem::RenderFlags flags);
+ virtual void addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nglyphs,
+ QPainterPath *path, QTextItem::RenderFlags flags);
+
+ HGDIOBJ selectDesignFont() const;
+
+ virtual glyph_metrics_t boundingBox(const QGlyphLayout &glyphs);
+ virtual glyph_metrics_t boundingBox(glyph_t g) { return boundingBox(g, QTransform()); }
+ virtual glyph_metrics_t boundingBox(glyph_t g, const QTransform &t);
+
+
+ virtual QFixed ascent() const;
+ virtual QFixed descent() const;
+ virtual QFixed leading() const;
+ virtual QFixed xHeight() const;
+ virtual QFixed averageCharWidth() const;
+ virtual qreal maxCharWidth() const;
+ virtual qreal minLeftBearing() const;
+ virtual qreal minRightBearing() const;
+
+ virtual const char *name() const;
+
+ bool canRender(const QChar *string, int len);
+
+ Type type() const;
+
+ virtual QImage alphaMapForGlyph(glyph_t t) { return alphaMapForGlyph(t, QTransform()); }
+ virtual QImage alphaMapForGlyph(glyph_t, const QTransform &xform);
+ virtual QImage alphaRGBMapForGlyph(glyph_t t, QFixed subPixelPosition, int margin, const QTransform &xform);
+
+ virtual QFontEngine *cloneWithSize(qreal pixelSize) const;
+
+#ifndef Q_CC_MINGW
+ virtual void getGlyphBearings(glyph_t glyph, qreal *leftBearing = 0, qreal *rightBearing = 0);
+#endif
+
+ int getGlyphIndexes(const QChar *ch, int numChars, QGlyphLayout *glyphs, bool mirrored) const;
+ void getCMap();
+
+ bool getOutlineMetrics(glyph_t glyph, const QTransform &t, glyph_metrics_t *metrics) const;
+
+ static QFontEngine *createEngine(int script, const QFontDef &request,
+ HDC fontHdc, int dpi, bool rawMode,
+ const QStringList &family_list,
+ const QSharedPointer<QWindowsFontEngineData> &data);
+
+ QSharedPointer<QWindowsFontEngineData> fontEngineData() const { return m_fontEngineData; }
+ LOGFONT logfont() const { return m_logfont; }
+
+private:
+ QWindowsNativeImage *drawGDIGlyph(HFONT font, glyph_t, int margin, const QTransform &xform,
+ QImage::Format mask_format);
+
+ const QSharedPointer<QWindowsFontEngineData> m_fontEngineData;
+
+ const QString _name;
+ QString uniqueFamilyName;
+ const HFONT hfont;
+ const LOGFONT m_logfont;
+ uint stockFont : 1;
+ uint ttf : 1;
+ uint hasOutline : 1;
+ TEXTMETRIC tm;
+ int lw;
+ const unsigned char *cmap;
+ QByteArray cmapTable;
+ mutable qreal lbearing;
+ mutable qreal rbearing;
+ QFixed designToDevice;
+ int unitsPerEm;
+ QFixed x_height;
+ FaceId _faceId;
+
+ mutable int synthesized_flags;
+ mutable QFixed lineWidth;
+ mutable unsigned char *widthCache;
+ mutable uint widthCacheSize;
+ mutable QFixed *designAdvances;
+ mutable int designAdvancesSize;
+};
+
+class QWindowsMultiFontEngine : public QFontEngineMulti
+{
+public:
+ QWindowsMultiFontEngine(QFontEngine *first, const QStringList &fallbacks);
+ virtual ~QWindowsMultiFontEngine();
+ void loadEngine(int at);
+
+ QStringList fallbacks;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSFONTENGINE_H
diff --git a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp
new file mode 100644
index 0000000000..46f0b0c336
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp
@@ -0,0 +1,737 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT_NO_DIRECTWRITE
+
+#include "qwindowsfontenginedirectwrite.h"
+#include "qwindowsfontdatabase.h"
+#include "qwindowscontext.h"
+
+#include <QtCore/QSettings>
+#include <QtCore/QtEndian>
+
+#include <dwrite.h>
+#include <d2d1.h>
+
+QT_BEGIN_NAMESPACE
+
+// Convert from design units to logical pixels
+#define DESIGN_TO_LOGICAL(DESIGN_UNIT_VALUE) \
+ QFixed::fromReal((qreal(DESIGN_UNIT_VALUE) / qreal(m_unitsPerEm)) * fontDef.pixelSize)
+
+namespace {
+
+ class GeometrySink: public IDWriteGeometrySink
+ {
+ public:
+ GeometrySink(QPainterPath *path) : m_path(path), m_refCount(0)
+ {
+ Q_ASSERT(m_path != 0);
+ }
+
+ IFACEMETHOD_(void, AddBeziers)(const D2D1_BEZIER_SEGMENT *beziers, UINT bezierCount);
+ IFACEMETHOD_(void, AddLines)(const D2D1_POINT_2F *points, UINT pointCount);
+ IFACEMETHOD_(void, BeginFigure)(D2D1_POINT_2F startPoint, D2D1_FIGURE_BEGIN figureBegin);
+ IFACEMETHOD(Close)();
+ IFACEMETHOD_(void, EndFigure)(D2D1_FIGURE_END figureEnd);
+ IFACEMETHOD_(void, SetFillMode)(D2D1_FILL_MODE fillMode);
+ IFACEMETHOD_(void, SetSegmentFlags)(D2D1_PATH_SEGMENT vertexFlags);
+
+ IFACEMETHOD_(unsigned long, AddRef)();
+ IFACEMETHOD_(unsigned long, Release)();
+ IFACEMETHOD(QueryInterface)(IID const &riid, void **ppvObject);
+
+ private:
+ inline static QPointF fromD2D1_POINT_2F(const D2D1_POINT_2F &inp)
+ {
+ return QPointF(inp.x, inp.y);
+ }
+
+ unsigned long m_refCount;
+ QPointF m_startPoint;
+ QPainterPath *m_path;
+ };
+
+ void GeometrySink::AddBeziers(const D2D1_BEZIER_SEGMENT *beziers,
+ UINT bezierCount)
+ {
+ for (uint i=0; i<bezierCount; ++i) {
+ QPointF c1 = fromD2D1_POINT_2F(beziers[i].point1);
+ QPointF c2 = fromD2D1_POINT_2F(beziers[i].point2);
+ QPointF p2 = fromD2D1_POINT_2F(beziers[i].point3);
+
+ m_path->cubicTo(c1, c2, p2);
+ }
+ }
+
+ void GeometrySink::AddLines(const D2D1_POINT_2F *points, UINT pointsCount)
+ {
+ for (uint i=0; i<pointsCount; ++i)
+ m_path->lineTo(fromD2D1_POINT_2F(points[i]));
+ }
+
+ void GeometrySink::BeginFigure(D2D1_POINT_2F startPoint,
+ D2D1_FIGURE_BEGIN /*figureBegin*/)
+ {
+ m_startPoint = fromD2D1_POINT_2F(startPoint);
+ m_path->moveTo(m_startPoint);
+ }
+
+ IFACEMETHODIMP GeometrySink::Close()
+ {
+ return E_NOTIMPL;
+ }
+
+ void GeometrySink::EndFigure(D2D1_FIGURE_END figureEnd)
+ {
+ if (figureEnd == D2D1_FIGURE_END_CLOSED)
+ m_path->closeSubpath();
+ }
+
+ void GeometrySink::SetFillMode(D2D1_FILL_MODE fillMode)
+ {
+ m_path->setFillRule(fillMode == D2D1_FILL_MODE_ALTERNATE
+ ? Qt::OddEvenFill
+ : Qt::WindingFill);
+ }
+
+ void GeometrySink::SetSegmentFlags(D2D1_PATH_SEGMENT /*vertexFlags*/)
+ {
+ /* Not implemented */
+ }
+
+ IFACEMETHODIMP_(unsigned long) GeometrySink::AddRef()
+ {
+ return InterlockedIncrement(&m_refCount);
+ }
+
+ IFACEMETHODIMP_(unsigned long) GeometrySink::Release()
+ {
+ unsigned long newCount = InterlockedDecrement(&m_refCount);
+ if (newCount == 0)
+ {
+ delete this;
+ return 0;
+ }
+
+ return newCount;
+ }
+
+ IFACEMETHODIMP GeometrySink::QueryInterface(IID const &riid, void **ppvObject)
+ {
+ if (__uuidof(IDWriteGeometrySink) == riid) {
+ *ppvObject = this;
+ } else if (__uuidof(IUnknown) == riid) {
+ *ppvObject = this;
+ } else {
+ *ppvObject = NULL;
+ return E_FAIL;
+ }
+
+ AddRef();
+ return S_OK;
+ }
+
+}
+
+/*!
+ \class QWindowsFontEngineDirectWrite
+ \brief Windows font engine using Direct Write.
+ \ingroup qt-lighthouse-win
+
+ Font engine for subpixel positioned text on Windows Vista
+ (with platform update) and Windows 7. If selected during
+ configuration, the engine will be selected only when the hinting
+ preference of a font is set to None or Vertical hinting. The font
+ database uses most of the same logic but creates a direct write
+ font based on the LOGFONT rather than a GDI handle.
+
+ The engine is currently regarded as experimental, meaning that code
+ using it should do substantial testing to make sure it covers their
+ use cases.
+
+ Will probably be superseded by a common Free Type font engine in Qt 5.X.
+*/
+
+QWindowsFontEngineDirectWrite::QWindowsFontEngineDirectWrite(IDWriteFontFace *directWriteFontFace,
+ qreal pixelSize,
+ const QSharedPointer<QWindowsFontEngineData> &d)
+
+ : m_fontEngineData(d)
+ , m_directWriteFontFace(directWriteFontFace)
+ , m_directWriteBitmapRenderTarget(0)
+ , m_lineThickness(-1)
+ , m_unitsPerEm(-1)
+ , m_ascent(-1)
+ , m_descent(-1)
+ , m_xHeight(-1)
+ , m_lineGap(-1)
+{
+ if (QWindowsContext::verboseFonts)
+ qDebug("%s %g", __FUNCTION__, pixelSize);
+
+ d->directWriteFactory->AddRef();
+ m_directWriteFontFace->AddRef();
+
+ fontDef.pixelSize = pixelSize;
+ collectMetrics();
+}
+
+QWindowsFontEngineDirectWrite::~QWindowsFontEngineDirectWrite()
+{
+ if (QWindowsContext::verboseFonts)
+ qDebug("%s", __FUNCTION__);
+
+ m_fontEngineData->directWriteFactory->Release();
+ m_directWriteFontFace->Release();
+
+ if (m_directWriteBitmapRenderTarget != 0)
+ m_directWriteBitmapRenderTarget->Release();
+}
+
+void QWindowsFontEngineDirectWrite::collectMetrics()
+{
+ if (m_directWriteFontFace != 0) {
+ DWRITE_FONT_METRICS metrics;
+
+ m_directWriteFontFace->GetMetrics(&metrics);
+ m_unitsPerEm = metrics.designUnitsPerEm;
+
+ m_lineThickness = DESIGN_TO_LOGICAL(metrics.underlineThickness);
+ m_ascent = DESIGN_TO_LOGICAL(metrics.ascent);
+ m_descent = DESIGN_TO_LOGICAL(metrics.descent);
+ m_xHeight = DESIGN_TO_LOGICAL(metrics.xHeight);
+ m_lineGap = DESIGN_TO_LOGICAL(metrics.lineGap);
+ }
+}
+
+QFixed QWindowsFontEngineDirectWrite::lineThickness() const
+{
+ if (m_lineThickness > 0)
+ return m_lineThickness;
+ else
+ return QFontEngine::lineThickness();
+}
+
+bool QWindowsFontEngineDirectWrite::getSfntTableData(uint tag, uchar *buffer, uint *length) const
+{
+ if (m_directWriteFontFace) {
+ DWORD t = qbswap<quint32>(tag);
+
+ const void *tableData = 0;
+ void *tableContext = 0;
+ UINT32 tableSize;
+ BOOL exists;
+ HRESULT hr = m_directWriteFontFace->TryGetFontTable(
+ t, &tableData, &tableSize, &tableContext, &exists
+ );
+
+ if (SUCCEEDED(hr)) {
+ if (!exists)
+ return false;
+
+ if (buffer == 0) {
+ *length = tableSize;
+ return true;
+ } else if (*length < tableSize) {
+ return false;
+ }
+
+ qMemCopy(buffer, tableData, tableSize);
+ m_directWriteFontFace->ReleaseFontTable(tableContext);
+
+ return true;
+ } else {
+ qErrnoWarning("%s: TryGetFontTable failed", __FUNCTION__);
+ }
+ }
+
+ return false;
+}
+
+QFixed QWindowsFontEngineDirectWrite::emSquareSize() const
+{
+ if (m_unitsPerEm > 0)
+ return m_unitsPerEm;
+ else
+ return QFontEngine::emSquareSize();
+}
+
+inline unsigned int getChar(const QChar *str, int &i, const int len)
+{
+ unsigned int uc = str[i].unicode();
+ if (uc >= 0xd800 && uc < 0xdc00 && i < len-1) {
+ uint low = str[i+1].unicode();
+ if (low >= 0xdc00 && low < 0xe000) {
+ uc = (uc - 0xd800)*0x400 + (low - 0xdc00) + 0x10000;
+ ++i;
+ }
+ }
+ return uc;
+}
+
+bool QWindowsFontEngineDirectWrite::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs,
+ int *nglyphs, QTextEngine::ShaperFlags flags) const
+{
+ if (m_directWriteFontFace != 0) {
+ QVarLengthArray<UINT32> codePoints(len);
+ for (int i=0; i<len; ++i) {
+ codePoints[i] = getChar(str, i, len);
+ if (flags & QTextEngine::RightToLeft)
+ codePoints[i] = QChar::mirroredChar(codePoints[i]);
+ }
+
+ QVarLengthArray<UINT16> glyphIndices(len);
+ HRESULT hr = m_directWriteFontFace->GetGlyphIndicesW(codePoints.data(),
+ len,
+ glyphIndices.data());
+
+ if (SUCCEEDED(hr)) {
+ for (int i=0; i<len; ++i)
+ glyphs->glyphs[i] = glyphIndices[i];
+
+ *nglyphs = len;
+
+ if (!(flags & QTextEngine::GlyphIndicesOnly))
+ recalcAdvances(glyphs, 0);
+
+ return true;
+ } else {
+ qErrnoWarning("%s: GetGlyphIndicesW failed", __FUNCTION__);
+ }
+ }
+
+ return false;
+}
+
+void QWindowsFontEngineDirectWrite::recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFlags) const
+{
+ if (m_directWriteFontFace == 0)
+ return;
+
+ QVarLengthArray<UINT16> glyphIndices(glyphs->numGlyphs);
+
+ // ### Caching?
+ for(int i=0; i<glyphs->numGlyphs; i++)
+ glyphIndices[i] = UINT16(glyphs->glyphs[i]);
+
+ QVarLengthArray<DWRITE_GLYPH_METRICS> glyphMetrics(glyphIndices.size());
+ HRESULT hr = m_directWriteFontFace->GetDesignGlyphMetrics(glyphIndices.data(),
+ glyphIndices.size(),
+ glyphMetrics.data());
+ if (SUCCEEDED(hr)) {
+ for (int i=0; i<glyphs->numGlyphs; ++i) {
+ glyphs->advances_x[i] = DESIGN_TO_LOGICAL(glyphMetrics[i].advanceWidth);
+ if (fontDef.styleStrategy & QFont::ForceIntegerMetrics)
+ glyphs->advances_x[i] = glyphs->advances_x[i].round();
+ glyphs->advances_y[i] = 0;
+ }
+ } else {
+ qErrnoWarning("%s: GetDesignGlyphMetrics failed", __FUNCTION__);
+ }
+}
+
+void QWindowsFontEngineDirectWrite::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nglyphs,
+ QPainterPath *path, QTextItem::RenderFlags flags)
+{
+ if (m_directWriteFontFace == 0)
+ return;
+
+ QVarLengthArray<UINT16> glyphIndices(nglyphs);
+ QVarLengthArray<DWRITE_GLYPH_OFFSET> glyphOffsets(nglyphs);
+ QVarLengthArray<FLOAT> glyphAdvances(nglyphs);
+
+ for (int i=0; i<nglyphs; ++i) {
+ glyphIndices[i] = glyphs[i];
+ glyphOffsets[i].advanceOffset = positions[i].x.toReal();
+ glyphOffsets[i].ascenderOffset = -positions[i].y.toReal();
+ glyphAdvances[i] = 0.0;
+ }
+
+ GeometrySink geometrySink(path);
+ HRESULT hr = m_directWriteFontFace->GetGlyphRunOutline(
+ fontDef.pixelSize,
+ glyphIndices.data(),
+ glyphAdvances.data(),
+ glyphOffsets.data(),
+ nglyphs,
+ false,
+ flags & QTextItem::RightToLeft,
+ &geometrySink
+ );
+
+ if (FAILED(hr))
+ qErrnoWarning("%s: GetGlyphRunOutline failed", __FUNCTION__);
+}
+
+glyph_metrics_t QWindowsFontEngineDirectWrite::boundingBox(const QGlyphLayout &glyphs)
+{
+ if (glyphs.numGlyphs == 0)
+ return glyph_metrics_t();
+
+ bool round = fontDef.styleStrategy & QFont::ForceIntegerMetrics;
+
+ QFixed w = 0;
+ for (int i = 0; i < glyphs.numGlyphs; ++i) {
+ w += round ? glyphs.effectiveAdvance(i).round() : glyphs.effectiveAdvance(i);
+
+ }
+
+ return glyph_metrics_t(0, -m_ascent, w - lastRightBearing(glyphs), m_ascent + m_descent, w, 0);
+}
+
+glyph_metrics_t QWindowsFontEngineDirectWrite::boundingBox(glyph_t g)
+{
+ if (m_directWriteFontFace == 0)
+ return glyph_metrics_t();
+
+ UINT16 glyphIndex = g;
+
+ DWRITE_GLYPH_METRICS glyphMetrics;
+ HRESULT hr = m_directWriteFontFace->GetDesignGlyphMetrics(&glyphIndex, 1, &glyphMetrics);
+ if (SUCCEEDED(hr)) {
+ QFixed advanceWidth = DESIGN_TO_LOGICAL(glyphMetrics.advanceWidth);
+ QFixed leftSideBearing = DESIGN_TO_LOGICAL(glyphMetrics.leftSideBearing);
+ QFixed rightSideBearing = DESIGN_TO_LOGICAL(glyphMetrics.rightSideBearing);
+ QFixed advanceHeight = DESIGN_TO_LOGICAL(glyphMetrics.advanceHeight);
+ QFixed verticalOriginY = DESIGN_TO_LOGICAL(glyphMetrics.verticalOriginY);
+
+ if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) {
+ advanceWidth = advanceWidth.round();
+ advanceHeight = advanceHeight.round();
+ }
+
+ QFixed width = advanceWidth - leftSideBearing - rightSideBearing;
+
+ return glyph_metrics_t(-leftSideBearing, -verticalOriginY,
+ width, m_ascent + m_descent,
+ advanceWidth, advanceHeight);
+ } else {
+ qErrnoWarning("%s: GetDesignGlyphMetrics failed", __FUNCTION__);
+ }
+
+ return glyph_metrics_t();
+}
+
+QFixed QWindowsFontEngineDirectWrite::ascent() const
+{
+ return fontDef.styleStrategy & QFont::ForceIntegerMetrics
+ ? m_ascent.round()
+ : m_ascent;
+}
+
+QFixed QWindowsFontEngineDirectWrite::descent() const
+{
+ return fontDef.styleStrategy & QFont::ForceIntegerMetrics
+ ? (m_descent - 1).round()
+ : (m_descent - 1);
+}
+
+QFixed QWindowsFontEngineDirectWrite::leading() const
+{
+ return fontDef.styleStrategy & QFont::ForceIntegerMetrics
+ ? m_lineGap.round()
+ : m_lineGap;
+}
+
+QFixed QWindowsFontEngineDirectWrite::xHeight() const
+{
+ return fontDef.styleStrategy & QFont::ForceIntegerMetrics
+ ? m_xHeight.round()
+ : m_xHeight;
+}
+
+qreal QWindowsFontEngineDirectWrite::maxCharWidth() const
+{
+ // ###
+ return 0;
+}
+
+QImage QWindowsFontEngineDirectWrite::alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition)
+{
+ QImage im = imageForGlyph(glyph, subPixelPosition, 0, QTransform());
+
+ QImage indexed(im.width(), im.height(), QImage::Format_Indexed8);
+ QVector<QRgb> colors(256);
+ for (int i=0; i<256; ++i)
+ colors[i] = qRgba(0, 0, 0, i);
+ indexed.setColorTable(colors);
+
+ for (int y=0; y<im.height(); ++y) {
+ uint *src = (uint*) im.scanLine(y);
+ uchar *dst = indexed.scanLine(y);
+ for (int x=0; x<im.width(); ++x) {
+ *dst = 255 - (m_fontEngineData->pow_gamma[qGray(0xffffffff - *src)] * 255. / 2047.);
+ ++dst;
+ ++src;
+ }
+ }
+
+ return indexed;
+}
+
+bool QWindowsFontEngineDirectWrite::supportsSubPixelPositions() const
+{
+ return true;
+}
+
+QImage QWindowsFontEngineDirectWrite::imageForGlyph(glyph_t t,
+ QFixed subPixelPosition,
+ int margin,
+ const QTransform &xform)
+{
+ glyph_metrics_t metrics = QFontEngine::boundingBox(t, xform);
+ int width = (metrics.width + margin * 2 + 4).ceil().toInt() ;
+ int height = (metrics.height + margin * 2 + 4).ceil().toInt();
+
+ UINT16 glyphIndex = t;
+ FLOAT glyphAdvance = metrics.xoff.toReal();
+
+ DWRITE_GLYPH_OFFSET glyphOffset;
+ glyphOffset.advanceOffset = 0;
+ glyphOffset.ascenderOffset = 0;
+
+ DWRITE_GLYPH_RUN glyphRun;
+ glyphRun.fontFace = m_directWriteFontFace;
+ glyphRun.fontEmSize = fontDef.pixelSize;
+ glyphRun.glyphCount = 1;
+ glyphRun.glyphIndices = &glyphIndex;
+ glyphRun.glyphAdvances = &glyphAdvance;
+ glyphRun.isSideways = false;
+ glyphRun.bidiLevel = 0;
+ glyphRun.glyphOffsets = &glyphOffset;
+
+ QFixed x = margin - metrics.x.round() + subPixelPosition;
+ QFixed y = margin - metrics.y.floor();
+
+ DWRITE_MATRIX transform;
+ transform.dx = x.toReal();
+ transform.dy = y.toReal();
+ transform.m11 = xform.m11();
+ transform.m12 = xform.m12();
+ transform.m21 = xform.m21();
+ transform.m22 = xform.m22();
+
+ IDWriteGlyphRunAnalysis *glyphAnalysis = NULL;
+ HRESULT hr = m_fontEngineData->directWriteFactory->CreateGlyphRunAnalysis(
+ &glyphRun,
+ 1.0f,
+ &transform,
+ DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC,
+ DWRITE_MEASURING_MODE_NATURAL,
+ 0.0, 0.0,
+ &glyphAnalysis
+ );
+
+ if (SUCCEEDED(hr)) {
+ RECT rect;
+ rect.left = 0;
+ rect.top = 0;
+ rect.right = width;
+ rect.bottom = height;
+
+ int size = width * height * 3;
+ BYTE *alphaValues = new BYTE[size];
+ qMemSet(alphaValues, size, 0);
+
+ hr = glyphAnalysis->CreateAlphaTexture(DWRITE_TEXTURE_CLEARTYPE_3x1,
+ &rect,
+ alphaValues,
+ size);
+
+ if (SUCCEEDED(hr)) {
+ QImage img(width, height, QImage::Format_RGB32);
+ img.fill(0xffffffff);
+
+ for (int y=0; y<height; ++y) {
+ uint *dest = reinterpret_cast<uint *>(img.scanLine(y));
+ BYTE *src = alphaValues + width * 3 * y;
+
+ for (int x=0; x<width; ++x) {
+ dest[x] = *(src) << 16
+ | *(src + 1) << 8
+ | *(src + 2);
+
+ src += 3;
+ }
+ }
+
+ delete[] alphaValues;
+ glyphAnalysis->Release();
+
+ return img;
+ } else {
+ delete[] alphaValues;
+ glyphAnalysis->Release();
+
+ qErrnoWarning("%s: CreateAlphaTexture failed", __FUNCTION__);
+ }
+
+ } else {
+ qErrnoWarning("%s: CreateGlyphRunAnalysis failed", __FUNCTION__);
+ }
+
+ return QImage();
+}
+
+QImage QWindowsFontEngineDirectWrite::alphaRGBMapForGlyph(glyph_t t,
+ QFixed subPixelPosition,
+ int margin,
+ const QTransform &xform)
+{
+ QImage mask = imageForGlyph(t, subPixelPosition, margin, xform);
+ return mask.depth() == 32
+ ? mask
+ : mask.convertToFormat(QImage::Format_RGB32);
+}
+
+const char *QWindowsFontEngineDirectWrite::name() const
+{
+ return 0;
+}
+
+bool QWindowsFontEngineDirectWrite::canRender(const QChar *string, int len)
+{
+ QVarLengthArray<UINT32> codePoints(len);
+ int actualLength = 0;
+ for (int i=0; i<len; ++i, actualLength++)
+ codePoints[actualLength] = getChar(string, i, len);
+
+ QVarLengthArray<UINT16> glyphIndices(actualLength);
+ HRESULT hr = m_directWriteFontFace->GetGlyphIndices(codePoints.data(), actualLength,
+ glyphIndices.data());
+ if (FAILED(hr)) {
+ qErrnoWarning("%s: GetGlyphIndices failed", __FUNCTION__);
+ return false;
+ } else {
+ for (int i=0; i<glyphIndices.size(); ++i) {
+ if (glyphIndices.at(i) == 0)
+ return false;
+ }
+
+ return true;
+ }
+}
+
+QFontEngine::Type QWindowsFontEngineDirectWrite::type() const
+{
+ return QFontEngine::DirectWrite;
+}
+
+QFontEngine *QWindowsFontEngineDirectWrite::cloneWithSize(qreal pixelSize) const
+{
+ QFontEngine *fontEngine = new QWindowsFontEngineDirectWrite(m_directWriteFontFace,
+ pixelSize, m_fontEngineData);
+
+ fontEngine->fontDef = fontDef;
+ fontEngine->fontDef.pixelSize = pixelSize;
+
+ return fontEngine;
+}
+
+void QWindowsFontEngineDirectWrite::initFontInfo(const QFontDef &request,
+ int dpi, IDWriteFont *font)
+{
+ fontDef = request;
+
+ IDWriteFontFamily *fontFamily = NULL;
+ HRESULT hr = font->GetFontFamily(&fontFamily);
+
+ IDWriteLocalizedStrings *familyNames = NULL;
+ if (SUCCEEDED(hr))
+ hr = fontFamily->GetFamilyNames(&familyNames);
+
+ UINT32 index = 0;
+ BOOL exists = false;
+
+ wchar_t localeName[LOCALE_NAME_MAX_LENGTH];
+
+ if (SUCCEEDED(hr)) {
+ int defaultLocaleSuccess = GetUserDefaultLocaleName(localeName, LOCALE_NAME_MAX_LENGTH);
+
+ if (defaultLocaleSuccess)
+ hr = familyNames->FindLocaleName(localeName, &index, &exists);
+
+ if (SUCCEEDED(hr) && !exists)
+ hr = familyNames->FindLocaleName(L"en-us", &index, &exists);
+ }
+
+ if (!exists)
+ index = 0;
+
+ UINT32 length = 0;
+ if (SUCCEEDED(hr))
+ hr = familyNames->GetStringLength(index, &length);
+
+ wchar_t *name = new (std::nothrow) wchar_t[length+1];
+ if (name == NULL)
+ hr = E_OUTOFMEMORY;
+
+ // Get the family name.
+ if (SUCCEEDED(hr))
+ hr = familyNames->GetString(index, name, length + 1);
+
+ if (SUCCEEDED(hr))
+ fontDef.family = QString::fromWCharArray(name);
+
+ delete[] name;
+ if (familyNames != NULL)
+ familyNames->Release();
+
+ if (FAILED(hr))
+ qErrnoWarning(hr, "initFontInfo: Failed to get family name");
+
+ if (fontDef.pointSize < 0)
+ fontDef.pointSize = fontDef.pixelSize * 72. / dpi;
+ else if (fontDef.pixelSize == -1)
+ fontDef.pixelSize = qRound(fontDef.pointSize * dpi / 72.);
+}
+
+QString QWindowsFontEngineDirectWrite::fontNameSubstitute(const QString &familyName)
+{
+ static const char keyC[] = "HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion\\"
+ "FontSubstitutes";
+ return QSettings(QLatin1String(keyC), QSettings::NativeFormat).value(familyName, familyName).toString();
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_DIRECTWRITE
diff --git a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h
new file mode 100644
index 0000000000..1333720481
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h
@@ -0,0 +1,133 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSFONTENGINEDIRECTWRITE_H
+#define QWINDOWSFONTENGINEDIRECTWRITE_H
+
+#ifndef QT_NO_DIRECTWRITE
+
+// Enable access to HB_Face in harfbuzz includes included by qfontengine_p.h.
+#define QT_BUILD_GUI_LIB
+#include <QtGui/private/qfontengine_p.h>
+#undef QT_BUILD_GUI_LIB
+
+#include <QtCore/QSharedPointer>
+
+class QWindowsFontEngineData;
+
+struct IDWriteFont ;
+struct IDWriteFontFace ;
+struct IDWriteFactory ;
+struct IDWriteBitmapRenderTarget ;
+struct IDWriteGdiInterop ;
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsFontEngineDirectWrite : public QFontEngine
+{
+ Q_OBJECT
+public:
+ explicit QWindowsFontEngineDirectWrite(IDWriteFontFace *directWriteFontFace,
+ qreal pixelSize,
+ const QSharedPointer<QWindowsFontEngineData> &d);
+ ~QWindowsFontEngineDirectWrite();
+
+ void initFontInfo(const QFontDef &request, int dpi, IDWriteFont *font);
+
+ QFixed lineThickness() const;
+ bool getSfntTableData(uint tag, uchar *buffer, uint *length) const;
+ QFixed emSquareSize() const;
+
+ bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const;
+ void recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFlags) const;
+
+ void addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nglyphs,
+ QPainterPath *path, QTextItem::RenderFlags flags);
+
+ glyph_metrics_t boundingBox(const QGlyphLayout &glyphs);
+ glyph_metrics_t boundingBox(glyph_t g);
+
+ QFixed ascent() const;
+ QFixed descent() const;
+ QFixed leading() const;
+ QFixed xHeight() const;
+ qreal maxCharWidth() const;
+
+ const char *name() const;
+
+ bool supportsSubPixelPositions() const;
+
+ QImage alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition);
+ QImage alphaRGBMapForGlyph(glyph_t t, QFixed subPixelPosition, int margin,
+ const QTransform &xform);
+
+ QFontEngine *cloneWithSize(qreal pixelSize) const;
+
+ bool canRender(const QChar *string, int len);
+ Type type() const;
+
+ static QString fontNameSubstitute(const QString &familyName);
+
+private:
+ friend class QRawFontPrivate;
+
+ QImage imageForGlyph(glyph_t t, QFixed subPixelPosition, int margin, const QTransform &xform);
+ void collectMetrics();
+
+ const QSharedPointer<QWindowsFontEngineData> m_fontEngineData;
+
+ IDWriteFontFace *m_directWriteFontFace;
+ IDWriteBitmapRenderTarget *m_directWriteBitmapRenderTarget;
+
+ QFixed m_lineThickness;
+ int m_unitsPerEm;
+ QFixed m_ascent;
+ QFixed m_descent;
+ QFixed m_xHeight;
+ QFixed m_lineGap;
+ FaceId m_faceId;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_DIRECTWRITE
+
+#endif // QWINDOWSFONTENGINEDIRECTWRITE_H
diff --git a/src/plugins/platforms/windows/qwindowsglcontext.cpp b/src/plugins/platforms/windows/qwindowsglcontext.cpp
new file mode 100644
index 0000000000..4abccfb416
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsglcontext.cpp
@@ -0,0 +1,971 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsglcontext.h"
+#include "qwindowscontext.h"
+#include "qwindowswindow.h"
+
+#include <QtCore/QDebug>
+#include <QtCore/QSysInfo>
+
+#include <WinGDI.h>
+#if defined(Q_CC_MINGW)
+# include <GL/Gl.h>
+#else
+# include <Gl.h>
+#endif
+
+// #define DEBUG_GL
+
+// ARB extension API
+#ifndef WGL_ARB_multisample
+#define WGL_SAMPLE_BUFFERS_ARB 0x2041
+#define WGL_SAMPLES_ARB 0x2042
+#endif
+
+#ifndef WGL_ARB_pixel_format
+#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
+#define WGL_DRAW_TO_WINDOW_ARB 0x2001
+#define WGL_DRAW_TO_BITMAP_ARB 0x2002
+#define WGL_ACCELERATION_ARB 0x2003
+#define WGL_NEED_PALETTE_ARB 0x2004
+#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005
+#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006
+#define WGL_SWAP_METHOD_ARB 0x2007
+#define WGL_NUMBER_OVERLAYS_ARB 0x2008
+#define WGL_NUMBER_UNDERLAYS_ARB 0x2009
+#define WGL_TRANSPARENT_ARB 0x200A
+#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037
+#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038
+#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039
+#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A
+#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B
+#define WGL_SHARE_DEPTH_ARB 0x200C
+#define WGL_SHARE_STENCIL_ARB 0x200D
+#define WGL_SHARE_ACCUM_ARB 0x200E
+#define WGL_SUPPORT_GDI_ARB 0x200F
+#define WGL_SUPPORT_OPENGL_ARB 0x2010
+#define WGL_DOUBLE_BUFFER_ARB 0x2011
+#define WGL_STEREO_ARB 0x2012
+#define WGL_PIXEL_TYPE_ARB 0x2013
+#define WGL_COLOR_BITS_ARB 0x2014
+#define WGL_RED_BITS_ARB 0x2015
+#define WGL_RED_SHIFT_ARB 0x2016
+#define WGL_GREEN_BITS_ARB 0x2017
+#define WGL_GREEN_SHIFT_ARB 0x2018
+#define WGL_BLUE_BITS_ARB 0x2019
+#define WGL_BLUE_SHIFT_ARB 0x201A
+#define WGL_ALPHA_BITS_ARB 0x201B
+#define WGL_ALPHA_SHIFT_ARB 0x201C
+#define WGL_ACCUM_BITS_ARB 0x201D
+#define WGL_ACCUM_RED_BITS_ARB 0x201E
+#define WGL_ACCUM_GREEN_BITS_ARB 0x201F
+#define WGL_ACCUM_BLUE_BITS_ARB 0x2020
+#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
+#define WGL_DEPTH_BITS_ARB 0x2022
+#define WGL_STENCIL_BITS_ARB 0x2023
+#define WGL_AUX_BUFFERS_ARB 0x2024
+#define WGL_NO_ACCELERATION_ARB 0x2025
+#define WGL_GENERIC_ACCELERATION_ARB 0x2026
+#define WGL_FULL_ACCELERATION_ARB 0x2027
+#define WGL_SWAP_EXCHANGE_ARB 0x2028
+#define WGL_SWAP_COPY_ARB 0x2029
+#define WGL_SWAP_UNDEFINED_ARB 0x202A
+#define WGL_TYPE_RGBA_ARB 0x202B
+#define WGL_TYPE_COLORINDEX_ARB 0x202C
+#endif
+
+#ifndef WGL_ARB_create_context
+#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
+#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
+#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093
+#define WGL_CONTEXT_FLAGS_ARB 0x2094
+#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
+#define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001
+#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002
+#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x0001
+#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x0002
+// Error codes returned by GetLastError().
+#define ERROR_INVALID_VERSION_ARB 0x2095
+#define ERROR_INVALID_PROFILE_ARB 0x2096
+#endif
+
+#ifndef GL_VERSION_3_2
+#define GL_CONTEXT_PROFILE_MASK 0x9126
+#define GL_MAJOR_VERSION 0x821B
+#define GL_MINOR_VERSION 0x821C
+#define GL_NUM_EXTENSIONS 0x821D
+#define GL_CONTEXT_FLAGS 0x821E
+#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x0001
+#endif
+
+QT_BEGIN_NAMESPACE
+
+template <class MaskType, class FlagType> inline bool testFlag(MaskType mask, FlagType flag)
+{
+ return (mask & MaskType(flag)) != 0;
+}
+
+static inline bool hasGLOverlay(const PIXELFORMATDESCRIPTOR &pd)
+{ return (pd.bReserved & 0x0f) != 0; }
+
+static inline bool isDirectRendering(const PIXELFORMATDESCRIPTOR &pfd)
+{ return (pfd.dwFlags & PFD_GENERIC_ACCELERATED) || !(pfd.dwFlags & PFD_GENERIC_FORMAT); }
+
+static inline void initPixelFormatDescriptor(PIXELFORMATDESCRIPTOR *d)
+{
+ memset(d, 0, sizeof(PIXELFORMATDESCRIPTOR));
+ d->nSize = sizeof(PIXELFORMATDESCRIPTOR);
+ d->nVersion = 1;
+}
+
+QDebug operator<<(QDebug d, const PIXELFORMATDESCRIPTOR &pd)
+{
+ QDebug nsp = d.nospace();
+ nsp << "PIXELFORMATDESCRIPTOR "
+ << "dwFlags=" << hex << showbase << pd.dwFlags << dec << noshowbase;
+ if (pd.dwFlags & PFD_DRAW_TO_WINDOW) nsp << " PFD_DRAW_TO_WINDOW";
+ if (pd.dwFlags & PFD_DRAW_TO_BITMAP) nsp << " PFD_DRAW_TO_BITMAP";
+ if (pd.dwFlags & PFD_SUPPORT_GDI) nsp << " PFD_SUPPORT_GDI";
+ if (pd.dwFlags & PFD_SUPPORT_OPENGL) nsp << " PFD_SUPPORT_OPENGL";
+ if (pd.dwFlags & PFD_GENERIC_ACCELERATED) nsp << " PFD_GENERIC_ACCELERATED";
+ if (pd.dwFlags & PFD_SUPPORT_DIRECTDRAW) nsp << " PFD_SUPPORT_DIRECTDRAW";
+ if (pd.dwFlags & PFD_DIRECT3D_ACCELERATED) nsp << " PFD_DIRECT3D_ACCELERATED";
+ if (pd.dwFlags & PFD_SUPPORT_COMPOSITION) nsp << " PFD_SUPPORT_COMPOSITION";
+ if (pd.dwFlags & PFD_GENERIC_FORMAT) nsp << " PFD_GENERIC_FORMAT";
+ if (pd.dwFlags & PFD_NEED_PALETTE) nsp << " PFD_NEED_PALETTE";
+ if (pd.dwFlags & PFD_NEED_SYSTEM_PALETTE) nsp << " PFD_NEED_SYSTEM_PALETTE";
+ if (pd.dwFlags & PFD_DOUBLEBUFFER) nsp << " PFD_DOUBLEBUFFER";
+ if (pd.dwFlags & PFD_STEREO) nsp << " PFD_STEREO";
+ if (pd.dwFlags & PFD_SWAP_LAYER_BUFFERS) nsp << " PFD_SWAP_LAYER_BUFFERS";
+ if (hasGLOverlay(pd)) nsp << " overlay";
+ nsp << " iPixelType=" << pd.iPixelType << " cColorBits=" << pd.cColorBits
+ << " cRedBits=" << pd.cRedBits << " cRedShift=" << pd.cRedShift
+ << " cGreenBits=" << pd.cGreenBits << " cGreenShift=" << pd.cGreenShift
+ << " cBlueBits=" << pd.cBlueBits << " cBlueShift=" << pd.cBlueShift;
+ nsp << " cDepthBits=" << pd.cDepthBits;
+ if (pd.cStencilBits)
+ nsp << " cStencilBits=" << pd.cStencilBits;
+ if (pd.cAuxBuffers)
+ nsp << " cAuxBuffers=" << pd.cAuxBuffers;
+ nsp << " iLayerType=" << pd.iLayerType;
+ if (pd.dwVisibleMask)
+ nsp << " dwVisibleMask=" << pd.dwVisibleMask;
+ if (pd.cAlphaBits)
+ nsp << " cAlphaBits=" << pd.cAlphaBits << " cAlphaShift=" << pd.cAlphaShift;
+ if (pd.cAccumBits)
+ nsp << " cAccumBits=" << pd.cAccumBits << " cAccumRedBits=" << pd.cAccumRedBits
+ << " cAccumGreenBits=" << pd.cAccumGreenBits << " cAccumBlueBits=" << pd.cAccumBlueBits
+ << " cAccumAlphaBits=" << pd.cAccumAlphaBits;
+ return d;
+}
+
+// Check whether an obtained PIXELFORMATDESCRIPTOR matches the request.
+static inline bool
+ isAcceptableFormat(const QWindowsOpenGLAdditionalFormat &additional,
+ const PIXELFORMATDESCRIPTOR &pfd,
+ bool ignoreGLSupport = false) // ARB format may not contain it.
+{
+ const bool pixmapRequested = testFlag(additional.formatFlags, QWindowsGLRenderToPixmap);
+ return (ignoreGLSupport || testFlag(pfd.dwFlags, PFD_SUPPORT_OPENGL))
+ && testFlag(pfd.dwFlags, PFD_DRAW_TO_BITMAP) == pixmapRequested
+ && hasGLOverlay(pfd) == testFlag(additional.formatFlags, QWindowsGLOverlay)
+ && (!pixmapRequested || pfd.cColorBits == additional.pixmapDepth);
+}
+
+static void describeFormats(HDC hdc)
+{
+ const int pfiMax = DescribePixelFormat(hdc, 0, 0, NULL);
+ for (int i = 0; i < pfiMax; i++) {
+ PIXELFORMATDESCRIPTOR pfd;
+ initPixelFormatDescriptor(&pfd);
+ DescribePixelFormat(hdc, i, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
+ qDebug() << '#' << i << '/' << pfiMax << ':' << pfd;
+ }
+}
+
+// Classic GDI API
+namespace GDI {
+static QSurfaceFormat
+ qSurfaceFormatFromPixelFormat(const PIXELFORMATDESCRIPTOR &pfd,
+ QWindowsOpenGLAdditionalFormat *additionalIn = 0)
+{
+ QSurfaceFormat format;
+ if (pfd.dwFlags & PFD_DOUBLEBUFFER)
+ format.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
+ format.setDepthBufferSize(pfd.cDepthBits);
+
+ if (pfd.iPixelType == PFD_TYPE_RGBA)
+ format.setAlphaBufferSize(pfd.cAlphaBits);
+ format.setRedBufferSize(pfd.cRedBits);
+ format.setGreenBufferSize(pfd.cGreenBits);
+ format.setBlueBufferSize(pfd.cBlueBits);
+ format.setStencilBufferSize(pfd.cStencilBits);
+ format.setStereo(pfd.dwFlags & PFD_STEREO);
+ if (additionalIn) {
+ QWindowsOpenGLAdditionalFormat additional;
+ if (isDirectRendering(pfd))
+ additional.formatFlags |= QWindowsGLDirectRendering;
+ if (hasGLOverlay(pfd))
+ additional.formatFlags |= QWindowsGLOverlay;
+ if (pfd.cAccumRedBits)
+ additional.formatFlags |= QWindowsGLAccumBuffer;
+ if (testFlag(pfd.dwFlags, PFD_DRAW_TO_BITMAP)) {
+ additional.formatFlags |= QWindowsGLRenderToPixmap;
+ additional.pixmapDepth = pfd.cColorBits;
+ }
+ *additionalIn = additional;
+ }
+ return format;
+}
+
+static PIXELFORMATDESCRIPTOR
+ qPixelFormatFromSurfaceFormat(const QSurfaceFormat &format,
+ const QWindowsOpenGLAdditionalFormat &additional)
+{
+ PIXELFORMATDESCRIPTOR pfd;
+ initPixelFormatDescriptor(&pfd);
+ pfd.iPixelType = PFD_TYPE_RGBA;
+ pfd.iLayerType = PFD_MAIN_PLANE;
+ pfd.dwFlags = PFD_SUPPORT_OPENGL;
+ if (QSysInfo::windowsVersion() >= QSysInfo::WV_VISTA)
+ pfd.dwFlags = PFD_SUPPORT_COMPOSITION;
+ const bool isPixmap = (additional.formatFlags & QWindowsGLRenderToPixmap) != 0;
+ pfd.dwFlags |= isPixmap ? PFD_DRAW_TO_BITMAP : PFD_DRAW_TO_WINDOW;
+ if (!(additional.formatFlags & QWindowsGLDirectRendering))
+ pfd.dwFlags |= PFD_GENERIC_FORMAT;
+
+ if (format.stereo())
+ pfd.dwFlags |= PFD_STEREO;
+ if (format.swapBehavior() == QSurfaceFormat::DoubleBuffer && !isPixmap)
+ pfd.dwFlags |= PFD_DOUBLEBUFFER;
+ pfd.cDepthBits =
+ format.depthBufferSize() >= 0 ? format.depthBufferSize() : 32;
+ pfd.cAlphaBits = format.alphaBufferSize() > 0 ? format.alphaBufferSize() : 8;
+ pfd.cStencilBits = format.stencilBufferSize() > 0 ? format.stencilBufferSize() : 8;
+ if (additional.formatFlags & QWindowsGLAccumBuffer)
+ pfd.cAccumRedBits = pfd.cAccumGreenBits = pfd.cAccumBlueBits = pfd.cAccumAlphaBits = 16;
+ return pfd;
+}
+
+// Choose a suitable pixelformat using GDI WinAPI in case ARB
+// functions cannot be found. First tries to find a suitable
+// format using GDI function ChoosePixelFormat(). Since that
+// does not handle overlay and direct-rendering requests, manually loop
+// over the available formats to find the best one.
+// Note: As of Windows 7, it seems direct-rendering is handled, so,
+// the code might be obsolete?
+static int choosePixelFormat(HDC hdc, const QSurfaceFormat &format,
+ const QWindowsOpenGLAdditionalFormat &additional,
+ PIXELFORMATDESCRIPTOR *obtainedPfd)
+{
+ // 1) Try ChoosePixelFormat().
+ PIXELFORMATDESCRIPTOR requestedPfd = qPixelFormatFromSurfaceFormat(format, QWindowsGLDirectRendering);
+ initPixelFormatDescriptor(obtainedPfd);
+ int pixelFormat = ChoosePixelFormat(hdc, &requestedPfd);
+ if (pixelFormat >= 0) {
+ DescribePixelFormat(hdc, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), obtainedPfd);
+ if (isAcceptableFormat(additional, *obtainedPfd))
+ return pixelFormat;
+ }
+ // 2) No matching format found, manual search loop.
+ const int pfiMax = DescribePixelFormat(hdc, 0, 0, NULL);
+ int bestScore = -1;
+ int bestPfi = -1;
+ const bool stereoRequested = format.stereo();
+ const bool accumBufferRequested = testFlag(additional.formatFlags, QWindowsGLAccumBuffer);
+ const bool doubleBufferRequested = format.swapBehavior() == QSurfaceFormat::DoubleBuffer;
+ const bool directRenderingRequested = testFlag(additional.formatFlags, QWindowsGLDirectRendering);
+ for (int pfi = 1; pfi <= pfiMax; pfi++) {
+ PIXELFORMATDESCRIPTOR checkPfd;
+ initPixelFormatDescriptor(&checkPfd);
+ DescribePixelFormat(hdc, pfi, sizeof(PIXELFORMATDESCRIPTOR), &checkPfd);
+ if (isAcceptableFormat(additional, checkPfd)) {
+ int score = checkPfd.cColorBits + checkPfd.cAlphaBits + checkPfd.cStencilBits;
+ if (accumBufferRequested)
+ score += checkPfd.cAccumBits;
+ if (doubleBufferRequested == testFlag(checkPfd.dwFlags, PFD_DOUBLEBUFFER))
+ score += 1000;
+ if (stereoRequested == testFlag(checkPfd.dwFlags, PFD_STEREO))
+ score += 2000;
+ if (directRenderingRequested == isDirectRendering(checkPfd))
+ score += 4000;
+ if (checkPfd.iPixelType == PFD_TYPE_RGBA)
+ score += 8000;
+ if (score > bestScore) {
+ bestScore = score;
+ bestPfi = pfi;
+ *obtainedPfd = checkPfd;
+ }
+ if (QWindowsContext::verboseGL)
+ qDebug() << __FUNCTION__ << " checking " << pfi << '/' << pfiMax
+ << " score=" << score << " (best " << bestPfi << '/' << bestScore
+ << ") " << checkPfd;
+ }
+ } // for
+ if (bestPfi > 0)
+ pixelFormat = bestPfi;
+ return pixelFormat;
+}
+
+static inline HGLRC createContext(HDC hdc, HGLRC shared)
+{
+ HGLRC result = wglCreateContext(hdc);
+ if (!result) {
+ qErrnoWarning("%s: wglCreateContext failed.", __FUNCTION__);
+ return 0;
+ }
+ if (shared && !wglShareLists(shared, result))
+ qErrnoWarning("%s: wglShareLists() failed.", __FUNCTION__);
+ return result;
+}
+} // namespace GDI
+
+// ARB OpenGL extension API
+namespace ARB {
+// Choose a suitable pixelformat using ARB extension functions.
+static int choosePixelFormat(HDC hdc,
+ const QOpenGLStaticContext &staticContext,
+ const QSurfaceFormat &format,
+ const QWindowsOpenGLAdditionalFormat &additional,
+ PIXELFORMATDESCRIPTOR *obtainedPfd)
+{
+ enum { attribSize =40 };
+ if ((additional.formatFlags & QWindowsGLRenderToPixmap) || !staticContext.hasExtensions())
+ return 0;
+
+ int iAttributes[attribSize];
+ qFill(iAttributes, iAttributes + attribSize, int(0));
+ int i = 0;
+ iAttributes[i++] = WGL_ACCELERATION_ARB;
+ iAttributes[i++] = testFlag(additional.formatFlags, QWindowsGLDirectRendering) ?
+ WGL_FULL_ACCELERATION_ARB : WGL_NO_ACCELERATION_ARB;
+ iAttributes[i++] = WGL_SUPPORT_OPENGL_ARB;
+ iAttributes[i++] = TRUE;
+ iAttributes[i++] = WGL_DRAW_TO_WINDOW_ARB;
+ iAttributes[i++] = TRUE;
+ iAttributes[i++] = WGL_COLOR_BITS_ARB;
+ iAttributes[i++] = 24;
+ switch (format.swapBehavior()) {
+ case QSurfaceFormat::DefaultSwapBehavior:
+ case QSurfaceFormat::TripleBuffer:
+ break;
+ case QSurfaceFormat::SingleBuffer:
+ iAttributes[i++] = WGL_DOUBLE_BUFFER_ARB;
+ iAttributes[i++] = FALSE;
+ break;
+ case QSurfaceFormat::DoubleBuffer:
+ iAttributes[i++] = WGL_DOUBLE_BUFFER_ARB;
+ iAttributes[i++] = TRUE;
+ break;
+ }
+ if (format.stereo()) {
+ iAttributes[i++] = WGL_STEREO_ARB;
+ iAttributes[i++] = TRUE;
+ }
+ if (format.depthBufferSize() >= 0) {
+ iAttributes[i++] = WGL_DEPTH_BITS_ARB;
+ iAttributes[i++] = format.depthBufferSize();
+ }
+ iAttributes[i++] = WGL_PIXEL_TYPE_ARB;
+ iAttributes[i++] = WGL_TYPE_RGBA_ARB;
+ if (format.redBufferSize() >= 0) {
+ iAttributes[i++] = WGL_RED_BITS_ARB;
+ iAttributes[i++] = format.redBufferSize();
+ }
+ if (format.greenBufferSize() >= 0) {
+ iAttributes[i++] = WGL_GREEN_BITS_ARB;
+ iAttributes[i++] = format.greenBufferSize();
+ }
+ if (format.blueBufferSize() >= 0) {
+ iAttributes[i++] = WGL_BLUE_BITS_ARB;
+ iAttributes[i++] = format.blueBufferSize();
+ }
+ iAttributes[i++] = WGL_ALPHA_BITS_ARB;
+ iAttributes[i++] = format.alphaBufferSize() >= 0 ? format.alphaBufferSize() : 8;
+ if (additional.formatFlags & QWindowsGLAccumBuffer) {
+ iAttributes[i++] = WGL_ACCUM_BITS_ARB;
+ iAttributes[i++] = 16;
+ }
+ iAttributes[i++] = WGL_STENCIL_BITS_ARB;
+ iAttributes[i++] = 8;
+ if (additional.formatFlags & QWindowsGLOverlay) {
+ iAttributes[i++] = WGL_NUMBER_OVERLAYS_ARB;
+ iAttributes[i++] = 1;
+ }
+ const bool sampleBuffersRequested = format.samples() > 1
+ && testFlag(staticContext.extensions, QOpenGLStaticContext::SampleBuffers);
+ int samplesValuePosition = 0;
+ int samplesEnabledPosition = 0;
+ if (sampleBuffersRequested) {
+ iAttributes[i++] = WGL_SAMPLE_BUFFERS_ARB;
+ samplesEnabledPosition = i;
+ iAttributes[i++] = TRUE;
+ iAttributes[i++] = WGL_SAMPLES_ARB;
+ samplesValuePosition = i;
+ iAttributes[i++] = format.samples();
+ }
+ // If sample buffer request cannot be satisfied, reduce request.
+ int pixelFormat = 0;
+ uint numFormats = 0;
+ while (true) {
+ const bool valid =
+ staticContext.wglChoosePixelFormatARB(hdc, iAttributes, 0, 1,
+ &pixelFormat, &numFormats)
+ && numFormats >= 1;
+ if (valid || !sampleBuffersRequested)
+ break;
+ if (iAttributes[samplesValuePosition] > 1) {
+ iAttributes[samplesValuePosition] /= 2;
+ } else {
+ break;
+ }
+ }
+ // Verify if format is acceptable. Note that the returned
+ // formats have been observed to not contain PFD_SUPPORT_OPENGL, ignore.
+ initPixelFormatDescriptor(obtainedPfd);
+ DescribePixelFormat(hdc, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), obtainedPfd);
+ if (!isAcceptableFormat(additional, *obtainedPfd, true)) {
+ if (QWindowsContext::verboseGL)
+ qDebug() << __FUNCTION__ << " obtained px #" << pixelFormat
+ << " not acceptable=" << *obtainedPfd;
+ pixelFormat = 0;
+ }
+
+ if (QWindowsContext::verboseGL) {
+ QDebug nsp = qDebug().nospace();
+ nsp << __FUNCTION__;
+ if (sampleBuffersRequested)
+ nsp << " samples=" << iAttributes[samplesValuePosition];
+ nsp << " Attributes: " << hex << showbase;
+ for (int ii = 0; ii < i; ++ii)
+ nsp << iAttributes[ii] << ',';
+ nsp << noshowbase << dec << "\n obtained px #" << pixelFormat
+ << " of " << numFormats << "\n " << *obtainedPfd;
+ } // Debug
+
+ return pixelFormat;
+}
+
+static QSurfaceFormat
+ qSurfaceFormatFromHDC(const QOpenGLStaticContext &staticContext,
+ HDC hdc, int pixelFormat,
+ QWindowsOpenGLAdditionalFormat *additionalIn = 0)
+{
+ enum { attribSize =40 };
+
+ QSurfaceFormat result;
+ if (!staticContext.hasExtensions())
+ return result;
+ int iAttributes[attribSize];
+ int iValues[attribSize];
+ qFill(iAttributes, iAttributes + attribSize, int(0));
+ qFill(iValues, iValues + attribSize, int(0));
+
+ int i = 0;
+ const bool hasSampleBuffers = testFlag(staticContext.extensions, QOpenGLStaticContext::SampleBuffers);
+
+ iAttributes[i++] = WGL_DOUBLE_BUFFER_ARB; // 0
+ iAttributes[i++] = WGL_DEPTH_BITS_ARB; // 1
+ iAttributes[i++] = WGL_PIXEL_TYPE_ARB; // 2
+ iAttributes[i++] = WGL_RED_BITS_ARB; // 3
+ iAttributes[i++] = WGL_GREEN_BITS_ARB; // 4
+ iAttributes[i++] = WGL_BLUE_BITS_ARB; // 5
+ iAttributes[i++] = WGL_ALPHA_BITS_ARB; // 6
+ iAttributes[i++] = WGL_ACCUM_BITS_ARB; // 7
+ iAttributes[i++] = WGL_STENCIL_BITS_ARB; // 8
+ iAttributes[i++] = WGL_STEREO_ARB; // 9
+ iAttributes[i++] = WGL_ACCELERATION_ARB; // 10
+ iAttributes[i++] = WGL_NUMBER_OVERLAYS_ARB; // 11
+ if (hasSampleBuffers) {
+ iAttributes[i++] = WGL_SAMPLE_BUFFERS_ARB; // 12
+ iAttributes[i++] = WGL_SAMPLES_ARB; // 13
+ }
+ if (!staticContext.wglGetPixelFormatAttribIVARB(hdc, pixelFormat, 0, i,
+ iAttributes, iValues))
+ return result;
+ if (iValues[0])
+ result.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
+ result.setDepthBufferSize(iValues[1]);
+ result.setRedBufferSize(iValues[3]);
+ result.setGreenBufferSize(iValues[4]);
+ result.setBlueBufferSize(iValues[5]);
+ result.setAlphaBufferSize(iValues[6]);
+ result.setStencilBufferSize(iValues[8]);
+ result.setStereo(iValues[9]);
+ if (hasSampleBuffers)
+ result.setSamples(iValues[13]);
+ if (additionalIn) {
+ if (iValues[7])
+ additionalIn->formatFlags |= QWindowsGLAccumBuffer;
+ if (iValues[10] == WGL_FULL_ACCELERATION_ARB)
+ additionalIn->formatFlags |= QWindowsGLDirectRendering;
+ if (iValues[11])
+ additionalIn->formatFlags |= QWindowsGLOverlay;
+ }
+ return result;
+}
+
+static HGLRC createContext(const QOpenGLStaticContext &staticContext,
+ HDC hdc,
+ const QSurfaceFormat &format,
+ const QWindowsOpenGLAdditionalFormat &additional,
+ int majorVersion = 0,
+ int minorVersion = 0,
+ HGLRC shared = 0)
+{
+ enum { attribSize = 11 };
+
+ if (!staticContext.hasExtensions())
+ return 0;
+ int attributes[attribSize];
+ int attribIndex = 0;
+ qFill(attributes, attributes + attribSize, int(0));
+
+ if (majorVersion) {
+ attributes[attribIndex++] = WGL_CONTEXT_MAJOR_VERSION_ARB;
+ attributes[attribIndex++] = majorVersion;
+ attributes[attribIndex++] = WGL_CONTEXT_MINOR_VERSION_ARB;
+ attributes[attribIndex++] = minorVersion;
+ }
+ if (majorVersion >= 3 && additional.formatFlags & QWindowsGLDeprecatedFunctions) {
+ attributes[attribIndex++] = WGL_CONTEXT_FLAGS_ARB;
+ attributes[attribIndex++] = WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
+ }
+ if ((staticContext.majorVersion == 3 && staticContext.minorVersion >= 2)
+ || staticContext.majorVersion > 3) {
+ switch (format.profile()) {
+ case QSurfaceFormat::NoProfile:
+ break;
+ case QSurfaceFormat::CoreProfile:
+ attributes[attribIndex++] = WGL_CONTEXT_PROFILE_MASK_ARB;
+ attributes[attribIndex++] = WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
+ break;
+ case QSurfaceFormat::CompatibilityProfile:
+ attributes[attribIndex++] = WGL_CONTEXT_PROFILE_MASK_ARB;
+ attributes[attribIndex++] = WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
+ break;
+ }
+ }
+ const HGLRC result =
+ staticContext.wglCreateContextAttribsARB(hdc, shared, attributes);
+ if (!result)
+ qErrnoWarning("%s: wglCreateContextAttribsARB() failed.", __FUNCTION__);
+ return result;
+}
+
+} // namespace ARB
+
+// Helpers for temporary contexts
+static inline HWND createDummyGLWindow()
+{
+ return QWindowsContext::instance()->
+ createDummyWindow(QStringLiteral("QtOpenGLDummyWindow"),
+ L"OpenGLDummyWindow", 0, WS_OVERLAPPED | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
+}
+
+// Create a dummy GL context (see QOpenGLTemporaryContext).
+static inline HGLRC createDummyGLContext(HDC dc)
+{
+ if (!dc)
+ return 0;
+ PIXELFORMATDESCRIPTOR pixelFormDescriptor;
+ initPixelFormatDescriptor(&pixelFormDescriptor);
+ pixelFormDescriptor.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | PFD_GENERIC_FORMAT;
+ pixelFormDescriptor.iPixelType = PFD_TYPE_RGBA;
+ const int pixelFormat = ChoosePixelFormat(dc, &pixelFormDescriptor);
+ if (!pixelFormat) {
+ qErrnoWarning("%s: ChoosePixelFormat failed.", __FUNCTION__);
+ return 0;
+ }
+ if (!SetPixelFormat(dc, pixelFormat, &pixelFormDescriptor)) {
+ qErrnoWarning("%s: SetPixelFormat failed.", __FUNCTION__);
+ return 0;
+ }
+ HGLRC rc = wglCreateContext(dc);
+ if (!rc) {
+ qErrnoWarning("%s: wglCreateContext failed.", __FUNCTION__);
+ return 0;
+ }
+ return rc;
+}
+
+static inline QOpenGLContextData currentOpenGLContextData()
+{
+ QOpenGLContextData result;
+ result.hdc = wglGetCurrentDC();
+ result.renderingContext = wglGetCurrentContext();
+ return result;
+}
+
+static inline QOpenGLContextData createDummyWindowOpenGLContextData()
+{
+ QOpenGLContextData result;
+ result.hwnd = createDummyGLWindow();
+ result.hdc = GetDC(result.hwnd);
+ result.renderingContext = createDummyGLContext(result.hdc);
+ return result;
+}
+
+/*!
+ \class QOpenGLTemporaryContext
+ \brief A temporary context that can be instantiated on the stack.
+
+ Functions like wglGetProcAddress() or glGetString() only work if there
+ is a current GL context.
+
+ \ingroup qt-lighthouse-win
+*/
+
+class QOpenGLTemporaryContext
+{
+ Q_DISABLE_COPY(QOpenGLTemporaryContext)
+public:
+ QOpenGLTemporaryContext();
+ ~QOpenGLTemporaryContext();
+
+private:
+ const QOpenGLContextData m_previous;
+ const QOpenGLContextData m_current;
+};
+
+QOpenGLTemporaryContext::QOpenGLTemporaryContext() :
+ m_previous(currentOpenGLContextData()),
+ m_current(createDummyWindowOpenGLContextData())
+{
+ wglMakeCurrent(m_current.hdc, m_current.renderingContext);
+}
+
+QOpenGLTemporaryContext::~QOpenGLTemporaryContext()
+{
+ wglMakeCurrent(m_previous.hdc, m_previous.renderingContext);
+ ReleaseDC(m_current.hwnd, m_current.hdc);
+ DestroyWindow(m_current.hwnd);
+ wglDeleteContext(m_current.renderingContext);
+}
+
+/*!
+ \class QWindowsOpenGLAdditionalFormat
+ \brief Additional format information that is not in QSurfaceFormat
+ \ingroup qt-lighthouse-win
+*/
+
+/*!
+ \class QOpenGLStaticContext
+ \brief Static Open GL context containing version information, extension function pointers, etc.
+
+ Functions pending integration in the next version of OpenGL are post-fixed ARB.
+
+ \note Initialization requires an active context (see create()).
+
+ \sa QWindowsGLContext
+ \ingroup qt-lighthouse-win
+*/
+
+#define SAMPLE_BUFFER_EXTENSION "GL_ARB_multisample"
+
+QOpenGLStaticContext::QOpenGLStaticContext() :
+ vendor(QOpenGLStaticContext::getGlString(GL_VENDOR)),
+ renderer(QOpenGLStaticContext::getGlString(GL_RENDERER)),
+ extensionNames(QOpenGLStaticContext::getGlString(GL_EXTENSIONS)),
+ majorVersion(0), minorVersion(0),
+ extensions(0),
+ wglGetPixelFormatAttribIVARB((WglGetPixelFormatAttribIVARB)wglGetProcAddress("wglGetPixelFormatAttribivARB")),
+ wglChoosePixelFormatARB((WglChoosePixelFormatARB)wglGetProcAddress("wglChoosePixelFormatARB")),
+ wglCreateContextAttribsARB((WglCreateContextAttribsARB)wglGetProcAddress("wglCreateContextAttribsARB"))
+{
+ if (extensionNames.startsWith(SAMPLE_BUFFER_EXTENSION" ")
+ || extensionNames.indexOf(" "SAMPLE_BUFFER_EXTENSION" ") != -1)
+ extensions |= SampleBuffers;
+ // Get version
+ do {
+ const QByteArray version = QOpenGLStaticContext::getGlString(GL_VERSION);
+ if (version.isEmpty())
+ break;
+ const int majorDot = version.indexOf('.');
+ if (majorDot == -1)
+ break;
+ int minorDot = version.indexOf('.', majorDot + 1);
+ if (minorDot == -1)
+ minorDot = version.size();
+ majorVersion = version.mid(0, majorDot).toInt();
+ minorVersion = version.mid(majorDot + 1, minorDot - majorDot - 1).toInt();
+ } while (false);
+}
+
+QByteArray QOpenGLStaticContext::getGlString(unsigned int which)
+{
+ if (const GLubyte *s = glGetString(which))
+ return QByteArray((const char*)s);
+ return QByteArray();
+}
+
+QOpenGLStaticContext *QOpenGLStaticContext::create()
+{
+ // We need a current context for wglGetProcAdress()/getGLString() to work.
+ QScopedPointer<QOpenGLTemporaryContext> temporaryContext;
+ if (!wglGetCurrentContext())
+ temporaryContext.reset(new QOpenGLTemporaryContext);
+ QOpenGLStaticContext *result = new QOpenGLStaticContext;
+ if (QWindowsContext::verboseGL)
+ qDebug() << __FUNCTION__ << *result;
+ return result;
+}
+
+QDebug operator<<(QDebug d, const QOpenGLStaticContext &s)
+{
+ QDebug nsp = d.nospace();
+ nsp << "OpenGL: " << s.vendor << ',' << s.renderer << ",v"
+ << s.majorVersion << '.' << s.minorVersion;
+ if (s.extensions & QOpenGLStaticContext::SampleBuffers)
+ nsp << ",SampleBuffers";
+ if (s.hasExtensions())
+ nsp << ", Extension-API present";
+ nsp << "\nExtensions: " << s.extensionNames;
+ return d;
+}
+
+/*!
+ \class QWindowsGLContext
+ \brief Open GL context.
+
+ An Open GL context for use with several windows.
+ As opposed to other implementations, activating a GL context for
+ a window requires a HDC allocated for it. The first time this
+ HDC is created for the window, the pixel format must be applied,
+ which will affect the window as well. The HDCs are stored in a list of
+ QOpenGLContextData and are released in doneCurrent().
+
+ \ingroup qt-lighthouse-win
+*/
+
+QWindowsGLContext::QWindowsGLContext(const QOpenGLStaticContextPtr &staticContext,
+ QOpenGLContext *context) :
+ m_staticContext(staticContext),
+ m_context(context),
+ m_pixelFormat(0), m_extensionsUsed(false)
+{
+ // workaround for matrox driver:
+ // make a cheap call to opengl to force loading of DLL
+ static bool opengl32dll = false;
+ if (!opengl32dll) {
+ GLint params;
+ glGetIntegerv(GL_DEPTH_BITS, &params);
+ opengl32dll = true;
+ }
+
+ // SetPixelFormat (as of Windows 7) requires a real window.
+ // Create a dummy one as we are not associated with a window yet.
+ // Try to find a suitable pixel format using preferably ARB extensions
+ // (default to GDI) and store that.
+ HWND dummyWindow = 0;
+ HDC hdc = 0;
+ do {
+ dummyWindow = createDummyGLWindow();
+ if (!dummyWindow)
+ break;
+ hdc = GetDC(dummyWindow);
+ if (!hdc)
+ break;
+
+ if (QWindowsContext::verboseGL > 1)
+ describeFormats(hdc);
+ // Preferably use direct rendering and ARB extensions (unless pixmap)
+ const QWindowsOpenGLAdditionalFormat
+ requestedAdditional(QWindowsGLDirectRendering|QWindowsGLDeprecatedFunctions);
+ const bool tryExtensions = m_staticContext->hasExtensions()
+ && !testFlag(requestedAdditional.formatFlags, QWindowsGLRenderToPixmap);
+ QWindowsOpenGLAdditionalFormat obtainedAdditional;
+ if (tryExtensions) {
+ m_pixelFormat =
+ ARB::choosePixelFormat(hdc, *m_staticContext, context->format(),
+ requestedAdditional, &m_obtainedPixelFormatDescriptor);
+ if (m_pixelFormat > 0) {
+ m_obtainedFormat =
+ ARB::qSurfaceFormatFromHDC(*m_staticContext, hdc, m_pixelFormat,
+ &obtainedAdditional);
+ m_extensionsUsed = true;
+ }
+ } // tryExtensions
+ if (!m_pixelFormat) { // Failed, try GDI
+ m_pixelFormat = GDI::choosePixelFormat(hdc, context->format(), requestedAdditional,
+ &m_obtainedPixelFormatDescriptor);
+ if (m_pixelFormat)
+ m_obtainedFormat =
+ GDI::qSurfaceFormatFromPixelFormat(m_obtainedPixelFormatDescriptor,
+ &obtainedAdditional);
+ } // try GDI
+ if (!m_pixelFormat) {
+ qWarning("%s: Unable find a suitable pixel format.", __FUNCTION__);
+ break;
+ }
+ if (!SetPixelFormat(hdc, m_pixelFormat, &m_obtainedPixelFormatDescriptor)) {
+ qErrnoWarning("SetPixelFormat failed.");
+ break;
+ }
+ // Create context with sharing, again preferably using ARB.
+ HGLRC sharingRenderingContext = 0;
+ if (const QPlatformOpenGLContext *sc = context->shareHandle())
+ sharingRenderingContext = static_cast<const QWindowsGLContext *>(sc)->renderingContext();
+
+ if (m_extensionsUsed)
+ m_renderingContext =
+ ARB::createContext(*m_staticContext, hdc, context->format(),
+ requestedAdditional, 0, 0, sharingRenderingContext);
+ if (!m_renderingContext)
+ m_renderingContext = GDI::createContext(hdc, sharingRenderingContext);
+
+ if (!m_renderingContext) {
+ qWarning("Unable to create a GL Context.");
+ break;
+ }
+ } while (false);
+ if (hdc)
+ ReleaseDC(dummyWindow, hdc);
+ if (dummyWindow)
+ DestroyWindow(dummyWindow);
+
+ if (QWindowsContext::verboseGL)
+ qDebug()
+ << __FUNCTION__ << this << " requested: " << context->format()
+ << "\n obtained #" << m_pixelFormat << (m_extensionsUsed ? "ARB" : "GDI")
+ << m_obtainedFormat << "\n " << m_obtainedPixelFormatDescriptor
+ << "\n HGLRC=" << m_renderingContext;
+}
+
+QWindowsGLContext::~QWindowsGLContext()
+{
+ if (m_renderingContext)
+ wglDeleteContext(m_renderingContext);
+ releaseDCs();
+}
+
+void QWindowsGLContext::releaseDCs()
+{
+ const QOpenGLContextData *end = m_windowContexts.end();
+ for (const QOpenGLContextData *p = m_windowContexts.begin(); p < end; ++p)
+ ReleaseDC(p->hwnd, p->hdc);
+ m_windowContexts.resize(0);
+}
+
+static inline QWindowsWindow *glWindowOf(QPlatformSurface *s)
+{
+ return static_cast<QWindowsWindow *>(s);
+}
+
+static inline HWND handleOf(QPlatformSurface *s)
+{
+ return glWindowOf(s)->handle();
+}
+
+// Find a window in a context list.
+static inline const QOpenGLContextData *
+ findByHWND(const Array<QOpenGLContextData> &data, HWND hwnd)
+{
+ const QOpenGLContextData *end = data.end();
+ for (const QOpenGLContextData *p = data.begin(); p < end; ++p)
+ if (p->hwnd == hwnd)
+ return p;
+ return 0;
+}
+
+void QWindowsGLContext::swapBuffers(QPlatformSurface *surface)
+{
+ if (QWindowsContext::verboseGL > 1)
+ qDebug() << __FUNCTION__ << surface;
+ if (const QOpenGLContextData *contextData = findByHWND(m_windowContexts, handleOf(surface))) {
+ SwapBuffers(contextData->hdc);
+ } else {
+ qWarning("%s: Cannot find window %p", __FUNCTION__, handleOf(surface));
+ }
+}
+
+bool QWindowsGLContext::makeCurrent(QPlatformSurface *surface)
+{
+#ifdef DEBUG_GL
+ if (QWindowsContext::verboseGL > 1)
+ qDebug("%s context=%p contexts=%d", __FUNCTION__, this, m_windowContexts.size());
+#endif // DEBUG_GL
+ // Do we already have a DC entry for that window?
+ QWindowsWindow *window = static_cast<QWindowsWindow *>(surface);
+ const HWND hwnd = window->handle();
+ if (const QOpenGLContextData *contextData = findByHWND(m_windowContexts, hwnd))
+ return wglMakeCurrent(contextData->hdc, contextData->renderingContext);
+ // Create a new entry.
+ const QOpenGLContextData newContext(m_renderingContext, hwnd, GetDC(hwnd));
+ if (!newContext.hdc)
+ return false;
+ // Initialize pixel format first time. This will apply to
+ // the HWND as well and must be done only once.
+ if (!window->testFlag(QWindowsWindow::PixelFormatInitialized)) {
+ if (!SetPixelFormat(newContext.hdc, m_pixelFormat, &m_obtainedPixelFormatDescriptor)) {
+ qErrnoWarning("%s: SetPixelFormat() failed", __FUNCTION__);
+ ReleaseDC(newContext.hwnd, newContext.hdc);
+ return false;
+ }
+ window->setFlag(QWindowsWindow::PixelFormatInitialized);
+ }
+ m_windowContexts.append(newContext);
+ return wglMakeCurrent(newContext.hdc, newContext.renderingContext);
+}
+
+void QWindowsGLContext::doneCurrent()
+{
+#ifdef DEBUG_GL
+ if (QWindowsContext::verboseGL > 1)
+ qDebug("%s context=%p %d contexts", __FUNCTION__, this, m_windowContexts.size());
+#endif // DEBUG_GL
+ wglMakeCurrent(0, 0);
+ releaseDCs();
+}
+
+QWindowsGLContext::GL_Proc QWindowsGLContext::getProcAddress(const QByteArray &procName)
+{
+ // TODO: Will that work with the calling conventions?
+ GL_Proc procAddress = reinterpret_cast<GL_Proc>(wglGetProcAddress(procName.constData()));
+ if (QWindowsContext::verboseGL)
+ qDebug("%s('%s') with current_hglrc=%p returns %p",
+ __FUNCTION__, procName.constData(),
+ wglGetCurrentContext(), procAddress);
+ return procAddress;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsglcontext.h b/src/plugins/platforms/windows/qwindowsglcontext.h
new file mode 100644
index 0000000000..0bf8ffbbc5
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsglcontext.h
@@ -0,0 +1,165 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSGLCONTEXT_H
+#define QWINDOWSGLCONTEXT_H
+
+#include "array.h"
+#include "qtwindows_additional.h"
+
+#include <QtGui/QPlatformOpenGLContext>
+#include <QtGui/QOpenGLContext>
+#include <QtCore/QSharedPointer>
+
+QT_BEGIN_NAMESPACE
+
+class QDebug;
+
+enum QWindowsGLFormatFlags
+{
+ QWindowsGLDirectRendering = 0x1,
+ QWindowsGLOverlay = 0x2,
+ QWindowsGLRenderToPixmap = 0x4,
+ QWindowsGLAccumBuffer = 0x8,
+ QWindowsGLDeprecatedFunctions = 0x10
+};
+
+// Additional format information for Windows.
+struct QWindowsOpenGLAdditionalFormat
+{
+ QWindowsOpenGLAdditionalFormat(unsigned formatFlagsIn = 0, unsigned pixmapDepthIn = 0) :
+ formatFlags(formatFlagsIn), pixmapDepth(pixmapDepthIn) {}
+ unsigned formatFlags; // QWindowsGLFormatFlags.
+ unsigned pixmapDepth; // for QWindowsGLRenderToPixmap
+};
+
+// Per-window data for active OpenGL contexts.
+struct QOpenGLContextData
+{
+ QOpenGLContextData(HGLRC r, HWND h, HDC d) : renderingContext(r), hwnd(h), hdc(d) {}
+ QOpenGLContextData() : renderingContext(0), hwnd(0), hdc(0) {}
+
+ HGLRC renderingContext;
+ HWND hwnd;
+ HDC hdc;
+};
+
+class QOpenGLStaticContext
+{
+ Q_DISABLE_COPY(QOpenGLStaticContext)
+ QOpenGLStaticContext();
+public:
+ enum Extensions
+ {
+ SampleBuffers = 0x1
+ };
+
+ typedef bool
+ (APIENTRY *WglGetPixelFormatAttribIVARB)
+ (HDC hdc, int iPixelFormat, int iLayerPlane,
+ uint nAttributes, const int *piAttributes, int *piValues);
+
+ typedef bool
+ (APIENTRY *WglChoosePixelFormatARB)(HDC hdc, const int *piAttribList,
+ const float *pfAttribFList, uint nMaxFormats, int *piFormats,
+ UINT *nNumFormats);
+
+ typedef HGLRC
+ (APIENTRY *WglCreateContextAttribsARB)(HDC, HGLRC, const int *);
+
+ bool hasExtensions() const
+ { return wglGetPixelFormatAttribIVARB && wglChoosePixelFormatARB && wglCreateContextAttribsARB; }
+
+ static QOpenGLStaticContext *create();
+ static QByteArray getGlString(unsigned int which);
+
+ const QByteArray vendor;
+ const QByteArray renderer;
+ const QByteArray extensionNames;
+ int majorVersion;
+ int minorVersion;
+ unsigned extensions;
+
+ WglGetPixelFormatAttribIVARB wglGetPixelFormatAttribIVARB;
+ WglChoosePixelFormatARB wglChoosePixelFormatARB;
+ WglCreateContextAttribsARB wglCreateContextAttribsARB;
+};
+
+QDebug operator<<(QDebug d, const QOpenGLStaticContext &);
+
+class QWindowsGLContext : public QPlatformOpenGLContext
+{
+public:
+ typedef QSharedPointer<QOpenGLStaticContext> QOpenGLStaticContextPtr;
+
+ explicit QWindowsGLContext(const QOpenGLStaticContextPtr &staticContext,
+ QOpenGLContext *context);
+ virtual ~QWindowsGLContext();
+ bool isValid() const { return m_renderingContext; }
+ virtual QSurfaceFormat format() const { return m_obtainedFormat; }
+
+ virtual void swapBuffers(QPlatformSurface *surface);
+
+ virtual bool makeCurrent(QPlatformSurface *surface);
+ virtual void doneCurrent();
+
+ typedef void (*GL_Proc) ();
+
+ virtual GL_Proc getProcAddress(const QByteArray &procName);
+
+ HGLRC renderingContext() const { return m_renderingContext; }
+
+private:
+ inline void releaseDCs();
+
+ const QOpenGLStaticContextPtr m_staticContext;
+ QOpenGLContext *m_context;
+ QSurfaceFormat m_obtainedFormat;
+ HGLRC m_renderingContext;
+ Array<QOpenGLContextData> m_windowContexts;
+ PIXELFORMATDESCRIPTOR m_obtainedPixelFormatDescriptor;
+ int m_pixelFormat;
+ bool m_extensionsUsed;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSGLCONTEXT_H
diff --git a/src/plugins/platforms/windows/qwindowsguieventdispatcher.cpp b/src/plugins/platforms/windows/qwindowsguieventdispatcher.cpp
new file mode 100644
index 0000000000..fe03a7ffe8
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsguieventdispatcher.cpp
@@ -0,0 +1,215 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsguieventdispatcher.h"
+#include "qwindowscontext.h"
+
+#include <QtGui/QWindowSystemInterface>
+
+#include <QtCore/QStack>
+#include <QtCore/QDebug>
+
+#include <windowsx.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QWindowsGuiEventDispatcher
+ \brief Event dispatcher for Windows
+
+ Maintains a global stack storing the current event dispatcher and
+ its processing flags for access from the Windows procedure
+ qWindowsWndProc. Handling the Lighthouse gui events should be done
+ from within the qWindowsWndProc to ensure correct processing of messages.
+
+ \ingroup qt-lighthouse-win
+*/
+
+typedef QStack<QWindowsGuiEventDispatcher::DispatchContext> DispatchContextStack;
+
+Q_GLOBAL_STATIC(DispatchContextStack, dispatchContextStack)
+
+QWindowsGuiEventDispatcher::QWindowsGuiEventDispatcher(QObject *parent) :
+ QEventDispatcherWin32(parent)
+{
+ setObjectName(QStringLiteral("QWindowsGuiEventDispatcher_0x") + QString::number((quintptr)this, 16));
+ if (QWindowsContext::verboseEvents)
+ qDebug("%s %s", __FUNCTION__, qPrintable(objectName()));
+ dispatchContextStack()->push(DispatchContext(this, QEventLoop::AllEvents));
+}
+
+QWindowsGuiEventDispatcher::~QWindowsGuiEventDispatcher()
+{
+ if (QWindowsContext::verboseEvents)
+ qDebug("%s %s", __FUNCTION__, qPrintable(objectName()));
+ if (!dispatchContextStack()->isEmpty())
+ dispatchContextStack()->pop();
+}
+
+bool QWindowsGuiEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags)
+{
+ DispatchContextStack &stack = *dispatchContextStack();
+ if (QWindowsContext::verboseEvents > 2)
+ qDebug(">%s %s %d", __FUNCTION__, qPrintable(objectName()), stack.size());
+ stack.push(DispatchContext(this, flags));
+ const bool rc = QEventDispatcherWin32::processEvents(flags);
+ stack.pop();
+ if (QWindowsContext::verboseEvents > 2)
+ qDebug("<%s %s returns %d", __FUNCTION__, qPrintable(objectName()), rc);
+ return rc;
+}
+
+QWindowsGuiEventDispatcher::DispatchContext QWindowsGuiEventDispatcher::currentDispatchContext()
+{
+ const DispatchContextStack &stack = *dispatchContextStack();
+ if (stack.isEmpty()) {
+ qWarning("%s: No dispatch context", __FUNCTION__);
+ return DispatchContext(0, 0);
+ }
+ return stack.top();
+}
+
+// Helpers for printing debug output for WM_* messages.
+struct MessageDebugEntry
+{
+ UINT message;
+ const char *description;
+ bool interesting;
+};
+
+static const MessageDebugEntry
+messageDebugEntries[] = {
+ {WM_CREATE, "WM_CREATE", true},
+ {WM_PAINT, "WM_PAINT", true},
+ {WM_CLOSE, "WM_CLOSE", true},
+ {WM_DESTROY, "WM_DESTROY", true},
+ {WM_MOVE, "WM_MOVE", true},
+ {WM_SIZE, "WM_SIZE", true},
+ {WM_MOUSEACTIVATE,"WM_MOUSEACTIVATE", true},
+ {WM_CHILDACTIVATE, "WM_CHILDACTIVATE", true},
+ {WM_PARENTNOTIFY, "WM_PARENTNOTIFY", true},
+ {WM_GETICON, "WM_GETICON", false},
+ {WM_KEYDOWN, "WM_KEYDOWN", true},
+ {WM_SYSKEYDOWN, "WM_SYSKEYDOWN", true},
+ {WM_SYSCOMMAND, "WM_SYSCOMMAND", true},
+ {WM_KEYUP, "WM_KEYUP", true},
+ {WM_SYSKEYUP, "WM_SYSKEYUP", true},
+ {WM_IME_CHAR, "WM_IMECHAR", true},
+ {WM_IME_KEYDOWN, "WM_IMECHAR", true},
+ {WM_CANCELMODE, "WM_CANCELMODE", true},
+ {WM_CHAR, "WM_CHAR", true},
+ {WM_DEADCHAR, "WM_DEADCHAR", true},
+ {WM_ACTIVATE, "WM_ACTIVATE", true},
+ {WM_GETMINMAXINFO, "WM_GETMINMAXINFO", true},
+ {WM_SETFOCUS, "WM_SETFOCUS", true},
+ {WM_KILLFOCUS, "WM_KILLFOCUS", true},
+ {WM_ENABLE, "WM_ENABLE", true},
+ {WM_SHOWWINDOW, "WM_SHOWWINDOW", true},
+ {WM_GETMINMAXINFO, "WM_GETMINMAXINFO"},
+ {WM_WINDOWPOSCHANGING, "WM_WINDOWPOSCHANGING", true},
+ {WM_WINDOWPOSCHANGED, "WM_WINDOWPOSCHANGED", true},
+ {WM_SETCURSOR, "WM_SETCURSOR", false},
+ {WM_GETFONT, "WM_GETFONT", true},
+ {WM_NCMOUSEMOVE, "WM_NCMOUSEMOVE", true},
+ {WM_LBUTTONDOWN, "WM_LBUTTONDOWN", true},
+ {WM_LBUTTONUP, "WM_LBUTTONUP", true},
+ {WM_LBUTTONDBLCLK, "WM_LBUTTONDBLCLK", true},
+ {WM_RBUTTONDOWN, "WM_RBUTTONDOWN", true},
+ {WM_RBUTTONUP, "WM_RBUTTONUP", true},
+ {WM_RBUTTONDBLCLK, "WM_RBUTTONDBLCLK", true},
+ {WM_MBUTTONDOWN, "WM_MBUTTONDOWN", true},
+ {WM_MBUTTONUP, "WM_MBUTTONUP", true},
+ {WM_MBUTTONDBLCLK, "WM_MBUTTONDBLCLK", true},
+ {WM_MOUSEWHEEL, "WM_MOUSEWHEEL", true},
+ {WM_XBUTTONDOWN, "WM_XBUTTONDOWN", true},
+ {WM_XBUTTONUP, "WM_XBUTTONUP", true},
+ {WM_XBUTTONDBLCLK, "WM_XBUTTONDBLCLK", true},
+ {WM_MOUSEHWHEEL, "WM_MOUSEHWHEEL", true},
+ {WM_NCCREATE, "WM_NCCREATE", true},
+ {WM_NCCALCSIZE, "WM_NCCALCSIZE", true},
+ {WM_NCACTIVATE, "WM_NCACTIVATE", true},
+ {WM_NCMOUSELEAVE, "WM_NCMOUSELEAVE", true},
+ {WM_NCLBUTTONDOWN, "WM_NCLBUTTONDOWN", true},
+ {WM_NCLBUTTONUP, "WM_NCLBUTTONUP", true},
+ {WM_ACTIVATEAPP, "WM_ACTIVATEAPP", true},
+ {WM_NCPAINT, "WM_NCPAINT", true},
+ {WM_ERASEBKGND, "WM_ERASEBKGND", true},
+ {WM_MOUSEMOVE, "WM_MOUSEMOVE", true},
+ {WM_MOUSELEAVE, "WM_MOUSELEAVE", true},
+ {WM_NCHITTEST, "WM_NCHITTEST", false},
+ {WM_IME_SETCONTEXT, "WM_IME_SETCONTEXT", true},
+ {WM_INPUTLANGCHANGE, "WM_INPUTLANGCHANGE", true},
+ {WM_IME_NOTIFY, "WM_IME_NOTIFY", true},
+#if defined(WM_DWMNCRENDERINGCHANGED)
+ {WM_DWMNCRENDERINGCHANGED, "WM_DWMNCRENDERINGCHANGED", true},
+#endif
+ {WM_IME_SETCONTEXT, "WM_IME_SETCONTEXT", true},
+ {WM_IME_NOTIFY, "WM_IME_NOTIFY", true},
+ {WM_TOUCH, "WM_TOUCH", true},
+ {WM_CHANGECBCHAIN, "WM_CHANGECBCHAIN", true},
+ {WM_DRAWCLIPBOARD, "WM_DRAWCLIPBOARD", true},
+ {WM_RENDERFORMAT, "WM_RENDERFORMAT", true},
+ {WM_RENDERALLFORMATS, "WM_RENDERALLFORMATS", true},
+ {WM_DESTROYCLIPBOARD, "WM_DESTROYCLIPBOARD", true},
+ {WM_CAPTURECHANGED, "WM_CAPTURECHANGED", true},
+ {WM_IME_STARTCOMPOSITION, "WM_IME_STARTCOMPOSITION"},
+ {WM_IME_COMPOSITION, "WM_IME_COMPOSITION"},
+ {WM_IME_ENDCOMPOSITION, "WM_IME_ENDCOMPOSITION"},
+ {WM_IME_NOTIFY, "WM_IME_NOTIFY"},
+ {WM_IME_REQUEST, "WM_IME_REQUEST"}
+};
+
+static inline const MessageDebugEntry *messageDebugEntry(UINT msg)
+{
+ for (size_t i = 0; i < sizeof(messageDebugEntries)/sizeof(MessageDebugEntry); i++)
+ if (messageDebugEntries[i].message == msg)
+ return messageDebugEntries + i;
+ return 0;
+}
+
+const char *QWindowsGuiEventDispatcher::windowsMessageName(UINT msg)
+{
+ if (const MessageDebugEntry *e = messageDebugEntry(msg))
+ return e->description;
+ return "Unknown";
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsguieventdispatcher.h b/src/plugins/platforms/windows/qwindowsguieventdispatcher.h
new file mode 100644
index 0000000000..00fd234eff
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsguieventdispatcher.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSGUIEVENTDISPATCHER_H
+#define QWINDOWSGUIEVENTDISPATCHER_H
+
+#include "qtwindowsglobal.h"
+#include "qtwindows_additional.h"
+
+#include <QtCore/QPair>
+#include <QtCore/private/qeventdispatcher_win_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsGuiEventDispatcher : public QEventDispatcherWin32
+{
+ Q_OBJECT
+public:
+ explicit QWindowsGuiEventDispatcher(QObject *parent = 0);
+ ~QWindowsGuiEventDispatcher();
+
+ typedef QPair<QAbstractEventDispatcher *, QEventLoop::ProcessEventsFlags> DispatchContext;
+
+ static DispatchContext currentDispatchContext();
+
+ static const char *windowsMessageName(UINT msg);
+
+ virtual bool QT_ENSURE_STACK_ALIGNED_FOR_SSE processEvents(QEventLoop::ProcessEventsFlags flags);
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSGUIEVENTDISPATCHER_H
diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.cpp b/src/plugins/platforms/windows/qwindowsinputcontext.cpp
new file mode 100644
index 0000000000..e3dc100805
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsinputcontext.cpp
@@ -0,0 +1,598 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsinputcontext.h"
+#include "qwindowscontext.h"
+#include "qwindowswindow.h"
+#include "qwindowsintegration.h"
+#include "qwindowsmousehandler.h"
+
+#include <QtCore/QDebug>
+#include <QtCore/QObject>
+#include <QtCore/QRect>
+#include <QtCore/QTextBoundaryFinder>
+
+#include <QtGui/QInputMethodEvent>
+#include <QtGui/QTextCharFormat>
+#include <QtGui/QPalette>
+#include <QtGui/QGuiApplication>
+
+QT_BEGIN_NAMESPACE
+
+static inline QByteArray debugComposition(int lParam)
+{
+ QByteArray str;
+ if (lParam & GCS_RESULTSTR)
+ str += "RESULTSTR ";
+ if (lParam & GCS_COMPSTR)
+ str += "COMPSTR ";
+ if (lParam & GCS_COMPATTR)
+ str += "COMPATTR ";
+ if (lParam & GCS_CURSORPOS)
+ str += "CURSORPOS ";
+ if (lParam & GCS_COMPCLAUSE)
+ str += "COMPCLAUSE ";
+ if (lParam & CS_INSERTCHAR)
+ str += "INSERTCHAR ";
+ if (lParam & CS_NOMOVECARET)
+ str += "NOMOVECARET ";
+ return str;
+}
+
+// Cancel current IME composition.
+static inline void imeNotifyCancelComposition(HWND hwnd)
+{
+ const HIMC himc = ImmGetContext(hwnd);
+ ImmNotifyIME(himc, NI_COMPOSITIONSTR, CPS_CANCEL, 0);
+ ImmReleaseContext(hwnd, himc);
+}
+
+// Query a QObject for an InputMethod-related value
+// by sending a QInputMethodQueryEvent.
+template <class T>
+ bool inputMethodQuery(QObject *fo, Qt::InputMethodQuery query, T *result)
+{
+ QInputMethodQueryEvent queryEvent(query);
+ if (!QCoreApplication::sendEvent(fo, &queryEvent))
+ return false;
+ *result = qvariant_cast<T>(queryEvent.value());
+ return true;
+}
+
+/*!
+ \class QWindowsInputContext
+ \brief Windows Input context implementation
+
+ Handles input of foreign characters (particularly East Asian)
+ languages.
+
+ \section1 Testing
+
+ \list
+ \o Install the East Asian language support and choose Japanese (say).
+ \o Compile the \a mainwindows/mdi example and open a text window.
+ \o In the language bar, switch to Japanese and choose the
+ Input method 'Hiragana'.
+ \o In a text editor control, type the syllable \a 'la'.
+ Underlined characters show up, indicating that there is completion
+ available. Press the Space key two times. A completion popup occurs
+ which shows the options.
+ \endlist
+
+ Reconversion: Input texts can be 'converted' into different
+ input modes or more completion suggestions can be made based on
+ context to correct errors. This is bound to the 'Conversion key'
+ (F13-key in Japanese, which can be changed in the
+ configuration). After writing text, pressing the key selects text
+ and triggers a conversion popup, which shows the alternatives for
+ the word.
+
+ \section1 Interaction
+
+ When the user activates input methods, Windows sends
+ WM_IME_STARTCOMPOSITION, WM_IME_COMPOSITION,
+ WM_IME_ENDCOMPOSITION messages that trigger startComposition(),
+ composition(), endComposition(), respectively. No key events are sent.
+
+ composition() determines the markup of the pre-edit or selected
+ text and/or the final text and sends that to the focus object.
+
+ In between startComposition(), endComposition(), multiple
+ compositions may happen (isComposing).
+
+ update() is called to synchronize the position of the candidate
+ window with the microfocus rectangle of the focus object.
+ Also, a hidden caret is moved along with that position,
+ which is important for some Chinese input methods.
+
+ reset() is called to cancel a composition if the mouse is
+ moved outside or for example some Undo/Redo operation is
+ invoked.
+
+ \note Mouse interaction of popups with
+ QtWindows::InputMethodOpenCandidateWindowEvent and
+ QtWindows::InputMethodCloseCandidateWindowEvent
+ needs to be checked (mouse grab might interfere with candidate window).
+
+ \ingroup qt-lighthouse-win
+*/
+
+QWindowsInputContext::CompositionContext::CompositionContext() :
+ hwnd(0), haveCaret(false), position(0), isComposing(false)
+{
+}
+
+QWindowsInputContext::QWindowsInputContext() :
+ m_WM_MSIME_MOUSE(RegisterWindowMessage(L"MSIMEMouseOperation")),
+ m_endCompositionRecursionGuard(false)
+{
+}
+
+QWindowsInputContext::~QWindowsInputContext()
+{
+}
+
+/*!
+ \brief Cancels a composition.
+*/
+
+void QWindowsInputContext::reset()
+{
+ QPlatformInputContext::reset();
+ if (!m_compositionContext.hwnd)
+ return;
+ QObject *fo = focusObject();
+ if (QWindowsContext::verboseInputMethods)
+ qDebug() << __FUNCTION__<< fo;
+ if (!fo)
+ return;
+ if (m_compositionContext.isComposing) {
+ QInputMethodEvent event;
+ if (!m_compositionContext.composition.isEmpty())
+ event.setCommitString(m_compositionContext.composition);
+ QCoreApplication::sendEvent(fo, &event);
+ endContextComposition();
+ }
+ imeNotifyCancelComposition(m_compositionContext.hwnd);
+ doneContext();
+}
+
+/*!
+ \brief Moves the candidate window along with microfocus of the focus object.
+*/
+
+void QWindowsInputContext::update()
+{
+ QPlatformInputContext::update();
+ if (!m_compositionContext.hwnd)
+ return;
+ QObject *fo = focusObject();
+ if (!fo)
+ return;
+ const HIMC himc = ImmGetContext(m_compositionContext.hwnd);
+ if (!himc)
+ return;
+ // Move candidate list window to the microfocus position.
+ QRect globalMicroFocusRect;
+ if (!inputMethodQuery(fo, Qt::ImCursorRectangle, &globalMicroFocusRect) || !globalMicroFocusRect.isValid())
+ return;
+ if (QWindowsContext::verboseInputMethods)
+ qDebug() << __FUNCTION__ << himc << globalMicroFocusRect;
+
+ if (globalMicroFocusRect.isValid()) {
+ const QRect microFocusRect(QWindowsGeometryHint::mapFromGlobal(m_compositionContext.hwnd,
+ globalMicroFocusRect.topLeft()),
+ globalMicroFocusRect.size());
+ COMPOSITIONFORM cf;
+ // ### need X-like inputStyle config settings
+ cf.dwStyle = CFS_FORCE_POSITION;
+ cf.ptCurrentPos.x = microFocusRect.x();
+ cf.ptCurrentPos.y = microFocusRect.y();
+
+ CANDIDATEFORM candf;
+ candf.dwIndex = 0;
+ candf.dwStyle = CFS_EXCLUDE;
+ candf.ptCurrentPos.x = microFocusRect.x();
+ candf.ptCurrentPos.y = microFocusRect.y() + microFocusRect.height();
+ candf.rcArea.left = microFocusRect.x();
+ candf.rcArea.top = microFocusRect.y();
+ candf.rcArea.right = microFocusRect.x() + microFocusRect.width();
+ candf.rcArea.bottom = microFocusRect.y() + microFocusRect.height();
+
+ if (m_compositionContext.haveCaret)
+ SetCaretPos(microFocusRect.x(), microFocusRect.y());
+
+ ImmSetCompositionWindow(himc, &cf);
+ ImmSetCandidateWindow(himc, &candf);
+ }
+ ImmReleaseContext(m_compositionContext.hwnd, himc);
+}
+
+void QWindowsInputContext::mouseHandler(int pos, QMouseEvent *event)
+{
+ if (event->type() != QEvent::MouseButtonPress || !m_compositionContext.hwnd)
+ return;
+ if (QWindowsContext::verboseInputMethods)
+ qDebug() << __FUNCTION__ << pos << event;
+
+ if (pos < 0 || pos > m_compositionContext.composition.size())
+ reset();
+
+ // Magic code that notifies Japanese IME about the cursor
+ // position.
+ const DWORD button = QWindowsMouseHandler::mouseButtonsToKeyState(event->buttons());
+ const HIMC himc = ImmGetContext(m_compositionContext.hwnd);
+ const HWND imeWindow = ImmGetDefaultIMEWnd(m_compositionContext.hwnd);
+ SendMessage(imeWindow, m_WM_MSIME_MOUSE, MAKELONG(MAKEWORD(button, pos == 0 ? 2 : 1), pos), (LPARAM)himc);
+ ImmReleaseContext(m_compositionContext.hwnd, himc);
+}
+
+void QWindowsInputContext::setFocusObject(QObject *object)
+{
+ if (QWindowsContext::verboseInputMethods)
+ qDebug() << __FUNCTION__ << object;
+
+ QPlatformInputContext::setFocusObject(object);
+}
+
+QWindowsInputContext *QWindowsInputContext::instance()
+{
+ return static_cast<QWindowsInputContext *>(QWindowsIntegration::instance()->inputContext());
+}
+
+static inline QString getCompositionString(HIMC himc, DWORD dwIndex)
+{
+ enum { bufferSize = 256 };
+ wchar_t buffer[bufferSize];
+ const int length = ImmGetCompositionString(himc, dwIndex, buffer, bufferSize * sizeof(wchar_t));
+ return QString::fromWCharArray(buffer, length / sizeof(wchar_t));
+}
+
+// Determine the converted string range as pair of start/length to be selected.
+static inline void getCompositionStringConvertedRange(HIMC himc, int *selStart, int *selLength)
+{
+ enum { bufferSize = 256 };
+ // Find the range of bytes with ATTR_TARGET_CONVERTED set.
+ char attrBuffer[bufferSize];
+ *selStart = *selLength = 0;
+ if (const int attrLength = ImmGetCompositionString(himc, GCS_COMPATTR, attrBuffer, bufferSize)) {
+ int start = 0;
+ while (start < attrLength && !(attrBuffer[start] & ATTR_TARGET_CONVERTED))
+ start++;
+ if (start < attrLength) {
+ int end = start + 1;
+ while (end < attrLength && (attrBuffer[end] & ATTR_TARGET_CONVERTED))
+ end++;
+ *selStart = start;
+ *selLength = end - start;
+ }
+ }
+}
+
+enum StandardFormat {
+ PreeditFormat,
+ SelectionFormat
+};
+
+static inline QTextFormat standardFormat(StandardFormat format)
+{
+ QTextCharFormat result;
+ switch (format) {
+ case PreeditFormat:
+ result.setUnderlineStyle(QTextCharFormat::DashUnderline);
+ break;
+ case SelectionFormat: {
+ // TODO: Should be that of the widget?
+ const QPalette palette = QGuiApplication::palette();
+ const QColor background = palette.text().color();
+ result.setBackground(QBrush(background));
+ result.setForeground(palette.background());
+ break;
+ }
+ }
+ return result;
+}
+
+bool QWindowsInputContext::startComposition(HWND hwnd)
+{
+ const QObject *fo = focusObject();
+ if (!fo)
+ return false;
+ // This should always match the object.
+ QWindow *window = QGuiApplication::activeWindow();
+ if (!window)
+ return false;
+ if (QWindowsContext::verboseInputMethods)
+ qDebug() << __FUNCTION__ << fo << window;
+ if (!fo || QWindowsWindow::handleOf(window) != hwnd)
+ return false;
+ initContext(hwnd);
+ startContextComposition();
+ return true;
+}
+
+void QWindowsInputContext::startContextComposition()
+{
+ if (m_compositionContext.isComposing) {
+ qWarning("%s: Called out of sequence.", __FUNCTION__);
+ return;
+ }
+ m_compositionContext.isComposing = true;
+ m_compositionContext.composition.clear();
+ m_compositionContext.position = 0;
+ update();
+}
+
+void QWindowsInputContext::endContextComposition()
+{
+ if (!m_compositionContext.isComposing) {
+ qWarning("%s: Called out of sequence.", __FUNCTION__);
+ return;
+ }
+ m_compositionContext.composition.clear();
+ m_compositionContext.position = 0;
+ m_compositionContext.isComposing = false;
+}
+
+// Create a list of markup attributes for QInputMethodEvent
+// to display the selected part of the intermediate composition
+// result differently.
+static inline QList<QInputMethodEvent::Attribute>
+ intermediateMarkup(int position, int compositionLength,
+ int selStart, int selLength)
+{
+ QList<QInputMethodEvent::Attribute> attributes;
+ if (selStart > 0)
+ attributes << QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, 0, selStart,
+ standardFormat(PreeditFormat));
+ if (selLength)
+ attributes << QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, selStart, selLength,
+ standardFormat(SelectionFormat));
+ if (selStart + selLength < compositionLength)
+ attributes << QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, selStart + selLength,
+ compositionLength - selStart - selLength,
+ standardFormat(PreeditFormat));
+ if (position >= 0)
+ attributes << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, position, selLength ? 0 : 1, QVariant());
+ return attributes;
+}
+
+/*!
+ \brief Notify focus object about markup or final text.
+*/
+
+bool QWindowsInputContext::composition(HWND hwnd, LPARAM lParamIn)
+{
+ QObject *fo = focusObject();
+ const int lParam = int(lParamIn);
+ if (QWindowsContext::verboseInputMethods)
+ qDebug() << '>' << __FUNCTION__ << fo << debugComposition(lParam)
+ << " composing=" << m_compositionContext.isComposing;
+ if (!fo || m_compositionContext.hwnd != hwnd || !lParam)
+ return false;
+ const HIMC himc = ImmGetContext(m_compositionContext.hwnd);
+ if (!himc)
+ return false;
+
+ QScopedPointer<QInputMethodEvent> event;
+ if (lParam & (GCS_COMPSTR | GCS_COMPATTR | GCS_CURSORPOS)) {
+ if (!m_compositionContext.isComposing)
+ startContextComposition();
+ // Some intermediate composition result. Parametrize event with
+ // attribute sequence specifying the formatting of the converted part.
+ int selStart, selLength;
+ m_compositionContext.composition = getCompositionString(himc, GCS_COMPSTR);
+ m_compositionContext.position = ImmGetCompositionString(himc, GCS_CURSORPOS, 0, 0);
+ getCompositionStringConvertedRange(himc, &selStart, &selLength);
+ if ((lParam & CS_INSERTCHAR) && (lParam & CS_NOMOVECARET)) {
+ // make Korean work correctly. Hope this is correct for all IMEs
+ selStart = 0;
+ selLength = m_compositionContext.composition.size();
+ }
+ if (!selLength)
+ selStart = 0;
+
+ event.reset(new QInputMethodEvent(m_compositionContext.composition,
+ intermediateMarkup(m_compositionContext.position,
+ m_compositionContext.composition.size(),
+ selStart, selLength)));
+ }
+ if (event.isNull())
+ event.reset(new QInputMethodEvent);
+
+ if (lParam & GCS_RESULTSTR) {
+ // A fixed result, return the converted string
+ event->setCommitString(getCompositionString(himc, GCS_RESULTSTR));
+ endContextComposition();
+ }
+ const bool result = QCoreApplication::sendEvent(fo, event.data());
+ if (QWindowsContext::verboseInputMethods)
+ qDebug() << '<' << __FUNCTION__ << "sending markup="
+ << event->attributes().size()
+ << " commit=" << event->commitString()
+ << " to " << fo << " returns " << result;
+ update();
+ ImmReleaseContext(m_compositionContext.hwnd, himc);
+ return result;
+}
+
+bool QWindowsInputContext::endComposition(HWND hwnd)
+{
+ if (QWindowsContext::verboseInputMethods)
+ qDebug() << __FUNCTION__ << m_endCompositionRecursionGuard << hwnd;
+ // Googles Pinyin Input Method likes to call endComposition again
+ // when we call notifyIME with CPS_CANCEL, so protect ourselves
+ // against that.
+ if (m_endCompositionRecursionGuard || m_compositionContext.hwnd != hwnd)
+ return false;
+ QObject *fo = focusObject();
+ if (!fo)
+ return false;
+
+ m_endCompositionRecursionGuard = true;
+
+ imeNotifyCancelComposition(m_compositionContext.hwnd);
+ if (m_compositionContext.isComposing) {
+ QInputMethodEvent event;
+ QCoreApplication::sendEvent(fo, &event);
+ }
+ doneContext();
+
+ m_endCompositionRecursionGuard = false;
+ return true;
+}
+
+void QWindowsInputContext::initContext(HWND hwnd)
+{
+ if (m_compositionContext.hwnd)
+ doneContext();
+ m_compositionContext.hwnd = hwnd;
+ // Create a hidden caret which is kept at the microfocus
+ // position in update(). This is important for some
+ // Chinese input methods.
+ m_compositionContext.haveCaret = CreateCaret(hwnd, 0, 1, 1);
+ HideCaret(hwnd);
+ update();
+ m_compositionContext.isComposing = false;
+ m_compositionContext.position = 0;
+}
+
+void QWindowsInputContext::doneContext()
+{
+ if (!m_compositionContext.hwnd)
+ return;
+ if (m_compositionContext.haveCaret)
+ DestroyCaret();
+ m_compositionContext.hwnd = 0;
+ m_compositionContext.composition.clear();
+ m_compositionContext.position = 0;
+ m_compositionContext.isComposing = m_compositionContext.haveCaret = false;
+}
+
+bool QWindowsInputContext::handleIME_Request(WPARAM wParam,
+ LPARAM lParam,
+ LRESULT *result)
+{
+ switch (int(wParam)) {
+ case IMR_RECONVERTSTRING: {
+ const int size = reconvertString(reinterpret_cast<RECONVERTSTRING *>(lParam));
+ if (size < 0)
+ return false;
+ *result = size;
+ return true;
+ }
+ break;
+ case IMR_CONFIRMRECONVERTSTRING:
+ return true;
+ default:
+ break;
+ }
+ return false;
+}
+
+/*!
+ \brief Determines the string for reconversion with selection.
+
+ This is triggered twice by WM_IME_REQUEST, first with reconv=0
+ to determine the length and later with a reconv struct to obtain
+ the string with the position of the selection to be reconverted.
+
+ Obtains the text from the focus object and marks the word
+ for selection (might not be entirely correct for Japanese).
+*/
+
+int QWindowsInputContext::reconvertString(RECONVERTSTRING *reconv)
+{
+ QObject *fo = focusObject();
+ if (!fo)
+ return false;
+
+ QString surroundingText;
+ if (!inputMethodQuery(fo, Qt::ImSurroundingText, &surroundingText))
+ return -1;
+ const DWORD memSize = sizeof(RECONVERTSTRING)
+ + (surroundingText.length() + 1) * sizeof(ushort);
+ if (QWindowsContext::verboseInputMethods)
+ qDebug() << __FUNCTION__ << " reconv=" << reconv
+ << " surroundingText=" << surroundingText
+ << " size=" << memSize;
+ // If memory is not allocated, return the required size.
+ if (!reconv)
+ return surroundingText.isEmpty() ? -1 : int(memSize);
+
+ int pos = 0;
+ inputMethodQuery(fo, Qt::ImCursorPosition, &pos);
+ // Find the word in the surrounding text.
+ QTextBoundaryFinder bounds(QTextBoundaryFinder::Word, surroundingText);
+ bounds.setPosition(pos);
+ if (bounds.isAtBoundary()) {
+ if (QTextBoundaryFinder::EndWord == bounds.boundaryReasons())
+ bounds.toPreviousBoundary();
+ } else {
+ bounds.toPreviousBoundary();
+ }
+ const int startPos = bounds.position();
+ bounds.toNextBoundary();
+ const int endPos = bounds.position();
+ if (QWindowsContext::verboseInputMethods)
+ qDebug() << __FUNCTION__ << " boundary=" << startPos << endPos;
+ // Select the text, this will be overwritten by following IME events.
+ QList<QInputMethodEvent::Attribute> attributes;
+ attributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, startPos, endPos-startPos, QVariant());
+ QInputMethodEvent selectEvent(QString(), attributes);
+ QCoreApplication::sendEvent(fo, &selectEvent);
+
+ reconv->dwSize = memSize;
+ reconv->dwVersion = 0;
+
+ reconv->dwStrLen = surroundingText.size();
+ reconv->dwStrOffset = sizeof(RECONVERTSTRING);
+ reconv->dwCompStrLen = endPos - startPos; // TCHAR count.
+ reconv->dwCompStrOffset = startPos * sizeof(ushort); // byte count.
+ reconv->dwTargetStrLen = reconv->dwCompStrLen;
+ reconv->dwTargetStrOffset = reconv->dwCompStrOffset;
+ ushort *pastReconv = reinterpret_cast<ushort *>(reconv + 1);
+ qCopy(surroundingText.utf16(), surroundingText.utf16() + surroundingText.size(),
+ pastReconv);
+ return memSize;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.h b/src/plugins/platforms/windows/qwindowsinputcontext.h
new file mode 100644
index 0000000000..8ea66774d4
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsinputcontext.h
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSINPUTCONTEXT_H
+#define QWINDOWSINPUTCONTEXT_H
+
+#include "qtwindows_additional.h"
+
+#include <QtGui/QPlatformInputContext>
+
+QT_BEGIN_NAMESPACE
+
+class QInputMethodEvent;
+
+class QWindowsInputContext : public QPlatformInputContext
+{
+ struct CompositionContext
+ {
+ CompositionContext();
+
+ HWND hwnd;
+ bool haveCaret;
+ QString composition;
+ int position;
+ bool isComposing;
+ };
+public:
+ explicit QWindowsInputContext();
+ ~QWindowsInputContext();
+
+ virtual void reset();
+ virtual void update();
+
+ virtual void mouseHandler(int x, QMouseEvent *event);
+ virtual void setFocusObject(QObject *o);
+
+ static QWindowsInputContext *instance();
+
+ bool startComposition(HWND hwnd);
+ bool composition(HWND hwnd, LPARAM lParam);
+ bool endComposition(HWND hwnd);
+
+ int reconvertString(RECONVERTSTRING *reconv);
+
+ bool handleIME_Request(WPARAM wparam, LPARAM lparam, LRESULT *result);
+
+private:
+ void initContext(HWND hwnd);
+ void doneContext();
+ void startContextComposition();
+ void endContextComposition();
+
+ const DWORD m_WM_MSIME_MOUSE;
+ CompositionContext m_compositionContext;
+ bool m_endCompositionRecursionGuard;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSINPUTCONTEXT_H
diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp
new file mode 100644
index 0000000000..cde6da671a
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsintegration.cpp
@@ -0,0 +1,271 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsintegration.h"
+#include "qwindowsbackingstore.h"
+#include "qwindowswindow.h"
+#include "qwindowscontext.h"
+#include "qwindowsglcontext.h"
+#include "qwindowsscreen.h"
+#include "qwindowsfontdatabase.h"
+#include "qwindowsguieventdispatcher.h"
+#include "qwindowsclipboard.h"
+#include "qwindowsdrag.h"
+#include "qwindowsinputcontext.h"
+
+#include <QtGui/QPlatformNativeInterface>
+#include <QtGui/QWindowSystemInterface>
+#include <QtGui/QBackingStore>
+#include <QtGui/private/qpixmap_raster_p.h>
+#include <QtGui/private/qguiapplication_p.h>
+
+#include <QtCore/private/qeventdispatcher_win_p.h>
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QWindowsNativeInterface
+ \brief Provides access to native handles.
+
+ Currently implemented keys
+ \list
+ \o handle (HWND)
+ \o getDC (DC)
+ \o releaseDC Releases the previously acquired DC and returns 0.
+ \endlist
+
+ \ingroup qt-lighthouse-win
+*/
+
+class QWindowsNativeInterface : public QPlatformNativeInterface
+{
+public:
+ virtual void *nativeResourceForWindow(const QByteArray &resource, QWindow *window);
+ virtual void *nativeResourceForBackingStore(const QByteArray &resource, QBackingStore *bs);
+};
+
+void *QWindowsNativeInterface::nativeResourceForWindow(const QByteArray &resource, QWindow *window)
+{
+ if (!window || !window->handle()) {
+ qWarning("%s: '%s' requested for null window or window without handle.", __FUNCTION__, resource.constData());
+ return 0;
+ }
+ QWindowsWindow *bw = static_cast<QWindowsWindow *>(window->handle());
+ if (resource == "handle")
+ return bw->handle();
+ if (window->surfaceType() == QWindow::RasterSurface) {
+ if (resource == "getDC")
+ return bw->getDC();
+ if (resource == "releaseDC") {
+ bw->releaseDC();
+ return 0;
+ }
+ }
+ qWarning("%s: Invalid key '%s' requested.", __FUNCTION__, resource.constData());
+ return 0;
+}
+
+void *QWindowsNativeInterface::nativeResourceForBackingStore(const QByteArray &resource, QBackingStore *bs)
+{
+ if (!bs || !bs->handle()) {
+ qWarning("%s: '%s' requested for null backingstore or backingstore without handle.", __FUNCTION__, resource.constData());
+ return 0;
+ }
+ QWindowsBackingStore *wbs = static_cast<QWindowsBackingStore *>(bs->handle());
+ if (resource == "getDC")
+ return wbs->getDC();
+ qWarning("%s: Invalid key '%s' requested.", __FUNCTION__, resource.constData());
+ return 0;
+}
+
+/*!
+ \class QWindowsIntegration
+ \brief QPlatformIntegration implementation for Windows.
+ \ingroup qt-lighthouse-win
+*/
+
+struct QWindowsIntegrationPrivate
+{
+ typedef QSharedPointer<QOpenGLStaticContext> QOpenGLStaticContextPtr;
+
+ explicit QWindowsIntegrationPrivate(bool openGL);
+
+ const bool m_openGL;
+ QWindowsContext m_context;
+ QWindowsFontDatabase m_fontDatabase;
+ QWindowsNativeInterface m_nativeInterface;
+ QWindowsClipboard m_clipboard;
+ QWindowsDrag m_drag;
+ QWindowsGuiEventDispatcher *m_eventDispatcher;
+ QOpenGLStaticContextPtr m_staticOpenGLContext;
+ QWindowsInputContext m_inputContext;
+};
+
+QWindowsIntegrationPrivate::QWindowsIntegrationPrivate(bool openGL)
+ : m_openGL(openGL)
+ , m_context(openGL)
+ , m_eventDispatcher(new QWindowsGuiEventDispatcher)
+{
+}
+
+QWindowsIntegration::QWindowsIntegration(bool openGL) :
+ d(new QWindowsIntegrationPrivate(openGL))
+{
+ QGuiApplicationPrivate::instance()->setEventDispatcher(d->m_eventDispatcher);
+ d->m_clipboard.registerViewer();
+ foreach (QPlatformScreen *pscr, QWindowsScreen::screens())
+ screenAdded(pscr);
+}
+
+QWindowsIntegration::~QWindowsIntegration()
+{
+ if (QWindowsContext::verboseIntegration)
+ qDebug("%s", __FUNCTION__);
+}
+
+bool QWindowsIntegration::hasCapability(QPlatformIntegration::Capability cap) const
+{
+ switch (cap) {
+ case ThreadedPixmaps:
+ return true;
+ case OpenGL:
+ return true;
+ case ThreadedOpenGL:
+ return true;
+ default:
+ return QPlatformIntegration::hasCapability(cap);
+ }
+ return false;
+}
+
+QPlatformPixmap *QWindowsIntegration::createPlatformPixmap(QPlatformPixmap::PixelType type) const
+{
+ if (QWindowsContext::verboseIntegration)
+ qDebug() << __FUNCTION__ << type;
+ return new QRasterPlatformPixmap(type);
+}
+
+QPlatformWindow *QWindowsIntegration::createPlatformWindow(QWindow *window) const
+{
+ const bool isGL = window->surfaceType() == QWindow::OpenGLSurface;
+ QWindowsWindow::WindowData requested;
+ requested.flags = window->windowFlags();
+ requested.geometry = window->geometry();
+ const QWindowsWindow::WindowData obtained
+ = QWindowsWindow::WindowData::create(window, requested, window->windowTitle(), isGL);
+ if (QWindowsContext::verboseIntegration || QWindowsContext::verboseWindows)
+ qDebug().nospace()
+ << __FUNCTION__ << ' ' << window << '\n'
+ << " Requested: " << requested.geometry << " Flags="
+ << QWindowsWindow::debugWindowFlags(requested.flags) << '\n'
+ << " Obtained : " << obtained.geometry << " Margins "
+ << obtained.frame << " Flags="
+ << QWindowsWindow::debugWindowFlags(obtained.flags)
+ << " Handle=" << obtained.hwnd << '\n';
+ if (!obtained.hwnd)
+ return 0;
+ if (requested.flags != obtained.flags)
+ window->setWindowFlags(obtained.flags);
+ if (requested.geometry != obtained.geometry)
+ QWindowSystemInterface::handleGeometryChange(window, obtained.geometry);
+ return new QWindowsWindow(window, obtained);
+}
+
+QPlatformBackingStore *QWindowsIntegration::createPlatformBackingStore(QWindow *window) const
+{
+ if (QWindowsContext::verboseIntegration)
+ qDebug() << __FUNCTION__ << window;
+ return new QWindowsBackingStore(window);
+}
+
+QPlatformOpenGLContext
+ *QWindowsIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
+{
+ if (QWindowsContext::verboseIntegration)
+ qDebug() << __FUNCTION__ << context->format();
+ if (d->m_staticOpenGLContext.isNull())
+ d->m_staticOpenGLContext =
+ QSharedPointer<QOpenGLStaticContext>(QOpenGLStaticContext::create());
+ QScopedPointer<QWindowsGLContext> result(new QWindowsGLContext(d->m_staticOpenGLContext, context));
+ if (result->isValid())
+ return result.take();
+ return 0;
+}
+
+QPlatformFontDatabase *QWindowsIntegration::fontDatabase() const
+{
+ return &d->m_fontDatabase;
+}
+
+QPlatformNativeInterface *QWindowsIntegration::nativeInterface() const
+{
+ return &d->m_nativeInterface;
+}
+
+QPlatformClipboard * QWindowsIntegration::clipboard() const
+{
+ return &d->m_clipboard;
+}
+
+QPlatformDrag *QWindowsIntegration::drag() const
+{
+ if (QWindowsContext::verboseIntegration)
+ qDebug("%s", __FUNCTION__ );
+ return &d->m_drag;
+}
+
+QPlatformInputContext * QWindowsIntegration::inputContext() const
+{
+ return &d->m_inputContext;
+}
+
+QWindowsIntegration *QWindowsIntegration::instance()
+{
+ return static_cast<QWindowsIntegration *>(QGuiApplicationPrivate::platformIntegration());
+}
+
+QAbstractEventDispatcher * QWindowsIntegration::guiThreadEventDispatcher() const
+{
+ return d->m_eventDispatcher;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsintegration.h b/src/plugins/platforms/windows/qwindowsintegration.h
new file mode 100644
index 0000000000..14a65c67e0
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsintegration.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSINTEGRATION_H
+#define QWINDOWSINTEGRATION_H
+
+#include <QtGui/QPlatformIntegration>
+#include <QtCore/QScopedPointer>
+
+QT_BEGIN_NAMESPACE
+
+struct QWindowsIntegrationPrivate;
+
+class QWindowsIntegration : public QPlatformIntegration
+{
+public:
+ QWindowsIntegration(bool openGL = false);
+ virtual ~QWindowsIntegration();
+
+ bool hasCapability(QPlatformIntegration::Capability cap) const;
+
+ virtual QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const;
+ QPlatformWindow *createPlatformWindow(QWindow *window) const;
+ QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const;
+ virtual QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const;
+ virtual QAbstractEventDispatcher *guiThreadEventDispatcher() const;
+
+ virtual QPlatformClipboard *clipboard() const;
+ virtual QPlatformDrag *drag() const;
+ virtual QPlatformInputContext *inputContext() const;
+ virtual QPlatformNativeInterface *nativeInterface() const;
+ virtual QPlatformFontDatabase *fontDatabase() const;
+
+ static QWindowsIntegration *instance();
+
+private:
+ QScopedPointer<QWindowsIntegrationPrivate> d;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/platforms/windows/qwindowsinternalmimedata.h b/src/plugins/platforms/windows/qwindowsinternalmimedata.h
new file mode 100644
index 0000000000..49fc69059b
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsinternalmimedata.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSINTERNALMIME_H
+#define QWINDOWSINTERNALMIME_H
+
+#include "qtwindows_additional.h"
+
+#include <QtGui/private/qdnd_p.h> // QInternalMime
+#include <QtCore/QVariant>
+
+QT_BEGIN_NAMESPACE
+
+class QDebug;
+
+// Implementation in qwindowsclipboard.cpp.
+class QWindowsInternalMimeData : public QInternalMimeData {
+public:
+ virtual bool hasFormat_sys(const QString &mimetype) const;
+ virtual QStringList formats_sys() const;
+ virtual QVariant retrieveData_sys(const QString &mimetype, QVariant::Type preferredType) const;
+
+protected:
+ virtual IDataObject *retrieveDataObject() const = 0;
+ virtual void releaseDataObject(IDataObject *) const {}
+};
+
+QDebug operator<<(QDebug d, const QMimeData &m);
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSINTERNALMIME_H
diff --git a/src/plugins/platforms/windows/qwindowskeymapper.cpp b/src/plugins/platforms/windows/qwindowskeymapper.cpp
new file mode 100644
index 0000000000..40613ea1f1
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowskeymapper.cpp
@@ -0,0 +1,1075 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowskeymapper.h"
+#include "qwindowscontext.h"
+#include "qwindowswindow.h"
+#include "qwindowsguieventdispatcher.h"
+
+#include <QtGui/QWindow>
+#include <QtGui/QWindowSystemInterface>
+#include <QtGui/QKeyEvent>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QWindowsKeyMapper
+ \brief Translates Windows keys to QWindowSystemInterface events.
+ \ingroup qt-lighthouse-win
+
+ In addition, handles some special keys to display system menus, etc.
+ The code originates from \c qkeymapper_win.cpp.
+*/
+
+QWindowsKeyMapper::QWindowsKeyMapper()
+ : m_useRTLExtensions(false), m_keyGrabber(0)
+{
+ memset(keyLayout, 0, sizeof(keyLayout));
+}
+
+QWindowsKeyMapper::~QWindowsKeyMapper()
+{
+ deleteLayouts();
+}
+
+#ifndef LANG_PASHTO
+#define LANG_PASHTO 0x63
+#endif
+#ifndef LANG_SYRIAC
+#define LANG_SYRIAC 0x5a
+#endif
+#ifndef LANG_DIVEHI
+#define LANG_DIVEHI 0x65
+#endif
+#ifndef VK_OEM_PLUS
+#define VK_OEM_PLUS 0xBB
+#endif
+#ifndef VK_OEM_3
+#define VK_OEM_3 0xC0
+#endif
+
+// Key recorder ------------------------------------------------------------------------[ start ] --
+struct KeyRecord {
+ KeyRecord(int c, int a, int s, const QString &t) : code(c), ascii(a), state(s), text(t) {}
+ KeyRecord() {}
+
+ int code;
+ int ascii;
+ int state;
+ QString text;
+};
+
+static const int QT_MAX_KEY_RECORDINGS = 64; // User has LOTS of fingers...
+struct KeyRecorder
+{
+ KeyRecorder() : nrecs(0) {}
+
+ inline KeyRecord *findKey(int code, bool remove);
+ inline void storeKey(int code, int ascii, int state, const QString& text);
+ inline void clearKeys();
+
+ int nrecs;
+ KeyRecord deleted_record; // A copy of last entry removed from records[]
+ KeyRecord records[QT_MAX_KEY_RECORDINGS];
+};
+static KeyRecorder key_recorder;
+
+KeyRecord *KeyRecorder::findKey(int code, bool remove)
+{
+ KeyRecord *result = 0;
+ for (int i = 0; i < nrecs; ++i) {
+ if (records[i].code == code) {
+ if (remove) {
+ deleted_record = records[i];
+ // Move rest down, and decrease count
+ while (i + 1 < nrecs) {
+ records[i] = records[i + 1];
+ ++i;
+ }
+ --nrecs;
+ result = &deleted_record;
+ } else {
+ result = &records[i];
+ }
+ break;
+ }
+ }
+ return result;
+}
+
+void KeyRecorder::storeKey(int code, int ascii, int state, const QString& text)
+{
+ Q_ASSERT_X(nrecs != QT_MAX_KEY_RECORDINGS,
+ "Internal KeyRecorder",
+ "Keyboard recorder buffer overflow, consider increasing QT_MAX_KEY_RECORDINGS");
+
+ if (nrecs == QT_MAX_KEY_RECORDINGS) {
+ qWarning("Qt: Internal keyboard buffer overflow");
+ return;
+ }
+ records[nrecs++] = KeyRecord(code,ascii,state,text);
+}
+
+void KeyRecorder::clearKeys()
+{
+ nrecs = 0;
+}
+// Key recorder --------------------------------------------------------------------------[ end ] --
+
+
+// Key translation ---------------------------------------------------------------------[ start ] --
+// Meaning of values:
+// 0 = Character output key, needs keyboard driver mapping
+// Key_unknown = Unknown Virtual Key, no translation possible, ignore
+static const uint KeyTbl[] = { // Keyboard mapping table
+ // Dec | Hex | Windows Virtual key
+ Qt::Key_unknown, // 0 0x00
+ Qt::Key_unknown, // 1 0x01 VK_LBUTTON | Left mouse button
+ Qt::Key_unknown, // 2 0x02 VK_RBUTTON | Right mouse button
+ Qt::Key_Cancel, // 3 0x03 VK_CANCEL | Control-Break processing
+ Qt::Key_unknown, // 4 0x04 VK_MBUTTON | Middle mouse button
+ Qt::Key_unknown, // 5 0x05 VK_XBUTTON1 | X1 mouse button
+ Qt::Key_unknown, // 6 0x06 VK_XBUTTON2 | X2 mouse button
+ Qt::Key_unknown, // 7 0x07 -- unassigned --
+ Qt::Key_Backspace, // 8 0x08 VK_BACK | BackSpace key
+ Qt::Key_Tab, // 9 0x09 VK_TAB | Tab key
+ Qt::Key_unknown, // 10 0x0A -- reserved --
+ Qt::Key_unknown, // 11 0x0B -- reserved --
+ Qt::Key_Clear, // 12 0x0C VK_CLEAR | Clear key
+ Qt::Key_Return, // 13 0x0D VK_RETURN | Enter key
+ Qt::Key_unknown, // 14 0x0E -- unassigned --
+ Qt::Key_unknown, // 15 0x0F -- unassigned --
+ Qt::Key_Shift, // 16 0x10 VK_SHIFT | Shift key
+ Qt::Key_Control, // 17 0x11 VK_CONTROL | Ctrl key
+ Qt::Key_Alt, // 18 0x12 VK_MENU | Alt key
+ Qt::Key_Pause, // 19 0x13 VK_PAUSE | Pause key
+ Qt::Key_CapsLock, // 20 0x14 VK_CAPITAL | Caps-Lock
+ Qt::Key_unknown, // 21 0x15 VK_KANA / VK_HANGUL | IME Kana or Hangul mode
+ Qt::Key_unknown, // 22 0x16 -- unassigned --
+ Qt::Key_unknown, // 23 0x17 VK_JUNJA | IME Junja mode
+ Qt::Key_unknown, // 24 0x18 VK_FINAL | IME final mode
+ Qt::Key_unknown, // 25 0x19 VK_HANJA / VK_KANJI | IME Hanja or Kanji mode
+ Qt::Key_unknown, // 26 0x1A -- unassigned --
+ Qt::Key_Escape, // 27 0x1B VK_ESCAPE | Esc key
+ Qt::Key_unknown, // 28 0x1C VK_CONVERT | IME convert
+ Qt::Key_unknown, // 29 0x1D VK_NONCONVERT | IME non-convert
+ Qt::Key_unknown, // 30 0x1E VK_ACCEPT | IME accept
+ Qt::Key_Mode_switch,// 31 0x1F VK_MODECHANGE | IME mode change request
+ Qt::Key_Space, // 32 0x20 VK_SPACE | Spacebar
+ Qt::Key_PageUp, // 33 0x21 VK_PRIOR | Page Up key
+ Qt::Key_PageDown, // 34 0x22 VK_NEXT | Page Down key
+ Qt::Key_End, // 35 0x23 VK_END | End key
+ Qt::Key_Home, // 36 0x24 VK_HOME | Home key
+ Qt::Key_Left, // 37 0x25 VK_LEFT | Left arrow key
+ Qt::Key_Up, // 38 0x26 VK_UP | Up arrow key
+ Qt::Key_Right, // 39 0x27 VK_RIGHT | Right arrow key
+ Qt::Key_Down, // 40 0x28 VK_DOWN | Down arrow key
+ Qt::Key_Select, // 41 0x29 VK_SELECT | Select key
+ Qt::Key_Printer, // 42 0x2A VK_PRINT | Print key
+ Qt::Key_Execute, // 43 0x2B VK_EXECUTE | Execute key
+ Qt::Key_Print, // 44 0x2C VK_SNAPSHOT | Print Screen key
+ Qt::Key_Insert, // 45 0x2D VK_INSERT | Ins key
+ Qt::Key_Delete, // 46 0x2E VK_DELETE | Del key
+ Qt::Key_Help, // 47 0x2F VK_HELP | Help key
+ 0, // 48 0x30 (VK_0) | 0 key
+ 0, // 49 0x31 (VK_1) | 1 key
+ 0, // 50 0x32 (VK_2) | 2 key
+ 0, // 51 0x33 (VK_3) | 3 key
+ 0, // 52 0x34 (VK_4) | 4 key
+ 0, // 53 0x35 (VK_5) | 5 key
+ 0, // 54 0x36 (VK_6) | 6 key
+ 0, // 55 0x37 (VK_7) | 7 key
+ 0, // 56 0x38 (VK_8) | 8 key
+ 0, // 57 0x39 (VK_9) | 9 key
+ Qt::Key_unknown, // 58 0x3A -- unassigned --
+ Qt::Key_unknown, // 59 0x3B -- unassigned --
+ Qt::Key_unknown, // 60 0x3C -- unassigned --
+ Qt::Key_unknown, // 61 0x3D -- unassigned --
+ Qt::Key_unknown, // 62 0x3E -- unassigned --
+ Qt::Key_unknown, // 63 0x3F -- unassigned --
+ Qt::Key_unknown, // 64 0x40 -- unassigned --
+ 0, // 65 0x41 (VK_A) | A key
+ 0, // 66 0x42 (VK_B) | B key
+ 0, // 67 0x43 (VK_C) | C key
+ 0, // 68 0x44 (VK_D) | D key
+ 0, // 69 0x45 (VK_E) | E key
+ 0, // 70 0x46 (VK_F) | F key
+ 0, // 71 0x47 (VK_G) | G key
+ 0, // 72 0x48 (VK_H) | H key
+ 0, // 73 0x49 (VK_I) | I key
+ 0, // 74 0x4A (VK_J) | J key
+ 0, // 75 0x4B (VK_K) | K key
+ 0, // 76 0x4C (VK_L) | L key
+ 0, // 77 0x4D (VK_M) | M key
+ 0, // 78 0x4E (VK_N) | N key
+ 0, // 79 0x4F (VK_O) | O key
+ 0, // 80 0x50 (VK_P) | P key
+ 0, // 81 0x51 (VK_Q) | Q key
+ 0, // 82 0x52 (VK_R) | R key
+ 0, // 83 0x53 (VK_S) | S key
+ 0, // 84 0x54 (VK_T) | T key
+ 0, // 85 0x55 (VK_U) | U key
+ 0, // 86 0x56 (VK_V) | V key
+ 0, // 87 0x57 (VK_W) | W key
+ 0, // 88 0x58 (VK_X) | X key
+ 0, // 89 0x59 (VK_Y) | Y key
+ 0, // 90 0x5A (VK_Z) | Z key
+ Qt::Key_Meta, // 91 0x5B VK_LWIN | Left Windows - MS Natural kbd
+ Qt::Key_Meta, // 92 0x5C VK_RWIN | Right Windows - MS Natural kbd
+ Qt::Key_Menu, // 93 0x5D VK_APPS | Application key-MS Natural kbd
+ Qt::Key_unknown, // 94 0x5E -- reserved --
+ Qt::Key_Sleep, // 95 0x5F VK_SLEEP
+ Qt::Key_0, // 96 0x60 VK_NUMPAD0 | Numeric keypad 0 key
+ Qt::Key_1, // 97 0x61 VK_NUMPAD1 | Numeric keypad 1 key
+ Qt::Key_2, // 98 0x62 VK_NUMPAD2 | Numeric keypad 2 key
+ Qt::Key_3, // 99 0x63 VK_NUMPAD3 | Numeric keypad 3 key
+ Qt::Key_4, // 100 0x64 VK_NUMPAD4 | Numeric keypad 4 key
+ Qt::Key_5, // 101 0x65 VK_NUMPAD5 | Numeric keypad 5 key
+ Qt::Key_6, // 102 0x66 VK_NUMPAD6 | Numeric keypad 6 key
+ Qt::Key_7, // 103 0x67 VK_NUMPAD7 | Numeric keypad 7 key
+ Qt::Key_8, // 104 0x68 VK_NUMPAD8 | Numeric keypad 8 key
+ Qt::Key_9, // 105 0x69 VK_NUMPAD9 | Numeric keypad 9 key
+ Qt::Key_Asterisk, // 106 0x6A VK_MULTIPLY | Multiply key
+ Qt::Key_Plus, // 107 0x6B VK_ADD | Add key
+ Qt::Key_Comma, // 108 0x6C VK_SEPARATOR | Separator key
+ Qt::Key_Minus, // 109 0x6D VK_SUBTRACT | Subtract key
+ Qt::Key_Period, // 110 0x6E VK_DECIMAL | Decimal key
+ Qt::Key_Slash, // 111 0x6F VK_DIVIDE | Divide key
+ Qt::Key_F1, // 112 0x70 VK_F1 | F1 key
+ Qt::Key_F2, // 113 0x71 VK_F2 | F2 key
+ Qt::Key_F3, // 114 0x72 VK_F3 | F3 key
+ Qt::Key_F4, // 115 0x73 VK_F4 | F4 key
+ Qt::Key_F5, // 116 0x74 VK_F5 | F5 key
+ Qt::Key_F6, // 117 0x75 VK_F6 | F6 key
+ Qt::Key_F7, // 118 0x76 VK_F7 | F7 key
+ Qt::Key_F8, // 119 0x77 VK_F8 | F8 key
+ Qt::Key_F9, // 120 0x78 VK_F9 | F9 key
+ Qt::Key_F10, // 121 0x79 VK_F10 | F10 key
+ Qt::Key_F11, // 122 0x7A VK_F11 | F11 key
+ Qt::Key_F12, // 123 0x7B VK_F12 | F12 key
+ Qt::Key_F13, // 124 0x7C VK_F13 | F13 key
+ Qt::Key_F14, // 125 0x7D VK_F14 | F14 key
+ Qt::Key_F15, // 126 0x7E VK_F15 | F15 key
+ Qt::Key_F16, // 127 0x7F VK_F16 | F16 key
+ Qt::Key_F17, // 128 0x80 VK_F17 | F17 key
+ Qt::Key_F18, // 129 0x81 VK_F18 | F18 key
+ Qt::Key_F19, // 130 0x82 VK_F19 | F19 key
+ Qt::Key_F20, // 131 0x83 VK_F20 | F20 key
+ Qt::Key_F21, // 132 0x84 VK_F21 | F21 key
+ Qt::Key_F22, // 133 0x85 VK_F22 | F22 key
+ Qt::Key_F23, // 134 0x86 VK_F23 | F23 key
+ Qt::Key_F24, // 135 0x87 VK_F24 | F24 key
+ Qt::Key_unknown, // 136 0x88 -- unassigned --
+ Qt::Key_unknown, // 137 0x89 -- unassigned --
+ Qt::Key_unknown, // 138 0x8A -- unassigned --
+ Qt::Key_unknown, // 139 0x8B -- unassigned --
+ Qt::Key_unknown, // 140 0x8C -- unassigned --
+ Qt::Key_unknown, // 141 0x8D -- unassigned --
+ Qt::Key_unknown, // 142 0x8E -- unassigned --
+ Qt::Key_unknown, // 143 0x8F -- unassigned --
+ Qt::Key_NumLock, // 144 0x90 VK_NUMLOCK | Num Lock key
+ Qt::Key_ScrollLock, // 145 0x91 VK_SCROLL | Scroll Lock key
+ // Fujitsu/OASYS kbd --------------------
+ 0, //Qt::Key_Jisho, // 146 0x92 VK_OEM_FJ_JISHO | 'Dictionary' key /
+ // VK_OEM_NEC_EQUAL = key on numpad on NEC PC-9800 kbd
+ Qt::Key_Massyo, // 147 0x93 VK_OEM_FJ_MASSHOU | 'Unregister word' key
+ Qt::Key_Touroku, // 148 0x94 VK_OEM_FJ_TOUROKU | 'Register word' key
+ 0, //Qt::Key_Oyayubi_Left,//149 0x95 VK_OEM_FJ_LOYA | 'Left OYAYUBI' key
+ 0, //Qt::Key_Oyayubi_Right,//150 0x96 VK_OEM_FJ_ROYA | 'Right OYAYUBI' key
+ Qt::Key_unknown, // 151 0x97 -- unassigned --
+ Qt::Key_unknown, // 152 0x98 -- unassigned --
+ Qt::Key_unknown, // 153 0x99 -- unassigned --
+ Qt::Key_unknown, // 154 0x9A -- unassigned --
+ Qt::Key_unknown, // 155 0x9B -- unassigned --
+ Qt::Key_unknown, // 156 0x9C -- unassigned --
+ Qt::Key_unknown, // 157 0x9D -- unassigned --
+ Qt::Key_unknown, // 158 0x9E -- unassigned --
+ Qt::Key_unknown, // 159 0x9F -- unassigned --
+ Qt::Key_Shift, // 160 0xA0 VK_LSHIFT | Left Shift key
+ Qt::Key_Shift, // 161 0xA1 VK_RSHIFT | Right Shift key
+ Qt::Key_Control, // 162 0xA2 VK_LCONTROL | Left Ctrl key
+ Qt::Key_Control, // 163 0xA3 VK_RCONTROL | Right Ctrl key
+ Qt::Key_Alt, // 164 0xA4 VK_LMENU | Left Menu key
+ Qt::Key_Alt, // 165 0xA5 VK_RMENU | Right Menu key
+ Qt::Key_Back, // 166 0xA6 VK_BROWSER_BACK | Browser Back key
+ Qt::Key_Forward, // 167 0xA7 VK_BROWSER_FORWARD | Browser Forward key
+ Qt::Key_Refresh, // 168 0xA8 VK_BROWSER_REFRESH | Browser Refresh key
+ Qt::Key_Stop, // 169 0xA9 VK_BROWSER_STOP | Browser Stop key
+ Qt::Key_Search, // 170 0xAA VK_BROWSER_SEARCH | Browser Search key
+ Qt::Key_Favorites, // 171 0xAB VK_BROWSER_FAVORITES| Browser Favorites key
+ Qt::Key_HomePage, // 172 0xAC VK_BROWSER_HOME | Browser Start and Home key
+ Qt::Key_VolumeMute, // 173 0xAD VK_VOLUME_MUTE | Volume Mute key
+ Qt::Key_VolumeDown, // 174 0xAE VK_VOLUME_DOWN | Volume Down key
+ Qt::Key_VolumeUp, // 175 0xAF VK_VOLUME_UP | Volume Up key
+ Qt::Key_MediaNext, // 176 0xB0 VK_MEDIA_NEXT_TRACK | Next Track key
+ Qt::Key_MediaPrevious, //177 0xB1 VK_MEDIA_PREV_TRACK | Previous Track key
+ Qt::Key_MediaStop, // 178 0xB2 VK_MEDIA_STOP | Stop Media key
+ Qt::Key_MediaPlay, // 179 0xB3 VK_MEDIA_PLAY_PAUSE | Play/Pause Media key
+ Qt::Key_LaunchMail, // 180 0xB4 VK_LAUNCH_MAIL | Start Mail key
+ Qt::Key_LaunchMedia,// 181 0xB5 VK_LAUNCH_MEDIA_SELECT Select Media key
+ Qt::Key_Launch0, // 182 0xB6 VK_LAUNCH_APP1 | Start Application 1 key
+ Qt::Key_Launch1, // 183 0xB7 VK_LAUNCH_APP2 | Start Application 2 key
+ Qt::Key_unknown, // 184 0xB8 -- reserved --
+ Qt::Key_unknown, // 185 0xB9 -- reserved --
+ 0, // 186 0xBA VK_OEM_1 | ';:' for US
+ 0, // 187 0xBB VK_OEM_PLUS | '+' any country
+ 0, // 188 0xBC VK_OEM_COMMA | ',' any country
+ 0, // 189 0xBD VK_OEM_MINUS | '-' any country
+ 0, // 190 0xBE VK_OEM_PERIOD | '.' any country
+ 0, // 191 0xBF VK_OEM_2 | '/?' for US
+ 0, // 192 0xC0 VK_OEM_3 | '`~' for US
+ Qt::Key_unknown, // 193 0xC1 -- reserved --
+ Qt::Key_unknown, // 194 0xC2 -- reserved --
+ Qt::Key_unknown, // 195 0xC3 -- reserved --
+ Qt::Key_unknown, // 196 0xC4 -- reserved --
+ Qt::Key_unknown, // 197 0xC5 -- reserved --
+ Qt::Key_unknown, // 198 0xC6 -- reserved --
+ Qt::Key_unknown, // 199 0xC7 -- reserved --
+ Qt::Key_unknown, // 200 0xC8 -- reserved --
+ Qt::Key_unknown, // 201 0xC9 -- reserved --
+ Qt::Key_unknown, // 202 0xCA -- reserved --
+ Qt::Key_unknown, // 203 0xCB -- reserved --
+ Qt::Key_unknown, // 204 0xCC -- reserved --
+ Qt::Key_unknown, // 205 0xCD -- reserved --
+ Qt::Key_unknown, // 206 0xCE -- reserved --
+ Qt::Key_unknown, // 207 0xCF -- reserved --
+ Qt::Key_unknown, // 208 0xD0 -- reserved --
+ Qt::Key_unknown, // 209 0xD1 -- reserved --
+ Qt::Key_unknown, // 210 0xD2 -- reserved --
+ Qt::Key_unknown, // 211 0xD3 -- reserved --
+ Qt::Key_unknown, // 212 0xD4 -- reserved --
+ Qt::Key_unknown, // 213 0xD5 -- reserved --
+ Qt::Key_unknown, // 214 0xD6 -- reserved --
+ Qt::Key_unknown, // 215 0xD7 -- reserved --
+ Qt::Key_unknown, // 216 0xD8 -- unassigned --
+ Qt::Key_unknown, // 217 0xD9 -- unassigned --
+ Qt::Key_unknown, // 218 0xDA -- unassigned --
+ 0, // 219 0xDB VK_OEM_4 | '[{' for US
+ 0, // 220 0xDC VK_OEM_5 | '\|' for US
+ 0, // 221 0xDD VK_OEM_6 | ']}' for US
+ 0, // 222 0xDE VK_OEM_7 | ''"' for US
+ 0, // 223 0xDF VK_OEM_8
+ Qt::Key_unknown, // 224 0xE0 -- reserved --
+ Qt::Key_unknown, // 225 0xE1 VK_OEM_AX | 'AX' key on Japanese AX kbd
+ Qt::Key_unknown, // 226 0xE2 VK_OEM_102 | "<>" or "\|" on RT 102-key kbd
+ Qt::Key_unknown, // 227 0xE3 VK_ICO_HELP | Help key on ICO
+ Qt::Key_unknown, // 228 0xE4 VK_ICO_00 | 00 key on ICO
+ Qt::Key_unknown, // 229 0xE5 VK_PROCESSKEY | IME Process key
+ Qt::Key_unknown, // 230 0xE6 VK_ICO_CLEAR |
+ Qt::Key_unknown, // 231 0xE7 VK_PACKET | Unicode char as keystrokes
+ Qt::Key_unknown, // 232 0xE8 -- unassigned --
+ // Nokia/Ericsson definitions ---------------
+ Qt::Key_unknown, // 233 0xE9 VK_OEM_RESET
+ Qt::Key_unknown, // 234 0xEA VK_OEM_JUMP
+ Qt::Key_unknown, // 235 0xEB VK_OEM_PA1
+ Qt::Key_unknown, // 236 0xEC VK_OEM_PA2
+ Qt::Key_unknown, // 237 0xED VK_OEM_PA3
+ Qt::Key_unknown, // 238 0xEE VK_OEM_WSCTRL
+ Qt::Key_unknown, // 239 0xEF VK_OEM_CUSEL
+ Qt::Key_unknown, // 240 0xF0 VK_OEM_ATTN
+ Qt::Key_unknown, // 241 0xF1 VK_OEM_FINISH
+ Qt::Key_unknown, // 242 0xF2 VK_OEM_COPY
+ Qt::Key_unknown, // 243 0xF3 VK_OEM_AUTO
+ Qt::Key_unknown, // 244 0xF4 VK_OEM_ENLW
+ Qt::Key_unknown, // 245 0xF5 VK_OEM_BACKTAB
+ Qt::Key_unknown, // 246 0xF6 VK_ATTN | Attn key
+ Qt::Key_unknown, // 247 0xF7 VK_CRSEL | CrSel key
+ Qt::Key_unknown, // 248 0xF8 VK_EXSEL | ExSel key
+ Qt::Key_unknown, // 249 0xF9 VK_EREOF | Erase EOF key
+ Qt::Key_Play, // 250 0xFA VK_PLAY | Play key
+ Qt::Key_Zoom, // 251 0xFB VK_ZOOM | Zoom key
+ Qt::Key_unknown, // 252 0xFC VK_NONAME | Reserved
+ Qt::Key_unknown, // 253 0xFD VK_PA1 | PA1 key
+ Qt::Key_Clear, // 254 0xFE VK_OEM_CLEAR | Clear key
+ 0
+};
+
+// Possible modifier states.
+// NOTE: The order of these states match the order in QWindowsKeyMapper::updatePossibleKeyCodes()!
+static const Qt::KeyboardModifiers ModsTbl[] = {
+ Qt::NoModifier, // 0
+ Qt::ShiftModifier, // 1
+ Qt::ControlModifier, // 2
+ Qt::ControlModifier | Qt::ShiftModifier, // 3
+ Qt::AltModifier, // 4
+ Qt::AltModifier | Qt::ShiftModifier, // 5
+ Qt::AltModifier | Qt::ControlModifier, // 6
+ Qt::AltModifier | Qt::ShiftModifier | Qt::ControlModifier, // 7
+ Qt::NoModifier, // Fall-back to raw Key_*
+};
+
+/**
+ Remap return or action key to select key for windows mobile.
+*/
+inline int winceKeyBend(int keyCode)
+{
+ return KeyTbl[keyCode];
+}
+
+// Translate a VK into a Qt key code, or unicode character
+static inline int toKeyOrUnicode(int vk, int scancode, unsigned char *kbdBuffer, bool *isDeadkey = 0)
+{
+ Q_ASSERT(vk > 0 && vk < 256);
+ int code = 0;
+ QChar unicodeBuffer[5];
+ int res = ToUnicode(vk, scancode, kbdBuffer, reinterpret_cast<LPWSTR>(unicodeBuffer), 5, 0);
+ if (res)
+ code = unicodeBuffer[0].toUpper().unicode();
+
+ // Qt::Key_*'s are not encoded below 0x20, so try again, and DEL keys (0x7f) is encoded with a
+ // proper Qt::Key_ code
+ if (code < 0x20 || code == 0x7f) // Handles res==0 too
+ code = winceKeyBend(vk);
+
+ if (isDeadkey)
+ *isDeadkey = (res == -1);
+
+ return code == Qt::Key_unknown ? 0 : code;
+}
+
+int qt_translateKeyCode(int vk)
+{
+ int code = winceKeyBend((vk < 0 || vk > 255) ? 0 : vk);
+ return code == Qt::Key_unknown ? 0 : code;
+}
+
+static inline int asciiToKeycode(char a, int state)
+{
+ if (a >= 'a' && a <= 'z')
+ a = toupper(a);
+ if ((state & Qt::ControlModifier) != 0) {
+ if (a >= 0 && a <= 31) // Ctrl+@..Ctrl+A..CTRL+Z..Ctrl+_
+ a += '@'; // to @..A..Z.._
+ }
+ return a & 0xff;
+}
+
+static inline bool isModifierKey(int code)
+{
+ return (code >= Qt::Key_Shift) && (code <= Qt::Key_ScrollLock);
+}
+// Key translation -----------------------------------------------------------------------[ end ]---
+
+
+// Keyboard map private ----------------------------------------------------------------[ start ]---
+
+/*
+ \internal
+ A Windows KeyboardLayoutItem has 8 possible states:
+ 1. Unmodified
+ 2. Shift
+ 3. Control
+ 4. Control + Shift
+ 5. Alt
+ 6. Alt + Shift
+ 7. Alt + Control
+ 8. Alt + Control + Shift
+*/
+struct KeyboardLayoutItem {
+ bool dirty;
+ quint8 deadkeys;
+ quint32 qtKey[9]; // Can by any Qt::Key_<foo>, or unicode character
+};
+
+void QWindowsKeyMapper::deleteLayouts()
+{
+ for (int i = 0; i < 255; ++i) {
+ if (keyLayout[i]) {
+ delete keyLayout[i];
+ keyLayout[i] = 0;
+ }
+ }
+}
+
+void QWindowsKeyMapper::changeKeyboard()
+{
+ deleteLayouts();
+
+ /* MAKELCID()'s first argument is a WORD, and GetKeyboardLayout()
+ * returns a DWORD. */
+
+ LCID newLCID = MAKELCID((quintptr)GetKeyboardLayout(0), SORT_DEFAULT);
+// keyboardInputLocale = qt_localeFromLCID(newLCID);
+
+ bool bidi = false;
+ wchar_t LCIDFontSig[16];
+ if (GetLocaleInfo(newLCID, LOCALE_FONTSIGNATURE, LCIDFontSig, sizeof(LCIDFontSig) / sizeof(wchar_t))
+ && (LCIDFontSig[7] & (wchar_t)0x0800))
+ bidi = true;
+
+ keyboardInputDirection = bidi ? Qt::RightToLeft : Qt::LeftToRight;
+}
+
+void QWindowsKeyMapper::clearRecordedKeys()
+{
+ key_recorder.clearKeys();
+}
+
+
+inline void setKbdState(unsigned char *kbd, bool shift, bool ctrl, bool alt)
+{
+ kbd[VK_LSHIFT ] = (shift ? 0x80 : 0);
+ kbd[VK_SHIFT ] = (shift ? 0x80 : 0);
+ kbd[VK_LCONTROL] = (ctrl ? 0x80 : 0);
+ kbd[VK_CONTROL ] = (ctrl ? 0x80 : 0);
+ kbd[VK_RMENU ] = (alt ? 0x80 : 0);
+ kbd[VK_MENU ] = (alt ? 0x80 : 0);
+}
+
+void QWindowsKeyMapper::updateKeyMap(const MSG &msg)
+{
+ unsigned char kbdBuffer[256]; // Will hold the complete keyboard state
+ GetKeyboardState(kbdBuffer);
+ quint32 scancode = (msg.lParam >> 16) & 0xfff;
+ updatePossibleKeyCodes(kbdBuffer, scancode, msg.wParam);
+}
+
+void QWindowsKeyMapper::updatePossibleKeyCodes(unsigned char *kbdBuffer, quint32 scancode,
+ quint32 vk_key)
+{
+ if (!vk_key || (keyLayout[vk_key] && !keyLayout[vk_key]->dirty))
+ return;
+
+ if (!keyLayout[vk_key])
+ keyLayout[vk_key] = new KeyboardLayoutItem;
+
+ // Copy keyboard state, so we can modify and query output for each possible permutation
+ unsigned char buffer[256];
+ memcpy(buffer, kbdBuffer, sizeof(buffer));
+ // Always 0, as Windows doesn't treat these as modifiers;
+ buffer[VK_LWIN ] = 0;
+ buffer[VK_RWIN ] = 0;
+ buffer[VK_CAPITAL ] = 0;
+ buffer[VK_NUMLOCK ] = 0;
+ buffer[VK_SCROLL ] = 0;
+ // Always 0, since we'll only change the other versions
+ buffer[VK_RSHIFT ] = 0;
+ buffer[VK_RCONTROL] = 0;
+ buffer[VK_LMENU ] = 0; // Use right Alt, since left Ctrl + right Alt is considered AltGraph
+
+ bool isDeadKey = false;
+ keyLayout[vk_key]->deadkeys = 0;
+ keyLayout[vk_key]->dirty = false;
+ setKbdState(buffer, false, false, false);
+ keyLayout[vk_key]->qtKey[0] = toKeyOrUnicode(vk_key, scancode, buffer, &isDeadKey);
+ keyLayout[vk_key]->deadkeys |= isDeadKey ? 0x01 : 0;
+ setKbdState(buffer, true, false, false);
+ keyLayout[vk_key]->qtKey[1] = toKeyOrUnicode(vk_key, scancode, buffer, &isDeadKey);
+ keyLayout[vk_key]->deadkeys |= isDeadKey ? 0x02 : 0;
+ setKbdState(buffer, false, true, false);
+ keyLayout[vk_key]->qtKey[2] = toKeyOrUnicode(vk_key, scancode, buffer, &isDeadKey);
+ keyLayout[vk_key]->deadkeys |= isDeadKey ? 0x04 : 0;
+ setKbdState(buffer, true, true, false);
+ keyLayout[vk_key]->qtKey[3] = toKeyOrUnicode(vk_key, scancode, buffer, &isDeadKey);
+ keyLayout[vk_key]->deadkeys |= isDeadKey ? 0x08 : 0;
+ setKbdState(buffer, false, false, true);
+ keyLayout[vk_key]->qtKey[4] = toKeyOrUnicode(vk_key, scancode, buffer, &isDeadKey);
+ keyLayout[vk_key]->deadkeys |= isDeadKey ? 0x10 : 0;
+ setKbdState(buffer, true, false, true);
+ keyLayout[vk_key]->qtKey[5] = toKeyOrUnicode(vk_key, scancode, buffer, &isDeadKey);
+ keyLayout[vk_key]->deadkeys |= isDeadKey ? 0x20 : 0;
+ setKbdState(buffer, false, true, true);
+ keyLayout[vk_key]->qtKey[6] = toKeyOrUnicode(vk_key, scancode, buffer, &isDeadKey);
+ keyLayout[vk_key]->deadkeys |= isDeadKey ? 0x40 : 0;
+ setKbdState(buffer, true, true, true);
+ keyLayout[vk_key]->qtKey[7] = toKeyOrUnicode(vk_key, scancode, buffer, &isDeadKey);
+ keyLayout[vk_key]->deadkeys |= isDeadKey ? 0x80 : 0;
+ // Add a fall back key for layouts which don't do composition and show non-latin1 characters
+ int fallbackKey = winceKeyBend(vk_key);
+ if (!fallbackKey || fallbackKey == Qt::Key_unknown) {
+ fallbackKey = 0;
+ if (vk_key != keyLayout[vk_key]->qtKey[0] && vk_key < 0x5B && vk_key > 0x2F)
+ fallbackKey = vk_key;
+ }
+ keyLayout[vk_key]->qtKey[8] = fallbackKey;
+
+ // If this vk_key a Dead Key
+ if (MapVirtualKey(vk_key, 2) & 0x80000000) {
+ // Push a Space, then the original key through the low-level ToAscii functions.
+ // We do this because these functions (ToAscii / ToUnicode) will alter the internal state of
+ // the keyboard driver By doing the following, we set the keyboard driver state back to what
+ // it was before we wrecked it with the code above.
+ // We need to push the space with an empty keystate map, since the driver checks the map for
+ // transitions in modifiers, so this helps us capture all possible deadkeys.
+ unsigned char emptyBuffer[256];
+ memset(emptyBuffer, 0, sizeof(emptyBuffer));
+ ::ToAscii(VK_SPACE, 0, emptyBuffer, reinterpret_cast<LPWORD>(&buffer), 0);
+ ::ToAscii(vk_key, scancode, kbdBuffer, reinterpret_cast<LPWORD>(&buffer), 0);
+ }
+
+ if (QWindowsContext::verboseEvents > 1) {
+ qDebug("updatePossibleKeyCodes for virtual key = 0x%02x!", vk_key);
+ for (int i = 0; i < 9; ++i) {
+ qDebug(" [%d] (%d,0x%02x,'%c') %s", i,
+ keyLayout[vk_key]->qtKey[i],
+ keyLayout[vk_key]->qtKey[i],
+ keyLayout[vk_key]->qtKey[i] ? keyLayout[vk_key]->qtKey[i] : 0x03,
+ keyLayout[vk_key]->deadkeys & (1<<i) ? "deadkey" : "");
+ }
+ }
+}
+
+bool QWindowsKeyMapper::isADeadKey(unsigned int vk_key, unsigned int modifiers)
+{
+ if (keyLayout && (vk_key < 256) && keyLayout[vk_key]) {
+ for (register int i = 0; i < 9; ++i) {
+ if (uint(ModsTbl[i]) == modifiers)
+ return bool(keyLayout[vk_key]->deadkeys & 1<<i);
+ }
+ }
+ return false;
+}
+
+static inline QString messageKeyText(const MSG &msg)
+{
+ const QChar ch = QChar((ushort)msg.wParam);
+ return ch.isNull() ? QString() : QString(ch);
+}
+
+static void showSystemMenu(QWindow* w)
+{
+ QWindow *topLevel = QWindowsWindow::topLevelOf(w);
+ HWND topLevelHwnd = QWindowsWindow::handleOf(topLevel);
+ HMENU menu = GetSystemMenu(topLevelHwnd, FALSE);
+ if (!menu)
+ return; // no menu for this window
+
+#define enabled (MF_BYCOMMAND | MF_ENABLED)
+#define disabled (MF_BYCOMMAND | MF_GRAYED)
+
+ EnableMenuItem(menu, SC_MINIMIZE, (topLevel->windowFlags() & Qt::WindowMinimizeButtonHint)?enabled:disabled);
+ bool maximized = IsZoomed(topLevelHwnd);
+
+ EnableMenuItem(menu, SC_MAXIMIZE, ! (topLevel->windowFlags() & Qt::WindowMaximizeButtonHint) || maximized?disabled:enabled);
+ EnableMenuItem(menu, SC_RESTORE, maximized?enabled:disabled);
+
+ // We should _not_ check with the setFixedSize(x,y) case here, since Windows is not able to check
+ // this and our menu here would be out-of-sync with the menu produced by mouse-click on the
+ // System Menu, or right-click on the title bar.
+ EnableMenuItem(menu, SC_SIZE, (topLevel->windowFlags() & Qt::MSWindowsFixedSizeDialogHint) || maximized?disabled:enabled);
+ EnableMenuItem(menu, SC_MOVE, maximized?disabled:enabled);
+ EnableMenuItem(menu, SC_CLOSE, enabled);
+ // Set bold on close menu item
+ MENUITEMINFO closeItem;
+ closeItem.cbSize = sizeof(MENUITEMINFO);
+ closeItem.fMask = MIIM_STATE;
+ closeItem.fState = MFS_DEFAULT;
+ SetMenuItemInfo(menu, SC_CLOSE, FALSE, &closeItem);
+
+#undef enabled
+#undef disabled
+ const int ret = TrackPopupMenuEx(menu,
+ TPM_LEFTALIGN | TPM_TOPALIGN | TPM_NONOTIFY | TPM_RETURNCMD,
+ topLevel->geometry().x(), topLevel->geometry().y(),
+ topLevelHwnd,
+ 0);
+ if (ret)
+ qWindowsWndProc(topLevelHwnd, WM_SYSCOMMAND, ret, 0);
+}
+
+static inline void sendExtendedPressRelease(QWindow *w, int k,
+ Qt::KeyboardModifiers mods,
+ quint32 nativeScanCode,
+ quint32 nativeVirtualKey,
+ quint32 nativeModifiers,
+ const QString & text = QString(),
+ bool autorep = false,
+ ushort count = 1)
+{
+ QWindowSystemInterface::handleExtendedKeyEvent(w, QEvent::KeyPress, k, mods, nativeScanCode, nativeVirtualKey, nativeModifiers, text, autorep, count);
+ QWindowSystemInterface::handleExtendedKeyEvent(w, QEvent::KeyRelease, k, mods, nativeScanCode, nativeVirtualKey, nativeModifiers, text, autorep, count);
+}
+
+/*!
+ \brief To be called from the window procedure.
+*/
+
+bool QWindowsKeyMapper::translateKeyEvent(QWindow *widget, HWND hwnd,
+ const MSG &msg, LRESULT *result)
+{
+ *result = 0;
+ MSG peekedMsg;
+ // consume dead chars?(for example, typing '`','a' resulting in a-accent).
+ if (PeekMessage(&peekedMsg, hwnd, 0, 0, PM_NOREMOVE) && peekedMsg.message == WM_DEADCHAR)
+ return true;
+ if (msg.message == WM_KEYDOWN || msg.message == WM_SYSKEYDOWN)
+ updateKeyMap(msg);
+ return translateKeyEventInternal(widget, msg, false);
+}
+
+bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, const MSG &msg, bool /* grab */)
+{
+ const int msgType = msg.message;
+
+ const quint32 scancode = (msg.lParam >> 16) & 0xfff;
+ const quint32 vk_key = MapVirtualKey(scancode, 1);
+ const bool isNumpad = (msg.wParam >= VK_NUMPAD0 && msg.wParam <= VK_NUMPAD9);
+ quint32 nModifiers = 0;
+
+ QWindow *receiver = m_keyGrabber ? m_keyGrabber : window;
+
+ // Map native modifiers to some bit representation
+ nModifiers |= (GetKeyState(VK_LSHIFT ) & 0x80 ? ShiftLeft : 0);
+ nModifiers |= (GetKeyState(VK_RSHIFT ) & 0x80 ? ShiftRight : 0);
+ nModifiers |= (GetKeyState(VK_LCONTROL) & 0x80 ? ControlLeft : 0);
+ nModifiers |= (GetKeyState(VK_RCONTROL) & 0x80 ? ControlRight : 0);
+ nModifiers |= (GetKeyState(VK_LMENU ) & 0x80 ? AltLeft : 0);
+ nModifiers |= (GetKeyState(VK_RMENU ) & 0x80 ? AltRight : 0);
+ nModifiers |= (GetKeyState(VK_LWIN ) & 0x80 ? MetaLeft : 0);
+ nModifiers |= (GetKeyState(VK_RWIN ) & 0x80 ? MetaRight : 0);
+ // Add Lock keys to the same bits
+ nModifiers |= (GetKeyState(VK_CAPITAL ) & 0x01 ? CapsLock : 0);
+ nModifiers |= (GetKeyState(VK_NUMLOCK ) & 0x01 ? NumLock : 0);
+ nModifiers |= (GetKeyState(VK_SCROLL ) & 0x01 ? ScrollLock : 0);
+
+ if (msg.lParam & ExtendedKey)
+ nModifiers |= msg.lParam & ExtendedKey;
+
+ // Get the modifier states (may be altered later, depending on key code)
+ int state = 0;
+ state |= (nModifiers & ShiftAny ? Qt::ShiftModifier : 0);
+ state |= (nModifiers & ControlAny ? Qt::ControlModifier : 0);
+ state |= (nModifiers & AltAny ? Qt::AltModifier : 0);
+ state |= (nModifiers & MetaAny ? Qt::MetaModifier : 0);
+
+ // Now we know enough to either have MapVirtualKey or our own keymap tell us if it's a deadkey
+ const bool isDeadKey = isADeadKey(msg.wParam, state)
+ || MapVirtualKey(msg.wParam, 2) & 0x80000000;
+
+ // A multi-character key or a Input method character
+ // not found by our look-ahead
+ if (msgType == WM_CHAR || msgType == WM_IME_CHAR) {
+ sendExtendedPressRelease(receiver, 0, Qt::KeyboardModifier(state), scancode, vk_key, nModifiers, messageKeyText(msg), false, 0);
+ return true;
+ }
+
+ bool result = false;
+ // handle Directionality changes (BiDi) with RTL extensions
+ if (m_useRTLExtensions) {
+ static int dirStatus = 0;
+ if (!dirStatus && state == Qt::ControlModifier
+ && msg.wParam == VK_CONTROL
+ && msgType == WM_KEYDOWN) {
+ if (GetKeyState(VK_LCONTROL) < 0)
+ dirStatus = VK_LCONTROL;
+ else if (GetKeyState(VK_RCONTROL) < 0)
+ dirStatus = VK_RCONTROL;
+ } else if (dirStatus) {
+ if (msgType == WM_KEYDOWN) {
+ if (msg.wParam == VK_SHIFT) {
+ if (dirStatus == VK_LCONTROL && GetKeyState(VK_LSHIFT) < 0)
+ dirStatus = VK_LSHIFT;
+ else if (dirStatus == VK_RCONTROL && GetKeyState(VK_RSHIFT) < 0)
+ dirStatus = VK_RSHIFT;
+ } else {
+ dirStatus = 0;
+ }
+ } else if (msgType == WM_KEYUP) {
+ if (dirStatus == VK_LSHIFT
+ && ((msg.wParam == VK_SHIFT && GetKeyState(VK_LCONTROL))
+ || (msg.wParam == VK_CONTROL && GetKeyState(VK_LSHIFT)))) {
+ sendExtendedPressRelease(receiver, Qt::Key_Direction_L, 0, scancode, msg.wParam, nModifiers, QString(), false, 0);
+ result = true;
+ dirStatus = 0;
+ } else if (dirStatus == VK_RSHIFT
+ && ( (msg.wParam == VK_SHIFT && GetKeyState(VK_RCONTROL))
+ || (msg.wParam == VK_CONTROL && GetKeyState(VK_RSHIFT)))) {
+ sendExtendedPressRelease(receiver, Qt::Key_Direction_R, 0, scancode, msg.wParam, nModifiers, QString(), false, 0);
+ result = true;
+ dirStatus = 0;
+ } else {
+ dirStatus = 0;
+ }
+ } else {
+ dirStatus = 0;
+ }
+ }
+ } // RTL
+
+ // IME will process these keys, so simply return
+ if (msg.wParam == VK_PROCESSKEY)
+ return true;
+
+ // Ignore invalid virtual keycodes (see bugs 127424, QTBUG-3630)
+ if (msg.wParam == 0 || msg.wParam == 0xFF)
+ return true;
+
+ // Translate VK_* (native) -> Key_* (Qt) keys
+ // If it's a dead key, we cannot use the toKeyOrUnicode() function, since that will change
+ // the internal state of the keyboard driver, resulting in that dead keys no longer works.
+ // ..also if we're typing numbers on the keypad, while holding down the Alt modifier.
+ int code = 0;
+ if (isNumpad && (nModifiers & AltAny)) {
+ code = winceKeyBend(msg.wParam);
+ } else if (!isDeadKey) {
+ unsigned char kbdBuffer[256]; // Will hold the complete keyboard state
+ GetKeyboardState(kbdBuffer);
+ code = toKeyOrUnicode(msg.wParam, scancode, kbdBuffer);
+ }
+
+ // Invert state logic:
+ // If the key actually pressed is a modifier key, then we remove its modifier key from the
+ // state, since a modifier-key can't have itself as a modifier
+ if (code == Qt::Key_Control)
+ state = state ^ Qt::ControlModifier;
+ else if (code == Qt::Key_Shift)
+ state = state ^ Qt::ShiftModifier;
+ else if (code == Qt::Key_Alt)
+ state = state ^ Qt::AltModifier;
+
+ // If the bit 24 of lParm is set you received a enter,
+ // otherwise a Return. (This is the extended key bit)
+ if ((code == Qt::Key_Return) && (msg.lParam & 0x1000000))
+ code = Qt::Key_Enter;
+
+ // All cursor keys without extended bit
+ if (!(msg.lParam & 0x1000000)) {
+ switch (code) {
+ case Qt::Key_Left:
+ case Qt::Key_Right:
+ case Qt::Key_Up:
+ case Qt::Key_Down:
+ case Qt::Key_PageUp:
+ case Qt::Key_PageDown:
+ case Qt::Key_Home:
+ case Qt::Key_End:
+ case Qt::Key_Insert:
+ case Qt::Key_Delete:
+ case Qt::Key_Asterisk:
+ case Qt::Key_Plus:
+ case Qt::Key_Minus:
+ case Qt::Key_Period:
+ case Qt::Key_0:
+ case Qt::Key_1:
+ case Qt::Key_2:
+ case Qt::Key_3:
+ case Qt::Key_4:
+ case Qt::Key_5:
+ case Qt::Key_6:
+ case Qt::Key_7:
+ case Qt::Key_8:
+ case Qt::Key_9:
+ state |= ((msg.wParam >= '0' && msg.wParam <= '9')
+ || (msg.wParam >= VK_OEM_PLUS && msg.wParam <= VK_OEM_3))
+ ? 0 : Qt::KeypadModifier;
+ default:
+ if ((uint)msg.lParam == 0x004c0001 || (uint)msg.lParam == 0xc04c0001)
+ state |= Qt::KeypadModifier;
+ break;
+ }
+ }
+ // Other keys with with extended bit
+ else {
+ switch (code) {
+ case Qt::Key_Enter:
+ case Qt::Key_Slash:
+ case Qt::Key_NumLock:
+ state |= Qt::KeypadModifier;
+ default:
+ break;
+ }
+ }
+
+ // KEYDOWN ---------------------------------------------------------------------------------
+ if (msgType == WM_KEYDOWN || msgType == WM_IME_KEYDOWN || msgType == WM_SYSKEYDOWN) {
+ // Get the last record of this key press, so we can validate the current state
+ // The record is not removed from the list
+ KeyRecord *rec = key_recorder.findKey(msg.wParam, false);
+
+ // If rec's state doesn't match the current state, something has changed behind our back
+ // (Consumed by modal widget is one possibility) So, remove the record from the list
+ // This will stop the auto-repeat of the key, should a modifier change, for example
+ if (rec && rec->state != state) {
+ key_recorder.findKey(msg.wParam, true);
+ rec = 0;
+ }
+
+ // Find unicode character from Windows Message Queue
+ MSG wm_char;
+ UINT charType = (msgType == WM_KEYDOWN
+ ? WM_CHAR
+ : msgType == WM_IME_KEYDOWN ? WM_IME_CHAR : WM_SYSCHAR);
+
+ QChar uch;
+ if (PeekMessage(&wm_char, 0, charType, charType, PM_REMOVE)) {
+ // Found a ?_CHAR
+ uch = QChar((ushort)wm_char.wParam);
+ if (msgType == WM_SYSKEYDOWN && uch.isLetter() && (msg.lParam & KF_ALTDOWN))
+ uch = uch.toLower(); // (See doc of WM_SYSCHAR) Alt-letter
+ if (!code && !uch.row())
+ code = asciiToKeycode(uch.cell(), state);
+ }
+
+ // Special handling for the WM_IME_KEYDOWN message. Microsoft IME (Korean) will not
+ // generate a WM_IME_CHAR message corresponding to this message. We might get wrong
+ // results, if we map this virtual key-code directly (for eg '?' US layouts). So try
+ // to find the correct key using the current message parameters & keyboard state.
+ if (uch.isNull() && msgType == WM_IME_KEYDOWN) {
+ BYTE keyState[256];
+ wchar_t newKey[3] = {0};
+ GetKeyboardState(keyState);
+ int val = ToUnicode(vk_key, scancode, keyState, newKey, 2, 0);
+ if (val == 1) {
+ uch = QChar(newKey[0]);
+ } else {
+ // If we are still not able to find a unicode key, pass the WM_IME_KEYDOWN
+ // message to DefWindowProc() for generating a proper WM_KEYDOWN.
+ return false;
+ }
+ }
+
+ // If no ?_CHAR was found in the queue; deduct character from the ?_KEYDOWN parameters
+ if (uch.isNull()) {
+ if (msg.wParam == VK_DELETE) {
+ uch = QChar(QLatin1Char(0x7f)); // Windows doesn't know this one.
+ } else {
+ if (msgType != WM_SYSKEYDOWN || !code) {
+ UINT map = MapVirtualKey(msg.wParam, 2);
+ // If the high bit of the return value is set, it's a deadkey
+ if (!(map & 0x80000000))
+ uch = QChar((ushort)map);
+ }
+ }
+ if (!code && !uch.row())
+ code = asciiToKeycode(uch.cell(), state);
+ }
+
+ // Special handling of global Windows hotkeys
+ if (state == Qt::AltModifier) {
+ switch (code) {
+ case Qt::Key_Escape:
+ case Qt::Key_Tab:
+ case Qt::Key_Enter:
+ case Qt::Key_F4:
+ return false; // Send the event on to Windows
+ case Qt::Key_Space:
+ // do not pass this key to windows, we will process it ourselves
+ showSystemMenu(receiver);
+ return true;
+ default:
+ break;
+ }
+ }
+
+ // Map SHIFT + Tab to SHIFT + BackTab, QShortcutMap knows about this translation
+ if (code == Qt::Key_Tab && (state & Qt::ShiftModifier) == Qt::ShiftModifier)
+ code = Qt::Key_Backtab;
+
+ // If we have a record, it means that the key is already pressed, the state is the same
+ // so, we have an auto-repeating key
+ if (rec) {
+ if (code < Qt::Key_Shift || code > Qt::Key_ScrollLock) {
+ QWindowSystemInterface::handleExtendedKeyEvent(receiver, QEvent::KeyRelease, code,
+ Qt::KeyboardModifier(state), scancode, msg.wParam, nModifiers, rec->text, true, 0);
+ QWindowSystemInterface::handleExtendedKeyEvent(receiver, QEvent::KeyPress, code,
+ Qt::KeyboardModifier(state), scancode, msg.wParam, nModifiers, rec->text, true, 0);
+ result = true;
+ }
+ }
+ // No record of the key being previous pressed, so we now send a QEvent::KeyPress event,
+ // and store the key data into our records.
+ else {
+ const QString text = uch.isNull() ? QString() : QString(uch);
+ const char a = uch.row() ? 0 : uch.cell();
+ key_recorder.storeKey(msg.wParam, a, state, text);
+ QWindowSystemInterface::handleExtendedKeyEvent(receiver, QEvent::KeyPress, code,
+ Qt::KeyboardModifier(state), scancode, msg.wParam, nModifiers, text, false, 0);
+ result =true;
+ bool store = true;
+ // Alt+<alphanumerical> go to the Win32 menu system if unhandled by Qt
+ if (msgType == WM_SYSKEYDOWN && !result && a) {
+ HWND parent = GetParent(QWindowsWindow::handleOf(receiver));
+ while (parent) {
+ if (GetMenu(parent)) {
+ SendMessage(parent, WM_SYSCOMMAND, SC_KEYMENU, a);
+ store = false;
+ result = true;
+ break;
+ }
+ parent = GetParent(parent);
+ }
+ }
+ if (!store)
+ key_recorder.findKey(msg.wParam, true);
+ }
+ }
+
+ // KEYUP -----------------------------------------------------------------------------------
+ else {
+ // Try to locate the key in our records, and remove it if it exists.
+ // The key may not be in our records if, for example, the down event was handled by
+ // win32 natively, or our window gets focus while a key is already press, but now gets
+ // the key release event.
+ KeyRecord* rec = key_recorder.findKey(msg.wParam, true);
+ if (!rec && !(code == Qt::Key_Shift
+ || code == Qt::Key_Control
+ || code == Qt::Key_Meta
+ || code == Qt::Key_Alt)) {
+ // Someone ate the key down event
+ } else {
+ if (!code)
+ code = asciiToKeycode(rec->ascii ? rec->ascii : msg.wParam, state);
+
+ // Map SHIFT + Tab to SHIFT + BackTab, QShortcutMap knows about this translation
+ if (code == Qt::Key_Tab && (state & Qt::ShiftModifier) == Qt::ShiftModifier)
+ code = Qt::Key_Backtab;
+ QWindowSystemInterface::handleExtendedKeyEvent(receiver, QEvent::KeyRelease, code,
+ Qt::KeyboardModifier(state), scancode, msg.wParam, nModifiers,
+ (rec ? rec->text : QString()), false, 0);
+ result = true;
+ // don't pass Alt to Windows unless we are embedded in a non-Qt window
+ if (code == Qt::Key_Alt) {
+ const QWindowsContext *context = QWindowsContext::instance();
+ HWND parent = GetParent(QWindowsWindow::handleOf(receiver));
+ while (parent) {
+ if (!context->findPlatformWindow(parent) && GetMenu(parent)) {
+ result = false;
+ break;
+ }
+ parent = GetParent(parent);
+ }
+ }
+ }
+ }
+ return result;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowskeymapper.h b/src/plugins/platforms/windows/qwindowskeymapper.h
new file mode 100644
index 0000000000..0d50193730
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowskeymapper.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSKEYMAPPER_H
+#define QWINDOWSKEYMAPPER_H
+
+#include "qtwindows_additional.h"
+
+#include <QtCore/QLocale>
+
+QT_BEGIN_NAMESPACE
+
+class QWindow;
+
+struct KeyboardLayoutItem;
+
+class QWindowsKeyMapper
+{
+ Q_DISABLE_COPY(QWindowsKeyMapper)
+public:
+ explicit QWindowsKeyMapper();
+ ~QWindowsKeyMapper();
+
+ void changeKeyboard();
+
+ void setUseRTLExtensions(bool e) { m_useRTLExtensions = e; }
+ bool useRTLExtensions() const { return m_useRTLExtensions; }
+
+ bool translateKeyEvent(QWindow *widget, HWND hwnd, const MSG &msg, LRESULT *result);
+
+ QWindow *keyGrabber() const { return m_keyGrabber; }
+ void setKeyGrabber(QWindow *w) { m_keyGrabber = w; }
+
+private:
+ bool translateKeyEventInternal(QWindow *receiver, const MSG &msg, bool grab);
+ void updateKeyMap(const MSG &msg);
+
+ bool m_useRTLExtensions;
+
+ QLocale keyboardInputLocale;
+ Qt::LayoutDirection keyboardInputDirection;
+
+ void clearRecordedKeys();
+ void updatePossibleKeyCodes(unsigned char *kbdBuffer, quint32 scancode, quint32 vk_key);
+ bool isADeadKey(unsigned int vk_key, unsigned int modifiers);
+ void deleteLayouts();
+
+ KeyboardLayoutItem *keyLayout[256];
+ QWindow *m_keyGrabber;
+};
+
+enum WindowsNativeModifiers {
+ ShiftLeft = 0x00000001,
+ ControlLeft = 0x00000002,
+ AltLeft = 0x00000004,
+ MetaLeft = 0x00000008,
+ ShiftRight = 0x00000010,
+ ControlRight = 0x00000020,
+ AltRight = 0x00000040,
+ MetaRight = 0x00000080,
+ CapsLock = 0x00000100,
+ NumLock = 0x00000200,
+ ScrollLock = 0x00000400,
+ ExtendedKey = 0x01000000,
+
+ // Convenience mappings
+ ShiftAny = 0x00000011,
+ ControlAny = 0x00000022,
+ AltAny = 0x00000044,
+ MetaAny = 0x00000088,
+ LockAny = 0x00000700
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSKEYMAPPER_H
diff --git a/src/plugins/platforms/windows/qwindowsmime.cpp b/src/plugins/platforms/windows/qwindowsmime.cpp
new file mode 100644
index 0000000000..09104a43cf
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsmime.cpp
@@ -0,0 +1,1557 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsmime.h"
+#include "qwindowscontext.h"
+
+#include <QtGui/private/qdnd_p.h>
+#include <QtCore/QTextCodec>
+#include <QtCore/QMap>
+#include <QtCore/QUrl>
+#include <QtCore/QDir>
+#include <QtCore/QDebug>
+#include <QtCore/QBuffer>
+#include <QtGui/QImageReader>
+#include <QtGui/QImageWriter>
+
+#include <shlobj.h>
+
+QT_BEGIN_NAMESPACE
+
+/* The MSVC compilers allows multi-byte characters, that has the behavior of
+ * that each character gets shifted into position. 0x73524742 below is for MSVC
+ * equivalent to doing 'sRGB', but this does of course not work
+ * on conformant C++ compilers. */
+#define BMP_LCS_sRGB 0x73524742
+#define BMP_LCS_GM_IMAGES 0x00000004L
+
+struct _CIEXYZ {
+ long ciexyzX, ciexyzY, ciexyzZ;
+};
+
+struct _CIEXYZTRIPLE {
+ _CIEXYZ ciexyzRed, ciexyzGreen, ciexyzBlue;
+};
+
+struct BMP_BITMAPV5HEADER {
+ DWORD bV5Size;
+ LONG bV5Width;
+ LONG bV5Height;
+ WORD bV5Planes;
+ WORD bV5BitCount;
+ DWORD bV5Compression;
+ DWORD bV5SizeImage;
+ LONG bV5XPelsPerMeter;
+ LONG bV5YPelsPerMeter;
+ DWORD bV5ClrUsed;
+ DWORD bV5ClrImportant;
+ DWORD bV5RedMask;
+ DWORD bV5GreenMask;
+ DWORD bV5BlueMask;
+ DWORD bV5AlphaMask;
+ DWORD bV5CSType;
+ _CIEXYZTRIPLE bV5Endpoints;
+ DWORD bV5GammaRed;
+ DWORD bV5GammaGreen;
+ DWORD bV5GammaBlue;
+ DWORD bV5Intent;
+ DWORD bV5ProfileData;
+ DWORD bV5ProfileSize;
+ DWORD bV5Reserved;
+};
+static const int BMP_BITFIELDS = 3;
+
+static const char dibFormatC[] = "dib";
+
+static inline QByteArray msgConversionError(const char *func, const char *format)
+{
+ QByteArray msg = func;
+ msg += ": Unable to convert DIB image. The image converter plugin for '";
+ msg += format;
+ msg += "' is not available. Available formats: ";
+ foreach (const QByteArray &af, QImageReader::supportedImageFormats()) {
+ msg += af;
+ msg += ' ';
+ }
+ return msg;
+}
+
+static inline QImage readDib(QByteArray data)
+{
+ QBuffer buffer(&data);
+ buffer.open(QIODevice::ReadOnly);
+ QImageReader reader(&buffer, dibFormatC);
+ if (!reader.canRead()) {
+ qWarning("%s", msgConversionError(__FUNCTION__, dibFormatC).constData());
+ return QImage();
+ }
+ return reader.read();
+}
+
+static QByteArray writeDib(const QImage &img)
+{
+ QByteArray ba;
+ QBuffer buffer(&ba);
+ buffer.open(QIODevice::ReadWrite);
+ QImageWriter writer(&buffer, dibFormatC);
+ if (!writer.canWrite()) {
+ qWarning("%s", msgConversionError(__FUNCTION__, dibFormatC).constData());
+ return ba;
+ }
+ if (!writer.write(img))
+ ba.clear();
+ return ba;
+}
+
+static bool qt_write_dibv5(QDataStream &s, QImage image)
+{
+ QIODevice* d = s.device();
+ if (!d->isWritable())
+ return false;
+
+ //depth will be always 32
+ int bpl_bmp = image.width()*4;
+
+ BMP_BITMAPV5HEADER bi ={0};
+ bi.bV5Size = sizeof(BMP_BITMAPV5HEADER);
+ bi.bV5Width = image.width();
+ bi.bV5Height = image.height();
+ bi.bV5Planes = 1;
+ bi.bV5BitCount = 32;
+ bi.bV5Compression = BI_BITFIELDS;
+ bi.bV5SizeImage = bpl_bmp*image.height();
+ bi.bV5XPelsPerMeter = 0;
+ bi.bV5YPelsPerMeter = 0;
+ bi.bV5ClrUsed = 0;
+ bi.bV5ClrImportant = 0;
+ bi.bV5BlueMask = 0x000000ff;
+ bi.bV5GreenMask = 0x0000ff00;
+ bi.bV5RedMask = 0x00ff0000;
+ bi.bV5AlphaMask = 0xff000000;
+ bi.bV5CSType = BMP_LCS_sRGB; //LCS_sRGB
+ bi.bV5Intent = BMP_LCS_GM_IMAGES; //LCS_GM_IMAGES
+
+ d->write(reinterpret_cast<const char*>(&bi), bi.bV5Size);
+ if (s.status() != QDataStream::Ok)
+ return false;
+
+ DWORD colorSpace[3] = {0x00ff0000,0x0000ff00,0x000000ff};
+ d->write(reinterpret_cast<const char*>(colorSpace), sizeof(colorSpace));
+ if (s.status() != QDataStream::Ok)
+ return false;
+
+ if (image.format() != QImage::Format_ARGB32)
+ image = image.convertToFormat(QImage::Format_ARGB32);
+
+ uchar *buf = new uchar[bpl_bmp];
+ uchar *b;
+
+ memset(buf, 0, bpl_bmp);
+ for (int y=image.height()-1; y>=0; y--) {
+ // write the image bits
+ QRgb *p = (QRgb *)image.scanLine(y);
+ QRgb *end = p + image.width();
+ b = buf;
+ while (p < end) {
+ int alpha = qAlpha(*p);
+ if (alpha) {
+ *b++ = qBlue(*p);
+ *b++ = qGreen(*p);
+ *b++ = qRed(*p);
+ } else {
+ //white for fully transparent pixels.
+ *b++ = 0xff;
+ *b++ = 0xff;
+ *b++ = 0xff;
+ }
+ *b++ = alpha;
+ p++;
+ }
+ d->write((char*)buf, bpl_bmp);
+ if (s.status() != QDataStream::Ok) {
+ delete[] buf;
+ return false;
+ }
+ }
+ delete[] buf;
+ return true;
+}
+
+static int calc_shift(int mask)
+{
+ int result = 0;
+ while (!(mask & 1)) {
+ result++;
+ mask >>= 1;
+ }
+ return result;
+}
+
+//Supports only 32 bit DIBV5
+static bool qt_read_dibv5(QDataStream &s, QImage &image)
+{
+ BMP_BITMAPV5HEADER bi;
+ QIODevice* d = s.device();
+ if (d->atEnd())
+ return false;
+
+ d->read((char *)&bi, sizeof(bi)); // read BITMAPV5HEADER header
+ if (s.status() != QDataStream::Ok)
+ return false;
+
+ int nbits = bi.bV5BitCount;
+ int comp = bi.bV5Compression;
+ if (nbits != 32 || bi.bV5Planes != 1 || comp != BMP_BITFIELDS)
+ return false; //Unsupported DIBV5 format
+
+ int w = bi.bV5Width, h = bi.bV5Height;
+ int red_mask = bi.bV5RedMask;
+ int green_mask = bi.bV5GreenMask;
+ int blue_mask = bi.bV5BlueMask;
+ int alpha_mask = bi.bV5AlphaMask;
+ int red_shift = 0;
+ int green_shift = 0;
+ int blue_shift = 0;
+ int alpha_shift = 0;
+ QImage::Format format = QImage::Format_ARGB32;
+
+ if (bi.bV5Height < 0)
+ h = -h; // support images with negative height
+ if (image.size() != QSize(w, h) || image.format() != format) {
+ image = QImage(w, h, format);
+ if (image.isNull()) // could not create image
+ return false;
+ }
+ image.setDotsPerMeterX(bi.bV5XPelsPerMeter);
+ image.setDotsPerMeterY(bi.bV5YPelsPerMeter);
+ // read color table
+ DWORD colorSpace[3];
+ if (d->read((char *)colorSpace, sizeof(colorSpace)) != sizeof(colorSpace))
+ return false;
+
+ red_shift = calc_shift(red_mask);
+ green_shift = calc_shift(green_mask);
+ blue_shift = calc_shift(blue_mask);
+ if (alpha_mask) {
+ alpha_shift = calc_shift(alpha_mask);
+ }
+
+ int bpl = image.bytesPerLine();
+ uchar *data = image.bits();
+ register QRgb *p;
+ QRgb *end;
+ uchar *buf24 = new uchar[bpl];
+ int bpl24 = ((w*nbits+31)/32)*4;
+ uchar *b;
+ unsigned int c;
+
+ while (--h >= 0) {
+ p = (QRgb *)(data + h*bpl);
+ end = p + w;
+ if (d->read((char *)buf24,bpl24) != bpl24)
+ break;
+ b = buf24;
+ while (p < end) {
+ c = *b | (*(b+1))<<8 | (*(b+2))<<16 | (*(b+3))<<24;
+ *p++ = qRgba(((c & red_mask) >> red_shift) ,
+ ((c & green_mask) >> green_shift),
+ ((c & blue_mask) >> blue_shift),
+ ((c & alpha_mask) >> alpha_shift));
+ b += 4;
+ }
+ }
+ delete[] buf24;
+
+ if (bi.bV5Height < 0) {
+ // Flip the image
+ uchar *buf = new uchar[bpl];
+ h = -bi.bV5Height;
+ for (int y = 0; y < h/2; ++y) {
+ memcpy(buf, data + y*bpl, bpl);
+ memcpy(data + y*bpl, data + (h-y-1)*bpl, bpl);
+ memcpy(data + (h-y-1)*bpl, buf, bpl);
+ }
+ delete [] buf;
+ }
+
+ return true;
+}
+
+//#define QMIME_DEBUG
+
+// helpers for using global memory
+
+static int getCf(const FORMATETC &formatetc)
+{
+ return formatetc.cfFormat;
+}
+
+static FORMATETC setCf(int cf)
+{
+ FORMATETC formatetc;
+ formatetc.cfFormat = cf;
+ formatetc.dwAspect = DVASPECT_CONTENT;
+ formatetc.lindex = -1;
+ formatetc.ptd = NULL;
+ formatetc.tymed = TYMED_HGLOBAL;
+ return formatetc;
+}
+
+static bool setData(const QByteArray &data, STGMEDIUM *pmedium)
+{
+ HGLOBAL hData = GlobalAlloc(0, data.size());
+ if (!hData)
+ return false;
+
+ void *out = GlobalLock(hData);
+ memcpy(out, data.data(), data.size());
+ GlobalUnlock(hData);
+ pmedium->tymed = TYMED_HGLOBAL;
+ pmedium->hGlobal = hData;
+ pmedium->pUnkForRelease = 0;
+ return true;
+}
+
+static QByteArray getData(int cf, IDataObject *pDataObj)
+{
+ QByteArray data;
+ FORMATETC formatetc = setCf(cf);
+ STGMEDIUM s;
+ if (pDataObj->GetData(&formatetc, &s) == S_OK) {
+ DWORD * val = (DWORD*)GlobalLock(s.hGlobal);
+ data = QByteArray::fromRawData((char*)val, GlobalSize(s.hGlobal));
+ data.detach();
+ GlobalUnlock(s.hGlobal);
+ ReleaseStgMedium(&s);
+ } else {
+ //Try reading IStream data
+ formatetc.tymed = TYMED_ISTREAM;
+ if (pDataObj->GetData(&formatetc, &s) == S_OK) {
+ char szBuffer[4096];
+ ULONG actualRead = 0;
+ LARGE_INTEGER pos = {{0, 0}};
+ //Move to front (can fail depending on the data model implemented)
+ HRESULT hr = s.pstm->Seek(pos, STREAM_SEEK_SET, NULL);
+ while(SUCCEEDED(hr)){
+ hr = s.pstm->Read(szBuffer, sizeof(szBuffer), &actualRead);
+ if (SUCCEEDED(hr) && actualRead > 0) {
+ data += QByteArray::fromRawData(szBuffer, actualRead);
+ }
+ if (actualRead != sizeof(szBuffer))
+ break;
+ }
+ data.detach();
+ ReleaseStgMedium(&s);
+ }
+ }
+ return data;
+}
+
+static bool canGetData(int cf, IDataObject * pDataObj)
+{
+ FORMATETC formatetc = setCf(cf);
+ if (pDataObj->QueryGetData(&formatetc) != S_OK){
+ formatetc.tymed = TYMED_ISTREAM;
+ return pDataObj->QueryGetData(&formatetc) == S_OK;
+ }
+ return true;
+}
+
+/*!
+ \class QWindowsMime
+ \brief The QWindowsMime class maps open-standard MIME to Window Clipboard formats.
+ \ingroup qt-lighthouse-win
+
+ Qt's drag-and-drop and clipboard facilities use the MIME standard.
+ On X11, this maps trivially to the Xdnd protocol, but on Windows
+ although some applications use MIME types to describe clipboard
+ formats, others use arbitrary non-standardized naming conventions,
+ or unnamed built-in formats of Windows.
+
+ By instantiating subclasses of QWindowsMime that provide conversions
+ between Windows Clipboard and MIME formats, you can convert
+ proprietary clipboard formats to MIME formats.
+
+ Qt has predefined support for the following Windows Clipboard formats:
+
+ \table
+ \header \o Windows Format \o Equivalent MIME type
+ \row \o \c CF_UNICODETEXT \o \c text/plain
+ \row \o \c CF_TEXT \o \c text/plain
+ \row \o \c CF_DIB \o \c{image/xyz}, where \c xyz is
+ a \l{QImageWriter::supportedImageFormats()}{Qt image format}
+ \row \o \c CF_HDROP \o \c text/uri-list
+ \row \o \c CF_INETURL \o \c text/uri-list
+ \row \o \c CF_HTML \o \c text/html
+ \endtable
+
+ An example use of this class would be to map the Windows Metafile
+ clipboard format (\c CF_METAFILEPICT) to and from the MIME type
+ \c{image/x-wmf}. This conversion might simply be adding or removing
+ a header, or even just passing on the data. See \l{Drag and Drop}
+ for more information on choosing and definition MIME types.
+
+ You can check if a MIME type is convertible using canConvertFromMime() and
+ can perform conversions with convertToMime() and convertFromMime().
+
+ \sa QWindowsMimeConverter
+*/
+
+/*!
+Constructs a new conversion object, adding it to the globally accessed
+list of available converters.
+*/
+QWindowsMime::QWindowsMime()
+{
+}
+
+/*!
+Destroys a conversion object, removing it from the global
+list of available converters.
+*/
+QWindowsMime::~QWindowsMime()
+{
+}
+
+/*!
+ Registers the MIME type \a mime, and returns an ID number
+ identifying the format on Windows.
+*/
+int QWindowsMime::registerMimeType(const QString &mime)
+{
+ int f = RegisterClipboardFormat(reinterpret_cast<const wchar_t *> (mime.utf16()));
+ if (!f)
+ qErrnoWarning("QWindowsMime::registerMimeType: Failed to register clipboard format");
+
+ return f;
+}
+
+/*!
+\fn bool QWindowsMime::canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const
+
+ Returns true if the converter can convert from the \a mimeData to
+ the format specified in \a formatetc.
+
+ All subclasses must reimplement this pure virtual function.
+*/
+
+/*!
+ \fn bool QWindowsMime::canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const
+
+ Returns true if the converter can convert to the \a mimeType from
+ the available formats in \a pDataObj.
+
+ All subclasses must reimplement this pure virtual function.
+*/
+
+/*!
+\fn QString QWindowsMime::mimeForFormat(const FORMATETC &formatetc) const
+
+ Returns the mime type that will be created form the format specified
+ in \a formatetc, or an empty string if this converter does not support
+ \a formatetc.
+
+ All subclasses must reimplement this pure virtual function.
+*/
+
+/*!
+\fn QVector<FORMATETC> QWindowsMime::formatsForMime(const QString &mimeType, const QMimeData *mimeData) const
+
+ Returns a QVector of FORMATETC structures representing the different windows clipboard
+ formats that can be provided for the \a mimeType from the \a mimeData.
+
+ All subclasses must reimplement this pure virtual function.
+*/
+
+/*!
+ \fn QVariant QWindowsMime::convertToMime(const QString &mimeType, IDataObject *pDataObj,
+ QVariant::Type preferredType) const
+
+ Returns a QVariant containing the converted data for \a mimeType from \a pDataObj.
+ If possible the QVariant should be of the \a preferredType to avoid needless conversions.
+
+ All subclasses must reimplement this pure virtual function.
+*/
+
+/*!
+\fn bool QWindowsMime::convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const
+
+ Convert the \a mimeData to the format specified in \a formatetc.
+ The converted data should then be placed in \a pmedium structure.
+
+ Return true if the conversion was successful.
+
+ All subclasses must reimplement this pure virtual function.
+*/
+
+class QWindowsMimeText : public QWindowsMime
+{
+public:
+ bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const;
+ QVariant convertToMime(const QString &mime, LPDATAOBJECT pDataObj, QVariant::Type preferredType) const;
+ QString mimeForFormat(const FORMATETC &formatetc) const;
+ bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const;
+ bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM *pmedium) const;
+ QVector<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const;
+};
+
+bool QWindowsMimeText::canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const
+{
+ int cf = getCf(formatetc);
+ return (cf == CF_UNICODETEXT || cf == CF_TEXT) && mimeData->hasText();
+}
+
+/*
+text/plain is defined as using CRLF, but so many programs don't,
+and programmers just look for '\n' in strings.
+Windows really needs CRLF, so we ensure it here.
+*/
+bool QWindowsMimeText::convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM *pmedium) const
+{
+ if (canConvertFromMime(formatetc, mimeData)) {
+ QByteArray data;
+ int cf = getCf(formatetc);
+ if (cf == CF_TEXT) {
+ data = mimeData->text().toLocal8Bit();
+ // Anticipate required space for CRLFs at 1/40
+ int maxsize=data.size()+data.size()/40+3;
+ QByteArray r(maxsize, '\0');
+ char* o = r.data();
+ const char* d = data.data();
+ const int s = data.size();
+ bool cr=false;
+ int j=0;
+ for (int i=0; i<s; i++) {
+ char c = d[i];
+ if (c=='\r')
+ cr=true;
+ else {
+ if (c=='\n') {
+ if (!cr)
+ o[j++]='\r';
+ }
+ cr=false;
+ }
+ o[j++]=c;
+ if (j+3 >= maxsize) {
+ maxsize += maxsize/4;
+ r.resize(maxsize);
+ o = r.data();
+ }
+ }
+ o[j]=0;
+ return setData(r, pmedium);
+ } else if (cf == CF_UNICODETEXT) {
+ QString str = mimeData->text();
+ const QChar *u = str.unicode();
+ QString res;
+ const int s = str.length();
+ int maxsize = s + s/40 + 3;
+ res.resize(maxsize);
+ int ri = 0;
+ bool cr = false;
+ for (int i=0; i < s; ++i) {
+ if (*u == QLatin1Char('\r'))
+ cr = true;
+ else {
+ if (*u == QLatin1Char('\n') && !cr)
+ res[ri++] = QLatin1Char('\r');
+ cr = false;
+ }
+ res[ri++] = *u;
+ if (ri+3 >= maxsize) {
+ maxsize += maxsize/4;
+ res.resize(maxsize);
+ }
+ ++u;
+ }
+ res.truncate(ri);
+ const int byteLength = res.length() * sizeof(ushort);
+ QByteArray r(byteLength + 2, '\0');
+ memcpy(r.data(), res.unicode(), byteLength);
+ r[byteLength] = 0;
+ r[byteLength+1] = 0;
+ return setData(r, pmedium);
+ }
+ }
+ return false;
+}
+
+bool QWindowsMimeText::canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const
+{
+ return mimeType.startsWith(QStringLiteral("text/plain"))
+ && (canGetData(CF_UNICODETEXT, pDataObj)
+ || canGetData(CF_TEXT, pDataObj));
+}
+
+QString QWindowsMimeText::mimeForFormat(const FORMATETC &formatetc) const
+{
+ int cf = getCf(formatetc);
+ if (cf == CF_UNICODETEXT || cf == CF_TEXT)
+ return QStringLiteral("text/plain");
+ return QString();
+}
+
+
+QVector<FORMATETC> QWindowsMimeText::formatsForMime(const QString &mimeType, const QMimeData *mimeData) const
+{
+ QVector<FORMATETC> formatics;
+ if (mimeType.startsWith(QStringLiteral("text/plain")) && mimeData->hasText()) {
+ formatics += setCf(CF_UNICODETEXT);
+ formatics += setCf(CF_TEXT);
+ }
+ return formatics;
+}
+
+QVariant QWindowsMimeText::convertToMime(const QString &mime, LPDATAOBJECT pDataObj, QVariant::Type preferredType) const
+{
+ QVariant ret;
+
+ if (canConvertToMime(mime, pDataObj)) {
+ QString str;
+ QByteArray data = getData(CF_UNICODETEXT, pDataObj);
+ if (!data.isEmpty()) {
+ str = QString::fromWCharArray((const wchar_t *)data.data());
+ str.replace(QStringLiteral("\r\n"), QStringLiteral("\n"));
+ } else {
+ data = getData(CF_TEXT, pDataObj);
+ if (!data.isEmpty()) {
+ const char* d = data.data();
+ const int s = qstrlen(d);
+ QByteArray r(data.size()+1, '\0');
+ char* o = r.data();
+ int j=0;
+ for (int i=0; i<s; i++) {
+ char c = d[i];
+ if (c!='\r')
+ o[j++]=c;
+ }
+ o[j]=0;
+ str = QString::fromLocal8Bit(r);
+ }
+ }
+ if (preferredType == QVariant::String)
+ ret = str;
+ else
+ ret = str.toUtf8();
+ }
+ if (QWindowsContext::verboseOLE)
+ qDebug() << __FUNCTION__ << ret;
+ return ret;
+}
+
+class QWindowsMimeURI : public QWindowsMime
+{
+public:
+ QWindowsMimeURI();
+ bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const;
+ QVariant convertToMime(const QString &mime, LPDATAOBJECT pDataObj, QVariant::Type preferredType) const;
+ QString mimeForFormat(const FORMATETC &formatetc) const;
+ bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const;
+ bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM *pmedium) const;
+ QVector<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const;
+private:
+ int CF_INETURL_W; // wide char version
+ int CF_INETURL;
+};
+
+QWindowsMimeURI::QWindowsMimeURI()
+{
+ CF_INETURL_W = QWindowsMime::registerMimeType(QStringLiteral("UniformResourceLocatorW"));
+ CF_INETURL = QWindowsMime::registerMimeType(QStringLiteral("UniformResourceLocator"));
+}
+
+bool QWindowsMimeURI::canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const
+{
+ if (getCf(formatetc) == CF_HDROP) {
+ QList<QUrl> urls = mimeData->urls();
+ for (int i=0; i<urls.size(); i++) {
+ if (!urls.at(i).toLocalFile().isEmpty())
+ return true;
+ }
+ }
+ return (getCf(formatetc) == CF_INETURL_W || getCf(formatetc) == CF_INETURL) && mimeData->hasFormat(QStringLiteral("text/uri-list"));
+}
+
+bool QWindowsMimeURI::convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM *pmedium) const
+{
+ if (canConvertFromMime(formatetc, mimeData)) {
+ if (getCf(formatetc) == CF_HDROP) {
+ QList<QUrl> urls = mimeData->urls();
+ QStringList fileNames;
+ int size = sizeof(DROPFILES)+2;
+ for (int i=0; i<urls.size(); i++) {
+ QString fn = QDir::toNativeSeparators(urls.at(i).toLocalFile());
+ if (!fn.isEmpty()) {
+ size += sizeof(ushort) * (fn.length() + 1);
+ fileNames.append(fn);
+ }
+ }
+
+ QByteArray result(size, '\0');
+ DROPFILES* d = (DROPFILES*)result.data();
+ d->pFiles = sizeof(DROPFILES);
+ GetCursorPos(&d->pt); // try
+ d->fNC = true;
+ char* files = ((char*)d) + d->pFiles;
+
+ d->fWide = true;
+ wchar_t* f = (wchar_t*)files;
+ for (int i=0; i<fileNames.size(); i++) {
+ int l = fileNames.at(i).length();
+ memcpy(f, fileNames.at(i).utf16(), l * sizeof(ushort));
+ f += l;
+ *f++ = 0;
+ }
+ *f = 0;
+
+ return setData(result, pmedium);
+ } else if (getCf(formatetc) == CF_INETURL_W) {
+ QList<QUrl> urls = mimeData->urls();
+ QByteArray result;
+ if (!urls.isEmpty()) {
+ QString url = urls.at(0).toString();
+ result = QByteArray((const char *)url.utf16(), url.length() * sizeof(ushort));
+ }
+ result.append('\0');
+ result.append('\0');
+ return setData(result, pmedium);
+ } else if (getCf(formatetc) == CF_INETURL) {
+ QList<QUrl> urls = mimeData->urls();
+ QByteArray result;
+ if (!urls.isEmpty())
+ result = urls.at(0).toString().toLocal8Bit();
+ return setData(result, pmedium);
+ }
+ }
+
+ return false;
+}
+
+bool QWindowsMimeURI::canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const
+{
+ return mimeType == QStringLiteral("text/uri-list")
+ && (canGetData(CF_HDROP, pDataObj) || canGetData(CF_INETURL_W, pDataObj) || canGetData(CF_INETURL, pDataObj));
+}
+
+QString QWindowsMimeURI::mimeForFormat(const FORMATETC &formatetc) const
+{
+ QString format;
+ if (getCf(formatetc) == CF_HDROP || getCf(formatetc) == CF_INETURL_W || getCf(formatetc) == CF_INETURL)
+ format = QStringLiteral("text/uri-list");
+ return format;
+}
+
+QVector<FORMATETC> QWindowsMimeURI::formatsForMime(const QString &mimeType, const QMimeData *mimeData) const
+{
+ QVector<FORMATETC> formatics;
+ if (mimeType == QStringLiteral("text/uri-list")) {
+ if (canConvertFromMime(setCf(CF_HDROP), mimeData))
+ formatics += setCf(CF_HDROP);
+ if (canConvertFromMime(setCf(CF_INETURL_W), mimeData))
+ formatics += setCf(CF_INETURL_W);
+ if (canConvertFromMime(setCf(CF_INETURL), mimeData))
+ formatics += setCf(CF_INETURL);
+ }
+ return formatics;
+}
+
+QVariant QWindowsMimeURI::convertToMime(const QString &mimeType, LPDATAOBJECT pDataObj, QVariant::Type preferredType) const
+{
+ if (mimeType == QStringLiteral("text/uri-list")) {
+ if (canGetData(CF_HDROP, pDataObj)) {
+ QByteArray texturi;
+ QList<QVariant> urls;
+
+ QByteArray data = getData(CF_HDROP, pDataObj);
+ if (data.isEmpty())
+ return QVariant();
+
+ LPDROPFILES hdrop = (LPDROPFILES)data.data();
+ if (hdrop->fWide) {
+ const wchar_t* filesw = (const wchar_t *)(data.data() + hdrop->pFiles);
+ int i = 0;
+ while (filesw[i]) {
+ QString fileurl = QString::fromWCharArray(filesw + i);
+ urls += QUrl::fromLocalFile(fileurl);
+ i += fileurl.length()+1;
+ }
+ } else {
+ const char* files = (const char *)data.data() + hdrop->pFiles;
+ int i=0;
+ while (files[i]) {
+ urls += QUrl::fromLocalFile(QString::fromLocal8Bit(files+i));
+ i += int(strlen(files+i))+1;
+ }
+ }
+
+ if (preferredType == QVariant::Url && urls.size() == 1)
+ return urls.at(0);
+ else if (!urls.isEmpty())
+ return urls;
+ } else if (canGetData(CF_INETURL_W, pDataObj)) {
+ QByteArray data = getData(CF_INETURL_W, pDataObj);
+ if (data.isEmpty())
+ return QVariant();
+ return QUrl(QString::fromWCharArray((const wchar_t *)data.constData()));
+ } else if (canGetData(CF_INETURL, pDataObj)) {
+ QByteArray data = getData(CF_INETURL, pDataObj);
+ if (data.isEmpty())
+ return QVariant();
+ return QUrl(QString::fromLocal8Bit(data.constData()));
+ }
+ }
+ return QVariant();
+}
+
+class QWindowsMimeHtml : public QWindowsMime
+{
+public:
+ QWindowsMimeHtml();
+
+ // for converting from Qt
+ bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const;
+ bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const;
+ QVector<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const;
+
+ // for converting to Qt
+ bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const;
+ QVariant convertToMime(const QString &mime, IDataObject *pDataObj, QVariant::Type preferredType) const;
+ QString mimeForFormat(const FORMATETC &formatetc) const;
+
+private:
+ int CF_HTML;
+};
+
+QWindowsMimeHtml::QWindowsMimeHtml()
+{
+ CF_HTML = QWindowsMime::registerMimeType(QStringLiteral("HTML Format"));
+}
+
+QVector<FORMATETC> QWindowsMimeHtml::formatsForMime(const QString &mimeType, const QMimeData *mimeData) const
+{
+ QVector<FORMATETC> formatetcs;
+ if (mimeType == QStringLiteral("text/html") && (!mimeData->html().isEmpty()))
+ formatetcs += setCf(CF_HTML);
+ return formatetcs;
+}
+
+QString QWindowsMimeHtml::mimeForFormat(const FORMATETC &formatetc) const
+{
+ if (getCf(formatetc) == CF_HTML)
+ return QStringLiteral("text/html");
+ return QString();
+}
+
+bool QWindowsMimeHtml::canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const
+{
+ return mimeType == QStringLiteral("text/html") && canGetData(CF_HTML, pDataObj);
+}
+
+
+bool QWindowsMimeHtml::canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const
+{
+ return getCf(formatetc) == CF_HTML && (!mimeData->html().isEmpty());
+}
+
+/*
+The windows HTML clipboard format is as follows (xxxxxxxxxx is a 10 integer number giving the positions
+in bytes). Charset used is mostly utf8, but can be different, ie. we have to look for the <meta> charset tag
+
+ Version: 1.0
+ StartHTML:xxxxxxxxxx
+ EndHTML:xxxxxxxxxx
+ StartFragment:xxxxxxxxxx
+ EndFragment:xxxxxxxxxx
+ ...html...
+
+*/
+QVariant QWindowsMimeHtml::convertToMime(const QString &mime, IDataObject *pDataObj, QVariant::Type preferredType) const
+{
+ Q_UNUSED(preferredType);
+ QVariant result;
+ if (canConvertToMime(mime, pDataObj)) {
+ QByteArray html = getData(CF_HTML, pDataObj);
+#ifdef QMIME_DEBUG
+ qDebug("QWindowsMimeHtml::convertToMime");
+ qDebug("raw :");
+ qDebug(html);
+#endif
+ int start = html.indexOf("StartFragment:");
+ int end = html.indexOf("EndFragment:");
+
+ if (start != -1) {
+ int startOffset = start + 14;
+ int i = startOffset;
+ while (html.at(i) != '\r' && html.at(i) != '\n')
+ ++i;
+ QByteArray bytecount = html.mid(startOffset, i - startOffset);
+ start = bytecount.toInt();
+ }
+
+ if (end != -1) {
+ int endOffset = end + 12;
+ int i = endOffset ;
+ while (html.at(i) != '\r' && html.at(i) != '\n')
+ ++i;
+ QByteArray bytecount = html.mid(endOffset , i - endOffset);
+ end = bytecount.toInt();
+ }
+
+ if (end > start && start > 0) {
+ html = "<!--StartFragment-->" + html.mid(start, end - start);
+ html += "<!--EndFragment-->";
+ html.replace('\r', "");
+ result = QString::fromUtf8(html);
+ }
+ }
+ return result;
+}
+
+bool QWindowsMimeHtml::convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const
+{
+ if (canConvertFromMime(formatetc, mimeData)) {
+ QByteArray data = mimeData->html().toUtf8();
+ QByteArray result =
+ "Version:1.0\r\n" // 0-12
+ "StartHTML:0000000105\r\n" // 13-35
+ "EndHTML:0000000000\r\n" // 36-55
+ "StartFragment:0000000000\r\n" // 58-86
+ "EndFragment:0000000000\r\n\r\n"; // 87-105
+
+ if (data.indexOf("<!--StartFragment-->") == -1)
+ result += "<!--StartFragment-->";
+ result += data;
+ if (data.indexOf("<!--EndFragment-->") == -1)
+ result += "<!--EndFragment-->";
+
+ // set the correct number for EndHTML
+ QByteArray pos = QString::number(result.size()).toLatin1();
+ memcpy((char *)(result.data() + 53 - pos.length()), pos.constData(), pos.length());
+
+ // set correct numbers for StartFragment and EndFragment
+ pos = QString::number(result.indexOf("<!--StartFragment-->") + 20).toLatin1();
+ memcpy((char *)(result.data() + 79 - pos.length()), pos.constData(), pos.length());
+ pos = QString::number(result.indexOf("<!--EndFragment-->")).toLatin1();
+ memcpy((char *)(result.data() + 103 - pos.length()), pos.constData(), pos.length());
+
+ return setData(result, pmedium);
+ }
+ return false;
+}
+
+
+#ifndef QT_NO_IMAGEFORMAT_BMP
+class QWindowsMimeImage : public QWindowsMime
+{
+public:
+ QWindowsMimeImage();
+ // for converting from Qt
+ bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const;
+ bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const;
+ QVector<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const;
+
+ // for converting to Qt
+ bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const;
+ QVariant convertToMime(const QString &mime, IDataObject *pDataObj, QVariant::Type preferredType) const;
+ QString mimeForFormat(const FORMATETC &formatetc) const;
+private:
+ bool hasOriginalDIBV5(IDataObject *pDataObj) const;
+ UINT CF_PNG;
+};
+
+QWindowsMimeImage::QWindowsMimeImage()
+{
+ CF_PNG = RegisterClipboardFormat(L"PNG");
+}
+
+QVector<FORMATETC> QWindowsMimeImage::formatsForMime(const QString &mimeType, const QMimeData *mimeData) const
+{
+ QVector<FORMATETC> formatetcs;
+ if (mimeData->hasImage() && mimeType == QStringLiteral("application/x-qt-image")) {
+ //add DIBV5 if image has alpha channel
+ QImage image = qvariant_cast<QImage>(mimeData->imageData());
+ if (!image.isNull() && image.hasAlphaChannel())
+ formatetcs += setCf(CF_DIBV5);
+ formatetcs += setCf(CF_DIB);
+ }
+ return formatetcs;
+}
+
+QString QWindowsMimeImage::mimeForFormat(const FORMATETC &formatetc) const
+{
+ int cf = getCf(formatetc);
+ if (cf == CF_DIB || cf == CF_DIBV5 || cf == int(CF_PNG))
+ return QStringLiteral("application/x-qt-image");
+ return QString();
+}
+
+bool QWindowsMimeImage::canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const
+{
+ if ((mimeType == QStringLiteral("application/x-qt-image")) &&
+ (canGetData(CF_DIB, pDataObj) || canGetData(CF_PNG, pDataObj)))
+ return true;
+ return false;
+}
+
+bool QWindowsMimeImage::canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const
+{
+ int cf = getCf(formatetc);
+ if (mimeData->hasImage()) {
+ if (cf == CF_DIB)
+ return true;
+ else if (cf == CF_DIBV5) {
+ //support DIBV5 conversion only if the image has alpha channel
+ QImage image = qvariant_cast<QImage>(mimeData->imageData());
+ if (!image.isNull() && image.hasAlphaChannel())
+ return true;
+ }
+ }
+ return false;
+}
+
+bool QWindowsMimeImage::convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const
+{
+ int cf = getCf(formatetc);
+ if ((cf == CF_DIB || cf == CF_DIBV5) && mimeData->hasImage()) {
+ QImage img = qvariant_cast<QImage>(mimeData->imageData());
+ if (img.isNull())
+ return false;
+ QByteArray ba;
+ if (cf == CF_DIB) {
+ if (img.format() > QImage::Format_ARGB32)
+ img = img.convertToFormat(QImage::Format_RGB32);
+ const QByteArray ba = writeDib(img);
+ if (!ba.isEmpty())
+ return setData(ba, pmedium);
+ } else {
+ QDataStream s(&ba, QIODevice::WriteOnly);
+ s.setByteOrder(QDataStream::LittleEndian);// Intel byte order ####
+ if (qt_write_dibv5(s, img))
+ return setData(ba, pmedium);
+ }
+ }
+ return false;
+}
+
+bool QWindowsMimeImage::hasOriginalDIBV5(IDataObject *pDataObj) const
+{
+ bool isSynthesized = true;
+ IEnumFORMATETC *pEnum =NULL;
+ HRESULT res = pDataObj->EnumFormatEtc(1, &pEnum);
+ if (res == S_OK && pEnum) {
+ FORMATETC fc;
+ while ((res = pEnum->Next(1, &fc, 0)) == S_OK) {
+ if (fc.ptd)
+ CoTaskMemFree(fc.ptd);
+ if (fc.cfFormat == CF_DIB)
+ break;
+ else if (fc.cfFormat == CF_DIBV5) {
+ isSynthesized = false;
+ break;
+ }
+ }
+ pEnum->Release();
+ }
+ return !isSynthesized;
+}
+
+QVariant QWindowsMimeImage::convertToMime(const QString &mimeType, IDataObject *pDataObj, QVariant::Type preferredType) const
+{
+ Q_UNUSED(preferredType);
+ QVariant result;
+ if (mimeType != QStringLiteral("application/x-qt-image"))
+ return result;
+ //Try to convert from a format which has more data
+ //DIBV5, use only if its is not synthesized
+ if (canGetData(CF_DIBV5, pDataObj) && hasOriginalDIBV5(pDataObj)) {
+ QImage img;
+ QByteArray data = getData(CF_DIBV5, pDataObj);
+ QDataStream s(&data, QIODevice::ReadOnly);
+ s.setByteOrder(QDataStream::LittleEndian);
+ if (qt_read_dibv5(s, img)) { // #### supports only 32bit DIBV5
+ return img;
+ }
+ }
+ //PNG, MS Office place this (undocumented)
+ if (canGetData(CF_PNG, pDataObj)) {
+ QImage img;
+ QByteArray data = getData(CF_PNG, pDataObj);
+ if (img.loadFromData(data, "PNG")) {
+ return img;
+ }
+ }
+ //Fallback to DIB
+ if (canGetData(CF_DIB, pDataObj)) {
+ const QImage img = readDib(getData(CF_DIB, pDataObj));
+ if (!img.isNull())
+ return img;
+ }
+ // Failed
+ return result;
+}
+#endif
+
+class QBuiltInMimes : public QWindowsMime
+{
+public:
+ QBuiltInMimes();
+
+ // for converting from Qt
+ bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const;
+ bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const;
+ QVector<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const;
+
+ // for converting to Qt
+ bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const;
+ QVariant convertToMime(const QString &mime, IDataObject *pDataObj, QVariant::Type preferredType) const;
+ QString mimeForFormat(const FORMATETC &formatetc) const;
+
+private:
+ QMap<int, QString> outFormats;
+ QMap<int, QString> inFormats;
+};
+
+QBuiltInMimes::QBuiltInMimes()
+: QWindowsMime()
+{
+ outFormats.insert(QWindowsMime::registerMimeType(QStringLiteral("application/x-color")), QStringLiteral("application/x-color"));
+ inFormats.insert(QWindowsMime::registerMimeType(QStringLiteral("application/x-color")), QStringLiteral("application/x-color"));
+}
+
+bool QBuiltInMimes::canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const
+{
+ // really check
+ return formatetc.tymed & TYMED_HGLOBAL
+ && outFormats.contains(formatetc.cfFormat)
+ && mimeData->formats().contains(outFormats.value(formatetc.cfFormat));
+}
+
+bool QBuiltInMimes::convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const
+{
+ if (canConvertFromMime(formatetc, mimeData)) {
+ QByteArray data;
+ if (outFormats.value(getCf(formatetc)) == QStringLiteral("text/html")) {
+ // text/html is in wide chars on windows (compatible with mozillia)
+ QString html = mimeData->html();
+ // same code as in the text converter up above
+ const QChar *u = html.unicode();
+ QString res;
+ const int s = html.length();
+ int maxsize = s + s/40 + 3;
+ res.resize(maxsize);
+ int ri = 0;
+ bool cr = false;
+ for (int i=0; i < s; ++i) {
+ if (*u == QLatin1Char('\r'))
+ cr = true;
+ else {
+ if (*u == QLatin1Char('\n') && !cr)
+ res[ri++] = QLatin1Char('\r');
+ cr = false;
+ }
+ res[ri++] = *u;
+ if (ri+3 >= maxsize) {
+ maxsize += maxsize/4;
+ res.resize(maxsize);
+ }
+ ++u;
+ }
+ res.truncate(ri);
+ const int byteLength = res.length() * sizeof(ushort);
+ QByteArray r(byteLength + 2, '\0');
+ memcpy(r.data(), res.unicode(), byteLength);
+ r[byteLength] = 0;
+ r[byteLength+1] = 0;
+ data = r;
+ } else {
+#ifndef QT_NO_DRAGANDDROP
+ data = QInternalMimeData::renderDataHelper(outFormats.value(getCf(formatetc)), mimeData);
+#endif //QT_NO_DRAGANDDROP
+ }
+ return setData(data, pmedium);
+ }
+ return false;
+}
+
+QVector<FORMATETC> QBuiltInMimes::formatsForMime(const QString &mimeType, const QMimeData *mimeData) const
+{
+ QVector<FORMATETC> formatetcs;
+ if (!outFormats.keys(mimeType).isEmpty() && mimeData->formats().contains(mimeType))
+ formatetcs += setCf(outFormats.key(mimeType));
+ return formatetcs;
+}
+
+bool QBuiltInMimes::canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const
+{
+ return (!inFormats.keys(mimeType).isEmpty())
+ && canGetData(inFormats.key(mimeType), pDataObj);
+}
+
+QVariant QBuiltInMimes::convertToMime(const QString &mimeType, IDataObject *pDataObj, QVariant::Type preferredType) const
+{
+ QVariant val;
+ if (canConvertToMime(mimeType, pDataObj)) {
+ QByteArray data = getData(inFormats.key(mimeType), pDataObj);
+ if (!data.isEmpty()) {
+#ifdef QMIME_DEBUG
+ qDebug("QBuiltInMimes::convertToMime()");
+#endif
+ if (mimeType == QStringLiteral("text/html") && preferredType == QVariant::String) {
+ // text/html is in wide chars on windows (compatible with Mozilla)
+ val = QString::fromWCharArray((const wchar_t *)data.data());
+ } else {
+ val = data; // it should be enough to return the data and let QMimeData do the rest.
+ }
+ }
+ }
+ return val;
+}
+
+QString QBuiltInMimes::mimeForFormat(const FORMATETC &formatetc) const
+{
+ return inFormats.value(getCf(formatetc));
+}
+
+
+class QLastResortMimes : public QWindowsMime
+{
+public:
+
+ QLastResortMimes();
+ // for converting from Qt
+ bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const;
+ bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const;
+ QVector<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const;
+
+ // for converting to Qt
+ bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const;
+ QVariant convertToMime(const QString &mime, IDataObject *pDataObj, QVariant::Type preferredType) const;
+ QString mimeForFormat(const FORMATETC &formatetc) const;
+
+private:
+ QMap<int, QString> formats;
+ static QStringList ianaTypes;
+ static QStringList excludeList;
+};
+
+QStringList QLastResortMimes::ianaTypes;
+QStringList QLastResortMimes::excludeList;
+
+QLastResortMimes::QLastResortMimes()
+{
+ //MIME Media-Types
+ if (!ianaTypes.size()) {
+ ianaTypes.append(QStringLiteral("application/"));
+ ianaTypes.append(QStringLiteral("audio/"));
+ ianaTypes.append(QStringLiteral("example/"));
+ ianaTypes.append(QStringLiteral("image/"));
+ ianaTypes.append(QStringLiteral("message/"));
+ ianaTypes.append(QStringLiteral("model/"));
+ ianaTypes.append(QStringLiteral("multipart/"));
+ ianaTypes.append(QStringLiteral("text/"));
+ ianaTypes.append(QStringLiteral("video/"));
+ }
+ //Types handled by other classes
+ if (!excludeList.size()) {
+ excludeList.append(QStringLiteral("HTML Format"));
+ excludeList.append(QStringLiteral("UniformResourceLocator"));
+ excludeList.append(QStringLiteral("text/html"));
+ excludeList.append(QStringLiteral("text/plain"));
+ excludeList.append(QStringLiteral("text/uri-list"));
+ excludeList.append(QStringLiteral("application/x-qt-image"));
+ excludeList.append(QStringLiteral("application/x-color"));
+ }
+}
+
+bool QLastResortMimes::canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const
+{
+ // really check
+#ifndef QT_NO_DRAGANDDROP
+ return formatetc.tymed & TYMED_HGLOBAL
+ && (formats.contains(formatetc.cfFormat)
+ && QInternalMimeData::hasFormatHelper(formats.value(formatetc.cfFormat), mimeData));
+#else
+ Q_UNUSED(mimeData);
+ Q_UNUSED(formatetc);
+ return formatetc.tymed & TYMED_HGLOBAL
+ && formats.contains(formatetc.cfFormat);
+#endif //QT_NO_DRAGANDDROP
+}
+
+bool QLastResortMimes::convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const
+{
+#ifndef QT_NO_DRAGANDDROP
+ return canConvertFromMime(formatetc, mimeData)
+ && setData(QInternalMimeData::renderDataHelper(formats.value(getCf(formatetc)), mimeData), pmedium);
+#else
+ Q_UNUSED(mimeData);
+ Q_UNUSED(formatetc);
+ Q_UNUSED(pmedium);
+ return false;
+#endif //QT_NO_DRAGANDDROP
+}
+
+QVector<FORMATETC> QLastResortMimes::formatsForMime(const QString &mimeType, const QMimeData * /*mimeData*/) const
+{
+ QVector<FORMATETC> formatetcs;
+ if (!formats.keys(mimeType).isEmpty()) {
+ formatetcs += setCf(formats.key(mimeType));
+ } else if (!excludeList.contains(mimeType, Qt::CaseInsensitive)){
+ // register any other available formats
+ int cf = QWindowsMime::registerMimeType(mimeType);
+ QLastResortMimes *that = const_cast<QLastResortMimes *>(this);
+ that->formats.insert(cf, mimeType);
+ formatetcs += setCf(cf);
+ }
+ return formatetcs;
+}
+static const char x_qt_windows_mime[] = "application/x-qt-windows-mime;value=\"";
+
+static bool isCustomMimeType(const QString &mimeType)
+{
+ return mimeType.startsWith(QLatin1String(x_qt_windows_mime), Qt::CaseInsensitive);
+}
+
+static QString customMimeType(const QString &mimeType)
+{
+ int len = sizeof(x_qt_windows_mime) - 1;
+ int n = mimeType.lastIndexOf(QLatin1Char('\"'))-len;
+ return mimeType.mid(len, n);
+}
+
+bool QLastResortMimes::canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const
+{
+ if (isCustomMimeType(mimeType)) {
+ QString clipFormat = customMimeType(mimeType);
+ int cf = RegisterClipboardFormat(reinterpret_cast<const wchar_t *> (clipFormat.utf16()));
+ return canGetData(cf, pDataObj);
+ } else if (formats.keys(mimeType).isEmpty()) {
+ // if it is not in there then register it an see if we can get it
+ int cf = QWindowsMime::registerMimeType(mimeType);
+ return canGetData(cf, pDataObj);
+ } else {
+ return canGetData(formats.key(mimeType), pDataObj);
+ }
+ return false;
+}
+
+QVariant QLastResortMimes::convertToMime(const QString &mimeType, IDataObject *pDataObj, QVariant::Type preferredType) const
+{
+ Q_UNUSED(preferredType);
+ QVariant val;
+ if (canConvertToMime(mimeType, pDataObj)) {
+ QByteArray data;
+ if (isCustomMimeType(mimeType)) {
+ QString clipFormat = customMimeType(mimeType);
+ int cf = RegisterClipboardFormat(reinterpret_cast<const wchar_t *> (clipFormat.utf16()));
+ data = getData(cf, pDataObj);
+ } else if (formats.keys(mimeType).isEmpty()) {
+ int cf = QWindowsMime::registerMimeType(mimeType);
+ data = getData(cf, pDataObj);
+ } else {
+ data = getData(formats.key(mimeType), pDataObj);
+ }
+ if (!data.isEmpty())
+ val = data; // it should be enough to return the data and let QMimeData do the rest.
+ }
+ return val;
+}
+
+QString QLastResortMimes::mimeForFormat(const FORMATETC &formatetc) const
+{
+ QString format = formats.value(getCf(formatetc));
+ if (!format.isEmpty())
+ return format;
+
+ wchar_t buffer[256];
+ int len = GetClipboardFormatName(getCf(formatetc), buffer, 256);
+
+ if (len) {
+ QString clipFormat = QString::fromWCharArray(buffer, len);
+#ifndef QT_NO_DRAGANDDROP
+ if (QInternalMimeData::canReadData(clipFormat))
+ format = clipFormat;
+ else if((formatetc.cfFormat >= 0xC000)){
+ //create the mime as custom. not registered.
+ if (!excludeList.contains(clipFormat, Qt::CaseInsensitive)) {
+ //check if this is a mime type
+ bool ianaType = false;
+ int sz = ianaTypes.size();
+ for (int i = 0; i < sz; i++) {
+ if (clipFormat.startsWith(ianaTypes[i], Qt::CaseInsensitive)) {
+ ianaType = true;
+ break;
+ }
+ }
+ if (!ianaType)
+ format = QLatin1String(x_qt_windows_mime) + clipFormat + QLatin1Char('\"');
+ else
+ format = clipFormat;
+ }
+ }
+#endif //QT_NO_DRAGANDDROP
+ }
+
+ return format;
+}
+
+/*!
+ \class QWindowsMimeConverter
+ \brief Manages the list of QWindowsMime instances.
+ \ingroup qt-lighthouse-win
+ \sa QWindowsMime
+*/
+
+QWindowsMimeConverter::QWindowsMimeConverter()
+{
+}
+
+QWindowsMimeConverter::~QWindowsMimeConverter()
+{
+ qDeleteAll(m_mimes);
+}
+
+QWindowsMime * QWindowsMimeConverter::converterToMime(const QString &mimeType, IDataObject *pDataObj) const
+{
+ ensureInitialized();
+ for (int i = m_mimes.size()-1; i >= 0; --i) {
+ if (m_mimes.at(i)->canConvertToMime(mimeType, pDataObj))
+ return m_mimes.at(i);
+ }
+ return 0;
+}
+
+QStringList QWindowsMimeConverter::allMimesForFormats(IDataObject *pDataObj) const
+{
+ ensureInitialized();
+ QStringList formats;
+ LPENUMFORMATETC FAR fmtenum;
+ HRESULT hr = pDataObj->EnumFormatEtc(DATADIR_GET, &fmtenum);
+
+ if (hr == NOERROR) {
+ FORMATETC fmtetc;
+ while (S_OK == fmtenum->Next(1, &fmtetc, 0)) {
+#if defined(QMIME_DEBUG)
+ qDebug("QWindowsMime::allMimesForFormats()");
+ wchar_t buf[256] = {0};
+ GetClipboardFormatName(fmtetc.cfFormat, buf, 255);
+ qDebug("CF = %d : %s", fmtetc.cfFormat, QString::fromWCharArray(buf));
+#endif
+ for (int i= m_mimes.size() - 1; i >= 0; --i) {
+ QString format = m_mimes.at(i)->mimeForFormat(fmtetc);
+ if (!format.isEmpty() && !formats.contains(format)) {
+ formats += format;
+ }
+ }
+ // as documented in MSDN to avoid possible memleak
+ if (fmtetc.ptd)
+ CoTaskMemFree(fmtetc.ptd);
+ }
+ fmtenum->Release();
+ }
+ if (QWindowsContext::verboseOLE)
+ qDebug() << __FUNCTION__ << pDataObj << formats;
+ return formats;
+}
+
+QWindowsMime * QWindowsMimeConverter::converterFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const
+{
+ ensureInitialized();
+ for (int i = m_mimes.size()-1; i >= 0; --i) {
+ if (m_mimes.at(i)->canConvertFromMime(formatetc, mimeData))
+ return m_mimes.at(i);
+ }
+ return 0;
+}
+
+QVector<FORMATETC> QWindowsMimeConverter::allFormatsForMime(const QMimeData *mimeData) const
+{
+ ensureInitialized();
+ QVector<FORMATETC> formatics;
+#ifdef QT_NO_DRAGANDDROP
+ Q_UNUSED(mimeData);
+#else
+ formatics.reserve(20);
+ const QStringList formats = QInternalMimeData::formatsHelper(mimeData);
+ for (int f = 0; f < formats.size(); ++f) {
+ for (int i = m_mimes.size() - 1; i >= 0; --i)
+ formatics += m_mimes.at(i)->formatsForMime(formats.at(f), mimeData);
+ }
+#endif //QT_NO_DRAGANDDROP
+ return formatics;
+}
+
+void QWindowsMimeConverter::ensureInitialized() const
+{
+ if (m_mimes.isEmpty()) {
+ m_mimes << new QWindowsMimeImage << new QLastResortMimes
+ << new QWindowsMimeText << new QWindowsMimeURI
+ << new QWindowsMimeHtml << new QBuiltInMimes;
+ }
+}
+
+QVariant QWindowsMimeConverter::convertToMime(const QStringList &mimeTypes,
+ IDataObject *pDataObj,
+ QVariant::Type preferredType,
+ QString *formatIn /* = 0 */) const
+{
+ foreach (const QString &format, mimeTypes) {
+ if (const QWindowsMime *converter = converterToMime(format, pDataObj)) {
+ if (converter->canConvertToMime(format, pDataObj)) {
+ const QVariant dataV = converter->convertToMime(format, pDataObj, preferredType);
+ if (dataV.isValid()) {
+ if (QWindowsContext::verboseOLE)
+ qDebug() << __FUNCTION__ << mimeTypes << "\nFormat: "
+ << format << pDataObj << " returns " << dataV;
+ if (formatIn)
+ *formatIn = format;
+ return dataV;
+ }
+ }
+ }
+ }
+ if (QWindowsContext::verboseOLE)
+ qDebug() << __FUNCTION__ << "fails" << mimeTypes << pDataObj << preferredType;
+ return QVariant();
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsmime.h b/src/plugins/platforms/windows/qwindowsmime.h
new file mode 100644
index 0000000000..85f61a91e2
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsmime.h
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSMIME_H
+#define QWINDOWSMIME_H
+
+#include "qtwindows_additional.h"
+
+#include <QtCore/QVector>
+#include <QtCore/QList>
+#include <QtCore/QVariant>
+#include <QtCore/QSharedPointer>
+
+QT_BEGIN_NAMESPACE
+
+class QMimeData;
+
+class QWindowsMime
+{
+ Q_DISABLE_COPY(QWindowsMime)
+public:
+ QWindowsMime();
+ virtual ~QWindowsMime();
+
+ // for converting from Qt
+ virtual bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const = 0;
+ virtual bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const = 0;
+ virtual QVector<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const = 0;
+
+ // for converting to Qt
+ virtual bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const = 0;
+ virtual QVariant convertToMime(const QString &mimeType, IDataObject *pDataObj, QVariant::Type preferredType) const = 0;
+ virtual QString mimeForFormat(const FORMATETC &formatetc) const = 0;
+
+ static int registerMimeType(const QString &mime);
+};
+
+class QWindowsMimeConverter
+{
+ Q_DISABLE_COPY(QWindowsMimeConverter)
+public:
+ QWindowsMimeConverter();
+ ~QWindowsMimeConverter();
+
+ QWindowsMime *converterToMime(const QString &mimeType, IDataObject *pDataObj) const;
+ QStringList allMimesForFormats(IDataObject *pDataObj) const;
+ QWindowsMime *converterFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const;
+ QVector<FORMATETC> allFormatsForMime(const QMimeData *mimeData) const;
+
+ // Convenience.
+ QVariant convertToMime(const QStringList &mimeTypes, IDataObject *pDataObj, QVariant::Type preferredType,
+ QString *format = 0) const;
+
+private:
+ typedef QSharedPointer<QWindowsMime> MimePtr;
+
+ void ensureInitialized() const;
+
+ mutable QList<QWindowsMime *> m_mimes;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSMIME_H
diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.cpp b/src/plugins/platforms/windows/qwindowsmousehandler.cpp
new file mode 100644
index 0000000000..dea965b439
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsmousehandler.cpp
@@ -0,0 +1,288 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsmousehandler.h"
+#include "qwindowscontext.h"
+#include "qwindowswindow.h"
+#include "qwindowsintegration.h"
+
+#include <QtGui/QWindowSystemInterface>
+#include <QtGui/QGuiApplication>
+#include <QtGui/QScreen>
+
+#include <QtCore/QDebug>
+#include <QtCore/QScopedArrayPointer>
+
+#include <windowsx.h>
+
+QT_BEGIN_NAMESPACE
+
+static inline void compressMouseMove(MSG *msg)
+{
+ // Compress mouse move events
+ if (msg->message == WM_MOUSEMOVE) {
+ MSG mouseMsg;
+ while (PeekMessage(&mouseMsg, msg->hwnd, WM_MOUSEFIRST,
+ WM_MOUSELAST, PM_NOREMOVE)) {
+ if (mouseMsg.message == WM_MOUSEMOVE) {
+#define PEEKMESSAGE_IS_BROKEN 1
+#ifdef PEEKMESSAGE_IS_BROKEN
+ // Since the Windows PeekMessage() function doesn't
+ // correctly return the wParam for WM_MOUSEMOVE events
+ // if there is a key release event in the queue
+ // _before_ the mouse event, we have to also consider
+ // key release events (kls 2003-05-13):
+ MSG keyMsg;
+ bool done = false;
+ while (PeekMessage(&keyMsg, 0, WM_KEYFIRST, WM_KEYLAST,
+ PM_NOREMOVE)) {
+ if (keyMsg.time < mouseMsg.time) {
+ if ((keyMsg.lParam & 0xC0000000) == 0x40000000) {
+ PeekMessage(&keyMsg, 0, keyMsg.message,
+ keyMsg.message, PM_REMOVE);
+ } else {
+ done = true;
+ break;
+ }
+ } else {
+ break; // no key event before the WM_MOUSEMOVE event
+ }
+ }
+ if (done)
+ break;
+#else
+ // Actually the following 'if' should work instead of
+ // the above key event checking, but apparently
+ // PeekMessage() is broken :-(
+ if (mouseMsg.wParam != msg.wParam)
+ break; // leave the message in the queue because
+ // the key state has changed
+#endif
+ // Update the passed in MSG structure with the
+ // most recent one.
+ msg->lParam = mouseMsg.lParam;
+ msg->wParam = mouseMsg.wParam;
+ // Extract the x,y coordinates from the lParam as we do in the WndProc
+ msg->pt.x = GET_X_LPARAM(mouseMsg.lParam);
+ msg->pt.y = GET_Y_LPARAM(mouseMsg.lParam);
+ ClientToScreen(msg->hwnd, &(msg->pt));
+ // Remove the mouse move message
+ PeekMessage(&mouseMsg, msg->hwnd, WM_MOUSEMOVE,
+ WM_MOUSEMOVE, PM_REMOVE);
+ } else {
+ break; // there was no more WM_MOUSEMOVE event
+ }
+ }
+ }
+}
+
+/*!
+ \class QWindowsMouseHandler
+ \brief Windows mouse handler
+
+ Dispatches mouse and touch events. Separate for code cleanliness.
+
+ \ingroup qt-lighthouse-win
+*/
+
+QWindowsMouseHandler::QWindowsMouseHandler() :
+ m_windowUnderMouse(0)
+{
+}
+
+bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
+ QtWindows::WindowsEventType et,
+ MSG msg, LRESULT *result)
+{
+ if (et & QtWindows::NonClientEventFlag)
+ return false;
+ if (et == QtWindows::MouseWheelEvent)
+ return translateMouseWheelEvent(window, hwnd, msg, result);
+ *result = 0;
+ if (msg.message == WM_MOUSELEAVE) {
+ // When moving out of a child, MouseMove within parent is received first
+ // (see below)
+ if (QWindowsContext::verboseEvents)
+ qDebug() << "WM_MOUSELEAVE for " << window << " current= " << m_windowUnderMouse;
+ if (window == m_windowUnderMouse) {
+ QWindowSystemInterface::handleLeaveEvent(window);
+ m_windowUnderMouse = 0;
+ }
+ return true;
+ }
+ compressMouseMove(&msg);
+ const QPoint client(GET_X_LPARAM(msg.lParam), GET_Y_LPARAM(msg.lParam));
+ // Enter new window: track to generate leave event.
+ if (m_windowUnderMouse != window) {
+ // The tracking on m_windowUnderMouse might still be active and
+ // trigger later on.
+ if (m_windowUnderMouse) {
+ if (QWindowsContext::verboseEvents)
+ qDebug() << "Synthetic leave for " << m_windowUnderMouse;
+ QWindowSystemInterface::handleLeaveEvent(m_windowUnderMouse);
+ }
+ m_windowUnderMouse = window;
+ if (QWindowsContext::verboseEvents)
+ qDebug() << "Entering " << window;
+ QWindowsWindow::baseWindowOf(window)->applyCursor();
+ QWindowSystemInterface::handleEnterEvent(window);
+ TRACKMOUSEEVENT tme;
+ tme.cbSize = sizeof(TRACKMOUSEEVENT);
+ tme.dwFlags = TME_LEAVE;
+ tme.hwndTrack = hwnd;
+ tme.dwHoverTime = HOVER_DEFAULT; //
+ if (!TrackMouseEvent(&tme))
+ qWarning("TrackMouseEvent failed.");
+ }
+ QWindowSystemInterface::handleMouseEvent(window, client,
+ QWindowsGeometryHint::mapToGlobal(hwnd, client),
+ keyStateToMouseButtons((int)msg.wParam));
+ return true;
+}
+
+bool QWindowsMouseHandler::translateMouseWheelEvent(QWindow *window, HWND,
+ MSG msg, LRESULT *)
+{
+ const Qt::MouseButtons buttons = keyStateToMouseButtons((int)msg.wParam);
+ int delta;
+ if (msg.message == WM_MOUSEWHEEL || msg.message == WM_MOUSEHWHEEL)
+ delta = (short) HIWORD (msg.wParam);
+ else
+ delta = (int) msg.wParam;
+
+ Qt::Orientation orientation = (msg.message == WM_MOUSEHWHEEL
+ || (buttons & Qt::AltModifier)) ?
+ Qt::Horizontal : Qt::Vertical;
+
+ // according to the MSDN documentation on WM_MOUSEHWHEEL:
+ // a positive value indicates that the wheel was rotated to the right;
+ // a negative value indicates that the wheel was rotated to the left.
+ // Qt defines this value as the exact opposite, so we have to flip the value!
+ if (msg.message == WM_MOUSEHWHEEL)
+ delta = -delta;
+
+ const QPoint globalPos(GET_X_LPARAM(msg.lParam), GET_Y_LPARAM(msg.lParam));
+ // TODO: if there is a widget under the mouse and it is not shadowed
+ // QWindow *receiver = windowAt(pos);
+ // by modality, we send the event to it first.
+ //synaptics touchpad shows its own widget at this position
+ //so widgetAt() will fail with that HWND, try child of this widget
+ // if (!receiver) receiver = window->childAt(pos);
+ QWindow *receiver = window;
+ QWindowSystemInterface::handleWheelEvent(receiver,
+ QWindowsGeometryHint::mapFromGlobal(receiver, globalPos),
+ globalPos,
+ delta, orientation);
+ return true;
+}
+
+// from bool QApplicationPrivate::translateTouchEvent()
+bool QWindowsMouseHandler::translateTouchEvent(QWindow *window, HWND,
+ QtWindows::WindowsEventType,
+ MSG msg, LRESULT *)
+{
+ typedef QWindowSystemInterface::TouchPoint QTouchPoint;
+ typedef QList<QWindowSystemInterface::TouchPoint> QTouchPointList;
+
+ const QRect screenGeometry = window->screen()->geometry();
+
+ const int winTouchPointCount = msg.wParam;
+ QScopedArrayPointer<TOUCHINPUT> winTouchInputs(new TOUCHINPUT[winTouchPointCount]);
+ memset(winTouchInputs.data(), 0, sizeof(TOUCHINPUT) * winTouchPointCount);
+
+ QTouchPointList touchPoints;
+ touchPoints.reserve(winTouchPointCount);
+ Qt::TouchPointStates allStates = 0;
+
+ Q_ASSERT(QWindowsContext::user32dll.getTouchInputInfo);
+
+ QWindowsContext::user32dll.getTouchInputInfo((HANDLE) msg.lParam, msg.wParam, winTouchInputs.data(), sizeof(TOUCHINPUT));
+ for (int i = 0; i < winTouchPointCount; ++i) {
+ const TOUCHINPUT &winTouchInput = winTouchInputs[i];
+ QTouchPoint touchPoint;
+ touchPoint.pressure = 1.0;
+ touchPoint.isPrimary = (winTouchInput.dwFlags & TOUCHEVENTF_PRIMARY) != 0;
+ touchPoint.id = m_touchInputIDToTouchPointID.value(winTouchInput.dwID, -1);
+ if (touchPoint.id == -1) {
+ touchPoint.id = m_touchInputIDToTouchPointID.size();
+ m_touchInputIDToTouchPointID.insert(winTouchInput.dwID, touchPoint.id);
+ }
+
+ QPointF screenPos = QPointF(qreal(winTouchInput.x) / qreal(100.), qreal(winTouchInput.y) / qreal(100.));
+ if (winTouchInput.dwMask & TOUCHINPUTMASKF_CONTACTAREA)
+ touchPoint.area.setSize(QSizeF(qreal(winTouchInput.cxContact) / qreal(100.),
+ qreal(winTouchInput.cyContact) / qreal(100.)));
+ touchPoint.area.moveCenter(screenPos);
+
+ if (winTouchInput.dwFlags & TOUCHEVENTF_DOWN) {
+ touchPoint.state = Qt::TouchPointPressed;
+ } else if (winTouchInput.dwFlags & TOUCHEVENTF_UP) {
+ touchPoint.state = Qt::TouchPointReleased;
+ } else {
+ // TODO: Previous code checked"
+ // screenPos == touchPoint.normalPosition -> Qt::TouchPointStationary, but
+ // but touchPoint.normalPosition was never initialized?
+ touchPoint.state = touchPoint.state;
+ }
+
+ touchPoint.normalPosition = QPointF(screenPos.x() / screenGeometry.width(),
+ screenPos.y() / screenGeometry.height());
+
+ allStates |= touchPoint.state;
+
+ touchPoints.append(touchPoint);
+ }
+
+ QWindowsContext::user32dll.closeTouchInputHandle((HANDLE) msg.lParam);
+
+ // all touch points released, forget the ids we've seen, they may not be reused
+ if ((allStates & Qt::TouchPointStateMask) == Qt::TouchPointReleased)
+ m_touchInputIDToTouchPointID.clear();
+
+ // TODO: Device used to be hardcoded to screen in previous code.
+ // What is the correct event type? Which parts of translateRawTouchEvent() are required?
+ QWindowSystemInterface::handleTouchEvent(window, QEvent::TouchBegin,
+ QTouchEvent::TouchScreen,
+ touchPoints);
+ return true;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.h b/src/plugins/platforms/windows/qwindowsmousehandler.h
new file mode 100644
index 0000000000..953649102a
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsmousehandler.h
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSMOUSEHANDLER_H
+#define QWINDOWSMOUSEHANDLER_H
+
+#include "qtwindowsglobal.h"
+#include "qtwindows_additional.h"
+
+#include <QtCore/QPointer>
+#include <QtCore/QHash>
+
+QT_BEGIN_NAMESPACE
+
+class QWindow;
+
+class QWindowsMouseHandler
+{
+ Q_DISABLE_COPY(QWindowsMouseHandler)
+public:
+ QWindowsMouseHandler();
+
+ bool translateMouseEvent(QWindow *widget, HWND hwnd,
+ QtWindows::WindowsEventType t, MSG msg,
+ LRESULT *result);
+ bool translateTouchEvent(QWindow *widget, HWND hwnd,
+ QtWindows::WindowsEventType t, MSG msg,
+ LRESULT *result);
+
+ static inline Qt::MouseButtons keyStateToMouseButtons(int);
+ static inline int mouseButtonsToKeyState(Qt::MouseButtons);
+
+ QWindow *windowUnderMouse() const { return m_windowUnderMouse.data(); }
+
+private:
+ inline bool translateMouseWheelEvent(QWindow *window, HWND hwnd,
+ MSG msg, LRESULT *result);
+
+ QPointer<QWindow> m_windowUnderMouse;
+ QHash<DWORD, int> m_touchInputIDToTouchPointID;
+};
+
+Qt::MouseButtons QWindowsMouseHandler::keyStateToMouseButtons(int wParam)
+{
+ Qt::MouseButtons mb(Qt::NoButton);
+ if (wParam & MK_LBUTTON)
+ mb |= Qt::LeftButton;
+ if (wParam & MK_MBUTTON)
+ mb |= Qt::MiddleButton;
+ if (wParam & MK_RBUTTON)
+ mb |= Qt::RightButton;
+ if (wParam & MK_XBUTTON1)
+ mb |= Qt::XButton1;
+ if (wParam & MK_XBUTTON2)
+ mb |= Qt::XButton2;
+ return mb;
+}
+
+int QWindowsMouseHandler::mouseButtonsToKeyState(Qt::MouseButtons mb)
+{
+ int result = 0;
+ if (mb & Qt::LeftButton)
+ result |= MK_LBUTTON;
+ if (mb & Qt::MiddleButton)
+ result |= MK_MBUTTON;
+ if (mb & Qt::RightButton)
+ result |= MK_RBUTTON;
+ if (mb & Qt::XButton1)
+ result |= MK_XBUTTON1;
+ if (mb & Qt::XButton2)
+ result |= MK_XBUTTON2;
+ return result;
+}
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSMOUSEHANDLER_H
diff --git a/src/plugins/platforms/windows/qwindowsnativeimage.cpp b/src/plugins/platforms/windows/qwindowsnativeimage.cpp
new file mode 100644
index 0000000000..2ecf334b39
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsnativeimage.cpp
@@ -0,0 +1,151 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsnativeimage.h"
+#include "qwindowscontext.h"
+
+#include <QtGui/private/qpaintengine_p.h>
+#include <QtGui/private/qpaintengine_raster_p.h>
+
+QT_BEGIN_NAMESPACE
+
+typedef struct {
+ BITMAPINFOHEADER bmiHeader;
+ DWORD redMask;
+ DWORD greenMask;
+ DWORD blueMask;
+} BITMAPINFO_MASK;
+
+/*!
+ \class QWindowsNativeImage
+ \brief Windows Native image
+
+ Note that size can be 0 (widget autotests with zero size), which
+ causes CreateDIBSection() to fail.
+
+ \sa QWindowsBackingStore
+ \ingroup qt-lighthouse-win
+*/
+
+static inline HDC createDC()
+{
+ HDC display_dc = GetDC(0);
+ HDC hdc = CreateCompatibleDC(display_dc);
+ ReleaseDC(0, display_dc);
+ Q_ASSERT(hdc);
+ return hdc;
+}
+
+static inline HBITMAP createDIB(HDC hdc, int width, int height,
+ QImage::Format format,
+ uchar **bitsIn)
+{
+ BITMAPINFO_MASK bmi;
+ memset(&bmi, 0, sizeof(bmi));
+ bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bmi.bmiHeader.biWidth = width;
+ bmi.bmiHeader.biHeight = -height; // top-down.
+ bmi.bmiHeader.biPlanes = 1;
+ bmi.bmiHeader.biSizeImage = 0;
+
+ if (format == QImage::Format_RGB16) {
+ bmi.bmiHeader.biBitCount = 16;
+ bmi.bmiHeader.biCompression = BI_BITFIELDS;
+ bmi.redMask = 0xF800;
+ bmi.greenMask = 0x07E0;
+ bmi.blueMask = 0x001F;
+ } else {
+ bmi.bmiHeader.biBitCount = 32;
+ bmi.bmiHeader.biCompression = BI_RGB;
+ bmi.redMask = 0;
+ bmi.greenMask = 0;
+ bmi.blueMask = 0;
+ }
+
+ void *bits = 0;
+ HBITMAP bitmap = CreateDIBSection(hdc, reinterpret_cast<BITMAPINFO *>(&bmi),
+ DIB_RGB_COLORS, &bits, 0, 0);
+ if (!bitmap || !bits)
+ qFatal("%s: CreateDIBSection failed.", __FUNCTION__);
+
+ *bitsIn = (uchar*)bits;
+ return bitmap;
+}
+
+QWindowsNativeImage::QWindowsNativeImage(int width, int height,
+ QImage::Format format) :
+ m_hdc(createDC()),
+ m_bitmap(0),
+ m_null_bitmap(0)
+{
+ if (width != 0 && height != 0) {
+ uchar *bits;
+ m_bitmap = createDIB(m_hdc, width, height, format, &bits);
+ m_null_bitmap = (HBITMAP)SelectObject(m_hdc, m_bitmap);
+ m_image = QImage(bits, width, height, format);
+ Q_ASSERT(m_image.paintEngine()->type() == QPaintEngine::Raster);
+ static_cast<QRasterPaintEngine *>(m_image.paintEngine())->setDC(m_hdc);
+ } else {
+ m_image = QImage(width, height, format);
+ }
+
+ GdiFlush();
+}
+
+QWindowsNativeImage::~QWindowsNativeImage()
+{
+ if (m_hdc) {
+ if (m_bitmap) {
+ if (m_null_bitmap)
+ SelectObject(m_hdc, m_null_bitmap);
+ DeleteObject(m_bitmap);
+ }
+ DeleteDC(m_hdc);
+ }
+}
+
+QImage::Format QWindowsNativeImage::systemFormat()
+{
+ static const int depth = QWindowsContext::instance()->screenDepth();
+ return depth == 16 ? QImage::Format_RGB16 : QImage::Format_RGB32;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsnativeimage.h b/src/plugins/platforms/windows/qwindowsnativeimage.h
new file mode 100644
index 0000000000..c77805a10a
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsnativeimage.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSNATIVEIMAGE_H
+#define QWINDOWSNATIVEIMAGE_H
+
+#include "qtwindows_additional.h"
+
+#include <QtGui/QImage>
+
+#include <QtCore/QtGlobal>
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsNativeImage
+{
+ Q_DISABLE_COPY(QWindowsNativeImage)
+public:
+ QWindowsNativeImage(int width, int height,
+ QImage::Format format);
+
+ ~QWindowsNativeImage();
+
+ inline int width() const { return m_image.width(); }
+ inline int height() const { return m_image.height(); }
+
+ QImage &image() { return m_image; }
+ const QImage &image() const { return m_image; }
+
+ HDC hdc() const { return m_hdc; }
+
+ static QImage::Format systemFormat();
+
+private:
+ const HDC m_hdc;
+ QImage m_image;
+
+ HBITMAP m_bitmap;
+ HBITMAP m_null_bitmap;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSNATIVEIMAGE_H
diff --git a/src/plugins/platforms/windows/qwindowsole.cpp b/src/plugins/platforms/windows/qwindowsole.cpp
new file mode 100644
index 0000000000..864dc3dbb7
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsole.cpp
@@ -0,0 +1,476 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsole.h"
+#include "qwindowsmime.h"
+#include "qwindowscontext.h"
+\
+#include <QtGui/QMouseEvent>
+#include <QtGui/QWindow>
+#include <QtGui/QPainter>
+#include <QtGui/QCursor>
+#include <QtGui/QGuiApplication>
+
+#include <QtCore/QMimeData>
+#include <QtCore/QDebug>
+
+#include <shlobj.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QWindowsOleDataObject
+ \brief OLE data container
+
+ The following methods are NOT supported for data transfer using the
+ clipboard or drag-drop:
+ \list
+ \o IDataObject::SetData -- return E_NOTIMPL
+ \o IDataObject::DAdvise -- return OLE_E_ADVISENOTSUPPORTED
+ \o ::DUnadvise
+ \o ::EnumDAdvise
+ \o IDataObject::GetCanonicalFormatEtc -- return E_NOTIMPL
+ (NOTE: must set pformatetcOut->ptd = NULL)
+ \endlist
+
+ \ingroup qt-lighthouse-win
+*/
+
+QWindowsOleDataObject::QWindowsOleDataObject(QMimeData *mimeData) :
+ m_refs(1), data(mimeData),
+ CF_PERFORMEDDROPEFFECT(RegisterClipboardFormat(CFSTR_PERFORMEDDROPEFFECT)),
+ performedEffect(DROPEFFECT_NONE)
+{
+ if (QWindowsContext::verboseOLE)
+ qDebug("%s '%s'", __FUNCTION__, qPrintable(mimeData->formats().join(QStringLiteral(", "))));
+}
+
+QWindowsOleDataObject::~QWindowsOleDataObject()
+{
+ if (QWindowsContext::verboseOLE)
+ qDebug("%s", __FUNCTION__);
+}
+
+void QWindowsOleDataObject::releaseQt()
+{
+ data = 0;
+}
+
+QMimeData *QWindowsOleDataObject::mimeData() const
+{
+ return data.data();
+}
+
+DWORD QWindowsOleDataObject::reportedPerformedEffect() const
+{
+ return performedEffect;
+}
+
+//---------------------------------------------------------------------
+// IUnknown Methods
+//---------------------------------------------------------------------
+
+STDMETHODIMP
+QWindowsOleDataObject::QueryInterface(REFIID iid, void FAR* FAR* ppv)
+{
+ if (iid == IID_IUnknown || iid == IID_IDataObject) {
+ *ppv = this;
+ AddRef();
+ return NOERROR;
+ }
+ *ppv = NULL;
+ return ResultFromScode(E_NOINTERFACE);
+}
+
+STDMETHODIMP_(ULONG)
+QWindowsOleDataObject::AddRef(void)
+{
+ return ++m_refs;
+}
+
+STDMETHODIMP_(ULONG)
+QWindowsOleDataObject::Release(void)
+{
+ if (--m_refs == 0) {
+ releaseQt();
+ delete this;
+ return 0;
+ }
+ return m_refs;
+}
+
+STDMETHODIMP
+QWindowsOleDataObject::GetData(LPFORMATETC pformatetc, LPSTGMEDIUM pmedium)
+{
+ HRESULT hr = ResultFromScode(DATA_E_FORMATETC);
+
+ if (QWindowsContext::verboseOLE) {
+ wchar_t buf[256] = {0};
+ GetClipboardFormatName(pformatetc->cfFormat, buf, 255);
+ qDebug("%s CF = %d : %s", __FUNCTION__, pformatetc->cfFormat, qPrintable(QString::fromWCharArray(buf)));
+ }
+
+ if (data) {
+ const QWindowsMimeConverter &mc = QWindowsContext::instance()->mimeConverter();
+ if (QWindowsMime *converter = mc.converterFromMime(*pformatetc, data))
+ if (converter->convertFromMime(*pformatetc, data, pmedium))
+ hr = ResultFromScode(S_OK);
+ }
+
+ if (QWindowsContext::verboseOLE) {
+ wchar_t buf[256] = {0};
+ GetClipboardFormatName(pformatetc->cfFormat, buf, 255);
+ qDebug("%s CF = %d : %s returns 0x%x", __FUNCTION__, pformatetc->cfFormat,
+ qPrintable(QString::fromWCharArray(buf)), int(hr));
+ }
+
+ return hr;
+}
+
+STDMETHODIMP
+QWindowsOleDataObject::GetDataHere(LPFORMATETC, LPSTGMEDIUM)
+{
+ return ResultFromScode(DATA_E_FORMATETC);
+}
+
+STDMETHODIMP
+QWindowsOleDataObject::QueryGetData(LPFORMATETC pformatetc)
+{
+ HRESULT hr = ResultFromScode(DATA_E_FORMATETC);
+
+ if (QWindowsContext::verboseOLE > 1)
+ qDebug("%s", __FUNCTION__);
+
+ if (data) {
+ const QWindowsMimeConverter &mc = QWindowsContext::instance()->mimeConverter();
+ hr = mc.converterFromMime(*pformatetc, data) ?
+ ResultFromScode(S_OK) : ResultFromScode(S_FALSE);
+ }
+ if (QWindowsContext::verboseOLE > 1)
+ qDebug("%s returns 0x%x", __FUNCTION__, int(hr));
+ return hr;
+}
+
+STDMETHODIMP
+QWindowsOleDataObject::GetCanonicalFormatEtc(LPFORMATETC, LPFORMATETC pformatetcOut)
+{
+ pformatetcOut->ptd = NULL;
+ return ResultFromScode(E_NOTIMPL);
+}
+
+STDMETHODIMP
+QWindowsOleDataObject::SetData(LPFORMATETC pFormatetc, STGMEDIUM *pMedium, BOOL fRelease)
+{
+ if (QWindowsContext::verboseOLE > 1)
+ qDebug("%s", __FUNCTION__);
+
+ HRESULT hr = ResultFromScode(E_NOTIMPL);
+
+ if (pFormatetc->cfFormat == CF_PERFORMEDDROPEFFECT && pMedium->tymed == TYMED_HGLOBAL) {
+ DWORD * val = (DWORD*)GlobalLock(pMedium->hGlobal);
+ performedEffect = *val;
+ GlobalUnlock(pMedium->hGlobal);
+ if (fRelease)
+ ReleaseStgMedium(pMedium);
+ hr = ResultFromScode(S_OK);
+ }
+ if (QWindowsContext::verboseOLE > 1)
+ qDebug("%s returns 0x%x", __FUNCTION__, int(hr));
+ return hr;
+}
+
+
+STDMETHODIMP
+QWindowsOleDataObject::EnumFormatEtc(DWORD dwDirection, LPENUMFORMATETC FAR* ppenumFormatEtc)
+{
+ if (QWindowsContext::verboseOLE > 1)
+ qDebug("%s", __FUNCTION__);
+
+ if (!data)
+ return ResultFromScode(DATA_E_FORMATETC);
+
+ SCODE sc = S_OK;
+
+ QVector<FORMATETC> fmtetcs;
+ if (dwDirection == DATADIR_GET) {
+ QWindowsMimeConverter &mc = QWindowsContext::instance()->mimeConverter();
+ fmtetcs = mc.allFormatsForMime(data);
+ } else {
+ FORMATETC formatetc;
+ formatetc.cfFormat = CF_PERFORMEDDROPEFFECT;
+ formatetc.dwAspect = DVASPECT_CONTENT;
+ formatetc.lindex = -1;
+ formatetc.ptd = NULL;
+ formatetc.tymed = TYMED_HGLOBAL;
+ fmtetcs.append(formatetc);
+ }
+
+ QWindowsOleEnumFmtEtc *enumFmtEtc = new QWindowsOleEnumFmtEtc(fmtetcs);
+ *ppenumFormatEtc = enumFmtEtc;
+ if (enumFmtEtc->isNull()) {
+ delete enumFmtEtc;
+ *ppenumFormatEtc = NULL;
+ sc = E_OUTOFMEMORY;
+ }
+
+ return ResultFromScode(sc);
+}
+
+STDMETHODIMP
+QWindowsOleDataObject::DAdvise(FORMATETC FAR*, DWORD,
+ LPADVISESINK, DWORD FAR*)
+{
+ return ResultFromScode(OLE_E_ADVISENOTSUPPORTED);
+}
+
+
+STDMETHODIMP
+QWindowsOleDataObject::DUnadvise(DWORD)
+{
+ return ResultFromScode(OLE_E_ADVISENOTSUPPORTED);
+}
+
+STDMETHODIMP
+QWindowsOleDataObject::EnumDAdvise(LPENUMSTATDATA FAR*)
+{
+ return ResultFromScode(OLE_E_ADVISENOTSUPPORTED);
+}
+
+/*!
+ \class QWindowsOleEnumFmtEtc
+ \brief Enumerates the FORMATETC structures supported by QWindowsOleDataObject.
+ \ingroup qt-lighthouse-win
+*/
+
+QWindowsOleEnumFmtEtc::QWindowsOleEnumFmtEtc(const QVector<FORMATETC> &fmtetcs) :
+ m_dwRefs(1), m_nIndex(0), m_isNull(false)
+{
+ if (QWindowsContext::verboseOLE > 1)
+ qDebug("%s", __FUNCTION__);
+ m_lpfmtetcs.reserve(fmtetcs.count());
+ for (int idx = 0; idx < fmtetcs.count(); ++idx) {
+ LPFORMATETC destetc = new FORMATETC();
+ if (copyFormatEtc(destetc, (LPFORMATETC)&(fmtetcs.at(idx)))) {
+ m_lpfmtetcs.append(destetc);
+ } else {
+ m_isNull = true;
+ delete destetc;
+ break;
+ }
+ }
+}
+
+QWindowsOleEnumFmtEtc::QWindowsOleEnumFmtEtc(const QVector<LPFORMATETC> &lpfmtetcs) :
+ m_dwRefs(1), m_nIndex(0), m_isNull(false)
+{
+ if (QWindowsContext::verboseOLE > 1)
+ qDebug("%s", __FUNCTION__);
+ m_lpfmtetcs.reserve(lpfmtetcs.count());
+ for (int idx = 0; idx < lpfmtetcs.count(); ++idx) {
+ LPFORMATETC srcetc = lpfmtetcs.at(idx);
+ LPFORMATETC destetc = new FORMATETC();
+ if (copyFormatEtc(destetc, srcetc)) {
+ m_lpfmtetcs.append(destetc);
+ } else {
+ m_isNull = true;
+ delete destetc;
+ break;
+ }
+ }
+}
+
+QWindowsOleEnumFmtEtc::~QWindowsOleEnumFmtEtc()
+{
+ LPMALLOC pmalloc;
+
+ if (CoGetMalloc(MEMCTX_TASK, &pmalloc) == NOERROR) {
+ for (int idx = 0; idx < m_lpfmtetcs.count(); ++idx) {
+ LPFORMATETC tmpetc = m_lpfmtetcs.at(idx);
+ if (tmpetc->ptd)
+ pmalloc->Free(tmpetc->ptd);
+ delete tmpetc;
+ }
+
+ pmalloc->Release();
+ }
+ m_lpfmtetcs.clear();
+}
+
+bool QWindowsOleEnumFmtEtc::isNull() const
+{
+ return m_isNull;
+}
+
+// IUnknown methods
+STDMETHODIMP
+QWindowsOleEnumFmtEtc::QueryInterface(REFIID riid, void FAR* FAR* ppvObj)
+{
+ if (riid == IID_IUnknown || riid == IID_IEnumFORMATETC) {
+ *ppvObj = this;
+ AddRef();
+ return NOERROR;
+ }
+ *ppvObj = NULL;
+ return ResultFromScode(E_NOINTERFACE);
+}
+
+STDMETHODIMP_(ULONG)
+QWindowsOleEnumFmtEtc::AddRef(void)
+{
+ return ++m_dwRefs;
+}
+
+STDMETHODIMP_(ULONG)
+QWindowsOleEnumFmtEtc::Release(void)
+{
+ if (--m_dwRefs == 0) {
+ delete this;
+ return 0;
+ }
+ return m_dwRefs;
+}
+
+// IEnumFORMATETC methods
+STDMETHODIMP
+QWindowsOleEnumFmtEtc::Next(ULONG celt, LPFORMATETC rgelt, ULONG FAR* pceltFetched)
+{
+ ULONG i=0;
+ ULONG nOffset;
+
+ if (rgelt == NULL)
+ return ResultFromScode(E_INVALIDARG);
+
+ while (i < celt) {
+ nOffset = m_nIndex + i;
+
+ if (nOffset < ULONG(m_lpfmtetcs.count())) {
+ copyFormatEtc((LPFORMATETC)&(rgelt[i]), m_lpfmtetcs.at(nOffset));
+ i++;
+ } else {
+ break;
+ }
+ }
+
+ m_nIndex += (WORD)i;
+
+ if (pceltFetched != NULL)
+ *pceltFetched = i;
+
+ if (i != celt)
+ return ResultFromScode(S_FALSE);
+
+ return NOERROR;
+}
+
+STDMETHODIMP
+QWindowsOleEnumFmtEtc::Skip(ULONG celt)
+{
+ ULONG i=0;
+ ULONG nOffset;
+
+ while (i < celt) {
+ nOffset = m_nIndex + i;
+
+ if (nOffset < ULONG(m_lpfmtetcs.count())) {
+ i++;
+ } else {
+ break;
+ }
+ }
+
+ m_nIndex += (WORD)i;
+
+ if (i != celt)
+ return ResultFromScode(S_FALSE);
+
+ return NOERROR;
+}
+
+STDMETHODIMP
+QWindowsOleEnumFmtEtc::Reset()
+{
+ m_nIndex = 0;
+ return NOERROR;
+}
+
+STDMETHODIMP
+QWindowsOleEnumFmtEtc::Clone(LPENUMFORMATETC FAR* newEnum)
+{
+ if (newEnum == NULL)
+ return ResultFromScode(E_INVALIDARG);
+
+ QWindowsOleEnumFmtEtc *result = new QWindowsOleEnumFmtEtc(m_lpfmtetcs);
+ result->m_nIndex = m_nIndex;
+
+ if (result->isNull()) {
+ delete result;
+ return ResultFromScode(E_OUTOFMEMORY);
+ } else {
+ *newEnum = result;
+ }
+
+ return NOERROR;
+}
+
+bool QWindowsOleEnumFmtEtc::copyFormatEtc(LPFORMATETC dest, LPFORMATETC src) const
+{
+ if (dest == NULL || src == NULL)
+ return false;
+
+ *dest = *src;
+
+ if (src->ptd) {
+ LPVOID pout;
+ LPMALLOC pmalloc;
+
+ if (CoGetMalloc(MEMCTX_TASK, &pmalloc) != NOERROR)
+ return false;
+
+ pout = (LPVOID)pmalloc->Alloc(src->ptd->tdSize);
+ memcpy(dest->ptd, src->ptd, size_t(src->ptd->tdSize));
+
+ pmalloc->Release();
+ }
+
+ return true;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsole.h b/src/plugins/platforms/windows/qwindowsole.h
new file mode 100644
index 0000000000..d979af3b31
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsole.h
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSOLE_H
+#define QWINDOWSOLE_H
+
+#include "qtwindows_additional.h"
+
+#include <QtCore/QObject>
+#include <QtCore/QMap>
+#include <QtCore/QPoint>
+#include <QtCore/QPointer>
+#include <QtCore/QVector>
+#include <QtCore/QRect>
+
+#include <objidl.h>
+
+QT_BEGIN_NAMESPACE
+
+class QMimeData;
+class QWindow;
+
+class QWindowsOleDataObject : public IDataObject
+{
+public:
+ explicit QWindowsOleDataObject(QMimeData *mimeData);
+ virtual ~QWindowsOleDataObject();
+
+ void releaseQt();
+ QMimeData *mimeData() const;
+ DWORD reportedPerformedEffect() const;
+
+ // IUnknown methods
+ STDMETHOD(QueryInterface)(REFIID riid, void FAR* FAR* ppvObj);
+ STDMETHOD_(ULONG,AddRef)(void);
+ STDMETHOD_(ULONG,Release)(void);
+
+ // IDataObject methods
+ STDMETHOD(GetData)(LPFORMATETC pformatetcIn, LPSTGMEDIUM pmedium);
+ STDMETHOD(GetDataHere)(LPFORMATETC pformatetc, LPSTGMEDIUM pmedium);
+ STDMETHOD(QueryGetData)(LPFORMATETC pformatetc);
+ STDMETHOD(GetCanonicalFormatEtc)(LPFORMATETC pformatetc, LPFORMATETC pformatetcOut);
+ STDMETHOD(SetData)(LPFORMATETC pformatetc, STGMEDIUM FAR * pmedium,
+ BOOL fRelease);
+ STDMETHOD(EnumFormatEtc)(DWORD dwDirection, LPENUMFORMATETC FAR* ppenumFormatEtc);
+ STDMETHOD(DAdvise)(FORMATETC FAR* pFormatetc, DWORD advf,
+ LPADVISESINK pAdvSink, DWORD FAR* pdwConnection);
+ STDMETHOD(DUnadvise)(DWORD dwConnection);
+ STDMETHOD(EnumDAdvise)(LPENUMSTATDATA FAR* ppenumAdvise);
+
+private:
+ ULONG m_refs;
+ QPointer<QMimeData> data;
+ int CF_PERFORMEDDROPEFFECT;
+ DWORD performedEffect;
+};
+
+class QWindowsOleEnumFmtEtc : public IEnumFORMATETC
+{
+public:
+ explicit QWindowsOleEnumFmtEtc(const QVector<FORMATETC> &fmtetcs);
+ explicit QWindowsOleEnumFmtEtc(const QVector<LPFORMATETC> &lpfmtetcs);
+ virtual ~QWindowsOleEnumFmtEtc();
+
+ bool isNull() const;
+
+ // IUnknown methods
+ STDMETHOD(QueryInterface)(REFIID riid, void FAR* FAR* ppvObj);
+ STDMETHOD_(ULONG,AddRef)(void);
+ STDMETHOD_(ULONG,Release)(void);
+
+ // IEnumFORMATETC methods
+ STDMETHOD(Next)(ULONG celt, LPFORMATETC rgelt, ULONG FAR* pceltFetched);
+ STDMETHOD(Skip)(ULONG celt);
+ STDMETHOD(Reset)(void);
+ STDMETHOD(Clone)(LPENUMFORMATETC FAR* newEnum);
+
+private:
+ bool copyFormatEtc(LPFORMATETC dest, LPFORMATETC src) const;
+
+ ULONG m_dwRefs;
+ ULONG m_nIndex;
+ QVector<LPFORMATETC> m_lpfmtetcs;
+ bool m_isNull;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSOLE_H
diff --git a/src/plugins/platforms/windows/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp
new file mode 100644
index 0000000000..3de508a1c7
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsscreen.cpp
@@ -0,0 +1,230 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsscreen.h"
+#include "qwindowscontext.h"
+#include "qwindowswindow.h"
+#include "pixmaputils.h"
+#include "qwindowscursor.h"
+
+#include "qtwindows_additional.h"
+
+#include <QtGui/QPixmap>
+#include <QtGui/QGuiApplication>
+#include <QtGui/QScreen>
+
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+typedef QPair<int, int> DPI;
+
+QWindowsScreenData::QWindowsScreenData() :
+ dpi(96, 96),
+ depth(32),
+ format(QImage::Format_ARGB32_Premultiplied), primary(false)
+{
+}
+
+static inline DPI deviceDPI(HDC hdc)
+{
+ return DPI(GetDeviceCaps(hdc, LOGPIXELSX), GetDeviceCaps(hdc, LOGPIXELSY));
+}
+
+static inline QSize deviceSizeMM(const QSize &pixels, const DPI &dpi)
+{
+ const qreal inchToMM = 25.4;
+ const qreal h = qreal(pixels.width()) / qreal(dpi.first) * inchToMM;
+ const qreal v = qreal(pixels.height()) / qreal(dpi.second) * inchToMM;
+ return QSize(qRound(h), qRound(v));
+}
+
+static inline DPI deviceDPI(const QSize &pixels, const QSize &physicalSizeMM)
+{
+ const qreal inchToMM = 25.4;
+ const qreal h = qreal(pixels.width()) / (qreal(physicalSizeMM.width()) / inchToMM);
+ const qreal v = qreal(pixels.height()) / (qreal(physicalSizeMM.height()) / inchToMM);
+ return DPI(qRound(v), qRound(h));
+}
+
+typedef QList<QWindowsScreenData> WindowsScreenDataList;
+
+// from QDesktopWidget, taking WindowsScreenDataList as LPARAM
+BOOL QT_WIN_CALLBACK monitorEnumCallback(HMONITOR hMonitor, HDC, LPRECT, LPARAM p)
+{
+ MONITORINFOEX info;
+ memset(&info, 0, sizeof(MONITORINFOEX));
+ info.cbSize = sizeof(MONITORINFOEX);
+ if (GetMonitorInfo(hMonitor, &info) == FALSE)
+ return TRUE;
+
+ WindowsScreenDataList *result = reinterpret_cast<WindowsScreenDataList *>(p);
+ QWindowsScreenData data;
+ data.geometry = QRect(QPoint(info.rcMonitor.left, info.rcMonitor.top), QPoint(info.rcMonitor.right - 1, info.rcMonitor.bottom - 1));
+ if (HDC hdc = CreateDC(info.szDevice, NULL, NULL, NULL)) {
+ data.dpi = deviceDPI(hdc);
+ DeleteDC(hdc);
+ } else {
+ qWarning("%s: Unable to obtain handle for monitor '%s', defaulting to %d DPI.",
+ __FUNCTION__, qPrintable(QString::fromWCharArray(info.szDevice)),
+ data.dpi.first);
+ }
+ data.physicalSizeMM = deviceSizeMM(data.geometry.size(), data.dpi);
+ data.geometry = QRect(QPoint(info.rcMonitor.left, info.rcMonitor.top), QPoint(info.rcMonitor.right - 1, info.rcMonitor.bottom - 1));
+ data.availableGeometry = QRect(QPoint(info.rcWork.left, info.rcWork.top), QPoint(info.rcWork.right - 1, info.rcWork.bottom - 1));
+ data.primary = (info.dwFlags & MONITORINFOF_PRIMARY) != 0;
+ result->append(data);
+ return TRUE;
+}
+
+/*!
+ \class QWindowsScreen
+ \brief Windows screen.
+ \ingroup qt-lighthouse-win
+*/
+
+QWindowsScreen::QWindowsScreen(const QWindowsScreenData &data) :
+ m_data(data), m_cursor(this)
+{
+}
+
+QList<QPlatformScreen *> QWindowsScreen::screens()
+{
+ // Retrieve monitors and add static depth information to each.
+ WindowsScreenDataList data;
+ EnumDisplayMonitors(0, 0, monitorEnumCallback, (LPARAM)&data);
+
+ const int depth = QWindowsContext::instance()->screenDepth();
+ const QImage::Format format = depth == 16 ? QImage::Format_RGB16 : QImage::Format_RGB32;
+ QList<QPlatformScreen *> result;
+
+ const WindowsScreenDataList::const_iterator scend = data.constEnd();
+ for (WindowsScreenDataList::const_iterator it = data.constBegin(); it != scend; ++it) {
+ QWindowsScreenData d = *it;
+ d.depth = depth;
+ d.format = format;
+ if (QWindowsContext::verboseIntegration)
+ qDebug() << "Screen" << d.geometry << d.availableGeometry << d.primary
+ << " physical " << d.physicalSizeMM << " DPI" << d.dpi
+ << "Depth: " << d.depth << " Format: " << d.format;
+ result.append(new QWindowsScreen(d));
+ }
+ return result;
+}
+
+QPixmap QWindowsScreen::grabWindow(WId window, int x, int y, int width, int height) const
+{
+ if (QWindowsContext::verboseIntegration)
+ qDebug() << __FUNCTION__ << window << x << y << width << height;
+ RECT r;
+ HWND hwnd = (HWND)window;
+ GetClientRect(hwnd, &r);
+
+ if (width < 0) width = r.right - r.left;
+ if (height < 0) height = r.bottom - r.top;
+
+ // Create and setup bitmap
+ HDC display_dc = GetDC(0);
+ HDC bitmap_dc = CreateCompatibleDC(display_dc);
+ HBITMAP bitmap = CreateCompatibleBitmap(display_dc, width, height);
+ HGDIOBJ null_bitmap = SelectObject(bitmap_dc, bitmap);
+
+ // copy data
+ HDC window_dc = GetDC(hwnd);
+ BitBlt(bitmap_dc, 0, 0, width, height, window_dc, x, y, SRCCOPY | CAPTUREBLT);
+
+ // clean up all but bitmap
+ ReleaseDC(hwnd, window_dc);
+ SelectObject(bitmap_dc, null_bitmap);
+ DeleteDC(bitmap_dc);
+
+ const QPixmap pixmap = qPixmapFromWinHBITMAP(bitmap, HBitmapNoAlpha);
+
+ DeleteObject(bitmap);
+ ReleaseDC(0, display_dc);
+
+ return pixmap;
+}
+
+/*!
+ \brief Find a top level window taking the flags of ChildWindowFromPointEx.
+*/
+
+QWindow *QWindowsScreen::findTopLevelAt(const QPoint &point, unsigned flags)
+{
+ QWindow* result = 0;
+ if (QPlatformWindow *bw = QWindowsContext::instance()->
+ findPlatformWindowAt(GetDesktopWindow(), point, flags))
+ result = QWindowsWindow::topLevelOf(bw->window());
+ if (QWindowsContext::verboseWindows)
+ qDebug() << __FUNCTION__ << point << flags << result;
+ return result;
+}
+
+QWindow *QWindowsScreen::windowAt(const QPoint &screenPoint, unsigned flags)
+{
+ QWindow* result = 0;
+ if (QPlatformWindow *bw = QWindowsContext::instance()->
+ findPlatformWindowAt(GetDesktopWindow(), screenPoint, flags))
+ result = bw->window();
+ if (QWindowsContext::verboseWindows)
+ qDebug() << __FUNCTION__ << screenPoint << " returns " << result;
+ return result;
+}
+
+QWindow *QWindowsScreen::windowUnderMouse(unsigned flags)
+{
+ return QWindowsScreen::windowAt(QWindowsCursor::mousePosition(), flags);
+}
+
+QWindowsScreen *QWindowsScreen::screenOf(const QWindow *w)
+{
+ if (w)
+ if (const QScreen *s = w->screen())
+ if (QPlatformScreen *pscr = s->handle())
+ return static_cast<QWindowsScreen *>(pscr);
+ if (const QScreen *ps = QGuiApplication::primaryScreen())
+ if (QPlatformScreen *ppscr = ps->handle())
+ return static_cast<QWindowsScreen *>(ppscr);
+ return 0;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsscreen.h b/src/plugins/platforms/windows/qwindowsscreen.h
new file mode 100644
index 0000000000..e24af7af09
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsscreen.h
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSSCREEN_H
+#define QWINDOWSSCREEN_H
+
+#include "qwindowscursor.h"
+
+#include <QtCore/QList>
+#include <QtCore/QPair>
+#include <QtGui/QPlatformScreen>
+
+QT_BEGIN_NAMESPACE
+
+struct QWindowsScreenData
+{
+ QWindowsScreenData();
+
+ QRect geometry;
+ QRect availableGeometry;
+ QPair<int, int> dpi;
+ QSize physicalSizeMM;
+ int depth;
+ QImage::Format format;
+ bool primary;
+};
+
+class QWindowsScreen : public QPlatformScreen
+{
+public:
+ explicit QWindowsScreen(const QWindowsScreenData &data);
+
+ static QWindowsScreen *screenOf(const QWindow *w = 0);
+
+ virtual QRect geometry() const { return m_data.geometry; }
+ virtual QRect availableGeometry() const { return m_data.availableGeometry; }
+ virtual int depth() const { return m_data.depth; }
+ virtual QImage::Format format() const { return m_data.format; }
+ virtual QSize physicalSize() const { return m_data.physicalSizeMM; }
+
+ virtual QWindow *topLevelAt(const QPoint &point) const
+ { return QWindowsScreen::findTopLevelAt(point, CWP_SKIPINVISIBLE); }
+
+ static QWindow *findTopLevelAt(const QPoint &point, unsigned flags);
+ static QWindow *windowAt(const QPoint &point, unsigned flags = CWP_SKIPINVISIBLE);
+ static QWindow *windowUnderMouse(unsigned flags = CWP_SKIPINVISIBLE);
+
+ static QList<QPlatformScreen *> screens();
+
+ virtual QPixmap grabWindow(WId window, int x, int y, int width, int height) const;
+
+ const QWindowsCursor &cursor() const { return m_cursor; }
+ QWindowsCursor &cursor() { return m_cursor; }
+
+private:
+ const QWindowsScreenData m_data;
+ QWindowsCursor m_cursor;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSSCREEN_H
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
new file mode 100644
index 0000000000..8e10ae694a
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -0,0 +1,1317 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowswindow.h"
+#include "qwindowsnativeimage.h"
+#include "qwindowscontext.h"
+#include "qwindowsdrag.h"
+#include "qwindowsscreen.h"
+#include "qwindowscursor.h"
+
+#include <QtGui/QGuiApplication>
+#include <QtGui/QScreen>
+#include <QtGui/QWindow>
+#include <QtGui/QWindowSystemInterface>
+
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+static QByteArray debugWinStyle(DWORD style)
+{
+
+ QByteArray rc = "0x";
+ rc += QByteArray::number(qulonglong(style), 16);
+ if (style & WS_POPUP)
+ rc += " WS_POPUP";
+ if (style & WS_CHILD)
+ rc += " WS_CHILD";
+ if (style & WS_OVERLAPPED)
+ rc += " WS_OVERLAPPED";
+ if (style & WS_CLIPSIBLINGS)
+ rc += " WS_CLIPSIBLINGS";
+ if (style & WS_CLIPCHILDREN)
+ rc += " WS_CLIPCHILDREN";
+ if (style & WS_THICKFRAME)
+ rc += " WS_THICKFRAME";
+ if (style & WS_DLGFRAME)
+ rc += " WS_DLGFRAME";
+ if (style & WS_SYSMENU)
+ rc += " WS_SYSMENU";
+ if (style & WS_MINIMIZEBOX)
+ rc += " WS_MINIMIZEBOX";
+ if (style & WS_MAXIMIZEBOX)
+ rc += " WS_MAXIMIZEBOX";
+ return rc;
+}
+
+static QByteArray debugWindowStates(Qt::WindowStates s)
+{
+
+ QByteArray rc = "0x";
+ rc += QByteArray::number(int(s), 16);
+ if (s & Qt::WindowMinimized)
+ rc += " WindowMinimized";
+ if (s & Qt::WindowMaximized)
+ rc += " WindowMaximized";
+ if (s & Qt::WindowFullScreen)
+ rc += " WindowFullScreen";
+ if (s & Qt::WindowActive)
+ rc += " WindowActive";
+ return rc;
+}
+
+QDebug operator<<(QDebug d, const MINMAXINFO &i)
+{
+ d.nospace() << "MINMAXINFO maxSize=" << i.ptMaxSize.x << ','
+ << i.ptMaxSize.y << " maxpos=" << i.ptMaxPosition.x
+ << ',' << i.ptMaxPosition.y << " mintrack="
+ << i.ptMinTrackSize.x << ',' << i.ptMinTrackSize.y
+ << " maxtrack=" << i.ptMaxTrackSize.x << ','
+ << i.ptMaxTrackSize.y;
+ return d;
+}
+
+static inline QSize qSizeOfRect(const RECT &rect)
+{
+ return QSize(rect.right -rect.left, rect.bottom - rect.top);
+}
+
+static inline QRect qrectFromRECT(const RECT &rect)
+{
+ return QRect(QPoint(rect.left, rect.top), qSizeOfRect(rect));
+}
+
+QDebug operator<<(QDebug d, const RECT &r)
+{
+ d.nospace() << "RECT: left/top=" << r.left << ',' << r.top
+ << " right/bottom=" << r.right << ',' << r.bottom;
+ return d;
+}
+
+QDebug operator<<(QDebug d, const NCCALCSIZE_PARAMS &p)
+{
+ qDebug().nospace() << "NCCALCSIZE_PARAMS "
+ << qrectFromRECT(p.rgrc[0])
+ << ' ' << qrectFromRECT(p.rgrc[1]) << ' '
+ << qrectFromRECT(p.rgrc[2]);
+ return d;
+}
+
+static inline QRect frameGeometry(HWND hwnd)
+{
+ RECT rect = { 0, 0, 0, 0 };
+ GetWindowRect(hwnd, &rect);
+ return qrectFromRECT(rect);
+}
+
+QSize clientSize(HWND hwnd)
+{
+ RECT rect = { 0, 0, 0, 0 };
+ GetClientRect(hwnd, &rect); // Always returns point 0,0, thus unusable for geometry.
+ return qSizeOfRect(rect);
+}
+
+// from qwidget_win.cpp/maximum layout size check removed.
+static bool shouldShowMaximizeButton(Qt::WindowFlags flags)
+{
+ if (flags & Qt::MSWindowsFixedSizeDialogHint)
+ return false;
+ // if the user explicitly asked for the maximize button, we try to add
+ // it even if the window has fixed size.
+ if (flags & Qt::CustomizeWindowHint &&
+ flags & Qt::WindowMaximizeButtonHint)
+ return true;
+ return flags & Qt::WindowMaximizeButtonHint;
+}
+
+/*!
+ \class WindowCreationData
+ \brief Window creation code.
+
+ This struct gathers all information required to create a window.
+ Window creation is split in 3 steps:
+
+ \list
+ \o fromWindow() Gather all required information
+ \o create() Create the system handle.
+ \o initialize() Post creation initialization steps.
+ \endlist
+
+ The reason for this split is to also enable changing the QWindowFlags
+ by calling:
+
+ \list
+ \o fromWindow() Gather information and determine new system styles
+ \o applyWindowFlags() to apply the new window system styles.
+ \o initialize() Post creation initialization steps.
+ \endlist
+
+ Contains the window creation code formerly in qwidget_win.cpp.
+
+ \sa QWindowCreationContext
+ \ingroup qt-lighthouse-win
+*/
+
+struct WindowCreationData
+{
+ typedef QWindowsWindow::WindowData WindowData;
+
+ WindowCreationData() : parentHandle(0), type(Qt::Widget), style(0), exStyle(0),
+ topLevel(false), popup(false), dialog(false), desktop(false),
+ tool(false) {}
+
+ void fromWindow(const QWindow *w, const Qt::WindowFlags flags, bool isGL);
+ inline WindowData create(const QWindow *w, const QRect &geometry, QString title) const;
+ inline void applyWindowFlags(HWND hwnd) const;
+ void initialize(HWND h, bool frameChange) const;
+
+ Qt::WindowFlags flags;
+ HWND parentHandle;
+ Qt::WindowType type;
+ unsigned style;
+ unsigned exStyle;
+ bool isGL;
+ bool topLevel;
+ bool popup;
+ bool dialog;
+ bool desktop;
+ bool tool;
+};
+
+QDebug operator<<(QDebug debug, const WindowCreationData &d)
+{
+ debug.nospace() << QWindowsWindow::debugWindowFlags(d.flags)
+ << " gs=" << d.isGL << " topLevel=" << d.topLevel << " popup="
+ << d.popup << " dialog=" << d.dialog << " desktop=" << d.desktop
+ << " tool=" << d.tool << " style=" << debugWinStyle(d.style)
+ << " exStyle=0x" << QString::number(d.exStyle, 16)
+ << " parent=" << d.parentHandle;
+ return debug;
+}
+
+void WindowCreationData::fromWindow(const QWindow *w, const Qt::WindowFlags flagsIn,
+ bool isGLin)
+{
+ isGL = isGLin;
+ flags = flagsIn;
+ topLevel = w->isTopLevel();
+
+ if (topLevel && flags == 1) {
+ qWarning("Remove me: fixing toplevel window flags");
+ flags |= Qt::WindowTitleHint|Qt::WindowSystemMenuHint|Qt::WindowMinimizeButtonHint
+ |Qt::WindowMaximizeButtonHint|Qt::WindowCloseButtonHint;
+ }
+
+ type = static_cast<Qt::WindowType>(int(flags) & Qt::WindowType_Mask);
+ switch (type) {
+ case Qt::Dialog:
+ case Qt::Sheet:
+ dialog = true;
+ break;
+ case Qt::Drawer:
+ case Qt::Tool:
+ tool = true;
+ break;
+ case Qt::Popup:
+ popup = true;
+ break;
+ case Qt::Desktop:
+ desktop = true;
+ break;
+ default:
+ break;
+ }
+ if ((flags & Qt::MSWindowsFixedSizeDialogHint))
+ dialog = true;
+
+ // Parent: Use transient parent for top levels.
+ if (popup) {
+ flags |= Qt::WindowStaysOnTopHint; // a popup stays on top, no parent.
+ } else {
+ if (const QWindow *parentWindow = topLevel ? w->transientParent() : w->parent())
+ parentHandle = QWindowsWindow::handleOf(parentWindow);
+ }
+
+ if (popup || (type == Qt::ToolTip) || (type == Qt::SplashScreen)) {
+ style = WS_POPUP;
+ } else if (topLevel && !desktop) {
+ if (flags & Qt::FramelessWindowHint)
+ style = WS_POPUP; // no border
+ else if (flags & Qt::WindowTitleHint)
+ style = WS_OVERLAPPED;
+ else
+ style = 0;
+ } else {
+ style = WS_CHILD;
+ }
+
+ if (!desktop) {
+ // if (!testAttribute(Qt::WA_PaintUnclipped))
+ // ### Commented out for now as it causes some problems, but
+ // this should be correct anyway, so dig some more into this
+#ifdef Q_FLATTEN_EXPOSE
+ if (isGL)
+ style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN; // see SetPixelFormat
+#else
+ style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN ;
+#endif
+ if (topLevel) {
+ if ((type == Qt::Window || dialog || tool)) {
+ if (!(flags & Qt::FramelessWindowHint)) {
+ style |= WS_POPUP;
+ if (flags & Qt::MSWindowsFixedSizeDialogHint) {
+ style |= WS_DLGFRAME;
+ } else {
+ style |= WS_THICKFRAME;
+ }
+ }
+ if (flags & Qt::WindowTitleHint)
+ style |= WS_CAPTION;
+ if (flags & Qt::WindowSystemMenuHint)
+ style |= WS_SYSMENU;
+ if (flags & Qt::WindowMinimizeButtonHint)
+ style |= WS_MINIMIZEBOX;
+ if (shouldShowMaximizeButton(flags))
+ style |= WS_MAXIMIZEBOX;
+ if (tool)
+ exStyle |= WS_EX_TOOLWINDOW;
+ if (flags & Qt::WindowContextHelpButtonHint)
+ exStyle |= WS_EX_CONTEXTHELP;
+ } else {
+ exStyle |= WS_EX_TOOLWINDOW;
+ }
+ }
+ }
+}
+
+QWindowsWindow::WindowData
+ WindowCreationData::create(const QWindow *w, const QRect &geometry, QString title) const
+{
+ typedef QSharedPointer<QWindowCreationContext> QWindowCreationContextPtr;
+
+ WindowData result;
+ result.flags = flags;
+
+ if (desktop) { // desktop widget. No frame, hopefully?
+ result.hwnd = GetDesktopWindow();
+ result.geometry = frameGeometry(result.hwnd);
+ if (QWindowsContext::verboseWindows)
+ qDebug().nospace() << "Created desktop window " << w << result.hwnd;
+ return result;
+ }
+
+ const HINSTANCE appinst = (HINSTANCE)GetModuleHandle(0);
+
+ const QString windowClassName = QWindowsContext::instance()->registerWindowClass(w, isGL);
+
+ if (title.isEmpty() && (result.flags & Qt::WindowTitleHint))
+ title = topLevel ? qAppName() : w->objectName();
+
+ const wchar_t *titleUtf16 = reinterpret_cast<const wchar_t *>(title.utf16());
+ const wchar_t *classNameUtf16 = reinterpret_cast<const wchar_t *>(windowClassName.utf16());
+
+ // Capture events before CreateWindowEx() returns.
+ const QWindowCreationContextPtr context(new QWindowCreationContext(w, geometry, style, exStyle));
+ QWindowsContext::instance()->setWindowCreationContext(context);
+
+ if (QWindowsContext::verboseWindows)
+ qDebug().nospace()
+ << "CreateWindowEx: " << w << *this
+ << " class=" <<windowClassName << " title=" << title
+ << "\nrequested: " << geometry << ": "
+ << context->frameWidth << 'x' << context->frameHeight
+ << '+' << context->frameX << '+' << context->frameY;
+
+ result.hwnd = CreateWindowEx(exStyle, classNameUtf16, titleUtf16,
+ style,
+ context->frameX, context->frameY,
+ context->frameWidth, context->frameHeight,
+ parentHandle, NULL, appinst, NULL);
+ QWindowsContext::instance()->setWindowCreationContext(QWindowCreationContextPtr());
+ if (QWindowsContext::verboseWindows)
+ qDebug().nospace()
+ << "CreateWindowEx: returns " << w << ' ' << result.hwnd << " obtained geometry: "
+ << context->obtainedGeometry << context->margins;
+
+ if (!result.hwnd) {
+ qErrnoWarning("%s: CreateWindowEx failed", __FUNCTION__);
+ return result;
+ }
+
+ result.geometry = context->obtainedGeometry;
+ result.frame = context->margins;
+ return result;
+}
+
+void WindowCreationData::applyWindowFlags(HWND hwnd) const
+{
+ // Keep enabled and visible from the current style.
+ const LONG_PTR oldStyle = GetWindowLongPtr(hwnd, GWL_STYLE);
+ const LONG_PTR oldExStyle = GetWindowLongPtr(hwnd, GWL_EXSTYLE);
+
+ const LONG_PTR newStyle = style | (oldStyle & (WS_DISABLED|WS_VISIBLE));
+ if (oldStyle != newStyle)
+ SetWindowLongPtr(hwnd, GWL_STYLE, newStyle);
+ const LONG_PTR newExStyle = exStyle;
+ if (newExStyle != oldExStyle)
+ SetWindowLongPtr(hwnd, GWL_EXSTYLE, newExStyle);
+ if (QWindowsContext::verboseWindows)
+ qDebug().nospace() << __FUNCTION__ << hwnd << *this
+ << "\n Style from " << debugWinStyle(oldStyle) << "\n to "
+ << debugWinStyle(newStyle) << "\n ExStyle from 0x"
+ << QByteArray::number(qulonglong(oldExStyle), 16) << " to 0x"
+ << QByteArray::number(qulonglong(newExStyle), 16);
+}
+
+void WindowCreationData::initialize(HWND hwnd, bool frameChange) const
+{
+ if (desktop || !hwnd)
+ return;
+ UINT flags = SWP_NOMOVE | SWP_NOSIZE;
+ if (frameChange)
+ flags |= SWP_FRAMECHANGED;
+ if (topLevel) {
+ flags |= SWP_NOACTIVATE;
+ if ((flags & Qt::WindowStaysOnTopHint) || (type == Qt::ToolTip)) {
+ SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, flags);
+ if (flags & Qt::WindowStaysOnBottomHint)
+ qWarning() << "QWidget: Incompatible window flags: the window can't be on top and on bottom at the same time";
+ } else if (flags & Qt::WindowStaysOnBottomHint) {
+ SetWindowPos(hwnd, HWND_BOTTOM, 0, 0, 0, 0, flags);
+ }
+ if (flags & (Qt::CustomizeWindowHint|Qt::WindowTitleHint)) {
+ HMENU systemMenu = GetSystemMenu(hwnd, FALSE);
+ if (flags & Qt::WindowCloseButtonHint)
+ EnableMenuItem(systemMenu, SC_CLOSE, MF_BYCOMMAND|MF_ENABLED);
+ else
+ EnableMenuItem(systemMenu, SC_CLOSE, MF_BYCOMMAND|MF_GRAYED);
+ }
+ } else { // child.
+ SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, flags);
+ }
+}
+
+/*!
+ \class QWindowsGeometryHint
+ \brief Stores geometry constraints and provides utility functions.
+
+ Geometry constraints ready to apply to a MINMAXINFO taking frame
+ into account.
+
+ \ingroup qt-lighthouse-win
+*/
+
+#define QWINDOWSIZE_MAX ((1<<24)-1)
+
+QWindowsGeometryHint::QWindowsGeometryHint(const QWindow *w) :
+ minimumSize(w->minimumSize()),
+ maximumSize(w->maximumSize())
+{
+}
+
+bool QWindowsGeometryHint::validSize(const QSize &s) const
+{
+ const int width = s.width();
+ const int height = s.height();
+ return width >= minimumSize.width() && width <= maximumSize.width()
+ && height >= minimumSize.height() && height <= maximumSize.height();
+}
+
+QMargins QWindowsGeometryHint::frame(DWORD style, DWORD exStyle)
+{
+ RECT rect = {0,0,0,0};
+ style &= ~(WS_OVERLAPPED); // Not permitted, see docs.
+ if (!AdjustWindowRectEx(&rect, style, FALSE, exStyle))
+ qErrnoWarning("%s: AdjustWindowRectEx failed", __FUNCTION__);
+ const QMargins result(qAbs(rect.left), qAbs(rect.top),
+ qAbs(rect.right), qAbs(rect.bottom));
+ if (QWindowsContext::verboseWindows)
+ qDebug().nospace() << __FUNCTION__ << " style= 0x"
+ << QString::number(style, 16)
+ << " exStyle=0x" << QString::number(exStyle, 16) << ' ' << rect << ' ' << result;
+
+ return result;
+}
+
+void QWindowsGeometryHint::applyToMinMaxInfo(HWND hwnd, MINMAXINFO *mmi) const
+{
+ return applyToMinMaxInfo(GetWindowLong(hwnd, GWL_STYLE),
+ GetWindowLong(hwnd, GWL_EXSTYLE), mmi);
+}
+
+void QWindowsGeometryHint::applyToMinMaxInfo(DWORD style, DWORD exStyle, MINMAXINFO *mmi) const
+{
+ if (QWindowsContext::verboseWindows)
+ qDebug().nospace() << '>' << __FUNCTION__ << '<' << " min="
+ << minimumSize.width() << ',' << minimumSize.height()
+ << " max=" << maximumSize.width() << ',' << maximumSize.height()
+ << " in " << *mmi;
+
+ const QMargins margins = QWindowsGeometryHint::frame(style, exStyle);
+ const int frameWidth = margins.left() + margins.right();
+ const int frameHeight = margins.top() + margins.bottom();
+ if (minimumSize.width() > 0)
+ mmi->ptMinTrackSize.x = minimumSize.width() + frameWidth;
+ if (minimumSize.height() > 0)
+ mmi->ptMinTrackSize.y = minimumSize.height() + frameHeight;
+
+ const int maximumWidth = qMax(maximumSize.width(), minimumSize.width());
+ const int maximumHeight = qMax(maximumSize.height(), minimumSize.height());
+ if (maximumWidth < QWINDOWSIZE_MAX)
+ mmi->ptMaxTrackSize.x = maximumWidth + frameWidth;
+ // windows with title bar have an implicit size limit of 112 pixels
+ if (maximumHeight < QWINDOWSIZE_MAX)
+ mmi->ptMaxTrackSize.y = qMax(maximumHeight + frameHeight, 112);
+ if (QWindowsContext::verboseWindows)
+ qDebug().nospace() << '<' << __FUNCTION__
+ << " frame=" << margins << ' ' << frameWidth << ',' << frameHeight
+ << " out " << *mmi;
+}
+
+/*!
+ \class QWindowCreationContext
+ \brief Active Context for creating windows.
+
+ There is a phase in window creation (WindowCreationData::create())
+ in which events are sent before the system API CreateWindowEx() returns
+ the handle. These cannot be handled by the platform window as the association
+ of the unknown handle value to the window does not exist yet and as not
+ to trigger recursive handle creation, etc.
+
+ In that phase, an instance of QWindowCreationContext is set on
+ QWindowsContext.
+
+ QWindowCreationContext stores the information to answer the initial
+ WM_GETMINMAXINFO and obtains the corrected size/position.
+
+ \sa WindowCreationData, QWindowsContext
+ \ingroup qt-lighthouse-win
+*/
+
+QWindowCreationContext::QWindowCreationContext(const QWindow *w,
+ const QRect &geometry,
+ DWORD style_, DWORD exStyle_) :
+ geometryHint(w), style(style_), exStyle(exStyle_),
+ requestedGeometry(geometry), obtainedGeometry(geometry),
+ margins(QWindowsGeometryHint::frame(style, exStyle)),
+ frameX(CW_USEDEFAULT), frameY(CW_USEDEFAULT),
+ frameWidth(CW_USEDEFAULT), frameHeight(CW_USEDEFAULT)
+{
+ // Geometry of toplevels does not consider window frames.
+ // TODO: No concept of WA_wasMoved yet that would indicate a
+ // CW_USEDEFAULT unless set. For now, assume that 0,0 means 'default'
+ // for toplevels.
+ if (geometry.isValid()) {
+ if (!w->isTopLevel() || geometry.y() >= margins.top()) {
+ frameX = geometry.x() - margins.left();
+ frameY = geometry.y() - margins.top();
+ }
+ frameWidth = geometry.width() + margins.left() + margins.right();
+ frameHeight = geometry.height() + margins.top() + margins.bottom();
+ }
+ if (QWindowsContext::verboseWindows)
+ qDebug().nospace()
+ << __FUNCTION__ << ' ' << w << " min" << geometryHint.minimumSize
+ << " min" << geometryHint.maximumSize;
+}
+
+/*!
+ \class QWindowsBaseWindow
+ \brief Raster or OpenGL Window.
+
+ \list
+ \o Raster type: handleWmPaint() is implemented to
+ to bitblt the image. The DC can be accessed
+ via getDC/Relase DC, which has a special handling
+ when within a paint event (in that case, the DC obtained
+ from BeginPaint() is returned).
+
+ \o Open GL: The first time QWindowsGLContext accesses
+ the handle, it sets up the pixelformat on the DC
+ which in turn sets it on the window (see flag
+ PixelFormatInitialized).
+ handleWmPaint() is empty (although required).
+ \endlist
+
+ \ingroup qt-lighthouse-win
+*/
+
+QWindowsWindow::QWindowsWindow(QWindow *aWindow, const WindowData &data) :
+ QPlatformWindow(aWindow),
+ m_data(data),
+ m_flags(0),
+ m_hdc(0),
+ m_windowState(aWindow->windowState()),
+ m_opacity(1.0),
+ m_mouseGrab(false),
+ m_cursor(QWindowsScreen::screenOf(aWindow)->cursor().standardWindowCursor()),
+ m_dropTarget(0)
+{
+ if (aWindow->surfaceType() == QWindow::OpenGLSurface)
+ setFlag(OpenGL_Surface);
+ QWindowsContext::instance()->addWindow(m_data.hwnd, this);
+ if (aWindow->isTopLevel()) {
+ switch (aWindow->windowType()) {
+ case Qt::Window:
+ case Qt::Dialog:
+ case Qt::Sheet:
+ case Qt::Drawer:
+ case Qt::Popup:
+ case Qt::Tool:
+ registerDropSite();
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+QWindowsWindow::~QWindowsWindow()
+{
+ destroyWindow();
+}
+
+void QWindowsWindow::destroyWindow()
+{
+ if (QWindowsContext::verboseIntegration || QWindowsContext::verboseWindows)
+ qDebug() << __FUNCTION__ << this << window() << m_data.hwnd;
+ if (m_data.hwnd) {
+ unregisterDropSite();
+ if (m_data.hwnd != GetDesktopWindow())
+ DestroyWindow(m_data.hwnd);
+ QWindowsContext::instance()->removeWindow(m_data.hwnd);
+ m_data.hwnd = 0;
+ }
+}
+
+void QWindowsWindow::registerDropSite()
+{
+ if (m_data.hwnd && !m_dropTarget) {
+ m_dropTarget = new QWindowsOleDropTarget(window());
+ RegisterDragDrop(m_data.hwnd, m_dropTarget);
+ CoLockObjectExternal(m_dropTarget, true, true);
+ }
+}
+
+void QWindowsWindow::unregisterDropSite()
+{
+ if (m_data.hwnd && m_dropTarget) {
+ m_dropTarget->Release();
+ CoLockObjectExternal(m_dropTarget, false, true);
+ RevokeDragDrop(m_data.hwnd);
+ m_dropTarget = 0;
+ }
+}
+
+QWindow *QWindowsWindow::topLevelOf(QWindow *w)
+{
+ while (QWindow *parent = w->parent())
+ w = parent;
+ return w;
+}
+
+QWindowsWindow::WindowData
+ QWindowsWindow::WindowData::create(const QWindow *w,
+ const WindowData &parameters,
+ const QString &title,
+ bool isGL)
+{
+ WindowCreationData creationData;
+ creationData.fromWindow(w, parameters.flags, isGL);
+ WindowData result = creationData.create(w, parameters.geometry, title);
+ creationData.initialize(result.hwnd, false);
+ return result;
+}
+
+void QWindowsWindow::setVisible(bool visible)
+{
+ if (QWindowsContext::verboseWindows)
+ qDebug() << __FUNCTION__ << this << window() << m_data.hwnd << visible;
+ if (m_data.hwnd) {
+ if (visible) {
+ show_sys();
+ } else {
+ hide_sys();
+ }
+ }
+}
+
+bool QWindowsWindow::isVisible() const
+{
+ return m_data.hwnd && IsWindowVisible(m_data.hwnd);
+}
+
+// partially from QWidgetPrivate::show_sys()
+void QWindowsWindow::show_sys() const
+{
+ int sm = SW_SHOWNORMAL;
+ bool fakedMaximize = false;
+ const QWindow *w = window();
+ const Qt::WindowFlags flags = w->windowFlags();
+ const Qt::WindowType type = w->windowType();
+ if (w->isTopLevel()) {
+ const Qt::WindowState state = w->windowState();
+ if (state & Qt::WindowMinimized) {
+ sm = SW_SHOWMINIMIZED;
+ if (!isVisible())
+ sm = SW_SHOWMINNOACTIVE;
+ } else if (state & Qt::WindowMaximized) {
+ sm = SW_SHOWMAXIMIZED;
+ // Windows will not behave correctly when we try to maximize a window which does not
+ // have minimize nor maximize buttons in the window frame. Windows would then ignore
+ // non-available geometry, and rather maximize the widget to the full screen, minus the
+ // window frame (caption). So, we do a trick here, by adding a maximize button before
+ // maximizing the widget, and then remove the maximize button afterwards.
+ if (flags & Qt::WindowTitleHint &&
+ !(flags & (Qt::WindowMinMaxButtonsHint | Qt::FramelessWindowHint))) {
+ fakedMaximize = TRUE;
+ setStyle(style() | WS_MAXIMIZEBOX);
+ }
+ }
+ }
+ if (type == Qt::Popup || type == Qt::ToolTip || type == Qt::Tool)
+ sm = SW_SHOWNOACTIVATE;
+
+ ShowWindow(m_data.hwnd, sm);
+
+ if (fakedMaximize) {
+ setStyle(style() & ~WS_MAXIMIZEBOX);
+ SetWindowPos(m_data.hwnd, 0, 0, 0, 0, 0,
+ SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER
+ | SWP_FRAMECHANGED);
+ }
+}
+
+// partially from QWidgetPrivate::hide_sys()
+void QWindowsWindow::hide_sys() const
+{
+ const Qt::WindowFlags flags = window()->windowFlags();
+ if (flags != Qt::Desktop) {
+ if (flags & Qt::Popup)
+ ShowWindow(m_data.hwnd, SW_HIDE);
+ else
+ SetWindowPos(m_data.hwnd,0, 0,0,0,0, SWP_HIDEWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER);
+ }
+}
+
+void QWindowsWindow::setParent(const QPlatformWindow *newParent)
+{
+ if (QWindowsContext::verboseWindows)
+ qDebug() << __FUNCTION__ << window() << newParent;
+
+ if (newParent != parent() && m_data.hwnd)
+ setParent_sys(newParent);
+}
+
+void QWindowsWindow::setParent_sys(const QPlatformWindow *parent) const
+{
+ HWND parentHWND = 0;
+ if (parent) {
+ const QWindowsWindow *parentW = static_cast<const QWindowsWindow *>(parent);
+ parentHWND = parentW->handle();
+ }
+ SetParent(m_data.hwnd, parentHWND);
+}
+
+void QWindowsWindow::handleShown()
+{
+ QWindowSystemInterface::handleMapEvent(window());
+}
+
+void QWindowsWindow::handleHidden()
+{
+ QWindowSystemInterface::handleUnmapEvent(window());
+}
+
+void QWindowsWindow::setGeometry(const QRect &rect)
+{
+ const QSize oldSize = m_data.geometry.size();
+ m_data.geometry = rect;
+ const QSize newSize = rect.size();
+ // Check on hint.
+ if (newSize != oldSize) {
+ const QWindowsGeometryHint hint(window());
+ if (!hint.validSize(newSize)) {
+ qWarning("%s: Attempt to set a size (%dx%d) violating the constraints"
+ "(%dx%d - %dx%d) on window '%s'.", __FUNCTION__,
+ newSize.width(), newSize.height(),
+ hint.minimumSize.width(), hint.minimumSize.height(),
+ hint.maximumSize.width(), hint.maximumSize.height(),
+ qPrintable(window()->objectName()));
+ }
+ }
+ if (m_data.hwnd) {
+ // A ResizeEvent with resulting geometry will be sent. If we cannot
+ // achieve that size (for example, window title minimal constraint),
+ // notify and warn.
+ setGeometry_sys(rect);
+ if (m_data.geometry != rect) {
+ qWarning("%s: Unable to set geometry %dx%d+%d+%d on '%s'."
+ " Resulting geometry: %dx%d+%d+%d.",
+ __FUNCTION__,
+ rect.width(), rect.height(), rect.x(), rect.y(),
+ qPrintable(window()->objectName()),
+ m_data.geometry.width(), m_data.geometry.height(),
+ m_data.geometry.x(), m_data.geometry.y());
+ }
+ } else {
+ QPlatformWindow::setGeometry(rect);
+ }
+}
+
+void QWindowsWindow::handleMoved()
+{
+ if (!IsIconic(m_data.hwnd)) // Minimize can send nonsensical move events.
+ handleGeometryChange();
+}
+
+void QWindowsWindow::handleResized(int wParam)
+{
+ switch (wParam) {
+ case SIZE_MAXHIDE: // Some other window affected.
+ case SIZE_MAXSHOW:
+ return;
+ case SIZE_MINIMIZED:
+ handleWindowStateChange(Qt::WindowMinimized);
+ return;
+ case SIZE_MAXIMIZED:
+ handleWindowStateChange(Qt::WindowMaximized);
+ handleGeometryChange();
+ break;
+ case SIZE_RESTORED:
+ if (m_windowState != Qt::WindowNoState)
+ handleWindowStateChange(Qt::WindowNoState);
+ handleGeometryChange();
+ break;
+ }
+}
+
+void QWindowsWindow::handleGeometryChange()
+{
+ m_data.geometry = geometry_sys();
+ QPlatformWindow::setGeometry(m_data.geometry);
+ QWindowSystemInterface::handleGeometryChange(window(), m_data.geometry);
+
+ if (QWindowsContext::verboseEvents || QWindowsContext::verboseWindows)
+ qDebug() << __FUNCTION__ << this << window() << m_data.geometry;
+}
+
+void QWindowsWindow::setGeometry_sys(const QRect &rect) const
+{
+ const QRect frameGeometry = rect + frameMargins();
+
+ if (QWindowsContext::verboseWindows)
+ qDebug() << '>' << __FUNCTION__ << this << window()
+ << " \n from " << geometry_sys() << " to " <<rect
+ << " new frame: " << frameGeometry;
+
+ const bool rc = MoveWindow(m_data.hwnd, frameGeometry.x(), frameGeometry.y(),
+ frameGeometry.width(), frameGeometry.height(), true);
+ if (QWindowsContext::verboseWindows)
+ qDebug() << '<' << __FUNCTION__ << this << window()
+ << " \n resulting " << rc << geometry_sys();
+}
+
+QRect QWindowsWindow::geometry_sys() const
+{
+ // Warning: Returns bogus values when minimized.
+ return frameGeometry(m_data.hwnd) - frameMargins();
+}
+
+/*!
+ Allocates a HDC for the window or returns the temporary one
+ obtained from WinAPI BeginPaint within a WM_PAINT event.
+
+ \sa releaseDC()
+*/
+
+HDC QWindowsWindow::getDC()
+{
+ if (!m_hdc)
+ m_hdc = GetDC(handle());
+ return m_hdc;
+}
+
+/*!
+ Relases the HDC for the window or does nothing in
+ case it was obtained from WinAPI BeginPaint within a WM_PAINT event.
+
+ \sa getDC()
+*/
+
+void QWindowsWindow::releaseDC()
+{
+ if (m_hdc && !testFlag(WithinWmPaint)) {
+ ReleaseDC(handle(), m_hdc);
+ m_hdc = 0;
+ }
+}
+
+void QWindowsWindow::handleWmPaint(HWND hwnd, UINT,
+ WPARAM, LPARAM)
+{
+ PAINTSTRUCT ps;
+ if (testFlag(OpenGL_Surface)) {
+ BeginPaint(hwnd, &ps); // WM_ERASEBKGND needs to be handled.
+ EndPaint(hwnd, &ps);
+ } else {
+ releaseDC();
+ m_hdc = BeginPaint(hwnd, &ps);
+ setFlag(WithinWmPaint);
+
+ const QRect updateRect = qrectFromRECT(ps.rcPaint);
+ if (QWindowsContext::verboseIntegration)
+ qDebug() << __FUNCTION__ << this << window() << updateRect;
+
+ QWindowSystemInterface::handleSynchronousExposeEvent(window(), QRegion(updateRect));
+ clearFlag(WithinWmPaint);
+ m_hdc = 0;
+ EndPaint(hwnd, &ps);
+ }
+}
+
+void QWindowsWindow::setWindowTitle(const QString &title)
+{
+ if (QWindowsContext::verboseWindows)
+ qDebug() << __FUNCTION__ << this << window() <<title;
+ if (m_data.hwnd)
+ SetWindowText(m_data.hwnd, (const wchar_t*)title.utf16());
+}
+
+Qt::WindowFlags QWindowsWindow::setWindowFlags(Qt::WindowFlags flags)
+{
+ if (QWindowsContext::verboseWindows)
+ qDebug() << '>' << __FUNCTION__ << this << window() << "\n from: "
+ << QWindowsWindow::debugWindowFlags(m_data.flags)
+ << "\n to: " << QWindowsWindow::debugWindowFlags(flags);
+ if (m_data.flags != flags) {
+ m_data.flags = flags;
+ if (m_data.hwnd)
+ m_data = setWindowFlags_sys(flags);
+ }
+ if (QWindowsContext::verboseWindows)
+ qDebug() << '<' << __FUNCTION__ << "\n returns: "
+ << QWindowsWindow::debugWindowFlags(m_data.flags);
+ return m_data.flags;
+}
+
+QWindowsWindow::WindowData QWindowsWindow::setWindowFlags_sys(Qt::WindowFlags wt) const
+{
+ // Geometry changes have not been observed here. Frames change, though.
+ WindowCreationData creationData;
+ creationData.fromWindow(window(), wt, window()->surfaceType() == QWindow::OpenGLSurface);
+ creationData.applyWindowFlags(m_data.hwnd);
+ creationData.initialize(m_data.hwnd, true);
+ WindowData result = m_data;
+ result.flags = creationData.flags;
+ setFlag(FrameDirty);
+ return result;
+}
+
+void QWindowsWindow::handleWindowStateChange(Qt::WindowState state)
+{
+ if (QWindowsContext::verboseWindows)
+ qDebug() << __FUNCTION__ << this << window()
+ << "\n from " << debugWindowStates(m_windowState)
+ << " to " << debugWindowStates(state);
+ setFlag(FrameDirty);
+ m_windowState = state;
+ QWindowSystemInterface::handleWindowStateChanged(window(), state);
+}
+
+Qt::WindowState QWindowsWindow::setWindowState(Qt::WindowState state)
+{
+ if (m_data.hwnd) {
+ setWindowState_sys(state);
+ m_windowState = state;
+ }
+ return state;
+}
+
+Qt::WindowState QWindowsWindow::windowState_sys() const
+{
+ if (IsIconic(m_data.hwnd))
+ return Qt::WindowMinimized;
+ if (IsZoomed(m_data.hwnd))
+ return Qt::WindowMaximized;
+ if (geometry_sys() == window()->screen()->geometry())
+ return Qt::WindowFullScreen;
+ return Qt::WindowNoState;
+}
+
+Qt::WindowStates QWindowsWindow::windowStates_sys() const
+{
+ Qt::WindowStates result = windowState_sys();
+ if (GetActiveWindow() == m_data.hwnd)
+ result |= Qt::WindowActive;
+ return result;
+}
+
+/*!
+ \brief Change the window state.
+
+ \note Window frames change when maximized;
+ the top margin shrinks somewhat but that cannot be obtained using
+ AdjustWindowRectEx().
+
+ \note Some calls to SetWindowLong require a subsequent call
+ to ShowWindow.
+*/
+
+void QWindowsWindow::setWindowState_sys(Qt::WindowState newState)
+{
+ const Qt::WindowStates oldStates = windowStates_sys();
+ // Maintain the active flag as the platform window API does not
+ // use it.
+ Qt::WindowStates newStates = newState;
+ if (oldStates & Qt::WindowActive)
+ newStates |= Qt::WindowActive;
+ if (oldStates == newStates)
+ return;
+ if (QWindowsContext::verboseWindows)
+ qDebug() << '>' << __FUNCTION__ << this << window()
+ << " from " << debugWindowStates(oldStates)
+ << " to " << debugWindowStates(newStates);
+
+ const bool isActive = newStates & Qt::WindowActive;
+ const int max = isActive ? SW_SHOWMAXIMIZED : SW_MAXIMIZE;
+ const int normal = isActive ? SW_SHOWNORMAL : SW_SHOWNOACTIVATE;
+ const int min = isActive ? SW_SHOWMINIMIZED : SW_MINIMIZE;
+ const bool visible = isVisible();
+
+ setFlag(FrameDirty);
+
+ if ((oldStates & Qt::WindowMaximized) != (newStates & Qt::WindowMaximized)) {
+ if (visible && !(newStates & Qt::WindowMinimized))
+ ShowWindow(m_data.hwnd, (newStates & Qt::WindowMaximized) ? max : normal);
+ }
+
+ if ((oldStates & Qt::WindowFullScreen) != (newStates & Qt::WindowFullScreen)) {
+ if (newStates & Qt::WindowFullScreen) {
+#ifndef Q_FLATTEN_EXPOSE
+ UINT newStyle = WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_POPUP;
+#else
+ UINT newStyle = WS_POPUP;
+#endif
+ if (style() & WS_SYSMENU)
+ newStyle |= WS_SYSMENU;
+ if (visible)
+ newStyle |= WS_VISIBLE;
+ setStyle(newStyle);
+
+ const QRect r = window()->screen()->geometry();
+ UINT swpf = SWP_FRAMECHANGED;
+ if (newStates & Qt::WindowActive)
+ swpf |= SWP_NOACTIVATE;
+
+ SetWindowPos(m_data.hwnd, HWND_TOP, r.left(), r.top(), r.width(), r.height(), swpf);
+ } else {
+ if (visible)
+ setStyle(style() | WS_VISIBLE);
+ UINT swpf = SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE;
+ if (newStates & Qt::WindowActive)
+ swpf |= SWP_NOACTIVATE;
+ SetWindowPos(m_data.hwnd, 0, 0, 0, 0, 0, swpf);
+
+ // preserve maximized state
+ if (visible)
+ ShowWindow(m_data.hwnd, (newStates & Qt::WindowMaximized) ? max : normal);
+ }
+ }
+
+ if ((oldStates & Qt::WindowMinimized) != (newStates & Qt::WindowMinimized)) {
+ if (visible)
+ ShowWindow(m_data.hwnd, (newStates & Qt::WindowMinimized) ? min :
+ (newStates & Qt::WindowMaximized) ? max : normal);
+ }
+ if (QWindowsContext::verboseWindows)
+ qDebug() << '<' << __FUNCTION__ << this << window()
+ << debugWindowStates(newStates);
+}
+
+void QWindowsWindow::setStyle(unsigned s) const
+{
+ if (QWindowsContext::verboseWindows)
+ qDebug() << __FUNCTION__ << this << window() << debugWinStyle(s);
+ setFlag(FrameDirty);
+ SetWindowLongPtr(m_data.hwnd, GWL_STYLE, s);
+}
+
+void QWindowsWindow::setExStyle(unsigned s) const
+{
+ if (QWindowsContext::verboseWindows)
+ qDebug().nospace() << __FUNCTION__ << ' ' << this << ' ' << window()
+ << " 0x" << QByteArray::number(s, 16);
+ setFlag(FrameDirty);
+ SetWindowLongPtr(m_data.hwnd, GWL_EXSTYLE, s);
+}
+
+void QWindowsWindow::raise()
+{
+ if (QWindowsContext::verboseWindows)
+ qDebug() << __FUNCTION__ << this << window();
+ SetWindowPos(m_data.hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
+}
+
+void QWindowsWindow::lower()
+{
+ if (QWindowsContext::verboseWindows)
+ qDebug() << __FUNCTION__ << this << window();
+ if (m_data.hwnd)
+ SetWindowPos(m_data.hwnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
+}
+
+void QWindowsWindow::propagateSizeHints()
+{
+ if (QWindowsContext::verboseWindows)
+ qDebug() << __FUNCTION__ << this << window();
+}
+
+QMargins QWindowsWindow::frameMargins() const
+{
+ // Frames are invalidated by style changes (window state, flags).
+ // As they are also required for geometry calculations in resize
+ // event sequences, introduce a dirty flag mechanism to be able
+ // to cache results.
+ if (testFlag(FrameDirty)) {
+ m_data.frame = QWindowsGeometryHint::frame(style(), exStyle());
+ clearFlag(FrameDirty);
+ }
+ return m_data.frame;
+}
+
+void QWindowsWindow::setOpacity(qreal level)
+{
+ if (QWindowsContext::verboseWindows)
+ qDebug() << __FUNCTION__ << level;
+ if (m_opacity != level) {
+ m_opacity = level;
+ if (m_data.hwnd)
+ setOpacity_sys(level);
+ }
+}
+
+void QWindowsWindow::setOpacity_sys(qreal level) const
+{
+ const long wl = GetWindowLong(m_data.hwnd, GWL_EXSTYLE);
+ const bool isOpaque = level == 1.0;
+
+ if (isOpaque) {
+ if (wl & WS_EX_LAYERED)
+ SetWindowLong(m_data.hwnd, GWL_EXSTYLE, wl & ~WS_EX_LAYERED);
+ } else {
+ if ((wl & WS_EX_LAYERED) == 0)
+ SetWindowLong(m_data.hwnd, GWL_EXSTYLE, wl | WS_EX_LAYERED);
+ if (m_data.flags & Qt::FramelessWindowHint) {
+ BLENDFUNCTION blend = {AC_SRC_OVER, 0, (int)(255.0 * level), AC_SRC_ALPHA};
+ QWindowsContext::user32dll.updateLayeredWindow(m_data.hwnd, NULL, NULL, NULL, NULL, NULL, 0, &blend, ULW_ALPHA);
+ } else {
+ QWindowsContext::user32dll.setLayeredWindowAttributes(m_data.hwnd, 0, (int)(level * 255), LWA_ALPHA);
+ }
+ }
+}
+
+void QWindowsWindow::requestActivateWindow()
+{
+ if (QWindowsContext::verboseWindows)
+ qDebug() << __FUNCTION__ << this << window();
+ if (m_data.hwnd)
+ SetForegroundWindow(m_data.hwnd);
+}
+
+bool QWindowsWindow::setKeyboardGrabEnabled(bool grab)
+{
+ if (!m_data.hwnd) {
+ qWarning("%s: No handle", __FUNCTION__);
+ return false;
+ }
+ if (QWindowsContext::verboseWindows)
+ qDebug() << __FUNCTION__ << this << window() << grab;
+
+ QWindowsContext *context = QWindowsContext::instance();
+ if (grab) {
+ context->setKeyGrabber(window());
+ } else {
+ if (context->keyGrabber() == window())
+ context->setKeyGrabber(0);
+ }
+ return true;
+}
+
+bool QWindowsWindow::setMouseGrabEnabled(bool grab)
+{
+ bool result = false;
+ if (!m_data.hwnd) {
+ qWarning("%s: No handle", __FUNCTION__);
+ return result;
+ }
+ if (QWindowsContext::verboseWindows)
+ qDebug() << __FUNCTION__ << window() << grab;
+
+ if (m_mouseGrab != grab) {
+ m_mouseGrab = grab;
+ if (isVisible())
+ setMouseGrabEnabled_sys(grab);
+ }
+ return grab;
+}
+
+void QWindowsWindow::setMouseGrabEnabled_sys(bool grab)
+{
+ if (grab) {
+ SetCapture(m_data.hwnd);
+ } else {
+ ReleaseCapture();
+ }
+}
+
+void QWindowsWindow::getSizeHints(MINMAXINFO *mmi) const
+{
+ const QWindowsGeometryHint hint(window());
+ hint.applyToMinMaxInfo(m_data.hwnd, mmi);
+ if (QWindowsContext::verboseWindows)
+ qDebug() << __FUNCTION__ << window() << *mmi;
+}
+
+/*!
+ \brief Applies to cursor property set on the window to the global cursor
+ unless there is an override cursor.
+
+ \sa QWindowsCursor
+*/
+
+void QWindowsWindow::applyCursor()
+{
+ if (!QGuiApplication::overrideCursor())
+ SetCursor(m_cursor.handle());
+}
+
+void QWindowsWindow::setCursor(const QWindowsWindowCursor &c)
+{
+ if (c.handle() != m_cursor.handle()) {
+ const bool underMouse = QWindowsContext::instance()->windowUnderMouse() == window();
+ if (QWindowsContext::verboseWindows)
+ qDebug() << window() << __FUNCTION__ << "Shape=" << c.cursor().shape()
+ << " isWUM=" << underMouse;
+ m_cursor = c;
+ if (underMouse)
+ applyCursor();
+ }
+}
+
+/*!
+ \brief Find a child window using flags from ChildWindowFromPointEx.
+*/
+
+QWindowsWindow *QWindowsWindow::childAtScreenPoint(const QPoint &screenPoint,
+ unsigned cwexflags) const
+{
+ if (m_data.hwnd)
+ return QWindowsContext::instance()->findPlatformWindowAt(m_data.hwnd, screenPoint, cwexflags);
+ return 0;
+}
+
+QWindowsWindow *QWindowsWindow::childAt(const QPoint &clientPoint, unsigned cwexflags) const
+{
+ if (m_data.hwnd)
+ return childAtScreenPoint(QWindowsGeometryHint::mapToGlobal(m_data.hwnd, clientPoint),
+ cwexflags);
+ return 0;
+}
+
+QByteArray QWindowsWindow::debugWindowFlags(Qt::WindowFlags wf)
+{
+ const int iwf = int(wf);
+ QByteArray rc = "0x";
+ rc += QByteArray::number(iwf, 16);
+ rc += " [";
+
+ switch ((iwf & Qt::WindowType_Mask)) {
+ case Qt::Widget:
+ rc += " Widget";
+ break;
+ case Qt::Window:
+ rc += " Window";
+ break;
+ case Qt::Dialog:
+ rc += " Dialog";
+ break;
+ case Qt::Sheet:
+ rc += " Sheet";
+ break;
+ case Qt::Popup:
+ rc += " Popup";
+ break;
+ case Qt::Tool:
+ rc += " Tool";
+ break;
+ case Qt::ToolTip:
+ rc += " ToolTip";
+ break;
+ case Qt::SplashScreen:
+ rc += " SplashScreen";
+ break;
+ case Qt::Desktop:
+ rc += " Desktop";
+ break;
+ case Qt::SubWindow:
+ rc += " SubWindow";
+ break;
+ }
+ if (iwf & Qt::MSWindowsFixedSizeDialogHint) rc += " MSWindowsFixedSizeDialogHint";
+ if (iwf & Qt::MSWindowsOwnDC) rc += " MSWindowsOwnDC";
+ if (iwf & Qt::FramelessWindowHint) rc += " FramelessWindowHint";
+ if (iwf & Qt::WindowTitleHint) rc += " WindowTitleHint";
+ if (iwf & Qt::WindowSystemMenuHint) rc += " WindowSystemMenuHint";
+ if (iwf & Qt::WindowMinimizeButtonHint) rc += " WindowMinimizeButtonHint";
+ if (iwf & Qt::WindowMaximizeButtonHint) rc += " WindowMaximizeButtonHint";
+ if (iwf & Qt::WindowContextHelpButtonHint) rc += " WindowContextHelpButtonHint";
+ if (iwf & Qt::WindowShadeButtonHint) rc += " WindowShadeButtonHint";
+ if (iwf & Qt::WindowStaysOnTopHint) rc += " WindowStaysOnTopHint";
+ if (iwf & Qt::CustomizeWindowHint) rc += " CustomizeWindowHint";
+ if (iwf & Qt::WindowStaysOnBottomHint) rc += " WindowStaysOnBottomHint";
+ if (iwf & Qt::WindowCloseButtonHint) rc += " WindowCloseButtonHint";
+ rc += ']';
+ return rc;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h
new file mode 100644
index 0000000000..dfaeb2a86d
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowswindow.h
@@ -0,0 +1,284 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSWINDOW_H
+#define QWINDOWSWINDOW_H
+
+#include "qtwindows_additional.h"
+#include "qwindowscursor.h"
+
+#include <QtGui/QPlatformWindow>
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsOleDropTarget;
+class QDebug;
+
+struct QWindowsGeometryHint
+{
+ QWindowsGeometryHint() {}
+ explicit QWindowsGeometryHint(const QWindow *w);
+ static QMargins frame(DWORD style, DWORD exStyle);
+ void applyToMinMaxInfo(DWORD style, DWORD exStyle, MINMAXINFO *mmi) const;
+ void applyToMinMaxInfo(HWND hwnd, MINMAXINFO *mmi) const;
+ bool validSize(const QSize &s) const;
+
+ static inline QPoint mapToGlobal(HWND hwnd, const QPoint &);
+ static inline QPoint mapToGlobal(const QWindow *w, const QPoint &);
+ static inline QPoint mapFromGlobal(const HWND hwnd, const QPoint &);
+ static inline QPoint mapFromGlobal(const QWindow *w, const QPoint &);
+
+ QSize minimumSize;
+ QSize maximumSize;
+};
+
+struct QWindowCreationContext
+{
+ QWindowCreationContext(const QWindow *w, const QRect &r,
+ DWORD style, DWORD exStyle);
+
+ void applyToMinMaxInfo(MINMAXINFO *mmi) const
+ { geometryHint.applyToMinMaxInfo(style, exStyle, mmi); }
+
+ QWindowsGeometryHint geometryHint;
+ DWORD style;
+ DWORD exStyle;
+ QRect requestedGeometry;
+ QRect obtainedGeometry;
+ QMargins margins;
+ int frameX; // Passed on to CreateWindowEx(), including frame.
+ int frameY;
+ int frameWidth;
+ int frameHeight;
+};
+
+class QWindowsWindow : public QPlatformWindow
+{
+public:
+ enum Flags
+ {
+ OpenGL_Surface = 0x1,
+ WithinWmPaint = 0x2,
+ PixelFormatInitialized = 0x4,
+ FrameDirty = 0x8 //! Frame outdated by setStyle, recalculate in next query.
+ };
+
+ struct WindowData
+ {
+ WindowData() : hwnd(0) {}
+
+ Qt::WindowFlags flags;
+ QRect geometry;
+ QMargins frame; // Do not use directly for windows, see FrameDirty.
+ HWND hwnd;
+
+ static WindowData create(const QWindow *w,
+ const WindowData &parameters,
+ const QString &title,
+ bool isGL);
+ };
+
+ QWindowsWindow(QWindow *window, const WindowData &data);
+ ~QWindowsWindow();
+
+ virtual void setGeometry(const QRect &rect);
+ virtual QRect geometry() const { return m_data.geometry; }
+
+ virtual void setVisible(bool visible);
+ bool isVisible() const;
+ virtual Qt::WindowFlags setWindowFlags(Qt::WindowFlags flags);
+ virtual Qt::WindowState setWindowState(Qt::WindowState state);
+
+ HWND handle() const { return m_data.hwnd; }
+
+ virtual WId winId() const { return WId(m_data.hwnd); }
+ virtual void setParent(const QPlatformWindow *window);
+
+ virtual void setWindowTitle(const QString &title);
+ virtual void raise();
+ virtual void lower();
+
+ virtual void propagateSizeHints();
+ virtual QMargins frameMargins() const;
+
+ virtual void setOpacity(qreal level);
+ virtual void requestActivateWindow();
+
+ virtual bool setKeyboardGrabEnabled(bool grab);
+ virtual bool setMouseGrabEnabled(bool grab);
+
+ Qt::WindowState windowState_sys() const;
+ Qt::WindowStates windowStates_sys() const;
+
+ inline unsigned style() const
+ { return GetWindowLongPtr(m_data.hwnd, GWL_STYLE); }
+ void setStyle(unsigned s) const;
+ inline unsigned exStyle() const
+ { return GetWindowLongPtr(m_data.hwnd, GWL_EXSTYLE); }
+ void setExStyle(unsigned s) const;
+
+ void handleWmPaint(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
+
+ void handleMoved();
+ void handleResized(int wParam);
+ void handleShown();
+ void handleHidden();
+
+ static inline HWND handleOf(const QWindow *w);
+ static inline QWindowsWindow *baseWindowOf(const QWindow *w);
+ static QWindow *topLevelOf(QWindow *w);
+ static inline void *userDataOf(HWND hwnd);
+ static inline void setUserDataOf(HWND hwnd, void *ud);
+
+ HDC getDC();
+ void releaseDC();
+
+ void getSizeHints(MINMAXINFO *mmi) const;
+
+ QWindowsWindowCursor cursor() const { return m_cursor; }
+ void setCursor(const QWindowsWindowCursor &c);
+ void applyCursor();
+
+ QWindowsWindow *childAt(const QPoint &clientPoint,
+ unsigned cwexflags = CWP_SKIPINVISIBLE) const;
+ QWindowsWindow *childAtScreenPoint(const QPoint &screenPoint,
+ unsigned cwexflags = CWP_SKIPINVISIBLE) const;
+
+ static QByteArray debugWindowFlags(Qt::WindowFlags wf);
+
+ inline bool testFlag(unsigned f) const { return (m_flags & f) != 0; }
+ inline void setFlag(unsigned f) const { m_flags |= f; }
+ inline void clearFlag(unsigned f) const { m_flags &= ~f; }
+
+private:
+ inline void show_sys() const;
+ inline void hide_sys() const;
+ inline void setGeometry_sys(const QRect &rect) const;
+ inline QRect geometry_sys() const;
+ inline WindowData setWindowFlags_sys(Qt::WindowFlags wt) const;
+ inline void setWindowState_sys(Qt::WindowState newState);
+ inline void setParent_sys(const QPlatformWindow *parent) const;
+ inline void setOpacity_sys(qreal level) const;
+ inline void setMouseGrabEnabled_sys(bool grab);
+ void destroyWindow();
+ void registerDropSite();
+ void unregisterDropSite();
+ void handleGeometryChange();
+ void handleWindowStateChange(Qt::WindowState state);
+
+ mutable WindowData m_data;
+ mutable unsigned m_flags;
+ HDC m_hdc;
+ Qt::WindowState m_windowState;
+ qreal m_opacity;
+ bool m_mouseGrab;
+ QWindowsWindowCursor m_cursor;
+ QWindowsOleDropTarget *m_dropTarget;
+};
+
+// Conveniences for window frames.
+inline QRect operator+(const QRect &r, const QMargins &m)
+{
+ return r.adjusted(-m.left(), -m.top(), m.right(), m.bottom());
+}
+
+inline QRect operator-(const QRect &r, const QMargins &m)
+{
+ return r.adjusted(m.left(), m.top(), -m.right(), -m.bottom());
+}
+
+// Debug
+QDebug operator<<(QDebug d, const RECT &r);
+QDebug operator<<(QDebug d, const MINMAXINFO &i);
+QDebug operator<<(QDebug d, const NCCALCSIZE_PARAMS &p);
+
+// ---------- QWindowsGeometryHint inline functions.
+QPoint QWindowsGeometryHint::mapToGlobal(HWND hwnd, const QPoint &qp)
+{
+ POINT p = { qp.x(), qp.y() };
+ ClientToScreen(hwnd, &p);
+ return QPoint(p.x, p.y);
+}
+
+QPoint QWindowsGeometryHint::mapFromGlobal(const HWND hwnd, const QPoint &qp)
+{
+ POINT p = { qp.x(), qp.y() };
+ ScreenToClient(hwnd, &p);
+ return QPoint(p.x, p.y);
+}
+
+QPoint QWindowsGeometryHint::mapToGlobal(const QWindow *w, const QPoint &p)
+ { return QWindowsGeometryHint::mapToGlobal(QWindowsWindow::handleOf(w), p); }
+
+QPoint QWindowsGeometryHint::mapFromGlobal(const QWindow *w, const QPoint &p)
+ { return QWindowsGeometryHint::mapFromGlobal(QWindowsWindow::handleOf(w), p); }
+
+
+// ---------- QWindowsBaseWindow inline functions.
+
+QWindowsWindow *QWindowsWindow::baseWindowOf(const QWindow *w)
+{
+ if (w)
+ if (QPlatformWindow *pw = w->handle())
+ return static_cast<QWindowsWindow *>(pw);
+ return 0;
+}
+
+HWND QWindowsWindow::handleOf(const QWindow *w)
+{
+ if (const QWindowsWindow *bw = QWindowsWindow::baseWindowOf(w))
+ return bw->handle();
+ return 0;
+}
+
+void *QWindowsWindow::userDataOf(HWND hwnd)
+{
+ return (void *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
+}
+
+void QWindowsWindow::setUserDataOf(HWND hwnd, void *ud)
+{
+ SetWindowLongPtr(hwnd, GWLP_USERDATA, LONG_PTR(ud));
+}
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSWINDOW_H
diff --git a/src/plugins/platforms/windows/windows.pro b/src/plugins/platforms/windows/windows.pro
new file mode 100644
index 0000000000..e5627ae574
--- /dev/null
+++ b/src/plugins/platforms/windows/windows.pro
@@ -0,0 +1,70 @@
+TARGET = windows
+load(qt_plugin)
+
+QT *= core-private
+QT *= gui-private
+
+INCLUDEPATH += ../../../3rdparty/harfbuzz/src
+QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/platforms
+
+# Note: OpenGL32 must precede Gdi32 as it overwrites some functions.
+LIBS *= -lOpenGL32 -lGdi32 -lUser32 -lOle32 -lWinspool -lImm32
+win32-g++: LIBS *= -luuid
+
+contains(QT_CONFIG, directwrite) {
+ LIBS *= -ldwrite
+ SOURCES += qwindowsfontenginedirectwrite.cpp
+ HEADERS += qwindowsfontenginedirectwrite.h
+} else {
+ DEFINES *= QT_NO_DIRECTWRITE
+}
+
+SOURCES += \
+ main.cpp \
+ qwindowsnativeimage.cpp \
+ qwindowswindow.cpp \
+ qwindowsintegration.cpp \
+ qwindowscontext.cpp \
+ qwindowsbackingstore.cpp \
+ qwindowsscreen.cpp \
+ qwindowskeymapper.cpp \
+ qwindowsfontengine.cpp \
+ qwindowsfontdatabase.cpp \
+ qwindowsmousehandler.cpp \
+ qwindowsguieventdispatcher.cpp \
+ qwindowsglcontext.cpp \
+ qwindowsclipboard.cpp \
+ qwindowsole.cpp \
+ qwindowsmime.cpp \
+ qwindowsdrag.cpp \
+ qwindowscursor.cpp \
+ pixmaputils.cpp \
+ qwindowsinputcontext.cpp
+
+HEADERS += \
+ qwindowsnativeimage.h \
+ qwindowswindow.h \
+ qwindowsintegration.h \
+ qwindowscontext.h \
+ qwindowsbackingstore.h \
+ qwindowsscreen.h \
+ qwindowskeymapper.h \
+ qwindowsfontengine.h \
+ qwindowsfontdatabase.h \
+ qwindowsmousehandler.h \
+ qwindowsguieventdispatcher.h \
+ qtwindowsglobal.h \
+ qtwindows_additional.h \
+ qwindowsglcontext.h \
+ qwindowsclipboard.h \
+ qwindowsole.h \
+ qwindowsmime.h \
+ qwindowsdrag.h \
+ qwindowsinternalmimedata.h \
+ qwindowscursor.h \
+ pixmaputils.h \
+ array.h \
+ qwindowsinputcontext.h
+
+target.path += $$[QT_INSTALL_PLUGINS]/platforms
+INSTALLS += target
diff --git a/src/plugins/platforms/xcb/README b/src/plugins/platforms/xcb/README
index 17a86e6d08..d2884f109c 100644
--- a/src/plugins/platforms/xcb/README
+++ b/src/plugins/platforms/xcb/README
@@ -1,3 +1,3 @@
Required packages:
-libxcb1 libxcb1-dev libx11-xcb1 libx11-xcb-dev libxcb-keysyms1 libxcb-keysyms1-dev libxcb-image0 libxcb-image0-dev libxcb-shm0 libxcb-shm0-dev libxcb-icccm1 libxcb-icccm1-dev libxcb-sync0 libxcb-sync0-dev
+libxcb1 libxcb1-dev libx11-xcb1 libx11-xcb-dev libxcb-keysyms1 libxcb-keysyms1-dev libxcb-image0 libxcb-image0-dev libxcb-shm0 libxcb-shm0-dev libxcb-icccm1 libxcb-icccm1-dev libxcb-sync0 libxcb-sync0-dev libxcb-render-util0 libxcb-render-util0-dev libxcb-xfixes0-dev
diff --git a/src/plugins/platforms/xcb/main.cpp b/src/plugins/platforms/xcb/main.cpp
index 7fee7455be..c544f7073d 100644
--- a/src/plugins/platforms/xcb/main.cpp
+++ b/src/plugins/platforms/xcb/main.cpp
@@ -58,11 +58,10 @@ QStringList QXcbIntegrationPlugin::keys() const
return list;
}
-QPlatformIntegration* QXcbIntegrationPlugin::create(const QString& system, const QStringList& paramList)
+QPlatformIntegration* QXcbIntegrationPlugin::create(const QString& system, const QStringList& parameters)
{
- Q_UNUSED(paramList);
if (system.toLower() == "xcb")
- return new QXcbIntegration;
+ return new QXcbIntegration(parameters);
return 0;
}
diff --git a/src/plugins/platforms/xcb/qdri2context.cpp b/src/plugins/platforms/xcb/qdri2context.cpp
index 8bcdacb92b..5f4aff5455 100644
--- a/src/plugins/platforms/xcb/qdri2context.cpp
+++ b/src/plugins/platforms/xcb/qdri2context.cpp
@@ -45,7 +45,7 @@
#include "qxcbconnection.h"
#include <QtCore/QDebug>
-#include <QtGui/QWidget>
+#include <QtWidgets/QWidget>
#include <xcb/dri2.h>
#include <xcb/xfixes.h>
@@ -134,9 +134,9 @@ QDri2Context::QDri2Context(QXcbWindow *window)
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERER,d->depth);
//restore the old current context
- const QPlatformGLContext *currentContext = QPlatformGLContext::currentContext();
+ const QPlatformOpenGLContext *currentContext = QPlatformOpenGLContext::currentContext();
if (currentContext)
- const_cast<QPlatformGLContext*>(currentContext)->makeCurrent();
+ const_cast<QPlatformOpenGLContext*>(currentContext)->makeCurrent();
}
QDri2Context::~QDri2Context()
@@ -146,7 +146,6 @@ QDri2Context::~QDri2Context()
void QDri2Context::makeCurrent()
{
- QPlatformGLContext::makeCurrent();
Q_D(QDri2Context);
eglMakeCurrent(EGL_DISPLAY_FROM_XCB(d->qXcbWindow),EGL_NO_SURFACE,EGL_NO_SURFACE,d->eglContext);
@@ -156,7 +155,6 @@ void QDri2Context::makeCurrent()
void QDri2Context::doneCurrent()
{
- QPlatformGLContext::doneCurrent();
Q_D(QDri2Context);
eglMakeCurrent(EGL_DISPLAY_FROM_XCB(d->qXcbWindow),EGL_NO_SURFACE,EGL_NO_SURFACE,EGL_NO_CONTEXT);
}
diff --git a/src/plugins/platforms/xcb/qdri2context.h b/src/plugins/platforms/xcb/qdri2context.h
index be7d637643..ec8b251c3f 100644
--- a/src/plugins/platforms/xcb/qdri2context.h
+++ b/src/plugins/platforms/xcb/qdri2context.h
@@ -42,14 +42,14 @@
#ifndef QDRI2CONTEXT_H
#define QDRI2CONTEXT_H
-#include <QtGui/QPlatformGLContext>
+#include <QtGui/QPlatformOpenGLContext>
class QXcbWindow;
class QDri2ContextPrivate;
struct xcb_dri2_dri2_buffer_t;
-class QDri2Context : public QPlatformGLContext
+class QDri2Context : public QPlatformOpenGLContext
{
Q_DECLARE_PRIVATE(QDri2Context);
public:
diff --git a/src/plugins/platforms/xcb/qglxintegration.cpp b/src/plugins/platforms/xcb/qglxintegration.cpp
index 8e04cbcb71..41bceaf406 100644
--- a/src/plugins/platforms/xcb/qglxintegration.cpp
+++ b/src/plugins/platforms/xcb/qglxintegration.cpp
@@ -41,7 +41,6 @@
#include <QDebug>
#include <QLibrary>
-#include <QGLFormat>
#include "qxcbwindow.h"
#include "qxcbscreen.h"
@@ -50,72 +49,56 @@
#include <X11/Xutil.h>
#include <GL/glx.h>
+#include <QtGui/QOpenGLContext>
+
#include "qglxintegration.h"
-#include "qglxconvenience.h"
+#include <QtPlatformSupport/private/qglxconvenience_p.h>
#if defined(Q_OS_LINUX) || defined(Q_OS_BSD4)
#include <dlfcn.h>
#endif
-QGLXContext::QGLXContext(Window window, QXcbScreen *screen, const QPlatformWindowFormat &format)
- : QPlatformGLContext()
+QGLXContext::QGLXContext(QXcbScreen *screen, const QSurfaceFormat &format, QPlatformOpenGLContext *share)
+ : QPlatformOpenGLContext()
, m_screen(screen)
- , m_drawable((Drawable)window)
, m_context(0)
{
- Q_XCB_NOOP(m_screen->connection());
- const QPlatformGLContext *sharePlatformContext;
- sharePlatformContext = format.sharedGLContext();
GLXContext shareGlxContext = 0;
- if (sharePlatformContext)
- shareGlxContext = static_cast<const QGLXContext*>(sharePlatformContext)->glxContext();
+ if (share)
+ shareGlxContext = static_cast<const QGLXContext*>(share)->glxContext();
GLXFBConfig config = qglx_findConfig(DISPLAY_FROM_XCB(screen),screen->screenNumber(),format);
m_context = glXCreateNewContext(DISPLAY_FROM_XCB(screen), config, GLX_RGBA_TYPE, shareGlxContext, TRUE);
- m_windowFormat = qglx_platformWindowFromGLXFBConfig(DISPLAY_FROM_XCB(screen), config, m_context);
- Q_XCB_NOOP(m_screen->connection());
-}
-
-QGLXContext::QGLXContext(QXcbScreen *screen, Drawable drawable, GLXContext context)
- : QPlatformGLContext(), m_screen(screen), m_drawable(drawable), m_context(context)
-{
-
+ m_format = qglx_surfaceFormatFromGLXFBConfig(DISPLAY_FROM_XCB(screen), config, m_context);
}
QGLXContext::~QGLXContext()
{
- Q_XCB_NOOP(m_screen->connection());
- if (m_context)
- glXDestroyContext(DISPLAY_FROM_XCB(m_screen), m_context);
- Q_XCB_NOOP(m_screen->connection());
+ glXDestroyContext(DISPLAY_FROM_XCB(m_screen), m_context);
}
-void QGLXContext::makeCurrent()
+bool QGLXContext::makeCurrent(QPlatformSurface *surface)
{
- Q_XCB_NOOP(m_screen->connection());
- QPlatformGLContext::makeCurrent();
- glXMakeCurrent(DISPLAY_FROM_XCB(m_screen), m_drawable, m_context);
- Q_XCB_NOOP(m_screen->connection());
+ Q_ASSERT(surface);
+
+ GLXDrawable glxDrawable = static_cast<QXcbWindow *>(surface)->xcb_window();
+
+ return glXMakeCurrent(DISPLAY_FROM_XCB(m_screen), glxDrawable, m_context);
}
void QGLXContext::doneCurrent()
{
- Q_XCB_NOOP(m_screen->connection());
- QPlatformGLContext::doneCurrent();
glXMakeCurrent(DISPLAY_FROM_XCB(m_screen), 0, 0);
- Q_XCB_NOOP(m_screen->connection());
}
-void QGLXContext::swapBuffers()
+void QGLXContext::swapBuffers(QPlatformSurface *surface)
{
- Q_XCB_NOOP(m_screen->connection());
- glXSwapBuffers(DISPLAY_FROM_XCB(m_screen), m_drawable);
- Q_XCB_NOOP(m_screen->connection());
+ GLXDrawable glxDrawable = static_cast<QXcbWindow *>(surface)->xcb_window();
+ glXSwapBuffers(DISPLAY_FROM_XCB(m_screen), glxDrawable);
}
-void* QGLXContext::getProcAddress(const QString& procName)
+void (*QGLXContext::getProcAddress(const QByteArray &procName)) ()
{
- Q_XCB_NOOP(m_screen->connection());
typedef void *(*qt_glXGetProcAddressARB)(const GLubyte *);
static qt_glXGetProcAddressARB glXGetProcAddressARB = 0;
static bool resolved = false;
@@ -144,10 +127,10 @@ void* QGLXContext::getProcAddress(const QString& procName)
}
if (!glXGetProcAddressARB)
return 0;
- return glXGetProcAddressARB(reinterpret_cast<const GLubyte *>(procName.toLatin1().data()));
+ return (void (*)())glXGetProcAddressARB(reinterpret_cast<const GLubyte *>(procName.constData()));
}
-QPlatformWindowFormat QGLXContext::platformWindowFormat() const
+QSurfaceFormat QGLXContext::format() const
{
- return m_windowFormat;
+ return m_format;
}
diff --git a/src/plugins/platforms/xcb/qglxintegration.h b/src/plugins/platforms/xcb/qglxintegration.h
index 84de7b7143..bbe67b653a 100644
--- a/src/plugins/platforms/xcb/qglxintegration.h
+++ b/src/plugins/platforms/xcb/qglxintegration.h
@@ -43,36 +43,34 @@
#define QGLXINTEGRATION_H
#include "qxcbwindow.h"
+#include "qxcbscreen.h"
-#include <QtGui/QPlatformGLContext>
-#include <QtGui/QPlatformWindowFormat>
+#include <QtGui/QPlatformOpenGLContext>
+#include <QtGui/QSurfaceFormat>
#include <QtCore/QMutex>
#include <GL/glx.h>
-class QGLXContext : public QPlatformGLContext
+class QGLXContext : public QPlatformOpenGLContext
{
public:
- QGLXContext(Window window, QXcbScreen *xd, const QPlatformWindowFormat &format);
+ QGLXContext(QXcbScreen *xd, const QSurfaceFormat &format, QPlatformOpenGLContext *share);
~QGLXContext();
- virtual void makeCurrent();
- virtual void doneCurrent();
- virtual void swapBuffers();
- virtual void* getProcAddress(const QString& procName);
+ bool makeCurrent(QPlatformSurface *surface);
+ void doneCurrent();
+ void swapBuffers(QPlatformSurface *surface);
+ void (*getProcAddress(const QByteArray &procName)) ();
- GLXContext glxContext() const { return m_context; }
+ QSurfaceFormat format() const;
- QPlatformWindowFormat platformWindowFormat() const;
+ GLXContext glxContext() const { return m_context; }
private:
QXcbScreen *m_screen;
- Drawable m_drawable;
GLXContext m_context;
- QPlatformWindowFormat m_windowFormat;
-
- QGLXContext (QXcbScreen *screen, Drawable drawable, GLXContext context);
+ QSurfaceFormat m_format;
};
#endif
diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.cpp b/src/plugins/platforms/xcb/qxcbbackingstore.cpp
new file mode 100644
index 0000000000..fadcb4d5b8
--- /dev/null
+++ b/src/plugins/platforms/xcb/qxcbbackingstore.cpp
@@ -0,0 +1,309 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxcbbackingstore.h"
+
+#include "qxcbconnection.h"
+#include "qxcbscreen.h"
+#include "qxcbwindow.h"
+
+#include <xcb/shm.h>
+#include <xcb/xcb_image.h>
+
+#include <sys/ipc.h>
+#include <sys/shm.h>
+
+#include <stdio.h>
+#include <errno.h>
+
+#include <qdebug.h>
+#include <qpainter.h>
+#include <qscreen.h>
+
+class QXcbShmImage : public QXcbObject
+{
+public:
+ QXcbShmImage(QXcbScreen *connection, const QSize &size, uint depth, QImage::Format format);
+ ~QXcbShmImage() { destroy(); }
+
+ QImage *image() { return &m_qimage; }
+ QSize size() const { return m_qimage.size(); }
+
+ void put(xcb_window_t window, const QPoint &dst, const QRect &source);
+ void preparePaint(const QRegion &region);
+
+private:
+ void destroy();
+
+ xcb_shm_segment_info_t m_shm_info;
+
+ xcb_image_t *m_xcb_image;
+
+ QImage m_qimage;
+
+ xcb_gcontext_t m_gc;
+ xcb_window_t m_gc_window;
+
+ QRegion m_dirty;
+};
+
+QXcbShmImage::QXcbShmImage(QXcbScreen *screen, const QSize &size, uint depth, QImage::Format format)
+ : QXcbObject(screen->connection())
+ , m_gc(0)
+ , m_gc_window(0)
+{
+ Q_XCB_NOOP(connection());
+ m_xcb_image = xcb_image_create_native(xcb_connection(),
+ size.width(),
+ size.height(),
+ XCB_IMAGE_FORMAT_Z_PIXMAP,
+ depth,
+ 0,
+ ~0,
+ 0);
+
+ const int segmentSize = m_xcb_image->stride * m_xcb_image->height;
+ if (!segmentSize)
+ return;
+
+ int id = shmget(IPC_PRIVATE, segmentSize, IPC_CREAT | 0777);
+ if (id == -1)
+ qWarning("QXcbShmImage: shmget() failed (%d) for size %d (%dx%d)",
+ errno, segmentSize, size.width(), size.height());
+ else
+ m_shm_info.shmid = id;
+ m_shm_info.shmaddr = m_xcb_image->data = (quint8 *)shmat (m_shm_info.shmid, 0, 0);
+ m_shm_info.shmseg = xcb_generate_id(xcb_connection());
+
+ xcb_generic_error_t *error = xcb_request_check(xcb_connection(), xcb_shm_attach_checked(xcb_connection(), m_shm_info.shmseg, m_shm_info.shmid, false));
+ if (error) {
+ free(error);
+
+ shmdt(m_shm_info.shmaddr);
+ shmctl(m_shm_info.shmid, IPC_RMID, 0);
+
+ m_shm_info.shmaddr = 0;
+
+ m_xcb_image->data = (uint8_t *)qMalloc(segmentSize);
+ } else {
+ if (shmctl(m_shm_info.shmid, IPC_RMID, 0) == -1)
+ qWarning() << "QXcbBackingStore: Error while marking the shared memory segment to be destroyed";
+ }
+
+ m_qimage = QImage( (uchar*) m_xcb_image->data, m_xcb_image->width, m_xcb_image->height, m_xcb_image->stride, format);
+}
+
+void QXcbShmImage::destroy()
+{
+ const int segmentSize = m_xcb_image ? (m_xcb_image->stride * m_xcb_image->height) : 0;
+ if (segmentSize && m_shm_info.shmaddr)
+ Q_XCB_CALL(xcb_shm_detach(xcb_connection(), m_shm_info.shmseg));
+
+ xcb_image_destroy(m_xcb_image);
+
+ if (segmentSize) {
+ if (m_shm_info.shmaddr) {
+ shmdt(m_shm_info.shmaddr);
+ shmctl(m_shm_info.shmid, IPC_RMID, 0);
+ } else {
+ qFree(m_xcb_image->data);
+ }
+ }
+
+ if (m_gc)
+ Q_XCB_CALL(xcb_free_gc(xcb_connection(), m_gc));
+}
+
+void QXcbShmImage::put(xcb_window_t window, const QPoint &target, const QRect &source)
+{
+ Q_XCB_NOOP(connection());
+ if (m_gc_window != window) {
+ if (m_gc)
+ Q_XCB_CALL(xcb_free_gc(xcb_connection(), m_gc));
+
+ m_gc = xcb_generate_id(xcb_connection());
+ Q_XCB_CALL(xcb_create_gc(xcb_connection(), m_gc, window, 0, 0));
+
+ m_gc_window = window;
+ }
+
+ Q_XCB_NOOP(connection());
+ if (m_shm_info.shmaddr) {
+ xcb_image_shm_put(xcb_connection(),
+ window,
+ m_gc,
+ m_xcb_image,
+ m_shm_info,
+ source.x(),
+ source.y(),
+ target.x(),
+ target.y(),
+ source.width(),
+ source.height(),
+ false);
+ } else {
+ xcb_image_t *subimage = xcb_image_subimage(m_xcb_image, source.x(), source.y(), source.width(), source.height(),
+ 0, 0, 0);
+ xcb_image_put(xcb_connection(),
+ window,
+ m_gc,
+ subimage,
+ target.x(),
+ target.y(),
+ 0);
+
+ xcb_image_destroy(subimage);
+ }
+ Q_XCB_NOOP(connection());
+
+ m_dirty = m_dirty | source;
+
+ xcb_flush(xcb_connection());
+ Q_XCB_NOOP(connection());
+}
+
+void QXcbShmImage::preparePaint(const QRegion &region)
+{
+ // to prevent X from reading from the image region while we're writing to it
+ if (m_dirty.intersects(region)) {
+ connection()->sync();
+ m_dirty = QRegion();
+ }
+}
+
+QXcbBackingStore::QXcbBackingStore(QWindow *window)
+ : QPlatformBackingStore(window)
+ , m_image(0)
+ , m_syncingResize(false)
+{
+ QXcbScreen *screen = static_cast<QXcbScreen *>(window->screen()->handle());
+ setConnection(screen->connection());
+}
+
+QXcbBackingStore::~QXcbBackingStore()
+{
+ delete m_image;
+}
+
+QPaintDevice *QXcbBackingStore::paintDevice()
+{
+ return m_image->image();
+}
+
+void QXcbBackingStore::beginPaint(const QRegion &region)
+{
+ m_image->preparePaint(region);
+
+#if 0
+ if (m_image->image()->hasAlphaChannel()) {
+ QPainter p(m_image->image());
+ p.setCompositionMode(QPainter::CompositionMode_Source);
+ const QVector<QRect> rects = region.rects();
+ const QColor blank = Qt::transparent;
+ for (QVector<QRect>::const_iterator it = rects.begin(); it != rects.end(); ++it) {
+ p.fillRect(*it, blank);
+ }
+ }
+#endif
+}
+
+void QXcbBackingStore::endPaint(const QRegion &)
+{
+}
+
+void QXcbBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
+{
+ QRect bounds = region.boundingRect();
+
+ if (!m_image || m_image->size().isEmpty())
+ return;
+
+ Q_XCB_NOOP(connection());
+
+ QXcbWindow *platformWindow = static_cast<QXcbWindow *>(window->handle());
+
+ QVector<QRect> rects = region.rects();
+ for (int i = 0; i < rects.size(); ++i)
+ m_image->put(platformWindow->xcb_window(), rects.at(i).topLeft(), rects.at(i).translated(offset));
+
+ Q_XCB_NOOP(connection());
+
+ if (m_syncingResize) {
+ xcb_flush(xcb_connection());
+ connection()->sync();
+ m_syncingResize = false;
+ platformWindow->updateSyncRequestCounter();
+ }
+}
+
+void QXcbBackingStore::resize(const QSize &size, const QRegion &)
+{
+ if (m_image && size == m_image->size())
+ return;
+
+ Q_XCB_NOOP(connection());
+
+ QXcbScreen *screen = static_cast<QXcbScreen *>(window()->screen()->handle());
+ QXcbWindow* win = static_cast<QXcbWindow *>(window()->handle());
+
+ delete m_image;
+ m_image = new QXcbShmImage(screen, size, win->depth(), win->imageFormat());
+ Q_XCB_NOOP(connection());
+
+ m_syncingResize = true;
+}
+
+extern void qt_scrollRectInImage(QImage &img, const QRect &rect, const QPoint &offset);
+
+bool QXcbBackingStore::scroll(const QRegion &area, int dx, int dy)
+{
+ if (!m_image || m_image->image()->isNull())
+ return false;
+
+ m_image->preparePaint(area);
+
+ const QVector<QRect> rects = area.rects();
+ for (int i = 0; i < rects.size(); ++i)
+ qt_scrollRectInImage(*m_image->image(), rects.at(i), QPoint(dx, dy));
+
+ return true;
+}
+
diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.h b/src/plugins/platforms/xcb/qxcbbackingstore.h
new file mode 100644
index 0000000000..db94d26b09
--- /dev/null
+++ b/src/plugins/platforms/xcb/qxcbbackingstore.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QXCBBACKINGSTORE_H
+#define QXCBBACKINGSTORE_H
+
+#include <qplatformbackingstore_qpa.h>
+
+#include <xcb/xcb.h>
+
+#include "qxcbobject.h"
+
+class QXcbShmImage;
+
+class QXcbBackingStore : public QXcbObject, public QPlatformBackingStore
+{
+public:
+ QXcbBackingStore(QWindow *widget);
+ ~QXcbBackingStore();
+
+ QPaintDevice *paintDevice();
+ void flush(QWindow *window, const QRegion &region, const QPoint &offset);
+ void resize(const QSize &size, const QRegion &staticContents);
+ bool scroll(const QRegion &area, int dx, int dy);
+
+ void beginPaint(const QRegion &);
+ void endPaint(const QRegion &);
+
+private:
+ QXcbShmImage *m_image;
+ bool m_syncingResize;
+};
+
+#endif
diff --git a/src/plugins/platforms/xcb/qxcbclipboard.cpp b/src/plugins/platforms/xcb/qxcbclipboard.cpp
new file mode 100644
index 0000000000..550b8cbd73
--- /dev/null
+++ b/src/plugins/platforms/xcb/qxcbclipboard.cpp
@@ -0,0 +1,848 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxcbclipboard.h"
+
+#include "qxcbconnection.h"
+#include "qxcbscreen.h"
+#include "qxcbmime.h"
+
+#include <private/qguiapplication_p.h>
+#include <QElapsedTimer>
+
+#include <QtCore/QDebug>
+
+#include <xcb/xcb_icccm.h>
+
+class QXcbClipboardMime : public QXcbMime
+{
+ Q_OBJECT
+public:
+ QXcbClipboardMime(QClipboard::Mode mode, QXcbClipboard *clipboard)
+ : QXcbMime()
+ , m_clipboard(clipboard)
+ {
+ switch (mode) {
+ case QClipboard::Selection:
+ modeAtom = XCB_ATOM_PRIMARY;
+ break;
+
+ case QClipboard::Clipboard:
+ modeAtom = m_clipboard->atom(QXcbAtom::CLIPBOARD);
+ break;
+
+ default:
+ qWarning("QTestLiteMime: Internal error: Unsupported clipboard mode");
+ break;
+ }
+ }
+
+protected:
+ QStringList formats_sys() const
+ {
+ if (empty())
+ return QStringList();
+
+ if (!formatList.count()) {
+ QXcbClipboardMime *that = const_cast<QXcbClipboardMime *>(this);
+ // get the list of targets from the current clipboard owner - we do this
+ // once so that multiple calls to this function don't require multiple
+ // server round trips...
+ that->format_atoms = m_clipboard->getDataInFormat(modeAtom, m_clipboard->atom(QXcbAtom::TARGETS));
+
+ if (format_atoms.size() > 0) {
+ xcb_atom_t *targets = (xcb_atom_t *) format_atoms.data();
+ int size = format_atoms.size() / sizeof(xcb_atom_t);
+
+ for (int i = 0; i < size; ++i) {
+ if (targets[i] == 0)
+ continue;
+
+ QString format = mimeAtomToString(m_clipboard->connection(), targets[i]);
+ if (!formatList.contains(format))
+ that->formatList.append(format);
+ }
+ }
+ }
+
+ return formatList;
+ }
+
+ bool hasFormat_sys(const QString &format) const
+ {
+ QStringList list = formats();
+ return list.contains(format);
+ }
+
+ QVariant retrieveData_sys(const QString &fmt, QVariant::Type requestedType) const
+ {
+ if (fmt.isEmpty() || empty())
+ return QByteArray();
+
+ (void)formats(); // trigger update of format list
+
+ QList<xcb_atom_t> atoms;
+ xcb_atom_t *targets = (xcb_atom_t *) format_atoms.data();
+ int size = format_atoms.size() / sizeof(xcb_atom_t);
+ for (int i = 0; i < size; ++i)
+ atoms.append(targets[i]);
+
+ QByteArray encoding;
+ xcb_atom_t fmtatom = mimeAtomForFormat(m_clipboard->connection(), fmt, requestedType, atoms, &encoding);
+
+ if (fmtatom == 0)
+ return QVariant();
+
+ return mimeConvertToFormat(m_clipboard->connection(), fmtatom, m_clipboard->getDataInFormat(modeAtom, fmtatom), fmt, requestedType, encoding);
+ }
+private:
+ bool empty() const
+ {
+ return m_clipboard->getSelectionOwner(modeAtom) == XCB_NONE;
+ }
+
+
+ xcb_atom_t modeAtom;
+ QXcbClipboard *m_clipboard;
+ QStringList formatList;
+ QByteArray format_atoms;
+};
+
+const int QXcbClipboard::clipboard_timeout = 5000;
+
+QXcbClipboard::QXcbClipboard(QXcbConnection *c)
+ : QXcbObject(c), QPlatformClipboard()
+ , m_requestor(XCB_NONE)
+ , m_owner(XCB_NONE)
+{
+ Q_ASSERT(QClipboard::Clipboard == 0);
+ Q_ASSERT(QClipboard::Selection == 1);
+ m_xClipboard[QClipboard::Clipboard] = 0;
+ m_xClipboard[QClipboard::Selection] = 0;
+ m_clientClipboard[QClipboard::Clipboard] = 0;
+ m_clientClipboard[QClipboard::Selection] = 0;
+ m_timestamp[QClipboard::Clipboard] = XCB_CURRENT_TIME;
+ m_timestamp[QClipboard::Selection] = XCB_CURRENT_TIME;
+
+ m_screen = connection()->screens().at(connection()->primaryScreen());
+
+ int x = 0, y = 0, w = 3, h = 3;
+
+ m_owner = xcb_generate_id(xcb_connection());
+ Q_XCB_CALL(xcb_create_window(xcb_connection(),
+ XCB_COPY_FROM_PARENT, // depth -- same as root
+ m_owner, // window id
+ m_screen->screen()->root, // parent window id
+ x, y, w, h,
+ 0, // border width
+ XCB_WINDOW_CLASS_INPUT_OUTPUT, // window class
+ m_screen->screen()->root_visual, // visual
+ 0, // value mask
+ 0)); // value list
+
+ if (connection()->hasXFixes()) {
+ const uint32_t mask = XCB_XFIXES_SELECTION_EVENT_MASK_SET_SELECTION_OWNER |
+ XCB_XFIXES_SELECTION_EVENT_MASK_SELECTION_WINDOW_DESTROY |
+ XCB_XFIXES_SELECTION_EVENT_MASK_SELECTION_CLIENT_CLOSE;
+ Q_XCB_CALL(xcb_xfixes_select_selection_input_checked(xcb_connection(), m_owner, XCB_ATOM_PRIMARY, mask));
+ Q_XCB_CALL(xcb_xfixes_select_selection_input_checked(xcb_connection(), m_owner, atom(QXcbAtom::CLIPBOARD), mask));
+ }
+}
+
+QXcbClipboard::~QXcbClipboard()
+{
+ // Transfer the clipboard content to the clipboard manager if we own a selection
+ if (m_timestamp[QClipboard::Clipboard] != XCB_CURRENT_TIME ||
+ m_timestamp[QClipboard::Selection] != XCB_CURRENT_TIME) {
+
+ // First we check if there is a clipboard manager.
+ xcb_get_selection_owner_cookie_t cookie = xcb_get_selection_owner(xcb_connection(), atom(QXcbAtom::CLIPBOARD_MANAGER));
+ xcb_get_selection_owner_reply_t *reply = xcb_get_selection_owner_reply(xcb_connection(), cookie, 0);
+ if (reply && reply->owner != XCB_NONE) {
+ // we delete the property so the manager saves all TARGETS.
+ xcb_delete_property(xcb_connection(), m_owner, atom(QXcbAtom::_QT_SELECTION));
+ xcb_convert_selection(xcb_connection(), m_owner, atom(QXcbAtom::CLIPBOARD_MANAGER), atom(QXcbAtom::SAVE_TARGETS),
+ atom(QXcbAtom::_QT_SELECTION), connection()->time());
+ connection()->sync();
+
+ // waiting until the clipboard manager fetches the content.
+ if (!waitForClipboardEvent(m_owner, XCB_SELECTION_NOTIFY, 5000)) {
+ qWarning("QClipboard: Unable to receive an event from the "
+ "clipboard manager in a reasonable time");
+ }
+ }
+ }
+}
+
+
+xcb_window_t QXcbClipboard::getSelectionOwner(xcb_atom_t atom) const
+{
+ xcb_connection_t *c = xcb_connection();
+ xcb_get_selection_owner_cookie_t cookie = xcb_get_selection_owner(c, atom);
+ xcb_get_selection_owner_reply_t *reply;
+ reply = xcb_get_selection_owner_reply(c, cookie, 0);
+ xcb_window_t win = reply->owner;
+ free(reply);
+ return win;
+}
+
+xcb_atom_t QXcbClipboard::atomForMode(QClipboard::Mode mode) const
+{
+ if (mode == QClipboard::Clipboard)
+ return atom(QXcbAtom::CLIPBOARD);
+ if (mode == QClipboard::Selection)
+ return XCB_ATOM_PRIMARY;
+ return XCB_NONE;
+}
+
+QClipboard::Mode QXcbClipboard::modeForAtom(xcb_atom_t a) const
+{
+ if (a == XCB_ATOM_PRIMARY)
+ return QClipboard::Selection;
+ if (a == atom(QXcbAtom::CLIPBOARD))
+ return QClipboard::Clipboard;
+ // not supported enum value, used to detect errors
+ return QClipboard::FindBuffer;
+}
+
+
+QMimeData * QXcbClipboard::mimeData(QClipboard::Mode mode)
+{
+ if (mode > QClipboard::Selection)
+ return 0;
+
+ xcb_window_t clipboardOwner = getSelectionOwner(atomForMode(mode));
+ if (clipboardOwner == owner()) {
+ return m_clientClipboard[mode];
+ } else {
+ if (!m_xClipboard[mode])
+ m_xClipboard[mode] = new QXcbClipboardMime(mode, this);
+
+ return m_xClipboard[mode];
+ }
+}
+
+void QXcbClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode)
+{
+ if (mode > QClipboard::Selection)
+ return;
+
+ xcb_atom_t modeAtom = atomForMode(mode);
+
+ if (m_clientClipboard[mode] == data)
+ return;
+
+ xcb_window_t newOwner = XCB_NONE;
+
+ if (m_clientClipboard[QClipboard::Clipboard] != m_clientClipboard[QClipboard::Selection])
+ delete m_clientClipboard[mode];
+ m_clientClipboard[mode] = 0;
+ m_timestamp[mode] = XCB_CURRENT_TIME;
+
+ if (data) {
+ newOwner = owner();
+
+ m_clientClipboard[mode] = data;
+ m_timestamp[mode] = connection()->time();
+ }
+
+ xcb_set_selection_owner(xcb_connection(), newOwner, modeAtom, connection()->time());
+
+ if (getSelectionOwner(modeAtom) != newOwner) {
+ qWarning("QClipboard::setData: Cannot set X11 selection owner");
+ }
+
+}
+
+bool QXcbClipboard::supportsMode(QClipboard::Mode mode) const
+{
+ if (mode <= QClipboard::Selection)
+ return true;
+ return false;
+}
+
+bool QXcbClipboard::ownsMode(QClipboard::Mode mode) const
+{
+ if (m_owner == XCB_NONE || mode > QClipboard::Selection)
+ return false;
+
+ Q_ASSERT(m_timestamp[mode] == XCB_CURRENT_TIME || getSelectionOwner(atomForMode(mode)) == m_owner);
+
+ return m_timestamp[mode] != XCB_CURRENT_TIME;
+}
+
+xcb_window_t QXcbClipboard::requestor() const
+{
+ if (!m_requestor) {
+ const int x = 0, y = 0, w = 3, h = 3;
+ QXcbClipboard *that = const_cast<QXcbClipboard *>(this);
+
+ xcb_window_t window = xcb_generate_id(xcb_connection());
+ Q_XCB_CALL(xcb_create_window(xcb_connection(),
+ XCB_COPY_FROM_PARENT, // depth -- same as root
+ window, // window id
+ m_screen->screen()->root, // parent window id
+ x, y, w, h,
+ 0, // border width
+ XCB_WINDOW_CLASS_INPUT_OUTPUT, // window class
+ m_screen->screen()->root_visual, // visual
+ 0, // value mask
+ 0)); // value list
+
+ uint32_t mask = XCB_EVENT_MASK_PROPERTY_CHANGE;
+ xcb_change_window_attributes(xcb_connection(), window, XCB_CW_EVENT_MASK, &mask);
+
+ that->setRequestor(window);
+ }
+ return m_requestor;
+}
+
+void QXcbClipboard::setRequestor(xcb_window_t window)
+{
+ if (m_requestor != XCB_NONE) {
+ xcb_destroy_window(xcb_connection(), m_requestor);
+ }
+ m_requestor = window;
+}
+
+xcb_window_t QXcbClipboard::owner() const
+{
+ return m_owner;
+}
+
+xcb_atom_t QXcbClipboard::sendTargetsSelection(QMimeData *d, xcb_window_t window, xcb_atom_t property)
+{
+ QVector<xcb_atom_t> types;
+ QStringList formats = QInternalMimeData::formatsHelper(d);
+ for (int i = 0; i < formats.size(); ++i) {
+ QList<xcb_atom_t> atoms = QXcbMime::mimeAtomsForFormat(connection(), formats.at(i));
+ for (int j = 0; j < atoms.size(); ++j) {
+ if (!types.contains(atoms.at(j)))
+ types.append(atoms.at(j));
+ }
+ }
+ types.append(atom(QXcbAtom::TARGETS));
+ types.append(atom(QXcbAtom::MULTIPLE));
+ types.append(atom(QXcbAtom::TIMESTAMP));
+ types.append(atom(QXcbAtom::SAVE_TARGETS));
+
+ xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, window, property, XCB_ATOM_ATOM,
+ 32, types.size(), (const void *)types.constData());
+ return property;
+}
+
+xcb_atom_t QXcbClipboard::sendSelection(QMimeData *d, xcb_atom_t target, xcb_window_t window, xcb_atom_t property)
+{
+ xcb_atom_t atomFormat = target;
+ int dataFormat = 0;
+ QByteArray data;
+
+ QString fmt = QXcbMime::mimeAtomToString(connection(), target);
+ if (fmt.isEmpty()) { // Not a MIME type we have
+// qDebug() << "QClipboard: send_selection(): converting to type" << connection()->atomName(target) << "is not supported";
+ return XCB_NONE;
+ }
+// qDebug() << "QClipboard: send_selection(): converting to type" << fmt;
+
+ if (QXcbMime::mimeDataForAtom(connection(), target, d, &data, &atomFormat, &dataFormat)) {
+
+ // don't allow INCR transfers when using MULTIPLE or to
+ // Motif clients (since Motif doesn't support INCR)
+ static xcb_atom_t motif_clip_temporary = atom(QXcbAtom::CLIP_TEMPORARY);
+ bool allow_incr = property != motif_clip_temporary;
+
+ // X_ChangeProperty protocol request is 24 bytes
+ const int increment = (xcb_get_maximum_request_length(xcb_connection()) * 4) - 24;
+ if (data.size() > increment && allow_incr) {
+ long bytes = data.size();
+ xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, window, property,
+ atom(QXcbAtom::INCR), 32, 1, (const void *)&bytes);
+
+// (void)new QClipboardINCRTransaction(window, property, atomFormat, dataFormat, data, increment);
+ qWarning() << "not implemented INCR just YET!";
+ return property;
+ }
+
+ // make sure we can perform the XChangeProperty in a single request
+ if (data.size() > increment)
+ return XCB_NONE; // ### perhaps use several XChangeProperty calls w/ PropModeAppend?
+ int dataSize = data.size() / (dataFormat / 8);
+ // use a single request to transfer data
+ xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, window, property, atomFormat,
+ dataFormat, dataSize, (const void *)data.constData());
+ }
+ return property;
+}
+
+void QXcbClipboard::handleSelectionClearRequest(xcb_selection_clear_event_t *event)
+{
+ QClipboard::Mode mode = modeForAtom(event->selection);
+ if (mode > QClipboard::Selection)
+ return;
+
+ // ignore the event if it was generated before we gained selection ownership
+ if (m_timestamp[mode] != XCB_CURRENT_TIME && event->time <= m_timestamp[mode])
+ return;
+
+// DEBUG("QClipboard: new selection owner 0x%lx at time %lx (ours %lx)",
+// XGetSelectionOwner(dpy, XA_PRIMARY),
+// xevent->xselectionclear.time, d->timestamp);
+
+// if (!waiting_for_data) {
+ setMimeData(0, mode);
+ emitChanged(mode);
+// } else {
+// pending_selection_changed = true;
+// if (! pending_timer_id)
+// pending_timer_id = QApplication::clipboard()->startTimer(0);
+// }
+}
+
+void QXcbClipboard::handleSelectionRequest(xcb_selection_request_event_t *req)
+{
+ if (requestor() && req->requestor == requestor()) {
+ qDebug() << "This should be caught before";
+ return;
+ }
+
+ xcb_selection_notify_event_t event;
+ event.response_type = XCB_SELECTION_NOTIFY;
+ event.requestor = req->requestor;
+ event.selection = req->selection;
+ event.target = req->target;
+ event.property = XCB_NONE;
+ event.time = req->time;
+
+ QMimeData *d;
+ QClipboard::Mode mode = modeForAtom(req->selection);
+ if (mode > QClipboard::Selection) {
+ qWarning() << "QClipboard: Unknown selection" << connection()->atomName(req->selection);
+ xcb_send_event(xcb_connection(), false, req->requestor, XCB_EVENT_MASK_NO_EVENT, (const char *)&event);
+ return;
+ }
+
+ d = m_clientClipboard[mode];
+
+ if (!d) {
+ qWarning("QClipboard: Cannot transfer data, no data available");
+ xcb_send_event(xcb_connection(), false, req->requestor, XCB_EVENT_MASK_NO_EVENT, (const char *)&event);
+ return;
+ }
+
+ if (m_timestamp[mode] == XCB_CURRENT_TIME // we don't own the selection anymore
+ || (req->time != XCB_CURRENT_TIME && req->time < m_timestamp[mode])) {
+ qDebug("QClipboard: SelectionRequest too old");
+ xcb_send_event(xcb_connection(), false, req->requestor, XCB_EVENT_MASK_NO_EVENT, (const char *)&event);
+ return;
+ }
+
+ xcb_atom_t xa_targets = atom(QXcbAtom::TARGETS);
+ xcb_atom_t xa_multiple = atom(QXcbAtom::MULTIPLE);
+ xcb_atom_t xa_timestamp = atom(QXcbAtom::TIMESTAMP);
+
+ struct AtomPair { xcb_atom_t target; xcb_atom_t property; } *multi = 0;
+ xcb_atom_t multi_type = XCB_NONE;
+ int multi_format = 0;
+ int nmulti = 0;
+ int imulti = -1;
+ bool multi_writeback = false;
+
+ if (req->target == xa_multiple) {
+ QByteArray multi_data;
+ if (req->property == XCB_NONE
+ || !clipboardReadProperty(req->requestor, req->property, false, &multi_data,
+ 0, &multi_type, &multi_format)
+ || multi_format != 32) {
+ // MULTIPLE property not formatted correctly
+ xcb_send_event(xcb_connection(), false, req->requestor, XCB_EVENT_MASK_NO_EVENT, (const char *)&event);
+ return;
+ }
+ nmulti = multi_data.size()/sizeof(*multi);
+ multi = new AtomPair[nmulti];
+ memcpy(multi,multi_data.data(),multi_data.size());
+ imulti = 0;
+ }
+
+ for (; imulti < nmulti; ++imulti) {
+ xcb_atom_t target;
+ xcb_atom_t property;
+
+ if (multi) {
+ target = multi[imulti].target;
+ property = multi[imulti].property;
+ } else {
+ target = req->target;
+ property = req->property;
+ if (property == XCB_NONE) // obsolete client
+ property = target;
+ }
+
+ xcb_atom_t ret = XCB_NONE;
+ if (target == XCB_NONE || property == XCB_NONE) {
+ ;
+ } else if (target == xa_timestamp) {
+ if (m_timestamp[mode] != XCB_CURRENT_TIME) {
+ xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, req->requestor,
+ property, XCB_ATOM_INTEGER, 32, 1, &m_timestamp[mode]);
+ ret = property;
+ } else {
+ qWarning("QClipboard: Invalid data timestamp");
+ }
+ } else if (target == xa_targets) {
+ ret = sendTargetsSelection(d, req->requestor, property);
+ } else {
+ ret = sendSelection(d, target, req->requestor, property);
+ }
+
+ if (nmulti > 0) {
+ if (ret == XCB_NONE) {
+ multi[imulti].property = XCB_NONE;
+ multi_writeback = true;
+ }
+ } else {
+ event.property = ret;
+ break;
+ }
+ }
+
+ if (nmulti > 0) {
+ if (multi_writeback) {
+ // according to ICCCM 2.6.2 says to put None back
+ // into the original property on the requestor window
+ xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, req->requestor, req->property,
+ multi_type, 32, nmulti*2, (const void *)multi);
+ }
+
+ delete [] multi;
+ event.property = req->property;
+ }
+
+ // send selection notify to requestor
+ xcb_send_event(xcb_connection(), false, req->requestor, XCB_EVENT_MASK_NO_EVENT, (const char *)&event);
+}
+
+void QXcbClipboard::handleXFixesSelectionRequest(xcb_xfixes_selection_notify_event_t *event)
+{
+ QClipboard::Mode mode = modeForAtom(event->selection);
+ if (event->owner != owner() && m_clientClipboard[mode] && m_timestamp[mode] < event->selection_timestamp) {
+ setMimeData(0, mode);
+ emitChanged(mode);
+ }
+}
+
+
+static inline int maxSelectionIncr(xcb_connection_t *c)
+{
+ int l = xcb_get_maximum_request_length(c);
+ return (l > 65536 ? 65536*4 : l*4) - 100;
+}
+
+bool QXcbClipboard::clipboardReadProperty(xcb_window_t win, xcb_atom_t property, bool deleteProperty, QByteArray *buffer, int *size, xcb_atom_t *type, int *format) const
+{
+ int maxsize = maxSelectionIncr(xcb_connection());
+ ulong bytes_left; // bytes_after
+ xcb_atom_t dummy_type;
+ int dummy_format;
+
+ if (!type) // allow null args
+ type = &dummy_type;
+ if (!format)
+ format = &dummy_format;
+
+ // Don't read anything, just get the size of the property data
+ xcb_get_property_cookie_t cookie = Q_XCB_CALL(xcb_get_property(xcb_connection(), false, win, property, XCB_GET_PROPERTY_TYPE_ANY, 0, 0));
+ xcb_get_property_reply_t *reply = xcb_get_property_reply(xcb_connection(), cookie, 0);
+ if (!reply || reply->type == XCB_NONE) {
+ buffer->resize(0);
+ return false;
+ }
+ *type = reply->type;
+ *format = reply->format;
+ bytes_left = reply->bytes_after;
+ free(reply);
+
+ int offset = 0, buffer_offset = 0, format_inc = 1, proplen = bytes_left;
+
+ switch (*format) {
+ case 8:
+ default:
+ format_inc = sizeof(char) / 1;
+ break;
+
+ case 16:
+ format_inc = sizeof(short) / 2;
+ proplen *= sizeof(short) / 2;
+ break;
+
+ case 32:
+ format_inc = sizeof(long) / 4;
+ proplen *= sizeof(long) / 4;
+ break;
+ }
+
+ int newSize = proplen;
+ buffer->resize(newSize);
+
+ bool ok = (buffer->size() == newSize);
+
+ if (ok && newSize) {
+ // could allocate buffer
+
+ while (bytes_left) {
+ // more to read...
+
+ xcb_get_property_cookie_t cookie = Q_XCB_CALL(xcb_get_property(xcb_connection(), false, win, property, XCB_GET_PROPERTY_TYPE_ANY, offset, maxsize/4));
+ reply = xcb_get_property_reply(xcb_connection(), cookie, 0);
+ if (!reply || reply->type == XCB_NONE) {
+ free(reply);
+ break;
+ }
+ *type = reply->type;
+ *format = reply->format;
+ bytes_left = reply->bytes_after;
+ char *data = (char *)xcb_get_property_value(reply);
+ int length = xcb_get_property_value_length(reply);
+
+ offset += length / (32 / *format);
+ length *= format_inc * (*format) / 8;
+
+ // Here we check if we get a buffer overflow and tries to
+ // recover -- this shouldn't normally happen, but it doesn't
+ // hurt to be defensive
+ if ((int)(buffer_offset + length) > buffer->size()) {
+ length = buffer->size() - buffer_offset;
+
+ // escape loop
+ bytes_left = 0;
+ }
+
+ memcpy(buffer->data() + buffer_offset, data, length);
+ buffer_offset += length;
+
+ free(reply);
+ }
+ }
+
+
+ // correct size, not 0-term.
+ if (size)
+ *size = buffer_offset;
+
+ if (deleteProperty)
+ xcb_delete_property(xcb_connection(), win, property);
+
+ connection()->flush();
+
+ return ok;
+}
+
+
+namespace
+{
+ class Notify {
+ public:
+ Notify(xcb_window_t win, int t)
+ : window(win), type(t) {}
+ xcb_window_t window;
+ int type;
+ bool check(xcb_generic_event_t *event) const {
+ if (!event)
+ return false;
+ int t = event->response_type & 0x7f;
+ if (t != type)
+ return false;
+ if (t == XCB_PROPERTY_NOTIFY) {
+ xcb_property_notify_event_t *pn = (xcb_property_notify_event_t *)event;
+ if (pn->window == window)
+ return true;
+ } else if (t == XCB_SELECTION_NOTIFY) {
+ xcb_selection_notify_event_t *sn = (xcb_selection_notify_event_t *)event;
+ if (sn->requestor == window)
+ return true;
+ }
+ return false;
+ }
+ };
+ class ClipboardEvent {
+ public:
+ ClipboardEvent(QXcbConnection *c)
+ { clipboard = c->internAtom("CLIPBOARD"); }
+ xcb_atom_t clipboard;
+ bool check(xcb_generic_event_t *e) const {
+ if (!e)
+ return false;
+ int type = e->response_type & 0x7f;
+ if (type == XCB_SELECTION_REQUEST) {
+ xcb_selection_request_event_t *sr = (xcb_selection_request_event_t *)e;
+ return sr->selection == XCB_ATOM_PRIMARY || sr->selection == clipboard;
+ } else if (type == XCB_SELECTION_CLEAR) {
+ xcb_selection_clear_event_t *sc = (xcb_selection_clear_event_t *)e;
+ return sc->selection == XCB_ATOM_PRIMARY || sc->selection == clipboard;
+ }
+ return false;
+ }
+ };
+}
+
+xcb_generic_event_t *QXcbClipboard::waitForClipboardEvent(xcb_window_t win, int type, int timeout)
+{
+ QElapsedTimer timer;
+ timer.start();
+ do {
+ Notify notify(win, type);
+ xcb_generic_event_t *e = connection()->checkEvent(notify);
+ if (e)
+ return e;
+
+ // process other clipboard events, since someone is probably requesting data from us
+ ClipboardEvent clipboard(connection());
+ e = connection()->checkEvent(clipboard);
+ if (e) {
+ connection()->handleXcbEvent(e);
+ free(e);
+ }
+
+ connection()->flush();
+
+ // sleep 50 ms, so we don't use up CPU cycles all the time.
+ struct timeval usleep_tv;
+ usleep_tv.tv_sec = 0;
+ usleep_tv.tv_usec = 50000;
+ select(0, 0, 0, 0, &usleep_tv);
+ } while (timer.elapsed() < timeout);
+
+ return 0;
+}
+
+QByteArray QXcbClipboard::clipboardReadIncrementalProperty(xcb_window_t win, xcb_atom_t property, int nbytes, bool nullterm)
+{
+ QByteArray buf;
+ QByteArray tmp_buf;
+ bool alloc_error = false;
+ int length;
+ int offset = 0;
+
+ if (nbytes > 0) {
+ // Reserve buffer + zero-terminator (for text data)
+ // We want to complete the INCR transfer even if we cannot
+ // allocate more memory
+ buf.resize(nbytes+1);
+ alloc_error = buf.size() != nbytes+1;
+ }
+
+ for (;;) {
+ connection()->flush();
+ xcb_generic_event_t *ge = waitForClipboardEvent(win, XCB_PROPERTY_NOTIFY, clipboard_timeout);
+ if (!ge)
+ break;
+
+ xcb_property_notify_event_t *event = (xcb_property_notify_event_t *)ge;
+ if (event->atom != property || event->state != XCB_PROPERTY_NEW_VALUE)
+ continue;
+ if (clipboardReadProperty(win, property, true, &tmp_buf, &length, 0, 0)) {
+ if (length == 0) { // no more data, we're done
+ if (nullterm) {
+ buf.resize(offset+1);
+ buf[offset] = '\0';
+ } else {
+ buf.resize(offset);
+ }
+ return buf;
+ } else if (!alloc_error) {
+ if (offset+length > (int)buf.size()) {
+ buf.resize(offset+length+65535);
+ if (buf.size() != offset+length+65535) {
+ alloc_error = true;
+ length = buf.size() - offset;
+ }
+ }
+ memcpy(buf.data()+offset, tmp_buf.constData(), length);
+ tmp_buf.resize(0);
+ offset += length;
+ }
+ } else {
+ break;
+ }
+
+ free(ge);
+ }
+
+ // timed out ... create a new requestor window, otherwise the requestor
+ // could consider next request to be still part of this timed out request
+ setRequestor(0);
+
+ return QByteArray();
+}
+
+QByteArray QXcbClipboard::getDataInFormat(xcb_atom_t modeAtom, xcb_atom_t fmtAtom)
+{
+ return getSelection(modeAtom, fmtAtom, atom(QXcbAtom::_QT_SELECTION));
+}
+
+QByteArray QXcbClipboard::getSelection(xcb_atom_t selection, xcb_atom_t target, xcb_atom_t property)
+{
+ QByteArray buf;
+ xcb_window_t win = requestor();
+
+ xcb_delete_property(xcb_connection(), win, property);
+ xcb_convert_selection(xcb_connection(), win, selection, target, property, connection()->time());
+
+ connection()->sync();
+
+ xcb_generic_event_t *ge = waitForClipboardEvent(win, XCB_SELECTION_NOTIFY, clipboard_timeout);
+ bool no_selection = !ge || ((xcb_selection_notify_event_t *)ge)->property == XCB_NONE;
+ free(ge);
+
+ if (no_selection)
+ return buf;
+
+ xcb_atom_t type;
+ if (clipboardReadProperty(win, property, true, &buf, 0, &type, 0)) {
+ if (type == atom(QXcbAtom::INCR)) {
+ int nbytes = buf.size() >= 4 ? *((int*)buf.data()) : 0;
+ buf = clipboardReadIncrementalProperty(win, property, nbytes, false);
+ }
+ }
+
+ return buf;
+}
+
+#include "qxcbclipboard.moc"
diff --git a/src/plugins/platforms/xcb/qxcbclipboard.h b/src/plugins/platforms/xcb/qxcbclipboard.h
new file mode 100644
index 0000000000..d23f93529b
--- /dev/null
+++ b/src/plugins/platforms/xcb/qxcbclipboard.h
@@ -0,0 +1,108 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QXCBCLIPBOARD_H
+#define QXCBCLIPBOARD_H
+
+#include <QPlatformClipboard>
+#include <qxcbobject.h>
+#include <xcb/xcb.h>
+#include <xcb/xfixes.h>
+
+class QXcbConnection;
+class QXcbScreen;
+class QXcbClipboardMime;
+
+class QXcbClipboard : public QXcbObject, public QPlatformClipboard
+{
+public:
+ QXcbClipboard(QXcbConnection *connection);
+ ~QXcbClipboard();
+
+ QMimeData *mimeData(QClipboard::Mode mode);
+ void setMimeData(QMimeData *data, QClipboard::Mode mode);
+
+ bool supportsMode(QClipboard::Mode mode) const;
+ bool ownsMode(QClipboard::Mode mode) const;
+
+ QXcbScreen *screen() const { return m_screen; }
+
+ xcb_window_t requestor() const;
+ void setRequestor(xcb_window_t window);
+
+ xcb_window_t owner() const;
+
+ void handleSelectionRequest(xcb_selection_request_event_t *event);
+ void handleSelectionClearRequest(xcb_selection_clear_event_t *event);
+ void handleXFixesSelectionRequest(xcb_xfixes_selection_notify_event_t *event);
+
+ bool clipboardReadProperty(xcb_window_t win, xcb_atom_t property, bool deleteProperty, QByteArray *buffer, int *size, xcb_atom_t *type, int *format) const;
+ QByteArray clipboardReadIncrementalProperty(xcb_window_t win, xcb_atom_t property, int nbytes, bool nullterm);
+
+ QByteArray getDataInFormat(xcb_atom_t modeAtom, xcb_atom_t fmtatom);
+
+ xcb_window_t getSelectionOwner(xcb_atom_t atom) const;
+ QByteArray getSelection(xcb_atom_t selection, xcb_atom_t target, xcb_atom_t property);
+
+private:
+ xcb_generic_event_t *waitForClipboardEvent(xcb_window_t win, int type, int timeout);
+
+ xcb_atom_t sendTargetsSelection(QMimeData *d, xcb_window_t window, xcb_atom_t property);
+ xcb_atom_t sendSelection(QMimeData *d, xcb_atom_t target, xcb_window_t window, xcb_atom_t property);
+
+ xcb_atom_t atomForMode(QClipboard::Mode mode) const;
+ QClipboard::Mode modeForAtom(xcb_atom_t atom) const;
+
+ QXcbScreen *m_screen;
+
+ // Selection and Clipboard
+ QXcbClipboardMime *m_xClipboard[2];
+ QMimeData *m_clientClipboard[2];
+ xcb_timestamp_t m_timestamp[2];
+
+ xcb_window_t m_requestor;
+ xcb_window_t m_owner;
+
+ static const int clipboard_timeout;
+
+};
+
+#endif // QXCBCLIPBOARD_H
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index 80a1624380..a0b894602d 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -39,33 +39,41 @@
**
****************************************************************************/
+#include <QtGui/private/qguiapplication_p.h>
+#include <QtCore/QDebug>
+
#include "qxcbconnection.h"
#include "qxcbkeyboard.h"
#include "qxcbscreen.h"
#include "qxcbwindow.h"
+#include "qxcbclipboard.h"
+#include "qxcbdrag.h"
+#include "qxcbwmsupport.h"
#include <QtAlgorithms>
#include <QSocketNotifier>
-#include <QtGui/private/qapplication_p.h>
#include <QAbstractEventDispatcher>
-
-#include <QtCore/QDebug>
+#include <QTimer>
#include <stdio.h>
#include <errno.h>
+#include <xcb/xfixes.h>
#ifdef XCB_USE_XLIB
#include <X11/Xlib.h>
#include <X11/Xlib-xcb.h>
#endif
+#ifdef XCB_USE_RENDER
+#include <xcb/render.h>
+#endif
+
#ifdef XCB_USE_EGL //dont pull in eglext prototypes
#include <EGL/egl.h>
#endif
#ifdef XCB_USE_DRI2
#include <xcb/dri2.h>
-#include <xcb/xfixes.h>
extern "C" {
#include <xf86drm.h>
}
@@ -83,12 +91,13 @@ QXcbConnection::QXcbConnection(const char *displayName)
, m_dri2_support_probed(false)
, m_has_support_for_dri2(false)
#endif
+ , xfixes_first_event(0)
{
- int primaryScreen = 0;
+ m_primaryScreen = 0;
#ifdef XCB_USE_XLIB
Display *dpy = XOpenDisplay(m_displayName.constData());
- primaryScreen = DefaultScreen(dpy);
+ m_primaryScreen = DefaultScreen(dpy);
m_connection = XGetXCBConnection(dpy);
XSetEventQueueOwner(dpy, XCBOwnsEventQueue);
m_xlib_display = dpy;
@@ -100,13 +109,33 @@ QXcbConnection::QXcbConnection(const char *displayName)
m_has_egl = eglInitialize(eglDisplay,&major,&minor);
#endif //XCB_USE_EGL
#else
- m_connection = xcb_connect(m_displayName.constData(), &primaryScreen);
-
+ m_connection = xcb_connect(m_displayName.constData(), &m_primaryScreen);
#endif //XCB_USE_XLIB
+
+ if (m_connection)
+ printf("Successfully connected to display %s\n", m_displayName.constData());
+
+ m_reader = new QXcbEventReader(m_connection);
+#ifdef XCB_POLL_FOR_QUEUED_EVENT
+ connect(m_reader, SIGNAL(eventPending()), this, SLOT(processXcbEvents()), Qt::QueuedConnection);
+ m_reader->start();
+#else
+ QSocketNotifier *notifier = new QSocketNotifier(xcb_get_file_descriptor(xcb_connection()), QSocketNotifier::Read, this);
+ connect(notifier, SIGNAL(activated(int)), this, SLOT(processXcbEvents()));
+
+ QAbstractEventDispatcher *dispatcher = QGuiApplicationPrivate::eventDispatcher;
+ connect(dispatcher, SIGNAL(aboutToBlock()), this, SLOT(processXcbEvents()));
+ connect(dispatcher, SIGNAL(awake()), this, SLOT(processXcbEvents()));
+#endif
+
+ xcb_prefetch_extension_data (m_connection, &xcb_xfixes_id);
+
m_setup = xcb_get_setup(xcb_connection());
initializeAllAtoms();
+ m_time = XCB_CURRENT_TIME;
+
xcb_screen_iterator_t it = xcb_setup_roots_iterator(m_setup);
int screenNumber = 0;
@@ -115,25 +144,38 @@ QXcbConnection::QXcbConnection(const char *displayName)
xcb_screen_next(&it);
}
+ m_connectionEventListener = xcb_generate_id(m_connection);
+ xcb_create_window(m_connection, XCB_COPY_FROM_PARENT,
+ m_connectionEventListener, m_screens.at(0)->root(),
+ 0, 0, 1, 1, 0, XCB_WINDOW_CLASS_INPUT_ONLY,
+ m_screens.at(0)->screen()->root_visual, 0, 0);
+
+ initializeXFixes();
+ initializeXRender();
+
+ m_wmSupport = new QXcbWMSupport(this);
m_keyboard = new QXcbKeyboard(this);
+ m_clipboard = new QXcbClipboard(this);
+ m_drag = new QXcbDrag(this);
#ifdef XCB_USE_DRI2
initializeDri2();
#endif
-
- QSocketNotifier *notifier = new QSocketNotifier(xcb_get_file_descriptor(xcb_connection()), QSocketNotifier::Read, this);
- connect(notifier, SIGNAL(activated(int)), this, SLOT(processXcbEvents()));
-
- QAbstractEventDispatcher *dispatcher = QAbstractEventDispatcher::instance(qApp->thread());
- connect(dispatcher, SIGNAL(aboutToBlock()), this, SLOT(processXcbEvents()));
-
sync();
}
QXcbConnection::~QXcbConnection()
{
+ delete m_clipboard;
+
qDeleteAll(m_screens);
+#ifdef XCB_POLL_FOR_QUEUED_EVENT
+ sendConnectionEvent(QXcbAtom::_QT_CLOSE_CONNECTION);
+ m_reader->wait();
+#endif
+ delete m_reader;
+
#ifdef XCB_USE_XLIB
XCloseDisplay((Display *)m_xlib_display);
#else
@@ -143,22 +185,26 @@ QXcbConnection::~QXcbConnection()
delete m_keyboard;
}
-QXcbWindow *platformWindowFromId(xcb_window_t id)
+void QXcbConnection::addWindow(xcb_window_t id, QXcbWindow *window)
{
- QWidget *widget = QWidget::find(id);
- if (widget)
- return static_cast<QXcbWindow *>(widget->platformWindow());
- return 0;
+ m_mapper.insert(id, window);
+}
+
+void QXcbConnection::removeWindow(xcb_window_t id)
+{
+ m_mapper.remove(id);
+}
+
+QXcbWindow *QXcbConnection::platformWindowFromId(xcb_window_t id)
+{
+ return m_mapper.value(id, 0);
}
-#define HANDLE_PLATFORM_WINDOW_EVENT(event_t, window, handler) \
+#define HANDLE_PLATFORM_WINDOW_EVENT(event_t, windowMember, handler) \
{ \
event_t *e = (event_t *)event; \
- if (QXcbWindow *platformWindow = platformWindowFromId(e->window)) { \
- QObjectPrivate *d = QObjectPrivate::get(platformWindow->widget()); \
- if (!d->wasDeleted) \
- platformWindow->handler(e); \
- } \
+ if (QXcbWindow *platformWindow = platformWindowFromId(e->windowMember)) \
+ platformWindow->handler(e); \
} \
break;
@@ -166,7 +212,7 @@ break;
{ \
event_t *e = (event_t *)event; \
if (QXcbWindow *platformWindow = platformWindowFromId(e->event)) \
- m_keyboard->handler(platformWindow->widget(), e); \
+ m_keyboard->handler(platformWindow, e); \
} \
break;
@@ -373,6 +419,7 @@ const char *xcb_protocol_request_codes[] =
#ifdef Q_XCB_DEBUG
void QXcbConnection::log(const char *file, int line, int sequence)
{
+ QMutexLocker locker(&m_callLogMutex);
CallInfo info;
info.sequence = sequence;
info.file = file;
@@ -392,6 +439,7 @@ void QXcbConnection::handleXcbError(xcb_generic_error_t *error)
int(error->major_code), xcb_protocol_request_codes[clamped_major_code],
int(error->minor_code));
#ifdef Q_XCB_DEBUG
+ QMutexLocker locker(&m_callLogMutex);
int i = 0;
for (; i < m_callLog.size(); ++i) {
if (m_callLog.at(i).sequence == error->sequence) {
@@ -409,67 +457,236 @@ void QXcbConnection::handleXcbError(xcb_generic_error_t *error)
#endif
}
+void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
+{
+#ifdef Q_XCB_DEBUG
+ {
+ QMutexLocker locker(&m_callLogMutex);
+ int i = 0;
+ for (; i < m_callLog.size(); ++i)
+ if (m_callLog.at(i).sequence >= event->sequence)
+ break;
+ m_callLog.remove(0, i);
+ }
+#endif
+ bool handled = true;
+
+ uint response_type = event->response_type & ~0x80;
+
+ switch (response_type) {
+ case XCB_EXPOSE:
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_expose_event_t, window, handleExposeEvent);
+ case XCB_BUTTON_PRESS:
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_button_press_event_t, event, handleButtonPressEvent);
+ case XCB_BUTTON_RELEASE:
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_button_release_event_t, event, handleButtonReleaseEvent);
+ case XCB_MOTION_NOTIFY:
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_motion_notify_event_t, event, handleMotionNotifyEvent);
+ case XCB_CONFIGURE_NOTIFY:
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_configure_notify_event_t, event, handleConfigureNotifyEvent);
+ case XCB_MAP_NOTIFY:
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_map_notify_event_t, event, handleMapNotifyEvent);
+ case XCB_UNMAP_NOTIFY:
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_unmap_notify_event_t, event, handleUnmapNotifyEvent);
+ case XCB_CLIENT_MESSAGE:
+ handleClientMessageEvent((xcb_client_message_event_t *)event);
+ case XCB_ENTER_NOTIFY:
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_enter_notify_event_t, event, handleEnterNotifyEvent);
+ case XCB_LEAVE_NOTIFY:
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_leave_notify_event_t, event, handleLeaveNotifyEvent);
+ case XCB_FOCUS_IN:
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_focus_in_event_t, event, handleFocusInEvent);
+ case XCB_FOCUS_OUT:
+ HANDLE_PLATFORM_WINDOW_EVENT(xcb_focus_out_event_t, event, handleFocusOutEvent);
+ case XCB_KEY_PRESS:
+ HANDLE_KEYBOARD_EVENT(xcb_key_press_event_t, handleKeyPressEvent);
+ case XCB_KEY_RELEASE:
+ HANDLE_KEYBOARD_EVENT(xcb_key_release_event_t, handleKeyReleaseEvent);
+ case XCB_MAPPING_NOTIFY:
+ m_keyboard->handleMappingNotifyEvent((xcb_mapping_notify_event_t *)event);
+ break;
+ case XCB_SELECTION_REQUEST:
+ {
+ xcb_selection_request_event_t *sr = (xcb_selection_request_event_t *)event;
+ if (sr->selection == atom(QXcbAtom::XdndSelection))
+ m_drag->handleSelectionRequest(sr);
+ else
+ m_clipboard->handleSelectionRequest(sr);
+ break;
+ }
+ case XCB_SELECTION_CLEAR:
+ setTime(((xcb_selection_clear_event_t *)event)->time);
+ m_clipboard->handleSelectionClearRequest((xcb_selection_clear_event_t *)event);
+ handled = true;
+ break;
+ case XCB_SELECTION_NOTIFY:
+ setTime(((xcb_selection_notify_event_t *)event)->time);
+ qDebug() << "XCB_SELECTION_NOTIFY";
+ handled = false;
+ break;
+ case XCB_PROPERTY_NOTIFY:
+ setTime(((xcb_property_notify_event_t *)event)->time);
+// qDebug() << "XCB_PROPERTY_NOTIFY";
+ handled = false;
+ break;
+ default:
+ handled = false;
+ break;
+ }
+
+ if (!handled) {
+ if (response_type == xfixes_first_event + XCB_XFIXES_SELECTION_NOTIFY) {
+ setTime(((xcb_xfixes_selection_notify_event_t *)event)->timestamp);
+ m_clipboard->handleXFixesSelectionRequest((xcb_xfixes_selection_notify_event_t *)event);
+ handled = true;
+ }
+ }
+
+ if (handled)
+ printXcbEvent("Handled XCB event", event);
+ else
+ printXcbEvent("Unhandled XCB event", event);
+}
+
+void QXcbConnection::addPeekFunc(PeekFunc f)
+{
+ m_peekFuncs.append(f);
+}
+
+#ifdef XCB_POLL_FOR_QUEUED_EVENT
+void QXcbEventReader::run()
+{
+ xcb_generic_event_t *event;
+ while (m_connection && (event = xcb_wait_for_event(m_connection))) {
+ m_mutex.lock();
+ addEvent(event);
+ while (m_connection && (event = xcb_poll_for_queued_event(m_connection)))
+ addEvent(event);
+ m_mutex.unlock();
+ emit eventPending();
+ }
+
+ for (int i = 0; i < m_events.size(); ++i)
+ free(m_events.at(i));
+}
+#endif
+
+void QXcbEventReader::addEvent(xcb_generic_event_t *event)
+{
+ if ((event->response_type & ~0x80) == XCB_CLIENT_MESSAGE
+ && ((xcb_client_message_event_t *)event)->type == QXcbAtom::_QT_CLOSE_CONNECTION)
+ m_connection = 0;
+ m_events << event;
+}
+
+QList<xcb_generic_event_t *> *QXcbEventReader::lock()
+{
+ m_mutex.lock();
+#ifndef XCB_POLL_FOR_QUEUED_EVENT
+ while (xcb_generic_event_t *event = xcb_poll_for_event(m_connection))
+ m_events << event;
+#endif
+ return &m_events;
+}
+
+void QXcbEventReader::unlock()
+{
+ m_mutex.unlock();
+}
+
+void QXcbConnection::sendConnectionEvent(QXcbAtom::Atom atom, uint id)
+{
+ xcb_client_message_event_t event;
+ memset(&event, 0, sizeof(event));
+
+ event.response_type = XCB_CLIENT_MESSAGE;
+ event.format = 32;
+ event.sequence = 0;
+ event.window = m_connectionEventListener;
+ event.type = atom;
+ event.data.data32[0] = id;
+
+ Q_XCB_CALL(xcb_send_event(xcb_connection(), false, m_connectionEventListener, XCB_EVENT_MASK_NO_EVENT, (const char *)&event));
+ xcb_flush(xcb_connection());
+}
+
void QXcbConnection::processXcbEvents()
{
- while (xcb_generic_event_t *event = xcb_poll_for_event(xcb_connection())) {
- bool handled = true;
+ QList<xcb_generic_event_t *> *eventqueue = m_reader->lock();
+
+ for(int i = 0; i < eventqueue->size(); ++i) {
+ xcb_generic_event_t *event = eventqueue->at(i);
+ if (!event)
+ continue;
+ (*eventqueue)[i] = 0;
uint response_type = event->response_type & ~0x80;
if (!response_type) {
handleXcbError((xcb_generic_error_t *)event);
- continue;
+ } else {
+ QVector<PeekFunc>::iterator it = m_peekFuncs.begin();
+ while (it != m_peekFuncs.end()) {
+ // These callbacks return true if the event is what they were
+ // waiting for, remove them from the list in that case.
+ if ((*it)(event))
+ it = m_peekFuncs.erase(it);
+ else
+ ++it;
+ }
+ handleXcbEvent(event);
}
-#ifdef Q_XCB_DEBUG
- {
- int i = 0;
- for (; i < m_callLog.size(); ++i)
- if (m_callLog.at(i).sequence >= event->sequence)
- break;
- m_callLog.remove(0, i);
- }
-#endif
+ free(event);
+ }
- switch (response_type) {
- case XCB_EXPOSE:
- HANDLE_PLATFORM_WINDOW_EVENT(xcb_expose_event_t, window, handleExposeEvent);
- case XCB_BUTTON_PRESS:
- HANDLE_PLATFORM_WINDOW_EVENT(xcb_button_press_event_t, event, handleButtonPressEvent);
- case XCB_BUTTON_RELEASE:
- HANDLE_PLATFORM_WINDOW_EVENT(xcb_button_release_event_t, event, handleButtonReleaseEvent);
- case XCB_MOTION_NOTIFY:
- HANDLE_PLATFORM_WINDOW_EVENT(xcb_motion_notify_event_t, event, handleMotionNotifyEvent);
- case XCB_CONFIGURE_NOTIFY:
- HANDLE_PLATFORM_WINDOW_EVENT(xcb_configure_notify_event_t, event, handleConfigureNotifyEvent);
- case XCB_CLIENT_MESSAGE:
- HANDLE_PLATFORM_WINDOW_EVENT(xcb_client_message_event_t, window, handleClientMessageEvent);
- case XCB_ENTER_NOTIFY:
- HANDLE_PLATFORM_WINDOW_EVENT(xcb_enter_notify_event_t, event, handleEnterNotifyEvent);
- case XCB_LEAVE_NOTIFY:
- HANDLE_PLATFORM_WINDOW_EVENT(xcb_leave_notify_event_t, event, handleLeaveNotifyEvent);
- case XCB_FOCUS_IN:
- HANDLE_PLATFORM_WINDOW_EVENT(xcb_focus_in_event_t, event, handleFocusInEvent);
- case XCB_FOCUS_OUT:
- HANDLE_PLATFORM_WINDOW_EVENT(xcb_focus_out_event_t, event, handleFocusOutEvent);
- case XCB_KEY_PRESS:
- HANDLE_KEYBOARD_EVENT(xcb_key_press_event_t, handleKeyPressEvent);
- case XCB_KEY_RELEASE:
- HANDLE_KEYBOARD_EVENT(xcb_key_release_event_t, handleKeyReleaseEvent);
- case XCB_MAPPING_NOTIFY:
- m_keyboard->handleMappingNotifyEvent((xcb_mapping_notify_event_t *)event);
- break;
- default:
- handled = false;
- break;
+ eventqueue->clear();
+
+ m_reader->unlock();
+
+ // Indicate with a null event that the event the callbacks are waiting for
+ // is not in the queue currently.
+ Q_FOREACH (PeekFunc f, m_peekFuncs)
+ f(0);
+ m_peekFuncs.clear();
+
+ xcb_flush(xcb_connection());
+}
+
+void QXcbConnection::handleClientMessageEvent(const xcb_client_message_event_t *event)
+{
+ if (event->format != 32)
+ return;
+
+ if (event->type == atom(QXcbAtom::XdndStatus)) {
+ drag()->handleStatus(event, false);
+ } else if (event->type == atom(QXcbAtom::XdndFinished)) {
+ drag()->handleFinished(event, false);
+ }
+
+ QXcbWindow *window = platformWindowFromId(event->window);
+ if (!window)
+ return;
+
+ window->handleClientMessageEvent(event);
+}
+
+xcb_generic_event_t *QXcbConnection::checkEvent(int type)
+{
+ QList<xcb_generic_event_t *> *eventqueue = m_reader->lock();
+
+ for (int i = 0; i < eventqueue->size(); ++i) {
+ xcb_generic_event_t *event = eventqueue->at(i);
+ if (event->response_type == type) {
+ (*eventqueue)[i] = 0;
+ m_reader->unlock();
+ return event;
}
- if (handled)
- printXcbEvent("Handled XCB event", event);
- else
- printXcbEvent("Unhandled XCB event", event);
}
- xcb_flush(xcb_connection());
+ m_reader->unlock();
+
+ return 0;
}
static const char * xcb_atomnames = {
@@ -511,6 +728,8 @@ static const char * xcb_atomnames = {
"_QT_SCROLL_DONE\0"
"_QT_INPUT_ENCODING\0"
+ "_QT_CLOSE_CONNECTION\0"
+
"_MOTIF_WM_HINTS\0"
"DTWM_IS_RUNNING\0"
@@ -579,7 +798,6 @@ static const char * xcb_atomnames = {
"_NET_ACTIVE_WINDOW\0"
// Property formats
- "COMPOUND_TEXT\0"
"TEXT\0"
"UTF8_STRING\0"
@@ -659,8 +877,57 @@ void QXcbConnection::initializeAllAtoms() {
for (i = 0; i < QXcbAtom::NAtoms; ++i)
cookies[i] = xcb_intern_atom(xcb_connection(), false, strlen(names[i]), names[i]);
- for (i = 0; i < QXcbAtom::NAtoms; ++i)
- m_allAtoms[i] = xcb_intern_atom_reply(xcb_connection(), cookies[i], 0)->atom;
+ for (i = 0; i < QXcbAtom::NAtoms; ++i) {
+ xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(xcb_connection(), cookies[i], 0);
+ m_allAtoms[i] = reply->atom;
+ free(reply);
+ }
+}
+
+xcb_atom_t QXcbConnection::internAtom(const char *name)
+{
+ if (!name || *name == 0)
+ return XCB_NONE;
+
+ xcb_intern_atom_cookie_t cookie = xcb_intern_atom(xcb_connection(), false, strlen(name), name);
+ xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(xcb_connection(), cookie, 0);
+ int atom = reply->atom;
+ free(reply);
+ return atom;
+}
+
+QByteArray QXcbConnection::atomName(xcb_atom_t atom)
+{
+ if (!atom)
+ return QByteArray();
+
+ xcb_generic_error_t *error = 0;
+ xcb_get_atom_name_cookie_t cookie = Q_XCB_CALL(xcb_get_atom_name(xcb_connection(), atom));
+ xcb_get_atom_name_reply_t *reply = xcb_get_atom_name_reply(xcb_connection(), cookie, &error);
+ if (error) {
+ qWarning() << "QXcbConnection::atomName: bad Atom" << atom;
+ }
+ if (reply) {
+ QByteArray result(xcb_get_atom_name_name(reply), xcb_get_atom_name_name_length(reply));
+ free(reply);
+ return result;
+ }
+ return QByteArray();
+}
+
+const xcb_format_t *QXcbConnection::formatForDepth(uint8_t depth) const
+{
+ xcb_format_iterator_t iterator =
+ xcb_setup_pixmap_formats_iterator(m_setup);
+
+ while (iterator.rem) {
+ xcb_format_t *format = iterator.data;
+ if (format->depth == depth)
+ return format;
+ xcb_format_next(&iterator);
+ }
+
+ return 0;
}
void QXcbConnection::sync()
@@ -670,6 +937,43 @@ void QXcbConnection::sync()
free(xcb_get_input_focus_reply(xcb_connection(), cookie, 0));
}
+void QXcbConnection::initializeXFixes()
+{
+ xcb_generic_error_t *error = 0;
+ const xcb_query_extension_reply_t *reply = xcb_get_extension_data(m_connection, &xcb_xfixes_id);
+ xfixes_first_event = reply->first_event;
+
+ xcb_xfixes_query_version_cookie_t xfixes_query_cookie = xcb_xfixes_query_version(m_connection,
+ XCB_XFIXES_MAJOR_VERSION,
+ XCB_XFIXES_MINOR_VERSION);
+ xcb_xfixes_query_version_reply_t *xfixes_query = xcb_xfixes_query_version_reply (m_connection,
+ xfixes_query_cookie, &error);
+ if (!xfixes_query || error || xfixes_query->major_version < 2) {
+ qWarning("Failed to initialize XFixes");
+ free(error);
+ xfixes_first_event = 0;
+ }
+ free(xfixes_query);
+
+}
+
+void QXcbConnection::initializeXRender()
+{
+#ifdef XCB_USE_RENDER
+ xcb_generic_error_t *error = 0;
+ xcb_render_query_version_cookie_t xrender_query_cookie = xcb_render_query_version(m_connection,
+ XCB_RENDER_MAJOR_VERSION,
+ XCB_RENDER_MINOR_VERSION);
+ xcb_render_query_version_reply_t *xrender_query = xcb_render_query_version_reply(m_connection,
+ xrender_query_cookie, &error);
+ if (!xrender_query || error || (xrender_query->major_version == 0 && xrender_query->minor_version < 5)) {
+ qWarning("Failed to initialize XRender");
+ free(error);
+ }
+ free(xrender_query);
+#endif
+}
+
#if defined(XCB_USE_EGL)
bool QXcbConnection::hasEgl() const
{
@@ -740,26 +1044,12 @@ bool QXcbConnection::hasSupportForDri2() const
if (!m_dri2_support_probed) {
xcb_generic_error_t *error = 0;
- xcb_prefetch_extension_data (m_connection, &xcb_xfixes_id);
xcb_prefetch_extension_data (m_connection, &xcb_dri2_id);
- xcb_xfixes_query_version_cookie_t xfixes_query_cookie = xcb_xfixes_query_version(m_connection,
- XCB_XFIXES_MAJOR_VERSION,
- XCB_XFIXES_MINOR_VERSION);
-
xcb_dri2_query_version_cookie_t dri2_query_cookie = xcb_dri2_query_version (m_connection,
XCB_DRI2_MAJOR_VERSION,
XCB_DRI2_MINOR_VERSION);
- xcb_xfixes_query_version_reply_t *xfixes_query = xcb_xfixes_query_version_reply (m_connection,
- xfixes_query_cookie, &error);
- if (!xfixes_query || error || xfixes_query->major_version < 2) {
- delete error;
- delete xfixes_query;
- return false;
- }
- delete xfixes_query;
-
xcb_dri2_query_version_reply_t *dri2_query = xcb_dri2_query_version_reply (m_connection,
dri2_query_cookie, &error);
if (!dri2_query || error) {
diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h
index 01bc719546..6d93093072 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.h
+++ b/src/plugins/platforms/xcb/qxcbconnection.h
@@ -44,13 +44,23 @@
#include <xcb/xcb.h>
+#include <QHash>
#include <QList>
+#include <QMutex>
#include <QObject>
+#include <QThread>
#include <QVector>
#define Q_XCB_DEBUG
class QXcbScreen;
+class QXcbWindow;
+class QXcbDrag;
+class QXcbKeyboard;
+class QXcbClipboard;
+class QXcbWMSupport;
+
+typedef QHash<xcb_window_t, QXcbWindow *> WindowMapper;
namespace QXcbAtom {
enum Atom {
@@ -92,6 +102,9 @@ namespace QXcbAtom {
_QT_SCROLL_DONE,
_QT_INPUT_ENCODING,
+ // Qt/XCB specific
+ _QT_CLOSE_CONNECTION,
+
_MOTIF_WM_HINTS,
DTWM_IS_RUNNING,
@@ -160,7 +173,6 @@ namespace QXcbAtom {
_NET_ACTIVE_WINDOW,
// Property formats
- COMPOUND_TEXT,
TEXT,
UTF8_STRING,
@@ -215,8 +227,34 @@ namespace QXcbAtom {
};
}
-class QXcbKeyboard;
+class QXcbEventReader : public QThread
+{
+ Q_OBJECT
+public:
+ QXcbEventReader(xcb_connection_t *connection)
+ : m_connection(connection)
+ {
+ }
+
+#ifdef XCB_POLL_FOR_QUEUED_EVENT
+ void run();
+#endif
+ QList<xcb_generic_event_t *> *lock();
+ void unlock();
+
+signals:
+ void eventPending();
+
+private:
+ void addEvent(xcb_generic_event_t *event);
+
+ QMutex m_mutex;
+ QList<xcb_generic_event_t *> m_events;
+ xcb_connection_t *m_connection;
+};
+
+class QAbstractEventDispatcher;
class QXcbConnection : public QObject
{
Q_OBJECT
@@ -226,17 +264,26 @@ public:
QXcbConnection *connection() const { return const_cast<QXcbConnection *>(this); }
- QList<QXcbScreen *> screens() const { return m_screens; }
+ const QList<QXcbScreen *> &screens() const { return m_screens; }
int primaryScreen() const { return m_primaryScreen; }
xcb_atom_t atom(QXcbAtom::Atom atom);
+ xcb_atom_t internAtom(const char *name);
+ QByteArray atomName(xcb_atom_t atom);
const char *displayName() const { return m_displayName.constData(); }
xcb_connection_t *xcb_connection() const { return m_connection; }
+ const xcb_setup_t *setup() const { return m_setup; }
+ const xcb_format_t *formatForDepth(uint8_t depth) const;
QXcbKeyboard *keyboard() const { return m_keyboard; }
+ QXcbClipboard *clipboard() const { return m_clipboard; }
+ QXcbDrag *drag() const { return m_drag; }
+
+ QXcbWMSupport *wmSupport() const { return m_wmSupport; }
+
#ifdef XCB_USE_XLIB
void *xlib_display() const { return m_xlib_display; }
#endif
@@ -253,7 +300,26 @@ public:
#endif
void sync();
+ void flush() { xcb_flush(m_connection); }
+
void handleXcbError(xcb_generic_error_t *error);
+ void handleXcbEvent(xcb_generic_event_t *event);
+
+ void addWindow(xcb_window_t id, QXcbWindow *window);
+ void removeWindow(xcb_window_t id);
+ QXcbWindow *platformWindowFromId(xcb_window_t id);
+
+ xcb_generic_event_t *checkEvent(int type);
+ template<typename T>
+ inline xcb_generic_event_t *checkEvent(const T &checker);
+
+ typedef bool (*PeekFunc)(xcb_generic_event_t *);
+ void addPeekFunc(PeekFunc f);
+
+ inline xcb_timestamp_t time() const { return m_time; }
+ inline void setTime(xcb_timestamp_t t) { if (t > m_time) m_time = t; }
+
+ bool hasXFixes() const { return xfixes_first_event > 0; }
private slots:
void processXcbEvents();
@@ -261,9 +327,12 @@ private slots:
private:
void initializeAllAtoms();
void sendConnectionEvent(QXcbAtom::Atom atom, uint id = 0);
+ void initializeXFixes();
+ void initializeXRender();
#ifdef XCB_USE_DRI2
void initializeDri2();
#endif
+ void handleClientMessageEvent(const xcb_client_message_event_t *event);
xcb_connection_t *m_connection;
const xcb_setup_t *m_setup;
@@ -273,14 +342,21 @@ private:
xcb_atom_t m_allAtoms[QXcbAtom::NAtoms];
+ xcb_timestamp_t m_time;
+
QByteArray m_displayName;
+ xcb_window_t m_connectionEventListener;
+
QXcbKeyboard *m_keyboard;
+ QXcbClipboard *m_clipboard;
+ QXcbDrag *m_drag;
+ QXcbWMSupport *m_wmSupport;
#if defined(XCB_USE_XLIB)
void *m_xlib_display;
#endif
-
+ QXcbEventReader *m_reader;
#ifdef XCB_USE_DRI2
uint32_t m_dri2_major;
uint32_t m_dri2_minor;
@@ -299,14 +375,39 @@ private:
int line;
};
QVector<CallInfo> m_callLog;
+ QMutex m_callLogMutex;
void log(const char *file, int line, int sequence);
template <typename cookie_t>
friend cookie_t q_xcb_call_template(const cookie_t &cookie, QXcbConnection *connection, const char *file, int line);
#endif
+
+ WindowMapper m_mapper;
+
+ QVector<PeekFunc> m_peekFuncs;
+
+ uint32_t xfixes_first_event;
};
#define DISPLAY_FROM_XCB(object) ((Display *)(object->connection()->xlib_display()))
+template<typename T>
+xcb_generic_event_t *QXcbConnection::checkEvent(const T &checker)
+{
+ QList<xcb_generic_event_t *> *eventqueue = m_reader->lock();
+
+ for (int i = 0; i < eventqueue->size(); ++i) {
+ xcb_generic_event_t *event = eventqueue->at(i);
+ if (checker.check(event)) {
+ (*eventqueue)[i] = 0;
+ m_reader->unlock();
+ return event;
+ }
+ }
+ m_reader->unlock();
+ return 0;
+}
+
+
#ifdef Q_XCB_DEBUG
template <typename cookie_t>
cookie_t q_xcb_call_template(const cookie_t &cookie, QXcbConnection *connection, const char *file, int line)
diff --git a/src/plugins/platforms/xcb/qxcbcursor.cpp b/src/plugins/platforms/xcb/qxcbcursor.cpp
new file mode 100644
index 0000000000..f6856d5694
--- /dev/null
+++ b/src/plugins/platforms/xcb/qxcbcursor.cpp
@@ -0,0 +1,546 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxcbcursor.h"
+#include "qxcbconnection.h"
+#include "qxcbwindow.h"
+#include "qxcbimage.h"
+#include <QtCore/QLibrary>
+#include <QtGui/QWindow>
+#include <QtGui/QBitmap>
+#include <QtGui/private/qguiapplication_p.h>
+#include <X11/cursorfont.h>
+#include <xcb/xfixes.h>
+#include <xcb/xcb_image.h>
+
+QT_BEGIN_NAMESPACE
+
+typedef int (*PtrXcursorLibraryLoadCursor)(void *, const char *);
+static PtrXcursorLibraryLoadCursor ptrXcursorLibraryLoadCursor = 0;
+static xcb_font_t cursorFont = 0;
+static int cursorCount = 0;
+
+static uint8_t cur_blank_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+static const uint8_t cur_ver_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0xf0, 0x0f,
+ 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0xf0, 0x0f,
+ 0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01, 0x00, 0x00 };
+static const uint8_t mcur_ver_bits[] = {
+ 0x00, 0x00, 0x80, 0x03, 0xc0, 0x07, 0xe0, 0x0f, 0xf0, 0x1f, 0xf8, 0x3f,
+ 0xfc, 0x7f, 0xc0, 0x07, 0xc0, 0x07, 0xc0, 0x07, 0xfc, 0x7f, 0xf8, 0x3f,
+ 0xf0, 0x1f, 0xe0, 0x0f, 0xc0, 0x07, 0x80, 0x03 };
+static const uint8_t cur_hor_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x08, 0x30, 0x18,
+ 0x38, 0x38, 0xfc, 0x7f, 0xfc, 0x7f, 0x38, 0x38, 0x30, 0x18, 0x20, 0x08,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+static const uint8_t mcur_hor_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x40, 0x04, 0x60, 0x0c, 0x70, 0x1c, 0x78, 0x3c,
+ 0xfc, 0x7f, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfc, 0x7f, 0x78, 0x3c,
+ 0x70, 0x1c, 0x60, 0x0c, 0x40, 0x04, 0x00, 0x00 };
+static const uint8_t cur_bdiag_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x3e, 0x00, 0x3c, 0x00, 0x3e,
+ 0x00, 0x37, 0x88, 0x23, 0xd8, 0x01, 0xf8, 0x00, 0x78, 0x00, 0xf8, 0x00,
+ 0xf8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+static const uint8_t mcur_bdiag_bits[] = {
+ 0x00, 0x00, 0xc0, 0x7f, 0x80, 0x7f, 0x00, 0x7f, 0x00, 0x7e, 0x04, 0x7f,
+ 0x8c, 0x7f, 0xdc, 0x77, 0xfc, 0x63, 0xfc, 0x41, 0xfc, 0x00, 0xfc, 0x01,
+ 0xfc, 0x03, 0xfc, 0x07, 0x00, 0x00, 0x00, 0x00 };
+static const uint8_t cur_fdiag_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x01, 0xf8, 0x00, 0x78, 0x00,
+ 0xf8, 0x00, 0xd8, 0x01, 0x88, 0x23, 0x00, 0x37, 0x00, 0x3e, 0x00, 0x3c,
+ 0x00, 0x3e, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00 };
+static const uint8_t mcur_fdiag_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0xfc, 0x07, 0xfc, 0x03, 0xfc, 0x01, 0xfc, 0x00,
+ 0xfc, 0x41, 0xfc, 0x63, 0xdc, 0x77, 0x8c, 0x7f, 0x04, 0x7f, 0x00, 0x7e,
+ 0x00, 0x7f, 0x80, 0x7f, 0xc0, 0x7f, 0x00, 0x00 };
+static const uint8_t *cursor_bits16[] = {
+ cur_ver_bits, mcur_ver_bits, cur_hor_bits, mcur_hor_bits,
+ cur_bdiag_bits, mcur_bdiag_bits, cur_fdiag_bits, mcur_fdiag_bits,
+ 0, 0, cur_blank_bits, cur_blank_bits };
+
+static const uint8_t vsplit_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xe0, 0x03, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xff, 0x7f, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x7f, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00,
+ 0x00, 0xc0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+static const uint8_t vsplitm_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0xc0, 0x01, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x00, 0xf0, 0x07, 0x00,
+ 0x00, 0xf8, 0x0f, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00,
+ 0x00, 0xc0, 0x01, 0x00, 0x80, 0xff, 0xff, 0x00, 0x80, 0xff, 0xff, 0x00,
+ 0x80, 0xff, 0xff, 0x00, 0x80, 0xff, 0xff, 0x00, 0x80, 0xff, 0xff, 0x00,
+ 0x80, 0xff, 0xff, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00,
+ 0x00, 0xc0, 0x01, 0x00, 0x00, 0xf8, 0x0f, 0x00, 0x00, 0xf0, 0x07, 0x00,
+ 0x00, 0xe0, 0x03, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+static const uint8_t hsplit_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00,
+ 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00,
+ 0x00, 0x41, 0x82, 0x00, 0x80, 0x41, 0x82, 0x01, 0xc0, 0x7f, 0xfe, 0x03,
+ 0x80, 0x41, 0x82, 0x01, 0x00, 0x41, 0x82, 0x00, 0x00, 0x40, 0x02, 0x00,
+ 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00,
+ 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+static const uint8_t hsplitm_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00,
+ 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe2, 0x47, 0x00, 0x00, 0xe3, 0xc7, 0x00,
+ 0x80, 0xe3, 0xc7, 0x01, 0xc0, 0xff, 0xff, 0x03, 0xe0, 0xff, 0xff, 0x07,
+ 0xc0, 0xff, 0xff, 0x03, 0x80, 0xe3, 0xc7, 0x01, 0x00, 0xe3, 0xc7, 0x00,
+ 0x00, 0xe2, 0x47, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00,
+ 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+static const uint8_t whatsthis_bits[] = {
+ 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0xf0, 0x07, 0x00,
+ 0x09, 0x18, 0x0e, 0x00, 0x11, 0x1c, 0x0e, 0x00, 0x21, 0x1c, 0x0e, 0x00,
+ 0x41, 0x1c, 0x0e, 0x00, 0x81, 0x1c, 0x0e, 0x00, 0x01, 0x01, 0x07, 0x00,
+ 0x01, 0x82, 0x03, 0x00, 0xc1, 0xc7, 0x01, 0x00, 0x49, 0xc0, 0x01, 0x00,
+ 0x95, 0xc0, 0x01, 0x00, 0x93, 0xc0, 0x01, 0x00, 0x21, 0x01, 0x00, 0x00,
+ 0x20, 0xc1, 0x01, 0x00, 0x40, 0xc2, 0x01, 0x00, 0x40, 0x02, 0x00, 0x00,
+ 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
+static const uint8_t whatsthism_bits[] = {
+ 0x01, 0x00, 0x00, 0x00, 0x03, 0xf0, 0x07, 0x00, 0x07, 0xf8, 0x0f, 0x00,
+ 0x0f, 0xfc, 0x1f, 0x00, 0x1f, 0x3e, 0x1f, 0x00, 0x3f, 0x3e, 0x1f, 0x00,
+ 0x7f, 0x3e, 0x1f, 0x00, 0xff, 0x3e, 0x1f, 0x00, 0xff, 0x9d, 0x0f, 0x00,
+ 0xff, 0xc3, 0x07, 0x00, 0xff, 0xe7, 0x03, 0x00, 0x7f, 0xe0, 0x03, 0x00,
+ 0xf7, 0xe0, 0x03, 0x00, 0xf3, 0xe0, 0x03, 0x00, 0xe1, 0xe1, 0x03, 0x00,
+ 0xe0, 0xe1, 0x03, 0x00, 0xc0, 0xe3, 0x03, 0x00, 0xc0, 0xe3, 0x03, 0x00,
+ 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
+static const uint8_t busy_bits[] = {
+ 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
+ 0x09, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
+ 0x41, 0xe0, 0xff, 0x00, 0x81, 0x20, 0x80, 0x00, 0x01, 0xe1, 0xff, 0x00,
+ 0x01, 0x42, 0x40, 0x00, 0xc1, 0x47, 0x40, 0x00, 0x49, 0x40, 0x55, 0x00,
+ 0x95, 0x80, 0x2a, 0x00, 0x93, 0x00, 0x15, 0x00, 0x21, 0x01, 0x0a, 0x00,
+ 0x20, 0x01, 0x11, 0x00, 0x40, 0x82, 0x20, 0x00, 0x40, 0x42, 0x44, 0x00,
+ 0x80, 0x41, 0x4a, 0x00, 0x00, 0x40, 0x55, 0x00, 0x00, 0xe0, 0xff, 0x00,
+ 0x00, 0x20, 0x80, 0x00, 0x00, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+static const uint8_t busym_bits[] = {
+ 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
+ 0x0f, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00,
+ 0x7f, 0xe0, 0xff, 0x00, 0xff, 0xe0, 0xff, 0x00, 0xff, 0xe1, 0xff, 0x00,
+ 0xff, 0xc3, 0x7f, 0x00, 0xff, 0xc7, 0x7f, 0x00, 0x7f, 0xc0, 0x7f, 0x00,
+ 0xf7, 0x80, 0x3f, 0x00, 0xf3, 0x00, 0x1f, 0x00, 0xe1, 0x01, 0x0e, 0x00,
+ 0xe0, 0x01, 0x1f, 0x00, 0xc0, 0x83, 0x3f, 0x00, 0xc0, 0xc3, 0x7f, 0x00,
+ 0x80, 0xc1, 0x7f, 0x00, 0x00, 0xc0, 0x7f, 0x00, 0x00, 0xe0, 0xff, 0x00,
+ 0x00, 0xe0, 0xff, 0x00, 0x00, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+static const uint8_t * const cursor_bits32[] = {
+ vsplit_bits, vsplitm_bits, hsplit_bits, hsplitm_bits,
+ 0, 0, 0, 0, whatsthis_bits, whatsthism_bits, busy_bits, busym_bits
+};
+
+static const uint8_t forbidden_bits[] = {
+ 0x00,0x00,0x00,0x80,0x1f,0x00,0xe0,0x7f,0x00,0xf0,0xf0,0x00,0x38,0xc0,0x01,
+ 0x7c,0x80,0x03,0xec,0x00,0x03,0xce,0x01,0x07,0x86,0x03,0x06,0x06,0x07,0x06,
+ 0x06,0x0e,0x06,0x06,0x1c,0x06,0x0e,0x38,0x07,0x0c,0x70,0x03,0x1c,0xe0,0x03,
+ 0x38,0xc0,0x01,0xf0,0xe0,0x00,0xe0,0x7f,0x00,0x80,0x1f,0x00,0x00,0x00,0x00 };
+
+static const uint8_t forbiddenm_bits[] = {
+ 0x80,0x1f,0x00,0xe0,0x7f,0x00,0xf0,0xff,0x00,0xf8,0xff,0x01,0xfc,0xf0,0x03,
+ 0xfe,0xc0,0x07,0xfe,0x81,0x07,0xff,0x83,0x0f,0xcf,0x07,0x0f,0x8f,0x0f,0x0f,
+ 0x0f,0x1f,0x0f,0x0f,0x3e,0x0f,0x1f,0xfc,0x0f,0x1e,0xf8,0x07,0x3e,0xf0,0x07,
+ 0xfc,0xe0,0x03,0xf8,0xff,0x01,0xf0,0xff,0x00,0xe0,0x7f,0x00,0x80,0x1f,0x00};
+
+static const uint8_t openhand_bits[] = {
+ 0x80,0x01,0x58,0x0e,0x64,0x12,0x64,0x52,0x48,0xb2,0x48,0x92,
+ 0x16,0x90,0x19,0x80,0x11,0x40,0x02,0x40,0x04,0x40,0x04,0x20,
+ 0x08,0x20,0x10,0x10,0x20,0x10,0x00,0x00};
+static const uint8_t openhandm_bits[] = {
+ 0x80,0x01,0xd8,0x0f,0xfc,0x1f,0xfc,0x5f,0xf8,0xff,0xf8,0xff,
+ 0xf6,0xff,0xff,0xff,0xff,0x7f,0xfe,0x7f,0xfc,0x7f,0xfc,0x3f,
+ 0xf8,0x3f,0xf0,0x1f,0xe0,0x1f,0x00,0x00};
+static const uint8_t closedhand_bits[] = {
+ 0x00,0x00,0x00,0x00,0x00,0x00,0xb0,0x0d,0x48,0x32,0x08,0x50,
+ 0x10,0x40,0x18,0x40,0x04,0x40,0x04,0x20,0x08,0x20,0x10,0x10,
+ 0x20,0x10,0x20,0x10,0x00,0x00,0x00,0x00};
+static const uint8_t closedhandm_bits[] = {
+ 0x00,0x00,0x00,0x00,0x00,0x00,0xb0,0x0d,0xf8,0x3f,0xf8,0x7f,
+ 0xf0,0x7f,0xf8,0x7f,0xfc,0x7f,0xfc,0x3f,0xf8,0x3f,0xf0,0x1f,
+ 0xe0,0x1f,0xe0,0x1f,0x00,0x00,0x00,0x00};
+
+static const uint8_t * const cursor_bits20[] = {
+ forbidden_bits, forbiddenm_bits
+};
+
+static const char * const cursorNames[] = {
+ "left_ptr",
+ "up_arrow",
+ "cross",
+ "wait",
+ "ibeam",
+ "size_ver",
+ "size_hor",
+ "size_bdiag",
+ "size_fdiag",
+ "size_all",
+ "blank",
+ "split_v",
+ "split_h",
+ "pointing_hand",
+ "forbidden",
+ "whats_this",
+ "left_ptr_watch",
+ "openhand",
+ "closedhand",
+ "copy",
+ "move",
+ "link"
+};
+
+QXcbCursor::QXcbCursor(QXcbConnection *conn, QXcbScreen *screen)
+ : QXcbObject(conn), QPlatformCursor(screen), m_screen(screen)
+{
+ if (cursorCount++)
+ return;
+
+ cursorFont = xcb_generate_id(xcb_connection());
+ const char *cursorStr = "cursor";
+ xcb_open_font(xcb_connection(), cursorFont, strlen(cursorStr), cursorStr);
+
+#ifdef XCB_USE_XLIB
+ QLibrary xcursorLib(QLatin1String("Xcursor"), 1);
+ bool xcursorFound = xcursorLib.load();
+ if (!xcursorFound) { // try without the version number
+ xcursorLib.setFileName(QLatin1String("Xcursor"));
+ xcursorFound = xcursorLib.load();
+ }
+ if (xcursorFound)
+ ptrXcursorLibraryLoadCursor =
+ (PtrXcursorLibraryLoadCursor) xcursorLib.resolve("XcursorLibraryLoadCursor");
+#endif
+}
+
+QXcbCursor::~QXcbCursor()
+{
+ if (!--cursorCount)
+ xcb_close_font(xcb_connection(), cursorFont);
+}
+
+void QXcbCursor::changeCursor(QCursor *cursor, QWindow *widget)
+{
+ QXcbWindow *w = 0;
+ if (widget && widget->handle())
+ w = static_cast<QXcbWindow *>(widget->handle());
+ else
+ // No X11 cursor control when there is no widget under the cursor
+ return;
+
+ xcb_cursor_t c;
+ if (cursor->shape() == Qt::BitmapCursor) {
+ qint64 id = cursor->pixmap().cacheKey();
+ if (!m_bitmapCursorMap.contains(id))
+ m_bitmapCursorMap.insert(id, createBitmapCursor(cursor));
+ c = m_bitmapCursorMap.value(id);
+ } else {
+ int id = cursor->handle();
+ if (!m_shapeCursorMap.contains(id))
+ m_shapeCursorMap.insert(id, createFontCursor(cursor->shape()));
+ c = m_shapeCursorMap.value(id);
+ }
+
+ w->setCursor(c);
+}
+
+static int cursorIdForShape(int cshape)
+{
+ int cursorId = 0;
+ switch (cshape) {
+ case Qt::ArrowCursor:
+ cursorId = XC_left_ptr;
+ break;
+ case Qt::UpArrowCursor:
+ cursorId = XC_center_ptr;
+ break;
+ case Qt::CrossCursor:
+ cursorId = XC_crosshair;
+ break;
+ case Qt::WaitCursor:
+ cursorId = XC_watch;
+ break;
+ case Qt::IBeamCursor:
+ cursorId = XC_xterm;
+ break;
+ case Qt::SizeAllCursor:
+ cursorId = XC_fleur;
+ break;
+ case Qt::PointingHandCursor:
+ cursorId = XC_hand2;
+ break;
+ case Qt::SizeBDiagCursor:
+ cursorId = XC_top_right_corner;
+ break;
+ case Qt::SizeFDiagCursor:
+ cursorId = XC_bottom_right_corner;
+ break;
+ case Qt::SizeVerCursor:
+ case Qt::SplitVCursor:
+ cursorId = XC_sb_v_double_arrow;
+ break;
+ case Qt::SizeHorCursor:
+ case Qt::SplitHCursor:
+ cursorId = XC_sb_h_double_arrow;
+ break;
+ case Qt::WhatsThisCursor:
+ cursorId = XC_question_arrow;
+ break;
+ case Qt::ForbiddenCursor:
+ cursorId = XC_circle;
+ break;
+ case Qt::BusyCursor:
+ cursorId = XC_watch;
+ break;
+ default:
+ break;
+ }
+ return cursorId;
+}
+
+xcb_cursor_t QXcbCursor::createNonStandardCursor(int cshape)
+{
+ xcb_cursor_t cursor = 0;
+ xcb_connection_t *conn = xcb_connection();
+
+ if (cshape == Qt::BlankCursor) {
+ xcb_pixmap_t cp = xcb_create_pixmap_from_bitmap_data(conn, m_screen->root(), cur_blank_bits, 16, 16,
+ 1, 0, 0, 0);
+ xcb_pixmap_t mp = xcb_create_pixmap_from_bitmap_data(conn, m_screen->root(), cur_blank_bits, 16, 16,
+ 1, 0, 0, 0);
+ cursor = xcb_generate_id(conn);
+ xcb_create_cursor(conn, cursor, cp, mp, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF, 8, 8);
+ } else if (cshape >= Qt::SizeVerCursor && cshape < Qt::SizeAllCursor) {
+ int i = (cshape - Qt::SizeVerCursor) * 2;
+ xcb_pixmap_t pm = xcb_create_pixmap_from_bitmap_data(conn, m_screen->root(),
+ const_cast<uint8_t*>(cursor_bits16[i]),
+ 16, 16, 1, 0, 0, 0);
+ xcb_pixmap_t pmm = xcb_create_pixmap_from_bitmap_data(conn, m_screen->root(),
+ const_cast<uint8_t*>(cursor_bits16[i + 1]),
+ 16, 16, 1, 0, 0, 0);
+ cursor = xcb_generate_id(conn);
+ xcb_create_cursor(conn, cursor, pm, pmm, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF, 8, 8);
+ } else if ((cshape >= Qt::SplitVCursor && cshape <= Qt::SplitHCursor)
+ || cshape == Qt::WhatsThisCursor || cshape == Qt::BusyCursor) {
+ int i = (cshape - Qt::SplitVCursor) * 2;
+ xcb_pixmap_t pm = xcb_create_pixmap_from_bitmap_data(conn, m_screen->root(),
+ const_cast<uint8_t*>(cursor_bits32[i]),
+ 32, 32, 1, 0, 0, 0);
+ xcb_pixmap_t pmm = xcb_create_pixmap_from_bitmap_data(conn, m_screen->root(),
+ const_cast<uint8_t*>(cursor_bits32[i + 1]),
+ 32, 32, 1, 0, 0, 0);
+ int hs = (cshape == Qt::PointingHandCursor || cshape == Qt::WhatsThisCursor
+ || cshape == Qt::BusyCursor) ? 0 : 16;
+ cursor = xcb_generate_id(conn);
+ xcb_create_cursor(conn, cursor, pm, pmm, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF, hs, hs);
+ } else if (cshape == Qt::ForbiddenCursor) {
+ int i = (cshape - Qt::ForbiddenCursor) * 2;
+ xcb_pixmap_t pm = xcb_create_pixmap_from_bitmap_data(conn, m_screen->root(),
+ const_cast<uint8_t*>(cursor_bits20[i]),
+ 20, 20, 1, 0, 0, 0);
+ xcb_pixmap_t pmm = xcb_create_pixmap_from_bitmap_data(conn, m_screen->root(),
+ const_cast<uint8_t*>(cursor_bits20[i + 1]),
+ 20, 20, 1, 0, 0, 0);
+ cursor = xcb_generate_id(conn);
+ xcb_create_cursor(conn, cursor, pm, pmm, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF, 10, 10);
+ } else if (cshape == Qt::OpenHandCursor || cshape == Qt::ClosedHandCursor) {
+ bool open = cshape == Qt::OpenHandCursor;
+ xcb_pixmap_t pm = xcb_create_pixmap_from_bitmap_data(conn, m_screen->root(),
+ const_cast<uint8_t*>(open ? openhand_bits : closedhand_bits),
+ 16, 16, 1, 0, 0, 0);
+ xcb_pixmap_t pmm = xcb_create_pixmap_from_bitmap_data(conn, m_screen->root(),
+ const_cast<uint8_t*>(open ? openhandm_bits : closedhandm_bits),
+ 16, 16, 1, 0, 0, 0);
+ cursor = xcb_generate_id(conn);
+ xcb_create_cursor(conn, cursor, pm, pmm, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF, 8, 8);
+ } else if (cshape == Qt::DragCopyCursor || cshape == Qt::DragMoveCursor
+ || cshape == Qt::DragLinkCursor) {
+ QImage image = QGuiApplicationPrivate::instance()->getPixmapCursor(static_cast<Qt::CursorShape>(cshape)).toImage();
+ xcb_pixmap_t pm = qt_xcb_XPixmapFromBitmap(m_screen, image);
+ xcb_pixmap_t pmm = qt_xcb_XPixmapFromBitmap(m_screen, image.createAlphaMask());
+ cursor = xcb_generate_id(conn);
+ xcb_create_cursor(conn, cursor, pm, pmm, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF, 8, 8);
+ }
+
+ return cursor;
+}
+
+xcb_cursor_t QXcbCursor::createFontCursor(int cshape)
+{
+ xcb_connection_t *conn = xcb_connection();
+ int cursorId = cursorIdForShape(cshape);
+ xcb_cursor_t cursor = XCB_NONE;
+
+ // Try Xcursor first
+#ifdef XCB_USE_XLIB
+ if (ptrXcursorLibraryLoadCursor && cshape >= 0 && cshape < Qt::LastCursor) {
+ void *dpy = connection()->xlib_display();
+ // special case for non-standard dnd-* cursors
+ switch (cshape) {
+ case Qt::DragCopyCursor:
+ cursor = ptrXcursorLibraryLoadCursor(dpy, "dnd-copy");
+ break;
+ case Qt::DragMoveCursor:
+ cursor = ptrXcursorLibraryLoadCursor(dpy, "dnd-move");
+ break;
+ case Qt::DragLinkCursor:
+ cursor = ptrXcursorLibraryLoadCursor(dpy, "dnd-link");
+ break;
+ default:
+ break;
+ }
+ if (!cursor)
+ cursor = ptrXcursorLibraryLoadCursor(dpy, cursorNames[cshape]);
+ }
+ if (cursor)
+ return cursor;
+#endif
+
+ // Non-standard X11 cursors are created from bitmaps
+ cursor = createNonStandardCursor(cshape);
+
+ // Create a glpyh cursor if everything else failed
+ if (!cursor && cursorId) {
+ cursor = xcb_generate_id(conn);
+ xcb_create_glyph_cursor(conn, cursor, cursorFont, cursorFont,
+ cursorId, cursorId + 1,
+ 0xFFFF, 0xFFFF, 0xFFFF, 0, 0, 0);
+ }
+
+ if (cursor && cshape >= 0 && cshape < Qt::LastCursor) {
+ const char *name = cursorNames[cshape];
+ xcb_xfixes_set_cursor_name(conn, cursor, strlen(name), name);
+ }
+
+ return cursor;
+}
+
+xcb_cursor_t QXcbCursor::createBitmapCursor(QCursor *cursor)
+{
+ xcb_connection_t *conn = xcb_connection();
+ QPoint spot = cursor->hotSpot();
+ xcb_cursor_t c = XCB_NONE;
+ if (cursor->pixmap().depth() > 1)
+ c = qt_xcb_createCursorXRender(m_screen, cursor->pixmap().toImage(), spot);
+ if (!c) {
+ xcb_pixmap_t cp = qt_xcb_XPixmapFromBitmap(m_screen, cursor->bitmap()->toImage());
+ xcb_pixmap_t mp = qt_xcb_XPixmapFromBitmap(m_screen, cursor->mask()->toImage());
+ c = xcb_generate_id(conn);
+ xcb_create_cursor(conn, c, cp, mp, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF,
+ spot.x(), spot.y());
+ xcb_free_pixmap(conn, cp);
+ xcb_free_pixmap(conn, mp);
+ }
+ return c;
+}
+
+static void getPosAndRoot(xcb_connection_t *conn, xcb_window_t *rootWin, QPoint *pos)
+{
+ if (pos)
+ *pos = QPoint();
+ xcb_screen_iterator_t it = xcb_setup_roots_iterator(xcb_get_setup(conn));
+ while (it.rem) {
+ xcb_window_t root = it.data->root;
+ xcb_query_pointer_cookie_t cookie = xcb_query_pointer(conn, root);
+ xcb_generic_error_t *err = 0;
+ xcb_query_pointer_reply_t *reply = xcb_query_pointer_reply(conn, cookie, &err);
+ if (!err && reply) {
+ if (pos)
+ *pos = QPoint(reply->root_x, reply->root_y);
+ if (rootWin)
+ *rootWin = root;
+ free(reply);
+ return;
+ }
+ free(err);
+ free(reply);
+ xcb_screen_next(&it);
+ }
+}
+
+QPoint QXcbCursor::pos() const
+{
+ QPoint p;
+ getPosAndRoot(xcb_connection(), 0, &p);
+ return p;
+}
+
+void QXcbCursor::setPos(const QPoint &pos)
+{
+ xcb_connection_t *conn = xcb_connection();
+ xcb_window_t root;
+ getPosAndRoot(conn, &root, 0);
+ xcb_warp_pointer(conn, XCB_NONE, root, 0, 0, 0, 0, pos.x(), pos.y());
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/qxcbcursor.h b/src/plugins/platforms/xcb/qxcbcursor.h
new file mode 100644
index 0000000000..4bbb9a928b
--- /dev/null
+++ b/src/plugins/platforms/xcb/qxcbcursor.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QXCBCURSOR_H
+#define QXCBCURSOR_H
+
+#include <QtGui/QPlatformCursor>
+#include "qxcbscreen.h"
+
+QT_BEGIN_NAMESPACE
+
+class QXcbCursor : public QXcbObject, public QPlatformCursor
+{
+public:
+ QXcbCursor(QXcbConnection *conn, QXcbScreen *screen);
+ ~QXcbCursor();
+ void changeCursor(QCursor *cursor, QWindow *widget);
+ QPoint pos() const;
+ void setPos(const QPoint &pos);
+
+private:
+ xcb_cursor_t createFontCursor(int cshape);
+ xcb_cursor_t createBitmapCursor(QCursor *cursor);
+ xcb_cursor_t createNonStandardCursor(int cshape);
+
+ QXcbScreen *m_screen;
+ QMap<int, xcb_cursor_t> m_shapeCursorMap;
+ QMap<qint64, xcb_cursor_t> m_bitmapCursorMap;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp
new file mode 100644
index 0000000000..8a6fd29986
--- /dev/null
+++ b/src/plugins/platforms/xcb/qxcbdrag.cpp
@@ -0,0 +1,1332 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxcbdrag.h"
+#include <xcb/xcb.h>
+#include "qxcbconnection.h"
+#include "qxcbclipboard.h"
+#include "qxcbmime.h"
+#include "qxcbwindow.h"
+#include "qxcbscreen.h"
+#include "qwindow.h"
+#include <private/qdnd_p.h>
+#include <qdebug.h>
+#include <qevent.h>
+#include <qguiapplication.h>
+#include <qrect.h>
+
+QT_BEGIN_NAMESPACE
+
+//#define DND_DEBUG
+#ifdef DND_DEBUG
+#define DEBUG qDebug
+#else
+#define DEBUG if(0) qDebug
+#endif
+
+#ifdef DND_DEBUG
+#define DNDDEBUG qDebug()
+#else
+#define DNDDEBUG if(0) qDebug()
+#endif
+
+const int xdnd_version = 5;
+
+static inline xcb_window_t xcb_window(QWindow *w)
+{
+ return static_cast<QXcbWindow *>(w->handle())->xcb_window();
+}
+
+
+static xcb_window_t xdndProxy(QXcbConnection *c, xcb_window_t w)
+{
+ xcb_window_t proxy = XCB_NONE;
+
+ xcb_get_property_cookie_t cookie = Q_XCB_CALL2(xcb_get_property(c->xcb_connection(), false, w, c->atom(QXcbAtom::XdndProxy),
+ XCB_ATOM_WINDOW, 0, 1), c);
+ xcb_get_property_reply_t *reply = xcb_get_property_reply(c->xcb_connection(), cookie, 0);
+
+ if (reply && reply->type == XCB_ATOM_WINDOW)
+ proxy = *((xcb_window_t *)xcb_get_property_value(reply));
+ free(reply);
+
+ if (proxy == XCB_NONE)
+ return proxy;
+
+ // exists and is real?
+ cookie = Q_XCB_CALL2(xcb_get_property(c->xcb_connection(), false, proxy, c->atom(QXcbAtom::XdndProxy),
+ XCB_ATOM_WINDOW, 0, 1), c);
+ reply = xcb_get_property_reply(c->xcb_connection(), cookie, 0);
+
+ if (reply && reply->type == XCB_ATOM_WINDOW) {
+ xcb_window_t p = *((xcb_window_t *)xcb_get_property_value(reply));
+ if (proxy != p)
+ proxy = 0;
+ } else {
+ proxy = 0;
+ }
+
+ free(reply);
+
+ return proxy;
+}
+
+
+class QDropData : public QXcbMime
+{
+public:
+ QDropData(QXcbDrag *d);
+ ~QDropData();
+
+protected:
+ bool hasFormat_sys(const QString &mimeType) const;
+ QStringList formats_sys() const;
+ QVariant retrieveData_sys(const QString &mimeType, QVariant::Type type) const;
+
+ QVariant xdndObtainData(const QByteArray &format, QVariant::Type requestedType) const;
+
+ QXcbDrag *drag;
+};
+
+
+QXcbDrag::QXcbDrag(QXcbConnection *c)
+ : QXcbObject(c)
+{
+ dropData = new QDropData(this);
+
+ init();
+ heartbeat = -1;
+
+ transaction_expiry_timer = -1;
+}
+
+QXcbDrag::~QXcbDrag()
+{
+ delete dropData;
+}
+
+void QXcbDrag::init()
+{
+ currentWindow.clear();
+
+ xdnd_dragsource = XCB_NONE;
+ last_target_accepted_action = Qt::IgnoreAction;
+
+ waiting_for_status = false;
+ current_target = XCB_NONE;
+ current_proxy_target = XCB_NONE;
+ xdnd_dragging = false;
+
+ source_time = XCB_CURRENT_TIME;
+ target_time = XCB_CURRENT_TIME;
+
+ current_screen = 0;
+ drag_types.clear();
+}
+
+QMimeData *QXcbDrag::platformDropData()
+{
+ return dropData;
+}
+
+void QXcbDrag::startDrag()
+{
+ init();
+
+ heartbeat = startTimer(200);
+ xdnd_dragging = true;
+
+ xcb_set_selection_owner(xcb_connection(), connection()->clipboard()->owner(),
+ atom(QXcbAtom::XdndSelection), connection()->time());
+
+ QDragManager *manager = QDragManager::self();
+ QStringList fmts = QXcbMime::formatsHelper(manager->dropData());
+ for (int i = 0; i < fmts.size(); ++i) {
+ QList<xcb_atom_t> atoms = QXcbMime::mimeAtomsForFormat(connection(), fmts.at(i));
+ for (int j = 0; j < atoms.size(); ++j) {
+ if (!drag_types.contains(atoms.at(j)))
+ drag_types.append(atoms.at(j));
+ }
+ }
+ if (drag_types.size() > 3)
+ xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, connection()->clipboard()->owner(),
+ atom(QXcbAtom::XdndTypelist),
+ XCB_ATOM_ATOM, 32, drag_types.size(), (const void *)drag_types.constData());
+
+ QPointF pos = QCursor::pos();
+ QMouseEvent me(QEvent::MouseMove, pos, pos, pos, Qt::LeftButton,
+ QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers());
+ move(&me);
+
+// if (!QWidget::mouseGrabber())
+// manager->shapedPixmapWindow->grabMouse();
+}
+
+void QXcbDrag::endDrag()
+{
+ Q_ASSERT(heartbeat != -1);
+ killTimer(heartbeat);
+ heartbeat = -1;
+
+ xdnd_dragging = false;
+}
+
+static xcb_translate_coordinates_reply_t *
+translateCoordinates(QXcbConnection *c, xcb_window_t from, xcb_window_t to, int x, int y)
+{
+ xcb_translate_coordinates_cookie_t cookie =
+ xcb_translate_coordinates(c->xcb_connection(), from, to, x, y);
+ return xcb_translate_coordinates_reply(c->xcb_connection(), cookie, 0);
+}
+
+void QXcbDrag::move(const QMouseEvent *me)
+{
+ DEBUG() << "QDragManager::move enter";
+
+ // ###
+ QPoint globalPos = me->globalPos();
+
+ if (source_sameanswer.contains(globalPos) && source_sameanswer.isValid())
+ return;
+
+ const QList<QXcbScreen *> &screens = connection()->screens();
+ QXcbScreen *screen = screens.at(connection()->primaryScreen());
+ for (int i = 0; i < screens.size(); ++i) {
+ if (screens.at(i)->geometry().contains(globalPos)) {
+ screen = screens.at(i);
+ break;
+ }
+ }
+ if (screen != current_screen) {
+ // ### need to recreate the shaped pixmap window?
+// int screen = QCursor::x11Screen();
+// if ((qt_xdnd_current_screen == -1 && screen != X11->defaultScreen) || (screen != qt_xdnd_current_screen)) {
+// // recreate the pixmap on the new screen...
+// delete xdnd_data.deco;
+// QWidget* parent = object->source()->window()->x11Info().screen() == screen
+// ? object->source()->window() : QApplication::desktop()->screen(screen);
+// xdnd_data.deco = new QShapedPixmapWidget(parent);
+// if (!QWidget::mouseGrabber()) {
+// updatePixmap();
+// xdnd_data.deco->grabMouse();
+// }
+// }
+// xdnd_data.deco->move(QCursor::pos() - xdnd_data.deco->pm_hot);
+ current_screen = screen;
+ }
+
+
+// qt_xdnd_current_screen = screen;
+ xcb_window_t rootwin = current_screen->root();
+ xcb_translate_coordinates_reply_t *translate =
+ ::translateCoordinates(connection(), rootwin, rootwin, globalPos.x(), globalPos.y());
+ if (!translate)
+ return;
+ xcb_window_t target = translate->child;
+ int lx = translate->dst_x;
+ int ly = translate->dst_y;
+ free (translate);
+
+ if (target == rootwin) {
+ // Ok.
+ } else if (target) {
+ //me
+ xcb_window_t src = rootwin;
+ while (target != 0) {
+ DNDDEBUG << "checking target for XdndAware" << target;
+
+ // translate coordinates
+ translate = ::translateCoordinates(connection(), src, target, lx, ly);
+ if (!translate) {
+ target = 0;
+ break;
+ }
+ lx = translate->dst_x;
+ ly = translate->dst_y;
+ src = translate->child;
+ free(translate);
+
+ // check if it has XdndAware
+ xcb_get_property_cookie_t cookie = Q_XCB_CALL(xcb_get_property(xcb_connection(), false, target,
+ atom(QXcbAtom::XdndAware), XCB_GET_PROPERTY_TYPE_ANY, 0, 0));
+ xcb_get_property_reply_t *reply = xcb_get_property_reply(xcb_connection(), cookie, 0);
+ bool aware = reply && reply->type != XCB_NONE;
+ free(reply);
+ if (aware) {
+ DNDDEBUG << "Found XdndAware on " << target;
+ break;
+ }
+
+ // find child at the coordinates
+ translate = ::translateCoordinates(connection(), src, src, lx, ly);
+ if (!translate) {
+ target = 0;
+ break;
+ }
+ target = translate->child;
+ free(translate);
+ }
+ // ####
+// if (xdnd_data.deco && (!target || target == xdnd_data.deco->effectiveWinId())) {
+// DNDDEBUG << "need to find real window";
+// target = findRealWindow(globalPos, rootwin, 6);
+// DNDDEBUG << "real window found" << QWidget::find(target) << target;
+// }
+ }
+
+ QXcbWindow *w = 0;
+ if (target) {
+ w = connection()->platformWindowFromId(target);
+ if (w && (w->window()->windowType() == Qt::Desktop) /*&& !w->acceptDrops()*/)
+ w = 0;
+ } else {
+ w = 0;
+ target = rootwin;
+ }
+
+ DNDDEBUG << "and the final target is " << target;
+ DNDDEBUG << "the widget w is" << (w ? w->window() : 0);
+
+ xcb_window_t proxy_target = xdndProxy(connection(), target);
+ if (!proxy_target)
+ proxy_target = target;
+ int target_version = 1;
+
+ if (proxy_target) {
+ xcb_get_property_cookie_t cookie = xcb_get_property(xcb_connection(), false, target,
+ atom(QXcbAtom::XdndAware), XCB_GET_PROPERTY_TYPE_ANY, 0, 1);
+ xcb_get_property_reply_t *reply = xcb_get_property_reply(xcb_connection(), cookie, 0);
+ if (!reply || reply->type == XCB_NONE)
+ target = 0;
+ target_version = xcb_get_property_value_length(reply) == 1 ? *(uint32_t *)xcb_get_property_value(reply) : 1;
+ if (target_version > xdnd_version)
+ target_version = xdnd_version;
+
+ free(reply);
+ }
+
+ DEBUG() << "target=" << target << "current_target=" << current_target;
+ if (target != current_target) {
+ if (current_target)
+ send_leave();
+
+ current_target = target;
+ current_proxy_target = proxy_target;
+ if (target) {
+ int flags = target_version << 24;
+ if (drag_types.size() > 3)
+ flags |= 0x0001;
+
+ xcb_client_message_event_t enter;
+ enter.response_type = XCB_CLIENT_MESSAGE;
+ enter.window = target;
+ enter.format = 32;
+ enter.type = atom(QXcbAtom::XdndEnter);
+ enter.data.data32[0] = connection()->clipboard()->owner();
+ enter.data.data32[1] = flags;
+ enter.data.data32[2] = drag_types.size()>0 ? drag_types.at(0) : 0;
+ enter.data.data32[3] = drag_types.size()>1 ? drag_types.at(1) : 0;
+ enter.data.data32[4] = drag_types.size()>2 ? drag_types.at(2) : 0;
+ // provisionally set the rectangle to 5x5 pixels...
+ source_sameanswer = QRect(globalPos.x() - 2, globalPos.y() -2 , 5, 5);
+
+ DEBUG() << "sending Xdnd enter source=" << enter.data.data32[0];
+ if (w)
+ handleEnter(w->window(), &enter);
+ else if (target)
+ xcb_send_event(xcb_connection(), false, proxy_target, XCB_EVENT_MASK_NO_EVENT, (const char *)&enter);
+ waiting_for_status = false;
+ }
+ }
+ if (waiting_for_status)
+ return;
+
+ QDragManager *m = QDragManager::self();
+
+ if (target) {
+ waiting_for_status = true;
+
+ xcb_client_message_event_t move;
+ move.response_type = XCB_CLIENT_MESSAGE;
+ move.window = target;
+ move.format = 32;
+ move.type = atom(QXcbAtom::XdndPosition);
+ move.window = target;
+ move.data.data32[0] = connection()->clipboard()->owner();
+ move.data.data32[1] = 0; // flags
+ move.data.data32[2] = (globalPos.x() << 16) + globalPos.y();
+ move.data.data32[3] = connection()->time();
+ move.data.data32[4] = toXdndAction(m->defaultAction(m->dragPrivate()->possible_actions, QGuiApplication::keyboardModifiers()));
+ DEBUG() << "sending Xdnd position source=" << move.data.data32[0] << "target=" << move.window;
+
+ source_time = connection()->time();
+
+ if (w)
+ handle_xdnd_position(w->window(), &move, false);
+ else
+ xcb_send_event(xcb_connection(), false, proxy_target, XCB_EVENT_MASK_NO_EVENT, (const char *)&move);
+ } else {
+ if (m->willDrop) {
+ m->willDrop = false;
+ m->updateCursor();
+ }
+ }
+ DEBUG() << "QDragManager::move leave";
+}
+
+void QXcbDrag::drop(const QMouseEvent *)
+{
+ endDrag();
+
+ if (!current_target)
+ return;
+
+ xcb_client_message_event_t drop;
+ drop.response_type = XCB_CLIENT_MESSAGE;
+ drop.window = current_target;
+ drop.format = 32;
+ drop.type = atom(QXcbAtom::XdndDrop);
+ drop.data.data32[0] = connection()->clipboard()->owner();
+ drop.data.data32[1] = 0; // flags
+ drop.data.data32[2] = connection()->time();
+
+ drop.data.data32[3] = 0;
+ drop.data.data32[4] = 0;
+
+ QXcbWindow *w = connection()->platformWindowFromId(current_proxy_target);
+
+ if (w && (w->window()->windowType() == Qt::Desktop) /*&& !w->acceptDrops()*/)
+ w = 0;
+
+ QDragManager *manager = QDragManager::self();
+
+ Transaction t = {
+ connection()->time(),
+ current_target,
+ current_proxy_target,
+ (w ? w->window() : 0),
+// current_embedding_widget,
+ manager->object
+ };
+ transactions.append(t);
+ restartDropExpiryTimer();
+
+ if (w)
+ handleDrop(w->window(), &drop, false);
+ else
+ xcb_send_event(xcb_connection(), false, current_proxy_target, XCB_EVENT_MASK_NO_EVENT, (const char *)&drop);
+
+ current_target = 0;
+ current_proxy_target = 0;
+ source_time = 0;
+// current_embedding_widget = 0;
+ manager->object = 0;
+}
+
+Qt::DropAction QXcbDrag::toDropAction(xcb_atom_t a) const
+{
+ if (a == atom(QXcbAtom::XdndActionCopy) || a == 0)
+ return Qt::CopyAction;
+ if (a == atom(QXcbAtom::XdndActionLink))
+ return Qt::LinkAction;
+ if (a == atom(QXcbAtom::XdndActionMove))
+ return Qt::MoveAction;
+ return Qt::CopyAction;
+}
+
+xcb_atom_t QXcbDrag::toXdndAction(Qt::DropAction a) const
+{
+ switch (a) {
+ case Qt::CopyAction:
+ return atom(QXcbAtom::XdndActionCopy);
+ case Qt::LinkAction:
+ return atom(QXcbAtom::XdndActionLink);
+ case Qt::MoveAction:
+ case Qt::TargetMoveAction:
+ return atom(QXcbAtom::XdndActionMove);
+ case Qt::IgnoreAction:
+ return XCB_NONE;
+ default:
+ return atom(QXcbAtom::XdndActionCopy);
+ }
+}
+
+// timer used to discard old XdndDrop transactions
+enum { XdndDropTransactionTimeout = 5000 }; // 5 seconds
+
+void QXcbDrag::restartDropExpiryTimer()
+{
+ if (transaction_expiry_timer != -1)
+ killTimer(transaction_expiry_timer);
+ transaction_expiry_timer = startTimer(XdndDropTransactionTimeout);
+}
+
+int QXcbDrag::findTransactionByWindow(xcb_window_t window)
+{
+ int at = -1;
+ for (int i = 0; i < transactions.count(); ++i) {
+ const Transaction &t = transactions.at(i);
+ if (t.target == window || t.proxy_target == window) {
+ at = i;
+ break;
+ }
+ }
+ return at;
+}
+
+int QXcbDrag::findTransactionByTime(xcb_timestamp_t timestamp)
+{
+ int at = -1;
+ for (int i = 0; i < transactions.count(); ++i) {
+ const Transaction &t = transactions.at(i);
+ if (t.timestamp == timestamp) {
+ at = i;
+ break;
+ }
+ }
+ return at;
+}
+
+#if 0
+
+// find an ancestor with XdndAware on it
+static Window findXdndAwareParent(Window window)
+{
+ Window target = 0;
+ forever {
+ // check if window has XdndAware
+ Atom type = 0;
+ int f;
+ unsigned long n, a;
+ unsigned char *data = 0;
+ if (XGetWindowProperty(X11->display, window, ATOM(XdndAware), 0, 0, False,
+ AnyPropertyType, &type, &f,&n,&a,&data) == Success) {
+ if (data)
+ XFree(data);
+ if (type) {
+ target = window;
+ break;
+ }
+ }
+
+ // try window's parent
+ Window root;
+ Window parent;
+ Window *children;
+ uint unused;
+ if (!XQueryTree(X11->display, window, &root, &parent, &children, &unused))
+ break;
+ if (children)
+ XFree(children);
+ if (window == root)
+ break;
+ window = parent;
+ }
+ return target;
+}
+
+
+// for embedding only
+static QWidget* current_embedding_widget = 0;
+static xcb_client_message_event_t last_enter_event;
+
+
+static bool checkEmbedded(QWidget* w, const XEvent* xe)
+{
+ if (!w)
+ return false;
+
+ if (current_embedding_widget != 0 && current_embedding_widget != w) {
+ current_target = ((QExtraWidget*)current_embedding_widget)->extraData()->xDndProxy;
+ current_proxy_target = current_target;
+ qt_xdnd_send_leave();
+ current_target = 0;
+ current_proxy_target = 0;
+ current_embedding_widget = 0;
+ }
+
+ QWExtra* extra = ((QExtraWidget*)w)->extraData();
+ if (extra && extra->xDndProxy != 0) {
+
+ if (current_embedding_widget != w) {
+
+ last_enter_event.xany.window = extra->xDndProxy;
+ XSendEvent(X11->display, extra->xDndProxy, False, NoEventMask, &last_enter_event);
+ current_embedding_widget = w;
+ }
+
+ ((XEvent*)xe)->xany.window = extra->xDndProxy;
+ XSendEvent(X11->display, extra->xDndProxy, False, NoEventMask, (XEvent*)xe);
+ if (currentWindow != w) {
+ currentWindow = w;
+ }
+ return true;
+ }
+ current_embedding_widget = 0;
+ return false;
+}
+#endif
+
+
+void QXcbDrag::handleEnter(QWindow *window, const xcb_client_message_event_t *event)
+{
+ Q_UNUSED(window);
+ DEBUG() << "handleEnter" << window;
+
+ xdnd_types.clear();
+// motifdnd_active = false;
+// last_enter_event.xclient = xe->xclient;
+
+ int version = (int)(event->data.data32[1] >> 24);
+ if (version > xdnd_version)
+ return;
+
+ xdnd_dragsource = event->data.data32[0];
+
+ if (event->data.data32[1] & 1) {
+ // get the types from XdndTypeList
+ xcb_get_property_cookie_t cookie = xcb_get_property(xcb_connection(), false, xdnd_dragsource,
+ atom(QXcbAtom::XdndTypelist), XCB_ATOM_ATOM,
+ 0, xdnd_max_type);
+ xcb_get_property_reply_t *reply = xcb_get_property_reply(xcb_connection(), cookie, 0);
+ if (reply && reply->type != XCB_NONE && reply->format == 32) {
+ int length = xcb_get_property_value_length(reply) / 4;
+ if (length > xdnd_max_type)
+ length = xdnd_max_type;
+
+ xcb_atom_t *atoms = (xcb_atom_t *)xcb_get_property_value(reply);
+ for (int i = 0; i < length; ++i)
+ xdnd_types.append(atoms[i]);
+ }
+ free(reply);
+ } else {
+ // get the types from the message
+ for(int i = 2; i < 5; i++) {
+ if (event->data.data32[i])
+ xdnd_types.append(event->data.data32[i]);
+ }
+ }
+ for(int i = 0; i < xdnd_types.length(); ++i)
+ DEBUG() << " " << connection()->atomName(xdnd_types.at(i));
+}
+
+void QXcbDrag::handle_xdnd_position(QWindow *w, const xcb_client_message_event_t *e, bool passive)
+{
+ QPoint p((e->data.data32[2] & 0xffff0000) >> 16, e->data.data32[2] & 0x0000ffff);
+ Q_ASSERT(w);
+ QRect geometry = w->geometry();
+
+ p -= geometry.topLeft();
+
+ // ####
+// if (!passive && checkEmbedded(w, e))
+// return;
+
+ if (!w || (/*!w->acceptDrops() &&*/ (w->windowType() == Qt::Desktop)))
+ return;
+
+ if (e->data.data32[0] != xdnd_dragsource) {
+ DEBUG("xdnd drag position from unexpected source (%x not %x)", e->data.data32[0], xdnd_dragsource);
+ return;
+ }
+
+ // timestamp from the source
+ if (e->data.data32[3] != XCB_NONE)
+ target_time /*= X11->userTime*/ = e->data.data32[3];
+
+ QDragManager *manager = QDragManager::self();
+ QMimeData *dropData = manager->dropData();
+
+ xcb_client_message_event_t response;
+ response.response_type = XCB_CLIENT_MESSAGE;
+ response.window = xdnd_dragsource;
+ response.format = 32;
+ response.type = atom(QXcbAtom::XdndStatus);
+ response.data.data32[0] = xcb_window(w);
+ response.data.data32[1] = 0; // flags
+ response.data.data32[2] = 0; // x, y
+ response.data.data32[3] = 0; // w, h
+ response.data.data32[4] = 0; // action
+
+ if (!passive) { // otherwise just reject
+ QRect answerRect(p + geometry.topLeft(), QSize(1,1));
+
+ if (manager->object) {
+ manager->possible_actions = manager->dragPrivate()->possible_actions;
+ } else {
+ manager->possible_actions = Qt::DropActions(toDropAction(e->data.data32[4]));
+ }
+ QDragMoveEvent me(p, manager->possible_actions, dropData,
+ QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers());
+
+ Qt::DropAction accepted_action = Qt::IgnoreAction;
+
+ currentPosition = p;
+
+ if (w != currentWindow.data()) {
+ if (currentWindow) {
+ QDragLeaveEvent e;
+ QGuiApplication::sendEvent(currentWindow.data(), &e);
+ }
+ currentWindow = w;
+
+ last_target_accepted_action = Qt::IgnoreAction;
+ QDragEnterEvent de(p, manager->possible_actions, dropData,
+ QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers());
+ QGuiApplication::sendEvent(w, &de);
+ if (de.isAccepted() && de.dropAction() != Qt::IgnoreAction)
+ last_target_accepted_action = de.dropAction();
+ }
+
+ DEBUG() << "qt_handle_xdnd_position action=" << connection()->atomName(e->data.data32[4]);
+
+ if (last_target_accepted_action != Qt::IgnoreAction) {
+ me.setDropAction(last_target_accepted_action);
+ me.accept();
+ }
+ QGuiApplication::sendEvent(w, &me);
+ if (me.isAccepted()) {
+ response.data.data32[1] = 1; // yes
+ accepted_action = me.dropAction();
+ last_target_accepted_action = accepted_action;
+ } else {
+ response.data.data32[0] = 0;
+ last_target_accepted_action = Qt::IgnoreAction;
+ }
+ answerRect = me.answerRect().translated(geometry.topLeft()).intersected(geometry);
+
+ if (answerRect.left() < 0)
+ answerRect.setLeft(0);
+ if (answerRect.right() > 4096)
+ answerRect.setRight(4096);
+ if (answerRect.top() < 0)
+ answerRect.setTop(0);
+ if (answerRect.bottom() > 4096)
+ answerRect.setBottom(4096);
+ if (answerRect.width() < 0)
+ answerRect.setWidth(0);
+ if (answerRect.height() < 0)
+ answerRect.setHeight(0);
+
+// response.data.data32[2] = (answerRect.x() << 16) + answerRect.y();
+// response.data.data32[3] = (answerRect.width() << 16) + answerRect.height();
+ response.data.data32[4] = toXdndAction(accepted_action);
+ }
+
+ // reset
+ target_time = XCB_CURRENT_TIME;
+
+ DEBUG() << "sending XdndStatus" << (xdnd_dragsource == connection()->clipboard()->owner()) << xdnd_dragsource
+ << response.data.data32[1] << connection()->atomName(response.data.data32[4]);
+ if (xdnd_dragsource == connection()->clipboard()->owner())
+ handle_xdnd_status(&response, passive);
+ else
+ Q_XCB_CALL(xcb_send_event(xcb_connection(), false, xdnd_dragsource,
+ XCB_EVENT_MASK_NO_EVENT, (const char *)&response));
+}
+
+namespace
+{
+ class ClientMessageScanner {
+ public:
+ ClientMessageScanner(xcb_atom_t a) : atom(a) {}
+ xcb_atom_t atom;
+ bool check(xcb_generic_event_t *event) const {
+ if (!event)
+ return false;
+ if ((event->response_type & 0x7f) != XCB_CLIENT_MESSAGE)
+ return false;
+ return ((xcb_client_message_event_t *)event)->type == atom;
+ }
+ };
+}
+
+void QXcbDrag::handlePosition(QWindow * w, const xcb_client_message_event_t *event, bool passive)
+{
+ xcb_client_message_event_t *lastEvent = const_cast<xcb_client_message_event_t *>(event);
+ xcb_generic_event_t *nextEvent;
+ ClientMessageScanner scanner(atom(QXcbAtom::XdndPosition));
+ while ((nextEvent = connection()->checkEvent(scanner))) {
+ if (lastEvent != event)
+ free(lastEvent);
+ lastEvent = (xcb_client_message_event_t *)nextEvent;
+ }
+
+ handle_xdnd_position(w, lastEvent, passive);
+ if (lastEvent != event)
+ free(lastEvent);
+}
+
+void QXcbDrag::handle_xdnd_status(const xcb_client_message_event_t *event, bool)
+{
+ DEBUG("xdndHandleStatus");
+ // ignore late status messages
+ if (event->data.data32[0] && event->data.data32[0] != current_proxy_target)
+ return;
+
+ Qt::DropAction newAction = (event->data.data32[1] & 0x1) ? toDropAction(event->data.data32[4]) : Qt::IgnoreAction;
+
+ if ((event->data.data32[1] & 2) == 0) {
+ QPoint p((event->data.data32[2] & 0xffff0000) >> 16, event->data.data32[2] & 0x0000ffff);
+ QSize s((event->data.data32[3] & 0xffff0000) >> 16, event->data.data32[3] & 0x0000ffff);
+ source_sameanswer = QRect(p, s);
+ } else {
+ source_sameanswer = QRect();
+ }
+ QDragManager *manager = QDragManager::self();
+ manager->willDrop = (event->data.data32[1] & 0x1);
+ if (manager->global_accepted_action != newAction) {
+ manager->global_accepted_action = newAction;
+ manager->emitActionChanged(newAction);
+ }
+ DEBUG() << "willDrop=" << manager->willDrop << "action=" << newAction;
+ manager->updateCursor();
+ waiting_for_status = false;
+}
+
+void QXcbDrag::handleStatus(const xcb_client_message_event_t *event, bool passive)
+{
+ if (event->window != connection()->clipboard()->owner())
+ return;
+
+ xcb_client_message_event_t *lastEvent = const_cast<xcb_client_message_event_t *>(event);
+ qDebug() << "handleStatus" << lastEvent->window << lastEvent->data.data32[0];
+ xcb_generic_event_t *nextEvent;
+ ClientMessageScanner scanner(atom(QXcbAtom::XdndStatus));
+ while ((nextEvent = connection()->checkEvent(scanner))) {
+ if (lastEvent != event)
+ free(lastEvent);
+ lastEvent = (xcb_client_message_event_t *)nextEvent;
+ }
+
+ handle_xdnd_status(lastEvent, passive);
+ if (lastEvent != event)
+ free(lastEvent);
+ DEBUG("xdndHandleStatus end");
+}
+
+void QXcbDrag::handleLeave(QWindow *w, const xcb_client_message_event_t *event, bool /*passive*/)
+{
+ DEBUG("xdnd leave");
+ if (!currentWindow || w != currentWindow.data())
+ return; // sanity
+
+ // ###
+// if (checkEmbedded(current_embedding_widget, event)) {
+// current_embedding_widget = 0;
+// currentWindow.clear();
+// return;
+// }
+
+ if (event->data.data32[0] != xdnd_dragsource) {
+ // This often happens - leave other-process window quickly
+ DEBUG("xdnd drag leave from unexpected source (%x not %x", event->data.data32[0], xdnd_dragsource);
+ }
+
+ QDragLeaveEvent e;
+ QGuiApplication::sendEvent(currentWindow.data(), &e);
+
+ xdnd_dragsource = 0;
+ xdnd_types.clear();
+ currentWindow.clear();
+}
+
+void QXcbDrag::send_leave()
+{
+ if (!current_target)
+ return;
+
+ QDragManager *manager = QDragManager::self();
+
+ xcb_client_message_event_t leave;
+ leave.response_type = XCB_CLIENT_MESSAGE;
+ leave.window = current_target;
+ leave.format = 32;
+ leave.type = atom(QXcbAtom::XdndLeave);
+ leave.data.data32[0] = connection()->clipboard()->owner();
+ leave.data.data32[1] = 0; // flags
+ leave.data.data32[2] = 0; // x, y
+ leave.data.data32[3] = 0; // w, h
+ leave.data.data32[4] = 0; // just null
+
+ QXcbWindow *w = connection()->platformWindowFromId(current_proxy_target);
+
+ if (w && (w->window()->windowType() == Qt::Desktop) /*&& !w->acceptDrops()*/)
+ w = 0;
+
+ if (w)
+ handleLeave(w->window(), (const xcb_client_message_event_t *)&leave, false);
+ else
+ xcb_send_event(xcb_connection(), false,current_proxy_target,
+ XCB_EVENT_MASK_NO_EVENT, (const char *)&leave);
+
+ // reset the drag manager state
+ manager->willDrop = false;
+ if (manager->global_accepted_action != Qt::IgnoreAction)
+ manager->emitActionChanged(Qt::IgnoreAction);
+ manager->global_accepted_action = Qt::IgnoreAction;
+ manager->updateCursor();
+ current_target = 0;
+ current_proxy_target = 0;
+ source_time = XCB_CURRENT_TIME;
+ waiting_for_status = false;
+}
+
+void QXcbDrag::handleDrop(QWindow *, const xcb_client_message_event_t *event, bool passive)
+{
+ DEBUG("xdndHandleDrop");
+ if (!currentWindow) {
+ xdnd_dragsource = 0;
+ return; // sanity
+ }
+
+ // ###
+// if (!passive && checkEmbedded(currentWindow, xe)){
+// current_embedding_widget = 0;
+// xdnd_dragsource = 0;
+// currentWindow = 0;
+// return;
+// }
+ const uint32_t *l = event->data.data32;
+
+ QDragManager *manager = QDragManager::self();
+ DEBUG("xdnd drop");
+
+ if (l[0] != xdnd_dragsource) {
+ DEBUG("xdnd drop from unexpected source (%x not %x", l[0], xdnd_dragsource);
+ return;
+ }
+
+ // update the "user time" from the timestamp in the event.
+ if (l[2] != 0)
+ target_time = /*X11->userTime =*/ l[2];
+
+ if (!passive) {
+ // this could be a same-application drop, just proxied due to
+ // some XEMBEDding, so try to find the real QMimeData used
+ // based on the timestamp for this drop.
+ QMimeData *dropData = 0;
+ // ###
+// int at = findXdndDropTransactionByTime(target_time);
+// if (at != -1)
+// dropData = QDragManager::dragPrivate(X11->dndDropTransactions.at(at).object)->data;
+ // if we can't find it, then use the data in the drag manager
+ if (!dropData)
+ dropData = manager->dropData();
+
+ // Drop coming from another app? Update keyboard modifiers.
+// if (!qt_xdnd_dragging) {
+// QApplicationPrivate::modifier_buttons = currentKeyboardModifiers();
+// }
+
+ QDropEvent de(currentPosition, manager->possible_actions, dropData,
+ QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers());
+ QGuiApplication::sendEvent(currentWindow.data(), &de);
+ if (!de.isAccepted()) {
+ // Ignore a failed drag
+ manager->global_accepted_action = Qt::IgnoreAction;
+ } else {
+ manager->global_accepted_action = de.dropAction();
+ }
+ xcb_client_message_event_t finished;
+ finished.response_type = XCB_CLIENT_MESSAGE;
+ finished.window = xdnd_dragsource;
+ finished.format = 32;
+ finished.type = atom(QXcbAtom::XdndFinished);
+ DNDDEBUG << "xdndHandleDrop"
+ << "currentWindow" << currentWindow.data()
+ << (currentWindow ? xcb_window(currentWindow.data()) : 0);
+ finished.data.data32[0] = currentWindow ? xcb_window(currentWindow.data()) : XCB_NONE;
+ finished.data.data32[1] = de.isAccepted() ? 1 : 0; // flags
+ finished.data.data32[2] = toXdndAction(manager->global_accepted_action);
+ Q_XCB_CALL(xcb_send_event(xcb_connection(), false, xdnd_dragsource,
+ XCB_EVENT_MASK_NO_EVENT, (char *)&finished));
+ } else {
+ QDragLeaveEvent e;
+ QGuiApplication::sendEvent(currentWindow.data(), &e);
+ }
+ xdnd_dragsource = 0;
+ currentWindow.clear();
+ waiting_for_status = false;
+
+ // reset
+ target_time = XCB_CURRENT_TIME;
+}
+
+
+void QXcbDrag::handleFinished(const xcb_client_message_event_t *event, bool)
+{
+ DEBUG("xdndHandleFinished");
+ if (event->window != connection()->clipboard()->owner())
+ return;
+
+ const unsigned long *l = (const unsigned long *)event->data.data32;
+
+ DNDDEBUG << "xdndHandleFinished, l[0]" << l[0]
+ << "current_target" << current_target
+ << "qt_xdnd_current_proxy_targe" << current_proxy_target;
+
+ if (l[0]) {
+ int at = findTransactionByWindow(l[0]);
+ if (at != -1) {
+ restartDropExpiryTimer();
+
+ Transaction t = transactions.takeAt(at);
+// QDragManager *manager = QDragManager::self();
+
+// Window target = current_target;
+// Window proxy_target = current_proxy_target;
+// QWidget *embedding_widget = current_embedding_widget;
+// QDrag *currentObject = manager->object;
+
+// current_target = t.target;
+// current_proxy_target = t.proxy_target;
+// current_embedding_widget = t.embedding_widget;
+// manager->object = t.object;
+
+// if (!passive)
+// (void) checkEmbedded(currentWindow, xe);
+
+// current_embedding_widget = 0;
+// current_target = 0;
+// current_proxy_target = 0;
+
+ if (t.object)
+ t.object->deleteLater();
+
+// current_target = target;
+// current_proxy_target = proxy_target;
+// current_embedding_widget = embedding_widget;
+// manager->object = currentObject;
+ }
+ }
+ waiting_for_status = false;
+}
+
+
+void QXcbDrag::timerEvent(QTimerEvent* e)
+{
+ if (e->timerId() == heartbeat && source_sameanswer.isNull()) {
+ QPointF pos = QCursor::pos();
+ QMouseEvent me(QEvent::MouseMove, pos, pos, pos, Qt::LeftButton,
+ QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers());
+ move(&me);
+ } else if (e->timerId() == transaction_expiry_timer) {
+ for (int i = 0; i < transactions.count(); ++i) {
+ const Transaction &t = transactions.at(i);
+ if (t.targetWindow) {
+ // dnd within the same process, don't delete these
+ continue;
+ }
+ t.object->deleteLater();
+ transactions.removeAt(i--);
+ }
+
+ killTimer(transaction_expiry_timer);
+ transaction_expiry_timer = -1;
+ }
+}
+
+void QXcbDrag::cancel()
+{
+ DEBUG("QXcbDrag::cancel");
+ endDrag();
+
+ if (current_target)
+ send_leave();
+
+ current_target = 0;
+}
+
+#if 0
+
+static
+Window findRealWindow(const QPoint & pos, Window w, int md)
+{
+ if (xdnd_data.deco && w == xdnd_data.deco->effectiveWinId())
+ return 0;
+
+ if (md) {
+ X11->ignoreBadwindow();
+ XWindowAttributes attr;
+ XGetWindowAttributes(X11->display, w, &attr);
+ if (X11->badwindow())
+ return 0;
+
+ if (attr.map_state == IsViewable
+ && QRect(attr.x,attr.y,attr.width,attr.height).contains(pos)) {
+ {
+ Atom type = XNone;
+ int f;
+ unsigned long n, a;
+ unsigned char *data;
+
+ XGetWindowProperty(X11->display, w, ATOM(XdndAware), 0, 0, False,
+ AnyPropertyType, &type, &f,&n,&a,&data);
+ if (data) XFree(data);
+ if (type)
+ return w;
+ }
+
+ Window r, p;
+ Window* c;
+ uint nc;
+ if (XQueryTree(X11->display, w, &r, &p, &c, &nc)) {
+ r=0;
+ for (uint i=nc; !r && i--;) {
+ r = findRealWindow(pos-QPoint(attr.x,attr.y),
+ c[i], md-1);
+ }
+ XFree(c);
+ if (r)
+ return r;
+
+ // We didn't find a client window! Just use the
+ // innermost window.
+ }
+
+ // No children!
+ return w;
+ }
+ }
+ return 0;
+}
+#endif
+
+void QXcbDrag::handleSelectionRequest(const xcb_selection_request_event_t *event)
+{
+ xcb_selection_notify_event_t notify;
+ notify.response_type = XCB_SELECTION_NOTIFY;
+ notify.requestor = event->requestor;
+ notify.selection = event->selection;
+ notify.target = XCB_NONE;
+ notify.property = XCB_NONE;
+ notify.time = event->time;
+
+ QDragManager *manager = QDragManager::self();
+ QDrag *currentObject = manager->object;
+
+ // which transaction do we use? (note: -2 means use current manager->object)
+ int at = -1;
+
+ // figure out which data the requestor is really interested in
+ if (manager->object && event->time == source_time) {
+ // requestor wants the current drag data
+ at = -2;
+ } else {
+ // if someone has requested data in response to XdndDrop, find the corresponding transaction. the
+ // spec says to call XConvertSelection() using the timestamp from the XdndDrop
+ at = findTransactionByTime(event->time);
+ if (at == -1) {
+ // no dice, perhaps the client was nice enough to use the same window id in XConvertSelection()
+ // that we sent the XdndDrop event to.
+ at = findTransactionByWindow(event->requestor);
+ }
+// if (at == -1 && event->time == XCB_CURRENT_TIME) {
+// // previous Qt versions always requested the data on a child of the target window
+// // using CurrentTime... but it could be asking for either drop data or the current drag's data
+// Window target = findXdndAwareParent(event->requestor);
+// if (target) {
+// if (current_target && current_target == target)
+// at = -2;
+// else
+// at = findXdndDropTransactionByWindow(target);
+// }
+// }
+ }
+ if (at >= 0) {
+ restartDropExpiryTimer();
+
+ // use the drag object from an XdndDrop tansaction
+ manager->object = transactions.at(at).object;
+ } else if (at != -2) {
+ // no transaction found, we'll have to reject the request
+ manager->object = 0;
+ }
+ if (manager->object) {
+ xcb_atom_t atomFormat = event->target;
+ int dataFormat = 0;
+ QByteArray data;
+ if (QXcbMime::mimeDataForAtom(connection(), event->target, manager->dragPrivate()->data,
+ &data, &atomFormat, &dataFormat)) {
+ int dataSize = data.size() / (dataFormat / 8);
+ xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, event->requestor, event->property,
+ atomFormat, dataFormat, dataSize, (const void *)data.constData());
+ notify.property = event->property;
+ notify.target = atomFormat;
+ }
+ }
+
+ // reset manager->object in case we modified it above
+ manager->object = currentObject;
+
+ xcb_send_event(xcb_connection(), false, event->requestor, XCB_EVENT_MASK_NO_EVENT, (const char *)&notify);
+}
+
+
+bool QXcbDrag::dndEnable(QXcbWindow *w, bool on)
+{
+ DNDDEBUG << "xdndEnable" << w << on;
+ if (on) {
+ QXcbWindow *xdnd_widget = 0;
+ if ((w->window()->windowType() == Qt::Desktop)) {
+ if (desktop_proxy) // *WE* already have one.
+ return false;
+
+ xcb_grab_server(xcb_connection());
+
+ // As per Xdnd4, use XdndProxy
+ xcb_window_t proxy_id = xdndProxy(connection(), w->xcb_window());
+
+ if (!proxy_id) {
+ desktop_proxy = new QWindow;
+ xdnd_widget = static_cast<QXcbWindow *>(desktop_proxy->handle());
+ proxy_id = xdnd_widget->xcb_window();
+ xcb_atom_t xdnd_proxy = atom(QXcbAtom::XdndProxy);
+ xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, w->xcb_window(), xdnd_proxy,
+ XCB_ATOM_WINDOW, 32, 1, &proxy_id);
+ xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, proxy_id, xdnd_proxy,
+ XCB_ATOM_WINDOW, 32, 1, &proxy_id);
+ }
+
+ xcb_ungrab_server(xcb_connection());
+ } else {
+ xdnd_widget = w;
+ }
+ if (xdnd_widget) {
+ DNDDEBUG << "setting XdndAware for" << xdnd_widget << xdnd_widget->xcb_window();
+ xcb_atom_t atm = xdnd_version;
+ xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, xdnd_widget->xcb_window(),
+ atom(QXcbAtom::XdndAware), XCB_ATOM_ATOM, 32, 1, &atm);
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ if ((w->window()->windowType() == Qt::Desktop)) {
+ xcb_delete_property(xcb_connection(), w->xcb_window(), atom(QXcbAtom::XdndProxy));
+ delete desktop_proxy;
+ desktop_proxy = 0;
+ } else {
+ DNDDEBUG << "not deleting XDndAware";
+ }
+ return true;
+ }
+}
+
+
+
+
+QDropData::QDropData(QXcbDrag *d)
+ : QXcbMime(),
+ drag(d)
+{
+}
+
+QDropData::~QDropData()
+{
+}
+
+QVariant QDropData::retrieveData_sys(const QString &mimetype, QVariant::Type requestedType) const
+{
+ QByteArray mime = mimetype.toLatin1();
+ QVariant data = /*X11->motifdnd_active
+ ? X11->motifdndObtainData(mime)
+ :*/ xdndObtainData(mime, requestedType);
+ return data;
+}
+
+QVariant QDropData::xdndObtainData(const QByteArray &format, QVariant::Type requestedType) const
+{
+ QByteArray result;
+
+ QDragManager *manager = QDragManager::self();
+ QXcbConnection *c = drag->connection();
+ QXcbWindow *xcb_window = c->platformWindowFromId(drag->xdnd_dragsource);
+ if (xcb_window && manager->object && xcb_window->window()->windowType() != Qt::Desktop) {
+ QDragPrivate *o = manager->dragPrivate();
+ if (o->data->hasFormat(QLatin1String(format)))
+ result = o->data->data(QLatin1String(format));
+ return result;
+ }
+
+ QList<xcb_atom_t> atoms = drag->xdnd_types;
+ QByteArray encoding;
+ xcb_atom_t a = mimeAtomForFormat(c, QLatin1String(format), requestedType, atoms, &encoding);
+ if (a == XCB_NONE)
+ return result;
+
+ if (c->clipboard()->getSelectionOwner(drag->atom(QXcbAtom::XdndSelection)) == XCB_NONE)
+ return result; // should never happen?
+
+ xcb_atom_t xdnd_selection = c->atom(QXcbAtom::XdndSelection);
+ result = c->clipboard()->getSelection(xdnd_selection, a, xdnd_selection);
+
+ return mimeConvertToFormat(c, a, result, QLatin1String(format), requestedType, encoding);
+}
+
+
+bool QDropData::hasFormat_sys(const QString &format) const
+{
+ return formats().contains(format);
+}
+
+QStringList QDropData::formats_sys() const
+{
+ QStringList formats;
+// if (X11->motifdnd_active) {
+// int i = 0;
+// QByteArray fmt;
+// while (!(fmt = X11->motifdndFormat(i)).isEmpty()) {
+// formats.append(QLatin1String(fmt));
+// ++i;
+// }
+// } else {
+ for (int i = 0; i < drag->xdnd_types.size(); ++i) {
+ QString f = mimeAtomToString(drag->connection(), drag->xdnd_types.at(i));
+ if (!formats.contains(f))
+ formats.append(f);
+ }
+// }
+ return formats;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/qxcbdrag.h b/src/plugins/platforms/xcb/qxcbdrag.h
new file mode 100644
index 0000000000..ce0f8faa54
--- /dev/null
+++ b/src/plugins/platforms/xcb/qxcbdrag.h
@@ -0,0 +1,158 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QXCBDRAG_H
+#define QXCBDRAG_H
+
+#include <qplatformdrag_qpa.h>
+#include <qxcbobject.h>
+#include <xcb/xcb.h>
+#include <qlist.h>
+#include <qpoint.h>
+#include <qrect.h>
+#include <qsharedpointer.h>
+#include <qvector.h>
+
+QT_BEGIN_NAMESPACE
+
+class QMouseEvent;
+class QWindow;
+class QXcbConnection;
+class QXcbWindow;
+class QDropData;
+class QXcbScreen;
+class QDrag;
+
+class QXcbDrag : public QObject, public QXcbObject, public QPlatformDrag
+{
+public:
+ QXcbDrag(QXcbConnection *c);
+ ~QXcbDrag();
+
+ virtual QMimeData *platformDropData();
+
+// virtual Qt::DropAction drag(QDrag *);
+
+ virtual void startDrag();
+ virtual void cancel();
+ virtual void move(const QMouseEvent *me);
+ virtual void drop(const QMouseEvent *me);
+ void endDrag();
+
+ void handleEnter(QWindow *window, const xcb_client_message_event_t *event);
+ void handlePosition(QWindow *w, const xcb_client_message_event_t *event, bool passive);
+ void handleLeave(QWindow *w, const xcb_client_message_event_t *event, bool /*passive*/);
+ void handleDrop(QWindow *, const xcb_client_message_event_t *event, bool passive);
+
+ void handleStatus(const xcb_client_message_event_t *event, bool passive);
+ void handleSelectionRequest(const xcb_selection_request_event_t *event);
+ void handleFinished(const xcb_client_message_event_t *event, bool passive);
+
+ bool dndEnable(QXcbWindow *win, bool on);
+
+protected:
+ void timerEvent(QTimerEvent* e);
+
+private:
+ friend class QDropData;
+
+ void init();
+
+ void handle_xdnd_position(QWindow *w, const xcb_client_message_event_t *event, bool passive);
+ void handle_xdnd_status(const xcb_client_message_event_t *event, bool);
+ void send_leave();
+
+ Qt::DropAction toDropAction(xcb_atom_t atom) const;
+ xcb_atom_t toXdndAction(Qt::DropAction a) const;
+
+ QWeakPointer<QWindow> currentWindow;
+ QPoint currentPosition;
+
+ QDropData *dropData;
+
+ QWindow *desktop_proxy;
+
+ xcb_atom_t xdnd_dragsource;
+
+ // the types in this drop. 100 is no good, but at least it's big.
+ enum { xdnd_max_type = 100 };
+ QList<xcb_atom_t> xdnd_types;
+
+ xcb_timestamp_t target_time;
+ xcb_timestamp_t source_time;
+ Qt::DropAction last_target_accepted_action;
+
+ // rectangle in which the answer will be the same
+ QRect source_sameanswer;
+ bool waiting_for_status;
+
+ // top-level window we sent position to last.
+ xcb_window_t current_target;
+ // window to send events to (always valid if current_target)
+ xcb_window_t current_proxy_target;
+
+ QXcbScreen *current_screen;
+
+ int heartbeat;
+ bool xdnd_dragging;
+
+ QVector<xcb_atom_t> drag_types;
+
+ struct Transaction
+ {
+ xcb_timestamp_t timestamp;
+ xcb_window_t target;
+ xcb_window_t proxy_target;
+ QWindow *targetWindow;
+// QWidget *embedding_widget;
+ QDrag *object;
+ };
+ QList<Transaction> transactions;
+
+ int transaction_expiry_timer;
+ void restartDropExpiryTimer();
+ int findTransactionByWindow(xcb_window_t window);
+ int findTransactionByTime(xcb_timestamp_t timestamp);
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/platforms/xcb/qxcbeglsurface.h b/src/plugins/platforms/xcb/qxcbeglsurface.h
new file mode 100644
index 0000000000..a1e6c148a2
--- /dev/null
+++ b/src/plugins/platforms/xcb/qxcbeglsurface.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QXCBEGLSURFACE_H
+#define QXCBEGLSURFACE_H
+
+#include <EGL/egl.h>
+
+class QXcbEGLSurface
+{
+public:
+ QXcbEGLSurface(EGLDisplay display, EGLSurface surface)
+ : m_display(display)
+ , m_surface(surface)
+ {
+ }
+
+ ~QXcbEGLSurface()
+ {
+ eglDestroySurface(m_display, m_surface);
+ }
+
+ EGLSurface surface() const { return m_surface; }
+
+private:
+ EGLDisplay m_display;
+ EGLSurface m_surface;
+};
+
+#endif
diff --git a/src/plugins/platforms/xcb/qxcbimage.cpp b/src/plugins/platforms/xcb/qxcbimage.cpp
new file mode 100644
index 0000000000..569e4fc4e4
--- /dev/null
+++ b/src/plugins/platforms/xcb/qxcbimage.cpp
@@ -0,0 +1,266 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxcbimage.h"
+#include <QtGui/QColor>
+#include <QtGui/private/qimage_p.h>
+#include <QtGui/private/qdrawhelper_p.h>
+#ifdef XCB_USE_RENDER
+#include <xcb/render.h>
+// 'template' is used as a function argument name in xcb_renderutil.h
+#define template template_param
+// extern "C" is missing too
+extern "C" {
+#include <xcb/xcb_renderutil.h>
+}
+#undef template
+#endif
+
+QT_BEGIN_NAMESPACE
+
+QImage::Format qt_xcb_imageFormatForVisual(QXcbConnection *connection, uint8_t depth,
+ const xcb_visualtype_t *visual)
+{
+ const xcb_format_t *format = connection->formatForDepth(depth);
+
+ if (!visual || !format)
+ return QImage::Format_Invalid;
+
+ if (depth == 32 && format->bits_per_pixel == 32 && visual->red_mask == 0xff0000
+ && visual->green_mask == 0xff00 && visual->blue_mask == 0xff)
+ return QImage::Format_ARGB32_Premultiplied;
+
+ if (depth == 24 && format->bits_per_pixel == 32 && visual->red_mask == 0xff0000
+ && visual->green_mask == 0xff00 && visual->blue_mask == 0xff)
+ return QImage::Format_RGB32;
+
+ if (depth == 16 && format->bits_per_pixel == 16 && visual->red_mask == 0xf800
+ && visual->green_mask == 0x7e0 && visual->blue_mask == 0x1f)
+ return QImage::Format_RGB16;
+
+ return QImage::Format_Invalid;
+}
+
+QPixmap qt_xcb_pixmapFromXPixmap(QXcbConnection *connection, xcb_pixmap_t pixmap,
+ int width, int height, int depth,
+ const xcb_visualtype_t *visual)
+{
+ xcb_connection_t *conn = connection->xcb_connection();
+ xcb_generic_error_t *error = 0;
+
+ xcb_get_image_cookie_t get_image_cookie =
+ xcb_get_image(conn, XCB_IMAGE_FORMAT_Z_PIXMAP, pixmap,
+ 0, 0, width, height, 0xffffffff);
+
+ xcb_get_image_reply_t *image_reply =
+ xcb_get_image_reply(conn, get_image_cookie, &error);
+
+ if (!image_reply) {
+ if (error) {
+ connection->handleXcbError(error);
+ free(error);
+ }
+ return QPixmap();
+ }
+
+ uint8_t *data = xcb_get_image_data(image_reply);
+ uint32_t length = xcb_get_image_data_length(image_reply);
+
+ QPixmap result;
+
+ QImage::Format format = qt_xcb_imageFormatForVisual(connection, depth, visual);
+ if (format != QImage::Format_Invalid) {
+ uint32_t bytes_per_line = length / height;
+ QImage image(const_cast<uint8_t *>(data), width, height, bytes_per_line, format);
+ uint8_t image_byte_order = connection->setup()->image_byte_order;
+
+ // we may have to swap the byte order
+ if ((QSysInfo::ByteOrder == QSysInfo::LittleEndian && image_byte_order == XCB_IMAGE_ORDER_MSB_FIRST)
+ || (QSysInfo::ByteOrder == QSysInfo::BigEndian && image_byte_order == XCB_IMAGE_ORDER_LSB_FIRST))
+ {
+ for (int i=0; i < image.height(); i++) {
+ switch (format) {
+ case QImage::Format_RGB16: {
+ ushort *p = (ushort*)image.scanLine(i);
+ ushort *end = p + image.width();
+ while (p < end) {
+ *p = ((*p << 8) & 0xff00) | ((*p >> 8) & 0x00ff);
+ p++;
+ }
+ break;
+ }
+ case QImage::Format_RGB32: // fall-through
+ case QImage::Format_ARGB32_Premultiplied: {
+ uint *p = (uint*)image.scanLine(i);
+ uint *end = p + image.width();
+ while (p < end) {
+ *p = ((*p << 24) & 0xff000000) | ((*p << 8) & 0x00ff0000)
+ | ((*p >> 8) & 0x0000ff00) | ((*p >> 24) & 0x000000ff);
+ p++;
+ }
+ break;
+ }
+ default:
+ Q_ASSERT(false);
+ }
+ }
+ }
+
+ // fix-up alpha channel
+ if (format == QImage::Format_RGB32) {
+ QRgb *p = (QRgb *)image.bits();
+ for (int y = 0; y < height; ++y) {
+ for (int x = 0; x < width; ++x)
+ p[x] |= 0xff000000;
+ p += bytes_per_line / 4;
+ }
+ }
+
+ result = QPixmap::fromImage(image.copy());
+ }
+
+ free(image_reply);
+ return result;
+}
+
+xcb_pixmap_t qt_xcb_XPixmapFromBitmap(QXcbScreen *screen, const QImage &image)
+{
+ xcb_connection_t *conn = screen->xcb_connection();
+ QImage bitmap = image.convertToFormat(QImage::Format_MonoLSB);
+ const QRgb c0 = QColor(Qt::black).rgb();
+ const QRgb c1 = QColor(Qt::white).rgb();
+ if (bitmap.color(0) == c0 && bitmap.color(1) == c1) {
+ bitmap.invertPixels();
+ bitmap.setColor(0, c1);
+ bitmap.setColor(1, c0);
+ }
+ const int width = bitmap.width();
+ const int height = bitmap.height();
+ const int bytesPerLine = bitmap.bytesPerLine();
+ int destLineSize = width / 8;
+ if (width % 8)
+ ++destLineSize;
+ const uchar *map = bitmap.bits();
+ uint8_t *buf = new uint8_t[height * destLineSize];
+ for (int i = 0; i < height; i++)
+ memcpy(buf + (destLineSize * i), map + (bytesPerLine * i), destLineSize);
+ xcb_pixmap_t pm = xcb_create_pixmap_from_bitmap_data(conn, screen->root(), buf,
+ width, height, 1, 0, 0, 0);
+ delete[] buf;
+ return pm;
+}
+
+xcb_cursor_t qt_xcb_createCursorXRender(QXcbScreen *screen, const QImage &image,
+ const QPoint &spot)
+{
+#ifdef XCB_USE_RENDER
+ xcb_connection_t *conn = screen->xcb_connection();
+ const int w = image.width();
+ const int h = image.height();
+ xcb_generic_error_t *error = 0;
+ xcb_render_query_pict_formats_cookie_t formatsCookie = xcb_render_query_pict_formats(conn);
+ xcb_render_query_pict_formats_reply_t *formatsReply = xcb_render_query_pict_formats_reply(conn,
+ formatsCookie,
+ &error);
+ if (!formatsReply || error) {
+ qWarning("createCursorXRender: query_pict_formats failed");
+ free(formatsReply);
+ free(error);
+ return XCB_NONE;
+ }
+ xcb_render_pictforminfo_t *fmt = xcb_render_util_find_standard_format(formatsReply,
+ XCB_PICT_STANDARD_ARGB_32);
+ if (!fmt) {
+ qWarning("createCursorXRender: Failed to find format PICT_STANDARD_ARGB_32");
+ free(formatsReply);
+ return XCB_NONE;
+ }
+
+ QImage img = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
+ xcb_image_t *xi = xcb_image_create(w, h, XCB_IMAGE_FORMAT_Z_PIXMAP,
+ 32, 32, 32, 32,
+ QSysInfo::ByteOrder == QSysInfo::BigEndian ? XCB_IMAGE_ORDER_MSB_FIRST : XCB_IMAGE_ORDER_LSB_FIRST,
+ XCB_IMAGE_ORDER_MSB_FIRST,
+ 0, 0, 0);
+ if (!xi) {
+ qWarning("createCursorXRender: xcb_image_create failed");
+ free(formatsReply);
+ return XCB_NONE;
+ }
+ xi->data = (uint8_t *) malloc(xi->stride * h);
+ if (!xi->data) {
+ qWarning("createCursorXRender: Failed to malloc() image data");
+ xcb_image_destroy(xi);
+ free(formatsReply);
+ return XCB_NONE;
+ }
+ memcpy(xi->data, img.constBits(), img.byteCount());
+
+ xcb_pixmap_t pix = xcb_generate_id(conn);
+ xcb_create_pixmap(conn, 32, pix, screen->root(), w, h);
+
+ xcb_render_picture_t pic = xcb_generate_id(conn);
+ xcb_render_create_picture(conn, pic, pix, fmt->id, 0, 0);
+
+ xcb_gcontext_t gc = xcb_generate_id(conn);
+ xcb_create_gc(conn, gc, pix, 0, 0);
+ xcb_image_put(conn, pix, gc, xi, 0, 0, 0);
+ xcb_free_gc(conn, gc);
+
+ xcb_cursor_t cursor = xcb_generate_id(conn);
+ xcb_render_create_cursor(conn, cursor, pic, spot.x(), spot.y());
+
+ free(xi->data);
+ xcb_image_destroy(xi);
+ xcb_render_free_picture(conn, pic);
+ xcb_free_pixmap(conn, pix);
+ free(formatsReply);
+ return cursor;
+
+#else
+ Q_UNUSED(screen);
+ Q_UNUSED(image);
+ Q_UNUSED(spot);
+ return XCB_NONE;
+#endif
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/qxcbimage.h b/src/plugins/platforms/xcb/qxcbimage.h
new file mode 100644
index 0000000000..1e7f104084
--- /dev/null
+++ b/src/plugins/platforms/xcb/qxcbimage.h
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QXCBIMAGE_H
+#define QXCBIMAGE_H
+
+#include "qxcbscreen.h"
+#include <QtCore/QPair>
+#include <QtGui/QImage>
+#include <QtGui/QPixmap>
+#include <xcb/xcb_image.h>
+
+QT_BEGIN_NAMESPACE
+
+QImage::Format qt_xcb_imageFormatForVisual(QXcbConnection *connection,
+ uint8_t depth, const xcb_visualtype_t *visual);
+QPixmap qt_xcb_pixmapFromXPixmap(QXcbConnection *connection, xcb_pixmap_t pixmap,
+ int width, int height, int depth,
+ const xcb_visualtype_t *visual);
+xcb_pixmap_t qt_xcb_XPixmapFromBitmap(QXcbScreen *screen, const QImage &image);
+xcb_cursor_t qt_xcb_createCursorXRender(QXcbScreen *screen, const QImage &image,
+ const QPoint &spot);
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp
index 12b63f36ea..b0d377bcac 100644
--- a/src/plugins/platforms/xcb/qxcbintegration.cpp
+++ b/src/plugins/platforms/xcb/qxcbintegration.cpp
@@ -43,76 +43,161 @@
#include "qxcbconnection.h"
#include "qxcbscreen.h"
#include "qxcbwindow.h"
-#include "qxcbwindowsurface.h"
+#include "qxcbbackingstore.h"
#include "qxcbnativeinterface.h"
+#include "qxcbclipboard.h"
+#include "qxcbdrag.h"
#include <xcb/xcb.h>
-#include <private/qpixmap_raster_p.h>
-
-#include "qgenericunixfontdatabase.h"
+#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
+#include <QtPlatformSupport/private/qgenericunixfontdatabase_p.h>
#include <stdio.h>
+//this has to be included before egl, since egl pulls in X headers
+#include <QtGui/private/qguiapplication_p.h>
+
#ifdef XCB_USE_EGL
#include <EGL/egl.h>
#endif
-QXcbIntegration::QXcbIntegration()
- : m_connection(new QXcbConnection)
+#include <private/qplatforminputcontextfactory_qpa_p.h>
+#include <qplatforminputcontext_qpa.h>
+
+#if defined(XCB_USE_GLX)
+#include "qglxintegration.h"
+#elif defined(XCB_USE_EGL)
+#include "qxcbeglsurface.h"
+#include <QtPlatformSupport/private/qeglplatformcontext_p.h>
+#endif
+
+#include <QtGui/QOpenGLContext>
+#include <QtGui/QScreen>
+
+QXcbIntegration::QXcbIntegration(const QStringList &parameters)
+ : m_eventDispatcher(createUnixEventDispatcher())
{
- foreach (QXcbScreen *screen, m_connection->screens())
- m_screens << screen;
+ QGuiApplicationPrivate::instance()->setEventDispatcher(m_eventDispatcher);
+
+#ifdef XCB_USE_XLIB
+ XInitThreads();
+#endif
+
+ m_connections << new QXcbConnection;
+
+ for (int i = 0; i < parameters.size() - 1; i += 2) {
+ qDebug() << parameters.at(i) << parameters.at(i+1);
+ QString display = parameters.at(i) + ':' + parameters.at(i+1);
+ m_connections << new QXcbConnection(display.toAscii().constData());
+ }
+
+ foreach (QXcbConnection *connection, m_connections)
+ foreach (QXcbScreen *screen, connection->screens())
+ screenAdded(screen);
m_fontDatabase = new QGenericUnixFontDatabase();
m_nativeInterface = new QXcbNativeInterface;
+
+ m_inputContext = QPlatformInputContextFactory::create();
}
QXcbIntegration::~QXcbIntegration()
{
- delete m_connection;
+ qDeleteAll(m_connections);
}
-bool QXcbIntegration::hasCapability(QPlatformIntegration::Capability cap) const
+QPlatformWindow *QXcbIntegration::createPlatformWindow(QWindow *window) const
{
- switch (cap) {
- case ThreadedPixmaps: return true;
- case OpenGL: return hasOpenGL();
- default: return QPlatformIntegration::hasCapability(cap);
- }
+ return new QXcbWindow(window);
}
-QPixmapData *QXcbIntegration::createPixmapData(QPixmapData::PixelType type) const
+#if defined(XCB_USE_EGL)
+class QEGLXcbPlatformContext : public QEGLPlatformContext
{
- return new QRasterPixmapData(type);
-}
+public:
+ QEGLXcbPlatformContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share,
+ EGLDisplay display, QXcbConnection *c)
+ : QEGLPlatformContext(glFormat, share, display)
+ , m_connection(c)
+ {
+ Q_XCB_NOOP(m_connection);
+ }
+
+ void swapBuffers(QPlatformSurface *surface)
+ {
+ Q_XCB_NOOP(m_connection);
+ QEGLPlatformContext::swapBuffers(surface);
+ Q_XCB_NOOP(m_connection);
+ }
+
+ bool makeCurrent(QPlatformSurface *surface)
+ {
+ Q_XCB_NOOP(m_connection);
+ bool ret = QEGLPlatformContext::makeCurrent(surface);
+ Q_XCB_NOOP(m_connection);
+ return ret;
+ }
+
+ void doneCurrent()
+ {
+ Q_XCB_NOOP(m_connection);
+ QEGLPlatformContext::doneCurrent();
+ Q_XCB_NOOP(m_connection);
+ }
+
+ EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface)
+ {
+ return static_cast<QXcbWindow *>(surface)->eglSurface()->surface();
+ }
-QPlatformWindow *QXcbIntegration::createPlatformWindow(QWidget *widget, WId winId) const
+private:
+ QXcbConnection *m_connection;
+};
+#endif
+
+QPlatformOpenGLContext *QXcbIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
{
- Q_UNUSED(winId);
- return new QXcbWindow(widget);
+ QXcbScreen *screen = static_cast<QXcbScreen *>(context->screen()->handle());
+#if defined(XCB_USE_GLX)
+ return new QGLXContext(screen, context->format(), context->shareHandle());
+#elif defined(XCB_USE_EGL)
+ return new QEGLXcbPlatformContext(context->format(), context->shareHandle(),
+ screen->connection()->egl_display(), screen->connection());
+#elif defined(XCB_USE_DRI2)
+ return new QDri2Context(context->format(), context->shareHandle());
+#endif
}
-QWindowSurface *QXcbIntegration::createWindowSurface(QWidget *widget, WId winId) const
+QPlatformBackingStore *QXcbIntegration::createPlatformBackingStore(QWindow *window) const
{
- Q_UNUSED(winId);
- return new QXcbWindowSurface(widget);
+ return new QXcbBackingStore(window);
}
-QList<QPlatformScreen *> QXcbIntegration::screens() const
+bool QXcbIntegration::hasCapability(QPlatformIntegration::Capability cap) const
{
- return m_screens;
+ switch (cap) {
+ case ThreadedPixmaps: return true;
+ case OpenGL: return true;
+ case ThreadedOpenGL:
+#ifdef XCB_POLL_FOR_QUEUED_EVENT
+ return true;
+#else
+ return false;
+#endif
+ default: return QPlatformIntegration::hasCapability(cap);
+ }
}
-void QXcbIntegration::moveToScreen(QWidget *window, int screen)
+QAbstractEventDispatcher *QXcbIntegration::guiThreadEventDispatcher() const
{
- Q_UNUSED(window);
- Q_UNUSED(screen);
+ return m_eventDispatcher;
}
-bool QXcbIntegration::isVirtualDesktop()
+void QXcbIntegration::moveToScreen(QWindow *window, int screen)
{
- return false;
+ Q_UNUSED(window);
+ Q_UNUSED(screen);
}
QPlatformFontDatabase *QXcbIntegration::fontDatabase() const
@@ -120,32 +205,22 @@ QPlatformFontDatabase *QXcbIntegration::fontDatabase() const
return m_fontDatabase;
}
-QPixmap QXcbIntegration::grabWindow(WId window, int x, int y, int width, int height) const
+QPlatformNativeInterface * QXcbIntegration::nativeInterface() const
{
- Q_UNUSED(window);
- Q_UNUSED(x);
- Q_UNUSED(y);
- Q_UNUSED(width);
- Q_UNUSED(height);
- return QPixmap();
+ return m_nativeInterface;
}
+QPlatformClipboard *QXcbIntegration::clipboard() const
+{
+ return m_connections.at(0)->clipboard();
+}
-bool QXcbIntegration::hasOpenGL() const
+QPlatformDrag *QXcbIntegration::drag() const
{
-#if defined(XCB_USE_GLX)
- return true;
-#elif defined(XCB_USE_EGL)
- return m_connection->hasEgl();
-#elif defined(XCB_USE_DRI2)
- if (m_connection->hasSupportForDri2()) {
- return true;
- }
-#endif
- return false;
+ return m_connections.at(0)->drag();
}
-QPlatformNativeInterface * QXcbIntegration::nativeInterface() const
+QPlatformInputContext *QXcbIntegration::inputContext() const
{
- return m_nativeInterface;
+ return m_inputContext;
}
diff --git a/src/plugins/platforms/xcb/qxcbintegration.h b/src/plugins/platforms/xcb/qxcbintegration.h
index cd68919b54..cad127c28e 100644
--- a/src/plugins/platforms/xcb/qxcbintegration.h
+++ b/src/plugins/platforms/xcb/qxcbintegration.h
@@ -48,34 +48,40 @@
QT_BEGIN_NAMESPACE
class QXcbConnection;
+class QAbstractEventDispatcher;
class QXcbIntegration : public QPlatformIntegration
{
public:
- QXcbIntegration();
+ QXcbIntegration(const QStringList &parameters);
~QXcbIntegration();
+ QPlatformWindow *createPlatformWindow(QWindow *window) const;
+ QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const;
+ QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const;
+
bool hasCapability(Capability cap) const;
- QPixmapData *createPixmapData(QPixmapData::PixelType type) const;
- QPlatformWindow *createPlatformWindow(QWidget *widget, WId winId) const;
- QWindowSurface *createWindowSurface(QWidget *widget, WId winId) const;
+ QAbstractEventDispatcher *guiThreadEventDispatcher() const;
- QList<QPlatformScreen *> screens() const;
- void moveToScreen(QWidget *window, int screen);
- bool isVirtualDesktop();
- QPixmap grabWindow(WId window, int x, int y, int width, int height) const;
+ void moveToScreen(QWindow *window, int screen);
QPlatformFontDatabase *fontDatabase() const;
QPlatformNativeInterface *nativeInterface()const;
+ QPlatformClipboard *clipboard() const;
+ QPlatformDrag *drag() const;
+
+ QPlatformInputContext *inputContext() const;
+
private:
- bool hasOpenGL() const;
- QList<QPlatformScreen *> m_screens;
- QXcbConnection *m_connection;
+ QList<QXcbConnection *> m_connections;
QPlatformFontDatabase *m_fontDatabase;
QPlatformNativeInterface *m_nativeInterface;
+
+ QPlatformInputContext *m_inputContext;
+ QAbstractEventDispatcher *m_eventDispatcher;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
index 6bbc3c18ca..907dd0f1b6 100644
--- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
@@ -40,16 +40,17 @@
****************************************************************************/
#include "qxcbkeyboard.h"
-
+#include "qxcbwindow.h"
+#include "qxcbscreen.h"
#include <xcb/xcb_keysyms.h>
-
#include <X11/keysym.h>
-
#include <QtGui/QWindowSystemInterface>
#include <QtCore/QTextCodec>
-
+#include <private/qguiapplication_p.h>
#include <stdio.h>
+#include <qplatforminputcontext_qpa.h>
+
#ifndef XK_ISO_Left_Tab
#define XK_ISO_Left_Tab 0xFE20
#endif
@@ -898,12 +899,9 @@ QString QXcbKeyboard::translateKeySym(xcb_keysym_t keysym, uint xmodifiers,
QXcbKeyboard::QXcbKeyboard(QXcbConnection *connection)
: QXcbObject(connection)
- , m_alt_mask(0)
- , m_super_mask(0)
- , m_hyper_mask(0)
- , m_meta_mask(0)
{
m_key_symbols = xcb_key_symbols_alloc(xcb_connection());
+ setupModifiers();
}
QXcbKeyboard::~QXcbKeyboard()
@@ -911,18 +909,113 @@ QXcbKeyboard::~QXcbKeyboard()
xcb_key_symbols_free(m_key_symbols);
}
-// #define XCB_KEYBOARD_DEBUG
+void QXcbKeyboard::setupModifiers()
+{
+ m_alt_mask = 0;
+ m_super_mask = 0;
+ m_hyper_mask = 0;
+ m_meta_mask = 0;
+ m_mode_switch_mask = 0;
+ m_num_lock_mask = 0;
+ m_caps_lock_mask = 0;
+
+ xcb_generic_error_t *error = 0;
+ xcb_connection_t *conn = xcb_connection();
+ xcb_get_modifier_mapping_cookie_t modMapCookie = xcb_get_modifier_mapping(conn);
+ xcb_get_modifier_mapping_reply_t *modMapReply =
+ xcb_get_modifier_mapping_reply(conn, modMapCookie, &error);
+ if (error) {
+ qWarning("xcb keyboard: failed to get modifier mapping");
+ free(error);
+ return;
+ }
+
+ // Figure out the modifier mapping, ICCCM 6.6
+ typedef QPair<uint, xcb_keycode_t *> SymCodes;
+ QList<SymCodes> modKeyCodes;
+
+ // for Alt and Meta L and R are the same
+ modKeyCodes << SymCodes(XK_Alt_L, xcb_key_symbols_get_keycode(m_key_symbols, XK_Alt_L));
+ modKeyCodes << SymCodes(XK_Meta_L, xcb_key_symbols_get_keycode(m_key_symbols, XK_Meta_L));
+ modKeyCodes << SymCodes(XK_Super_L, xcb_key_symbols_get_keycode(m_key_symbols, XK_Super_L));
+ modKeyCodes << SymCodes(XK_Super_R, xcb_key_symbols_get_keycode(m_key_symbols, XK_Super_R));
+ modKeyCodes << SymCodes(XK_Hyper_L, xcb_key_symbols_get_keycode(m_key_symbols, XK_Hyper_L));
+ modKeyCodes << SymCodes(XK_Hyper_R, xcb_key_symbols_get_keycode(m_key_symbols, XK_Hyper_R));
+ modKeyCodes << SymCodes(XK_Num_Lock, xcb_key_symbols_get_keycode(m_key_symbols, XK_Num_Lock));
+ modKeyCodes << SymCodes(XK_Mode_switch, xcb_key_symbols_get_keycode(m_key_symbols, XK_Mode_switch));
+ modKeyCodes << SymCodes(XK_Caps_Lock, xcb_key_symbols_get_keycode(m_key_symbols, XK_Caps_Lock));
+
+ xcb_keycode_t *modMap = xcb_get_modifier_mapping_keycodes(modMapReply);
+ const int w = modMapReply->keycodes_per_modifier;
+ for (int i = 0; i < modKeyCodes.count(); ++i) {
+ for (int bit = 0; bit < 8; ++bit) {
+ uint mask = 1 << bit;
+ for (int x = 0; x < w; ++x) {
+ xcb_keycode_t keyCode = modMap[x + bit * w];
+ xcb_keycode_t *itk = modKeyCodes.at(i).second;
+ while (itk && *itk != XCB_NO_SYMBOL)
+ if (*itk++ == keyCode)
+ setMask(modKeyCodes.at(i).first, mask);
+ }
+ }
+ }
-void QXcbKeyboard::handleKeyEvent(QWidget *widget, QEvent::Type type, xcb_keycode_t code, quint16 state, xcb_timestamp_t time)
+ for (int i = 0; i < modKeyCodes.count(); ++i)
+ free(modKeyCodes.at(i).second);
+ free(modMapReply);
+}
+
+void QXcbKeyboard::setMask(uint sym, uint mask)
{
- int col = state & XCB_MOD_MASK_SHIFT ? 1 : 0;
+ if (m_alt_mask == 0
+ && m_meta_mask != mask
+ && m_super_mask != mask
+ && m_hyper_mask != mask
+ && (sym == XK_Alt_L || sym == XK_Alt_R))
+ m_alt_mask = mask;
+
+ if (m_meta_mask == 0
+ && m_alt_mask != mask
+ && m_super_mask != mask
+ && m_hyper_mask != mask
+ && (sym == XK_Meta_L || sym == XK_Meta_R))
+ m_meta_mask = mask;
+
+ if (m_super_mask == 0
+ && m_alt_mask != mask
+ && m_meta_mask != mask
+ && m_hyper_mask != mask
+ && (sym == XK_Super_L || sym == XK_Super_R))
+ m_super_mask = mask;
+
+ if (m_hyper_mask == 0
+ && m_alt_mask != mask
+ && m_meta_mask != mask
+ && m_super_mask != mask
+ && (sym == XK_Hyper_L || sym == XK_Hyper_R))
+ m_hyper_mask = mask;
+
+ if (m_mode_switch_mask == 0
+ && m_alt_mask != mask
+ && m_meta_mask != mask
+ && m_super_mask != mask
+ && m_hyper_mask != mask
+ && sym == XK_Mode_switch)
+ m_mode_switch_mask = mask;
+
+ if (m_num_lock_mask == 0 && sym == XK_Num_Lock)
+ m_num_lock_mask = mask;
+
+ if (m_caps_lock_mask == 0 && sym == XK_Caps_Lock)
+ m_caps_lock_mask = mask;
+}
- const int altGrOffset = 4;
- if (state & 128)
- col += altGrOffset;
+// #define XCB_KEYBOARD_DEBUG
+void QXcbKeyboard::handleKeyEvent(QWindow *window, QEvent::Type type, xcb_keycode_t code,
+ quint16 state, xcb_timestamp_t time)
+{
Q_XCB_NOOP(connection());
-
#ifdef XCB_KEYBOARD_DEBUG
printf("key code: %d, state: %d, syms: ", code, state);
for (int i = 0; i <= 5; ++i) {
@@ -931,43 +1024,105 @@ void QXcbKeyboard::handleKeyEvent(QWidget *widget, QEvent::Type type, xcb_keycod
printf("\n");
#endif
- Q_XCB_NOOP(connection());
+ QByteArray chars;
+ xcb_keysym_t sym = lookupString(window, state, code, type, &chars);
+
+
+ if (QObject* inputContext = QGuiApplicationPrivate::platformIntegration()->inputContext()) {
+ bool retval;
+ QMetaObject::invokeMethod(inputContext, "x11FilterEvent", Qt::DirectConnection,
+ Q_RETURN_ARG(bool, retval),
+ Q_ARG(uint, sym),
+ Q_ARG(uint, code),
+ Q_ARG(uint, state),
+ Q_ARG(bool, type == QEvent::KeyPress));
+ if (retval)
+ return;
+ }
+ Qt::KeyboardModifiers modifiers;
+ int qtcode = 0;
+ int count = chars.count();
+ QString string = translateKeySym(sym, state, qtcode, modifiers, chars, count);
+ QWindowSystemInterface::handleExtendedKeyEvent(window, time, type, qtcode, modifiers,
+ code, 0, state, string.left(count));
+}
+
+#ifdef XCB_USE_XLIB
+extern "C" {
+ int XLookupString(void *event, char *buf, int count, void *keysym, void *comp);
+}
+typedef struct { // must match XKeyEvent in Xlib.h
+ int type;
+ unsigned long serial;
+ int send_event;
+ void *display;
+ unsigned long window;
+ unsigned long root;
+ unsigned long subwindow;
+ unsigned long time;
+ int x, y;
+ int x_root, y_root;
+ unsigned int state;
+ unsigned int keycode;
+ int same_screen;
+} FakeXKeyEvent;
+#endif
+
+xcb_keysym_t QXcbKeyboard::lookupString(QWindow *window, uint state, xcb_keycode_t code,
+ QEvent::Type type, QByteArray *chars)
+{
+#ifdef XCB_USE_XLIB
+
+ xcb_keysym_t sym = XCB_NO_SYMBOL;
+ chars->resize(512);
+ FakeXKeyEvent event;
+ memset(&event, 0, sizeof(event));
+ event.type = (type == QEvent::KeyRelease ? 3 : 2);
+ event.display = connection()->xlib_display();
+ event.window = static_cast<QXcbWindow *>(window->handle())->xcb_window();
+ event.root = connection()->screens().at(0)->root();
+ event.state = state;
+ event.keycode = code;
+ int count = XLookupString(&event, chars->data(), chars->size(), &sym, 0);
+ chars->resize(count);
+ return sym;
+
+#else
+
+ // No XLookupString available. The following is really incomplete...
+
+ int col = state & XCB_MOD_MASK_SHIFT ? 1 : 0;
+ const int altGrOffset = 4;
+ if (state & 128)
+ col += altGrOffset;
xcb_keysym_t sym = xcb_key_symbols_get_keysym(m_key_symbols, code, col);
if (sym == XCB_NO_SYMBOL)
sym = xcb_key_symbols_get_keysym(m_key_symbols, code, col ^ 0x1);
-
if (state & XCB_MOD_MASK_LOCK && sym <= 0x7f && isprint(sym)) {
if (isupper(sym))
sym = tolower(sym);
else
sym = toupper(sym);
}
+ return sym;
- Q_XCB_NOOP(connection());
-
- QByteArray chars;
-
- Qt::KeyboardModifiers modifiers;
- int qtcode = 0;
- int count = 0;
-
- QString string = translateKeySym(sym, state, qtcode, modifiers, chars, count);
-
- QWindowSystemInterface::handleExtendedKeyEvent(widget, time, type, qtcode, modifiers, code, 0, state, string.left(count));
+#endif
}
-void QXcbKeyboard::handleKeyPressEvent(QWidget *widget, const xcb_key_press_event_t *event)
+void QXcbKeyboard::handleKeyPressEvent(QXcbWindow *window, const xcb_key_press_event_t *event)
{
- handleKeyEvent(widget, QEvent::KeyPress, event->detail, event->state, event->time);
+ window->updateNetWmUserTime(event->time);
+ handleKeyEvent(window->window(), QEvent::KeyPress, event->detail, event->state, event->time);
}
-void QXcbKeyboard::handleKeyReleaseEvent(QWidget *widget, const xcb_key_release_event_t *event)
+void QXcbKeyboard::handleKeyReleaseEvent(QXcbWindow *window, const xcb_key_release_event_t *event)
{
- handleKeyEvent(widget, QEvent::KeyRelease, event->detail, event->state, event->time);
+ handleKeyEvent(window->window(), QEvent::KeyRelease, event->detail, event->state, event->time);
}
void QXcbKeyboard::handleMappingNotifyEvent(const xcb_mapping_notify_event_t *event)
{
xcb_refresh_keyboard_mapping(m_key_symbols, const_cast<xcb_mapping_notify_event_t *>(event));
+ setupModifiers();
}
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.h b/src/plugins/platforms/xcb/qxcbkeyboard.h
index 095c3e4efb..ea5f84e8c2 100644
--- a/src/plugins/platforms/xcb/qxcbkeyboard.h
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.h
@@ -48,26 +48,32 @@
#include <QEvent>
+class QWindow;
+
class QXcbKeyboard : public QXcbObject
{
public:
QXcbKeyboard(QXcbConnection *connection);
~QXcbKeyboard();
- void handleKeyPressEvent(QWidget *widget, const xcb_key_press_event_t *event);
- void handleKeyReleaseEvent(QWidget *widget, const xcb_key_release_event_t *event);
+ void handleKeyPressEvent(QXcbWindow *window, const xcb_key_press_event_t *event);
+ void handleKeyReleaseEvent(QXcbWindow *window, const xcb_key_release_event_t *event);
void handleMappingNotifyEvent(const xcb_mapping_notify_event_t *event);
Qt::KeyboardModifiers translateModifiers(int s);
private:
- void handleKeyEvent(QWidget *widget, QEvent::Type type, xcb_keycode_t code, quint16 state, xcb_timestamp_t time);
+ void handleKeyEvent(QWindow *window, QEvent::Type type, xcb_keycode_t code, quint16 state, xcb_timestamp_t time);
int translateKeySym(uint key) const;
QString translateKeySym(xcb_keysym_t keysym, uint xmodifiers,
int &code, Qt::KeyboardModifiers &modifiers,
QByteArray &chars, int &count);
+ void setupModifiers();
+ void setMask(uint sym, uint mask);
+ xcb_keysym_t lookupString(QWindow *window, uint state, xcb_keycode_t code,
+ QEvent::Type type, QByteArray *chars);
uint m_alt_mask;
uint m_super_mask;
@@ -75,6 +81,7 @@ private:
uint m_meta_mask;
uint m_mode_switch_mask;
uint m_num_lock_mask;
+ uint m_caps_lock_mask;
xcb_key_symbols_t *m_key_symbols;
};
diff --git a/src/plugins/platforms/xcb/qxcbmime.cpp b/src/plugins/platforms/xcb/qxcbmime.cpp
new file mode 100644
index 0000000000..d4f80ca09d
--- /dev/null
+++ b/src/plugins/platforms/xcb/qxcbmime.cpp
@@ -0,0 +1,288 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxcbmime.h"
+
+#include <QtCore/QTextCodec>
+#include <QtGui/QImageWriter>
+#include <QtCore/QBuffer>
+#include <qdebug.h>
+
+#include <X11/Xutil.h>
+
+#undef XCB_ATOM_STRING
+#undef XCB_ATOM_PIXMAP
+#undef XCB_ATOM_BITMAP
+
+QXcbMime::QXcbMime()
+ : QInternalMimeData()
+{ }
+
+QXcbMime::~QXcbMime()
+{}
+
+
+
+QString QXcbMime::mimeAtomToString(QXcbConnection *connection, xcb_atom_t a)
+{
+ if (a == XCB_NONE)
+ return QString();
+
+ // special cases for string type
+ if (a == XCB_ATOM_STRING
+ || a == connection->atom(QXcbAtom::UTF8_STRING)
+ || a == connection->atom(QXcbAtom::TEXT))
+ return QLatin1String("text/plain");
+
+ // special case for images
+ if (a == XCB_ATOM_PIXMAP)
+ return QLatin1String("image/ppm");
+
+ QByteArray atomName = connection->atomName(a);
+
+ // special cases for uris
+ if (atomName == "text/x-moz-url")
+ atomName = "text/uri-list";
+
+ return QString::fromLatin1(atomName.constData());
+}
+
+bool QXcbMime::mimeDataForAtom(QXcbConnection *connection, xcb_atom_t a, QMimeData *mimeData, QByteArray *data,
+ xcb_atom_t *atomFormat, int *dataFormat)
+{
+ if (!data)
+ return false;
+
+ bool ret = false;
+ *atomFormat = a;
+ *dataFormat = 8;
+
+ if ((a == connection->atom(QXcbAtom::UTF8_STRING)
+ || a == XCB_ATOM_STRING
+ || a == connection->atom(QXcbAtom::TEXT))
+ && QInternalMimeData::hasFormatHelper(QLatin1String("text/plain"), mimeData)) {
+ if (a == connection->atom(QXcbAtom::UTF8_STRING)) {
+ *data = QInternalMimeData::renderDataHelper(QLatin1String("text/plain"), mimeData);
+ ret = true;
+ } else if (a == XCB_ATOM_STRING ||
+ a == connection->atom(QXcbAtom::TEXT)) {
+ // ICCCM says STRING is latin1
+ *data = QString::fromUtf8(QInternalMimeData::renderDataHelper(
+ QLatin1String("text/plain"), mimeData)).toLatin1();
+ ret = true;
+ }
+ return ret;
+ }
+
+ QString atomName = mimeAtomToString(connection, a);
+ if (QInternalMimeData::hasFormatHelper(atomName, mimeData)) {
+ *data = QInternalMimeData::renderDataHelper(atomName, mimeData);
+ if (atomName == QLatin1String("application/x-color"))
+ *dataFormat = 16;
+ ret = true;
+ } else if (atomName == QLatin1String("text/x-moz-url") &&
+ QInternalMimeData::hasFormatHelper(QLatin1String("text/uri-list"), mimeData)) {
+ QByteArray uri = QInternalMimeData::renderDataHelper(
+ QLatin1String("text/uri-list"), mimeData).split('\n').first();
+ QString mozUri = QString::fromLatin1(uri, uri.size());
+ mozUri += QLatin1Char('\n');
+ *data = QByteArray(reinterpret_cast<const char *>(mozUri.utf16()), mozUri.length() * 2);
+ ret = true;
+ } else if ((a == XCB_ATOM_PIXMAP || a == XCB_ATOM_BITMAP) && mimeData->hasImage()) {
+ ret = true;
+ }
+ return ret;
+}
+
+QList<xcb_atom_t> QXcbMime::mimeAtomsForFormat(QXcbConnection *connection, const QString &format)
+{
+ QList<xcb_atom_t> atoms;
+ atoms.append(connection->internAtom(format.toLatin1()));
+
+ // special cases for strings
+ if (format == QLatin1String("text/plain")) {
+ atoms.append(connection->atom(QXcbAtom::UTF8_STRING));
+ atoms.append(XCB_ATOM_STRING);
+ atoms.append(connection->atom(QXcbAtom::TEXT));
+ }
+
+ // special cases for uris
+ if (format == QLatin1String("text/uri-list"))
+ atoms.append(connection->internAtom("text/x-moz-url"));
+
+ //special cases for images
+ if (format == QLatin1String("image/ppm"))
+ atoms.append(XCB_ATOM_PIXMAP);
+ if (format == QLatin1String("image/pbm"))
+ atoms.append(XCB_ATOM_BITMAP);
+
+ return atoms;
+}
+
+QVariant QXcbMime::mimeConvertToFormat(QXcbConnection *connection, xcb_atom_t a, const QByteArray &data, const QString &format,
+ QVariant::Type requestedType, const QByteArray &encoding)
+{
+ QString atomName = mimeAtomToString(connection, a);
+// qDebug() << "mimeConvertDataToFormat" << format << atomName << data;
+
+ if (!encoding.isEmpty()
+ && atomName == format + QLatin1String(";charset=") + QString::fromLatin1(encoding)) {
+
+ if (requestedType == QVariant::String) {
+ QTextCodec *codec = QTextCodec::codecForName(encoding);
+ if (codec)
+ return codec->toUnicode(data);
+ }
+
+ return data;
+ }
+
+ // special cases for string types
+ if (format == QLatin1String("text/plain")) {
+ if (a == connection->atom(QXcbAtom::UTF8_STRING))
+ return QString::fromUtf8(data);
+ if (a == XCB_ATOM_STRING ||
+ a == connection->atom(QXcbAtom::TEXT))
+ return QString::fromLatin1(data);
+ }
+
+ // special case for uri types
+ if (format == QLatin1String("text/uri-list")) {
+ if (atomName == QLatin1String("text/x-moz-url")) {
+ // we expect this as utf16 <url><space><title>
+ // the first part is a url that should only contain ascci char
+ // so it should be safe to check that the second char is 0
+ // to verify that it is utf16
+ if (data.size() > 1 && data.at(1) == 0)
+ return QString::fromRawData((const QChar *)data.constData(),
+ data.size() / 2).split(QLatin1Char('\n')).first().toLatin1();
+ }
+ }
+
+ if (atomName == format)
+ return data;
+
+#if 0 // ###
+ // special case for images
+ if (format == QLatin1String("image/ppm")) {
+ if (a == XCB_ATOM_PIXMAP && data.size() == sizeof(Pixmap)) {
+ Pixmap xpm = *((Pixmap*)data.data());
+ if (!xpm)
+ return QByteArray();
+ Window root;
+ int x;
+ int y;
+ uint width;
+ uint height;
+ uint border_width;
+ uint depth;
+
+ XGetGeometry(display, xpm, &root, &x, &y, &width, &height, &border_width, &depth);
+ XImage *ximg = XGetImage(display,xpm,x,y,width,height,AllPlanes,depth==1 ? XYPixmap : ZPixmap);
+ QImage qimg = QXlibStatic::qimageFromXImage(ximg);
+ XDestroyImage(ximg);
+
+ QImageWriter imageWriter;
+ imageWriter.setFormat("PPMRAW");
+ QBuffer buf;
+ buf.open(QIODevice::WriteOnly);
+ imageWriter.setDevice(&buf);
+ imageWriter.write(qimg);
+ return buf.buffer();
+ }
+ }
+#endif
+ return QVariant();
+}
+
+xcb_atom_t QXcbMime::mimeAtomForFormat(QXcbConnection *connection, const QString &format, QVariant::Type requestedType,
+ const QList<xcb_atom_t> &atoms, QByteArray *requestedEncoding)
+{
+ requestedEncoding->clear();
+
+ // find matches for string types
+ if (format == QLatin1String("text/plain")) {
+ if (atoms.contains(connection->atom(QXcbAtom::UTF8_STRING)))
+ return connection->atom(QXcbAtom::UTF8_STRING);
+ if (atoms.contains(XCB_ATOM_STRING))
+ return XCB_ATOM_STRING;
+ if (atoms.contains(connection->atom(QXcbAtom::TEXT)))
+ return connection->atom(QXcbAtom::TEXT);
+ }
+
+ // find matches for uri types
+ if (format == QLatin1String("text/uri-list")) {
+ xcb_atom_t a = connection->internAtom(format.toLatin1());
+ if (a && atoms.contains(a))
+ return a;
+ a = connection->internAtom("text/x-moz-url");
+ if (a && atoms.contains(a))
+ return a;
+ }
+
+ // find match for image
+ if (format == QLatin1String("image/ppm")) {
+ if (atoms.contains(XCB_ATOM_PIXMAP))
+ return XCB_ATOM_PIXMAP;
+ }
+
+ // for string/text requests try to use a format with a well-defined charset
+ // first to avoid encoding problems
+ if (requestedType == QVariant::String
+ && format.startsWith(QLatin1String("text/"))
+ && !format.contains(QLatin1String("charset="))) {
+
+ QString formatWithCharset = format;
+ formatWithCharset.append(QLatin1String(";charset=utf-8"));
+
+ xcb_atom_t a = connection->internAtom(formatWithCharset.toLatin1());
+ if (a && atoms.contains(a)) {
+ *requestedEncoding = "utf-8";
+ return a;
+ }
+ }
+
+ xcb_atom_t a = connection->internAtom(format.toLatin1());
+ if (a && atoms.contains(a))
+ return a;
+
+ return 0;
+}
diff --git a/src/plugins/platforms/xcb/qxcbmime.h b/src/plugins/platforms/xcb/qxcbmime.h
new file mode 100644
index 0000000000..4ab38ed803
--- /dev/null
+++ b/src/plugins/platforms/xcb/qxcbmime.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QXCBMIME_H
+#define QXCBMIME_H
+
+#include <private/qdnd_p.h>
+
+#include <QtGui/QClipboard>
+
+#include "qxcbintegration.h"
+#include "qxcbconnection.h"
+
+class QXcbMime : public QInternalMimeData {
+ Q_OBJECT
+public:
+ QXcbMime();
+ ~QXcbMime();
+
+ static QList<xcb_atom_t> mimeAtomsForFormat(QXcbConnection *connection, const QString &format);
+ static QString mimeAtomToString(QXcbConnection *connection, xcb_atom_t a);
+ static bool mimeDataForAtom(QXcbConnection *connection, xcb_atom_t a, QMimeData *mimeData, QByteArray *data,
+ xcb_atom_t *atomFormat, int *dataFormat);
+ static QVariant mimeConvertToFormat(QXcbConnection *connection, xcb_atom_t a, const QByteArray &data, const QString &format,
+ QVariant::Type requestedType, const QByteArray &encoding);
+ static xcb_atom_t mimeAtomForFormat(QXcbConnection *connection, const QString &format, QVariant::Type requestedType,
+ const QList<xcb_atom_t> &atoms, QByteArray *requestedEncoding);
+};
+
+#endif // QXCBMIME_H
diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
index 6423f1b798..3c9cdfd257 100644
--- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
+++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
@@ -43,13 +43,16 @@
#include "qxcbscreen.h"
-#include <QtGui/private/qapplication_p.h>
+#include <private/qguiapplication_p.h>
#include <QtCore/QMap>
#include <QtCore/QDebug>
+#include <QtGui/qopenglcontext.h>
+#include <QtGui/qscreen.h>
+
#if defined(XCB_USE_EGL)
-#include "../eglconvenience/qeglplatformcontext.h"
+#include "QtPlatformSupport/private/qeglplatformcontext_p.h"
#elif defined (XCB_USE_DRI2)
#include "qdri2context.h"
#endif
@@ -71,29 +74,41 @@ public:
Q_GLOBAL_STATIC(QXcbResourceMap, qXcbResourceMap)
-void *QXcbNativeInterface::nativeResourceForWidget(const QByteArray &resourceString, QWidget *widget)
+void *QXcbNativeInterface::nativeResourceForContext(const QByteArray &resourceString, QOpenGLContext *context)
+{
+ QByteArray lowerCaseResource = resourceString.toLower();
+ ResourceType resource = qXcbResourceMap()->value(lowerCaseResource);
+ void *result = 0;
+ switch(resource) {
+ case EglContext:
+ result = eglContextForContext(context);
+ break;
+ default:
+ result = 0;
+ }
+ return result;
+}
+
+void *QXcbNativeInterface::nativeResourceForWindow(const QByteArray &resourceString, QWindow *window)
{
QByteArray lowerCaseResource = resourceString.toLower();
ResourceType resource = qXcbResourceMap()->value(lowerCaseResource);
void *result = 0;
switch(resource) {
case Display:
- result = displayForWidget(widget);
+ result = displayForWindow(window);
break;
case EglDisplay:
- result = eglDisplayForWidget(widget);
+ result = eglDisplayForWindow(window);
break;
case Connection:
- result = connectionForWidget(widget);
+ result = connectionForWindow(window);
break;
case Screen:
- result = qPlatformScreenForWidget(widget);
+ result = qPlatformScreenForWindow(window);
break;
case GraphicsDevice:
- result = graphicsDeviceForWidget(widget);
- break;
- case EglContext:
- result = eglContextForWidget(widget);
+ result = graphicsDeviceForWindow(window);
break;
default:
result = 0;
@@ -101,75 +116,76 @@ void *QXcbNativeInterface::nativeResourceForWidget(const QByteArray &resourceStr
return result;
}
-QXcbScreen *QXcbNativeInterface::qPlatformScreenForWidget(QWidget *widget)
+QXcbScreen *QXcbNativeInterface::qPlatformScreenForWindow(QWindow *window)
{
QXcbScreen *screen;
- if (widget) {
- screen = static_cast<QXcbScreen *>(QPlatformScreen::platformScreenForWidget(widget));
- }else {
- screen = static_cast<QXcbScreen *>(QApplicationPrivate::platformIntegration()->screens()[0]);
+ if (window) {
+ screen = static_cast<QXcbScreen *>(window->screen()->handle());
+ } else {
+ screen = static_cast<QXcbScreen *>(QGuiApplication::primaryScreen()->handle());
}
return screen;
}
-void *QXcbNativeInterface::displayForWidget(QWidget *widget)
+void *QXcbNativeInterface::displayForWindow(QWindow *window)
{
#if defined(XCB_USE_XLIB)
- QXcbScreen *screen = qPlatformScreenForWidget(widget);
+ QXcbScreen *screen = qPlatformScreenForWindow(window);
return screen->connection()->xlib_display();
#else
- Q_UNUSED(widget);
+ Q_UNUSED(window);
return 0;
#endif
}
-void *QXcbNativeInterface::eglDisplayForWidget(QWidget *widget)
+void *QXcbNativeInterface::eglDisplayForWindow(QWindow *window)
{
#if defined(XCB_USE_DRI2) || defined(XCB_USE_EGL)
- QXcbScreen *screen = qPlatformScreenForWidget(widget);
+ QXcbScreen *screen = qPlatformScreenForWindow(window);
return screen->connection()->egl_display();
#else
- Q_UNUSED(widget)
+ Q_UNUSED(window)
return 0;
#endif
}
-void *QXcbNativeInterface::connectionForWidget(QWidget *widget)
+void *QXcbNativeInterface::connectionForWindow(QWindow *window)
{
- QXcbScreen *screen = qPlatformScreenForWidget(widget);
+ QXcbScreen *screen = qPlatformScreenForWindow(window);
return screen->xcb_connection();
}
-void *QXcbNativeInterface::screenForWidget(QWidget *widget)
+void *QXcbNativeInterface::screenForWindow(QWindow *window)
{
- QXcbScreen *screen = qPlatformScreenForWidget(widget);
+ QXcbScreen *screen = qPlatformScreenForWindow(window);
return screen->screen();
}
-void *QXcbNativeInterface::graphicsDeviceForWidget(QWidget *widget)
+void *QXcbNativeInterface::graphicsDeviceForWindow(QWindow *window)
{
#if defined(XCB_USE_DRI2)
- QXcbScreen *screen = qPlatformScreenForWidget(widget);
+ QXcbScreen *screen = qPlatformScreenForWindow(window);
QByteArray deviceName = screen->connection()->dri2DeviceName();
return deviceName.data();
#else
- Q_UNUSED(widget);
+ Q_UNUSED(window);
return 0;
#endif
}
-void * QXcbNativeInterface::eglContextForWidget(QWidget *widget)
+void * QXcbNativeInterface::eglContextForContext(QOpenGLContext *context)
{
- Q_ASSERT(widget);
- if (!widget->platformWindow()) {
- qDebug() << "QPlatformWindow does not exist for widget" << widget
- << "cannot return EGLContext";
- return 0;
- }
- QPlatformGLContext *platformContext = widget->platformWindow()->glContext();
+ Q_ASSERT(context);
+#if defined(XCB_USE_EGL)
+ QEGLPlatformContext *eglPlatformContext = static_cast<QEGLPlatformContext *>(context->handle());
+ return eglPlatformContext->eglContext();
+#endif
+#if 0
+ Q_ASSERT(window);
+ QPlatformOpenGLContext *platformContext = window->glContext()->handle();
if (!platformContext) {
- qDebug() << "QPlatformWindow" << widget->platformWindow() << "does not have a glContext"
+ qDebug() << "QWindow" << window << "does not have a glContext"
<< "cannot return EGLContext";
return 0;
}
@@ -182,4 +198,7 @@ void * QXcbNativeInterface::eglContextForWidget(QWidget *widget)
#else
return 0;
#endif
+#else
+ return 0;
+#endif
}
diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.h b/src/plugins/platforms/xcb/qxcbnativeinterface.h
index 3fb0fa5e2d..8dec83267a 100644
--- a/src/plugins/platforms/xcb/qxcbnativeinterface.h
+++ b/src/plugins/platforms/xcb/qxcbnativeinterface.h
@@ -59,17 +59,19 @@ public:
EglContext
};
- void *nativeResourceForWidget(const QByteArray &resourceString, QWidget *widget);
+ void *nativeResourceForContext(const QByteArray &resourceString, QOpenGLContext *context);
+ void *nativeResourceForWindow(const QByteArray &resourceString, QWindow *window);
- void *displayForWidget(QWidget *widget);
- void *eglDisplayForWidget(QWidget *widget);
- void *connectionForWidget(QWidget *widget);
- void *screenForWidget(QWidget *widget);
- void *graphicsDeviceForWidget(QWidget *widget);
- void *eglContextForWidget(QWidget *widget);
+ void *displayForWindow(QWindow *window);
+ void *eglDisplayForWindow(QWindow *window);
+ void *connectionForWindow(QWindow *window);
+ void *screenForWindow(QWindow *window);
+ void *graphicsDeviceForWindow(QWindow *window);
+
+ void *eglContextForContext(QOpenGLContext *context);
private:
- static QXcbScreen *qPlatformScreenForWidget(QWidget *widget);
+ static QXcbScreen *qPlatformScreenForWindow(QWindow *window);
};
#endif // QXCBNATIVEINTERFACE_H
diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp
index 9a4858123b..42259feda8 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.cpp
+++ b/src/plugins/platforms/xcb/qxcbscreen.cpp
@@ -40,6 +40,9 @@
****************************************************************************/
#include "qxcbscreen.h"
+#include "qxcbwindow.h"
+#include "qxcbcursor.h"
+#include "qxcbimage.h"
#include <stdio.h>
@@ -102,10 +105,104 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, xcb_screen_t *screen, int num
free(reply);
m_syncRequestSupported = m_windowManagerName != QLatin1String("KWin");
+
+ m_clientLeader = xcb_generate_id(xcb_connection());
+ Q_XCB_CALL2(xcb_create_window(xcb_connection(),
+ XCB_COPY_FROM_PARENT,
+ m_clientLeader,
+ m_screen->root,
+ 0, 0, 1, 1,
+ 0,
+ XCB_WINDOW_CLASS_INPUT_OUTPUT,
+ m_screen->root_visual,
+ 0, 0), connection);
+
+ Q_XCB_CALL2(xcb_change_property(xcb_connection(),
+ XCB_PROP_MODE_REPLACE,
+ m_clientLeader,
+ atom(QXcbAtom::WM_CLIENT_LEADER),
+ XCB_ATOM_WINDOW,
+ 32,
+ 1,
+ &m_clientLeader), connection);
+
+ xcb_depth_iterator_t depth_iterator =
+ xcb_screen_allowed_depths_iterator(screen);
+
+ while (depth_iterator.rem) {
+ xcb_depth_t *depth = depth_iterator.data;
+ xcb_visualtype_iterator_t visualtype_iterator =
+ xcb_depth_visuals_iterator(depth);
+
+ while (visualtype_iterator.rem) {
+ xcb_visualtype_t *visualtype = visualtype_iterator.data;
+ m_visuals.insert(visualtype->visual_id, *visualtype);
+ xcb_visualtype_next(&visualtype_iterator);
+ }
+
+ xcb_depth_next(&depth_iterator);
+ }
+
+ m_cursor = new QXcbCursor(connection, this);
}
QXcbScreen::~QXcbScreen()
{
+ delete m_cursor;
+}
+
+
+QWindow *QXcbScreen::topLevelAt(const QPoint &p) const
+{
+ xcb_window_t root = m_screen->root;
+
+ int x = p.x();
+ int y = p.y();
+
+ xcb_generic_error_t *error;
+
+ xcb_window_t parent = root;
+ xcb_window_t child = root;
+
+ do {
+ xcb_translate_coordinates_cookie_t translate_cookie =
+ xcb_translate_coordinates(xcb_connection(), parent, child, x, y);
+
+ xcb_translate_coordinates_reply_t *translate_reply =
+ xcb_translate_coordinates_reply(xcb_connection(), translate_cookie, &error);
+
+ if (!translate_reply) {
+ if (error) {
+ connection()->handleXcbError(error);
+ free(error);
+ }
+ return 0;
+ }
+
+ parent = child;
+ child = translate_reply->child;
+ x = translate_reply->dst_x;
+ y = translate_reply->dst_y;
+
+ free(translate_reply);
+
+ if (!child || child == root)
+ return 0;
+
+ QPlatformWindow *platformWindow = connection()->platformWindowFromId(child);
+ if (platformWindow)
+ return platformWindow->window();
+ } while (parent != child);
+
+ return 0;
+}
+
+const xcb_visualtype_t *QXcbScreen::visualForId(xcb_visualid_t visualid) const
+{
+ QMap<xcb_visualid_t, xcb_visualtype_t>::const_iterator it = m_visuals.find(visualid);
+ if (it == m_visuals.constEnd())
+ return 0;
+ return &*it;
}
QRect QXcbScreen::geometry() const
@@ -132,3 +229,126 @@ int QXcbScreen::screenNumber() const
{
return m_number;
}
+
+QPixmap QXcbScreen::grabWindow(WId window, int x, int y, int width, int height) const
+{
+ if (width == 0 || height == 0)
+ return QPixmap();
+
+ xcb_get_geometry_cookie_t geometry_cookie = xcb_get_geometry(xcb_connection(), window);
+
+ xcb_generic_error_t *error;
+ xcb_get_geometry_reply_t *reply =
+ xcb_get_geometry_reply(xcb_connection(), geometry_cookie, &error);
+
+ if (!reply) {
+ if (error) {
+ connection()->handleXcbError(error);
+ free(error);
+ }
+ return QPixmap();
+ }
+
+ if (width < 0)
+ width = reply->width - x;
+ if (height < 0)
+ height = reply->height - y;
+
+ // TODO: handle multiple screens
+ QXcbScreen *screen = const_cast<QXcbScreen *>(this);
+ xcb_window_t root = screen->root();
+ geometry_cookie = xcb_get_geometry(xcb_connection(), root);
+ xcb_get_geometry_reply_t *root_reply =
+ xcb_get_geometry_reply(xcb_connection(), geometry_cookie, &error);
+
+ if (!root_reply) {
+ if (error) {
+ connection()->handleXcbError(error);
+ free(error);
+ }
+ free(reply);
+ return QPixmap();
+ }
+
+ if (reply->depth == root_reply->depth) {
+ // if the depth of the specified window and the root window are the
+ // same, grab pixels from the root window (so that we get the any
+ // overlapping windows and window manager frames)
+
+ // map x and y to the root window
+ xcb_translate_coordinates_cookie_t translate_cookie =
+ xcb_translate_coordinates(xcb_connection(), window, root, x, y);
+
+ xcb_translate_coordinates_reply_t *translate_reply =
+ xcb_translate_coordinates_reply(xcb_connection(), translate_cookie, &error);
+
+ if (!translate_reply) {
+ if (error) {
+ connection()->handleXcbError(error);
+ free(error);
+ }
+ free(reply);
+ free(root_reply);
+ return QPixmap();
+ }
+
+ x = translate_reply->dst_x;
+ y = translate_reply->dst_y;
+
+ window = root;
+
+ free(translate_reply);
+ free(reply);
+ reply = root_reply;
+ } else {
+ free(root_reply);
+ root_reply = 0;
+ }
+
+ xcb_get_window_attributes_reply_t *attributes_reply =
+ xcb_get_window_attributes_reply(xcb_connection(), xcb_get_window_attributes(xcb_connection(), window), &error);
+
+ if (!attributes_reply) {
+ if (error) {
+ connection()->handleXcbError(error);
+ free(error);
+ }
+ free(reply);
+ return QPixmap();
+ }
+
+ const xcb_visualtype_t *visual = screen->visualForId(attributes_reply->visual);
+ free(attributes_reply);
+
+ xcb_pixmap_t pixmap = xcb_generate_id(xcb_connection());
+ error = xcb_request_check(xcb_connection(), xcb_create_pixmap_checked(xcb_connection(), reply->depth, pixmap, window, width, height));
+ if (error) {
+ connection()->handleXcbError(error);
+ free(error);
+ }
+
+ uint32_t gc_value_mask = XCB_GC_SUBWINDOW_MODE;
+ uint32_t gc_value_list[] = { XCB_SUBWINDOW_MODE_INCLUDE_INFERIORS };
+
+ xcb_gcontext_t gc = xcb_generate_id(xcb_connection());
+ xcb_create_gc(xcb_connection(), gc, pixmap, gc_value_mask, gc_value_list);
+
+ error = xcb_request_check(xcb_connection(), xcb_copy_area_checked(xcb_connection(), window, pixmap, gc, x, y, 0, 0, width, height));
+ if (error) {
+ connection()->handleXcbError(error);
+ free(error);
+ }
+
+ QPixmap result = qt_xcb_pixmapFromXPixmap(connection(), pixmap, width, height, reply->depth, visual);
+
+ free(reply);
+ xcb_free_gc(xcb_connection(), gc);
+ xcb_free_pixmap(xcb_connection(), pixmap);
+
+ return result;
+}
+
+QString QXcbScreen::name() const
+{
+ return connection()->displayName() + QLatin1String(".") + QString::number(screenNumber());
+}
diff --git a/src/plugins/platforms/xcb/qxcbscreen.h b/src/plugins/platforms/xcb/qxcbscreen.h
index a78ee822f4..07d855b398 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.h
+++ b/src/plugins/platforms/xcb/qxcbscreen.h
@@ -50,6 +50,7 @@
#include "qxcbobject.h"
class QXcbConnection;
+class QXcbCursor;
class QXcbScreen : public QXcbObject, public QPlatformScreen
{
@@ -57,6 +58,10 @@ public:
QXcbScreen(QXcbConnection *connection, xcb_screen_t *screen, int number);
~QXcbScreen();
+ QPixmap grabWindow(WId window, int x, int y, int width, int height) const;
+
+ QWindow *topLevelAt(const QPoint &point) const;
+
QRect geometry() const;
int depth() const;
QImage::Format format() const;
@@ -67,14 +72,23 @@ public:
xcb_screen_t *screen() const { return m_screen; }
xcb_window_t root() const { return m_screen->root; }
+ xcb_window_t clientLeader() const { return m_clientLeader; }
+
QString windowManagerName() const { return m_windowManagerName; }
bool syncRequestSupported() const { return m_syncRequestSupported; }
+ const xcb_visualtype_t *visualForId(xcb_visualid_t) const;
+
+ QString name() const;
+
private:
xcb_screen_t *m_screen;
int m_number;
QString m_windowManagerName;
bool m_syncRequestSupported;
+ xcb_window_t m_clientLeader;
+ QMap<xcb_visualid_t, xcb_visualtype_t> m_visuals;
+ QXcbCursor *m_cursor;
};
#endif
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index 20e4187541..db8d37e817 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -42,9 +42,13 @@
#include "qxcbwindow.h"
#include <QtDebug>
+#include <QScreen>
#include "qxcbconnection.h"
#include "qxcbscreen.h"
+#include "qxcbdrag.h"
+#include "qxcbwmsupport.h"
+
#ifdef XCB_USE_DRI2
#include "qdri2context.h"
#endif
@@ -61,9 +65,10 @@
#define xcb_set_wm_hints xcb_icccm_set_wm_hints
#endif
-#include <private/qapplication_p.h>
-#include <private/qwindowsurface_p.h>
+#include <private/qguiapplication_p.h>
+#include <private/qwindow_p.h>
+#include <QtGui/QPlatformBackingStore>
#include <QtGui/QWindowSystemInterface>
#include <stdio.h>
@@ -75,38 +80,71 @@
#if defined(XCB_USE_GLX)
#include "qglxintegration.h"
-#include "qglxconvenience.h"
+#include <QtPlatformSupport/private/qglxconvenience_p.h>
#elif defined(XCB_USE_EGL)
-#include "../eglconvenience/qeglplatformcontext.h"
-#include "../eglconvenience/qeglconvenience.h"
-#include "../eglconvenience/qxlibeglintegration.h"
+#include "qxcbeglsurface.h"
+#include <QtPlatformSupport/private/qeglconvenience_p.h>
+#include <QtPlatformSupport/private/qxlibeglintegration_p.h>
#endif
+#define XCOORD_MAX 16383
+
+//#ifdef NET_WM_STATE_DEBUG
+
// Returns true if we should set WM_TRANSIENT_FOR on \a w
-static inline bool isTransient(const QWidget *w)
+static inline bool isTransient(const QWindow *w)
{
- return ((w->windowType() == Qt::Dialog
- || w->windowType() == Qt::Sheet
- || w->windowType() == Qt::Tool
- || w->windowType() == Qt::SplashScreen
- || w->windowType() == Qt::ToolTip
- || w->windowType() == Qt::Drawer
- || w->windowType() == Qt::Popup)
- && !w->testAttribute(Qt::WA_X11BypassTransientForHint));
+ return w->windowType() == Qt::Dialog
+ || w->windowType() == Qt::Sheet
+ || w->windowType() == Qt::Tool
+ || w->windowType() == Qt::SplashScreen
+ || w->windowType() == Qt::ToolTip
+ || w->windowType() == Qt::Drawer
+ || w->windowType() == Qt::Popup;
}
-QXcbWindow::QXcbWindow(QWidget *tlw)
- : QPlatformWindow(tlw)
- , m_context(0)
+QXcbWindow::QXcbWindow(QWindow *window)
+ : QPlatformWindow(window)
+ , m_window(0)
+ , m_syncCounter(0)
+ , m_mapped(false)
+ , m_netWmUserTimeWindow(XCB_NONE)
+#if defined(XCB_USE_EGL)
+ , m_eglSurface(0)
+#endif
{
- m_screen = static_cast<QXcbScreen *>(QPlatformScreen::platformScreenForWidget(tlw));
+ m_screen = static_cast<QXcbScreen *>(window->screen()->handle());
setConnection(m_screen->connection());
- const quint32 mask = XCB_CW_BACK_PIXMAP | XCB_CW_EVENT_MASK;
+ create();
+}
+
+void QXcbWindow::create()
+{
+ destroy();
+
+ m_windowState = Qt::WindowNoState;
+ m_dirtyFrameMargins = true;
+
+ Qt::WindowType type = window()->windowType();
+
+ if (type == Qt::Desktop) {
+ m_window = m_screen->root();
+ m_depth = m_screen->screen()->root_depth;
+ m_imageFormat = (m_depth == 32) ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32;
+ connection()->addWindow(m_window, this);
+ return;
+ }
+
+ const quint32 mask = XCB_CW_BACK_PIXMAP | XCB_CW_OVERRIDE_REDIRECT | XCB_CW_SAVE_UNDER | XCB_CW_EVENT_MASK;
const quint32 values[] = {
// XCB_CW_BACK_PIXMAP
XCB_NONE,
+ // XCB_CW_OVERRIDE_REDIRECT
+ type == Qt::Popup || type == Qt::ToolTip,
+ // XCB_CW_SAVE_UNDER
+ type == Qt::Popup || type == Qt::Tool || type == Qt::SplashScreen || type == Qt::ToolTip || type == Qt::Drawer,
// XCB_CW_EVENT_MASK
XCB_EVENT_MASK_EXPOSURE
| XCB_EVENT_MASK_STRUCTURE_NOTIFY
@@ -117,20 +155,33 @@ QXcbWindow::QXcbWindow(QWidget *tlw)
| XCB_EVENT_MASK_BUTTON_MOTION
| XCB_EVENT_MASK_ENTER_WINDOW
| XCB_EVENT_MASK_LEAVE_WINDOW
+ | XCB_EVENT_MASK_POINTER_MOTION
| XCB_EVENT_MASK_PROPERTY_CHANGE
| XCB_EVENT_MASK_FOCUS_CHANGE
};
-#if defined(XCB_USE_GLX) || defined(XCB_USE_EGL)
- if (tlw->platformWindowFormat().windowApi() == QPlatformWindowFormat::OpenGL
- && QApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL)
- || tlw->platformWindowFormat().alpha())
+ QRect rect = window()->geometry();
+ QPlatformWindow::setGeometry(rect);
+
+ rect.setWidth(qBound(1, rect.width(), XCOORD_MAX));
+ rect.setHeight(qBound(1, rect.height(), XCOORD_MAX));
+
+ xcb_window_t xcb_parent_id = m_screen->root();
+ if (parent())
+ xcb_parent_id = static_cast<QXcbWindow *>(parent())->xcb_window();
+
+ m_requestedFormat = window()->format();
+
+#if (defined(XCB_USE_GLX) || defined(XCB_USE_EGL)) && defined(XCB_USE_XLIB)
+ if (QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL)
+ || window()->format().hasAlpha())
{
#if defined(XCB_USE_GLX)
- XVisualInfo *visualInfo = qglx_findVisualInfo(DISPLAY_FROM_XCB(m_screen),m_screen->screenNumber(), tlw->platformWindowFormat());
+ XVisualInfo *visualInfo = qglx_findVisualInfo(DISPLAY_FROM_XCB(m_screen),m_screen->screenNumber(), window()->format());
+
#elif defined(XCB_USE_EGL)
EGLDisplay eglDisplay = connection()->egl_display();
- EGLConfig eglConfig = q_configFromQPlatformWindowFormat(eglDisplay,tlw->platformWindowFormat(),true);
+ EGLConfig eglConfig = q_configFromGLFormat(eglDisplay, window()->format(), true);
VisualID id = QXlibEglIntegration::getCompatibleVisualId(DISPLAY_FROM_XCB(this), eglDisplay, eglConfig);
XVisualInfo visualInfoTemplate;
@@ -143,18 +194,16 @@ QXcbWindow::QXcbWindow(QWidget *tlw)
#endif //XCB_USE_GLX
if (visualInfo) {
m_depth = visualInfo->depth;
- m_format = (m_depth == 32) ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32;
- Colormap cmap = XCreateColormap(DISPLAY_FROM_XCB(this), m_screen->root(), visualInfo->visual, AllocNone);
+ m_imageFormat = (m_depth == 32) ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32;
+ Colormap cmap = XCreateColormap(DISPLAY_FROM_XCB(this), xcb_parent_id, visualInfo->visual, AllocNone);
XSetWindowAttributes a;
a.background_pixel = WhitePixel(DISPLAY_FROM_XCB(this), m_screen->screenNumber());
a.border_pixel = BlackPixel(DISPLAY_FROM_XCB(this), m_screen->screenNumber());
a.colormap = cmap;
- m_window = XCreateWindow(DISPLAY_FROM_XCB(this), m_screen->root(), tlw->x(), tlw->y(), tlw->width(), tlw->height(),
+ m_window = XCreateWindow(DISPLAY_FROM_XCB(this), xcb_parent_id, rect.x(), rect.y(), rect.width(), rect.height(),
0, visualInfo->depth, InputOutput, visualInfo->visual,
CWBackPixel|CWBorderPixel|CWColormap, &a);
-
- printf("created GL window: %d\n", m_window);
} else {
qFatal("no window!");
}
@@ -163,25 +212,25 @@ QXcbWindow::QXcbWindow(QWidget *tlw)
{
m_window = xcb_generate_id(xcb_connection());
m_depth = m_screen->screen()->root_depth;
- m_format = (m_depth == 32) ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32;
+ m_imageFormat = (m_depth == 32) ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32;
Q_XCB_CALL(xcb_create_window(xcb_connection(),
XCB_COPY_FROM_PARENT, // depth -- same as root
m_window, // window id
- m_screen->root(), // parent window id
- tlw->x(),
- tlw->y(),
- tlw->width(),
- tlw->height(),
+ xcb_parent_id, // parent window id
+ rect.x(),
+ rect.y(),
+ rect.width(),
+ rect.height(),
0, // border width
XCB_WINDOW_CLASS_INPUT_OUTPUT, // window class
m_screen->screen()->root_visual, // visual
0, // value mask
0)); // value list
-
- printf("created regular window: %d\n", m_window);
}
+ connection()->addWindow(m_window, this);
+
Q_XCB_CALL(xcb_change_window_attributes(xcb_connection(), m_window, mask, values));
xcb_atom_t properties[4];
@@ -193,7 +242,7 @@ QXcbWindow::QXcbWindow(QWidget *tlw)
if (m_screen->syncRequestSupported())
properties[propertyCount++] = atom(QXcbAtom::_NET_WM_SYNC_REQUEST);
- if (tlw->windowFlags() & Qt::WindowContextHelpButtonHint)
+ if (window()->windowFlags() & Qt::WindowContextHelpButtonHint)
properties[propertyCount++] = atom(QXcbAtom::_NET_WM_CONTEXT_HELP);
Q_XCB_CALL(xcb_change_property(xcb_connection(),
@@ -221,29 +270,49 @@ QXcbWindow::QXcbWindow(QWidget *tlw)
&m_syncCounter));
}
- if (isTransient(tlw) && tlw->parentWidget()) {
- // ICCCM 4.1.2.6
- QWidget *p = tlw->parentWidget()->window();
- xcb_window_t parentWindow = p->winId();
- Q_XCB_CALL(xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window,
- XCB_ATOM_WM_TRANSIENT_FOR, XCB_ATOM_WINDOW, 32,
- 1, &parentWindow));
-
- }
-
// set the PID to let the WM kill the application if unresponsive
long pid = getpid();
Q_XCB_CALL(xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window,
atom(QXcbAtom::_NET_WM_PID), XCB_ATOM_CARDINAL, 32,
1, &pid));
+
+ xcb_wm_hints_t hints;
+ memset(&hints, 0, sizeof(hints));
+ xcb_wm_hints_set_normal(&hints);
+
+ xcb_set_wm_hints(xcb_connection(), m_window, &hints);
+
+ xcb_window_t leader = m_screen->clientLeader();
+ Q_XCB_CALL(xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window,
+ atom(QXcbAtom::WM_CLIENT_LEADER), XCB_ATOM_WINDOW, 32,
+ 1, &leader));
+
+ setWindowFlags(window()->windowFlags());
+ setWindowTitle(window()->windowTitle());
+ setWindowState(window()->windowState());
+
+ connection()->drag()->dndEnable(this, true);
}
QXcbWindow::~QXcbWindow()
{
- delete m_context;
- if (m_screen->syncRequestSupported())
+ destroy();
+}
+
+void QXcbWindow::destroy()
+{
+ if (m_syncCounter && m_screen->syncRequestSupported())
Q_XCB_CALL(xcb_sync_destroy_counter(xcb_connection(), m_syncCounter));
- Q_XCB_CALL(xcb_destroy_window(xcb_connection(), m_window));
+ if (m_window) {
+ connection()->removeWindow(m_window);
+ Q_XCB_CALL(xcb_destroy_window(xcb_connection(), m_window));
+ }
+ m_mapped = false;
+
+#if defined(XCB_USE_EGL)
+ delete m_eglSurface;
+ m_eglSurface = 0;
+#endif
}
void QXcbWindow::setGeometry(const QRect &rect)
@@ -251,40 +320,182 @@ void QXcbWindow::setGeometry(const QRect &rect)
QPlatformWindow::setGeometry(rect);
const quint32 mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT;
- const quint32 values[] = { rect.x(), rect.y(), rect.width(), rect.height() };
+ const quint32 values[] = { rect.x(),
+ rect.y(),
+ qBound(1, rect.width(), XCOORD_MAX),
+ qBound(1, rect.height(), XCOORD_MAX) };
Q_XCB_CALL(xcb_configure_window(xcb_connection(), m_window, mask, values));
}
+QMargins QXcbWindow::frameMargins() const
+{
+ if (m_dirtyFrameMargins) {
+ xcb_window_t window = m_window;
+ xcb_window_t parent = m_window;
+
+ bool foundRoot = false;
+
+ const QVector<xcb_window_t> &virtualRoots =
+ connection()->wmSupport()->virtualRoots();
+
+ while (!foundRoot) {
+ xcb_query_tree_cookie_t cookie = xcb_query_tree(xcb_connection(), parent);
+
+ xcb_generic_error_t *error;
+ xcb_query_tree_reply_t *reply = xcb_query_tree_reply(xcb_connection(), cookie, &error);
+ if (reply) {
+ if (reply->root == reply->parent || virtualRoots.indexOf(reply->parent) != -1) {
+ foundRoot = true;
+ } else {
+ window = parent;
+ parent = reply->parent;
+ }
+
+ free(reply);
+ } else {
+ if (error) {
+ connection()->handleXcbError(error);
+ free(error);
+ }
+
+ m_dirtyFrameMargins = false;
+ m_frameMargins = QMargins();
+ return m_frameMargins;
+ }
+ }
+
+ QPoint offset;
+
+ xcb_generic_error_t *error;
+ xcb_translate_coordinates_reply_t *reply =
+ xcb_translate_coordinates_reply(
+ xcb_connection(),
+ xcb_translate_coordinates(xcb_connection(), window, parent, 0, 0),
+ &error);
+
+ if (reply) {
+ offset = QPoint(reply->dst_x, reply->dst_y);
+ free(reply);
+ } else if (error) {
+ free(error);
+ }
+
+ xcb_get_geometry_reply_t *geom =
+ xcb_get_geometry_reply(
+ xcb_connection(),
+ xcb_get_geometry(xcb_connection(), parent),
+ &error);
+
+ if (geom) {
+ // --
+ // add the border_width for the window managers frame... some window managers
+ // do not use a border_width of zero for their frames, and if we the left and
+ // top strut, we ensure that pos() is absolutely correct. frameGeometry()
+ // will still be incorrect though... perhaps i should have foffset as well, to
+ // indicate the frame offset (equal to the border_width on X).
+ // - Brad
+ // -- copied from qwidget_x11.cpp
+
+ int left = offset.x() + geom->border_width;
+ int top = offset.y() + geom->border_width;
+ int right = geom->width + geom->border_width - geometry().width() - offset.x();
+ int bottom = geom->height + geom->border_width - geometry().height() - offset.y();
+
+ m_frameMargins = QMargins(left, top, right, bottom);
+
+ free(geom);
+ } else if (error) {
+ free(error);
+ }
+
+ m_dirtyFrameMargins = false;
+ }
+
+ return m_frameMargins;
+}
+
void QXcbWindow::setVisible(bool visible)
{
- xcb_wm_hints_t hints;
- if (visible) {
- if (widget()->isMinimized())
+ if (visible)
+ show();
+ else
+ hide();
+}
+
+void QXcbWindow::show()
+{
+ if (window()->isTopLevel()) {
+ xcb_get_property_cookie_t cookie = xcb_get_wm_hints(xcb_connection(), m_window);
+
+ xcb_generic_error_t *error;
+
+ xcb_wm_hints_t hints;
+ xcb_get_wm_hints_reply(xcb_connection(), cookie, &hints, &error);
+
+ if (error) {
+ connection()->handleXcbError(error);
+ free(error);
+ }
+
+ m_dirtyFrameMargins = true;
+
+ if (window()->windowState() & Qt::WindowMinimized)
xcb_wm_hints_set_iconic(&hints);
else
xcb_wm_hints_set_normal(&hints);
+
xcb_set_wm_hints(xcb_connection(), m_window, &hints);
- Q_XCB_CALL(xcb_map_window(xcb_connection(), m_window));
- connection()->sync();
- } else {
- Q_XCB_CALL(xcb_unmap_window(xcb_connection(), m_window));
-
- // send synthetic UnmapNotify event according to icccm 4.1.4
- xcb_unmap_notify_event_t event;
- event.response_type = XCB_UNMAP_NOTIFY;
- event.sequence = 0; // does this matter?
- event.event = m_screen->root();
- event.window = m_window;
- event.from_configure = false;
- Q_XCB_CALL(xcb_send_event(xcb_connection(), false, m_screen->root(),
- XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&event));
- xcb_flush(xcb_connection());
+ // update WM_NORMAL_HINTS
+ propagateSizeHints();
+
+ // update WM_TRANSIENT_FOR
+ if (window()->transientParent() && isTransient(window())) {
+ QXcbWindow *transientXcbParent = static_cast<QXcbWindow *>(window()->transientParent()->handle());
+ if (transientXcbParent) {
+ // ICCCM 4.1.2.6
+ xcb_window_t parentWindow = transientXcbParent->xcb_window();
+
+ // todo: set transient for group (wm_client_leader) if no parent, a la qwidget_x11.cpp
+ Q_XCB_CALL(xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window,
+ XCB_ATOM_WM_TRANSIENT_FOR, XCB_ATOM_WINDOW, 32,
+ 1, &parentWindow));
+ }
+ }
+
+ // update _MOTIF_WM_HINTS
+ updateMotifWmHintsBeforeMap();
+
+ // update _NET_WM_STATE
+ updateNetWmStateBeforeMap();
}
+
+ Q_XCB_CALL(xcb_map_window(xcb_connection(), m_window));
+ xcb_flush(xcb_connection());
+
+ connection()->sync();
+}
+
+void QXcbWindow::hide()
+{
+ Q_XCB_CALL(xcb_unmap_window(xcb_connection(), m_window));
+
+ // send synthetic UnmapNotify event according to icccm 4.1.4
+ xcb_unmap_notify_event_t event;
+ event.response_type = XCB_UNMAP_NOTIFY;
+ event.event = m_screen->root();
+ event.window = m_window;
+ event.from_configure = false;
+ Q_XCB_CALL(xcb_send_event(xcb_connection(), false, m_screen->root(),
+ XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&event));
+
+ xcb_flush(xcb_connection());
+
+ m_mapped = false;
}
-struct QtMWMHints {
+struct QtMotifWmHints {
quint32 flags, functions, decorations;
qint32 input_mode;
quint32 status;
@@ -317,33 +528,142 @@ enum {
MWM_INPUT_FULL_APPLICATION_MODAL = 3L
};
+static QtMotifWmHints getMotifWmHints(QXcbConnection *c, xcb_window_t window)
+{
+ QtMotifWmHints hints;
+
+ xcb_get_property_cookie_t get_cookie =
+ xcb_get_property(c->xcb_connection(), 0, window, c->atom(QXcbAtom::_MOTIF_WM_HINTS),
+ c->atom(QXcbAtom::_MOTIF_WM_HINTS), 0, 20);
+
+ xcb_generic_error_t *error;
+
+ xcb_get_property_reply_t *reply =
+ xcb_get_property_reply(c->xcb_connection(), get_cookie, &error);
+
+ if (reply && reply->format == 32 && reply->type == c->atom(QXcbAtom::_MOTIF_WM_HINTS)) {
+ hints = *((QtMotifWmHints *)xcb_get_property_value(reply));
+ } else if (error) {
+ c->handleXcbError(error);
+ free(error);
+
+ hints.flags = 0L;
+ hints.functions = MWM_FUNC_ALL;
+ hints.decorations = MWM_DECOR_ALL;
+ hints.input_mode = 0L;
+ hints.status = 0L;
+ }
+
+ free(reply);
+
+ return hints;
+}
+
+static void setMotifWmHints(QXcbConnection *c, xcb_window_t window, const QtMotifWmHints &hints)
+{
+ if (hints.flags != 0l) {
+ Q_XCB_CALL2(xcb_change_property(c->xcb_connection(),
+ XCB_PROP_MODE_REPLACE,
+ window,
+ c->atom(QXcbAtom::_MOTIF_WM_HINTS),
+ c->atom(QXcbAtom::_MOTIF_WM_HINTS),
+ 32,
+ 5,
+ &hints), c);
+ } else {
+ Q_XCB_CALL2(xcb_delete_property(c->xcb_connection(), window, c->atom(QXcbAtom::_MOTIF_WM_HINTS)), c);
+ }
+}
+
+void QXcbWindow::printNetWmState(const QVector<xcb_atom_t> &state)
+{
+ printf("_NET_WM_STATE (%d): ", state.size());
+ for (int i = 0; i < state.size(); ++i) {
+#define CHECK_WM_STATE(state_atom) \
+ if (state.at(i) == atom(QXcbAtom::state_atom))\
+ printf(#state_atom " ");
+ CHECK_WM_STATE(_NET_WM_STATE_ABOVE)
+ CHECK_WM_STATE(_NET_WM_STATE_BELOW)
+ CHECK_WM_STATE(_NET_WM_STATE_FULLSCREEN)
+ CHECK_WM_STATE(_NET_WM_STATE_MAXIMIZED_HORZ)
+ CHECK_WM_STATE(_NET_WM_STATE_MAXIMIZED_VERT)
+ CHECK_WM_STATE(_NET_WM_STATE_MODAL)
+ CHECK_WM_STATE(_NET_WM_STATE_STAYS_ON_TOP)
+ CHECK_WM_STATE(_NET_WM_STATE_DEMANDS_ATTENTION)
+#undef CHECK_WM_STATE
+ }
+ printf("\n");
+}
+
+QVector<xcb_atom_t> QXcbWindow::getNetWmState()
+{
+ QVector<xcb_atom_t> result;
+
+ xcb_get_property_cookie_t get_cookie =
+ xcb_get_property(xcb_connection(), 0, m_window, atom(QXcbAtom::_NET_WM_STATE),
+ XCB_ATOM_ATOM, 0, 1024);
+
+ xcb_generic_error_t *error;
+
+ xcb_get_property_reply_t *reply =
+ xcb_get_property_reply(xcb_connection(), get_cookie, &error);
+
+ if (reply && reply->format == 32 && reply->type == XCB_ATOM_ATOM) {
+ result.resize(reply->length);
+
+ memcpy(result.data(), xcb_get_property_value(reply), reply->length * sizeof(xcb_atom_t));
+
+#ifdef NET_WM_STATE_DEBUG
+ printf("getting net wm state (%x)\n", m_window);
+ printNetWmState(result);
+#endif
+
+ free(reply);
+ } else if (error) {
+ connection()->handleXcbError(error);
+ free(error);
+ } else {
+#ifdef NET_WM_STATE_DEBUG
+ printf("getting net wm state (%x), empty\n", m_window);
+#endif
+ }
+
+ return result;
+}
+
+void QXcbWindow::setNetWmState(const QVector<xcb_atom_t> &atoms)
+{
+ if (atoms.isEmpty()) {
+ Q_XCB_CALL(xcb_delete_property(xcb_connection(), m_window, atom(QXcbAtom::_NET_WM_STATE)));
+ } else {
+ Q_XCB_CALL(xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window,
+ atom(QXcbAtom::_NET_WM_STATE), XCB_ATOM_ATOM, 32,
+ atoms.count(), atoms.constData()));
+ }
+ xcb_flush(xcb_connection());
+}
+
+
Qt::WindowFlags QXcbWindow::setWindowFlags(Qt::WindowFlags flags)
{
Qt::WindowType type = static_cast<Qt::WindowType>(int(flags & Qt::WindowType_Mask));
- setNetWmWindowTypes(flags);
-
if (type == Qt::ToolTip)
flags |= Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint;
if (type == Qt::Popup)
flags |= Qt::X11BypassWindowManagerHint;
- bool topLevel = (flags & Qt::Window);
- bool popup = (type == Qt::Popup);
- bool dialog = (type == Qt::Dialog
- || type == Qt::Sheet);
- bool desktop = (type == Qt::Desktop);
- bool tool = (type == Qt::Tool || type == Qt::SplashScreen
- || type == Qt::ToolTip || type == Qt::Drawer);
+ setNetWmWindowFlags(flags);
+ setMotifWindowFlags(flags);
- Q_UNUSED(topLevel);
- Q_UNUSED(dialog);
- Q_UNUSED(desktop);
- Q_UNUSED(tool);
+ return flags;
+}
- bool tooltip = (type == Qt::ToolTip);
+void QXcbWindow::setMotifWindowFlags(Qt::WindowFlags flags)
+{
+ Qt::WindowType type = static_cast<Qt::WindowType>(int(flags & Qt::WindowType_Mask));
- QtMWMHints mwmhints;
+ QtMotifWmHints mwmhints;
mwmhints.flags = 0L;
mwmhints.functions = 0L;
mwmhints.decorations = 0;
@@ -403,30 +723,90 @@ Qt::WindowFlags QXcbWindow::setWindowFlags(Qt::WindowFlags flags)
mwmhints.decorations = 0;
}
- if (mwmhints.flags != 0l) {
- Q_XCB_CALL(xcb_change_property(xcb_connection(),
- XCB_PROP_MODE_REPLACE,
- m_window,
- atom(QXcbAtom::_MOTIF_WM_HINTS),
- atom(QXcbAtom::_MOTIF_WM_HINTS),
- 32,
- 5,
- &mwmhints));
- } else {
- Q_XCB_CALL(xcb_delete_property(xcb_connection(), m_window, atom(QXcbAtom::_MOTIF_WM_HINTS)));
- }
+ setMotifWmHints(connection(), m_window, mwmhints);
+}
+
+void QXcbWindow::changeNetWmState(bool set, xcb_atom_t one, xcb_atom_t two)
+{
+ xcb_client_message_event_t event;
+
+ event.response_type = XCB_CLIENT_MESSAGE;
+ event.format = 32;
+ event.window = m_window;
+ event.type = atom(QXcbAtom::_NET_WM_STATE);
+ event.data.data32[0] = set ? 1 : 0;
+ event.data.data32[1] = one;
+ event.data.data32[2] = two;
+ event.data.data32[3] = 0;
+ event.data.data32[4] = 0;
+
+ Q_XCB_CALL(xcb_send_event(xcb_connection(), 0, m_screen->root(), XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&event));
+}
- if (popup || tooltip) {
- const quint32 mask = XCB_CW_OVERRIDE_REDIRECT | XCB_CW_SAVE_UNDER;
- const quint32 values[] = { true, true };
+Qt::WindowState QXcbWindow::setWindowState(Qt::WindowState state)
+{
+ if (state == m_windowState)
+ return state;
+
+ m_dirtyFrameMargins = true;
+
+ // unset old state
+ switch (m_windowState) {
+ case Qt::WindowMinimized:
+ Q_XCB_CALL(xcb_map_window(xcb_connection(), m_window));
+ break;
+ case Qt::WindowMaximized:
+ changeNetWmState(false,
+ atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_HORZ),
+ atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_VERT));
+ break;
+ case Qt::WindowFullScreen:
+ changeNetWmState(false, atom(QXcbAtom::_NET_WM_STATE_FULLSCREEN));
+ break;
+ default:
+ break;
+ }
- Q_XCB_CALL(xcb_change_window_attributes(xcb_connection(), m_window, mask, values));
+ // set new state
+ switch (state) {
+ case Qt::WindowMinimized:
+ {
+ xcb_client_message_event_t event;
+
+ event.response_type = XCB_CLIENT_MESSAGE;
+ event.format = 32;
+ event.window = m_window;
+ event.type = atom(QXcbAtom::WM_CHANGE_STATE);
+ event.data.data32[0] = XCB_WM_STATE_ICONIC;
+ event.data.data32[1] = 0;
+ event.data.data32[2] = 0;
+ event.data.data32[3] = 0;
+ event.data.data32[4] = 0;
+
+ Q_XCB_CALL(xcb_send_event(xcb_connection(), 0, m_screen->root(), XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&event));
+ }
+ break;
+ case Qt::WindowMaximized:
+ changeNetWmState(true,
+ atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_HORZ),
+ atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_VERT));
+ break;
+ case Qt::WindowFullScreen:
+ changeNetWmState(true, atom(QXcbAtom::_NET_WM_STATE_FULLSCREEN));
+ break;
+ case Qt::WindowNoState:
+ break;
+ default:
+ break;
}
- return QPlatformWindow::setWindowFlags(flags);
+ connection()->sync();
+
+ m_windowState = state;
+ return m_windowState;
}
-void QXcbWindow::setNetWmWindowTypes(Qt::WindowFlags flags)
+void QXcbWindow::setNetWmWindowFlags(Qt::WindowFlags flags)
{
// in order of decreasing priority
QVector<uint> windowTypes;
@@ -462,6 +842,127 @@ void QXcbWindow::setNetWmWindowTypes(Qt::WindowFlags flags)
windowTypes.count(), windowTypes.constData()));
}
+void QXcbWindow::updateMotifWmHintsBeforeMap()
+{
+ QtMotifWmHints mwmhints = getMotifWmHints(connection(), m_window);
+
+ if (window()->windowModality() != Qt::NonModal) {
+ switch (window()->windowModality()) {
+ case Qt::WindowModal:
+ mwmhints.input_mode = MWM_INPUT_PRIMARY_APPLICATION_MODAL;
+ break;
+ case Qt::ApplicationModal:
+ default:
+ mwmhints.input_mode = MWM_INPUT_FULL_APPLICATION_MODAL;
+ break;
+ }
+ mwmhints.flags |= MWM_HINTS_INPUT_MODE;
+ } else {
+ mwmhints.input_mode = MWM_INPUT_MODELESS;
+ mwmhints.flags &= ~MWM_HINTS_INPUT_MODE;
+ }
+
+ if (window()->minimumSize() == window()->maximumSize()) {
+ // fixed size, remove the resize handle (since mwm/dtwm
+ // isn't smart enough to do it itself)
+ mwmhints.flags |= MWM_HINTS_FUNCTIONS;
+ if (mwmhints.functions == MWM_FUNC_ALL) {
+ mwmhints.functions = MWM_FUNC_MOVE;
+ } else {
+ mwmhints.functions &= ~MWM_FUNC_RESIZE;
+ }
+
+ if (mwmhints.decorations == MWM_DECOR_ALL) {
+ mwmhints.flags |= MWM_HINTS_DECORATIONS;
+ mwmhints.decorations = (MWM_DECOR_BORDER
+ | MWM_DECOR_TITLE
+ | MWM_DECOR_MENU);
+ } else {
+ mwmhints.decorations &= ~MWM_DECOR_RESIZEH;
+ }
+ }
+
+ if (window()->windowFlags() & Qt::WindowMinimizeButtonHint) {
+ mwmhints.flags |= MWM_HINTS_DECORATIONS;
+ mwmhints.decorations |= MWM_DECOR_MINIMIZE;
+ mwmhints.functions |= MWM_FUNC_MINIMIZE;
+ }
+ if (window()->windowFlags() & Qt::WindowMaximizeButtonHint) {
+ mwmhints.flags |= MWM_HINTS_DECORATIONS;
+ mwmhints.decorations |= MWM_DECOR_MAXIMIZE;
+ mwmhints.functions |= MWM_FUNC_MAXIMIZE;
+ }
+ if (window()->windowFlags() & Qt::WindowCloseButtonHint)
+ mwmhints.functions |= MWM_FUNC_CLOSE;
+
+ setMotifWmHints(connection(), m_window, mwmhints);
+}
+
+void QXcbWindow::updateNetWmStateBeforeMap()
+{
+ QVector<xcb_atom_t> netWmState;
+
+ Qt::WindowFlags flags = window()->windowFlags();
+ if (flags & Qt::WindowStaysOnTopHint) {
+ netWmState.append(atom(QXcbAtom::_NET_WM_STATE_ABOVE));
+ netWmState.append(atom(QXcbAtom::_NET_WM_STATE_STAYS_ON_TOP));
+ } else if (flags & Qt::WindowStaysOnBottomHint) {
+ netWmState.append(atom(QXcbAtom::_NET_WM_STATE_BELOW));
+ }
+
+ if (window()->windowState() & Qt::WindowFullScreen) {
+ netWmState.append(atom(QXcbAtom::_NET_WM_STATE_FULLSCREEN));
+ }
+
+ if (window()->windowState() & Qt::WindowMaximized) {
+ netWmState.append(atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_HORZ));
+ netWmState.append(atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_VERT));
+ }
+
+ if (window()->windowModality() != Qt::NonModal) {
+ netWmState.append(atom(QXcbAtom::_NET_WM_STATE_MODAL));
+ }
+
+ setNetWmState(netWmState);
+}
+
+void QXcbWindow::updateNetWmUserTime(xcb_timestamp_t timestamp)
+{
+ xcb_window_t wid = m_window;
+
+ const bool isSupportedByWM = connection()->wmSupport()->isSupportedByWM(atom(QXcbAtom::_NET_WM_USER_TIME_WINDOW));
+ if (m_netWmUserTimeWindow || isSupportedByWM) {
+ if (!m_netWmUserTimeWindow) {
+ m_netWmUserTimeWindow = xcb_generate_id(xcb_connection());
+ Q_XCB_CALL(xcb_create_window(xcb_connection(),
+ XCB_COPY_FROM_PARENT, // depth -- same as root
+ m_netWmUserTimeWindow, // window id
+ m_window, // parent window id
+ -1, -1, 1, 1,
+ 0, // border width
+ XCB_WINDOW_CLASS_INPUT_OUTPUT, // window class
+ m_screen->screen()->root_visual, // visual
+ 0, // value mask
+ 0)); // value list
+ wid = m_netWmUserTimeWindow;
+ xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window, atom(QXcbAtom::_NET_WM_USER_TIME_WINDOW),
+ XCB_ATOM_WINDOW, 32, 1, &m_netWmUserTimeWindow);
+ xcb_delete_property(xcb_connection(), m_window, atom(QXcbAtom::_NET_WM_USER_TIME));
+ } else if (!isSupportedByWM) {
+ // WM no longer supports it, then we should remove the
+ // _NET_WM_USER_TIME_WINDOW atom.
+ xcb_delete_property(xcb_connection(), m_window, atom(QXcbAtom::_NET_WM_USER_TIME_WINDOW));
+ xcb_destroy_window(xcb_connection(), m_netWmUserTimeWindow);
+ m_netWmUserTimeWindow = XCB_NONE;
+ } else {
+ wid = m_netWmUserTimeWindow;
+ }
+ }
+ xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, wid, atom(QXcbAtom::_NET_WM_USER_TIME),
+ XCB_ATOM_CARDINAL, 32, 1, &timestamp);
+}
+
+
WId QXcbWindow::winId() const
{
return m_window;
@@ -469,8 +970,13 @@ WId QXcbWindow::winId() const
void QXcbWindow::setParent(const QPlatformWindow *parent)
{
+ // re-create for compatibility
+ create();
+
QPoint topLeft = geometry().topLeft();
- Q_XCB_CALL(xcb_reparent_window(xcb_connection(), window(), static_cast<const QXcbWindow *>(parent)->window(), topLeft.x(), topLeft.y()));
+
+ xcb_window_t xcb_parent_id = parent ? static_cast<const QXcbWindow *>(parent)->xcb_window() : m_screen->root();
+ Q_XCB_CALL(xcb_reparent_window(xcb_connection(), xcb_window(), xcb_parent_id, topLeft.x(), topLeft.y()));
}
void QXcbWindow::setWindowTitle(const QString &title)
@@ -500,56 +1006,87 @@ void QXcbWindow::lower()
Q_XCB_CALL(xcb_configure_window(xcb_connection(), m_window, mask, values));
}
+void QXcbWindow::propagateSizeHints()
+{
+ // update WM_NORMAL_HINTS
+ xcb_size_hints_t hints;
+ memset(&hints, 0, sizeof(hints));
+
+ QRect rect = geometry();
+
+ xcb_size_hints_set_position(&hints, true, rect.x(), rect.y());
+ xcb_size_hints_set_size(&hints, true, rect.width(), rect.height());
+ xcb_size_hints_set_win_gravity(&hints, XCB_GRAVITY_STATIC);
+
+ QWindow *win = window();
+
+ QSize minimumSize = win->minimumSize();
+ QSize maximumSize = win->maximumSize();
+ QSize baseSize = win->baseSize();
+ QSize sizeIncrement = win->sizeIncrement();
+
+ if (minimumSize.width() > 0 || minimumSize.height() > 0)
+ xcb_size_hints_set_min_size(&hints, minimumSize.width(), minimumSize.height());
+
+ if (maximumSize.width() < QWINDOWSIZE_MAX || maximumSize.height() < QWINDOWSIZE_MAX)
+ xcb_size_hints_set_max_size(&hints,
+ qMin(XCOORD_MAX, maximumSize.width()),
+ qMin(XCOORD_MAX, maximumSize.height()));
+
+ if (sizeIncrement.width() > 0 || sizeIncrement.height() > 0) {
+ xcb_size_hints_set_base_size(&hints, baseSize.width(), baseSize.height());
+ xcb_size_hints_set_resize_inc(&hints, sizeIncrement.width(), sizeIncrement.height());
+ }
+
+ xcb_set_wm_normal_hints(xcb_connection(), m_window, &hints);
+}
+
void QXcbWindow::requestActivateWindow()
{
- Q_XCB_CALL(xcb_set_input_focus(xcb_connection(), XCB_INPUT_FOCUS_PARENT, m_window, XCB_TIME_CURRENT_TIME));
+ if (m_mapped){
+ updateNetWmUserTime(connection()->time());
+ Q_XCB_CALL(xcb_set_input_focus(xcb_connection(), XCB_INPUT_FOCUS_PARENT, m_window, connection()->time()));
+ }
connection()->sync();
}
-QPlatformGLContext *QXcbWindow::glContext() const
+QSurfaceFormat QXcbWindow::format() const
{
- if (!QApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL)) {
- printf("no opengl\n");
- return 0;
- }
- if (!m_context) {
-#if defined(XCB_USE_GLX)
- QXcbWindow *that = const_cast<QXcbWindow *>(this);
- that->m_context = new QGLXContext(m_window, m_screen, widget()->platformWindowFormat());
-#elif defined(XCB_USE_EGL)
+ // ### return actual format
+ return m_requestedFormat;
+}
+
+#if defined(XCB_USE_EGL)
+QXcbEGLSurface *QXcbWindow::eglSurface() const
+{
+ if (!m_eglSurface) {
EGLDisplay display = connection()->egl_display();
- EGLConfig config = q_configFromQPlatformWindowFormat(display,widget()->platformWindowFormat(),true);
- QVector<EGLint> eglContextAttrs;
- eglContextAttrs.append(EGL_CONTEXT_CLIENT_VERSION);
- eglContextAttrs.append(2);
- eglContextAttrs.append(EGL_NONE);
-
- EGLSurface eglSurface = eglCreateWindowSurface(display,config,(EGLNativeWindowType)m_window,0);
- QXcbWindow *that = const_cast<QXcbWindow *>(this);
- that->m_context = new QEGLPlatformContext(display, config, eglContextAttrs.data(), eglSurface, EGL_OPENGL_ES_API);
-#elif defined(XCB_USE_DRI2)
- QXcbWindow *that = const_cast<QXcbWindow *>(this);
- that->m_context = new QDri2Context(that);
-#endif
+ EGLConfig config = q_configFromGLFormat(display, window()->format(), true);
+ EGLSurface surface = eglCreateWindowSurface(display, config, (EGLNativeWindowType)m_window, 0);
+
+ m_eglSurface = new QXcbEGLSurface(display, surface);
}
- return m_context;
+
+ return m_eglSurface;
}
+#endif
void QXcbWindow::handleExposeEvent(const xcb_expose_event_t *event)
{
- QWindowSurface *surface = widget()->windowSurface();
- if (surface) {
- QRect rect(event->x, event->y, event->width, event->height);
-
- surface->flush(widget(), rect, QPoint());
- }
+ QRect rect(event->x, event->y, event->width, event->height);
+ QWindowSystemInterface::handleSynchronousExposeEvent(window(), rect);
}
void QXcbWindow::handleClientMessageEvent(const xcb_client_message_event_t *event)
{
- if (event->format == 32 && event->type == atom(QXcbAtom::WM_PROTOCOLS)) {
+ if (event->format != 32)
+ return;
+
+ if (event->type == atom(QXcbAtom::WM_PROTOCOLS)) {
if (event->data.data32[0] == atom(QXcbAtom::WM_DELETE_WINDOW)) {
- QWindowSystemInterface::handleCloseEvent(widget());
+ QWindowSystemInterface::handleCloseEvent(window());
+ } else if (event->data.data32[0] == atom(QXcbAtom::WM_TAKE_FOCUS)) {
+ connection()->setTime(event->data.data32[1]);
} else if (event->data.data32[0] == atom(QXcbAtom::_NET_WM_PING)) {
xcb_client_message_event_t reply = *event;
@@ -559,13 +1096,22 @@ void QXcbWindow::handleClientMessageEvent(const xcb_client_message_event_t *even
xcb_send_event(xcb_connection(), 0, m_screen->root(), XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&reply);
xcb_flush(xcb_connection());
} else if (event->data.data32[0] == atom(QXcbAtom::_NET_WM_SYNC_REQUEST)) {
- if (!m_hasReceivedSyncRequest) {
- m_hasReceivedSyncRequest = true;
- printf("Window manager supports _NET_WM_SYNC_REQUEST, syncing resizes\n");
- }
+ connection()->setTime(event->data.data32[1]);
m_syncValue.lo = event->data.data32[2];
m_syncValue.hi = event->data.data32[3];
+ } else {
+ qWarning() << "unhandled WM_PROTOCOLS message:" << connection()->atomName(event->data.data32[0]);
}
+ } else if (event->type == atom(QXcbAtom::XdndEnter)) {
+ connection()->drag()->handleEnter(window(), event);
+ } else if (event->type == atom(QXcbAtom::XdndPosition)) {
+ connection()->drag()->handlePosition(window(), event, false);
+ } else if (event->type == atom(QXcbAtom::XdndLeave)) {
+ connection()->drag()->handleLeave(window(), event, false);
+ } else if (event->type == atom(QXcbAtom::XdndDrop)) {
+ connection()->drag()->handleDrop(window(), event, false);
+ } else {
+ qWarning() << "unhandled client message:" << connection()->atomName(event->type);
}
}
@@ -581,11 +1127,8 @@ void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t *
QRect rect(xpos, ypos, event->width, event->height);
- if (rect == geometry())
- return;
-
QPlatformWindow::setGeometry(rect);
- QWindowSystemInterface::handleGeometryChange(widget(), rect);
+ QWindowSystemInterface::handleGeometryChange(window(), rect);
#if XCB_USE_DRI2
if (m_context)
@@ -593,6 +1136,22 @@ void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t *
#endif
}
+void QXcbWindow::handleMapNotifyEvent(const xcb_map_notify_event_t *event)
+{
+ if (event->window == m_window) {
+ m_mapped = true;
+ QWindowSystemInterface::handleMapEvent(window());
+ }
+}
+
+void QXcbWindow::handleUnmapNotifyEvent(const xcb_unmap_notify_event_t *event)
+{
+ if (event->window == m_window) {
+ m_mapped = false;
+ QWindowSystemInterface::handleUnmapEvent(window());
+ }
+}
+
static Qt::MouseButtons translateMouseButtons(int s)
{
Qt::MouseButtons ret = 0;
@@ -621,6 +1180,8 @@ static Qt::MouseButton translateMouseButton(xcb_button_t s)
void QXcbWindow::handleButtonPressEvent(const xcb_button_press_event_t *event)
{
+ updateNetWmUserTime(event->time);
+
QPoint local(event->event_x, event->event_y);
QPoint global(event->root_x, event->root_y);
@@ -633,7 +1194,7 @@ void QXcbWindow::handleButtonPressEvent(const xcb_button_press_event_t *event)
&& (modifiers & Qt::AltModifier))
|| (event->detail == 6 || event->detail == 7));
- QWindowSystemInterface::handleWheelEvent(widget(), event->time,
+ QWindowSystemInterface::handleWheelEvent(window(), event->time,
local, global, delta, hor ? Qt::Horizontal : Qt::Vertical);
return;
}
@@ -659,32 +1220,65 @@ void QXcbWindow::handleMotionNotifyEvent(const xcb_motion_notify_event_t *event)
void QXcbWindow::handleMouseEvent(xcb_button_t detail, uint16_t state, xcb_timestamp_t time, const QPoint &local, const QPoint &global)
{
+ connection()->setTime(time);
+
Qt::MouseButtons buttons = translateMouseButtons(state);
Qt::MouseButton button = translateMouseButton(detail);
buttons ^= button; // X event uses state *before*, Qt uses state *after*
- QWindowSystemInterface::handleMouseEvent(widget(), time, local, global, buttons);
+ QWindowSystemInterface::handleMouseEvent(window(), time, local, global, buttons);
}
-void QXcbWindow::handleEnterNotifyEvent(const xcb_enter_notify_event_t *)
+void QXcbWindow::handleEnterNotifyEvent(const xcb_enter_notify_event_t *event)
{
- QWindowSystemInterface::handleEnterEvent(widget());
+ connection()->setTime(event->time);
+
+ if ((event->mode != XCB_NOTIFY_MODE_NORMAL && event->mode != XCB_NOTIFY_MODE_UNGRAB)
+ || event->detail == XCB_NOTIFY_DETAIL_VIRTUAL
+ || event->detail == XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL)
+ {
+ return;
+ }
+
+ QWindowSystemInterface::handleEnterEvent(window());
}
-void QXcbWindow::handleLeaveNotifyEvent(const xcb_leave_notify_event_t *)
+void QXcbWindow::handleLeaveNotifyEvent(const xcb_leave_notify_event_t *event)
{
- QWindowSystemInterface::handleLeaveEvent(widget());
+ connection()->setTime(event->time);
+
+ if ((event->mode != XCB_NOTIFY_MODE_NORMAL && event->mode != XCB_NOTIFY_MODE_UNGRAB)
+ || event->detail == XCB_NOTIFY_DETAIL_INFERIOR)
+ {
+ return;
+ }
+
+ QWindowSystemInterface::handleLeaveEvent(window());
}
void QXcbWindow::handleFocusInEvent(const xcb_focus_in_event_t *)
{
- QWindowSystemInterface::handleWindowActivated(widget());
+ QWindowSystemInterface::handleWindowActivated(window());
+}
+
+static bool focusInPeeker(xcb_generic_event_t *event)
+{
+ if (!event) {
+ // FocusIn event is not in the queue, proceed with FocusOut normally.
+ QWindowSystemInterface::handleWindowActivated(0);
+ return true;
+ }
+ uint response_type = event->response_type & ~0x80;
+ return response_type == XCB_FOCUS_IN;
}
void QXcbWindow::handleFocusOutEvent(const xcb_focus_out_event_t *)
{
- QWindowSystemInterface::handleWindowActivated(0);
+ // Do not set the active window to 0 if there is a FocusIn coming.
+ // There is however no equivalent for XPutBackEvent so register a
+ // callback for QXcbConnection instead.
+ connection()->addPeekFunc(focusInPeeker);
}
void QXcbWindow::updateSyncRequestCounter()
@@ -698,3 +1292,47 @@ void QXcbWindow::updateSyncRequestCounter()
m_syncValue.hi = 0;
}
}
+
+bool QXcbWindow::setKeyboardGrabEnabled(bool grab)
+{
+ if (!grab) {
+ xcb_ungrab_keyboard(xcb_connection(), XCB_TIME_CURRENT_TIME);
+ return true;
+ }
+ xcb_grab_keyboard_cookie_t cookie = xcb_grab_keyboard(xcb_connection(), false,
+ m_window, XCB_TIME_CURRENT_TIME,
+ XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC);
+ xcb_generic_error_t *err;
+ xcb_grab_keyboard_reply_t *reply = xcb_grab_keyboard_reply(xcb_connection(), cookie, &err);
+ bool result = !(err || !reply || reply->status != XCB_GRAB_STATUS_SUCCESS);
+ free(reply);
+ free(err);
+ return result;
+}
+
+bool QXcbWindow::setMouseGrabEnabled(bool grab)
+{
+ if (!grab) {
+ xcb_ungrab_pointer(xcb_connection(), XCB_TIME_CURRENT_TIME);
+ return true;
+ }
+ xcb_grab_pointer_cookie_t cookie = xcb_grab_pointer(xcb_connection(), false, m_window,
+ (XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE
+ | XCB_EVENT_MASK_BUTTON_MOTION | XCB_EVENT_MASK_ENTER_WINDOW
+ | XCB_EVENT_MASK_LEAVE_WINDOW | XCB_EVENT_MASK_POINTER_MOTION),
+ XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC,
+ XCB_WINDOW_NONE, XCB_CURSOR_NONE,
+ XCB_TIME_CURRENT_TIME);
+ xcb_generic_error_t *err;
+ xcb_grab_pointer_reply_t *reply = xcb_grab_pointer_reply(xcb_connection(), cookie, &err);
+ bool result = !(err || !reply || reply->status != XCB_GRAB_STATUS_SUCCESS);
+ free(reply);
+ free(err);
+ return result;
+}
+
+void QXcbWindow::setCursor(xcb_cursor_t cursor)
+{
+ xcb_change_window_attributes(xcb_connection(), m_window, XCB_CW_CURSOR, &cursor);
+ xcb_flush(xcb_connection());
+}
diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h
index 69d0bc2f1d..a85760ea8d 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.h
+++ b/src/plugins/platforms/xcb/qxcbwindow.h
@@ -43,7 +43,7 @@
#define QXCBWINDOW_H
#include <QtGui/QPlatformWindow>
-#include <QtGui/QPlatformWindowFormat>
+#include <QtGui/QSurfaceFormat>
#include <QtGui/QImage>
#include <xcb/xcb.h>
@@ -52,35 +52,47 @@
#include "qxcbobject.h"
class QXcbScreen;
+class QXcbEGLSurface;
class QXcbWindow : public QXcbObject, public QPlatformWindow
{
public:
- QXcbWindow(QWidget *tlw);
+ QXcbWindow(QWindow *window);
~QXcbWindow();
void setGeometry(const QRect &rect);
+ QMargins frameMargins() const;
+
void setVisible(bool visible);
Qt::WindowFlags setWindowFlags(Qt::WindowFlags flags);
+ Qt::WindowState setWindowState(Qt::WindowState state);
WId winId() const;
void setParent(const QPlatformWindow *window);
void setWindowTitle(const QString &title);
void raise();
void lower();
+ void propagateSizeHints();
void requestActivateWindow();
- QPlatformGLContext *glContext() const;
+ bool setKeyboardGrabEnabled(bool grab);
+ bool setMouseGrabEnabled(bool grab);
+
+ void setCursor(xcb_cursor_t cursor);
- xcb_window_t window() const { return m_window; }
+ QSurfaceFormat format() const;
+
+ xcb_window_t xcb_window() const { return m_window; }
uint depth() const { return m_depth; }
- QImage::Format format() const { return m_format; }
+ QImage::Format imageFormat() const { return m_imageFormat; }
void handleExposeEvent(const xcb_expose_event_t *event);
void handleClientMessageEvent(const xcb_client_message_event_t *event);
void handleConfigureNotifyEvent(const xcb_configure_notify_event_t *event);
+ void handleMapNotifyEvent(const xcb_map_notify_event_t *event);
+ void handleUnmapNotifyEvent(const xcb_unmap_notify_event_t *event);
void handleButtonPressEvent(const xcb_button_press_event_t *event);
void handleButtonReleaseEvent(const xcb_button_release_event_t *event);
void handleMotionNotifyEvent(const xcb_motion_notify_event_t *event);
@@ -93,22 +105,54 @@ public:
void handleMouseEvent(xcb_button_t detail, uint16_t state, xcb_timestamp_t time, const QPoint &local, const QPoint &global);
void updateSyncRequestCounter();
+ void updateNetWmUserTime(xcb_timestamp_t timestamp);
+ void netWmUserTime() const;
+
+#if defined(XCB_USE_EGL)
+ QXcbEGLSurface *eglSurface() const;
+#endif
private:
- void setNetWmWindowTypes(Qt::WindowFlags flags);
+ void changeNetWmState(bool set, xcb_atom_t one, xcb_atom_t two = 0);
+ QVector<xcb_atom_t> getNetWmState();
+ void setNetWmState(const QVector<xcb_atom_t> &atoms);
+ void printNetWmState(const QVector<xcb_atom_t> &state);
+
+ void setNetWmWindowFlags(Qt::WindowFlags flags);
+ void setMotifWindowFlags(Qt::WindowFlags flags);
+
+ void updateMotifWmHintsBeforeMap();
+ void updateNetWmStateBeforeMap();
+
+ void create();
+ void destroy();
+
+ void show();
+ void hide();
QXcbScreen *m_screen;
xcb_window_t m_window;
- QPlatformGLContext *m_context;
uint m_depth;
- QImage::Format m_format;
+ QImage::Format m_imageFormat;
xcb_sync_int64_t m_syncValue;
xcb_sync_counter_t m_syncCounter;
- bool m_hasReceivedSyncRequest;
+ Qt::WindowState m_windowState;
+
+ bool m_mapped;
+ xcb_window_t m_netWmUserTimeWindow;
+
+ QSurfaceFormat m_requestedFormat;
+
+ mutable bool m_dirtyFrameMargins;
+ mutable QMargins m_frameMargins;
+
+#if defined(XCB_USE_EGL)
+ mutable QXcbEGLSurface *m_eglSurface;
+#endif
};
#endif
diff --git a/src/plugins/platforms/xcb/qxcbwindowsurface.cpp b/src/plugins/platforms/xcb/qxcbwindowsurface.cpp
deleted file mode 100644
index 4fcd207df3..0000000000
--- a/src/plugins/platforms/xcb/qxcbwindowsurface.cpp
+++ /dev/null
@@ -1,270 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qxcbwindowsurface.h"
-
-#include "qxcbconnection.h"
-#include "qxcbscreen.h"
-#include "qxcbwindow.h"
-
-#include <xcb/shm.h>
-#include <xcb/xcb_image.h>
-
-#include <sys/ipc.h>
-#include <sys/shm.h>
-
-#include <stdio.h>
-
-#include <qdebug.h>
-#include <qpainter.h>
-
-class QXcbShmImage : public QXcbObject
-{
-public:
- QXcbShmImage(QXcbScreen *connection, const QSize &size, uint depth, QImage::Format format);
- ~QXcbShmImage() { destroy(); }
-
- QImage *image() { return &m_qimage; }
-
- void put(xcb_window_t window, const QPoint &dst, const QRect &source);
- void preparePaint(const QRegion &region);
-
-private:
- void destroy();
-
- xcb_shm_segment_info_t m_shm_info;
-
- xcb_image_t *m_xcb_image;
-
- QImage m_qimage;
-
- xcb_gcontext_t m_gc;
- xcb_window_t m_gc_window;
-
- QRegion m_dirty;
-};
-
-QXcbShmImage::QXcbShmImage(QXcbScreen *screen, const QSize &size, uint depth, QImage::Format format)
- : QXcbObject(screen->connection())
- , m_gc(0)
- , m_gc_window(0)
-{
- Q_XCB_NOOP(connection());
- m_xcb_image = xcb_image_create_native(xcb_connection(),
- size.width(),
- size.height(),
- XCB_IMAGE_FORMAT_Z_PIXMAP,
- depth,
- 0,
- ~0,
- 0);
-
- m_shm_info.shmid = shmget (IPC_PRIVATE,
- m_xcb_image->stride * m_xcb_image->height, IPC_CREAT|0777);
-
- m_shm_info.shmaddr = m_xcb_image->data = (quint8 *)shmat (m_shm_info.shmid, 0, 0);
- m_shm_info.shmseg = xcb_generate_id(xcb_connection());
-
- xcb_generic_error_t *error = xcb_request_check(xcb_connection(), xcb_shm_attach_checked(xcb_connection(), m_shm_info.shmseg, m_shm_info.shmid, false));
- if (error) {
- qWarning() << "QXcbWindowSurface: Unable to attach to shared memory segment";
- free(error);
- }
-
- if (shmctl(m_shm_info.shmid, IPC_RMID, 0) == -1)
- qWarning() << "QXcbWindowSurface: Error while marking the shared memory segment to be destroyed";
-
- m_qimage = QImage( (uchar*) m_xcb_image->data, m_xcb_image->width, m_xcb_image->height, m_xcb_image->stride, format);
-}
-
-void QXcbShmImage::destroy()
-{
- Q_XCB_CALL(xcb_shm_detach(xcb_connection(), m_shm_info.shmseg));
- xcb_image_destroy(m_xcb_image);
- shmdt(m_shm_info.shmaddr);
- shmctl(m_shm_info.shmid, IPC_RMID, 0);
- if (m_gc)
- Q_XCB_CALL(xcb_free_gc(xcb_connection(), m_gc));
-}
-
-void QXcbShmImage::put(xcb_window_t window, const QPoint &target, const QRect &source)
-{
- Q_XCB_NOOP(connection());
- if (m_gc_window != window) {
- if (m_gc)
- Q_XCB_CALL(xcb_free_gc(xcb_connection(), m_gc));
-
- m_gc = xcb_generate_id(xcb_connection());
- Q_XCB_CALL(xcb_create_gc(xcb_connection(), m_gc, window, 0, 0));
-
- m_gc_window = window;
- }
-
- Q_XCB_NOOP(connection());
- xcb_image_shm_put(xcb_connection(),
- window,
- m_gc,
- m_xcb_image,
- m_shm_info,
- source.x(),
- source.y(),
- target.x(),
- target.y(),
- source.width(),
- source.height(),
- false);
- Q_XCB_NOOP(connection());
-
- m_dirty = m_dirty | source;
-
- xcb_flush(xcb_connection());
- Q_XCB_NOOP(connection());
-}
-
-void QXcbShmImage::preparePaint(const QRegion &region)
-{
- // to prevent X from reading from the image region while we're writing to it
- if (m_dirty.intersects(region)) {
- connection()->sync();
- m_dirty = QRegion();
- }
-}
-
-QXcbWindowSurface::QXcbWindowSurface(QWidget *widget, bool setDefaultSurface)
- : QWindowSurface(widget, setDefaultSurface)
- , m_image(0)
- , m_syncingResize(false)
-{
- QXcbScreen *screen = static_cast<QXcbScreen *>(QPlatformScreen::platformScreenForWidget(widget));
- setConnection(screen->connection());
-}
-
-QXcbWindowSurface::~QXcbWindowSurface()
-{
- delete m_image;
-}
-
-QPaintDevice *QXcbWindowSurface::paintDevice()
-{
- return m_image->image();
-}
-
-void QXcbWindowSurface::beginPaint(const QRegion &region)
-{
- m_image->preparePaint(region);
-
- if (m_image->image()->hasAlphaChannel()) {
- QPainter p(m_image->image());
- p.setCompositionMode(QPainter::CompositionMode_Source);
- const QVector<QRect> rects = region.rects();
- const QColor blank = Qt::transparent;
- for (QVector<QRect>::const_iterator it = rects.begin(); it != rects.end(); ++it) {
- p.fillRect(*it, blank);
- }
- }
-}
-
-void QXcbWindowSurface::endPaint(const QRegion &)
-{
-}
-
-void QXcbWindowSurface::flush(QWidget *widget, const QRegion &region, const QPoint &offset)
-{
- QRect bounds = region.boundingRect();
-
- if (size().isEmpty() || !geometry().contains(bounds))
- return;
-
- Q_XCB_NOOP(connection());
-
- QXcbWindow *window = static_cast<QXcbWindow *>(widget->window()->platformWindow());
-
- extern QWidgetData* qt_widget_data(QWidget *);
- QPoint widgetOffset = qt_qwidget_data(widget)->wrect.topLeft();
-
- QVector<QRect> rects = region.rects();
- for (int i = 0; i < rects.size(); ++i)
- m_image->put(window->window(), rects.at(i).topLeft() - widgetOffset, rects.at(i).translated(offset));
-
- Q_XCB_NOOP(connection());
-
- if (m_syncingResize) {
- xcb_flush(xcb_connection());
- connection()->sync();
- m_syncingResize = false;
- window->updateSyncRequestCounter();
- }
-}
-
-void QXcbWindowSurface::resize(const QSize &size)
-{
- if (size == QWindowSurface::size())
- return;
-
- Q_XCB_NOOP(connection());
- QWindowSurface::resize(size);
-
- QXcbScreen *screen = static_cast<QXcbScreen *>(QPlatformScreen::platformScreenForWidget(window()));
- QXcbWindow* win = static_cast<QXcbWindow *>(window()->platformWindow());
-
- delete m_image;
- m_image = new QXcbShmImage(screen, size, win->depth(), win->format());
- Q_XCB_NOOP(connection());
-
- m_syncingResize = true;
-}
-
-extern void qt_scrollRectInImage(QImage &img, const QRect &rect, const QPoint &offset);
-
-bool QXcbWindowSurface::scroll(const QRegion &area, int dx, int dy)
-{
- if (m_image->image()->isNull())
- return false;
-
- m_image->preparePaint(area);
-
- const QVector<QRect> rects = area.rects();
- for (int i = 0; i < rects.size(); ++i)
- qt_scrollRectInImage(*m_image->image(), rects.at(i), QPoint(dx, dy));
-
- return true;
-}
-
diff --git a/src/plugins/platforms/xcb/qxcbwindowsurface.h b/src/plugins/platforms/xcb/qxcbwindowsurface.h
deleted file mode 100644
index 5f61815b65..0000000000
--- a/src/plugins/platforms/xcb/qxcbwindowsurface.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QXCBWINDOWSURFACE_H
-#define QXCBWINDOWSURFACE_H
-
-#include <private/qwindowsurface_p.h>
-
-#include <xcb/xcb.h>
-
-#include "qxcbobject.h"
-
-class QXcbShmImage;
-
-class QXcbWindowSurface : public QXcbObject, public QWindowSurface
-{
-public:
- QXcbWindowSurface(QWidget *widget, bool setDefaultSurface = true);
- ~QXcbWindowSurface();
-
- QPaintDevice *paintDevice();
- void flush(QWidget *widget, const QRegion &region, const QPoint &offset);
- void resize(const QSize &size);
- bool scroll(const QRegion &area, int dx, int dy);
-
- void beginPaint(const QRegion &);
- void endPaint(const QRegion &);
-
-private:
- QXcbShmImage *m_image;
- bool m_syncingResize;
-};
-
-#endif
diff --git a/src/plugins/platforms/xcb/qxcbwmsupport.cpp b/src/plugins/platforms/xcb/qxcbwmsupport.cpp
new file mode 100644
index 0000000000..5fb67b6377
--- /dev/null
+++ b/src/plugins/platforms/xcb/qxcbwmsupport.cpp
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxcbwmsupport.h"
+#include "qxcbscreen.h"
+
+#include <qdebug.h>
+
+QXcbWMSupport::QXcbWMSupport(QXcbConnection *c)
+ : QXcbObject(c)
+{
+ updateNetWMAtoms();
+ updateVirtualRoots();
+}
+
+bool QXcbWMSupport::isSupportedByWM(xcb_atom_t atom) const
+{
+ return net_wm_atoms.contains(atom);
+}
+
+
+
+void QXcbWMSupport::updateNetWMAtoms()
+{
+ net_wm_atoms.clear();
+
+ xcb_window_t root = connection()->screens().at(connection()->primaryScreen())->root();
+ int offset = 0;
+ int remaining = 0;
+ do {
+ xcb_generic_error_t *error = 0;
+ xcb_get_property_cookie_t cookie = xcb_get_property(xcb_connection(), false, root, atom(QXcbAtom::_NET_SUPPORTED), XCB_ATOM_ATOM, offset, 1024);
+ xcb_get_property_reply_t *reply = xcb_get_property_reply(xcb_connection(), cookie, &error);
+ if (!reply || error)
+ break;
+
+ remaining = 0;
+
+ if (reply->type == XCB_ATOM_ATOM && reply->format == 32) {
+ int len = xcb_get_property_value_length(reply)/4;
+ xcb_atom_t *atoms = (xcb_atom_t *)xcb_get_property_value(reply);
+ int s = net_wm_atoms.size();
+ net_wm_atoms.resize(s + len);
+ memcpy(net_wm_atoms.data() + s, atoms, len*sizeof(xcb_atom_t));
+
+ remaining = reply->bytes_after;
+ offset += len;
+ }
+
+ free(reply);
+ } while (remaining > 0);
+
+// qDebug() << "======== updateNetWMAtoms";
+// for (int i = 0; i < net_wm_atoms.size(); ++i)
+// qDebug() << atomName(net_wm_atoms.at(i));
+// qDebug() << "======== updateNetWMAtoms";
+}
+
+// update the virtual roots array
+void QXcbWMSupport::updateVirtualRoots()
+{
+ net_virtual_roots.clear();
+
+ if (!isSupportedByWM(atom(QXcbAtom::_NET_VIRTUAL_ROOTS)))
+ return;
+
+ xcb_window_t root = connection()->screens().at(connection()->primaryScreen())->root();
+ int offset = 0;
+ int remaining = 0;
+ do {
+ xcb_generic_error_t *error = 0;
+ xcb_get_property_cookie_t cookie = xcb_get_property(xcb_connection(), false, root, atom(QXcbAtom::_NET_VIRTUAL_ROOTS), XCB_ATOM_ATOM, offset, 1024);
+ xcb_get_property_reply_t *reply = xcb_get_property_reply(xcb_connection(), cookie, &error);
+ if (!reply || error)
+ break;
+
+ remaining = 0;
+
+ if (reply->type == XCB_ATOM_ATOM && reply->format == 32) {
+ int len = xcb_get_property_value_length(reply)/4;
+ xcb_atom_t *atoms = (xcb_atom_t *)xcb_get_property_value(reply);
+ int s = net_wm_atoms.size();
+ net_wm_atoms.resize(s + len);
+ memcpy(net_wm_atoms.data() + s, atoms, len*sizeof(xcb_atom_t));
+
+ remaining = reply->bytes_after;
+ offset += len;
+ }
+
+ free(reply);
+ } while (remaining > 0);
+
+ qDebug() << "======== updateVirtualRoots";
+ for (int i = 0; i < net_virtual_roots.size(); ++i)
+ qDebug() << connection()->atomName(net_virtual_roots.at(i));
+ qDebug() << "======== updateVirtualRoots";
+}
+
diff --git a/src/plugins/platforms/xcb/qxcbwmsupport.h b/src/plugins/platforms/xcb/qxcbwmsupport.h
new file mode 100644
index 0000000000..3b02ef3e7e
--- /dev/null
+++ b/src/plugins/platforms/xcb/qxcbwmsupport.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QXCBWMSUPPORT_H
+#define QXCBWMSUPPORT_H
+
+#include "qxcbobject.h"
+#include "qxcbconnection.h"
+#include <qvector.h>
+
+class QXcbWMSupport : public QXcbObject
+{
+public:
+ QXcbWMSupport(QXcbConnection *c);
+
+
+ bool isSupportedByWM(xcb_atom_t atom) const;
+ const QVector<xcb_window_t> &virtualRoots() const { return net_virtual_roots; }
+
+private:
+ friend class QXcbConnection;
+ void updateNetWMAtoms();
+ void updateVirtualRoots();
+
+ QVector<xcb_atom_t> net_wm_atoms;
+ QVector<xcb_window_t> net_virtual_roots;
+};
+
+
+#endif
diff --git a/src/plugins/platforms/xcb/xcb.pro b/src/plugins/platforms/xcb/xcb.pro
index 27d10b6756..143a671047 100644
--- a/src/plugins/platforms/xcb/xcb.pro
+++ b/src/plugins/platforms/xcb/xcb.pro
@@ -3,70 +3,91 @@ TARGET = xcb
load(qt_plugin)
QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/platforms
-QT += core-private gui-private
+QT += core-private gui-private platformsupport-private
SOURCES = \
+ qxcbclipboard.cpp \
qxcbconnection.cpp \
qxcbintegration.cpp \
qxcbkeyboard.cpp \
+ qxcbmime.cpp \
+ qxcbdrag.cpp \
qxcbscreen.cpp \
qxcbwindow.cpp \
- qxcbwindowsurface.cpp \
+ qxcbbackingstore.cpp \
+ qxcbwmsupport.cpp \
main.cpp \
- qxcbnativeinterface.cpp
+ qxcbnativeinterface.cpp \
+ qxcbcursor.cpp \
+ qxcbimage.cpp
HEADERS = \
+ qxcbclipboard.h \
qxcbconnection.h \
qxcbintegration.h \
qxcbkeyboard.h \
+ qxcbdrag.h \
+ qxcbmime.h \
qxcbobject.h \
qxcbscreen.h \
qxcbwindow.h \
- qxcbwindowsurface.h \
- qxcbnativeinterface.h
+ qxcbbackingstore.h \
+ qxcbwmsupport.h \
+ qxcbnativeinterface.h \
+ qxcbcursor.h \
+ qxcbimage.h
-contains(QT_CONFIG, opengl) {
- QT += opengl
+contains(QT_CONFIG, xcb-poll-for-queued-event) {
+ DEFINES += XCB_POLL_FOR_QUEUED_EVENT
+}
+
+# needed by GLX, Xcursor, XLookupString, ...
+contains(QT_CONFIG, xcb-xlib) {
+ DEFINES += XCB_USE_XLIB
+ LIBS += -lX11 -lX11-xcb
+}
+
+# to support custom cursors with depth > 1
+contains(QT_CONFIG, xcb-render) {
+ DEFINES += XCB_USE_RENDER
+ LIBS += -lxcb-render -lxcb-render-util -lXrender
+}
# DEFINES += XCB_USE_DRI2
- contains(DEFINES, XCB_USE_DRI2) {
- LIBS += -lxcb-dri2 -lxcb-xfixes -lEGL
-
- CONFIG += link_pkgconfig
- PKGCONFIG += libdrm
-
- HEADERS += qdri2context.h
- SOURCES += qdri2context.cpp
-
- } else {
- DEFINES += XCB_USE_XLIB
- LIBS += -lX11 -lX11-xcb
-
- contains(QT_CONFIG, opengles2) {
- DEFINES += XCB_USE_EGL
- HEADERS += \
- ../eglconvenience/qeglplatformcontext.h \
- ../eglconvenience/qeglconvenience.h \
- ../eglconvenience/qxlibeglintegration.h
-
- SOURCES += \
- ../eglconvenience/qeglplatformcontext.cpp \
- ../eglconvenience/qeglconvenience.cpp \
- ../eglconvenience/qxlibeglintegration.cpp
-
- LIBS += -lEGL
- } else {
- DEFINES += XCB_USE_GLX
- include (../glxconvenience/glxconvenience.pri)
- HEADERS += qglxintegration.h
- SOURCES += qglxintegration.cpp
- }
+contains(DEFINES, XCB_USE_DRI2) {
+ LIBS += -lxcb-dri2 -lEGL
+
+ CONFIG += link_pkgconfig
+ PKGCONFIG += libdrm
+
+ HEADERS += qdri2context.h
+ SOURCES += qdri2context.cpp
+
+} else {
+ contains(QT_CONFIG, opengles2) {
+ DEFINES += XCB_USE_EGL
+ LIBS += -lEGL
+ HEADERS += qxcbeglsurface.h
+ } else:contains(QT_CONFIG, xcb-xlib) {
+ DEFINES += XCB_USE_GLX
+ HEADERS += qglxintegration.h
+ SOURCES += qglxintegration.cpp
}
}
-LIBS += -lxcb -lxcb-image -lxcb-keysyms -lxcb-icccm -lxcb-sync
+LIBS += -lxcb -lxcb-image -lxcb-keysyms -lxcb-icccm -lxcb-sync -lxcb-xfixes
+
+DEFINES += $$QMAKE_DEFINES_XCB
+LIBS += $$QMAKE_LIBS_XCB
+QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_XCB
-include (../fontdatabases/genericunix/genericunix.pri)
+CONFIG += qpa/genericunixfontdatabase
+
+contains(QT_CONFIG, dbus) {
+DEFINES += XCB_USE_IBUS
+QT += dbus
+LIBS += -ldbus-1
+}
target.path += $$[QT_INSTALL_PLUGINS]/platforms
INSTALLS += target
diff --git a/src/plugins/platforms/xlib/main.cpp b/src/plugins/platforms/xlib/main.cpp
index 63eba3288b..b4241fa228 100644
--- a/src/plugins/platforms/xlib/main.cpp
+++ b/src/plugins/platforms/xlib/main.cpp
@@ -54,10 +54,7 @@ public:
QStringList QXlibIntegrationPlugin::keys() const
{
QStringList list;
- list << "Xlib";
-#ifndef QT_NO_OPENGL
- list << "XlibGL";
-#endif
+ list << "xlib";
return list;
}
@@ -66,10 +63,6 @@ QPlatformIntegration* QXlibIntegrationPlugin::create(const QString& system, cons
Q_UNUSED(paramList);
if (system.toLower() == "xlib")
return new QXlibIntegration;
-#ifndef QT_NO_OPENGL
- if (system.toLower() == "xlibgl")
- return new QXlibIntegration(true);
-#endif
return 0;
}
diff --git a/src/plugins/platforms/xlib/qglxintegration.cpp b/src/plugins/platforms/xlib/qglxintegration.cpp
index d827d606bb..6733f22093 100644
--- a/src/plugins/platforms/xlib/qglxintegration.cpp
+++ b/src/plugins/platforms/xlib/qglxintegration.cpp
@@ -51,7 +51,7 @@
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <GL/glx.h>
-#include "qglxconvenience.h"
+#include "private/qglxconvenience_p.h"
#include "qglxintegration.h"
@@ -61,34 +61,24 @@
QT_BEGIN_NAMESPACE
-QGLXContext::QGLXContext(Window window, QXlibScreen *screen, const QPlatformWindowFormat &format)
- : QPlatformGLContext()
+QGLXContext::QGLXContext(QXlibScreen *screen, const QSurfaceFormat &format, QPlatformOpenGLContext *share)
+ : QPlatformOpenGLContext()
, m_screen(screen)
- , m_drawable((Drawable)window)
, m_context(0)
{
-
- const QPlatformGLContext *sharePlatformContext;
- sharePlatformContext = format.sharedGLContext();
GLXContext shareGlxContext = 0;
- if (sharePlatformContext)
- shareGlxContext = static_cast<const QGLXContext*>(sharePlatformContext)->glxContext();
+ if (share)
+ shareGlxContext = static_cast<const QGLXContext*>(share)->glxContext();
GLXFBConfig config = qglx_findConfig(screen->display()->nativeDisplay(),screen->xScreenNumber(),format);
m_context = glXCreateNewContext(screen->display()->nativeDisplay(),config,GLX_RGBA_TYPE,shareGlxContext,TRUE);
- m_windowFormat = qglx_platformWindowFromGLXFBConfig(screen->display()->nativeDisplay(),config,m_context);
+ m_windowFormat = qglx_surfaceFormatFromGLXFBConfig(screen->display()->nativeDisplay(),config,m_context);
#ifdef MYX11_DEBUG
qDebug() << "QGLXGLContext::create context" << m_context;
#endif
}
-QGLXContext::QGLXContext(QXlibScreen *screen, Drawable drawable, GLXContext context)
- : QPlatformGLContext(), m_screen(screen), m_drawable(drawable), m_context(context)
-{
-
-}
-
QGLXContext::~QGLXContext()
{
if (m_context) {
@@ -97,27 +87,36 @@ QGLXContext::~QGLXContext()
}
}
-void QGLXContext::makeCurrent()
+QSurfaceFormat QGLXContext::format() const
{
- QPlatformGLContext::makeCurrent();
+ return m_windowFormat;
+}
+
+bool QGLXContext::makeCurrent(QPlatformSurface *surface)
+{
+ Q_UNUSED(surface);
+
+ GLXDrawable glxDrawable = static_cast<QXlibWindow *>(surface)->winId();
#ifdef MYX11_DEBUG
- qDebug("QGLXGLContext::makeCurrent(window=0x%x, ctx=0x%x)", m_drawable, m_context);
+ qDebug("QGLXGLContext::makeCurrent(window=0x%x, ctx=0x%x)", glxDrawable, m_context);
#endif
- glXMakeCurrent(m_screen->display()->nativeDisplay(), m_drawable, m_context);
+ return glXMakeCurrent(m_screen->display()->nativeDisplay(), glxDrawable, m_context);
}
void QGLXContext::doneCurrent()
{
- QPlatformGLContext::doneCurrent();
glXMakeCurrent(m_screen->display()->nativeDisplay(), 0, 0);
}
-void QGLXContext::swapBuffers()
+void QGLXContext::swapBuffers(QPlatformSurface *surface)
{
- glXSwapBuffers(m_screen->display()->nativeDisplay(), m_drawable);
+ Q_UNUSED(surface);
+
+ GLXDrawable glxDrawable = static_cast<QXlibWindow *>(surface)->winId();
+ glXSwapBuffers(m_screen->display()->nativeDisplay(), glxDrawable);
}
-void* QGLXContext::getProcAddress(const QString& procName)
+void (*QGLXContext::getProcAddress(const QByteArray& procName))()
{
typedef void *(*qt_glXGetProcAddressARB)(const GLubyte *);
static qt_glXGetProcAddressARB glXGetProcAddressARB = 0;
@@ -147,10 +146,10 @@ void* QGLXContext::getProcAddress(const QString& procName)
}
if (!glXGetProcAddressARB)
return 0;
- return glXGetProcAddressARB(reinterpret_cast<const GLubyte *>(procName.toLatin1().data()));
+ return (void (*)())glXGetProcAddressARB(reinterpret_cast<const GLubyte *>(procName.constData()));
}
-QPlatformWindowFormat QGLXContext::platformWindowFormat() const
+QSurfaceFormat QGLXContext::surfaceFormat() const
{
return m_windowFormat;
}
diff --git a/src/plugins/platforms/xlib/qglxintegration.h b/src/plugins/platforms/xlib/qglxintegration.h
index 07c2a77f5d..e3172b718c 100644
--- a/src/plugins/platforms/xlib/qglxintegration.h
+++ b/src/plugins/platforms/xlib/qglxintegration.h
@@ -44,8 +44,8 @@
#include "qxlibwindow.h"
-#include <QtGui/QPlatformGLContext>
-#include <QtGui/QPlatformWindowFormat>
+#include <QtGui/QPlatformOpenGLContext>
+#include <QtGui/qsurfaceformat.h>
#include <QtCore/QMutex>
@@ -54,28 +54,26 @@
QT_BEGIN_NAMESPACE
-class QGLXContext : public QPlatformGLContext
+class QGLXContext : public QPlatformOpenGLContext
{
public:
- QGLXContext(Window window, QXlibScreen *xd, const QPlatformWindowFormat &format);
+ QGLXContext(QXlibScreen *xd, const QSurfaceFormat &format, QPlatformOpenGLContext *share);
~QGLXContext();
- virtual void makeCurrent();
- virtual void doneCurrent();
- virtual void swapBuffers();
- virtual void* getProcAddress(const QString& procName);
+ QSurfaceFormat format() const;
+ void swapBuffers(QPlatformSurface *surface);
+ bool makeCurrent(QPlatformSurface *surface);
+ void doneCurrent();
+ virtual void (*getProcAddress(const QByteArray& procName))();
GLXContext glxContext() const {return m_context;}
- QPlatformWindowFormat platformWindowFormat() const;
+ QSurfaceFormat surfaceFormat() const;
private:
QXlibScreen *m_screen;
- Drawable m_drawable;
GLXContext m_context;
- QPlatformWindowFormat m_windowFormat;
-
- QGLXContext (QXlibScreen *screen, Drawable drawable, GLXContext context);
+ QSurfaceFormat m_windowFormat;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xlib/qxlibbackingstore.cpp b/src/plugins/platforms/xlib/qxlibbackingstore.cpp
new file mode 100644
index 0000000000..24a346a29d
--- /dev/null
+++ b/src/plugins/platforms/xlib/qxlibbackingstore.cpp
@@ -0,0 +1,223 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxlibbackingstore.h"
+#include "qxlibintegration.h"
+
+#include <QtCore/qdebug.h>
+#include <QWindowSystemInterface>
+
+#include "qxlibwindow.h"
+#include "qxlibscreen.h"
+#include "qxlibdisplay.h"
+
+#include "qpainter.h"
+
+# include <sys/ipc.h>
+# include <sys/shm.h>
+# include <X11/extensions/XShm.h>
+
+QT_BEGIN_NAMESPACE
+
+struct QXlibShmImageInfo {
+ QXlibShmImageInfo(Display *xdisplay) : image(0), display(xdisplay) {}
+ ~QXlibShmImageInfo() { destroy(); }
+
+ void destroy();
+
+ XShmSegmentInfo shminfo;
+ XImage *image;
+ Display *display;
+};
+
+
+#ifndef DONT_USE_MIT_SHM
+void QXlibShmImageInfo::destroy()
+{
+ XShmDetach (display, &shminfo);
+ XDestroyImage (image);
+ shmdt (shminfo.shmaddr);
+ shmctl (shminfo.shmid, IPC_RMID, 0);
+}
+#endif
+
+void QXlibBackingStore::resizeShmImage(int width, int height)
+{
+ QXlibScreen *screen = QXlibScreen::testLiteScreenForWidget(window());
+ QXlibWindow *win = static_cast<QXlibWindow*>(window()->handle());
+
+ QImage::Format format = win->depth() == 16 ? QImage::Format_RGB16 : QImage::Format_RGB32;
+
+#ifdef DONT_USE_MIT_SHM
+ shm_img = QImage(width, height, format);
+#else
+
+ if (image_info)
+ image_info->destroy();
+ else
+ image_info = new QXlibShmImageInfo(screen->display()->nativeDisplay());
+
+ XImage *image = XShmCreateImage (screen->display()->nativeDisplay(), win->visual(), win->depth(), ZPixmap, 0,
+ &image_info->shminfo, width, height);
+
+
+ image_info->shminfo.shmid = shmget (IPC_PRIVATE,
+ image->bytes_per_line * image->height, IPC_CREAT|0777);
+
+ image_info->shminfo.shmaddr = image->data = (char*)shmat (image_info->shminfo.shmid, 0, 0);
+ image_info->shminfo.readOnly = False;
+
+ image_info->image = image;
+
+ Status shm_attach_status = XShmAttach(screen->display()->nativeDisplay(), &image_info->shminfo);
+
+ Q_ASSERT(shm_attach_status == True);
+
+ shm_img = QImage((uchar*) image->data, image->width, image->height, image->bytes_per_line, format);
+#endif
+ painted = false;
+}
+
+
+void QXlibBackingStore::resizeBuffer(QSize s)
+{
+ if (shm_img.size() != s)
+ resizeShmImage(s.width(), s.height());
+}
+
+QSize QXlibBackingStore::bufferSize() const
+{
+ return shm_img.size();
+}
+
+QXlibBackingStore::QXlibBackingStore(QWindow *window)
+ : QPlatformBackingStore(window),
+ painted(false), image_info(0)
+{
+ xw = static_cast<QXlibWindow*>(window->handle());
+// qDebug() << "QTestLiteWindowSurface::QTestLiteWindowSurface:" << xw->window;
+}
+
+QXlibBackingStore::~QXlibBackingStore()
+{
+ delete image_info;
+}
+
+QPaintDevice *QXlibBackingStore::paintDevice()
+{
+ return &shm_img;
+}
+
+
+void QXlibBackingStore::flush(QWindow *w, const QRegion &region, const QPoint &offset)
+{
+ Q_UNUSED(region);
+ Q_UNUSED(offset);
+
+ if (!painted)
+ return;
+
+ QXlibScreen *screen = QXlibScreen::testLiteScreenForWidget(w);
+ GC gc = xw->graphicsContext();
+ Window window = xw->xWindow();
+#ifdef DONT_USE_MIT_SHM
+ // just convert the image every time...
+ if (!shm_img.isNull()) {
+ QXlibWindow *win = static_cast<QXlibWindow*>(w->handle());
+
+ QImage image = shm_img;
+ //img.convertToFormat(
+ XImage *xi = XCreateImage(screen->display()->nativeDisplay(), win->visual(), win->depth(), ZPixmap,
+ 0, (char *) image.scanLine(0), image.width(), image.height(),
+ 32, image.bytesPerLine());
+
+ int x = 0;
+ int y = 0;
+
+ /*int r =*/ XPutImage(screen->display()->nativeDisplay(), window, gc, xi, 0, 0, x, y, image.width(), image.height());
+
+ xi->data = 0; // QImage owns these bits
+ XDestroyImage(xi);
+ }
+#else
+ // Use MIT_SHM
+ if (image_info && image_info->image) {
+ //qDebug() << "Here we go" << image_info->image->width << image_info->image->height;
+ int x = 0;
+ int y = 0;
+
+ // We could set send_event to true, and then use the ShmCompletion to synchronize,
+ // but let's do like Qt/11 and just use XSync
+ XShmPutImage (screen->display()->nativeDisplay(), window, gc, image_info->image, 0, 0,
+ x, y, image_info->image->width, image_info->image->height,
+ /*send_event*/ False);
+
+ screen->display()->sync();
+ }
+#endif
+}
+
+void QXlibBackingStore::resize(const QSize &size, const QRegion &)
+{
+ resizeBuffer(size);
+}
+
+
+void QXlibBackingStore::beginPaint(const QRegion &region)
+{
+ Q_UNUSED(region);
+
+ if (shm_img.hasAlphaChannel()) {
+ QPainter p(&shm_img);
+ p.setCompositionMode(QPainter::CompositionMode_Source);
+ const QVector<QRect> rects = region.rects();
+ const QColor blank = Qt::transparent;
+ for (QVector<QRect>::const_iterator it = rects.begin(); it != rects.end(); ++it) {
+ p.fillRect(*it, blank);
+ }
+ }
+}
+
+void QXlibBackingStore::endPaint()
+{
+ painted = true; //there is content in the buffer
+}
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xlib/qxlibbackingstore.h b/src/plugins/platforms/xlib/qxlibbackingstore.h
new file mode 100644
index 0000000000..35093f6784
--- /dev/null
+++ b/src/plugins/platforms/xlib/qxlibbackingstore.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSURFACE_TESTLITE_H
+#define QWINDOWSURFACE_TESTLITE_H
+
+#include <QtGui/qplatformbackingstore_qpa.h>
+#include <QtGui/QImage>
+
+QT_BEGIN_NAMESPACE
+
+class QXlibWindow;
+class QXlibIntegration;
+class QXlibScreen;
+class QXlibShmImageInfo;
+
+class QXlibBackingStore : public QPlatformBackingStore
+{
+public:
+ QXlibBackingStore (QWindow *window);
+ ~QXlibBackingStore();
+
+ QPaintDevice *paintDevice();
+ void flush(QWindow *window, const QRegion &region, const QPoint &offset);
+
+ void resize(const QSize &size, const QRegion &staticContents);
+
+ void beginPaint(const QRegion &region);
+ void endPaint();
+
+private:
+ bool painted;
+ void resizeBuffer(QSize);
+ QSize bufferSize() const;
+
+
+ void resizeShmImage(int width, int height);
+
+ QImage shm_img;
+ QXlibShmImageInfo *image_info;
+
+ QXlibWindow *xw;
+
+};
+
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/platforms/xlib/qxlibclipboard.cpp b/src/plugins/platforms/xlib/qxlibclipboard.cpp
index 2c1d91bde8..3ee4d4269c 100644
--- a/src/plugins/platforms/xlib/qxlibclipboard.cpp
+++ b/src/plugins/platforms/xlib/qxlibclipboard.cpp
@@ -39,14 +39,14 @@
**
****************************************************************************/
+#include <private/qguiapplication_p.h>
+
#include "qxlibclipboard.h"
#include "qxlibscreen.h"
#include "qxlibmime.h"
#include "qxlibdisplay.h"
-#include <private/qapplication_p.h>
-
#include <QtCore/QDebug>
class QXlibClipboardMime : public QXlibMime
diff --git a/src/plugins/platforms/xlib/qxlibcursor.cpp b/src/plugins/platforms/xlib/qxlibcursor.cpp
index 0af4aefecd..7a074bc0e6 100644
--- a/src/plugins/platforms/xlib/qxlibcursor.cpp
+++ b/src/plugins/platforms/xlib/qxlibcursor.cpp
@@ -57,12 +57,11 @@ QXlibCursor::QXlibCursor(QXlibScreen *screen)
{
}
-void QXlibCursor::changeCursor(QCursor *cursor, QWidget *widget)
+void QXlibCursor::changeCursor(QCursor *cursor, QWindow *window)
{
QXlibWindow *w = 0;
- if (widget) {
- QWidget *window = widget->window();
- w = static_cast<QXlibWindow*>(window->platformWindow());
+ if (window) {
+ w = static_cast<QXlibWindow*>(window->handle());
} else {
// No X11 cursor control when there is no widget under the cursor
return;
diff --git a/src/plugins/platforms/xlib/qxlibcursor.h b/src/plugins/platforms/xlib/qxlibcursor.h
index e2543d2e2a..fd574778d7 100644
--- a/src/plugins/platforms/xlib/qxlibcursor.h
+++ b/src/plugins/platforms/xlib/qxlibcursor.h
@@ -53,7 +53,7 @@ class QXlibCursor : QPlatformCursor
public:
QXlibCursor(QXlibScreen *screen);
- void changeCursor(QCursor * cursor, QWidget * widget);
+ void changeCursor(QCursor * cursor, QWindow * widget);
private:
Cursor createCursorBitmap(QCursor * cursor);
diff --git a/src/plugins/platforms/xlib/qxlibintegration.cpp b/src/plugins/platforms/xlib/qxlibintegration.cpp
index 02104d9f74..c1f0941619 100644
--- a/src/plugins/platforms/xlib/qxlibintegration.cpp
+++ b/src/plugins/platforms/xlib/qxlibintegration.cpp
@@ -39,91 +39,66 @@
**
****************************************************************************/
+#include <private/qguiapplication_p.h>
#include "qxlibintegration.h"
-#include "qxlibwindowsurface.h"
+#include "qxlibbackingstore.h"
#include <QtGui/private/qpixmap_raster_p.h>
#include <QtCore/qdebug.h>
+#include <QtGui/qopenglcontext.h>
+#include <QtGui/qscreen.h>
#include "qxlibwindow.h"
-#include "qgenericunixfontdatabase.h"
+#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
+#include <QtPlatformSupport/private/qgenericunixfontdatabase_p.h>
#include "qxlibscreen.h"
#include "qxlibclipboard.h"
#include "qxlibdisplay.h"
#include "qxlibnativeinterface.h"
-
-#if !defined(QT_NO_OPENGL)
-#if !defined(QT_OPENGL_ES_2)
-#include <GL/glx.h>
-#else
-#include <EGL/egl.h>
-#endif //!defined(QT_OPENGL_ES_2)
-#include <private/qwindowsurface_gl_p.h>
-#include <private/qpixmapdata_gl_p.h>
-#endif //QT_NO_OPENGL
+#include "qglxintegration.h"
QT_BEGIN_NAMESPACE
-QXlibIntegration::QXlibIntegration(bool useOpenGL)
- : mUseOpenGL(useOpenGL)
- , mFontDb(new QGenericUnixFontDatabase())
+QXlibIntegration::QXlibIntegration()
+ : mFontDb(new QGenericUnixFontDatabase())
, mClipboard(0)
, mNativeInterface(new QXlibNativeInterface)
{
+ mEventDispatcher = createUnixEventDispatcher();
+ QGuiApplicationPrivate::instance()->setEventDispatcher(mEventDispatcher);
+
+ XInitThreads();
+
mPrimaryScreen = new QXlibScreen();
mScreens.append(mPrimaryScreen);
+ screenAdded(mPrimaryScreen);
}
-bool QXlibIntegration::hasCapability(QPlatformIntegration::Capability cap) const
+bool QXlibIntegration::hasCapability(QPlatformIntegration::Capability) const
{
- switch (cap) {
- case ThreadedPixmaps: return true;
- case OpenGL: return hasOpenGL();
- default: return QPlatformIntegration::hasCapability(cap);
- }
+ return true;
}
-QPixmapData *QXlibIntegration::createPixmapData(QPixmapData::PixelType type) const
+QPlatformBackingStore *QXlibIntegration::createPlatformBackingStore(QWindow *window) const
{
-#ifndef QT_NO_OPENGL
- if (mUseOpenGL)
- return new QGLPixmapData(type);
-#endif
- return new QRasterPixmapData(type);
+ return new QXlibBackingStore(window);
}
-QWindowSurface *QXlibIntegration::createWindowSurface(QWidget *widget, WId) const
+QPlatformOpenGLContext *QXlibIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
{
-#ifndef QT_NO_OPENGL
- if (mUseOpenGL)
- return new QGLWindowSurface(widget);
-#endif
- return new QXlibWindowSurface(widget);
+ QXlibScreen *screen = static_cast<QXlibScreen *>(context->screen()->handle());
+
+ return new QGLXContext(screen, context->format(), context->shareHandle());
}
-QPlatformWindow *QXlibIntegration::createPlatformWindow(QWidget *widget, WId /*winId*/) const
+QPlatformWindow *QXlibIntegration::createPlatformWindow(QWindow *window) const
{
- return new QXlibWindow(widget);
+ return new QXlibWindow(window);
}
-
-
-QPixmap QXlibIntegration::grabWindow(WId window, int x, int y, int width, int height) const
+QAbstractEventDispatcher *QXlibIntegration::guiThreadEventDispatcher() const
{
- QImage image;
- QWidget *widget = QWidget::find(window);
- if (widget) {
- QXlibScreen *screen = QXlibScreen::testLiteScreenForWidget(widget);
- image = screen->grabWindow(window,x,y,width,height);
- } else {
- for (int i = 0; i < mScreens.size(); i++) {
- QXlibScreen *screen = static_cast<QXlibScreen *>(mScreens[i]);
- if (screen->rootWindow() == window) {
- image = screen->grabWindow(window,x,y,width,height);
- }
- }
- }
- return QPixmap::fromImage(image);
+ return mEventDispatcher;
}
QPlatformFontDatabase *QXlibIntegration::fontDatabase() const
@@ -146,28 +121,4 @@ QPlatformNativeInterface * QXlibIntegration::nativeInterface() const
return mNativeInterface;
}
-bool QXlibIntegration::hasOpenGL() const
-{
-#if !defined(QT_NO_OPENGL)
-#if !defined(QT_OPENGL_ES_2)
- QXlibScreen *screen = static_cast<QXlibScreen *>(mScreens.at(0));
- return glXQueryExtension(screen->display()->nativeDisplay(), 0, 0) != 0;
-#else
- static bool eglHasbeenInitialized = false;
- static bool wasEglInitialized = false;
- if (!eglHasbeenInitialized) {
- eglHasbeenInitialized = true;
- QXlibScreen *screen = static_cast<QXlibScreen *>(mScreens.at(0));
- EGLint major, minor;
- eglBindAPI(EGL_OPENGL_ES_API);
- EGLDisplay disp = eglGetDisplay(screen->display()->nativeDisplay());
- wasEglInitialized = eglInitialize(disp,&major,&minor);
- screen->setEglDisplay(disp);
- }
- return wasEglInitialized;
-#endif
-#endif
- return false;
-}
-
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xlib/qxlibintegration.h b/src/plugins/platforms/xlib/qxlibintegration.h
index 9c814ead69..f5150fca6f 100644
--- a/src/plugins/platforms/xlib/qxlibintegration.h
+++ b/src/plugins/platforms/xlib/qxlibintegration.h
@@ -58,12 +58,15 @@ class QXlibScreen;
class QXlibIntegration : public QPlatformIntegration
{
public:
- QXlibIntegration(bool useOpenGL = false);
+ QXlibIntegration();
bool hasCapability(Capability cap) const;
- QPixmapData *createPixmapData(QPixmapData::PixelType type) const;
- QPlatformWindow *createPlatformWindow(QWidget *widget, WId winId) const;
- QWindowSurface *createWindowSurface(QWidget *widget, WId winId) const;
+
+ QPlatformWindow *createPlatformWindow(QWindow *window) const;
+ QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const;
+ QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const;
+
+ QAbstractEventDispatcher *guiThreadEventDispatcher() const;
QPixmap grabWindow(WId window, int x, int y, int width, int height) const;
@@ -75,14 +78,12 @@ public:
QPlatformNativeInterface *nativeInterface() const;
private:
- bool hasOpenGL() const;
-
- bool mUseOpenGL;
QXlibScreen *mPrimaryScreen;
QList<QPlatformScreen *> mScreens;
QPlatformFontDatabase *mFontDb;
QPlatformClipboard *mClipboard;
QPlatformNativeInterface *mNativeInterface;
+ QAbstractEventDispatcher *mEventDispatcher;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xlib/qxlibkeyboard.cpp b/src/plugins/platforms/xlib/qxlibkeyboard.cpp
index c152070e5a..66e48fec93 100644
--- a/src/plugins/platforms/xlib/qxlibkeyboard.cpp
+++ b/src/plugins/platforms/xlib/qxlibkeyboard.cpp
@@ -987,7 +987,7 @@ static Qt::KeyboardModifiers modifierFromKeyCode(int qtcode)
}
}
-void QXlibKeyboard::handleKeyEvent(QWidget *widget, QEvent::Type type, XKeyEvent *ev)
+void QXlibKeyboard::handleKeyEvent(QWindow *widget, QEvent::Type type, XKeyEvent *ev)
{
int qtcode = 0;
Qt::KeyboardModifiers modifiers = translateModifiers(ev->state);
diff --git a/src/plugins/platforms/xlib/qxlibkeyboard.h b/src/plugins/platforms/xlib/qxlibkeyboard.h
index 71dbf8f78d..a33ad61d27 100644
--- a/src/plugins/platforms/xlib/qxlibkeyboard.h
+++ b/src/plugins/platforms/xlib/qxlibkeyboard.h
@@ -51,7 +51,7 @@ public:
void changeLayout();
- void handleKeyEvent(QWidget *widget, QEvent::Type type, XKeyEvent *ev);
+ void handleKeyEvent(QWindow *widget, QEvent::Type type, XKeyEvent *ev);
Qt::KeyboardModifiers translateModifiers(int s);
diff --git a/src/plugins/platforms/xlib/qxlibnativeinterface.cpp b/src/plugins/platforms/xlib/qxlibnativeinterface.cpp
index 76396aaeb6..2c706e64e4 100644
--- a/src/plugins/platforms/xlib/qxlibnativeinterface.cpp
+++ b/src/plugins/platforms/xlib/qxlibnativeinterface.cpp
@@ -39,10 +39,11 @@
**
****************************************************************************/
+#include <private/qguiapplication_p.h>
#include "qxlibnativeinterface.h"
#include "qxlibdisplay.h"
-#include <QtGui/private/qapplication_p.h>
+#include "qscreen.h"
class QXlibResourceMap : public QMap<QByteArray, QXlibNativeInterface::ResourceType>
{
@@ -62,29 +63,29 @@ public:
Q_GLOBAL_STATIC(QXlibResourceMap, qXlibResourceMap)
-void * QXlibNativeInterface::nativeResourceForWidget(const QByteArray &resourceString, QWidget *widget)
+void * QXlibNativeInterface::nativeResourceForWindow(const QByteArray &resourceString, QWindow *window)
{
QByteArray lowerCaseResource = resourceString.toLower();
ResourceType resource = qXlibResourceMap()->value(lowerCaseResource);
void *result = 0;
switch(resource) {
case Display:
- result = displayForWidget(widget);
+ result = displayForWindow(window);
break;
case EglDisplay:
- result = eglDisplayForWidget(widget);
+ result = eglDisplayForWindow(window);
break;
case Connection:
- result = connectionForWidget(widget);
+ result = connectionForWindow(window);
break;
case Screen:
- result = reinterpret_cast<void *>(qPlatformScreenForWidget(widget)->xScreenNumber());
+ result = reinterpret_cast<void *>(qPlatformScreenForWindow(window)->xScreenNumber());
break;
case GraphicsDevice:
- result = graphicsDeviceForWidget(widget);
+ result = graphicsDeviceForWindow(window);
break;
case EglContext:
- result = eglContextForWidget(widget);
+ result = eglContextForWindow(window);
break;
default:
result = 0;
@@ -92,42 +93,37 @@ void * QXlibNativeInterface::nativeResourceForWidget(const QByteArray &resourceS
return result;
}
-void * QXlibNativeInterface::displayForWidget(QWidget *widget)
+void * QXlibNativeInterface::displayForWindow(QWindow *window)
{
- return qPlatformScreenForWidget(widget)->display()->nativeDisplay();
+ return qPlatformScreenForWindow(window)->display()->nativeDisplay();
}
-void * QXlibNativeInterface::eglDisplayForWidget(QWidget *widget)
+void * QXlibNativeInterface::eglDisplayForWindow(QWindow *window)
{
- Q_UNUSED(widget);
+ Q_UNUSED(window);
return 0;
}
-void * QXlibNativeInterface::screenForWidget(QWidget *widget)
+void * QXlibNativeInterface::screenForWindow(QWindow *window)
{
- Q_UNUSED(widget);
+ Q_UNUSED(window);
return 0;
}
-void * QXlibNativeInterface::graphicsDeviceForWidget(QWidget *widget)
+void * QXlibNativeInterface::graphicsDeviceForWindow(QWindow *window)
{
- Q_UNUSED(widget);
+ Q_UNUSED(window);
return 0;
}
-void * QXlibNativeInterface::eglContextForWidget(QWidget *widget)
+void * QXlibNativeInterface::eglContextForWindow(QWindow *window)
{
- Q_UNUSED(widget);
+ Q_UNUSED(window);
return 0;
}
-QXlibScreen * QXlibNativeInterface::qPlatformScreenForWidget(QWidget *widget)
+QXlibScreen * QXlibNativeInterface::qPlatformScreenForWindow(QWindow *window)
{
- QXlibScreen *screen;
- if (widget) {
- screen = static_cast<QXlibScreen *>(QPlatformScreen::platformScreenForWidget(widget));
- }else {
- screen = static_cast<QXlibScreen *>(QApplicationPrivate::platformIntegration()->screens()[0]);
- }
- return screen;
+ QScreen *screen = window ? window->screen() : QGuiApplication::primaryScreen();
+ return static_cast<QXlibScreen *>(screen->handle());
}
diff --git a/src/plugins/platforms/xlib/qxlibnativeinterface.h b/src/plugins/platforms/xlib/qxlibnativeinterface.h
index e1f5cea8b2..4c6ce770b0 100644
--- a/src/plugins/platforms/xlib/qxlibnativeinterface.h
+++ b/src/plugins/platforms/xlib/qxlibnativeinterface.h
@@ -58,17 +58,17 @@ public:
EglContext
};
- void *nativeResourceForWidget(const QByteArray &resourceString, QWidget *widget);
+ void *nativeResourceForWindow(const QByteArray &resourceString, QWindow *window);
- void *displayForWidget(QWidget *widget);
- void *eglDisplayForWidget(QWidget *widget);
- void *connectionForWidget(QWidget *widget);
- void *screenForWidget(QWidget *widget);
- void *graphicsDeviceForWidget(QWidget *widget);
- void *eglContextForWidget(QWidget *widget);
+ void *displayForWindow(QWindow *window);
+ void *eglDisplayForWindow(QWindow *window);
+ void *connectionForWindow(QWindow *window);
+ void *screenForWindow(QWindow *window);
+ void *graphicsDeviceForWindow(QWindow *window);
+ void *eglContextForWindow(QWindow *window);
private:
- static QXlibScreen *qPlatformScreenForWidget(QWidget *widget);
+ static QXlibScreen *qPlatformScreenForWindow(QWindow *window);
};
diff --git a/src/plugins/platforms/xlib/qxlibscreen.cpp b/src/plugins/platforms/xlib/qxlibscreen.cpp
index b069985a5c..e6263c0b33 100644
--- a/src/plugins/platforms/xlib/qxlibscreen.cpp
+++ b/src/plugins/platforms/xlib/qxlibscreen.cpp
@@ -39,6 +39,7 @@
**
****************************************************************************/
+#include <private/qguiapplication_p.h>
#include "qxlibscreen.h"
#include <X11/extensions/Xfixes.h>
@@ -54,7 +55,7 @@
#include <QtCore/QSocketNotifier>
#include <QtCore/QElapsedTimer>
-#include <private/qapplication_p.h>
+#include <QtGui/QScreen>
QT_BEGIN_NAMESPACE
@@ -263,11 +264,9 @@ unsigned long QXlibScreen::whitePixel()
bool QXlibScreen::handleEvent(XEvent *xe)
{
int quit = false;
- QXlibWindow *platformWindow = 0;
- QWidget *widget = QWidget::find(xe->xany.window);
- if (widget) {
- platformWindow = static_cast<QXlibWindow *>(widget->platformWindow());
- }
+ QXlibWindow *platformWindow = QXlibWindow::platformWindowForXWindow(xe->xany.window);
+ if (!platformWindow)
+ return false;
Atom wmProtocolsAtom = QXlibStatic::atom(QXlibStatic::WM_PROTOCOLS);
Atom wmDeleteWindowAtom = QXlibStatic::atom(QXlibStatic::WM_DELETE_WINDOW);
@@ -282,56 +281,48 @@ bool QXlibScreen::handleEvent(XEvent *xe)
break;
case Expose:
- if (platformWindow)
- if (xe->xexpose.count == 0)
- platformWindow->paintEvent();
+ // ###
+// if (xe->xexpose.count == 0)
+// platformWindow->paintEvent();
break;
case ConfigureNotify:
- if (platformWindow)
- platformWindow->resizeEvent(&xe->xconfigure);
+ platformWindow->resizeEvent(&xe->xconfigure);
break;
case ButtonPress:
- if (platformWindow)
- platformWindow->mousePressEvent(&xe->xbutton);
+ platformWindow->mousePressEvent(&xe->xbutton);
break;
case ButtonRelease:
- if (platformWindow)
- platformWindow->handleMouseEvent(QEvent::MouseButtonRelease, &xe->xbutton);
+ platformWindow->handleMouseEvent(QEvent::MouseButtonRelease, &xe->xbutton);
break;
case MotionNotify:
- if (platformWindow)
- platformWindow->handleMouseEvent(QEvent::MouseMove, &xe->xbutton);
+ platformWindow->handleMouseEvent(QEvent::MouseMove, &xe->xbutton);
break;
- case XKeyPress:
- mKeyboard->handleKeyEvent(widget,QEvent::KeyPress, &xe->xkey);
+ case XKeyPress:
+ mKeyboard->handleKeyEvent(platformWindow->window(), QEvent::KeyPress, &xe->xkey);
break;
case XKeyRelease:
- mKeyboard->handleKeyEvent(widget,QEvent::KeyRelease, &xe->xkey);
+ mKeyboard->handleKeyEvent(platformWindow->window(), QEvent::KeyRelease, &xe->xkey);
break;
case EnterNotify:
- if (platformWindow)
- platformWindow->handleEnterEvent();
+ platformWindow->handleEnterEvent();
break;
case LeaveNotify:
- if (platformWindow)
- platformWindow->handleLeaveEvent();
+ platformWindow->handleLeaveEvent();
break;
case XFocusIn:
- if (platformWindow)
- platformWindow->handleFocusInEvent();
+ platformWindow->handleFocusInEvent();
break;
case XFocusOut:
- if (platformWindow)
- platformWindow->handleFocusOutEvent();
+ platformWindow->handleFocusOutEvent();
break;
case PropertyNotify:
@@ -452,10 +443,9 @@ QImage QXlibScreen::grabWindow(Window window, int x, int y, int w, int h)
return result;
}
-QXlibScreen * QXlibScreen::testLiteScreenForWidget(QWidget *widget)
+QXlibScreen * QXlibScreen::testLiteScreenForWidget(QWindow *widget)
{
- QPlatformScreen *platformScreen = platformScreenForWidget(widget);
- return static_cast<QXlibScreen *>(platformScreen);
+ return static_cast<QXlibScreen *>(widget->screen()->handle());
}
QXlibDisplay * QXlibScreen::display() const
@@ -480,7 +470,7 @@ QXlibKeyboard * QXlibScreen::keyboard() const
void QXlibScreen::handleSelectionRequest(XEvent *event)
{
- QPlatformIntegration *integration = QApplicationPrivate::platformIntegration();
+ QPlatformIntegration *integration = QGuiApplicationPrivate::platformIntegration();
QXlibClipboard *clipboard = static_cast<QXlibClipboard *>(integration->clipboard());
clipboard->handleSelectionRequest(event);
}
diff --git a/src/plugins/platforms/xlib/qxlibscreen.h b/src/plugins/platforms/xlib/qxlibscreen.h
index 81625e561e..6e1a3e401d 100644
--- a/src/plugins/platforms/xlib/qxlibscreen.h
+++ b/src/plugins/platforms/xlib/qxlibscreen.h
@@ -51,7 +51,7 @@ class QXlibCursor;
class QXlibKeyboard;
class QXlibDisplay;
-class QXlibScreen : public QPlatformScreen
+class QXlibScreen : public QObject, public QPlatformScreen
{
Q_OBJECT
public:
@@ -73,7 +73,7 @@ public:
QImage grabWindow(Window window, int x, int y, int w, int h);
- static QXlibScreen *testLiteScreenForWidget(QWidget *widget);
+ static QXlibScreen *testLiteScreenForWidget(QWindow *widget);
QXlibDisplay *display() const;
int xScreenNumber() const;
diff --git a/src/plugins/platforms/xlib/qxlibstatic.cpp b/src/plugins/platforms/xlib/qxlibstatic.cpp
index 3ba0eb4c32..c9ed13aeea 100644
--- a/src/plugins/platforms/xlib/qxlibstatic.cpp
+++ b/src/plugins/platforms/xlib/qxlibstatic.cpp
@@ -39,13 +39,14 @@
**
****************************************************************************/
+#include <private/qguiapplication_p.h>
#include "qxlibstatic.h"
#include "qxlibscreen.h"
#include "qxlibdisplay.h"
#include <qplatformdefs.h>
+#include <QtGui/qscreen.h>
-#include <QtGui/private/qapplication_p.h>
#include <QtCore/QBuffer>
#include <QtCore/QLibrary>
@@ -258,7 +259,7 @@ public:
, xfixes_eventbase(0)
, xfixes_errorbase(0)
{
- QXlibScreen *screen = qobject_cast<QXlibScreen *> (QApplicationPrivate::platformIntegration()->screens().at(0));
+ QXlibScreen *screen = static_cast<QXlibScreen *> (QGuiApplication::primaryScreen()->handle());
Q_ASSERT(screen);
initializeAllAtoms(screen);
diff --git a/src/plugins/platforms/xlib/qxlibwindow.cpp b/src/plugins/platforms/xlib/qxlibwindow.cpp
index 823fae9de3..e388f1054d 100644
--- a/src/plugins/platforms/xlib/qxlibwindow.cpp
+++ b/src/plugins/platforms/xlib/qxlibwindow.cpp
@@ -39,6 +39,7 @@
**
****************************************************************************/
+#include <QtGui/private/qguiapplication_p.h>
#include "qxlibwindow.h"
#include "qxlibintegration.h"
@@ -50,7 +51,7 @@
#if !defined(QT_NO_OPENGL)
#if !defined(QT_OPENGL_ES_2)
#include "qglxintegration.h"
-#include "qglxconvenience.h"
+#include "private/qglxconvenience_p.h"
#else
#include "../eglconvenience/qeglconvenience.h"
#include "../eglconvenience/qeglplatformcontext.h"
@@ -64,14 +65,14 @@
#include <QApplication>
#include <QDebug>
-#include <QtGui/private/qwindowsurface_p.h>
-#include <QtGui/private/qapplication_p.h>
-
//#define MYX11_DEBUG
QT_BEGIN_NAMESPACE
-QXlibWindow::QXlibWindow(QWidget *window)
+QHash<Window, QXlibWindow *> QXlibWindow::windowMap;
+
+
+QXlibWindow::QXlibWindow(QWindow *window)
: QPlatformWindow(window)
, mGLContext(0)
, mScreen(QXlibScreen::testLiteScreenForWidget(window))
@@ -82,11 +83,10 @@ QXlibWindow::QXlibWindow(QWidget *window)
int h = window->height();
#if !defined(QT_NO_OPENGL)
- if(window->platformWindowFormat().windowApi() == QPlatformWindowFormat::OpenGL
- && QApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL)
- || window->platformWindowFormat().alpha()) {
+ if(window->surfaceType() == QWindow::OpenGLSurface) {
#if !defined(QT_OPENGL_ES_2)
- XVisualInfo *visualInfo = qglx_findVisualInfo(mScreen->display()->nativeDisplay(),mScreen->xScreenNumber(),window->platformWindowFormat());
+ XVisualInfo *visualInfo = qglx_findVisualInfo(mScreen->display()->nativeDisplay(), mScreen->xScreenNumber(),
+ window->format());
#else
QPlatformWindowFormat windowFormat = correctColorBuffers(window->platformWindowFormat());
@@ -156,6 +156,8 @@ QXlibWindow::QXlibWindow(QWidget *window)
if (window->windowFlags() & Qt::WindowContextHelpButtonHint)
protocols[n++] = QXlibStatic::atom(QXlibStatic::_NET_WM_CONTEXT_HELP);
XSetWMProtocols(mScreen->display()->nativeDisplay(), x_window, protocols, n);
+
+ windowMap.insert(x_window, this);
}
@@ -165,6 +167,9 @@ QXlibWindow::~QXlibWindow()
#ifdef MYX11_DEBUG
qDebug() << "~QTestLiteWindow" << hex << x_window;
#endif
+
+ windowMap.remove(x_window);
+
delete mGLContext;
XFreeGC(mScreen->display()->nativeDisplay(), gc);
XDestroyWindow(mScreen->display()->nativeDisplay(), x_window);
@@ -209,7 +214,7 @@ void QXlibWindow::handleMouseEvent(QEvent::Type type, XButtonEvent *e)
bool hor = (((e->button == Button4 || e->button == Button5)
&& (modifiers & Qt::AltModifier))
|| (e->button == 6 || e->button == 7));
- QWindowSystemInterface::handleWheelEvent(widget(), e->time,
+ QWindowSystemInterface::handleWheelEvent(window(), e->time,
QPoint(e->x, e->y),
QPoint(e->x_root, e->y_root),
delta, hor ? Qt::Horizontal : Qt::Vertical);
@@ -222,7 +227,7 @@ void QXlibWindow::handleMouseEvent(QEvent::Type type, XButtonEvent *e)
buttons ^= button; // X event uses state *before*, Qt uses state *after*
- QWindowSystemInterface::handleMouseEvent(widget(), e->time, QPoint(e->x, e->y),
+ QWindowSystemInterface::handleMouseEvent(window(), e->time, QPoint(e->x, e->y),
QPoint(e->x_root, e->y_root),
buttons);
@@ -231,23 +236,23 @@ void QXlibWindow::handleMouseEvent(QEvent::Type type, XButtonEvent *e)
void QXlibWindow::handleCloseEvent()
{
- QWindowSystemInterface::handleCloseEvent(widget());
+ QWindowSystemInterface::handleCloseEvent(window());
}
void QXlibWindow::handleEnterEvent()
{
- QWindowSystemInterface::handleEnterEvent(widget());
+ QWindowSystemInterface::handleEnterEvent(window());
}
void QXlibWindow::handleLeaveEvent()
{
- QWindowSystemInterface::handleLeaveEvent(widget());
+ QWindowSystemInterface::handleLeaveEvent(window());
}
void QXlibWindow::handleFocusInEvent()
{
- QWindowSystemInterface::handleWindowActivated(widget());
+ QWindowSystemInterface::handleWindowActivated(window());
}
void QXlibWindow::handleFocusOutEvent()
@@ -313,16 +318,6 @@ GC QXlibWindow::createGC()
return gc;
}
-void QXlibWindow::paintEvent()
-{
-#ifdef MYX11_DEBUG
-// qDebug() << "QTestLiteWindow::paintEvent" << shm_img.size() << painted;
-#endif
-
- if (QWindowSurface *surface = widget()->windowSurface())
- surface->flush(widget(), widget()->geometry(), QPoint());
-}
-
void QXlibWindow::requestActivateWindow()
{
XSetInputFocus(mScreen->display()->nativeDisplay(), x_window, XRevertToParent, CurrentTime);
@@ -340,11 +335,12 @@ void QXlibWindow::resizeEvent(XConfigureEvent *e)
ypos = e->y;
}
#ifdef MYX11_DEBUG
- qDebug() << hex << x_window << dec << "ConfigureNotify" << e->x << e->y << e->width << e->height << "geometry" << xpos << ypos << width << height;
+ qDebug() << hex << x_window << dec << "ConfigureNotify" << e->x << e->y << e->width << e->height <<
+ "geometry" << xpos << ypos << e->width << e->height;
#endif
QRect newRect(xpos, ypos, e->width, e->height);
- QWindowSystemInterface::handleGeometryChange(widget(), newRect);
+ QWindowSystemInterface::handleGeometryChange(window(), newRect);
}
void QXlibWindow::mousePressEvent(XButtonEvent *e)
@@ -413,16 +409,15 @@ void QXlibWindow::setMWMHints(const QXlibMWMHints &mwmhints)
}
// Returns true if we should set WM_TRANSIENT_FOR on \a w
-static inline bool isTransient(const QWidget *w)
+static inline bool isTransient(const QWindow *w)
{
- return ((w->windowType() == Qt::Dialog
+ return (w->windowType() == Qt::Dialog
|| w->windowType() == Qt::Sheet
|| w->windowType() == Qt::Tool
|| w->windowType() == Qt::SplashScreen
|| w->windowType() == Qt::ToolTip
|| w->windowType() == Qt::Drawer
- || w->windowType() == Qt::Popup)
- && !w->testAttribute(Qt::WA_X11BypassTransientForHint));
+ || w->windowType() == Qt::Popup);
}
QVector<Atom> QXlibWindow::getNetWmState() const
@@ -568,9 +563,9 @@ Qt::WindowFlags QXlibWindow::setWindowFlags(Qt::WindowFlags flags)
mwmhints.decorations = 0;
}
- if (widget()->windowModality() == Qt::WindowModal) {
+ if (window()->windowModality() == Qt::WindowModal) {
mwmhints.input_mode = MWM_INPUT_PRIMARY_APPLICATION_MODAL;
- } else if (widget()->windowModality() == Qt::ApplicationModal) {
+ } else if (window()->windowModality() == Qt::ApplicationModal) {
mwmhints.input_mode = MWM_INPUT_FULL_APPLICATION_MODAL;
}
@@ -580,7 +575,7 @@ Qt::WindowFlags QXlibWindow::setWindowFlags(Qt::WindowFlags flags)
if (flags & Qt::WindowStaysOnTopHint) {
if (flags & Qt::WindowStaysOnBottomHint)
- qWarning() << "QWidget: Incompatible window flags: the window can't be on top and on bottom at the same time";
+ qWarning() << "QWindow: Incompatible window flags: the window can't be on top and on bottom at the same time";
if (!netWmState.contains(QXlibStatic::atom(QXlibStatic::_NET_WM_STATE_ABOVE)))
netWmState.append(QXlibStatic::atom(QXlibStatic::_NET_WM_STATE_ABOVE));
if (!netWmState.contains(QXlibStatic::atom(QXlibStatic::_NET_WM_STATE_STAYS_ON_TOP)))
@@ -589,17 +584,17 @@ Qt::WindowFlags QXlibWindow::setWindowFlags(Qt::WindowFlags flags)
if (!netWmState.contains(QXlibStatic::atom(QXlibStatic::_NET_WM_STATE_BELOW)))
netWmState.append(QXlibStatic::atom(QXlibStatic::_NET_WM_STATE_BELOW));
}
- if (widget()->isFullScreen()) {
+ if (window()->windowState() & Qt::WindowFullScreen) {
if (!netWmState.contains(QXlibStatic::atom(QXlibStatic::_NET_WM_STATE_FULLSCREEN)))
netWmState.append(QXlibStatic::atom(QXlibStatic::_NET_WM_STATE_FULLSCREEN));
}
- if (widget()->isMaximized()) {
+ if (window()->windowState() & Qt::WindowMaximized) {
if (!netWmState.contains(QXlibStatic::atom(QXlibStatic::_NET_WM_STATE_MAXIMIZED_HORZ)))
netWmState.append(QXlibStatic::atom(QXlibStatic::_NET_WM_STATE_MAXIMIZED_HORZ));
if (!netWmState.contains(QXlibStatic::atom(QXlibStatic::_NET_WM_STATE_MAXIMIZED_VERT)))
netWmState.append(QXlibStatic::atom(QXlibStatic::_NET_WM_STATE_MAXIMIZED_VERT));
}
- if (widget()->windowModality() != Qt::NonModal) {
+ if (window()->windowModality() != Qt::NonModal) {
if (!netWmState.contains(QXlibStatic::atom(QXlibStatic::_NET_WM_STATE_MODAL)))
netWmState.append(QXlibStatic::atom(QXlibStatic::_NET_WM_STATE_MODAL));
}
@@ -634,24 +629,29 @@ Qt::WindowFlags QXlibWindow::setWindowFlags(Qt::WindowFlags flags)
return flags;
}
+Qt::WindowState QXlibWindow::setWindowState(Qt::WindowState state)
+{
+ // ####
+ return state;
+}
+
void QXlibWindow::setVisible(bool visible)
{
#ifdef MYX11_DEBUG
qDebug() << "QTestLiteWindow::setVisible" << visible << hex << x_window;
#endif
- if (isTransient(widget())) {
+ if (isTransient(window())) {
Window parentXWindow = x_window;
- if (widget()->parentWidget()) {
- QWidget *widgetParent = widget()->parentWidget()->window();
- if (widgetParent && widgetParent->platformWindow()) {
- QXlibWindow *parentWidnow = static_cast<QXlibWindow *>(widgetParent->platformWindow());
- parentXWindow = parentWidnow->x_window;
- }
+ QWindow *parent = window()->parent();
+ if (parent && parent->handle()) {
+ QXlibWindow *xlibParent = static_cast<QXlibWindow *>(parent->handle());
+ parentXWindow = xlibParent->x_window;
}
XSetTransientForHint(mScreen->display()->nativeDisplay(),x_window,parentXWindow);
}
if (visible) {
+ qDebug() << ">>> mapping";
//ensure that the window is viewed in correct position.
doSizeHints();
XMapWindow(mScreen->display()->nativeDisplay(), x_window);
@@ -666,34 +666,12 @@ void QXlibWindow::setCursor(const Cursor &cursor)
mScreen->display()->flush();
}
-QPlatformGLContext *QXlibWindow::glContext() const
+QSurfaceFormat QXlibWindow::format() const
{
- if (!QApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL))
- return 0;
- if (!mGLContext) {
- QXlibWindow *that = const_cast<QXlibWindow *>(this);
-#if !defined(QT_NO_OPENGL)
-#if !defined(QT_OPENGL_ES_2)
- that->mGLContext = new QGLXContext(x_window, mScreen,widget()->platformWindowFormat());
-#else
- EGLDisplay display = mScreen->eglDisplay();
-
- QPlatformWindowFormat windowFormat = correctColorBuffers(widget()->platformWindowFormat());
-
- EGLConfig config = q_configFromQPlatformWindowFormat(display,windowFormat);
- QVector<EGLint> eglContextAttrs;
- eglContextAttrs.append(EGL_CONTEXT_CLIENT_VERSION);
- eglContextAttrs.append(2);
- eglContextAttrs.append(EGL_NONE);
-
- EGLSurface eglSurface = eglCreateWindowSurface(display,config,(EGLNativeWindowType)x_window,0);
- that->mGLContext = new QEGLPlatformContext(display, config, eglContextAttrs.data(), eglSurface, EGL_OPENGL_ES_API);
-#endif
-#endif
- }
- return mGLContext;
+ return window()->format();
}
+
Window QXlibWindow::xWindow() const
{
return x_window;
@@ -706,7 +684,7 @@ GC QXlibWindow::graphicsContext() const
void QXlibWindow::doSizeHints()
{
- Q_ASSERT(widget()->testAttribute(Qt::WA_WState_Created));
+// Q_ASSERT(window()->testAttribute(Qt::WA_WState_Created));
XSizeHints s;
s.flags = 0;
QRect g = geometry();
@@ -723,27 +701,10 @@ void QXlibWindow::doSizeHints()
XSetWMNormalHints(mScreen->display()->nativeDisplay(), x_window, &s);
}
-QPlatformWindowFormat QXlibWindow::correctColorBuffers(const QPlatformWindowFormat &platformWindowFormat) const
-{
- // I have only tested this setup on a dodgy intel setup, where I didn't use standard libs,
- // so this might be not what we want to do :)
- if ( !(platformWindowFormat.redBufferSize() == -1 &&
- platformWindowFormat.greenBufferSize() == -1 &&
- platformWindowFormat.blueBufferSize() == -1))
- return platformWindowFormat;
- QPlatformWindowFormat windowFormat = platformWindowFormat;
- if (mScreen->depth() == 16) {
- windowFormat.setRedBufferSize(5);
- windowFormat.setGreenBufferSize(6);
- windowFormat.setBlueBufferSize(5);
- } else {
- windowFormat.setRedBufferSize(8);
- windowFormat.setGreenBufferSize(8);
- windowFormat.setBlueBufferSize(8);
- }
-
- return windowFormat;
+QXlibWindow *QXlibWindow::platformWindowForXWindow(Window window)
+{
+ return windowMap.value(window);
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xlib/qxlibwindow.h b/src/plugins/platforms/xlib/qxlibwindow.h
index da29efbff1..9b64dc5624 100644
--- a/src/plugins/platforms/xlib/qxlibwindow.h
+++ b/src/plugins/platforms/xlib/qxlibwindow.h
@@ -49,6 +49,7 @@
#include <QObject>
#include <QImage>
+#include <QHash>
struct QXlibMWMHints {
ulong flags, functions, decorations;
@@ -86,7 +87,7 @@ enum {
class QXlibWindow : public QPlatformWindow
{
public:
- QXlibWindow(QWidget *window);
+ QXlibWindow(QWindow *window);
~QXlibWindow();
@@ -100,7 +101,6 @@ public:
void handleFocusOutEvent();
void resizeEvent(XConfigureEvent *configure_event);
- void paintEvent();
void requestActivateWindow();
@@ -108,6 +108,8 @@ public:
Qt::WindowFlags setWindowFlags(Qt::WindowFlags type);
Qt::WindowFlags windowFlags() const;
+ Qt::WindowState setWindowState(Qt::WindowState state);
+
void setVisible(bool visible);
WId winId() const;
void setParent(const QPlatformWindow *window);
@@ -117,14 +119,14 @@ public:
void setCursor(const Cursor &cursor);
- QPlatformGLContext *glContext() const;
-
Window xWindow() const;
GC graphicsContext() const;
- inline uint depth() const { return mDepth; }
- QImage::Format format() const { return mFormat; }
+ QSurfaceFormat format() const;
Visual* visual() const { return mVisual; }
+ int depth() const { return mDepth; }
+
+ static QXlibWindow *platformWindowForXWindow(Window window);
protected:
QVector<Atom> getNetWmState() const;
@@ -134,8 +136,6 @@ protected:
void doSizeHints();
private:
- QPlatformWindowFormat correctColorBuffers(const QPlatformWindowFormat &windowFormat)const;
-
Window x_window;
GC gc;
@@ -145,9 +145,11 @@ private:
GC createGC();
- QPlatformGLContext *mGLContext;
+ QPlatformOpenGLContext *mGLContext;
QXlibScreen *mScreen;
Qt::WindowFlags mWindowFlags;
+
+ static QHash<Window, QXlibWindow *> windowMap;
};
#endif
diff --git a/src/plugins/platforms/xlib/qxlibwindowsurface.cpp b/src/plugins/platforms/xlib/qxlibwindowsurface.cpp
deleted file mode 100644
index e0c272d110..0000000000
--- a/src/plugins/platforms/xlib/qxlibwindowsurface.cpp
+++ /dev/null
@@ -1,235 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qxlibwindowsurface.h"
-#include "qxlibintegration.h"
-
-#include <QtCore/qdebug.h>
-#include <QWindowSystemInterface>
-
-#include "qxlibwindow.h"
-#include "qxlibscreen.h"
-#include "qxlibdisplay.h"
-
-#include "qpainter.h"
-
-# include <sys/ipc.h>
-# include <sys/shm.h>
-# include <X11/extensions/XShm.h>
-
-QT_BEGIN_NAMESPACE
-
-
-struct QXlibShmImageInfo {
- QXlibShmImageInfo(Display *xdisplay) : image(0), display(xdisplay) {}
- ~QXlibShmImageInfo() { destroy(); }
-
- void destroy();
-
- XShmSegmentInfo shminfo;
- XImage *image;
- Display *display;
-};
-
-
-#ifndef DONT_USE_MIT_SHM
-void QXlibShmImageInfo::destroy()
-{
- XShmDetach (display, &shminfo);
- XDestroyImage (image);
- shmdt (shminfo.shmaddr);
- shmctl (shminfo.shmid, IPC_RMID, 0);
-}
-#endif
-
-void QXlibWindowSurface::resizeShmImage(int width, int height)
-{
- QXlibScreen *screen = QXlibScreen::testLiteScreenForWidget(window());
- QXlibWindow *win = static_cast<QXlibWindow*>(window()->platformWindow());
-
-#ifdef DONT_USE_MIT_SHM
- shm_img = QImage(width, height, win->format());
-#else
-
- if (image_info)
- image_info->destroy();
- else
- image_info = new QXlibShmImageInfo(screen->display()->nativeDisplay());
-
- XImage *image = XShmCreateImage (screen->display()->nativeDisplay(), win->visual(), win->depth(), ZPixmap, 0,
- &image_info->shminfo, width, height);
-
-
- image_info->shminfo.shmid = shmget (IPC_PRIVATE,
- image->bytes_per_line * image->height, IPC_CREAT|0777);
-
- image_info->shminfo.shmaddr = image->data = (char*)shmat (image_info->shminfo.shmid, 0, 0);
- image_info->shminfo.readOnly = False;
-
- image_info->image = image;
-
- Status shm_attach_status = XShmAttach(screen->display()->nativeDisplay(), &image_info->shminfo);
-
- Q_ASSERT(shm_attach_status == True);
-
- shm_img = QImage( (uchar*) image->data, image->width, image->height, image->bytes_per_line, win->format() );
-#endif
- painted = false;
-}
-
-
-void QXlibWindowSurface::resizeBuffer(QSize s)
-{
- if (shm_img.size() != s)
- resizeShmImage(s.width(), s.height());
-}
-
-QSize QXlibWindowSurface::bufferSize() const
-{
- return shm_img.size();
-}
-
-QXlibWindowSurface::QXlibWindowSurface (QWidget *window)
- : QWindowSurface(window),
- painted(false), image_info(0)
-{
- xw = static_cast<QXlibWindow*>(window->platformWindow());
-// qDebug() << "QTestLiteWindowSurface::QTestLiteWindowSurface:" << xw->window;
-}
-
-QXlibWindowSurface::~QXlibWindowSurface()
-{
- delete image_info;
-}
-
-QPaintDevice *QXlibWindowSurface::paintDevice()
-{
- return &shm_img;
-}
-
-
-void QXlibWindowSurface::flush(QWidget *widget, const QRegion &region, const QPoint &offset)
-{
- Q_UNUSED(widget);
- Q_UNUSED(region);
- Q_UNUSED(offset);
-
- if (!painted)
- return;
-
- QXlibScreen *screen = QXlibScreen::testLiteScreenForWidget(widget);
- GC gc = xw->graphicsContext();
- Window window = xw->xWindow();
-#ifdef DONT_USE_MIT_SHM
- // just convert the image every time...
- if (!shm_img.isNull()) {
- QXlibWindow *win = static_cast<QXlibWindow*>(window()->platformWindow());
-
- QImage image = shm_img;
- //img.convertToFormat(
- XImage *xi = XCreateImage(screen->display(), win->visual(), win->depth(), ZPixmap,
- 0, (char *) image.scanLine(0), image.width(), image.height(),
- 32, image.bytesPerLine());
-
- int x = 0;
- int y = 0;
-
- /*int r =*/ XPutImage(screen->display(), window, gc, xi, 0, 0, x, y, image.width(), image.height());
-
- xi->data = 0; // QImage owns these bits
- XDestroyImage(xi);
- }
-#else
- // Use MIT_SHM
- if (image_info && image_info->image) {
- //qDebug() << "Here we go" << image_info->image->width << image_info->image->height;
- int x = 0;
- int y = 0;
-
- // We could set send_event to true, and then use the ShmCompletion to synchronize,
- // but let's do like Qt/11 and just use XSync
- XShmPutImage (screen->display()->nativeDisplay(), window, gc, image_info->image, 0, 0,
- x, y, image_info->image->width, image_info->image->height,
- /*send_event*/ False);
-
- screen->display()->sync();
- }
-#endif
-}
-
-// from qwindowsurface.cpp
-extern void qt_scrollRectInImage(QImage &img, const QRect &rect, const QPoint &offset);
-
-bool QXlibWindowSurface::scroll(const QRegion &area, int dx, int dy)
-{
- if (shm_img.isNull())
- return false;
-
- const QVector<QRect> rects = area.rects();
- for (int i = 0; i < rects.size(); ++i)
- qt_scrollRectInImage(shm_img, rects.at(i), QPoint(dx, dy));
-
- return true;
-}
-
-
-void QXlibWindowSurface::beginPaint(const QRegion &region)
-{
- Q_UNUSED(region);
- resizeBuffer(size());
-
- if (shm_img.hasAlphaChannel()) {
- QPainter p(&shm_img);
- p.setCompositionMode(QPainter::CompositionMode_Source);
- const QVector<QRect> rects = region.rects();
- const QColor blank = Qt::transparent;
- for (QVector<QRect>::const_iterator it = rects.begin(); it != rects.end(); ++it) {
- p.fillRect(*it, blank);
- }
- }
-}
-
-void QXlibWindowSurface::endPaint(const QRegion &region)
-{
- Q_UNUSED(region);
- painted = true; //there is content in the buffer
-}
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xlib/qxlibwindowsurface.h b/src/plugins/platforms/xlib/qxlibwindowsurface.h
deleted file mode 100644
index aeec781fc9..0000000000
--- a/src/plugins/platforms/xlib/qxlibwindowsurface.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWINDOWSURFACE_TESTLITE_H
-#define QWINDOWSURFACE_TESTLITE_H
-
-#include <QtGui/private/qwindowsurface_p.h>
-
-
-QT_BEGIN_NAMESPACE
-
-class QXlibWindow;
-class QXlibIntegration;
-class QXlibScreen;
-class QXlibShmImageInfo;
-
-class QXlibWindowSurface : public QWindowSurface
-{
-public:
- QXlibWindowSurface (QWidget *window);
- ~QXlibWindowSurface();
-
- QPaintDevice *paintDevice();
- void flush(QWidget *widget, const QRegion &region, const QPoint &offset);
- bool scroll(const QRegion &area, int dx, int dy);
-
- void beginPaint(const QRegion &region);
- void endPaint(const QRegion &region);
-
-private:
- bool painted;
- void resizeBuffer(QSize);
- QSize bufferSize() const;
-
-
- void resizeShmImage(int width, int height);
-
- QImage shm_img;
- QXlibShmImageInfo *image_info;
-
- QXlibWindow *xw;
-
-};
-
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/plugins/platforms/xlib/xlib.pro b/src/plugins/platforms/xlib/xlib.pro
index 2cba5513d5..ea95ae83a1 100644
--- a/src/plugins/platforms/xlib/xlib.pro
+++ b/src/plugins/platforms/xlib/xlib.pro
@@ -1,14 +1,14 @@
TARGET = qxlib
load(qt_plugin)
-DESTDIR = $$QT.gui.plugins/platforms
+QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/platforms
-QT += core-private gui-private opengl-private
+QT += core-private gui-private platformsupport-private
SOURCES = \
main.cpp \
qxlibintegration.cpp \
- qxlibwindowsurface.cpp \
+ qxlibbackingstore.cpp \
qxlibwindow.cpp \
qxlibcursor.cpp \
qxlibscreen.cpp \
@@ -21,7 +21,7 @@ SOURCES = \
HEADERS = \
qxlibintegration.h \
- qxlibwindowsurface.h \
+ qxlibbackingstore.h \
qxlibwindow.h \
qxlibcursor.h \
qxlibscreen.h \
@@ -38,24 +38,18 @@ mac {
LIBS += -L/usr/X11/lib -lz -framework Carbon
}
-include (../fontdatabases/genericunix/genericunix.pri)
+CONFIG += qpa/genericunixfontdatabase
contains(QT_CONFIG, opengl) {
QT += opengl
!contains(QT_CONFIG, opengles2) {
- include (../glxconvenience/glxconvenience.pri)
+# load(qpa/glx/convenience)
HEADERS += qglxintegration.h
SOURCES += qglxintegration.cpp
} else { # There is no easy way to detect if we'r suppose to use glx or not
- HEADERS += \
- ../eglconvenience/qeglplatformcontext.h \
- ../eglconvenience/qeglconvenience.h \
- ../eglconvenience/qxlibeglintegration.h
-
- SOURCES += \
- ../eglconvenience/qeglplatformcontext.cpp \
- ../eglconvenience/qeglconvenience.cpp \
- ../eglconvenience/qxlibeglintegration.cpp
+# load(qpa/egl/context)
+# load(qpa/egl/convenience)
+# load(qpa/egl/xlibintegration)
LIBS += -lEGL
}
}
diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro
index 0f2392eeeb..f47c000dfb 100644
--- a/src/plugins/plugins.pro
+++ b/src/plugins/plugins.pro
@@ -6,12 +6,11 @@ unix:!symbian {
} else {
SUBDIRS *= codecs
}
-!contains(QT_CONFIG, no-gui) {
- SUBDIRS *= imageformats
- !embedded:!qpa:SUBDIRS *= graphicssystems
- !win32:!embedded:!mac:!symbian:SUBDIRS *= inputmethods
- !symbian:SUBDIRS += accessible
-}
-embedded:SUBDIRS *= gfxdrivers decorations mousedrivers kbddrivers
+!contains(QT_CONFIG, no-gui): SUBDIRS *= imageformats
+!symbian:!contains(QT_CONFIG, no-gui):SUBDIRS += accessible
+
symbian:SUBDIRS += s60
-qpa:SUBDIRS += platforms
+qpa: {
+ SUBDIRS += platforms
+ SUBDIRS += platforminputcontexts
+}
diff --git a/src/printsupport/dialogs/dialogs.pri b/src/printsupport/dialogs/dialogs.pri
new file mode 100644
index 0000000000..5dbaa9fec3
--- /dev/null
+++ b/src/printsupport/dialogs/dialogs.pri
@@ -0,0 +1,43 @@
+# Qt dialogs module
+
+HEADERS += \
+ dialogs/qabstractprintdialog.h \
+ dialogs/qabstractprintdialog_p.h \
+ dialogs/qabstractpagesetupdialog.h \
+ dialogs/qabstractpagesetupdialog_p.h \
+ dialogs/qpagesetupdialog.h \
+ dialogs/qprintdialog.h \
+ dialogs/qprintpreviewdialog.h
+
+!qpa:mac {
+ OBJECTIVE_SOURCES += dialogs/qpagesetupdialog_mac.mm \
+ dialogs/qprintdialog_mac.mm
+
+}
+
+win32 {
+ qpa:DEFINES += QT_NO_PRINTDIALOG
+
+ SOURCES += dialogs/qpagesetupdialog_win.cpp \
+ dialogs/qprintdialog_win.cpp
+}
+
+!mac:!symbian:unix|qpa:!win32 {
+ HEADERS += dialogs/qpagesetupdialog_unix_p.h
+ SOURCES += dialogs/qprintdialog_unix.cpp \
+ dialogs/qpagesetupdialog_unix.cpp
+ FORMS += dialogs/qprintsettingsoutput.ui \
+ dialogs/qprintwidget.ui \
+ dialogs/qprintpropertieswidget.ui
+}
+
+INCLUDEPATH += $$PWD
+
+SOURCES += \
+ dialogs/qabstractprintdialog.cpp \
+ dialogs/qabstractpagesetupdialog.cpp \
+ dialogs/qpagesetupdialog.cpp \
+ dialogs/qprintpreviewdialog.cpp
+
+FORMS += dialogs/qpagesetupwidget.ui
+RESOURCES += dialogs/qprintdialog.qrc
diff --git a/src/gui/dialogs/images/fit-page-24.png b/src/printsupport/dialogs/images/fit-page-24.png
index c7b39d8853..c7b39d8853 100644
--- a/src/gui/dialogs/images/fit-page-24.png
+++ b/src/printsupport/dialogs/images/fit-page-24.png
Binary files differ
diff --git a/src/gui/dialogs/images/fit-page-32.png b/src/printsupport/dialogs/images/fit-page-32.png
index 98bc12d3ed..98bc12d3ed 100644
--- a/src/gui/dialogs/images/fit-page-32.png
+++ b/src/printsupport/dialogs/images/fit-page-32.png
Binary files differ
diff --git a/src/gui/dialogs/images/fit-width-24.png b/src/printsupport/dialogs/images/fit-width-24.png
index a729ffda54..a729ffda54 100644
--- a/src/gui/dialogs/images/fit-width-24.png
+++ b/src/printsupport/dialogs/images/fit-width-24.png
Binary files differ
diff --git a/src/gui/dialogs/images/fit-width-32.png b/src/printsupport/dialogs/images/fit-width-32.png
index 470a8b45d0..470a8b45d0 100644
--- a/src/gui/dialogs/images/fit-width-32.png
+++ b/src/printsupport/dialogs/images/fit-width-32.png
Binary files differ
diff --git a/src/gui/dialogs/images/go-first-24.png b/src/printsupport/dialogs/images/go-first-24.png
index 55315ffa38..55315ffa38 100644
--- a/src/gui/dialogs/images/go-first-24.png
+++ b/src/printsupport/dialogs/images/go-first-24.png
Binary files differ
diff --git a/src/gui/dialogs/images/go-first-32.png b/src/printsupport/dialogs/images/go-first-32.png
index 0fe6f94b77..0fe6f94b77 100644
--- a/src/gui/dialogs/images/go-first-32.png
+++ b/src/printsupport/dialogs/images/go-first-32.png
Binary files differ
diff --git a/src/gui/dialogs/images/go-last-24.png b/src/printsupport/dialogs/images/go-last-24.png
index 81061b80f2..81061b80f2 100644
--- a/src/gui/dialogs/images/go-last-24.png
+++ b/src/printsupport/dialogs/images/go-last-24.png
Binary files differ
diff --git a/src/gui/dialogs/images/go-last-32.png b/src/printsupport/dialogs/images/go-last-32.png
index 887506107e..887506107e 100644
--- a/src/gui/dialogs/images/go-last-32.png
+++ b/src/printsupport/dialogs/images/go-last-32.png
Binary files differ
diff --git a/src/gui/dialogs/images/go-next-24.png b/src/printsupport/dialogs/images/go-next-24.png
index 9a55ef3d86..9a55ef3d86 100644
--- a/src/gui/dialogs/images/go-next-24.png
+++ b/src/printsupport/dialogs/images/go-next-24.png
Binary files differ
diff --git a/src/gui/dialogs/images/go-next-32.png b/src/printsupport/dialogs/images/go-next-32.png
index 6d98f50f4f..6d98f50f4f 100644
--- a/src/gui/dialogs/images/go-next-32.png
+++ b/src/printsupport/dialogs/images/go-next-32.png
Binary files differ
diff --git a/src/gui/dialogs/images/go-previous-24.png b/src/printsupport/dialogs/images/go-previous-24.png
index 2ea769eb8d..2ea769eb8d 100644
--- a/src/gui/dialogs/images/go-previous-24.png
+++ b/src/printsupport/dialogs/images/go-previous-24.png
Binary files differ
diff --git a/src/gui/dialogs/images/go-previous-32.png b/src/printsupport/dialogs/images/go-previous-32.png
index 37ba0c4e8d..37ba0c4e8d 100644
--- a/src/gui/dialogs/images/go-previous-32.png
+++ b/src/printsupport/dialogs/images/go-previous-32.png
Binary files differ
diff --git a/src/gui/dialogs/images/layout-landscape-24.png b/src/printsupport/dialogs/images/layout-landscape-24.png
index 6f89a31cb6..6f89a31cb6 100644
--- a/src/gui/dialogs/images/layout-landscape-24.png
+++ b/src/printsupport/dialogs/images/layout-landscape-24.png
Binary files differ
diff --git a/src/gui/dialogs/images/layout-landscape-32.png b/src/printsupport/dialogs/images/layout-landscape-32.png
index 6a94946c36..6a94946c36 100644
--- a/src/gui/dialogs/images/layout-landscape-32.png
+++ b/src/printsupport/dialogs/images/layout-landscape-32.png
Binary files differ
diff --git a/src/gui/dialogs/images/layout-portrait-24.png b/src/printsupport/dialogs/images/layout-portrait-24.png
index e0dbabc83b..e0dbabc83b 100644
--- a/src/gui/dialogs/images/layout-portrait-24.png
+++ b/src/printsupport/dialogs/images/layout-portrait-24.png
Binary files differ
diff --git a/src/gui/dialogs/images/layout-portrait-32.png b/src/printsupport/dialogs/images/layout-portrait-32.png
index d17468c0a4..d17468c0a4 100644
--- a/src/gui/dialogs/images/layout-portrait-32.png
+++ b/src/printsupport/dialogs/images/layout-portrait-32.png
Binary files differ
diff --git a/src/gui/dialogs/images/page-setup-24.png b/src/printsupport/dialogs/images/page-setup-24.png
index 4bfafdace0..4bfafdace0 100644
--- a/src/gui/dialogs/images/page-setup-24.png
+++ b/src/printsupport/dialogs/images/page-setup-24.png
Binary files differ
diff --git a/src/gui/dialogs/images/page-setup-32.png b/src/printsupport/dialogs/images/page-setup-32.png
index 2313b8fe3b..2313b8fe3b 100644
--- a/src/gui/dialogs/images/page-setup-32.png
+++ b/src/printsupport/dialogs/images/page-setup-32.png
Binary files differ
diff --git a/src/gui/dialogs/images/print-24.png b/src/printsupport/dialogs/images/print-24.png
index c6bf3e8672..c6bf3e8672 100644
--- a/src/gui/dialogs/images/print-24.png
+++ b/src/printsupport/dialogs/images/print-24.png
Binary files differ
diff --git a/src/gui/dialogs/images/print-32.png b/src/printsupport/dialogs/images/print-32.png
index 5830888653..5830888653 100644
--- a/src/gui/dialogs/images/print-32.png
+++ b/src/printsupport/dialogs/images/print-32.png
Binary files differ
diff --git a/src/gui/dialogs/images/status-color.png b/src/printsupport/dialogs/images/status-color.png
index af3cbfa31c..af3cbfa31c 100644
--- a/src/gui/dialogs/images/status-color.png
+++ b/src/printsupport/dialogs/images/status-color.png
Binary files differ
diff --git a/src/gui/dialogs/images/status-gray-scale.png b/src/printsupport/dialogs/images/status-gray-scale.png
index 4462588809..4462588809 100644
--- a/src/gui/dialogs/images/status-gray-scale.png
+++ b/src/printsupport/dialogs/images/status-gray-scale.png
Binary files differ
diff --git a/src/gui/dialogs/images/view-page-multi-24.png b/src/printsupport/dialogs/images/view-page-multi-24.png
index 87241472ae..87241472ae 100644
--- a/src/gui/dialogs/images/view-page-multi-24.png
+++ b/src/printsupport/dialogs/images/view-page-multi-24.png
Binary files differ
diff --git a/src/gui/dialogs/images/view-page-multi-32.png b/src/printsupport/dialogs/images/view-page-multi-32.png
index 130885a041..130885a041 100644
--- a/src/gui/dialogs/images/view-page-multi-32.png
+++ b/src/printsupport/dialogs/images/view-page-multi-32.png
Binary files differ
diff --git a/src/gui/dialogs/images/view-page-one-24.png b/src/printsupport/dialogs/images/view-page-one-24.png
index 4c6457b892..4c6457b892 100644
--- a/src/gui/dialogs/images/view-page-one-24.png
+++ b/src/printsupport/dialogs/images/view-page-one-24.png
Binary files differ
diff --git a/src/gui/dialogs/images/view-page-one-32.png b/src/printsupport/dialogs/images/view-page-one-32.png
index 537193984e..537193984e 100644
--- a/src/gui/dialogs/images/view-page-one-32.png
+++ b/src/printsupport/dialogs/images/view-page-one-32.png
Binary files differ
diff --git a/src/gui/dialogs/images/view-page-sided-24.png b/src/printsupport/dialogs/images/view-page-sided-24.png
index 2131305c41..2131305c41 100644
--- a/src/gui/dialogs/images/view-page-sided-24.png
+++ b/src/printsupport/dialogs/images/view-page-sided-24.png
Binary files differ
diff --git a/src/gui/dialogs/images/view-page-sided-32.png b/src/printsupport/dialogs/images/view-page-sided-32.png
index e4d63f9992..e4d63f9992 100644
--- a/src/gui/dialogs/images/view-page-sided-32.png
+++ b/src/printsupport/dialogs/images/view-page-sided-32.png
Binary files differ
diff --git a/src/gui/dialogs/images/zoom-in-24.png b/src/printsupport/dialogs/images/zoom-in-24.png
index d29b142b6c..d29b142b6c 100644
--- a/src/gui/dialogs/images/zoom-in-24.png
+++ b/src/printsupport/dialogs/images/zoom-in-24.png
Binary files differ
diff --git a/src/gui/dialogs/images/zoom-in-32.png b/src/printsupport/dialogs/images/zoom-in-32.png
index 34d70af37b..34d70af37b 100644
--- a/src/gui/dialogs/images/zoom-in-32.png
+++ b/src/printsupport/dialogs/images/zoom-in-32.png
Binary files differ
diff --git a/src/gui/dialogs/images/zoom-out-24.png b/src/printsupport/dialogs/images/zoom-out-24.png
index 19703474f8..19703474f8 100644
--- a/src/gui/dialogs/images/zoom-out-24.png
+++ b/src/printsupport/dialogs/images/zoom-out-24.png
Binary files differ
diff --git a/src/gui/dialogs/images/zoom-out-32.png b/src/printsupport/dialogs/images/zoom-out-32.png
index b832206612..b832206612 100644
--- a/src/gui/dialogs/images/zoom-out-32.png
+++ b/src/printsupport/dialogs/images/zoom-out-32.png
Binary files differ
diff --git a/src/printsupport/dialogs/qabstractpagesetupdialog.cpp b/src/printsupport/dialogs/qabstractpagesetupdialog.cpp
new file mode 100644
index 0000000000..8268065bfd
--- /dev/null
+++ b/src/printsupport/dialogs/qabstractpagesetupdialog.cpp
@@ -0,0 +1,139 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qabstractpagesetupdialog.h"
+#include "qabstractpagesetupdialog_p.h"
+
+#ifndef QT_NO_PRINTDIALOG
+
+#include <QtCore/qcoreapplication.h>
+#include <QtPrintSupport/qprinter.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \internal
+ \class QAbstractPageSetupDialog
+
+ \brief The QAbstractPageSetupDialog class provides a base for
+ implementations of page setup dialogs.
+*/
+
+/*!
+ Constructs the page setup dialog for the printer \a printer with
+ \a parent as parent widget.
+*/
+QAbstractPageSetupDialog::QAbstractPageSetupDialog(QPrinter *printer, QWidget *parent)
+ : QDialog(*(new QAbstractPageSetupDialogPrivate), parent)
+{
+ Q_D(QAbstractPageSetupDialog);
+ setWindowTitle(QCoreApplication::translate("QPrintPreviewDialog", "Page Setup"));
+ d->setPrinter(printer);
+}
+
+/*!
+ \internal
+*/
+QAbstractPageSetupDialog::QAbstractPageSetupDialog(QAbstractPageSetupDialogPrivate &ptr,
+ QPrinter *printer, QWidget *parent)
+ : QDialog(ptr, parent)
+{
+ Q_D(QAbstractPageSetupDialog);
+ setWindowTitle(QCoreApplication::translate("QPrintPreviewDialog", "Page Setup"));
+ d->setPrinter(printer);
+}
+
+QAbstractPageSetupDialog::~QAbstractPageSetupDialog()
+{
+ Q_D(QAbstractPageSetupDialog);
+ if (d->opts & QPageSetupDialog::OwnsPrinter)
+ delete d->printer;
+}
+
+/*!
+ Returns the printer that this page setup dialog is operating on.
+*/
+QPrinter *QAbstractPageSetupDialog::printer()
+{
+ Q_D(QAbstractPageSetupDialog);
+ return d->printer;
+}
+
+void QAbstractPageSetupDialogPrivate::setPrinter(QPrinter *newPrinter)
+{
+ if (newPrinter) {
+ printer = newPrinter;
+ } else {
+ printer = new QPrinter;
+ opts |= QPageSetupDialog::OwnsPrinter;
+ }
+#ifndef Q_WS_X11
+ if (printer->outputFormat() != QPrinter::NativeFormat)
+ qWarning("QPageSetupDialog: Cannot be used on non-native printers");
+#endif
+}
+
+/*!
+ \fn int QAbstractPageSetupDialog::exec()
+
+ This virtual function is called to pop up the dialog. It must be
+ reimplemented in subclasses.
+*/
+
+/*!
+ \reimp
+*/
+void QAbstractPageSetupDialog::done(int result)
+{
+ Q_D(QAbstractPageSetupDialog);
+ QDialog::done(result);
+ if (d->receiverToDisconnectOnClose) {
+ disconnect(this, SIGNAL(accepted()),
+ d->receiverToDisconnectOnClose, d->memberToDisconnectOnClose);
+ d->receiverToDisconnectOnClose = 0;
+ }
+ d->memberToDisconnectOnClose.clear();
+
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_PRINTDIALOG
diff --git a/src/printsupport/dialogs/qabstractpagesetupdialog.h b/src/printsupport/dialogs/qabstractpagesetupdialog.h
new file mode 100644
index 0000000000..597a7258d9
--- /dev/null
+++ b/src/printsupport/dialogs/qabstractpagesetupdialog.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QABSTRACTPAGESETUPDIALOG_H
+#define QABSTRACTPAGESETUPDIALOG_H
+
+#include <QtWidgets/qdialog.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_PRINTDIALOG
+
+class QAbstractPageSetupDialogPrivate;
+class QPrinter;
+
+// ### Qt 5: Remove this class
+class Q_PRINTSUPPORT_EXPORT QAbstractPageSetupDialog : public QDialog
+{
+ Q_DECLARE_PRIVATE(QAbstractPageSetupDialog)
+ Q_OBJECT
+
+public:
+ explicit QAbstractPageSetupDialog(QPrinter *printer, QWidget *parent = 0);
+ QAbstractPageSetupDialog(QAbstractPageSetupDialogPrivate &ptr,
+ QPrinter *printer, QWidget *parent = 0);
+ ~QAbstractPageSetupDialog();
+
+ virtual int exec() = 0;
+ void done(int result);
+
+ QPrinter *printer();
+};
+
+#endif // QT_NO_PRINTDIALOG
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QABSTRACTPAGESETUPDIALOG_H
diff --git a/src/gui/dialogs/qabstractpagesetupdialog_p.h b/src/printsupport/dialogs/qabstractpagesetupdialog_p.h
index 3a4711dd6b..3a4711dd6b 100644
--- a/src/gui/dialogs/qabstractpagesetupdialog_p.h
+++ b/src/printsupport/dialogs/qabstractpagesetupdialog_p.h
diff --git a/src/printsupport/dialogs/qabstractprintdialog.cpp b/src/printsupport/dialogs/qabstractprintdialog.cpp
new file mode 100644
index 0000000000..73b9c4f14e
--- /dev/null
+++ b/src/printsupport/dialogs/qabstractprintdialog.cpp
@@ -0,0 +1,501 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qabstractprintdialog_p.h"
+#include "qcoreapplication.h"
+#include "qprintdialog.h"
+#include "qprinter.h"
+#include "private/qprinter_p.h"
+
+#ifndef QT_NO_PRINTDIALOG
+
+QT_BEGIN_NAMESPACE
+
+// hack
+class QPrintDialogPrivate : public QAbstractPrintDialogPrivate
+{
+};
+
+/*!
+ \class QAbstractPrintDialog
+ \brief The QAbstractPrintDialog class provides a base implementation for
+ print dialogs used to configure printers.
+
+ \ingroup printing
+
+ This class implements getter and setter functions that are used to
+ customize settings shown in print dialogs, but it is not used directly.
+ Use QPrintDialog to display a print dialog in your application.
+
+ In Symbian, there is no support for printing. Hence, this dialog should not
+ be used in Symbian.
+
+ \sa QPrintDialog, QPrinter, {Printing with Qt}
+*/
+
+/*!
+ \enum QAbstractPrintDialog::PrintRange
+
+ Used to specify the print range selection option.
+
+ \value AllPages All pages should be printed.
+ \value Selection Only the selection should be printed.
+ \value PageRange The specified page range should be printed.
+ \value CurrentPage Only the currently visible page should be printed.
+
+ \sa QPrinter::PrintRange
+*/
+
+/*!
+ \enum QAbstractPrintDialog::PrintDialogOption
+
+ Used to specify which parts of the print dialog should be visible.
+
+ \value None None of the options are enabled.
+ \value PrintToFile The print to file option is enabled.
+ \value PrintSelection The print selection option is enabled.
+ \value PrintPageRange The page range selection option is enabled.
+ \value PrintShowPageSize Show the page size + margins page only if this is enabled.
+ \value PrintCollateCopies The collate copies option is enabled
+ \value PrintCurrentPage The print current page option is enabled
+
+ This value is obsolete and does nothing since Qt 4.5:
+
+ \value DontUseSheet In previous versions of Qt, exec() the print dialog
+ would create a sheet by default the dialog was given a parent.
+ This is no longer supported in Qt 4.5. If you want to use sheets, use
+ QPrintDialog::open() instead.
+*/
+
+/*!
+ Constructs an abstract print dialog for \a printer with \a parent
+ as parent widget.
+*/
+QAbstractPrintDialog::QAbstractPrintDialog(QPrinter *printer, QWidget *parent)
+ : QDialog(*(new QAbstractPrintDialogPrivate), parent)
+{
+ Q_D(QAbstractPrintDialog);
+ setWindowTitle(QCoreApplication::translate("QPrintDialog", "Print"));
+ d->setPrinter(printer);
+ d->minPage = printer->fromPage();
+ int to = printer->toPage();
+ d->maxPage = to > 0 ? to : INT_MAX;
+}
+
+/*!
+ \internal
+*/
+QAbstractPrintDialog::QAbstractPrintDialog(QAbstractPrintDialogPrivate &ptr,
+ QPrinter *printer,
+ QWidget *parent)
+ : QDialog(ptr, parent)
+{
+ Q_D(QAbstractPrintDialog);
+ setWindowTitle(QCoreApplication::translate("QPrintDialog", "Print"));
+ d->setPrinter(printer);
+}
+
+/*!
+ \internal
+*/
+QAbstractPrintDialog::~QAbstractPrintDialog()
+{
+ Q_D(QAbstractPrintDialog);
+ if (d->ownsPrinter)
+ delete d->printer;
+}
+
+/*!
+ Sets the given \a option to be enabled if \a on is true;
+ otherwise, clears the given \a option.
+
+ \sa options, testOption()
+*/
+void QPrintDialog::setOption(PrintDialogOption option, bool on)
+{
+ Q_D(QPrintDialog);
+ if (!(d->options & option) != !on)
+ setOptions(d->options ^ option);
+}
+
+/*!
+ Returns true if the given \a option is enabled; otherwise, returns
+ false.
+
+ \sa options, setOption()
+*/
+bool QPrintDialog::testOption(PrintDialogOption option) const
+{
+ Q_D(const QPrintDialog);
+ return (d->options & option) != 0;
+}
+
+/*!
+ \property QPrintDialog::options
+ \brief the various options that affect the look and feel of the dialog
+ \since 4.5
+
+ By default, all options are disabled.
+
+ Options should be set before showing the dialog. Setting them while the
+ dialog is visible is not guaranteed to have an immediate effect on the
+ dialog (depending on the option and on the platform).
+
+ \sa setOption(), testOption()
+*/
+void QPrintDialog::setOptions(PrintDialogOptions options)
+{
+ Q_D(QPrintDialog);
+
+ PrintDialogOptions changed = (options ^ d->options);
+ if (!changed)
+ return;
+
+ d->options = options;
+}
+
+QPrintDialog::PrintDialogOptions QPrintDialog::options() const
+{
+ Q_D(const QPrintDialog);
+ return d->options;
+}
+
+/*!
+ \obsolete
+
+ Use QPrintDialog::setOptions() instead.
+*/
+void QAbstractPrintDialog::setEnabledOptions(PrintDialogOptions options)
+{
+ Q_D(QAbstractPrintDialog);
+ d->options = options;
+}
+
+/*!
+ \obsolete
+
+ Use QPrintDialog::setOption(\a option, true) instead.
+*/
+void QAbstractPrintDialog::addEnabledOption(PrintDialogOption option)
+{
+ Q_D(QAbstractPrintDialog);
+ d->options |= option;
+}
+
+/*!
+ \obsolete
+
+ Use QPrintDialog::options() instead.
+*/
+QAbstractPrintDialog::PrintDialogOptions QAbstractPrintDialog::enabledOptions() const
+{
+ Q_D(const QAbstractPrintDialog);
+ return d->options;
+}
+
+/*!
+ \obsolete
+
+ Use QPrintDialog::testOption(\a option) instead.
+*/
+bool QAbstractPrintDialog::isOptionEnabled(PrintDialogOption option) const
+{
+ Q_D(const QAbstractPrintDialog);
+ return d->options & option;
+}
+
+/*!
+ Sets the print range option in to be \a range.
+ */
+void QAbstractPrintDialog::setPrintRange(PrintRange range)
+{
+ Q_D(QAbstractPrintDialog);
+ d->printer->setPrintRange(QPrinter::PrintRange(range));
+}
+
+/*!
+ Returns the print range.
+*/
+QAbstractPrintDialog::PrintRange QAbstractPrintDialog::printRange() const
+{
+ Q_D(const QAbstractPrintDialog);
+ return QAbstractPrintDialog::PrintRange(d->pd->printRange);
+}
+
+/*!
+ Sets the page range in this dialog to be from \a min to \a max. This also
+ enables the PrintPageRange option.
+*/
+void QAbstractPrintDialog::setMinMax(int min, int max)
+{
+ Q_D(QAbstractPrintDialog);
+ Q_ASSERT_X(min <= max, "QAbstractPrintDialog::setMinMax",
+ "'min' must be less than or equal to 'max'");
+ d->minPage = min;
+ d->maxPage = max;
+ d->options |= PrintPageRange;
+}
+
+/*!
+ Returns the minimum page in the page range.
+ By default, this value is set to 1.
+*/
+int QAbstractPrintDialog::minPage() const
+{
+ Q_D(const QAbstractPrintDialog);
+ return d->minPage;
+}
+
+/*!
+ Returns the maximum page in the page range. As of Qt 4.4, this
+ function returns INT_MAX by default. Previous versions returned 1
+ by default.
+*/
+int QAbstractPrintDialog::maxPage() const
+{
+ Q_D(const QAbstractPrintDialog);
+ return d->maxPage;
+}
+
+/*!
+ Sets the range in the print dialog to be from \a from to \a to.
+*/
+void QAbstractPrintDialog::setFromTo(int from, int to)
+{
+ Q_D(QAbstractPrintDialog);
+ Q_ASSERT_X(from <= to, "QAbstractPrintDialog::setFromTo",
+ "'from' must be less than or equal to 'to'");
+ d->printer->setFromTo(from, to);
+
+ if (d->minPage == 0 && d->maxPage == 0)
+ setMinMax(1, to);
+}
+
+/*!
+ Returns the first page to be printed
+ By default, this value is set to 0.
+*/
+int QAbstractPrintDialog::fromPage() const
+{
+ Q_D(const QAbstractPrintDialog);
+ return d->printer->fromPage();
+}
+
+/*!
+ Returns the last page to be printed.
+ By default, this value is set to 0.
+*/
+int QAbstractPrintDialog::toPage() const
+{
+ Q_D(const QAbstractPrintDialog);
+ return d->printer->toPage();
+}
+
+
+/*!
+ Returns the printer that this printer dialog operates
+ on.
+*/
+QPrinter *QAbstractPrintDialog::printer() const
+{
+ Q_D(const QAbstractPrintDialog);
+ return d->printer;
+}
+
+void QAbstractPrintDialogPrivate::setPrinter(QPrinter *newPrinter)
+{
+ if (newPrinter) {
+ printer = newPrinter;
+ ownsPrinter = false;
+ if (printer->fromPage() || printer->toPage())
+ options |= QAbstractPrintDialog::PrintPageRange;
+ } else {
+ printer = new QPrinter;
+ ownsPrinter = true;
+ }
+ pd = printer->d_func();
+}
+
+/*!
+ \fn int QAbstractPrintDialog::exec()
+
+ This virtual function is called to pop up the dialog. It must be
+ reimplemented in subclasses.
+*/
+
+/*!
+ \class QPrintDialog
+
+ \brief The QPrintDialog class provides a dialog for specifying
+ the printer's configuration.
+
+ \ingroup standard-dialogs
+ \ingroup printing
+
+ The dialog allows users to change document-related settings, such
+ as the paper size and orientation, type of print (color or
+ grayscale), range of pages, and number of copies to print.
+
+ Controls are also provided to enable users to choose from the
+ printers available, including any configured network printers.
+
+ Typically, QPrintDialog objects are constructed with a QPrinter
+ object, and executed using the exec() function.
+
+ \snippet doc/src/snippets/code/src_gui_dialogs_qabstractprintdialog.cpp 0
+
+ If the dialog is accepted by the user, the QPrinter object is
+ correctly configured for printing.
+
+ \table
+ \row
+ \o \inlineimage plastique-printdialog.png
+ \o \inlineimage plastique-printdialog-properties.png
+ \endtable
+
+ The printer dialog (shown above in Plastique style) enables access to common
+ printing properties. On X11 platforms that use the CUPS printing system, the
+ settings for each available printer can be modified via the dialog's
+ \gui{Properties} push button.
+
+ On Windows and Mac OS X, the native print dialog is used, which means that
+ some QWidget and QDialog properties set on the dialog won't be respected.
+ The native print dialog on Mac OS X does not support setting printer options,
+ i.e. setOptions() and setOption() have no effect.
+
+ In Qt 4.4, it was possible to use the static functions to show a sheet on
+ Mac OS X. This is no longer supported in Qt 4.5. If you want this
+ functionality, use QPrintDialog::open().
+
+ \sa QPageSetupDialog, QPrinter, {Pixelator Example}, {Order Form Example},
+ {Image Viewer Example}, {Scribble Example}
+*/
+
+/*!
+ \fn QPrintDialog::QPrintDialog(QPrinter *printer, QWidget *parent)
+
+ Constructs a new modal printer dialog for the given \a printer
+ with the given \a parent.
+*/
+
+/*!
+ \fn QPrintDialog::~QPrintDialog()
+
+ Destroys the print dialog.
+*/
+
+/*!
+ \fn int QPrintDialog::exec()
+ \reimp
+*/
+
+/*!
+ \since 4.4
+
+ Set a list of widgets as \a tabs to be shown on the print dialog, if supported.
+
+ Currently this option is only supported on X11.
+
+ Setting the option tabs will transfer their ownership to the print dialog.
+*/
+void QAbstractPrintDialog::setOptionTabs(const QList<QWidget*> &tabs)
+{
+ Q_D(QAbstractPrintDialog);
+ d->setTabs(tabs);
+}
+
+/*!
+
+ \fn void QPrintDialog::accepted(QPrinter *printer)
+
+ This signal is emitted when the user accepts the values set in the print dialog.
+ The \a printer parameter includes the printer that the settings were applied to.
+*/
+
+/*!
+ \fn QPrinter *QPrintDialog::printer()
+
+ Returns the printer that this printer dialog operates
+ on. This can be useful when using the QPrintDialog::open() method.
+*/
+
+/*!
+ Closes the dialog and sets its result code to \a result. If this dialog
+ is shown with exec(), done() causes the local event loop to finish,
+ and exec() to return \a result.
+
+ \sa QDialog::done()
+*/
+void QPrintDialog::done(int result)
+{
+ Q_D(QPrintDialog);
+ QDialog::done(result);
+ if (result == Accepted)
+ emit accepted(printer());
+ if (d->receiverToDisconnectOnClose) {
+ disconnect(this, SIGNAL(accepted(QPrinter*)),
+ d->receiverToDisconnectOnClose, d->memberToDisconnectOnClose);
+ d->receiverToDisconnectOnClose = 0;
+ }
+ d->memberToDisconnectOnClose.clear();
+}
+
+/*!
+ \since 4.5
+ \overload
+
+ Opens the dialog and connects its accepted() signal to the slot specified
+ by \a receiver and \a member.
+
+ The signal will be disconnected from the slot when the dialog is closed.
+*/
+void QPrintDialog::open(QObject *receiver, const char *member)
+{
+ Q_D(QPrintDialog);
+ connect(this, SIGNAL(accepted(QPrinter*)), receiver, member);
+ d->receiverToDisconnectOnClose = receiver;
+ d->memberToDisconnectOnClose = member;
+ QDialog::open();
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_PRINTDIALOG
diff --git a/src/printsupport/dialogs/qabstractprintdialog.h b/src/printsupport/dialogs/qabstractprintdialog.h
new file mode 100644
index 0000000000..2f8a750827
--- /dev/null
+++ b/src/printsupport/dialogs/qabstractprintdialog.h
@@ -0,0 +1,130 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QABSTRACTPRINTDIALOG_H
+#define QABSTRACTPRINTDIALOG_H
+
+#include <QtWidgets/qdialog.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_PRINTER
+
+class QAbstractPrintDialogPrivate;
+class QPrinter;
+
+// ### Qt 5: remove this class
+class Q_PRINTSUPPORT_EXPORT QAbstractPrintDialog : public QDialog
+{
+ Q_DECLARE_PRIVATE(QAbstractPrintDialog)
+ Q_OBJECT
+
+public:
+ // Keep in sync with QPrinter::PrintRange
+ enum PrintRange {
+ AllPages,
+ Selection,
+ PageRange,
+ CurrentPage
+ };
+
+ enum PrintDialogOption {
+ None = 0x0000, // obsolete
+ PrintToFile = 0x0001,
+ PrintSelection = 0x0002,
+ PrintPageRange = 0x0004,
+ PrintShowPageSize = 0x0008,
+ PrintCollateCopies = 0x0010,
+ DontUseSheet = 0x0020,
+ PrintCurrentPage = 0x0040
+ };
+
+ Q_DECLARE_FLAGS(PrintDialogOptions, PrintDialogOption)
+
+#ifndef QT_NO_PRINTDIALOG
+ explicit QAbstractPrintDialog(QPrinter *printer, QWidget *parent = 0);
+ ~QAbstractPrintDialog();
+
+ virtual int exec() = 0;
+
+ // obsolete
+ void addEnabledOption(PrintDialogOption option);
+ void setEnabledOptions(PrintDialogOptions options);
+ PrintDialogOptions enabledOptions() const;
+ bool isOptionEnabled(PrintDialogOption option) const;
+
+ void setOptionTabs(const QList<QWidget*> &tabs);
+
+ void setPrintRange(PrintRange range);
+ PrintRange printRange() const;
+
+ void setMinMax(int min, int max);
+ int minPage() const;
+ int maxPage() const;
+
+ void setFromTo(int fromPage, int toPage);
+ int fromPage() const;
+ int toPage() const;
+
+ QPrinter *printer() const;
+
+protected:
+ QAbstractPrintDialog(QAbstractPrintDialogPrivate &ptr, QPrinter *printer, QWidget *parent = 0);
+
+private:
+ Q_DISABLE_COPY(QAbstractPrintDialog)
+
+#endif // QT_NO_PRINTDIALOG
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QAbstractPrintDialog::PrintDialogOptions)
+
+#endif // QT_NO_PRINTER
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QABSTRACTPRINTDIALOG_H
diff --git a/src/printsupport/dialogs/qabstractprintdialog_p.h b/src/printsupport/dialogs/qabstractprintdialog_p.h
new file mode 100644
index 0000000000..e329cb3169
--- /dev/null
+++ b/src/printsupport/dialogs/qabstractprintdialog_p.h
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QABSTRACTPRINTDIALOG_P_H
+#define QABSTRACTPRINTDIALOG_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "private/qdialog_p.h"
+
+#ifndef QT_NO_PRINTDIALOG
+
+#include "QtPrintSupport/qabstractprintdialog.h"
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_PRINTER
+
+class QPrinter;
+class QPrinterPrivate;
+
+class QAbstractPrintDialogPrivate : public QDialogPrivate
+{
+ Q_DECLARE_PUBLIC(QAbstractPrintDialog)
+
+public:
+ QAbstractPrintDialogPrivate()
+ : printer(0), pd(0), ownsPrinter(false)
+ , options(QAbstractPrintDialog::PrintToFile | QAbstractPrintDialog::PrintPageRange |
+ QAbstractPrintDialog::PrintCollateCopies | QAbstractPrintDialog::PrintShowPageSize),
+ minPage(0), maxPage(INT_MAX)
+ {
+ }
+
+ QPrinter *printer;
+ QPrinterPrivate *pd;
+ bool ownsPrinter;
+ QPointer<QObject> receiverToDisconnectOnClose;
+ QByteArray memberToDisconnectOnClose;
+
+ QAbstractPrintDialog::PrintDialogOptions options;
+
+ virtual void setTabs(const QList<QWidget *> &) {}
+ void setPrinter(QPrinter *newPrinter);
+ int minPage;
+ int maxPage;
+};
+
+#endif //QT_NO_PRINTER
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_PRINTDIALOG
+
+#endif // QABSTRACTPRINTDIALOG_P_H
diff --git a/src/gui/dialogs/qpagesetupdialog.cpp b/src/printsupport/dialogs/qpagesetupdialog.cpp
index 658dfc1def..658dfc1def 100644
--- a/src/gui/dialogs/qpagesetupdialog.cpp
+++ b/src/printsupport/dialogs/qpagesetupdialog.cpp
diff --git a/src/printsupport/dialogs/qpagesetupdialog.h b/src/printsupport/dialogs/qpagesetupdialog.h
new file mode 100644
index 0000000000..1581ce6c41
--- /dev/null
+++ b/src/printsupport/dialogs/qpagesetupdialog.h
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPAGESETUPDIALOG_H
+#define QPAGESETUPDIALOG_H
+
+#include <QtPrintSupport/qabstractpagesetupdialog.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_PRINTDIALOG
+
+class QPageSetupDialogPrivate;
+
+class Q_PRINTSUPPORT_EXPORT QPageSetupDialog : public QAbstractPageSetupDialog
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QPageSetupDialog)
+ Q_ENUMS(PageSetupDialogOption)
+ Q_PROPERTY(PageSetupDialogOptions options READ options WRITE setOptions)
+
+public:
+ enum PageSetupDialogOption {
+ None = 0x00000000, // internal
+ DontUseSheet = 0x00000001,
+ OwnsPrinter = 0x80000000 // internal
+ };
+
+ Q_DECLARE_FLAGS(PageSetupDialogOptions, PageSetupDialogOption)
+
+ explicit QPageSetupDialog(QPrinter *printer, QWidget *parent = 0);
+ explicit QPageSetupDialog(QWidget *parent = 0);
+
+ // obsolete
+ void addEnabledOption(PageSetupDialogOption option);
+ void setEnabledOptions(PageSetupDialogOptions options);
+ PageSetupDialogOptions enabledOptions() const;
+ bool isOptionEnabled(PageSetupDialogOption option) const;
+
+ void setOption(PageSetupDialogOption option, bool on = true);
+ bool testOption(PageSetupDialogOption option) const;
+ void setOptions(PageSetupDialogOptions options);
+ PageSetupDialogOptions options() const;
+
+#if defined(Q_WS_MAC) || defined(Q_OS_WIN)
+ virtual void setVisible(bool visible);
+#endif
+ virtual int exec();
+
+#ifdef Q_NO_USING_KEYWORD
+#ifndef Q_QDOC
+ void open() { QDialog::open(); }
+#endif
+#else
+ using QDialog::open;
+#endif
+ void open(QObject *receiver, const char *member);
+
+#ifdef qdoc
+ QPrinter *printer();
+#endif
+};
+
+#endif // QT_NO_PRINTDIALOG
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QPAGESETUPDIALOG_H
diff --git a/src/gui/dialogs/qpagesetupdialog_mac.mm b/src/printsupport/dialogs/qpagesetupdialog_mac.mm
index 725520116a..725520116a 100644
--- a/src/gui/dialogs/qpagesetupdialog_mac.mm
+++ b/src/printsupport/dialogs/qpagesetupdialog_mac.mm
diff --git a/src/printsupport/dialogs/qpagesetupdialog_unix.cpp b/src/printsupport/dialogs/qpagesetupdialog_unix.cpp
new file mode 100644
index 0000000000..e5b12f8ba5
--- /dev/null
+++ b/src/printsupport/dialogs/qpagesetupdialog_unix.cpp
@@ -0,0 +1,620 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qpagesetupdialog.h"
+
+#ifndef QT_NO_PRINTDIALOG
+#include "qpagesetupdialog_unix_p.h"
+
+#include "qpainter.h"
+#include "qprintdialog.h"
+#include "qdialogbuttonbox.h"
+#include <ui_qpagesetupwidget.h>
+
+#include <QtPrintSupport/qprinter.h>
+#include <private/qabstractpagesetupdialog_p.h>
+#include <private/qprinter_p.h>
+
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+# include <private/qcups_p.h>
+# include <cups/cups.h>
+# include <private/qprintengine_pdf_p.h>
+#endif
+
+
+QT_BEGIN_NAMESPACE
+
+QSizeF qt_printerPaperSize(QPrinter::Orientation, QPrinter::PaperSize, QPrinter::Unit, int);
+
+// Disabled until we have support for papersources on unix
+// #define PSD_ENABLE_PAPERSOURCE
+
+static void populatePaperSizes(QComboBox* cb)
+{
+ cb->addItem(QPrintDialog::tr("A0"), QPrinter::A0);
+ cb->addItem(QPrintDialog::tr("A1"), QPrinter::A1);
+ cb->addItem(QPrintDialog::tr("A2"), QPrinter::A2);
+ cb->addItem(QPrintDialog::tr("A3"), QPrinter::A3);
+ cb->addItem(QPrintDialog::tr("A4"), QPrinter::A4);
+ cb->addItem(QPrintDialog::tr("A5"), QPrinter::A5);
+ cb->addItem(QPrintDialog::tr("A6"), QPrinter::A6);
+ cb->addItem(QPrintDialog::tr("A7"), QPrinter::A7);
+ cb->addItem(QPrintDialog::tr("A8"), QPrinter::A8);
+ cb->addItem(QPrintDialog::tr("A9"), QPrinter::A9);
+ cb->addItem(QPrintDialog::tr("B0"), QPrinter::B0);
+ cb->addItem(QPrintDialog::tr("B1"), QPrinter::B1);
+ cb->addItem(QPrintDialog::tr("B2"), QPrinter::B2);
+ cb->addItem(QPrintDialog::tr("B3"), QPrinter::B3);
+ cb->addItem(QPrintDialog::tr("B4"), QPrinter::B4);
+ cb->addItem(QPrintDialog::tr("B5"), QPrinter::B5);
+ cb->addItem(QPrintDialog::tr("B6"), QPrinter::B6);
+ cb->addItem(QPrintDialog::tr("B7"), QPrinter::B7);
+ cb->addItem(QPrintDialog::tr("B8"), QPrinter::B8);
+ cb->addItem(QPrintDialog::tr("B9"), QPrinter::B9);
+ cb->addItem(QPrintDialog::tr("B10"), QPrinter::B10);
+ cb->addItem(QPrintDialog::tr("C5E"), QPrinter::C5E);
+ cb->addItem(QPrintDialog::tr("DLE"), QPrinter::DLE);
+ cb->addItem(QPrintDialog::tr("Executive"), QPrinter::Executive);
+ cb->addItem(QPrintDialog::tr("Folio"), QPrinter::Folio);
+ cb->addItem(QPrintDialog::tr("Ledger"), QPrinter::Ledger);
+ cb->addItem(QPrintDialog::tr("Legal"), QPrinter::Legal);
+ cb->addItem(QPrintDialog::tr("Letter"), QPrinter::Letter);
+ cb->addItem(QPrintDialog::tr("Tabloid"), QPrinter::Tabloid);
+ cb->addItem(QPrintDialog::tr("US Common #10 Envelope"), QPrinter::Comm10E);
+ cb->addItem(QPrintDialog::tr("Custom"), QPrinter::Custom);
+}
+
+
+static QSizeF sizeForOrientation(QPrinter::Orientation orientation, const QSizeF &size)
+{
+ return (orientation == QPrinter::Portrait) ? size : QSizeF(size.height(), size.width());
+}
+
+#ifdef PSD_ENABLE_PAPERSOURCE
+static const char *paperSourceNames[] = {
+ "Only One",
+ "Lower",
+ "Middle",
+ "Manual",
+ "Envelope",
+ "Envelope manual",
+ "Auto",
+ "Tractor",
+ "Small format",
+ "Large format",
+ "Large capacity",
+ "Cassette",
+ "Form source",
+ 0
+};
+
+struct PaperSourceNames
+{
+ PaperSourceNames(const char *nam, QPrinter::PaperSource ps)
+ : paperSource(ps), name(nam) {}
+ QPrinter::PaperSource paperSource;
+ const char *name;
+};
+#endif
+
+
+class QPagePreview : public QWidget
+{
+public:
+ QPagePreview(QWidget *parent) : QWidget(parent)
+ {
+ setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ setMinimumSize(50, 50);
+ }
+
+ void setPaperSize(const QSizeF& size)
+ {
+ m_size = size;
+ update();
+ }
+
+ void setMargins(qreal left, qreal top, qreal right, qreal bottom)
+ {
+ m_left = left;
+ m_top = top;
+ m_right = right;
+ m_bottom = bottom;
+ update();
+ }
+
+protected:
+ void paintEvent(QPaintEvent *)
+ {
+ QRect pageRect;
+ QSizeF adjustedSize(m_size);
+ adjustedSize.scale(width()-10, height()-10, Qt::KeepAspectRatio);
+ pageRect = QRect(QPoint(0,0), adjustedSize.toSize());
+ pageRect.moveCenter(rect().center());
+
+ qreal width_factor = pageRect.width() / m_size.width();
+ qreal height_factor = pageRect.height() / m_size.height();
+ int leftSize = qRound(m_left*width_factor);
+ int topSize = qRound(m_top*height_factor);
+ int rightSize = qRound(m_right*width_factor);
+ int bottomSize = qRound(m_bottom * height_factor);
+ QRect marginRect(pageRect.x()+leftSize,
+ pageRect.y()+topSize,
+ pageRect.width() - (leftSize+rightSize+1),
+ pageRect.height() - (topSize+bottomSize+1));
+
+ QPainter p(this);
+ QColor shadow(palette().mid().color());
+ for (int i=1; i<6; ++i) {
+ shadow.setAlpha(180-i*30);
+ QRect offset(pageRect.adjusted(i, i, i, i));
+ p.setPen(shadow);
+ p.drawLine(offset.left(), offset.bottom(), offset.right(), offset.bottom());
+ p.drawLine(offset.right(), offset.top(), offset.right(), offset.bottom()-1);
+ }
+ p.fillRect(pageRect, palette().light());
+
+ if (marginRect.isValid()) {
+ p.setPen(QPen(palette().color(QPalette::Dark), 0, Qt::DotLine));
+ p.drawRect(marginRect);
+
+ marginRect.adjust(2, 2, -1, -1);
+ p.setClipRect(marginRect);
+ QFont font;
+ font.setPointSizeF(font.pointSizeF()*0.25);
+ p.setFont(font);
+ p.setPen(palette().color(QPalette::Dark));
+ QString text(QLatin1String("Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi."));
+ for (int i=0; i<3; ++i)
+ text += text;
+ p.drawText(marginRect, Qt::TextWordWrap|Qt::AlignVCenter, text);
+ }
+ }
+
+private:
+ // all these are in points
+ qreal m_left, m_top, m_right, m_bottom;
+ QSizeF m_size;
+};
+
+
+class QPageSetupDialogPrivate : public QAbstractPageSetupDialogPrivate
+{
+ Q_DECLARE_PUBLIC(QPageSetupDialog)
+
+public:
+ ~QPageSetupDialogPrivate();
+ void init();
+
+ QPageSetupWidget *widget;
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+ QCUPSSupport *cups;
+#endif
+};
+
+QPageSetupDialogPrivate::~QPageSetupDialogPrivate()
+{
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+ delete cups;
+#endif
+}
+
+void QPageSetupDialogPrivate::init()
+{
+ Q_Q(QPageSetupDialog);
+
+ widget = new QPageSetupWidget(q);
+ widget->setPrinter(printer);
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+ if (printer->outputFormat() == QPrinter::NativeFormat && QCUPSSupport::isAvailable()) {
+ cups = new QCUPSSupport;
+ widget->selectPrinter(cups);
+ } else {
+ cups = 0;
+ }
+#endif
+
+ QDialogButtonBox *buttons = new QDialogButtonBox(QDialogButtonBox::Ok
+ | QDialogButtonBox::Cancel,
+ Qt::Horizontal, q);
+ QObject::connect(buttons, SIGNAL(accepted()), q, SLOT(accept()));
+ QObject::connect(buttons, SIGNAL(rejected()), q, SLOT(reject()));
+
+ QVBoxLayout *lay = new QVBoxLayout(q);
+ lay->addWidget(widget);
+ lay->addWidget(buttons);
+}
+
+QPageSetupWidget::QPageSetupWidget(QWidget *parent)
+ : QWidget(parent),
+ m_printer(0),
+ m_blockSignals(false),
+ m_cups(0)
+{
+ widget.setupUi(this);
+
+ QString suffix = (QLocale::system().measurementSystem() == QLocale::ImperialSystem)
+ ? QString::fromLatin1(" in")
+ : QString::fromLatin1(" mm");
+ widget.topMargin->setSuffix(suffix);
+ widget.bottomMargin->setSuffix(suffix);
+ widget.leftMargin->setSuffix(suffix);
+ widget.rightMargin->setSuffix(suffix);
+ widget.paperWidth->setSuffix(suffix);
+ widget.paperHeight->setSuffix(suffix);
+
+ QVBoxLayout *lay = new QVBoxLayout(widget.preview);
+ widget.preview->setLayout(lay);
+ m_pagePreview = new QPagePreview(widget.preview);
+ lay->addWidget(m_pagePreview);
+
+ setAttribute(Qt::WA_WState_Polished, false);
+
+#ifdef PSD_ENABLE_PAPERSOURCE
+ for (int i=0; paperSourceNames[i]; ++i)
+ widget.paperSource->insertItem(paperSourceNames[i]);
+#else
+ widget.paperSourceLabel->setVisible(false);
+ widget.paperSource->setVisible(false);
+#endif
+
+ widget.reverseLandscape->setVisible(false);
+ widget.reversePortrait->setVisible(false);
+
+ populatePaperSizes(widget.paperSize);
+
+ QStringList units;
+ units << tr("Centimeters (cm)") << tr("Millimeters (mm)") << tr("Inches (in)") << tr("Points (pt)");
+ widget.unit->addItems(units);
+ connect(widget.unit, SIGNAL(activated(int)), this, SLOT(unitChanged(int)));
+ widget.unit->setCurrentIndex((QLocale::system().measurementSystem() == QLocale::ImperialSystem) ? 2 : 1);
+
+ connect(widget.paperSize, SIGNAL(currentIndexChanged(int)), this, SLOT(_q_paperSizeChanged()));
+ connect(widget.paperWidth, SIGNAL(valueChanged(double)), this, SLOT(_q_paperSizeChanged()));
+ connect(widget.paperHeight, SIGNAL(valueChanged(double)), this, SLOT(_q_paperSizeChanged()));
+
+ connect(widget.leftMargin, SIGNAL(valueChanged(double)), this, SLOT(setLeftMargin(double)));
+ connect(widget.topMargin, SIGNAL(valueChanged(double)), this, SLOT(setTopMargin(double)));
+ connect(widget.rightMargin, SIGNAL(valueChanged(double)), this, SLOT(setRightMargin(double)));
+ connect(widget.bottomMargin, SIGNAL(valueChanged(double)), this, SLOT(setBottomMargin(double)));
+
+ connect(widget.portrait, SIGNAL(clicked()), this, SLOT(_q_pageOrientationChanged()));
+ connect(widget.landscape, SIGNAL(clicked()), this, SLOT(_q_pageOrientationChanged()));
+}
+
+void QPageSetupWidget::setPrinter(QPrinter *printer)
+{
+ m_printer = printer;
+ m_blockSignals = true;
+ selectPdfPsPrinter(printer);
+ printer->getPageMargins(&m_leftMargin, &m_topMargin, &m_rightMargin, &m_bottomMargin, QPrinter::Point);
+ unitChanged(widget.unit->currentIndex());
+ m_pagePreview->setMargins(m_leftMargin, m_topMargin, m_rightMargin, m_bottomMargin);
+ m_paperSize = printer->paperSize(QPrinter::Point);
+ widget.paperWidth->setValue(m_paperSize.width() / m_currentMultiplier);
+ widget.paperHeight->setValue(m_paperSize.height() / m_currentMultiplier);
+
+ widget.landscape->setChecked(printer->orientation() == QPrinter::Landscape);
+
+#ifdef PSD_ENABLE_PAPERSOURCE
+ widget.paperSource->setCurrentItem(printer->paperSource());
+#endif
+ Q_ASSERT(m_blockSignals);
+ m_blockSignals = false;
+ _q_paperSizeChanged();
+}
+
+// set gui data on printer
+void QPageSetupWidget::setupPrinter() const
+{
+ QPrinter::Orientation orientation = widget.portrait->isChecked()
+ ? QPrinter::Portrait
+ : QPrinter::Landscape;
+ m_printer->setOrientation(orientation);
+ // paper format
+ QVariant val = widget.paperSize->itemData(widget.paperSize->currentIndex());
+ int ps = m_printer->pageSize();
+ if (val.type() == QVariant::Int) {
+ ps = val.toInt();
+ }
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+ else if (m_cups && QCUPSSupport::isAvailable() && m_cups->currentPPD()) {
+ QByteArray cupsPageSize = val.toByteArray();
+ QPrintEngine *engine = m_printer->printEngine();
+ engine->setProperty(PPK_CupsStringPageSize, QString::fromLatin1(cupsPageSize));
+ engine->setProperty(PPK_CupsOptions, m_cups->options());
+
+ QRect pageRect = m_cups->pageRect(cupsPageSize);
+ engine->setProperty(PPK_CupsPageRect, pageRect);
+
+ QRect paperRect = m_cups->paperRect(cupsPageSize);
+ engine->setProperty(PPK_CupsPaperRect, paperRect);
+
+ for(ps = 0; ps < QPrinter::NPageSize; ++ps) {
+ QPdf::PaperSize size = QPdf::paperSize(QPrinter::PaperSize(ps));
+ if (size.width == paperRect.width() && size.height == paperRect.height())
+ break;
+ }
+ }
+#endif
+ if (ps == QPrinter::Custom)
+ m_printer->setPaperSize(sizeForOrientation(orientation, m_paperSize), QPrinter::Point);
+ else
+ m_printer->setPaperSize(static_cast<QPrinter::PaperSize>(ps));
+
+#ifdef PSD_ENABLE_PAPERSOURCE
+ m_printer->setPaperSource((QPrinter::PaperSource)widget.paperSource->currentIndex());
+#endif
+ m_printer->setPageMargins(m_leftMargin, m_topMargin, m_rightMargin, m_bottomMargin, QPrinter::Point);
+
+}
+
+void QPageSetupWidget::selectPrinter(QCUPSSupport *cups)
+{
+ m_cups = cups;
+ widget.paperSize->clear();
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+ if (m_cups && QCUPSSupport::isAvailable()) {
+ const ppd_option_t* pageSizes = m_cups->pageSizes();
+ const int numChoices = pageSizes ? pageSizes->num_choices : 0;
+
+ int cupsDefaultSize = 0;
+ QSize qtPreferredSize = m_printer->paperSize(QPrinter::Point).toSize();
+ bool preferredSizeMatched = false;
+ for (int i = 0; i < numChoices; ++i) {
+ widget.paperSize->addItem(QString::fromLocal8Bit(pageSizes->choices[i].text), QByteArray(pageSizes->choices[i].choice));
+ if (static_cast<int>(pageSizes->choices[i].marked) == 1)
+ cupsDefaultSize = i;
+ if (m_printer->d_func()->hasUserSetPageSize) {
+ QRect cupsPaperSize = m_cups->paperRect(pageSizes->choices[i].choice);
+ QSize diff = cupsPaperSize.size() - qtPreferredSize;
+ if (qAbs(diff.width()) < 5 && qAbs(diff.height()) < 5) {
+ widget.paperSize->setCurrentIndex(i);
+ preferredSizeMatched = true;
+ }
+ }
+ }
+ if (!preferredSizeMatched)
+ widget.paperSize->setCurrentIndex(cupsDefaultSize);
+ if (m_printer->d_func()->hasCustomPageMargins) {
+ m_printer->getPageMargins(&m_leftMargin, &m_topMargin, &m_rightMargin, &m_bottomMargin, QPrinter::Point);
+ } else {
+ QByteArray cupsPaperSizeChoice = widget.paperSize->itemData(widget.paperSize->currentIndex()).toByteArray();
+ QRect paper = m_cups->paperRect(cupsPaperSizeChoice);
+ QRect content = m_cups->pageRect(cupsPaperSizeChoice);
+
+ m_leftMargin = content.x() - paper.x();
+ m_topMargin = content.y() - paper.y();
+ m_rightMargin = paper.right() - content.right();
+ m_bottomMargin = paper.bottom() - content.bottom();
+ }
+ }
+#endif
+ if (widget.paperSize->count() == 0) {
+ populatePaperSizes(widget.paperSize);
+ widget.paperSize->setCurrentIndex(widget.paperSize->findData(
+ QLocale::system().measurementSystem() == QLocale::ImperialSystem ? QPrinter::Letter : QPrinter::A4));
+ }
+
+ unitChanged(widget.unit->currentIndex());
+ m_pagePreview->setMargins(m_leftMargin, m_topMargin, m_rightMargin, m_bottomMargin);
+}
+
+void QPageSetupWidget::selectPdfPsPrinter(const QPrinter *p)
+{
+ m_cups = 0;
+ widget.paperSize->clear();
+ populatePaperSizes(widget.paperSize);
+ widget.paperSize->setCurrentIndex(widget.paperSize->findData(p->paperSize()));
+
+ m_leftMargin = 90;
+ m_topMargin = 72;
+ m_bottomMargin = 72;
+ m_rightMargin = 90;
+ unitChanged(widget.unit->currentIndex());
+ m_pagePreview->setMargins(m_leftMargin, m_topMargin, m_rightMargin, m_bottomMargin);
+}
+
+// Updates size/preview after the combobox has been changed.
+void QPageSetupWidget::_q_paperSizeChanged()
+{
+ QVariant val = widget.paperSize->itemData(widget.paperSize->currentIndex());
+ int index = m_printer->pageSize();
+ if (val.type() == QVariant::Int) {
+ index = val.toInt();
+ }
+
+ if (m_blockSignals) return;
+ m_blockSignals = true;
+
+ QPrinter::PaperSize size = QPrinter::PaperSize(index);
+ QPrinter::Orientation orientation = widget.portrait->isChecked()
+ ? QPrinter::Portrait
+ : QPrinter::Landscape;
+
+ bool custom = size == QPrinter::Custom;
+
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+ custom = custom ? !m_cups : custom;
+#endif
+
+ widget.paperWidth->setEnabled(custom);
+ widget.paperHeight->setEnabled(custom);
+ widget.widthLabel->setEnabled(custom);
+ widget.heightLabel->setEnabled(custom);
+ if (custom) {
+ m_paperSize.setWidth( widget.paperWidth->value() * m_currentMultiplier);
+ m_paperSize.setHeight( widget.paperHeight->value() * m_currentMultiplier);
+ m_pagePreview->setPaperSize(m_paperSize);
+ } else {
+ Q_ASSERT(m_printer);
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+ if (m_cups) { // combobox is filled with cups based data
+ QByteArray cupsPageSize = widget.paperSize->itemData(widget.paperSize->currentIndex()).toByteArray();
+ m_paperSize = m_cups->paperRect(cupsPageSize).size();
+ if (orientation == QPrinter::Landscape)
+ m_paperSize = QSizeF(m_paperSize.height(), m_paperSize.width()); // swap
+ }
+ else
+#endif
+ m_paperSize = qt_printerPaperSize(orientation, size, QPrinter::Point, 1);
+
+ m_pagePreview->setPaperSize(m_paperSize);
+ widget.paperWidth->setValue(m_paperSize.width() / m_currentMultiplier);
+ widget.paperHeight->setValue(m_paperSize.height() / m_currentMultiplier);
+ }
+ m_blockSignals = false;
+}
+
+void QPageSetupWidget::_q_pageOrientationChanged()
+{
+ if (QPrinter::PaperSize(widget.paperSize->currentIndex()) == QPrinter::Custom) {
+ double tmp = widget.paperWidth->value();
+ widget.paperWidth->setValue(widget.paperHeight->value());
+ widget.paperHeight->setValue(tmp);
+ }
+ _q_paperSizeChanged();
+}
+
+extern double qt_multiplierForUnit(QPrinter::Unit unit, int resolution);
+
+void QPageSetupWidget::unitChanged(int item)
+{
+ QString suffix;
+ switch(item) {
+ case 0:
+ m_currentMultiplier = 10 * qt_multiplierForUnit(QPrinter::Millimeter, 1);
+ suffix = QString::fromLatin1(" cm");
+ break;
+ case 2:
+ m_currentMultiplier = qt_multiplierForUnit(QPrinter::Inch, 1);
+ suffix = QString::fromLatin1(" in");
+ break;
+ case 3:
+ m_currentMultiplier = qt_multiplierForUnit(QPrinter::Point, 1);
+ suffix = QString::fromLatin1(" pt");
+ break;
+ case 1:
+ default:
+ m_currentMultiplier = qt_multiplierForUnit(QPrinter::Millimeter, 1);
+ suffix = QString::fromLatin1(" mm");
+ break;
+ }
+ const bool old = m_blockSignals;
+ m_blockSignals = true;
+ widget.topMargin->setSuffix(suffix);
+ widget.leftMargin->setSuffix(suffix);
+ widget.rightMargin->setSuffix(suffix);
+ widget.bottomMargin->setSuffix(suffix);
+ widget.paperWidth->setSuffix(suffix);
+ widget.paperHeight->setSuffix(suffix);
+ widget.topMargin->setValue(m_topMargin / m_currentMultiplier);
+ widget.leftMargin->setValue(m_leftMargin / m_currentMultiplier);
+ widget.rightMargin->setValue(m_rightMargin / m_currentMultiplier);
+ widget.bottomMargin->setValue(m_bottomMargin / m_currentMultiplier);
+ widget.paperWidth->setValue(m_paperSize.width() / m_currentMultiplier);
+ widget.paperHeight->setValue(m_paperSize.height() / m_currentMultiplier);
+ m_blockSignals = old;
+}
+
+void QPageSetupWidget::setTopMargin(double newValue)
+{
+ if (m_blockSignals) return;
+ m_topMargin = newValue * m_currentMultiplier;
+ m_pagePreview->setMargins(m_leftMargin, m_topMargin, m_rightMargin, m_bottomMargin);
+}
+
+void QPageSetupWidget::setBottomMargin(double newValue)
+{
+ if (m_blockSignals) return;
+ m_bottomMargin = newValue * m_currentMultiplier;
+ m_pagePreview->setMargins(m_leftMargin, m_topMargin, m_rightMargin, m_bottomMargin);
+}
+
+void QPageSetupWidget::setLeftMargin(double newValue)
+{
+ if (m_blockSignals) return;
+ m_leftMargin = newValue * m_currentMultiplier;
+ m_pagePreview->setMargins(m_leftMargin, m_topMargin, m_rightMargin, m_bottomMargin);
+}
+
+void QPageSetupWidget::setRightMargin(double newValue)
+{
+ if (m_blockSignals) return;
+ m_rightMargin = newValue * m_currentMultiplier;
+ m_pagePreview->setMargins(m_leftMargin, m_topMargin, m_rightMargin, m_bottomMargin);
+}
+
+
+
+QPageSetupDialog::QPageSetupDialog(QPrinter *printer, QWidget *parent)
+ : QAbstractPageSetupDialog(*(new QPageSetupDialogPrivate), printer, parent)
+{
+ Q_D(QPageSetupDialog);
+ d->init();
+}
+
+
+QPageSetupDialog::QPageSetupDialog(QWidget *parent)
+ : QAbstractPageSetupDialog(*(new QPageSetupDialogPrivate), 0, parent)
+{
+ Q_D(QPageSetupDialog);
+ d->init();
+}
+
+/*!
+ \internal
+*/
+int QPageSetupDialog::exec()
+{
+ Q_D(QPageSetupDialog);
+
+ int ret = QDialog::exec();
+ if (ret == Accepted)
+ d->widget->setupPrinter();
+ return ret;
+}
+
+
+QT_END_NAMESPACE
+
+#include "moc_qpagesetupdialog.cpp"
+
+#endif // QT_NO_PRINTDIALOG
diff --git a/src/gui/dialogs/qpagesetupdialog_unix_p.h b/src/printsupport/dialogs/qpagesetupdialog_unix_p.h
index 2303db9fe8..2303db9fe8 100644
--- a/src/gui/dialogs/qpagesetupdialog_unix_p.h
+++ b/src/printsupport/dialogs/qpagesetupdialog_unix_p.h
diff --git a/src/gui/dialogs/qpagesetupdialog_win.cpp b/src/printsupport/dialogs/qpagesetupdialog_win.cpp
index 2e7cf860fc..2e7cf860fc 100644
--- a/src/gui/dialogs/qpagesetupdialog_win.cpp
+++ b/src/printsupport/dialogs/qpagesetupdialog_win.cpp
diff --git a/src/gui/dialogs/qpagesetupwidget.ui b/src/printsupport/dialogs/qpagesetupwidget.ui
index ace2ab8f44..ace2ab8f44 100644
--- a/src/gui/dialogs/qpagesetupwidget.ui
+++ b/src/printsupport/dialogs/qpagesetupwidget.ui
diff --git a/src/printsupport/dialogs/qprintdialog.h b/src/printsupport/dialogs/qprintdialog.h
new file mode 100644
index 0000000000..1b04263261
--- /dev/null
+++ b/src/printsupport/dialogs/qprintdialog.h
@@ -0,0 +1,174 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPRINTDIALOG_H
+#define QPRINTDIALOG_H
+
+#include <QtPrintSupport/qabstractprintdialog.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_PRINTDIALOG
+
+class QPrintDialogPrivate;
+class QPushButton;
+class QPrinter;
+
+#if defined (Q_OS_UNIX) && !defined(QTOPIA_PRINTDIALOG) && !defined(Q_WS_MAC) && !defined(Q_OS_SYMBIAN)
+class QUnixPrintWidgetPrivate;
+
+class Q_PRINTSUPPORT_EXPORT QUnixPrintWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ QUnixPrintWidget(QPrinter *printer, QWidget *parent = 0);
+ ~QUnixPrintWidget();
+ void updatePrinter();
+
+private:
+ friend class QPrintDialogPrivate;
+ friend class QUnixPrintWidgetPrivate;
+ QUnixPrintWidgetPrivate *d;
+ Q_PRIVATE_SLOT(d, void _q_printerChanged(int))
+ Q_PRIVATE_SLOT(d, void _q_btnBrowseClicked())
+ Q_PRIVATE_SLOT(d, void _q_btnPropertiesClicked())
+};
+#endif
+
+class Q_PRINTSUPPORT_EXPORT QPrintDialog : public QAbstractPrintDialog
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QPrintDialog)
+ Q_ENUMS(PrintDialogOption)
+ Q_PROPERTY(PrintDialogOptions options READ options WRITE setOptions)
+
+public:
+ explicit QPrintDialog(QPrinter *printer, QWidget *parent = 0);
+ explicit QPrintDialog(QWidget *parent = 0);
+ ~QPrintDialog();
+
+ int exec();
+#if defined (Q_OS_UNIX) && !defined(QTOPIA_PRINTDIALOG) && !defined(Q_WS_MAC)
+ virtual void accept();
+#endif
+ void done(int result);
+
+#if defined (Q_OS_UNIX) && defined (QT3_SUPPORT)
+ QT3_SUPPORT void setPrinter(QPrinter *, bool = false);
+ QT3_SUPPORT QPrinter *printer() const;
+ QT3_SUPPORT void addButton(QPushButton *button);
+#endif
+
+ void setOption(PrintDialogOption option, bool on = true);
+ bool testOption(PrintDialogOption option) const;
+ void setOptions(PrintDialogOptions options);
+ PrintDialogOptions options() const;
+
+#if defined(Q_OS_UNIX) || defined(Q_WS_MAC) || defined(Q_OS_WIN)
+ void setVisible(bool visible);
+#endif
+
+#ifdef Q_NO_USING_KEYWORD
+#ifndef Q_QDOC
+ void open() { QDialog::open(); }
+#endif
+#else
+ using QDialog::open;
+#endif
+ void open(QObject *receiver, const char *member);
+
+#ifdef qdoc
+ QPrinter *printer();
+#endif
+
+#ifdef QTOPIA_PRINTDIALOG
+public:
+ bool eventFilter(QObject *, QEvent *);
+#endif
+
+#ifdef Q_NO_USING_KEYWORD
+#ifndef Q_QDOC
+ void accepted() { QDialog::accepted(); }
+#endif
+#else
+ using QDialog::accepted;
+#endif
+
+Q_SIGNALS:
+ void accepted(QPrinter *printer);
+
+private:
+#ifndef QTOPIA_PRINTDIALOG
+ Q_PRIVATE_SLOT(d_func(), void _q_chbPrintLastFirstToggled(bool))
+#if defined (Q_OS_UNIX) && !defined (Q_OS_MAC)
+ Q_PRIVATE_SLOT(d_func(), void _q_collapseOrExpandDialog())
+#endif
+# if defined(Q_OS_UNIX) && !defined (Q_OS_MAC) && !defined(QT_NO_MESSAGEBOX)
+ Q_PRIVATE_SLOT(d_func(), void _q_checkFields())
+# endif
+#else // QTOPIA_PRINTDIALOG
+ Q_PRIVATE_SLOT(d_func(), void _q_okClicked())
+ Q_PRIVATE_SLOT(d_func(),void _q_printerOrFileSelected(QAbstractButton *b))
+ Q_PRIVATE_SLOT(d_func(),void _q_paperSizeSelected(int))
+ Q_PRIVATE_SLOT(d_func(), void _q_orientSelected(int))
+ Q_PRIVATE_SLOT(d_func(), void _q_pageOrderSelected(int))
+ Q_PRIVATE_SLOT(d_func(), void _q_colorModeSelected(QAbstractButton *))
+ Q_PRIVATE_SLOT(d_func(), void _q_setNumCopies(int))
+ Q_PRIVATE_SLOT(d_func(), void _q_printRangeSelected(int))
+ Q_PRIVATE_SLOT(d_func(), void _q_setFirstPage(int))
+ Q_PRIVATE_SLOT(d_func(), void _q_setLastPage(int))
+ Q_PRIVATE_SLOT(d_func(), void _q_fileNameEditChanged(const QString &text))
+#endif // QTOPIA_PRINTDIALOG
+ friend class QUnixPrintWidget;
+};
+
+#endif // QT_NO_PRINTDIALOG
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QPRINTDIALOG_H
diff --git a/src/gui/dialogs/qprintdialog.qdoc b/src/printsupport/dialogs/qprintdialog.qdoc
index 53bbc9b490..53bbc9b490 100644
--- a/src/gui/dialogs/qprintdialog.qdoc
+++ b/src/printsupport/dialogs/qprintdialog.qdoc
diff --git a/src/gui/dialogs/qprintdialog.qrc b/src/printsupport/dialogs/qprintdialog.qrc
index f54eb6b5ee..f54eb6b5ee 100644
--- a/src/gui/dialogs/qprintdialog.qrc
+++ b/src/printsupport/dialogs/qprintdialog.qrc
diff --git a/src/gui/dialogs/qprintdialog_mac.mm b/src/printsupport/dialogs/qprintdialog_mac.mm
index 2e902e61ce..2e902e61ce 100644
--- a/src/gui/dialogs/qprintdialog_mac.mm
+++ b/src/printsupport/dialogs/qprintdialog_mac.mm
diff --git a/src/printsupport/dialogs/qprintdialog_unix.cpp b/src/printsupport/dialogs/qprintdialog_unix.cpp
new file mode 100644
index 0000000000..57baf76704
--- /dev/null
+++ b/src/printsupport/dialogs/qprintdialog_unix.cpp
@@ -0,0 +1,1288 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qplatformdefs.h"
+
+#ifndef QT_NO_PRINTDIALOG
+
+#include "private/qabstractprintdialog_p.h"
+#include <QtWidgets/qmessagebox.h>
+#include "qprintdialog.h"
+#include "qfiledialog.h"
+#include <QtCore/qdir.h>
+#include <QtGui/qevent.h>
+#include <QtWidgets/qfilesystemmodel.h>
+#include <QtWidgets/qstyleditemdelegate.h>
+#include <QtPrintSupport/qprinter.h>
+
+#include <QtWidgets/qdialogbuttonbox.h>
+
+#include "private/qfscompleter_p.h"
+#include "ui_qprintpropertieswidget.h"
+#include "ui_qprintsettingsoutput.h"
+#include "ui_qprintwidget.h"
+
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+# include <private/qcups_p.h>
+# include <cups/cups.h>
+# include <private/qprintengine_pdf_p.h>
+#else
+# include <QtCore/qlibrary.h>
+#endif
+
+#include <private/qprinterinfo_unix_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QOptionTreeItem;
+class QPPDOptionsModel;
+
+class QPrintPropertiesDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ QPrintPropertiesDialog(QAbstractPrintDialog *parent = 0);
+ ~QPrintPropertiesDialog();
+
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+ void setCups(QCUPSSupport *cups) { m_cups = cups; }
+ void addItemToOptions(QOptionTreeItem *parent, QList<const ppd_option_t*>& options, QList<const char*>& markedOptions) const;
+#endif
+
+ void selectPrinter();
+ void selectPdfPsPrinter(const QPrinter *p);
+
+ /// copy printer properties to the widget
+ void applyPrinterProperties(QPrinter *p);
+ void setupPrinter() const;
+
+protected:
+ void showEvent(QShowEvent* event);
+
+private:
+ Ui::QPrintPropertiesWidget widget;
+ QDialogButtonBox *m_buttons;
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+ QCUPSSupport *m_cups;
+ QPPDOptionsModel *m_cupsOptionsModel;
+#endif
+};
+
+class QPrintDialogPrivate : public QAbstractPrintDialogPrivate
+{
+ Q_DECLARE_PUBLIC(QPrintDialog)
+ Q_DECLARE_TR_FUNCTIONS(QPrintDialog)
+public:
+ QPrintDialogPrivate();
+ ~QPrintDialogPrivate();
+
+ void init();
+ /// copy printer properties to the widget
+ void applyPrinterProperties(QPrinter *p);
+
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+ void selectPrinter(QCUPSSupport *cups);
+#endif
+
+ void _q_chbPrintLastFirstToggled(bool);
+#ifndef QT_NO_MESSAGEBOX
+ void _q_checkFields();
+#endif
+ void _q_collapseOrExpandDialog();
+
+ void setupPrinter();
+ void updateWidgets();
+
+ virtual void setTabs(const QList<QWidget*> &tabs);
+
+ Ui::QPrintSettingsOutput options;
+ QUnixPrintWidget *top;
+ QWidget *bottom;
+ QDialogButtonBox *buttons;
+ QPushButton *collapseButton;
+};
+
+#if defined (Q_OS_UNIX)
+class QUnixPrintWidgetPrivate
+{
+public:
+ QUnixPrintWidgetPrivate(QUnixPrintWidget *q);
+ ~QUnixPrintWidgetPrivate();
+
+ /// copy printer properties to the widget
+ void applyPrinterProperties(QPrinter *p);
+ bool checkFields();
+ void setupPrinter();
+ void setOptionsPane(QPrintDialogPrivate *pane);
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+ void setCupsProperties();
+#endif
+
+// slots
+ void _q_printerChanged(int index);
+ void _q_btnPropertiesClicked();
+ void _q_btnBrowseClicked();
+
+ QUnixPrintWidget * const parent;
+ QPrintPropertiesDialog *propertiesDialog;
+ Ui::QPrintWidget widget;
+ QAbstractPrintDialog * q;
+ QPrinter *printer;
+ QList<QPrinterDescription> lprPrinters;
+ void updateWidget();
+
+private:
+ QPrintDialogPrivate *optionsPane;
+ bool filePrintersAdded;
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+ QCUPSSupport* cups;
+ int cupsPrinterCount;
+ const cups_dest_t* cupsPrinters;
+ const ppd_file_t* cupsPPD;
+#endif
+};
+#endif
+
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+class QOptionTreeItem
+{
+public:
+ enum ItemType { Root, Group, Option, Choice };
+
+ QOptionTreeItem(ItemType t, int i, const void* p, const char* desc, QOptionTreeItem* pi)
+ : type(t),
+ index(i),
+ ptr(p),
+ description(desc),
+ selected(-1),
+ selDescription(0),
+ parentItem(pi) {}
+
+ ~QOptionTreeItem() {
+ while (!childItems.isEmpty())
+ delete childItems.takeFirst();
+ }
+
+ ItemType type;
+ int index;
+ const void* ptr;
+ const char* description;
+ int selected;
+ const char* selDescription;
+ QOptionTreeItem* parentItem;
+ QList<QOptionTreeItem*> childItems;
+};
+
+class QPPDOptionsModel : public QAbstractItemModel
+{
+ friend class QPPDOptionsEditor;
+public:
+ QPPDOptionsModel(QCUPSSupport *cups, QObject *parent = 0);
+ ~QPPDOptionsModel();
+
+ int columnCount(const QModelIndex& parent = QModelIndex()) const;
+ int rowCount(const QModelIndex& parent = QModelIndex()) const;
+ QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
+ QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const;
+ QModelIndex parent(const QModelIndex& index) const;
+ Qt::ItemFlags flags(const QModelIndex& index) const;
+ QVariant headerData ( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const;
+
+ QOptionTreeItem* rootItem;
+ QCUPSSupport *cups;
+ const ppd_file_t* ppd;
+ void parseItems();
+ void parseGroups(QOptionTreeItem* parent);
+ void parseOptions(QOptionTreeItem* parent);
+ void parseChoices(QOptionTreeItem* parent);
+};
+
+class QPPDOptionsEditor : public QStyledItemDelegate
+{
+ Q_OBJECT
+public:
+ QPPDOptionsEditor(QObject* parent = 0) : QStyledItemDelegate(parent) {}
+ ~QPPDOptionsEditor() {}
+
+ QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const;
+ void setEditorData(QWidget* editor, const QModelIndex& index) const;
+ void setModelData( QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const;
+
+private slots:
+ void cbChanged(int index);
+
+};
+
+#endif
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+QPrintPropertiesDialog::QPrintPropertiesDialog(QAbstractPrintDialog *parent)
+ : QDialog(parent)
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+ , m_cups(0), m_cupsOptionsModel(0)
+#endif
+{
+ QVBoxLayout *lay = new QVBoxLayout(this);
+ this->setLayout(lay);
+ QWidget *content = new QWidget(this);
+ widget.setupUi(content);
+ m_buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, this);
+ lay->addWidget(content);
+ lay->addWidget(m_buttons);
+
+ connect(m_buttons->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(accept()));
+ connect(m_buttons->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), this, SLOT(reject()));
+}
+
+QPrintPropertiesDialog::~QPrintPropertiesDialog()
+{
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+ delete m_cupsOptionsModel;
+#else
+ delete widget.cupsPropertiesPage;
+#endif
+}
+
+void QPrintPropertiesDialog::applyPrinterProperties(QPrinter *p)
+{
+ widget.pageSetup->setPrinter(p);
+}
+
+void QPrintPropertiesDialog::setupPrinter() const
+{
+ widget.pageSetup->setupPrinter();
+
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+ QPPDOptionsModel* model = static_cast<QPPDOptionsModel*>(widget.treeView->model());
+ if (model) {
+ QOptionTreeItem* rootItem = model->rootItem;
+ QList<const ppd_option_t*> options;
+ QList<const char*> markedOptions;
+
+ addItemToOptions(rootItem, options, markedOptions);
+ model->cups->saveOptions(options, markedOptions);
+ }
+#endif
+}
+
+void QPrintPropertiesDialog::selectPrinter()
+{
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+ widget.pageSetup->selectPrinter(m_cups);
+ widget.treeView->setModel(0);
+ if (m_cups && QCUPSSupport::isAvailable()) {
+
+ if (m_cupsOptionsModel == 0) {
+ m_cupsOptionsModel = new QPPDOptionsModel(m_cups);
+
+ widget.treeView->setItemDelegate(new QPPDOptionsEditor(this));
+ } else {
+ // update the model
+ m_cupsOptionsModel->parseItems();
+ }
+
+ if (m_cupsOptionsModel->rowCount() > 0) {
+ widget.treeView->setModel(m_cupsOptionsModel);
+
+ for (int i = 0; i < m_cupsOptionsModel->rowCount(); ++i)
+ widget.treeView->expand(m_cupsOptionsModel->index(i,0));
+
+ widget.tabs->setTabEnabled(1, true); // enable the advanced tab
+ } else {
+ widget.tabs->setTabEnabled(1, false);
+ }
+
+ } else
+#endif
+ {
+ widget.cupsPropertiesPage->setEnabled(false);
+ widget.pageSetup->selectPrinter(0);
+ }
+}
+
+void QPrintPropertiesDialog::selectPdfPsPrinter(const QPrinter *p)
+{
+ widget.treeView->setModel(0);
+ widget.pageSetup->selectPdfPsPrinter(p);
+ widget.tabs->setTabEnabled(1, false); // disable the advanced tab
+}
+
+void QPrintPropertiesDialog::showEvent(QShowEvent* event)
+{
+ widget.treeView->resizeColumnToContents(0);
+ event->accept();
+}
+
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+void QPrintPropertiesDialog::addItemToOptions(QOptionTreeItem *parent, QList<const ppd_option_t*>& options, QList<const char*>& markedOptions) const
+{
+ for (int i = 0; i < parent->childItems.count(); ++i) {
+ QOptionTreeItem *itm = parent->childItems.at(i);
+ if (itm->type == QOptionTreeItem::Option) {
+ const ppd_option_t* opt = reinterpret_cast<const ppd_option_t*>(itm->ptr);
+ options << opt;
+ if (qstrcmp(opt->defchoice, opt->choices[itm->selected].choice) != 0) {
+ markedOptions << opt->keyword << opt->choices[itm->selected].choice;
+ }
+ } else {
+ addItemToOptions(itm, options, markedOptions);
+ }
+ }
+}
+#endif
+
+QPrintDialogPrivate::QPrintDialogPrivate()
+ : top(0), bottom(0), buttons(0), collapseButton(0)
+{
+}
+
+QPrintDialogPrivate::~QPrintDialogPrivate()
+{
+}
+
+void QPrintDialogPrivate::init()
+{
+ Q_Q(QPrintDialog);
+
+ top = new QUnixPrintWidget(0, q);
+ bottom = new QWidget(q);
+ options.setupUi(bottom);
+ options.color->setIconSize(QSize(32, 32));
+ options.color->setIcon(QIcon(QLatin1String(":/trolltech/dialogs/qprintdialog/images/status-color.png")));
+ options.grayscale->setIconSize(QSize(32, 32));
+ options.grayscale->setIcon(QIcon(QLatin1String(":/trolltech/dialogs/qprintdialog/images/status-gray-scale.png")));
+ top->d->setOptionsPane(this);
+
+ buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, q);
+ collapseButton = new QPushButton(QPrintDialog::tr("&Options >>"), buttons);
+ buttons->addButton(collapseButton, QDialogButtonBox::ResetRole);
+ bottom->setVisible(false);
+
+ QPushButton *printButton = buttons->button(QDialogButtonBox::Ok);
+ printButton->setText(QPrintDialog::tr("&Print"));
+ printButton->setDefault(true);
+
+ QVBoxLayout *lay = new QVBoxLayout(q);
+ q->setLayout(lay);
+ lay->addWidget(top);
+ lay->addWidget(bottom);
+ lay->addWidget(buttons);
+
+ QPrinter* p = q->printer();
+
+ applyPrinterProperties(p);
+
+#ifdef QT_NO_MESSAGEBOX
+ QObject::connect(buttons, SIGNAL(accepted()), q, SLOT(accept()));
+#else
+ QObject::connect(buttons, SIGNAL(accepted()), q, SLOT(_q_checkFields()));
+#endif
+ QObject::connect(buttons, SIGNAL(rejected()), q, SLOT(reject()));
+
+ QObject::connect(options.reverse, SIGNAL(toggled(bool)),
+ q, SLOT(_q_chbPrintLastFirstToggled(bool)));
+
+ QObject::connect(collapseButton, SIGNAL(released()), q, SLOT(_q_collapseOrExpandDialog()));
+}
+
+void QPrintDialogPrivate::applyPrinterProperties(QPrinter *p)
+{
+ if (p->colorMode() == QPrinter::Color)
+ options.color->setChecked(true);
+ else
+ options.grayscale->setChecked(true);
+
+ switch(p->duplex()) {
+ case QPrinter::DuplexNone:
+ options.noDuplex->setChecked(true); break;
+ case QPrinter::DuplexLongSide:
+ case QPrinter::DuplexAuto:
+ options.duplexLong->setChecked(true); break;
+ case QPrinter::DuplexShortSide:
+ options.duplexShort->setChecked(true); break;
+ }
+ options.copies->setValue(p->copyCount());
+ options.collate->setChecked(p->collateCopies());
+ options.reverse->setChecked(p->pageOrder() == QPrinter::LastPageFirst);
+ top->d->applyPrinterProperties(p);
+}
+
+void QPrintDialogPrivate::_q_chbPrintLastFirstToggled(bool checked)
+{
+ Q_Q(QPrintDialog);
+ if (checked)
+ q->printer()->setPageOrder(QPrinter::LastPageFirst);
+ else
+ q->printer()->setPageOrder(QPrinter::FirstPageFirst);
+}
+
+void QPrintDialogPrivate::_q_collapseOrExpandDialog()
+{
+ int collapseHeight = 0;
+ Q_Q(QPrintDialog);
+ QWidget *widgetToHide = bottom;
+ if (widgetToHide->isVisible()) {
+ collapseButton->setText(QPrintDialog::tr("&Options >>"));
+ collapseHeight = widgetToHide->y() + widgetToHide->height() - (top->y() + top->height());
+ }
+ else
+ collapseButton->setText(QPrintDialog::tr("&Options <<"));
+ widgetToHide->setVisible(! widgetToHide->isVisible());
+ if (! widgetToHide->isVisible()) { // make it shrink
+ q->layout()->activate();
+ q->resize( QSize(q->width(), q->height() - collapseHeight) );
+ }
+}
+
+#ifndef QT_NO_MESSAGEBOX
+void QPrintDialogPrivate::_q_checkFields()
+{
+ Q_Q(QPrintDialog);
+ if (top->d->checkFields())
+ q->accept();
+}
+#endif // QT_NO_MESSAGEBOX
+
+void QPrintDialogPrivate::setupPrinter()
+{
+ Q_Q(QPrintDialog);
+ QPrinter* p = q->printer();
+
+ if (options.duplex->isEnabled()) {
+ if (options.noDuplex->isChecked())
+ p->setDuplex(QPrinter::DuplexNone);
+ else if (options.duplexLong->isChecked())
+ p->setDuplex(QPrinter::DuplexLongSide);
+ else
+ p->setDuplex(QPrinter::DuplexShortSide);
+ }
+
+ p->setColorMode( options.color->isChecked() ? QPrinter::Color : QPrinter::GrayScale );
+
+ // print range
+ if (options.printAll->isChecked()) {
+ p->setPrintRange(QPrinter::AllPages);
+ p->setFromTo(0,0);
+ } else if (options.printSelection->isChecked()) {
+ p->setPrintRange(QPrinter::Selection);
+ p->setFromTo(0,0);
+ } else if (options.printCurrentPage->isChecked()) {
+ p->setPrintRange(QPrinter::CurrentPage);
+ p->setFromTo(0,0);
+ } else if (options.printRange->isChecked()) {
+ p->setPrintRange(QPrinter::PageRange);
+ p->setFromTo(options.from->value(), qMax(options.from->value(), options.to->value()));
+ }
+
+ // copies
+ p->setCopyCount(options.copies->value());
+ p->setCollateCopies(options.collate->isChecked());
+
+ top->d->setupPrinter();
+}
+
+void QPrintDialogPrivate::updateWidgets()
+{
+ Q_Q(QPrintDialog);
+ options.gbPrintRange->setVisible(q->isOptionEnabled(QPrintDialog::PrintPageRange) ||
+ q->isOptionEnabled(QPrintDialog::PrintSelection) ||
+ q->isOptionEnabled(QPrintDialog::PrintCurrentPage));
+
+ options.printRange->setEnabled(q->isOptionEnabled(QPrintDialog::PrintPageRange));
+ options.printSelection->setVisible(q->isOptionEnabled(QPrintDialog::PrintSelection));
+ options.printCurrentPage->setVisible(q->isOptionEnabled(QPrintDialog::PrintCurrentPage));
+ options.collate->setVisible(q->isOptionEnabled(QPrintDialog::PrintCollateCopies));
+
+ switch (q->printRange()) {
+ case QPrintDialog::AllPages:
+ options.printAll->setChecked(true);
+ break;
+ case QPrintDialog::Selection:
+ options.printSelection->setChecked(true);
+ break;
+ case QPrintDialog::PageRange:
+ options.printRange->setChecked(true);
+ break;
+ case QPrintDialog::CurrentPage:
+ if (q->isOptionEnabled(QPrintDialog::PrintCurrentPage))
+ options.printCurrentPage->setChecked(true);
+ break;
+ default:
+ break;
+ }
+ const int minPage = qMax(1, qMin(q->minPage() , q->maxPage()));
+ const int maxPage = qMax(1, q->maxPage() == INT_MAX ? 9999 : q->maxPage());
+
+ options.from->setMinimum(minPage);
+ options.to->setMinimum(minPage);
+ options.from->setMaximum(maxPage);
+ options.to->setMaximum(maxPage);
+
+ options.from->setValue(q->fromPage());
+ options.to->setValue(q->toPage());
+ top->d->updateWidget();
+}
+
+void QPrintDialogPrivate::setTabs(const QList<QWidget*> &tabWidgets)
+{
+ while(options.tabs->count() > 2)
+ delete options.tabs->widget(2);
+
+ QList<QWidget*>::ConstIterator iter = tabWidgets.begin();
+ while(iter != tabWidgets.constEnd()) {
+ QWidget *tab = *iter;
+ options.tabs->addTab(tab, tab->windowTitle());
+ ++iter;
+ }
+}
+
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+void QPrintDialogPrivate::selectPrinter(QCUPSSupport *cups)
+{
+ options.duplex->setEnabled(cups && cups->ppdOption("Duplex"));
+}
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+
+QPrintDialog::QPrintDialog(QPrinter *printer, QWidget *parent)
+ : QAbstractPrintDialog(*(new QPrintDialogPrivate), printer, parent)
+{
+ Q_D(QPrintDialog);
+ d->init();
+}
+
+/*!
+ Constructs a print dialog with the given \a parent.
+*/
+QPrintDialog::QPrintDialog(QWidget *parent)
+ : QAbstractPrintDialog(*(new QPrintDialogPrivate), 0, parent)
+{
+ Q_D(QPrintDialog);
+ d->init();
+}
+
+QPrintDialog::~QPrintDialog()
+{
+}
+
+void QPrintDialog::setVisible(bool visible)
+{
+ Q_D(QPrintDialog);
+
+ if (visible)
+ d->updateWidgets();
+
+ QAbstractPrintDialog::setVisible(visible);
+}
+
+int QPrintDialog::exec()
+{
+ return QDialog::exec();
+}
+
+void QPrintDialog::accept()
+{
+ Q_D(QPrintDialog);
+ d->setupPrinter();
+ QDialog::accept();
+}
+
+#ifdef QT3_SUPPORT
+QPrinter *QPrintDialog::printer() const
+{
+ Q_D(const QPrintDialog);
+ return d->printer;
+}
+
+void QPrintDialog::setPrinter(QPrinter *printer, bool pickupSettings)
+{
+ if (!printer)
+ return;
+
+ Q_D(QPrintDialog);
+ d->printer = printer;
+
+ if (pickupSettings)
+ d->applyPrinterProperties(printer);
+}
+
+void QPrintDialog::addButton(QPushButton *button)
+{
+ Q_D(QPrintDialog);
+ d->buttons->addButton(button, QDialogButtonBox::HelpRole);
+}
+#endif // QT3_SUPPORT
+
+#if defined (Q_OS_UNIX)
+
+/*! \internal
+*/
+QUnixPrintWidgetPrivate::QUnixPrintWidgetPrivate(QUnixPrintWidget *p)
+ : parent(p), propertiesDialog(0), printer(0), optionsPane(0), filePrintersAdded(false)
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+ , cups(0), cupsPrinterCount(0), cupsPrinters(0), cupsPPD(0)
+#endif
+{
+ q = 0;
+ if (parent)
+ q = qobject_cast<QAbstractPrintDialog*> (parent->parent());
+
+ widget.setupUi(parent);
+
+ int currentPrinterIndex = 0;
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+ cups = new QCUPSSupport;
+ if (QCUPSSupport::isAvailable()) {
+ cupsPPD = cups->currentPPD();
+ cupsPrinterCount = cups->availablePrintersCount();
+ cupsPrinters = cups->availablePrinters();
+
+ for (int i = 0; i < cupsPrinterCount; ++i) {
+ QString printerName(QString::fromLocal8Bit(cupsPrinters[i].name));
+ if (cupsPrinters[i].instance)
+ printerName += QLatin1Char('/') + QString::fromLocal8Bit(cupsPrinters[i].instance);
+
+ widget.printers->addItem(printerName);
+ if (cupsPrinters[i].is_default)
+ widget.printers->setCurrentIndex(i);
+ }
+ // the model depends on valid ppd. so before enabling the
+ // properties button we make sure the ppd is in fact valid.
+ if (cupsPrinterCount && cups->currentPPD()) {
+ widget.properties->setEnabled(true);
+ }
+ currentPrinterIndex = cups->currentPrinterIndex();
+ } else {
+#endif
+ currentPrinterIndex = qt_getLprPrinters(lprPrinters);
+ // populating printer combo
+ QList<QPrinterDescription>::const_iterator i = lprPrinters.constBegin();
+ for(; i != lprPrinters.constEnd(); ++i)
+ widget.printers->addItem((*i).name);
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+ }
+#endif
+
+#if !defined(QT_NO_FILESYSTEMMODEL) && !defined(QT_NO_COMPLETER)
+ QFileSystemModel *fsm = new QFileSystemModel(widget.filename);
+ fsm->setRootPath(QDir::homePath());
+ widget.filename->setCompleter(new QCompleter(fsm, widget.filename));
+#endif
+ _q_printerChanged(currentPrinterIndex);
+
+ QObject::connect(widget.printers, SIGNAL(currentIndexChanged(int)),
+ parent, SLOT(_q_printerChanged(int)));
+ QObject::connect(widget.fileBrowser, SIGNAL(clicked()), parent, SLOT(_q_btnBrowseClicked()));
+ QObject::connect(widget.properties, SIGNAL(clicked()), parent, SLOT(_q_btnPropertiesClicked()));
+
+ // disable features that QPrinter does not yet support.
+ widget.preview->setVisible(false);
+}
+
+void QUnixPrintWidgetPrivate::updateWidget()
+{
+ const bool printToFile = q == 0 || q->isOptionEnabled(QPrintDialog::PrintToFile);
+ if (printToFile && !filePrintersAdded) {
+ if (widget.printers->count())
+ widget.printers->insertSeparator(widget.printers->count());
+ widget.printers->addItem(QPrintDialog::tr("Print to File (PDF)"));
+ filePrintersAdded = true;
+ }
+ if (!printToFile && filePrintersAdded) {
+ widget.printers->removeItem(widget.printers->count()-1);
+ widget.printers->removeItem(widget.printers->count()-1);
+ if (widget.printers->count())
+ widget.printers->removeItem(widget.printers->count()-1); // remove separator
+ filePrintersAdded = false;
+ }
+ if (printer && filePrintersAdded && (printer->outputFormat() != QPrinter::NativeFormat
+ || printer->printerName().isEmpty()))
+ {
+ if (printer->outputFormat() == QPrinter::PdfFormat)
+ widget.printers->setCurrentIndex(widget.printers->count() - 1);
+ widget.filename->setEnabled(true);
+ widget.lOutput->setEnabled(true);
+ }
+
+ widget.filename->setVisible(printToFile);
+ widget.lOutput->setVisible(printToFile);
+ widget.fileBrowser->setVisible(printToFile);
+
+ widget.properties->setVisible(q->isOptionEnabled(QAbstractPrintDialog::PrintShowPageSize));
+}
+
+QUnixPrintWidgetPrivate::~QUnixPrintWidgetPrivate()
+{
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+ delete cups;
+#endif
+}
+
+void QUnixPrintWidgetPrivate::_q_printerChanged(int index)
+{
+ if (index < 0)
+ return;
+ const int printerCount = widget.printers->count();
+ widget.filename->setEnabled(false);
+ widget.lOutput->setEnabled(false);
+
+ if (filePrintersAdded) {
+ Q_ASSERT(index != printerCount - 3); // separator
+ if (index == printerCount - 1) { // PDF
+ widget.location->setText(QPrintDialog::tr("Local file"));
+ widget.type->setText(QPrintDialog::tr("Write PDF file"));
+ widget.properties->setEnabled(true);
+ widget.filename->setEnabled(true);
+ QString filename = widget.filename->text();
+ QString suffix = QFileInfo(filename).suffix();
+ widget.filename->setText(filename);
+ widget.lOutput->setEnabled(true);
+ if (propertiesDialog)
+ propertiesDialog->selectPdfPsPrinter(printer);
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+ if (optionsPane)
+ optionsPane->selectPrinter(0);
+#endif
+ return;
+ }
+ }
+
+ widget.location->setText(QString());
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+ if (QCUPSSupport::isAvailable()) {
+ cups->setCurrentPrinter(index);
+
+ const cups_option_t *opt = cups->printerOption(QString::fromLatin1("printer-location"));
+ QString location;
+ if (opt)
+ location = QString::fromLocal8Bit(opt->value);
+ widget.location->setText(location);
+
+ cupsPPD = cups->currentPPD();
+ // set printer type line
+ QString type;
+ if (cupsPPD)
+ type = QString::fromLocal8Bit(cupsPPD->manufacturer) + QLatin1String(" - ") + QString::fromLocal8Bit(cupsPPD->modelname);
+ widget.type->setText(type);
+ if (propertiesDialog)
+ propertiesDialog->selectPrinter();
+ if (optionsPane)
+ optionsPane->selectPrinter(cups);
+ } else {
+ if (optionsPane)
+ optionsPane->selectPrinter(0);
+#endif
+ if (lprPrinters.count() > 0) {
+ QString type = lprPrinters.at(index).name + QLatin1Char('@') + lprPrinters.at(index).host;
+ if (!lprPrinters.at(index).comment.isEmpty())
+ type += QLatin1String(", ") + lprPrinters.at(index).comment;
+ widget.type->setText(type);
+ if (propertiesDialog)
+ propertiesDialog->selectPrinter();
+ }
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+ }
+#endif
+}
+
+void QUnixPrintWidgetPrivate::setOptionsPane(QPrintDialogPrivate *pane)
+{
+ optionsPane = pane;
+ if (optionsPane)
+ _q_printerChanged(widget.printers->currentIndex());
+}
+
+void QUnixPrintWidgetPrivate::_q_btnBrowseClicked()
+{
+ QString filename = widget.filename->text();
+#ifndef QT_NO_FILEDIALOG
+ filename = QFileDialog::getSaveFileName(parent, QPrintDialog::tr("Print To File ..."), filename,
+ QString(), 0, QFileDialog::DontConfirmOverwrite);
+#else
+ filename.clear();
+#endif
+ if (!filename.isEmpty()) {
+ widget.filename->setText(filename);
+ widget.printers->setCurrentIndex(widget.printers->count() - 1); // the pdf one
+ }
+}
+
+void QUnixPrintWidgetPrivate::applyPrinterProperties(QPrinter *p)
+{
+ if (p == 0)
+ return;
+ printer = p;
+ if (p->outputFileName().isEmpty()) {
+ QString home = QString::fromLocal8Bit(qgetenv("HOME").constData());
+ QString cur = QDir::currentPath();
+ if (home.at(home.length()-1) != QLatin1Char('/'))
+ home += QLatin1Char('/');
+ if (cur.at(cur.length()-1) != QLatin1Char('/'))
+ cur += QLatin1Char('/');
+ if (cur.left(home.length()) != home)
+ cur = home;
+#ifdef Q_WS_X11
+ if (p->docName().isEmpty()) {
+ cur += QLatin1String("print.pdf");
+ } else {
+ QRegExp re(QString::fromLatin1("(.*)\\.\\S+"));
+ if (re.exactMatch(p->docName()))
+ cur += re.cap(1);
+ else
+ cur += p->docName();
+ cur += QLatin1String(".pdf");
+ }
+#endif
+ widget.filename->setText(cur);
+ }
+ else
+ widget.filename->setText( p->outputFileName() );
+ QString printer = p->printerName();
+ if (!printer.isEmpty()) {
+ for (int i = 0; i < widget.printers->count(); ++i) {
+ if (widget.printers->itemText(i) == printer) {
+ widget.printers->setCurrentIndex(i);
+ break;
+ }
+ }
+ }
+ // PDF and PS printers are not added to the dialog yet, we'll handle those cases in QUnixPrintWidgetPrivate::updateWidget
+
+ if (propertiesDialog)
+ propertiesDialog->applyPrinterProperties(p);
+}
+
+#ifndef QT_NO_MESSAGEBOX
+bool QUnixPrintWidgetPrivate::checkFields()
+{
+ if (widget.filename->isEnabled()) {
+ QString file = widget.filename->text();
+ QFile f(file);
+ QFileInfo fi(f);
+ bool exists = fi.exists();
+ bool opened = false;
+ if (exists && fi.isDir()) {
+ QMessageBox::warning(q, q->windowTitle(),
+ QPrintDialog::tr("%1 is a directory.\nPlease choose a different file name.").arg(file));
+ return false;
+ } else if ((exists && !fi.isWritable()) || !(opened = f.open(QFile::Append))) {
+ QMessageBox::warning(q, q->windowTitle(),
+ QPrintDialog::tr("File %1 is not writable.\nPlease choose a different file name.").arg(file));
+ return false;
+ } else if (exists) {
+ int ret = QMessageBox::question(q, q->windowTitle(),
+ QPrintDialog::tr("%1 already exists.\nDo you want to overwrite it?").arg(file),
+ QMessageBox::Yes|QMessageBox::No, QMessageBox::No);
+ if (ret == QMessageBox::No)
+ return false;
+ }
+ if (opened) {
+ f.close();
+ if (!exists)
+ f.remove();
+ }
+ }
+
+ // Every test passed. Accept the dialog.
+ return true;
+}
+#endif // QT_NO_MESSAGEBOX
+
+void QUnixPrintWidgetPrivate::_q_btnPropertiesClicked()
+{
+ if (!propertiesDialog) {
+ propertiesDialog = new QPrintPropertiesDialog(q);
+ propertiesDialog->setResult(QDialog::Rejected);
+ }
+
+ if (propertiesDialog->result() == QDialog::Rejected) {
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+ propertiesDialog->setCups(cups);
+#endif
+ propertiesDialog->applyPrinterProperties(q->printer());
+
+ if (q->isOptionEnabled(QPrintDialog::PrintToFile)
+ && (widget.printers->currentIndex() == widget.printers->count() - 1)) // PDF
+ propertiesDialog->selectPdfPsPrinter(q->printer());
+ else
+ propertiesDialog->selectPrinter();
+ }
+ propertiesDialog->exec();
+}
+
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+void QUnixPrintWidgetPrivate::setCupsProperties()
+{
+ if (cups && QCUPSSupport::isAvailable() && cups->pageSizes()) {
+ QPrintEngine *engine = printer->printEngine();
+ const ppd_option_t* pageSizes = cups->pageSizes();
+ QByteArray cupsPageSize;
+ for (int i = 0; i < pageSizes->num_choices; ++i) {
+ if (static_cast<int>(pageSizes->choices[i].marked) == 1)
+ cupsPageSize = pageSizes->choices[i].choice;
+ }
+ engine->setProperty(PPK_CupsStringPageSize, QString::fromLatin1(cupsPageSize));
+ engine->setProperty(PPK_CupsOptions, cups->options());
+
+ QRect pageRect = cups->pageRect(cupsPageSize);
+ engine->setProperty(PPK_CupsPageRect, pageRect);
+
+ QRect paperRect = cups->paperRect(cupsPageSize);
+ engine->setProperty(PPK_CupsPaperRect, paperRect);
+
+ for (int ps = 0; ps < QPrinter::NPageSize; ++ps) {
+ QPdf::PaperSize size = QPdf::paperSize(QPrinter::PaperSize(ps));
+ if (size.width == paperRect.width() && size.height == paperRect.height())
+ printer->setPaperSize(static_cast<QPrinter::PaperSize>(ps));
+ }
+ }
+}
+#endif
+
+void QUnixPrintWidgetPrivate::setupPrinter()
+{
+ const int printerCount = widget.printers->count();
+ const int index = widget.printers->currentIndex();
+
+ if (filePrintersAdded && index == printerCount - 1) { // PDF
+ printer->setPrinterName(QString());
+ Q_ASSERT(index != printerCount - 3); // separator
+ printer->setOutputFormat(QPrinter::PdfFormat);
+ QString path = widget.filename->text();
+ if (QDir::isRelativePath(path))
+ path = QDir::homePath() + QDir::separator() + path;
+ printer->setOutputFileName(path);
+ }
+ else {
+ printer->setPrinterName(widget.printers->currentText());
+ printer->setOutputFileName(QString());
+ }
+
+ if (propertiesDialog && propertiesDialog->result() == QDialog::Accepted)
+ propertiesDialog->setupPrinter();
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+ if (!propertiesDialog)
+ setCupsProperties();
+#endif
+}
+
+
+/*! \internal
+*/
+QUnixPrintWidget::QUnixPrintWidget(QPrinter *printer, QWidget *parent)
+ : QWidget(parent), d(new QUnixPrintWidgetPrivate(this))
+{
+ d->applyPrinterProperties(printer);
+}
+
+/*! \internal
+*/
+QUnixPrintWidget::~QUnixPrintWidget()
+{
+ delete d;
+}
+
+/*! \internal
+
+ Updates the printer with the states held in the QUnixPrintWidget.
+*/
+void QUnixPrintWidget::updatePrinter()
+{
+ d->setupPrinter();
+}
+
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+
+QPPDOptionsModel::QPPDOptionsModel(QCUPSSupport *c, QObject *parent)
+ : QAbstractItemModel(parent), rootItem(0), cups(c), ppd(c->currentPPD())
+{
+ parseItems();
+}
+
+QPPDOptionsModel::~QPPDOptionsModel()
+{
+}
+
+int QPPDOptionsModel::columnCount(const QModelIndex&) const
+{
+ return 2;
+}
+
+int QPPDOptionsModel::rowCount(const QModelIndex& parent) const
+{
+ QOptionTreeItem* itm;
+ if (!parent.isValid())
+ itm = rootItem;
+ else
+ itm = reinterpret_cast<QOptionTreeItem*>(parent.internalPointer());
+
+ if (itm->type == QOptionTreeItem::Option)
+ return 0;
+
+ return itm->childItems.count();
+}
+
+QVariant QPPDOptionsModel::data(const QModelIndex& index, int role) const
+{
+ switch(role) {
+ case Qt::FontRole: {
+ QOptionTreeItem* itm = reinterpret_cast<QOptionTreeItem*>(index.internalPointer());
+ if (itm && itm->type == QOptionTreeItem::Group){
+ QFont font = QApplication::font();
+ font.setBold(true);
+ return QVariant(font);
+ }
+ return QVariant();
+ }
+ break;
+
+ case Qt::DisplayRole: {
+ QOptionTreeItem* itm;
+ if (!index.isValid())
+ itm = rootItem;
+ else
+ itm = reinterpret_cast<QOptionTreeItem*>(index.internalPointer());
+
+ if (index.column() == 0)
+ return cups->unicodeString(itm->description);
+ else if (itm->type == QOptionTreeItem::Option && itm->selected > -1)
+ return cups->unicodeString(itm->selDescription);
+ else
+ return QVariant();
+ }
+ break;
+
+ default:
+ return QVariant();
+ }
+ if (role != Qt::DisplayRole)
+ return QVariant();
+}
+
+QModelIndex QPPDOptionsModel::index(int row, int column, const QModelIndex& parent) const
+{
+ QOptionTreeItem* itm;
+ if (!parent.isValid())
+ itm = rootItem;
+ else
+ itm = reinterpret_cast<QOptionTreeItem*>(parent.internalPointer());
+
+ return createIndex(row, column, itm->childItems.at(row));
+}
+
+
+QModelIndex QPPDOptionsModel::parent(const QModelIndex& index) const
+{
+ if (!index.isValid())
+ return QModelIndex();
+
+ QOptionTreeItem* itm = reinterpret_cast<QOptionTreeItem*>(index.internalPointer());
+
+ if (itm->parentItem && itm->parentItem != rootItem)
+ return createIndex(itm->parentItem->index, 0, itm->parentItem);
+ else
+ return QModelIndex();
+}
+
+Qt::ItemFlags QPPDOptionsModel::flags(const QModelIndex& index) const
+{
+ if (!index.isValid() || reinterpret_cast<QOptionTreeItem*>(index.internalPointer())->type == QOptionTreeItem::Group)
+ return Qt::ItemIsEnabled;
+
+ if (index.column() == 1)
+ return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
+
+ return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
+}
+
+void QPPDOptionsModel::parseItems()
+{
+ emit layoutAboutToBeChanged();
+ ppd = cups->currentPPD();
+ delete rootItem;
+ rootItem = new QOptionTreeItem(QOptionTreeItem::Root, 0, ppd, "Root Item", 0);
+ parseGroups(rootItem);
+ emit layoutChanged();
+}
+
+void QPPDOptionsModel::parseGroups(QOptionTreeItem* parent)
+{
+ if (parent->type == QOptionTreeItem::Root) {
+
+ const ppd_file_t* ppdFile = reinterpret_cast<const ppd_file_t*>(parent->ptr);
+
+ if (ppdFile) {
+ for (int i = 0; i < ppdFile->num_groups; ++i) {
+ QOptionTreeItem* group = new QOptionTreeItem(QOptionTreeItem::Group, i, &ppdFile->groups[i], ppdFile->groups[i].text, parent);
+ parent->childItems.append(group);
+ parseGroups(group); // parse possible subgroups
+ parseOptions(group); // parse options
+ }
+ }
+ } else if (parent->type == QOptionTreeItem::Group) {
+
+ const ppd_group_t* group = reinterpret_cast<const ppd_group_t*>(parent->ptr);
+
+ if (group) {
+ for (int i = 0; i < group->num_subgroups; ++i) {
+ QOptionTreeItem* subgroup = new QOptionTreeItem(QOptionTreeItem::Group, i, &group->subgroups[i], group->subgroups[i].text, parent);
+ parent->childItems.append(subgroup);
+ parseGroups(subgroup); // parse possible subgroups
+ parseOptions(subgroup); // parse options
+ }
+ }
+ }
+}
+
+void QPPDOptionsModel::parseOptions(QOptionTreeItem* parent)
+{
+ const ppd_group_t* group = reinterpret_cast<const ppd_group_t*>(parent->ptr);
+ for (int i = 0; i < group->num_options; ++i) {
+ QOptionTreeItem* opt = new QOptionTreeItem(QOptionTreeItem::Option, i, &group->options[i], group->options[i].text, parent);
+ parent->childItems.append(opt);
+ parseChoices(opt);
+ }
+}
+
+void QPPDOptionsModel::parseChoices(QOptionTreeItem* parent)
+{
+ const ppd_option_t* option = reinterpret_cast<const ppd_option_t*>(parent->ptr);
+ bool marked = false;
+ for (int i = 0; i < option->num_choices; ++i) {
+ QOptionTreeItem* choice = new QOptionTreeItem(QOptionTreeItem::Choice, i, &option->choices[i], option->choices[i].text, parent);
+ if (static_cast<int>(option->choices[i].marked) == 1) {
+ parent->selected = i;
+ parent->selDescription = option->choices[i].text;
+ marked = true;
+ } else if (!marked && qstrcmp(option->choices[i].choice, option->defchoice) == 0) {
+ parent->selected = i;
+ parent->selDescription = option->choices[i].text;
+ }
+ parent->childItems.append(choice);
+ }
+}
+
+QVariant QPPDOptionsModel::headerData(int section, Qt::Orientation, int role) const
+{
+ if (role != Qt::DisplayRole)
+ return QVariant();
+
+ switch(section){
+ case 0:
+ return QVariant(QApplication::translate("QPPDOptionsModel", "Name"));
+ case 1:
+ return QVariant(QApplication::translate("QPPDOptionsModel", "Value"));
+ default:
+ return QVariant();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+QWidget* QPPDOptionsEditor::createEditor(QWidget* parent, const QStyleOptionViewItem&, const QModelIndex& index) const
+{
+ if (index.column() == 1 && reinterpret_cast<QOptionTreeItem*>(index.internalPointer())->type == QOptionTreeItem::Option)
+ return new QComboBox(parent);
+ else
+ return 0;
+}
+
+void QPPDOptionsEditor::setEditorData(QWidget* editor, const QModelIndex& index) const
+{
+ if (index.column() != 1)
+ return;
+
+ QComboBox* cb = static_cast<QComboBox*>(editor);
+ QOptionTreeItem* itm = reinterpret_cast<QOptionTreeItem*>(index.internalPointer());
+
+ if (itm->selected == -1)
+ cb->addItem(QString());
+
+ for (int i = 0; i < itm->childItems.count(); ++i)
+ cb->addItem(QString::fromLocal8Bit(itm->childItems.at(i)->description));
+
+ if (itm->selected > -1)
+ cb->setCurrentIndex(itm->selected);
+
+ connect(cb, SIGNAL(currentIndexChanged(int)), this, SLOT(cbChanged(int)));
+}
+
+void QPPDOptionsEditor::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const
+{
+ QComboBox* cb = static_cast<QComboBox*>(editor);
+ QOptionTreeItem* itm = reinterpret_cast<QOptionTreeItem*>(index.internalPointer());
+
+ if (itm->selected == cb->currentIndex())
+ return;
+
+ const ppd_option_t* opt = reinterpret_cast<const ppd_option_t*>(itm->ptr);
+ QPPDOptionsModel* m = static_cast<QPPDOptionsModel*>(model);
+
+ if (m->cups->markOption(opt->keyword, opt->choices[cb->currentIndex()].choice) == 0) {
+ itm->selected = cb->currentIndex();
+ itm->selDescription = reinterpret_cast<const ppd_option_t*>(itm->ptr)->choices[itm->selected].text;
+ }
+}
+
+void QPPDOptionsEditor::cbChanged(int)
+{
+/*
+ emit commitData(static_cast<QWidget*>(sender()));
+*/
+}
+
+#endif
+
+QT_END_NAMESPACE
+
+#include "moc_qprintdialog.cpp"
+#include "qprintdialog_unix.moc"
+#ifndef Q_OS_MAC
+#include "qrc_qprintdialog.cpp"
+#endif
+
+#endif // QT_NO_PRINTDIALOG
+
diff --git a/src/gui/dialogs/qprintdialog_win.cpp b/src/printsupport/dialogs/qprintdialog_win.cpp
index c8d92d45f2..c8d92d45f2 100644
--- a/src/gui/dialogs/qprintdialog_win.cpp
+++ b/src/printsupport/dialogs/qprintdialog_win.cpp
diff --git a/src/printsupport/dialogs/qprintpreviewdialog.cpp b/src/printsupport/dialogs/qprintpreviewdialog.cpp
new file mode 100644
index 0000000000..55ebc194f2
--- /dev/null
+++ b/src/printsupport/dialogs/qprintpreviewdialog.cpp
@@ -0,0 +1,803 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qprintpreviewdialog.h"
+#include "qprintpreviewwidget.h"
+#include <private/qprinter_p.h>
+#include "private/qdialog_p.h"
+#include "qprintdialog.h"
+
+#include <QtWidgets/qaction.h>
+#include <QtWidgets/qboxlayout.h>
+#include <QtWidgets/qcombobox.h>
+#include <QtWidgets/qlabel.h>
+#include <QtWidgets/qlineedit.h>
+#include <QtPrintSupport/qpagesetupdialog.h>
+#include <QtPrintSupport/qprinter.h>
+#include <QtWidgets/qstyle.h>
+#include <QtWidgets/qtoolbutton.h>
+#include <QtGui/qvalidator.h>
+#include <QtWidgets/qfiledialog.h>
+#include <QtWidgets/qmainwindow.h>
+#include <QtWidgets/qtoolbar.h>
+#include <QtWidgets/qformlayout.h>
+#include <QtCore/QCoreApplication>
+
+#include <math.h>
+
+#ifndef QT_NO_PRINTPREVIEWDIALOG
+
+QT_BEGIN_NAMESPACE
+
+namespace {
+class QPrintPreviewMainWindow : public QMainWindow
+{
+public:
+ QPrintPreviewMainWindow(QWidget *parent) : QMainWindow(parent) {}
+ QMenu *createPopupMenu() { return 0; }
+};
+
+class ZoomFactorValidator : public QDoubleValidator
+{
+public:
+ ZoomFactorValidator(QObject* parent)
+ : QDoubleValidator(parent) {}
+ ZoomFactorValidator(qreal bottom, qreal top, int decimals, QObject *parent)
+ : QDoubleValidator(bottom, top, decimals, parent) {}
+
+ State validate(QString &input, int &pos) const
+ {
+ bool replacePercent = false;
+ if (input.endsWith(QLatin1Char('%'))) {
+ input = input.left(input.length() - 1);
+ replacePercent = true;
+ }
+ State state = QDoubleValidator::validate(input, pos);
+ if (replacePercent)
+ input += QLatin1Char('%');
+ const int num_size = 4;
+ if (state == Intermediate) {
+ int i = input.indexOf(QLocale::system().decimalPoint());
+ if ((i == -1 && input.size() > num_size)
+ || (i != -1 && i > num_size))
+ return Invalid;
+ }
+ return state;
+ }
+};
+
+class LineEdit : public QLineEdit
+{
+ Q_OBJECT
+public:
+ LineEdit(QWidget* parent = 0)
+ : QLineEdit(parent)
+ {
+ setContextMenuPolicy(Qt::NoContextMenu);
+ connect(this, SIGNAL(returnPressed()), SLOT(handleReturnPressed()));
+ }
+
+protected:
+ void focusInEvent(QFocusEvent *e)
+ {
+ origText = text();
+ QLineEdit::focusInEvent(e);
+ }
+
+ void focusOutEvent(QFocusEvent *e)
+ {
+ if (isModified() && !hasAcceptableInput())
+ setText(origText);
+ QLineEdit::focusOutEvent(e);
+ }
+
+private slots:
+ void handleReturnPressed()
+ {
+ origText = text();
+ }
+
+private:
+ QString origText;
+};
+} // anonymous namespace
+
+class QPrintPreviewDialogPrivate : public QDialogPrivate
+{
+ Q_DECLARE_PUBLIC(QPrintPreviewDialog)
+public:
+ QPrintPreviewDialogPrivate()
+ : printDialog(0), ownPrinter(false),
+ initialized(false) {}
+
+ // private slots
+ void _q_fit(QAction *action);
+ void _q_zoomIn();
+ void _q_zoomOut();
+ void _q_navigate(QAction *action);
+ void _q_setMode(QAction *action);
+ void _q_pageNumEdited();
+ void _q_print();
+ void _q_pageSetup();
+ void _q_previewChanged();
+ void _q_zoomFactorChanged();
+
+ void init(QPrinter *printer = 0);
+ void populateScene();
+ void layoutPages();
+ void setupActions();
+ void updateNavActions();
+ void setFitting(bool on);
+ bool isFitting();
+ void updatePageNumLabel();
+ void updateZoomFactor();
+
+ QPrintDialog *printDialog;
+ QPrintPreviewWidget *preview;
+ QPrinter *printer;
+ bool ownPrinter;
+ bool initialized;
+
+ // widgets:
+ QLineEdit *pageNumEdit;
+ QLabel *pageNumLabel;
+ QComboBox *zoomFactor;
+
+ // actions:
+ QActionGroup* navGroup;
+ QAction *nextPageAction;
+ QAction *prevPageAction;
+ QAction *firstPageAction;
+ QAction *lastPageAction;
+
+ QActionGroup* fitGroup;
+ QAction *fitWidthAction;
+ QAction *fitPageAction;
+
+ QActionGroup* zoomGroup;
+ QAction *zoomInAction;
+ QAction *zoomOutAction;
+
+ QActionGroup* orientationGroup;
+ QAction *portraitAction;
+ QAction *landscapeAction;
+
+ QActionGroup* modeGroup;
+ QAction *singleModeAction;
+ QAction *facingModeAction;
+ QAction *overviewModeAction;
+
+ QActionGroup *printerGroup;
+ QAction *printAction;
+ QAction *pageSetupAction;
+#if defined(Q_WS_MAC) && !defined(QT_MAC_USE_COCOA)
+ QAction *closeAction;
+#endif
+
+ QPointer<QObject> receiverToDisconnectOnClose;
+ QByteArray memberToDisconnectOnClose;
+};
+
+void QPrintPreviewDialogPrivate::init(QPrinter *_printer)
+{
+ Q_Q(QPrintPreviewDialog);
+
+ if (_printer) {
+ preview = new QPrintPreviewWidget(_printer, q);
+ printer = _printer;
+ } else {
+ ownPrinter = true;
+ printer = new QPrinter;
+ preview = new QPrintPreviewWidget(printer, q);
+ }
+ QObject::connect(preview, SIGNAL(paintRequested(QPrinter*)), q, SIGNAL(paintRequested(QPrinter*)));
+ QObject::connect(preview, SIGNAL(previewChanged()), q, SLOT(_q_previewChanged()));
+ setupActions();
+
+ pageNumEdit = new LineEdit;
+ pageNumEdit->setAlignment(Qt::AlignRight);
+ pageNumEdit->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
+ pageNumLabel = new QLabel;
+ QObject::connect(pageNumEdit, SIGNAL(editingFinished()), q, SLOT(_q_pageNumEdited()));
+
+ zoomFactor = new QComboBox;
+ zoomFactor->setEditable(true);
+ zoomFactor->setMinimumContentsLength(7);
+ zoomFactor->setInsertPolicy(QComboBox::NoInsert);
+ LineEdit *zoomEditor = new LineEdit;
+ zoomEditor->setValidator(new ZoomFactorValidator(1, 1000, 1, zoomEditor));
+ zoomFactor->setLineEdit(zoomEditor);
+ static const short factorsX2[] = { 25, 50, 100, 200, 250, 300, 400, 800, 1600 };
+ for (int i = 0; i < int(sizeof(factorsX2) / sizeof(factorsX2[0])); ++i)
+ zoomFactor->addItem(QPrintPreviewDialog::tr("%1%").arg(factorsX2[i] / 2.0));
+ QObject::connect(zoomFactor->lineEdit(), SIGNAL(editingFinished()),
+ q, SLOT(_q_zoomFactorChanged()));
+ QObject::connect(zoomFactor, SIGNAL(currentIndexChanged(int)),
+ q, SLOT(_q_zoomFactorChanged()));
+
+ QPrintPreviewMainWindow *mw = new QPrintPreviewMainWindow(q);
+ QToolBar *toolbar = new QToolBar(mw);
+ toolbar->addAction(fitWidthAction);
+ toolbar->addAction(fitPageAction);
+ toolbar->addSeparator();
+ toolbar->addWidget(zoomFactor);
+ toolbar->addAction(zoomOutAction);
+ toolbar->addAction(zoomInAction);
+ toolbar->addSeparator();
+ toolbar->addAction(portraitAction);
+ toolbar->addAction(landscapeAction);
+ toolbar->addSeparator();
+ toolbar->addAction(firstPageAction);
+ toolbar->addAction(prevPageAction);
+
+ // this is to ensure the label text and the editor text are
+ // aligned in all styles - the extra QVBoxLayout is a workaround
+ // for bug in QFormLayout
+ QWidget *pageEdit = new QWidget(toolbar);
+ QVBoxLayout *vboxLayout = new QVBoxLayout;
+ vboxLayout->setContentsMargins(0, 0, 0, 0);
+#ifdef Q_WS_MAC
+ // We query the widgets about their size and then we fix the size.
+ // This should do the trick for the laying out part...
+ QSize pageNumEditSize, pageNumLabelSize;
+ pageNumEditSize = pageNumEdit->minimumSizeHint();
+ pageNumLabelSize = pageNumLabel->minimumSizeHint();
+ pageNumEdit->resize(pageNumEditSize);
+ pageNumLabel->resize(pageNumLabelSize);
+#endif
+ QFormLayout *formLayout = new QFormLayout;
+#ifdef Q_WS_MAC
+ // We have to change the growth policy in Mac.
+ formLayout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow);
+#endif
+ formLayout->setWidget(0, QFormLayout::LabelRole, pageNumEdit);
+ formLayout->setWidget(0, QFormLayout::FieldRole, pageNumLabel);
+ vboxLayout->addLayout(formLayout);
+ vboxLayout->setAlignment(Qt::AlignVCenter);
+ pageEdit->setLayout(vboxLayout);
+ toolbar->addWidget(pageEdit);
+
+ toolbar->addAction(nextPageAction);
+ toolbar->addAction(lastPageAction);
+ toolbar->addSeparator();
+ toolbar->addAction(singleModeAction);
+ toolbar->addAction(facingModeAction);
+ toolbar->addAction(overviewModeAction);
+ toolbar->addSeparator();
+ toolbar->addAction(pageSetupAction);
+ toolbar->addAction(printAction);
+#if defined(Q_WS_MAC) && !defined(QT_MAC_USE_COCOA)
+ toolbar->addAction(closeAction);
+#endif
+
+ // Cannot use the actions' triggered signal here, since it doesn't autorepeat
+ QToolButton *zoomInButton = static_cast<QToolButton *>(toolbar->widgetForAction(zoomInAction));
+ QToolButton *zoomOutButton = static_cast<QToolButton *>(toolbar->widgetForAction(zoomOutAction));
+ zoomInButton->setAutoRepeat(true);
+ zoomInButton->setAutoRepeatInterval(200);
+ zoomInButton->setAutoRepeatDelay(200);
+ zoomOutButton->setAutoRepeat(true);
+ zoomOutButton->setAutoRepeatInterval(200);
+ zoomOutButton->setAutoRepeatDelay(200);
+ QObject::connect(zoomInButton, SIGNAL(clicked()), q, SLOT(_q_zoomIn()));
+ QObject::connect(zoomOutButton, SIGNAL(clicked()), q, SLOT(_q_zoomOut()));
+
+ mw->addToolBar(toolbar);
+ mw->setCentralWidget(preview);
+ // QMainWindows are always created as top levels, force it to be a
+ // plain widget
+ mw->setParent(q, Qt::Widget);
+
+ QVBoxLayout *topLayout = new QVBoxLayout;
+ topLayout->addWidget(mw);
+ topLayout->setMargin(0);
+ q->setLayout(topLayout);
+
+ QString caption = QCoreApplication::translate("QPrintPreviewDialog", "Print Preview");
+ if (!printer->docName().isEmpty())
+ caption += QString::fromLatin1(": ") + printer->docName();
+ q->setWindowTitle(caption);
+
+ if (!printer->isValid()
+#if defined(Q_WS_WIN) || defined(Q_WS_MAC)
+ || printer->outputFormat() != QPrinter::NativeFormat
+#endif
+ )
+ pageSetupAction->setEnabled(false);
+ preview->setFocus();
+}
+
+static inline void qt_setupActionIcon(QAction *action, const QLatin1String &name)
+{
+ QLatin1String imagePrefix(":/trolltech/dialogs/qprintpreviewdialog/images/");
+ QIcon icon;
+ icon.addFile(imagePrefix + name + QLatin1String("-24.png"), QSize(24, 24));
+ icon.addFile(imagePrefix + name + QLatin1String("-32.png"), QSize(32, 32));
+ action->setIcon(icon);
+}
+
+void QPrintPreviewDialogPrivate::setupActions()
+{
+ Q_Q(QPrintPreviewDialog);
+
+ // Navigation
+ navGroup = new QActionGroup(q);
+ navGroup->setExclusive(false);
+ nextPageAction = navGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Next page"));
+ prevPageAction = navGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Previous page"));
+ firstPageAction = navGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "First page"));
+ lastPageAction = navGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Last page"));
+ qt_setupActionIcon(nextPageAction, QLatin1String("go-next"));
+ qt_setupActionIcon(prevPageAction, QLatin1String("go-previous"));
+ qt_setupActionIcon(firstPageAction, QLatin1String("go-first"));
+ qt_setupActionIcon(lastPageAction, QLatin1String("go-last"));
+ QObject::connect(navGroup, SIGNAL(triggered(QAction*)), q, SLOT(_q_navigate(QAction*)));
+
+
+ fitGroup = new QActionGroup(q);
+ fitWidthAction = fitGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Fit width"));
+ fitPageAction = fitGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Fit page"));
+ fitWidthAction->setObjectName(QLatin1String("fitWidthAction"));
+ fitPageAction->setObjectName(QLatin1String("fitPageAction"));
+ fitWidthAction->setCheckable(true);
+ fitPageAction->setCheckable(true);
+ qt_setupActionIcon(fitWidthAction, QLatin1String("fit-width"));
+ qt_setupActionIcon(fitPageAction, QLatin1String("fit-page"));
+ QObject::connect(fitGroup, SIGNAL(triggered(QAction*)), q, SLOT(_q_fit(QAction*)));
+
+ // Zoom
+ zoomGroup = new QActionGroup(q);
+ zoomInAction = zoomGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Zoom in"));
+ zoomOutAction = zoomGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Zoom out"));
+ qt_setupActionIcon(zoomInAction, QLatin1String("zoom-in"));
+ qt_setupActionIcon(zoomOutAction, QLatin1String("zoom-out"));
+
+ // Portrait/Landscape
+ orientationGroup = new QActionGroup(q);
+ portraitAction = orientationGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Portrait"));
+ landscapeAction = orientationGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Landscape"));
+ portraitAction->setCheckable(true);
+ landscapeAction->setCheckable(true);
+ qt_setupActionIcon(portraitAction, QLatin1String("layout-portrait"));
+ qt_setupActionIcon(landscapeAction, QLatin1String("layout-landscape"));
+ QObject::connect(portraitAction, SIGNAL(triggered(bool)), preview, SLOT(setPortraitOrientation()));
+ QObject::connect(landscapeAction, SIGNAL(triggered(bool)), preview, SLOT(setLandscapeOrientation()));
+
+ // Display mode
+ modeGroup = new QActionGroup(q);
+ singleModeAction = modeGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Show single page"));
+ facingModeAction = modeGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Show facing pages"));
+ overviewModeAction = modeGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Show overview of all pages"));
+ qt_setupActionIcon(singleModeAction, QLatin1String("view-page-one"));
+ qt_setupActionIcon(facingModeAction, QLatin1String("view-page-sided"));
+ qt_setupActionIcon(overviewModeAction, QLatin1String("view-page-multi"));
+ singleModeAction->setObjectName(QLatin1String("singleModeAction"));
+ facingModeAction->setObjectName(QLatin1String("facingModeAction"));
+ overviewModeAction->setObjectName(QLatin1String("overviewModeAction"));
+
+ singleModeAction->setCheckable(true);
+ facingModeAction->setCheckable(true);
+ overviewModeAction->setCheckable(true);
+ QObject::connect(modeGroup, SIGNAL(triggered(QAction*)), q, SLOT(_q_setMode(QAction*)));
+
+ // Print
+ printerGroup = new QActionGroup(q);
+ printAction = printerGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Print"));
+ pageSetupAction = printerGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Page setup"));
+ qt_setupActionIcon(printAction, QLatin1String("print"));
+ qt_setupActionIcon(pageSetupAction, QLatin1String("page-setup"));
+ QObject::connect(printAction, SIGNAL(triggered(bool)), q, SLOT(_q_print()));
+ QObject::connect(pageSetupAction, SIGNAL(triggered(bool)), q, SLOT(_q_pageSetup()));
+#if defined(Q_WS_MAC) && !defined(QT_MAC_USE_COCOA)
+ closeAction = printerGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Close"));
+ QObject::connect(closeAction, SIGNAL(triggered(bool)), q, SLOT(reject()));
+#endif
+
+ // Initial state:
+ fitPageAction->setChecked(true);
+ singleModeAction->setChecked(true);
+ if (preview->orientation() == QPrinter::Portrait)
+ portraitAction->setChecked(true);
+ else
+ landscapeAction->setChecked(true);
+}
+
+
+bool QPrintPreviewDialogPrivate::isFitting()
+{
+ return (fitGroup->isExclusive()
+ && (fitWidthAction->isChecked() || fitPageAction->isChecked()));
+}
+
+
+void QPrintPreviewDialogPrivate::setFitting(bool on)
+{
+ if (isFitting() == on)
+ return;
+ fitGroup->setExclusive(on);
+ if (on) {
+ QAction* action = fitWidthAction->isChecked() ? fitWidthAction : fitPageAction;
+ action->setChecked(true);
+ if (fitGroup->checkedAction() != action) {
+ // work around exclusitivity problem
+ fitGroup->removeAction(action);
+ fitGroup->addAction(action);
+ }
+ } else {
+ fitWidthAction->setChecked(false);
+ fitPageAction->setChecked(false);
+ }
+}
+
+void QPrintPreviewDialogPrivate::updateNavActions()
+{
+ int curPage = preview->currentPage();
+ int numPages = preview->pageCount();
+ nextPageAction->setEnabled(curPage < numPages);
+ prevPageAction->setEnabled(curPage > 1);
+ firstPageAction->setEnabled(curPage > 1);
+ lastPageAction->setEnabled(curPage < numPages);
+ pageNumEdit->setText(QString::number(curPage));
+}
+
+void QPrintPreviewDialogPrivate::updatePageNumLabel()
+{
+ Q_Q(QPrintPreviewDialog);
+
+ int numPages = preview->pageCount();
+ int maxChars = QString::number(numPages).length();
+ pageNumLabel->setText(QString::fromLatin1("/ %1").arg(numPages));
+ int cyphersWidth = q->fontMetrics().width(QString().fill(QLatin1Char('8'), maxChars));
+ int maxWidth = pageNumEdit->minimumSizeHint().width() + cyphersWidth;
+ pageNumEdit->setMinimumWidth(maxWidth);
+ pageNumEdit->setMaximumWidth(maxWidth);
+ pageNumEdit->setValidator(new QIntValidator(1, numPages, pageNumEdit));
+ // any old one will be deleted later along with its parent pageNumEdit
+}
+
+void QPrintPreviewDialogPrivate::updateZoomFactor()
+{
+ zoomFactor->lineEdit()->setText(QString().sprintf("%.1f%%", preview->zoomFactor()*100));
+}
+
+void QPrintPreviewDialogPrivate::_q_fit(QAction* action)
+{
+ setFitting(true);
+ if (action == fitPageAction)
+ preview->fitInView();
+ else
+ preview->fitToWidth();
+}
+
+void QPrintPreviewDialogPrivate::_q_zoomIn()
+{
+ setFitting(false);
+ preview->zoomIn();
+ updateZoomFactor();
+}
+
+void QPrintPreviewDialogPrivate::_q_zoomOut()
+{
+ setFitting(false);
+ preview->zoomOut();
+ updateZoomFactor();
+}
+
+void QPrintPreviewDialogPrivate::_q_pageNumEdited()
+{
+ bool ok = false;
+ int res = pageNumEdit->text().toInt(&ok);
+ if (ok)
+ preview->setCurrentPage(res);
+}
+
+void QPrintPreviewDialogPrivate::_q_navigate(QAction* action)
+{
+ int curPage = preview->currentPage();
+ if (action == prevPageAction)
+ preview->setCurrentPage(curPage - 1);
+ else if (action == nextPageAction)
+ preview->setCurrentPage(curPage + 1);
+ else if (action == firstPageAction)
+ preview->setCurrentPage(1);
+ else if (action == lastPageAction)
+ preview->setCurrentPage(preview->pageCount());
+ updateNavActions();
+}
+
+void QPrintPreviewDialogPrivate::_q_setMode(QAction* action)
+{
+ if (action == overviewModeAction) {
+ preview->setViewMode(QPrintPreviewWidget::AllPagesView);
+ setFitting(false);
+ fitGroup->setEnabled(false);
+ navGroup->setEnabled(false);
+ pageNumEdit->setEnabled(false);
+ pageNumLabel->setEnabled(false);
+ } else if (action == facingModeAction) {
+ preview->setViewMode(QPrintPreviewWidget::FacingPagesView);
+ } else {
+ preview->setViewMode(QPrintPreviewWidget::SinglePageView);
+ }
+ if (action == facingModeAction || action == singleModeAction) {
+ fitGroup->setEnabled(true);
+ navGroup->setEnabled(true);
+ pageNumEdit->setEnabled(true);
+ pageNumLabel->setEnabled(true);
+ setFitting(true);
+ }
+}
+
+void QPrintPreviewDialogPrivate::_q_print()
+{
+ Q_Q(QPrintPreviewDialog);
+
+#if defined(Q_WS_WIN) || defined(Q_WS_MAC)
+ if (printer->outputFormat() != QPrinter::NativeFormat) {
+ QString title;
+ QString suffix;
+ if (printer->outputFormat() == QPrinter::PdfFormat) {
+ title = QCoreApplication::translate("QPrintPreviewDialog", "Export to PDF");
+ suffix = QLatin1String(".pdf");
+ } else {
+ title = QCoreApplication::translate("QPrintPreviewDialog", "Export to PostScript");
+ suffix = QLatin1String(".ps");
+ }
+ QString fileName = QFileDialog::getSaveFileName(q, title, printer->outputFileName(),
+ QLatin1Char('*') + suffix);
+ if (!fileName.isEmpty()) {
+ if (QFileInfo(fileName).suffix().isEmpty())
+ fileName.append(suffix);
+ printer->setOutputFileName(fileName);
+ }
+ if (!printer->outputFileName().isEmpty())
+ preview->print();
+ q->accept();
+ return;
+ }
+#endif
+
+ if (!printDialog)
+ printDialog = new QPrintDialog(printer, q);
+ if (printDialog->exec() == QDialog::Accepted) {
+ preview->print();
+ q->accept();
+ }
+}
+
+void QPrintPreviewDialogPrivate::_q_pageSetup()
+{
+ Q_Q(QPrintPreviewDialog);
+
+ QPageSetupDialog pageSetup(printer, q);
+ if (pageSetup.exec() == QDialog::Accepted) {
+ // update possible orientation changes
+ if (preview->orientation() == QPrinter::Portrait) {
+ portraitAction->setChecked(true);
+ preview->setPortraitOrientation();
+ }else {
+ landscapeAction->setChecked(true);
+ preview->setLandscapeOrientation();
+ }
+ }
+}
+
+void QPrintPreviewDialogPrivate::_q_previewChanged()
+{
+ updateNavActions();
+ updatePageNumLabel();
+ updateZoomFactor();
+}
+
+void QPrintPreviewDialogPrivate::_q_zoomFactorChanged()
+{
+ QString text = zoomFactor->lineEdit()->text();
+ bool ok;
+ qreal factor = text.remove(QLatin1Char('%')).toFloat(&ok);
+ factor = qMax(qreal(1.0), qMin(qreal(1000.0), factor));
+ if (ok) {
+ preview->setZoomFactor(factor/100.0);
+ zoomFactor->setEditText(QString::fromLatin1("%1%").arg(factor));
+ setFitting(false);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+/*!
+ \class QPrintPreviewDialog
+ \since 4.4
+
+ \brief The QPrintPreviewDialog class provides a dialog for
+ previewing and configuring page layouts for printer output.
+
+ \ingroup standard-dialogs
+ \ingroup printing
+
+ Using QPrintPreviewDialog in your existing application is
+ straightforward:
+
+ \list 1
+ \o Create the QPrintPreviewDialog.
+
+ You can construct a QPrintPreviewDialog with an existing QPrinter
+ object, or you can have QPrintPreviewDialog create one for you,
+ which will be the system default printer.
+
+ \o Connect the paintRequested() signal to a slot.
+
+ When the dialog needs to generate a set of preview pages, the
+ paintRequested() signal will be emitted. You can use the exact
+ same code for the actual printing as for having the preview
+ generated, including calling QPrinter::newPage() to start a new
+ page in the preview. Connect a slot to the paintRequested()
+ signal, where you draw onto the QPrinter object that is passed
+ into the slot.
+
+ \o Call exec().
+
+ Call QPrintPreviewDialog::exec() to show the preview dialog.
+ \endlist
+
+ In Symbian, there is no support for printing. Hence, this dialog should not
+ be used in Symbian.
+
+ \sa QPrinter, QPrintDialog, QPageSetupDialog, QPrintPreviewWidget
+*/
+
+/*!
+ Constructs a QPrintPreviewDialog based on \a printer and with \a
+ parent as the parent widget. The widget flags \a flags are passed on
+ to the QWidget constructor.
+
+ \sa QWidget::setWindowFlags()
+*/
+QPrintPreviewDialog::QPrintPreviewDialog(QPrinter* printer, QWidget *parent, Qt::WindowFlags flags)
+ : QDialog(*new QPrintPreviewDialogPrivate, parent, flags)
+{
+ Q_D(QPrintPreviewDialog);
+ d->init(printer);
+}
+
+/*!
+ \overload
+ \fn QPrintPreviewDialog::QPrintPreviewDialog(QWidget *parent, Qt::WindowFlags flags)
+
+ This will create an internal QPrinter object, which will use the
+ system default printer.
+*/
+QPrintPreviewDialog::QPrintPreviewDialog(QWidget *parent, Qt::WindowFlags f)
+ : QDialog(*new QPrintPreviewDialogPrivate, parent, f)
+{
+ Q_D(QPrintPreviewDialog);
+ d->init();
+}
+
+/*!
+ Destroys the QPrintPreviewDialog.
+*/
+QPrintPreviewDialog::~QPrintPreviewDialog()
+{
+ Q_D(QPrintPreviewDialog);
+ if (d->ownPrinter)
+ delete d->printer;
+ delete d->printDialog;
+}
+
+/*!
+ \reimp
+*/
+void QPrintPreviewDialog::setVisible(bool visible)
+{
+ Q_D(QPrintPreviewDialog);
+ // this will make the dialog get a decent default size
+ if (visible && !d->initialized) {
+ d->preview->updatePreview();
+ d->initialized = true;
+ }
+ QDialog::setVisible(visible);
+}
+
+/*!
+ \reimp
+*/
+void QPrintPreviewDialog::done(int result)
+{
+ Q_D(QPrintPreviewDialog);
+ QDialog::done(result);
+ if (d->receiverToDisconnectOnClose) {
+ disconnect(this, SIGNAL(finished(int)),
+ d->receiverToDisconnectOnClose, d->memberToDisconnectOnClose);
+ d->receiverToDisconnectOnClose = 0;
+ }
+ d->memberToDisconnectOnClose.clear();
+}
+
+/*!
+ \overload
+ \since 4.5
+
+ Opens the dialog and connects its finished(int) signal to the slot specified
+ by \a receiver and \a member.
+
+ The signal will be disconnected from the slot when the dialog is closed.
+*/
+void QPrintPreviewDialog::open(QObject *receiver, const char *member)
+{
+ Q_D(QPrintPreviewDialog);
+ // the int parameter isn't very useful here; we could just as well connect
+ // to reject(), but this feels less robust somehow
+ connect(this, SIGNAL(finished(int)), receiver, member);
+ d->receiverToDisconnectOnClose = receiver;
+ d->memberToDisconnectOnClose = member;
+ QDialog::open();
+}
+
+/*!
+ Returns a pointer to the QPrinter object this dialog is currently
+ operating on.
+*/
+QPrinter *QPrintPreviewDialog::printer()
+{
+ Q_D(QPrintPreviewDialog);
+ return d->printer;
+}
+
+/*!
+ \fn void QPrintPreviewDialog::paintRequested(QPrinter *printer)
+
+ This signal is emitted when the QPrintPreviewDialog needs to generate
+ a set of preview pages.
+
+ The \a printer instance supplied is the paint device onto which you should
+ paint the contents of each page, using the QPrinter instance in the same way
+ as you would when printing directly.
+*/
+
+
+QT_END_NAMESPACE
+
+#include "moc_qprintpreviewdialog.cpp"
+#include "qprintpreviewdialog.moc"
+
+#endif // QT_NO_PRINTPREVIEWDIALOG
+
+
diff --git a/src/printsupport/dialogs/qprintpreviewdialog.h b/src/printsupport/dialogs/qprintpreviewdialog.h
new file mode 100644
index 0000000000..f2997b09f5
--- /dev/null
+++ b/src/printsupport/dialogs/qprintpreviewdialog.h
@@ -0,0 +1,108 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPRINTPREVIEWDIALOG_H
+#define QPRINTPREVIEWDIALOG_H
+
+#include <QtWidgets/qdialog.h>
+
+#ifndef QT_NO_PRINTPREVIEWDIALOG
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QGraphicsView;
+class QPrintPreviewDialogPrivate;
+class QPrinter;
+
+class Q_PRINTSUPPORT_EXPORT QPrintPreviewDialog : public QDialog
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QPrintPreviewDialog)
+
+public:
+ explicit QPrintPreviewDialog(QWidget *parent = 0, Qt::WindowFlags flags = 0);
+ explicit QPrintPreviewDialog(QPrinter *printer, QWidget *parent = 0, Qt::WindowFlags flags = 0);
+ ~QPrintPreviewDialog();
+
+#ifdef Q_NO_USING_KEYWORD
+#ifndef Q_QDOC
+ void open() { QDialog::open(); }
+#endif
+#else
+ using QDialog::open;
+#endif
+ void open(QObject *receiver, const char *member);
+
+ QPrinter *printer();
+
+ void setVisible(bool visible);
+ void done(int result);
+
+Q_SIGNALS:
+ void paintRequested(QPrinter *printer);
+
+private:
+ Q_PRIVATE_SLOT(d_func(), void _q_fit(QAction *action))
+ Q_PRIVATE_SLOT(d_func(), void _q_zoomIn())
+ Q_PRIVATE_SLOT(d_func(), void _q_zoomOut())
+ Q_PRIVATE_SLOT(d_func(), void _q_navigate(QAction *action))
+ Q_PRIVATE_SLOT(d_func(), void _q_setMode(QAction *action))
+ Q_PRIVATE_SLOT(d_func(), void _q_pageNumEdited())
+ Q_PRIVATE_SLOT(d_func(), void _q_print())
+ Q_PRIVATE_SLOT(d_func(), void _q_pageSetup())
+ Q_PRIVATE_SLOT(d_func(), void _q_previewChanged())
+ Q_PRIVATE_SLOT(d_func(), void _q_zoomFactorChanged())
+
+ void *dummy; // ### Qt 5 - remove me
+};
+
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QT_NO_PRINTPREVIEWDIALOG
+
+#endif // QPRINTPREVIEWDIALOG_H
diff --git a/src/gui/dialogs/qprintpropertieswidget.ui b/src/printsupport/dialogs/qprintpropertieswidget.ui
index 26fa09599e..26fa09599e 100644
--- a/src/gui/dialogs/qprintpropertieswidget.ui
+++ b/src/printsupport/dialogs/qprintpropertieswidget.ui
diff --git a/src/gui/dialogs/qprintsettingsoutput.ui b/src/printsupport/dialogs/qprintsettingsoutput.ui
index be916790fb..be916790fb 100644
--- a/src/gui/dialogs/qprintsettingsoutput.ui
+++ b/src/printsupport/dialogs/qprintsettingsoutput.ui
diff --git a/src/gui/dialogs/qprintwidget.ui b/src/printsupport/dialogs/qprintwidget.ui
index 8a4f3bde0a..8a4f3bde0a 100644
--- a/src/gui/dialogs/qprintwidget.ui
+++ b/src/printsupport/dialogs/qprintwidget.ui
diff --git a/src/printsupport/kernel/kernel.pri b/src/printsupport/kernel/kernel.pri
new file mode 100644
index 0000000000..3868d9e212
--- /dev/null
+++ b/src/printsupport/kernel/kernel.pri
@@ -0,0 +1,34 @@
+HEADERS += \
+ $$PWD/qpaintengine_alpha_p.h \
+ $$PWD/qpaintengine_preview_p.h \
+ $$PWD/qprintengine.h \
+ $$PWD/qprinter.h \
+ $$PWD/qprinter_p.h \
+ $$PWD/qprinterinfo.h \
+ $$PWD/qprinterinfo_p.h \
+ $$PWD/qplatformprintplugin_qpa.h \
+ $$PWD/qplatformprintersupport_qpa.h
+
+SOURCES += \
+ $$PWD/qpaintengine_alpha.cpp \
+ $$PWD/qpaintengine_preview.cpp \
+ $$PWD/qprintengine_pdf.cpp \
+ $$PWD/qprinter.cpp \
+ $$PWD/qprinterinfo.cpp \
+ $$PWD/qplatformprintplugin.cpp \
+ $$PWD/qplatformprintersupport_qpa.cpp
+
+unix:!symbian {
+ HEADERS += \
+ $$PWD/qprinterinfo_unix_p.h
+ SOURCES += \
+ $$PWD/qprinterinfo_unix.cpp
+}
+
+
+x11|qpa:!win32 {
+ SOURCES += $$PWD/qcups.cpp
+ HEADERS += $$PWD/qcups_p.h
+} else {
+ DEFINES += QT_NO_CUPS QT_NO_LPR
+}
diff --git a/src/printsupport/kernel/qcups.cpp b/src/printsupport/kernel/qcups.cpp
new file mode 100644
index 0000000000..76050d9d71
--- /dev/null
+++ b/src/printsupport/kernel/qcups.cpp
@@ -0,0 +1,446 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <qdebug.h>
+#include "qcups_p.h"
+#include "qprinterinfo_unix_p.h"
+
+#ifndef QT_NO_CUPS
+
+#ifndef QT_LINUXBASE // LSB merges everything into cups.h
+# include <cups/language.h>
+#endif
+#include <qtextcodec.h>
+
+QT_BEGIN_NAMESPACE
+
+typedef int (*CupsGetDests)(cups_dest_t **dests);
+typedef void (*CupsFreeDests)(int num_dests, cups_dest_t *dests);
+typedef const char* (*CupsGetPPD)(const char *printer);
+typedef int (*CupsMarkOptions)(ppd_file_t *ppd, int num_options, cups_option_t *options);
+typedef ppd_file_t* (*PPDOpenFile)(const char *filename);
+typedef void (*PPDMarkDefaults)(ppd_file_t *ppd);
+typedef int (*PPDMarkOption)(ppd_file_t *ppd, const char *keyword, const char *option);
+typedef void (*PPDClose)(ppd_file_t *ppd);
+typedef int (*PPDMarkOption)(ppd_file_t *ppd, const char *keyword, const char *option);
+typedef void (*CupsFreeOptions)(int num_options, cups_option_t *options);
+typedef void (*CupsSetDests)(int num_dests, cups_dest_t *dests);
+typedef cups_lang_t* (*CupsLangGet)(const char *language);
+typedef const char* (*CupsLangEncoding)(cups_lang_t *language);
+typedef int (*CupsAddOption)(const char *name, const char *value, int num_options, cups_option_t **options);
+typedef int (*CupsTempFd)(char *name, int len);
+typedef int (*CupsPrintFile)(const char * name, const char * filename, const char * title, int num_options, cups_option_t * options);
+
+static bool cupsLoaded = false;
+static int qt_cups_num_printers = 0;
+static CupsGetDests _cupsGetDests = 0;
+static CupsFreeDests _cupsFreeDests = 0;
+static CupsGetPPD _cupsGetPPD = 0;
+static PPDOpenFile _ppdOpenFile = 0;
+static PPDMarkDefaults _ppdMarkDefaults = 0;
+static PPDClose _ppdClose = 0;
+static CupsMarkOptions _cupsMarkOptions = 0;
+static PPDMarkOption _ppdMarkOption = 0;
+static CupsFreeOptions _cupsFreeOptions = 0;
+static CupsSetDests _cupsSetDests = 0;
+static CupsLangGet _cupsLangGet = 0;
+static CupsLangEncoding _cupsLangEncoding = 0;
+static CupsAddOption _cupsAddOption = 0;
+static CupsTempFd _cupsTempFd = 0;
+static CupsPrintFile _cupsPrintFile = 0;
+
+static void resolveCups()
+{
+ QLibrary cupsLib(QLatin1String("cups"), 2);
+ if(cupsLib.load()) {
+ _cupsGetDests = (CupsGetDests) cupsLib.resolve("cupsGetDests");
+ _cupsFreeDests = (CupsFreeDests) cupsLib.resolve("cupsFreeDests");
+ _cupsGetPPD = (CupsGetPPD) cupsLib.resolve("cupsGetPPD");
+ _cupsLangGet = (CupsLangGet) cupsLib.resolve("cupsLangGet");
+ _cupsLangEncoding = (CupsLangEncoding) cupsLib.resolve("cupsLangEncoding");
+ _ppdOpenFile = (PPDOpenFile) cupsLib.resolve("ppdOpenFile");
+ _ppdMarkDefaults = (PPDMarkDefaults) cupsLib.resolve("ppdMarkDefaults");
+ _ppdClose = (PPDClose) cupsLib.resolve("ppdClose");
+ _cupsMarkOptions = (CupsMarkOptions) cupsLib.resolve("cupsMarkOptions");
+ _ppdMarkOption = (PPDMarkOption) cupsLib.resolve("ppdMarkOption");
+ _cupsFreeOptions = (CupsFreeOptions) cupsLib.resolve("cupsFreeOptions");
+ _cupsSetDests = (CupsSetDests) cupsLib.resolve("cupsSetDests");
+ _cupsAddOption = (CupsAddOption) cupsLib.resolve("cupsAddOption");
+ _cupsTempFd = (CupsTempFd) cupsLib.resolve("cupsTempFd");
+ _cupsPrintFile = (CupsPrintFile) cupsLib.resolve("cupsPrintFile");
+
+ if (_cupsGetDests && _cupsFreeDests) {
+ cups_dest_t *printers;
+ int num_printers = _cupsGetDests(&printers);
+ if (num_printers)
+ _cupsFreeDests(num_printers, printers);
+ qt_cups_num_printers = num_printers;
+ }
+ }
+ cupsLoaded = true;
+}
+
+// ================ CUPS Support class ========================
+
+QCUPSSupport::QCUPSSupport()
+ :
+ prnCount(0),
+ printers(0),
+ page_sizes(0),
+ currPrinterIndex(0),
+ currPPD(0)
+{
+ if (!cupsLoaded)
+ resolveCups();
+
+ // getting all available printers
+ if (!isAvailable())
+ return;
+
+ prnCount = _cupsGetDests(&printers);
+
+ for (int i = 0; i < prnCount; ++i) {
+ if (printers[i].is_default) {
+ currPrinterIndex = i;
+ setCurrentPrinter(i);
+ break;
+ }
+ }
+
+#ifndef QT_NO_TEXTCODEC
+ cups_lang_t *cupsLang = _cupsLangGet(0);
+ codec = QTextCodec::codecForName(_cupsLangEncoding(cupsLang));
+ if (!codec)
+ codec = QTextCodec::codecForLocale();
+#endif
+}
+
+QCUPSSupport::~QCUPSSupport()
+{
+ if (currPPD)
+ _ppdClose(currPPD);
+ if (prnCount)
+ _cupsFreeDests(prnCount, printers);
+}
+
+int QCUPSSupport::availablePrintersCount() const
+{
+ return prnCount;
+}
+
+const cups_dest_t* QCUPSSupport::availablePrinters() const
+{
+ return printers;
+}
+
+const ppd_file_t* QCUPSSupport::currentPPD() const
+{
+ return currPPD;
+}
+
+const ppd_file_t* QCUPSSupport::setCurrentPrinter(int index)
+{
+ Q_ASSERT(index >= 0 && index <= prnCount);
+ if (index == prnCount)
+ return 0;
+
+ currPrinterIndex = index;
+
+ if (currPPD)
+ _ppdClose(currPPD);
+ currPPD = 0;
+ page_sizes = 0;
+
+ const char *ppdFile = _cupsGetPPD(printers[index].name);
+
+ if (!ppdFile)
+ return 0;
+
+ currPPD = _ppdOpenFile(ppdFile);
+ unlink(ppdFile);
+
+ // marking default options
+ _ppdMarkDefaults(currPPD);
+
+ // marking options explicitly set
+ _cupsMarkOptions(currPPD, printers[currPrinterIndex].num_options, printers[currPrinterIndex].options);
+
+ // getting pointer to page sizes
+ page_sizes = ppdOption("PageSize");
+
+ return currPPD;
+}
+
+int QCUPSSupport::currentPrinterIndex() const
+{
+ return currPrinterIndex;
+}
+
+bool QCUPSSupport::isAvailable()
+{
+ if(!cupsLoaded)
+ resolveCups();
+
+ return _cupsGetDests &&
+ _cupsFreeDests &&
+ _cupsGetPPD &&
+ _ppdOpenFile &&
+ _ppdMarkDefaults &&
+ _ppdClose &&
+ _cupsMarkOptions &&
+ _ppdMarkOption &&
+ _cupsFreeOptions &&
+ _cupsSetDests &&
+ _cupsLangGet &&
+ _cupsLangEncoding &&
+ _cupsAddOption &&
+ (qt_cups_num_printers > 0);
+}
+
+const ppd_option_t* QCUPSSupport::ppdOption(const char *key) const
+{
+ if (currPPD) {
+ for (int gr = 0; gr < currPPD->num_groups; ++gr) {
+ for (int opt = 0; opt < currPPD->groups[gr].num_options; ++opt) {
+ if (qstrcmp(currPPD->groups[gr].options[opt].keyword, key) == 0)
+ return &currPPD->groups[gr].options[opt];
+ }
+ }
+ }
+ return 0;
+}
+
+const cups_option_t* QCUPSSupport::printerOption(const QString &key) const
+{
+ for (int i = 0; i < printers[currPrinterIndex].num_options; ++i) {
+ if (QLatin1String(printers[currPrinterIndex].options[i].name) == key)
+ return &printers[currPrinterIndex].options[i];
+ }
+ return 0;
+}
+
+const ppd_option_t* QCUPSSupport::pageSizes() const
+{
+ return page_sizes;
+}
+
+int QCUPSSupport::markOption(const char* name, const char* value)
+{
+ return _ppdMarkOption(currPPD, name, value);
+}
+
+void QCUPSSupport::saveOptions(QList<const ppd_option_t*> options, QList<const char*> markedOptions)
+{
+ int oldOptionCount = printers[currPrinterIndex].num_options;
+ cups_option_t* oldOptions = printers[currPrinterIndex].options;
+
+ int newOptionCount = 0;
+ cups_option_t* newOptions = 0;
+
+ // copying old options that are not on the new list
+ for (int i = 0; i < oldOptionCount; ++i) {
+ bool contains = false;
+ for (int j = 0; j < options.count(); ++j) {
+ if (qstrcmp(options.at(j)->keyword, oldOptions[i].name) == 0) {
+ contains = true;
+ break;
+ }
+ }
+
+ if (!contains) {
+ newOptionCount = _cupsAddOption(oldOptions[i].name, oldOptions[i].value, newOptionCount, &newOptions);
+ }
+ }
+
+ // we can release old option list
+ _cupsFreeOptions(oldOptionCount, oldOptions);
+
+ // adding marked options
+ for (int i = 0; i < markedOptions.count(); ++i) {
+ const char* name = markedOptions.at(i);
+ ++i;
+ newOptionCount = _cupsAddOption(name, markedOptions.at(i), newOptionCount, &newOptions);
+ }
+
+ // placing the new option list
+ printers[currPrinterIndex].num_options = newOptionCount;
+ printers[currPrinterIndex].options = newOptions;
+
+ // saving new default values
+ _cupsSetDests(prnCount, printers);
+}
+
+QRect QCUPSSupport::paperRect(const char *choice) const
+{
+ if (!currPPD)
+ return QRect();
+ for (int i = 0; i < currPPD->num_sizes; ++i) {
+ if (qstrcmp(currPPD->sizes[i].name, choice) == 0)
+ return QRect(0, 0, qRound(currPPD->sizes[i].width), qRound(currPPD->sizes[i].length));
+ }
+ return QRect();
+}
+
+QRect QCUPSSupport::pageRect(const char *choice) const
+{
+ if (!currPPD)
+ return QRect();
+ for (int i = 0; i < currPPD->num_sizes; ++i) {
+ if (qstrcmp(currPPD->sizes[i].name, choice) == 0)
+ return QRect(qRound(currPPD->sizes[i].left),
+ qRound(currPPD->sizes[i].length - currPPD->sizes[i].top),
+ qRound(currPPD->sizes[i].right - currPPD->sizes[i].left),
+ qRound(currPPD->sizes[i].top - currPPD->sizes[i].bottom));
+ }
+ return QRect();
+}
+
+QStringList QCUPSSupport::options() const
+{
+ QStringList list;
+ collectMarkedOptions(list);
+ return list;
+}
+
+bool QCUPSSupport::printerHasPPD(const char *printerName)
+{
+ if (!isAvailable())
+ return false;
+ const char *ppdFile = _cupsGetPPD(printerName);
+ if (ppdFile)
+ unlink(ppdFile);
+ return (ppdFile != 0);
+}
+
+QString QCUPSSupport::unicodeString(const char *s)
+{
+#ifndef QT_NO_TEXTCODEC
+ return codec->toUnicode(s);
+#else
+ return QLatin1String(s);
+#endif
+}
+
+void QCUPSSupport::collectMarkedOptions(QStringList& list, const ppd_group_t* group) const
+{
+ if (group == 0) {
+ if (!currPPD)
+ return;
+ for (int i = 0; i < currPPD->num_groups; ++i) {
+ collectMarkedOptions(list, &currPPD->groups[i]);
+ collectMarkedOptionsHelper(list, &currPPD->groups[i]);
+ }
+ } else {
+ for (int i = 0; i < group->num_subgroups; ++i)
+ collectMarkedOptionsHelper(list, &group->subgroups[i]);
+ }
+}
+
+void QCUPSSupport::collectMarkedOptionsHelper(QStringList& list, const ppd_group_t* group) const
+{
+ for (int i = 0; i < group->num_options; ++i) {
+ for (int j = 0; j < group->options[i].num_choices; ++j) {
+ if (group->options[i].choices[j].marked == 1 && qstrcmp(group->options[i].choices[j].choice, group->options[i].defchoice) != 0)
+ list << QString::fromLocal8Bit(group->options[i].keyword) << QString::fromLocal8Bit(group->options[i].choices[j].choice);
+ }
+ }
+}
+
+QPair<int, QString> QCUPSSupport::tempFd()
+{
+ char filename[512];
+ int fd = _cupsTempFd(filename, 512);
+ return QPair<int, QString>(fd, QString::fromLocal8Bit(filename));
+}
+
+// Prints the given file and returns a job id.
+int QCUPSSupport::printFile(const char * printerName, const char * filename, const char * title,
+ int num_options, cups_option_t * options)
+{
+ return _cupsPrintFile(printerName, filename, title, num_options, options);
+}
+
+QCUPSSupport::Printer::Printer(const QString &n) : name(n), isDefault(false), cupsPrinterIndex(-1)
+{
+}
+
+QList<QCUPSSupport::Printer> QCUPSSupport::availableUnixPrinters()
+{
+ QList<Printer> printers;
+
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+ if (QCUPSSupport::isAvailable()) {
+ QCUPSSupport cups;
+ int cupsPrinterCount = cups.availablePrintersCount();
+ const cups_dest_t* cupsPrinters = cups.availablePrinters();
+ for (int i = 0; i < cupsPrinterCount; ++i) {
+ QString printerName(QString::fromLocal8Bit(cupsPrinters[i].name));
+ if (cupsPrinters[i].instance)
+ printerName += QLatin1Char('/') + QString::fromLocal8Bit(cupsPrinters[i].instance);
+
+ Printer p(printerName);
+ if (cupsPrinters[i].is_default)
+ p.isDefault = true;
+ p.cupsPrinterIndex = i;
+ printers.append(p);
+ }
+ } else
+#endif
+ {
+ QList<QPrinterDescription> lprPrinters;
+ int defprn = qt_getLprPrinters(lprPrinters);
+ // populating printer combo
+ foreach (const QPrinterDescription &description, lprPrinters)
+ printers.append(Printer(description.name));
+ if (defprn >= 0 && defprn < printers.size())
+ printers[defprn].isDefault = true;
+ }
+
+ return printers;
+}
+
+QList<QPrinter::PaperSize> QCUPSSupport::getCupsPrinterPaperSizes(int cupsPrinterIndex)
+{
+ return qt_getCupsPrinterPaperSizes(cupsPrinterIndex);
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_CUPS
diff --git a/src/printsupport/kernel/qcups_p.h b/src/printsupport/kernel/qcups_p.h
new file mode 100644
index 0000000000..cb7a79e486
--- /dev/null
+++ b/src/printsupport/kernel/qcups_p.h
@@ -0,0 +1,133 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCUPS_P_H
+#define QCUPS_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+#include "QtCore/qstring.h"
+#include "QtCore/qstringlist.h"
+#include "QtCore/qpair.h"
+#include "QtPrintSupport/qprinter.h"
+
+#ifndef QT_NO_CUPS
+#include <QtCore/qlibrary.h>
+#include <cups/cups.h>
+#include <cups/ppd.h>
+
+QT_BEGIN_NAMESPACE
+
+Q_DECLARE_TYPEINFO(cups_option_t, Q_MOVABLE_TYPE | Q_PRIMITIVE_TYPE);
+
+class Q_PRINTSUPPORT_EXPORT QCUPSSupport
+{
+public:
+ struct Printer
+ {
+ Printer(const QString &name = QString());
+
+ QString name;
+ bool isDefault;
+ int cupsPrinterIndex;
+ };
+ QCUPSSupport();
+ ~QCUPSSupport();
+
+ static bool isAvailable();
+ static int cupsVersion() { return isAvailable() ? CUPS_VERSION_MAJOR*10000+CUPS_VERSION_MINOR*100+CUPS_VERSION_PATCH : 0; }
+ int availablePrintersCount() const;
+ const cups_dest_t* availablePrinters() const;
+ int currentPrinterIndex() const;
+ const ppd_file_t* setCurrentPrinter(int index);
+
+ const ppd_file_t* currentPPD() const;
+ const ppd_option_t* ppdOption(const char *key) const;
+
+ const cups_option_t* printerOption(const QString &key) const;
+ const ppd_option_t* pageSizes() const;
+
+ int markOption(const char* name, const char* value);
+ void saveOptions(QList<const ppd_option_t*> options, QList<const char*> markedOptions);
+
+ QRect paperRect(const char *choice) const;
+ QRect pageRect(const char *choice) const;
+
+ QStringList options() const;
+
+ static bool printerHasPPD(const char *printerName);
+
+ QString unicodeString(const char *s);
+
+ QPair<int, QString> tempFd();
+ int printFile(const char * printerName, const char * filename, const char * title,
+ int num_options, cups_option_t * options);
+
+ static QList<Printer> availableUnixPrinters();
+ static QList<QPrinter::PaperSize> getCupsPrinterPaperSizes(int cupsPrinterIndex);
+
+private:
+ void collectMarkedOptions(QStringList& list, const ppd_group_t* group = 0) const;
+ void collectMarkedOptionsHelper(QStringList& list, const ppd_group_t* group) const;
+
+ int prnCount;
+ cups_dest_t *printers;
+ const ppd_option_t* page_sizes;
+ int currPrinterIndex;
+ ppd_file_t *currPPD;
+#ifndef QT_NO_TEXTCODEC
+ QTextCodec *codec;
+#endif
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_CUPS
+
+#endif
diff --git a/src/gui/painting/qpaintengine_alpha.cpp b/src/printsupport/kernel/qpaintengine_alpha.cpp
index beda2c7144..beda2c7144 100644
--- a/src/gui/painting/qpaintengine_alpha.cpp
+++ b/src/printsupport/kernel/qpaintengine_alpha.cpp
diff --git a/src/gui/painting/qpaintengine_alpha_p.h b/src/printsupport/kernel/qpaintengine_alpha_p.h
index 5694e2a5bc..5694e2a5bc 100644
--- a/src/gui/painting/qpaintengine_alpha_p.h
+++ b/src/printsupport/kernel/qpaintengine_alpha_p.h
diff --git a/src/printsupport/kernel/qpaintengine_preview.cpp b/src/printsupport/kernel/qpaintengine_preview.cpp
new file mode 100644
index 0000000000..3cf06f5770
--- /dev/null
+++ b/src/printsupport/kernel/qpaintengine_preview.cpp
@@ -0,0 +1,223 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <private/qpaintengine_preview_p.h>
+#include <private/qpainter_p.h>
+#include <private/qpaintengine_p.h>
+#include <private/qpicture_p.h>
+
+#include <QtPrintSupport/qprintengine.h>
+#include <QtGui/qpainter.h>
+#include <QtGui/qpicture.h>
+
+#ifndef QT_NO_PRINTPREVIEWWIDGET
+QT_BEGIN_NAMESPACE
+
+class QPreviewPaintEnginePrivate : public QPaintEnginePrivate
+{
+ Q_DECLARE_PUBLIC(QPreviewPaintEngine)
+public:
+ QPreviewPaintEnginePrivate() : state(QPrinter::Idle) {}
+ ~QPreviewPaintEnginePrivate() {}
+
+ QList<const QPicture *> pages;
+ QPaintEngine *engine;
+ QPainter *painter;
+ QPrinter::PrinterState state;
+
+ QPaintEngine *proxy_paint_engine;
+ QPrintEngine *proxy_print_engine;
+};
+
+
+QPreviewPaintEngine::QPreviewPaintEngine()
+ : QPaintEngine(*(new QPreviewPaintEnginePrivate), PaintEngineFeatures(AllFeatures & ~ObjectBoundingModeGradients))
+{
+ Q_D(QPreviewPaintEngine);
+ d->proxy_print_engine = 0;
+ d->proxy_paint_engine = 0;
+}
+
+QPreviewPaintEngine::~QPreviewPaintEngine()
+{
+ Q_D(QPreviewPaintEngine);
+
+ qDeleteAll(d->pages);
+}
+
+bool QPreviewPaintEngine::begin(QPaintDevice *)
+{
+ Q_D(QPreviewPaintEngine);
+
+ qDeleteAll(d->pages);
+ d->pages.clear();
+
+ QPicture *page = new QPicture;
+ page->d_func()->in_memory_only = true;
+ d->painter = new QPainter(page);
+ d->engine = d->painter->paintEngine();
+ d->pages.append(page);
+ d->state = QPrinter::Active;
+ return true;
+}
+
+bool QPreviewPaintEngine::end()
+{
+ Q_D(QPreviewPaintEngine);
+
+ delete d->painter;
+ d->painter = 0;
+ d->engine = 0;
+ d->state = QPrinter::Idle;
+ return true;
+}
+
+void QPreviewPaintEngine::updateState(const QPaintEngineState &state)
+{
+ Q_D(QPreviewPaintEngine);
+ d->engine->updateState(state);
+}
+
+void QPreviewPaintEngine::drawPath(const QPainterPath &path)
+{
+ Q_D(QPreviewPaintEngine);
+ d->engine->drawPath(path);
+}
+
+void QPreviewPaintEngine::drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode)
+{
+ Q_D(QPreviewPaintEngine);
+ d->engine->drawPolygon(points, pointCount, mode);
+}
+
+void QPreviewPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem)
+{
+ Q_D(QPreviewPaintEngine);
+ d->engine->drawTextItem(p, textItem);
+}
+
+void QPreviewPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr)
+{
+ Q_D(QPreviewPaintEngine);
+ d->engine->drawPixmap(r, pm, sr);
+}
+
+void QPreviewPaintEngine::drawTiledPixmap(const QRectF &r, const QPixmap &pm, const QPointF &p)
+{
+ Q_D(QPreviewPaintEngine);
+ d->engine->drawTiledPixmap(r, pm, p);
+}
+
+bool QPreviewPaintEngine::newPage()
+{
+ Q_D(QPreviewPaintEngine);
+
+ QPicture *page = new QPicture;
+ page->d_func()->in_memory_only = true;
+ QPainter *tmp_painter = new QPainter(page);
+ QPaintEngine *tmp_engine = tmp_painter->paintEngine();
+
+ // copy the painter state from the original painter
+ Q_ASSERT(painter()->d_func()->state && tmp_painter->d_func()->state);
+ *tmp_painter->d_func()->state = *painter()->d_func()->state;
+
+ // composition modes aren't supported on a QPrinter and yields a
+ // warning, so ignore it for now
+ tmp_engine->setDirty(DirtyFlags(AllDirty & ~DirtyCompositionMode));
+ tmp_engine->syncState();
+
+ delete d->painter;
+ d->painter = tmp_painter;
+ d->pages.append(page);
+ d->engine = tmp_engine;
+ return true;
+}
+
+bool QPreviewPaintEngine::abort()
+{
+ Q_D(QPreviewPaintEngine);
+ end();
+ qDeleteAll(d->pages);
+ d->state = QPrinter::Aborted;
+
+ return true;
+}
+
+QList<const QPicture *> QPreviewPaintEngine::pages()
+{
+ Q_D(QPreviewPaintEngine);
+ return d->pages;
+}
+
+void QPreviewPaintEngine::setProxyEngines(QPrintEngine *printEngine, QPaintEngine *paintEngine)
+{
+ Q_D(QPreviewPaintEngine);
+ d->proxy_print_engine = printEngine;
+ d->proxy_paint_engine = paintEngine;
+}
+
+void QPreviewPaintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &value)
+{
+ Q_D(QPreviewPaintEngine);
+ d->proxy_print_engine->setProperty(key, value);
+}
+
+QVariant QPreviewPaintEngine::property(PrintEnginePropertyKey key) const
+{
+ Q_D(const QPreviewPaintEngine);
+ return d->proxy_print_engine->property(key);
+}
+
+int QPreviewPaintEngine::metric(QPaintDevice::PaintDeviceMetric id) const
+{
+ Q_D(const QPreviewPaintEngine);
+ return d->proxy_print_engine->metric(id);
+}
+
+QPrinter::PrinterState QPreviewPaintEngine::printerState() const
+{
+ Q_D(const QPreviewPaintEngine);
+ return d->state;
+}
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/printsupport/kernel/qpaintengine_preview_p.h b/src/printsupport/kernel/qpaintengine_preview_p.h
new file mode 100644
index 0000000000..c2e11313c2
--- /dev/null
+++ b/src/printsupport/kernel/qpaintengine_preview_p.h
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPREVIEWPAINTENGINE_P_H
+#define QPREVIEWPAINTENGINE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of QPreviewPrinter and friends. This header file may change from
+// version to version without notice, or even be removed.
+//
+// We mean it.
+//
+//
+
+#include <QtGui/qpaintengine.h>
+#include <QtPrintSupport/qprintengine.h>
+
+#ifndef QT_NO_PRINTPREVIEWWIDGET
+
+QT_BEGIN_NAMESPACE
+
+class QPreviewPaintEnginePrivate;
+
+class QPreviewPaintEngine : public QPaintEngine, public QPrintEngine
+{
+ Q_DECLARE_PRIVATE(QPreviewPaintEngine)
+public:
+ QPreviewPaintEngine();
+ ~QPreviewPaintEngine();
+
+ bool begin(QPaintDevice *dev);
+ bool end();
+
+ void updateState(const QPaintEngineState &state);
+
+ void drawPath(const QPainterPath &path);
+ void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode);
+ void drawTextItem(const QPointF &p, const QTextItem &textItem);
+
+ void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr);
+ void drawTiledPixmap(const QRectF &r, const QPixmap &pm, const QPointF &p);
+
+ QList<const QPicture *> pages();
+
+ QPaintEngine::Type type() const { return Picture; }
+
+ void setProxyEngines(QPrintEngine *printEngine, QPaintEngine *paintEngine);
+
+ void setProperty(PrintEnginePropertyKey key, const QVariant &value);
+ QVariant property(PrintEnginePropertyKey key) const;
+
+ bool newPage();
+ bool abort();
+
+ int metric(QPaintDevice::PaintDeviceMetric) const;
+
+ QPrinter::PrinterState printerState() const;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_PRINTPREVIEWWIDGET
+
+#endif
diff --git a/src/printsupport/kernel/qplatformprintersupport_qpa.cpp b/src/printsupport/kernel/qplatformprintersupport_qpa.cpp
new file mode 100644
index 0000000000..3c11b3304c
--- /dev/null
+++ b/src/printsupport/kernel/qplatformprintersupport_qpa.cpp
@@ -0,0 +1,133 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qplatformprintersupport_qpa.h"
+
+#include <QtPrintSupport/qprinterinfo.h>
+
+#include <private/qprinterinfo_p.h>
+
+#ifndef QT_NO_PRINTER
+
+QT_BEGIN_NAMESPACE
+
+QPlatformPrinterSupport::QPlatformPrinterSupport()
+{
+}
+
+QPlatformPrinterSupport::~QPlatformPrinterSupport()
+{
+}
+
+QPrintEngine *QPlatformPrinterSupport::createNativePrintEngine(QPrinter::PrinterMode)
+{
+ return 0;
+}
+
+QPaintEngine *QPlatformPrinterSupport::createPaintEngine(QPrintEngine *, QPrinter::PrinterMode)
+{
+ return 0;
+}
+
+QList<QPrinter::PaperSize> QPlatformPrinterSupport::supportedPaperSizes(const QPrinterInfo &) const
+{
+ return QList<QPrinter::PaperSize>();
+}
+
+QList<QPrinterInfo> QPlatformPrinterSupport::availablePrinters()
+{
+ return QList<QPrinterInfo>();
+}
+
+QPrinterInfo QPlatformPrinterSupport::defaultPrinter()
+{
+ const QList<QPrinterInfo> printers = availablePrinters();
+ foreach (const QPrinterInfo &printerInfo, printers) {
+ if (printerInfo.isDefault())
+ return printerInfo;
+ }
+ return printers.isEmpty() ? QPrinterInfo() : printers.front();
+}
+
+QPrinterInfo QPlatformPrinterSupport::printerInfo(const QString &printerName, bool isDefault)
+{
+ QPrinterInfo pi = QPrinterInfo(printerName);
+ pi.d_func()->isDefault = isDefault;
+ return pi;
+}
+
+void QPlatformPrinterSupport::setPrinterInfoDefault(QPrinterInfo *p, bool isDefault)
+{
+ p->d_func()->isDefault = isDefault;
+}
+
+bool QPlatformPrinterSupport::printerInfoIsDefault(const QPrinterInfo &p)
+{
+ return p.d_func()->isDefault;
+}
+
+int QPlatformPrinterSupport::printerInfoCupsPrinterIndex(const QPrinterInfo &p)
+{
+ int i = -1;
+#if (defined(Q_OS_UNIX) && !defined(Q_OS_MAC) && !defined(Q_OS_SYMBIAN)) || defined(Q_WS_QPA)
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+ if (!p.isNull())
+ return i = p.d_func()->cupsPrinterIndex;
+#endif
+#endif
+ Q_UNUSED(p)
+ return i;
+}
+
+void QPlatformPrinterSupport::setPrinterInfoCupsPrinterIndex(QPrinterInfo *p, int index)
+{
+#if (defined(Q_OS_UNIX) && !defined(Q_OS_MAC) && !defined(Q_OS_SYMBIAN)) || defined(Q_WS_QPA)
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+ p->d_func()->cupsPrinterIndex = index;
+#endif
+#endif
+ Q_UNUSED(p)
+ Q_UNUSED(index)
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_PRINTER
diff --git a/src/printsupport/kernel/qplatformprintersupport_qpa.h b/src/printsupport/kernel/qplatformprintersupport_qpa.h
new file mode 100644
index 0000000000..800713c5bb
--- /dev/null
+++ b/src/printsupport/kernel/qplatformprintersupport_qpa.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPLATFORMPRINTINGSUPPORT_H
+#define QPLATFORMPRINTINGSUPPORT_H
+
+#include <QtPrintSupport/qprinter.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_PRINTER
+
+class QPrintEngine;
+
+class Q_PRINTSUPPORT_EXPORT QPlatformPrinterSupport
+{
+public:
+ QPlatformPrinterSupport();
+ virtual ~QPlatformPrinterSupport();
+
+ virtual QPrintEngine *createNativePrintEngine(QPrinter::PrinterMode printerMode);
+ virtual QPaintEngine *createPaintEngine(QPrintEngine *, QPrinter::PrinterMode printerMode);
+ virtual QList<QPrinter::PaperSize> supportedPaperSizes(const QPrinterInfo &) const;
+
+ virtual QList<QPrinterInfo> availablePrinters();
+ virtual QPrinterInfo defaultPrinter();
+
+protected:
+ static QPrinterInfo printerInfo(const QString &printerName, bool isDefault = false);
+ static void setPrinterInfoDefault(QPrinterInfo *p, bool isDefault);
+ static bool printerInfoIsDefault(const QPrinterInfo &p);
+ static int printerInfoCupsPrinterIndex(const QPrinterInfo &p);
+ static void setPrinterInfoCupsPrinterIndex(QPrinterInfo *p, int index);
+};
+
+#endif // QT_NO_PRINTER
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QPLATFORMPRINTINGSUPPORT_H
diff --git a/src/printsupport/kernel/qplatformprintplugin.cpp b/src/printsupport/kernel/qplatformprintplugin.cpp
new file mode 100644
index 0000000000..8b3c75127e
--- /dev/null
+++ b/src/printsupport/kernel/qplatformprintplugin.cpp
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qplatformprintplugin_qpa.h"
+#include "private/qfactoryloader_p.h"
+
+QT_BEGIN_NAMESPACE
+
+#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
+ (QPlatformPrinterSupportFactoryInterface_iid, QLatin1String("/printsupport"), Qt::CaseInsensitive))
+#endif
+
+QPlatformPrinterSupportPlugin::QPlatformPrinterSupportPlugin(QObject *parent)
+ : QObject(parent)
+{
+}
+
+QPlatformPrinterSupportPlugin::~QPlatformPrinterSupportPlugin()
+{
+}
+
+QPlatformPrinterSupport *QPlatformPrinterSupportPlugin::get()
+{
+ QStringList k = loader()->keys();
+ if (k.isEmpty())
+ return 0;
+ QPlatformPrinterSupportPlugin *plugin = qobject_cast<QPlatformPrinterSupportPlugin *>(loader()->instance(k.first()));
+ if (!plugin)
+ return 0;
+ return plugin->create(k.first());
+}
+
+QT_END_NAMESPACE
diff --git a/src/printsupport/kernel/qplatformprintplugin_qpa.h b/src/printsupport/kernel/qplatformprintplugin_qpa.h
new file mode 100644
index 0000000000..831a0546b0
--- /dev/null
+++ b/src/printsupport/kernel/qplatformprintplugin_qpa.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPLATFORMPRINTERSUPPORTPLUGIN_H
+#define QPLATFORMPRINTERSUPPORTPLUGIN_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qplugin.h>
+#include <QtCore/qfactoryinterface.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QPlatformPrinterSupport;
+
+struct QPlatformPrinterSupportFactoryInterface : public QFactoryInterface
+{
+ virtual QPlatformPrinterSupport *create(const QString &key) = 0;
+};
+
+#define QPlatformPrinterSupportFactoryInterface_iid "org.qt-project.QPlatformPrinterSupportFactoryInterface"
+
+Q_DECLARE_INTERFACE(QPlatformPrinterSupportFactoryInterface, QPlatformPrinterSupportFactoryInterface_iid)
+
+class Q_PRINTSUPPORT_EXPORT QPlatformPrinterSupportPlugin : public QObject, public QPlatformPrinterSupportFactoryInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QPlatformPrinterSupportFactoryInterface:QFactoryInterface)
+public:
+ explicit QPlatformPrinterSupportPlugin(QObject *parent = 0);
+ ~QPlatformPrinterSupportPlugin();
+
+ virtual QStringList keys() const = 0;
+ virtual QPlatformPrinterSupport *create(const QString &key) = 0;
+
+ static QPlatformPrinterSupport *get();
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QPLATFORMPRINTERSUPPORTPLUGIN_H
diff --git a/src/printsupport/kernel/qprintengine.h b/src/printsupport/kernel/qprintengine.h
new file mode 100644
index 0000000000..782b6ef8bd
--- /dev/null
+++ b/src/printsupport/kernel/qprintengine.h
@@ -0,0 +1,119 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPRINTENGINE_H
+#define QPRINTENGINE_H
+
+#include <QtCore/qvariant.h>
+#include <QtPrintSupport/qprinter.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_PRINTER
+
+class Q_PRINTSUPPORT_EXPORT QPrintEngine
+{
+public:
+ virtual ~QPrintEngine() {}
+ enum PrintEnginePropertyKey {
+ PPK_CollateCopies,
+ PPK_ColorMode,
+ PPK_Creator,
+ PPK_DocumentName,
+ PPK_FullPage,
+ PPK_NumberOfCopies,
+ PPK_Orientation,
+ PPK_OutputFileName,
+ PPK_PageOrder,
+ PPK_PageRect,
+ PPK_PageSize,
+ PPK_PaperRect,
+ PPK_PaperSource,
+ PPK_PrinterName,
+ PPK_PrinterProgram,
+ PPK_Resolution,
+ PPK_SelectionOption,
+ PPK_SupportedResolutions,
+
+ PPK_WindowsPageSize,
+ PPK_FontEmbedding,
+ PPK_SuppressSystemPrintStatus,
+
+ PPK_Duplex,
+
+ PPK_PaperSources,
+ PPK_CustomPaperSize,
+ PPK_PageMargins,
+ PPK_CopyCount,
+ PPK_SupportsMultipleCopies,
+ PPK_PaperSize = PPK_PageSize,
+
+ PPK_CustomBase = 0xff00
+ };
+
+ virtual void setProperty(PrintEnginePropertyKey key, const QVariant &value) = 0;
+ virtual QVariant property(PrintEnginePropertyKey key) const = 0;
+
+ virtual bool newPage() = 0;
+ virtual bool abort() = 0;
+
+ virtual int metric(QPaintDevice::PaintDeviceMetric) const = 0;
+
+ virtual QPrinter::PrinterState printerState() const = 0;
+
+#ifdef Q_WS_WIN
+ virtual HDC getPrinterDC() const { return 0; }
+ virtual void releasePrinterDC(HDC) const { }
+#endif
+
+};
+
+#endif // QT_NO_PRINTER
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QPRINTENGINE_H
diff --git a/src/printsupport/kernel/qprintengine_pdf.cpp b/src/printsupport/kernel/qprintengine_pdf.cpp
new file mode 100644
index 0000000000..c8ce2cfa0f
--- /dev/null
+++ b/src/printsupport/kernel/qprintengine_pdf.cpp
@@ -0,0 +1,666 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtPrintSupport/qprintengine.h>
+
+#include <qiodevice.h>
+#include <qfile.h>
+#include <qdebug.h>
+#include <qbuffer.h>
+#include "private/qcups_p.h"
+#include "qprinterinfo.h"
+
+#ifndef QT_NO_PRINTER
+#include <limits.h>
+#include <math.h>
+
+#include "qprintengine_pdf_p.h"
+
+#ifdef Q_OS_UNIX
+#include "private/qcore_unix_p.h" // overrides QT_OPEN
+#endif
+
+#ifdef Q_OS_WIN
+#include <io.h> // _close.
+#endif
+
+QT_BEGIN_NAMESPACE
+
+//#define FONT_DUMP
+
+extern QSizeF qt_paperSizeToQSizeF(QPrinter::PaperSize size);
+
+#define Q_MM(n) int((n * 720 + 127) / 254)
+#define Q_IN(n) int(n * 72)
+
+static const char * const psToStr[QPrinter::NPageSize+1] =
+{
+ "A4", "B5", "Letter", "Legal", "Executive",
+ "A0", "A1", "A2", "A3", "A5", "A6", "A7", "A8", "A9", "B0", "B1",
+ "B10", "B2", "B3", "B4", "B6", "B7", "B8", "B9", "C5E", "Comm10E",
+ "DLE", "Folio", "Ledger", "Tabloid", 0
+};
+
+QPdf::PaperSize QPdf::paperSize(QPrinter::PaperSize paperSize)
+{
+ QSizeF s = qt_paperSizeToQSizeF(paperSize);
+ PaperSize p = { Q_MM(s.width()), Q_MM(s.height()) };
+ return p;
+}
+
+const char *QPdf::paperSizeToString(QPrinter::PaperSize paperSize)
+{
+ return psToStr[paperSize];
+}
+
+
+QPdfPrintEngine::QPdfPrintEngine(QPrinter::PrinterMode m)
+ : QPdfEngine(*new QPdfPrintEnginePrivate(m))
+{
+ Q_D(QPdfPrintEngine);
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+ if (QCUPSSupport::isAvailable()) {
+ QCUPSSupport cups;
+ const cups_dest_t* printers = cups.availablePrinters();
+ int prnCount = cups.availablePrintersCount();
+
+ for (int i = 0; i < prnCount; ++i) {
+ if (printers[i].is_default) {
+ d->printerName = QString::fromLocal8Bit(printers[i].name);
+ break;
+ }
+ }
+
+ } else
+#endif
+ {
+ d->printerName = QString::fromLocal8Bit(qgetenv("PRINTER"));
+ if (d->printerName.isEmpty())
+ d->printerName = QString::fromLocal8Bit(qgetenv("LPDEST"));
+ if (d->printerName.isEmpty())
+ d->printerName = QString::fromLocal8Bit(qgetenv("NPRINTER"));
+ if (d->printerName.isEmpty())
+ d->printerName = QString::fromLocal8Bit(qgetenv("NGPRINTER"));
+ }
+
+ state = QPrinter::Idle;
+}
+
+QPdfPrintEngine::~QPdfPrintEngine()
+{
+}
+
+bool QPdfPrintEngine::begin(QPaintDevice *pdev)
+{
+ Q_D(QPdfPrintEngine);
+
+ if (!d->openPrintDevice()) {
+ state = QPrinter::Error;
+ return false;
+ }
+ state = QPrinter::Active;
+
+ return QPdfEngine::begin(pdev);
+}
+
+bool QPdfPrintEngine::end()
+{
+ Q_D(QPdfPrintEngine);
+
+ QPdfEngine::end();
+
+ d->closePrintDevice();
+ state = QPrinter::Idle;
+
+ return true;
+}
+
+bool QPdfPrintEngine::newPage()
+{
+ return QPdfEngine::newPage();
+}
+
+int QPdfPrintEngine::metric(QPaintDevice::PaintDeviceMetric m) const
+{
+ return QPdfEngine::metric(m);
+}
+
+void QPdfPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &value)
+{
+ Q_D(QPdfPrintEngine);
+
+ switch (int(key)) {
+ case PPK_CollateCopies:
+ d->collate = value.toBool();
+ break;
+ case PPK_ColorMode:
+ d->grayscale = (QPrinter::ColorMode(value.toInt()) == QPrinter::GrayScale);
+ break;
+ case PPK_Creator:
+ d->creator = value.toString();
+ break;
+ case PPK_DocumentName:
+ d->title = value.toString();
+ break;
+ case PPK_FullPage:
+ d->fullPage = value.toBool();
+ break;
+ case PPK_CopyCount: // fallthrough
+ case PPK_NumberOfCopies:
+ d->copies = value.toInt();
+ break;
+ case PPK_Orientation:
+ d->landscape = (QPrinter::Orientation(value.toInt()) == QPrinter::Landscape);
+ break;
+ case PPK_OutputFileName:
+ d->outputFileName = value.toString();
+ break;
+ case PPK_PageOrder:
+ d->pageOrder = QPrinter::PageOrder(value.toInt());
+ break;
+ case PPK_PaperSize:
+ d->printerPaperSize = QPrinter::PaperSize(value.toInt());
+ d->updatePaperSize();
+ break;
+ case PPK_PaperSource:
+ d->paperSource = QPrinter::PaperSource(value.toInt());
+ break;
+ case PPK_PrinterName:
+ d->printerName = value.toString();
+ break;
+ case PPK_PrinterProgram:
+ d->printProgram = value.toString();
+ break;
+ case PPK_Resolution:
+ d->resolution = value.toInt();
+ break;
+ case PPK_SelectionOption:
+ d->selectionOption = value.toString();
+ break;
+ case PPK_FontEmbedding:
+ d->embedFonts = value.toBool();
+ break;
+ case PPK_Duplex:
+ d->duplex = static_cast<QPrinter::DuplexMode> (value.toInt());
+ break;
+ case PPK_CupsPageRect:
+ d->cupsPageRect = value.toRect();
+ break;
+ case PPK_CupsPaperRect:
+ d->cupsPaperRect = value.toRect();
+ break;
+ case PPK_CupsOptions:
+ d->cupsOptions = value.toStringList();
+ break;
+ case PPK_CupsStringPageSize:
+ d->cupsStringPageSize = value.toString();
+ break;
+ case PPK_CustomPaperSize:
+ d->printerPaperSize = QPrinter::Custom;
+ d->customPaperSize = value.toSizeF();
+ d->updatePaperSize();
+ break;
+ case PPK_PageMargins:
+ {
+ QList<QVariant> margins(value.toList());
+ Q_ASSERT(margins.size() == 4);
+ d->leftMargin = margins.at(0).toReal();
+ d->topMargin = margins.at(1).toReal();
+ d->rightMargin = margins.at(2).toReal();
+ d->bottomMargin = margins.at(3).toReal();
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+QVariant QPdfPrintEngine::property(PrintEnginePropertyKey key) const
+{
+ Q_D(const QPdfPrintEngine);
+
+ QVariant ret;
+ switch (int(key)) {
+ case PPK_CollateCopies:
+ ret = d->collate;
+ break;
+ case PPK_ColorMode:
+ ret = d->grayscale ? QPrinter::GrayScale : QPrinter::Color;
+ break;
+ case PPK_Creator:
+ ret = d->creator;
+ break;
+ case PPK_DocumentName:
+ ret = d->title;
+ break;
+ case PPK_FullPage:
+ ret = d->fullPage;
+ break;
+ case PPK_CopyCount:
+ ret = d->copies;
+ break;
+ case PPK_SupportsMultipleCopies:
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+ if (QCUPSSupport::isAvailable())
+ ret = true;
+ else
+#endif
+ ret = false;
+ break;
+ case PPK_NumberOfCopies:
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+ if (QCUPSSupport::isAvailable())
+ ret = 1;
+ else
+#endif
+ ret = d->copies;
+ break;
+ case PPK_Orientation:
+ ret = d->landscape ? QPrinter::Landscape : QPrinter::Portrait;
+ break;
+ case PPK_OutputFileName:
+ ret = d->outputFileName;
+ break;
+ case PPK_PageOrder:
+ ret = d->pageOrder;
+ break;
+ case PPK_PaperSize:
+ ret = d->paperSize;
+ break;
+ case PPK_PaperSource:
+ ret = d->paperSource;
+ break;
+ case PPK_PrinterName:
+ ret = d->printerName;
+ break;
+ case PPK_PrinterProgram:
+ ret = d->printProgram;
+ break;
+ case PPK_Resolution:
+ ret = d->resolution;
+ break;
+ case PPK_SupportedResolutions:
+ ret = QList<QVariant>() << 72;
+ break;
+ case PPK_PaperRect:
+ ret = d->paperRect();
+ break;
+ case PPK_PageRect:
+ ret = d->pageRect();
+ break;
+ case PPK_SelectionOption:
+ ret = d->selectionOption;
+ break;
+ case PPK_FontEmbedding:
+ ret = d->embedFonts;
+ break;
+ case PPK_Duplex:
+ ret = d->duplex;
+ break;
+ case PPK_CupsPageRect:
+ ret = d->cupsPageRect;
+ break;
+ case PPK_CupsPaperRect:
+ ret = d->cupsPaperRect;
+ break;
+ case PPK_CupsOptions:
+ ret = d->cupsOptions;
+ break;
+ case PPK_CupsStringPageSize:
+ ret = d->cupsStringPageSize;
+ break;
+ case PPK_CustomPaperSize:
+ ret = d->customPaperSize;
+ break;
+ case PPK_PageMargins:
+ {
+ QList<QVariant> margins;
+ margins << d->leftMargin << d->topMargin
+ << d->rightMargin << d->bottomMargin;
+ ret = margins;
+ break;
+ }
+ default:
+ break;
+ }
+ return ret;
+}
+
+
+#ifndef QT_NO_LPR
+static void closeAllOpenFds()
+{
+ // hack time... getting the maximum number of open
+ // files, if possible. if not we assume it's the
+ // larger of 256 and the fd we got
+ int i;
+#if defined(_SC_OPEN_MAX)
+ i = (int)sysconf(_SC_OPEN_MAX);
+#elif defined(_POSIX_OPEN_MAX)
+ i = (int)_POSIX_OPEN_MAX;
+#elif defined(OPEN_MAX)
+ i = (int)OPEN_MAX;
+#else
+ i = 256;
+#endif
+ // leave stdin/out/err untouched
+ while(--i > 2)
+ QT_CLOSE(i);
+}
+#endif
+
+bool QPdfPrintEnginePrivate::openPrintDevice()
+{
+ if (outDevice)
+ return false;
+
+ if (!outputFileName.isEmpty()) {
+ QFile *file = new QFile(outputFileName);
+ if (! file->open(QFile::WriteOnly|QFile::Truncate)) {
+ delete file;
+ return false;
+ }
+ outDevice = file;
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+ } else if (QCUPSSupport::isAvailable()) {
+ QCUPSSupport cups;
+ QPair<int, QString> ret = cups.tempFd();
+ if (ret.first < 0) {
+ qWarning("QPdfPrinter: Could not open temporary file to print");
+ return false;
+ }
+ cupsTempFile = ret.second;
+ outDevice = new QFile();
+ static_cast<QFile *>(outDevice)->open(ret.first, QIODevice::WriteOnly);
+#endif
+#ifndef QT_NO_LPR
+ } else {
+ QString pr;
+ if (!printerName.isEmpty())
+ pr = printerName;
+ int fds[2];
+ if (qt_safe_pipe(fds) != 0) {
+ qWarning("QPdfPrinter: Could not open pipe to print");
+ return false;
+ }
+
+ pid_t pid = fork();
+ if (pid == 0) { // child process
+ // if possible, exit quickly, so the actual lp/lpr
+ // becomes a child of init, and ::waitpid() is
+ // guaranteed not to wait.
+ if (fork() > 0) {
+ closeAllOpenFds();
+
+ // try to replace this process with "true" - this prevents
+ // global destructors from being called (that could possibly
+ // do wrong things to the parent process)
+ (void)execlp("true", "true", (char *)0);
+ (void)execl("/bin/true", "true", (char *)0);
+ (void)execl("/usr/bin/true", "true", (char *)0);
+ ::_exit(0);
+ }
+ qt_safe_dup2(fds[0], 0, 0);
+
+ closeAllOpenFds();
+
+ if (!printProgram.isEmpty()) {
+ if (!selectionOption.isEmpty())
+ pr.prepend(selectionOption);
+ else
+ pr.prepend(QLatin1String("-P"));
+ (void)execlp(printProgram.toLocal8Bit().data(), printProgram.toLocal8Bit().data(),
+ pr.toLocal8Bit().data(), (char *)0);
+ } else {
+ // if no print program has been specified, be smart
+ // about the option string too.
+ QList<QByteArray> lprhack;
+ QList<QByteArray> lphack;
+ QByteArray media;
+ if (!pr.isEmpty() || !selectionOption.isEmpty()) {
+ if (!selectionOption.isEmpty()) {
+ QStringList list = selectionOption.split(QLatin1Char(' '));
+ for (int i = 0; i < list.size(); ++i)
+ lprhack.append(list.at(i).toLocal8Bit());
+ lphack = lprhack;
+ } else {
+ lprhack.append("-P");
+ lphack.append("-d");
+ }
+ lprhack.append(pr.toLocal8Bit());
+ lphack.append(pr.toLocal8Bit());
+ }
+ lphack.append("-s");
+
+ char ** lpargs = new char *[lphack.size()+6];
+ char lp[] = "lp";
+ lpargs[0] = lp;
+ int i;
+ for (i = 0; i < lphack.size(); ++i)
+ lpargs[i+1] = (char *)lphack.at(i).constData();
+#ifndef Q_OS_OSF
+ if (QPdf::paperSizeToString(printerPaperSize)) {
+ char dash_o[] = "-o";
+ lpargs[++i] = dash_o;
+ lpargs[++i] = const_cast<char *>(QPdf::paperSizeToString(printerPaperSize));
+ lpargs[++i] = dash_o;
+ media = "media=";
+ media += QPdf::paperSizeToString(printerPaperSize);
+ lpargs[++i] = media.data();
+ }
+#endif
+ lpargs[++i] = 0;
+ char **lprargs = new char *[lprhack.size()+2];
+ char lpr[] = "lpr";
+ lprargs[0] = lpr;
+ for (int i = 0; i < lprhack.size(); ++i)
+ lprargs[i+1] = (char *)lprhack[i].constData();
+ lprargs[lprhack.size() + 1] = 0;
+ (void)execvp("lp", lpargs);
+ (void)execvp("lpr", lprargs);
+ (void)execv("/bin/lp", lpargs);
+ (void)execv("/bin/lpr", lprargs);
+ (void)execv("/usr/bin/lp", lpargs);
+ (void)execv("/usr/bin/lpr", lprargs);
+
+ delete []lpargs;
+ delete []lprargs;
+ }
+ // if we couldn't exec anything, close the fd,
+ // wait for a second so the parent process (the
+ // child of the GUI process) has exited. then
+ // exit.
+ QT_CLOSE(0);
+ (void)::sleep(1);
+ ::_exit(0);
+ }
+ // parent process
+ QT_CLOSE(fds[0]);
+ fd = fds[1];
+ (void)qt_safe_waitpid(pid, 0, 0);
+
+ if (fd < 0)
+ return false;
+
+ outDevice = new QFile();
+ static_cast<QFile *>(outDevice)->open(fd, QIODevice::WriteOnly);
+#endif
+ }
+
+ return true;
+}
+
+void QPdfPrintEnginePrivate::closePrintDevice()
+{
+ if (outDevice) {
+ outDevice->close();
+ if (fd >= 0)
+ #if defined(Q_OS_WIN) && defined(_MSC_VER) && _MSC_VER >= 1400
+ ::_close(fd);
+ #else
+ ::close(fd);
+ #endif
+ fd = -1;
+ delete outDevice;
+ outDevice = 0;
+ }
+
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+ if (!cupsTempFile.isEmpty()) {
+ QString tempFile = cupsTempFile;
+ cupsTempFile.clear();
+ QCUPSSupport cups;
+
+ // Set up print options.
+ QByteArray prnName;
+ QList<QPair<QByteArray, QByteArray> > options;
+ QVector<cups_option_t> cupsOptStruct;
+
+ if (!printerName.isEmpty()) {
+ prnName = printerName.toLocal8Bit();
+ } else {
+ QPrinterInfo def = QPrinterInfo::defaultPrinter();
+ if (def.isNull()) {
+ qWarning("Could not determine printer to print to");
+ QFile::remove(tempFile);
+ return;
+ }
+ prnName = def.printerName().toLocal8Bit();
+ }
+
+ if (!cupsStringPageSize.isEmpty()) {
+ options.append(QPair<QByteArray, QByteArray>("media", cupsStringPageSize.toLocal8Bit()));
+ }
+
+ if (copies > 1) {
+ options.append(QPair<QByteArray, QByteArray>("copies", QString::number(copies).toLocal8Bit()));
+ }
+
+ if (collate) {
+ options.append(QPair<QByteArray, QByteArray>("Collate", "True"));
+ }
+
+ if (duplex != QPrinter::DuplexNone) {
+ switch(duplex) {
+ case QPrinter::DuplexNone: break;
+ case QPrinter::DuplexAuto:
+ if (!landscape)
+ options.append(QPair<QByteArray, QByteArray>("sides", "two-sided-long-edge"));
+ else
+ options.append(QPair<QByteArray, QByteArray>("sides", "two-sided-short-edge"));
+ break;
+ case QPrinter::DuplexLongSide:
+ options.append(QPair<QByteArray, QByteArray>("sides", "two-sided-long-edge"));
+ break;
+ case QPrinter::DuplexShortSide:
+ options.append(QPair<QByteArray, QByteArray>("sides", "two-sided-short-edge"));
+ break;
+ }
+ }
+
+ if (QCUPSSupport::cupsVersion() >= 10300 && landscape) {
+ options.append(QPair<QByteArray, QByteArray>("landscape", ""));
+ }
+
+ QStringList::const_iterator it = cupsOptions.constBegin();
+ while (it != cupsOptions.constEnd()) {
+ options.append(QPair<QByteArray, QByteArray>((*it).toLocal8Bit(), (*(it+1)).toLocal8Bit()));
+ it += 2;
+ }
+
+ for (int c = 0; c < options.size(); ++c) {
+ cups_option_t opt;
+ opt.name = options[c].first.data();
+ opt.value = options[c].second.data();
+ cupsOptStruct.append(opt);
+ }
+
+ // Print the file.
+ cups_option_t* optPtr = cupsOptStruct.size() ? &cupsOptStruct.first() : 0;
+ cups.printFile(prnName.constData(), tempFile.toLocal8Bit().constData(),
+ title.toLocal8Bit().constData(), cupsOptStruct.size(), optPtr);
+
+ QFile::remove(tempFile);
+ }
+#endif
+}
+
+
+
+QPdfPrintEnginePrivate::QPdfPrintEnginePrivate(QPrinter::PrinterMode m)
+ : QPdfEnginePrivate(),
+ duplex(QPrinter::DuplexNone),
+ collate(false),
+ copies(1),
+ pageOrder(QPrinter::FirstPageFirst),
+ paperSource(QPrinter::Auto),
+ printerPaperSize(QPrinter::A4),
+ fd(-1)
+{
+ resolution = 72;
+ if (m == QPrinter::HighResolution)
+ resolution = 1200;
+ else if (m == QPrinter::ScreenResolution)
+ resolution = qt_defaultDpi();
+}
+
+QPdfPrintEnginePrivate::~QPdfPrintEnginePrivate()
+{
+}
+
+
+void QPdfPrintEnginePrivate::updatePaperSize()
+{
+ if (printerPaperSize == QPrinter::Custom) {
+ paperSize = customPaperSize;
+ } else if (!cupsPaperRect.isNull()) {
+ QRect r = cupsPaperRect;
+ paperSize = r.size();
+ } else{
+ QPdf::PaperSize s = QPdf::paperSize(printerPaperSize);
+ paperSize = QSize(s.width, s.height);
+ }
+}
+
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_PRINTER
diff --git a/src/printsupport/kernel/qprintengine_pdf_p.h b/src/printsupport/kernel/qprintengine_pdf_p.h
new file mode 100644
index 0000000000..483cde9af9
--- /dev/null
+++ b/src/printsupport/kernel/qprintengine_pdf_p.h
@@ -0,0 +1,165 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPRINTENGINE_PDF_P_H
+#define QPRINTENGINE_PDF_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "QtPrintSupport/qprintengine.h"
+
+#ifndef QT_NO_PRINTER
+#include "QtCore/qmap.h"
+#include "QtGui/qmatrix.h"
+#include "QtCore/qstring.h"
+#include "QtCore/qvector.h"
+#include "QtGui/qpaintengine.h"
+#include "QtGui/qpainterpath.h"
+#include "QtCore/qdatastream.h"
+
+#include "private/qfontengine_p.h"
+#include "private/qpdf_p.h"
+#include "private/qpaintengine_p.h"
+#include "qprintengine.h"
+
+QT_BEGIN_NAMESPACE
+
+class QImage;
+class QDataStream;
+class QPen;
+class QPointF;
+class QRegion;
+class QFile;
+class QPdfPrintEngine;
+
+#define PPK_CupsOptions QPrintEngine::PrintEnginePropertyKey(0xfe00)
+#define PPK_CupsPageRect QPrintEngine::PrintEnginePropertyKey(0xfe01)
+#define PPK_CupsPaperRect QPrintEngine::PrintEnginePropertyKey(0xfe02)
+#define PPK_CupsStringPageSize QPrintEngine::PrintEnginePropertyKey(0xfe03)
+
+namespace QPdf {
+
+ struct PaperSize {
+ int width, height; // in postscript points
+ };
+ Q_PRINTSUPPORT_EXPORT PaperSize paperSize(QPrinter::PaperSize paperSize);
+ Q_PRINTSUPPORT_EXPORT const char *paperSizeToString(QPrinter::PaperSize paperSize);
+}
+
+class QPdfPrintEnginePrivate;
+
+class QPdfPrintEngine : public QPdfEngine, public QPrintEngine
+{
+ Q_DECLARE_PRIVATE(QPdfPrintEngine)
+public:
+ QPdfPrintEngine(QPrinter::PrinterMode m);
+ virtual ~QPdfPrintEngine();
+
+ // reimplementations QPaintEngine
+ bool begin(QPaintDevice *pdev);
+ bool end();
+ // end reimplementations QPaintEngine
+
+ // reimplementations QPrintEngine
+ bool abort() {return false;}
+ QPrinter::PrinterState printerState() const {return state;}
+
+ bool newPage();
+ int metric(QPaintDevice::PaintDeviceMetric) const;
+ void setProperty(PrintEnginePropertyKey key, const QVariant &value);
+ QVariant property(PrintEnginePropertyKey key) const;
+ // end reimplementations QPrintEngine
+
+ QPrinter::PrinterState state;
+
+private:
+ Q_DISABLE_COPY(QPdfPrintEngine)
+};
+
+class QPdfPrintEnginePrivate : public QPdfEnginePrivate
+{
+ Q_DECLARE_PUBLIC(QPdfPrintEngine)
+public:
+ QPdfPrintEnginePrivate(QPrinter::PrinterMode m);
+ ~QPdfPrintEnginePrivate();
+
+ bool openPrintDevice();
+ void closePrintDevice();
+
+ void updatePaperSize();
+
+private:
+ Q_DISABLE_COPY(QPdfPrintEnginePrivate)
+
+ QString printerName;
+ QString printProgram;
+ QString selectionOption;
+ QStringList cupsOptions;
+ QString cupsStringPageSize;
+
+ QPrinter::DuplexMode duplex;
+ bool collate;
+ int copies;
+ QPrinter::PageOrder pageOrder;
+ QPrinter::PaperSource paperSource;
+
+ QPrinter::PaperSize printerPaperSize;
+ QRect cupsPaperRect;
+ QRect cupsPageRect;
+ QSizeF customPaperSize; // in postscript points
+
+ int fd;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_PRINTER
+
+#endif // QPRINTENGINE_PDF_P_H
diff --git a/src/printsupport/kernel/qprinter.cpp b/src/printsupport/kernel/qprinter.cpp
new file mode 100644
index 0000000000..ae215945d3
--- /dev/null
+++ b/src/printsupport/kernel/qprinter.cpp
@@ -0,0 +1,2264 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qprinter_p.h"
+#include "qprinter.h"
+#include "qprintengine.h"
+#include "qprinterinfo.h"
+#include "qlist.h"
+#include <qcoreapplication.h>
+#include <qfileinfo.h>
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+#include "private/qcups_p.h"
+#endif
+
+#ifndef QT_NO_PRINTER
+
+#include "qplatformprintplugin_qpa.h"
+#include <QtPrintSupport/QPlatformPrinterSupport>
+#include <private/qpagedpaintdevice_p.h>
+
+#if defined (Q_WS_WIN)
+#include <private/qprintengine_win_p.h>
+#elif defined (Q_WS_MAC)
+#include <private/qprintengine_mac_p.h>
+#elif defined (QTOPIA_PRINTENGINE)
+#include <private/qprintengine_qws_p.h>
+#endif
+
+#if defined(Q_WS_X11)
+#include <private/qt_x11_p.h>
+#endif
+
+#ifndef QT_NO_PDF
+#include "qprintengine_pdf_p.h"
+#endif
+
+#include <qpicture.h>
+#include <private/qpaintengine_preview_p.h>
+
+QT_BEGIN_NAMESPACE
+
+#define ABORT_IF_ACTIVE(location) \
+ if (d->printEngine->printerState() == QPrinter::Active) { \
+ qWarning("%s: Cannot be changed while printer is active", location); \
+ return; \
+ }
+
+// NB! This table needs to be in sync with QPrinter::PaperSize
+static const float qt_paperSizes[][2] = {
+ {210, 297}, // A4
+ {176, 250}, // B5
+ {215.9f, 279.4f}, // Letter
+ {215.9f, 355.6f}, // Legal
+ {190.5f, 254}, // Executive
+ {841, 1189}, // A0
+ {594, 841}, // A1
+ {420, 594}, // A2
+ {297, 420}, // A3
+ {148, 210}, // A5
+ {105, 148}, // A6
+ {74, 105}, // A7
+ {52, 74}, // A8
+ {37, 52}, // A8
+ {1000, 1414}, // B0
+ {707, 1000}, // B1
+ {31, 44}, // B10
+ {500, 707}, // B2
+ {353, 500}, // B3
+ {250, 353}, // B4
+ {125, 176}, // B6
+ {88, 125}, // B7
+ {62, 88}, // B8
+ {33, 62}, // B9
+ {163, 229}, // C5E
+ {105, 241}, // US Common
+ {110, 220}, // DLE
+ {210, 330}, // Folio
+ {431.8f, 279.4f}, // Ledger
+ {279.4f, 431.8f} // Tabloid
+};
+
+/// return the multiplier of converting from the unit value to postscript-points.
+Q_PRINTSUPPORT_EXPORT double qt_multiplierForUnit(QPrinter::Unit unit, int resolution)
+{
+ switch(unit) {
+ case QPrinter::Millimeter:
+ return 2.83464566929;
+ case QPrinter::Point:
+ return 1.0;
+ case QPrinter::Inch:
+ return 72.0;
+ case QPrinter::Pica:
+ return 12;
+ case QPrinter::Didot:
+ return 1.065826771;
+ case QPrinter::Cicero:
+ return 12.789921252;
+ case QPrinter::DevicePixel:
+ return 72.0/resolution;
+ }
+ return 1.0;
+}
+
+// not static: it's needed in qpagesetupdialog_unix.cpp
+Q_PRINTSUPPORT_EXPORT QSizeF qt_printerPaperSize(QPrinter::Orientation orientation,
+ QPrinter::PaperSize paperSize,
+ QPrinter::Unit unit,
+ int resolution)
+{
+ int width_index = 0;
+ int height_index = 1;
+ if (orientation == QPrinter::Landscape) {
+ width_index = 1;
+ height_index = 0;
+ }
+ const qreal multiplier = qt_multiplierForUnit(unit, resolution);
+ return QSizeF((qt_paperSizes[paperSize][width_index] * 72 / 25.4) / multiplier,
+ (qt_paperSizes[paperSize][height_index] * 72 / 25.4) / multiplier);
+}
+
+void QPrinterPrivate::createDefaultEngines()
+{
+ QPrinter::OutputFormat realOutputFormat = outputFormat;
+#if defined (Q_OS_UNIX) && ! defined (Q_WS_MAC)
+ if(outputFormat == QPrinter::NativeFormat) {
+ realOutputFormat = QPrinter::PdfFormat;
+ }
+#endif
+
+ switch (realOutputFormat) {
+ case QPrinter::NativeFormat: {
+#if defined (Q_WS_QPA)
+ QPlatformPrinterSupport *ps = QPlatformPrinterSupportPlugin::get();
+ if (ps) {
+ printEngine = ps->createNativePrintEngine(printerMode);
+ paintEngine = ps->createPaintEngine(printEngine, printerMode);
+ } else {
+ QPdfPrintEngine *pdfEngine = new QPdfPrintEngine(printerMode);
+ paintEngine = pdfEngine;
+ printEngine = pdfEngine;
+ }
+#elif defined (Q_WS_WIN)
+ QWin32PrintEngine *winEngine = new QWin32PrintEngine(printerMode);
+ paintEngine = winEngine;
+ printEngine = winEngine;
+#elif defined (Q_WS_MAC)
+ QMacPrintEngine *macEngine = new QMacPrintEngine(printerMode);
+ paintEngine = macEngine;
+ printEngine = macEngine;
+#elif defined (Q_OS_UNIX)
+ Q_ASSERT(false);
+#endif
+ }
+ break;
+ case QPrinter::PdfFormat: {
+ QPdfPrintEngine *pdfEngine = new QPdfPrintEngine(printerMode);
+ paintEngine = pdfEngine;
+ printEngine = pdfEngine;
+ }
+ break;
+ }
+ use_default_engine = true;
+ had_default_engines = true;
+}
+
+#ifndef QT_NO_PRINTPREVIEWWIDGET
+QList<const QPicture *> QPrinterPrivate::previewPages() const
+{
+ if (previewEngine)
+ return previewEngine->pages();
+ return QList<const QPicture *>();
+}
+
+void QPrinterPrivate::setPreviewMode(bool enable)
+{
+ Q_Q(QPrinter);
+ if (enable) {
+ if (!previewEngine)
+ previewEngine = new QPreviewPaintEngine;
+ had_default_engines = use_default_engine;
+ use_default_engine = false;
+ realPrintEngine = printEngine;
+ realPaintEngine = paintEngine;
+ q->setEngines(previewEngine, previewEngine);
+ previewEngine->setProxyEngines(realPrintEngine, realPaintEngine);
+ } else {
+ q->setEngines(realPrintEngine, realPaintEngine);
+ use_default_engine = had_default_engines;
+ }
+}
+#endif // QT_NO_PRINTPREVIEWWIDGET
+
+void QPrinterPrivate::addToManualSetList(QPrintEngine::PrintEnginePropertyKey key)
+{
+ for (int c = 0; c < manualSetList.size(); ++c) {
+ if (manualSetList[c] == key) return;
+ }
+ manualSetList.append(key);
+}
+
+
+/*!
+ \class QPrinter
+ \reentrant
+
+ \brief The QPrinter class is a paint device that paints on a printer.
+
+ \ingroup printing
+
+
+ This device represents a series of pages of printed output, and is
+ used in almost exactly the same way as other paint devices such as
+ QWidget and QPixmap.
+ A set of additional functions are provided to manage device-specific
+ features, such as orientation and resolution, and to step through
+ the pages in a document as it is generated.
+
+ When printing directly to a printer on Windows or Mac OS X, QPrinter uses
+ the built-in printer drivers. On X11, QPrinter uses the
+ \l{Common Unix Printing System (CUPS)} or the standard Unix \l lpr utility
+ to send 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
+ general, QPrinter passes these functions onto the underlying QPrintEngine.
+
+ The most important parameters are:
+ \list
+ \i setOrientation() tells QPrinter which page orientation to use.
+ \i setPaperSize() tells QPrinter what paper size to expect from the
+ printer.
+ \i setResolution() tells QPrinter what resolution you wish the
+ printer to provide, in dots per inch (DPI).
+ \i setFullPage() tells QPrinter whether you want to deal with the
+ full page or just with the part the printer can draw on.
+ \i setCopyCount() tells QPrinter how many copies of the document
+ it should print.
+ \endlist
+
+ Many of these functions can only be called before the actual printing
+ begins (i.e., before QPainter::begin() is called). This usually makes
+ sense because, for example, it's not possible to change the number of
+ copies when you are halfway through printing. There are also some
+ settings that the user sets (through the printer dialog) and that
+ applications are expected to obey. See QAbstractPrintDialog's
+ documentation for more details.
+
+ When QPainter::begin() is called, the QPrinter it operates on is prepared for
+ a new page, enabling the QPainter to be used immediately to paint the first
+ page in a document. Once the first page has been painted, newPage() can be
+ called to request a new blank page to paint on, or QPainter::end() can be
+ called to finish printing. The second page and all following pages are
+ prepared using a call to newPage() before they are painted.
+
+ The first page in a document does not need to be preceded by a call to
+ newPage(). You only need to calling newPage() after QPainter::begin() if you
+ need to insert a blank page at the beginning of a printed document.
+ Similarly, calling newPage() after the last page in a document is painted will
+ result in a trailing blank page appended to the end of the printed document.
+
+ If you want to abort the print job, abort() will try its best to
+ stop printing. It may cancel the entire job or just part of it.
+
+ Since QPrinter can print to any QPrintEngine subclass, it is possible to
+ extend printing support to cover new types of printing subsystem by
+ subclassing QPrintEngine and reimplementing its interface.
+
+ \sa QPrintDialog, {Printing with Qt}
+*/
+
+/*!
+ \enum QPrinter::PrinterState
+
+ \value Idle
+ \value Active
+ \value Aborted
+ \value Error
+*/
+
+/*!
+ \enum QPrinter::PrinterMode
+
+ This enum describes the mode the printer should work in. It
+ basically presets a certain resolution and working mode.
+
+ \value ScreenResolution Sets the resolution of the print device to
+ the screen resolution. This has the big advantage that the results
+ obtained when painting on the printer will match more or less
+ exactly the visible output on the screen. It is the easiest to
+ use, as font metrics on the screen and on the printer are the
+ same. This is the default value. ScreenResolution will produce a
+ lower quality output than HighResolution and should only be used
+ for drafts.
+
+ \value PrinterResolution This value is deprecated. Is is
+ equivalent to ScreenResolution on Unix and HighResolution on
+ Windows and Mac. Due do the difference between ScreenResolution
+ and HighResolution, use of this value may lead to non-portable
+ printer code.
+
+ \value HighResolution On Windows, sets the printer resolution to that
+ defined for the printer in use. For PDF printing, sets the
+ resolution of the PDF driver to 1200 dpi.
+
+ \note When rendering text on a QPrinter device, it is important
+ to realize that the size of text, when specified in points, is
+ independent of the resolution specified for the device itself.
+ Therefore, it may be useful to specify the font size in pixels
+ when combining text with graphics to ensure that their relative
+ sizes are what you expect.
+*/
+
+/*!
+ \enum QPrinter::Orientation
+
+ This enum type (not to be confused with \c Orientation) is used
+ to specify each page's orientation.
+
+ \value Portrait the page's height is greater than its width.
+
+ \value Landscape the page's width is greater than its height.
+
+ This type interacts with \l QPrinter::PaperSize and
+ QPrinter::setFullPage() to determine the final size of the page
+ available to the application.
+*/
+
+
+/*!
+ \enum QPrinter::PrintRange
+
+ Used to specify the print range selection option.
+
+ \value AllPages All pages should be printed.
+ \value Selection Only the selection should be printed.
+ \value PageRange The specified page range should be printed.
+ \value CurrentPage Only the current page should be printed.
+
+ \sa QAbstractPrintDialog::PrintRange
+*/
+
+/*!
+ \enum QPrinter::PrinterOption
+ \compat
+
+ Use QAbstractPrintDialog::PrintDialogOption instead.
+
+ \value PrintToFile
+ \value PrintSelection
+ \value PrintPageRange
+*/
+
+/*!
+ \enum QPrinter::PaperSize
+ \since 4.4
+
+ This enum type specifies what paper size QPrinter should use.
+ QPrinter does not check that the paper size is available; it just
+ uses this information, together with QPrinter::Orientation and
+ QPrinter::setFullPage(), to determine the printable area.
+
+ The defined sizes (with setFullPage(true)) are:
+
+ \value A0 841 x 1189 mm
+ \value A1 594 x 841 mm
+ \value A2 420 x 594 mm
+ \value A3 297 x 420 mm
+ \value A4 210 x 297 mm, 8.26 x 11.69 inches
+ \value A5 148 x 210 mm
+ \value A6 105 x 148 mm
+ \value A7 74 x 105 mm
+ \value A8 52 x 74 mm
+ \value A9 37 x 52 mm
+ \value B0 1000 x 1414 mm
+ \value B1 707 x 1000 mm
+ \value B2 500 x 707 mm
+ \value B3 353 x 500 mm
+ \value B4 250 x 353 mm
+ \value B5 176 x 250 mm, 6.93 x 9.84 inches
+ \value B6 125 x 176 mm
+ \value B7 88 x 125 mm
+ \value B8 62 x 88 mm
+ \value B9 33 x 62 mm
+ \value B10 31 x 44 mm
+ \value C5E 163 x 229 mm
+ \value Comm10E 105 x 241 mm, U.S. Common 10 Envelope
+ \value DLE 110 x 220 mm
+ \value Executive 7.5 x 10 inches, 190.5 x 254 mm
+ \value Folio 210 x 330 mm
+ \value Ledger 431.8 x 279.4 mm
+ \value Legal 8.5 x 14 inches, 215.9 x 355.6 mm
+ \value Letter 8.5 x 11 inches, 215.9 x 279.4 mm
+ \value Tabloid 279.4 x 431.8 mm
+ \value Custom Unknown, or a user defined size.
+
+ With setFullPage(false) (the default), the metrics will be a bit
+ smaller; how much depends on the printer in use.
+
+ \omitvalue NPageSize
+ \omitvalue NPaperSize
+*/
+
+
+/*!
+ \enum QPrinter::PageOrder
+
+ This enum type is used by QPrinter to tell the application program
+ how to print.
+
+ \value FirstPageFirst the lowest-numbered page should be printed
+ first.
+
+ \value LastPageFirst the highest-numbered page should be printed
+ first.
+*/
+
+/*!
+ \enum QPrinter::ColorMode
+
+ This enum type is used to indicate whether QPrinter should print
+ in color or not.
+
+ \value Color print in color if available, otherwise in grayscale.
+
+ \value GrayScale print in grayscale, even on color printers.
+*/
+
+/*!
+ \enum QPrinter::PaperSource
+
+ This enum type specifies what paper source QPrinter is to use.
+ QPrinter does not check that the paper source is available; it
+ just uses this information to try and set the paper source.
+ Whether it will set the paper source depends on whether the
+ printer has that particular source.
+
+ \warning This is currently only implemented for Windows.
+
+ \value Auto
+ \value Cassette
+ \value Envelope
+ \value EnvelopeManual
+ \value FormSource
+ \value LargeCapacity
+ \value LargeFormat
+ \value Lower
+ \value MaxPageSource
+ \value Middle
+ \value Manual
+ \value OnlyOne
+ \value Tractor
+ \value SmallFormat
+*/
+
+/*!
+ \enum QPrinter::Unit
+ \since 4.4
+
+ This enum type is used to specify the measurement unit for page and
+ paper sizes.
+
+ \value Millimeter
+ \value Point
+ \value Inch
+ \value Pica
+ \value Didot
+ \value Cicero
+ \value DevicePixel
+
+ Note the difference between Point and DevicePixel. The Point unit is
+ defined to be 1/72th of an inch, while the DevicePixel unit is
+ resolution dependant and is based on the actual pixels, or dots, on
+ the printer.
+*/
+
+
+/*
+ \enum QPrinter::PrintRange
+
+ This enum is used to specify which print range the application
+ should use to print.
+
+ \value AllPages All the pages should be printed.
+ \value Selection Only the selection should be printed.
+ \value PageRange Print according to the from page and to page options.
+ \value CurrentPage Only the current page should be printed.
+
+ \sa setPrintRange(), printRange()
+*/
+
+/*
+ \enum QPrinter::PrinterOption
+
+ This enum describes various printer options that appear in the
+ printer setup dialog. It is used to enable and disable these
+ options in the setup dialog.
+
+ \value PrintToFile Describes if print to file should be enabled.
+ \value PrintSelection Describes if printing selections should be enabled.
+ \value PrintPageRange Describes if printing page ranges (from, to) should
+ be enabled
+ \value PrintCurrentPage if Print Current Page option should be enabled
+
+ \sa setOptionEnabled(), isOptionEnabled()
+*/
+
+/*!
+ Creates a new printer object with the given \a mode.
+*/
+QPrinter::QPrinter(PrinterMode mode)
+ : QPagedPaintDevice(),
+ d_ptr(new QPrinterPrivate(this))
+{
+ init(mode);
+ QPrinterInfo defPrn(QPrinterInfo::defaultPrinter());
+ if (!defPrn.isNull()) {
+ setPrinterName(defPrn.printerName());
+ } else if (QPrinterInfo::availablePrinters().isEmpty()
+ && d_ptr->paintEngine->type() != QPaintEngine::Windows
+ && d_ptr->paintEngine->type() != QPaintEngine::MacPrinter) {
+ setOutputFormat(QPrinter::PdfFormat);
+ }
+}
+
+/*!
+ \since 4.4
+
+ Creates a new printer object with the given \a printer and \a mode.
+*/
+QPrinter::QPrinter(const QPrinterInfo& printer, PrinterMode mode)
+ : QPagedPaintDevice(),
+ d_ptr(new QPrinterPrivate(this))
+{
+ init(mode);
+ setPrinterName(printer.printerName());
+}
+
+void QPrinter::init(PrinterMode mode)
+{
+#if !defined(Q_WS_X11)
+ if (!QCoreApplication::instance()) {
+#else
+ if (!QCoreApplication::instance() || !X11) {
+#endif
+ qFatal("QPrinter: Must construct a QApplication before a QPaintDevice");
+ return;
+ }
+ Q_D(QPrinter);
+
+ d->printerMode = mode;
+ d->outputFormat = QPrinter::NativeFormat;
+ d->createDefaultEngines();
+
+#ifndef QT_NO_PRINTPREVIEWWIDGET
+ d->previewEngine = 0;
+#endif
+ d->realPrintEngine = 0;
+ d->realPaintEngine = 0;
+
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+ if (QCUPSSupport::cupsVersion() >= 10200 && QCUPSSupport().currentPPD()) {
+ setOutputFormat(QPrinter::PdfFormat);
+ d->outputFormat = QPrinter::NativeFormat;
+ }
+#endif
+}
+
+/*!
+ This function is used by subclasses of QPrinter to specify custom
+ print and paint engines (\a printEngine and \a paintEngine,
+ respectively).
+
+ QPrinter does not take ownership of the engines, so you need to
+ manage these engine instances yourself.
+
+ Note that changing the engines will reset the printer state and
+ all its properties.
+
+ \sa printEngine() paintEngine() setOutputFormat()
+
+ \since 4.1
+*/
+void QPrinter::setEngines(QPrintEngine *printEngine, QPaintEngine *paintEngine)
+{
+ Q_D(QPrinter);
+
+ if (d->use_default_engine)
+ delete d->printEngine;
+
+ d->printEngine = printEngine;
+ d->paintEngine = paintEngine;
+ d->use_default_engine = false;
+}
+
+/*!
+ Destroys the printer object and frees any allocated resources. If
+ the printer is destroyed while a print job is in progress this may
+ or may not affect the print job.
+*/
+QPrinter::~QPrinter()
+{
+ Q_D(QPrinter);
+ if (d->use_default_engine)
+ delete d->printEngine;
+#ifndef QT_NO_PRINTPREVIEWWIDGET
+ delete d->previewEngine;
+#endif
+}
+
+/*!
+ \enum QPrinter::OutputFormat
+
+ The OutputFormat enum is used to describe the format QPrinter should
+ use for printing.
+
+ \value NativeFormat QPrinter will print output using a method defined
+ by the platform it is running on. This mode is the default when printing
+ directly to a printer.
+
+ \value PdfFormat QPrinter will generate its output as a searchable PDF file.
+ This mode is the default when printing to a file.
+
+ \sa outputFormat(), setOutputFormat(), setOutputFileName()
+*/
+
+/*!
+ \since 4.1
+
+ Sets the output format for this printer to \a format.
+*/
+void QPrinter::setOutputFormat(OutputFormat format)
+{
+
+#ifndef QT_NO_PDF
+ Q_D(QPrinter);
+ if (d->validPrinter && d->outputFormat == format)
+ return;
+ d->outputFormat = format;
+
+ QPrintEngine *oldPrintEngine = d->printEngine;
+ const bool def_engine = d->use_default_engine;
+ d->printEngine = 0;
+
+ d->createDefaultEngines();
+
+ if (oldPrintEngine) {
+ for (int i = 0; i < d->manualSetList.size(); ++i) {
+ QPrintEngine::PrintEnginePropertyKey key = d->manualSetList[i];
+ QVariant prop;
+ // PPK_NumberOfCopies need special treatmeant since it in most cases
+ // will return 1, disregarding the actual value that was set
+ if (key == QPrintEngine::PPK_NumberOfCopies)
+ prop = QVariant(copyCount());
+ else
+ prop = oldPrintEngine->property(key);
+ if (prop.isValid())
+ d->printEngine->setProperty(key, prop);
+ }
+ }
+
+ if (def_engine)
+ delete oldPrintEngine;
+
+ if (d->outputFormat == QPrinter::PdfFormat)
+ d->validPrinter = true;
+#else
+ Q_UNUSED(format);
+#endif
+}
+
+/*!
+ \since 4.1
+
+ Returns the output format for this printer.
+*/
+QPrinter::OutputFormat QPrinter::outputFormat() const
+{
+ Q_D(const QPrinter);
+ return d->outputFormat;
+}
+
+
+
+/*! \internal
+*/
+int QPrinter::devType() const
+{
+ return QInternal::Printer;
+}
+
+/*!
+ Returns the printer name. This value is initially set to the name
+ of the default printer.
+
+ \sa setPrinterName()
+*/
+QString QPrinter::printerName() const
+{
+ Q_D(const QPrinter);
+ return d->printEngine->property(QPrintEngine::PPK_PrinterName).toString();
+}
+
+/*!
+ Sets the printer name to \a name.
+
+ \sa printerName(), isValid()
+*/
+void QPrinter::setPrinterName(const QString &name)
+{
+ Q_D(QPrinter);
+ ABORT_IF_ACTIVE("QPrinter::setPrinterName");
+
+#if defined(Q_OS_UNIX) && !defined(QT_NO_CUPS)
+ if(d->use_default_engine && d->outputFormat == QPrinter::NativeFormat) {
+ setOutputFormat(QPrinter::PdfFormat);
+ d->outputFormat = QPrinter::NativeFormat;
+ }
+#endif
+
+ QList<QPrinterInfo> prnList = QPrinterInfo::availablePrinters();
+ if (name.isEmpty()) {
+ d->validPrinter = d->outputFormat == QPrinter::PdfFormat;
+ } else {
+ d->validPrinter = false;
+ for (int i = 0; i < prnList.size(); ++i) {
+ if (prnList[i].printerName() == name) {
+ d->validPrinter = true;
+ break;
+ }
+ }
+ }
+
+ d->printEngine->setProperty(QPrintEngine::PPK_PrinterName, name);
+ d->addToManualSetList(QPrintEngine::PPK_PrinterName);
+}
+
+
+/*!
+ \since 4.4
+
+ Returns true if the printer currently selected is a valid printer
+ in the system, or a pure PDF printer; otherwise returns false.
+
+ To detect other failures check the output of QPainter::begin() or QPrinter::newPage().
+
+ \snippet doc/src/snippets/printing-qprinter/errors.cpp 0
+
+ \sa setPrinterName()
+*/
+bool QPrinter::isValid() const
+{
+ Q_D(const QPrinter);
+#if defined(Q_WS_X11)
+ if (!qApp || !X11) {
+ return false;
+ }
+#endif
+ return d->validPrinter;
+}
+
+
+/*!
+ \fn bool QPrinter::outputToFile() const
+
+ Returns true if the output should be written to a file, or false
+ if the output should be sent directly to the printer. The default
+ setting is false.
+
+ \sa setOutputToFile(), setOutputFileName()
+*/
+
+
+/*!
+ \fn void QPrinter::setOutputToFile(bool enable)
+
+ Specifies whether the output should be written to a file or sent
+ directly to the printer.
+
+ Will output to a file if \a enable is true, or will output
+ directly to the printer if \a enable is false.
+
+ \sa outputToFile(), setOutputFileName()
+*/
+
+
+/*!
+ \fn QString QPrinter::outputFileName() const
+
+ Returns the name of the output file. By default, this is an empty string
+ (indicating that the printer shouldn't print to file).
+
+ \sa QPrintEngine::PrintEnginePropertyKey
+
+*/
+
+QString QPrinter::outputFileName() const
+{
+ Q_D(const QPrinter);
+ return d->printEngine->property(QPrintEngine::PPK_OutputFileName).toString();
+}
+
+/*!
+ Sets the name of the output file to \a fileName.
+
+ Setting a null or empty name (0 or "") disables printing to a file.
+ Setting a non-empty name enables printing to a file.
+
+ This can change the value of outputFormat().
+ If the file name has the ".pdf" suffix PDF is generated. If the file name
+ has a suffix other than ".pdf", the output format used is the
+ one set with setOutputFormat().
+
+ QPrinter uses Qt's cross-platform PDF print engines
+ respectively. If you can produce this format natively, for example
+ Mac OS X can generate PDF's from its print engine, set the output format
+ back to NativeFormat.
+
+ \sa outputFileName() setOutputToFile() setOutputFormat()
+*/
+
+void QPrinter::setOutputFileName(const QString &fileName)
+{
+ Q_D(QPrinter);
+ ABORT_IF_ACTIVE("QPrinter::setOutputFileName");
+
+ QFileInfo fi(fileName);
+ if (!fi.suffix().compare(QLatin1String("pdf"), Qt::CaseInsensitive))
+ setOutputFormat(QPrinter::PdfFormat);
+ else if (fileName.isEmpty())
+ setOutputFormat(QPrinter::NativeFormat);
+
+ d->printEngine->setProperty(QPrintEngine::PPK_OutputFileName, fileName);
+ d->addToManualSetList(QPrintEngine::PPK_OutputFileName);
+}
+
+
+/*!
+ Returns the name of the program that sends the print output to the
+ printer.
+
+ The default is to return an empty string; meaning that QPrinter will try to
+ be smart in a system-dependent way. On X11 only, you can set it to something
+ different to use a specific print program. On the other platforms, this
+ returns an empty string.
+
+ \sa setPrintProgram(), setPrinterSelectionOption()
+*/
+QString QPrinter::printProgram() const
+{
+ Q_D(const QPrinter);
+ return d->printEngine->property(QPrintEngine::PPK_PrinterProgram).toString();
+}
+
+
+/*!
+ Sets the name of the program that should do the print job to \a
+ printProg.
+
+ On X11, this function sets the program to call with the PDF
+ output. On other platforms, it has no effect.
+
+ \sa printProgram()
+*/
+void QPrinter::setPrintProgram(const QString &printProg)
+{
+ Q_D(QPrinter);
+ ABORT_IF_ACTIVE("QPrinter::setPrintProgram");
+ d->printEngine->setProperty(QPrintEngine::PPK_PrinterProgram, printProg);
+ d->addToManualSetList(QPrintEngine::PPK_PrinterProgram);
+}
+
+
+/*!
+ Returns the document name.
+
+ \sa setDocName(), QPrintEngine::PrintEnginePropertyKey
+*/
+QString QPrinter::docName() const
+{
+ Q_D(const QPrinter);
+ return d->printEngine->property(QPrintEngine::PPK_DocumentName).toString();
+}
+
+
+/*!
+ Sets the document name to \a name.
+
+ On X11, the document name is for example used as the default
+ output filename in QPrintDialog. Note that the document name does
+ not affect the file name if the printer is printing to a file.
+ Use the setOutputFile() function for this.
+
+ \sa docName(), QPrintEngine::PrintEnginePropertyKey
+*/
+void QPrinter::setDocName(const QString &name)
+{
+ Q_D(QPrinter);
+ ABORT_IF_ACTIVE("QPrinter::setDocName");
+ d->printEngine->setProperty(QPrintEngine::PPK_DocumentName, name);
+ d->addToManualSetList(QPrintEngine::PPK_DocumentName);
+}
+
+
+/*!
+ Returns the name of the application that created the document.
+
+ \sa setCreator()
+*/
+QString QPrinter::creator() const
+{
+ Q_D(const QPrinter);
+ return d->printEngine->property(QPrintEngine::PPK_Creator).toString();
+}
+
+
+/*!
+ Sets the name of the application that created the document to \a
+ creator.
+
+ This function is only applicable to the X11 version of Qt. If no
+ creator name is specified, the creator will be set to "Qt"
+ followed by some version number.
+
+ \sa creator()
+*/
+void QPrinter::setCreator(const QString &creator)
+{
+ Q_D(QPrinter);
+ ABORT_IF_ACTIVE("QPrinter::setCreator");
+ d->printEngine->setProperty(QPrintEngine::PPK_Creator, creator);
+ d->addToManualSetList(QPrintEngine::PPK_Creator);
+}
+
+
+/*!
+ Returns the orientation setting. This is driver-dependent, but is usually
+ QPrinter::Portrait.
+
+ \sa setOrientation()
+*/
+QPrinter::Orientation QPrinter::orientation() const
+{
+ Q_D(const QPrinter);
+ return QPrinter::Orientation(d->printEngine->property(QPrintEngine::PPK_Orientation).toInt());
+}
+
+
+/*!
+ Sets the print orientation to \a orientation.
+
+ The orientation can be either QPrinter::Portrait or
+ QPrinter::Landscape.
+
+ The printer driver reads this setting and prints using the
+ specified orientation.
+
+ On Windows, this option can be changed while printing and will
+ take effect from the next call to newPage().
+
+ On Mac OS X, changing the orientation during a print job has no effect.
+
+ \sa orientation()
+*/
+
+void QPrinter::setOrientation(Orientation orientation)
+{
+ Q_D(QPrinter);
+ d->printEngine->setProperty(QPrintEngine::PPK_Orientation, orientation);
+ d->addToManualSetList(QPrintEngine::PPK_Orientation);
+}
+
+
+/*!
+ \since 4.4
+ Returns the printer paper size. The default value is driver-dependent.
+
+ \sa setPaperSize() pageRect() paperRect()
+*/
+
+QPrinter::PaperSize QPrinter::paperSize() const
+{
+ Q_D(const QPrinter);
+ return QPrinter::PaperSize(d->printEngine->property(QPrintEngine::PPK_PaperSize).toInt());
+}
+
+/*!
+ \since 4.4
+
+ Sets the printer paper size to \a newPaperSize if that size is
+ supported. The result is undefined if \a newPaperSize is not
+ supported.
+
+ The default paper size is driver-dependent.
+
+ This function is useful mostly for setting a default value that
+ the user can override in the print dialog.
+
+ \sa paperSize() PaperSize setFullPage() setResolution() pageRect() paperRect()
+*/
+void QPrinter::setPaperSize(PaperSize newPaperSize)
+{
+ setPageSize(newPaperSize);
+}
+
+/*!
+ \obsolete
+
+ Returns the printer page size. The default value is driver-dependent.
+
+ Use paperSize() instead.
+*/
+QPrinter::PageSize QPrinter::pageSize() const
+{
+ return paperSize();
+}
+
+
+/*!
+ \obsolete
+
+ Sets the printer page size based on \a newPageSize.
+
+ Use setPaperSize() instead.
+*/
+
+void QPrinter::setPageSize(PageSize newPageSize)
+{
+ QPagedPaintDevice::setPageSize(newPageSize);
+
+ Q_D(QPrinter);
+ if (d->paintEngine->type() != QPaintEngine::Pdf)
+ ABORT_IF_ACTIVE("QPrinter::setPaperSize");
+ if (newPageSize < 0 || newPageSize >= NPageSize) {
+ qWarning("QPrinter::setPaperSize: Illegal paper size %d", newPageSize);
+ return;
+ }
+ d->printEngine->setProperty(QPrintEngine::PPK_PaperSize, newPageSize);
+ d->addToManualSetList(QPrintEngine::PPK_PaperSize);
+ d->hasUserSetPageSize = true;
+}
+
+/*!
+ \since 4.4
+
+ Sets the paper size based on \a paperSize in \a unit.
+
+ \sa paperSize()
+*/
+
+void QPrinter::setPaperSize(const QSizeF &paperSize, QPrinter::Unit unit)
+{
+ Q_D(QPrinter);
+ if (d->paintEngine->type() != QPaintEngine::Pdf)
+ ABORT_IF_ACTIVE("QPrinter::setPaperSize");
+ const qreal multiplier = qt_multiplierForUnit(unit, resolution());
+ QSizeF size(paperSize.width() * multiplier * 25.4/72., paperSize.height() * multiplier * 25.4/72.);
+ setPageSizeMM(size);
+}
+
+/*!
+ \reimp
+ */
+void QPrinter::setPageSizeMM(const QSizeF &size)
+{
+ Q_D(QPrinter);
+
+ QPagedPaintDevice::setPageSizeMM(size);
+
+ QSizeF s = size * 72./25.4;
+ d->printEngine->setProperty(QPrintEngine::PPK_CustomPaperSize, s);
+ d->addToManualSetList(QPrintEngine::PPK_CustomPaperSize);
+ d->hasUserSetPageSize = true;
+}
+
+/*!
+ \since 4.4
+
+ Returns the paper size in \a unit.
+
+ \sa setPaperSize()
+*/
+
+QSizeF QPrinter::paperSize(Unit unit) const
+{
+ Q_D(const QPrinter);
+ int res = resolution();
+ const qreal multiplier = qt_multiplierForUnit(unit, res);
+ PaperSize paperType = paperSize();
+ if (paperType == Custom) {
+ QSizeF size = d->printEngine->property(QPrintEngine::PPK_CustomPaperSize).toSizeF();
+ return QSizeF(size.width() / multiplier, size.height() / multiplier);
+ }
+ else {
+ return qt_printerPaperSize(orientation(), paperType, unit, res);
+ }
+}
+
+/*!
+ Sets the page order to \a pageOrder.
+
+ The page order can be QPrinter::FirstPageFirst or
+ QPrinter::LastPageFirst. The application is responsible for
+ reading the page order and printing accordingly.
+
+ This function is mostly useful for setting a default value that
+ the user can override in the print dialog.
+
+ This function is only supported under X11.
+*/
+
+void QPrinter::setPageOrder(PageOrder pageOrder)
+{
+ d->pageOrderAscending = (pageOrder == FirstPageFirst);
+
+ Q_D(QPrinter);
+ ABORT_IF_ACTIVE("QPrinter::setPageOrder");
+ d->printEngine->setProperty(QPrintEngine::PPK_PageOrder, pageOrder);
+ d->addToManualSetList(QPrintEngine::PPK_PageOrder);
+}
+
+
+/*!
+ Returns the current page order.
+
+ The default page order is \c FirstPageFirst.
+*/
+
+QPrinter::PageOrder QPrinter::pageOrder() const
+{
+ Q_D(const QPrinter);
+ return QPrinter::PageOrder(d->printEngine->property(QPrintEngine::PPK_PageOrder).toInt());
+}
+
+
+/*!
+ Sets the printer's color mode to \a newColorMode, which can be
+ either \c Color or \c GrayScale.
+
+ \sa colorMode()
+*/
+
+void QPrinter::setColorMode(ColorMode newColorMode)
+{
+ Q_D(QPrinter);
+ ABORT_IF_ACTIVE("QPrinter::setColorMode");
+ d->printEngine->setProperty(QPrintEngine::PPK_ColorMode, newColorMode);
+ d->addToManualSetList(QPrintEngine::PPK_ColorMode);
+}
+
+
+/*!
+ Returns the current color mode.
+
+ \sa setColorMode()
+*/
+QPrinter::ColorMode QPrinter::colorMode() const
+{
+ Q_D(const QPrinter);
+ return QPrinter::ColorMode(d->printEngine->property(QPrintEngine::PPK_ColorMode).toInt());
+}
+
+
+/*!
+ \obsolete
+ Returns the number of copies to be printed. The default value is 1.
+
+ On Windows, Mac OS X and X11 systems that support CUPS, this will always
+ return 1 as these operating systems can internally handle the number
+ of copies.
+
+ On X11, this value will return the number of times the application is
+ required to print in order to match the number specified in the printer setup
+ dialog. This has been done since some printer drivers are not capable of
+ buffering up the copies and in those cases the application must make an
+ explicit call to the print code for each copy.
+
+ Use copyCount() in conjunction with supportsMultipleCopies() instead.
+
+ \sa setNumCopies(), actualNumCopies()
+*/
+
+int QPrinter::numCopies() const
+{
+ Q_D(const QPrinter);
+ return d->printEngine->property(QPrintEngine::PPK_NumberOfCopies).toInt();
+}
+
+
+/*!
+ \obsolete
+ \since 4.6
+
+ Returns the number of copies that will be printed. The default
+ value is 1.
+
+ This function always returns the actual value specified in the print
+ dialog or using setNumCopies().
+
+ Use copyCount() instead.
+
+ \sa setNumCopies(), numCopies()
+*/
+int QPrinter::actualNumCopies() const
+{
+ return copyCount();
+}
+
+
+
+/*!
+ \obsolete
+ Sets the number of copies to be printed to \a numCopies.
+
+ The printer driver reads this setting and prints the specified
+ number of copies.
+
+ Use setCopyCount() instead.
+
+ \sa numCopies()
+*/
+
+void QPrinter::setNumCopies(int numCopies)
+{
+ Q_D(QPrinter);
+ ABORT_IF_ACTIVE("QPrinter::setNumCopies");
+ d->printEngine->setProperty(QPrintEngine::PPK_NumberOfCopies, numCopies);
+ d->addToManualSetList(QPrintEngine::PPK_NumberOfCopies);
+}
+
+/*!
+ \since 4.7
+
+ Sets the number of copies to be printed to \a count.
+
+ The printer driver reads this setting and prints the specified number of
+ copies.
+
+ \sa copyCount(), supportsMultipleCopies()
+*/
+
+void QPrinter::setCopyCount(int count)
+{
+ Q_D(QPrinter);
+ ABORT_IF_ACTIVE("QPrinter::setCopyCount;");
+ d->printEngine->setProperty(QPrintEngine::PPK_CopyCount, count);
+ d->addToManualSetList(QPrintEngine::PPK_CopyCount);
+}
+
+/*!
+ \since 4.7
+
+ Returns the number of copies that will be printed. The default value is 1.
+
+ \sa setCopyCount(), supportsMultipleCopies()
+*/
+
+int QPrinter::copyCount() const
+{
+ Q_D(const QPrinter);
+ return d->printEngine->property(QPrintEngine::PPK_CopyCount).toInt();
+}
+
+/*!
+ \since 4.7
+
+ Returns true if the printer supports printing multiple copies of the same
+ document in one job; otherwise false is returned.
+
+ On most systems this function will return true. However, on X11 systems
+ that do not support CUPS, this function will return false. That means the
+ application has to handle the number of copies by printing the same
+ document the required number of times.
+
+ \sa setCopyCount(), copyCount()
+*/
+
+bool QPrinter::supportsMultipleCopies() const
+{
+ Q_D(const QPrinter);
+ return d->printEngine->property(QPrintEngine::PPK_SupportsMultipleCopies).toBool();
+}
+
+/*!
+ \since 4.1
+
+ Returns true if collation is turned on when multiple copies is selected.
+ Returns false if it is turned off when multiple copies is selected.
+ When collating is turned off the printing of each individual page will be repeated
+ the numCopies() amount before the next page is started. With collating turned on
+ all pages are printed before the next copy of those pages is started.
+
+ \sa setCollateCopies()
+*/
+bool QPrinter::collateCopies() const
+{
+ Q_D(const QPrinter);
+ return d->printEngine->property(QPrintEngine::PPK_CollateCopies).toBool();
+}
+
+
+/*!
+ \since 4.1
+
+ Sets the default value for collation checkbox when the print
+ dialog appears. If \a collate is true, it will enable
+ setCollateCopiesEnabled(). The default value is false. This value
+ will be changed by what the user presses in the print dialog.
+
+ \sa collateCopies()
+*/
+void QPrinter::setCollateCopies(bool collate)
+{
+ Q_D(QPrinter);
+ ABORT_IF_ACTIVE("QPrinter::setCollateCopies");
+ d->printEngine->setProperty(QPrintEngine::PPK_CollateCopies, collate);
+ d->addToManualSetList(QPrintEngine::PPK_CollateCopies);
+}
+
+
+
+/*!
+ If \a fp is true, enables support for painting over the entire page;
+ otherwise restricts painting to the printable area reported by the
+ device.
+
+ By default, full page printing is disabled. In this case, the origin
+ of the QPrinter's coordinate system coincides with the top-left
+ corner of the printable area.
+
+ If full page printing is enabled, the origin of the QPrinter's
+ coordinate system coincides with the top-left corner of the paper
+ itself. In this case, the
+ \l{QPaintDevice::PaintDeviceMetric}{device metrics} will report
+ the exact same dimensions as indicated by \l{PaperSize}. It may not
+ be possible to print on the entire physical page because of the
+ printer's margins, so the application must account for the margins
+ itself.
+
+ \sa fullPage(), setPaperSize(), width(), height(), {Printing with Qt}
+*/
+
+void QPrinter::setFullPage(bool fp)
+{
+ Q_D(QPrinter);
+ d->printEngine->setProperty(QPrintEngine::PPK_FullPage, fp);
+ d->addToManualSetList(QPrintEngine::PPK_FullPage);
+}
+
+
+/*!
+ Returns true if the origin of the printer's coordinate system is
+ at the corner of the page and false if it is at the edge of the
+ printable area.
+
+ See setFullPage() for details and caveats.
+
+ \sa setFullPage() PaperSize
+*/
+
+bool QPrinter::fullPage() const
+{
+ Q_D(const QPrinter);
+ return d->printEngine->property(QPrintEngine::PPK_FullPage).toBool();
+}
+
+
+/*!
+ Requests that the printer prints at \a dpi or as near to \a dpi as
+ possible.
+
+ This setting affects the coordinate system as returned by, for
+ example QPainter::viewport().
+
+ This function must be called before QPainter::begin() to have an effect on
+ all platforms.
+
+ \sa resolution() setPaperSize()
+*/
+
+void QPrinter::setResolution(int dpi)
+{
+ Q_D(QPrinter);
+ ABORT_IF_ACTIVE("QPrinter::setResolution");
+ d->printEngine->setProperty(QPrintEngine::PPK_Resolution, dpi);
+ d->addToManualSetList(QPrintEngine::PPK_Resolution);
+}
+
+
+/*!
+ Returns the current assumed resolution of the printer, as set by
+ setResolution() or by the printer driver.
+
+ \sa setResolution()
+*/
+
+int QPrinter::resolution() const
+{
+ Q_D(const QPrinter);
+ return d->printEngine->property(QPrintEngine::PPK_Resolution).toInt();
+}
+
+/*!
+ Sets the paper source setting to \a source.
+
+ Windows only: This option can be changed while printing and will
+ take effect from the next call to newPage()
+
+ \sa paperSource()
+*/
+
+void QPrinter::setPaperSource(PaperSource source)
+{
+ Q_D(QPrinter);
+ d->printEngine->setProperty(QPrintEngine::PPK_PaperSource, source);
+ d->addToManualSetList(QPrintEngine::PPK_PaperSource);
+}
+
+/*!
+ Returns the printer's paper source. This is \c Manual or a printer
+ tray or paper cassette.
+*/
+QPrinter::PaperSource QPrinter::paperSource() const
+{
+ Q_D(const QPrinter);
+ return QPrinter::PaperSource(d->printEngine->property(QPrintEngine::PPK_PaperSource).toInt());
+}
+
+
+/*!
+ \since 4.1
+
+ Enabled or disables font embedding depending on \a enable.
+
+ Currently this option is only supported on X11.
+
+ \sa fontEmbeddingEnabled()
+*/
+void QPrinter::setFontEmbeddingEnabled(bool enable)
+{
+ Q_D(QPrinter);
+ d->printEngine->setProperty(QPrintEngine::PPK_FontEmbedding, enable);
+ d->addToManualSetList(QPrintEngine::PPK_FontEmbedding);
+}
+
+/*!
+ \since 4.1
+
+ Returns true if font embedding is enabled.
+
+ Currently this option is only supported on X11.
+
+ \sa setFontEmbeddingEnabled()
+*/
+bool QPrinter::fontEmbeddingEnabled() const
+{
+ Q_D(const QPrinter);
+ return d->printEngine->property(QPrintEngine::PPK_FontEmbedding).toBool();
+}
+
+/*!
+ \enum QPrinter::DuplexMode
+ \since 4.4
+
+ This enum is used to indicate whether printing will occur on one or both sides
+ of each sheet of paper (simplex or duplex printing).
+
+ \value DuplexNone Single sided (simplex) printing only.
+ \value DuplexAuto The printer's default setting is used to determine whether
+ duplex printing is used.
+ \value DuplexLongSide Both sides of each sheet of paper are used for printing.
+ The paper is turned over its longest edge before the second
+ side is printed
+ \value DuplexShortSide Both sides of each sheet of paper are used for printing.
+ The paper is turned over its shortest edge before the second
+ side is printed
+*/
+
+/*!
+ \since 4.2
+
+ Enables double sided printing if \a doubleSided is true; otherwise disables it.
+
+ Currently this option is only supported on X11.
+*/
+void QPrinter::setDoubleSidedPrinting(bool doubleSided)
+{
+ setDuplex(doubleSided ? DuplexAuto : DuplexNone);
+}
+
+
+/*!
+ \since 4.2
+
+ Returns true if double side printing is enabled.
+
+ Currently this option is only supported on X11.
+*/
+bool QPrinter::doubleSidedPrinting() const
+{
+ return duplex() != DuplexNone;
+}
+
+/*!
+ \since 4.4
+
+ Enables double sided printing based on the \a duplex mode.
+
+ Currently this option is only supported on X11.
+*/
+void QPrinter::setDuplex(DuplexMode duplex)
+{
+ Q_D(QPrinter);
+ d->printEngine->setProperty(QPrintEngine::PPK_Duplex, duplex);
+ d->addToManualSetList(QPrintEngine::PPK_Duplex);
+}
+
+/*!
+ \since 4.4
+
+ Returns the current duplex mode.
+
+ Currently this option is only supported on X11.
+*/
+QPrinter::DuplexMode QPrinter::duplex() const
+{
+ Q_D(const QPrinter);
+ return static_cast <DuplexMode> (d->printEngine->property(QPrintEngine::PPK_Duplex).toInt());
+}
+
+/*!
+ \since 4.4
+
+ Returns the page's rectangle in \a unit; this is usually smaller
+ than the paperRect() since the page normally has margins between
+ its borders and the paper.
+
+ \sa paperSize()
+*/
+QRectF QPrinter::pageRect(Unit unit) const
+{
+ Q_D(const QPrinter);
+ int res = resolution();
+ const qreal multiplier = qt_multiplierForUnit(unit, res);
+ // the page rect is in device pixels
+ QRect devRect(d->printEngine->property(QPrintEngine::PPK_PageRect).toRect());
+ if (unit == DevicePixel)
+ return devRect;
+ QRectF diRect(devRect.x()*72.0/res,
+ devRect.y()*72.0/res,
+ devRect.width()*72.0/res,
+ devRect.height()*72.0/res);
+ return QRectF(diRect.x()/multiplier, diRect.y()/multiplier,
+ diRect.width()/multiplier, diRect.height()/multiplier);
+}
+
+
+/*!
+ \since 4.4
+
+ Returns the paper's rectangle in \a unit; this is usually larger
+ than the pageRect().
+
+ \sa pageRect()
+*/
+QRectF QPrinter::paperRect(Unit unit) const
+{
+ Q_D(const QPrinter);
+ int res = resolution();
+ const qreal multiplier = qt_multiplierForUnit(unit, resolution());
+ // the page rect is in device pixels
+ QRect devRect(d->printEngine->property(QPrintEngine::PPK_PaperRect).toRect());
+ if (unit == DevicePixel)
+ return devRect;
+ QRectF diRect(devRect.x()*72.0/res,
+ devRect.y()*72.0/res,
+ devRect.width()*72.0/res,
+ devRect.height()*72.0/res);
+ return QRectF(diRect.x()/multiplier, diRect.y()/multiplier,
+ diRect.width()/multiplier, diRect.height()/multiplier);
+}
+
+/*!
+ Returns the page's rectangle; this is usually smaller than the
+ paperRect() since the page normally has margins between its
+ borders and the paper.
+
+ The unit of the returned rectangle is DevicePixel.
+
+ \sa paperSize()
+*/
+QRect QPrinter::pageRect() const
+{
+ Q_D(const QPrinter);
+ return d->printEngine->property(QPrintEngine::PPK_PageRect).toRect();
+}
+
+/*!
+ Returns the paper's rectangle; this is usually larger than the
+ pageRect().
+
+ The unit of the returned rectangle is DevicePixel.
+
+ \sa pageRect()
+*/
+QRect QPrinter::paperRect() const
+{
+ Q_D(const QPrinter);
+ return d->printEngine->property(QPrintEngine::PPK_PaperRect).toRect();
+}
+
+
+/*!
+ \since 4.4
+
+ This function sets the \a left, \a top, \a right and \a bottom
+ page margins for this printer. The unit of the margins are
+ specified with the \a unit parameter.
+*/
+void QPrinter::setPageMargins(qreal left, qreal top, qreal right, qreal bottom, QPrinter::Unit unit)
+{
+ const qreal multiplier = qt_multiplierForUnit(unit, resolution()) * 25.4/72.;
+ Margins m = { left*multiplier, right*multiplier, top*multiplier, bottom*multiplier };
+ setMargins(m);
+}
+
+/*!
+ reimp
+ */
+void QPrinter::setMargins(const Margins &m)
+{
+ Q_D(QPrinter);
+
+ const qreal multiplier = 72./25.4;
+ QList<QVariant> margins;
+ margins << (m.left * multiplier) << (m.top * multiplier)
+ << (m.right * multiplier) << (m.bottom * multiplier);
+ d->printEngine->setProperty(QPrintEngine::PPK_PageMargins, margins);
+ d->addToManualSetList(QPrintEngine::PPK_PageMargins);
+ d->hasCustomPageMargins = true;
+}
+
+
+/*!
+ \since 4.4
+
+ Returns the page margins for this printer in \a left, \a top, \a
+ right, \a bottom. The unit of the returned margins are specified
+ with the \a unit parameter.
+*/
+void QPrinter::getPageMargins(qreal *left, qreal *top, qreal *right, qreal *bottom, QPrinter::Unit unit) const
+{
+ Q_D(const QPrinter);
+ Q_ASSERT(left && top && right && bottom);
+ const qreal multiplier = qt_multiplierForUnit(unit, resolution());
+ QList<QVariant> margins(d->printEngine->property(QPrintEngine::PPK_PageMargins).toList());
+ *left = margins.at(0).toReal() / multiplier;
+ *top = margins.at(1).toReal() / multiplier;
+ *right = margins.at(2).toReal() / multiplier;
+ *bottom = margins.at(3).toReal() / multiplier;
+}
+
+/*!
+ \internal
+
+ Returns the metric for the given \a id.
+*/
+int QPrinter::metric(PaintDeviceMetric id) const
+{
+ Q_D(const QPrinter);
+ return d->printEngine->metric(id);
+}
+
+/*!
+ Returns the paint engine used by the printer.
+*/
+QPaintEngine *QPrinter::paintEngine() const
+{
+ Q_D(const QPrinter);
+ return d->paintEngine;
+}
+
+/*!
+ \since 4.1
+
+ Returns the print engine used by the printer.
+*/
+QPrintEngine *QPrinter::printEngine() const
+{
+ Q_D(const QPrinter);
+ return d->printEngine;
+}
+
+#if defined (Q_WS_WIN)
+/*!
+ Sets the page size to be used by the printer under Windows to \a
+ pageSize.
+
+ \warning This function is not portable so you may prefer to use
+ setPaperSize() instead.
+
+ \sa winPageSize()
+*/
+void QPrinter::setWinPageSize(int pageSize)
+{
+ Q_D(QPrinter);
+ ABORT_IF_ACTIVE("QPrinter::setWinPageSize");
+ d->printEngine->setProperty(QPrintEngine::PPK_WindowsPageSize, pageSize);
+ d->addToManualSetList(QPrintEngine::PPK_WindowsPageSize);
+}
+
+/*!
+ Returns the page size used by the printer under Windows.
+
+ \warning This function is not portable so you may prefer to use
+ paperSize() instead.
+
+ \sa setWinPageSize()
+*/
+int QPrinter::winPageSize() const
+{
+ Q_D(const QPrinter);
+ return d->printEngine->property(QPrintEngine::PPK_WindowsPageSize).toInt();
+}
+#endif // Q_WS_WIN
+
+/*!
+ Returns a list of the resolutions (a list of dots-per-inch
+ integers) that the printer says it supports.
+
+ For X11 where all printing is directly to PDF, this
+ function will always return a one item list containing only the
+ PDF resolution, i.e., 72 (72 dpi -- but see PrinterMode).
+*/
+QList<int> QPrinter::supportedResolutions() const
+{
+ Q_D(const QPrinter);
+ QList<QVariant> varlist
+ = d->printEngine->property(QPrintEngine::PPK_SupportedResolutions).toList();
+ QList<int> intlist;
+ for (int i=0; i<varlist.size(); ++i)
+ intlist << varlist.at(i).toInt();
+ return intlist;
+}
+
+/*!
+ Tells the printer to eject the current page and to continue
+ printing on a new page. Returns true if this was successful;
+ otherwise returns false.
+
+ Calling newPage() on an inactive QPrinter object will always
+ fail.
+*/
+bool QPrinter::newPage()
+{
+ Q_D(QPrinter);
+ if (d->printEngine->printerState() != QPrinter::Active)
+ return false;
+ return d->printEngine->newPage();
+}
+
+/*!
+ Aborts the current print run. Returns true if the print run was
+ successfully aborted and printerState() will return QPrinter::Aborted; otherwise
+ returns false.
+
+ It is not always possible to abort a print job. For example,
+ all the data has gone to the printer but the printer cannot or
+ will not cancel the job when asked to.
+*/
+bool QPrinter::abort()
+{
+ Q_D(QPrinter);
+ return d->printEngine->abort();
+}
+
+/*!
+ Returns the current state of the printer. This may not always be
+ accurate (for example if the printer doesn't have the capability
+ of reporting its state to the operating system).
+*/
+QPrinter::PrinterState QPrinter::printerState() const
+{
+ Q_D(const QPrinter);
+ return d->printEngine->printerState();
+}
+
+
+/*! \fn void QPrinter::margins(uint *top, uint *left, uint *bottom, uint *right) const
+
+ Sets *\a top, *\a left, *\a bottom, *\a right to be the top,
+ left, bottom, and right margins.
+
+ This function has been superseded by paperRect() and pageRect().
+ Use paperRect().top() - pageRect().top() for the top margin,
+ paperRect().left() - pageRect().left() for the left margin,
+ paperRect().bottom() - pageRect().bottom() for the bottom margin,
+ and papaerRect().right() - pageRect().right() for the right
+ margin.
+
+ \oldcode
+ uint rightMargin;
+ uint bottomMargin;
+ printer->margins(0, 0, &bottomMargin, &rightMargin);
+ \newcode
+ int rightMargin = printer->paperRect().right() - printer->pageRect().right();
+ int bottomMargin = printer->paperRect().bottom() - printer->pageRect().bottom();
+ \endcode
+*/
+
+/*! \fn QSize QPrinter::margins() const
+
+ \overload
+
+ Returns a QSize containing the left margin and the top margin.
+
+ This function has been superseded by paperRect() and pageRect().
+ Use paperRect().left() - pageRect().left() for the left margin,
+ and paperRect().top() - pageRect().top() for the top margin.
+
+ \oldcode
+ QSize margins = printer->margins();
+ int leftMargin = margins.width();
+ int topMargin = margins.height();
+ \newcode
+ int leftMargin = printer->paperRect().left() - printer->pageRect().left();
+ int topMargin = printer->paperRect().top() - printer->pageRect().top();
+ \endcode
+*/
+
+/*! \fn bool QPrinter::aborted()
+
+ Use printerState() == QPrinter::Aborted instead.
+*/
+
+#ifdef Q_WS_WIN
+/*!
+ \internal
+*/
+HDC QPrinter::getDC() const
+{
+ Q_D(const QPrinter);
+ return d->printEngine->getPrinterDC();
+}
+
+/*!
+ \internal
+*/
+void QPrinter::releaseDC(HDC hdc) const
+{
+ Q_D(const QPrinter);
+ d->printEngine->releasePrinterDC(hdc);
+}
+
+/*!
+ Returns the supported paper sizes for this printer.
+
+ The values will be either a value that matches an entry in the
+ QPrinter::PaperSource enum or a driver spesific value. The driver
+ spesific values are greater than the constant DMBIN_USER declared
+ in wingdi.h.
+
+ \warning This function is only available in windows.
+*/
+
+QList<QPrinter::PaperSource> QPrinter::supportedPaperSources() const
+{
+ Q_D(const QPrinter);
+ QVariant v = d->printEngine->property(QPrintEngine::PPK_PaperSources);
+
+ QList<QVariant> variant_list = v.toList();
+ QList<QPrinter::PaperSource> int_list;
+ for (int i=0; i<variant_list.size(); ++i)
+ int_list << (QPrinter::PaperSource) variant_list.at(i).toInt();
+
+ return int_list;
+}
+
+#endif
+
+/*!
+ \fn QString QPrinter::printerSelectionOption() const
+
+ Returns the printer options selection string. This is useful only
+ if the print command has been explicitly set.
+
+ The default value (an empty string) implies that the printer should
+ be selected in a system-dependent manner.
+
+ Any other value implies that the given value should be used.
+
+ \warning This function is not available on Windows.
+
+ \sa setPrinterSelectionOption()
+*/
+
+/*!
+ \fn void QPrinter::setPrinterSelectionOption(const QString &option)
+
+ Sets the printer to use \a option to select the printer. \a option
+ is null by default (which implies that Qt should be smart enough
+ to guess correctly), but it can be set to other values to use a
+ specific printer selection option.
+
+ If the printer selection option is changed while the printer is
+ active, the current print job may or may not be affected.
+
+ \warning This function is not available on Windows.
+
+ \sa printerSelectionOption()
+*/
+
+#ifndef Q_WS_WIN
+QString QPrinter::printerSelectionOption() const
+{
+ Q_D(const QPrinter);
+ return d->printEngine->property(QPrintEngine::PPK_SelectionOption).toString();
+}
+
+void QPrinter::setPrinterSelectionOption(const QString &option)
+{
+ Q_D(QPrinter);
+ d->printEngine->setProperty(QPrintEngine::PPK_SelectionOption, option);
+ d->addToManualSetList(QPrintEngine::PPK_SelectionOption);
+}
+#endif
+
+/*!
+ \since 4.1
+ \fn int QPrinter::fromPage() const
+
+ Returns the number of the first page in a range of pages to be printed
+ (the "from page" setting). Pages in a document are numbered according to
+ the convention that the first page is page 1.
+
+ By default, this function returns a special value of 0, meaning that
+ the "from page" setting is unset.
+
+ \note If fromPage() and toPage() both return 0, this indicates that
+ \e{the whole document will be printed}.
+
+ \sa setFromTo(), toPage()
+*/
+
+int QPrinter::fromPage() const
+{
+ return d->fromPage;
+}
+
+/*!
+ \since 4.1
+
+ Returns the number of the last page in a range of pages to be printed
+ (the "to page" setting). Pages in a document are numbered according to
+ the convention that the first page is page 1.
+
+ By default, this function returns a special value of 0, meaning that
+ the "to page" setting is unset.
+
+ \note If fromPage() and toPage() both return 0, this indicates that
+ \e{the whole document will be printed}.
+
+ The programmer is responsible for reading this setting and
+ printing accordingly.
+
+ \sa setFromTo(), fromPage()
+*/
+
+int QPrinter::toPage() const
+{
+ return d->toPage;
+}
+
+/*!
+ \since 4.1
+
+ Sets the range of pages to be printed to cover the pages with numbers
+ specified by \a from and \a to, where \a from corresponds to the first
+ page in the range and \a to corresponds to the last.
+
+ \note Pages in a document are numbered according to the convention that
+ the first page is page 1. However, if \a from and \a to are both set to 0,
+ the \e{whole document will be printed}.
+
+ This function is mostly used to set a default value that the user can
+ override in the print dialog when you call setup().
+
+ \sa fromPage(), toPage()
+*/
+
+void QPrinter::setFromTo(int from, int to)
+{
+ if (from > to) {
+ qWarning() << "QPrinter::setFromTo: 'from' must be less than or equal to 'to'";
+ from = to;
+ }
+ d->fromPage = from;
+ d->toPage = to;
+}
+
+/*!
+ \since 4.1
+
+ Sets the print range option in to be \a range.
+*/
+void QPrinter::setPrintRange( PrintRange range )
+{
+ d->printSelectionOnly = (range == Selection);
+
+ Q_D(QPrinter);
+ d->printRange = range;
+}
+
+/*!
+ \since 4.1
+
+ Returns the page range of the QPrinter. After the print setup
+ dialog has been opened, this function returns the value selected
+ by the user.
+
+ \sa setPrintRange()
+*/
+QPrinter::PrintRange QPrinter::printRange() const
+{
+ Q_D(const QPrinter);
+ return d->printRange;
+}
+
+
+/*!
+ \class QPrintEngine
+ \reentrant
+
+ \ingroup printing
+
+ \brief The QPrintEngine class defines an interface for how QPrinter
+ interacts with a given printing subsystem.
+
+ The common case when creating your own print engine is to derive from both
+ QPaintEngine and QPrintEngine. Various properties of a print engine are
+ given with property() and set with setProperty().
+
+ \sa QPaintEngine
+*/
+
+/*!
+ \enum QPrintEngine::PrintEnginePropertyKey
+
+ This enum is used to communicate properties between the print
+ engine and QPrinter. A property may or may not be supported by a
+ given print engine.
+
+ \value PPK_CollateCopies A boolean value indicating whether the
+ printout should be collated or not.
+
+ \value PPK_ColorMode Refers to QPrinter::ColorMode, either color or
+ monochrome.
+
+ \value PPK_Creator A string describing the document's creator.
+
+ \value PPK_Duplex A boolean value indicating whether both sides of
+ the printer paper should be used for the printout.
+
+ \value PPK_DocumentName A string describing the document name in
+ the spooler.
+
+ \value PPK_FontEmbedding A boolean value indicating whether data for
+ the document's fonts should be embedded in the data sent to the
+ printer.
+
+ \value PPK_FullPage A boolean describing if the printer should be
+ full page or not.
+
+ \value PPK_NumberOfCopies Obsolete. An integer specifying the number of
+ copies. Use PPK_CopyCount instead.
+
+ \value PPK_Orientation Specifies a QPrinter::Orientation value.
+
+ \value PPK_OutputFileName The output file name as a string. An
+ empty file name indicates that the printer should not print to a file.
+
+ \value PPK_PageOrder Specifies a QPrinter::PageOrder value.
+
+ \value PPK_PageRect A QRect specifying the page rectangle
+
+ \value PPK_PageSize Obsolete. Use PPK_PaperSize instead.
+
+ \value PPK_PaperRect A QRect specifying the paper rectangle.
+
+ \value PPK_PaperSource Specifies a QPrinter::PaperSource value.
+
+ \value PPK_PaperSources Specifies more than one QPrinter::PaperSource value.
+
+ \value PPK_PaperSize Specifies a QPrinter::PaperSize value.
+
+ \value PPK_PrinterName A string specifying the name of the printer.
+
+ \value PPK_PrinterProgram A string specifying the name of the
+ printer program used for printing,
+
+ \value PPK_Resolution An integer describing the dots per inch for
+ this printer.
+
+ \value PPK_SelectionOption
+
+ \value PPK_SupportedResolutions A list of integer QVariants
+ describing the set of supported resolutions that the printer has.
+
+ \value PPK_SuppressSystemPrintStatus Suppress the built-in dialog for showing
+ printing progress. As of 4.1 this only has effect on Mac OS X where, by default,
+ a status dialog is shown.
+
+ \value PPK_WindowsPageSize An integer specifying a DM_PAPER entry
+ on Windows.
+
+ \value PPK_CustomPaperSize A QSizeF specifying a custom paper size
+ in the QPrinter::Point unit.
+
+ \value PPK_PageMargins A QList<QVariant> containing the left, top,
+ right and bottom margin values.
+
+ \value PPK_CopyCount An integer specifying the number of copies to print.
+
+ \value PPK_SupportsMultipleCopies A boolean value indicating whether or not
+ the printer supports printing multiple copies in one job.
+
+ \value PPK_CustomBase Basis for extension.
+*/
+
+/*!
+ \fn QPrintEngine::~QPrintEngine()
+
+ Destroys the print engine.
+*/
+
+/*!
+ \fn void QPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &value)
+
+ Sets the print engine's property specified by \a key to the given \a value.
+
+ \sa property()
+*/
+
+/*!
+ \fn void QPrintEngine::property(PrintEnginePropertyKey key) const
+
+ Returns the print engine's property specified by \a key.
+
+ \sa setProperty()
+*/
+
+/*!
+ \fn bool QPrintEngine::newPage()
+
+ Instructs the print engine to start a new page. Returns true if
+ the printer was able to create the new page; otherwise returns false.
+*/
+
+/*!
+ \fn bool QPrintEngine::abort()
+
+ Instructs the print engine to abort the printing process. Returns
+ true if successful; otherwise returns false.
+*/
+
+/*!
+ \fn int QPrintEngine::metric(QPaintDevice::PaintDeviceMetric id) const
+
+ Returns the metric for the given \a id.
+*/
+
+/*!
+ \fn QPrinter::PrinterState QPrintEngine::printerState() const
+
+ Returns the current state of the printer being used by the print engine.
+*/
+
+/*!
+ \fn HDC QPrintEngine::getPrinterDC() const
+ \internal
+*/
+
+/*!
+ \fn void QPrintEngine::releasePrinterDC(HDC) const
+ \internal
+*/
+
+/*
+ Returns the dimensions for the given paper size, \a size, in millimeters.
+*/
+QSizeF qt_paperSizeToQSizeF(QPrinter::PaperSize size)
+{
+ if (size == QPrinter::Custom) return QSizeF(0, 0);
+ return QSizeF(qt_paperSizes[size][0], qt_paperSizes[size][1]);
+}
+
+/*
+ Returns the PaperSize type that matches \a size, where \a size
+ is in millimeters.
+
+ Because dimensions may not always be completely accurate (for
+ example when converting between units), a particular PaperSize
+ will be returned if it matches within -1/+1 millimeters.
+*/
+QPrinter::PaperSize qSizeFTopaperSize(const QSizeF& size)
+{
+ for (int i = 0; i < static_cast<int>(QPrinter::NPageSize); ++i) {
+ if (qt_paperSizes[i][0] >= size.width() - 1 &&
+ qt_paperSizes[i][0] <= size.width() + 1 &&
+ qt_paperSizes[i][1] >= size.height() - 1 &&
+ qt_paperSizes[i][1] <= size.height() + 1) {
+ return QPrinter::PaperSize(i);
+ }
+ }
+
+ return QPrinter::Custom;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_PRINTER
diff --git a/src/printsupport/kernel/qprinter.h b/src/printsupport/kernel/qprinter.h
new file mode 100644
index 0000000000..7d04099a8f
--- /dev/null
+++ b/src/printsupport/kernel/qprinter.h
@@ -0,0 +1,279 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPRINTER_H
+#define QPRINTER_H
+
+#include <QtCore/qstring.h>
+#include <QtCore/qscopedpointer.h>
+#include <QtGui/qpagedpaintdevice.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_PRINTER
+
+#if defined(B0)
+#undef B0 // Terminal hang-up. We assume that you do not want that.
+#endif
+
+class QPrinterPrivate;
+class QPaintEngine;
+class QPrintEngine;
+class QPrinterInfo;
+
+class Q_PRINTSUPPORT_EXPORT QPrinter : public QPagedPaintDevice
+{
+ Q_DECLARE_PRIVATE(QPrinter)
+public:
+ enum PrinterMode { ScreenResolution, PrinterResolution, HighResolution };
+
+ explicit QPrinter(PrinterMode mode = ScreenResolution);
+ explicit QPrinter(const QPrinterInfo& printer, PrinterMode mode = ScreenResolution);
+ ~QPrinter();
+
+ int devType() const;
+
+ enum Orientation { Portrait, Landscape };
+
+#ifndef Q_QDOC
+ typedef PageSize PaperSize;
+#else
+ enum PaperSize { A4, B5, Letter, Legal, Executive,
+ A0, A1, A2, A3, A5, A6, A7, A8, A9, B0, B1,
+ B10, B2, B3, B4, B6, B7, B8, B9, C5E, Comm10E,
+ DLE, Folio, Ledger, Tabloid, Custom, NPageSize = Custom, NPaperSize = Custom };
+#endif
+
+ enum PageOrder { FirstPageFirst,
+ LastPageFirst };
+
+ enum ColorMode { GrayScale,
+ Color };
+
+ enum PaperSource { OnlyOne,
+ Lower,
+ Middle,
+ Manual,
+ Envelope,
+ EnvelopeManual,
+ Auto,
+ Tractor,
+ SmallFormat,
+ LargeFormat,
+ LargeCapacity,
+ Cassette,
+ FormSource,
+ MaxPageSource
+ };
+
+ enum PrinterState { Idle,
+ Active,
+ Aborted,
+ Error };
+
+ enum OutputFormat { NativeFormat, PdfFormat };
+
+ // Keep in sync with QAbstractPrintDialog::PrintRange
+ enum PrintRange { AllPages, Selection, PageRange, CurrentPage };
+
+ enum Unit {
+ Millimeter,
+ Point,
+ Inch,
+ Pica,
+ Didot,
+ Cicero,
+ DevicePixel
+ };
+
+ enum DuplexMode {
+ DuplexNone = 0,
+ DuplexAuto,
+ DuplexLongSide,
+ DuplexShortSide
+ };
+
+ void setOutputFormat(OutputFormat format);
+ OutputFormat outputFormat() const;
+
+ void setPrinterName(const QString &);
+ QString printerName() const;
+
+ bool isValid() const;
+
+ void setOutputFileName(const QString &);
+ QString outputFileName()const;
+
+ void setPrintProgram(const QString &);
+ QString printProgram() const;
+
+ void setDocName(const QString &);
+ QString docName() const;
+
+ void setCreator(const QString &);
+ QString creator() const;
+
+ void setOrientation(Orientation);
+ Orientation orientation() const;
+
+ void setPageSize(PageSize);
+ PageSize pageSize() const;
+
+ void setPageSizeMM(const QSizeF &size);
+
+ void setPaperSize(PaperSize);
+ PaperSize paperSize() const;
+
+ void setPaperSize(const QSizeF &paperSize, Unit unit);
+ QSizeF paperSize(Unit unit) const;
+
+ void setPageOrder(PageOrder);
+ PageOrder pageOrder() const;
+
+ void setResolution(int);
+ int resolution() const;
+
+ void setColorMode(ColorMode);
+ ColorMode colorMode() const;
+
+ void setCollateCopies(bool collate);
+ bool collateCopies() const;
+
+ void setFullPage(bool);
+ bool fullPage() const;
+
+ void setNumCopies(int);
+ int numCopies() const;
+
+ int actualNumCopies() const;
+
+ void setCopyCount(int);
+ int copyCount() const;
+ bool supportsMultipleCopies() const;
+
+ void setPaperSource(PaperSource);
+ PaperSource paperSource() const;
+
+ void setDuplex(DuplexMode duplex);
+ DuplexMode duplex() const;
+
+ QList<int> supportedResolutions() const;
+
+#ifdef Q_WS_WIN
+ QList<PaperSource> supportedPaperSources() const;
+#endif
+
+ void setFontEmbeddingEnabled(bool enable);
+ bool fontEmbeddingEnabled() const;
+
+ void setDoubleSidedPrinting(bool enable);
+ bool doubleSidedPrinting() const;
+
+#ifdef Q_WS_WIN
+ void setWinPageSize(int winPageSize);
+ int winPageSize() const;
+#endif
+
+ QRect paperRect() const;
+ QRect pageRect() const;
+ QRectF paperRect(Unit) const;
+ QRectF pageRect(Unit) const;
+
+#if !defined(Q_WS_WIN) || defined(qdoc)
+ QString printerSelectionOption() const;
+ void setPrinterSelectionOption(const QString &);
+#endif
+
+ bool newPage();
+ bool abort();
+
+ PrinterState printerState() const;
+
+ QPaintEngine *paintEngine() const;
+ QPrintEngine *printEngine() const;
+
+#ifdef Q_WS_WIN
+ HDC getDC() const;
+ void releaseDC(HDC hdc) const;
+#endif
+
+ void setFromTo(int fromPage, int toPage);
+ int fromPage() const;
+ int toPage() const;
+
+ void setPrintRange(PrintRange range);
+ PrintRange printRange() const;
+
+ void setMargins(const Margins &m);
+
+ void setPageMargins(qreal left, qreal top, qreal right, qreal bottom, Unit unit);
+ void getPageMargins(qreal *left, qreal *top, qreal *right, qreal *bottom, Unit unit) const;
+
+protected:
+ int metric(PaintDeviceMetric) const;
+ void setEngines(QPrintEngine *printEngine, QPaintEngine *paintEngine);
+
+private:
+ void init(PrinterMode mode);
+
+ Q_DISABLE_COPY(QPrinter)
+
+ QScopedPointer<QPrinterPrivate> d_ptr;
+
+ friend class QPrintDialogPrivate;
+ friend class QAbstractPrintDialog;
+ friend class QAbstractPrintDialogPrivate;
+ friend class QPrintPreviewWidgetPrivate;
+ friend class QTextDocument;
+ friend class QPageSetupWidget;
+};
+
+#endif // QT_NO_PRINTER
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QPRINTER_H
diff --git a/src/printsupport/kernel/qprinter_p.h b/src/printsupport/kernel/qprinter_p.h
new file mode 100644
index 0000000000..08877f08c5
--- /dev/null
+++ b/src/printsupport/kernel/qprinter_p.h
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPRINTER_P_H
+#define QPRINTER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+
+#include "QtCore/qglobal.h"
+
+#ifndef QT_NO_PRINTER
+
+#include "QtPrintSupport/qprinter.h"
+#include "QtPrintSupport/qprintengine.h"
+#include "QtCore/qpointer.h"
+
+#include <limits.h>
+
+QT_BEGIN_NAMESPACE
+
+class QPrintEngine;
+class QPreviewPaintEngine;
+class QPicture;
+
+class Q_PRINTSUPPORT_EXPORT QPrinterPrivate
+{
+ Q_DECLARE_PUBLIC(QPrinter)
+public:
+ QPrinterPrivate(QPrinter *printer)
+ : printEngine(0)
+ , paintEngine(0)
+ , q_ptr(printer)
+ , printRange(QPrinter::AllPages)
+ , use_default_engine(true)
+ , validPrinter(false)
+ , hasCustomPageMargins(false)
+ , hasUserSetPageSize(false)
+ {
+ }
+
+ ~QPrinterPrivate() {
+
+ }
+
+ void createDefaultEngines();
+#ifndef QT_NO_PRINTPREVIEWWIDGET
+ QList<const QPicture *> previewPages() const;
+ void setPreviewMode(bool);
+#endif
+
+ void addToManualSetList(QPrintEngine::PrintEnginePropertyKey key);
+
+ QPrinter::PrinterMode printerMode;
+ QPrinter::OutputFormat outputFormat;
+ QPrintEngine *printEngine;
+ QPaintEngine *paintEngine;
+
+ QPrintEngine *realPrintEngine;
+ QPaintEngine *realPaintEngine;
+#ifndef QT_NO_PRINTPREVIEWWIDGET
+ QPreviewPaintEngine *previewEngine;
+#endif
+
+ QPrinter *q_ptr;
+
+ QPrinter::PrintRange printRange;
+
+ uint use_default_engine : 1;
+ uint had_default_engines : 1;
+
+ uint validPrinter : 1;
+ uint hasCustomPageMargins : 1;
+ uint hasUserSetPageSize : 1;
+
+ // Used to remember which properties have been manually set by the user.
+ QList<QPrintEngine::PrintEnginePropertyKey> manualSetList;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_PRINTER
+
+#endif // QPRINTER_P_H
diff --git a/src/printsupport/kernel/qprinterinfo.cpp b/src/printsupport/kernel/qprinterinfo.cpp
new file mode 100644
index 0000000000..5be73e76b9
--- /dev/null
+++ b/src/printsupport/kernel/qprinterinfo.cpp
@@ -0,0 +1,205 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** GNU Free Documentation License
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms
+** and conditions contained in a signed written agreement between you
+** and Nokia.
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qprinterinfo.h"
+#include "qprinterinfo_p.h"
+
+#ifndef QT_NO_PRINTER
+
+#include "qplatformprintplugin_qpa.h"
+#include <QtPrintSupport/QPlatformPrinterSupport>
+
+QT_BEGIN_NAMESPACE
+
+QPrinterInfoPrivate QPrinterInfoPrivate::shared_null;
+
+
+/*!
+ \class QPrinterInfo
+
+ \brief The QPrinterInfo class gives access to information about
+ existing printers.
+
+ \ingroup printing
+
+ Use the static functions to generate a list of QPrinterInfo
+ objects. Each QPrinterInfo object in the list represents a single
+ printer and can be queried for name, supported paper sizes, and
+ whether or not it is the default printer.
+
+ \since 4.4
+*/
+
+/*!
+ \fn QList<QPrinterInfo> QPrinterInfo::availablePrinters()
+
+ Returns a list of available printers on the system.
+*/
+
+/*!
+ \fn QPrinterInfo QPrinterInfo::defaultPrinter()
+
+ Returns the default printer on the system.
+
+ The return value should be checked using isNull() before being
+ used, in case there is no default printer.
+
+ \sa isNull()
+*/
+
+/*!
+ Constructs an empty QPrinterInfo object.
+
+ \sa isNull()
+*/
+QPrinterInfo::QPrinterInfo()
+ : d_ptr(&QPrinterInfoPrivate::shared_null)
+{
+}
+
+/*!
+ Constructs a copy of \a other.
+*/
+QPrinterInfo::QPrinterInfo(const QPrinterInfo &other)
+ : d_ptr(new QPrinterInfoPrivate(*other.d_ptr))
+{
+}
+
+/*!
+ Constructs a QPrinterInfo object from \a printer.
+*/
+QPrinterInfo::QPrinterInfo(const QPrinter &printer)
+ : d_ptr(&QPrinterInfoPrivate::shared_null)
+{
+ foreach (const QPrinterInfo &printerInfo, availablePrinters()) {
+ if (printerInfo.printerName() == printer.printerName()) {
+ d_ptr.reset(new QPrinterInfoPrivate(*printerInfo.d_ptr));
+ break;
+ }
+ }
+}
+
+/*!
+ \internal
+*/
+QPrinterInfo::QPrinterInfo(const QString &name)
+ : d_ptr(new QPrinterInfoPrivate(name))
+{
+}
+
+/*!
+ Destroys the QPrinterInfo object. References to the values in the
+ object become invalid.
+*/
+QPrinterInfo::~QPrinterInfo()
+{
+}
+
+/*!
+ Sets the QPrinterInfo object to be equal to \a other.
+*/
+QPrinterInfo &QPrinterInfo::operator=(const QPrinterInfo &other)
+{
+ Q_ASSERT(d_ptr);
+ d_ptr.reset(new QPrinterInfoPrivate(*other.d_ptr));
+ return *this;
+}
+
+/*!
+ Returns the name of the printer.
+
+ \sa QPrinter::setPrinterName()
+*/
+QString QPrinterInfo::printerName() const
+{
+ const Q_D(QPrinterInfo);
+ return d->name;
+}
+
+/*!
+ Returns whether this QPrinterInfo object holds a printer definition.
+
+ An empty QPrinterInfo object could result for example from calling
+ defaultPrinter() when there are no printers on the system.
+*/
+bool QPrinterInfo::isNull() const
+{
+ const Q_D(QPrinterInfo);
+ return d == &QPrinterInfoPrivate::shared_null;
+}
+
+/*!
+ Returns whether this printer is the default printer.
+*/
+bool QPrinterInfo::isDefault() const
+{
+ const Q_D(QPrinterInfo);
+ return d->isDefault;
+}
+
+/*!
+ \fn QList< QPrinter::PaperSize> QPrinterInfo::supportedPaperSizes() const
+ \since 4.4
+
+ Returns a list of supported paper sizes by the printer.
+
+ Not all printer drivers support this query, so the list may be empty.
+ On Mac OS X 10.3, this function always returns an empty list.
+*/
+
+#ifdef Q_WS_QPA
+QList<QPrinter::PaperSize> QPrinterInfo::supportedPaperSizes() const
+{
+ const Q_D(QPrinterInfo);
+ if (!isNull() && !d->hasPaperSizes) {
+ d->paperSizes = QPlatformPrinterSupportPlugin::get()->supportedPaperSizes(*this);
+ d->hasPaperSizes = true;
+ }
+ return d->paperSizes;
+}
+
+QList<QPrinterInfo> QPrinterInfo::availablePrinters()
+{
+ QPlatformPrinterSupport *ps = QPlatformPrinterSupportPlugin::get();
+ if (!ps)
+ return QList<QPrinterInfo>();
+ return ps->availablePrinters();
+}
+
+QPrinterInfo QPrinterInfo::defaultPrinter()
+{
+ QPlatformPrinterSupport *ps = QPlatformPrinterSupportPlugin::get();
+ if (!ps)
+ return QPrinterInfo();
+ return QPlatformPrinterSupportPlugin::get()->defaultPrinter();
+}
+
+#endif //Q_WS_QPA
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_PRINTER
diff --git a/src/printsupport/kernel/qprinterinfo.h b/src/printsupport/kernel/qprinterinfo.h
new file mode 100644
index 0000000000..535c29c4d6
--- /dev/null
+++ b/src/printsupport/kernel/qprinterinfo.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPRINTERINFO_H
+#define QPRINTERINFO_H
+
+#include <QtCore/QList>
+
+#include <QtPrintSupport/QPrinter>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_PRINTER
+class QPrinterInfoPrivate;
+class QPrinterInfoPrivateDeleter;
+class Q_PRINTSUPPORT_EXPORT QPrinterInfo
+{
+public:
+ QPrinterInfo();
+ QPrinterInfo(const QPrinterInfo &other);
+ QPrinterInfo(const QPrinter &printer);
+ ~QPrinterInfo();
+
+ QPrinterInfo &operator=(const QPrinterInfo &other);
+
+ QString printerName() const;
+ bool isNull() const;
+ bool isDefault() const;
+ QList<QPrinter::PaperSize> supportedPaperSizes() const;
+
+ static QList<QPrinterInfo> availablePrinters();
+ static QPrinterInfo defaultPrinter();
+
+private:
+ QPrinterInfo(const QString &name);
+
+private:
+ friend class QPlatformPrinterSupport;
+ Q_DECLARE_PRIVATE(QPrinterInfo)
+ QScopedPointer<QPrinterInfoPrivate, QPrinterInfoPrivateDeleter> d_ptr;
+};
+
+#endif // QT_NO_PRINTER
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QPRINTERINFO_H
diff --git a/src/printsupport/kernel/qprinterinfo_p.h b/src/printsupport/kernel/qprinterinfo_p.h
new file mode 100644
index 0000000000..a3c654e7b7
--- /dev/null
+++ b/src/printsupport/kernel/qprinterinfo_p.h
@@ -0,0 +1,108 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPRINTERINFO_P_H
+#define QPRINTERINFO_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "QtCore/qglobal.h"
+
+#ifndef QT_NO_PRINTER
+
+#include "QtCore/qlist.h"
+
+QT_BEGIN_NAMESPACE
+
+class QPrinterInfoPrivate
+{
+public:
+ QPrinterInfoPrivate(const QString& name = QString()) :
+ name(name), isDefault(false)
+#if (defined(Q_OS_UNIX) && !defined(Q_OS_MAC) && !defined(Q_OS_SYMBIAN)) || defined(Q_WS_QPA)
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+ , cupsPrinterIndex(0)
+#endif
+#endif
+ , hasPaperSizes(false)
+ {}
+ ~QPrinterInfoPrivate()
+ {}
+
+ static QPrinterInfoPrivate shared_null;
+
+ QString name;
+ bool isDefault;
+
+#if (defined(Q_OS_UNIX) && !defined(Q_OS_MAC) && !defined(Q_OS_SYMBIAN)) || defined(Q_WS_QPA)
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+ int cupsPrinterIndex;
+#endif
+#endif
+ mutable bool hasPaperSizes;
+ mutable QList<QPrinter::PaperSize> paperSizes;
+};
+
+
+class QPrinterInfoPrivateDeleter
+{
+public:
+ static inline void cleanup(QPrinterInfoPrivate *d)
+ {
+ if (d != &QPrinterInfoPrivate::shared_null)
+ delete d;
+ }
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_PRINTER
+
+#endif // QPRINTERINFO_P_H
diff --git a/src/printsupport/kernel/qprinterinfo_unix.cpp b/src/printsupport/kernel/qprinterinfo_unix.cpp
new file mode 100644
index 0000000000..c7dbb7cc32
--- /dev/null
+++ b/src/printsupport/kernel/qprinterinfo_unix.cpp
@@ -0,0 +1,857 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qprinterinfo.h"
+#include "qprinterinfo_p.h"
+
+#include <qfile.h>
+#include <qfileinfo.h>
+#include <qdir.h>
+#include <qlibrary.h>
+#include <qtextstream.h>
+#include <qcoreapplication.h>
+
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+# include <private/qcups_p.h>
+# include <cups/cups.h>
+# include <private/qpdf_p.h>
+#endif
+
+#include <private/qprinterinfo_unix_p.h>
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_PRINTER
+
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+// preserver names in ascending order for the binary search
+static const struct NamedPaperSize {
+ const char *const name;
+ QPrinter::PaperSize size;
+} named_sizes_map[QPrinter::NPageSize] = {
+ { "A0", QPrinter::A0 },
+ { "A1", QPrinter::A1 },
+ { "A2", QPrinter::A2 },
+ { "A3", QPrinter::A3 },
+ { "A4", QPrinter::A4 },
+ { "A5", QPrinter::A5 },
+ { "A6", QPrinter::A6 },
+ { "A7", QPrinter::A7 },
+ { "A8", QPrinter::A8 },
+ { "A9", QPrinter::A9 },
+ { "B0", QPrinter::B0 },
+ { "B1", QPrinter::B1 },
+ { "B10", QPrinter::B10 },
+ { "B2", QPrinter::B2 },
+ { "B4", QPrinter::B4 },
+ { "B5", QPrinter::B5 },
+ { "B6", QPrinter::B6 },
+ { "B7", QPrinter::B7 },
+ { "B8", QPrinter::B8 },
+ { "B9", QPrinter::B9 },
+ { "C5E", QPrinter::C5E },
+ { "Comm10E", QPrinter::Comm10E },
+ { "Custom", QPrinter::Custom },
+ { "DLE", QPrinter::DLE },
+ { "Executive", QPrinter::Executive },
+ { "Folio", QPrinter::Folio },
+ { "Ledger", QPrinter::Ledger },
+ { "Legal", QPrinter::Legal },
+ { "Letter", QPrinter::Letter },
+ { "Tabloid", QPrinter::Tabloid }
+};
+
+inline bool operator<(const char *name, const NamedPaperSize &data)
+{ return qstrcmp(name, data.name) < 0; }
+inline bool operator<(const NamedPaperSize &data, const char *name)
+{ return qstrcmp(data.name, name) < 0; }
+
+static inline QPrinter::PaperSize string2PaperSize(const char *name)
+{
+ const NamedPaperSize *r = qBinaryFind(named_sizes_map, named_sizes_map + QPrinter::NPageSize, name);
+ if (r - named_sizes_map != QPrinter::NPageSize)
+ return r->size;
+ return QPrinter::Custom;
+}
+
+static inline const char *paperSize2String(QPrinter::PaperSize size)
+{
+ for (int i = 0; i < QPrinter::NPageSize; ++i) {
+ if (size == named_sizes_map[i].size)
+ return named_sizes_map[i].name;
+ }
+ return 0;
+}
+#endif
+
+void qt_perhapsAddPrinter(QList<QPrinterDescription> *printers, const QString &name,
+ QString host, QString comment,
+ QStringList aliases)
+{
+ for (int i = 0; i < printers->size(); ++i)
+ if (printers->at(i).samePrinter(name))
+ return;
+
+ if (host.isEmpty())
+ host = QCoreApplication::translate("QPrinter", "locally connected");
+ printers->append(QPrinterDescription(name.simplified(), host.simplified(), comment.simplified(), aliases));
+}
+
+void qt_parsePrinterDesc(QString printerDesc, QList<QPrinterDescription> *printers)
+{
+ if (printerDesc.length() < 1)
+ return;
+
+ printerDesc = printerDesc.simplified();
+ int i = printerDesc.indexOf(QLatin1Char(':'));
+ QString printerName, printerComment, printerHost;
+ QStringList aliases;
+
+ if (i >= 0) {
+ // have ':' want '|'
+ int j = printerDesc.indexOf(QLatin1Char('|'));
+ if (j > 0 && j < i) {
+ printerName = printerDesc.left(j);
+ aliases = printerDesc.mid(j + 1, i - j - 1).split(QLatin1Char('|'));
+ // try extracting a comment from the aliases
+ printerComment = QCoreApplication::translate("QPrinter", "Aliases: %1")
+ .arg(aliases.join(QLatin1String(", ")));
+ } else {
+ printerName = printerDesc.left(i);
+ }
+ // look for lprng pseudo all printers entry
+ i = printerDesc.indexOf(QRegExp(QLatin1String(": *all *=")));
+ if (i >= 0)
+ printerName = QString();
+ // look for signs of this being a remote printer
+ i = printerDesc.indexOf(QRegExp(QLatin1String(": *rm *=")));
+ if (i >= 0) {
+ // point k at the end of remote host name
+ while (printerDesc[i] != QLatin1Char('='))
+ i++;
+ while (printerDesc[i] == QLatin1Char('=') || printerDesc[i].isSpace())
+ i++;
+ j = i;
+ while (j < (int)printerDesc.length() && printerDesc[j] != QLatin1Char(':'))
+ j++;
+
+ // and stuff that into the string
+ printerHost = printerDesc.mid(i, j - i);
+ }
+ }
+ if (printerName.length())
+ qt_perhapsAddPrinter(printers, printerName, printerHost, printerComment,
+ aliases);
+}
+
+int qt_parsePrintcap(QList<QPrinterDescription> *printers, const QString& fileName)
+{
+ QFile printcap(fileName);
+ if (!printcap.open(QIODevice::ReadOnly))
+ return NotFound;
+
+ char *line_ascii = new char[1025];
+ line_ascii[1024] = '\0';
+
+ QString printerDesc;
+ bool atEnd = false;
+
+ while (!atEnd) {
+ if (printcap.atEnd() || printcap.readLine(line_ascii, 1024) <= 0)
+ atEnd = true;
+ QString line = QString::fromLocal8Bit(line_ascii);
+ line = line.trimmed();
+ if (line.length() >= 1 && line[int(line.length()) - 1] == QLatin1Char('\\'))
+ line.chop(1);
+ if (line[0] == QLatin1Char('#')) {
+ if (!atEnd)
+ continue;
+ } else if (line[0] == QLatin1Char('|') || line[0] == QLatin1Char(':')
+ || line.isEmpty()) {
+ printerDesc += line;
+ if (!atEnd)
+ continue;
+ }
+
+ qt_parsePrinterDesc(printerDesc, printers);
+
+ // add the first line of the new printer definition
+ printerDesc = line;
+ }
+ delete[] line_ascii;
+ return Success;
+}
+
+/*!
+ \internal
+
+ Checks $HOME/.printers for a line matching '_default <name>' (where
+ <name> does not contain any white space). The first such match
+ results in <name> being returned.
+ If no lines match then an empty string is returned.
+*/
+QString qt_getDefaultFromHomePrinters()
+{
+ QFile file(QDir::homePath() + QLatin1String("/.printers"));
+ if (!file.open(QIODevice::ReadOnly))
+ return QString();
+ QString all(QLatin1String(file.readAll()));
+ QStringList words = all.split(QRegExp(QLatin1String("\\W+")), QString::SkipEmptyParts);
+ const int i = words.indexOf(QLatin1String("_default"));
+ if (i != -1 && i < words.size() - 1)
+ return words.at(i + 1);
+ return QString();
+}
+
+// solaris, not 2.6
+void qt_parseEtcLpPrinters(QList<QPrinterDescription> *printers)
+{
+ QDir lp(QLatin1String("/etc/lp/printers"));
+ QFileInfoList dirs = lp.entryInfoList();
+ if (dirs.isEmpty())
+ return;
+
+ QString tmp;
+ for (int i = 0; i < dirs.size(); ++i) {
+ QFileInfo printer = dirs.at(i);
+ if (printer.isDir()) {
+ tmp.sprintf("/etc/lp/printers/%s/configuration",
+ printer.fileName().toAscii().data());
+ QFile configuration(tmp);
+ char *line = new char[1025];
+ QString remote(QLatin1String("Remote:"));
+ QString contentType(QLatin1String("Content types:"));
+ QString printerHost;
+ bool canPrintPostscript = false;
+ if (configuration.open(QIODevice::ReadOnly)) {
+ while (!configuration.atEnd() &&
+ configuration.readLine(line, 1024) > 0) {
+ if (QString::fromLatin1(line).startsWith(remote)) {
+ const char *p = line;
+ while (*p != ':')
+ p++;
+ p++;
+ while (isspace((uchar) *p))
+ p++;
+ printerHost = QString::fromLocal8Bit(p);
+ printerHost = printerHost.simplified();
+ } else if (QString::fromLatin1(line).startsWith(contentType)) {
+ char *p = line;
+ while (*p != ':')
+ p++;
+ p++;
+ char *e;
+ while (*p) {
+ while (isspace((uchar) *p))
+ p++;
+ if (*p) {
+ char s;
+ e = p;
+ while (isalnum((uchar) *e))
+ e++;
+ s = *e;
+ *e = '\0';
+ if (!qstrcmp(p, "postscript") ||
+ !qstrcmp(p, "any"))
+ canPrintPostscript = true;
+ *e = s;
+ if (s == ',')
+ e++;
+ p = e;
+ }
+ }
+ }
+ }
+ if (canPrintPostscript)
+ qt_perhapsAddPrinter(printers, printer.fileName(),
+ printerHost, QLatin1String(""));
+ }
+ delete[] line;
+ }
+ }
+}
+
+// solaris 2.6
+char *qt_parsePrintersConf(QList<QPrinterDescription> *printers, bool *found)
+{
+ QFile pc(QLatin1String("/etc/printers.conf"));
+ if (!pc.open(QIODevice::ReadOnly)) {
+ if (found)
+ *found = false;
+ return 0;
+ }
+ if (found)
+ *found = true;
+
+ char *line = new char[1025];
+ line[1024] = '\0';
+
+ QString printerDesc;
+ int lineLength = 0;
+
+ char *defaultPrinter = 0;
+
+ while (!pc.atEnd() &&
+ (lineLength=pc.readLine(line, 1024)) > 0) {
+ if (*line == '#') {
+ *line = '\0';
+ lineLength = 0;
+ }
+ if (lineLength >= 2 && line[lineLength-2] == '\\') {
+ line[lineLength-2] = '\0';
+ printerDesc += QString::fromLocal8Bit(line);
+ } else {
+ printerDesc += QString::fromLocal8Bit(line);
+ printerDesc = printerDesc.simplified();
+ int i = printerDesc.indexOf(QLatin1Char(':'));
+ QString printerName, printerHost, printerComment;
+ QStringList aliases;
+ if (i >= 0) {
+ // have : want |
+ int j = printerDesc.indexOf(QLatin1Char('|'));
+ if (j >= i)
+ j = -1;
+ printerName = printerDesc.mid(0, j < 0 ? i : j);
+ if (printerName == QLatin1String("_default")) {
+ i = printerDesc.indexOf(
+ QRegExp(QLatin1String(": *use *=")));
+ while (printerDesc[i] != QLatin1Char('='))
+ i++;
+ while (printerDesc[i] == QLatin1Char('=') || printerDesc[i].isSpace())
+ i++;
+ j = i;
+ while (j < (int)printerDesc.length() &&
+ printerDesc[j] != QLatin1Char(':') && printerDesc[j] != QLatin1Char(','))
+ j++;
+ // that's our default printer
+ defaultPrinter =
+ qstrdup(printerDesc.mid(i, j-i).toAscii().data());
+ printerName = QString();
+ printerDesc = QString();
+ } else if (printerName == QLatin1String("_all")) {
+ // skip it.. any other cases we want to skip?
+ printerName = QString();
+ printerDesc = QString();
+ }
+
+ if (j > 0) {
+ // try extracting a comment from the aliases
+ aliases = printerDesc.mid(j + 1, i - j - 1).split(QLatin1Char('|'));
+ printerComment = QCoreApplication::translate("QPrinter", "Aliases: %1")
+ .arg(aliases.join(QLatin1String(", ")));
+ }
+ // look for signs of this being a remote printer
+ i = printerDesc.indexOf(
+ QRegExp(QLatin1String(": *bsdaddr *=")));
+ if (i >= 0) {
+ // point k at the end of remote host name
+ while (printerDesc[i] != QLatin1Char('='))
+ i++;
+ while (printerDesc[i] == QLatin1Char('=') || printerDesc[i].isSpace())
+ i++;
+ j = i;
+ while (j < (int)printerDesc.length() &&
+ printerDesc[j] != QLatin1Char(':') && printerDesc[j] != QLatin1Char(','))
+ j++;
+ // and stuff that into the string
+ printerHost = printerDesc.mid(i, j-i);
+ // maybe stick the remote printer name into the comment
+ if (printerDesc[j] == QLatin1Char(',')) {
+ i = ++j;
+ while (printerDesc[i].isSpace())
+ i++;
+ j = i;
+ while (j < (int)printerDesc.length() &&
+ printerDesc[j] != QLatin1Char(':') && printerDesc[j] != QLatin1Char(','))
+ j++;
+ if (printerName != printerDesc.mid(i, j-i)) {
+ printerComment =
+ QLatin1String("Remote name: ");
+ printerComment += printerDesc.mid(i, j-i);
+ }
+ }
+ }
+ }
+ if (printerComment == QLatin1String(":"))
+ printerComment = QString(); // for cups
+ if (printerName.length())
+ qt_perhapsAddPrinter(printers, printerName, printerHost,
+ printerComment, aliases);
+ // chop away the line, for processing the next one
+ printerDesc = QString();
+ }
+ }
+ delete[] line;
+ return defaultPrinter;
+}
+
+#ifndef QT_NO_NIS
+
+#if defined(Q_C_CALLBACKS)
+extern "C" {
+#endif
+
+int qt_pd_foreach(int /*status */, char * /*key */, int /*keyLen */,
+ char *val, int valLen, char *data)
+{
+ qt_parsePrinterDesc(QString::fromLatin1(val, valLen), (QList<QPrinterDescription> *)data);
+ return 0;
+}
+
+#if defined(Q_C_CALLBACKS)
+}
+#endif
+
+int qt_retrieveNisPrinters(QList<QPrinterDescription> *printers)
+{
+#ifndef QT_NO_LIBRARY
+ typedef int (*WildCast)(int, char *, int, char *, int, char *);
+ char printersConfByname[] = "printers.conf.byname";
+ char *domain;
+ int err;
+
+ QLibrary lib(QLatin1String("nsl"));
+ typedef int (*ypGetDefaultDomain)(char **);
+ ypGetDefaultDomain _ypGetDefaultDomain = (ypGetDefaultDomain)lib.resolve("yp_get_default_domain");
+ typedef int (*ypAll)(const char *, const char *, const struct ypall_callback *);
+ ypAll _ypAll = (ypAll)lib.resolve("yp_all");
+
+ if (_ypGetDefaultDomain && _ypAll) {
+ err = _ypGetDefaultDomain(&domain);
+ if (err == 0) {
+ ypall_callback cb;
+ // wild cast to support K&R-style system headers
+ (WildCast &) cb.foreach = (WildCast) qt_pd_foreach;
+ cb.data = (char *) printers;
+ err = _ypAll(domain, printersConfByname, &cb);
+ }
+ if (!err)
+ return Success;
+ }
+#endif //QT_NO_LIBRARY
+ return Unavail;
+}
+
+#endif // QT_NO_NIS
+
+char *qt_parseNsswitchPrintersEntry(QList<QPrinterDescription> *printers, char *line)
+{
+#define skipSpaces() \
+ while (line[k] != '\0' && isspace((uchar) line[k])) \
+ k++
+
+ char *defaultPrinter = 0;
+ bool stop = false;
+ int lastStatus = NotFound;
+
+ int k = 8;
+ skipSpaces();
+ if (line[k] != ':')
+ return 0;
+ k++;
+
+ char *cp = strchr(line, '#');
+ if (cp != 0)
+ *cp = '\0';
+
+ while (line[k] != '\0') {
+ if (isspace((uchar) line[k])) {
+ k++;
+ } else if (line[k] == '[') {
+ k++;
+ skipSpaces();
+ while (line[k] != '\0') {
+ char status = tolower(line[k]);
+ char action = '?';
+
+ while (line[k] != '=' && line[k] != ']' && line[k] != '\0')
+ k++;
+ if (line[k] == '=') {
+ k++;
+ skipSpaces();
+ action = tolower(line[k]);
+ while (line[k] != '\0' && !isspace((uchar) line[k]) && line[k] != ']')
+ k++;
+ } else if (line[k] == ']') {
+ k++;
+ break;
+ }
+ skipSpaces();
+
+ if (lastStatus == status)
+ stop = (action == (char) Return);
+ }
+ } else {
+ if (stop)
+ break;
+
+ QByteArray source;
+ while (line[k] != '\0' && !isspace((uchar) line[k]) && line[k] != '[') {
+ source += line[k];
+ k++;
+ }
+
+ if (source == "user") {
+ lastStatus = qt_parsePrintcap(printers,
+ QDir::homePath() + QLatin1String("/.printers"));
+ } else if (source == "files") {
+ bool found;
+ defaultPrinter = qt_parsePrintersConf(printers, &found);
+ if (found)
+ lastStatus = Success;
+#ifndef QT_NO_NIS
+ } else if (source == "nis") {
+ lastStatus = qt_retrieveNisPrinters(printers);
+#endif
+ } else {
+ // nisplus, dns, etc., are not implemented yet
+ lastStatus = NotFound;
+ }
+ stop = (lastStatus == Success);
+ }
+ }
+ return defaultPrinter;
+}
+
+char *qt_parseNsswitchConf(QList<QPrinterDescription> *printers)
+{
+ QFile nc(QLatin1String("/etc/nsswitch.conf"));
+ if (!nc.open(QIODevice::ReadOnly))
+ return 0;
+
+ char *defaultPrinter = 0;
+
+ char *line = new char[1025];
+ line[1024] = '\0';
+
+ while (!nc.atEnd() &&
+ nc.readLine(line, 1024) > 0) {
+ if (qstrncmp(line, "printers", 8) == 0) {
+ defaultPrinter = qt_parseNsswitchPrintersEntry(printers, line);
+ delete[] line;
+ return defaultPrinter;
+ }
+ }
+
+ strcpy(line, "printers: user files nis nisplus xfn");
+ defaultPrinter = qt_parseNsswitchPrintersEntry(printers, line);
+ delete[] line;
+ return defaultPrinter;
+}
+
+// HP-UX
+void qt_parseEtcLpMember(QList<QPrinterDescription> *printers)
+{
+ QDir lp(QLatin1String("/etc/lp/member"));
+ if (!lp.exists())
+ return;
+ QFileInfoList dirs = lp.entryInfoList();
+ if (dirs.isEmpty())
+ return;
+
+ QString tmp;
+ for (int i = 0; i < dirs.size(); ++i) {
+ QFileInfo printer = dirs.at(i);
+ // I haven't found any real documentation, so I'm guessing that
+ // since lpstat uses /etc/lp/member rather than one of the
+ // other directories, it's the one to use. I did not find a
+ // decent way to locate aliases and remote printers.
+ if (printer.isFile())
+ qt_perhapsAddPrinter(printers, printer.fileName(),
+ QCoreApplication::translate("QPrinter", "unknown"),
+ QLatin1String(""));
+ }
+}
+
+// IRIX 6.x
+void qt_parseSpoolInterface(QList<QPrinterDescription> *printers)
+{
+ QDir lp(QLatin1String("/usr/spool/lp/interface"));
+ if (!lp.exists())
+ return;
+ QFileInfoList files = lp.entryInfoList();
+ if(files.isEmpty())
+ return;
+
+ for (int i = 0; i < files.size(); ++i) {
+ QFileInfo printer = files.at(i);
+
+ if (!printer.isFile())
+ continue;
+
+ // parse out some information
+ QFile configFile(printer.filePath());
+ if (!configFile.open(QIODevice::ReadOnly))
+ continue;
+
+ QByteArray line;
+ line.resize(1025);
+ QString namePrinter;
+ QString hostName;
+ QString hostPrinter;
+ QString printerType;
+
+ QString nameKey(QLatin1String("NAME="));
+ QString typeKey(QLatin1String("TYPE="));
+ QString hostKey(QLatin1String("HOSTNAME="));
+ QString hostPrinterKey(QLatin1String("HOSTPRINTER="));
+
+ while (!configFile.atEnd() &&
+ (configFile.readLine(line.data(), 1024)) > 0) {
+ QString uline = QString::fromLocal8Bit(line);
+ if (uline.startsWith(typeKey) ) {
+ printerType = uline.mid(nameKey.length());
+ printerType = printerType.simplified();
+ } else if (uline.startsWith(hostKey)) {
+ hostName = uline.mid(hostKey.length());
+ hostName = hostName.simplified();
+ } else if (uline.startsWith(hostPrinterKey)) {
+ hostPrinter = uline.mid(hostPrinterKey.length());
+ hostPrinter = hostPrinter.simplified();
+ } else if (uline.startsWith(nameKey)) {
+ namePrinter = uline.mid(nameKey.length());
+ namePrinter = namePrinter.simplified();
+ }
+ }
+ configFile.close();
+
+ printerType = printerType.trimmed();
+ if (printerType.indexOf(QLatin1String("postscript"), 0, Qt::CaseInsensitive) < 0)
+ continue;
+
+ int ii = 0;
+ while ((ii = namePrinter.indexOf(QLatin1Char('"'), ii)) >= 0)
+ namePrinter.remove(ii, 1);
+
+ if (hostName.isEmpty() || hostPrinter.isEmpty()) {
+ qt_perhapsAddPrinter(printers, printer.fileName(),
+ QLatin1String(""), namePrinter);
+ } else {
+ QString comment;
+ comment = namePrinter;
+ comment += QLatin1String(" (");
+ comment += hostPrinter;
+ comment += QLatin1Char(')');
+ qt_perhapsAddPrinter(printers, printer.fileName(),
+ hostName, comment);
+ }
+ }
+}
+
+
+// Every unix must have its own. It's a standard. Here is AIX.
+void qt_parseQconfig(QList<QPrinterDescription> *printers)
+{
+ QFile qconfig(QLatin1String("/etc/qconfig"));
+ if (!qconfig.open(QIODevice::ReadOnly))
+ return;
+
+ QTextStream ts(&qconfig);
+ QString line;
+
+ QString stanzaName; // either a queue or a device name
+ bool up = true; // queue up? default true, can be false
+ QString remoteHost; // null if local
+ QString deviceName; // null if remote
+
+ QRegExp newStanza(QLatin1String("^[0-z\\-]*:$"));
+
+ // our basic strategy here is to process each line, detecting new
+ // stanzas. each time we see a new stanza, we check if the
+ // previous stanza was a valid queue for a) a remote printer or b)
+ // a local printer. if it wasn't, we assume that what we see is
+ // the start of the first stanza, or that the previous stanza was
+ // a device stanza, or that there is some syntax error (we don't
+ // report those).
+
+ do {
+ line = ts.readLine();
+ bool indented = line[0].isSpace();
+ line = line.simplified();
+
+ int i = line.indexOf(QLatin1Char('='));
+ if (indented && i != -1) { // line in stanza
+ QString variable = line.left(i).simplified();
+ QString value=line.mid(i+1, line.length()).simplified();
+ if (variable == QLatin1String("device"))
+ deviceName = value;
+ else if (variable == QLatin1String("host"))
+ remoteHost = value;
+ else if (variable == QLatin1String("up"))
+ up = !(value.toLower() == QLatin1String("false"));
+ } else if (line[0] == QLatin1Char('*')) { // comment
+ // nothing to do
+ } else if (ts.atEnd() || // end of file, or beginning of new stanza
+ (!indented && line.contains(newStanza))) {
+ if (up && stanzaName.length() > 0 && stanzaName.length() < 21) {
+ if (remoteHost.length()) // remote printer
+ qt_perhapsAddPrinter(printers, stanzaName, remoteHost,
+ QString());
+ else if (deviceName.length()) // local printer
+ qt_perhapsAddPrinter(printers, stanzaName, QString(),
+ QString());
+ }
+ line.chop(1);
+ if (line.length() >= 1 && line.length() <= 20)
+ stanzaName = line;
+ up = true;
+ remoteHost.clear();
+ deviceName.clear();
+ } else {
+ // syntax error? ignore.
+ }
+ } while (!ts.atEnd());
+}
+
+Q_PRINTSUPPORT_EXPORT int qt_getLprPrinters(QList<QPrinterDescription>& printers)
+{
+ QByteArray etcLpDefault;
+ qt_parsePrintcap(&printers, QLatin1String("/etc/printcap"));
+ qt_parseEtcLpMember(&printers);
+ qt_parseSpoolInterface(&printers);
+ qt_parseQconfig(&printers);
+
+ QFileInfo f;
+ f.setFile(QLatin1String("/etc/lp/printers"));
+ if (f.isDir()) {
+ qt_parseEtcLpPrinters(&printers);
+ QFile def(QLatin1String("/etc/lp/default"));
+ if (def.open(QIODevice::ReadOnly)) {
+ etcLpDefault.resize(1025);
+ if (def.readLine(etcLpDefault.data(), 1024) > 0) {
+ QRegExp rx(QLatin1String("^(\\S+)"));
+ if (rx.indexIn(QString::fromLatin1(etcLpDefault)) != -1)
+ etcLpDefault = rx.cap(1).toAscii();
+ }
+ }
+ }
+
+ char *def = 0;
+ f.setFile(QLatin1String("/etc/nsswitch.conf"));
+ if (f.isFile()) {
+ def = qt_parseNsswitchConf(&printers);
+ } else {
+ f.setFile(QLatin1String("/etc/printers.conf"));
+ if (f.isFile())
+ def = qt_parsePrintersConf(&printers);
+ }
+
+ if (def) {
+ etcLpDefault = def;
+ delete [] def;
+ }
+
+ QString homePrintersDefault = qt_getDefaultFromHomePrinters();
+
+ // all printers hopefully known. try to find a good default
+ QString dollarPrinter;
+ {
+ dollarPrinter = QString::fromLocal8Bit(qgetenv("PRINTER"));
+ if (dollarPrinter.isEmpty())
+ dollarPrinter = QString::fromLocal8Bit(qgetenv("LPDEST"));
+ if (dollarPrinter.isEmpty())
+ dollarPrinter = QString::fromLocal8Bit(qgetenv("NPRINTER"));
+ if (dollarPrinter.isEmpty())
+ dollarPrinter = QString::fromLocal8Bit(qgetenv("NGPRINTER"));
+ if (!dollarPrinter.isEmpty())
+ qt_perhapsAddPrinter(&printers, dollarPrinter,
+ QCoreApplication::translate("QPrinter", "unknown"),
+ QLatin1String(""));
+ }
+
+ QRegExp ps(QLatin1String("[^a-z]ps(?:[^a-z]|$)"));
+ QRegExp lp(QLatin1String("[^a-z]lp(?:[^a-z]|$)"));
+
+ int quality = 0;
+ int best = 0;
+ for (int i = 0; i < printers.size(); ++i) {
+ QString name = printers.at(i).name;
+ QString comment = printers.at(i).comment;
+ if (quality < 5 && name == dollarPrinter) {
+ best = i;
+ quality = 5;
+ } else if (quality < 4 && !homePrintersDefault.isEmpty() &&
+ name == homePrintersDefault) {
+ best = i;
+ quality = 4;
+ } else if (quality < 3 && !etcLpDefault.isEmpty() &&
+ name == QLatin1String(etcLpDefault)) {
+ best = i;
+ quality = 3;
+ } else if (quality < 2 &&
+ (name == QLatin1String("ps") ||
+ ps.indexIn(comment) != -1)) {
+ best = i;
+ quality = 2;
+ } else if (quality < 1 &&
+ (name == QLatin1String("lp") ||
+ lp.indexIn(comment) > -1)) {
+ best = i;
+ quality = 1;
+ }
+ }
+
+ return best;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+
+QList<QPrinter::PaperSize> qt_getCupsPrinterPaperSizes(int cupsPrinterIndex)
+{
+ QList<QPrinter::PaperSize> result;
+#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+ if (!QCUPSSupport::isAvailable() || cupsPrinterIndex < 0)
+ return result;
+ // Find paper sizes from CUPS.
+ QCUPSSupport cups;
+ cups.setCurrentPrinter(cupsPrinterIndex);
+ if (const ppd_option_t* size = cups.pageSizes()) {
+ for (int j = 0; j < size->num_choices; ++j)
+ result.append(string2PaperSize(size->choices[j].choice));
+ }
+ return result;
+#endif
+}
+
+#endif // QT_NO_PRINTER
+
+QT_END_NAMESPACE
diff --git a/src/printsupport/kernel/qprinterinfo_unix_p.h b/src/printsupport/kernel/qprinterinfo_unix_p.h
new file mode 100644
index 0000000000..c12aa39556
--- /dev/null
+++ b/src/printsupport/kernel/qprinterinfo_unix_p.h
@@ -0,0 +1,130 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPRINTERINFO_UNIX_P_H
+#define QPRINTERINFO_UNIX_P_H
+
+#include <QtPrintSupport/qprinter.h>
+#include <QtCore/qstringlist.h>
+
+#ifndef QT_NO_NIS
+# ifndef BOOL_DEFINED
+# define BOOL_DEFINED
+# endif
+
+# include <sys/types.h>
+# include <rpc/rpc.h>
+# include <rpcsvc/ypclnt.h>
+# include <rpcsvc/yp_prot.h>
+#endif // QT_NO_NIS
+
+#ifdef Success
+# undef Success
+#endif
+
+#include <ctype.h>
+
+QT_BEGIN_NAMESPACE
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QT_NO_PRINTER
+
+struct QPrinterDescription {
+ QPrinterDescription(const QString &n, const QString &h, const QString &c, const QStringList &a)
+ : name(n), host(h), comment(c), aliases(a) {}
+ QString name;
+ QString host;
+ QString comment;
+ QStringList aliases;
+ bool samePrinter(const QString& printer) const {
+ return name == printer || aliases.contains(printer);
+ }
+};
+
+enum { Success = 's', Unavail = 'u', NotFound = 'n', TryAgain = 't' };
+enum { Continue = 'c', Return = 'r' };
+
+void qt_perhapsAddPrinter(QList<QPrinterDescription> *printers, const QString &name,
+ QString host, QString comment,
+ QStringList aliases = QStringList());
+void qt_parsePrinterDesc(QString printerDesc, QList<QPrinterDescription> *printers);
+
+int qt_parsePrintcap(QList<QPrinterDescription> *printers, const QString& fileName);
+QString qt_getDefaultFromHomePrinters();
+void qt_parseEtcLpPrinters(QList<QPrinterDescription> *printers);
+char *qt_parsePrintersConf(QList<QPrinterDescription> *printers, bool *found = 0);
+
+#ifndef QT_NO_NIS
+#if defined(Q_C_CALLBACKS)
+extern "C" {
+#endif
+int qt_pd_foreach(int /*status */, char * /*key */, int /*keyLen */,
+ char *val, int valLen, char *data);
+
+#if defined(Q_C_CALLBACKS)
+}
+#endif
+int qt_retrieveNisPrinters(QList<QPrinterDescription> *printers);
+#endif // QT_NO_NIS
+char *qt_parseNsswitchPrintersEntry(QList<QPrinterDescription> *printers, char *line);
+char *qt_parseNsswitchConf(QList<QPrinterDescription> *printers);
+void qt_parseEtcLpMember(QList<QPrinterDescription> *printers);
+void qt_parseSpoolInterface(QList<QPrinterDescription> *printers);
+void qt_parseQconfig(QList<QPrinterDescription> *printers);
+int qt_getLprPrinters(QList<QPrinterDescription>& printers);
+
+QList<QPrinter::PaperSize> qt_getCupsPrinterPaperSizes(int cupsPrinterIndex);
+
+#endif // QT_NO_PRINTER
+
+QT_END_NAMESPACE
+
+#endif // QPRINTERINFO_UNIX_P_H
diff --git a/src/printsupport/printsupport.pro b/src/printsupport/printsupport.pro
new file mode 100644
index 0000000000..0aa92a95de
--- /dev/null
+++ b/src/printsupport/printsupport.pro
@@ -0,0 +1,22 @@
+load(qt_module)
+
+TARGET = QtPrintSupport
+QPRO_PWD = $$PWD
+QT = core-private gui-private widgets-private
+
+CONFIG += module
+MODULE_PRI = ../modules/qt_printsupport.pri
+
+DEFINES += QT_BUILD_PRINTSUPPORT_LIB QT_NO_USING_NAMESPACE
+
+unix|win32-g++*:QMAKE_PKGCONFIG_REQUIRES = QtCore QtGui
+
+load(qt_module_config)
+
+HEADERS += $$QT_SOURCE_TREE/src/printsupport/qtprintsupportversion.h
+
+QMAKE_LIBS += $$QMAKE_LIBS_PRINTSUPPORT
+
+include(kernel/kernel.pri)
+include(widgets/widgets.pri)
+include(dialogs/dialogs.pri)
diff --git a/src/printsupport/widgets/qprintpreviewwidget.cpp b/src/printsupport/widgets/qprintpreviewwidget.cpp
new file mode 100644
index 0000000000..96b009f8c1
--- /dev/null
+++ b/src/printsupport/widgets/qprintpreviewwidget.cpp
@@ -0,0 +1,844 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qprintpreviewwidget.h"
+#include "private/qwidget_p.h"
+#include <private/qprinter_p.h>
+
+#include <QtCore/qmath.h>
+#include <QtWidgets/qboxlayout.h>
+#include <QtWidgets/qgraphicsitem.h>
+#include <QtWidgets/qgraphicsview.h>
+#include <QtWidgets/qscrollbar.h>
+#include <QtWidgets/qstyleoption.h>
+
+#ifndef QT_NO_PRINTPREVIEWWIDGET
+
+QT_BEGIN_NAMESPACE
+
+namespace {
+class PageItem : public QGraphicsItem
+{
+public:
+ PageItem(int _pageNum, const QPicture* _pagePicture, QSize _paperSize, QRect _pageRect)
+ : pageNum(_pageNum), pagePicture(_pagePicture),
+ paperSize(_paperSize), pageRect(_pageRect)
+ {
+ qreal border = qMax(paperSize.height(), paperSize.width()) / 25;
+ brect = QRectF(QPointF(-border, -border),
+ QSizeF(paperSize)+QSizeF(2*border, 2*border));
+ setCacheMode(DeviceCoordinateCache);
+ }
+
+ inline QRectF boundingRect() const
+ { return brect; }
+
+ inline int pageNumber() const
+ { return pageNum; }
+
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *item, QWidget *widget);
+
+private:
+ int pageNum;
+ const QPicture* pagePicture;
+ QSize paperSize;
+ QRect pageRect;
+ QRectF brect;
+};
+
+void PageItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+ Q_UNUSED(widget);
+
+#if 0
+ // Draw item bounding rect, for debugging
+ painter->save();
+ painter->setPen(QPen(Qt::red, 0));
+ painter->setBrush(Qt::NoBrush);
+ painter->drawRect(QRectF(-border()+1.0, -border()+1.0, boundingRect().width()-2, boundingRect().height()-2));
+ painter->restore();
+#endif
+
+ QRectF paperRect(0,0, paperSize.width(), paperSize.height());
+
+ // Draw shadow
+ painter->setClipRect(option->exposedRect);
+ qreal shWidth = paperRect.width()/100;
+ QRectF rshadow(paperRect.topRight() + QPointF(0, shWidth),
+ paperRect.bottomRight() + QPointF(shWidth, 0));
+ QLinearGradient rgrad(rshadow.topLeft(), rshadow.topRight());
+ rgrad.setColorAt(0.0, QColor(0,0,0,255));
+ rgrad.setColorAt(1.0, QColor(0,0,0,0));
+ painter->fillRect(rshadow, QBrush(rgrad));
+ QRectF bshadow(paperRect.bottomLeft() + QPointF(shWidth, 0),
+ paperRect.bottomRight() + QPointF(0, shWidth));
+ QLinearGradient bgrad(bshadow.topLeft(), bshadow.bottomLeft());
+ bgrad.setColorAt(0.0, QColor(0,0,0,255));
+ bgrad.setColorAt(1.0, QColor(0,0,0,0));
+ painter->fillRect(bshadow, QBrush(bgrad));
+ QRectF cshadow(paperRect.bottomRight(),
+ paperRect.bottomRight() + QPointF(shWidth, shWidth));
+ QRadialGradient cgrad(cshadow.topLeft(), shWidth, cshadow.topLeft());
+ cgrad.setColorAt(0.0, QColor(0,0,0,255));
+ cgrad.setColorAt(1.0, QColor(0,0,0,0));
+ painter->fillRect(cshadow, QBrush(cgrad));
+
+ painter->setClipRect(paperRect & option->exposedRect);
+ painter->fillRect(paperRect, Qt::white);
+ if (!pagePicture)
+ return;
+ painter->drawPicture(pageRect.topLeft(), *pagePicture);
+
+ // Effect: make anything drawn in the margins look washed out.
+ QPainterPath path;
+ path.addRect(paperRect);
+ path.addRect(pageRect);
+ painter->setPen(QPen(Qt::NoPen));
+ painter->setBrush(QColor(255, 255, 255, 180));
+ painter->drawPath(path);
+
+#if 0
+ // Draw frame around paper.
+ painter->setPen(QPen(Qt::black, 0));
+ painter->setBrush(Qt::NoBrush);
+ painter->drawRect(paperRect);
+#endif
+
+ // todo: drawtext "Page N" below paper
+}
+
+class GraphicsView : public QGraphicsView
+{
+ Q_OBJECT
+public:
+ GraphicsView(QWidget* parent = 0)
+ : QGraphicsView(parent)
+ {
+#ifdef Q_WS_MAC
+ setFrameStyle(QFrame::NoFrame);
+#endif
+ }
+signals:
+ void resized();
+
+protected:
+ void resizeEvent(QResizeEvent* e)
+ {
+ QGraphicsView::resizeEvent(e);
+ emit resized();
+ }
+
+ void showEvent(QShowEvent* e)
+ {
+ QGraphicsView::showEvent(e);
+ emit resized();
+ }
+};
+
+} // anonymous namespace
+
+class QPrintPreviewWidgetPrivate : public QWidgetPrivate
+{
+ Q_DECLARE_PUBLIC(QPrintPreviewWidget)
+public:
+ QPrintPreviewWidgetPrivate()
+ : scene(0), curPage(1),
+ viewMode(QPrintPreviewWidget::SinglePageView),
+ zoomMode(QPrintPreviewWidget::FitInView),
+ zoomFactor(1), initialized(false), fitting(true)
+ {}
+
+ // private slots
+ void _q_fit(bool doFitting = false);
+ void _q_updateCurrentPage();
+
+ void init();
+ void populateScene();
+ void layoutPages();
+ void generatePreview();
+ void setCurrentPage(int pageNumber);
+ void zoom(qreal zoom);
+ void setZoomFactor(qreal zoomFactor);
+ int calcCurrentPage();
+
+ GraphicsView *graphicsView;
+ QGraphicsScene *scene;
+
+ int curPage;
+ QList<const QPicture *> pictures;
+ QList<QGraphicsItem *> pages;
+
+ QPrintPreviewWidget::ViewMode viewMode;
+ QPrintPreviewWidget::ZoomMode zoomMode;
+ qreal zoomFactor;
+ bool ownPrinter;
+ QPrinter* printer;
+ bool initialized;
+ bool fitting;
+};
+
+void QPrintPreviewWidgetPrivate::_q_fit(bool doFitting)
+{
+ Q_Q(QPrintPreviewWidget);
+
+ if (curPage < 1 || curPage > pages.count())
+ return;
+
+ if (!doFitting && !fitting)
+ return;
+
+ if (doFitting && fitting) {
+ QRect viewRect = graphicsView->viewport()->rect();
+ if (zoomMode == QPrintPreviewWidget::FitInView) {
+ QList<QGraphicsItem*> containedItems = graphicsView->items(viewRect, Qt::ContainsItemBoundingRect);
+ foreach(QGraphicsItem* item, containedItems) {
+ PageItem* pg = static_cast<PageItem*>(item);
+ if (pg->pageNumber() == curPage)
+ return;
+ }
+ }
+
+ int newPage = calcCurrentPage();
+ if (newPage != curPage)
+ curPage = newPage;
+ }
+
+ QRectF target = pages.at(curPage-1)->sceneBoundingRect();
+ if (viewMode == QPrintPreviewWidget::FacingPagesView) {
+ // fit two pages
+ if (curPage % 2)
+ target.setLeft(target.left() - target.width());
+ else
+ target.setRight(target.right() + target.width());
+ } else if (viewMode == QPrintPreviewWidget::AllPagesView) {
+ target = scene->itemsBoundingRect();
+ }
+
+ if (zoomMode == QPrintPreviewWidget::FitToWidth) {
+ QTransform t;
+ qreal scale = graphicsView->viewport()->width() / target.width();
+ t.scale(scale, scale);
+ graphicsView->setTransform(t);
+ if (doFitting && fitting) {
+ QRectF viewSceneRect = graphicsView->viewportTransform().mapRect(graphicsView->viewport()->rect());
+ viewSceneRect.moveTop(target.top());
+ graphicsView->ensureVisible(viewSceneRect); // Nah...
+ }
+ } else {
+ graphicsView->fitInView(target, Qt::KeepAspectRatio);
+ if (zoomMode == QPrintPreviewWidget::FitInView) {
+ int step = qRound(graphicsView->matrix().mapRect(target).height());
+ graphicsView->verticalScrollBar()->setSingleStep(step);
+ graphicsView->verticalScrollBar()->setPageStep(step);
+ }
+ }
+
+ zoomFactor = graphicsView->transform().m11() * (float(printer->logicalDpiY()) / q->logicalDpiY());
+ emit q->previewChanged();
+}
+
+void QPrintPreviewWidgetPrivate::_q_updateCurrentPage()
+{
+ Q_Q(QPrintPreviewWidget);
+
+ if (viewMode == QPrintPreviewWidget::AllPagesView)
+ return;
+
+ int newPage = calcCurrentPage();
+ if (newPage != curPage) {
+ curPage = newPage;
+ emit q->previewChanged();
+ }
+}
+
+int QPrintPreviewWidgetPrivate::calcCurrentPage()
+{
+ int maxArea = 0;
+ int newPage = curPage;
+ QRect viewRect = graphicsView->viewport()->rect();
+ QList<QGraphicsItem*> items = graphicsView->items(viewRect);
+ for (int i=0; i<items.size(); ++i) {
+ PageItem* pg = static_cast<PageItem*>(items.at(i));
+ QRect overlap = graphicsView->mapFromScene(pg->sceneBoundingRect()).boundingRect() & viewRect;
+ int area = overlap.width() * overlap.height();
+ if (area > maxArea) {
+ maxArea = area;
+ newPage = pg->pageNumber();
+ } else if (area == maxArea && pg->pageNumber() < newPage) {
+ newPage = pg->pageNumber();
+ }
+ }
+ return newPage;
+}
+
+void QPrintPreviewWidgetPrivate::init()
+{
+ Q_Q(QPrintPreviewWidget);
+
+ graphicsView = new GraphicsView;
+ graphicsView->setInteractive(false);
+ graphicsView->setDragMode(QGraphicsView::ScrollHandDrag);
+ graphicsView->setViewportUpdateMode(QGraphicsView::SmartViewportUpdate);
+ QObject::connect(graphicsView->verticalScrollBar(), SIGNAL(valueChanged(int)),
+ q, SLOT(_q_updateCurrentPage()));
+ QObject::connect(graphicsView, SIGNAL(resized()), q, SLOT(_q_fit()));
+
+ scene = new QGraphicsScene(graphicsView);
+ scene->setBackgroundBrush(Qt::gray);
+ graphicsView->setScene(scene);
+
+ QVBoxLayout *layout = new QVBoxLayout;
+ q->setLayout(layout);
+ layout->setContentsMargins(0, 0, 0, 0);
+ layout->addWidget(graphicsView);
+}
+
+void QPrintPreviewWidgetPrivate::populateScene()
+{
+ // remove old pages
+ for (int i = 0; i < pages.size(); i++)
+ scene->removeItem(pages.at(i));
+ qDeleteAll(pages);
+ pages.clear();
+
+ int numPages = pictures.count();
+ QSize paperSize = printer->paperRect().size();
+ QRect pageRect = printer->pageRect();
+
+ for (int i = 0; i < numPages; i++) {
+ PageItem* item = new PageItem(i+1, pictures.at(i), paperSize, pageRect);
+ scene->addItem(item);
+ pages.append(item);
+ }
+}
+
+void QPrintPreviewWidgetPrivate::layoutPages()
+{
+ int numPages = pages.count();
+ if (numPages < 1)
+ return;
+
+ int numPagePlaces = numPages;
+ int cols = 1; // singleMode and default
+ if (viewMode == QPrintPreviewWidget::AllPagesView) {
+ if (printer->orientation() == QPrinter::Portrait)
+ cols = qCeil(qSqrt((float) numPages));
+ else
+ cols = qFloor(qSqrt((float) numPages));
+ cols += cols % 2; // Nicer with an even number of cols
+ }
+ else if (viewMode == QPrintPreviewWidget::FacingPagesView) {
+ cols = 2;
+ numPagePlaces += 1;
+ }
+ int rows = qCeil(qreal(numPagePlaces) / cols);
+
+ qreal itemWidth = pages.at(0)->boundingRect().width();
+ qreal itemHeight = pages.at(0)->boundingRect().height();
+ int pageNum = 1;
+ for (int i = 0; i < rows && pageNum <= numPages; i++) {
+ for (int j = 0; j < cols && pageNum <= numPages; j++) {
+ if (!i && !j && viewMode == QPrintPreviewWidget::FacingPagesView) {
+ // Front page doesn't have a facing page
+ continue;
+ } else {
+ pages.at(pageNum-1)->setPos(QPointF(j*itemWidth, i*itemHeight));
+ pageNum++;
+ }
+ }
+ }
+ scene->setSceneRect(scene->itemsBoundingRect());
+}
+
+void QPrintPreviewWidgetPrivate::generatePreview()
+{
+ //### If QPrinter::setPreviewMode() becomes public, handle the
+ //### case that we have been constructed with a printer that
+ //### _already_ has been preview-painted to, so we should
+ //### initially just show the pages it already contains, and not
+ //### emit paintRequested() until the user changes some parameter
+
+ Q_Q(QPrintPreviewWidget);
+ printer->d_func()->setPreviewMode(true);
+ emit q->paintRequested(printer);
+ printer->d_func()->setPreviewMode(false);
+ pictures = printer->d_func()->previewPages();
+ populateScene(); // i.e. setPreviewPrintedPictures() e.l.
+ layoutPages();
+ curPage = qBound(1, curPage, pages.count());
+ if (fitting)
+ _q_fit();
+ emit q->previewChanged();
+}
+
+void QPrintPreviewWidgetPrivate::setCurrentPage(int pageNumber)
+{
+ if (pageNumber < 1 || pageNumber > pages.count())
+ return;
+
+ int lastPage = curPage;
+ curPage = pageNumber;
+
+ if (lastPage != curPage && lastPage > 0 && lastPage <= pages.count()) {
+ if (zoomMode != QPrintPreviewWidget::FitInView) {
+ QScrollBar *hsc = graphicsView->horizontalScrollBar();
+ QScrollBar *vsc = graphicsView->verticalScrollBar();
+ QPointF pt = graphicsView->transform().map(pages.at(curPage-1)->pos());
+ vsc->setValue(int(pt.y()) - 10);
+ hsc->setValue(int(pt.x()) - 10);
+ } else {
+ graphicsView->centerOn(pages.at(curPage-1));
+ }
+ }
+}
+
+void QPrintPreviewWidgetPrivate::zoom(qreal zoom)
+{
+ zoomFactor *= zoom;
+ graphicsView->scale(zoom, zoom);
+}
+
+void QPrintPreviewWidgetPrivate::setZoomFactor(qreal _zoomFactor)
+{
+ Q_Q(QPrintPreviewWidget);
+ zoomFactor = _zoomFactor;
+ graphicsView->resetTransform();
+ int dpi_y = q->logicalDpiY();
+ int printer_dpi_y = printer->logicalDpiY();
+ graphicsView->scale(zoomFactor*(dpi_y/float(printer_dpi_y)),
+ zoomFactor*(dpi_y/float(printer_dpi_y)));
+}
+
+///////////////////////////////////////
+
+/*!
+ \class QPrintPreviewWidget
+ \since 4.4
+
+ \brief The QPrintPreviewWidget class provides a widget for
+ previewing page layouts for printer output.
+
+ \ingroup printing
+
+ QPrintPreviewDialog uses a QPrintPreviewWidget internally, and the
+ purpose of QPrintPreviewWidget is to make it possible to embed the
+ preview into other widgets. It also makes it possible to build a different
+ user interface around it than the default one provided with QPrintPreviewDialog.
+
+ Using QPrintPreviewWidget is straightforward:
+
+ \list 1
+ \o Create the QPrintPreviewWidget
+
+ Construct the QPrintPreviewWidget either by passing in an
+ existing QPrinter object, or have QPrintPreviewWidget create a
+ default constructed QPrinter object for you.
+
+ \o Connect the paintRequested() signal to a slot.
+
+ When the widget needs to generate a set of preview pages, a
+ paintRequested() signal will be emitted from the widget. Connect a
+ slot to this signal, and draw onto the QPrinter passed in as a
+ signal parameter. Call QPrinter::newPage(), to start a new
+ page in the preview.
+
+ \endlist
+
+ \sa QPrinter, QPrintDialog, QPageSetupDialog, QPrintPreviewDialog
+*/
+
+
+/*!
+ \enum QPrintPreviewWidget::ViewMode
+
+ This enum is used to describe the view mode of the preview widget.
+
+ \value SinglePageView A mode where single pages in the preview
+ is viewed.
+
+ \value FacingPagesView A mode where the facing pages in the preview
+ is viewed.
+
+ \value AllPagesView A view mode where all the pages in the preview
+ is viewed.
+*/
+
+/*!
+ \enum QPrintPreviewWidget::ZoomMode
+
+ This enum is used to describe zoom mode of the preview widget.
+
+ \value CustomZoom The zoom is set to a custom zoom value.
+
+ \value FitToWidth This mode fits the current page to the width of the view.
+
+ \value FitInView This mode fits the current page inside the view.
+
+*/
+
+/*!
+ Constructs a QPrintPreviewWidget based on \a printer and with \a
+ parent as the parent widget. The widget flags \a flags are passed on
+ to the QWidget constructor.
+
+ \sa QWidget::setWindowFlags()
+*/
+QPrintPreviewWidget::QPrintPreviewWidget(QPrinter *printer, QWidget *parent, Qt::WindowFlags flags)
+ : QWidget(*new QPrintPreviewWidgetPrivate, parent, flags)
+{
+ Q_D(QPrintPreviewWidget);
+ d->printer = printer;
+ d->ownPrinter = false;
+ d->init();
+}
+
+/*!
+ \overload
+
+ This will cause QPrintPreviewWidget to create an internal, default
+ constructed QPrinter object, which will be used to generate the
+ preview.
+*/
+QPrintPreviewWidget::QPrintPreviewWidget(QWidget *parent, Qt::WindowFlags flags)
+ : QWidget(*new QPrintPreviewWidgetPrivate, parent, flags)
+{
+ Q_D(QPrintPreviewWidget);
+ d->printer = new QPrinter;
+ d->ownPrinter = true;
+ d->init();
+}
+
+
+/*!
+ Destroys the QPrintPreviewWidget.
+*/
+QPrintPreviewWidget::~QPrintPreviewWidget()
+{
+ Q_D(QPrintPreviewWidget);
+ if (d->ownPrinter)
+ delete d->printer;
+}
+
+/*!
+ Returns the current view mode. The default view mode is SinglePageView.
+*/
+QPrintPreviewWidget::ViewMode QPrintPreviewWidget::viewMode() const
+{
+ Q_D(const QPrintPreviewWidget);
+ return d->viewMode;
+}
+
+/*!
+ Sets the view mode to \a mode. The default view mode is
+ SinglePageView.
+*/
+void QPrintPreviewWidget::setViewMode(ViewMode mode)
+{
+ Q_D(QPrintPreviewWidget);
+ d->viewMode = mode;
+ d->layoutPages();
+ if (d->viewMode == AllPagesView) {
+ d->graphicsView->fitInView(d->scene->itemsBoundingRect(), Qt::KeepAspectRatio);
+ d->fitting = false;
+ d->zoomMode = QPrintPreviewWidget::CustomZoom;
+ d->zoomFactor = d->graphicsView->transform().m11() * (float(d->printer->logicalDpiY()) / logicalDpiY());
+ emit previewChanged();
+ } else {
+ d->fitting = true;
+ d->_q_fit();
+ }
+}
+
+/*!
+ Returns the current orientation of the preview. This value is
+ obtained from the QPrinter object associated with the preview.
+*/
+QPrinter::Orientation QPrintPreviewWidget::orientation() const
+{
+ Q_D(const QPrintPreviewWidget);
+ return d->printer->orientation();
+}
+
+/*!
+ Sets the current orientation to \a orientation. This value will be
+ set on the QPrinter object associated with the preview.
+*/
+void QPrintPreviewWidget::setOrientation(QPrinter::Orientation orientation)
+{
+ Q_D(QPrintPreviewWidget);
+ d->printer->setOrientation(orientation);
+ d->generatePreview();
+}
+
+/*!
+ Prints the preview to the printer associated with the preview.
+*/
+void QPrintPreviewWidget::print()
+{
+ Q_D(QPrintPreviewWidget);
+ // ### make use of the generated pages
+ emit paintRequested(d->printer);
+}
+
+/*!
+ Zooms the current view in by \a factor. The default value for \a
+ factor is 1.1, which means the view will be scaled up by 10%.
+*/
+void QPrintPreviewWidget::zoomIn(qreal factor)
+{
+ Q_D(QPrintPreviewWidget);
+ d->fitting = false;
+ d->zoomMode = QPrintPreviewWidget::CustomZoom;
+ d->zoom(factor);
+}
+
+/*!
+ Zooms the current view out by \a factor. The default value for \a
+ factor is 1.1, which means the view will be scaled down by 10%.
+*/
+void QPrintPreviewWidget::zoomOut(qreal factor)
+{
+ Q_D(QPrintPreviewWidget);
+ d->fitting = false;
+ d->zoomMode = QPrintPreviewWidget::CustomZoom;
+ d->zoom(1/factor);
+}
+
+/*!
+ Returns the zoom factor of the view.
+*/
+qreal QPrintPreviewWidget::zoomFactor() const
+{
+ Q_D(const QPrintPreviewWidget);
+ return d->zoomFactor;
+}
+
+/*!
+ Sets the zoom factor of the view to \a factor. For example, a
+ value of 1.0 indicates an unscaled view, which is approximately
+ the size the view will have on paper. A value of 0.5 will halve
+ the size of the view, while a value of 2.0 will double the size of
+ the view.
+*/
+void QPrintPreviewWidget::setZoomFactor(qreal factor)
+{
+ Q_D(QPrintPreviewWidget);
+ d->fitting = false;
+ d->zoomMode = QPrintPreviewWidget::CustomZoom;
+ d->setZoomFactor(factor);
+}
+
+/*!
+ \obsolete
+ Returns the number of pages in the preview.
+ \sa pageCount()
+*/
+int QPrintPreviewWidget::numPages() const
+{
+ Q_D(const QPrintPreviewWidget);
+ return d->pages.size();
+}
+
+/*!
+ \since 4.6
+ Returns the number of pages in the preview.
+*/
+int QPrintPreviewWidget::pageCount() const
+{
+ Q_D(const QPrintPreviewWidget);
+ return d->pages.size();
+}
+
+/*!
+ Returns the currently viewed page in the preview.
+*/
+int QPrintPreviewWidget::currentPage() const
+{
+ Q_D(const QPrintPreviewWidget);
+ return d->curPage;
+}
+
+/*!
+ Sets the current page in the preview. This will cause the view to
+ skip to the beginning of \a page.
+*/
+void QPrintPreviewWidget::setCurrentPage(int page)
+{
+ Q_D(QPrintPreviewWidget);
+ d->setCurrentPage(page);
+}
+
+/*!
+ This is a convenience function and is the same as calling \c
+ {setZoomMode(QPrintPreviewWidget::FitToWidth)}.
+*/
+void QPrintPreviewWidget::fitToWidth()
+{
+ setZoomMode(FitToWidth);
+}
+
+/*!
+ This is a convenience function and is the same as calling \c
+ {setZoomMode(QPrintPreviewWidget::FitInView)}.
+*/
+void QPrintPreviewWidget::fitInView()
+{
+ setZoomMode(FitInView);
+}
+
+/*!
+ Sets the zoom mode to \a zoomMode. The default zoom mode is FitInView.
+
+ \sa zoomMode(), viewMode(), setViewMode()
+*/
+void QPrintPreviewWidget::setZoomMode(QPrintPreviewWidget::ZoomMode zoomMode)
+{
+ Q_D(QPrintPreviewWidget);
+ d->zoomMode = zoomMode;
+ if (d->zoomMode == FitInView || d->zoomMode == FitToWidth) {
+ d->fitting = true;
+ d->_q_fit(true);
+ } else {
+ d->fitting = false;
+ }
+}
+
+/*!
+ Returns the current zoom mode.
+
+ \sa setZoomMode(), viewMode(), setViewMode()
+*/
+QPrintPreviewWidget::ZoomMode QPrintPreviewWidget::zoomMode() const
+{
+ Q_D(const QPrintPreviewWidget);
+ return d->zoomMode;
+}
+
+/*!
+ This is a convenience function and is the same as calling \c
+ {setOrientation(QPrinter::Landscape)}.
+*/
+void QPrintPreviewWidget::setLandscapeOrientation()
+{
+ setOrientation(QPrinter::Landscape);
+}
+
+/*!
+ This is a convenience function and is the same as calling \c
+ {setOrientation(QPrinter::Portrait)}.
+*/
+void QPrintPreviewWidget::setPortraitOrientation()
+{
+ setOrientation(QPrinter::Portrait);
+}
+
+/*!
+ This is a convenience function and is the same as calling \c
+ {setViewMode(QPrintPreviewWidget::SinglePageView)}.
+*/
+void QPrintPreviewWidget::setSinglePageViewMode()
+{
+ setViewMode(SinglePageView);
+}
+
+/*!
+ This is a convenience function and is the same as calling \c
+ {setViewMode(QPrintPreviewWidget::FacingPagesView)}.
+*/
+void QPrintPreviewWidget::setFacingPagesViewMode()
+{
+ setViewMode(FacingPagesView);
+}
+
+/*!
+ This is a convenience function and is the same as calling \c
+ {setViewMode(QPrintPreviewWidget::AllPagesView)}.
+*/
+void QPrintPreviewWidget::setAllPagesViewMode()
+{
+ setViewMode(AllPagesView);
+}
+
+
+/*!
+ This function updates the preview, which causes the
+ paintRequested() signal to be emitted.
+*/
+void QPrintPreviewWidget::updatePreview()
+{
+ Q_D(QPrintPreviewWidget);
+ d->initialized = true;
+ d->generatePreview();
+ d->graphicsView->updateGeometry();
+}
+
+/*! \reimp
+*/
+void QPrintPreviewWidget::setVisible(bool visible)
+{
+ Q_D(QPrintPreviewWidget);
+ if (visible && !d->initialized)
+ updatePreview();
+ QWidget::setVisible(visible);
+}
+
+/*!
+ \fn void QPrintPreviewWidget::paintRequested(QPrinter *printer)
+
+ This signal is emitted when the preview widget needs to generate a
+ set of preview pages. \a printer is the printer associated with
+ this preview widget.
+*/
+
+/*!
+ \fn void QPrintPreviewWidget::previewChanged()
+
+ This signal is emitted whenever the preview widget has changed
+ some internal state, such as the orientation.
+*/
+
+
+QT_END_NAMESPACE
+
+#include "moc_qprintpreviewwidget.cpp"
+#include "qprintpreviewwidget.moc"
+
+#endif // QT_NO_PRINTPREVIEWWIDGET
diff --git a/src/printsupport/widgets/qprintpreviewwidget.h b/src/printsupport/widgets/qprintpreviewwidget.h
new file mode 100644
index 0000000000..1c12bc0945
--- /dev/null
+++ b/src/printsupport/widgets/qprintpreviewwidget.h
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPRINTPREVIEWWIDGET_H
+#define QPRINTPREVIEWWIDGET_H
+
+#include <QtWidgets/qwidget.h>
+#include <QtPrintSupport/qprinter.h>
+
+#ifndef QT_NO_PRINTPREVIEWWIDGET
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QPrintPreviewWidgetPrivate;
+
+class Q_PRINTSUPPORT_EXPORT QPrintPreviewWidget : public QWidget
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QPrintPreviewWidget)
+public:
+
+ enum ViewMode {
+ SinglePageView,
+ FacingPagesView,
+ AllPagesView
+ };
+
+ enum ZoomMode {
+ CustomZoom,
+ FitToWidth,
+ FitInView
+ };
+
+ explicit QPrintPreviewWidget(QPrinter *printer, QWidget *parent = 0, Qt::WindowFlags flags = 0);
+ explicit QPrintPreviewWidget(QWidget *parent = 0, Qt::WindowFlags flags = 0);
+ ~QPrintPreviewWidget();
+
+ qreal zoomFactor() const;
+ QPrinter::Orientation orientation() const;
+ ViewMode viewMode() const;
+ ZoomMode zoomMode() const;
+ int currentPage() const;
+#ifdef QT_DEPRECATED
+ QT_DEPRECATED int numPages() const;
+#endif
+ int pageCount() const;
+ void setVisible(bool visible);
+
+public Q_SLOTS:
+ void print();
+
+ void zoomIn(qreal zoom = 1.1);
+ void zoomOut(qreal zoom = 1.1);
+ void setZoomFactor(qreal zoomFactor);
+ void setOrientation(QPrinter::Orientation orientation);
+ void setViewMode(ViewMode viewMode);
+ void setZoomMode(ZoomMode zoomMode);
+ void setCurrentPage(int pageNumber);
+
+ void fitToWidth();
+ void fitInView();
+ void setLandscapeOrientation();
+ void setPortraitOrientation();
+ void setSinglePageViewMode();
+ void setFacingPagesViewMode();
+ void setAllPagesViewMode();
+
+ void updatePreview();
+
+Q_SIGNALS:
+ void paintRequested(QPrinter *printer);
+ void previewChanged();
+
+private:
+ void *dummy; // ### remove in Qt 5.0
+ Q_PRIVATE_SLOT(d_func(), void _q_fit())
+ Q_PRIVATE_SLOT(d_func(), void _q_updateCurrentPage())
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QT_NO_PRINTPREVIEWWIDGET
+#endif // QPRINTPREVIEWWIDGET_H
diff --git a/src/printsupport/widgets/widgets.pri b/src/printsupport/widgets/widgets.pri
new file mode 100644
index 0000000000..40eb306623
--- /dev/null
+++ b/src/printsupport/widgets/widgets.pri
@@ -0,0 +1,2 @@
+HEADERS += widgets/qprintpreviewwidget.h
+SOURCES += widgets/qprintpreviewwidget.cpp
diff --git a/src/sql/models/qsqlrelationaldelegate.h b/src/sql/models/qsqlrelationaldelegate.h
index 76565461ef..93f0089c71 100644
--- a/src/sql/models/qsqlrelationaldelegate.h
+++ b/src/sql/models/qsqlrelationaldelegate.h
@@ -44,9 +44,9 @@
#ifdef QT_GUI_LIB
-#include <QtGui/qitemdelegate.h>
-#include <QtGui/qlistview.h>
-#include <QtGui/qcombobox.h>
+#include <QtWidgets/qitemdelegate.h>
+#include <QtWidgets/qlistview.h>
+#include <QtWidgets/qcombobox.h>
#include <QtSql/qsqlrelationaltablemodel.h>
QT_BEGIN_HEADER
diff --git a/src/src.pro b/src/src.pro
index 55a0ad3034..4263c0eb92 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -4,16 +4,20 @@ TEMPLATE = subdirs
unset(SRC_SUBDIRS)
win32:SRC_SUBDIRS += src_winmain
symbian:SRC_SUBDIRS += src_s60main
-SRC_SUBDIRS += src_corelib src_network src_sql src_testlib src_xml src_uitools
+!wince*:!symbian-abld:!symbian-sbsv2:include(tools/tools.pro)
+SRC_SUBDIRS += src_corelib
+# TODO: Move idc to ActiveQt
+!cross_compile {
+ win32:!wince*: SRC_SUBDIRS += src_tools_idc
+}
+SRC_SUBDIRS += src_network src_sql src_gui src_xml src_uitools src_widgets src_printsupport src_testlib src_platformsupport
nacl: SRC_SUBDIRS -= src_network src_testlib
!symbian:contains(QT_CONFIG, dbus):SRC_SUBDIRS += src_dbus
-!contains(QT_CONFIG, no-gui): SRC_SUBDIRS += src_gui
-contains(QT_CONFIG, v8): SRC_SUBDIRS += src_v8
-!wince*:!symbian-abld:!symbian-sbsv2:include(tools/tools.pro)
+contains(QT_CONFIG, no-gui): SRC_SUBDIRS -= src_gui
+contains(QT_CONFIG, v8): SRC_SUBDIRS += src_v8
contains(QT_CONFIG, opengl)|contains(QT_CONFIG, opengles1)|contains(QT_CONFIG, opengles2): SRC_SUBDIRS += src_opengl
-contains(QT_CONFIG, openvg): SRC_SUBDIRS += src_openvg
SRC_SUBDIRS += src_plugins
# s60installs need to be at the end, because qtbase.pro does an ordered build,
@@ -44,29 +48,35 @@ src_network.subdir = $$QT_SOURCE_TREE/src/network
src_network.target = sub-network
src_opengl.subdir = $$QT_SOURCE_TREE/src/opengl
src_opengl.target = sub-opengl
-src_openvg.subdir = $$QT_SOURCE_TREE/src/openvg
-src_openvg.target = sub-openvg
src_plugins.subdir = $$QT_SOURCE_TREE/src/plugins
src_plugins.target = sub-plugins
+src_widgets.subdir = $$QT_SOURCE_TREE/src/widgets
+src_widgets.target = sub-widgets
+src_printsupport.subdir = $$QT_SOURCE_TREE/src/printsupport
+src_printsupport.target = sub-printsupport
src_testlib.subdir = $$QT_SOURCE_TREE/src/testlib
src_testlib.target = sub-testlib
+src_platformsupport.subdir = $$QT_SOURCE_TREE/src/platformsupport
+src_platformsupport.target = sub-platformsupport
+
#CONFIG += ordered
!wince*:!ordered:!symbian-abld:!symbian-sbsv2 {
src_corelib.depends = src_tools_moc src_tools_rcc
- src_gui.depends = src_corelib src_tools_uic
+ src_gui.depends = src_corelib
+ src_printsupport.depends = src_corelib src_gui src_widgets
+ src_widgets.depends = src_corelib src_gui src_tools_uic
embedded: src_gui.depends += src_network
src_xml.depends = src_corelib
- src_uitools.depends = src_corelib src_xml
+ src_uitools.depends = src_corelib src_widgets
src_dbus.depends = src_corelib src_xml
src_network.depends = src_corelib
- src_opengl.depends = src_gui
- src_openvg.depends = src_gui
+ src_opengl.depends = src_gui src_widgets
src_sql.depends = src_corelib
- src_testlib.depends = src_corelib
+ src_testlib.depends = src_corelib src_gui src_widgets
src_tools_idc.depends = src_corelib # target defined in tools.pro
- src_tools_uic3.depends = src_qt3support src_xml # target defined in tools.pro
src_plugins.depends = src_gui src_sql src_xml
+ qpa: src_plugins.depends = src_platformsupport
src_s60installs.depends = $$TOOLS_SUBDIRS $$SRC_SUBDIRS
src_s60installs.depends -= src_s60installs
contains(QT_CONFIG, opengl)|contains(QT_CONFIG, opengles1)|contains(QT_CONFIG, opengles2) {
diff --git a/src/testlib/qasciikey.cpp b/src/testlib/qasciikey.cpp
index 874b9a06c7..80e94acd0b 100644
--- a/src/testlib/qasciikey.cpp
+++ b/src/testlib/qasciikey.cpp
@@ -59,6 +59,8 @@ Qt::Key QTest::asciiToKey(char ascii)
case 0x0b: return Qt::Key_Backtab;
case 0x0d: return Qt::Key_Return;
case 0x1b: return Qt::Key_Escape;
+ case 0x13: return Qt::Key_Up;
+ case 0x15: return Qt::Key_Down;
case 0x20: return Qt::Key_Space;
case 0x21: return Qt::Key_Exclam;
case 0x22: return Qt::Key_QuoteDbl;
diff --git a/src/testlib/qbenchmark.cpp b/src/testlib/qbenchmark.cpp
index 8894d41bee..49fad5da4d 100644
--- a/src/testlib/qbenchmark.cpp
+++ b/src/testlib/qbenchmark.cpp
@@ -44,7 +44,7 @@
#include "QtTest/private/qbenchmarkmetric_p.h"
#ifdef QT_GUI_LIB
-#include <QtGui/qapplication.h>
+#include <QtGui/qguiapplication.h>
#endif
#include <QtCore/qprocess.h>
diff --git a/src/testlib/qtest.h b/src/testlib/qtest.h
index 386f154f72..e671828b77 100644
--- a/src/testlib/qtest.h
+++ b/src/testlib/qtest.h
@@ -247,7 +247,7 @@ int main(int argc, char *argv[]) \
#include <QtTest/qtestsystem.h>
-#ifdef QT_GUI_LIB
+#if defined(QT_WIDGETS_LIB)
#include <QtTest/qtest_gui.h>
@@ -266,6 +266,18 @@ int main(int argc, char *argv[]) \
return QTest::qExec(&tc, argc, argv); \
}
+#elif defined(QT_GUI_LIB)
+
+#include <QtTest/qtest_gui.h>
+
+#define QTEST_MAIN(TestObject) \
+int main(int argc, char *argv[]) \
+{ \
+ QGuiApplication app(argc, argv); \
+ TestObject tc; \
+ return QTest::qExec(&tc, argc, argv); \
+}
+
#else
#define QTEST_MAIN(TestObject) \
diff --git a/src/testlib/qtest_gui.h b/src/testlib/qtest_gui.h
index 722e20d961..77b19f0e21 100644
--- a/src/testlib/qtest_gui.h
+++ b/src/testlib/qtest_gui.h
@@ -57,7 +57,7 @@
#include <QtTest/qtesttouch.h>
#include <QtTest/qtestkeyboard.h>
-#include <QtGui/qicon.h>
+#include <QtWidgets/qicon.h>
#include <QtGui/qpixmap.h>
#if 0
diff --git a/src/testlib/qtestaccessible.h b/src/testlib/qtestaccessible.h
index 9cec1a6bbe..a58ed2ff69 100644
--- a/src/testlib/qtestaccessible.h
+++ b/src/testlib/qtestaccessible.h
@@ -53,8 +53,8 @@
QVERIFY(QTestAccessibility::verifyEvent(object, child, (int)event))
#include <QtCore/qlist.h>
-#include <QtGui/qaccessible.h>
-#include <QtGui/qapplication.h>
+#include <QtWidgets/qaccessible.h>
+#include <QtWidgets/qapplication.h>
QT_BEGIN_HEADER
diff --git a/src/testlib/qtestkeyboard.h b/src/testlib/qtestkeyboard.h
index 43fed84abc..4dfdaeaf56 100644
--- a/src/testlib/qtestkeyboard.h
+++ b/src/testlib/qtestkeyboard.h
@@ -53,9 +53,10 @@
#include <QtTest/qtestspontaneevent.h>
#include <QtCore/qpointer.h>
-#include <QtGui/qapplication.h>
+#include <QtWidgets/qapplication.h>
#include <QtGui/qevent.h>
-#include <QtGui/qwidget.h>
+#include <QtWidgets/qwidget.h>
+#include <QtGui/qwindowsysteminterface_qpa.h>
QT_BEGIN_HEADER
@@ -83,6 +84,14 @@ namespace QTest
if (!qApp->notify(widget, &a))
QTest::qWarn("Keyboard event not accepted by receiving widget");
}
+ //QWindow overload
+ static void simulateEvent(QWindow *window, bool press, int code,
+ Qt::KeyboardModifiers modifier, QString text, bool repeat, int delay=-1)
+ {
+ QEvent::Type type;
+ type = press ? QEvent::KeyPress : QEvent::KeyRelease;
+ QWindowSystemInterface::handleKeyEvent(window, type, code, modifier, text, repeat, delay);
+ }
static void sendKeyEvent(KeyAction action, QWidget *widget, Qt::Key code,
QString text, Qt::KeyboardModifiers modifier, int delay=-1)
@@ -147,6 +156,52 @@ namespace QTest
simulateEvent(widget, false, Qt::Key_Shift, modifier & Qt::ShiftModifier, QString(), false, delay);
}
}
+ //QWindow overload
+ static void sendKeyEvent(KeyAction action, QWindow *window, Qt::Key code,
+ QString text, Qt::KeyboardModifiers modifier, int delay=-1)
+ {
+ QTEST_ASSERT(qApp);
+ QTEST_ASSERT(window);
+
+ if (action == Click) {
+ sendKeyEvent(Press, window, code, text, modifier, delay);
+ sendKeyEvent(Release, window, code, text, modifier, delay);
+ return;
+ }
+
+ bool repeat = false;
+
+ if (action == Press) {
+ if (modifier & Qt::ShiftModifier)
+ simulateEvent(window, true, Qt::Key_Shift, 0, QString(), false, delay);
+
+ if (modifier & Qt::ControlModifier)
+ simulateEvent(window, true, Qt::Key_Control, modifier & Qt::ShiftModifier, QString(), false, delay);
+
+ if (modifier & Qt::AltModifier)
+ simulateEvent(window, true, Qt::Key_Alt,
+ modifier & (Qt::ShiftModifier | Qt::ControlModifier), QString(), false, delay);
+ if (modifier & Qt::MetaModifier)
+ simulateEvent(window, true, Qt::Key_Meta, modifier & (Qt::ShiftModifier
+ | Qt::ControlModifier | Qt::AltModifier), QString(), false, delay);
+ simulateEvent(window, true, code, modifier, text, repeat, delay);
+ } else if (action == Release) {
+ simulateEvent(window, false, code, modifier, text, repeat, delay);
+
+ if (modifier & Qt::MetaModifier)
+ simulateEvent(window, false, Qt::Key_Meta, modifier, QString(), false, delay);
+ if (modifier & Qt::AltModifier)
+ simulateEvent(window, false, Qt::Key_Alt, modifier &
+ (Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier), QString(), false, delay);
+
+ if (modifier & Qt::ControlModifier)
+ simulateEvent(window, false, Qt::Key_Control,
+ modifier & (Qt::ShiftModifier | Qt::ControlModifier), QString(), false, delay);
+
+ if (modifier & Qt::ShiftModifier)
+ simulateEvent(window, false, Qt::Key_Shift, modifier & Qt::ShiftModifier, QString(), false, delay);
+ }
+ }
// Convenience function
static void sendKeyEvent(KeyAction action, QWidget *widget, Qt::Key code,
@@ -157,6 +212,15 @@ namespace QTest
text = QString(QChar::fromLatin1(ascii));
sendKeyEvent(action, widget, code, text, modifier, delay);
}
+ // QWindow convenience function
+ static void sendKeyEvent(KeyAction action, QWindow *window, Qt::Key code,
+ char ascii, Qt::KeyboardModifiers modifier, int delay=-1)
+ {
+ QString text;
+ if (ascii)
+ text = QString(QChar::fromLatin1(ascii));
+ sendKeyEvent(action, window, code, text, modifier, delay);
+ }
inline static void keyEvent(KeyAction action, QWidget *widget, char ascii,
Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
@@ -165,6 +229,14 @@ namespace QTest
Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
{ sendKeyEvent(action, widget, key, keyToAscii(key), modifier, delay); }
+ //Support QWindow
+ inline static void keyEvent(KeyAction action, QWindow *window, char ascii,
+ Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
+ { sendKeyEvent(action, window, asciiToKey(ascii), ascii, modifier, delay); }
+ inline static void keyEvent(KeyAction action, QWindow *window, Qt::Key key,
+ Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
+ { sendKeyEvent(action, window, key, keyToAscii(key), modifier, delay); }
+ ///////////////
inline static void keyClicks(QWidget *widget, const QString &sequence,
Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
{
@@ -184,6 +256,17 @@ namespace QTest
{ keyEvent(Release, widget, key, modifier, delay); }
inline static void keyClick(QWidget *widget, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
{ keyEvent(Click, widget, key, modifier, delay); }
+ //Support QWindow
+ inline static void keyClick(QWindow *window, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
+ { keyEvent(Click, window, key, modifier, delay); }
+ inline static void keyClick(QWindow *window, char key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
+ { keyEvent(Click, window, key, modifier, delay); }
+ inline static void keyRelease(QWindow *window, char key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
+ { keyEvent(Release, window, key, modifier, delay); }
+ inline static void keyPress(QWindow *window, char key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
+ { keyEvent(Press, window, key, modifier, delay); }
+ inline static void keyPress(QWindow *window, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
+ { keyEvent(Press, window, key, modifier, delay); }
}
diff --git a/src/testlib/qtestmouse.h b/src/testlib/qtestmouse.h
index 942b041eb1..dfd07a9d42 100644
--- a/src/testlib/qtestmouse.h
+++ b/src/testlib/qtestmouse.h
@@ -51,12 +51,12 @@
#include <QtTest/qtestassert.h>
#include <QtTest/qtestsystem.h>
#include <QtTest/qtestspontaneevent.h>
-
#include <QtCore/qpoint.h>
#include <QtCore/qstring.h>
-#include <QtGui/qapplication.h>
+#include <QtWidgets/qapplication.h>
#include <QtGui/qevent.h>
-#include <QtGui/qwidget.h>
+#include <QtWidgets/qwidget.h>
+#include <QtGui/qwindowsysteminterface_qpa.h>
QT_BEGIN_HEADER
@@ -126,6 +126,66 @@ namespace QTest
}
+ static void mouseEvent(MouseAction action, QWindow *window, Qt::MouseButton button,
+ Qt::KeyboardModifiers stateKey, QPoint pos, int delay=-1)
+ {
+ QTEST_ASSERT(window);
+ extern int Q_TESTLIB_EXPORT defaultMouseDelay();
+
+ static Qt::MouseButton lastButton = Qt::NoButton;
+
+ if (delay == -1 || delay < defaultMouseDelay())
+ delay = defaultMouseDelay();
+ if (delay > 0)
+ QTest::qWait(delay);
+
+ if (pos.isNull())
+ pos = window->geometry().center();
+
+ if (action == MouseClick) {
+ mouseEvent(MousePress, window, button, stateKey, pos);
+ mouseEvent(MouseRelease, window, button, stateKey, pos);
+ return;
+ }
+ QTEST_ASSERT(button == Qt::NoButton || button & Qt::MouseButtonMask);
+ QTEST_ASSERT(stateKey == 0 || stateKey & Qt::KeyboardModifierMask);
+
+ stateKey &= static_cast<unsigned int>(Qt::KeyboardModifierMask);
+
+
+ switch (action)
+ {
+ case MousePress:
+ QWindowSystemInterface::handleMouseEvent(window,pos,window->mapToGlobal(pos),button);
+ lastButton = button;
+ break;
+ case MouseRelease:
+ QWindowSystemInterface::handleMouseEvent(window,pos,window->mapToGlobal(pos),Qt::NoButton);
+ lastButton = Qt::NoButton;
+ break;
+ case MouseDClick:
+ QWindowSystemInterface::handleMouseEvent(window,pos,window->mapToGlobal(pos),button);
+ qWait(10);
+ QWindowSystemInterface::handleMouseEvent(window,pos,window->mapToGlobal(pos),Qt::NoButton);
+ qWait(20);
+ QWindowSystemInterface::handleMouseEvent(window,pos,window->mapToGlobal(pos),button);
+ qWait(10);
+ QWindowSystemInterface::handleMouseEvent(window,pos,window->mapToGlobal(pos),Qt::NoButton);
+ break;
+ case MouseMove:
+ QWindowSystemInterface::handleMouseEvent(window,pos,window->mapToGlobal(pos),lastButton);
+ //QCursor::setPos(window->mapToGlobal(pos));
+#ifdef QT_MAC_USE_COCOA
+ QTest::qWait(20);
+#else
+ qApp->processEvents();
+#endif
+ return;
+ default:
+ QTEST_ASSERT(false);
+ }
+ }
+
inline void mousePress(QWidget *widget, Qt::MouseButton button, Qt::KeyboardModifiers stateKey = 0,
QPoint pos = QPoint(), int delay=-1)
{ mouseEvent(MousePress, widget, button, stateKey, pos, delay); }
@@ -141,6 +201,21 @@ namespace QTest
inline void mouseMove(QWidget *widget, QPoint pos = QPoint(), int delay=-1)
{ mouseEvent(MouseMove, widget, Qt::NoButton, 0, pos, delay); }
+ //Support QWindow
+ inline void mousePress(QWindow *window, Qt::MouseButton button, Qt::KeyboardModifiers stateKey = 0,
+ QPoint pos = QPoint(), int delay=-1)
+ { mouseEvent(MousePress, window, button, stateKey, pos, delay); }
+ inline void mouseRelease(QWindow *window, Qt::MouseButton button, Qt::KeyboardModifiers stateKey = 0,
+ QPoint pos = QPoint(), int delay=-1)
+ { mouseEvent(MouseRelease, window, button, stateKey, pos, delay); }
+ inline void mouseClick(QWindow *window, Qt::MouseButton button, Qt::KeyboardModifiers stateKey = 0,
+ QPoint pos = QPoint(), int delay=-1)
+ { mouseEvent(MouseClick, window, button, stateKey, pos, delay); }
+ inline void mouseDClick(QWindow *window, Qt::MouseButton button, Qt::KeyboardModifiers stateKey = 0,
+ QPoint pos = QPoint(), int delay=-1)
+ { mouseEvent(MouseDClick, window, button, stateKey, pos, delay); }
+ inline void mouseMove(QWindow *window, QPoint pos = QPoint(), int delay=-1)
+ { mouseEvent(MouseMove, window, Qt::NoButton, 0, pos, delay); }
}
QT_END_NAMESPACE
diff --git a/src/testlib/qtestsystem.h b/src/testlib/qtestsystem.h
index de20abeeee..0165e51528 100644
--- a/src/testlib/qtestsystem.h
+++ b/src/testlib/qtestsystem.h
@@ -45,6 +45,7 @@
#include <QtTest/qtestcase.h>
#include <QtCore/qcoreapplication.h>
#include <QtCore/qelapsedtimer.h>
+#include <QtGui/QWindow>
QT_BEGIN_HEADER
@@ -82,6 +83,12 @@ namespace QTest
#endif
return true;
}
+ inline static bool qWaitForWindowShown(QWindow *window)
+ {
+ Q_UNUSED(window);
+ qWait(200);
+ return true;
+ }
}
diff --git a/src/testlib/qtesttouch.h b/src/testlib/qtesttouch.h
index a1fe2df382..c855677189 100644
--- a/src/testlib/qtesttouch.h
+++ b/src/testlib/qtesttouch.h
@@ -51,10 +51,10 @@
#include <QtTest/qtestassert.h>
#include <QtTest/qtestsystem.h>
#include <QtTest/qtestspontaneevent.h>
-
+#include <QtGui/QWindowSystemInterface>
#include <QtCore/qmap.h>
#include <QtGui/qevent.h>
-#include <QtGui/qwidget.h>
+#include <QtWidgets/qwidget.h>
QT_BEGIN_HEADER
@@ -84,6 +84,14 @@ namespace QTest
p.setState(Qt::TouchPointPressed);
return *this;
}
+ QTouchEventSequence& press(int touchId, const QPoint &pt, QWindow *window = 0)
+ {
+ QTouchEvent::TouchPoint &p = point(touchId);
+ p.setScreenPos(mapToScreen(window, pt));
+ p.setState(Qt::TouchPointPressed);
+ return *this;
+ }
+
QTouchEventSequence& move(int touchId, const QPoint &pt, QWidget *widget = 0)
{
QTouchEvent::TouchPoint &p = point(touchId);
@@ -91,6 +99,13 @@ namespace QTest
p.setState(Qt::TouchPointMoved);
return *this;
}
+ QTouchEventSequence& move(int touchId, const QPoint &pt, QWindow *window = 0)
+ {
+ QTouchEvent::TouchPoint &p = point(touchId);
+ p.setScreenPos(mapToScreen(window, pt));
+ p.setState(Qt::TouchPointMoved);
+ return *this;
+ }
QTouchEventSequence& release(int touchId, const QPoint &pt, QWidget *widget = 0)
{
QTouchEvent::TouchPoint &p = point(touchId);
@@ -98,6 +113,13 @@ namespace QTest
p.setState(Qt::TouchPointReleased);
return *this;
}
+ QTouchEventSequence& release(int touchId, const QPoint &pt, QWindow *window = 0)
+ {
+ QTouchEvent::TouchPoint &p = point(touchId);
+ p.setScreenPos(mapToScreen(window, pt));
+ p.setState(Qt::TouchPointReleased);
+ return *this;
+ }
QTouchEventSequence& stationary(int touchId)
{
QTouchEvent::TouchPoint &p = point(touchId);
@@ -110,6 +132,10 @@ namespace QTest
: targetWidget(widget), deviceType(aDeviceType)
{
}
+ QTouchEventSequence(QWindow *window, QTouchEvent::DeviceType aDeviceType)
+ : targetWindow(window), deviceType(aDeviceType)
+ {
+ }
QTouchEventSequence(const QTouchEventSequence &v);
void operator=(const QTouchEventSequence&);
@@ -125,16 +151,53 @@ namespace QTest
return widget->mapToGlobal(pt);
return targetWidget ? targetWidget->mapToGlobal(pt) : pt;
}
+ QPoint mapToScreen(QWindow *window, const QPoint &pt)
+ {
+ if(window)
+ return window->mapToGlobal(pt);
+ return targetWindow ? targetWindow->mapToGlobal(pt) : pt;
+ }
+ QWindowSystemInterface::TouchPoint touchPoint(const QTouchEvent::TouchPoint& point)
+ {
+ QWindowSystemInterface::TouchPoint p;
+ p.id = point.id();
+ p.isPrimary = point.isPrimary();
+ p.normalPosition = point.screenRect().topLeft();
+ p.area = point.screenRect();
+ p.pressure = point.pressure();
+ p.state = point.state();
+ return p;
+ }
+ QList<struct QWindowSystemInterface::TouchPoint> touchPointList(const QList<QTouchEvent::TouchPoint>& pointList)
+ {
+ QList<struct QWindowSystemInterface::TouchPoint> newList;
+
+ foreach(QTouchEvent::TouchPoint p, pointList)
+ {
+ newList.append(touchPoint(p));
+ }
+ return newList;
+ }
void commit()
{
- qt_translateRawTouchEvent(targetWidget, deviceType, points.values());
- targetWidget = 0;
+ if(targetWindow)
+ {
+ QWindowSystemInterface::handleTouchEvent(targetWindow,QEvent::None,deviceType, touchPointList(points.values()));
+ targetWindow = 0;
+ }
+ else if(targetWidget)
+ {
+ qt_translateRawTouchEvent(targetWidget, deviceType, points.values());
+ targetWidget = 0;
+ }
}
QMap<int, QTouchEvent::TouchPoint> points;
QWidget *targetWidget;
+ QWindow *targetWindow;
QTouchEvent::DeviceType deviceType;
friend QTouchEventSequence touchEvent(QWidget *, QTouchEvent::DeviceType);
+ friend QTouchEventSequence touchEvent(QWindow *, QTouchEvent::DeviceType);
};
inline
@@ -143,6 +206,12 @@ namespace QTest
{
return QTouchEventSequence(widget, deviceType);
}
+ inline
+ QTouchEventSequence touchEvent(QWindow *window = 0,
+ QTouchEvent::DeviceType deviceType = QTouchEvent::TouchScreen)
+ {
+ return QTouchEventSequence(window, deviceType);
+ }
}
diff --git a/src/testlib/testlib.pro b/src/testlib/testlib.pro
index d4dec9660e..e8858ea1c4 100644
--- a/src/testlib/testlib.pro
+++ b/src/testlib/testlib.pro
@@ -2,7 +2,7 @@ load(qt_module)
TARGET = QtTest
QPRO_PWD = $$PWD
-QT = core
+QT = core gui widgets
CONFIG += module
MODULE_PRI = ../modules/qt_testlib.pri
diff --git a/src/tools/bootstrap/bootstrap.pro b/src/tools/bootstrap/bootstrap.pro
index 6ff948c8e8..11d35b7509 100644
--- a/src/tools/bootstrap/bootstrap.pro
+++ b/src/tools/bootstrap/bootstrap.pro
@@ -108,7 +108,6 @@ else:unix:SOURCES += ../../corelib/tools/qlocale_unix.cpp
else:win32:SOURCES += ../../corelib/tools/qlocale_win.cpp
macx: {
- QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.4 #enables weak linking for 10.4 (exported)
SOURCES += ../../corelib/io/qfilesystemengine_mac.cpp
SOURCES += ../../corelib/kernel/qcore_mac.cpp
LIBS += -framework CoreServices
diff --git a/src/tools/idc/idc.pro b/src/tools/idc/idc.pro
index c33de6797c..5338ffb832 100644
--- a/src/tools/idc/idc.pro
+++ b/src/tools/idc/idc.pro
@@ -6,6 +6,8 @@ build_all:!build_pass {
CONFIG += release
}
+QT -= gui
+
DESTDIR = ../../../bin
SOURCES = main.cpp
diff --git a/src/tools/tools.pro b/src/tools/tools.pro
index ca42da6edf..47e216efc9 100644
--- a/src/tools/tools.pro
+++ b/src/tools/tools.pro
@@ -2,10 +2,6 @@ TEMPLATE = subdirs
TOOLS_SUBDIRS = src_tools_bootstrap src_tools_moc src_tools_rcc
!contains(QT_CONFIG, no-gui): TOOLS_SUBDIRS += src_tools_uic
-!cross_compile {
- win32:!wince*: SRC_SUBDIRS += src_tools_idc
-}
-
# Set subdir and respective target name
src_tools_bootstrap.subdir = $$QT_SOURCE_TREE/src/tools/bootstrap
src_tools_bootstrap.target = sub-tools-bootstrap
diff --git a/src/tools/uic/qclass_lib_map.h b/src/tools/uic/qclass_lib_map.h
index cf5a53deff..09d275d8a1 100644
--- a/src/tools/uic/qclass_lib_map.h
+++ b/src/tools/uic/qclass_lib_map.h
@@ -603,163 +603,94 @@ QT_CLASS_LIB(QSQLite2Result, QtSql, qsql_sqlite2.h)
QT_CLASS_LIB(QSQLite2Driver, QtSql, qsql_sqlite2.h)
QT_CLASS_LIB(QTDSResult, QtSql, qsql_tds.h)
QT_CLASS_LIB(QTDSDriver, QtSql, qsql_tds.h)
-QT_CLASS_LIB(QAccessible, QtGui, qaccessible.h)
-QT_CLASS_LIB(QAccessibleInterface, QtGui, qaccessible.h)
-QT_CLASS_LIB(QAccessibleInterfaceEx, QtGui, qaccessible.h)
-QT_CLASS_LIB(QAccessibleEvent, QtGui, qaccessible.h)
-QT_CLASS_LIB(QAccessible2Interface, QtGui, qaccessible2.h)
-QT_CLASS_LIB(QAccessibleTextInterface, QtGui, qaccessible2.h)
-QT_CLASS_LIB(QAccessibleEditableTextInterface, QtGui, qaccessible2.h)
-QT_CLASS_LIB(QAccessibleSimpleEditableTextInterface, QtGui, qaccessible2.h)
-QT_CLASS_LIB(QAccessibleValueInterface, QtGui, qaccessible2.h)
-QT_CLASS_LIB(QAccessibleTableInterface, QtGui, qaccessible2.h)
-QT_CLASS_LIB(QAccessibleActionInterface, QtGui, qaccessible2.h)
-QT_CLASS_LIB(QAccessibleImageInterface, QtGui, qaccessible2.h)
-QT_CLASS_LIB(QAccessibleBridge, QtGui, qaccessiblebridge.h)
-QT_CLASS_LIB(QAccessibleBridgeFactoryInterface, QtGui, qaccessiblebridge.h)
-QT_CLASS_LIB(QAccessibleBridgePlugin, QtGui, qaccessiblebridge.h)
-QT_CLASS_LIB(QAccessibleObject, QtGui, qaccessibleobject.h)
-QT_CLASS_LIB(QAccessibleObjectEx, QtGui, qaccessibleobject.h)
-QT_CLASS_LIB(QAccessibleApplication, QtGui, qaccessibleobject.h)
-QT_CLASS_LIB(QAccessibleFactoryInterface, QtGui, qaccessibleplugin.h)
-QT_CLASS_LIB(QAccessiblePlugin, QtGui, qaccessibleplugin.h)
-QT_CLASS_LIB(QAccessibleWidget, QtGui, qaccessiblewidget.h)
-QT_CLASS_LIB(QAccessibleWidgetEx, QtGui, qaccessiblewidget.h)
-QT_CLASS_LIB(QAbstractPageSetupDialog, QtGui, qabstractpagesetupdialog.h)
-QT_CLASS_LIB(QAbstractPrintDialog, QtGui, qabstractprintdialog.h)
-QT_CLASS_LIB(QColorDialog, QtGui, qcolordialog.h)
-QT_CLASS_LIB(QDialog, QtGui, qdialog.h)
-QT_CLASS_LIB(QErrorMessage, QtGui, qerrormessage.h)
-QT_CLASS_LIB(QFileDialog, QtGui, qfiledialog.h)
-QT_CLASS_LIB(QFileSystemModel, QtGui, qfilesystemmodel.h)
-QT_CLASS_LIB(QFontDialog, QtGui, qfontdialog.h)
-QT_CLASS_LIB(QInputDialog, QtGui, qinputdialog.h)
-QT_CLASS_LIB(QMessageBox, QtGui, qmessagebox.h)
-QT_CLASS_LIB(QPageSetupDialog, QtGui, qpagesetupdialog.h)
-QT_CLASS_LIB(QUnixPrintWidget, QtGui, qprintdialog.h)
-QT_CLASS_LIB(QPrintDialog, QtGui, qprintdialog.h)
-QT_CLASS_LIB(QPrintPreviewDialog, QtGui, qprintpreviewdialog.h)
-QT_CLASS_LIB(QProgressDialog, QtGui, qprogressdialog.h)
-QT_CLASS_LIB(QWizard, QtGui, qwizard.h)
-QT_CLASS_LIB(QWizardPage, QtGui, qwizard.h)
-QT_CLASS_LIB(QGraphicsEffect, QtGui, qgraphicseffect.h)
-QT_CLASS_LIB(QGraphicsColorizeEffect, QtGui, qgraphicseffect.h)
-QT_CLASS_LIB(QGraphicsBlurEffect, QtGui, qgraphicseffect.h)
-QT_CLASS_LIB(QGraphicsDropShadowEffect, QtGui, qgraphicseffect.h)
-QT_CLASS_LIB(QGraphicsOpacityEffect, QtGui, qgraphicseffect.h)
-QT_CLASS_LIB(QCopChannel, QtGui, qcopchannel_qws.h)
-QT_CLASS_LIB(QDecorationAction, QtGui, qdecoration_qws.h)
-QT_CLASS_LIB(QDecoration, QtGui, qdecoration_qws.h)
-QT_CLASS_LIB(QDecorationDefault, QtGui, qdecorationdefault_qws.h)
-QT_CLASS_LIB(QDecorationFactory, QtGui, qdecorationfactory_qws.h)
-QT_CLASS_LIB(QDecorationFactoryInterface, QtGui, qdecorationplugin_qws.h)
-QT_CLASS_LIB(QDecorationPlugin, QtGui, qdecorationplugin_qws.h)
-QT_CLASS_LIB(QDecorationStyled, QtGui, qdecorationstyled_qws.h)
-QT_CLASS_LIB(QDecorationWindows, QtGui, qdecorationwindows_qws.h)
-QT_CLASS_LIB(QDirectPainter, QtGui, qdirectpainter_qws.h)
-QT_CLASS_LIB(QWSKeyboardHandler, QtGui, qkbd_qws.h)
-QT_CLASS_LIB(QKbdDriverFactory, QtGui, qkbddriverfactory_qws.h)
-QT_CLASS_LIB(QWSKeyboardHandlerFactoryInterface, QtGui, qkbddriverplugin_qws.h)
-QT_CLASS_LIB(QKbdDriverPlugin, QtGui, qkbddriverplugin_qws.h)
-QT_CLASS_LIB(QWSLinuxInputKeyboardHandler, QtGui, qkbdlinuxinput_qws.h)
-QT_CLASS_LIB(QWSQnxKeyboardHandler, QtGui, qkbdqnx_qws.h)
-QT_CLASS_LIB(QWSTtyKeyboardHandler, QtGui, qkbdtty_qws.h)
-QT_CLASS_LIB(QWSUmKeyboardHandler, QtGui, qkbdum_qws.h)
-QT_CLASS_LIB(QVFbKeyboardHandler, QtGui, qkbdvfb_qws.h)
-QT_CLASS_LIB(QWSPointerCalibrationData, QtGui, qmouse_qws.h)
-QT_CLASS_LIB(QWSMouseHandler, QtGui, qmouse_qws.h)
-QT_CLASS_LIB(QWSCalibratedMouseHandler, QtGui, qmouse_qws.h)
-QT_CLASS_LIB(QMouseDriverFactory, QtGui, qmousedriverfactory_qws.h)
-QT_CLASS_LIB(QWSMouseHandlerFactoryInterface, QtGui, qmousedriverplugin_qws.h)
-QT_CLASS_LIB(QMouseDriverPlugin, QtGui, qmousedriverplugin_qws.h)
-QT_CLASS_LIB(QWSLinuxInputMouseHandler, QtGui, qmouselinuxinput_qws.h)
-QT_CLASS_LIB(QWSLinuxTPMouseHandler, QtGui, qmouselinuxtp_qws.h)
-QT_CLASS_LIB(QWSPcMouseHandler, QtGui, qmousepc_qws.h)
-QT_CLASS_LIB(QQnxMouseHandler, QtGui, qmouseqnx_qws.h)
-QT_CLASS_LIB(QWSTslibMouseHandler, QtGui, qmousetslib_qws.h)
-QT_CLASS_LIB(QVFbMouseHandler, QtGui, qmousevfb_qws.h)
-QT_CLASS_LIB(QScreenCursor, QtGui, qscreen_qws.h)
-QT_CLASS_LIB(QPoolEntry, QtGui, qscreen_qws.h)
-QT_CLASS_LIB(QScreen, QtGui, qscreen_qws.h)
-QT_CLASS_LIB(QScreenDriverFactory, QtGui, qscreendriverfactory_qws.h)
-QT_CLASS_LIB(QScreenDriverFactoryInterface, QtGui, qscreendriverplugin_qws.h)
-QT_CLASS_LIB(QScreenDriverPlugin, QtGui, qscreendriverplugin_qws.h)
-QT_CLASS_LIB(QLinuxFb_Shared, QtGui, qscreenlinuxfb_qws.h)
-QT_CLASS_LIB(QLinuxFbScreen, QtGui, qscreenlinuxfb_qws.h)
-QT_CLASS_LIB(QProxyScreenCursor, QtGui, qscreenproxy_qws.h)
-QT_CLASS_LIB(QProxyScreen, QtGui, qscreenproxy_qws.h)
-QT_CLASS_LIB(QQnxScreen, QtGui, qscreenqnx_qws.h)
-QT_CLASS_LIB(QTransformedScreen, QtGui, qscreentransformed_qws.h)
-QT_CLASS_LIB(QVFbScreen, QtGui, qscreenvfb_qws.h)
-QT_CLASS_LIB(QWSSoundServer, QtGui, qsoundqss_qws.h)
-QT_CLASS_LIB(QWSSoundClient, QtGui, qsoundqss_qws.h)
-QT_CLASS_LIB(QWSSoundServerSocket, QtGui, qsoundqss_qws.h)
-QT_CLASS_LIB(QTransportAuth, QtGui, qtransportauth_qws.h)
-QT_CLASS_LIB(QAuthDevice, QtGui, qtransportauth_qws.h)
-QT_CLASS_LIB(QVFbHeader, QtGui, qvfbhdr.h)
-QT_CLASS_LIB(QVFbKeyData, QtGui, qvfbhdr.h)
-QT_CLASS_LIB(QWSInternalWindowInfo, QtGui, qwindowsystem_qws.h)
-QT_CLASS_LIB(QWSScreenSaver, QtGui, qwindowsystem_qws.h)
-QT_CLASS_LIB(QWSWindow, QtGui, qwindowsystem_qws.h)
-QT_CLASS_LIB(QWSSoundServer, QtGui, qwindowsystem_qws.h)
-QT_CLASS_LIB(QWSServer, QtGui, qwindowsystem_qws.h)
-QT_CLASS_LIB(QWSInputMethod, QtGui, qwindowsystem_qws.h)
-QT_CLASS_LIB(QWSCursorMap, QtGui, qwindowsystem_qws.h)
-QT_CLASS_LIB(QWSClient, QtGui, qwindowsystem_qws.h)
-QT_CLASS_LIB(QWSCursor, QtGui, qwscursor_qws.h)
-QT_CLASS_LIB(QWSWindowInfo, QtGui, qwsdisplay_qws.h)
-QT_CLASS_LIB(QWSDisplay, QtGui, qwsdisplay_qws.h)
-QT_CLASS_LIB(QWSEmbedWidget, QtGui, qwsembedwidget.h)
-QT_CLASS_LIB(QWSEvent, QtGui, qwsevent_qws.h)
-QT_CLASS_LIB(QWSManager, QtGui, qwsmanager_qws.h)
-QT_CLASS_LIB(QWSPropertyManager, QtGui, qwsproperty_qws.h)
-QT_CLASS_LIB(QWSProtocolItem, QtGui, qwsprotocolitem_qws.h)
-QT_CLASS_LIB(QWSSocket, QtGui, qwssocket_qws.h)
-QT_CLASS_LIB(QWSServerSocket, QtGui, qwssocket_qws.h)
-QT_CLASS_LIB(QGraphicsAnchor, QtGui, qgraphicsanchorlayout.h)
-QT_CLASS_LIB(QGraphicsAnchorLayout, QtGui, qgraphicsanchorlayout.h)
-QT_CLASS_LIB(QGraphicsGridLayout, QtGui, qgraphicsgridlayout.h)
-QT_CLASS_LIB(QGraphicsItem, QtGui, qgraphicsitem.h)
-QT_CLASS_LIB(QGraphicsObject, QtGui, qgraphicsitem.h)
-QT_CLASS_LIB(QAbstractGraphicsShapeItem, QtGui, qgraphicsitem.h)
-QT_CLASS_LIB(QGraphicsPathItem, QtGui, qgraphicsitem.h)
-QT_CLASS_LIB(QGraphicsRectItem, QtGui, qgraphicsitem.h)
-QT_CLASS_LIB(QGraphicsEllipseItem, QtGui, qgraphicsitem.h)
-QT_CLASS_LIB(QGraphicsPolygonItem, QtGui, qgraphicsitem.h)
-QT_CLASS_LIB(QGraphicsLineItem, QtGui, qgraphicsitem.h)
-QT_CLASS_LIB(QGraphicsPixmapItem, QtGui, qgraphicsitem.h)
-QT_CLASS_LIB(QGraphicsTextItem, QtGui, qgraphicsitem.h)
-QT_CLASS_LIB(QGraphicsSimpleTextItem, QtGui, qgraphicsitem.h)
-QT_CLASS_LIB(QGraphicsItemGroup, QtGui, qgraphicsitem.h)
-QT_CLASS_LIB(QGraphicsItemAnimation, QtGui, qgraphicsitemanimation.h)
-QT_CLASS_LIB(QGraphicsLayout, QtGui, qgraphicslayout.h)
-QT_CLASS_LIB(QGraphicsLayoutItem, QtGui, qgraphicslayoutitem.h)
-QT_CLASS_LIB(QGraphicsLinearLayout, QtGui, qgraphicslinearlayout.h)
-QT_CLASS_LIB(QGraphicsProxyWidget, QtGui, qgraphicsproxywidget.h)
-QT_CLASS_LIB(QGraphicsScene, QtGui, qgraphicsscene.h)
-QT_CLASS_LIB(QGraphicsSceneEvent, QtGui, qgraphicssceneevent.h)
-QT_CLASS_LIB(QGraphicsSceneMouseEvent, QtGui, qgraphicssceneevent.h)
-QT_CLASS_LIB(QGraphicsSceneWheelEvent, QtGui, qgraphicssceneevent.h)
-QT_CLASS_LIB(QGraphicsSceneContextMenuEvent, QtGui, qgraphicssceneevent.h)
-QT_CLASS_LIB(QGraphicsSceneHoverEvent, QtGui, qgraphicssceneevent.h)
-QT_CLASS_LIB(QGraphicsSceneHelpEvent, QtGui, qgraphicssceneevent.h)
-QT_CLASS_LIB(QGraphicsSceneDragDropEvent, QtGui, qgraphicssceneevent.h)
-QT_CLASS_LIB(QGraphicsSceneResizeEvent, QtGui, qgraphicssceneevent.h)
-QT_CLASS_LIB(QGraphicsSceneMoveEvent, QtGui, qgraphicssceneevent.h)
-QT_CLASS_LIB(QGraphicsTransform, QtGui, qgraphicstransform.h)
-QT_CLASS_LIB(QGraphicsScale, QtGui, qgraphicstransform.h)
-QT_CLASS_LIB(QGraphicsRotation, QtGui, qgraphicstransform.h)
-QT_CLASS_LIB(QGraphicsView, QtGui, qgraphicsview.h)
-QT_CLASS_LIB(QGraphicsWidget, QtGui, qgraphicswidget.h)
+QT_CLASS_LIB(QAccessible, QtWidgets, qaccessible.h)
+QT_CLASS_LIB(QAccessibleInterface, QtWidgets, qaccessible.h)
+QT_CLASS_LIB(QAccessibleInterfaceEx, QtWidgets, qaccessible.h)
+QT_CLASS_LIB(QAccessibleEvent, QtWidgets, qaccessible.h)
+QT_CLASS_LIB(QAccessible2Interface, QtWidgets, qaccessible2.h)
+QT_CLASS_LIB(QAccessibleTextInterface, QtWidgets, qaccessible2.h)
+QT_CLASS_LIB(QAccessibleEditableTextInterface, QtWidgets, qaccessible2.h)
+QT_CLASS_LIB(QAccessibleSimpleEditableTextInterface, QtWidgets, qaccessible2.h)
+QT_CLASS_LIB(QAccessibleValueInterface, QtWidgets, qaccessible2.h)
+QT_CLASS_LIB(QAccessibleTableInterface, QtWidgets, qaccessible2.h)
+QT_CLASS_LIB(QAccessibleActionInterface, QtWidgets, qaccessible2.h)
+QT_CLASS_LIB(QAccessibleImageInterface, QtWidgets, qaccessible2.h)
+QT_CLASS_LIB(QAccessibleBridge, QtWidgets, qaccessiblebridge.h)
+QT_CLASS_LIB(QAccessibleBridgeFactoryInterface, QtWidgets, qaccessiblebridge.h)
+QT_CLASS_LIB(QAccessibleBridgePlugin, QtWidgets, qaccessiblebridge.h)
+QT_CLASS_LIB(QAccessibleObject, QtWidgets, qaccessibleobject.h)
+QT_CLASS_LIB(QAccessibleObjectEx, QtWidgets, qaccessibleobject.h)
+QT_CLASS_LIB(QAccessibleApplication, QtWidgets, qaccessibleobject.h)
+QT_CLASS_LIB(QAccessibleFactoryInterface, QtWidgets, qaccessibleplugin.h)
+QT_CLASS_LIB(QAccessiblePlugin, QtWidgets, qaccessibleplugin.h)
+QT_CLASS_LIB(QAccessibleWidget, QtWidgets, qaccessiblewidget.h)
+QT_CLASS_LIB(QAccessibleWidgetEx, QtWidgets, qaccessiblewidget.h)
+QT_CLASS_LIB(QAbstractPageSetupDialog, QtWidgets, qabstractpagesetupdialog.h)
+QT_CLASS_LIB(QAbstractPrintDialog, QtWidgets, qabstractprintdialog.h)
+QT_CLASS_LIB(QColorDialog, QtWidgets, qcolordialog.h)
+QT_CLASS_LIB(QDialog, QtWidgets, qdialog.h)
+QT_CLASS_LIB(QErrorMessage, QtWidgets, qerrormessage.h)
+QT_CLASS_LIB(QFileDialog, QtWidgets, qfiledialog.h)
+QT_CLASS_LIB(QFileSystemModel, QtWidgets, qfilesystemmodel.h)
+QT_CLASS_LIB(QFontDialog, QtWidgets, qfontdialog.h)
+QT_CLASS_LIB(QInputDialog, QtWidgets, qinputdialog.h)
+QT_CLASS_LIB(QMessageBox, QtWidgets, qmessagebox.h)
+QT_CLASS_LIB(QPageSetupDialog, QtWidgets, qpagesetupdialog.h)
+QT_CLASS_LIB(QUnixPrintWidget, QtWidgets, qprintdialog.h)
+QT_CLASS_LIB(QPrintDialog, QtWidgets, qprintdialog.h)
+QT_CLASS_LIB(QPrintPreviewDialog, QtWidgets, qprintpreviewdialog.h)
+QT_CLASS_LIB(QProgressDialog, QtWidgets, qprogressdialog.h)
+QT_CLASS_LIB(QWizard, QtWidgets, qwizard.h)
+QT_CLASS_LIB(QWizardPage, QtWidgets, qwizard.h)
+QT_CLASS_LIB(QGraphicsEffect, QtWidgets, qgraphicseffect.h)
+QT_CLASS_LIB(QGraphicsColorizeEffect, QtWidgets, qgraphicseffect.h)
+QT_CLASS_LIB(QGraphicsBlurEffect, QtWidgets, qgraphicseffect.h)
+QT_CLASS_LIB(QGraphicsDropShadowEffect, QtWidgets, qgraphicseffect.h)
+QT_CLASS_LIB(QGraphicsOpacityEffect, QtWidgets, qgraphicseffect.h)
+QT_CLASS_LIB(QGraphicsAnchor, QtWidgets, qgraphicsanchorlayout.h)
+QT_CLASS_LIB(QGraphicsAnchorLayout, QtWidgets, qgraphicsanchorlayout.h)
+QT_CLASS_LIB(QGraphicsGridLayout, QtWidgets, qgraphicsgridlayout.h)
+QT_CLASS_LIB(QGraphicsItem, QtWidgets, qgraphicsitem.h)
+QT_CLASS_LIB(QGraphicsObject, QtWidgets, qgraphicsitem.h)
+QT_CLASS_LIB(QAbstractGraphicsShapeItem, QtWidgets, qgraphicsitem.h)
+QT_CLASS_LIB(QGraphicsPathItem, QtWidgets, qgraphicsitem.h)
+QT_CLASS_LIB(QGraphicsRectItem, QtWidgets, qgraphicsitem.h)
+QT_CLASS_LIB(QGraphicsEllipseItem, QtWidgets, qgraphicsitem.h)
+QT_CLASS_LIB(QGraphicsPolygonItem, QtWidgets, qgraphicsitem.h)
+QT_CLASS_LIB(QGraphicsLineItem, QtWidgets, qgraphicsitem.h)
+QT_CLASS_LIB(QGraphicsPixmapItem, QtWidgets, qgraphicsitem.h)
+QT_CLASS_LIB(QGraphicsTextItem, QtWidgets, qgraphicsitem.h)
+QT_CLASS_LIB(QGraphicsSimpleTextItem, QtWidgets, qgraphicsitem.h)
+QT_CLASS_LIB(QGraphicsItemGroup, QtWidgets, qgraphicsitem.h)
+QT_CLASS_LIB(QGraphicsItemAnimation, QtWidgets, qgraphicsitemanimation.h)
+QT_CLASS_LIB(QGraphicsLayout, QtWidgets, qgraphicslayout.h)
+QT_CLASS_LIB(QGraphicsLayoutItem, QtWidgets, qgraphicslayoutitem.h)
+QT_CLASS_LIB(QGraphicsLinearLayout, QtWidgets, qgraphicslinearlayout.h)
+QT_CLASS_LIB(QGraphicsProxyWidget, QtWidgets, qgraphicsproxywidget.h)
+QT_CLASS_LIB(QGraphicsScene, QtWidgets, qgraphicsscene.h)
+QT_CLASS_LIB(QGraphicsSceneEvent, QtWidgets, qgraphicssceneevent.h)
+QT_CLASS_LIB(QGraphicsSceneMouseEvent, QtWidgets, qgraphicssceneevent.h)
+QT_CLASS_LIB(QGraphicsSceneWheelEvent, QtWidgets, qgraphicssceneevent.h)
+QT_CLASS_LIB(QGraphicsSceneContextMenuEvent, QtWidgets, qgraphicssceneevent.h)
+QT_CLASS_LIB(QGraphicsSceneHoverEvent, QtWidgets, qgraphicssceneevent.h)
+QT_CLASS_LIB(QGraphicsSceneHelpEvent, QtWidgets, qgraphicssceneevent.h)
+QT_CLASS_LIB(QGraphicsSceneDragDropEvent, QtWidgets, qgraphicssceneevent.h)
+QT_CLASS_LIB(QGraphicsSceneResizeEvent, QtWidgets, qgraphicssceneevent.h)
+QT_CLASS_LIB(QGraphicsSceneMoveEvent, QtWidgets, qgraphicssceneevent.h)
+QT_CLASS_LIB(QGraphicsTransform, QtWidgets, qgraphicstransform.h)
+QT_CLASS_LIB(QGraphicsScale, QtWidgets, qgraphicstransform.h)
+QT_CLASS_LIB(QGraphicsRotation, QtWidgets, qgraphicstransform.h)
+QT_CLASS_LIB(QGraphicsView, QtWidgets, qgraphicsview.h)
+QT_CLASS_LIB(QGraphicsWidget, QtWidgets, qgraphicswidget.h)
QT_CLASS_LIB(QBitmap, QtGui, qbitmap.h)
-QT_CLASS_LIB(QIcon, QtGui, qicon.h)
-QT_CLASS_LIB(QIconSet, QtGui, qicon.h)
-QT_CLASS_LIB(QIconEngine, QtGui, qiconengine.h)
-QT_CLASS_LIB(QIconEngineV2, QtGui, qiconengine.h)
-QT_CLASS_LIB(QIconEngineFactoryInterface, QtGui, qiconengineplugin.h)
-QT_CLASS_LIB(QIconEnginePlugin, QtGui, qiconengineplugin.h)
-QT_CLASS_LIB(QIconEngineFactoryInterfaceV2, QtGui, qiconengineplugin.h)
-QT_CLASS_LIB(QIconEnginePluginV2, QtGui, qiconengineplugin.h)
+QT_CLASS_LIB(QIcon, QtWidgets, qicon.h)
+QT_CLASS_LIB(QIconSet, QtWidgets, qicon.h)
+QT_CLASS_LIB(QIconEngine, QtWidgets, qiconengine.h)
+QT_CLASS_LIB(QIconEngineV2, QtWidgets, qiconengine.h)
+QT_CLASS_LIB(QIconEngineFactoryInterface, QtWidgets, qiconengineplugin.h)
+QT_CLASS_LIB(QIconEnginePlugin, QtWidgets, qiconengineplugin.h)
+QT_CLASS_LIB(QIconEngineFactoryInterfaceV2, QtWidgets, qiconengineplugin.h)
+QT_CLASS_LIB(QIconEnginePluginV2, QtWidgets, qiconengineplugin.h)
QT_CLASS_LIB(QImageTextKeyLang, QtGui, qimage.h)
QT_CLASS_LIB(QImage, QtGui, qimage.h)
QT_CLASS_LIB(QImageIOHandler, QtGui, qimageiohandler.h)
@@ -774,55 +705,55 @@ QT_CLASS_LIB(QPictureFormatInterface, QtGui, qpictureformatplugin.h)
QT_CLASS_LIB(QPictureFormatPlugin, QtGui, qpictureformatplugin.h)
QT_CLASS_LIB(QPixmap, QtGui, qpixmap.h)
QT_CLASS_LIB(QPixmapCache, QtGui, qpixmapcache.h)
-QT_CLASS_LIB(QInputContext, QtGui, qinputcontext.h)
-QT_CLASS_LIB(QInputContextFactory, QtGui, qinputcontextfactory.h)
-QT_CLASS_LIB(QInputContextFactoryInterface, QtGui, qinputcontextplugin.h)
-QT_CLASS_LIB(QInputContextPlugin, QtGui, qinputcontextplugin.h)
-QT_CLASS_LIB(QAbstractItemDelegate, QtGui, qabstractitemdelegate.h)
-QT_CLASS_LIB(QAbstractItemView, QtGui, qabstractitemview.h)
-QT_CLASS_LIB(QAbstractProxyModel, QtGui, qabstractproxymodel.h)
-QT_CLASS_LIB(QColumnView, QtGui, qcolumnview.h)
-QT_CLASS_LIB(QDataWidgetMapper, QtGui, qdatawidgetmapper.h)
-QT_CLASS_LIB(QDirModel, QtGui, qdirmodel.h)
-QT_CLASS_LIB(QFileIconProvider, QtGui, qfileiconprovider.h)
-QT_CLASS_LIB(QHeaderView, QtGui, qheaderview.h)
-QT_CLASS_LIB(QItemDelegate, QtGui, qitemdelegate.h)
-QT_CLASS_LIB(QItemEditorCreatorBase, QtGui, qitemeditorfactory.h)
-QT_CLASS_LIB(QItemEditorCreator, QtGui, qitemeditorfactory.h)
-QT_CLASS_LIB(QStandardItemEditorCreator, QtGui, qitemeditorfactory.h)
-QT_CLASS_LIB(QItemEditorFactory, QtGui, qitemeditorfactory.h)
-QT_CLASS_LIB(QItemSelectionRange, QtGui, qitemselectionmodel.h)
-QT_CLASS_LIB(QItemSelectionModel, QtGui, qitemselectionmodel.h)
-QT_CLASS_LIB(QItemSelection, QtGui, qitemselectionmodel.h)
-QT_CLASS_LIB(QListView, QtGui, qlistview.h)
-QT_CLASS_LIB(QListWidgetItem, QtGui, qlistwidget.h)
-QT_CLASS_LIB(QListWidget, QtGui, qlistwidget.h)
-QT_CLASS_LIB(QProxyModel, QtGui, qproxymodel.h)
-QT_CLASS_LIB(QSortFilterProxyModel, QtGui, qsortfilterproxymodel.h)
-QT_CLASS_LIB(QStandardItem, QtGui, qstandarditemmodel.h)
-QT_CLASS_LIB(QStandardItemModel, QtGui, qstandarditemmodel.h)
-QT_CLASS_LIB(QStringListModel, QtGui, qstringlistmodel.h)
-QT_CLASS_LIB(QStyledItemDelegate, QtGui, qstyleditemdelegate.h)
-QT_CLASS_LIB(QTableView, QtGui, qtableview.h)
-QT_CLASS_LIB(QTableWidgetSelectionRange, QtGui, qtablewidget.h)
-QT_CLASS_LIB(QTableWidgetItem, QtGui, qtablewidget.h)
-QT_CLASS_LIB(QTableWidget, QtGui, qtablewidget.h)
-QT_CLASS_LIB(QTreeView, QtGui, qtreeview.h)
-QT_CLASS_LIB(QTreeWidgetItem, QtGui, qtreewidget.h)
-QT_CLASS_LIB(QTreeWidget, QtGui, qtreewidget.h)
-QT_CLASS_LIB(QTreeWidgetItemIterator, QtGui, qtreewidgetitemiterator.h)
-QT_CLASS_LIB(QAction, QtGui, qaction.h)
-QT_CLASS_LIB(QActionGroup, QtGui, qactiongroup.h)
-QT_CLASS_LIB(QApplication, QtGui, qapplication.h)
-QT_CLASS_LIB(QBoxLayout, QtGui, qboxlayout.h)
-QT_CLASS_LIB(QHBoxLayout, QtGui, qboxlayout.h)
-QT_CLASS_LIB(QVBoxLayout, QtGui, qboxlayout.h)
+QT_CLASS_LIB(QInputContext, QtWidgets, qinputcontext.h)
+QT_CLASS_LIB(QInputContextFactory, QtWidgets, qinputcontextfactory.h)
+QT_CLASS_LIB(QInputContextFactoryInterface, QtWidgets, qinputcontextplugin.h)
+QT_CLASS_LIB(QInputContextPlugin, QtWidgets, qinputcontextplugin.h)
+QT_CLASS_LIB(QAbstractItemDelegate, QtWidgets, qabstractitemdelegate.h)
+QT_CLASS_LIB(QAbstractItemView, QtWidgets, qabstractitemview.h)
+QT_CLASS_LIB(QAbstractProxyModel, QtWidgets, qabstractproxymodel.h)
+QT_CLASS_LIB(QColumnView, QtWidgets, qcolumnview.h)
+QT_CLASS_LIB(QDataWidgetMapper, QtWidgets, qdatawidgetmapper.h)
+QT_CLASS_LIB(QDirModel, QtWidgets, qdirmodel.h)
+QT_CLASS_LIB(QFileIconProvider, QtWidgets, qfileiconprovider.h)
+QT_CLASS_LIB(QHeaderView, QtWidgets, qheaderview.h)
+QT_CLASS_LIB(QItemDelegate, QtWidgets, qitemdelegate.h)
+QT_CLASS_LIB(QItemEditorCreatorBase, QtWidgets, qitemeditorfactory.h)
+QT_CLASS_LIB(QItemEditorCreator, QtWidgets, qitemeditorfactory.h)
+QT_CLASS_LIB(QStandardItemEditorCreator, QtWidgets, qitemeditorfactory.h)
+QT_CLASS_LIB(QItemEditorFactory, QtWidgets, qitemeditorfactory.h)
+QT_CLASS_LIB(QItemSelectionRange, QtWidgets, qitemselectionmodel.h)
+QT_CLASS_LIB(QItemSelectionModel, QtWidgets, qitemselectionmodel.h)
+QT_CLASS_LIB(QItemSelection, QtWidgets, qitemselectionmodel.h)
+QT_CLASS_LIB(QListView, QtWidgets, qlistview.h)
+QT_CLASS_LIB(QListWidgetItem, QtWidgets, qlistwidget.h)
+QT_CLASS_LIB(QListWidget, QtWidgets, qlistwidget.h)
+QT_CLASS_LIB(QProxyModel, QtWidgets, qproxymodel.h)
+QT_CLASS_LIB(QSortFilterProxyModel, QtWidgets, qsortfilterproxymodel.h)
+QT_CLASS_LIB(QStandardItem, QtWidgets, qstandarditemmodel.h)
+QT_CLASS_LIB(QStandardItemModel, QtWidgets, qstandarditemmodel.h)
+QT_CLASS_LIB(QStringListModel, QtWidgets, qstringlistmodel.h)
+QT_CLASS_LIB(QStyledItemDelegate, QtWidgets, qstyleditemdelegate.h)
+QT_CLASS_LIB(QTableView, QtWidgets, qtableview.h)
+QT_CLASS_LIB(QTableWidgetSelectionRange, QtWidgets, qtablewidget.h)
+QT_CLASS_LIB(QTableWidgetItem, QtWidgets, qtablewidget.h)
+QT_CLASS_LIB(QTableWidget, QtWidgets, qtablewidget.h)
+QT_CLASS_LIB(QTreeView, QtWidgets, qtreeview.h)
+QT_CLASS_LIB(QTreeWidgetItem, QtWidgets, qtreewidget.h)
+QT_CLASS_LIB(QTreeWidget, QtWidgets, qtreewidget.h)
+QT_CLASS_LIB(QTreeWidgetItemIterator, QtWidgets, qtreewidgetitemiterator.h)
+QT_CLASS_LIB(QAction, QtWidgets, qaction.h)
+QT_CLASS_LIB(QActionGroup, QtWidgets, qactiongroup.h)
+QT_CLASS_LIB(QApplication, QtWidgets, qapplication.h)
+QT_CLASS_LIB(QBoxLayout, QtWidgets, qboxlayout.h)
+QT_CLASS_LIB(QHBoxLayout, QtWidgets, qboxlayout.h)
+QT_CLASS_LIB(QVBoxLayout, QtWidgets, qboxlayout.h)
QT_CLASS_LIB(QClipboard, QtGui, qclipboard.h)
QT_CLASS_LIB(QCursor, QtGui, qcursor.h)
QT_CLASS_LIB(QCursor, QtGui, qcursor.h)
-QT_CLASS_LIB(QCursorShape, QtGui, qcursor.h)
-QT_CLASS_LIB(QDesktopWidget, QtGui, qdesktopwidget.h)
-QT_CLASS_LIB(QDrag, QtGui, qdrag.h)
+QT_CLASS_LIB(QCursorShape, QtWidgets, qcursor.h)
+QT_CLASS_LIB(QDesktopWidget, QtWidgets, qdesktopwidget.h)
+QT_CLASS_LIB(QDrag, QtWidgets, qdrag.h)
QT_CLASS_LIB(QtEvents, QtGui, qevent.h)
QT_CLASS_LIB(QInputEvent, QtGui, qevent.h)
QT_CLASS_LIB(QMouseEvent, QtGui, qevent.h)
@@ -844,7 +775,6 @@ QT_CLASS_LIB(QInputMethodEvent, QtGui, qevent.h)
QT_CLASS_LIB(QDropEvent, QtGui, qevent.h)
QT_CLASS_LIB(QDragMoveEvent, QtGui, qevent.h)
QT_CLASS_LIB(QDragEnterEvent, QtGui, qevent.h)
-QT_CLASS_LIB(QDragResponseEvent, QtGui, qevent.h)
QT_CLASS_LIB(QDragLeaveEvent, QtGui, qevent.h)
QT_CLASS_LIB(QHelpEvent, QtGui, qevent.h)
QT_CLASS_LIB(QStatusTipEvent, QtGui, qevent.h)
@@ -860,37 +790,36 @@ QT_CLASS_LIB(QTouchEvent, QtGui, qevent.h)
QT_CLASS_LIB(QGestureEvent, QtGui, qevent.h)
QT_CLASS_LIB(QScrollPrepareEvent, QtGui, qevent.h)
QT_CLASS_LIB(QScrollEvent, QtGui, qevent.h)
-QT_CLASS_LIB(QFormLayout, QtGui, qformlayout.h)
+QT_CLASS_LIB(QFormLayout, QtWidgets, qformlayout.h)
QT_CLASS_LIB(QGenericPluginFactoryInterface, QtGui, qgenericplugin_qpa.h)
QT_CLASS_LIB(QGenericPlugin, QtGui, qgenericplugin_qpa.h)
QT_CLASS_LIB(QGenericPluginFactory, QtGui, qgenericpluginfactory_qpa.h)
-QT_CLASS_LIB(QGesture, QtGui, qgesture.h)
-QT_CLASS_LIB(QPanGesture, QtGui, qgesture.h)
-QT_CLASS_LIB(QPinchGesture, QtGui, qgesture.h)
-QT_CLASS_LIB(QSwipeGesture, QtGui, qgesture.h)
-QT_CLASS_LIB(QTapGesture, QtGui, qgesture.h)
-QT_CLASS_LIB(QTapAndHoldGesture, QtGui, qgesture.h)
-QT_CLASS_LIB(QGestureRecognizer, QtGui, qgesturerecognizer.h)
-QT_CLASS_LIB(QGridLayout, QtGui, qgridlayout.h)
+QT_CLASS_LIB(QGesture, QtWidgets, qgesture.h)
+QT_CLASS_LIB(QPanGesture, QtWidgets, qgesture.h)
+QT_CLASS_LIB(QPinchGesture, QtWidgets, qgesture.h)
+QT_CLASS_LIB(QSwipeGesture, QtWidgets, qgesture.h)
+QT_CLASS_LIB(QTapGesture, QtWidgets, qgesture.h)
+QT_CLASS_LIB(QTapAndHoldGesture, QtWidgets, qgesture.h)
+QT_CLASS_LIB(QGestureRecognizer, QtWidgets, qgesturerecognizer.h)
+QT_CLASS_LIB(QGridLayout, QtWidgets, qgridlayout.h)
QT_CLASS_LIB(QKeySequence, QtGui, qkeysequence.h)
QT_CLASS_LIB(QKeySequence, QtGui, qkeysequence.h)
-QT_CLASS_LIB(QLayoutIterator, QtGui, qlayout.h)
-QT_CLASS_LIB(QLayout, QtGui, qlayout.h)
-QT_CLASS_LIB(QLayoutItem, QtGui, qlayoutitem.h)
-QT_CLASS_LIB(QSpacerItem, QtGui, qlayoutitem.h)
-QT_CLASS_LIB(QWidgetItem, QtGui, qlayoutitem.h)
-QT_CLASS_LIB(QWidgetItemV2, QtGui, qlayoutitem.h)
+QT_CLASS_LIB(QLayoutIterator, QtWidgets, qlayout.h)
+QT_CLASS_LIB(QLayout, QtWidgets, qlayout.h)
+QT_CLASS_LIB(QLayoutItem, QtWidgets, qlayoutitem.h)
+QT_CLASS_LIB(QSpacerItem, QtWidgets, qlayoutitem.h)
+QT_CLASS_LIB(QWidgetItem, QtWidgets, qlayoutitem.h)
+QT_CLASS_LIB(QWidgetItemV2, QtWidgets, qlayoutitem.h)
QT_CLASS_LIB(QMimeSource, QtGui, qmime.h)
QT_CLASS_LIB(QWindowsMime, QtGui, qmime.h)
QT_CLASS_LIB(QMacMime, QtGui, qmime.h)
QT_CLASS_LIB(QMacPasteboardMime, QtGui, qmime.h)
QT_CLASS_LIB(QPalette, QtGui, qpalette.h)
-QT_CLASS_LIB(QColorGroup, QtGui, qpalette.h)
+QT_CLASS_LIB(QColorGroup, QtWidgets, qpalette.h)
QT_CLASS_LIB(QPlatformCursorImage, QtGui, qplatformcursor_qpa.h)
QT_CLASS_LIB(QPlatformCursorPrivate, QtGui, qplatformcursor_qpa.h)
QT_CLASS_LIB(QPlatformCursor, QtGui, qplatformcursor_qpa.h)
-QT_CLASS_LIB(QPlatformEventLoopIntegration, QtGui, qplatformeventloopintegration_qpa.h)
-QT_CLASS_LIB(QPlatformGLContext, QtGui, qplatformglcontext_qpa.h)
+QT_CLASS_LIB(QPlatformOpenGLContext, QtGui, qplatformopenglcontext_qpa.h)
QT_CLASS_LIB(QPlatformIntegration, QtGui, qplatformintegration_qpa.h)
QT_CLASS_LIB(QPlatformIntegrationFactoryInterface, QtGui, qplatformintegrationplugin_qpa.h)
QT_CLASS_LIB(QPlatformIntegrationPlugin, QtGui, qplatformintegrationplugin_qpa.h)
@@ -898,22 +827,22 @@ QT_CLASS_LIB(QPlatformScreen, QtGui, qplatformscreen_qpa.h)
QT_CLASS_LIB(QPlatformWindow, QtGui, qplatformwindow_qpa.h)
QT_CLASS_LIB(QPlatformWindowFormat, QtGui, qplatformwindowformat_qpa.h)
QT_CLASS_LIB(QSessionManager, QtGui, qsessionmanager.h)
-QT_CLASS_LIB(QShortcut, QtGui, qshortcut.h)
-QT_CLASS_LIB(QSizePolicy, QtGui, qsizepolicy.h)
-QT_CLASS_LIB(QSound, QtGui, qsound.h)
-QT_CLASS_LIB(QStackedLayout, QtGui, qstackedlayout.h)
-QT_CLASS_LIB(QToolTip, QtGui, qtooltip.h)
-QT_CLASS_LIB(QWhatsThis, QtGui, qwhatsthis.h)
-QT_CLASS_LIB(QWidgetData, QtGui, qwidget.h)
-QT_CLASS_LIB(QWidget, QtGui, qwidget.h)
-QT_CLASS_LIB(QWidgetAction, QtGui, qwidgetaction.h)
-QT_CLASS_LIB(QWidgetList, QtGui, qwindowdefs.h)
-QT_CLASS_LIB(QWidgetMapper, QtGui, qwindowdefs.h)
-QT_CLASS_LIB(QWidgetSet, QtGui, qwindowdefs.h)
-QT_CLASS_LIB(QWindowSystemInterface, QtGui, qwindowsysteminterface_qpa.h)
-QT_CLASS_LIB(QX11EmbedWidget, QtGui, qx11embed_x11.h)
-QT_CLASS_LIB(QX11EmbedContainer, QtGui, qx11embed_x11.h)
-QT_CLASS_LIB(QX11Info, QtGui, qx11info_x11.h)
+QT_CLASS_LIB(QShortcut, QtWidgets, qshortcut.h)
+QT_CLASS_LIB(QSizePolicy, QtWidgets, qsizepolicy.h)
+QT_CLASS_LIB(QSound, QtWidgets, qsound.h)
+QT_CLASS_LIB(QStackedLayout, QtWidgets, qstackedlayout.h)
+QT_CLASS_LIB(QToolTip, QtWidgets, qtooltip.h)
+QT_CLASS_LIB(QWhatsThis, QtWidgets, qwhatsthis.h)
+QT_CLASS_LIB(QWidgetData, QtWidgets, qwidget.h)
+QT_CLASS_LIB(QWidget, QtWidgets, qwidget.h)
+QT_CLASS_LIB(QWidgetAction, QtWidgets, qwidgetaction.h)
+QT_CLASS_LIB(QWidgetList, QtWidgets, qwindowdefs.h)
+QT_CLASS_LIB(QWidgetMapper, QtWidgets, qwindowdefs.h)
+QT_CLASS_LIB(QWidgetSet, QtWidgets, qwindowdefs.h)
+QT_CLASS_LIB(QWindowSystemInterface, QtWidgets, qwindowsysteminterface_qpa.h)
+QT_CLASS_LIB(QX11EmbedWidget, QtWidgets, qx11embed_x11.h)
+QT_CLASS_LIB(QX11EmbedContainer, QtWidgets, qx11embed_x11.h)
+QT_CLASS_LIB(QX11Info, QtWidgets, qx11info_x11.h)
QT_CLASS_LIB(QGenericMatrix, QtGui, qgenericmatrix.h)
QT_CLASS_LIB(QMatrix2x2, QtGui, qgenericmatrix.h)
QT_CLASS_LIB(QMatrix2x3, QtGui, qgenericmatrix.h)
@@ -960,80 +889,80 @@ QT_CLASS_LIB(QStylePainter, QtGui, qstylepainter.h)
QT_CLASS_LIB(QTransform, QtGui, qtransform.h)
QT_CLASS_LIB(QWMatrix, QtGui, qwmatrix.h)
QT_CLASS_LIB(QS60MainApplicationBase, QtGui, qs60mainapplication.h)
-QT_CLASS_LIB(QS60MainApplicationBase, QtGui, qs60mainapplication.h)
-QT_CLASS_LIB(QS60MainApplication, QtGui, qs60mainapplication.h)
-QT_CLASS_LIB(QS60MainAppUiBase, QtGui, qs60mainappui.h)
-QT_CLASS_LIB(QS60StubAknAppUiBase, QtGui, qs60mainappui.h)
-QT_CLASS_LIB(QS60StubMEikStatusPaneObserver, QtGui, qs60mainappui.h)
-QT_CLASS_LIB(QS60StubMAknTouchPaneObserver, QtGui, qs60mainappui.h)
-QT_CLASS_LIB(QS60StubAknAppUi, QtGui, qs60mainappui.h)
-QT_CLASS_LIB(QS60MainAppUiBase, QtGui, qs60mainappui.h)
-QT_CLASS_LIB(QS60MainAppUi, QtGui, qs60mainappui.h)
-QT_CLASS_LIB(QS60MainDocumentBase, QtGui, qs60maindocument.h)
-QT_CLASS_LIB(QS60MainDocumentBase, QtGui, qs60maindocument.h)
-QT_CLASS_LIB(QS60MainDocument, QtGui, qs60maindocument.h)
-QT_CLASS_LIB(QKeyEventTransition, QtGui, qkeyeventtransition.h)
-QT_CLASS_LIB(QMouseEventTransition, QtGui, qmouseeventtransition.h)
-QT_CLASS_LIB(QCDEStyle, QtGui, qcdestyle.h)
-QT_CLASS_LIB(QCleanlooksStyle, QtGui, qcleanlooksstyle.h)
-QT_CLASS_LIB(QCommonStyle, QtGui, qcommonstyle.h)
-QT_CLASS_LIB(QGtkStyle, QtGui, qgtkstyle.h)
-QT_CLASS_LIB(QMacStyle, QtGui, qmacstyle_mac.h)
-QT_CLASS_LIB(QMotifStyle, QtGui, qmotifstyle.h)
-QT_CLASS_LIB(QPlastiqueStyle, QtGui, qplastiquestyle.h)
-QT_CLASS_LIB(QProxyStyle, QtGui, qproxystyle.h)
-QT_CLASS_LIB(QS60Style, QtGui, qs60style.h)
-QT_CLASS_LIB(QStyle, QtGui, qstyle.h)
-QT_CLASS_LIB(QStyleFactory, QtGui, qstylefactory.h)
-QT_CLASS_LIB(QStyleOption, QtGui, qstyleoption.h)
-QT_CLASS_LIB(QStyleOptionFocusRect, QtGui, qstyleoption.h)
-QT_CLASS_LIB(QStyleOptionFrame, QtGui, qstyleoption.h)
-QT_CLASS_LIB(QStyleOptionFrameV2, QtGui, qstyleoption.h)
-QT_CLASS_LIB(QStyleOptionFrameV3, QtGui, qstyleoption.h)
-QT_CLASS_LIB(QStyleOptionTabWidgetFrame, QtGui, qstyleoption.h)
-QT_CLASS_LIB(QStyleOptionTabWidgetFrameV2, QtGui, qstyleoption.h)
-QT_CLASS_LIB(QStyleOptionTabBarBase, QtGui, qstyleoption.h)
-QT_CLASS_LIB(QStyleOptionTabBarBaseV2, QtGui, qstyleoption.h)
-QT_CLASS_LIB(QStyleOptionHeader, QtGui, qstyleoption.h)
-QT_CLASS_LIB(QStyleOptionButton, QtGui, qstyleoption.h)
-QT_CLASS_LIB(QStyleOptionTab, QtGui, qstyleoption.h)
-QT_CLASS_LIB(QStyleOptionTabV2, QtGui, qstyleoption.h)
-QT_CLASS_LIB(QStyleOptionTabV3, QtGui, qstyleoption.h)
-QT_CLASS_LIB(QStyleOptionToolBar, QtGui, qstyleoption.h)
-QT_CLASS_LIB(QStyleOptionProgressBar, QtGui, qstyleoption.h)
-QT_CLASS_LIB(QStyleOptionProgressBarV2, QtGui, qstyleoption.h)
-QT_CLASS_LIB(QStyleOptionMenuItem, QtGui, qstyleoption.h)
-QT_CLASS_LIB(QStyleOptionQ3ListViewItem, QtGui, qstyleoption.h)
-QT_CLASS_LIB(QStyleOptionQ3DockWindow, QtGui, qstyleoption.h)
-QT_CLASS_LIB(QStyleOptionDockWidget, QtGui, qstyleoption.h)
-QT_CLASS_LIB(QStyleOptionDockWidgetV2, QtGui, qstyleoption.h)
-QT_CLASS_LIB(QStyleOptionViewItem, QtGui, qstyleoption.h)
-QT_CLASS_LIB(QStyleOptionViewItemV2, QtGui, qstyleoption.h)
-QT_CLASS_LIB(QStyleOptionViewItemV3, QtGui, qstyleoption.h)
-QT_CLASS_LIB(QStyleOptionViewItemV4, QtGui, qstyleoption.h)
-QT_CLASS_LIB(QStyleOptionToolBox, QtGui, qstyleoption.h)
-QT_CLASS_LIB(QStyleOptionToolBoxV2, QtGui, qstyleoption.h)
-QT_CLASS_LIB(QStyleOptionRubberBand, QtGui, qstyleoption.h)
-QT_CLASS_LIB(QStyleOptionComplex, QtGui, qstyleoption.h)
-QT_CLASS_LIB(QStyleOptionSlider, QtGui, qstyleoption.h)
-QT_CLASS_LIB(QStyleOptionSpinBox, QtGui, qstyleoption.h)
-QT_CLASS_LIB(QStyleOptionQ3ListView, QtGui, qstyleoption.h)
-QT_CLASS_LIB(QStyleOptionToolButton, QtGui, qstyleoption.h)
-QT_CLASS_LIB(QStyleOptionComboBox, QtGui, qstyleoption.h)
-QT_CLASS_LIB(QStyleOptionTitleBar, QtGui, qstyleoption.h)
-QT_CLASS_LIB(QStyleOptionGroupBox, QtGui, qstyleoption.h)
-QT_CLASS_LIB(QStyleOptionSizeGrip, QtGui, qstyleoption.h)
-QT_CLASS_LIB(QStyleOptionGraphicsItem, QtGui, qstyleoption.h)
-QT_CLASS_LIB(QStyleHintReturn, QtGui, qstyleoption.h)
-QT_CLASS_LIB(QStyleHintReturnMask, QtGui, qstyleoption.h)
-QT_CLASS_LIB(QStyleHintReturnVariant, QtGui, qstyleoption.h)
-QT_CLASS_LIB(QStyleFactoryInterface, QtGui, qstyleplugin.h)
-QT_CLASS_LIB(QStylePlugin, QtGui, qstyleplugin.h)
-QT_CLASS_LIB(QWindowsCEStyle, QtGui, qwindowscestyle.h)
-QT_CLASS_LIB(QWindowsMobileStyle, QtGui, qwindowsmobilestyle.h)
-QT_CLASS_LIB(QWindowsStyle, QtGui, qwindowsstyle.h)
-QT_CLASS_LIB(QWindowsVistaStyle, QtGui, qwindowsvistastyle.h)
-QT_CLASS_LIB(QWindowsXPStyle, QtGui, qwindowsxpstyle.h)
+QT_CLASS_LIB(QS60MainApplicationBase, QtWidgets, qs60mainapplication.h)
+QT_CLASS_LIB(QS60MainApplication, QtWidgets, qs60mainapplication.h)
+QT_CLASS_LIB(QS60MainAppUiBase, QtWidgets, qs60mainappui.h)
+QT_CLASS_LIB(QS60StubAknAppUiBase, QtWidgets, qs60mainappui.h)
+QT_CLASS_LIB(QS60StubMEikStatusPaneObserver, QtWidgets, qs60mainappui.h)
+QT_CLASS_LIB(QS60StubMAknTouchPaneObserver, QtWidgets, qs60mainappui.h)
+QT_CLASS_LIB(QS60StubAknAppUi, QtWidgets, qs60mainappui.h)
+QT_CLASS_LIB(QS60MainAppUiBase, QtWidgets, qs60mainappui.h)
+QT_CLASS_LIB(QS60MainAppUi, QtWidgets, qs60mainappui.h)
+QT_CLASS_LIB(QS60MainDocumentBase, QtWidgets, qs60maindocument.h)
+QT_CLASS_LIB(QS60MainDocumentBase, QtWidgets, qs60maindocument.h)
+QT_CLASS_LIB(QS60MainDocument, QtWidgets, qs60maindocument.h)
+QT_CLASS_LIB(QKeyEventTransition, QtWidgets, qkeyeventtransition.h)
+QT_CLASS_LIB(QMouseEventTransition, QtWidgets, qmouseeventtransition.h)
+QT_CLASS_LIB(QCDEStyle, QtWidgets, qcdestyle.h)
+QT_CLASS_LIB(QCleanlooksStyle, QtWidgets, qcleanlooksstyle.h)
+QT_CLASS_LIB(QCommonStyle, QtWidgets, qcommonstyle.h)
+QT_CLASS_LIB(QGtkStyle, QtWidgets, qgtkstyle.h)
+QT_CLASS_LIB(QMacStyle, QtWidgets, qmacstyle_mac.h)
+QT_CLASS_LIB(QMotifStyle, QtWidgets, qmotifstyle.h)
+QT_CLASS_LIB(QPlastiqueStyle, QtWidgets, qplastiquestyle.h)
+QT_CLASS_LIB(QProxyStyle, QtWidgets, qproxystyle.h)
+QT_CLASS_LIB(QS60Style, QtWidgets, qs60style.h)
+QT_CLASS_LIB(QStyle, QtWidgets, qstyle.h)
+QT_CLASS_LIB(QStyleFactory, QtWidgets, qstylefactory.h)
+QT_CLASS_LIB(QStyleOption, QtWidgets, qstyleoption.h)
+QT_CLASS_LIB(QStyleOptionFocusRect, QtWidgets, qstyleoption.h)
+QT_CLASS_LIB(QStyleOptionFrame, QtWidgets, qstyleoption.h)
+QT_CLASS_LIB(QStyleOptionFrameV2, QtWidgets, qstyleoption.h)
+QT_CLASS_LIB(QStyleOptionFrameV3, QtWidgets, qstyleoption.h)
+QT_CLASS_LIB(QStyleOptionTabWidgetFrame, QtWidgets, qstyleoption.h)
+QT_CLASS_LIB(QStyleOptionTabWidgetFrameV2, QtWidgets, qstyleoption.h)
+QT_CLASS_LIB(QStyleOptionTabBarBase, QtWidgets, qstyleoption.h)
+QT_CLASS_LIB(QStyleOptionTabBarBaseV2, QtWidgets, qstyleoption.h)
+QT_CLASS_LIB(QStyleOptionHeader, QtWidgets, qstyleoption.h)
+QT_CLASS_LIB(QStyleOptionButton, QtWidgets, qstyleoption.h)
+QT_CLASS_LIB(QStyleOptionTab, QtWidgets, qstyleoption.h)
+QT_CLASS_LIB(QStyleOptionTabV2, QtWidgets, qstyleoption.h)
+QT_CLASS_LIB(QStyleOptionTabV3, QtWidgets, qstyleoption.h)
+QT_CLASS_LIB(QStyleOptionToolBar, QtWidgets, qstyleoption.h)
+QT_CLASS_LIB(QStyleOptionProgressBar, QtWidgets, qstyleoption.h)
+QT_CLASS_LIB(QStyleOptionProgressBarV2, QtWidgets, qstyleoption.h)
+QT_CLASS_LIB(QStyleOptionMenuItem, QtWidgets, qstyleoption.h)
+QT_CLASS_LIB(QStyleOptionQ3ListViewItem, QtWidgets, qstyleoption.h)
+QT_CLASS_LIB(QStyleOptionQ3DockWindow, QtWidgets, qstyleoption.h)
+QT_CLASS_LIB(QStyleOptionDockWidget, QtWidgets, qstyleoption.h)
+QT_CLASS_LIB(QStyleOptionDockWidgetV2, QtWidgets, qstyleoption.h)
+QT_CLASS_LIB(QStyleOptionViewItem, QtWidgets, qstyleoption.h)
+QT_CLASS_LIB(QStyleOptionViewItemV2, QtWidgets, qstyleoption.h)
+QT_CLASS_LIB(QStyleOptionViewItemV3, QtWidgets, qstyleoption.h)
+QT_CLASS_LIB(QStyleOptionViewItemV4, QtWidgets, qstyleoption.h)
+QT_CLASS_LIB(QStyleOptionToolBox, QtWidgets, qstyleoption.h)
+QT_CLASS_LIB(QStyleOptionToolBoxV2, QtWidgets, qstyleoption.h)
+QT_CLASS_LIB(QStyleOptionRubberBand, QtWidgets, qstyleoption.h)
+QT_CLASS_LIB(QStyleOptionComplex, QtWidgets, qstyleoption.h)
+QT_CLASS_LIB(QStyleOptionSlider, QtWidgets, qstyleoption.h)
+QT_CLASS_LIB(QStyleOptionSpinBox, QtWidgets, qstyleoption.h)
+QT_CLASS_LIB(QStyleOptionQ3ListView, QtWidgets, qstyleoption.h)
+QT_CLASS_LIB(QStyleOptionToolButton, QtWidgets, qstyleoption.h)
+QT_CLASS_LIB(QStyleOptionComboBox, QtWidgets, qstyleoption.h)
+QT_CLASS_LIB(QStyleOptionTitleBar, QtWidgets, qstyleoption.h)
+QT_CLASS_LIB(QStyleOptionGroupBox, QtWidgets, qstyleoption.h)
+QT_CLASS_LIB(QStyleOptionSizeGrip, QtWidgets, qstyleoption.h)
+QT_CLASS_LIB(QStyleOptionGraphicsItem, QtWidgets, qstyleoption.h)
+QT_CLASS_LIB(QStyleHintReturn, QtWidgets, qstyleoption.h)
+QT_CLASS_LIB(QStyleHintReturnMask, QtWidgets, qstyleoption.h)
+QT_CLASS_LIB(QStyleHintReturnVariant, QtWidgets, qstyleoption.h)
+QT_CLASS_LIB(QStyleFactoryInterface, QtWidgets, qstyleplugin.h)
+QT_CLASS_LIB(QStylePlugin, QtWidgets, qstyleplugin.h)
+QT_CLASS_LIB(QWindowsCEStyle, QtWidgets, qwindowscestyle.h)
+QT_CLASS_LIB(QWindowsMobileStyle, QtWidgets, qwindowsmobilestyle.h)
+QT_CLASS_LIB(QWindowsStyle, QtWidgets, qwindowsstyle.h)
+QT_CLASS_LIB(QWindowsVistaStyle, QtWidgets, qwindowsvistastyle.h)
+QT_CLASS_LIB(QWindowsXPStyle, QtWidgets, qwindowsxpstyle.h)
QT_CLASS_LIB(QSymbianEvent, QtGui, qsymbianevent.h)
QT_CLASS_LIB(QFontEngineInfo, QtGui, qabstractfontengine_qws.h)
QT_CLASS_LIB(QFontEngineFactoryInterface, QtGui, qabstractfontengine_qws.h)
@@ -1078,76 +1007,76 @@ QT_CLASS_LIB(QTextBlock, QtGui, qtextobject.h)
QT_CLASS_LIB(QTextFragment, QtGui, qtextobject.h)
QT_CLASS_LIB(QTextOption, QtGui, qtextoption.h)
QT_CLASS_LIB(QTextTableCell, QtGui, qtexttable.h)
-QT_CLASS_LIB(QTextTable, QtGui, qtexttable.h)
-QT_CLASS_LIB(QCompleter, QtGui, qcompleter.h)
-QT_CLASS_LIB(QDesktopServices, QtGui, qdesktopservices.h)
-QT_CLASS_LIB(QScroller, QtGui, qscroller.h)
-QT_CLASS_LIB(QScrollerProperties, QtGui, qscrollerproperties.h)
+QT_CLASS_LIB(QTextTable, QtWidgets, qtexttable.h)
+QT_CLASS_LIB(QCompleter, QtWidgets, qcompleter.h)
+QT_CLASS_LIB(QDesktopServices, QtWidgets, qdesktopservices.h)
+QT_CLASS_LIB(QScroller, QtWidgets, qscroller.h)
+QT_CLASS_LIB(QScrollerProperties, QtWidgets, qscrollerproperties.h)
QT_CLASS_LIB(QSystemTrayIcon, QtGui, qsystemtrayicon.h)
-QT_CLASS_LIB(QUndoGroup, QtGui, qundogroup.h)
-QT_CLASS_LIB(QUndoCommand, QtGui, qundostack.h)
-QT_CLASS_LIB(QUndoStack, QtGui, qundostack.h)
-QT_CLASS_LIB(QUndoView, QtGui, qundoview.h)
-QT_CLASS_LIB(QAbstractButton, QtGui, qabstractbutton.h)
-QT_CLASS_LIB(QAbstractScrollArea, QtGui, qabstractscrollarea.h)
-QT_CLASS_LIB(QAbstractSlider, QtGui, qabstractslider.h)
-QT_CLASS_LIB(QAbstractSpinBox, QtGui, qabstractspinbox.h)
-QT_CLASS_LIB(QButtonGroup, QtGui, qbuttongroup.h)
-QT_CLASS_LIB(QCalendarWidget, QtGui, qcalendarwidget.h)
-QT_CLASS_LIB(QCheckBox, QtGui, qcheckbox.h)
-QT_CLASS_LIB(QComboBox, QtGui, qcombobox.h)
-QT_CLASS_LIB(QCommandLinkButton, QtGui, qcommandlinkbutton.h)
-QT_CLASS_LIB(QDateTimeEdit, QtGui, qdatetimeedit.h)
-QT_CLASS_LIB(QTimeEdit, QtGui, qdatetimeedit.h)
-QT_CLASS_LIB(QDateEdit, QtGui, qdatetimeedit.h)
-QT_CLASS_LIB(QDial, QtGui, qdial.h)
-QT_CLASS_LIB(QDialogButtonBox, QtGui, qdialogbuttonbox.h)
-QT_CLASS_LIB(QDockWidget, QtGui, qdockwidget.h)
-QT_CLASS_LIB(QFocusFrame, QtGui, qfocusframe.h)
-QT_CLASS_LIB(QFontComboBox, QtGui, qfontcombobox.h)
-QT_CLASS_LIB(QFrame, QtGui, qframe.h)
-QT_CLASS_LIB(QGroupBox, QtGui, qgroupbox.h)
-QT_CLASS_LIB(QLabel, QtGui, qlabel.h)
-QT_CLASS_LIB(QLCDNumber, QtGui, qlcdnumber.h)
-QT_CLASS_LIB(QLineEdit, QtGui, qlineedit.h)
-QT_CLASS_LIB(QMacCocoaViewContainer, QtGui, qmaccocoaviewcontainer_mac.h)
-QT_CLASS_LIB(QMacNativeWidget, QtGui, qmacnativewidget_mac.h)
-QT_CLASS_LIB(QMainWindow, QtGui, qmainwindow.h)
-QT_CLASS_LIB(QMdiArea, QtGui, qmdiarea.h)
-QT_CLASS_LIB(QMdiSubWindow, QtGui, qmdisubwindow.h)
-QT_CLASS_LIB(QMenu, QtGui, qmenu.h)
-QT_CLASS_LIB(QMenuBar, QtGui, qmenubar.h)
-QT_CLASS_LIB(QMenuItem, QtGui, qmenudata.h)
-QT_CLASS_LIB(QPlainTextEdit, QtGui, qplaintextedit.h)
-QT_CLASS_LIB(QPlainTextDocumentLayout, QtGui, qplaintextedit.h)
-QT_CLASS_LIB(QPrintPreviewWidget, QtGui, qprintpreviewwidget.h)
-QT_CLASS_LIB(QProgressBar, QtGui, qprogressbar.h)
-QT_CLASS_LIB(QPushButton, QtGui, qpushbutton.h)
-QT_CLASS_LIB(QRadioButton, QtGui, qradiobutton.h)
-QT_CLASS_LIB(QRubberBand, QtGui, qrubberband.h)
-QT_CLASS_LIB(QScrollArea, QtGui, qscrollarea.h)
-QT_CLASS_LIB(QScrollBar, QtGui, qscrollbar.h)
-QT_CLASS_LIB(QSizeGrip, QtGui, qsizegrip.h)
-QT_CLASS_LIB(QSlider, QtGui, qslider.h)
-QT_CLASS_LIB(QSpinBox, QtGui, qspinbox.h)
-QT_CLASS_LIB(QDoubleSpinBox, QtGui, qspinbox.h)
-QT_CLASS_LIB(QSplashScreen, QtGui, qsplashscreen.h)
-QT_CLASS_LIB(QSplitter, QtGui, qsplitter.h)
-QT_CLASS_LIB(QSplitterHandle, QtGui, qsplitter.h)
-QT_CLASS_LIB(QStackedWidget, QtGui, qstackedwidget.h)
-QT_CLASS_LIB(QStatusBar, QtGui, qstatusbar.h)
-QT_CLASS_LIB(QTabBar, QtGui, qtabbar.h)
-QT_CLASS_LIB(QTabWidget, QtGui, qtabwidget.h)
-QT_CLASS_LIB(QTextBrowser, QtGui, qtextbrowser.h)
-QT_CLASS_LIB(QTextEdit, QtGui, qtextedit.h)
-QT_CLASS_LIB(QToolBar, QtGui, qtoolbar.h)
-QT_CLASS_LIB(QToolBox, QtGui, qtoolbox.h)
-QT_CLASS_LIB(QToolButton, QtGui, qtoolbutton.h)
-QT_CLASS_LIB(QValidator, QtGui, qvalidator.h)
-QT_CLASS_LIB(QIntValidator, QtGui, qvalidator.h)
-QT_CLASS_LIB(QDoubleValidator, QtGui, qvalidator.h)
-QT_CLASS_LIB(QRegExpValidator, QtGui, qvalidator.h)
-QT_CLASS_LIB(QWorkspace, QtGui, qworkspace.h)
+QT_CLASS_LIB(QUndoGroup, QtWidgets, qundogroup.h)
+QT_CLASS_LIB(QUndoCommand, QtWidgets, qundostack.h)
+QT_CLASS_LIB(QUndoStack, QtWidgets, qundostack.h)
+QT_CLASS_LIB(QUndoView, QtWidgets, qundoview.h)
+QT_CLASS_LIB(QAbstractButton, QtWidgets, qabstractbutton.h)
+QT_CLASS_LIB(QAbstractScrollArea, QtWidgets, qabstractscrollarea.h)
+QT_CLASS_LIB(QAbstractSlider, QtWidgets, qabstractslider.h)
+QT_CLASS_LIB(QAbstractSpinBox, QtWidgets, qabstractspinbox.h)
+QT_CLASS_LIB(QButtonGroup, QtWidgets, qbuttongroup.h)
+QT_CLASS_LIB(QCalendarWidget, QtWidgets, qcalendarwidget.h)
+QT_CLASS_LIB(QCheckBox, QtWidgets, qcheckbox.h)
+QT_CLASS_LIB(QComboBox, QtWidgets, qcombobox.h)
+QT_CLASS_LIB(QCommandLinkButton, QtWidgets, qcommandlinkbutton.h)
+QT_CLASS_LIB(QDateTimeEdit, QtWidgets, qdatetimeedit.h)
+QT_CLASS_LIB(QTimeEdit, QtWidgets, qdatetimeedit.h)
+QT_CLASS_LIB(QDateEdit, QtWidgets, qdatetimeedit.h)
+QT_CLASS_LIB(QDial, QtWidgets, qdial.h)
+QT_CLASS_LIB(QDialogButtonBox, QtWidgets, qdialogbuttonbox.h)
+QT_CLASS_LIB(QDockWidget, QtWidgets, qdockwidget.h)
+QT_CLASS_LIB(QFocusFrame, QtWidgets, qfocusframe.h)
+QT_CLASS_LIB(QFontComboBox, QtWidgets, qfontcombobox.h)
+QT_CLASS_LIB(QFrame, QtWidgets, qframe.h)
+QT_CLASS_LIB(QGroupBox, QtWidgets, qgroupbox.h)
+QT_CLASS_LIB(QLabel, QtWidgets, qlabel.h)
+QT_CLASS_LIB(QLCDNumber, QtWidgets, qlcdnumber.h)
+QT_CLASS_LIB(QLineEdit, QtWidgets, qlineedit.h)
+QT_CLASS_LIB(QMacCocoaViewContainer, QtWidgets, qmaccocoaviewcontainer_mac.h)
+QT_CLASS_LIB(QMacNativeWidget, QtWidgets, qmacnativewidget_mac.h)
+QT_CLASS_LIB(QMainWindow, QtWidgets, qmainwindow.h)
+QT_CLASS_LIB(QMdiArea, QtWidgets, qmdiarea.h)
+QT_CLASS_LIB(QMdiSubWindow, QtWidgets, qmdisubwindow.h)
+QT_CLASS_LIB(QMenu, QtWidgets, qmenu.h)
+QT_CLASS_LIB(QMenuBar, QtWidgets, qmenubar.h)
+QT_CLASS_LIB(QMenuItem, QtWidgets, qmenudata.h)
+QT_CLASS_LIB(QPlainTextEdit, QtWidgets, qplaintextedit.h)
+QT_CLASS_LIB(QPlainTextDocumentLayout, QtWidgets, qplaintextedit.h)
+QT_CLASS_LIB(QPrintPreviewWidget, QtWidgets, qprintpreviewwidget.h)
+QT_CLASS_LIB(QProgressBar, QtWidgets, qprogressbar.h)
+QT_CLASS_LIB(QPushButton, QtWidgets, qpushbutton.h)
+QT_CLASS_LIB(QRadioButton, QtWidgets, qradiobutton.h)
+QT_CLASS_LIB(QRubberBand, QtWidgets, qrubberband.h)
+QT_CLASS_LIB(QScrollArea, QtWidgets, qscrollarea.h)
+QT_CLASS_LIB(QScrollBar, QtWidgets, qscrollbar.h)
+QT_CLASS_LIB(QSizeGrip, QtWidgets, qsizegrip.h)
+QT_CLASS_LIB(QSlider, QtWidgets, qslider.h)
+QT_CLASS_LIB(QSpinBox, QtWidgets, qspinbox.h)
+QT_CLASS_LIB(QDoubleSpinBox, QtWidgets, qspinbox.h)
+QT_CLASS_LIB(QSplashScreen, QtWidgets, qsplashscreen.h)
+QT_CLASS_LIB(QSplitter, QtWidgets, qsplitter.h)
+QT_CLASS_LIB(QSplitterHandle, QtWidgets, qsplitter.h)
+QT_CLASS_LIB(QStackedWidget, QtWidgets, qstackedwidget.h)
+QT_CLASS_LIB(QStatusBar, QtWidgets, qstatusbar.h)
+QT_CLASS_LIB(QTabBar, QtWidgets, qtabbar.h)
+QT_CLASS_LIB(QTabWidget, QtWidgets, qtabwidget.h)
+QT_CLASS_LIB(QTextBrowser, QtWidgets, qtextbrowser.h)
+QT_CLASS_LIB(QTextEdit, QtWidgets, qtextedit.h)
+QT_CLASS_LIB(QToolBar, QtWidgets, qtoolbar.h)
+QT_CLASS_LIB(QToolBox, QtWidgets, qtoolbox.h)
+QT_CLASS_LIB(QToolButton, QtWidgets, qtoolbutton.h)
+QT_CLASS_LIB(QValidator, QtWidgets, qvalidator.h)
+QT_CLASS_LIB(QIntValidator, QtWidgets, qvalidator.h)
+QT_CLASS_LIB(QDoubleValidator, QtWidgets, qvalidator.h)
+QT_CLASS_LIB(QRegExpValidator, QtWidgets, qvalidator.h)
+QT_CLASS_LIB(QWorkspace, QtWidgets, qworkspace.h)
QT_CLASS_LIB(QScriptEngineDebugger, QtScriptTools, qscriptenginedebugger.h)
QT_CLASS_LIB(QUiLoader, QtUiTools, quiloader.h)
QT_CLASS_LIB(QDesignerComponents, QtDesigner, qdesigner_components.h)
diff --git a/src/uitools/quiloader.cpp b/src/uitools/quiloader.cpp
index 20f4585163..19d4277aed 100644
--- a/src/uitools/quiloader.cpp
+++ b/src/uitools/quiloader.cpp
@@ -50,21 +50,21 @@
#include <ui4_p.h>
#include <QtCore/qdebug.h>
-#include <QtGui/QAction>
-#include <QtGui/QActionGroup>
-#include <QtGui/QApplication>
+#include <QtWidgets/QAction>
+#include <QtWidgets/QActionGroup>
+#include <QtWidgets/QApplication>
#include <QtCore/QDir>
#include <QtCore/QLibraryInfo>
-#include <QtGui/QLayout>
-#include <QtGui/QWidget>
+#include <QtWidgets/QLayout>
+#include <QtWidgets/QWidget>
#include <QtCore/QMap>
-#include <QtGui/QTabWidget>
-#include <QtGui/QTreeWidget>
-#include <QtGui/QListWidget>
-#include <QtGui/QTableWidget>
-#include <QtGui/QToolBox>
-#include <QtGui/QComboBox>
-#include <QtGui/QFontComboBox>
+#include <QtWidgets/QTabWidget>
+#include <QtWidgets/QTreeWidget>
+#include <QtWidgets/QListWidget>
+#include <QtWidgets/QTableWidget>
+#include <QtWidgets/QToolBox>
+#include <QtWidgets/QComboBox>
+#include <QtWidgets/QFontComboBox>
QT_BEGIN_NAMESPACE
diff --git a/src/v8/v8.pri b/src/v8/v8.pri
index 79c4bd0714..1d1abc85c0 100644
--- a/src/v8/v8.pri
+++ b/src/v8/v8.pri
@@ -9,6 +9,7 @@ equals(QT_ARCH, x86_64)|contains(CONFIG, x86_64):CONFIG += arch_x86_64
else:equals(QT_ARCH, "i386"):CONFIG += arch_i386
else:equals(QT_ARCH, "arm"):CONFIG += arch_arm
else:equals(QMAKE_HOST.arch, armv7l):CONFIG += arch_arm
+else:equals(QMAKE_HOST.arch, armv5tel):CONFIG += arch_arm
else:equals(QMAKE_HOST.arch, x86_64):CONFIG += arch_x86_64
else:equals(QMAKE_HOST.arch, x86):CONFIG += arch_i386
else:equals(QMAKE_HOST.arch, i386):CONFIG += arch_i386
diff --git a/src/gui/QtGui.dynlist b/src/widgets/QtGui.dynlist
index ea47f598a7..ea47f598a7 100644
--- a/src/gui/QtGui.dynlist
+++ b/src/widgets/QtGui.dynlist
diff --git a/src/widgets/accessible/accessible.pri b/src/widgets/accessible/accessible.pri
new file mode 100644
index 0000000000..ff75563eed
--- /dev/null
+++ b/src/widgets/accessible/accessible.pri
@@ -0,0 +1,25 @@
+# Qt accessibility module
+
+contains(QT_CONFIG, accessibility) {
+ HEADERS += accessible/qaccessible.h \
+ accessible/qaccessible2.h \
+ accessible/qaccessibleobject.h \
+ accessible/qaccessiblewidget.h \
+ accessible/qaccessibleplugin.h
+ SOURCES += accessible/qaccessible.cpp \
+ accessible/qaccessible2.cpp \
+ accessible/qaccessibleobject.cpp \
+ accessible/qaccessiblewidget.cpp \
+ accessible/qaccessibleplugin.cpp
+
+ mac:!qpa {
+ HEADERS += accessible/qaccessible_mac_p.h
+ OBJECTIVE_SOURCES += accessible/qaccessible_mac.mm \
+ accessible/qaccessible_mac_cocoa.mm
+ } else:win32:!qpa {
+ SOURCES += accessible/qaccessible_win.cpp
+ } else {
+ HEADERS += accessible/qaccessiblebridge.h
+ SOURCES += accessible/qaccessible_unix.cpp accessible/qaccessiblebridge.cpp
+ }
+}
diff --git a/src/gui/accessible/qaccessible.cpp b/src/widgets/accessible/qaccessible.cpp
index 10e5785cd5..10e5785cd5 100644
--- a/src/gui/accessible/qaccessible.cpp
+++ b/src/widgets/accessible/qaccessible.cpp
diff --git a/src/widgets/accessible/qaccessible.h b/src/widgets/accessible/qaccessible.h
new file mode 100644
index 0000000000..3a59810866
--- /dev/null
+++ b/src/widgets/accessible/qaccessible.h
@@ -0,0 +1,472 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QACCESSIBLE_H
+#define QACCESSIBLE_H
+
+#include <QtCore/qglobal.h>
+#include <QtCore/qobject.h>
+#include <QtCore/qrect.h>
+#include <QtCore/qset.h>
+#include <QtCore/qvector.h>
+#include <QtCore/qvariant.h>
+#include <QtGui/qcolor.h>
+#include <QtGui/qevent.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_ACCESSIBILITY
+
+class QAccessibleInterface;
+
+class Q_WIDGETS_EXPORT QAccessible
+{
+public:
+ enum Event {
+ SoundPlayed = 0x0001,
+ Alert = 0x0002,
+ ForegroundChanged = 0x0003,
+ MenuStart = 0x0004,
+ MenuEnd = 0x0005,
+ PopupMenuStart = 0x0006,
+ PopupMenuEnd = 0x0007,
+ ContextHelpStart = 0x000C,
+ ContextHelpEnd = 0x000D,
+ DragDropStart = 0x000E,
+ DragDropEnd = 0x000F,
+ DialogStart = 0x0010,
+ DialogEnd = 0x0011,
+ ScrollingStart = 0x0012,
+ ScrollingEnd = 0x0013,
+
+ MenuCommand = 0x0018,
+
+ // Values from IAccessible2
+ ActionChanged = 0x0101,
+ ActiveDescendantChanged = 0x0102,
+ AttributeChanged = 0x0103,
+ DocumentContentChanged = 0x0104,
+ DocumentLoadComplete = 0x0105,
+ DocumentLoadStopped = 0x0106,
+ DocumentReload = 0x0107,
+ HyperlinkEndIndexChanged = 0x0108,
+ HyperlinkNumberOfAnchorsChanged = 0x0109,
+ HyperlinkSelectedLinkChanged = 0x010A,
+ HypertextLinkActivated = 0x010B,
+ HypertextLinkSelected = 0x010C,
+ HyperlinkStartIndexChanged = 0x010D,
+ HypertextChanged = 0x010E,
+ HypertextNLinksChanged = 0x010F,
+ ObjectAttributeChanged = 0x0110,
+ PageChanged = 0x0111,
+ SectionChanged = 0x0112,
+ TableCaptionChanged = 0x0113,
+ TableColumnDescriptionChanged = 0x0114,
+ TableColumnHeaderChanged = 0x0115,
+ TableModelChanged = 0x0116,
+ TableRowDescriptionChanged = 0x0117,
+ TableRowHeaderChanged = 0x0118,
+ TableSummaryChanged = 0x0119,
+ TextAttributeChanged = 0x011A,
+ TextCaretMoved = 0x011B,
+ // TextChanged = 0x011C, is deprecated in IA2, use TextUpdated
+ TextColumnChanged = 0x011D,
+ TextInserted = 0x011E,
+ TextRemoved = 0x011F,
+ TextUpdated = 0x0120,
+ TextSelectionChanged = 0x0121,
+ VisibleDataChanged = 0x0122,
+
+ ObjectCreated = 0x8000,
+ ObjectDestroyed = 0x8001,
+ ObjectShow = 0x8002,
+ ObjectHide = 0x8003,
+ ObjectReorder = 0x8004,
+ Focus = 0x8005,
+ Selection = 0x8006,
+ SelectionAdd = 0x8007,
+ SelectionRemove = 0x8008,
+ SelectionWithin = 0x8009,
+ StateChanged = 0x800A,
+ LocationChanged = 0x800B,
+ NameChanged = 0x800C,
+ DescriptionChanged = 0x800D,
+ ValueChanged = 0x800E,
+ ParentChanged = 0x800F,
+ HelpChanged = 0x80A0,
+ DefaultActionChanged = 0x80B0,
+ AcceleratorChanged = 0x80C0
+ };
+
+ enum StateFlag {
+ Normal = 0x00000000,
+ Unavailable = 0x00000001,
+ Selected = 0x00000002,
+ Focused = 0x00000004,
+ Pressed = 0x00000008,
+ Checked = 0x00000010,
+ Mixed = 0x00000020,
+ ReadOnly = 0x00000040,
+ HotTracked = 0x00000080,
+ DefaultButton = 0x00000100,
+ // #### Qt5 Expandable
+ Expanded = 0x00000200,
+ Collapsed = 0x00000400,
+ Busy = 0x00000800,
+ // Floating = 0x00001000,
+ Marqueed = 0x00002000,
+ Animated = 0x00004000,
+ Invisible = 0x00008000,
+ Offscreen = 0x00010000,
+ Sizeable = 0x00020000,
+ Movable = 0x00040000,
+#ifdef QT3_SUPPORT
+ Moveable = Movable,
+#endif
+ SelfVoicing = 0x00080000,
+ Focusable = 0x00100000,
+ Selectable = 0x00200000,
+ Linked = 0x00400000,
+ Traversed = 0x00800000,
+ MultiSelectable = 0x01000000,
+ ExtSelectable = 0x02000000,
+ //AlertLow = 0x04000000,
+ //AlertMedium = 0x08000000,
+ //AlertHigh = 0x10000000, /* reused for HasInvokeExtension */
+ Protected = 0x20000000,
+ HasPopup = 0x40000000,
+ Modal = 0x80000000,
+
+ // #### Qt5 ManagesDescendants
+ // #### Qt5 remove HasInvokeExtension
+ HasInvokeExtension = 0x10000000 // internal
+ };
+ Q_DECLARE_FLAGS(State, StateFlag)
+
+ enum Role {
+ NoRole = 0x00000000,
+ TitleBar = 0x00000001,
+ MenuBar = 0x00000002,
+ ScrollBar = 0x00000003,
+ Grip = 0x00000004,
+ Sound = 0x00000005,
+ Cursor = 0x00000006,
+ Caret = 0x00000007,
+ AlertMessage = 0x00000008,
+ Window = 0x00000009,
+ Client = 0x0000000A,
+ PopupMenu = 0x0000000B,
+ MenuItem = 0x0000000C,
+ ToolTip = 0x0000000D,
+ Application = 0x0000000E,
+ Document = 0x0000000F,
+ Pane = 0x00000010,
+ Chart = 0x00000011,
+ Dialog = 0x00000012,
+ Border = 0x00000013,
+ Grouping = 0x00000014,
+ Separator = 0x00000015,
+ ToolBar = 0x00000016,
+ StatusBar = 0x00000017,
+ Table = 0x00000018,
+ ColumnHeader = 0x00000019,
+ RowHeader = 0x0000001A,
+ Column = 0x0000001B,
+ Row = 0x0000001C,
+ Cell = 0x0000001D,
+ Link = 0x0000001E,
+ HelpBalloon = 0x0000001F,
+ Assistant = 0x00000020,
+ List = 0x00000021,
+ ListItem = 0x00000022,
+ Tree = 0x00000023,
+ TreeItem = 0x00000024,
+ PageTab = 0x00000025,
+ PropertyPage = 0x00000026,
+ Indicator = 0x00000027,
+ Graphic = 0x00000028,
+ StaticText = 0x00000029,
+ EditableText = 0x0000002A, // Editable, selectable, etc.
+ PushButton = 0x0000002B,
+ CheckBox = 0x0000002C,
+ RadioButton = 0x0000002D,
+ ComboBox = 0x0000002E,
+ // DropList = 0x0000002F,
+ ProgressBar = 0x00000030,
+ Dial = 0x00000031,
+ HotkeyField = 0x00000032,
+ Slider = 0x00000033,
+ SpinBox = 0x00000034,
+ Canvas = 0x00000035,
+ Animation = 0x00000036,
+ Equation = 0x00000037,
+ ButtonDropDown = 0x00000038,
+ ButtonMenu = 0x00000039,
+ ButtonDropGrid = 0x0000003A,
+ Whitespace = 0x0000003B,
+ PageTabList = 0x0000003C,
+ Clock = 0x0000003D,
+ Splitter = 0x0000003E,
+ // Additional Qt roles where enum value does not map directly to MSAA:
+ LayeredPane = 0x0000003F,
+ UserRole = 0x0000ffff
+ };
+
+ enum Text {
+ Name = 0,
+ Description,
+ Value,
+ Help,
+ Accelerator,
+ UserText = 0x0000ffff
+ };
+
+ enum RelationFlag {
+ Unrelated = 0x00000000,
+ Self = 0x00000001,
+ Ancestor = 0x00000002,
+ Child = 0x00000004,
+ Descendent = 0x00000008,
+ Sibling = 0x00000010,
+ HierarchyMask = 0x000000ff,
+
+ Up = 0x00000100,
+ Down = 0x00000200,
+ Left = 0x00000400,
+ Right = 0x00000800,
+ Covers = 0x00001000,
+ Covered = 0x00002000,
+ GeometryMask = 0x0000ff00,
+
+ FocusChild = 0x00010000,
+ Label = 0x00020000,
+ Labelled = 0x00040000,
+ Controller = 0x00080000,
+ Controlled = 0x00100000,
+ LogicalMask = 0x00ff0000
+ };
+ Q_DECLARE_FLAGS(Relation, RelationFlag)
+
+ enum Action {
+ DefaultAction = 0,
+ Press = -1,
+ FirstStandardAction = Press,
+ SetFocus = -2,
+ Increase = -3,
+ Decrease = -4,
+ Accept = -5,
+ Cancel = -6,
+ Select = -7,
+ ClearSelection = -8,
+ RemoveSelection = -9,
+ ExtendSelection = -10,
+ AddToSelection = -11,
+ LastStandardAction = AddToSelection
+ };
+
+ enum Method {
+ ListSupportedMethods = 0,
+ SetCursorPosition = 1,
+ GetCursorPosition = 2,
+ ForegroundColor = 3,
+ BackgroundColor = 4
+ };
+
+ typedef QAccessibleInterface*(*InterfaceFactory)(const QString &key, QObject*);
+ typedef void(*UpdateHandler)(QObject*, int who, Event reason);
+ typedef void(*RootObjectHandler)(QObject*);
+
+ static void installFactory(InterfaceFactory);
+ static void removeFactory(InterfaceFactory);
+ static UpdateHandler installUpdateHandler(UpdateHandler);
+ static RootObjectHandler installRootObjectHandler(RootObjectHandler);
+
+ static QAccessibleInterface *queryAccessibleInterface(QObject *);
+ static void updateAccessibility(QObject *, int who, Event reason);
+ static bool isActive();
+ static void setRootObject(QObject*);
+
+ static void initialize();
+ static void cleanup();
+
+private:
+ static UpdateHandler updateHandler;
+ static RootObjectHandler rootObjectHandler;
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QAccessible::State)
+Q_DECLARE_OPERATORS_FOR_FLAGS(QAccessible::Relation)
+QT_END_NAMESPACE
+Q_DECLARE_METATYPE(QSet<QAccessible::Method>)
+QT_BEGIN_NAMESPACE
+
+namespace QAccessible2
+{
+ enum InterfaceType
+ {
+ TextInterface,
+ EditableTextInterface,
+ ValueInterface,
+ TableInterface,
+ ActionInterface,
+ ImageInterface,
+ Table2Interface
+ };
+}
+
+class QAccessible2Interface;
+class QAccessibleTextInterface;
+class QAccessibleEditableTextInterface;
+class QAccessibleValueInterface;
+class QAccessibleTableInterface;
+class QAccessibleActionInterface;
+class QAccessibleImageInterface;
+class QAccessibleTable2Interface;
+
+class Q_WIDGETS_EXPORT QAccessibleInterface : public QAccessible
+{
+public:
+ virtual ~QAccessibleInterface() {}
+ // check for valid pointers
+ virtual bool isValid() const = 0;
+ virtual QObject *object() const = 0;
+
+ // hierarchy
+ virtual int childCount() const = 0;
+ virtual int indexOfChild(const QAccessibleInterface *) const = 0;
+
+ // relations
+ virtual Relation relationTo(int child, const QAccessibleInterface *other,
+ int otherChild) const = 0;
+ virtual int childAt(int x, int y) const = 0;
+
+ // navigation
+ virtual int navigate(RelationFlag relation, int index, QAccessibleInterface **iface) const = 0;
+
+ // properties and state
+ virtual QString text(Text t, int child) const = 0;
+ virtual void setText(Text t, int child, const QString &text) = 0;
+ virtual QRect rect(int child) const = 0;
+ virtual Role role(int child) const = 0;
+ virtual State state(int child) const = 0;
+
+ // action
+ virtual int userActionCount(int child) const = 0;
+ virtual QString actionText(int action, Text t, int child) const = 0;
+ virtual bool doAction(int action, int child, const QVariantList &params = QVariantList()) = 0;
+
+ QVariant invokeMethod(Method method, int child = 0,
+ const QVariantList &params = QVariantList());
+
+ inline QSet<Method> supportedMethods()
+ { return qvariant_cast<QSet<Method> >(invokeMethod(ListSupportedMethods)); }
+
+ inline QColor foregroundColor()
+ { return qvariant_cast<QColor>(invokeMethod(ForegroundColor)); }
+
+ inline QColor backgroundColor()
+ { return qvariant_cast<QColor>(invokeMethod(BackgroundColor)); }
+
+ inline QAccessibleTextInterface *textInterface()
+ { return reinterpret_cast<QAccessibleTextInterface *>(cast_helper(QAccessible2::TextInterface)); }
+
+ inline QAccessibleEditableTextInterface *editableTextInterface()
+ { return reinterpret_cast<QAccessibleEditableTextInterface *>(cast_helper(QAccessible2::EditableTextInterface)); }
+
+ inline QAccessibleValueInterface *valueInterface()
+ { return reinterpret_cast<QAccessibleValueInterface *>(cast_helper(QAccessible2::ValueInterface)); }
+
+ inline QAccessibleTableInterface *tableInterface()
+ { return reinterpret_cast<QAccessibleTableInterface *>(cast_helper(QAccessible2::TableInterface)); }
+
+ inline QAccessibleActionInterface *actionInterface()
+ { return reinterpret_cast<QAccessibleActionInterface *>(cast_helper(QAccessible2::ActionInterface)); }
+
+ inline QAccessibleImageInterface *imageInterface()
+ { return reinterpret_cast<QAccessibleImageInterface *>(cast_helper(QAccessible2::ImageInterface)); }
+
+ inline QAccessibleTable2Interface *table2Interface()
+ { return reinterpret_cast<QAccessibleTable2Interface *>(cast_helper(QAccessible2::Table2Interface)); }
+
+private:
+ QAccessible2Interface *cast_helper(QAccessible2::InterfaceType);
+};
+
+class Q_WIDGETS_EXPORT QAccessibleInterfaceEx: public QAccessibleInterface
+{
+public:
+ virtual QVariant invokeMethodEx(Method method, int child, const QVariantList &params) = 0;
+ virtual QVariant virtual_hook(const QVariant &data);
+ virtual QAccessible2Interface *interface_cast(QAccessible2::InterfaceType)
+ { return 0; }
+};
+
+
+class Q_WIDGETS_EXPORT QAccessibleEvent : public QEvent
+{
+public:
+ inline QAccessibleEvent(Type type, int child);
+ inline int child() const { return c; }
+ inline QString value() const { return val; }
+ inline void setValue(const QString &aText) { val = aText; }
+
+private:
+ int c;
+ QString val;
+};
+
+inline QAccessibleEvent::QAccessibleEvent(Type atype, int achild)
+ : QEvent(atype), c(achild) {}
+
+#define QAccessibleInterface_iid "com.trolltech.Qt.QAccessibleInterface"
+Q_DECLARE_INTERFACE(QAccessibleInterface, QAccessibleInterface_iid)
+
+#endif // QT_NO_ACCESSIBILITY
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QACCESSIBLE_H
diff --git a/src/widgets/accessible/qaccessible2.cpp b/src/widgets/accessible/qaccessible2.cpp
new file mode 100644
index 0000000000..896c2c8915
--- /dev/null
+++ b/src/widgets/accessible/qaccessible2.cpp
@@ -0,0 +1,317 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qaccessible2.h"
+#include "qapplication.h"
+#include "qclipboard.h"
+#include "qtextboundaryfinder.h"
+
+#ifndef QT_NO_ACCESSIBILITY
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \namespace QAccessible2
+ \ingroup accessibility
+ \internal
+ \preliminary
+
+ \brief The QAccessible2 namespace defines constants relating to
+ IAccessible2-based interfaces
+
+ \link http://www.linux-foundation.org/en/Accessibility/IAccessible2 IAccessible2 Specification \endlink
+*/
+
+/*!
+ \class QAccessibleTextInterface
+
+ \ingroup accessibility
+ \internal
+ \preliminary
+
+ \brief The QAccessibleTextInterface class implements support for
+ the IAccessibleText interface.
+
+ \link http://www.linux-foundation.org/en/Accessibility/IAccessible2 IAccessible2 Specification \endlink
+*/
+
+/*!
+ \class QAccessibleEditableTextInterface
+ \ingroup accessibility
+ \internal
+ \preliminary
+
+ \brief The QAccessibleEditableTextInterface class implements support for
+ the IAccessibleEditableText interface.
+
+ \link http://www.linux-foundation.org/en/Accessibility/IAccessible2 IAccessible2 Specification \endlink
+*/
+
+/*!
+ \class QAccessibleSimpleEditableTextInterface
+ \ingroup accessibility
+ \internal
+ \preliminary
+
+ \brief The QAccessibleSimpleEditableTextInterface class is a convenience class for
+ text-based widgets.
+
+ \link http://www.linux-foundation.org/en/Accessibility/IAccessible2 IAccessible2 Specification \endlink
+*/
+
+/*!
+ \class QAccessibleValueInterface
+ \ingroup accessibility
+ \internal
+ \preliminary
+
+ \brief The QAccessibleValueInterface class implements support for
+ the IAccessibleValue interface.
+
+ \link http://www.linux-foundation.org/en/Accessibility/IAccessible2 IAccessible2 Specification \endlink
+*/
+
+/*!
+ \class QAccessibleActionInterface
+ \ingroup accessibility
+ \internal
+ \preliminary
+
+ \brief The QAccessibleActionInterface class implements support for
+ the IAccessibleAction interface.
+
+ \link http://www.linux-foundation.org/en/Accessibility/IAccessible2 IAccessible2 Specification \endlink
+*/
+
+/*!
+ \class QAccessibleImageInterface
+ \ingroup accessibility
+ \internal
+ \preliminary
+
+ \brief The QAccessibleImageInterface class implements support for
+ the IAccessibleImage interface.
+
+ \link http://www.linux-foundation.org/en/Accessibility/IAccessible2 IAccessible2 Specification \endlink
+*/
+
+
+/*!
+ \internal
+*/
+QString Q_WIDGETS_EXPORT qTextBeforeOffsetFromString(int offset, QAccessible2::BoundaryType boundaryType,
+ int *startOffset, int *endOffset, const QString& text)
+{
+ QTextBoundaryFinder::BoundaryType type;
+ switch (boundaryType) {
+ case QAccessible2::CharBoundary:
+ type = QTextBoundaryFinder::Grapheme;
+ break;
+ case QAccessible2::WordBoundary:
+ type = QTextBoundaryFinder::Word;
+ break;
+ case QAccessible2::SentenceBoundary:
+ type = QTextBoundaryFinder::Sentence;
+ break;
+ default:
+ // in any other case return the whole line
+ *startOffset = 0;
+ *endOffset = text.length();
+ return text;
+ }
+
+ QTextBoundaryFinder boundary(type, text);
+ boundary.setPosition(offset);
+
+ if (!boundary.isAtBoundary()) {
+ boundary.toPreviousBoundary();
+ }
+ boundary.toPreviousBoundary();
+ *startOffset = boundary.position();
+ boundary.toNextBoundary();
+ *endOffset = boundary.position();
+
+ return text.mid(*startOffset, *endOffset - *startOffset);
+}
+
+/*!
+ \internal
+*/
+QString Q_WIDGETS_EXPORT qTextAfterOffsetFromString(int offset, QAccessible2::BoundaryType boundaryType,
+ int *startOffset, int *endOffset, const QString& text)
+{
+ QTextBoundaryFinder::BoundaryType type;
+ switch (boundaryType) {
+ case QAccessible2::CharBoundary:
+ type = QTextBoundaryFinder::Grapheme;
+ break;
+ case QAccessible2::WordBoundary:
+ type = QTextBoundaryFinder::Word;
+ break;
+ case QAccessible2::SentenceBoundary:
+ type = QTextBoundaryFinder::Sentence;
+ break;
+ default:
+ // in any other case return the whole line
+ *startOffset = 0;
+ *endOffset = text.length();
+ return text;
+ }
+
+ QTextBoundaryFinder boundary(type, text);
+ boundary.setPosition(offset);
+
+ boundary.toNextBoundary();
+ *startOffset = boundary.position();
+ boundary.toNextBoundary();
+ *endOffset = boundary.position();
+
+ return text.mid(*startOffset, *endOffset - *startOffset);
+}
+
+/*!
+ \internal
+*/
+QString Q_WIDGETS_EXPORT qTextAtOffsetFromString(int offset, QAccessible2::BoundaryType boundaryType,
+ int *startOffset, int *endOffset, const QString& text)
+{
+ QTextBoundaryFinder::BoundaryType type;
+ switch (boundaryType) {
+ case QAccessible2::CharBoundary:
+ type = QTextBoundaryFinder::Grapheme;
+ break;
+ case QAccessible2::WordBoundary:
+ type = QTextBoundaryFinder::Word;
+ break;
+ case QAccessible2::SentenceBoundary:
+ type = QTextBoundaryFinder::Sentence;
+ break;
+ default:
+ // in any other case return the whole line
+ *startOffset = 0;
+ *endOffset = text.length();
+ return text;
+ }
+
+ QTextBoundaryFinder boundary(type, text);
+ boundary.setPosition(offset);
+
+ if (!boundary.isAtBoundary()) {
+ boundary.toPreviousBoundary();
+ }
+ *startOffset = boundary.position();
+ boundary.toNextBoundary();
+ *endOffset = boundary.position();
+
+ return text.mid(*startOffset, *endOffset - *startOffset);
+}
+
+QAccessibleSimpleEditableTextInterface::QAccessibleSimpleEditableTextInterface(
+ QAccessibleInterface *accessibleInterface)
+ : iface(accessibleInterface)
+{
+ Q_ASSERT(iface);
+}
+
+#ifndef QT_NO_CLIPBOARD
+static QString textForRange(QAccessibleInterface *iface, int startOffset, int endOffset)
+{
+ return iface->text(QAccessible::Value, 0).mid(startOffset, endOffset - startOffset);
+}
+#endif
+
+void QAccessibleSimpleEditableTextInterface::copyText(int startOffset, int endOffset)
+{
+#ifdef QT_NO_CLIPBOARD
+ Q_UNUSED(startOffset);
+ Q_UNUSED(endOffset);
+#else
+ QApplication::clipboard()->setText(textForRange(iface, startOffset, endOffset));
+#endif
+}
+
+void QAccessibleSimpleEditableTextInterface::deleteText(int startOffset, int endOffset)
+{
+ QString txt = iface->text(QAccessible::Value, 0);
+ txt.remove(startOffset, endOffset - startOffset);
+ iface->setText(QAccessible::Value, 0, txt);
+}
+
+void QAccessibleSimpleEditableTextInterface::insertText(int offset, const QString &text)
+{
+ QString txt = iface->text(QAccessible::Value, 0);
+ txt.insert(offset, text);
+ iface->setText(QAccessible::Value, 0, txt);
+}
+
+void QAccessibleSimpleEditableTextInterface::cutText(int startOffset, int endOffset)
+{
+#ifdef QT_NO_CLIPBOARD
+ Q_UNUSED(startOffset);
+ Q_UNUSED(endOffset);
+#else
+ QString sub = textForRange(iface, startOffset, endOffset);
+ deleteText(startOffset, endOffset);
+ QApplication::clipboard()->setText(sub);
+#endif
+}
+
+void QAccessibleSimpleEditableTextInterface::pasteText(int offset)
+{
+#ifdef QT_NO_CLIPBOARD
+ Q_UNUSED(offset);
+#else
+ QString txt = iface->text(QAccessible::Value, 0);
+ txt.insert(offset, QApplication::clipboard()->text());
+ iface->setText(QAccessible::Value, 0, txt);
+#endif
+}
+
+void QAccessibleSimpleEditableTextInterface::replaceText(int startOffset, int endOffset, const QString &text)
+{
+ QString txt = iface->text(QAccessible::Value, 0);
+ txt.replace(startOffset, endOffset - startOffset, text);
+ iface->setText(QAccessible::Value, 0, txt);
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_ACCESSIBILITY
diff --git a/src/widgets/accessible/qaccessible2.h b/src/widgets/accessible/qaccessible2.h
new file mode 100644
index 0000000000..69c19499c2
--- /dev/null
+++ b/src/widgets/accessible/qaccessible2.h
@@ -0,0 +1,358 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QACCESSIBLE2_H
+#define QACCESSIBLE2_H
+
+#include <QtWidgets/qaccessible.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_ACCESSIBILITY
+
+class QModelIndex;
+
+namespace QAccessible2
+{
+ enum CoordinateType
+ {
+ RelativeToScreen = 0,
+ RelativeToParent = 1
+ };
+
+ enum BoundaryType {
+ CharBoundary,
+ WordBoundary,
+ SentenceBoundary,
+ ParagraphBoundary,
+ LineBoundary,
+ NoBoundary
+ };
+
+ enum TableModelChangeType {
+ TableModelChangeInsert,
+ TableModelChangeDelete,
+ TableModelChangeUpdate
+ };
+
+ struct TableModelChange {
+ int firstColumn;
+ int firstRow;
+ int lastColumn;
+ int lastRow;
+ TableModelChangeType type;
+
+ TableModelChange()
+ : firstColumn(0), firstRow(0), lastColumn(0), lastRow(0), type(TableModelChangeUpdate)
+ {}
+ };
+}
+
+class Q_WIDGETS_EXPORT QAccessible2Interface
+{
+public:
+ virtual ~QAccessible2Interface() {}
+};
+
+// catch-all functions. If an accessible class doesn't implement interface T, return 0
+inline QAccessible2Interface *qAccessibleValueCastHelper() { return 0; }
+inline QAccessible2Interface *qAccessibleTextCastHelper() { return 0; }
+inline QAccessible2Interface *qAccessibleEditableTextCastHelper() { return 0; }
+inline QAccessible2Interface *qAccessibleTableCastHelper() { return 0; }
+inline QAccessible2Interface *qAccessibleActionCastHelper() { return 0; }
+inline QAccessible2Interface *qAccessibleImageCastHelper() { return 0; }
+inline QAccessible2Interface *qAccessibleTable2CastHelper() { return 0; }
+
+#define Q_ACCESSIBLE_OBJECT \
+ public: \
+ QAccessible2Interface *interface_cast(QAccessible2::InterfaceType t) \
+ { \
+ switch (t) { \
+ case QAccessible2::TextInterface: \
+ return qAccessibleTextCastHelper(); \
+ case QAccessible2::EditableTextInterface: \
+ return qAccessibleEditableTextCastHelper(); \
+ case QAccessible2::ValueInterface: \
+ return qAccessibleValueCastHelper(); \
+ case QAccessible2::TableInterface: \
+ return qAccessibleTableCastHelper(); \
+ case QAccessible2::ActionInterface: \
+ return qAccessibleActionCastHelper(); \
+ case QAccessible2::ImageInterface: \
+ return qAccessibleImageCastHelper(); \
+ case QAccessible2::Table2Interface: \
+ return qAccessibleTable2CastHelper(); \
+ } \
+ return 0; \
+ } \
+ private:
+
+class Q_WIDGETS_EXPORT QAccessibleTextInterface: public QAccessible2Interface
+{
+public:
+ inline QAccessible2Interface *qAccessibleTextCastHelper() { return this; }
+
+ virtual ~QAccessibleTextInterface() {}
+
+ virtual void addSelection(int startOffset, int endOffset) = 0;
+ virtual QString attributes(int offset, int *startOffset, int *endOffset) = 0;
+ virtual int cursorPosition() = 0;
+ virtual QRect characterRect(int offset, QAccessible2::CoordinateType coordType) = 0;
+ virtual int selectionCount() = 0;
+ virtual int offsetAtPoint(const QPoint &point, QAccessible2::CoordinateType coordType) = 0;
+ virtual void selection(int selectionIndex, int *startOffset, int *endOffset) = 0;
+ virtual QString text(int startOffset, int endOffset) = 0;
+ virtual QString textBeforeOffset (int offset, QAccessible2::BoundaryType boundaryType,
+ int *startOffset, int *endOffset) = 0;
+ virtual QString textAfterOffset(int offset, QAccessible2::BoundaryType boundaryType,
+ int *startOffset, int *endOffset) = 0;
+ virtual QString textAtOffset(int offset, QAccessible2::BoundaryType boundaryType,
+ int *startOffset, int *endOffset) = 0;
+ virtual void removeSelection(int selectionIndex) = 0;
+ virtual void setCursorPosition(int position) = 0;
+ virtual void setSelection(int selectionIndex, int startOffset, int endOffset) = 0;
+ virtual int characterCount() = 0;
+ virtual void scrollToSubstring(int startIndex, int endIndex) = 0;
+};
+
+class Q_WIDGETS_EXPORT QAccessibleEditableTextInterface: public QAccessible2Interface
+{
+public:
+ inline QAccessible2Interface *qAccessibleEditableTextCastHelper() { return this; }
+
+ virtual ~QAccessibleEditableTextInterface() {}
+
+ virtual void copyText(int startOffset, int endOffset) = 0;
+ virtual void deleteText(int startOffset, int endOffset) = 0;
+ virtual void insertText(int offset, const QString &text) = 0;
+ virtual void cutText(int startOffset, int endOffset) = 0;
+ virtual void pasteText(int offset) = 0;
+ virtual void replaceText(int startOffset, int endOffset, const QString &text) = 0;
+ virtual void setAttributes(int startOffset, int endOffset, const QString &attributes) = 0;
+};
+
+class Q_WIDGETS_EXPORT QAccessibleSimpleEditableTextInterface: public QAccessibleEditableTextInterface
+{
+public:
+ QAccessibleSimpleEditableTextInterface(QAccessibleInterface *accessibleInterface);
+
+ void copyText(int startOffset, int endOffset);
+ void deleteText(int startOffset, int endOffset);
+ void insertText(int offset, const QString &text);
+ void cutText(int startOffset, int endOffset);
+ void pasteText(int offset);
+ void replaceText(int startOffset, int endOffset, const QString &text);
+ inline void setAttributes(int, int, const QString &) {}
+
+private:
+ QAccessibleInterface *iface;
+};
+
+class Q_WIDGETS_EXPORT QAccessibleValueInterface: public QAccessible2Interface
+{
+public:
+ inline QAccessible2Interface *qAccessibleValueCastHelper() { return this; }
+
+ virtual ~QAccessibleValueInterface() {}
+
+ virtual QVariant currentValue() = 0;
+ virtual void setCurrentValue(const QVariant &value) = 0;
+ virtual QVariant maximumValue() = 0;
+ virtual QVariant minimumValue() = 0;
+};
+
+class Q_WIDGETS_EXPORT QAccessibleTableInterface: public QAccessible2Interface
+{
+public:
+ inline QAccessible2Interface *qAccessibleTableCastHelper() { return this; }
+
+ virtual QAccessibleInterface *accessibleAt(int row, int column) = 0;
+ virtual QAccessibleInterface *caption() = 0;
+ virtual int childIndex(int rowIndex, int columnIndex) = 0;
+ virtual QString columnDescription(int column) = 0;
+ virtual int columnSpan(int row, int column) = 0;
+ virtual QAccessibleInterface *columnHeader() = 0;
+ virtual int columnIndex(int childIndex) = 0;
+ virtual int columnCount() = 0;
+ virtual int rowCount() = 0;
+ virtual int selectedColumnCount() = 0;
+ virtual int selectedRowCount() = 0;
+ virtual QString rowDescription(int row) = 0;
+ virtual int rowSpan(int row, int column) = 0;
+ virtual QAccessibleInterface *rowHeader() = 0;
+ virtual int rowIndex(int childIndex) = 0;
+ virtual int selectedRows(int maxRows, QList<int> *rows) = 0;
+ virtual int selectedColumns(int maxColumns, QList<int> *columns) = 0;
+ virtual QAccessibleInterface *summary() = 0;
+ virtual bool isColumnSelected(int column) = 0;
+ virtual bool isRowSelected(int row) = 0;
+ virtual bool isSelected(int row, int column) = 0;
+ virtual void selectRow(int row) = 0;
+ virtual void selectColumn(int column) = 0;
+ virtual void unselectRow(int row) = 0;
+ virtual void unselectColumn(int column) = 0;
+ virtual void cellAtIndex(int index, int *row, int *column, int *rowSpan,
+ int *columnSpan, bool *isSelected) = 0;
+};
+
+class Q_WIDGETS_EXPORT QAccessibleTable2CellInterface: public QAccessibleInterface
+{
+public:
+ // Returns the number of columns occupied by this cell accessible.
+ virtual int columnExtent() const = 0;
+
+ // Returns the column headers as an array of cell accessibles.
+ virtual QList<QAccessibleInterface*> columnHeaderCells() const = 0;
+
+ // Translates this cell accessible into the corresponding column index.
+ virtual int columnIndex() const = 0;
+ // Returns the number of rows occupied by this cell accessible.
+ virtual int rowExtent() const = 0;
+ // Returns the row headers as an array of cell accessibles.
+ virtual QList<QAccessibleInterface*> rowHeaderCells() const = 0;
+ // Translates this cell accessible into the corresponding row index.
+ virtual int rowIndex() const = 0;
+ // Returns a boolean value indicating whether this cell is selected.
+ virtual bool isSelected() const = 0;
+
+ // Gets the row and column indexes and extents of this cell accessible and whether or not it is selected.
+ virtual void rowColumnExtents(int *row, int *column, int *rowExtents, int *columnExtents, bool *selected) const = 0;
+ // Returns a reference to the accessbile of the containing table.
+ virtual QAccessibleTable2Interface* table() const = 0;
+
+ // #### Qt5 this should not be here but part of the state
+ virtual bool isExpandable() const = 0;
+};
+
+class Q_WIDGETS_EXPORT QAccessibleTable2Interface: public QAccessible2Interface
+{
+public:
+ inline QAccessible2Interface *qAccessibleTable2CastHelper() { return this; }
+
+ // Returns the cell at the specified row and column in the table.
+ virtual QAccessibleTable2CellInterface *cellAt (int row, int column) const = 0;
+ // Returns the caption for the table.
+ virtual QAccessibleInterface *caption() const = 0;
+ // Returns the description text of the specified column in the table.
+ virtual QString columnDescription(int column) const = 0;
+ // Returns the total number of columns in table.
+ virtual int columnCount() const = 0;
+ // Returns the total number of rows in table.
+ virtual int rowCount() const = 0;
+ // Returns the total number of selected cells.
+ virtual int selectedCellCount() const = 0;
+ // Returns the total number of selected columns.
+ virtual int selectedColumnCount() const = 0;
+ // Returns the total number of selected rows.
+ virtual int selectedRowCount() const = 0;
+ // Returns the description text of the specified row in the table.
+ virtual QString rowDescription(int row) const = 0;
+ // Returns a list of accessibles currently selected.
+ virtual QList<QAccessibleTable2CellInterface*> selectedCells() const = 0;
+ // Returns a list of column indexes currently selected (0 based).
+ virtual QList<int> selectedColumns() const = 0;
+ // Returns a list of row indexes currently selected (0 based).
+ virtual QList<int> selectedRows() const = 0;
+ // Returns the summary description of the table.
+ virtual QAccessibleInterface *summary() const = 0;
+ // Returns a boolean value indicating whether the specified column is completely selected.
+ virtual bool isColumnSelected(int column) const = 0;
+ // Returns a boolean value indicating whether the specified row is completely selected.
+ virtual bool isRowSelected(int row) const = 0;
+ // Selects a row and unselects all previously selected rows.
+ virtual bool selectRow(int row) = 0;
+ // Selects a column and unselects all previously selected columns.
+ virtual bool selectColumn(int column) = 0;
+ // Unselects one row, leaving other selected rows selected (if any).
+ virtual bool unselectRow(int row) = 0;
+ // Unselects one column, leaving other selected columns selected (if any).
+ virtual bool unselectColumn(int column) = 0;
+ // Returns the type and extents describing how a table changed.
+ virtual QAccessible2::TableModelChange modelChange() const = 0;
+
+protected:
+ // These functions are called when the model changes.
+ virtual void modelReset() = 0;
+ virtual void rowsInserted(const QModelIndex &parent, int first, int last) = 0;
+ virtual void rowsRemoved(const QModelIndex &parent, int first, int last) = 0;
+ virtual void columnsInserted(const QModelIndex &parent, int first, int last) = 0;
+ virtual void columnsRemoved(const QModelIndex &parent, int first, int last) = 0;
+ virtual void rowsMoved( const QModelIndex &parent, int start, int end, const QModelIndex &destination, int row) = 0;
+ virtual void columnsMoved( const QModelIndex &parent, int start, int end, const QModelIndex &destination, int column) = 0;
+
+friend class QAbstractItemView;
+friend class QAbstractItemViewPrivate;
+};
+
+class Q_WIDGETS_EXPORT QAccessibleActionInterface : public QAccessible2Interface
+{
+public:
+ inline QAccessible2Interface *qAccessibleActionCastHelper() { return this; }
+
+ virtual int actionCount() = 0;
+ virtual void doAction(int actionIndex) = 0;
+ virtual QString description(int actionIndex) = 0;
+ virtual QString name(int actionIndex) = 0;
+ virtual QString localizedName(int actionIndex) = 0;
+ virtual QStringList keyBindings(int actionIndex) = 0;
+};
+
+class Q_WIDGETS_EXPORT QAccessibleImageInterface : public QAccessible2Interface
+{
+public:
+ inline QAccessible2Interface *qAccessibleImageCastHelper() { return this; }
+
+ virtual QString imageDescription() = 0;
+ virtual QSize imageSize() = 0;
+ virtual QRect imagePosition(QAccessible2::CoordinateType coordType) = 0;
+};
+
+#endif // QT_NO_ACCESSIBILITY
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/gui/accessible/qaccessible_mac.mm b/src/widgets/accessible/qaccessible_mac.mm
index a250730493..a250730493 100644
--- a/src/gui/accessible/qaccessible_mac.mm
+++ b/src/widgets/accessible/qaccessible_mac.mm
diff --git a/src/gui/accessible/qaccessible_mac_carbon.cpp b/src/widgets/accessible/qaccessible_mac_carbon.cpp
index 32a242f274..32a242f274 100644
--- a/src/gui/accessible/qaccessible_mac_carbon.cpp
+++ b/src/widgets/accessible/qaccessible_mac_carbon.cpp
diff --git a/src/gui/accessible/qaccessible_mac_cocoa.mm b/src/widgets/accessible/qaccessible_mac_cocoa.mm
index 461b61aacf..461b61aacf 100644
--- a/src/gui/accessible/qaccessible_mac_cocoa.mm
+++ b/src/widgets/accessible/qaccessible_mac_cocoa.mm
diff --git a/src/gui/accessible/qaccessible_mac_p.h b/src/widgets/accessible/qaccessible_mac_p.h
index 9b7d25a334..9b7d25a334 100644
--- a/src/gui/accessible/qaccessible_mac_p.h
+++ b/src/widgets/accessible/qaccessible_mac_p.h
diff --git a/src/gui/accessible/qaccessible_unix.cpp b/src/widgets/accessible/qaccessible_unix.cpp
index 1c1eb2ad05..1c1eb2ad05 100644
--- a/src/gui/accessible/qaccessible_unix.cpp
+++ b/src/widgets/accessible/qaccessible_unix.cpp
diff --git a/src/widgets/accessible/qaccessible_win.cpp b/src/widgets/accessible/qaccessible_win.cpp
new file mode 100644
index 0000000000..f09f4bb631
--- /dev/null
+++ b/src/widgets/accessible/qaccessible_win.cpp
@@ -0,0 +1,1439 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "qaccessible.h"
+#ifndef QT_NO_ACCESSIBILITY
+
+#include "qapplication.h"
+#include <private/qsystemlibrary_p.h>
+#include "qmessagebox.h" // ### dependency
+#include "qt_windows.h"
+#include "qwidget.h"
+#include "qsettings.h"
+#include <QtCore/qmap.h>
+#include <QtCore/qpair.h>
+#include <QtWidgets/qgraphicsitem.h>
+#include <QtWidgets/qgraphicsscene.h>
+#include <QtWidgets/qgraphicsview.h>
+
+#include <winuser.h>
+#if !defined(WINABLEAPI)
+# if defined(Q_WS_WINCE)
+# include <bldver.h>
+# endif
+# include <winable.h>
+#endif
+
+#include <oleacc.h>
+#if !defined(Q_CC_BOR) && !defined (Q_CC_GNU)
+#include <comdef.h>
+#endif
+
+#ifdef Q_WS_WINCE
+#include "qguifunctions_wince.h"
+#endif
+
+QT_BEGIN_NAMESPACE
+
+//#define DEBUG_SHOW_ATCLIENT_COMMANDS
+#ifdef DEBUG_SHOW_ATCLIENT_COMMANDS
+QT_BEGIN_INCLUDE_NAMESPACE
+#include <qdebug.h>
+QT_END_INCLUDE_NAMESPACE
+
+static const char *roleString(QAccessible::Role role)
+{
+ static const char *roles[] = {
+ "NoRole" /* = 0x00000000 */,
+ "TitleBar" /* = 0x00000001 */,
+ "MenuBar" /* = 0x00000002 */,
+ "ScrollBar" /* = 0x00000003 */,
+ "Grip" /* = 0x00000004 */,
+ "Sound" /* = 0x00000005 */,
+ "Cursor" /* = 0x00000006 */,
+ "Caret" /* = 0x00000007 */,
+ "AlertMessage" /* = 0x00000008 */,
+ "Window" /* = 0x00000009 */,
+ "Client" /* = 0x0000000A */,
+ "PopupMenu" /* = 0x0000000B */,
+ "MenuItem" /* = 0x0000000C */,
+ "ToolTip" /* = 0x0000000D */,
+ "Application" /* = 0x0000000E */,
+ "Document" /* = 0x0000000F */,
+ "Pane" /* = 0x00000010 */,
+ "Chart" /* = 0x00000011 */,
+ "Dialog" /* = 0x00000012 */,
+ "Border" /* = 0x00000013 */,
+ "Grouping" /* = 0x00000014 */,
+ "Separator" /* = 0x00000015 */,
+ "ToolBar" /* = 0x00000016 */,
+ "StatusBar" /* = 0x00000017 */,
+ "Table" /* = 0x00000018 */,
+ "ColumnHeader" /* = 0x00000019 */,
+ "RowHeader" /* = 0x0000001A */,
+ "Column" /* = 0x0000001B */,
+ "Row" /* = 0x0000001C */,
+ "Cell" /* = 0x0000001D */,
+ "Link" /* = 0x0000001E */,
+ "HelpBalloon" /* = 0x0000001F */,
+ "Assistant" /* = 0x00000020 */,
+ "List" /* = 0x00000021 */,
+ "ListItem" /* = 0x00000022 */,
+ "Tree" /* = 0x00000023 */,
+ "TreeItem" /* = 0x00000024 */,
+ "PageTab" /* = 0x00000025 */,
+ "PropertyPage" /* = 0x00000026 */,
+ "Indicator" /* = 0x00000027 */,
+ "Graphic" /* = 0x00000028 */,
+ "StaticText" /* = 0x00000029 */,
+ "EditableText" /* = 0x0000002A */, // Editable, selectable, etc.
+ "PushButton" /* = 0x0000002B */,
+ "CheckBox" /* = 0x0000002C */,
+ "RadioButton" /* = 0x0000002D */,
+ "ComboBox" /* = 0x0000002E */,
+ "DropList" /* = 0x0000002F */, // commented out
+ "ProgressBar" /* = 0x00000030 */,
+ "Dial" /* = 0x00000031 */,
+ "HotkeyField" /* = 0x00000032 */,
+ "Slider" /* = 0x00000033 */,
+ "SpinBox" /* = 0x00000034 */,
+ "Canvas" /* = 0x00000035 */,
+ "Animation" /* = 0x00000036 */,
+ "Equation" /* = 0x00000037 */,
+ "ButtonDropDown" /* = 0x00000038 */,
+ "ButtonMenu" /* = 0x00000039 */,
+ "ButtonDropGrid" /* = 0x0000003A */,
+ "Whitespace" /* = 0x0000003B */,
+ "PageTabList" /* = 0x0000003C */,
+ "Clock" /* = 0x0000003D */,
+ "Splitter" /* = 0x0000003E */,
+ "LayeredPane" /* = 0x0000003F */,
+ "UserRole" /* = 0x0000ffff*/
+ };
+
+ if (role >=0x40)
+ role = QAccessible::UserRole;
+ return roles[int(role)];
+}
+
+static const char *eventString(QAccessible::Event ev)
+{
+ static const char *events[] = {
+ "null", // 0
+ "SoundPlayed" /*= 0x0001*/,
+ "Alert" /*= 0x0002*/,
+ "ForegroundChanged" /*= 0x0003*/,
+ "MenuStart" /*= 0x0004*/,
+ "MenuEnd" /*= 0x0005*/,
+ "PopupMenuStart" /*= 0x0006*/,
+ "PopupMenuEnd" /*= 0x0007*/,
+ "ContextHelpStart" /*= 0x000C*/, // 8
+ "ContextHelpEnd" /*= 0x000D*/,
+ "DragDropStart" /*= 0x000E*/,
+ "DragDropEnd" /*= 0x000F*/,
+ "DialogStart" /*= 0x0010*/,
+ "DialogEnd" /*= 0x0011*/,
+ "ScrollingStart" /*= 0x0012*/,
+ "ScrollingEnd" /*= 0x0013*/,
+ "MenuCommand" /*= 0x0018*/, // 16
+
+ // Values from IAccessible2
+ "ActionChanged" /*= 0x0101*/, // 17
+ "ActiveDescendantChanged",
+ "AttributeChanged",
+ "DocumentContentChanged",
+ "DocumentLoadComplete",
+ "DocumentLoadStopped",
+ "DocumentReload",
+ "HyperlinkEndIndexChanged",
+ "HyperlinkNumberOfAnchorsChanged",
+ "HyperlinkSelectedLinkChanged",
+ "HypertextLinkActivated",
+ "HypertextLinkSelected",
+ "HyperlinkStartIndexChanged",
+ "HypertextChanged",
+ "HypertextNLinksChanged",
+ "ObjectAttributeChanged",
+ "PageChanged",
+ "SectionChanged",
+ "TableCaptionChanged",
+ "TableColumnDescriptionChanged",
+ "TableColumnHeaderChanged",
+ "TableModelChanged",
+ "TableRowDescriptionChanged",
+ "TableRowHeaderChanged",
+ "TableSummaryChanged",
+ "TextAttributeChanged",
+ "TextCaretMoved",
+ // TextChanged, deprecated, use TextUpdated
+ //TextColumnChanged = TextCaretMoved + 2,
+ "TextInserted",
+ "TextRemoved",
+ "TextUpdated",
+ "TextSelectionChanged",
+ "VisibleDataChanged", /*= 0x0101+32*/
+ "ObjectCreated" /*= 0x8000*/, // 49
+ "ObjectDestroyed" /*= 0x8001*/,
+ "ObjectShow" /*= 0x8002*/,
+ "ObjectHide" /*= 0x8003*/,
+ "ObjectReorder" /*= 0x8004*/,
+ "Focus" /*= 0x8005*/,
+ "Selection" /*= 0x8006*/,
+ "SelectionAdd" /*= 0x8007*/,
+ "SelectionRemove" /*= 0x8008*/,
+ "SelectionWithin" /*= 0x8009*/,
+ "StateChanged" /*= 0x800A*/,
+ "LocationChanged" /*= 0x800B*/,
+ "NameChanged" /*= 0x800C*/,
+ "DescriptionChanged" /*= 0x800D*/,
+ "ValueChanged" /*= 0x800E*/,
+ "ParentChanged" /*= 0x800F*/,
+ "HelpChanged" /*= 0x80A0*/,
+ "DefaultActionChanged" /*= 0x80B0*/,
+ "AcceleratorChanged" /*= 0x80C0*/
+ };
+ int e = int(ev);
+ if (e <= 0x80c0) {
+ const int last = sizeof(events)/sizeof(char*) - 1;
+
+ if (e <= 0x07)
+ return events[e];
+ else if (e <= 0x13)
+ return events[e - 0x0c + 8];
+ else if (e == 0x18)
+ return events[16];
+ else if (e <= 0x0101 + 32)
+ return events[e - 0x101 + 17];
+ else if (e <= 0x800f)
+ return events[e - 0x8000 + 49];
+ else if (e == 0x80a0)
+ return events[last - 2];
+ else if (e == 0x80b0)
+ return events[last - 1];
+ else if (e == 0x80c0)
+ return events[last];
+ }
+ return "unknown";
+};
+
+void showDebug(const char* funcName, const QAccessibleInterface *iface)
+{
+ qDebug() << "Role:" << roleString(iface->role(0))
+ << "Name:" << iface->text(QAccessible::Name, 0)
+ << "State:" << QString::number(int(iface->state(0)), 16)
+ << QLatin1String(funcName);
+}
+#else
+# define showDebug(f, iface)
+#endif
+
+// This stuff is used for widgets/items with no window handle:
+typedef QMap<int, QPair<QObject*,int> > NotifyMap;
+Q_GLOBAL_STATIC(NotifyMap, qAccessibleRecentSentEvents)
+static int eventNum = 0;
+
+
+void QAccessible::initialize()
+{
+
+}
+void QAccessible::cleanup()
+{
+
+}
+
+void QAccessible::updateAccessibility(QObject *o, int who, Event reason)
+{
+ Q_ASSERT(o);
+
+ if (updateHandler) {
+ updateHandler(o, who, reason);
+ return;
+ }
+
+ QString soundName;
+ switch (reason) {
+ case PopupMenuStart:
+ soundName = QLatin1String("MenuPopup");
+ break;
+
+ case MenuCommand:
+ soundName = QLatin1String("MenuCommand");
+ break;
+
+ case Alert:
+ {
+#ifndef QT_NO_MESSAGEBOX
+ QMessageBox *mb = qobject_cast<QMessageBox*>(o);
+ if (mb) {
+ switch (mb->icon()) {
+ case QMessageBox::Warning:
+ soundName = QLatin1String("SystemExclamation");
+ break;
+ case QMessageBox::Critical:
+ soundName = QLatin1String("SystemHand");
+ break;
+ case QMessageBox::Information:
+ soundName = QLatin1String("SystemAsterisk");
+ break;
+ default:
+ break;
+ }
+ } else
+#endif // QT_NO_MESSAGEBOX
+ {
+ soundName = QLatin1String("SystemAsterisk");
+ }
+
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (soundName.size()) {
+#ifndef QT_NO_SETTINGS
+ QSettings settings(QLatin1String("HKEY_CURRENT_USER\\AppEvents\\Schemes\\Apps\\.Default\\") + soundName,
+ QSettings::NativeFormat);
+ QString file = settings.value(QLatin1String(".Current/.")).toString();
+#else
+ QString file;
+#endif
+ if (!file.isEmpty()) {
+ PlaySound(reinterpret_cast<const wchar_t *>(soundName.utf16()), 0, SND_ALIAS | SND_ASYNC | SND_NODEFAULT | SND_NOWAIT);
+ }
+ }
+
+ if (!isActive())
+ return;
+
+ typedef void (WINAPI *PtrNotifyWinEvent)(DWORD, HWND, LONG, LONG);
+
+#if defined(Q_WS_WINCE) // ### TODO: check for NotifyWinEvent in CE 6.0
+ // There is no user32.lib nor NotifyWinEvent for CE
+ return;
+#else
+ static PtrNotifyWinEvent ptrNotifyWinEvent = 0;
+ static bool resolvedNWE = false;
+ if (!resolvedNWE) {
+ resolvedNWE = true;
+ ptrNotifyWinEvent = (PtrNotifyWinEvent)QSystemLibrary::resolve(QLatin1String("user32"), "NotifyWinEvent");
+ }
+ if (!ptrNotifyWinEvent)
+ return;
+
+ // An event has to be associated with a window,
+ // so find the first parent that is a widget.
+ QWidget *w = 0;
+ QObject *p = o;
+ do {
+ if (p->isWidgetType()) {
+ w = static_cast<QWidget*>(p);
+ if (w->internalWinId())
+ break;
+ }
+ if (QGraphicsObject *gfxObj = qobject_cast<QGraphicsObject*>(p)) {
+ QGraphicsItem *parentItem = gfxObj->parentItem();
+ if (parentItem) {
+ p = parentItem->toGraphicsObject();
+ } else {
+ QGraphicsView *view = 0;
+ if (QGraphicsScene *scene = gfxObj->scene()) {
+ QWidget *fw = QApplication::focusWidget();
+ const QList<QGraphicsView*> views = scene->views();
+ for (int i = 0 ; i < views.count() && view != fw; ++i) {
+ view = views.at(i);
+ }
+ }
+ p = view;
+ }
+ } else {
+ p = p->parent();
+ }
+
+ } while (p);
+
+ //qDebug() << "updateAccessibility(), hwnd:" << w << ", object:" << o << "," << eventString(reason);
+ if (!w) {
+ if (reason != QAccessible::ContextHelpStart &&
+ reason != QAccessible::ContextHelpEnd)
+ w = QApplication::focusWidget();
+ if (!w) {
+ w = QApplication::activeWindow();
+
+ if (!w)
+ return;
+
+// ### Fixme
+// if (!w) {
+// w = qApp->mainWidget();
+// if (!w)
+// return;
+// }
+ }
+ }
+
+ WId wid = w->internalWinId();
+ if (reason != MenuCommand) { // MenuCommand is faked
+ if (w != o) {
+ // See comment "SENDING EVENTS TO OBJECTS WITH NO WINDOW HANDLE"
+ eventNum %= 50; //[0..49]
+ int eventId = - eventNum - 1;
+
+ qAccessibleRecentSentEvents()->insert(eventId, qMakePair(o,who));
+ ptrNotifyWinEvent(reason, wid, OBJID_CLIENT, eventId );
+
+ ++eventNum;
+ } else {
+ ptrNotifyWinEvent(reason, wid, OBJID_CLIENT, who);
+ }
+ }
+#endif // Q_WS_WINCE
+}
+
+/* == SENDING EVENTS TO OBJECTS WITH NO WINDOW HANDLE ==
+
+ If the user requested to send the event to a widget with no window,
+ we need to send an event to an object with no hwnd.
+ The way we do that is to send it to the *first* ancestor widget
+ with a window.
+ Then we'll need a way of identifying the child:
+ We'll just keep a list of the most recent events that we have sent,
+ where each entry in the list is identified by a negative value
+ between [-50,-1]. This negative value we will pass on to
+ NotifyWinEvent() as the child id. When the negative value have
+ reached -50, it will wrap around to -1. This seems to be enough
+
+ Now, when the client receives that event, he will first call
+ AccessibleObjectFromEvent() where dwChildID is the special
+ negative value. AccessibleObjectFromEvent does two steps:
+ 1. It will first sent a WM_GETOBJECT to the server, asking
+ for the IAccessible interface for the HWND.
+ 2. With the IAccessible interface it got hold of it will call
+ acc_getChild where the child id argument is the special
+ negative identifier. In our reimplementation of get_accChild
+ we check for this if the child id is negative. If it is, then
+ we'll look up in our table for the entry that is associated
+ with that value.
+ The entry will then contain a pointer to the QObject /QWidget
+ that we can use to call queryAccessibleInterface() on.
+
+
+ The following figure shows how the interaction between server and
+ client is in the case when the server is sending an event.
+
+SERVER (Qt) | CLIENT |
+--------------------------------------------+---------------------------------------+
+ |
+acc->updateAccessibility(obj, childIndex) |
+ |
+recentEvents()->insert(- 1 - eventNum, |
+ qMakePair(obj, childIndex) |
+NotifyWinEvent(hwnd, childId) => |
+ | AccessibleObjectFromEvent(event, hwnd, OBJID_CLIENT, childId )
+ | will do:
+ <=== 1. send WM_GETOBJECT(hwnd, OBJID_CLIENT)
+widget ~= hwnd
+iface = queryAccessibleInteface(widget)
+(create IAccessible interface wrapper for
+ iface)
+ return iface ===> IAccessible* iface; (for hwnd)
+ |
+ <=== call iface->get_accChild(childId)
+get_accChild() { |
+ if (varChildID.lVal < 0) {
+ QPair ref = recentEvents().value(varChildID.lVal);
+ [...]
+ }
+*/
+
+
+void QAccessible::setRootObject(QObject *o)
+{
+ if (rootObjectHandler) {
+ rootObjectHandler(o);
+ }
+}
+
+class QWindowsEnumerate : public IEnumVARIANT
+{
+public:
+ QWindowsEnumerate(const QVector<int> &a)
+ : ref(0), current(0),array(a)
+ {
+ }
+
+ virtual ~QWindowsEnumerate() {}
+
+ HRESULT STDMETHODCALLTYPE QueryInterface(REFIID, LPVOID *);
+ ULONG STDMETHODCALLTYPE AddRef();
+ ULONG STDMETHODCALLTYPE Release();
+
+ HRESULT STDMETHODCALLTYPE Clone(IEnumVARIANT **ppEnum);
+ HRESULT STDMETHODCALLTYPE Next(unsigned long celt, VARIANT FAR* rgVar, unsigned long FAR* pCeltFetched);
+ HRESULT STDMETHODCALLTYPE Reset();
+ HRESULT STDMETHODCALLTYPE Skip(unsigned long celt);
+
+private:
+ ULONG ref;
+ ULONG current;
+ QVector<int> array;
+};
+
+HRESULT STDMETHODCALLTYPE QWindowsEnumerate::QueryInterface(REFIID id, LPVOID *iface)
+{
+ *iface = 0;
+ if (id == IID_IUnknown)
+ *iface = (IUnknown*)this;
+ else if (id == IID_IEnumVARIANT)
+ *iface = (IEnumVARIANT*)this;
+
+ if (*iface) {
+ AddRef();
+ return S_OK;
+ }
+
+ return E_NOINTERFACE;
+}
+
+ULONG STDMETHODCALLTYPE QWindowsEnumerate::AddRef()
+{
+ return ++ref;
+}
+
+ULONG STDMETHODCALLTYPE QWindowsEnumerate::Release()
+{
+ if (!--ref) {
+ delete this;
+ return 0;
+ }
+ return ref;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsEnumerate::Clone(IEnumVARIANT **ppEnum)
+{
+ QWindowsEnumerate *penum = 0;
+ *ppEnum = 0;
+
+ penum = new QWindowsEnumerate(array);
+ if (!penum)
+ return E_OUTOFMEMORY;
+ penum->current = current;
+ penum->array = array;
+ penum->AddRef();
+ *ppEnum = penum;
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsEnumerate::Next(unsigned long celt, VARIANT FAR* rgVar, unsigned long FAR* pCeltFetched)
+{
+ if (pCeltFetched)
+ *pCeltFetched = 0;
+
+ ULONG l;
+ for (l = 0; l < celt; l++) {
+ VariantInit(&rgVar[l]);
+ if ((current+1) > (ULONG)array.size()) {
+ *pCeltFetched = l;
+ return S_FALSE;
+ }
+
+ rgVar[l].vt = VT_I4;
+ rgVar[l].lVal = array[(int)current];
+ ++current;
+ }
+ *pCeltFetched = l;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsEnumerate::Reset()
+{
+ current = 0;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsEnumerate::Skip(unsigned long celt)
+{
+ current += celt;
+ if (current > (ULONG)array.size()) {
+ current = array.size();
+ return S_FALSE;
+ }
+ return S_OK;
+}
+
+/*
+*/
+class QWindowsAccessible : public IAccessible, IOleWindow, QAccessible
+{
+public:
+ QWindowsAccessible(QAccessibleInterface *a)
+ : ref(0), accessible(a)
+ {
+ }
+
+ virtual ~QWindowsAccessible()
+ {
+ delete accessible;
+ }
+
+ /* IUnknown */
+ HRESULT STDMETHODCALLTYPE QueryInterface(REFIID, LPVOID *);
+ ULONG STDMETHODCALLTYPE AddRef();
+ ULONG STDMETHODCALLTYPE Release();
+
+ /* IDispatch */
+ HRESULT STDMETHODCALLTYPE GetTypeInfoCount(unsigned int *);
+ HRESULT STDMETHODCALLTYPE GetTypeInfo(unsigned int, unsigned long, ITypeInfo **);
+ HRESULT STDMETHODCALLTYPE GetIDsOfNames(const _GUID &, wchar_t **, unsigned int, unsigned long, long *);
+ HRESULT STDMETHODCALLTYPE Invoke(long, const _GUID &, unsigned long, unsigned short, tagDISPPARAMS *, tagVARIANT *, tagEXCEPINFO *, unsigned int *);
+
+ /* IAccessible */
+ HRESULT STDMETHODCALLTYPE accHitTest(long xLeft, long yTop, VARIANT *pvarID);
+ HRESULT STDMETHODCALLTYPE accLocation(long *pxLeft, long *pyTop, long *pcxWidth, long *pcyHeight, VARIANT varID);
+ HRESULT STDMETHODCALLTYPE accNavigate(long navDir, VARIANT varStart, VARIANT *pvarEnd);
+ HRESULT STDMETHODCALLTYPE get_accChild(VARIANT varChildID, IDispatch** ppdispChild);
+ HRESULT STDMETHODCALLTYPE get_accChildCount(long* pcountChildren);
+ HRESULT STDMETHODCALLTYPE get_accParent(IDispatch** ppdispParent);
+
+ HRESULT STDMETHODCALLTYPE accDoDefaultAction(VARIANT varID);
+ HRESULT STDMETHODCALLTYPE get_accDefaultAction(VARIANT varID, BSTR* pszDefaultAction);
+ HRESULT STDMETHODCALLTYPE get_accDescription(VARIANT varID, BSTR* pszDescription);
+ HRESULT STDMETHODCALLTYPE get_accHelp(VARIANT varID, BSTR *pszHelp);
+ HRESULT STDMETHODCALLTYPE get_accHelpTopic(BSTR *pszHelpFile, VARIANT varChild, long *pidTopic);
+ HRESULT STDMETHODCALLTYPE get_accKeyboardShortcut(VARIANT varID, BSTR *pszKeyboardShortcut);
+ HRESULT STDMETHODCALLTYPE get_accName(VARIANT varID, BSTR* pszName);
+ HRESULT STDMETHODCALLTYPE put_accName(VARIANT varChild, BSTR szName);
+ HRESULT STDMETHODCALLTYPE get_accRole(VARIANT varID, VARIANT *pvarRole);
+ HRESULT STDMETHODCALLTYPE get_accState(VARIANT varID, VARIANT *pvarState);
+ HRESULT STDMETHODCALLTYPE get_accValue(VARIANT varID, BSTR* pszValue);
+ HRESULT STDMETHODCALLTYPE put_accValue(VARIANT varChild, BSTR szValue);
+
+ HRESULT STDMETHODCALLTYPE accSelect(long flagsSelect, VARIANT varID);
+ HRESULT STDMETHODCALLTYPE get_accFocus(VARIANT *pvarID);
+ HRESULT STDMETHODCALLTYPE get_accSelection(VARIANT *pvarChildren);
+
+ /* IOleWindow */
+ HRESULT STDMETHODCALLTYPE GetWindow(HWND *phwnd);
+ HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL fEnterMode);
+
+private:
+ ULONG ref;
+ QAccessibleInterface *accessible;
+};
+
+static inline BSTR QStringToBSTR(const QString &str)
+{
+ BSTR bstrVal;
+
+ int wlen = str.length()+1;
+ bstrVal = SysAllocStringByteLen(0, wlen*2);
+ memcpy(bstrVal, str.unicode(), sizeof(QChar)*(wlen));
+ bstrVal[wlen] = 0;
+
+ return bstrVal;
+}
+
+/*
+*/
+IAccessible *qt_createWindowsAccessible(QAccessibleInterface *access)
+{
+ QWindowsAccessible *acc = new QWindowsAccessible(access);
+ IAccessible *iface;
+ acc->QueryInterface(IID_IAccessible, (void**)&iface);
+
+ return iface;
+}
+
+/*
+ IUnknown
+*/
+HRESULT STDMETHODCALLTYPE QWindowsAccessible::QueryInterface(REFIID id, LPVOID *iface)
+{
+ *iface = 0;
+ if (id == IID_IUnknown)
+ *iface = (IUnknown*)(IDispatch*)this;
+ else if (id == IID_IDispatch)
+ *iface = (IDispatch*)this;
+ else if (id == IID_IAccessible)
+ *iface = (IAccessible*)this;
+ else if (id == IID_IOleWindow)
+ *iface = (IOleWindow*)this;
+ else
+ return E_NOINTERFACE;
+
+ AddRef();
+ return S_OK;
+}
+
+ULONG STDMETHODCALLTYPE QWindowsAccessible::AddRef()
+{
+ return ++ref;
+}
+
+ULONG STDMETHODCALLTYPE QWindowsAccessible::Release()
+{
+ if (!--ref) {
+ delete this;
+ return 0;
+ }
+ return ref;
+}
+
+/*
+ IDispatch
+*/
+
+HRESULT STDMETHODCALLTYPE QWindowsAccessible::GetTypeInfoCount(unsigned int * pctinfo)
+{
+ // We don't use a type library
+ *pctinfo = 0;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsAccessible::GetTypeInfo(unsigned int, unsigned long, ITypeInfo **pptinfo)
+{
+ // We don't use a type library
+ *pptinfo = 0;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsAccessible::GetIDsOfNames(const _GUID &, wchar_t **rgszNames, unsigned int, unsigned long, long *rgdispid)
+{
+#if !defined(Q_CC_BOR) && !defined(Q_CC_GNU)
+ // PROPERTIES: Hierarchical
+ if (_bstr_t(rgszNames[0]) == _bstr_t(L"accParent"))
+ rgdispid[0] = DISPID_ACC_PARENT;
+ else if(_bstr_t(rgszNames[0]) == _bstr_t(L"accChildCount"))
+ rgdispid[0] = DISPID_ACC_CHILDCOUNT;
+ else if(_bstr_t(rgszNames[0]) == _bstr_t(L"accChild"))
+ rgdispid[0] = DISPID_ACC_CHILD;
+
+ // PROPERTIES: Descriptional
+ else if(_bstr_t(rgszNames[0]) == _bstr_t(L"accName("))
+ rgdispid[0] = DISPID_ACC_NAME;
+ else if(_bstr_t(rgszNames[0]) == _bstr_t(L"accValue"))
+ rgdispid[0] = DISPID_ACC_VALUE;
+ else if(_bstr_t(rgszNames[0]) == _bstr_t(L"accDescription"))
+ rgdispid[0] = DISPID_ACC_DESCRIPTION;
+ else if(_bstr_t(rgszNames[0]) == _bstr_t(L"accRole"))
+ rgdispid[0] = DISPID_ACC_ROLE;
+ else if(_bstr_t(rgszNames[0]) == _bstr_t(L"accState"))
+ rgdispid[0] = DISPID_ACC_STATE;
+ else if(_bstr_t(rgszNames[0]) == _bstr_t(L"accHelp"))
+ rgdispid[0] = DISPID_ACC_HELP;
+ else if(_bstr_t(rgszNames[0]) == _bstr_t(L"accHelpTopic"))
+ rgdispid[0] = DISPID_ACC_HELPTOPIC;
+ else if(_bstr_t(rgszNames[0]) == _bstr_t(L"accKeyboardShortcut"))
+ rgdispid[0] = DISPID_ACC_KEYBOARDSHORTCUT;
+ else if(_bstr_t(rgszNames[0]) == _bstr_t(L"accFocus"))
+ rgdispid[0] = DISPID_ACC_FOCUS;
+ else if(_bstr_t(rgszNames[0]) == _bstr_t(L"accSelection"))
+ rgdispid[0] = DISPID_ACC_SELECTION;
+ else if(_bstr_t(rgszNames[0]) == _bstr_t(L"accDefaultAction"))
+ rgdispid[0] = DISPID_ACC_DEFAULTACTION;
+
+ // METHODS
+ else if(_bstr_t(rgszNames[0]) == _bstr_t(L"accSelect"))
+ rgdispid[0] = DISPID_ACC_SELECT;
+ else if(_bstr_t(rgszNames[0]) == _bstr_t(L"accLocation"))
+ rgdispid[0] = DISPID_ACC_LOCATION;
+ else if(_bstr_t(rgszNames[0]) == _bstr_t(L"accNavigate"))
+ rgdispid[0] = DISPID_ACC_NAVIGATE;
+ else if(_bstr_t(rgszNames[0]) == _bstr_t(L"accHitTest"))
+ rgdispid[0] = DISPID_ACC_HITTEST;
+ else if(_bstr_t(rgszNames[0]) == _bstr_t(L"accDoDefaultAction"))
+ rgdispid[0] = DISPID_ACC_DODEFAULTACTION;
+ else
+ return DISP_E_UNKNOWNINTERFACE;
+
+ return S_OK;
+#else
+ Q_UNUSED(rgszNames);
+ Q_UNUSED(rgdispid);
+
+ return DISP_E_MEMBERNOTFOUND;
+#endif
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsAccessible::Invoke(long dispIdMember, const _GUID &, unsigned long, unsigned short wFlags, tagDISPPARAMS *pDispParams, tagVARIANT *pVarResult, tagEXCEPINFO *, unsigned int *)
+{
+ HRESULT hr = DISP_E_MEMBERNOTFOUND;
+
+ switch(dispIdMember)
+ {
+ case DISPID_ACC_PARENT:
+ if (wFlags == DISPATCH_PROPERTYGET) {
+ if (!pVarResult)
+ return E_INVALIDARG;
+ hr = get_accParent(&pVarResult->pdispVal);
+ } else {
+ hr = DISP_E_MEMBERNOTFOUND;
+ }
+ break;
+
+ case DISPID_ACC_CHILDCOUNT:
+ if (wFlags == DISPATCH_PROPERTYGET) {
+ if (!pVarResult)
+ return E_INVALIDARG;
+ hr = get_accChildCount(&pVarResult->lVal);
+ } else {
+ hr = DISP_E_MEMBERNOTFOUND;
+ }
+ break;
+
+ case DISPID_ACC_CHILD:
+ if (wFlags == DISPATCH_PROPERTYGET)
+ hr = get_accChild(pDispParams->rgvarg[0], &pVarResult->pdispVal);
+ else
+ hr = DISP_E_MEMBERNOTFOUND;
+ break;
+
+ case DISPID_ACC_NAME:
+ if (wFlags == DISPATCH_PROPERTYGET)
+ hr = get_accName(pDispParams->rgvarg[0], &pVarResult->bstrVal);
+ else if (wFlags == DISPATCH_PROPERTYPUT)
+ hr = put_accName(pDispParams->rgvarg[0], pVarResult->bstrVal);
+ else
+ hr = DISP_E_MEMBERNOTFOUND;
+ break;
+
+ case DISPID_ACC_VALUE:
+ if (wFlags == DISPATCH_PROPERTYGET)
+ hr = get_accValue(pDispParams->rgvarg[0], &pVarResult->bstrVal);
+ else if (wFlags == DISPATCH_PROPERTYPUT)
+ hr = put_accValue(pDispParams->rgvarg[0], pVarResult->bstrVal);
+ else
+ hr = DISP_E_MEMBERNOTFOUND;
+ break;
+
+ case DISPID_ACC_DESCRIPTION:
+ if (wFlags == DISPATCH_PROPERTYGET)
+ hr = get_accDescription(pDispParams->rgvarg[0], &pVarResult->bstrVal);
+ else
+ hr = DISP_E_MEMBERNOTFOUND;
+ break;
+
+ case DISPID_ACC_ROLE:
+ if (wFlags == DISPATCH_PROPERTYGET)
+ hr = get_accRole(pDispParams->rgvarg[0], pVarResult);
+ else
+ hr = DISP_E_MEMBERNOTFOUND;
+ break;
+
+ case DISPID_ACC_STATE:
+ if (wFlags == DISPATCH_PROPERTYGET)
+ hr = get_accState(pDispParams->rgvarg[0], pVarResult);
+ else
+ hr = DISP_E_MEMBERNOTFOUND;
+ break;
+
+ case DISPID_ACC_HELP:
+ if (wFlags == DISPATCH_PROPERTYGET)
+ hr = get_accHelp(pDispParams->rgvarg[0], &pVarResult->bstrVal);
+ else
+ hr = DISP_E_MEMBERNOTFOUND;
+ break;
+
+ case DISPID_ACC_HELPTOPIC:
+ if (wFlags == DISPATCH_PROPERTYGET)
+ hr = get_accHelpTopic(&pDispParams->rgvarg[2].bstrVal, pDispParams->rgvarg[1], &pDispParams->rgvarg[0].lVal);
+ else
+ hr = DISP_E_MEMBERNOTFOUND;
+ break;
+
+ case DISPID_ACC_KEYBOARDSHORTCUT:
+ if (wFlags == DISPATCH_PROPERTYGET)
+ hr = get_accKeyboardShortcut(pDispParams->rgvarg[0], &pVarResult->bstrVal);
+ else
+ hr = DISP_E_MEMBERNOTFOUND;
+ break;
+
+ case DISPID_ACC_FOCUS:
+ if (wFlags == DISPATCH_PROPERTYGET)
+ hr = get_accFocus(pVarResult);
+ else
+ hr = DISP_E_MEMBERNOTFOUND;
+ break;
+
+ case DISPID_ACC_SELECTION:
+ if (wFlags == DISPATCH_PROPERTYGET)
+ hr = get_accSelection(pVarResult);
+ else
+ hr = DISP_E_MEMBERNOTFOUND;
+ break;
+
+ case DISPID_ACC_DEFAULTACTION:
+ if (wFlags == DISPATCH_PROPERTYGET)
+ hr = get_accDefaultAction(pDispParams->rgvarg[0], &pVarResult->bstrVal);
+ else
+ hr = DISP_E_MEMBERNOTFOUND;
+ break;
+
+ case DISPID_ACC_SELECT:
+ if (wFlags == DISPATCH_METHOD)
+ hr = accSelect(pDispParams->rgvarg[1].lVal, pDispParams->rgvarg[0]);
+ else
+ hr = DISP_E_MEMBERNOTFOUND;
+ break;
+
+ case DISPID_ACC_LOCATION:
+ if (wFlags == DISPATCH_METHOD)
+ hr = accLocation(&pDispParams->rgvarg[4].lVal, &pDispParams->rgvarg[3].lVal, &pDispParams->rgvarg[2].lVal, &pDispParams->rgvarg[1].lVal, pDispParams->rgvarg[0]);
+ else
+ hr = DISP_E_MEMBERNOTFOUND;
+ break;
+
+ case DISPID_ACC_NAVIGATE:
+ if (wFlags == DISPATCH_METHOD)
+ hr = accNavigate(pDispParams->rgvarg[1].lVal, pDispParams->rgvarg[0], pVarResult);
+ else
+ hr = DISP_E_MEMBERNOTFOUND;
+ break;
+
+ case DISPID_ACC_HITTEST:
+ if (wFlags == DISPATCH_METHOD)
+ hr = accHitTest(pDispParams->rgvarg[1].lVal, pDispParams->rgvarg[0].lVal, pVarResult);
+ else
+ hr = DISP_E_MEMBERNOTFOUND;
+ break;
+
+ case DISPID_ACC_DODEFAULTACTION:
+ if (wFlags == DISPATCH_METHOD)
+ hr = accDoDefaultAction(pDispParams->rgvarg[0]);
+ else
+ hr = DISP_E_MEMBERNOTFOUND;
+ break;
+
+ default:
+ hr = DISP_E_MEMBERNOTFOUND;
+ break;
+ }
+
+ if (!SUCCEEDED(hr)) {
+ return hr;
+ }
+ return hr;
+}
+
+/*
+ IAccessible
+*/
+HRESULT STDMETHODCALLTYPE QWindowsAccessible::accHitTest(long xLeft, long yTop, VARIANT *pvarID)
+{
+ showDebug(__FUNCTION__, accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+
+ int control = accessible->childAt(xLeft, yTop);
+ if (control == -1) {
+ (*pvarID).vt = VT_EMPTY;
+ return S_FALSE;
+ }
+ QAccessibleInterface *acc = 0;
+ if (control)
+ accessible->navigate(Child, control, &acc);
+ if (!acc) {
+ (*pvarID).vt = VT_I4;
+ (*pvarID).lVal = control;
+ return S_OK;
+ }
+
+ QWindowsAccessible* wacc = new QWindowsAccessible(acc);
+ IDispatch *iface = 0;
+ wacc->QueryInterface(IID_IDispatch, (void**)&iface);
+ if (iface) {
+ (*pvarID).vt = VT_DISPATCH;
+ (*pvarID).pdispVal = iface;
+ return S_OK;
+ } else {
+ delete wacc;
+ }
+
+ (*pvarID).vt = VT_EMPTY;
+ return S_FALSE;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsAccessible::accLocation(long *pxLeft, long *pyTop, long *pcxWidth, long *pcyHeight, VARIANT varID)
+{
+ showDebug(__FUNCTION__, accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+
+ QRect rect = accessible->rect(varID.lVal);
+ if (rect.isValid()) {
+ *pxLeft = rect.x();
+ *pyTop = rect.y();
+ *pcxWidth = rect.width();
+ *pcyHeight = rect.height();
+ } else {
+ *pxLeft = 0;
+ *pyTop = 0;
+ *pcxWidth = 0;
+ *pcyHeight = 0;
+ }
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsAccessible::accNavigate(long navDir, VARIANT varStart, VARIANT *pvarEnd)
+{
+ showDebug(__FUNCTION__, accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+
+ QAccessibleInterface *acc = 0;
+ int control = -1;
+ switch(navDir) {
+ case NAVDIR_FIRSTCHILD:
+ control = accessible->navigate(Child, 1, &acc);
+ break;
+ case NAVDIR_LASTCHILD:
+ control = accessible->navigate(Child, accessible->childCount(), &acc);
+ break;
+ case NAVDIR_NEXT:
+ case NAVDIR_PREVIOUS:
+ if (!varStart.lVal){
+ QAccessibleInterface *parent = 0;
+ accessible->navigate(Ancestor, 1, &parent);
+ if (parent) {
+ int index = parent->indexOfChild(accessible);
+ index += (navDir == NAVDIR_NEXT) ? 1 : -1;
+ if (index > 0 && index <= parent->childCount())
+ control = parent->navigate(Child, index, &acc);
+ delete parent;
+ }
+ } else {
+ int index = varStart.lVal;
+ index += (navDir == NAVDIR_NEXT) ? 1 : -1;
+ if (index > 0 && index <= accessible->childCount())
+ control = accessible->navigate(Child, index, &acc);
+ }
+ break;
+ case NAVDIR_UP:
+ control = accessible->navigate(Up, varStart.lVal, &acc);
+ break;
+ case NAVDIR_DOWN:
+ control = accessible->navigate(Down, varStart.lVal, &acc);
+ break;
+ case NAVDIR_LEFT:
+ control = accessible->navigate(Left, varStart.lVal, &acc);
+ break;
+ case NAVDIR_RIGHT:
+ control = accessible->navigate(Right, varStart.lVal, &acc);
+ break;
+ default:
+ break;
+ }
+ if (control == -1) {
+ (*pvarEnd).vt = VT_EMPTY;
+ return S_FALSE;
+ }
+ if (!acc) {
+ (*pvarEnd).vt = VT_I4;
+ (*pvarEnd).lVal = control;
+ return S_OK;
+ }
+
+ QWindowsAccessible* wacc = new QWindowsAccessible(acc);
+
+ IDispatch *iface = 0;
+ wacc->QueryInterface(IID_IDispatch, (void**)&iface);
+ if (iface) {
+ (*pvarEnd).vt = VT_DISPATCH;
+ (*pvarEnd).pdispVal = iface;
+ return S_OK;
+ } else {
+ delete wacc;
+ }
+
+ (*pvarEnd).vt = VT_EMPTY;
+ return S_FALSE;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accChild(VARIANT varChildID, IDispatch** ppdispChild)
+{
+ showDebug(__FUNCTION__, accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+
+ if (varChildID.vt == VT_EMPTY)
+ return E_INVALIDARG;
+
+
+ int childIndex = varChildID.lVal;
+ QAccessibleInterface *acc = 0;
+
+ if (childIndex < 0) {
+ const int entry = childIndex;
+ QPair<QObject*, int> ref = qAccessibleRecentSentEvents()->value(entry);
+ if (ref.first) {
+ acc = queryAccessibleInterface(ref.first);
+ if (acc && ref.second) {
+ if (ref.second) {
+ QAccessibleInterface *res;
+ int index = acc->navigate(Child, ref.second, &res);
+ delete acc;
+ if (index == -1)
+ return E_INVALIDARG;
+ acc = res;
+ }
+ }
+ }
+ } else {
+ RelationFlag rel = childIndex ? Child : Self;
+ accessible->navigate(rel, childIndex, &acc);
+ }
+
+ if (acc) {
+ QWindowsAccessible* wacc = new QWindowsAccessible(acc);
+ wacc->QueryInterface(IID_IDispatch, (void**)ppdispChild);
+ return S_OK;
+ }
+
+ *ppdispChild = 0;
+ return S_FALSE;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accChildCount(long* pcountChildren)
+{
+ showDebug(__FUNCTION__, accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+
+ *pcountChildren = accessible->childCount();
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accParent(IDispatch** ppdispParent)
+{
+ showDebug(__FUNCTION__, accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+
+ QAccessibleInterface *acc = 0;
+ accessible->navigate(Ancestor, 1, &acc);
+ if (acc) {
+ QWindowsAccessible* wacc = new QWindowsAccessible(acc);
+ wacc->QueryInterface(IID_IDispatch, (void**)ppdispParent);
+
+ if (*ppdispParent)
+ return S_OK;
+ }
+
+ *ppdispParent = 0;
+ return S_FALSE;
+}
+
+/*
+ Properties and methods
+*/
+HRESULT STDMETHODCALLTYPE QWindowsAccessible::accDoDefaultAction(VARIANT varID)
+{
+ showDebug(__FUNCTION__, accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+
+ return accessible->doAction(DefaultAction, varID.lVal, QVariantList()) ? S_OK : S_FALSE;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accDefaultAction(VARIANT varID, BSTR* pszDefaultAction)
+{
+ showDebug(__FUNCTION__, accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+
+ QString def = accessible->actionText(DefaultAction, Name, varID.lVal);
+ if (def.isEmpty()) {
+ *pszDefaultAction = 0;
+ return S_FALSE;
+ }
+
+ *pszDefaultAction = QStringToBSTR(def);
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accDescription(VARIANT varID, BSTR* pszDescription)
+{
+ showDebug(__FUNCTION__, accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+
+ QString descr = accessible->text(Description, varID.lVal);
+ if (descr.size()) {
+ *pszDescription = QStringToBSTR(descr);
+ return S_OK;
+ }
+
+ *pszDescription = 0;
+ return S_FALSE;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accHelp(VARIANT varID, BSTR *pszHelp)
+{
+ showDebug(__FUNCTION__, accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+
+ QString help = accessible->text(Help, varID.lVal);
+ if (help.size()) {
+ *pszHelp = QStringToBSTR(help);
+ return S_OK;
+ }
+
+ *pszHelp = 0;
+ return S_FALSE;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accHelpTopic(BSTR *, VARIANT, long *)
+{
+ return DISP_E_MEMBERNOTFOUND;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accKeyboardShortcut(VARIANT varID, BSTR *pszKeyboardShortcut)
+{
+ showDebug(__FUNCTION__, accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+
+ QString sc = accessible->text(Accelerator, varID.lVal);
+ if (sc.size()) {
+ *pszKeyboardShortcut = QStringToBSTR(sc);
+ return S_OK;
+ }
+
+ *pszKeyboardShortcut = 0;
+ return S_FALSE;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accName(VARIANT varID, BSTR* pszName)
+{
+ showDebug(__FUNCTION__, accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+
+ QString n = accessible->text(Name, varID.lVal);
+ if (n.size()) {
+ *pszName = QStringToBSTR(n);
+ return S_OK;
+ }
+
+ *pszName = 0;
+ return S_FALSE;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsAccessible::put_accName(VARIANT, BSTR)
+{
+ showDebug(__FUNCTION__, accessible);
+ return DISP_E_MEMBERNOTFOUND;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accRole(VARIANT varID, VARIANT *pvarRole)
+{
+ showDebug(__FUNCTION__, accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+
+ Role role = accessible->role(varID.lVal);
+ if (role != NoRole) {
+ if (role == LayeredPane)
+ role = QAccessible::Pane;
+ (*pvarRole).vt = VT_I4;
+ (*pvarRole).lVal = role;
+ } else {
+ (*pvarRole).vt = VT_EMPTY;
+ }
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accState(VARIANT varID, VARIANT *pvarState)
+{
+ showDebug(__FUNCTION__, accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+
+ (*pvarState).vt = VT_I4;
+ (*pvarState).lVal = accessible->state(varID.lVal);
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accValue(VARIANT varID, BSTR* pszValue)
+{
+ showDebug(__FUNCTION__, accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+
+ QString value = accessible->text(Value, varID.lVal);
+ if (!value.isNull()) {
+ *pszValue = QStringToBSTR(value);
+ return S_OK;
+ }
+
+ *pszValue = 0;
+ return S_FALSE;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsAccessible::put_accValue(VARIANT, BSTR)
+{
+ showDebug(__FUNCTION__, accessible);
+ return DISP_E_MEMBERNOTFOUND;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsAccessible::accSelect(long flagsSelect, VARIANT varID)
+{
+ showDebug(__FUNCTION__, accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+
+ bool res = false;
+
+ if (flagsSelect & SELFLAG_TAKEFOCUS)
+ res = accessible->doAction(SetFocus, varID.lVal, QVariantList());
+ if (flagsSelect & SELFLAG_TAKESELECTION) {
+ accessible->doAction(ClearSelection, 0, QVariantList());
+ res = accessible->doAction(AddToSelection, varID.lVal, QVariantList());
+ }
+ if (flagsSelect & SELFLAG_EXTENDSELECTION)
+ res = accessible->doAction(ExtendSelection, varID.lVal, QVariantList());
+ if (flagsSelect & SELFLAG_ADDSELECTION)
+ res = accessible->doAction(AddToSelection, varID.lVal, QVariantList());
+ if (flagsSelect & SELFLAG_REMOVESELECTION)
+ res = accessible->doAction(RemoveSelection, varID.lVal, QVariantList());
+
+ return res ? S_OK : S_FALSE;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accFocus(VARIANT *pvarID)
+{
+ showDebug(__FUNCTION__, accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+
+ QAccessibleInterface *acc = 0;
+ int control = accessible->navigate(FocusChild, 1, &acc);
+ if (control == -1) {
+ (*pvarID).vt = VT_EMPTY;
+ return S_FALSE;
+ }
+ if (!acc || control == 0) {
+ (*pvarID).vt = VT_I4;
+ (*pvarID).lVal = control ? control : CHILDID_SELF;
+ return S_OK;
+ }
+
+ QWindowsAccessible* wacc = new QWindowsAccessible(acc);
+ IDispatch *iface = 0;
+ wacc->QueryInterface(IID_IDispatch, (void**)&iface);
+ if (iface) {
+ (*pvarID).vt = VT_DISPATCH;
+ (*pvarID).pdispVal = iface;
+ return S_OK;
+ } else {
+ delete wacc;
+ }
+
+ (*pvarID).vt = VT_EMPTY;
+ return S_FALSE;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accSelection(VARIANT *pvarChildren)
+{
+ showDebug(__FUNCTION__, accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+
+ int cc = accessible->childCount();
+ QVector<int> sel(cc);
+ int selIndex = 0;
+ for (int i = 1; i <= cc; ++i) {
+ QAccessibleInterface *child = 0;
+ int i2 = accessible->navigate(Child, i, &child);
+ bool isSelected = false;
+ if (child) {
+ isSelected = child->state(0) & Selected;
+ delete child;
+ child = 0;
+ } else {
+ isSelected = accessible->state(i2) & Selected;
+ }
+ if (isSelected)
+ sel[selIndex++] = i;
+ }
+ sel.resize(selIndex);
+ if (sel.isEmpty()) {
+ (*pvarChildren).vt = VT_EMPTY;
+ return S_FALSE;
+ }
+ if (sel.size() == 1) {
+ (*pvarChildren).vt = VT_I4;
+ (*pvarChildren).lVal = sel[0];
+ return S_OK;
+ }
+ IEnumVARIANT *iface = new QWindowsEnumerate(sel);
+ IUnknown *uiface;
+ iface->QueryInterface(IID_IUnknown, (void**)&uiface);
+ (*pvarChildren).vt = VT_UNKNOWN;
+ (*pvarChildren).punkVal = uiface;
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsAccessible::GetWindow(HWND *phwnd)
+{
+ *phwnd = 0;
+ if (!accessible->isValid())
+ return E_UNEXPECTED;
+
+ QObject *o = accessible->object();
+ if (!o || !o->isWidgetType())
+ return E_FAIL;
+
+ *phwnd = static_cast<QWidget*>(o)->effectiveWinId();
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsAccessible::ContextSensitiveHelp(BOOL)
+{
+ return S_OK;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_ACCESSIBILITY
diff --git a/src/gui/accessible/qaccessiblebridge.cpp b/src/widgets/accessible/qaccessiblebridge.cpp
index af08654d70..af08654d70 100644
--- a/src/gui/accessible/qaccessiblebridge.cpp
+++ b/src/widgets/accessible/qaccessiblebridge.cpp
diff --git a/src/widgets/accessible/qaccessiblebridge.h b/src/widgets/accessible/qaccessiblebridge.h
new file mode 100644
index 0000000000..0ea04501d0
--- /dev/null
+++ b/src/widgets/accessible/qaccessiblebridge.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QACCESSIBLEBRIDGE_H
+#define QACCESSIBLEBRIDGE_H
+
+#include <QtCore/qplugin.h>
+#include <QtCore/qfactoryinterface.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_ACCESSIBILITY
+
+class QAccessibleInterface;
+
+class QAccessibleBridge
+{
+public:
+ virtual ~QAccessibleBridge() {}
+ virtual void setRootObject(QAccessibleInterface *) = 0;
+ virtual void notifyAccessibilityUpdate(int, QAccessibleInterface*, int) = 0;
+};
+
+struct Q_WIDGETS_EXPORT QAccessibleBridgeFactoryInterface : public QFactoryInterface
+{
+ virtual QAccessibleBridge *create(const QString& name) = 0;
+};
+
+#define QAccessibleBridgeFactoryInterface_iid "com.trolltech.Qt.QAccessibleBridgeFactoryInterface"
+Q_DECLARE_INTERFACE(QAccessibleBridgeFactoryInterface, QAccessibleBridgeFactoryInterface_iid)
+
+class Q_WIDGETS_EXPORT QAccessibleBridgePlugin : public QObject, public QAccessibleBridgeFactoryInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QAccessibleBridgeFactoryInterface:QFactoryInterface)
+public:
+ explicit QAccessibleBridgePlugin(QObject *parent = 0);
+ ~QAccessibleBridgePlugin();
+
+ virtual QStringList keys() const = 0;
+ virtual QAccessibleBridge *create(const QString &key) = 0;
+};
+
+#endif // QT_NO_ACCESSIBILITY
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QACCESSIBLEBRIDGE_H
diff --git a/src/gui/accessible/qaccessibleobject.cpp b/src/widgets/accessible/qaccessibleobject.cpp
index 20f3a15bb4..20f3a15bb4 100644
--- a/src/gui/accessible/qaccessibleobject.cpp
+++ b/src/widgets/accessible/qaccessibleobject.cpp
diff --git a/src/widgets/accessible/qaccessibleobject.h b/src/widgets/accessible/qaccessibleobject.h
new file mode 100644
index 0000000000..f2ec2ba9c9
--- /dev/null
+++ b/src/widgets/accessible/qaccessibleobject.h
@@ -0,0 +1,140 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QACCESSIBLEOBJECT_H
+#define QACCESSIBLEOBJECT_H
+
+#include <QtWidgets/qaccessible.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_ACCESSIBILITY
+
+class QAccessibleObjectPrivate;
+class QObject;
+
+class Q_WIDGETS_EXPORT QAccessibleObject : public QAccessibleInterface
+{
+public:
+ explicit QAccessibleObject(QObject *object);
+
+ bool isValid() const;
+ QObject *object() const;
+
+ // properties
+ QRect rect(int child) const;
+ void setText(Text t, int child, const QString &text);
+
+ // actions
+ int userActionCount(int child) const;
+ bool doAction(int action, int child, const QVariantList &params);
+ QString actionText(int action, Text t, int child) const;
+
+protected:
+ virtual ~QAccessibleObject();
+
+private:
+ friend class QAccessibleObjectEx;
+ QAccessibleObjectPrivate *d;
+ Q_DISABLE_COPY(QAccessibleObject)
+};
+
+class Q_WIDGETS_EXPORT QAccessibleObjectEx : public QAccessibleInterfaceEx
+{
+public:
+ explicit QAccessibleObjectEx(QObject *object);
+
+ bool isValid() const;
+ QObject *object() const;
+
+ // properties
+ QRect rect(int child) const;
+ void setText(Text t, int child, const QString &text);
+
+ // actions
+ int userActionCount(int child) const;
+ bool doAction(int action, int child, const QVariantList &params);
+ QString actionText(int action, Text t, int child) const;
+
+protected:
+ virtual ~QAccessibleObjectEx();
+
+private:
+ QAccessibleObjectPrivate *d;
+ Q_DISABLE_COPY(QAccessibleObjectEx)
+};
+
+class Q_WIDGETS_EXPORT QAccessibleApplication : public QAccessibleObject
+{
+public:
+ QAccessibleApplication();
+
+ // relations
+ int childCount() const;
+ int indexOfChild(const QAccessibleInterface*) const;
+ Relation relationTo(int, const QAccessibleInterface *, int) const;
+
+ // navigation
+ int childAt(int x, int y) const;
+ int navigate(RelationFlag, int, QAccessibleInterface **) const;
+
+ // properties and state
+ QString text(Text t, int child) const;
+ Role role(int child) const;
+ State state(int child) const;
+
+ // actions
+ int userActionCount(int child) const;
+ bool doAction(int action, int child, const QVariantList &params);
+ QString actionText(int action, Text t, int child) const;
+};
+
+#endif // QT_NO_ACCESSIBILITY
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QACCESSIBLEOBJECT_H
diff --git a/src/gui/accessible/qaccessibleplugin.cpp b/src/widgets/accessible/qaccessibleplugin.cpp
index 509463b9ed..509463b9ed 100644
--- a/src/gui/accessible/qaccessibleplugin.cpp
+++ b/src/widgets/accessible/qaccessibleplugin.cpp
diff --git a/src/widgets/accessible/qaccessibleplugin.h b/src/widgets/accessible/qaccessibleplugin.h
new file mode 100644
index 0000000000..a71a1433e1
--- /dev/null
+++ b/src/widgets/accessible/qaccessibleplugin.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QACCESSIBLEPLUGIN_H
+#define QACCESSIBLEPLUGIN_H
+
+#include <QtWidgets/qaccessible.h>
+#include <QtCore/qfactoryinterface.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_ACCESSIBILITY
+
+class QStringList;
+class QAccessibleInterface;
+
+struct Q_WIDGETS_EXPORT QAccessibleFactoryInterface : public QAccessible, public QFactoryInterface
+{
+ virtual QAccessibleInterface* create(const QString &key, QObject *object) = 0;
+};
+
+#define QAccessibleFactoryInterface_iid "com.trolltech.Qt.QAccessibleFactoryInterface"
+Q_DECLARE_INTERFACE(QAccessibleFactoryInterface, QAccessibleFactoryInterface_iid)
+
+class QAccessiblePluginPrivate;
+
+class Q_WIDGETS_EXPORT QAccessiblePlugin : public QObject, public QAccessibleFactoryInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QAccessibleFactoryInterface:QFactoryInterface)
+public:
+ explicit QAccessiblePlugin(QObject *parent = 0);
+ ~QAccessiblePlugin();
+
+ virtual QStringList keys() const = 0;
+ virtual QAccessibleInterface *create(const QString &key, QObject *object) = 0;
+};
+
+#endif // QT_NO_ACCESSIBILITY
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QACCESSIBLEPLUGIN_H
diff --git a/src/widgets/accessible/qaccessiblewidget.cpp b/src/widgets/accessible/qaccessiblewidget.cpp
new file mode 100644
index 0000000000..05948dcc9c
--- /dev/null
+++ b/src/widgets/accessible/qaccessiblewidget.cpp
@@ -0,0 +1,1034 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qaccessiblewidget.h"
+
+#ifndef QT_NO_ACCESSIBILITY
+
+#include "qaction.h"
+#include "qapplication.h"
+#include "qgroupbox.h"
+#include "qlabel.h"
+#include "qtooltip.h"
+#include "qwhatsthis.h"
+#include "qwidget.h"
+#include "qdebug.h"
+#include <qmath.h>
+#include <QRubberBand>
+#include <QFocusFrame>
+#include <QMenu>
+
+QT_BEGIN_NAMESPACE
+
+static QList<QWidget*> childWidgets(const QWidget *widget)
+{
+ QList<QObject*> list = widget->children();
+ QList<QWidget*> widgets;
+ for (int i = 0; i < list.size(); ++i) {
+ QWidget *w = qobject_cast<QWidget *>(list.at(i));
+ if (w && !w->isWindow()
+ && !qobject_cast<QFocusFrame*>(w)
+#if !defined(QT_NO_MENU)
+ && !qobject_cast<QMenu*>(w)
+#endif
+ && w->objectName() != QLatin1String("qt_rubberband"))
+ widgets.append(w);
+ }
+ return widgets;
+}
+
+static QString buddyString(const QWidget *widget)
+{
+ if (!widget)
+ return QString();
+ QWidget *parent = widget->parentWidget();
+ if (!parent)
+ return QString();
+#ifndef QT_NO_SHORTCUT
+ QObjectList ol = parent->children();
+ for (int i = 0; i < ol.size(); ++i) {
+ QLabel *label = qobject_cast<QLabel*>(ol.at(i));
+ if (label && label->buddy() == widget)
+ return label->text();
+ }
+#endif
+
+#ifndef QT_NO_GROUPBOX
+ QGroupBox *groupbox = qobject_cast<QGroupBox*>(parent);
+ if (groupbox)
+ return groupbox->title();
+#endif
+
+ return QString();
+}
+
+QString Q_WIDGETS_EXPORT qt_accStripAmp(const QString &text)
+{
+ return QString(text).remove(QLatin1Char('&'));
+}
+
+QString Q_WIDGETS_EXPORT qt_accHotKey(const QString &text)
+{
+#ifndef QT_NO_SHORTCUT
+ if (text.isEmpty())
+ return text;
+
+ int fa = 0;
+ QChar ac;
+ while ((fa = text.indexOf(QLatin1Char('&'), fa)) != -1) {
+ ++fa;
+ if (fa < text.length()) {
+ // ignore "&&"
+ if (text.at(fa) == QLatin1Char('&')) {
+ ++fa;
+ continue;
+ } else {
+ ac = text.at(fa);
+ break;
+ }
+ }
+ }
+ if (ac.isNull())
+ return QString();
+ return (QString)QKeySequence(Qt::ALT) + ac.toUpper();
+#else
+ Q_UNUSED(text);
+ return QString();
+#endif
+}
+
+class QAccessibleWidgetPrivate : public QAccessible
+{
+public:
+ QAccessibleWidgetPrivate()
+ :role(Client)
+ {}
+
+ Role role;
+ QString name;
+ QString description;
+ QString value;
+ QString help;
+ QString accelerator;
+ QStringList primarySignals;
+ const QAccessibleInterface *asking;
+};
+
+/*!
+ \class QAccessibleWidget
+ \brief The QAccessibleWidget class implements the QAccessibleInterface for QWidgets.
+
+ \ingroup accessibility
+
+ This class is convenient to use as a base class for custom
+ implementations of QAccessibleInterfaces that provide information
+ about widget objects.
+
+ The class provides functions to retrieve the parentObject() (the
+ widget's parent widget), and the associated widget(). Controlling
+ signals can be added with addControllingSignal(), and setters are
+ provided for various aspects of the interface implementation, for
+ example setValue(), setDescription(), setAccelerator(), and
+ setHelp().
+
+ \sa QAccessible, QAccessibleObject
+*/
+
+/*!
+ Creates a QAccessibleWidget object for widget \a w.
+ \a role and \a name are optional parameters that set the object's
+ role and name properties.
+*/
+QAccessibleWidget::QAccessibleWidget(QWidget *w, Role role, const QString &name)
+: QAccessibleObject(w)
+{
+ Q_ASSERT(widget());
+ d = new QAccessibleWidgetPrivate();
+ d->role = role;
+ d->name = name;
+ d->asking = 0;
+}
+
+/*!
+ Destroys this object.
+*/
+QAccessibleWidget::~QAccessibleWidget()
+{
+ delete d;
+}
+
+/*!
+ Returns the associated widget.
+*/
+QWidget *QAccessibleWidget::widget() const
+{
+ return qobject_cast<QWidget*>(object());
+}
+
+/*!
+ Returns the associated widget's parent object, which is either the
+ parent widget, or qApp for top-level widgets.
+*/
+QObject *QAccessibleWidget::parentObject() const
+{
+ QObject *parent = object()->parent();
+ if (!parent)
+ parent = qApp;
+ return parent;
+}
+
+/*! \reimp */
+int QAccessibleWidget::childAt(int x, int y) const
+{
+ QWidget *w = widget();
+ if (!w->isVisible())
+ return -1;
+ QPoint gp = w->mapToGlobal(QPoint(0, 0));
+ if (!QRect(gp.x(), gp.y(), w->width(), w->height()).contains(x, y))
+ return -1;
+
+ QWidgetList list = childWidgets(w);
+ int ccount = childCount();
+
+ // a complex child
+ if (list.size() < ccount) {
+ for (int i = 1; i <= ccount; ++i) {
+ if (rect(i).contains(x, y))
+ return i;
+ }
+ return 0;
+ }
+
+ QPoint rp = w->mapFromGlobal(QPoint(x, y));
+ for (int i = 0; i<list.size(); ++i) {
+ QWidget *child = list.at(i);
+ if (!child->isWindow() && !child->isHidden() && child->geometry().contains(rp)) {
+ return i + 1;
+ }
+ }
+ return 0;
+}
+
+/*! \reimp */
+QRect QAccessibleWidget::rect(int child) const
+{
+ if (child) {
+ qWarning("QAccessibleWidget::rect: This implementation does not support subelements! "
+ "(ID %d unknown for %s)", child, widget()->metaObject()->className());
+ }
+
+ QWidget *w = widget();
+ if (!w->isVisible())
+ return QRect();
+ QPoint wpos = w->mapToGlobal(QPoint(0, 0));
+
+ return QRect(wpos.x(), wpos.y(), w->width(), w->height());
+}
+
+QT_BEGIN_INCLUDE_NAMESPACE
+#include <private/qobject_p.h>
+QT_END_INCLUDE_NAMESPACE
+
+class QACConnectionObject : public QObject
+{
+ Q_DECLARE_PRIVATE(QObject)
+public:
+ inline bool isSender(const QObject *receiver, const char *signal) const
+ { return d_func()->isSender(receiver, signal); }
+ inline QObjectList receiverList(const char *signal) const
+ { return d_func()->receiverList(signal); }
+ inline QObjectList senderList() const
+ { return d_func()->senderList(); }
+};
+
+/*!
+ Registers \a signal as a controlling signal.
+
+ An object is a Controller to any other object connected to a
+ controlling signal.
+*/
+void QAccessibleWidget::addControllingSignal(const QString &signal)
+{
+ QByteArray s = QMetaObject::normalizedSignature(signal.toAscii());
+ if (object()->metaObject()->indexOfSignal(s) < 0)
+ qWarning("Signal %s unknown in %s", s.constData(), object()->metaObject()->className());
+ d->primarySignals << QLatin1String(s);
+}
+
+/*!
+ Sets the value of this interface implementation to \a value.
+
+ The default implementation of text() returns the set value for
+ the Value text.
+
+ Note that the object wrapped by this interface is not modified.
+*/
+void QAccessibleWidget::setValue(const QString &value)
+{
+ d->value = value;
+}
+
+/*!
+ Sets the description of this interface implementation to \a desc.
+
+ The default implementation of text() returns the set value for
+ the Description text.
+
+ Note that the object wrapped by this interface is not modified.
+*/
+void QAccessibleWidget::setDescription(const QString &desc)
+{
+ d->description = desc;
+}
+
+/*!
+ Sets the help of this interface implementation to \a help.
+
+ The default implementation of text() returns the set value for
+ the Help text.
+
+ Note that the object wrapped by this interface is not modified.
+*/
+void QAccessibleWidget::setHelp(const QString &help)
+{
+ d->help = help;
+}
+
+/*!
+ Sets the accelerator of this interface implementation to \a accel.
+
+ The default implementation of text() returns the set value for
+ the Accelerator text.
+
+ Note that the object wrapped by this interface is not modified.
+*/
+void QAccessibleWidget::setAccelerator(const QString &accel)
+{
+ d->accelerator = accel;
+}
+
+static inline bool isAncestor(const QObject *obj, const QObject *child)
+{
+ while (child) {
+ if (child == obj)
+ return true;
+ child = child->parent();
+ }
+ return false;
+}
+
+
+/*! \reimp */
+QAccessible::Relation QAccessibleWidget::relationTo(int child,
+ const QAccessibleInterface *other, int otherChild) const
+{
+ Relation relation = Unrelated;
+ if (d->asking == this) // recursive call
+ return relation;
+
+ QObject *o = other ? other->object() : 0;
+ if (!o)
+ return relation;
+
+ QWidget *focus = widget()->focusWidget();
+ if (object() == focus && isAncestor(o, focus))
+ relation |= FocusChild;
+
+ QACConnectionObject *connectionObject = (QACConnectionObject*)object();
+ for (int sig = 0; sig < d->primarySignals.count(); ++sig) {
+ if (connectionObject->isSender(o, d->primarySignals.at(sig).toAscii())) {
+ relation |= Controller;
+ break;
+ }
+ }
+ // test for passive relationships.
+ // d->asking protects from endless recursion.
+ d->asking = this;
+ int inverse = other->relationTo(otherChild, this, child);
+ d->asking = 0;
+
+ if (inverse & Controller)
+ relation |= Controlled;
+ if (inverse & Label)
+ relation |= Labelled;
+
+ if(o == object()) {
+ if (child && !otherChild)
+ return relation | Child;
+ if (!child && otherChild)
+ return relation | Ancestor;
+ if (!child && !otherChild)
+ return relation | Self;
+ }
+
+ QObject *parent = object()->parent();
+ if (o == parent)
+ return relation | Child;
+
+ if (o->parent() == parent) {
+ relation |= Sibling;
+ QAccessibleInterface *sibIface = QAccessible::queryAccessibleInterface(o);
+ Q_ASSERT(sibIface);
+ QRect wg = rect(0);
+ QRect sg = sibIface->rect(0);
+ if (wg.intersects(sg)) {
+ QAccessibleInterface *pIface = 0;
+ sibIface->navigate(Ancestor, 1, &pIface);
+ if (pIface && !((sibIface->state(0) | state(0)) & Invisible)) {
+ int wi = pIface->indexOfChild(this);
+ int si = pIface->indexOfChild(sibIface);
+
+ if (wi > si)
+ relation |= QAccessible::Covers;
+ else
+ relation |= QAccessible::Covered;
+ }
+ delete pIface;
+ } else {
+ QPoint wc = wg.center();
+ QPoint sc = sg.center();
+ if (wc.x() < sc.x())
+ relation |= QAccessible::Left;
+ else if(wc.x() > sc.x())
+ relation |= QAccessible::Right;
+ if (wc.y() < sc.y())
+ relation |= QAccessible::Up;
+ else if (wc.y() > sc.y())
+ relation |= QAccessible::Down;
+ }
+ delete sibIface;
+
+ return relation;
+ }
+
+ if (isAncestor(o, object()))
+ return relation | Descendent;
+ if (isAncestor(object(), o))
+ return relation | Ancestor;
+
+ return relation;
+}
+
+/*! \reimp */
+int QAccessibleWidget::navigate(RelationFlag relation, int entry,
+ QAccessibleInterface **target) const
+{
+ if (!target)
+ return -1;
+
+ *target = 0;
+ QObject *targetObject = 0;
+
+ QWidgetList childList = childWidgets(widget());
+ bool complexWidget = childList.size() < childCount();
+
+ switch (relation) {
+ // Hierarchical
+ case Self:
+ targetObject = object();
+ break;
+ case Child:
+ if (complexWidget) {
+ if (entry > 0 && entry <= childCount())
+ return entry;
+ return -1;
+ }else {
+ if (entry > 0 && childList.size() >= entry)
+ targetObject = childList.at(entry - 1);
+ }
+ break;
+ case Ancestor:
+ {
+ if (entry <= 0)
+ return -1;
+ targetObject = widget()->parentWidget();
+ int i;
+ for (i = entry; i > 1 && targetObject; --i)
+ targetObject = targetObject->parent();
+ if (!targetObject && i == 1)
+ targetObject = qApp;
+ }
+ break;
+ case Sibling:
+ {
+ QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(parentObject());
+ if (!iface)
+ return -1;
+
+ iface->navigate(Child, entry, target);
+ delete iface;
+ if (*target)
+ return 0;
+ }
+ break;
+
+ // Geometrical
+ case QAccessible::Left:
+ if (complexWidget && entry) {
+ if (entry < 2 || widget()->height() > widget()->width() + 20) // looks vertical
+ return -1;
+ return entry - 1;
+ }
+ // fall through
+ case QAccessible::Right:
+ if (complexWidget && entry) {
+ if (entry >= childCount() || widget()->height() > widget()->width() + 20) // looks vertical
+ return -1;
+ return entry + 1;
+ }
+ // fall through
+ case QAccessible::Up:
+ if (complexWidget && entry) {
+ if (entry < 2 || widget()->width() > widget()->height() + 20) // looks horizontal
+ return - 1;
+ return entry - 1;
+ }
+ // fall through
+ case QAccessible::Down:
+ if (complexWidget && entry) {
+ if (entry >= childCount() || widget()->width() > widget()->height() + 20) // looks horizontal
+ return - 1;
+ return entry + 1;
+ } else {
+ QAccessibleInterface *pIface = QAccessible::queryAccessibleInterface(parentObject());
+ if (!pIface)
+ return -1;
+
+ QRect startg = rect(0);
+ QPoint startc = startg.center();
+ QAccessibleInterface *candidate = 0;
+ int mindist = 100000;
+ int sibCount = pIface->childCount();
+ for (int i = 0; i < sibCount; ++i) {
+ QAccessibleInterface *sibling = 0;
+ pIface->navigate(Child, i+1, &sibling);
+ Q_ASSERT(sibling);
+ if ((relationTo(0, sibling, 0) & Self) || (sibling->state(0) & QAccessible::Invisible)) {
+ //ignore ourself and invisible siblings
+ delete sibling;
+ continue;
+ }
+
+ QRect sibg = sibling->rect(0);
+ QPoint sibc = sibg.center();
+ QPoint sibp;
+ QPoint startp;
+ QPoint distp;
+ switch (relation) {
+ case QAccessible::Left:
+ startp = QPoint(startg.left(), startg.top() + startg.height() / 2);
+ sibp = QPoint(sibg.right(), sibg.top() + sibg.height() / 2);
+ if (QPoint(sibc - startc).x() >= 0) {
+ delete sibling;
+ continue;
+ }
+ distp = sibp - startp;
+ break;
+ case QAccessible::Right:
+ startp = QPoint(startg.right(), startg.top() + startg.height() / 2);
+ sibp = QPoint(sibg.left(), sibg.top() + sibg.height() / 2);
+ if (QPoint(sibc - startc).x() <= 0) {
+ delete sibling;
+ continue;
+ }
+ distp = sibp - startp;
+ break;
+ case QAccessible::Up:
+ startp = QPoint(startg.left() + startg.width() / 2, startg.top());
+ sibp = QPoint(sibg.left() + sibg.width() / 2, sibg.bottom());
+ if (QPoint(sibc - startc).y() >= 0) {
+ delete sibling;
+ continue;
+ }
+ distp = sibp - startp;
+ break;
+ case QAccessible::Down:
+ startp = QPoint(startg.left() + startg.width() / 2, startg.bottom());
+ sibp = QPoint(sibg.left() + sibg.width() / 2, sibg.top());
+ if (QPoint(sibc - startc).y() <= 0) {
+ delete sibling;
+ continue;
+ }
+ distp = sibp - startp;
+ break;
+ default:
+ break;
+ }
+
+ int dist = (int)qSqrt((qreal)distp.x() * distp.x() + distp.y() * distp.y());
+ if (dist < mindist) {
+ delete candidate;
+ candidate = sibling;
+ mindist = dist;
+ } else {
+ delete sibling;
+ }
+ }
+ delete pIface;
+ *target = candidate;
+ if (*target)
+ return 0;
+ }
+ break;
+ case Covers:
+ if (entry > 0) {
+ QAccessibleInterface *pIface = QAccessible::queryAccessibleInterface(parentObject());
+ if (!pIface)
+ return -1;
+
+ QRect r = rect(0);
+ int sibCount = pIface->childCount();
+ QAccessibleInterface *sibling = 0;
+ for (int i = pIface->indexOfChild(this) + 1; i <= sibCount && entry; ++i) {
+ pIface->navigate(Child, i, &sibling);
+ if (!sibling || (sibling->state(0) & Invisible)) {
+ delete sibling;
+ sibling = 0;
+ continue;
+ }
+ if (sibling->rect(0).intersects(r))
+ --entry;
+ if (!entry)
+ break;
+ delete sibling;
+ sibling = 0;
+ }
+ delete pIface;
+ *target = sibling;
+ if (*target)
+ return 0;
+ }
+ break;
+ case Covered:
+ if (entry > 0) {
+ QAccessibleInterface *pIface = QAccessible::queryAccessibleInterface(parentObject());
+ if (!pIface)
+ return -1;
+
+ QRect r = rect(0);
+ int index = pIface->indexOfChild(this);
+ QAccessibleInterface *sibling = 0;
+ for (int i = 1; i < index && entry; ++i) {
+ pIface->navigate(Child, i, &sibling);
+ Q_ASSERT(sibling);
+ if (!sibling || (sibling->state(0) & Invisible)) {
+ delete sibling;
+ sibling = 0;
+ continue;
+ }
+ if (sibling->rect(0).intersects(r))
+ --entry;
+ if (!entry)
+ break;
+ delete sibling;
+ sibling = 0;
+ }
+ delete pIface;
+ *target = sibling;
+ if (*target)
+ return 0;
+ }
+ break;
+
+ // Logical
+ case FocusChild:
+ {
+ if (widget()->hasFocus()) {
+ targetObject = object();
+ break;
+ }
+
+ QWidget *fw = widget()->focusWidget();
+ if (!fw)
+ return -1;
+
+ if (isAncestor(widget(), fw) || fw == widget())
+ targetObject = fw;
+ /* ###
+ QWidget *parent = fw;
+ while (parent && !targetObject) {
+ parent = parent->parentWidget();
+ if (parent == widget())
+ targetObject = fw;
+ }
+ */
+ }
+ break;
+ case Label:
+ if (entry > 0) {
+ QAccessibleInterface *pIface = QAccessible::queryAccessibleInterface(parentObject());
+ if (!pIface)
+ return -1;
+
+ // first check for all siblings that are labels to us
+ // ideally we would go through all objects and check, but that
+ // will be too expensive
+ int sibCount = pIface->childCount();
+ QAccessibleInterface *candidate = 0;
+ for (int i = 0; i < sibCount && entry; ++i) {
+ const int childId = pIface->navigate(Child, i+1, &candidate);
+ Q_ASSERT(childId >= 0);
+ if (childId > 0)
+ candidate = pIface;
+ if (candidate->relationTo(childId, this, 0) & Label)
+ --entry;
+ if (!entry)
+ break;
+ if (candidate != pIface)
+ delete candidate;
+ candidate = 0;
+ }
+ if (!candidate) {
+ if (pIface->relationTo(0, this, 0) & Label)
+ --entry;
+ if (!entry)
+ candidate = pIface;
+ }
+ if (pIface != candidate)
+ delete pIface;
+
+ *target = candidate;
+ if (*target)
+ return 0;
+ }
+ break;
+ case Labelled: // only implemented in subclasses
+ break;
+ case Controller:
+ if (entry > 0) {
+ // check all senders we are connected to,
+ // and figure out which one are controllers to us
+ QACConnectionObject *connectionObject = (QACConnectionObject*)object();
+ QObjectList allSenders = connectionObject->senderList();
+ QObjectList senders;
+ for (int s = 0; s < allSenders.size(); ++s) {
+ QObject *sender = allSenders.at(s);
+ QAccessibleInterface *candidate = QAccessible::queryAccessibleInterface(sender);
+ if (!candidate)
+ continue;
+ if (candidate->relationTo(0, this, 0)&Controller)
+ senders << sender;
+ delete candidate;
+ }
+ if (entry <= senders.size())
+ targetObject = senders.at(entry-1);
+ }
+ break;
+ case Controlled:
+ if (entry > 0) {
+ QObjectList allReceivers;
+ QACConnectionObject *connectionObject = (QACConnectionObject*)object();
+ for (int sig = 0; sig < d->primarySignals.count(); ++sig) {
+ QObjectList receivers = connectionObject->receiverList(d->primarySignals.at(sig).toAscii());
+ allReceivers += receivers;
+ }
+ if (entry <= allReceivers.size())
+ targetObject = allReceivers.at(entry-1);
+ }
+ break;
+ default:
+ break;
+ }
+
+ *target = QAccessible::queryAccessibleInterface(targetObject);
+ return *target ? 0 : -1;
+}
+
+/*! \reimp */
+int QAccessibleWidget::childCount() const
+{
+ QWidgetList cl = childWidgets(widget());
+ return cl.size();
+}
+
+/*! \reimp */
+int QAccessibleWidget::indexOfChild(const QAccessibleInterface *child) const
+{
+ QWidgetList cl = childWidgets(widget());
+ int index = cl.indexOf(qobject_cast<QWidget *>(child->object()));
+ if (index != -1)
+ ++index;
+ return index;
+}
+
+// from qwidget.cpp
+extern QString qt_setWindowTitle_helperHelper(const QString &, const QWidget*);
+
+/*! \reimp */
+QString QAccessibleWidget::text(Text t, int child) const
+{
+ QString str;
+
+ switch (t) {
+ case Name:
+ if (!d->name.isEmpty()) {
+ str = d->name;
+ } else if (!widget()->accessibleName().isEmpty()) {
+ str = widget()->accessibleName();
+ } else if (!child && widget()->isWindow()) {
+ if (widget()->isMinimized())
+ str = qt_setWindowTitle_helperHelper(widget()->windowIconText(), widget());
+ else
+ str = qt_setWindowTitle_helperHelper(widget()->windowTitle(), widget());
+ } else {
+ str = qt_accStripAmp(buddyString(widget()));
+ }
+ break;
+ case Description:
+ if (!d->description.isEmpty())
+ str = d->description;
+ else if (!widget()->accessibleDescription().isEmpty())
+ str = widget()->accessibleDescription();
+#ifndef QT_NO_TOOLTIP
+ else
+ str = widget()->toolTip();
+#endif
+ break;
+ case Help:
+ if (!d->help.isEmpty())
+ str = d->help;
+#ifndef QT_NO_WHATSTHIS
+ else
+ str = widget()->whatsThis();
+#endif
+ break;
+ case Accelerator:
+ if (!d->accelerator.isEmpty())
+ str = d->accelerator;
+ else
+ str = qt_accHotKey(buddyString(widget()));
+ break;
+ case Value:
+ str = d->value;
+ break;
+ default:
+ break;
+ }
+ return str;
+}
+
+#ifndef QT_NO_ACTION
+
+/*! \reimp */
+int QAccessibleWidget::userActionCount(int child) const
+{
+ if (child)
+ return 0;
+ return widget()->actions().count();
+}
+
+/*! \reimp */
+QString QAccessibleWidget::actionText(int action, Text t, int child) const
+{
+ if (action == DefaultAction)
+ action = SetFocus;
+
+ if (action > 0 && !child) {
+ QAction *act = widget()->actions().value(action - 1);
+ if (act) {
+ switch (t) {
+ case Name:
+ return act->text();
+ case Description:
+ return act->toolTip();
+#ifndef QT_NO_SHORTCUT
+ case Accelerator:
+ return act->shortcut().toString();
+#endif
+ default:
+ break;
+ }
+ }
+ }
+
+ return QAccessibleObject::actionText(action, t, child);
+}
+
+/*! \reimp */
+bool QAccessibleWidget::doAction(int action, int child, const QVariantList &params)
+{
+ if (action == SetFocus || action == DefaultAction) {
+ if (child || !widget()->isEnabled())
+ return false;
+ if (widget()->focusPolicy() != Qt::NoFocus)
+ widget()->setFocus();
+ else if (widget()->isWindow())
+ widget()->activateWindow();
+ else
+ return false;
+ return true;
+ } else if (action > 0) {
+ if (QAction *act = widget()->actions().value(action - 1)) {
+ act->trigger();
+ return true;
+ }
+ }
+ return QAccessibleObject::doAction(action, child, params);
+}
+
+#endif // QT_NO_ACTION
+
+/*! \reimp */
+QAccessible::Role QAccessibleWidget::role(int child) const
+{
+ if (!child)
+ return d->role;
+
+ QWidgetList childList = childWidgets(widget());
+ if (childList.count() > 0 && child <= childList.count()) {
+ QWidget *targetWidget = childList.at(child - 1);
+ QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(targetWidget);
+ if (iface) {
+ QAccessible::Role role = iface->role(0);
+ delete iface;
+ return role;
+ }
+ }
+
+ return NoRole;
+}
+
+/*! \reimp */
+QAccessible::State QAccessibleWidget::state(int child) const
+{
+ if (child)
+ return Normal;
+
+ QAccessible::State state = Normal;
+
+ QWidget *w = widget();
+ if (w->testAttribute(Qt::WA_WState_Visible) == false)
+ state |= Invisible;
+ if (w->focusPolicy() != Qt::NoFocus && w->isActiveWindow())
+ state |= Focusable;
+ if (w->hasFocus())
+ state |= Focused;
+ if (!w->isEnabled())
+ state |= Unavailable;
+ if (w->isWindow()) {
+ if (w->windowFlags() & Qt::WindowSystemMenuHint)
+ state |= Movable;
+ if (w->minimumSize() != w->maximumSize())
+ state |= Sizeable;
+ }
+
+ return state;
+}
+
+// ### Qt 5: remove me - binary compatibility hack
+QAccessibleWidgetEx::QAccessibleWidgetEx(QWidget *o, Role role, const QString& name)
+ : QAccessibleObjectEx(o)
+{
+ Q_ASSERT(widget());
+ d = new QAccessibleWidgetPrivate();
+ d->role = role;
+ d->name = name;
+ d->asking = 0;
+}
+
+int QAccessibleWidgetEx::childCount() const
+{ return reinterpret_cast<const QAccessibleWidget *>(this)->QAccessibleWidget::childCount(); }
+int QAccessibleWidgetEx::indexOfChild(const QAccessibleInterface *child) const
+{ return reinterpret_cast<const QAccessibleWidget *>(this)->QAccessibleWidget::indexOfChild(child); }
+QAccessible::Relation QAccessibleWidgetEx::relationTo(int child, const QAccessibleInterface *other, int otherChild) const
+{ return reinterpret_cast<const QAccessibleWidget *>(this)->QAccessibleWidget::relationTo(child, other, otherChild); }
+
+int QAccessibleWidgetEx::childAt(int x, int y) const
+{ return reinterpret_cast<const QAccessibleWidget *>(this)->QAccessibleWidget::childAt(x, y); }
+QRect QAccessibleWidgetEx::rect(int child) const
+{ return reinterpret_cast<const QAccessibleWidget *>(this)->QAccessibleWidget::rect(child); }
+int QAccessibleWidgetEx::navigate(RelationFlag rel, int entry, QAccessibleInterface **target) const
+{ return reinterpret_cast<const QAccessibleWidget *>(this)->QAccessibleWidget::navigate(rel, entry, target); }
+
+QString QAccessibleWidgetEx::text(Text t, int child) const
+{ return reinterpret_cast<const QAccessibleWidget *>(this)->QAccessibleWidget::text(t, child); }
+QAccessible::Role QAccessibleWidgetEx::role(int child) const
+{ return reinterpret_cast<const QAccessibleWidget *>(this)->QAccessibleWidget::role(child); }
+QAccessible::State QAccessibleWidgetEx::state(int child) const
+{ return (reinterpret_cast<const QAccessibleWidget *>(this)->QAccessibleWidget::state(child))
+ | HasInvokeExtension; }
+
+QString QAccessibleWidgetEx::actionText(int action, Text t, int child) const
+{ return reinterpret_cast<const QAccessibleWidget *>(this)->QAccessibleWidget::actionText(action, t, child); }
+bool QAccessibleWidgetEx::doAction(int action, int child, const QVariantList &params)
+{ return reinterpret_cast<QAccessibleWidget *>(this)->QAccessibleWidget::doAction(action, child, params); }
+
+QAccessibleWidgetEx::~QAccessibleWidgetEx()
+{ delete d; }
+QWidget *QAccessibleWidgetEx::widget() const
+{ return reinterpret_cast<const QAccessibleWidget *>(this)->QAccessibleWidget::widget(); }
+QObject *QAccessibleWidgetEx::parentObject() const
+{ return reinterpret_cast<const QAccessibleWidget *>(this)->QAccessibleWidget::parentObject(); }
+
+void QAccessibleWidgetEx::addControllingSignal(const QString &signal)
+{ reinterpret_cast<QAccessibleWidget *>(this)->QAccessibleWidget::addControllingSignal(signal); }
+void QAccessibleWidgetEx::setValue(const QString &value)
+{ reinterpret_cast<QAccessibleWidget *>(this)->QAccessibleWidget::setValue(value); }
+void QAccessibleWidgetEx::setDescription(const QString &desc)
+{ reinterpret_cast<QAccessibleWidget *>(this)->QAccessibleWidget::setDescription(desc); }
+void QAccessibleWidgetEx::setHelp(const QString &help)
+{ reinterpret_cast<QAccessibleWidget *>(this)->QAccessibleWidget::setHelp(help); }
+void QAccessibleWidgetEx::setAccelerator(const QString &accel)
+{ reinterpret_cast<QAccessibleWidget *>(this)->QAccessibleWidget::setAccelerator(accel); }
+
+QVariant QAccessibleWidgetEx::invokeMethodEx(Method method, int child, const QVariantList & /*params*/)
+{
+ if (child)
+ return QVariant();
+
+ switch (method) {
+ case ListSupportedMethods: {
+ QSet<QAccessible::Method> set;
+ set << ListSupportedMethods << ForegroundColor << BackgroundColor;
+ return QVariant::fromValue(set);
+ }
+ case ForegroundColor:
+ return widget()->palette().color(widget()->foregroundRole());
+ case BackgroundColor:
+ return widget()->palette().color(widget()->backgroundRole());
+ default:
+ return QVariant();
+ }
+}
+
+QT_END_NAMESPACE
+
+#endif //QT_NO_ACCESSIBILITY
diff --git a/src/widgets/accessible/qaccessiblewidget.h b/src/widgets/accessible/qaccessiblewidget.h
new file mode 100644
index 0000000000..3b68e30a63
--- /dev/null
+++ b/src/widgets/accessible/qaccessiblewidget.h
@@ -0,0 +1,141 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QACCESSIBLEWIDGET_H
+#define QACCESSIBLEWIDGET_H
+
+#include <QtWidgets/qaccessibleobject.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_ACCESSIBILITY
+
+class QAccessibleWidgetPrivate;
+
+class Q_WIDGETS_EXPORT QAccessibleWidget : public QAccessibleObject
+{
+public:
+ explicit QAccessibleWidget(QWidget *o, Role r = Client, const QString& name = QString());
+
+ int childCount() const;
+ int indexOfChild(const QAccessibleInterface *child) const;
+ Relation relationTo(int child, const QAccessibleInterface *other, int otherChild) const;
+
+ int childAt(int x, int y) const;
+ QRect rect(int child) const;
+ int navigate(RelationFlag rel, int entry, QAccessibleInterface **target) const;
+
+ QString text(Text t, int child) const;
+ Role role(int child) const;
+ State state(int child) const;
+
+#ifndef QT_NO_ACTION
+ int userActionCount(int child) const;
+ QString actionText(int action, Text t, int child) const;
+ bool doAction(int action, int child, const QVariantList &params);
+#endif
+
+protected:
+ ~QAccessibleWidget();
+ QWidget *widget() const;
+ QObject *parentObject() const;
+
+ void addControllingSignal(const QString &signal);
+ void setValue(const QString &value);
+ void setDescription(const QString &desc);
+ void setHelp(const QString &help);
+ void setAccelerator(const QString &accel);
+
+private:
+ friend class QAccessibleWidgetEx;
+ QAccessibleWidgetPrivate *d;
+ Q_DISABLE_COPY(QAccessibleWidget)
+};
+
+class Q_WIDGETS_EXPORT QAccessibleWidgetEx : public QAccessibleObjectEx
+{
+public:
+ explicit QAccessibleWidgetEx(QWidget *o, Role r = Client, const QString& name = QString());
+
+ int childCount() const;
+ int indexOfChild(const QAccessibleInterface *child) const;
+ Relation relationTo(int child, const QAccessibleInterface *other, int otherChild) const;
+
+ int childAt(int x, int y) const;
+ QRect rect(int child) const;
+ int navigate(RelationFlag rel, int entry, QAccessibleInterface **target) const;
+
+ QString text(Text t, int child) const;
+ Role role(int child) const;
+ State state(int child) const;
+
+ QString actionText(int action, Text t, int child) const;
+ bool doAction(int action, int child, const QVariantList &params);
+
+ QVariant invokeMethodEx(Method method, int child, const QVariantList &params);
+
+protected:
+ ~QAccessibleWidgetEx();
+ QWidget *widget() const;
+ QObject *parentObject() const;
+
+ void addControllingSignal(const QString &signal);
+ void setValue(const QString &value);
+ void setDescription(const QString &desc);
+ void setHelp(const QString &help);
+ void setAccelerator(const QString &accel);
+
+private:
+ QAccessibleWidgetPrivate *d;
+ Q_DISABLE_COPY(QAccessibleWidgetEx)
+};
+
+#endif // QT_NO_ACCESSIBILITY
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QACCESSIBLEWIDGET_H
diff --git a/src/gui/animation/animation.pri b/src/widgets/animation/animation.pri
index 27763ca003..27763ca003 100644
--- a/src/gui/animation/animation.pri
+++ b/src/widgets/animation/animation.pri
diff --git a/src/gui/animation/qguivariantanimation.cpp b/src/widgets/animation/qguivariantanimation.cpp
index b0b18ed21b..b0b18ed21b 100644
--- a/src/gui/animation/qguivariantanimation.cpp
+++ b/src/widgets/animation/qguivariantanimation.cpp
diff --git a/src/widgets/dialogs/dialogs.pri b/src/widgets/dialogs/dialogs.pri
new file mode 100644
index 0000000000..41d81b8afc
--- /dev/null
+++ b/src/widgets/dialogs/dialogs.pri
@@ -0,0 +1,82 @@
+# Qt dialogs module
+
+HEADERS += \
+ dialogs/qcolordialog.h \
+ dialogs/qcolordialog_p.h \
+ dialogs/qfscompleter_p.h \
+ dialogs/qdialog.h \
+ dialogs/qdialog_p.h \
+ dialogs/qerrormessage.h \
+ dialogs/qfiledialog.h \
+ dialogs/qfiledialog_p.h \
+ dialogs/qfontdialog.h \
+ dialogs/qfontdialog_p.h \
+ dialogs/qinputdialog.h \
+ dialogs/qmessagebox.h \
+ dialogs/qprogressdialog.h \
+ dialogs/qsidebar_p.h \
+ dialogs/qfilesystemmodel.h \
+ dialogs/qfilesystemmodel_p.h \
+ dialogs/qfileinfogatherer_p.h \
+ dialogs/qwizard.h
+
+!qpa:mac {
+ OBJECTIVE_SOURCES += dialogs/qfiledialog_mac.mm \
+ dialogs/qfontdialog_mac.mm \
+ dialogs/qnspanelproxy_mac.mm
+
+# Compile qcolordialog_mac.mm with exception support, disregarding the -no-exceptions
+# configure option. (qcolordialog_mac needs to catch exceptions thrown by cocoa)
+ EXCEPTION_SOURCES = dialogs/qcolordialog_mac.mm
+ exceptions_compiler.commands = $$QMAKE_CXX -c
+ exceptions_compiler.commands += $(CXXFLAGS) $(INCPATH) ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT}
+ exceptions_compiler.commands += -fexceptions
+ exceptions_compiler.dependency_type = TYPE_C
+ exceptions_compiler.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_OBJ)}
+ exceptions_compiler.input = EXCEPTION_SOURCES
+ exceptions_compiler.variable_out = OBJECTS
+ exceptions_compiler.name = compiling[exceptopns] ${QMAKE_FILE_IN}
+ silent:exceptions_compiler.commands = @echo compiling[exceptopns] ${QMAKE_FILE_IN} && $$exceptions_compiler.commands
+ QMAKE_EXTRA_COMPILERS += exceptions_compiler
+}
+
+win32 {
+ qpa:DEFINES += QT_NO_PRINTDIALOG
+
+ HEADERS += dialogs/qwizard_win_p.h \
+ dialogs/qfiledialog_win_p.h
+ SOURCES += dialogs/qdialogsbinarycompat_win.cpp \
+ dialogs/qfiledialog_win.cpp \
+ dialogs/qwizard_win.cpp
+
+ !win32-borland:!wince*: LIBS += -lshell32 # the filedialog needs this library
+}
+
+wince*|symbian: FORMS += dialogs/qfiledialog_embedded.ui
+else: FORMS += dialogs/qfiledialog.ui
+
+INCLUDEPATH += $$PWD
+SOURCES += \
+ dialogs/qcolordialog.cpp \
+ dialogs/qdialog.cpp \
+ dialogs/qerrormessage.cpp \
+ dialogs/qfiledialog.cpp \
+ dialogs/qfontdialog.cpp \
+ dialogs/qinputdialog.cpp \
+ dialogs/qmessagebox.cpp \
+ dialogs/qprogressdialog.cpp \
+ dialogs/qsidebar.cpp \
+ dialogs/qfilesystemmodel.cpp \
+ dialogs/qfileinfogatherer.cpp \
+ dialogs/qwizard.cpp \
+
+symbian:contains(QT_CONFIG, s60) {
+ LIBS += -lCommonDialogs
+ SOURCES += dialogs/qfiledialog_symbian.cpp \
+ dialogs/qcolordialog_symbian.cpp
+}
+
+RESOURCES += dialogs/qmessagebox.qrc
+
+# Compensate for lack of platform defines in Symbian3
+symbian: DEFINES += SYMBIAN_VERSION_$$upper($$replace(SYMBIAN_VERSION,\\.,_))
diff --git a/src/gui/dialogs/images/qtlogo-64.png b/src/widgets/dialogs/images/qtlogo-64.png
index 4f68e162de..4f68e162de 100644
--- a/src/gui/dialogs/images/qtlogo-64.png
+++ b/src/widgets/dialogs/images/qtlogo-64.png
Binary files differ
diff --git a/src/widgets/dialogs/qcolordialog.cpp b/src/widgets/dialogs/qcolordialog.cpp
new file mode 100644
index 0000000000..b26e911899
--- /dev/null
+++ b/src/widgets/dialogs/qcolordialog.cpp
@@ -0,0 +1,2115 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcolordialog_p.h"
+
+#ifndef QT_NO_COLORDIALOG
+
+#include "qapplication.h"
+#include "qdesktopwidget.h"
+#include "qdrawutil.h"
+#include "qevent.h"
+#include "qimage.h"
+#include "qdrag.h"
+#include "qlabel.h"
+#include "qlayout.h"
+#include "qlineedit.h"
+#include "qmenu.h"
+#include "qpainter.h"
+#include "qpixmap.h"
+#include "qpushbutton.h"
+#include "qsettings.h"
+#include "qstyle.h"
+#include "qstyleoption.h"
+#include "qvalidator.h"
+#include "qmime.h"
+#include "qspinbox.h"
+#include "qdialogbuttonbox.h"
+#include "private/qguiplatformplugin_p.h"
+
+#ifdef Q_WS_S60
+#include "private/qt_s60_p.h"
+#endif
+
+#if defined(Q_WS_S60) || defined(Q_WS_MAEMO_5)
+# define QT_SMALL_COLORDIALOG
+#endif
+
+QT_BEGIN_NAMESPACE
+
+//////////// QWellArray BEGIN
+
+struct QWellArrayData;
+
+class QWellArray : public QWidget
+{
+ Q_OBJECT
+ Q_PROPERTY(int selectedColumn READ selectedColumn)
+ Q_PROPERTY(int selectedRow READ selectedRow)
+
+public:
+ QWellArray(int rows, int cols, QWidget* parent=0);
+ ~QWellArray() {}
+ QString cellContent(int row, int col) const;
+
+ int selectedColumn() const { return selCol; }
+ int selectedRow() const { return selRow; }
+
+ virtual void setCurrent(int row, int col);
+ virtual void setSelected(int row, int col);
+
+ QSize sizeHint() const;
+
+ virtual void setCellBrush(int row, int col, const QBrush &);
+ QBrush cellBrush(int row, int col);
+
+ inline int cellWidth() const
+ { return cellw; }
+
+ inline int cellHeight() const
+ { return cellh; }
+
+ inline int rowAt(int y) const
+ { return y / cellh; }
+
+ inline int columnAt(int x) const
+ { if (isRightToLeft()) return ncols - (x / cellw) - 1; return x / cellw; }
+
+ inline int rowY(int row) const
+ { return cellh * row; }
+
+ inline int columnX(int column) const
+ { if (isRightToLeft()) return cellw * (ncols - column - 1); return cellw * column; }
+
+ inline int numRows() const
+ { return nrows; }
+
+ inline int numCols() const
+ {return ncols; }
+
+ inline QRect cellRect() const
+ { return QRect(0, 0, cellw, cellh); }
+
+ inline QSize gridSize() const
+ { return QSize(ncols * cellw, nrows * cellh); }
+
+ QRect cellGeometry(int row, int column)
+ {
+ QRect r;
+ if (row >= 0 && row < nrows && column >= 0 && column < ncols)
+ r.setRect(columnX(column), rowY(row), cellw, cellh);
+ return r;
+ }
+
+ inline void updateCell(int row, int column) { update(cellGeometry(row, column)); }
+
+signals:
+ void selected(int row, int col);
+
+protected:
+ virtual void paintCell(QPainter *, int row, int col, const QRect&);
+ virtual void paintCellContents(QPainter *, int row, int col, const QRect&);
+
+ void mousePressEvent(QMouseEvent*);
+ void mouseReleaseEvent(QMouseEvent*);
+ void keyPressEvent(QKeyEvent*);
+ void focusInEvent(QFocusEvent*);
+ void focusOutEvent(QFocusEvent*);
+ void paintEvent(QPaintEvent *);
+
+private:
+ Q_DISABLE_COPY(QWellArray)
+
+ int nrows;
+ int ncols;
+ int cellw;
+ int cellh;
+ int curRow;
+ int curCol;
+ int selRow;
+ int selCol;
+ QWellArrayData *d;
+};
+
+void QWellArray::paintEvent(QPaintEvent *e)
+{
+ QRect r = e->rect();
+ int cx = r.x();
+ int cy = r.y();
+ int ch = r.height();
+ int cw = r.width();
+ int colfirst = columnAt(cx);
+ int collast = columnAt(cx + cw);
+ int rowfirst = rowAt(cy);
+ int rowlast = rowAt(cy + ch);
+
+ if (isRightToLeft()) {
+ int t = colfirst;
+ colfirst = collast;
+ collast = t;
+ }
+
+ QPainter painter(this);
+ QPainter *p = &painter;
+ QRect rect(0, 0, cellWidth(), cellHeight());
+
+
+ if (collast < 0 || collast >= ncols)
+ collast = ncols-1;
+ if (rowlast < 0 || rowlast >= nrows)
+ rowlast = nrows-1;
+
+ // Go through the rows
+ for (int r = rowfirst; r <= rowlast; ++r) {
+ // get row position and height
+ int rowp = rowY(r);
+
+ // Go through the columns in the row r
+ // if we know from where to where, go through [colfirst, collast],
+ // else go through all of them
+ for (int c = colfirst; c <= collast; ++c) {
+ // get position and width of column c
+ int colp = columnX(c);
+ // Translate painter and draw the cell
+ rect.translate(colp, rowp);
+ paintCell(p, r, c, rect);
+ rect.translate(-colp, -rowp);
+ }
+ }
+}
+
+struct QWellArrayData {
+ QBrush *brush;
+};
+
+QWellArray::QWellArray(int rows, int cols, QWidget *parent)
+ : QWidget(parent)
+ ,nrows(rows), ncols(cols)
+{
+ d = 0;
+ setFocusPolicy(Qt::StrongFocus);
+ cellw = 28;
+ cellh = 24;
+ curCol = 0;
+ curRow = 0;
+ selCol = -1;
+ selRow = -1;
+}
+
+QSize QWellArray::sizeHint() const
+{
+ ensurePolished();
+ return gridSize().boundedTo(QSize(640, 480));
+}
+
+
+void QWellArray::paintCell(QPainter* p, int row, int col, const QRect &rect)
+{
+ int b = 3; //margin
+
+ const QPalette & g = palette();
+ QStyleOptionFrame opt;
+ int dfw = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
+ opt.lineWidth = dfw;
+ opt.midLineWidth = 1;
+ opt.rect = rect.adjusted(b, b, -b, -b);
+ opt.palette = g;
+ opt.state = QStyle::State_Enabled | QStyle::State_Sunken;
+ style()->drawPrimitive(QStyle::PE_Frame, &opt, p, this);
+ b += dfw;
+
+ if ((row == curRow) && (col == curCol)) {
+ if (hasFocus()) {
+ QStyleOptionFocusRect opt;
+ opt.palette = g;
+ opt.rect = rect;
+ opt.state = QStyle::State_None | QStyle::State_KeyboardFocusChange;
+ style()->drawPrimitive(QStyle::PE_FrameFocusRect, &opt, p, this);
+ }
+ }
+ paintCellContents(p, row, col, opt.rect.adjusted(dfw, dfw, -dfw, -dfw));
+}
+
+/*!
+ Reimplement this function to change the contents of the well array.
+ */
+void QWellArray::paintCellContents(QPainter *p, int row, int col, const QRect &r)
+{
+ if (d) {
+ p->fillRect(r, d->brush[row*numCols()+col]);
+ } else {
+ p->fillRect(r, Qt::white);
+ p->setPen(Qt::black);
+ p->drawLine(r.topLeft(), r.bottomRight());
+ p->drawLine(r.topRight(), r.bottomLeft());
+ }
+}
+
+void QWellArray::mousePressEvent(QMouseEvent *e)
+{
+ // The current cell marker is set to the cell the mouse is pressed in
+ QPoint pos = e->pos();
+ setCurrent(rowAt(pos.y()), columnAt(pos.x()));
+}
+
+void QWellArray::mouseReleaseEvent(QMouseEvent * /* event */)
+{
+ // The current cell marker is set to the cell the mouse is clicked in
+ setSelected(curRow, curCol);
+}
+
+
+/*
+ Sets the cell currently having the focus. This is not necessarily
+ the same as the currently selected cell.
+*/
+
+void QWellArray::setCurrent(int row, int col)
+{
+ if ((curRow == row) && (curCol == col))
+ return;
+
+ if (row < 0 || col < 0)
+ row = col = -1;
+
+ int oldRow = curRow;
+ int oldCol = curCol;
+
+ curRow = row;
+ curCol = col;
+
+ updateCell(oldRow, oldCol);
+ updateCell(curRow, curCol);
+}
+
+/*
+ Sets the currently selected cell to \a row, \a column. If \a row or
+ \a column are less than zero, the current cell is unselected.
+
+ Does not set the position of the focus indicator.
+*/
+void QWellArray::setSelected(int row, int col)
+{
+ int oldRow = selRow;
+ int oldCol = selCol;
+
+ if (row < 0 || col < 0)
+ row = col = -1;
+
+ selCol = col;
+ selRow = row;
+
+ updateCell(oldRow, oldCol);
+ updateCell(selRow, selCol);
+ if (row >= 0)
+ emit selected(row, col);
+
+#ifndef QT_NO_MENU
+ if (isVisible() && qobject_cast<QMenu*>(parentWidget()))
+ parentWidget()->close();
+#endif
+}
+
+void QWellArray::focusInEvent(QFocusEvent*)
+{
+ updateCell(curRow, curCol);
+}
+
+void QWellArray::setCellBrush(int row, int col, const QBrush &b)
+{
+ if (!d) {
+ d = new QWellArrayData;
+ int i = numRows()*numCols();
+ d->brush = new QBrush[i];
+ }
+ if (row >= 0 && row < numRows() && col >= 0 && col < numCols())
+ d->brush[row*numCols()+col] = b;
+}
+
+/*
+ Returns the brush set for the cell at \a row, \a column. If no brush is
+ set, Qt::NoBrush is returned.
+*/
+
+QBrush QWellArray::cellBrush(int row, int col)
+{
+ if (d && row >= 0 && row < numRows() && col >= 0 && col < numCols())
+ return d->brush[row*numCols()+col];
+ return Qt::NoBrush;
+}
+
+
+
+/*!\reimp
+*/
+
+void QWellArray::focusOutEvent(QFocusEvent*)
+{
+ updateCell(curRow, curCol);
+}
+
+/*\reimp
+*/
+void QWellArray::keyPressEvent(QKeyEvent* e)
+{
+ switch(e->key()) { // Look at the key code
+ case Qt::Key_Left: // If 'left arrow'-key,
+ if(curCol > 0) // and cr't not in leftmost col
+ setCurrent(curRow, curCol - 1); // set cr't to next left column
+ break;
+ case Qt::Key_Right: // Correspondingly...
+ if(curCol < numCols()-1)
+ setCurrent(curRow, curCol + 1);
+ break;
+ case Qt::Key_Up:
+ if(curRow > 0)
+ setCurrent(curRow - 1, curCol);
+ break;
+ case Qt::Key_Down:
+ if(curRow < numRows()-1)
+ setCurrent(curRow + 1, curCol);
+ break;
+#if 0
+ // bad idea that shouldn't have been implemented; very counterintuitive
+ case Qt::Key_Return:
+ case Qt::Key_Enter:
+ /*
+ ignore the key, so that the dialog get it, but still select
+ the current row/col
+ */
+ e->ignore();
+ // fallthrough intended
+#endif
+ case Qt::Key_Space:
+ setSelected(curRow, curCol);
+ break;
+ default: // If not an interesting key,
+ e->ignore(); // we don't accept the event
+ return;
+ }
+
+}
+
+//////////// QWellArray END
+
+static bool initrgb = false;
+static QRgb stdrgb[6*8];
+static QRgb cusrgb[2*8];
+static bool customSet = false;
+
+
+static void initRGB()
+{
+ if (initrgb)
+ return;
+ initrgb = true;
+ int i = 0;
+ for (int g = 0; g < 4; g++)
+ for (int r = 0; r < 4; r++)
+ for (int b = 0; b < 3; b++)
+ stdrgb[i++] = qRgb(r * 255 / 3, g * 255 / 3, b * 255 / 2);
+
+ for (i = 0; i < 2*8; i++)
+ cusrgb[i] = 0xffffffff;
+}
+
+/*!
+ Returns the number of custom colors supported by QColorDialog. All
+ color dialogs share the same custom colors.
+*/
+int QColorDialog::customCount()
+{
+ return 2 * 8;
+}
+
+/*!
+ \since 4.5
+
+ Returns the custom color at the given \a index as a QRgb value.
+*/
+QRgb QColorDialog::customColor(int index)
+{
+ if (uint(index) >= uint(customCount()))
+ return qRgb(255, 255, 255);
+ initRGB();
+ return cusrgb[index];
+}
+
+/*!
+ Sets the custom color at \a index to the QRgb \a color value.
+
+ \note This function does not apply to the Native Color Dialog on the Mac
+ OS X platform. If you still require this function, use the
+ QColorDialog::DontUseNativeDialog option.
+*/
+void QColorDialog::setCustomColor(int index, QRgb color)
+{
+ if (uint(index) >= uint(customCount()))
+ return;
+ initRGB();
+ customSet = true;
+ cusrgb[index] = color;
+}
+
+/*!
+ Sets the standard color at \a index to the QRgb \a color value.
+
+ \note This function does not apply to the Native Color Dialog on the Mac
+ OS X platform. If you still require this function, use the
+ QColorDialog::DontUseNativeDialog option.
+*/
+
+void QColorDialog::setStandardColor(int index, QRgb color)
+{
+ if (uint(index) >= uint(6 * 8))
+ return;
+ initRGB();
+ stdrgb[index] = color;
+}
+
+static inline void rgb2hsv(QRgb rgb, int &h, int &s, int &v)
+{
+ QColor c;
+ c.setRgb(rgb);
+ c.getHsv(&h, &s, &v);
+}
+
+class QColorWell : public QWellArray
+{
+public:
+ QColorWell(QWidget *parent, int r, int c, QRgb *vals)
+ :QWellArray(r, c, parent), values(vals), mousePressed(false), oldCurrent(-1, -1)
+ { setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum)); }
+
+protected:
+ void paintCellContents(QPainter *, int row, int col, const QRect&);
+ void mousePressEvent(QMouseEvent *e);
+ void mouseMoveEvent(QMouseEvent *e);
+ void mouseReleaseEvent(QMouseEvent *e);
+#ifndef QT_NO_DRAGANDDROP
+ void dragEnterEvent(QDragEnterEvent *e);
+ void dragLeaveEvent(QDragLeaveEvent *e);
+ void dragMoveEvent(QDragMoveEvent *e);
+ void dropEvent(QDropEvent *e);
+#endif
+
+private:
+ QRgb *values;
+ bool mousePressed;
+ QPoint pressPos;
+ QPoint oldCurrent;
+
+};
+
+void QColorWell::paintCellContents(QPainter *p, int row, int col, const QRect &r)
+{
+ int i = row + col*numRows();
+ p->fillRect(r, QColor(values[i]));
+}
+
+void QColorWell::mousePressEvent(QMouseEvent *e)
+{
+ oldCurrent = QPoint(selectedRow(), selectedColumn());
+ QWellArray::mousePressEvent(e);
+ mousePressed = true;
+ pressPos = e->pos();
+}
+
+void QColorWell::mouseMoveEvent(QMouseEvent *e)
+{
+ QWellArray::mouseMoveEvent(e);
+#ifndef QT_NO_DRAGANDDROP
+ if (!mousePressed)
+ return;
+ if ((pressPos - e->pos()).manhattanLength() > QApplication::startDragDistance()) {
+ setCurrent(oldCurrent.x(), oldCurrent.y());
+ int i = rowAt(pressPos.y()) + columnAt(pressPos.x()) * numRows();
+ QColor col(values[i]);
+ QMimeData *mime = new QMimeData;
+ mime->setColorData(col);
+ QPixmap pix(cellWidth(), cellHeight());
+ pix.fill(col);
+ QPainter p(&pix);
+ p.drawRect(0, 0, pix.width() - 1, pix.height() - 1);
+ p.end();
+ QDrag *drg = new QDrag(this);
+ drg->setMimeData(mime);
+ drg->setPixmap(pix);
+ mousePressed = false;
+ drg->start();
+ }
+#endif
+}
+
+#ifndef QT_NO_DRAGANDDROP
+void QColorWell::dragEnterEvent(QDragEnterEvent *e)
+{
+ if (qvariant_cast<QColor>(e->mimeData()->colorData()).isValid())
+ e->accept();
+ else
+ e->ignore();
+}
+
+void QColorWell::dragLeaveEvent(QDragLeaveEvent *)
+{
+ if (hasFocus())
+ parentWidget()->setFocus();
+}
+
+void QColorWell::dragMoveEvent(QDragMoveEvent *e)
+{
+ if (qvariant_cast<QColor>(e->mimeData()->colorData()).isValid()) {
+ setCurrent(rowAt(e->pos().y()), columnAt(e->pos().x()));
+ e->accept();
+ } else {
+ e->ignore();
+ }
+}
+
+void QColorWell::dropEvent(QDropEvent *e)
+{
+ QColor col = qvariant_cast<QColor>(e->mimeData()->colorData());
+ if (col.isValid()) {
+ int i = rowAt(e->pos().y()) + columnAt(e->pos().x()) * numRows();
+ values[i] = col.rgb();
+ update();
+ e->accept();
+ } else {
+ e->ignore();
+ }
+}
+
+#endif // QT_NO_DRAGANDDROP
+
+void QColorWell::mouseReleaseEvent(QMouseEvent *e)
+{
+ if (!mousePressed)
+ return;
+ QWellArray::mouseReleaseEvent(e);
+ mousePressed = false;
+}
+
+class QColorPicker : public QFrame
+{
+ Q_OBJECT
+public:
+ QColorPicker(QWidget* parent);
+ ~QColorPicker();
+
+public slots:
+ void setCol(int h, int s);
+
+signals:
+ void newCol(int h, int s);
+
+protected:
+ QSize sizeHint() const;
+ void paintEvent(QPaintEvent*);
+ void mouseMoveEvent(QMouseEvent *);
+ void mousePressEvent(QMouseEvent *);
+ void resizeEvent(QResizeEvent *);
+
+private:
+ int hue;
+ int sat;
+
+ QPoint colPt();
+ int huePt(const QPoint &pt);
+ int satPt(const QPoint &pt);
+ void setCol(const QPoint &pt);
+
+ QPixmap pix;
+};
+
+static int pWidth = 220;
+static int pHeight = 200;
+
+class QColorLuminancePicker : public QWidget
+{
+ Q_OBJECT
+public:
+ QColorLuminancePicker(QWidget* parent=0);
+ ~QColorLuminancePicker();
+
+public slots:
+ void setCol(int h, int s, int v);
+ void setCol(int h, int s);
+
+signals:
+ void newHsv(int h, int s, int v);
+
+protected:
+ void paintEvent(QPaintEvent*);
+ void mouseMoveEvent(QMouseEvent *);
+ void mousePressEvent(QMouseEvent *);
+
+private:
+ enum { foff = 3, coff = 4 }; //frame and contents offset
+ int val;
+ int hue;
+ int sat;
+
+ int y2val(int y);
+ int val2y(int val);
+ void setVal(int v);
+
+ QPixmap *pix;
+};
+
+
+int QColorLuminancePicker::y2val(int y)
+{
+ int d = height() - 2*coff - 1;
+ return 255 - (y - coff)*255/d;
+}
+
+int QColorLuminancePicker::val2y(int v)
+{
+ int d = height() - 2*coff - 1;
+ return coff + (255-v)*d/255;
+}
+
+QColorLuminancePicker::QColorLuminancePicker(QWidget* parent)
+ :QWidget(parent)
+{
+ hue = 100; val = 100; sat = 100;
+ pix = 0;
+ // setAttribute(WA_NoErase, true);
+}
+
+QColorLuminancePicker::~QColorLuminancePicker()
+{
+ delete pix;
+}
+
+void QColorLuminancePicker::mouseMoveEvent(QMouseEvent *m)
+{
+ setVal(y2val(m->y()));
+}
+void QColorLuminancePicker::mousePressEvent(QMouseEvent *m)
+{
+ setVal(y2val(m->y()));
+}
+
+void QColorLuminancePicker::setVal(int v)
+{
+ if (val == v)
+ return;
+ val = qMax(0, qMin(v,255));
+ delete pix; pix=0;
+ repaint();
+ emit newHsv(hue, sat, val);
+}
+
+//receives from a hue,sat chooser and relays.
+void QColorLuminancePicker::setCol(int h, int s)
+{
+ setCol(h, s, val);
+ emit newHsv(h, s, val);
+}
+
+void QColorLuminancePicker::paintEvent(QPaintEvent *)
+{
+ int w = width() - 5;
+
+ QRect r(0, foff, w, height() - 2*foff);
+ int wi = r.width() - 2;
+ int hi = r.height() - 2;
+ if (!pix || pix->height() != hi || pix->width() != wi) {
+ delete pix;
+ QImage img(wi, hi, QImage::Format_RGB32);
+ int y;
+ uint *pixel = (uint *) img.scanLine(0);
+ for (y = 0; y < hi; y++) {
+ const uint *end = pixel + wi;
+ while (pixel < end) {
+ QColor c;
+ c.setHsv(hue, sat, y2val(y+coff));
+ *pixel = c.rgb();
+ ++pixel;
+ }
+ }
+ pix = new QPixmap(QPixmap::fromImage(img));
+ }
+ QPainter p(this);
+ p.drawPixmap(1, coff, *pix);
+ const QPalette &g = palette();
+ qDrawShadePanel(&p, r, g, true);
+ p.setPen(g.foreground().color());
+ p.setBrush(g.foreground());
+ QPolygon a;
+ int y = val2y(val);
+ a.setPoints(3, w, y, w+5, y+5, w+5, y-5);
+ p.eraseRect(w, 0, 5, height());
+ p.drawPolygon(a);
+}
+
+void QColorLuminancePicker::setCol(int h, int s , int v)
+{
+ val = v;
+ hue = h;
+ sat = s;
+ delete pix; pix=0;
+ repaint();
+}
+
+QPoint QColorPicker::colPt()
+{
+ QRect r = contentsRect();
+ return QPoint((360 - hue) * (r.width() - 1) / 360, (255 - sat) * (r.height() - 1) / 255);
+}
+
+int QColorPicker::huePt(const QPoint &pt)
+{
+ QRect r = contentsRect();
+ return 360 - pt.x() * 360 / (r.width() - 1);
+}
+
+int QColorPicker::satPt(const QPoint &pt)
+{
+ QRect r = contentsRect();
+ return 255 - pt.y() * 255 / (r.height() - 1);
+}
+
+void QColorPicker::setCol(const QPoint &pt)
+{
+ setCol(huePt(pt), satPt(pt));
+}
+
+QColorPicker::QColorPicker(QWidget* parent)
+ : QFrame(parent)
+{
+ hue = 0; sat = 0;
+ setCol(150, 255);
+
+ setAttribute(Qt::WA_NoSystemBackground);
+ setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed) );
+}
+
+QColorPicker::~QColorPicker()
+{
+}
+
+QSize QColorPicker::sizeHint() const
+{
+ return QSize(pWidth + 2*frameWidth(), pHeight + 2*frameWidth());
+}
+
+void QColorPicker::setCol(int h, int s)
+{
+ int nhue = qMin(qMax(0,h), 359);
+ int nsat = qMin(qMax(0,s), 255);
+ if (nhue == hue && nsat == sat)
+ return;
+
+ QRect r(colPt(), QSize(20,20));
+ hue = nhue; sat = nsat;
+ r = r.united(QRect(colPt(), QSize(20,20)));
+ r.translate(contentsRect().x()-9, contentsRect().y()-9);
+ // update(r);
+ repaint(r);
+}
+
+void QColorPicker::mouseMoveEvent(QMouseEvent *m)
+{
+ QPoint p = m->pos() - contentsRect().topLeft();
+ setCol(p);
+ emit newCol(hue, sat);
+}
+
+void QColorPicker::mousePressEvent(QMouseEvent *m)
+{
+ QPoint p = m->pos() - contentsRect().topLeft();
+ setCol(p);
+ emit newCol(hue, sat);
+}
+
+void QColorPicker::paintEvent(QPaintEvent* )
+{
+ QPainter p(this);
+ drawFrame(&p);
+ QRect r = contentsRect();
+
+ p.drawPixmap(r.topLeft(), pix);
+ QPoint pt = colPt() + r.topLeft();
+ p.setPen(Qt::black);
+
+ p.fillRect(pt.x()-9, pt.y(), 20, 2, Qt::black);
+ p.fillRect(pt.x(), pt.y()-9, 2, 20, Qt::black);
+
+}
+
+void QColorPicker::resizeEvent(QResizeEvent *ev)
+{
+ QFrame::resizeEvent(ev);
+
+ int w = width() - frameWidth() * 2;
+ int h = height() - frameWidth() * 2;
+ QImage img(w, h, QImage::Format_RGB32);
+ int x, y;
+ uint *pixel = (uint *) img.scanLine(0);
+ for (y = 0; y < h; y++) {
+ const uint *end = pixel + w;
+ x = 0;
+ while (pixel < end) {
+ QPoint p(x, y);
+ QColor c;
+ c.setHsv(huePt(p), satPt(p), 200);
+ *pixel = c.rgb();
+ ++pixel;
+ ++x;
+ }
+ }
+ pix = QPixmap::fromImage(img);
+}
+
+
+class QColSpinBox : public QSpinBox
+{
+public:
+ QColSpinBox(QWidget *parent)
+ : QSpinBox(parent) { setRange(0, 255); }
+ void setValue(int i) {
+ bool block = signalsBlocked();
+ blockSignals(true);
+ QSpinBox::setValue(i);
+ blockSignals(block);
+ }
+};
+
+class QColorShowLabel;
+
+class QColorShower : public QWidget
+{
+ Q_OBJECT
+public:
+ QColorShower(QColorDialog *parent);
+
+ //things that don't emit signals
+ void setHsv(int h, int s, int v);
+
+ int currentAlpha() const
+ { return (colorDialog->options() & QColorDialog::ShowAlphaChannel) ? alphaEd->value() : 255; }
+ void setCurrentAlpha(int a) { alphaEd->setValue(a); rgbEd(); }
+ void showAlpha(bool b);
+ bool isAlphaVisible() const;
+
+ QRgb currentColor() const { return curCol; }
+ QColor currentQColor() const { return curQColor; }
+ void retranslateStrings();
+ void updateQColor();
+
+public slots:
+ void setRgb(QRgb rgb);
+
+signals:
+ void newCol(QRgb rgb);
+ void currentColorChanged(const QColor &color);
+
+private slots:
+ void rgbEd();
+ void hsvEd();
+private:
+ void showCurrentColor();
+ int hue, sat, val;
+ QRgb curCol;
+ QColor curQColor;
+ QLabel *lblHue;
+ QLabel *lblSat;
+ QLabel *lblVal;
+ QLabel *lblRed;
+ QLabel *lblGreen;
+ QLabel *lblBlue;
+ QColSpinBox *hEd;
+ QColSpinBox *sEd;
+ QColSpinBox *vEd;
+ QColSpinBox *rEd;
+ QColSpinBox *gEd;
+ QColSpinBox *bEd;
+ QColSpinBox *alphaEd;
+ QLabel *alphaLab;
+ QColorShowLabel *lab;
+ bool rgbOriginal;
+ QColorDialog *colorDialog;
+
+ friend class QColorDialog;
+ friend class QColorDialogPrivate;
+};
+
+class QColorShowLabel : public QFrame
+{
+ Q_OBJECT
+
+public:
+ QColorShowLabel(QWidget *parent) : QFrame(parent) {
+ setFrameStyle(QFrame::Panel|QFrame::Sunken);
+ setAcceptDrops(true);
+ mousePressed = false;
+ }
+ void setColor(QColor c) { col = c; }
+
+signals:
+ void colorDropped(QRgb);
+
+protected:
+ void paintEvent(QPaintEvent *);
+ void mousePressEvent(QMouseEvent *e);
+ void mouseMoveEvent(QMouseEvent *e);
+ void mouseReleaseEvent(QMouseEvent *e);
+#ifndef QT_NO_DRAGANDDROP
+ void dragEnterEvent(QDragEnterEvent *e);
+ void dragLeaveEvent(QDragLeaveEvent *e);
+ void dropEvent(QDropEvent *e);
+#endif
+
+private:
+ QColor col;
+ bool mousePressed;
+ QPoint pressPos;
+};
+
+void QColorShowLabel::paintEvent(QPaintEvent *e)
+{
+ QPainter p(this);
+ drawFrame(&p);
+ p.fillRect(contentsRect()&e->rect(), col);
+}
+
+void QColorShower::showAlpha(bool b)
+{
+ alphaLab->setVisible(b);
+ alphaEd->setVisible(b);
+}
+
+inline bool QColorShower::isAlphaVisible() const
+{
+ return alphaLab->isVisible();
+}
+
+void QColorShowLabel::mousePressEvent(QMouseEvent *e)
+{
+ mousePressed = true;
+ pressPos = e->pos();
+}
+
+void QColorShowLabel::mouseMoveEvent(QMouseEvent *e)
+{
+#ifdef QT_NO_DRAGANDDROP
+ Q_UNUSED(e);
+#else
+ if (!mousePressed)
+ return;
+ if ((pressPos - e->pos()).manhattanLength() > QApplication::startDragDistance()) {
+ QMimeData *mime = new QMimeData;
+ mime->setColorData(col);
+ QPixmap pix(30, 20);
+ pix.fill(col);
+ QPainter p(&pix);
+ p.drawRect(0, 0, pix.width() - 1, pix.height() - 1);
+ p.end();
+ QDrag *drg = new QDrag(this);
+ drg->setMimeData(mime);
+ drg->setPixmap(pix);
+ mousePressed = false;
+ drg->start();
+ }
+#endif
+}
+
+#ifndef QT_NO_DRAGANDDROP
+void QColorShowLabel::dragEnterEvent(QDragEnterEvent *e)
+{
+ if (qvariant_cast<QColor>(e->mimeData()->colorData()).isValid())
+ e->accept();
+ else
+ e->ignore();
+}
+
+void QColorShowLabel::dragLeaveEvent(QDragLeaveEvent *)
+{
+}
+
+void QColorShowLabel::dropEvent(QDropEvent *e)
+{
+ QColor color = qvariant_cast<QColor>(e->mimeData()->colorData());
+ if (color.isValid()) {
+ col = color;
+ repaint();
+ emit colorDropped(col.rgb());
+ e->accept();
+ } else {
+ e->ignore();
+ }
+}
+#endif // QT_NO_DRAGANDDROP
+
+void QColorShowLabel::mouseReleaseEvent(QMouseEvent *)
+{
+ if (!mousePressed)
+ return;
+ mousePressed = false;
+}
+
+QColorShower::QColorShower(QColorDialog *parent)
+ : QWidget(parent)
+{
+ colorDialog = parent;
+
+ curCol = qRgb(255, 255, 255);
+ curQColor = Qt::white;
+
+ QGridLayout *gl = new QGridLayout(this);
+ gl->setMargin(gl->spacing());
+ lab = new QColorShowLabel(this);
+
+#ifdef QT_SMALL_COLORDIALOG
+# ifdef Q_WS_S60
+ const bool nonTouchUI = !S60->hasTouchscreen;
+# elif defined Q_WS_MAEMO_5
+ const bool nonTouchUI = false;
+# endif
+#endif
+
+#ifndef Q_WS_WINCE
+#ifdef QT_SMALL_COLORDIALOG
+ lab->setMinimumHeight(60);
+#endif
+ lab->setMinimumWidth(60);
+#else
+ lab->setMinimumWidth(20);
+#endif
+
+// In S60, due to small screen and different screen layouts need to re-arrange the widgets.
+// For QVGA screens only the comboboxes and color label are visible.
+// For nHD screens only color and luminence pickers and color label are visible.
+#if !defined(QT_SMALL_COLORDIALOG)
+ gl->addWidget(lab, 0, 0, -1, 1);
+#else
+ if (nonTouchUI)
+ gl->addWidget(lab, 0, 0, 1, -1);
+ else
+ gl->addWidget(lab, 0, 0, -1, 1);
+#endif
+ connect(lab, SIGNAL(colorDropped(QRgb)), this, SIGNAL(newCol(QRgb)));
+ connect(lab, SIGNAL(colorDropped(QRgb)), this, SLOT(setRgb(QRgb)));
+
+ hEd = new QColSpinBox(this);
+ hEd->setRange(0, 359);
+ lblHue = new QLabel(this);
+#ifndef QT_NO_SHORTCUT
+ lblHue->setBuddy(hEd);
+#endif
+ lblHue->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
+#if !defined(QT_SMALL_COLORDIALOG)
+ gl->addWidget(lblHue, 0, 1);
+ gl->addWidget(hEd, 0, 2);
+#else
+ if (nonTouchUI) {
+ gl->addWidget(lblHue, 1, 0);
+ gl->addWidget(hEd, 2, 0);
+ } else {
+ lblHue->hide();
+ hEd->hide();
+ }
+#endif
+
+ sEd = new QColSpinBox(this);
+ lblSat = new QLabel(this);
+#ifndef QT_NO_SHORTCUT
+ lblSat->setBuddy(sEd);
+#endif
+ lblSat->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
+#if !defined(QT_SMALL_COLORDIALOG)
+ gl->addWidget(lblSat, 1, 1);
+ gl->addWidget(sEd, 1, 2);
+#else
+ if (nonTouchUI) {
+ gl->addWidget(lblSat, 1, 1);
+ gl->addWidget(sEd, 2, 1);
+ } else {
+ lblSat->hide();
+ sEd->hide();
+ }
+#endif
+
+ vEd = new QColSpinBox(this);
+ lblVal = new QLabel(this);
+#ifndef QT_NO_SHORTCUT
+ lblVal->setBuddy(vEd);
+#endif
+ lblVal->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
+#if !defined(QT_SMALL_COLORDIALOG)
+ gl->addWidget(lblVal, 2, 1);
+ gl->addWidget(vEd, 2, 2);
+#else
+ if (nonTouchUI) {
+ gl->addWidget(lblVal, 1, 2);
+ gl->addWidget(vEd, 2, 2);
+ } else {
+ lblVal->hide();
+ vEd->hide();
+ }
+#endif
+
+ rEd = new QColSpinBox(this);
+ lblRed = new QLabel(this);
+#ifndef QT_NO_SHORTCUT
+ lblRed->setBuddy(rEd);
+#endif
+ lblRed->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
+#if !defined(QT_SMALL_COLORDIALOG)
+ gl->addWidget(lblRed, 0, 3);
+ gl->addWidget(rEd, 0, 4);
+#else
+ if (nonTouchUI) {
+ gl->addWidget(lblRed, 3, 0);
+ gl->addWidget(rEd, 4, 0);
+ } else {
+ lblRed->hide();
+ rEd->hide();
+ }
+#endif
+
+ gEd = new QColSpinBox(this);
+ lblGreen = new QLabel(this);
+#ifndef QT_NO_SHORTCUT
+ lblGreen->setBuddy(gEd);
+#endif
+ lblGreen->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
+#if !defined(QT_SMALL_COLORDIALOG)
+ gl->addWidget(lblGreen, 1, 3);
+ gl->addWidget(gEd, 1, 4);
+#else
+ if (nonTouchUI) {
+ gl->addWidget(lblGreen, 3, 1);
+ gl->addWidget(gEd, 4, 1);
+ } else {
+ lblGreen->hide();
+ gEd->hide();
+ }
+#endif
+
+ bEd = new QColSpinBox(this);
+ lblBlue = new QLabel(this);
+#ifndef QT_NO_SHORTCUT
+ lblBlue->setBuddy(bEd);
+#endif
+ lblBlue->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
+#if !defined(QT_SMALL_COLORDIALOG)
+ gl->addWidget(lblBlue, 2, 3);
+ gl->addWidget(bEd, 2, 4);
+#else
+ if (nonTouchUI) {
+ gl->addWidget(lblBlue, 3, 2);
+ gl->addWidget(bEd, 4, 2);
+ } else {
+ lblBlue->hide();
+ bEd->hide();
+ }
+#endif
+
+ alphaEd = new QColSpinBox(this);
+ alphaLab = new QLabel(this);
+#ifndef QT_NO_SHORTCUT
+ alphaLab->setBuddy(alphaEd);
+#endif
+ alphaLab->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
+#if !defined(QT_SMALL_COLORDIALOG)
+ gl->addWidget(alphaLab, 3, 1, 1, 3);
+ gl->addWidget(alphaEd, 3, 4);
+#else
+ if (nonTouchUI) {
+ gl->addWidget(alphaLab, 1, 3, 3, 1);
+ gl->addWidget(alphaEd, 4, 3);
+ } else {
+ alphaLab->hide();
+ alphaEd->hide();
+ }
+#endif
+ alphaEd->hide();
+ alphaLab->hide();
+
+ connect(hEd, SIGNAL(valueChanged(int)), this, SLOT(hsvEd()));
+ connect(sEd, SIGNAL(valueChanged(int)), this, SLOT(hsvEd()));
+ connect(vEd, SIGNAL(valueChanged(int)), this, SLOT(hsvEd()));
+
+ connect(rEd, SIGNAL(valueChanged(int)), this, SLOT(rgbEd()));
+ connect(gEd, SIGNAL(valueChanged(int)), this, SLOT(rgbEd()));
+ connect(bEd, SIGNAL(valueChanged(int)), this, SLOT(rgbEd()));
+ connect(alphaEd, SIGNAL(valueChanged(int)), this, SLOT(rgbEd()));
+
+ retranslateStrings();
+}
+
+inline QRgb QColorDialogPrivate::currentColor() const { return cs->currentColor(); }
+inline int QColorDialogPrivate::currentAlpha() const { return cs->currentAlpha(); }
+inline void QColorDialogPrivate::setCurrentAlpha(int a) { cs->setCurrentAlpha(a); }
+inline void QColorDialogPrivate::showAlpha(bool b) { cs->showAlpha(b); }
+inline bool QColorDialogPrivate::isAlphaVisible() const { return cs->isAlphaVisible(); }
+
+QColor QColorDialogPrivate::currentQColor() const
+{
+ return cs->currentQColor();
+}
+
+void QColorShower::showCurrentColor()
+{
+ lab->setColor(currentColor());
+ lab->repaint();
+}
+
+void QColorShower::rgbEd()
+{
+ rgbOriginal = true;
+ curCol = qRgba(rEd->value(), gEd->value(), bEd->value(), currentAlpha());
+
+ rgb2hsv(currentColor(), hue, sat, val);
+
+ hEd->setValue(hue);
+ sEd->setValue(sat);
+ vEd->setValue(val);
+
+ showCurrentColor();
+ emit newCol(currentColor());
+ updateQColor();
+}
+
+void QColorShower::hsvEd()
+{
+ rgbOriginal = false;
+ hue = hEd->value();
+ sat = sEd->value();
+ val = vEd->value();
+
+ QColor c;
+ c.setHsv(hue, sat, val);
+ curCol = c.rgb();
+
+ rEd->setValue(qRed(currentColor()));
+ gEd->setValue(qGreen(currentColor()));
+ bEd->setValue(qBlue(currentColor()));
+
+ showCurrentColor();
+ emit newCol(currentColor());
+ updateQColor();
+}
+
+void QColorShower::setRgb(QRgb rgb)
+{
+ rgbOriginal = true;
+ curCol = rgb;
+
+ rgb2hsv(currentColor(), hue, sat, val);
+
+ hEd->setValue(hue);
+ sEd->setValue(sat);
+ vEd->setValue(val);
+
+ rEd->setValue(qRed(currentColor()));
+ gEd->setValue(qGreen(currentColor()));
+ bEd->setValue(qBlue(currentColor()));
+
+ showCurrentColor();
+ updateQColor();
+}
+
+void QColorShower::setHsv(int h, int s, int v)
+{
+ if (h < -1 || (uint)s > 255 || (uint)v > 255)
+ return;
+
+ rgbOriginal = false;
+ hue = h; val = v; sat = s;
+ QColor c;
+ c.setHsv(hue, sat, val);
+ curCol = c.rgb();
+
+ hEd->setValue(hue);
+ sEd->setValue(sat);
+ vEd->setValue(val);
+
+ rEd->setValue(qRed(currentColor()));
+ gEd->setValue(qGreen(currentColor()));
+ bEd->setValue(qBlue(currentColor()));
+
+ showCurrentColor();
+ updateQColor();
+}
+
+void QColorShower::retranslateStrings()
+{
+ lblHue->setText(QColorDialog::tr("Hu&e:"));
+ lblSat->setText(QColorDialog::tr("&Sat:"));
+ lblVal->setText(QColorDialog::tr("&Val:"));
+ lblRed->setText(QColorDialog::tr("&Red:"));
+ lblGreen->setText(QColorDialog::tr("&Green:"));
+ lblBlue->setText(QColorDialog::tr("Bl&ue:"));
+ alphaLab->setText(QColorDialog::tr("A&lpha channel:"));
+}
+
+void QColorShower::updateQColor()
+{
+ QColor oldQColor(curQColor);
+ curQColor.setRgba(qRgba(qRed(curCol), qGreen(curCol), qBlue(curCol), currentAlpha()));
+ if (curQColor != oldQColor)
+ emit currentColorChanged(curQColor);
+}
+
+//sets all widgets to display h,s,v
+void QColorDialogPrivate::_q_newHsv(int h, int s, int v)
+{
+ cs->setHsv(h, s, v);
+ cp->setCol(h, s);
+ lp->setCol(h, s, v);
+}
+
+//sets all widgets to display rgb
+void QColorDialogPrivate::setCurrentColor(QRgb rgb)
+{
+ cs->setRgb(rgb);
+ _q_newColorTypedIn(rgb);
+}
+
+// hack; doesn't keep curCol in sync, so use with care
+void QColorDialogPrivate::setCurrentQColor(const QColor &color)
+{
+ Q_Q(QColorDialog);
+ if (cs->curQColor != color) {
+ cs->curQColor = color;
+ emit q->currentColorChanged(color);
+ }
+}
+
+bool QColorDialogPrivate::selectColor(const QColor &col)
+{
+ QRgb color = col.rgb();
+ int i = 0, j = 0;
+ // Check standard colors
+ if (standard) {
+ for (i = 0; i < 6; i++) {
+ for (j = 0; j < 8; j++) {
+ if (color == stdrgb[i + j*6]) {
+ _q_newStandard(i, j);
+ standard->setCurrent(i, j);
+ standard->setSelected(i, j);
+ standard->setFocus();
+ return true;
+ }
+ }
+ }
+ }
+ // Check custom colors
+ if (custom) {
+ for (i = 0; i < 2; i++) {
+ for (j = 0; j < 8; j++) {
+ if (color == cusrgb[i + j*2]) {
+ _q_newCustom(i, j);
+ custom->setCurrent(i, j);
+ custom->setSelected(i, j);
+ custom->setFocus();
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+}
+
+//sets all widgets except cs to display rgb
+void QColorDialogPrivate::_q_newColorTypedIn(QRgb rgb)
+{
+ int h, s, v;
+ rgb2hsv(rgb, h, s, v);
+ cp->setCol(h, s);
+ lp->setCol(h, s, v);
+}
+
+void QColorDialogPrivate::_q_newCustom(int r, int c)
+{
+ int i = r+2*c;
+ setCurrentColor(cusrgb[i]);
+ nextCust = i;
+ if (standard)
+ standard->setSelected(-1,-1);
+}
+
+void QColorDialogPrivate::_q_newStandard(int r, int c)
+{
+ setCurrentColor(stdrgb[r+c*6]);
+ if (custom)
+ custom->setSelected(-1,-1);
+}
+
+void QColorDialogPrivate::init(const QColor &initial)
+{
+ Q_Q(QColorDialog);
+
+ q->setSizeGripEnabled(false);
+ q->setWindowTitle(QColorDialog::tr("Select Color"));
+
+ nativeDialogInUse = false;
+
+ nextCust = 0;
+ QVBoxLayout *mainLay = new QVBoxLayout(q);
+ // there's nothing in this dialog that benefits from sizing up
+ mainLay->setSizeConstraint(QLayout::SetFixedSize);
+
+ QHBoxLayout *topLay = new QHBoxLayout();
+ mainLay->addLayout(topLay);
+
+ leftLay = 0;
+
+#if defined(Q_WS_WINCE) || defined(QT_SMALL_COLORDIALOG)
+ smallDisplay = true;
+ const int lumSpace = 20;
+#else
+ // small displays (e.g. PDAs) cannot fit the full color dialog,
+ // so just use the color picker.
+ smallDisplay = (QApplication::desktop()->width() < 480 || QApplication::desktop()->height() < 350);
+ const int lumSpace = topLay->spacing() / 2;
+#endif
+
+ if (!smallDisplay) {
+ leftLay = new QVBoxLayout;
+ topLay->addLayout(leftLay);
+ }
+
+ initRGB();
+
+#ifndef QT_NO_SETTINGS
+ if (!customSet) {
+ QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
+ for (int i = 0; i < 2*8; ++i) {
+ QVariant v = settings.value(QLatin1String("Qt/customColors/") + QString::number(i));
+ if (v.isValid()) {
+ QRgb rgb = v.toUInt();
+ cusrgb[i] = rgb;
+ }
+ }
+ }
+#endif
+
+#if defined(QT_SMALL_COLORDIALOG)
+# if defined(Q_WS_S60)
+ const bool nonTouchUI = !S60->hasTouchscreen;
+# elif defined(Q_WS_MAEMO_5)
+ const bool nonTouchUI = false;
+# endif
+#endif
+
+ if (!smallDisplay) {
+ standard = new QColorWell(q, 6, 8, stdrgb);
+ lblBasicColors = new QLabel(q);
+#ifndef QT_NO_SHORTCUT
+ lblBasicColors->setBuddy(standard);
+#endif
+ q->connect(standard, SIGNAL(selected(int,int)), SLOT(_q_newStandard(int,int)));
+ leftLay->addWidget(lblBasicColors);
+ leftLay->addWidget(standard);
+
+#if !defined(Q_WS_WINCE)
+ leftLay->addStretch();
+#endif
+
+ custom = new QColorWell(q, 2, 8, cusrgb);
+ custom->setAcceptDrops(true);
+
+ q->connect(custom, SIGNAL(selected(int,int)), SLOT(_q_newCustom(int,int)));
+ lblCustomColors = new QLabel(q);
+#ifndef QT_NO_SHORTCUT
+ lblCustomColors->setBuddy(custom);
+#endif
+ leftLay->addWidget(lblCustomColors);
+ leftLay->addWidget(custom);
+
+ addCusBt = new QPushButton(q);
+ QObject::connect(addCusBt, SIGNAL(clicked()), q, SLOT(_q_addCustom()));
+ leftLay->addWidget(addCusBt);
+ } else {
+ // better color picker size for small displays
+#if defined(QT_SMALL_COLORDIALOG)
+ QSize screenSize = QApplication::desktop()->availableGeometry(QCursor::pos()).size();
+ pWidth = pHeight = qMin(screenSize.width(), screenSize.height());
+ pHeight -= 20;
+ if(screenSize.height() > screenSize.width())
+ pWidth -= 20;
+#else
+ pWidth = 150;
+ pHeight = 100;
+#endif
+ custom = 0;
+ standard = 0;
+ }
+
+ QVBoxLayout *rightLay = new QVBoxLayout;
+ topLay->addLayout(rightLay);
+
+ QHBoxLayout *pickLay = new QHBoxLayout;
+ rightLay->addLayout(pickLay);
+
+ QVBoxLayout *cLay = new QVBoxLayout;
+ pickLay->addLayout(cLay);
+ cp = new QColorPicker(q);
+
+ cp->setFrameStyle(QFrame::Panel + QFrame::Sunken);
+
+#if defined(QT_SMALL_COLORDIALOG)
+ if (!nonTouchUI) {
+ pickLay->addWidget(cp);
+ cLay->addSpacing(lumSpace);
+ } else {
+ cp->hide();
+ }
+#else
+ cLay->addSpacing(lumSpace);
+ cLay->addWidget(cp);
+#endif
+ cLay->addSpacing(lumSpace);
+
+ lp = new QColorLuminancePicker(q);
+#if defined(QT_SMALL_COLORDIALOG)
+ QSize screenSize = QApplication::desktop()->availableGeometry(QCursor::pos()).size();
+ const int minDimension = qMin(screenSize.height(), screenSize.width());
+ //set picker to be finger-usable
+ int pickerWidth = !nonTouchUI ? minDimension/9 : minDimension/12;
+ lp->setFixedWidth(pickerWidth);
+ if (!nonTouchUI)
+ pickLay->addWidget(lp);
+ else
+ lp->hide();
+#else
+ lp->setFixedWidth(20);
+ pickLay->addWidget(lp);
+#endif
+
+ QObject::connect(cp, SIGNAL(newCol(int,int)), lp, SLOT(setCol(int,int)));
+ QObject::connect(lp, SIGNAL(newHsv(int,int,int)), q, SLOT(_q_newHsv(int,int,int)));
+
+ rightLay->addStretch();
+
+ cs = new QColorShower(q);
+ QObject::connect(cs, SIGNAL(newCol(QRgb)), q, SLOT(_q_newColorTypedIn(QRgb)));
+ QObject::connect(cs, SIGNAL(currentColorChanged(QColor)),
+ q, SIGNAL(currentColorChanged(QColor)));
+#if defined(QT_SMALL_COLORDIALOG)
+ if (!nonTouchUI)
+ pWidth -= cp->size().width();
+ topLay->addWidget(cs);
+#else
+ rightLay->addWidget(cs);
+#endif
+
+ buttons = new QDialogButtonBox(q);
+ mainLay->addWidget(buttons);
+
+ ok = buttons->addButton(QDialogButtonBox::Ok);
+ QObject::connect(ok, SIGNAL(clicked()), q, SLOT(accept()));
+ ok->setDefault(true);
+ cancel = buttons->addButton(QDialogButtonBox::Cancel);
+ QObject::connect(cancel, SIGNAL(clicked()), q, SLOT(reject()));
+
+ retranslateStrings();
+
+#ifdef Q_WS_MAC
+ delegate = 0;
+#endif
+
+ q->setCurrentColor(initial);
+}
+
+void QColorDialogPrivate::_q_addCustom()
+{
+ cusrgb[nextCust] = cs->currentColor();
+ if (custom)
+ custom->update();
+ nextCust = (nextCust+1) % 16;
+}
+
+void QColorDialogPrivate::retranslateStrings()
+{
+ if (!smallDisplay) {
+ lblBasicColors->setText(QColorDialog::tr("&Basic colors"));
+ lblCustomColors->setText(QColorDialog::tr("&Custom colors"));
+ addCusBt->setText(QColorDialog::tr("&Add to Custom Colors"));
+ }
+
+ cs->retranslateStrings();
+}
+
+static const Qt::WindowFlags DefaultWindowFlags =
+ Qt::Dialog | Qt::WindowTitleHint | Qt::MSWindowsFixedSizeDialogHint
+ | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint;
+
+/*!
+ \class QColorDialog
+ \brief The QColorDialog class provides a dialog widget for specifying colors.
+
+ \ingroup standard-dialogs
+
+ The color dialog's function is to allow users to choose colors.
+ For example, you might use this in a drawing program to allow the
+ user to set the brush color.
+
+ The static functions provide modal color dialogs.
+ \omit
+ 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. 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
+ during the execution of the program. Use setCustomColor() to set
+ the custom colors, and use customColor() to get them.
+
+ Additional widgets that allow users to pick colors are available
+ as \l{Qt Solutions}.
+
+ The \l{dialogs/standarddialogs}{Standard Dialogs} example shows
+ how to use QColorDialog as well as other built-in Qt dialogs.
+
+ \image plastique-colordialog.png A color dialog in the Plastique widget style.
+
+ \sa QColor, QFileDialog, QPrintDialog, QFontDialog, {Standard Dialogs Example}
+*/
+
+/*!
+ \since 4.5
+
+ Constructs a color dialog with the given \a parent.
+*/
+QColorDialog::QColorDialog(QWidget *parent)
+ : QDialog(*new QColorDialogPrivate, parent, DefaultWindowFlags)
+{
+ Q_D(QColorDialog);
+ d->init(Qt::white);
+}
+
+/*!
+ \since 4.5
+
+ Constructs a color dialog with the given \a parent and specified
+ \a initial color.
+*/
+QColorDialog::QColorDialog(const QColor &initial, QWidget *parent)
+ : QDialog(*new QColorDialogPrivate, parent, DefaultWindowFlags)
+{
+ Q_D(QColorDialog);
+ d->init(initial);
+}
+
+/*!
+ \property QColorDialog::currentColor
+ \brief the currently selected color in the dialog
+*/
+
+void QColorDialog::setCurrentColor(const QColor &color)
+{
+ Q_D(QColorDialog);
+ d->setCurrentColor(color.rgb());
+ d->selectColor(color);
+ d->setCurrentAlpha(color.alpha());
+
+#ifdef Q_WS_MAC
+ d->setCurrentQColor(color);
+ d->setCocoaPanelColor(color);
+#endif
+ if (d->nativeDialogInUse)
+ qt_guiPlatformPlugin()->colorDialogSetCurrentColor(this, color);
+}
+
+QColor QColorDialog::currentColor() const
+{
+ Q_D(const QColorDialog);
+ return d->currentQColor();
+}
+
+
+/*!
+ Returns the color that the user selected by clicking the \gui{OK}
+ or equivalent button.
+
+ \note This color is not always the same as the color held by the
+ \l currentColor property since the user can choose different colors
+ before finally selecting the one to use.
+*/
+QColor QColorDialog::selectedColor() const
+{
+ Q_D(const QColorDialog);
+ return d->selectedQColor;
+}
+
+/*!
+ Sets the given \a option to be enabled if \a on is true;
+ otherwise, clears the given \a option.
+
+ \sa options, testOption()
+*/
+void QColorDialog::setOption(ColorDialogOption option, bool on)
+{
+ Q_D(QColorDialog);
+ if (!(d->opts & option) != !on)
+ setOptions(d->opts ^ option);
+}
+
+/*!
+ \since 4.5
+
+ Returns true if the given \a option is enabled; otherwise, returns
+ false.
+
+ \sa options, setOption()
+*/
+bool QColorDialog::testOption(ColorDialogOption option) const
+{
+ Q_D(const QColorDialog);
+ return (d->opts & option) != 0;
+}
+
+/*!
+ \property QColorDialog::options
+ \brief the various options that affect the look and feel of the dialog
+
+ By default, all options are disabled.
+
+ Options should be set before showing the dialog. Setting them while the
+ dialog is visible is not guaranteed to have an immediate effect on the
+ dialog (depending on the option and on the platform).
+
+ \sa setOption(), testOption()
+*/
+void QColorDialog::setOptions(ColorDialogOptions options)
+{
+ Q_D(QColorDialog);
+
+ ColorDialogOptions changed = (options ^ d->opts);
+ if (!changed)
+ return;
+
+ d->opts = options;
+ d->buttons->setVisible(!(options & NoButtons));
+ d->showAlpha(options & ShowAlphaChannel);
+}
+
+QColorDialog::ColorDialogOptions QColorDialog::options() const
+{
+ Q_D(const QColorDialog);
+ return d->opts;
+}
+
+/*!
+ \enum QColorDialog::ColorDialogOption
+
+ \since 4.5
+
+ This enum specifies various options that affect the look and feel
+ of a color dialog.
+
+ \value ShowAlphaChannel Allow the user to select the alpha component of a color.
+ \value NoButtons Don't display \gui{OK} and \gui{Cancel} buttons. (Useful for "live dialogs".)
+ \value DontUseNativeDialog Use Qt's standard color dialog on the Mac instead of Apple's
+ native color panel.
+
+ \sa options, setOption(), testOption(), windowModality()
+*/
+
+/*!
+ \fn void QColorDialog::currentColorChanged(const QColor &color)
+
+ This signal is emitted whenever the current color changes in the dialog.
+ The current color is specified by \a color.
+
+ \sa color, colorSelected()
+*/
+
+#ifdef Q_WS_MAC
+// can only have one Cocoa color panel active
+bool QColorDialogPrivate::sharedColorPanelAvailable = true;
+#endif
+
+/*!
+ \fn void QColorDialog::colorSelected(const QColor &color);
+
+ This signal is emitted just after the user has clicked \gui{OK} to
+ select a color to use. The chosen color is specified by \a color.
+
+ \sa color, currentColorChanged()
+*/
+
+/*!
+ Changes the visibility of the dialog. If \a visible is true, the dialog
+ is shown; otherwise, it is hidden.
+*/
+void QColorDialog::setVisible(bool visible)
+{
+ Q_D(QColorDialog);
+
+ if (visible){
+ if (testAttribute(Qt::WA_WState_ExplicitShowHide) && !testAttribute(Qt::WA_WState_Hidden))
+ return;
+ } else if (testAttribute(Qt::WA_WState_ExplicitShowHide) && testAttribute(Qt::WA_WState_Hidden))
+ return;
+
+ if (visible)
+ d->selectedQColor = QColor();
+
+#if defined(Q_WS_MAC)
+ if (visible) {
+ if (d->delegate || (QColorDialogPrivate::sharedColorPanelAvailable &&
+ !(testAttribute(Qt::WA_DontShowOnScreen) || (d->opts & DontUseNativeDialog)))){
+ d->openCocoaColorPanel(currentColor(), parentWidget(), windowTitle(), options());
+ QColorDialogPrivate::sharedColorPanelAvailable = false;
+ setAttribute(Qt::WA_DontShowOnScreen);
+ }
+ setWindowFlags(windowModality() == Qt::WindowModal ? Qt::Sheet : DefaultWindowFlags);
+ } else {
+ if (d->delegate) {
+ d->closeCocoaColorPanel();
+ setAttribute(Qt::WA_DontShowOnScreen, false);
+ }
+ }
+#else
+
+ if (!(d->opts & DontUseNativeDialog) && qt_guiPlatformPlugin()->colorDialogSetVisible(this, visible)) {
+ d->nativeDialogInUse = true;
+ // Set WA_DontShowOnScreen so that QDialog::setVisible(visible) below
+ // updates the state correctly, but skips showing the non-native version:
+ setAttribute(Qt::WA_DontShowOnScreen);
+ } else {
+ d->nativeDialogInUse = false;
+ setAttribute(Qt::WA_DontShowOnScreen, false);
+ }
+#endif
+
+ QDialog::setVisible(visible);
+}
+
+/*!
+ \overload
+ \since 4.5
+
+ Opens the dialog and connects its colorSelected() signal to the slot specified
+ by \a receiver and \a member.
+
+ The signal will be disconnected from the slot when the dialog is closed.
+*/
+void QColorDialog::open(QObject *receiver, const char *member)
+{
+ Q_D(QColorDialog);
+ connect(this, SIGNAL(colorSelected(QColor)), receiver, member);
+ d->receiverToDisconnectOnClose = receiver;
+ d->memberToDisconnectOnClose = member;
+ QDialog::open();
+}
+
+/*!
+ \fn QColorDialog::open()
+
+ \since 4.5
+ Shows the dialog as a \l{QDialog#Modal Dialogs}{window modal dialog},
+ returning immediately.
+
+ \sa QDialog::open()
+*/
+
+/*
+ For Symbian color dialogs
+*/
+#ifdef Q_WS_S60
+extern QColor qtSymbianGetColor(const QColor &initial);
+#endif
+/*!
+ \since 4.5
+
+ Pops up a modal color dialog with the given window \a title (or "Select Color" if none is
+ specified), lets the user choose a color, and returns that color. The color is initially set
+ to \a initial. The dialog is a child of \a parent. It returns an invalid (see
+ QColor::isValid()) color if the user cancels the dialog.
+
+ The \a options argument allows you to customize the dialog.
+
+ On Symbian, this static function will use the native color dialog and not a QColorDialog.
+ On Symbian the parameters \a title and \a parent has no relevance and the
+ \a options parameter is only used to define if the native color dialog is
+ used or not.
+*/
+QColor QColorDialog::getColor(const QColor &initial, QWidget *parent, const QString &title,
+ ColorDialogOptions options)
+{
+#ifdef Q_WS_S60
+ if (!(options & DontUseNativeDialog))
+ return qtSymbianGetColor(initial);
+#endif
+ QColorDialog dlg(parent);
+ if (!title.isEmpty())
+ dlg.setWindowTitle(title);
+ dlg.setOptions(options);
+ dlg.setCurrentColor(initial);
+ dlg.exec();
+ return dlg.selectedColor();
+}
+
+/*!
+ Pops up a modal color dialog, lets the user choose a color, and
+ returns that color. The color is initially set to \a initial. The
+ dialog is a child of \a parent. It returns an invalid (see
+ QColor::isValid()) color if the user cancels the dialog.
+
+ On Symbian, this static function will use the native
+ color dialog and not a QColorDialog.
+*/
+
+QColor QColorDialog::getColor(const QColor &initial, QWidget *parent)
+{
+#ifdef Q_WS_S60
+ return qtSymbianGetColor(initial);
+#endif
+ return getColor(initial, parent, QString(), ColorDialogOptions(0));
+}
+
+
+/*!
+ \obsolete
+
+ Pops up a modal color dialog to allow the user to choose a color
+ and an alpha channel (transparency) value. The color+alpha is
+ initially set to \a initial. The dialog is a child of \a parent.
+
+ If \a ok is non-null, \e *\a ok is set to true if the user clicked
+ \gui{OK}, and to false if the user clicked Cancel.
+
+ If the user clicks Cancel, the \a initial value is returned.
+
+ Use QColorDialog::getColor() instead, passing the
+ QColorDialog::ShowAlphaChannel option.
+*/
+
+QRgb QColorDialog::getRgba(QRgb initial, bool *ok, QWidget *parent)
+{
+ QColor color(getColor(QColor(initial), parent, QString(), ShowAlphaChannel));
+ QRgb result = color.isValid() ? color.rgba() : initial;
+ if (ok)
+ *ok = color.isValid();
+ return result;
+}
+
+/*!
+ Destroys the color dialog.
+*/
+
+QColorDialog::~QColorDialog()
+{
+ Q_D(QColorDialog);
+#if defined(Q_WS_MAC)
+ if (d->delegate) {
+ d->releaseCocoaColorPanelDelegate();
+ QColorDialogPrivate::sharedColorPanelAvailable = true;
+ }
+#endif
+
+#ifndef QT_NO_SETTINGS
+ if (!customSet) {
+ QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
+ for (int i = 0; i < 2*8; ++i)
+ settings.setValue(QLatin1String("Qt/customColors/") + QString::number(i), cusrgb[i]);
+ }
+#endif
+ if (d->nativeDialogInUse)
+ qt_guiPlatformPlugin()->colorDialogDelete(this);
+
+}
+
+
+/*!
+ \reimp
+*/
+void QColorDialog::changeEvent(QEvent *e)
+{
+ Q_D(QColorDialog);
+ if (e->type() == QEvent::LanguageChange)
+ d->retranslateStrings();
+ QDialog::changeEvent(e);
+}
+
+/*!
+ Closes the dialog and sets its result code to \a result. If this dialog
+ is shown with exec(), done() causes the local event loop to finish,
+ and exec() to return \a result.
+
+ \sa QDialog::done()
+*/
+void QColorDialog::done(int result)
+{
+ Q_D(QColorDialog);
+ QDialog::done(result);
+ if (result == Accepted) {
+ d->selectedQColor = d->currentQColor();
+ emit colorSelected(d->selectedQColor);
+ } else {
+ d->selectedQColor = QColor();
+ }
+ if (d->receiverToDisconnectOnClose) {
+ disconnect(this, SIGNAL(colorSelected(QColor)),
+ d->receiverToDisconnectOnClose, d->memberToDisconnectOnClose);
+ d->receiverToDisconnectOnClose = 0;
+ }
+ d->memberToDisconnectOnClose.clear();
+}
+
+QT_END_NAMESPACE
+
+#include "qcolordialog.moc"
+#include "moc_qcolordialog.cpp"
+
+#endif // QT_NO_COLORDIALOG
+
+/*!
+ \fn QColor QColorDialog::getColor(const QColor &init, QWidget *parent, const char *name)
+ \compat
+*/
+
+/*!
+ \fn QRgb QColorDialog::getRgba(QRgb rgba, bool *ok, QWidget *parent, const char *name)
+ \compat
+*/
diff --git a/src/widgets/dialogs/qcolordialog.h b/src/widgets/dialogs/qcolordialog.h
new file mode 100644
index 0000000000..2eb4658634
--- /dev/null
+++ b/src/widgets/dialogs/qcolordialog.h
@@ -0,0 +1,150 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCOLORDIALOG_H
+#define QCOLORDIALOG_H
+
+#include <QtWidgets/qdialog.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_COLORDIALOG
+
+class QColorDialogPrivate;
+
+class Q_WIDGETS_EXPORT QColorDialog : public QDialog
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QColorDialog)
+ Q_ENUMS(ColorDialogOption)
+ Q_PROPERTY(QColor currentColor READ currentColor WRITE setCurrentColor
+ NOTIFY currentColorChanged)
+ Q_PROPERTY(ColorDialogOptions options READ options WRITE setOptions)
+
+public:
+ enum ColorDialogOption {
+ ShowAlphaChannel = 0x00000001,
+ NoButtons = 0x00000002,
+ DontUseNativeDialog = 0x00000004
+ };
+
+ Q_DECLARE_FLAGS(ColorDialogOptions, ColorDialogOption)
+
+ explicit QColorDialog(QWidget *parent = 0);
+ explicit QColorDialog(const QColor &initial, QWidget *parent = 0);
+ ~QColorDialog();
+
+ void setCurrentColor(const QColor &color);
+ QColor currentColor() const;
+
+ QColor selectedColor() const;
+
+ void setOption(ColorDialogOption option, bool on = true);
+ bool testOption(ColorDialogOption option) const;
+ void setOptions(ColorDialogOptions options);
+ ColorDialogOptions options() const;
+
+#ifdef Q_NO_USING_KEYWORD
+ void open() { QDialog::open(); }
+#else
+ using QDialog::open;
+#endif
+ void open(QObject *receiver, const char *member);
+
+ void setVisible(bool visible);
+
+ // ### Qt 5: merge overloads with title = QString()
+ static QColor getColor(const QColor &initial, QWidget *parent, const QString &title,
+ ColorDialogOptions options = 0);
+ static QColor getColor(const QColor &initial = Qt::white, QWidget *parent = 0);
+
+ // obsolete
+ static QRgb getRgba(QRgb rgba = 0xffffffff, bool *ok = 0, QWidget *parent = 0);
+
+ // ### Qt 5: use QColor in signatures
+ static int customCount();
+ static QRgb customColor(int index);
+ static void setCustomColor(int index, QRgb color);
+ static void setStandardColor(int index, QRgb color);
+
+#ifdef QT3_SUPPORT
+ static QColor getColor(const QColor &init, QWidget *parent, const char *name)
+ { Q_UNUSED(name); return getColor(init, parent); }
+ static QRgb getRgba(QRgb rgba, bool *ok, QWidget *parent, const char *name)
+ { Q_UNUSED(name); return getRgba(rgba, ok, parent); }
+#endif
+
+Q_SIGNALS:
+ void currentColorChanged(const QColor &color);
+ void colorSelected(const QColor &color);
+
+protected:
+ void changeEvent(QEvent *event);
+ void done(int result);
+
+private:
+ Q_DISABLE_COPY(QColorDialog)
+
+ Q_PRIVATE_SLOT(d_func(), void _q_addCustom())
+ Q_PRIVATE_SLOT(d_func(), void _q_newHsv(int h, int s, int v))
+ Q_PRIVATE_SLOT(d_func(), void _q_newColorTypedIn(QRgb rgb))
+ Q_PRIVATE_SLOT(d_func(), void _q_newCustom(int, int))
+ Q_PRIVATE_SLOT(d_func(), void _q_newStandard(int, int))
+#if defined(Q_WS_MAC)
+ Q_PRIVATE_SLOT(d_func(), void _q_macRunNativeAppModalPanel())
+#endif
+
+ friend class QColorShower;
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QColorDialog::ColorDialogOptions)
+
+#endif // QT_NO_COLORDIALOG
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QCOLORDIALOG_H
diff --git a/src/gui/dialogs/qcolordialog_mac.mm b/src/widgets/dialogs/qcolordialog_mac.mm
index 1d77751e2b..1d77751e2b 100644
--- a/src/gui/dialogs/qcolordialog_mac.mm
+++ b/src/widgets/dialogs/qcolordialog_mac.mm
diff --git a/src/gui/dialogs/qcolordialog_p.h b/src/widgets/dialogs/qcolordialog_p.h
index f1865e66ec..f1865e66ec 100644
--- a/src/gui/dialogs/qcolordialog_p.h
+++ b/src/widgets/dialogs/qcolordialog_p.h
diff --git a/src/gui/dialogs/qcolordialog_symbian.cpp b/src/widgets/dialogs/qcolordialog_symbian.cpp
index eab35f5ac8..eab35f5ac8 100644
--- a/src/gui/dialogs/qcolordialog_symbian.cpp
+++ b/src/widgets/dialogs/qcolordialog_symbian.cpp
diff --git a/src/gui/dialogs/qdialog.cpp b/src/widgets/dialogs/qdialog.cpp
index 2fb6c67e50..2fb6c67e50 100644
--- a/src/gui/dialogs/qdialog.cpp
+++ b/src/widgets/dialogs/qdialog.cpp
diff --git a/src/widgets/dialogs/qdialog.h b/src/widgets/dialogs/qdialog.h
new file mode 100644
index 0000000000..ce8aa91bc7
--- /dev/null
+++ b/src/widgets/dialogs/qdialog.h
@@ -0,0 +1,140 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDIALOG_H
+#define QDIALOG_H
+
+#include <QtWidgets/qwidget.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QPushButton;
+class QDialogPrivate;
+
+class Q_WIDGETS_EXPORT QDialog : public QWidget
+{
+ Q_OBJECT
+ friend class QPushButton;
+
+ Q_PROPERTY(bool sizeGripEnabled READ isSizeGripEnabled WRITE setSizeGripEnabled)
+ Q_PROPERTY(bool modal READ isModal WRITE setModal)
+
+public:
+ explicit QDialog(QWidget *parent = 0, Qt::WindowFlags f = 0);
+#ifdef QT3_SUPPORT
+ QT3_SUPPORT_CONSTRUCTOR QDialog(QWidget *parent, const char *name, bool modal = false,
+ Qt::WindowFlags f = 0);
+#endif
+ ~QDialog();
+
+ enum DialogCode { Rejected, Accepted };
+
+ int result() const;
+
+ void setVisible(bool visible);
+
+ void setOrientation(Qt::Orientation orientation);
+ Qt::Orientation orientation() const;
+
+ void setExtension(QWidget* extension);
+ QWidget* extension() const;
+
+ QSize sizeHint() const;
+ QSize minimumSizeHint() const;
+
+ void setSizeGripEnabled(bool);
+ bool isSizeGripEnabled() const;
+
+ void setModal(bool modal);
+ void setResult(int r);
+
+Q_SIGNALS:
+ void finished(int result);
+ void accepted();
+ void rejected();
+
+public Q_SLOTS:
+ void open();
+ int exec();
+ virtual void done(int);
+ virtual void accept();
+ virtual void reject();
+
+ void showExtension(bool);
+
+protected:
+ QDialog(QDialogPrivate &, QWidget *parent, Qt::WindowFlags f = 0);
+
+#if defined(Q_WS_WINCE) || defined(Q_OS_SYMBIAN)
+ bool event(QEvent *e);
+#endif
+ void keyPressEvent(QKeyEvent *);
+ void closeEvent(QCloseEvent *);
+ void showEvent(QShowEvent *);
+ void resizeEvent(QResizeEvent *);
+#ifndef QT_NO_CONTEXTMENU
+ void contextMenuEvent(QContextMenuEvent *);
+#endif
+ bool eventFilter(QObject *, QEvent *);
+ void adjustPosition(QWidget*);
+private:
+ Q_DECLARE_PRIVATE(QDialog)
+ Q_DISABLE_COPY(QDialog)
+
+#if defined(Q_OS_SYMBIAN)
+ bool symbianAdjustedPosition();
+#endif
+
+
+#ifdef Q_WS_WINCE_WM
+ Q_PRIVATE_SLOT(d_func(), void _q_doneAction())
+#endif
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QDIALOG_H
diff --git a/src/widgets/dialogs/qdialog_p.h b/src/widgets/dialogs/qdialog_p.h
new file mode 100644
index 0000000000..3ee88f4703
--- /dev/null
+++ b/src/widgets/dialogs/qdialog_p.h
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDIALOG_P_H
+#define QDIALOG_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "private/qwidget_p.h"
+#include "QtCore/qeventloop.h"
+#include "QtCore/qpointer.h"
+#include "QtWidgets/qdialog.h"
+#include "QtWidgets/qpushbutton.h"
+
+QT_BEGIN_NAMESPACE
+
+class QSizeGrip;
+
+class QDialogPrivate : public QWidgetPrivate
+{
+ Q_DECLARE_PUBLIC(QDialog)
+public:
+
+ QDialogPrivate()
+ : mainDef(0), orientation(Qt::Horizontal),extension(0), doShowExtension(false),
+#ifndef QT_NO_SIZEGRIP
+ resizer(0),
+ sizeGripEnabled(false),
+#endif
+ rescode(0), resetModalityTo(-1), wasModalitySet(true), eventLoop(0)
+ {}
+
+ QPointer<QPushButton> mainDef;
+ Qt::Orientation orientation;
+ QWidget *extension;
+ bool doShowExtension;
+ QSize size, min, max;
+#ifndef QT_NO_SIZEGRIP
+ QSizeGrip *resizer;
+ bool sizeGripEnabled;
+#endif
+ QPoint lastRMBPress;
+
+ void setDefault(QPushButton *);
+ void setMainDefault(QPushButton *);
+ void hideDefault();
+ void resetModalitySetByOpen();
+
+#ifdef Q_WS_WINCE_WM
+ void _q_doneAction();
+#endif
+
+#ifdef Q_WS_MAC
+ virtual void mac_nativeDialogModalHelp() {}
+#endif
+
+ int rescode;
+ int resetModalityTo;
+ bool wasModalitySet;
+
+ QPointer<QEventLoop> eventLoop;
+};
+
+QT_END_NAMESPACE
+
+#endif // QDIALOG_P_H
diff --git a/src/widgets/dialogs/qdialogsbinarycompat_win.cpp b/src/widgets/dialogs/qdialogsbinarycompat_win.cpp
new file mode 100644
index 0000000000..09c96eaafd
--- /dev/null
+++ b/src/widgets/dialogs/qdialogsbinarycompat_win.cpp
@@ -0,0 +1,137 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qglobal.h>
+
+// ### Qt 5: eliminate this file
+
+/*
+ This is evil. MSVC doesn't let us remove private symbols, nor change their
+ visibility; yet there are some symbols we really needed to make public, e.g.,
+ ~QColorDialog(), and then there were some totally needless symbols in our
+ header files, e.g., setSelectedAlpha(). So we define a new version of
+ QColorDialog & Co. with only the private symbols that we removed from the
+ public header files. The friends are there only to prevent potential compiler
+ warnings.
+
+ It would have been nicer to export the missing symbols as mangled "C" symbols
+ instead but unfortunately MSVC uses out-of-reach characters like @ and . in
+ their mangled C++ symbols.
+*/
+
+#if QT_VERSION < 0x050000 && defined(Q_CC_MSVC)
+
+QT_BEGIN_NAMESPACE
+
+#include <QtGui/QColor>
+#include <QtGui/QFont>
+
+class QColorDialogPrivate;
+class QFontDialogPrivate;
+class QInputDialogPrivate;
+class QWidget;
+
+class Q_WIDGETS_EXPORT QColorDialog
+{
+private:
+ explicit QColorDialog(QWidget *, bool);
+ ~QColorDialog();
+
+ void setColor(const QColor &);
+ QColor color() const;
+ bool selectColor(const QColor &);
+ void setSelectedAlpha(int);
+ int selectedAlpha() const;
+
+ friend class QColorDialogPrivate;
+};
+
+QColorDialog::QColorDialog(QWidget *, bool) {}
+QColorDialog::~QColorDialog() {}
+void QColorDialog::setColor(const QColor &) {}
+QColor QColorDialog::color() const { return QColor(); }
+bool QColorDialog::selectColor(const QColor &) { return false; }
+void QColorDialog::setSelectedAlpha(int) {}
+int QColorDialog::selectedAlpha() const { return 0; }
+
+class Q_WIDGETS_EXPORT QFontDialog
+{
+private:
+ explicit QFontDialog(QWidget *, bool, Qt::WindowFlags);
+ ~QFontDialog();
+
+ QFont font() const;
+ void setFont(const QFont &);
+ void updateFamilies();
+ void updateStyles();
+ void updateSizes();
+
+ static QFont getFont(bool *, const QFont *, QWidget *);
+
+ friend class QFontDialogPrivate;
+};
+
+QFontDialog::QFontDialog(QWidget *, bool, Qt::WindowFlags) {}
+QFontDialog::~QFontDialog() {}
+QFont QFontDialog::font() const { return QFont(); }
+void QFontDialog::setFont(const QFont &) { }
+void QFontDialog::updateFamilies() {}
+void QFontDialog::updateStyles() {}
+void QFontDialog::updateSizes() {}
+QFont QFontDialog::getFont(bool *, const QFont *, QWidget *) { return QFont(); }
+
+class Q_WIDGETS_EXPORT QInputDialog
+{
+private:
+ enum Type { LineEdit, SpinBox, DoubleSpinBox, ComboBox, EditableComboBox };
+
+ QInputDialog(const QString &, QWidget *, Type, Qt::WindowFlags);
+ QInputDialog(const QString &, const QString &, QWidget *, QWidget *, Qt::WindowFlags);
+ ~QInputDialog();
+};
+
+QInputDialog::QInputDialog(const QString &, QWidget *, Type, Qt::WindowFlags) {}
+QInputDialog::QInputDialog(const QString &, const QString &, QWidget *, QWidget *, Qt::WindowFlags) {}
+QInputDialog::~QInputDialog() {}
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/gui/dialogs/qerrormessage.cpp b/src/widgets/dialogs/qerrormessage.cpp
index 890e6ca6b7..890e6ca6b7 100644
--- a/src/gui/dialogs/qerrormessage.cpp
+++ b/src/widgets/dialogs/qerrormessage.cpp
diff --git a/src/widgets/dialogs/qerrormessage.h b/src/widgets/dialogs/qerrormessage.h
new file mode 100644
index 0000000000..a8805a2372
--- /dev/null
+++ b/src/widgets/dialogs/qerrormessage.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QERRORMESSAGE_H
+#define QERRORMESSAGE_H
+
+#include <QtWidgets/qdialog.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_ERRORMESSAGE
+
+class QErrorMessagePrivate;
+
+class Q_WIDGETS_EXPORT QErrorMessage: public QDialog
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QErrorMessage)
+public:
+ explicit QErrorMessage(QWidget* parent = 0);
+ ~QErrorMessage();
+
+ static QErrorMessage * qtHandler();
+
+public Q_SLOTS:
+ void showMessage(const QString &message);
+ void showMessage(const QString &message, const QString &type);
+#ifdef QT3_SUPPORT
+ inline QT_MOC_COMPAT void message(const QString &text) { showMessage(text); }
+#endif
+
+protected:
+ void done(int);
+ void changeEvent(QEvent *e);
+
+private:
+ Q_DISABLE_COPY(QErrorMessage)
+};
+
+#endif // QT_NO_ERRORMESSAGE
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QERRORMESSAGE_H
diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp
new file mode 100644
index 0000000000..9d6e348b0d
--- /dev/null
+++ b/src/widgets/dialogs/qfiledialog.cpp
@@ -0,0 +1,3555 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qvariant.h>
+#include <private/qwidgetitemdata_p.h>
+#include "qfiledialog.h"
+
+#ifndef QT_NO_FILEDIALOG
+#include "qfiledialog_p.h"
+#include <qfontmetrics.h>
+#include <qaction.h>
+#include <qheaderview.h>
+#include <qshortcut.h>
+#include <qgridlayout.h>
+#include <qmenu.h>
+#include <qmessagebox.h>
+#include <qinputdialog.h>
+#include <stdlib.h>
+#include <qsettings.h>
+#include <qdebug.h>
+#include <qapplication.h>
+#include <qstylepainter.h>
+#if !defined(Q_WS_WINCE) && !defined(Q_OS_SYMBIAN)
+#include "ui_qfiledialog.h"
+#else
+#define Q_EMBEDDED_SMALLSCREEN
+#include "ui_qfiledialog_embedded.h"
+#if defined(Q_OS_WINCE)
+extern bool qt_priv_ptr_valid;
+#endif
+#if defined(Q_OS_UNIX)
+#include <pwd.h>
+#endif
+#endif
+
+QT_BEGIN_NAMESPACE
+
+Q_GLOBAL_STATIC(QString, lastVisitedDir)
+
+/*
+ \internal
+
+ Exported hooks that can be used to customize the static functions.
+ */
+typedef QString (*_qt_filedialog_existing_directory_hook)(QWidget *parent, const QString &caption, const QString &dir, QFileDialog::Options options);
+Q_WIDGETS_EXPORT _qt_filedialog_existing_directory_hook qt_filedialog_existing_directory_hook = 0;
+
+typedef QString (*_qt_filedialog_open_filename_hook)(QWidget * parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options);
+Q_WIDGETS_EXPORT _qt_filedialog_open_filename_hook qt_filedialog_open_filename_hook = 0;
+
+typedef QStringList (*_qt_filedialog_open_filenames_hook)(QWidget * parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options);
+Q_WIDGETS_EXPORT _qt_filedialog_open_filenames_hook qt_filedialog_open_filenames_hook = 0;
+
+typedef QString (*_qt_filedialog_save_filename_hook)(QWidget * parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options);
+Q_WIDGETS_EXPORT _qt_filedialog_save_filename_hook qt_filedialog_save_filename_hook = 0;
+
+/*!
+ \class QFileDialog
+ \brief The QFileDialog class provides a dialog that allow users to select files or directories.
+ \ingroup standard-dialogs
+
+
+ The QFileDialog class enables a user to traverse the file system in
+ order to select one or many files or a directory.
+
+ The easiest way to create a QFileDialog is to use the static
+ functions. On Windows, Mac OS X, KDE and GNOME, these static functions will
+ call the native file dialog when possible.
+
+ \snippet doc/src/snippets/code/src_gui_dialogs_qfiledialog.cpp 0
+
+ In the above example, a modal QFileDialog is created using a static
+ function. The dialog initially displays the contents of the "/home/jana"
+ directory, and displays files matching the patterns given in the
+ string "Image Files (*.png *.jpg *.bmp)". The parent of the file dialog
+ is set to \e this, and the window title is set to "Open Image".
+
+ If you want to use multiple filters, separate each one with
+ \e two semicolons. For example:
+
+ \snippet doc/src/snippets/code/src_gui_dialogs_qfiledialog.cpp 1
+
+ You can create your own QFileDialog without using the static
+ functions. By calling setFileMode(), you can specify what the user must
+ select in the dialog:
+
+ \snippet doc/src/snippets/code/src_gui_dialogs_qfiledialog.cpp 2
+
+ In the above example, the mode of the file dialog is set to
+ AnyFile, meaning that the user can select any file, or even specify a
+ file that doesn't exist. This mode is useful for creating a
+ "Save As" file dialog. Use ExistingFile if the user must select an
+ existing file, or \l Directory if only a directory may be selected.
+ See the \l QFileDialog::FileMode enum for the complete list of modes.
+
+ The fileMode property contains the mode of operation for the dialog;
+ this indicates what types of objects the user is expected to select.
+ Use setNameFilter() to set the dialog's file filter. For example:
+
+ \snippet doc/src/snippets/code/src_gui_dialogs_qfiledialog.cpp 3
+
+ In the above example, the filter is set to \c{"Images (*.png *.xpm *.jpg)"},
+ this means that only files with the extension \c png, \c xpm,
+ or \c jpg will be shown in the QFileDialog. You can apply
+ several filters by using setNameFilters(). Use selectNameFilter() to select
+ one of the filters you've given as the file dialog's default filter.
+
+ The file dialog has two view modes: \l{QFileDialog::}{List} and
+ \l{QFileDialog::}{Detail}.
+ \l{QFileDialog::}{List} presents the contents of the current directory
+ as a list of file and directory names. \l{QFileDialog::}{Detail} also
+ displays a list of file and directory names, but provides additional
+ information alongside each name, such as the file size and modification
+ date. Set the mode with setViewMode():
+
+ \snippet doc/src/snippets/code/src_gui_dialogs_qfiledialog.cpp 4
+
+ The last important function you will need to use when creating your
+ own file dialog is selectedFiles().
+
+ \snippet doc/src/snippets/code/src_gui_dialogs_qfiledialog.cpp 5
+
+ In the above example, a modal file dialog is created and shown. If
+ the user clicked OK, the file they selected is put in \c fileName.
+
+ The dialog's working directory can be set with setDirectory().
+ Each file in the current directory can be selected using
+ the selectFile() function.
+
+ The \l{dialogs/standarddialogs}{Standard Dialogs} example shows
+ how to use QFileDialog as well as other built-in Qt dialogs.
+
+ \sa QDir, QFileInfo, QFile, QPrintDialog, QColorDialog, QFontDialog, {Standard Dialogs Example},
+ {Application Example}
+*/
+
+/*!
+ \enum QFileDialog::AcceptMode
+
+ \value AcceptOpen
+ \value AcceptSave
+*/
+
+/*!
+ \enum QFileDialog::ViewMode
+
+ This enum describes the view mode of the file dialog; i.e. what
+ information about each file will be displayed.
+
+ \value Detail Displays an icon, a name, and details for each item in
+ the directory.
+ \value List Displays only an icon and a name for each item in the
+ directory.
+
+ \sa setViewMode()
+*/
+
+/*!
+ \enum QFileDialog::FileMode
+
+ This enum is used to indicate what the user may select in the file
+ dialog; i.e. what the dialog will return if the user clicks OK.
+
+ \value AnyFile The name of a file, whether it exists or not.
+ \value ExistingFile The name of a single existing file.
+ \value Directory The name of a directory. Both files and
+ directories are displayed.
+ \value ExistingFiles The names of zero or more existing files.
+
+ This value is obsolete since Qt 4.5:
+
+ \value DirectoryOnly Use \c Directory and setOption(ShowDirsOnly, true) instead.
+
+ \sa setFileMode()
+*/
+
+/*!
+ \enum QFileDialog::Option
+
+ \value ShowDirsOnly Only show directories in the file dialog. By
+ default both files and directories are shown. (Valid only in the
+ \l Directory file mode.)
+
+ \value DontResolveSymlinks Don't resolve symlinks in the file
+ dialog. By default symlinks are resolved.
+
+ \value DontConfirmOverwrite Don't ask for confirmation if an
+ existing file is selected. By default confirmation is requested.
+
+ \value DontUseNativeDialog Don't use the native file dialog. By
+ default, the native file dialog is used unless you use a subclass
+ of QFileDialog that contains the Q_OBJECT macro.
+
+ \value ReadOnly Indicates that the model is readonly.
+
+ \value HideNameFilterDetails Indicates if the file name filter details are
+ hidden or not.
+
+ \value DontUseSheet In previous versions of Qt, the static
+ functions would create a sheet by default if the static function
+ was given a parent. This is no longer supported and does nothing in Qt 4.5, The
+ static functions will always be an application modal dialog. If
+ you want to use sheets, use QFileDialog::open() instead.
+
+*/
+
+/*!
+ \enum QFileDialog::DialogLabel
+
+ \value LookIn
+ \value FileName
+ \value FileType
+ \value Accept
+ \value Reject
+*/
+
+/*!
+ \fn void QFileDialog::filesSelected(const QStringList &selected)
+
+ When the selection changes and the dialog is accepted, this signal is
+ emitted with the (possibly empty) list of \a selected files.
+
+ \sa currentChanged(), QDialog::Accepted
+*/
+
+
+/*!
+ \fn void QFileDialog::fileSelected(const QString &file)
+
+ When the selection changes and the dialog is accepted, this signal is
+ emitted with the (possibly empty) selected \a file.
+
+ \sa currentChanged(), QDialog::Accepted
+*/
+
+
+/*!
+ \fn void QFileDialog::currentChanged(const QString &path)
+
+ When the current file changes, this signal is emitted with the
+ new file name as the \a path parameter.
+
+ \sa filesSelected()
+*/
+
+/*!
+ \fn void QFileDialog::directoryEntered(const QString &directory)
+ \since 4.3
+
+ This signal is emitted when the user enters a \a directory.
+*/
+
+/*!
+ \fn void QFileDialog::filterSelected(const QString &filter)
+ \since 4.3
+
+ This signal is emitted when the user selects a \a filter.
+*/
+
+#if defined(Q_WS_WIN) || defined(Q_WS_MAC)
+bool Q_WIDGETS_EXPORT qt_use_native_dialogs = true; // for the benefit of testing tools, until we have a proper API
+#endif
+
+QT_BEGIN_INCLUDE_NAMESPACE
+#ifdef Q_WS_WIN
+#include <qwindowsstyle.h>
+#endif
+#include <qshortcut.h>
+#ifdef Q_WS_MAC
+#include <qmacstyle_mac.h>
+#endif
+QT_END_INCLUDE_NAMESPACE
+
+/*!
+ \fn QFileDialog::QFileDialog(QWidget *parent, Qt::WindowFlags flags)
+
+ Constructs a file dialog with the given \a parent and widget \a flags.
+*/
+QFileDialog::QFileDialog(QWidget *parent, Qt::WindowFlags f)
+ : QDialog(*new QFileDialogPrivate, parent, f)
+{
+ Q_D(QFileDialog);
+ d->init();
+ d->lineEdit()->selectAll();
+}
+
+/*!
+ Constructs a file dialog with the given \a parent and \a caption that
+ initially displays the contents of the specified \a directory.
+ The contents of the directory are filtered before being shown in the
+ dialog, using a semicolon-separated list of filters specified by
+ \a filter.
+*/
+QFileDialog::QFileDialog(QWidget *parent,
+ const QString &caption,
+ const QString &directory,
+ const QString &filter)
+ : QDialog(*new QFileDialogPrivate, parent, 0)
+{
+ Q_D(QFileDialog);
+ d->init(directory, filter, caption);
+ d->lineEdit()->selectAll();
+}
+
+/*!
+ \internal
+*/
+QFileDialog::QFileDialog(const QFileDialogArgs &args)
+ : QDialog(*new QFileDialogPrivate, args.parent, 0)
+{
+ Q_D(QFileDialog);
+ d->init(args.directory, args.filter, args.caption);
+ setFileMode(args.mode);
+ setOptions(args.options);
+ selectFile(args.selection);
+ d->lineEdit()->selectAll();
+}
+
+/*!
+ Destroys the file dialog.
+*/
+QFileDialog::~QFileDialog()
+{
+ Q_D(QFileDialog);
+#ifndef QT_NO_SETTINGS
+ QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
+ settings.beginGroup(QLatin1String("Qt"));
+ settings.setValue(QLatin1String("filedialog"), saveState());
+#endif
+ d->deleteNativeDialog_sys();
+}
+
+/*!
+ \since 4.3
+ Sets the \a urls that are located in the sidebar.
+
+ For instance:
+
+ \snippet doc/src/snippets/filedialogurls.cpp 0
+
+ The file dialog will then look like this:
+
+ \image filedialogurls.png
+
+ \sa sidebarUrls()
+*/
+void QFileDialog::setSidebarUrls(const QList<QUrl> &urls)
+{
+ Q_D(QFileDialog);
+ d->qFileDialogUi->sidebar->setUrls(urls);
+}
+
+/*!
+ \since 4.3
+ Returns a list of urls that are currently in the sidebar
+*/
+QList<QUrl> QFileDialog::sidebarUrls() const
+{
+ Q_D(const QFileDialog);
+ return d->qFileDialogUi->sidebar->urls();
+}
+
+static const qint32 QFileDialogMagic = 0xbe;
+
+const char *qt_file_dialog_filter_reg_exp =
+"^(.*)\\(([a-zA-Z0-9_.*? +;#\\-\\[\\]@\\{\\}/!<>\\$%&=^~:\\|]*)\\)$";
+
+/*!
+ \since 4.3
+ Saves the state of the dialog's layout, history and current directory.
+
+ Typically this is used in conjunction with QSettings to remember the size
+ for a future session. A version number is stored as part of the data.
+*/
+QByteArray QFileDialog::saveState() const
+{
+ Q_D(const QFileDialog);
+ int version = 3;
+ QByteArray data;
+ QDataStream stream(&data, QIODevice::WriteOnly);
+
+ stream << qint32(QFileDialogMagic);
+ stream << qint32(version);
+ stream << d->qFileDialogUi->splitter->saveState();
+ stream << d->qFileDialogUi->sidebar->urls();
+ stream << history();
+ stream << *lastVisitedDir();
+ stream << d->qFileDialogUi->treeView->header()->saveState();
+ stream << qint32(viewMode());
+ return data;
+}
+
+/*!
+ \since 4.3
+ Restores the dialogs's layout, history and current directory to the \a state specified.
+
+ Typically this is used in conjunction with QSettings to restore the size
+ from a past session.
+
+ Returns false if there are errors
+*/
+bool QFileDialog::restoreState(const QByteArray &state)
+{
+ Q_D(QFileDialog);
+ int version = 3;
+ QByteArray sd = state;
+ QDataStream stream(&sd, QIODevice::ReadOnly);
+ if (stream.atEnd())
+ return false;
+ QByteArray splitterState;
+ QByteArray headerData;
+ QList<QUrl> bookmarks;
+ QStringList history;
+ QString currentDirectory;
+ qint32 marker;
+ qint32 v;
+ qint32 viewMode;
+ stream >> marker;
+ stream >> v;
+ if (marker != QFileDialogMagic || v != version)
+ return false;
+
+ stream >> splitterState
+ >> bookmarks
+ >> history
+ >> currentDirectory
+ >> headerData
+ >> viewMode;
+
+ if (!d->qFileDialogUi->splitter->restoreState(splitterState))
+ return false;
+ QList<int> list = d->qFileDialogUi->splitter->sizes();
+ if (list.count() >= 2 && list.at(0) == 0 && list.at(1) == 0) {
+ for (int i = 0; i < list.count(); ++i)
+ list[i] = d->qFileDialogUi->splitter->widget(i)->sizeHint().width();
+ d->qFileDialogUi->splitter->setSizes(list);
+ }
+
+ d->qFileDialogUi->sidebar->setUrls(bookmarks);
+ while (history.count() > 5)
+ history.pop_front();
+ setHistory(history);
+ setDirectory(lastVisitedDir()->isEmpty() ? currentDirectory : *lastVisitedDir());
+ if (!d->qFileDialogUi->treeView->header()->restoreState(headerData))
+ return false;
+
+ setViewMode(ViewMode(viewMode));
+ return true;
+}
+
+/*!
+ \reimp
+*/
+void QFileDialog::changeEvent(QEvent *e)
+{
+ Q_D(QFileDialog);
+ if (e->type() == QEvent::LanguageChange) {
+ d->retranslateWindowTitle();
+ d->retranslateStrings();
+ }
+ QDialog::changeEvent(e);
+}
+
+QFileDialogPrivate::QFileDialogPrivate()
+ :
+#ifndef QT_NO_PROXYMODEL
+ proxyModel(0),
+#endif
+ model(0),
+ fileMode(QFileDialog::AnyFile),
+ acceptMode(QFileDialog::AcceptOpen),
+ currentHistoryLocation(-1),
+ renameAction(0),
+ deleteAction(0),
+ showHiddenAction(0),
+ useDefaultCaption(true),
+ defaultFileTypes(true),
+ fileNameLabelExplicitlySat(false),
+ nativeDialogInUse(false),
+#ifdef Q_WS_MAC
+ mDelegate(0),
+#ifndef QT_MAC_USE_COCOA
+ mDialog(0),
+ mDialogStarted(false),
+ mDialogClosed(true),
+#endif
+#endif
+ qFileDialogUi(0)
+{
+}
+
+QFileDialogPrivate::~QFileDialogPrivate()
+{
+}
+
+void QFileDialogPrivate::retranslateWindowTitle()
+{
+ Q_Q(QFileDialog);
+ if (!useDefaultCaption || setWindowTitle != q->windowTitle())
+ return;
+ if (acceptMode == QFileDialog::AcceptOpen) {
+ if (fileMode == QFileDialog::DirectoryOnly || fileMode == QFileDialog::Directory)
+ q->setWindowTitle(QFileDialog::tr("Find Directory"));
+ else
+ q->setWindowTitle(QFileDialog::tr("Open"));
+ } else
+ q->setWindowTitle(QFileDialog::tr("Save As"));
+
+ setWindowTitle = q->windowTitle();
+}
+
+void QFileDialogPrivate::setLastVisitedDirectory(const QString &dir)
+{
+ *lastVisitedDir() = dir;
+}
+
+void QFileDialogPrivate::retranslateStrings()
+{
+ Q_Q(QFileDialog);
+ /* WIDGETS */
+ if (defaultFileTypes)
+ q->setNameFilter(QFileDialog::tr("All Files (*)"));
+
+ QList<QAction*> actions = qFileDialogUi->treeView->header()->actions();
+ QAbstractItemModel *abstractModel = model;
+#ifndef QT_NO_PROXYMODEL
+ if (proxyModel)
+ abstractModel = proxyModel;
+#endif
+ int total = qMin(abstractModel->columnCount(QModelIndex()), actions.count() + 1);
+ for (int i = 1; i < total; ++i) {
+ actions.at(i - 1)->setText(QFileDialog::tr("Show ") + abstractModel->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString());
+ }
+
+ /* MENU ACTIONS */
+ renameAction->setText(QFileDialog::tr("&Rename"));
+ deleteAction->setText(QFileDialog::tr("&Delete"));
+ showHiddenAction->setText(QFileDialog::tr("Show &hidden files"));
+ newFolderAction->setText(QFileDialog::tr("&New Folder"));
+ qFileDialogUi->retranslateUi(q);
+
+ if (!fileNameLabelExplicitlySat){
+ if (fileMode == QFileDialog::DirectoryOnly || fileMode == QFileDialog::Directory) {
+ q->setLabelText(QFileDialog::FileName, QFileDialog::tr("Directory:"));
+ } else {
+ q->setLabelText(QFileDialog::FileName, QFileDialog::tr("File &name:"));
+ }
+ fileNameLabelExplicitlySat = false;
+ }
+}
+
+void QFileDialogPrivate::emitFilesSelected(const QStringList &files)
+{
+ Q_Q(QFileDialog);
+ emit q->filesSelected(files);
+ if (files.count() == 1)
+ emit q->fileSelected(files.first());
+}
+
+bool QFileDialogPrivate::canBeNativeDialog()
+{
+ Q_Q(QFileDialog);
+ if (nativeDialogInUse)
+ return true;
+ if (q->testAttribute(Qt::WA_DontShowOnScreen))
+ return false;
+ if (opts & QFileDialog::DontUseNativeDialog)
+ return false;
+
+ QLatin1String staticName(QFileDialog::staticMetaObject.className());
+ QLatin1String dynamicName(q->metaObject()->className());
+ return (staticName == dynamicName);
+}
+
+/*!
+ \since 4.5
+ Sets the given \a option to be enabled if \a on is true; otherwise,
+ clears the given \a option.
+
+ \sa options, testOption()
+*/
+void QFileDialog::setOption(Option option, bool on)
+{
+ Q_D(QFileDialog);
+ if (!(d->opts & option) != !on)
+ setOptions(d->opts ^ option);
+}
+
+/*!
+ \since 4.5
+
+ Returns true if the given \a option is enabled; otherwise, returns
+ false.
+
+ \sa options, setOption()
+*/
+bool QFileDialog::testOption(Option option) const
+{
+ Q_D(const QFileDialog);
+ return (d->opts & option) != 0;
+}
+
+/*!
+ \property QFileDialog::options
+ \brief the various options that affect the look and feel of the dialog
+ \since 4.5
+
+ By default, all options are disabled.
+
+ Options should be set before showing the dialog. Setting them while the
+ dialog is visible is not guaranteed to have an immediate effect on the
+ dialog (depending on the option and on the platform).
+
+ \sa setOption(), testOption()
+*/
+void QFileDialog::setOptions(Options options)
+{
+ Q_D(QFileDialog);
+
+ Options changed = (options ^ d->opts);
+ if (!changed)
+ return;
+
+ d->opts = options;
+ if (changed & DontResolveSymlinks)
+ d->model->setResolveSymlinks(!(options & DontResolveSymlinks));
+ if (changed & ReadOnly) {
+ bool ro = (options & ReadOnly);
+ d->model->setReadOnly(ro);
+ d->qFileDialogUi->newFolderButton->setEnabled(!ro);
+ d->renameAction->setEnabled(!ro);
+ d->deleteAction->setEnabled(!ro);
+ }
+ if (changed & HideNameFilterDetails)
+ setNameFilters(d->nameFilters);
+
+ if (changed & ShowDirsOnly)
+ setFilter((options & ShowDirsOnly) ? filter() & ~QDir::Files : filter() | QDir::Files);
+}
+
+QFileDialog::Options QFileDialog::options() const
+{
+ Q_D(const QFileDialog);
+ return d->opts;
+}
+
+/*!
+ \overload
+
+ \since 4.5
+
+ This function connects one of its signals to the slot specified by \a receiver
+ and \a member. The specific signal depends is filesSelected() if fileMode is
+ ExistingFiles and fileSelected() if fileMode is anything else.
+
+ The signal will be disconnected from the slot when the dialog is closed.
+*/
+void QFileDialog::open(QObject *receiver, const char *member)
+{
+ Q_D(QFileDialog);
+ const char *signal = (fileMode() == ExistingFiles) ? SIGNAL(filesSelected(QStringList))
+ : SIGNAL(fileSelected(QString));
+ connect(this, signal, receiver, member);
+ d->signalToDisconnectOnClose = signal;
+ d->receiverToDisconnectOnClose = receiver;
+ d->memberToDisconnectOnClose = member;
+
+ QDialog::open();
+}
+
+
+/*!
+ \reimp
+*/
+void QFileDialog::setVisible(bool visible)
+{
+ Q_D(QFileDialog);
+ if (visible){
+ if (testAttribute(Qt::WA_WState_ExplicitShowHide) && !testAttribute(Qt::WA_WState_Hidden))
+ return;
+ } else if (testAttribute(Qt::WA_WState_ExplicitShowHide) && testAttribute(Qt::WA_WState_Hidden))
+ return;
+
+ if (d->canBeNativeDialog()){
+ if (d->setVisible_sys(visible)){
+ d->nativeDialogInUse = true;
+ // Set WA_DontShowOnScreen so that QDialog::setVisible(visible) below
+ // updates the state correctly, but skips showing the non-native version:
+ setAttribute(Qt::WA_DontShowOnScreen);
+#ifndef QT_NO_FSCOMPLETER
+ //So the completer don't try to complete and therefore to show a popup
+ d->completer->setModel(0);
+#endif
+ } else {
+ d->nativeDialogInUse = false;
+ setAttribute(Qt::WA_DontShowOnScreen, false);
+#ifndef QT_NO_FSCOMPLETER
+ if (d->proxyModel != 0)
+ d->completer->setModel(d->proxyModel);
+ else
+ d->completer->setModel(d->model);
+#endif
+ }
+ }
+
+ if (!d->nativeDialogInUse)
+ d->qFileDialogUi->fileNameEdit->setFocus();
+
+ QDialog::setVisible(visible);
+}
+
+/*!
+ \internal
+ set the directory to url
+*/
+void QFileDialogPrivate::_q_goToUrl(const QUrl &url)
+{
+ //The shortcut in the side bar may have a parent that is not fetched yet (e.g. an hidden file)
+ //so we force the fetching
+ QFileSystemModelPrivate::QFileSystemNode *node = model->d_func()->node(url.toLocalFile(), true);
+ QModelIndex idx = model->d_func()->index(node);
+ _q_enterDirectory(idx);
+}
+
+/*!
+ \fn void QFileDialog::setDirectory(const QDir &directory)
+
+ \overload
+*/
+
+/*!
+ Sets the file dialog's current \a directory.
+*/
+void QFileDialog::setDirectory(const QString &directory)
+{
+ Q_D(QFileDialog);
+ QString newDirectory = directory;
+ QFileInfo info(directory);
+ //we remove .. and . from the given path if exist
+ if (!directory.isEmpty())
+ newDirectory = QDir::cleanPath(directory);
+
+ if (!directory.isEmpty() && newDirectory.isEmpty())
+ return;
+
+ d->setLastVisitedDirectory(newDirectory);
+
+ if (d->nativeDialogInUse){
+ d->setDirectory_sys(newDirectory);
+ return;
+ }
+ if (d->rootPath() == newDirectory)
+ return;
+ QModelIndex root = d->model->setRootPath(newDirectory);
+ d->qFileDialogUi->newFolderButton->setEnabled(d->model->flags(root) & Qt::ItemIsDropEnabled);
+ if (root != d->rootIndex()) {
+#ifndef QT_NO_FSCOMPLETER
+ if (directory.endsWith(QLatin1Char('/')))
+ d->completer->setCompletionPrefix(newDirectory);
+ else
+ d->completer->setCompletionPrefix(newDirectory + QLatin1Char('/'));
+#endif
+ d->setRootIndex(root);
+ }
+ d->qFileDialogUi->listView->selectionModel()->clear();
+}
+
+/*!
+ Returns the directory currently being displayed in the dialog.
+*/
+QDir QFileDialog::directory() const
+{
+ Q_D(const QFileDialog);
+ return QDir(d->nativeDialogInUse ? d->directory_sys() : d->rootPath());
+}
+
+/*!
+ Selects the given \a filename in the file dialog.
+
+ \sa selectedFiles()
+*/
+void QFileDialog::selectFile(const QString &filename)
+{
+ Q_D(QFileDialog);
+ if (filename.isEmpty())
+ return;
+
+ if (d->nativeDialogInUse){
+ d->selectFile_sys(filename);
+ return;
+ }
+
+ if (!QDir::isRelativePath(filename)) {
+ QFileInfo info(filename);
+ QString filenamePath = info.absoluteDir().path();
+
+ if (d->model->rootPath() != filenamePath)
+ setDirectory(filenamePath);
+ }
+
+ QModelIndex index = d->model->index(filename);
+ QString file;
+ if (!index.isValid()) {
+ // save as dialog where we want to input a default value
+ QString text = 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);
+ }
+ file = text;
+ } else {
+ file = index.data().toString();
+ }
+ d->qFileDialogUi->listView->selectionModel()->clear();
+ if (!isVisible() || !d->lineEdit()->hasFocus())
+ d->lineEdit()->setText(file);
+}
+
+#ifdef Q_OS_UNIX
+Q_AUTOTEST_EXPORT QString qt_tildeExpansion(const QString &path, bool *expanded = 0)
+{
+ if (expanded != 0)
+ *expanded = false;
+ if (!path.startsWith(QLatin1Char('~')))
+ return path;
+ QString ret = path;
+ QStringList tokens = ret.split(QDir::separator());
+ if (tokens.first() == QLatin1String("~")) {
+ ret.replace(0, 1, QDir::homePath());
+ } else {
+ QString userName = tokens.first();
+ userName.remove(0, 1);
+#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_OPENBSD)
+ passwd pw;
+ passwd *tmpPw;
+ char buf[200];
+ const int bufSize = sizeof(buf);
+ int err = getpwnam_r(userName.toLocal8Bit().constData(), &pw, buf, bufSize, &tmpPw);
+ if (err || !tmpPw)
+ return ret;
+ const QString homePath = QString::fromLocal8Bit(pw.pw_dir);
+#else
+ passwd *pw = getpwnam(userName.toLocal8Bit().constData());
+ if (!pw)
+ return ret;
+ const QString homePath = QString::fromLocal8Bit(pw->pw_dir);
+#endif
+ ret.replace(0, tokens.first().length(), homePath);
+ }
+ if (expanded != 0)
+ *expanded = true;
+ return ret;
+}
+#endif
+
+/**
+ Returns the text in the line edit which can be one or more file names
+ */
+QStringList QFileDialogPrivate::typedFiles() const
+{
+ Q_Q(const QFileDialog);
+ QStringList files;
+ QString editText = lineEdit()->text();
+ if (!editText.contains(QLatin1Char('"'))) {
+#ifdef Q_OS_UNIX
+ const QString prefix = q->directory().absolutePath() + QDir::separator();
+ if (QFile::exists(prefix + editText))
+ files << editText;
+ else
+ files << qt_tildeExpansion(editText);
+#else
+ files << editText;
+#endif
+ } else {
+ // " is used to separate files like so: "file1" "file2" "file3" ...
+ // ### need escape character for filenames with quotes (")
+ QStringList tokens = editText.split(QLatin1Char('\"'));
+ for (int i=0; i<tokens.size(); ++i) {
+ if ((i % 2) == 0)
+ continue; // Every even token is a separator
+#ifdef Q_OS_UNIX
+ const QString token = tokens.at(i);
+ const QString prefix = q->directory().absolutePath() + QDir::separator();
+ if (QFile::exists(prefix + token))
+ files << token;
+ else
+ files << qt_tildeExpansion(token);
+#else
+ files << toInternal(tokens.at(i));
+#endif
+ }
+ }
+ return addDefaultSuffixToFiles(files);
+}
+
+QStringList QFileDialogPrivate::addDefaultSuffixToFiles(const QStringList filesToFix) const
+{
+ QStringList files;
+ for (int i=0; i<filesToFix.size(); ++i) {
+ QString name = toInternal(filesToFix.at(i));
+ QFileInfo info(name);
+ // if the filename has no suffix, add the default suffix
+ if (!defaultSuffix.isEmpty() && !info.isDir() && name.lastIndexOf(QLatin1Char('.')) == -1)
+ name += QLatin1Char('.') + defaultSuffix;
+ if (info.isAbsolute()) {
+ files.append(name);
+ } else {
+ // at this point the path should only have Qt path separators.
+ // This check is needed since we might be at the root directory
+ // and on Windows it already ends with slash.
+ QString path = rootPath();
+ if (!path.endsWith(QLatin1Char('/')))
+ path += QLatin1Char('/');
+ path += name;
+ files.append(path);
+ }
+ }
+ return files;
+}
+
+
+/*!
+ Returns a list of strings containing the absolute paths of the
+ selected files in the dialog. If no files are selected, or
+ the mode is not ExistingFiles or ExistingFile, selectedFiles() contains the current path in the viewport.
+
+ \sa selectedNameFilter(), selectFile()
+*/
+QStringList QFileDialog::selectedFiles() const
+{
+ Q_D(const QFileDialog);
+ if (d->nativeDialogInUse)
+ return d->addDefaultSuffixToFiles(d->selectedFiles_sys());
+
+ QModelIndexList indexes = d->qFileDialogUi->listView->selectionModel()->selectedRows();
+ QStringList files;
+ for (int i = 0; i < indexes.count(); ++i)
+ files.append(indexes.at(i).data(QFileSystemModel::FilePathRole).toString());
+
+ if (files.isEmpty() && !d->lineEdit()->text().isEmpty())
+ files = d->typedFiles();
+
+ if (files.isEmpty() && !(d->fileMode == ExistingFile || d->fileMode == ExistingFiles))
+ files.append(d->rootIndex().data(QFileSystemModel::FilePathRole).toString());
+ return files;
+}
+
+/*
+ Makes a list of filters from ;;-separated text.
+ Used by the mac and windows implementations
+*/
+QStringList qt_make_filter_list(const QString &filter)
+{
+ QString f(filter);
+
+ if (f.isEmpty())
+ return QStringList();
+
+ QString sep(QLatin1String(";;"));
+ int i = f.indexOf(sep, 0);
+ if (i == -1) {
+ if (f.indexOf(QLatin1Char('\n'), 0) != -1) {
+ sep = QLatin1Char('\n');
+ i = f.indexOf(sep, 0);
+ }
+ }
+
+ return f.split(sep);
+}
+
+/*!
+ \since 4.4
+
+ Sets the filter used in the file dialog to the given \a filter.
+
+ If \a filter contains a pair of parentheses containing one or more
+ of \bold{anything*something}, separated by spaces, then only the
+ text contained in the parentheses is used as the filter. This means
+ that these calls are all equivalent:
+
+ \snippet doc/src/snippets/code/src_gui_dialogs_qfiledialog.cpp 6
+
+ \sa setNameFilters()
+*/
+void QFileDialog::setNameFilter(const QString &filter)
+{
+ setNameFilters(qt_make_filter_list(filter));
+}
+
+/*!
+ \obsolete
+
+ Use setNameFilter() instead.
+*/
+void QFileDialog::setFilter(const QString &filter)
+{
+ setNameFilter(filter);
+}
+
+/*!
+ \property QFileDialog::nameFilterDetailsVisible
+ \obsolete
+ \brief This property holds whether the filter details is shown or not.
+ \since 4.4
+
+ When this property is true (the default), the filter details are shown
+ in the combo box. When the property is set to false, these are hidden.
+
+ Use setOption(HideNameFilterDetails, !\e enabled) or
+ !testOption(HideNameFilterDetails).
+*/
+void QFileDialog::setNameFilterDetailsVisible(bool enabled)
+{
+ setOption(HideNameFilterDetails, !enabled);
+}
+
+bool QFileDialog::isNameFilterDetailsVisible() const
+{
+ return !testOption(HideNameFilterDetails);
+}
+
+
+/*
+ Strip the filters by removing the details, e.g. (*.*).
+*/
+QStringList qt_strip_filters(const QStringList &filters)
+{
+ QStringList strippedFilters;
+ QRegExp r(QString::fromLatin1(qt_file_dialog_filter_reg_exp));
+ for (int i = 0; i < filters.count(); ++i) {
+ QString filterName;
+ int index = r.indexIn(filters[i]);
+ if (index >= 0)
+ filterName = r.cap(1);
+ strippedFilters.append(filterName.simplified());
+ }
+ return strippedFilters;
+}
+
+
+/*!
+ \since 4.4
+
+ Sets the \a filters used in the file dialog.
+
+ \snippet doc/src/snippets/code/src_gui_dialogs_qfiledialog.cpp 7
+*/
+void QFileDialog::setNameFilters(const QStringList &filters)
+{
+ Q_D(QFileDialog);
+ d->defaultFileTypes = (filters == QStringList(QFileDialog::tr("All Files (*)")));
+ QStringList cleanedFilters;
+ for (int i = 0; i < filters.count(); ++i) {
+ cleanedFilters << filters[i].simplified();
+ }
+ d->nameFilters = cleanedFilters;
+
+ if (d->nativeDialogInUse){
+ d->setNameFilters_sys(cleanedFilters);
+ return;
+ }
+
+ d->qFileDialogUi->fileTypeCombo->clear();
+ if (cleanedFilters.isEmpty())
+ return;
+
+ if (testOption(HideNameFilterDetails))
+ d->qFileDialogUi->fileTypeCombo->addItems(qt_strip_filters(cleanedFilters));
+ else
+ d->qFileDialogUi->fileTypeCombo->addItems(cleanedFilters);
+
+ d->_q_useNameFilter(0);
+}
+
+/*!
+ \obsolete
+
+ Use setNameFilters() instead.
+*/
+void QFileDialog::setFilters(const QStringList &filters)
+{
+ setNameFilters(filters);
+}
+
+/*!
+ \since 4.4
+
+ Returns the file type filters that are in operation on this file
+ dialog.
+*/
+QStringList QFileDialog::nameFilters() const
+{
+ return d_func()->nameFilters;
+}
+
+/*!
+ \obsolete
+
+ Use nameFilters() instead.
+*/
+
+QStringList QFileDialog::filters() const
+{
+ return nameFilters();
+}
+
+/*!
+ \since 4.4
+
+ Sets the current file type \a filter. Multiple filters can be
+ passed in \a filter by separating them with semicolons or spaces.
+
+ \sa setNameFilter(), setNameFilters(), selectedNameFilter()
+*/
+void QFileDialog::selectNameFilter(const QString &filter)
+{
+ Q_D(QFileDialog);
+ if (d->nativeDialogInUse) {
+ d->selectNameFilter_sys(filter);
+ return;
+ }
+ int i;
+ if (testOption(HideNameFilterDetails)) {
+ i = d->qFileDialogUi->fileTypeCombo->findText(qt_strip_filters(qt_make_filter_list(filter)).first());
+ } else {
+ i = d->qFileDialogUi->fileTypeCombo->findText(filter);
+ }
+ if (i >= 0) {
+ d->qFileDialogUi->fileTypeCombo->setCurrentIndex(i);
+ d->_q_useNameFilter(d->qFileDialogUi->fileTypeCombo->currentIndex());
+ }
+}
+
+/*!
+ \obsolete
+
+ Use selectNameFilter() instead.
+*/
+
+void QFileDialog::selectFilter(const QString &filter)
+{
+ selectNameFilter(filter);
+}
+
+/*!
+ \since 4.4
+
+ Returns the filter that the user selected in the file dialog.
+
+ \sa selectedFiles()
+*/
+QString QFileDialog::selectedNameFilter() const
+{
+ Q_D(const QFileDialog);
+ if (d->nativeDialogInUse)
+ return d->selectedNameFilter_sys();
+
+ return d->qFileDialogUi->fileTypeCombo->currentText();
+}
+
+/*!
+ \obsolete
+
+ Use selectedNameFilter() instead.
+*/
+QString QFileDialog::selectedFilter() const
+{
+ return selectedNameFilter();
+}
+
+/*!
+ \since 4.4
+
+ Returns the filter that is used when displaying files.
+
+ \sa setFilter()
+*/
+QDir::Filters QFileDialog::filter() const
+{
+ Q_D(const QFileDialog);
+ return d->model->filter();
+}
+
+/*!
+ \since 4.4
+
+ Sets the filter used by the model to \a filters. The filter is used
+ to specify the kind of files that should be shown.
+
+ \sa filter()
+*/
+
+void QFileDialog::setFilter(QDir::Filters filters)
+{
+ Q_D(QFileDialog);
+ d->model->setFilter(filters);
+ if (d->nativeDialogInUse){
+ d->setFilter_sys();
+ return;
+ }
+
+ d->showHiddenAction->setChecked((filters & QDir::Hidden));
+}
+
+/*!
+ \property QFileDialog::viewMode
+ \brief the way files and directories are displayed in the dialog
+
+ By default, the \c Detail mode is used to display information about
+ files and directories.
+
+ \sa ViewMode
+*/
+void QFileDialog::setViewMode(QFileDialog::ViewMode mode)
+{
+ Q_D(QFileDialog);
+ if (mode == Detail)
+ d->_q_showDetailsView();
+ else
+ d->_q_showListView();
+}
+
+QFileDialog::ViewMode QFileDialog::viewMode() const
+{
+ Q_D(const QFileDialog);
+ return (d->qFileDialogUi->stackedWidget->currentWidget() == d->qFileDialogUi->listView->parent() ? QFileDialog::List : QFileDialog::Detail);
+}
+
+/*!
+ \property QFileDialog::fileMode
+ \brief the file mode of the dialog
+
+ The file mode defines the number and type of items that the user is
+ expected to select in the dialog.
+
+ By default, this property is set to AnyFile.
+
+ This function will set the labels for the FileName and
+ \l{QFileDialog::}{Accept} \l{DialogLabel}s. It is possible to set
+ custom text after the call to setFileMode().
+
+ \sa FileMode
+*/
+void QFileDialog::setFileMode(QFileDialog::FileMode mode)
+{
+ Q_D(QFileDialog);
+ d->fileMode = mode;
+ d->retranslateWindowTitle();
+
+ // keep ShowDirsOnly option in sync with fileMode (BTW, DirectoryOnly is obsolete)
+ setOption(ShowDirsOnly, mode == DirectoryOnly);
+
+ // set selection mode and behavior
+ QAbstractItemView::SelectionMode selectionMode;
+ if (mode == QFileDialog::ExistingFiles)
+ selectionMode = QAbstractItemView::ExtendedSelection;
+ else
+ selectionMode = QAbstractItemView::SingleSelection;
+ d->qFileDialogUi->listView->setSelectionMode(selectionMode);
+ d->qFileDialogUi->treeView->setSelectionMode(selectionMode);
+ // set filter
+ d->model->setFilter(d->filterForMode(filter()));
+ // setup file type for directory
+ QString buttonText = (d->acceptMode == AcceptOpen ? tr("&Open") : tr("&Save"));
+ if (mode == DirectoryOnly || mode == Directory) {
+ d->qFileDialogUi->fileTypeCombo->clear();
+ d->qFileDialogUi->fileTypeCombo->addItem(tr("Directories"));
+ d->qFileDialogUi->fileTypeCombo->setEnabled(false);
+
+ if (!d->fileNameLabelExplicitlySat){
+ setLabelText(FileName, tr("Directory:"));
+ d->fileNameLabelExplicitlySat = false;
+ }
+ buttonText = tr("&Choose");
+ } else {
+ if (!d->fileNameLabelExplicitlySat){
+ setLabelText(FileName, tr("File &name:"));
+ d->fileNameLabelExplicitlySat = false;
+ }
+ }
+ setLabelText(Accept, buttonText);
+ if (d->nativeDialogInUse){
+ d->setFilter_sys();
+ return;
+ }
+
+ d->qFileDialogUi->fileTypeCombo->setEnabled(!testOption(ShowDirsOnly));
+ d->_q_updateOkButton();
+}
+
+QFileDialog::FileMode QFileDialog::fileMode() const
+{
+ Q_D(const QFileDialog);
+ return d->fileMode;
+}
+
+/*!
+ \property QFileDialog::acceptMode
+ \brief the accept mode of the dialog
+
+ The action mode defines whether the dialog is for opening or saving files.
+
+ By default, this property is set to \l{AcceptOpen}.
+
+ \sa AcceptMode
+*/
+void QFileDialog::setAcceptMode(QFileDialog::AcceptMode mode)
+{
+ Q_D(QFileDialog);
+ d->acceptMode = mode;
+ bool directoryMode = (d->fileMode == Directory || d->fileMode == DirectoryOnly);
+ QDialogButtonBox::StandardButton button = (mode == AcceptOpen ? QDialogButtonBox::Open : QDialogButtonBox::Save);
+ d->qFileDialogUi->buttonBox->setStandardButtons(button | QDialogButtonBox::Cancel);
+ d->qFileDialogUi->buttonBox->button(button)->setEnabled(false);
+ d->_q_updateOkButton();
+ if (mode == AcceptOpen && directoryMode)
+ setLabelText(Accept, tr("&Choose"));
+ else
+ setLabelText(Accept, (mode == AcceptOpen ? tr("&Open") : tr("&Save")));
+ if (mode == AcceptSave) {
+ d->qFileDialogUi->lookInCombo->setEditable(false);
+ }
+ d->retranslateWindowTitle();
+#if defined(Q_WS_MAC)
+ d->deleteNativeDialog_sys();
+ setAttribute(Qt::WA_DontShowOnScreen, false);
+#endif
+}
+
+/*
+ Returns the file system model index that is the root index in the
+ views
+*/
+QModelIndex QFileDialogPrivate::rootIndex() const {
+ return mapToSource(qFileDialogUi->listView->rootIndex());
+}
+
+QAbstractItemView *QFileDialogPrivate::currentView() const {
+ if (!qFileDialogUi->stackedWidget)
+ return 0;
+ if (qFileDialogUi->stackedWidget->currentWidget() == qFileDialogUi->listView->parent())
+ return qFileDialogUi->listView;
+ return qFileDialogUi->treeView;
+}
+
+QLineEdit *QFileDialogPrivate::lineEdit() const {
+ return (QLineEdit*)qFileDialogUi->fileNameEdit;
+}
+
+/*
+ Sets the view root index to be the file system model index
+*/
+void QFileDialogPrivate::setRootIndex(const QModelIndex &index) const {
+ Q_ASSERT(index.isValid() ? index.model() == model : true);
+ QModelIndex idx = mapFromSource(index);
+ qFileDialogUi->treeView->setRootIndex(idx);
+ qFileDialogUi->listView->setRootIndex(idx);
+}
+/*
+ Select a file system model index
+ returns the index that was selected (or not depending upon sortfilterproxymodel)
+*/
+QModelIndex QFileDialogPrivate::select(const QModelIndex &index) const {
+ Q_ASSERT(index.isValid() ? index.model() == model : true);
+
+ QModelIndex idx = mapFromSource(index);
+ if (idx.isValid() && !qFileDialogUi->listView->selectionModel()->isSelected(idx))
+ qFileDialogUi->listView->selectionModel()->select(idx,
+ QItemSelectionModel::Select | QItemSelectionModel::Rows);
+ return idx;
+}
+
+QFileDialog::AcceptMode QFileDialog::acceptMode() const
+{
+ Q_D(const QFileDialog);
+ return d->acceptMode;
+}
+
+/*!
+ \property QFileDialog::readOnly
+ \obsolete
+ \brief Whether the filedialog is read-only
+
+ If this property is set to false, the file dialog will allow renaming,
+ and deleting of files and directories and creating directories.
+
+ Use setOption(ReadOnly, \e enabled) or testOption(ReadOnly) instead.
+*/
+void QFileDialog::setReadOnly(bool enabled)
+{
+ setOption(ReadOnly, enabled);
+}
+
+bool QFileDialog::isReadOnly() const
+{
+ return testOption(ReadOnly);
+}
+
+/*!
+ \property QFileDialog::resolveSymlinks
+ \obsolete
+ \brief whether the filedialog should resolve shortcuts
+
+ If this property is set to true, the file dialog will resolve
+ shortcuts or symbolic links.
+
+ Use setOption(DontResolveSymlinks, !\a enabled) or
+ !testOption(DontResolveSymlinks).
+*/
+void QFileDialog::setResolveSymlinks(bool enabled)
+{
+ setOption(DontResolveSymlinks, !enabled);
+}
+
+bool QFileDialog::resolveSymlinks() const
+{
+ return !testOption(DontResolveSymlinks);
+}
+
+/*!
+ \property QFileDialog::confirmOverwrite
+ \obsolete
+ \brief whether the filedialog should ask before accepting a selected file,
+ when the accept mode is AcceptSave
+
+ Use setOption(DontConfirmOverwrite, !\e enabled) or
+ !testOption(DontConfirmOverwrite) instead.
+*/
+void QFileDialog::setConfirmOverwrite(bool enabled)
+{
+ setOption(DontConfirmOverwrite, !enabled);
+}
+
+bool QFileDialog::confirmOverwrite() const
+{
+ return !testOption(DontConfirmOverwrite);
+}
+
+/*!
+ \property QFileDialog::defaultSuffix
+ \brief suffix added to the filename if no other suffix was specified
+
+ This property specifies a string that will be added to the
+ filename if it has no suffix already. The suffix is typically
+ used to indicate the file type (e.g. "txt" indicates a text
+ file).
+*/
+void QFileDialog::setDefaultSuffix(const QString &suffix)
+{
+ Q_D(QFileDialog);
+ d->defaultSuffix = suffix;
+}
+
+QString QFileDialog::defaultSuffix() const
+{
+ Q_D(const QFileDialog);
+ return d->defaultSuffix;
+}
+
+/*!
+ Sets the browsing history of the filedialog to contain the given
+ \a paths.
+*/
+void QFileDialog::setHistory(const QStringList &paths)
+{
+ Q_D(QFileDialog);
+ d->qFileDialogUi->lookInCombo->setHistory(paths);
+}
+
+void QFileDialogComboBox::setHistory(const QStringList &paths)
+{
+ m_history = paths;
+ // Only populate the first item, showPopup will populate the rest if needed
+ QList<QUrl> list;
+ QModelIndex idx = d_ptr->model->index(d_ptr->rootPath());
+ //On windows the popup display the "C:\", convert to nativeSeparators
+ QUrl url = QUrl::fromLocalFile(QDir::toNativeSeparators(idx.data(QFileSystemModel::FilePathRole).toString()));
+ if (url.isValid())
+ list.append(url);
+ urlModel->setUrls(list);
+}
+
+/*!
+ Returns the browsing history of the filedialog as a list of paths.
+*/
+QStringList QFileDialog::history() const
+{
+ Q_D(const QFileDialog);
+ QStringList currentHistory = d->qFileDialogUi->lookInCombo->history();
+ //On windows the popup display the "C:\", convert to nativeSeparators
+ QString newHistory = QDir::toNativeSeparators(d->rootIndex().data(QFileSystemModel::FilePathRole).toString());
+ if (!currentHistory.contains(newHistory))
+ currentHistory << newHistory;
+ return currentHistory;
+}
+
+/*!
+ Sets the item delegate used to render items in the views in the
+ file dialog to the given \a delegate.
+
+ \warning You should not share the same instance of a delegate between views.
+ Doing so can cause incorrect or unintuitive editing behavior since each
+ view connected to a given delegate may receive the \l{QAbstractItemDelegate::}{closeEditor()}
+ signal, and attempt to access, modify or close an editor that has already been closed.
+
+ Note that the model used is QFileSystemModel. It has custom item data roles, which is
+ described by the \l{QFileSystemModel::}{Roles} enum. You can use a QFileIconProvider if
+ you only want custom icons.
+
+ \sa itemDelegate(), setIconProvider(), QFileSystemModel
+*/
+void QFileDialog::setItemDelegate(QAbstractItemDelegate *delegate)
+{
+ Q_D(QFileDialog);
+ d->qFileDialogUi->listView->setItemDelegate(delegate);
+ d->qFileDialogUi->treeView->setItemDelegate(delegate);
+}
+
+/*!
+ Returns the item delegate used to render the items in the views in the filedialog.
+*/
+QAbstractItemDelegate *QFileDialog::itemDelegate() const
+{
+ Q_D(const QFileDialog);
+ return d->qFileDialogUi->listView->itemDelegate();
+}
+
+/*!
+ Sets the icon provider used by the filedialog to the specified \a provider.
+*/
+void QFileDialog::setIconProvider(QFileIconProvider *provider)
+{
+ Q_D(QFileDialog);
+ d->model->setIconProvider(provider);
+ //It forces the refresh of all entries in the side bar, then we can get new icons
+ d->qFileDialogUi->sidebar->setUrls(d->qFileDialogUi->sidebar->urls());
+}
+
+/*!
+ Returns the icon provider used by the filedialog.
+*/
+QFileIconProvider *QFileDialog::iconProvider() const
+{
+ Q_D(const QFileDialog);
+ return d->model->iconProvider();
+}
+
+/*!
+ Sets the \a text shown in the filedialog in the specified \a label.
+*/
+void QFileDialog::setLabelText(DialogLabel label, const QString &text)
+{
+ Q_D(QFileDialog);
+ QPushButton *button;
+ switch (label) {
+ case LookIn:
+ d->qFileDialogUi->lookInLabel->setText(text);
+ break;
+ case FileName:
+ d->qFileDialogUi->fileNameLabel->setText(text);
+ d->fileNameLabelExplicitlySat = true;
+ break;
+ case FileType:
+ d->qFileDialogUi->fileTypeLabel->setText(text);
+ break;
+ case Accept:
+ d->acceptLabel = text;
+ if (acceptMode() == AcceptOpen)
+ button = d->qFileDialogUi->buttonBox->button(QDialogButtonBox::Open);
+ else
+ button = d->qFileDialogUi->buttonBox->button(QDialogButtonBox::Save);
+ if (button)
+ button->setText(text);
+ break;
+ case Reject:
+ button = d->qFileDialogUi->buttonBox->button(QDialogButtonBox::Cancel);
+ if (button)
+ button->setText(text);
+ break;
+ }
+}
+
+/*!
+ Returns the text shown in the filedialog in the specified \a label.
+*/
+QString QFileDialog::labelText(DialogLabel label) const
+{
+ QPushButton *button;
+ Q_D(const QFileDialog);
+ switch (label) {
+ case LookIn:
+ return d->qFileDialogUi->lookInLabel->text();
+ case FileName:
+ return d->qFileDialogUi->fileNameLabel->text();
+ case FileType:
+ return d->qFileDialogUi->fileTypeLabel->text();
+ case Accept:
+ if (acceptMode() == AcceptOpen)
+ button = d->qFileDialogUi->buttonBox->button(QDialogButtonBox::Open);
+ else
+ button = d->qFileDialogUi->buttonBox->button(QDialogButtonBox::Save);
+ if (button)
+ return button->text();
+ case Reject:
+ button = d->qFileDialogUi->buttonBox->button(QDialogButtonBox::Cancel);
+ if (button)
+ return button->text();
+ }
+ return QString();
+}
+
+/*
+ For the native file dialogs
+*/
+
+#if defined(Q_WS_WIN)
+extern QString qt_win_get_open_file_name(const QFileDialogArgs &args,
+ QString *initialDirectory,
+ QString *selectedFilter);
+
+extern QString qt_win_get_save_file_name(const QFileDialogArgs &args,
+ QString *initialDirectory,
+ QString *selectedFilter);
+
+extern QStringList qt_win_get_open_file_names(const QFileDialogArgs &args,
+ QString *initialDirectory,
+ QString *selectedFilter);
+
+extern QString qt_win_get_existing_directory(const QFileDialogArgs &args);
+#endif
+
+/*
+ For Symbian file dialogs
+*/
+#if defined(Q_WS_S60)
+extern QString qtSymbianGetOpenFileName(const QString &caption,
+ const QString &dir,
+ const QString &filter);
+
+extern QStringList qtSymbianGetOpenFileNames(const QString &caption,
+ const QString &dir,
+ const QString &filter);
+
+extern QString qtSymbianGetSaveFileName(const QString &caption,
+ const QString &dir);
+
+extern QString qtSymbianGetExistingDirectory(const QString &caption,
+ const QString &dir);
+#endif
+
+/*!
+ This is a convenience static function that returns an existing file
+ selected by the user. If the user presses Cancel, it returns a null string.
+
+ \snippet doc/src/snippets/code/src_gui_dialogs_qfiledialog.cpp 8
+
+ The function creates a modal file dialog with the given \a parent widget.
+ If \a parent is not 0, the dialog will be shown centered over the parent
+ widget.
+
+ The file dialog's working directory will be set to \a dir. If \a dir
+ includes a file name, the file will be selected. Only files that match the
+ given \a filter are shown. The filter selected is set to \a selectedFilter.
+ The parameters \a dir, \a selectedFilter, and \a filter may be empty
+ strings. If you want multiple filters, separate them with ';;', for
+ example:
+
+ \code
+ "Images (*.png *.xpm *.jpg);;Text files (*.txt);;XML files (*.xml)"
+ \endcode
+
+ The \a options argument holds various options about how to run the dialog,
+ see the QFileDialog::Option enum for more information on the flags you can
+ pass.
+
+ The dialog's caption is set to \a caption. If \a caption is not specified
+ then a default caption will be used.
+
+ On Windows, Mac OS X and Symbian^3, this static function will use the
+ native file dialog and not a QFileDialog.
+
+ On Windows the dialog will spin a blocking modal event loop that will not
+ dispatch any QTimers, and if \a parent is not 0 then it will position the
+ dialog just below the parent's title bar.
+
+ On Unix/X11, the normal behavior of the file dialog is to resolve and
+ follow symlinks. For example, if \c{/usr/tmp} is a symlink to \c{/var/tmp},
+ the file dialog will change to \c{/var/tmp} after entering \c{/usr/tmp}. If
+ \a options includes DontResolveSymlinks, the file dialog will treat
+ symlinks as regular directories.
+
+ On Symbian^3 the parameter \a selectedFilter has no meaning and the
+ \a options parameter is only used to define if the native file dialog is
+ used.
+
+ \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
+ QFileDialog constructors.
+
+ \sa getOpenFileNames(), getSaveFileName(), getExistingDirectory()
+*/
+QString QFileDialog::getOpenFileName(QWidget *parent,
+ const QString &caption,
+ const QString &dir,
+ const QString &filter,
+ QString *selectedFilter,
+ Options options)
+{
+ if (qt_filedialog_open_filename_hook && !(options & DontUseNativeDialog))
+ return qt_filedialog_open_filename_hook(parent, caption, dir, filter, selectedFilter, options);
+#if defined(Q_WS_S60)
+ if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0 && !(options & DontUseNativeDialog))
+ return qtSymbianGetOpenFileName(caption, dir, filter);
+#endif
+ QFileDialogArgs args;
+ args.parent = parent;
+ args.caption = caption;
+ args.directory = QFileDialogPrivate::workingDirectory(dir);
+ args.selection = QFileDialogPrivate::initialSelection(dir);
+ args.filter = filter;
+ args.mode = ExistingFile;
+ args.options = options;
+#if defined(Q_WS_WIN)
+ if (qt_use_native_dialogs && !(args.options & DontUseNativeDialog)) {
+ return qt_win_get_open_file_name(args, &(args.directory), selectedFilter);
+ }
+#endif
+
+ // create a qt dialog
+ QFileDialog dialog(args);
+ if (selectedFilter)
+ dialog.selectNameFilter(*selectedFilter);
+ if (dialog.exec() == QDialog::Accepted) {
+ if (selectedFilter)
+ *selectedFilter = dialog.selectedFilter();
+ return dialog.selectedFiles().value(0);
+ }
+ return QString();
+}
+
+/*!
+ This is a convenience static function that will return one or more existing
+ files selected by the user.
+
+ \snippet doc/src/snippets/code/src_gui_dialogs_qfiledialog.cpp 9
+
+ This function creates a modal file dialog with the given \a parent widget.
+ If \a parent is not 0, the dialog will be shown centered over the parent
+ widget.
+
+ The file dialog's working directory will be set to \a dir. If \a dir
+ includes a file name, the file will be selected. The filter is set to
+ \a filter so that only those files which match the filter are shown. The
+ filter selected is set to \a selectedFilter. The parameters \a dir,
+ \a selectedFilter and \a filter may be empty strings. If you need multiple
+ filters, separate them with ';;', for instance:
+
+ \code
+ "Images (*.png *.xpm *.jpg);;Text files (*.txt);;XML files (*.xml)"
+ \endcode
+
+ The dialog's caption is set to \a caption. If \a caption is not specified
+ then a default caption will be used.
+
+ On Windows, Mac OS X and Symbian^3, this static function will use the
+ native file dialog and not a QFileDialog.
+
+ On Windows the dialog will spin a blocking modal event loop that will not
+ dispatch any QTimers, and if \a parent is not 0 then it will position the
+ dialog just below the parent's title bar.
+
+ On Unix/X11, the normal behavior of the file dialog is to resolve and
+ follow symlinks. For example, if \c{/usr/tmp} is a symlink to \c{/var/tmp},
+ the file dialog will change to \c{/var/tmp} after entering \c{/usr/tmp}.
+ The \a options argument holds various options about how to run the dialog,
+ see the QFileDialog::Option enum for more information on the flags you can
+ pass.
+
+ \note If you want to iterate over the list of files, you should iterate
+ over a copy. For example:
+
+ \snippet doc/src/snippets/code/src_gui_dialogs_qfiledialog.cpp 10
+
+ On Symbian^3 the parameter \a selectedFilter has no meaning and the
+ \a options parameter is only used to define if the native file dialog is
+ used. On Symbian^3, this function can only return a single filename.
+
+ \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
+ QFileDialog constructors.
+
+ \sa getOpenFileName(), getSaveFileName(), getExistingDirectory()
+*/
+QStringList QFileDialog::getOpenFileNames(QWidget *parent,
+ const QString &caption,
+ const QString &dir,
+ const QString &filter,
+ QString *selectedFilter,
+ Options options)
+{
+ if (qt_filedialog_open_filenames_hook && !(options & DontUseNativeDialog))
+ return qt_filedialog_open_filenames_hook(parent, caption, dir, filter, selectedFilter, options);
+#if defined(Q_WS_S60)
+ if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0 && !(options & DontUseNativeDialog))
+ return qtSymbianGetOpenFileNames(caption, dir, filter);
+#endif
+ QFileDialogArgs args;
+ args.parent = parent;
+ args.caption = caption;
+ args.directory = QFileDialogPrivate::workingDirectory(dir);
+ args.selection = QFileDialogPrivate::initialSelection(dir);
+ args.filter = filter;
+ args.mode = ExistingFiles;
+ args.options = options;
+
+#if defined(Q_WS_WIN)
+ if (qt_use_native_dialogs && !(args.options & DontUseNativeDialog)) {
+ return qt_win_get_open_file_names(args, &(args.directory), selectedFilter);
+ }
+#endif
+
+ // create a qt dialog
+ QFileDialog dialog(args);
+ if (selectedFilter)
+ dialog.selectNameFilter(*selectedFilter);
+ if (dialog.exec() == QDialog::Accepted) {
+ if (selectedFilter)
+ *selectedFilter = dialog.selectedFilter();
+ return dialog.selectedFiles();
+ }
+ return QStringList();
+}
+
+/*!
+ This is a convenience static function that will return a file name selected
+ by the user. The file does not have to exist.
+
+ It creates a modal file dialog with the given \a parent widget. If
+ \a parent is not 0, the dialog will be shown centered over the parent
+ widget.
+
+ \snippet doc/src/snippets/code/src_gui_dialogs_qfiledialog.cpp 11
+
+ The file dialog's working directory will be set to \a dir. If \a dir
+ includes a file name, the file will be selected. Only files that match the
+ \a filter are shown. The filter selected is set to \a selectedFilter. The
+ parameters \a dir, \a selectedFilter, and \a filter may be empty strings.
+ Multiple filters are separated with ';;'. For instance:
+
+ \code
+ "Images (*.png *.xpm *.jpg);;Text files (*.txt);;XML files (*.xml)"
+ \endcode
+
+ The \a options argument holds various options about how to run the dialog,
+ see the QFileDialog::Option enum for more information on the flags you can
+ pass.
+
+ The default filter can be chosen by setting \a selectedFilter to the
+ desired value.
+
+ The dialog's caption is set to \a caption. If \a caption is not specified,
+ a default caption will be used.
+
+ On Windows, Mac OS X and Symbian^3, this static function will use the
+ native file dialog and not a QFileDialog.
+
+ On Windows the dialog will spin a blocking modal event loop that will not
+ dispatch any QTimers, and if \a parent is not 0 then it will position the
+ dialog just below the parent's title bar. On Mac OS X, with its native file
+ dialog, the filter argument is ignored.
+
+ On Unix/X11, the normal behavior of the file dialog is to resolve and
+ follow symlinks. For example, if \c{/usr/tmp} is a symlink to \c{/var/tmp},
+ the file dialog will change to \c{/var/tmp} after entering \c{/usr/tmp}. If
+ \a options includes DontResolveSymlinks the file dialog will treat symlinks
+ as regular directories.
+
+ On Symbian^3 the parameters \a filter and \a selectedFilter have no
+ meaning. The \a options parameter is only used to define if the native file
+ dialog is used.
+
+ \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
+ QFileDialog constructors.
+
+ \sa getOpenFileName(), getOpenFileNames(), getExistingDirectory()
+*/
+QString QFileDialog::getSaveFileName(QWidget *parent,
+ const QString &caption,
+ const QString &dir,
+ const QString &filter,
+ QString *selectedFilter,
+ Options options)
+{
+ if (qt_filedialog_save_filename_hook && !(options & DontUseNativeDialog))
+ return qt_filedialog_save_filename_hook(parent, caption, dir, filter, selectedFilter, options);
+#if defined(Q_WS_S60)
+ if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0 && !(options & DontUseNativeDialog))
+ return qtSymbianGetSaveFileName(caption, dir);
+#endif
+ QFileDialogArgs args;
+ args.parent = parent;
+ args.caption = caption;
+ args.directory = QFileDialogPrivate::workingDirectory(dir);
+ args.selection = QFileDialogPrivate::initialSelection(dir);
+ args.filter = filter;
+ args.mode = AnyFile;
+ args.options = options;
+
+#if defined(Q_WS_WIN)
+ if (qt_use_native_dialogs && !(args.options & DontUseNativeDialog)) {
+ return qt_win_get_save_file_name(args, &(args.directory), selectedFilter);
+ }
+#endif
+
+ // create a qt dialog
+ QFileDialog dialog(args);
+ dialog.setAcceptMode(AcceptSave);
+ if (selectedFilter)
+ dialog.selectNameFilter(*selectedFilter);
+ if (dialog.exec() == QDialog::Accepted) {
+ if (selectedFilter)
+ *selectedFilter = dialog.selectedFilter();
+ return dialog.selectedFiles().value(0);
+ }
+
+ return QString();
+}
+
+/*!
+ This is a convenience static function that will return an existing
+ directory selected by the user.
+
+ \snippet doc/src/snippets/code/src_gui_dialogs_qfiledialog.cpp 12
+
+ This function creates a modal file dialog with the given \a parent widget.
+ If \a parent is not 0, the dialog will be shown centered over the parent
+ widget.
+
+ The dialog's working directory is set to \a dir, and the caption is set to
+ \a caption. Either of these may be an empty string in which case the
+ current directory and a default caption will be used respectively.
+
+ The \a options argument holds various options about how to run the dialog,
+ see the QFileDialog::Option enum for more information on the flags you can
+ pass. To ensure a native file dialog, \l{QFileDialog::}{ShowDirsOnly} must
+ be set.
+
+ On Windows, Mac OS X and Symbian^3, this static function will use the
+ native file dialog and not a QFileDialog. On Windows CE, if the device has
+ no native file dialog, a QFileDialog will be used.
+
+ On Unix/X11, the normal behavior of the file dialog is to resolve and
+ follow symlinks. For example, if \c{/usr/tmp} is a symlink to \c{/var/tmp},
+ the file dialog will change to \c{/var/tmp} after entering \c{/usr/tmp}. If
+ \a options includes DontResolveSymlinks, the file dialog will treat
+ symlinks as regular directories.
+
+ On Windows the dialog will spin a blocking modal event loop that will not
+ dispatch any QTimers, and if \a parent is not 0 then it will position the
+ dialog just below the parent's title bar.
+
+ On Symbian^3 the \a options parameter is only used to define if the native
+ file dialog is used.
+
+ \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
+ QFileDialog constructors.
+
+ \sa getOpenFileName(), getOpenFileNames(), getSaveFileName()
+*/
+QString QFileDialog::getExistingDirectory(QWidget *parent,
+ const QString &caption,
+ const QString &dir,
+ Options options)
+{
+ if (qt_filedialog_existing_directory_hook && !(options & DontUseNativeDialog))
+ return qt_filedialog_existing_directory_hook(parent, caption, dir, options);
+#if defined(Q_WS_S60)
+ if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0 && !(options & DontUseNativeDialog))
+ return qtSymbianGetExistingDirectory(caption, dir);
+#endif
+ QFileDialogArgs args;
+ args.parent = parent;
+ args.caption = caption;
+ args.directory = QFileDialogPrivate::workingDirectory(dir);
+ args.mode = (options & ShowDirsOnly ? DirectoryOnly : Directory);
+ args.options = options;
+
+#if defined(Q_WS_WIN)
+ if (qt_use_native_dialogs && !(args.options & DontUseNativeDialog) && (options & ShowDirsOnly)
+#if defined(Q_WS_WINCE)
+ && qt_priv_ptr_valid
+#endif
+ ) {
+ return qt_win_get_existing_directory(args);
+ }
+#endif
+
+ // create a qt dialog
+ QFileDialog dialog(args);
+ if (dialog.exec() == QDialog::Accepted) {
+ return dialog.selectedFiles().value(0);
+ }
+ return QString();
+}
+
+inline static QString _qt_get_directory(const QString &path)
+{
+ QFileInfo info = QFileInfo(QDir::current(), path);
+ if (info.exists() && info.isDir())
+ return QDir::cleanPath(info.absoluteFilePath());
+ info.setFile(info.absolutePath());
+ if (info.exists() && info.isDir())
+ return info.absoluteFilePath();
+ return QString();
+}
+/*
+ Get the initial directory path
+
+ \sa initialSelection()
+ */
+QString QFileDialogPrivate::workingDirectory(const QString &path)
+{
+ if (!path.isEmpty()) {
+ QString directory = _qt_get_directory(path);
+ if (!directory.isEmpty())
+ return directory;
+ }
+ QString directory = _qt_get_directory(*lastVisitedDir());
+ if (!directory.isEmpty())
+ return directory;
+ return QDir::currentPath();
+}
+
+/*
+ Get the initial selection given a path. The initial directory
+ can contain both the initial directory and initial selection
+ /home/user/foo.txt
+
+ \sa workingDirectory()
+ */
+QString QFileDialogPrivate::initialSelection(const QString &path)
+{
+ if (!path.isEmpty()) {
+ QFileInfo info(path);
+ if (!info.isDir())
+ return info.fileName();
+ }
+ return QString();
+}
+
+/*!
+ \reimp
+*/
+void QFileDialog::done(int result)
+{
+ Q_D(QFileDialog);
+
+ QDialog::done(result);
+
+ if (d->receiverToDisconnectOnClose) {
+ disconnect(this, d->signalToDisconnectOnClose,
+ d->receiverToDisconnectOnClose, d->memberToDisconnectOnClose);
+ d->receiverToDisconnectOnClose = 0;
+ }
+ d->memberToDisconnectOnClose.clear();
+ d->signalToDisconnectOnClose.clear();
+}
+
+/*!
+ \reimp
+*/
+void QFileDialog::accept()
+{
+ Q_D(QFileDialog);
+ QStringList files = selectedFiles();
+ if (files.isEmpty())
+ return;
+ if (d->nativeDialogInUse){
+ d->emitFilesSelected(files);
+ QDialog::accept();
+ return;
+ }
+
+ QString lineEditText = d->lineEdit()->text();
+ // "hidden feature" type .. and then enter, and it will move up a dir
+ // special case for ".."
+ if (lineEditText == QLatin1String("..")) {
+ d->_q_navigateToParent();
+ bool block = d->qFileDialogUi->fileNameEdit->blockSignals(true);
+ d->lineEdit()->selectAll();
+ d->qFileDialogUi->fileNameEdit->blockSignals(block);
+ return;
+ }
+
+ switch (d->fileMode) {
+ case DirectoryOnly:
+ case Directory: {
+ QString fn = files.first();
+ QFileInfo info(fn);
+ if (!info.exists())
+ info = QFileInfo(d->getEnvironmentVariable(fn));
+ if (!info.exists()) {
+#ifndef QT_NO_MESSAGEBOX
+ QString message = tr("%1\nDirectory not found.\nPlease verify the "
+ "correct directory name was given.");
+ QMessageBox::warning(this, windowTitle(), message.arg(info.fileName()));
+#endif // QT_NO_MESSAGEBOX
+ return;
+ }
+ if (info.isDir()) {
+ d->emitFilesSelected(files);
+ QDialog::accept();
+ }
+ return;
+ }
+
+ case AnyFile: {
+ QString fn = files.first();
+ QFileInfo info(fn);
+ if (info.isDir()) {
+ setDirectory(info.absoluteFilePath());
+ return;
+ }
+
+ if (!info.exists()) {
+ int maxNameLength = d->maxNameLength(info.path());
+ if (maxNameLength >= 0 && info.fileName().length() > maxNameLength)
+ return;
+ }
+
+ // check if we have to ask for permission to overwrite the file
+ if (!info.exists() || !confirmOverwrite() || acceptMode() == AcceptOpen) {
+ d->emitFilesSelected(QStringList(fn));
+ QDialog::accept();
+#ifndef QT_NO_MESSAGEBOX
+ } else {
+ if (QMessageBox::warning(this, windowTitle(),
+ tr("%1 already exists.\nDo you want to replace it?")
+ .arg(info.fileName()),
+ QMessageBox::Yes | QMessageBox::No, QMessageBox::No)
+ == QMessageBox::Yes) {
+ d->emitFilesSelected(QStringList(fn));
+ QDialog::accept();
+ }
+#endif
+ }
+ return;
+ }
+
+ case ExistingFile:
+ case ExistingFiles:
+ for (int i = 0; i < files.count(); ++i) {
+ QFileInfo info(files.at(i));
+ if (!info.exists())
+ info = QFileInfo(d->getEnvironmentVariable(files.at(i)));
+ if (!info.exists()) {
+#ifndef QT_NO_MESSAGEBOX
+ QString message = tr("%1\nFile not found.\nPlease verify the "
+ "correct file name was given.");
+ QMessageBox::warning(this, windowTitle(), message.arg(info.fileName()));
+#endif // QT_NO_MESSAGEBOX
+ return;
+ }
+ if (info.isDir()) {
+ setDirectory(info.absoluteFilePath());
+ d->lineEdit()->clear();
+ return;
+ }
+ }
+ d->emitFilesSelected(files);
+ QDialog::accept();
+ return;
+ }
+}
+
+/*!
+ \internal
+
+ Create widgets, layout and set default values
+*/
+void QFileDialogPrivate::init(const QString &directory, const QString &nameFilter,
+ const QString &caption)
+{
+ Q_Q(QFileDialog);
+ if (!caption.isEmpty()) {
+ useDefaultCaption = false;
+ setWindowTitle = caption;
+ q->setWindowTitle(caption);
+ }
+
+ createWidgets();
+ createMenuActions();
+ retranslateStrings();
+ q->setFileMode(fileMode);
+
+#ifndef QT_NO_SETTINGS
+ QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
+ settings.beginGroup(QLatin1String("Qt"));
+ if (!directory.isEmpty())
+ setLastVisitedDirectory(workingDirectory(directory));
+ q->restoreState(settings.value(QLatin1String("filedialog")).toByteArray());
+#endif
+
+#if defined(Q_EMBEDDED_SMALLSCREEN)
+ qFileDialogUi->lookInLabel->setVisible(false);
+ qFileDialogUi->fileNameLabel->setVisible(false);
+ qFileDialogUi->fileTypeLabel->setVisible(false);
+ qFileDialogUi->sidebar->hide();
+#endif
+ // Default case
+ if (!nameFilter.isEmpty())
+ q->setNameFilter(nameFilter);
+ q->setAcceptMode(QFileDialog::AcceptOpen);
+ q->setDirectory(workingDirectory(directory));
+ q->selectFile(initialSelection(directory));
+
+ _q_updateOkButton();
+ q->resize(q->sizeHint());
+}
+
+/*!
+ \internal
+
+ Create the widgets, set properties and connections
+*/
+void QFileDialogPrivate::createWidgets()
+{
+ Q_Q(QFileDialog);
+ model = new QFileSystemModel(q);
+ model->setObjectName(QLatin1String("qt_filesystem_model"));
+#ifdef Q_WS_MAC
+ model->setNameFilterDisables(true);
+#else
+ model->setNameFilterDisables(false);
+#endif
+ model->d_func()->disableRecursiveSort = true;
+ QFileDialog::connect(model, SIGNAL(fileRenamed(QString,QString,QString)), q, SLOT(_q_fileRenamed(QString,QString,QString)));
+ QFileDialog::connect(model, SIGNAL(rootPathChanged(QString)),
+ q, SLOT(_q_pathChanged(QString)));
+ QFileDialog::connect(model, SIGNAL(rowsInserted(QModelIndex,int,int)),
+ q, SLOT(_q_rowsInserted(QModelIndex)));
+ model->setReadOnly(false);
+
+ qFileDialogUi.reset(new Ui_QFileDialog());
+ qFileDialogUi->setupUi(q);
+
+ QList<QUrl> initialBookmarks;
+ initialBookmarks << QUrl::fromLocalFile(QLatin1String(""))
+ << QUrl::fromLocalFile(QDir::homePath());
+ qFileDialogUi->sidebar->init(model, initialBookmarks);
+ QFileDialog::connect(qFileDialogUi->sidebar, SIGNAL(goToUrl(QUrl)),
+ q, SLOT(_q_goToUrl(QUrl)));
+
+ QObject::connect(qFileDialogUi->buttonBox, SIGNAL(accepted()), q, SLOT(accept()));
+ QObject::connect(qFileDialogUi->buttonBox, SIGNAL(rejected()), q, SLOT(reject()));
+
+
+ qFileDialogUi->lookInCombo->init(this);
+ QObject::connect(qFileDialogUi->lookInCombo, SIGNAL(activated(QString)), q, SLOT(_q_goToDirectory(QString)));
+
+ qFileDialogUi->lookInCombo->setInsertPolicy(QComboBox::NoInsert);
+ qFileDialogUi->lookInCombo->setDuplicatesEnabled(false);
+
+ // filename
+ qFileDialogUi->fileNameEdit->init(this);
+#ifndef QT_NO_SHORTCUT
+ qFileDialogUi->fileNameLabel->setBuddy(qFileDialogUi->fileNameEdit);
+#endif
+#ifndef QT_NO_FSCOMPLETER
+ completer = new QFSCompleter(model, q);
+ qFileDialogUi->fileNameEdit->setCompleter(completer);
+#endif // QT_NO_FSCOMPLETER
+ QObject::connect(qFileDialogUi->fileNameEdit, SIGNAL(textChanged(QString)),
+ q, SLOT(_q_autoCompleteFileName(QString)));
+ QObject::connect(qFileDialogUi->fileNameEdit, SIGNAL(textChanged(QString)),
+ q, SLOT(_q_updateOkButton()));
+
+ QObject::connect(qFileDialogUi->fileNameEdit, SIGNAL(returnPressed()), q, SLOT(accept()));
+
+ // filetype
+ qFileDialogUi->fileTypeCombo->setDuplicatesEnabled(false);
+ qFileDialogUi->fileTypeCombo->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLength);
+ qFileDialogUi->fileTypeCombo->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
+ QObject::connect(qFileDialogUi->fileTypeCombo, SIGNAL(activated(int)),
+ q, SLOT(_q_useNameFilter(int)));
+ QObject::connect(qFileDialogUi->fileTypeCombo, SIGNAL(activated(QString)),
+ q, SIGNAL(filterSelected(QString)));
+
+ qFileDialogUi->listView->init(this);
+ qFileDialogUi->listView->setModel(model);
+ QObject::connect(qFileDialogUi->listView, SIGNAL(activated(QModelIndex)),
+ q, SLOT(_q_enterDirectory(QModelIndex)));
+ QObject::connect(qFileDialogUi->listView, SIGNAL(customContextMenuRequested(QPoint)),
+ q, SLOT(_q_showContextMenu(QPoint)));
+#ifndef QT_NO_SHORTCUT
+ QShortcut *shortcut = new QShortcut(qFileDialogUi->listView);
+ shortcut->setKey(QKeySequence(QLatin1String("Delete")));
+ QObject::connect(shortcut, SIGNAL(activated()), q, SLOT(_q_deleteCurrent()));
+#endif
+
+ qFileDialogUi->treeView->init(this);
+ qFileDialogUi->treeView->setModel(model);
+ QHeaderView *treeHeader = qFileDialogUi->treeView->header();
+ QFontMetrics fm(q->font());
+ treeHeader->resizeSection(0, fm.width(QLatin1String("wwwwwwwwwwwwwwwwwwwwwwwwww")));
+ treeHeader->resizeSection(1, fm.width(QLatin1String("128.88 GB")));
+ treeHeader->resizeSection(2, fm.width(QLatin1String("mp3Folder")));
+ treeHeader->resizeSection(3, fm.width(QLatin1String("10/29/81 02:02PM")));
+ treeHeader->setContextMenuPolicy(Qt::ActionsContextMenu);
+
+ QActionGroup *showActionGroup = new QActionGroup(q);
+ showActionGroup->setExclusive(false);
+ QObject::connect(showActionGroup, SIGNAL(triggered(QAction*)),
+ q, SLOT(_q_showHeader(QAction*)));;
+
+ QAbstractItemModel *abstractModel = model;
+#ifndef QT_NO_PROXYMODEL
+ if (proxyModel)
+ abstractModel = proxyModel;
+#endif
+ for (int i = 1; i < abstractModel->columnCount(QModelIndex()); ++i) {
+ QAction *showHeader = new QAction(showActionGroup);
+ showHeader->setCheckable(true);
+ showHeader->setChecked(true);
+ treeHeader->addAction(showHeader);
+ }
+
+ QScopedPointer<QItemSelectionModel> selModel(qFileDialogUi->treeView->selectionModel());
+ qFileDialogUi->treeView->setSelectionModel(qFileDialogUi->listView->selectionModel());
+
+ QObject::connect(qFileDialogUi->treeView, SIGNAL(activated(QModelIndex)),
+ q, SLOT(_q_enterDirectory(QModelIndex)));
+ QObject::connect(qFileDialogUi->treeView, SIGNAL(customContextMenuRequested(QPoint)),
+ q, SLOT(_q_showContextMenu(QPoint)));
+#ifndef QT_NO_SHORTCUT
+ shortcut = new QShortcut(qFileDialogUi->treeView);
+ shortcut->setKey(QKeySequence(QLatin1String("Delete")));
+ QObject::connect(shortcut, SIGNAL(activated()), q, SLOT(_q_deleteCurrent()));
+#endif
+
+ // Selections
+ QItemSelectionModel *selections = qFileDialogUi->listView->selectionModel();
+ QObject::connect(selections, SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
+ q, SLOT(_q_selectionChanged()));
+ QObject::connect(selections, SIGNAL(currentChanged(QModelIndex,QModelIndex)),
+ q, SLOT(_q_currentChanged(QModelIndex)));
+ qFileDialogUi->splitter->setStretchFactor(qFileDialogUi->splitter->indexOf(qFileDialogUi->splitter->widget(1)), QSizePolicy::Expanding);
+
+ createToolButtons();
+}
+
+void QFileDialogPrivate::_q_showHeader(QAction *action)
+{
+ Q_Q(QFileDialog);
+ QActionGroup *actionGroup = qobject_cast<QActionGroup*>(q->sender());
+ qFileDialogUi->treeView->header()->setSectionHidden(actionGroup->actions().indexOf(action) + 1, !action->isChecked());
+}
+
+#ifndef QT_NO_PROXYMODEL
+/*!
+ \since 4.3
+
+ Sets the model for the views to the given \a proxyModel. This is useful if you
+ want to modify the underlying model; for example, to add columns, filter
+ data or add drives.
+
+ Any existing proxy model will be removed, but not deleted. The file dialog
+ will take ownership of the \a proxyModel.
+
+ \sa proxyModel()
+*/
+void QFileDialog::setProxyModel(QAbstractProxyModel *proxyModel)
+{
+ Q_D(QFileDialog);
+ if ((!proxyModel && !d->proxyModel)
+ || (proxyModel == d->proxyModel))
+ return;
+
+ QModelIndex idx = d->rootIndex();
+ if (d->proxyModel) {
+ disconnect(d->proxyModel, SIGNAL(rowsInserted(QModelIndex,int,int)),
+ this, SLOT(_q_rowsInserted(QModelIndex)));
+ } else {
+ disconnect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)),
+ this, SLOT(_q_rowsInserted(QModelIndex)));
+ }
+
+ if (proxyModel != 0) {
+ proxyModel->setParent(this);
+ d->proxyModel = proxyModel;
+ proxyModel->setSourceModel(d->model);
+ d->qFileDialogUi->listView->setModel(d->proxyModel);
+ d->qFileDialogUi->treeView->setModel(d->proxyModel);
+#ifndef QT_NO_FSCOMPLETER
+ d->completer->setModel(d->proxyModel);
+ d->completer->proxyModel = d->proxyModel;
+#endif
+ connect(d->proxyModel, SIGNAL(rowsInserted(QModelIndex,int,int)),
+ this, SLOT(_q_rowsInserted(QModelIndex)));
+ } else {
+ d->proxyModel = 0;
+ d->qFileDialogUi->listView->setModel(d->model);
+ d->qFileDialogUi->treeView->setModel(d->model);
+#ifndef QT_NO_FSCOMPLETER
+ d->completer->setModel(d->model);
+ d->completer->sourceModel = d->model;
+ d->completer->proxyModel = 0;
+#endif
+ connect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)),
+ this, SLOT(_q_rowsInserted(QModelIndex)));
+ }
+ QScopedPointer<QItemSelectionModel> selModel(d->qFileDialogUi->treeView->selectionModel());
+ d->qFileDialogUi->treeView->setSelectionModel(d->qFileDialogUi->listView->selectionModel());
+
+ d->setRootIndex(idx);
+
+ // reconnect selection
+ QItemSelectionModel *selections = d->qFileDialogUi->listView->selectionModel();
+ QObject::connect(selections, SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
+ this, SLOT(_q_selectionChanged()));
+ QObject::connect(selections, SIGNAL(currentChanged(QModelIndex,QModelIndex)),
+ this, SLOT(_q_currentChanged(QModelIndex)));
+}
+
+/*!
+ Returns the proxy model used by the file dialog. By default no proxy is set.
+
+ \sa setProxyModel()
+*/
+QAbstractProxyModel *QFileDialog::proxyModel() const
+{
+ Q_D(const QFileDialog);
+ return d->proxyModel;
+}
+#endif // QT_NO_PROXYMODEL
+
+/*!
+ \internal
+
+ Create tool buttons, set properties and connections
+*/
+void QFileDialogPrivate::createToolButtons()
+{
+ Q_Q(QFileDialog);
+ qFileDialogUi->backButton->setIcon(q->style()->standardIcon(QStyle::SP_ArrowBack, 0, q));
+ qFileDialogUi->backButton->setAutoRaise(true);
+ qFileDialogUi->backButton->setEnabled(false);
+ QObject::connect(qFileDialogUi->backButton, SIGNAL(clicked()), q, SLOT(_q_navigateBackward()));
+
+ qFileDialogUi->forwardButton->setIcon(q->style()->standardIcon(QStyle::SP_ArrowForward, 0, q));
+ qFileDialogUi->forwardButton->setAutoRaise(true);
+ qFileDialogUi->forwardButton->setEnabled(false);
+ QObject::connect(qFileDialogUi->forwardButton, SIGNAL(clicked()), q, SLOT(_q_navigateForward()));
+
+ qFileDialogUi->toParentButton->setIcon(q->style()->standardIcon(QStyle::SP_FileDialogToParent, 0, q));
+ qFileDialogUi->toParentButton->setAutoRaise(true);
+ qFileDialogUi->toParentButton->setEnabled(false);
+ QObject::connect(qFileDialogUi->toParentButton, SIGNAL(clicked()), q, SLOT(_q_navigateToParent()));
+
+ qFileDialogUi->listModeButton->setIcon(q->style()->standardIcon(QStyle::SP_FileDialogListView, 0, q));
+ qFileDialogUi->listModeButton->setAutoRaise(true);
+ qFileDialogUi->listModeButton->setDown(true);
+ QObject::connect(qFileDialogUi->listModeButton, SIGNAL(clicked()), q, SLOT(_q_showListView()));
+
+ qFileDialogUi->detailModeButton->setIcon(q->style()->standardIcon(QStyle::SP_FileDialogDetailedView, 0, q));
+ qFileDialogUi->detailModeButton->setAutoRaise(true);
+ QObject::connect(qFileDialogUi->detailModeButton, SIGNAL(clicked()), q, SLOT(_q_showDetailsView()));
+
+ QSize toolSize(qFileDialogUi->fileNameEdit->sizeHint().height(), qFileDialogUi->fileNameEdit->sizeHint().height());
+ qFileDialogUi->backButton->setFixedSize(toolSize);
+ qFileDialogUi->listModeButton->setFixedSize(toolSize);
+ qFileDialogUi->detailModeButton->setFixedSize(toolSize);
+ qFileDialogUi->forwardButton->setFixedSize(toolSize);
+ qFileDialogUi->toParentButton->setFixedSize(toolSize);
+
+ qFileDialogUi->newFolderButton->setIcon(q->style()->standardIcon(QStyle::SP_FileDialogNewFolder, 0, q));
+ qFileDialogUi->newFolderButton->setFixedSize(toolSize);
+ qFileDialogUi->newFolderButton->setAutoRaise(true);
+ qFileDialogUi->newFolderButton->setEnabled(false);
+ QObject::connect(qFileDialogUi->newFolderButton, SIGNAL(clicked()), q, SLOT(_q_createDirectory()));
+}
+
+/*!
+ \internal
+
+ Create actions which will be used in the right click.
+*/
+void QFileDialogPrivate::createMenuActions()
+{
+ Q_Q(QFileDialog);
+
+ QAction *goHomeAction = new QAction(q);
+#ifndef QT_NO_SHORTCUT
+ goHomeAction->setShortcut(Qt::CTRL + Qt::Key_H + Qt::SHIFT);
+#endif
+ QObject::connect(goHomeAction, SIGNAL(triggered()), q, SLOT(_q_goHome()));
+ q->addAction(goHomeAction);
+
+ // ### TODO add Desktop & Computer actions
+
+ QAction *goToParent = new QAction(q);
+ goToParent->setObjectName(QLatin1String("qt_goto_parent_action"));
+#ifndef QT_NO_SHORTCUT
+ goToParent->setShortcut(Qt::CTRL + Qt::UpArrow);
+#endif
+ QObject::connect(goToParent, SIGNAL(triggered()), q, SLOT(_q_navigateToParent()));
+ q->addAction(goToParent);
+
+ renameAction = new QAction(q);
+ renameAction->setEnabled(false);
+ renameAction->setObjectName(QLatin1String("qt_rename_action"));
+ QObject::connect(renameAction, SIGNAL(triggered()), q, SLOT(_q_renameCurrent()));
+
+ deleteAction = new QAction(q);
+ deleteAction->setEnabled(false);
+ deleteAction->setObjectName(QLatin1String("qt_delete_action"));
+ QObject::connect(deleteAction, SIGNAL(triggered()), q, SLOT(_q_deleteCurrent()));
+
+ showHiddenAction = new QAction(q);
+ showHiddenAction->setObjectName(QLatin1String("qt_show_hidden_action"));
+ showHiddenAction->setCheckable(true);
+ QObject::connect(showHiddenAction, SIGNAL(triggered()), q, SLOT(_q_showHidden()));
+
+ newFolderAction = new QAction(q);
+ newFolderAction->setObjectName(QLatin1String("qt_new_folder_action"));
+ QObject::connect(newFolderAction, SIGNAL(triggered()), q, SLOT(_q_createDirectory()));
+}
+
+void QFileDialogPrivate::_q_goHome()
+{
+ Q_Q(QFileDialog);
+ q->setDirectory(QDir::homePath());
+}
+
+/*!
+ \internal
+
+ Update history with new path, buttons, and combo
+*/
+void QFileDialogPrivate::_q_pathChanged(const QString &newPath)
+{
+ Q_Q(QFileDialog);
+ QDir dir(model->rootDirectory());
+ qFileDialogUi->toParentButton->setEnabled(dir.exists());
+ qFileDialogUi->sidebar->selectUrl(QUrl::fromLocalFile(newPath));
+ q->setHistory(qFileDialogUi->lookInCombo->history());
+
+ if (currentHistoryLocation < 0 || currentHistory.value(currentHistoryLocation) != QDir::toNativeSeparators(newPath)) {
+ while (currentHistoryLocation >= 0 && currentHistoryLocation + 1 < currentHistory.count()) {
+ currentHistory.removeLast();
+ }
+ currentHistory.append(QDir::toNativeSeparators(newPath));
+ ++currentHistoryLocation;
+ }
+ qFileDialogUi->forwardButton->setEnabled(currentHistory.size() - currentHistoryLocation > 1);
+ qFileDialogUi->backButton->setEnabled(currentHistoryLocation > 0);
+}
+
+/*!
+ \internal
+
+ Navigates to the last directory viewed in the dialog.
+*/
+void QFileDialogPrivate::_q_navigateBackward()
+{
+ Q_Q(QFileDialog);
+ if (!currentHistory.isEmpty() && currentHistoryLocation > 0) {
+ --currentHistoryLocation;
+ QString previousHistory = currentHistory.at(currentHistoryLocation);
+ q->setDirectory(previousHistory);
+ }
+}
+
+/*!
+ \internal
+
+ Navigates to the last directory viewed in the dialog.
+*/
+void QFileDialogPrivate::_q_navigateForward()
+{
+ Q_Q(QFileDialog);
+ if (!currentHistory.isEmpty() && currentHistoryLocation < currentHistory.size() - 1) {
+ ++currentHistoryLocation;
+ QString nextHistory = currentHistory.at(currentHistoryLocation);
+ q->setDirectory(nextHistory);
+ }
+}
+
+/*!
+ \internal
+
+ Navigates to the parent directory of the currently displayed directory
+ in the dialog.
+*/
+void QFileDialogPrivate::_q_navigateToParent()
+{
+ Q_Q(QFileDialog);
+ QDir dir(model->rootDirectory());
+ QString newDirectory;
+ if (dir.isRoot()) {
+ newDirectory = model->myComputer().toString();
+ } else {
+ dir.cdUp();
+ newDirectory = dir.absolutePath();
+ }
+ q->setDirectory(newDirectory);
+ emit q->directoryEntered(newDirectory);
+}
+
+/*!
+ \internal
+
+ Creates a new directory, first asking the user for a suitable name.
+*/
+void QFileDialogPrivate::_q_createDirectory()
+{
+ Q_Q(QFileDialog);
+ qFileDialogUi->listView->clearSelection();
+
+ QString newFolderString = QFileDialog::tr("New Folder");
+ QString folderName = newFolderString;
+ QString prefix = q->directory().absolutePath() + QDir::separator();
+ if (QFile::exists(prefix + folderName)) {
+ qlonglong suffix = 2;
+ while (QFile::exists(prefix + folderName)) {
+ folderName = newFolderString + QString::number(suffix++);
+ }
+ }
+
+ QModelIndex parent = rootIndex();
+ QModelIndex index = model->mkdir(parent, folderName);
+ if (!index.isValid())
+ return;
+
+ index = select(index);
+ if (index.isValid()) {
+ qFileDialogUi->treeView->setCurrentIndex(index);
+ currentView()->edit(index);
+ }
+}
+
+void QFileDialogPrivate::_q_showListView()
+{
+ qFileDialogUi->listModeButton->setDown(true);
+ qFileDialogUi->detailModeButton->setDown(false);
+ qFileDialogUi->treeView->hide();
+ qFileDialogUi->listView->show();
+ qFileDialogUi->stackedWidget->setCurrentWidget(qFileDialogUi->listView->parentWidget());
+ qFileDialogUi->listView->doItemsLayout();
+}
+
+void QFileDialogPrivate::_q_showDetailsView()
+{
+ qFileDialogUi->listModeButton->setDown(false);
+ qFileDialogUi->detailModeButton->setDown(true);
+ qFileDialogUi->listView->hide();
+ qFileDialogUi->treeView->show();
+ qFileDialogUi->stackedWidget->setCurrentWidget(qFileDialogUi->treeView->parentWidget());
+ qFileDialogUi->treeView->doItemsLayout();
+}
+
+/*!
+ \internal
+
+ Show the context menu for the file/dir under position
+*/
+void QFileDialogPrivate::_q_showContextMenu(const QPoint &position)
+{
+#ifdef QT_NO_MENU
+ Q_UNUSED(position);
+#else
+ Q_Q(QFileDialog);
+ QAbstractItemView *view = 0;
+ if (q->viewMode() == QFileDialog::Detail)
+ view = qFileDialogUi->treeView;
+ else
+ view = qFileDialogUi->listView;
+ QModelIndex index = view->indexAt(position);
+ index = mapToSource(index.sibling(index.row(), 0));
+
+ QMenu menu(view);
+ if (index.isValid()) {
+ // file context menu
+ QFile::Permissions p(index.parent().data(QFileSystemModel::FilePermissions).toInt());
+ renameAction->setEnabled(p & QFile::WriteUser);
+ menu.addAction(renameAction);
+ deleteAction->setEnabled(p & QFile::WriteUser);
+ menu.addAction(deleteAction);
+ menu.addSeparator();
+ }
+ menu.addAction(showHiddenAction);
+ if (qFileDialogUi->newFolderButton->isVisible()) {
+ newFolderAction->setEnabled(qFileDialogUi->newFolderButton->isEnabled());
+ menu.addAction(newFolderAction);
+ }
+ menu.exec(view->viewport()->mapToGlobal(position));
+#endif // QT_NO_MENU
+}
+
+/*!
+ \internal
+*/
+void QFileDialogPrivate::_q_renameCurrent()
+{
+ Q_Q(QFileDialog);
+ QModelIndex index = qFileDialogUi->listView->currentIndex();
+ index = index.sibling(index.row(), 0);
+ if (q->viewMode() == QFileDialog::List)
+ qFileDialogUi->listView->edit(index);
+ else
+ qFileDialogUi->treeView->edit(index);
+}
+
+bool QFileDialogPrivate::removeDirectory(const QString &path)
+{
+ QModelIndex modelIndex = model->index(path);
+ return model->remove(modelIndex);
+}
+
+/*!
+ \internal
+
+ Deletes the currently selected item in the dialog.
+*/
+void QFileDialogPrivate::_q_deleteCurrent()
+{
+ if (model->isReadOnly())
+ return;
+
+ QModelIndexList list = qFileDialogUi->listView->selectionModel()->selectedRows();
+ for (int i = list.count() - 1; i >= 0; --i) {
+ QModelIndex index = list.at(i);
+ if (index == qFileDialogUi->listView->rootIndex())
+ continue;
+
+ index = mapToSource(index.sibling(index.row(), 0));
+ if (!index.isValid())
+ continue;
+
+ QString fileName = index.data(QFileSystemModel::FileNameRole).toString();
+ QString filePath = index.data(QFileSystemModel::FilePathRole).toString();
+ bool isDir = model->isDir(index);
+
+ QFile::Permissions p(index.parent().data(QFileSystemModel::FilePermissions).toInt());
+#ifndef QT_NO_MESSAGEBOX
+ Q_Q(QFileDialog);
+ if (!(p & QFile::WriteUser) && (QMessageBox::warning(q_func(), q_func()->windowTitle(),
+ QFileDialog::tr("'%1' is write protected.\nDo you want to delete it anyway?")
+ .arg(fileName),
+ QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::No))
+ return;
+ else if (QMessageBox::warning(q_func(), q_func()->windowTitle(),
+ QFileDialog::tr("Are sure you want to delete '%1'?")
+ .arg(fileName),
+ QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::No)
+ return;
+
+#else
+ if (!(p & QFile::WriteUser))
+ return;
+#endif // QT_NO_MESSAGEBOX
+
+ // the event loop has run, we can NOT reuse index because the model might have removed it.
+ if (isDir) {
+ if (!removeDirectory(filePath)) {
+#ifndef QT_NO_MESSAGEBOX
+ QMessageBox::warning(q, q->windowTitle(),
+ QFileDialog::tr("Could not delete directory."));
+#endif
+ }
+ } else {
+ model->remove(index);
+ }
+ }
+}
+
+void QFileDialogPrivate::_q_autoCompleteFileName(const QString &text)
+{
+ if (text.startsWith(QLatin1String("//")) || text.startsWith(QLatin1Char('\\'))) {
+ qFileDialogUi->listView->selectionModel()->clearSelection();
+ return;
+ }
+
+ QStringList multipleFiles = typedFiles();
+ if (multipleFiles.count() > 0) {
+ QModelIndexList oldFiles = qFileDialogUi->listView->selectionModel()->selectedRows();
+ QModelIndexList newFiles;
+ for (int i = 0; i < multipleFiles.count(); ++i) {
+ QModelIndex idx = model->index(multipleFiles.at(i));
+ if (oldFiles.contains(idx))
+ oldFiles.removeAll(idx);
+ else
+ newFiles.append(idx);
+ }
+ for (int i = 0; i < newFiles.count(); ++i)
+ select(newFiles.at(i));
+ if (lineEdit()->hasFocus())
+ for (int i = 0; i < oldFiles.count(); ++i)
+ qFileDialogUi->listView->selectionModel()->select(oldFiles.at(i),
+ QItemSelectionModel::Toggle | QItemSelectionModel::Rows);
+ }
+}
+
+/*!
+ \internal
+*/
+void QFileDialogPrivate::_q_updateOkButton()
+{
+ Q_Q(QFileDialog);
+ QPushButton *button = qFileDialogUi->buttonBox->button((acceptMode == QFileDialog::AcceptOpen)
+ ? QDialogButtonBox::Open : QDialogButtonBox::Save);
+ if (!button)
+ return;
+
+ bool enableButton = true;
+ bool isOpenDirectory = false;
+
+ QStringList files = q->selectedFiles();
+ QString lineEditText = lineEdit()->text();
+
+ if (lineEditText.startsWith(QLatin1String("//")) || lineEditText.startsWith(QLatin1Char('\\'))) {
+ button->setEnabled(true);
+ if (acceptMode == QFileDialog::AcceptSave)
+ button->setText(acceptLabel);
+ return;
+ }
+
+ if (files.isEmpty()) {
+ enableButton = false;
+ } else if (lineEditText == QLatin1String("..")) {
+ isOpenDirectory = true;
+ } else {
+ switch (fileMode) {
+ case QFileDialog::DirectoryOnly:
+ case QFileDialog::Directory: {
+ QString fn = files.first();
+ QModelIndex idx = model->index(fn);
+ if (!idx.isValid())
+ idx = model->index(getEnvironmentVariable(fn));
+ if (!idx.isValid() || !model->isDir(idx))
+ enableButton = false;
+ break;
+ }
+ case QFileDialog::AnyFile: {
+ QString fn = files.first();
+ QFileInfo info(fn);
+ QModelIndex idx = model->index(fn);
+ QString fileDir;
+ QString fileName;
+ if (info.isDir()) {
+ fileDir = info.canonicalFilePath();
+ } else {
+ fileDir = fn.mid(0, fn.lastIndexOf(QLatin1Char('/')));
+ fileName = fn.mid(fileDir.length() + 1);
+ }
+ if (lineEditText.contains(QLatin1String(".."))) {
+ fileDir = info.canonicalFilePath();
+ fileName = info.fileName();
+ }
+
+ if (fileDir == q->directory().canonicalPath() && fileName.isEmpty()) {
+ enableButton = false;
+ break;
+ }
+ if (idx.isValid() && model->isDir(idx)) {
+ isOpenDirectory = true;
+ enableButton = true;
+ break;
+ }
+ if (!idx.isValid()) {
+ int maxLength = maxNameLength(fileDir);
+ enableButton = maxLength < 0 || fileName.length() <= maxLength;
+ }
+ break;
+ }
+ case QFileDialog::ExistingFile:
+ case QFileDialog::ExistingFiles:
+ for (int i = 0; i < files.count(); ++i) {
+ QModelIndex idx = model->index(files.at(i));
+ if (!idx.isValid())
+ idx = model->index(getEnvironmentVariable(files.at(i)));
+ if (!idx.isValid()) {
+ enableButton = false;
+ break;
+ }
+ if (idx.isValid() && model->isDir(idx)) {
+ isOpenDirectory = true;
+ break;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ button->setEnabled(enableButton);
+ if (acceptMode == QFileDialog::AcceptSave)
+ button->setText(isOpenDirectory ? QFileDialog::tr("&Open") : acceptLabel);
+}
+
+/*!
+ \internal
+*/
+void QFileDialogPrivate::_q_currentChanged(const QModelIndex &index)
+{
+ _q_updateOkButton();
+ emit q_func()->currentChanged(index.data(QFileSystemModel::FilePathRole).toString());
+}
+
+/*!
+ \internal
+
+ This is called when the user double clicks on a file with the corresponding
+ model item \a index.
+*/
+void QFileDialogPrivate::_q_enterDirectory(const QModelIndex &index)
+{
+ Q_Q(QFileDialog);
+ // My Computer or a directory
+ QModelIndex sourceIndex = index.model() == proxyModel ? mapToSource(index) : 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
+ || fileMode == QFileDialog::DirectoryOnly) {
+ // ### find out why you have to do both of these.
+ lineEdit()->setText(QString());
+ lineEdit()->clear();
+ }
+ } else {
+ q->accept();
+ }
+}
+
+/*!
+ \internal
+
+ Changes the file dialog's current directory to the one specified
+ by \a path.
+*/
+void QFileDialogPrivate::_q_goToDirectory(const QString &path)
+{
+ #ifndef QT_NO_MESSAGEBOX
+ Q_Q(QFileDialog);
+#endif
+ QModelIndex index = qFileDialogUi->lookInCombo->model()->index(qFileDialogUi->lookInCombo->currentIndex(),
+ qFileDialogUi->lookInCombo->modelColumn(),
+ qFileDialogUi->lookInCombo->rootModelIndex());
+ QString path2 = path;
+ if (!index.isValid())
+ index = mapFromSource(model->index(getEnvironmentVariable(path)));
+ else {
+ path2 = index.data(UrlRole).toUrl().toLocalFile();
+ index = mapFromSource(model->index(path2));
+ }
+ QDir dir(path2);
+ if (!dir.exists())
+ dir = getEnvironmentVariable(path2);
+
+ if (dir.exists() || path2.isEmpty() || path2 == model->myComputer().toString()) {
+ _q_enterDirectory(index);
+#ifndef QT_NO_MESSAGEBOX
+ } else {
+ QString message = QFileDialog::tr("%1\nDirectory not found.\nPlease verify the "
+ "correct directory name was given.");
+ QMessageBox::warning(q, q->windowTitle(), message.arg(path2));
+#endif // QT_NO_MESSAGEBOX
+ }
+}
+
+// Makes a list of filters from a normal filter string "Image Files (*.png *.jpg)"
+QStringList qt_clean_filter_list(const QString &filter)
+{
+ QRegExp regexp(QString::fromLatin1(qt_file_dialog_filter_reg_exp));
+ QString f = filter;
+ int i = regexp.indexIn(f);
+ if (i >= 0)
+ f = regexp.cap(2);
+ return f.split(QLatin1Char(' '), QString::SkipEmptyParts);
+}
+
+/*!
+ \internal
+
+ Sets the current name filter to be nameFilter and
+ update the qFileDialogUi->fileNameEdit when in AcceptSave mode with the new extension.
+*/
+void QFileDialogPrivate::_q_useNameFilter(int index)
+{
+ if (index == nameFilters.size()) {
+ QAbstractItemModel *comboModel = qFileDialogUi->fileTypeCombo->model();
+ nameFilters.append(comboModel->index(comboModel->rowCount() - 1, 0).data().toString());
+ }
+
+ QString nameFilter = nameFilters.at(index);
+ QStringList newNameFilters = qt_clean_filter_list(nameFilter);
+ if (acceptMode == QFileDialog::AcceptSave) {
+ QString newNameFilterExtension;
+ if (newNameFilters.count() > 0)
+ newNameFilterExtension = QFileInfo(newNameFilters.at(0)).suffix();
+
+ QString fileName = lineEdit()->text();
+ const QString fileNameExtension = QFileInfo(fileName).suffix();
+ if (!fileNameExtension.isEmpty() && !newNameFilterExtension.isEmpty()) {
+ const int fileNameExtensionLength = fileNameExtension.count();
+ fileName.replace(fileName.count() - fileNameExtensionLength,
+ fileNameExtensionLength, newNameFilterExtension);
+ qFileDialogUi->listView->clearSelection();
+ lineEdit()->setText(fileName);
+ }
+ }
+
+ model->setNameFilters(newNameFilters);
+}
+
+/*!
+ \internal
+
+ This is called when the model index corresponding to the current file is changed
+ from \a index to \a current.
+*/
+void QFileDialogPrivate::_q_selectionChanged()
+{
+ QModelIndexList indexes = qFileDialogUi->listView->selectionModel()->selectedRows();
+ bool stripDirs = (fileMode != QFileDialog::DirectoryOnly && fileMode != QFileDialog::Directory);
+
+ QStringList allFiles;
+ for (int i = 0; i < indexes.count(); ++i) {
+ if (stripDirs && model->isDir(mapToSource(indexes.at(i))))
+ continue;
+ allFiles.append(indexes.at(i).data().toString());
+ }
+ if (allFiles.count() > 1)
+ for (int i = 0; i < allFiles.count(); ++i) {
+ allFiles.replace(i, QString(QLatin1Char('"') + allFiles.at(i) + QLatin1Char('"')));
+ }
+
+ QString finalFiles = allFiles.join(QLatin1String(" "));
+ if (!finalFiles.isEmpty() && !lineEdit()->hasFocus() && lineEdit()->isVisible())
+ lineEdit()->setText(finalFiles);
+ else
+ _q_updateOkButton();
+}
+
+/*!
+ \internal
+
+ Includes hidden files and directories in the items displayed in the dialog.
+*/
+void QFileDialogPrivate::_q_showHidden()
+{
+ Q_Q(QFileDialog);
+ QDir::Filters dirFilters = q->filter();
+ if (showHiddenAction->isChecked())
+ dirFilters |= QDir::Hidden;
+ else
+ dirFilters &= ~QDir::Hidden;
+ q->setFilter(dirFilters);
+}
+
+/*!
+ \internal
+
+ When parent is root and rows have been inserted when none was there before
+ then select the first one.
+*/
+void QFileDialogPrivate::_q_rowsInserted(const QModelIndex &parent)
+{
+ if (!qFileDialogUi->treeView
+ || parent != qFileDialogUi->treeView->rootIndex()
+ || !qFileDialogUi->treeView->selectionModel()
+ || qFileDialogUi->treeView->selectionModel()->hasSelection()
+ || qFileDialogUi->treeView->model()->rowCount(parent) == 0)
+ return;
+}
+
+void QFileDialogPrivate::_q_fileRenamed(const QString &path, const QString oldName, const QString newName)
+{
+ if (fileMode == QFileDialog::Directory || fileMode == QFileDialog::DirectoryOnly) {
+ if (path == rootPath() && lineEdit()->text() == oldName)
+ lineEdit()->setText(newName);
+ }
+}
+
+/*!
+ \internal
+
+ For the list and tree view watch keys to goto parent and back in the history
+
+ returns true if handled
+*/
+bool QFileDialogPrivate::itemViewKeyboardEvent(QKeyEvent *event) {
+
+ Q_Q(QFileDialog);
+ switch (event->key()) {
+ case Qt::Key_Backspace:
+ _q_navigateToParent();
+ return true;
+ case Qt::Key_Back:
+#ifdef QT_KEYPAD_NAVIGATION
+ if (QApplication::keypadNavigationEnabled())
+ return false;
+#endif
+ case Qt::Key_Left:
+ if (event->key() == Qt::Key_Back || event->modifiers() == Qt::AltModifier) {
+ _q_navigateBackward();
+ return true;
+ }
+ break;
+ case Qt::Key_Escape:
+ q->hide();
+ return true;
+ default:
+ break;
+ }
+ return false;
+}
+
+QString QFileDialogPrivate::getEnvironmentVariable(const QString &string)
+{
+#ifdef Q_OS_UNIX
+ if (string.size() > 1 && string.startsWith(QLatin1Char('$'))) {
+ return QString::fromLocal8Bit(getenv(string.mid(1).toLatin1().constData()));
+ }
+#else
+ if (string.size() > 2 && string.startsWith(QLatin1Char('%')) && string.endsWith(QLatin1Char('%'))) {
+ return QString::fromLocal8Bit(qgetenv(string.mid(1, string.size() - 2).toLatin1().constData()));
+ }
+#endif
+ return string;
+}
+
+void QFileDialogComboBox::init(QFileDialogPrivate *d_pointer) {
+ d_ptr = d_pointer;
+ urlModel = new QUrlModel(this);
+ urlModel->showFullPath = true;
+ urlModel->setFileSystemModel(d_ptr->model);
+ setModel(urlModel);
+}
+
+void QFileDialogComboBox::showPopup()
+{
+ if (model()->rowCount() > 1)
+ QComboBox::showPopup();
+
+ urlModel->setUrls(QList<QUrl>());
+ QList<QUrl> list;
+ QModelIndex idx = d_ptr->model->index(d_ptr->rootPath());
+ while (idx.isValid()) {
+ QUrl url = QUrl::fromLocalFile(idx.data(QFileSystemModel::FilePathRole).toString());
+ if (url.isValid())
+ list.append(url);
+ idx = idx.parent();
+ }
+ // add "my computer"
+ list.append(QUrl::fromLocalFile(QLatin1String("")));
+ urlModel->addUrls(list, 0);
+ idx = model()->index(model()->rowCount() - 1, 0);
+
+ // append history
+ QList<QUrl> urls;
+ for (int i = 0; i < m_history.count(); ++i) {
+ QUrl path = QUrl::fromLocalFile(m_history.at(i));
+ if (!urls.contains(path))
+ urls.prepend(path);
+ }
+ if (urls.count() > 0) {
+ model()->insertRow(model()->rowCount());
+ idx = model()->index(model()->rowCount()-1, 0);
+ // ### TODO maybe add a horizontal line before this
+ model()->setData(idx, QFileDialog::tr("Recent Places"));
+ QStandardItemModel *m = qobject_cast<QStandardItemModel*>(model());
+ if (m) {
+ Qt::ItemFlags flags = m->flags(idx);
+ flags &= ~Qt::ItemIsEnabled;
+ m->item(idx.row(), idx.column())->setFlags(flags);
+ }
+ urlModel->addUrls(urls, -1, false);
+ }
+ setCurrentIndex(0);
+
+ QComboBox::showPopup();
+}
+
+// Exact same as QComboBox::paintEvent(), except we elide the text.
+void QFileDialogComboBox::paintEvent(QPaintEvent *)
+{
+ QStylePainter painter(this);
+ painter.setPen(palette().color(QPalette::Text));
+
+ // draw the combobox frame, focusrect and selected etc.
+ QStyleOptionComboBox opt;
+ initStyleOption(&opt);
+
+ QRect editRect = style()->subControlRect(QStyle::CC_ComboBox, &opt,
+ QStyle::SC_ComboBoxEditField, this);
+ int size = editRect.width() - opt.iconSize.width() - 4;
+ opt.currentText = opt.fontMetrics.elidedText(opt.currentText, Qt::ElideMiddle, size);
+ painter.drawComplexControl(QStyle::CC_ComboBox, opt);
+
+ // draw the icon and text
+ painter.drawControl(QStyle::CE_ComboBoxLabel, opt);
+}
+
+QFileDialogListView::QFileDialogListView(QWidget *parent) : QListView(parent)
+{
+}
+
+void QFileDialogListView::init(QFileDialogPrivate *d_pointer)
+{
+ d_ptr = d_pointer;
+ setSelectionBehavior(QAbstractItemView::SelectRows);
+ setWrapping(true);
+ setResizeMode(QListView::Adjust);
+ setEditTriggers(QAbstractItemView::EditKeyPressed);
+ setContextMenuPolicy(Qt::CustomContextMenu);
+#ifndef QT_NO_DRAGANDDROP
+ setDragDropMode(QAbstractItemView::InternalMove);
+#endif
+}
+
+QSize QFileDialogListView::sizeHint() const
+{
+ int height = qMax(10, sizeHintForRow(0));
+ return QSize(QListView::sizeHint().width() * 2, height * 30);
+}
+
+void QFileDialogListView::keyPressEvent(QKeyEvent *e)
+{
+#ifdef QT_KEYPAD_NAVIGATION
+ if (QApplication::navigationMode() == Qt::NavigationModeKeypadDirectional) {
+ QListView::keyPressEvent(e);
+ return;
+ }
+#endif // QT_KEYPAD_NAVIGATION
+
+ if (!d_ptr->itemViewKeyboardEvent(e))
+ QListView::keyPressEvent(e);
+ e->accept();
+}
+
+QFileDialogTreeView::QFileDialogTreeView(QWidget *parent) : QTreeView(parent)
+{
+}
+
+void QFileDialogTreeView::init(QFileDialogPrivate *d_pointer)
+{
+ d_ptr = d_pointer;
+ setSelectionBehavior(QAbstractItemView::SelectRows);
+ setRootIsDecorated(false);
+ setItemsExpandable(false);
+ setSortingEnabled(true);
+ header()->setSortIndicator(0, Qt::AscendingOrder);
+ header()->setStretchLastSection(false);
+ setTextElideMode(Qt::ElideMiddle);
+ setEditTriggers(QAbstractItemView::EditKeyPressed);
+ setContextMenuPolicy(Qt::CustomContextMenu);
+#ifndef QT_NO_DRAGANDDROP
+ setDragDropMode(QAbstractItemView::InternalMove);
+#endif
+}
+
+void QFileDialogTreeView::keyPressEvent(QKeyEvent *e)
+{
+#ifdef QT_KEYPAD_NAVIGATION
+ if (QApplication::navigationMode() == Qt::NavigationModeKeypadDirectional) {
+ QTreeView::keyPressEvent(e);
+ return;
+ }
+#endif // QT_KEYPAD_NAVIGATION
+
+ if (!d_ptr->itemViewKeyboardEvent(e))
+ QTreeView::keyPressEvent(e);
+ e->accept();
+}
+
+QSize QFileDialogTreeView::sizeHint() const
+{
+ int height = qMax(10, sizeHintForRow(0));
+ QSize sizeHint = header()->sizeHint();
+ return QSize(sizeHint.width() * 4, height * 30);
+}
+
+/*!
+ // FIXME: this is a hack to avoid propagating key press events
+ // to the dialog and from there to the "Ok" button
+*/
+void QFileDialogLineEdit::keyPressEvent(QKeyEvent *e)
+{
+#ifdef QT_KEYPAD_NAVIGATION
+ if (QApplication::navigationMode() == Qt::NavigationModeKeypadDirectional) {
+ QLineEdit::keyPressEvent(e);
+ return;
+ }
+#endif // QT_KEYPAD_NAVIGATION
+
+ int key = e->key();
+ QLineEdit::keyPressEvent(e);
+ if (key != Qt::Key_Escape)
+ e->accept();
+ if (hideOnEsc && (key == Qt::Key_Escape || key == Qt::Key_Return || key == Qt::Key_Enter)) {
+ e->accept();
+ hide();
+ d_ptr->currentView()->setFocus(Qt::ShortcutFocusReason);
+ }
+}
+
+#ifndef QT_NO_FSCOMPLETER
+
+QString QFSCompleter::pathFromIndex(const QModelIndex &index) const
+{
+ 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)) {
+#if defined(Q_OS_UNIX) || defined(Q_OS_WINCE)
+ if (currentLocation == QDir::separator())
+ return path.mid(currentLocation.length());
+#endif
+ if (currentLocation.endsWith(QLatin1Char('/')))
+ return path.mid(currentLocation.length());
+ else
+ return path.mid(currentLocation.length()+1);
+ }
+ return index.data(QFileSystemModel::FilePathRole).toString();
+}
+
+QStringList QFSCompleter::splitPath(const QString &path) const
+{
+ if (path.isEmpty())
+ return QStringList(completionPrefix());
+
+ QString pathCopy = QDir::toNativeSeparators(path);
+ QString sep = QDir::separator();
+#if defined(Q_OS_SYMBIAN)
+ if (pathCopy == QLatin1String("\\"))
+ return QStringList(pathCopy);
+#elif defined(Q_OS_WIN)
+ if (pathCopy == QLatin1String("\\") || pathCopy == QLatin1String("\\\\"))
+ return QStringList(pathCopy);
+ QString doubleSlash(QLatin1String("\\\\"));
+ if (pathCopy.startsWith(doubleSlash))
+ pathCopy = pathCopy.mid(2);
+ else
+ doubleSlash.clear();
+#elif defined(Q_OS_UNIX)
+ bool expanded;
+ pathCopy = qt_tildeExpansion(pathCopy, &expanded);
+ if (expanded) {
+ QFileSystemModel *dirModel;
+ if (proxyModel)
+ dirModel = qobject_cast<QFileSystemModel *>(proxyModel->sourceModel());
+ else
+ dirModel = sourceModel;
+ dirModel->fetchMore(dirModel->index(pathCopy));
+ }
+#endif
+
+ QRegExp re(QLatin1Char('[') + QRegExp::escape(sep) + QLatin1Char(']'));
+
+#if defined(Q_OS_SYMBIAN)
+ QStringList parts = pathCopy.split(re, QString::SkipEmptyParts);
+ if (pathCopy.endsWith(sep))
+ parts.append(QString());
+#elif defined(Q_OS_WIN)
+ QStringList parts = pathCopy.split(re, QString::SkipEmptyParts);
+ if (!doubleSlash.isEmpty() && !parts.isEmpty())
+ parts[0].prepend(doubleSlash);
+ if (pathCopy.endsWith(sep))
+ parts.append(QString());
+#else
+ QStringList parts = pathCopy.split(re);
+ if (pathCopy[0] == sep[0]) // read the "/" at the beginning as the split removed it
+ parts[0] = sep[0];
+#endif
+
+#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
+ bool startsFromRoot = !parts.isEmpty() && parts[0].endsWith(QLatin1Char(':'));
+#else
+ bool startsFromRoot = pathCopy[0] == sep[0];
+#endif
+ if (parts.count() == 1 || (parts.count() > 1 && !startsFromRoot)) {
+ const QFileSystemModel *dirModel;
+ if (proxyModel)
+ dirModel = qobject_cast<const QFileSystemModel *>(proxyModel->sourceModel());
+ else
+ dirModel = sourceModel;
+ QString currentLocation = QDir::toNativeSeparators(dirModel->rootPath());
+#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
+ if (currentLocation.endsWith(QLatin1Char(':')))
+ currentLocation.append(sep);
+#endif
+ if (currentLocation.contains(sep) && path != currentLocation) {
+ QStringList currentLocationList = splitPath(currentLocation);
+ while (!currentLocationList.isEmpty()
+ && parts.count() > 0
+ && parts.at(0) == QLatin1String("..")) {
+ parts.removeFirst();
+ currentLocationList.removeLast();
+ }
+ if (!currentLocationList.isEmpty() && currentLocationList.last().isEmpty())
+ currentLocationList.removeLast();
+ return currentLocationList + parts;
+ }
+ }
+ return parts;
+}
+
+#endif // QT_NO_COMPLETER
+
+#ifdef QT3_SUPPORT
+/*!
+ Use selectedFiles() instead.
+
+ \oldcode
+ QString selected = dialog->selectedFile();
+ \newcode
+ QStringList files = dialog->selectedFiles();
+ QString selected;
+ if (!files.isEmpty())
+ selected = files[0];
+ \endcode
+*/
+QString QFileDialog::selectedFile() const
+{
+ QStringList files = selectedFiles();
+ return files.size() ? files.at(0) : QString();
+}
+
+/*!
+ \typedef QFileDialog::Mode
+
+ Use QFileDialog::FileMode instead.
+*/
+
+/*!
+ \fn void QFileDialog::setMode(FileMode m)
+
+ Use setFileMode() instead.
+*/
+
+/*!
+ \fn FileMode QFileDialog::mode() const
+
+ Use fileMode() instead.
+*/
+
+/*!
+ \fn void QFileDialog::setDir(const QString &directory)
+
+ Use setDirectory() instead.
+*/
+
+/*!
+ \fn void QFileDialog::setDir( const QDir &directory )
+
+ Use setDirectory() instead.
+*/
+
+/*!
+ \fn QStringList QFileDialog::getOpenFileNames(const QString &filter,
+ const QString &dir, QWidget *parent, const char* name,
+ const QString &caption, QString *selectedFilter, bool resolveSymlinks)
+
+ Use the getOpenFileNames() overload that takes \a parent as the first
+ argument instead.
+*/
+
+/*!
+ \fn QString QFileDialog::getOpenFileName(const QString &dir,
+ const QString &filter, QWidget *parent = 0, const char *name,
+ const QString &caption, QString *selectedFilter, bool resolveSymlinks)
+
+ Use the getOpenFileName() overload that takes \a parent as the first
+ argument instead.
+*/
+
+/*!
+ \fn QString QFileDialog::getSaveFileName(const QString &dir,
+ const QString &filter, QWidget *parent, const char *name,
+ const QString &caption, QString *selectedFilter, bool resolveSymlinks)
+
+ Use the getSaveFileName() overload that takes \a parent as the first
+ argument instead.
+*/
+
+/*!
+ \fn QString QFileDialog::getExistingDirectory(const QString &dir,
+ QWidget *parent, const char *name, const QString &caption,
+ bool dirOnly, bool resolveSymlinks)
+
+ Use the getExistingDirectory() overload that takes \a parent as
+ the first argument instead.
+*/
+
+#endif // QT3_SUPPORT
+
+QT_END_NAMESPACE
+
+#include "moc_qfiledialog.cpp"
+
+#endif // QT_NO_FILEDIALOG
diff --git a/src/widgets/dialogs/qfiledialog.h b/src/widgets/dialogs/qfiledialog.h
new file mode 100644
index 0000000000..1fd7c25255
--- /dev/null
+++ b/src/widgets/dialogs/qfiledialog.h
@@ -0,0 +1,331 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QFILEDIALOG_H
+#define QFILEDIALOG_H
+
+#include <QtCore/qdir.h>
+#include <QtCore/qstring.h>
+#include <QtWidgets/qdialog.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_FILEDIALOG
+
+class QModelIndex;
+class QItemSelection;
+struct QFileDialogArgs;
+class QFileIconProvider;
+class QFileDialogPrivate;
+class QAbstractItemDelegate;
+class QAbstractProxyModel;
+class QUrl;
+
+class Q_WIDGETS_EXPORT QFileDialog : public QDialog
+{
+ Q_OBJECT
+ Q_ENUMS(ViewMode FileMode AcceptMode Option)
+ Q_FLAGS(Options)
+ Q_PROPERTY(ViewMode viewMode READ viewMode WRITE setViewMode)
+ Q_PROPERTY(FileMode fileMode READ fileMode WRITE setFileMode)
+ Q_PROPERTY(AcceptMode acceptMode READ acceptMode WRITE setAcceptMode)
+ Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly DESIGNABLE false)
+ Q_PROPERTY(bool resolveSymlinks READ resolveSymlinks WRITE setResolveSymlinks DESIGNABLE false)
+ Q_PROPERTY(bool confirmOverwrite READ confirmOverwrite WRITE setConfirmOverwrite DESIGNABLE false)
+ Q_PROPERTY(QString defaultSuffix READ defaultSuffix WRITE setDefaultSuffix)
+ Q_PROPERTY(bool nameFilterDetailsVisible READ isNameFilterDetailsVisible
+ WRITE setNameFilterDetailsVisible DESIGNABLE false)
+ Q_PROPERTY(Options options READ options WRITE setOptions)
+
+public:
+ enum ViewMode { Detail, List };
+ enum FileMode { AnyFile, ExistingFile, Directory, ExistingFiles, DirectoryOnly };
+ enum AcceptMode { AcceptOpen, AcceptSave };
+ enum DialogLabel { LookIn, FileName, FileType, Accept, Reject };
+
+ // ### Rename to FileDialogOption and FileDialogOptions for Qt 5.0
+ enum Option
+ {
+ ShowDirsOnly = 0x00000001,
+ DontResolveSymlinks = 0x00000002,
+ DontConfirmOverwrite = 0x00000004,
+ DontUseSheet = 0x00000008,
+ DontUseNativeDialog = 0x00000010,
+ ReadOnly = 0x00000020,
+ HideNameFilterDetails = 0x00000040
+ };
+ Q_DECLARE_FLAGS(Options, Option)
+
+ QFileDialog(QWidget *parent, Qt::WindowFlags f);
+ explicit QFileDialog(QWidget *parent = 0,
+ const QString &caption = QString(),
+ const QString &directory = QString(),
+ const QString &filter = QString());
+ ~QFileDialog();
+
+ void setDirectory(const QString &directory);
+ inline void setDirectory(const QDir &directory);
+ QDir directory() const;
+
+ void selectFile(const QString &filename);
+ QStringList selectedFiles() const;
+
+#ifdef QT_DEPRECATED
+ QT_DEPRECATED void setFilter(const QString &filter);
+ QT_DEPRECATED void setFilters(const QStringList &filters);
+ QT_DEPRECATED QStringList filters() const;
+ QT_DEPRECATED void selectFilter(const QString &filter);
+ QT_DEPRECATED QString selectedFilter() const;
+#endif
+ void setNameFilterDetailsVisible(bool enabled);
+ bool isNameFilterDetailsVisible() const;
+
+ void setNameFilter(const QString &filter);
+ void setNameFilters(const QStringList &filters);
+ QStringList nameFilters() const;
+ void selectNameFilter(const QString &filter);
+ QString selectedNameFilter() const;
+
+ QDir::Filters filter() const;
+ void setFilter(QDir::Filters filters);
+
+ void setViewMode(ViewMode mode);
+ ViewMode viewMode() const;
+
+ void setFileMode(FileMode mode);
+ FileMode fileMode() const;
+
+ void setAcceptMode(AcceptMode mode);
+ AcceptMode acceptMode() const;
+
+ void setReadOnly(bool enabled);
+ bool isReadOnly() const;
+
+ void setResolveSymlinks(bool enabled);
+ bool resolveSymlinks() const;
+
+ void setSidebarUrls(const QList<QUrl> &urls);
+ QList<QUrl> sidebarUrls() const;
+
+ QByteArray saveState() const;
+ bool restoreState(const QByteArray &state);
+
+ void setConfirmOverwrite(bool enabled);
+ bool confirmOverwrite() const;
+
+ void setDefaultSuffix(const QString &suffix);
+ QString defaultSuffix() const;
+
+ void setHistory(const QStringList &paths);
+ QStringList history() const;
+
+ void setItemDelegate(QAbstractItemDelegate *delegate);
+ QAbstractItemDelegate *itemDelegate() const;
+
+ void setIconProvider(QFileIconProvider *provider);
+ QFileIconProvider *iconProvider() const;
+
+ void setLabelText(DialogLabel label, const QString &text);
+ QString labelText(DialogLabel label) const;
+
+#ifndef QT_NO_PROXYMODEL
+ void setProxyModel(QAbstractProxyModel *model);
+ QAbstractProxyModel *proxyModel() const;
+#endif
+
+ void setOption(Option option, bool on = true);
+ bool testOption(Option option) const;
+ void setOptions(Options options);
+ Options options() const;
+
+#ifdef Q_NO_USING_KEYWORD
+#ifndef Q_QDOC
+ void open() { QDialog::open(); }
+#endif
+#else
+ using QDialog::open;
+#endif
+ void open(QObject *receiver, const char *member);
+ void setVisible(bool visible);
+
+Q_SIGNALS:
+ void fileSelected(const QString &file);
+ void filesSelected(const QStringList &files);
+ void currentChanged(const QString &path);
+ void directoryEntered(const QString &directory);
+ void filterSelected(const QString &filter);
+
+public:
+#ifdef QT3_SUPPORT
+ typedef FileMode Mode;
+ inline QT3_SUPPORT void setMode(FileMode m) { setFileMode(m); }
+ inline QT3_SUPPORT FileMode mode() const { return fileMode(); }
+ inline QT3_SUPPORT void setDir(const QString &directory) { setDirectory(directory); }
+ inline QT3_SUPPORT void setDir( const QDir &directory ) { setDirectory(directory); }
+ QT3_SUPPORT QString selectedFile() const;
+#endif
+
+ static QString getOpenFileName(QWidget *parent = 0,
+ const QString &caption = QString(),
+ const QString &dir = QString(),
+ const QString &filter = QString(),
+ QString *selectedFilter = 0,
+ Options options = 0);
+
+ static QString getSaveFileName(QWidget *parent = 0,
+ const QString &caption = QString(),
+ const QString &dir = QString(),
+ const QString &filter = QString(),
+ QString *selectedFilter = 0,
+ Options options = 0);
+
+ static QString getExistingDirectory(QWidget *parent = 0,
+ const QString &caption = QString(),
+ const QString &dir = QString(),
+ Options options = ShowDirsOnly);
+
+ static QStringList getOpenFileNames(QWidget *parent = 0,
+ const QString &caption = QString(),
+ const QString &dir = QString(),
+ const QString &filter = QString(),
+ QString *selectedFilter = 0,
+ Options options = 0);
+
+#ifdef QT3_SUPPORT
+ inline static QString QT3_SUPPORT getOpenFileName(const QString &dir,
+ const QString &filter = QString(),
+ QWidget *parent = 0, const char* name = 0,
+ const QString &caption = QString(),
+ QString *selectedFilter = 0,
+ bool resolveSymlinks = true)
+ { Q_UNUSED(name);
+ return getOpenFileName(parent, caption, dir, filter, selectedFilter,
+ resolveSymlinks ? Option(0) : DontResolveSymlinks); }
+
+ inline static QString QT3_SUPPORT getSaveFileName(const QString &dir,
+ const QString &filter = QString(),
+ QWidget *parent = 0, const char* name = 0,
+ const QString &caption = QString(),
+ QString *selectedFilter = 0,
+ bool resolveSymlinks = true)
+ { Q_UNUSED(name);
+ return getSaveFileName(parent, caption, dir, filter, selectedFilter,
+ resolveSymlinks ? Option(0) : DontResolveSymlinks); }
+
+ inline static QString QT3_SUPPORT getExistingDirectory(const QString &dir,
+ QWidget *parent = 0,
+ const char* name = 0,
+ const QString &caption = QString(),
+ bool dirOnly = true,
+ bool resolveSymlinks = true)
+ { Q_UNUSED(name);
+ return getExistingDirectory(parent, caption, dir,
+ Options((resolveSymlinks ? Option(0) : DontResolveSymlinks)
+ | (dirOnly ? ShowDirsOnly : Option(0)))); }
+
+ inline static QStringList QT3_SUPPORT getOpenFileNames(const QString &filter,
+ const QString &dir = QString(),
+ QWidget *parent = 0,
+ const char* name = 0,
+ const QString &caption = QString(),
+ QString *selectedFilter = 0,
+ bool resolveSymlinks = true)
+ { Q_UNUSED(name);
+ return getOpenFileNames(parent, caption, dir, filter, selectedFilter,
+ resolveSymlinks ? Option(0) : DontResolveSymlinks); }
+#endif // QT3_SUPPORT
+
+protected:
+ QFileDialog(const QFileDialogArgs &args);
+ void done(int result);
+ void accept();
+ void changeEvent(QEvent *e);
+
+private:
+ Q_DECLARE_PRIVATE(QFileDialog)
+ Q_DISABLE_COPY(QFileDialog)
+
+ Q_PRIVATE_SLOT(d_func(), void _q_pathChanged(const QString &))
+
+ Q_PRIVATE_SLOT(d_func(), void _q_navigateBackward())
+ Q_PRIVATE_SLOT(d_func(), void _q_navigateForward())
+ Q_PRIVATE_SLOT(d_func(), void _q_navigateToParent())
+ Q_PRIVATE_SLOT(d_func(), void _q_createDirectory())
+ Q_PRIVATE_SLOT(d_func(), void _q_showListView())
+ Q_PRIVATE_SLOT(d_func(), void _q_showDetailsView())
+ Q_PRIVATE_SLOT(d_func(), void _q_showContextMenu(const QPoint &))
+ Q_PRIVATE_SLOT(d_func(), void _q_renameCurrent())
+ Q_PRIVATE_SLOT(d_func(), void _q_deleteCurrent())
+ Q_PRIVATE_SLOT(d_func(), void _q_showHidden())
+ Q_PRIVATE_SLOT(d_func(), void _q_updateOkButton())
+ Q_PRIVATE_SLOT(d_func(), void _q_currentChanged(const QModelIndex &index))
+ Q_PRIVATE_SLOT(d_func(), void _q_enterDirectory(const QModelIndex &index))
+ Q_PRIVATE_SLOT(d_func(), void _q_goToDirectory(const QString &path))
+ Q_PRIVATE_SLOT(d_func(), void _q_useNameFilter(int index))
+ Q_PRIVATE_SLOT(d_func(), void _q_selectionChanged())
+ Q_PRIVATE_SLOT(d_func(), void _q_goToUrl(const QUrl &url))
+ Q_PRIVATE_SLOT(d_func(), void _q_goHome())
+ Q_PRIVATE_SLOT(d_func(), void _q_showHeader(QAction *))
+ Q_PRIVATE_SLOT(d_func(), void _q_autoCompleteFileName(const QString &text))
+ Q_PRIVATE_SLOT(d_func(), void _q_rowsInserted(const QModelIndex & parent))
+ Q_PRIVATE_SLOT(d_func(), void _q_fileRenamed(const QString &path,
+ const QString oldName, const QString newName))
+#if defined(Q_WS_MAC)
+ Q_PRIVATE_SLOT(d_func(), void _q_macRunNativeAppModalPanel())
+#endif
+};
+
+inline void QFileDialog::setDirectory(const QDir &adirectory)
+{ setDirectory(adirectory.absolutePath()); }
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QFileDialog::Options)
+
+#endif // QT_NO_FILEDIALOG
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QFILEDIALOG_H
diff --git a/src/gui/dialogs/qfiledialog.ui b/src/widgets/dialogs/qfiledialog.ui
index 01a49f975e..01a49f975e 100644
--- a/src/gui/dialogs/qfiledialog.ui
+++ b/src/widgets/dialogs/qfiledialog.ui
diff --git a/src/gui/dialogs/qfiledialog_embedded.ui b/src/widgets/dialogs/qfiledialog_embedded.ui
index f067d31f62..f067d31f62 100644
--- a/src/gui/dialogs/qfiledialog_embedded.ui
+++ b/src/widgets/dialogs/qfiledialog_embedded.ui
diff --git a/src/gui/dialogs/qfiledialog_mac.mm b/src/widgets/dialogs/qfiledialog_mac.mm
index 885ce77c52..885ce77c52 100644
--- a/src/gui/dialogs/qfiledialog_mac.mm
+++ b/src/widgets/dialogs/qfiledialog_mac.mm
diff --git a/src/gui/dialogs/qfiledialog_p.h b/src/widgets/dialogs/qfiledialog_p.h
index 6a534bb60f..6a534bb60f 100644
--- a/src/gui/dialogs/qfiledialog_p.h
+++ b/src/widgets/dialogs/qfiledialog_p.h
diff --git a/src/gui/dialogs/qfiledialog_symbian.cpp b/src/widgets/dialogs/qfiledialog_symbian.cpp
index a4a7a228ba..a4a7a228ba 100644
--- a/src/gui/dialogs/qfiledialog_symbian.cpp
+++ b/src/widgets/dialogs/qfiledialog_symbian.cpp
diff --git a/src/widgets/dialogs/qfiledialog_win.cpp b/src/widgets/dialogs/qfiledialog_win.cpp
new file mode 100644
index 0000000000..8c3b3cfda7
--- /dev/null
+++ b/src/widgets/dialogs/qfiledialog_win.cpp
@@ -0,0 +1,839 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qfiledialog.h"
+
+#ifndef QT_NO_FILEDIALOG
+
+#include <private/qfiledialog_p.h>
+#include <qapplication.h>
+#include <private/qapplication_p.h>
+#include <qt_windows.h>
+#include <qglobal.h>
+#include <qregexp.h>
+#include <qbuffer.h>
+#include <qdir.h>
+#include <qstringlist.h>
+#include <private/qsystemlibrary_p.h>
+#include "qfiledialog_win_p.h"
+#include "qplatformnativeinterface_qpa.h"
+
+#ifndef QT_NO_THREAD
+# include <private/qmutexpool_p.h>
+#endif
+
+#ifdef Q_WS_WINCE
+#include <commdlg.h>
+bool qt_priv_ptr_valid = false;
+#else
+//we have to declare them here because they're not present for all SDK/compilers
+static const IID QT_IID_IFileOpenDialog = {0xd57c7288, 0xd4ad, 0x4768, {0xbe, 0x02, 0x9d, 0x96, 0x95, 0x32, 0xd9, 0x60} };
+static const IID QT_IID_IShellItem = {0x43826d1e, 0xe718, 0x42ee, {0xbc, 0x55, 0xa1, 0xe2, 0x61, 0xc3, 0x7b, 0xfe} };
+static const CLSID QT_CLSID_FileOpenDialog = {0xdc1c5a9c, 0xe88a, 0x4dde, {0xa5, 0xa1, 0x60, 0xf8, 0x2a, 0x20, 0xae, 0xf7} };
+#endif
+
+
+typedef qt_LPITEMIDLIST (WINAPI *PtrSHBrowseForFolder)(qt_BROWSEINFO*);
+static PtrSHBrowseForFolder ptrSHBrowseForFolder = 0;
+typedef BOOL (WINAPI *PtrSHGetPathFromIDList)(qt_LPITEMIDLIST, LPWSTR);
+static PtrSHGetPathFromIDList ptrSHGetPathFromIDList = 0;
+typedef HRESULT (WINAPI *PtrSHGetMalloc)(LPMALLOC *);
+static PtrSHGetMalloc ptrSHGetMalloc = 0;
+
+
+QT_BEGIN_NAMESPACE
+
+static void qt_win_resolve_libs()
+{
+ static bool triedResolve = false;
+
+ if (!triedResolve) {
+#ifndef QT_NO_THREAD
+ // protect initialization
+ QMutexLocker locker(QMutexPool::globalInstanceGet(&triedResolve));
+ // check triedResolve again, since another thread may have already
+ // done the initialization
+ if (triedResolve) {
+ // another thread did initialize the security function pointers,
+ // so we shouldn't do it again.
+ return;
+ }
+#endif
+
+ triedResolve = true;
+#if !defined(Q_WS_WINCE)
+ QSystemLibrary lib(L"shell32");
+ ptrSHBrowseForFolder = (PtrSHBrowseForFolder)lib.resolve("SHBrowseForFolderW");
+ ptrSHGetPathFromIDList = (PtrSHGetPathFromIDList)lib.resolve("SHGetPathFromIDListW");
+ ptrSHGetMalloc = (PtrSHGetMalloc)lib.resolve("SHGetMalloc");
+#else
+ // CE stores them in a different lib and does not use unicode version
+ HINSTANCE handle = LoadLibrary(L"Ceshell");
+ ptrSHBrowseForFolder = (PtrSHBrowseForFolder)GetProcAddress(handle, L"SHBrowseForFolder");
+ ptrSHGetPathFromIDList = (PtrSHGetPathFromIDList)GetProcAddress(handle, L"SHGetPathFromIDList");
+ ptrSHGetMalloc = (PtrSHGetMalloc)GetProcAddress(handle, L"SHGetMalloc");
+ if (ptrSHBrowseForFolder && ptrSHGetPathFromIDList && ptrSHGetMalloc)
+ qt_priv_ptr_valid = true;
+#endif
+ }
+}
+
+extern const char* qt_file_dialog_filter_reg_exp; // defined in qfiledialog.cpp
+extern QStringList qt_make_filter_list(const QString &filter);
+
+const int maxNameLen = 1023;
+const int maxMultiLen = 65535;
+
+// Returns the wildcard part of a filter.
+static QString qt_win_extract_filter(const QString &rawFilter)
+{
+ QString result = rawFilter;
+ QRegExp r(QString::fromLatin1(qt_file_dialog_filter_reg_exp));
+ int index = r.indexIn(result);
+ if (index >= 0)
+ result = r.cap(2);
+ QStringList list = result.split(QLatin1Char(' '));
+ for(QStringList::iterator it = list.begin(); it < list.end(); ++it) {
+ if (*it == QLatin1String("*")) {
+ *it = QLatin1String("*.*");
+ break;
+ }
+ }
+ return list.join(QLatin1String(";"));
+}
+
+static QStringList qt_win_make_filters_list(const QString &filter)
+{
+ QString f(filter);
+
+ if (f.isEmpty())
+ f = QFileDialog::tr("All Files (*.*)");
+
+ return qt_make_filter_list(f);
+}
+
+// Makes a NUL-oriented Windows filter from a Qt filter.
+static QString qt_win_filter(const QString &filter, bool hideFiltersDetails)
+{
+ QStringList filterLst = qt_win_make_filters_list(filter);
+ QStringList::Iterator it = filterLst.begin();
+ QString winfilters;
+ QRegExp r(QString::fromLatin1(qt_file_dialog_filter_reg_exp));
+ for (; it != filterLst.end(); ++it) {
+ QString subfilter = *it;
+ if (!subfilter.isEmpty()) {
+ if (hideFiltersDetails) {
+ int index = r.indexIn(subfilter);
+ if (index >= 0)
+ winfilters += r.cap(1);
+ } else {
+ winfilters += subfilter;
+ }
+ winfilters += QChar();
+ winfilters += qt_win_extract_filter(subfilter);
+ winfilters += QChar();
+ }
+ }
+ winfilters += QChar();
+ return winfilters;
+}
+
+static QString qt_win_selected_filter(const QString &filter, DWORD idx)
+{
+ return qt_win_make_filters_list(filter).at((int)idx - 1);
+}
+
+static QString tFilters, tTitle, tInitDir;
+
+static OPENFILENAME* qt_win_make_OFN(QWidget *parent,
+ const QString& initialSelection,
+ const QString& initialDirectory,
+ const QString& title,
+ const QString& filters,
+ QFileDialog::FileMode mode,
+ QFileDialog::Options options)
+{
+ if (parent)
+ parent = parent->window();
+ else
+ parent = QApplication::activeWindow();
+
+ tInitDir = QDir::toNativeSeparators(initialDirectory);
+ tFilters = filters;
+ tTitle = title;
+ QString initSel = QDir::toNativeSeparators(initialSelection);
+ if (!initSel.isEmpty()) {
+ initSel.remove(QLatin1Char('<'));
+ initSel.remove(QLatin1Char('>'));
+ initSel.remove(QLatin1Char('\"'));
+ initSel.remove(QLatin1Char('|'));
+ }
+
+ int maxLen = mode == QFileDialog::ExistingFiles ? maxMultiLen : maxNameLen;
+ wchar_t *tInitSel = new wchar_t[maxLen + 1];
+ if (initSel.length() > 0 && initSel.length() <= maxLen)
+ memcpy(tInitSel, initSel.utf16(), (initSel.length()+1)*sizeof(QChar));
+ else
+ tInitSel[0] = 0;
+
+ OPENFILENAME* ofn = new OPENFILENAME;
+ memset(ofn, 0, sizeof(OPENFILENAME));
+
+ ofn->lStructSize = sizeof(OPENFILENAME);
+ ofn->hwndOwner = QApplicationPrivate::getHWNDForWidget(parent);
+ ofn->lpstrFilter = (wchar_t*)tFilters.utf16();
+ ofn->lpstrFile = tInitSel;
+ ofn->nMaxFile = maxLen;
+ ofn->lpstrInitialDir = (wchar_t*)tInitDir.utf16();
+ ofn->lpstrTitle = (wchar_t*)tTitle.utf16();
+ ofn->Flags = (OFN_NOCHANGEDIR | OFN_HIDEREADONLY | OFN_EXPLORER | OFN_PATHMUSTEXIST);
+ if (mode == QFileDialog::ExistingFile ||
+ mode == QFileDialog::ExistingFiles)
+ ofn->Flags |= (OFN_FILEMUSTEXIST);
+ if (mode == QFileDialog::ExistingFiles)
+ ofn->Flags |= (OFN_ALLOWMULTISELECT);
+ if (!(options & QFileDialog::DontConfirmOverwrite))
+ ofn->Flags |= OFN_OVERWRITEPROMPT;
+
+ return ofn;
+}
+
+static void qt_win_clean_up_OFN(OPENFILENAME **ofn)
+{
+ delete [] (*ofn)->lpstrFile;
+ delete *ofn;
+ *ofn = 0;
+}
+
+void qt_win_eatMouseMove()
+{
+ // after closing a windows dialog with a double click (i.e. open a file)
+ // the message queue still contains a dubious WM_MOUSEMOVE message where
+ // the left button is reported to be down (wParam != 0).
+ // remove all those messages (usually 1) and post the last one with a
+ // reset button state
+
+ MSG msg = {0, 0, 0, 0, 0, {0, 0} };
+ while (PeekMessage(&msg, 0, WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE))
+ ;
+ if (msg.message == WM_MOUSEMOVE)
+ PostMessage(msg.hwnd, msg.message, 0, msg.lParam);
+}
+
+QString qt_win_get_open_file_name(const QFileDialogArgs &args,
+ QString *initialDirectory,
+ QString *selectedFilter)
+{
+ QString result;
+
+ QString isel = args.selection;
+
+ if (initialDirectory && initialDirectory->left(5) == QLatin1String("file:"))
+ initialDirectory->remove(0, 5);
+ QFileInfo fi(*initialDirectory);
+
+ if (initialDirectory && !fi.isDir()) {
+ *initialDirectory = fi.absolutePath();
+ if (isel.isEmpty())
+ isel = fi.fileName();
+ }
+
+ if (!fi.exists())
+ *initialDirectory = QDir::homePath();
+
+ DWORD selFilIdx = 0;
+
+ int idx = 0;
+ if (selectedFilter) {
+ QStringList filterLst = qt_win_make_filters_list(args.filter);
+ idx = filterLst.indexOf(*selectedFilter);
+ }
+
+ QDialog modal_widget;
+ modal_widget.setAttribute(Qt::WA_NoChildEventsForParent, true);
+ modal_widget.setParent(args.parent, Qt::Window);
+ QApplicationPrivate::enterModal(&modal_widget);
+
+ bool hideFiltersDetails = args.options & QFileDialog::HideNameFilterDetails;
+ OPENFILENAME* ofn = qt_win_make_OFN(args.parent, args.selection,
+ args.directory, args.caption,
+ qt_win_filter(args.filter, hideFiltersDetails),
+ QFileDialog::ExistingFile,
+ args.options);
+ if (idx)
+ ofn->nFilterIndex = idx + 1;
+ if (GetOpenFileName(ofn)) {
+ result = QString::fromWCharArray(ofn->lpstrFile);
+ selFilIdx = ofn->nFilterIndex;
+ }
+ qt_win_clean_up_OFN(&ofn);
+
+ QApplicationPrivate::leaveModal(&modal_widget);
+
+ qt_win_eatMouseMove();
+
+ if (result.isEmpty())
+ return result;
+
+ fi = result;
+ *initialDirectory = fi.path();
+ if (selectedFilter)
+ *selectedFilter = qt_win_selected_filter(args.filter, selFilIdx);
+ return fi.absoluteFilePath();
+}
+
+QString qt_win_get_save_file_name(const QFileDialogArgs &args,
+ QString *initialDirectory,
+ QString *selectedFilter)
+{
+ QString result;
+
+ QString isel = args.selection;
+ if (initialDirectory && initialDirectory->left(5) == QLatin1String("file:"))
+ initialDirectory->remove(0, 5);
+ QFileInfo fi(*initialDirectory);
+
+ if (initialDirectory && !fi.isDir()) {
+ *initialDirectory = fi.absolutePath();
+ if (isel.isEmpty())
+ isel = fi.fileName();
+ }
+
+ if (!fi.exists())
+ *initialDirectory = QDir::homePath();
+
+ DWORD selFilIdx = 0;
+
+ int idx = 0;
+ if (selectedFilter) {
+ QStringList filterLst = qt_win_make_filters_list(args.filter);
+ idx = filterLst.indexOf(*selectedFilter);
+ }
+
+ QDialog modal_widget;
+ modal_widget.setAttribute(Qt::WA_NoChildEventsForParent, true);
+ modal_widget.setParent(args.parent, Qt::Window);
+ QApplicationPrivate::enterModal(&modal_widget);
+ bool hideFiltersDetails = args.options & QFileDialog::HideNameFilterDetails;
+ // This block is used below for the lpstrDefExt member.
+ // Note that the current MSDN docs document this member wrong.
+ // It should rather be documented as "the default extension if no extension was given and if the
+ // current filter does not have a extension (e.g (*)). If the current filter have an extension, use
+ // the extension of the current filter"
+ QString defaultSaveExt;
+ if (selectedFilter && !selectedFilter->isEmpty()) {
+ defaultSaveExt = qt_win_extract_filter(*selectedFilter);
+ // make sure we only have the extension
+ int firstDot = defaultSaveExt.indexOf(QLatin1Char('.'));
+ if (firstDot != -1) {
+ defaultSaveExt.remove(0, firstDot + 1);
+ } else {
+ defaultSaveExt.clear();
+ }
+ }
+
+ OPENFILENAME *ofn = qt_win_make_OFN(args.parent, args.selection,
+ args.directory, args.caption,
+ qt_win_filter(args.filter, hideFiltersDetails),
+ QFileDialog::AnyFile,
+ args.options);
+
+ ofn->lpstrDefExt = (wchar_t*)defaultSaveExt.utf16();
+
+ if (idx)
+ ofn->nFilterIndex = idx + 1;
+ if (GetSaveFileName(ofn)) {
+ result = QString::fromWCharArray(ofn->lpstrFile);
+ selFilIdx = ofn->nFilterIndex;
+ }
+ qt_win_clean_up_OFN(&ofn);
+
+#if defined(Q_WS_WINCE)
+ int semIndex = result.indexOf(QLatin1Char(';'));
+ if (semIndex >= 0)
+ result = result.left(semIndex);
+#endif
+
+ QApplicationPrivate::leaveModal(&modal_widget);
+
+ qt_win_eatMouseMove();
+
+ if (result.isEmpty())
+ return result;
+
+ fi = result;
+ *initialDirectory = fi.path();
+ if (selectedFilter)
+ *selectedFilter = qt_win_selected_filter(args.filter, selFilIdx);
+ return fi.absoluteFilePath();
+}
+
+
+#ifndef Q_WS_WINCE
+
+typedef HRESULT (WINAPI *PtrSHCreateItemFromParsingName)(PCWSTR pszPath, IBindCtx *pbc, REFIID riid, void **ppv);
+static PtrSHCreateItemFromParsingName pSHCreateItemFromParsingName = 0;
+
+static bool qt_win_set_IFileDialogOptions(IFileDialog *pfd,
+ const QString& initialSelection,
+ const QString& initialDirectory,
+ const QString& title,
+ const QStringList& filterLst,
+ QFileDialog::FileMode mode,
+ QFileDialog::Options options)
+{
+ if (!pSHCreateItemFromParsingName) {
+ // This function is available only in Vista & above.
+ QSystemLibrary shellLib(QLatin1String("Shell32"));
+ pSHCreateItemFromParsingName = (PtrSHCreateItemFromParsingName)
+ shellLib.resolve("SHCreateItemFromParsingName");
+ if (!pSHCreateItemFromParsingName)
+ return false;
+ }
+ HRESULT hr;
+ QString winfilters;
+ int numFilters = 0;
+ quint32 currentOffset = 0;
+ QList<quint32> offsets;
+ QStringList::ConstIterator it = filterLst.begin();
+ // Create the native filter string and save offset to each entry.
+ for (; it != filterLst.end(); ++it) {
+ QString subfilter = *it;
+ if (!subfilter.isEmpty()) {
+ offsets<<currentOffset;
+ //Here the COMMON_ITEM_DIALOG API always add the details for the filter (e.g. *.txt)
+ //so we don't need to handle the flag HideNameFilterDetails.
+ winfilters += subfilter; // The name of the filter.
+ winfilters += QChar();
+ currentOffset += subfilter.size()+1;
+ offsets<<currentOffset;
+ QString spec = qt_win_extract_filter(subfilter);
+ winfilters += spec; // The actual filter spec.
+ winfilters += QChar();
+ currentOffset += spec.size()+1;
+ numFilters++;
+ }
+ }
+ // Add the filters to the file dialog.
+ if (numFilters) {
+ wchar_t *szData = (wchar_t*)winfilters.utf16();
+ qt_COMDLG_FILTERSPEC *filterSpec = new qt_COMDLG_FILTERSPEC[numFilters];
+ for(int i = 0; i<numFilters; i++) {
+ filterSpec[i].pszName = szData+offsets[i*2];
+ filterSpec[i].pszSpec = szData+offsets[(i*2)+1];
+ }
+ hr = pfd->SetFileTypes(numFilters, filterSpec);
+ delete []filterSpec;
+ }
+ // Set the starting folder.
+ tInitDir = QDir::toNativeSeparators(initialDirectory);
+ if (!tInitDir.isEmpty()) {
+ IShellItem *psiDefaultFolder;
+ hr = pSHCreateItemFromParsingName((wchar_t*)tInitDir.utf16(), NULL, QT_IID_IShellItem,
+ reinterpret_cast<void**>(&psiDefaultFolder));
+
+ if (SUCCEEDED(hr)) {
+ hr = pfd->SetFolder(psiDefaultFolder);
+ psiDefaultFolder->Release();
+ }
+ }
+ // Set the currently selected file.
+ QString initSel = QDir::toNativeSeparators(initialSelection);
+ if (!initSel.isEmpty()) {
+ initSel.remove(QLatin1Char('<'));
+ initSel.remove(QLatin1Char('>'));
+ initSel.remove(QLatin1Char('\"'));
+ initSel.remove(QLatin1Char('|'));
+ }
+ if (!initSel.isEmpty()) {
+ hr = pfd->SetFileName((wchar_t*)initSel.utf16());
+ }
+ // Set the title for the file dialog.
+ if (!title.isEmpty()) {
+ hr = pfd->SetTitle((wchar_t*)title.utf16());
+ }
+ // Set other flags for the dialog.
+ DWORD newOptions;
+ hr = pfd->GetOptions(&newOptions);
+ if (SUCCEEDED(hr)) {
+ newOptions |= FOS_NOCHANGEDIR;
+ if (mode == QFileDialog::ExistingFile ||
+ mode == QFileDialog::ExistingFiles)
+ newOptions |= (FOS_FILEMUSTEXIST | FOS_PATHMUSTEXIST);
+ if (mode == QFileDialog::ExistingFiles)
+ newOptions |= FOS_ALLOWMULTISELECT;
+ if (!(options & QFileDialog::DontConfirmOverwrite))
+ newOptions |= FOS_OVERWRITEPROMPT;
+ hr = pfd->SetOptions(newOptions);
+ }
+ return SUCCEEDED(hr);
+}
+
+static QStringList qt_win_CID_get_open_file_names(const QFileDialogArgs &args,
+ QString *initialDirectory,
+ const QStringList &filterList,
+ QString *selectedFilter,
+ int selectedFilterIndex)
+{
+ QStringList result;
+ QDialog modal_widget;
+ modal_widget.setAttribute(Qt::WA_NoChildEventsForParent, true);
+ modal_widget.setParent(args.parent, Qt::Window);
+ QApplicationPrivate::enterModal(&modal_widget);
+ // Multiple selection is allowed only in IFileOpenDialog.
+ IFileOpenDialog *pfd = 0;
+ HRESULT hr = CoCreateInstance(QT_CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER, QT_IID_IFileOpenDialog,
+ reinterpret_cast<void**>(&pfd));
+
+ if (SUCCEEDED(hr)) {
+ qt_win_set_IFileDialogOptions(pfd, args.selection,
+ args.directory, args.caption,
+ filterList, QFileDialog::ExistingFiles,
+ args.options);
+ // Set the currently selected filter (one-based index).
+ hr = pfd->SetFileTypeIndex(selectedFilterIndex+1);
+ QWidget *parentWindow = args.parent;
+ if (parentWindow)
+ parentWindow = parentWindow->window();
+ else
+ parentWindow = QApplication::activeWindow();
+ // Show the file dialog.
+ hr = pfd->Show(QApplicationPrivate::getHWNDForWidget(parentWindow));
+ if (SUCCEEDED(hr)) {
+ // Retrieve the results.
+ IShellItemArray *psiaResults;
+ hr = pfd->GetResults(&psiaResults);
+ if (SUCCEEDED(hr)) {
+ DWORD numItems = 0;
+ psiaResults->GetCount(&numItems);
+ for (DWORD i = 0; i<numItems; i++) {
+ IShellItem *psi = 0;
+ hr = psiaResults->GetItemAt(i, &psi);
+ if (SUCCEEDED(hr)) {
+ // Retrieve the file name from shell item.
+ wchar_t *pszPath;
+ hr = psi->GetDisplayName(SIGDN_FILESYSPATH, &pszPath);
+ if (SUCCEEDED(hr)) {
+ QString fileName = QString::fromWCharArray(pszPath);
+ result.append(fileName);
+ CoTaskMemFree(pszPath);
+ }
+ psi->Release(); // Free the current item.
+ }
+ }
+ psiaResults->Release(); // Free the array of items.
+ }
+ }
+ }
+ QApplicationPrivate::leaveModal(&modal_widget);
+
+ qt_win_eatMouseMove();
+
+ if (!result.isEmpty()) {
+ // Retrieve the current folder name.
+ IShellItem *psi = 0;
+ hr = pfd->GetFolder(&psi);
+ if (SUCCEEDED(hr)) {
+ wchar_t *pszPath;
+ hr = psi->GetDisplayName(SIGDN_FILESYSPATH, &pszPath);
+ if (SUCCEEDED(hr)) {
+ *initialDirectory = QString::fromWCharArray(pszPath);
+ CoTaskMemFree(pszPath);
+ }
+ psi->Release();
+ }
+ // Retrieve the currently selected filter.
+ if (selectedFilter) {
+ quint32 filetype = 0;
+ hr = pfd->GetFileTypeIndex(&filetype);
+ if (SUCCEEDED(hr) && filetype && filetype <= (quint32)filterList.length()) {
+ // This is a one-based index, not zero-based.
+ *selectedFilter = filterList[filetype-1];
+ }
+ }
+ }
+ if (pfd)
+ pfd->Release();
+ return result;
+}
+
+QString qt_win_CID_get_existing_directory(const QFileDialogArgs &args)
+{
+ QString result;
+ QDialog modal_widget;
+ modal_widget.setAttribute(Qt::WA_NoChildEventsForParent, true);
+ modal_widget.setParent(args.parent, Qt::Window);
+ QApplicationPrivate::enterModal(&modal_widget);
+
+ IFileOpenDialog *pfd = 0;
+ HRESULT hr = CoCreateInstance(QT_CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER,
+ QT_IID_IFileOpenDialog, reinterpret_cast<void**>(&pfd));
+
+ if (SUCCEEDED(hr)) {
+ qt_win_set_IFileDialogOptions(pfd, args.selection,
+ args.directory, args.caption,
+ QStringList(), QFileDialog::ExistingFiles,
+ args.options);
+
+ // Set the FOS_PICKFOLDERS flag
+ DWORD newOptions;
+ hr = pfd->GetOptions(&newOptions);
+ newOptions |= (FOS_PICKFOLDERS | FOS_FORCEFILESYSTEM);
+ if (SUCCEEDED(hr) && SUCCEEDED((hr = pfd->SetOptions(newOptions)))) {
+ QWidget *parentWindow = args.parent;
+ if (parentWindow)
+ parentWindow = parentWindow->window();
+ else
+ parentWindow = QApplication::activeWindow();
+
+ // Show the file dialog.
+ hr = pfd->Show(QApplicationPrivate::getHWNDForWidget(parentWindow));
+ if (SUCCEEDED(hr)) {
+ // Retrieve the result
+ IShellItem *psi = 0;
+ hr = pfd->GetResult(&psi);
+ if (SUCCEEDED(hr)) {
+ // Retrieve the file name from shell item.
+ wchar_t *pszPath;
+ hr = psi->GetDisplayName(SIGDN_FILESYSPATH, &pszPath);
+ if (SUCCEEDED(hr)) {
+ result = QString::fromWCharArray(pszPath);
+ CoTaskMemFree(pszPath);
+ }
+ psi->Release(); // Free the current item.
+ }
+ }
+ }
+ }
+ QApplicationPrivate::leaveModal(&modal_widget);
+
+ qt_win_eatMouseMove();
+
+ if (pfd)
+ pfd->Release();
+ return result;
+}
+
+#endif
+
+QStringList qt_win_get_open_file_names(const QFileDialogArgs &args,
+ QString *initialDirectory,
+ QString *selectedFilter)
+{
+ QFileInfo fi;
+ QDir dir;
+
+ if (initialDirectory && initialDirectory->left(5) == QLatin1String("file:"))
+ initialDirectory->remove(0, 5);
+ fi = QFileInfo(*initialDirectory);
+
+ if (initialDirectory && !fi.isDir()) {
+ *initialDirectory = fi.absolutePath();
+ }
+
+ if (!fi.exists())
+ *initialDirectory = QDir::homePath();
+
+ DWORD selFilIdx = 0;
+
+ QStringList filterLst = qt_win_make_filters_list(args.filter);
+ int idx = 0;
+ if (selectedFilter) {
+ idx = filterLst.indexOf(*selectedFilter);
+ }
+ // Windows Vista (& above) allows users to search from file dialogs. If user selects
+ // multiple files belonging to different folders from these search results, the
+ // GetOpenFileName() will return only one folder name for all the files. To retrieve
+ // the correct path for all selected files, we have to use Common Item Dialog interfaces.
+#ifndef Q_WS_WINCE
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)
+ return qt_win_CID_get_open_file_names(args, initialDirectory, filterLst, selectedFilter, idx);
+#endif
+
+ QStringList result;
+ QDialog modal_widget;
+ modal_widget.setAttribute(Qt::WA_NoChildEventsForParent, true);
+ modal_widget.setParent(args.parent, Qt::Window);
+ QApplicationPrivate::enterModal(&modal_widget);
+
+ bool hideFiltersDetails = args.options & QFileDialog::HideNameFilterDetails;
+ OPENFILENAME* ofn = qt_win_make_OFN(args.parent, args.selection,
+ args.directory, args.caption,
+ qt_win_filter(args.filter, hideFiltersDetails),
+ QFileDialog::ExistingFiles,
+ args.options);
+ if (idx)
+ ofn->nFilterIndex = idx + 1;
+ if (GetOpenFileName(ofn)) {
+ QString fileOrDir = QString::fromWCharArray(ofn->lpstrFile);
+ selFilIdx = ofn->nFilterIndex;
+ int offset = fileOrDir.length() + 1;
+ if (ofn->lpstrFile[offset] == 0) {
+ // Only one file selected; has full path
+ fi.setFile(fileOrDir);
+ QString res = fi.absoluteFilePath();
+ if (!res.isEmpty())
+ result.append(res);
+ }
+ else {
+ // Several files selected; first string is path
+ dir.setPath(fileOrDir);
+ QString f;
+ while(!(f = QString::fromWCharArray(ofn->lpstrFile + offset)).isEmpty()) {
+ fi.setFile(dir, f);
+ QString res = fi.absoluteFilePath();
+ if (!res.isEmpty())
+ result.append(res);
+ offset += f.length() + 1;
+ }
+ }
+ }
+ qt_win_clean_up_OFN(&ofn);
+
+ QApplicationPrivate::leaveModal(&modal_widget);
+
+ qt_win_eatMouseMove();
+
+ if (!result.isEmpty()) {
+ *initialDirectory = fi.path(); // only save the path if there is a result
+ if (selectedFilter)
+ *selectedFilter = qt_win_selected_filter(args.filter, selFilIdx);
+ }
+ return result;
+}
+
+// MFC Directory Dialog. Contrib: Steve Williams (minor parts from Scott Powers)
+
+static int __stdcall winGetExistDirCallbackProc(HWND hwnd,
+ UINT uMsg,
+ LPARAM lParam,
+ LPARAM lpData)
+{
+ if (uMsg == BFFM_INITIALIZED && lpData != 0) {
+ QString *initDir = (QString *)(lpData);
+ if (!initDir->isEmpty()) {
+ SendMessage(hwnd, BFFM_SETSELECTION, TRUE, LPARAM(initDir->utf16()));
+ }
+ } else if (uMsg == BFFM_SELCHANGED) {
+ qt_win_resolve_libs();
+ if (ptrSHGetPathFromIDList) {
+ wchar_t path[MAX_PATH];
+ ptrSHGetPathFromIDList(qt_LPITEMIDLIST(lParam), path);
+ QString tmpStr = QString::fromWCharArray(path);
+ if (!tmpStr.isEmpty())
+ SendMessage(hwnd, BFFM_ENABLEOK, 1, 1);
+ else
+ SendMessage(hwnd, BFFM_ENABLEOK, 0, 0);
+ SendMessage(hwnd, BFFM_SETSTATUSTEXT, 1, LPARAM(path));
+ }
+ }
+ return 0;
+}
+
+QString qt_win_get_existing_directory(const QFileDialogArgs &args)
+{
+#ifndef Q_WS_WINCE
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)
+ return qt_win_CID_get_existing_directory(args);
+#endif
+
+ QString currentDir = QDir::currentPath();
+ QString result;
+ QWidget *parent = args.parent;
+ if (parent)
+ parent = parent->window();
+ else
+ parent = QApplication::activeWindow();
+ if (parent)
+ parent->createWinId();
+
+ QDialog modal_widget;
+ modal_widget.setAttribute(Qt::WA_NoChildEventsForParent, true);
+ modal_widget.setParent(parent, Qt::Window);
+ QApplicationPrivate::enterModal(&modal_widget);
+
+ QString initDir = QDir::toNativeSeparators(args.directory);
+ wchar_t path[MAX_PATH];
+ wchar_t initPath[MAX_PATH];
+ initPath[0] = 0;
+ path[0] = 0;
+ tTitle = args.caption;
+
+ qt_BROWSEINFO bi;
+
+ Q_ASSERT(!parent ||parent->testAttribute(Qt::WA_WState_Created));
+ bi.hwndOwner = QApplicationPrivate::getHWNDForWidget(parent);
+ bi.pidlRoot = NULL;
+ //### This does not seem to be respected? - the dialog always displays "Browse for folder"
+ bi.lpszTitle = (wchar_t*)tTitle.utf16();
+ bi.pszDisplayName = initPath;
+ bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT | BIF_NEWDIALOGSTYLE;
+ bi.lpfn = winGetExistDirCallbackProc;
+ bi.lParam = LPARAM(&initDir);
+
+ qt_win_resolve_libs();
+ if (ptrSHBrowseForFolder) {
+ qt_LPITEMIDLIST pItemIDList = ptrSHBrowseForFolder(&bi);
+ if (pItemIDList) {
+ ptrSHGetPathFromIDList(pItemIDList, path);
+ IMalloc *pMalloc;
+ if (ptrSHGetMalloc(&pMalloc) == NOERROR) {
+ pMalloc->Free(pItemIDList);
+ pMalloc->Release();
+ result = QString::fromWCharArray(path);
+ }
+ }
+ }
+ tTitle = QString();
+
+ QApplicationPrivate::leaveModal(&modal_widget);
+
+ qt_win_eatMouseMove();
+
+ if (!result.isEmpty())
+ result.replace(QLatin1Char('\\'), QLatin1Char('/'));
+ return result;
+}
+
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/gui/dialogs/qfiledialog_win_p.h b/src/widgets/dialogs/qfiledialog_win_p.h
index 1ff29d2e26..1ff29d2e26 100644
--- a/src/gui/dialogs/qfiledialog_win_p.h
+++ b/src/widgets/dialogs/qfiledialog_win_p.h
diff --git a/src/gui/dialogs/qfileinfogatherer.cpp b/src/widgets/dialogs/qfileinfogatherer.cpp
index 315b93131f..315b93131f 100644
--- a/src/gui/dialogs/qfileinfogatherer.cpp
+++ b/src/widgets/dialogs/qfileinfogatherer.cpp
diff --git a/src/gui/dialogs/qfileinfogatherer_p.h b/src/widgets/dialogs/qfileinfogatherer_p.h
index 98217c1dc8..98217c1dc8 100644
--- a/src/gui/dialogs/qfileinfogatherer_p.h
+++ b/src/widgets/dialogs/qfileinfogatherer_p.h
diff --git a/src/gui/dialogs/qfilesystemmodel.cpp b/src/widgets/dialogs/qfilesystemmodel.cpp
index 10d627c594..10d627c594 100644
--- a/src/gui/dialogs/qfilesystemmodel.cpp
+++ b/src/widgets/dialogs/qfilesystemmodel.cpp
diff --git a/src/widgets/dialogs/qfilesystemmodel.h b/src/widgets/dialogs/qfilesystemmodel.h
new file mode 100644
index 0000000000..ce907cd10e
--- /dev/null
+++ b/src/widgets/dialogs/qfilesystemmodel.h
@@ -0,0 +1,180 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QFILESYSTEMMODEL_H
+#define QFILESYSTEMMODEL_H
+
+#include <QtCore/qabstractitemmodel.h>
+#include <QtCore/qpair.h>
+#include <QtCore/qdir.h>
+#include <QtWidgets/qicon.h>
+#include <QtCore/qdiriterator.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_FILESYSTEMMODEL
+
+class ExtendedInformation;
+class QFileSystemModelPrivate;
+class QFileIconProvider;
+
+class Q_WIDGETS_EXPORT QFileSystemModel : public QAbstractItemModel
+{
+ Q_OBJECT
+ Q_PROPERTY(bool resolveSymlinks READ resolveSymlinks WRITE setResolveSymlinks)
+ Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly)
+ Q_PROPERTY(bool nameFilterDisables READ nameFilterDisables WRITE setNameFilterDisables)
+
+Q_SIGNALS:
+ void rootPathChanged(const QString &newPath);
+ void fileRenamed(const QString &path, const QString &oldName, const QString &newName);
+ void directoryLoaded(const QString &path);
+
+public:
+ enum Roles {
+ FileIconRole = Qt::DecorationRole,
+ FilePathRole = Qt::UserRole + 1,
+ FileNameRole = Qt::UserRole + 2,
+ FilePermissions = Qt::UserRole + 3
+ };
+
+ explicit QFileSystemModel(QObject *parent = 0);
+ ~QFileSystemModel();
+
+ QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
+ QModelIndex index(const QString &path, int column = 0) const;
+ QModelIndex parent(const QModelIndex &child) const;
+ bool hasChildren(const QModelIndex &parent = QModelIndex()) const;
+ bool canFetchMore(const QModelIndex &parent) const;
+ void fetchMore(const QModelIndex &parent);
+
+ int rowCount(const QModelIndex &parent = QModelIndex()) const;
+ int columnCount(const QModelIndex &parent = QModelIndex()) const;
+
+ QVariant myComputer(int role = Qt::DisplayRole) const;
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+ bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
+
+ QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
+
+ Qt::ItemFlags flags(const QModelIndex &index) const;
+
+ void sort(int column, Qt::SortOrder order = Qt::AscendingOrder);
+
+ QStringList mimeTypes() const;
+ QMimeData *mimeData(const QModelIndexList &indexes) const;
+ bool dropMimeData(const QMimeData *data, Qt::DropAction action,
+ int row, int column, const QModelIndex &parent);
+ Qt::DropActions supportedDropActions() const;
+
+ // QFileSystemModel specific API
+ QModelIndex setRootPath(const QString &path);
+ QString rootPath() const;
+ QDir rootDirectory() const;
+
+ void setIconProvider(QFileIconProvider *provider);
+ QFileIconProvider *iconProvider() const;
+
+ void setFilter(QDir::Filters filters);
+ QDir::Filters filter() const;
+
+ void setResolveSymlinks(bool enable);
+ bool resolveSymlinks() const;
+
+ void setReadOnly(bool enable);
+ bool isReadOnly() const;
+
+ void setNameFilterDisables(bool enable);
+ bool nameFilterDisables() const;
+
+ void setNameFilters(const QStringList &filters);
+ QStringList nameFilters() const;
+
+ QString filePath(const QModelIndex &index) const;
+ bool isDir(const QModelIndex &index) const;
+ qint64 size(const QModelIndex &index) const;
+ QString type(const QModelIndex &index) const;
+ QDateTime lastModified(const QModelIndex &index) const;
+
+ QModelIndex mkdir(const QModelIndex &parent, const QString &name);
+ bool rmdir(const QModelIndex &index) const; // ### Qt5: should not be const
+ inline QString fileName(const QModelIndex &index) const;
+ inline QIcon fileIcon(const QModelIndex &index) const;
+ QFile::Permissions permissions(const QModelIndex &index) const;
+ inline QFileInfo fileInfo(const QModelIndex &index) const;
+ bool remove(const QModelIndex &index) const;
+
+protected:
+ QFileSystemModel(QFileSystemModelPrivate &, QObject *parent = 0);
+ void timerEvent(QTimerEvent *event);
+ bool event(QEvent *event);
+
+private:
+ Q_DECLARE_PRIVATE(QFileSystemModel)
+ Q_DISABLE_COPY(QFileSystemModel)
+
+ Q_PRIVATE_SLOT(d_func(), void _q_directoryChanged(const QString &directory, const QStringList &list))
+ Q_PRIVATE_SLOT(d_func(), void _q_performDelayedSort())
+ Q_PRIVATE_SLOT(d_func(), void _q_fileSystemChanged(const QString &path, const QList<QPair<QString, QFileInfo> > &))
+ Q_PRIVATE_SLOT(d_func(), void _q_resolvedName(const QString &fileName, const QString &resolvedName))
+
+ friend class QFileDialogPrivate;
+};
+
+inline QString QFileSystemModel::fileName(const QModelIndex &aindex) const
+{ return aindex.data(Qt::DisplayRole).toString(); }
+inline QIcon QFileSystemModel::fileIcon(const QModelIndex &aindex) const
+{ return qvariant_cast<QIcon>(aindex.data(Qt::DecorationRole)); }
+inline QFileInfo QFileSystemModel::fileInfo(const QModelIndex &aindex) const
+{ return QFileInfo(filePath(aindex)); }
+
+#endif // QT_NO_FILESYSTEMMODEL
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QFILESYSTEMMODEL_H
+
diff --git a/src/gui/dialogs/qfilesystemmodel_p.h b/src/widgets/dialogs/qfilesystemmodel_p.h
index 3d5f5b7f00..3d5f5b7f00 100644
--- a/src/gui/dialogs/qfilesystemmodel_p.h
+++ b/src/widgets/dialogs/qfilesystemmodel_p.h
diff --git a/src/widgets/dialogs/qfontdialog.cpp b/src/widgets/dialogs/qfontdialog.cpp
new file mode 100644
index 0000000000..df49fee9bb
--- /dev/null
+++ b/src/widgets/dialogs/qfontdialog.cpp
@@ -0,0 +1,1077 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowdefs.h"
+
+#ifndef QT_NO_FONTDIALOG
+
+#include "qfontdialog.h"
+#include "qfontdialog_p.h"
+
+#include <qapplication.h>
+#include <qcheckbox.h>
+#include <qcombobox.h>
+#include <qevent.h>
+#include <qfontdatabase.h>
+#include <qgroupbox.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qlineedit.h>
+#include <qpushbutton.h>
+#include <qstyle.h>
+#include <qdialogbuttonbox.h>
+#include <qheaderview.h>
+#include <qlistview.h>
+#include <qstringlistmodel.h>
+#include <qvalidator.h>
+#include <private/qdialog_p.h>
+#include <private/qfont_p.h>
+
+#if defined(Q_WS_S60)
+#include <QtWidgets/qdesktopwidget.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+class QFontListView : public QListView
+{
+ Q_OBJECT
+public:
+ QFontListView(QWidget *parent);
+ inline QStringListModel *model() const {
+ return static_cast<QStringListModel *>(QListView::model());
+ }
+ inline void setCurrentItem(int item) {
+ QListView::setCurrentIndex(static_cast<QAbstractListModel*>(model())->index(item));
+ }
+ inline int currentItem() const {
+ return QListView::currentIndex().row();
+ }
+ inline int count() const {
+ return model()->rowCount();
+ }
+ inline QString currentText() const {
+ int row = QListView::currentIndex().row();
+ return row < 0 ? QString() : model()->stringList().at(row);
+ }
+ void currentChanged(const QModelIndex &current, const QModelIndex &previous) {
+ QListView::currentChanged(current, previous);
+ if (current.isValid())
+ emit highlighted(current.row());
+ }
+ QString text(int i) const {
+ return model()->stringList().at(i);
+ }
+signals:
+ void highlighted(int);
+};
+
+QFontListView::QFontListView(QWidget *parent)
+ : QListView(parent)
+{
+ setModel(new QStringListModel(parent));
+ setEditTriggers(NoEditTriggers);
+}
+
+static const Qt::WindowFlags DefaultWindowFlags =
+ Qt::Dialog | Qt::WindowSystemMenuHint;
+
+/*!
+ \class QFontDialog
+ \ingroup standard-dialogs
+
+ \brief The QFontDialog class provides a dialog widget for selecting a font.
+
+ A font dialog is created through one of the static getFont()
+ functions.
+
+ Examples:
+
+ \snippet doc/src/snippets/code/src_gui_dialogs_qfontdialog.cpp 0
+
+ The dialog can also be used to set a widget's font directly:
+ \snippet doc/src/snippets/code/src_gui_dialogs_qfontdialog.cpp 1
+ If the user clicks OK the font they chose will be used for myWidget,
+ and if they click Cancel the original font is used.
+
+ \image plastique-fontdialog.png A font dialog in the Plastique widget style.
+
+ \sa QFont, QFontInfo, QFontMetrics, QColorDialog, QFileDialog, QPrintDialog,
+ {Standard Dialogs Example}
+*/
+
+/*!
+ \since 4.5
+
+ Constructs a standard font dialog.
+
+ Use setCurrentFont() to set the initial font attributes.
+
+ The \a parent parameter is passed to the QDialog constructor.
+
+ \sa getFont()
+*/
+QFontDialog::QFontDialog(QWidget *parent)
+ : QDialog(*new QFontDialogPrivate, parent, DefaultWindowFlags)
+{
+ Q_D(QFontDialog);
+ d->init();
+}
+
+/*!
+ \since 4.5
+
+ Constructs a standard font dialog with the given \a parent and specified
+ \a initial color.
+*/
+QFontDialog::QFontDialog(const QFont &initial, QWidget *parent)
+ : QDialog(*new QFontDialogPrivate, parent, DefaultWindowFlags)
+{
+ Q_D(QFontDialog);
+ d->init();
+ setCurrentFont(initial);
+}
+
+void QFontDialogPrivate::init()
+{
+ Q_Q(QFontDialog);
+
+#ifdef Q_WS_MAC
+ nativeDialogInUse = false;
+ delegate = 0;
+#endif
+
+ q->setSizeGripEnabled(true);
+ q->setWindowTitle(QFontDialog::tr("Select Font"));
+
+ // grid
+ familyEdit = new QLineEdit(q);
+ familyEdit->setReadOnly(true);
+ familyList = new QFontListView(q);
+ familyEdit->setFocusProxy(familyList);
+
+ familyAccel = new QLabel(q);
+#ifndef QT_NO_SHORTCUT
+ familyAccel->setBuddy(familyList);
+#endif
+ familyAccel->setIndent(2);
+
+ styleEdit = new QLineEdit(q);
+ styleEdit->setReadOnly(true);
+ styleList = new QFontListView(q);
+ styleEdit->setFocusProxy(styleList);
+
+ styleAccel = new QLabel(q);
+#ifndef QT_NO_SHORTCUT
+ styleAccel->setBuddy(styleList);
+#endif
+ styleAccel->setIndent(2);
+
+ sizeEdit = new QLineEdit(q);
+ sizeEdit->setFocusPolicy(Qt::ClickFocus);
+ QIntValidator *validator = new QIntValidator(1, 512, q);
+ sizeEdit->setValidator(validator);
+ sizeList = new QFontListView(q);
+
+ sizeAccel = new QLabel(q);
+#ifndef QT_NO_SHORTCUT
+ sizeAccel->setBuddy(sizeEdit);
+#endif
+ sizeAccel->setIndent(2);
+
+ // effects box
+ effects = new QGroupBox(q);
+ QVBoxLayout *vbox = new QVBoxLayout(effects);
+ strikeout = new QCheckBox(effects);
+ vbox->addWidget(strikeout);
+ underline = new QCheckBox(effects);
+ vbox->addWidget(underline);
+
+ sample = new QGroupBox(q);
+ QHBoxLayout *hbox = new QHBoxLayout(sample);
+ sampleEdit = new QLineEdit(sample);
+ sampleEdit->setSizePolicy(QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored));
+ sampleEdit->setAlignment(Qt::AlignCenter);
+ // Note that the sample text is *not* translated with tr(), as the
+ // characters used depend on the charset encoding.
+ sampleEdit->setText(QLatin1String("AaBbYyZz"));
+ hbox->addWidget(sampleEdit);
+
+ writingSystemCombo = new QComboBox(q);
+
+ writingSystemAccel = new QLabel(q);
+#ifndef QT_NO_SHORTCUT
+ writingSystemAccel->setBuddy(writingSystemCombo);
+#endif
+ writingSystemAccel->setIndent(2);
+
+ size = 0;
+ smoothScalable = false;
+
+ QObject::connect(writingSystemCombo, SIGNAL(activated(int)), q, SLOT(_q_writingSystemHighlighted(int)));
+ QObject::connect(familyList, SIGNAL(highlighted(int)), q, SLOT(_q_familyHighlighted(int)));
+ QObject::connect(styleList, SIGNAL(highlighted(int)), q, SLOT(_q_styleHighlighted(int)));
+ QObject::connect(sizeList, SIGNAL(highlighted(int)), q, SLOT(_q_sizeHighlighted(int)));
+ QObject::connect(sizeEdit, SIGNAL(textChanged(QString)), q, SLOT(_q_sizeChanged(QString)));
+
+ QObject::connect(strikeout, SIGNAL(clicked()), q, SLOT(_q_updateSample()));
+ QObject::connect(underline, SIGNAL(clicked()), q, SLOT(_q_updateSample()));
+
+ for (int i = 0; i < QFontDatabase::WritingSystemsCount; ++i) {
+ QFontDatabase::WritingSystem ws = QFontDatabase::WritingSystem(i);
+ QString writingSystemName = QFontDatabase::writingSystemName(ws);
+ if (writingSystemName.isEmpty())
+ break;
+ writingSystemCombo->addItem(writingSystemName);
+ }
+
+ updateFamilies();
+ if (familyList->count() != 0)
+ familyList->setCurrentItem(0);
+
+ // grid layout
+ QGridLayout *mainGrid = new QGridLayout(q);
+
+ int spacing = mainGrid->spacing();
+ if (spacing >= 0) { // uniform spacing
+ mainGrid->setSpacing(0);
+
+ mainGrid->setColumnMinimumWidth(1, spacing);
+ mainGrid->setColumnMinimumWidth(3, spacing);
+
+ int margin = 0;
+ mainGrid->getContentsMargins(0, 0, 0, &margin);
+
+ mainGrid->setRowMinimumHeight(3, margin);
+ mainGrid->setRowMinimumHeight(6, 2);
+ mainGrid->setRowMinimumHeight(8, margin);
+ }
+
+ mainGrid->addWidget(familyAccel, 0, 0);
+ mainGrid->addWidget(familyEdit, 1, 0);
+ mainGrid->addWidget(familyList, 2, 0);
+
+ mainGrid->addWidget(styleAccel, 0, 2);
+ mainGrid->addWidget(styleEdit, 1, 2);
+ mainGrid->addWidget(styleList, 2, 2);
+
+ mainGrid->addWidget(sizeAccel, 0, 4);
+ mainGrid->addWidget(sizeEdit, 1, 4);
+ mainGrid->addWidget(sizeList, 2, 4);
+
+ mainGrid->setColumnStretch(0, 38);
+ mainGrid->setColumnStretch(2, 24);
+ mainGrid->setColumnStretch(4, 10);
+
+ mainGrid->addWidget(effects, 4, 0);
+
+ mainGrid->addWidget(sample, 4, 2, 4, 3);
+
+ mainGrid->addWidget(writingSystemAccel, 5, 0);
+ mainGrid->addWidget(writingSystemCombo, 7, 0);
+
+ buttonBox = new QDialogButtonBox(q);
+ mainGrid->addWidget(buttonBox, 9, 0, 1, 5);
+
+ QPushButton *button
+ = static_cast<QPushButton *>(buttonBox->addButton(QDialogButtonBox::Ok));
+ QObject::connect(buttonBox, SIGNAL(accepted()), q, SLOT(accept()));
+ button->setDefault(true);
+
+ buttonBox->addButton(QDialogButtonBox::Cancel);
+ QObject::connect(buttonBox, SIGNAL(rejected()), q, SLOT(reject()));
+
+#if defined(Q_WS_WINCE)
+ q->resize(180, 120);
+#elif defined(Q_WS_S60)
+ q->resize(QApplication::desktop()->availableGeometry(QCursor::pos()).size());
+#else
+ q->resize(500, 360);
+#endif // Q_WS_WINCE
+
+ sizeEdit->installEventFilter(q);
+ familyList->installEventFilter(q);
+ styleList->installEventFilter(q);
+ sizeList->installEventFilter(q);
+
+ familyList->setFocus();
+ retranslateStrings();
+}
+
+/*!
+ \internal
+ Destroys the font dialog and frees up its storage.
+*/
+
+QFontDialog::~QFontDialog()
+{
+#ifdef Q_WS_MAC
+ Q_D(QFontDialog);
+ if (d->delegate) {
+ d->closeCocoaFontPanel();
+ return;
+ }
+#endif
+}
+
+/*!
+ Executes a modal font dialog and returns a font.
+
+ If the user clicks \gui OK, the selected font is returned. If the user
+ clicks \gui Cancel, the \a initial font is returned.
+
+ The dialog is constructed with the given \a parent and the options specified
+ in \a options. \a title is shown as the window title of the dialog and \a
+ initial is the initially selected font. If the \a ok parameter is not-null,
+ the value it refers to is set to true if the user clicks \gui OK, and set to
+ false if the user clicks \gui Cancel.
+
+ Examples:
+ \snippet doc/src/snippets/code/src_gui_dialogs_qfontdialog.cpp 2
+
+ The dialog can also be used to set a widget's font directly:
+ \snippet doc/src/snippets/code/src_gui_dialogs_qfontdialog.cpp 3
+ In this example, if the user clicks OK the font they chose will be
+ used, and if they click Cancel the original font is used.
+
+ \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 QFontDialog constructors.
+*/
+QFont QFontDialog::getFont(bool *ok, const QFont &initial, QWidget *parent, const QString &title,
+ FontDialogOptions options)
+{
+ return QFontDialogPrivate::getFont(ok, initial, parent, title, options);
+}
+
+/*!
+ \overload
+ \since 4.5
+*/
+QFont QFontDialog::getFont(bool *ok, const QFont &initial, QWidget *parent, const QString &title)
+{
+ return QFontDialogPrivate::getFont(ok, initial, parent, title, 0);
+}
+
+/*!
+ \overload
+*/
+QFont QFontDialog::getFont(bool *ok, const QFont &initial, QWidget *parent)
+{
+ return QFontDialogPrivate::getFont(ok, initial, parent, QString(), 0);
+}
+
+/*!
+ \overload
+
+ Executes a modal font dialog and returns a font.
+
+ If the user clicks \gui OK, the selected font is returned. If the user
+ clicks \gui Cancel, the Qt default font is returned.
+
+ The dialog is constructed with the given \a parent.
+ If the \a ok parameter is not-null, the value it refers to is set
+ to true if the user clicks \gui OK, and false if the user clicks
+ \gui Cancel.
+
+ Example:
+ \snippet doc/src/snippets/code/src_gui_dialogs_qfontdialog.cpp 4
+
+ \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 QFontDialog constructors.
+*/
+QFont QFontDialog::getFont(bool *ok, QWidget *parent)
+{
+ QFont initial;
+ return QFontDialogPrivate::getFont(ok, initial, parent, QString(), 0);
+}
+
+QFont QFontDialogPrivate::getFont(bool *ok, const QFont &initial, QWidget *parent,
+ const QString &title, QFontDialog::FontDialogOptions options)
+{
+ QFontDialog dlg(parent);
+ dlg.setOptions(options);
+ dlg.setCurrentFont(initial);
+ if (!title.isEmpty())
+ dlg.setWindowTitle(title);
+
+ int ret = (dlg.exec() || (options & QFontDialog::NoButtons));
+ if (ok)
+ *ok = !!ret;
+ if (ret) {
+ return dlg.selectedFont();
+ } else {
+ return initial;
+ }
+}
+
+/*!
+ \internal
+ An event filter to make the Up, Down, PageUp and PageDown keys work
+ correctly in the line edits. The source of the event is the object
+ \a o and the event is \a e.
+*/
+
+bool QFontDialog::eventFilter(QObject *o , QEvent *e)
+{
+ Q_D(QFontDialog);
+ if (e->type() == QEvent::KeyPress) {
+ QKeyEvent *k = (QKeyEvent *)e;
+ if (o == d->sizeEdit &&
+ (k->key() == Qt::Key_Up ||
+ k->key() == Qt::Key_Down ||
+ k->key() == Qt::Key_PageUp ||
+ k->key() == Qt::Key_PageDown)) {
+
+ int ci = d->sizeList->currentItem();
+ (void)QApplication::sendEvent(d->sizeList, k);
+
+ if (ci != d->sizeList->currentItem()
+ && style()->styleHint(QStyle::SH_FontDialog_SelectAssociatedText, 0, this))
+ d->sizeEdit->selectAll();
+ return true;
+ } else if ((o == d->familyList || o == d->styleList) &&
+ (k->key() == Qt::Key_Return || k->key() == Qt::Key_Enter)) {
+ k->accept();
+ accept();
+ return true;
+ }
+ } else if (e->type() == QEvent::FocusIn
+ && style()->styleHint(QStyle::SH_FontDialog_SelectAssociatedText, 0, this)) {
+ if (o == d->familyList)
+ d->familyEdit->selectAll();
+ else if (o == d->styleList)
+ d->styleEdit->selectAll();
+ else if (o == d->sizeList)
+ d->sizeEdit->selectAll();
+ } else if (e->type() == QEvent::MouseButtonPress && o == d->sizeList) {
+ d->sizeEdit->setFocus();
+ }
+ return QDialog::eventFilter(o, e);
+}
+
+/*
+ Updates the contents of the "font family" list box. This
+ function can be reimplemented if you have special requirements.
+*/
+
+void QFontDialogPrivate::updateFamilies()
+{
+ Q_Q(QFontDialog);
+
+ enum match_t { MATCH_NONE = 0, MATCH_LAST_RESORT = 1, MATCH_APP = 2, MATCH_FAMILY = 3 };
+
+ QStringList familyNames = fdb.families(writingSystem);
+
+ familyList->model()->setStringList(familyNames);
+
+ QString foundryName1, familyName1, foundryName2, familyName2;
+ int bestFamilyMatch = -1;
+ match_t bestFamilyType = MATCH_NONE;
+
+ QFont f;
+
+ // ##### do the right thing for a list of family names in the font.
+ QFontDatabase::parseFontName(family, foundryName1, familyName1);
+
+ QStringList::const_iterator it = familyNames.constBegin();
+ int i = 0;
+ for(; it != familyNames.constEnd(); ++it, ++i) {
+ QFontDatabase::parseFontName(*it, foundryName2, familyName2);
+
+ //try to match...
+ if (familyName1 == familyName2) {
+ bestFamilyType = MATCH_FAMILY;
+ if (foundryName1 == foundryName2) {
+ bestFamilyMatch = i;
+ break;
+ }
+ if (bestFamilyMatch < MATCH_FAMILY)
+ bestFamilyMatch = i;
+ }
+
+ //and try some fall backs
+ match_t type = MATCH_NONE;
+ if (bestFamilyType <= MATCH_NONE && familyName2 == f.lastResortFamily())
+ type = MATCH_LAST_RESORT;
+ if (bestFamilyType <= MATCH_LAST_RESORT && familyName2 == f.family())
+ type = MATCH_APP;
+ // ### add fallback for writingSystem
+ if (type != MATCH_NONE) {
+ bestFamilyType = type;
+ bestFamilyMatch = i;
+ }
+ }
+
+ if (i != -1 && bestFamilyType != MATCH_NONE)
+ familyList->setCurrentItem(bestFamilyMatch);
+ else
+ familyList->setCurrentItem(0);
+ familyEdit->setText(familyList->currentText());
+ if (q->style()->styleHint(QStyle::SH_FontDialog_SelectAssociatedText, 0, q)
+ && familyList->hasFocus())
+ familyEdit->selectAll();
+
+ updateStyles();
+}
+
+/*
+ Updates the contents of the "font style" list box. This
+ function can be reimplemented if you have special requirements.
+*/
+void QFontDialogPrivate::updateStyles()
+{
+ Q_Q(QFontDialog);
+ QStringList styles = fdb.styles(familyList->currentText());
+ styleList->model()->setStringList(styles);
+
+ if (styles.isEmpty()) {
+ styleEdit->clear();
+ smoothScalable = false;
+ } else {
+ if (!style.isEmpty()) {
+ bool found = false;
+ bool first = true;
+ QString cstyle = style;
+
+ redo:
+ for (int i = 0; i < (int)styleList->count(); i++) {
+ if (cstyle == styleList->text(i)) {
+ styleList->setCurrentItem(i);
+ found = true;
+ break;
+ }
+ }
+ if (!found && first) {
+ if (cstyle.contains(QLatin1String("Italic"))) {
+ cstyle.replace(QLatin1String("Italic"), QLatin1String("Oblique"));
+ first = false;
+ goto redo;
+ } else if (cstyle.contains(QLatin1String("Oblique"))) {
+ cstyle.replace(QLatin1String("Oblique"), QLatin1String("Italic"));
+ first = false;
+ goto redo;
+ }
+ }
+ if (!found)
+ styleList->setCurrentItem(0);
+ } else {
+ styleList->setCurrentItem(0);
+ }
+
+ styleEdit->setText(styleList->currentText());
+ if (q->style()->styleHint(QStyle::SH_FontDialog_SelectAssociatedText, 0, q)
+ && styleList->hasFocus())
+ styleEdit->selectAll();
+
+ smoothScalable = fdb.isSmoothlyScalable(familyList->currentText(), styleList->currentText());
+ }
+
+ updateSizes();
+}
+
+/*!
+ \internal
+ Updates the contents of the "font size" list box. This
+ function can be reimplemented if you have special requirements.
+*/
+
+void QFontDialogPrivate::updateSizes()
+{
+ Q_Q(QFontDialog);
+
+ if (!familyList->currentText().isEmpty()) {
+ QList<int> sizes = fdb.pointSizes(familyList->currentText(), styleList->currentText());
+
+ int i = 0;
+ int current = -1;
+ QStringList str_sizes;
+ for(QList<int>::const_iterator it = sizes.constBegin(); it != sizes.constEnd(); ++it) {
+ str_sizes.append(QString::number(*it));
+ if (current == -1 && *it >= size)
+ current = i;
+ ++i;
+ }
+ sizeList->model()->setStringList(str_sizes);
+ if (current == -1) {
+ // we request a size bigger than the ones in the list, select the biggest one
+ current = sizeList->count() - 1;
+ }
+ sizeList->setCurrentItem(current);
+
+ sizeEdit->blockSignals(true);
+ sizeEdit->setText((smoothScalable ? QString::number(size) : sizeList->currentText()));
+ if (q->style()->styleHint(QStyle::SH_FontDialog_SelectAssociatedText, 0, q)
+ && sizeList->hasFocus())
+ sizeEdit->selectAll();
+ sizeEdit->blockSignals(false);
+ } else {
+ sizeEdit->clear();
+ }
+
+ _q_updateSample();
+}
+
+void QFontDialogPrivate::_q_updateSample()
+{
+ // compute new font
+ int pSize = sizeEdit->text().toInt();
+ QFont newFont(fdb.font(familyList->currentText(), style, pSize));
+ newFont.setStrikeOut(strikeout->isChecked());
+ newFont.setUnderline(underline->isChecked());
+
+ if (familyList->currentText().isEmpty())
+ sampleEdit->clear();
+
+ updateSampleFont(newFont);
+}
+
+void QFontDialogPrivate::updateSampleFont(const QFont &newFont)
+{
+ Q_Q(QFontDialog);
+ if (newFont != sampleEdit->font()) {
+ sampleEdit->setFont(newFont);
+ emit q->currentFontChanged(newFont);
+ }
+}
+
+/*!
+ \internal
+*/
+void QFontDialogPrivate::_q_writingSystemHighlighted(int index)
+{
+ writingSystem = QFontDatabase::WritingSystem(index);
+ sampleEdit->setText(fdb.writingSystemSample(writingSystem));
+ updateFamilies();
+}
+
+/*!
+ \internal
+*/
+void QFontDialogPrivate::_q_familyHighlighted(int i)
+{
+ Q_Q(QFontDialog);
+ family = familyList->text(i);
+ familyEdit->setText(family);
+ if (q->style()->styleHint(QStyle::SH_FontDialog_SelectAssociatedText, 0, q)
+ && familyList->hasFocus())
+ familyEdit->selectAll();
+
+ updateStyles();
+}
+
+
+/*!
+ \internal
+*/
+
+void QFontDialogPrivate::_q_styleHighlighted(int index)
+{
+ Q_Q(QFontDialog);
+ QString s = styleList->text(index);
+ styleEdit->setText(s);
+ if (q->style()->styleHint(QStyle::SH_FontDialog_SelectAssociatedText, 0, q)
+ && styleList->hasFocus())
+ styleEdit->selectAll();
+
+ style = s;
+
+ updateSizes();
+}
+
+
+/*!
+ \internal
+*/
+
+void QFontDialogPrivate::_q_sizeHighlighted(int index)
+{
+ Q_Q(QFontDialog);
+ QString s = sizeList->text(index);
+ sizeEdit->setText(s);
+ if (q->style()->styleHint(QStyle::SH_FontDialog_SelectAssociatedText, 0, q)
+ && sizeEdit->hasFocus())
+ sizeEdit->selectAll();
+
+ size = s.toInt();
+ _q_updateSample();
+}
+
+/*!
+ \internal
+ This slot is called if the user changes the font size.
+ The size is passed in the \a s argument as a \e string.
+*/
+
+void QFontDialogPrivate::_q_sizeChanged(const QString &s)
+{
+ // no need to check if the conversion is valid, since we have an QIntValidator in the size edit
+ int size = s.toInt();
+ if (this->size == size)
+ return;
+
+ this->size = size;
+ if (sizeList->count() != 0) {
+ int i;
+ for (i = 0; i < sizeList->count() - 1; i++) {
+ if (sizeList->text(i).toInt() >= this->size)
+ break;
+ }
+ sizeList->blockSignals(true);
+ sizeList->setCurrentItem(i);
+ sizeList->blockSignals(false);
+ }
+ _q_updateSample();
+}
+
+void QFontDialogPrivate::retranslateStrings()
+{
+ familyAccel->setText(QFontDialog::tr("&Font"));
+ styleAccel->setText(QFontDialog::tr("Font st&yle"));
+ sizeAccel->setText(QFontDialog::tr("&Size"));
+#ifndef Q_WS_S60
+ // Removed the title due to lack of screen estate in small S60 screen.
+ // The effects are descriptive without a title (strikeout, underline).
+ effects->setTitle(QFontDialog::tr("Effects"));
+#endif
+ strikeout->setText(QFontDialog::tr("Stri&keout"));
+ underline->setText(QFontDialog::tr("&Underline"));
+ sample->setTitle(QFontDialog::tr("Sample"));
+ writingSystemAccel->setText(QFontDialog::tr("Wr&iting System"));
+}
+
+/*!
+ \reimp
+*/
+void QFontDialog::changeEvent(QEvent *e)
+{
+ Q_D(QFontDialog);
+ if (e->type() == QEvent::LanguageChange) {
+ d->retranslateStrings();
+ }
+ QDialog::changeEvent(e);
+}
+
+/*!
+ \since 4.5
+
+ \property QFontDialog::currentFont
+ \brief the current font of the dialog.
+*/
+
+/*!
+ \since 4.5
+
+ Sets the font highlighted in the QFontDialog to the given \a font.
+
+ \sa selectedFont()
+*/
+void QFontDialog::setCurrentFont(const QFont &font)
+{
+ Q_D(QFontDialog);
+ d->family = font.family();
+ d->style = d->fdb.styleString(font);
+ d->size = font.pointSize();
+ if (d->size == -1) {
+ QFontInfo fi(font);
+ d->size = fi.pointSize();
+ }
+ d->strikeout->setChecked(font.strikeOut());
+ d->underline->setChecked(font.underline());
+ d->updateFamilies();
+
+#ifdef Q_WS_MAC
+ if (d->delegate)
+ QFontDialogPrivate::setFont(d->delegate, font);
+#endif
+}
+
+/*!
+ \since 4.5
+
+ Returns the current font.
+
+ \sa selectedFont()
+*/
+QFont QFontDialog::currentFont() const
+{
+ Q_D(const QFontDialog);
+ return d->sampleEdit->font();
+}
+
+/*!
+ Returns the font that the user selected by clicking the \gui{OK}
+ or equivalent button.
+
+ \note This font is not always the same as the font held by the
+ \l currentFont property since the user can choose different fonts
+ before finally selecting the one to use.
+*/
+QFont QFontDialog::selectedFont() const
+{
+ Q_D(const QFontDialog);
+ return d->selectedFont;
+}
+
+/*!
+ \enum QFontDialog::FontDialogOption
+ \since 4.5
+
+ This enum specifies various options that affect the look and feel
+ of a font dialog.
+
+ \value NoButtons Don't display \gui{OK} and \gui{Cancel} buttons. (Useful for "live dialogs".)
+ \value DontUseNativeDialog Use Qt's standard font dialog on the Mac instead of Apple's
+ native font panel. (Currently, the native dialog is never used,
+ but this is likely to change in future Qt releases.)
+
+ \sa options, setOption(), testOption()
+*/
+
+/*!
+ Sets the given \a option to be enabled if \a on is true;
+ otherwise, clears the given \a option.
+
+ \sa options, testOption()
+*/
+void QFontDialog::setOption(FontDialogOption option, bool on)
+{
+ Q_D(QFontDialog);
+ if (!(d->opts & option) != !on)
+ setOptions(d->opts ^ option);
+}
+
+/*!
+ Returns true if the given \a option is enabled; otherwise, returns
+ false.
+
+ \sa options, setOption()
+*/
+bool QFontDialog::testOption(FontDialogOption option) const
+{
+ Q_D(const QFontDialog);
+ return (d->opts & option) != 0;
+}
+
+/*!
+ \property QFontDialog::options
+ \brief the various options that affect the look and feel of the dialog
+ \since 4.5
+
+ By default, all options are disabled.
+
+ Options should be set before showing the dialog. Setting them while the
+ dialog is visible is not guaranteed to have an immediate effect on the
+ dialog (depending on the option and on the platform).
+
+ \sa setOption(), testOption()
+*/
+void QFontDialog::setOptions(FontDialogOptions options)
+{
+ Q_D(QFontDialog);
+
+ FontDialogOptions changed = (options ^ d->opts);
+ if (!changed)
+ return;
+
+ d->opts = options;
+ d->buttonBox->setVisible(!(options & NoButtons));
+}
+
+QFontDialog::FontDialogOptions QFontDialog::options() const
+{
+ Q_D(const QFontDialog);
+ return d->opts;
+}
+
+#ifdef Q_WS_MAC
+// can only have one Cocoa font panel active
+bool QFontDialogPrivate::sharedFontPanelAvailable = true;
+#endif
+
+/*!
+ \since 4.5
+ \overload
+
+ Opens the dialog and connects its fontSelected() signal to the slot specified
+ by \a receiver and \a member.
+
+ The signal will be disconnected from the slot when the dialog is closed.
+*/
+void QFontDialog::open(QObject *receiver, const char *member)
+{
+ Q_D(QFontDialog);
+ connect(this, SIGNAL(fontSelected(QFont)), receiver, member);
+ d->receiverToDisconnectOnClose = receiver;
+ d->memberToDisconnectOnClose = member;
+ QDialog::open();
+}
+
+/*!
+ \since 4.5
+
+ \fn void QFontDialog::currentFontChanged(const QFont &font)
+
+ This signal is emitted when the current font is changed. The new font is
+ specified in \a font.
+
+ The signal is emitted while a user is selecting a font. Ultimately, the
+ chosen font may differ from the font currently selected.
+
+ \sa currentFont, fontSelected(), selectedFont()
+*/
+
+/*!
+ \since 4.5
+
+ \fn void QFontDialog::fontSelected(const QFont &font)
+
+ This signal is emitted when a font has been selected. The selected font is
+ specified in \a font.
+
+ The signal is only emitted when a user has chosen the final font to be
+ used. It is not emitted while the user is changing the current font in the
+ font dialog.
+
+ \sa selectedFont(), currentFontChanged(), currentFont
+*/
+
+/*!
+ \reimp
+*/
+void QFontDialog::setVisible(bool visible)
+{
+ if (testAttribute(Qt::WA_WState_ExplicitShowHide) && testAttribute(Qt::WA_WState_Hidden) != visible)
+ return;
+#ifdef Q_WS_MAC
+ Q_D(QFontDialog);
+ if (d->canBeNativeDialog()){
+ if (d->setVisible_sys(visible)){
+ d->nativeDialogInUse = true;
+ // Set WA_DontShowOnScreen so that QDialog::setVisible(visible) below
+ // updates the state correctly, but skips showing the non-native version:
+ setAttribute(Qt::WA_DontShowOnScreen, true);
+ } else {
+ d->nativeDialogInUse = false;
+ setAttribute(Qt::WA_DontShowOnScreen, false);
+ }
+ }
+#endif // Q_WS_MAC
+ QDialog::setVisible(visible);
+}
+
+/*!
+ Closes the dialog and sets its result code to \a result. If this dialog
+ is shown with exec(), done() causes the local event loop to finish,
+ and exec() to return \a result.
+
+ \sa QDialog::done()
+*/
+void QFontDialog::done(int result)
+{
+ Q_D(QFontDialog);
+ QDialog::done(result);
+ if (result == Accepted) {
+ // We check if this is the same font we had before, if so we emit currentFontChanged
+ QFont selectedFont = currentFont();
+ if(selectedFont != d->selectedFont)
+ emit(currentFontChanged(selectedFont));
+ d->selectedFont = selectedFont;
+ emit fontSelected(d->selectedFont);
+ } else
+ d->selectedFont = QFont();
+ if (d->receiverToDisconnectOnClose) {
+ disconnect(this, SIGNAL(fontSelected(QFont)),
+ d->receiverToDisconnectOnClose, d->memberToDisconnectOnClose);
+ d->receiverToDisconnectOnClose = 0;
+ }
+ d->memberToDisconnectOnClose.clear();
+}
+
+#ifdef Q_WS_MAC
+bool QFontDialogPrivate::canBeNativeDialog()
+{
+ Q_Q(QFontDialog);
+ if (nativeDialogInUse)
+ return true;
+ if (q->testAttribute(Qt::WA_DontShowOnScreen))
+ return false;
+ if (opts & QFontDialog::DontUseNativeDialog)
+ return false;
+
+ QLatin1String staticName(QFontDialog::staticMetaObject.className());
+ QLatin1String dynamicName(q->metaObject()->className());
+ return (staticName == dynamicName);
+}
+#endif // Q_WS_MAC
+
+/*!
+ \fn QFont QFontDialog::getFont(bool *ok, const QFont &initial, QWidget* parent, const char* name)
+ \since 4.5
+
+ Call getFont(\a ok, \a initial, \a parent) instead.
+
+ \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 QFontDialog constructors.
+
+ The \a name parameter is ignored.
+*/
+
+/*!
+ \fn QFont QFontDialog::getFont(bool *ok, QWidget* parent, const char* name)
+
+ Call getFont(\a ok, \a parent) instead.
+
+ \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 QFontDialog constructors.
+
+ The \a name parameter is ignored.
+*/
+
+QT_END_NAMESPACE
+
+#include "qfontdialog.moc"
+#include "moc_qfontdialog.cpp"
+
+#endif // QT_NO_FONTDIALOG
diff --git a/src/widgets/dialogs/qfontdialog.h b/src/widgets/dialogs/qfontdialog.h
new file mode 100644
index 0000000000..03ef2b7e81
--- /dev/null
+++ b/src/widgets/dialogs/qfontdialog.h
@@ -0,0 +1,147 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QFONTDIALOG_H
+#define QFONTDIALOG_H
+
+#include <QtGui/qwindowdefs.h>
+#include <QtWidgets/qdialog.h>
+#include <QtGui/qfont.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_FONTDIALOG
+
+class QFontDialogPrivate;
+
+class Q_WIDGETS_EXPORT QFontDialog : public QDialog
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QFontDialog)
+ Q_ENUMS(FontDialogOption)
+ Q_PROPERTY(QFont currentFont READ currentFont WRITE setCurrentFont NOTIFY currentFontChanged)
+ Q_PROPERTY(FontDialogOptions options READ options WRITE setOptions)
+
+public:
+ enum FontDialogOption {
+ NoButtons = 0x00000001,
+ DontUseNativeDialog = 0x00000002
+ };
+
+ Q_DECLARE_FLAGS(FontDialogOptions, FontDialogOption)
+
+ explicit QFontDialog(QWidget *parent = 0);
+ explicit QFontDialog(const QFont &initial, QWidget *parent = 0);
+ ~QFontDialog();
+
+ void setCurrentFont(const QFont &font);
+ QFont currentFont() const;
+
+ QFont selectedFont() const;
+
+ void setOption(FontDialogOption option, bool on = true);
+ bool testOption(FontDialogOption option) const;
+ void setOptions(FontDialogOptions options);
+ FontDialogOptions options() const;
+
+#ifdef Q_NO_USING_KEYWORD
+#ifndef Q_QDOC
+ void open() { QDialog::open(); }
+#endif
+#else
+ using QDialog::open;
+#endif
+ void open(QObject *receiver, const char *member);
+
+ void setVisible(bool visible);
+
+ // ### Qt 5: merge overloads
+ static QFont getFont(bool *ok, const QFont &initial, QWidget *parent, const QString &title,
+ FontDialogOptions options);
+ static QFont getFont(bool *ok, const QFont &initial, QWidget *parent, const QString &title);
+ static QFont getFont(bool *ok, const QFont &initial, QWidget *parent = 0);
+ static QFont getFont(bool *ok, QWidget *parent = 0);
+
+#ifdef QT3_SUPPORT
+ static QFont getFont(bool *ok, const QFont &initial, QWidget *parent, const char *name)
+ { Q_UNUSED(name); return getFont(ok, initial, parent); }
+ static QFont getFont(bool *ok, QWidget *parent, const char *name)
+ { Q_UNUSED(name); return getFont(ok, parent); }
+#endif
+
+Q_SIGNALS:
+ void currentFontChanged(const QFont &font);
+ void fontSelected(const QFont &font);
+
+protected:
+ void changeEvent(QEvent *event);
+ void done(int result);
+
+private:
+ // ### Qt 5: make protected
+ bool eventFilter(QObject *object, QEvent *event);
+
+ Q_DISABLE_COPY(QFontDialog)
+
+ Q_PRIVATE_SLOT(d_func(), void _q_sizeChanged(const QString &))
+ Q_PRIVATE_SLOT(d_func(), void _q_familyHighlighted(int))
+ Q_PRIVATE_SLOT(d_func(), void _q_writingSystemHighlighted(int))
+ Q_PRIVATE_SLOT(d_func(), void _q_styleHighlighted(int))
+ Q_PRIVATE_SLOT(d_func(), void _q_sizeHighlighted(int))
+ Q_PRIVATE_SLOT(d_func(), void _q_updateSample())
+#if defined(Q_WS_MAC)
+ Q_PRIVATE_SLOT(d_func(), void _q_macRunNativeAppModalPanel())
+#endif
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QFontDialog::FontDialogOptions)
+
+#endif // QT_NO_FONTDIALOG
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QFONTDIALOG_H
diff --git a/src/gui/dialogs/qfontdialog_mac.mm b/src/widgets/dialogs/qfontdialog_mac.mm
index 088aa52085..088aa52085 100644
--- a/src/gui/dialogs/qfontdialog_mac.mm
+++ b/src/widgets/dialogs/qfontdialog_mac.mm
diff --git a/src/gui/dialogs/qfontdialog_p.h b/src/widgets/dialogs/qfontdialog_p.h
index 349e2d3fcb..349e2d3fcb 100644
--- a/src/gui/dialogs/qfontdialog_p.h
+++ b/src/widgets/dialogs/qfontdialog_p.h
diff --git a/src/widgets/dialogs/qfscompleter_p.h b/src/widgets/dialogs/qfscompleter_p.h
new file mode 100644
index 0000000000..e078542cdc
--- /dev/null
+++ b/src/widgets/dialogs/qfscompleter_p.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QFSCOMPLETOR_P_H
+#define QFSCOMPLETOR_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qcompleter.h"
+#include <QtWidgets/qfilesystemmodel.h>
+QT_BEGIN_NAMESPACE
+#ifndef QT_NO_FSCOMPLETER
+
+/*!
+ QCompleter that can deal with QFileSystemModel
+ */
+class Q_WIDGETS_EXPORT QFSCompleter : public QCompleter {
+public:
+ QFSCompleter(QFileSystemModel *model, QObject *parent = 0)
+ : QCompleter(model, parent), proxyModel(0), sourceModel(model)
+ {
+#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
+ setCaseSensitivity(Qt::CaseInsensitive);
+#endif
+ }
+ QString pathFromIndex(const QModelIndex &index) const;
+ QStringList splitPath(const QString& path) const;
+
+ QAbstractProxyModel *proxyModel;
+ QFileSystemModel *sourceModel;
+};
+#endif // QT_NO_FSCOMPLETER
+QT_END_NAMESPACE
+#endif // QFSCOMPLETOR_P_H
+
diff --git a/src/gui/dialogs/qinputdialog.cpp b/src/widgets/dialogs/qinputdialog.cpp
index 5ca947ccbd..5ca947ccbd 100644
--- a/src/gui/dialogs/qinputdialog.cpp
+++ b/src/widgets/dialogs/qinputdialog.cpp
diff --git a/src/widgets/dialogs/qinputdialog.h b/src/widgets/dialogs/qinputdialog.h
new file mode 100644
index 0000000000..51411c7ae1
--- /dev/null
+++ b/src/widgets/dialogs/qinputdialog.h
@@ -0,0 +1,256 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QINPUTDIALOG_H
+#define QINPUTDIALOG_H
+
+#include <QtWidgets/qdialog.h>
+#include <QtCore/qstring.h>
+#include <QtWidgets/qlineedit.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_INPUTDIALOG
+
+class QInputDialogPrivate;
+
+class Q_WIDGETS_EXPORT QInputDialog : public QDialog
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QInputDialog)
+// Q_ENUMS(InputMode InputDialogOption)
+ QDOC_PROPERTY(InputMode inputMode READ inputMode WRITE setInputMode)
+ QDOC_PROPERTY(QString labelText READ labelText WRITE setLabelText)
+ QDOC_PROPERTY(InputDialogOptions options READ options WRITE setOptions)
+ QDOC_PROPERTY(QString textValue READ textValue WRITE setTextValue NOTIFY textValueChanged)
+ QDOC_PROPERTY(int intValue READ intValue WRITE setIntValue NOTIFY intValueChanged)
+ QDOC_PROPERTY(int doubleValue READ doubleValue WRITE setDoubleValue NOTIFY doubleValueChanged)
+ QDOC_PROPERTY(QLineEdit::EchoMode textEchoMode READ textEchoMode WRITE setTextEchoMode)
+ QDOC_PROPERTY(bool comboBoxEditable READ isComboBoxEditable WRITE setComboBoxEditable)
+ QDOC_PROPERTY(QStringList comboBoxItems READ comboBoxItems WRITE setComboBoxItems)
+ QDOC_PROPERTY(int intMinimum READ intMinimum WRITE setIntMinimum)
+ QDOC_PROPERTY(int intMaximum READ intMaximum WRITE setIntMaximum)
+ QDOC_PROPERTY(int intStep READ intStep WRITE setIntStep)
+ QDOC_PROPERTY(double doubleMinimum READ doubleMinimum WRITE setDoubleMinimum)
+ QDOC_PROPERTY(double doubleMaximum READ doubleMaximum WRITE setDoubleMaximum)
+ QDOC_PROPERTY(int doubleDecimals READ doubleDecimals WRITE setDoubleDecimals)
+ QDOC_PROPERTY(QString okButtonText READ okButtonText WRITE setOkButtonText)
+ QDOC_PROPERTY(QString cancelButtonText READ cancelButtonText WRITE setCancelButtonText)
+
+public:
+ enum InputDialogOption {
+ NoButtons = 0x00000001,
+ UseListViewForComboBoxItems = 0x00000002
+ };
+
+ Q_DECLARE_FLAGS(InputDialogOptions, InputDialogOption)
+
+ enum InputMode {
+ TextInput,
+ IntInput,
+ DoubleInput
+ };
+
+ QInputDialog(QWidget *parent = 0, Qt::WindowFlags flags = 0);
+ ~QInputDialog();
+
+ void setInputMode(InputMode mode);
+ InputMode inputMode() const;
+
+ void setLabelText(const QString &text);
+ QString labelText() const;
+
+ void setOption(InputDialogOption option, bool on = true);
+ bool testOption(InputDialogOption option) const;
+ void setOptions(InputDialogOptions options);
+ InputDialogOptions options() const;
+
+ void setTextValue(const QString &text);
+ QString textValue() const;
+
+ void setTextEchoMode(QLineEdit::EchoMode mode);
+ QLineEdit::EchoMode textEchoMode() const;
+
+ void setComboBoxEditable(bool editable);
+ bool isComboBoxEditable() const;
+
+ void setComboBoxItems(const QStringList &items);
+ QStringList comboBoxItems() const;
+
+ void setIntValue(int value);
+ int intValue() const;
+
+ void setIntMinimum(int min);
+ int intMinimum() const;
+
+ void setIntMaximum(int max);
+ int intMaximum() const;
+
+ void setIntRange(int min, int max);
+
+ void setIntStep(int step);
+ int intStep() const;
+
+ void setDoubleValue(double value);
+ double doubleValue() const;
+
+ void setDoubleMinimum(double min);
+ double doubleMinimum() const;
+
+ void setDoubleMaximum(double max);
+ double doubleMaximum() const;
+
+ void setDoubleRange(double min, double max);
+
+ void setDoubleDecimals(int decimals);
+ int doubleDecimals() const;
+
+ void setOkButtonText(const QString &text);
+ QString okButtonText() const;
+
+ void setCancelButtonText(const QString &text);
+ QString cancelButtonText() const;
+
+#ifdef Q_NO_USING_KEYWORD
+#ifndef Q_QDOC
+ void open() { QDialog::open(); }
+#endif
+#else
+ using QDialog::open;
+#endif
+ void open(QObject *receiver, const char *member);
+
+ QSize minimumSizeHint() const;
+ QSize sizeHint() const;
+
+ void setVisible(bool visible);
+
+#ifdef Q_QDOC
+ static QString getText(QWidget *parent, const QString &title, const QString &label,
+ QLineEdit::EchoMode echo = QLineEdit::Normal,
+ const QString &text = QString(), bool *ok = 0, Qt::WindowFlags flags = 0,
+ Qt::InputMethodHints inputMethodHints = Qt::ImhNone);
+ static QString getItem(QWidget *parent, const QString &title, const QString &label,
+ const QStringList &items, int current = 0, bool editable = true,
+ bool *ok = 0, Qt::WindowFlags flags = 0,
+ Qt::InputMethodHints inputMethodHints = Qt::ImhNone);
+#else
+ static QString getText(QWidget *parent, const QString &title, const QString &label,
+ QLineEdit::EchoMode echo = QLineEdit::Normal,
+ const QString &text = QString(), bool *ok = 0, Qt::WindowFlags flags = 0);
+ static QString getItem(QWidget *parent, const QString &title, const QString &label,
+ const QStringList &items, int current = 0, bool editable = true,
+ bool *ok = 0, Qt::WindowFlags flags = 0);
+ static QString getText(QWidget *parent, const QString &title, const QString &label,
+ QLineEdit::EchoMode echo,
+ const QString &text, bool *ok, Qt::WindowFlags flags,
+ Qt::InputMethodHints inputMethodHints);
+ static QString getItem(QWidget *parent, const QString &title, const QString &label,
+ const QStringList &items, int current, bool editable,
+ bool *ok, Qt::WindowFlags flags,
+ Qt::InputMethodHints inputMethodHints);
+#endif
+ static int getInt(QWidget *parent, const QString &title, const QString &label, int value = 0,
+ int minValue = -2147483647, int maxValue = 2147483647,
+ int step = 1, bool *ok = 0, Qt::WindowFlags flags = 0);
+ static double getDouble(QWidget *parent, const QString &title, const QString &label, double value = 0,
+ double minValue = -2147483647, double maxValue = 2147483647,
+ int decimals = 1, bool *ok = 0, Qt::WindowFlags flags = 0);
+
+ // obsolete
+ static int getInteger(QWidget *parent, const QString &title, const QString &label, int value = 0,
+ int minValue = -2147483647, int maxValue = 2147483647,
+ int step = 1, bool *ok = 0, Qt::WindowFlags flags = 0);
+
+#ifdef QT3_SUPPORT
+ inline static QT3_SUPPORT QString getText(const QString &title, const QString &label,
+ QLineEdit::EchoMode echo = QLineEdit::Normal,
+ const QString &text = QString(), bool *ok = 0,
+ QWidget *parent = 0, const char * = 0, Qt::WindowFlags flags = 0)
+ { return getText(parent, title, label, echo, text, ok, flags); }
+ inline static QT3_SUPPORT int getInteger(const QString &title, const QString &label, int value = 0,
+ int minValue = -2147483647, int maxValue = 2147483647,
+ int step = 1, bool *ok = 0,
+ QWidget *parent = 0, const char * = 0, Qt::WindowFlags flags = 0)
+ { return getInteger(parent, title, label, value, minValue, maxValue, step, ok, flags); }
+ inline static QT3_SUPPORT double getDouble(const QString &title, const QString &label, double value = 0,
+ double minValue = -2147483647, double maxValue = 2147483647,
+ int decimals = 1, bool *ok = 0,
+ QWidget *parent = 0, const char * = 0, Qt::WindowFlags flags = 0)
+ { return getDouble(parent, title, label, value, minValue, maxValue, decimals, ok, flags); }
+ inline static QT3_SUPPORT QString getItem(const QString &title, const QString &label, const QStringList &list,
+ int current = 0, bool editable = true, bool *ok = 0,
+ QWidget *parent = 0, const char * = 0, Qt::WindowFlags flags = 0)
+ { return getItem(parent, title, label, list, current, editable, ok, flags); }
+#endif
+
+Q_SIGNALS:
+ // ### emit signals!
+ void textValueChanged(const QString &text);
+ void textValueSelected(const QString &text);
+ void intValueChanged(int value);
+ void intValueSelected(int value);
+ void doubleValueChanged(double value);
+ void doubleValueSelected(double value);
+
+
+public:
+ void done(int result); // ### Qt 5: Make protected.
+
+private:
+ Q_DISABLE_COPY(QInputDialog)
+ Q_PRIVATE_SLOT(d_func(), void _q_textChanged(const QString&))
+ Q_PRIVATE_SLOT(d_func(), void _q_currentRowChanged(const QModelIndex&, const QModelIndex&))
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QInputDialog::InputDialogOptions)
+
+#endif // QT_NO_INPUTDIALOG
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QINPUTDIALOG_H
diff --git a/src/widgets/dialogs/qmessagebox.cpp b/src/widgets/dialogs/qmessagebox.cpp
new file mode 100644
index 0000000000..26180ab38b
--- /dev/null
+++ b/src/widgets/dialogs/qmessagebox.cpp
@@ -0,0 +1,2753 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtWidgets/qmessagebox.h>
+
+#ifndef QT_NO_MESSAGEBOX
+
+#include <QtWidgets/qdialogbuttonbox.h>
+#include "private/qlabel_p.h"
+#include "private/qapplication_p.h"
+#include <QtCore/qlist.h>
+#include <QtCore/qdebug.h>
+#include <QtWidgets/qstyle.h>
+#include <QtWidgets/qstyleoption.h>
+#include <QtWidgets/qgridlayout.h>
+#include <QtWidgets/qdesktopwidget.h>
+#include <QtWidgets/qpushbutton.h>
+#include <QtWidgets/qaccessible.h>
+#include <QtWidgets/qicon.h>
+#include <QtGui/qtextdocument.h>
+#include <QtWidgets/qapplication.h>
+#include <QtWidgets/qtextedit.h>
+#include <QtWidgets/qtextbrowser.h>
+#include <QtWidgets/qmenu.h>
+#include "qdialog_p.h"
+#include <QtGui/qfont.h>
+#include <QtGui/qfontmetrics.h>
+#include <QtGui/qclipboard.h>
+
+#ifndef QT_NO_STYLE_S60
+#include <qs60style.h>
+#endif
+
+#ifdef Q_WS_WINCE
+extern bool qt_wince_is_mobile(); //defined in qguifunctions_wince.cpp
+extern bool qt_wince_is_smartphone();//defined in qguifunctions_wince.cpp
+extern bool qt_wince_is_pocket_pc(); //defined in qguifunctions_wince.cpp
+
+#include "qguifunctions_wince.h"
+#endif
+
+QT_BEGIN_NAMESPACE
+
+enum Button { Old_Ok = 1, Old_Cancel = 2, Old_Yes = 3, Old_No = 4, Old_Abort = 5, Old_Retry = 6,
+ Old_Ignore = 7, Old_YesAll = 8, Old_NoAll = 9, Old_ButtonMask = 0xFF,
+ NewButtonMask = 0xFFFFFC00 };
+
+enum DetailButtonLabel { ShowLabel = 0, HideLabel = 1 };
+#ifndef QT_NO_TEXTEDIT
+class QMessageBoxDetailsText : public QWidget
+{
+public:
+ class TextEdit : public QTextEdit
+ {
+ public:
+ TextEdit(QWidget *parent=0) : QTextEdit(parent) { }
+ void contextMenuEvent(QContextMenuEvent * e)
+ {
+#ifndef QT_NO_CONTEXTMENU
+ QMenu *menu = createStandardContextMenu();
+ menu->setAttribute(Qt::WA_DeleteOnClose);
+ menu->popup(e->globalPos());
+#else
+ Q_UNUSED(e);
+#endif
+ }
+ };
+
+ QMessageBoxDetailsText(QWidget *parent=0)
+ : QWidget(parent)
+ {
+ QVBoxLayout *layout = new QVBoxLayout;
+ layout->setMargin(0);
+ QFrame *line = new QFrame(this);
+ line->setFrameShape(QFrame::HLine);
+ line->setFrameShadow(QFrame::Sunken);
+ layout->addWidget(line);
+ textEdit = new TextEdit();
+ textEdit->setFixedHeight(100);
+ textEdit->setFocusPolicy(Qt::NoFocus);
+ textEdit->setReadOnly(true);
+ layout->addWidget(textEdit);
+ setLayout(layout);
+ }
+ void setText(const QString &text) { textEdit->setPlainText(text); }
+ QString text() const { return textEdit->toPlainText(); }
+private:
+ TextEdit *textEdit;
+};
+#endif // QT_NO_TEXTEDIT
+
+class DetailButton : public QPushButton
+{
+public:
+ DetailButton(QWidget *parent) : QPushButton(label(ShowLabel), parent)
+ {
+ setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+ }
+
+ QString label(DetailButtonLabel label) const
+ { return label == ShowLabel ? QMessageBox::tr("Show Details...") : QMessageBox::tr("Hide Details..."); }
+
+ void setLabel(DetailButtonLabel lbl)
+ { setText(label(lbl)); }
+
+ QSize sizeHint() const
+ {
+ ensurePolished();
+ QStyleOptionButton opt;
+ initStyleOption(&opt);
+ const QFontMetrics fm = fontMetrics();
+ opt.text = label(ShowLabel);
+ QSize sz = fm.size(Qt::TextShowMnemonic, opt.text);
+ QSize ret = style()->sizeFromContents(QStyle::CT_PushButton, &opt, sz, this).
+ expandedTo(QApplication::globalStrut());
+ opt.text = label(HideLabel);
+ sz = fm.size(Qt::TextShowMnemonic, opt.text);
+ ret.expandedTo(style()->sizeFromContents(QStyle::CT_PushButton, &opt, sz, this).
+ expandedTo(QApplication::globalStrut()));
+ return ret;
+ }
+};
+
+
+class QMessageBoxPrivate : public QDialogPrivate
+{
+ Q_DECLARE_PUBLIC(QMessageBox)
+
+public:
+ QMessageBoxPrivate() : escapeButton(0), defaultButton(0), clickedButton(0), detailsButton(0),
+#ifndef QT_NO_TEXTEDIT
+ detailsText(0),
+#endif
+ compatMode(false), autoAddOkButton(true),
+ detectedEscapeButton(0), informativeLabel(0) { }
+
+ void init(const QString &title = QString(), const QString &text = QString());
+ void _q_buttonClicked(QAbstractButton *);
+
+ QAbstractButton *findButton(int button0, int button1, int button2, int flags);
+ void addOldButtons(int button0, int button1, int button2);
+
+ QAbstractButton *abstractButtonForId(int id) const;
+ int execReturnCode(QAbstractButton *button);
+
+ void detectEscapeButton();
+ void updateSize();
+ int layoutMinimumWidth();
+ void retranslateStrings();
+
+#ifdef Q_WS_WINCE
+ void hideSpecial();
+#endif
+
+ static int showOldMessageBox(QWidget *parent, QMessageBox::Icon icon,
+ const QString &title, const QString &text,
+ int button0, int button1, int button2);
+ static int showOldMessageBox(QWidget *parent, QMessageBox::Icon icon,
+ const QString &title, const QString &text,
+ const QString &button0Text,
+ const QString &button1Text,
+ const QString &button2Text,
+ int defaultButtonNumber,
+ int escapeButtonNumber);
+
+ static QMessageBox::StandardButton showNewMessageBox(QWidget *parent,
+ QMessageBox::Icon icon, const QString& title, const QString& text,
+ QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton);
+
+ static QPixmap standardIcon(QMessageBox::Icon icon, QMessageBox *mb);
+
+ QLabel *label;
+ QMessageBox::Icon icon;
+ QLabel *iconLabel;
+ QDialogButtonBox *buttonBox;
+ QList<QAbstractButton *> customButtonList;
+ QAbstractButton *escapeButton;
+ QPushButton *defaultButton;
+ QAbstractButton *clickedButton;
+ DetailButton *detailsButton;
+#ifndef QT_NO_TEXTEDIT
+ QMessageBoxDetailsText *detailsText;
+#endif
+ bool compatMode;
+ bool autoAddOkButton;
+ QAbstractButton *detectedEscapeButton;
+ QLabel *informativeLabel;
+#if defined(Q_OS_SYMBIAN) || defined(Q_WS_MAEMO_5)
+ QTextBrowser *textBrowser;
+#endif
+ QPointer<QObject> receiverToDisconnectOnClose;
+ QByteArray memberToDisconnectOnClose;
+ QByteArray signalToDisconnectOnClose;
+};
+
+void QMessageBoxPrivate::init(const QString &title, const QString &text)
+{
+ Q_Q(QMessageBox);
+
+ label = new QLabel;
+ label->setObjectName(QLatin1String("qt_msgbox_label"));
+ label->setTextInteractionFlags(Qt::TextInteractionFlags(q->style()->styleHint(QStyle::SH_MessageBox_TextInteractionFlags, 0, q)));
+ label->setAlignment(Qt::AlignVCenter | Qt::AlignLeft);
+ label->setOpenExternalLinks(true);
+#if defined(Q_WS_MAC)
+ label->setContentsMargins(16, 0, 0, 0);
+#elif !defined(Q_WS_QWS)
+ label->setContentsMargins(2, 0, 0, 0);
+ label->setIndent(9);
+#endif
+ icon = QMessageBox::NoIcon;
+ iconLabel = new QLabel;
+ iconLabel->setObjectName(QLatin1String("qt_msgboxex_icon_label"));
+ iconLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+
+ buttonBox = new QDialogButtonBox;
+ buttonBox->setObjectName(QLatin1String("qt_msgbox_buttonbox"));
+ buttonBox->setCenterButtons(q->style()->styleHint(QStyle::SH_MessageBox_CenterButtons, 0, q));
+ QObject::connect(buttonBox, SIGNAL(clicked(QAbstractButton*)),
+ q, SLOT(_q_buttonClicked(QAbstractButton*)));
+
+ QGridLayout *grid = new QGridLayout;
+#ifndef Q_WS_MAC
+ grid->addWidget(iconLabel, 0, 0, 2, 1, Qt::AlignTop);
+ grid->addWidget(label, 0, 1, 1, 1);
+ // -- leave space for information label --
+ grid->addWidget(buttonBox, 2, 0, 1, 2);
+#else
+ grid->setMargin(0);
+ grid->setVerticalSpacing(8);
+ grid->setHorizontalSpacing(0);
+ q->setContentsMargins(24, 15, 24, 20);
+ grid->addWidget(iconLabel, 0, 0, 2, 1, Qt::AlignTop | Qt::AlignLeft);
+ grid->addWidget(label, 0, 1, 1, 1);
+ // -- leave space for information label --
+ grid->setRowStretch(1, 100);
+ grid->setRowMinimumHeight(2, 6);
+ grid->addWidget(buttonBox, 3, 1, 1, 1);
+#endif
+
+ grid->setSizeConstraint(QLayout::SetNoConstraint);
+ q->setLayout(grid);
+
+ if (!title.isEmpty() || !text.isEmpty()) {
+ q->setWindowTitle(title);
+ q->setText(text);
+ }
+ q->setModal(true);
+
+#ifdef Q_WS_MAC
+ QFont f = q->font();
+ f.setBold(true);
+ label->setFont(f);
+#endif
+ retranslateStrings();
+}
+
+int QMessageBoxPrivate::layoutMinimumWidth()
+{
+ layout->activate();
+ return layout->totalMinimumSize().width();
+}
+
+void QMessageBoxPrivate::updateSize()
+{
+ Q_Q(QMessageBox);
+
+ if (!q->isVisible())
+ return;
+
+ QSize screenSize = QApplication::desktop()->availableGeometry(QCursor::pos()).size();
+#if defined(Q_WS_QWS) || defined(Q_WS_WINCE) || defined(Q_OS_SYMBIAN)
+ // the width of the screen, less the window border.
+ int hardLimit = screenSize.width() - (q->frameGeometry().width() - q->geometry().width());
+#else
+ int hardLimit = qMin(screenSize.width() - 480, 1000); // can never get bigger than this
+ // on small screens allows the messagebox be the same size as the screen
+ if (screenSize.width() <= 1024)
+ hardLimit = screenSize.width();
+#endif
+#ifdef Q_WS_MAC
+ int softLimit = qMin(screenSize.width()/2, 420);
+#elif defined(Q_WS_QWS)
+ int softLimit = qMin(hardLimit, 500);
+#else
+ // note: ideally on windows, hard and soft limits but it breaks compat
+#ifndef Q_WS_WINCE
+ int softLimit = qMin(screenSize.width()/2, 500);
+#else
+ int softLimit = qMin(screenSize.width() * 3 / 4, 500);
+#endif //Q_WS_WINCE
+#endif
+
+ if (informativeLabel)
+ informativeLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
+
+ label->setWordWrap(false); // makes the label return min size
+ int width = layoutMinimumWidth();
+
+ if (width > softLimit) {
+ label->setWordWrap(true);
+ width = qMax(softLimit, layoutMinimumWidth());
+
+ if (width > hardLimit) {
+ label->d_func()->ensureTextControl();
+ if (QWidgetTextControl *control = label->d_func()->control) {
+ QTextOption opt = control->document()->defaultTextOption();
+ opt.setWrapMode(QTextOption::WrapAnywhere);
+ control->document()->setDefaultTextOption(opt);
+ }
+ width = hardLimit;
+ }
+ }
+#ifdef Q_WS_S60
+ // in S60 portait messageBoxes should always occupy maximum width
+ if (QApplication::desktop()->size().height() > QApplication::desktop()->size().width()){
+ width = hardLimit;
+ } else {
+ // in landscape the messageBoxes should be of same width as in portrait
+ width = qMin(QApplication::desktop()->size().height(), hardLimit);
+ }
+#endif
+
+ if (informativeLabel) {
+ label->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
+ QSizePolicy policy(QSizePolicy::Minimum, QSizePolicy::Preferred);
+ policy.setHeightForWidth(true);
+ informativeLabel->setSizePolicy(policy);
+ width = qMax(width, layoutMinimumWidth());
+ if (width > hardLimit) { // longest word is really big, so wrap anywhere
+ informativeLabel->d_func()->ensureTextControl();
+ if (QWidgetTextControl *control = informativeLabel->d_func()->control) {
+ QTextOption opt = control->document()->defaultTextOption();
+ opt.setWrapMode(QTextOption::WrapAnywhere);
+ control->document()->setDefaultTextOption(opt);
+ }
+ width = hardLimit;
+ }
+ policy.setHeightForWidth(label->wordWrap());
+ label->setSizePolicy(policy);
+ }
+
+ QFontMetrics fm(QApplication::font("QWorkspaceTitleBar"));
+ int windowTitleWidth = qMin(fm.width(q->windowTitle()) + 50, hardLimit);
+ if (windowTitleWidth > width)
+ width = windowTitleWidth;
+
+ layout->activate();
+ int height = (layout->hasHeightForWidth())
+ ? layout->totalHeightForWidth(width)
+ : layout->totalMinimumSize().height();
+
+#ifndef QT_NO_STYLE_S60
+ QS60Style *s60Style = 0;
+ s60Style = qobject_cast<QS60Style *>(QApplication::style());
+
+ //use custom pixel metric to deduce the minimum height of the messagebox
+ if (s60Style)
+ height = qMax(height, s60Style->pixelMetric((QStyle::PixelMetric)PM_MessageBoxHeight));
+#endif
+
+ q->setFixedSize(width, height);
+ QCoreApplication::removePostedEvents(q, QEvent::LayoutRequest);
+}
+
+
+#ifdef Q_WS_WINCE
+/*!
+ \internal
+ Hides special buttons which are rather shown in the title bar
+ on WinCE, to conserve screen space.
+*/
+
+void QMessageBoxPrivate::hideSpecial()
+{
+ Q_Q(QMessageBox);
+ QList<QPushButton*> list = q->findChildren<QPushButton*>();
+ for (int i=0; i<list.size(); ++i) {
+ QPushButton *pb = list.at(i);
+ QString text = pb->text();
+ text.remove(QChar::fromLatin1('&'));
+ if (text == QApplication::translate("QMessageBox", "OK" ))
+ pb->setFixedSize(0,0);
+ }
+}
+#endif
+
+static int oldButton(int button)
+{
+ switch (button & QMessageBox::ButtonMask) {
+ case QMessageBox::Ok:
+ return Old_Ok;
+ case QMessageBox::Cancel:
+ return Old_Cancel;
+ case QMessageBox::Yes:
+ return Old_Yes;
+ case QMessageBox::No:
+ return Old_No;
+ case QMessageBox::Abort:
+ return Old_Abort;
+ case QMessageBox::Retry:
+ return Old_Retry;
+ case QMessageBox::Ignore:
+ return Old_Ignore;
+ case QMessageBox::YesToAll:
+ return Old_YesAll;
+ case QMessageBox::NoToAll:
+ return Old_NoAll;
+ default:
+ return 0;
+ }
+}
+
+int QMessageBoxPrivate::execReturnCode(QAbstractButton *button)
+{
+ int ret = buttonBox->standardButton(button);
+ if (ret == QMessageBox::NoButton) {
+ ret = customButtonList.indexOf(button); // if button == 0, correctly sets ret = -1
+ } else if (compatMode) {
+ ret = oldButton(ret);
+ }
+ return ret;
+}
+
+void QMessageBoxPrivate::_q_buttonClicked(QAbstractButton *button)
+{
+ Q_Q(QMessageBox);
+#ifndef QT_NO_TEXTEDIT
+ if (detailsButton && detailsText && button == detailsButton) {
+ detailsButton->setLabel(detailsText->isHidden() ? HideLabel : ShowLabel);
+ detailsText->setHidden(!detailsText->isHidden());
+ updateSize();
+ } else
+#endif
+ {
+ clickedButton = button;
+ q->done(execReturnCode(button)); // does not trigger closeEvent
+ emit q->buttonClicked(button);
+
+ if (receiverToDisconnectOnClose) {
+ QObject::disconnect(q, signalToDisconnectOnClose, receiverToDisconnectOnClose,
+ memberToDisconnectOnClose);
+ receiverToDisconnectOnClose = 0;
+ }
+ signalToDisconnectOnClose.clear();
+ memberToDisconnectOnClose.clear();
+ }
+}
+
+/*!
+ \class QMessageBox
+
+ \brief The QMessageBox class provides a modal dialog for informing
+ the user or for asking the user a question and receiving an answer.
+
+ \ingroup standard-dialogs
+
+
+ A message box displays a primary \l{QMessageBox::text}{text} to
+ alert the user to a situation, an \l{QMessageBox::informativeText}
+ {informative text} to further explain the alert or to ask the user
+ a question, and an optional \l{QMessageBox::detailedText}
+ {detailed text} to provide even more data if the user requests
+ it. A message box can also display an \l{QMessageBox::icon} {icon}
+ and \l{QMessageBox::standardButtons} {standard buttons} for
+ accepting a user response.
+
+ Two APIs for using QMessageBox are provided, the property-based
+ API, and the static functions. Calling one of the static functions
+ is the simpler approach, but it is less flexible than using the
+ property-based API, and the result is less informative. Using the
+ property-based API is recommended.
+
+ \section1 The Property-based API
+
+ To use the property-based API, construct an instance of
+ QMessageBox, set the desired properties, and call exec() to show
+ the message. The simplest configuration is to set only the
+ \l{QMessageBox::text} {message text} property.
+
+ \snippet doc/src/snippets/code/src_gui_dialogs_qmessagebox.cpp 5
+
+ The user must click the \gui{OK} button to dismiss the message
+ box. The rest of the GUI is blocked until the message box is
+ dismissed.
+
+ \image msgbox1.png
+
+ A better approach than just alerting the user to an event is to
+ also ask the user what to do about it. Store the question in the
+ \l{QMessageBox::informativeText} {informative text} property, and
+ set the \l{QMessageBox::standardButtons} {standard buttons}
+ property to the set of buttons you want as the set of user
+ responses. The buttons are specified by combining values from
+ StandardButtons using the bitwise OR operator. The display order
+ for the buttons is platform-dependent. For example, on Windows,
+ \gui{Save} is displayed to the left of \gui{Cancel}, whereas on
+ Mac OS, the order is reversed.
+
+ Mark one of your standard buttons to be your
+ \l{QMessageBox::defaultButton()} {default button}.
+
+ \snippet doc/src/snippets/code/src_gui_dialogs_qmessagebox.cpp 6
+
+ This is the approach recommended in the
+ \l{http://developer.apple.com/documentation/UserExperience/Conceptual/AppleHIGuidelines/XHIGWindows/chapter_18_section_7.html}
+ {Mac OS X Guidlines}. Similar guidlines apply for the other
+ platforms, but note the different ways the
+ \l{QMessageBox::informativeText} {informative text} is handled for
+ different platforms.
+
+ \image msgbox2.png
+
+ The exec() slot returns the StandardButtons value of the button
+ that was clicked.
+
+ \snippet doc/src/snippets/code/src_gui_dialogs_qmessagebox.cpp 7
+
+ To give the user more information to help him answer the question,
+ set the \l{QMessageBox::detailedText} {detailed text} property. If
+ the \l{QMessageBox::detailedText} {detailed text} property is set,
+ the \gui{Show Details...} button will be shown.
+
+ \image msgbox3.png
+
+ Clicking the \gui{Show Details...} button displays the detailed text.
+
+ \image msgbox4.png
+
+ \section2 Rich Text and the Text Format Property
+
+ The \l{QMessageBox::detailedText} {detailed text} property is
+ always interpreted as plain text. The \l{QMessageBox::text} {main
+ text} and \l{QMessageBox::informativeText} {informative text}
+ properties can be either plain text or rich text. These strings
+ are interpreted according to the setting of the
+ \l{QMessageBox::textFormat} {text format} property. The default
+ setting is \l{Qt::AutoText} {auto-text}.
+
+ Note that for some plain text strings containing XML
+ meta-characters, the auto-text \l{Qt::mightBeRichText()} {rich
+ text detection test} may fail causing your plain text string to be
+ interpreted incorrectly as rich text. In these rare cases, use
+ Qt::convertFromPlainText() to convert your plain text string to a
+ visually equivalent rich text string, or set the
+ \l{QMessageBox::textFormat} {text format} property explicitly with
+ setTextFormat().
+
+ \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
+ guidelines:
+
+ \table
+ \row
+ \o \img qmessagebox-quest.png
+ \o \l Question
+ \o For asking a question during normal operations.
+ \row
+ \o \img qmessagebox-info.png
+ \o \l Information
+ \o For reporting information about normal operations.
+ \row
+ \o \img qmessagebox-warn.png
+ \o \l Warning
+ \o For reporting non-critical errors.
+ \row
+ \o \img qmessagebox-crit.png
+ \o \l Critical
+ \o For reporting critical errors.
+ \endtable
+
+ \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
+
+ Building message boxes with the static functions API, although
+ convenient, is less flexible than using the property-based API,
+ because the static function signatures lack parameters for setting
+ the \l{QMessageBox::informativeText} {informative text} and
+ \l{QMessageBox::detailedText} {detailed text} properties. One
+ work-around for this has been to use the \c{title} parameter as
+ the message box main text and the \c{text} parameter as the
+ message box informative text. Because this has the obvious
+ drawback of making a less readable message box, platform
+ guidelines do not recommend it. The \e{Microsoft Windows User
+ Interface Guidelines} recommend using the
+ \l{QCoreApplication::applicationName} {application name} as the
+ \l{QMessageBox::setWindowTitle()} {window's title}, which means
+ that if you have an informative text in addition to your main
+ text, you must concatenate it to the \c{text} parameter.
+
+ Note that the static function signatures have changed with respect
+ to their button parameters, which are now used to set the
+ \l{QMessageBox::standardButtons} {standard buttons} and the
+ \l{QMessageBox::defaultButton()} {default button}.
+
+ Static functions are available for creating information(),
+ question(), warning(), and critical() message boxes.
+
+ \snippet doc/src/snippets/code/src_gui_dialogs_qmessagebox.cpp 0
+
+ The \l{dialogs/standarddialogs}{Standard Dialogs} example shows
+ how to use QMessageBox and the other built-in Qt dialogs.
+
+ \section1 Advanced Usage
+
+ If the \l{QMessageBox::StandardButtons} {standard buttons} are not
+ flexible enough for your message box, you can use the addButton()
+ overload that takes a text and a ButtonRoleto to add custom
+ buttons. The ButtonRole is used by QMessageBox to determine the
+ ordering of the buttons on screen (which varies according to the
+ platform). You can test the value of clickedButton() after calling
+ exec(). For example,
+
+ \snippet doc/src/snippets/code/src_gui_dialogs_qmessagebox.cpp 2
+
+ \section1 Default and Escape Keys
+
+ The default button (i.e., the button activated when \key Enter is
+ pressed) can be specified using setDefaultButton(). If a default
+ button is not specified, QMessageBox tries to find one based on
+ the \l{ButtonRole} {button roles} of the buttons used in the
+ message box.
+
+ The escape button (the button activated when \key Esc is pressed)
+ can be specified using setEscapeButton(). If an escape button is
+ not specified, QMessageBox tries to find one using these rules:
+
+ \list 1
+
+ \o If there is only one button, it is the button activated when
+ \key Esc is pressed.
+
+ \o If there is a \l Cancel button, it is the button activated when
+ \key Esc is pressed.
+
+ \o If there is exactly one button having either
+ \l{QMessageBox::RejectRole} {the Reject role} or the
+ \l{QMessageBox::NoRole} {the No role}, it is the button
+ activated when \key Esc is pressed.
+
+ \endlist
+
+ When an escape button can't be determined using these rules,
+ pressing \key Esc has no effect.
+
+ \sa QDialogButtonBox, {fowler}{GUI Design Handbook: Message Box}, {Standard Dialogs Example}, {Application Example}
+*/
+
+/*!
+ \enum QMessageBox::StandardButton
+ \since 4.2
+
+ These enums describe flags for standard buttons. Each button has a
+ defined \l ButtonRole.
+
+ \value Ok An "OK" button defined with the \l AcceptRole.
+ \value Open A "Open" button defined with the \l AcceptRole.
+ \value Save A "Save" button defined with the \l AcceptRole.
+ \value Cancel A "Cancel" button defined with the \l RejectRole.
+ \value Close A "Close" button defined with the \l RejectRole.
+ \value Discard A "Discard" or "Don't Save" button, depending on the platform,
+ defined with the \l DestructiveRole.
+ \value Apply An "Apply" button defined with the \l ApplyRole.
+ \value Reset A "Reset" button defined with the \l ResetRole.
+ \value RestoreDefaults A "Restore Defaults" button defined with the \l ResetRole.
+ \value Help A "Help" button defined with the \l HelpRole.
+ \value SaveAll A "Save All" button defined with the \l AcceptRole.
+ \value Yes A "Yes" button defined with the \l YesRole.
+ \value YesToAll A "Yes to All" button defined with the \l YesRole.
+ \value No A "No" button defined with the \l NoRole.
+ \value NoToAll A "No to All" button defined with the \l NoRole.
+ \value Abort An "Abort" button defined with the \l RejectRole.
+ \value Retry A "Retry" button defined with the \l AcceptRole.
+ \value Ignore An "Ignore" button defined with the \l AcceptRole.
+
+ \value NoButton An invalid button.
+
+ \omitvalue FirstButton
+ \omitvalue LastButton
+
+ The following values are obsolete:
+
+ \value YesAll Use YesToAll instead.
+ \value NoAll Use NoToAll instead.
+ \value Default Use the \c defaultButton argument of
+ information(), warning(), etc. instead, or call
+ setDefaultButton().
+ \value Escape Call setEscapeButton() instead.
+ \value FlagMask
+ \value ButtonMask
+
+ \sa ButtonRole, standardButtons
+*/
+
+/*!
+ \fn void QMessageBox::buttonClicked(QAbstractButton *button)
+
+ This signal is emitted whenever a button is clicked inside the QMessageBox.
+ The button that was clicked in returned in \a button.
+*/
+
+/*!
+ Constructs a message box with no text and no buttons. \a parent is
+ passed to the QDialog constructor.
+
+ On Mac OS X, if you want your message box to appear
+ as a Qt::Sheet of its \a parent, set the message box's
+ \l{setWindowModality()} {window modality} to Qt::WindowModal or use open().
+ Otherwise, the message box will be a standard dialog.
+
+*/
+QMessageBox::QMessageBox(QWidget *parent)
+ : QDialog(*new QMessageBoxPrivate, parent, Qt::MSWindowsFixedSizeDialogHint | Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint)
+{
+ Q_D(QMessageBox);
+ d->init();
+}
+
+/*!
+ Constructs a message box with the given \a icon, \a title, \a
+ text, and standard \a buttons. Standard or custom buttons can be
+ added at any time using addButton(). The \a parent and \a f
+ arguments are passed to the QDialog constructor.
+
+ The message box is an \l{Qt::ApplicationModal} {application modal}
+ dialog box.
+
+ On Mac OS X, if \a parent is not 0 and you want your message box
+ to appear as a Qt::Sheet of that parent, set the message box's
+ \l{setWindowModality()} {window modality} to Qt::WindowModal
+ (default). Otherwise, the message box will be a standard dialog.
+
+ \sa setWindowTitle(), setText(), setIcon(), setStandardButtons()
+*/
+QMessageBox::QMessageBox(Icon icon, const QString &title, const QString &text,
+ StandardButtons buttons, QWidget *parent,
+ Qt::WindowFlags f)
+: QDialog(*new QMessageBoxPrivate, parent, f | Qt::MSWindowsFixedSizeDialogHint | Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint)
+{
+ Q_D(QMessageBox);
+ d->init(title, text);
+ setIcon(icon);
+ if (buttons != NoButton)
+ setStandardButtons(buttons);
+}
+
+/*!
+ Destroys the message box.
+*/
+QMessageBox::~QMessageBox()
+{
+}
+
+/*!
+ \since 4.2
+
+ Adds the given \a button to the message box with the specified \a
+ role.
+
+ \sa removeButton(), button(), setStandardButtons()
+*/
+void QMessageBox::addButton(QAbstractButton *button, ButtonRole role)
+{
+ Q_D(QMessageBox);
+ if (!button)
+ return;
+ removeButton(button);
+ d->buttonBox->addButton(button, (QDialogButtonBox::ButtonRole)role);
+ d->customButtonList.append(button);
+ d->autoAddOkButton = false;
+}
+
+/*!
+ \since 4.2
+ \overload
+
+ Creates a button with the given \a text, adds it to the message box for the
+ specified \a role, and returns it.
+*/
+QPushButton *QMessageBox::addButton(const QString& text, ButtonRole role)
+{
+ Q_D(QMessageBox);
+ QPushButton *pushButton = new QPushButton(text);
+ addButton(pushButton, role);
+ d->updateSize();
+ return pushButton;
+}
+
+/*!
+ \since 4.2
+ \overload
+
+ Adds a standard \a button to the message box if it is valid to do so, and
+ returns the push button.
+
+ \sa setStandardButtons()
+*/
+QPushButton *QMessageBox::addButton(StandardButton button)
+{
+ Q_D(QMessageBox);
+ QPushButton *pushButton = d->buttonBox->addButton((QDialogButtonBox::StandardButton)button);
+ if (pushButton)
+ d->autoAddOkButton = false;
+ return pushButton;
+}
+
+/*!
+ \since 4.2
+
+ Removes \a button from the button box without deleting it.
+
+ \sa addButton(), setStandardButtons()
+*/
+void QMessageBox::removeButton(QAbstractButton *button)
+{
+ Q_D(QMessageBox);
+ d->customButtonList.removeAll(button);
+ if (d->escapeButton == button)
+ d->escapeButton = 0;
+ if (d->defaultButton == button)
+ d->defaultButton = 0;
+ d->buttonBox->removeButton(button);
+ d->updateSize();
+}
+
+/*!
+ \property QMessageBox::standardButtons
+ \brief collection of standard buttons in the message box
+ \since 4.2
+
+ This property controls which standard buttons are used by the message box.
+
+ By default, this property contains no standard buttons.
+
+ \sa addButton()
+*/
+void QMessageBox::setStandardButtons(StandardButtons buttons)
+{
+ Q_D(QMessageBox);
+ d->buttonBox->setStandardButtons(QDialogButtonBox::StandardButtons(int(buttons)));
+
+ QList<QAbstractButton *> buttonList = d->buttonBox->buttons();
+ if (!buttonList.contains(d->escapeButton))
+ d->escapeButton = 0;
+ if (!buttonList.contains(d->defaultButton))
+ d->defaultButton = 0;
+ d->autoAddOkButton = false;
+ d->updateSize();
+}
+
+QMessageBox::StandardButtons QMessageBox::standardButtons() const
+{
+ Q_D(const QMessageBox);
+ return QMessageBox::StandardButtons(int(d->buttonBox->standardButtons()));
+}
+
+/*!
+ \since 4.2
+
+ Returns the standard button enum value corresponding to the given \a button,
+ or NoButton if the given \a button isn't a standard button.
+
+ \sa button(), standardButtons()
+*/
+QMessageBox::StandardButton QMessageBox::standardButton(QAbstractButton *button) const
+{
+ Q_D(const QMessageBox);
+ return (QMessageBox::StandardButton)d->buttonBox->standardButton(button);
+}
+
+/*!
+ \since 4.2
+
+ Returns a pointer corresponding to the standard button \a which,
+ or 0 if the standard button doesn't exist in this message box.
+
+ \sa standardButtons, standardButton()
+*/
+QAbstractButton *QMessageBox::button(StandardButton which) const
+{
+ Q_D(const QMessageBox);
+ return d->buttonBox->button(QDialogButtonBox::StandardButton(which));
+}
+
+/*!
+ \since 4.2
+
+ Returns the button that is activated when escape is pressed.
+
+ By default, QMessageBox attempts to automatically detect an
+ escape button as follows:
+
+ \list 1
+ \o If there is only one button, it is made the escape button.
+ \o If there is a \l Cancel button, it is made the escape button.
+ \o On Mac OS X only, if there is exactly one button with the role
+ QMessageBox::RejectRole, it is made the escape button.
+ \endlist
+
+ When an escape button could not be automatically detected, pressing
+ \key Esc has no effect.
+
+ \sa addButton()
+*/
+QAbstractButton *QMessageBox::escapeButton() const
+{
+ Q_D(const QMessageBox);
+ return d->escapeButton;
+}
+
+/*!
+ \since 4.2
+
+ Sets the button that gets activated when the \key Escape key is
+ pressed to \a button.
+
+ \sa addButton(), clickedButton()
+*/
+void QMessageBox::setEscapeButton(QAbstractButton *button)
+{
+ Q_D(QMessageBox);
+ if (d->buttonBox->buttons().contains(button))
+ d->escapeButton = button;
+}
+
+/*!
+ \since 4.3
+
+ Sets the buttons that gets activated when the \key Escape key is
+ pressed to \a button.
+
+ \sa addButton(), clickedButton()
+*/
+void QMessageBox::setEscapeButton(QMessageBox::StandardButton button)
+{
+ Q_D(QMessageBox);
+ setEscapeButton(d->buttonBox->button(QDialogButtonBox::StandardButton(button)));
+}
+
+void QMessageBoxPrivate::detectEscapeButton()
+{
+ if (escapeButton) { // escape button explicitly set
+ detectedEscapeButton = escapeButton;
+ return;
+ }
+
+ // Cancel button automatically becomes escape button
+ detectedEscapeButton = buttonBox->button(QDialogButtonBox::Cancel);
+ if (detectedEscapeButton)
+ return;
+
+ // If there is only one button, make it the escape button
+ const QList<QAbstractButton *> buttons = buttonBox->buttons();
+ if (buttons.count() == 1) {
+ detectedEscapeButton = buttons.first();
+ return;
+ }
+
+ // if the message box has one RejectRole button, make it the escape button
+ for (int i = 0; i < buttons.count(); i++) {
+ if (buttonBox->buttonRole(buttons.at(i)) == QDialogButtonBox::RejectRole) {
+ if (detectedEscapeButton) { // already detected!
+ detectedEscapeButton = 0;
+ break;
+ }
+ detectedEscapeButton = buttons.at(i);
+ }
+ }
+ if (detectedEscapeButton)
+ return;
+
+ // if the message box has one NoRole button, make it the escape button
+ for (int i = 0; i < buttons.count(); i++) {
+ if (buttonBox->buttonRole(buttons.at(i)) == QDialogButtonBox::NoRole) {
+ if (detectedEscapeButton) { // already detected!
+ detectedEscapeButton = 0;
+ break;
+ }
+ detectedEscapeButton = buttons.at(i);
+ }
+ }
+}
+
+/*!
+ \since 4.2
+
+ Returns the button that was clicked by the user,
+ or 0 if the user hit the \key Esc key and
+ no \l{setEscapeButton()}{escape button} was set.
+
+ If exec() hasn't been called yet, returns 0.
+
+ Example:
+
+ \snippet doc/src/snippets/code/src_gui_dialogs_qmessagebox.cpp 3
+
+ \sa standardButton(), button()
+*/
+QAbstractButton *QMessageBox::clickedButton() const
+{
+ Q_D(const QMessageBox);
+ return d->clickedButton;
+}
+
+/*!
+ \since 4.2
+
+ Returns the button that should be the message box's
+ \l{QPushButton::setDefault()}{default button}. Returns 0
+ if no default button was set.
+
+ \sa addButton(), QPushButton::setDefault()
+*/
+QPushButton *QMessageBox::defaultButton() const
+{
+ Q_D(const QMessageBox);
+ return d->defaultButton;
+}
+
+/*!
+ \since 4.2
+
+ Sets the message box's \l{QPushButton::setDefault()}{default button}
+ to \a button.
+
+ \sa addButton(), QPushButton::setDefault()
+*/
+void QMessageBox::setDefaultButton(QPushButton *button)
+{
+ Q_D(QMessageBox);
+ if (!d->buttonBox->buttons().contains(button))
+ return;
+ d->defaultButton = button;
+ button->setDefault(true);
+ button->setFocus();
+}
+
+/*!
+ \since 4.3
+
+ Sets the message box's \l{QPushButton::setDefault()}{default button}
+ to \a button.
+
+ \sa addButton(), QPushButton::setDefault()
+*/
+void QMessageBox::setDefaultButton(QMessageBox::StandardButton button)
+{
+ Q_D(QMessageBox);
+ setDefaultButton(d->buttonBox->button(QDialogButtonBox::StandardButton(button)));
+}
+
+/*!
+ \property QMessageBox::text
+ \brief the message box text to be displayed.
+
+ The text will be interpreted either as a plain text or as rich text,
+ depending on the text format setting (\l QMessageBox::textFormat).
+ The default setting is Qt::AutoText, i.e., the message box will try
+ to auto-detect the format of the text.
+
+ The default value of this property is an empty string.
+
+ \sa textFormat, QMessageBox::informativeText, QMessageBox::detailedText
+*/
+QString QMessageBox::text() const
+{
+ Q_D(const QMessageBox);
+ return d->label->text();
+}
+
+void QMessageBox::setText(const QString &text)
+{
+ Q_D(QMessageBox);
+ d->label->setText(text);
+ d->label->setWordWrap(d->label->textFormat() == Qt::RichText
+ || (d->label->textFormat() == Qt::AutoText && Qt::mightBeRichText(text)));
+ d->updateSize();
+}
+
+/*!
+ \enum QMessageBox::Icon
+
+ This enum has the following values:
+
+ \value NoIcon the message box does not have any icon.
+
+ \value Question an icon indicating that
+ the message is asking a question.
+
+ \value Information an icon indicating that
+ the message is nothing out of the ordinary.
+
+ \value Warning an icon indicating that the
+ message is a warning, but can be dealt with.
+
+ \value Critical an icon indicating that
+ the message represents a critical problem.
+
+*/
+
+/*!
+ \property QMessageBox::icon
+ \brief the message box's icon
+
+ The icon of the message box can be specified with one of the
+ values:
+
+ \list
+ \o QMessageBox::NoIcon
+ \o QMessageBox::Question
+ \o QMessageBox::Information
+ \o QMessageBox::Warning
+ \o QMessageBox::Critical
+ \endlist
+
+ The default is QMessageBox::NoIcon.
+
+ The pixmap used to display the actual icon depends on the current
+ \l{QWidget::style()} {GUI style}. You can also set a custom pixmap
+ for the icon by setting the \l{QMessageBox::iconPixmap} {icon
+ pixmap} property.
+
+ \sa iconPixmap
+*/
+QMessageBox::Icon QMessageBox::icon() const
+{
+ Q_D(const QMessageBox);
+ return d->icon;
+}
+
+void QMessageBox::setIcon(Icon icon)
+{
+ Q_D(QMessageBox);
+ setIconPixmap(QMessageBoxPrivate::standardIcon((QMessageBox::Icon)icon,
+ this));
+ d->icon = icon;
+}
+
+/*!
+ \property QMessageBox::iconPixmap
+ \brief the current icon
+
+ The icon currently used by the message box. Note that it's often
+ hard to draw one pixmap that looks appropriate in all GUI styles;
+ you may want to supply a different pixmap for each platform.
+
+ By default, this property is undefined.
+
+ \sa icon
+*/
+QPixmap QMessageBox::iconPixmap() const
+{
+ Q_D(const QMessageBox);
+ if (d->iconLabel && d->iconLabel->pixmap())
+ return *d->iconLabel->pixmap();
+ return QPixmap();
+}
+
+void QMessageBox::setIconPixmap(const QPixmap &pixmap)
+{
+ Q_D(QMessageBox);
+ d->iconLabel->setPixmap(pixmap);
+ d->updateSize();
+ d->icon = NoIcon;
+}
+
+/*!
+ \property QMessageBox::textFormat
+ \brief the format of the text displayed by the message box
+
+ The current text format used by the message box. See the \l
+ Qt::TextFormat enum for an explanation of the possible options.
+
+ The default format is Qt::AutoText.
+
+ \sa setText()
+*/
+Qt::TextFormat QMessageBox::textFormat() const
+{
+ Q_D(const QMessageBox);
+ return d->label->textFormat();
+}
+
+void QMessageBox::setTextFormat(Qt::TextFormat format)
+{
+ Q_D(QMessageBox);
+ d->label->setTextFormat(format);
+ d->label->setWordWrap(format == Qt::RichText
+ || (format == Qt::AutoText && Qt::mightBeRichText(d->label->text())));
+ d->updateSize();
+}
+
+/*!
+ \reimp
+*/
+bool QMessageBox::event(QEvent *e)
+{
+ bool result =QDialog::event(e);
+ switch (e->type()) {
+ case QEvent::LayoutRequest:
+ d_func()->updateSize();
+ break;
+ case QEvent::LanguageChange:
+ d_func()->retranslateStrings();
+ break;
+#ifdef Q_WS_WINCE
+ case QEvent::OkRequest:
+ case QEvent::HelpRequest: {
+ QString bName =
+ (e->type() == QEvent::OkRequest)
+ ? QApplication::translate("QMessageBox", "OK")
+ : QApplication::translate("QMessageBox", "Help");
+ QList<QPushButton*> list = findChildren<QPushButton*>();
+ for (int i=0; i<list.size(); ++i) {
+ QPushButton *pb = list.at(i);
+ if (pb->text() == bName) {
+ if (pb->isEnabled())
+ pb->click();
+ return pb->isEnabled();
+ }
+ }
+ }
+#endif
+ default:
+ break;
+ }
+ return result;
+}
+
+/*!
+ \reimp
+*/
+void QMessageBox::resizeEvent(QResizeEvent *event)
+{
+ QDialog::resizeEvent(event);
+}
+
+/*!
+ \reimp
+*/
+void QMessageBox::closeEvent(QCloseEvent *e)
+{
+ Q_D(QMessageBox);
+ if (!d->detectedEscapeButton) {
+ e->ignore();
+ return;
+ }
+ QDialog::closeEvent(e);
+ d->clickedButton = d->detectedEscapeButton;
+ setResult(d->execReturnCode(d->detectedEscapeButton));
+}
+
+/*!
+ \reimp
+*/
+void QMessageBox::changeEvent(QEvent *ev)
+{
+ Q_D(QMessageBox);
+ switch (ev->type()) {
+ case QEvent::StyleChange:
+ {
+ if (d->icon != NoIcon)
+ setIcon(d->icon);
+ Qt::TextInteractionFlags flags(style()->styleHint(QStyle::SH_MessageBox_TextInteractionFlags, 0, this));
+ d->label->setTextInteractionFlags(flags);
+ d->buttonBox->setCenterButtons(style()->styleHint(QStyle::SH_MessageBox_CenterButtons, 0, this));
+ if (d->informativeLabel)
+ d->informativeLabel->setTextInteractionFlags(flags);
+ // intentional fall through
+ }
+ case QEvent::FontChange:
+ case QEvent::ApplicationFontChange:
+#ifdef Q_WS_MAC
+ {
+ QFont f = font();
+ f.setBold(true);
+ d->label->setFont(f);
+ }
+#endif
+ default:
+ break;
+ }
+ QDialog::changeEvent(ev);
+}
+
+/*!
+ \reimp
+*/
+void QMessageBox::keyPressEvent(QKeyEvent *e)
+{
+ Q_D(QMessageBox);
+ if (e->key() == Qt::Key_Escape
+#ifdef Q_WS_MAC
+ || (e->modifiers() == Qt::ControlModifier && e->key() == Qt::Key_Period)
+#endif
+ ) {
+ if (d->detectedEscapeButton) {
+#ifdef Q_WS_MAC
+ d->detectedEscapeButton->animateClick();
+#else
+ d->detectedEscapeButton->click();
+#endif
+ }
+ return;
+ }
+
+#if defined (Q_OS_WIN) && !defined(QT_NO_CLIPBOARD) && !defined(QT_NO_SHORTCUT)
+ if (e == QKeySequence::Copy) {
+ QString separator = QString::fromLatin1("---------------------------\n");
+ QString textToCopy = separator;
+ separator.prepend(QLatin1Char('\n'));
+ textToCopy += windowTitle() + separator; // title
+ textToCopy += d->label->text() + separator; // text
+
+ if (d->informativeLabel)
+ textToCopy += d->informativeLabel->text() + separator;
+
+ QString buttonTexts;
+ QList<QAbstractButton *> buttons = d->buttonBox->buttons();
+ for (int i = 0; i < buttons.count(); i++) {
+ buttonTexts += buttons[i]->text() + QLatin1String(" ");
+ }
+ textToCopy += buttonTexts + separator;
+
+ QApplication::clipboard()->setText(textToCopy);
+ return;
+ }
+#endif //QT_NO_SHORTCUT QT_NO_CLIPBOARD Q_OS_WIN
+
+#ifndef QT_NO_SHORTCUT
+ if (!(e->modifiers() & Qt::AltModifier)) {
+ int key = e->key() & ~((int)Qt::MODIFIER_MASK|(int)Qt::UNICODE_ACCEL);
+ if (key) {
+ const QList<QAbstractButton *> buttons = d->buttonBox->buttons();
+ for (int i = 0; i < buttons.count(); ++i) {
+ QAbstractButton *pb = buttons.at(i);
+ int acc = pb->shortcut() & ~((int)Qt::MODIFIER_MASK|(int)Qt::UNICODE_ACCEL);
+ if (acc == key) {
+ pb->animateClick();
+ return;
+ }
+ }
+ }
+ }
+#endif
+ QDialog::keyPressEvent(e);
+}
+
+#ifdef Q_WS_WINCE
+/*!
+ \reimp
+*/
+void QMessageBox::setVisible(bool visible)
+{
+ Q_D(QMessageBox);
+ if (visible)
+ d->hideSpecial();
+ QDialog::setVisible(visible);
+}
+#endif
+
+
+/*!
+ \overload
+
+ Opens the dialog and connects its finished() or buttonClicked() signal to
+ the slot specified by \a receiver and \a member. If the slot in \a member
+ has a pointer for its first parameter the connection is to buttonClicked(),
+ otherwise the connection is to finished().
+
+ The signal will be disconnected from the slot when the dialog is closed.
+*/
+void QMessageBox::open(QObject *receiver, const char *member)
+{
+ Q_D(QMessageBox);
+ const char *signal = member && strchr(member, '*') ? SIGNAL(buttonClicked(QAbstractButton*))
+ : SIGNAL(finished(int));
+ connect(this, signal, receiver, member);
+ d->signalToDisconnectOnClose = signal;
+ d->receiverToDisconnectOnClose = receiver;
+ d->memberToDisconnectOnClose = member;
+ QDialog::open();
+}
+
+/*!
+ \since 4.5
+
+ Returns a list of all the buttons that have been added to the message box.
+
+ \sa buttonRole(), addButton(), removeButton()
+*/
+QList<QAbstractButton *> QMessageBox::buttons() const
+{
+ Q_D(const QMessageBox);
+ return d->buttonBox->buttons();
+}
+
+/*!
+ \since 4.5
+
+ Returns the button role for the specified \a button. This function returns
+ \l InvalidRole if \a button is 0 or has not been added to the message box.
+
+ \sa buttons(), addButton()
+*/
+QMessageBox::ButtonRole QMessageBox::buttonRole(QAbstractButton *button) const
+{
+ Q_D(const QMessageBox);
+ return QMessageBox::ButtonRole(d->buttonBox->buttonRole(button));
+}
+
+/*!
+ \reimp
+*/
+void QMessageBox::showEvent(QShowEvent *e)
+{
+ Q_D(QMessageBox);
+ if (d->autoAddOkButton) {
+ addButton(Ok);
+#if defined(Q_WS_WINCE)
+ d->hideSpecial();
+#endif
+ }
+ if (d->detailsButton)
+ addButton(d->detailsButton, QMessageBox::ActionRole);
+ d->detectEscapeButton();
+ d->updateSize();
+
+#ifndef QT_NO_ACCESSIBILITY
+ QAccessible::updateAccessibility(this, 0, QAccessible::Alert);
+#endif
+#ifdef Q_WS_WIN
+ HMENU systemMenu = GetSystemMenu((HWND)winId(), FALSE);
+ if (!d->detectedEscapeButton) {
+ EnableMenuItem(systemMenu, SC_CLOSE, MF_BYCOMMAND|MF_GRAYED);
+ }
+ else {
+ EnableMenuItem(systemMenu, SC_CLOSE, MF_BYCOMMAND|MF_ENABLED);
+ }
+#endif
+ QDialog::showEvent(e);
+}
+
+
+static QMessageBox::StandardButton showNewMessageBox(QWidget *parent,
+ QMessageBox::Icon icon,
+ const QString& title, const QString& text,
+ QMessageBox::StandardButtons buttons,
+ QMessageBox::StandardButton defaultButton)
+{
+ // necessary for source compatibility with Qt 4.0 and 4.1
+ // handles (Yes, No) and (Yes|Default, No)
+ if (defaultButton && !(buttons & defaultButton))
+ return (QMessageBox::StandardButton)
+ QMessageBoxPrivate::showOldMessageBox(parent, icon, title,
+ text, int(buttons),
+ int(defaultButton), 0);
+
+ QMessageBox msgBox(icon, title, text, QMessageBox::NoButton, parent);
+ QDialogButtonBox *buttonBox = msgBox.findChild<QDialogButtonBox*>();
+ Q_ASSERT(buttonBox != 0);
+
+ uint mask = QMessageBox::FirstButton;
+ while (mask <= QMessageBox::LastButton) {
+ uint sb = buttons & mask;
+ mask <<= 1;
+ if (!sb)
+ continue;
+ QPushButton *button = msgBox.addButton((QMessageBox::StandardButton)sb);
+ // Choose the first accept role as the default
+ if (msgBox.defaultButton())
+ continue;
+ if ((defaultButton == QMessageBox::NoButton && buttonBox->buttonRole(button) == QDialogButtonBox::AcceptRole)
+ || (defaultButton != QMessageBox::NoButton && sb == uint(defaultButton)))
+ msgBox.setDefaultButton(button);
+ }
+ if (msgBox.exec() == -1)
+ return QMessageBox::Cancel;
+ return msgBox.standardButton(msgBox.clickedButton());
+}
+
+/*!
+ \since 4.2
+
+ Opens an information message box with the given \a title and
+ \a text in front of the specified \a parent widget.
+
+ The standard \a buttons are added to the message box.
+ \a defaultButton specifies the button used when \key Enter is pressed.
+ \a defaultButton must refer to a button that was given in \a buttons.
+ If \a defaultButton is QMessageBox::NoButton, QMessageBox
+ chooses a suitable default automatically.
+
+ Returns the identity of the standard button that was clicked. If
+ \key Esc was pressed instead, the \l{Default and Escape Keys}
+ {escape button} is returned.
+
+ The message box is an \l{Qt::ApplicationModal}{application modal}
+ dialog box.
+
+ \warning Do not delete \a parent during the execution of the dialog.
+ If you want to do this, you should create the dialog
+ yourself using one of the QMessageBox constructors.
+
+ \sa question(), warning(), critical()
+*/
+QMessageBox::StandardButton QMessageBox::information(QWidget *parent, const QString &title,
+ const QString& text, StandardButtons buttons,
+ StandardButton defaultButton)
+{
+ return showNewMessageBox(parent, Information, title, text, buttons,
+ defaultButton);
+}
+
+
+/*!
+ \since 4.2
+
+ Opens a question message box with the given \a title and \a
+ text in front of the specified \a parent widget.
+
+ The standard \a buttons are added to the message box. \a
+ defaultButton specifies the button used when \key Enter is
+ pressed. \a defaultButton must refer to a button that was given in \a buttons.
+ If \a defaultButton is QMessageBox::NoButton, QMessageBox
+ chooses a suitable default automatically.
+
+ Returns the identity of the standard button that was clicked. If
+ \key Esc was pressed instead, the \l{Default and Escape Keys}
+ {escape button} is returned.
+
+ The message box is an \l{Qt::ApplicationModal} {application modal}
+ dialog box.
+
+ \warning Do not delete \a parent during the execution of the dialog.
+ If you want to do this, you should create the dialog
+ yourself using one of the QMessageBox constructors.
+
+ \sa information(), warning(), critical()
+*/
+QMessageBox::StandardButton QMessageBox::question(QWidget *parent, const QString &title,
+ const QString& text, StandardButtons buttons,
+ StandardButton defaultButton)
+{
+ return showNewMessageBox(parent, Question, title, text, buttons, defaultButton);
+}
+
+/*!
+ \since 4.2
+
+ Opens a warning message box with the given \a title and \a
+ text in front of the specified \a parent widget.
+
+ The standard \a buttons are added to the message box. \a
+ defaultButton specifies the button used when \key Enter is
+ pressed. \a defaultButton must refer to a button that was given in \a buttons.
+ If \a defaultButton is QMessageBox::NoButton, QMessageBox
+ chooses a suitable default automatically.
+
+ Returns the identity of the standard button that was clicked. If
+ \key Esc was pressed instead, the \l{Default and Escape Keys}
+ {escape button} is returned.
+
+ The message box is an \l{Qt::ApplicationModal} {application modal}
+ dialog box.
+
+ \warning Do not delete \a parent during the execution of the dialog.
+ If you want to do this, you should create the dialog
+ yourself using one of the QMessageBox constructors.
+
+ \sa question(), information(), critical()
+*/
+QMessageBox::StandardButton QMessageBox::warning(QWidget *parent, const QString &title,
+ const QString& text, StandardButtons buttons,
+ StandardButton defaultButton)
+{
+ return showNewMessageBox(parent, Warning, title, text, buttons, defaultButton);
+}
+
+/*!
+ \since 4.2
+
+ Opens a critical message box with the given \a title and \a
+ text in front of the specified \a parent widget.
+
+ The standard \a buttons are added to the message box. \a
+ defaultButton specifies the button used when \key Enter is
+ pressed. \a defaultButton must refer to a button that was given in \a buttons.
+ If \a defaultButton is QMessageBox::NoButton, QMessageBox
+ chooses a suitable default automatically.
+
+ Returns the identity of the standard button that was clicked. If
+ \key Esc was pressed instead, the \l{Default and Escape Keys}
+ {escape button} is returned.
+
+ The message box is an \l{Qt::ApplicationModal} {application modal}
+ dialog box.
+
+ \warning Do not delete \a parent during the execution of the dialog.
+ If you want to do this, you should create the dialog
+ yourself using one of the QMessageBox constructors.
+
+ \sa question(), warning(), information()
+*/
+QMessageBox::StandardButton QMessageBox::critical(QWidget *parent, const QString &title,
+ const QString& text, StandardButtons buttons,
+ StandardButton defaultButton)
+{
+ return showNewMessageBox(parent, Critical, title, text, buttons, defaultButton);
+}
+
+/*!
+ Displays a simple about box with title \a title and text \a
+ text. The about box's parent is \a parent.
+
+ about() looks for a suitable icon in four locations:
+
+ \list 1
+ \o It prefers \link QWidget::windowIcon() parent->icon() \endlink
+ if that exists.
+ \o If not, it tries the top-level widget containing \a parent.
+ \o If that fails, it tries the \link
+ QApplication::activeWindow() active window. \endlink
+ \o As a last resort it uses the Information icon.
+ \endlist
+
+ The about box has a single button labelled "OK". On Mac OS X, the
+ about box is popped up as a modeless window; on other platforms,
+ it is currently application modal.
+
+ \sa QWidget::windowIcon(), QApplication::activeWindow()
+*/
+void QMessageBox::about(QWidget *parent, const QString &title, const QString &text)
+{
+#ifdef Q_WS_MAC
+ static QPointer<QMessageBox> oldMsgBox;
+
+ if (oldMsgBox && oldMsgBox->text() == text) {
+ oldMsgBox->show();
+ oldMsgBox->raise();
+ oldMsgBox->activateWindow();
+ return;
+ }
+#endif
+
+ QMessageBox *msgBox = new QMessageBox(title, text, Information, 0, 0, 0, parent
+#ifdef Q_WS_MAC
+ , Qt::WindowTitleHint | Qt::WindowSystemMenuHint
+#endif
+ );
+ msgBox->setAttribute(Qt::WA_DeleteOnClose);
+ QIcon icon = msgBox->windowIcon();
+ QSize size = icon.actualSize(QSize(64, 64));
+ msgBox->setIconPixmap(icon.pixmap(size));
+
+ // should perhaps be a style hint
+#ifdef Q_WS_MAC
+ oldMsgBox = msgBox;
+#if 0
+ // ### doesn't work until close button is enabled in title bar
+ msgBox->d_func()->autoAddOkButton = false;
+#else
+ msgBox->d_func()->buttonBox->setCenterButtons(true);
+#endif
+ msgBox->show();
+#else
+ msgBox->exec();
+#endif
+}
+
+/*!
+ Displays a simple message box about Qt, with the given \a title
+ and centered over \a parent (if \a parent is not 0). 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.
+
+ QApplication provides this functionality as a slot.
+
+ On Mac OS X, the about box is popped up as a modeless window; on
+ other platforms, it is currently application modal.
+
+ \sa QApplication::aboutQt()
+*/
+void QMessageBox::aboutQt(QWidget *parent, const QString &title)
+{
+#ifdef Q_WS_MAC
+ static QPointer<QMessageBox> oldMsgBox;
+
+ if (oldMsgBox) {
+ oldMsgBox->show();
+ oldMsgBox->raise();
+ oldMsgBox->activateWindow();
+ return;
+ }
+#endif
+
+ QString translatedTextAboutQtCaption;
+ translatedTextAboutQtCaption = QMessageBox::tr(
+ "<h3>About Qt</h3>"
+ "<p>This program uses Qt version %1.</p>"
+ ).arg(QLatin1String(QT_VERSION_STR));
+ QString translatedTextAboutQtText;
+ translatedTextAboutQtText = QMessageBox::tr(
+ "<p>Qt is a C++ toolkit for cross-platform application "
+ "development.</p>"
+ "<p>Qt provides single-source portability across MS&nbsp;Windows, "
+ "Mac&nbsp;OS&nbsp;X, Linux, and all major commercial Unix variants. "
+ "Qt is also available for embedded devices as Qt for Embedded Linux "
+ "and Qt for Windows CE.</p>"
+ "<p>Qt is available under three different licensing options designed "
+ "to accommodate the needs of our various users.</p>"
+ "<p>Qt licensed under our commercial license agreement is appropriate "
+ "for development of proprietary/commercial software where you do not "
+ "want to share any source code with third parties or otherwise cannot "
+ "comply with the terms of the GNU LGPL version 2.1 or GNU GPL version "
+ "3.0.</p>"
+ "<p>Qt licensed under the GNU LGPL version 2.1 is appropriate for the "
+ "development of Qt applications (proprietary or open source) provided "
+ "you can comply with the terms and conditions of the GNU LGPL version "
+ "2.1.</p>"
+ "<p>Qt licensed under the GNU General Public License version 3.0 is "
+ "appropriate for the development of Qt applications where you wish to "
+ "use such applications in combination with software subject to the "
+ "terms of the GNU GPL version 3.0 or where you are otherwise willing "
+ "to comply with the terms of the GNU GPL version 3.0.</p>"
+ "<p>Please see <a href=\"http://qt.nokia.com/products/licensing\">qt.nokia.com/products/licensing</a> "
+ "for an overview of Qt licensing.</p>"
+ "<p>Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).</p>"
+ "<p>Qt is a Nokia product. See <a href=\"http://qt.nokia.com/\">qt.nokia.com</a> "
+ "for more information.</p>"
+ );
+ QMessageBox *msgBox = new QMessageBox(parent);
+ msgBox->setAttribute(Qt::WA_DeleteOnClose);
+ msgBox->setWindowTitle(title.isEmpty() ? tr("About Qt") : title);
+ msgBox->setText(translatedTextAboutQtCaption);
+ msgBox->setInformativeText(translatedTextAboutQtText);
+
+ QPixmap pm(QLatin1String(":/trolltech/qmessagebox/images/qtlogo-64.png"));
+ if (!pm.isNull())
+ msgBox->setIconPixmap(pm);
+#if defined(Q_WS_WINCE)
+ msgBox->setDefaultButton(msgBox->addButton(QMessageBox::Ok));
+#endif
+
+ // should perhaps be a style hint
+#ifdef Q_WS_MAC
+ oldMsgBox = msgBox;
+#if 0
+ // ### doesn't work until close button is enabled in title bar
+ msgBox->d_func()->autoAddOkButton = false;
+#else
+ msgBox->d_func()->buttonBox->setCenterButtons(true);
+#endif
+ msgBox->show();
+#else
+ msgBox->exec();
+#endif
+}
+
+/*!
+ \internal
+*/
+QSize QMessageBox::sizeHint() const
+{
+ // ### Qt 5: remove
+ return QDialog::sizeHint();
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Source and binary compatibility routines for 4.0 and 4.1
+
+static QMessageBox::StandardButton newButton(int button)
+{
+ // this is needed for source compatibility with Qt 4.0 and 4.1
+ if (button == QMessageBox::NoButton || (button & NewButtonMask))
+ return QMessageBox::StandardButton(button & QMessageBox::ButtonMask);
+
+#if QT_VERSION < 0x050000
+ // this is needed for binary compatibility with Qt 4.0 and 4.1
+ switch (button & Old_ButtonMask) {
+ case Old_Ok:
+ return QMessageBox::Ok;
+ case Old_Cancel:
+ return QMessageBox::Cancel;
+ case Old_Yes:
+ return QMessageBox::Yes;
+ case Old_No:
+ return QMessageBox::No;
+ case Old_Abort:
+ return QMessageBox::Abort;
+ case Old_Retry:
+ return QMessageBox::Retry;
+ case Old_Ignore:
+ return QMessageBox::Ignore;
+ case Old_YesAll:
+ return QMessageBox::YesToAll;
+ case Old_NoAll:
+ return QMessageBox::NoToAll;
+ default:
+ return QMessageBox::NoButton;
+ }
+#else
+ return QMessageBox::NoButton;
+#endif
+}
+
+static bool detectedCompat(int button0, int button1, int button2)
+{
+ if (button0 != 0 && !(button0 & NewButtonMask))
+ return true;
+ if (button1 != 0 && !(button1 & NewButtonMask))
+ return true;
+ if (button2 != 0 && !(button2 & NewButtonMask))
+ return true;
+ return false;
+}
+
+QAbstractButton *QMessageBoxPrivate::findButton(int button0, int button1, int button2, int flags)
+{
+ Q_Q(QMessageBox);
+ int button = 0;
+
+ if (button0 & flags) {
+ button = button0;
+ } else if (button1 & flags) {
+ button = button1;
+ } else if (button2 & flags) {
+ button = button2;
+ }
+ return q->button(newButton(button));
+}
+
+void QMessageBoxPrivate::addOldButtons(int button0, int button1, int button2)
+{
+ Q_Q(QMessageBox);
+ q->addButton(newButton(button0));
+ q->addButton(newButton(button1));
+ q->addButton(newButton(button2));
+ q->setDefaultButton(
+ static_cast<QPushButton *>(findButton(button0, button1, button2, QMessageBox::Default)));
+ q->setEscapeButton(findButton(button0, button1, button2, QMessageBox::Escape));
+ compatMode = detectedCompat(button0, button1, button2);
+}
+
+QAbstractButton *QMessageBoxPrivate::abstractButtonForId(int id) const
+{
+ Q_Q(const QMessageBox);
+ QAbstractButton *result = customButtonList.value(id);
+ if (result)
+ return result;
+ if (id & QMessageBox::FlagMask) // for compatibility with Qt 4.0/4.1 (even if it is silly)
+ return 0;
+ return q->button(newButton(id));
+}
+
+int QMessageBoxPrivate::showOldMessageBox(QWidget *parent, QMessageBox::Icon icon,
+ const QString &title, const QString &text,
+ int button0, int button1, int button2)
+{
+ QMessageBox messageBox(icon, title, text, QMessageBox::NoButton, parent);
+ messageBox.d_func()->addOldButtons(button0, button1, button2);
+ return messageBox.exec();
+}
+
+int QMessageBoxPrivate::showOldMessageBox(QWidget *parent, QMessageBox::Icon icon,
+ const QString &title, const QString &text,
+ const QString &button0Text,
+ const QString &button1Text,
+ const QString &button2Text,
+ int defaultButtonNumber,
+ int escapeButtonNumber)
+{
+ QMessageBox messageBox(icon, title, text, QMessageBox::NoButton, parent);
+ QString myButton0Text = button0Text;
+ if (myButton0Text.isEmpty())
+ myButton0Text = QDialogButtonBox::tr("OK");
+ messageBox.addButton(myButton0Text, QMessageBox::ActionRole);
+ if (!button1Text.isEmpty())
+ messageBox.addButton(button1Text, QMessageBox::ActionRole);
+ if (!button2Text.isEmpty())
+ messageBox.addButton(button2Text, QMessageBox::ActionRole);
+
+ const QList<QAbstractButton *> &buttonList = messageBox.d_func()->customButtonList;
+ messageBox.setDefaultButton(static_cast<QPushButton *>(buttonList.value(defaultButtonNumber)));
+ messageBox.setEscapeButton(buttonList.value(escapeButtonNumber));
+
+ return messageBox.exec();
+}
+
+void QMessageBoxPrivate::retranslateStrings()
+{
+#ifndef QT_NO_TEXTEDIT
+ if (detailsButton)
+ detailsButton->setLabel(detailsText->isHidden() ? ShowLabel : HideLabel);
+#endif
+}
+
+/*!
+ \obsolete
+
+ Constructs a message box with a \a title, a \a text, an \a icon,
+ and up to three buttons.
+
+ The \a icon must be one of the following:
+ \list
+ \o QMessageBox::NoIcon
+ \o QMessageBox::Question
+ \o QMessageBox::Information
+ \o QMessageBox::Warning
+ \o QMessageBox::Critical
+ \endlist
+
+ Each button, \a button0, \a button1 and \a button2, can have one
+ of the following values:
+ \list
+ \o QMessageBox::NoButton
+ \o QMessageBox::Ok
+ \o QMessageBox::Cancel
+ \o QMessageBox::Yes
+ \o QMessageBox::No
+ \o QMessageBox::Abort
+ \o QMessageBox::Retry
+ \o QMessageBox::Ignore
+ \o QMessageBox::YesAll
+ \o QMessageBox::NoAll
+ \endlist
+
+ Use QMessageBox::NoButton for the later parameters to have fewer
+ than three buttons in your message box. If you don't specify any
+ buttons at all, QMessageBox will provide an Ok button.
+
+ One of the buttons can be OR-ed with the QMessageBox::Default
+ flag to make it the default button (clicked when Enter is
+ pressed).
+
+ One of the buttons can be OR-ed with the QMessageBox::Escape flag
+ to make it the cancel or close button (clicked when \key Esc is
+ pressed).
+
+ \snippet doc/src/snippets/dialogs/dialogs.cpp 2
+
+ The message box is an \l{Qt::ApplicationModal} {application modal}
+ dialog box.
+
+ The \a parent and \a f arguments are passed to
+ the QDialog constructor.
+
+ \sa setWindowTitle(), setText(), setIcon()
+*/
+QMessageBox::QMessageBox(const QString &title, const QString &text, Icon icon,
+ int button0, int button1, int button2, QWidget *parent,
+ Qt::WindowFlags f)
+ : QDialog(*new QMessageBoxPrivate, parent,
+ f /*| Qt::MSWindowsFixedSizeDialogHint #### */| Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint)
+{
+ Q_D(QMessageBox);
+ d->init(title, text);
+ setIcon(icon);
+ d->addOldButtons(button0, button1, button2);
+}
+
+/*!
+ \obsolete
+
+ Opens an information message box with the given \a title and the
+ \a text. The dialog may have up to three buttons. Each of the
+ buttons, \a button0, \a button1 and \a button2 may be set to one
+ of the following values:
+
+ \list
+ \o QMessageBox::NoButton
+ \o QMessageBox::Ok
+ \o QMessageBox::Cancel
+ \o QMessageBox::Yes
+ \o QMessageBox::No
+ \o QMessageBox::Abort
+ \o QMessageBox::Retry
+ \o QMessageBox::Ignore
+ \o QMessageBox::YesAll
+ \o QMessageBox::NoAll
+ \endlist
+
+ If you don't want all three buttons, set the last button, or last
+ two buttons to QMessageBox::NoButton.
+
+ One button can be OR-ed with QMessageBox::Default, and one
+ button can be OR-ed with QMessageBox::Escape.
+
+ Returns the identity (QMessageBox::Ok, or QMessageBox::No, etc.)
+ of the button that was clicked.
+
+ The message box is an \l{Qt::ApplicationModal} {application modal}
+ dialog box.
+
+ \warning Do not delete \a parent during the execution of the dialog.
+ If you want to do this, you should create the dialog
+ yourself using one of the QMessageBox constructors.
+
+ \sa question(), warning(), critical()
+*/
+int QMessageBox::information(QWidget *parent, const QString &title, const QString& text,
+ int button0, int button1, int button2)
+{
+ return QMessageBoxPrivate::showOldMessageBox(parent, Information, title, text,
+ button0, button1, button2);
+}
+
+/*!
+ \obsolete
+ \overload
+
+ Displays an information message box with the given \a title and
+ \a text, as well as one, two or three buttons. Returns the index
+ of the button that was clicked (0, 1 or 2).
+
+ \a button0Text is the text of the first button, and is optional.
+ If \a button0Text is not supplied, "OK" (translated) will be
+ used. \a button1Text is the text of the second button, and is
+ optional. \a button2Text is the text of the third button, and is
+ optional. \a defaultButtonNumber (0, 1 or 2) is the index of the
+ default button; pressing Return or Enter is the same as clicking
+ the default button. It defaults to 0 (the first button). \a
+ escapeButtonNumber is the index of the escape button; pressing
+ \key Esc is the same as clicking this button. It defaults to -1;
+ supply 0, 1 or 2 to make pressing \key Esc equivalent to clicking
+ the relevant button.
+
+ The message box is an \l{Qt::ApplicationModal} {application modal}
+ dialog box.
+
+ \warning Do not delete \a parent during the execution of the dialog.
+ If you want to do this, you should create the dialog
+ yourself using one of the QMessageBox constructors.
+
+ \sa question(), warning(), critical()
+*/
+
+int QMessageBox::information(QWidget *parent, const QString &title, const QString& text,
+ const QString& button0Text, const QString& button1Text,
+ const QString& button2Text, int defaultButtonNumber,
+ int escapeButtonNumber)
+{
+ return QMessageBoxPrivate::showOldMessageBox(parent, Information, title, text,
+ button0Text, button1Text, button2Text,
+ defaultButtonNumber, escapeButtonNumber);
+}
+
+/*!
+ \obsolete
+
+ Opens a question message box with the given \a title and \a text.
+ The dialog may have up to three buttons. Each of the buttons, \a
+ button0, \a button1 and \a button2 may be set to one of the
+ following values:
+
+ \list
+ \o QMessageBox::NoButton
+ \o QMessageBox::Ok
+ \o QMessageBox::Cancel
+ \o QMessageBox::Yes
+ \o QMessageBox::No
+ \o QMessageBox::Abort
+ \o QMessageBox::Retry
+ \o QMessageBox::Ignore
+ \o QMessageBox::YesAll
+ \o QMessageBox::NoAll
+ \endlist
+
+ If you don't want all three buttons, set the last button, or last
+ two buttons to QMessageBox::NoButton.
+
+ One button can be OR-ed with QMessageBox::Default, and one
+ button can be OR-ed with QMessageBox::Escape.
+
+ Returns the identity (QMessageBox::Yes, or QMessageBox::No, etc.)
+ of the button that was clicked.
+
+ The message box is an \l{Qt::ApplicationModal} {application modal}
+ dialog box.
+
+ \warning Do not delete \a parent during the execution of the dialog.
+ If you want to do this, you should create the dialog
+ yourself using one of the QMessageBox constructors.
+
+ \sa information(), warning(), critical()
+*/
+int QMessageBox::question(QWidget *parent, const QString &title, const QString& text,
+ int button0, int button1, int button2)
+{
+ return QMessageBoxPrivate::showOldMessageBox(parent, Question, title, text,
+ button0, button1, button2);
+}
+
+/*!
+ \obsolete
+ \overload
+
+ Displays a question message box with the given \a title and \a
+ text, as well as one, two or three buttons. Returns the index of
+ the button that was clicked (0, 1 or 2).
+
+ \a button0Text is the text of the first button, and is optional.
+ If \a button0Text is not supplied, "OK" (translated) will be used.
+ \a button1Text is the text of the second button, and is optional.
+ \a button2Text is the text of the third button, and is optional.
+ \a defaultButtonNumber (0, 1 or 2) is the index of the default
+ button; pressing Return or Enter is the same as clicking the
+ default button. It defaults to 0 (the first button). \a
+ escapeButtonNumber is the index of the Escape button; pressing
+ Escape is the same as clicking this button. It defaults to -1;
+ supply 0, 1 or 2 to make pressing Escape equivalent to clicking
+ the relevant button.
+
+ The message box is an \l{Qt::ApplicationModal} {application modal}
+ dialog box.
+
+ \warning Do not delete \a parent during the execution of the dialog.
+ If you want to do this, you should create the dialog
+ yourself using one of the QMessageBox constructors.
+
+ \sa information(), warning(), critical()
+*/
+int QMessageBox::question(QWidget *parent, const QString &title, const QString& text,
+ const QString& button0Text, const QString& button1Text,
+ const QString& button2Text, int defaultButtonNumber,
+ int escapeButtonNumber)
+{
+ return QMessageBoxPrivate::showOldMessageBox(parent, Question, title, text,
+ button0Text, button1Text, button2Text,
+ defaultButtonNumber, escapeButtonNumber);
+}
+
+
+/*!
+ \obsolete
+
+ Opens a warning message box with the given \a title and \a text.
+ The dialog may have up to three buttons. Each of the button
+ parameters, \a button0, \a button1 and \a button2 may be set to
+ one of the following values:
+
+ \list
+ \o QMessageBox::NoButton
+ \o QMessageBox::Ok
+ \o QMessageBox::Cancel
+ \o QMessageBox::Yes
+ \o QMessageBox::No
+ \o QMessageBox::Abort
+ \o QMessageBox::Retry
+ \o QMessageBox::Ignore
+ \o QMessageBox::YesAll
+ \o QMessageBox::NoAll
+ \endlist
+
+ If you don't want all three buttons, set the last button, or last
+ two buttons to QMessageBox::NoButton.
+
+ One button can be OR-ed with QMessageBox::Default, and one
+ button can be OR-ed with QMessageBox::Escape.
+
+ Returns the identity (QMessageBox::Ok or QMessageBox::No or ...)
+ of the button that was clicked.
+
+ The message box is an \l{Qt::ApplicationModal} {application modal}
+ dialog box.
+
+ \warning Do not delete \a parent during the execution of the dialog.
+ If you want to do this, you should create the dialog
+ yourself using one of the QMessageBox constructors.
+
+ \sa information(), question(), critical()
+*/
+int QMessageBox::warning(QWidget *parent, const QString &title, const QString& text,
+ int button0, int button1, int button2)
+{
+ return QMessageBoxPrivate::showOldMessageBox(parent, Warning, title, text,
+ button0, button1, button2);
+}
+
+/*!
+ \obsolete
+ \overload
+
+ Displays a warning message box with the given \a title and \a
+ text, as well as one, two, or three buttons. Returns the number
+ of the button that was clicked (0, 1, or 2).
+
+ \a button0Text is the text of the first button, and is optional.
+ If \a button0Text is not supplied, "OK" (translated) will be used.
+ \a button1Text is the text of the second button, and is optional,
+ and \a button2Text is the text of the third button, and is
+ optional. \a defaultButtonNumber (0, 1 or 2) is the index of the
+ default button; pressing Return or Enter is the same as clicking
+ the default button. It defaults to 0 (the first button). \a
+ escapeButtonNumber is the index of the Escape button; pressing
+ Escape is the same as clicking this button. It defaults to -1;
+ supply 0, 1, or 2 to make pressing Escape equivalent to clicking
+ the relevant button.
+
+ The message box is an \l{Qt::ApplicationModal} {application modal}
+ dialog box.
+
+ \warning Do not delete \a parent during the execution of the dialog.
+ If you want to do this, you should create the dialog
+ yourself using one of the QMessageBox constructors.
+
+ \sa information(), question(), critical()
+*/
+int QMessageBox::warning(QWidget *parent, const QString &title, const QString& text,
+ const QString& button0Text, const QString& button1Text,
+ const QString& button2Text, int defaultButtonNumber,
+ int escapeButtonNumber)
+{
+ return QMessageBoxPrivate::showOldMessageBox(parent, Warning, title, text,
+ button0Text, button1Text, button2Text,
+ defaultButtonNumber, escapeButtonNumber);
+}
+
+/*!
+ \obsolete
+
+ Opens a critical message box with the given \a title and \a text.
+ The dialog may have up to three buttons. Each of the button
+ parameters, \a button0, \a button1 and \a button2 may be set to
+ one of the following values:
+
+ \list
+ \o QMessageBox::NoButton
+ \o QMessageBox::Ok
+ \o QMessageBox::Cancel
+ \o QMessageBox::Yes
+ \o QMessageBox::No
+ \o QMessageBox::Abort
+ \o QMessageBox::Retry
+ \o QMessageBox::Ignore
+ \o QMessageBox::YesAll
+ \o QMessageBox::NoAll
+ \endlist
+
+ If you don't want all three buttons, set the last button, or last
+ two buttons to QMessageBox::NoButton.
+
+ One button can be OR-ed with QMessageBox::Default, and one
+ button can be OR-ed with QMessageBox::Escape.
+
+ Returns the identity (QMessageBox::Ok, or QMessageBox::No, etc.)
+ of the button that was clicked.
+
+ The message box is an \l{Qt::ApplicationModal} {application modal}
+ dialog box.
+
+ \warning Do not delete \a parent during the execution of the dialog.
+ If you want to do this, you should create the dialog
+ yourself using one of the QMessageBox constructors.
+
+ \sa information(), question(), warning()
+*/
+
+int QMessageBox::critical(QWidget *parent, const QString &title, const QString& text,
+ int button0, int button1, int button2)
+{
+ return QMessageBoxPrivate::showOldMessageBox(parent, Critical, title, text,
+ button0, button1, button2);
+}
+
+/*!
+ \obsolete
+ \overload
+
+ Displays a critical error message box with the given \a title and
+ \a text, as well as one, two, or three buttons. Returns the
+ number of the button that was clicked (0, 1 or 2).
+
+ \a button0Text is the text of the first button, and is optional.
+ If \a button0Text is not supplied, "OK" (translated) will be used.
+ \a button1Text is the text of the second button, and is optional,
+ and \a button2Text is the text of the third button, and is
+ optional. \a defaultButtonNumber (0, 1 or 2) is the index of the
+ default button; pressing Return or Enter is the same as clicking
+ the default button. It defaults to 0 (the first button). \a
+ escapeButtonNumber is the index of the Escape button; pressing
+ Escape is the same as clicking this button. It defaults to -1;
+ supply 0, 1, or 2 to make pressing Escape equivalent to clicking
+ the relevant button.
+
+ The message box is an \l{Qt::ApplicationModal} {application modal}
+ dialog box.
+
+ \warning Do not delete \a parent during the execution of the dialog.
+ If you want to do this, you should create the dialog
+ yourself using one of the QMessageBox constructors.
+
+ \sa information(), question(), warning()
+*/
+int QMessageBox::critical(QWidget *parent, const QString &title, const QString& text,
+ const QString& button0Text, const QString& button1Text,
+ const QString& button2Text, int defaultButtonNumber,
+ int escapeButtonNumber)
+{
+ return QMessageBoxPrivate::showOldMessageBox(parent, Critical, title, text,
+ button0Text, button1Text, button2Text,
+ defaultButtonNumber, escapeButtonNumber);
+}
+
+
+/*!
+ \obsolete
+
+ Returns the text of the message box button \a button, or
+ an empty string if the message box does not contain the button.
+
+ Use button() and QPushButton::text() instead.
+*/
+QString QMessageBox::buttonText(int button) const
+{
+ Q_D(const QMessageBox);
+
+ if (QAbstractButton *abstractButton = d->abstractButtonForId(button)) {
+ return abstractButton->text();
+ } else if (d->buttonBox->buttons().isEmpty() && (button == Ok || button == Old_Ok)) {
+ // for compatibility with Qt 4.0/4.1
+ return QDialogButtonBox::tr("OK");
+ }
+ return QString();
+}
+
+/*!
+ \obsolete
+
+ Sets the text of the message box button \a button to \a text.
+ Setting the text of a button that is not in the message box is
+ silently ignored.
+
+ Use addButton() instead.
+*/
+void QMessageBox::setButtonText(int button, const QString &text)
+{
+ Q_D(QMessageBox);
+ if (QAbstractButton *abstractButton = d->abstractButtonForId(button)) {
+ abstractButton->setText(text);
+ } else if (d->buttonBox->buttons().isEmpty() && (button == Ok || button == Old_Ok)) {
+ // for compatibility with Qt 4.0/4.1
+ addButton(QMessageBox::Ok)->setText(text);
+ }
+}
+
+#ifndef QT_NO_TEXTEDIT
+/*!
+ \property QMessageBox::detailedText
+ \brief the text to be displayed in the details area.
+ \since 4.2
+
+ The text will be interpreted as a plain text.
+
+ By default, this property contains an empty string.
+
+ \sa QMessageBox::text, QMessageBox::informativeText
+*/
+QString QMessageBox::detailedText() const
+{
+ Q_D(const QMessageBox);
+ return d->detailsText ? d->detailsText->text() : QString();
+}
+
+void QMessageBox::setDetailedText(const QString &text)
+{
+ Q_D(QMessageBox);
+ if (text.isEmpty()) {
+ delete d->detailsText;
+ d->detailsText = 0;
+ removeButton(d->detailsButton);
+ delete d->detailsButton;
+ d->detailsButton = 0;
+ return;
+ }
+
+ if (!d->detailsText) {
+ d->detailsText = new QMessageBoxDetailsText(this);
+ QGridLayout* grid = qobject_cast<QGridLayout*>(layout());
+ if (grid)
+ grid->addWidget(d->detailsText, grid->rowCount(), 0, 1, grid->columnCount());
+ d->detailsText->hide();
+ }
+ if (!d->detailsButton)
+ d->detailsButton = new DetailButton(this);
+ d->detailsText->setText(text);
+}
+#endif // QT_NO_TEXTEDIT
+
+/*!
+ \property QMessageBox::informativeText
+
+ \brief the informative text that provides a fuller description for
+ the message
+
+ \since 4.2
+
+ Infromative text can be used to expand upon the text() to give more
+ information to the user. On the Mac, this text appears in small
+ system font below the text(). On other platforms, it is simply
+ appended to the existing text.
+
+ By default, this property contains an empty string.
+
+ \sa QMessageBox::text, QMessageBox::detailedText
+*/
+QString QMessageBox::informativeText() const
+{
+ Q_D(const QMessageBox);
+ return d->informativeLabel ? d->informativeLabel->text() : QString();
+}
+
+void QMessageBox::setInformativeText(const QString &text)
+{
+ Q_D(QMessageBox);
+ if (text.isEmpty()) {
+ layout()->removeWidget(d->informativeLabel);
+ delete d->informativeLabel;
+ d->informativeLabel = 0;
+#ifndef Q_WS_MAC
+ d->label->setContentsMargins(2, 0, 0, 0);
+#endif
+ d->updateSize();
+ return;
+ }
+
+ if (!d->informativeLabel) {
+ QLabel *label = new QLabel;
+ label->setObjectName(QLatin1String("qt_msgbox_informativelabel"));
+ label->setTextInteractionFlags(Qt::TextInteractionFlags(style()->styleHint(QStyle::SH_MessageBox_TextInteractionFlags, 0, this)));
+ label->setAlignment(Qt::AlignTop | Qt::AlignLeft);
+ label->setOpenExternalLinks(true);
+ label->setWordWrap(true);
+#ifndef Q_WS_MAC
+ d->label->setContentsMargins(2, 0, 0, 0);
+ label->setContentsMargins(2, 0, 0, 6);
+ label->setIndent(9);
+#else
+ label->setContentsMargins(16, 0, 0, 0);
+ // apply a smaller font the information label on the mac
+ label->setFont(qt_app_fonts_hash()->value("QTipLabel"));
+#endif
+ label->setWordWrap(true);
+ QGridLayout *grid = static_cast<QGridLayout *>(layout());
+#if defined(Q_OS_SYMBIAN) || defined(Q_WS_MAEMO_5)
+ label->hide();
+ QTextBrowser *textBrowser = new QTextBrowser(this);
+ textBrowser->setOpenExternalLinks(true);
+ grid->addWidget(textBrowser, 1, 1, 1, 1);
+ d->textBrowser = textBrowser;
+#else
+ grid->addWidget(label, 1, 1, 1, 1);
+#endif
+ d->informativeLabel = label;
+ }
+ d->informativeLabel->setText(text);
+
+#if defined(Q_OS_SYMBIAN) || defined(Q_WS_MAEMO_5)
+ //We need to put the informative label inside textBrowser to enable scrolling of long texts.
+ d->textBrowser->setText(d->informativeLabel->text());
+#endif
+
+ d->updateSize();
+}
+
+/*!
+ \since 4.2
+
+ This function shadows QWidget::setWindowTitle().
+
+ Sets the title of the message box to \a title. On Mac OS X,
+ the window title is ignored (as required by the Mac OS X
+ Guidelines).
+*/
+void QMessageBox::setWindowTitle(const QString &title)
+{
+ // Message boxes on the mac do not have a title
+#ifndef Q_WS_MAC
+ QDialog::setWindowTitle(title);
+#else
+ Q_UNUSED(title);
+#endif
+}
+
+
+/*!
+ \since 4.2
+
+ This function shadows QWidget::setWindowModality().
+
+ Sets the modality of the message box to \a windowModality.
+
+ On Mac OS X, if the modality is set to Qt::WindowModal and the message box
+ has a parent, then the message box will be a Qt::Sheet, otherwise the
+ message box will be a standard dialog.
+*/
+void QMessageBox::setWindowModality(Qt::WindowModality windowModality)
+{
+ QDialog::setWindowModality(windowModality);
+
+ if (parentWidget() && windowModality == Qt::WindowModal)
+ setParent(parentWidget(), Qt::Sheet);
+ else
+ setParent(parentWidget(), Qt::Dialog);
+ setDefaultButton(d_func()->defaultButton);
+}
+
+#ifdef QT3_SUPPORT
+/*!
+ \compat
+
+ Constructs a message box with the given \a parent, \a name, and
+ window flags, \a f.
+ The window title is specified by \a title, and the message box
+ displays message text and an icon specified by \a text and \a icon.
+
+ The buttons that the user can access to respond to the message are
+ defined by \a button0, \a button1, and \a button2.
+*/
+QMessageBox::QMessageBox(const QString& title,
+ const QString &text, Icon icon,
+ int button0, int button1, int button2,
+ QWidget *parent, const char *name,
+ bool modal, Qt::WindowFlags f)
+ : QDialog(*new QMessageBoxPrivate, parent,
+ f | Qt::WStyle_Customize | Qt::WStyle_DialogBorder | Qt::WStyle_Title | Qt::WStyle_SysMenu | Qt::WindowCloseButtonHint)
+{
+ Q_D(QMessageBox);
+ setObjectName(QString::fromAscii(name));
+ d->init(title, text);
+ d->addOldButtons(button0, button1, button2);
+ setModal(modal);
+ setIcon(icon);
+}
+
+/*!
+ \compat
+ Constructs a message box with the given \a parent and \a name.
+*/
+QMessageBox::QMessageBox(QWidget *parent, const char *name)
+ : QDialog(*new QMessageBoxPrivate, parent,
+ Qt::WStyle_Customize | Qt::WStyle_DialogBorder | Qt::WStyle_Title | Qt::WStyle_SysMenu | Qt::WindowCloseButtonHint)
+{
+ Q_D(QMessageBox);
+ setObjectName(QString::fromAscii(name));
+ d->init();
+}
+
+/*!
+ Returns the pixmap used for a standard icon. This
+ allows the pixmaps to be used in more complex message boxes.
+ \a icon specifies the required icon, e.g. QMessageBox::Information,
+ QMessageBox::Warning or QMessageBox::Critical.
+
+ \a style is unused.
+*/
+
+QPixmap QMessageBox::standardIcon(Icon icon, Qt::GUIStyle style)
+{
+ Q_UNUSED(style);
+ return QMessageBox::standardIcon(icon);
+}
+
+/*!
+ \fn int QMessageBox::message(const QString &title, const QString &text,
+ const QString &buttonText, QWidget *parent = 0,
+ const char *name = 0)
+
+ Opens a modal message box with the given \a title and showing the
+ given \a text. The message box has a single button which has the
+ given \a buttonText (or tr("OK")). The message box is centred over
+ its \a parent and is called \a name.
+
+ Use information(), warning(), question(), or critical() instead.
+
+ \oldcode
+ QMessageBox::message(tr("My App"), tr("All occurrences replaced."),
+ tr("Close"), this);
+ \newcode
+ QMessageBox::information(this, tr("My App"),
+ tr("All occurrences replaced."),
+ QMessageBox::Close);
+ \endcode
+*/
+
+/*!
+ \fn bool QMessageBox::query(const QString &caption,
+ const QString& text,
+ const QString& yesButtonText,
+ const QString& noButtonText,
+ QWidget *parent, const char *name)
+
+ \obsolete
+
+ Queries the user using a modal message box with up to two buttons.
+ The message box has the given \a caption (although some window
+ managers don't show it), and shows the given \a text. The left
+ button has the \a yesButtonText (or tr("OK")), and the right button
+ has the \a noButtonText (or isn't shown). The message box is centred
+ over its \a parent and is called \a name.
+
+ Use information(), question(), warning(), or critical() instead.
+*/
+
+#endif
+
+QPixmap QMessageBoxPrivate::standardIcon(QMessageBox::Icon icon, QMessageBox *mb)
+{
+ QStyle *style = mb ? mb->style() : QApplication::style();
+ int iconSize = style->pixelMetric(QStyle::PM_MessageBoxIconSize, 0, mb);
+ QIcon tmpIcon;
+ switch (icon) {
+ case QMessageBox::Information:
+ tmpIcon = style->standardIcon(QStyle::SP_MessageBoxInformation, 0, mb);
+ break;
+ case QMessageBox::Warning:
+ tmpIcon = style->standardIcon(QStyle::SP_MessageBoxWarning, 0, mb);
+ break;
+ case QMessageBox::Critical:
+ tmpIcon = style->standardIcon(QStyle::SP_MessageBoxCritical, 0, mb);
+ break;
+ case QMessageBox::Question:
+ tmpIcon = style->standardIcon(QStyle::SP_MessageBoxQuestion, 0, mb);
+ default:
+ break;
+ }
+ if (!tmpIcon.isNull())
+ return tmpIcon.pixmap(iconSize, iconSize);
+ return QPixmap();
+}
+
+/*!
+ \obsolete
+
+ Returns the pixmap used for a standard icon. This allows the
+ pixmaps to be used in more complex message boxes. \a icon
+ specifies the required icon, e.g. QMessageBox::Question,
+ QMessageBox::Information, QMessageBox::Warning or
+ QMessageBox::Critical.
+
+ Call QStyle::standardIcon() with QStyle::SP_MessageBoxInformation etc.
+ instead.
+*/
+
+QPixmap QMessageBox::standardIcon(Icon icon)
+{
+ return QMessageBoxPrivate::standardIcon(icon, 0);
+}
+
+/*!
+ \typedef QMessageBox::Button
+ \obsolete
+
+ Use QMessageBox::StandardButton instead.
+*/
+
+/*!
+ \fn int QMessageBox::information(QWidget *parent, const QString &title,
+ const QString& text, StandardButton button0,
+ StandardButton button1)
+ \fn int QMessageBox::warning(QWidget *parent, const QString &title,
+ const QString& text, StandardButton button0,
+ StandardButton button1)
+ \fn int QMessageBox::critical(QWidget *parent, const QString &title,
+ const QString& text, StandardButton button0,
+ StandardButton button1)
+ \fn int QMessageBox::question(QWidget *parent, const QString &title,
+ const QString& text, StandardButton button0,
+ StandardButton button1)
+ \internal
+
+ ### Needed for Qt 4 source compatibility
+*/
+
+/*!
+ \fn int QMessageBox::exec()
+
+ Shows the message box as a \l{QDialog#Modal Dialogs}{modal dialog},
+ blocking until the user closes it.
+
+ When using a QMessageBox with standard buttons, this functions returns a
+ \l StandardButton value indicating the standard button that was clicked.
+ When using QMessageBox with custom buttons, this function returns an
+ opaque value; use clickedButton() to determine which button was clicked.
+
+ Users cannot interact with any other window in the same
+ application until they close the dialog, either by clicking a
+ button or by using a mechanism provided by the window system.
+
+ \sa show(), result()
+*/
+
+QT_END_NAMESPACE
+
+#include "moc_qmessagebox.cpp"
+
+#endif // QT_NO_MESSAGEBOX
diff --git a/src/widgets/dialogs/qmessagebox.h b/src/widgets/dialogs/qmessagebox.h
new file mode 100644
index 0000000000..b2c99d3881
--- /dev/null
+++ b/src/widgets/dialogs/qmessagebox.h
@@ -0,0 +1,365 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMESSAGEBOX_H
+#define QMESSAGEBOX_H
+
+#include <QtWidgets/qdialog.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_MESSAGEBOX
+
+class QLabel;
+class QMessageBoxPrivate;
+class QAbstractButton;
+
+class Q_WIDGETS_EXPORT QMessageBox : public QDialog
+{
+ Q_OBJECT
+ Q_ENUMS(Icon)
+ Q_FLAGS(StandardButtons)
+ Q_PROPERTY(QString text READ text WRITE setText)
+ // ### Qt 5: Rename 'icon' 'standardIcon' and 'iconPixmap' 'icon' (and use QIcon?)
+ Q_PROPERTY(Icon icon READ icon WRITE setIcon)
+ Q_PROPERTY(QPixmap iconPixmap READ iconPixmap WRITE setIconPixmap)
+ Q_PROPERTY(Qt::TextFormat textFormat READ textFormat WRITE setTextFormat)
+ Q_PROPERTY(StandardButtons standardButtons READ standardButtons WRITE setStandardButtons)
+#ifndef QT_NO_TEXTEDIT
+ Q_PROPERTY(QString detailedText READ detailedText WRITE setDetailedText)
+#endif
+ Q_PROPERTY(QString informativeText READ informativeText WRITE setInformativeText)
+
+public:
+ enum Icon {
+ NoIcon = 0,
+ Information = 1,
+ Warning = 2,
+ Critical = 3,
+ Question = 4
+ };
+
+ enum ButtonRole {
+ // keep this in sync with QDialogButtonBox::ButtonRole
+ InvalidRole = -1,
+ AcceptRole,
+ RejectRole,
+ DestructiveRole,
+ ActionRole,
+ HelpRole,
+ YesRole,
+ NoRole,
+ ResetRole,
+ ApplyRole,
+
+ NRoles
+ };
+
+ enum StandardButton {
+ // keep this in sync with QDialogButtonBox::StandardButton
+ NoButton = 0x00000000,
+ Ok = 0x00000400,
+ Save = 0x00000800,
+ SaveAll = 0x00001000,
+ Open = 0x00002000,
+ Yes = 0x00004000,
+ YesToAll = 0x00008000,
+ No = 0x00010000,
+ NoToAll = 0x00020000,
+ Abort = 0x00040000,
+ Retry = 0x00080000,
+ Ignore = 0x00100000,
+ Close = 0x00200000,
+ Cancel = 0x00400000,
+ Discard = 0x00800000,
+ Help = 0x01000000,
+ Apply = 0x02000000,
+ Reset = 0x04000000,
+ RestoreDefaults = 0x08000000,
+
+ FirstButton = Ok, // internal
+ LastButton = RestoreDefaults, // internal
+
+ YesAll = YesToAll, // obsolete
+ NoAll = NoToAll, // obsolete
+
+ Default = 0x00000100, // obsolete
+ Escape = 0x00000200, // obsolete
+ FlagMask = 0x00000300, // obsolete
+ ButtonMask = ~FlagMask // obsolete
+ };
+ typedef StandardButton Button; // obsolete
+
+ Q_DECLARE_FLAGS(StandardButtons, StandardButton)
+
+ explicit QMessageBox(QWidget *parent = 0);
+ QMessageBox(Icon icon, const QString &title, const QString &text,
+ StandardButtons buttons = NoButton, QWidget *parent = 0,
+ Qt::WindowFlags flags = Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint);
+ ~QMessageBox();
+
+ void addButton(QAbstractButton *button, ButtonRole role);
+ QPushButton *addButton(const QString &text, ButtonRole role);
+ QPushButton *addButton(StandardButton button);
+ void removeButton(QAbstractButton *button);
+
+#ifdef Q_WS_WINCE
+ void setVisible(bool visible);
+#endif
+
+#ifdef Q_NO_USING_KEYWORD
+#ifndef Q_QDOC
+ void open() { QDialog::open(); }
+#endif
+#else
+ using QDialog::open;
+#endif
+ void open(QObject *receiver, const char *member);
+
+ QList<QAbstractButton *> buttons() const;
+ ButtonRole buttonRole(QAbstractButton *button) const;
+
+ void setStandardButtons(StandardButtons buttons);
+ StandardButtons standardButtons() const;
+ StandardButton standardButton(QAbstractButton *button) const;
+ QAbstractButton *button(StandardButton which) const;
+
+ QPushButton *defaultButton() const;
+ void setDefaultButton(QPushButton *button);
+ void setDefaultButton(StandardButton button);
+
+ QAbstractButton *escapeButton() const;
+ void setEscapeButton(QAbstractButton *button);
+ void setEscapeButton(StandardButton button);
+
+ QAbstractButton *clickedButton() const;
+
+ QString text() const;
+ void setText(const QString &text);
+
+ Icon icon() const;
+ void setIcon(Icon);
+
+ QPixmap iconPixmap() const;
+ void setIconPixmap(const QPixmap &pixmap);
+
+ Qt::TextFormat textFormat() const;
+ void setTextFormat(Qt::TextFormat format);
+
+ static StandardButton information(QWidget *parent, const QString &title,
+ const QString &text, StandardButtons buttons = Ok,
+ StandardButton defaultButton = NoButton);
+ // ### Qt 5: Replace Ok with Yes|No in question() function.
+ // Also consider if Ok == Yes and Cancel == No.
+ static StandardButton question(QWidget *parent, const QString &title,
+ const QString &text, StandardButtons buttons = Ok,
+ StandardButton defaultButton = NoButton);
+ static StandardButton warning(QWidget *parent, const QString &title,
+ const QString &text, StandardButtons buttons = Ok,
+ StandardButton defaultButton = NoButton);
+ static StandardButton critical(QWidget *parent, const QString &title,
+ const QString &text, StandardButtons buttons = Ok,
+ StandardButton defaultButton = NoButton);
+ static void about(QWidget *parent, const QString &title, const QString &text);
+ static void aboutQt(QWidget *parent, const QString &title = QString());
+
+ QSize sizeHint() const;
+
+ // the following functions are obsolete:
+
+ QMessageBox(const QString &title, const QString &text, Icon icon,
+ int button0, int button1, int button2,
+ QWidget *parent = 0,
+ Qt::WindowFlags f = Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint);
+
+ static int information(QWidget *parent, const QString &title,
+ const QString& text,
+ int button0, int button1 = 0, int button2 = 0);
+ static int information(QWidget *parent, const QString &title,
+ const QString& text,
+ const QString& button0Text,
+ const QString& button1Text = QString(),
+ const QString& button2Text = QString(),
+ int defaultButtonNumber = 0,
+ int escapeButtonNumber = -1);
+ inline static StandardButton information(QWidget *parent, const QString &title,
+ const QString& text,
+ StandardButton button0, StandardButton button1 = NoButton)
+ { return information(parent, title, text, StandardButtons(button0), button1); }
+
+ static int question(QWidget *parent, const QString &title,
+ const QString& text,
+ int button0, int button1 = 0, int button2 = 0);
+ static int question(QWidget *parent, const QString &title,
+ const QString& text,
+ const QString& button0Text,
+ const QString& button1Text = QString(),
+ const QString& button2Text = QString(),
+ int defaultButtonNumber = 0,
+ int escapeButtonNumber = -1);
+ inline static int question(QWidget *parent, const QString &title,
+ const QString& text,
+ StandardButton button0, StandardButton button1)
+ { return question(parent, title, text, StandardButtons(button0), button1); }
+
+ static int warning(QWidget *parent, const QString &title,
+ const QString& text,
+ int button0, int button1, int button2 = 0);
+ static int warning(QWidget *parent, const QString &title,
+ const QString& text,
+ const QString& button0Text,
+ const QString& button1Text = QString(),
+ const QString& button2Text = QString(),
+ int defaultButtonNumber = 0,
+ int escapeButtonNumber = -1);
+ inline static int warning(QWidget *parent, const QString &title,
+ const QString& text,
+ StandardButton button0, StandardButton button1)
+ { return warning(parent, title, text, StandardButtons(button0), button1); }
+
+ static int critical(QWidget *parent, const QString &title,
+ const QString& text,
+ int button0, int button1, int button2 = 0);
+ static int critical(QWidget *parent, const QString &title,
+ const QString& text,
+ const QString& button0Text,
+ const QString& button1Text = QString(),
+ const QString& button2Text = QString(),
+ int defaultButtonNumber = 0,
+ int escapeButtonNumber = -1);
+ inline static int critical(QWidget *parent, const QString &title,
+ const QString& text,
+ StandardButton button0, StandardButton button1)
+ { return critical(parent, title, text, StandardButtons(button0), button1); }
+
+ QString buttonText(int button) const;
+ void setButtonText(int button, const QString &text);
+
+ QString informativeText() const;
+ void setInformativeText(const QString &text);
+
+#ifndef QT_NO_TEXTEDIT
+ QString detailedText() const;
+ void setDetailedText(const QString &text);
+#endif
+
+ void setWindowTitle(const QString &title);
+ void setWindowModality(Qt::WindowModality windowModality);
+
+#ifdef QT3_SUPPORT
+ QT3_SUPPORT_CONSTRUCTOR QMessageBox(const QString &title, const QString &text, Icon icon,
+ int button0, int button1, int button2,
+ QWidget *parent, const char *name, bool modal,
+ Qt::WindowFlags f = Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint);
+ QT3_SUPPORT_CONSTRUCTOR QMessageBox(QWidget *parent, const char *name);
+
+ static QT3_SUPPORT QPixmap standardIcon(Icon icon, Qt::GUIStyle);
+ static QT3_SUPPORT int message(const QString &title,
+ const QString& text,
+ const QString& buttonText=QString(),
+ QWidget *parent = 0, const char * = 0) {
+ return QMessageBox::information(parent, title, text,
+ buttonText.isEmpty() ? tr("OK") : buttonText) == 0;
+ }
+ static QT3_SUPPORT bool query(const QString &title,
+ const QString& text,
+ const QString& yesButtonText = QString(),
+ const QString& noButtonText = QString(),
+ QWidget *parent = 0, const char * = 0) {
+ return QMessageBox::information(parent, title, text,
+ yesButtonText.isEmpty() ? tr("OK") : yesButtonText,
+ noButtonText) == 0;
+ }
+#endif
+
+ static QPixmap standardIcon(Icon icon);
+
+Q_SIGNALS:
+ void buttonClicked(QAbstractButton *button);
+
+#ifdef qdoc
+public Q_SLOTS:
+ int exec();
+#endif
+
+protected:
+ bool event(QEvent *e);
+ void resizeEvent(QResizeEvent *event);
+ void showEvent(QShowEvent *event);
+ void closeEvent(QCloseEvent *event);
+ void keyPressEvent(QKeyEvent *event);
+ void changeEvent(QEvent *event);
+
+private:
+ Q_PRIVATE_SLOT(d_func(), void _q_buttonClicked(QAbstractButton *))
+
+ Q_DISABLE_COPY(QMessageBox)
+ Q_DECLARE_PRIVATE(QMessageBox)
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QMessageBox::StandardButtons)
+
+#define QT_REQUIRE_VERSION(argc, argv, str) { QString s = QString::fromLatin1(str);\
+QString sq = QString::fromLatin1(qVersion()); \
+if ((sq.section(QChar::fromLatin1('.'),0,0).toInt()<<16)+\
+(sq.section(QChar::fromLatin1('.'),1,1).toInt()<<8)+\
+sq.section(QChar::fromLatin1('.'),2,2).toInt()<(s.section(QChar::fromLatin1('.'),0,0).toInt()<<16)+\
+(s.section(QChar::fromLatin1('.'),1,1).toInt()<<8)+\
+s.section(QChar::fromLatin1('.'),2,2).toInt()) { \
+if (!qApp){ \
+ new QApplication(argc,argv); \
+} \
+QString s = QApplication::tr("Executable '%1' requires Qt "\
+ "%2, found Qt %3.").arg(qAppName()).arg(QString::fromLatin1(\
+str)).arg(QString::fromLatin1(qVersion())); QMessageBox::critical(0, QApplication::tr(\
+"Incompatible Qt Library Error"), s, QMessageBox::Abort, 0); qFatal("%s", s.toLatin1().data()); }}
+
+#endif // QT_NO_MESSAGEBOX
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QMESSAGEBOX_H
diff --git a/src/gui/dialogs/qmessagebox.qrc b/src/widgets/dialogs/qmessagebox.qrc
index 8e6d7af671..8e6d7af671 100644
--- a/src/gui/dialogs/qmessagebox.qrc
+++ b/src/widgets/dialogs/qmessagebox.qrc
diff --git a/src/gui/dialogs/qnspanelproxy_mac.mm b/src/widgets/dialogs/qnspanelproxy_mac.mm
index 1de548413a..1de548413a 100644
--- a/src/gui/dialogs/qnspanelproxy_mac.mm
+++ b/src/widgets/dialogs/qnspanelproxy_mac.mm
diff --git a/src/widgets/dialogs/qprogressdialog.cpp b/src/widgets/dialogs/qprogressdialog.cpp
new file mode 100644
index 0000000000..8701dc10fb
--- /dev/null
+++ b/src/widgets/dialogs/qprogressdialog.cpp
@@ -0,0 +1,907 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qprogressdialog.h"
+
+#ifndef QT_NO_PROGRESSDIALOG
+
+#include "qshortcut.h"
+#include "qpainter.h"
+#include "qdrawutil.h"
+#include "qlabel.h"
+#include "qprogressbar.h"
+#include "qapplication.h"
+#include "qstyle.h"
+#include "qpushbutton.h"
+#include "qcursor.h"
+#include "qtimer.h"
+#include "qelapsedtimer.h"
+#include <private/qdialog_p.h>
+#include <limits.h>
+
+#if defined(QT_SOFTKEYS_ENABLED)
+#include <qaction.h>
+#endif
+#ifdef Q_WS_S60
+#include <QtWidgets/qdesktopwidget.h>
+#endif
+
+
+QT_BEGIN_NAMESPACE
+
+// If the operation is expected to take this long (as predicted by
+// progress time), show the progress dialog.
+static const int defaultShowTime = 4000;
+// Wait at least this long before attempting to make a prediction.
+static const int minWaitTime = 50;
+
+class QProgressDialogPrivate : public QDialogPrivate
+{
+ Q_DECLARE_PUBLIC(QProgressDialog)
+
+public:
+ QProgressDialogPrivate() : label(0), cancel(0), bar(0),
+ shown_once(false),
+ cancellation_flag(false),
+ showTime(defaultShowTime),
+#ifndef QT_NO_SHORTCUT
+ escapeShortcut(0),
+#endif
+#ifdef QT_SOFTKEYS_ENABLED
+ cancelAction(0),
+#endif
+ useDefaultCancelText(false)
+ {
+ }
+
+ void init(const QString &labelText, const QString &cancelText, int min, int max);
+ void layout();
+ void retranslateStrings();
+ void _q_disconnectOnClose();
+
+ QLabel *label;
+ QPushButton *cancel;
+ QProgressBar *bar;
+ QTimer *forceTimer;
+ bool shown_once;
+ bool cancellation_flag;
+ QElapsedTimer starttime;
+#ifndef QT_NO_CURSOR
+ QCursor parentCursor;
+#endif
+ int showTime;
+ bool autoClose;
+ bool autoReset;
+ bool forceHide;
+#ifndef QT_NO_SHORTCUT
+ QShortcut *escapeShortcut;
+#endif
+#ifdef QT_SOFTKEYS_ENABLED
+ QAction *cancelAction;
+#endif
+ bool useDefaultCancelText;
+ QPointer<QObject> receiverToDisconnectOnClose;
+ QByteArray memberToDisconnectOnClose;
+};
+
+void QProgressDialogPrivate::init(const QString &labelText, const QString &cancelText,
+ int min, int max)
+{
+ Q_Q(QProgressDialog);
+ label = new QLabel(labelText, q);
+ int align = q->style()->styleHint(QStyle::SH_ProgressDialog_TextLabelAlignment, 0, q);
+ label->setAlignment(Qt::Alignment(align));
+ bar = new QProgressBar(q);
+ bar->setRange(min, max);
+ autoClose = true;
+ autoReset = true;
+ forceHide = false;
+ QObject::connect(q, SIGNAL(canceled()), q, SLOT(cancel()));
+ forceTimer = new QTimer(q);
+ QObject::connect(forceTimer, SIGNAL(timeout()), q, SLOT(forceShow()));
+ if (useDefaultCancelText) {
+ retranslateStrings();
+ } else {
+ q->setCancelButtonText(cancelText);
+ }
+}
+
+void QProgressDialogPrivate::layout()
+{
+ Q_Q(QProgressDialog);
+ int sp = q->style()->pixelMetric(QStyle::PM_DefaultLayoutSpacing);
+ int mtb = q->style()->pixelMetric(QStyle::PM_DefaultTopLevelMargin);
+ int mlr = qMin(q->width() / 10, mtb);
+ const bool centered =
+ bool(q->style()->styleHint(QStyle::SH_ProgressDialog_CenterCancelButton, 0, q));
+
+ int additionalSpacing = 0;
+#ifdef Q_OS_SYMBIAN
+ //In Symbian, we need to have wider margins for dialog borders, as the actual border is some pixels
+ //inside the dialog area (to enable transparent borders)
+ additionalSpacing = mlr;
+#endif
+
+ QSize cs = cancel ? cancel->sizeHint() : QSize(0,0);
+ QSize bh = bar->sizeHint();
+ int cspc;
+ int lh = 0;
+
+ // Find spacing and sizes that fit. It is important that a progress
+ // dialog can be made very small if the user demands it so.
+ for (int attempt=5; attempt--;) {
+ cspc = cancel ? cs.height() + sp : 0;
+ lh = qMax(0, q->height() - mtb - bh.height() - sp - cspc);
+
+ if (lh < q->height()/4) {
+ // Getting cramped
+ sp /= 2;
+ mtb /= 2;
+ if (cancel) {
+ cs.setHeight(qMax(4,cs.height()-sp-2));
+ }
+ bh.setHeight(qMax(4,bh.height()-sp-1));
+ } else {
+ break;
+ }
+ }
+
+ if (cancel) {
+ cancel->setGeometry(
+ centered ? q->width()/2 - cs.width()/2 : q->width() - mlr - cs.width(),
+ q->height() - mtb - cs.height(),
+ cs.width(), cs.height());
+ }
+
+ if (label)
+ label->setGeometry(mlr, additionalSpacing, q->width() - mlr * 2, lh);
+ bar->setGeometry(mlr, lh + sp + additionalSpacing, q->width() - mlr * 2, bh.height());
+}
+
+void QProgressDialogPrivate::retranslateStrings()
+{
+ Q_Q(QProgressDialog);
+ if (useDefaultCancelText)
+ q->setCancelButtonText(QProgressDialog::tr("Cancel"));
+}
+
+void QProgressDialogPrivate::_q_disconnectOnClose()
+{
+ Q_Q(QProgressDialog);
+ if (receiverToDisconnectOnClose) {
+ QObject::disconnect(q, SIGNAL(canceled()), receiverToDisconnectOnClose,
+ memberToDisconnectOnClose);
+ receiverToDisconnectOnClose = 0;
+ }
+ memberToDisconnectOnClose.clear();
+}
+
+/*!
+ \class QProgressDialog
+ \brief The QProgressDialog class provides feedback on the progress of a slow operation.
+ \ingroup standard-dialogs
+
+
+ A progress dialog is used to give the user an indication of how long
+ an operation is going to take, and to demonstrate that the
+ application has not frozen. It can also give the user an opportunity
+ to abort the operation.
+
+ A common problem with progress dialogs is that it is difficult to know
+ when to use them; operations take different amounts of time on different
+ hardware. QProgressDialog offers a solution to this problem:
+ it estimates the time the operation will take (based on time for
+ steps), and only shows itself if that estimate is beyond minimumDuration()
+ (4 seconds by default).
+
+ Use setMinimum() and setMaximum() or the constructor to set the number of
+ "steps" in the operation and call setValue() as the operation
+ progresses. The number of steps can be chosen arbitrarily. It can be the
+ number of files copied, the number of bytes received, the number of
+ iterations through the main loop of your algorithm, or some other
+ suitable unit. Progress starts at the value set by setMinimum(),
+ and the progress dialog shows that the operation has finished when
+ you call setValue() with the value set by setMaximum() as its argument.
+
+ The dialog automatically resets and hides itself at the end of the
+ operation. Use setAutoReset() and setAutoClose() to change this
+ behavior. Note that if you set a new maximum (using setMaximum() or
+ setRange()) that equals your current value(), the dialog will not
+ close regardless.
+
+ There are two ways of using QProgressDialog: modal and modeless.
+
+ Compared to a modeless QProgressDialog, a modal QProgressDialog is simpler
+ to use for the programmer. Do the operation in a loop, call \l setValue() at
+ intervals, and check for cancellation with wasCanceled(). For example:
+
+ \snippet doc/src/snippets/dialogs/dialogs.cpp 3
+
+ A modeless progress dialog is suitable for operations that take
+ place in the background, where the user is able to interact with the
+ application. Such operations are typically based on QTimer (or
+ QObject::timerEvent()), QSocketNotifier, or QUrlOperator; or performed
+ in a separate thread. A QProgressBar in the status bar of your main window
+ is often an alternative to a modeless progress dialog.
+
+ You need to have an event loop to be running, connect the
+ canceled() signal to a slot that stops the operation, and call \l
+ setValue() at intervals. For example:
+
+ \snippet doc/src/snippets/dialogs/dialogs.cpp 4
+ \codeline
+ \snippet doc/src/snippets/dialogs/dialogs.cpp 5
+ \codeline
+ \snippet doc/src/snippets/dialogs/dialogs.cpp 6
+
+ In both modes the progress dialog may be customized by
+ replacing the child widgets with custom widgets by using setLabel(),
+ setBar(), and setCancelButton().
+ The functions setLabelText() and setCancelButtonText()
+ set the texts shown.
+
+ \image plastique-progressdialog.png A progress dialog shown in the Plastique widget style.
+
+ \sa QDialog, QProgressBar, {fowler}{GUI Design Handbook: Progress Indicator},
+ {Find Files Example}, {Pixelator Example}
+*/
+
+
+/*!
+ Constructs a progress dialog.
+
+ Default settings:
+ \list
+ \i The label text is empty.
+ \i The cancel button text is (translated) "Cancel".
+ \i minimum is 0;
+ \i maximum is 100
+ \endlist
+
+ The \a parent argument is dialog's parent widget. The widget flags, \a f, are
+ passed to the QDialog::QDialog() constructor.
+
+ \sa setLabelText(), setCancelButtonText(), setCancelButton(),
+ setMinimum(), setMaximum()
+*/
+
+QProgressDialog::QProgressDialog(QWidget *parent, Qt::WindowFlags f)
+ : QDialog(*(new QProgressDialogPrivate), parent, f)
+{
+ Q_D(QProgressDialog);
+ d->useDefaultCancelText = true;
+ d->init(QString::fromLatin1(""), QString(), 0, 100);
+}
+
+/*!
+ Constructs a progress dialog.
+
+ The \a labelText is the text used to remind the user what is progressing.
+
+ The \a cancelButtonText is the text to display on the cancel button. If
+ QString() is passed then no cancel button is shown.
+
+ The \a minimum and \a maximum is the number of steps in the operation for
+ which this progress dialog shows progress. For example, if the
+ operation is to examine 50 files, this value minimum value would be 0,
+ and the maximum would be 50. Before examining the first file, call
+ setValue(0). As each file is processed call setValue(1), setValue(2),
+ etc., finally calling setValue(50) after examining the last file.
+
+ The \a parent argument is the dialog's parent widget. The parent, \a parent, and
+ widget flags, \a f, are passed to the QDialog::QDialog() constructor.
+
+ \sa setLabelText(), setLabel(), setCancelButtonText(), setCancelButton(),
+ setMinimum(), setMaximum()
+*/
+
+QProgressDialog::QProgressDialog(const QString &labelText,
+ const QString &cancelButtonText,
+ int minimum, int maximum,
+ QWidget *parent, Qt::WindowFlags f)
+ : QDialog(*(new QProgressDialogPrivate), parent, f)
+{
+ Q_D(QProgressDialog);
+ d->init(labelText, cancelButtonText, minimum, maximum);
+}
+
+
+/*!
+ Destroys the progress dialog.
+*/
+
+QProgressDialog::~QProgressDialog()
+{
+}
+
+/*!
+ \fn void QProgressDialog::canceled()
+
+ This signal is emitted when the cancel button is clicked.
+ It is connected to the cancel() slot by default.
+
+ \sa wasCanceled()
+*/
+
+
+/*!
+ Sets the label to \a label. The progress dialog resizes to fit. The
+ label becomes owned by the progress dialog and will be deleted when
+ necessary, so do not pass the address of an object on the stack.
+
+ \sa setLabelText()
+*/
+
+void QProgressDialog::setLabel(QLabel *label)
+{
+ Q_D(QProgressDialog);
+ delete d->label;
+ d->label = label;
+ if (label) {
+ if (label->parentWidget() == this) {
+ label->hide(); // until we resize
+ } else {
+ label->setParent(this, 0);
+ }
+ }
+ int w = qMax(isVisible() ? width() : 0, sizeHint().width());
+ int h = qMax(isVisible() ? height() : 0, sizeHint().height());
+ resize(w, h);
+ if (label)
+ label->show();
+}
+
+
+/*!
+ \property QProgressDialog::labelText
+ \brief the label's text
+
+ The default text is an empty string.
+*/
+
+QString QProgressDialog::labelText() const
+{
+ Q_D(const QProgressDialog);
+ if (d->label)
+ return d->label->text();
+ return QString();
+}
+
+void QProgressDialog::setLabelText(const QString &text)
+{
+ Q_D(QProgressDialog);
+ if (d->label) {
+ d->label->setText(text);
+ int w = qMax(isVisible() ? width() : 0, sizeHint().width());
+ int h = qMax(isVisible() ? height() : 0, sizeHint().height());
+ resize(w, h);
+ }
+}
+
+
+/*!
+ Sets the cancel button to the push button, \a cancelButton. The
+ progress dialog takes ownership of this button which will be deleted
+ when necessary, so do not pass the address of an object that is on
+ the stack, i.e. use new() to create the button. If 0 is passed then
+ no cancel button will be shown.
+
+ \sa setCancelButtonText()
+*/
+
+void QProgressDialog::setCancelButton(QPushButton *cancelButton)
+{
+ Q_D(QProgressDialog);
+ delete d->cancel;
+ d->cancel = cancelButton;
+ if (cancelButton) {
+ if (cancelButton->parentWidget() == this) {
+ cancelButton->hide(); // until we resize
+ } else {
+ cancelButton->setParent(this, 0);
+ }
+ connect(d->cancel, SIGNAL(clicked()), this, SIGNAL(canceled()));
+#ifndef QT_NO_SHORTCUT
+ d->escapeShortcut = new QShortcut(Qt::Key_Escape, this, SIGNAL(canceled()));
+#endif
+ } else {
+#ifndef QT_NO_SHORTCUT
+ delete d->escapeShortcut;
+ d->escapeShortcut = 0;
+#endif
+ }
+ int w = qMax(isVisible() ? width() : 0, sizeHint().width());
+ int h = qMax(isVisible() ? height() : 0, sizeHint().height());
+ resize(w, h);
+ if (cancelButton)
+#if !defined(QT_SOFTKEYS_ENABLED)
+ cancelButton->show();
+#else
+ {
+ d->cancelAction = new QAction(cancelButton->text(), cancelButton);
+ d->cancelAction->setSoftKeyRole(QAction::NegativeSoftKey);
+ connect(d->cancelAction, SIGNAL(triggered()), this, SIGNAL(canceled()));
+ addAction(d->cancelAction);
+ }
+#endif
+}
+
+/*!
+ Sets the cancel button's text to \a cancelButtonText. If the text
+ is set to QString() then it will cause the cancel button to be
+ hidden and deleted.
+
+ \sa setCancelButton()
+*/
+
+void QProgressDialog::setCancelButtonText(const QString &cancelButtonText)
+{
+ Q_D(QProgressDialog);
+ d->useDefaultCancelText = false;
+
+ if (!cancelButtonText.isNull()) {
+ if (d->cancel) {
+ d->cancel->setText(cancelButtonText);
+#ifdef QT_SOFTKEYS_ENABLED
+ d->cancelAction->setText(cancelButtonText);
+#endif
+ } else {
+ setCancelButton(new QPushButton(cancelButtonText, this));
+ }
+ } else {
+ setCancelButton(0);
+ }
+ int w = qMax(isVisible() ? width() : 0, sizeHint().width());
+ int h = qMax(isVisible() ? height() : 0, sizeHint().height());
+ resize(w, h);
+}
+
+
+/*!
+ Sets the progress bar widget to \a bar. The progress dialog resizes to
+ fit. The progress dialog takes ownership of the progress \a bar which
+ will be deleted when necessary, so do not use a progress bar
+ allocated on the stack.
+*/
+
+void QProgressDialog::setBar(QProgressBar *bar)
+{
+ Q_D(QProgressDialog);
+ if (!bar) {
+ qWarning("QProgressDialog::setBar: Cannot set a null progress bar");
+ return;
+ }
+#ifndef QT_NO_DEBUG
+ if (value() > 0)
+ qWarning("QProgressDialog::setBar: Cannot set a new progress bar "
+ "while the old one is active");
+#endif
+ delete d->bar;
+ d->bar = bar;
+ int w = qMax(isVisible() ? width() : 0, sizeHint().width());
+ int h = qMax(isVisible() ? height() : 0, sizeHint().height());
+ resize(w, h);
+}
+
+
+/*!
+ \property QProgressDialog::wasCanceled
+ \brief whether the dialog was canceled
+*/
+
+bool QProgressDialog::wasCanceled() const
+{
+ Q_D(const QProgressDialog);
+ return d->cancellation_flag;
+}
+
+
+/*!
+ \property QProgressDialog::maximum
+ \brief the highest value represented by the progress bar
+
+ The default is 0.
+
+ \sa minimum, setRange()
+*/
+
+int QProgressDialog::maximum() const
+{
+ Q_D(const QProgressDialog);
+ return d->bar->maximum();
+}
+
+void QProgressDialog::setMaximum(int maximum)
+{
+ Q_D(QProgressDialog);
+ d->bar->setMaximum(maximum);
+}
+
+/*!
+ \property QProgressDialog::minimum
+ \brief the lowest value represented by the progress bar
+
+ The default is 0.
+
+ \sa maximum, setRange()
+*/
+
+int QProgressDialog::minimum() const
+{
+ Q_D(const QProgressDialog);
+ return d->bar->minimum();
+}
+
+void QProgressDialog::setMinimum(int minimum)
+{
+ Q_D(QProgressDialog);
+ d->bar->setMinimum(minimum);
+}
+
+/*!
+ Sets the progress dialog's minimum and maximum values
+ to \a minimum and \a maximum, respectively.
+
+ If \a maximum is smaller than \a minimum, \a minimum becomes the only
+ legal value.
+
+ If the current value falls outside the new range, the progress
+ dialog is reset with reset().
+
+ \sa minimum, maximum
+*/
+void QProgressDialog::setRange(int minimum, int maximum)
+{
+ Q_D(QProgressDialog);
+ d->bar->setRange(minimum, maximum);
+}
+
+
+/*!
+ Resets the progress dialog.
+ The progress dialog becomes hidden if autoClose() is true.
+
+ \sa setAutoClose(), setAutoReset()
+*/
+
+void QProgressDialog::reset()
+{
+ Q_D(QProgressDialog);
+#ifndef QT_NO_CURSOR
+ if (value() >= 0) {
+ if (parentWidget())
+ parentWidget()->setCursor(d->parentCursor);
+ }
+#endif
+ if (d->autoClose || d->forceHide)
+ hide();
+ d->bar->reset();
+ d->cancellation_flag = false;
+ d->shown_once = false;
+ d->forceTimer->stop();
+
+ /*
+ I wish we could disconnect the user slot provided to open() here but
+ unfortunately reset() is usually called before the slot has been invoked.
+ (reset() is itself invoked when canceled() is emitted.)
+ */
+ if (d->receiverToDisconnectOnClose)
+ QMetaObject::invokeMethod(this, "_q_disconnectOnClose", Qt::QueuedConnection);
+}
+
+/*!
+ Resets the progress dialog. wasCanceled() becomes true until
+ the progress dialog is reset.
+ The progress dialog becomes hidden.
+*/
+
+void QProgressDialog::cancel()
+{
+ Q_D(QProgressDialog);
+ d->forceHide = true;
+ reset();
+ d->forceHide = false;
+ d->cancellation_flag = true;
+}
+
+
+int QProgressDialog::value() const
+{
+ Q_D(const QProgressDialog);
+ return d->bar->value();
+}
+
+/*!
+ \property QProgressDialog::value
+ \brief the current amount of progress made.
+
+ For the progress dialog to work as expected, you should initially set
+ this property to 0 and finally set it to
+ QProgressDialog::maximum(); you can call setValue() any number of times
+ in-between.
+
+ \warning If the progress dialog is modal
+ (see QProgressDialog::QProgressDialog()),
+ setValue() calls QApplication::processEvents(), so take care that
+ this does not cause undesirable re-entrancy in your code. For example,
+ don't use a QProgressDialog inside a paintEvent()!
+
+ \sa minimum, maximum
+*/
+void QProgressDialog::setValue(int progress)
+{
+ Q_D(QProgressDialog);
+ if (progress == d->bar->value()
+ || (d->bar->value() == -1 && progress == d->bar->maximum()))
+ return;
+
+ d->bar->setValue(progress);
+
+ if (d->shown_once) {
+ if (isModal())
+ QApplication::processEvents();
+ } else {
+ if (progress == 0) {
+ d->starttime.start();
+ d->forceTimer->start(d->showTime);
+ return;
+ } else {
+ bool need_show;
+ int elapsed = d->starttime.elapsed();
+ if (elapsed >= d->showTime) {
+ need_show = true;
+ } else {
+ if (elapsed > minWaitTime) {
+ int estimate;
+ int totalSteps = maximum() - minimum();
+ int myprogress = progress - minimum();
+ if ((totalSteps - myprogress) >= INT_MAX / elapsed)
+ estimate = (totalSteps - myprogress) / myprogress * elapsed;
+ else
+ estimate = elapsed * (totalSteps - myprogress) / myprogress;
+ need_show = estimate >= d->showTime;
+ } else {
+ need_show = false;
+ }
+ }
+ if (need_show) {
+ int w = qMax(isVisible() ? width() : 0, sizeHint().width());
+ int h = qMax(isVisible() ? height() : 0, sizeHint().height());
+ resize(w, h);
+ show();
+ d->shown_once = true;
+ }
+ }
+#ifdef Q_WS_MAC
+ QApplication::flush();
+#endif
+ }
+
+ if (progress == d->bar->maximum() && d->autoReset)
+ reset();
+}
+
+/*!
+ Returns a size that fits the contents of the progress dialog.
+ The progress dialog resizes itself as required, so you should not
+ need to call this yourself.
+*/
+
+QSize QProgressDialog::sizeHint() const
+{
+ Q_D(const QProgressDialog);
+ QSize sh = d->label ? d->label->sizeHint() : QSize(0, 0);
+ QSize bh = d->bar->sizeHint();
+ int margin = style()->pixelMetric(QStyle::PM_DefaultTopLevelMargin);
+ int spacing = style()->pixelMetric(QStyle::PM_DefaultLayoutSpacing);
+ int h = margin * 2 + bh.height() + sh.height() + spacing;
+ if (d->cancel)
+ h += d->cancel->sizeHint().height() + spacing;
+#ifdef Q_WS_S60
+ if (QApplication::desktop()->size().height() > QApplication::desktop()->size().width())
+ return QSize(qMax(QApplication::desktop()->size().width(), sh.width() + 2 * margin), h);
+ else
+ return QSize(qMax(QApplication::desktop()->size().height(), sh.width() + 2 * margin), h);
+#else
+ return QSize(qMax(200, sh.width() + 2 * margin), h);
+#endif
+}
+
+/*!\reimp
+*/
+void QProgressDialog::resizeEvent(QResizeEvent *)
+{
+ Q_D(QProgressDialog);
+ d->layout();
+}
+
+/*!
+ \reimp
+*/
+void QProgressDialog::changeEvent(QEvent *ev)
+{
+ Q_D(QProgressDialog);
+ if (ev->type() == QEvent::StyleChange) {
+ d->layout();
+ } else if (ev->type() == QEvent::LanguageChange) {
+ d->retranslateStrings();
+ }
+ QDialog::changeEvent(ev);
+}
+
+/*!
+ \property QProgressDialog::minimumDuration
+ \brief the time that must pass before the dialog appears
+
+ If the expected duration of the task is less than the
+ minimumDuration, the dialog will not appear at all. This prevents
+ the dialog popping up for tasks that are quickly over. For tasks
+ that are expected to exceed the minimumDuration, the dialog will
+ pop up after the minimumDuration time or as soon as any progress
+ is set.
+
+ If set to 0, the dialog is always shown as soon as any progress is
+ set. The default is 4000 milliseconds.
+*/
+void QProgressDialog::setMinimumDuration(int ms)
+{
+ Q_D(QProgressDialog);
+ d->showTime = ms;
+ if (d->bar->value() == 0) {
+ d->forceTimer->stop();
+ d->forceTimer->start(ms);
+ }
+}
+
+int QProgressDialog::minimumDuration() const
+{
+ Q_D(const QProgressDialog);
+ return d->showTime;
+}
+
+
+/*!
+ \reimp
+*/
+
+void QProgressDialog::closeEvent(QCloseEvent *e)
+{
+ emit canceled();
+ QDialog::closeEvent(e);
+}
+
+/*!
+ \property QProgressDialog::autoReset
+ \brief whether the progress dialog calls reset() as soon as value() equals maximum()
+
+ The default is true.
+
+ \sa setAutoClose()
+*/
+
+void QProgressDialog::setAutoReset(bool b)
+{
+ Q_D(QProgressDialog);
+ d->autoReset = b;
+}
+
+bool QProgressDialog::autoReset() const
+{
+ Q_D(const QProgressDialog);
+ return d->autoReset;
+}
+
+/*!
+ \property QProgressDialog::autoClose
+ \brief whether the dialog gets hidden by reset()
+
+ The default is true.
+
+ \sa setAutoReset()
+*/
+
+void QProgressDialog::setAutoClose(bool close)
+{
+ Q_D(QProgressDialog);
+ d->autoClose = close;
+}
+
+bool QProgressDialog::autoClose() const
+{
+ Q_D(const QProgressDialog);
+ return d->autoClose;
+}
+
+/*!
+ \reimp
+*/
+
+void QProgressDialog::showEvent(QShowEvent *e)
+{
+ Q_D(QProgressDialog);
+ QDialog::showEvent(e);
+ int w = qMax(isVisible() ? width() : 0, sizeHint().width());
+ int h = qMax(isVisible() ? height() : 0, sizeHint().height());
+ resize(w, h);
+ d->forceTimer->stop();
+}
+
+/*!
+ Shows the dialog if it is still hidden after the algorithm has been started
+ and minimumDuration milliseconds have passed.
+
+ \sa setMinimumDuration()
+*/
+
+void QProgressDialog::forceShow()
+{
+ Q_D(QProgressDialog);
+ d->forceTimer->stop();
+ if (d->shown_once || d->cancellation_flag)
+ return;
+
+ show();
+ d->shown_once = true;
+}
+
+/*!
+ \since 4.5
+ \overload
+
+ Opens the dialog and connects its accepted() signal to the slot specified
+ by \a receiver and \a member.
+
+ The signal will be disconnected from the slot when the dialog is closed.
+*/
+void QProgressDialog::open(QObject *receiver, const char *member)
+{
+ Q_D(QProgressDialog);
+ connect(this, SIGNAL(canceled()), receiver, member);
+ d->receiverToDisconnectOnClose = receiver;
+ d->memberToDisconnectOnClose = member;
+ QDialog::open();
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qprogressdialog.cpp"
+
+#endif // QT_NO_PROGRESSDIALOG
diff --git a/src/widgets/dialogs/qprogressdialog.h b/src/widgets/dialogs/qprogressdialog.h
new file mode 100644
index 0000000000..b981e5ef63
--- /dev/null
+++ b/src/widgets/dialogs/qprogressdialog.h
@@ -0,0 +1,145 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPROGRESSDIALOG_H
+#define QPROGRESSDIALOG_H
+
+#include <QtWidgets/qdialog.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_PROGRESSDIALOG
+
+class QPushButton;
+class QLabel;
+class QProgressBar;
+class QTimer;
+class QProgressDialogPrivate;
+
+class Q_WIDGETS_EXPORT QProgressDialog : public QDialog
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QProgressDialog)
+ Q_PROPERTY(bool wasCanceled READ wasCanceled)
+ Q_PROPERTY(int minimum READ minimum WRITE setMinimum)
+ Q_PROPERTY(int maximum READ maximum WRITE setMaximum)
+ Q_PROPERTY(int value READ value WRITE setValue)
+ Q_PROPERTY(bool autoReset READ autoReset WRITE setAutoReset)
+ Q_PROPERTY(bool autoClose READ autoClose WRITE setAutoClose)
+ Q_PROPERTY(int minimumDuration READ minimumDuration WRITE setMinimumDuration)
+ Q_PROPERTY(QString labelText READ labelText WRITE setLabelText)
+
+public:
+ explicit QProgressDialog(QWidget *parent = 0, Qt::WindowFlags flags = 0);
+ QProgressDialog(const QString &labelText, const QString &cancelButtonText,
+ int minimum, int maximum, QWidget *parent = 0, Qt::WindowFlags flags = 0);
+ ~QProgressDialog();
+
+ void setLabel(QLabel *label);
+ void setCancelButton(QPushButton *button);
+ void setBar(QProgressBar *bar);
+
+ bool wasCanceled() const;
+
+ int minimum() const;
+ int maximum() const;
+
+ int value() const;
+
+ QSize sizeHint() const;
+
+ QString labelText() const;
+ int minimumDuration() const;
+
+ void setAutoReset(bool reset);
+ bool autoReset() const;
+ void setAutoClose(bool close);
+ bool autoClose() const;
+
+#ifdef Q_NO_USING_KEYWORD
+#ifndef Q_QDOC
+ void open() { QDialog::open(); }
+#endif
+#else
+ using QDialog::open;
+#endif
+ void open(QObject *receiver, const char *member);
+
+public Q_SLOTS:
+ void cancel();
+ void reset();
+ void setMaximum(int maximum);
+ void setMinimum(int minimum);
+ void setRange(int minimum, int maximum);
+ void setValue(int progress);
+ void setLabelText(const QString &text);
+ void setCancelButtonText(const QString &text);
+ void setMinimumDuration(int ms);
+
+Q_SIGNALS:
+ void canceled();
+
+protected:
+ void resizeEvent(QResizeEvent *event);
+ void closeEvent(QCloseEvent *event);
+ void changeEvent(QEvent *event);
+ void showEvent(QShowEvent *event);
+
+protected Q_SLOTS:
+ void forceShow();
+
+private:
+ Q_DISABLE_COPY(QProgressDialog)
+
+ Q_PRIVATE_SLOT(d_func(), void _q_disconnectOnClose())
+};
+
+#endif // QT_NO_PROGRESSDIALOG
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QPROGRESSDIALOG_H
diff --git a/src/gui/dialogs/qsidebar.cpp b/src/widgets/dialogs/qsidebar.cpp
index 8efbb8dfcd..8efbb8dfcd 100644
--- a/src/gui/dialogs/qsidebar.cpp
+++ b/src/widgets/dialogs/qsidebar.cpp
diff --git a/src/gui/dialogs/qsidebar_p.h b/src/widgets/dialogs/qsidebar_p.h
index 6ad2716780..6ad2716780 100644
--- a/src/gui/dialogs/qsidebar_p.h
+++ b/src/widgets/dialogs/qsidebar_p.h
diff --git a/src/gui/dialogs/qwizard.cpp b/src/widgets/dialogs/qwizard.cpp
index 83bdaa0e55..83bdaa0e55 100644
--- a/src/gui/dialogs/qwizard.cpp
+++ b/src/widgets/dialogs/qwizard.cpp
diff --git a/src/widgets/dialogs/qwizard.h b/src/widgets/dialogs/qwizard.h
new file mode 100644
index 0000000000..77eef53037
--- /dev/null
+++ b/src/widgets/dialogs/qwizard.h
@@ -0,0 +1,268 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWIZARD_H
+#define QWIZARD_H
+
+#include <QtWidgets/qdialog.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_WIZARD
+
+class QAbstractButton;
+class QWizardPage;
+class QWizardPrivate;
+
+class Q_WIDGETS_EXPORT QWizard : public QDialog
+{
+ Q_OBJECT
+ Q_ENUMS(WizardStyle WizardOption)
+ Q_FLAGS(WizardOptions)
+ Q_PROPERTY(WizardStyle wizardStyle READ wizardStyle WRITE setWizardStyle)
+ Q_PROPERTY(WizardOptions options READ options WRITE setOptions)
+ Q_PROPERTY(Qt::TextFormat titleFormat READ titleFormat WRITE setTitleFormat)
+ Q_PROPERTY(Qt::TextFormat subTitleFormat READ subTitleFormat WRITE setSubTitleFormat)
+ Q_PROPERTY(int startId READ startId WRITE setStartId)
+ Q_PROPERTY(int currentId READ currentId NOTIFY currentIdChanged)
+
+public:
+ enum WizardButton {
+ BackButton,
+ NextButton,
+ CommitButton,
+ FinishButton,
+ CancelButton,
+ HelpButton,
+ CustomButton1,
+ CustomButton2,
+ CustomButton3,
+ Stretch,
+
+ NoButton = -1,
+ NStandardButtons = 6,
+ NButtons = 9
+ };
+
+ enum WizardPixmap {
+ WatermarkPixmap,
+ LogoPixmap,
+ BannerPixmap,
+ BackgroundPixmap,
+ NPixmaps
+ };
+
+ enum WizardStyle {
+ ClassicStyle,
+ ModernStyle,
+ MacStyle,
+ AeroStyle,
+ NStyles
+ };
+
+ enum WizardOption {
+ IndependentPages = 0x00000001,
+ IgnoreSubTitles = 0x00000002,
+ ExtendedWatermarkPixmap = 0x00000004,
+ NoDefaultButton = 0x00000008,
+ NoBackButtonOnStartPage = 0x00000010,
+ NoBackButtonOnLastPage = 0x00000020,
+ DisabledBackButtonOnLastPage = 0x00000040,
+ HaveNextButtonOnLastPage = 0x00000080,
+ HaveFinishButtonOnEarlyPages = 0x00000100,
+ NoCancelButton = 0x00000200,
+ CancelButtonOnLeft = 0x00000400,
+ HaveHelpButton = 0x00000800,
+ HelpButtonOnRight = 0x00001000,
+ HaveCustomButton1 = 0x00002000,
+ HaveCustomButton2 = 0x00004000,
+ HaveCustomButton3 = 0x00008000
+ };
+
+ Q_DECLARE_FLAGS(WizardOptions, WizardOption)
+
+ explicit QWizard(QWidget *parent = 0, Qt::WindowFlags flags = 0);
+ ~QWizard();
+
+ int addPage(QWizardPage *page);
+ void setPage(int id, QWizardPage *page);
+ void removePage(int id);
+ QWizardPage *page(int id) const;
+ bool hasVisitedPage(int id) const;
+ QList<int> visitedPages() const; // ### visitedIds()?
+ QList<int> pageIds() const;
+ void setStartId(int id);
+ int startId() const;
+ QWizardPage *currentPage() const;
+ int currentId() const;
+
+ virtual bool validateCurrentPage();
+ virtual int nextId() const;
+
+ void setField(const QString &name, const QVariant &value);
+ QVariant field(const QString &name) const;
+
+ void setWizardStyle(WizardStyle style);
+ WizardStyle wizardStyle() const;
+
+ void setOption(WizardOption option, bool on = true);
+ bool testOption(WizardOption option) const;
+ void setOptions(WizardOptions options);
+ WizardOptions options() const;
+
+ void setButtonText(WizardButton which, const QString &text);
+ QString buttonText(WizardButton which) const;
+ void setButtonLayout(const QList<WizardButton> &layout);
+ void setButton(WizardButton which, QAbstractButton *button);
+ QAbstractButton *button(WizardButton which) const;
+
+ void setTitleFormat(Qt::TextFormat format);
+ Qt::TextFormat titleFormat() const;
+ void setSubTitleFormat(Qt::TextFormat format);
+ Qt::TextFormat subTitleFormat() const;
+ void setPixmap(WizardPixmap which, const QPixmap &pixmap);
+ QPixmap pixmap(WizardPixmap which) const;
+
+ void setSideWidget(QWidget *widget);
+ QWidget *sideWidget() const;
+
+ void setDefaultProperty(const char *className, const char *property,
+ const char *changedSignal);
+
+ void setVisible(bool visible);
+ QSize sizeHint() const;
+
+Q_SIGNALS:
+ void currentIdChanged(int id);
+ void helpRequested();
+ void customButtonClicked(int which);
+ void pageAdded(int id);
+ void pageRemoved(int id);
+
+public Q_SLOTS:
+ void back();
+ void next();
+ void restart();
+
+protected:
+ bool event(QEvent *event);
+ void resizeEvent(QResizeEvent *event);
+ void paintEvent(QPaintEvent *event);
+#if defined(Q_WS_WIN)
+ bool winEvent(MSG * message, long * result);
+#endif
+ void done(int result);
+ virtual void initializePage(int id);
+ virtual void cleanupPage(int id);
+
+private:
+ Q_DISABLE_COPY(QWizard)
+ Q_DECLARE_PRIVATE(QWizard)
+ Q_PRIVATE_SLOT(d_func(), void _q_emitCustomButtonClicked())
+ Q_PRIVATE_SLOT(d_func(), void _q_updateButtonStates())
+ Q_PRIVATE_SLOT(d_func(), void _q_handleFieldObjectDestroyed(QObject *))
+
+ friend class QWizardPage;
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QWizard::WizardOptions)
+
+class QWizardPagePrivate;
+
+class Q_WIDGETS_EXPORT QWizardPage : public QWidget
+{
+ Q_OBJECT
+ Q_PROPERTY(QString title READ title WRITE setTitle)
+ Q_PROPERTY(QString subTitle READ subTitle WRITE setSubTitle)
+
+public:
+ QWizardPage(QWidget *parent = 0);
+
+ void setTitle(const QString &title);
+ QString title() const;
+ void setSubTitle(const QString &subTitle);
+ QString subTitle() const;
+ void setPixmap(QWizard::WizardPixmap which, const QPixmap &pixmap);
+ QPixmap pixmap(QWizard::WizardPixmap which) const;
+ void setFinalPage(bool finalPage);
+ bool isFinalPage() const;
+ void setCommitPage(bool commitPage);
+ bool isCommitPage() const;
+ void setButtonText(QWizard::WizardButton which, const QString &text);
+ QString buttonText(QWizard::WizardButton which) const;
+
+ virtual void initializePage();
+ virtual void cleanupPage();
+ virtual bool validatePage();
+ virtual bool isComplete() const;
+ virtual int nextId() const;
+
+Q_SIGNALS:
+ void completeChanged();
+
+protected:
+ void setField(const QString &name, const QVariant &value);
+ QVariant field(const QString &name) const;
+ void registerField(const QString &name, QWidget *widget, const char *property = 0,
+ const char *changedSignal = 0);
+ QWizard *wizard() const;
+
+private:
+ Q_DISABLE_COPY(QWizardPage)
+ Q_DECLARE_PRIVATE(QWizardPage)
+ Q_PRIVATE_SLOT(d_func(), void _q_maybeEmitCompleteChanged())
+ Q_PRIVATE_SLOT(d_func(), void _q_updateCachedCompleteState())
+
+ friend class QWizard;
+ friend class QWizardPrivate;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QT_NO_WIZARD
+
+#endif // QWIZARD_H
diff --git a/src/widgets/dialogs/qwizard_win.cpp b/src/widgets/dialogs/qwizard_win.cpp
new file mode 100644
index 0000000000..6177700d8c
--- /dev/null
+++ b/src/widgets/dialogs/qwizard_win.cpp
@@ -0,0 +1,773 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT_NO_WIZARD
+#ifndef QT_NO_STYLE_WINDOWSVISTA
+
+#include "qwizard_win_p.h"
+#include <private/qsystemlibrary_p.h>
+#include <private/qapplication_p.h>
+#include "qplatformnativeinterface_qpa.h"
+#include "qwizard.h"
+#include "qpaintengine.h"
+#include "qapplication.h"
+#include <QtGui/QMouseEvent>
+#include <QtWidgets/QDesktopWidget>
+
+// Note, these tests are duplicates in qwindowsxpstyle_p.h.
+#ifdef Q_CC_GNU
+# include <w32api.h>
+# if (__W32API_MAJOR_VERSION >= 3 || (__W32API_MAJOR_VERSION == 2 && __W32API_MINOR_VERSION >= 5))
+# ifdef _WIN32_WINNT
+# undef _WIN32_WINNT
+# endif
+# define _WIN32_WINNT 0x0501
+# include <commctrl.h>
+# endif
+#endif
+
+#include <uxtheme.h>
+
+QT_BEGIN_NAMESPACE
+
+//DWM related
+typedef struct { //MARGINS
+ int cxLeftWidth; // width of left border that retains its size
+ int cxRightWidth; // width of right border that retains its size
+ int cyTopHeight; // height of top border that retains its size
+ int cyBottomHeight; // height of bottom border that retains its size
+} WIZ_MARGINS;
+typedef struct { //DTTOPTS
+ DWORD dwSize;
+ DWORD dwFlags;
+ COLORREF crText;
+ COLORREF crBorder;
+ COLORREF crShadow;
+ int eTextShadowType;
+ POINT ptShadowOffset;
+ int iBorderSize;
+ int iFontPropId;
+ int iColorPropId;
+ int iStateId;
+ BOOL fApplyOverlay;
+ int iGlowSize;
+} WIZ_DTTOPTS;
+
+typedef struct {
+ DWORD dwFlags;
+ DWORD dwMask;
+} WIZ_WTA_OPTIONS;
+
+#define WIZ_WM_THEMECHANGED 0x031A
+#define WIZ_WM_DWMCOMPOSITIONCHANGED 0x031E
+
+enum WIZ_WINDOWTHEMEATTRIBUTETYPE {
+ WIZ_WTA_NONCLIENT = 1
+};
+
+#define WIZ_WTNCA_NODRAWCAPTION 0x00000001
+#define WIZ_WTNCA_NODRAWICON 0x00000002
+
+#define WIZ_DT_CENTER 0x00000001 //DT_CENTER
+#define WIZ_DT_VCENTER 0x00000004
+#define WIZ_DT_SINGLELINE 0x00000020
+#define WIZ_DT_NOPREFIX 0x00000800
+
+enum WIZ_NAVIGATIONPARTS { //NAVIGATIONPARTS
+ WIZ_NAV_BACKBUTTON = 1,
+ WIZ_NAV_FORWARDBUTTON = 2,
+ WIZ_NAV_MENUBUTTON = 3,
+};
+
+enum WIZ_NAV_BACKBUTTONSTATES { //NAV_BACKBUTTONSTATES
+ WIZ_NAV_BB_NORMAL = 1,
+ WIZ_NAV_BB_HOT = 2,
+ WIZ_NAV_BB_PRESSED = 3,
+ WIZ_NAV_BB_DISABLED = 4,
+};
+
+#define WIZ_TMT_CAPTIONFONT (801) //TMT_CAPTIONFONT
+#define WIZ_DTT_COMPOSITED (1UL << 13) //DTT_COMPOSITED
+#define WIZ_DTT_GLOWSIZE (1UL << 11) //DTT_GLOWSIZE
+
+#define WIZ_WM_NCMOUSELEAVE 674 //WM_NCMOUSELEAVE
+
+#define WIZ_WP_CAPTION 1 //WP_CAPTION
+#define WIZ_CS_ACTIVE 1 //CS_ACTIVE
+#define WIZ_TMT_FILLCOLORHINT 3821 //TMT_FILLCOLORHINT
+#define WIZ_TMT_BORDERCOLORHINT 3822 //TMT_BORDERCOLORHINT
+
+typedef BOOL (WINAPI *PtrDwmDefWindowProc)(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, LRESULT *plResult);
+typedef HRESULT (WINAPI *PtrDwmIsCompositionEnabled)(BOOL* pfEnabled);
+typedef HRESULT (WINAPI *PtrDwmExtendFrameIntoClientArea)(HWND hWnd, const WIZ_MARGINS* pMarInset);
+typedef HRESULT (WINAPI *PtrSetWindowThemeAttribute)(HWND hwnd, enum WIZ_WINDOWTHEMEATTRIBUTETYPE eAttribute, PVOID pvAttribute, DWORD cbAttribute);
+
+static PtrDwmDefWindowProc pDwmDefWindowProc = 0;
+static PtrDwmIsCompositionEnabled pDwmIsCompositionEnabled = 0;
+static PtrDwmExtendFrameIntoClientArea pDwmExtendFrameIntoClientArea = 0;
+static PtrSetWindowThemeAttribute pSetWindowThemeAttribute = 0;
+
+//Theme related
+typedef bool (WINAPI *PtrIsAppThemed)();
+typedef bool (WINAPI *PtrIsThemeActive)();
+typedef HANDLE (WINAPI *PtrOpenThemeData)(HWND hwnd, LPCWSTR pszClassList);
+typedef HRESULT (WINAPI *PtrCloseThemeData)(HANDLE hTheme);
+typedef HRESULT (WINAPI *PtrGetThemeSysFont)(HANDLE hTheme, int iFontId, LOGFONTW *plf);
+typedef HRESULT (WINAPI *PtrDrawThemeTextEx)(HANDLE hTheme, HDC hdc, int iPartId, int iStateId, LPCWSTR pszText, int cchText, DWORD dwTextFlags, LPRECT pRect, const WIZ_DTTOPTS *pOptions);
+typedef HRESULT (WINAPI *PtrDrawThemeBackground)(HANDLE hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, OPTIONAL const RECT *pClipRect);
+typedef HRESULT (WINAPI *PtrGetThemePartSize)(HANDLE hTheme, HDC hdc, int iPartId, int iStateId, OPTIONAL RECT *prc, enum THEMESIZE eSize, OUT SIZE *psz);
+typedef HRESULT (WINAPI *PtrGetThemeColor)(HANDLE hTheme, int iPartId, int iStateId, int iPropId, OUT COLORREF *pColor);
+
+static PtrIsAppThemed pIsAppThemed = 0;
+static PtrIsThemeActive pIsThemeActive = 0;
+static PtrOpenThemeData pOpenThemeData = 0;
+static PtrCloseThemeData pCloseThemeData = 0;
+static PtrGetThemeSysFont pGetThemeSysFont = 0;
+static PtrDrawThemeTextEx pDrawThemeTextEx = 0;
+static PtrDrawThemeBackground pDrawThemeBackground = 0;
+static PtrGetThemePartSize pGetThemePartSize = 0;
+static PtrGetThemeColor pGetThemeColor = 0;
+
+bool QVistaHelper::is_vista = false;
+QVistaHelper::VistaState QVistaHelper::cachedVistaState = QVistaHelper::Dirty;
+
+/******************************************************************************
+** QVistaBackButton
+*/
+
+QVistaBackButton::QVistaBackButton(QWidget *widget)
+ : QAbstractButton(widget)
+{
+ setFocusPolicy(Qt::NoFocus);
+}
+
+QSize QVistaBackButton::sizeHint() const
+{
+ ensurePolished();
+ int size = int(QStyleHelper::dpiScaled(32));
+ int width = size, height = size;
+/*
+ HANDLE theme = pOpenThemeData(0, L"Navigation");
+ SIZE size;
+ if (pGetThemePartSize(theme, 0, WIZ_NAV_BACKBUTTON, WIZ_NAV_BB_NORMAL, 0, TS_TRUE, &size) == S_OK) {
+ width = size.cx;
+ height = size.cy;
+ }
+*/
+ return QSize(width, height);
+}
+
+void QVistaBackButton::enterEvent(QEvent *event)
+{
+ if (isEnabled())
+ update();
+ QAbstractButton::enterEvent(event);
+}
+
+void QVistaBackButton::leaveEvent(QEvent *event)
+{
+ if (isEnabled())
+ update();
+ QAbstractButton::leaveEvent(event);
+}
+
+void QVistaBackButton::paintEvent(QPaintEvent *)
+{
+ QPainter p(this);
+ QRect r = rect();
+ HANDLE theme = pOpenThemeData(0, L"Navigation");
+ //RECT rect;
+ RECT clipRect;
+ int xoffset = QWidget::mapToParent(r.topLeft()).x() - 1;
+ int yoffset = QWidget::mapToParent(r.topLeft()).y() - 1;
+
+ clipRect.top = r.top() + yoffset;
+ clipRect.bottom = r.bottom() + yoffset;
+ clipRect.left = r.left() + xoffset;
+ clipRect.right = r.right() + xoffset;
+
+ int state = WIZ_NAV_BB_NORMAL;
+ if (!isEnabled())
+ state = WIZ_NAV_BB_DISABLED;
+ else if (isDown())
+ state = WIZ_NAV_BB_PRESSED;
+ else if (underMouse())
+ state = WIZ_NAV_BB_HOT;
+
+ QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface();
+ HDC hdc = static_cast<HDC>(nativeInterface->nativeResourceForBackingStore("getDC", backingStore()));
+ pDrawThemeBackground(theme, hdc, WIZ_NAV_BACKBUTTON, state, &clipRect, &clipRect);
+}
+
+/******************************************************************************
+** QVistaHelper
+*/
+
+QVistaHelper::QVistaHelper(QWizard *wizard)
+ : QObject(wizard)
+ , pressed(false)
+ , wizard(wizard)
+ , backButton_(0)
+{
+ is_vista = resolveSymbols();
+ if (is_vista)
+ backButton_ = new QVistaBackButton(wizard);
+
+ // Handle diff between Windows 7 and Vista
+ iconSpacing = QStyleHelper::dpiScaled(7);
+ textSpacing = QSysInfo::WindowsVersion >= QSysInfo::WV_WINDOWS7 ?
+ iconSpacing : QStyleHelper::dpiScaled(20);
+}
+
+QVistaHelper::~QVistaHelper()
+{
+}
+
+bool QVistaHelper::isCompositionEnabled()
+{
+ bool value = is_vista;
+ if (is_vista) {
+ HRESULT hr;
+ BOOL bEnabled;
+
+ hr = pDwmIsCompositionEnabled(&bEnabled);
+ value = (SUCCEEDED(hr) && bEnabled);
+ }
+ return value;
+}
+
+bool QVistaHelper::isThemeActive()
+{
+ return is_vista && pIsThemeActive();
+}
+
+QVistaHelper::VistaState QVistaHelper::vistaState()
+{
+ if (cachedVistaState == Dirty)
+ cachedVistaState =
+ isCompositionEnabled() ? VistaAero : isThemeActive() ? VistaBasic : Classic;
+ return cachedVistaState;
+}
+
+QColor QVistaHelper::basicWindowFrameColor()
+{
+ DWORD rgb;
+ HWND handle = QApplicationPrivate::getHWNDForWidget(QApplication::desktop());
+ HANDLE hTheme = pOpenThemeData(handle, L"WINDOW");
+ pGetThemeColor(
+ hTheme, WIZ_WP_CAPTION, WIZ_CS_ACTIVE,
+ wizard->isActiveWindow() ? WIZ_TMT_FILLCOLORHINT : WIZ_TMT_BORDERCOLORHINT,
+ &rgb);
+ BYTE r = GetRValue(rgb);
+ BYTE g = GetGValue(rgb);
+ BYTE b = GetBValue(rgb);
+ return QColor(r, g, b);
+}
+
+bool QVistaHelper::setDWMTitleBar(TitleBarChangeType type)
+{
+ bool value = false;
+ if (vistaState() == VistaAero) {
+ WIZ_MARGINS mar = {0};
+ if (type == NormalTitleBar)
+ mar.cyTopHeight = 0;
+ else
+ mar.cyTopHeight = titleBarSize() + topOffset();
+ HWND wizardHandle = QApplicationPrivate::getHWNDForWidget(wizard);
+ HRESULT hr = pDwmExtendFrameIntoClientArea(wizardHandle, &mar);
+ value = SUCCEEDED(hr);
+ }
+ return value;
+}
+
+void QVistaHelper::drawTitleBar(QPainter *painter)
+{
+ Q_ASSERT(backButton_);
+ QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface();
+ QBackingStore *backingStore = backButton_->backingStore();
+ HDC hdc = static_cast<HDC>(nativeInterface->nativeResourceForBackingStore("getDC", backingStore));
+
+ if (vistaState() == VistaAero)
+ drawBlackRect(QRect(0, 0, wizard->width(),
+ titleBarSize() + topOffset()), hdc);
+ const int btnTop = backButton_->mapToParent(QPoint()).y();
+ const int btnHeight = backButton_->size().height();
+ const int verticalCenter = (btnTop + btnHeight / 2) - 1;
+
+ const QString text = wizard->window()->windowTitle();
+ const QFont font = QApplication::font("QWorkspaceTitleBar");
+ const QFontMetrics fontMetrics(font);
+ const QRect brect = fontMetrics.boundingRect(text);
+ int textHeight = brect.height();
+ int textWidth = brect.width();
+ int glowOffset = 0;
+
+ if (vistaState() == VistaAero) {
+ textHeight += 2 * glowSize();
+ textWidth += 2 * glowSize();
+ glowOffset = glowSize();
+ }
+
+ drawTitleText(
+ painter, text,
+ QRect(titleOffset() - glowOffset, verticalCenter - textHeight / 2, textWidth, textHeight),
+ hdc);
+
+ if (!wizard->windowIcon().isNull()) {
+ QRect rect(leftMargin(), verticalCenter - iconSize() / 2, iconSize(), iconSize());
+ HICON hIcon = 0; //###FIXME wizard->windowIcon().pixmap(iconSize()).toWinHICON();
+ DrawIconEx(hdc, rect.left(), rect.top(), hIcon, 0, 0, 0, NULL, DI_NORMAL | DI_COMPAT);
+ DestroyIcon(hIcon);
+ }
+}
+
+void QVistaHelper::setTitleBarIconAndCaptionVisible(bool visible)
+{
+ if (is_vista) {
+ WIZ_WTA_OPTIONS opt;
+ opt.dwFlags = WIZ_WTNCA_NODRAWICON | WIZ_WTNCA_NODRAWCAPTION;
+ if (visible)
+ opt.dwMask = 0;
+ else
+ opt.dwMask = WIZ_WTNCA_NODRAWICON | WIZ_WTNCA_NODRAWCAPTION;
+ HWND handle = QApplicationPrivate::getHWNDForWidget(wizard);
+ pSetWindowThemeAttribute(handle, WIZ_WTA_NONCLIENT, &opt, sizeof(WIZ_WTA_OPTIONS));
+ }
+}
+
+bool QVistaHelper::winEvent(MSG* msg, long* result)
+{
+ bool retval = true;
+
+ switch (msg->message) {
+ case WM_NCHITTEST: {
+ LRESULT lResult;
+ pDwmDefWindowProc(msg->hwnd, msg->message, msg->wParam, msg->lParam, &lResult);
+ if (lResult == HTCLOSE || lResult == HTMAXBUTTON || lResult == HTMINBUTTON || lResult == HTHELP)
+ *result = lResult;
+ else
+ *result = DefWindowProc(msg->hwnd, msg->message, msg->wParam, msg->lParam);
+ break;
+ }
+ case WM_NCMOUSEMOVE:
+ case WM_NCLBUTTONDOWN:
+ case WM_NCLBUTTONUP:
+ case WIZ_WM_NCMOUSELEAVE: {
+ LRESULT lResult;
+ pDwmDefWindowProc(msg->hwnd, msg->message, msg->wParam, msg->lParam, &lResult);
+ *result = DefWindowProc(msg->hwnd, msg->message, msg->wParam, msg->lParam);
+ break;
+ }
+ case WM_NCCALCSIZE: {
+ NCCALCSIZE_PARAMS* lpncsp = (NCCALCSIZE_PARAMS*)msg->lParam;
+ *result = DefWindowProc(msg->hwnd, msg->message, msg->wParam, msg->lParam);
+ lpncsp->rgrc[0].top -= (vistaState() == VistaAero ? titleBarSize() : 0);
+ break;
+ }
+ default:
+ retval = false;
+ }
+
+ return retval;
+}
+
+void QVistaHelper::setMouseCursor(QPoint pos)
+{
+#ifndef QT_NO_CURSOR
+ if (rtTop.contains(pos))
+ wizard->setCursor(Qt::SizeVerCursor);
+ else
+ wizard->setCursor(Qt::ArrowCursor);
+#endif
+}
+
+void QVistaHelper::mouseEvent(QEvent *event)
+{
+ switch (event->type()) {
+ case QEvent::MouseMove:
+ mouseMoveEvent(static_cast<QMouseEvent *>(event));
+ break;
+ case QEvent::MouseButtonPress:
+ mousePressEvent(static_cast<QMouseEvent *>(event));
+ break;
+ case QEvent::MouseButtonRelease:
+ mouseReleaseEvent(static_cast<QMouseEvent *>(event));
+ break;
+ default:
+ break;
+ }
+}
+
+// The following hack ensures that the titlebar is updated correctly
+// when the wizard style changes to and from AeroStyle. Specifically,
+// this function causes a Windows message of type WM_NCCALCSIZE to
+// be triggered.
+void QVistaHelper::setWindowPosHack()
+{
+ const int x = wizard->geometry().x(); // ignored by SWP_NOMOVE
+ const int y = wizard->geometry().y(); // ignored by SWP_NOMOVE
+ const int w = wizard->width();
+ const int h = wizard->height();
+ HWND handle = QApplicationPrivate::getHWNDForWidget(wizard);
+ SetWindowPos(handle, 0, x, y, w, h, SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED);
+}
+
+// The following hack allows any QWidget subclass to access
+// QWidgetPrivate::topData() without being declared as a
+// friend by QWidget.
+class QHackWidget : public QWidget
+{
+public:
+ Q_DECLARE_PRIVATE(QWidget)
+ QTLWExtra* topData() { return d_func()->topData(); }
+};
+
+void QVistaHelper::collapseTopFrameStrut()
+{
+ QTLWExtra *top = ((QHackWidget *)wizard)->d_func()->topData();
+ int x1, y1, x2, y2;
+ top->frameStrut.getCoords(&x1, &y1, &x2, &y2);
+ top->frameStrut.setCoords(x1, 0, x2, y2);
+}
+
+bool QVistaHelper::handleWinEvent(MSG *message, long *result)
+{
+ if (message->message == WIZ_WM_THEMECHANGED || message->message == WIZ_WM_DWMCOMPOSITIONCHANGED)
+ cachedVistaState = Dirty;
+
+ bool status = false;
+ if (wizard->wizardStyle() == QWizard::AeroStyle && vistaState() == VistaAero) {
+ status = winEvent(message, result);
+ if (message->message == WM_NCCALCSIZE) {
+ if (status)
+ collapseTopFrameStrut();
+ } else if (message->message == WM_NCPAINT) {
+ wizard->update();
+ }
+ }
+ return status;
+}
+
+void QVistaHelper::resizeEvent(QResizeEvent * event)
+{
+ Q_UNUSED(event);
+ rtTop = QRect (0, 0, wizard->width(), frameSize());
+ int height = captionSize() + topOffset();
+ if (vistaState() == VistaBasic)
+ height -= titleBarSize();
+ rtTitle = QRect (0, frameSize(), wizard->width(), height);
+}
+
+void QVistaHelper::paintEvent(QPaintEvent *event)
+{
+ Q_UNUSED(event);
+ QPainter painter(wizard);
+ drawTitleBar(&painter);
+}
+
+void QVistaHelper::mouseMoveEvent(QMouseEvent *event)
+{
+ if (wizard->windowState() & Qt::WindowMaximized) {
+ event->ignore();
+ return;
+ }
+
+ QRect rect = wizard->geometry();
+ if (pressed) {
+ switch (change) {
+ case resizeTop:
+ {
+ const int dy = event->pos().y() - pressedPos.y();
+ if ((dy > 0 && rect.height() > wizard->minimumHeight())
+ || (dy < 0 && rect.height() < wizard->maximumHeight()))
+ rect.setTop(rect.top() + dy);
+ }
+ break;
+ case movePosition: {
+ QPoint newPos = event->pos() - pressedPos;
+ rect.moveLeft(rect.left() + newPos.x());
+ rect.moveTop(rect.top() + newPos.y());
+ break; }
+ default:
+ break;
+ }
+ wizard->setGeometry(rect);
+
+ } else if (vistaState() == VistaAero) {
+ setMouseCursor(event->pos());
+ }
+ event->ignore();
+}
+
+void QVistaHelper::mousePressEvent(QMouseEvent *event)
+{
+ change = noChange;
+
+ if (wizard->windowState() & Qt::WindowMaximized) {
+ event->ignore();
+ return;
+ }
+
+ if (rtTitle.contains(event->pos())) {
+ change = movePosition;
+ } else if (rtTop.contains(event->pos()))
+ change = (vistaState() == VistaAero) ? resizeTop : movePosition;
+
+ if (change != noChange) {
+ if (vistaState() == VistaAero)
+ setMouseCursor(event->pos());
+ pressed = true;
+ pressedPos = event->pos();
+ } else {
+ event->ignore();
+ }
+}
+
+void QVistaHelper::mouseReleaseEvent(QMouseEvent *event)
+{
+ change = noChange;
+ if (pressed) {
+ pressed = false;
+ wizard->releaseMouse();
+ if (vistaState() == VistaAero)
+ setMouseCursor(event->pos());
+ }
+ event->ignore();
+}
+
+bool QVistaHelper::eventFilter(QObject *obj, QEvent *event)
+{
+ if (obj != wizard)
+ return QObject::eventFilter(obj, event);
+
+ if (event->type() == QEvent::MouseMove) {
+ QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
+ long result;
+ MSG msg;
+ msg.message = WM_NCHITTEST;
+ msg.wParam = 0;
+ msg.lParam = MAKELPARAM(mouseEvent->globalX(), mouseEvent->globalY());
+ HWND handle = QApplicationPrivate::getHWNDForWidget(wizard);
+ msg.hwnd = handle;
+ winEvent(&msg, &result);
+ msg.wParam = result;
+ msg.message = WM_NCMOUSEMOVE;
+ winEvent(&msg, &result);
+ } else if (event->type() == QEvent::MouseButtonPress) {
+ QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
+ long result;
+ MSG msg;
+ msg.message = WM_NCHITTEST;
+ msg.wParam = 0;
+ msg.lParam = MAKELPARAM(mouseEvent->globalX(), mouseEvent->globalY());
+ HWND handle = QApplicationPrivate::getHWNDForWidget(wizard);
+ msg.hwnd = handle;
+ winEvent(&msg, &result);
+ msg.wParam = result;
+ msg.message = WM_NCLBUTTONDOWN;
+ winEvent(&msg, &result);
+ } else if (event->type() == QEvent::MouseButtonRelease) {
+ QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
+ long result;
+ MSG msg;
+ msg.message = WM_NCHITTEST;
+ msg.wParam = 0;
+ msg.lParam = MAKELPARAM(mouseEvent->globalX(), mouseEvent->globalY());
+ HWND handle = QApplicationPrivate::getHWNDForWidget(wizard);
+ msg.hwnd = handle;
+ winEvent(&msg, &result);
+ msg.wParam = result;
+ msg.message = WM_NCLBUTTONUP;
+ winEvent(&msg, &result);
+ }
+
+ return false;
+}
+
+HFONT QVistaHelper::getCaptionFont(HANDLE hTheme)
+{
+ LOGFONT lf = {0};
+
+ if (!hTheme)
+ pGetThemeSysFont(hTheme, WIZ_TMT_CAPTIONFONT, &lf);
+ else
+ {
+ NONCLIENTMETRICS ncm = {sizeof(NONCLIENTMETRICS)};
+ SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, false);
+ lf = ncm.lfMessageFont;
+ }
+ return CreateFontIndirect(&lf);
+}
+
+bool QVistaHelper::drawTitleText(QPainter *painter, const QString &text, const QRect &rect, HDC hdc)
+{
+ bool value = false;
+ if (vistaState() == VistaAero) {
+ HWND handle = QApplicationPrivate::getHWNDForWidget(QApplication::desktop());
+ HANDLE hTheme = pOpenThemeData(handle, L"WINDOW");
+ if (!hTheme) return false;
+ // Set up a memory DC and bitmap that we'll draw into
+ HDC dcMem;
+ HBITMAP bmp;
+ BITMAPINFO dib = {{0}};
+ dcMem = CreateCompatibleDC(hdc);
+
+ dib.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ dib.bmiHeader.biWidth = rect.width();
+ dib.bmiHeader.biHeight = -rect.height();
+ dib.bmiHeader.biPlanes = 1;
+ dib.bmiHeader.biBitCount = 32;
+ dib.bmiHeader.biCompression = BI_RGB;
+
+ bmp = CreateDIBSection(hdc, &dib, DIB_RGB_COLORS, NULL, NULL, 0);
+
+ // Set up the DC
+ HFONT hCaptionFont = getCaptionFont(hTheme);
+ HBITMAP hOldBmp = (HBITMAP)SelectObject(dcMem, (HGDIOBJ) bmp);
+ HFONT hOldFont = (HFONT)SelectObject(dcMem, (HGDIOBJ) hCaptionFont);
+
+ // Draw the text!
+ WIZ_DTTOPTS dto = { sizeof(WIZ_DTTOPTS) };
+ const UINT uFormat = WIZ_DT_SINGLELINE|WIZ_DT_CENTER|WIZ_DT_VCENTER|WIZ_DT_NOPREFIX;
+ RECT rctext ={0,0, rect.width(), rect.height()};
+
+ dto.dwFlags = WIZ_DTT_COMPOSITED|WIZ_DTT_GLOWSIZE;
+ dto.iGlowSize = glowSize();
+
+ pDrawThemeTextEx(hTheme, dcMem, 0, 0, (LPCWSTR)text.utf16(), -1, uFormat, &rctext, &dto );
+ BitBlt(hdc, rect.left(), rect.top(), rect.width(), rect.height(), dcMem, 0, 0, SRCCOPY);
+ SelectObject(dcMem, (HGDIOBJ) hOldBmp);
+ SelectObject(dcMem, (HGDIOBJ) hOldFont);
+ DeleteObject(bmp);
+ DeleteObject(hCaptionFont);
+ DeleteDC(dcMem);
+ //ReleaseDC(hwnd, hdc);
+ } else if (vistaState() == VistaBasic) {
+ painter->drawText(rect, text);
+ }
+ return value;
+}
+
+bool QVistaHelper::drawBlackRect(const QRect &rect, HDC hdc)
+{
+ bool value = false;
+ if (vistaState() == VistaAero) {
+ // Set up a memory DC and bitmap that we'll draw into
+ HDC dcMem;
+ HBITMAP bmp;
+ BITMAPINFO dib = {{0}};
+ dcMem = CreateCompatibleDC(hdc);
+
+ dib.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ dib.bmiHeader.biWidth = rect.width();
+ dib.bmiHeader.biHeight = -rect.height();
+ dib.bmiHeader.biPlanes = 1;
+ dib.bmiHeader.biBitCount = 32;
+ dib.bmiHeader.biCompression = BI_RGB;
+
+ bmp = CreateDIBSection(hdc, &dib, DIB_RGB_COLORS, NULL, NULL, 0);
+ HBITMAP hOldBmp = (HBITMAP)SelectObject(dcMem, (HGDIOBJ) bmp);
+
+ BitBlt(hdc, rect.left(), rect.top(), rect.width(), rect.height(), dcMem, 0, 0, SRCCOPY);
+ SelectObject(dcMem, (HGDIOBJ) hOldBmp);
+
+ DeleteObject(bmp);
+ DeleteDC(dcMem);
+ }
+ return value;
+}
+
+bool QVistaHelper::resolveSymbols()
+{
+ static bool tried = false;
+ if (!tried) {
+ tried = true;
+ QSystemLibrary dwmLib(L"dwmapi");
+ pDwmIsCompositionEnabled =
+ (PtrDwmIsCompositionEnabled)dwmLib.resolve("DwmIsCompositionEnabled");
+ if (pDwmIsCompositionEnabled) {
+ pDwmDefWindowProc = (PtrDwmDefWindowProc)dwmLib.resolve("DwmDefWindowProc");
+ pDwmExtendFrameIntoClientArea =
+ (PtrDwmExtendFrameIntoClientArea)dwmLib.resolve("DwmExtendFrameIntoClientArea");
+ }
+ QSystemLibrary themeLib(L"uxtheme");
+ pIsAppThemed = (PtrIsAppThemed)themeLib.resolve("IsAppThemed");
+ if (pIsAppThemed) {
+ pDrawThemeBackground = (PtrDrawThemeBackground)themeLib.resolve("DrawThemeBackground");
+ pGetThemePartSize = (PtrGetThemePartSize)themeLib.resolve("GetThemePartSize");
+ pGetThemeColor = (PtrGetThemeColor)themeLib.resolve("GetThemeColor");
+ pIsThemeActive = (PtrIsThemeActive)themeLib.resolve("IsThemeActive");
+ pOpenThemeData = (PtrOpenThemeData)themeLib.resolve("OpenThemeData");
+ pCloseThemeData = (PtrCloseThemeData)themeLib.resolve("CloseThemeData");
+ pGetThemeSysFont = (PtrGetThemeSysFont)themeLib.resolve("GetThemeSysFont");
+ pDrawThemeTextEx = (PtrDrawThemeTextEx)themeLib.resolve("DrawThemeTextEx");
+ pSetWindowThemeAttribute = (PtrSetWindowThemeAttribute)themeLib.resolve("SetWindowThemeAttribute");
+ }
+ }
+
+ return (
+ pDwmIsCompositionEnabled != 0
+ && pDwmDefWindowProc != 0
+ && pDwmExtendFrameIntoClientArea != 0
+ && pIsAppThemed != 0
+ && pDrawThemeBackground != 0
+ && pGetThemePartSize != 0
+ && pGetThemeColor != 0
+ && pIsThemeActive != 0
+ && pOpenThemeData != 0
+ && pCloseThemeData != 0
+ && pGetThemeSysFont != 0
+ && pDrawThemeTextEx != 0
+ && pSetWindowThemeAttribute != 0
+ );
+}
+
+int QVistaHelper::titleOffset()
+{
+ int iconOffset = wizard ->windowIcon().isNull() ? 0 : iconSize() + textSpacing;
+ return leftMargin() + iconOffset;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_STYLE_WINDOWSVISTA
+
+#endif // QT_NO_WIZARD
diff --git a/src/widgets/dialogs/qwizard_win_p.h b/src/widgets/dialogs/qwizard_win_p.h
new file mode 100644
index 0000000000..f53a9ba75c
--- /dev/null
+++ b/src/widgets/dialogs/qwizard_win_p.h
@@ -0,0 +1,158 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWIZARD_WIN_P_H
+#define QWIZARD_WIN_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QT_NO_WIZARD
+#ifndef QT_NO_STYLE_WINDOWSVISTA
+
+#include <qt_windows.h>
+#include <qobject.h>
+#include <qwidget.h>
+#include <qabstractbutton.h>
+#include <QtWidgets/private/qwidget_p.h>
+#include <QtWidgets/private/qstylehelper_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QVistaBackButton : public QAbstractButton
+{
+public:
+ QVistaBackButton(QWidget *widget);
+
+ QSize sizeHint() const;
+ inline QSize minimumSizeHint() const
+ { return sizeHint(); }
+
+ void enterEvent(QEvent *event);
+ void leaveEvent(QEvent *event);
+ void paintEvent(QPaintEvent *event);
+};
+
+class QWizard;
+
+class QVistaHelper : public QObject
+{
+public:
+ QVistaHelper(QWizard *wizard);
+ ~QVistaHelper();
+ enum TitleBarChangeType { NormalTitleBar, ExtendedTitleBar };
+ bool setDWMTitleBar(TitleBarChangeType type);
+ void setTitleBarIconAndCaptionVisible(bool visible);
+ void mouseEvent(QEvent *event);
+ bool handleWinEvent(MSG *message, long *result);
+ void resizeEvent(QResizeEvent *event);
+ void paintEvent(QPaintEvent *event);
+ QVistaBackButton *backButton() const { return backButton_; }
+ void disconnectBackButton() { if (backButton_) backButton_->disconnect(); }
+ void hideBackButton() { if (backButton_) backButton_->hide(); }
+ void setWindowPosHack();
+ QColor basicWindowFrameColor();
+ enum VistaState { VistaAero, VistaBasic, Classic, Dirty };
+ static VistaState vistaState();
+ static int titleBarSize() { return frameSize() + captionSize(); }
+ static int topPadding() { // padding under text
+ return int(QStyleHelper::dpiScaled(
+ QSysInfo::WindowsVersion >= QSysInfo::WV_WINDOWS7 ? 4 : 6));
+ }
+ static int topOffset() {
+ static int aeroOffset = QSysInfo::WindowsVersion >= QSysInfo::WV_WINDOWS7 ?
+ QStyleHelper::dpiScaled(4) : QStyleHelper::dpiScaled(13);
+ return (titleBarSize() + (vistaState() == VistaAero ? aeroOffset : 3)); }
+private:
+ static HFONT getCaptionFont(HANDLE hTheme);
+ bool drawTitleText(QPainter *painter, const QString &text, const QRect &rect, HDC hdc);
+ static bool drawBlackRect(const QRect &rect, HDC hdc);
+
+ static int frameSize() { return GetSystemMetrics(SM_CYSIZEFRAME); }
+ static int captionSize() { return GetSystemMetrics(SM_CYCAPTION); }
+
+ static int backButtonSize() { return int(QStyleHelper::dpiScaled(30)); }
+ static int iconSize() { return 16; } // Standard Aero
+ static int glowSize() { return 10; }
+ int leftMargin() { return backButton_->isVisible() ? backButtonSize() + iconSpacing : 0; }
+
+ int titleOffset();
+ bool resolveSymbols();
+ void drawTitleBar(QPainter *painter);
+ void setMouseCursor(QPoint pos);
+ void collapseTopFrameStrut();
+ bool winEvent(MSG *message, long *result);
+ void mouseMoveEvent(QMouseEvent *event);
+ void mousePressEvent(QMouseEvent *event);
+ void mouseReleaseEvent(QMouseEvent *event);
+ bool eventFilter(QObject *obj, QEvent *event);
+
+ static bool is_vista;
+ static VistaState cachedVistaState;
+ static bool isCompositionEnabled();
+ static bool isThemeActive();
+ enum Changes { resizeTop, movePosition, noChange } change;
+ QPoint pressedPos;
+ bool pressed;
+ QRect rtTop;
+ QRect rtTitle;
+ QWizard *wizard;
+ QVistaBackButton *backButton_;
+
+ int titleBarOffset; // Extra spacing above the text
+ int iconSpacing; // Space between button and icon
+ int textSpacing; // Space between icon and text
+};
+
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_STYLE_WINDOWSVISTA
+#endif // QT_NO_WIZARD
+#endif // QWIZARD_WIN_P_H
diff --git a/src/widgets/effects/effects.pri b/src/widgets/effects/effects.pri
new file mode 100644
index 0000000000..a21f941866
--- /dev/null
+++ b/src/widgets/effects/effects.pri
@@ -0,0 +1,6 @@
+HEADERS += effects/qgraphicseffect.h \
+ effects/qgraphicseffect_p.h \
+ effects/qpixmapfilter_p.h
+
+SOURCES += effects/qgraphicseffect.cpp \
+ effects/qpixmapfilter.cpp
diff --git a/src/widgets/effects/qgraphicseffect.cpp b/src/widgets/effects/qgraphicseffect.cpp
new file mode 100644
index 0000000000..5df29cd297
--- /dev/null
+++ b/src/widgets/effects/qgraphicseffect.cpp
@@ -0,0 +1,1235 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \class QGraphicsEffect
+ \brief The QGraphicsEffect class is the base class for all graphics
+ effects.
+ \since 4.6
+ \ingroup multimedia
+ \ingroup graphicsview-api
+
+ Effects alter the appearance of elements by hooking into the rendering
+ pipeline and operating between the source (e.g., a QGraphicsPixmapItem)
+ and the destination device (e.g., QGraphicsView's viewport). Effects can be
+ disabled by calling setEnabled(false). If effects are disabled, the source
+ is rendered directly.
+
+ To add a visual effect to a QGraphicsItem, for example, you can use one of
+ the standard effects, or alternately, create your own effect by creating a
+ subclass of QGraphicsEffect. The effect can then be installed on the item
+ using QGraphicsItem::setGraphicsEffect().
+
+ Qt provides the following standard effects:
+
+ \list
+ \o QGraphicsBlurEffect - blurs the item by a given radius
+ \o QGraphicsDropShadowEffect - renders a dropshadow behind the item
+ \o QGraphicsColorizeEffect - renders the item in shades of any given color
+ \o QGraphicsOpacityEffect - renders the item with an opacity
+ \endlist
+
+ \table
+ \row
+ \o{2,1} \img graphicseffect-plain.png
+ \row
+ \o \img graphicseffect-blur.png
+ \o \img graphicseffect-colorize.png
+ \row
+ \o \img graphicseffect-opacity.png
+ \o \img graphicseffect-drop-shadow.png
+ \endtable
+
+ \img graphicseffect-widget.png
+
+ For more information on how to use each effect, refer to the specific
+ effect's documentation.
+
+ To create your own custom effect, create a subclass of QGraphicsEffect (or
+ any other existing effects) and reimplement the virtual function draw().
+ This function is called whenever the effect needs to redraw. The draw()
+ function takes the painter with which to draw as an argument. For more
+ information, refer to the documenation for draw(). In the draw() function
+ you can call sourcePixmap() to get a pixmap of the graphics effect source
+ which you can then process.
+
+ If your effect changes, use update() to request for a redraw. If your
+ custom effect changes the bounding rectangle of the source, e.g., a radial
+ glow effect may need to apply an extra margin, you can reimplement the
+ virtual boundingRectFor() function, and call updateBoundingRect()
+ to notify the framework whenever this rectangle changes. The virtual
+ sourceChanged() function is called to notify the effects that
+ the source has changed in some way - e.g., if the source is a
+ QGraphicsRectItem and its rectangle parameters have changed.
+
+ \sa QGraphicsItem::setGraphicsEffect(), QWidget::setGraphicsEffect()
+*/
+
+#include "qgraphicseffect_p.h"
+#include "private/qgraphicsitem_p.h"
+
+#include <QtWidgets/qgraphicsitem.h>
+
+#include <QtGui/qimage.h>
+#include <QtGui/qpainter.h>
+#include <QtGui/qpaintengine.h>
+#include <QtCore/qrect.h>
+#include <QtCore/qdebug.h>
+#include <private/qdrawhelper_p.h>
+
+#ifndef QT_NO_GRAPHICSEFFECT
+QT_BEGIN_NAMESPACE
+
+/*!
+ \internal
+ \class QGraphicsEffectSource
+ \brief The QGraphicsEffectSource class represents the source on which a
+ QGraphicsEffect is installed on.
+
+ When a QGraphicsEffect is installed on a QGraphicsItem, for example, this
+ class will act as a wrapper around QGraphicsItem. Then, calling update() is
+ effectively the same as calling QGraphicsItem::update().
+
+ QGraphicsEffectSource also provides a pixmap() function which creates a
+ pixmap with the source painted into it.
+
+ \sa QGraphicsItem::setGraphicsEffect(), QWidget::setGraphicsEffect().
+*/
+
+/*!
+ \internal
+*/
+QGraphicsEffectSource::QGraphicsEffectSource(QGraphicsEffectSourcePrivate &dd, QObject *parent)
+ : QObject(dd, parent)
+{}
+
+/*!
+ Destroys the effect source.
+*/
+QGraphicsEffectSource::~QGraphicsEffectSource()
+{}
+
+/*!
+ Returns the bounding rectangle of the source mapped to the given \a system.
+
+ \sa draw()
+*/
+QRectF QGraphicsEffectSource::boundingRect(Qt::CoordinateSystem system) const
+{
+ return d_func()->boundingRect(system);
+}
+
+/*!
+ Returns the bounding rectangle of the source mapped to the given \a system.
+
+ Calling this function with Qt::DeviceCoordinates outside of
+ QGraphicsEffect::draw() will give undefined results, as there is no device
+ context available.
+
+ \sa draw()
+*/
+QRectF QGraphicsEffect::sourceBoundingRect(Qt::CoordinateSystem system) const
+{
+ Q_D(const QGraphicsEffect);
+ if (d->source)
+ return d->source->boundingRect(system);
+ return QRectF();
+}
+
+/*!
+ Returns a pointer to the item if this source is a QGraphicsItem; otherwise
+ returns 0.
+
+ \sa widget()
+*/
+const QGraphicsItem *QGraphicsEffectSource::graphicsItem() const
+{
+ return d_func()->graphicsItem();
+}
+
+/*!
+ Returns a pointer to the widget if this source is a QWidget; otherwise
+ returns 0.
+
+ \sa graphicsItem()
+*/
+const QWidget *QGraphicsEffectSource::widget() const
+{
+ return d_func()->widget();
+}
+
+/*!
+ Returns a pointer to the style options (used when drawing the source) if
+ available; otherwise returns 0.
+
+ \sa graphicsItem(), widget()
+*/
+const QStyleOption *QGraphicsEffectSource::styleOption() const
+{
+ return d_func()->styleOption();
+}
+
+/*!
+ Draws the source using the given \a painter.
+
+ This function should only be called from QGraphicsEffect::draw().
+
+ \sa QGraphicsEffect::draw()
+*/
+void QGraphicsEffectSource::draw(QPainter *painter)
+{
+ Q_D(const QGraphicsEffectSource);
+
+ QPixmap pm;
+ if (QPixmapCache::find(d->m_cacheKey, &pm)) {
+ QTransform restoreTransform;
+ if (d->m_cachedSystem == Qt::DeviceCoordinates) {
+ restoreTransform = painter->worldTransform();
+ painter->setWorldTransform(QTransform());
+ }
+
+ painter->drawPixmap(d->m_cachedOffset, pm);
+
+ if (d->m_cachedSystem == Qt::DeviceCoordinates)
+ painter->setWorldTransform(restoreTransform);
+ } else {
+ d_func()->draw(painter);
+ }
+}
+
+/*!
+ Draws the source directly using the given \a painter.
+
+ This function should only be called from QGraphicsEffect::draw().
+
+ For example:
+
+ \snippet doc/src/snippets/code/src_gui_effects_qgraphicseffect.cpp 0
+
+ \sa QGraphicsEffect::draw()
+*/
+void QGraphicsEffect::drawSource(QPainter *painter)
+{
+ Q_D(const QGraphicsEffect);
+ if (d->source)
+ d->source->draw(painter);
+}
+
+/*!
+ Schedules a redraw of the source. Call this function whenever the source
+ needs to be redrawn.
+
+ \sa QGraphicsEffect::updateBoundingRect(), QWidget::update(),
+ QGraphicsItem::update(),
+*/
+void QGraphicsEffectSource::update()
+{
+ d_func()->update();
+}
+
+/*!
+ Returns true if the source effectively is a pixmap, e.g., a
+ QGraphicsPixmapItem.
+
+ This function is useful for optimization purposes. For instance, there's no
+ point in drawing the source in device coordinates to avoid pixmap scaling
+ if this function returns true - the source pixmap will be scaled anyways.
+*/
+bool QGraphicsEffectSource::isPixmap() const
+{
+ return d_func()->isPixmap();
+}
+
+/*!
+ Returns true if the source effectively is a pixmap, e.g., a
+ QGraphicsPixmapItem.
+
+ This function is useful for optimization purposes. For instance, there's no
+ point in drawing the source in device coordinates to avoid pixmap scaling
+ if this function returns true - the source pixmap will be scaled anyways.
+*/
+bool QGraphicsEffect::sourceIsPixmap() const
+{
+ return source() ? source()->isPixmap() : false;
+}
+
+/*!
+ Returns a pixmap with the source painted into it.
+
+ The \a system specifies which coordinate system to be used for the source.
+ The optional \a offset parameter returns the offset where the pixmap should
+ be painted at using the current painter.
+
+ The \a mode determines how much of the effect the pixmap will contain.
+ By default, the pixmap will contain the whole effect.
+
+ The returned pixmap is bound to the current painter's device rectangle when
+ \a system is Qt::DeviceCoordinates.
+
+ \sa QGraphicsEffect::draw(), boundingRect()
+*/
+QPixmap QGraphicsEffectSource::pixmap(Qt::CoordinateSystem system, QPoint *offset, QGraphicsEffect::PixmapPadMode mode) const
+{
+ Q_D(const QGraphicsEffectSource);
+
+ // Shortcut, no cache for childless pixmap items...
+ const QGraphicsItem *item = graphicsItem();
+ if (system == Qt::LogicalCoordinates && mode == QGraphicsEffect::NoPad && item && isPixmap()) {
+ const QGraphicsPixmapItem *pixmapItem = static_cast<const QGraphicsPixmapItem *>(item);
+ if (offset)
+ *offset = pixmapItem->offset().toPoint();
+ return pixmapItem->pixmap();
+ }
+
+ if (system == Qt::DeviceCoordinates && item
+ && !static_cast<const QGraphicsItemEffectSourcePrivate *>(d_func())->info) {
+ qWarning("QGraphicsEffectSource::pixmap: Not yet implemented, lacking device context");
+ return QPixmap();
+ }
+
+ QPixmap pm;
+ if (item && d->m_cachedSystem == system && d->m_cachedMode == mode)
+ QPixmapCache::find(d->m_cacheKey, &pm);
+
+ if (pm.isNull()) {
+ pm = d->pixmap(system, &d->m_cachedOffset, mode);
+ d->m_cachedSystem = system;
+ d->m_cachedMode = mode;
+
+ d->invalidateCache();
+ d->m_cacheKey = QPixmapCache::insert(pm);
+ }
+
+ if (offset)
+ *offset = d->m_cachedOffset;
+
+ return pm;
+}
+
+/*!
+ Returns a pixmap with the source painted into it.
+
+ The \a system specifies which coordinate system to be used for the source.
+ The optional \a offset parameter returns the offset where the pixmap should
+ be painted at using the current painter. For control on how the pixmap is
+ padded use the \a mode parameter.
+
+ The returned pixmap is clipped to the current painter's device rectangle when
+ \a system is Qt::DeviceCoordinates.
+
+ Calling this function with Qt::DeviceCoordinates outside of
+ QGraphicsEffect::draw() will give undefined results, as there is no device
+ context available.
+
+ \sa draw(), boundingRect()
+*/
+QPixmap QGraphicsEffect::sourcePixmap(Qt::CoordinateSystem system, QPoint *offset, QGraphicsEffect::PixmapPadMode mode) const
+{
+ Q_D(const QGraphicsEffect);
+ if (d->source)
+ return d->source->pixmap(system, offset, mode);
+ return QPixmap();
+}
+
+QGraphicsEffectSourcePrivate::~QGraphicsEffectSourcePrivate()
+{
+ invalidateCache();
+}
+
+void QGraphicsEffectSourcePrivate::setCachedOffset(const QPoint &offset)
+{
+ m_cachedOffset = offset;
+}
+
+void QGraphicsEffectSourcePrivate::invalidateCache(InvalidateReason reason) const
+{
+ if (m_cachedMode != QGraphicsEffect::PadToEffectiveBoundingRect
+ && (reason == EffectRectChanged
+ || (reason == TransformChanged && m_cachedSystem == Qt::LogicalCoordinates))) {
+ return;
+ }
+
+ QPixmapCache::remove(m_cacheKey);
+}
+
+/*!
+ Constructs a new QGraphicsEffect instance having the
+ specified \a parent.
+*/
+QGraphicsEffect::QGraphicsEffect(QObject *parent)
+ : QObject(*new QGraphicsEffectPrivate, parent)
+{
+}
+
+/*!
+ \internal
+*/
+QGraphicsEffect::QGraphicsEffect(QGraphicsEffectPrivate &dd, QObject *parent)
+ : QObject(dd, parent)
+{
+}
+
+/*!
+ Removes the effect from the source, and destroys the graphics effect.
+*/
+QGraphicsEffect::~QGraphicsEffect()
+{
+ Q_D(QGraphicsEffect);
+ d->setGraphicsEffectSource(0);
+}
+
+/*!
+ Returns the effective bounding rectangle for this effect, i.e., the
+ bounding rectangle of the source in device coordinates, adjusted by
+ any margins applied by the effect itself.
+
+ \sa boundingRectFor(), updateBoundingRect()
+*/
+QRectF QGraphicsEffect::boundingRect() const
+{
+ Q_D(const QGraphicsEffect);
+ if (d->source)
+ return boundingRectFor(d->source->boundingRect());
+ return QRectF();
+}
+
+/*!
+ Returns the effective bounding rectangle for this effect, given the
+ provided \a rect in the device coordinates. When writing
+ you own custom effect, you must call updateBoundingRect() whenever any
+ parameters are changed that may cause this this function to return a
+ different value.
+
+ \sa sourceBoundingRect()
+*/
+QRectF QGraphicsEffect::boundingRectFor(const QRectF &rect) const
+{
+ return rect;
+}
+
+/*!
+ \property QGraphicsEffect::enabled
+ \brief whether the effect is enabled or not.
+
+ If an effect is disabled, the source will be rendered with as normal, with
+ no interference from the effect. If the effect is enabled, the source will
+ be rendered with the effect applied.
+
+ This property is enabled by default.
+
+ Using this property, you can disable certain effects on slow platforms, in
+ order to ensure that the user interface is responsive.
+*/
+bool QGraphicsEffect::isEnabled() const
+{
+ Q_D(const QGraphicsEffect);
+ return d->isEnabled;
+}
+
+void QGraphicsEffect::setEnabled(bool enable)
+{
+ Q_D(QGraphicsEffect);
+ if (d->isEnabled == enable)
+ return;
+
+ d->isEnabled = enable;
+ if (d->source) {
+ d->source->d_func()->effectBoundingRectChanged();
+ d->source->d_func()->invalidateCache();
+ }
+ emit enabledChanged(enable);
+}
+
+/*!
+ \fn void QGraphicsEffect::enabledChanged(bool enabled)
+
+ This signal is emitted whenever the effect is enabled or disabled.
+ The \a enabled parameter holds the effects's new enabled state.
+
+ \sa isEnabled()
+*/
+
+/*!
+ Schedules a redraw of the effect. Call this function whenever the effect
+ needs to be redrawn. This function does not trigger a redraw of the source.
+
+ \sa updateBoundingRect()
+*/
+void QGraphicsEffect::update()
+{
+ Q_D(QGraphicsEffect);
+ if (d->source)
+ d->source->update();
+}
+
+/*!
+ \internal
+
+ Returns a pointer to the source, which provides extra context information
+ that can be useful for the effect.
+
+ \sa draw()
+*/
+QGraphicsEffectSource *QGraphicsEffect::source() const
+{
+ Q_D(const QGraphicsEffect);
+ return d->source;
+}
+
+/*!
+ This function notifies the effect framework when the effect's bounding
+ rectangle has changed. As a custom effect author, you must call this
+ function whenever you change any parameters that will cause the virtual
+ boundingRectFor() function to return a different value.
+
+ This function will call update() if this is necessary.
+
+ \sa boundingRectFor(), boundingRect(), sourceBoundingRect()
+*/
+void QGraphicsEffect::updateBoundingRect()
+{
+ Q_D(QGraphicsEffect);
+ if (d->source) {
+ d->source->d_func()->effectBoundingRectChanged();
+ d->source->d_func()->invalidateCache(QGraphicsEffectSourcePrivate::EffectRectChanged);
+ }
+}
+
+/*!
+ \fn virtual void QGraphicsEffect::draw(QPainter *painter) = 0
+
+ This pure virtual function draws the effect and is called whenever the
+ source needs to be drawn.
+
+ Reimplement this function in a QGraphicsEffect subclass to provide the
+ effect's drawing implementation, using \a painter.
+
+ For example:
+
+ \snippet doc/src/snippets/code/src_gui_effects_qgraphicseffect.cpp 1
+
+ This function should not be called explicitly by the user, since it is
+ meant for reimplementation purposes only.
+*/
+
+/*!
+ \enum QGraphicsEffect::ChangeFlag
+
+ This enum describes what has changed in QGraphicsEffectSource.
+
+ \value SourceAttached The effect is installed on a source.
+ \value SourceDetached The effect is uninstalled on a source.
+ \value SourceBoundingRectChanged The bounding rect of the source has
+ changed.
+ \value SourceInvalidated The visual appearance of the source has changed.
+*/
+
+/*!
+ \enum QGraphicsEffect::PixmapPadMode
+
+ This enum describes how the pixmap returned from sourcePixmap should be
+ padded.
+
+ \value NoPad The pixmap should not receive any additional
+ padding.
+ \value PadToTransparentBorder The pixmap should be padded
+ to ensure it has a completely transparent border.
+ \value PadToEffectiveBoundingRect The pixmap should be padded to
+ match the effective bounding rectangle of the effect.
+*/
+
+/*!
+ This virtual function is called by QGraphicsEffect to notify the effect
+ that the source has changed. If the effect applies any cache, then this
+ cache must be purged in order to reflect the new appearance of the source.
+
+ The \a flags describes what has changed.
+*/
+void QGraphicsEffect::sourceChanged(ChangeFlags flags)
+{
+ Q_UNUSED(flags);
+}
+
+/*!
+ \class QGraphicsColorizeEffect
+ \brief The QGraphicsColorizeEffect class provides a colorize effect.
+ \since 4.6
+
+ A colorize effect renders the source with a tint of its color(). The color
+ can be modified using the setColor() function.
+
+ By default, the color is light blue (QColor(0, 0, 192)).
+
+ \img graphicseffect-colorize.png
+
+ \sa QGraphicsDropShadowEffect, QGraphicsBlurEffect, QGraphicsOpacityEffect
+*/
+
+/*!
+ Constructs a new QGraphicsColorizeEffect instance.
+ The \a parent parameter is passed to QGraphicsEffect's constructor.
+*/
+QGraphicsColorizeEffect::QGraphicsColorizeEffect(QObject *parent)
+ : QGraphicsEffect(*new QGraphicsColorizeEffectPrivate, parent)
+{
+}
+
+/*!
+ Destroys the effect.
+*/
+QGraphicsColorizeEffect::~QGraphicsColorizeEffect()
+{
+}
+
+/*!
+ \property QGraphicsColorizeEffect::color
+ \brief the color of the effect.
+
+ By default, the color is light blue (QColor(0, 0, 192)).
+*/
+QColor QGraphicsColorizeEffect::color() const
+{
+ Q_D(const QGraphicsColorizeEffect);
+ return d->filter->color();
+}
+
+void QGraphicsColorizeEffect::setColor(const QColor &color)
+{
+ Q_D(QGraphicsColorizeEffect);
+ if (d->filter->color() == color)
+ return;
+
+ d->filter->setColor(color);
+ update();
+ emit colorChanged(color);
+}
+
+/*!
+ \property QGraphicsColorizeEffect::strength
+ \brief the strength of the effect.
+
+ By default, the strength is 1.0.
+ A strength 0.0 equals to no effect, while 1.0 means full colorization.
+*/
+qreal QGraphicsColorizeEffect::strength() const
+{
+ Q_D(const QGraphicsColorizeEffect);
+ return d->filter->strength();
+}
+
+void QGraphicsColorizeEffect::setStrength(qreal strength)
+{
+ Q_D(QGraphicsColorizeEffect);
+ if (qFuzzyCompare(d->filter->strength(), strength))
+ return;
+
+ d->filter->setStrength(strength);
+ d->opaque = !qFuzzyIsNull(strength);
+ update();
+ emit strengthChanged(strength);
+}
+
+/*! \fn void QGraphicsColorizeEffect::strengthChanged(qreal strength)
+ This signal is emitted whenever setStrength() changes the colorize
+ strength property. \a strength contains the new strength value of
+ the colorize effect.
+ */
+
+/*!
+ \fn void QGraphicsColorizeEffect::colorChanged(const QColor &color)
+
+ This signal is emitted whenever the effect's color changes.
+ The \a color parameter holds the effect's new color.
+*/
+
+/*!
+ \reimp
+*/
+void QGraphicsColorizeEffect::draw(QPainter *painter)
+{
+ Q_D(QGraphicsColorizeEffect);
+
+ if (!d->opaque) {
+ drawSource(painter);
+ return;
+ }
+
+ QPoint offset;
+ if (sourceIsPixmap()) {
+ // No point in drawing in device coordinates (pixmap will be scaled anyways).
+ const QPixmap pixmap = sourcePixmap(Qt::LogicalCoordinates, &offset, NoPad);
+ if (!pixmap.isNull())
+ d->filter->draw(painter, offset, pixmap);
+
+ return;
+ }
+
+ // Draw pixmap in deviceCoordinates to avoid pixmap scaling.
+ const QPixmap pixmap = sourcePixmap(Qt::DeviceCoordinates, &offset);
+ if (pixmap.isNull())
+ return;
+
+ QTransform restoreTransform = painter->worldTransform();
+ painter->setWorldTransform(QTransform());
+ d->filter->draw(painter, offset, pixmap);
+ painter->setWorldTransform(restoreTransform);
+}
+
+/*!
+ \class QGraphicsBlurEffect
+ \brief The QGraphicsBlurEffect class provides a blur effect.
+ \since 4.6
+
+ A blur effect blurs the source. This effect is useful for reducing details,
+ such as when the source loses focus and you want to draw attention to other
+ elements. The level of detail can be modified using the setBlurRadius()
+ function. Use setBlurHints() to choose the blur hints.
+
+ By default, the blur radius is 5 pixels. The blur radius is specified in
+ device coordinates.
+
+ \img graphicseffect-blur.png
+
+ \sa QGraphicsDropShadowEffect, QGraphicsColorizeEffect, QGraphicsOpacityEffect
+*/
+
+/*!
+ \enum QGraphicsBlurEffect::BlurHint
+ \since 4.6
+
+ This enum describes the possible hints that can be used to control how
+ blur effects are applied. The hints might not have an effect in all the
+ paint engines.
+
+ \value PerformanceHint Indicates that rendering performance is the most important factor,
+ at the potential cost of lower quality.
+
+ \value QualityHint Indicates that rendering quality is the most important factor,
+ at the potential cost of lower performance.
+
+ \value AnimationHint Indicates that the blur radius is going to be animated, hinting
+ that the implementation can keep a cache of blurred verisons of the source.
+ Do not use this hint if the source is going to be dynamically changing.
+
+ \sa blurHints(), setBlurHints()
+*/
+
+
+/*!
+ Constructs a new QGraphicsBlurEffect instance.
+ The \a parent parameter is passed to QGraphicsEffect's constructor.
+*/
+QGraphicsBlurEffect::QGraphicsBlurEffect(QObject *parent)
+ : QGraphicsEffect(*new QGraphicsBlurEffectPrivate, parent)
+{
+ Q_D(QGraphicsBlurEffect);
+ d->filter->setBlurHints(QGraphicsBlurEffect::PerformanceHint);
+}
+
+/*!
+ Destroys the effect.
+*/
+QGraphicsBlurEffect::~QGraphicsBlurEffect()
+{
+}
+
+/*!
+ \property QGraphicsBlurEffect::blurRadius
+ \brief the blur radius of the effect.
+
+ Using a smaller radius results in a sharper appearance, whereas a bigger
+ radius results in a more blurred appearance.
+
+ By default, the blur radius is 5 pixels.
+
+ The radius is given in device coordinates, meaning it is
+ unaffected by scale.
+*/
+qreal QGraphicsBlurEffect::blurRadius() const
+{
+ Q_D(const QGraphicsBlurEffect);
+ return d->filter->radius();
+}
+
+void QGraphicsBlurEffect::setBlurRadius(qreal radius)
+{
+ Q_D(QGraphicsBlurEffect);
+ if (qFuzzyCompare(d->filter->radius(), radius))
+ return;
+
+ d->filter->setRadius(radius);
+ updateBoundingRect();
+ emit blurRadiusChanged(radius);
+}
+
+/*!
+ \fn void QGraphicsBlurEffect::blurRadiusChanged(qreal radius)
+
+ This signal is emitted whenever the effect's blur radius changes.
+ The \a radius parameter holds the effect's new blur radius.
+*/
+
+/*!
+ \property QGraphicsBlurEffect::blurHints
+ \brief the blur hint of the effect.
+
+ Use the PerformanceHint hint to say that you want a faster blur,
+ the QualityHint hint to say that you prefer a higher quality blur,
+ or the AnimationHint when you want to animate the blur radius.
+
+ By default, the blur hint is PerformanceHint.
+*/
+QGraphicsBlurEffect::BlurHints QGraphicsBlurEffect::blurHints() const
+{
+ Q_D(const QGraphicsBlurEffect);
+ return d->filter->blurHints();
+}
+
+void QGraphicsBlurEffect::setBlurHints(QGraphicsBlurEffect::BlurHints hints)
+{
+ Q_D(QGraphicsBlurEffect);
+ if (d->filter->blurHints() == hints)
+ return;
+
+ d->filter->setBlurHints(hints);
+ emit blurHintsChanged(hints);
+}
+
+/*!
+ \fn void QGraphicsBlurEffect::blurHintsChanged(QGraphicsBlurEffect::BlurHints hints)
+
+ This signal is emitted whenever the effect's blur hints changes.
+ The \a hints parameter holds the effect's new blur hints.
+*/
+
+/*!
+ \reimp
+*/
+QRectF QGraphicsBlurEffect::boundingRectFor(const QRectF &rect) const
+{
+ Q_D(const QGraphicsBlurEffect);
+ return d->filter->boundingRectFor(rect);
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsBlurEffect::draw(QPainter *painter)
+{
+ Q_D(QGraphicsBlurEffect);
+ if (d->filter->radius() < 1) {
+ drawSource(painter);
+ return;
+ }
+
+ PixmapPadMode mode = PadToEffectiveBoundingRect;
+ if (painter->paintEngine()->type() == QPaintEngine::OpenGL2)
+ mode = NoPad;
+
+ QPoint offset;
+ QPixmap pixmap = sourcePixmap(Qt::LogicalCoordinates, &offset, mode);
+ if (pixmap.isNull())
+ return;
+
+ d->filter->draw(painter, offset, pixmap);
+}
+
+/*!
+ \class QGraphicsDropShadowEffect
+ \brief The QGraphicsDropShadowEffect class provides a drop shadow effect.
+ \since 4.6
+
+ A drop shadow effect renders the source with a drop shadow. The color of
+ the drop shadow can be modified using the setColor() function. The drop
+ shadow offset can be modified using the setOffset() function and the blur
+ radius of the drop shadow can be changed with the setBlurRadius()
+ function.
+
+ By default, the drop shadow is a semi-transparent dark gray
+ (QColor(63, 63, 63, 180)) shadow, blurred with a radius of 1 at an offset
+ of 8 pixels towards the lower right. The drop shadow offset is specified
+ in device coordinates.
+
+ \img graphicseffect-drop-shadow.png
+
+ \sa QGraphicsBlurEffect, QGraphicsColorizeEffect, QGraphicsOpacityEffect
+*/
+
+/*!
+ Constructs a new QGraphicsDropShadowEffect instance.
+ The \a parent parameter is passed to QGraphicsEffect's constructor.
+*/
+QGraphicsDropShadowEffect::QGraphicsDropShadowEffect(QObject *parent)
+ : QGraphicsEffect(*new QGraphicsDropShadowEffectPrivate, parent)
+{
+}
+
+/*!
+ Destroys the effect.
+*/
+QGraphicsDropShadowEffect::~QGraphicsDropShadowEffect()
+{
+}
+
+/*!
+ \property QGraphicsDropShadowEffect::offset
+ \brief the shadow offset in pixels.
+
+ By default, the offset is 8 pixels towards the lower right.
+
+ The offset is given in device coordinates, which means it is
+ unaffected by scale.
+
+ \sa xOffset(), yOffset(), blurRadius(), color()
+*/
+QPointF QGraphicsDropShadowEffect::offset() const
+{
+ Q_D(const QGraphicsDropShadowEffect);
+ return d->filter->offset();
+}
+
+void QGraphicsDropShadowEffect::setOffset(const QPointF &offset)
+{
+ Q_D(QGraphicsDropShadowEffect);
+ if (d->filter->offset() == offset)
+ return;
+
+ d->filter->setOffset(offset);
+ updateBoundingRect();
+ emit offsetChanged(offset);
+}
+
+/*!
+ \property QGraphicsDropShadowEffect::xOffset
+ \brief the horizontal shadow offset in pixels.
+
+ By default, the horizontal shadow offset is 8 pixels.
+
+
+
+ \sa yOffset(), offset()
+*/
+
+/*!
+ \property QGraphicsDropShadowEffect::yOffset
+ \brief the vertical shadow offset in pixels.
+
+ By default, the vertical shadow offset is 8 pixels.
+
+ \sa xOffset(), offset()
+*/
+
+/*!
+ \fn void QGraphicsDropShadowEffect::offsetChanged(const QPointF &offset)
+
+ This signal is emitted whenever the effect's shadow offset changes.
+ The \a offset parameter holds the effect's new shadow offset.
+*/
+
+/*!
+ \property QGraphicsDropShadowEffect::blurRadius
+ \brief the blur radius in pixels of the drop shadow.
+
+ Using a smaller radius results in a sharper shadow, whereas using a bigger
+ radius results in a more blurred shadow.
+
+ By default, the blur radius is 1 pixel.
+
+ \sa color(), offset().
+*/
+qreal QGraphicsDropShadowEffect::blurRadius() const
+{
+ Q_D(const QGraphicsDropShadowEffect);
+ return d->filter->blurRadius();
+}
+
+void QGraphicsDropShadowEffect::setBlurRadius(qreal blurRadius)
+{
+ Q_D(QGraphicsDropShadowEffect);
+ if (qFuzzyCompare(d->filter->blurRadius(), blurRadius))
+ return;
+
+ d->filter->setBlurRadius(blurRadius);
+ updateBoundingRect();
+ emit blurRadiusChanged(blurRadius);
+}
+
+/*!
+ \fn void QGraphicsDropShadowEffect::blurRadiusChanged(qreal blurRadius)
+
+ This signal is emitted whenever the effect's blur radius changes.
+ The \a blurRadius parameter holds the effect's new blur radius.
+*/
+
+/*!
+ \property QGraphicsDropShadowEffect::color
+ \brief the color of the drop shadow.
+
+ By default, the drop color is a semi-transparent dark gray
+ (QColor(63, 63, 63, 180)).
+
+ \sa offset(), blurRadius()
+*/
+QColor QGraphicsDropShadowEffect::color() const
+{
+ Q_D(const QGraphicsDropShadowEffect);
+ return d->filter->color();
+}
+
+void QGraphicsDropShadowEffect::setColor(const QColor &color)
+{
+ Q_D(QGraphicsDropShadowEffect);
+ if (d->filter->color() == color)
+ return;
+
+ d->filter->setColor(color);
+ update();
+ emit colorChanged(color);
+}
+
+/*!
+ \fn void QGraphicsDropShadowEffect::colorChanged(const QColor &color)
+
+ This signal is emitted whenever the effect's color changes.
+ The \a color parameter holds the effect's new color.
+*/
+
+/*!
+ \reimp
+*/
+QRectF QGraphicsDropShadowEffect::boundingRectFor(const QRectF &rect) const
+{
+ Q_D(const QGraphicsDropShadowEffect);
+ return d->filter->boundingRectFor(rect);
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsDropShadowEffect::draw(QPainter *painter)
+{
+ Q_D(QGraphicsDropShadowEffect);
+ if (d->filter->blurRadius() <= 0 && d->filter->offset().isNull()) {
+ drawSource(painter);
+ return;
+ }
+
+ PixmapPadMode mode = PadToEffectiveBoundingRect;
+ if (painter->paintEngine()->type() == QPaintEngine::OpenGL2)
+ mode = NoPad;
+
+ // Draw pixmap in device coordinates to avoid pixmap scaling.
+ QPoint offset;
+ const QPixmap pixmap = sourcePixmap(Qt::DeviceCoordinates, &offset, mode);
+ if (pixmap.isNull())
+ return;
+
+ QTransform restoreTransform = painter->worldTransform();
+ painter->setWorldTransform(QTransform());
+ d->filter->draw(painter, offset, pixmap);
+ painter->setWorldTransform(restoreTransform);
+}
+
+/*!
+ \class QGraphicsOpacityEffect
+ \brief The QGraphicsOpacityEffect class provides an opacity effect.
+ \since 4.6
+
+ An opacity effect renders the source with an opacity. This effect is useful
+ for making the source semi-transparent, similar to a fade-in/fade-out
+ sequence. The opacity can be modified using the setOpacity() function.
+
+ By default, the opacity is 0.7.
+
+ \img graphicseffect-opacity.png
+
+ \sa QGraphicsDropShadowEffect, QGraphicsBlurEffect, QGraphicsColorizeEffect
+*/
+
+/*!
+ Constructs a new QGraphicsOpacityEffect instance.
+ The \a parent parameter is passed to QGraphicsEffect's constructor.
+*/
+QGraphicsOpacityEffect::QGraphicsOpacityEffect(QObject *parent)
+ : QGraphicsEffect(*new QGraphicsOpacityEffectPrivate, parent)
+{
+}
+
+/*!
+ Destroys the effect.
+*/
+QGraphicsOpacityEffect::~QGraphicsOpacityEffect()
+{
+}
+
+/*!
+ \property QGraphicsOpacityEffect::opacity
+ \brief the opacity of the effect.
+
+ The value should be in the range of 0.0 to 1.0, where 0.0 is
+ fully transparent and 1.0 is fully opaque.
+
+ By default, the opacity is 0.7.
+
+ \sa setOpacityMask()
+*/
+qreal QGraphicsOpacityEffect::opacity() const
+{
+ Q_D(const QGraphicsOpacityEffect);
+ return d->opacity;
+}
+
+void QGraphicsOpacityEffect::setOpacity(qreal opacity)
+{
+ Q_D(QGraphicsOpacityEffect);
+ opacity = qBound(qreal(0.0), opacity, qreal(1.0));
+
+ if (qFuzzyCompare(d->opacity, opacity))
+ return;
+
+ d->opacity = opacity;
+ if ((d->isFullyTransparent = qFuzzyIsNull(d->opacity)))
+ d->isFullyOpaque = 0;
+ else
+ d->isFullyOpaque = qFuzzyIsNull(d->opacity - 1);
+ update();
+ emit opacityChanged(opacity);
+}
+
+/*!
+ \fn void QGraphicsOpacityEffect::opacityChanged(qreal opacity)
+
+ This signal is emitted whenever the effect's opacity changes.
+ The \a opacity parameter holds the effect's new opacity.
+*/
+
+/*!
+ \property QGraphicsOpacityEffect::opacityMask
+ \brief the opacity mask of the effect.
+
+ An opacity mask allows you apply opacity to portions of an element.
+
+ For example:
+
+ \snippet doc/src/snippets/code/src_gui_effects_qgraphicseffect.cpp 2
+
+ There is no opacity mask by default.
+
+ \sa setOpacity()
+*/
+QBrush QGraphicsOpacityEffect::opacityMask() const
+{
+ Q_D(const QGraphicsOpacityEffect);
+ return d->opacityMask;
+}
+
+void QGraphicsOpacityEffect::setOpacityMask(const QBrush &mask)
+{
+ Q_D(QGraphicsOpacityEffect);
+ if (d->opacityMask == mask)
+ return;
+
+ d->opacityMask = mask;
+ d->hasOpacityMask = (mask.style() != Qt::NoBrush);
+ update();
+
+ emit opacityMaskChanged(mask);
+}
+
+/*!
+ \fn void QGraphicsOpacityEffect::opacityMaskChanged(const QBrush &mask)
+
+ This signal is emitted whenever the effect's opacity mask changes.
+ The \a mask parameter holds the effect's new opacity mask.
+*/
+
+/*!
+ \reimp
+*/
+void QGraphicsOpacityEffect::draw(QPainter *painter)
+{
+ Q_D(QGraphicsOpacityEffect);
+
+ // Transparent; nothing to draw.
+ if (d->isFullyTransparent)
+ return;
+
+ // Opaque; draw directly without going through a pixmap.
+ if (d->isFullyOpaque && !d->hasOpacityMask) {
+ drawSource(painter);
+ return;
+ }
+
+ QPoint offset;
+ Qt::CoordinateSystem system = sourceIsPixmap() ? Qt::LogicalCoordinates : Qt::DeviceCoordinates;
+ QPixmap pixmap = sourcePixmap(system, &offset, QGraphicsEffect::NoPad);
+ if (pixmap.isNull())
+ return;
+
+ painter->save();
+ painter->setOpacity(d->opacity);
+
+ if (d->hasOpacityMask) {
+ QPainter pixmapPainter(&pixmap);
+ pixmapPainter.setRenderHints(painter->renderHints());
+ pixmapPainter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
+ if (system == Qt::DeviceCoordinates) {
+ QTransform worldTransform = painter->worldTransform();
+ worldTransform *= QTransform::fromTranslate(-offset.x(), -offset.y());
+ pixmapPainter.setWorldTransform(worldTransform);
+ pixmapPainter.fillRect(sourceBoundingRect(), d->opacityMask);
+ } else {
+ pixmapPainter.translate(-offset);
+ pixmapPainter.fillRect(pixmap.rect(), d->opacityMask);
+ }
+ }
+
+ if (system == Qt::DeviceCoordinates)
+ painter->setWorldTransform(QTransform());
+
+ painter->drawPixmap(offset, pixmap);
+ painter->restore();
+}
+
+
+QT_END_NAMESPACE
+
+#endif //QT_NO_GRAPHICSEFFECT
diff --git a/src/widgets/effects/qgraphicseffect.h b/src/widgets/effects/qgraphicseffect.h
new file mode 100644
index 0000000000..0ee6b26463
--- /dev/null
+++ b/src/widgets/effects/qgraphicseffect.h
@@ -0,0 +1,289 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGRAPHICSEFFECT_H
+#define QGRAPHICSEFFECT_H
+
+#include <QtCore/qobject.h>
+#include <QtCore/qpoint.h>
+#include <QtCore/qrect.h>
+#include <QtGui/qcolor.h>
+#include <QtGui/qbrush.h>
+
+#ifndef QT_NO_GRAPHICSEFFECT
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QGraphicsItem;
+class QStyleOption;
+class QPainter;
+class QPixmap;
+
+class QGraphicsEffectSource;
+
+class QGraphicsEffectPrivate;
+class Q_WIDGETS_EXPORT QGraphicsEffect : public QObject
+{
+ Q_OBJECT
+ Q_FLAGS(ChangeFlags)
+ Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged)
+public:
+ enum ChangeFlag {
+ SourceAttached = 0x1,
+ SourceDetached = 0x2,
+ SourceBoundingRectChanged = 0x4,
+ SourceInvalidated = 0x8
+ };
+ Q_DECLARE_FLAGS(ChangeFlags, ChangeFlag)
+
+ enum PixmapPadMode {
+ NoPad,
+ PadToTransparentBorder,
+ PadToEffectiveBoundingRect
+ };
+
+ QGraphicsEffect(QObject *parent = 0);
+ virtual ~QGraphicsEffect();
+
+ virtual QRectF boundingRectFor(const QRectF &sourceRect) const;
+ QRectF boundingRect() const;
+
+ bool isEnabled() const;
+
+public Q_SLOTS:
+ void setEnabled(bool enable);
+ void update();
+
+Q_SIGNALS:
+ void enabledChanged(bool enabled);
+
+protected:
+ QGraphicsEffect(QGraphicsEffectPrivate &d, QObject *parent = 0);
+ virtual void draw(QPainter *painter) = 0;
+ virtual void sourceChanged(ChangeFlags flags);
+ void updateBoundingRect();
+
+ bool sourceIsPixmap() const;
+ QRectF sourceBoundingRect(Qt::CoordinateSystem system = Qt::LogicalCoordinates) const;
+ void drawSource(QPainter *painter);
+ QPixmap sourcePixmap(Qt::CoordinateSystem system = Qt::LogicalCoordinates,
+ QPoint *offset = 0,
+ PixmapPadMode mode = PadToEffectiveBoundingRect) const;
+
+private:
+ Q_DECLARE_PRIVATE(QGraphicsEffect)
+ Q_DISABLE_COPY(QGraphicsEffect)
+ friend class QGraphicsItem;
+ friend class QGraphicsItemPrivate;
+ friend class QGraphicsScenePrivate;
+ friend class QWidget;
+ friend class QWidgetPrivate;
+
+public:
+ QGraphicsEffectSource *source() const; // internal
+
+};
+Q_DECLARE_OPERATORS_FOR_FLAGS(QGraphicsEffect::ChangeFlags)
+
+class QGraphicsColorizeEffectPrivate;
+class Q_WIDGETS_EXPORT QGraphicsColorizeEffect: public QGraphicsEffect
+{
+ Q_OBJECT
+ Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
+ Q_PROPERTY(qreal strength READ strength WRITE setStrength NOTIFY strengthChanged)
+public:
+ QGraphicsColorizeEffect(QObject *parent = 0);
+ ~QGraphicsColorizeEffect();
+
+ QColor color() const;
+ qreal strength() const;
+
+public Q_SLOTS:
+ void setColor(const QColor &c);
+ void setStrength(qreal strength);
+
+Q_SIGNALS:
+ void colorChanged(const QColor &color);
+ void strengthChanged(qreal strength);
+
+protected:
+ void draw(QPainter *painter);
+
+private:
+ Q_DECLARE_PRIVATE(QGraphicsColorizeEffect)
+ Q_DISABLE_COPY(QGraphicsColorizeEffect)
+};
+
+class QGraphicsBlurEffectPrivate;
+class Q_WIDGETS_EXPORT QGraphicsBlurEffect: public QGraphicsEffect
+{
+ Q_OBJECT
+ Q_FLAGS(BlurHint BlurHints)
+ Q_PROPERTY(qreal blurRadius READ blurRadius WRITE setBlurRadius NOTIFY blurRadiusChanged)
+ Q_PROPERTY(BlurHints blurHints READ blurHints WRITE setBlurHints NOTIFY blurHintsChanged)
+public:
+ enum BlurHint {
+ PerformanceHint = 0x00,
+ QualityHint = 0x01,
+ AnimationHint = 0x02
+ };
+ Q_DECLARE_FLAGS(BlurHints, BlurHint)
+
+ QGraphicsBlurEffect(QObject *parent = 0);
+ ~QGraphicsBlurEffect();
+
+ QRectF boundingRectFor(const QRectF &rect) const;
+ qreal blurRadius() const;
+ BlurHints blurHints() const;
+
+public Q_SLOTS:
+ void setBlurRadius(qreal blurRadius);
+ void setBlurHints(BlurHints hints);
+
+Q_SIGNALS:
+ void blurRadiusChanged(qreal blurRadius);
+ void blurHintsChanged(BlurHints hints);
+
+protected:
+ void draw(QPainter *painter);
+
+private:
+ Q_DECLARE_PRIVATE(QGraphicsBlurEffect)
+ Q_DISABLE_COPY(QGraphicsBlurEffect)
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QGraphicsBlurEffect::BlurHints)
+
+class QGraphicsDropShadowEffectPrivate;
+class Q_WIDGETS_EXPORT QGraphicsDropShadowEffect: public QGraphicsEffect
+{
+ Q_OBJECT
+ Q_PROPERTY(QPointF offset READ offset WRITE setOffset NOTIFY offsetChanged)
+ Q_PROPERTY(qreal xOffset READ xOffset WRITE setXOffset NOTIFY offsetChanged)
+ Q_PROPERTY(qreal yOffset READ yOffset WRITE setYOffset NOTIFY offsetChanged)
+ Q_PROPERTY(qreal blurRadius READ blurRadius WRITE setBlurRadius NOTIFY blurRadiusChanged)
+ Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
+public:
+ QGraphicsDropShadowEffect(QObject *parent = 0);
+ ~QGraphicsDropShadowEffect();
+
+ QRectF boundingRectFor(const QRectF &rect) const;
+ QPointF offset() const;
+
+ inline qreal xOffset() const
+ { return offset().x(); }
+
+ inline qreal yOffset() const
+ { return offset().y(); }
+
+ qreal blurRadius() const;
+ QColor color() const;
+
+public Q_SLOTS:
+ void setOffset(const QPointF &ofs);
+
+ inline void setOffset(qreal dx, qreal dy)
+ { setOffset(QPointF(dx, dy)); }
+
+ inline void setOffset(qreal d)
+ { setOffset(QPointF(d, d)); }
+
+ inline void setXOffset(qreal dx)
+ { setOffset(QPointF(dx, yOffset())); }
+
+ inline void setYOffset(qreal dy)
+ { setOffset(QPointF(xOffset(), dy)); }
+
+ void setBlurRadius(qreal blurRadius);
+ void setColor(const QColor &color);
+
+Q_SIGNALS:
+ void offsetChanged(const QPointF &offset);
+ void blurRadiusChanged(qreal blurRadius);
+ void colorChanged(const QColor &color);
+
+protected:
+ void draw(QPainter *painter);
+
+private:
+ Q_DECLARE_PRIVATE(QGraphicsDropShadowEffect)
+ Q_DISABLE_COPY(QGraphicsDropShadowEffect)
+};
+
+class QGraphicsOpacityEffectPrivate;
+class Q_WIDGETS_EXPORT QGraphicsOpacityEffect: public QGraphicsEffect
+{
+ Q_OBJECT
+ Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity NOTIFY opacityChanged)
+ Q_PROPERTY(QBrush opacityMask READ opacityMask WRITE setOpacityMask NOTIFY opacityMaskChanged)
+public:
+ QGraphicsOpacityEffect(QObject *parent = 0);
+ ~QGraphicsOpacityEffect();
+
+ qreal opacity() const;
+ QBrush opacityMask() const;
+
+public Q_SLOTS:
+ void setOpacity(qreal opacity);
+ void setOpacityMask(const QBrush &mask);
+
+Q_SIGNALS:
+ void opacityChanged(qreal opacity);
+ void opacityMaskChanged(const QBrush &mask);
+
+protected:
+ void draw(QPainter *painter);
+
+private:
+ Q_DECLARE_PRIVATE(QGraphicsOpacityEffect)
+ Q_DISABLE_COPY(QGraphicsOpacityEffect)
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+#endif //QT_NO_GRAPHICSEFFECT
+
+#endif // QGRAPHICSEFFECT_H
+
diff --git a/src/widgets/effects/qgraphicseffect_p.h b/src/widgets/effects/qgraphicseffect_p.h
new file mode 100644
index 0000000000..ac15f04d05
--- /dev/null
+++ b/src/widgets/effects/qgraphicseffect_p.h
@@ -0,0 +1,231 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGRAPHICSEFFECT_P_H
+#define QGRAPHICSEFFECT_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qgraphicseffect.h"
+
+#include <QPixmapCache>
+
+#include <private/qobject_p.h>
+#include <private/qpixmapfilter_p.h>
+
+#ifndef QT_NO_GRAPHICSEFFECT
+QT_BEGIN_NAMESPACE
+
+class QGraphicsEffectSourcePrivate;
+class Q_WIDGETS_EXPORT QGraphicsEffectSource : public QObject
+{
+ Q_OBJECT
+public:
+ ~QGraphicsEffectSource();
+ const QGraphicsItem *graphicsItem() const;
+ const QWidget *widget() const;
+ const QStyleOption *styleOption() const;
+
+ bool isPixmap() const;
+ void draw(QPainter *painter);
+ void update();
+
+ QRectF boundingRect(Qt::CoordinateSystem coordinateSystem = Qt::LogicalCoordinates) const;
+ QRect deviceRect() const;
+ QPixmap pixmap(Qt::CoordinateSystem system = Qt::LogicalCoordinates,
+ QPoint *offset = 0,
+ QGraphicsEffect::PixmapPadMode mode = QGraphicsEffect::PadToEffectiveBoundingRect) const;
+
+protected:
+ QGraphicsEffectSource(QGraphicsEffectSourcePrivate &dd, QObject *parent = 0);
+
+private:
+ Q_DECLARE_PRIVATE(QGraphicsEffectSource)
+ Q_DISABLE_COPY(QGraphicsEffectSource)
+ friend class QGraphicsEffect;
+ friend class QGraphicsEffectPrivate;
+ friend class QGraphicsScenePrivate;
+ friend class QGraphicsItem;
+ friend class QGraphicsItemPrivate;
+ friend class QWidget;
+ friend class QWidgetPrivate;
+};
+
+class QGraphicsEffectSourcePrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QGraphicsEffectSource)
+public:
+ QGraphicsEffectSourcePrivate()
+ : QObjectPrivate()
+ , m_cachedSystem(Qt::DeviceCoordinates)
+ , m_cachedMode(QGraphicsEffect::PadToTransparentBorder)
+ {}
+
+ enum InvalidateReason
+ {
+ TransformChanged,
+ EffectRectChanged,
+ SourceChanged
+ };
+
+ virtual ~QGraphicsEffectSourcePrivate();
+ virtual void detach() = 0;
+ virtual QRectF boundingRect(Qt::CoordinateSystem system) const = 0;
+ virtual QRect deviceRect() const = 0;
+ virtual const QGraphicsItem *graphicsItem() const = 0;
+ virtual const QWidget *widget() const = 0;
+ virtual const QStyleOption *styleOption() const = 0;
+ virtual void draw(QPainter *p) = 0;
+ virtual void update() = 0;
+ virtual bool isPixmap() const = 0;
+ virtual QPixmap pixmap(Qt::CoordinateSystem system, QPoint *offset = 0,
+ QGraphicsEffect::PixmapPadMode mode = QGraphicsEffect::PadToTransparentBorder) const = 0;
+ virtual void effectBoundingRectChanged() = 0;
+
+ void setCachedOffset(const QPoint &offset);
+ void invalidateCache(InvalidateReason reason = SourceChanged) const;
+ Qt::CoordinateSystem currentCachedSystem() const { return m_cachedSystem; }
+ QGraphicsEffect::PixmapPadMode currentCachedMode() const { return m_cachedMode; }
+
+ friend class QGraphicsScenePrivate;
+ friend class QGraphicsItem;
+ friend class QGraphicsItemPrivate;
+
+private:
+ mutable Qt::CoordinateSystem m_cachedSystem;
+ mutable QGraphicsEffect::PixmapPadMode m_cachedMode;
+ mutable QPoint m_cachedOffset;
+ mutable QPixmapCache::Key m_cacheKey;
+};
+
+class Q_WIDGETS_EXPORT QGraphicsEffectPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QGraphicsEffect)
+public:
+ QGraphicsEffectPrivate() : source(0), isEnabled(1) {}
+
+ inline void setGraphicsEffectSource(QGraphicsEffectSource *newSource)
+ {
+ QGraphicsEffect::ChangeFlags flags;
+ if (source) {
+ flags |= QGraphicsEffect::SourceDetached;
+ source->d_func()->invalidateCache();
+ source->d_func()->detach();
+ delete source;
+ }
+ source = newSource;
+ if (newSource)
+ flags |= QGraphicsEffect::SourceAttached;
+ q_func()->sourceChanged(flags);
+ }
+
+ QGraphicsEffectSource *source;
+ QRectF boundingRect;
+ quint32 isEnabled : 1;
+ quint32 padding : 31; // feel free to use
+};
+
+
+class QGraphicsColorizeEffectPrivate : public QGraphicsEffectPrivate
+{
+ Q_DECLARE_PUBLIC(QGraphicsColorizeEffect)
+public:
+ QGraphicsColorizeEffectPrivate()
+ : opaque(true)
+ {
+ filter = new QPixmapColorizeFilter;
+ }
+ ~QGraphicsColorizeEffectPrivate() { delete filter; }
+
+ QPixmapColorizeFilter *filter;
+ quint32 opaque : 1;
+ quint32 padding : 31;
+};
+
+class QGraphicsBlurEffectPrivate : public QGraphicsEffectPrivate
+{
+ Q_DECLARE_PUBLIC(QGraphicsBlurEffect)
+public:
+ QGraphicsBlurEffectPrivate() : filter(new QPixmapBlurFilter) {}
+ ~QGraphicsBlurEffectPrivate() { delete filter; }
+
+ QPixmapBlurFilter *filter;
+};
+
+class QGraphicsDropShadowEffectPrivate : public QGraphicsEffectPrivate
+{
+ Q_DECLARE_PUBLIC(QGraphicsDropShadowEffect)
+public:
+ QGraphicsDropShadowEffectPrivate() : filter(new QPixmapDropShadowFilter) {}
+ ~QGraphicsDropShadowEffectPrivate() { delete filter; }
+
+ QPixmapDropShadowFilter *filter;
+};
+
+class QGraphicsOpacityEffectPrivate : public QGraphicsEffectPrivate
+{
+ Q_DECLARE_PUBLIC(QGraphicsOpacityEffect)
+public:
+ QGraphicsOpacityEffectPrivate()
+ : opacity(qreal(0.7)), isFullyTransparent(0), isFullyOpaque(0), hasOpacityMask(0) {}
+ ~QGraphicsOpacityEffectPrivate() {}
+
+ qreal opacity;
+ QBrush opacityMask;
+ uint isFullyTransparent : 1;
+ uint isFullyOpaque : 1;
+ uint hasOpacityMask : 1;
+};
+
+QT_END_NAMESPACE
+
+#endif //QT_NO_GRAPHICSEFFECT
+#endif // QGRAPHICSEFFECT_P_H
+
diff --git a/src/widgets/effects/qpixmapfilter.cpp b/src/widgets/effects/qpixmapfilter.cpp
new file mode 100644
index 0000000000..9cdedc19a3
--- /dev/null
+++ b/src/widgets/effects/qpixmapfilter.cpp
@@ -0,0 +1,1381 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qglobal.h>
+
+#include <QDebug>
+
+#include "qpainter.h"
+#include "qpixmap.h"
+#include "qpixmapfilter_p.h"
+#include "qvarlengtharray.h"
+
+#include "private/qguiapplication_p.h"
+#include "private/qpaintengineex_p.h"
+#include "private/qpaintengine_raster_p.h"
+#include "qmath.h"
+#include "private/qmath_p.h"
+#include "private/qmemrotate_p.h"
+#include "private/qdrawhelper_p.h"
+
+#ifndef QT_NO_GRAPHICSEFFECT
+QT_BEGIN_NAMESPACE
+
+class QPixmapFilterPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QPixmapFilter)
+public:
+ QPixmapFilter::FilterType type;
+};
+
+/*!
+ \class QPixmapFilter
+ \since 4.5
+ \ingroup painting
+
+ \brief The QPixmapFilter class provides the basic functionality for
+ pixmap filter classes. Pixmap filter can be for example colorize or blur.
+
+ QPixmapFilter is the base class for every pixmap filter. QPixmapFilter is
+ an abstract class and cannot itself be instantiated. It provides a standard
+ interface for filter processing.
+
+ \internal
+*/
+
+/*!
+ \enum QPixmapFilter::FilterType
+
+ \internal
+
+ This enum describes the types of filter that can be applied to pixmaps.
+
+ \value ConvolutionFilter A filter that is used to calculate the convolution
+ of the image with a kernel. See
+ QPixmapConvolutionFilter for more information.
+ \value ColorizeFilter A filter that is used to change the overall color
+ of an image. See QPixmapColorizeFilter for more
+ information.
+ \value DropShadowFilter A filter that is used to add a drop shadow to an
+ image. See QPixmapDropShadowFilter for more
+ information.
+ \value BlurFilter A filter that is used to blur an image using
+ a simple blur radius. See QPixmapBlurFilter
+ for more information.
+
+ \value UserFilter The first filter type that can be used for
+ application-specific purposes.
+*/
+
+
+/*!
+ Constructs a default QPixmapFilter with the given \a type.
+
+ This constructor should be used when subclassing QPixmapFilter to
+ create custom user filters.
+
+ \internal
+*/
+QPixmapFilter::QPixmapFilter(FilterType type, QObject *parent)
+ : QObject(*new QPixmapFilterPrivate, parent)
+{
+ d_func()->type = type;
+}
+
+
+
+/*!
+ \internal
+*/
+QPixmapFilter::QPixmapFilter(QPixmapFilterPrivate&d, QPixmapFilter::FilterType type, QObject *parent)
+ : QObject(d, parent)
+{
+ d_func()->type = type;
+}
+
+
+/*!
+ Destroys the pixmap filter.
+
+ \internal
+*/
+QPixmapFilter::~QPixmapFilter()
+{
+}
+
+/*!
+ Returns the type of the filter. All standard pixmap filter classes
+ are associated with a unique value.
+
+ \internal
+*/
+QPixmapFilter::FilterType QPixmapFilter::type() const
+{
+ Q_D(const QPixmapFilter);
+ return d->type;
+}
+
+/*!
+ Returns the bounding rectangle that is affected by the pixmap
+ filter if the filter is applied to the specified \a rect.
+
+ \internal
+*/
+QRectF QPixmapFilter::boundingRectFor(const QRectF &rect) const
+{
+ return rect;
+}
+
+/*!
+ \fn void QPixmapFilter::draw(QPainter *painter, const QPointF &p, const QPixmap &src, const QRectF& srcRect) const
+
+ Uses \a painter to draw filtered result of \a src at the point
+ specified by \a p. If \a srcRect is specified the it will
+ be used as a source rectangle to only draw a part of the source.
+
+ draw() will affect the area which boundingRectFor() returns.
+
+ \internal
+*/
+
+/*!
+ \class QPixmapConvolutionFilter
+ \since 4.5
+ \ingroup painting
+
+ \brief The QPixmapConvolutionFilter class provides convolution
+ filtering for pixmaps.
+
+ QPixmapConvolutionFilter implements a convolution pixmap filter,
+ which is applied when \l{QPixmapFilter::}{draw()} is called. A
+ convolution filter lets you distort an image by setting the values
+ of a matrix of qreal values called its
+ \l{setConvolutionKernel()}{kernel}. The matrix's values are
+ usually between -1.0 and 1.0.
+
+ \omit
+ In convolution filtering, the pixel value is calculated from the
+ neighboring pixels based on the weighting convolution kernel.
+ This needs explaining to be useful.
+ \endomit
+
+ Example:
+ \snippet doc/src/snippets/code/src_gui_image_qpixmapfilter.cpp 1
+
+ \sa {Pixmap Filters Example}, QPixmapColorizeFilter, QPixmapDropShadowFilter
+
+
+ \internal
+*/
+
+class QPixmapConvolutionFilterPrivate : public QPixmapFilterPrivate
+{
+public:
+ QPixmapConvolutionFilterPrivate(): convolutionKernel(0), kernelWidth(0), kernelHeight(0), convoluteAlpha(false) {}
+ ~QPixmapConvolutionFilterPrivate() {
+ delete[] convolutionKernel;
+ }
+
+ qreal *convolutionKernel;
+ int kernelWidth;
+ int kernelHeight;
+ bool convoluteAlpha;
+};
+
+
+/*!
+ Constructs a pixmap convolution filter.
+
+ By default there is no convolution kernel.
+
+ \internal
+*/
+QPixmapConvolutionFilter::QPixmapConvolutionFilter(QObject *parent)
+ : QPixmapFilter(*new QPixmapConvolutionFilterPrivate, ConvolutionFilter, parent)
+{
+ Q_D(QPixmapConvolutionFilter);
+ d->convoluteAlpha = true;
+}
+
+/*!
+ Destructor of pixmap convolution filter.
+
+ \internal
+*/
+QPixmapConvolutionFilter::~QPixmapConvolutionFilter()
+{
+}
+
+/*!
+ Sets convolution kernel with the given number of \a rows and \a columns.
+ Values from \a kernel are copied to internal data structure.
+
+ To preserve the intensity of the pixmap, the sum of all the
+ values in the convolution kernel should add up to 1.0. A sum
+ greater than 1.0 produces a lighter result and a sum less than 1.0
+ produces a darker and transparent result.
+
+ \internal
+*/
+void QPixmapConvolutionFilter::setConvolutionKernel(const qreal *kernel, int rows, int columns)
+{
+ Q_D(QPixmapConvolutionFilter);
+ delete [] d->convolutionKernel;
+ d->convolutionKernel = new qreal[rows * columns];
+ memcpy(d->convolutionKernel, kernel, sizeof(qreal) * rows * columns);
+ d->kernelWidth = columns;
+ d->kernelHeight = rows;
+}
+
+/*!
+ Gets the convolution kernel data.
+
+ \internal
+*/
+const qreal *QPixmapConvolutionFilter::convolutionKernel() const
+{
+ Q_D(const QPixmapConvolutionFilter);
+ return d->convolutionKernel;
+}
+
+/*!
+ Gets the number of rows in the convolution kernel.
+
+ \internal
+*/
+int QPixmapConvolutionFilter::rows() const
+{
+ Q_D(const QPixmapConvolutionFilter);
+ return d->kernelHeight;
+}
+
+/*!
+ Gets the number of columns in the convolution kernel.
+
+ \internal
+*/
+int QPixmapConvolutionFilter::columns() const
+{
+ Q_D(const QPixmapConvolutionFilter);
+ return d->kernelWidth;
+}
+
+
+/*!
+ \internal
+*/
+QRectF QPixmapConvolutionFilter::boundingRectFor(const QRectF &rect) const
+{
+ Q_D(const QPixmapConvolutionFilter);
+ return rect.adjusted(-d->kernelWidth / 2, -d->kernelHeight / 2, (d->kernelWidth - 1) / 2, (d->kernelHeight - 1) / 2);
+}
+
+// Convolutes the image
+static void convolute(
+ QImage *destImage,
+ const QPointF &pos,
+ const QImage &srcImage,
+ const QRectF &srcRect,
+ QPainter::CompositionMode mode,
+ qreal *kernel,
+ int kernelWidth,
+ int kernelHeight )
+{
+ const QImage processImage = (srcImage.format() != QImage::Format_ARGB32_Premultiplied ) ? srcImage.convertToFormat(QImage::Format_ARGB32_Premultiplied) : srcImage;
+ // TODO: support also other formats directly without copying
+
+ int *fixedKernel = new int[kernelWidth*kernelHeight];
+ for(int i = 0; i < kernelWidth*kernelHeight; i++)
+ {
+ fixedKernel[i] = (int)(65536 * kernel[i]);
+ }
+ QRectF trect = srcRect.isNull() ? processImage.rect() : srcRect;
+ trect.moveTo(pos);
+ QRectF bounded = trect.adjusted(-kernelWidth / 2, -kernelHeight / 2, (kernelWidth - 1) / 2, (kernelHeight - 1) / 2);
+ QRect rect = bounded.toAlignedRect();
+ QRect targetRect = rect.intersected(destImage->rect());
+
+ QRectF srect = srcRect.isNull() ? processImage.rect() : srcRect;
+ QRectF sbounded = srect.adjusted(-kernelWidth / 2, -kernelHeight / 2, (kernelWidth - 1) / 2, (kernelHeight - 1) / 2);
+ QPoint srcStartPoint = sbounded.toAlignedRect().topLeft()+(targetRect.topLeft()-rect.topLeft());
+
+ const uint *sourceStart = (uint*)processImage.scanLine(0);
+ uint *outputStart = (uint*)destImage->scanLine(0);
+
+ int yk = srcStartPoint.y();
+ for (int y = targetRect.top(); y <= targetRect.bottom(); y++) {
+ uint* output = outputStart + (destImage->bytesPerLine()/sizeof(uint))*y+targetRect.left();
+ int xk = srcStartPoint.x();
+ for(int x = targetRect.left(); x <= targetRect.right(); x++) {
+ int r = 0;
+ int g = 0;
+ int b = 0;
+ int a = 0;
+
+ // some out of bounds pre-checking to avoid inner-loop ifs
+ int kernely = -kernelHeight/2;
+ int starty = 0;
+ int endy = kernelHeight;
+ if(yk+kernely+endy >= srcImage.height())
+ endy = kernelHeight-((yk+kernely+endy)-srcImage.height())-1;
+ if(yk+kernely < 0)
+ starty = -(yk+kernely);
+
+ int kernelx = -kernelWidth/2;
+ int startx = 0;
+ int endx = kernelWidth;
+ if(xk+kernelx+endx >= srcImage.width())
+ endx = kernelWidth-((xk+kernelx+endx)-srcImage.width())-1;
+ if(xk+kernelx < 0)
+ startx = -(xk+kernelx);
+
+ for (int ys = starty; ys < endy; ys ++) {
+ const uint *pix = sourceStart + (processImage.bytesPerLine()/sizeof(uint))*(yk+kernely+ys) + ((xk+kernelx+startx));
+ const uint *endPix = pix+endx-startx;
+ int kernelPos = ys*kernelWidth+startx;
+ while (pix < endPix) {
+ int factor = fixedKernel[kernelPos++];
+ a += (((*pix) & 0xff000000)>>24) * factor;
+ r += (((*pix) & 0x00ff0000)>>16) * factor;
+ g += (((*pix) & 0x0000ff00)>>8 ) * factor;
+ b += (((*pix) & 0x000000ff) ) * factor;
+ pix++;
+ }
+ }
+
+ r = qBound((int)0, r >> 16, (int)255);
+ g = qBound((int)0, g >> 16, (int)255);
+ b = qBound((int)0, b >> 16, (int)255);
+ a = qBound((int)0, a >> 16, (int)255);
+ // composition mode checking could be moved outside of loop
+ if(mode == QPainter::CompositionMode_Source) {
+ uint color = (a<<24)+(r<<16)+(g<<8)+b;
+ *output++ = color;
+ } else {
+ uint current = *output;
+ uchar ca = (current&0xff000000)>>24;
+ uchar cr = (current&0x00ff0000)>>16;
+ uchar cg = (current&0x0000ff00)>>8;
+ uchar cb = (current&0x000000ff);
+ uint color =
+ (((ca*(255-a) >> 8)+a) << 24)+
+ (((cr*(255-a) >> 8)+r) << 16)+
+ (((cg*(255-a) >> 8)+g) << 8)+
+ (((cb*(255-a) >> 8)+b));
+ *output++ = color;;
+ }
+ xk++;
+ }
+ yk++;
+ }
+ delete[] fixedKernel;
+}
+
+/*!
+ \internal
+*/
+void QPixmapConvolutionFilter::draw(QPainter *painter, const QPointF &p, const QPixmap &src, const QRectF& srcRect) const
+{
+ Q_D(const QPixmapConvolutionFilter);
+ if (!painter->isActive())
+ return;
+
+ if(d->kernelWidth<=0 || d->kernelHeight <= 0)
+ return;
+
+ if (src.isNull())
+ return;
+
+ QPixmapFilter *filter = painter->paintEngine() && painter->paintEngine()->isExtended() ?
+ static_cast<QPaintEngineEx *>(painter->paintEngine())->pixmapFilter(type(), this) : 0;
+ QPixmapConvolutionFilter *convolutionFilter = static_cast<QPixmapConvolutionFilter*>(filter);
+ if (convolutionFilter) {
+ convolutionFilter->setConvolutionKernel(d->convolutionKernel, d->kernelWidth, d->kernelHeight);
+ convolutionFilter->d_func()->convoluteAlpha = d->convoluteAlpha;
+ convolutionFilter->draw(painter, p, src, srcRect);
+ return;
+ }
+
+ // falling back to raster implementation
+
+ QImage *target = 0;
+ if (painter->paintEngine()->paintDevice()->devType() == QInternal::Image) {
+ target = static_cast<QImage *>(painter->paintEngine()->paintDevice());
+
+ QTransform mat = painter->combinedTransform();
+
+ if (mat.type() > QTransform::TxTranslate) {
+ // Disabled because of transformation...
+ target = 0;
+ } else {
+ QRasterPaintEngine *pe = static_cast<QRasterPaintEngine *>(painter->paintEngine());
+ if (pe->clipType() == QRasterPaintEngine::ComplexClip)
+ // disabled because of complex clipping...
+ target = 0;
+ else {
+ QRectF clip = pe->clipBoundingRect();
+ QRectF rect = boundingRectFor(srcRect.isEmpty() ? src.rect() : srcRect);
+ QTransform x = painter->deviceTransform();
+ if (!clip.contains(rect.translated(x.dx() + p.x(), x.dy() + p.y()))) {
+ target = 0;
+ }
+
+ }
+ }
+ }
+
+ if (target) {
+ QTransform x = painter->deviceTransform();
+ QPointF offset(x.dx(), x.dy());
+
+ convolute(target, p+offset, src.toImage(), srcRect, QPainter::CompositionMode_SourceOver, d->convolutionKernel, d->kernelWidth, d->kernelHeight);
+ } else {
+ QRect srect = srcRect.isNull() ? src.rect() : srcRect.toRect();
+ QRect rect = boundingRectFor(srect).toRect();
+ QImage result = QImage(rect.size(), QImage::Format_ARGB32_Premultiplied);
+ QPoint offset = srect.topLeft() - rect.topLeft();
+ convolute(&result,
+ offset,
+ src.toImage(),
+ srect,
+ QPainter::CompositionMode_Source,
+ d->convolutionKernel,
+ d->kernelWidth,
+ d->kernelHeight);
+ painter->drawImage(p - offset, result);
+ }
+}
+
+/*!
+ \class QPixmapBlurFilter
+ \since 4.6
+ \ingroup multimedia
+
+ \brief The QPixmapBlurFilter class provides blur filtering
+ for pixmaps.
+
+ QPixmapBlurFilter implements a blur pixmap filter,
+ which is applied when \l{QPixmapFilter::}{draw()} is called.
+
+ The filter lets you specialize the radius of the blur as well
+ as hints as to whether to prefer performance or quality.
+
+ By default, the blur effect is produced by applying an exponential
+ filter generated from the specified blurRadius(). Paint engines
+ may override this with a custom blur that is faster on the
+ underlying hardware.
+
+ \sa {Pixmap Filters Example}, QPixmapConvolutionFilter, QPixmapDropShadowFilter
+
+ \internal
+*/
+
+class QPixmapBlurFilterPrivate : public QPixmapFilterPrivate
+{
+public:
+ QPixmapBlurFilterPrivate() : radius(5), hints(QGraphicsBlurEffect::PerformanceHint) {}
+
+ qreal radius;
+ QGraphicsBlurEffect::BlurHints hints;
+};
+
+
+/*!
+ Constructs a pixmap blur filter.
+
+ \internal
+*/
+QPixmapBlurFilter::QPixmapBlurFilter(QObject *parent)
+ : QPixmapFilter(*new QPixmapBlurFilterPrivate, BlurFilter, parent)
+{
+}
+
+/*!
+ Destructor of pixmap blur filter.
+
+ \internal
+*/
+QPixmapBlurFilter::~QPixmapBlurFilter()
+{
+}
+
+/*!
+ Sets the radius of the blur filter. Higher radius produces increased blurriness.
+
+ \internal
+*/
+void QPixmapBlurFilter::setRadius(qreal radius)
+{
+ Q_D(QPixmapBlurFilter);
+ d->radius = radius;
+}
+
+/*!
+ Gets the radius of the blur filter.
+
+ \internal
+*/
+qreal QPixmapBlurFilter::radius() const
+{
+ Q_D(const QPixmapBlurFilter);
+ return d->radius;
+}
+
+/*!
+ Setting the blur hints to PerformanceHint causes the implementation
+ to trade off visual quality to blur the image faster. Setting the
+ blur hints to QualityHint causes the implementation to improve
+ visual quality at the expense of speed.
+
+ AnimationHint causes the implementation to optimize for animating
+ the blur radius, possibly by caching blurred versions of the source
+ pixmap.
+
+ The implementation is free to ignore this value if it only has a single
+ blur algorithm.
+
+ \internal
+*/
+void QPixmapBlurFilter::setBlurHints(QGraphicsBlurEffect::BlurHints hints)
+{
+ Q_D(QPixmapBlurFilter);
+ d->hints = hints;
+}
+
+/*!
+ Gets the blur hints of the blur filter.
+
+ \internal
+*/
+QGraphicsBlurEffect::BlurHints QPixmapBlurFilter::blurHints() const
+{
+ Q_D(const QPixmapBlurFilter);
+ return d->hints;
+}
+
+const qreal radiusScale = qreal(2.5);
+
+/*!
+ \internal
+*/
+QRectF QPixmapBlurFilter::boundingRectFor(const QRectF &rect) const
+{
+ Q_D(const QPixmapBlurFilter);
+ const qreal delta = radiusScale * d->radius + 1;
+ return rect.adjusted(-delta, -delta, delta, delta);
+}
+
+template <int shift>
+inline int qt_static_shift(int value)
+{
+ if (shift == 0)
+ return value;
+ else if (shift > 0)
+ return value << (uint(shift) & 0x1f);
+ else
+ return value >> (uint(-shift) & 0x1f);
+}
+
+template<int aprec, int zprec>
+inline void qt_blurinner(uchar *bptr, int &zR, int &zG, int &zB, int &zA, int alpha)
+{
+ QRgb *pixel = (QRgb *)bptr;
+
+#define Z_MASK (0xff << zprec)
+ const int A_zprec = qt_static_shift<zprec - 24>(*pixel) & Z_MASK;
+ const int R_zprec = qt_static_shift<zprec - 16>(*pixel) & Z_MASK;
+ const int G_zprec = qt_static_shift<zprec - 8>(*pixel) & Z_MASK;
+ const int B_zprec = qt_static_shift<zprec>(*pixel) & Z_MASK;
+#undef Z_MASK
+
+ const int zR_zprec = zR >> aprec;
+ const int zG_zprec = zG >> aprec;
+ const int zB_zprec = zB >> aprec;
+ const int zA_zprec = zA >> aprec;
+
+ zR += alpha * (R_zprec - zR_zprec);
+ zG += alpha * (G_zprec - zG_zprec);
+ zB += alpha * (B_zprec - zB_zprec);
+ zA += alpha * (A_zprec - zA_zprec);
+
+#define ZA_MASK (0xff << (zprec + aprec))
+ *pixel =
+ qt_static_shift<24 - zprec - aprec>(zA & ZA_MASK)
+ | qt_static_shift<16 - zprec - aprec>(zR & ZA_MASK)
+ | qt_static_shift<8 - zprec - aprec>(zG & ZA_MASK)
+ | qt_static_shift<-zprec - aprec>(zB & ZA_MASK);
+#undef ZA_MASK
+}
+
+const int alphaIndex = (QSysInfo::ByteOrder == QSysInfo::BigEndian ? 0 : 3);
+
+template<int aprec, int zprec>
+inline void qt_blurinner_alphaOnly(uchar *bptr, int &z, int alpha)
+{
+ const int A_zprec = int(*(bptr)) << zprec;
+ const int z_zprec = z >> aprec;
+ z += alpha * (A_zprec - z_zprec);
+ *(bptr) = z >> (zprec + aprec);
+}
+
+template<int aprec, int zprec, bool alphaOnly>
+inline void qt_blurrow(QImage & im, int line, int alpha)
+{
+ uchar *bptr = im.scanLine(line);
+
+ int zR = 0, zG = 0, zB = 0, zA = 0;
+
+ if (alphaOnly && im.format() != QImage::Format_Indexed8)
+ bptr += alphaIndex;
+
+ const int stride = im.depth() >> 3;
+ const int im_width = im.width();
+ for (int index = 0; index < im_width; ++index) {
+ if (alphaOnly)
+ qt_blurinner_alphaOnly<aprec, zprec>(bptr, zA, alpha);
+ else
+ qt_blurinner<aprec, zprec>(bptr, zR, zG, zB, zA, alpha);
+ bptr += stride;
+ }
+
+ bptr -= stride;
+
+ for (int index = im_width - 2; index >= 0; --index) {
+ bptr -= stride;
+ if (alphaOnly)
+ qt_blurinner_alphaOnly<aprec, zprec>(bptr, zA, alpha);
+ else
+ qt_blurinner<aprec, zprec>(bptr, zR, zG, zB, zA, alpha);
+ }
+}
+
+/*
+* expblur(QImage &img, int radius)
+*
+* Based on exponential blur algorithm by Jani Huhtanen
+*
+* In-place blur of image 'img' with kernel
+* of approximate radius 'radius'.
+*
+* Blurs with two sided exponential impulse
+* response.
+*
+* aprec = precision of alpha parameter
+* in fixed-point format 0.aprec
+*
+* zprec = precision of state parameters
+* zR,zG,zB and zA in fp format 8.zprec
+*/
+template <int aprec, int zprec, bool alphaOnly>
+void expblur(QImage &img, qreal radius, bool improvedQuality = false, int transposed = 0)
+{
+ // halve the radius if we're using two passes
+ if (improvedQuality)
+ radius *= qreal(0.5);
+
+ Q_ASSERT(img.format() == QImage::Format_ARGB32_Premultiplied
+ || img.format() == QImage::Format_RGB32
+ || img.format() == QImage::Format_Indexed8);
+
+ // choose the alpha such that pixels at radius distance from a fully
+ // saturated pixel will have an alpha component of no greater than
+ // the cutOffIntensity
+ const qreal cutOffIntensity = 2;
+ int alpha = radius <= qreal(1e-5)
+ ? ((1 << aprec)-1)
+ : qRound((1<<aprec)*(1 - qPow(cutOffIntensity * (1 / qreal(255)), 1 / radius)));
+
+ int img_height = img.height();
+ for (int row = 0; row < img_height; ++row) {
+ for (int i = 0; i <= int(improvedQuality); ++i)
+ qt_blurrow<aprec, zprec, alphaOnly>(img, row, alpha);
+ }
+
+ QImage temp(img.height(), img.width(), img.format());
+ if (transposed >= 0) {
+ if (img.depth() == 8) {
+ qt_memrotate270(reinterpret_cast<const quint8*>(img.bits()),
+ img.width(), img.height(), img.bytesPerLine(),
+ reinterpret_cast<quint8*>(temp.bits()),
+ temp.bytesPerLine());
+ } else {
+ qt_memrotate270(reinterpret_cast<const quint32*>(img.bits()),
+ img.width(), img.height(), img.bytesPerLine(),
+ reinterpret_cast<quint32*>(temp.bits()),
+ temp.bytesPerLine());
+ }
+ } else {
+ if (img.depth() == 8) {
+ qt_memrotate90(reinterpret_cast<const quint8*>(img.bits()),
+ img.width(), img.height(), img.bytesPerLine(),
+ reinterpret_cast<quint8*>(temp.bits()),
+ temp.bytesPerLine());
+ } else {
+ qt_memrotate90(reinterpret_cast<const quint32*>(img.bits()),
+ img.width(), img.height(), img.bytesPerLine(),
+ reinterpret_cast<quint32*>(temp.bits()),
+ temp.bytesPerLine());
+ }
+ }
+
+ img_height = temp.height();
+ for (int row = 0; row < img_height; ++row) {
+ for (int i = 0; i <= int(improvedQuality); ++i)
+ qt_blurrow<aprec, zprec, alphaOnly>(temp, row, alpha);
+ }
+
+ if (transposed == 0) {
+ if (img.depth() == 8) {
+ qt_memrotate90(reinterpret_cast<const quint8*>(temp.bits()),
+ temp.width(), temp.height(), temp.bytesPerLine(),
+ reinterpret_cast<quint8*>(img.bits()),
+ img.bytesPerLine());
+ } else {
+ qt_memrotate90(reinterpret_cast<const quint32*>(temp.bits()),
+ temp.width(), temp.height(), temp.bytesPerLine(),
+ reinterpret_cast<quint32*>(img.bits()),
+ img.bytesPerLine());
+ }
+ } else {
+ img = temp;
+ }
+}
+#define AVG(a,b) ( ((((a)^(b)) & 0xfefefefeUL) >> 1) + ((a)&(b)) )
+#define AVG16(a,b) ( ((((a)^(b)) & 0xf7deUL) >> 1) + ((a)&(b)) )
+
+Q_WIDGETS_EXPORT QImage qt_halfScaled(const QImage &source)
+{
+ if (source.width() < 2 || source.height() < 2)
+ return QImage();
+
+ QImage srcImage = source;
+
+ if (source.format() == QImage::Format_Indexed8) {
+ // assumes grayscale
+ QImage dest(source.width() / 2, source.height() / 2, srcImage.format());
+
+ const uchar *src = reinterpret_cast<const uchar*>(const_cast<const QImage &>(srcImage).bits());
+ int sx = srcImage.bytesPerLine();
+ int sx2 = sx << 1;
+
+ uchar *dst = reinterpret_cast<uchar*>(dest.bits());
+ int dx = dest.bytesPerLine();
+ int ww = dest.width();
+ int hh = dest.height();
+
+ for (int y = hh; y; --y, dst += dx, src += sx2) {
+ const uchar *p1 = src;
+ const uchar *p2 = src + sx;
+ uchar *q = dst;
+ for (int x = ww; x; --x, ++q, p1 += 2, p2 += 2)
+ *q = ((int(p1[0]) + int(p1[1]) + int(p2[0]) + int(p2[1])) + 2) >> 2;
+ }
+
+ return dest;
+ } else if (source.format() == QImage::Format_ARGB8565_Premultiplied) {
+ QImage dest(source.width() / 2, source.height() / 2, srcImage.format());
+
+ const uchar *src = reinterpret_cast<const uchar*>(const_cast<const QImage &>(srcImage).bits());
+ int sx = srcImage.bytesPerLine();
+ int sx2 = sx << 1;
+
+ uchar *dst = reinterpret_cast<uchar*>(dest.bits());
+ int dx = dest.bytesPerLine();
+ int ww = dest.width();
+ int hh = dest.height();
+
+ for (int y = hh; y; --y, dst += dx, src += sx2) {
+ const uchar *p1 = src;
+ const uchar *p2 = src + sx;
+ uchar *q = dst;
+ for (int x = ww; x; --x, q += 3, p1 += 6, p2 += 6) {
+ // alpha
+ q[0] = AVG(AVG(p1[0], p1[3]), AVG(p2[0], p2[3]));
+ // rgb
+ const quint16 p16_1 = (p1[2] << 8) | p1[1];
+ const quint16 p16_2 = (p1[5] << 8) | p1[4];
+ const quint16 p16_3 = (p2[2] << 8) | p2[1];
+ const quint16 p16_4 = (p2[5] << 8) | p2[4];
+ const quint16 result = AVG16(AVG16(p16_1, p16_2), AVG16(p16_3, p16_4));
+ q[1] = result & 0xff;
+ q[2] = result >> 8;
+ }
+ }
+
+ return dest;
+ } else if (source.format() != QImage::Format_ARGB32_Premultiplied
+ && source.format() != QImage::Format_RGB32)
+ {
+ srcImage = source.convertToFormat(QImage::Format_ARGB32_Premultiplied);
+ }
+
+ QImage dest(source.width() / 2, source.height() / 2, srcImage.format());
+
+ const quint32 *src = reinterpret_cast<const quint32*>(const_cast<const QImage &>(srcImage).bits());
+ int sx = srcImage.bytesPerLine() >> 2;
+ int sx2 = sx << 1;
+
+ quint32 *dst = reinterpret_cast<quint32*>(dest.bits());
+ int dx = dest.bytesPerLine() >> 2;
+ int ww = dest.width();
+ int hh = dest.height();
+
+ for (int y = hh; y; --y, dst += dx, src += sx2) {
+ const quint32 *p1 = src;
+ const quint32 *p2 = src + sx;
+ quint32 *q = dst;
+ for (int x = ww; x; --x, q++, p1 += 2, p2 += 2)
+ *q = AVG(AVG(p1[0], p1[1]), AVG(p2[0], p2[1]));
+ }
+
+ return dest;
+}
+
+Q_WIDGETS_EXPORT void qt_blurImage(QPainter *p, QImage &blurImage, qreal radius, bool quality, bool alphaOnly, int transposed = 0)
+{
+ if (blurImage.format() != QImage::Format_ARGB32_Premultiplied
+ && blurImage.format() != QImage::Format_RGB32)
+ {
+ blurImage = blurImage.convertToFormat(QImage::Format_ARGB32_Premultiplied);
+ }
+
+ qreal scale = 1;
+ if (radius >= 4 && blurImage.width() >= 2 && blurImage.height() >= 2) {
+ blurImage = qt_halfScaled(blurImage);
+ scale = 2;
+ radius *= qreal(0.5);
+ }
+
+ if (alphaOnly)
+ expblur<12, 10, true>(blurImage, radius, quality, transposed);
+ else
+ expblur<12, 10, false>(blurImage, radius, quality, transposed);
+
+ if (p) {
+ p->scale(scale, scale);
+ p->setRenderHint(QPainter::SmoothPixmapTransform);
+ p->drawImage(QRect(0, 0, blurImage.width(), blurImage.height()), blurImage);
+ }
+}
+
+Q_WIDGETS_EXPORT void qt_blurImage(QImage &blurImage, qreal radius, bool quality, int transposed = 0)
+{
+ if (blurImage.format() == QImage::Format_Indexed8)
+ expblur<12, 10, true>(blurImage, radius, quality, transposed);
+ else
+ expblur<12, 10, false>(blurImage, radius, quality, transposed);
+}
+
+Q_GUI_EXPORT extern bool qt_scaleForTransform(const QTransform &transform, qreal *scale);
+
+/*!
+ \internal
+*/
+void QPixmapBlurFilter::draw(QPainter *painter, const QPointF &p, const QPixmap &src, const QRectF &rect) const
+{
+ Q_D(const QPixmapBlurFilter);
+ if (!painter->isActive())
+ return;
+
+ if (src.isNull())
+ return;
+
+ QRectF srcRect = rect;
+ if (srcRect.isNull())
+ srcRect = src.rect();
+
+ if (d->radius <= 1) {
+ painter->drawPixmap(srcRect.translated(p), src, srcRect);
+ return;
+ }
+
+ qreal scaledRadius = radiusScale * d->radius;
+ qreal scale;
+ if (qt_scaleForTransform(painter->transform(), &scale))
+ scaledRadius /= scale;
+
+ QPixmapFilter *filter = painter->paintEngine() && painter->paintEngine()->isExtended() ?
+ static_cast<QPaintEngineEx *>(painter->paintEngine())->pixmapFilter(type(), this) : 0;
+ QPixmapBlurFilter *blurFilter = static_cast<QPixmapBlurFilter*>(filter);
+ if (blurFilter) {
+ blurFilter->setRadius(scaledRadius);
+ blurFilter->setBlurHints(d->hints);
+ blurFilter->draw(painter, p, src, srcRect);
+ return;
+ }
+
+ QImage srcImage;
+ QImage destImage;
+
+ if (srcRect == src.rect()) {
+ srcImage = src.toImage();
+ } else {
+ QRect rect = srcRect.toAlignedRect().intersected(src.rect());
+ srcImage = src.copy(rect).toImage();
+ }
+
+ QTransform transform = painter->worldTransform();
+ painter->translate(p);
+ qt_blurImage(painter, srcImage, scaledRadius, (d->hints & QGraphicsBlurEffect::QualityHint), false);
+ painter->setWorldTransform(transform);
+}
+
+// grayscales the image to dest (could be same). If rect isn't defined
+// destination image size is used to determine the dimension of grayscaling
+// process.
+static void grayscale(const QImage &image, QImage &dest, const QRect& rect = QRect())
+{
+ QRect destRect = rect;
+ QRect srcRect = rect;
+ if (rect.isNull()) {
+ srcRect = dest.rect();
+ destRect = dest.rect();
+ }
+ if (&image != &dest) {
+ destRect.moveTo(QPoint(0, 0));
+ }
+
+ unsigned int *data = (unsigned int *)image.bits();
+ unsigned int *outData = (unsigned int *)dest.bits();
+
+ if (dest.size() == image.size() && image.rect() == srcRect) {
+ // a bit faster loop for grayscaling everything
+ int pixels = dest.width() * dest.height();
+ for (int i = 0; i < pixels; ++i) {
+ int val = qGray(data[i]);
+ outData[i] = qRgba(val, val, val, qAlpha(data[i]));
+ }
+ } else {
+ int yd = destRect.top();
+ for (int y = srcRect.top(); y <= srcRect.bottom() && y < image.height(); y++) {
+ data = (unsigned int*)image.scanLine(y);
+ outData = (unsigned int*)dest.scanLine(yd++);
+ int xd = destRect.left();
+ for (int x = srcRect.left(); x <= srcRect.right() && x < image.width(); x++) {
+ int val = qGray(data[x]);
+ outData[xd++] = qRgba(val, val, val, qAlpha(data[x]));
+ }
+ }
+ }
+}
+
+/*!
+ \class QPixmapColorizeFilter
+ \since 4.5
+ \ingroup painting
+
+ \brief The QPixmapColorizeFilter class provides colorizing
+ filtering for pixmaps.
+
+ A colorize filter gives the pixmap a tint of its color(). The
+ filter first grayscales the pixmap and then converts those to
+ colorized values using QPainter::CompositionMode_Screen with the
+ chosen color. The alpha-channel is not changed.
+
+ Example:
+ \snippet doc/src/snippets/code/src_gui_image_qpixmapfilter.cpp 0
+
+ \sa QPainter::CompositionMode
+
+ \internal
+*/
+class QPixmapColorizeFilterPrivate : public QPixmapFilterPrivate
+{
+ Q_DECLARE_PUBLIC(QPixmapColorizeFilter)
+public:
+ QColor color;
+ qreal strength;
+ quint32 opaque : 1;
+ quint32 alphaBlend : 1;
+ quint32 padding : 30;
+};
+
+/*!
+ Constructs an pixmap colorize filter.
+
+ Default color value for colorizing is QColor(0, 0, 192).
+
+ \internal
+*/
+QPixmapColorizeFilter::QPixmapColorizeFilter(QObject *parent)
+ : QPixmapFilter(*new QPixmapColorizeFilterPrivate, ColorizeFilter, parent)
+{
+ Q_D(QPixmapColorizeFilter);
+ d->color = QColor(0, 0, 192);
+ d->strength = qreal(1);
+ d->opaque = true;
+ d->alphaBlend = false;
+}
+
+/*!
+ Gets the color of the colorize filter.
+
+ \internal
+*/
+QColor QPixmapColorizeFilter::color() const
+{
+ Q_D(const QPixmapColorizeFilter);
+ return d->color;
+}
+
+/*!
+ Sets the color of the colorize filter to the \a color specified.
+
+ \internal
+*/
+void QPixmapColorizeFilter::setColor(const QColor &color)
+{
+ Q_D(QPixmapColorizeFilter);
+ d->color = color;
+}
+
+/*!
+ Gets the strength of the colorize filter, 1.0 means full colorized while
+ 0.0 equals to no filtering at all.
+
+ \internal
+*/
+qreal QPixmapColorizeFilter::strength() const
+{
+ Q_D(const QPixmapColorizeFilter);
+ return d->strength;
+}
+
+/*!
+ Sets the strength of the colorize filter to \a strength.
+
+ \internal
+*/
+void QPixmapColorizeFilter::setStrength(qreal strength)
+{
+ Q_D(QPixmapColorizeFilter);
+ d->strength = qBound(qreal(0), strength, qreal(1));
+ d->opaque = !qFuzzyIsNull(d->strength);
+ d->alphaBlend = !qFuzzyIsNull(d->strength - 1);
+}
+
+/*!
+ \internal
+*/
+void QPixmapColorizeFilter::draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect) const
+{
+ Q_D(const QPixmapColorizeFilter);
+
+ if (src.isNull())
+ return;
+
+ QPixmapFilter *filter = painter->paintEngine() && painter->paintEngine()->isExtended() ?
+ static_cast<QPaintEngineEx *>(painter->paintEngine())->pixmapFilter(type(), this) : 0;
+ QPixmapColorizeFilter *colorizeFilter = static_cast<QPixmapColorizeFilter*>(filter);
+ if (colorizeFilter) {
+ colorizeFilter->setColor(d->color);
+ colorizeFilter->setStrength(d->strength);
+ colorizeFilter->draw(painter, dest, src, srcRect);
+ return;
+ }
+
+ // falling back to raster implementation
+
+ if (!d->opaque) {
+ painter->drawPixmap(dest, src, srcRect);
+ return;
+ }
+
+ QImage srcImage;
+ QImage destImage;
+
+ if (srcRect.isNull()) {
+ srcImage = src.toImage();
+ srcImage = srcImage.convertToFormat(srcImage.hasAlphaChannel() ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32);
+ destImage = QImage(srcImage.size(), srcImage.format());
+ } else {
+ QRect rect = srcRect.toAlignedRect().intersected(src.rect());
+
+ srcImage = src.copy(rect).toImage();
+ srcImage = srcImage.convertToFormat(srcImage.hasAlphaChannel() ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32);
+ destImage = QImage(rect.size(), srcImage.format());
+ }
+
+ // do colorizing
+ QPainter destPainter(&destImage);
+ grayscale(srcImage, destImage, srcImage.rect());
+ destPainter.setCompositionMode(QPainter::CompositionMode_Screen);
+ destPainter.fillRect(srcImage.rect(), d->color);
+ destPainter.end();
+
+ if (d->alphaBlend) {
+ // alpha blending srcImage and destImage
+ QImage buffer = srcImage;
+ QPainter bufPainter(&buffer);
+ bufPainter.setOpacity(d->strength);
+ bufPainter.drawImage(0, 0, destImage);
+ bufPainter.end();
+ destImage = buffer;
+ }
+
+ if (srcImage.hasAlphaChannel())
+ destImage.setAlphaChannel(srcImage.alphaChannel());
+
+ painter->drawImage(dest, destImage);
+}
+
+class QPixmapDropShadowFilterPrivate : public QPixmapFilterPrivate
+{
+public:
+ QPixmapDropShadowFilterPrivate()
+ : offset(8, 8), color(63, 63, 63, 180), radius(1) {}
+
+ QPointF offset;
+ QColor color;
+ qreal radius;
+};
+
+/*!
+ \class QPixmapDropShadowFilter
+ \since 4.5
+ \ingroup painting
+
+ \brief The QPixmapDropShadowFilter class is a convenience class
+ for drawing pixmaps with drop shadows.
+
+ The drop shadow is produced by taking a copy of the source pixmap
+ and applying a color to the copy using a
+ QPainter::CompositionMode_DestinationIn operation. This produces a
+ homogeneously-colored pixmap which is then drawn using a
+ QPixmapConvolutionFilter at an offset. The original pixmap is
+ drawn on top.
+
+ The QPixmapDropShadowFilter class provides some customization
+ options to specify how the drop shadow should appear. The color of
+ the drop shadow can be modified using the setColor() function, the
+ drop shadow offset can be modified using the setOffset() function,
+ and the blur radius of the drop shadow can be changed through the
+ setBlurRadius() function.
+
+ By default, the drop shadow is a dark gray shadow, blurred with a
+ radius of 1 at an offset of 8 pixels towards the lower right.
+
+ Example:
+ \snippet doc/src/snippets/code/src_gui_image_qpixmapfilter.cpp 2
+
+ \sa QPixmapColorizeFilter, QPixmapConvolutionFilter
+
+ \internal
+ */
+
+/*!
+ Constructs drop shadow filter.
+
+ \internal
+*/
+QPixmapDropShadowFilter::QPixmapDropShadowFilter(QObject *parent)
+ : QPixmapFilter(*new QPixmapDropShadowFilterPrivate, DropShadowFilter, parent)
+{
+}
+
+/*!
+ Destroys drop shadow filter.
+
+ \internal
+*/
+QPixmapDropShadowFilter::~QPixmapDropShadowFilter()
+{
+}
+
+/*!
+ Returns the radius in pixels of the blur on the drop shadow.
+
+ A smaller radius results in a sharper shadow.
+
+ \sa color(), offset()
+
+ \internal
+*/
+qreal QPixmapDropShadowFilter::blurRadius() const
+{
+ Q_D(const QPixmapDropShadowFilter);
+ return d->radius;
+}
+
+/*!
+ Sets the radius in pixels of the blur on the drop shadow to the \a radius specified.
+
+ Using a smaller radius results in a sharper shadow.
+
+ \sa setColor(), setOffset()
+
+ \internal
+*/
+void QPixmapDropShadowFilter::setBlurRadius(qreal radius)
+{
+ Q_D(QPixmapDropShadowFilter);
+ d->radius = radius;
+}
+
+/*!
+ Returns the color of the drop shadow.
+
+ \sa blurRadius(), offset()
+
+ \internal
+*/
+QColor QPixmapDropShadowFilter::color() const
+{
+ Q_D(const QPixmapDropShadowFilter);
+ return d->color;
+}
+
+/*!
+ Sets the color of the drop shadow to the \a color specified.
+
+ \sa setBlurRadius(), setOffset()
+
+ \internal
+*/
+void QPixmapDropShadowFilter::setColor(const QColor &color)
+{
+ Q_D(QPixmapDropShadowFilter);
+ d->color = color;
+}
+
+/*!
+ Returns the shadow offset in pixels.
+
+ \sa blurRadius(), color()
+
+ \internal
+*/
+QPointF QPixmapDropShadowFilter::offset() const
+{
+ Q_D(const QPixmapDropShadowFilter);
+ return d->offset;
+}
+
+/*!
+ Sets the shadow offset in pixels to the \a offset specified.
+
+ \sa setBlurRadius(), setColor()
+
+ \internal
+*/
+void QPixmapDropShadowFilter::setOffset(const QPointF &offset)
+{
+ Q_D(QPixmapDropShadowFilter);
+ d->offset = offset;
+}
+
+/*!
+ \fn void QPixmapDropShadowFilter::setOffset(qreal dx, qreal dy)
+ \overload
+
+ Sets the shadow offset in pixels to be the displacement specified by the
+ horizontal \a dx and vertical \a dy coordinates.
+
+ \sa setBlurRadius(), setColor()
+
+ \internal
+*/
+
+/*!
+ \internal
+ */
+QRectF QPixmapDropShadowFilter::boundingRectFor(const QRectF &rect) const
+{
+ Q_D(const QPixmapDropShadowFilter);
+ return rect.united(rect.translated(d->offset).adjusted(-d->radius, -d->radius, d->radius, d->radius));
+}
+
+/*!
+ \internal
+ */
+void QPixmapDropShadowFilter::draw(QPainter *p,
+ const QPointF &pos,
+ const QPixmap &px,
+ const QRectF &src) const
+{
+ Q_D(const QPixmapDropShadowFilter);
+
+ if (px.isNull())
+ return;
+
+ QPixmapFilter *filter = p->paintEngine() && p->paintEngine()->isExtended() ?
+ static_cast<QPaintEngineEx *>(p->paintEngine())->pixmapFilter(type(), this) : 0;
+ QPixmapDropShadowFilter *dropShadowFilter = static_cast<QPixmapDropShadowFilter*>(filter);
+ if (dropShadowFilter) {
+ dropShadowFilter->setColor(d->color);
+ dropShadowFilter->setBlurRadius(d->radius);
+ dropShadowFilter->setOffset(d->offset);
+ dropShadowFilter->draw(p, pos, px, src);
+ return;
+ }
+
+ QImage tmp(px.size(), QImage::Format_ARGB32_Premultiplied);
+ tmp.fill(0);
+ QPainter tmpPainter(&tmp);
+ tmpPainter.setCompositionMode(QPainter::CompositionMode_Source);
+ tmpPainter.drawPixmap(d->offset, px);
+ tmpPainter.end();
+
+ // blur the alpha channel
+ QImage blurred(tmp.size(), QImage::Format_ARGB32_Premultiplied);
+ blurred.fill(0);
+ QPainter blurPainter(&blurred);
+ qt_blurImage(&blurPainter, tmp, d->radius, false, true);
+ blurPainter.end();
+
+ tmp = blurred;
+
+ // blacken the image...
+ tmpPainter.begin(&tmp);
+ tmpPainter.setCompositionMode(QPainter::CompositionMode_SourceIn);
+ tmpPainter.fillRect(tmp.rect(), d->color);
+ tmpPainter.end();
+
+ // draw the blurred drop shadow...
+ p->drawImage(pos, tmp);
+
+ // Draw the actual pixmap...
+ p->drawPixmap(pos, px, src);
+}
+
+QT_END_NAMESPACE
+
+#endif //QT_NO_GRAPHICSEFFECT
diff --git a/src/widgets/effects/qpixmapfilter_p.h b/src/widgets/effects/qpixmapfilter_p.h
new file mode 100644
index 0000000000..b0edd8d4b0
--- /dev/null
+++ b/src/widgets/effects/qpixmapfilter_p.h
@@ -0,0 +1,196 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPIXMAPFILTER_H
+#define QPIXMAPFILTER_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qnamespace.h>
+#include <QtGui/qpixmap.h>
+#include <QtWidgets/qgraphicseffect.h>
+
+#ifndef QT_NO_GRAPHICSEFFECT
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QPainter;
+class QPlatformPixmap;
+
+class QPixmapFilterPrivate;
+
+class Q_WIDGETS_EXPORT QPixmapFilter : public QObject
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QPixmapFilter)
+public:
+ virtual ~QPixmapFilter() = 0;
+
+ enum FilterType {
+ ConvolutionFilter,
+ ColorizeFilter,
+ DropShadowFilter,
+ BlurFilter,
+
+ UserFilter = 1024
+ };
+
+ FilterType type() const;
+
+ virtual QRectF boundingRectFor(const QRectF &rect) const;
+
+ virtual void draw(QPainter *painter, const QPointF &p, const QPixmap &src, const QRectF &srcRect = QRectF()) const = 0;
+
+protected:
+ QPixmapFilter(QPixmapFilterPrivate &d, FilterType type, QObject *parent);
+ QPixmapFilter(FilterType type, QObject *parent);
+};
+
+class QPixmapConvolutionFilterPrivate;
+
+class Q_WIDGETS_EXPORT QPixmapConvolutionFilter : public QPixmapFilter
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QPixmapConvolutionFilter)
+
+public:
+ QPixmapConvolutionFilter(QObject *parent = 0);
+ ~QPixmapConvolutionFilter();
+
+ void setConvolutionKernel(const qreal *matrix, int rows, int columns);
+
+ QRectF boundingRectFor(const QRectF &rect) const;
+ void draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect = QRectF()) const;
+
+private:
+ friend class QGLPixmapConvolutionFilter;
+ friend class QVGPixmapConvolutionFilter;
+ const qreal *convolutionKernel() const;
+ int rows() const;
+ int columns() const;
+};
+
+class QPixmapBlurFilterPrivate;
+
+class Q_WIDGETS_EXPORT QPixmapBlurFilter : public QPixmapFilter
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QPixmapBlurFilter)
+
+public:
+ QPixmapBlurFilter(QObject *parent = 0);
+ ~QPixmapBlurFilter();
+
+ void setRadius(qreal radius);
+ void setBlurHints(QGraphicsBlurEffect::BlurHints hints);
+
+ qreal radius() const;
+ QGraphicsBlurEffect::BlurHints blurHints() const;
+
+ QRectF boundingRectFor(const QRectF &rect) const;
+ void draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect = QRectF()) const;
+
+private:
+ friend class QGLPixmapBlurFilter;
+};
+
+class QPixmapColorizeFilterPrivate;
+
+class Q_WIDGETS_EXPORT QPixmapColorizeFilter : public QPixmapFilter
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QPixmapColorizeFilter)
+
+public:
+ QPixmapColorizeFilter(QObject *parent = 0);
+
+ void setColor(const QColor& color);
+ QColor color() const;
+
+ void setStrength(qreal strength);
+ qreal strength() const;
+
+ void draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect = QRectF()) const;
+};
+
+class QPixmapDropShadowFilterPrivate;
+
+class Q_WIDGETS_EXPORT QPixmapDropShadowFilter : public QPixmapFilter
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QPixmapDropShadowFilter)
+
+public:
+ QPixmapDropShadowFilter(QObject *parent = 0);
+ ~QPixmapDropShadowFilter();
+
+ QRectF boundingRectFor(const QRectF &rect) const;
+ void draw(QPainter *p, const QPointF &pos, const QPixmap &px, const QRectF &src = QRectF()) const;
+
+ qreal blurRadius() const;
+ void setBlurRadius(qreal radius);
+
+ QColor color() const;
+ void setColor(const QColor &color);
+
+ QPointF offset() const;
+ void setOffset(const QPointF &offset);
+ inline void setOffset(qreal dx, qreal dy) { setOffset(QPointF(dx, dy)); }
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif //QT_NO_GRAPHICSEFFECT
+#endif // QPIXMAPFILTER_H
diff --git a/src/gui/graphicsview/graphicsview.pri b/src/widgets/graphicsview/graphicsview.pri
index 547d7ce7ae..547d7ce7ae 100644
--- a/src/gui/graphicsview/graphicsview.pri
+++ b/src/widgets/graphicsview/graphicsview.pri
diff --git a/src/gui/graphicsview/qgraph_p.h b/src/widgets/graphicsview/qgraph_p.h
index 3b9d839a17..3b9d839a17 100644
--- a/src/gui/graphicsview/qgraph_p.h
+++ b/src/widgets/graphicsview/qgraph_p.h
diff --git a/src/gui/graphicsview/qgraphicsanchorlayout.cpp b/src/widgets/graphicsview/qgraphicsanchorlayout.cpp
index 08c5972534..08c5972534 100644
--- a/src/gui/graphicsview/qgraphicsanchorlayout.cpp
+++ b/src/widgets/graphicsview/qgraphicsanchorlayout.cpp
diff --git a/src/widgets/graphicsview/qgraphicsanchorlayout.h b/src/widgets/graphicsview/qgraphicsanchorlayout.h
new file mode 100644
index 0000000000..4e57dbccf9
--- /dev/null
+++ b/src/widgets/graphicsview/qgraphicsanchorlayout.h
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGRAPHICSANCHORLAYOUT_H
+#define QGRAPHICSANCHORLAYOUT_H
+
+#include <QtWidgets/qgraphicsitem.h>
+#include <QtWidgets/qgraphicslayout.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW
+
+class QGraphicsAnchorPrivate;
+class QGraphicsAnchorLayout;
+class QGraphicsAnchorLayoutPrivate;
+
+class Q_WIDGETS_EXPORT QGraphicsAnchor : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(qreal spacing READ spacing WRITE setSpacing RESET unsetSpacing)
+ Q_PROPERTY(QSizePolicy::Policy sizePolicy READ sizePolicy WRITE setSizePolicy)
+public:
+ void setSpacing(qreal spacing);
+ void unsetSpacing();
+ qreal spacing() const;
+ void setSizePolicy(QSizePolicy::Policy policy);
+ QSizePolicy::Policy sizePolicy() const;
+ ~QGraphicsAnchor();
+private:
+ QGraphicsAnchor(QGraphicsAnchorLayout *parent);
+
+ Q_DECLARE_PRIVATE(QGraphicsAnchor)
+
+ friend class QGraphicsAnchorLayoutPrivate;
+ friend struct AnchorData;
+};
+
+class Q_WIDGETS_EXPORT QGraphicsAnchorLayout : public QGraphicsLayout
+{
+public:
+ QGraphicsAnchorLayout(QGraphicsLayoutItem *parent = 0);
+ virtual ~QGraphicsAnchorLayout();
+
+ QGraphicsAnchor *addAnchor(QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge,
+ QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge);
+ QGraphicsAnchor *anchor(QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge,
+ QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge);
+
+ void addCornerAnchors(QGraphicsLayoutItem *firstItem, Qt::Corner firstCorner,
+ QGraphicsLayoutItem *secondItem, Qt::Corner secondCorner);
+
+ void addAnchors(QGraphicsLayoutItem *firstItem,
+ QGraphicsLayoutItem *secondItem,
+ Qt::Orientations orientations = Qt::Horizontal | Qt::Vertical);
+
+ void setHorizontalSpacing(qreal spacing);
+ void setVerticalSpacing(qreal spacing);
+ void setSpacing(qreal spacing);
+ qreal horizontalSpacing() const;
+ qreal verticalSpacing() const;
+
+ void removeAt(int index);
+ void setGeometry(const QRectF &rect);
+ int count() const;
+ QGraphicsLayoutItem *itemAt(int index) const;
+
+ void invalidate();
+protected:
+ QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const;
+
+private:
+ Q_DISABLE_COPY(QGraphicsAnchorLayout)
+ Q_DECLARE_PRIVATE(QGraphicsAnchorLayout)
+
+ friend class QGraphicsAnchor;
+};
+
+#endif
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/widgets/graphicsview/qgraphicsanchorlayout_p.cpp b/src/widgets/graphicsview/qgraphicsanchorlayout_p.cpp
new file mode 100644
index 0000000000..c9bda58123
--- /dev/null
+++ b/src/widgets/graphicsview/qgraphicsanchorlayout_p.cpp
@@ -0,0 +1,3016 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtWidgets/qwidget.h>
+#include <QtWidgets/qapplication.h>
+#include <QtCore/qlinkedlist.h>
+#include <QtCore/qstack.h>
+
+#ifdef QT_DEBUG
+#include <QtCore/qfile.h>
+#endif
+
+#include "qgraphicsanchorlayout_p.h"
+
+#ifndef QT_NO_GRAPHICSVIEW
+QT_BEGIN_NAMESPACE
+
+// To ensure that all variables inside the simplex solver are non-negative,
+// we limit the size of anchors in the interval [-limit, limit]. Then before
+// sending them to the simplex solver we add "limit" as an offset, so that
+// they are actually calculated in the interval [0, 2 * limit]
+// To avoid numerical errors in platforms where we use single precision,
+// we use a tighter limit for the variables range.
+const qreal g_offset = (sizeof(qreal) == sizeof(double)) ? QWIDGETSIZE_MAX : QWIDGETSIZE_MAX / 32;
+
+QGraphicsAnchorPrivate::QGraphicsAnchorPrivate(int version)
+ : QObjectPrivate(version), layoutPrivate(0), data(0),
+ sizePolicy(QSizePolicy::Fixed), preferredSize(0),
+ hasSize(true)
+{
+}
+
+QGraphicsAnchorPrivate::~QGraphicsAnchorPrivate()
+{
+ if (data) {
+ // The QGraphicsAnchor was already deleted at this moment. We must clean
+ // the dangling pointer to avoid double deletion in the AnchorData dtor.
+ data->graphicsAnchor = 0;
+
+ layoutPrivate->removeAnchor(data->from, data->to);
+ }
+}
+
+void QGraphicsAnchorPrivate::setSizePolicy(QSizePolicy::Policy policy)
+{
+ if (sizePolicy != policy) {
+ sizePolicy = policy;
+ layoutPrivate->q_func()->invalidate();
+ }
+}
+
+void QGraphicsAnchorPrivate::setSpacing(qreal value)
+{
+ if (!data) {
+ qWarning("QGraphicsAnchor::setSpacing: The anchor does not exist.");
+ return;
+ }
+
+ if (hasSize && (preferredSize == value))
+ return;
+
+ // The anchor has an user-defined size
+ hasSize = true;
+ preferredSize = value;
+
+ layoutPrivate->q_func()->invalidate();
+}
+
+void QGraphicsAnchorPrivate::unsetSpacing()
+{
+ if (!data) {
+ qWarning("QGraphicsAnchor::setSpacing: The anchor does not exist.");
+ return;
+ }
+
+ // Return to standard direction
+ hasSize = false;
+
+ layoutPrivate->q_func()->invalidate();
+}
+
+qreal QGraphicsAnchorPrivate::spacing() const
+{
+ if (!data) {
+ qWarning("QGraphicsAnchor::setSpacing: The anchor does not exist.");
+ return 0;
+ }
+
+ return preferredSize;
+}
+
+
+static void applySizePolicy(QSizePolicy::Policy policy,
+ qreal minSizeHint, qreal prefSizeHint, qreal maxSizeHint,
+ qreal *minSize, qreal *prefSize,
+ qreal *maxSize)
+{
+ // minSize, prefSize and maxSize are initialized
+ // with item's preferred Size: this is QSizePolicy::Fixed.
+ //
+ // Then we check each flag to find the resultant QSizePolicy,
+ // according to the following table:
+ //
+ // constant value
+ // QSizePolicy::Fixed 0
+ // QSizePolicy::Minimum GrowFlag
+ // QSizePolicy::Maximum ShrinkFlag
+ // QSizePolicy::Preferred GrowFlag | ShrinkFlag
+ // QSizePolicy::Ignored GrowFlag | ShrinkFlag | IgnoreFlag
+
+ if (policy & QSizePolicy::ShrinkFlag)
+ *minSize = minSizeHint;
+ else
+ *minSize = prefSizeHint;
+
+ if (policy & QSizePolicy::GrowFlag)
+ *maxSize = maxSizeHint;
+ else
+ *maxSize = prefSizeHint;
+
+ // Note that these two initializations are affected by the previous flags
+ if (policy & QSizePolicy::IgnoreFlag)
+ *prefSize = *minSize;
+ else
+ *prefSize = prefSizeHint;
+}
+
+AnchorData::~AnchorData()
+{
+ if (graphicsAnchor) {
+ // Remove reference to ourself to avoid double removal in
+ // QGraphicsAnchorPrivate dtor.
+ graphicsAnchor->d_func()->data = 0;
+
+ delete graphicsAnchor;
+ }
+}
+
+
+void AnchorData::refreshSizeHints(const QLayoutStyleInfo *styleInfo)
+{
+ QSizePolicy::Policy policy;
+ qreal minSizeHint;
+ qreal prefSizeHint;
+ qreal maxSizeHint;
+
+ if (item) {
+ // It is an internal anchor, fetch size information from the item
+ if (isLayoutAnchor) {
+ minSize = 0;
+ prefSize = 0;
+ maxSize = QWIDGETSIZE_MAX;
+ if (isCenterAnchor)
+ maxSize /= 2;
+
+ minPrefSize = prefSize;
+ maxPrefSize = maxSize;
+ return;
+ } else {
+ if (orientation == QGraphicsAnchorLayoutPrivate::Horizontal) {
+ policy = item->sizePolicy().horizontalPolicy();
+ minSizeHint = item->effectiveSizeHint(Qt::MinimumSize).width();
+ prefSizeHint = item->effectiveSizeHint(Qt::PreferredSize).width();
+ maxSizeHint = item->effectiveSizeHint(Qt::MaximumSize).width();
+ } else {
+ policy = item->sizePolicy().verticalPolicy();
+ minSizeHint = item->effectiveSizeHint(Qt::MinimumSize).height();
+ prefSizeHint = item->effectiveSizeHint(Qt::PreferredSize).height();
+ maxSizeHint = item->effectiveSizeHint(Qt::MaximumSize).height();
+ }
+
+ if (isCenterAnchor) {
+ minSizeHint /= 2;
+ prefSizeHint /= 2;
+ maxSizeHint /= 2;
+ }
+ }
+ } else {
+ // It is a user-created anchor, fetch size information from the associated QGraphicsAnchor
+ Q_ASSERT(graphicsAnchor);
+ QGraphicsAnchorPrivate *anchorPrivate = graphicsAnchor->d_func();
+
+ // Policy, min and max sizes are straightforward
+ policy = anchorPrivate->sizePolicy;
+ minSizeHint = 0;
+ maxSizeHint = QWIDGETSIZE_MAX;
+
+ // Preferred Size
+ if (anchorPrivate->hasSize) {
+ // Anchor has user-defined size
+ prefSizeHint = anchorPrivate->preferredSize;
+ } else {
+ // Fetch size information from style
+ const Qt::Orientation orient = Qt::Orientation(QGraphicsAnchorLayoutPrivate::edgeOrientation(from->m_edge) + 1);
+ qreal s = styleInfo->defaultSpacing(orient);
+ if (s < 0) {
+ QSizePolicy::ControlType controlTypeFrom = from->m_item->sizePolicy().controlType();
+ QSizePolicy::ControlType controlTypeTo = to->m_item->sizePolicy().controlType();
+ s = styleInfo->perItemSpacing(controlTypeFrom, controlTypeTo, orient);
+
+ // ### Currently we do not support negative anchors inside the graph.
+ // To avoid those being created by a negative style spacing, we must
+ // make this test.
+ if (s < 0)
+ s = 0;
+ }
+ prefSizeHint = s;
+ }
+ }
+
+ // Fill minSize, prefSize and maxSize based on policy and sizeHints
+ applySizePolicy(policy, minSizeHint, prefSizeHint, maxSizeHint,
+ &minSize, &prefSize, &maxSize);
+
+ minPrefSize = prefSize;
+ maxPrefSize = maxSize;
+
+ // Set the anchor effective sizes to preferred.
+ //
+ // Note: The idea here is that all items should remain at their
+ // preferred size unless where that's impossible. In cases where
+ // the item is subject to restrictions (anchored to the layout
+ // edges, for instance), the simplex solver will be run to
+ // recalculate and override the values we set here.
+ sizeAtMinimum = prefSize;
+ sizeAtPreferred = prefSize;
+ sizeAtMaximum = prefSize;
+}
+
+void ParallelAnchorData::updateChildrenSizes()
+{
+ firstEdge->sizeAtMinimum = sizeAtMinimum;
+ firstEdge->sizeAtPreferred = sizeAtPreferred;
+ firstEdge->sizeAtMaximum = sizeAtMaximum;
+
+ if (secondForward()) {
+ secondEdge->sizeAtMinimum = sizeAtMinimum;
+ secondEdge->sizeAtPreferred = sizeAtPreferred;
+ secondEdge->sizeAtMaximum = sizeAtMaximum;
+ } else {
+ secondEdge->sizeAtMinimum = -sizeAtMinimum;
+ secondEdge->sizeAtPreferred = -sizeAtPreferred;
+ secondEdge->sizeAtMaximum = -sizeAtMaximum;
+ }
+
+ firstEdge->updateChildrenSizes();
+ secondEdge->updateChildrenSizes();
+}
+
+/*
+ \internal
+
+ Initialize the parallel anchor size hints using the sizeHint information from
+ its children.
+
+ Note that parallel groups can lead to unfeasibility, so during calculation, we can
+ find out one unfeasibility. Because of that this method return boolean. This can't
+ happen in sequential, so there the method is void.
+ */
+bool ParallelAnchorData::calculateSizeHints()
+{
+ // Normalize second child sizes.
+ // A negative anchor of sizes min, minPref, pref, maxPref and max, is equivalent
+ // to a forward anchor of sizes -max, -maxPref, -pref, -minPref, -min
+ qreal secondMin;
+ qreal secondMinPref;
+ qreal secondPref;
+ qreal secondMaxPref;
+ qreal secondMax;
+
+ if (secondForward()) {
+ secondMin = secondEdge->minSize;
+ secondMinPref = secondEdge->minPrefSize;
+ secondPref = secondEdge->prefSize;
+ secondMaxPref = secondEdge->maxPrefSize;
+ secondMax = secondEdge->maxSize;
+ } else {
+ secondMin = -secondEdge->maxSize;
+ secondMinPref = -secondEdge->maxPrefSize;
+ secondPref = -secondEdge->prefSize;
+ secondMaxPref = -secondEdge->minPrefSize;
+ secondMax = -secondEdge->minSize;
+ }
+
+ minSize = qMax(firstEdge->minSize, secondMin);
+ maxSize = qMin(firstEdge->maxSize, secondMax);
+
+ // This condition means that the maximum size of one anchor being simplified is smaller than
+ // the minimum size of the other anchor. The consequence is that there won't be a valid size
+ // for this parallel setup.
+ if (minSize > maxSize) {
+ return false;
+ }
+
+ // Preferred size calculation
+ // The calculation of preferred size is done as follows:
+ //
+ // 1) Check whether one of the child anchors is the layout structural anchor
+ // If so, we can simply copy the preferred information from the other child,
+ // after bounding it to our minimum and maximum sizes.
+ // If not, then we proceed with the actual calculations.
+ //
+ // 2) The whole algorithm for preferred size calculation is based on the fact
+ // that, if a given anchor cannot remain at its preferred size, it'd rather
+ // grow than shrink.
+ //
+ // What happens though is that while this affirmative is true for simple
+ // anchors, it may not be true for sequential anchors that have one or more
+ // reversed anchors inside it. That happens because when a sequential anchor
+ // grows, any reversed anchors inside it may be required to shrink, something
+ // we try to avoid, as said above.
+ //
+ // To overcome this, besides their actual preferred size "prefSize", each anchor
+ // exports what we call "minPrefSize" and "maxPrefSize". These two values define
+ // a surrounding interval where, if required to move, the anchor would rather
+ // remain inside.
+ //
+ // For standard anchors, this area simply represents the region between
+ // prefSize and maxSize, which makes sense since our first affirmation.
+ // For composed anchors, these values are calculated as to reduce the global
+ // "damage", that is, to reduce the total deviation and the total amount of
+ // anchors that had to shrink.
+
+ if (firstEdge->isLayoutAnchor) {
+ prefSize = qBound(minSize, secondPref, maxSize);
+ minPrefSize = qBound(minSize, secondMinPref, maxSize);
+ maxPrefSize = qBound(minSize, secondMaxPref, maxSize);
+ } else if (secondEdge->isLayoutAnchor) {
+ prefSize = qBound(minSize, firstEdge->prefSize, maxSize);
+ minPrefSize = qBound(minSize, firstEdge->minPrefSize, maxSize);
+ maxPrefSize = qBound(minSize, firstEdge->maxPrefSize, maxSize);
+ } else {
+ // Calculate the intersection between the "preferred" regions of each child
+ const qreal lowerBoundary =
+ qBound(minSize, qMax(firstEdge->minPrefSize, secondMinPref), maxSize);
+ const qreal upperBoundary =
+ qBound(minSize, qMin(firstEdge->maxPrefSize, secondMaxPref), maxSize);
+ const qreal prefMean =
+ qBound(minSize, (firstEdge->prefSize + secondPref) / 2, maxSize);
+
+ if (lowerBoundary < upperBoundary) {
+ // If there is an intersection between the two regions, this intersection
+ // will be used as the preferred region of the parallel anchor itself.
+ // The preferred size will be the bounded average between the two preferred
+ // sizes.
+ prefSize = qBound(lowerBoundary, prefMean, upperBoundary);
+ minPrefSize = lowerBoundary;
+ maxPrefSize = upperBoundary;
+ } else {
+ // If there is no intersection, we have to attribute "damage" to at least
+ // one of the children. The minimum total damage is achieved in points
+ // inside the region that extends from (1) the upper boundary of the lower
+ // region to (2) the lower boundary of the upper region.
+ // Then, we expose this region as _our_ preferred region and once again,
+ // use the bounded average as our preferred size.
+ prefSize = qBound(upperBoundary, prefMean, lowerBoundary);
+ minPrefSize = upperBoundary;
+ maxPrefSize = lowerBoundary;
+ }
+ }
+
+ // See comment in AnchorData::refreshSizeHints() about sizeAt* values
+ sizeAtMinimum = prefSize;
+ sizeAtPreferred = prefSize;
+ sizeAtMaximum = prefSize;
+
+ return true;
+}
+
+/*!
+ \internal
+ returns the factor in the interval [-1, 1].
+ -1 is at Minimum
+ 0 is at Preferred
+ 1 is at Maximum
+*/
+static QPair<QGraphicsAnchorLayoutPrivate::Interval, qreal> getFactor(qreal value, qreal min,
+ qreal minPref, qreal pref,
+ qreal maxPref, qreal max)
+{
+ QGraphicsAnchorLayoutPrivate::Interval interval;
+ qreal lower;
+ qreal upper;
+
+ if (value < minPref) {
+ interval = QGraphicsAnchorLayoutPrivate::MinimumToMinPreferred;
+ lower = min;
+ upper = minPref;
+ } else if (value < pref) {
+ interval = QGraphicsAnchorLayoutPrivate::MinPreferredToPreferred;
+ lower = minPref;
+ upper = pref;
+ } else if (value < maxPref) {
+ interval = QGraphicsAnchorLayoutPrivate::PreferredToMaxPreferred;
+ lower = pref;
+ upper = maxPref;
+ } else {
+ interval = QGraphicsAnchorLayoutPrivate::MaxPreferredToMaximum;
+ lower = maxPref;
+ upper = max;
+ }
+
+ qreal progress;
+ if (upper == lower) {
+ progress = 0;
+ } else {
+ progress = (value - lower) / (upper - lower);
+ }
+
+ return qMakePair(interval, progress);
+}
+
+static qreal interpolate(const QPair<QGraphicsAnchorLayoutPrivate::Interval, qreal> &factor,
+ qreal min, qreal minPref, qreal pref, qreal maxPref, qreal max)
+{
+ qreal lower = 0;
+ qreal upper = 0;
+
+ switch (factor.first) {
+ case QGraphicsAnchorLayoutPrivate::MinimumToMinPreferred:
+ lower = min;
+ upper = minPref;
+ break;
+ case QGraphicsAnchorLayoutPrivate::MinPreferredToPreferred:
+ lower = minPref;
+ upper = pref;
+ break;
+ case QGraphicsAnchorLayoutPrivate::PreferredToMaxPreferred:
+ lower = pref;
+ upper = maxPref;
+ break;
+ case QGraphicsAnchorLayoutPrivate::MaxPreferredToMaximum:
+ lower = maxPref;
+ upper = max;
+ break;
+ }
+
+ return lower + factor.second * (upper - lower);
+}
+
+void SequentialAnchorData::updateChildrenSizes()
+{
+ // Band here refers if the value is in the Minimum To Preferred
+ // band (the lower band) or the Preferred To Maximum (the upper band).
+
+ const QPair<QGraphicsAnchorLayoutPrivate::Interval, qreal> minFactor =
+ getFactor(sizeAtMinimum, minSize, minPrefSize, prefSize, maxPrefSize, maxSize);
+ const QPair<QGraphicsAnchorLayoutPrivate::Interval, qreal> prefFactor =
+ getFactor(sizeAtPreferred, minSize, minPrefSize, prefSize, maxPrefSize, maxSize);
+ const QPair<QGraphicsAnchorLayoutPrivate::Interval, qreal> maxFactor =
+ getFactor(sizeAtMaximum, minSize, minPrefSize, prefSize, maxPrefSize, maxSize);
+
+ // XXX This is not safe if Vertex simplification takes place after the sequential
+ // anchor is created. In that case, "prev" will be a group-vertex, different from
+ // "from" or "to", that _contains_ one of them.
+ AnchorVertex *prev = from;
+
+ for (int i = 0; i < m_edges.count(); ++i) {
+ AnchorData *e = m_edges.at(i);
+
+ const bool edgeIsForward = (e->from == prev);
+ if (edgeIsForward) {
+ e->sizeAtMinimum = interpolate(minFactor, e->minSize, e->minPrefSize,
+ e->prefSize, e->maxPrefSize, e->maxSize);
+ e->sizeAtPreferred = interpolate(prefFactor, e->minSize, e->minPrefSize,
+ e->prefSize, e->maxPrefSize, e->maxSize);
+ e->sizeAtMaximum = interpolate(maxFactor, e->minSize, e->minPrefSize,
+ e->prefSize, e->maxPrefSize, e->maxSize);
+ prev = e->to;
+ } else {
+ Q_ASSERT(prev == e->to);
+ e->sizeAtMinimum = interpolate(minFactor, e->maxSize, e->maxPrefSize,
+ e->prefSize, e->minPrefSize, e->minSize);
+ e->sizeAtPreferred = interpolate(prefFactor, e->maxSize, e->maxPrefSize,
+ e->prefSize, e->minPrefSize, e->minSize);
+ e->sizeAtMaximum = interpolate(maxFactor, e->maxSize, e->maxPrefSize,
+ e->prefSize, e->minPrefSize, e->minSize);
+ prev = e->from;
+ }
+
+ e->updateChildrenSizes();
+ }
+}
+
+void SequentialAnchorData::calculateSizeHints()
+{
+ minSize = 0;
+ prefSize = 0;
+ maxSize = 0;
+ minPrefSize = 0;
+ maxPrefSize = 0;
+
+ AnchorVertex *prev = from;
+
+ for (int i = 0; i < m_edges.count(); ++i) {
+ AnchorData *edge = m_edges.at(i);
+
+ const bool edgeIsForward = (edge->from == prev);
+ if (edgeIsForward) {
+ minSize += edge->minSize;
+ prefSize += edge->prefSize;
+ maxSize += edge->maxSize;
+ minPrefSize += edge->minPrefSize;
+ maxPrefSize += edge->maxPrefSize;
+ prev = edge->to;
+ } else {
+ Q_ASSERT(prev == edge->to);
+ minSize -= edge->maxSize;
+ prefSize -= edge->prefSize;
+ maxSize -= edge->minSize;
+ minPrefSize -= edge->maxPrefSize;
+ maxPrefSize -= edge->minPrefSize;
+ prev = edge->from;
+ }
+ }
+
+ // See comment in AnchorData::refreshSizeHints() about sizeAt* values
+ sizeAtMinimum = prefSize;
+ sizeAtPreferred = prefSize;
+ sizeAtMaximum = prefSize;
+}
+
+#ifdef QT_DEBUG
+void AnchorData::dump(int indent) {
+ if (type == Parallel) {
+ qDebug("%*s type: parallel:", indent, "");
+ ParallelAnchorData *p = static_cast<ParallelAnchorData *>(this);
+ p->firstEdge->dump(indent+2);
+ p->secondEdge->dump(indent+2);
+ } else if (type == Sequential) {
+ SequentialAnchorData *s = static_cast<SequentialAnchorData *>(this);
+ int kids = s->m_edges.count();
+ qDebug("%*s type: sequential(%d):", indent, "", kids);
+ for (int i = 0; i < kids; ++i) {
+ s->m_edges.at(i)->dump(indent+2);
+ }
+ } else {
+ qDebug("%*s type: Normal:", indent, "");
+ }
+}
+
+#endif
+
+QSimplexConstraint *GraphPath::constraint(const GraphPath &path) const
+{
+ // Calculate
+ QSet<AnchorData *> cPositives;
+ QSet<AnchorData *> cNegatives;
+ QSet<AnchorData *> intersection;
+
+ cPositives = positives + path.negatives;
+ cNegatives = negatives + path.positives;
+
+ intersection = cPositives & cNegatives;
+
+ cPositives -= intersection;
+ cNegatives -= intersection;
+
+ // Fill
+ QSimplexConstraint *c = new QSimplexConstraint;
+ QSet<AnchorData *>::iterator i;
+ for (i = cPositives.begin(); i != cPositives.end(); ++i)
+ c->variables.insert(*i, 1.0);
+
+ for (i = cNegatives.begin(); i != cNegatives.end(); ++i)
+ c->variables.insert(*i, -1.0);
+
+ return c;
+}
+
+#ifdef QT_DEBUG
+QString GraphPath::toString() const
+{
+ QString string(QLatin1String("Path: "));
+ foreach(AnchorData *edge, positives)
+ string += QString::fromAscii(" (+++) %1").arg(edge->toString());
+
+ foreach(AnchorData *edge, negatives)
+ string += QString::fromAscii(" (---) %1").arg(edge->toString());
+
+ return string;
+}
+#endif
+
+QGraphicsAnchorLayoutPrivate::QGraphicsAnchorLayoutPrivate()
+ : calculateGraphCacheDirty(true), styleInfoDirty(true)
+{
+ for (int i = 0; i < NOrientations; ++i) {
+ for (int j = 0; j < 3; ++j) {
+ sizeHints[i][j] = -1;
+ }
+ interpolationProgress[i] = -1;
+
+ spacings[i] = -1;
+ graphHasConflicts[i] = false;
+
+ layoutFirstVertex[i] = 0;
+ layoutCentralVertex[i] = 0;
+ layoutLastVertex[i] = 0;
+ }
+}
+
+Qt::AnchorPoint QGraphicsAnchorLayoutPrivate::oppositeEdge(Qt::AnchorPoint edge)
+{
+ switch (edge) {
+ case Qt::AnchorLeft:
+ edge = Qt::AnchorRight;
+ break;
+ case Qt::AnchorRight:
+ edge = Qt::AnchorLeft;
+ break;
+ case Qt::AnchorTop:
+ edge = Qt::AnchorBottom;
+ break;
+ case Qt::AnchorBottom:
+ edge = Qt::AnchorTop;
+ break;
+ default:
+ break;
+ }
+ return edge;
+}
+
+
+/*!
+ * \internal
+ *
+ * helper function in order to avoid overflowing anchor sizes
+ * the returned size will never be larger than FLT_MAX
+ *
+ */
+inline static qreal checkAdd(qreal a, qreal b)
+{
+ if (FLT_MAX - b < a)
+ return FLT_MAX;
+ return a + b;
+}
+
+/*!
+ \internal
+
+ Adds \a newAnchor to the graph.
+
+ Returns the newAnchor itself if it could be added without further changes to the graph. If a
+ new parallel anchor had to be created, then returns the new parallel anchor. If a parallel anchor
+ had to be created and it results in an unfeasible setup, \a feasible is set to false, otherwise
+ true.
+
+ Note that in the case a new parallel anchor is created, it might also take over some constraints
+ from its children anchors.
+*/
+AnchorData *QGraphicsAnchorLayoutPrivate::addAnchorMaybeParallel(AnchorData *newAnchor, bool *feasible)
+{
+ Orientation orientation = Orientation(newAnchor->orientation);
+ Graph<AnchorVertex, AnchorData> &g = graph[orientation];
+ *feasible = true;
+
+ // If already exists one anchor where newAnchor is supposed to be, we create a parallel
+ // anchor.
+ if (AnchorData *oldAnchor = g.takeEdge(newAnchor->from, newAnchor->to)) {
+ ParallelAnchorData *parallel = new ParallelAnchorData(oldAnchor, newAnchor);
+
+ // The parallel anchor will "replace" its children anchors in
+ // every center constraint that they appear.
+
+ // ### If the dependent (center) anchors had reference(s) to their constraints, we
+ // could avoid traversing all the itemCenterConstraints.
+ QList<QSimplexConstraint *> &constraints = itemCenterConstraints[orientation];
+
+ AnchorData *children[2] = { oldAnchor, newAnchor };
+ QList<QSimplexConstraint *> *childrenConstraints[2] = { &parallel->m_firstConstraints,
+ &parallel->m_secondConstraints };
+
+ for (int i = 0; i < 2; ++i) {
+ AnchorData *child = children[i];
+ QList<QSimplexConstraint *> *childConstraints = childrenConstraints[i];
+
+ // We need to fix the second child constraints if the parallel group will have the
+ // opposite direction of the second child anchor. For the point of view of external
+ // entities, this anchor was reversed. So if at some point we say that the parallel
+ // has a value of 20, this mean that the second child (when reversed) will be
+ // assigned -20.
+ const bool needsReverse = i == 1 && !parallel->secondForward();
+
+ if (!child->isCenterAnchor)
+ continue;
+
+ parallel->isCenterAnchor = true;
+
+ for (int j = 0; j < constraints.count(); ++j) {
+ QSimplexConstraint *c = constraints[j];
+ if (c->variables.contains(child)) {
+ childConstraints->append(c);
+ qreal v = c->variables.take(child);
+ if (needsReverse)
+ v *= -1;
+ c->variables.insert(parallel, v);
+ }
+ }
+ }
+
+ // At this point we can identify that the parallel anchor is not feasible, e.g. one
+ // anchor minimum size is bigger than the other anchor maximum size.
+ *feasible = parallel->calculateSizeHints();
+ newAnchor = parallel;
+ }
+
+ g.createEdge(newAnchor->from, newAnchor->to, newAnchor);
+ return newAnchor;
+}
+
+/*!
+ \internal
+
+ Takes the sequence of vertices described by (\a before, \a vertices, \a after) and removes
+ all anchors connected to the vertices in \a vertices, returning one simplified anchor between
+ \a before and \a after.
+
+ Note that this function doesn't add the created anchor to the graph. This should be done by
+ the caller.
+*/
+static AnchorData *createSequence(Graph<AnchorVertex, AnchorData> *graph,
+ AnchorVertex *before,
+ const QVector<AnchorVertex*> &vertices,
+ AnchorVertex *after)
+{
+#if defined(QT_DEBUG) && 0
+ QString strVertices;
+ for (int i = 0; i < vertices.count(); ++i) {
+ strVertices += QString::fromAscii("%1 - ").arg(vertices.at(i)->toString());
+ }
+ QString strPath = QString::fromAscii("%1 - %2%3").arg(before->toString(), strVertices, after->toString());
+ qDebug("simplifying [%s] to [%s - %s]", qPrintable(strPath), qPrintable(before->toString()), qPrintable(after->toString()));
+#endif
+
+ AnchorVertex *prev = before;
+ QVector<AnchorData *> edges;
+
+ // Take from the graph, the edges that will be simplificated
+ for (int i = 0; i < vertices.count(); ++i) {
+ AnchorVertex *next = vertices.at(i);
+ AnchorData *ad = graph->takeEdge(prev, next);
+ Q_ASSERT(ad);
+ edges.append(ad);
+ prev = next;
+ }
+
+ // Take the last edge (not covered in the loop above)
+ AnchorData *ad = graph->takeEdge(vertices.last(), after);
+ Q_ASSERT(ad);
+ edges.append(ad);
+
+ // Create sequence
+ SequentialAnchorData *sequence = new SequentialAnchorData(vertices, edges);
+ sequence->from = before;
+ sequence->to = after;
+
+ sequence->calculateSizeHints();
+
+ return sequence;
+}
+
+/*!
+ \internal
+
+ The purpose of this function is to simplify the graph.
+ Simplification serves two purposes:
+ 1. Reduce the number of edges in the graph, (thus the number of variables to the equation
+ solver is reduced, and the solver performs better).
+ 2. Be able to do distribution of sequences of edges more intelligently (esp. with sequential
+ anchors)
+
+ It is essential that it must be possible to restore simplified anchors back to their "original"
+ form. This is done by restoreSimplifiedAnchor().
+
+ There are two types of simplification that can be done:
+ 1. Sequential simplification
+ Sequential simplification means that all sequences of anchors will be merged into one single
+ anchor. Only anhcors that points in the same direction will be merged.
+ 2. Parallel simplification
+ If a simplified sequential anchor is about to be inserted between two vertices in the graph
+ and there already exist an anchor between those two vertices, a parallel anchor will be
+ created that serves as a placeholder for the sequential anchor and the anchor that was
+ already between the two vertices.
+
+ The process of simplification can be described as:
+
+ 1. Simplify all sequences of anchors into one anchor.
+ If no further simplification was done, go to (3)
+ - If there already exist an anchor where the sequential anchor is supposed to be inserted,
+ take that anchor out of the graph
+ - Then create a parallel anchor that holds the sequential anchor and the anchor just taken
+ out of the graph.
+ 2. Go to (1)
+ 3. Done
+
+ When creating the parallel anchors, the algorithm might identify unfeasible situations. In this
+ case the simplification process stops and returns false. Otherwise returns true.
+*/
+bool QGraphicsAnchorLayoutPrivate::simplifyGraph(Orientation orientation)
+{
+ if (items.isEmpty())
+ return true;
+
+#if defined(QT_DEBUG) && 0
+ qDebug("Simplifying Graph for %s",
+ orientation == Horizontal ? "Horizontal" : "Vertical");
+
+ static int count = 0;
+ if (orientation == Horizontal) {
+ count++;
+ dumpGraph(QString::fromAscii("%1-full").arg(count));
+ }
+#endif
+
+ // Vertex simplification
+ if (!simplifyVertices(orientation)) {
+ restoreVertices(orientation);
+ return false;
+ }
+
+ // Anchor simplification
+ bool dirty;
+ bool feasible = true;
+ do {
+ dirty = simplifyGraphIteration(orientation, &feasible);
+ } while (dirty && feasible);
+
+ // Note that if we are not feasible, we fallback and make sure that the graph is fully restored
+ if (!feasible) {
+ restoreSimplifiedGraph(orientation);
+ restoreVertices(orientation);
+ return false;
+ }
+
+#if defined(QT_DEBUG) && 0
+ dumpGraph(QString::fromAscii("%1-simplified-%2").arg(count).arg(
+ QString::fromAscii(orientation == Horizontal ? "Horizontal" : "Vertical")));
+#endif
+
+ return true;
+}
+
+static AnchorVertex *replaceVertex_helper(AnchorData *data, AnchorVertex *oldV, AnchorVertex *newV)
+{
+ AnchorVertex *other;
+ if (data->from == oldV) {
+ data->from = newV;
+ other = data->to;
+ } else {
+ data->to = newV;
+ other = data->from;
+ }
+ return other;
+}
+
+bool QGraphicsAnchorLayoutPrivate::replaceVertex(Orientation orientation, AnchorVertex *oldV,
+ AnchorVertex *newV, const QList<AnchorData *> &edges)
+{
+ Graph<AnchorVertex, AnchorData> &g = graph[orientation];
+ bool feasible = true;
+
+ for (int i = 0; i < edges.count(); ++i) {
+ AnchorData *ad = edges[i];
+ AnchorVertex *otherV = replaceVertex_helper(ad, oldV, newV);
+
+#if defined(QT_DEBUG)
+ ad->name = QString::fromAscii("%1 --to--> %2").arg(ad->from->toString()).arg(ad->to->toString());
+#endif
+
+ bool newFeasible;
+ AnchorData *newAnchor = addAnchorMaybeParallel(ad, &newFeasible);
+ feasible &= newFeasible;
+
+ if (newAnchor != ad) {
+ // A parallel was created, we mark that in the list of anchors created by vertex
+ // simplification. This is needed because we want to restore them in a separate step
+ // from the restoration of anchor simplification.
+ anchorsFromSimplifiedVertices[orientation].append(newAnchor);
+ }
+
+ g.takeEdge(oldV, otherV);
+ }
+
+ return feasible;
+}
+
+/*!
+ \internal
+*/
+bool QGraphicsAnchorLayoutPrivate::simplifyVertices(Orientation orientation)
+{
+ Q_Q(QGraphicsAnchorLayout);
+ Graph<AnchorVertex, AnchorData> &g = graph[orientation];
+
+ // We'll walk through vertices
+ QStack<AnchorVertex *> stack;
+ stack.push(layoutFirstVertex[orientation]);
+ QSet<AnchorVertex *> visited;
+
+ while (!stack.isEmpty()) {
+ AnchorVertex *v = stack.pop();
+ visited.insert(v);
+
+ // Each adjacent of 'v' is a possible vertex to be merged. So we traverse all of
+ // them. Since once a merge is made, we might add new adjacents, and we don't want to
+ // pass two times through one adjacent. The 'index' is used to track our position.
+ QList<AnchorVertex *> adjacents = g.adjacentVertices(v);
+ int index = 0;
+
+ while (index < adjacents.count()) {
+ AnchorVertex *next = adjacents.at(index);
+ index++;
+
+ AnchorData *data = g.edgeData(v, next);
+ const bool bothLayoutVertices = v->m_item == q && next->m_item == q;
+ const bool zeroSized = !data->minSize && !data->maxSize;
+
+ if (!bothLayoutVertices && zeroSized) {
+
+ // Create a new vertex pair, note that we keep a list of those vertices so we can
+ // easily process them when restoring the graph.
+ AnchorVertexPair *newV = new AnchorVertexPair(v, next, data);
+ simplifiedVertices[orientation].append(newV);
+
+ // Collect the anchors of both vertices, the new vertex pair will take their place
+ // in those anchors
+ const QList<AnchorVertex *> &vAdjacents = g.adjacentVertices(v);
+ const QList<AnchorVertex *> &nextAdjacents = g.adjacentVertices(next);
+
+ for (int i = 0; i < vAdjacents.count(); ++i) {
+ AnchorVertex *adjacent = vAdjacents.at(i);
+ if (adjacent != next) {
+ AnchorData *ad = g.edgeData(v, adjacent);
+ newV->m_firstAnchors.append(ad);
+ }
+ }
+
+ for (int i = 0; i < nextAdjacents.count(); ++i) {
+ AnchorVertex *adjacent = nextAdjacents.at(i);
+ if (adjacent != v) {
+ AnchorData *ad = g.edgeData(next, adjacent);
+ newV->m_secondAnchors.append(ad);
+
+ // We'll also add new vertices to the adjacent list of the new 'v', to be
+ // created as a vertex pair and replace the current one.
+ if (!adjacents.contains(adjacent))
+ adjacents.append(adjacent);
+ }
+ }
+
+ // ### merge this loop into the ones that calculated m_firstAnchors/m_secondAnchors?
+ // Make newV take the place of v and next
+ bool feasible = replaceVertex(orientation, v, newV, newV->m_firstAnchors);
+ feasible &= replaceVertex(orientation, next, newV, newV->m_secondAnchors);
+
+ // Update the layout vertex information if one of the vertices is a layout vertex.
+ AnchorVertex *layoutVertex = 0;
+ if (v->m_item == q)
+ layoutVertex = v;
+ else if (next->m_item == q)
+ layoutVertex = next;
+
+ if (layoutVertex) {
+ // Layout vertices always have m_item == q...
+ newV->m_item = q;
+ changeLayoutVertex(orientation, layoutVertex, newV);
+ }
+
+ g.takeEdge(v, next);
+
+ // If a non-feasibility is found, we leave early and cancel the simplification
+ if (!feasible)
+ return false;
+
+ v = newV;
+ visited.insert(newV);
+
+ } else if (!visited.contains(next) && !stack.contains(next)) {
+ // If the adjacent is not fit for merge and it wasn't visited by the outermost
+ // loop, we add it to the stack.
+ stack.push(next);
+ }
+ }
+ }
+
+ return true;
+}
+
+/*!
+ \internal
+
+ One iteration of the simplification algorithm. Returns true if another iteration is needed.
+
+ The algorithm walks the graph in depth-first order, and only collects vertices that has two
+ edges connected to it. If the vertex does not have two edges or if it is a layout edge, it
+ will take all the previously collected vertices and try to create a simplified sequential
+ anchor representing all the previously collected vertices. Once the simplified anchor is
+ inserted, the collected list is cleared in order to find the next sequence to simplify.
+
+ Note that there are some catches to this that are not covered by the above explanation, see
+ the function comments for more details.
+*/
+bool QGraphicsAnchorLayoutPrivate::simplifyGraphIteration(QGraphicsAnchorLayoutPrivate::Orientation orientation,
+ bool *feasible)
+{
+ Q_Q(QGraphicsAnchorLayout);
+ Graph<AnchorVertex, AnchorData> &g = graph[orientation];
+
+ QSet<AnchorVertex *> visited;
+ QStack<QPair<AnchorVertex *, AnchorVertex *> > stack;
+ stack.push(qMakePair(static_cast<AnchorVertex *>(0), layoutFirstVertex[orientation]));
+ QVector<AnchorVertex*> candidates;
+
+ // Walk depth-first, in the stack we store start of the candidate sequence (beforeSequence)
+ // and the vertex to be visited.
+ while (!stack.isEmpty()) {
+ QPair<AnchorVertex *, AnchorVertex *> pair = stack.pop();
+ AnchorVertex *beforeSequence = pair.first;
+ AnchorVertex *v = pair.second;
+
+ // The basic idea is to determine whether we found an end of sequence,
+ // if that's the case, we stop adding vertices to the candidate list
+ // and do a simplification step.
+ //
+ // A vertex can trigger an end of sequence if
+ // (a) it is a layout vertex, we don't simplify away the layout vertices;
+ // (b) it does not have exactly 2 adjacents;
+ // (c) its next adjacent is already visited (a cycle in the graph).
+ // (d) the next anchor is a center anchor.
+
+ const QList<AnchorVertex *> &adjacents = g.adjacentVertices(v);
+ const bool isLayoutVertex = v->m_item == q;
+ AnchorVertex *afterSequence = v;
+ bool endOfSequence = false;
+
+ //
+ // Identify the end cases.
+ //
+
+ // Identifies cases (a) and (b)
+ endOfSequence = isLayoutVertex || adjacents.count() != 2;
+
+ if (!endOfSequence) {
+ // This is a tricky part. We peek at the next vertex to find out whether
+ //
+ // - we already visited the next vertex (c);
+ // - the next anchor is a center (d).
+ //
+ // Those are needed to identify the remaining end of sequence cases. Note that unlike
+ // (a) and (b), we preempt the end of sequence by looking into the next vertex.
+
+ // Peek at the next vertex
+ AnchorVertex *after;
+ if (candidates.isEmpty())
+ after = (beforeSequence == adjacents.last() ? adjacents.first() : adjacents.last());
+ else
+ after = (candidates.last() == adjacents.last() ? adjacents.first() : adjacents.last());
+
+ // ### At this point we assumed that candidates will not contain 'after', this may not hold
+ // when simplifying FLOATing anchors.
+ Q_ASSERT(!candidates.contains(after));
+
+ const AnchorData *data = g.edgeData(v, after);
+ Q_ASSERT(data);
+ const bool cycleFound = visited.contains(after);
+
+ // Now cases (c) and (d)...
+ endOfSequence = cycleFound || data->isCenterAnchor;
+
+ if (!endOfSequence) {
+ // If it's not an end of sequence, then the vertex didn't trigger neither of the
+ // previously three cases, so it can be added to the candidates list.
+ candidates.append(v);
+ } else if (cycleFound && (beforeSequence != after)) {
+ afterSequence = after;
+ candidates.append(v);
+ }
+ }
+
+ //
+ // Add next non-visited vertices to the stack.
+ //
+ for (int i = 0; i < adjacents.count(); ++i) {
+ AnchorVertex *next = adjacents.at(i);
+ if (visited.contains(next))
+ continue;
+
+ // If current vertex is an end of sequence, and it'll reset the candidates list. So
+ // the next vertices will build candidates lists with the current vertex as 'before'
+ // vertex. If it's not an end of sequence, we keep the original 'before' vertex,
+ // since we are keeping the candidates list.
+ if (endOfSequence)
+ stack.push(qMakePair(v, next));
+ else
+ stack.push(qMakePair(beforeSequence, next));
+ }
+
+ visited.insert(v);
+
+ if (!endOfSequence || candidates.isEmpty())
+ continue;
+
+ //
+ // Create a sequence for (beforeSequence, candidates, afterSequence).
+ //
+
+ // One restriction we have is to not simplify half of an anchor and let the other half
+ // unsimplified. So we remove center edges before and after the sequence.
+ const AnchorData *firstAnchor = g.edgeData(beforeSequence, candidates.first());
+ if (firstAnchor->isCenterAnchor) {
+ beforeSequence = candidates.first();
+ candidates.remove(0);
+
+ // If there's not candidates to be simplified, leave.
+ if (candidates.isEmpty())
+ continue;
+ }
+
+ const AnchorData *lastAnchor = g.edgeData(candidates.last(), afterSequence);
+ if (lastAnchor->isCenterAnchor) {
+ afterSequence = candidates.last();
+ candidates.remove(candidates.count() - 1);
+
+ if (candidates.isEmpty())
+ continue;
+ }
+
+ //
+ // Add the sequence to the graph.
+ //
+
+ AnchorData *sequence = createSequence(&g, beforeSequence, candidates, afterSequence);
+
+ // If 'beforeSequence' and 'afterSequence' already had an anchor between them, we'll
+ // create a parallel anchor between the new sequence and the old anchor.
+ bool newFeasible;
+ AnchorData *newAnchor = addAnchorMaybeParallel(sequence, &newFeasible);
+
+ if (!newFeasible) {
+ *feasible = false;
+ return false;
+ }
+
+ // When a new parallel anchor is create in the graph, we finish the iteration and return
+ // true to indicate a new iteration is needed. This happens because a parallel anchor
+ // changes the number of adjacents one vertex has, possibly opening up oportunities for
+ // building candidate lists (when adjacents == 2).
+ if (newAnchor != sequence)
+ return true;
+
+ // If there was no parallel simplification, we'll keep walking the graph. So we clear the
+ // candidates list to start again.
+ candidates.clear();
+ }
+
+ return false;
+}
+
+void QGraphicsAnchorLayoutPrivate::restoreSimplifiedAnchor(AnchorData *edge)
+{
+#if 0
+ static const char *anchortypes[] = {"Normal",
+ "Sequential",
+ "Parallel"};
+ qDebug("Restoring %s edge.", anchortypes[int(edge->type)]);
+#endif
+
+ Graph<AnchorVertex, AnchorData> &g = graph[edge->orientation];
+
+ if (edge->type == AnchorData::Normal) {
+ g.createEdge(edge->from, edge->to, edge);
+
+ } else if (edge->type == AnchorData::Sequential) {
+ SequentialAnchorData *sequence = static_cast<SequentialAnchorData *>(edge);
+
+ for (int i = 0; i < sequence->m_edges.count(); ++i) {
+ AnchorData *data = sequence->m_edges.at(i);
+ restoreSimplifiedAnchor(data);
+ }
+
+ delete sequence;
+
+ } else if (edge->type == AnchorData::Parallel) {
+
+ // Skip parallel anchors that were created by vertex simplification, they will be processed
+ // later, when restoring vertex simplification.
+ // ### we could improve this check bit having a bit inside 'edge'
+ if (anchorsFromSimplifiedVertices[edge->orientation].contains(edge))
+ return;
+
+ ParallelAnchorData* parallel = static_cast<ParallelAnchorData*>(edge);
+ restoreSimplifiedConstraints(parallel);
+
+ // ### Because of the way parallel anchors are created in the anchor simplification
+ // algorithm, we know that one of these will be a sequence, so it'll be safe if the other
+ // anchor create an edge between the same vertices as the parallel.
+ Q_ASSERT(parallel->firstEdge->type == AnchorData::Sequential
+ || parallel->secondEdge->type == AnchorData::Sequential);
+ restoreSimplifiedAnchor(parallel->firstEdge);
+ restoreSimplifiedAnchor(parallel->secondEdge);
+
+ delete parallel;
+ }
+}
+
+void QGraphicsAnchorLayoutPrivate::restoreSimplifiedConstraints(ParallelAnchorData *parallel)
+{
+ if (!parallel->isCenterAnchor)
+ return;
+
+ for (int i = 0; i < parallel->m_firstConstraints.count(); ++i) {
+ QSimplexConstraint *c = parallel->m_firstConstraints.at(i);
+ qreal v = c->variables[parallel];
+ c->variables.remove(parallel);
+ c->variables.insert(parallel->firstEdge, v);
+ }
+
+ // When restoring, we might have to revert constraints back. See comments on
+ // addAnchorMaybeParallel().
+ const bool needsReverse = !parallel->secondForward();
+
+ for (int i = 0; i < parallel->m_secondConstraints.count(); ++i) {
+ QSimplexConstraint *c = parallel->m_secondConstraints.at(i);
+ qreal v = c->variables[parallel];
+ if (needsReverse)
+ v *= -1;
+ c->variables.remove(parallel);
+ c->variables.insert(parallel->secondEdge, v);
+ }
+}
+
+void QGraphicsAnchorLayoutPrivate::restoreSimplifiedGraph(Orientation orientation)
+{
+#if 0
+ qDebug("Restoring Simplified Graph for %s",
+ orientation == Horizontal ? "Horizontal" : "Vertical");
+#endif
+
+ // Restore anchor simplification
+ Graph<AnchorVertex, AnchorData> &g = graph[orientation];
+ QList<QPair<AnchorVertex*, AnchorVertex*> > connections = g.connections();
+ for (int i = 0; i < connections.count(); ++i) {
+ AnchorVertex *v1 = connections.at(i).first;
+ AnchorVertex *v2 = connections.at(i).second;
+ AnchorData *edge = g.edgeData(v1, v2);
+
+ // We restore only sequential anchors and parallels that were not created by
+ // vertex simplification.
+ if (edge->type == AnchorData::Sequential
+ || (edge->type == AnchorData::Parallel &&
+ !anchorsFromSimplifiedVertices[orientation].contains(edge))) {
+
+ g.takeEdge(v1, v2);
+ restoreSimplifiedAnchor(edge);
+ }
+ }
+
+ restoreVertices(orientation);
+}
+
+void QGraphicsAnchorLayoutPrivate::restoreVertices(Orientation orientation)
+{
+ Q_Q(QGraphicsAnchorLayout);
+
+ Graph<AnchorVertex, AnchorData> &g = graph[orientation];
+ QList<AnchorVertexPair *> &toRestore = simplifiedVertices[orientation];
+
+ // Since we keep a list of parallel anchors and vertices that were created during vertex
+ // simplification, we can now iterate on those lists instead of traversing the graph
+ // recursively.
+
+ // First, restore the constraints changed when we created parallel anchors. Note that this
+ // works at this point because the constraints doesn't depend on vertex information and at
+ // this point it's always safe to identify whether the second child is forward or backwards.
+ // In the next step, we'll change the anchors vertices so that would not be possible anymore.
+ QList<AnchorData *> &parallelAnchors = anchorsFromSimplifiedVertices[orientation];
+
+ for (int i = parallelAnchors.count() - 1; i >= 0; --i) {
+ ParallelAnchorData *parallel = static_cast<ParallelAnchorData *>(parallelAnchors.at(i));
+ restoreSimplifiedConstraints(parallel);
+ }
+
+ // Then, we will restore the vertices in the inverse order of creation, this way we ensure that
+ // the vertex being restored was not wrapped by another simplification.
+ for (int i = toRestore.count() - 1; i >= 0; --i) {
+ AnchorVertexPair *pair = toRestore.at(i);
+ QList<AnchorVertex *> adjacents = g.adjacentVertices(pair);
+
+ // Restore the removed edge, this will also restore both vertices 'first' and 'second' to
+ // the graph structure.
+ AnchorVertex *first = pair->m_first;
+ AnchorVertex *second = pair->m_second;
+ g.createEdge(first, second, pair->m_removedAnchor);
+
+ // Restore the anchors for the first child vertex
+ for (int j = 0; j < pair->m_firstAnchors.count(); ++j) {
+ AnchorData *ad = pair->m_firstAnchors.at(j);
+ Q_ASSERT(ad->from == pair || ad->to == pair);
+
+ replaceVertex_helper(ad, pair, first);
+ g.createEdge(ad->from, ad->to, ad);
+ }
+
+ // Restore the anchors for the second child vertex
+ for (int j = 0; j < pair->m_secondAnchors.count(); ++j) {
+ AnchorData *ad = pair->m_secondAnchors.at(j);
+ Q_ASSERT(ad->from == pair || ad->to == pair);
+
+ replaceVertex_helper(ad, pair, second);
+ g.createEdge(ad->from, ad->to, ad);
+ }
+
+ for (int j = 0; j < adjacents.count(); ++j) {
+ g.takeEdge(pair, adjacents.at(j));
+ }
+
+ // The pair simplified a layout vertex, so place back the correct vertex in the variable
+ // that track layout vertices
+ if (pair->m_item == q) {
+ AnchorVertex *layoutVertex = first->m_item == q ? first : second;
+ Q_ASSERT(layoutVertex->m_item == q);
+ changeLayoutVertex(orientation, pair, layoutVertex);
+ }
+
+ delete pair;
+ }
+ qDeleteAll(parallelAnchors);
+ parallelAnchors.clear();
+ toRestore.clear();
+}
+
+QGraphicsAnchorLayoutPrivate::Orientation
+QGraphicsAnchorLayoutPrivate::edgeOrientation(Qt::AnchorPoint edge)
+{
+ return edge > Qt::AnchorRight ? Vertical : Horizontal;
+}
+
+/*!
+ \internal
+
+ Create internal anchors to connect the layout edges (Left to Right and
+ Top to Bottom).
+
+ These anchors doesn't have size restrictions, that will be enforced by
+ other anchors and items in the layout.
+*/
+void QGraphicsAnchorLayoutPrivate::createLayoutEdges()
+{
+ Q_Q(QGraphicsAnchorLayout);
+ QGraphicsLayoutItem *layout = q;
+
+ // Horizontal
+ AnchorData *data = new AnchorData;
+ addAnchor_helper(layout, Qt::AnchorLeft, layout,
+ Qt::AnchorRight, data);
+ data->maxSize = QWIDGETSIZE_MAX;
+
+ // Save a reference to layout vertices
+ layoutFirstVertex[Horizontal] = internalVertex(layout, Qt::AnchorLeft);
+ layoutCentralVertex[Horizontal] = 0;
+ layoutLastVertex[Horizontal] = internalVertex(layout, Qt::AnchorRight);
+
+ // Vertical
+ data = new AnchorData;
+ addAnchor_helper(layout, Qt::AnchorTop, layout,
+ Qt::AnchorBottom, data);
+ data->maxSize = QWIDGETSIZE_MAX;
+
+ // Save a reference to layout vertices
+ layoutFirstVertex[Vertical] = internalVertex(layout, Qt::AnchorTop);
+ layoutCentralVertex[Vertical] = 0;
+ layoutLastVertex[Vertical] = internalVertex(layout, Qt::AnchorBottom);
+}
+
+void QGraphicsAnchorLayoutPrivate::deleteLayoutEdges()
+{
+ Q_Q(QGraphicsAnchorLayout);
+
+ Q_ASSERT(!internalVertex(q, Qt::AnchorHorizontalCenter));
+ Q_ASSERT(!internalVertex(q, Qt::AnchorVerticalCenter));
+
+ removeAnchor_helper(internalVertex(q, Qt::AnchorLeft),
+ internalVertex(q, Qt::AnchorRight));
+ removeAnchor_helper(internalVertex(q, Qt::AnchorTop),
+ internalVertex(q, Qt::AnchorBottom));
+}
+
+void QGraphicsAnchorLayoutPrivate::createItemEdges(QGraphicsLayoutItem *item)
+{
+ items.append(item);
+
+ // Create horizontal and vertical internal anchors for the item and
+ // refresh its size hint / policy values.
+ AnchorData *data = new AnchorData;
+ addAnchor_helper(item, Qt::AnchorLeft, item, Qt::AnchorRight, data);
+ data->refreshSizeHints();
+
+ data = new AnchorData;
+ addAnchor_helper(item, Qt::AnchorTop, item, Qt::AnchorBottom, data);
+ data->refreshSizeHints();
+}
+
+/*!
+ \internal
+
+ By default, each item in the layout is represented internally as
+ a single anchor in each direction. For instance, from Left to Right.
+
+ However, to support anchorage of items to the center of items, we
+ must split this internal anchor into two half-anchors. From Left
+ to Center and then from Center to Right, with the restriction that
+ these anchors must have the same time at all times.
+*/
+void QGraphicsAnchorLayoutPrivate::createCenterAnchors(
+ QGraphicsLayoutItem *item, Qt::AnchorPoint centerEdge)
+{
+ Q_Q(QGraphicsAnchorLayout);
+
+ Orientation orientation;
+ switch (centerEdge) {
+ case Qt::AnchorHorizontalCenter:
+ orientation = Horizontal;
+ break;
+ case Qt::AnchorVerticalCenter:
+ orientation = Vertical;
+ break;
+ default:
+ // Don't create center edges unless needed
+ return;
+ }
+
+ // Check if vertex already exists
+ if (internalVertex(item, centerEdge))
+ return;
+
+ // Orientation code
+ Qt::AnchorPoint firstEdge;
+ Qt::AnchorPoint lastEdge;
+
+ if (orientation == Horizontal) {
+ firstEdge = Qt::AnchorLeft;
+ lastEdge = Qt::AnchorRight;
+ } else {
+ firstEdge = Qt::AnchorTop;
+ lastEdge = Qt::AnchorBottom;
+ }
+
+ AnchorVertex *first = internalVertex(item, firstEdge);
+ AnchorVertex *last = internalVertex(item, lastEdge);
+ Q_ASSERT(first && last);
+
+ // Create new anchors
+ QSimplexConstraint *c = new QSimplexConstraint;
+
+ AnchorData *data = new AnchorData;
+ c->variables.insert(data, 1.0);
+ addAnchor_helper(item, firstEdge, item, centerEdge, data);
+ data->isCenterAnchor = true;
+ data->dependency = AnchorData::Master;
+ data->refreshSizeHints();
+
+ data = new AnchorData;
+ c->variables.insert(data, -1.0);
+ addAnchor_helper(item, centerEdge, item, lastEdge, data);
+ data->isCenterAnchor = true;
+ data->dependency = AnchorData::Slave;
+ data->refreshSizeHints();
+
+ itemCenterConstraints[orientation].append(c);
+
+ // Remove old one
+ removeAnchor_helper(first, last);
+
+ if (item == q) {
+ layoutCentralVertex[orientation] = internalVertex(q, centerEdge);
+ }
+}
+
+void QGraphicsAnchorLayoutPrivate::removeCenterAnchors(
+ QGraphicsLayoutItem *item, Qt::AnchorPoint centerEdge,
+ bool substitute)
+{
+ Q_Q(QGraphicsAnchorLayout);
+
+ Orientation orientation;
+ switch (centerEdge) {
+ case Qt::AnchorHorizontalCenter:
+ orientation = Horizontal;
+ break;
+ case Qt::AnchorVerticalCenter:
+ orientation = Vertical;
+ break;
+ default:
+ // Don't remove edges that not the center ones
+ return;
+ }
+
+ // Orientation code
+ Qt::AnchorPoint firstEdge;
+ Qt::AnchorPoint lastEdge;
+
+ if (orientation == Horizontal) {
+ firstEdge = Qt::AnchorLeft;
+ lastEdge = Qt::AnchorRight;
+ } else {
+ firstEdge = Qt::AnchorTop;
+ lastEdge = Qt::AnchorBottom;
+ }
+
+ AnchorVertex *center = internalVertex(item, centerEdge);
+ if (!center)
+ return;
+ AnchorVertex *first = internalVertex(item, firstEdge);
+
+ Q_ASSERT(first);
+ Q_ASSERT(center);
+
+ Graph<AnchorVertex, AnchorData> &g = graph[orientation];
+
+
+ AnchorData *oldData = g.edgeData(first, center);
+ // Remove center constraint
+ for (int i = itemCenterConstraints[orientation].count() - 1; i >= 0; --i) {
+ if (itemCenterConstraints[orientation].at(i)->variables.contains(oldData)) {
+ delete itemCenterConstraints[orientation].takeAt(i);
+ break;
+ }
+ }
+
+ if (substitute) {
+ // Create the new anchor that should substitute the left-center-right anchors.
+ AnchorData *data = new AnchorData;
+ addAnchor_helper(item, firstEdge, item, lastEdge, data);
+ data->refreshSizeHints();
+
+ // Remove old anchors
+ removeAnchor_helper(first, center);
+ removeAnchor_helper(center, internalVertex(item, lastEdge));
+
+ } else {
+ // this is only called from removeAnchors()
+ // first, remove all non-internal anchors
+ QList<AnchorVertex*> adjacents = g.adjacentVertices(center);
+ for (int i = 0; i < adjacents.count(); ++i) {
+ AnchorVertex *v = adjacents.at(i);
+ if (v->m_item != item) {
+ removeAnchor_helper(center, internalVertex(v->m_item, v->m_edge));
+ }
+ }
+ // when all non-internal anchors is removed it will automatically merge the
+ // center anchor into a left-right (or top-bottom) anchor. We must also delete that.
+ // by this time, the center vertex is deleted and merged into a non-centered internal anchor
+ removeAnchor_helper(first, internalVertex(item, lastEdge));
+ }
+
+ if (item == q) {
+ layoutCentralVertex[orientation] = 0;
+ }
+}
+
+
+void QGraphicsAnchorLayoutPrivate::removeCenterConstraints(QGraphicsLayoutItem *item,
+ Orientation orientation)
+{
+ // Remove the item center constraints associated to this item
+ // ### This is a temporary solution. We should probably use a better
+ // data structure to hold items and/or their associated constraints
+ // so that we can remove those easily
+
+ AnchorVertex *first = internalVertex(item, orientation == Horizontal ?
+ Qt::AnchorLeft :
+ Qt::AnchorTop);
+ AnchorVertex *center = internalVertex(item, orientation == Horizontal ?
+ Qt::AnchorHorizontalCenter :
+ Qt::AnchorVerticalCenter);
+
+ // Skip if no center constraints exist
+ if (!center)
+ return;
+
+ Q_ASSERT(first);
+ AnchorData *internalAnchor = graph[orientation].edgeData(first, center);
+
+ // Look for our anchor in all item center constraints, then remove it
+ for (int i = 0; i < itemCenterConstraints[orientation].size(); ++i) {
+ if (itemCenterConstraints[orientation].at(i)->variables.contains(internalAnchor)) {
+ delete itemCenterConstraints[orientation].takeAt(i);
+ break;
+ }
+ }
+}
+
+/*!
+ * \internal
+ * Implements the high level "addAnchor" feature. Called by the public API
+ * addAnchor method.
+ *
+ * The optional \a spacing argument defines the size of the anchor. If not provided,
+ * the anchor size is either 0 or not-set, depending on type of anchor created (see
+ * matrix below).
+ *
+ * All anchors that remain with size not-set will assume the standard spacing,
+ * set either by the layout style or through the "setSpacing" layout API.
+ */
+QGraphicsAnchor *QGraphicsAnchorLayoutPrivate::addAnchor(QGraphicsLayoutItem *firstItem,
+ Qt::AnchorPoint firstEdge,
+ QGraphicsLayoutItem *secondItem,
+ Qt::AnchorPoint secondEdge,
+ qreal *spacing)
+{
+ Q_Q(QGraphicsAnchorLayout);
+ if ((firstItem == 0) || (secondItem == 0)) {
+ qWarning("QGraphicsAnchorLayout::addAnchor(): "
+ "Cannot anchor NULL items");
+ return 0;
+ }
+
+ if (firstItem == secondItem) {
+ qWarning("QGraphicsAnchorLayout::addAnchor(): "
+ "Cannot anchor the item to itself");
+ return 0;
+ }
+
+ if (edgeOrientation(secondEdge) != edgeOrientation(firstEdge)) {
+ qWarning("QGraphicsAnchorLayout::addAnchor(): "
+ "Cannot anchor edges of different orientations");
+ return 0;
+ }
+
+ const QGraphicsLayoutItem *parentWidget = q->parentLayoutItem();
+ if (firstItem == parentWidget || secondItem == parentWidget) {
+ qWarning("QGraphicsAnchorLayout::addAnchor(): "
+ "You cannot add the parent of the layout to the layout.");
+ return 0;
+ }
+
+ // In QGraphicsAnchorLayout, items are represented in its internal
+ // graph as four anchors that connect:
+ // - Left -> HCenter
+ // - HCenter-> Right
+ // - Top -> VCenter
+ // - VCenter -> Bottom
+
+ // Ensure that the internal anchors have been created for both items.
+ if (firstItem != q && !items.contains(firstItem)) {
+ createItemEdges(firstItem);
+ addChildLayoutItem(firstItem);
+ }
+ if (secondItem != q && !items.contains(secondItem)) {
+ createItemEdges(secondItem);
+ addChildLayoutItem(secondItem);
+ }
+
+ // Create center edges if needed
+ createCenterAnchors(firstItem, firstEdge);
+ createCenterAnchors(secondItem, secondEdge);
+
+ // Use heuristics to find out what the user meant with this anchor.
+ correctEdgeDirection(firstItem, firstEdge, secondItem, secondEdge);
+
+ AnchorData *data = new AnchorData;
+ QGraphicsAnchor *graphicsAnchor = acquireGraphicsAnchor(data);
+
+ addAnchor_helper(firstItem, firstEdge, secondItem, secondEdge, data);
+
+ if (spacing) {
+ graphicsAnchor->setSpacing(*spacing);
+ } else {
+ // If firstItem or secondItem is the layout itself, the spacing will default to 0.
+ // Otherwise, the following matrix is used (questionmark means that the spacing
+ // is queried from the style):
+ // from
+ // to Left HCenter Right
+ // Left 0 0 ?
+ // HCenter 0 0 0
+ // Right ? 0 0
+ if (firstItem == q
+ || secondItem == q
+ || pickEdge(firstEdge, Horizontal) == Qt::AnchorHorizontalCenter
+ || oppositeEdge(firstEdge) != secondEdge) {
+ graphicsAnchor->setSpacing(0);
+ } else {
+ graphicsAnchor->unsetSpacing();
+ }
+ }
+
+ return graphicsAnchor;
+}
+
+/*
+ \internal
+
+ This method adds an AnchorData to the internal graph. It is responsible for doing
+ the boilerplate part of such task.
+
+ If another AnchorData exists between the mentioned vertices, it is deleted and
+ the new one is inserted.
+*/
+void QGraphicsAnchorLayoutPrivate::addAnchor_helper(QGraphicsLayoutItem *firstItem,
+ Qt::AnchorPoint firstEdge,
+ QGraphicsLayoutItem *secondItem,
+ Qt::AnchorPoint secondEdge,
+ AnchorData *data)
+{
+ Q_Q(QGraphicsAnchorLayout);
+
+ const Orientation orientation = edgeOrientation(firstEdge);
+
+ // Create or increase the reference count for the related vertices.
+ AnchorVertex *v1 = addInternalVertex(firstItem, firstEdge);
+ AnchorVertex *v2 = addInternalVertex(secondItem, secondEdge);
+
+ // Remove previous anchor
+ if (graph[orientation].edgeData(v1, v2)) {
+ removeAnchor_helper(v1, v2);
+ }
+
+ // If its an internal anchor, set the associated item
+ if (firstItem == secondItem)
+ data->item = firstItem;
+
+ data->orientation = orientation;
+
+ // Create a bi-directional edge in the sense it can be transversed both
+ // from v1 or v2. "data" however is shared between the two references
+ // so we still know that the anchor direction is from 1 to 2.
+ data->from = v1;
+ data->to = v2;
+#ifdef QT_DEBUG
+ data->name = QString::fromAscii("%1 --to--> %2").arg(v1->toString()).arg(v2->toString());
+#endif
+ // ### bit to track internal anchors, since inside AnchorData methods
+ // we don't have access to the 'q' pointer.
+ data->isLayoutAnchor = (data->item == q);
+
+ graph[orientation].createEdge(v1, v2, data);
+}
+
+QGraphicsAnchor *QGraphicsAnchorLayoutPrivate::getAnchor(QGraphicsLayoutItem *firstItem,
+ Qt::AnchorPoint firstEdge,
+ QGraphicsLayoutItem *secondItem,
+ Qt::AnchorPoint secondEdge)
+{
+ // Do not expose internal anchors
+ if (firstItem == secondItem)
+ return 0;
+
+ const Orientation orientation = edgeOrientation(firstEdge);
+ AnchorVertex *v1 = internalVertex(firstItem, firstEdge);
+ AnchorVertex *v2 = internalVertex(secondItem, secondEdge);
+
+ QGraphicsAnchor *graphicsAnchor = 0;
+
+ AnchorData *data = graph[orientation].edgeData(v1, v2);
+ if (data) {
+ // We could use "acquireGraphicsAnchor" here, but to avoid a regression where
+ // an internal anchor was wrongly exposed, I want to ensure no new
+ // QGraphicsAnchor instances are created by this call.
+ // This assumption must hold because anchors are either user-created (and already
+ // have their public object created), or they are internal (and must not reach
+ // this point).
+ Q_ASSERT(data->graphicsAnchor);
+ graphicsAnchor = data->graphicsAnchor;
+ }
+ return graphicsAnchor;
+}
+
+/*!
+ * \internal
+ *
+ * Implements the high level "removeAnchor" feature. Called by
+ * the QAnchorData destructor.
+ */
+void QGraphicsAnchorLayoutPrivate::removeAnchor(AnchorVertex *firstVertex,
+ AnchorVertex *secondVertex)
+{
+ Q_Q(QGraphicsAnchorLayout);
+
+ // Save references to items while it's safe to assume the vertices exist
+ QGraphicsLayoutItem *firstItem = firstVertex->m_item;
+ QGraphicsLayoutItem *secondItem = secondVertex->m_item;
+
+ // Delete the anchor (may trigger deletion of center vertices)
+ removeAnchor_helper(firstVertex, secondVertex);
+
+ // Ensure no dangling pointer is left behind
+ firstVertex = secondVertex = 0;
+
+ // Checking if the item stays in the layout or not
+ bool keepFirstItem = false;
+ bool keepSecondItem = false;
+
+ QPair<AnchorVertex *, int> v;
+ int refcount = -1;
+
+ if (firstItem != q) {
+ for (int i = Qt::AnchorLeft; i <= Qt::AnchorBottom; ++i) {
+ v = m_vertexList.value(qMakePair(firstItem, static_cast<Qt::AnchorPoint>(i)));
+ if (v.first) {
+ if (i == Qt::AnchorHorizontalCenter || i == Qt::AnchorVerticalCenter)
+ refcount = 2;
+ else
+ refcount = 1;
+
+ if (v.second > refcount) {
+ keepFirstItem = true;
+ break;
+ }
+ }
+ }
+ } else
+ keepFirstItem = true;
+
+ if (secondItem != q) {
+ for (int i = Qt::AnchorLeft; i <= Qt::AnchorBottom; ++i) {
+ v = m_vertexList.value(qMakePair(secondItem, static_cast<Qt::AnchorPoint>(i)));
+ if (v.first) {
+ if (i == Qt::AnchorHorizontalCenter || i == Qt::AnchorVerticalCenter)
+ refcount = 2;
+ else
+ refcount = 1;
+
+ if (v.second > refcount) {
+ keepSecondItem = true;
+ break;
+ }
+ }
+ }
+ } else
+ keepSecondItem = true;
+
+ if (!keepFirstItem)
+ q->removeAt(items.indexOf(firstItem));
+
+ if (!keepSecondItem)
+ q->removeAt(items.indexOf(secondItem));
+
+ // Removing anchors invalidates the layout
+ q->invalidate();
+}
+
+/*
+ \internal
+
+ Implements the low level "removeAnchor" feature. Called by
+ private methods.
+*/
+void QGraphicsAnchorLayoutPrivate::removeAnchor_helper(AnchorVertex *v1, AnchorVertex *v2)
+{
+ Q_ASSERT(v1 && v2);
+
+ // Remove edge from graph
+ const Orientation o = edgeOrientation(v1->m_edge);
+ graph[o].removeEdge(v1, v2);
+
+ // Decrease vertices reference count (may trigger a deletion)
+ removeInternalVertex(v1->m_item, v1->m_edge);
+ removeInternalVertex(v2->m_item, v2->m_edge);
+}
+
+AnchorVertex *QGraphicsAnchorLayoutPrivate::addInternalVertex(QGraphicsLayoutItem *item,
+ Qt::AnchorPoint edge)
+{
+ QPair<QGraphicsLayoutItem *, Qt::AnchorPoint> pair(item, edge);
+ QPair<AnchorVertex *, int> v = m_vertexList.value(pair);
+
+ if (!v.first) {
+ Q_ASSERT(v.second == 0);
+ v.first = new AnchorVertex(item, edge);
+ }
+ v.second++;
+ m_vertexList.insert(pair, v);
+ return v.first;
+}
+
+/**
+ * \internal
+ *
+ * returns the AnchorVertex that was dereferenced, also when it was removed.
+ * returns 0 if it did not exist.
+ */
+void QGraphicsAnchorLayoutPrivate::removeInternalVertex(QGraphicsLayoutItem *item,
+ Qt::AnchorPoint edge)
+{
+ QPair<QGraphicsLayoutItem *, Qt::AnchorPoint> pair(item, edge);
+ QPair<AnchorVertex *, int> v = m_vertexList.value(pair);
+
+ if (!v.first) {
+ qWarning("This item with this edge is not in the graph");
+ return;
+ }
+
+ v.second--;
+ if (v.second == 0) {
+ // Remove reference and delete vertex
+ m_vertexList.remove(pair);
+ delete v.first;
+ } else {
+ // Update reference count
+ m_vertexList.insert(pair, v);
+
+ if ((v.second == 2) &&
+ ((edge == Qt::AnchorHorizontalCenter) ||
+ (edge == Qt::AnchorVerticalCenter))) {
+ removeCenterAnchors(item, edge, true);
+ }
+ }
+}
+
+void QGraphicsAnchorLayoutPrivate::removeVertex(QGraphicsLayoutItem *item, Qt::AnchorPoint edge)
+{
+ if (AnchorVertex *v = internalVertex(item, edge)) {
+ Graph<AnchorVertex, AnchorData> &g = graph[edgeOrientation(edge)];
+ const QList<AnchorVertex *> allVertices = graph[edgeOrientation(edge)].adjacentVertices(v);
+ AnchorVertex *v2;
+ foreach (v2, allVertices) {
+ g.removeEdge(v, v2);
+ removeInternalVertex(item, edge);
+ removeInternalVertex(v2->m_item, v2->m_edge);
+ }
+ }
+}
+
+void QGraphicsAnchorLayoutPrivate::removeAnchors(QGraphicsLayoutItem *item)
+{
+ // remove the center anchor first!!
+ removeCenterAnchors(item, Qt::AnchorHorizontalCenter, false);
+ removeVertex(item, Qt::AnchorLeft);
+ removeVertex(item, Qt::AnchorRight);
+
+ removeCenterAnchors(item, Qt::AnchorVerticalCenter, false);
+ removeVertex(item, Qt::AnchorTop);
+ removeVertex(item, Qt::AnchorBottom);
+}
+
+/*!
+ \internal
+
+ Use heuristics to determine the correct orientation of a given anchor.
+
+ After API discussions, we decided we would like expressions like
+ anchor(A, Left, B, Right) to mean the same as anchor(B, Right, A, Left).
+ The problem with this is that anchors could become ambiguous, for
+ instance, what does the anchor A, B of size X mean?
+
+ "pos(B) = pos(A) + X" or "pos(A) = pos(B) + X" ?
+
+ To keep the API user friendly and at the same time, keep our algorithm
+ deterministic, we use an heuristic to determine a direction for each
+ added anchor and then keep it. The heuristic is based on the fact
+ that people usually avoid overlapping items, therefore:
+
+ "A, RIGHT to B, LEFT" means that B is to the LEFT of A.
+ "B, LEFT to A, RIGHT" is corrected to the above anchor.
+
+ Special correction is also applied when one of the items is the
+ layout. We handle Layout Left as if it was another items's Right
+ and Layout Right as another item's Left.
+*/
+void QGraphicsAnchorLayoutPrivate::correctEdgeDirection(QGraphicsLayoutItem *&firstItem,
+ Qt::AnchorPoint &firstEdge,
+ QGraphicsLayoutItem *&secondItem,
+ Qt::AnchorPoint &secondEdge)
+{
+ Q_Q(QGraphicsAnchorLayout);
+
+ if ((firstItem != q) && (secondItem != q)) {
+ // If connection is between widgets (not the layout itself)
+ // Ensure that "right-edges" sit to the left of "left-edges".
+ if (firstEdge < secondEdge) {
+ qSwap(firstItem, secondItem);
+ qSwap(firstEdge, secondEdge);
+ }
+ } else if (firstItem == q) {
+ // If connection involves the right or bottom of a layout, ensure
+ // the layout is the second item.
+ if ((firstEdge == Qt::AnchorRight) || (firstEdge == Qt::AnchorBottom)) {
+ qSwap(firstItem, secondItem);
+ qSwap(firstEdge, secondEdge);
+ }
+ } else if ((secondEdge != Qt::AnchorRight) && (secondEdge != Qt::AnchorBottom)) {
+ // If connection involves the left, center or top of layout, ensure
+ // the layout is the first item.
+ qSwap(firstItem, secondItem);
+ qSwap(firstEdge, secondEdge);
+ }
+}
+
+QLayoutStyleInfo &QGraphicsAnchorLayoutPrivate::styleInfo() const
+{
+ if (styleInfoDirty) {
+ Q_Q(const QGraphicsAnchorLayout);
+ //### Fix this if QGV ever gets support for Metal style or different Aqua sizes.
+ QWidget *wid = 0;
+
+ QGraphicsLayoutItem *parent = q->parentLayoutItem();
+ while (parent && parent->isLayout()) {
+ parent = parent->parentLayoutItem();
+ }
+ QGraphicsWidget *w = 0;
+ if (parent) {
+ QGraphicsItem *parentItem = parent->graphicsItem();
+ if (parentItem && parentItem->isWidget())
+ w = static_cast<QGraphicsWidget*>(parentItem);
+ }
+
+ QStyle *style = w ? w->style() : QApplication::style();
+ cachedStyleInfo = QLayoutStyleInfo(style, wid);
+ cachedStyleInfo.setDefaultSpacing(Qt::Horizontal, spacings[0]);
+ cachedStyleInfo.setDefaultSpacing(Qt::Vertical, spacings[1]);
+
+ styleInfoDirty = false;
+ }
+ return cachedStyleInfo;
+}
+
+/*!
+ \internal
+
+ Called on activation. Uses Linear Programming to define minimum, preferred
+ and maximum sizes for the layout. Also calculates the sizes that each item
+ should assume when the layout is in one of such situations.
+*/
+void QGraphicsAnchorLayoutPrivate::calculateGraphs()
+{
+ if (!calculateGraphCacheDirty)
+ return;
+ calculateGraphs(Horizontal);
+ calculateGraphs(Vertical);
+ calculateGraphCacheDirty = false;
+}
+
+// ### Maybe getGraphParts could return the variables when traversing, at least
+// for trunk...
+QList<AnchorData *> getVariables(QList<QSimplexConstraint *> constraints)
+{
+ QSet<AnchorData *> variableSet;
+ for (int i = 0; i < constraints.count(); ++i) {
+ const QSimplexConstraint *c = constraints.at(i);
+ foreach (QSimplexVariable *var, c->variables.keys()) {
+ variableSet += static_cast<AnchorData *>(var);
+ }
+ }
+ return variableSet.toList();
+}
+
+/*!
+ \internal
+
+ Calculate graphs is the method that puts together all the helper routines
+ so that the AnchorLayout can calculate the sizes of each item.
+
+ In a nutshell it should do:
+
+ 1) Refresh anchor nominal sizes, that is, the size that each anchor would
+ have if no other restrictions applied. This is done by quering the
+ layout style and the sizeHints of the items belonging to the layout.
+
+ 2) Simplify the graph by grouping together parallel and sequential anchors
+ into "group anchors". These have equivalent minimum, preferred and maximum
+ sizeHints as the anchors they replace.
+
+ 3) Check if we got to a trivial case. In some cases, the whole graph can be
+ simplified into a single anchor. If so, use this information. If not,
+ then call the Simplex solver to calculate the anchors sizes.
+
+ 4) Once the root anchors had its sizes calculated, propagate that to the
+ anchors they represent.
+*/
+void QGraphicsAnchorLayoutPrivate::calculateGraphs(
+ QGraphicsAnchorLayoutPrivate::Orientation orientation)
+{
+#if defined(QT_DEBUG) || defined(Q_AUTOTEST_EXPORT)
+ lastCalculationUsedSimplex[orientation] = false;
+#endif
+
+ static bool simplificationEnabled = qgetenv("QT_ANCHORLAYOUT_NO_SIMPLIFICATION").isEmpty();
+
+ // Reset the nominal sizes of each anchor based on the current item sizes
+ refreshAllSizeHints(orientation);
+
+ // Simplify the graph
+ if (simplificationEnabled && !simplifyGraph(orientation)) {
+ qWarning("QGraphicsAnchorLayout: anchor setup is not feasible.");
+ graphHasConflicts[orientation] = true;
+ return;
+ }
+
+ // Traverse all graph edges and store the possible paths to each vertex
+ findPaths(orientation);
+
+ // From the paths calculated above, extract the constraints that the current
+ // anchor setup impose, to our Linear Programming problem.
+ constraintsFromPaths(orientation);
+
+ // Split the constraints and anchors into groups that should be fed to the
+ // simplex solver independently. Currently we find two groups:
+ //
+ // 1) The "trunk", that is, the set of anchors (items) that are connected
+ // to the two opposite sides of our layout, and thus need to stretch in
+ // order to fit in the current layout size.
+ //
+ // 2) The floating or semi-floating anchors (items) that are those which
+ // are connected to only one (or none) of the layout sides, thus are not
+ // influenced by the layout size.
+ QList<QList<QSimplexConstraint *> > parts = getGraphParts(orientation);
+
+ // Now run the simplex solver to calculate Minimum, Preferred and Maximum sizes
+ // of the "trunk" set of constraints and variables.
+ // ### does trunk always exist? empty = trunk is the layout left->center->right
+ QList<QSimplexConstraint *> trunkConstraints = parts.at(0);
+ QList<AnchorData *> trunkVariables = getVariables(trunkConstraints);
+
+ // For minimum and maximum, use the path between the two layout sides as the
+ // objective function.
+ AnchorVertex *v = layoutLastVertex[orientation];
+ GraphPath trunkPath = graphPaths[orientation].value(v);
+
+ bool feasible = calculateTrunk(orientation, trunkPath, trunkConstraints, trunkVariables);
+
+ // For the other parts that not the trunk, solve only for the preferred size
+ // that is the size they will remain at, since they are not stretched by the
+ // layout.
+
+ // Skipping the first (trunk)
+ for (int i = 1; i < parts.count(); ++i) {
+ if (!feasible)
+ break;
+
+ QList<QSimplexConstraint *> partConstraints = parts.at(i);
+ QList<AnchorData *> partVariables = getVariables(partConstraints);
+ Q_ASSERT(!partVariables.isEmpty());
+ feasible &= calculateNonTrunk(partConstraints, partVariables);
+ }
+
+ // Propagate the new sizes down the simplified graph, ie. tell the
+ // group anchors to set their children anchors sizes.
+ updateAnchorSizes(orientation);
+
+ graphHasConflicts[orientation] = !feasible;
+
+ // Clean up our data structures. They are not needed anymore since
+ // distribution uses just interpolation.
+ qDeleteAll(constraints[orientation]);
+ constraints[orientation].clear();
+ graphPaths[orientation].clear(); // ###
+
+ if (simplificationEnabled)
+ restoreSimplifiedGraph(orientation);
+}
+
+/*!
+ \internal
+
+ Shift all the constraints by a certain amount. This allows us to deal with negative values in
+ the linear program if they are bounded by a certain limit. Functions should be careful to
+ call it again with a negative amount, to shift the constraints back.
+*/
+static void shiftConstraints(const QList<QSimplexConstraint *> &constraints, qreal amount)
+{
+ for (int i = 0; i < constraints.count(); ++i) {
+ QSimplexConstraint *c = constraints.at(i);
+ qreal multiplier = 0;
+ foreach (qreal v, c->variables.values()) {
+ multiplier += v;
+ }
+ c->constant += multiplier * amount;
+ }
+}
+
+/*!
+ \internal
+
+ Calculate the sizes for all anchors which are part of the trunk. This works
+ on top of a (possibly) simplified graph.
+*/
+bool QGraphicsAnchorLayoutPrivate::calculateTrunk(Orientation orientation, const GraphPath &path,
+ const QList<QSimplexConstraint *> &constraints,
+ const QList<AnchorData *> &variables)
+{
+ bool feasible = true;
+ bool needsSimplex = !constraints.isEmpty();
+
+#if 0
+ qDebug("Simplex %s for trunk of %s", needsSimplex ? "used" : "NOT used",
+ orientation == Horizontal ? "Horizontal" : "Vertical");
+#endif
+
+ if (needsSimplex) {
+
+ QList<QSimplexConstraint *> sizeHintConstraints = constraintsFromSizeHints(variables);
+ QList<QSimplexConstraint *> allConstraints = constraints + sizeHintConstraints;
+
+ shiftConstraints(allConstraints, g_offset);
+
+ // Solve min and max size hints
+ qreal min, max;
+ feasible = solveMinMax(allConstraints, path, &min, &max);
+
+ if (feasible) {
+ solvePreferred(constraints, variables);
+
+ // Calculate and set the preferred size for the layout,
+ // from the edge sizes that were calculated above.
+ qreal pref(0.0);
+ foreach (const AnchorData *ad, path.positives) {
+ pref += ad->sizeAtPreferred;
+ }
+ foreach (const AnchorData *ad, path.negatives) {
+ pref -= ad->sizeAtPreferred;
+ }
+
+ sizeHints[orientation][Qt::MinimumSize] = min;
+ sizeHints[orientation][Qt::PreferredSize] = pref;
+ sizeHints[orientation][Qt::MaximumSize] = max;
+ }
+
+ qDeleteAll(sizeHintConstraints);
+ shiftConstraints(constraints, -g_offset);
+
+ } else {
+ // No Simplex is necessary because the path was simplified all the way to a single
+ // anchor.
+ Q_ASSERT(path.positives.count() == 1);
+ Q_ASSERT(path.negatives.count() == 0);
+
+ AnchorData *ad = path.positives.toList()[0];
+ ad->sizeAtMinimum = ad->minSize;
+ ad->sizeAtPreferred = ad->prefSize;
+ ad->sizeAtMaximum = ad->maxSize;
+
+ sizeHints[orientation][Qt::MinimumSize] = ad->sizeAtMinimum;
+ sizeHints[orientation][Qt::PreferredSize] = ad->sizeAtPreferred;
+ sizeHints[orientation][Qt::MaximumSize] = ad->sizeAtMaximum;
+ }
+
+#if defined(QT_DEBUG) || defined(Q_AUTOTEST_EXPORT)
+ lastCalculationUsedSimplex[orientation] = needsSimplex;
+#endif
+
+ return feasible;
+}
+
+/*!
+ \internal
+*/
+bool QGraphicsAnchorLayoutPrivate::calculateNonTrunk(const QList<QSimplexConstraint *> &constraints,
+ const QList<AnchorData *> &variables)
+{
+ shiftConstraints(constraints, g_offset);
+ bool feasible = solvePreferred(constraints, variables);
+
+ if (feasible) {
+ // Propagate size at preferred to other sizes. Semi-floats always will be
+ // in their sizeAtPreferred.
+ for (int j = 0; j < variables.count(); ++j) {
+ AnchorData *ad = variables.at(j);
+ Q_ASSERT(ad);
+ ad->sizeAtMinimum = ad->sizeAtPreferred;
+ ad->sizeAtMaximum = ad->sizeAtPreferred;
+ }
+ }
+
+ shiftConstraints(constraints, -g_offset);
+ return feasible;
+}
+
+/*!
+ \internal
+
+ Traverse the graph refreshing the size hints. Edges will query their associated
+ item or graphicsAnchor for their size hints.
+*/
+void QGraphicsAnchorLayoutPrivate::refreshAllSizeHints(Orientation orientation)
+{
+ Graph<AnchorVertex, AnchorData> &g = graph[orientation];
+ QList<QPair<AnchorVertex *, AnchorVertex *> > vertices = g.connections();
+
+ QLayoutStyleInfo styleInf = styleInfo();
+ for (int i = 0; i < vertices.count(); ++i) {
+ AnchorData *data = g.edgeData(vertices.at(i).first, vertices.at(i).second);
+ data->refreshSizeHints(&styleInf);
+ }
+}
+
+/*!
+ \internal
+
+ This method walks the graph using a breadth-first search to find paths
+ between the root vertex and each vertex on the graph. The edges
+ directions in each path are considered and they are stored as a
+ positive edge (left-to-right) or negative edge (right-to-left).
+
+ The list of paths is used later to generate a list of constraints.
+ */
+void QGraphicsAnchorLayoutPrivate::findPaths(Orientation orientation)
+{
+ QQueue<QPair<AnchorVertex *, AnchorVertex *> > queue;
+
+ QSet<AnchorData *> visited;
+
+ AnchorVertex *root = layoutFirstVertex[orientation];
+
+ graphPaths[orientation].insert(root, GraphPath());
+
+ foreach (AnchorVertex *v, graph[orientation].adjacentVertices(root)) {
+ queue.enqueue(qMakePair(root, v));
+ }
+
+ while(!queue.isEmpty()) {
+ QPair<AnchorVertex *, AnchorVertex *> pair = queue.dequeue();
+ AnchorData *edge = graph[orientation].edgeData(pair.first, pair.second);
+
+ if (visited.contains(edge))
+ continue;
+
+ visited.insert(edge);
+ GraphPath current = graphPaths[orientation].value(pair.first);
+
+ if (edge->from == pair.first)
+ current.positives.insert(edge);
+ else
+ current.negatives.insert(edge);
+
+ graphPaths[orientation].insert(pair.second, current);
+
+ foreach (AnchorVertex *v,
+ graph[orientation].adjacentVertices(pair.second)) {
+ queue.enqueue(qMakePair(pair.second, v));
+ }
+ }
+
+ // We will walk through every reachable items (non-float) store them in a temporary set.
+ // We them create a set of all items and subtract the non-floating items from the set in
+ // order to get the floating items. The floating items is then stored in m_floatItems
+ identifyFloatItems(visited, orientation);
+}
+
+/*!
+ \internal
+
+ Each vertex on the graph that has more than one path to it
+ represents a contra int to the sizes of the items in these paths.
+
+ This method walks the list of paths to each vertex, generate
+ the constraints and store them in a list so they can be used later
+ by the Simplex solver.
+*/
+void QGraphicsAnchorLayoutPrivate::constraintsFromPaths(Orientation orientation)
+{
+ foreach (AnchorVertex *vertex, graphPaths[orientation].uniqueKeys())
+ {
+ int valueCount = graphPaths[orientation].count(vertex);
+ if (valueCount == 1)
+ continue;
+
+ QList<GraphPath> pathsToVertex = graphPaths[orientation].values(vertex);
+ for (int i = 1; i < valueCount; ++i) {
+ constraints[orientation] += \
+ pathsToVertex[0].constraint(pathsToVertex.at(i));
+ }
+ }
+}
+
+/*!
+ \internal
+*/
+void QGraphicsAnchorLayoutPrivate::updateAnchorSizes(Orientation orientation)
+{
+ Graph<AnchorVertex, AnchorData> &g = graph[orientation];
+ const QList<QPair<AnchorVertex *, AnchorVertex *> > &vertices = g.connections();
+
+ for (int i = 0; i < vertices.count(); ++i) {
+ AnchorData *ad = g.edgeData(vertices.at(i).first, vertices.at(i).second);
+ ad->updateChildrenSizes();
+ }
+}
+
+/*!
+ \internal
+
+ Create LP constraints for each anchor based on its minimum and maximum
+ sizes, as specified in its size hints
+*/
+QList<QSimplexConstraint *> QGraphicsAnchorLayoutPrivate::constraintsFromSizeHints(
+ const QList<AnchorData *> &anchors)
+{
+ if (anchors.isEmpty())
+ return QList<QSimplexConstraint *>();
+
+ // Look for the layout edge. That can be either the first half in case the
+ // layout is split in two, or the whole layout anchor.
+ Orientation orient = Orientation(anchors.first()->orientation);
+ AnchorData *layoutEdge = 0;
+ if (layoutCentralVertex[orient]) {
+ layoutEdge = graph[orient].edgeData(layoutFirstVertex[orient], layoutCentralVertex[orient]);
+ } else {
+ layoutEdge = graph[orient].edgeData(layoutFirstVertex[orient], layoutLastVertex[orient]);
+ }
+
+ // If maxSize is less then "infinite", that means there are other anchors
+ // grouped together with this one. We can't ignore its maximum value so we
+ // set back the variable to NULL to prevent the continue condition from being
+ // satisfied in the loop below.
+ const qreal expectedMax = layoutCentralVertex[orient] ? QWIDGETSIZE_MAX / 2 : QWIDGETSIZE_MAX;
+ qreal actualMax;
+ if (layoutEdge->from == layoutFirstVertex[orient]) {
+ actualMax = layoutEdge->maxSize;
+ } else {
+ actualMax = -layoutEdge->minSize;
+ }
+ if (actualMax != expectedMax) {
+ layoutEdge = 0;
+ }
+
+ // For each variable, create constraints based on size hints
+ QList<QSimplexConstraint *> anchorConstraints;
+ bool unboundedProblem = true;
+ for (int i = 0; i < anchors.size(); ++i) {
+ AnchorData *ad = anchors.at(i);
+
+ // Anchors that have their size directly linked to another one don't need constraints
+ // For exammple, the second half of an item has exactly the same size as the first half
+ // thus constraining the latter is enough.
+ if (ad->dependency == AnchorData::Slave)
+ continue;
+
+ // To use negative variables inside simplex, we shift them so the minimum negative value is
+ // mapped to zero before solving. To make sure that it works, we need to guarantee that the
+ // variables are all inside a certain boundary.
+ qreal boundedMin = qBound(-g_offset, ad->minSize, g_offset);
+ qreal boundedMax = qBound(-g_offset, ad->maxSize, g_offset);
+
+ if ((boundedMin == boundedMax) || qFuzzyCompare(boundedMin, boundedMax)) {
+ QSimplexConstraint *c = new QSimplexConstraint;
+ c->variables.insert(ad, 1.0);
+ c->constant = boundedMin;
+ c->ratio = QSimplexConstraint::Equal;
+ anchorConstraints += c;
+ unboundedProblem = false;
+ } else {
+ QSimplexConstraint *c = new QSimplexConstraint;
+ c->variables.insert(ad, 1.0);
+ c->constant = boundedMin;
+ c->ratio = QSimplexConstraint::MoreOrEqual;
+ anchorConstraints += c;
+
+ // We avoid adding restrictions to the layout internal anchors. That's
+ // to prevent unnecessary fair distribution from happening due to this
+ // artificial restriction.
+ if (ad == layoutEdge)
+ continue;
+
+ c = new QSimplexConstraint;
+ c->variables.insert(ad, 1.0);
+ c->constant = boundedMax;
+ c->ratio = QSimplexConstraint::LessOrEqual;
+ anchorConstraints += c;
+ unboundedProblem = false;
+ }
+ }
+
+ // If no upper boundary restriction was added, add one to avoid unbounded problem
+ if (unboundedProblem) {
+ QSimplexConstraint *c = new QSimplexConstraint;
+ c->variables.insert(layoutEdge, 1.0);
+ // The maximum size that the layout can take
+ c->constant = g_offset;
+ c->ratio = QSimplexConstraint::LessOrEqual;
+ anchorConstraints += c;
+ }
+
+ return anchorConstraints;
+}
+
+/*!
+ \internal
+*/
+QList< QList<QSimplexConstraint *> >
+QGraphicsAnchorLayoutPrivate::getGraphParts(Orientation orientation)
+{
+ Q_ASSERT(layoutFirstVertex[orientation] && layoutLastVertex[orientation]);
+
+ AnchorData *edgeL1 = 0;
+ AnchorData *edgeL2 = 0;
+
+ // The layout may have a single anchor between Left and Right or two half anchors
+ // passing through the center
+ if (layoutCentralVertex[orientation]) {
+ edgeL1 = graph[orientation].edgeData(layoutFirstVertex[orientation], layoutCentralVertex[orientation]);
+ edgeL2 = graph[orientation].edgeData(layoutCentralVertex[orientation], layoutLastVertex[orientation]);
+ } else {
+ edgeL1 = graph[orientation].edgeData(layoutFirstVertex[orientation], layoutLastVertex[orientation]);
+ }
+
+ QLinkedList<QSimplexConstraint *> remainingConstraints;
+ for (int i = 0; i < constraints[orientation].count(); ++i) {
+ remainingConstraints += constraints[orientation].at(i);
+ }
+ for (int i = 0; i < itemCenterConstraints[orientation].count(); ++i) {
+ remainingConstraints += itemCenterConstraints[orientation].at(i);
+ }
+
+ QList<QSimplexConstraint *> trunkConstraints;
+ QSet<QSimplexVariable *> trunkVariables;
+
+ trunkVariables += edgeL1;
+ if (edgeL2)
+ trunkVariables += edgeL2;
+
+ bool dirty;
+ do {
+ dirty = false;
+
+ QLinkedList<QSimplexConstraint *>::iterator it = remainingConstraints.begin();
+ while (it != remainingConstraints.end()) {
+ QSimplexConstraint *c = *it;
+ bool match = false;
+
+ // Check if this constraint have some overlap with current
+ // trunk variables...
+ foreach (QSimplexVariable *ad, trunkVariables) {
+ if (c->variables.contains(ad)) {
+ match = true;
+ break;
+ }
+ }
+
+ // If so, we add it to trunk, and erase it from the
+ // remaining constraints.
+ if (match) {
+ trunkConstraints += c;
+ trunkVariables += QSet<QSimplexVariable *>::fromList(c->variables.keys());
+ it = remainingConstraints.erase(it);
+ dirty = true;
+ } else {
+ // Note that we don't erase the constraint if it's not
+ // a match, since in a next iteration of a do-while we
+ // can pass on it again and it will be a match.
+ //
+ // For example: if trunk share a variable with
+ // remainingConstraints[1] and it shares with
+ // remainingConstraints[0], we need a second iteration
+ // of the do-while loop to match both.
+ ++it;
+ }
+ }
+ } while (dirty);
+
+ QList< QList<QSimplexConstraint *> > result;
+ result += trunkConstraints;
+
+ if (!remainingConstraints.isEmpty()) {
+ QList<QSimplexConstraint *> nonTrunkConstraints;
+ QLinkedList<QSimplexConstraint *>::iterator it = remainingConstraints.begin();
+ while (it != remainingConstraints.end()) {
+ nonTrunkConstraints += *it;
+ ++it;
+ }
+ result += nonTrunkConstraints;
+ }
+
+ return result;
+}
+
+/*!
+ \internal
+
+ Use all visited Anchors on findPaths() so we can identify non-float Items.
+*/
+void QGraphicsAnchorLayoutPrivate::identifyFloatItems(const QSet<AnchorData *> &visited, Orientation orientation)
+{
+ QSet<QGraphicsLayoutItem *> nonFloating;
+
+ foreach (const AnchorData *ad, visited)
+ identifyNonFloatItems_helper(ad, &nonFloating);
+
+ QSet<QGraphicsLayoutItem *> allItems;
+ foreach (QGraphicsLayoutItem *item, items)
+ allItems.insert(item);
+ m_floatItems[orientation] = allItems - nonFloating;
+}
+
+
+/*!
+ \internal
+
+ Given an anchor, if it is an internal anchor and Normal we must mark it's item as non-float.
+ If the anchor is Sequential or Parallel, we must iterate on its children recursively until we reach
+ internal anchors (items).
+*/
+void QGraphicsAnchorLayoutPrivate::identifyNonFloatItems_helper(const AnchorData *ad, QSet<QGraphicsLayoutItem *> *nonFloatingItemsIdentifiedSoFar)
+{
+ Q_Q(QGraphicsAnchorLayout);
+
+ switch(ad->type) {
+ case AnchorData::Normal:
+ if (ad->item && ad->item != q)
+ nonFloatingItemsIdentifiedSoFar->insert(ad->item);
+ break;
+ case AnchorData::Sequential:
+ foreach (const AnchorData *d, static_cast<const SequentialAnchorData *>(ad)->m_edges)
+ identifyNonFloatItems_helper(d, nonFloatingItemsIdentifiedSoFar);
+ break;
+ case AnchorData::Parallel:
+ identifyNonFloatItems_helper(static_cast<const ParallelAnchorData *>(ad)->firstEdge, nonFloatingItemsIdentifiedSoFar);
+ identifyNonFloatItems_helper(static_cast<const ParallelAnchorData *>(ad)->secondEdge, nonFloatingItemsIdentifiedSoFar);
+ break;
+ }
+}
+
+/*!
+ \internal
+
+ Use the current vertices distance to calculate and set the geometry of
+ each item.
+*/
+void QGraphicsAnchorLayoutPrivate::setItemsGeometries(const QRectF &geom)
+{
+ Q_Q(QGraphicsAnchorLayout);
+ AnchorVertex *firstH, *secondH, *firstV, *secondV;
+
+ qreal top;
+ qreal left;
+ qreal right;
+
+ q->getContentsMargins(&left, &top, &right, 0);
+ const Qt::LayoutDirection visualDir = visualDirection();
+ if (visualDir == Qt::RightToLeft)
+ qSwap(left, right);
+
+ left += geom.left();
+ top += geom.top();
+ right = geom.right() - right;
+
+ foreach (QGraphicsLayoutItem *item, items) {
+ QRectF newGeom;
+ QSizeF itemPreferredSize = item->effectiveSizeHint(Qt::PreferredSize);
+ if (m_floatItems[Horizontal].contains(item)) {
+ newGeom.setLeft(0);
+ newGeom.setRight(itemPreferredSize.width());
+ } else {
+ firstH = internalVertex(item, Qt::AnchorLeft);
+ secondH = internalVertex(item, Qt::AnchorRight);
+
+ if (visualDir == Qt::LeftToRight) {
+ newGeom.setLeft(left + firstH->distance);
+ newGeom.setRight(left + secondH->distance);
+ } else {
+ newGeom.setLeft(right - secondH->distance);
+ newGeom.setRight(right - firstH->distance);
+ }
+ }
+
+ if (m_floatItems[Vertical].contains(item)) {
+ newGeom.setTop(0);
+ newGeom.setBottom(itemPreferredSize.height());
+ } else {
+ firstV = internalVertex(item, Qt::AnchorTop);
+ secondV = internalVertex(item, Qt::AnchorBottom);
+
+ newGeom.setTop(top + firstV->distance);
+ newGeom.setBottom(top + secondV->distance);
+ }
+
+ item->setGeometry(newGeom);
+ }
+}
+
+/*!
+ \internal
+
+ Calculate the position of each vertex based on the paths to each of
+ them as well as the current edges sizes.
+*/
+void QGraphicsAnchorLayoutPrivate::calculateVertexPositions(
+ QGraphicsAnchorLayoutPrivate::Orientation orientation)
+{
+ QQueue<QPair<AnchorVertex *, AnchorVertex *> > queue;
+ QSet<AnchorVertex *> visited;
+
+ // Get root vertex
+ AnchorVertex *root = layoutFirstVertex[orientation];
+
+ root->distance = 0;
+ visited.insert(root);
+
+ // Add initial edges to the queue
+ foreach (AnchorVertex *v, graph[orientation].adjacentVertices(root)) {
+ queue.enqueue(qMakePair(root, v));
+ }
+
+ // Do initial calculation required by "interpolateEdge()"
+ setupEdgesInterpolation(orientation);
+
+ // Traverse the graph and calculate vertex positions
+ while (!queue.isEmpty()) {
+ QPair<AnchorVertex *, AnchorVertex *> pair = queue.dequeue();
+ AnchorData *edge = graph[orientation].edgeData(pair.first, pair.second);
+
+ if (visited.contains(pair.second))
+ continue;
+
+ visited.insert(pair.second);
+ interpolateEdge(pair.first, edge);
+
+ QList<AnchorVertex *> adjacents = graph[orientation].adjacentVertices(pair.second);
+ for (int i = 0; i < adjacents.count(); ++i) {
+ if (!visited.contains(adjacents.at(i)))
+ queue.enqueue(qMakePair(pair.second, adjacents.at(i)));
+ }
+ }
+}
+
+/*!
+ \internal
+
+ Calculate interpolation parameters based on current Layout Size.
+ Must be called once before calling "interpolateEdgeSize()" for
+ the edges.
+*/
+void QGraphicsAnchorLayoutPrivate::setupEdgesInterpolation(
+ Orientation orientation)
+{
+ Q_Q(QGraphicsAnchorLayout);
+
+ qreal current;
+ current = (orientation == Horizontal) ? q->contentsRect().width() : q->contentsRect().height();
+
+ QPair<Interval, qreal> result;
+ result = getFactor(current,
+ sizeHints[orientation][Qt::MinimumSize],
+ sizeHints[orientation][Qt::PreferredSize],
+ sizeHints[orientation][Qt::PreferredSize],
+ sizeHints[orientation][Qt::PreferredSize],
+ sizeHints[orientation][Qt::MaximumSize]);
+
+ interpolationInterval[orientation] = result.first;
+ interpolationProgress[orientation] = result.second;
+}
+
+/*!
+ \internal
+
+ Calculate the current Edge size based on the current Layout size and the
+ size the edge is supposed to have when the layout is at its:
+
+ - minimum size,
+ - preferred size,
+ - maximum size.
+
+ These three key values are calculated in advance using linear
+ programming (more expensive) or the simplification algorithm, then
+ subsequential resizes of the parent layout require a simple
+ interpolation.
+*/
+void QGraphicsAnchorLayoutPrivate::interpolateEdge(AnchorVertex *base, AnchorData *edge)
+{
+ const Orientation orientation = Orientation(edge->orientation);
+ const QPair<Interval, qreal> factor(interpolationInterval[orientation],
+ interpolationProgress[orientation]);
+
+ qreal edgeDistance = interpolate(factor, edge->sizeAtMinimum, edge->sizeAtPreferred,
+ edge->sizeAtPreferred, edge->sizeAtPreferred,
+ edge->sizeAtMaximum);
+
+ Q_ASSERT(edge->from == base || edge->to == base);
+
+ // Calculate the distance for the vertex opposite to the base
+ if (edge->from == base) {
+ edge->to->distance = base->distance + edgeDistance;
+ } else {
+ edge->from->distance = base->distance - edgeDistance;
+ }
+}
+
+bool QGraphicsAnchorLayoutPrivate::solveMinMax(const QList<QSimplexConstraint *> &constraints,
+ GraphPath path, qreal *min, qreal *max)
+{
+ QSimplex simplex;
+ bool feasible = simplex.setConstraints(constraints);
+ if (feasible) {
+ // Obtain the objective constraint
+ QSimplexConstraint objective;
+ QSet<AnchorData *>::const_iterator iter;
+ for (iter = path.positives.constBegin(); iter != path.positives.constEnd(); ++iter)
+ objective.variables.insert(*iter, 1.0);
+
+ for (iter = path.negatives.constBegin(); iter != path.negatives.constEnd(); ++iter)
+ objective.variables.insert(*iter, -1.0);
+
+ const qreal objectiveOffset = (path.positives.count() - path.negatives.count()) * g_offset;
+ simplex.setObjective(&objective);
+
+ // Calculate minimum values
+ *min = simplex.solveMin() - objectiveOffset;
+
+ // Save sizeAtMinimum results
+ QList<AnchorData *> variables = getVariables(constraints);
+ for (int i = 0; i < variables.size(); ++i) {
+ AnchorData *ad = static_cast<AnchorData *>(variables.at(i));
+ ad->sizeAtMinimum = ad->result - g_offset;
+ }
+
+ // Calculate maximum values
+ *max = simplex.solveMax() - objectiveOffset;
+
+ // Save sizeAtMaximum results
+ for (int i = 0; i < variables.size(); ++i) {
+ AnchorData *ad = static_cast<AnchorData *>(variables.at(i));
+ ad->sizeAtMaximum = ad->result - g_offset;
+ }
+ }
+ return feasible;
+}
+
+enum slackType { Grower = -1, Shrinker = 1 };
+static QPair<QSimplexVariable *, QSimplexConstraint *> createSlack(QSimplexConstraint *sizeConstraint,
+ qreal interval, slackType type)
+{
+ QSimplexVariable *slack = new QSimplexVariable;
+ sizeConstraint->variables.insert(slack, type);
+
+ QSimplexConstraint *limit = new QSimplexConstraint;
+ limit->variables.insert(slack, 1.0);
+ limit->ratio = QSimplexConstraint::LessOrEqual;
+ limit->constant = interval;
+
+ return qMakePair(slack, limit);
+}
+
+bool QGraphicsAnchorLayoutPrivate::solvePreferred(const QList<QSimplexConstraint *> &constraints,
+ const QList<AnchorData *> &variables)
+{
+ QList<QSimplexConstraint *> preferredConstraints;
+ QList<QSimplexVariable *> preferredVariables;
+ QSimplexConstraint objective;
+
+ // Fill the objective coefficients for this variable. In the
+ // end the objective function will be
+ //
+ // z = n * (A_shrinker_hard + A_grower_hard + B_shrinker_hard + B_grower_hard + ...) +
+ // (A_shrinker_soft + A_grower_soft + B_shrinker_soft + B_grower_soft + ...)
+ //
+ // where n is the number of variables that have
+ // slacks. Note that here we use the number of variables
+ // as coefficient, this is to mark the "shrinker slack
+ // variable" less likely to get value than the "grower
+ // slack variable".
+
+ // This will fill the values for the structural constraints
+ // and we now fill the values for the slack constraints (one per variable),
+ // which have this form (the constant A_pref was set when creating the slacks):
+ //
+ // A + A_shrinker_hard + A_shrinker_soft - A_grower_hard - A_grower_soft = A_pref
+ //
+ for (int i = 0; i < variables.size(); ++i) {
+ AnchorData *ad = variables.at(i);
+
+ // The layout original structure anchors are not relevant in preferred size calculation
+ if (ad->isLayoutAnchor)
+ continue;
+
+ // By default, all variables are equal to their preferred size. If they have room to
+ // grow or shrink, such flexibility will be added by the additional variables below.
+ QSimplexConstraint *sizeConstraint = new QSimplexConstraint;
+ preferredConstraints += sizeConstraint;
+ sizeConstraint->variables.insert(ad, 1.0);
+ sizeConstraint->constant = ad->prefSize + g_offset;
+
+ // Can easily shrink
+ QPair<QSimplexVariable *, QSimplexConstraint *> slack;
+ const qreal softShrinkInterval = ad->prefSize - ad->minPrefSize;
+ if (softShrinkInterval) {
+ slack = createSlack(sizeConstraint, softShrinkInterval, Shrinker);
+ preferredVariables += slack.first;
+ preferredConstraints += slack.second;
+
+ // Add to objective with ratio == 1 (soft)
+ objective.variables.insert(slack.first, 1.0);
+ }
+
+ // Can easily grow
+ const qreal softGrowInterval = ad->maxPrefSize - ad->prefSize;
+ if (softGrowInterval) {
+ slack = createSlack(sizeConstraint, softGrowInterval, Grower);
+ preferredVariables += slack.first;
+ preferredConstraints += slack.second;
+
+ // Add to objective with ratio == 1 (soft)
+ objective.variables.insert(slack.first, 1.0);
+ }
+
+ // Can shrink if really necessary
+ const qreal hardShrinkInterval = ad->minPrefSize - ad->minSize;
+ if (hardShrinkInterval) {
+ slack = createSlack(sizeConstraint, hardShrinkInterval, Shrinker);
+ preferredVariables += slack.first;
+ preferredConstraints += slack.second;
+
+ // Add to objective with ratio == N (hard)
+ objective.variables.insert(slack.first, variables.size());
+ }
+
+ // Can grow if really necessary
+ const qreal hardGrowInterval = ad->maxSize - ad->maxPrefSize;
+ if (hardGrowInterval) {
+ slack = createSlack(sizeConstraint, hardGrowInterval, Grower);
+ preferredVariables += slack.first;
+ preferredConstraints += slack.second;
+
+ // Add to objective with ratio == N (hard)
+ objective.variables.insert(slack.first, variables.size());
+ }
+ }
+
+ QSimplex *simplex = new QSimplex;
+ bool feasible = simplex->setConstraints(constraints + preferredConstraints);
+ if (feasible) {
+ simplex->setObjective(&objective);
+
+ // Calculate minimum values
+ simplex->solveMin();
+
+ // Save sizeAtPreferred results
+ for (int i = 0; i < variables.size(); ++i) {
+ AnchorData *ad = variables.at(i);
+ ad->sizeAtPreferred = ad->result - g_offset;
+ }
+ }
+
+ // Make sure we delete the simplex solver -before- we delete the
+ // constraints used by it.
+ delete simplex;
+
+ // Delete constraints and variables we created.
+ qDeleteAll(preferredConstraints);
+ qDeleteAll(preferredVariables);
+
+ return feasible;
+}
+
+/*!
+ \internal
+ Returns true if there are no arrangement that satisfies all constraints.
+ Otherwise returns false.
+
+ \sa addAnchor()
+*/
+bool QGraphicsAnchorLayoutPrivate::hasConflicts() const
+{
+ QGraphicsAnchorLayoutPrivate *that = const_cast<QGraphicsAnchorLayoutPrivate*>(this);
+ that->calculateGraphs();
+
+ bool floatConflict = !m_floatItems[0].isEmpty() || !m_floatItems[1].isEmpty();
+
+ return graphHasConflicts[0] || graphHasConflicts[1] || floatConflict;
+}
+
+#ifdef QT_DEBUG
+void QGraphicsAnchorLayoutPrivate::dumpGraph(const QString &name)
+{
+ QFile file(QString::fromAscii("anchorlayout.%1.dot").arg(name));
+ if (!file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate))
+ qWarning("Could not write to %s", file.fileName().toLocal8Bit().constData());
+
+ QString str = QString::fromAscii("digraph anchorlayout {\nnode [shape=\"rect\"]\n%1}");
+ QString dotContents = graph[0].serializeToDot();
+ dotContents += graph[1].serializeToDot();
+ file.write(str.arg(dotContents).toLocal8Bit());
+
+ file.close();
+}
+#endif
+
+QT_END_NAMESPACE
+#endif //QT_NO_GRAPHICSVIEW
diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.h b/src/widgets/graphicsview/qgraphicsanchorlayout_p.h
index d78e5c89c3..d78e5c89c3 100644
--- a/src/gui/graphicsview/qgraphicsanchorlayout_p.h
+++ b/src/widgets/graphicsview/qgraphicsanchorlayout_p.h
diff --git a/src/gui/graphicsview/qgraphicsgridlayout.cpp b/src/widgets/graphicsview/qgraphicsgridlayout.cpp
index 2fbfc5dda9..2fbfc5dda9 100644
--- a/src/gui/graphicsview/qgraphicsgridlayout.cpp
+++ b/src/widgets/graphicsview/qgraphicsgridlayout.cpp
diff --git a/src/widgets/graphicsview/qgraphicsgridlayout.h b/src/widgets/graphicsview/qgraphicsgridlayout.h
new file mode 100644
index 0000000000..c6bc2229b6
--- /dev/null
+++ b/src/widgets/graphicsview/qgraphicsgridlayout.h
@@ -0,0 +1,144 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGRAPHICSGRIDLAYOUT_H
+#define QGRAPHICSGRIDLAYOUT_H
+
+#include <QtWidgets/qgraphicsitem.h>
+#include <QtWidgets/qgraphicslayout.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW
+
+class QGraphicsGridLayoutPrivate;
+
+class Q_WIDGETS_EXPORT QGraphicsGridLayout : public QGraphicsLayout
+{
+public:
+ QGraphicsGridLayout(QGraphicsLayoutItem *parent = 0);
+ virtual ~QGraphicsGridLayout();
+
+ void addItem(QGraphicsLayoutItem *item, int row, int column, int rowSpan, int columnSpan,
+ Qt::Alignment alignment = 0);
+ inline void addItem(QGraphicsLayoutItem *item, int row, int column, Qt::Alignment alignment = 0);
+
+ void setHorizontalSpacing(qreal spacing);
+ qreal horizontalSpacing() const;
+ void setVerticalSpacing(qreal spacing);
+ qreal verticalSpacing() const;
+ void setSpacing(qreal spacing);
+
+ void setRowSpacing(int row, qreal spacing);
+ qreal rowSpacing(int row) const;
+ void setColumnSpacing(int column, qreal spacing);
+ qreal columnSpacing(int column) const;
+
+ void setRowStretchFactor(int row, int stretch);
+ int rowStretchFactor(int row) const;
+ void setColumnStretchFactor(int column, int stretch);
+ int columnStretchFactor(int column) const;
+
+ void setRowMinimumHeight(int row, qreal height);
+ qreal rowMinimumHeight(int row) const;
+ void setRowPreferredHeight(int row, qreal height);
+ qreal rowPreferredHeight(int row) const;
+ void setRowMaximumHeight(int row, qreal height);
+ qreal rowMaximumHeight(int row) const;
+ void setRowFixedHeight(int row, qreal height);
+
+ void setColumnMinimumWidth(int column, qreal width);
+ qreal columnMinimumWidth(int column) const;
+ void setColumnPreferredWidth(int column, qreal width);
+ qreal columnPreferredWidth(int column) const;
+ void setColumnMaximumWidth(int column, qreal width);
+ qreal columnMaximumWidth(int column) const;
+ void setColumnFixedWidth(int column, qreal width);
+
+ void setRowAlignment(int row, Qt::Alignment alignment);
+ Qt::Alignment rowAlignment(int row) const;
+ void setColumnAlignment(int column, Qt::Alignment alignment);
+ Qt::Alignment columnAlignment(int column) const;
+
+ void setAlignment(QGraphicsLayoutItem *item, Qt::Alignment alignment);
+ Qt::Alignment alignment(QGraphicsLayoutItem *item) const;
+
+ int rowCount() const;
+ int columnCount() const;
+
+ QGraphicsLayoutItem *itemAt(int row, int column) const;
+
+ // inherited from QGraphicsLayout
+ int count() const;
+ QGraphicsLayoutItem *itemAt(int index) const;
+ void removeAt(int index);
+ void removeItem(QGraphicsLayoutItem *item);
+
+ void invalidate();
+
+ // inherited from QGraphicsLayoutItem
+ void setGeometry(const QRectF &rect);
+ QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const;
+
+ // ####
+ //QRect cellRect(int row, int column, int rowSpan = 1, int columnSpan = 1) const;
+ //QSizePolicy::ControlTypes controlTypes(LayoutSide side) const;
+
+private:
+ Q_DISABLE_COPY(QGraphicsGridLayout)
+ Q_DECLARE_PRIVATE(QGraphicsGridLayout)
+};
+
+inline void QGraphicsGridLayout::addItem(QGraphicsLayoutItem *aitem, int arow, int acolumn, Qt::Alignment aalignment)
+{ addItem(aitem, arow, acolumn, 1, 1, aalignment); }
+
+#endif
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
+
diff --git a/src/widgets/graphicsview/qgraphicsitem.cpp b/src/widgets/graphicsview/qgraphicsitem.cpp
new file mode 100644
index 0000000000..c0f6339deb
--- /dev/null
+++ b/src/widgets/graphicsview/qgraphicsitem.cpp
@@ -0,0 +1,11603 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \class QGraphicsItem
+ \brief The QGraphicsItem class is the base class for all graphical
+ items in a QGraphicsScene.
+ \since 4.2
+
+ \ingroup graphicsview-api
+
+ It provides a light-weight foundation for writing your own custom items.
+ This includes defining the item's geometry, collision detection, its
+ painting implementation and item interaction through its event handlers.
+ QGraphicsItem is part of the \l{Graphics View Framework}
+
+ \image graphicsview-items.png
+
+ For convenience, Qt provides a set of standard graphics items for the most
+ common shapes. These are:
+
+ \list
+ \o QGraphicsEllipseItem provides an ellipse item
+ \o QGraphicsLineItem provides a line item
+ \o QGraphicsPathItem provides an arbitrary path item
+ \o QGraphicsPixmapItem provides a pixmap item
+ \o QGraphicsPolygonItem provides a polygon item
+ \o QGraphicsRectItem provides a rectangular item
+ \o QGraphicsSimpleTextItem provides a simple text label item
+ \o QGraphicsTextItem provides an advanced text browser item
+ \endlist
+
+ All of an item's geometric information is based on its local coordinate
+ system. The item's position, pos(), is the only function that does not
+ operate in local coordinates, as it returns a position in parent
+ coordinates. \l {The Graphics View Coordinate System} describes the coordinate
+ system in detail.
+
+ You can set whether an item should be visible (i.e., drawn, and accepting
+ events), by calling setVisible(). Hiding an item will also hide its
+ children. Similarly, you can enable or disable an item by calling
+ setEnabled(). If you disable an item, all its children will also be
+ disabled. By default, items are both visible and enabled. To toggle
+ whether an item is selected or not, first enable selection by setting
+ the ItemIsSelectable flag, and then call setSelected(). Normally,
+ selection is toggled by the scene, as a result of user interaction.
+
+ To write your own graphics item, you first create a subclass of
+ QGraphicsItem, and then start by implementing its two pure virtual public
+ functions: boundingRect(), which returns an estimate of the area painted
+ by the item, and paint(), which implements the actual painting. For
+ example:
+
+ \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 0
+
+ The boundingRect() function has many different purposes.
+ QGraphicsScene bases its item index on boundingRect(), and
+ QGraphicsView uses it both for culling invisible items, and for
+ determining the area that needs to be recomposed when drawing
+ overlapping items. In addition, QGraphicsItem's collision
+ detection mechanisms use boundingRect() to provide an efficient
+ cut-off. The fine grained collision algorithm in
+ collidesWithItem() is based on calling shape(), which returns an
+ accurate outline of the item's shape as a QPainterPath.
+
+ QGraphicsScene expects all items boundingRect() and shape() to
+ remain unchanged unless it is notified. If you want to change an
+ item's geometry in any way, you must first call
+ prepareGeometryChange() to allow QGraphicsScene to update its
+ bookkeeping.
+
+ Collision detection can be done in two ways:
+
+ \list 1
+
+ \o Reimplement shape() to return an accurate shape for your item,
+ and rely on the default implementation of collidesWithItem() to do
+ shape-shape intersection. This can be rather expensive if the
+ shapes are complex.
+
+ \o Reimplement collidesWithItem() to provide your own custom item
+ and shape collision algorithm.
+
+ \endlist
+
+ The contains() function can be called to determine whether the item \e
+ contains a point or not. This function can also be reimplemented by the
+ item. The default behavior of contains() is based on calling shape().
+
+ Items can contain other items, and also be contained by other items. All
+ items can have a parent item and a list of children. Unless the item has
+ no parent, its position is in \e parent coordinates (i.e., the parent's
+ local coordinates). Parent items propagate both their position and their
+ transformation to all children.
+
+ \img graphicsview-parentchild.png
+
+ \target Transformations
+ \section1 Transformations
+
+ QGraphicsItem supports projective transformations in addition to its base
+ position, pos(). There are several ways to change an item's transformation.
+ For simple transformations, you can call either of the convenience
+ functions setRotation() or setScale(), or you can pass any transformation
+ matrix to setTransform(). For advanced transformation control you also have
+ the option of setting several combined transformations by calling
+ setTransformations().
+
+ Item transformations accumulate from parent to child, so if both a parent
+ and child item are rotated 90 degrees, the child's total transformation
+ will be 180 degrees. Similarly, if the item's parent is scaled to 2x its
+ original size, its children will also be twice as large. An item's
+ transformation does not affect its own local geometry; all geometry
+ functions (e.g., contains(), update(), and all the mapping functions) still
+ operate in local coordinates. For convenience, QGraphicsItem provides the
+ functions sceneTransform(), which returns the item's total transformation
+ matrix (including its position and all parents' positions and
+ transformations), and scenePos(), which returns its position in scene
+ coordinates. To reset an item's matrix, call resetTransform().
+
+ Certain transformation operations produce a different outcome depending on
+ the order in which they are applied. For example, if you scale an
+ transform, and then rotate it, you may get a different result than if the
+ transform was rotated first. However, the order you set the transformation
+ properties on QGraphicsItem does not affect the resulting transformation;
+ QGraphicsItem always applies the properties in a fixed, defined order:
+
+ \list
+ \o The item's base transform is applied (transform())
+ \o The item's transformations list is applied in order (transformations())
+ \o The item is rotated relative to its transform origin point (rotation(), transformOriginPoint())
+ \o The item is scaled relative to its transform origin point (scale(), transformOriginPoint())
+ \endlist
+
+ \section1 Painting
+
+ The paint() function is called by QGraphicsView to paint the item's
+ contents. The item has no background or default fill of its own; whatever
+ is behind the item will shine through all areas that are not explicitly
+ painted in this function. You can call update() to schedule a repaint,
+ optionally passing the rectangle that needs a repaint. Depending on
+ whether or not the item is visible in a view, the item may or may not be
+ repainted; there is no equivalent to QWidget::repaint() in QGraphicsItem.
+
+ Items are painted by the view, starting with the parent items and then
+ drawing children, in ascending stacking order. You can set an item's
+ stacking order by calling setZValue(), and test it by calling
+ zValue(), where items with low z-values are painted before items with
+ high z-values. Stacking order applies to sibling items; parents are always
+ drawn before their children.
+
+ \section1 Sorting
+
+ All items are drawn in a defined, stable order, and this same order decides
+ which items will receive mouse input first when you click on the scene.
+ Normally you don't have to worry about sorting, as the items follow a
+ "natural order", following the logical structure of the scene.
+
+ An item's children are stacked on top of the parent, and sibling items are
+ stacked by insertion order (i.e., in the same order that they were either
+ added to the scene, or added to the same parent). If you add item A, and
+ then B, then B will be on top of A. If you then add C, the items' stacking
+ order will be A, then B, then C.
+
+ \image graphicsview-zorder.png
+
+ This example shows the stacking order of all limbs of the robot from the
+ \l{graphicsview/dragdroprobot}{Drag and Drop Robot} example. The torso is
+ the root item (all other items are children or descendants of the torso),
+ so it is drawn first. Next, the head is drawn, as it is the first item in
+ the torso's list of children. Then the upper left arm is drawn. As the
+ lower arm is a child of the upper arm, the lower arm is then drawn,
+ followed by the upper arm's next sibling, which is the upper right arm, and
+ so on.
+
+ For advanced users, there are ways to alter how your items are sorted:
+
+ \list
+ \o You can call setZValue() on an item to explicitly stack it on top of, or
+ under, other sibling items. The default Z value for an item is 0. Items
+ with the same Z value are stacked by insertion order.
+
+ \o You can call stackBefore() to reorder the list of children. This will
+ directly modify the insertion order.
+
+ \o You can set the ItemStacksBehindParent flag to stack a child item behind
+ its parent.
+ \endlist
+
+ The stacking order of two sibling items also counts for each item's
+ children and descendant items. So if one item is on top of another, then
+ all its children will also be on top of all the other item's children as
+ well.
+
+ \section1 Events
+
+ QGraphicsItem receives events from QGraphicsScene through the virtual
+ function sceneEvent(). This function distributes the most common events
+ to a set of convenience event handlers:
+
+ \list
+ \o contextMenuEvent() handles context menu events
+ \o focusInEvent() and focusOutEvent() handle focus in and out events
+ \o hoverEnterEvent(), hoverMoveEvent(), and hoverLeaveEvent() handles
+ hover enter, move and leave events
+ \o inputMethodEvent() handles input events, for accessibility support
+ \o keyPressEvent() and keyReleaseEvent() handle key press and release events
+ \o mousePressEvent(), mouseMoveEvent(), mouseReleaseEvent(), and
+ mouseDoubleClickEvent() handles mouse press, move, release, click and
+ doubleclick events
+ \endlist
+
+ You can filter events for any other item by installing event filters. This
+ functionality is separate from Qt's regular event filters (see
+ QObject::installEventFilter()), which only work on subclasses of QObject. After
+ installing your item as an event filter for another item by calling
+ installSceneEventFilter(), the filtered events will be received by the virtual
+ function sceneEventFilter(). You can remove item event filters by calling
+ removeSceneEventFilter().
+
+ \section1 Custom Data
+
+ Sometimes it's useful to register custom data with an item, be it a custom
+ item, or a standard item. You can call setData() on any item to store data
+ in it using a key-value pair (the key being an integer, and the value is a
+ QVariant). To get custom data from an item, call data(). This
+ functionality is completely untouched by Qt itself; it is provided for the
+ user's convenience.
+
+ \sa QGraphicsScene, QGraphicsView, {Graphics View Framework}
+*/
+
+/*!
+ \variable QGraphicsItem::Type
+
+ The type value returned by the virtual type() function in standard
+ graphics item classes in Qt. All such standard graphics item
+ classes in Qt are associated with a unique value for Type,
+ e.g. the value returned by QGraphicsPathItem::type() is 2.
+
+ \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 18
+*/
+
+/*!
+ \variable QGraphicsItem::UserType
+
+ The lowest permitted type value for custom items (subclasses
+ of QGraphicsItem or any of the standard items). This value is
+ used in conjunction with a reimplementation of QGraphicsItem::type()
+ and declaring a Type enum value. Example:
+
+ \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 1
+
+ \note UserType = 65536
+*/
+
+/*!
+ \enum QGraphicsItem::GraphicsItemFlag
+
+ This enum describes different flags that you can set on an item to
+ toggle different features in the item's behavior.
+
+ All flags are disabled by default.
+
+ \value ItemIsMovable The item supports interactive movement using
+ the mouse. By clicking on the item and then dragging, the item
+ will move together with the mouse cursor. If the item has
+ children, all children are also moved. If the item is part of a
+ selection, all selected items are also moved. This feature is
+ provided as a convenience through the base implementation of
+ QGraphicsItem's mouse event handlers.
+
+ \value ItemIsSelectable The item supports selection. Enabling this
+ feature will enable setSelected() to toggle selection for the
+ item. It will also let the item be selected automatically as a
+ result of calling QGraphicsScene::setSelectionArea(), by clicking
+ on an item, or by using rubber band selection in QGraphicsView.
+
+ \value ItemIsFocusable The item supports keyboard input focus (i.e., it is
+ an input item). Enabling this flag will allow the item to accept focus,
+ which again allows the delivery of key events to
+ QGraphicsItem::keyPressEvent() and QGraphicsItem::keyReleaseEvent().
+
+ \value ItemClipsToShape The item clips to its own shape. The item cannot
+ draw or receive mouse, tablet, drag and drop or hover events outside its
+ shape. It is disabled by default. This behavior is enforced by
+ QGraphicsView::drawItems() or QGraphicsScene::drawItems(). This flag was
+ introduced in Qt 4.3.
+
+ \value ItemClipsChildrenToShape The item clips the painting of all its
+ descendants to its own shape. Items that are either direct or indirect
+ children of this item cannot draw outside this item's shape. By default,
+ this flag is disabled; children can draw anywhere. This behavior is
+ enforced by QGraphicsView::drawItems() or
+ QGraphicsScene::drawItems(). This flag was introduced in Qt 4.3.
+
+ \value ItemIgnoresTransformations The item ignores inherited
+ transformations (i.e., its position is still anchored to its parent, but
+ the parent or view rotation, zoom or shear transformations are ignored).
+ This flag is useful for keeping text label items horizontal and unscaled,
+ so they will still be readable if the view is transformed. When set, the
+ item's view geometry and scene geometry will be maintained separately. You
+ must call deviceTransform() to map coordinates and detect collisions in
+ the view. By default, this flag is disabled. This flag was introduced in
+ Qt 4.3. \note With this flag set you can still scale the item itself, and
+ that scale transformation will influence the item's children.
+
+ \value ItemIgnoresParentOpacity The item ignores its parent's opacity. The
+ item's effective opacity is the same as its own; it does not combine with
+ the parent's opacity. This flags allows your item to keep its absolute
+ opacity even if the parent is semitransparent. This flag was introduced in
+ Qt 4.5.
+
+ \value ItemDoesntPropagateOpacityToChildren The item doesn't propagate its
+ opacity to its children. This flag allows you to create a semitransparent
+ item that does not affect the opacity of its children. This flag was
+ introduced in Qt 4.5.
+
+ \value ItemStacksBehindParent The item is stacked behind its parent. By
+ default, child items are stacked on top of the parent item. But setting
+ this flag, the child will be stacked behind it. This flag is useful for
+ drop shadow effects and for decoration objects that follow the parent
+ item's geometry without drawing on top of it. This flag was introduced
+ in Qt 4.5.
+
+ \value ItemUsesExtendedStyleOption The item makes use of either
+ \l{QStyleOptionGraphicsItem::} {exposedRect} or
+ \l{QStyleOptionGraphicsItem::} {matrix} in
+ QStyleOptionGraphicsItem. By default, the
+ \l{QStyleOptionGraphicsItem::} {exposedRect} is initialized to the
+ item's boundingRect() and the
+ \l{QStyleOptionGraphicsItem::}{matrix} is untransformed. You can
+ enable this flag for the style options to be set up with more
+ fine-grained values. Note that
+ QStyleOptionGraphicsItem::levelOfDetail is unaffected by this flag
+ and always initialized to 1. Use
+ QStyleOptionGraphicsItem::levelOfDetailFromTransform() if you need
+ a higher value. This flag was introduced in Qt 4.6.
+
+ \value ItemHasNoContents The item does not paint anything (i.e., calling
+ paint() on the item has no effect). You should set this flag on items that
+ do not need to be painted to ensure that Graphics View avoids unnecessary
+ painting preparations. This flag was introduced in Qt 4.6.
+
+ \value ItemSendsGeometryChanges The item enables itemChange()
+ notifications for ItemPositionChange, ItemPositionHasChanged,
+ ItemMatrixChange, ItemTransformChange, ItemTransformHasChanged,
+ ItemRotationChange, ItemRotationHasChanged, ItemScaleChange, ItemScaleHasChanged,
+ ItemTransformOriginPointChange, and ItemTransformOriginPointHasChanged. For
+ performance reasons, these notifications are disabled by default. You must
+ enable this flag to receive notifications for position and transform
+ changes. This flag was introduced in Qt 4.6.
+
+ \value ItemAcceptsInputMethod The item supports input methods typically
+ used for Asian languages.
+ This flag was introduced in Qt 4.6.
+
+ \value ItemNegativeZStacksBehindParent The item automatically
+ stacks behind it's parent if it's z-value is negative. This flag
+ enables setZValue() to toggle ItemStacksBehindParent. This flag
+ was introduced in Qt 4.6.
+
+ \value ItemIsPanel The item is a panel. A panel provides activation and
+ contained focus handling. Only one panel can be active at a time (see
+ QGraphicsItem::isActive()). When no panel is active, QGraphicsScene
+ activates all non-panel items. Window items (i.e.,
+ QGraphicsItem::isWindow() returns true) are panels. This flag was
+ introduced in Qt 4.6.
+
+ \omitvalue ItemIsFocusScope \omit Internal only (for now). \endomit
+
+ \value ItemSendsScenePositionChanges The item enables itemChange()
+ notifications for ItemScenePositionHasChanged. For performance reasons,
+ these notifications are disabled by default. You must enable this flag
+ to receive notifications for scene position changes. This flag was
+ introduced in Qt 4.6.
+
+ \omitvalue ItemStopsClickFocusPropagation \omit The item stops propagating
+ click focus to items underneath when being clicked on. This flag
+ allows you create a non-focusable item that can be clicked on without
+ changing the focus. \endomit
+
+ \omitvalue ItemStopsFocusHandling \omit Same as
+ ItemStopsClickFocusPropagation, but also suppresses focus-out. This flag
+ allows you to completely take over focus handling.
+ This flag was introduced in Qt 4.7. \endomit
+*/
+
+/*!
+ \enum QGraphicsItem::GraphicsItemChange
+
+ This enum describes the state changes that are notified by
+ QGraphicsItem::itemChange(). The notifications are sent as the state
+ changes, and in some cases, adjustments can be made (see the documentation
+ for each change for details).
+
+ Note: Be careful with calling functions on the QGraphicsItem itself inside
+ itemChange(), as certain function calls can lead to unwanted
+ recursion. For example, you cannot call setPos() in itemChange() on an
+ ItemPositionChange notification, as the setPos() function will again call
+ itemChange(ItemPositionChange). Instead, you can return the new, adjusted
+ position from itemChange().
+
+ \value ItemEnabledChange The item's enabled state changes. If the item is
+ presently enabled, it will become disabled, and vice verca. The value
+ argument is the new enabled state (i.e., true or false). Do not call
+ setEnabled() in itemChange() as this notification is delivered. Instead,
+ you can return the new state from itemChange().
+
+ \value ItemEnabledHasChanged The item's enabled state has changed. The
+ value argument is the new enabled state (i.e., true or false). Do not call
+ setEnabled() in itemChange() as this notification is delivered. The return
+ value is ignored.
+
+ \value ItemMatrixChange The item's affine transformation matrix is
+ changing. This value is obsolete; you can use ItemTransformChange instead.
+
+ \value ItemPositionChange The item's position changes. This notification
+ is sent if the ItemSendsGeometryChanges flag is enabled, and when the
+ item's local position changes, relative to its parent (i.e., as a result
+ of calling setPos() or moveBy()). The value argument is the new position
+ (i.e., a QPointF). You can call pos() to get the original position. Do
+ not call setPos() or moveBy() in itemChange() as this notification is
+ delivered; instead, you can return the new, adjusted position from
+ itemChange(). After this notification, QGraphicsItem immediately sends the
+ ItemPositionHasChanged notification if the position changed.
+
+ \value ItemPositionHasChanged The item's position has changed. This
+ notification is sent if the ItemSendsGeometryChanges flag is enabled, and
+ after the item's local position, relative to its parent, has changed. The
+ value argument is the new position (the same as pos()), and QGraphicsItem
+ ignores the return value for this notification (i.e., a read-only
+ notification).
+
+ \value ItemTransformChange The item's transformation matrix changes. This
+ notification is send if the ItemSendsGeometryChanges flag is enabled, and
+ when the item's local transformation matrix changes (i.e., as a result of
+ calling setTransform(). The value argument is the new matrix (i.e., a
+ QTransform); to get the old matrix, call transform(). Do not call
+ setTransform() or set any of the transformation properties in itemChange()
+ as this notification is delivered; instead, you can return the new matrix
+ from itemChange(). This notification is not sent if you change the
+ transformation properties.
+
+ \value ItemTransformHasChanged The item's transformation matrix has
+ changed either because setTransform is called, or one of the
+ transformation properties is changed. This notification is sent if the
+ ItemSendsGeometryChanges flag is enabled, and after the item's local
+ transformation matrix has changed. The value argument is the new matrix
+ (same as transform()), and QGraphicsItem ignores the return value for this
+ notification (i.e., a read-only notification).
+
+ \value ItemRotationChange The item's rotation property changes. This
+ notification is sent if the ItemSendsGeometryChanges flag is enabled, and
+ when the item's rotation property changes (i.e., as a result of calling
+ setRotation()). The value argument is the new rotation (i.e., a double);
+ to get the old rotation, call rotation(). Do not call setRotation() in
+ itemChange() as this notification is delivered; instead, you can return
+ the new rotation from itemChange().
+
+ \value ItemRotationHasChanged The item's rotation property has changed.
+ This notification is sent if the ItemSendsGeometryChanges flag is enabled,
+ and after the item's rotation property has changed. The value argument is
+ the new rotation (i.e., a double), and QGraphicsItem ignores the return
+ value for this notification (i.e., a read-only notification). Do not call
+ setRotation() in itemChange() as this notification is delivered.
+
+ \value ItemScaleChange The item's scale property changes. This notification
+ is sent if the ItemSendsGeometryChanges flag is enabled, and when the item's
+ scale property changes (i.e., as a result of calling setScale()). The value
+ argument is the new scale (i.e., a double); to get the old scale, call
+ scale(). Do not call setScale() in itemChange() as this notification is
+ delivered; instead, you can return the new scale from itemChange().
+
+ \value ItemScaleHasChanged The item's scale property has changed. This
+ notification is sent if the ItemSendsGeometryChanges flag is enabled, and
+ after the item's scale property has changed. The value argument is the new
+ scale (i.e., a double), and QGraphicsItem ignores the return value for this
+ notification (i.e., a read-only notification). Do not call setScale() in
+ itemChange() as this notification is delivered.
+
+ \value ItemTransformOriginPointChange The item's transform origin point
+ property changes. This notification is sent if the ItemSendsGeometryChanges
+ flag is enabled, and when the item's transform origin point property changes
+ (i.e., as a result of calling setTransformOriginPoint()). The value argument
+ is the new origin point (i.e., a QPointF); to get the old origin point, call
+ transformOriginPoint(). Do not call setTransformOriginPoint() in itemChange()
+ as this notification is delivered; instead, you can return the new transform
+ origin point from itemChange().
+
+ \value ItemTransformOriginPointHasChanged The item's transform origin point
+ property has changed. This notification is sent if the ItemSendsGeometryChanges
+ flag is enabled, and after the item's transform origin point property has
+ changed. The value argument is the new origin point (i.e., a QPointF), and
+ QGraphicsItem ignores the return value for this notification (i.e., a read-only
+ notification). Do not call setTransformOriginPoint() in itemChange() as this
+ notification is delivered.
+
+ \value ItemSelectedChange The item's selected state changes. If the item is
+ presently selected, it will become unselected, and vice verca. The value
+ argument is the new selected state (i.e., true or false). Do not call
+ setSelected() in itemChange() as this notification is delivered; instead, you
+ can return the new selected state from itemChange().
+
+ \value ItemSelectedHasChanged The item's selected state has changed. The
+ value argument is the new selected state (i.e., true or false). Do not
+ call setSelected() in itemChange() as this notification is delivered. The
+ return value is ignored.
+
+ \value ItemVisibleChange The item's visible state changes. If the item is
+ presently visible, it will become invisible, and vice verca. The value
+ argument is the new visible state (i.e., true or false). Do not call
+ setVisible() in itemChange() as this notification is delivered; instead,
+ you can return the new visible state from itemChange().
+
+ \value ItemVisibleHasChanged The item's visible state has changed. The
+ value argument is the new visible state (i.e., true or false). Do not call
+ setVisible() in itemChange() as this notification is delivered. The return
+ value is ignored.
+
+ \value ItemParentChange The item's parent changes. The value argument is
+ the new parent item (i.e., a QGraphicsItem pointer). Do not call
+ setParentItem() in itemChange() as this notification is delivered;
+ instead, you can return the new parent from itemChange().
+
+ \value ItemParentHasChanged The item's parent has changed. The value
+ argument is the new parent (i.e., a pointer to a QGraphicsItem). Do not
+ call setParentItem() in itemChange() as this notification is
+ delivered. The return value is ignored.
+
+ \value ItemChildAddedChange A child is added to this item. The value
+ argument is the new child item (i.e., a QGraphicsItem pointer). Do not
+ pass this item to any item's setParentItem() function as this notification
+ is delivered. The return value is unused; you cannot adjust anything in
+ this notification. Note that the new child might not be fully constructed
+ when this notification is sent; calling pure virtual functions on
+ the child can lead to a crash.
+
+ \value ItemChildRemovedChange A child is removed from this item. The value
+ argument is the child item that is about to be removed (i.e., a
+ QGraphicsItem pointer). The return value is unused; you cannot adjust
+ anything in this notification.
+
+ \value ItemSceneChange The item is moved to a new scene. This notification is
+ also sent when the item is added to its initial scene, and when it is removed.
+ The item's scene() is the old scene (or 0 if the item has not been added to a
+ scene yet). The value argument is the new scene (i.e., a QGraphicsScene
+ pointer), or a null pointer if the item is removed from a scene. Do not
+ override this change by passing this item to QGraphicsScene::addItem() as this
+ notification is delivered; instead, you can return the new scene from
+ itemChange(). Use this feature with caution; objecting to a scene change can
+ quickly lead to unwanted recursion.
+
+ \value ItemSceneHasChanged The item's scene has changed. The item's scene() is
+ the new scene. This notification is also sent when the item is added to its
+ initial scene, and when it is removed.The value argument is the new scene
+ (i.e., a pointer to a QGraphicsScene). Do not call setScene() in itemChange()
+ as this notification is delivered. The return value is ignored.
+
+ \value ItemCursorChange The item's cursor changes. The value argument is
+ the new cursor (i.e., a QCursor). Do not call setCursor() in itemChange()
+ as this notification is delivered. Instead, you can return a new cursor
+ from itemChange().
+
+ \value ItemCursorHasChanged The item's cursor has changed. The value
+ argument is the new cursor (i.e., a QCursor). Do not call setCursor() as
+ this notification is delivered. The return value is ignored.
+
+ \value ItemToolTipChange The item's tooltip changes. The value argument is
+ the new tooltip (i.e., a QToolTip). Do not call setToolTip() in
+ itemChange() as this notification is delivered. Instead, you can return a
+ new tooltip from itemChange().
+
+ \value ItemToolTipHasChanged The item's tooltip has changed. The value
+ argument is the new tooltip (i.e., a QToolTip). Do not call setToolTip()
+ as this notification is delivered. The return value is ignored.
+
+ \value ItemFlagsChange The item's flags change. The value argument is the
+ new flags (i.e., a quint32). Do not call setFlags() in itemChange() as
+ this notification is delivered. Instead, you can return the new flags from
+ itemChange().
+
+ \value ItemFlagsHaveChanged The item's flags have changed. The value
+ argument is the new flags (i.e., a quint32). Do not call setFlags() in
+ itemChange() as this notification is delivered. The return value is
+ ignored.
+
+ \value ItemZValueChange The item's Z-value changes. The value argument is
+ the new Z-value (i.e., a double). Do not call setZValue() in itemChange()
+ as this notification is delivered. Instead, you can return a new Z-value
+ from itemChange().
+
+ \value ItemZValueHasChanged The item's Z-value has changed. The value
+ argument is the new Z-value (i.e., a double). Do not call setZValue() as
+ this notification is delivered. The return value is ignored.
+
+ \value ItemOpacityChange The item's opacity changes. The value argument is
+ the new opacity (i.e., a double). Do not call setOpacity() in itemChange()
+ as this notification is delivered. Instead, you can return a new opacity
+ from itemChange().
+
+ \value ItemOpacityHasChanged The item's opacity has changed. The value
+ argument is the new opacity (i.e., a double). Do not call setOpacity() as
+ this notification is delivered. The return value is ignored.
+
+ \value ItemScenePositionHasChanged The item's scene position has changed.
+ This notification is sent if the ItemSendsScenePositionChanges flag is
+ enabled, and after the item's scene position has changed (i.e., the
+ position or transformation of the item itself or the position or
+ transformation of any ancestor has changed). The value argument is the
+ new scene position (the same as scenePos()), and QGraphicsItem ignores
+ the return value for this notification (i.e., a read-only notification).
+*/
+
+/*!
+ \enum QGraphicsItem::CacheMode
+ \since 4.4
+
+ This enum describes QGraphicsItem's cache modes. Caching is used to speed
+ up rendering by allocating and rendering to an off-screen pixel buffer,
+ which can be reused when the item requires redrawing. For some paint
+ devices, the cache is stored directly in graphics memory, which makes
+ rendering very quick.
+
+ \value NoCache The default; all item caching is
+ disabled. QGraphicsItem::paint() is called every time the item needs
+ redrawing.
+
+ \value ItemCoordinateCache Caching is enabled for the item's logical
+ (local) coordinate system. QGraphicsItem creates an off-screen pixel
+ buffer with a configurable size / resolution that you can pass to
+ QGraphicsItem::setCacheMode(). Rendering quality will typically degrade,
+ depending on the resolution of the cache and the item transformation. The
+ first time the item is redrawn, it will render itself into the cache, and
+ the cache is then reused for every subsequent expose. The cache is also
+ reused as the item is transformed. To adjust the resolution of the cache,
+ you can call setCacheMode() again.
+
+ \value DeviceCoordinateCache Caching is enabled at the paint device level,
+ in device coordinates. This mode is for items that can move, but are not
+ rotated, scaled or sheared. If the item is transformed directly or
+ indirectly, the cache will be regenerated automatically. Unlike
+ ItemCoordinateCacheMode, DeviceCoordinateCache always renders at maximum
+ quality.
+
+ \sa QGraphicsItem::setCacheMode()
+*/
+
+/*!
+ \enum QGraphicsItem::Extension
+ \internal
+
+ Note: This is provided as a hook to avoid future problems related
+ to adding virtual functions. See also extension(),
+ supportsExtension() and setExtension().
+*/
+
+/*!
+ \enum QGraphicsItem::PanelModality
+ \since 4.6
+
+ This enum specifies the behavior of a modal panel. A modal panel
+ is one that blocks input to other panels. Note that items that
+ are children of a modal panel are not blocked.
+
+ The values are:
+
+ \value NonModal The panel is not modal and does not block input to
+ other panels. This is the default value for panels.
+
+ \value PanelModal The panel is modal to a single item hierarchy
+ and blocks input to its parent pane, all grandparent panels, and
+ all siblings of its parent and grandparent panels.
+
+ \value SceneModal The window is modal to the entire scene and
+ blocks input to all panels.
+
+ \sa QGraphicsItem::setPanelModality(), QGraphicsItem::panelModality(), QGraphicsItem::ItemIsPanel
+*/
+
+#include "qgraphicsitem.h"
+
+#ifndef QT_NO_GRAPHICSVIEW
+
+#include "qgraphicsscene.h"
+#include "qgraphicsscene_p.h"
+#include "qgraphicssceneevent.h"
+#include "qgraphicsview.h"
+#include "qgraphicswidget.h"
+#include "qgraphicsproxywidget.h"
+#include "qgraphicsscenebsptreeindex_p.h"
+#include <QtCore/qbitarray.h>
+#include <QtCore/qdebug.h>
+#include <QtCore/qpoint.h>
+#include <QtCore/qstack.h>
+#include <QtCore/qtimer.h>
+#include <QtCore/qvariant.h>
+#include <QtCore/qvarlengtharray.h>
+#include <QtCore/qnumeric.h>
+#include <QtWidgets/qapplication.h>
+#include <QtGui/qbitmap.h>
+#include <QtGui/qpainter.h>
+#include <QtGui/qpainterpath.h>
+#include <QtGui/qpixmapcache.h>
+#include <QtWidgets/qstyleoption.h>
+#include <QtGui/qevent.h>
+#include <QtWidgets/qinputcontext.h>
+#include <QtWidgets/qgraphicseffect.h>
+#ifndef QT_NO_ACCESSIBILITY
+# include "qaccessible.h"
+#endif
+
+#include <private/qgraphicsitem_p.h>
+#include <private/qgraphicswidget_p.h>
+#include <private/qwidgettextcontrol_p.h>
+#include <private/qtextdocumentlayout_p.h>
+#include <private/qtextengine_p.h>
+#include <private/qwidget_p.h>
+#include <private/qapplication_p.h>
+
+#ifdef Q_WS_X11
+#include <private/qt_x11_p.h>
+#include <private/qpixmap_x11_p.h>
+#endif
+
+#include <private/qgesturemanager_p.h>
+
+#include <math.h>
+
+QT_BEGIN_NAMESPACE
+
+static inline void _q_adjustRect(QRect *rect)
+{
+ Q_ASSERT(rect);
+ if (!rect->width())
+ rect->adjust(0, 0, 1, 0);
+ if (!rect->height())
+ rect->adjust(0, 0, 0, 1);
+}
+
+/*
+ ### Move this into QGraphicsItemPrivate
+ */
+class QGraphicsItemCustomDataStore
+{
+public:
+ QMap<const QGraphicsItem *, QMap<int, QVariant> > data;
+};
+Q_GLOBAL_STATIC(QGraphicsItemCustomDataStore, qt_dataStore)
+
+/*!
+ \internal
+
+ Returns a QPainterPath of \a path when stroked with the \a pen.
+ Ignoring dash pattern.
+*/
+static QPainterPath qt_graphicsItem_shapeFromPath(const QPainterPath &path, const QPen &pen)
+{
+ // We unfortunately need this hack as QPainterPathStroker will set a width of 1.0
+ // if we pass a value of 0.0 to QPainterPathStroker::setWidth()
+ const qreal penWidthZero = qreal(0.00000001);
+
+ if (path == QPainterPath())
+ return path;
+ QPainterPathStroker ps;
+ ps.setCapStyle(pen.capStyle());
+ if (pen.widthF() <= 0.0)
+ ps.setWidth(penWidthZero);
+ else
+ ps.setWidth(pen.widthF());
+ ps.setJoinStyle(pen.joinStyle());
+ ps.setMiterLimit(pen.miterLimit());
+ QPainterPath p = ps.createStroke(path);
+ p.addPath(path);
+ return p;
+}
+
+/*!
+ \internal
+
+ Propagates the ancestor flag \a flag with value \a enabled to all this
+ item's children. If \a root is false, the flag is also set on this item
+ (default is true).
+*/
+void QGraphicsItemPrivate::updateAncestorFlag(QGraphicsItem::GraphicsItemFlag childFlag,
+ AncestorFlag flag, bool enabled, bool root)
+{
+ Q_Q(QGraphicsItem);
+ if (root) {
+ // For root items only. This is the item that has either enabled or
+ // disabled \a childFlag, or has been reparented.
+ switch (int(childFlag)) {
+ case -2:
+ flag = AncestorFiltersChildEvents;
+ enabled = q->filtersChildEvents();
+ break;
+ case -1:
+ flag = AncestorHandlesChildEvents;
+ enabled = q->handlesChildEvents();
+ break;
+ case QGraphicsItem::ItemClipsChildrenToShape:
+ flag = AncestorClipsChildren;
+ enabled = flags & QGraphicsItem::ItemClipsChildrenToShape;
+ break;
+ case QGraphicsItem::ItemIgnoresTransformations:
+ flag = AncestorIgnoresTransformations;
+ enabled = flags & QGraphicsItem::ItemIgnoresTransformations;
+ break;
+ default:
+ return;
+ }
+
+ if (parent) {
+ // Inherit the enabled-state from our parents.
+ if ((parent->d_ptr->ancestorFlags & flag)
+ || (int(parent->d_ptr->flags & childFlag) == childFlag)
+ || (childFlag == -1 && parent->d_ptr->handlesChildEvents)
+ || (childFlag == -2 && parent->d_ptr->filtersDescendantEvents)) {
+ enabled = true;
+ ancestorFlags |= flag;
+ } else {
+ ancestorFlags &= ~flag;
+ }
+ } else {
+ // Top-level root items don't have any ancestors, so there are no
+ // ancestor flags either.
+ ancestorFlags = 0;
+ }
+ } else {
+ // Don't set or propagate the ancestor flag if it's already correct.
+ if (((ancestorFlags & flag) && enabled) || (!(ancestorFlags & flag) && !enabled))
+ return;
+
+ // Set the flag.
+ if (enabled)
+ ancestorFlags |= flag;
+ else
+ ancestorFlags &= ~flag;
+
+ // Don't process children if the item has the main flag set on itself.
+ if ((childFlag != -1 && int(flags & childFlag) == childFlag)
+ || (int(childFlag) == -1 && handlesChildEvents)
+ || (int(childFlag) == -2 && filtersDescendantEvents))
+ return;
+ }
+
+ for (int i = 0; i < children.size(); ++i)
+ children.at(i)->d_ptr->updateAncestorFlag(childFlag, flag, enabled, false);
+}
+
+void QGraphicsItemPrivate::updateAncestorFlags()
+{
+ int flags = 0;
+ if (parent) {
+ // Inherit the parent's ancestor flags.
+ QGraphicsItemPrivate *pd = parent->d_ptr.data();
+ flags = pd->ancestorFlags;
+
+ // Add in flags from the parent.
+ if (pd->filtersDescendantEvents)
+ flags |= AncestorFiltersChildEvents;
+ if (pd->handlesChildEvents)
+ flags |= AncestorHandlesChildEvents;
+ if (pd->flags & QGraphicsItem::ItemClipsChildrenToShape)
+ flags |= AncestorClipsChildren;
+ if (pd->flags & QGraphicsItem::ItemIgnoresTransformations)
+ flags |= AncestorIgnoresTransformations;
+ }
+
+ if (ancestorFlags == flags)
+ return; // No change; stop propagation.
+ ancestorFlags = flags;
+
+ // Propagate to children recursively.
+ for (int i = 0; i < children.size(); ++i)
+ children.at(i)->d_ptr->updateAncestorFlags();
+}
+
+/*!
+ \internal
+
+ Propagates item group membership.
+*/
+void QGraphicsItemPrivate::setIsMemberOfGroup(bool enabled)
+{
+ Q_Q(QGraphicsItem);
+ isMemberOfGroup = enabled;
+ if (!qgraphicsitem_cast<QGraphicsItemGroup *>(q)) {
+ foreach (QGraphicsItem *child, children)
+ child->d_func()->setIsMemberOfGroup(enabled);
+ }
+}
+
+/*!
+ \internal
+
+ Maps any item pos properties of \a event to \a item's coordinate system.
+*/
+void QGraphicsItemPrivate::remapItemPos(QEvent *event, QGraphicsItem *item)
+{
+ Q_Q(QGraphicsItem);
+ switch (event->type()) {
+ case QEvent::GraphicsSceneMouseMove:
+ case QEvent::GraphicsSceneMousePress:
+ case QEvent::GraphicsSceneMouseRelease:
+ case QEvent::GraphicsSceneMouseDoubleClick: {
+ QGraphicsSceneMouseEvent *mouseEvent = static_cast<QGraphicsSceneMouseEvent *>(event);
+ mouseEvent->setPos(item->mapFromItem(q, mouseEvent->pos()));
+ mouseEvent->setLastPos(item->mapFromItem(q, mouseEvent->pos()));
+ for (int i = 0x1; i <= 0x10; i <<= 1) {
+ if (mouseEvent->buttons() & i) {
+ Qt::MouseButton button = Qt::MouseButton(i);
+ mouseEvent->setButtonDownPos(button, item->mapFromItem(q, mouseEvent->buttonDownPos(button)));
+ }
+ }
+ break;
+ }
+ case QEvent::GraphicsSceneWheel: {
+ QGraphicsSceneWheelEvent *wheelEvent = static_cast<QGraphicsSceneWheelEvent *>(event);
+ wheelEvent->setPos(item->mapFromItem(q, wheelEvent->pos()));
+ break;
+ }
+ case QEvent::GraphicsSceneContextMenu: {
+ QGraphicsSceneContextMenuEvent *contextEvent = static_cast<QGraphicsSceneContextMenuEvent *>(event);
+ contextEvent->setPos(item->mapFromItem(q, contextEvent->pos()));
+ break;
+ }
+ case QEvent::GraphicsSceneHoverMove: {
+ QGraphicsSceneHoverEvent *hoverEvent = static_cast<QGraphicsSceneHoverEvent *>(event);
+ hoverEvent->setPos(item->mapFromItem(q, hoverEvent->pos()));
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+/*!
+ \internal
+
+ Maps the point \a pos from scene to item coordinates. If \a view is passed and the item
+ is untransformable, this function will correctly map \a pos from the scene using the
+ view's transformation.
+*/
+QPointF QGraphicsItemPrivate::genericMapFromScene(const QPointF &pos,
+ const QWidget *viewport) const
+{
+ Q_Q(const QGraphicsItem);
+ if (!itemIsUntransformable())
+ return q->mapFromScene(pos);
+ QGraphicsView *view = 0;
+ if (viewport)
+ view = qobject_cast<QGraphicsView *>(viewport->parentWidget());
+ if (!view)
+ return q->mapFromScene(pos);
+ // ### More ping pong than needed.
+ return q->deviceTransform(view->viewportTransform()).inverted().map(view->mapFromScene(pos));
+}
+
+/*!
+ \internal
+
+ Combines this item's position and transform onto \a transform.
+
+ If you need to change this function (e.g., adding more transformation
+ modes / options), make sure to change all places marked with COMBINE.
+*/
+void QGraphicsItemPrivate::combineTransformToParent(QTransform *x, const QTransform *viewTransform) const
+{
+ // COMBINE
+ if (viewTransform && itemIsUntransformable()) {
+ *x = q_ptr->deviceTransform(*viewTransform);
+ } else {
+ if (transformData)
+ *x *= transformData->computedFullTransform();
+ if (!pos.isNull())
+ *x *= QTransform::fromTranslate(pos.x(), pos.y());
+ }
+}
+
+/*!
+ \internal
+
+ Combines this item's position and transform onto \a transform.
+
+ If you need to change this function (e.g., adding more transformation
+ modes / options), make sure to change QGraphicsItem::deviceTransform() as
+ well.
+*/
+void QGraphicsItemPrivate::combineTransformFromParent(QTransform *x, const QTransform *viewTransform) const
+{
+ // COMBINE
+ if (viewTransform && itemIsUntransformable()) {
+ *x = q_ptr->deviceTransform(*viewTransform);
+ } else {
+ x->translate(pos.x(), pos.y());
+ if (transformData)
+ *x = transformData->computedFullTransform(x);
+ }
+}
+
+void QGraphicsItemPrivate::updateSceneTransformFromParent()
+{
+ if (parent) {
+ Q_ASSERT(!parent->d_ptr->dirtySceneTransform);
+ if (parent->d_ptr->sceneTransformTranslateOnly) {
+ sceneTransform = QTransform::fromTranslate(parent->d_ptr->sceneTransform.dx() + pos.x(),
+ parent->d_ptr->sceneTransform.dy() + pos.y());
+ } else {
+ sceneTransform = parent->d_ptr->sceneTransform;
+ sceneTransform.translate(pos.x(), pos.y());
+ }
+ if (transformData) {
+ sceneTransform = transformData->computedFullTransform(&sceneTransform);
+ sceneTransformTranslateOnly = (sceneTransform.type() <= QTransform::TxTranslate);
+ } else {
+ sceneTransformTranslateOnly = parent->d_ptr->sceneTransformTranslateOnly;
+ }
+ } else if (!transformData) {
+ sceneTransform = QTransform::fromTranslate(pos.x(), pos.y());
+ sceneTransformTranslateOnly = 1;
+ } else if (transformData->onlyTransform) {
+ sceneTransform = transformData->transform;
+ if (!pos.isNull())
+ sceneTransform *= QTransform::fromTranslate(pos.x(), pos.y());
+ sceneTransformTranslateOnly = (sceneTransform.type() <= QTransform::TxTranslate);
+ } else if (pos.isNull()) {
+ sceneTransform = transformData->computedFullTransform();
+ sceneTransformTranslateOnly = (sceneTransform.type() <= QTransform::TxTranslate);
+ } else {
+ sceneTransform = QTransform::fromTranslate(pos.x(), pos.y());
+ sceneTransform = transformData->computedFullTransform(&sceneTransform);
+ sceneTransformTranslateOnly = (sceneTransform.type() <= QTransform::TxTranslate);
+ }
+ dirtySceneTransform = 0;
+}
+
+/*!
+ \internal
+
+ This helper function helped us add input method query support in
+ Qt 4.4.1 without having to reimplement the inputMethodQuery()
+ function in QGraphicsProxyWidget. ### Qt 5: Remove. We cannot
+ remove it in 4.5+ even if we do reimplement the function properly,
+ because apps compiled with 4.4 will not be able to call the
+ reimplementation.
+*/
+QVariant QGraphicsItemPrivate::inputMethodQueryHelper(Qt::InputMethodQuery query) const
+{
+ Q_UNUSED(query);
+ return QVariant();
+}
+
+/*!
+ \internal
+
+ Make sure not to trigger any pure virtual function calls (e.g.,
+ prepareGeometryChange) if the item is in its destructor, i.e.
+ inDestructor is 1.
+*/
+void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent, const QVariant *newParentVariant,
+ const QVariant *thisPointerVariant)
+{
+ Q_Q(QGraphicsItem);
+ if (newParent == parent)
+ return;
+
+ if (isWidget)
+ static_cast<QGraphicsWidgetPrivate *>(this)->fixFocusChainBeforeReparenting((newParent &&
+ newParent->isWidget()) ? static_cast<QGraphicsWidget *>(newParent) : 0,
+ scene);
+ if (scene) {
+ // Deliver the change to the index
+ if (scene->d_func()->indexMethod != QGraphicsScene::NoIndex)
+ scene->d_func()->index->itemChange(q, QGraphicsItem::ItemParentChange, newParent);
+
+ // Disable scene pos notifications for old ancestors
+ if (scenePosDescendants || (flags & QGraphicsItem::ItemSendsScenePositionChanges))
+ scene->d_func()->setScenePosItemEnabled(q, false);
+ }
+
+ if (subFocusItem && parent) {
+ // Make sure none of the old parents point to this guy.
+ subFocusItem->d_ptr->clearSubFocus(parent);
+ }
+
+ // We anticipate geometry changes. If the item is deleted, it will be
+ // removed from the index at a later stage, and the whole scene will be
+ // updated.
+ if (!inDestructor)
+ q_ptr->prepareGeometryChange();
+
+ if (parent) {
+ // Remove from current parent
+ parent->d_ptr->removeChild(q);
+ if (thisPointerVariant)
+ parent->itemChange(QGraphicsItem::ItemChildRemovedChange, *thisPointerVariant);
+ }
+
+ // Update toplevelitem list. If this item is being deleted, its parent
+ // will be 0 but we don't want to register/unregister it in the TLI list.
+ if (scene && !inDestructor) {
+ if (parent && !newParent) {
+ scene->d_func()->registerTopLevelItem(q);
+ } else if (!parent && newParent) {
+ scene->d_func()->unregisterTopLevelItem(q);
+ }
+ }
+
+ // Ensure any last parent focus scope does not point to this item or any of
+ // its descendents.
+ QGraphicsItem *p = parent;
+ QGraphicsItem *parentFocusScopeItem = 0;
+ while (p) {
+ if (p->d_ptr->flags & QGraphicsItem::ItemIsFocusScope) {
+ // If this item's focus scope's focus scope item points
+ // to this item or a descendent, then clear it.
+ QGraphicsItem *fsi = p->d_ptr->focusScopeItem;
+ if (q_ptr == fsi || q_ptr->isAncestorOf(fsi)) {
+ parentFocusScopeItem = fsi;
+ p->d_ptr->focusScopeItem = 0;
+ fsi->d_ptr->focusScopeItemChange(false);
+ }
+ break;
+ }
+ p = p->d_ptr->parent;
+ }
+
+ // Update graphics effect optimization flag
+ if (newParent && (graphicsEffect || mayHaveChildWithGraphicsEffect))
+ newParent->d_ptr->updateChildWithGraphicsEffectFlagRecursively();
+
+ // Update focus scope item ptr in new scope.
+ QGraphicsItem *newFocusScopeItem = subFocusItem ? subFocusItem : parentFocusScopeItem;
+ if (newFocusScopeItem && newParent) {
+ QGraphicsItem *p = newParent;
+ while (p) {
+ if (p->d_ptr->flags & QGraphicsItem::ItemIsFocusScope) {
+ if (subFocusItem && subFocusItem != q_ptr) {
+ // Find the subFocusItem's topmost focus scope within the new parent's focusscope
+ QGraphicsItem *ancestorScope = 0;
+ QGraphicsItem *p2 = subFocusItem->d_ptr->parent;
+ while (p2 && p2 != p) {
+ if (p2->d_ptr->flags & QGraphicsItem::ItemIsFocusScope)
+ ancestorScope = p2;
+ if (p2->d_ptr->flags & QGraphicsItem::ItemIsPanel)
+ break;
+ if (p2 == q_ptr)
+ break;
+ p2 = p2->d_ptr->parent;
+ }
+ if (ancestorScope)
+ newFocusScopeItem = ancestorScope;
+ }
+
+ p->d_ptr->focusScopeItem = newFocusScopeItem;
+ newFocusScopeItem->d_ptr->focusScopeItemChange(true);
+ // Ensure the new item is no longer the subFocusItem. The
+ // only way to set focus on a child of a focus scope is
+ // by setting focus on the scope itself.
+ if (subFocusItem && !p->focusItem())
+ subFocusItem->d_ptr->clearSubFocus();
+ break;
+ }
+ p = p->d_ptr->parent;
+ }
+ }
+
+ // Resolve depth.
+ invalidateDepthRecursively();
+
+ if ((parent = newParent)) {
+ if (parent->d_func()->scene && parent->d_func()->scene != scene) {
+ // Move this item to its new parent's scene
+ parent->d_func()->scene->addItem(q);
+ } else if (!parent->d_func()->scene && scene) {
+ // Remove this item from its former scene
+ scene->removeItem(q);
+ }
+
+ parent->d_ptr->addChild(q);
+ if (thisPointerVariant)
+ parent->itemChange(QGraphicsItem::ItemChildAddedChange, *thisPointerVariant);
+ if (scene) {
+ // Re-enable scene pos notifications for new ancestors
+ if (scenePosDescendants || (flags & QGraphicsItem::ItemSendsScenePositionChanges))
+ scene->d_func()->setScenePosItemEnabled(q, true);
+ }
+
+ // Propagate dirty flags to the new parent
+ markParentDirty(/*updateBoundingRect=*/true);
+
+ // Inherit ancestor flags from the new parent.
+ updateAncestorFlags();
+
+ // Update item visible / enabled.
+ if (parent->d_ptr->visible != visible) {
+ if (!parent->d_ptr->visible || !explicitlyHidden)
+ setVisibleHelper(parent->d_ptr->visible, /* explicit = */ false, /* update = */ false);
+ }
+ if (parent->isEnabled() != enabled) {
+ if (!parent->d_ptr->enabled || !explicitlyDisabled)
+ setEnabledHelper(parent->d_ptr->enabled, /* explicit = */ false, /* update = */ false);
+ }
+
+ // Auto-activate if visible and the parent is active.
+ if (visible && parent->isActive())
+ q->setActive(true);
+ } else {
+ // Inherit ancestor flags from the new parent.
+ updateAncestorFlags();
+
+ if (!inDestructor) {
+ // Update item visible / enabled.
+ if (!visible && !explicitlyHidden)
+ setVisibleHelper(true, /* explicit = */ false);
+ if (!enabled && !explicitlyDisabled)
+ setEnabledHelper(true, /* explicit = */ false);
+ }
+ }
+
+ dirtySceneTransform = 1;
+ if (!inDestructor && (transformData || (newParent && newParent->d_ptr->transformData)))
+ transformChanged();
+
+ // Restore the sub focus chain.
+ if (subFocusItem) {
+ subFocusItem->d_ptr->setSubFocus(newParent);
+ if (parent && parent->isActive())
+ subFocusItem->setFocus();
+ }
+
+ // Deliver post-change notification
+ if (newParentVariant)
+ q->itemChange(QGraphicsItem::ItemParentHasChanged, *newParentVariant);
+
+ if (isObject)
+ emit static_cast<QGraphicsObject *>(q)->parentChanged();
+}
+
+/*!
+ \internal
+
+ Returns the bounding rect of this item's children (excluding itself).
+*/
+void QGraphicsItemPrivate::childrenBoundingRectHelper(QTransform *x, QRectF *rect, QGraphicsItem *topMostEffectItem)
+{
+ Q_Q(QGraphicsItem);
+
+ QRectF childrenRect;
+ QRectF *result = rect;
+ rect = &childrenRect;
+ const bool setTopMostEffectItem = !topMostEffectItem;
+
+ for (int i = 0; i < children.size(); ++i) {
+ QGraphicsItem *child = children.at(i);
+ QGraphicsItemPrivate *childd = child->d_ptr.data();
+ if (setTopMostEffectItem)
+ topMostEffectItem = child;
+ bool hasPos = !childd->pos.isNull();
+ if (hasPos || childd->transformData) {
+ // COMBINE
+ QTransform matrix = childd->transformToParent();
+ if (x)
+ matrix *= *x;
+ *rect |= matrix.mapRect(child->d_ptr->effectiveBoundingRect(topMostEffectItem));
+ if (!childd->children.isEmpty())
+ childd->childrenBoundingRectHelper(&matrix, rect, topMostEffectItem);
+ } else {
+ if (x)
+ *rect |= x->mapRect(child->d_ptr->effectiveBoundingRect(topMostEffectItem));
+ else
+ *rect |= child->d_ptr->effectiveBoundingRect(topMostEffectItem);
+ if (!childd->children.isEmpty())
+ childd->childrenBoundingRectHelper(x, rect, topMostEffectItem);
+ }
+ }
+
+ if (flags & QGraphicsItem::ItemClipsChildrenToShape){
+ if (x)
+ *rect &= x->mapRect(q->boundingRect());
+ else
+ *rect &= q->boundingRect();
+ }
+
+ *result |= *rect;
+}
+
+void QGraphicsItemPrivate::initStyleOption(QStyleOptionGraphicsItem *option, const QTransform &worldTransform,
+ const QRegion &exposedRegion, bool allItems) const
+{
+ Q_ASSERT(option);
+ Q_Q(const QGraphicsItem);
+
+ // Initialize standard QStyleOption values.
+ const QRectF brect = q->boundingRect();
+ option->state = QStyle::State_None;
+ option->rect = brect.toRect();
+ option->levelOfDetail = 1;
+ option->exposedRect = brect;
+ if (selected)
+ option->state |= QStyle::State_Selected;
+ if (enabled)
+ option->state |= QStyle::State_Enabled;
+ if (q->hasFocus())
+ option->state |= QStyle::State_HasFocus;
+ if (scene) {
+ if (scene->d_func()->hoverItems.contains(q_ptr))
+ option->state |= QStyle::State_MouseOver;
+ if (q == scene->mouseGrabberItem())
+ option->state |= QStyle::State_Sunken;
+ }
+
+ if (!(flags & QGraphicsItem::ItemUsesExtendedStyleOption))
+ return;
+
+ // Initialize QStyleOptionGraphicsItem specific values (matrix, exposedRect).
+ option->matrix = worldTransform.toAffine(); //### discards perspective
+
+ if (!allItems) {
+ // Determine the item's exposed area
+ option->exposedRect = QRectF();
+ const QTransform reverseMap = worldTransform.inverted();
+ const QVector<QRect> exposedRects(exposedRegion.rects());
+ for (int i = 0; i < exposedRects.size(); ++i) {
+ option->exposedRect |= reverseMap.mapRect(QRectF(exposedRects.at(i)));
+ if (option->exposedRect.contains(brect))
+ break;
+ }
+ option->exposedRect &= brect;
+ }
+}
+
+/*!
+ \internal
+
+ Empty all cached pixmaps from the pixmap cache.
+*/
+void QGraphicsItemCache::purge()
+{
+ QPixmapCache::remove(key);
+ key = QPixmapCache::Key();
+ QMutableMapIterator<QPaintDevice *, DeviceData> it(deviceData);
+ while (it.hasNext()) {
+ DeviceData &data = it.next().value();
+ QPixmapCache::remove(data.key);
+ data.cacheIndent = QPoint();
+ }
+ deviceData.clear();
+ allExposed = true;
+ exposed.clear();
+}
+
+/*!
+ Constructs a QGraphicsItem with the given \a parent item.
+ It does not modify the parent object returned by QObject::parent().
+
+ If \a parent is 0, you can add the item to a scene by calling
+ QGraphicsScene::addItem(). The item will then become a top-level item.
+
+ \sa QGraphicsScene::addItem(), setParentItem()
+*/
+QGraphicsItem::QGraphicsItem(QGraphicsItem *parent
+#ifndef Q_QDOC
+ // obsolete argument
+ , QGraphicsScene *scene
+#endif
+ )
+ : d_ptr(new QGraphicsItemPrivate)
+{
+ d_ptr->q_ptr = this;
+ setParentItem(parent);
+
+ if (scene && parent && parent->scene() != scene) {
+ qWarning("QGraphicsItem::QGraphicsItem: ignoring scene (%p), which is"
+ " different from parent's scene (%p)",
+ scene, parent->scene());
+ return;
+ }
+ if (scene && !parent)
+ scene->addItem(this);
+}
+
+/*!
+ \internal
+*/
+QGraphicsItem::QGraphicsItem(QGraphicsItemPrivate &dd, QGraphicsItem *parent,
+ QGraphicsScene *scene)
+ : d_ptr(&dd)
+{
+ d_ptr->q_ptr = this;
+ setParentItem(parent);
+
+ if (scene && parent && parent->scene() != scene) {
+ qWarning("QGraphicsItem::QGraphicsItem: ignoring scene (%p), which is"
+ " different from parent's scene (%p)",
+ scene, parent->scene());
+ return;
+ }
+ if (scene && !parent)
+ scene->addItem(this);
+}
+
+/*!
+ Destroys the QGraphicsItem and all its children. If this item is currently
+ associated with a scene, the item will be removed from the scene before it
+ is deleted.
+
+ \note It is more efficient to remove the item from the QGraphicsScene before
+ destroying the item.
+*/
+QGraphicsItem::~QGraphicsItem()
+{
+ if (d_ptr->isObject) {
+ QGraphicsObject *o = static_cast<QGraphicsObject *>(this);
+ QObjectPrivate *p = QObjectPrivate::get(o);
+ p->wasDeleted = true;
+ if (p->declarativeData) {
+ QAbstractDeclarativeData::destroyed(p->declarativeData, o);
+ p->declarativeData = 0;
+ }
+ }
+
+ d_ptr->inDestructor = 1;
+ d_ptr->removeExtraItemCache();
+
+#ifndef QT_NO_GESTURES
+ if (d_ptr->isObject && !d_ptr->gestureContext.isEmpty()) {
+ QGraphicsObject *o = static_cast<QGraphicsObject *>(this);
+ if (QGestureManager *manager = QGestureManager::instance()) {
+ foreach (Qt::GestureType type, d_ptr->gestureContext.keys())
+ manager->cleanupCachedGestures(o, type);
+ }
+ }
+#endif
+
+ clearFocus();
+
+ // Update focus scope item ptr.
+ QGraphicsItem *p = d_ptr->parent;
+ while (p) {
+ if (p->flags() & ItemIsFocusScope) {
+ if (p->d_ptr->focusScopeItem == this)
+ p->d_ptr->focusScopeItem = 0;
+ break;
+ }
+ p = p->d_ptr->parent;
+ }
+
+ if (!d_ptr->children.isEmpty()) {
+ while (!d_ptr->children.isEmpty())
+ delete d_ptr->children.first();
+ Q_ASSERT(d_ptr->children.isEmpty());
+ }
+
+ if (d_ptr->scene) {
+ d_ptr->scene->d_func()->removeItemHelper(this);
+ } else {
+ d_ptr->resetFocusProxy();
+ setParentItem(0);
+ }
+
+#ifndef QT_NO_GRAPHICSEFFECT
+ delete d_ptr->graphicsEffect;
+#endif //QT_NO_GRAPHICSEFFECT
+ if (d_ptr->transformData) {
+ for(int i = 0; i < d_ptr->transformData->graphicsTransforms.size(); ++i) {
+ QGraphicsTransform *t = d_ptr->transformData->graphicsTransforms.at(i);
+ static_cast<QGraphicsTransformPrivate *>(t->d_ptr.data())->item = 0;
+ delete t;
+ }
+ }
+ delete d_ptr->transformData;
+
+ if (QGraphicsItemCustomDataStore *dataStore = qt_dataStore())
+ dataStore->data.remove(this);
+}
+
+/*!
+ Returns the current scene for the item, or 0 if the item is not stored in
+ a scene.
+
+ To add or move an item to a scene, call QGraphicsScene::addItem().
+*/
+QGraphicsScene *QGraphicsItem::scene() const
+{
+ return d_ptr->scene;
+}
+
+/*!
+ Returns a pointer to this item's item group, or 0 if this item is not
+ member of a group.
+
+ \sa QGraphicsItemGroup, QGraphicsScene::createItemGroup()
+*/
+QGraphicsItemGroup *QGraphicsItem::group() const
+{
+ if (!d_ptr->isMemberOfGroup)
+ return 0;
+ QGraphicsItem *parent = const_cast<QGraphicsItem *>(this);
+ while ((parent = parent->d_ptr->parent)) {
+ if (QGraphicsItemGroup *group = qgraphicsitem_cast<QGraphicsItemGroup *>(parent))
+ return group;
+ }
+ // Unreachable; if d_ptr->isMemberOfGroup is != 0, then one parent of this
+ // item is a group item.
+ return 0;
+}
+
+/*!
+ Adds this item to the item group \a group. If \a group is 0, this item is
+ removed from any current group and added as a child of the previous
+ group's parent.
+
+ \sa group(), QGraphicsScene::createItemGroup()
+*/
+void QGraphicsItem::setGroup(QGraphicsItemGroup *group)
+{
+ if (!group) {
+ if (QGraphicsItemGroup *group = this->group())
+ group->removeFromGroup(this);
+ } else {
+ group->addToGroup(this);
+ }
+}
+
+/*!
+ Returns a pointer to this item's parent item. If this item does not have a
+ parent, 0 is returned.
+
+ \sa setParentItem(), childItems()
+*/
+QGraphicsItem *QGraphicsItem::parentItem() const
+{
+ return d_ptr->parent;
+}
+
+/*!
+ Returns this item's top-level item. The top-level item is the item's
+ topmost ancestor item whose parent is 0. If an item has no parent, its own
+ pointer is returned (i.e., a top-level item is its own top-level item).
+
+ \sa parentItem()
+*/
+QGraphicsItem *QGraphicsItem::topLevelItem() const
+{
+ QGraphicsItem *parent = const_cast<QGraphicsItem *>(this);
+ while (QGraphicsItem *grandPa = parent->parentItem())
+ parent = grandPa;
+ return parent;
+}
+
+/*!
+ \since 4.6
+
+ Returns a pointer to the item's parent, cast to a QGraphicsObject. returns 0 if the parent item
+ is not a QGraphicsObject.
+
+ \sa parentItem(), childItems()
+*/
+QGraphicsObject *QGraphicsItem::parentObject() const
+{
+ QGraphicsItem *p = d_ptr->parent;
+ return (p && p->d_ptr->isObject) ? static_cast<QGraphicsObject *>(p) : 0;
+}
+
+/*!
+ \since 4.4
+
+ Returns a pointer to the item's parent widget. The item's parent widget is
+ the closest parent item that is a widget.
+
+ \sa parentItem(), childItems()
+*/
+QGraphicsWidget *QGraphicsItem::parentWidget() const
+{
+ QGraphicsItem *p = parentItem();
+ while (p && !p->isWidget())
+ p = p->parentItem();
+ return (p && p->isWidget()) ? static_cast<QGraphicsWidget *>(p) : 0;
+}
+
+/*!
+ \since 4.4
+
+ Returns a pointer to the item's top level widget (i.e., the item's
+ ancestor whose parent is 0, or whose parent is not a widget), or 0 if this
+ item does not have a top level widget. If the item is its own top level
+ widget, this function returns a pointer to the item itself.
+*/
+QGraphicsWidget *QGraphicsItem::topLevelWidget() const
+{
+ if (const QGraphicsWidget *p = parentWidget())
+ return p->topLevelWidget();
+ return isWidget() ? static_cast<QGraphicsWidget *>(const_cast<QGraphicsItem *>(this)) : 0;
+}
+
+/*!
+ \since 4.4
+
+ Returns the item's window, or 0 if this item does not have a window. If
+ the item is a window, it will return itself. Otherwise it will return the
+ closest ancestor that is a window.
+
+ \sa QGraphicsWidget::isWindow()
+*/
+QGraphicsWidget *QGraphicsItem::window() const
+{
+ QGraphicsItem *p = panel();
+ if (p && p->isWindow())
+ return static_cast<QGraphicsWidget *>(p);
+ return 0;
+}
+
+/*!
+ \since 4.6
+
+ Returns the item's panel, or 0 if this item does not have a panel. If the
+ item is a panel, it will return itself. Otherwise it will return the
+ closest ancestor that is a panel.
+
+ \sa isPanel(), ItemIsPanel
+*/
+QGraphicsItem *QGraphicsItem::panel() const
+{
+ if (d_ptr->flags & ItemIsPanel)
+ return const_cast<QGraphicsItem *>(this);
+ return d_ptr->parent ? d_ptr->parent->panel() : 0;
+}
+
+/*!
+ \since 4.6
+
+ Return the graphics item cast to a QGraphicsObject, if the class is actually a
+ graphics object, 0 otherwise.
+*/
+QGraphicsObject *QGraphicsItem::toGraphicsObject()
+{
+ return d_ptr->isObject ? static_cast<QGraphicsObject *>(this) : 0;
+}
+
+/*!
+ \since 4.6
+
+ Return the graphics item cast to a QGraphicsObject, if the class is actually a
+ graphics object, 0 otherwise.
+*/
+const QGraphicsObject *QGraphicsItem::toGraphicsObject() const
+{
+ return d_ptr->isObject ? static_cast<const QGraphicsObject *>(this) : 0;
+}
+
+/*!
+ Sets this item's parent item to \a newParent. If this item already
+ has a parent, it is first removed from the previous parent. If \a
+ newParent is 0, this item will become a top-level item.
+
+ Note that this implicitly adds this graphics item to the scene of
+ the parent. You should not \l{QGraphicsScene::addItem()}{add} the
+ item to the scene yourself.
+
+ Calling this function on an item that is an ancestor of \a newParent
+ have undefined behaviour.
+
+ \sa parentItem(), childItems()
+*/
+void QGraphicsItem::setParentItem(QGraphicsItem *newParent)
+{
+ if (newParent == this) {
+ qWarning("QGraphicsItem::setParentItem: cannot assign %p as a parent of itself", this);
+ return;
+ }
+ if (newParent == d_ptr->parent)
+ return;
+
+ const QVariant newParentVariant(itemChange(QGraphicsItem::ItemParentChange,
+ QVariant::fromValue<QGraphicsItem *>(newParent)));
+ newParent = qvariant_cast<QGraphicsItem *>(newParentVariant);
+ if (newParent == d_ptr->parent)
+ return;
+
+ const QVariant thisPointerVariant(QVariant::fromValue<QGraphicsItem *>(this));
+ d_ptr->setParentItemHelper(newParent, &newParentVariant, &thisPointerVariant);
+}
+
+/*!
+ \obsolete
+
+ Use childItems() instead.
+
+ \sa setParentItem()
+*/
+QList<QGraphicsItem *> QGraphicsItem::children() const
+{
+ return childItems();
+}
+
+/*!
+ \since 4.4
+
+ Returns a list of this item's children.
+
+ The items are sorted by stacking order. This takes into account both the
+ items' insertion order and their Z-values.
+
+ \sa setParentItem(), zValue(), {QGraphicsItem#Sorting}{Sorting}
+*/
+QList<QGraphicsItem *> QGraphicsItem::childItems() const
+{
+ const_cast<QGraphicsItem *>(this)->d_ptr->ensureSortedChildren();
+ return d_ptr->children;
+}
+
+/*!
+ \since 4.4
+ Returns true if this item is a widget (i.e., QGraphicsWidget); otherwise,
+ returns false.
+*/
+bool QGraphicsItem::isWidget() const
+{
+ return d_ptr->isWidget;
+}
+
+/*!
+ \since 4.4
+ Returns true if the item is a QGraphicsWidget window, otherwise returns
+ false.
+
+ \sa QGraphicsWidget::windowFlags()
+*/
+bool QGraphicsItem::isWindow() const
+{
+ return d_ptr->isWidget && (static_cast<const QGraphicsWidget *>(this)->windowType() & Qt::Window);
+}
+
+/*!
+ \since 4.6
+ Returns true if the item is a panel; otherwise returns false.
+
+ \sa QGraphicsItem::panel(), ItemIsPanel
+*/
+bool QGraphicsItem::isPanel() const
+{
+ return d_ptr->flags & ItemIsPanel;
+}
+
+/*!
+ Returns this item's flags. The flags describe what configurable features
+ of the item are enabled and not. For example, if the flags include
+ ItemIsFocusable, the item can accept input focus.
+
+ By default, no flags are enabled.
+
+ \sa setFlags(), setFlag()
+*/
+QGraphicsItem::GraphicsItemFlags QGraphicsItem::flags() const
+{
+ return GraphicsItemFlags(d_ptr->flags);
+}
+
+/*!
+ If \a enabled is true, the item flag \a flag is enabled; otherwise, it is
+ disabled.
+
+ \sa flags(), setFlags()
+*/
+void QGraphicsItem::setFlag(GraphicsItemFlag flag, bool enabled)
+{
+ if (enabled)
+ setFlags(GraphicsItemFlags(d_ptr->flags) | flag);
+ else
+ setFlags(GraphicsItemFlags(d_ptr->flags) & ~flag);
+}
+
+/*!
+ \internal
+
+ Sets the flag \a flag on \a item and all its children, to \a enabled.
+*/
+static void _q_qgraphicsItemSetFlag(QGraphicsItem *item, QGraphicsItem::GraphicsItemFlag flag,
+ bool enabled)
+{
+ if (item->flags() & flag) {
+ // If this item already has the correct flag set, we don't have to
+ // propagate it.
+ return;
+ }
+ item->setFlag(flag, enabled);
+ foreach (QGraphicsItem *child, item->children())
+ _q_qgraphicsItemSetFlag(child, flag, enabled);
+}
+
+/*!
+ Sets the item flags to \a flags. All flags in \a flags are enabled; all
+ flags not in \a flags are disabled.
+
+ If the item had focus and \a flags does not enable ItemIsFocusable, the
+ item loses focus as a result of calling this function. Similarly, if the
+ item was selected, and \a flags does not enabled ItemIsSelectable, the
+ item is automatically unselected.
+
+ By default, no flags are enabled. (QGraphicsWidget enables the
+ ItemSendsGeometryChanges flag by default in order to track position
+ changes.)
+
+ \sa flags(), setFlag()
+*/
+void QGraphicsItem::setFlags(GraphicsItemFlags flags)
+{
+ // Notify change and check for adjustment.
+ if (quint32(d_ptr->flags) == quint32(flags))
+ return;
+ flags = GraphicsItemFlags(itemChange(ItemFlagsChange, quint32(flags)).toUInt());
+ if (quint32(d_ptr->flags) == quint32(flags))
+ return;
+ if (d_ptr->scene && d_ptr->scene->d_func()->indexMethod != QGraphicsScene::NoIndex)
+ d_ptr->scene->d_func()->index->itemChange(this, ItemFlagsChange, &flags);
+
+ // Flags that alter the geometry of the item (or its children).
+ const quint32 geomChangeFlagsMask = (ItemClipsChildrenToShape | ItemClipsToShape | ItemIgnoresTransformations | ItemIsSelectable);
+ bool fullUpdate = (quint32(flags) & geomChangeFlagsMask) != (d_ptr->flags & geomChangeFlagsMask);
+ if (fullUpdate)
+ d_ptr->updatePaintedViewBoundingRects(/*children=*/true);
+
+ // Keep the old flags to compare the diff.
+ GraphicsItemFlags oldFlags = GraphicsItemFlags(d_ptr->flags);
+
+ // Update flags.
+ d_ptr->flags = flags;
+
+ if (!(d_ptr->flags & ItemIsFocusable) && hasFocus()) {
+ // Clear focus on the item if it has focus when the focusable flag
+ // is unset.
+ clearFocus();
+ }
+
+ if (!(d_ptr->flags & ItemIsSelectable) && isSelected()) {
+ // Unselect the item if it is selected when the selectable flag is
+ // unset.
+ setSelected(false);
+ }
+
+ if ((flags & ItemClipsChildrenToShape) != (oldFlags & ItemClipsChildrenToShape)) {
+ // Item children clipping changes. Propagate the ancestor flag to
+ // all children.
+ d_ptr->updateAncestorFlag(ItemClipsChildrenToShape);
+ // The childrenBoundingRect is clipped to the boundingRect in case of ItemClipsChildrenToShape,
+ // which means we have to invalidate the cached childrenBoundingRect whenever this flag changes.
+ d_ptr->dirtyChildrenBoundingRect = 1;
+ d_ptr->markParentDirty(true);
+ }
+
+ if ((flags & ItemIgnoresTransformations) != (oldFlags & ItemIgnoresTransformations)) {
+ // Item children clipping changes. Propagate the ancestor flag to
+ // all children.
+ d_ptr->updateAncestorFlag(ItemIgnoresTransformations);
+ }
+
+ if ((flags & ItemNegativeZStacksBehindParent) != (oldFlags & ItemNegativeZStacksBehindParent)) {
+ // NB! We change the flags directly here, so we must also update d_ptr->flags.
+ // Note that this has do be done before the ItemStacksBehindParent check
+ // below; otherwise we will loose the change.
+
+ // Update stack-behind.
+ if (d_ptr->z < qreal(0.0))
+ flags |= ItemStacksBehindParent;
+ else
+ flags &= ~ItemStacksBehindParent;
+ d_ptr->flags = flags;
+ }
+
+ if ((flags & ItemStacksBehindParent) != (oldFlags & ItemStacksBehindParent)) {
+ // NB! This check has to come after the ItemNegativeZStacksBehindParent
+ // check above. Be careful.
+
+ // Ensure child item sorting is up to date when toggling this flag.
+ if (d_ptr->parent)
+ d_ptr->parent->d_ptr->needSortChildren = 1;
+ else if (d_ptr->scene)
+ d_ptr->scene->d_func()->needSortTopLevelItems = 1;
+ }
+
+ if ((flags & ItemAcceptsInputMethod) != (oldFlags & ItemAcceptsInputMethod)) {
+ // Update input method sensitivity in any views.
+ if (d_ptr->scene)
+ d_ptr->scene->d_func()->updateInputMethodSensitivityInViews();
+ }
+
+
+ if ((d_ptr->panelModality != NonModal)
+ && d_ptr->scene
+ && (flags & ItemIsPanel) != (oldFlags & ItemIsPanel)) {
+ // update the panel's modal state
+ if (flags & ItemIsPanel)
+ d_ptr->scene->d_func()->enterModal(this);
+ else
+ d_ptr->scene->d_func()->leaveModal(this);
+ }
+
+ if (d_ptr->scene) {
+ if ((flags & ItemSendsScenePositionChanges) != (oldFlags & ItemSendsScenePositionChanges)) {
+ if (flags & ItemSendsScenePositionChanges)
+ d_ptr->scene->d_func()->registerScenePosItem(this);
+ else
+ d_ptr->scene->d_func()->unregisterScenePosItem(this);
+ }
+ d_ptr->scene->d_func()->markDirty(this, QRectF(), /*invalidateChildren=*/true);
+ }
+
+ // Notify change.
+ itemChange(ItemFlagsHaveChanged, quint32(flags));
+}
+
+/*!
+ \since 4.4
+ Returns the cache mode for this item. The default mode is NoCache (i.e.,
+ cache is disabled and all painting is immediate).
+
+ \sa setCacheMode()
+*/
+QGraphicsItem::CacheMode QGraphicsItem::cacheMode() const
+{
+ return QGraphicsItem::CacheMode(d_ptr->cacheMode);
+}
+
+/*!
+ \since 4.4
+ Sets the item's cache mode to \a mode.
+
+ The optional \a logicalCacheSize argument is used only by
+ ItemCoordinateCache mode, and describes the resolution of the cache
+ buffer; if \a logicalCacheSize is (100, 100), QGraphicsItem will fit the
+ item into 100x100 pixels in graphics memory, regardless of the logical
+ size of the item itself. By default QGraphicsItem uses the size of
+ boundingRect(). For all other cache modes than ItemCoordinateCache, \a
+ logicalCacheSize is ignored.
+
+ Caching can speed up rendering if your item spends a significant time
+ redrawing itself. In some cases the cache can also slow down rendering, in
+ particular when the item spends less time redrawing than QGraphicsItem
+ spends redrawing from the cache. When enabled, the item's paint() function
+ will be called only once for each call to update(); for any subsequent
+ repaint requests, the Graphics View framework will redraw from the
+ cache. This approach works particularly well with QGLWidget, which stores
+ all the cache as OpenGL textures.
+
+ Be aware that QPixmapCache's cache limit may need to be changed to obtain
+ optimal performance.
+
+ You can read more about the different cache modes in the CacheMode
+ documentation.
+
+ \sa CacheMode, QPixmapCache::setCacheLimit()
+*/
+void QGraphicsItem::setCacheMode(CacheMode mode, const QSize &logicalCacheSize)
+{
+ CacheMode lastMode = CacheMode(d_ptr->cacheMode);
+ d_ptr->cacheMode = mode;
+ bool noVisualChange = (mode == NoCache && lastMode == NoCache)
+ || (mode == NoCache && lastMode == DeviceCoordinateCache)
+ || (mode == DeviceCoordinateCache && lastMode == NoCache)
+ || (mode == DeviceCoordinateCache && lastMode == DeviceCoordinateCache);
+ if (mode == NoCache) {
+ d_ptr->removeExtraItemCache();
+ } else {
+ QGraphicsItemCache *cache = d_ptr->extraItemCache();
+
+ // Reset old cache
+ cache->purge();
+
+ if (mode == ItemCoordinateCache) {
+ if (lastMode == mode && cache->fixedSize == logicalCacheSize)
+ noVisualChange = true;
+ cache->fixedSize = logicalCacheSize;
+ }
+ }
+ if (!noVisualChange)
+ update();
+}
+
+/*!
+ \since 4.6
+
+ Returns the modality for this item.
+*/
+QGraphicsItem::PanelModality QGraphicsItem::panelModality() const
+{
+ return d_ptr->panelModality;
+}
+
+/*!
+ \since 4.6
+
+ Sets the modality for this item to \a panelModality.
+
+ Changing the modality of a visible item takes effect immediately.
+*/
+void QGraphicsItem::setPanelModality(PanelModality panelModality)
+{
+ if (d_ptr->panelModality == panelModality)
+ return;
+
+ PanelModality previousModality = d_ptr->panelModality;
+ bool enterLeaveModal = (isPanel() && d_ptr->scene && isVisible());
+ if (enterLeaveModal && panelModality == NonModal)
+ d_ptr->scene->d_func()->leaveModal(this);
+ d_ptr->panelModality = panelModality;
+ if (enterLeaveModal && d_ptr->panelModality != NonModal)
+ d_ptr->scene->d_func()->enterModal(this, previousModality);
+}
+
+/*!
+ \since 4.6
+
+ Returns true if this item is blocked by a modal panel, false otherwise. If \a blockingPanel is
+ non-zero, \a blockingPanel will be set to the modal panel that is blocking this item. If this
+ item is not blocked, \a blockingPanel will not be set by this function.
+
+ This function always returns false for items not in a scene.
+
+ \sa panelModality() setPanelModality() PanelModality
+*/
+bool QGraphicsItem::isBlockedByModalPanel(QGraphicsItem **blockingPanel) const
+{
+ if (!d_ptr->scene)
+ return false;
+
+
+ QGraphicsItem *dummy = 0;
+ if (!blockingPanel)
+ blockingPanel = &dummy;
+
+ QGraphicsScenePrivate *scene_d = d_ptr->scene->d_func();
+ if (scene_d->modalPanels.isEmpty())
+ return false;
+
+ // ###
+ if (!scene_d->popupWidgets.isEmpty() && scene_d->popupWidgets.first() == this)
+ return false;
+
+ for (int i = 0; i < scene_d->modalPanels.count(); ++i) {
+ QGraphicsItem *modalPanel = scene_d->modalPanels.at(i);
+ if (modalPanel->panelModality() == QGraphicsItem::SceneModal) {
+ // Scene modal panels block all non-descendents.
+ if (modalPanel != this && !modalPanel->isAncestorOf(this)) {
+ *blockingPanel = modalPanel;
+ return true;
+ }
+ } else {
+ // Window modal panels block ancestors and siblings/cousins.
+ if (modalPanel != this
+ && !modalPanel->isAncestorOf(this)
+ && commonAncestorItem(modalPanel)) {
+ *blockingPanel = modalPanel;
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+#ifndef QT_NO_TOOLTIP
+/*!
+ Returns the item's tool tip, or an empty QString if no tool tip has been
+ set.
+
+ \sa setToolTip(), QToolTip
+*/
+QString QGraphicsItem::toolTip() const
+{
+ return d_ptr->extra(QGraphicsItemPrivate::ExtraToolTip).toString();
+}
+
+/*!
+ Sets the item's tool tip to \a toolTip. If \a toolTip is empty, the item's
+ tool tip is cleared.
+
+ \sa toolTip(), QToolTip
+*/
+void QGraphicsItem::setToolTip(const QString &toolTip)
+{
+ const QVariant toolTipVariant(itemChange(ItemToolTipChange, toolTip));
+ d_ptr->setExtra(QGraphicsItemPrivate::ExtraToolTip, toolTipVariant.toString());
+ itemChange(ItemToolTipHasChanged, toolTipVariant);
+}
+#endif // QT_NO_TOOLTIP
+
+#ifndef QT_NO_CURSOR
+/*!
+ Returns the current cursor shape for the item. The mouse cursor
+ will assume this shape when it's over this item. See the \link
+ Qt::CursorShape list of predefined cursor objects\endlink for a
+ range of useful shapes.
+
+ An editor item might want to use an I-beam cursor:
+
+ \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 2
+
+ If no cursor has been set, the cursor of the item beneath is used.
+
+ \sa setCursor(), hasCursor(), unsetCursor(), QWidget::cursor,
+ QApplication::overrideCursor()
+*/
+QCursor QGraphicsItem::cursor() const
+{
+ return qvariant_cast<QCursor>(d_ptr->extra(QGraphicsItemPrivate::ExtraCursor));
+}
+
+/*!
+ Sets the current cursor shape for the item to \a cursor. The mouse cursor
+ will assume this shape when it's over this item. See the \link
+ Qt::CursorShape list of predefined cursor objects\endlink for a range of
+ useful shapes.
+
+ An editor item might want to use an I-beam cursor:
+
+ \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 3
+
+ If no cursor has been set, the cursor of the item beneath is used.
+
+ \sa cursor(), hasCursor(), unsetCursor(), QWidget::cursor,
+ QApplication::overrideCursor()
+*/
+void QGraphicsItem::setCursor(const QCursor &cursor)
+{
+ const QVariant cursorVariant(itemChange(ItemCursorChange, QVariant::fromValue<QCursor>(cursor)));
+ d_ptr->setExtra(QGraphicsItemPrivate::ExtraCursor, qvariant_cast<QCursor>(cursorVariant));
+ d_ptr->hasCursor = 1;
+ if (d_ptr->scene) {
+ d_ptr->scene->d_func()->allItemsUseDefaultCursor = false;
+ foreach (QGraphicsView *view, d_ptr->scene->views()) {
+ view->viewport()->setMouseTracking(true);
+ // Note: Some of this logic is duplicated in QGraphicsView's mouse events.
+ if (view->underMouse()) {
+ foreach (QGraphicsItem *itemUnderCursor, view->items(view->mapFromGlobal(QCursor::pos()))) {
+ if (itemUnderCursor->hasCursor()) {
+ QMetaObject::invokeMethod(view, "_q_setViewportCursor",
+ Q_ARG(QCursor, itemUnderCursor->cursor()));
+ break;
+ }
+ }
+ break;
+ }
+ }
+ }
+ itemChange(ItemCursorHasChanged, cursorVariant);
+}
+
+/*!
+ Returns true if this item has a cursor set; otherwise, false is returned.
+
+ By default, items don't have any cursor set. cursor() will return a
+ standard pointing arrow cursor.
+
+ \sa unsetCursor()
+*/
+bool QGraphicsItem::hasCursor() const
+{
+ return d_ptr->hasCursor;
+}
+
+/*!
+ Clears the cursor from this item.
+
+ \sa hasCursor(), setCursor()
+*/
+void QGraphicsItem::unsetCursor()
+{
+ d_ptr->unsetExtra(QGraphicsItemPrivate::ExtraCursor);
+ d_ptr->hasCursor = 0;
+ if (d_ptr->scene) {
+ foreach (QGraphicsView *view, d_ptr->scene->views()) {
+ if (view->underMouse() && view->itemAt(view->mapFromGlobal(QCursor::pos())) == this) {
+ QMetaObject::invokeMethod(view, "_q_unsetViewportCursor");
+ break;
+ }
+ }
+ }
+}
+
+#endif // QT_NO_CURSOR
+
+/*!
+ Returns true if the item is visible; otherwise, false is returned.
+
+ Note that the item's general visibility is unrelated to whether or not it
+ is actually being visualized by a QGraphicsView.
+
+ \sa setVisible()
+*/
+bool QGraphicsItem::isVisible() const
+{
+ return d_ptr->visible;
+}
+
+/*!
+ \since 4.4
+ Returns true if the item is visible to \a parent; otherwise, false is
+ returned. \a parent can be 0, in which case this function will return
+ whether the item is visible to the scene or not.
+
+ An item may not be visible to its ancestors even if isVisible() is true. If
+ any ancestor is hidden, the item itself will be implicitly hidden, in which
+ case this function will return false.
+
+ \sa isVisible(), setVisible()
+*/
+bool QGraphicsItem::isVisibleTo(const QGraphicsItem *parent) const
+{
+ if (!d_ptr->visible)
+ return false;
+ if (parent == this)
+ return true;
+ if (parentItem() && parentItem()->isVisibleTo(parent))
+ return true;
+ if (!parent && !parentItem())
+ return true;
+ return false;
+}
+
+/*!
+ \internal
+
+ Sets this item's visibility to \a newVisible. If \a explicitly is true,
+ this item will be "explicitly" \a newVisible; otherwise, it.. will not be.
+*/
+void QGraphicsItemPrivate::setVisibleHelper(bool newVisible, bool explicitly, bool update)
+{
+ Q_Q(QGraphicsItem);
+
+ // Update explicit bit.
+ if (explicitly)
+ explicitlyHidden = newVisible ? 0 : 1;
+
+ // Check if there's nothing to do.
+ if (visible == quint32(newVisible))
+ return;
+
+ // Don't show child if parent is not visible
+ if (parent && newVisible && !parent->d_ptr->visible)
+ return;
+
+ // Modify the property.
+ const QVariant newVisibleVariant(q_ptr->itemChange(QGraphicsItem::ItemVisibleChange,
+ quint32(newVisible)));
+ newVisible = newVisibleVariant.toBool();
+ if (visible == quint32(newVisible))
+ return;
+ visible = newVisible;
+
+ // Schedule redrawing
+ if (update) {
+ QGraphicsItemCache *c = (QGraphicsItemCache *)qvariant_cast<void *>(extra(ExtraCacheData));
+ if (c)
+ c->purge();
+ if (scene) {
+#ifndef QT_NO_GRAPHICSEFFECT
+ invalidateParentGraphicsEffectsRecursively();
+#endif //QT_NO_GRAPHICSEFFECT
+ scene->d_func()->markDirty(q_ptr, QRectF(), /*invalidateChildren=*/false, /*force=*/true);
+ }
+ }
+
+ // Certain properties are dropped as an item becomes invisible.
+ bool hasFocus = q_ptr->hasFocus();
+ if (!newVisible) {
+ if (scene) {
+ if (scene->d_func()->mouseGrabberItems.contains(q))
+ q->ungrabMouse();
+ if (scene->d_func()->keyboardGrabberItems.contains(q))
+ q->ungrabKeyboard();
+ if (q->isPanel() && panelModality != QGraphicsItem::NonModal)
+ scene->d_func()->leaveModal(q_ptr);
+ }
+ if (hasFocus && scene) {
+ // Hiding the closest non-panel ancestor of the focus item
+ QGraphicsItem *focusItem = scene->focusItem();
+ bool clear = true;
+ if (isWidget && !focusItem->isPanel()) {
+ do {
+ if (focusItem == q_ptr) {
+ clear = !static_cast<QGraphicsWidget *>(q_ptr)->focusNextPrevChild(true);
+ break;
+ }
+ } while ((focusItem = focusItem->parentWidget()) && !focusItem->isPanel());
+ }
+ if (clear)
+ clearFocusHelper(/* giveFocusToParent = */ false);
+ }
+ if (q_ptr->isSelected())
+ q_ptr->setSelected(false);
+ } else {
+ geometryChanged = 1;
+ paintedViewBoundingRectsNeedRepaint = 1;
+ if (scene) {
+ if (isWidget) {
+ QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(q_ptr);
+ if (widget->windowType() == Qt::Popup)
+ scene->d_func()->addPopup(widget);
+ }
+ if (q->isPanel() && panelModality != QGraphicsItem::NonModal) {
+ scene->d_func()->enterModal(q_ptr);
+ }
+ }
+ }
+
+ // 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, updateChildren);
+ }
+
+ // Update activation
+ if (scene && q->isPanel()) {
+ if (newVisible) {
+ if (parent && parent->isActive())
+ q->setActive(true);
+ } else {
+ if (q->isActive())
+ scene->setActivePanel(parent);
+ }
+ }
+
+ // Enable subfocus
+ if (scene) {
+ if (newVisible) {
+ // Item is shown
+ QGraphicsItem *p = parent;
+ bool done = false;
+ while (p) {
+ if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
+ QGraphicsItem *fsi = p->d_ptr->focusScopeItem;
+ if (q_ptr == fsi || q_ptr->isAncestorOf(fsi)) {
+ done = true;
+ while (fsi->d_ptr->focusScopeItem && fsi->d_ptr->focusScopeItem->isVisible())
+ fsi = fsi->d_ptr->focusScopeItem;
+ fsi->d_ptr->setFocusHelper(Qt::OtherFocusReason, /* climb = */ true,
+ /* focusFromHide = */ false);
+ }
+ break;
+ }
+ p = p->d_ptr->parent;
+ }
+ if (!done) {
+ QGraphicsItem *fi = subFocusItem;
+ if (fi && fi != scene->focusItem()) {
+ scene->setFocusItem(fi);
+ } else if (flags & QGraphicsItem::ItemIsFocusScope &&
+ !scene->focusItem() &&
+ q->isAncestorOf(scene->d_func()->lastFocusItem)) {
+ q_ptr->setFocus();
+ }
+ }
+ } else {
+ // Item is hidden
+ if (hasFocus) {
+ QGraphicsItem *p = parent;
+ while (p) {
+ if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
+ if (p->d_ptr->visible) {
+ p->d_ptr->setFocusHelper(Qt::OtherFocusReason, /* climb = */ true,
+ /* focusFromHide = */ true);
+ }
+ break;
+ }
+ p = p->d_ptr->parent;
+ }
+ }
+ }
+ }
+
+ // Deliver post-change notification.
+ q_ptr->itemChange(QGraphicsItem::ItemVisibleHasChanged, newVisibleVariant);
+
+ if (isObject)
+ emit static_cast<QGraphicsObject *>(q_ptr)->visibleChanged();
+}
+
+/*!
+ If \a visible is true, the item is made visible. Otherwise, the item is
+ made invisible. Invisible items are not painted, nor do they receive any
+ events. In particular, mouse events pass right through invisible items,
+ and are delivered to any item that may be behind. Invisible items are also
+ unselectable, they cannot take input focus, and are not detected by
+ QGraphicsScene's item location functions.
+
+ If an item becomes invisible while grabbing the mouse, (i.e., while it is
+ receiving mouse events,) it will automatically lose the mouse grab, and
+ the grab is not regained by making the item visible again; it must receive
+ a new mouse press to regain the mouse grab.
+
+ Similarly, an invisible item cannot have focus, so if the item has focus
+ when it becomes invisible, it will lose focus, and the focus is not
+ regained by simply making the item visible again.
+
+ If you hide a parent item, all its children will also be hidden. If you
+ show a parent item, all children will be shown, unless they have been
+ explicitly hidden (i.e., if you call setVisible(false) on a child, it will
+ not be reshown even if its parent is hidden, and then shown again).
+
+ Items are visible by default; it is unnecessary to call
+ setVisible() on a new item.
+
+ \sa isVisible(), show(), hide()
+*/
+void QGraphicsItem::setVisible(bool visible)
+{
+ d_ptr->setVisibleHelper(visible, /* explicit = */ true);
+}
+
+/*!
+ \fn void QGraphicsItem::hide()
+
+ Hides the item. (Items are visible by default.)
+
+ This convenience function is equivalent to calling \c setVisible(false).
+
+ \sa show(), setVisible()
+*/
+
+/*!
+ \fn void QGraphicsItem::show()
+
+ Shows the item. (Items are visible by default.)
+
+ This convenience function is equivalent to calling \c setVisible(true).
+
+ \sa hide(), setVisible()
+*/
+
+/*!
+ Returns true if the item is enabled; otherwise, false is returned.
+
+ \sa setEnabled()
+*/
+bool QGraphicsItem::isEnabled() const
+{
+ return d_ptr->enabled;
+}
+
+/*!
+ \internal
+
+ Sets this item's visibility to \a newEnabled. If \a explicitly is true,
+ this item will be "explicitly" \a newEnabled; otherwise, it.. will not be.
+*/
+void QGraphicsItemPrivate::setEnabledHelper(bool newEnabled, bool explicitly, bool update)
+{
+ // Update explicit bit.
+ if (explicitly)
+ explicitlyDisabled = newEnabled ? 0 : 1;
+
+ // Check if there's nothing to do.
+ if (enabled == quint32(newEnabled))
+ return;
+
+ // Certain properties are dropped when an item is disabled.
+ if (!newEnabled) {
+ if (scene && scene->mouseGrabberItem() == q_ptr)
+ q_ptr->ungrabMouse();
+ if (q_ptr->hasFocus()) {
+ // Disabling the closest non-panel ancestor of the focus item
+ // causes focus to pop to the next item, otherwise it's cleared.
+ QGraphicsItem *focusItem = scene->focusItem();
+ bool clear = true;
+ if (isWidget && !focusItem->isPanel() && q_ptr->isAncestorOf(focusItem)) {
+ do {
+ if (focusItem == q_ptr) {
+ clear = !static_cast<QGraphicsWidget *>(q_ptr)->focusNextPrevChild(true);
+ break;
+ }
+ } while ((focusItem = focusItem->parentWidget()) && !focusItem->isPanel());
+ }
+ if (clear)
+ q_ptr->clearFocus();
+ }
+ if (q_ptr->isSelected())
+ q_ptr->setSelected(false);
+ }
+
+ // Modify the property.
+ const QVariant newEnabledVariant(q_ptr->itemChange(QGraphicsItem::ItemEnabledChange,
+ quint32(newEnabled)));
+ enabled = newEnabledVariant.toBool();
+
+ // Schedule redraw.
+ if (update)
+ q_ptr->update();
+
+ foreach (QGraphicsItem *child, children) {
+ if (!newEnabled || !child->d_ptr->explicitlyDisabled)
+ child->d_ptr->setEnabledHelper(newEnabled, /* explicitly = */ false);
+ }
+
+ // Deliver post-change notification.
+ q_ptr->itemChange(QGraphicsItem::ItemEnabledHasChanged, newEnabledVariant);
+
+ if (isObject)
+ emit static_cast<QGraphicsObject *>(q_ptr)->enabledChanged();
+}
+
+/*!
+ If \a enabled is true, the item is enabled; otherwise, it is disabled.
+
+ Disabled items are visible, but they do not receive any events, and cannot
+ take focus nor be selected. Mouse events are discarded; they are not
+ propagated unless the item is also invisible, or if it does not accept
+ mouse events (see acceptedMouseButtons()). A disabled item cannot become the
+ mouse grabber, and as a result of this, an item loses the grab if it
+ becomes disabled when grabbing the mouse, just like it loses focus if it
+ had focus when it was disabled.
+
+ Disabled items are traditionally drawn using grayed-out colors (see \l
+ QPalette::Disabled).
+
+ If you disable a parent item, all its children will also be disabled. If
+ you enable a parent item, all children will be enabled, unless they have
+ been explicitly disabled (i.e., if you call setEnabled(false) on a child,
+ it will not be reenabled if its parent is disabled, and then enabled
+ again).
+
+ Items are enabled by default.
+
+ \note If you install an event filter, you can still intercept events
+ before they are delivered to items; this mechanism disregards the item's
+ enabled state.
+
+ \sa isEnabled()
+*/
+void QGraphicsItem::setEnabled(bool enabled)
+{
+ d_ptr->setEnabledHelper(enabled, /* explicitly = */ true);
+}
+
+/*!
+ Returns true if this item is selected; otherwise, false is returned.
+
+ Items that are in a group inherit the group's selected state.
+
+ Items are not selected by default.
+
+ \sa setSelected(), QGraphicsScene::setSelectionArea()
+*/
+bool QGraphicsItem::isSelected() const
+{
+ if (QGraphicsItemGroup *group = this->group())
+ return group->isSelected();
+ return d_ptr->selected;
+}
+
+/*!
+ If \a selected is true and this item is selectable, this item is selected;
+ otherwise, it is unselected.
+
+ If the item is in a group, the whole group's selected state is toggled by
+ this function. If the group is selected, all items in the group are also
+ selected, and if the group is not selected, no item in the group is
+ selected.
+
+ Only visible, enabled, selectable items can be selected. If \a selected
+ is true and this item is either invisible or disabled or unselectable,
+ this function does nothing.
+
+ By default, items cannot be selected. To enable selection, set the
+ ItemIsSelectable flag.
+
+ This function is provided for convenience, allowing individual toggling of
+ the selected state of an item. However, a more common way of selecting
+ items is to call QGraphicsScene::setSelectionArea(), which will call this
+ function for all visible, enabled, and selectable items within a specified
+ area on the scene.
+
+ \sa isSelected(), QGraphicsScene::selectedItems()
+*/
+void QGraphicsItem::setSelected(bool selected)
+{
+ if (QGraphicsItemGroup *group = this->group()) {
+ group->setSelected(selected);
+ return;
+ }
+
+ if (!(d_ptr->flags & ItemIsSelectable) || !d_ptr->enabled || !d_ptr->visible)
+ selected = false;
+ if (d_ptr->selected == selected)
+ return;
+ const QVariant newSelectedVariant(itemChange(ItemSelectedChange, quint32(selected)));
+ bool newSelected = newSelectedVariant.toBool();
+ if (d_ptr->selected == newSelected)
+ return;
+ d_ptr->selected = newSelected;
+
+ update();
+ if (d_ptr->scene) {
+ QGraphicsScenePrivate *sceneD = d_ptr->scene->d_func();
+ if (selected) {
+ sceneD->selectedItems << this;
+ } else {
+ // QGraphicsScene::selectedItems() lazily pulls out all items that are
+ // no longer selected.
+ }
+ if (!sceneD->selectionChanging)
+ emit d_ptr->scene->selectionChanged();
+ }
+
+ // Deliver post-change notification.
+ itemChange(QGraphicsItem::ItemSelectedHasChanged, newSelectedVariant);
+}
+
+/*!
+ \since 4.5
+
+ Returns this item's local opacity, which is between 0.0 (transparent) and
+ 1.0 (opaque). This value is combined with parent and ancestor values into
+ the effectiveOpacity(). The effective opacity decides how the item is
+ rendered.
+
+ The opacity property decides the state of the painter passed to the
+ paint() function. If the item is cached, i.e., ItemCoordinateCache or
+ DeviceCoordinateCache, the effective property will be applied to the item's
+ cache as it is rendered.
+
+ The default opacity is 1.0; fully opaque.
+
+ \sa setOpacity(), paint(), ItemIgnoresParentOpacity,
+ ItemDoesntPropagateOpacityToChildren
+*/
+qreal QGraphicsItem::opacity() const
+{
+ return d_ptr->opacity;
+}
+
+/*!
+ \since 4.5
+
+ Returns this item's \e effective opacity, which is between 0.0
+ (transparent) and 1.0 (opaque). This value is a combination of this item's
+ local opacity, and its parent and ancestors' opacities. The effective
+ opacity decides how the item is rendered.
+
+ \sa opacity(), setOpacity(), paint(), ItemIgnoresParentOpacity,
+ ItemDoesntPropagateOpacityToChildren
+*/
+qreal QGraphicsItem::effectiveOpacity() const
+{
+ return d_ptr->effectiveOpacity();
+}
+
+/*!
+ \since 4.5
+
+ Sets this item's local \a opacity, between 0.0 (transparent) and 1.0
+ (opaque). The item's local opacity is combined with parent and ancestor
+ opacities into the effectiveOpacity().
+
+ By default, opacity propagates from parent to child, so if a parent's
+ opacity is 0.5 and the child is also 0.5, the child's effective opacity
+ will be 0.25.
+
+ The opacity property decides the state of the painter passed to the
+ paint() function. If the item is cached, i.e., ItemCoordinateCache or
+ DeviceCoordinateCache, the effective property will be applied to the
+ item's cache as it is rendered.
+
+ There are two item flags that affect how the item's opacity is combined
+ with the parent: ItemIgnoresParentOpacity and
+ ItemDoesntPropagateOpacityToChildren.
+
+ \sa opacity(), effectiveOpacity()
+*/
+void QGraphicsItem::setOpacity(qreal opacity)
+{
+ // Notify change.
+ const QVariant newOpacityVariant(itemChange(ItemOpacityChange, opacity));
+
+ // Normalized opacity
+ qreal newOpacity = qBound(qreal(0), newOpacityVariant.toReal(), qreal(1));
+
+ // No change? Done.
+ if (newOpacity == d_ptr->opacity)
+ return;
+
+ bool wasFullyTransparent = d_ptr->isOpacityNull();
+ d_ptr->opacity = newOpacity;
+
+ // Notify change.
+ itemChange(ItemOpacityHasChanged, newOpacityVariant);
+
+ // Update.
+ if (d_ptr->scene) {
+#ifndef QT_NO_GRAPHICSEFFECT
+ d_ptr->invalidateParentGraphicsEffectsRecursively();
+ if (!(d_ptr->flags & ItemDoesntPropagateOpacityToChildren))
+ d_ptr->invalidateChildGraphicsEffectsRecursively(QGraphicsItemPrivate::OpacityChanged);
+#endif //QT_NO_GRAPHICSEFFECT
+ d_ptr->scene->d_func()->markDirty(this, QRectF(),
+ /*invalidateChildren=*/true,
+ /*force=*/false,
+ /*ignoreOpacity=*/d_ptr->isOpacityNull());
+ if (wasFullyTransparent)
+ d_ptr->paintedViewBoundingRectsNeedRepaint = 1;
+ }
+
+ if (d_ptr->isObject)
+ emit static_cast<QGraphicsObject *>(this)->opacityChanged();
+}
+
+/*!
+ Returns a pointer to this item's effect if it has one; otherwise 0.
+
+ \since 4.6
+*/
+#ifndef QT_NO_GRAPHICSEFFECT
+QGraphicsEffect *QGraphicsItem::graphicsEffect() const
+{
+ return d_ptr->graphicsEffect;
+}
+
+/*!
+ Sets \a effect as the item's effect. If there already is an effect installed
+ on this item, QGraphicsItem will delete the existing effect before installing
+ the new \a effect.
+
+ If \a effect is the installed on a different item, setGraphicsEffect() will remove
+ the effect from the item and install it on this item.
+
+ QGraphicsItem takes ownership of \a effect.
+
+ \note This function will apply the effect on itself and all its children.
+
+ \since 4.6
+*/
+void QGraphicsItem::setGraphicsEffect(QGraphicsEffect *effect)
+{
+ if (d_ptr->graphicsEffect == effect)
+ return;
+
+ if (d_ptr->graphicsEffect) {
+ delete d_ptr->graphicsEffect;
+ d_ptr->graphicsEffect = 0;
+ } else if (d_ptr->parent) {
+ d_ptr->parent->d_ptr->updateChildWithGraphicsEffectFlagRecursively();
+ }
+
+ if (effect) {
+ // Set new effect.
+ QGraphicsEffectSourcePrivate *sourced = new QGraphicsItemEffectSourcePrivate(this);
+ QGraphicsEffectSource *source = new QGraphicsEffectSource(*sourced);
+ d_ptr->graphicsEffect = effect;
+ effect->d_func()->setGraphicsEffectSource(source);
+ prepareGeometryChange();
+ }
+}
+#endif //QT_NO_GRAPHICSEFFECT
+
+void QGraphicsItemPrivate::updateChildWithGraphicsEffectFlagRecursively()
+{
+#ifndef QT_NO_GRAPHICSEFFECT
+ QGraphicsItemPrivate *itemPrivate = this;
+ do {
+ // parent chain already notified?
+ if (itemPrivate->mayHaveChildWithGraphicsEffect)
+ return;
+ itemPrivate->mayHaveChildWithGraphicsEffect = 1;
+ } while ((itemPrivate = itemPrivate->parent ? itemPrivate->parent->d_ptr.data() : 0));
+#endif
+}
+
+/*!
+ \internal
+ \since 4.6
+ Returns the effective bounding rect of the given item space rect.
+ If the item has no effect, the rect is returned unmodified.
+ If the item has an effect, the effective rect can be extend beyond the
+ item's bounding rect, depending on the effect.
+
+ \sa boundingRect()
+*/
+QRectF QGraphicsItemPrivate::effectiveBoundingRect(const QRectF &rect) const
+{
+#ifndef QT_NO_GRAPHICSEFFECT
+ Q_Q(const QGraphicsItem);
+ QGraphicsEffect *effect = graphicsEffect;
+ if (scene && effect && effect->isEnabled()) {
+ if (scene->d_func()->views.isEmpty())
+ return effect->boundingRectFor(rect);
+ QRectF sceneRect = q->mapRectToScene(rect);
+ QRectF sceneEffectRect;
+ foreach (QGraphicsView *view, scene->views()) {
+ QRectF deviceRect = view->d_func()->mapRectFromScene(sceneRect);
+ QRect deviceEffectRect = effect->boundingRectFor(deviceRect).toAlignedRect();
+ sceneEffectRect |= view->d_func()->mapRectToScene(deviceEffectRect);
+ }
+ return q->mapRectFromScene(sceneEffectRect);
+ }
+#endif //QT_NO_GRAPHICSEFFECT
+ return rect;
+}
+
+/*!
+ \internal
+ \since 4.6
+ Returns the effective bounding rect of the item.
+ If the item has no effect, this is the same as the item's bounding rect.
+ If the item has an effect, the effective rect can be larger than the item's
+ bouding rect, depending on the effect.
+
+ \sa boundingRect()
+*/
+QRectF QGraphicsItemPrivate::effectiveBoundingRect(QGraphicsItem *topMostEffectItem) const
+{
+#ifndef QT_NO_GRAPHICSEFFECT
+ Q_Q(const QGraphicsItem);
+ QRectF brect = effectiveBoundingRect(q_ptr->boundingRect());
+ if (ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren || topMostEffectItem == q)
+ return brect;
+
+ const QGraphicsItem *effectParent = parent;
+ while (effectParent) {
+ QGraphicsEffect *effect = effectParent->d_ptr->graphicsEffect;
+ if (scene && effect && effect->isEnabled()) {
+ const QRectF brectInParentSpace = q->mapRectToItem(effectParent, brect);
+ const QRectF effectRectInParentSpace = effectParent->d_ptr->effectiveBoundingRect(brectInParentSpace);
+ brect = effectParent->mapRectToItem(q, effectRectInParentSpace);
+ }
+ if (effectParent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren
+ || topMostEffectItem == effectParent) {
+ return brect;
+ }
+ effectParent = effectParent->d_ptr->parent;
+ }
+
+ return brect;
+#else //QT_NO_GRAPHICSEFFECT
+ return q_ptr->boundingRect();
+#endif //QT_NO_GRAPHICSEFFECT
+
+}
+
+/*!
+ \internal
+ \since 4.6
+ Returns the effective bounding rect of this item in scene coordinates,
+ by combining sceneTransform() with boundingRect(), taking into account
+ the effect that the item might have.
+
+ If the item has no effect, this is the same as sceneBoundingRect().
+
+ \sa effectiveBoundingRect(), sceneBoundingRect()
+*/
+QRectF QGraphicsItemPrivate::sceneEffectiveBoundingRect() const
+{
+ // Find translate-only offset
+ // COMBINE
+ QPointF offset;
+ const QGraphicsItem *parentItem = q_ptr;
+ const QGraphicsItemPrivate *itemd;
+ do {
+ itemd = parentItem->d_ptr.data();
+ if (itemd->transformData)
+ break;
+ offset += itemd->pos;
+ } while ((parentItem = itemd->parent));
+
+ QRectF br = effectiveBoundingRect();
+ br.translate(offset);
+ return !parentItem ? br : parentItem->sceneTransform().mapRect(br);
+}
+
+/*!
+ Returns true if this item can accept drag and drop events; otherwise,
+ returns false. By default, items do not accept drag and drop events; items
+ are transparent to drag and drop.
+
+ \sa setAcceptDrops()
+*/
+bool QGraphicsItem::acceptDrops() const
+{
+ return d_ptr->acceptDrops;
+}
+
+/*!
+ If \a on is true, this item will accept drag and drop events; otherwise,
+ it is transparent for drag and drop events. By default, items do not
+ accept drag and drop events.
+
+ \sa acceptDrops()
+*/
+void QGraphicsItem::setAcceptDrops(bool on)
+{
+ d_ptr->acceptDrops = on;
+}
+
+/*!
+ Returns the mouse buttons that this item accepts mouse events for. By
+ default, all mouse buttons are accepted.
+
+ If an item accepts a mouse button, it will become the mouse
+ grabber item when a mouse press event is delivered for that mouse
+ button. However, if the item does not accept the button,
+ QGraphicsScene will forward the mouse events to the first item
+ beneath it that does.
+
+ \sa setAcceptedMouseButtons(), mousePressEvent()
+*/
+Qt::MouseButtons QGraphicsItem::acceptedMouseButtons() const
+{
+ return Qt::MouseButtons(d_ptr->acceptedMouseButtons);
+}
+
+/*!
+ Sets the mouse \a buttons that this item accepts mouse events for.
+
+ By default, all mouse buttons are accepted. If an item accepts a
+ mouse button, it will become the mouse grabber item when a mouse
+ press event is delivered for that button. However, if the item
+ does not accept the mouse button, QGraphicsScene will forward the
+ mouse events to the first item beneath it that does.
+
+ To disable mouse events for an item (i.e., make it transparent for mouse
+ events), call setAcceptedMouseButtons(0).
+
+ \sa acceptedMouseButtons(), mousePressEvent()
+*/
+void QGraphicsItem::setAcceptedMouseButtons(Qt::MouseButtons buttons)
+{
+ if (Qt::MouseButtons(d_ptr->acceptedMouseButtons) != buttons) {
+ if (buttons == 0 && d_ptr->scene && d_ptr->scene->mouseGrabberItem() == this
+ && d_ptr->scene->d_func()->lastMouseGrabberItemHasImplicitMouseGrab) {
+ ungrabMouse();
+ }
+ d_ptr->acceptedMouseButtons = quint32(buttons);
+ }
+}
+
+/*!
+ \since 4.4
+
+ Returns true if an item accepts hover events
+ (QGraphicsSceneHoverEvent); otherwise, returns false. By default,
+ items do not accept hover events.
+
+ \sa setAcceptedMouseButtons()
+*/
+bool QGraphicsItem::acceptHoverEvents() const
+{
+ return d_ptr->acceptsHover;
+}
+
+/*!
+ \obsolete
+
+ Call acceptHoverEvents() instead.
+*/
+bool QGraphicsItem::acceptsHoverEvents() const
+{
+ return d_ptr->acceptsHover;
+}
+
+/*!
+ \since 4.4
+
+ If \a enabled is true, this item will accept hover events;
+ otherwise, it will ignore them. By default, items do not accept
+ hover events.
+
+ Hover events are delivered when there is no current mouse grabber
+ item. They are sent when the mouse cursor enters an item, when it
+ moves around inside the item, and when the cursor leaves an
+ item. Hover events are commonly used to highlight an item when
+ it's entered, and for tracking the mouse cursor as it hovers over
+ the item (equivalent to QWidget::mouseTracking).
+
+ Parent items receive hover enter events before their children, and
+ leave events after their children. The parent does not receive a
+ hover leave event if the cursor enters a child, though; the parent
+ stays "hovered" until the cursor leaves its area, including its
+ children's areas.
+
+ If a parent item handles child events, it will receive hover move,
+ drag move, and drop events as the cursor passes through its
+ children, but it does not receive hover enter and hover leave, nor
+ drag enter and drag leave events on behalf of its children.
+
+ A QGraphicsWidget with window decorations will accept hover events
+ regardless of the value of acceptHoverEvents().
+
+ \sa acceptHoverEvents(), hoverEnterEvent(), hoverMoveEvent(),
+ hoverLeaveEvent()
+*/
+void QGraphicsItem::setAcceptHoverEvents(bool enabled)
+{
+ if (d_ptr->acceptsHover == quint32(enabled))
+ return;
+ d_ptr->acceptsHover = quint32(enabled);
+ if (d_ptr->acceptsHover && d_ptr->scene && d_ptr->scene->d_func()->allItemsIgnoreHoverEvents) {
+ d_ptr->scene->d_func()->allItemsIgnoreHoverEvents = false;
+ d_ptr->scene->d_func()->enableMouseTrackingOnViews();
+ }
+}
+
+/*!
+ \obsolete
+
+ Use setAcceptHoverEvents(\a enabled) instead.
+*/
+void QGraphicsItem::setAcceptsHoverEvents(bool enabled)
+{
+ setAcceptHoverEvents(enabled);
+}
+
+/*! \since 4.6
+
+ Returns true if an item accepts \l{QTouchEvent}{touch events};
+ otherwise, returns false. By default, items do not accept touch events.
+
+ \sa setAcceptTouchEvents()
+*/
+bool QGraphicsItem::acceptTouchEvents() const
+{
+ return d_ptr->acceptTouchEvents;
+}
+
+/*!
+ \since 4.6
+
+ If \a enabled is true, this item will accept \l{QTouchEvent}{touch events};
+ otherwise, it will ignore them. By default, items do not accept
+ touch events.
+*/
+void QGraphicsItem::setAcceptTouchEvents(bool enabled)
+{
+ if (d_ptr->acceptTouchEvents == quint32(enabled))
+ return;
+ d_ptr->acceptTouchEvents = quint32(enabled);
+ if (d_ptr->acceptTouchEvents && d_ptr->scene && d_ptr->scene->d_func()->allItemsIgnoreTouchEvents) {
+ d_ptr->scene->d_func()->allItemsIgnoreTouchEvents = false;
+ d_ptr->scene->d_func()->enableTouchEventsOnViews();
+ }
+}
+
+/*!
+ \since 4.6
+
+ Returns true if this item filters child events (i.e., all events
+ intended for any of its children are instead sent to this item);
+ otherwise, false is returned.
+
+ The default value is false; child events are not filtered.
+
+ \sa setFiltersChildEvents()
+*/
+bool QGraphicsItem::filtersChildEvents() const
+{
+ return d_ptr->filtersDescendantEvents;
+}
+
+/*!
+ \since 4.6
+
+ If \a enabled is true, this item is set to filter all events for
+ all its children (i.e., all events intented for any of its
+ children are instead sent to this item); otherwise, if \a enabled
+ is false, this item will only handle its own events. The default
+ value is false.
+
+ \sa filtersChildEvents()
+*/
+void QGraphicsItem::setFiltersChildEvents(bool enabled)
+{
+ if (d_ptr->filtersDescendantEvents == enabled)
+ return;
+
+ d_ptr->filtersDescendantEvents = enabled;
+ d_ptr->updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-2));
+}
+
+/*!
+ \obsolete
+
+ Returns true if this item handles child events (i.e., all events
+ intended for any of its children are instead sent to this item);
+ otherwise, false is returned.
+
+ This property is useful for item groups; it allows one item to
+ handle events on behalf of its children, as opposed to its
+ children handling their events individually.
+
+ The default is to return false; children handle their own events.
+ The exception for this is if the item is a QGraphicsItemGroup, then
+ it defaults to return true.
+
+ \sa setHandlesChildEvents()
+*/
+bool QGraphicsItem::handlesChildEvents() const
+{
+ return d_ptr->handlesChildEvents;
+}
+
+/*!
+ \obsolete
+
+ If \a enabled is true, this item is set to handle all events for
+ all its children (i.e., all events intented for any of its
+ children are instead sent to this item); otherwise, if \a enabled
+ is false, this item will only handle its own events. The default
+ value is false.
+
+ This property is useful for item groups; it allows one item to
+ handle events on behalf of its children, as opposed to its
+ children handling their events individually.
+
+ If a child item accepts hover events, its parent will receive
+ hover move events as the cursor passes through the child, but it
+ does not receive hover enter and hover leave events on behalf of
+ its child.
+
+ \sa handlesChildEvents()
+*/
+void QGraphicsItem::setHandlesChildEvents(bool enabled)
+{
+ if (d_ptr->handlesChildEvents == enabled)
+ return;
+
+ d_ptr->handlesChildEvents = enabled;
+ d_ptr->updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-1));
+}
+/*!
+ \since 4.6
+ Returns true if this item is active; otherwise returns false.
+
+ An item can only be active if the scene is active. An item is active
+ if it is, or is a descendent of, an active panel. Items in non-active
+ panels are not active.
+
+ Items that are not part of a panel follow scene activation when the
+ scene has no active panel.
+
+ Only active items can gain input focus.
+
+ \sa QGraphicsScene::isActive(), QGraphicsScene::activePanel(), panel(), isPanel()
+*/
+bool QGraphicsItem::isActive() const
+{
+ if (!d_ptr->scene || !d_ptr->scene->isActive())
+ return false;
+ return panel() == d_ptr->scene->activePanel();
+}
+
+/*!
+ \since 4.6
+
+ If \a active is true, and the scene is active, this item's panel will be
+ activated. Otherwise, the panel is deactivated.
+
+ If the item is not part of an active scene, \a active will decide what
+ happens to the panel when the scene becomes active or the item is added to
+ the scene. If true, the item's panel will be activated when the item is
+ either added to the scene or the scene is activated. Otherwise, the item
+ will stay inactive independent of the scene's activated state.
+
+ \sa isPanel(), QGraphicsScene::setActivePanel(), QGraphicsScene::isActive()
+*/
+void QGraphicsItem::setActive(bool active)
+{
+ d_ptr->explicitActivate = 1;
+ d_ptr->wantsActive = active;
+ if (d_ptr->scene) {
+ if (active) {
+ // Activate this item.
+ d_ptr->scene->setActivePanel(this);
+ } else {
+ // Deactivate this item, and reactivate the last active item
+ // (if any).
+ QGraphicsItem *lastActive = d_ptr->scene->d_func()->lastActivePanel;
+ d_ptr->scene->setActivePanel(lastActive != this ? lastActive : 0);
+ }
+ }
+}
+
+/*!
+ Returns true if this item is active, and it or its \l{focusProxy()}{focus
+ proxy} has keyboard input focus; otherwise, returns false.
+
+ \sa focusItem(), setFocus(), QGraphicsScene::setFocusItem(), isActive()
+*/
+bool QGraphicsItem::hasFocus() const
+{
+ if (!d_ptr->scene || !d_ptr->scene->isActive())
+ return false;
+
+ if (d_ptr->focusProxy)
+ return d_ptr->focusProxy->hasFocus();
+
+ if (d_ptr->scene->d_func()->focusItem != this)
+ return false;
+
+ return panel() == d_ptr->scene->d_func()->activePanel;
+}
+
+/*!
+ Gives keyboard input focus to this item. The \a focusReason argument will
+ be passed into any \l{QFocusEvent}{focus event} generated by this function;
+ it is used to give an explanation of what caused the item to get focus.
+
+ Only enabled items that set the ItemIsFocusable flag can accept keyboard
+ focus.
+
+ If this item is not visible, not active, or not associated with a scene,
+ it will not gain immediate input focus. However, it will be registered as
+ the preferred focus item for its subtree of items, should it later become
+ visible.
+
+ As a result of calling this function, this item will receive a
+ \l{focusInEvent()}{focus in event} with \a focusReason. If another item
+ already has focus, that item will first receive a \l{focusOutEvent()}
+ {focus out event} indicating that it has lost input focus.
+
+ \sa clearFocus(), hasFocus(), focusItem(), focusProxy()
+*/
+void QGraphicsItem::setFocus(Qt::FocusReason focusReason)
+{
+ d_ptr->setFocusHelper(focusReason, /* climb = */ true, /* focusFromHide = */ false);
+}
+
+/*!
+ \internal
+*/
+void QGraphicsItemPrivate::setFocusHelper(Qt::FocusReason focusReason, bool climb, bool focusFromHide)
+{
+ // Disabled / unfocusable items cannot accept focus.
+ if (!q_ptr->isEnabled() || !(flags & QGraphicsItem::ItemIsFocusable))
+ return;
+
+ // Find focus proxy.
+ QGraphicsItem *f = q_ptr;
+ while (f->d_ptr->focusProxy)
+ f = f->d_ptr->focusProxy;
+
+ // Return if it already has focus.
+ if (scene && scene->focusItem() == f)
+ return;
+
+ // Update focus scope item ptr.
+ QGraphicsItem *p = parent;
+ while (p) {
+ if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
+ QGraphicsItem *oldFocusScopeItem = p->d_ptr->focusScopeItem;
+ p->d_ptr->focusScopeItem = q_ptr;
+ if (!p->focusItem() && !focusFromHide) {
+ if (oldFocusScopeItem)
+ oldFocusScopeItem->d_ptr->focusScopeItemChange(false);
+ focusScopeItemChange(true);
+ // If you call setFocus on a child of a focus scope that
+ // doesn't currently have a focus item, then stop.
+ return;
+ }
+ break;
+ }
+ p = p->d_ptr->parent;
+ }
+
+ if (climb) {
+ while (f->d_ptr->focusScopeItem && f->d_ptr->focusScopeItem->isVisible())
+ f = f->d_ptr->focusScopeItem;
+ }
+
+ // Update the child focus chain.
+ QGraphicsItem *commonAncestor = 0;
+ if (scene && scene->focusItem()) {
+ commonAncestor = scene->focusItem()->commonAncestorItem(f);
+ scene->focusItem()->d_ptr->clearSubFocus(scene->focusItem(), commonAncestor);
+ }
+
+ f->d_ptr->setSubFocus(f, commonAncestor);
+
+ // Update the scene's focus item.
+ if (scene) {
+ QGraphicsItem *p = q_ptr->panel();
+ if ((!p && scene->isActive()) || (p && p->isActive())) {
+ // Visible items immediately gain focus from scene.
+ scene->d_func()->setFocusItemHelper(f, focusReason);
+ }
+ }
+}
+
+/*!
+ Takes keyboard input focus from the item.
+
+ If it has focus, a \l{focusOutEvent()}{focus out event} is sent to this
+ item to tell it that it is about to lose the focus.
+
+ Only items that set the ItemIsFocusable flag, or widgets that set an
+ appropriate focus policy, can accept keyboard focus.
+
+ \sa setFocus(), hasFocus(), QGraphicsWidget::focusPolicy
+*/
+void QGraphicsItem::clearFocus()
+{
+ d_ptr->clearFocusHelper(/* giveFocusToParent = */ true);
+}
+
+/*!
+ \internal
+*/
+void QGraphicsItemPrivate::clearFocusHelper(bool giveFocusToParent)
+{
+ if (giveFocusToParent) {
+ // Pass focus to the closest parent focus scope
+ if (!inDestructor) {
+ QGraphicsItem *p = parent;
+ while (p) {
+ if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
+ if (p->d_ptr->focusScopeItem == q_ptr) {
+ p->d_ptr->focusScopeItem = 0;
+ if (!q_ptr->hasFocus()) //if it has focus, focusScopeItemChange is called elsewhere
+ focusScopeItemChange(false);
+ }
+ if (q_ptr->hasFocus())
+ p->d_ptr->setFocusHelper(Qt::OtherFocusReason, /* climb = */ false,
+ /* focusFromHide = */ false);
+ return;
+ }
+ p = p->d_ptr->parent;
+ }
+ }
+ }
+
+ if (q_ptr->hasFocus()) {
+ // Invisible items with focus must explicitly clear subfocus.
+ clearSubFocus(q_ptr);
+
+ // If this item has the scene's input focus, clear it.
+ scene->setFocusItem(0);
+ }
+}
+
+/*!
+ \since 4.6
+
+ Returns this item's focus proxy, or 0 if this item has no
+ focus proxy.
+
+ \sa setFocusProxy(), setFocus(), hasFocus()
+*/
+QGraphicsItem *QGraphicsItem::focusProxy() const
+{
+ return d_ptr->focusProxy;
+}
+
+/*!
+ \since 4.6
+
+ Sets the item's focus proxy to \a item.
+
+ If an item has a focus proxy, the focus proxy will receive
+ input focus when the item gains input focus. The item itself
+ will still have focus (i.e., hasFocus() will return true),
+ but only the focus proxy will receive the keyboard input.
+
+ A focus proxy can itself have a focus proxy, and so on. In
+ such case, keyboard input will be handled by the outermost
+ focus proxy.
+
+ The focus proxy \a item must belong to the same scene as
+ this item.
+
+ \sa focusProxy(), setFocus(), hasFocus()
+*/
+void QGraphicsItem::setFocusProxy(QGraphicsItem *item)
+{
+ if (item == d_ptr->focusProxy)
+ return;
+ if (item == this) {
+ qWarning("QGraphicsItem::setFocusProxy: cannot assign self as focus proxy");
+ return;
+ }
+ if (item) {
+ if (item->d_ptr->scene != d_ptr->scene) {
+ qWarning("QGraphicsItem::setFocusProxy: focus proxy must be in same scene");
+ return;
+ }
+ for (QGraphicsItem *f = item->focusProxy(); f != 0; f = f->focusProxy()) {
+ if (f == this) {
+ qWarning("QGraphicsItem::setFocusProxy: %p is already in the focus proxy chain", item);
+ return;
+ }
+ }
+ }
+
+ QGraphicsItem *lastFocusProxy = d_ptr->focusProxy;
+ if (lastFocusProxy)
+ lastFocusProxy->d_ptr->focusProxyRefs.removeOne(&d_ptr->focusProxy);
+ d_ptr->focusProxy = item;
+ if (item)
+ item->d_ptr->focusProxyRefs << &d_ptr->focusProxy;
+}
+
+/*!
+ \since 4.6
+
+ If this item, a child or descendant of this item currently has input
+ focus, this function will return a pointer to that item. If
+ no descendant has input focus, 0 is returned.
+
+ \sa hasFocus(), setFocus(), QWidget::focusWidget()
+*/
+QGraphicsItem *QGraphicsItem::focusItem() const
+{
+ return d_ptr->subFocusItem;
+}
+
+/*!
+ \internal
+
+ Returns this item's focus scope item.
+*/
+QGraphicsItem *QGraphicsItem::focusScopeItem() const
+{
+ return d_ptr->focusScopeItem;
+}
+
+/*!
+ \since 4.4
+ Grabs the mouse input.
+
+ This item will receive all mouse events for the scene until any of the
+ following events occurs:
+
+ \list
+ \o The item becomes invisible
+ \o The item is removed from the scene
+ \o The item is deleted
+ \o The item call ungrabMouse()
+ \o Another item calls grabMouse(); the item will regain the mouse grab
+ when the other item calls ungrabMouse().
+ \endlist
+
+ When an item gains the mouse grab, it receives a QEvent::GrabMouse
+ event. When it loses the mouse grab, it receives a QEvent::UngrabMouse
+ event. These events can be used to detect when your item gains or loses
+ the mouse grab through other means than receiving mouse button events.
+
+ It is almost never necessary to explicitly grab the mouse in Qt, as Qt
+ grabs and releases it sensibly. In particular, Qt grabs the mouse when you
+ press a mouse button, and keeps the mouse grabbed until you release the
+ last mouse button. Also, Qt::Popup widgets implicitly call grabMouse()
+ when shown, and ungrabMouse() when hidden.
+
+ Note that only visible items can grab mouse input. Calling grabMouse() on
+ an invisible item has no effect.
+
+ Keyboard events are not affected.
+
+ \sa QGraphicsScene::mouseGrabberItem(), ungrabMouse(), grabKeyboard()
+*/
+void QGraphicsItem::grabMouse()
+{
+ if (!d_ptr->scene) {
+ qWarning("QGraphicsItem::grabMouse: cannot grab mouse without scene");
+ return;
+ }
+ if (!d_ptr->visible) {
+ qWarning("QGraphicsItem::grabMouse: cannot grab mouse while invisible");
+ return;
+ }
+ d_ptr->scene->d_func()->grabMouse(this);
+}
+
+/*!
+ \since 4.4
+ Releases the mouse grab.
+
+ \sa grabMouse(), ungrabKeyboard()
+*/
+void QGraphicsItem::ungrabMouse()
+{
+ if (!d_ptr->scene) {
+ qWarning("QGraphicsItem::ungrabMouse: cannot ungrab mouse without scene");
+ return;
+ }
+ d_ptr->scene->d_func()->ungrabMouse(this);
+}
+
+/*!
+ \since 4.4
+ Grabs the keyboard input.
+
+ The item will receive all keyboard input to the scene until one of the
+ following events occur:
+
+ \list
+ \o The item becomes invisible
+ \o The item is removed from the scene
+ \o The item is deleted
+ \o The item calls ungrabKeyboard()
+ \o Another item calls grabKeyboard(); the item will regain the keyboard grab
+ when the other item calls ungrabKeyboard().
+ \endlist
+
+ When an item gains the keyboard grab, it receives a QEvent::GrabKeyboard
+ event. When it loses the keyboard grab, it receives a
+ QEvent::UngrabKeyboard event. These events can be used to detect when your
+ item gains or loses the keyboard grab through other means than gaining
+ input focus.
+
+ It is almost never necessary to explicitly grab the keyboard in Qt, as Qt
+ grabs and releases it sensibly. In particular, Qt grabs the keyboard when
+ your item gains input focus, and releases it when your item loses input
+ focus, or when the item is hidden.
+
+ Note that only visible items can grab keyboard input. Calling
+ grabKeyboard() on an invisible item has no effect.
+
+ Keyboard events are not affected.
+
+ \sa ungrabKeyboard(), grabMouse(), setFocus()
+*/
+void QGraphicsItem::grabKeyboard()
+{
+ if (!d_ptr->scene) {
+ qWarning("QGraphicsItem::grabKeyboard: cannot grab keyboard without scene");
+ return;
+ }
+ if (!d_ptr->visible) {
+ qWarning("QGraphicsItem::grabKeyboard: cannot grab keyboard while invisible");
+ return;
+ }
+ d_ptr->scene->d_func()->grabKeyboard(this);
+}
+
+/*!
+ \since 4.4
+ Releases the keyboard grab.
+
+ \sa grabKeyboard(), ungrabMouse()
+*/
+void QGraphicsItem::ungrabKeyboard()
+{
+ if (!d_ptr->scene) {
+ qWarning("QGraphicsItem::ungrabKeyboard: cannot ungrab keyboard without scene");
+ return;
+ }
+ d_ptr->scene->d_func()->ungrabKeyboard(this);
+}
+
+/*!
+ Returns the position of the item in parent coordinates. If the item has no
+ parent, its position is given in scene coordinates.
+
+ The position of the item describes its origin (local coordinate
+ (0, 0)) in parent coordinates; this function returns the same as
+ mapToParent(0, 0).
+
+ For convenience, you can also call scenePos() to determine the
+ item's position in scene coordinates, regardless of its parent.
+
+ \sa x(), y(), setPos(), transform(), {The Graphics View Coordinate System}
+*/
+QPointF QGraphicsItem::pos() const
+{
+ return d_ptr->pos;
+}
+
+/*!
+ \fn QGraphicsItem::x() const
+
+ This convenience function is equivalent to calling pos().x().
+
+ \sa y()
+*/
+
+/*!
+ \since 4.6
+
+ Set's the \a x coordinate of the item's position. Equivalent to
+ calling setPos(x, y()).
+
+ \sa x(), setPos()
+*/
+void QGraphicsItem::setX(qreal x)
+{
+ if (d_ptr->inDestructor)
+ return;
+
+ if (qIsNaN(x))
+ return;
+
+ setPos(QPointF(x, d_ptr->pos.y()));
+}
+
+/*!
+ \fn QGraphicsItem::y() const
+
+ This convenience function is equivalent to calling pos().y().
+
+ \sa x()
+*/
+
+/*!
+ \since 4.6
+
+ Set's the \a y coordinate of the item's position. Equivalent to
+ calling setPos(x(), y).
+
+ \sa x(), setPos()
+*/
+void QGraphicsItem::setY(qreal y)
+{
+ if (d_ptr->inDestructor)
+ return;
+
+ if (qIsNaN(y))
+ return;
+
+ setPos(QPointF(d_ptr->pos.x(), y));
+}
+
+/*!
+ Returns the item's position in scene coordinates. This is
+ equivalent to calling \c mapToScene(0, 0).
+
+ \sa pos(), sceneTransform(), {The Graphics View Coordinate System}
+*/
+QPointF QGraphicsItem::scenePos() const
+{
+ return mapToScene(0, 0);
+}
+
+/*!
+ \internal
+
+ Sets the position \a pos.
+*/
+void QGraphicsItemPrivate::setPosHelper(const QPointF &pos)
+{
+ Q_Q(QGraphicsItem);
+ inSetPosHelper = 1;
+ if (scene)
+ q->prepareGeometryChange();
+ QPointF oldPos = this->pos;
+ this->pos = pos;
+ dirtySceneTransform = 1;
+ inSetPosHelper = 0;
+ if (isObject) {
+ if (pos.x() != oldPos.x())
+ emit static_cast<QGraphicsObject *>(q_ptr)->xChanged();
+ if (pos.y() != oldPos.y())
+ emit static_cast<QGraphicsObject *>(q_ptr)->yChanged();
+ }
+}
+
+/*!
+ \internal
+
+ Sets the transform \a transform.
+*/
+void QGraphicsItemPrivate::setTransformHelper(const QTransform &transform)
+{
+ q_ptr->prepareGeometryChange();
+ transformData->transform = transform;
+ dirtySceneTransform = 1;
+ transformChanged();
+}
+
+/*!
+ Sets the position of the item to \a pos, which is in parent
+ coordinates. For items with no parent, \a pos is in scene
+ coordinates.
+
+ The position of the item describes its origin (local coordinate
+ (0, 0)) in parent coordinates.
+
+ \sa pos(), scenePos(), {The Graphics View Coordinate System}
+*/
+void QGraphicsItem::setPos(const QPointF &pos)
+{
+ if (d_ptr->pos == pos)
+ return;
+
+ if (d_ptr->inDestructor)
+ return;
+
+ // Update and repositition.
+ if (!(d_ptr->flags & (ItemSendsGeometryChanges | ItemSendsScenePositionChanges))) {
+ d_ptr->setPosHelper(pos);
+ if (d_ptr->isWidget)
+ static_cast<QGraphicsWidget *>(this)->d_func()->setGeometryFromSetPos();
+ if (d_ptr->scenePosDescendants)
+ d_ptr->sendScenePosChange();
+ return;
+ }
+
+ // Notify the item that the position is changing.
+ const QVariant newPosVariant(itemChange(ItemPositionChange, QVariant::fromValue<QPointF>(pos)));
+ QPointF newPos = newPosVariant.toPointF();
+ if (newPos == d_ptr->pos)
+ return;
+
+ // Update and repositition.
+ d_ptr->setPosHelper(newPos);
+
+ // Send post-notification.
+ itemChange(QGraphicsItem::ItemPositionHasChanged, newPosVariant);
+ d_ptr->sendScenePosChange();
+}
+
+/*!
+ \fn void QGraphicsItem::setPos(qreal x, qreal y)
+ \overload
+
+ This convenience function is equivalent to calling setPos(QPointF(\a x, \a
+ y)).
+*/
+
+/*!
+ \fn void QGraphicsItem::moveBy(qreal dx, qreal dy)
+
+ Moves the item by \a dx points horizontally, and \a dy point
+ vertically. This function is equivalent to calling setPos(pos() +
+ QPointF(\a dx, \a dy)).
+*/
+
+/*!
+ If this item is part of a scene that is viewed by a QGraphicsView, this
+ convenience function will attempt to scroll the view to ensure that \a
+ rect is visible inside the view's viewport. If \a rect is a null rect (the
+ default), QGraphicsItem will default to the item's bounding rect. \a xmargin
+ and \a ymargin are the number of pixels the view should use for margins.
+
+ If the specified rect cannot be reached, the contents are scrolled to the
+ nearest valid position.
+
+ If this item is not viewed by a QGraphicsView, this function does nothing.
+
+ \sa QGraphicsView::ensureVisible()
+*/
+void QGraphicsItem::ensureVisible(const QRectF &rect, int xmargin, int ymargin)
+{
+ if (d_ptr->scene) {
+ QRectF sceneRect;
+ if (!rect.isNull())
+ sceneRect = sceneTransform().mapRect(rect);
+ else
+ sceneRect = sceneBoundingRect();
+ foreach (QGraphicsView *view, d_ptr->scene->d_func()->views)
+ view->ensureVisible(sceneRect, xmargin, ymargin);
+ }
+}
+
+/*!
+ \fn void QGraphicsItem::ensureVisible(qreal x, qreal y, qreal w, qreal h,
+ int xmargin = 50, int ymargin = 50)
+
+ This convenience function is equivalent to calling
+ ensureVisible(QRectF(\a x, \a y, \a w, \a h), \a xmargin, \a ymargin):
+*/
+
+/*!
+ \obsolete
+
+ Returns the item's affine transformation matrix. This is a subset or the
+ item's full transformation matrix, and might not represent the item's full
+ transformation.
+
+ Use transform() instead.
+
+ \sa setTransform(), sceneTransform()
+*/
+QMatrix QGraphicsItem::matrix() const
+{
+ return transform().toAffine();
+}
+
+/*!
+ \since 4.3
+
+ Returns this item's transformation matrix.
+
+ The transformation matrix is combined with the item's rotation(), scale()
+ and transformations() into a combined transformations for the item.
+
+ The default transformation matrix is an identity matrix.
+
+ \sa setTransform(), sceneTransform()
+*/
+QTransform QGraphicsItem::transform() const
+{
+ if (!d_ptr->transformData)
+ return QTransform();
+ return d_ptr->transformData->transform;
+}
+
+/*!
+ \since 4.6
+
+ Returns the clockwise rotation, in degrees, around the Z axis. The default
+ value is 0 (i.e., the item is not rotated).
+
+ The rotation is combined with the item's scale(), transform() and
+ transformations() to map the item's coordinate system to the parent item.
+
+ \sa setRotation(), transformOriginPoint(), {Transformations}
+*/
+qreal QGraphicsItem::rotation() const
+{
+ if (!d_ptr->transformData)
+ return 0;
+ return d_ptr->transformData->rotation;
+}
+
+/*!
+ \since 4.6
+
+ Sets the clockwise rotation \a angle, in degrees, around the Z axis. The
+ default value is 0 (i.e., the item is not rotated). Assigning a negative
+ value will rotate the item counter-clockwise. Normally the rotation angle
+ is in the range (-360, 360), but it's also possible to assign values
+ outside of this range (e.g., a rotation of 370 degrees is the same as a
+ rotation of 10 degrees).
+
+ The item is rotated around its transform origin point, which by default
+ is (0, 0). You can select a different transformation origin by calling
+ setTransformOriginPoint().
+
+ The rotation is combined with the item's scale(), transform() and
+ transformations() to map the item's coordinate system to the parent item.
+
+ \sa rotation(), setTransformOriginPoint(), {Transformations}
+*/
+void QGraphicsItem::setRotation(qreal angle)
+{
+ prepareGeometryChange();
+ qreal newRotation = angle;
+
+ if (d_ptr->flags & ItemSendsGeometryChanges) {
+ // Notify the item that the rotation is changing.
+ const QVariant newRotationVariant(itemChange(ItemRotationChange, angle));
+ newRotation = newRotationVariant.toReal();
+ }
+
+ if (!d_ptr->transformData)
+ d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
+
+ if (d_ptr->transformData->rotation == newRotation)
+ return;
+
+ d_ptr->transformData->rotation = newRotation;
+ d_ptr->transformData->onlyTransform = false;
+ d_ptr->dirtySceneTransform = 1;
+
+ // Send post-notification.
+ if (d_ptr->flags & ItemSendsGeometryChanges)
+ itemChange(ItemRotationHasChanged, newRotation);
+
+ if (d_ptr->isObject)
+ emit static_cast<QGraphicsObject *>(this)->rotationChanged();
+
+ d_ptr->transformChanged();
+}
+
+/*!
+ \since 4.6
+
+ Returns the scale factor of the item. The default scale factor is 1.0
+ (i.e., the item is not scaled).
+
+ The scale is combined with the item's rotation(), transform() and
+ transformations() to map the item's coordinate system to the parent item.
+
+ \sa setScale(), rotation(), {Transformations}
+*/
+qreal QGraphicsItem::scale() const
+{
+ if (!d_ptr->transformData)
+ return 1.;
+ return d_ptr->transformData->scale;
+}
+
+/*!
+ \since 4.6
+
+ Sets the scale \a factor of the item. The default scale factor is 1.0
+ (i.e., the item is not scaled). A scale factor of 0.0 will collapse the
+ item to a single point. If you provide a negative scale factor, the
+ item will be flipped and mirrored (i.e., rotated 180 degrees).
+
+ The item is scaled around its transform origin point, which by default
+ is (0, 0). You can select a different transformation origin by calling
+ setTransformOriginPoint().
+
+ The scale is combined with the item's rotation(), transform() and
+ transformations() to map the item's coordinate system to the parent item.
+
+ \sa scale(), setTransformOriginPoint(), {Transformations Example}
+*/
+void QGraphicsItem::setScale(qreal factor)
+{
+ prepareGeometryChange();
+ qreal newScale = factor;
+
+ if (d_ptr->flags & ItemSendsGeometryChanges) {
+ // Notify the item that the scale is changing.
+ const QVariant newScaleVariant(itemChange(ItemScaleChange, factor));
+ newScale = newScaleVariant.toReal();
+ }
+
+ if (!d_ptr->transformData)
+ d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
+
+ if (d_ptr->transformData->scale == newScale)
+ return;
+
+ d_ptr->transformData->scale = newScale;
+ d_ptr->transformData->onlyTransform = false;
+ d_ptr->dirtySceneTransform = 1;
+
+ // Send post-notification.
+ if (d_ptr->flags & ItemSendsGeometryChanges)
+ itemChange(ItemScaleHasChanged, newScale);
+
+ if (d_ptr->isObject)
+ emit static_cast<QGraphicsObject *>(this)->scaleChanged();
+
+ d_ptr->transformChanged();
+}
+
+
+/*!
+ \since 4.6
+
+ Returns a list of graphics transforms that currently apply to this item.
+
+ QGraphicsTransform is for applying and controlling a chain of individual
+ transformation operations on an item. It's particularly useful in
+ animations, where each transform operation needs to be interpolated
+ independently, or differently.
+
+ The transformations are combined with the item's rotation(), scale() and
+ transform() to map the item's coordinate system to the parent item.
+
+ \sa scale(), rotation(), transformOriginPoint(), {Transformations}
+*/
+QList<QGraphicsTransform *> QGraphicsItem::transformations() const
+{
+ if (!d_ptr->transformData)
+ return QList<QGraphicsTransform *>();
+ return d_ptr->transformData->graphicsTransforms;
+}
+
+/*!
+ \since 4.6
+
+ Sets a list of graphics \a transformations (QGraphicsTransform) that
+ currently apply to this item.
+
+ If all you want is to rotate or scale an item, you should call setRotation()
+ or setScale() instead. If you want to set an arbitrary transformation on
+ an item, you can call setTransform().
+
+ QGraphicsTransform is for applying and controlling a chain of individual
+ transformation operations on an item. It's particularly useful in
+ animations, where each transform operation needs to be interpolated
+ independently, or differently.
+
+ The transformations are combined with the item's rotation(), scale() and
+ transform() to map the item's coordinate system to the parent item.
+
+ \sa scale(), setTransformOriginPoint(), {Transformations}
+*/
+void QGraphicsItem::setTransformations(const QList<QGraphicsTransform *> &transformations)
+{
+ prepareGeometryChange();
+ if (!d_ptr->transformData)
+ d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
+ d_ptr->transformData->graphicsTransforms = transformations;
+ for (int i = 0; i < transformations.size(); ++i)
+ transformations.at(i)->d_func()->setItem(this);
+ d_ptr->transformData->onlyTransform = false;
+ d_ptr->dirtySceneTransform = 1;
+ d_ptr->transformChanged();
+}
+
+/*!
+ \internal
+*/
+void QGraphicsItemPrivate::prependGraphicsTransform(QGraphicsTransform *t)
+{
+ if (!transformData)
+ transformData = new QGraphicsItemPrivate::TransformData;
+ if (!transformData->graphicsTransforms.contains(t))
+ transformData->graphicsTransforms.prepend(t);
+
+ Q_Q(QGraphicsItem);
+ t->d_func()->setItem(q);
+ transformData->onlyTransform = false;
+ dirtySceneTransform = 1;
+ transformChanged();
+}
+
+/*!
+ \internal
+*/
+void QGraphicsItemPrivate::appendGraphicsTransform(QGraphicsTransform *t)
+{
+ if (!transformData)
+ transformData = new QGraphicsItemPrivate::TransformData;
+ if (!transformData->graphicsTransforms.contains(t))
+ transformData->graphicsTransforms.append(t);
+
+ Q_Q(QGraphicsItem);
+ t->d_func()->setItem(q);
+ transformData->onlyTransform = false;
+ dirtySceneTransform = 1;
+ transformChanged();
+}
+
+/*!
+ \since 4.6
+
+ Returns the origin point for the transformation in item coordinates.
+
+ The default is QPointF(0,0).
+
+ \sa setTransformOriginPoint(), {Transformations}
+*/
+QPointF QGraphicsItem::transformOriginPoint() const
+{
+ if (!d_ptr->transformData)
+ return QPointF(0,0);
+ return QPointF(d_ptr->transformData->xOrigin, d_ptr->transformData->yOrigin);
+}
+
+/*!
+ \since 4.6
+
+ Sets the \a origin point for the transformation in item coordinates.
+
+ \sa transformOriginPoint(), {Transformations}
+*/
+void QGraphicsItem::setTransformOriginPoint(const QPointF &origin)
+{
+ prepareGeometryChange();
+ QPointF newOrigin = origin;
+
+ if (d_ptr->flags & ItemSendsGeometryChanges) {
+ // Notify the item that the origin point is changing.
+ const QVariant newOriginVariant(itemChange(ItemTransformOriginPointChange,
+ QVariant::fromValue<QPointF>(origin)));
+ newOrigin = newOriginVariant.toPointF();
+ }
+
+ if (!d_ptr->transformData)
+ d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
+
+ if (d_ptr->transformData->xOrigin == newOrigin.x()
+ && d_ptr->transformData->yOrigin == newOrigin.y()) {
+ return;
+ }
+
+ d_ptr->transformData->xOrigin = newOrigin.x();
+ d_ptr->transformData->yOrigin = newOrigin.y();
+ d_ptr->transformData->onlyTransform = false;
+ d_ptr->dirtySceneTransform = 1;
+
+ // Send post-notification.
+ if (d_ptr->flags & ItemSendsGeometryChanges)
+ itemChange(ItemTransformOriginPointHasChanged, QVariant::fromValue<QPointF>(newOrigin));
+}
+
+/*!
+ \fn void QGraphicsItem::setTransformOriginPoint(qreal x, qreal y)
+
+ \since 4.6
+ \overload
+
+ Sets the origin point for the transformation in item coordinates.
+ This is equivalent to calling setTransformOriginPoint(QPointF(\a x, \a y)).
+
+ \sa setTransformOriginPoint(), {Transformations}
+*/
+
+
+/*!
+ \obsolete
+
+ Use sceneTransform() instead.
+
+ \sa transform(), setTransform(), scenePos(), {The Graphics View Coordinate System}
+*/
+QMatrix QGraphicsItem::sceneMatrix() const
+{
+ d_ptr->ensureSceneTransform();
+ return d_ptr->sceneTransform.toAffine();
+}
+
+
+/*!
+ \since 4.3
+
+ Returns this item's scene transformation matrix. This matrix can be used
+ to map coordinates and geometrical shapes from this item's local
+ coordinate system to the scene's coordinate system. To map coordinates
+ from the scene, you must first invert the returned matrix.
+
+ Example:
+
+ \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 4
+
+ Unlike transform(), which returns only an item's local transformation, this
+ function includes the item's (and any parents') position, and all the transfomation properties.
+
+ \sa transform(), setTransform(), scenePos(), {The Graphics View Coordinate System}, {Transformations}
+*/
+QTransform QGraphicsItem::sceneTransform() const
+{
+ d_ptr->ensureSceneTransform();
+ return d_ptr->sceneTransform;
+}
+
+/*!
+ \since 4.3
+
+ Returns this item's device transformation matrix, using \a
+ viewportTransform to map from scene to device coordinates. This matrix can
+ be used to map coordinates and geometrical shapes from this item's local
+ coordinate system to the viewport's (or any device's) coordinate
+ system. To map coordinates from the viewport, you must first invert the
+ returned matrix.
+
+ Example:
+
+ \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 5
+
+ This function is the same as combining this item's scene transform with
+ the view's viewport transform, but it also understands the
+ ItemIgnoresTransformations flag. The device transform can be used to do
+ accurate coordinate mapping (and collision detection) for untransformable
+ items.
+
+ \sa transform(), setTransform(), scenePos(), {The Graphics View Coordinate
+ System}, itemTransform()
+*/
+QTransform QGraphicsItem::deviceTransform(const QTransform &viewportTransform) const
+{
+ // Ensure we return the standard transform if we're not untransformable.
+ if (!d_ptr->itemIsUntransformable()) {
+ d_ptr->ensureSceneTransform();
+ return d_ptr->sceneTransform * viewportTransform;
+ }
+
+ // Find the topmost item that ignores view transformations.
+ const QGraphicsItem *untransformedAncestor = this;
+ QList<const QGraphicsItem *> parents;
+ while (untransformedAncestor && ((untransformedAncestor->d_ptr->ancestorFlags
+ & QGraphicsItemPrivate::AncestorIgnoresTransformations))) {
+ parents.prepend(untransformedAncestor);
+ untransformedAncestor = untransformedAncestor->parentItem();
+ }
+
+ if (!untransformedAncestor) {
+ // Assert in debug mode, continue in release.
+ Q_ASSERT_X(untransformedAncestor, "QGraphicsItem::deviceTransform",
+ "Invalid object structure!");
+ return QTransform();
+ }
+
+ // First translate the base untransformable item.
+ untransformedAncestor->d_ptr->ensureSceneTransform();
+ QPointF mappedPoint = (untransformedAncestor->d_ptr->sceneTransform * viewportTransform).map(QPointF(0, 0));
+
+ // COMBINE
+ QTransform matrix = QTransform::fromTranslate(mappedPoint.x(), mappedPoint.y());
+ if (untransformedAncestor->d_ptr->transformData)
+ matrix = untransformedAncestor->d_ptr->transformData->computedFullTransform(&matrix);
+
+ // Then transform and translate all children.
+ for (int i = 0; i < parents.size(); ++i) {
+ const QGraphicsItem *parent = parents.at(i);
+ parent->d_ptr->combineTransformFromParent(&matrix);
+ }
+
+ return matrix;
+}
+
+/*!
+ \since 4.5
+
+ Returns a QTransform that maps coordinates from this item to \a other. If
+ \a ok is not null, and if there is no such transform, the boolean pointed
+ to by \a ok will be set to false; otherwise it will be set to true.
+
+ This transform provides an alternative to the mapToItem() or mapFromItem()
+ functions, by returning the appropriate transform so that you can map
+ shapes and coordinates yourself. It also helps you write more efficient
+ code when repeatedly mapping between the same two items.
+
+ \note In rare circumstances, there is no transform that maps between two
+ items.
+
+ \sa mapToItem(), mapFromItem(), deviceTransform()
+*/
+QTransform QGraphicsItem::itemTransform(const QGraphicsItem *other, bool *ok) const
+{
+ // Catch simple cases first.
+ if (other == 0) {
+ qWarning("QGraphicsItem::itemTransform: null pointer passed");
+ return QTransform();
+ }
+ if (other == this) {
+ if (ok)
+ *ok = true;
+ return QTransform();
+ }
+
+ QGraphicsItem *parent = d_ptr->parent;
+ const QGraphicsItem *otherParent = other->d_ptr->parent;
+
+ // This is other's child
+ if (parent == other) {
+ if (ok)
+ *ok = true;
+ QTransform x;
+ d_ptr->combineTransformFromParent(&x);
+ return x;
+ }
+
+ // This is other's parent
+ if (otherParent == this) {
+ const QPointF &otherPos = other->d_ptr->pos;
+ if (other->d_ptr->transformData) {
+ QTransform otherToParent;
+ other->d_ptr->combineTransformFromParent(&otherToParent);
+ return otherToParent.inverted(ok);
+ }
+ if (ok)
+ *ok = true;
+ return QTransform::fromTranslate(-otherPos.x(), -otherPos.y());
+ }
+
+ // Siblings
+ if (parent == otherParent) {
+ // COMBINE
+ const QPointF &itemPos = d_ptr->pos;
+ const QPointF &otherPos = other->d_ptr->pos;
+ if (!d_ptr->transformData && !other->d_ptr->transformData) {
+ QPointF delta = itemPos - otherPos;
+ if (ok)
+ *ok = true;
+ return QTransform::fromTranslate(delta.x(), delta.y());
+ }
+
+ QTransform itemToParent;
+ d_ptr->combineTransformFromParent(&itemToParent);
+ QTransform otherToParent;
+ other->d_ptr->combineTransformFromParent(&otherToParent);
+ return itemToParent * otherToParent.inverted(ok);
+ }
+
+ // Find the closest common ancestor. If the two items don't share an
+ // ancestor, then the only way is to combine their scene transforms.
+ const QGraphicsItem *commonAncestor = commonAncestorItem(other);
+ if (!commonAncestor) {
+ d_ptr->ensureSceneTransform();
+ other->d_ptr->ensureSceneTransform();
+ return d_ptr->sceneTransform * other->d_ptr->sceneTransform.inverted(ok);
+ }
+
+ // If the two items are cousins (in sibling branches), map both to the
+ // common ancestor, and combine the two transforms.
+ bool cousins = other != commonAncestor && this != commonAncestor;
+ if (cousins) {
+ bool good = false;
+ QTransform thisToScene = itemTransform(commonAncestor, &good);
+ QTransform otherToScene(Qt::Uninitialized);
+ if (good)
+ otherToScene = other->itemTransform(commonAncestor, &good);
+ if (!good) {
+ if (ok)
+ *ok = false;
+ return QTransform();
+ }
+ return thisToScene * otherToScene.inverted(ok);
+ }
+
+ // One is an ancestor of the other; walk the chain.
+ bool parentOfOther = isAncestorOf(other);
+ const QGraphicsItem *child = parentOfOther ? other : this;
+ const QGraphicsItem *root = parentOfOther ? this : other;
+
+ QTransform x;
+ const QGraphicsItem *p = child;
+ do {
+ p->d_ptr.data()->combineTransformToParent(&x);
+ } while ((p = p->d_ptr->parent) && p != root);
+ if (parentOfOther)
+ return x.inverted(ok);
+ if (ok)
+ *ok = true;
+ return x;
+}
+
+/*!
+ \obsolete
+
+ Sets the item's affine transformation matrix. This is a subset or the
+ item's full transformation matrix, and might not represent the item's full
+ transformation.
+
+ Use setTransform() instead.
+
+ \sa transform(), {The Graphics View Coordinate System}
+*/
+void QGraphicsItem::setMatrix(const QMatrix &matrix, bool combine)
+{
+ if (!d_ptr->transformData)
+ d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
+
+ QTransform newTransform(combine ? QTransform(matrix) * d_ptr->transformData->transform : QTransform(matrix));
+ if (d_ptr->transformData->transform == newTransform)
+ return;
+
+ // Update and set the new transformation.
+ if (!(d_ptr->flags & ItemSendsGeometryChanges)) {
+ d_ptr->setTransformHelper(newTransform);
+ return;
+ }
+
+ // Notify the item that the transformation matrix is changing.
+ const QVariant newMatrixVariant = QVariant::fromValue<QMatrix>(newTransform.toAffine());
+ newTransform = QTransform(qvariant_cast<QMatrix>(itemChange(ItemMatrixChange, newMatrixVariant)));
+ if (d_ptr->transformData->transform == newTransform)
+ return;
+
+ // Update and set the new transformation.
+ d_ptr->setTransformHelper(newTransform);
+
+ // Send post-notification.
+ itemChange(ItemTransformHasChanged, QVariant::fromValue<QTransform>(newTransform));
+}
+
+/*!
+ \since 4.3
+
+ Sets the item's current transformation matrix to \a matrix.
+
+ If \a combine is true, then \a matrix is combined with the current matrix;
+ otherwise, \a matrix \e replaces the current matrix. \a combine is false
+ by default.
+
+ To simplify interation with items using a transformed view, QGraphicsItem
+ provides mapTo... and mapFrom... functions that can translate between
+ items' and the scene's coordinates. For example, you can call mapToScene()
+ to map an item coordiate to a scene coordinate, or mapFromScene() to map
+ from scene coordinates to item coordinates.
+
+ The transformation matrix is combined with the item's rotation(), scale()
+ and transformations() into a combined transformation that maps the item's
+ coordinate system to its parent.
+
+ \sa transform(), setRotation(), setScale(), setTransformOriginPoint(), {The Graphics View Coordinate System}, {Transformations}
+*/
+void QGraphicsItem::setTransform(const QTransform &matrix, bool combine)
+{
+ if (!d_ptr->transformData)
+ d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
+
+ QTransform newTransform(combine ? matrix * d_ptr->transformData->transform : matrix);
+ if (d_ptr->transformData->transform == newTransform)
+ return;
+
+ // Update and set the new transformation.
+ if (!(d_ptr->flags & (ItemSendsGeometryChanges | ItemSendsScenePositionChanges))) {
+ d_ptr->setTransformHelper(newTransform);
+ if (d_ptr->scenePosDescendants)
+ d_ptr->sendScenePosChange();
+ return;
+ }
+
+ // Notify the item that the transformation matrix is changing.
+ const QVariant newTransformVariant(itemChange(ItemTransformChange,
+ QVariant::fromValue<QTransform>(newTransform)));
+ newTransform = qvariant_cast<QTransform>(newTransformVariant);
+ if (d_ptr->transformData->transform == newTransform)
+ return;
+
+ // Update and set the new transformation.
+ d_ptr->setTransformHelper(newTransform);
+
+ // Send post-notification.
+ itemChange(ItemTransformHasChanged, newTransformVariant);
+ d_ptr->sendScenePosChange();
+}
+
+/*!
+ \obsolete
+
+ Use resetTransform() instead.
+*/
+void QGraphicsItem::resetMatrix()
+{
+ resetTransform();
+}
+
+/*!
+ \since 4.3
+
+ Resets this item's transformation matrix to the identity matrix or
+ all the transformation properties to their default values.
+ This is equivalent to calling \c setTransform(QTransform()).
+
+ \sa setTransform(), transform()
+*/
+void QGraphicsItem::resetTransform()
+{
+ setTransform(QTransform(), false);
+}
+
+/*!
+ \obsolete
+
+ Use
+
+ \code
+ setRotation(rotation() + angle);
+ \endcode
+
+ instead.
+
+ Rotates the current item transformation \a angle degrees clockwise around
+ its origin. To translate around an arbitrary point (x, y), you need to
+ combine translation and rotation with setTransform().
+
+ Example:
+
+ \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 6
+
+ \sa setTransform(), transform(), scale(), shear(), translate()
+*/
+void QGraphicsItem::rotate(qreal angle)
+{
+ setTransform(QTransform().rotate(angle), true);
+}
+
+/*!
+ \obsolete
+
+ Use
+
+ \code
+ setTransform(QTransform::fromScale(sx, sy), true);
+ \endcode
+
+ instead.
+
+ Scales the current item transformation by (\a sx, \a sy) around its
+ origin. To scale from an arbitrary point (x, y), you need to combine
+ translation and scaling with setTransform().
+
+ Example:
+
+ \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 7
+
+ \sa setTransform(), transform()
+*/
+void QGraphicsItem::scale(qreal sx, qreal sy)
+{
+ setTransform(QTransform::fromScale(sx, sy), true);
+}
+
+/*!
+ \obsolete
+
+ Use
+
+ \code
+ setTransform(QTransform().shear(sh, sv), true);
+ \endcode
+
+ instead.
+
+ Shears the current item transformation by (\a sh, \a sv).
+
+ \sa setTransform(), transform()
+*/
+void QGraphicsItem::shear(qreal sh, qreal sv)
+{
+ setTransform(QTransform().shear(sh, sv), true);
+}
+
+/*!
+ \obsolete
+
+ Use setPos() or setTransformOriginPoint() instead. For identical
+ behavior, use
+
+ \code
+ setTransform(QTransform::fromTranslate(dx, dy), true);
+ \endcode
+
+ Translates the current item transformation by (\a dx, \a dy).
+
+ If all you want is to move an item, you should call moveBy() or
+ setPos() instead; this function changes the item's translation,
+ which is conceptually separate from its position.
+
+ \sa setTransform(), transform()
+*/
+void QGraphicsItem::translate(qreal dx, qreal dy)
+{
+ setTransform(QTransform::fromTranslate(dx, dy), true);
+}
+
+/*!
+ This virtual function is called twice for all items by the
+ QGraphicsScene::advance() slot. In the first phase, all items are called
+ with \a phase == 0, indicating that items on the scene are about to
+ advance, and then all items are called with \a phase == 1. Reimplement
+ this function to update your item if you need simple scene-controlled
+ animation.
+
+ The default implementation does nothing.
+
+ For individual item animation, an alternative to this function is to
+ either use QGraphicsItemAnimation, or to multiple-inherit from QObject and
+ QGraphicsItem, and animate your item using QObject::startTimer() and
+ QObject::timerEvent().
+
+ \sa QGraphicsItemAnimation, QTimeLine
+*/
+void QGraphicsItem::advance(int phase)
+{
+ Q_UNUSED(phase);
+}
+
+/*!
+ Returns the Z-value of the item. The Z-value affects the stacking order of
+ sibling (neighboring) items.
+
+ The default Z-value is 0.
+
+ \sa setZValue(), {QGraphicsItem#Sorting}{Sorting}, stackBefore(), ItemStacksBehindParent
+*/
+qreal QGraphicsItem::zValue() const
+{
+ return d_ptr->z;
+}
+
+/*!
+ Sets the Z-value of the item to \a z. The Z value decides the stacking
+ order of sibling (neighboring) items. A sibling item of high Z value will
+ always be drawn on top of another sibling item with a lower Z value.
+
+ If you restore the Z value, the item's insertion order will decide its
+ stacking order.
+
+ The Z-value does not affect the item's size in any way.
+
+ The default Z-value is 0.
+
+ \sa zValue(), {QGraphicsItem#Sorting}{Sorting}, stackBefore(), ItemStacksBehindParent
+*/
+void QGraphicsItem::setZValue(qreal z)
+{
+ const QVariant newZVariant(itemChange(ItemZValueChange, z));
+ qreal newZ = newZVariant.toReal();
+ if (newZ == d_ptr->z)
+ return;
+
+ if (d_ptr->scene && d_ptr->scene->d_func()->indexMethod != QGraphicsScene::NoIndex) {
+ // Z Value has changed, we have to notify the index.
+ d_ptr->scene->d_func()->index->itemChange(this, ItemZValueChange, &newZ);
+ }
+
+ d_ptr->z = newZ;
+ if (d_ptr->parent)
+ d_ptr->parent->d_ptr->needSortChildren = 1;
+ else if (d_ptr->scene)
+ d_ptr->scene->d_func()->needSortTopLevelItems = 1;
+
+ if (d_ptr->scene)
+ d_ptr->scene->d_func()->markDirty(this, QRectF(), /*invalidateChildren=*/true);
+
+ itemChange(ItemZValueHasChanged, newZVariant);
+
+ if (d_ptr->flags & ItemNegativeZStacksBehindParent)
+ setFlag(QGraphicsItem::ItemStacksBehindParent, z < qreal(0.0));
+
+ if (d_ptr->isObject)
+ emit static_cast<QGraphicsObject *>(this)->zChanged();
+}
+
+/*!
+ \internal
+
+ Ensures that the list of children is sorted by insertion order, and that
+ the siblingIndexes are packed (no gaps), and start at 0.
+
+ ### This function is almost identical to
+ QGraphicsScenePrivate::ensureSequentialTopLevelSiblingIndexes().
+*/
+void QGraphicsItemPrivate::ensureSequentialSiblingIndex()
+{
+ if (!sequentialOrdering) {
+ qSort(children.begin(), children.end(), insertionOrder);
+ sequentialOrdering = 1;
+ needSortChildren = 1;
+ }
+ if (holesInSiblingIndex) {
+ holesInSiblingIndex = 0;
+ for (int i = 0; i < children.size(); ++i)
+ children[i]->d_ptr->siblingIndex = i;
+ }
+}
+
+/*!
+ \internal
+*/
+inline void QGraphicsItemPrivate::sendScenePosChange()
+{
+ Q_Q(QGraphicsItem);
+ if (scene) {
+ if (flags & QGraphicsItem::ItemSendsScenePositionChanges)
+ q->itemChange(QGraphicsItem::ItemScenePositionHasChanged, q->scenePos());
+ if (scenePosDescendants) {
+ foreach (QGraphicsItem *item, scene->d_func()->scenePosItems) {
+ if (q->isAncestorOf(item))
+ item->itemChange(QGraphicsItem::ItemScenePositionHasChanged, item->scenePos());
+ }
+ }
+ }
+}
+
+/*!
+ \since 4.6
+
+ Stacks this item before \a sibling, which must be a sibling item (i.e., the
+ two items must share the same parent item, or must both be toplevel items).
+ The \a sibling must have the same Z value as this item, otherwise calling
+ this function will have no effect.
+
+ By default, all sibling items are stacked by insertion order (i.e., the
+ first item you add is drawn before the next item you add). If two items' Z
+ values are different, then the item with the highest Z value is drawn on
+ top. When the Z values are the same, the insertion order will decide the
+ stacking order.
+
+ \sa setZValue(), ItemStacksBehindParent, {QGraphicsItem#Sorting}{Sorting}
+*/
+void QGraphicsItem::stackBefore(const QGraphicsItem *sibling)
+{
+ if (sibling == this)
+ return;
+ if (!sibling || d_ptr->parent != sibling->parentItem()) {
+ qWarning("QGraphicsItem::stackUnder: cannot stack under %p, which must be a sibling", sibling);
+ return;
+ }
+ QList<QGraphicsItem *> *siblings = d_ptr->parent
+ ? &d_ptr->parent->d_ptr->children
+ : (d_ptr->scene ? &d_ptr->scene->d_func()->topLevelItems : 0);
+ if (!siblings) {
+ qWarning("QGraphicsItem::stackUnder: cannot stack under %p, which must be a sibling", sibling);
+ return;
+ }
+
+ // First, make sure that the sibling indexes have no holes. This also
+ // marks the children list for sorting.
+ if (d_ptr->parent)
+ d_ptr->parent->d_ptr->ensureSequentialSiblingIndex();
+ else
+ d_ptr->scene->d_func()->ensureSequentialTopLevelSiblingIndexes();
+
+ // Only move items with the same Z value, and that need moving.
+ int siblingIndex = sibling->d_ptr->siblingIndex;
+ int myIndex = d_ptr->siblingIndex;
+ if (myIndex >= siblingIndex) {
+ siblings->move(myIndex, siblingIndex);
+ // Fixup the insertion ordering.
+ for (int i = 0; i < siblings->size(); ++i) {
+ int &index = siblings->at(i)->d_ptr->siblingIndex;
+ if (i != siblingIndex && index >= siblingIndex && index <= myIndex)
+ ++index;
+ }
+ d_ptr->siblingIndex = siblingIndex;
+ for (int i = 0; i < siblings->size(); ++i) {
+ int &index = siblings->at(i)->d_ptr->siblingIndex;
+ if (i != siblingIndex && index >= siblingIndex && index <= myIndex)
+ siblings->at(i)->d_ptr->siblingOrderChange();
+ }
+ d_ptr->siblingOrderChange();
+ }
+}
+
+/*!
+ Returns the bounding rect of this item's descendants (i.e., its
+ children, their children, etc.) in local coordinates. The
+ rectangle will contain all descendants after they have been mapped
+ to local coordinates. If the item has no children, this function
+ returns an empty QRectF.
+
+ This does not include this item's own bounding rect; it only returns
+ its descendants' accumulated bounding rect. If you need to include this
+ item's bounding rect, you can add boundingRect() to childrenBoundingRect()
+ using QRectF::operator|().
+
+ This function is linear in complexity; it determines the size of the
+ returned bounding rect by iterating through all descendants.
+
+ \sa boundingRect(), sceneBoundingRect()
+*/
+QRectF QGraphicsItem::childrenBoundingRect() const
+{
+ if (!d_ptr->dirtyChildrenBoundingRect)
+ return d_ptr->childrenBoundingRect;
+
+ d_ptr->childrenBoundingRect = QRectF();
+ d_ptr->childrenBoundingRectHelper(0, &d_ptr->childrenBoundingRect, 0);
+ d_ptr->dirtyChildrenBoundingRect = 0;
+ return d_ptr->childrenBoundingRect;
+}
+
+/*!
+ \fn virtual QRectF QGraphicsItem::boundingRect() const = 0
+
+ This pure virtual function defines the outer bounds of the item as
+ a rectangle; all painting must be restricted to inside an item's
+ bounding rect. QGraphicsView uses this to determine whether the
+ item requires redrawing.
+
+ Although the item's shape can be arbitrary, the bounding rect is
+ always rectangular, and it is unaffected by the items'
+ transformation.
+
+ If you want to change the item's bounding rectangle, you must first call
+ prepareGeometryChange(). This notifies the scene of the imminent change,
+ so that its can update its item geometry index; otherwise, the scene will
+ be unaware of the item's new geometry, and the results are undefined
+ (typically, rendering artifacts are left around in the view).
+
+ Reimplement this function to let QGraphicsView determine what
+ parts of the widget, if any, need to be redrawn.
+
+ Note: For shapes that paint an outline / stroke, it is important
+ to include half the pen width in the bounding rect. It is not
+ necessary to compensate for antialiasing, though.
+
+ Example:
+
+ \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 8
+
+ \sa boundingRegion(), shape(), contains(), {The Graphics View Coordinate
+ System}, prepareGeometryChange()
+*/
+
+/*!
+ Returns the bounding rect of this item in scene coordinates, by combining
+ sceneTransform() with boundingRect().
+
+ \sa boundingRect(), {The Graphics View Coordinate System}
+*/
+QRectF QGraphicsItem::sceneBoundingRect() const
+{
+ // Find translate-only offset
+ // COMBINE
+ QPointF offset;
+ const QGraphicsItem *parentItem = this;
+ const QGraphicsItemPrivate *itemd;
+ do {
+ itemd = parentItem->d_ptr.data();
+ if (itemd->transformData)
+ break;
+ offset += itemd->pos;
+ } while ((parentItem = itemd->parent));
+
+ QRectF br = boundingRect();
+ br.translate(offset);
+ if (!parentItem)
+ return br;
+ if (parentItem->d_ptr->hasTranslateOnlySceneTransform()) {
+ br.translate(parentItem->d_ptr->sceneTransform.dx(), parentItem->d_ptr->sceneTransform.dy());
+ return br;
+ }
+ return parentItem->d_ptr->sceneTransform.mapRect(br);
+}
+
+/*!
+ Returns the shape of this item as a QPainterPath in local
+ coordinates. The shape is used for many things, including collision
+ detection, hit tests, and for the QGraphicsScene::items() functions.
+
+ The default implementation calls boundingRect() to return a simple
+ rectangular shape, but subclasses can reimplement this function to return
+ a more accurate shape for non-rectangular items. For example, a round item
+ may choose to return an elliptic shape for better collision detection. For
+ example:
+
+ \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 9
+
+ The outline of a shape can vary depending on the width and style of the
+ pen used when drawing. If you want to include this outline in the item's
+ shape, you can create a shape from the stroke using QPainterPathStroker.
+
+ This function is called by the default implementations of contains() and
+ collidesWithPath().
+
+ \sa boundingRect(), contains(), prepareGeometryChange(), QPainterPathStroker
+*/
+QPainterPath QGraphicsItem::shape() const
+{
+ QPainterPath path;
+ path.addRect(boundingRect());
+ return path;
+}
+
+/*!
+ Returns true if this item is clipped. An item is clipped if it has either
+ set the \l ItemClipsToShape flag, or if it or any of its ancestors has set
+ the \l ItemClipsChildrenToShape flag.
+
+ Clipping affects the item's appearance (i.e., painting), as well as mouse
+ and hover event delivery.
+
+ \sa clipPath(), shape(), setFlags()
+*/
+bool QGraphicsItem::isClipped() const
+{
+ Q_D(const QGraphicsItem);
+ return (d->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)
+ || (d->flags & QGraphicsItem::ItemClipsToShape);
+}
+
+/*!
+ \since 4.5
+
+ Returns this item's clip path, or an empty QPainterPath if this item is
+ not clipped. The clip path constrains the item's appearance and
+ interaction (i.e., restricts the area the item can draw, and it also
+ restricts the area that the item receives events).
+
+ You can enable clipping by setting the ItemClipsToShape or
+ ItemClipsChildrenToShape flags. The item's clip path is calculated by
+ intersecting all clipping ancestors' shapes. If the item sets
+ ItemClipsToShape, the final clip is intersected with the item's own shape.
+
+ \note Clipping introduces a performance penalty for all items involved;
+ you should generally avoid using clipping if you can (e.g., if your items
+ always draw inside boundingRect() or shape() boundaries, clipping is not
+ necessary).
+
+ \sa isClipped(), shape(), setFlags()
+*/
+QPainterPath QGraphicsItem::clipPath() const
+{
+ Q_D(const QGraphicsItem);
+ if (!isClipped())
+ return QPainterPath();
+
+ const QRectF thisBoundingRect(boundingRect());
+ if (thisBoundingRect.isEmpty())
+ return QPainterPath();
+
+ QPainterPath clip;
+ // Start with the item's bounding rect.
+ clip.addRect(thisBoundingRect);
+
+ if (d->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) {
+ const QGraphicsItem *parent = this;
+ const QGraphicsItem *lastParent = this;
+
+ // Intersect any in-between clips starting at the top and moving downwards.
+ while ((parent = parent->d_ptr->parent)) {
+ if (parent->d_ptr->flags & ItemClipsChildrenToShape) {
+ // Map clip to the current parent and intersect with its shape/clipPath
+ clip = lastParent->itemTransform(parent).map(clip);
+ clip = clip.intersected(parent->shape());
+ if (clip.isEmpty())
+ return clip;
+ lastParent = parent;
+ }
+
+ if (!(parent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren))
+ break;
+ }
+
+ if (lastParent != this) {
+ // Map clip back to the item's transform.
+ // ### what if itemtransform fails
+ clip = lastParent->itemTransform(this).map(clip);
+ }
+ }
+
+ if (d->flags & ItemClipsToShape)
+ clip = clip.intersected(shape());
+
+ return clip;
+}
+
+/*!
+ Returns true if this item contains \a point, which is in local
+ coordinates; otherwise, false is returned. It is most often called from
+ QGraphicsView to determine what item is under the cursor, and for that
+ reason, the implementation of this function should be as light-weight as
+ possible.
+
+ By default, this function calls shape(), but you can reimplement it in a
+ subclass to provide a (perhaps more efficient) implementation.
+
+ \sa shape(), boundingRect(), collidesWithPath()
+*/
+bool QGraphicsItem::contains(const QPointF &point) const
+{
+ return isClipped() ? clipPath().contains(point) : shape().contains(point);
+}
+
+/*!
+
+ Returns true if this item collides with \a other; otherwise
+ returns false.
+
+ The \a mode is applied to \a other, and the resulting shape or
+ bounding rectangle is then compared to this item's shape. The
+ default value for \a mode is Qt::IntersectsItemShape; \a other
+ collides with this item if it either intersects, contains, or is
+ contained by this item's shape (see Qt::ItemSelectionMode for
+ details).
+
+ The default implementation is based on shape intersection, and it calls
+ shape() on both items. Because the complexity of arbitrary shape-shape
+ intersection grows with an order of magnitude when the shapes are complex,
+ this operation can be noticably time consuming. You have the option of
+ reimplementing this function in a subclass of QGraphicsItem to provide a
+ custom algorithm. This allows you to make use of natural constraints in
+ the shapes of your own items, in order to improve the performance of the
+ collision detection. For instance, two untransformed perfectly circular
+ items' collision can be determined very efficiently by comparing their
+ positions and radii.
+
+ Keep in mind that when reimplementing this function and calling shape() or
+ boundingRect() on \a other, the returned coordinates must be mapped to
+ this item's coordinate system before any intersection can take place.
+
+ \sa contains(), shape()
+*/
+bool QGraphicsItem::collidesWithItem(const QGraphicsItem *other, Qt::ItemSelectionMode mode) const
+{
+ if (other == this)
+ return true;
+ if (!other)
+ return false;
+ // The items share the same clip if their closest clipper is the same, or
+ // if one clips the other.
+ bool clips = (d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren);
+ bool otherClips = (other->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren);
+ if (clips || otherClips) {
+ const QGraphicsItem *closestClipper = isAncestorOf(other) ? this : parentItem();
+ while (closestClipper && !(closestClipper->flags() & ItemClipsChildrenToShape))
+ closestClipper = closestClipper->parentItem();
+ const QGraphicsItem *otherClosestClipper = other->isAncestorOf(this) ? other : other->parentItem();
+ while (otherClosestClipper && !(otherClosestClipper->flags() & ItemClipsChildrenToShape))
+ otherClosestClipper = otherClosestClipper->parentItem();
+ if (closestClipper == otherClosestClipper) {
+ d_ptr->localCollisionHack = 1;
+ bool res = collidesWithPath(mapFromItem(other, other->shape()), mode);
+ d_ptr->localCollisionHack = 0;
+ return res;
+ }
+ }
+
+ QPainterPath otherShape = other->isClipped() ? other->clipPath() : other->shape();
+ return collidesWithPath(mapFromItem(other, otherShape), mode);
+}
+
+/*!
+ Returns true if this item collides with \a path.
+
+ The collision is determined by \a mode. The default value for \a mode is
+ Qt::IntersectsItemShape; \a path collides with this item if it either
+ intersects, contains, or is contained by this item's shape.
+
+ Note that this function checks whether the item's shape or
+ bounding rectangle (depending on \a mode) is contained within \a
+ path, and not whether \a path is contained within the items shape
+ or bounding rectangle.
+
+ \sa collidesWithItem(), contains(), shape()
+*/
+bool QGraphicsItem::collidesWithPath(const QPainterPath &path, Qt::ItemSelectionMode mode) const
+{
+ if (path.isEmpty()) {
+ // No collision with empty paths.
+ return false;
+ }
+
+ 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.
+ return false;
+ }
+
+ // For further testing, we need this item's shape or bounding rect.
+ QPainterPath thisShape;
+ if (mode == Qt::IntersectsItemShape || mode == Qt::ContainsItemShape)
+ thisShape = (isClipped() && !d_ptr->localCollisionHack) ? clipPath() : shape();
+ else
+ thisShape.addRect(rectA);
+
+ if (thisShape == QPainterPath()) {
+ // Empty shape? No collision.
+ return false;
+ }
+
+ // Use QPainterPath boolean operations to determine the collision, O(N*logN).
+ if (mode == Qt::IntersectsItemShape || mode == Qt::IntersectsItemBoundingRect)
+ return path.intersects(thisShape);
+ return path.contains(thisShape);
+}
+
+/*!
+ Returns a list of all items that collide with this item.
+
+ The way collisions are detected is determined by applying \a mode
+ to items that are compared to this item, i.e., each item's shape
+ or bounding rectangle is checked against this item's shape. The
+ default value for \a mode is Qt::IntersectsItemShape.
+
+ \sa collidesWithItem()
+*/
+QList<QGraphicsItem *> QGraphicsItem::collidingItems(Qt::ItemSelectionMode mode) const
+{
+ if (d_ptr->scene)
+ return d_ptr->scene->collidingItems(this, mode);
+ return QList<QGraphicsItem *>();
+}
+
+/*!
+ Returns true if this item's bounding rect is completely obscured by the
+ opaque shape of any of colliding items above it (i.e., with a higher Z
+ value than this item).
+
+ Its implementation is based on calling isObscuredBy(), which you can
+ reimplement to provide a custom obscurity algorithm.
+
+ \sa opaqueArea()
+*/
+bool QGraphicsItem::isObscured() const
+{
+ return isObscured(QRectF());
+}
+
+/*!
+ \internal
+
+ Item obscurity helper function.
+
+ Returns true if the subrect \a rect of \a item's bounding rect is obscured
+ by \a other (i.e., \a other's opaque area covers \a item's \a rect
+ completely. \a other is assumed to already be "on top of" \a item
+ wrt. stacking order.
+*/
+static bool qt_QGraphicsItem_isObscured(const QGraphicsItem *item,
+ const QGraphicsItem *other,
+ const QRectF &rect)
+{
+ return other->mapToItem(item, other->opaqueArea()).contains(rect);
+}
+
+/*!
+ \overload
+ \since 4.3
+
+ Returns true if \a rect is completely obscured by the opaque shape of any
+ of colliding items above it (i.e., with a higher Z value than this item).
+
+ Unlike the default isObscured() function, this function does not call
+ isObscuredBy().
+
+ \sa opaqueArea()
+*/
+bool QGraphicsItem::isObscured(const QRectF &rect) const
+{
+ Q_D(const QGraphicsItem);
+ if (!d->scene)
+ return false;
+
+ QRectF br = boundingRect();
+ QRectF testRect = rect.isNull() ? br : rect;
+
+ foreach (QGraphicsItem *item, d->scene->items(mapToScene(br), Qt::IntersectsItemBoundingRect)) {
+ if (item == this)
+ break;
+ if (qt_QGraphicsItem_isObscured(this, item, testRect))
+ return true;
+ }
+ return false;
+}
+
+/*!
+ \fn bool QGraphicsItem::isObscured(qreal x, qreal y, qreal w, qreal h) const
+ \since 4.3
+
+ This convenience function is equivalent to calling isObscured(QRectF(\a x, \a y, \a w, \a h)).
+*/
+
+/*!
+ Returns true if this item's bounding rect is completely obscured by the
+ opaque shape of \a item.
+
+ The base implementation maps \a item's opaqueArea() to this item's
+ coordinate system, and then checks if this item's boundingRect() is fully
+ contained within the mapped shape.
+
+ You can reimplement this function to provide a custom algorithm for
+ determining whether this item is obscured by \a item.
+
+ \sa opaqueArea(), isObscured()
+*/
+bool QGraphicsItem::isObscuredBy(const QGraphicsItem *item) const
+{
+ if (!item)
+ return false;
+ return qt_closestItemFirst(item, this)
+ && qt_QGraphicsItem_isObscured(this, item, boundingRect());
+}
+
+/*!
+ This virtual function returns a shape representing the area where this
+ item is opaque. An area is opaque if it is filled using an opaque brush or
+ color (i.e., not transparent).
+
+ This function is used by isObscuredBy(), which is called by underlying
+ items to determine if they are obscured by this item.
+
+ The default implementation returns an empty QPainterPath, indicating that
+ this item is completely transparent and does not obscure any other items.
+
+ \sa isObscuredBy(), isObscured(), shape()
+*/
+QPainterPath QGraphicsItem::opaqueArea() const
+{
+ return QPainterPath();
+}
+
+/*!
+ \since 4.4
+
+ Returns the bounding region for this item. The coordinate space of the
+ returned region depends on \a itemToDeviceTransform. If you pass an
+ identity QTransform as a parameter, this function will return a local
+ coordinate region.
+
+ The bounding region describes a coarse outline of the item's visual
+ contents. Although it's expensive to calculate, it's also more precise
+ than boundingRect(), and it can help to avoid unnecessary repainting when
+ an item is updated. This is particularly efficient for thin items (e.g.,
+ lines or simple polygons). You can tune the granularity for the bounding
+ region by calling setBoundingRegionGranularity(). The default granularity
+ is 0; in which the item's bounding region is the same as its bounding
+ rect.
+
+ \a itemToDeviceTransform is the transformation from item coordinates to
+ device coordinates. If you want this function to return a QRegion in scene
+ coordinates, you can pass sceneTransform() as an argument.
+
+ \sa boundingRegionGranularity()
+*/
+QRegion QGraphicsItem::boundingRegion(const QTransform &itemToDeviceTransform) const
+{
+ // ### Ideally we would have a better way to generate this region,
+ // preferably something in the lines of QPainterPath::toRegion(QTransform)
+ // coupled with a way to generate a painter path from a set of painter
+ // operations (e.g., QPicture::toPainterPath() or so). The current
+ // approach generates a bitmap with the size of the item's bounding rect
+ // in device coordinates, scaled by b.r.granularity, then paints the item
+ // 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 = itemToDeviceTransform.mapRect(boundingRect()).toRect();
+ _q_adjustRect(&deviceRect);
+ if (granularity == 0.0)
+ return QRegion(deviceRect);
+
+ int pad = 1;
+ QSize bitmapSize(qMax(1, int(deviceRect.width() * granularity) + pad * 2),
+ qMax(1, int(deviceRect.height() * granularity) + pad * 2));
+ QImage mask(bitmapSize, QImage::Format_ARGB32_Premultiplied);
+ mask.fill(0);
+ QPainter p(&mask);
+ p.setRenderHints(QPainter::Antialiasing);
+
+ // Transform painter (### this code is from QGraphicsScene::drawItemHelper
+ // and doesn't work properly with perspective transformations).
+ QPointF viewOrigo = itemToDeviceTransform.map(QPointF(0, 0));
+ QPointF offset = viewOrigo - deviceRect.topLeft();
+ p.scale(granularity, granularity);
+ p.translate(offset);
+ p.translate(pad, pad);
+ p.setWorldTransform(itemToDeviceTransform, true);
+ p.translate(itemToDeviceTransform.inverted().map(QPointF(0, 0)));
+
+ // Render
+ QStyleOptionGraphicsItem option;
+ const_cast<QGraphicsItem *>(this)->paint(&p, &option, 0);
+ p.end();
+
+ // Transform QRegion back to device space
+ QTransform unscale = QTransform::fromScale(1 / granularity, 1 / granularity);
+ QRegion r;
+ QBitmap colorMask = QBitmap::fromImage(mask.createMaskFromColor(0));
+ foreach (const QRect &rect, QRegion( colorMask ).rects()) {
+ QRect xrect = unscale.mapRect(rect).translated(deviceRect.topLeft() - QPoint(pad, pad));
+ r += xrect.adjusted(-1, -1, 1, 1) & deviceRect;
+ }
+ return r;
+}
+
+/*!
+ \since 4.4
+
+ Returns the item's bounding region granularity; a value between and
+ including 0 and 1. The default value is 0 (i.e., the lowest granularity,
+ where the bounding region corresponds to the item's bounding rectangle).
+
+\omit
+### NOTE
+\endomit
+
+ \sa setBoundingRegionGranularity()
+*/
+qreal QGraphicsItem::boundingRegionGranularity() const
+{
+ return d_ptr->hasBoundingRegionGranularity
+ ? qvariant_cast<qreal>(d_ptr->extra(QGraphicsItemPrivate::ExtraBoundingRegionGranularity))
+ : 0;
+}
+
+/*!
+ \since 4.4
+ Sets the bounding region granularity to \a granularity; a value between
+ and including 0 and 1. The default value is 0 (i.e., the lowest
+ granularity, where the bounding region corresponds to the item's bounding
+ rectangle).
+
+ The granularity is used by boundingRegion() to calculate how fine the
+ bounding region of the item should be. The highest achievable granularity
+ is 1, where boundingRegion() will return the finest outline possible for
+ the respective device (e.g., for a QGraphicsView viewport, this gives you
+ a pixel-perfect bounding region). The lowest possible granularity is
+ 0. The value of \a granularity describes the ratio between device
+ resolution and the resolution of the bounding region (e.g., a value of
+ 0.25 will provide a region where each chunk corresponds to 4x4 device
+ units / pixels).
+
+ \sa boundingRegionGranularity()
+*/
+void QGraphicsItem::setBoundingRegionGranularity(qreal granularity)
+{
+ if (granularity < 0.0 || granularity > 1.0) {
+ qWarning("QGraphicsItem::setBoundingRegionGranularity: invalid granularity %g", granularity);
+ return;
+ }
+ if (granularity == 0.0) {
+ d_ptr->unsetExtra(QGraphicsItemPrivate::ExtraBoundingRegionGranularity);
+ d_ptr->hasBoundingRegionGranularity = 0;
+ return;
+ }
+ d_ptr->hasBoundingRegionGranularity = 1;
+ d_ptr->setExtra(QGraphicsItemPrivate::ExtraBoundingRegionGranularity,
+ QVariant::fromValue<qreal>(granularity));
+}
+
+/*!
+ \fn virtual void QGraphicsItem::paint(QPainter *painter, const
+ QStyleOptionGraphicsItem *option, QWidget *widget = 0) = 0
+
+ This function, which is usually called by QGraphicsView, paints the
+ contents of an item in local coordinates.
+
+ Reimplement this function in a QGraphicsItem subclass to provide the
+ item's painting implementation, using \a painter. The \a option parameter
+ provides style options for the item, such as its state, exposed area and
+ its level-of-detail hints. The \a widget argument is optional. If
+ provided, it points to the widget that is being painted on; otherwise, it
+ is 0. For cached painting, \a widget is always 0.
+
+ \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 10
+
+ The painter's pen is 0-width by default, and its pen is initialized to the
+ QPalette::Text brush from the paint device's palette. The brush is
+ initialized to QPalette::Window.
+
+ Make sure to constrain all painting inside the boundaries of
+ boundingRect() to avoid rendering artifacts (as QGraphicsView does not
+ clip the painter for you). In particular, when QPainter renders the
+ outline of a shape using an assigned QPen, half of the outline will be
+ drawn outside, and half inside, the shape you're rendering (e.g., with a
+ pen width of 2 units, you must draw outlines 1 unit inside
+ boundingRect()). QGraphicsItem does not support use of cosmetic pens with
+ a non-zero width.
+
+ All painting is done in local coordinates.
+
+ \sa setCacheMode(), QPen::width(), {Item Coordinates}, ItemUsesExtendedStyleOption
+*/
+
+/*!
+ \internal
+ Returns true if we can discard an update request; otherwise false.
+*/
+bool QGraphicsItemPrivate::discardUpdateRequest(bool ignoreVisibleBit, bool ignoreDirtyBit,
+ bool ignoreOpacity) 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 !scene
+ || (!visible && !ignoreVisibleBit && !this->ignoreVisible)
+ || (!ignoreDirtyBit && fullUpdatePending)
+ || (!ignoreOpacity && !this->ignoreOpacity && childrenCombineOpacity() && isFullyTransparent());
+}
+
+/*!
+ \internal
+*/
+int QGraphicsItemPrivate::depth() const
+{
+ if (itemDepth == -1)
+ const_cast<QGraphicsItemPrivate *>(this)->resolveDepth();
+
+ return itemDepth;
+}
+
+/*!
+ \internal
+*/
+#ifndef QT_NO_GRAPHICSEFFECT
+void QGraphicsItemPrivate::invalidateParentGraphicsEffectsRecursively()
+{
+ QGraphicsItemPrivate *itemPrivate = this;
+ do {
+ if (itemPrivate->graphicsEffect) {
+ itemPrivate->notifyInvalidated = 1;
+
+ if (!itemPrivate->updateDueToGraphicsEffect)
+ static_cast<QGraphicsItemEffectSourcePrivate *>(itemPrivate->graphicsEffect->d_func()->source->d_func())->invalidateCache();
+ }
+ } while ((itemPrivate = itemPrivate->parent ? itemPrivate->parent->d_ptr.data() : 0));
+}
+
+void QGraphicsItemPrivate::invalidateChildGraphicsEffectsRecursively(QGraphicsItemPrivate::InvalidateReason reason)
+{
+ if (!mayHaveChildWithGraphicsEffect)
+ return;
+
+ for (int i = 0; i < children.size(); ++i) {
+ QGraphicsItemPrivate *childPrivate = children.at(i)->d_ptr.data();
+ if (reason == OpacityChanged && (childPrivate->flags & QGraphicsItem::ItemIgnoresParentOpacity))
+ continue;
+ if (childPrivate->graphicsEffect) {
+ childPrivate->notifyInvalidated = 1;
+ static_cast<QGraphicsItemEffectSourcePrivate *>(childPrivate->graphicsEffect->d_func()->source->d_func())->invalidateCache();
+ }
+
+ childPrivate->invalidateChildGraphicsEffectsRecursively(reason);
+ }
+}
+#endif //QT_NO_GRAPHICSEFFECT
+
+/*!
+ \internal
+*/
+void QGraphicsItemPrivate::invalidateDepthRecursively()
+{
+ if (itemDepth == -1)
+ return;
+
+ itemDepth = -1;
+ for (int i = 0; i < children.size(); ++i)
+ children.at(i)->d_ptr->invalidateDepthRecursively();
+}
+
+/*!
+ \internal
+
+ Resolves the stacking depth of this object and all its ancestors.
+*/
+void QGraphicsItemPrivate::resolveDepth()
+{
+ if (!parent)
+ itemDepth = 0;
+ else {
+ if (parent->d_ptr->itemDepth == -1)
+ parent->d_ptr->resolveDepth();
+ itemDepth = parent->d_ptr->itemDepth + 1;
+ }
+}
+
+/*!
+ \internal
+
+ ### This function is almost identical to
+ QGraphicsScenePrivate::registerTopLevelItem().
+*/
+void QGraphicsItemPrivate::addChild(QGraphicsItem *child)
+{
+ // Remove all holes from the sibling index list. Now the max index
+ // number is equal to the size of the children list.
+ ensureSequentialSiblingIndex();
+ needSortChildren = 1; // ### maybe 0
+ child->d_ptr->siblingIndex = children.size();
+ children.append(child);
+ if (isObject)
+ emit static_cast<QGraphicsObject *>(q_ptr)->childrenChanged();
+}
+
+/*!
+ \internal
+
+ ### This function is almost identical to
+ QGraphicsScenePrivate::unregisterTopLevelItem().
+*/
+void QGraphicsItemPrivate::removeChild(QGraphicsItem *child)
+{
+ // When removing elements in the middle of the children list,
+ // there will be a "gap" in the list of sibling indexes (0,1,3,4).
+ if (!holesInSiblingIndex)
+ holesInSiblingIndex = child->d_ptr->siblingIndex != children.size() - 1;
+ if (sequentialOrdering && !holesInSiblingIndex)
+ children.removeAt(child->d_ptr->siblingIndex);
+ else
+ children.removeOne(child);
+ // NB! Do not use children.removeAt(child->d_ptr->siblingIndex) because
+ // the child is not guaranteed to be at the index after the list is sorted.
+ // (see ensureSortedChildren()).
+ child->d_ptr->siblingIndex = -1;
+ if (isObject)
+ emit static_cast<QGraphicsObject *>(q_ptr)->childrenChanged();
+}
+
+/*!
+ \internal
+*/
+QGraphicsItemCache *QGraphicsItemPrivate::maybeExtraItemCache() const
+{
+ return (QGraphicsItemCache *)qvariant_cast<void *>(extra(ExtraCacheData));
+}
+
+/*!
+ \internal
+*/
+QGraphicsItemCache *QGraphicsItemPrivate::extraItemCache() const
+{
+ QGraphicsItemCache *c = (QGraphicsItemCache *)qvariant_cast<void *>(extra(ExtraCacheData));
+ if (!c) {
+ QGraphicsItemPrivate *that = const_cast<QGraphicsItemPrivate *>(this);
+ c = new QGraphicsItemCache;
+ that->setExtra(ExtraCacheData, QVariant::fromValue<void *>(c));
+ }
+ return c;
+}
+
+/*!
+ \internal
+*/
+void QGraphicsItemPrivate::removeExtraItemCache()
+{
+ QGraphicsItemCache *c = (QGraphicsItemCache *)qvariant_cast<void *>(extra(ExtraCacheData));
+ if (c) {
+ c->purge();
+ delete c;
+ }
+ unsetExtra(ExtraCacheData);
+}
+
+void QGraphicsItemPrivate::updatePaintedViewBoundingRects(bool updateChildren)
+{
+ if (!scene)
+ return;
+
+ for (int i = 0; i < scene->d_func()->views.size(); ++i) {
+ QGraphicsViewPrivate *viewPrivate = scene->d_func()->views.at(i)->d_func();
+ QRect rect = paintedViewBoundingRects.value(viewPrivate->viewport);
+ rect.translate(viewPrivate->dirtyScrollOffset);
+ viewPrivate->updateRect(rect);
+ }
+
+ if (updateChildren) {
+ for (int i = 0; i < children.size(); ++i)
+ children.at(i)->d_ptr->updatePaintedViewBoundingRects(true);
+ }
+}
+
+// Traverses all the ancestors up to the top-level and updates the pointer to
+// always point to the top-most item that has a dirty scene transform.
+// It then backtracks to the top-most dirty item and start calculating the
+// scene transform by combining the item's transform (+pos) with the parent's
+// cached scene transform (which we at this point know for sure is valid).
+void QGraphicsItemPrivate::ensureSceneTransformRecursive(QGraphicsItem **topMostDirtyItem)
+{
+ Q_ASSERT(topMostDirtyItem);
+
+ if (dirtySceneTransform)
+ *topMostDirtyItem = q_ptr;
+
+ if (parent)
+ parent->d_ptr->ensureSceneTransformRecursive(topMostDirtyItem);
+
+ if (*topMostDirtyItem == q_ptr) {
+ if (!dirtySceneTransform)
+ return; // OK, neither my ancestors nor I have dirty scene transforms.
+ *topMostDirtyItem = 0;
+ } else if (*topMostDirtyItem) {
+ return; // Continue backtrack.
+ }
+
+ // This item and all its descendants have dirty scene transforms.
+ // We're about to validate this item's scene transform, so we have to
+ // invalidate all the children; otherwise there's no way for the descendants
+ // to detect that the ancestor has changed.
+ invalidateChildrenSceneTransform();
+
+ // COMBINE my transform with the parent's scene transform.
+ updateSceneTransformFromParent();
+ Q_ASSERT(!dirtySceneTransform);
+}
+
+/*!
+ \internal
+*/
+void QGraphicsItemPrivate::setSubFocus(QGraphicsItem *rootItem, QGraphicsItem *stopItem)
+{
+ // Update focus child chain. Stop at panels, or if this item
+ // is hidden, stop at the first item with a visible parent.
+ QGraphicsItem *parent = rootItem ? rootItem : q_ptr;
+ if (parent->panel() != q_ptr->panel())
+ return;
+
+ do {
+ // Clear any existing ancestor's subFocusItem.
+ if (parent != q_ptr && parent->d_ptr->subFocusItem) {
+ if (parent->d_ptr->subFocusItem == q_ptr)
+ break;
+ parent->d_ptr->subFocusItem->d_ptr->clearSubFocus(0, stopItem);
+ }
+ parent->d_ptr->subFocusItem = q_ptr;
+ parent->d_ptr->subFocusItemChange();
+ } while (!parent->isPanel() && (parent = parent->d_ptr->parent) && (visible || !parent->d_ptr->visible));
+
+ if (scene && !scene->isActive()) {
+ scene->d_func()->passiveFocusItem = subFocusItem;
+ scene->d_func()->lastFocusItem = subFocusItem;
+ }
+}
+
+/*!
+ \internal
+*/
+void QGraphicsItemPrivate::clearSubFocus(QGraphicsItem *rootItem, QGraphicsItem *stopItem)
+{
+ // Reset sub focus chain.
+ QGraphicsItem *parent = rootItem ? rootItem : q_ptr;
+ do {
+ if (parent->d_ptr->subFocusItem != q_ptr)
+ break;
+ parent->d_ptr->subFocusItem = 0;
+ if (parent != stopItem && !parent->isAncestorOf(stopItem))
+ parent->d_ptr->subFocusItemChange();
+ } while (!parent->isPanel() && (parent = parent->d_ptr->parent));
+}
+
+/*!
+ \internal
+
+ Sets the focusProxy pointer to 0 for all items that have this item as their
+ focusProxy. ### Qt 5: Use QPointer instead.
+*/
+void QGraphicsItemPrivate::resetFocusProxy()
+{
+ for (int i = 0; i < focusProxyRefs.size(); ++i)
+ *focusProxyRefs.at(i) = 0;
+ focusProxyRefs.clear();
+}
+
+/*!
+ \internal
+
+ Subclasses can reimplement this function to be notified when subFocusItem
+ changes.
+*/
+void QGraphicsItemPrivate::subFocusItemChange()
+{
+}
+
+/*!
+ \internal
+
+ Subclasses can reimplement this function to be notified when an item
+ becomes a focusScopeItem (or is no longer a focusScopeItem).
+*/
+void QGraphicsItemPrivate::focusScopeItemChange(bool isSubFocusItem)
+{
+ Q_UNUSED(isSubFocusItem);
+}
+
+/*!
+ \internal
+
+ Subclasses can reimplement this function to be notified when its
+ siblingIndex order is changed.
+*/
+void QGraphicsItemPrivate::siblingOrderChange()
+{
+}
+
+/*!
+ \internal
+
+ Tells us if it is a proxy widget
+*/
+bool QGraphicsItemPrivate::isProxyWidget() const
+{
+ return false;
+}
+
+/*!
+ Schedules a redraw of the area covered by \a rect in this item. You can
+ call this function whenever your item needs to be redrawn, such as if it
+ changes appearance or size.
+
+ This function does not cause an immediate paint; instead it schedules a
+ paint request that is processed by QGraphicsView after control reaches the
+ event loop. The item will only be redrawn if it is visible in any
+ associated view.
+
+ As a side effect of the item being repainted, other items that overlap the
+ area \a rect may also be repainted.
+
+ If the item is invisible (i.e., isVisible() returns false), this function
+ does nothing.
+
+ \sa paint(), boundingRect()
+*/
+void QGraphicsItem::update(const QRectF &rect)
+{
+ if (rect.isEmpty() && !rect.isNull())
+ return;
+
+ // Make sure we notify effects about invalidated source.
+#ifndef QT_NO_GRAPHICSEFFECT
+ d_ptr->invalidateParentGraphicsEffectsRecursively();
+#endif //QT_NO_GRAPHICSEFFECT
+
+ if (CacheMode(d_ptr->cacheMode) != NoCache) {
+ // Invalidate cache.
+ QGraphicsItemCache *cache = d_ptr->extraItemCache();
+ if (!cache->allExposed) {
+ if (rect.isNull()) {
+ cache->allExposed = true;
+ cache->exposed.clear();
+ } else {
+ cache->exposed.append(rect);
+ }
+ }
+ // Only invalidate cache; item is already dirty.
+ if (d_ptr->fullUpdatePending)
+ return;
+ }
+
+ if (d_ptr->scene)
+ d_ptr->scene->d_func()->markDirty(this, rect);
+}
+
+/*!
+ \since 4.4
+ Scrolls the contents of \a rect by \a dx, \a dy. If \a rect is a null rect
+ (the default), the item's bounding rect is scrolled.
+
+ Scrolling provides a fast alternative to simply redrawing when the
+ contents of the item (or parts of the item) are shifted vertically or
+ horizontally. Depending on the current transformation and the capabilities
+ of the paint device (i.e., the viewport), this operation may consist of
+ simply moving pixels from one location to another using memmove(). In most
+ cases this is faster than rerendering the entire area.
+
+ After scrolling, the item will issue an update for the newly exposed
+ areas. If scrolling is not supported (e.g., you are rendering to an OpenGL
+ viewport, which does not benefit from scroll optimizations), this function
+ is equivalent to calling update(\a rect).
+
+ \bold{Note:} Scrolling is only supported when QGraphicsItem::ItemCoordinateCache
+ is enabled; in all other cases calling this function is equivalent to calling
+ update(\a rect). If you for sure know that the item is opaque and not overlapped
+ by other items, you can map the \a rect to viewport coordinates and scroll the
+ viewport.
+
+ \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 19
+
+ \sa boundingRect()
+*/
+void QGraphicsItem::scroll(qreal dx, qreal dy, const QRectF &rect)
+{
+ Q_D(QGraphicsItem);
+ if (dx == 0.0 && dy == 0.0)
+ return;
+ if (!d->scene)
+ return;
+
+ // Accelerated scrolling means moving pixels from one location to another
+ // and only redraw the newly exposed area. The following requirements must
+ // be fulfilled in order to do that:
+ //
+ // 1) Item is opaque.
+ // 2) Item is not overlapped by other items.
+ //
+ // There's (yet) no way to detect whether an item is opaque or not, which means
+ // we cannot do accelerated scrolling unless the cache is enabled. In case of using
+ // DeviceCoordinate cache we also have to take the device transform into account in
+ // order to determine whether we can do accelerated scrolling or not. That's left out
+ // for simplicity here, but it is definitely something we can consider in the future
+ // as a performance improvement.
+ if (d->cacheMode != QGraphicsItem::ItemCoordinateCache
+ || !qFuzzyIsNull(dx - int(dx)) || !qFuzzyIsNull(dy - int(dy))) {
+ update(rect);
+ return;
+ }
+
+ QGraphicsItemCache *cache = d->extraItemCache();
+ if (cache->allExposed || cache->fixedSize.isValid()) {
+ // Cache is either invalidated or item is scaled (see QGraphicsItem::setCacheMode).
+ update(rect);
+ return;
+ }
+
+ // Find pixmap in cache.
+ QPixmap cachedPixmap;
+ if (!QPixmapCache::find(cache->key, &cachedPixmap)) {
+ update(rect);
+ return;
+ }
+
+ QRect scrollRect = (rect.isNull() ? boundingRect() : rect).toAlignedRect();
+ if (!scrollRect.intersects(cache->boundingRect))
+ return; // Nothing to scroll.
+
+ // Remove from cache to avoid deep copy when modifying.
+ QPixmapCache::remove(cache->key);
+
+ QRegion exposed;
+ cachedPixmap.scroll(dx, dy, scrollRect.translated(-cache->boundingRect.topLeft()), &exposed);
+
+ // Reinsert into cache.
+ cache->key = QPixmapCache::insert(cachedPixmap);
+
+ // Translate the existing expose.
+ for (int i = 0; i < cache->exposed.size(); ++i) {
+ QRectF &e = cache->exposed[i];
+ if (!rect.isNull() && !e.intersects(rect))
+ continue;
+ e.translate(dx, dy);
+ }
+
+ // Append newly exposed areas. Note that the exposed region is currently
+ // in pixmap coordinates, so we have to translate it to item coordinates.
+ exposed.translate(cache->boundingRect.topLeft());
+ const QVector<QRect> exposedRects = exposed.rects();
+ for (int i = 0; i < exposedRects.size(); ++i)
+ cache->exposed += exposedRects.at(i);
+
+ // Trigger update. This will redraw the newly exposed area and make sure
+ // the pixmap is re-blitted in case there are overlapping items.
+ d->scene->d_func()->markDirty(this, rect);
+}
+
+/*!
+ \fn void QGraphicsItem::update(qreal x, qreal y, qreal width, qreal height)
+ \overload
+
+ This convenience function is equivalent to calling update(QRectF(\a x, \a
+ y, \a width, \a height)).
+*/
+
+/*!
+ Maps the point \a point, which is in this item's coordinate system, to \a
+ item's coordinate system, and returns the mapped coordinate.
+
+ If \a item is 0, this function returns the same as mapToScene().
+
+ \sa itemTransform(), mapToParent(), mapToScene(), transform(), mapFromItem(), {The Graphics
+ View Coordinate System}
+*/
+QPointF QGraphicsItem::mapToItem(const QGraphicsItem *item, const QPointF &point) const
+{
+ if (item)
+ return itemTransform(item).map(point);
+ return mapToScene(point);
+}
+
+/*!
+ \fn QPointF QGraphicsItem::mapToItem(const QGraphicsItem *item, qreal x, qreal y) const
+ \overload
+
+ This convenience function is equivalent to calling mapToItem(\a item,
+ QPointF(\a x, \a y)).
+*/
+
+/*!
+ Maps the point \a point, which is in this item's coordinate system, to its
+ parent's coordinate system, and returns the mapped coordinate. If the item
+ has no parent, \a point will be mapped to the scene's coordinate system.
+
+ \sa mapToItem(), mapToScene(), transform(), mapFromParent(), {The Graphics
+ View Coordinate System}
+*/
+QPointF QGraphicsItem::mapToParent(const QPointF &point) const
+{
+ // COMBINE
+ if (!d_ptr->transformData)
+ return point + d_ptr->pos;
+ return d_ptr->transformToParent().map(point);
+}
+
+/*!
+ \fn QPointF QGraphicsItem::mapToParent(qreal x, qreal y) const
+ \overload
+
+ This convenience function is equivalent to calling mapToParent(QPointF(\a
+ x, \a y)).
+*/
+
+/*!
+ Maps the point \a point, which is in this item's coordinate system, to the
+ scene's coordinate system, and returns the mapped coordinate.
+
+ \sa mapToItem(), mapToParent(), transform(), mapFromScene(), {The Graphics
+ View Coordinate System}
+*/
+QPointF QGraphicsItem::mapToScene(const QPointF &point) const
+{
+ if (d_ptr->hasTranslateOnlySceneTransform())
+ return QPointF(point.x() + d_ptr->sceneTransform.dx(), point.y() + d_ptr->sceneTransform.dy());
+ return d_ptr->sceneTransform.map(point);
+}
+
+/*!
+ \fn QPointF QGraphicsItem::mapToScene(qreal x, qreal y) const
+ \overload
+
+ This convenience function is equivalent to calling mapToScene(QPointF(\a
+ x, \a y)).
+*/
+
+/*!
+ Maps the rectangle \a rect, which is in this item's coordinate system, to
+ \a item's coordinate system, and returns the mapped rectangle as a polygon.
+
+ If \a item is 0, this function returns the same as mapToScene().
+
+ \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
+ Graphics View Coordinate System}
+*/
+QPolygonF QGraphicsItem::mapToItem(const QGraphicsItem *item, const QRectF &rect) const
+{
+ if (item)
+ return itemTransform(item).map(rect);
+ return mapToScene(rect);
+}
+
+/*!
+ \fn QPolygonF QGraphicsItem::mapToItem(const QGraphicsItem *item, qreal x, qreal y, qreal w, qreal h) const
+ \since 4.3
+
+ This convenience function is equivalent to calling mapToItem(item, QRectF(\a x, \a y, \a w, \a h)).
+*/
+
+/*!
+ Maps the rectangle \a rect, which is in this item's coordinate system, to
+ its parent's coordinate system, and returns the mapped rectangle as a
+ polygon. If the item has no parent, \a rect will be mapped to the scene's
+ coordinate system.
+
+ \sa mapToScene(), mapToItem(), mapFromParent(), {The Graphics View
+ Coordinate System}
+*/
+QPolygonF QGraphicsItem::mapToParent(const QRectF &rect) const
+{
+ // COMBINE
+ if (!d_ptr->transformData)
+ return rect.translated(d_ptr->pos);
+ return d_ptr->transformToParent().map(rect);
+}
+
+/*!
+ \fn QPolygonF QGraphicsItem::mapToParent(qreal x, qreal y, qreal w, qreal h) const
+ \since 4.3
+
+ This convenience function is equivalent to calling mapToParent(QRectF(\a x, \a y, \a w, \a h)).
+*/
+
+/*!
+ Maps the rectangle \a rect, which is in this item's coordinate system, to
+ the scene's coordinate system, and returns the mapped rectangle as a polygon.
+
+ \sa mapToParent(), mapToItem(), mapFromScene(), {The Graphics View
+ Coordinate System}
+*/
+QPolygonF QGraphicsItem::mapToScene(const QRectF &rect) const
+{
+ if (d_ptr->hasTranslateOnlySceneTransform())
+ return rect.translated(d_ptr->sceneTransform.dx(), d_ptr->sceneTransform.dy());
+ return d_ptr->sceneTransform.map(rect);
+}
+
+/*!
+ \fn QPolygonF QGraphicsItem::mapToScene(qreal x, qreal y, qreal w, qreal h) const
+ \since 4.3
+
+ This convenience function is equivalent to calling mapToScene(QRectF(\a x, \a y, \a w, \a h)).
+*/
+
+/*!
+ \since 4.5
+
+ Maps the rectangle \a rect, which is in this item's coordinate system, to
+ \a item's coordinate system, and returns the mapped rectangle as a new
+ rectangle (i.e., the bounding rectangle of the resulting polygon).
+
+ If \a item is 0, this function returns the same as mapRectToScene().
+
+ \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
+ Graphics View Coordinate System}
+*/
+QRectF QGraphicsItem::mapRectToItem(const QGraphicsItem *item, const QRectF &rect) const
+{
+ if (item)
+ return itemTransform(item).mapRect(rect);
+ return mapRectToScene(rect);
+}
+
+/*!
+ \fn QRectF QGraphicsItem::mapRectToItem(const QGraphicsItem *item, qreal x, qreal y, qreal w, qreal h) const
+ \since 4.5
+
+ This convenience function is equivalent to calling mapRectToItem(item, QRectF(\a x, \a y, \a w, \a h)).
+*/
+
+/*!
+ \since 4.5
+
+ Maps the rectangle \a rect, which is in this item's coordinate system, to
+ its parent's coordinate system, and returns the mapped rectangle as a new
+ rectangle (i.e., the bounding rectangle of the resulting polygon).
+
+ \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
+ Graphics View Coordinate System}
+*/
+QRectF QGraphicsItem::mapRectToParent(const QRectF &rect) const
+{
+ // COMBINE
+ if (!d_ptr->transformData)
+ return rect.translated(d_ptr->pos);
+ return d_ptr->transformToParent().mapRect(rect);
+}
+
+/*!
+ \fn QRectF QGraphicsItem::mapRectToParent(qreal x, qreal y, qreal w, qreal h) const
+ \since 4.5
+
+ This convenience function is equivalent to calling mapRectToParent(QRectF(\a x, \a y, \a w, \a h)).
+*/
+
+/*!
+ \since 4.5
+
+ Maps the rectangle \a rect, which is in this item's coordinate system, to
+ the scene coordinate system, and returns the mapped rectangle as a new
+ rectangle (i.e., the bounding rectangle of the resulting polygon).
+
+ \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
+ Graphics View Coordinate System}
+*/
+QRectF QGraphicsItem::mapRectToScene(const QRectF &rect) const
+{
+ if (d_ptr->hasTranslateOnlySceneTransform())
+ return rect.translated(d_ptr->sceneTransform.dx(), d_ptr->sceneTransform.dy());
+ return d_ptr->sceneTransform.mapRect(rect);
+}
+
+/*!
+ \fn QRectF QGraphicsItem::mapRectToScene(qreal x, qreal y, qreal w, qreal h) const
+ \since 4.5
+
+ This convenience function is equivalent to calling mapRectToScene(QRectF(\a x, \a y, \a w, \a h)).
+*/
+
+/*!
+ \since 4.5
+
+ Maps the rectangle \a rect, which is in \a item's coordinate system, to
+ this item's coordinate system, and returns the mapped rectangle as a new
+ rectangle (i.e., the bounding rectangle of the resulting polygon).
+
+ If \a item is 0, this function returns the same as mapRectFromScene().
+
+ \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
+ Graphics View Coordinate System}
+*/
+QRectF QGraphicsItem::mapRectFromItem(const QGraphicsItem *item, const QRectF &rect) const
+{
+ if (item)
+ return item->itemTransform(this).mapRect(rect);
+ return mapRectFromScene(rect);
+}
+
+/*!
+ \fn QRectF QGraphicsItem::mapRectFromItem(const QGraphicsItem *item, qreal x, qreal y, qreal w, qreal h) const
+ \since 4.5
+
+ This convenience function is equivalent to calling mapRectFromItem(item, QRectF(\a x, \a y, \a w, \a h)).
+*/
+
+/*!
+ \since 4.5
+
+ Maps the rectangle \a rect, which is in this item's parent's coordinate
+ system, to this item's coordinate system, and returns the mapped rectangle
+ as a new rectangle (i.e., the bounding rectangle of the resulting
+ polygon).
+
+ \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
+ Graphics View Coordinate System}
+*/
+QRectF QGraphicsItem::mapRectFromParent(const QRectF &rect) const
+{
+ // COMBINE
+ if (!d_ptr->transformData)
+ return rect.translated(-d_ptr->pos);
+ return d_ptr->transformToParent().inverted().mapRect(rect);
+}
+
+/*!
+ \fn QRectF QGraphicsItem::mapRectFromParent(qreal x, qreal y, qreal w, qreal h) const
+ \since 4.5
+
+ This convenience function is equivalent to calling mapRectFromParent(QRectF(\a x, \a y, \a w, \a h)).
+*/
+
+/*!
+ \since 4.5
+
+ Maps the rectangle \a rect, which is in scene coordinates, to this item's
+ coordinate system, and returns the mapped rectangle as a new rectangle
+ (i.e., the bounding rectangle of the resulting polygon).
+
+ \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
+ Graphics View Coordinate System}
+*/
+QRectF QGraphicsItem::mapRectFromScene(const QRectF &rect) const
+{
+ if (d_ptr->hasTranslateOnlySceneTransform())
+ return rect.translated(-d_ptr->sceneTransform.dx(), -d_ptr->sceneTransform.dy());
+ return d_ptr->sceneTransform.inverted().mapRect(rect);
+}
+
+/*!
+ \fn QRectF QGraphicsItem::mapRectFromScene(qreal x, qreal y, qreal w, qreal h) const
+ \since 4.5
+
+ This convenience function is equivalent to calling mapRectFromScene(QRectF(\a x, \a y, \a w, \a h)).
+*/
+
+/*!
+ Maps the polygon \a polygon, which is in this item's coordinate system, to
+ \a item's coordinate system, and returns the mapped polygon.
+
+ If \a item is 0, this function returns the same as mapToScene().
+
+ \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
+ Graphics View Coordinate System}
+*/
+QPolygonF QGraphicsItem::mapToItem(const QGraphicsItem *item, const QPolygonF &polygon) const
+{
+ if (item)
+ return itemTransform(item).map(polygon);
+ return mapToScene(polygon);
+}
+
+/*!
+ Maps the polygon \a polygon, which is in this item's coordinate system, to
+ its parent's coordinate system, and returns the mapped polygon. If the
+ item has no parent, \a polygon will be mapped to the scene's coordinate
+ system.
+
+ \sa mapToScene(), mapToItem(), mapFromParent(), {The Graphics View
+ Coordinate System}
+*/
+QPolygonF QGraphicsItem::mapToParent(const QPolygonF &polygon) const
+{
+ // COMBINE
+ if (!d_ptr->transformData)
+ return polygon.translated(d_ptr->pos);
+ return d_ptr->transformToParent().map(polygon);
+}
+
+/*!
+ Maps the polygon \a polygon, which is in this item's coordinate system, to
+ the scene's coordinate system, and returns the mapped polygon.
+
+ \sa mapToParent(), mapToItem(), mapFromScene(), {The Graphics View
+ Coordinate System}
+*/
+QPolygonF QGraphicsItem::mapToScene(const QPolygonF &polygon) const
+{
+ if (d_ptr->hasTranslateOnlySceneTransform())
+ return polygon.translated(d_ptr->sceneTransform.dx(), d_ptr->sceneTransform.dy());
+ return d_ptr->sceneTransform.map(polygon);
+}
+
+/*!
+ Maps the path \a path, which is in this item's coordinate system, to
+ \a item's coordinate system, and returns the mapped path.
+
+ If \a item is 0, this function returns the same as mapToScene().
+
+ \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
+ Graphics View Coordinate System}
+*/
+QPainterPath QGraphicsItem::mapToItem(const QGraphicsItem *item, const QPainterPath &path) const
+{
+ if (item)
+ return itemTransform(item).map(path);
+ return mapToScene(path);
+}
+
+/*!
+ Maps the path \a path, which is in this item's coordinate system, to
+ its parent's coordinate system, and returns the mapped path. If the
+ item has no parent, \a path will be mapped to the scene's coordinate
+ system.
+
+ \sa mapToScene(), mapToItem(), mapFromParent(), {The Graphics View
+ Coordinate System}
+*/
+QPainterPath QGraphicsItem::mapToParent(const QPainterPath &path) const
+{
+ // COMBINE
+ if (!d_ptr->transformData)
+ return path.translated(d_ptr->pos);
+ return d_ptr->transformToParent().map(path);
+}
+
+/*!
+ Maps the path \a path, which is in this item's coordinate system, to
+ the scene's coordinate system, and returns the mapped path.
+
+ \sa mapToParent(), mapToItem(), mapFromScene(), {The Graphics View
+ Coordinate System}
+*/
+QPainterPath QGraphicsItem::mapToScene(const QPainterPath &path) const
+{
+ if (d_ptr->hasTranslateOnlySceneTransform())
+ return path.translated(d_ptr->sceneTransform.dx(), d_ptr->sceneTransform.dy());
+ return d_ptr->sceneTransform.map(path);
+}
+
+/*!
+ Maps the point \a point, which is in \a item's coordinate system, to this
+ item's coordinate system, and returns the mapped coordinate.
+
+ If \a item is 0, this function returns the same as mapFromScene().
+
+ \sa itemTransform(), mapFromParent(), mapFromScene(), transform(), mapToItem(), {The Graphics
+ View Coordinate System}
+*/
+QPointF QGraphicsItem::mapFromItem(const QGraphicsItem *item, const QPointF &point) const
+{
+ if (item)
+ return item->itemTransform(this).map(point);
+ return mapFromScene(point);
+}
+
+/*!
+ \fn QPointF QGraphicsItem::mapFromItem(const QGraphicsItem *item, qreal x, qreal y) const
+ \overload
+
+ This convenience function is equivalent to calling mapFromItem(\a item,
+ QPointF(\a x, \a y)).
+*/
+
+/*!
+ Maps the point \a point, which is in this item's parent's coordinate
+ system, to this item's coordinate system, and returns the mapped
+ coordinate.
+
+ \sa mapFromItem(), mapFromScene(), transform(), mapToParent(), {The Graphics
+ View Coordinate System}
+*/
+QPointF QGraphicsItem::mapFromParent(const QPointF &point) const
+{
+ // COMBINE
+ if (d_ptr->transformData)
+ return d_ptr->transformToParent().inverted().map(point);
+ return point - d_ptr->pos;
+}
+
+/*!
+ \fn QPointF QGraphicsItem::mapFromParent(qreal x, qreal y) const
+ \overload
+
+ This convenience function is equivalent to calling
+ mapFromParent(QPointF(\a x, \a y)).
+*/
+
+/*!
+ Maps the point \a point, which is in this item's scene's coordinate
+ system, to this item's coordinate system, and returns the mapped
+ coordinate.
+
+ \sa mapFromItem(), mapFromParent(), transform(), mapToScene(), {The Graphics
+ View Coordinate System}
+*/
+QPointF QGraphicsItem::mapFromScene(const QPointF &point) const
+{
+ if (d_ptr->hasTranslateOnlySceneTransform())
+ return QPointF(point.x() - d_ptr->sceneTransform.dx(), point.y() - d_ptr->sceneTransform.dy());
+ return d_ptr->sceneTransform.inverted().map(point);
+}
+
+/*!
+ \fn QPointF QGraphicsItem::mapFromScene(qreal x, qreal y) const
+ \overload
+
+ This convenience function is equivalent to calling mapFromScene(QPointF(\a
+ x, \a y)).
+*/
+
+/*!
+ Maps the rectangle \a rect, which is in \a item's coordinate system, to
+ this item's coordinate system, and returns the mapped rectangle as a
+ polygon.
+
+ If \a item is 0, this function returns the same as mapFromScene()
+
+ \sa itemTransform(), mapToItem(), mapFromParent(), transform(), {The Graphics View Coordinate
+ System}
+*/
+QPolygonF QGraphicsItem::mapFromItem(const QGraphicsItem *item, const QRectF &rect) const
+{
+ if (item)
+ return item->itemTransform(this).map(rect);
+ return mapFromScene(rect);
+}
+
+/*!
+ \fn QPolygonF QGraphicsItem::mapFromItem(const QGraphicsItem *item, qreal x, qreal y, qreal w, qreal h) const
+ \since 4.3
+
+ This convenience function is equivalent to calling mapFromItem(item, QRectF(\a x, \a y, \a w, \a h)).
+*/
+
+/*!
+ Maps the rectangle \a rect, which is in this item's parent's coordinate
+ system, to this item's coordinate system, and returns the mapped rectangle
+ as a polygon.
+
+ \sa mapToParent(), mapFromItem(), transform(), {The Graphics View Coordinate
+ System}
+*/
+QPolygonF QGraphicsItem::mapFromParent(const QRectF &rect) const
+{
+ // COMBINE
+ if (!d_ptr->transformData)
+ return rect.translated(-d_ptr->pos);
+ return d_ptr->transformToParent().inverted().map(rect);
+}
+
+/*!
+ \fn QPolygonF QGraphicsItem::mapFromParent(qreal x, qreal y, qreal w, qreal h) const
+ \since 4.3
+
+ This convenience function is equivalent to calling mapFromItem(QRectF(\a x, \a y, \a w, \a h)).
+*/
+
+/*!
+ Maps the rectangle \a rect, which is in this item's scene's coordinate
+ system, to this item's coordinate system, and returns the mapped rectangle
+ as a polygon.
+
+ \sa mapToScene(), mapFromItem(), transform(), {The Graphics View Coordinate
+ System}
+*/
+QPolygonF QGraphicsItem::mapFromScene(const QRectF &rect) const
+{
+ if (d_ptr->hasTranslateOnlySceneTransform())
+ return rect.translated(-d_ptr->sceneTransform.dx(), -d_ptr->sceneTransform.dy());
+ return d_ptr->sceneTransform.inverted().map(rect);
+}
+
+/*!
+ \fn QPolygonF QGraphicsItem::mapFromScene(qreal x, qreal y, qreal w, qreal h) const
+ \since 4.3
+
+ This convenience function is equivalent to calling mapFromScene(QRectF(\a x, \a y, \a w, \a h)).
+*/
+
+/*!
+ Maps the polygon \a polygon, which is in \a item's coordinate system, to
+ this item's coordinate system, and returns the mapped polygon.
+
+ If \a item is 0, this function returns the same as mapFromScene().
+
+ \sa itemTransform(), mapToItem(), mapFromParent(), transform(), {The
+ Graphics View Coordinate System}
+*/
+QPolygonF QGraphicsItem::mapFromItem(const QGraphicsItem *item, const QPolygonF &polygon) const
+{
+ if (item)
+ return item->itemTransform(this).map(polygon);
+ return mapFromScene(polygon);
+}
+
+/*!
+ Maps the polygon \a polygon, which is in this item's parent's coordinate
+ system, to this item's coordinate system, and returns the mapped polygon.
+
+ \sa mapToParent(), mapToItem(), transform(), {The Graphics View Coordinate
+ System}
+*/
+QPolygonF QGraphicsItem::mapFromParent(const QPolygonF &polygon) const
+{
+ // COMBINE
+ if (!d_ptr->transformData)
+ return polygon.translated(-d_ptr->pos);
+ return d_ptr->transformToParent().inverted().map(polygon);
+}
+
+/*!
+ Maps the polygon \a polygon, which is in this item's scene's coordinate
+ system, to this item's coordinate system, and returns the mapped polygon.
+
+ \sa mapToScene(), mapFromParent(), transform(), {The Graphics View Coordinate
+ System}
+*/
+QPolygonF QGraphicsItem::mapFromScene(const QPolygonF &polygon) const
+{
+ if (d_ptr->hasTranslateOnlySceneTransform())
+ return polygon.translated(-d_ptr->sceneTransform.dx(), -d_ptr->sceneTransform.dy());
+ return d_ptr->sceneTransform.inverted().map(polygon);
+}
+
+/*!
+ Maps the path \a path, which is in \a item's coordinate system, to
+ this item's coordinate system, and returns the mapped path.
+
+ If \a item is 0, this function returns the same as mapFromScene().
+
+ \sa itemTransform(), mapFromParent(), mapFromScene(), mapToItem(), {The
+ Graphics View Coordinate System}
+*/
+QPainterPath QGraphicsItem::mapFromItem(const QGraphicsItem *item, const QPainterPath &path) const
+{
+ if (item)
+ return item->itemTransform(this).map(path);
+ return mapFromScene(path);
+}
+
+/*!
+ Maps the path \a path, which is in this item's parent's coordinate
+ system, to this item's coordinate system, and returns the mapped path.
+
+ \sa mapFromScene(), mapFromItem(), mapToParent(), {The Graphics View
+ Coordinate System}
+*/
+QPainterPath QGraphicsItem::mapFromParent(const QPainterPath &path) const
+{
+ // COMBINE
+ if (!d_ptr->transformData)
+ return path.translated(-d_ptr->pos);
+ return d_ptr->transformToParent().inverted().map(path);
+}
+
+/*!
+ Maps the path \a path, which is in this item's scene's coordinate
+ system, to this item's coordinate system, and returns the mapped path.
+
+ \sa mapFromParent(), mapFromItem(), mapToScene(), {The Graphics View
+ Coordinate System}
+*/
+QPainterPath QGraphicsItem::mapFromScene(const QPainterPath &path) const
+{
+ if (d_ptr->hasTranslateOnlySceneTransform())
+ return path.translated(-d_ptr->sceneTransform.dx(), -d_ptr->sceneTransform.dy());
+ return d_ptr->sceneTransform.inverted().map(path);
+}
+
+/*!
+ Returns true if this item is an ancestor of \a child (i.e., if this item
+ is \a child's parent, or one of \a child's parent's ancestors).
+
+ \sa parentItem()
+*/
+bool QGraphicsItem::isAncestorOf(const QGraphicsItem *child) const
+{
+ if (!child || child == this)
+ return false;
+ if (child->d_ptr->depth() < d_ptr->depth())
+ return false;
+ const QGraphicsItem *ancestor = child;
+ while ((ancestor = ancestor->d_ptr->parent)) {
+ if (ancestor == this)
+ return true;
+ }
+ return false;
+}
+
+/*!
+ \since 4.4
+
+ Returns the closest common ancestor item of this item and \a other, or 0
+ if either \a other is 0, or there is no common ancestor.
+
+ \sa isAncestorOf()
+*/
+QGraphicsItem *QGraphicsItem::commonAncestorItem(const QGraphicsItem *other) const
+{
+ if (!other)
+ return 0;
+ if (other == this)
+ return const_cast<QGraphicsItem *>(this);
+ const QGraphicsItem *thisw = this;
+ const QGraphicsItem *otherw = other;
+ int thisDepth = d_ptr->depth();
+ int otherDepth = other->d_ptr->depth();
+ while (thisDepth > otherDepth) {
+ thisw = thisw->d_ptr->parent;
+ --thisDepth;
+ }
+ while (otherDepth > thisDepth) {
+ otherw = otherw->d_ptr->parent;
+ --otherDepth;
+ }
+ while (thisw && thisw != otherw) {
+ thisw = thisw->d_ptr->parent;
+ otherw = otherw->d_ptr->parent;
+ }
+ return const_cast<QGraphicsItem *>(thisw);
+}
+
+/*!
+ \since 4,4
+ Returns true if this item is currently under the mouse cursor in one of
+ the views; otherwise, false is returned.
+
+ \sa QGraphicsScene::views(), QCursor::pos()
+*/
+bool QGraphicsItem::isUnderMouse() const
+{
+ Q_D(const QGraphicsItem);
+ if (!d->scene)
+ return false;
+
+ QPoint cursorPos = QCursor::pos();
+ foreach (QGraphicsView *view, d->scene->views()) {
+ if (contains(mapFromScene(view->mapToScene(view->mapFromGlobal(cursorPos)))))
+ return true;
+ }
+ return false;
+}
+
+/*!
+ Returns this item's custom data for the key \a key as a QVariant.
+
+ Custom item data is useful for storing arbitrary properties in any
+ item. Example:
+
+ \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 11
+
+ Qt does not use this feature for storing data; it is provided solely
+ for the convenience of the user.
+
+ \sa setData()
+*/
+QVariant QGraphicsItem::data(int key) const
+{
+ QGraphicsItemCustomDataStore *store = qt_dataStore();
+ if (!store->data.contains(this))
+ return QVariant();
+ return store->data.value(this).value(key);
+}
+
+/*!
+ Sets this item's custom data for the key \a key to \a value.
+
+ Custom item data is useful for storing arbitrary properties for any
+ item. Qt does not use this feature for storing data; it is provided solely
+ for the convenience of the user.
+
+ \sa data()
+*/
+void QGraphicsItem::setData(int key, const QVariant &value)
+{
+ qt_dataStore()->data[this][key] = value;
+}
+
+/*!
+ \fn T qgraphicsitem_cast(QGraphicsItem *item)
+ \relates QGraphicsItem
+ \since 4.2
+
+ Returns the given \a item cast to type T if \a item is of type T;
+ otherwise, 0 is returned.
+
+ \note To make this function work correctly with custom items, reimplement
+ the \l{QGraphicsItem::}{type()} function for each custom QGraphicsItem
+ subclass.
+
+ \sa QGraphicsItem::type(), QGraphicsItem::UserType
+*/
+
+/*!
+ Returns the type of an item as an int. All standard graphicsitem classes
+ are associated with a unique value; see QGraphicsItem::Type. This type
+ information is used by qgraphicsitem_cast() to distinguish between types.
+
+ The default implementation (in QGraphicsItem) returns UserType.
+
+ To enable use of qgraphicsitem_cast() with a custom item, reimplement this
+ function and declare a Type enum value equal to your custom item's type.
+ Custom items must return a value larger than or equal to UserType (65536).
+
+ For example:
+
+ \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp QGraphicsItem type
+
+ \sa UserType
+*/
+int QGraphicsItem::type() const
+{
+ return (int)UserType;
+}
+
+/*!
+ Installs an event filter for this item on \a filterItem, causing
+ all events for this item to first pass through \a filterItem's
+ sceneEventFilter() function.
+
+ To filter another item's events, install this item as an event filter
+ for the other item. Example:
+
+ \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 12
+
+ An item can only filter events for other items in the same
+ scene. Also, an item cannot filter its own events; instead, you
+ can reimplement sceneEvent() directly.
+
+ Items must belong to a scene for scene event filters to be installed and
+ used.
+
+ \sa removeSceneEventFilter(), sceneEventFilter(), sceneEvent()
+*/
+void QGraphicsItem::installSceneEventFilter(QGraphicsItem *filterItem)
+{
+ if (!d_ptr->scene) {
+ qWarning("QGraphicsItem::installSceneEventFilter: event filters can only be installed"
+ " on items in a scene.");
+ return;
+ }
+ if (d_ptr->scene != filterItem->scene()) {
+ qWarning("QGraphicsItem::installSceneEventFilter: event filters can only be installed"
+ " on items in the same scene.");
+ return;
+ }
+ d_ptr->scene->d_func()->installSceneEventFilter(this, filterItem);
+}
+
+/*!
+ Removes an event filter on this item from \a filterItem.
+
+ \sa installSceneEventFilter()
+*/
+void QGraphicsItem::removeSceneEventFilter(QGraphicsItem *filterItem)
+{
+ if (!d_ptr->scene || d_ptr->scene != filterItem->scene())
+ return;
+ d_ptr->scene->d_func()->removeSceneEventFilter(this, filterItem);
+}
+
+/*!
+ Filters events for the item \a watched. \a event is the filtered
+ event.
+
+ Reimplementing this function in a subclass makes it possible
+ for the item to be used as an event filter for other items,
+ intercepting all the events send to those items before they are
+ able to respond.
+
+ Reimplementations must return true to prevent further processing of
+ a given event, ensuring that it will not be delivered to the watched
+ item, or return false to indicate that the event should be propagated
+ further by the event system.
+
+ \sa installSceneEventFilter()
+*/
+bool QGraphicsItem::sceneEventFilter(QGraphicsItem *watched, QEvent *event)
+{
+ Q_UNUSED(watched);
+ Q_UNUSED(event);
+ return false;
+}
+
+/*!
+ This virtual function receives events to this item. Reimplement
+ this function to intercept events before they are dispatched to
+ the specialized event handlers contextMenuEvent(), focusInEvent(),
+ focusOutEvent(), hoverEnterEvent(), hoverMoveEvent(),
+ hoverLeaveEvent(), keyPressEvent(), keyReleaseEvent(),
+ mousePressEvent(), mouseReleaseEvent(), mouseMoveEvent(), and
+ mouseDoubleClickEvent().
+
+ Returns true if the event was recognized and handled; otherwise, (e.g., if
+ the event type was not recognized,) false is returned.
+
+ \a event is the intercepted event.
+*/
+bool QGraphicsItem::sceneEvent(QEvent *event)
+{
+ if (d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorHandlesChildEvents) {
+ if (event->type() == QEvent::HoverEnter || event->type() == QEvent::HoverLeave
+ || event->type() == QEvent::DragEnter || event->type() == QEvent::DragLeave) {
+ // Hover enter and hover leave events for children are ignored;
+ // hover move events are forwarded.
+ return true;
+ }
+
+ QGraphicsItem *handler = this;
+ do {
+ handler = handler->d_ptr->parent;
+ Q_ASSERT(handler);
+ } while (handler->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorHandlesChildEvents);
+ // Forward the event to the closest parent that handles child
+ // events, mapping existing item-local coordinates to its
+ // coordinate system.
+ d_ptr->remapItemPos(event, handler);
+ handler->sceneEvent(event);
+ return true;
+ }
+
+ if (event->type() == QEvent::FocusOut) {
+ focusOutEvent(static_cast<QFocusEvent *>(event));
+ return true;
+ }
+
+ if (!d_ptr->visible) {
+ // Eaten
+ return true;
+ }
+
+ switch (event->type()) {
+ case QEvent::FocusIn:
+ focusInEvent(static_cast<QFocusEvent *>(event));
+ break;
+ case QEvent::GraphicsSceneContextMenu:
+ contextMenuEvent(static_cast<QGraphicsSceneContextMenuEvent *>(event));
+ break;
+ case QEvent::GraphicsSceneDragEnter:
+ dragEnterEvent(static_cast<QGraphicsSceneDragDropEvent *>(event));
+ break;
+ case QEvent::GraphicsSceneDragMove:
+ dragMoveEvent(static_cast<QGraphicsSceneDragDropEvent *>(event));
+ break;
+ case QEvent::GraphicsSceneDragLeave:
+ dragLeaveEvent(static_cast<QGraphicsSceneDragDropEvent *>(event));
+ break;
+ case QEvent::GraphicsSceneDrop:
+ dropEvent(static_cast<QGraphicsSceneDragDropEvent *>(event));
+ break;
+ case QEvent::GraphicsSceneHoverEnter:
+ hoverEnterEvent(static_cast<QGraphicsSceneHoverEvent *>(event));
+ break;
+ case QEvent::GraphicsSceneHoverMove:
+ hoverMoveEvent(static_cast<QGraphicsSceneHoverEvent *>(event));
+ break;
+ case QEvent::GraphicsSceneHoverLeave:
+ hoverLeaveEvent(static_cast<QGraphicsSceneHoverEvent *>(event));
+ break;
+ case QEvent::GraphicsSceneMouseMove:
+ mouseMoveEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
+ break;
+ case QEvent::GraphicsSceneMousePress:
+ mousePressEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
+ break;
+ case QEvent::GraphicsSceneMouseRelease:
+ mouseReleaseEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
+ break;
+ case QEvent::GraphicsSceneMouseDoubleClick:
+ mouseDoubleClickEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
+ break;
+ case QEvent::GraphicsSceneWheel:
+ wheelEvent(static_cast<QGraphicsSceneWheelEvent *>(event));
+ break;
+ case QEvent::KeyPress: {
+ QKeyEvent *k = static_cast<QKeyEvent *>(event);
+ if (k->key() == Qt::Key_Tab || k->key() == Qt::Key_Backtab) {
+ if (!(k->modifiers() & (Qt::ControlModifier | Qt::AltModifier))) { //### Add MetaModifier?
+ bool res = false;
+ if (k->key() == Qt::Key_Backtab
+ || (k->key() == Qt::Key_Tab && (k->modifiers() & Qt::ShiftModifier))) {
+ if (d_ptr->isWidget) {
+ res = static_cast<QGraphicsWidget *>(this)->focusNextPrevChild(false);
+ } else if (d_ptr->scene) {
+ res = d_ptr->scene->focusNextPrevChild(false);
+ }
+ } else if (k->key() == Qt::Key_Tab) {
+ if (d_ptr->isWidget) {
+ res = static_cast<QGraphicsWidget *>(this)->focusNextPrevChild(true);
+ } else if (d_ptr->scene) {
+ res = d_ptr->scene->focusNextPrevChild(true);
+ }
+ }
+ if (!res)
+ event->ignore();
+ return true;
+ }
+ }
+ keyPressEvent(static_cast<QKeyEvent *>(event));
+ break;
+ }
+ case QEvent::KeyRelease:
+ keyReleaseEvent(static_cast<QKeyEvent *>(event));
+ break;
+ case QEvent::InputMethod:
+ inputMethodEvent(static_cast<QInputMethodEvent *>(event));
+ break;
+ case QEvent::WindowActivate:
+ case QEvent::WindowDeactivate:
+ // Propagate panel activation.
+ if (d_ptr->scene) {
+ for (int i = 0; i < d_ptr->children.size(); ++i) {
+ QGraphicsItem *child = d_ptr->children.at(i);
+ if (child->isVisible() && !child->isPanel()) {
+ if (!(child->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorHandlesChildEvents))
+ d_ptr->scene->sendEvent(child, event);
+ }
+ }
+ }
+ break;
+ default:
+ return false;
+ }
+
+ return true;
+}
+
+/*!
+ This event handler can be reimplemented in a subclass to process context
+ menu events. The \a event parameter contains details about the event to
+ be handled.
+
+ If you ignore the event, (i.e., by calling QEvent::ignore(),) \a event
+ will propagate to any item beneath this item. If no items accept the
+ event, it will be ignored by the scene, and propagate to the view.
+
+ It's common to open a QMenu in response to receiving a context menu
+ event. Example:
+
+ \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 13
+
+ The default implementation ignores the event.
+
+ \sa sceneEvent()
+*/
+void QGraphicsItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
+{
+ event->ignore();
+}
+
+/*!
+ This event handler, for event \a event, can be reimplemented to receive
+ drag enter events for this item. Drag enter events are generated as the
+ cursor enters the item's area.
+
+ By accepting the event, (i.e., by calling QEvent::accept(),) the item will
+ accept drop events, in addition to receiving drag move and drag
+ leave. Otherwise, the event will be ignored and propagate to the item
+ beneath. If the event is accepted, the item will receive a drag move event
+ before control goes back to the event loop.
+
+ A common implementation of dragEnterEvent accepts or ignores \a event
+ depending on the associated mime data in \a event. Example:
+
+ \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 14
+
+ Items do not receive drag and drop events by default; to enable this
+ feature, call \c setAcceptDrops(true).
+
+ The default implementation does nothing.
+
+ \sa dropEvent(), dragMoveEvent(), dragLeaveEvent()
+*/
+void QGraphicsItem::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
+{
+ Q_D(QGraphicsItem);
+ // binary compatibility workaround between 4.4 and 4.5
+ if (d->isProxyWidget())
+ static_cast<QGraphicsProxyWidget*>(this)->dragEnterEvent(event);
+}
+
+/*!
+ This event handler, for event \a event, can be reimplemented to receive
+ drag leave events for this item. Drag leave events are generated as the
+ cursor leaves the item's area. Most often you will not need to reimplement
+ this function, but it can be useful for resetting state in your item
+ (e.g., highlighting).
+
+ Calling QEvent::ignore() or QEvent::accept() on \a event has no effect.
+
+ Items do not receive drag and drop events by default; to enable this
+ feature, call \c setAcceptDrops(true).
+
+ The default implementation does nothing.
+
+ \sa dragEnterEvent(), dropEvent(), dragMoveEvent()
+*/
+void QGraphicsItem::dragLeaveEvent(QGraphicsSceneDragDropEvent *event)
+{
+ Q_D(QGraphicsItem);
+ // binary compatibility workaround between 4.4 and 4.5
+ if (d->isProxyWidget())
+ static_cast<QGraphicsProxyWidget*>(this)->dragLeaveEvent(event);
+}
+
+/*!
+ This event handler, for event \a event, can be reimplemented to receive
+ drag move events for this item. Drag move events are generated as the
+ cursor moves around inside the item's area. Most often you will not need
+ to reimplement this function; it is used to indicate that only parts of
+ the item can accept drops.
+
+ Calling QEvent::ignore() or QEvent::accept() on \a event toggles whether
+ or not the item will accept drops at the position from the event. By
+ default, \a event is accepted, indicating that the item allows drops at
+ the specified position.
+
+ Items do not receive drag and drop events by default; to enable this
+ feature, call \c setAcceptDrops(true).
+
+ The default implementation does nothing.
+
+ \sa dropEvent(), dragEnterEvent(), dragLeaveEvent()
+*/
+void QGraphicsItem::dragMoveEvent(QGraphicsSceneDragDropEvent *event)
+{
+ Q_D(QGraphicsItem);
+ // binary compatibility workaround between 4.4 and 4.5
+ if (d->isProxyWidget())
+ static_cast<QGraphicsProxyWidget*>(this)->dragMoveEvent(event);
+}
+
+/*!
+ This event handler, for event \a event, can be reimplemented to receive
+ drop events for this item. Items can only receive drop events if the last
+ drag move event was accepted.
+
+ Calling QEvent::ignore() or QEvent::accept() on \a event has no effect.
+
+ Items do not receive drag and drop events by default; to enable this
+ feature, call \c setAcceptDrops(true).
+
+ The default implementation does nothing.
+
+ \sa dragEnterEvent(), dragMoveEvent(), dragLeaveEvent()
+*/
+void QGraphicsItem::dropEvent(QGraphicsSceneDragDropEvent *event)
+{
+ Q_D(QGraphicsItem);
+ // binary compatibility workaround between 4.4 and 4.5
+ if (d->isProxyWidget())
+ static_cast<QGraphicsProxyWidget*>(this)->dropEvent(event);
+}
+
+/*!
+ This event handler, for event \a event, can be reimplemented to receive
+ focus in events for this item. The default implementation calls
+ ensureVisible().
+
+ \sa focusOutEvent(), sceneEvent(), setFocus()
+*/
+void QGraphicsItem::focusInEvent(QFocusEvent *event)
+{
+ Q_UNUSED(event);
+ update();
+}
+
+/*!
+ This event handler, for event \a event, can be reimplemented to receive
+ focus out events for this item. The default implementation does nothing.
+
+ \sa focusInEvent(), sceneEvent(), setFocus()
+*/
+void QGraphicsItem::focusOutEvent(QFocusEvent *event)
+{
+ Q_UNUSED(event);
+ update();
+}
+
+/*!
+ This event handler, for event \a event, can be reimplemented to receive
+ hover enter events for this item. The default implementation calls
+ update(); otherwise it does nothing.
+
+ Calling QEvent::ignore() or QEvent::accept() on \a event has no effect.
+
+ \sa hoverMoveEvent(), hoverLeaveEvent(), sceneEvent(), setAcceptHoverEvents()
+*/
+void QGraphicsItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
+{
+ Q_UNUSED(event);
+ update();
+}
+
+/*!
+ This event handler, for event \a event, can be reimplemented to receive
+ hover move events for this item. The default implementation does nothing.
+
+ Calling QEvent::ignore() or QEvent::accept() on \a event has no effect.
+
+ \sa hoverEnterEvent(), hoverLeaveEvent(), sceneEvent(), setAcceptHoverEvents()
+*/
+void QGraphicsItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
+{
+ Q_UNUSED(event);
+}
+
+/*!
+ This event handler, for event \a event, can be reimplemented to receive
+ hover leave events for this item. The default implementation calls
+ update(); otherwise it does nothing.
+
+ Calling QEvent::ignore() or QEvent::accept() on \a event has no effect.
+
+ \sa hoverEnterEvent(), hoverMoveEvent(), sceneEvent(), setAcceptHoverEvents()
+*/
+void QGraphicsItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
+{
+ Q_UNUSED(event);
+ update();
+}
+
+/*!
+ This event handler, for event \a event, can be reimplemented to
+ receive key press events for this item. The default implementation
+ ignores the event. If you reimplement this handler, the event will by
+ default be accepted.
+
+ Note that key events are only received for items that set the
+ ItemIsFocusable flag, and that have keyboard input focus.
+
+ \sa keyReleaseEvent(), setFocus(), QGraphicsScene::setFocusItem(),
+ sceneEvent()
+*/
+void QGraphicsItem::keyPressEvent(QKeyEvent *event)
+{
+ event->ignore();
+}
+
+/*!
+ This event handler, for event \a event, can be reimplemented to receive
+ key release events for this item. The default implementation
+ ignores the event. If you reimplement this handler, the event will by
+ default be accepted.
+
+ Note that key events are only received for items that set the
+ ItemIsFocusable flag, and that have keyboard input focus.
+
+ \sa keyPressEvent(), setFocus(), QGraphicsScene::setFocusItem(),
+ sceneEvent()
+*/
+void QGraphicsItem::keyReleaseEvent(QKeyEvent *event)
+{
+ event->ignore();
+}
+
+/*!
+ This event handler, for event \a event, can be reimplemented to
+ receive mouse press events for this item. Mouse press events are
+ only delivered to items that accept the mouse button that is
+ pressed. By default, an item accepts all mouse buttons, but you
+ can change this by calling setAcceptedMouseButtons().
+
+ The mouse press event decides which item should become the mouse
+ grabber (see QGraphicsScene::mouseGrabberItem()). If you do not
+ reimplement this function, the press event will propagate to any
+ topmost item beneath this item, and no other mouse events will be
+ delivered to this item.
+
+ If you do reimplement this function, \a event will by default be
+ accepted (see QEvent::accept()), and this item is then the mouse
+ grabber. This allows the item to receive future move, release and
+ doubleclick events. If you call QEvent::ignore() on \a event, this
+ item will lose the mouse grab, and \a event will propagate to any
+ topmost item beneath. No further mouse events will be delivered to
+ this item unless a new mouse press event is received.
+
+ The default implementation handles basic item interaction, such as
+ selection and moving. If you want to keep the base implementation
+ when reimplementing this function, call
+ QGraphicsItem::mousePressEvent() in your reimplementation.
+
+ The event is \l{QEvent::ignore()}d for items that are neither
+ \l{QGraphicsItem::ItemIsMovable}{movable} nor
+ \l{QGraphicsItem::ItemIsSelectable}{selectable}.
+
+ \sa mouseMoveEvent(), mouseReleaseEvent(),
+ mouseDoubleClickEvent(), sceneEvent()
+*/
+void QGraphicsItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
+{
+ if (event->button() == Qt::LeftButton && (flags() & ItemIsSelectable)) {
+ bool multiSelect = (event->modifiers() & Qt::ControlModifier) != 0;
+ if (!multiSelect) {
+ if (!d_ptr->selected) {
+ if (QGraphicsScene *scene = d_ptr->scene) {
+ ++scene->d_func()->selectionChanging;
+ scene->clearSelection();
+ --scene->d_func()->selectionChanging;
+ }
+ setSelected(true);
+ }
+ }
+ } else if (!(flags() & ItemIsMovable)) {
+ event->ignore();
+ }
+ if (d_ptr->isWidget) {
+ // Qt::Popup closes when you click outside.
+ QGraphicsWidget *w = static_cast<QGraphicsWidget *>(this);
+ if ((w->windowFlags() & Qt::Popup) == Qt::Popup) {
+ event->accept();
+ if (!w->rect().contains(event->pos()))
+ w->close();
+ }
+ }
+}
+
+/*!
+ obsolete
+*/
+bool _qt_movableAncestorIsSelected(const QGraphicsItem *item)
+{
+ const QGraphicsItem *parent = item->parentItem();
+ return parent && (((parent->flags() & QGraphicsItem::ItemIsMovable) && parent->isSelected()) || _qt_movableAncestorIsSelected(parent));
+}
+
+bool QGraphicsItemPrivate::movableAncestorIsSelected(const QGraphicsItem *item)
+{
+ const QGraphicsItem *parent = item->d_ptr->parent;
+ return parent && (((parent->flags() & QGraphicsItem::ItemIsMovable) && parent->isSelected()) || _qt_movableAncestorIsSelected(parent));
+}
+
+/*!
+ This event handler, for event \a event, can be reimplemented to
+ receive mouse move events for this item. If you do receive this
+ event, you can be certain that this item also received a mouse
+ press event, and that this item is the current mouse grabber.
+
+ Calling QEvent::ignore() or QEvent::accept() on \a event has no
+ effect.
+
+ The default implementation handles basic item interaction, such as
+ selection and moving. If you want to keep the base implementation
+ when reimplementing this function, call
+ QGraphicsItem::mouseMoveEvent() in your reimplementation.
+
+ Please note that mousePressEvent() decides which graphics item it
+ is that receives mouse events. See the mousePressEvent()
+ description for details.
+
+ \sa mousePressEvent(), mouseReleaseEvent(),
+ mouseDoubleClickEvent(), sceneEvent()
+*/
+void QGraphicsItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
+{
+ if ((event->buttons() & Qt::LeftButton) && (flags() & ItemIsMovable)) {
+ // Determine the list of items that need to be moved.
+ QList<QGraphicsItem *> selectedItems;
+ QMap<QGraphicsItem *, QPointF> initialPositions;
+ if (d_ptr->scene) {
+ selectedItems = d_ptr->scene->selectedItems();
+ initialPositions = d_ptr->scene->d_func()->movingItemsInitialPositions;
+ if (initialPositions.isEmpty()) {
+ foreach (QGraphicsItem *item, selectedItems)
+ initialPositions[item] = item->pos();
+ initialPositions[this] = pos();
+ }
+ d_ptr->scene->d_func()->movingItemsInitialPositions = initialPositions;
+ }
+
+ // Find the active view.
+ QGraphicsView *view = 0;
+ if (event->widget())
+ view = qobject_cast<QGraphicsView *>(event->widget()->parentWidget());
+
+ // Move all selected items
+ int i = 0;
+ bool movedMe = false;
+ while (i <= selectedItems.size()) {
+ QGraphicsItem *item = 0;
+ if (i < selectedItems.size())
+ item = selectedItems.at(i);
+ else
+ item = this;
+ if (item == this) {
+ // Slightly clumsy-looking way to ensure that "this" is part
+ // of the list of items to move, this is to avoid allocations
+ // (appending this item to the list of selected items causes a
+ // detach).
+ if (movedMe)
+ break;
+ movedMe = true;
+ }
+
+ if ((item->flags() & ItemIsMovable) && !QGraphicsItemPrivate::movableAncestorIsSelected(item)) {
+ QPointF currentParentPos;
+ QPointF buttonDownParentPos;
+ if (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorIgnoresTransformations) {
+ // Items whose ancestors ignore transformations need to
+ // map screen coordinates to local coordinates, then map
+ // those to the parent.
+ QTransform viewToItemTransform = (item->deviceTransform(view->viewportTransform())).inverted();
+ currentParentPos = mapToParent(viewToItemTransform.map(QPointF(view->mapFromGlobal(event->screenPos()))));
+ buttonDownParentPos = mapToParent(viewToItemTransform.map(QPointF(view->mapFromGlobal(event->buttonDownScreenPos(Qt::LeftButton)))));
+ } else if (item->flags() & ItemIgnoresTransformations) {
+ // Root items that ignore transformations need to
+ // calculate their diff by mapping viewport coordinates
+ // directly to parent coordinates.
+ // COMBINE
+ QTransform itemTransform;
+ if (item->d_ptr->transformData)
+ itemTransform = item->d_ptr->transformData->computedFullTransform();
+ itemTransform.translate(item->d_ptr->pos.x(), item->d_ptr->pos.y());
+ QTransform viewToParentTransform = itemTransform
+ * (item->sceneTransform() * view->viewportTransform()).inverted();
+ currentParentPos = viewToParentTransform.map(QPointF(view->mapFromGlobal(event->screenPos())));
+ buttonDownParentPos = viewToParentTransform.map(QPointF(view->mapFromGlobal(event->buttonDownScreenPos(Qt::LeftButton))));
+ } else {
+ // All other items simply map from the scene.
+ currentParentPos = item->mapToParent(item->mapFromScene(event->scenePos()));
+ buttonDownParentPos = item->mapToParent(item->mapFromScene(event->buttonDownScenePos(Qt::LeftButton)));
+ }
+
+ item->setPos(initialPositions.value(item) + currentParentPos - buttonDownParentPos);
+
+ if (item->flags() & ItemIsSelectable)
+ item->setSelected(true);
+ }
+ ++i;
+ }
+
+ } else {
+ event->ignore();
+ }
+}
+
+/*!
+ This event handler, for event \a event, can be reimplemented to
+ receive mouse release events for this item.
+
+ Calling QEvent::ignore() or QEvent::accept() on \a event has no
+ effect.
+
+ The default implementation handles basic item interaction, such as
+ selection and moving. If you want to keep the base implementation
+ when reimplementing this function, call
+ QGraphicsItem::mouseReleaseEvent() in your reimplementation.
+
+ Please note that mousePressEvent() decides which graphics item it
+ is that receives mouse events. See the mousePressEvent()
+ description for details.
+
+ \sa mousePressEvent(), mouseMoveEvent(), mouseDoubleClickEvent(),
+ sceneEvent()
+*/
+void QGraphicsItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
+{
+ if (flags() & ItemIsSelectable) {
+ bool multiSelect = (event->modifiers() & Qt::ControlModifier) != 0;
+ if (event->scenePos() == event->buttonDownScenePos(Qt::LeftButton)) {
+ // The item didn't move
+ if (multiSelect) {
+ setSelected(!isSelected());
+ } else {
+ bool selectionChanged = false;
+ if (QGraphicsScene *scene = d_ptr->scene) {
+ ++scene->d_func()->selectionChanging;
+ // Clear everything but this item. Bypass
+ // QGraphicsScene::clearSelection()'s default behavior by
+ // temporarily removing this item from the selection list.
+ if (d_ptr->selected) {
+ scene->d_func()->selectedItems.remove(this);
+ foreach (QGraphicsItem *item, scene->d_func()->selectedItems) {
+ if (item->isSelected()) {
+ selectionChanged = true;
+ break;
+ }
+ }
+ }
+ scene->clearSelection();
+ if (d_ptr->selected)
+ scene->d_func()->selectedItems.insert(this);
+ --scene->d_func()->selectionChanging;
+ if (selectionChanged)
+ emit d_ptr->scene->selectionChanged();
+ }
+ setSelected(true);
+ }
+ }
+ }
+ if (d_ptr->scene && !event->buttons())
+ d_ptr->scene->d_func()->movingItemsInitialPositions.clear();
+}
+
+/*!
+ This event handler, for event \a event, can be reimplemented to
+ receive mouse doubleclick events for this item.
+
+ When doubleclicking an item, the item will first receive a mouse
+ press event, followed by a release event (i.e., a click), then a
+ doubleclick event, and finally a release event.
+
+ Calling QEvent::ignore() or QEvent::accept() on \a event has no
+ effect.
+
+ The default implementation calls mousePressEvent(). If you want to
+ keep the base implementation when reimplementing this function,
+ call QGraphicsItem::mouseDoubleClickEvent() in your
+ reimplementation.
+
+ Note that an item will not receive double click events if it is
+ neither \l {QGraphicsItem::ItemIsSelectable}{selectable} nor
+ \l{QGraphicsItem::ItemIsMovable}{movable} (single mouse clicks are
+ ignored in this case, and that stops the generation of double
+ clicks).
+
+ \sa mousePressEvent(), mouseMoveEvent(), mouseReleaseEvent(), sceneEvent()
+*/
+void QGraphicsItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
+{
+ mousePressEvent(event);
+}
+
+/*!
+ This event handler, for event \a event, can be reimplemented to receive
+ wheel events for this item. If you reimplement this function, \a event
+ will be accepted by default.
+
+ If you ignore the event, (i.e., by calling QEvent::ignore(),) it will
+ propagate to any item beneath this item. If no items accept the event, it
+ will be ignored by the scene, and propagate to the view (e.g., the view's
+ vertical scroll bar).
+
+ The default implementation ignores the event.
+
+ \sa sceneEvent()
+*/
+void QGraphicsItem::wheelEvent(QGraphicsSceneWheelEvent *event)
+{
+ event->ignore();
+}
+
+/*!
+ This event handler, for event \a event, can be reimplemented to receive
+ input method events for this item. The default implementation ignores the
+ event.
+
+ \sa inputMethodQuery(), sceneEvent()
+*/
+void QGraphicsItem::inputMethodEvent(QInputMethodEvent *event)
+{
+ event->ignore();
+}
+
+/*!
+ This method is only relevant for input items. It is used by the
+ input method to query a set of properties of the item to be able
+ to support complex input method operations, such as support for
+ surrounding text and reconversions. \a query specifies which
+ property is queried.
+
+ \sa inputMethodEvent(), QInputMethodEvent, QInputContext
+*/
+QVariant QGraphicsItem::inputMethodQuery(Qt::InputMethodQuery query) const
+{
+ if (isWidget()) {
+ // ### Qt 5: Remove. The reimplementation in
+ // QGraphicsProxyWidget solves this problem (but requires a
+ // recompile to take effect).
+ return d_ptr->inputMethodQueryHelper(query);
+ }
+
+ Q_UNUSED(query);
+ return QVariant();
+}
+
+/*!
+ Returns the current input method hints of this item.
+
+ Input method hints are only relevant for input items.
+ The hints are used by the input method to indicate how it should operate.
+ For example, if the Qt::ImhNumbersOnly flag is set, the input method may change
+ its visual components to reflect that only numbers can be entered.
+
+ The effect may vary between input method implementations.
+
+ \since 4.6
+
+ \sa setInputMethodHints(), inputMethodQuery(), QInputContext
+*/
+Qt::InputMethodHints QGraphicsItem::inputMethodHints() const
+{
+ Q_D(const QGraphicsItem);
+ return d->imHints;
+}
+
+/*!
+ Sets the current input method hints of this item to \a hints.
+
+ \since 4.6
+
+ \sa inputMethodHints(), inputMethodQuery(), QInputContext
+*/
+void QGraphicsItem::setInputMethodHints(Qt::InputMethodHints hints)
+{
+ Q_D(QGraphicsItem);
+ d->imHints = hints;
+ if (!hasFocus())
+ return;
+ d->scene->d_func()->updateInputMethodSensitivityInViews();
+#if !defined(QT_NO_IM) && (defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN))
+ QWidget *fw = QApplication::focusWidget();
+ if (!fw)
+ return;
+ for (int i = 0 ; i < scene()->views().count() ; ++i)
+ if (scene()->views().at(i) == fw)
+ if (QInputContext *inputContext = fw->inputContext())
+ inputContext->update();
+#endif
+}
+
+/*!
+ Updates the item's micro focus.
+
+ \since 4.7
+
+ \sa QInputContext
+*/
+void QGraphicsItem::updateMicroFocus()
+{
+#if !defined(QT_NO_IM) && (defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN))
+ if (QWidget *fw = QApplication::focusWidget()) {
+ if (scene()) {
+ for (int i = 0 ; i < scene()->views().count() ; ++i) {
+ if (scene()->views().at(i) == fw) {
+ if (QInputContext *inputContext = fw->inputContext()) {
+ inputContext->update();
+#ifndef QT_NO_ACCESSIBILITY
+ // ##### is this correct
+ if (toGraphicsObject())
+ QAccessible::updateAccessibility(toGraphicsObject(), 0, QAccessible::StateChanged);
+#endif
+ break;
+ }
+ }
+ }
+ }
+ }
+#endif
+}
+
+/*!
+ This virtual function is called by QGraphicsItem to notify custom items
+ that some part of the item's state changes. By reimplementing this
+ function, your can react to a change, and in some cases, (depending on \a
+ change,) adjustments can be made.
+
+ \a change is the parameter of the item that is changing. \a value is the
+ new value; the type of the value depends on \a change.
+
+ Example:
+
+ \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 15
+
+ The default implementation does nothing, and returns \a value.
+
+ Note: Certain QGraphicsItem functions cannot be called in a
+ reimplementation of this function; see the GraphicsItemChange
+ documentation for details.
+
+ \sa GraphicsItemChange
+*/
+QVariant QGraphicsItem::itemChange(GraphicsItemChange change, const QVariant &value)
+{
+ Q_UNUSED(change);
+ return value;
+}
+
+/*!
+ \internal
+
+ Note: This is provided as a hook to avoid future problems related
+ to adding virtual functions.
+*/
+bool QGraphicsItem::supportsExtension(Extension extension) const
+{
+ Q_UNUSED(extension);
+ return false;
+}
+
+/*!
+ \internal
+
+ Note: This is provided as a hook to avoid future problems related
+ to adding virtual functions.
+*/
+void QGraphicsItem::setExtension(Extension extension, const QVariant &variant)
+{
+ Q_UNUSED(extension);
+ Q_UNUSED(variant);
+}
+
+/*!
+ \internal
+
+ Note: This is provided as a hook to avoid future problems related
+ to adding virtual functions.
+*/
+QVariant QGraphicsItem::extension(const QVariant &variant) const
+{
+ Q_UNUSED(variant);
+ return QVariant();
+}
+
+/*!
+ \internal
+
+ Adds this item to the scene's index. Called in conjunction with
+ removeFromIndex() to ensure the index bookkeeping is correct when
+ the item's position, transformation or shape changes.
+*/
+void QGraphicsItem::addToIndex()
+{
+ if (d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) {
+ // ### add to child index only if applicable
+ return;
+ }
+ if (d_ptr->scene)
+ d_ptr->scene->d_func()->index->addItem(this);
+}
+
+/*!
+ \internal
+
+ Removes this item from the scene's index. Called in conjunction
+ with addToIndex() to ensure the index bookkeeping is correct when
+ the item's position, transformation or shape changes.
+*/
+void QGraphicsItem::removeFromIndex()
+{
+ if (d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) {
+ // ### remove from child index only if applicable
+ return;
+ }
+ if (d_ptr->scene)
+ d_ptr->scene->d_func()->index->removeItem(this);
+}
+
+/*!
+ Prepares the item for a geometry change. Call this function before
+ changing the bounding rect of an item to keep QGraphicsScene's index up to
+ date.
+
+ prepareGeometryChange() will call update() if this is necessary.
+
+ Example:
+
+ \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 16
+
+ \sa boundingRect()
+*/
+void QGraphicsItem::prepareGeometryChange()
+{
+ if (d_ptr->inDestructor)
+ return;
+ if (d_ptr->scene) {
+ d_ptr->scene->d_func()->dirtyGrowingItemsBoundingRect = true;
+ d_ptr->geometryChanged = 1;
+ d_ptr->paintedViewBoundingRectsNeedRepaint = 1;
+ d_ptr->notifyBoundingRectChanged = !d_ptr->inSetPosHelper;
+
+ QGraphicsScenePrivate *scenePrivate = d_ptr->scene->d_func();
+ scenePrivate->index->prepareBoundingRectChange(this);
+ scenePrivate->markDirty(this, QRectF(), /*invalidateChildren=*/true, /*force=*/false,
+ /*ignoreOpacity=*/ false, /*removingItemFromScene=*/ false,
+ /*updateBoundingRect=*/true);
+
+ // For compatibility reasons, we have to update the item's old geometry
+ // if someone is connected to the changed signal or the scene has no views.
+ // Note that this has to be done *after* markDirty to ensure that
+ // _q_processDirtyItems is called before _q_emitUpdated.
+ if (scenePrivate->isSignalConnected(scenePrivate->changedSignalIndex)
+ || scenePrivate->views.isEmpty()) {
+ if (d_ptr->hasTranslateOnlySceneTransform()) {
+ d_ptr->scene->update(boundingRect().translated(d_ptr->sceneTransform.dx(),
+ d_ptr->sceneTransform.dy()));
+ } else {
+ d_ptr->scene->update(d_ptr->sceneTransform.mapRect(boundingRect()));
+ }
+ }
+ }
+
+ d_ptr->markParentDirty(/*updateBoundingRect=*/true);
+}
+
+/*!
+ \internal
+
+ Highlights \a item as selected.
+
+ NOTE: This function is a duplicate of qt_graphicsItem_highlightSelected() in
+ qgraphicssvgitem.cpp!
+*/
+static void qt_graphicsItem_highlightSelected(
+ QGraphicsItem *item, QPainter *painter, const QStyleOptionGraphicsItem *option)
+{
+ const QRectF murect = painter->transform().mapRect(QRectF(0, 0, 1, 1));
+ if (qFuzzyIsNull(qMax(murect.width(), murect.height())))
+ return;
+
+ const QRectF mbrect = painter->transform().mapRect(item->boundingRect());
+ if (qMin(mbrect.width(), mbrect.height()) < qreal(1.0))
+ return;
+
+ qreal itemPenWidth;
+ switch (item->type()) {
+ case QGraphicsEllipseItem::Type:
+ itemPenWidth = static_cast<QGraphicsEllipseItem *>(item)->pen().widthF();
+ break;
+ case QGraphicsPathItem::Type:
+ itemPenWidth = static_cast<QGraphicsPathItem *>(item)->pen().widthF();
+ break;
+ case QGraphicsPolygonItem::Type:
+ itemPenWidth = static_cast<QGraphicsPolygonItem *>(item)->pen().widthF();
+ break;
+ case QGraphicsRectItem::Type:
+ itemPenWidth = static_cast<QGraphicsRectItem *>(item)->pen().widthF();
+ break;
+ case QGraphicsSimpleTextItem::Type:
+ itemPenWidth = static_cast<QGraphicsSimpleTextItem *>(item)->pen().widthF();
+ break;
+ case QGraphicsLineItem::Type:
+ itemPenWidth = static_cast<QGraphicsLineItem *>(item)->pen().widthF();
+ break;
+ default:
+ itemPenWidth = 1.0;
+ }
+ const qreal pad = itemPenWidth / 2;
+
+ const qreal penWidth = 0; // cosmetic pen
+
+ const QColor fgcolor = option->palette.windowText().color();
+ const QColor bgcolor( // ensure good contrast against fgcolor
+ fgcolor.red() > 127 ? 0 : 255,
+ fgcolor.green() > 127 ? 0 : 255,
+ fgcolor.blue() > 127 ? 0 : 255);
+
+ painter->setPen(QPen(bgcolor, penWidth, Qt::SolidLine));
+ painter->setBrush(Qt::NoBrush);
+ painter->drawRect(item->boundingRect().adjusted(pad, pad, -pad, -pad));
+
+ painter->setPen(QPen(option->palette.windowText(), 0, Qt::DashLine));
+ painter->setBrush(Qt::NoBrush);
+ painter->drawRect(item->boundingRect().adjusted(pad, pad, -pad, -pad));
+}
+
+/*!
+ \class QGraphicsObject
+ \brief The QGraphicsObject class provides a base class for all graphics items that
+ require signals, slots and properties.
+ \since 4.6
+ \ingroup graphicsview-api
+
+ The class extends a QGraphicsItem with QObject's signal/slot and property mechanisms.
+ It maps many of QGraphicsItem's basic setters and getters to properties and adds notification
+ signals for many of them.
+
+ \section1 Parents and Children
+
+ Each graphics object can be constructed with a parent item. This ensures that the
+ item will be destroyed when its parent item is destroyed. Although QGraphicsObject
+ inherits from both QObject and QGraphicsItem, you should use the functions provided
+ by QGraphicsItem, \e not QObject, to manage the relationships between parent and
+ child items.
+
+ The relationships between items can be explored using the parentItem() and childItems()
+ functions. In the hierarchy of items in a scene, the parentObject() and parentWidget()
+ functions are the equivalent of the QWidget::parent() and QWidget::parentWidget()
+ functions for QWidget subclasses.
+
+ \sa QGraphicsWidget
+*/
+
+/*!
+ Constructs a QGraphicsObject with \a parent.
+*/
+QGraphicsObject::QGraphicsObject(QGraphicsItem *parent)
+ : QGraphicsItem(parent)
+{
+ QGraphicsItem::d_ptr->isObject = true;
+}
+
+/*!
+ \internal
+*/
+QGraphicsObject::QGraphicsObject(QGraphicsItemPrivate &dd, QGraphicsItem *parent, QGraphicsScene *scene)
+ : QGraphicsItem(dd, parent, scene)
+{
+ QGraphicsItem::d_ptr->isObject = true;
+}
+
+#ifndef QT_NO_GESTURES
+/*!
+ Subscribes the graphics object to the given \a gesture with specific \a flags.
+
+ \sa ungrabGesture(), QGestureEvent
+*/
+void QGraphicsObject::grabGesture(Qt::GestureType gesture, Qt::GestureFlags flags)
+{
+ bool contains = QGraphicsItem::d_ptr->gestureContext.contains(gesture);
+ QGraphicsItem::d_ptr->gestureContext.insert(gesture, flags);
+ if (!contains && QGraphicsItem::d_ptr->scene)
+ QGraphicsItem::d_ptr->scene->d_func()->grabGesture(this, gesture);
+}
+
+/*!
+ Unsubscribes the graphics object from the given \a gesture.
+
+ \sa grabGesture(), QGestureEvent
+*/
+void QGraphicsObject::ungrabGesture(Qt::GestureType gesture)
+{
+ if (QGraphicsItem::d_ptr->gestureContext.remove(gesture) && QGraphicsItem::d_ptr->scene)
+ QGraphicsItem::d_ptr->scene->d_func()->ungrabGesture(this, gesture);
+}
+#endif // QT_NO_GESTURES
+
+/*!
+ Updates the item's micro focus. This is slot for convenience.
+
+ \since 4.7
+
+ \sa QInputContext
+*/
+void QGraphicsObject::updateMicroFocus()
+{
+ QGraphicsItem::updateMicroFocus();
+}
+
+void QGraphicsItemPrivate::children_append(QDeclarativeListProperty<QGraphicsObject> *list, QGraphicsObject *item)
+{
+ if (item) {
+ QGraphicsObject *graphicsObject = static_cast<QGraphicsObject *>(list->object);
+ if (QGraphicsItemPrivate::get(graphicsObject)->sendParentChangeNotification) {
+ item->setParentItem(graphicsObject);
+ } else {
+ QGraphicsItemPrivate::get(item)->setParentItemHelper(graphicsObject, 0, 0);
+ }
+ }
+}
+
+int QGraphicsItemPrivate::children_count(QDeclarativeListProperty<QGraphicsObject> *list)
+{
+ QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(static_cast<QGraphicsObject *>(list->object));
+ return d->children.count();
+}
+
+QGraphicsObject *QGraphicsItemPrivate::children_at(QDeclarativeListProperty<QGraphicsObject> *list, int index)
+{
+ QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(static_cast<QGraphicsObject *>(list->object));
+ if (index >= 0 && index < d->children.count())
+ return d->children.at(index)->toGraphicsObject();
+ else
+ return 0;
+}
+
+void QGraphicsItemPrivate::children_clear(QDeclarativeListProperty<QGraphicsObject> *list)
+{
+ QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(static_cast<QGraphicsObject *>(list->object));
+ int childCount = d->children.count();
+ if (d->sendParentChangeNotification) {
+ for (int index = 0; index < childCount; index++)
+ d->children.at(0)->setParentItem(0);
+ } else {
+ for (int index = 0; index < childCount; index++)
+ QGraphicsItemPrivate::get(d->children.at(0))->setParentItemHelper(0, 0, 0);
+ }
+}
+
+/*!
+ Returns a list of this item's children.
+
+ The items are sorted by stacking order. This takes into account both the
+ items' insertion order and their Z-values.
+
+*/
+QDeclarativeListProperty<QGraphicsObject> QGraphicsItemPrivate::childrenList()
+{
+ Q_Q(QGraphicsItem);
+ if (isObject) {
+ QGraphicsObject *that = static_cast<QGraphicsObject *>(q);
+ return QDeclarativeListProperty<QGraphicsObject>(that, &children, children_append,
+ children_count, children_at, children_clear);
+ } else {
+ //QGraphicsItem is not supported for this property
+ return QDeclarativeListProperty<QGraphicsObject>();
+ }
+}
+
+/*!
+ \internal
+ Returns the width of the item
+ Reimplemented by QGraphicsWidget
+*/
+qreal QGraphicsItemPrivate::width() const
+{
+ return 0;
+}
+
+/*!
+ \internal
+ Set the width of the item
+ Reimplemented by QGraphicsWidget
+*/
+void QGraphicsItemPrivate::setWidth(qreal w)
+{
+ Q_UNUSED(w);
+}
+
+/*!
+ \internal
+ Reset the width of the item
+ Reimplemented by QGraphicsWidget
+*/
+void QGraphicsItemPrivate::resetWidth()
+{
+}
+
+/*!
+ \internal
+ Returns the height of the item
+ Reimplemented by QGraphicsWidget
+*/
+qreal QGraphicsItemPrivate::height() const
+{
+ return 0;
+}
+
+/*!
+ \internal
+ Set the height of the item
+ Reimplemented by QGraphicsWidget
+*/
+void QGraphicsItemPrivate::setHeight(qreal h)
+{
+ Q_UNUSED(h);
+}
+
+/*!
+ \internal
+ Reset the height of the item
+ Reimplemented by QGraphicsWidget
+*/
+void QGraphicsItemPrivate::resetHeight()
+{
+}
+
+/*!
+ \property QGraphicsObject::children
+ \since 4.7
+ \internal
+*/
+
+/*!
+ \property QGraphicsObject::width
+ \since 4.7
+ \internal
+*/
+
+/*!
+ \property QGraphicsObject::height
+ \since 4.7
+ \internal
+*/
+
+/*!
+ \property QGraphicsObject::parent
+ \brief the parent of the item
+
+ \note The item's parent is set independently of the parent object returned
+ by QObject::parent().
+
+ \sa QGraphicsItem::setParentItem(), QGraphicsItem::parentObject()
+*/
+
+/*!
+ \property QGraphicsObject::opacity
+ \brief the opacity of the item
+
+ \sa QGraphicsItem::setOpacity(), QGraphicsItem::opacity()
+*/
+
+/*!
+ \fn QGraphicsObject::opacityChanged()
+
+ This signal gets emitted whenever the opacity of the item changes
+
+ \sa QGraphicsItem::opacity()
+*/
+
+/*!
+ \fn QGraphicsObject::parentChanged()
+
+ This signal gets emitted whenever the parent of the item changes
+*/
+
+/*!
+ \property QGraphicsObject::pos
+ \brief the position of the item
+
+ Describes the items position.
+
+ \sa QGraphicsItem::setPos(), QGraphicsItem::pos()
+*/
+
+/*!
+ \property QGraphicsObject::x
+ \brief the x position of the item
+
+ Describes the items x position.
+
+ \sa QGraphicsItem::setX(), setPos(), xChanged()
+*/
+
+/*!
+ \fn QGraphicsObject::xChanged()
+
+ This signal gets emitted whenever the x position of the item changes
+
+ \sa pos()
+*/
+
+/*!
+ \property QGraphicsObject::y
+ \brief the y position of the item
+
+ Describes the items y position.
+
+ \sa QGraphicsItem::setY(), setPos(), yChanged()
+*/
+
+/*!
+ \fn QGraphicsObject::yChanged()
+
+ This signal gets emitted whenever the y position of the item changes.
+
+ \sa pos()
+*/
+
+/*!
+ \property QGraphicsObject::z
+ \brief the z value of the item
+
+ Describes the items z value.
+
+ \sa QGraphicsItem::setZValue(), zValue(), zChanged()
+*/
+
+/*!
+ \fn QGraphicsObject::zChanged()
+
+ This signal gets emitted whenever the z value of the item changes.
+
+ \sa pos()
+*/
+
+/*!
+ \property QGraphicsObject::rotation
+ This property holds the rotation of the item in degrees.
+
+ This specifies how many degrees to rotate the item around its transformOrigin.
+ The default rotation is 0 degrees (i.e. not rotated at all).
+*/
+
+/*!
+ \fn QGraphicsObject::rotationChanged()
+
+ This signal gets emitted whenever the roation of the item changes.
+*/
+
+/*!
+ \property QGraphicsObject::scale
+ This property holds the scale of the item.
+
+ A scale of less than 1 means the item will be displayed smaller than
+ normal, and a scale of greater than 1 means the item will be
+ displayed larger than normal. A negative scale means the item will
+ be mirrored.
+
+ By default, items are displayed at a scale of 1 (i.e. at their
+ normal size).
+
+ Scaling is from the item's transformOrigin.
+*/
+
+/*!
+ \fn void QGraphicsObject::scaleChanged()
+
+ This signal is emitted when the scale of the item changes.
+*/
+
+
+/*!
+ \property QGraphicsObject::enabled
+ \brief whether the item is enabled or not
+
+ This property is declared in QGraphicsItem.
+
+ By default, this property is true.
+
+ \sa QGraphicsItem::isEnabled(), QGraphicsItem::setEnabled()
+ \sa QGraphicsObject::enabledChanged()
+*/
+
+/*!
+ \fn void QGraphicsObject::enabledChanged()
+
+ This signal gets emitted whenever the item get's enabled or disabled.
+
+ \sa isEnabled()
+*/
+
+/*!
+ \property QGraphicsObject::visible
+ \brief whether the item is visible or not
+
+ This property is declared in QGraphicsItem.
+
+ By default, this property is true.
+
+ \sa QGraphicsItem::isVisible(), QGraphicsItem::setVisible(), visibleChanged()
+*/
+
+/*!
+ \fn QGraphicsObject::visibleChanged()
+
+ This signal gets emitted whenever the visibility of the item changes
+
+ \sa visible
+*/
+
+/*!
+ \fn const QObjectList &QGraphicsObject::children() const
+ \internal
+
+ This function returns the same value as QObject::children(). It's
+ provided to differentiate between the obsolete member
+ QGraphicsItem::children() and QObject::children(). QGraphicsItem now
+ provides childItems() instead.
+*/
+
+/*!
+ \property QGraphicsObject::transformOriginPoint
+ \brief the transformation origin
+
+ This property sets a specific point in the items coordiante system as the
+ origin for scale and rotation.
+
+ \sa scale, rotation, QGraphicsItem::transformOriginPoint()
+*/
+
+/*!
+ \fn void QGraphicsObject::widthChanged()
+ \internal
+*/
+
+/*!
+ \fn void QGraphicsObject::heightChanged()
+ \internal
+*/
+
+/*!
+
+ \fn QGraphicsObject::childrenChanged()
+
+ This signal gets emitted whenever the children list changes
+ \internal
+*/
+
+/*!
+ \property QGraphicsObject::effect
+ \since 4.7
+ \brief the effect attached to this item
+
+ \sa QGraphicsItem::setGraphicsEffect(), QGraphicsItem::graphicsEffect()
+*/
+
+/*!
+ \class QAbstractGraphicsShapeItem
+ \brief The QAbstractGraphicsShapeItem class provides a common base for
+ all path items.
+ \since 4.2
+ \ingroup graphicsview-api
+
+ This class does not fully implement an item by itself; in particular, it
+ does not implement boundingRect() and paint(), which are inherited by
+ QGraphicsItem.
+
+ You can subclass this item to provide a simple base implementation of
+ accessors for the item's pen and brush.
+
+ \sa QGraphicsRectItem, QGraphicsEllipseItem, QGraphicsPathItem,
+ QGraphicsPolygonItem, QGraphicsTextItem, QGraphicsLineItem,
+ QGraphicsPixmapItem, {Graphics View Framework}
+*/
+
+class QAbstractGraphicsShapeItemPrivate : public QGraphicsItemPrivate
+{
+ Q_DECLARE_PUBLIC(QAbstractGraphicsShapeItem)
+public:
+
+ QBrush brush;
+ QPen pen;
+
+ // Cached bounding rectangle
+ mutable QRectF boundingRect;
+};
+
+/*!
+ Constructs a QAbstractGraphicsShapeItem. \a parent is passed to
+ QGraphicsItem's constructor.
+*/
+QAbstractGraphicsShapeItem::QAbstractGraphicsShapeItem(QGraphicsItem *parent
+#ifndef Q_QDOC
+ // obsolete argument
+ , QGraphicsScene *scene
+#endif
+ )
+ : QGraphicsItem(*new QAbstractGraphicsShapeItemPrivate, parent, scene)
+{
+}
+
+/*!
+ \internal
+*/
+QAbstractGraphicsShapeItem::QAbstractGraphicsShapeItem(QAbstractGraphicsShapeItemPrivate &dd,
+ QGraphicsItem *parent,
+ QGraphicsScene *scene)
+ : QGraphicsItem(dd, parent, scene)
+{
+}
+
+/*!
+ Destroys a QAbstractGraphicsShapeItem.
+*/
+QAbstractGraphicsShapeItem::~QAbstractGraphicsShapeItem()
+{
+}
+
+/*!
+ Returns the item's pen. If no pen has been set, this function returns
+ QPen(), a default black solid line pen with 0 width.
+*/
+QPen QAbstractGraphicsShapeItem::pen() const
+{
+ Q_D(const QAbstractGraphicsShapeItem);
+ return d->pen;
+}
+
+/*!
+ Sets the pen for this item to \a pen.
+
+ The pen is used to draw the item's outline.
+
+ \sa pen()
+*/
+void QAbstractGraphicsShapeItem::setPen(const QPen &pen)
+{
+ Q_D(QAbstractGraphicsShapeItem);
+ if (d->pen == pen)
+ return;
+ prepareGeometryChange();
+ d->pen = pen;
+ d->boundingRect = QRectF();
+ update();
+}
+
+/*!
+ Returns the item's brush, or an empty brush if no brush has been set.
+
+ \sa setBrush()
+*/
+QBrush QAbstractGraphicsShapeItem::brush() const
+{
+ Q_D(const QAbstractGraphicsShapeItem);
+ return d->brush;
+}
+
+/*!
+ Sets the item's brush to \a brush.
+
+ The item's brush is used to fill the item.
+
+ If you use a brush with a QGradient, the gradient
+ is relative to the item's coordinate system.
+
+ \sa brush()
+*/
+void QAbstractGraphicsShapeItem::setBrush(const QBrush &brush)
+{
+ Q_D(QAbstractGraphicsShapeItem);
+ if (d->brush == brush)
+ return;
+ d->brush = brush;
+ update();
+}
+
+/*!
+ \reimp
+*/
+bool QAbstractGraphicsShapeItem::isObscuredBy(const QGraphicsItem *item) const
+{
+ return QGraphicsItem::isObscuredBy(item);
+}
+
+/*!
+ \reimp
+*/
+QPainterPath QAbstractGraphicsShapeItem::opaqueArea() const
+{
+ Q_D(const QAbstractGraphicsShapeItem);
+ if (d->brush.isOpaque())
+ return isClipped() ? clipPath() : shape();
+ return QGraphicsItem::opaqueArea();
+}
+
+/*!
+ \class QGraphicsPathItem
+ \brief The QGraphicsPathItem class provides a path item that you
+ can add to a QGraphicsScene.
+ \since 4.2
+ \ingroup graphicsview-api
+
+ To set the item's path, pass a QPainterPath to QGraphicsPathItem's
+ constructor, or call the setPath() function. The path() function
+ returns the current path.
+
+ \image graphicsview-pathitem.png
+
+ QGraphicsPathItem uses the path to provide a reasonable
+ implementation of boundingRect(), shape(), and contains(). The
+ paint() function draws the path using the item's associated pen
+ and brush, which you can set by calling the setPen() and
+ setBrush() functions.
+
+ \sa QGraphicsRectItem, QGraphicsEllipseItem, QGraphicsPolygonItem,
+ QGraphicsTextItem, QGraphicsLineItem, QGraphicsPixmapItem, {Graphics
+ View Framework}
+*/
+
+class QGraphicsPathItemPrivate : public QAbstractGraphicsShapeItemPrivate
+{
+ Q_DECLARE_PUBLIC(QGraphicsPathItem)
+public:
+ QPainterPath path;
+};
+
+/*!
+ Constructs a QGraphicsPath item using \a path as the default path. \a
+ parent is passed to QAbstractGraphicsShapeItem's constructor.
+
+ \sa QGraphicsScene::addItem()
+*/
+QGraphicsPathItem::QGraphicsPathItem(const QPainterPath &path,
+ QGraphicsItem *parent
+#ifndef Q_QDOC
+ // obsolete argument
+ , QGraphicsScene *scene
+#endif
+ )
+ : QAbstractGraphicsShapeItem(*new QGraphicsPathItemPrivate, parent, scene)
+{
+ if (!path.isEmpty())
+ setPath(path);
+}
+
+/*!
+ Constructs a QGraphicsPath. \a parent is passed to
+ QAbstractGraphicsShapeItem's constructor.
+
+ \sa QGraphicsScene::addItem()
+*/
+QGraphicsPathItem::QGraphicsPathItem(QGraphicsItem *parent
+#ifndef Q_QDOC
+ // obsolete argument
+ , QGraphicsScene *scene
+#endif
+ )
+ : QAbstractGraphicsShapeItem(*new QGraphicsPathItemPrivate, parent, scene)
+{
+}
+
+/*!
+ Destroys the QGraphicsPathItem.
+*/
+QGraphicsPathItem::~QGraphicsPathItem()
+{
+}
+
+/*!
+ Returns the item's path as a QPainterPath. If no item has been set, an
+ empty QPainterPath is returned.
+
+ \sa setPath()
+*/
+QPainterPath QGraphicsPathItem::path() const
+{
+ Q_D(const QGraphicsPathItem);
+ return d->path;
+}
+
+/*!
+ Sets the item's path to be the given \a path.
+
+ \sa path()
+*/
+void QGraphicsPathItem::setPath(const QPainterPath &path)
+{
+ Q_D(QGraphicsPathItem);
+ if (d->path == path)
+ return;
+ prepareGeometryChange();
+ d->path = path;
+ d->boundingRect = QRectF();
+ update();
+}
+
+/*!
+ \reimp
+*/
+QRectF QGraphicsPathItem::boundingRect() const
+{
+ Q_D(const QGraphicsPathItem);
+ if (d->boundingRect.isNull()) {
+ qreal pw = pen().widthF();
+ if (pw == 0.0)
+ d->boundingRect = d->path.controlPointRect();
+ else {
+ d->boundingRect = shape().controlPointRect();
+ }
+ }
+ return d->boundingRect;
+}
+
+/*!
+ \reimp
+*/
+QPainterPath QGraphicsPathItem::shape() const
+{
+ Q_D(const QGraphicsPathItem);
+ return qt_graphicsItem_shapeFromPath(d->path, d->pen);
+}
+
+/*!
+ \reimp
+*/
+bool QGraphicsPathItem::contains(const QPointF &point) const
+{
+ return QAbstractGraphicsShapeItem::contains(point);
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsPathItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
+ QWidget *widget)
+{
+ Q_D(QGraphicsPathItem);
+ Q_UNUSED(widget);
+ painter->setPen(d->pen);
+ painter->setBrush(d->brush);
+ painter->drawPath(d->path);
+
+ if (option->state & QStyle::State_Selected)
+ qt_graphicsItem_highlightSelected(this, painter, option);
+}
+
+/*!
+ \reimp
+*/
+bool QGraphicsPathItem::isObscuredBy(const QGraphicsItem *item) const
+{
+ return QAbstractGraphicsShapeItem::isObscuredBy(item);
+}
+
+/*!
+ \reimp
+*/
+QPainterPath QGraphicsPathItem::opaqueArea() const
+{
+ return QAbstractGraphicsShapeItem::opaqueArea();
+}
+
+/*!
+ \reimp
+*/
+int QGraphicsPathItem::type() const
+{
+ return Type;
+}
+
+/*!
+ \internal
+*/
+bool QGraphicsPathItem::supportsExtension(Extension extension) const
+{
+ Q_UNUSED(extension);
+ return false;
+}
+
+/*!
+ \internal
+*/
+void QGraphicsPathItem::setExtension(Extension extension, const QVariant &variant)
+{
+ Q_UNUSED(extension);
+ Q_UNUSED(variant);
+}
+
+/*!
+ \internal
+*/
+QVariant QGraphicsPathItem::extension(const QVariant &variant) const
+{
+ Q_UNUSED(variant);
+ return QVariant();
+}
+
+/*!
+ \class QGraphicsRectItem
+ \brief The QGraphicsRectItem class provides a rectangle item that you
+ can add to a QGraphicsScene.
+ \since 4.2
+ \ingroup graphicsview-api
+
+ To set the item's rectangle, pass a QRectF to QGraphicsRectItem's
+ constructor, or call the setRect() function. The rect() function
+ returns the current rectangle.
+
+ \image graphicsview-rectitem.png
+
+ QGraphicsRectItem uses the rectangle and the pen width to provide
+ a reasonable implementation of boundingRect(), shape(), and
+ contains(). The paint() function draws the rectangle using the
+ item's associated pen and brush, which you can set by calling the
+ setPen() and setBrush() functions.
+
+ \note The rendering of invalid rectangles, such as those with negative
+ widths or heights, is undefined. If you cannot be sure that you are
+ using valid rectangles (for example, if you are creating
+ rectangles using data from an unreliable source) then you should
+ use QRectF::normalized() to create normalized rectangles, and use
+ those instead.
+
+ \sa QGraphicsPathItem, QGraphicsEllipseItem, QGraphicsPolygonItem,
+ QGraphicsTextItem, QGraphicsLineItem, QGraphicsPixmapItem, {Graphics
+ View Framework}
+*/
+
+class QGraphicsRectItemPrivate : public QAbstractGraphicsShapeItemPrivate
+{
+ Q_DECLARE_PUBLIC(QGraphicsRectItem)
+public:
+ QRectF rect;
+};
+
+/*!
+ Constructs a QGraphicsRectItem, using \a rect as the default rectangle.
+ \a parent is passed to QAbstractGraphicsShapeItem's constructor.
+
+ \sa QGraphicsScene::addItem()
+*/
+QGraphicsRectItem::QGraphicsRectItem(const QRectF &rect, QGraphicsItem *parent
+#ifndef Q_QDOC
+ // obsolete argument
+ , QGraphicsScene *scene
+#endif
+ )
+ : QAbstractGraphicsShapeItem(*new QGraphicsRectItemPrivate, parent, scene)
+{
+ setRect(rect);
+}
+
+/*!
+ \fn QGraphicsRectItem::QGraphicsRectItem(qreal x, qreal y, qreal width, qreal height,
+ QGraphicsItem *parent)
+
+ Constructs a QGraphicsRectItem with a default rectangle defined
+ by (\a x, \a y) and the given \a width and \a height.
+
+ \a parent is passed to QAbstractGraphicsShapeItem's constructor.
+
+ \sa QGraphicsScene::addItem()
+*/
+QGraphicsRectItem::QGraphicsRectItem(qreal x, qreal y, qreal w, qreal h,
+ QGraphicsItem *parent
+#ifndef Q_QDOC
+ // obsolete argument
+ , QGraphicsScene *scene
+#endif
+ )
+ : QAbstractGraphicsShapeItem(*new QGraphicsRectItemPrivate, parent, scene)
+{
+ setRect(QRectF(x, y, w, h));
+}
+
+/*!
+ Constructs a QGraphicsRectItem. \a parent is passed to
+ QAbstractGraphicsShapeItem's constructor.
+
+ \sa QGraphicsScene::addItem()
+*/
+QGraphicsRectItem::QGraphicsRectItem(QGraphicsItem *parent
+#ifndef Q_QDOC
+ // obsolete argument
+ , QGraphicsScene *scene
+#endif
+ )
+ : QAbstractGraphicsShapeItem(*new QGraphicsRectItemPrivate, parent, scene)
+{
+}
+
+/*!
+ Destroys the QGraphicsRectItem.
+*/
+QGraphicsRectItem::~QGraphicsRectItem()
+{
+}
+
+/*!
+ Returns the item's rectangle.
+
+ \sa setRect()
+*/
+QRectF QGraphicsRectItem::rect() const
+{
+ Q_D(const QGraphicsRectItem);
+ return d->rect;
+}
+
+/*!
+ \fn void QGraphicsRectItem::setRect(const QRectF &rectangle)
+
+ Sets the item's rectangle to be the given \a rectangle.
+
+ \sa rect()
+*/
+void QGraphicsRectItem::setRect(const QRectF &rect)
+{
+ Q_D(QGraphicsRectItem);
+ if (d->rect == rect)
+ return;
+ prepareGeometryChange();
+ d->rect = rect;
+ d->boundingRect = QRectF();
+ update();
+}
+
+/*!
+ \fn void QGraphicsRectItem::setRect(qreal x, qreal y, qreal width, qreal height)
+ \fn void QGraphicsEllipseItem::setRect(qreal x, qreal y, qreal width, qreal height)
+
+ Sets the item's rectangle to the rectangle defined by (\a x, \a y)
+ and the given \a width and \a height.
+
+ This convenience function is equivalent to calling \c
+ {setRect(QRectF(x, y, width, height))}
+
+ \sa rect()
+*/
+
+/*!
+ \reimp
+*/
+QRectF QGraphicsRectItem::boundingRect() const
+{
+ Q_D(const QGraphicsRectItem);
+ if (d->boundingRect.isNull()) {
+ qreal halfpw = pen().widthF() / 2;
+ d->boundingRect = d->rect;
+ if (halfpw > 0.0)
+ d->boundingRect.adjust(-halfpw, -halfpw, halfpw, halfpw);
+ }
+ return d->boundingRect;
+}
+
+/*!
+ \reimp
+*/
+QPainterPath QGraphicsRectItem::shape() const
+{
+ Q_D(const QGraphicsRectItem);
+ QPainterPath path;
+ path.addRect(d->rect);
+ return qt_graphicsItem_shapeFromPath(path, d->pen);
+}
+
+/*!
+ \reimp
+*/
+bool QGraphicsRectItem::contains(const QPointF &point) const
+{
+ return QAbstractGraphicsShapeItem::contains(point);
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsRectItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
+ QWidget *widget)
+{
+ Q_D(QGraphicsRectItem);
+ Q_UNUSED(widget);
+ painter->setPen(d->pen);
+ painter->setBrush(d->brush);
+ painter->drawRect(d->rect);
+
+ if (option->state & QStyle::State_Selected)
+ qt_graphicsItem_highlightSelected(this, painter, option);
+}
+
+/*!
+ \reimp
+*/
+bool QGraphicsRectItem::isObscuredBy(const QGraphicsItem *item) const
+{
+ return QAbstractGraphicsShapeItem::isObscuredBy(item);
+}
+
+/*!
+ \reimp
+*/
+QPainterPath QGraphicsRectItem::opaqueArea() const
+{
+ return QAbstractGraphicsShapeItem::opaqueArea();
+}
+
+/*!
+ \reimp
+*/
+int QGraphicsRectItem::type() const
+{
+ return Type;
+}
+
+/*!
+ \internal
+*/
+bool QGraphicsRectItem::supportsExtension(Extension extension) const
+{
+ Q_UNUSED(extension);
+ return false;
+}
+
+/*!
+ \internal
+*/
+void QGraphicsRectItem::setExtension(Extension extension, const QVariant &variant)
+{
+ Q_UNUSED(extension);
+ Q_UNUSED(variant);
+}
+
+/*!
+ \internal
+*/
+QVariant QGraphicsRectItem::extension(const QVariant &variant) const
+{
+ Q_UNUSED(variant);
+ return QVariant();
+}
+
+/*!
+ \class QGraphicsEllipseItem
+ \brief The QGraphicsEllipseItem class provides an ellipse item that you
+ can add to a QGraphicsScene.
+ \since 4.2
+ \ingroup graphicsview-api
+
+ QGraphicsEllipseItem respresents an ellipse with a fill and an outline,
+ and you can also use it for ellipse segments (see startAngle(),
+ spanAngle()).
+
+ \table
+ \row
+ \o \inlineimage graphicsview-ellipseitem.png
+ \o \inlineimage graphicsview-ellipseitem-pie.png
+ \endtable
+
+ To set the item's ellipse, pass a QRectF to QGraphicsEllipseItem's
+ constructor, or call setRect(). The rect() function returns the
+ current ellipse geometry.
+
+ QGraphicsEllipseItem uses the rect and the pen width to provide a
+ reasonable implementation of boundingRect(), shape(), and contains(). The
+ paint() function draws the ellipse using the item's associated pen and
+ brush, which you can set by calling setPen() and setBrush().
+
+ \sa QGraphicsPathItem, QGraphicsRectItem, QGraphicsPolygonItem,
+ QGraphicsTextItem, QGraphicsLineItem, QGraphicsPixmapItem, {Graphics
+ View Framework}
+*/
+
+class QGraphicsEllipseItemPrivate : public QAbstractGraphicsShapeItemPrivate
+{
+ Q_DECLARE_PUBLIC(QGraphicsEllipseItem)
+public:
+ inline QGraphicsEllipseItemPrivate()
+ : startAngle(0), spanAngle(360 * 16)
+ { }
+
+ QRectF rect;
+ int startAngle;
+ int spanAngle;
+};
+
+/*!
+ Constructs a QGraphicsEllipseItem using \a rect as the default rectangle.
+ \a parent is passed to QAbstractGraphicsShapeItem's constructor.
+
+ \sa QGraphicsScene::addItem()
+*/
+QGraphicsEllipseItem::QGraphicsEllipseItem(const QRectF &rect, QGraphicsItem *parent
+#ifndef Q_QDOC
+ // obsolete argument
+ , QGraphicsScene *scene
+#endif
+ )
+ : QAbstractGraphicsShapeItem(*new QGraphicsEllipseItemPrivate, parent, scene)
+{
+ setRect(rect);
+}
+
+/*!
+ \fn QGraphicsEllipseItem::QGraphicsEllipseItem(qreal x, qreal y, qreal width, qreal height, QGraphicsItem *parent)
+ \since 4.3
+
+ Constructs a QGraphicsEllipseItem using the rectangle defined by (\a x, \a
+ y) and the given \a width and \a height, as the default rectangle. \a
+ parent is passed to QAbstractGraphicsShapeItem's constructor.
+
+ \sa QGraphicsScene::addItem()
+*/
+QGraphicsEllipseItem::QGraphicsEllipseItem(qreal x, qreal y, qreal w, qreal h,
+ QGraphicsItem *parent
+#ifndef Q_QDOC
+ // obsolete argument
+ , QGraphicsScene *scene
+#endif
+ )
+ : QAbstractGraphicsShapeItem(*new QGraphicsEllipseItemPrivate, parent, scene)
+{
+ setRect(x,y,w,h);
+}
+
+
+
+/*!
+ Constructs a QGraphicsEllipseItem. \a parent is passed to
+ QAbstractGraphicsShapeItem's constructor.
+
+ \sa QGraphicsScene::addItem()
+*/
+QGraphicsEllipseItem::QGraphicsEllipseItem(QGraphicsItem *parent
+#ifndef Q_QDOC
+ // obsolete argument
+ , QGraphicsScene *scene
+#endif
+ )
+ : QAbstractGraphicsShapeItem(*new QGraphicsEllipseItemPrivate, parent, scene)
+{
+}
+
+/*!
+ Destroys the QGraphicsEllipseItem.
+*/
+QGraphicsEllipseItem::~QGraphicsEllipseItem()
+{
+}
+
+/*!
+ Returns the item's ellipse geometry as a QRectF.
+
+ \sa setRect(), QPainter::drawEllipse()
+*/
+QRectF QGraphicsEllipseItem::rect() const
+{
+ Q_D(const QGraphicsEllipseItem);
+ return d->rect;
+}
+
+/*!
+ Sets the item's ellipse geometry to \a rect. The rectangle's left edge
+ defines the left edge of the ellipse, and the rectangle's top edge
+ describes the top of the ellipse. The height and width of the rectangle
+ describe the height and width of the ellipse.
+
+ \sa rect(), QPainter::drawEllipse()
+*/
+void QGraphicsEllipseItem::setRect(const QRectF &rect)
+{
+ Q_D(QGraphicsEllipseItem);
+ if (d->rect == rect)
+ return;
+ prepareGeometryChange();
+ d->rect = rect;
+ d->boundingRect = QRectF();
+ update();
+}
+
+/*!
+ Returns the start angle for an ellipse segment in 16ths of a degree. This
+ angle is used together with spanAngle() for representing an ellipse
+ segment (a pie). By default, the start angle is 0.
+
+ \sa setStartAngle(), spanAngle()
+*/
+int QGraphicsEllipseItem::startAngle() const
+{
+ Q_D(const QGraphicsEllipseItem);
+ return d->startAngle;
+}
+
+/*!
+ Sets the start angle for an ellipse segment to \a angle, which is in 16ths
+ of a degree. This angle is used together with spanAngle() for representing
+ an ellipse segment (a pie). By default, the start angle is 0.
+
+ \sa startAngle(), setSpanAngle(), QPainter::drawPie()
+*/
+void QGraphicsEllipseItem::setStartAngle(int angle)
+{
+ Q_D(QGraphicsEllipseItem);
+ if (angle != d->startAngle) {
+ prepareGeometryChange();
+ d->boundingRect = QRectF();
+ d->startAngle = angle;
+ update();
+ }
+}
+
+/*!
+ Returns the span angle of an ellipse segment in 16ths of a degree. This
+ angle is used together with startAngle() for representing an ellipse
+ segment (a pie). By default, this function returns 5760 (360 * 16, a full
+ ellipse).
+
+ \sa setSpanAngle(), startAngle()
+*/
+int QGraphicsEllipseItem::spanAngle() const
+{
+ Q_D(const QGraphicsEllipseItem);
+ return d->spanAngle;
+}
+
+/*!
+ Sets the span angle for an ellipse segment to \a angle, which is in 16ths
+ of a degree. This angle is used together with startAngle() to represent an
+ ellipse segment (a pie). By default, the span angle is 5760 (360 * 16, a
+ full ellipse).
+
+ \sa spanAngle(), setStartAngle(), QPainter::drawPie()
+*/
+void QGraphicsEllipseItem::setSpanAngle(int angle)
+{
+ Q_D(QGraphicsEllipseItem);
+ if (angle != d->spanAngle) {
+ prepareGeometryChange();
+ d->boundingRect = QRectF();
+ d->spanAngle = angle;
+ update();
+ }
+}
+
+/*!
+ \reimp
+*/
+QRectF QGraphicsEllipseItem::boundingRect() const
+{
+ Q_D(const QGraphicsEllipseItem);
+ if (d->boundingRect.isNull()) {
+ qreal pw = pen().widthF();
+ if (pw == 0.0 && d->spanAngle == 360 * 16)
+ d->boundingRect = d->rect;
+ else
+ d->boundingRect = shape().controlPointRect();
+ }
+ return d->boundingRect;
+}
+
+/*!
+ \reimp
+*/
+QPainterPath QGraphicsEllipseItem::shape() const
+{
+ Q_D(const QGraphicsEllipseItem);
+ QPainterPath path;
+ if (d->rect.isNull())
+ return path;
+ if (d->spanAngle != 360 * 16) {
+ path.moveTo(d->rect.center());
+ path.arcTo(d->rect, d->startAngle / 16.0, d->spanAngle / 16.0);
+ } else {
+ path.addEllipse(d->rect);
+ }
+
+ return qt_graphicsItem_shapeFromPath(path, d->pen);
+}
+
+/*!
+ \reimp
+*/
+bool QGraphicsEllipseItem::contains(const QPointF &point) const
+{
+ return QAbstractGraphicsShapeItem::contains(point);
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsEllipseItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
+ QWidget *widget)
+{
+ Q_D(QGraphicsEllipseItem);
+ Q_UNUSED(widget);
+ painter->setPen(d->pen);
+ painter->setBrush(d->brush);
+ if ((d->spanAngle != 0) && (qAbs(d->spanAngle) % (360 * 16) == 0))
+ painter->drawEllipse(d->rect);
+ else
+ painter->drawPie(d->rect, d->startAngle, d->spanAngle);
+
+ if (option->state & QStyle::State_Selected)
+ qt_graphicsItem_highlightSelected(this, painter, option);
+}
+
+/*!
+ \reimp
+*/
+bool QGraphicsEllipseItem::isObscuredBy(const QGraphicsItem *item) const
+{
+ return QAbstractGraphicsShapeItem::isObscuredBy(item);
+}
+
+/*!
+ \reimp
+*/
+QPainterPath QGraphicsEllipseItem::opaqueArea() const
+{
+ return QAbstractGraphicsShapeItem::opaqueArea();
+}
+
+/*!
+ \reimp
+*/
+int QGraphicsEllipseItem::type() const
+{
+ return Type;
+}
+
+
+/*!
+ \internal
+*/
+bool QGraphicsEllipseItem::supportsExtension(Extension extension) const
+{
+ Q_UNUSED(extension);
+ return false;
+}
+
+/*!
+ \internal
+*/
+void QGraphicsEllipseItem::setExtension(Extension extension, const QVariant &variant)
+{
+ Q_UNUSED(extension);
+ Q_UNUSED(variant);
+}
+
+/*!
+ \internal
+*/
+QVariant QGraphicsEllipseItem::extension(const QVariant &variant) const
+{
+ Q_UNUSED(variant);
+ return QVariant();
+}
+
+/*!
+ \class QGraphicsPolygonItem
+ \brief The QGraphicsPolygonItem class provides a polygon item that you
+ can add to a QGraphicsScene.
+ \since 4.2
+ \ingroup graphicsview-api
+
+ To set the item's polygon, pass a QPolygonF to
+ QGraphicsPolygonItem's constructor, or call the setPolygon()
+ function. The polygon() function returns the current polygon.
+
+ \image graphicsview-polygonitem.png
+
+ QGraphicsPolygonItem uses the polygon and the pen width to provide
+ a reasonable implementation of boundingRect(), shape(), and
+ contains(). The paint() function draws the polygon using the
+ item's associated pen and brush, which you can set by calling the
+ setPen() and setBrush() functions.
+
+ \sa QGraphicsPathItem, QGraphicsRectItem, QGraphicsEllipseItem,
+ QGraphicsTextItem, QGraphicsLineItem, QGraphicsPixmapItem, {Graphics
+ View Framework}
+*/
+
+class QGraphicsPolygonItemPrivate : public QAbstractGraphicsShapeItemPrivate
+{
+ Q_DECLARE_PUBLIC(QGraphicsPolygonItem)
+public:
+ inline QGraphicsPolygonItemPrivate()
+ : fillRule(Qt::OddEvenFill)
+ { }
+
+ QPolygonF polygon;
+ Qt::FillRule fillRule;
+};
+
+/*!
+ Constructs a QGraphicsPolygonItem with \a polygon as the default
+ polygon. \a parent is passed to QAbstractGraphicsShapeItem's constructor.
+
+ \sa QGraphicsScene::addItem()
+*/
+QGraphicsPolygonItem::QGraphicsPolygonItem(const QPolygonF &polygon,
+ QGraphicsItem *parent
+#ifndef Q_QDOC
+ // obsolete argument
+ , QGraphicsScene *scene
+#endif
+ )
+ : QAbstractGraphicsShapeItem(*new QGraphicsPolygonItemPrivate, parent, scene)
+{
+ setPolygon(polygon);
+}
+
+/*!
+ Constructs a QGraphicsPolygonItem. \a parent is passed to
+ QAbstractGraphicsShapeItem's constructor.
+
+ \sa QGraphicsScene::addItem()
+*/
+QGraphicsPolygonItem::QGraphicsPolygonItem(QGraphicsItem *parent
+#ifndef Q_QDOC
+ // obsolete argument
+ , QGraphicsScene *scene
+#endif
+ )
+ : QAbstractGraphicsShapeItem(*new QGraphicsPolygonItemPrivate, parent, scene)
+{
+}
+
+/*!
+ Destroys the QGraphicsPolygonItem.
+*/
+QGraphicsPolygonItem::~QGraphicsPolygonItem()
+{
+}
+
+/*!
+ Returns the item's polygon, or an empty polygon if no polygon
+ has been set.
+
+ \sa setPolygon()
+*/
+QPolygonF QGraphicsPolygonItem::polygon() const
+{
+ Q_D(const QGraphicsPolygonItem);
+ return d->polygon;
+}
+
+/*!
+ Sets the item's polygon to be the given \a polygon.
+
+ \sa polygon()
+*/
+void QGraphicsPolygonItem::setPolygon(const QPolygonF &polygon)
+{
+ Q_D(QGraphicsPolygonItem);
+ if (d->polygon == polygon)
+ return;
+ prepareGeometryChange();
+ d->polygon = polygon;
+ d->boundingRect = QRectF();
+ update();
+}
+
+/*!
+ Returns the fill rule of the polygon. The default fill rule is
+ Qt::OddEvenFill.
+
+ \sa setFillRule(), QPainterPath::fillRule(), QPainter::drawPolygon()
+*/
+Qt::FillRule QGraphicsPolygonItem::fillRule() const
+{
+ Q_D(const QGraphicsPolygonItem);
+ return d->fillRule;
+}
+
+/*!
+ Sets the fill rule of the polygon to \a rule. The default fill rule is
+ Qt::OddEvenFill.
+
+ \sa fillRule(), QPainterPath::fillRule(), QPainter::drawPolygon()
+*/
+void QGraphicsPolygonItem::setFillRule(Qt::FillRule rule)
+{
+ Q_D(QGraphicsPolygonItem);
+ if (rule != d->fillRule) {
+ d->fillRule = rule;
+ update();
+ }
+}
+
+/*!
+ \reimp
+*/
+QRectF QGraphicsPolygonItem::boundingRect() const
+{
+ Q_D(const QGraphicsPolygonItem);
+ if (d->boundingRect.isNull()) {
+ qreal pw = pen().widthF();
+ if (pw == 0.0)
+ d->boundingRect = d->polygon.boundingRect();
+ else
+ d->boundingRect = shape().controlPointRect();
+ }
+ return d->boundingRect;
+}
+
+/*!
+ \reimp
+*/
+QPainterPath QGraphicsPolygonItem::shape() const
+{
+ Q_D(const QGraphicsPolygonItem);
+ QPainterPath path;
+ path.addPolygon(d->polygon);
+ return qt_graphicsItem_shapeFromPath(path, d->pen);
+}
+
+/*!
+ \reimp
+*/
+bool QGraphicsPolygonItem::contains(const QPointF &point) const
+{
+ return QAbstractGraphicsShapeItem::contains(point);
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsPolygonItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+ Q_D(QGraphicsPolygonItem);
+ Q_UNUSED(widget);
+ painter->setPen(d->pen);
+ painter->setBrush(d->brush);
+ painter->drawPolygon(d->polygon, d->fillRule);
+
+ if (option->state & QStyle::State_Selected)
+ qt_graphicsItem_highlightSelected(this, painter, option);
+}
+
+/*!
+ \reimp
+*/
+bool QGraphicsPolygonItem::isObscuredBy(const QGraphicsItem *item) const
+{
+ return QAbstractGraphicsShapeItem::isObscuredBy(item);
+}
+
+/*!
+ \reimp
+*/
+QPainterPath QGraphicsPolygonItem::opaqueArea() const
+{
+ return QAbstractGraphicsShapeItem::opaqueArea();
+}
+
+/*!
+ \reimp
+*/
+int QGraphicsPolygonItem::type() const
+{
+ return Type;
+}
+
+/*!
+ \internal
+*/
+bool QGraphicsPolygonItem::supportsExtension(Extension extension) const
+{
+ Q_UNUSED(extension);
+ return false;
+}
+
+/*!
+ \internal
+*/
+void QGraphicsPolygonItem::setExtension(Extension extension, const QVariant &variant)
+{
+ Q_UNUSED(extension);
+ Q_UNUSED(variant);
+}
+
+/*!
+ \internal
+*/
+QVariant QGraphicsPolygonItem::extension(const QVariant &variant) const
+{
+ Q_UNUSED(variant);
+ return QVariant();
+}
+
+/*!
+ \class QGraphicsLineItem
+ \brief The QGraphicsLineItem class provides a line item that you can add to a
+ QGraphicsScene.
+ \since 4.2
+ \ingroup graphicsview-api
+
+ To set the item's line, pass a QLineF to QGraphicsLineItem's
+ constructor, or call the setLine() function. The line() function
+ returns the current line. By default the line is black with a
+ width of 0, but you can change this by calling setPen().
+
+ \img graphicsview-lineitem.png
+
+ QGraphicsLineItem uses the line and the pen width to provide a reasonable
+ implementation of boundingRect(), shape(), and contains(). The paint()
+ function draws the line using the item's associated pen.
+
+ \sa QGraphicsPathItem, QGraphicsRectItem, QGraphicsEllipseItem,
+ QGraphicsTextItem, QGraphicsPolygonItem, QGraphicsPixmapItem,
+ {Graphics View Framework}
+*/
+
+class QGraphicsLineItemPrivate : public QGraphicsItemPrivate
+{
+ Q_DECLARE_PUBLIC(QGraphicsLineItem)
+public:
+ QLineF line;
+ QPen pen;
+};
+
+/*!
+ Constructs a QGraphicsLineItem, using \a line as the default line. \a
+ parent is passed to QGraphicsItem's constructor.
+
+ \sa QGraphicsScene::addItem()
+*/
+QGraphicsLineItem::QGraphicsLineItem(const QLineF &line, QGraphicsItem *parent
+#ifndef Q_QDOC
+ // obsolete argument
+ , QGraphicsScene *scene
+#endif
+ )
+ : QGraphicsItem(*new QGraphicsLineItemPrivate, parent, scene)
+{
+ setLine(line);
+}
+
+/*!
+ Constructs a QGraphicsLineItem, using the line between (\a x1, \a y1) and
+ (\a x2, \a y2) as the default line. \a parent is passed to
+ QGraphicsItem's constructor.
+
+ \sa QGraphicsScene::addItem()
+*/
+QGraphicsLineItem::QGraphicsLineItem(qreal x1, qreal y1, qreal x2, qreal y2, QGraphicsItem *parent
+#ifndef Q_QDOC
+ // obsolete argument
+ , QGraphicsScene *scene
+#endif
+ )
+ : QGraphicsItem(*new QGraphicsLineItemPrivate, parent, scene)
+{
+ setLine(x1, y1, x2, y2);
+}
+
+
+
+/*!
+ Constructs a QGraphicsLineItem. \a parent is passed to QGraphicsItem's
+ constructor.
+
+ \sa QGraphicsScene::addItem()
+*/
+QGraphicsLineItem::QGraphicsLineItem(QGraphicsItem *parent
+#ifndef Q_QDOC
+ // obsolete argument
+ , QGraphicsScene *scene
+#endif
+ )
+ : QGraphicsItem(*new QGraphicsLineItemPrivate, parent, scene)
+{
+}
+
+/*!
+ Destroys the QGraphicsLineItem.
+*/
+QGraphicsLineItem::~QGraphicsLineItem()
+{
+}
+
+/*!
+ Returns the item's pen, or a black solid 0-width pen if no pen has
+ been set.
+
+ \sa setPen()
+*/
+QPen QGraphicsLineItem::pen() const
+{
+ Q_D(const QGraphicsLineItem);
+ return d->pen;
+}
+
+/*!
+ Sets the item's pen to \a pen. If no pen is set, the line will be painted
+ using a black solid 0-width pen.
+
+ \sa pen()
+*/
+void QGraphicsLineItem::setPen(const QPen &pen)
+{
+ Q_D(QGraphicsLineItem);
+ if (d->pen == pen)
+ return;
+ prepareGeometryChange();
+ d->pen = pen;
+ update();
+}
+
+/*!
+ Returns the item's line, or a null line if no line has been set.
+
+ \sa setLine()
+*/
+QLineF QGraphicsLineItem::line() const
+{
+ Q_D(const QGraphicsLineItem);
+ return d->line;
+}
+
+/*!
+ Sets the item's line to be the given \a line.
+
+ \sa line()
+*/
+void QGraphicsLineItem::setLine(const QLineF &line)
+{
+ Q_D(QGraphicsLineItem);
+ if (d->line == line)
+ return;
+ prepareGeometryChange();
+ d->line = line;
+ update();
+}
+
+/*!
+ \fn void QGraphicsLineItem::setLine(qreal x1, qreal y1, qreal x2, qreal y2)
+ \overload
+
+ Sets the item's line to be the line between (\a x1, \a y1) and (\a
+ x2, \a y2).
+
+ This is the same as calling \c {setLine(QLineF(x1, y1, x2, y2))}.
+*/
+
+/*!
+ \reimp
+*/
+QRectF QGraphicsLineItem::boundingRect() const
+{
+ Q_D(const QGraphicsLineItem);
+ if (d->pen.widthF() == 0.0) {
+ const qreal x1 = d->line.p1().x();
+ const qreal x2 = d->line.p2().x();
+ const qreal y1 = d->line.p1().y();
+ const qreal y2 = d->line.p2().y();
+ qreal lx = qMin(x1, x2);
+ qreal rx = qMax(x1, x2);
+ qreal ty = qMin(y1, y2);
+ qreal by = qMax(y1, y2);
+ return QRectF(lx, ty, rx - lx, by - ty);
+ }
+ return shape().controlPointRect();
+}
+
+/*!
+ \reimp
+*/
+QPainterPath QGraphicsLineItem::shape() const
+{
+ Q_D(const QGraphicsLineItem);
+ QPainterPath path;
+ if (d->line == QLineF())
+ return path;
+
+ path.moveTo(d->line.p1());
+ path.lineTo(d->line.p2());
+ return qt_graphicsItem_shapeFromPath(path, d->pen);
+}
+
+/*!
+ \reimp
+*/
+bool QGraphicsLineItem::contains(const QPointF &point) const
+{
+ return QGraphicsItem::contains(point);
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsLineItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+ Q_D(QGraphicsLineItem);
+ Q_UNUSED(widget);
+ painter->setPen(d->pen);
+ painter->drawLine(d->line);
+
+ if (option->state & QStyle::State_Selected)
+ qt_graphicsItem_highlightSelected(this, painter, option);
+}
+
+/*!
+ \reimp
+*/
+bool QGraphicsLineItem::isObscuredBy(const QGraphicsItem *item) const
+{
+ return QGraphicsItem::isObscuredBy(item);
+}
+
+/*!
+ \reimp
+*/
+QPainterPath QGraphicsLineItem::opaqueArea() const
+{
+ return QGraphicsItem::opaqueArea();
+}
+
+/*!
+ \reimp
+*/
+int QGraphicsLineItem::type() const
+{
+ return Type;
+}
+
+/*!
+ \internal
+*/
+bool QGraphicsLineItem::supportsExtension(Extension extension) const
+{
+ Q_UNUSED(extension);
+ return false;
+}
+
+/*!
+ \internal
+*/
+void QGraphicsLineItem::setExtension(Extension extension, const QVariant &variant)
+{
+ Q_UNUSED(extension);
+ Q_UNUSED(variant);
+}
+
+/*!
+ \internal
+*/
+QVariant QGraphicsLineItem::extension(const QVariant &variant) const
+{
+ Q_UNUSED(variant);
+ return QVariant();
+}
+
+/*!
+ \class QGraphicsPixmapItem
+ \brief The QGraphicsPixmapItem class provides a pixmap item that you can add to
+ a QGraphicsScene.
+ \since 4.2
+ \ingroup graphicsview-api
+
+ To set the item's pixmap, pass a QPixmap to QGraphicsPixmapItem's
+ constructor, or call the setPixmap() function. The pixmap()
+ function returns the current pixmap.
+
+ QGraphicsPixmapItem uses pixmap's optional alpha mask to provide a
+ reasonable implementation of boundingRect(), shape(), and contains().
+
+ \image graphicsview-pixmapitem.png
+
+ The pixmap is drawn at the item's (0, 0) coordinate, as returned by
+ offset(). You can change the drawing offset by calling setOffset().
+
+ You can set the pixmap's transformation mode by calling
+ setTransformationMode(). By default, Qt::FastTransformation is used, which
+ provides fast, non-smooth scaling. Qt::SmoothTransformation enables
+ QPainter::SmoothPixmapTransform on the painter, and the quality depends on
+ the platform and viewport. The result is usually not as good as calling
+ QPixmap::scale() directly. Call transformationMode() to get the current
+ transformation mode for the item.
+
+ \sa QGraphicsPathItem, QGraphicsRectItem, QGraphicsEllipseItem,
+ QGraphicsTextItem, QGraphicsPolygonItem, QGraphicsLineItem,
+ {Graphics View Framework}
+*/
+
+/*!
+ \enum QGraphicsPixmapItem::ShapeMode
+
+ This enum describes how QGraphicsPixmapItem calculates its shape and
+ opaque area.
+
+ The default value is MaskShape.
+
+ \value MaskShape The shape is determined by calling QPixmap::mask().
+ This shape includes only the opaque pixels of the pixmap.
+ Because the shape is more complex, however, it can be slower than the other modes,
+ and uses more memory.
+
+ \value BoundingRectShape The shape is determined by tracing the outline of
+ the pixmap. This is the fastest shape mode, but it does not take into account
+ any transparent areas on the pixmap.
+
+ \value HeuristicMaskShape The shape is determine by calling
+ QPixmap::createHeuristicMask(). The performance and memory consumption
+ is similar to MaskShape.
+*/
+extern QPainterPath qt_regionToPath(const QRegion &region);
+
+class QGraphicsPixmapItemPrivate : public QGraphicsItemPrivate
+{
+ Q_DECLARE_PUBLIC(QGraphicsPixmapItem)
+public:
+ QGraphicsPixmapItemPrivate()
+ : transformationMode(Qt::FastTransformation),
+ shapeMode(QGraphicsPixmapItem::MaskShape),
+ hasShape(false)
+ {}
+
+ QPixmap pixmap;
+ Qt::TransformationMode transformationMode;
+ QPointF offset;
+ QGraphicsPixmapItem::ShapeMode shapeMode;
+ QPainterPath shape;
+ bool hasShape;
+
+ void updateShape()
+ {
+ shape = QPainterPath();
+ switch (shapeMode) {
+ case QGraphicsPixmapItem::MaskShape: {
+ QBitmap mask = pixmap.mask();
+ if (!mask.isNull()) {
+ shape = qt_regionToPath(QRegion(mask).translated(offset.toPoint()));
+ break;
+ }
+ // FALL THROUGH
+ }
+ case QGraphicsPixmapItem::BoundingRectShape:
+ shape.addRect(QRectF(offset.x(), offset.y(), pixmap.width(), pixmap.height()));
+ break;
+ case QGraphicsPixmapItem::HeuristicMaskShape:
+#ifndef QT_NO_IMAGE_HEURISTIC_MASK
+ shape = qt_regionToPath(QRegion(pixmap.createHeuristicMask()).translated(offset.toPoint()));
+#else
+ shape.addRect(QRectF(offset.x(), offset.y(), pixmap.width(), pixmap.height()));
+#endif
+ break;
+ }
+ }
+};
+
+/*!
+ Constructs a QGraphicsPixmapItem, using \a pixmap as the default pixmap.
+ \a parent is passed to QGraphicsItem's constructor.
+
+ \sa QGraphicsScene::addItem()
+*/
+QGraphicsPixmapItem::QGraphicsPixmapItem(const QPixmap &pixmap,
+ QGraphicsItem *parent
+#ifndef Q_QDOC
+ // obsolete argument
+ , QGraphicsScene *scene
+#endif
+ )
+ : QGraphicsItem(*new QGraphicsPixmapItemPrivate, parent, scene)
+{
+ setPixmap(pixmap);
+}
+
+/*!
+ Constructs a QGraphicsPixmapItem. \a parent is passed to QGraphicsItem's
+ constructor.
+
+ \sa QGraphicsScene::addItem()
+*/
+QGraphicsPixmapItem::QGraphicsPixmapItem(QGraphicsItem *parent
+#ifndef Q_QDOC
+ // obsolete argument
+ , QGraphicsScene *scene
+#endif
+ )
+ : QGraphicsItem(*new QGraphicsPixmapItemPrivate, parent, scene)
+{
+}
+
+/*!
+ Destroys the QGraphicsPixmapItem.
+*/
+QGraphicsPixmapItem::~QGraphicsPixmapItem()
+{
+}
+
+/*!
+ Sets the item's pixmap to \a pixmap.
+
+ \sa pixmap()
+*/
+void QGraphicsPixmapItem::setPixmap(const QPixmap &pixmap)
+{
+ Q_D(QGraphicsPixmapItem);
+ prepareGeometryChange();
+ d->pixmap = pixmap;
+ d->hasShape = false;
+ update();
+}
+
+/*!
+ Returns the item's pixmap, or an invalid QPixmap if no pixmap has been
+ set.
+
+ \sa setPixmap()
+*/
+QPixmap QGraphicsPixmapItem::pixmap() const
+{
+ Q_D(const QGraphicsPixmapItem);
+ return d->pixmap;
+}
+
+/*!
+ Returns the transformation mode of the pixmap. The default mode is
+ Qt::FastTransformation, which provides quick transformation with no
+ smoothing.
+
+ \sa setTransformationMode()
+*/
+Qt::TransformationMode QGraphicsPixmapItem::transformationMode() const
+{
+ Q_D(const QGraphicsPixmapItem);
+ return d->transformationMode;
+}
+
+/*!
+ Sets the pixmap item's transformation mode to \a mode, and toggles an
+ update of the item. The default mode is Qt::FastTransformation, which
+ provides quick transformation with no smoothing.
+
+ Qt::SmoothTransformation enables QPainter::SmoothPixmapTransform on the
+ painter, and the quality depends on the platform and viewport. The result
+ is usually not as good as calling QPixmap::scale() directly.
+
+ \sa transformationMode()
+*/
+void QGraphicsPixmapItem::setTransformationMode(Qt::TransformationMode mode)
+{
+ Q_D(QGraphicsPixmapItem);
+ if (mode != d->transformationMode) {
+ d->transformationMode = mode;
+ update();
+ }
+}
+
+/*!
+ Returns the pixmap item's \e offset, which defines the point of the
+ top-left corner of the pixmap, in local coordinates.
+
+ \sa setOffset()
+*/
+QPointF QGraphicsPixmapItem::offset() const
+{
+ Q_D(const QGraphicsPixmapItem);
+ return d->offset;
+}
+
+/*!
+ Sets the pixmap item's offset to \a offset. QGraphicsPixmapItem will draw
+ its pixmap using \a offset for its top-left corner.
+
+ \sa offset()
+*/
+void QGraphicsPixmapItem::setOffset(const QPointF &offset)
+{
+ Q_D(QGraphicsPixmapItem);
+ if (d->offset == offset)
+ return;
+ prepareGeometryChange();
+ d->offset = offset;
+ d->hasShape = false;
+ update();
+}
+
+/*!
+ \fn void QGraphicsPixmapItem::setOffset(qreal x, qreal y)
+ \since 4.3
+
+ This convenience function is equivalent to calling setOffset(QPointF(\a x, \a y)).
+*/
+
+/*!
+ \reimp
+*/
+QRectF QGraphicsPixmapItem::boundingRect() const
+{
+ Q_D(const QGraphicsPixmapItem);
+ if (d->pixmap.isNull())
+ return QRectF();
+ if (d->flags & ItemIsSelectable) {
+ qreal pw = 1.0;
+ return QRectF(d->offset, d->pixmap.size()).adjusted(-pw/2, -pw/2, pw/2, pw/2);
+ } else {
+ return QRectF(d->offset, d->pixmap.size());
+ }
+}
+
+/*!
+ \reimp
+*/
+QPainterPath QGraphicsPixmapItem::shape() const
+{
+ Q_D(const QGraphicsPixmapItem);
+ if (!d->hasShape) {
+ QGraphicsPixmapItemPrivate *thatD = const_cast<QGraphicsPixmapItemPrivate *>(d);
+ thatD->updateShape();
+ thatD->hasShape = true;
+ }
+ return d_func()->shape;
+}
+
+/*!
+ \reimp
+*/
+bool QGraphicsPixmapItem::contains(const QPointF &point) const
+{
+ return QGraphicsItem::contains(point);
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsPixmapItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
+ QWidget *widget)
+{
+ Q_D(QGraphicsPixmapItem);
+ Q_UNUSED(widget);
+
+ painter->setRenderHint(QPainter::SmoothPixmapTransform,
+ (d->transformationMode == Qt::SmoothTransformation));
+
+ painter->drawPixmap(d->offset, d->pixmap);
+
+ if (option->state & QStyle::State_Selected)
+ qt_graphicsItem_highlightSelected(this, painter, option);
+}
+
+/*!
+ \reimp
+*/
+bool QGraphicsPixmapItem::isObscuredBy(const QGraphicsItem *item) const
+{
+ return QGraphicsItem::isObscuredBy(item);
+}
+
+/*!
+ \reimp
+*/
+QPainterPath QGraphicsPixmapItem::opaqueArea() const
+{
+ return shape();
+}
+
+/*!
+ \reimp
+*/
+int QGraphicsPixmapItem::type() const
+{
+ return Type;
+}
+
+/*!
+ Returns the item's shape mode. The shape mode describes how
+ QGraphicsPixmapItem calculates its shape. The default mode is MaskShape.
+
+ \sa setShapeMode(), ShapeMode
+*/
+QGraphicsPixmapItem::ShapeMode QGraphicsPixmapItem::shapeMode() const
+{
+ return d_func()->shapeMode;
+}
+
+/*!
+ Sets the item's shape mode to \a mode. The shape mode describes how
+ QGraphicsPixmapItem calculates its shape. The default mode is MaskShape.
+
+ \sa shapeMode(), ShapeMode
+*/
+void QGraphicsPixmapItem::setShapeMode(ShapeMode mode)
+{
+ Q_D(QGraphicsPixmapItem);
+ if (d->shapeMode == mode)
+ return;
+ d->shapeMode = mode;
+ d->hasShape = false;
+}
+
+/*!
+ \internal
+*/
+bool QGraphicsPixmapItem::supportsExtension(Extension extension) const
+{
+ Q_UNUSED(extension);
+ return false;
+}
+
+/*!
+ \internal
+*/
+void QGraphicsPixmapItem::setExtension(Extension extension, const QVariant &variant)
+{
+ Q_UNUSED(extension);
+ Q_UNUSED(variant);
+}
+
+/*!
+ \internal
+*/
+QVariant QGraphicsPixmapItem::extension(const QVariant &variant) const
+{
+ Q_UNUSED(variant);
+ return QVariant();
+}
+
+/*!
+ \class QGraphicsTextItem
+ \brief The QGraphicsTextItem class provides a text item that you can add to
+ a QGraphicsScene to display formatted text.
+ \since 4.2
+ \ingroup graphicsview-api
+
+ If you only need to show plain text in an item, consider using QGraphicsSimpleTextItem
+ instead.
+
+ To set the item's text, pass a QString to QGraphicsTextItem's
+ constructor, or call setHtml()/setPlainText().
+
+ QGraphicsTextItem uses the text's formatted size and the associated font
+ to provide a reasonable implementation of boundingRect(), shape(),
+ and contains(). You can set the font by calling setFont().
+
+ It is possible to make the item editable by setting the Qt::TextEditorInteraction flag
+ using setTextInteractionFlags().
+
+ The item's preferred text width can be set using setTextWidth() and obtained
+ using textWidth().
+
+ \note In order to align HTML text in the center, the item's text width must be set.
+
+ \img graphicsview-textitem.png
+
+ \note QGraphicsTextItem accepts \l{QGraphicsItem::acceptHoverEvents()}{hover events}
+ by default. You can change this with \l{QGraphicsItem::}{setAcceptHoverEvents()}.
+
+ \sa QGraphicsSimpleTextItem, QGraphicsPathItem, QGraphicsRectItem,
+ QGraphicsEllipseItem, QGraphicsPixmapItem, QGraphicsPolygonItem,
+ QGraphicsLineItem, {Graphics View Framework}
+*/
+
+class QGraphicsTextItemPrivate
+{
+public:
+ QGraphicsTextItemPrivate()
+ : control(0), pageNumber(0), useDefaultImpl(false), tabChangesFocus(false), clickCausedFocus(0)
+ { }
+
+ mutable QWidgetTextControl *control;
+ QWidgetTextControl *textControl() const;
+
+ inline QPointF controlOffset() const
+ { return QPointF(0., pageNumber * control->document()->pageSize().height()); }
+ inline void sendControlEvent(QEvent *e)
+ { if (control) control->processEvent(e, controlOffset()); }
+
+ void _q_updateBoundingRect(const QSizeF &);
+ void _q_update(QRectF);
+ void _q_ensureVisible(QRectF);
+ bool _q_mouseOnEdge(QGraphicsSceneMouseEvent *);
+
+ QRectF boundingRect;
+ int pageNumber;
+ bool useDefaultImpl;
+ bool tabChangesFocus;
+
+ uint clickCausedFocus : 1;
+
+ QGraphicsTextItem *qq;
+};
+
+
+/*!
+ Constructs a QGraphicsTextItem, using \a text as the default plain
+ text. \a parent is passed to QGraphicsItem's constructor.
+
+ \sa QGraphicsScene::addItem()
+*/
+QGraphicsTextItem::QGraphicsTextItem(const QString &text, QGraphicsItem *parent
+#ifndef Q_QDOC
+ // obsolete argument
+ , QGraphicsScene *scene
+#endif
+ )
+ : QGraphicsObject(*new QGraphicsItemPrivate, parent, scene), dd(new QGraphicsTextItemPrivate)
+{
+ dd->qq = this;
+ if (!text.isEmpty())
+ setPlainText(text);
+ setAcceptDrops(true);
+ setAcceptHoverEvents(true);
+ setFlags(ItemUsesExtendedStyleOption);
+}
+
+/*!
+ Constructs a QGraphicsTextItem. \a parent is passed to QGraphicsItem's
+ constructor.
+
+ \sa QGraphicsScene::addItem()
+*/
+QGraphicsTextItem::QGraphicsTextItem(QGraphicsItem *parent
+#ifndef Q_QDOC
+ // obsolete argument
+ , QGraphicsScene *scene
+#endif
+ )
+ : QGraphicsObject(*new QGraphicsItemPrivate, parent, scene), dd(new QGraphicsTextItemPrivate)
+{
+ dd->qq = this;
+ setAcceptDrops(true);
+ setAcceptHoverEvents(true);
+ setFlag(ItemUsesExtendedStyleOption);
+}
+
+/*!
+ Destroys the QGraphicsTextItem.
+*/
+QGraphicsTextItem::~QGraphicsTextItem()
+{
+ delete dd;
+}
+
+/*!
+ Returns the item's text converted to HTML, or an empty QString if no text has been set.
+
+ \sa setHtml()
+*/
+QString QGraphicsTextItem::toHtml() const
+{
+#ifndef QT_NO_TEXTHTMLPARSER
+ if (dd->control)
+ return dd->control->toHtml();
+#endif
+ return QString();
+}
+
+/*!
+ Sets the item's text to \a text, assuming that text is HTML formatted. If
+ the item has keyboard input focus, this function will also call
+ ensureVisible() to ensure that the text is visible in all viewports.
+
+ \sa toHtml(), hasFocus(), QGraphicsSimpleTextItem
+*/
+void QGraphicsTextItem::setHtml(const QString &text)
+{
+ dd->textControl()->setHtml(text);
+}
+
+/*!
+ Returns the item's text converted to plain text, or an empty QString if no text has been set.
+
+ \sa setPlainText()
+*/
+QString QGraphicsTextItem::toPlainText() const
+{
+ if (dd->control)
+ return dd->control->toPlainText();
+ return QString();
+}
+
+/*!
+ Sets the item's text to \a text. If the item has keyboard input focus,
+ this function will also call ensureVisible() to ensure that the text is
+ visible in all viewports.
+
+ \sa toHtml(), hasFocus()
+*/
+void QGraphicsTextItem::setPlainText(const QString &text)
+{
+ dd->textControl()->setPlainText(text);
+}
+
+/*!
+ Returns the item's font, which is used to render the text.
+
+ \sa setFont()
+*/
+QFont QGraphicsTextItem::font() const
+{
+ if (!dd->control)
+ return QFont();
+ return dd->control->document()->defaultFont();
+}
+
+/*!
+ Sets the font used to render the text item to \a font.
+
+ \sa font()
+*/
+void QGraphicsTextItem::setFont(const QFont &font)
+{
+ dd->textControl()->document()->setDefaultFont(font);
+}
+
+/*!
+ Sets the color for unformatted text to \a col.
+*/
+void QGraphicsTextItem::setDefaultTextColor(const QColor &col)
+{
+ QWidgetTextControl *c = dd->textControl();
+ QPalette pal = c->palette();
+ QColor old = pal.color(QPalette::Text);
+ pal.setColor(QPalette::Text, col);
+ c->setPalette(pal);
+ if (old != col)
+ update();
+}
+
+/*!
+ Returns the default text color that is used to for unformatted text.
+*/
+QColor QGraphicsTextItem::defaultTextColor() const
+{
+ return dd->textControl()->palette().color(QPalette::Text);
+}
+
+/*!
+ \reimp
+*/
+QRectF QGraphicsTextItem::boundingRect() const
+{
+ return dd->boundingRect;
+}
+
+/*!
+ \reimp
+*/
+QPainterPath QGraphicsTextItem::shape() const
+{
+ if (!dd->control)
+ return QPainterPath();
+ QPainterPath path;
+ path.addRect(dd->boundingRect);
+ return path;
+}
+
+/*!
+ \reimp
+*/
+bool QGraphicsTextItem::contains(const QPointF &point) const
+{
+ return dd->boundingRect.contains(point);
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsTextItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
+ QWidget *widget)
+{
+ Q_UNUSED(widget);
+ if (dd->control) {
+ painter->save();
+ QRectF r = option->exposedRect;
+ painter->translate(-dd->controlOffset());
+ r.translate(dd->controlOffset());
+
+ QTextDocument *doc = dd->control->document();
+ QTextDocumentLayout *layout = qobject_cast<QTextDocumentLayout *>(doc->documentLayout());
+
+ // the layout might need to expand the root frame to
+ // the viewport if NoWrap is set
+ if (layout)
+ layout->setViewport(dd->boundingRect);
+
+ dd->control->drawContents(painter, r);
+
+ if (layout)
+ layout->setViewport(QRect());
+
+ painter->restore();
+ }
+
+ if (option->state & (QStyle::State_Selected | QStyle::State_HasFocus))
+ qt_graphicsItem_highlightSelected(this, painter, option);
+}
+
+/*!
+ \reimp
+*/
+bool QGraphicsTextItem::isObscuredBy(const QGraphicsItem *item) const
+{
+ return QGraphicsItem::isObscuredBy(item);
+}
+
+/*!
+ \reimp
+*/
+QPainterPath QGraphicsTextItem::opaqueArea() const
+{
+ return QGraphicsItem::opaqueArea();
+}
+
+/*!
+ \reimp
+*/
+int QGraphicsTextItem::type() const
+{
+ return Type;
+}
+
+/*!
+ Sets the preferred width for the item's text. If the actual text
+ is wider than the specified width then it will be broken into
+ multiple lines.
+
+ If \a width is set to -1 then the text will not be broken into
+ multiple lines unless it is enforced through an explicit line
+ break or a new paragraph.
+
+ The default value is -1.
+
+ Note that QGraphicsTextItem keeps a QTextDocument internally,
+ which is used to calculate the text width.
+
+ \sa textWidth(), QTextDocument::setTextWidth()
+*/
+void QGraphicsTextItem::setTextWidth(qreal width)
+{
+ dd->textControl()->setTextWidth(width);
+}
+
+/*!
+ Returns the text width.
+
+ The width is calculated with the QTextDocument that
+ QGraphicsTextItem keeps internally.
+
+ \sa setTextWidth(), QTextDocument::textWidth()
+*/
+qreal QGraphicsTextItem::textWidth() const
+{
+ if (!dd->control)
+ return -1;
+ return dd->control->textWidth();
+}
+
+/*!
+ Adjusts the text item to a reasonable size.
+*/
+void QGraphicsTextItem::adjustSize()
+{
+ if (dd->control)
+ dd->control->adjustSize();
+}
+
+/*!
+ Sets the text document \a document on the item.
+*/
+void QGraphicsTextItem::setDocument(QTextDocument *document)
+{
+ dd->textControl()->setDocument(document);
+ dd->_q_updateBoundingRect(dd->control->size());
+}
+
+/*!
+ Returns the item's text document.
+*/
+QTextDocument *QGraphicsTextItem::document() const
+{
+ return dd->textControl()->document();
+}
+
+/*!
+ \reimp
+*/
+bool QGraphicsTextItem::sceneEvent(QEvent *event)
+{
+ QEvent::Type t = event->type();
+ if (!dd->tabChangesFocus && (t == QEvent::KeyPress || t == QEvent::KeyRelease)) {
+ int k = ((QKeyEvent *)event)->key();
+ if (k == Qt::Key_Tab || k == Qt::Key_Backtab) {
+ dd->sendControlEvent(event);
+ return true;
+ }
+ }
+ bool result = QGraphicsItem::sceneEvent(event);
+
+ // Ensure input context is updated.
+ switch (event->type()) {
+ case QEvent::ContextMenu:
+ case QEvent::FocusIn:
+ case QEvent::FocusOut:
+ case QEvent::GraphicsSceneDragEnter:
+ case QEvent::GraphicsSceneDragLeave:
+ case QEvent::GraphicsSceneDragMove:
+ case QEvent::GraphicsSceneDrop:
+ case QEvent::GraphicsSceneHoverEnter:
+ case QEvent::GraphicsSceneHoverLeave:
+ case QEvent::GraphicsSceneHoverMove:
+ case QEvent::GraphicsSceneMouseDoubleClick:
+ case QEvent::GraphicsSceneMousePress:
+ case QEvent::GraphicsSceneMouseMove:
+ case QEvent::GraphicsSceneMouseRelease:
+ case QEvent::KeyPress:
+ case QEvent::KeyRelease:
+ // Reset the focus widget's input context, regardless
+ // of how this item gained or lost focus.
+ if (QWidget *fw = qApp->focusWidget()) {
+#ifndef QT_NO_IM
+ if (QInputContext *qic = fw->inputContext()) {
+ if (event->type() == QEvent::FocusIn || event->type() == QEvent::FocusOut)
+ qic->reset();
+ else
+ qic->update();
+ }
+#endif //QT_NO_IM
+ }
+ break;
+ case QEvent::ShortcutOverride:
+ dd->sendControlEvent(event);
+ return true;
+ default:
+ break;
+ }
+
+ return result;
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsTextItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
+{
+ if ((QGraphicsItem::d_ptr->flags & (ItemIsSelectable | ItemIsMovable))
+ && (event->buttons() & Qt::LeftButton) && dd->_q_mouseOnEdge(event)) {
+ // User left-pressed on edge of selectable/movable item, use
+ // base impl.
+ dd->useDefaultImpl = true;
+ } else if (event->buttons() == event->button()
+ && dd->control->textInteractionFlags() == Qt::NoTextInteraction) {
+ // User pressed first button on non-interactive item.
+ dd->useDefaultImpl = true;
+ }
+ if (dd->useDefaultImpl) {
+ QGraphicsItem::mousePressEvent(event);
+ if (!event->isAccepted())
+ dd->useDefaultImpl = false;
+ return;
+ }
+
+ dd->sendControlEvent(event);
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsTextItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
+{
+ if (dd->useDefaultImpl) {
+ QGraphicsItem::mouseMoveEvent(event);
+ return;
+ }
+
+ dd->sendControlEvent(event);
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsTextItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
+{
+ if (dd->useDefaultImpl) {
+ QGraphicsItem::mouseReleaseEvent(event);
+ if (dd->control->textInteractionFlags() == Qt::NoTextInteraction
+ && !event->buttons()) {
+ // User released last button on non-interactive item.
+ dd->useDefaultImpl = false;
+ } else if ((event->buttons() & Qt::LeftButton) == 0) {
+ // User released the left button on an interactive item.
+ dd->useDefaultImpl = false;
+ }
+ return;
+ }
+
+ QWidget *widget = event->widget();
+ if (widget && (dd->control->textInteractionFlags() & Qt::TextEditable) && boundingRect().contains(event->pos())) {
+ qt_widget_private(widget)->handleSoftwareInputPanel(event->button(), dd->clickCausedFocus);
+ }
+ dd->clickCausedFocus = 0;
+ dd->sendControlEvent(event);
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsTextItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
+{
+ if (dd->useDefaultImpl) {
+ QGraphicsItem::mouseDoubleClickEvent(event);
+ return;
+ }
+
+ if (!hasFocus()) {
+ QGraphicsItem::mouseDoubleClickEvent(event);
+ return;
+ }
+
+ dd->sendControlEvent(event);
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsTextItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
+{
+ dd->sendControlEvent(event);
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsTextItem::keyPressEvent(QKeyEvent *event)
+{
+ dd->sendControlEvent(event);
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsTextItem::keyReleaseEvent(QKeyEvent *event)
+{
+ dd->sendControlEvent(event);
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsTextItem::focusInEvent(QFocusEvent *event)
+{
+ dd->sendControlEvent(event);
+ if (event->reason() == Qt::MouseFocusReason) {
+ dd->clickCausedFocus = 1;
+ }
+ update();
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsTextItem::focusOutEvent(QFocusEvent *event)
+{
+ dd->sendControlEvent(event);
+ update();
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsTextItem::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
+{
+ dd->sendControlEvent(event);
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsTextItem::dragLeaveEvent(QGraphicsSceneDragDropEvent *event)
+{
+ dd->sendControlEvent(event);
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsTextItem::dragMoveEvent(QGraphicsSceneDragDropEvent *event)
+{
+ dd->sendControlEvent(event);
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsTextItem::dropEvent(QGraphicsSceneDragDropEvent *event)
+{
+ dd->sendControlEvent(event);
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsTextItem::inputMethodEvent(QInputMethodEvent *event)
+{
+ dd->sendControlEvent(event);
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsTextItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
+{
+ dd->sendControlEvent(event);
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsTextItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
+{
+ dd->sendControlEvent(event);
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsTextItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
+{
+ dd->sendControlEvent(event);
+}
+
+/*!
+ \reimp
+*/
+QVariant QGraphicsTextItem::inputMethodQuery(Qt::InputMethodQuery query) const
+{
+ QVariant v;
+ if (dd->control)
+ v = dd->control->inputMethodQuery(query);
+ if (v.type() == QVariant::RectF)
+ v = v.toRectF().translated(-dd->controlOffset());
+ else if (v.type() == QVariant::PointF)
+ v = v.toPointF() - dd->controlOffset();
+ else if (v.type() == QVariant::Rect)
+ v = v.toRect().translated(-dd->controlOffset().toPoint());
+ else if (v.type() == QVariant::Point)
+ v = v.toPoint() - dd->controlOffset().toPoint();
+ return v;
+}
+
+/*!
+ \internal
+*/
+bool QGraphicsTextItem::supportsExtension(Extension extension) const
+{
+ Q_UNUSED(extension);
+ return false;
+}
+
+/*!
+ \internal
+*/
+void QGraphicsTextItem::setExtension(Extension extension, const QVariant &variant)
+{
+ Q_UNUSED(extension);
+ Q_UNUSED(variant);
+}
+
+/*!
+ \internal
+*/
+QVariant QGraphicsTextItem::extension(const QVariant &variant) const
+{
+ Q_UNUSED(variant);
+ return QVariant();
+}
+
+/*!
+ \internal
+*/
+void QGraphicsTextItemPrivate::_q_update(QRectF rect)
+{
+ if (rect.isValid()) {
+ rect.translate(-controlOffset());
+ } else {
+ rect = boundingRect;
+ }
+ if (rect.intersects(boundingRect))
+ qq->update(rect);
+}
+
+/*!
+ \internal
+*/
+void QGraphicsTextItemPrivate::_q_updateBoundingRect(const QSizeF &size)
+{
+ if (!control) return; // can't happen
+ const QSizeF pageSize = control->document()->pageSize();
+ // paged items have a constant (page) size
+ if (size == boundingRect.size() || pageSize.height() != -1)
+ return;
+ qq->prepareGeometryChange();
+ boundingRect.setSize(size);
+ qq->update();
+}
+
+/*!
+ \internal
+*/
+void QGraphicsTextItemPrivate::_q_ensureVisible(QRectF rect)
+{
+ if (qq->hasFocus()) {
+ rect.translate(-controlOffset());
+ qq->ensureVisible(rect, /*xmargin=*/0, /*ymargin=*/0);
+ }
+}
+
+QWidgetTextControl *QGraphicsTextItemPrivate::textControl() const
+{
+ if (!control) {
+ QGraphicsTextItem *that = const_cast<QGraphicsTextItem *>(qq);
+ control = new QWidgetTextControl(that);
+ control->setTextInteractionFlags(Qt::NoTextInteraction);
+
+ QObject::connect(control, SIGNAL(updateRequest(QRectF)),
+ qq, SLOT(_q_update(QRectF)));
+ QObject::connect(control, SIGNAL(documentSizeChanged(QSizeF)),
+ qq, SLOT(_q_updateBoundingRect(QSizeF)));
+ QObject::connect(control, SIGNAL(visibilityRequest(QRectF)),
+ qq, SLOT(_q_ensureVisible(QRectF)));
+ QObject::connect(control, SIGNAL(linkActivated(QString)),
+ qq, SIGNAL(linkActivated(QString)));
+ QObject::connect(control, SIGNAL(linkHovered(QString)),
+ qq, SIGNAL(linkHovered(QString)));
+
+ const QSizeF pgSize = control->document()->pageSize();
+ if (pgSize.height() != -1) {
+ qq->prepareGeometryChange();
+ that->dd->boundingRect.setSize(pgSize);
+ qq->update();
+ } else {
+ that->dd->_q_updateBoundingRect(control->size());
+ }
+ }
+ return control;
+}
+
+/*!
+ \internal
+*/
+bool QGraphicsTextItemPrivate::_q_mouseOnEdge(QGraphicsSceneMouseEvent *event)
+{
+ QPainterPath path;
+ path.addRect(qq->boundingRect());
+
+ QPainterPath docPath;
+ const QTextFrameFormat format = control->document()->rootFrame()->frameFormat();
+ docPath.addRect(
+ qq->boundingRect().adjusted(
+ format.leftMargin(),
+ format.topMargin(),
+ -format.rightMargin(),
+ -format.bottomMargin()));
+
+ return path.subtracted(docPath).contains(event->pos());
+}
+
+/*!
+ \fn QGraphicsTextItem::linkActivated(const QString &link)
+
+ This signal is emitted when the user clicks on a link on a text item
+ that enables Qt::LinksAccessibleByMouse or Qt::LinksAccessibleByKeyboard.
+ \a link is the link that was clicked.
+
+ \sa setTextInteractionFlags()
+*/
+
+/*!
+ \fn QGraphicsTextItem::linkHovered(const QString &link)
+
+ This signal is emitted when the user hovers over a link on a text item
+ that enables Qt::LinksAccessibleByMouse. \a link is
+ the link that was hovered over.
+
+ \sa setTextInteractionFlags()
+*/
+
+/*!
+ Sets the flags \a flags to specify how the text item should react to user
+ input.
+
+ The default for a QGraphicsTextItem is Qt::NoTextInteraction. This function
+ also affects the ItemIsFocusable QGraphicsItem flag by setting it if \a flags
+ is different from Qt::NoTextInteraction and clearing it otherwise.
+
+ By default, the text is read-only. To transform the item into an editor,
+ set the Qt::TextEditable flag.
+*/
+void QGraphicsTextItem::setTextInteractionFlags(Qt::TextInteractionFlags flags)
+{
+ if (flags == Qt::NoTextInteraction)
+ setFlags(this->flags() & ~(QGraphicsItem::ItemIsFocusable | QGraphicsItem::ItemAcceptsInputMethod));
+ else
+ setFlags(this->flags() | QGraphicsItem::ItemIsFocusable | QGraphicsItem::ItemAcceptsInputMethod);
+
+ dd->textControl()->setTextInteractionFlags(flags);
+}
+
+/*!
+ Returns the current text interaction flags.
+
+ \sa setTextInteractionFlags()
+*/
+Qt::TextInteractionFlags QGraphicsTextItem::textInteractionFlags() const
+{
+ if (!dd->control)
+ return Qt::NoTextInteraction;
+ return dd->control->textInteractionFlags();
+}
+
+/*!
+ \since 4.5
+
+ If \a b is true, the \gui Tab key will cause the widget to change focus;
+ otherwise, the tab key will insert a tab into the document.
+
+ In some occasions text edits should not allow the user to input tabulators
+ or change indentation using the \gui Tab key, as this breaks the focus
+ chain. The default is false.
+
+ \sa tabChangesFocus(), ItemIsFocusable, textInteractionFlags()
+*/
+void QGraphicsTextItem::setTabChangesFocus(bool b)
+{
+ dd->tabChangesFocus = b;
+}
+
+/*!
+ \since 4.5
+
+ 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
+{
+ return dd->tabChangesFocus;
+}
+
+/*!
+ \property QGraphicsTextItem::openExternalLinks
+
+ Specifies whether QGraphicsTextItem should automatically open links using
+ QDesktopServices::openUrl() instead of emitting the
+ linkActivated signal.
+
+ The default value is false.
+*/
+void QGraphicsTextItem::setOpenExternalLinks(bool open)
+{
+ dd->textControl()->setOpenExternalLinks(open);
+}
+
+bool QGraphicsTextItem::openExternalLinks() const
+{
+ if (!dd->control)
+ return false;
+ return dd->control->openExternalLinks();
+}
+
+/*!
+ \property QGraphicsTextItem::textCursor
+
+ This property represents the visible text cursor in an editable
+ text item.
+
+ By default, if the item's text has not been set, this property
+ contains a null text cursor; otherwise it contains a text cursor
+ placed at the start of the item's document.
+*/
+void QGraphicsTextItem::setTextCursor(const QTextCursor &cursor)
+{
+ dd->textControl()->setTextCursor(cursor);
+}
+
+QTextCursor QGraphicsTextItem::textCursor() const
+{
+ if (!dd->control)
+ return QTextCursor();
+ return dd->control->textCursor();
+}
+
+class QGraphicsSimpleTextItemPrivate : public QAbstractGraphicsShapeItemPrivate
+{
+ Q_DECLARE_PUBLIC(QGraphicsSimpleTextItem)
+public:
+ inline QGraphicsSimpleTextItemPrivate() {
+ pen.setStyle(Qt::NoPen);
+ brush.setStyle(Qt::SolidPattern);
+ }
+ QString text;
+ QFont font;
+ QRectF boundingRect;
+
+ void updateBoundingRect();
+};
+
+static QRectF setupTextLayout(QTextLayout *layout)
+{
+ layout->setCacheEnabled(true);
+ layout->beginLayout();
+ while (layout->createLine().isValid())
+ ;
+ layout->endLayout();
+ qreal maxWidth = 0;
+ qreal y = 0;
+ for (int i = 0; i < layout->lineCount(); ++i) {
+ QTextLine line = layout->lineAt(i);
+ maxWidth = qMax(maxWidth, line.naturalTextWidth());
+ line.setPosition(QPointF(0, y));
+ y += line.height();
+ }
+ return QRectF(0, 0, maxWidth, y);
+}
+
+void QGraphicsSimpleTextItemPrivate::updateBoundingRect()
+{
+ Q_Q(QGraphicsSimpleTextItem);
+ QRectF br;
+ if (text.isEmpty()) {
+ br = QRectF();
+ } else {
+ QString tmp = text;
+ tmp.replace(QLatin1Char('\n'), QChar::LineSeparator);
+ QStackTextEngine engine(tmp, font);
+ QTextLayout layout(&engine);
+ br = setupTextLayout(&layout);
+ }
+ if (br != boundingRect) {
+ q->prepareGeometryChange();
+ boundingRect = br;
+ q->update();
+ }
+}
+
+/*!
+ \class QGraphicsSimpleTextItem
+ \brief The QGraphicsSimpleTextItem class provides a simple text path item
+ that you can add to a QGraphicsScene.
+ \since 4.2
+ \ingroup graphicsview-api
+
+ To set the item's text, you can either pass a QString to
+ QGraphicsSimpleTextItem's constructor, or call setText() to change the
+ text later. To set the text fill color, call setBrush().
+
+ The simple text item can have both a fill and an outline; setBrush() will
+ set the text fill (i.e., text color), and setPen() sets the pen that will
+ be used to draw the text outline. (The latter can be slow, especially for
+ complex pens, and items with long text content.) If all you want is to
+ draw a simple line of text, you should call setBrush() only, and leave the
+ pen unset; QGraphicsSimpleTextItem's pen is by default Qt::NoPen.
+
+ QGraphicsSimpleTextItem uses the text's formatted size and the associated
+ font to provide a reasonable implementation of boundingRect(), shape(),
+ and contains(). You can set the font by calling setFont().
+
+ QGraphicsSimpleText does not display rich text; instead, you can use
+ QGraphicsTextItem, which provides full text control capabilities.
+
+ \img graphicsview-simpletextitem.png
+
+ \sa QGraphicsTextItem, QGraphicsPathItem, QGraphicsRectItem,
+ QGraphicsEllipseItem, QGraphicsPixmapItem, QGraphicsPolygonItem,
+ QGraphicsLineItem, {Graphics View Framework}
+*/
+
+/*!
+ Constructs a QGraphicsSimpleTextItem.
+
+ \a parent is passed to QGraphicsItem's constructor.
+
+ \sa QGraphicsScene::addItem()
+*/
+QGraphicsSimpleTextItem::QGraphicsSimpleTextItem(QGraphicsItem *parent
+#ifndef Q_QDOC
+ // obsolete argument
+ , QGraphicsScene *scene
+#endif
+ )
+ : QAbstractGraphicsShapeItem(*new QGraphicsSimpleTextItemPrivate, parent, scene)
+{
+}
+
+/*!
+ Constructs a QGraphicsSimpleTextItem, using \a text as the default plain text.
+
+ \a parent is passed to QGraphicsItem's constructor.
+
+ \sa QGraphicsScene::addItem()
+*/
+QGraphicsSimpleTextItem::QGraphicsSimpleTextItem(const QString &text, QGraphicsItem *parent
+#ifndef Q_QDOC
+ // obsolete argument
+ , QGraphicsScene *scene
+#endif
+ )
+ : QAbstractGraphicsShapeItem(*new QGraphicsSimpleTextItemPrivate, parent, scene)
+{
+ setText(text);
+}
+
+/*!
+ Destroys the QGraphicsSimpleTextItem.
+*/
+QGraphicsSimpleTextItem::~QGraphicsSimpleTextItem()
+{
+}
+
+/*!
+ Sets the item's text to \a text. The text will be displayed as
+ plain text. Newline characters ('\n') as well as characters of
+ type QChar::LineSeparator will cause item to break the text into
+ multiple lines.
+*/
+void QGraphicsSimpleTextItem::setText(const QString &text)
+{
+ Q_D(QGraphicsSimpleTextItem);
+ if (d->text == text)
+ return;
+ d->text = text;
+ d->updateBoundingRect();
+ update();
+}
+
+/*!
+ Returns the item's text.
+*/
+QString QGraphicsSimpleTextItem::text() const
+{
+ Q_D(const QGraphicsSimpleTextItem);
+ return d->text;
+}
+
+/*!
+ Sets the font that is used to draw the item's text to \a font.
+*/
+void QGraphicsSimpleTextItem::setFont(const QFont &font)
+{
+ Q_D(QGraphicsSimpleTextItem);
+ d->font = font;
+ d->updateBoundingRect();
+}
+
+/*!
+ Returns the font that is used to draw the item's text.
+*/
+QFont QGraphicsSimpleTextItem::font() const
+{
+ Q_D(const QGraphicsSimpleTextItem);
+ return d->font;
+}
+
+/*!
+ \reimp
+*/
+QRectF QGraphicsSimpleTextItem::boundingRect() const
+{
+ Q_D(const QGraphicsSimpleTextItem);
+ return d->boundingRect;
+}
+
+/*!
+ \reimp
+*/
+QPainterPath QGraphicsSimpleTextItem::shape() const
+{
+ Q_D(const QGraphicsSimpleTextItem);
+ QPainterPath path;
+ path.addRect(d->boundingRect);
+ return path;
+}
+
+/*!
+ \reimp
+*/
+bool QGraphicsSimpleTextItem::contains(const QPointF &point) const
+{
+ Q_D(const QGraphicsSimpleTextItem);
+ return d->boundingRect.contains(point);
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsSimpleTextItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+ Q_UNUSED(widget);
+ Q_D(QGraphicsSimpleTextItem);
+
+ painter->setFont(d->font);
+
+ QString tmp = d->text;
+ tmp.replace(QLatin1Char('\n'), QChar::LineSeparator);
+ QStackTextEngine engine(tmp, d->font);
+ QTextLayout layout(&engine);
+ setupTextLayout(&layout);
+
+ QPen p;
+ p.setBrush(d->brush);
+ painter->setPen(p);
+ if (d->pen.style() == Qt::NoPen && d->brush.style() == Qt::SolidPattern) {
+ painter->setBrush(Qt::NoBrush);
+ } else {
+ QTextLayout::FormatRange range;
+ range.start = 0;
+ range.length = layout.text().length();
+ range.format.setTextOutline(d->pen);
+ QList<QTextLayout::FormatRange> formats;
+ formats.append(range);
+ layout.setAdditionalFormats(formats);
+ }
+
+ layout.draw(painter, QPointF(0, 0));
+
+ if (option->state & (QStyle::State_Selected | QStyle::State_HasFocus))
+ qt_graphicsItem_highlightSelected(this, painter, option);
+}
+
+/*!
+ \reimp
+*/
+bool QGraphicsSimpleTextItem::isObscuredBy(const QGraphicsItem *item) const
+{
+ return QAbstractGraphicsShapeItem::isObscuredBy(item);
+}
+
+/*!
+ \reimp
+*/
+QPainterPath QGraphicsSimpleTextItem::opaqueArea() const
+{
+ return QAbstractGraphicsShapeItem::opaqueArea();
+}
+
+/*!
+ \reimp
+*/
+int QGraphicsSimpleTextItem::type() const
+{
+ return Type;
+}
+
+/*!
+ \internal
+*/
+bool QGraphicsSimpleTextItem::supportsExtension(Extension extension) const
+{
+ Q_UNUSED(extension);
+ return false;
+}
+
+/*!
+ \internal
+*/
+void QGraphicsSimpleTextItem::setExtension(Extension extension, const QVariant &variant)
+{
+ Q_UNUSED(extension);
+ Q_UNUSED(variant);
+}
+
+/*!
+ \internal
+*/
+QVariant QGraphicsSimpleTextItem::extension(const QVariant &variant) const
+{
+ Q_UNUSED(variant);
+ return QVariant();
+}
+
+/*!
+ \class QGraphicsItemGroup
+ \brief The QGraphicsItemGroup class provides a container that treats
+ a group of items as a single item.
+ \since 4.2
+ \ingroup graphicsview-api
+
+ A QGraphicsItemGroup is a special type of compound item that
+ treats itself and all its children as one item (i.e., all events
+ and geometries for all children are merged together). It's common
+ to use item groups in presentation tools, when the user wants to
+ group several smaller items into one big item in order to simplify
+ moving and copying of items.
+
+ If all you want is to store items inside other items, you can use
+ any QGraphicsItem directly by passing a suitable parent to
+ setParentItem().
+
+ The boundingRect() function of QGraphicsItemGroup returns the
+ bounding rectangle of all items in the item group.
+ QGraphicsItemGroup ignores the ItemIgnoresTransformations flag on
+ its children (i.e., with respect to the geometry of the group
+ item, the children are treated as if they were transformable).
+
+ There are two ways to construct an item group. The easiest and
+ most common approach is to pass a list of items (e.g., all
+ selected items) to QGraphicsScene::createItemGroup(), which
+ returns a new QGraphicsItemGroup item. The other approach is to
+ manually construct a QGraphicsItemGroup item, add it to the scene
+ calling QGraphicsScene::addItem(), and then add items to the group
+ manually, one at a time by calling addToGroup(). To dismantle
+ ("ungroup") an item group, you can either call
+ QGraphicsScene::destroyItemGroup(), or you can manually remove all
+ items from the group by calling removeFromGroup().
+
+ \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 17
+
+ The operation of adding and removing items preserves the items'
+ scene-relative position and transformation, as opposed to calling
+ setParentItem(), where only the child item's parent-relative
+ position and transformation are kept.
+
+ The addtoGroup() function reparents the target item to this item
+ group, keeping the item's position and transformation intact
+ relative to the scene. Visually, this means that items added via
+ addToGroup() will remain completely unchanged as a result of this
+ operation, regardless of the item or the group's current position
+ or transformation; although the item's position and matrix are
+ likely to change.
+
+ The removeFromGroup() function has similar semantics to
+ setParentItem(); it reparents the item to the parent item of the
+ item group. As with addToGroup(), the item's scene-relative
+ position and transformation remain intact.
+
+ \sa QGraphicsItem, {Graphics View Framework}
+*/
+
+class QGraphicsItemGroupPrivate : public QGraphicsItemPrivate
+{
+public:
+ QRectF itemsBoundingRect;
+};
+
+/*!
+ Constructs a QGraphicsItemGroup. \a parent is passed to QGraphicsItem's
+ constructor.
+
+ \sa QGraphicsScene::addItem()
+*/
+QGraphicsItemGroup::QGraphicsItemGroup(QGraphicsItem *parent
+#ifndef Q_QDOC
+ // obsolete argument
+ , QGraphicsScene *scene
+#endif
+ )
+ : QGraphicsItem(*new QGraphicsItemGroupPrivate, parent, scene)
+{
+ setHandlesChildEvents(true);
+}
+
+/*!
+ Destroys the QGraphicsItemGroup.
+*/
+QGraphicsItemGroup::~QGraphicsItemGroup()
+{
+}
+
+/*!
+ Adds the given \a item to this item group. The item will be
+ reparented to this group, but its position and transformation
+ relative to the scene will stay intact.
+
+ \sa removeFromGroup(), QGraphicsScene::createItemGroup()
+*/
+void QGraphicsItemGroup::addToGroup(QGraphicsItem *item)
+{
+ Q_D(QGraphicsItemGroup);
+ if (!item) {
+ qWarning("QGraphicsItemGroup::addToGroup: cannot add null item");
+ return;
+ }
+ if (item == this) {
+ qWarning("QGraphicsItemGroup::addToGroup: cannot add a group to itself");
+ return;
+ }
+
+ // COMBINE
+ bool ok;
+ QTransform itemTransform = item->itemTransform(this, &ok);
+
+ if (!ok) {
+ qWarning("QGraphicsItemGroup::addToGroup: could not find a valid transformation from item to group coordinates");
+ return;
+ }
+
+ QTransform newItemTransform(itemTransform);
+ item->setPos(mapFromItem(item, 0, 0));
+ item->setParentItem(this);
+
+ // removing position from translation component of the new transform
+ if (!item->pos().isNull())
+ newItemTransform *= QTransform::fromTranslate(-item->x(), -item->y());
+
+ // removing additional transformations properties applied with itemTransform()
+ QPointF origin = item->transformOriginPoint();
+ QMatrix4x4 m;
+ QList<QGraphicsTransform*> transformList = item->transformations();
+ for (int i = 0; i < transformList.size(); ++i)
+ transformList.at(i)->applyTo(&m);
+ newItemTransform *= m.toTransform().inverted();
+ newItemTransform.translate(origin.x(), origin.y());
+ newItemTransform.rotate(-item->rotation());
+ newItemTransform.scale(1/item->scale(), 1/item->scale());
+ newItemTransform.translate(-origin.x(), -origin.y());
+
+ // ### Expensive, we could maybe use dirtySceneTransform bit for optimization
+
+ item->setTransform(newItemTransform);
+ item->d_func()->setIsMemberOfGroup(true);
+ prepareGeometryChange();
+ d->itemsBoundingRect |= itemTransform.mapRect(item->boundingRect() | item->childrenBoundingRect());
+ update();
+}
+
+/*!
+ Removes the specified \a item from this group. The item will be
+ reparented to this group's parent item, or to 0 if this group has
+ no parent. Its position and transformation relative to the scene
+ will stay intact.
+
+ \sa addToGroup(), QGraphicsScene::destroyItemGroup()
+*/
+void QGraphicsItemGroup::removeFromGroup(QGraphicsItem *item)
+{
+ Q_D(QGraphicsItemGroup);
+ if (!item) {
+ qWarning("QGraphicsItemGroup::removeFromGroup: cannot remove null item");
+ return;
+ }
+
+ QGraphicsItem *newParent = d_ptr->parent;
+
+ // COMBINE
+ bool ok;
+ QTransform itemTransform;
+ if (newParent)
+ itemTransform = item->itemTransform(newParent, &ok);
+ else
+ itemTransform = item->sceneTransform();
+
+ QPointF oldPos = item->mapToItem(newParent, 0, 0);
+ item->setParentItem(newParent);
+ item->setPos(oldPos);
+
+ // removing position from translation component of the new transform
+ if (!item->pos().isNull())
+ itemTransform *= QTransform::fromTranslate(-item->x(), -item->y());
+
+ // removing additional transformations properties applied
+ // with itemTransform() or sceneTransform()
+ QPointF origin = item->transformOriginPoint();
+ QMatrix4x4 m;
+ QList<QGraphicsTransform*> transformList = item->transformations();
+ for (int i = 0; i < transformList.size(); ++i)
+ transformList.at(i)->applyTo(&m);
+ itemTransform *= m.toTransform().inverted();
+ itemTransform.translate(origin.x(), origin.y());
+ itemTransform.rotate(-item->rotation());
+ itemTransform.scale(1 / item->scale(), 1 / item->scale());
+ itemTransform.translate(-origin.x(), -origin.y());
+
+ // ### Expensive, we could maybe use dirtySceneTransform bit for optimization
+
+ item->setTransform(itemTransform);
+ item->d_func()->setIsMemberOfGroup(item->group() != 0);
+
+ // ### Quite expensive. But removeFromGroup() isn't called very often.
+ prepareGeometryChange();
+ d->itemsBoundingRect = childrenBoundingRect();
+}
+
+/*!
+ \reimp
+
+ Returns the bounding rect of this group item, and all its children.
+*/
+QRectF QGraphicsItemGroup::boundingRect() const
+{
+ Q_D(const QGraphicsItemGroup);
+ return d->itemsBoundingRect;
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsItemGroup::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
+ QWidget *widget)
+{
+ Q_UNUSED(widget);
+ if (option->state & QStyle::State_Selected) {
+ Q_D(QGraphicsItemGroup);
+ painter->setBrush(Qt::NoBrush);
+ painter->drawRect(d->itemsBoundingRect);
+ }
+}
+
+/*!
+ \reimp
+*/
+bool QGraphicsItemGroup::isObscuredBy(const QGraphicsItem *item) const
+{
+ return QGraphicsItem::isObscuredBy(item);
+}
+
+/*!
+ \reimp
+*/
+QPainterPath QGraphicsItemGroup::opaqueArea() const
+{
+ return QGraphicsItem::opaqueArea();
+}
+
+/*!
+ \reimp
+*/
+int QGraphicsItemGroup::type() const
+{
+ return Type;
+}
+
+#ifndef QT_NO_GRAPHICSEFFECT
+QRectF QGraphicsItemEffectSourcePrivate::boundingRect(Qt::CoordinateSystem system) const
+{
+ const bool deviceCoordinates = (system == Qt::DeviceCoordinates);
+ if (!info && deviceCoordinates) {
+ // Device coordinates without info not yet supported.
+ qWarning("QGraphicsEffectSource::boundingRect: Not yet implemented, lacking device context");
+ return QRectF();
+ }
+
+ QRectF rect = item->boundingRect();
+ if (!item->d_ptr->children.isEmpty())
+ rect |= item->childrenBoundingRect();
+
+ if (deviceCoordinates) {
+ Q_ASSERT(info->painter);
+ rect = info->painter->worldTransform().mapRect(rect);
+ }
+
+ return rect;
+}
+
+void QGraphicsItemEffectSourcePrivate::draw(QPainter *painter)
+{
+ if (!info) {
+ qWarning("QGraphicsEffectSource::draw: Can only begin as a result of QGraphicsEffect::draw");
+ return;
+ }
+
+ Q_ASSERT(item->d_ptr->scene);
+ QGraphicsScenePrivate *scened = item->d_ptr->scene->d_func();
+ if (painter == info->painter) {
+ scened->draw(item, painter, info->viewTransform, info->transformPtr, info->exposedRegion,
+ info->widget, info->opacity, info->effectTransform, info->wasDirtySceneTransform,
+ info->drawItem);
+ } else {
+ QTransform effectTransform = info->painter->worldTransform().inverted();
+ effectTransform *= painter->worldTransform();
+ scened->draw(item, painter, info->viewTransform, info->transformPtr, info->exposedRegion,
+ info->widget, info->opacity, &effectTransform, info->wasDirtySceneTransform,
+ info->drawItem);
+ }
+}
+
+// sourceRect must be in the given coordinate system
+QRect QGraphicsItemEffectSourcePrivate::paddedEffectRect(Qt::CoordinateSystem system, QGraphicsEffect::PixmapPadMode mode, const QRectF &sourceRect, bool *unpadded) const
+{
+ QRectF effectRectF;
+
+ if (unpadded)
+ *unpadded = false;
+
+ if (mode == QGraphicsEffect::PadToEffectiveBoundingRect) {
+ if (info) {
+ QRectF deviceRect = system == Qt::DeviceCoordinates ? sourceRect : info->painter->worldTransform().mapRect(sourceRect);
+ effectRectF = item->graphicsEffect()->boundingRectFor(deviceRect);
+ if (unpadded)
+ *unpadded = (effectRectF.size() == sourceRect.size());
+ if (info && system == Qt::LogicalCoordinates)
+ effectRectF = info->painter->worldTransform().inverted().mapRect(effectRectF);
+ } else {
+ // no choice but to send a logical coordinate bounding rect to boundingRectFor
+ effectRectF = item->graphicsEffect()->boundingRectFor(sourceRect);
+ }
+ } else if (mode == QGraphicsEffect::PadToTransparentBorder) {
+ // adjust by 1.5 to account for cosmetic pens
+ effectRectF = sourceRect.adjusted(-1.5, -1.5, 1.5, 1.5);
+ } else {
+ effectRectF = sourceRect;
+ if (unpadded)
+ *unpadded = true;
+ }
+
+ return effectRectF.toAlignedRect();
+}
+
+QPixmap QGraphicsItemEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QPoint *offset,
+ QGraphicsEffect::PixmapPadMode mode) const
+{
+ const bool deviceCoordinates = (system == Qt::DeviceCoordinates);
+ if (!info && deviceCoordinates) {
+ // Device coordinates without info not yet supported.
+ qWarning("QGraphicsEffectSource::pixmap: Not yet implemented, lacking device context");
+ return QPixmap();
+ }
+ if (!item->d_ptr->scene)
+ return QPixmap();
+ QGraphicsScenePrivate *scened = item->d_ptr->scene->d_func();
+
+ bool unpadded;
+ const QRectF sourceRect = boundingRect(system);
+ QRect effectRect = paddedEffectRect(system, mode, sourceRect, &unpadded);
+
+ if (offset)
+ *offset = effectRect.topLeft();
+
+ bool untransformed = !deviceCoordinates
+ || info->painter->worldTransform().type() <= QTransform::TxTranslate;
+ if (untransformed && unpadded && isPixmap()) {
+ if (offset)
+ *offset = boundingRect(system).topLeft().toPoint();
+ return static_cast<QGraphicsPixmapItem *>(item)->pixmap();
+ }
+
+ if (effectRect.isEmpty())
+ return QPixmap();
+
+ QPixmap pixmap(effectRect.size());
+ pixmap.fill(Qt::transparent);
+ QPainter pixmapPainter(&pixmap);
+ pixmapPainter.setRenderHints(info ? info->painter->renderHints() : QPainter::TextAntialiasing);
+
+ QTransform effectTransform = QTransform::fromTranslate(-effectRect.x(), -effectRect.y());
+ if (deviceCoordinates && info->effectTransform)
+ effectTransform *= *info->effectTransform;
+
+ if (!info) {
+ // Logical coordinates without info.
+ QTransform sceneTransform = item->sceneTransform();
+ QTransform newEffectTransform = sceneTransform.inverted();
+ newEffectTransform *= effectTransform;
+ scened->draw(item, &pixmapPainter, 0, &sceneTransform, 0, 0, qreal(1.0),
+ &newEffectTransform, false, true);
+ } else if (deviceCoordinates) {
+ // Device coordinates with info.
+ scened->draw(item, &pixmapPainter, info->viewTransform, info->transformPtr, 0,
+ info->widget, info->opacity, &effectTransform, info->wasDirtySceneTransform,
+ info->drawItem);
+ } else {
+ // Item coordinates with info.
+ QTransform newEffectTransform = info->transformPtr->inverted();
+ newEffectTransform *= effectTransform;
+ scened->draw(item, &pixmapPainter, info->viewTransform, info->transformPtr, 0,
+ info->widget, info->opacity, &newEffectTransform, info->wasDirtySceneTransform,
+ info->drawItem);
+ }
+
+ pixmapPainter.end();
+
+ return pixmap;
+}
+#endif //QT_NO_GRAPHICSEFFECT
+
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug debug, QGraphicsItem *item)
+{
+ if (!item) {
+ debug << "QGraphicsItem(0)";
+ return debug;
+ }
+
+ if (QGraphicsObject *o = item->toGraphicsObject())
+ debug << o->metaObject()->className();
+ else
+ debug << "QGraphicsItem";
+ debug << "(this =" << (void*)item
+ << ", parent =" << (void*)item->parentItem()
+ << ", pos =" << item->pos()
+ << ", z =" << item->zValue() << ", flags = "
+ << item->flags() << ")";
+ return debug;
+}
+
+QDebug operator<<(QDebug debug, QGraphicsObject *item)
+{
+ if (!item) {
+ debug << "QGraphicsObject(0)";
+ return debug;
+ }
+
+ debug.nospace() << item->metaObject()->className() << '(' << (void*)item;
+ if (!item->objectName().isEmpty())
+ debug << ", name = " << item->objectName();
+ debug.nospace() << ", parent = " << ((void*)item->parentItem())
+ << ", pos = " << item->pos()
+ << ", z = " << item->zValue() << ", flags = "
+ << item->flags() << ')';
+ return debug.space();
+}
+
+QDebug operator<<(QDebug debug, QGraphicsItem::GraphicsItemChange change)
+{
+ const char *str = "UnknownChange";
+ switch (change) {
+ case QGraphicsItem::ItemChildAddedChange:
+ str = "ItemChildAddedChange";
+ break;
+ case QGraphicsItem::ItemChildRemovedChange:
+ str = "ItemChildRemovedChange";
+ break;
+ case QGraphicsItem::ItemCursorChange:
+ str = "ItemCursorChange";
+ break;
+ case QGraphicsItem::ItemCursorHasChanged:
+ str = "ItemCursorHasChanged";
+ break;
+ case QGraphicsItem::ItemEnabledChange:
+ str = "ItemEnabledChange";
+ break;
+ case QGraphicsItem::ItemEnabledHasChanged:
+ str = "ItemEnabledHasChanged";
+ break;
+ case QGraphicsItem::ItemFlagsChange:
+ str = "ItemFlagsChange";
+ break;
+ case QGraphicsItem::ItemFlagsHaveChanged:
+ str = "ItemFlagsHaveChanged";
+ break;
+ case QGraphicsItem::ItemMatrixChange:
+ str = "ItemMatrixChange";
+ break;
+ case QGraphicsItem::ItemParentChange:
+ str = "ItemParentChange";
+ break;
+ case QGraphicsItem::ItemParentHasChanged:
+ str = "ItemParentHasChanged";
+ break;
+ case QGraphicsItem::ItemPositionChange:
+ str = "ItemPositionChange";
+ break;
+ case QGraphicsItem::ItemPositionHasChanged:
+ str = "ItemPositionHasChanged";
+ break;
+ case QGraphicsItem::ItemSceneChange:
+ str = "ItemSceneChange";
+ break;
+ case QGraphicsItem::ItemSceneHasChanged:
+ str = "ItemSceneHasChanged";
+ break;
+ case QGraphicsItem::ItemSelectedChange:
+ str = "ItemSelectedChange";
+ break;
+ case QGraphicsItem::ItemSelectedHasChanged:
+ str = "ItemSelectedHasChanged";
+ break;
+ case QGraphicsItem::ItemToolTipChange:
+ str = "ItemToolTipChange";
+ break;
+ case QGraphicsItem::ItemToolTipHasChanged:
+ str = "ItemToolTipHasChanged";
+ break;
+ case QGraphicsItem::ItemTransformChange:
+ str = "ItemTransformChange";
+ break;
+ case QGraphicsItem::ItemTransformHasChanged:
+ str = "ItemTransformHasChanged";
+ break;
+ case QGraphicsItem::ItemVisibleChange:
+ str = "ItemVisibleChange";
+ break;
+ case QGraphicsItem::ItemVisibleHasChanged:
+ str = "ItemVisibleHasChanged";
+ break;
+ case QGraphicsItem::ItemZValueChange:
+ str = "ItemZValueChange";
+ break;
+ case QGraphicsItem::ItemZValueHasChanged:
+ str = "ItemZValueHasChanged";
+ break;
+ case QGraphicsItem::ItemOpacityChange:
+ str = "ItemOpacityChange";
+ break;
+ case QGraphicsItem::ItemOpacityHasChanged:
+ str = "ItemOpacityHasChanged";
+ break;
+ case QGraphicsItem::ItemScenePositionHasChanged:
+ str = "ItemScenePositionHasChanged";
+ break;
+ case QGraphicsItem::ItemRotationChange:
+ str = "ItemRotationChange";
+ break;
+ case QGraphicsItem::ItemRotationHasChanged:
+ str = "ItemRotationHasChanged";
+ break;
+ case QGraphicsItem::ItemScaleChange:
+ str = "ItemScaleChange";
+ break;
+ case QGraphicsItem::ItemScaleHasChanged:
+ str = "ItemScaleHasChanged";
+ break;
+ case QGraphicsItem::ItemTransformOriginPointChange:
+ str = "ItemTransformOriginPointChange";
+ break;
+ case QGraphicsItem::ItemTransformOriginPointHasChanged:
+ str = "ItemTransformOriginPointHasChanged";
+ break;
+ }
+ debug << str;
+ return debug;
+}
+
+QDebug operator<<(QDebug debug, QGraphicsItem::GraphicsItemFlag flag)
+{
+ const char *str = "UnknownFlag";
+ switch (flag) {
+ case QGraphicsItem::ItemIsMovable:
+ str = "ItemIsMovable";
+ break;
+ case QGraphicsItem::ItemIsSelectable:
+ str = "ItemIsSelectable";
+ break;
+ case QGraphicsItem::ItemIsFocusable:
+ str = "ItemIsFocusable";
+ break;
+ case QGraphicsItem::ItemClipsToShape:
+ str = "ItemClipsToShape";
+ break;
+ case QGraphicsItem::ItemClipsChildrenToShape:
+ str = "ItemClipsChildrenToShape";
+ break;
+ case QGraphicsItem::ItemIgnoresTransformations:
+ str = "ItemIgnoresTransformations";
+ break;
+ case QGraphicsItem::ItemIgnoresParentOpacity:
+ str = "ItemIgnoresParentOpacity";
+ break;
+ case QGraphicsItem::ItemDoesntPropagateOpacityToChildren:
+ str = "ItemDoesntPropagateOpacityToChildren";
+ break;
+ case QGraphicsItem::ItemStacksBehindParent:
+ str = "ItemStacksBehindParent";
+ break;
+ case QGraphicsItem::ItemUsesExtendedStyleOption:
+ str = "ItemUsesExtendedStyleOption";
+ break;
+ case QGraphicsItem::ItemHasNoContents:
+ str = "ItemHasNoContents";
+ break;
+ case QGraphicsItem::ItemSendsGeometryChanges:
+ str = "ItemSendsGeometryChanges";
+ break;
+ case QGraphicsItem::ItemAcceptsInputMethod:
+ str = "ItemAcceptsInputMethod";
+ break;
+ case QGraphicsItem::ItemNegativeZStacksBehindParent:
+ str = "ItemNegativeZStacksBehindParent";
+ break;
+ case QGraphicsItem::ItemIsPanel:
+ str = "ItemIsPanel";
+ break;
+ case QGraphicsItem::ItemIsFocusScope:
+ str = "ItemIsFocusScope";
+ break;
+ case QGraphicsItem::ItemSendsScenePositionChanges:
+ str = "ItemSendsScenePositionChanges";
+ break;
+ case QGraphicsItem::ItemStopsClickFocusPropagation:
+ str = "ItemStopsClickFocusPropagation";
+ break;
+ case QGraphicsItem::ItemStopsFocusHandling:
+ str = "ItemStopsFocusHandling";
+ break;
+ }
+ debug << str;
+ return debug;
+}
+
+QDebug operator<<(QDebug debug, QGraphicsItem::GraphicsItemFlags flags)
+{
+ debug << '(';
+ bool f = false;
+ for (int i = 0; i < 17; ++i) {
+ if (flags & (1 << i)) {
+ if (f)
+ debug << '|';
+ f = true;
+ debug << QGraphicsItem::GraphicsItemFlag(int(flags & (1 << i)));
+ }
+ }
+ debug << ')';
+ return debug;
+}
+
+#endif
+
+QT_END_NAMESPACE
+
+#include "moc_qgraphicsitem.cpp"
+
+#endif // QT_NO_GRAPHICSVIEW
diff --git a/src/widgets/graphicsview/qgraphicsitem.h b/src/widgets/graphicsview/qgraphicsitem.h
new file mode 100644
index 0000000000..1e4cbaced6
--- /dev/null
+++ b/src/widgets/graphicsview/qgraphicsitem.h
@@ -0,0 +1,1172 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGRAPHICSITEM_H
+#define QGRAPHICSITEM_H
+
+#include <QtCore/qglobal.h>
+#include <QtCore/qobject.h>
+#include <QtCore/qvariant.h>
+#include <QtCore/qrect.h>
+#include <QtCore/qscopedpointer.h>
+#include <QtGui/qpainterpath.h>
+#include <QtGui/qpixmap.h>
+
+class tst_QGraphicsItem;
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW
+
+class QBrush;
+class QCursor;
+class QFocusEvent;
+class QGraphicsEffect;
+class QGraphicsItemGroup;
+class QGraphicsObject;
+class QGraphicsSceneContextMenuEvent;
+class QGraphicsSceneDragDropEvent;
+class QGraphicsSceneEvent;
+class QGraphicsSceneHoverEvent;
+class QGraphicsSceneMouseEvent;
+class QGraphicsSceneWheelEvent;
+class QGraphicsScene;
+class QGraphicsTransform;
+class QGraphicsWidget;
+class QInputMethodEvent;
+class QKeyEvent;
+class QMatrix;
+class QMenu;
+class QPainter;
+class QPen;
+class QPointF;
+class QRectF;
+class QStyleOptionGraphicsItem;
+
+class QGraphicsItemPrivate;
+class Q_WIDGETS_EXPORT QGraphicsItem
+{
+public:
+ enum GraphicsItemFlag {
+ ItemIsMovable = 0x1,
+ ItemIsSelectable = 0x2,
+ ItemIsFocusable = 0x4,
+ ItemClipsToShape = 0x8,
+ ItemClipsChildrenToShape = 0x10,
+ ItemIgnoresTransformations = 0x20,
+ ItemIgnoresParentOpacity = 0x40,
+ ItemDoesntPropagateOpacityToChildren = 0x80,
+ ItemStacksBehindParent = 0x100,
+ ItemUsesExtendedStyleOption = 0x200,
+ ItemHasNoContents = 0x400,
+ ItemSendsGeometryChanges = 0x800,
+ ItemAcceptsInputMethod = 0x1000,
+ ItemNegativeZStacksBehindParent = 0x2000,
+ ItemIsPanel = 0x4000,
+ ItemIsFocusScope = 0x8000, // internal
+ ItemSendsScenePositionChanges = 0x10000,
+ ItemStopsClickFocusPropagation = 0x20000,
+ ItemStopsFocusHandling = 0x40000
+ // NB! Don't forget to increase the d_ptr->flags bit field by 1 when adding a new flag.
+ };
+ Q_DECLARE_FLAGS(GraphicsItemFlags, GraphicsItemFlag)
+
+ enum GraphicsItemChange {
+ ItemPositionChange,
+ ItemMatrixChange,
+ ItemVisibleChange,
+ ItemEnabledChange,
+ ItemSelectedChange,
+ ItemParentChange,
+ ItemChildAddedChange,
+ ItemChildRemovedChange,
+ ItemTransformChange,
+ ItemPositionHasChanged,
+ ItemTransformHasChanged,
+ ItemSceneChange,
+ ItemVisibleHasChanged,
+ ItemEnabledHasChanged,
+ ItemSelectedHasChanged,
+ ItemParentHasChanged,
+ ItemSceneHasChanged,
+ ItemCursorChange,
+ ItemCursorHasChanged,
+ ItemToolTipChange,
+ ItemToolTipHasChanged,
+ ItemFlagsChange,
+ ItemFlagsHaveChanged,
+ ItemZValueChange,
+ ItemZValueHasChanged,
+ ItemOpacityChange,
+ ItemOpacityHasChanged,
+ ItemScenePositionHasChanged,
+ ItemRotationChange,
+ ItemRotationHasChanged,
+ ItemScaleChange,
+ ItemScaleHasChanged,
+ ItemTransformOriginPointChange,
+ ItemTransformOriginPointHasChanged
+ };
+
+ enum CacheMode {
+ NoCache,
+ ItemCoordinateCache,
+ DeviceCoordinateCache
+ };
+
+ enum PanelModality
+ {
+ NonModal,
+ PanelModal,
+ SceneModal
+ };
+
+ QGraphicsItem(QGraphicsItem *parent = 0
+#ifndef Q_QDOC
+ // ### obsolete argument
+ , QGraphicsScene *scene = 0
+#endif
+ );
+ virtual ~QGraphicsItem();
+
+ QGraphicsScene *scene() const;
+
+ QGraphicsItem *parentItem() const;
+ QGraphicsItem *topLevelItem() const;
+ QGraphicsObject *parentObject() const;
+ QGraphicsWidget *parentWidget() const;
+ QGraphicsWidget *topLevelWidget() const;
+ QGraphicsWidget *window() const;
+ QGraphicsItem *panel() const;
+ void setParentItem(QGraphicsItem *parent);
+ QList<QGraphicsItem *> children() const; // ### obsolete
+ QList<QGraphicsItem *> childItems() const;
+ bool isWidget() const;
+ bool isWindow() const;
+ bool isPanel() const;
+
+ QGraphicsObject *toGraphicsObject();
+ const QGraphicsObject *toGraphicsObject() const;
+
+ QGraphicsItemGroup *group() const;
+ void setGroup(QGraphicsItemGroup *group);
+
+ GraphicsItemFlags flags() const;
+ void setFlag(GraphicsItemFlag flag, bool enabled = true);
+ void setFlags(GraphicsItemFlags flags);
+
+ CacheMode cacheMode() const;
+ void setCacheMode(CacheMode mode, const QSize &cacheSize = QSize());
+
+ PanelModality panelModality() const;
+ void setPanelModality(PanelModality panelModality);
+ bool isBlockedByModalPanel(QGraphicsItem **blockingPanel = 0) const;
+
+#ifndef QT_NO_TOOLTIP
+ QString toolTip() const;
+ void setToolTip(const QString &toolTip);
+#endif
+
+#ifndef QT_NO_CURSOR
+ QCursor cursor() const;
+ void setCursor(const QCursor &cursor);
+ bool hasCursor() const;
+ void unsetCursor();
+#endif
+
+ bool isVisible() const;
+ bool isVisibleTo(const QGraphicsItem *parent) const;
+ void setVisible(bool visible);
+ inline void hide() { setVisible(false); }
+ inline void show() { setVisible(true); }
+
+ bool isEnabled() const;
+ void setEnabled(bool enabled);
+
+ bool isSelected() const;
+ void setSelected(bool selected);
+
+ bool acceptDrops() const;
+ void setAcceptDrops(bool on);
+
+ qreal opacity() const;
+ qreal effectiveOpacity() const;
+ void setOpacity(qreal opacity);
+
+#ifndef QT_NO_GRAPHICSEFFECT
+ // Effect
+ QGraphicsEffect *graphicsEffect() const;
+ void setGraphicsEffect(QGraphicsEffect *effect);
+#endif //QT_NO_GRAPHICSEFFECT
+
+ Qt::MouseButtons acceptedMouseButtons() const;
+ void setAcceptedMouseButtons(Qt::MouseButtons buttons);
+
+ bool acceptsHoverEvents() const; // ### obsolete
+ void setAcceptsHoverEvents(bool enabled); // ### obsolete
+ bool acceptHoverEvents() const;
+ void setAcceptHoverEvents(bool enabled);
+ bool acceptTouchEvents() const;
+ void setAcceptTouchEvents(bool enabled);
+
+ bool filtersChildEvents() const;
+ void setFiltersChildEvents(bool enabled);
+
+ bool handlesChildEvents() const;
+ void setHandlesChildEvents(bool enabled);
+
+ bool isActive() const;
+ void setActive(bool active);
+
+ bool hasFocus() const;
+ void setFocus(Qt::FocusReason focusReason = Qt::OtherFocusReason);
+ void clearFocus();
+
+ QGraphicsItem *focusProxy() const;
+ void setFocusProxy(QGraphicsItem *item);
+
+ QGraphicsItem *focusItem() const;
+ QGraphicsItem *focusScopeItem() const;
+
+ void grabMouse();
+ void ungrabMouse();
+ void grabKeyboard();
+ void ungrabKeyboard();
+
+ // Positioning in scene coordinates
+ QPointF pos() const;
+ inline qreal x() const { return pos().x(); }
+ void setX(qreal x);
+ inline qreal y() const { return pos().y(); }
+ void setY(qreal y);
+ QPointF scenePos() const;
+ void setPos(const QPointF &pos);
+ inline void setPos(qreal x, qreal y);
+ inline void moveBy(qreal dx, qreal dy) { setPos(pos().x() + dx, pos().y() + dy); }
+
+ void ensureVisible(const QRectF &rect = QRectF(), int xmargin = 50, int ymargin = 50);
+ inline void ensureVisible(qreal x, qreal y, qreal w, qreal h, int xmargin = 50, int ymargin = 50);
+
+ // Local transformation
+ QMatrix matrix() const;
+ QMatrix sceneMatrix() const;
+ void setMatrix(const QMatrix &matrix, bool combine = false);
+ void resetMatrix();
+ QTransform transform() const;
+ QTransform sceneTransform() const;
+ QTransform deviceTransform(const QTransform &viewportTransform) const;
+ QTransform itemTransform(const QGraphicsItem *other, bool *ok = 0) const;
+ void setTransform(const QTransform &matrix, bool combine = false);
+ void resetTransform();
+
+ void rotate(qreal angle); // ### obsolete
+ void scale(qreal sx, qreal sy); // ### obsolete
+ void shear(qreal sh, qreal sv); // ### obsolete
+ void translate(qreal dx, qreal dy); // ### obsolete
+
+ void setRotation(qreal angle);
+ qreal rotation() const;
+
+ void setScale(qreal scale);
+ qreal scale() const;
+
+ QList<QGraphicsTransform *> transformations() const;
+ void setTransformations(const QList<QGraphicsTransform *> &transformations);
+
+ QPointF transformOriginPoint() const;
+ void setTransformOriginPoint(const QPointF &origin);
+ inline void setTransformOriginPoint(qreal ax, qreal ay)
+ { setTransformOriginPoint(QPointF(ax,ay)); }
+
+ virtual void advance(int phase);
+
+ // Stacking order
+ qreal zValue() const;
+ void setZValue(qreal z);
+ void stackBefore(const QGraphicsItem *sibling);
+
+ // Hit test
+ virtual QRectF boundingRect() const = 0;
+ QRectF childrenBoundingRect() const;
+ QRectF sceneBoundingRect() const;
+ virtual QPainterPath shape() const;
+ bool isClipped() const;
+ QPainterPath clipPath() const;
+ virtual bool contains(const QPointF &point) const;
+ virtual bool collidesWithItem(const QGraphicsItem *other, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const;
+ virtual bool collidesWithPath(const QPainterPath &path, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const;
+ QList<QGraphicsItem *> collidingItems(Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const;
+ bool isObscured() const;
+ bool isObscured(const QRectF &rect) const; // ### Qt 5: merge with isObscured(), add QRectF arg to isObscuredBy()
+ inline bool isObscured(qreal x, qreal y, qreal w, qreal h) const;
+ virtual bool isObscuredBy(const QGraphicsItem *item) const;
+ virtual QPainterPath opaqueArea() const;
+
+ QRegion boundingRegion(const QTransform &itemToDeviceTransform) const;
+ qreal boundingRegionGranularity() const;
+ void setBoundingRegionGranularity(qreal granularity);
+
+ // Drawing
+ virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) = 0;
+ void update(const QRectF &rect = QRectF());
+ inline void update(qreal x, qreal y, qreal width, qreal height);
+ void scroll(qreal dx, qreal dy, const QRectF &rect = QRectF());
+
+ // Coordinate mapping
+ QPointF mapToItem(const QGraphicsItem *item, const QPointF &point) const;
+ QPointF mapToParent(const QPointF &point) const;
+ QPointF mapToScene(const QPointF &point) const;
+ QPolygonF mapToItem(const QGraphicsItem *item, const QRectF &rect) const;
+ QPolygonF mapToParent(const QRectF &rect) const;
+ QPolygonF mapToScene(const QRectF &rect) const;
+ QRectF mapRectToItem(const QGraphicsItem *item, const QRectF &rect) const;
+ QRectF mapRectToParent(const QRectF &rect) const;
+ QRectF mapRectToScene(const QRectF &rect) const;
+ QPolygonF mapToItem(const QGraphicsItem *item, const QPolygonF &polygon) const;
+ QPolygonF mapToParent(const QPolygonF &polygon) const;
+ QPolygonF mapToScene(const QPolygonF &polygon) const;
+ QPainterPath mapToItem(const QGraphicsItem *item, const QPainterPath &path) const;
+ QPainterPath mapToParent(const QPainterPath &path) const;
+ QPainterPath mapToScene(const QPainterPath &path) const;
+ QPointF mapFromItem(const QGraphicsItem *item, const QPointF &point) const;
+ QPointF mapFromParent(const QPointF &point) const;
+ QPointF mapFromScene(const QPointF &point) const;
+ QPolygonF mapFromItem(const QGraphicsItem *item, const QRectF &rect) const;
+ QPolygonF mapFromParent(const QRectF &rect) const;
+ QPolygonF mapFromScene(const QRectF &rect) const;
+ QRectF mapRectFromItem(const QGraphicsItem *item, const QRectF &rect) const;
+ QRectF mapRectFromParent(const QRectF &rect) const;
+ QRectF mapRectFromScene(const QRectF &rect) const;
+ QPolygonF mapFromItem(const QGraphicsItem *item, const QPolygonF &polygon) const;
+ QPolygonF mapFromParent(const QPolygonF &polygon) const;
+ QPolygonF mapFromScene(const QPolygonF &polygon) const;
+ QPainterPath mapFromItem(const QGraphicsItem *item, const QPainterPath &path) const;
+ QPainterPath mapFromParent(const QPainterPath &path) const;
+ QPainterPath mapFromScene(const QPainterPath &path) const;
+
+ inline QPointF mapToItem(const QGraphicsItem *item, qreal x, qreal y) const;
+ inline QPointF mapToParent(qreal x, qreal y) const;
+ inline QPointF mapToScene(qreal x, qreal y) const;
+ inline QPolygonF mapToItem(const QGraphicsItem *item, qreal x, qreal y, qreal w, qreal h) const;
+ inline QPolygonF mapToParent(qreal x, qreal y, qreal w, qreal h) const;
+ inline QPolygonF mapToScene(qreal x, qreal y, qreal w, qreal h) const;
+ inline QRectF mapRectToItem(const QGraphicsItem *item, qreal x, qreal y, qreal w, qreal h) const;
+ inline QRectF mapRectToParent(qreal x, qreal y, qreal w, qreal h) const;
+ inline QRectF mapRectToScene(qreal x, qreal y, qreal w, qreal h) const;
+ inline QPointF mapFromItem(const QGraphicsItem *item, qreal x, qreal y) const;
+ inline QPointF mapFromParent(qreal x, qreal y) const;
+ inline QPointF mapFromScene(qreal x, qreal y) const;
+ inline QPolygonF mapFromItem(const QGraphicsItem *item, qreal x, qreal y, qreal w, qreal h) const;
+ inline QPolygonF mapFromParent(qreal x, qreal y, qreal w, qreal h) const;
+ inline QPolygonF mapFromScene(qreal x, qreal y, qreal w, qreal h) const;
+ inline QRectF mapRectFromItem(const QGraphicsItem *item, qreal x, qreal y, qreal w, qreal h) const;
+ inline QRectF mapRectFromParent(qreal x, qreal y, qreal w, qreal h) const;
+ inline QRectF mapRectFromScene(qreal x, qreal y, qreal w, qreal h) const;
+
+ bool isAncestorOf(const QGraphicsItem *child) const;
+ QGraphicsItem *commonAncestorItem(const QGraphicsItem *other) const;
+ bool isUnderMouse() const;
+
+ // Custom data
+ QVariant data(int key) const;
+ void setData(int key, const QVariant &value);
+
+ Qt::InputMethodHints inputMethodHints() const;
+ void setInputMethodHints(Qt::InputMethodHints hints);
+
+ enum {
+ Type = 1,
+ UserType = 65536
+ };
+ virtual int type() const;
+
+ void installSceneEventFilter(QGraphicsItem *filterItem);
+ void removeSceneEventFilter(QGraphicsItem *filterItem);
+
+protected:
+ void updateMicroFocus();
+ virtual bool sceneEventFilter(QGraphicsItem *watched, QEvent *event);
+ virtual bool sceneEvent(QEvent *event);
+ virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent *event);
+ virtual void dragEnterEvent(QGraphicsSceneDragDropEvent *event);
+ virtual void dragLeaveEvent(QGraphicsSceneDragDropEvent *event);
+ virtual void dragMoveEvent(QGraphicsSceneDragDropEvent *event);
+ virtual void dropEvent(QGraphicsSceneDragDropEvent *event);
+ virtual void focusInEvent(QFocusEvent *event);
+ virtual void focusOutEvent(QFocusEvent *event);
+ virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
+ virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *event);
+ virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
+ virtual void keyPressEvent(QKeyEvent *event);
+ virtual void keyReleaseEvent(QKeyEvent *event);
+ virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
+ virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
+ virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
+ virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event);
+ virtual void wheelEvent(QGraphicsSceneWheelEvent *event);
+ virtual void inputMethodEvent(QInputMethodEvent *event);
+ virtual QVariant inputMethodQuery(Qt::InputMethodQuery query) const;
+
+ virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value);
+
+ enum Extension {
+ UserExtension = 0x80000000
+ };
+ virtual bool supportsExtension(Extension extension) const;
+ virtual void setExtension(Extension extension, const QVariant &variant);
+ virtual QVariant extension(const QVariant &variant) const;
+
+protected:
+ QGraphicsItem(QGraphicsItemPrivate &dd,
+ QGraphicsItem *parent, QGraphicsScene *scene);
+ QScopedPointer<QGraphicsItemPrivate> d_ptr;
+
+ void addToIndex();
+ void removeFromIndex();
+ void prepareGeometryChange();
+
+private:
+ Q_DISABLE_COPY(QGraphicsItem)
+ Q_DECLARE_PRIVATE(QGraphicsItem)
+ friend class QGraphicsItemGroup;
+ friend class QGraphicsScene;
+ friend class QGraphicsScenePrivate;
+ friend class QGraphicsSceneFindItemBspTreeVisitor;
+ friend class QGraphicsSceneBspTree;
+ friend class QGraphicsView;
+ friend class QGraphicsViewPrivate;
+ friend class QGraphicsObject;
+ friend class QGraphicsWidget;
+ friend class QGraphicsWidgetPrivate;
+ friend class QGraphicsProxyWidgetPrivate;
+ friend class QGraphicsSceneIndex;
+ friend class QGraphicsSceneIndexPrivate;
+ friend class QGraphicsSceneBspTreeIndex;
+ friend class QGraphicsSceneBspTreeIndexPrivate;
+ friend class QGraphicsItemEffectSourcePrivate;
+ friend class QGraphicsTransformPrivate;
+#ifndef QT_NO_GESTURES
+ friend class QGestureManager;
+#endif
+ friend class ::tst_QGraphicsItem;
+ friend bool qt_closestLeaf(const QGraphicsItem *, const QGraphicsItem *);
+ friend bool qt_closestItemFirst(const QGraphicsItem *, const QGraphicsItem *);
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QGraphicsItem::GraphicsItemFlags)
+Q_DECLARE_INTERFACE(QGraphicsItem, "com.trolltech.Qt.QGraphicsItem")
+
+inline void QGraphicsItem::setPos(qreal ax, qreal ay)
+{ setPos(QPointF(ax, ay)); }
+inline void QGraphicsItem::ensureVisible(qreal ax, qreal ay, qreal w, qreal h, int xmargin, int ymargin)
+{ ensureVisible(QRectF(ax, ay, w, h), xmargin, ymargin); }
+inline void QGraphicsItem::update(qreal ax, qreal ay, qreal width, qreal height)
+{ update(QRectF(ax, ay, width, height)); }
+inline bool QGraphicsItem::isObscured(qreal ax, qreal ay, qreal w, qreal h) const
+{ return isObscured(QRectF(ax, ay, w, h)); }
+inline QPointF QGraphicsItem::mapToItem(const QGraphicsItem *item, qreal ax, qreal ay) const
+{ return mapToItem(item, QPointF(ax, ay)); }
+inline QPointF QGraphicsItem::mapToParent(qreal ax, qreal ay) const
+{ return mapToParent(QPointF(ax, ay)); }
+inline QPointF QGraphicsItem::mapToScene(qreal ax, qreal ay) const
+{ return mapToScene(QPointF(ax, ay)); }
+inline QPointF QGraphicsItem::mapFromItem(const QGraphicsItem *item, qreal ax, qreal ay) const
+{ return mapFromItem(item, QPointF(ax, ay)); }
+inline QPointF QGraphicsItem::mapFromParent(qreal ax, qreal ay) const
+{ return mapFromParent(QPointF(ax, ay)); }
+inline QPointF QGraphicsItem::mapFromScene(qreal ax, qreal ay) const
+{ return mapFromScene(QPointF(ax, ay)); }
+inline QPolygonF QGraphicsItem::mapToItem(const QGraphicsItem *item, qreal ax, qreal ay, qreal w, qreal h) const
+{ return mapToItem(item, QRectF(ax, ay, w, h)); }
+inline QPolygonF QGraphicsItem::mapToParent(qreal ax, qreal ay, qreal w, qreal h) const
+{ return mapToParent(QRectF(ax, ay, w, h)); }
+inline QPolygonF QGraphicsItem::mapToScene(qreal ax, qreal ay, qreal w, qreal h) const
+{ return mapToScene(QRectF(ax, ay, w, h)); }
+inline QRectF QGraphicsItem::mapRectToItem(const QGraphicsItem *item, qreal ax, qreal ay, qreal w, qreal h) const
+{ return mapRectToItem(item, QRectF(ax, ay, w, h)); }
+inline QRectF QGraphicsItem::mapRectToParent(qreal ax, qreal ay, qreal w, qreal h) const
+{ return mapRectToParent(QRectF(ax, ay, w, h)); }
+inline QRectF QGraphicsItem::mapRectToScene(qreal ax, qreal ay, qreal w, qreal h) const
+{ return mapRectToScene(QRectF(ax, ay, w, h)); }
+inline QPolygonF QGraphicsItem::mapFromItem(const QGraphicsItem *item, qreal ax, qreal ay, qreal w, qreal h) const
+{ return mapFromItem(item, QRectF(ax, ay, w, h)); }
+inline QPolygonF QGraphicsItem::mapFromParent(qreal ax, qreal ay, qreal w, qreal h) const
+{ return mapFromParent(QRectF(ax, ay, w, h)); }
+inline QPolygonF QGraphicsItem::mapFromScene(qreal ax, qreal ay, qreal w, qreal h) const
+{ return mapFromScene(QRectF(ax, ay, w, h)); }
+inline QRectF QGraphicsItem::mapRectFromItem(const QGraphicsItem *item, qreal ax, qreal ay, qreal w, qreal h) const
+{ return mapRectFromItem(item, QRectF(ax, ay, w, h)); }
+inline QRectF QGraphicsItem::mapRectFromParent(qreal ax, qreal ay, qreal w, qreal h) const
+{ return mapRectFromParent(QRectF(ax, ay, w, h)); }
+inline QRectF QGraphicsItem::mapRectFromScene(qreal ax, qreal ay, qreal w, qreal h) const
+{ return mapRectFromScene(QRectF(ax, ay, w, h)); }
+
+
+class Q_WIDGETS_EXPORT QGraphicsObject : public QObject, public QGraphicsItem
+{
+ Q_OBJECT
+ Q_PROPERTY(QGraphicsObject * parent READ parentObject WRITE setParentItem NOTIFY parentChanged DESIGNABLE false)
+ Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity NOTIFY opacityChanged FINAL)
+ Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged)
+ Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged FINAL)
+ Q_PROPERTY(QPointF pos READ pos WRITE setPos FINAL)
+ Q_PROPERTY(qreal x READ x WRITE setX NOTIFY xChanged FINAL)
+ Q_PROPERTY(qreal y READ y WRITE setY NOTIFY yChanged FINAL)
+ Q_PROPERTY(qreal z READ zValue WRITE setZValue NOTIFY zChanged FINAL)
+ Q_PROPERTY(qreal rotation READ rotation WRITE setRotation NOTIFY rotationChanged)
+ Q_PROPERTY(qreal scale READ scale WRITE setScale NOTIFY scaleChanged)
+ Q_PROPERTY(QPointF transformOriginPoint READ transformOriginPoint WRITE setTransformOriginPoint)
+#ifndef QT_NO_GRAPHICSEFFECT
+ Q_PROPERTY(QGraphicsEffect *effect READ graphicsEffect WRITE setGraphicsEffect)
+#endif
+ Q_PRIVATE_PROPERTY(QGraphicsItem::d_func(), QDeclarativeListProperty<QGraphicsObject> children READ childrenList DESIGNABLE false NOTIFY childrenChanged)
+ Q_PRIVATE_PROPERTY(QGraphicsItem::d_func(), qreal width READ width WRITE setWidth NOTIFY widthChanged RESET resetWidth FINAL)
+ Q_PRIVATE_PROPERTY(QGraphicsItem::d_func(), qreal height READ height WRITE setHeight NOTIFY heightChanged RESET resetHeight FINAL)
+ Q_CLASSINFO("DefaultProperty", "children")
+ Q_INTERFACES(QGraphicsItem)
+public:
+ QGraphicsObject(QGraphicsItem *parent = 0);
+
+ // ### Qt 5: Disambiguate
+#ifdef Q_NO_USING_KEYWORD
+ const QObjectList &children() const { return QObject::children(); }
+#else
+ using QObject::children;
+#endif
+
+#ifndef QT_NO_GESTURES
+ void grabGesture(Qt::GestureType type, Qt::GestureFlags flags = Qt::GestureFlags());
+ void ungrabGesture(Qt::GestureType type);
+#endif
+
+protected Q_SLOTS:
+ void updateMicroFocus();
+
+Q_SIGNALS:
+ void parentChanged();
+ void opacityChanged();
+ void visibleChanged();
+ void enabledChanged();
+ void xChanged();
+ void yChanged();
+ void zChanged();
+ void rotationChanged();
+ void scaleChanged();
+ void childrenChanged();
+ void widthChanged();
+ void heightChanged();
+
+protected:
+ QGraphicsObject(QGraphicsItemPrivate &dd, QGraphicsItem *parent, QGraphicsScene *scene);
+private:
+ friend class QGraphicsItem;
+ friend class QGraphicsItemPrivate;
+};
+
+
+class QAbstractGraphicsShapeItemPrivate;
+class Q_WIDGETS_EXPORT QAbstractGraphicsShapeItem : public QGraphicsItem
+{
+public:
+ QAbstractGraphicsShapeItem(QGraphicsItem *parent = 0
+#ifndef Q_QDOC
+ // ### obsolete argument
+ , QGraphicsScene *scene = 0
+#endif
+ );
+ ~QAbstractGraphicsShapeItem();
+
+ QPen pen() const;
+ void setPen(const QPen &pen);
+
+ QBrush brush() const;
+ void setBrush(const QBrush &brush);
+
+ bool isObscuredBy(const QGraphicsItem *item) const;
+ QPainterPath opaqueArea() const;
+
+protected:
+ QAbstractGraphicsShapeItem(QAbstractGraphicsShapeItemPrivate &dd,
+ QGraphicsItem *parent, QGraphicsScene *scene);
+
+private:
+ Q_DISABLE_COPY(QAbstractGraphicsShapeItem)
+ Q_DECLARE_PRIVATE(QAbstractGraphicsShapeItem)
+};
+
+class QGraphicsPathItemPrivate;
+class Q_WIDGETS_EXPORT QGraphicsPathItem : public QAbstractGraphicsShapeItem
+{
+public:
+ QGraphicsPathItem(QGraphicsItem *parent = 0
+#ifndef Q_QDOC
+ // ### obsolete argument
+ , QGraphicsScene *scene = 0
+#endif
+ );
+ QGraphicsPathItem(const QPainterPath &path, QGraphicsItem *parent = 0
+#ifndef Q_QDOC
+ // ### obsolete argument
+ , QGraphicsScene *scene = 0
+#endif
+ );
+ ~QGraphicsPathItem();
+
+ QPainterPath path() const;
+ void setPath(const QPainterPath &path);
+
+ QRectF boundingRect() const;
+ QPainterPath shape() const;
+ bool contains(const QPointF &point) const;
+
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
+
+ bool isObscuredBy(const QGraphicsItem *item) const;
+ QPainterPath opaqueArea() const;
+
+ enum { Type = 2 };
+ int type() const;
+
+protected:
+ bool supportsExtension(Extension extension) const;
+ void setExtension(Extension extension, const QVariant &variant);
+ QVariant extension(const QVariant &variant) const;
+
+private:
+ Q_DISABLE_COPY(QGraphicsPathItem)
+ Q_DECLARE_PRIVATE(QGraphicsPathItem)
+};
+
+class QGraphicsRectItemPrivate;
+class Q_WIDGETS_EXPORT QGraphicsRectItem : public QAbstractGraphicsShapeItem
+{
+public:
+ QGraphicsRectItem(QGraphicsItem *parent = 0
+#ifndef Q_QDOC
+ // ### obsolete argument
+ , QGraphicsScene *scene = 0
+#endif
+ );
+ QGraphicsRectItem(const QRectF &rect, QGraphicsItem *parent = 0
+#ifndef Q_QDOC
+ // ### obsolete argument
+ , QGraphicsScene *scene = 0
+#endif
+ );
+ QGraphicsRectItem(qreal x, qreal y, qreal w, qreal h, QGraphicsItem *parent = 0
+#ifndef Q_QDOC
+ // ### obsolete argument
+ , QGraphicsScene *scene = 0
+#endif
+ );
+ ~QGraphicsRectItem();
+
+ QRectF rect() const;
+ void setRect(const QRectF &rect);
+ inline void setRect(qreal x, qreal y, qreal w, qreal h);
+
+ QRectF boundingRect() const;
+ QPainterPath shape() const;
+ bool contains(const QPointF &point) const;
+
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
+
+ bool isObscuredBy(const QGraphicsItem *item) const;
+ QPainterPath opaqueArea() const;
+
+ enum { Type = 3 };
+ int type() const;
+
+protected:
+ bool supportsExtension(Extension extension) const;
+ void setExtension(Extension extension, const QVariant &variant);
+ QVariant extension(const QVariant &variant) const;
+
+private:
+ Q_DISABLE_COPY(QGraphicsRectItem)
+ Q_DECLARE_PRIVATE(QGraphicsRectItem)
+};
+
+inline void QGraphicsRectItem::setRect(qreal ax, qreal ay, qreal w, qreal h)
+{ setRect(QRectF(ax, ay, w, h)); }
+
+class QGraphicsEllipseItemPrivate;
+class Q_WIDGETS_EXPORT QGraphicsEllipseItem : public QAbstractGraphicsShapeItem
+{
+public:
+ QGraphicsEllipseItem(QGraphicsItem *parent = 0
+#ifndef Q_QDOC
+ // ### obsolete argument
+ , QGraphicsScene *scene = 0
+#endif
+ );
+ QGraphicsEllipseItem(const QRectF &rect, QGraphicsItem *parent = 0
+#ifndef Q_QDOC
+ // ### obsolete argument
+ , QGraphicsScene *scene = 0
+#endif
+ );
+ QGraphicsEllipseItem(qreal x, qreal y, qreal w, qreal h, QGraphicsItem *parent = 0
+#ifndef Q_QDOC
+ // ### obsolete argument
+ , QGraphicsScene *scene = 0
+#endif
+ );
+ ~QGraphicsEllipseItem();
+
+ QRectF rect() const;
+ void setRect(const QRectF &rect);
+ inline void setRect(qreal x, qreal y, qreal w, qreal h);
+
+ int startAngle() const;
+ void setStartAngle(int angle);
+
+ int spanAngle() const;
+ void setSpanAngle(int angle);
+
+ QRectF boundingRect() const;
+ QPainterPath shape() const;
+ bool contains(const QPointF &point) const;
+
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
+
+ bool isObscuredBy(const QGraphicsItem *item) const;
+ QPainterPath opaqueArea() const;
+
+ enum { Type = 4 };
+ int type() const;
+
+protected:
+ bool supportsExtension(Extension extension) const;
+ void setExtension(Extension extension, const QVariant &variant);
+ QVariant extension(const QVariant &variant) const;
+
+private:
+ Q_DISABLE_COPY(QGraphicsEllipseItem)
+ Q_DECLARE_PRIVATE(QGraphicsEllipseItem)
+};
+
+inline void QGraphicsEllipseItem::setRect(qreal ax, qreal ay, qreal w, qreal h)
+{ setRect(QRectF(ax, ay, w, h)); }
+
+class QGraphicsPolygonItemPrivate;
+class Q_WIDGETS_EXPORT QGraphicsPolygonItem : public QAbstractGraphicsShapeItem
+{
+public:
+ QGraphicsPolygonItem(QGraphicsItem *parent = 0
+#ifndef Q_QDOC
+ // ### obsolete argument
+ , QGraphicsScene *scene = 0
+#endif
+ );
+ QGraphicsPolygonItem(const QPolygonF &polygon,
+ QGraphicsItem *parent = 0
+#ifndef Q_QDOC
+ // ### obsolete argument
+ , QGraphicsScene *scene = 0
+#endif
+ );
+ ~QGraphicsPolygonItem();
+
+ QPolygonF polygon() const;
+ void setPolygon(const QPolygonF &polygon);
+
+ Qt::FillRule fillRule() const;
+ void setFillRule(Qt::FillRule rule);
+
+ QRectF boundingRect() const;
+ QPainterPath shape() const;
+ bool contains(const QPointF &point) const;
+
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
+
+ bool isObscuredBy(const QGraphicsItem *item) const;
+ QPainterPath opaqueArea() const;
+
+ enum { Type = 5 };
+ int type() const;
+
+protected:
+ bool supportsExtension(Extension extension) const;
+ void setExtension(Extension extension, const QVariant &variant);
+ QVariant extension(const QVariant &variant) const;
+
+private:
+ Q_DISABLE_COPY(QGraphicsPolygonItem)
+ Q_DECLARE_PRIVATE(QGraphicsPolygonItem)
+};
+
+class QGraphicsLineItemPrivate;
+class Q_WIDGETS_EXPORT QGraphicsLineItem : public QGraphicsItem
+{
+public:
+ QGraphicsLineItem(QGraphicsItem *parent = 0
+#ifndef Q_QDOC
+ // ### obsolete argument
+ , QGraphicsScene *scene = 0
+#endif
+ );
+ QGraphicsLineItem(const QLineF &line, QGraphicsItem *parent = 0
+#ifndef Q_QDOC
+ // ### obsolete argument
+ , QGraphicsScene *scene = 0
+#endif
+ );
+ QGraphicsLineItem(qreal x1, qreal y1, qreal x2, qreal y2, QGraphicsItem *parent = 0
+#ifndef Q_QDOC
+ // ### obsolete argument
+ , QGraphicsScene *scene = 0
+#endif
+ );
+ ~QGraphicsLineItem();
+
+ QPen pen() const;
+ void setPen(const QPen &pen);
+
+ QLineF line() const;
+ void setLine(const QLineF &line);
+ inline void setLine(qreal x1, qreal y1, qreal x2, qreal y2)
+ { setLine(QLineF(x1, y1, x2, y2)); }
+
+ QRectF boundingRect() const;
+ QPainterPath shape() const;
+ bool contains(const QPointF &point) const;
+
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
+
+ bool isObscuredBy(const QGraphicsItem *item) const;
+ QPainterPath opaqueArea() const;
+
+ enum { Type = 6 };
+ int type() const;
+
+protected:
+ bool supportsExtension(Extension extension) const;
+ void setExtension(Extension extension, const QVariant &variant);
+ QVariant extension(const QVariant &variant) const;
+
+private:
+ Q_DISABLE_COPY(QGraphicsLineItem)
+ Q_DECLARE_PRIVATE(QGraphicsLineItem)
+};
+
+class QGraphicsPixmapItemPrivate;
+class Q_WIDGETS_EXPORT QGraphicsPixmapItem : public QGraphicsItem
+{
+public:
+ enum ShapeMode {
+ MaskShape,
+ BoundingRectShape,
+ HeuristicMaskShape
+ };
+
+ QGraphicsPixmapItem(QGraphicsItem *parent = 0
+#ifndef Q_QDOC
+ // ### obsolete argument
+ , QGraphicsScene *scene = 0
+#endif
+ );
+ QGraphicsPixmapItem(const QPixmap &pixmap, QGraphicsItem *parent = 0
+#ifndef Q_QDOC
+ // ### obsolete argument
+ , QGraphicsScene *scene = 0
+#endif
+ );
+ ~QGraphicsPixmapItem();
+
+ QPixmap pixmap() const;
+ void setPixmap(const QPixmap &pixmap);
+
+ Qt::TransformationMode transformationMode() const;
+ void setTransformationMode(Qt::TransformationMode mode);
+
+ QPointF offset() const;
+ void setOffset(const QPointF &offset);
+ inline void setOffset(qreal x, qreal y);
+
+ QRectF boundingRect() const;
+ QPainterPath shape() const;
+ bool contains(const QPointF &point) const;
+
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
+
+ bool isObscuredBy(const QGraphicsItem *item) const;
+ QPainterPath opaqueArea() const;
+
+ enum { Type = 7 };
+ int type() const;
+
+ ShapeMode shapeMode() const;
+ void setShapeMode(ShapeMode mode);
+
+protected:
+ bool supportsExtension(Extension extension) const;
+ void setExtension(Extension extension, const QVariant &variant);
+ QVariant extension(const QVariant &variant) const;
+
+private:
+ Q_DISABLE_COPY(QGraphicsPixmapItem)
+ Q_DECLARE_PRIVATE(QGraphicsPixmapItem)
+};
+
+inline void QGraphicsPixmapItem::setOffset(qreal ax, qreal ay)
+{ setOffset(QPointF(ax, ay)); }
+
+class QGraphicsTextItemPrivate;
+class QTextDocument;
+class QTextCursor;
+class Q_WIDGETS_EXPORT QGraphicsTextItem : public QGraphicsObject
+{
+ Q_OBJECT
+ QDOC_PROPERTY(bool openExternalLinks READ openExternalLinks WRITE setOpenExternalLinks)
+ QDOC_PROPERTY(QTextCursor textCursor READ textCursor WRITE setTextCursor)
+
+public:
+ QGraphicsTextItem(QGraphicsItem *parent = 0
+#ifndef Q_QDOC
+ // ### obsolete argument
+ , QGraphicsScene *scene = 0
+#endif
+ );
+ QGraphicsTextItem(const QString &text, QGraphicsItem *parent = 0
+#ifndef Q_QDOC
+ // ### obsolete argument
+ , QGraphicsScene *scene = 0
+#endif
+ );
+ ~QGraphicsTextItem();
+
+ QString toHtml() const;
+ void setHtml(const QString &html);
+
+ QString toPlainText() const;
+ void setPlainText(const QString &text);
+
+ QFont font() const;
+ void setFont(const QFont &font);
+
+ void setDefaultTextColor(const QColor &c);
+ QColor defaultTextColor() const;
+
+ QRectF boundingRect() const;
+ QPainterPath shape() const;
+ bool contains(const QPointF &point) const;
+
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
+
+ bool isObscuredBy(const QGraphicsItem *item) const;
+ QPainterPath opaqueArea() const;
+
+ enum { Type = 8 };
+ int type() const;
+
+ void setTextWidth(qreal width);
+ qreal textWidth() const;
+
+ void adjustSize();
+
+ void setDocument(QTextDocument *document);
+ QTextDocument *document() const;
+
+ void setTextInteractionFlags(Qt::TextInteractionFlags flags);
+ Qt::TextInteractionFlags textInteractionFlags() const;
+
+ void setTabChangesFocus(bool b);
+ bool tabChangesFocus() const;
+
+ void setOpenExternalLinks(bool open);
+ bool openExternalLinks() const;
+
+ void setTextCursor(const QTextCursor &cursor);
+ QTextCursor textCursor() const;
+
+Q_SIGNALS:
+ void linkActivated(const QString &);
+ void linkHovered(const QString &);
+
+protected:
+ bool sceneEvent(QEvent *event);
+ void mousePressEvent(QGraphicsSceneMouseEvent *event);
+ void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
+ void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
+ void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event);
+ void contextMenuEvent(QGraphicsSceneContextMenuEvent *event);
+ void keyPressEvent(QKeyEvent *event);
+ void keyReleaseEvent(QKeyEvent *event);
+ void focusInEvent(QFocusEvent *event);
+ void focusOutEvent(QFocusEvent *event);
+ void dragEnterEvent(QGraphicsSceneDragDropEvent *event);
+ void dragLeaveEvent(QGraphicsSceneDragDropEvent *event);
+ void dragMoveEvent(QGraphicsSceneDragDropEvent *event);
+ void dropEvent(QGraphicsSceneDragDropEvent *event);
+ void inputMethodEvent(QInputMethodEvent *event);
+ void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
+ void hoverMoveEvent(QGraphicsSceneHoverEvent *event);
+ void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
+
+ QVariant inputMethodQuery(Qt::InputMethodQuery query) const;
+
+ bool supportsExtension(Extension extension) const;
+ void setExtension(Extension extension, const QVariant &variant);
+ QVariant extension(const QVariant &variant) const;
+
+private:
+ Q_DISABLE_COPY(QGraphicsTextItem)
+ Q_PRIVATE_SLOT(dd, void _q_updateBoundingRect(const QSizeF &))
+ Q_PRIVATE_SLOT(dd, void _q_update(QRectF))
+ Q_PRIVATE_SLOT(dd, void _q_ensureVisible(QRectF))
+ QGraphicsTextItemPrivate *dd;
+ friend class QGraphicsTextItemPrivate;
+};
+
+class QGraphicsSimpleTextItemPrivate;
+class Q_WIDGETS_EXPORT QGraphicsSimpleTextItem : public QAbstractGraphicsShapeItem
+{
+public:
+ QGraphicsSimpleTextItem(QGraphicsItem *parent = 0
+#ifndef Q_QDOC
+ // ### obsolete argument
+ , QGraphicsScene *scene = 0
+#endif
+ );
+ QGraphicsSimpleTextItem(const QString &text, QGraphicsItem *parent = 0
+#ifndef Q_QDOC
+ // ### obsolete argument
+ , QGraphicsScene *scene = 0
+#endif
+ );
+ ~QGraphicsSimpleTextItem();
+
+ void setText(const QString &text);
+ QString text() const;
+
+ void setFont(const QFont &font);
+ QFont font() const;
+
+ QRectF boundingRect() const;
+ QPainterPath shape() const;
+ bool contains(const QPointF &point) const;
+
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
+
+ bool isObscuredBy(const QGraphicsItem *item) const;
+ QPainterPath opaqueArea() const;
+
+ enum { Type = 9 };
+ int type() const;
+
+protected:
+ bool supportsExtension(Extension extension) const;
+ void setExtension(Extension extension, const QVariant &variant);
+ QVariant extension(const QVariant &variant) const;
+
+private:
+ Q_DISABLE_COPY(QGraphicsSimpleTextItem)
+ Q_DECLARE_PRIVATE(QGraphicsSimpleTextItem)
+};
+
+class QGraphicsItemGroupPrivate;
+class Q_WIDGETS_EXPORT QGraphicsItemGroup : public QGraphicsItem
+{
+public:
+ QGraphicsItemGroup(QGraphicsItem *parent = 0
+#ifndef Q_QDOC
+ // ### obsolete argument
+ , QGraphicsScene *scene = 0
+#endif
+ );
+ ~QGraphicsItemGroup();
+
+ void addToGroup(QGraphicsItem *item);
+ void removeFromGroup(QGraphicsItem *item);
+
+ QRectF boundingRect() const;
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
+
+ bool isObscuredBy(const QGraphicsItem *item) const;
+ QPainterPath opaqueArea() const;
+
+ enum { Type = 10 };
+ int type() const;
+
+private:
+ Q_DISABLE_COPY(QGraphicsItemGroup)
+ Q_DECLARE_PRIVATE(QGraphicsItemGroup)
+};
+
+template <class T> inline T qgraphicsitem_cast(QGraphicsItem *item)
+{
+ return int(static_cast<T>(0)->Type) == int(QGraphicsItem::Type)
+ || (item && int(static_cast<T>(0)->Type) == item->type()) ? static_cast<T>(item) : 0;
+}
+
+template <class T> inline T qgraphicsitem_cast(const QGraphicsItem *item)
+{
+ return int(static_cast<T>(0)->Type) == int(QGraphicsItem::Type)
+ || (item && int(static_cast<T>(0)->Type) == item->type()) ? static_cast<T>(item) : 0;
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+Q_WIDGETS_EXPORT QDebug operator<<(QDebug debug, QGraphicsItem *item);
+Q_WIDGETS_EXPORT QDebug operator<<(QDebug debug, QGraphicsObject *item);
+Q_WIDGETS_EXPORT QDebug operator<<(QDebug debug, QGraphicsItem::GraphicsItemChange change);
+Q_WIDGETS_EXPORT QDebug operator<<(QDebug debug, QGraphicsItem::GraphicsItemFlag flag);
+Q_WIDGETS_EXPORT QDebug operator<<(QDebug debug, QGraphicsItem::GraphicsItemFlags flags);
+#endif
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QGraphicsItem *)
+Q_DECLARE_METATYPE(QGraphicsScene *)
+
+QT_BEGIN_NAMESPACE
+
+#endif // QT_NO_GRAPHICSVIEW
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QGRAPHICSITEM_H
diff --git a/src/widgets/graphicsview/qgraphicsitem_p.h b/src/widgets/graphicsview/qgraphicsitem_p.h
new file mode 100644
index 0000000000..3cd77f3cdb
--- /dev/null
+++ b/src/widgets/graphicsview/qgraphicsitem_p.h
@@ -0,0 +1,891 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGRAPHICSITEM_P_H
+#define QGRAPHICSITEM_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qgraphicsitem.h"
+#include "qset.h"
+#include "qpixmapcache.h"
+#include <private/qgraphicsview_p.h>
+#include "qgraphicstransform.h"
+#include <private/qgraphicstransform_p.h>
+
+#include <private/qgraphicseffect_p.h>
+#include <qgraphicseffect.h>
+
+#include <QtCore/qpoint.h>
+
+#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW
+
+QT_BEGIN_NAMESPACE
+
+class QGraphicsItemPrivate;
+
+#ifndef QDECLARATIVELISTPROPERTY
+#define QDECLARATIVELISTPROPERTY
+template<typename T>
+class QDeclarativeListProperty {
+public:
+ typedef void (*AppendFunction)(QDeclarativeListProperty<T> *, T*);
+ typedef int (*CountFunction)(QDeclarativeListProperty<T> *);
+ typedef T *(*AtFunction)(QDeclarativeListProperty<T> *, int);
+ typedef void (*ClearFunction)(QDeclarativeListProperty<T> *);
+
+ QDeclarativeListProperty()
+ : object(0), data(0), append(0), count(0), at(0), clear(0), dummy1(0), dummy2(0) {}
+ QDeclarativeListProperty(QObject *o, QList<T *> &list)
+ : object(o), data(&list), append(qlist_append), count(qlist_count), at(qlist_at),
+ clear(qlist_clear), dummy1(0), dummy2(0) {}
+ QDeclarativeListProperty(QObject *o, void *d, AppendFunction a, CountFunction c = 0, AtFunction t = 0,
+ ClearFunction r = 0)
+ : object(o), data(d), append(a), count(c), at(t), clear(r), dummy1(0), dummy2(0) {}
+
+ bool operator==(const QDeclarativeListProperty &o) const {
+ return object == o.object &&
+ data == o.data &&
+ append == o.append &&
+ count == o.count &&
+ at == o.at &&
+ clear == o.clear;
+ }
+
+ QObject *object;
+ void *data;
+
+ AppendFunction append;
+
+ CountFunction count;
+ AtFunction at;
+
+ ClearFunction clear;
+
+ void *dummy1;
+ void *dummy2;
+
+private:
+ static void qlist_append(QDeclarativeListProperty *p, T *v) {
+ ((QList<T *> *)p->data)->append(v);
+ }
+ static int qlist_count(QDeclarativeListProperty *p) {
+ return ((QList<T *> *)p->data)->count();
+ }
+ static T *qlist_at(QDeclarativeListProperty *p, int idx) {
+ return ((QList<T *> *)p->data)->at(idx);
+ }
+ static void qlist_clear(QDeclarativeListProperty *p) {
+ return ((QList<T *> *)p->data)->clear();
+ }
+};
+#endif
+
+class QGraphicsItemCache
+{
+public:
+ QGraphicsItemCache() : allExposed(false) { }
+
+ // ItemCoordinateCache only
+ QRect boundingRect;
+ QSize fixedSize;
+ QPixmapCache::Key key;
+
+ // DeviceCoordinateCache only
+ struct DeviceData {
+ DeviceData() {}
+ QTransform lastTransform;
+ QPoint cacheIndent;
+ QPixmapCache::Key key;
+ };
+ QMap<QPaintDevice *, DeviceData> deviceData;
+
+ // List of logical exposed rects
+ QVector<QRectF> exposed;
+ bool allExposed;
+
+ // Empty cache
+ void purge();
+};
+
+class Q_WIDGETS_EXPORT QGraphicsItemPrivate
+{
+ Q_DECLARE_PUBLIC(QGraphicsItem)
+public:
+ enum Extra {
+ ExtraToolTip,
+ ExtraCursor,
+ ExtraCacheData,
+ ExtraMaxDeviceCoordCacheSize,
+ ExtraBoundingRegionGranularity
+ };
+
+ enum AncestorFlag {
+ NoFlag = 0,
+ AncestorHandlesChildEvents = 0x1,
+ AncestorClipsChildren = 0x2,
+ AncestorIgnoresTransformations = 0x4,
+ AncestorFiltersChildEvents = 0x8
+ };
+
+ inline QGraphicsItemPrivate()
+ : z(0),
+ opacity(1.),
+ scene(0),
+ parent(0),
+ transformData(0),
+ graphicsEffect(0),
+ index(-1),
+ siblingIndex(-1),
+ itemDepth(-1),
+ focusProxy(0),
+ subFocusItem(0),
+ focusScopeItem(0),
+ imHints(Qt::ImhNone),
+ panelModality(QGraphicsItem::NonModal),
+ acceptedMouseButtons(0x1f),
+ visible(1),
+ explicitlyHidden(0),
+ enabled(1),
+ explicitlyDisabled(0),
+ selected(0),
+ acceptsHover(0),
+ acceptDrops(0),
+ isMemberOfGroup(0),
+ handlesChildEvents(0),
+ itemDiscovered(0),
+ hasCursor(0),
+ ancestorFlags(0),
+ cacheMode(0),
+ hasBoundingRegionGranularity(0),
+ isWidget(0),
+ dirty(0),
+ dirtyChildren(0),
+ localCollisionHack(0),
+ inSetPosHelper(0),
+ needSortChildren(0),
+ allChildrenDirty(0),
+ fullUpdatePending(0),
+ dirtyChildrenBoundingRect(1),
+ flags(0),
+ paintedViewBoundingRectsNeedRepaint(0),
+ dirtySceneTransform(1),
+ geometryChanged(1),
+ inDestructor(0),
+ isObject(0),
+ ignoreVisible(0),
+ ignoreOpacity(0),
+ acceptTouchEvents(0),
+ acceptedTouchBeginEvent(0),
+ filtersDescendantEvents(0),
+ sceneTransformTranslateOnly(0),
+ notifyBoundingRectChanged(0),
+ notifyInvalidated(0),
+ mouseSetsFocus(1),
+ explicitActivate(0),
+ wantsActive(0),
+ holesInSiblingIndex(0),
+ sequentialOrdering(1),
+ updateDueToGraphicsEffect(0),
+ scenePosDescendants(0),
+ pendingPolish(0),
+ mayHaveChildWithGraphicsEffect(0),
+ isDeclarativeItem(0),
+ sendParentChangeNotification(0),
+ globalStackingOrder(-1),
+ q_ptr(0)
+ {
+ }
+
+ inline virtual ~QGraphicsItemPrivate()
+ { }
+
+ static const QGraphicsItemPrivate *get(const QGraphicsItem *item)
+ {
+ return item->d_ptr.data();
+ }
+ static QGraphicsItemPrivate *get(QGraphicsItem *item)
+ {
+ return item->d_ptr.data();
+ }
+
+ void updateChildWithGraphicsEffectFlagRecursively();
+ void updateAncestorFlag(QGraphicsItem::GraphicsItemFlag childFlag,
+ AncestorFlag flag = NoFlag, bool enabled = false, bool root = true);
+ void updateAncestorFlags();
+ void setIsMemberOfGroup(bool enabled);
+ void remapItemPos(QEvent *event, QGraphicsItem *item);
+ QPointF genericMapFromScene(const QPointF &pos, const QWidget *viewport) const;
+ inline bool itemIsUntransformable() const
+ {
+ return (flags & QGraphicsItem::ItemIgnoresTransformations)
+ || (ancestorFlags & AncestorIgnoresTransformations);
+ }
+
+ void combineTransformToParent(QTransform *x, const QTransform *viewTransform = 0) const;
+ void combineTransformFromParent(QTransform *x, const QTransform *viewTransform = 0) const;
+ virtual void updateSceneTransformFromParent();
+
+ // ### Qt 5: Remove. Workaround for reimplementation added after Qt 4.4.
+ virtual QVariant inputMethodQueryHelper(Qt::InputMethodQuery query) const;
+ static bool movableAncestorIsSelected(const QGraphicsItem *item);
+
+ virtual void setPosHelper(const QPointF &pos);
+ void setTransformHelper(const QTransform &transform);
+ void prependGraphicsTransform(QGraphicsTransform *t);
+ void appendGraphicsTransform(QGraphicsTransform *t);
+ void setVisibleHelper(bool newVisible, bool explicitly, bool update = true);
+ void setEnabledHelper(bool newEnabled, bool explicitly, bool update = true);
+ bool discardUpdateRequest(bool ignoreVisibleBit = false,
+ bool ignoreDirtyBit = false, bool ignoreOpacity = false) const;
+ virtual void transformChanged() {}
+ int depth() const;
+#ifndef QT_NO_GRAPHICSEFFECT
+ enum InvalidateReason {
+ OpacityChanged
+ };
+ void invalidateParentGraphicsEffectsRecursively();
+ void invalidateChildGraphicsEffectsRecursively(InvalidateReason reason);
+#endif //QT_NO_GRAPHICSEFFECT
+ void invalidateDepthRecursively();
+ void resolveDepth();
+ void addChild(QGraphicsItem *child);
+ void removeChild(QGraphicsItem *child);
+ QDeclarativeListProperty<QGraphicsObject> childrenList();
+ void setParentItemHelper(QGraphicsItem *parent, const QVariant *newParentVariant,
+ const QVariant *thisPointerVariant);
+ void childrenBoundingRectHelper(QTransform *x, QRectF *rect, QGraphicsItem *topMostEffectItem);
+ void initStyleOption(QStyleOptionGraphicsItem *option, const QTransform &worldTransform,
+ const QRegion &exposedRegion, bool allItems = false) const;
+ QRectF effectiveBoundingRect(QGraphicsItem *topMostEffectItem = 0) const;
+ QRectF sceneEffectiveBoundingRect() const;
+
+ QRectF effectiveBoundingRect(const QRectF &rect) const;
+
+ virtual void resolveFont(uint inheritedMask)
+ {
+ for (int i = 0; i < children.size(); ++i)
+ children.at(i)->d_ptr->resolveFont(inheritedMask);
+ }
+
+ virtual void resolvePalette(uint inheritedMask)
+ {
+ for (int i = 0; i < children.size(); ++i)
+ children.at(i)->d_ptr->resolveFont(inheritedMask);
+ }
+
+ virtual bool isProxyWidget() const;
+
+ inline QVariant extra(Extra type) const
+ {
+ for (int i = 0; i < extras.size(); ++i) {
+ const ExtraStruct &extra = extras.at(i);
+ if (extra.type == type)
+ return extra.value;
+ }
+ return QVariant();
+ }
+
+ inline void setExtra(Extra type, const QVariant &value)
+ {
+ int index = -1;
+ for (int i = 0; i < extras.size(); ++i) {
+ if (extras.at(i).type == type) {
+ index = i;
+ break;
+ }
+ }
+
+ if (index == -1) {
+ extras << ExtraStruct(type, value);
+ } else {
+ extras[index].value = value;
+ }
+ }
+
+ inline void unsetExtra(Extra type)
+ {
+ for (int i = 0; i < extras.size(); ++i) {
+ if (extras.at(i).type == type) {
+ extras.removeAt(i);
+ return;
+ }
+ }
+ }
+
+ struct ExtraStruct {
+ ExtraStruct(Extra type, QVariant value)
+ : type(type), value(value)
+ { }
+
+ Extra type;
+ QVariant value;
+
+ bool operator<(Extra extra) const
+ { return type < extra; }
+ };
+
+ QList<ExtraStruct> extras;
+
+ QGraphicsItemCache *maybeExtraItemCache() const;
+ QGraphicsItemCache *extraItemCache() const;
+ void removeExtraItemCache();
+
+ void updatePaintedViewBoundingRects(bool updateChildren);
+ void ensureSceneTransformRecursive(QGraphicsItem **topMostDirtyItem);
+ inline void ensureSceneTransform()
+ {
+ QGraphicsItem *that = q_func();
+ ensureSceneTransformRecursive(&that);
+ }
+
+ inline bool hasTranslateOnlySceneTransform()
+ {
+ ensureSceneTransform();
+ return sceneTransformTranslateOnly;
+ }
+
+ inline void invalidateChildrenSceneTransform()
+ {
+ for (int i = 0; i < children.size(); ++i)
+ children.at(i)->d_ptr->dirtySceneTransform = 1;
+ }
+
+ inline qreal calcEffectiveOpacity() const
+ {
+ qreal o = opacity;
+ QGraphicsItem *p = parent;
+ int myFlags = flags;
+ while (p) {
+ int parentFlags = p->d_ptr->flags;
+
+ // If I have a parent, and I don't ignore my parent's opacity, and my
+ // parent propagates to me, then combine my local opacity with my parent's
+ // effective opacity into my effective opacity.
+ if ((myFlags & QGraphicsItem::ItemIgnoresParentOpacity)
+ || (parentFlags & QGraphicsItem::ItemDoesntPropagateOpacityToChildren)) {
+ break;
+ }
+
+ o *= p->d_ptr->opacity;
+ p = p->d_ptr->parent;
+ myFlags = parentFlags;
+ }
+ return o;
+ }
+
+ inline bool isOpacityNull() const
+ { return (opacity < qreal(0.001)); }
+
+ static inline bool isOpacityNull(qreal opacity)
+ { return (opacity < qreal(0.001)); }
+
+ inline bool isFullyTransparent() const
+ {
+ if (isOpacityNull())
+ return true;
+ if (!parent)
+ return false;
+
+ return isOpacityNull(calcEffectiveOpacity());
+ }
+
+ inline qreal effectiveOpacity() const {
+ if (!parent || !opacity)
+ return opacity;
+
+ return calcEffectiveOpacity();
+ }
+
+ inline qreal combineOpacityFromParent(qreal parentOpacity) const
+ {
+ if (parent && !(flags & QGraphicsItem::ItemIgnoresParentOpacity)
+ && !(parent->d_ptr->flags & QGraphicsItem::ItemDoesntPropagateOpacityToChildren)) {
+ return parentOpacity * opacity;
+ }
+ return opacity;
+ }
+
+ inline bool childrenCombineOpacity() const
+ {
+ if (!children.size())
+ return true;
+ if (flags & QGraphicsItem::ItemDoesntPropagateOpacityToChildren)
+ return false;
+
+ for (int i = 0; i < children.size(); ++i) {
+ if (children.at(i)->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity)
+ return false;
+ }
+ return true;
+ }
+
+ inline bool childrenClippedToShape() const
+ { return (flags & QGraphicsItem::ItemClipsChildrenToShape) || children.isEmpty(); }
+
+ inline bool isInvisible() const
+ {
+ return !visible || (childrenCombineOpacity() && isFullyTransparent());
+ }
+
+ inline void markParentDirty(bool updateBoundingRect = false);
+
+ void setFocusHelper(Qt::FocusReason focusReason, bool climb, bool focusFromHide);
+ void clearFocusHelper(bool giveFocusToParent);
+ void setSubFocus(QGraphicsItem *rootItem = 0, QGraphicsItem *stopItem = 0);
+ void clearSubFocus(QGraphicsItem *rootItem = 0, QGraphicsItem *stopItem = 0);
+ void resetFocusProxy();
+ virtual void subFocusItemChange();
+ virtual void focusScopeItemChange(bool isSubFocusItem);
+
+ static void children_append(QDeclarativeListProperty<QGraphicsObject> *list, QGraphicsObject *item);
+ static int children_count(QDeclarativeListProperty<QGraphicsObject> *list);
+ static QGraphicsObject *children_at(QDeclarativeListProperty<QGraphicsObject> *list, int);
+ static void children_clear(QDeclarativeListProperty<QGraphicsObject> *list);
+
+ inline QTransform transformToParent() const;
+ inline void ensureSortedChildren();
+ static inline bool insertionOrder(QGraphicsItem *a, QGraphicsItem *b);
+ void ensureSequentialSiblingIndex();
+ inline void sendScenePosChange();
+ virtual void siblingOrderChange();
+
+ // Private Properties
+ virtual qreal width() const;
+ virtual void setWidth(qreal);
+ virtual void resetWidth();
+
+ virtual qreal height() const;
+ virtual void setHeight(qreal);
+ virtual void resetHeight();
+
+ QRectF childrenBoundingRect;
+ QRectF needsRepaint;
+ QMap<QWidget *, QRect> paintedViewBoundingRects;
+ QPointF pos;
+ qreal z;
+ qreal opacity;
+ QGraphicsScene *scene;
+ QGraphicsItem *parent;
+ QList<QGraphicsItem *> children;
+ struct TransformData;
+ TransformData *transformData;
+ QGraphicsEffect *graphicsEffect;
+ QTransform sceneTransform;
+ int index;
+ int siblingIndex;
+ int itemDepth; // Lazily calculated when calling depth().
+ QGraphicsItem *focusProxy;
+ QList<QGraphicsItem **> focusProxyRefs;
+ QGraphicsItem *subFocusItem;
+ QGraphicsItem *focusScopeItem;
+ Qt::InputMethodHints imHints;
+ QGraphicsItem::PanelModality panelModality;
+#ifndef QT_NO_GESTURES
+ QMap<Qt::GestureType, Qt::GestureFlags> gestureContext;
+#endif
+
+ // Packed 32 bits
+ quint32 acceptedMouseButtons : 5;
+ quint32 visible : 1;
+ quint32 explicitlyHidden : 1;
+ quint32 enabled : 1;
+ quint32 explicitlyDisabled : 1;
+ quint32 selected : 1;
+ quint32 acceptsHover : 1;
+ quint32 acceptDrops : 1;
+ quint32 isMemberOfGroup : 1;
+ quint32 handlesChildEvents : 1;
+ quint32 itemDiscovered : 1;
+ quint32 hasCursor : 1;
+ quint32 ancestorFlags : 4;
+ quint32 cacheMode : 2;
+ quint32 hasBoundingRegionGranularity : 1;
+ quint32 isWidget : 1;
+ quint32 dirty : 1;
+ quint32 dirtyChildren : 1;
+ quint32 localCollisionHack : 1;
+ quint32 inSetPosHelper : 1;
+ quint32 needSortChildren : 1;
+ quint32 allChildrenDirty : 1;
+ quint32 fullUpdatePending : 1;
+ quint32 dirtyChildrenBoundingRect : 1;
+
+ // Packed 32 bits
+ quint32 flags : 19;
+ quint32 paintedViewBoundingRectsNeedRepaint : 1;
+ quint32 dirtySceneTransform : 1;
+ quint32 geometryChanged : 1;
+ quint32 inDestructor : 1;
+ quint32 isObject : 1;
+ quint32 ignoreVisible : 1;
+ quint32 ignoreOpacity : 1;
+ quint32 acceptTouchEvents : 1;
+ quint32 acceptedTouchBeginEvent : 1;
+ quint32 filtersDescendantEvents : 1;
+ quint32 sceneTransformTranslateOnly : 1;
+ quint32 notifyBoundingRectChanged : 1;
+ quint32 notifyInvalidated : 1;
+
+ // New 32 bits
+ quint32 mouseSetsFocus : 1;
+ quint32 explicitActivate : 1;
+ quint32 wantsActive : 1;
+ quint32 holesInSiblingIndex : 1;
+ quint32 sequentialOrdering : 1;
+ quint32 updateDueToGraphicsEffect : 1;
+ quint32 scenePosDescendants : 1;
+ quint32 pendingPolish : 1;
+ quint32 mayHaveChildWithGraphicsEffect : 1;
+ quint32 isDeclarativeItem : 1;
+ quint32 sendParentChangeNotification : 1;
+ quint32 padding : 21;
+
+ // Optional stacking order
+ int globalStackingOrder;
+ QGraphicsItem *q_ptr;
+};
+
+struct QGraphicsItemPrivate::TransformData
+{
+ QTransform transform;
+ qreal scale;
+ qreal rotation;
+ qreal xOrigin;
+ qreal yOrigin;
+ QList<QGraphicsTransform *> graphicsTransforms;
+ bool onlyTransform;
+
+ TransformData() :
+ scale(1.0), rotation(0.0),
+ xOrigin(0.0), yOrigin(0.0),
+ onlyTransform(true)
+ { }
+
+ QTransform computedFullTransform(QTransform *postmultiplyTransform = 0) const
+ {
+ if (onlyTransform) {
+ if (!postmultiplyTransform || postmultiplyTransform->isIdentity())
+ return transform;
+ if (transform.isIdentity())
+ return *postmultiplyTransform;
+ return transform * *postmultiplyTransform;
+ }
+
+ QTransform x(transform);
+ if (!graphicsTransforms.isEmpty()) {
+ QMatrix4x4 m;
+ for (int i = 0; i < graphicsTransforms.size(); ++i)
+ graphicsTransforms.at(i)->applyTo(&m);
+ x *= m.toTransform();
+ }
+ x.translate(xOrigin, yOrigin);
+ x.rotate(rotation);
+ x.scale(scale, scale);
+ x.translate(-xOrigin, -yOrigin);
+ if (postmultiplyTransform)
+ x *= *postmultiplyTransform;
+ return x;
+ }
+};
+
+struct QGraphicsItemPaintInfo
+{
+ inline QGraphicsItemPaintInfo(const QTransform *const xform1, const QTransform *const xform2,
+ const QTransform *const xform3,
+ QRegion *r, QWidget *w, QStyleOptionGraphicsItem *opt,
+ QPainter *p, qreal o, bool b1, bool b2)
+ : viewTransform(xform1), transformPtr(xform2), effectTransform(xform3), exposedRegion(r), widget(w),
+ option(opt), painter(p), opacity(o), wasDirtySceneTransform(b1), drawItem(b2)
+ {}
+
+ const QTransform *viewTransform;
+ const QTransform *transformPtr;
+ const QTransform *effectTransform;
+ QRegion *exposedRegion;
+ QWidget *widget;
+ QStyleOptionGraphicsItem *option;
+ QPainter *painter;
+ qreal opacity;
+ quint32 wasDirtySceneTransform : 1;
+ quint32 drawItem : 1;
+};
+
+#ifndef QT_NO_GRAPHICSEFFECT
+class QGraphicsItemEffectSourcePrivate : public QGraphicsEffectSourcePrivate
+{
+public:
+ QGraphicsItemEffectSourcePrivate(QGraphicsItem *i)
+ : QGraphicsEffectSourcePrivate(), item(i), info(0)
+ {}
+
+ inline void detach()
+ {
+ item->d_ptr->graphicsEffect = 0;
+ item->prepareGeometryChange();
+ }
+
+ inline const QGraphicsItem *graphicsItem() const
+ { return item; }
+
+ inline const QWidget *widget() const
+ { return 0; }
+
+ inline void update() {
+ item->d_ptr->updateDueToGraphicsEffect = true;
+ item->update();
+ item->d_ptr->updateDueToGraphicsEffect = false;
+ }
+
+ inline void effectBoundingRectChanged()
+ { item->prepareGeometryChange(); }
+
+ inline bool isPixmap() const
+ {
+ return item->type() == QGraphicsPixmapItem::Type
+ && !(item->flags() & QGraphicsItem::ItemIsSelectable)
+ && item->d_ptr->children.size() == 0;
+ //|| (item->d_ptr->isObject && qobject_cast<QDeclarativeImage *>(q_func()));
+ }
+
+ inline const QStyleOption *styleOption() const
+ { return info ? info->option : 0; }
+
+ inline QRect deviceRect() const
+ {
+ if (!info || !info->widget) {
+ qWarning("QGraphicsEffectSource::deviceRect: Not yet implemented, lacking device context");
+ return QRect();
+ }
+ return info->widget->rect();
+ }
+
+ QRectF boundingRect(Qt::CoordinateSystem system) const;
+ void draw(QPainter *);
+ QPixmap pixmap(Qt::CoordinateSystem system,
+ QPoint *offset,
+ QGraphicsEffect::PixmapPadMode mode) const;
+ QRect paddedEffectRect(Qt::CoordinateSystem system, QGraphicsEffect::PixmapPadMode mode, const QRectF &sourceRect, bool *unpadded = 0) const;
+
+ QGraphicsItem *item;
+ QGraphicsItemPaintInfo *info;
+ QTransform lastEffectTransform;
+};
+#endif //QT_NO_GRAPHICSEFFECT
+
+/*!
+ Returns true if \a item1 is on top of \a item2.
+ The items don't need to be siblings.
+
+ \internal
+*/
+inline bool qt_closestItemFirst(const QGraphicsItem *item1, const QGraphicsItem *item2)
+{
+ // Siblings? Just check their z-values.
+ const QGraphicsItemPrivate *d1 = item1->d_ptr.data();
+ const QGraphicsItemPrivate *d2 = item2->d_ptr.data();
+ if (d1->parent == d2->parent)
+ return qt_closestLeaf(item1, item2);
+
+ // Find common ancestor, and each item's ancestor closest to the common
+ // ancestor.
+ int item1Depth = d1->depth();
+ int item2Depth = d2->depth();
+ const QGraphicsItem *p = item1;
+ const QGraphicsItem *t1 = item1;
+ while (item1Depth > item2Depth && (p = p->d_ptr->parent)) {
+ if (p == item2) {
+ // item2 is one of item1's ancestors; item1 is on top
+ return !(t1->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent);
+ }
+ t1 = p;
+ --item1Depth;
+ }
+ p = item2;
+ const QGraphicsItem *t2 = item2;
+ while (item2Depth > item1Depth && (p = p->d_ptr->parent)) {
+ if (p == item1) {
+ // item1 is one of item2's ancestors; item1 is not on top
+ return (t2->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent);
+ }
+ t2 = p;
+ --item2Depth;
+ }
+
+ // item1Ancestor is now at the same level as item2Ancestor, but not the same.
+ const QGraphicsItem *p1 = t1;
+ const QGraphicsItem *p2 = t2;
+ while (t1 && t1 != t2) {
+ p1 = t1;
+ p2 = t2;
+ t1 = t1->d_ptr->parent;
+ t2 = t2->d_ptr->parent;
+ }
+
+ // in case we have a common ancestor, we compare the immediate children in the ancestor's path.
+ // otherwise we compare the respective items' topLevelItems directly.
+ return qt_closestLeaf(p1, p2);
+}
+
+/*!
+ Returns true if \a item2 is on top of \a item1.
+ The items don't need to be siblings.
+
+ \internal
+*/
+inline bool qt_closestItemLast(const QGraphicsItem *item1, const QGraphicsItem *item2)
+{
+ return qt_closestItemFirst(item2, item1);
+}
+
+/*!
+ \internal
+*/
+inline bool qt_closestLeaf(const QGraphicsItem *item1, const QGraphicsItem *item2)
+{
+ // Return true if sibling item1 is on top of item2.
+ const QGraphicsItemPrivate *d1 = item1->d_ptr.data();
+ const QGraphicsItemPrivate *d2 = item2->d_ptr.data();
+ bool f1 = d1->flags & QGraphicsItem::ItemStacksBehindParent;
+ bool f2 = d2->flags & QGraphicsItem::ItemStacksBehindParent;
+ if (f1 != f2)
+ return f2;
+ if (d1->z != d2->z)
+ return d1->z > d2->z;
+ return d1->siblingIndex > d2->siblingIndex;
+}
+
+/*!
+ \internal
+*/
+inline bool qt_notclosestLeaf(const QGraphicsItem *item1, const QGraphicsItem *item2)
+{ return qt_closestLeaf(item2, item1); }
+
+/*
+ return the full transform of the item to the parent. This include the position and all the transform data
+*/
+inline QTransform QGraphicsItemPrivate::transformToParent() const
+{
+ QTransform matrix;
+ combineTransformToParent(&matrix);
+ return matrix;
+}
+
+/*!
+ \internal
+*/
+inline void QGraphicsItemPrivate::ensureSortedChildren()
+{
+ if (needSortChildren) {
+ needSortChildren = 0;
+ sequentialOrdering = 1;
+ if (children.isEmpty())
+ return;
+ qSort(children.begin(), children.end(), qt_notclosestLeaf);
+ for (int i = 0; i < children.size(); ++i) {
+ if (children.at(i)->d_ptr->siblingIndex != i) {
+ sequentialOrdering = 0;
+ break;
+ }
+ }
+ }
+}
+
+/*!
+ \internal
+*/
+inline bool QGraphicsItemPrivate::insertionOrder(QGraphicsItem *a, QGraphicsItem *b)
+{
+ return a->d_ptr->siblingIndex < b->d_ptr->siblingIndex;
+}
+
+/*!
+ \internal
+*/
+inline void QGraphicsItemPrivate::markParentDirty(bool updateBoundingRect)
+{
+ QGraphicsItemPrivate *parentp = this;
+#ifndef QT_NO_GRAPHICSEFFECT
+ if (updateBoundingRect && parentp->graphicsEffect && !parentp->inSetPosHelper) {
+ parentp->notifyInvalidated = 1;
+ static_cast<QGraphicsItemEffectSourcePrivate *>(parentp->graphicsEffect->d_func()
+ ->source->d_func())->invalidateCache();
+ }
+#endif
+ while (parentp->parent) {
+ parentp = parentp->parent->d_ptr.data();
+ parentp->dirtyChildren = 1;
+
+ if (updateBoundingRect) {
+ parentp->dirtyChildrenBoundingRect = 1;
+ // ### Only do this if the parent's effect applies to the entire subtree.
+ parentp->notifyBoundingRectChanged = 1;
+ }
+#ifndef QT_NO_GRAPHICSEFFECT
+ if (parentp->graphicsEffect) {
+ if (updateBoundingRect) {
+ static_cast<QGraphicsItemEffectSourcePrivate *>(parentp->graphicsEffect->d_func()
+ ->source->d_func())->invalidateCache();
+ parentp->notifyInvalidated = 1;
+ }
+ if (parentp->scene && parentp->graphicsEffect->isEnabled()) {
+ parentp->dirty = 1;
+ parentp->fullUpdatePending = 1;
+ }
+ }
+#endif
+ }
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_GRAPHICSVIEW
+
+#endif
diff --git a/src/gui/graphicsview/qgraphicsitemanimation.cpp b/src/widgets/graphicsview/qgraphicsitemanimation.cpp
index 104e21cf41..104e21cf41 100644
--- a/src/gui/graphicsview/qgraphicsitemanimation.cpp
+++ b/src/widgets/graphicsview/qgraphicsitemanimation.cpp
diff --git a/src/widgets/graphicsview/qgraphicsitemanimation.h b/src/widgets/graphicsview/qgraphicsitemanimation.h
new file mode 100644
index 0000000000..a6425a50e4
--- /dev/null
+++ b/src/widgets/graphicsview/qgraphicsitemanimation.h
@@ -0,0 +1,120 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGRAPHICSITEMANIMATION_H
+#define QGRAPHICSITEMANIMATION_H
+
+#include <QtCore/qobject.h>
+
+#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QGraphicsItem;
+class QMatrix;
+class QPointF;
+class QTimeLine;
+template <class T1, class T2> struct QPair;
+
+class QGraphicsItemAnimationPrivate;
+class Q_WIDGETS_EXPORT QGraphicsItemAnimation : public QObject
+{
+ Q_OBJECT
+public:
+ QGraphicsItemAnimation(QObject *parent = 0);
+ virtual ~QGraphicsItemAnimation();
+
+ QGraphicsItem *item() const;
+ void setItem(QGraphicsItem *item);
+
+ QTimeLine *timeLine() const;
+ void setTimeLine(QTimeLine *timeLine);
+
+ QPointF posAt(qreal step) const;
+ QList<QPair<qreal, QPointF> > posList() const;
+ void setPosAt(qreal step, const QPointF &pos);
+
+ QMatrix matrixAt(qreal step) const;
+
+ qreal rotationAt(qreal step) const;
+ QList<QPair<qreal, qreal> > rotationList() const;
+ void setRotationAt(qreal step, qreal angle);
+
+ qreal xTranslationAt(qreal step) const;
+ qreal yTranslationAt(qreal step) const;
+ QList<QPair<qreal, QPointF> > translationList() const;
+ void setTranslationAt(qreal step, qreal dx, qreal dy);
+
+ qreal verticalScaleAt(qreal step) const;
+ qreal horizontalScaleAt(qreal step) const;
+ QList<QPair<qreal, QPointF> > scaleList() const;
+ void setScaleAt(qreal step, qreal sx, qreal sy);
+
+ qreal verticalShearAt(qreal step) const;
+ qreal horizontalShearAt(qreal step) const;
+ QList<QPair<qreal, QPointF> > shearList() const;
+ void setShearAt(qreal step, qreal sh, qreal sv);
+
+ void clear();
+
+public Q_SLOTS:
+ void setStep(qreal x);
+ void reset();
+
+protected:
+ virtual void beforeAnimationStep(qreal step);
+ virtual void afterAnimationStep(qreal step);
+
+private:
+ Q_DISABLE_COPY(QGraphicsItemAnimation)
+ QGraphicsItemAnimationPrivate *d;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QT_NO_GRAPHICSVIEW
+#endif
diff --git a/src/gui/graphicsview/qgraphicslayout.cpp b/src/widgets/graphicsview/qgraphicslayout.cpp
index 76d2d040c7..76d2d040c7 100644
--- a/src/gui/graphicsview/qgraphicslayout.cpp
+++ b/src/widgets/graphicsview/qgraphicslayout.cpp
diff --git a/src/widgets/graphicsview/qgraphicslayout.h b/src/widgets/graphicsview/qgraphicslayout.h
new file mode 100644
index 0000000000..6b19f0e622
--- /dev/null
+++ b/src/widgets/graphicsview/qgraphicslayout.h
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGRAPHICSLAYOUT_H
+#define QGRAPHICSLAYOUT_H
+
+#include <QtWidgets/qgraphicslayoutitem.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW
+
+class QGraphicsLayoutPrivate;
+class QGraphicsLayoutItem;
+class QGraphicsWidget;
+
+class Q_WIDGETS_EXPORT QGraphicsLayout : public QGraphicsLayoutItem
+{
+public:
+ QGraphicsLayout(QGraphicsLayoutItem *parent = 0);
+ ~QGraphicsLayout();
+
+ void setContentsMargins(qreal left, qreal top, qreal right, qreal bottom);
+ void getContentsMargins(qreal *left, qreal *top, qreal *right, qreal *bottom) const;
+
+ void activate();
+ bool isActivated() const;
+ virtual void invalidate();
+ virtual void updateGeometry();
+
+ virtual void widgetEvent(QEvent *e);
+
+ virtual int count() const = 0;
+ virtual QGraphicsLayoutItem *itemAt(int i) const = 0;
+ virtual void removeAt(int index) = 0;
+
+ static void setInstantInvalidatePropagation(bool enable);
+ static bool instantInvalidatePropagation();
+protected:
+ QGraphicsLayout(QGraphicsLayoutPrivate &, QGraphicsLayoutItem *);
+ void addChildLayoutItem(QGraphicsLayoutItem *layoutItem);
+
+private:
+ Q_DISABLE_COPY(QGraphicsLayout)
+ Q_DECLARE_PRIVATE(QGraphicsLayout)
+ friend class QGraphicsWidget;
+};
+
+Q_DECLARE_INTERFACE(QGraphicsLayout, "com.trolltech.Qt.QGraphicsLayout")
+
+#endif
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
+
diff --git a/src/gui/graphicsview/qgraphicslayout_p.cpp b/src/widgets/graphicsview/qgraphicslayout_p.cpp
index c0df2c0d64..c0df2c0d64 100644
--- a/src/gui/graphicsview/qgraphicslayout_p.cpp
+++ b/src/widgets/graphicsview/qgraphicslayout_p.cpp
diff --git a/src/widgets/graphicsview/qgraphicslayout_p.h b/src/widgets/graphicsview/qgraphicslayout_p.h
new file mode 100644
index 0000000000..f11bfbf38c
--- /dev/null
+++ b/src/widgets/graphicsview/qgraphicslayout_p.h
@@ -0,0 +1,154 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGRAPHICSLAYOUT_P_H
+#define QGRAPHICSLAYOUT_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qglobal.h>
+
+#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW
+
+#include "qgraphicslayout.h"
+#include "qgraphicslayoutitem_p.h"
+#include <QtWidgets/qstyle.h>
+#include <QtWidgets/qwidget.h>
+#include <QtWidgets/qstyleoption.h>
+
+QT_BEGIN_NAMESPACE
+
+class QGraphicsLayoutItem;
+class QGraphicsWidget;
+
+#ifdef QT_DEBUG
+inline bool qt_graphicsLayoutDebug()
+{
+ static int checked_env = -1;
+ if(checked_env == -1)
+ checked_env = !!qgetenv("QT_GRAPHICSLAYOUT_DEBUG").toInt();
+ return checked_env;
+}
+#endif
+
+
+class QLayoutStyleInfo
+{
+public:
+ inline QLayoutStyleInfo() { invalidate(); }
+ inline QLayoutStyleInfo(QStyle *style, QWidget *widget)
+ : m_valid(true), m_style(style), m_widget(widget)
+ {
+ Q_ASSERT(style);
+ if (widget) //###
+ m_styleOption.initFrom(widget);
+ m_defaultSpacing[0] = style->pixelMetric(QStyle::PM_LayoutHorizontalSpacing);
+ m_defaultSpacing[1] = style->pixelMetric(QStyle::PM_LayoutVerticalSpacing);
+ }
+
+ inline void invalidate() { m_valid = false; m_style = 0; m_widget = 0; }
+
+ inline QStyle *style() const { return m_style; }
+ inline QWidget *widget() const { return m_widget; }
+
+ inline bool operator==(const QLayoutStyleInfo &other) const
+ { return m_style == other.m_style && m_widget == other.m_widget; }
+ inline bool operator!=(const QLayoutStyleInfo &other) const
+ { return !(*this == other); }
+
+ inline void setDefaultSpacing(Qt::Orientation o, qreal spacing){
+ if (spacing >= 0)
+ m_defaultSpacing[o - 1] = spacing;
+ }
+
+ inline qreal defaultSpacing(Qt::Orientation o) const {
+ return m_defaultSpacing[o - 1];
+ }
+
+ inline qreal perItemSpacing(QSizePolicy::ControlType control1,
+ QSizePolicy::ControlType control2,
+ Qt::Orientation orientation) const
+ {
+ Q_ASSERT(style());
+ return style()->layoutSpacing(control1, control2, orientation, &m_styleOption, widget());
+ }
+private:
+ bool m_valid;
+ QStyle *m_style;
+ QWidget *m_widget;
+ QStyleOption m_styleOption;
+ qreal m_defaultSpacing[2];
+};
+
+class Q_AUTOTEST_EXPORT QGraphicsLayoutPrivate : public QGraphicsLayoutItemPrivate
+{
+ Q_DECLARE_PUBLIC(QGraphicsLayout)
+
+public:
+ QGraphicsLayoutPrivate() : QGraphicsLayoutItemPrivate(0, true), left(-1.0), top(-1.0), right(-1.0), bottom(-1.0),
+ activated(true) { }
+
+ void reparentChildItems(QGraphicsItem *newParent);
+ void getMargin(qreal *result, qreal userMargin, QStyle::PixelMetric pm) const;
+ Qt::LayoutDirection visualDirection() const;
+
+ void addChildLayoutItem(QGraphicsLayoutItem *item);
+ void activateRecursive(QGraphicsLayoutItem *item);
+
+ qreal left, top, right, bottom;
+ bool activated;
+};
+
+
+QT_END_NAMESPACE
+
+#endif //QT_NO_GRAPHICSVIEW
+
+#endif
diff --git a/src/gui/graphicsview/qgraphicslayoutitem.cpp b/src/widgets/graphicsview/qgraphicslayoutitem.cpp
index 0631df80dd..0631df80dd 100644
--- a/src/gui/graphicsview/qgraphicslayoutitem.cpp
+++ b/src/widgets/graphicsview/qgraphicslayoutitem.cpp
diff --git a/src/widgets/graphicsview/qgraphicslayoutitem.h b/src/widgets/graphicsview/qgraphicslayoutitem.h
new file mode 100644
index 0000000000..c617959a06
--- /dev/null
+++ b/src/widgets/graphicsview/qgraphicslayoutitem.h
@@ -0,0 +1,155 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGRAPHICSLAYOUTITEM_H
+#define QGRAPHICSLAYOUTITEM_H
+
+#include <QtCore/qscopedpointer.h>
+#include <QtWidgets/qsizepolicy.h>
+#include <QtGui/qevent.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW
+
+class QGraphicsLayoutItemPrivate;
+class QGraphicsItem;
+class Q_WIDGETS_EXPORT QGraphicsLayoutItem
+{
+public:
+ QGraphicsLayoutItem(QGraphicsLayoutItem *parent = 0, bool isLayout = false);
+ virtual ~QGraphicsLayoutItem();
+
+ void setSizePolicy(const QSizePolicy &policy);
+ void setSizePolicy(QSizePolicy::Policy hPolicy, QSizePolicy::Policy vPolicy, QSizePolicy::ControlType controlType = QSizePolicy::DefaultType);
+ QSizePolicy sizePolicy() const;
+
+ void setMinimumSize(const QSizeF &size);
+ inline void setMinimumSize(qreal w, qreal h);
+ QSizeF minimumSize() const;
+ void setMinimumWidth(qreal width);
+ inline qreal minimumWidth() const;
+ void setMinimumHeight(qreal height);
+ inline qreal minimumHeight() const;
+
+ void setPreferredSize(const QSizeF &size);
+ inline void setPreferredSize(qreal w, qreal h);
+ QSizeF preferredSize() const;
+ void setPreferredWidth(qreal width);
+ inline qreal preferredWidth() const;
+ void setPreferredHeight(qreal height);
+ inline qreal preferredHeight() const;
+
+ void setMaximumSize(const QSizeF &size);
+ inline void setMaximumSize(qreal w, qreal h);
+ QSizeF maximumSize() const;
+ void setMaximumWidth(qreal width);
+ inline qreal maximumWidth() const;
+ void setMaximumHeight(qreal height);
+ inline qreal maximumHeight() const;
+
+ virtual void setGeometry(const QRectF &rect);
+ QRectF geometry() const;
+ virtual void getContentsMargins(qreal *left, qreal *top, qreal *right, qreal *bottom) const;
+ QRectF contentsRect() const;
+
+ QSizeF effectiveSizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const;
+
+ virtual void updateGeometry(); //### rename to sizeHintChanged()
+
+ QGraphicsLayoutItem *parentLayoutItem() const;
+ void setParentLayoutItem(QGraphicsLayoutItem *parent);
+
+ bool isLayout() const;
+ // ###Qt5: Make automatic reparenting work regardless of item/object/widget type.
+ QGraphicsItem *graphicsItem() const;
+ bool ownedByLayout() const;
+
+protected:
+ void setGraphicsItem(QGraphicsItem *item);
+ void setOwnedByLayout(bool ownedByLayout);
+ QGraphicsLayoutItem(QGraphicsLayoutItemPrivate &dd);
+
+ virtual QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const = 0;
+ QScopedPointer<QGraphicsLayoutItemPrivate> d_ptr;
+
+private:
+ QSizeF *effectiveSizeHints(const QSizeF &constraint) const;
+ Q_DECLARE_PRIVATE(QGraphicsLayoutItem)
+
+ friend class QGraphicsLayout;
+};
+
+Q_DECLARE_INTERFACE(QGraphicsLayoutItem, "com.trolltech.Qt.QGraphicsLayoutItem")
+
+inline void QGraphicsLayoutItem::setMinimumSize(qreal aw, qreal ah)
+{ setMinimumSize(QSizeF(aw, ah)); }
+inline void QGraphicsLayoutItem::setPreferredSize(qreal aw, qreal ah)
+{ setPreferredSize(QSizeF(aw, ah)); }
+inline void QGraphicsLayoutItem::setMaximumSize(qreal aw, qreal ah)
+{ setMaximumSize(QSizeF(aw, ah)); }
+
+inline qreal QGraphicsLayoutItem::minimumWidth() const
+{ return effectiveSizeHint(Qt::MinimumSize).width(); }
+inline qreal QGraphicsLayoutItem::minimumHeight() const
+{ return effectiveSizeHint(Qt::MinimumSize).height(); }
+
+inline qreal QGraphicsLayoutItem::preferredWidth() const
+{ return effectiveSizeHint(Qt::PreferredSize).width(); }
+inline qreal QGraphicsLayoutItem::preferredHeight() const
+{ return effectiveSizeHint(Qt::PreferredSize).height(); }
+
+inline qreal QGraphicsLayoutItem::maximumWidth() const
+{ return effectiveSizeHint(Qt::MaximumSize).width(); }
+inline qreal QGraphicsLayoutItem::maximumHeight() const
+{ return effectiveSizeHint(Qt::MaximumSize).height(); }
+
+#endif
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/widgets/graphicsview/qgraphicslayoutitem_p.h b/src/widgets/graphicsview/qgraphicslayoutitem_p.h
new file mode 100644
index 0000000000..244c699faa
--- /dev/null
+++ b/src/widgets/graphicsview/qgraphicslayoutitem_p.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGRAPHICSLAYOUTITEM_P_H
+#define QGRAPHICSLAYOUTITEM_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/QSizeF>
+#include <QtWidgets/QSizePolicy>
+
+QT_BEGIN_NAMESPACE
+
+class QGraphicsLayoutItem;
+class Q_AUTOTEST_EXPORT QGraphicsLayoutItemPrivate
+{
+ Q_DECLARE_PUBLIC(QGraphicsLayoutItem)
+public:
+ virtual ~QGraphicsLayoutItemPrivate();
+ QGraphicsLayoutItemPrivate(QGraphicsLayoutItem *parent, bool isLayout);
+ static QGraphicsLayoutItemPrivate *get(QGraphicsLayoutItem *q) { return q->d_func();}
+ static const QGraphicsLayoutItemPrivate *get(const QGraphicsLayoutItem *q) { return q->d_func();}
+
+ void init();
+ QSizeF *effectiveSizeHints(const QSizeF &constraint) const;
+ QGraphicsItem *parentItem() const;
+ void ensureUserSizeHints();
+ void setSize(Qt::SizeHint which, const QSizeF &size);
+ enum SizeComponent { Width, Height };
+ void setSizeComponent(Qt::SizeHint which, SizeComponent component, qreal value);
+
+ bool hasHeightForWidth() const;
+ bool hasWidthForHeight() const;
+
+ QSizePolicy sizePolicy;
+ QGraphicsLayoutItem *parent;
+
+ QSizeF *userSizeHints;
+ mutable QSizeF cachedSizeHints[Qt::NSizeHints];
+ mutable QSizeF cachedConstraint;
+ mutable QSizeF cachedSizeHintsWithConstraints[Qt::NSizeHints];
+
+ mutable quint32 sizeHintCacheDirty : 1;
+ mutable quint32 sizeHintWithConstraintCacheDirty : 1;
+ quint32 isLayout : 1;
+ quint32 ownedByLayout : 1;
+
+ QGraphicsLayoutItem *q_ptr;
+ QRectF geom;
+ QGraphicsItem *graphicsItem;
+};
+
+QT_END_NAMESPACE
+
+#endif //QGRAPHICSLAYOUTITEM_P_H
+
diff --git a/src/gui/graphicsview/qgraphicslinearlayout.cpp b/src/widgets/graphicsview/qgraphicslinearlayout.cpp
index 2a5d5a510e..2a5d5a510e 100644
--- a/src/gui/graphicsview/qgraphicslinearlayout.cpp
+++ b/src/widgets/graphicsview/qgraphicslinearlayout.cpp
diff --git a/src/widgets/graphicsview/qgraphicslinearlayout.h b/src/widgets/graphicsview/qgraphicslinearlayout.h
new file mode 100644
index 0000000000..5d2d5c309f
--- /dev/null
+++ b/src/widgets/graphicsview/qgraphicslinearlayout.h
@@ -0,0 +1,119 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGRAPHICSLINEARLAYOUT_H
+#define QGRAPHICSLINEARLAYOUT_H
+
+#include <QtWidgets/qgraphicsitem.h>
+#include <QtWidgets/qgraphicslayout.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW
+
+class QGraphicsLinearLayoutPrivate;
+
+class Q_WIDGETS_EXPORT QGraphicsLinearLayout : public QGraphicsLayout
+{
+public:
+ QGraphicsLinearLayout(QGraphicsLayoutItem *parent = 0);
+ QGraphicsLinearLayout(Qt::Orientation orientation, QGraphicsLayoutItem *parent = 0);
+ virtual ~QGraphicsLinearLayout();
+
+ void setOrientation(Qt::Orientation orientation);
+ Qt::Orientation orientation() const;
+
+ inline void addItem(QGraphicsLayoutItem *item) { insertItem(-1, item); }
+ inline void addStretch(int stretch = 1) { insertStretch(-1, stretch); }
+
+ void insertItem(int index, QGraphicsLayoutItem *item);
+ void insertStretch(int index, int stretch = 1);
+
+ void removeItem(QGraphicsLayoutItem *item);
+ void removeAt(int index);
+
+ void setSpacing(qreal spacing);
+ qreal spacing() const;
+ void setItemSpacing(int index, qreal spacing);
+ qreal itemSpacing(int index) const;
+
+ void setStretchFactor(QGraphicsLayoutItem *item, int stretch);
+ int stretchFactor(QGraphicsLayoutItem *item) const;
+
+ void setAlignment(QGraphicsLayoutItem *item, Qt::Alignment alignment);
+ Qt::Alignment alignment(QGraphicsLayoutItem *item) const;
+
+ void setGeometry(const QRectF &rect);
+
+ int count() const;
+ QGraphicsLayoutItem *itemAt(int index) const;
+
+ void invalidate();
+ QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const;
+
+#if 0 // ###
+ Q5SizePolicy::ControlTypes controlTypes(LayoutSide side) const;
+#endif
+
+ void dump(int indent = 0) const;
+
+protected:
+#if 0
+ QSize contentsSizeHint(Qt::SizeHint which, const QSize &constraint = QSize()) const;
+#endif
+
+private:
+ Q_DISABLE_COPY(QGraphicsLinearLayout)
+ Q_DECLARE_PRIVATE(QGraphicsLinearLayout)
+};
+
+#endif
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
+
diff --git a/src/widgets/graphicsview/qgraphicsproxywidget.cpp b/src/widgets/graphicsview/qgraphicsproxywidget.cpp
new file mode 100644
index 0000000000..cb8e2259f4
--- /dev/null
+++ b/src/widgets/graphicsview/qgraphicsproxywidget.cpp
@@ -0,0 +1,1569 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qglobal.h"
+
+#ifndef QT_NO_GRAPHICSVIEW
+
+#include "qgraphicslayout.h"
+#include "qgraphicsproxywidget.h"
+#include "private/qgraphicsproxywidget_p.h"
+#include "private/qwidget_p.h"
+#include "private/qapplication_p.h"
+
+#include <QtCore/qdebug.h>
+#include <QtGui/qevent.h>
+#include <QtWidgets/qgraphicsscene.h>
+#include <QtWidgets/qgraphicssceneevent.h>
+#include <QtWidgets/qlayout.h>
+#include <QtGui/qpainter.h>
+#include <QtWidgets/qstyleoption.h>
+#include <QtWidgets/qgraphicsview.h>
+#include <QtWidgets/qlistview.h>
+#include <QtWidgets/qlineedit.h>
+#include <QtWidgets/qtextedit.h>
+
+QT_BEGIN_NAMESPACE
+
+//#define GRAPHICSPROXYWIDGET_DEBUG
+
+/*!
+ \class QGraphicsProxyWidget
+ \brief The QGraphicsProxyWidget class provides a proxy layer for embedding
+ a QWidget in a QGraphicsScene.
+ \since 4.4
+ \ingroup graphicsview-api
+
+ QGraphicsProxyWidget embeds QWidget-based widgets, for example, a
+ QPushButton, QFontComboBox, or even QFileDialog, into
+ QGraphicsScene. It forwards events between the two objects and
+ translates between QWidget's integer-based geometry and
+ QGraphicsWidget's qreal-based geometry. QGraphicsProxyWidget
+ supports all core features of QWidget, including tab focus,
+ keyboard input, Drag & Drop, and popups. You can also embed
+ complex widgets, e.g., widgets with subwidgets.
+
+ Example:
+
+ \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsproxywidget.cpp 0
+
+ QGraphicsProxyWidget takes care of automatically embedding popup children
+ of embedded widgets through creating a child proxy for each popup. This
+ means that when an embedded QComboBox shows its popup list, a new
+ QGraphicsProxyWidget is created automatically, embedding the popup, and
+ positioning it correctly. This only works if the popup is child of the
+ embedded widget (for example QToolButton::setMenu() requires the QMenu instance
+ to be child of the QToolButton).
+
+ \section1 Embedding a Widget with QGraphicsProxyWidget
+
+ There are two ways to embed a widget using QGraphicsProxyWidget. The most
+ common way is to pass a widget pointer to QGraphicsScene::addWidget()
+ together with any relevant \l Qt::WindowFlags. This function returns a
+ pointer to a QGraphicsProxyWidget. You can then choose to reparent or
+ position either the proxy, or the embedded widget itself.
+
+ For example, in the code snippet below, we embed a group box into the proxy:
+
+ \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsproxywidget.cpp 1
+
+ The image below is the output obtained with its contents margin and
+ contents rect labeled.
+
+ \image qgraphicsproxywidget-embed.png
+
+ Alternatively, you can start by creating a new QGraphicsProxyWidget item,
+ and then call setWidget() to embed a QWidget later. The widget() function
+ returns a pointer to the embedded widget. QGraphicsProxyWidget shares
+ ownership with QWidget, so if either of the two widgets are destroyed, the
+ other widget will be automatically destroyed as well.
+
+ \section1 Synchronizing Widget States
+
+ QGraphicsProxyWidget keeps its state in sync with the embedded widget. For
+ example, if the proxy is hidden or disabled, the embedded widget will be
+ hidden or disabled as well, and vice versa. When the widget is embedded by
+ calling addWidget(), QGraphicsProxyWidget copies the state from the widget
+ into the proxy, and after that, the two will stay synchronized where
+ possible. By default, when you embed a widget into a proxy, both the widget
+ and the proxy will be visible because a QGraphicsWidget is visible when
+ created (you do not have to call show()). If you explicitly hide the
+ embedded widget, the proxy will also become invisible.
+
+ Example:
+
+ \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsproxywidget.cpp 2
+
+ QGraphicsProxyWidget maintains symmetry for the following states:
+
+ \table
+ \header \o QWidget state \o QGraphicsProxyWidget state \o Notes
+ \row \o QWidget::enabled
+ \o QGraphicsProxyWidget::enabled
+ \o
+ \row \o QWidget::visible
+ \o QGraphicsProxyWidget::visible
+ \o The explicit state is also symmetric.
+ \row \o QWidget::geometry
+ \o QGraphicsProxyWidget::geometry
+ \o Geometry is only guaranteed to be symmetric while
+ the embedded widget is visible.
+ \row \o QWidget::layoutDirection
+ \o QGraphicsProxyWidget::layoutDirection
+ \o
+ \row \o QWidget::style
+ \o QGraphicsProxyWidget::style
+ \o
+ \row \o QWidget::palette
+ \o QGraphicsProxyWidget::palette
+ \o
+ \row \o QWidget::font
+ \o QGraphicsProxyWidget::font
+ \o
+ \row \o QWidget::cursor
+ \o QGraphicsProxyWidget::cursor
+ \o The embedded widget overrides the proxy widget
+ cursor. The proxy cursor changes depending on
+ which embedded subwidget is currently under the
+ mouse.
+ \row \o QWidget::sizeHint()
+ \o QGraphicsProxyWidget::sizeHint()
+ \o All size hint functionality from the embedded
+ widget is forwarded by the proxy.
+ \row \o QWidget::getContentsMargins()
+ \o QGraphicsProxyWidget::getContentsMargins()
+ \o Updated once by setWidget().
+ \row \o QWidget::windowTitle
+ \o QGraphicsProxyWidget::windowTitle
+ \o Updated once by setWidget().
+ \endtable
+
+ \note QGraphicsScene keeps the embedded widget in a special state that
+ prevents it from disturbing other widgets (both embedded and not embedded)
+ 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
+*/
+
+extern bool qt_sendSpontaneousEvent(QObject *, QEvent *);
+Q_WIDGETS_EXPORT extern bool qt_tab_all_widgets;
+
+/*!
+ \internal
+*/
+void QGraphicsProxyWidgetPrivate::init()
+{
+ Q_Q(QGraphicsProxyWidget);
+ q->setFocusPolicy(Qt::WheelFocus);
+ q->setAcceptDrops(true);
+}
+
+/*!
+ \internal
+*/
+void QGraphicsProxyWidgetPrivate::sendWidgetMouseEvent(QGraphicsSceneHoverEvent *event)
+{
+ QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMouseMove);
+ mouseEvent.setPos(event->pos());
+ mouseEvent.setScreenPos(event->screenPos());
+ mouseEvent.setButton(Qt::NoButton);
+ mouseEvent.setButtons(0);
+ mouseEvent.setModifiers(event->modifiers());
+ sendWidgetMouseEvent(&mouseEvent);
+ event->setAccepted(mouseEvent.isAccepted());
+}
+
+/*!
+ \internal
+*/
+void QGraphicsProxyWidgetPrivate::sendWidgetMouseEvent(QGraphicsSceneMouseEvent *event)
+{
+ if (!event || !widget || !widget->isVisible())
+ return;
+ Q_Q(QGraphicsProxyWidget);
+
+ // Find widget position and receiver.
+ QPointF pos = event->pos();
+ QPointer<QWidget> alienWidget = widget->childAt(pos.toPoint());
+ QPointer<QWidget> receiver = alienWidget ? alienWidget : widget;
+
+ if (QWidgetPrivate::nearestGraphicsProxyWidget(receiver) != q)
+ return; //another proxywidget will handle the events
+
+ // Translate QGraphicsSceneMouse events to QMouseEvents.
+ QEvent::Type type = QEvent::None;
+ switch (event->type()) {
+ case QEvent::GraphicsSceneMousePress:
+ type = QEvent::MouseButtonPress;
+ if (!embeddedMouseGrabber)
+ embeddedMouseGrabber = receiver;
+ else
+ receiver = embeddedMouseGrabber;
+ break;
+ case QEvent::GraphicsSceneMouseRelease:
+ type = QEvent::MouseButtonRelease;
+ if (embeddedMouseGrabber)
+ receiver = embeddedMouseGrabber;
+ break;
+ case QEvent::GraphicsSceneMouseDoubleClick:
+ type = QEvent::MouseButtonDblClick;
+ if (!embeddedMouseGrabber)
+ embeddedMouseGrabber = receiver;
+ else
+ receiver = embeddedMouseGrabber;
+ break;
+ case QEvent::GraphicsSceneMouseMove:
+ type = QEvent::MouseMove;
+ if (embeddedMouseGrabber)
+ receiver = embeddedMouseGrabber;
+ break;
+ default:
+ Q_ASSERT_X(false, "QGraphicsProxyWidget", "internal error");
+ break;
+ }
+
+ if (!lastWidgetUnderMouse) {
+ QApplicationPrivate::dispatchEnterLeave(embeddedMouseGrabber ? embeddedMouseGrabber : receiver, 0);
+ lastWidgetUnderMouse = receiver;
+ }
+
+ // Map event position from us to the receiver
+ pos = mapToReceiver(pos, receiver);
+
+ // Send mouse event.
+ QMouseEvent mouseEvent(type, pos, receiver->mapTo(receiver->topLevelWidget(), pos.toPoint()),
+ receiver->mapToGlobal(pos.toPoint()),
+ event->button(), event->buttons(), event->modifiers());
+
+ QWidget *embeddedMouseGrabberPtr = (QWidget *)embeddedMouseGrabber;
+ QApplicationPrivate::sendMouseEvent(receiver, &mouseEvent, alienWidget, widget,
+ &embeddedMouseGrabberPtr, lastWidgetUnderMouse, event->spontaneous());
+ embeddedMouseGrabber = embeddedMouseGrabberPtr;
+
+ // Handle enter/leave events when last button is released from mouse
+ // grabber child widget.
+ if (embeddedMouseGrabber && type == QEvent::MouseButtonRelease && !event->buttons()) {
+ Q_Q(QGraphicsProxyWidget);
+ if (q->rect().contains(event->pos()) && q->acceptsHoverEvents())
+ lastWidgetUnderMouse = alienWidget ? alienWidget : widget;
+ else // released on the frame our outside the item, or doesn't accept hover events.
+ lastWidgetUnderMouse = 0;
+
+ QApplicationPrivate::dispatchEnterLeave(lastWidgetUnderMouse, embeddedMouseGrabber);
+ embeddedMouseGrabber = 0;
+
+#ifndef QT_NO_CURSOR
+ // ### Restore the cursor, don't override it.
+ if (!lastWidgetUnderMouse)
+ q->unsetCursor();
+#endif
+ }
+
+ event->setAccepted(mouseEvent.isAccepted());
+}
+
+void QGraphicsProxyWidgetPrivate::sendWidgetKeyEvent(QKeyEvent *event)
+{
+ Q_Q(QGraphicsProxyWidget);
+ if (!event || !widget || !widget->isVisible())
+ return;
+
+ QPointer<QWidget> receiver = widget->focusWidget();
+ if (!receiver)
+ receiver = widget;
+ Q_ASSERT(receiver);
+
+ do {
+ bool res = QApplication::sendEvent(receiver, event);
+ if ((res && event->isAccepted()) || (q->isWindow() && receiver == widget))
+ break;
+ receiver = receiver->parentWidget();
+ } while (receiver);
+}
+
+/*!
+ \internal
+*/
+void QGraphicsProxyWidgetPrivate::removeSubFocusHelper(QWidget *widget, Qt::FocusReason reason)
+{
+ QFocusEvent event(QEvent::FocusOut, reason);
+ QPointer<QWidget> widgetGuard = widget;
+ QApplication::sendEvent(widget, &event);
+ if (widgetGuard && event.isAccepted())
+ QApplication::sendEvent(widget->style(), &event);
+}
+
+/*!
+ \internal
+
+ Reimplemented from QGraphicsItemPrivate. ### Qt 5: Move impl to
+ reimplementation QGraphicsProxyWidget::inputMethodQuery().
+*/
+QVariant QGraphicsProxyWidgetPrivate::inputMethodQueryHelper(Qt::InputMethodQuery query) const
+{
+ Q_Q(const QGraphicsProxyWidget);
+ if (!widget || !q->hasFocus())
+ return QVariant();
+
+ QWidget *focusWidget = widget->focusWidget();
+ if (!focusWidget)
+ focusWidget = widget;
+ QVariant v = focusWidget->inputMethodQuery(query);
+ QPointF focusWidgetPos = q->subWidgetRect(focusWidget).topLeft();
+ switch (v.type()) {
+ case QVariant::RectF:
+ v = v.toRectF().translated(focusWidgetPos);
+ break;
+ case QVariant::PointF:
+ v = v.toPointF() + focusWidgetPos;
+ break;
+ case QVariant::Rect:
+ v = v.toRect().translated(focusWidgetPos.toPoint());
+ break;
+ case QVariant::Point:
+ v = v.toPoint() + focusWidgetPos.toPoint();
+ break;
+ default:
+ break;
+ }
+ return v;
+}
+
+/*!
+ \internal
+ Some of the logic is shared with QApplicationPrivate::focusNextPrevChild_helper
+*/
+QWidget *QGraphicsProxyWidgetPrivate::findFocusChild(QWidget *child, bool next) const
+{
+ if (!widget)
+ return 0;
+
+ // Run around the focus chain until we find a widget that can take tab focus.
+ if (!child) {
+ child = next ? (QWidget *)widget : widget->d_func()->focus_prev;
+ } else {
+ child = next ? child->d_func()->focus_next : child->d_func()->focus_prev;
+ if ((next && child == widget) || (!next && child == widget->d_func()->focus_prev)) {
+ return 0;
+ }
+ }
+
+ QWidget *oldChild = child;
+ uint focus_flag = qt_tab_all_widgets ? Qt::TabFocus : Qt::StrongFocus;
+ do {
+ if (child->isEnabled()
+ && child->isVisibleTo(widget)
+ && ((child->focusPolicy() & focus_flag) == focus_flag)
+ && !(child->d_func()->extra && child->d_func()->extra->focus_proxy)) {
+ return child;
+ }
+ child = next ? child->d_func()->focus_next : child->d_func()->focus_prev;
+ } while (child != oldChild && !(next && child == widget) && !(!next && child == widget->d_func()->focus_prev));
+ return 0;
+}
+
+/*!
+ \internal
+*/
+void QGraphicsProxyWidgetPrivate::_q_removeWidgetSlot()
+{
+ Q_Q(QGraphicsProxyWidget);
+ widget = 0;
+ delete q;
+}
+
+/*!
+ \internal
+*/
+void QGraphicsProxyWidgetPrivate::updateWidgetGeometryFromProxy()
+{
+}
+
+/*!
+ \internal
+*/
+void QGraphicsProxyWidgetPrivate::updateProxyGeometryFromWidget()
+{
+ Q_Q(QGraphicsProxyWidget);
+ if (!widget)
+ return;
+
+ QRectF widgetGeometry = widget->geometry();
+ QWidget *parentWidget = widget->parentWidget();
+ if (widget->isWindow()) {
+ QGraphicsProxyWidget *proxyParent = 0;
+ if (parentWidget && (proxyParent = qobject_cast<QGraphicsProxyWidget *>(q->parentWidget()))) {
+ // Nested window proxy (e.g., combobox popup), map widget to the
+ // parent widget's global coordinates, and map that to the parent
+ // proxy's child coordinates.
+ widgetGeometry.moveTo(proxyParent->subWidgetRect(parentWidget).topLeft()
+ + parentWidget->mapFromGlobal(widget->pos()));
+ }
+ }
+
+ // Adjust to size hint if the widget has never been resized.
+ if (!widget->size().isValid())
+ widgetGeometry.setSize(widget->sizeHint());
+
+ // Assign new geometry.
+ posChangeMode = QGraphicsProxyWidgetPrivate::WidgetToProxyMode;
+ sizeChangeMode = QGraphicsProxyWidgetPrivate::WidgetToProxyMode;
+ q->setGeometry(widgetGeometry);
+ posChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
+ sizeChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
+}
+
+/*!
+ \internal
+*/
+void QGraphicsProxyWidgetPrivate::updateProxyInputMethodAcceptanceFromWidget()
+{
+ Q_Q(QGraphicsProxyWidget);
+ if (!widget)
+ return;
+
+ QWidget *focusWidget = widget->focusWidget();
+ if (!focusWidget)
+ focusWidget = widget;
+ q->setFlag(QGraphicsItem::ItemAcceptsInputMethod,
+ focusWidget->testAttribute(Qt::WA_InputMethodEnabled));
+}
+
+/*!
+ \internal
+
+ Embeds \a subWin as a subwindow of this proxy widget. \a subWin must be a top-level
+ widget and a descendant of the widget managed by this proxy. A separate subproxy
+ will be created as a child of this proxy widget to manage \a subWin.
+*/
+void QGraphicsProxyWidgetPrivate::embedSubWindow(QWidget *subWin)
+{
+ QWExtra *extra;
+ if (!((extra = subWin->d_func()->extra) && extra->proxyWidget)) {
+ QGraphicsProxyWidget *subProxy = new QGraphicsProxyWidget(q_func(), subWin->windowFlags());
+ subProxy->d_func()->setWidget_helper(subWin, false);
+ }
+}
+
+/*!
+ \internal
+
+ Removes ("unembeds") \a subWin and deletes the proxy holder item. This can
+ happen when QWidget::setParent() reparents the embedded window out of
+ "embedded space".
+*/
+void QGraphicsProxyWidgetPrivate::unembedSubWindow(QWidget *subWin)
+{
+ foreach (QGraphicsItem *child, children) {
+ if (child->isWidget()) {
+ if (QGraphicsProxyWidget *proxy = qobject_cast<QGraphicsProxyWidget *>(static_cast<QGraphicsWidget *>(child))) {
+ if (proxy->widget() == subWin) {
+ proxy->setWidget(0);
+ scene->removeItem(proxy);
+ delete proxy;
+ return;
+ }
+ }
+ }
+ }
+}
+
+bool QGraphicsProxyWidgetPrivate::isProxyWidget() const
+{
+ return true;
+}
+
+/*!
+ \internal
+*/
+QPointF QGraphicsProxyWidgetPrivate::mapToReceiver(const QPointF &pos, const QWidget *receiver) const
+{
+ QPointF p = pos;
+ // Map event position from us to the receiver, preserving its
+ // precision (don't use QWidget::mapFrom here).
+ while (receiver && receiver != widget) {
+ p -= QPointF(receiver->pos());
+ receiver = receiver->parentWidget();
+ }
+ return p;
+}
+
+/*!
+ Constructs a new QGraphicsProxy widget. \a parent and \a wFlags are passed
+ to QGraphicsItem's constructor.
+*/
+QGraphicsProxyWidget::QGraphicsProxyWidget(QGraphicsItem *parent, Qt::WindowFlags wFlags)
+ : QGraphicsWidget(*new QGraphicsProxyWidgetPrivate, parent, 0, wFlags)
+{
+ Q_D(QGraphicsProxyWidget);
+ d->init();
+}
+
+/*!
+ Destroys the proxy widget and any embedded widget.
+*/
+QGraphicsProxyWidget::~QGraphicsProxyWidget()
+{
+ Q_D(QGraphicsProxyWidget);
+ if (d->widget) {
+ QObject::disconnect(d->widget, SIGNAL(destroyed()), this, SLOT(_q_removeWidgetSlot()));
+ delete d->widget;
+ }
+}
+
+/*!
+ Embeds \a widget into this proxy widget. The embedded widget must reside
+ exclusively either inside or outside of Graphics View. You cannot embed a
+ widget as long as it is is visible elsewhere in the UI, at the same time.
+
+ \a widget must be a top-level widget whose parent is 0.
+
+ When the widget is embedded, its state (e.g., visible, enabled, geometry,
+ size hints) is copied into the proxy widget. If the embedded widget is
+ explicitly hidden or disabled, the proxy widget will become explicitly
+ hidden or disabled after embedding is complete. The class documentation
+ has a full overview over the shared state.
+
+ QGraphicsProxyWidget's window flags determine whether the widget, after
+ embedding, will be given window decorations or not.
+
+ After this function returns, QGraphicsProxyWidget will keep its state
+ synchronized with that of \a widget whenever possible.
+
+ If a widget is already embedded by this proxy when this function is
+ called, that widget will first be automatically unembedded. Passing 0 for
+ the \a widget argument will only unembed the widget, and the ownership of
+ the currently embedded widget will be passed on to the caller.
+ Every child widget that are embedded will also be embedded and their proxy
+ widget destroyed.
+
+ Note that widgets with the Qt::WA_PaintOnScreen widget attribute
+ set and widgets that wrap an external application or controller
+ cannot be embedded. Examples are QGLWidget and QAxWidget.
+
+ \sa widget()
+*/
+void QGraphicsProxyWidget::setWidget(QWidget *widget)
+{
+ Q_D(QGraphicsProxyWidget);
+ d->setWidget_helper(widget, true);
+}
+
+void QGraphicsProxyWidgetPrivate::setWidget_helper(QWidget *newWidget, bool autoShow)
+{
+ Q_Q(QGraphicsProxyWidget);
+ if (newWidget == widget)
+ return;
+ if (widget) {
+ QObject::disconnect(widget, SIGNAL(destroyed()), q, SLOT(_q_removeWidgetSlot()));
+ widget->removeEventFilter(q);
+ widget->setAttribute(Qt::WA_DontShowOnScreen, false);
+ widget->d_func()->extra->proxyWidget = 0;
+ resolveFont(inheritedFontResolveMask);
+ resolvePalette(inheritedPaletteResolveMask);
+ widget->update();
+
+ foreach (QGraphicsItem *child, q->childItems()) {
+ if (child->d_ptr->isProxyWidget()) {
+ QGraphicsProxyWidget *childProxy = static_cast<QGraphicsProxyWidget *>(child);
+ QWidget * parent = childProxy->widget();
+ while (parent->parentWidget() != 0) {
+ if (parent == widget)
+ break;
+ parent = parent->parentWidget();
+ }
+ if (!childProxy->widget() || parent != widget)
+ continue;
+ childProxy->setWidget(0);
+ delete childProxy;
+ }
+ }
+
+ widget = 0;
+#ifndef QT_NO_CURSOR
+ q->unsetCursor();
+#endif
+ q->setAcceptHoverEvents(false);
+ if (!newWidget)
+ q->update();
+ }
+ if (!newWidget)
+ return;
+ if (!newWidget->isWindow()) {
+ QWExtra *extra = newWidget->parentWidget()->d_func()->extra;
+ if (!extra || !extra->proxyWidget) {
+ qWarning("QGraphicsProxyWidget::setWidget: cannot embed widget %p "
+ "which is not a toplevel widget, and is not a child of an embedded widget", newWidget);
+ return;
+ }
+ }
+
+ // Register this proxy within the widget's private.
+ // ### This is a bit backdoorish
+ QWExtra *extra = newWidget->d_func()->extra;
+ if (!extra) {
+ newWidget->d_func()->createExtra();
+ extra = newWidget->d_func()->extra;
+ }
+ QGraphicsProxyWidget **proxyWidget = &extra->proxyWidget;
+ if (*proxyWidget) {
+ if (*proxyWidget != q) {
+ qWarning("QGraphicsProxyWidget::setWidget: cannot embed widget %p"
+ "; already embedded", newWidget);
+ }
+ return;
+ }
+ *proxyWidget = q;
+
+ newWidget->setAttribute(Qt::WA_DontShowOnScreen);
+ newWidget->ensurePolished();
+ // Do not wait for this widget to close before the app closes ###
+ // shouldn't this widget inherit the attribute?
+ newWidget->setAttribute(Qt::WA_QuitOnClose, false);
+ q->setAcceptHoverEvents(true);
+
+ if (newWidget->testAttribute(Qt::WA_NoSystemBackground))
+ q->setAttribute(Qt::WA_NoSystemBackground);
+ if (newWidget->testAttribute(Qt::WA_OpaquePaintEvent))
+ q->setAttribute(Qt::WA_OpaquePaintEvent);
+
+ widget = newWidget;
+
+ // Changes only go from the widget to the proxy.
+ enabledChangeMode = QGraphicsProxyWidgetPrivate::WidgetToProxyMode;
+ visibleChangeMode = QGraphicsProxyWidgetPrivate::WidgetToProxyMode;
+ posChangeMode = QGraphicsProxyWidgetPrivate::WidgetToProxyMode;
+ sizeChangeMode = QGraphicsProxyWidgetPrivate::WidgetToProxyMode;
+
+ if ((autoShow && !newWidget->testAttribute(Qt::WA_WState_ExplicitShowHide)) || !newWidget->testAttribute(Qt::WA_WState_Hidden)) {
+ newWidget->show();
+ }
+
+ // Copy the state from the widget onto the proxy.
+#ifndef QT_NO_CURSOR
+ if (newWidget->testAttribute(Qt::WA_SetCursor))
+ q->setCursor(widget->cursor());
+#endif
+ q->setEnabled(newWidget->isEnabled());
+ q->setVisible(newWidget->isVisible());
+ q->setLayoutDirection(newWidget->layoutDirection());
+ if (newWidget->testAttribute(Qt::WA_SetStyle))
+ q->setStyle(widget->style());
+
+ resolveFont(inheritedFontResolveMask);
+ resolvePalette(inheritedPaletteResolveMask);
+
+ if (!newWidget->testAttribute(Qt::WA_Resized))
+ newWidget->adjustSize();
+
+ int left, top, right, bottom;
+ newWidget->getContentsMargins(&left, &top, &right, &bottom);
+ q->setContentsMargins(left, top, right, bottom);
+ q->setWindowTitle(newWidget->windowTitle());
+
+ // size policies and constraints..
+ q->setSizePolicy(newWidget->sizePolicy());
+ QSize sz = newWidget->minimumSize();
+ q->setMinimumSize(sz.isNull() ? QSizeF() : QSizeF(sz));
+ sz = newWidget->maximumSize();
+ q->setMaximumSize(sz.isNull() ? QSizeF() : QSizeF(sz));
+
+ updateProxyGeometryFromWidget();
+
+ updateProxyInputMethodAcceptanceFromWidget();
+
+ // Hook up the event filter to keep the state up to date.
+ newWidget->installEventFilter(q);
+ QObject::connect(newWidget, SIGNAL(destroyed()), q, SLOT(_q_removeWidgetSlot()));
+
+ // Changes no longer go only from the widget to the proxy.
+ enabledChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
+ visibleChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
+ posChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
+ sizeChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
+}
+
+/*!
+ Returns a pointer to the embedded widget.
+
+ \sa setWidget()
+*/
+QWidget *QGraphicsProxyWidget::widget() const
+{
+ Q_D(const QGraphicsProxyWidget);
+ return d->widget;
+}
+
+/*!
+ Returns the rectangle for \a widget, which must be a descendant of
+ widget(), or widget() itself, in this proxy item's local coordinates.
+
+ If no widget is embedded, \a widget is 0, or \a widget is not a
+ descendant of the embedded widget, this function returns an empty QRectF.
+
+ \sa widget()
+*/
+QRectF QGraphicsProxyWidget::subWidgetRect(const QWidget *widget) const
+{
+ Q_D(const QGraphicsProxyWidget);
+ if (!widget || !d->widget)
+ return QRectF();
+ if (d->widget == widget || d->widget->isAncestorOf(widget))
+ return QRectF(widget->mapTo(d->widget, QPoint(0, 0)), widget->size());
+ return QRectF();
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsProxyWidget::setGeometry(const QRectF &rect)
+{
+ Q_D(QGraphicsProxyWidget);
+ bool proxyResizesWidget = !d->posChangeMode && !d->sizeChangeMode;
+ if (proxyResizesWidget) {
+ d->posChangeMode = QGraphicsProxyWidgetPrivate::ProxyToWidgetMode;
+ d->sizeChangeMode = QGraphicsProxyWidgetPrivate::ProxyToWidgetMode;
+ }
+ QGraphicsWidget::setGeometry(rect);
+ if (proxyResizesWidget) {
+ d->posChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
+ d->sizeChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
+ }
+}
+
+/*!
+ \reimp
+*/
+QVariant QGraphicsProxyWidget::itemChange(GraphicsItemChange change,
+ const QVariant &value)
+{
+ Q_D(QGraphicsProxyWidget);
+
+ switch (change) {
+ case ItemPositionChange:
+ // The item's position is either changed directly on the proxy, in
+ // which case the position change should propagate to the widget,
+ // otherwise it happens as a side effect when filtering QEvent::Move.
+ if (!d->posChangeMode)
+ d->posChangeMode = QGraphicsProxyWidgetPrivate::ProxyToWidgetMode;
+ break;
+ case ItemPositionHasChanged:
+ // Move the internal widget if we're in widget-to-proxy
+ // mode. Otherwise the widget has already moved.
+ if (d->widget && d->posChangeMode != QGraphicsProxyWidgetPrivate::WidgetToProxyMode)
+ d->widget->move(value.toPoint());
+ if (d->posChangeMode == QGraphicsProxyWidgetPrivate::ProxyToWidgetMode)
+ d->posChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
+ break;
+ case ItemVisibleChange:
+ if (!d->visibleChangeMode)
+ d->visibleChangeMode = QGraphicsProxyWidgetPrivate::ProxyToWidgetMode;
+ break;
+ case ItemVisibleHasChanged:
+ if (d->widget && d->visibleChangeMode != QGraphicsProxyWidgetPrivate::WidgetToProxyMode)
+ d->widget->setVisible(isVisible());
+ if (d->visibleChangeMode == QGraphicsProxyWidgetPrivate::ProxyToWidgetMode)
+ d->visibleChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
+ break;
+ case ItemEnabledChange:
+ if (!d->enabledChangeMode)
+ d->enabledChangeMode = QGraphicsProxyWidgetPrivate::ProxyToWidgetMode;
+ break;
+ case ItemEnabledHasChanged:
+ if (d->widget && d->enabledChangeMode != QGraphicsProxyWidgetPrivate::WidgetToProxyMode)
+ d->widget->setEnabled(isEnabled());
+ if (d->enabledChangeMode == QGraphicsProxyWidgetPrivate::ProxyToWidgetMode)
+ d->enabledChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
+ break;
+ default:
+ break;
+ }
+ return QGraphicsWidget::itemChange(change, value);
+}
+
+/*!
+ \reimp
+*/
+bool QGraphicsProxyWidget::event(QEvent *event)
+{
+ Q_D(QGraphicsProxyWidget);
+ if (!d->widget)
+ return QGraphicsWidget::event(event);
+
+ switch (event->type()) {
+ case QEvent::StyleChange:
+ // Propagate style changes to the embedded widget.
+ if (!d->styleChangeMode) {
+ d->styleChangeMode = QGraphicsProxyWidgetPrivate::ProxyToWidgetMode;
+ d->widget->setStyle(style());
+ d->styleChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
+ }
+ break;
+ case QEvent::FontChange: {
+ // Propagate to widget.
+ QWidgetPrivate *wd = d->widget->d_func();
+ int mask = d->font.resolve() | d->inheritedFontResolveMask;
+ wd->inheritedFontResolveMask = mask;
+ wd->resolveFont();
+ break;
+ }
+ case QEvent::PaletteChange: {
+ // Propagate to widget.
+ QWidgetPrivate *wd = d->widget->d_func();
+ int mask = d->palette.resolve() | d->inheritedPaletteResolveMask;
+ wd->inheritedPaletteResolveMask = mask;
+ wd->resolvePalette();
+ break;
+ }
+ case QEvent::InputMethod: {
+ // Forward input method events if the focus widget enables
+ // input methods.
+ // ### Qt 4.5: this code must also go into a reimplementation
+ // of inputMethodEvent().
+ QWidget *focusWidget = d->widget->focusWidget();
+ if (focusWidget && focusWidget->testAttribute(Qt::WA_InputMethodEnabled))
+ QApplication::sendEvent(focusWidget, event);
+ break;
+ }
+ case QEvent::ShortcutOverride: {
+ QWidget *focusWidget = d->widget->focusWidget();
+ while (focusWidget) {
+ QApplication::sendEvent(focusWidget, event);
+ if (event->isAccepted())
+ return true;
+ focusWidget = focusWidget->parentWidget();
+ }
+ return false;
+ }
+ case QEvent::KeyPress: {
+ QKeyEvent *k = static_cast<QKeyEvent *>(event);
+ if (k->key() == Qt::Key_Tab || k->key() == Qt::Key_Backtab) {
+ if (!(k->modifiers() & (Qt::ControlModifier | Qt::AltModifier))) { //### Add MetaModifier?
+ QWidget *focusWidget = d->widget->focusWidget();
+ while (focusWidget) {
+ bool res = QApplication::sendEvent(focusWidget, event);
+ if ((res && event->isAccepted()) || (isWindow() && focusWidget == d->widget)) {
+ event->accept();
+ break;
+ }
+ focusWidget = focusWidget->parentWidget();
+ }
+ return true;
+ }
+ }
+ break;
+ }
+#ifndef QT_NO_TOOLTIP
+ case QEvent::GraphicsSceneHelp: {
+ // Propagate the help event (for tooltip) to the widget under mouse
+ if (d->lastWidgetUnderMouse) {
+ QGraphicsSceneHelpEvent *he = static_cast<QGraphicsSceneHelpEvent *>(event);
+ QPoint pos = d->mapToReceiver(mapFromScene(he->scenePos()), d->lastWidgetUnderMouse).toPoint();
+ QHelpEvent e(QEvent::ToolTip, pos, he->screenPos());
+ QApplication::sendEvent(d->lastWidgetUnderMouse, &e);
+ event->setAccepted(e.isAccepted());
+ return e.isAccepted();
+ }
+ break;
+ }
+ case QEvent::ToolTipChange: {
+ // Propagate tooltip change to the widget
+ if (!d->tooltipChangeMode) {
+ d->tooltipChangeMode = QGraphicsProxyWidgetPrivate::ProxyToWidgetMode;
+ d->widget->setToolTip(toolTip());
+ d->tooltipChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
+ }
+ break;
+ }
+#endif
+ default:
+ break;
+ }
+ return QGraphicsWidget::event(event);
+}
+
+/*!
+ \reimp
+*/
+bool QGraphicsProxyWidget::eventFilter(QObject *object, QEvent *event)
+{
+ Q_D(QGraphicsProxyWidget);
+
+ if (object == d->widget) {
+ switch (event->type()) {
+ case QEvent::LayoutRequest:
+ updateGeometry();
+ break;
+ case QEvent::Resize:
+ // If the widget resizes itself, we resize the proxy too.
+ // Prevent feed-back by checking the geometry change mode.
+ if (!d->sizeChangeMode)
+ d->updateProxyGeometryFromWidget();
+ break;
+ case QEvent::Move:
+ // If the widget moves itself, we move the proxy too. Prevent
+ // feed-back by checking the geometry change mode.
+ if (!d->posChangeMode)
+ d->updateProxyGeometryFromWidget();
+ break;
+ case QEvent::Hide:
+ case QEvent::Show:
+ // If the widget toggles its visible state, the proxy will follow.
+ if (!d->visibleChangeMode) {
+ d->visibleChangeMode = QGraphicsProxyWidgetPrivate::WidgetToProxyMode;
+ setVisible(event->type() == QEvent::Show);
+ d->visibleChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
+ }
+ break;
+ case QEvent::EnabledChange:
+ // If the widget toggles its enabled state, the proxy will follow.
+ if (!d->enabledChangeMode) {
+ d->enabledChangeMode = QGraphicsProxyWidgetPrivate::WidgetToProxyMode;
+ setEnabled(d->widget->isEnabled());
+ d->enabledChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
+ }
+ break;
+ case QEvent::StyleChange:
+ // Propagate style changes to the proxy.
+ if (!d->styleChangeMode) {
+ d->styleChangeMode = QGraphicsProxyWidgetPrivate::WidgetToProxyMode;
+ setStyle(d->widget->style());
+ d->styleChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
+ }
+ break;
+#ifndef QT_NO_TOOLTIP
+ case QEvent::ToolTipChange:
+ // Propagate tooltip change to the proxy.
+ if (!d->tooltipChangeMode) {
+ d->tooltipChangeMode = QGraphicsProxyWidgetPrivate::WidgetToProxyMode;
+ setToolTip(d->widget->toolTip());
+ d->tooltipChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
+ }
+ break;
+#endif
+ default:
+ break;
+ }
+ }
+ return QGraphicsWidget::eventFilter(object, event);
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsProxyWidget::showEvent(QShowEvent *event)
+{
+ Q_UNUSED(event);
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsProxyWidget::hideEvent(QHideEvent *event)
+{
+ Q_UNUSED(event);
+}
+
+#ifndef QT_NO_CONTEXTMENU
+/*!
+ \reimp
+*/
+void QGraphicsProxyWidget::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
+{
+ Q_D(QGraphicsProxyWidget);
+ if (!event || !d->widget || !d->widget->isVisible() || !hasFocus())
+ return;
+
+ // Find widget position and receiver.
+ QPointF pos = event->pos();
+ QPointer<QWidget> alienWidget = d->widget->childAt(pos.toPoint());
+ QPointer<QWidget> receiver = alienWidget ? alienWidget : d->widget;
+
+ // Map event position from us to the receiver
+ pos = d->mapToReceiver(pos, receiver);
+
+ QPoint globalPos = receiver->mapToGlobal(pos.toPoint());
+ //If the receiver by-pass the proxy its popups
+ //will be top level QWidgets therefore they need
+ //the screen position. mapToGlobal expect the widget to
+ //have proper coordinates in regards of the windowing system
+ //but it's not true because the widget is embedded.
+ if (bypassGraphicsProxyWidget(receiver))
+ globalPos = event->screenPos();
+
+ // Send mouse event. ### Doesn't propagate the event.
+ QContextMenuEvent contextMenuEvent(QContextMenuEvent::Reason(event->reason()),
+ pos.toPoint(), globalPos, event->modifiers());
+ QApplication::sendEvent(receiver, &contextMenuEvent);
+
+ event->setAccepted(contextMenuEvent.isAccepted());
+}
+#endif // QT_NO_CONTEXTMENU
+
+#ifndef QT_NO_DRAGANDDROP
+/*!
+ \reimp
+*/
+void QGraphicsProxyWidget::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
+{
+#ifdef QT_NO_DRAGANDDROP
+ Q_UNUSED(event);
+#else
+ Q_D(QGraphicsProxyWidget);
+ if (!d->widget)
+ return;
+
+ QDragEnterEvent proxyDragEnter(event->pos().toPoint(), event->dropAction(), event->mimeData(), event->buttons(), event->modifiers());
+ proxyDragEnter.setAccepted(event->isAccepted());
+ QApplication::sendEvent(d->widget, &proxyDragEnter);
+ event->setAccepted(proxyDragEnter.isAccepted());
+ if (proxyDragEnter.isAccepted()) // we discard answerRect
+ event->setDropAction(proxyDragEnter.dropAction());
+#endif
+}
+/*!
+ \reimp
+*/
+void QGraphicsProxyWidget::dragLeaveEvent(QGraphicsSceneDragDropEvent *event)
+{
+ Q_UNUSED(event);
+#ifndef QT_NO_DRAGANDDROP
+ Q_D(QGraphicsProxyWidget);
+ if (!d->widget || !d->dragDropWidget)
+ return;
+ QDragLeaveEvent proxyDragLeave;
+ QApplication::sendEvent(d->dragDropWidget, &proxyDragLeave);
+ d->dragDropWidget = 0;
+#endif
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsProxyWidget::dragMoveEvent(QGraphicsSceneDragDropEvent *event)
+{
+#ifdef QT_NO_DRAGANDDROP
+ Q_UNUSED(event);
+#else
+ Q_D(QGraphicsProxyWidget);
+ if (!d->widget)
+ return;
+ QPointF p = event->pos();
+ event->ignore();
+ QPointer<QWidget> subWidget = d->widget->childAt(p.toPoint());
+ QPointer<QWidget> receiver = subWidget ? subWidget : d->widget;
+ bool eventDelivered = false;
+ for (; receiver; receiver = receiver->parentWidget()) {
+ if (!receiver->isEnabled() || !receiver->acceptDrops())
+ continue;
+ // Map event position from us to the receiver
+ QPoint receiverPos = d->mapToReceiver(p, receiver).toPoint();
+ 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());
+ QApplication::sendEvent(receiver, &dragEnter);
+ event->setAccepted(dragEnter.isAccepted());
+ event->setDropAction(dragEnter.dropAction());
+ if (!event->isAccepted()) {
+ // propagate to the parent widget
+ continue;
+ }
+
+ d->lastDropAction = event->dropAction();
+
+ if (d->dragDropWidget) {
+ QDragLeaveEvent dragLeave;
+ QApplication::sendEvent(d->dragDropWidget, &dragLeave);
+ }
+ d->dragDropWidget = receiver;
+ }
+
+ QDragMoveEvent dragMove(receiverPos, event->possibleActions(), event->mimeData(), event->buttons(), event->modifiers());
+ event->setDropAction(d->lastDropAction);
+ QApplication::sendEvent(receiver, &dragMove);
+ event->setAccepted(dragMove.isAccepted());
+ event->setDropAction(dragMove.dropAction());
+ if (event->isAccepted())
+ d->lastDropAction = event->dropAction();
+ eventDelivered = true;
+ break;
+ }
+
+ if (!eventDelivered) {
+ if (d->dragDropWidget) {
+ // Leave the last drag drop item
+ QDragLeaveEvent dragLeave;
+ QApplication::sendEvent(d->dragDropWidget, &dragLeave);
+ d->dragDropWidget = 0;
+ }
+ // Propagate
+ event->setDropAction(Qt::IgnoreAction);
+ }
+#endif
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsProxyWidget::dropEvent(QGraphicsSceneDragDropEvent *event)
+{
+#ifdef QT_NO_DRAGANDDROP
+ Q_UNUSED(event);
+#else
+ Q_D(QGraphicsProxyWidget);
+ if (d->widget && d->dragDropWidget) {
+ QPoint widgetPos = d->mapToReceiver(event->pos(), d->dragDropWidget).toPoint();
+ QDropEvent dropEvent(widgetPos, event->possibleActions(), event->mimeData(), event->buttons(), event->modifiers());
+ QApplication::sendEvent(d->dragDropWidget, &dropEvent);
+ event->setAccepted(dropEvent.isAccepted());
+ d->dragDropWidget = 0;
+ }
+#endif
+}
+#endif
+
+/*!
+ \reimp
+*/
+void QGraphicsProxyWidget::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
+{
+ Q_UNUSED(event);
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsProxyWidget::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
+{
+ Q_UNUSED(event);
+ Q_D(QGraphicsProxyWidget);
+ // If hoverMove was compressed away, make sure we update properly here.
+ if (d->lastWidgetUnderMouse) {
+ QApplicationPrivate::dispatchEnterLeave(0, d->lastWidgetUnderMouse);
+ d->lastWidgetUnderMouse = 0;
+ }
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsProxyWidget::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
+{
+ Q_D(QGraphicsProxyWidget);
+#ifdef GRAPHICSPROXYWIDGET_DEBUG
+ qDebug() << "QGraphicsProxyWidget::hoverMoveEvent";
+#endif
+ // Ignore events on the window frame.
+ if (!d->widget || !rect().contains(event->pos())) {
+ if (d->lastWidgetUnderMouse) {
+ QApplicationPrivate::dispatchEnterLeave(0, d->lastWidgetUnderMouse);
+ d->lastWidgetUnderMouse = 0;
+ }
+ return;
+ }
+
+ d->embeddedMouseGrabber = 0;
+ d->sendWidgetMouseEvent(event);
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsProxyWidget::grabMouseEvent(QEvent *event)
+{
+ Q_UNUSED(event);
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsProxyWidget::ungrabMouseEvent(QEvent *event)
+{
+ Q_D(QGraphicsProxyWidget);
+ Q_UNUSED(event);
+ d->embeddedMouseGrabber = 0;
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsProxyWidget::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
+{
+ Q_D(QGraphicsProxyWidget);
+#ifdef GRAPHICSPROXYWIDGET_DEBUG
+ qDebug() << "QGraphicsProxyWidget::mouseMoveEvent";
+#endif
+ d->sendWidgetMouseEvent(event);
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsProxyWidget::mousePressEvent(QGraphicsSceneMouseEvent *event)
+{
+ Q_D(QGraphicsProxyWidget);
+#ifdef GRAPHICSPROXYWIDGET_DEBUG
+ qDebug() << "QGraphicsProxyWidget::mousePressEvent";
+#endif
+ d->sendWidgetMouseEvent(event);
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsProxyWidget::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
+{
+ Q_D(QGraphicsProxyWidget);
+#ifdef GRAPHICSPROXYWIDGET_DEBUG
+ qDebug() << "QGraphicsProxyWidget::mouseDoubleClickEvent";
+#endif
+ d->sendWidgetMouseEvent(event);
+}
+
+/*!
+ \reimp
+*/
+#ifndef QT_NO_WHEELEVENT
+void QGraphicsProxyWidget::wheelEvent(QGraphicsSceneWheelEvent *event)
+{
+ Q_D(QGraphicsProxyWidget);
+#ifdef GRAPHICSPROXYWIDGET_DEBUG
+ qDebug() << "QGraphicsProxyWidget::wheelEvent";
+#endif
+ if (!d->widget)
+ return;
+
+ QPointF pos = event->pos();
+ QPointer<QWidget> receiver = d->widget->childAt(pos.toPoint());
+ if (!receiver)
+ receiver = d->widget;
+
+ // Map event position from us to the receiver
+ pos = d->mapToReceiver(pos, receiver);
+
+ // Send mouse event.
+ QWheelEvent wheelEvent(pos.toPoint(), event->screenPos(), event->delta(),
+ event->buttons(), event->modifiers(), event->orientation());
+ QPointer<QWidget> focusWidget = d->widget->focusWidget();
+ extern bool qt_sendSpontaneousEvent(QObject *, QEvent *);
+ qt_sendSpontaneousEvent(receiver, &wheelEvent);
+ event->setAccepted(wheelEvent.isAccepted());
+
+ // ### Remove, this should be done by proper focusIn/focusOut events.
+ if (focusWidget && !focusWidget->hasFocus()) {
+ focusWidget->update();
+ focusWidget = d->widget->focusWidget();
+ if (focusWidget && focusWidget->hasFocus())
+ focusWidget->update();
+ }
+}
+#endif
+
+/*!
+ \reimp
+*/
+void QGraphicsProxyWidget::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
+{
+ Q_D(QGraphicsProxyWidget);
+#ifdef GRAPHICSPROXYWIDGET_DEBUG
+ qDebug() << "QGraphicsProxyWidget::mouseReleaseEvent";
+#endif
+ d->sendWidgetMouseEvent(event);
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsProxyWidget::keyPressEvent(QKeyEvent *event)
+{
+ Q_D(QGraphicsProxyWidget);
+#ifdef GRAPHICSPROXYWIDGET_DEBUG
+ qDebug() << "QGraphicsProxyWidget::keyPressEvent";
+#endif
+ d->sendWidgetKeyEvent(event);
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsProxyWidget::keyReleaseEvent(QKeyEvent *event)
+{
+ Q_D(QGraphicsProxyWidget);
+#ifdef GRAPHICSPROXYWIDGET_DEBUG
+ qDebug() << "QGraphicsProxyWidget::keyReleaseEvent";
+#endif
+ d->sendWidgetKeyEvent(event);
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsProxyWidget::focusInEvent(QFocusEvent *event)
+{
+#ifdef GRAPHICSPROXYWIDGET_DEBUG
+ qDebug() << "QGraphicsProxyWidget::focusInEvent";
+#endif
+ Q_D(QGraphicsProxyWidget);
+
+ if (d->focusFromWidgetToProxy) {
+ // Prevent recursion when the proxy autogains focus through the
+ // embedded widget calling setFocus(). ### Could be done with event
+ // filter on FocusIn instead?
+ return;
+ }
+
+ d->proxyIsGivingFocus = true;
+
+ switch (event->reason()) {
+ case Qt::TabFocusReason: {
+ if (QWidget *focusChild = d->findFocusChild(0, true))
+ focusChild->setFocus(event->reason());
+ break;
+ }
+ case Qt::BacktabFocusReason:
+ if (QWidget *focusChild = d->findFocusChild(0, false))
+ focusChild->setFocus(event->reason());
+ break;
+ default:
+ if (d->widget && d->widget->focusWidget()) {
+ d->widget->focusWidget()->setFocus(event->reason());
+ }
+ break;
+ }
+
+ d->proxyIsGivingFocus = false;
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsProxyWidget::focusOutEvent(QFocusEvent *event)
+{
+#ifdef GRAPHICSPROXYWIDGET_DEBUG
+ qDebug() << "QGraphicsProxyWidget::focusOutEvent";
+#endif
+ Q_D(QGraphicsProxyWidget);
+ if (d->widget) {
+ // We need to explicitly remove subfocus from the embedded widget's
+ // focus widget.
+ if (QWidget *focusWidget = d->widget->focusWidget())
+ d->removeSubFocusHelper(focusWidget, event->reason());
+ }
+}
+
+/*!
+ \reimp
+*/
+bool QGraphicsProxyWidget::focusNextPrevChild(bool next)
+{
+ Q_D(QGraphicsProxyWidget);
+ if (!d->widget || !d->scene)
+ return QGraphicsWidget::focusNextPrevChild(next);
+
+ Qt::FocusReason reason = next ? Qt::TabFocusReason : Qt::BacktabFocusReason;
+ QWidget *lastFocusChild = d->widget->focusWidget();
+ if (QWidget *newFocusChild = d->findFocusChild(lastFocusChild, next)) {
+ newFocusChild->setFocus(reason);
+ return true;
+ }
+
+ return QGraphicsWidget::focusNextPrevChild(next);
+}
+
+/*!
+ \reimp
+*/
+QSizeF QGraphicsProxyWidget::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
+{
+ Q_D(const QGraphicsProxyWidget);
+ if (!d->widget)
+ return QGraphicsWidget::sizeHint(which, constraint);
+
+ QSizeF sh;
+ switch (which) {
+ case Qt::PreferredSize:
+ if (QLayout *l = d->widget->layout())
+ sh = l->sizeHint();
+ else
+ sh = d->widget->sizeHint();
+ break;
+ case Qt::MinimumSize:
+ if (QLayout *l = d->widget->layout())
+ sh = l->minimumSize();
+ else
+ sh = d->widget->minimumSizeHint();
+ break;
+ case Qt::MaximumSize:
+ if (QLayout *l = d->widget->layout())
+ sh = l->maximumSize();
+ else
+ sh = QSizeF(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
+ break;
+ case Qt::MinimumDescent:
+ sh = constraint;
+ break;
+ default:
+ break;
+ }
+ return sh;
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsProxyWidget::resizeEvent(QGraphicsSceneResizeEvent *event)
+{
+ Q_D(QGraphicsProxyWidget);
+ if (d->widget) {
+ if (d->sizeChangeMode != QGraphicsProxyWidgetPrivate::WidgetToProxyMode)
+ d->widget->resize(event->newSize().toSize());
+ }
+ QGraphicsWidget::resizeEvent(event);
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsProxyWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+ Q_D(QGraphicsProxyWidget);
+ Q_UNUSED(widget);
+ if (!d->widget || !d->widget->isVisible())
+ return;
+
+ // Filter out repaints on the window frame.
+ const QRect exposedWidgetRect = (option->exposedRect & rect()).toAlignedRect();
+ if (exposedWidgetRect.isEmpty())
+ return;
+
+ // Disable QPainter's default pen being cosmetic. This allows widgets and
+ // styles to follow Qt's existing defaults without getting ugly cosmetic
+ // lines when scaled.
+ bool restore = !(painter->renderHints() & QPainter::NonCosmeticDefaultPen);
+ painter->setRenderHints(QPainter::NonCosmeticDefaultPen, true);
+
+ d->widget->render(painter, exposedWidgetRect.topLeft(), exposedWidgetRect);
+
+ // Restore the render hints if necessary.
+ if (restore)
+ painter->setRenderHints(QPainter::NonCosmeticDefaultPen, false);
+}
+
+/*!
+ \reimp
+*/
+int QGraphicsProxyWidget::type() const
+{
+ return Type;
+}
+
+/*!
+ \since 4.5
+
+ Creates a proxy widget for the given \a child of the widget
+ contained in this proxy.
+
+ This function makes it possible to acquire proxies for
+ non top-level widgets. For instance, you can embed a dialog,
+ and then transform only one of its widgets.
+
+ If the widget is already embedded, return the existing proxy widget.
+
+ \sa newProxyWidget(), QGraphicsScene::addWidget()
+*/
+QGraphicsProxyWidget *QGraphicsProxyWidget::createProxyForChildWidget(QWidget *child)
+{
+ QGraphicsProxyWidget *proxy = child->graphicsProxyWidget();
+ if (proxy)
+ return proxy;
+ if (!child->parentWidget()) {
+ qWarning("QGraphicsProxyWidget::createProxyForChildWidget: top-level widget not in a QGraphicsScene");
+ return 0;
+ }
+
+ QGraphicsProxyWidget *parentProxy = createProxyForChildWidget(child->parentWidget());
+ if (!parentProxy)
+ return 0;
+
+ if (!QMetaObject::invokeMethod(parentProxy, "newProxyWidget", Qt::DirectConnection,
+ Q_RETURN_ARG(QGraphicsProxyWidget*, proxy), Q_ARG(const QWidget*, child)))
+ return 0;
+ proxy->setParent(parentProxy);
+ proxy->setWidget(child);
+ return proxy;
+}
+
+/*!
+ \fn QGraphicsProxyWidget *QGraphicsProxyWidget::newProxyWidget(const QWidget *child)
+ \since 4.5
+
+ Creates a proxy widget for the given \a child of the widget contained in this
+ proxy.
+
+ You should not call this function directly; use
+ QGraphicsProxyWidget::createProxyForChildWidget() instead.
+
+ This function is a fake virtual slot that you can reimplement in
+ your subclass in order to control how new proxy widgets are
+ created. The default implementation returns a proxy created with
+ the QGraphicsProxyWidget() constructor with this proxy widget as
+ the parent.
+
+ \sa createProxyForChildWidget()
+*/
+QGraphicsProxyWidget *QGraphicsProxyWidget::newProxyWidget(const QWidget *)
+{
+ return new QGraphicsProxyWidget(this);
+}
+
+
+
+QT_END_NAMESPACE
+
+#include "moc_qgraphicsproxywidget.cpp"
+
+#endif //QT_NO_GRAPHICSVIEW
diff --git a/src/widgets/graphicsview/qgraphicsproxywidget.h b/src/widgets/graphicsview/qgraphicsproxywidget.h
new file mode 100644
index 0000000000..9f0a711c46
--- /dev/null
+++ b/src/widgets/graphicsview/qgraphicsproxywidget.h
@@ -0,0 +1,147 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGRAPHICSPROXYWIDGET_H
+#define QGRAPHICSPROXYWIDGET_H
+
+#include <QtWidgets/qgraphicswidget.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW
+
+class QGraphicsProxyWidgetPrivate;
+
+class Q_WIDGETS_EXPORT QGraphicsProxyWidget : public QGraphicsWidget
+{
+ Q_OBJECT
+public:
+ QGraphicsProxyWidget(QGraphicsItem *parent = 0, Qt::WindowFlags wFlags = 0);
+ ~QGraphicsProxyWidget();
+
+ void setWidget(QWidget *widget);
+ QWidget *widget() const;
+
+ QRectF subWidgetRect(const QWidget *widget) const;
+
+ void setGeometry(const QRectF &rect);
+
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
+
+ enum {
+ Type = 12
+ };
+ int type() const;
+
+ QGraphicsProxyWidget *createProxyForChildWidget(QWidget *child);
+
+protected:
+ QVariant itemChange(GraphicsItemChange change, const QVariant &value);
+
+ bool event(QEvent *event);
+ bool eventFilter(QObject *object, QEvent *event);
+
+ void showEvent(QShowEvent *event);
+ void hideEvent(QHideEvent *event);
+
+#ifndef QT_NO_CONTEXTMENU
+ void contextMenuEvent(QGraphicsSceneContextMenuEvent *event);
+#endif
+
+#ifndef QT_NO_DRAGANDDROP
+ void dragEnterEvent(QGraphicsSceneDragDropEvent *event);
+ void dragLeaveEvent(QGraphicsSceneDragDropEvent *event);
+ void dragMoveEvent(QGraphicsSceneDragDropEvent *event);
+ void dropEvent(QGraphicsSceneDragDropEvent *event);
+#endif
+
+ void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
+ void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
+ void hoverMoveEvent(QGraphicsSceneHoverEvent *event);
+ void grabMouseEvent(QEvent *event);
+ void ungrabMouseEvent(QEvent *event);
+
+ void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
+ void mousePressEvent(QGraphicsSceneMouseEvent *event);
+ void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
+ void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event);
+#ifndef QT_NO_WHEELEVENT
+ void wheelEvent(QGraphicsSceneWheelEvent *event);
+#endif
+
+ void keyPressEvent(QKeyEvent *event);
+ void keyReleaseEvent(QKeyEvent *event);
+
+ void focusInEvent(QFocusEvent *event);
+ void focusOutEvent(QFocusEvent *event);
+ bool focusNextPrevChild(bool next);
+ // ### Qt 4.5:
+ // QVariant inputMethodQuery(Qt::InputMethodQuery query) const;
+ // void inputMethodEvent(QInputMethodEvent *event);
+
+ QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const;
+ void resizeEvent(QGraphicsSceneResizeEvent *event);
+
+protected Q_SLOTS:
+ QGraphicsProxyWidget *newProxyWidget(const QWidget *);
+
+private:
+ Q_DISABLE_COPY(QGraphicsProxyWidget)
+ Q_DECLARE_PRIVATE_D(QGraphicsItem::d_ptr.data(), QGraphicsProxyWidget)
+ Q_PRIVATE_SLOT(d_func(), void _q_removeWidgetSlot())
+
+ friend class QWidget;
+ friend class QWidgetPrivate;
+ friend class QGraphicsItem;
+};
+
+#endif
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
+
diff --git a/src/gui/graphicsview/qgraphicsproxywidget_p.h b/src/widgets/graphicsview/qgraphicsproxywidget_p.h
index 86aec5f86b..86aec5f86b 100644
--- a/src/gui/graphicsview/qgraphicsproxywidget_p.h
+++ b/src/widgets/graphicsview/qgraphicsproxywidget_p.h
diff --git a/src/widgets/graphicsview/qgraphicsscene.cpp b/src/widgets/graphicsview/qgraphicsscene.cpp
new file mode 100644
index 0000000000..165096637b
--- /dev/null
+++ b/src/widgets/graphicsview/qgraphicsscene.cpp
@@ -0,0 +1,6503 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \class QGraphicsScene
+ \brief The QGraphicsScene class provides a surface for managing a large
+ number of 2D graphical items.
+ \since 4.2
+ \ingroup graphicsview-api
+
+
+ The class serves as a container for QGraphicsItems. It is used together
+ with QGraphicsView for visualizing graphical items, such as lines,
+ rectangles, text, or even custom items, on a 2D surface. QGraphicsScene is
+ part of the \l{Graphics View Framework}.
+
+ QGraphicsScene also provides functionality that lets you efficiently
+ determine both the location of items, and for determining what items are
+ visible within an arbitrary area on the scene. With the QGraphicsView
+ widget, you can either visualize the whole scene, or zoom in and view only
+ parts of the scene.
+
+ Example:
+
+ \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsscene.cpp 0
+
+ Note that QGraphicsScene has no visual appearance of its own; it only
+ manages the items. You need to create a QGraphicsView widget to visualize
+ the scene.
+
+ To add items to a scene, you start off by constructing a QGraphicsScene
+ object. Then, you have two options: either add your existing QGraphicsItem
+ objects by calling addItem(), or you can call one of the convenience
+ functions addEllipse(), addLine(), addPath(), addPixmap(), addPolygon(),
+ addRect(), or addText(), which all return a pointer to the newly added item.
+ The dimensions of the items added with these functions are relative to the
+ item's coordinate system, and the items position is initialized to (0,
+ 0) in the scene.
+
+ You can then visualize the scene using QGraphicsView. When the scene
+ changes, (e.g., when an item moves or is transformed) QGraphicsScene
+ emits the changed() signal. To remove an item, call removeItem().
+
+ QGraphicsScene uses an indexing algorithm to manage the location of items
+ efficiently. By default, a BSP (Binary Space Partitioning) tree is used; an
+ algorithm suitable for large scenes where most items remain static (i.e.,
+ do not move around). You can choose to disable this index by calling
+ setItemIndexMethod(). For more information about the available indexing
+ algorithms, see the itemIndexMethod property.
+
+ The scene's bounding rect is set by calling setSceneRect(). Items can be
+ placed at any position on the scene, and the size of the scene is by
+ default unlimited. The scene rect is used only for internal bookkeeping,
+ maintaining the scene's item index. If the scene rect is unset,
+ QGraphicsScene will use the bounding area of all items, as returned by
+ itemsBoundingRect(), as the scene rect. However, itemsBoundingRect() is a
+ relatively time consuming function, as it operates by collecting
+ positional information for every item on the scene. Because of this, you
+ should always set the scene rect when operating on large scenes.
+
+ One of QGraphicsScene's greatest strengths is its ability to efficiently
+ determine the location of items. Even with millions of items on the scene,
+ the items() functions can determine the location of an item within few
+ milliseconds. There are several overloads to items(): one that finds items
+ at a certain position, one that finds items inside or intersecting with a
+ polygon or a rectangle, and more. The list of returned items is sorted by
+ stacking order, with the topmost item being the first item in the list.
+ For convenience, there is also an itemAt() function that returns the
+ topmost item at a given position.
+
+ QGraphicsScene maintains selection information for the scene. To select
+ items, call setSelectionArea(), and to clear the current selection, call
+ clearSelection(). Call selectedItems() to get the list of all selected
+ items.
+
+ \section1 Event Handling and Propagation
+
+ Another responsibility that QGraphicsScene has, is to propagate events
+ from QGraphicsView. To send an event to a scene, you construct an event
+ that inherits QEvent, and then send it using, for example,
+ QApplication::sendEvent(). event() is responsible for dispatching
+ the event to the individual items. Some common events are handled by
+ convenience event handlers. For example, key press events are handled by
+ keyPressEvent(), and mouse press events are handled by mousePressEvent().
+
+ Key events are delivered to the \e {focus item}. To set the focus item,
+ you can either call setFocusItem(), passing an item that accepts focus, or
+ the item itself can call QGraphicsItem::setFocus(). Call focusItem() to
+ get the current focus item. For compatibility with widgets, the scene also
+ maintains its own focus information. By default, the scene does not have
+ focus, and all key events are discarded. If setFocus() is called, or if an
+ item on the scene gains focus, the scene automatically gains focus. If the
+ scene has focus, hasFocus() will return true, and key events will be
+ forwarded to the focus item, if any. If the scene loses focus, (i.e.,
+ someone calls clearFocus()) while an item has focus, the scene will
+ maintain its item focus information, and once the scene regains focus, it
+ will make sure the last focus item regains focus.
+
+ For mouse-over effects, QGraphicsScene dispatches \e {hover
+ events}. If an item accepts hover events (see
+ QGraphicsItem::acceptHoverEvents()), it will receive a \l
+ {QEvent::}{GraphicsSceneHoverEnter} event when the mouse enters
+ its area. As the mouse continues moving inside the item's area,
+ QGraphicsScene will send it \l {QEvent::}{GraphicsSceneHoverMove}
+ events. When the mouse leaves the item's area, the item will
+ receive a \l {QEvent::}{GraphicsSceneHoverLeave} event.
+
+ All mouse events are delivered to the current \e {mouse grabber}
+ item. An item becomes the scene's mouse grabber if it accepts
+ mouse events (see QGraphicsItem::acceptedMouseButtons()) and it
+ receives a mouse press. It stays the mouse grabber until it
+ receives a mouse release when no other mouse buttons are
+ pressed. You can call mouseGrabberItem() to determine what item is
+ currently grabbing the mouse.
+
+ \sa QGraphicsItem, QGraphicsView
+*/
+
+/*!
+ \enum QGraphicsScene::SceneLayer
+ \since 4.3
+
+ This enum describes the rendering layers in a QGraphicsScene. When
+ QGraphicsScene draws the scene contents, it renders each of these layers
+ separately, in order.
+
+ Each layer represents a flag that can be OR'ed together when calling
+ functions such as invalidate() or QGraphicsView::invalidateScene().
+
+ \value ItemLayer The item layer. QGraphicsScene renders all items are in
+ this layer by calling the virtual function drawItems(). The item layer is
+ drawn after the background layer, but before the foreground layer.
+
+ \value BackgroundLayer The background layer. QGraphicsScene renders the
+ scene's background in this layer by calling the virtual function
+ drawBackground(). The background layer is drawn first of all layers.
+
+ \value ForegroundLayer The foreground layer. QGraphicsScene renders the
+ scene's foreground in this layer by calling the virtual function
+ drawForeground(). The foreground layer is drawn last of all layers.
+
+ \value AllLayers All layers; this value represents a combination of all
+ three layers.
+
+ \sa invalidate(), QGraphicsView::invalidateScene()
+*/
+
+/*!
+ \enum QGraphicsScene::ItemIndexMethod
+
+ This enum describes the indexing algorithms QGraphicsScene provides for
+ managing positional information about items on the scene.
+
+ \value BspTreeIndex A Binary Space Partitioning tree is applied. All
+ QGraphicsScene's item location algorithms are of an order close to
+ logarithmic complexity, by making use of binary search. Adding, moving and
+ removing items is logarithmic. This approach is best for static scenes
+ (i.e., scenes where most items do not move).
+
+ \value NoIndex No index is applied. Item location is of linear complexity,
+ as all items on the scene are searched. Adding, moving and removing items,
+ however, is done in constant time. This approach is ideal for dynamic
+ scenes, where many items are added, moved or removed continuously.
+
+ \sa setItemIndexMethod(), bspTreeDepth
+*/
+
+#include "qgraphicsscene.h"
+
+#ifndef QT_NO_GRAPHICSVIEW
+
+#include "qgraphicsitem.h"
+#include "qgraphicsitem_p.h"
+#include "qgraphicslayout.h"
+#include "qgraphicsscene_p.h"
+#include "qgraphicssceneevent.h"
+#include "qgraphicsview.h"
+#include "qgraphicsview_p.h"
+#include "qgraphicswidget.h"
+#include "qgraphicswidget_p.h"
+#include "qgraphicssceneindex_p.h"
+#include "qgraphicsscenebsptreeindex_p.h"
+#include "qgraphicsscenelinearindex_p.h"
+
+#include <QtCore/qdebug.h>
+#include <QtCore/qlist.h>
+#include <QtCore/qmath.h>
+#include <QtCore/qrect.h>
+#include <QtCore/qset.h>
+#include <QtCore/qstack.h>
+#include <QtCore/qtimer.h>
+#include <QtCore/qvarlengtharray.h>
+#include <QtCore/QMetaMethod>
+#include <QtWidgets/qapplication.h>
+#include <QtWidgets/qdesktopwidget.h>
+#include <QtGui/qevent.h>
+#include <QtWidgets/qgraphicslayout.h>
+#include <QtWidgets/qgraphicsproxywidget.h>
+#include <QtWidgets/qgraphicswidget.h>
+#include <QtGui/qmatrix.h>
+#include <QtGui/qpaintengine.h>
+#include <QtGui/qpainter.h>
+#include <QtGui/qpixmapcache.h>
+#include <QtGui/qpolygon.h>
+#include <QtWidgets/qstyleoption.h>
+#include <QtWidgets/qtooltip.h>
+#include <QtGui/qtransform.h>
+#include <QtWidgets/qinputcontext.h>
+#include <QtWidgets/qgraphicseffect.h>
+#ifndef QT_NO_ACCESSIBILITY
+# include <QtWidgets/qaccessible.h>
+#endif
+#include <private/qapplication_p.h>
+#include <private/qobject_p.h>
+#ifdef Q_WS_X11
+#include <private/qt_x11_p.h>
+#endif
+#include <private/qgraphicseffect_p.h>
+#include <private/qgesturemanager_p.h>
+#include <private/qpathclipper_p.h>
+
+// #define GESTURE_DEBUG
+#ifndef GESTURE_DEBUG
+# define DEBUG if (0) qDebug
+#else
+# define DEBUG qDebug
+#endif
+
+QT_BEGIN_NAMESPACE
+
+bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event);
+
+static void _q_hoverFromMouseEvent(QGraphicsSceneHoverEvent *hover, const QGraphicsSceneMouseEvent *mouseEvent)
+{
+ hover->setWidget(mouseEvent->widget());
+ hover->setPos(mouseEvent->pos());
+ hover->setScenePos(mouseEvent->scenePos());
+ hover->setScreenPos(mouseEvent->screenPos());
+ hover->setLastPos(mouseEvent->lastPos());
+ hover->setLastScenePos(mouseEvent->lastScenePos());
+ hover->setLastScreenPos(mouseEvent->lastScreenPos());
+ hover->setModifiers(mouseEvent->modifiers());
+ hover->setAccepted(mouseEvent->isAccepted());
+}
+
+/*!
+ \internal
+*/
+QGraphicsScenePrivate::QGraphicsScenePrivate()
+ : indexMethod(QGraphicsScene::BspTreeIndex),
+ index(0),
+ lastItemCount(0),
+ hasSceneRect(false),
+ dirtyGrowingItemsBoundingRect(true),
+ updateAll(false),
+ calledEmitUpdated(false),
+ processDirtyItemsEmitted(false),
+ needSortTopLevelItems(true),
+ holesInTopLevelSiblingIndex(false),
+ topLevelSequentialOrdering(true),
+ scenePosDescendantsUpdatePending(false),
+ stickyFocus(false),
+ hasFocus(false),
+ lastMouseGrabberItemHasImplicitMouseGrab(false),
+ allItemsIgnoreHoverEvents(true),
+ allItemsUseDefaultCursor(true),
+ painterStateProtection(true),
+ sortCacheEnabled(false),
+ allItemsIgnoreTouchEvents(true),
+ selectionChanging(0),
+ rectAdjust(2),
+ focusItem(0),
+ lastFocusItem(0),
+ passiveFocusItem(0),
+ tabFocusFirst(0),
+ activePanel(0),
+ lastActivePanel(0),
+ activationRefCount(0),
+ childExplicitActivation(0),
+ lastMouseGrabberItem(0),
+ dragDropItem(0),
+ enterWidget(0),
+ lastDropAction(Qt::IgnoreAction),
+ style(0)
+{
+}
+
+/*!
+ \internal
+*/
+void QGraphicsScenePrivate::init()
+{
+ Q_Q(QGraphicsScene);
+
+ index = new QGraphicsSceneBspTreeIndex(q);
+
+ // Keep this index so we can check for connected slots later on.
+ changedSignalIndex = signalIndex("changed(QList<QRectF>)");
+ processDirtyItemsIndex = q->metaObject()->indexOfSlot("_q_processDirtyItems()");
+ polishItemsIndex = q->metaObject()->indexOfSlot("_q_polishItems()");
+
+ qApp->d_func()->scene_list.append(q);
+ q->update();
+}
+
+/*!
+ \internal
+*/
+QGraphicsScenePrivate *QGraphicsScenePrivate::get(QGraphicsScene *q)
+{
+ return q->d_func();
+}
+
+void QGraphicsScenePrivate::_q_emitUpdated()
+{
+ Q_Q(QGraphicsScene);
+ calledEmitUpdated = false;
+
+ if (dirtyGrowingItemsBoundingRect) {
+ if (!hasSceneRect) {
+ const QRectF oldGrowingItemsBoundingRect = growingItemsBoundingRect;
+ growingItemsBoundingRect |= q->itemsBoundingRect();
+ if (oldGrowingItemsBoundingRect != growingItemsBoundingRect)
+ emit q->sceneRectChanged(growingItemsBoundingRect);
+ }
+ dirtyGrowingItemsBoundingRect = false;
+ }
+
+ // Ensure all views are connected if anything is connected. This disables
+ // the optimization that items send updates directly to the views, but it
+ // needs to happen in order to keep compatibility with the behavior from
+ // Qt 4.4 and backward.
+ if (isSignalConnected(changedSignalIndex)) {
+ for (int i = 0; i < views.size(); ++i) {
+ QGraphicsView *view = views.at(i);
+ if (!view->d_func()->connectedToScene) {
+ view->d_func()->connectedToScene = true;
+ q->connect(q, SIGNAL(changed(QList<QRectF>)),
+ views.at(i), SLOT(updateScene(QList<QRectF>)));
+ }
+ }
+ } else {
+ if (views.isEmpty()) {
+ updateAll = false;
+ return;
+ }
+ for (int i = 0; i < views.size(); ++i)
+ views.at(i)->d_func()->processPendingUpdates();
+ // It's important that we update all views before we dispatch, hence two for-loops.
+ for (int i = 0; i < views.size(); ++i)
+ views.at(i)->d_func()->dispatchPendingUpdateRequests();
+ return;
+ }
+
+ // Notify the changes to anybody interested.
+ QList<QRectF> oldUpdatedRects;
+ oldUpdatedRects = updateAll ? (QList<QRectF>() << q->sceneRect()) : updatedRects;
+ updateAll = false;
+ updatedRects.clear();
+ emit q->changed(oldUpdatedRects);
+}
+
+/*!
+ \internal
+
+ ### This function is almost identical to QGraphicsItemPrivate::addChild().
+*/
+void QGraphicsScenePrivate::registerTopLevelItem(QGraphicsItem *item)
+{
+ item->d_ptr->ensureSequentialSiblingIndex();
+ needSortTopLevelItems = true; // ### maybe false
+ item->d_ptr->siblingIndex = topLevelItems.size();
+ topLevelItems.append(item);
+}
+
+/*!
+ \internal
+
+ ### This function is almost identical to QGraphicsItemPrivate::removeChild().
+*/
+void QGraphicsScenePrivate::unregisterTopLevelItem(QGraphicsItem *item)
+{
+ if (!holesInTopLevelSiblingIndex)
+ holesInTopLevelSiblingIndex = item->d_ptr->siblingIndex != topLevelItems.size() - 1;
+ if (topLevelSequentialOrdering && !holesInTopLevelSiblingIndex)
+ topLevelItems.removeAt(item->d_ptr->siblingIndex);
+ else
+ topLevelItems.removeOne(item);
+ // NB! Do not use topLevelItems.removeAt(item->d_ptr->siblingIndex) because
+ // the item is not guaranteed to be at the index after the list is sorted
+ // (see ensureSortedTopLevelItems()).
+ item->d_ptr->siblingIndex = -1;
+ if (topLevelSequentialOrdering)
+ topLevelSequentialOrdering = !holesInTopLevelSiblingIndex;
+}
+
+/*!
+ \internal
+*/
+void QGraphicsScenePrivate::_q_polishItems()
+{
+ if (unpolishedItems.isEmpty())
+ return;
+
+ const QVariant booleanTrueVariant(true);
+ QGraphicsItem *item = 0;
+ QGraphicsItemPrivate *itemd = 0;
+ const int oldUnpolishedCount = unpolishedItems.count();
+
+ for (int i = 0; i < oldUnpolishedCount; ++i) {
+ item = unpolishedItems.at(i);
+ if (!item)
+ continue;
+ itemd = item->d_ptr.data();
+ itemd->pendingPolish = false;
+ if (!itemd->explicitlyHidden) {
+ item->itemChange(QGraphicsItem::ItemVisibleChange, booleanTrueVariant);
+ item->itemChange(QGraphicsItem::ItemVisibleHasChanged, booleanTrueVariant);
+ }
+ if (itemd->isWidget) {
+ QEvent event(QEvent::Polish);
+ QApplication::sendEvent((QGraphicsWidget *)item, &event);
+ }
+ }
+
+ if (unpolishedItems.count() == oldUnpolishedCount) {
+ // No new items were added to the vector.
+ unpolishedItems.clear();
+ } else {
+ // New items were appended; keep them and remove the old ones.
+ unpolishedItems.remove(0, oldUnpolishedCount);
+ unpolishedItems.squeeze();
+ QMetaObject::invokeMethod(q_ptr, "_q_polishItems", Qt::QueuedConnection);
+ }
+}
+
+void QGraphicsScenePrivate::_q_processDirtyItems()
+{
+ processDirtyItemsEmitted = false;
+
+ if (updateAll) {
+ Q_ASSERT(calledEmitUpdated);
+ // No need for further processing (except resetting the dirty states).
+ // The growingItemsBoundingRect is updated in _q_emitUpdated.
+ for (int i = 0; i < topLevelItems.size(); ++i)
+ resetDirtyItem(topLevelItems.at(i), /*recursive=*/true);
+ return;
+ }
+
+ const bool wasPendingSceneUpdate = calledEmitUpdated;
+ const QRectF oldGrowingItemsBoundingRect = growingItemsBoundingRect;
+
+ // Process items recursively.
+ for (int i = 0; i < topLevelItems.size(); ++i)
+ processDirtyItemsRecursive(topLevelItems.at(i));
+
+ dirtyGrowingItemsBoundingRect = false;
+ if (!hasSceneRect && oldGrowingItemsBoundingRect != growingItemsBoundingRect)
+ emit q_func()->sceneRectChanged(growingItemsBoundingRect);
+
+ if (wasPendingSceneUpdate)
+ return;
+
+ for (int i = 0; i < views.size(); ++i)
+ views.at(i)->d_func()->processPendingUpdates();
+
+ if (calledEmitUpdated) {
+ // We did a compatibility QGraphicsScene::update in processDirtyItemsRecursive
+ // and we cannot wait for the control to reach the eventloop before the
+ // changed signal is emitted, so we emit it now.
+ _q_emitUpdated();
+ }
+
+ // Immediately dispatch all pending update requests on the views.
+ for (int i = 0; i < views.size(); ++i)
+ views.at(i)->d_func()->dispatchPendingUpdateRequests();
+}
+
+/*!
+ \internal
+*/
+void QGraphicsScenePrivate::setScenePosItemEnabled(QGraphicsItem *item, bool enabled)
+{
+ QGraphicsItem *p = item->d_ptr->parent;
+ while (p) {
+ p->d_ptr->scenePosDescendants = enabled;
+ p = p->d_ptr->parent;
+ }
+ if (!enabled && !scenePosDescendantsUpdatePending) {
+ scenePosDescendantsUpdatePending = true;
+ QMetaObject::invokeMethod(q_func(), "_q_updateScenePosDescendants", Qt::QueuedConnection);
+ }
+}
+
+/*!
+ \internal
+*/
+void QGraphicsScenePrivate::registerScenePosItem(QGraphicsItem *item)
+{
+ scenePosItems.insert(item);
+ setScenePosItemEnabled(item, true);
+}
+
+/*!
+ \internal
+*/
+void QGraphicsScenePrivate::unregisterScenePosItem(QGraphicsItem *item)
+{
+ scenePosItems.remove(item);
+ setScenePosItemEnabled(item, false);
+}
+
+/*!
+ \internal
+*/
+void QGraphicsScenePrivate::_q_updateScenePosDescendants()
+{
+ foreach (QGraphicsItem *item, scenePosItems) {
+ QGraphicsItem *p = item->d_ptr->parent;
+ while (p) {
+ p->d_ptr->scenePosDescendants = 1;
+ p = p->d_ptr->parent;
+ }
+ }
+ scenePosDescendantsUpdatePending = false;
+}
+
+/*!
+ \internal
+
+ Schedules an item for removal. This function leaves some stale indexes
+ around in the BSP tree if called from the item's destructor; these will
+ be cleaned up the next time someone triggers purgeRemovedItems().
+
+ Note: This function might get called from QGraphicsItem's destructor. \a item is
+ being destroyed, so we cannot call any pure virtual functions on it (such
+ as boundingRect()). Also, it is unnecessary to update the item's own state
+ in any way.
+*/
+void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item)
+{
+ Q_Q(QGraphicsScene);
+
+ // Clear focus on the item to remove any reference in the focusWidget chain.
+ item->clearFocus();
+
+ markDirty(item, QRectF(), /*invalidateChildren=*/false, /*force=*/false,
+ /*ignoreOpacity=*/false, /*removingItemFromScene=*/true);
+
+ if (item->d_ptr->inDestructor) {
+ // The item is actually in its destructor, we call the special method in the index.
+ index->deleteItem(item);
+ } else {
+ // Can potentially call item->boundingRect() (virtual function), that's why
+ // we only can call this function if the item is not in its destructor.
+ index->removeItem(item);
+ }
+
+ item->d_ptr->clearSubFocus();
+
+ if (item->flags() & QGraphicsItem::ItemSendsScenePositionChanges)
+ unregisterScenePosItem(item);
+
+ QGraphicsScene *oldScene = item->d_func()->scene;
+ item->d_func()->scene = 0;
+
+ //We need to remove all children first because they might use their parent
+ //attributes (e.g. sceneTransform).
+ if (!item->d_ptr->inDestructor) {
+ // Remove all children recursively
+ for (int i = 0; i < item->d_ptr->children.size(); ++i)
+ q->removeItem(item->d_ptr->children.at(i));
+ }
+
+ if (!item->d_ptr->inDestructor && item == tabFocusFirst) {
+ QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(item);
+ widget->d_func()->fixFocusChainBeforeReparenting(0, oldScene, 0);
+ }
+
+ // Unregister focus proxy.
+ item->d_ptr->resetFocusProxy();
+
+ // Remove from parent, or unregister from toplevels.
+ if (QGraphicsItem *parentItem = item->parentItem()) {
+ if (parentItem->scene()) {
+ Q_ASSERT_X(parentItem->scene() == q, "QGraphicsScene::removeItem",
+ "Parent item's scene is different from this item's scene");
+ item->setParentItem(0);
+ }
+ } else {
+ unregisterTopLevelItem(item);
+ }
+
+ // Reset the mouse grabber and focus item data.
+ if (item == focusItem)
+ focusItem = 0;
+ if (item == lastFocusItem)
+ lastFocusItem = 0;
+ if (item == passiveFocusItem)
+ passiveFocusItem = 0;
+ if (item == activePanel) {
+ // ### deactivate...
+ activePanel = 0;
+ }
+ if (item == lastActivePanel)
+ lastActivePanel = 0;
+
+ // Cancel active touches
+ {
+ QMap<int, QGraphicsItem *>::iterator it = itemForTouchPointId.begin();
+ while (it != itemForTouchPointId.end()) {
+ if (it.value() == item) {
+ sceneCurrentTouchPoints.remove(it.key());
+ it = itemForTouchPointId.erase(it);
+ } else {
+ ++it;
+ }
+ }
+ }
+
+ // Disable selectionChanged() for individual items
+ ++selectionChanging;
+ int oldSelectedItemsSize = selectedItems.size();
+
+ // Update selected & hovered item bookkeeping
+ selectedItems.remove(item);
+ hoverItems.removeAll(item);
+ cachedItemsUnderMouse.removeAll(item);
+ if (item->d_ptr->pendingPolish) {
+ const int unpolishedIndex = unpolishedItems.indexOf(item);
+ if (unpolishedIndex != -1)
+ unpolishedItems[unpolishedIndex] = 0;
+ item->d_ptr->pendingPolish = false;
+ }
+ resetDirtyItem(item);
+
+ //We remove all references of item from the sceneEventFilter arrays
+ QMultiMap<QGraphicsItem*, QGraphicsItem*>::iterator iterator = sceneEventFilters.begin();
+ while (iterator != sceneEventFilters.end()) {
+ if (iterator.value() == item || iterator.key() == item)
+ iterator = sceneEventFilters.erase(iterator);
+ else
+ ++iterator;
+ }
+
+ if (item->isPanel() && item->isVisible() && item->panelModality() != QGraphicsItem::NonModal)
+ leaveModal(item);
+
+ // Reset the mouse grabber and focus item data.
+ if (mouseGrabberItems.contains(item))
+ ungrabMouse(item, /* item is dying */ item->d_ptr->inDestructor);
+
+ // Reset the keyboard grabber
+ if (keyboardGrabberItems.contains(item))
+ ungrabKeyboard(item, /* item is dying */ item->d_ptr->inDestructor);
+
+ // Reset the last mouse grabber item
+ if (item == lastMouseGrabberItem)
+ lastMouseGrabberItem = 0;
+
+ // Reset the current drop item
+ if (item == dragDropItem)
+ dragDropItem = 0;
+
+ // Reenable selectionChanged() for individual items
+ --selectionChanging;
+ if (!selectionChanging && selectedItems.size() != oldSelectedItemsSize)
+ emit q->selectionChanged();
+
+#ifndef QT_NO_GESTURES
+ QHash<QGesture *, QGraphicsObject *>::iterator it;
+ for (it = gestureTargets.begin(); it != gestureTargets.end();) {
+ if (it.value() == item)
+ it = gestureTargets.erase(it);
+ else
+ ++it;
+ }
+
+ QGraphicsObject *dummy = static_cast<QGraphicsObject *>(item);
+ cachedTargetItems.removeOne(dummy);
+ cachedItemGestures.remove(dummy);
+ cachedAlreadyDeliveredGestures.remove(dummy);
+
+ foreach (Qt::GestureType gesture, item->d_ptr->gestureContext.keys())
+ ungrabGesture(item, gesture);
+#endif // QT_NO_GESTURES
+}
+
+/*!
+ \internal
+*/
+void QGraphicsScenePrivate::setActivePanelHelper(QGraphicsItem *item, bool duringActivationEvent)
+{
+ Q_Q(QGraphicsScene);
+ if (item && item->scene() != q) {
+ qWarning("QGraphicsScene::setActivePanel: item %p must be part of this scene",
+ item);
+ return;
+ }
+
+ // Ensure the scene has focus when we change panel activation.
+ q->setFocus(Qt::ActiveWindowFocusReason);
+
+ // Find the item's panel.
+ QGraphicsItem *panel = item ? item->panel() : 0;
+ lastActivePanel = panel ? activePanel : 0;
+ if (panel == activePanel || (!q->isActive() && !duringActivationEvent))
+ return;
+
+ // Deactivate the last active panel.
+ if (activePanel) {
+ if (QGraphicsItem *fi = activePanel->focusItem()) {
+ // Remove focus from the current focus item.
+ if (fi == q->focusItem())
+ q->setFocusItem(0, Qt::ActiveWindowFocusReason);
+ }
+
+ QEvent event(QEvent::WindowDeactivate);
+ q->sendEvent(activePanel, &event);
+ } else if (panel && !duringActivationEvent) {
+ // Deactivate the scene if changing activation to a panel.
+ QEvent event(QEvent::WindowDeactivate);
+ foreach (QGraphicsItem *item, q->items()) {
+ if (item->isVisible() && !item->isPanel() && !item->parentItem())
+ q->sendEvent(item, &event);
+ }
+ }
+
+ // Update activate state.
+ activePanel = panel;
+ QEvent event(QEvent::ActivationChange);
+ QApplication::sendEvent(q, &event);
+
+ // Activate
+ if (panel) {
+ QEvent event(QEvent::WindowActivate);
+ q->sendEvent(panel, &event);
+
+ // Set focus on the panel's focus item.
+ if (QGraphicsItem *focusItem = panel->focusItem())
+ focusItem->setFocus(Qt::ActiveWindowFocusReason);
+ } else if (q->isActive()) {
+ // Activate the scene
+ QEvent event(QEvent::WindowActivate);
+ foreach (QGraphicsItem *item, q->items()) {
+ if (item->isVisible() && !item->isPanel() && !item->parentItem())
+ q->sendEvent(item, &event);
+ }
+ }
+}
+
+/*!
+ \internal
+*/
+void QGraphicsScenePrivate::setFocusItemHelper(QGraphicsItem *item,
+ Qt::FocusReason focusReason)
+{
+ Q_Q(QGraphicsScene);
+ if (item == focusItem)
+ return;
+
+ // Clear focus if asked to set focus on something that can't
+ // accept input focus.
+ if (item && (!(item->flags() & QGraphicsItem::ItemIsFocusable)
+ || !item->isVisible() || !item->isEnabled())) {
+ item = 0;
+ }
+
+ // Set focus on the scene if an item requests focus.
+ if (item) {
+ q->setFocus(focusReason);
+ if (item == focusItem)
+ return;
+ }
+
+ if (focusItem) {
+ lastFocusItem = focusItem;
+
+#ifndef QT_NO_IM
+ if (lastFocusItem
+ && (lastFocusItem->flags() & QGraphicsItem::ItemAcceptsInputMethod)) {
+ // Close any external input method panel. This happens
+ // automatically by removing WA_InputMethodEnabled on
+ // the views, but if we are changing focus, we have to
+ // do it ourselves.
+ for (int i = 0; i < views.size(); ++i)
+ if (views.at(i)->inputContext())
+ views.at(i)->inputContext()->reset();
+ }
+
+ focusItem = 0;
+ QFocusEvent event(QEvent::FocusOut, focusReason);
+ sendEvent(lastFocusItem, &event);
+#endif //QT_NO_IM
+ }
+
+ // This handles the case that the item has been removed from the
+ // scene in response to the FocusOut event.
+ if (item && item->scene() != q)
+ item = 0;
+
+ if (item)
+ focusItem = item;
+ updateInputMethodSensitivityInViews();
+
+#ifndef QT_NO_ACCESSIBILITY
+ if (focusItem) {
+ if (QGraphicsObject *focusObj = focusItem->toGraphicsObject()) {
+ QAccessible::updateAccessibility(focusObj, 0, QAccessible::Focus);
+ }
+ }
+#endif
+ if (item) {
+ QFocusEvent event(QEvent::FocusIn, focusReason);
+ sendEvent(item, &event);
+ }
+}
+
+/*!
+ \internal
+*/
+void QGraphicsScenePrivate::addPopup(QGraphicsWidget *widget)
+{
+ Q_ASSERT(widget);
+ Q_ASSERT(!popupWidgets.contains(widget));
+ popupWidgets << widget;
+ if (QGraphicsWidget *focusWidget = widget->focusWidget()) {
+ focusWidget->setFocus(Qt::PopupFocusReason);
+ } else {
+ grabKeyboard((QGraphicsItem *)widget);
+ if (focusItem && popupWidgets.size() == 1) {
+ QFocusEvent event(QEvent::FocusOut, Qt::PopupFocusReason);
+ sendEvent(focusItem, &event);
+ }
+ }
+ grabMouse((QGraphicsItem *)widget);
+}
+
+/*!
+ \internal
+
+ Remove \a widget from the popup list. Important notes:
+
+ \a widget is guaranteed to be in the list of popups, but it might not be
+ the last entry; you can hide any item in the pop list before the others,
+ and this must cause all later mouse grabbers to lose the grab.
+*/
+void QGraphicsScenePrivate::removePopup(QGraphicsWidget *widget, bool itemIsDying)
+{
+ Q_ASSERT(widget);
+ int index = popupWidgets.indexOf(widget);
+ Q_ASSERT(index != -1);
+
+ for (int i = popupWidgets.size() - 1; i >= index; --i) {
+ QGraphicsWidget *widget = popupWidgets.takeLast();
+ ungrabMouse(widget, itemIsDying);
+ if (focusItem && popupWidgets.isEmpty()) {
+ QFocusEvent event(QEvent::FocusIn, Qt::PopupFocusReason);
+ sendEvent(focusItem, &event);
+ } else if (keyboardGrabberItems.contains(static_cast<QGraphicsItem *>(widget))) {
+ ungrabKeyboard(static_cast<QGraphicsItem *>(widget), itemIsDying);
+ }
+ if (!itemIsDying && widget->isVisible()) {
+ widget->QGraphicsItem::d_ptr->setVisibleHelper(false, /* explicit = */ false);
+ }
+ }
+}
+
+/*!
+ \internal
+*/
+void QGraphicsScenePrivate::grabMouse(QGraphicsItem *item, bool implicit)
+{
+ // Append to list of mouse grabber items, and send a mouse grab event.
+ if (mouseGrabberItems.contains(item)) {
+ if (mouseGrabberItems.last() == item) {
+ Q_ASSERT(!implicit);
+ if (!lastMouseGrabberItemHasImplicitMouseGrab) {
+ qWarning("QGraphicsItem::grabMouse: already a mouse grabber");
+ } else {
+ // Upgrade to an explicit mouse grab
+ lastMouseGrabberItemHasImplicitMouseGrab = false;
+ }
+ } else {
+ qWarning("QGraphicsItem::grabMouse: already blocked by mouse grabber: %p",
+ mouseGrabberItems.last());
+ }
+ return;
+ }
+
+ // Send ungrab event to the last grabber.
+ if (!mouseGrabberItems.isEmpty()) {
+ QGraphicsItem *last = mouseGrabberItems.last();
+ if (lastMouseGrabberItemHasImplicitMouseGrab) {
+ // Implicit mouse grab is immediately lost.
+ last->ungrabMouse();
+ } else {
+ // Just send ungrab event to current grabber.
+ QEvent ungrabEvent(QEvent::UngrabMouse);
+ sendEvent(last, &ungrabEvent);
+ }
+ }
+
+ mouseGrabberItems << item;
+ lastMouseGrabberItemHasImplicitMouseGrab = implicit;
+
+ // Send grab event to current grabber.
+ QEvent grabEvent(QEvent::GrabMouse);
+ sendEvent(item, &grabEvent);
+}
+
+/*!
+ \internal
+*/
+void QGraphicsScenePrivate::ungrabMouse(QGraphicsItem *item, bool itemIsDying)
+{
+ int index = mouseGrabberItems.indexOf(item);
+ if (index == -1) {
+ qWarning("QGraphicsItem::ungrabMouse: not a mouse grabber");
+ return;
+ }
+
+ if (item != mouseGrabberItems.last()) {
+ // Recursively ungrab the next mouse grabber until we reach this item
+ // to ensure state consistency.
+ ungrabMouse(mouseGrabberItems.at(index + 1), itemIsDying);
+ }
+ if (!popupWidgets.isEmpty() && item == popupWidgets.last()) {
+ // If the item is a popup, go via removePopup to ensure state
+ // consistency and that it gets hidden correctly - beware that
+ // removePopup() reenters this function to continue removing the grab.
+ removePopup((QGraphicsWidget *)item, itemIsDying);
+ return;
+ }
+
+ // Send notification about mouse ungrab.
+ if (!itemIsDying) {
+ QEvent event(QEvent::UngrabMouse);
+ sendEvent(item, &event);
+ }
+
+ // Remove the item from the list of grabbers. Whenever this happens, we
+ // reset the implicitGrab (there can be only ever be one implicit grabber
+ // in a scene, and it is always the latest grabber; if the implicit grab
+ // is lost, it is not automatically regained.
+ mouseGrabberItems.takeLast();
+ lastMouseGrabberItemHasImplicitMouseGrab = false;
+
+ // Send notification about mouse regrab. ### It's unfortunate that all the
+ // items get a GrabMouse event, but this is a rare case with a simple
+ // implementation and it does ensure a consistent state.
+ if (!itemIsDying && !mouseGrabberItems.isEmpty()) {
+ QGraphicsItem *last = mouseGrabberItems.last();
+ QEvent event(QEvent::GrabMouse);
+ sendEvent(last, &event);
+ }
+}
+
+/*!
+ \internal
+*/
+void QGraphicsScenePrivate::clearMouseGrabber()
+{
+ if (!mouseGrabberItems.isEmpty())
+ mouseGrabberItems.first()->ungrabMouse();
+ lastMouseGrabberItem = 0;
+}
+
+/*!
+ \internal
+*/
+void QGraphicsScenePrivate::grabKeyboard(QGraphicsItem *item)
+{
+ if (keyboardGrabberItems.contains(item)) {
+ if (keyboardGrabberItems.last() == item)
+ qWarning("QGraphicsItem::grabKeyboard: already a keyboard grabber");
+ else
+ qWarning("QGraphicsItem::grabKeyboard: already blocked by keyboard grabber: %p",
+ keyboardGrabberItems.last());
+ return;
+ }
+
+ // Send ungrab event to the last grabber.
+ if (!keyboardGrabberItems.isEmpty()) {
+ // Just send ungrab event to current grabber.
+ QEvent ungrabEvent(QEvent::UngrabKeyboard);
+ sendEvent(keyboardGrabberItems.last(), &ungrabEvent);
+ }
+
+ keyboardGrabberItems << item;
+
+ // Send grab event to current grabber.
+ QEvent grabEvent(QEvent::GrabKeyboard);
+ sendEvent(item, &grabEvent);
+}
+
+/*!
+ \internal
+*/
+void QGraphicsScenePrivate::ungrabKeyboard(QGraphicsItem *item, bool itemIsDying)
+{
+ int index = keyboardGrabberItems.lastIndexOf(item);
+ if (index == -1) {
+ qWarning("QGraphicsItem::ungrabKeyboard: not a keyboard grabber");
+ return;
+ }
+ if (item != keyboardGrabberItems.last()) {
+ // Recursively ungrab the topmost keyboard grabber until we reach this
+ // item to ensure state consistency.
+ ungrabKeyboard(keyboardGrabberItems.at(index + 1), itemIsDying);
+ }
+
+ // Send notification about keyboard ungrab.
+ if (!itemIsDying) {
+ QEvent event(QEvent::UngrabKeyboard);
+ sendEvent(item, &event);
+ }
+
+ // Remove the item from the list of grabbers.
+ keyboardGrabberItems.takeLast();
+
+ // Send notification about mouse regrab.
+ if (!itemIsDying && !keyboardGrabberItems.isEmpty()) {
+ QGraphicsItem *last = keyboardGrabberItems.last();
+ QEvent event(QEvent::GrabKeyboard);
+ sendEvent(last, &event);
+ }
+}
+
+/*!
+ \internal
+*/
+void QGraphicsScenePrivate::clearKeyboardGrabber()
+{
+ if (!keyboardGrabberItems.isEmpty())
+ ungrabKeyboard(keyboardGrabberItems.first());
+}
+
+void QGraphicsScenePrivate::enableMouseTrackingOnViews()
+{
+ foreach (QGraphicsView *view, views)
+ view->viewport()->setMouseTracking(true);
+}
+
+/*!
+ Returns all items for the screen position in \a event.
+*/
+QList<QGraphicsItem *> QGraphicsScenePrivate::itemsAtPosition(const QPoint &/*screenPos*/,
+ const QPointF &scenePos,
+ QWidget *widget) const
+{
+ Q_Q(const QGraphicsScene);
+ QGraphicsView *view = widget ? qobject_cast<QGraphicsView *>(widget->parentWidget()) : 0;
+ if (!view)
+ return q->items(scenePos, Qt::IntersectsItemShape, Qt::DescendingOrder, QTransform());
+
+ const QRectF pointRect(scenePos, QSizeF(1, 1));
+ if (!view->isTransformed())
+ return q->items(pointRect, Qt::IntersectsItemShape, Qt::DescendingOrder);
+
+ const QTransform viewTransform = view->viewportTransform();
+ return q->items(pointRect, Qt::IntersectsItemShape,
+ Qt::DescendingOrder, viewTransform);
+}
+
+/*!
+ \internal
+*/
+void QGraphicsScenePrivate::storeMouseButtonsForMouseGrabber(QGraphicsSceneMouseEvent *event)
+{
+ for (int i = 0x1; i <= 0x10; i <<= 1) {
+ if (event->buttons() & i) {
+ mouseGrabberButtonDownPos.insert(Qt::MouseButton(i),
+ mouseGrabberItems.last()->d_ptr->genericMapFromScene(event->scenePos(),
+ event->widget()));
+ mouseGrabberButtonDownScenePos.insert(Qt::MouseButton(i), event->scenePos());
+ mouseGrabberButtonDownScreenPos.insert(Qt::MouseButton(i), event->screenPos());
+ }
+ }
+}
+
+/*!
+ \internal
+*/
+void QGraphicsScenePrivate::installSceneEventFilter(QGraphicsItem *watched, QGraphicsItem *filter)
+{
+ sceneEventFilters.insert(watched, filter);
+}
+
+/*!
+ \internal
+*/
+void QGraphicsScenePrivate::removeSceneEventFilter(QGraphicsItem *watched, QGraphicsItem *filter)
+{
+ if (!sceneEventFilters.contains(watched))
+ return;
+
+ QMultiMap<QGraphicsItem *, QGraphicsItem *>::Iterator it = sceneEventFilters.lowerBound(watched);
+ QMultiMap<QGraphicsItem *, QGraphicsItem *>::Iterator end = sceneEventFilters.upperBound(watched);
+ do {
+ if (it.value() == filter)
+ it = sceneEventFilters.erase(it);
+ else
+ ++it;
+ } while (it != end);
+}
+
+/*!
+ \internal
+*/
+bool QGraphicsScenePrivate::filterDescendantEvent(QGraphicsItem *item, QEvent *event)
+{
+ if (item && (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorFiltersChildEvents)) {
+ QGraphicsItem *parent = item->parentItem();
+ while (parent) {
+ if (parent->d_ptr->filtersDescendantEvents && parent->sceneEventFilter(item, event))
+ return true;
+ if (!(parent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorFiltersChildEvents))
+ return false;
+ parent = parent->parentItem();
+ }
+ }
+ return false;
+}
+
+/*!
+ \internal
+*/
+bool QGraphicsScenePrivate::filterEvent(QGraphicsItem *item, QEvent *event)
+{
+ if (item && !sceneEventFilters.contains(item))
+ return false;
+
+ QMultiMap<QGraphicsItem *, QGraphicsItem *>::Iterator it = sceneEventFilters.lowerBound(item);
+ QMultiMap<QGraphicsItem *, QGraphicsItem *>::Iterator end = sceneEventFilters.upperBound(item);
+ while (it != end) {
+ // ### The filterer and filteree might both be deleted.
+ if (it.value()->sceneEventFilter(it.key(), event))
+ return true;
+ ++it;
+ }
+ return false;
+}
+
+/*!
+ \internal
+
+ This is the final dispatch point for any events from the scene to the
+ item. It filters the event first - if the filter returns true, the event
+ is considered to have been eaten by the filter, and is therefore stopped
+ (the default filter returns false). Then/otherwise, if the item is
+ enabled, the event is sent; otherwise it is stopped.
+*/
+bool QGraphicsScenePrivate::sendEvent(QGraphicsItem *item, QEvent *event)
+{
+ if (QGraphicsObject *object = item->toGraphicsObject()) {
+#ifndef QT_NO_GESTURES
+ QGestureManager *gestureManager = QApplicationPrivate::instance()->gestureManager;
+ if (gestureManager) {
+ if (gestureManager->filterEvent(object, event))
+ return true;
+ }
+#endif // QT_NO_GESTURES
+ }
+
+ if (filterEvent(item, event))
+ return false;
+ if (filterDescendantEvent(item, event))
+ return false;
+ if (!item || !item->isEnabled())
+ return false;
+ if (QGraphicsObject *o = item->toGraphicsObject()) {
+ bool spont = event->spontaneous();
+ if (spont ? qt_sendSpontaneousEvent(o, event) : QApplication::sendEvent(o, event))
+ return true;
+ event->spont = spont;
+ }
+ return item->sceneEvent(event);
+}
+
+/*!
+ \internal
+*/
+void QGraphicsScenePrivate::cloneDragDropEvent(QGraphicsSceneDragDropEvent *dest,
+ QGraphicsSceneDragDropEvent *source)
+{
+ dest->setWidget(source->widget());
+ dest->setPos(source->pos());
+ dest->setScenePos(source->scenePos());
+ dest->setScreenPos(source->screenPos());
+ dest->setButtons(source->buttons());
+ dest->setModifiers(source->modifiers());
+ dest->setPossibleActions(source->possibleActions());
+ dest->setProposedAction(source->proposedAction());
+ dest->setDropAction(source->dropAction());
+ dest->setSource(source->source());
+ dest->setMimeData(source->mimeData());
+}
+
+/*!
+ \internal
+*/
+void QGraphicsScenePrivate::sendDragDropEvent(QGraphicsItem *item,
+ QGraphicsSceneDragDropEvent *dragDropEvent)
+{
+ dragDropEvent->setPos(item->d_ptr->genericMapFromScene(dragDropEvent->scenePos(), dragDropEvent->widget()));
+ sendEvent(item, dragDropEvent);
+}
+
+/*!
+ \internal
+*/
+void QGraphicsScenePrivate::sendHoverEvent(QEvent::Type type, QGraphicsItem *item,
+ QGraphicsSceneHoverEvent *hoverEvent)
+{
+ QGraphicsSceneHoverEvent event(type);
+ event.setWidget(hoverEvent->widget());
+ event.setPos(item->d_ptr->genericMapFromScene(hoverEvent->scenePos(), hoverEvent->widget()));
+ event.setScenePos(hoverEvent->scenePos());
+ event.setScreenPos(hoverEvent->screenPos());
+ event.setLastPos(item->d_ptr->genericMapFromScene(hoverEvent->lastScenePos(), hoverEvent->widget()));
+ event.setLastScenePos(hoverEvent->lastScenePos());
+ event.setLastScreenPos(hoverEvent->lastScreenPos());
+ event.setModifiers(hoverEvent->modifiers());
+ sendEvent(item, &event);
+}
+
+/*!
+ \internal
+*/
+void QGraphicsScenePrivate::sendMouseEvent(QGraphicsSceneMouseEvent *mouseEvent)
+{
+ if (mouseEvent->button() == 0 && mouseEvent->buttons() == 0 && lastMouseGrabberItemHasImplicitMouseGrab) {
+ // ### This is a temporary fix for until we get proper mouse
+ // grab events.
+ clearMouseGrabber();
+ return;
+ }
+
+ QGraphicsItem *item = mouseGrabberItems.last();
+ if (item->isBlockedByModalPanel())
+ return;
+
+ for (int i = 0x1; i <= 0x10; i <<= 1) {
+ Qt::MouseButton button = Qt::MouseButton(i);
+ mouseEvent->setButtonDownPos(button, mouseGrabberButtonDownPos.value(button, item->d_ptr->genericMapFromScene(mouseEvent->scenePos(), mouseEvent->widget())));
+ mouseEvent->setButtonDownScenePos(button, mouseGrabberButtonDownScenePos.value(button, mouseEvent->scenePos()));
+ mouseEvent->setButtonDownScreenPos(button, mouseGrabberButtonDownScreenPos.value(button, mouseEvent->screenPos()));
+ }
+ mouseEvent->setPos(item->d_ptr->genericMapFromScene(mouseEvent->scenePos(), mouseEvent->widget()));
+ mouseEvent->setLastPos(item->d_ptr->genericMapFromScene(mouseEvent->lastScenePos(), mouseEvent->widget()));
+ sendEvent(item, mouseEvent);
+}
+
+/*!
+ \internal
+*/
+void QGraphicsScenePrivate::mousePressEventHandler(QGraphicsSceneMouseEvent *mouseEvent)
+{
+ Q_Q(QGraphicsScene);
+
+ // Ignore by default, unless we find a mouse grabber that accepts it.
+ mouseEvent->ignore();
+
+ // Deliver to any existing mouse grabber.
+ if (!mouseGrabberItems.isEmpty()) {
+ if (mouseGrabberItems.last()->isBlockedByModalPanel())
+ return;
+ // The event is ignored by default, but we disregard the event's
+ // accepted state after delivery; the mouse is grabbed, after all.
+ sendMouseEvent(mouseEvent);
+ return;
+ }
+
+ // Start by determining the number of items at the current position.
+ // Reuse value from earlier calculations if possible.
+ if (cachedItemsUnderMouse.isEmpty()) {
+ cachedItemsUnderMouse = itemsAtPosition(mouseEvent->screenPos(),
+ mouseEvent->scenePos(),
+ mouseEvent->widget());
+ }
+
+ // Update window activation.
+ QGraphicsItem *topItem = cachedItemsUnderMouse.value(0);
+ QGraphicsWidget *newActiveWindow = topItem ? topItem->window() : 0;
+ if (newActiveWindow && newActiveWindow->isBlockedByModalPanel(&topItem)) {
+ // pass activation to the blocking modal window
+ newActiveWindow = topItem ? topItem->window() : 0;
+ }
+
+ if (newActiveWindow != q->activeWindow())
+ q->setActiveWindow(newActiveWindow);
+
+ // Set focus on the topmost enabled item that can take focus.
+ bool setFocus = false;
+
+ foreach (QGraphicsItem *item, cachedItemsUnderMouse) {
+ if (item->isBlockedByModalPanel()
+ || (item->d_ptr->flags & QGraphicsItem::ItemStopsFocusHandling)) {
+ // Make sure we don't clear focus.
+ setFocus = true;
+ break;
+ }
+ if (item->isEnabled() && ((item->flags() & QGraphicsItem::ItemIsFocusable))) {
+ if (!item->isWidget() || ((QGraphicsWidget *)item)->focusPolicy() & Qt::ClickFocus) {
+ setFocus = true;
+ if (item != q->focusItem() && item->d_ptr->mouseSetsFocus)
+ q->setFocusItem(item, Qt::MouseFocusReason);
+ break;
+ }
+ }
+ if (item->isPanel())
+ break;
+ if (item->d_ptr->flags & QGraphicsItem::ItemStopsClickFocusPropagation)
+ break;
+ }
+
+ // Check for scene modality.
+ bool sceneModality = false;
+ for (int i = 0; i < modalPanels.size(); ++i) {
+ if (modalPanels.at(i)->panelModality() == QGraphicsItem::SceneModal) {
+ sceneModality = true;
+ break;
+ }
+ }
+
+ // If nobody could take focus, clear it.
+ if (!stickyFocus && !setFocus && !sceneModality)
+ q->setFocusItem(0, Qt::MouseFocusReason);
+
+ // Any item will do.
+ if (sceneModality && cachedItemsUnderMouse.isEmpty())
+ cachedItemsUnderMouse << modalPanels.first();
+
+ // Find a mouse grabber by sending mouse press events to all mouse grabber
+ // candidates one at a time, until the event is accepted. It's accepted by
+ // default, so the receiver has to explicitly ignore it for it to pass
+ // through.
+ foreach (QGraphicsItem *item, cachedItemsUnderMouse) {
+ if (!(item->acceptedMouseButtons() & mouseEvent->button())) {
+ // Skip items that don't accept the event's mouse button.
+ continue;
+ }
+
+ // Check if this item is blocked by a modal panel and deliver the mouse event to the
+ // blocking panel instead of this item if blocked.
+ (void) item->isBlockedByModalPanel(&item);
+
+ grabMouse(item, /* implicit = */ true);
+ mouseEvent->accept();
+
+ // check if the item we are sending to are disabled (before we send the event)
+ bool disabled = !item->isEnabled();
+ bool isPanel = item->isPanel();
+ if (mouseEvent->type() == QEvent::GraphicsSceneMouseDoubleClick
+ && item != lastMouseGrabberItem && lastMouseGrabberItem) {
+ // If this item is different from the item that received the last
+ // mouse event, and mouseEvent is a doubleclick event, then the
+ // event is converted to a press. Known limitation:
+ // Triple-clicking will not generate a doubleclick, though.
+ QGraphicsSceneMouseEvent mousePress(QEvent::GraphicsSceneMousePress);
+ mousePress.spont = mouseEvent->spont;
+ mousePress.accept();
+ mousePress.setButton(mouseEvent->button());
+ mousePress.setButtons(mouseEvent->buttons());
+ mousePress.setScreenPos(mouseEvent->screenPos());
+ mousePress.setScenePos(mouseEvent->scenePos());
+ mousePress.setModifiers(mouseEvent->modifiers());
+ mousePress.setWidget(mouseEvent->widget());
+ mousePress.setButtonDownPos(mouseEvent->button(),
+ mouseEvent->buttonDownPos(mouseEvent->button()));
+ mousePress.setButtonDownScenePos(mouseEvent->button(),
+ mouseEvent->buttonDownScenePos(mouseEvent->button()));
+ mousePress.setButtonDownScreenPos(mouseEvent->button(),
+ mouseEvent->buttonDownScreenPos(mouseEvent->button()));
+ sendMouseEvent(&mousePress);
+ mouseEvent->setAccepted(mousePress.isAccepted());
+ } else {
+ sendMouseEvent(mouseEvent);
+ }
+
+ bool dontSendUngrabEvents = mouseGrabberItems.isEmpty() || mouseGrabberItems.last() != item;
+ if (disabled) {
+ ungrabMouse(item, /* itemIsDying = */ dontSendUngrabEvents);
+ break;
+ }
+ if (mouseEvent->isAccepted()) {
+ if (!mouseGrabberItems.isEmpty())
+ storeMouseButtonsForMouseGrabber(mouseEvent);
+ lastMouseGrabberItem = item;
+ return;
+ }
+ ungrabMouse(item, /* itemIsDying = */ dontSendUngrabEvents);
+
+ // Don't propagate through panels.
+ if (isPanel)
+ break;
+ }
+
+ // Is the event still ignored? Then the mouse press goes to the scene.
+ // Reset the mouse grabber, clear the selection, clear focus, and leave
+ // the event ignored so that it can propagate through the originating
+ // view.
+ if (!mouseEvent->isAccepted()) {
+ clearMouseGrabber();
+
+ QGraphicsView *view = mouseEvent->widget() ? qobject_cast<QGraphicsView *>(mouseEvent->widget()->parentWidget()) : 0;
+ bool dontClearSelection = view && view->dragMode() == QGraphicsView::ScrollHandDrag;
+ if (!dontClearSelection) {
+ // Clear the selection if the originating view isn't in scroll
+ // hand drag mode. The view will clear the selection if no drag
+ // happened.
+ q->clearSelection();
+ }
+ }
+}
+
+/*!
+ \internal
+
+ Ensures that the list of toplevels is sorted by insertion order, and that
+ the siblingIndexes are packed (no gaps), and start at 0.
+
+ ### This function is almost identical to
+ QGraphicsItemPrivate::ensureSequentialSiblingIndex().
+*/
+void QGraphicsScenePrivate::ensureSequentialTopLevelSiblingIndexes()
+{
+ if (!topLevelSequentialOrdering) {
+ qSort(topLevelItems.begin(), topLevelItems.end(), QGraphicsItemPrivate::insertionOrder);
+ topLevelSequentialOrdering = true;
+ needSortTopLevelItems = 1;
+ }
+ if (holesInTopLevelSiblingIndex) {
+ holesInTopLevelSiblingIndex = 0;
+ for (int i = 0; i < topLevelItems.size(); ++i)
+ topLevelItems[i]->d_ptr->siblingIndex = i;
+ }
+}
+
+/*!
+ \internal
+
+ Set the font and propagate the changes if the font is different from the
+ current font.
+*/
+void QGraphicsScenePrivate::setFont_helper(const QFont &font)
+{
+ if (this->font == font && this->font.resolve() == font.resolve())
+ return;
+ updateFont(font);
+}
+
+/*!
+ \internal
+
+ Resolve the scene's font against the application font, and propagate the
+ changes too all items in the scene.
+*/
+void QGraphicsScenePrivate::resolveFont()
+{
+ QFont naturalFont = QApplication::font();
+ naturalFont.resolve(0);
+ QFont resolvedFont = font.resolve(naturalFont);
+ updateFont(resolvedFont);
+}
+
+/*!
+ \internal
+
+ Update the font, and whether or not it has changed, reresolve all fonts in
+ the scene.
+*/
+void QGraphicsScenePrivate::updateFont(const QFont &font)
+{
+ Q_Q(QGraphicsScene);
+
+ // Update local font setting.
+ this->font = font;
+
+ // Resolve the fonts of all top-level widget items, or widget items
+ // whose parent is not a widget.
+ foreach (QGraphicsItem *item, q->items()) {
+ if (!item->parentItem()) {
+ // Resolvefont for an item is a noop operation, but
+ // every item can be a widget, or can have a widget
+ // childre.
+ item->d_ptr->resolveFont(font.resolve());
+ }
+ }
+
+ // Send the scene a FontChange event.
+ QEvent event(QEvent::FontChange);
+ QApplication::sendEvent(q, &event);
+}
+
+/*!
+ \internal
+
+ Set the palette and propagate the changes if the palette is different from
+ the current palette.
+*/
+void QGraphicsScenePrivate::setPalette_helper(const QPalette &palette)
+{
+ if (this->palette == palette && this->palette.resolve() == palette.resolve())
+ return;
+ updatePalette(palette);
+}
+
+/*!
+ \internal
+
+ Resolve the scene's palette against the application palette, and propagate
+ the changes too all items in the scene.
+*/
+void QGraphicsScenePrivate::resolvePalette()
+{
+ QPalette naturalPalette = QApplication::palette();
+ naturalPalette.resolve(0);
+ QPalette resolvedPalette = palette.resolve(naturalPalette);
+ updatePalette(resolvedPalette);
+}
+
+/*!
+ \internal
+
+ Update the palette, and whether or not it has changed, reresolve all
+ palettes in the scene.
+*/
+void QGraphicsScenePrivate::updatePalette(const QPalette &palette)
+{
+ Q_Q(QGraphicsScene);
+
+ // Update local palette setting.
+ this->palette = palette;
+
+ // Resolve the palettes of all top-level widget items, or widget items
+ // whose parent is not a widget.
+ foreach (QGraphicsItem *item, q->items()) {
+ if (!item->parentItem()) {
+ // Resolvefont for an item is a noop operation, but
+ // every item can be a widget, or can have a widget
+ // childre.
+ item->d_ptr->resolvePalette(palette.resolve());
+ }
+ }
+
+ // Send the scene a PaletteChange event.
+ QEvent event(QEvent::PaletteChange);
+ QApplication::sendEvent(q, &event);
+}
+
+/*!
+ Constructs a QGraphicsScene object. The \a parent parameter is
+ passed to QObject's constructor.
+*/
+QGraphicsScene::QGraphicsScene(QObject *parent)
+ : QObject(*new QGraphicsScenePrivate, parent)
+{
+ d_func()->init();
+}
+
+/*!
+ Constructs a QGraphicsScene object, using \a sceneRect for its
+ scene rectangle. The \a parent parameter is passed to QObject's
+ constructor.
+
+ \sa sceneRect
+*/
+QGraphicsScene::QGraphicsScene(const QRectF &sceneRect, QObject *parent)
+ : QObject(*new QGraphicsScenePrivate, parent)
+{
+ d_func()->init();
+ setSceneRect(sceneRect);
+}
+
+/*!
+ Constructs a QGraphicsScene object, using the rectangle specified
+ by (\a x, \a y), and the given \a width and \a height for its
+ scene rectangle. The \a parent parameter is passed to QObject's
+ constructor.
+
+ \sa sceneRect
+*/
+QGraphicsScene::QGraphicsScene(qreal x, qreal y, qreal width, qreal height, QObject *parent)
+ : QObject(*new QGraphicsScenePrivate, parent)
+{
+ d_func()->init();
+ setSceneRect(x, y, width, height);
+}
+
+/*!
+ Removes and deletes all items from the scene object
+ before destroying the scene object. The scene object
+ is removed from the application's global scene list,
+ and it is removed from all associated views.
+*/
+QGraphicsScene::~QGraphicsScene()
+{
+ Q_D(QGraphicsScene);
+
+ // Remove this scene from qApp's global scene list.
+ if (!QApplicationPrivate::is_app_closing)
+ qApp->d_func()->scene_list.removeAll(this);
+
+ clear();
+
+ // Remove this scene from all associated views.
+ for (int j = 0; j < d->views.size(); ++j)
+ d->views.at(j)->setScene(0);
+}
+
+/*!
+ \property QGraphicsScene::sceneRect
+ \brief the scene rectangle; the bounding rectangle of the scene
+
+ The scene rectangle defines the extent of the scene. It is
+ primarily used by QGraphicsView to determine the view's default
+ scrollable area, and by QGraphicsScene to manage item indexing.
+
+ If unset, or if set to a null QRectF, sceneRect() will return the largest
+ bounding rect of all items on the scene since the scene was created (i.e.,
+ a rectangle that grows when items are added to or moved in the scene, but
+ never shrinks).
+
+ \sa width(), height(), QGraphicsView::sceneRect
+*/
+QRectF QGraphicsScene::sceneRect() const
+{
+ Q_D(const QGraphicsScene);
+ if (d->hasSceneRect)
+ return d->sceneRect;
+
+ if (d->dirtyGrowingItemsBoundingRect) {
+ // Lazily update the growing items bounding rect
+ QGraphicsScenePrivate *thatd = const_cast<QGraphicsScenePrivate *>(d);
+ QRectF oldGrowingBoundingRect = thatd->growingItemsBoundingRect;
+ thatd->growingItemsBoundingRect |= itemsBoundingRect();
+ thatd->dirtyGrowingItemsBoundingRect = false;
+ if (oldGrowingBoundingRect != thatd->growingItemsBoundingRect)
+ emit const_cast<QGraphicsScene *>(this)->sceneRectChanged(thatd->growingItemsBoundingRect);
+ }
+ return d->growingItemsBoundingRect;
+}
+void QGraphicsScene::setSceneRect(const QRectF &rect)
+{
+ Q_D(QGraphicsScene);
+ if (rect != d->sceneRect) {
+ d->hasSceneRect = !rect.isNull();
+ d->sceneRect = rect;
+ emit sceneRectChanged(d->hasSceneRect ? rect : d->growingItemsBoundingRect);
+ }
+}
+
+/*!
+ \fn qreal QGraphicsScene::width() const
+
+ This convenience function is equivalent to calling sceneRect().width().
+
+ \sa height()
+*/
+
+/*!
+ \fn qreal QGraphicsScene::height() const
+
+ This convenience function is equivalent to calling \c sceneRect().height().
+
+ \sa width()
+*/
+
+/*!
+ Renders the \a source rect from scene into \a target, using \a painter. This
+ function is useful for capturing the contents of the scene onto a paint
+ device, such as a QImage (e.g., to take a screenshot), or for printing
+ with QPrinter. For example:
+
+ \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsscene.cpp 1
+
+ If \a source is a null rect, this function will use sceneRect() to
+ determine what to render. If \a target is a null rect, the dimensions of \a
+ painter's paint device will be used.
+
+ The source rect contents will be transformed according to \a
+ aspectRatioMode to fit into the target rect. By default, the aspect ratio
+ is kept, and \a source is scaled to fit in \a target.
+
+ \sa QGraphicsView::render()
+*/
+void QGraphicsScene::render(QPainter *painter, const QRectF &target, const QRectF &source,
+ Qt::AspectRatioMode aspectRatioMode)
+{
+ // ### Switch to using the recursive rendering algorithm instead.
+
+ // Default source rect = scene rect
+ QRectF sourceRect = source;
+ if (sourceRect.isNull())
+ sourceRect = sceneRect();
+
+ // Default target rect = device rect
+ QRectF targetRect = target;
+ if (targetRect.isNull()) {
+ if (painter->device()->devType() == QInternal::Picture)
+ targetRect = sourceRect;
+ else
+ targetRect.setRect(0, 0, painter->device()->width(), painter->device()->height());
+ }
+
+ // Find the ideal x / y scaling ratio to fit \a source into \a target.
+ qreal xratio = targetRect.width() / sourceRect.width();
+ qreal yratio = targetRect.height() / sourceRect.height();
+
+ // Scale according to the aspect ratio mode.
+ switch (aspectRatioMode) {
+ case Qt::KeepAspectRatio:
+ xratio = yratio = qMin(xratio, yratio);
+ break;
+ case Qt::KeepAspectRatioByExpanding:
+ xratio = yratio = qMax(xratio, yratio);
+ break;
+ case Qt::IgnoreAspectRatio:
+ break;
+ }
+
+ // Find all items to draw, and reverse the list (we want to draw
+ // in reverse order).
+ QList<QGraphicsItem *> itemList = items(sourceRect, Qt::IntersectsItemBoundingRect);
+ QGraphicsItem **itemArray = new QGraphicsItem *[itemList.size()];
+ int numItems = itemList.size();
+ for (int i = 0; i < numItems; ++i)
+ itemArray[numItems - i - 1] = itemList.at(i);
+ itemList.clear();
+
+ painter->save();
+
+ // Transform the painter.
+ painter->setClipRect(targetRect, Qt::IntersectClip);
+ QTransform painterTransform;
+ painterTransform *= QTransform()
+ .translate(targetRect.left(), targetRect.top())
+ .scale(xratio, yratio)
+ .translate(-sourceRect.left(), -sourceRect.top());
+ painter->setWorldTransform(painterTransform, true);
+
+ // Two unit vectors.
+ QLineF v1(0, 0, 1, 0);
+ QLineF v2(0, 0, 0, 1);
+
+ // Generate the style options
+ QStyleOptionGraphicsItem *styleOptionArray = new QStyleOptionGraphicsItem[numItems];
+ for (int i = 0; i < numItems; ++i)
+ itemArray[i]->d_ptr->initStyleOption(&styleOptionArray[i], painterTransform, targetRect.toRect());
+
+ // Render the scene.
+ drawBackground(painter, sourceRect);
+ drawItems(painter, numItems, itemArray, styleOptionArray);
+ drawForeground(painter, sourceRect);
+
+ delete [] itemArray;
+ delete [] styleOptionArray;
+
+ painter->restore();
+}
+
+/*!
+ \property QGraphicsScene::itemIndexMethod
+ \brief the item indexing method.
+
+ QGraphicsScene applies an indexing algorithm to the scene, to speed up
+ item discovery functions like items() and itemAt(). Indexing is most
+ efficient for static scenes (i.e., where items don't move around). For
+ dynamic scenes, or scenes with many animated items, the index bookkeeping
+ can outweight the fast lookup speeds.
+
+ For the common case, the default index method BspTreeIndex works fine. If
+ your scene uses many animations and you are experiencing slowness, you can
+ disable indexing by calling \c setItemIndexMethod(NoIndex).
+
+ \sa bspTreeDepth
+*/
+QGraphicsScene::ItemIndexMethod QGraphicsScene::itemIndexMethod() const
+{
+ Q_D(const QGraphicsScene);
+ return d->indexMethod;
+}
+void QGraphicsScene::setItemIndexMethod(ItemIndexMethod method)
+{
+ Q_D(QGraphicsScene);
+ if (d->indexMethod == method)
+ return;
+
+ d->indexMethod = method;
+
+ QList<QGraphicsItem *> oldItems = d->index->items(Qt::DescendingOrder);
+ delete d->index;
+ if (method == BspTreeIndex)
+ d->index = new QGraphicsSceneBspTreeIndex(this);
+ else
+ d->index = new QGraphicsSceneLinearIndex(this);
+ for (int i = oldItems.size() - 1; i >= 0; --i)
+ d->index->addItem(oldItems.at(i));
+}
+
+/*!
+ \property QGraphicsScene::bspTreeDepth
+ \brief the depth of QGraphicsScene's BSP index tree
+ \since 4.3
+
+ This property has no effect when NoIndex is used.
+
+ This value determines the depth of QGraphicsScene's BSP tree. The depth
+ directly affects QGraphicsScene's performance and memory usage; the latter
+ growing exponentially with the depth of the tree. With an optimal tree
+ depth, QGraphicsScene can instantly determine the locality of items, even
+ for scenes with thousands or millions of items. This also greatly improves
+ rendering performance.
+
+ By default, the value is 0, in which case Qt will guess a reasonable
+ default depth based on the size, location and number of items in the
+ scene. If these parameters change frequently, however, you may experience
+ slowdowns as QGraphicsScene retunes the depth internally. You can avoid
+ potential slowdowns by fixating the tree depth through setting this
+ property.
+
+ The depth of the tree and the size of the scene rectangle decide the
+ granularity of the scene's partitioning. The size of each scene segment is
+ determined by the following algorithm:
+
+ \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsscene.cpp 2
+
+ The BSP tree has an optimal size when each segment contains between 0 and
+ 10 items.
+
+ \sa itemIndexMethod
+*/
+int QGraphicsScene::bspTreeDepth() const
+{
+ Q_D(const QGraphicsScene);
+ QGraphicsSceneBspTreeIndex *bspTree = qobject_cast<QGraphicsSceneBspTreeIndex *>(d->index);
+ return bspTree ? bspTree->bspTreeDepth() : 0;
+}
+void QGraphicsScene::setBspTreeDepth(int depth)
+{
+ Q_D(QGraphicsScene);
+ if (depth < 0) {
+ qWarning("QGraphicsScene::setBspTreeDepth: invalid depth %d ignored; must be >= 0", depth);
+ return;
+ }
+
+ QGraphicsSceneBspTreeIndex *bspTree = qobject_cast<QGraphicsSceneBspTreeIndex *>(d->index);
+ if (!bspTree) {
+ qWarning("QGraphicsScene::setBspTreeDepth: can not apply if indexing method is not BSP");
+ return;
+ }
+ bspTree->setBspTreeDepth(depth);
+}
+
+/*!
+ \property QGraphicsScene::sortCacheEnabled
+ \brief whether sort caching is enabled
+ \since 4.5
+ \obsolete
+
+ Since Qt 4.6, this property has no effect.
+*/
+bool QGraphicsScene::isSortCacheEnabled() const
+{
+ Q_D(const QGraphicsScene);
+ return d->sortCacheEnabled;
+}
+void QGraphicsScene::setSortCacheEnabled(bool enabled)
+{
+ Q_D(QGraphicsScene);
+ if (d->sortCacheEnabled == enabled)
+ return;
+ d->sortCacheEnabled = enabled;
+}
+
+/*!
+ Calculates and returns the bounding rect of all items on the scene. This
+ function works by iterating over all items, and because if this, it can
+ be slow for large scenes.
+
+ \sa sceneRect()
+*/
+QRectF QGraphicsScene::itemsBoundingRect() const
+{
+ // Does not take untransformable items into account.
+ QRectF boundingRect;
+ foreach (QGraphicsItem *item, items())
+ boundingRect |= item->sceneBoundingRect();
+ return boundingRect;
+}
+
+/*!
+ Returns a list of all items in the scene in descending stacking order.
+
+ \sa addItem(), removeItem(), {QGraphicsItem#Sorting}{Sorting}
+*/
+QList<QGraphicsItem *> QGraphicsScene::items() const
+{
+ Q_D(const QGraphicsScene);
+ return d->index->items(Qt::DescendingOrder);
+}
+
+/*!
+ Returns an ordered list of all items on the scene. \a order decides the
+ stacking order.
+
+ \sa addItem(), removeItem(), {QGraphicsItem#Sorting}{Sorting}
+*/
+QList<QGraphicsItem *> QGraphicsScene::items(Qt::SortOrder order) const
+{
+ Q_D(const QGraphicsScene);
+ return d->index->items(order);
+}
+
+/*!
+ \obsolete
+
+ Returns all visible items at position \a pos in the scene. The items are
+ listed in descending stacking order (i.e., the first item in the list is the
+ top-most item, and the last item is the bottom-most item).
+
+ This function is deprecated and returns incorrect results if the scene
+ contains items that ignore transformations. Use the overload that takes
+ a QTransform instead.
+
+ \sa itemAt(), {QGraphicsItem#Sorting}{Sorting}
+*/
+QList<QGraphicsItem *> QGraphicsScene::items(const QPointF &pos) const
+{
+ Q_D(const QGraphicsScene);
+ return d->index->items(pos, Qt::IntersectsItemShape, Qt::DescendingOrder);
+}
+
+/*!
+ \overload
+ \obsolete
+
+ Returns all visible items that, depending on \a mode, are either inside or
+ intersect with the specified \a rectangle.
+
+ The default value for \a mode is Qt::IntersectsItemShape; all items whose
+ exact shape intersects with or is contained by \a rectangle are returned.
+
+ This function is deprecated and returns incorrect results if the scene
+ contains items that ignore transformations. Use the overload that takes
+ a QTransform instead.
+
+ \sa itemAt(), {QGraphicsItem#Sorting}{Sorting}
+*/
+QList<QGraphicsItem *> QGraphicsScene::items(const QRectF &rectangle, Qt::ItemSelectionMode mode) const
+{
+ Q_D(const QGraphicsScene);
+ return d->index->items(rectangle, mode, Qt::DescendingOrder);
+}
+
+/*!
+ \fn QList<QGraphicsItem *> QGraphicsScene::items(qreal x, qreal y, qreal w, qreal h, Qt::ItemSelectionMode mode) const
+ \obsolete
+ \since 4.3
+
+ This convenience function is equivalent to calling items(QRectF(\a x, \a y, \a w, \a h), \a mode).
+
+ This function is deprecated and returns incorrect results if the scene
+ contains items that ignore transformations. Use the overload that takes
+ a QTransform instead.
+*/
+
+/*!
+ \fn QList<QGraphicsItem *> QGraphicsScene::items(qreal x, qreal y, qreal w, qreal h, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const
+ \overload
+ \since 4.6
+
+ \brief Returns all visible items that, depending on \a mode, are
+ either inside or intersect with the rectangle defined by \a x, \a y,
+ \a w and \a h, in a list sorted using \a order.
+
+ \a deviceTransform is the transformation that applies to the view, and needs to
+ be provided if the scene contains items that ignore transformations.
+*/
+
+/*!
+ \fn QList<QGraphicsItem *> QGraphicsScene::items(const QPolygonF &polygon, Qt::ItemSelectionMode mode) const
+ \overload
+ \obsolete
+
+ Returns all visible items that, depending on \a mode, are either inside or
+ intersect with the polygon \a polygon.
+
+ The default value for \a mode is Qt::IntersectsItemShape; all items whose
+ exact shape intersects with or is contained by \a polygon are returned.
+
+ This function is deprecated and returns incorrect results if the scene
+ contains items that ignore transformations. Use the overload that takes
+ a QTransform instead.
+
+ \sa itemAt(), {QGraphicsItem#Sorting}{Sorting}
+*/
+QList<QGraphicsItem *> QGraphicsScene::items(const QPolygonF &polygon, Qt::ItemSelectionMode mode) const
+{
+ Q_D(const QGraphicsScene);
+ return d->index->items(polygon, mode, Qt::DescendingOrder);
+}
+
+/*!
+ \fn QList<QGraphicsItem *> QGraphicsScene::items(const QPainterPath &path, Qt::ItemSelectionMode mode) const
+ \overload
+ \obsolete
+
+ Returns all visible items that, depending on \a path, are either inside or
+ intersect with the path \a path.
+
+ The default value for \a mode is Qt::IntersectsItemShape; all items whose
+ exact shape intersects with or is contained by \a path are returned.
+
+ This function is deprecated and returns incorrect results if the scene
+ contains items that ignore transformations. Use the overload that takes
+ a QTransform instead.
+
+ \sa itemAt(), {QGraphicsItem#Sorting}{Sorting}
+*/
+QList<QGraphicsItem *> QGraphicsScene::items(const QPainterPath &path, Qt::ItemSelectionMode mode) const
+{
+ Q_D(const QGraphicsScene);
+ return d->index->items(path, mode, Qt::DescendingOrder);
+}
+
+/*!
+ \fn QList<QGraphicsItem *> QGraphicsScene::items(const QPointF &pos, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const
+ \since 4.6
+
+ \brief Returns all visible items that, depending on \a mode, are at
+ the specified \a pos in a list sorted using \a order.
+
+ The default value for \a mode is Qt::IntersectsItemShape; all items whose
+ exact shape intersects with \a pos are returned.
+
+ \a deviceTransform is the transformation that applies to the view, and needs to
+ be provided if the scene contains items that ignore transformations.
+
+ \sa itemAt(), {QGraphicsItem#Sorting}{Sorting}
+*/
+QList<QGraphicsItem *> QGraphicsScene::items(const QPointF &pos, Qt::ItemSelectionMode mode,
+ Qt::SortOrder order, const QTransform &deviceTransform) const
+{
+ Q_D(const QGraphicsScene);
+ return d->index->items(pos, mode, order, deviceTransform);
+}
+
+/*!
+ \fn QList<QGraphicsItem *> QGraphicsScene::items(const QRectF &rect, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const
+ \overload
+ \since 4.6
+
+ \brief Returns all visible items that, depending on \a mode, are
+ either inside or intersect with the specified \a rect and return a
+ list sorted using \a order.
+
+ The default value for \a mode is Qt::IntersectsItemShape; all items whose
+ exact shape intersects with or is contained by \a rect are returned.
+
+ \a deviceTransform is the transformation that applies to the view, and needs to
+ be provided if the scene contains items that ignore transformations.
+
+ \sa itemAt(), {QGraphicsItem#Sorting}{Sorting}
+*/
+QList<QGraphicsItem *> QGraphicsScene::items(const QRectF &rect, Qt::ItemSelectionMode mode,
+ Qt::SortOrder order, const QTransform &deviceTransform) const
+{
+ Q_D(const QGraphicsScene);
+ return d->index->items(rect, mode, order, deviceTransform);
+}
+
+/*!
+ \fn QList<QGraphicsItem *> QGraphicsScene::items(const QPolygonF &polygon, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const
+ \overload
+ \since 4.6
+
+ \brief Returns all visible items that, depending on \a mode, are
+ either inside or intersect with the specified \a polygon and return
+ a list sorted using \a order.
+
+ The default value for \a mode is Qt::IntersectsItemShape; all items whose
+ exact shape intersects with or is contained by \a polygon are returned.
+
+ \a deviceTransform is the transformation that applies to the view, and needs to
+ be provided if the scene contains items that ignore transformations.
+
+ \sa itemAt(), {QGraphicsItem#Sorting}{Sorting}
+*/
+QList<QGraphicsItem *> QGraphicsScene::items(const QPolygonF &polygon, Qt::ItemSelectionMode mode,
+ Qt::SortOrder order, const QTransform &deviceTransform) const
+{
+ Q_D(const QGraphicsScene);
+ return d->index->items(polygon, mode, order, deviceTransform);
+}
+
+/*!
+ \fn QList<QGraphicsItem *> QGraphicsScene::items(const QPainterPath &path, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const
+ \overload
+ \since 4.6
+
+ \brief Returns all visible items that, depending on \a mode, are
+ either inside or intersect with the specified \a path and return a
+ list sorted using \a order.
+
+ The default value for \a mode is Qt::IntersectsItemShape; all items whose
+ exact shape intersects with or is contained by \a path are returned.
+
+ \a deviceTransform is the transformation that applies to the view, and needs to
+ be provided if the scene contains items that ignore transformations.
+
+ \sa itemAt(), {QGraphicsItem#Sorting}{Sorting}
+*/
+QList<QGraphicsItem *> QGraphicsScene::items(const QPainterPath &path, Qt::ItemSelectionMode mode,
+ Qt::SortOrder order, const QTransform &deviceTransform) const
+{
+ Q_D(const QGraphicsScene);
+ return d->index->items(path, mode, order, deviceTransform);
+}
+
+/*!
+ Returns a list of all items that collide with \a item. Collisions are
+ determined by calling QGraphicsItem::collidesWithItem(); the collision
+ detection is determined by \a mode. By default, all items whose shape
+ intersects \a item or is contained inside \a item's shape are returned.
+
+ The items are returned in descending stacking order (i.e., the first item
+ in the list is the uppermost item, and the last item is the lowermost
+ item).
+
+ \sa items(), itemAt(), QGraphicsItem::collidesWithItem(), {QGraphicsItem#Sorting}{Sorting}
+*/
+QList<QGraphicsItem *> QGraphicsScene::collidingItems(const QGraphicsItem *item,
+ Qt::ItemSelectionMode mode) const
+{
+ Q_D(const QGraphicsScene);
+ if (!item) {
+ qWarning("QGraphicsScene::collidingItems: cannot find collisions for null item");
+ return QList<QGraphicsItem *>();
+ }
+
+ // Does not support ItemIgnoresTransformations.
+ QList<QGraphicsItem *> tmp;
+ foreach (QGraphicsItem *itemInVicinity, d->index->estimateItems(item->sceneBoundingRect(), Qt::DescendingOrder)) {
+ if (item != itemInVicinity && item->collidesWithItem(itemInVicinity, mode))
+ tmp << itemInVicinity;
+ }
+ return tmp;
+}
+
+/*!
+ \overload
+ \obsolete
+
+ Returns the topmost visible item at the specified \a position, or 0 if
+ there are no items at this position.
+
+ This function is deprecated and returns incorrect results if the scene
+ contains items that ignore transformations. Use the overload that takes
+ a QTransform instead.
+
+ \sa items(), collidingItems(), {QGraphicsItem#Sorting}{Sorting}
+*/
+QGraphicsItem *QGraphicsScene::itemAt(const QPointF &position) const
+{
+ QList<QGraphicsItem *> itemsAtPoint = items(position);
+ return itemsAtPoint.isEmpty() ? 0 : itemsAtPoint.first();
+}
+
+/*!
+ \since 4.6
+
+ Returns the topmost visible item at the specified \a position, or 0
+ if there are no items at this position.
+
+ \a deviceTransform is the transformation that applies to the view, and needs to
+ be provided if the scene contains items that ignore transformations.
+
+ \sa items(), collidingItems(), {QGraphicsItem#Sorting}{Sorting}
+*/
+QGraphicsItem *QGraphicsScene::itemAt(const QPointF &position, const QTransform &deviceTransform) const
+{
+ QList<QGraphicsItem *> itemsAtPoint = items(position, Qt::IntersectsItemShape,
+ Qt::DescendingOrder, deviceTransform);
+ return itemsAtPoint.isEmpty() ? 0 : itemsAtPoint.first();
+}
+
+/*!
+ \fn QGraphicsScene::itemAt(qreal x, qreal y, const QTransform &deviceTransform) const
+ \overload
+ \since 4.6
+
+ Returns the topmost item at the position specified by (\a x, \a
+ y), or 0 if there are no items at this position.
+
+ \a deviceTransform is the transformation that applies to the view, and needs to
+ be provided if the scene contains items that ignore transformations.
+
+ This convenience function is equivalent to calling \c
+ {itemAt(QPointF(x, y), deviceTransform)}.
+*/
+
+/*!
+ \fn QGraphicsScene::itemAt(qreal x, qreal y) const
+ \overload
+ \obsolete
+
+ Returns the topmost item at the position specified by (\a x, \a
+ y), or 0 if there are no items at this position.
+
+ This convenience function is equivalent to calling \c
+ {itemAt(QPointF(x, y))}.
+
+ This function is deprecated and returns incorrect results if the scene
+ contains items that ignore transformations. Use the overload that takes
+ a QTransform instead.
+*/
+
+/*!
+ Returns a list of all currently selected items. The items are
+ returned in no particular order.
+
+ \sa setSelectionArea()
+*/
+QList<QGraphicsItem *> QGraphicsScene::selectedItems() const
+{
+ Q_D(const QGraphicsScene);
+
+ // Optimization: Lazily removes items that are not selected.
+ QGraphicsScene *that = const_cast<QGraphicsScene *>(this);
+ QSet<QGraphicsItem *> actuallySelectedSet;
+ foreach (QGraphicsItem *item, that->d_func()->selectedItems) {
+ if (item->isSelected())
+ actuallySelectedSet << item;
+ }
+
+ that->d_func()->selectedItems = actuallySelectedSet;
+
+ return d->selectedItems.values();
+}
+
+/*!
+ Returns the selection area that was previously set with
+ setSelectionArea(), or an empty QPainterPath if no selection area has been
+ set.
+
+ \sa setSelectionArea()
+*/
+QPainterPath QGraphicsScene::selectionArea() const
+{
+ Q_D(const QGraphicsScene);
+ return d->selectionArea;
+}
+
+/*!
+ \since 4.6
+
+ Sets the selection area to \a path. All items within this area are
+ immediately selected, and all items outside are unselected. You can get
+ the list of all selected items by calling selectedItems().
+
+ \a deviceTransform is the transformation that applies to the view, and needs to
+ be provided if the scene contains items that ignore transformations.
+
+ For an item to be selected, it must be marked as \e selectable
+ (QGraphicsItem::ItemIsSelectable).
+
+ \sa clearSelection(), selectionArea()
+*/
+void QGraphicsScene::setSelectionArea(const QPainterPath &path, const QTransform &deviceTransform)
+{
+ setSelectionArea(path, Qt::IntersectsItemShape, deviceTransform);
+}
+
+/*!
+ \obsolete
+ \overload
+
+ Sets the selection area to \a path.
+
+ This function is deprecated and leads to incorrect results if the scene
+ contains items that ignore transformations. Use the overload that takes
+ a QTransform instead.
+*/
+void QGraphicsScene::setSelectionArea(const QPainterPath &path)
+{
+ setSelectionArea(path, Qt::IntersectsItemShape, QTransform());
+}
+
+/*!
+ \obsolete
+ \overload
+ \since 4.3
+
+ Sets the selection area to \a path using \a mode to determine if items are
+ included in the selection area.
+
+ \sa clearSelection(), selectionArea()
+*/
+void QGraphicsScene::setSelectionArea(const QPainterPath &path, Qt::ItemSelectionMode mode)
+{
+ setSelectionArea(path, mode, QTransform());
+}
+
+/*!
+ \overload
+ \since 4.6
+
+ Sets the selection area to \a path using \a mode to determine if items are
+ included in the selection area.
+
+ \a deviceTransform is the transformation that applies to the view, and needs to
+ be provided if the scene contains items that ignore transformations.
+
+ \sa clearSelection(), selectionArea()
+*/
+void QGraphicsScene::setSelectionArea(const QPainterPath &path, Qt::ItemSelectionMode mode,
+ const QTransform &deviceTransform)
+{
+ Q_D(QGraphicsScene);
+
+ // Note: with boolean path operations, we can improve performance here
+ // quite a lot by "growing" the old path instead of replacing it. That
+ // allows us to only check the intersect area for changes, instead of
+ // reevaluating the whole path over again.
+ d->selectionArea = path;
+
+ QSet<QGraphicsItem *> unselectItems = d->selectedItems;
+
+ // Disable emitting selectionChanged() for individual items.
+ ++d->selectionChanging;
+ bool changed = false;
+
+ // Set all items in path to selected.
+ foreach (QGraphicsItem *item, items(path, mode, Qt::DescendingOrder, deviceTransform)) {
+ if (item->flags() & QGraphicsItem::ItemIsSelectable) {
+ if (!item->isSelected())
+ changed = true;
+ unselectItems.remove(item);
+ item->setSelected(true);
+ }
+ }
+
+ // Unselect all items outside path.
+ foreach (QGraphicsItem *item, unselectItems) {
+ item->setSelected(false);
+ changed = true;
+ }
+
+ // Reenable emitting selectionChanged() for individual items.
+ --d->selectionChanging;
+
+ if (!d->selectionChanging && changed)
+ emit selectionChanged();
+}
+
+/*!
+ Clears the current selection.
+
+ \sa setSelectionArea(), selectedItems()
+*/
+void QGraphicsScene::clearSelection()
+{
+ Q_D(QGraphicsScene);
+
+ // Disable emitting selectionChanged
+ ++d->selectionChanging;
+ bool changed = !d->selectedItems.isEmpty();
+
+ foreach (QGraphicsItem *item, d->selectedItems)
+ item->setSelected(false);
+ d->selectedItems.clear();
+
+ // Reenable emitting selectionChanged() for individual items.
+ --d->selectionChanging;
+
+ if (!d->selectionChanging && changed)
+ emit selectionChanged();
+}
+
+/*!
+ \since 4.4
+
+ Removes and deletes all items from the scene, but otherwise leaves the
+ state of the scene unchanged.
+
+ \sa addItem()
+*/
+void QGraphicsScene::clear()
+{
+ Q_D(QGraphicsScene);
+ // NB! We have to clear the index before deleting items; otherwise the
+ // index might try to access dangling item pointers.
+ d->index->clear();
+ // NB! QGraphicsScenePrivate::unregisterTopLevelItem() removes items
+ while (!d->topLevelItems.isEmpty())
+ delete d->topLevelItems.first();
+ Q_ASSERT(d->topLevelItems.isEmpty());
+ d->lastItemCount = 0;
+ d->allItemsIgnoreHoverEvents = true;
+ d->allItemsUseDefaultCursor = true;
+ d->allItemsIgnoreTouchEvents = true;
+}
+
+/*!
+ Groups all items in \a items into a new QGraphicsItemGroup, and returns a
+ pointer to the group. The group is created with the common ancestor of \a
+ items as its parent, and with position (0, 0). The items are all
+ reparented to the group, and their positions and transformations are
+ mapped to the group. If \a items is empty, this function will return an
+ empty top-level QGraphicsItemGroup.
+
+ QGraphicsScene has ownership of the group item; you do not need to delete
+ it. To dismantle (ungroup) a group, call destroyItemGroup().
+
+ \sa destroyItemGroup(), QGraphicsItemGroup::addToGroup()
+*/
+QGraphicsItemGroup *QGraphicsScene::createItemGroup(const QList<QGraphicsItem *> &items)
+{
+ // Build a list of the first item's ancestors
+ QList<QGraphicsItem *> ancestors;
+ int n = 0;
+ if (!items.isEmpty()) {
+ QGraphicsItem *parent = items.at(n++);
+ while ((parent = parent->parentItem()))
+ ancestors.append(parent);
+ }
+
+ // Find the common ancestor for all items
+ QGraphicsItem *commonAncestor = 0;
+ if (!ancestors.isEmpty()) {
+ while (n < items.size()) {
+ int commonIndex = -1;
+ QGraphicsItem *parent = items.at(n++);
+ do {
+ int index = ancestors.indexOf(parent, qMax(0, commonIndex));
+ if (index != -1) {
+ commonIndex = index;
+ break;
+ }
+ } while ((parent = parent->parentItem()));
+
+ if (commonIndex == -1) {
+ commonAncestor = 0;
+ break;
+ }
+
+ commonAncestor = ancestors.at(commonIndex);
+ }
+ }
+
+ // Create a new group at that level
+ QGraphicsItemGroup *group = new QGraphicsItemGroup(commonAncestor);
+ if (!commonAncestor)
+ addItem(group);
+ foreach (QGraphicsItem *item, items)
+ group->addToGroup(item);
+ return group;
+}
+
+/*!
+ Reparents all items in \a group to \a group's parent item, then removes \a
+ group from the scene, and finally deletes it. The items' positions and
+ transformations are mapped from the group to the group's parent.
+
+ \sa createItemGroup(), QGraphicsItemGroup::removeFromGroup()
+*/
+void QGraphicsScene::destroyItemGroup(QGraphicsItemGroup *group)
+{
+ foreach (QGraphicsItem *item, group->children())
+ group->removeFromGroup(item);
+ removeItem(group);
+ delete group;
+}
+
+/*!
+ Adds or moves the \a item and all its childen to this scene.
+ This scene takes ownership of the \a item.
+
+ If the item is visible (i.e., QGraphicsItem::isVisible() returns
+ true), QGraphicsScene will emit changed() once control goes back
+ to the event loop.
+
+ If the item is already in a different scene, it will first be
+ removed from its old scene, and then added to this scene as a
+ top-level.
+
+ QGraphicsScene will send ItemSceneChange notifications to \a item
+ while it is added to the scene. If item does not currently belong
+ to a scene, only one notification is sent. If it does belong to
+ scene already (i.e., it is moved to this scene), QGraphicsScene
+ will send an addition notification as the item is removed from its
+ previous scene.
+
+ If the item is a panel, the scene is active, and there is no
+ active panel in the scene, then the item will be activated.
+
+ \sa removeItem(), addEllipse(), addLine(), addPath(), addPixmap(),
+ addRect(), addText(), addWidget(), {QGraphicsItem#Sorting}{Sorting}
+*/
+void QGraphicsScene::addItem(QGraphicsItem *item)
+{
+ Q_D(QGraphicsScene);
+ if (!item) {
+ qWarning("QGraphicsScene::addItem: cannot add null item");
+ return;
+ }
+ if (item->d_ptr->scene == this) {
+ qWarning("QGraphicsScene::addItem: item has already been added to this scene");
+ return;
+ }
+ // Remove this item from its existing scene
+ if (QGraphicsScene *oldScene = item->d_ptr->scene)
+ oldScene->removeItem(item);
+
+ // Notify the item that its scene is changing, and allow the item to
+ // react.
+ const QVariant newSceneVariant(item->itemChange(QGraphicsItem::ItemSceneChange,
+ QVariant::fromValue<QGraphicsScene *>(this)));
+ QGraphicsScene *targetScene = qvariant_cast<QGraphicsScene *>(newSceneVariant);
+ if (targetScene != this) {
+ if (targetScene && item->d_ptr->scene != targetScene)
+ targetScene->addItem(item);
+ return;
+ }
+
+ // QDeclarativeItems do not rely on initial itemChanged message, as the componentComplete
+ // function allows far more opportunity for delayed-construction optimization.
+ if (!item->d_ptr->isDeclarativeItem) {
+ if (d->unpolishedItems.isEmpty()) {
+ QMetaMethod method = metaObject()->method(d->polishItemsIndex);
+ method.invoke(this, Qt::QueuedConnection);
+ }
+ d->unpolishedItems.append(item);
+ item->d_ptr->pendingPolish = true;
+ }
+
+ // Detach this item from its parent if the parent's scene is different
+ // from this scene.
+ if (QGraphicsItem *itemParent = item->d_ptr->parent) {
+ if (itemParent->d_ptr->scene != this)
+ item->setParentItem(0);
+ }
+
+ // Add the item to this scene
+ item->d_func()->scene = targetScene;
+
+ // Add the item in the index
+ d->index->addItem(item);
+
+ // Add to list of toplevels if this item is a toplevel.
+ if (!item->d_ptr->parent)
+ d->registerTopLevelItem(item);
+
+ // Add to list of items that require an update. We cannot assume that the
+ // item is fully constructed, so calling item->update() can lead to a pure
+ // virtual function call to boundingRect().
+ d->markDirty(item);
+ d->dirtyGrowingItemsBoundingRect = true;
+
+ // Disable selectionChanged() for individual items
+ ++d->selectionChanging;
+ int oldSelectedItemSize = d->selectedItems.size();
+
+ // Enable mouse tracking if the item accepts hover events or has a cursor set.
+ if (d->allItemsIgnoreHoverEvents && d->itemAcceptsHoverEvents_helper(item)) {
+ d->allItemsIgnoreHoverEvents = false;
+ d->enableMouseTrackingOnViews();
+ }
+#ifndef QT_NO_CURSOR
+ if (d->allItemsUseDefaultCursor && item->d_ptr->hasCursor) {
+ d->allItemsUseDefaultCursor = false;
+ if (d->allItemsIgnoreHoverEvents) // already enabled otherwise
+ d->enableMouseTrackingOnViews();
+ }
+#endif //QT_NO_CURSOR
+
+ // Enable touch events if the item accepts touch events.
+ if (d->allItemsIgnoreTouchEvents && item->d_ptr->acceptTouchEvents) {
+ d->allItemsIgnoreTouchEvents = false;
+ d->enableTouchEventsOnViews();
+ }
+
+#ifndef QT_NO_GESTURES
+ foreach (Qt::GestureType gesture, item->d_ptr->gestureContext.keys())
+ d->grabGesture(item, gesture);
+#endif
+
+ // Update selection lists
+ if (item->isSelected())
+ d->selectedItems << item;
+ if (item->isWidget() && item->isVisible() && static_cast<QGraphicsWidget *>(item)->windowType() == Qt::Popup)
+ d->addPopup(static_cast<QGraphicsWidget *>(item));
+ if (item->isPanel() && item->isVisible() && item->panelModality() != QGraphicsItem::NonModal)
+ d->enterModal(item);
+
+ // Update creation order focus chain. Make sure to leave the widget's
+ // internal tab order intact.
+ if (item->isWidget()) {
+ QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(item);
+ if (!d->tabFocusFirst) {
+ // No first tab focus widget - make this the first tab focus
+ // widget.
+ d->tabFocusFirst = widget;
+ } else if (!widget->parentWidget()) {
+ // Adding a widget that is not part of a tab focus chain.
+ QGraphicsWidget *last = d->tabFocusFirst->d_func()->focusPrev;
+ QGraphicsWidget *lastNew = widget->d_func()->focusPrev;
+ last->d_func()->focusNext = widget;
+ widget->d_func()->focusPrev = last;
+ d->tabFocusFirst->d_func()->focusPrev = lastNew;
+ lastNew->d_func()->focusNext = d->tabFocusFirst;
+ }
+ }
+
+ // Add all children recursively
+ item->d_ptr->ensureSortedChildren();
+ for (int i = 0; i < item->d_ptr->children.size(); ++i)
+ addItem(item->d_ptr->children.at(i));
+
+ // Resolve font and palette.
+ item->d_ptr->resolveFont(d->font.resolve());
+ item->d_ptr->resolvePalette(d->palette.resolve());
+
+
+ // Reenable selectionChanged() for individual items
+ --d->selectionChanging;
+ if (!d->selectionChanging && d->selectedItems.size() != oldSelectedItemSize)
+ emit selectionChanged();
+
+ // Deliver post-change notification
+ item->itemChange(QGraphicsItem::ItemSceneHasChanged, newSceneVariant);
+
+ // Update explicit activation
+ bool autoActivate = true;
+ if (!d->childExplicitActivation && item->d_ptr->explicitActivate)
+ d->childExplicitActivation = item->d_ptr->wantsActive ? 1 : 2;
+ if (d->childExplicitActivation && item->isPanel()) {
+ if (d->childExplicitActivation == 1)
+ setActivePanel(item);
+ else
+ autoActivate = false;
+ d->childExplicitActivation = 0;
+ } else if (!item->d_ptr->parent) {
+ d->childExplicitActivation = 0;
+ }
+
+ // Auto-activate this item's panel if nothing else has been activated
+ if (autoActivate) {
+ if (!d->lastActivePanel && !d->activePanel && item->isPanel()) {
+ if (isActive())
+ setActivePanel(item);
+ else
+ d->lastActivePanel = item;
+ }
+ }
+
+ if (item->d_ptr->flags & QGraphicsItem::ItemSendsScenePositionChanges)
+ d->registerScenePosItem(item);
+
+ // Ensure that newly added items that have subfocus set, gain
+ // focus automatically if there isn't a focus item already.
+ if (!d->focusItem && item != d->lastFocusItem && item->focusItem() == item)
+ item->focusItem()->setFocus();
+
+ d->updateInputMethodSensitivityInViews();
+}
+
+/*!
+ Creates and adds an ellipse item to the scene, and returns the item
+ pointer. The geometry of the ellipse is defined by \a rect, and its pen
+ and brush are initialized to \a pen and \a brush.
+
+ Note that the item's geometry is provided in item coordinates, and its
+ position is initialized to (0, 0).
+
+ If the item is visible (i.e., QGraphicsItem::isVisible() returns true),
+ QGraphicsScene will emit changed() once control goes back to the event
+ loop.
+
+ \sa addLine(), addPath(), addPixmap(), addRect(), addText(), addItem(),
+ addWidget()
+*/
+QGraphicsEllipseItem *QGraphicsScene::addEllipse(const QRectF &rect, const QPen &pen, const QBrush &brush)
+{
+ QGraphicsEllipseItem *item = new QGraphicsEllipseItem(rect);
+ item->setPen(pen);
+ item->setBrush(brush);
+ addItem(item);
+ return item;
+}
+
+/*!
+ \fn QGraphicsEllipseItem *QGraphicsScene::addEllipse(qreal x, qreal y, qreal w, qreal h, const QPen &pen, const QBrush &brush)
+ \since 4.3
+
+ This convenience function is equivalent to calling addEllipse(QRectF(\a x,
+ \a y, \a w, \a h), \a pen, \a brush).
+*/
+
+/*!
+ Creates and adds a line item to the scene, and returns the item
+ pointer. The geometry of the line is defined by \a line, and its pen
+ is initialized to \a pen.
+
+ Note that the item's geometry is provided in item coordinates, and its
+ position is initialized to (0, 0).
+
+ If the item is visible (i.e., QGraphicsItem::isVisible() returns true),
+ QGraphicsScene will emit changed() once control goes back to the event
+ loop.
+
+ \sa addEllipse(), addPath(), addPixmap(), addRect(), addText(), addItem(),
+ addWidget()
+*/
+QGraphicsLineItem *QGraphicsScene::addLine(const QLineF &line, const QPen &pen)
+{
+ QGraphicsLineItem *item = new QGraphicsLineItem(line);
+ item->setPen(pen);
+ addItem(item);
+ return item;
+}
+
+/*!
+ \fn QGraphicsLineItem *QGraphicsScene::addLine(qreal x1, qreal y1, qreal x2, qreal y2, const QPen &pen)
+ \since 4.3
+
+ This convenience function is equivalent to calling addLine(QLineF(\a x1,
+ \a y1, \a x2, \a y2), \a pen).
+*/
+
+/*!
+ Creates and adds a path item to the scene, and returns the item
+ pointer. The geometry of the path is defined by \a path, and its pen and
+ brush are initialized to \a pen and \a brush.
+
+ Note that the item's geometry is provided in item coordinates, and its
+ position is initialized to (0, 0).
+
+ If the item is visible (i.e., QGraphicsItem::isVisible() returns true),
+ QGraphicsScene will emit changed() once control goes back to the event
+ loop.
+
+ \sa addEllipse(), addLine(), addPixmap(), addRect(), addText(), addItem(),
+ addWidget()
+*/
+QGraphicsPathItem *QGraphicsScene::addPath(const QPainterPath &path, const QPen &pen, const QBrush &brush)
+{
+ QGraphicsPathItem *item = new QGraphicsPathItem(path);
+ item->setPen(pen);
+ item->setBrush(brush);
+ addItem(item);
+ return item;
+}
+
+/*!
+ Creates and adds a pixmap item to the scene, and returns the item
+ pointer. The pixmap is defined by \a pixmap.
+
+ Note that the item's geometry is provided in item coordinates, and its
+ position is initialized to (0, 0).
+
+ If the item is visible (i.e., QGraphicsItem::isVisible() returns true),
+ QGraphicsScene will emit changed() once control goes back to the event
+ loop.
+
+ \sa addEllipse(), addLine(), addPath(), addRect(), addText(), addItem(),
+ addWidget()
+*/
+QGraphicsPixmapItem *QGraphicsScene::addPixmap(const QPixmap &pixmap)
+{
+ QGraphicsPixmapItem *item = new QGraphicsPixmapItem(pixmap);
+ addItem(item);
+ return item;
+}
+
+/*!
+ Creates and adds a polygon item to the scene, and returns the item
+ pointer. The polygon is defined by \a polygon, and its pen and
+ brush are initialized to \a pen and \a brush.
+
+ Note that the item's geometry is provided in item coordinates, and its
+ position is initialized to (0, 0).
+
+ If the item is visible (i.e., QGraphicsItem::isVisible() returns true),
+ QGraphicsScene will emit changed() once control goes back to the event
+ loop.
+
+ \sa addEllipse(), addLine(), addPath(), addRect(), addText(), addItem(),
+ addWidget()
+*/
+QGraphicsPolygonItem *QGraphicsScene::addPolygon(const QPolygonF &polygon,
+ const QPen &pen, const QBrush &brush)
+{
+ QGraphicsPolygonItem *item = new QGraphicsPolygonItem(polygon);
+ item->setPen(pen);
+ item->setBrush(brush);
+ addItem(item);
+ return item;
+}
+
+/*!
+ Creates and adds a rectangle item to the scene, and returns the item
+ pointer. The geometry of the rectangle is defined by \a rect, and its pen
+ and brush are initialized to \a pen and \a brush.
+
+ Note that the item's geometry is provided in item coordinates, and its
+ position is initialized to (0, 0). For example, if a QRect(50, 50, 100,
+ 100) is added, its top-left corner will be at (50, 50) relative to the
+ origin in the items coordinate system.
+
+ If the item is visible (i.e., QGraphicsItem::isVisible() returns true),
+ QGraphicsScene will emit changed() once control goes back to the event
+ loop.
+
+ \sa addEllipse(), addLine(), addPixmap(), addPixmap(), addText(),
+ addItem(), addWidget()
+*/
+QGraphicsRectItem *QGraphicsScene::addRect(const QRectF &rect, const QPen &pen, const QBrush &brush)
+{
+ QGraphicsRectItem *item = new QGraphicsRectItem(rect);
+ item->setPen(pen);
+ item->setBrush(brush);
+ addItem(item);
+ return item;
+}
+
+/*!
+ \fn QGraphicsRectItem *QGraphicsScene::addRect(qreal x, qreal y, qreal w, qreal h, const QPen &pen, const QBrush &brush)
+ \since 4.3
+
+ This convenience function is equivalent to calling addRect(QRectF(\a x,
+ \a y, \a w, \a h), \a pen, \a brush).
+*/
+
+/*!
+ Creates and adds a text item to the scene, and returns the item
+ pointer. The text string is initialized to \a text, and its font
+ is initialized to \a font.
+
+ The item's position is initialized to (0, 0).
+
+ If the item is visible (i.e., QGraphicsItem::isVisible() returns true),
+ QGraphicsScene will emit changed() once control goes back to the event
+ loop.
+
+ \sa addEllipse(), addLine(), addPixmap(), addPixmap(), addRect(),
+ addItem(), addWidget()
+*/
+QGraphicsTextItem *QGraphicsScene::addText(const QString &text, const QFont &font)
+{
+ QGraphicsTextItem *item = new QGraphicsTextItem(text);
+ item->setFont(font);
+ addItem(item);
+ return item;
+}
+
+/*!
+ Creates and adds a QGraphicsSimpleTextItem to the scene, and returns the
+ item pointer. The text string is initialized to \a text, and its font is
+ initialized to \a font.
+
+ The item's position is initialized to (0, 0).
+
+ If the item is visible (i.e., QGraphicsItem::isVisible() returns true),
+ QGraphicsScene will emit changed() once control goes back to the event
+ loop.
+
+ \sa addEllipse(), addLine(), addPixmap(), addPixmap(), addRect(),
+ addItem(), addWidget()
+*/
+QGraphicsSimpleTextItem *QGraphicsScene::addSimpleText(const QString &text, const QFont &font)
+{
+ QGraphicsSimpleTextItem *item = new QGraphicsSimpleTextItem(text);
+ item->setFont(font);
+ addItem(item);
+ return item;
+}
+
+/*!
+ Creates a new QGraphicsProxyWidget for \a widget, adds it to the scene,
+ and returns a pointer to the proxy. \a wFlags set the default window flags
+ for the embedding proxy widget.
+
+ The item's position is initialized to (0, 0).
+
+ If the item is visible (i.e., QGraphicsItem::isVisible() returns true),
+ QGraphicsScene will emit changed() once control goes back to the event
+ loop.
+
+ Note that widgets with the Qt::WA_PaintOnScreen widget attribute
+ set and widgets that wrap an external application or controller
+ are not supported. Examples are QGLWidget and QAxWidget.
+
+ \sa addEllipse(), addLine(), addPixmap(), addPixmap(), addRect(),
+ addText(), addSimpleText(), addItem()
+*/
+QGraphicsProxyWidget *QGraphicsScene::addWidget(QWidget *widget, Qt::WindowFlags wFlags)
+{
+ QGraphicsProxyWidget *proxy = new QGraphicsProxyWidget(0, wFlags);
+ proxy->setWidget(widget);
+ addItem(proxy);
+ return proxy;
+}
+
+/*!
+ Removes the item \a item and all its children from the scene. The
+ ownership of \a item is passed on to the caller (i.e.,
+ QGraphicsScene will no longer delete \a item when destroyed).
+
+ \sa addItem()
+*/
+void QGraphicsScene::removeItem(QGraphicsItem *item)
+{
+ // ### Refactoring: This function shares much functionality with _q_removeItemLater()
+ Q_D(QGraphicsScene);
+ if (!item) {
+ qWarning("QGraphicsScene::removeItem: cannot remove 0-item");
+ return;
+ }
+ if (item->scene() != this) {
+ qWarning("QGraphicsScene::removeItem: item %p's scene (%p)"
+ " is different from this scene (%p)",
+ item, item->scene(), this);
+ return;
+ }
+
+ // Notify the item that it's scene is changing to 0, allowing the item to
+ // react.
+ const QVariant newSceneVariant(item->itemChange(QGraphicsItem::ItemSceneChange,
+ QVariant::fromValue<QGraphicsScene *>(0)));
+ QGraphicsScene *targetScene = qvariant_cast<QGraphicsScene *>(newSceneVariant);
+ if (targetScene != 0 && targetScene != this) {
+ targetScene->addItem(item);
+ return;
+ }
+
+ d->removeItemHelper(item);
+
+ // Deliver post-change notification
+ item->itemChange(QGraphicsItem::ItemSceneHasChanged, newSceneVariant);
+
+ d->updateInputMethodSensitivityInViews();
+}
+
+/*!
+ When the scene is active, this functions returns the scene's current focus
+ item, or 0 if no item currently has focus. When the scene is inactive, this
+ functions returns the item that will gain input focus when the scene becomes
+ active.
+
+ The focus item receives keyboard input when the scene receives a
+ key event.
+
+ \sa setFocusItem(), QGraphicsItem::hasFocus(), isActive()
+*/
+QGraphicsItem *QGraphicsScene::focusItem() const
+{
+ Q_D(const QGraphicsScene);
+ return isActive() ? d->focusItem : d->passiveFocusItem;
+}
+
+/*!
+ Sets the scene's focus item to \a item, with the focus reason \a
+ focusReason, after removing focus from any previous item that may have had
+ focus.
+
+ If \a item is 0, or if it either does not accept focus (i.e., it does not
+ have the QGraphicsItem::ItemIsFocusable flag enabled), or is not visible
+ or not enabled, this function only removes focus from any previous
+ focusitem.
+
+ If item is not 0, and the scene does not currently have focus (i.e.,
+ hasFocus() returns false), this function will call setFocus()
+ automatically.
+
+ \sa focusItem(), hasFocus(), setFocus()
+*/
+void QGraphicsScene::setFocusItem(QGraphicsItem *item, Qt::FocusReason focusReason)
+{
+ Q_D(QGraphicsScene);
+ if (item)
+ item->setFocus(focusReason);
+ else
+ d->setFocusItemHelper(item, focusReason);
+}
+
+/*!
+ Returns true if the scene has focus; otherwise returns false. If the scene
+ has focus, it will will forward key events from QKeyEvent to any item that
+ has focus.
+
+ \sa setFocus(), setFocusItem()
+*/
+bool QGraphicsScene::hasFocus() const
+{
+ Q_D(const QGraphicsScene);
+ return d->hasFocus;
+}
+
+/*!
+ Sets focus on the scene by sending a QFocusEvent to the scene, passing \a
+ focusReason as the reason. If the scene regains focus after having
+ previously lost it while an item had focus, the last focus item will
+ receive focus with \a focusReason as the reason.
+
+ If the scene already has focus, this function does nothing.
+
+ \sa hasFocus(), clearFocus(), setFocusItem()
+*/
+void QGraphicsScene::setFocus(Qt::FocusReason focusReason)
+{
+ Q_D(QGraphicsScene);
+ if (d->hasFocus || !isActive())
+ return;
+ QFocusEvent event(QEvent::FocusIn, focusReason);
+ QCoreApplication::sendEvent(this, &event);
+}
+
+/*!
+ Clears focus from the scene. If any item has focus when this function is
+ called, it will lose focus, and regain focus again once the scene regains
+ focus.
+
+ A scene that does not have focus ignores key events.
+
+ \sa hasFocus(), setFocus(), setFocusItem()
+*/
+void QGraphicsScene::clearFocus()
+{
+ Q_D(QGraphicsScene);
+ if (d->hasFocus) {
+ d->hasFocus = false;
+ d->passiveFocusItem = d->focusItem;
+ setFocusItem(0, Qt::OtherFocusReason);
+ }
+}
+
+/*!
+ \property QGraphicsScene::stickyFocus
+ \brief whether clicking into the scene background will clear focus
+
+ \since 4.6
+
+ In a QGraphicsScene with stickyFocus set to true, focus will remain
+ unchanged when the user clicks into the scene background or on an item
+ that does not accept focus. Otherwise, focus will be cleared.
+
+ By default, this property is false.
+
+ Focus changes in response to a mouse press. You can reimplement
+ mousePressEvent() in a subclass of QGraphicsScene to toggle this property
+ based on where the user has clicked.
+
+ \sa clearFocus(), setFocusItem()
+*/
+void QGraphicsScene::setStickyFocus(bool enabled)
+{
+ Q_D(QGraphicsScene);
+ d->stickyFocus = enabled;
+}
+bool QGraphicsScene::stickyFocus() const
+{
+ Q_D(const QGraphicsScene);
+ return d->stickyFocus;
+}
+
+/*!
+ Returns the current mouse grabber item, or 0 if no item is currently
+ grabbing the mouse. The mouse grabber item is the item that receives all
+ mouse events sent to the scene.
+
+ An item becomes a mouse grabber when it receives and accepts a
+ mouse press event, and it stays the mouse grabber until either of
+ the following events occur:
+
+ \list
+ \o If the item receives a mouse release event when there are no other
+ buttons pressed, it loses the mouse grab.
+ \o If the item becomes invisible (i.e., someone calls \c {item->setVisible(false)}),
+ or if it becomes disabled (i.e., someone calls \c {item->setEnabled(false)}),
+ it loses the mouse grab.
+ \o If the item is removed from the scene, it loses the mouse grab.
+ \endlist
+
+ If the item loses its mouse grab, the scene will ignore all mouse events
+ until a new item grabs the mouse (i.e., until a new item receives a mouse
+ press event).
+*/
+QGraphicsItem *QGraphicsScene::mouseGrabberItem() const
+{
+ Q_D(const QGraphicsScene);
+ return !d->mouseGrabberItems.isEmpty() ? d->mouseGrabberItems.last() : 0;
+}
+
+/*!
+ \property QGraphicsScene::backgroundBrush
+ \brief the background brush of the scene.
+
+ Set this property to changes the scene's background to a different color,
+ gradient or texture. The default background brush is Qt::NoBrush. The
+ background is drawn before (behind) the items.
+
+ Example:
+
+ \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsscene.cpp 3
+
+ QGraphicsScene::render() calls drawBackground() to draw the scene
+ background. For more detailed control over how the background is drawn,
+ you can reimplement drawBackground() in a subclass of QGraphicsScene.
+*/
+QBrush QGraphicsScene::backgroundBrush() const
+{
+ Q_D(const QGraphicsScene);
+ return d->backgroundBrush;
+}
+void QGraphicsScene::setBackgroundBrush(const QBrush &brush)
+{
+ Q_D(QGraphicsScene);
+ d->backgroundBrush = brush;
+ foreach (QGraphicsView *view, d->views) {
+ view->resetCachedContent();
+ view->viewport()->update();
+ }
+ update();
+}
+
+/*!
+ \property QGraphicsScene::foregroundBrush
+ \brief the foreground brush of the scene.
+
+ Change this property to set the scene's foreground to a different
+ color, gradient or texture.
+
+ The foreground is drawn after (on top of) the items. The default
+ foreground brush is Qt::NoBrush ( i.e. the foreground is not
+ drawn).
+
+ Example:
+
+ \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsscene.cpp 4
+
+ QGraphicsScene::render() calls drawForeground() to draw the scene
+ foreground. For more detailed control over how the foreground is
+ drawn, you can reimplement the drawForeground() function in a
+ QGraphicsScene subclass.
+*/
+QBrush QGraphicsScene::foregroundBrush() const
+{
+ Q_D(const QGraphicsScene);
+ return d->foregroundBrush;
+}
+void QGraphicsScene::setForegroundBrush(const QBrush &brush)
+{
+ Q_D(QGraphicsScene);
+ d->foregroundBrush = brush;
+ foreach (QGraphicsView *view, views())
+ view->viewport()->update();
+ update();
+}
+
+/*!
+ This method is used by input methods to query a set of properties of
+ the scene to be able to support complex input method operations as support
+ for surrounding text and reconversions.
+
+ The \a query parameter specifies which property is queried.
+
+ \sa QWidget::inputMethodQuery()
+*/
+QVariant QGraphicsScene::inputMethodQuery(Qt::InputMethodQuery query) const
+{
+ Q_D(const QGraphicsScene);
+ if (!d->focusItem || !(d->focusItem->flags() & QGraphicsItem::ItemAcceptsInputMethod))
+ return QVariant();
+ const QTransform matrix = d->focusItem->sceneTransform();
+ QVariant value = d->focusItem->inputMethodQuery(query);
+ if (value.type() == QVariant::RectF)
+ value = matrix.mapRect(value.toRectF());
+ else if (value.type() == QVariant::PointF)
+ value = matrix.map(value.toPointF());
+ else if (value.type() == QVariant::Rect)
+ value = matrix.mapRect(value.toRect());
+ else if (value.type() == QVariant::Point)
+ value = matrix.map(value.toPoint());
+ return value;
+}
+
+/*!
+ \fn void QGraphicsScene::update(const QRectF &rect)
+ Schedules a redraw of the area \a rect on the scene.
+
+ \sa sceneRect(), changed()
+*/
+void QGraphicsScene::update(const QRectF &rect)
+{
+ Q_D(QGraphicsScene);
+ if (d->updateAll || (rect.isEmpty() && !rect.isNull()))
+ return;
+
+ // Check if anyone's connected; if not, we can send updates directly to
+ // the views. Otherwise or if there are no views, use old behavior.
+ bool directUpdates = !(d->isSignalConnected(d->changedSignalIndex)) && !d->views.isEmpty();
+ if (rect.isNull()) {
+ d->updateAll = true;
+ d->updatedRects.clear();
+ if (directUpdates) {
+ // Update all views.
+ for (int i = 0; i < d->views.size(); ++i)
+ d->views.at(i)->d_func()->fullUpdatePending = true;
+ }
+ } else {
+ if (directUpdates) {
+ // Update all views.
+ for (int i = 0; i < d->views.size(); ++i) {
+ QGraphicsView *view = d->views.at(i);
+ if (view->isTransformed())
+ view->d_func()->updateRectF(view->viewportTransform().mapRect(rect));
+ else
+ view->d_func()->updateRectF(rect);
+ }
+ } else {
+ d->updatedRects << rect;
+ }
+ }
+
+ if (!d->calledEmitUpdated) {
+ d->calledEmitUpdated = true;
+ QMetaObject::invokeMethod(this, "_q_emitUpdated", Qt::QueuedConnection);
+ }
+}
+
+/*!
+ \fn void QGraphicsScene::update(qreal x, qreal y, qreal w, qreal h)
+ \overload
+ \since 4.3
+
+ This function is equivalent to calling update(QRectF(\a x, \a y, \a w,
+ \a h));
+*/
+
+/*!
+ Invalidates and schedules a redraw of the \a layers in \a rect on the
+ scene. Any cached content in \a layers is unconditionally invalidated and
+ redrawn.
+
+ You can use this function overload to notify QGraphicsScene of changes to
+ the background or the foreground of the scene. This function is commonly
+ used for scenes with tile-based backgrounds to notify changes when
+ QGraphicsView has enabled
+ \l{QGraphicsView::CacheBackground}{CacheBackground}.
+
+ Example:
+
+ \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsscene.cpp 5
+
+ Note that QGraphicsView currently supports background caching only (see
+ QGraphicsView::CacheBackground). This function is equivalent to calling
+ update() if any layer but BackgroundLayer is passed.
+
+ \sa QGraphicsView::resetCachedContent()
+*/
+void QGraphicsScene::invalidate(const QRectF &rect, SceneLayers layers)
+{
+ foreach (QGraphicsView *view, views())
+ view->invalidateScene(rect, layers);
+ update(rect);
+}
+
+/*!
+ \fn void QGraphicsScene::invalidate(qreal x, qreal y, qreal w, qreal h, SceneLayers layers)
+ \overload
+ \since 4.3
+
+ This convenience function is equivalent to calling invalidate(QRectF(\a x, \a
+ y, \a w, \a h), \a layers);
+*/
+
+/*!
+ Returns a list of all the views that display this scene.
+
+ \sa QGraphicsView::scene()
+*/
+QList <QGraphicsView *> QGraphicsScene::views() const
+{
+ Q_D(const QGraphicsScene);
+ return d->views;
+}
+
+/*!
+ This slot \e advances the scene by one step, by calling
+ QGraphicsItem::advance() for all items on the scene. This is done in two
+ phases: in the first phase, all items are notified that the scene is about
+ to change, and in the second phase all items are notified that they can
+ move. In the first phase, QGraphicsItem::advance() is called passing a
+ value of 0 as an argument, and 1 is passed in the second phase.
+
+ \sa QGraphicsItem::advance(), QGraphicsItemAnimation, QTimeLine
+*/
+void QGraphicsScene::advance()
+{
+ for (int i = 0; i < 2; ++i) {
+ foreach (QGraphicsItem *item, items())
+ item->advance(i);
+ }
+}
+
+/*!
+ Processes the event \a event, and dispatches it to the respective
+ event handlers.
+
+ In addition to calling the convenience event handlers, this
+ function is responsible for converting mouse move events to hover
+ events for when there is no mouse grabber item. Hover events are
+ delivered directly to items; there is no convenience function for
+ them.
+
+ Unlike QWidget, QGraphicsScene does not have the convenience functions
+ \l{QWidget::}{enterEvent()} and \l{QWidget::}{leaveEvent()}. Use this
+ function to obtain those events instead.
+
+ \sa contextMenuEvent(), keyPressEvent(), keyReleaseEvent(),
+ mousePressEvent(), mouseMoveEvent(), mouseReleaseEvent(),
+ mouseDoubleClickEvent(), focusInEvent(), focusOutEvent()
+*/
+bool QGraphicsScene::event(QEvent *event)
+{
+ Q_D(QGraphicsScene);
+
+ switch (event->type()) {
+ case QEvent::GraphicsSceneMousePress:
+ case QEvent::GraphicsSceneMouseMove:
+ case QEvent::GraphicsSceneMouseRelease:
+ case QEvent::GraphicsSceneMouseDoubleClick:
+ case QEvent::GraphicsSceneHoverEnter:
+ case QEvent::GraphicsSceneHoverLeave:
+ case QEvent::GraphicsSceneHoverMove:
+ case QEvent::TouchBegin:
+ case QEvent::TouchUpdate:
+ case QEvent::TouchEnd:
+ // Reset the under-mouse list to ensure that this event gets fresh
+ // item-under-mouse data. Be careful about this list; if people delete
+ // items from inside event handlers, this list can quickly end up
+ // having stale pointers in it. We need to clear it before dispatching
+ // events that use it.
+ // ### this should only be cleared if we received a new mouse move event,
+ // which relies on us fixing the replay mechanism in QGraphicsView.
+ d->cachedItemsUnderMouse.clear();
+ default:
+ break;
+ }
+
+ switch (event->type()) {
+ case QEvent::GraphicsSceneDragEnter:
+ dragEnterEvent(static_cast<QGraphicsSceneDragDropEvent *>(event));
+ break;
+ case QEvent::GraphicsSceneDragMove:
+ dragMoveEvent(static_cast<QGraphicsSceneDragDropEvent *>(event));
+ break;
+ case QEvent::GraphicsSceneDragLeave:
+ dragLeaveEvent(static_cast<QGraphicsSceneDragDropEvent *>(event));
+ break;
+ case QEvent::GraphicsSceneDrop:
+ dropEvent(static_cast<QGraphicsSceneDragDropEvent *>(event));
+ break;
+ case QEvent::GraphicsSceneContextMenu:
+ contextMenuEvent(static_cast<QGraphicsSceneContextMenuEvent *>(event));
+ break;
+ case QEvent::KeyPress:
+ if (!d->focusItem) {
+ QKeyEvent *k = static_cast<QKeyEvent *>(event);
+ if (k->key() == Qt::Key_Tab || k->key() == Qt::Key_Backtab) {
+ if (!(k->modifiers() & (Qt::ControlModifier | Qt::AltModifier))) { //### Add MetaModifier?
+ bool res = false;
+ if (k->key() == Qt::Key_Backtab
+ || (k->key() == Qt::Key_Tab && (k->modifiers() & Qt::ShiftModifier))) {
+ res = focusNextPrevChild(false);
+ } else if (k->key() == Qt::Key_Tab) {
+ res = focusNextPrevChild(true);
+ }
+ if (!res)
+ event->ignore();
+ return true;
+ }
+ }
+ }
+ keyPressEvent(static_cast<QKeyEvent *>(event));
+ break;
+ case QEvent::KeyRelease:
+ keyReleaseEvent(static_cast<QKeyEvent *>(event));
+ break;
+ case QEvent::ShortcutOverride: {
+ QGraphicsItem *parent = focusItem();
+ while (parent) {
+ d->sendEvent(parent, event);
+ if (event->isAccepted())
+ return true;
+ parent = parent->parentItem();
+ }
+ }
+ return false;
+ case QEvent::GraphicsSceneMouseMove:
+ {
+ QGraphicsSceneMouseEvent *mouseEvent = static_cast<QGraphicsSceneMouseEvent *>(event);
+ d->lastSceneMousePos = mouseEvent->scenePos();
+ mouseMoveEvent(mouseEvent);
+ break;
+ }
+ case QEvent::GraphicsSceneMousePress:
+ mousePressEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
+ break;
+ case QEvent::GraphicsSceneMouseRelease:
+ mouseReleaseEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
+ break;
+ case QEvent::GraphicsSceneMouseDoubleClick:
+ mouseDoubleClickEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
+ break;
+ case QEvent::GraphicsSceneWheel:
+ wheelEvent(static_cast<QGraphicsSceneWheelEvent *>(event));
+ break;
+ case QEvent::FocusIn:
+ focusInEvent(static_cast<QFocusEvent *>(event));
+ break;
+ case QEvent::FocusOut:
+ focusOutEvent(static_cast<QFocusEvent *>(event));
+ break;
+ case QEvent::GraphicsSceneHoverEnter:
+ case QEvent::GraphicsSceneHoverLeave:
+ case QEvent::GraphicsSceneHoverMove:
+ {
+ QGraphicsSceneHoverEvent *hoverEvent = static_cast<QGraphicsSceneHoverEvent *>(event);
+ d->lastSceneMousePos = hoverEvent->scenePos();
+ d->dispatchHoverEvent(hoverEvent);
+ break;
+ }
+ case QEvent::Leave:
+ // hackieshly unpacking the viewport pointer from the leave event.
+ d->leaveScene(reinterpret_cast<QWidget *>(event->d));
+ break;
+ case QEvent::GraphicsSceneHelp:
+ helpEvent(static_cast<QGraphicsSceneHelpEvent *>(event));
+ break;
+ case QEvent::InputMethod:
+ inputMethodEvent(static_cast<QInputMethodEvent *>(event));
+ break;
+ case QEvent::WindowActivate:
+ if (!d->activationRefCount++) {
+ if (d->lastActivePanel) {
+ // Activate the last panel.
+ d->setActivePanelHelper(d->lastActivePanel, true);
+ } else if (d->tabFocusFirst && d->tabFocusFirst->isPanel()) {
+ // Activate the panel of the first item in the tab focus
+ // chain.
+ d->setActivePanelHelper(d->tabFocusFirst, true);
+ } else {
+ // Activate all toplevel items.
+ QEvent event(QEvent::WindowActivate);
+ foreach (QGraphicsItem *item, items()) {
+ if (item->isVisible() && !item->isPanel() && !item->parentItem())
+ sendEvent(item, &event);
+ }
+ }
+ }
+ break;
+ case QEvent::WindowDeactivate:
+ if (!--d->activationRefCount) {
+ if (d->activePanel) {
+ // Deactivate the active panel (but keep it so we can
+ // reactivate it later).
+ QGraphicsItem *lastActivePanel = d->activePanel;
+ d->setActivePanelHelper(0, true);
+ d->lastActivePanel = lastActivePanel;
+ } else {
+ // Activate all toplevel items.
+ QEvent event(QEvent::WindowDeactivate);
+ foreach (QGraphicsItem *item, items()) {
+ if (item->isVisible() && !item->isPanel() && !item->parentItem())
+ sendEvent(item, &event);
+ }
+ }
+ }
+ break;
+ case QEvent::ApplicationFontChange: {
+ // Resolve the existing scene font.
+ d->resolveFont();
+ break;
+ }
+ case QEvent::FontChange:
+ // Update the entire scene when the font changes.
+ update();
+ break;
+ case QEvent::ApplicationPaletteChange: {
+ // Resolve the existing scene palette.
+ d->resolvePalette();
+ break;
+ }
+ case QEvent::PaletteChange:
+ // Update the entire scene when the palette changes.
+ update();
+ break;
+ case QEvent::StyleChange:
+ // Reresolve all widgets' styles. Update all top-level widgets'
+ // geometries that do not have an explicit style set.
+ update();
+ break;
+ case QEvent::TouchBegin:
+ case QEvent::TouchUpdate:
+ case QEvent::TouchEnd:
+ d->touchEventHandler(static_cast<QTouchEvent *>(event));
+ break;
+#ifndef QT_NO_GESTURES
+ case QEvent::Gesture:
+ case QEvent::GestureOverride:
+ d->gestureEventHandler(static_cast<QGestureEvent *>(event));
+ break;
+#endif // QT_NO_GESTURES
+ default:
+ return QObject::event(event);
+ }
+ return true;
+}
+
+/*!
+ \reimp
+
+ QGraphicsScene filters QApplication's events to detect palette and font
+ changes.
+*/
+bool QGraphicsScene::eventFilter(QObject *watched, QEvent *event)
+{
+ if (watched != qApp)
+ return false;
+
+ switch (event->type()) {
+ case QEvent::ApplicationPaletteChange:
+ QApplication::postEvent(this, new QEvent(QEvent::ApplicationPaletteChange));
+ break;
+ case QEvent::ApplicationFontChange:
+ QApplication::postEvent(this, new QEvent(QEvent::ApplicationFontChange));
+ break;
+ default:
+ break;
+ }
+ return false;
+}
+
+/*!
+ This event handler, for event \a contextMenuEvent, can be reimplemented in
+ a subclass to receive context menu events. The default implementation
+ forwards the event to the topmost item that accepts context menu events at
+ the position of the event. If no items accept context menu events at this
+ position, the event is ignored.
+
+ \sa QGraphicsItem::contextMenuEvent()
+*/
+void QGraphicsScene::contextMenuEvent(QGraphicsSceneContextMenuEvent *contextMenuEvent)
+{
+ Q_D(QGraphicsScene);
+ // Ignore by default.
+ contextMenuEvent->ignore();
+
+ // Send the event to all items at this position until one item accepts the
+ // event.
+ foreach (QGraphicsItem *item, d->itemsAtPosition(contextMenuEvent->screenPos(),
+ contextMenuEvent->scenePos(),
+ contextMenuEvent->widget())) {
+ contextMenuEvent->setPos(item->d_ptr->genericMapFromScene(contextMenuEvent->scenePos(),
+ contextMenuEvent->widget()));
+ contextMenuEvent->accept();
+ if (!d->sendEvent(item, contextMenuEvent))
+ break;
+
+ if (contextMenuEvent->isAccepted())
+ break;
+ }
+}
+
+/*!
+ This event handler, for event \a event, can be reimplemented in a subclass
+ to receive drag enter events for the scene.
+
+ The default implementation accepts the event and prepares the scene to
+ accept drag move events.
+
+ \sa QGraphicsItem::dragEnterEvent(), dragMoveEvent(), dragLeaveEvent(),
+ dropEvent()
+*/
+void QGraphicsScene::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
+{
+ Q_D(QGraphicsScene);
+ d->dragDropItem = 0;
+ d->lastDropAction = Qt::IgnoreAction;
+ event->accept();
+}
+
+/*!
+ This event handler, for event \a event, can be reimplemented in a subclass
+ to receive drag move events for the scene.
+
+ \sa QGraphicsItem::dragMoveEvent(), dragEnterEvent(), dragLeaveEvent(),
+ dropEvent()
+*/
+void QGraphicsScene::dragMoveEvent(QGraphicsSceneDragDropEvent *event)
+{
+ Q_D(QGraphicsScene);
+ event->ignore();
+
+ if (!d->mouseGrabberItems.isEmpty()) {
+ // Mouse grabbers that start drag events lose the mouse grab.
+ d->clearMouseGrabber();
+ d->mouseGrabberButtonDownPos.clear();
+ d->mouseGrabberButtonDownScenePos.clear();
+ d->mouseGrabberButtonDownScreenPos.clear();
+ }
+
+ bool eventDelivered = false;
+
+ // Find the topmost enabled items under the cursor. They are all
+ // candidates for accepting drag & drop events.
+ foreach (QGraphicsItem *item, d->itemsAtPosition(event->screenPos(),
+ event->scenePos(),
+ event->widget())) {
+ if (!item->isEnabled() || !item->acceptDrops())
+ continue;
+
+ if (item != d->dragDropItem) {
+ // Enter the new drag drop item. If it accepts the event, we send
+ // the leave to the parent item.
+ QGraphicsSceneDragDropEvent dragEnter(QEvent::GraphicsSceneDragEnter);
+ d->cloneDragDropEvent(&dragEnter, event);
+ dragEnter.setDropAction(event->proposedAction());
+ d->sendDragDropEvent(item, &dragEnter);
+ event->setAccepted(dragEnter.isAccepted());
+ event->setDropAction(dragEnter.dropAction());
+ if (!event->isAccepted()) {
+ // Propagate to the item under
+ continue;
+ }
+
+ d->lastDropAction = event->dropAction();
+
+ if (d->dragDropItem) {
+ // Leave the last drag drop item. A perfect implementation
+ // would set the position of this event to the point where
+ // this event and the last event intersect with the item's
+ // shape, but that's not easy to do. :-)
+ QGraphicsSceneDragDropEvent dragLeave(QEvent::GraphicsSceneDragLeave);
+ d->cloneDragDropEvent(&dragLeave, event);
+ d->sendDragDropEvent(d->dragDropItem, &dragLeave);
+ }
+
+ // We've got a new drag & drop item
+ d->dragDropItem = item;
+ }
+
+ // Send the move event.
+ event->setDropAction(d->lastDropAction);
+ event->accept();
+ d->sendDragDropEvent(item, event);
+ if (event->isAccepted())
+ d->lastDropAction = event->dropAction();
+ eventDelivered = true;
+ break;
+ }
+
+ if (!eventDelivered) {
+ if (d->dragDropItem) {
+ // Leave the last drag drop item
+ QGraphicsSceneDragDropEvent dragLeave(QEvent::GraphicsSceneDragLeave);
+ d->cloneDragDropEvent(&dragLeave, event);
+ d->sendDragDropEvent(d->dragDropItem, &dragLeave);
+ d->dragDropItem = 0;
+ }
+ // Propagate
+ event->setDropAction(Qt::IgnoreAction);
+ }
+}
+
+/*!
+ This event handler, for event \a event, can be reimplemented in a subclass
+ to receive drag leave events for the scene.
+
+ \sa QGraphicsItem::dragLeaveEvent(), dragEnterEvent(), dragMoveEvent(),
+ dropEvent()
+*/
+void QGraphicsScene::dragLeaveEvent(QGraphicsSceneDragDropEvent *event)
+{
+ Q_D(QGraphicsScene);
+ if (d->dragDropItem) {
+ // Leave the last drag drop item
+ d->sendDragDropEvent(d->dragDropItem, event);
+ d->dragDropItem = 0;
+ }
+}
+
+/*!
+ This event handler, for event \a event, can be reimplemented in a subclass
+ to receive drop events for the scene.
+
+ \sa QGraphicsItem::dropEvent(), dragEnterEvent(), dragMoveEvent(),
+ dragLeaveEvent()
+*/
+void QGraphicsScene::dropEvent(QGraphicsSceneDragDropEvent *event)
+{
+ Q_UNUSED(event);
+ Q_D(QGraphicsScene);
+ if (d->dragDropItem) {
+ // Drop on the last drag drop item
+ d->sendDragDropEvent(d->dragDropItem, event);
+ d->dragDropItem = 0;
+ }
+}
+
+/*!
+ This event handler, for event \a focusEvent, can be reimplemented in a
+ subclass to receive focus in events.
+
+ The default implementation sets focus on the scene, and then on the last
+ focus item.
+
+ \sa QGraphicsItem::focusOutEvent()
+*/
+void QGraphicsScene::focusInEvent(QFocusEvent *focusEvent)
+{
+ Q_D(QGraphicsScene);
+
+ d->hasFocus = true;
+ switch (focusEvent->reason()) {
+ case Qt::TabFocusReason:
+ if (!focusNextPrevChild(true))
+ focusEvent->ignore();
+ break;
+ case Qt::BacktabFocusReason:
+ if (!focusNextPrevChild(false))
+ focusEvent->ignore();
+ break;
+ default:
+ if (d->passiveFocusItem) {
+ // Set focus on the last focus item
+ setFocusItem(d->passiveFocusItem, focusEvent->reason());
+ }
+ break;
+ }
+}
+
+/*!
+ This event handler, for event \a focusEvent, can be reimplemented in a
+ subclass to receive focus out events.
+
+ The default implementation removes focus from any focus item, then removes
+ focus from the scene.
+
+ \sa QGraphicsItem::focusInEvent()
+*/
+void QGraphicsScene::focusOutEvent(QFocusEvent *focusEvent)
+{
+ Q_D(QGraphicsScene);
+ d->hasFocus = false;
+ d->passiveFocusItem = d->focusItem;
+ setFocusItem(0, focusEvent->reason());
+
+ // Remove all popups when the scene loses focus.
+ if (!d->popupWidgets.isEmpty())
+ d->removePopup(d->popupWidgets.first());
+}
+
+/*!
+ This event handler, for event \a helpEvent, can be
+ reimplemented in a subclass to receive help events. The events
+ are of type QEvent::ToolTip, which are created when a tooltip is
+ requested.
+
+ The default implementation shows the tooltip of the topmost
+ item, i.e., the item with the highest z-value, at the mouse
+ cursor position. If no item has a tooltip set, this function
+ does nothing.
+
+ \sa QGraphicsItem::toolTip(), QGraphicsSceneHelpEvent
+*/
+void QGraphicsScene::helpEvent(QGraphicsSceneHelpEvent *helpEvent)
+{
+#ifdef QT_NO_TOOLTIP
+ Q_UNUSED(helpEvent);
+#else
+ // Find the first item that does tooltips
+ Q_D(QGraphicsScene);
+ QList<QGraphicsItem *> itemsAtPos = d->itemsAtPosition(helpEvent->screenPos(),
+ helpEvent->scenePos(),
+ helpEvent->widget());
+ QGraphicsItem *toolTipItem = 0;
+ for (int i = 0; i < itemsAtPos.size(); ++i) {
+ QGraphicsItem *tmp = itemsAtPos.at(i);
+ if (tmp->d_func()->isProxyWidget()) {
+ // if the item is a proxy widget, the event is forwarded to it
+ sendEvent(tmp, helpEvent);
+ if (helpEvent->isAccepted())
+ return;
+ }
+ if (!tmp->toolTip().isEmpty()) {
+ toolTipItem = tmp;
+ break;
+ }
+ }
+
+ // Show or hide the tooltip
+ QString text;
+ QPoint point;
+ if (toolTipItem && !toolTipItem->toolTip().isEmpty()) {
+ text = toolTipItem->toolTip();
+ point = helpEvent->screenPos();
+ }
+ QToolTip::showText(point, text, helpEvent->widget());
+ helpEvent->setAccepted(!text.isEmpty());
+#endif
+}
+
+bool QGraphicsScenePrivate::itemAcceptsHoverEvents_helper(const QGraphicsItem *item) const
+{
+ return (item->d_ptr->acceptsHover
+ || (item->d_ptr->isWidget
+ && static_cast<const QGraphicsWidget *>(item)->d_func()->hasDecoration()))
+ && !item->isBlockedByModalPanel();
+}
+
+/*!
+ This event handler, for event \a hoverEvent, can be reimplemented in a
+ subclass to receive hover enter events. The default implementation
+ forwards the event to the topmost item that accepts hover events at the
+ scene position from the event.
+
+ \sa QGraphicsItem::hoverEvent(), QGraphicsItem::setAcceptHoverEvents()
+*/
+bool QGraphicsScenePrivate::dispatchHoverEvent(QGraphicsSceneHoverEvent *hoverEvent)
+{
+ if (allItemsIgnoreHoverEvents)
+ return false;
+
+ // Find the first item that accepts hover events, reusing earlier
+ // calculated data is possible.
+ if (cachedItemsUnderMouse.isEmpty()) {
+ cachedItemsUnderMouse = itemsAtPosition(hoverEvent->screenPos(),
+ hoverEvent->scenePos(),
+ hoverEvent->widget());
+ }
+
+ QGraphicsItem *item = 0;
+ for (int i = 0; i < cachedItemsUnderMouse.size(); ++i) {
+ QGraphicsItem *tmp = cachedItemsUnderMouse.at(i);
+ if (itemAcceptsHoverEvents_helper(tmp)) {
+ item = tmp;
+ break;
+ }
+ }
+
+ // Find the common ancestor item for the new topmost hoverItem and the
+ // last item in the hoverItem list.
+ QGraphicsItem *commonAncestorItem = (item && !hoverItems.isEmpty()) ? item->commonAncestorItem(hoverItems.last()) : 0;
+ while (commonAncestorItem && !itemAcceptsHoverEvents_helper(commonAncestorItem))
+ commonAncestorItem = commonAncestorItem->parentItem();
+ if (commonAncestorItem && commonAncestorItem->panel() != item->panel()) {
+ // The common ancestor isn't in the same panel as the two hovered
+ // items.
+ commonAncestorItem = 0;
+ }
+
+ // Check if the common ancestor item is known.
+ int index = commonAncestorItem ? hoverItems.indexOf(commonAncestorItem) : -1;
+ // Send hover leaves to any existing hovered children of the common
+ // ancestor item.
+ for (int i = hoverItems.size() - 1; i > index; --i) {
+ QGraphicsItem *lastItem = hoverItems.takeLast();
+ if (itemAcceptsHoverEvents_helper(lastItem))
+ sendHoverEvent(QEvent::GraphicsSceneHoverLeave, lastItem, hoverEvent);
+ }
+
+ // Item is a child of a known item. Generate enter events for the
+ // missing links.
+ QList<QGraphicsItem *> parents;
+ QGraphicsItem *parent = item;
+ while (parent && parent != commonAncestorItem) {
+ parents.prepend(parent);
+ if (parent->isPanel()) {
+ // Stop at the panel - we don't deliver beyond this point.
+ break;
+ }
+ parent = parent->parentItem();
+ }
+ for (int i = 0; i < parents.size(); ++i) {
+ parent = parents.at(i);
+ hoverItems << parent;
+ if (itemAcceptsHoverEvents_helper(parent))
+ sendHoverEvent(QEvent::GraphicsSceneHoverEnter, parent, hoverEvent);
+ }
+
+ // Generate a move event for the item itself
+ if (item
+ && !hoverItems.isEmpty()
+ && item == hoverItems.last()) {
+ sendHoverEvent(QEvent::GraphicsSceneHoverMove, item, hoverEvent);
+ return true;
+ }
+ return false;
+}
+
+/*!
+ \internal
+
+ Handles all actions necessary to clean up the scene when the mouse leaves
+ the view.
+*/
+void QGraphicsScenePrivate::leaveScene(QWidget *viewport)
+{
+#ifndef QT_NO_TOOLTIP
+ QToolTip::hideText();
+#endif
+ QGraphicsView *view = qobject_cast<QGraphicsView *>(viewport->parent());
+ // Send HoverLeave events to all existing hover items, topmost first.
+ QGraphicsSceneHoverEvent hoverEvent;
+ hoverEvent.setWidget(viewport);
+
+ if (view) {
+ QPoint cursorPos = QCursor::pos();
+ hoverEvent.setScenePos(view->mapToScene(viewport->mapFromGlobal(cursorPos)));
+ hoverEvent.setLastScenePos(hoverEvent.scenePos());
+ hoverEvent.setScreenPos(cursorPos);
+ hoverEvent.setLastScreenPos(hoverEvent.screenPos());
+ }
+
+ while (!hoverItems.isEmpty()) {
+ QGraphicsItem *lastItem = hoverItems.takeLast();
+ if (itemAcceptsHoverEvents_helper(lastItem))
+ sendHoverEvent(QEvent::GraphicsSceneHoverLeave, lastItem, &hoverEvent);
+ }
+}
+
+/*!
+ This event handler, for event \a keyEvent, can be reimplemented in a
+ subclass to receive keypress events. The default implementation forwards
+ the event to current focus item.
+
+ \sa QGraphicsItem::keyPressEvent(), focusItem()
+*/
+void QGraphicsScene::keyPressEvent(QKeyEvent *keyEvent)
+{
+ // ### Merge this function with keyReleaseEvent; they are identical
+ // ### (except this comment).
+ Q_D(QGraphicsScene);
+ QGraphicsItem *item = !d->keyboardGrabberItems.isEmpty() ? d->keyboardGrabberItems.last() : 0;
+ if (!item)
+ item = focusItem();
+ if (item) {
+ QGraphicsItem *p = item;
+ do {
+ // Accept the event by default
+ keyEvent->accept();
+ // Send it; QGraphicsItem::keyPressEvent ignores it. If the event
+ // is filtered out, stop propagating it.
+ if (p->isBlockedByModalPanel())
+ break;
+ if (!d->sendEvent(p, keyEvent))
+ break;
+ } while (!keyEvent->isAccepted() && !p->isPanel() && (p = p->parentItem()));
+ } else {
+ keyEvent->ignore();
+ }
+}
+
+/*!
+ This event handler, for event \a keyEvent, can be reimplemented in a
+ subclass to receive key release events. The default implementation
+ forwards the event to current focus item.
+
+ \sa QGraphicsItem::keyReleaseEvent(), focusItem()
+*/
+void QGraphicsScene::keyReleaseEvent(QKeyEvent *keyEvent)
+{
+ // ### Merge this function with keyPressEvent; they are identical (except
+ // ### this comment).
+ Q_D(QGraphicsScene);
+ QGraphicsItem *item = !d->keyboardGrabberItems.isEmpty() ? d->keyboardGrabberItems.last() : 0;
+ if (!item)
+ item = focusItem();
+ if (item) {
+ QGraphicsItem *p = item;
+ do {
+ // Accept the event by default
+ keyEvent->accept();
+ // Send it; QGraphicsItem::keyPressEvent ignores it. If the event
+ // is filtered out, stop propagating it.
+ if (p->isBlockedByModalPanel())
+ break;
+ if (!d->sendEvent(p, keyEvent))
+ break;
+ } while (!keyEvent->isAccepted() && !p->isPanel() && (p = p->parentItem()));
+ } else {
+ keyEvent->ignore();
+ }
+}
+
+/*!
+ This event handler, for event \a mouseEvent, can be reimplemented
+ in a subclass to receive mouse press events for the scene.
+
+ The default implementation depends on the state of the scene. If
+ there is a mouse grabber item, then the event is sent to the mouse
+ grabber. Otherwise, it is forwarded to the topmost item that
+ accepts mouse events at the scene position from the event, and
+ that item promptly becomes the mouse grabber item.
+
+ If there is no item at the given position on the scene, the
+ selection area is reset, any focus item loses its input focus, and
+ the event is then ignored.
+
+ \sa QGraphicsItem::mousePressEvent(),
+ QGraphicsItem::setAcceptedMouseButtons()
+*/
+void QGraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
+{
+ Q_D(QGraphicsScene);
+ if (d->mouseGrabberItems.isEmpty()) {
+ // Dispatch hover events
+ QGraphicsSceneHoverEvent hover;
+ _q_hoverFromMouseEvent(&hover, mouseEvent);
+ d->dispatchHoverEvent(&hover);
+ }
+
+ d->mousePressEventHandler(mouseEvent);
+}
+
+/*!
+ This event handler, for event \a mouseEvent, can be reimplemented
+ in a subclass to receive mouse move events for the scene.
+
+ The default implementation depends on the mouse grabber state. If there is
+ a mouse grabber item, the event is sent to the mouse grabber. If there
+ are any items that accept hover events at the current position, the event
+ is translated into a hover event and accepted; otherwise it's ignored.
+
+ \sa QGraphicsItem::mousePressEvent(), QGraphicsItem::mouseReleaseEvent(),
+ QGraphicsItem::mouseDoubleClickEvent(), QGraphicsItem::setAcceptedMouseButtons()
+*/
+void QGraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent)
+{
+ Q_D(QGraphicsScene);
+ if (d->mouseGrabberItems.isEmpty()) {
+ if (mouseEvent->buttons())
+ return;
+ QGraphicsSceneHoverEvent hover;
+ _q_hoverFromMouseEvent(&hover, mouseEvent);
+ mouseEvent->setAccepted(d->dispatchHoverEvent(&hover));
+ return;
+ }
+
+ // Forward the event to the mouse grabber
+ d->sendMouseEvent(mouseEvent);
+ mouseEvent->accept();
+}
+
+/*!
+ This event handler, for event \a mouseEvent, can be reimplemented
+ in a subclass to receive mouse release events for the scene.
+
+ The default implementation depends on the mouse grabber state. If
+ there is no mouse grabber, the event is ignored. Otherwise, if
+ there is a mouse grabber item, the event is sent to the mouse
+ grabber. If this mouse release represents the last pressed button
+ on the mouse, the mouse grabber item then loses the mouse grab.
+
+ \sa QGraphicsItem::mousePressEvent(), QGraphicsItem::mouseMoveEvent(),
+ QGraphicsItem::mouseDoubleClickEvent(), QGraphicsItem::setAcceptedMouseButtons()
+*/
+void QGraphicsScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent)
+{
+ Q_D(QGraphicsScene);
+ if (d->mouseGrabberItems.isEmpty()) {
+ mouseEvent->ignore();
+ return;
+ }
+
+ // Forward the event to the mouse grabber
+ d->sendMouseEvent(mouseEvent);
+ mouseEvent->accept();
+
+ // Reset the mouse grabber when the last mouse button has been released.
+ if (!mouseEvent->buttons()) {
+ if (!d->mouseGrabberItems.isEmpty()) {
+ d->lastMouseGrabberItem = d->mouseGrabberItems.last();
+ if (d->lastMouseGrabberItemHasImplicitMouseGrab)
+ d->mouseGrabberItems.last()->ungrabMouse();
+ } else {
+ d->lastMouseGrabberItem = 0;
+ }
+
+ // Generate a hoverevent
+ QGraphicsSceneHoverEvent hoverEvent;
+ _q_hoverFromMouseEvent(&hoverEvent, mouseEvent);
+ d->dispatchHoverEvent(&hoverEvent);
+ }
+}
+
+/*!
+ This event handler, for event \a mouseEvent, can be reimplemented
+ in a subclass to receive mouse doubleclick events for the scene.
+
+ If someone doubleclicks on the scene, the scene will first receive
+ a mouse press event, followed by a release event (i.e., a click),
+ then a doubleclick event, and finally a release event. If the
+ doubleclick event is delivered to a different item than the one
+ that received the first press and release, it will be delivered as
+ a press event. However, tripleclick events are not delivered as
+ doubleclick events in this case.
+
+ The default implementation is similar to mousePressEvent().
+
+ \sa QGraphicsItem::mousePressEvent(), QGraphicsItem::mouseMoveEvent(),
+ QGraphicsItem::mouseReleaseEvent(), QGraphicsItem::setAcceptedMouseButtons()
+*/
+void QGraphicsScene::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *mouseEvent)
+{
+ Q_D(QGraphicsScene);
+ d->mousePressEventHandler(mouseEvent);
+}
+
+/*!
+ This event handler, for event \a wheelEvent, can be reimplemented in a
+ subclass to receive mouse wheel events for the scene.
+
+ By default, the event is delivered to the topmost visible item under the
+ cursor. If ignored, the event propagates to the item beneath, and again
+ until the event is accepted, or it reaches the scene. If no items accept
+ the event, it is ignored.
+
+ \sa QGraphicsItem::wheelEvent()
+*/
+void QGraphicsScene::wheelEvent(QGraphicsSceneWheelEvent *wheelEvent)
+{
+ Q_D(QGraphicsScene);
+ QList<QGraphicsItem *> wheelCandidates = d->itemsAtPosition(wheelEvent->screenPos(),
+ wheelEvent->scenePos(),
+ wheelEvent->widget());
+
+#ifdef Q_WS_MAC
+ // On Mac, ignore the event if the first item under the mouse is not the last opened
+ // popup (or one of its descendant)
+ if (!d->popupWidgets.isEmpty() && !wheelCandidates.isEmpty() && wheelCandidates.first() != d->popupWidgets.back() && !d->popupWidgets.back()->isAncestorOf(wheelCandidates.first())) {
+ wheelEvent->accept();
+ return;
+ }
+#else
+ // Find the first popup under the mouse (including the popup's descendants) starting from the last.
+ // Remove all popups after the one found, or all or them if no popup is under the mouse.
+ // Then continue with the event.
+ QList<QGraphicsWidget *>::const_iterator iter = d->popupWidgets.end();
+ while (--iter >= d->popupWidgets.begin() && !wheelCandidates.isEmpty()) {
+ if (wheelCandidates.first() == *iter || (*iter)->isAncestorOf(wheelCandidates.first()))
+ break;
+ d->removePopup(*iter);
+ }
+#endif
+
+ bool hasSetFocus = false;
+ foreach (QGraphicsItem *item, wheelCandidates) {
+ if (!hasSetFocus && item->isEnabled()
+ && ((item->flags() & QGraphicsItem::ItemIsFocusable) && item->d_ptr->mouseSetsFocus)) {
+ if (item->isWidget() && static_cast<QGraphicsWidget *>(item)->focusPolicy() == Qt::WheelFocus) {
+ hasSetFocus = true;
+ if (item != focusItem())
+ setFocusItem(item, Qt::MouseFocusReason);
+ }
+ }
+
+ wheelEvent->setPos(item->d_ptr->genericMapFromScene(wheelEvent->scenePos(),
+ wheelEvent->widget()));
+ wheelEvent->accept();
+ bool isPanel = item->isPanel();
+ d->sendEvent(item, wheelEvent);
+ if (isPanel || wheelEvent->isAccepted())
+ break;
+ }
+}
+
+/*!
+ This event handler, for event \a event, can be reimplemented in a
+ subclass to receive input method events for the scene.
+
+ The default implementation forwards the event to the focusItem().
+ If no item currently has focus or the current focus item does not
+ accept input methods, this function does nothing.
+
+ \sa QGraphicsItem::inputMethodEvent()
+*/
+void QGraphicsScene::inputMethodEvent(QInputMethodEvent *event)
+{
+ Q_D(QGraphicsScene);
+ if (d->focusItem && (d->focusItem->flags() & QGraphicsItem::ItemAcceptsInputMethod))
+ d->sendEvent(d->focusItem, event);
+}
+
+/*!
+ Draws the background of the scene using \a painter, before any items and
+ the foreground are drawn. Reimplement this function to provide a custom
+ background for the scene.
+
+ All painting is done in \e scene coordinates. The \a rect
+ parameter is the exposed rectangle.
+
+ If all you want is to define a color, texture, or gradient for the
+ background, you can call setBackgroundBrush() instead.
+
+ \sa drawForeground(), drawItems()
+*/
+void QGraphicsScene::drawBackground(QPainter *painter, const QRectF &rect)
+{
+ Q_D(QGraphicsScene);
+
+ if (d->backgroundBrush.style() != Qt::NoBrush) {
+ if (d->painterStateProtection)
+ painter->save();
+ painter->setBrushOrigin(0, 0);
+ painter->fillRect(rect, backgroundBrush());
+ if (d->painterStateProtection)
+ painter->restore();
+ }
+}
+
+/*!
+ Draws the foreground of the scene using \a painter, after the background
+ and all items have been drawn. Reimplement this function to provide a
+ custom foreground for the scene.
+
+ All painting is done in \e scene coordinates. The \a rect
+ parameter is the exposed rectangle.
+
+ If all you want is to define a color, texture or gradient for the
+ foreground, you can call setForegroundBrush() instead.
+
+ \sa drawBackground(), drawItems()
+*/
+void QGraphicsScene::drawForeground(QPainter *painter, const QRectF &rect)
+{
+ Q_D(QGraphicsScene);
+
+ if (d->foregroundBrush.style() != Qt::NoBrush) {
+ if (d->painterStateProtection)
+ painter->save();
+ painter->setBrushOrigin(0, 0);
+ painter->fillRect(rect, foregroundBrush());
+ if (d->painterStateProtection)
+ painter->restore();
+ }
+}
+
+static void _q_paintItem(QGraphicsItem *item, QPainter *painter,
+ const QStyleOptionGraphicsItem *option, QWidget *widget,
+ bool useWindowOpacity, bool painterStateProtection)
+{
+ if (!item->isWidget()) {
+ item->paint(painter, option, widget);
+ return;
+ }
+ QGraphicsWidget *widgetItem = static_cast<QGraphicsWidget *>(item);
+ QGraphicsProxyWidget *proxy = qobject_cast<QGraphicsProxyWidget *>(widgetItem);
+ const qreal windowOpacity = (proxy && proxy->widget() && useWindowOpacity)
+ ? proxy->widget()->windowOpacity() : 1.0;
+ const qreal oldPainterOpacity = painter->opacity();
+
+ if (qFuzzyIsNull(windowOpacity))
+ return;
+ // Set new painter opacity.
+ if (windowOpacity < 1.0)
+ painter->setOpacity(oldPainterOpacity * windowOpacity);
+
+ // set layoutdirection on the painter
+ Qt::LayoutDirection oldLayoutDirection = painter->layoutDirection();
+ painter->setLayoutDirection(widgetItem->layoutDirection());
+
+ if (widgetItem->isWindow() && widgetItem->windowType() != Qt::Popup && widgetItem->windowType() != Qt::ToolTip
+ && !(widgetItem->windowFlags() & Qt::FramelessWindowHint)) {
+ if (painterStateProtection)
+ painter->save();
+ widgetItem->paintWindowFrame(painter, option, widget);
+ if (painterStateProtection)
+ painter->restore();
+ } else if (widgetItem->autoFillBackground()) {
+ painter->fillRect(option->exposedRect, widgetItem->palette().window());
+ }
+
+ widgetItem->paint(painter, option, widget);
+
+ // Restore layoutdirection on the painter.
+ painter->setLayoutDirection(oldLayoutDirection);
+ // Restore painter opacity.
+ if (windowOpacity < 1.0)
+ painter->setOpacity(oldPainterOpacity);
+}
+
+static void _q_paintIntoCache(QPixmap *pix, QGraphicsItem *item, const QRegion &pixmapExposed,
+ const QTransform &itemToPixmap, QPainter::RenderHints renderHints,
+ const QStyleOptionGraphicsItem *option, bool painterStateProtection)
+{
+ QPixmap subPix;
+ QPainter pixmapPainter;
+ QRect br = pixmapExposed.boundingRect();
+
+ // Don't use subpixmap if we get a full update.
+ if (pixmapExposed.isEmpty() || (pixmapExposed.rectCount() == 1 && br.contains(pix->rect()))) {
+ pix->fill(Qt::transparent);
+ pixmapPainter.begin(pix);
+ } else {
+ subPix = QPixmap(br.size());
+ subPix.fill(Qt::transparent);
+ pixmapPainter.begin(&subPix);
+ pixmapPainter.translate(-br.topLeft());
+ if (!pixmapExposed.isEmpty()) {
+ // Applied to subPix; paint is adjusted to the coordinate space is
+ // correct.
+ pixmapPainter.setClipRegion(pixmapExposed);
+ }
+ }
+
+ pixmapPainter.setRenderHints(pixmapPainter.renderHints(), false);
+ pixmapPainter.setRenderHints(renderHints, true);
+ pixmapPainter.setWorldTransform(itemToPixmap, true);
+
+ // Render.
+ _q_paintItem(item, &pixmapPainter, option, 0, false, painterStateProtection);
+ pixmapPainter.end();
+
+ if (!subPix.isNull()) {
+ // Blit the subpixmap into the main pixmap.
+ pixmapPainter.begin(pix);
+ pixmapPainter.setCompositionMode(QPainter::CompositionMode_Source);
+ pixmapPainter.setClipRegion(pixmapExposed);
+ pixmapPainter.drawPixmap(br.topLeft(), subPix);
+ pixmapPainter.end();
+ }
+}
+
+// Copied from qpaintengine_vg.cpp
+// Returns true for 90, 180, and 270 degree rotations.
+static inline bool transformIsSimple(const QTransform& transform)
+{
+ QTransform::TransformationType type = transform.type();
+ if (type <= QTransform::TxScale) {
+ return true;
+ } else if (type == QTransform::TxRotate) {
+ // Check for 90, and 270 degree rotations.
+ qreal m11 = transform.m11();
+ qreal m12 = transform.m12();
+ qreal m21 = transform.m21();
+ qreal m22 = transform.m22();
+ if (m11 == 0.0f && m22 == 0.0f) {
+ if (m12 == 1.0f && m21 == -1.0f)
+ return true; // 90 degrees.
+ else if (m12 == -1.0f && m21 == 1.0f)
+ return true; // 270 degrees.
+ else if (m12 == -1.0f && m21 == -1.0f)
+ return true; // 90 degrees inverted y.
+ else if (m12 == 1.0f && m21 == 1.0f)
+ return true; // 270 degrees inverted y.
+ }
+ }
+ return false;
+}
+
+/*!
+ \internal
+
+ Draws items directly, or using cache.
+*/
+void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painter,
+ const QStyleOptionGraphicsItem *option, QWidget *widget,
+ bool painterStateProtection)
+{
+ QGraphicsItemPrivate *itemd = item->d_ptr.data();
+ QGraphicsItem::CacheMode cacheMode = QGraphicsItem::CacheMode(itemd->cacheMode);
+
+ // Render directly, using no cache.
+ if (cacheMode == QGraphicsItem::NoCache
+#ifdef Q_WS_X11
+ || !X11->use_xrender
+#endif
+ ) {
+ _q_paintItem(static_cast<QGraphicsWidget *>(item), painter, option, widget, true, painterStateProtection);
+ return;
+ }
+
+ const qreal oldPainterOpacity = painter->opacity();
+ qreal newPainterOpacity = oldPainterOpacity;
+ QGraphicsProxyWidget *proxy = item->isWidget() ? qobject_cast<QGraphicsProxyWidget *>(static_cast<QGraphicsWidget *>(item)) : 0;
+ if (proxy && proxy->widget()) {
+ const qreal windowOpacity = proxy->widget()->windowOpacity();
+ if (windowOpacity < 1.0)
+ newPainterOpacity *= windowOpacity;
+ }
+
+ // Item's (local) bounding rect
+ QRectF brect = item->boundingRect();
+ QRectF adjustedBrect(brect);
+ _q_adjustRect(&adjustedBrect);
+ if (adjustedBrect.isEmpty())
+ return;
+
+ // Fetch the off-screen transparent buffer and exposed area info.
+ QPixmapCache::Key pixmapKey;
+ QPixmap pix;
+ bool pixmapFound;
+ QGraphicsItemCache *itemCache = itemd->extraItemCache();
+ if (cacheMode == QGraphicsItem::ItemCoordinateCache) {
+ pixmapKey = itemCache->key;
+ } else {
+ pixmapKey = itemCache->deviceData.value(widget).key;
+ }
+
+ // Find pixmap in cache.
+ pixmapFound = QPixmapCache::find(pixmapKey, &pix);
+
+ // Render using item coordinate cache mode.
+ if (cacheMode == QGraphicsItem::ItemCoordinateCache) {
+ QSize pixmapSize;
+ bool fixedCacheSize = false;
+ QRect br = brect.toAlignedRect();
+ if ((fixedCacheSize = itemCache->fixedSize.isValid())) {
+ pixmapSize = itemCache->fixedSize;
+ } else {
+ pixmapSize = br.size();
+ }
+
+ // Create or recreate the pixmap.
+ int adjust = itemCache->fixedSize.isValid() ? 0 : 2;
+ QSize adjustSize(adjust*2, adjust*2);
+ br.adjust(-adjust, -adjust, adjust, adjust);
+ if (pix.isNull() || (!fixedCacheSize && (pixmapSize + adjustSize) != pix.size())) {
+ pix = QPixmap(pixmapSize + adjustSize);
+ itemCache->boundingRect = br;
+ itemCache->exposed.clear();
+ itemCache->allExposed = true;
+ } else if (itemCache->boundingRect != br) {
+ itemCache->boundingRect = br;
+ itemCache->exposed.clear();
+ itemCache->allExposed = true;
+ }
+
+ // Redraw any newly exposed areas.
+ if (itemCache->allExposed || !itemCache->exposed.isEmpty()) {
+
+ //We know that we will modify the pixmap, removing it from the cache
+ //will detach the one we have and avoid a deep copy
+ if (pixmapFound)
+ QPixmapCache::remove(pixmapKey);
+
+ // Fit the item's bounding rect into the pixmap's coordinates.
+ QTransform itemToPixmap;
+ 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
+ // rects to device coordinates.
+ styleOptionTmp = *option;
+ QRegion pixmapExposed;
+ QRectF exposedRect;
+ if (!itemCache->allExposed) {
+ for (int i = 0; i < itemCache->exposed.size(); ++i) {
+ QRectF r = itemCache->exposed.at(i);
+ exposedRect |= r;
+ pixmapExposed += itemToPixmap.mapRect(r).toAlignedRect();
+ }
+ } else {
+ exposedRect = brect;
+ }
+ styleOptionTmp.exposedRect = exposedRect;
+
+ // Render.
+ _q_paintIntoCache(&pix, item, pixmapExposed, itemToPixmap, painter->renderHints(),
+ &styleOptionTmp, painterStateProtection);
+
+ // insert this pixmap into the cache.
+ itemCache->key = QPixmapCache::insert(pix);
+
+ // Reset expose data.
+ itemCache->allExposed = false;
+ itemCache->exposed.clear();
+ }
+
+ // Redraw the exposed area using the transformed painter. Depending on
+ // the hardware, this may be a server-side operation, or an expensive
+ // qpixmap-image-transform-pixmap roundtrip.
+ if (newPainterOpacity != oldPainterOpacity) {
+ painter->setOpacity(newPainterOpacity);
+ painter->drawPixmap(br.topLeft(), pix);
+ painter->setOpacity(oldPainterOpacity);
+ } else {
+ painter->drawPixmap(br.topLeft(), pix);
+ }
+ return;
+ }
+
+ // Render using device coordinate cache mode.
+ if (cacheMode == QGraphicsItem::DeviceCoordinateCache) {
+ // Find the item's bounds in device coordinates.
+ QRectF deviceBounds = painter->worldTransform().mapRect(brect);
+ QRect deviceRect = deviceBounds.toRect().adjusted(-1, -1, 1, 1);
+ if (deviceRect.isEmpty())
+ return;
+ QRect viewRect = widget ? widget->rect() : QRect();
+ if (widget && !viewRect.intersects(deviceRect))
+ return;
+
+ // Resort to direct rendering if the device rect exceeds the
+ // (optional) maximum bounds. (QGraphicsSvgItem uses this).
+ QSize maximumCacheSize =
+ itemd->extra(QGraphicsItemPrivate::ExtraMaxDeviceCoordCacheSize).toSize();
+ if (!maximumCacheSize.isEmpty()
+ && (deviceRect.width() > maximumCacheSize.width()
+ || deviceRect.height() > maximumCacheSize.height())) {
+ _q_paintItem(static_cast<QGraphicsWidget *>(item), painter, option, widget,
+ oldPainterOpacity != newPainterOpacity, painterStateProtection);
+ return;
+ }
+
+ // Create or reuse offscreen pixmap, possibly scroll/blit from the old one.
+ // If the world transform is rotated we always recreate the cache to avoid
+ // wrong blending.
+ bool pixModified = false;
+ QGraphicsItemCache::DeviceData *deviceData = &itemCache->deviceData[widget];
+ bool invertable = true;
+ QTransform diff = deviceData->lastTransform.inverted(&invertable);
+ if (invertable)
+ diff *= painter->worldTransform();
+ deviceData->lastTransform = painter->worldTransform();
+ bool allowPartialCacheExposure = false;
+ bool simpleTransform = invertable && diff.type() <= QTransform::TxTranslate
+ && transformIsSimple(painter->worldTransform());
+ if (!simpleTransform) {
+ pixModified = true;
+ itemCache->allExposed = true;
+ itemCache->exposed.clear();
+ deviceData->cacheIndent = QPoint();
+ pix = QPixmap();
+ } else if (!viewRect.isNull()) {
+ allowPartialCacheExposure = deviceData->cacheIndent != QPoint();
+ }
+
+ // Allow partial cache exposure if the device rect isn't fully contained and
+ // deviceRect is 20% taller or wider than the viewRect.
+ if (!allowPartialCacheExposure && !viewRect.isNull() && !viewRect.contains(deviceRect)) {
+ allowPartialCacheExposure = (viewRect.width() * 1.2 < deviceRect.width())
+ || (viewRect.height() * 1.2 < deviceRect.height());
+ }
+
+ QRegion scrollExposure;
+ if (allowPartialCacheExposure) {
+ // Part of pixmap is drawn. Either device contains viewrect (big
+ // item covers whole screen) or parts of device are outside the
+ // viewport. In either case the device rect must be the intersect
+ // between the two.
+ int dx = deviceRect.left() < viewRect.left() ? viewRect.left() - deviceRect.left() : 0;
+ int dy = deviceRect.top() < viewRect.top() ? viewRect.top() - deviceRect.top() : 0;
+ QPoint newCacheIndent(dx, dy);
+ deviceRect &= viewRect;
+
+ if (pix.isNull()) {
+ deviceData->cacheIndent = QPoint();
+ itemCache->allExposed = true;
+ itemCache->exposed.clear();
+ pixModified = true;
+ }
+
+ // Copy / "scroll" the old pixmap onto the new ole and calculate
+ // scrolled exposure.
+ 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.drawPixmap(-diff, pix);
+ newPixPainter.end();
+ }
+ QRegion exposed;
+ exposed += newPix.rect();
+ if (!pix.isNull())
+ exposed -= QRect(-diff, pix.size());
+ scrollExposure = exposed;
+
+ pix = newPix;
+ pixModified = true;
+ }
+ deviceData->cacheIndent = newCacheIndent;
+ } else {
+ // Full pixmap is drawn.
+ deviceData->cacheIndent = QPoint();
+
+ // Auto-adjust the pixmap size.
+ if (deviceRect.size() != pix.size()) {
+ // exposed needs to cover the whole pixmap
+ pix = QPixmap(deviceRect.size());
+ pixModified = true;
+ itemCache->allExposed = true;
+ itemCache->exposed.clear();
+ }
+ }
+
+ // Check for newly invalidated areas.
+ if (itemCache->allExposed || !itemCache->exposed.isEmpty() || !scrollExposure.isEmpty()) {
+ //We know that we will modify the pixmap, removing it from the cache
+ //will detach the one we have and avoid a deep copy
+ if (pixmapFound)
+ QPixmapCache::remove(pixmapKey);
+
+ // Construct an item-to-pixmap transform.
+ QPointF p = deviceRect.topLeft();
+ 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;
+ if (!itemCache->allExposed) {
+ const QVector<QRectF> &exposed = itemCache->exposed;
+ for (int i = 0; i < exposed.size(); ++i)
+ pixmapExposed += itemToPixmap.mapRect(exposed.at(i)).toRect().adjusted(-1, -1, 1, 1);
+ }
+
+ // Calculate the style option's exposedRect.
+ QRectF br;
+ if (itemCache->allExposed) {
+ br = item->boundingRect();
+ } else {
+ const QVector<QRectF> &exposed = itemCache->exposed;
+ for (int i = 0; i < exposed.size(); ++i)
+ br |= exposed.at(i);
+ QTransform pixmapToItem = itemToPixmap.inverted();
+ foreach (QRect r, scrollExposure.rects())
+ br |= pixmapToItem.mapRect(r);
+ }
+ styleOptionTmp = *option;
+ styleOptionTmp.exposedRect = br.adjusted(-1, -1, 1, 1);
+
+ // Render the exposed areas.
+ _q_paintIntoCache(&pix, item, pixmapExposed, itemToPixmap, painter->renderHints(),
+ &styleOptionTmp, painterStateProtection);
+
+ // Reset expose data.
+ pixModified = true;
+ itemCache->allExposed = false;
+ itemCache->exposed.clear();
+ }
+
+ if (pixModified) {
+ // Insert this pixmap into the cache.
+ deviceData->key = QPixmapCache::insert(pix);
+ }
+
+ // Redraw the exposed area using an untransformed painter. This
+ // effectively becomes a bitblit that does not transform the cache.
+ QTransform restoreTransform = painter->worldTransform();
+ painter->setWorldTransform(QTransform());
+ if (newPainterOpacity != oldPainterOpacity) {
+ painter->setOpacity(newPainterOpacity);
+ painter->drawPixmap(deviceRect.topLeft(), pix);
+ painter->setOpacity(oldPainterOpacity);
+ } else {
+ painter->drawPixmap(deviceRect.topLeft(), pix);
+ }
+ painter->setWorldTransform(restoreTransform);
+ return;
+ }
+}
+
+void QGraphicsScenePrivate::drawItems(QPainter *painter, const QTransform *const viewTransform,
+ QRegion *exposedRegion, QWidget *widget)
+{
+ // Make sure we don't have unpolished items before we draw.
+ if (!unpolishedItems.isEmpty())
+ _q_polishItems();
+
+ updateAll = false;
+ QRectF exposedSceneRect;
+ if (exposedRegion && indexMethod != QGraphicsScene::NoIndex) {
+ exposedSceneRect = exposedRegion->boundingRect().adjusted(-1, -1, 1, 1);
+ if (viewTransform)
+ exposedSceneRect = viewTransform->inverted().mapRect(exposedSceneRect);
+ }
+ const QList<QGraphicsItem *> tli = index->estimateTopLevelItems(exposedSceneRect, Qt::AscendingOrder);
+ for (int i = 0; i < tli.size(); ++i)
+ drawSubtreeRecursive(tli.at(i), painter, viewTransform, exposedRegion, widget);
+}
+
+void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter *painter,
+ const QTransform *const viewTransform,
+ QRegion *exposedRegion, QWidget *widget,
+ qreal parentOpacity, const QTransform *const effectTransform)
+{
+ Q_ASSERT(item);
+
+ if (!item->d_ptr->visible)
+ return;
+
+ const bool itemHasContents = !(item->d_ptr->flags & QGraphicsItem::ItemHasNoContents);
+ const bool itemHasChildren = !item->d_ptr->children.isEmpty();
+ if (!itemHasContents && !itemHasChildren)
+ return; // Item has neither contents nor children!(?)
+
+ const qreal opacity = item->d_ptr->combineOpacityFromParent(parentOpacity);
+ const bool itemIsFullyTransparent = QGraphicsItemPrivate::isOpacityNull(opacity);
+ if (itemIsFullyTransparent && (!itemHasChildren || item->d_ptr->childrenCombineOpacity()))
+ return;
+
+ QTransform transform(Qt::Uninitialized);
+ QTransform *transformPtr = 0;
+ bool translateOnlyTransform = false;
+#define ENSURE_TRANSFORM_PTR \
+ if (!transformPtr) { \
+ Q_ASSERT(!itemIsUntransformable); \
+ if (viewTransform) { \
+ transform = item->d_ptr->sceneTransform; \
+ transform *= *viewTransform; \
+ transformPtr = &transform; \
+ } else { \
+ transformPtr = &item->d_ptr->sceneTransform; \
+ translateOnlyTransform = item->d_ptr->sceneTransformTranslateOnly; \
+ } \
+ }
+
+ // Update the item's scene transform if the item is transformable;
+ // otherwise calculate the full transform,
+ bool wasDirtyParentSceneTransform = false;
+ const bool itemIsUntransformable = item->d_ptr->itemIsUntransformable();
+ if (itemIsUntransformable) {
+ transform = item->deviceTransform(viewTransform ? *viewTransform : QTransform());
+ transformPtr = &transform;
+ } else if (item->d_ptr->dirtySceneTransform) {
+ item->d_ptr->updateSceneTransformFromParent();
+ Q_ASSERT(!item->d_ptr->dirtySceneTransform);
+ wasDirtyParentSceneTransform = true;
+ }
+
+ const bool itemClipsChildrenToShape = (item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape);
+ bool drawItem = itemHasContents && !itemIsFullyTransparent;
+ if (drawItem) {
+ const QRectF brect = adjustedItemEffectiveBoundingRect(item);
+ ENSURE_TRANSFORM_PTR
+ QRect viewBoundingRect = translateOnlyTransform ? brect.translated(transformPtr->dx(), transformPtr->dy()).toAlignedRect()
+ : transformPtr->mapRect(brect).toAlignedRect();
+ viewBoundingRect.adjust(-int(rectAdjust), -int(rectAdjust), rectAdjust, rectAdjust);
+ if (widget)
+ item->d_ptr->paintedViewBoundingRects.insert(widget, viewBoundingRect);
+ drawItem = exposedRegion ? exposedRegion->intersects(viewBoundingRect)
+ : !viewBoundingRect.normalized().isEmpty();
+ if (!drawItem) {
+ if (!itemHasChildren)
+ return;
+ if (itemClipsChildrenToShape) {
+ if (wasDirtyParentSceneTransform)
+ item->d_ptr->invalidateChildrenSceneTransform();
+ return;
+ }
+ }
+ } // else we know for sure this item has children we must process.
+
+ if (itemHasChildren && itemClipsChildrenToShape)
+ ENSURE_TRANSFORM_PTR;
+
+#ifndef QT_NO_GRAPHICSEFFECT
+ if (item->d_ptr->graphicsEffect && item->d_ptr->graphicsEffect->isEnabled()) {
+ ENSURE_TRANSFORM_PTR;
+ QGraphicsItemPaintInfo info(viewTransform, transformPtr, effectTransform, exposedRegion, widget, &styleOptionTmp,
+ painter, opacity, wasDirtyParentSceneTransform, itemHasContents && !itemIsFullyTransparent);
+ QGraphicsEffectSource *source = item->d_ptr->graphicsEffect->d_func()->source;
+ QGraphicsItemEffectSourcePrivate *sourced = static_cast<QGraphicsItemEffectSourcePrivate *>
+ (source->d_func());
+ sourced->info = &info;
+ const QTransform restoreTransform = painter->worldTransform();
+ if (effectTransform)
+ painter->setWorldTransform(*transformPtr * *effectTransform);
+ else
+ painter->setWorldTransform(*transformPtr);
+ painter->setOpacity(opacity);
+
+ if (sourced->currentCachedSystem() != Qt::LogicalCoordinates
+ && sourced->lastEffectTransform != painter->worldTransform())
+ {
+ if (sourced->lastEffectTransform.type() <= QTransform::TxTranslate
+ && painter->worldTransform().type() <= QTransform::TxTranslate)
+ {
+ QRectF sourceRect = sourced->boundingRect(Qt::DeviceCoordinates);
+ QRect effectRect = sourced->paddedEffectRect(Qt::DeviceCoordinates, sourced->currentCachedMode(), sourceRect);
+
+ sourced->setCachedOffset(effectRect.topLeft());
+ } else {
+ sourced->invalidateCache(QGraphicsEffectSourcePrivate::TransformChanged);
+ }
+
+ sourced->lastEffectTransform = painter->worldTransform();
+ }
+
+ item->d_ptr->graphicsEffect->draw(painter);
+ painter->setWorldTransform(restoreTransform);
+ sourced->info = 0;
+ } else
+#endif //QT_NO_GRAPHICSEFFECT
+ {
+ draw(item, painter, viewTransform, transformPtr, exposedRegion, widget, opacity,
+ effectTransform, wasDirtyParentSceneTransform, drawItem);
+ }
+}
+
+static inline void setClip(QPainter *painter, QGraphicsItem *item)
+{
+ painter->save();
+ QRectF clipRect;
+ const QPainterPath clipPath(item->shape());
+ if (QPathClipper::pathToRect(clipPath, &clipRect))
+ painter->setClipRect(clipRect, Qt::IntersectClip);
+ else
+ painter->setClipPath(clipPath, Qt::IntersectClip);
+}
+
+static inline void setWorldTransform(QPainter *painter, const QTransform *const transformPtr,
+ const QTransform *effectTransform)
+{
+ Q_ASSERT(transformPtr);
+ if (effectTransform)
+ painter->setWorldTransform(*transformPtr * *effectTransform);
+ else
+ painter->setWorldTransform(*transformPtr);
+}
+
+void QGraphicsScenePrivate::draw(QGraphicsItem *item, QPainter *painter, const QTransform *const viewTransform,
+ const QTransform *const transformPtr, QRegion *exposedRegion, QWidget *widget,
+ qreal opacity, const QTransform *effectTransform,
+ bool wasDirtyParentSceneTransform, bool drawItem)
+{
+ const bool itemIsFullyTransparent = QGraphicsItemPrivate::isOpacityNull(opacity);
+ const bool itemClipsChildrenToShape = (item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape);
+ const bool itemHasChildren = !item->d_ptr->children.isEmpty();
+ bool setChildClip = itemClipsChildrenToShape;
+ bool itemHasChildrenStackedBehind = false;
+
+ int i = 0;
+ if (itemHasChildren) {
+ if (itemClipsChildrenToShape)
+ setWorldTransform(painter, transformPtr, effectTransform);
+
+ item->d_ptr->ensureSortedChildren();
+ // Items with the 'ItemStacksBehindParent' flag are put in front of the list
+ // so all we have to do is to check the first item.
+ itemHasChildrenStackedBehind = (item->d_ptr->children.at(0)->d_ptr->flags
+ & QGraphicsItem::ItemStacksBehindParent);
+
+ if (itemHasChildrenStackedBehind) {
+ if (itemClipsChildrenToShape) {
+ setClip(painter, item);
+ setChildClip = false;
+ }
+
+ // Draw children behind
+ for (i = 0; i < item->d_ptr->children.size(); ++i) {
+ QGraphicsItem *child = item->d_ptr->children.at(i);
+ if (wasDirtyParentSceneTransform)
+ child->d_ptr->dirtySceneTransform = 1;
+ if (!(child->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent))
+ break;
+ if (itemIsFullyTransparent && !(child->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity))
+ continue;
+ drawSubtreeRecursive(child, painter, viewTransform, exposedRegion, widget, opacity, effectTransform);
+ }
+ }
+ }
+
+ // Draw item
+ if (drawItem) {
+ Q_ASSERT(!itemIsFullyTransparent);
+ Q_ASSERT(!(item->d_ptr->flags & QGraphicsItem::ItemHasNoContents));
+ Q_ASSERT(transformPtr);
+ item->d_ptr->initStyleOption(&styleOptionTmp, *transformPtr, exposedRegion
+ ? *exposedRegion : QRegion(), exposedRegion == 0);
+
+ const bool itemClipsToShape = item->d_ptr->flags & QGraphicsItem::ItemClipsToShape;
+ bool restorePainterClip = false;
+
+ if (!itemHasChildren || !itemClipsChildrenToShape) {
+ // Item does not have children or clip children to shape.
+ setWorldTransform(painter, transformPtr, effectTransform);
+ if ((restorePainterClip = itemClipsToShape))
+ setClip(painter, item);
+ } else if (itemHasChildrenStackedBehind){
+ // Item clips children to shape and has children stacked behind, which means
+ // the painter is already clipped to the item's shape.
+ if (itemClipsToShape) {
+ // The clip is already correct. Ensure correct world transform.
+ setWorldTransform(painter, transformPtr, effectTransform);
+ } else {
+ // Remove clip (this also ensures correct world transform).
+ painter->restore();
+ setChildClip = true;
+ }
+ } else if (itemClipsToShape) {
+ // Item clips children and itself to shape. It does not have hildren stacked
+ // behind, which means the clip has not yet been set. We set it now and re-use it
+ // for the children.
+ setClip(painter, item);
+ setChildClip = false;
+ }
+
+ if (painterStateProtection && !restorePainterClip)
+ painter->save();
+
+ painter->setOpacity(opacity);
+ if (!item->d_ptr->cacheMode && !item->d_ptr->isWidget)
+ item->paint(painter, &styleOptionTmp, widget);
+ else
+ drawItemHelper(item, painter, &styleOptionTmp, widget, painterStateProtection);
+
+ if (painterStateProtection || restorePainterClip)
+ painter->restore();
+
+ static int drawRect = qgetenv("QT_DRAW_SCENE_ITEM_RECTS").toInt();
+ if (drawRect) {
+ QPen oldPen = painter->pen();
+ QBrush oldBrush = painter->brush();
+ quintptr ptr = reinterpret_cast<quintptr>(item);
+ const QColor color = QColor::fromHsv(ptr % 255, 255, 255);
+ painter->setPen(color);
+ painter->setBrush(Qt::NoBrush);
+ painter->drawRect(adjustedItemBoundingRect(item));
+ painter->setPen(oldPen);
+ painter->setBrush(oldBrush);
+ }
+ }
+
+ // Draw children in front
+ if (itemHasChildren) {
+ if (setChildClip)
+ setClip(painter, item);
+
+ for (; i < item->d_ptr->children.size(); ++i) {
+ QGraphicsItem *child = item->d_ptr->children.at(i);
+ if (wasDirtyParentSceneTransform)
+ child->d_ptr->dirtySceneTransform = 1;
+ if (itemIsFullyTransparent && !(child->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity))
+ continue;
+ drawSubtreeRecursive(child, painter, viewTransform, exposedRegion, widget, opacity, effectTransform);
+ }
+
+ // Restore child clip
+ if (itemClipsChildrenToShape)
+ painter->restore();
+ }
+}
+
+void QGraphicsScenePrivate::markDirty(QGraphicsItem *item, const QRectF &rect, bool invalidateChildren,
+ bool force, bool ignoreOpacity, bool removingItemFromScene,
+ bool updateBoundingRect)
+{
+ Q_ASSERT(item);
+ if (updateAll)
+ return;
+
+ if (removingItemFromScene && !ignoreOpacity && !item->d_ptr->ignoreOpacity) {
+ // If any of the item's ancestors ignore opacity, it means that the opacity
+ // was set to 0 (and the update request has not yet been processed). That
+ // also means that we have to ignore the opacity for the item itself; otherwise
+ // things like: parent->setOpacity(0); scene->removeItem(child) won't work.
+ // Note that we only do this when removing items from the scene. In all other
+ // cases the ignoreOpacity bit propagates properly in processDirtyItems, but
+ // since the item is removed immediately it won't be processed there.
+ QGraphicsItem *p = item->d_ptr->parent;
+ while (p) {
+ if (p->d_ptr->ignoreOpacity) {
+ item->d_ptr->ignoreOpacity = true;
+ break;
+ }
+ p = p->d_ptr->parent;
+ }
+ }
+
+ if (item->d_ptr->discardUpdateRequest(/*ignoreVisibleBit=*/force,
+ /*ignoreDirtyBit=*/removingItemFromScene || invalidateChildren,
+ /*ignoreOpacity=*/ignoreOpacity)) {
+ if (item->d_ptr->dirty) {
+ // The item is already marked as dirty and will be processed later. However,
+ // we have to make sure ignoreVisible and ignoreOpacity are set properly;
+ // otherwise things like: item->update(); item->hide() (force is now true)
+ // won't work as expected.
+ if (force)
+ item->d_ptr->ignoreVisible = 1;
+ if (ignoreOpacity)
+ item->d_ptr->ignoreOpacity = 1;
+ }
+ return;
+ }
+
+ const bool fullItemUpdate = rect.isNull();
+ if (!fullItemUpdate && rect.isEmpty())
+ return;
+
+ if (!processDirtyItemsEmitted) {
+ QMetaMethod method = q_ptr->metaObject()->method(processDirtyItemsIndex);
+ method.invoke(q_ptr, Qt::QueuedConnection);
+// QMetaObject::invokeMethod(q_ptr, "_q_processDirtyItems", Qt::QueuedConnection);
+ processDirtyItemsEmitted = true;
+ }
+
+ if (removingItemFromScene) {
+ // Note that this function can be called from the item's destructor, so
+ // do NOT call any virtual functions on it within this block.
+ if (isSignalConnected(changedSignalIndex) || views.isEmpty()) {
+ // This block of code is kept for compatibility. Since 4.5, by default
+ // QGraphicsView does not connect the signal and we use the below
+ // method of delivering updates.
+ q_func()->update();
+ return;
+ }
+
+ for (int i = 0; i < views.size(); ++i) {
+ QGraphicsViewPrivate *viewPrivate = views.at(i)->d_func();
+ QRect rect = item->d_ptr->paintedViewBoundingRects.value(viewPrivate->viewport);
+ rect.translate(viewPrivate->dirtyScrollOffset);
+ viewPrivate->updateRect(rect);
+ }
+ return;
+ }
+
+ bool hasNoContents = item->d_ptr->flags & QGraphicsItem::ItemHasNoContents;
+ if (!hasNoContents) {
+ item->d_ptr->dirty = 1;
+ if (fullItemUpdate)
+ item->d_ptr->fullUpdatePending = 1;
+ else if (!item->d_ptr->fullUpdatePending)
+ item->d_ptr->needsRepaint |= rect;
+ } else if (item->d_ptr->graphicsEffect) {
+ invalidateChildren = true;
+ }
+
+ if (invalidateChildren) {
+ item->d_ptr->allChildrenDirty = 1;
+ item->d_ptr->dirtyChildren = 1;
+ }
+
+ if (force)
+ item->d_ptr->ignoreVisible = 1;
+ if (ignoreOpacity)
+ item->d_ptr->ignoreOpacity = 1;
+
+ if (!updateBoundingRect)
+ item->d_ptr->markParentDirty();
+}
+
+static inline bool updateHelper(QGraphicsViewPrivate *view, QGraphicsItemPrivate *item,
+ const QRectF &rect, bool itemIsUntransformable)
+{
+ Q_ASSERT(view);
+ Q_ASSERT(item);
+
+ QGraphicsItem *itemq = static_cast<QGraphicsItem *>(item->q_ptr);
+ QGraphicsView *viewq = static_cast<QGraphicsView *>(view->q_ptr);
+
+ if (itemIsUntransformable) {
+ const QTransform xform = itemq->deviceTransform(viewq->viewportTransform());
+ if (!item->hasBoundingRegionGranularity)
+ return view->updateRectF(xform.mapRect(rect));
+ return view->updateRegion(rect, xform);
+ }
+
+ if (item->sceneTransformTranslateOnly && view->identityMatrix) {
+ const qreal dx = item->sceneTransform.dx();
+ const qreal dy = item->sceneTransform.dy();
+ QRectF r(rect);
+ r.translate(dx - view->horizontalScroll(), dy - view->verticalScroll());
+ return view->updateRectF(r);
+ }
+
+ if (!viewq->isTransformed()) {
+ if (!item->hasBoundingRegionGranularity)
+ return view->updateRectF(item->sceneTransform.mapRect(rect));
+ return view->updateRegion(rect, item->sceneTransform);
+ }
+
+ QTransform xform = item->sceneTransform;
+ xform *= viewq->viewportTransform();
+ if (!item->hasBoundingRegionGranularity)
+ return view->updateRectF(xform.mapRect(rect));
+ return view->updateRegion(rect, xform);
+}
+
+void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool dirtyAncestorContainsChildren,
+ qreal parentOpacity)
+{
+ Q_Q(QGraphicsScene);
+ Q_ASSERT(item);
+ Q_ASSERT(!updateAll);
+
+ if (!item->d_ptr->dirty && !item->d_ptr->dirtyChildren) {
+ resetDirtyItem(item);
+ return;
+ }
+
+ const bool itemIsHidden = !item->d_ptr->ignoreVisible && !item->d_ptr->visible;
+ if (itemIsHidden) {
+ resetDirtyItem(item, /*recursive=*/true);
+ return;
+ }
+
+ bool itemHasContents = !(item->d_ptr->flags & QGraphicsItem::ItemHasNoContents);
+ const bool itemHasChildren = !item->d_ptr->children.isEmpty();
+ if (!itemHasContents) {
+ if (!itemHasChildren) {
+ resetDirtyItem(item);
+ return; // Item has neither contents nor children!(?)
+ }
+ if (item->d_ptr->graphicsEffect)
+ itemHasContents = true;
+ }
+
+ const qreal opacity = item->d_ptr->combineOpacityFromParent(parentOpacity);
+ const bool itemIsFullyTransparent = !item->d_ptr->ignoreOpacity
+ && QGraphicsItemPrivate::isOpacityNull(opacity);
+ if (itemIsFullyTransparent && (!itemHasChildren || item->d_ptr->childrenCombineOpacity())) {
+ resetDirtyItem(item, /*recursive=*/itemHasChildren);
+ return;
+ }
+
+ bool wasDirtyParentSceneTransform = item->d_ptr->dirtySceneTransform;
+ const bool itemIsUntransformable = item->d_ptr->itemIsUntransformable();
+ if (wasDirtyParentSceneTransform && !itemIsUntransformable) {
+ item->d_ptr->updateSceneTransformFromParent();
+ Q_ASSERT(!item->d_ptr->dirtySceneTransform);
+ }
+
+ const bool wasDirtyParentViewBoundingRects = item->d_ptr->paintedViewBoundingRectsNeedRepaint;
+ if (itemIsFullyTransparent || !itemHasContents || dirtyAncestorContainsChildren) {
+ // Make sure we don't process invisible items or items with no content.
+ item->d_ptr->dirty = 0;
+ item->d_ptr->fullUpdatePending = 0;
+ // Might have a dirty view bounding rect otherwise.
+ if (itemIsFullyTransparent || !itemHasContents)
+ item->d_ptr->paintedViewBoundingRectsNeedRepaint = 0;
+ }
+
+ if (!hasSceneRect && item->d_ptr->geometryChanged && item->d_ptr->visible) {
+ // Update growingItemsBoundingRect.
+ if (item->d_ptr->sceneTransformTranslateOnly) {
+ growingItemsBoundingRect |= item->boundingRect().translated(item->d_ptr->sceneTransform.dx(),
+ item->d_ptr->sceneTransform.dy());
+ } else {
+ growingItemsBoundingRect |= item->d_ptr->sceneTransform.mapRect(item->boundingRect());
+ }
+ }
+
+ // Process item.
+ if (item->d_ptr->dirty || item->d_ptr->paintedViewBoundingRectsNeedRepaint) {
+ const bool useCompatUpdate = views.isEmpty() || isSignalConnected(changedSignalIndex);
+ const QRectF itemBoundingRect = adjustedItemEffectiveBoundingRect(item);
+
+ if (useCompatUpdate && !itemIsUntransformable && qFuzzyIsNull(item->boundingRegionGranularity())) {
+ // This block of code is kept for compatibility. Since 4.5, by default
+ // QGraphicsView does not connect the signal and we use the below
+ // method of delivering updates.
+ if (item->d_ptr->sceneTransformTranslateOnly) {
+ q->update(itemBoundingRect.translated(item->d_ptr->sceneTransform.dx(),
+ item->d_ptr->sceneTransform.dy()));
+ } else {
+ QRectF rect = item->d_ptr->sceneTransform.mapRect(itemBoundingRect);
+ if (!rect.isEmpty())
+ q->update(rect);
+ }
+ } else {
+ QRectF dirtyRect;
+ bool uninitializedDirtyRect = true;
+
+ for (int j = 0; j < views.size(); ++j) {
+ QGraphicsView *view = views.at(j);
+ QGraphicsViewPrivate *viewPrivate = view->d_func();
+ QRect &paintedViewBoundingRect = item->d_ptr->paintedViewBoundingRects[viewPrivate->viewport];
+ if (viewPrivate->fullUpdatePending
+ || viewPrivate->viewportUpdateMode == QGraphicsView::NoViewportUpdate) {
+ // Okay, if we have a full update pending or no viewport update, this item's
+ // paintedViewBoundingRect will be updated correctly in the next paintEvent if
+ // it is inside the viewport, but for now we can pretend that it is outside.
+ paintedViewBoundingRect = QRect(-1, -1, -1, -1);
+ continue;
+ }
+
+ if (item->d_ptr->paintedViewBoundingRectsNeedRepaint) {
+ paintedViewBoundingRect.translate(viewPrivate->dirtyScrollOffset);
+ if (!viewPrivate->updateRect(paintedViewBoundingRect))
+ paintedViewBoundingRect = QRect(-1, -1, -1, -1); // Outside viewport.
+ }
+
+ if (!item->d_ptr->dirty)
+ continue;
+
+ if (!item->d_ptr->paintedViewBoundingRectsNeedRepaint
+ && paintedViewBoundingRect.x() == -1 && paintedViewBoundingRect.y() == -1
+ && paintedViewBoundingRect.width() == -1 && paintedViewBoundingRect.height() == -1) {
+ continue; // Outside viewport.
+ }
+
+ if (uninitializedDirtyRect) {
+ dirtyRect = itemBoundingRect;
+ if (!item->d_ptr->fullUpdatePending) {
+ _q_adjustRect(&item->d_ptr->needsRepaint);
+ dirtyRect &= item->d_ptr->needsRepaint;
+ }
+ uninitializedDirtyRect = false;
+ }
+
+ if (dirtyRect.isEmpty())
+ continue; // Discard updates outside the bounding rect.
+
+ if (!updateHelper(viewPrivate, item->d_ptr.data(), dirtyRect, itemIsUntransformable)
+ && item->d_ptr->paintedViewBoundingRectsNeedRepaint) {
+ paintedViewBoundingRect = QRect(-1, -1, -1, -1); // Outside viewport.
+ }
+ }
+ }
+ }
+
+ // Process children.
+ if (itemHasChildren && item->d_ptr->dirtyChildren) {
+ const bool itemClipsChildrenToShape = item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape;
+ // Items with no content are threated as 'dummy' items which means they are never drawn and
+ // 'processed', so the painted view bounding rect is never up-to-date. This means that whenever
+ // such an item changes geometry, its children have to take care of the update regardless
+ // of whether the item clips children to shape or not.
+ const bool bypassUpdateClip = !itemHasContents && wasDirtyParentViewBoundingRects;
+ if (itemClipsChildrenToShape && !bypassUpdateClip) {
+ // Make sure child updates are clipped to the item's bounding rect.
+ for (int i = 0; i < views.size(); ++i)
+ views.at(i)->d_func()->setUpdateClip(item);
+ }
+ if (!dirtyAncestorContainsChildren) {
+ dirtyAncestorContainsChildren = item->d_ptr->fullUpdatePending
+ && itemClipsChildrenToShape;
+ }
+ const bool allChildrenDirty = item->d_ptr->allChildrenDirty;
+ const bool parentIgnoresVisible = item->d_ptr->ignoreVisible;
+ const bool parentIgnoresOpacity = item->d_ptr->ignoreOpacity;
+ for (int i = 0; i < item->d_ptr->children.size(); ++i) {
+ QGraphicsItem *child = item->d_ptr->children.at(i);
+ if (wasDirtyParentSceneTransform)
+ child->d_ptr->dirtySceneTransform = 1;
+ if (wasDirtyParentViewBoundingRects)
+ child->d_ptr->paintedViewBoundingRectsNeedRepaint = 1;
+ if (parentIgnoresVisible)
+ child->d_ptr->ignoreVisible = 1;
+ if (parentIgnoresOpacity)
+ child->d_ptr->ignoreOpacity = 1;
+ if (allChildrenDirty) {
+ child->d_ptr->dirty = 1;
+ child->d_ptr->fullUpdatePending = 1;
+ child->d_ptr->dirtyChildren = 1;
+ child->d_ptr->allChildrenDirty = 1;
+ }
+ processDirtyItemsRecursive(child, dirtyAncestorContainsChildren, opacity);
+ }
+
+ if (itemClipsChildrenToShape) {
+ // Reset updateClip.
+ for (int i = 0; i < views.size(); ++i)
+ views.at(i)->d_func()->setUpdateClip(0);
+ }
+ } else if (wasDirtyParentSceneTransform) {
+ item->d_ptr->invalidateChildrenSceneTransform();
+ }
+
+ resetDirtyItem(item);
+}
+
+/*!
+ \obsolete
+
+ Paints the given \a items using the provided \a painter, after the
+ background has been drawn, and before the foreground has been
+ drawn. All painting is done in \e scene coordinates. Before
+ drawing each item, the painter must be transformed using
+ QGraphicsItem::sceneTransform().
+
+ The \a options parameter is the list of style option objects for
+ each item in \a items. The \a numItems parameter is the number of
+ items in \a items and options in \a options. The \a widget
+ parameter is optional; if specified, it should point to the widget
+ that is being painted on.
+
+ The default implementation prepares the painter matrix, and calls
+ QGraphicsItem::paint() on all items. Reimplement this function to
+ provide custom painting of all items for the scene; gaining
+ complete control over how each item is drawn. In some cases this
+ can increase drawing performance significantly.
+
+ Example:
+
+ \snippet doc/src/snippets/graphicssceneadditemsnippet.cpp 0
+
+ Since Qt 4.6, this function is not called anymore unless
+ the QGraphicsView::IndirectPainting flag is given as an Optimization
+ flag.
+
+ \sa drawBackground(), drawForeground()
+*/
+void QGraphicsScene::drawItems(QPainter *painter,
+ int numItems,
+ QGraphicsItem *items[],
+ const QStyleOptionGraphicsItem options[], QWidget *widget)
+{
+ Q_D(QGraphicsScene);
+ // Make sure we don't have unpolished items before we draw.
+ if (!d->unpolishedItems.isEmpty())
+ d->_q_polishItems();
+
+ const qreal opacity = painter->opacity();
+ QTransform viewTransform = painter->worldTransform();
+ Q_UNUSED(options);
+
+ // Determine view, expose and flags.
+ QGraphicsView *view = widget ? qobject_cast<QGraphicsView *>(widget->parentWidget()) : 0;
+ QRegion *expose = 0;
+ const quint32 oldRectAdjust = d->rectAdjust;
+ if (view) {
+ d->updateAll = false;
+ expose = &view->d_func()->exposedRegion;
+ if (view->d_func()->optimizationFlags & QGraphicsView::DontAdjustForAntialiasing)
+ d->rectAdjust = 1;
+ else
+ d->rectAdjust = 2;
+ }
+
+ // Find all toplevels, they are already sorted.
+ QList<QGraphicsItem *> topLevelItems;
+ for (int i = 0; i < numItems; ++i) {
+ QGraphicsItem *item = items[i]->topLevelItem();
+ if (!item->d_ptr->itemDiscovered) {
+ topLevelItems << item;
+ item->d_ptr->itemDiscovered = 1;
+ d->drawSubtreeRecursive(item, painter, &viewTransform, expose, widget);
+ }
+ }
+
+ d->rectAdjust = oldRectAdjust;
+ // Reset discovery bits.
+ for (int i = 0; i < topLevelItems.size(); ++i)
+ topLevelItems.at(i)->d_ptr->itemDiscovered = 0;
+
+ painter->setWorldTransform(viewTransform);
+ painter->setOpacity(opacity);
+}
+
+/*!
+ \since 4.4
+
+ Finds a new widget to give the keyboard focus to, as appropriate for Tab
+ and Shift+Tab, and returns true if it can find a new widget, or false if
+ it cannot. If \a next is true, this function searches forward; if \a next
+ is false, it searches backward.
+
+ You can reimplement this function in a subclass of QGraphicsScene to
+ provide fine-grained control over how tab focus passes inside your
+ scene. The default implementation is based on the tab focus chain defined
+ by QGraphicsWidget::setTabOrder().
+*/
+bool QGraphicsScene::focusNextPrevChild(bool next)
+{
+ Q_D(QGraphicsScene);
+
+ QGraphicsItem *item = focusItem();
+ if (item && !item->isWidget()) {
+ // Tab out of the scene.
+ return false;
+ }
+ if (!item) {
+ if (d->lastFocusItem && !d->lastFocusItem->isWidget()) {
+ // Restore focus to the last focusable non-widget item that had
+ // focus.
+ setFocusItem(d->lastFocusItem, next ? Qt::TabFocusReason : Qt::BacktabFocusReason);
+ return true;
+ }
+ }
+ if (!d->tabFocusFirst) {
+ // No widgets...
+ return false;
+ }
+
+ // The item must be a widget.
+ QGraphicsWidget *widget = 0;
+ if (!item) {
+ widget = next ? d->tabFocusFirst : d->tabFocusFirst->d_func()->focusPrev;
+ } else {
+ QGraphicsWidget *test = static_cast<QGraphicsWidget *>(item);
+ widget = next ? test->d_func()->focusNext : test->d_func()->focusPrev;
+ if ((next && widget == d->tabFocusFirst) || (!next && widget == d->tabFocusFirst->d_func()->focusPrev))
+ return false;
+ }
+ QGraphicsWidget *widgetThatHadFocus = widget;
+
+ // Run around the focus chain until we find a widget that can take tab focus.
+ do {
+ if (widget->flags() & QGraphicsItem::ItemIsFocusable
+ && widget->isEnabled() && widget->isVisibleTo(0)
+ && (widget->focusPolicy() & Qt::TabFocus)
+ && (!item || !item->isPanel() || item->isAncestorOf(widget))
+ ) {
+ setFocusItem(widget, next ? Qt::TabFocusReason : Qt::BacktabFocusReason);
+ return true;
+ }
+ widget = next ? widget->d_func()->focusNext : widget->d_func()->focusPrev;
+ if ((next && widget == d->tabFocusFirst) || (!next && widget == d->tabFocusFirst->d_func()->focusPrev))
+ return false;
+ } while (widget != widgetThatHadFocus);
+
+ return false;
+}
+
+/*!
+ \fn QGraphicsScene::changed(const QList<QRectF> &region)
+
+ This signal is emitted by QGraphicsScene when control reaches the
+ event loop, if the scene content changes. The \a region parameter
+ contains a list of scene rectangles that indicate the area that
+ has been changed.
+
+ \sa QGraphicsView::updateScene()
+*/
+
+/*!
+ \fn QGraphicsScene::sceneRectChanged(const QRectF &rect)
+
+ This signal is emitted by QGraphicsScene whenever the scene rect changes.
+ The \a rect parameter is the new scene rectangle.
+
+ \sa QGraphicsView::updateSceneRect()
+*/
+
+/*!
+ \fn QGraphicsScene::selectionChanged()
+ \since 4.3
+
+ This signal is emitted by QGraphicsScene whenever the selection
+ changes. You can call selectedItems() to get the new list of selected
+ items.
+
+ The selection changes whenever an item is selected or unselected, a
+ selection area is set, cleared or otherwise changed, if a preselected item
+ is added to the scene, or if a selected item is removed from the scene.
+
+ QGraphicsScene emits this signal only once for group selection operations.
+ For example, if you set a selection area, select or unselect a
+ QGraphicsItemGroup, or if you add or remove from the scene a parent item
+ that contains several selected items, selectionChanged() is emitted only
+ once after the operation has completed (instead of once for each item).
+
+ \sa setSelectionArea(), selectedItems(), QGraphicsItem::setSelected()
+*/
+
+/*!
+ \since 4.4
+
+ Returns the scene's style, or the same as QApplication::style() if the
+ scene has not been explicitly assigned a style.
+
+ \sa setStyle()
+*/
+QStyle *QGraphicsScene::style() const
+{
+ Q_D(const QGraphicsScene);
+ // ### This function, and the use of styles in general, is non-reentrant.
+ return d->style ? d->style : QApplication::style();
+}
+
+/*!
+ \since 4.4
+
+ Sets or replaces the style of the scene to \a style, and reparents the
+ style to this scene. Any previously assigned style is deleted. The scene's
+ style defaults to QApplication::style(), and serves as the default for all
+ QGraphicsWidget items in the scene.
+
+ Changing the style, either directly by calling this function, or
+ indirectly by calling QApplication::setStyle(), will automatically update
+ the style for all widgets in the scene that do not have a style explicitly
+ assigned to them.
+
+ If \a style is 0, QGraphicsScene will revert to QApplication::style().
+
+ \sa style()
+*/
+void QGraphicsScene::setStyle(QStyle *style)
+{
+ Q_D(QGraphicsScene);
+ // ### This function, and the use of styles in general, is non-reentrant.
+ if (style == d->style)
+ return;
+
+ // Delete the old style,
+ delete d->style;
+ if ((d->style = style))
+ d->style->setParent(this);
+
+ // Notify the scene.
+ QEvent event(QEvent::StyleChange);
+ QApplication::sendEvent(this, &event);
+
+ // Notify all widgets that don't have a style explicitly set.
+ foreach (QGraphicsItem *item, items()) {
+ if (item->isWidget()) {
+ QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(item);
+ if (!widget->testAttribute(Qt::WA_SetStyle))
+ QApplication::sendEvent(widget, &event);
+ }
+ }
+}
+
+/*!
+ \property QGraphicsScene::font
+ \since 4.4
+ \brief the scene's default font
+
+ This property provides the scene's font. The scene font defaults to,
+ and resolves all its entries from, QApplication::font.
+
+ If the scene's font changes, either directly through setFont() or
+ indirectly when the application font changes, QGraphicsScene first
+ sends itself a \l{QEvent::FontChange}{FontChange} event, and it then
+ sends \l{QEvent::FontChange}{FontChange} events to all top-level
+ widget items in the scene. These items respond by resolving their own
+ fonts to the scene, and they then notify their children, who again
+ notify their children, and so on, until all widget items have updated
+ their fonts.
+
+ Changing the scene font, (directly or indirectly through
+ QApplication::setFont(),) automatically schedules a redraw the entire
+ scene.
+
+ \sa QWidget::font, QApplication::setFont(), palette, style()
+*/
+QFont QGraphicsScene::font() const
+{
+ Q_D(const QGraphicsScene);
+ return d->font;
+}
+void QGraphicsScene::setFont(const QFont &font)
+{
+ Q_D(QGraphicsScene);
+ QFont naturalFont = QApplication::font();
+ naturalFont.resolve(0);
+ QFont resolvedFont = font.resolve(naturalFont);
+ d->setFont_helper(resolvedFont);
+}
+
+/*!
+ \property QGraphicsScene::palette
+ \since 4.4
+ \brief the scene's default palette
+
+ This property provides the scene's palette. The scene palette defaults to,
+ and resolves all its entries from, QApplication::palette.
+
+ If the scene's palette changes, either directly through setPalette() or
+ indirectly when the application palette changes, QGraphicsScene first
+ sends itself a \l{QEvent::PaletteChange}{PaletteChange} event, and it then
+ sends \l{QEvent::PaletteChange}{PaletteChange} events to all top-level
+ widget items in the scene. These items respond by resolving their own
+ palettes to the scene, and they then notify their children, who again
+ notify their children, and so on, until all widget items have updated
+ their palettes.
+
+ Changing the scene palette, (directly or indirectly through
+ QApplication::setPalette(),) automatically schedules a redraw the entire
+ scene.
+
+ \sa QWidget::palette, QApplication::setPalette(), font, style()
+*/
+QPalette QGraphicsScene::palette() const
+{
+ Q_D(const QGraphicsScene);
+ return d->palette;
+}
+void QGraphicsScene::setPalette(const QPalette &palette)
+{
+ Q_D(QGraphicsScene);
+ QPalette naturalPalette = QApplication::palette();
+ naturalPalette.resolve(0);
+ QPalette resolvedPalette = palette.resolve(naturalPalette);
+ d->setPalette_helper(resolvedPalette);
+}
+
+/*!
+ \since 4.6
+
+ Returns true if the scene is active (e.g., it's viewed by
+ at least one QGraphicsView that is active); otherwise returns false.
+
+ \sa QGraphicsItem::isActive(), QWidget::isActiveWindow()
+*/
+bool QGraphicsScene::isActive() const
+{
+ Q_D(const QGraphicsScene);
+ return d->activationRefCount > 0;
+}
+
+/*!
+ \since 4.6
+ Returns the current active panel, or 0 if no panel is currently active.
+
+ \sa QGraphicsScene::setActivePanel()
+*/
+QGraphicsItem *QGraphicsScene::activePanel() const
+{
+ Q_D(const QGraphicsScene);
+ return d->activePanel;
+}
+
+/*!
+ \since 4.6
+ Activates \a item, which must be an item in this scene. You
+ can also pass 0 for \a item, in which case QGraphicsScene will
+ deactivate any currently active panel.
+
+ If the scene is currently inactive, \a item remains inactive until the
+ scene becomes active (or, ir \a item is 0, no item will be activated).
+
+ \sa activePanel(), isActive(), QGraphicsItem::isActive()
+*/
+void QGraphicsScene::setActivePanel(QGraphicsItem *item)
+{
+ Q_D(QGraphicsScene);
+ d->setActivePanelHelper(item, false);
+}
+
+/*!
+ \since 4.4
+
+ Returns the current active window, or 0 if no window is currently
+ active.
+
+ \sa QGraphicsScene::setActiveWindow()
+*/
+QGraphicsWidget *QGraphicsScene::activeWindow() const
+{
+ Q_D(const QGraphicsScene);
+ if (d->activePanel && d->activePanel->isWindow())
+ return static_cast<QGraphicsWidget *>(d->activePanel);
+ return 0;
+}
+
+/*!
+ \since 4.4
+ Activates \a widget, which must be a widget in this scene. You can also
+ pass 0 for \a widget, in which case QGraphicsScene will deactivate any
+ currently active window.
+
+ \sa activeWindow(), QGraphicsWidget::isActiveWindow()
+*/
+void QGraphicsScene::setActiveWindow(QGraphicsWidget *widget)
+{
+ if (widget && widget->scene() != this) {
+ qWarning("QGraphicsScene::setActiveWindow: widget %p must be part of this scene",
+ widget);
+ return;
+ }
+
+ // Activate the widget's panel (all windows are panels).
+ QGraphicsItem *panel = widget ? widget->panel() : 0;
+ setActivePanel(panel);
+
+ // Raise
+ if (panel) {
+ QList<QGraphicsItem *> siblingWindows;
+ QGraphicsItem *parent = panel->parentItem();
+ // Raise ### inefficient for toplevels
+ foreach (QGraphicsItem *sibling, parent ? parent->children() : items()) {
+ if (sibling != panel && sibling->isWindow())
+ siblingWindows << sibling;
+ }
+
+ // Find the highest z value.
+ qreal z = panel->zValue();
+ for (int i = 0; i < siblingWindows.size(); ++i)
+ z = qMax(z, siblingWindows.at(i)->zValue());
+
+ // This will probably never overflow.
+ const qreal litt = qreal(0.001);
+ panel->setZValue(z + litt);
+ }
+}
+
+/*!
+ \since 4.6
+
+ Sends event \a event to item \a item through possible event filters.
+
+ The event is sent only if the item is enabled.
+
+ Returns \c false if the event was filtered or if the item is disabled.
+ Otherwise returns the value that was returned from the event handler.
+
+ \sa QGraphicsItem::sceneEvent(), QGraphicsItem::sceneEventFilter()
+*/
+bool QGraphicsScene::sendEvent(QGraphicsItem *item, QEvent *event)
+{
+ Q_D(QGraphicsScene);
+ if (!item) {
+ qWarning("QGraphicsScene::sendEvent: cannot send event to a null item");
+ return false;
+ }
+ if (item->scene() != this) {
+ qWarning("QGraphicsScene::sendEvent: item %p's scene (%p)"
+ " is different from this scene (%p)",
+ item, item->scene(), this);
+ return false;
+ }
+ return d->sendEvent(item, event);
+}
+
+void QGraphicsScenePrivate::addView(QGraphicsView *view)
+{
+ views << view;
+#ifndef QT_NO_GESTURES
+ foreach (Qt::GestureType gesture, grabbedGestures.keys())
+ view->viewport()->grabGesture(gesture);
+#endif
+}
+
+void QGraphicsScenePrivate::removeView(QGraphicsView *view)
+{
+ views.removeAll(view);
+}
+
+void QGraphicsScenePrivate::updateTouchPointsForItem(QGraphicsItem *item, QTouchEvent *touchEvent)
+{
+ QList<QTouchEvent::TouchPoint> touchPoints = touchEvent->touchPoints();
+ for (int i = 0; i < touchPoints.count(); ++i) {
+ QTouchEvent::TouchPoint &touchPoint = touchPoints[i];
+ touchPoint.setRect(item->mapFromScene(touchPoint.sceneRect()).boundingRect());
+ touchPoint.setStartPos(item->d_ptr->genericMapFromScene(touchPoint.startScenePos(), touchEvent->widget()));
+ touchPoint.setLastPos(item->d_ptr->genericMapFromScene(touchPoint.lastScenePos(), touchEvent->widget()));
+ }
+ touchEvent->setTouchPoints(touchPoints);
+}
+
+int QGraphicsScenePrivate::findClosestTouchPointId(const QPointF &scenePos)
+{
+ int closestTouchPointId = -1;
+ qreal closestDistance = qreal(0.);
+ foreach (const QTouchEvent::TouchPoint &touchPoint, sceneCurrentTouchPoints) {
+ qreal distance = QLineF(scenePos, touchPoint.scenePos()).length();
+ if (closestTouchPointId == -1|| distance < closestDistance) {
+ closestTouchPointId = touchPoint.id();
+ closestDistance = distance;
+ }
+ }
+ return closestTouchPointId;
+}
+
+void QGraphicsScenePrivate::touchEventHandler(QTouchEvent *sceneTouchEvent)
+{
+ typedef QPair<Qt::TouchPointStates, QList<QTouchEvent::TouchPoint> > StatesAndTouchPoints;
+ QHash<QGraphicsItem *, StatesAndTouchPoints> itemsNeedingEvents;
+
+ for (int i = 0; i < sceneTouchEvent->touchPoints().count(); ++i) {
+ const QTouchEvent::TouchPoint &touchPoint = sceneTouchEvent->touchPoints().at(i);
+
+ // update state
+ QGraphicsItem *item = 0;
+ if (touchPoint.state() == Qt::TouchPointPressed) {
+ if (sceneTouchEvent->deviceType() == QTouchEvent::TouchPad) {
+ // on touch-pad devices, send all touch points to the same item
+ item = itemForTouchPointId.isEmpty()
+ ? 0
+ : itemForTouchPointId.constBegin().value();
+ }
+
+ if (!item) {
+ // determine which item this touch point will go to
+ cachedItemsUnderMouse = itemsAtPosition(touchPoint.screenPos().toPoint(),
+ touchPoint.scenePos(),
+ sceneTouchEvent->widget());
+ item = cachedItemsUnderMouse.isEmpty() ? 0 : cachedItemsUnderMouse.first();
+ }
+
+ if (sceneTouchEvent->deviceType() == QTouchEvent::TouchScreen) {
+ // on touch-screens, combine this touch point with the closest one we find
+ int closestTouchPointId = findClosestTouchPointId(touchPoint.scenePos());
+ QGraphicsItem *closestItem = itemForTouchPointId.value(closestTouchPointId);
+ if (!item || (closestItem && cachedItemsUnderMouse.contains(closestItem)))
+ item = closestItem;
+ }
+ if (!item)
+ continue;
+
+ itemForTouchPointId.insert(touchPoint.id(), item);
+ sceneCurrentTouchPoints.insert(touchPoint.id(), touchPoint);
+ } else if (touchPoint.state() == Qt::TouchPointReleased) {
+ item = itemForTouchPointId.take(touchPoint.id());
+ if (!item)
+ continue;
+
+ sceneCurrentTouchPoints.remove(touchPoint.id());
+ } else {
+ item = itemForTouchPointId.value(touchPoint.id());
+ if (!item)
+ continue;
+ Q_ASSERT(sceneCurrentTouchPoints.contains(touchPoint.id()));
+ sceneCurrentTouchPoints[touchPoint.id()] = touchPoint;
+ }
+
+ StatesAndTouchPoints &statesAndTouchPoints = itemsNeedingEvents[item];
+ statesAndTouchPoints.first |= touchPoint.state();
+ statesAndTouchPoints.second.append(touchPoint);
+ }
+
+ if (itemsNeedingEvents.isEmpty()) {
+ sceneTouchEvent->accept();
+ return;
+ }
+
+ bool ignoreSceneTouchEvent = true;
+ QHash<QGraphicsItem *, StatesAndTouchPoints>::ConstIterator it = itemsNeedingEvents.constBegin();
+ const QHash<QGraphicsItem *, StatesAndTouchPoints>::ConstIterator end = itemsNeedingEvents.constEnd();
+ for (; it != end; ++it) {
+ QGraphicsItem *item = it.key();
+
+ (void) item->isBlockedByModalPanel(&item);
+
+ // determine event type from the state mask
+ QEvent::Type eventType;
+ switch (it.value().first) {
+ case Qt::TouchPointPressed:
+ // all touch points have pressed state
+ eventType = QEvent::TouchBegin;
+ break;
+ case Qt::TouchPointReleased:
+ // all touch points have released state
+ eventType = QEvent::TouchEnd;
+ break;
+ case Qt::TouchPointStationary:
+ // don't send the event if nothing changed
+ continue;
+ default:
+ // all other combinations
+ eventType = QEvent::TouchUpdate;
+ break;
+ }
+
+ QTouchEvent touchEvent(eventType);
+ touchEvent.setWidget(sceneTouchEvent->widget());
+ touchEvent.setDeviceType(sceneTouchEvent->deviceType());
+ touchEvent.setModifiers(sceneTouchEvent->modifiers());
+ touchEvent.setTouchPointStates(it.value().first);
+ touchEvent.setTouchPoints(it.value().second);
+
+ switch (touchEvent.type()) {
+ case QEvent::TouchBegin:
+ {
+ // if the TouchBegin handler recurses, we assume that means the event
+ // has been implicitly accepted and continue to send touch events
+ item->d_ptr->acceptedTouchBeginEvent = true;
+ bool res = sendTouchBeginEvent(item, &touchEvent)
+ && touchEvent.isAccepted();
+ if (!res) {
+ // forget about these touch points, we didn't handle them
+ for (int i = 0; i < touchEvent.touchPoints().count(); ++i) {
+ const QTouchEvent::TouchPoint &touchPoint = touchEvent.touchPoints().at(i);
+ itemForTouchPointId.remove(touchPoint.id());
+ sceneCurrentTouchPoints.remove(touchPoint.id());
+ }
+ ignoreSceneTouchEvent = false;
+ }
+ break;
+ }
+ default:
+ if (item->d_ptr->acceptedTouchBeginEvent) {
+ updateTouchPointsForItem(item, &touchEvent);
+ (void) sendEvent(item, &touchEvent);
+ ignoreSceneTouchEvent = false;
+ }
+ break;
+ }
+ }
+ sceneTouchEvent->setAccepted(ignoreSceneTouchEvent);
+}
+
+bool QGraphicsScenePrivate::sendTouchBeginEvent(QGraphicsItem *origin, QTouchEvent *touchEvent)
+{
+ Q_Q(QGraphicsScene);
+
+ if (cachedItemsUnderMouse.isEmpty() || cachedItemsUnderMouse.first() != origin) {
+ const QTouchEvent::TouchPoint &firstTouchPoint = touchEvent->touchPoints().first();
+ cachedItemsUnderMouse = itemsAtPosition(firstTouchPoint.screenPos().toPoint(),
+ firstTouchPoint.scenePos(),
+ touchEvent->widget());
+ }
+ Q_ASSERT(cachedItemsUnderMouse.first() == origin);
+
+ // Set focus on the topmost enabled item that can take focus.
+ bool setFocus = false;
+
+ foreach (QGraphicsItem *item, cachedItemsUnderMouse) {
+ if (item->isEnabled() && ((item->flags() & QGraphicsItem::ItemIsFocusable) && item->d_ptr->mouseSetsFocus)) {
+ if (!item->isWidget() || ((QGraphicsWidget *)item)->focusPolicy() & Qt::ClickFocus) {
+ setFocus = true;
+ if (item != q->focusItem())
+ q->setFocusItem(item, Qt::MouseFocusReason);
+ break;
+ }
+ }
+ if (item->isPanel())
+ break;
+ if (item->d_ptr->flags & QGraphicsItem::ItemStopsClickFocusPropagation)
+ break;
+ if (item->d_ptr->flags & QGraphicsItem::ItemStopsFocusHandling) {
+ // Make sure we don't clear focus.
+ setFocus = true;
+ break;
+ }
+ }
+
+ // If nobody could take focus, clear it.
+ if (!stickyFocus && !setFocus)
+ q->setFocusItem(0, Qt::MouseFocusReason);
+
+ bool res = false;
+ bool eventAccepted = touchEvent->isAccepted();
+ foreach (QGraphicsItem *item, cachedItemsUnderMouse) {
+ // first, try to deliver the touch event
+ updateTouchPointsForItem(item, touchEvent);
+ bool acceptTouchEvents = item->acceptTouchEvents();
+ touchEvent->setAccepted(acceptTouchEvents);
+ res = acceptTouchEvents && sendEvent(item, touchEvent);
+ eventAccepted = touchEvent->isAccepted();
+ if (itemForTouchPointId.value(touchEvent->touchPoints().first().id()) == 0) {
+ // item was deleted
+ item = 0;
+ } else {
+ item->d_ptr->acceptedTouchBeginEvent = (res && eventAccepted);
+ }
+ touchEvent->spont = false;
+ if (res && eventAccepted) {
+ // the first item to accept the TouchBegin gets an implicit grab.
+ for (int i = 0; i < touchEvent->touchPoints().count(); ++i) {
+ const QTouchEvent::TouchPoint &touchPoint = touchEvent->touchPoints().at(i);
+ itemForTouchPointId[touchPoint.id()] = item; // can be zero
+ }
+ break;
+ }
+ if (item && item->isPanel())
+ break;
+ }
+
+ touchEvent->setAccepted(eventAccepted);
+ return res;
+}
+
+void QGraphicsScenePrivate::enableTouchEventsOnViews()
+{
+ foreach (QGraphicsView *view, views)
+ view->viewport()->setAttribute(Qt::WA_AcceptTouchEvents, true);
+}
+
+void QGraphicsScenePrivate::updateInputMethodSensitivityInViews()
+{
+ for (int i = 0; i < views.size(); ++i)
+ views.at(i)->d_func()->updateInputMethodSensitivity();
+}
+
+void QGraphicsScenePrivate::enterModal(QGraphicsItem *panel, QGraphicsItem::PanelModality previousModality)
+{
+ Q_Q(QGraphicsScene);
+ Q_ASSERT(panel && panel->isPanel());
+
+ QGraphicsItem::PanelModality panelModality = panel->d_ptr->panelModality;
+ if (previousModality != QGraphicsItem::NonModal) {
+ // the panel is changing from one modality type to another... temporarily set it back so
+ // that blockedPanels is populated correctly
+ panel->d_ptr->panelModality = previousModality;
+ }
+
+ QSet<QGraphicsItem *> blockedPanels;
+ QList<QGraphicsItem *> items = q->items(); // ### store panels separately
+ for (int i = 0; i < items.count(); ++i) {
+ QGraphicsItem *item = items.at(i);
+ if (item->isPanel() && item->isBlockedByModalPanel())
+ blockedPanels.insert(item);
+ }
+ // blockedPanels contains all currently blocked panels
+
+ if (previousModality != QGraphicsItem::NonModal) {
+ // reset the modality to the proper value, since we changed it above
+ panel->d_ptr->panelModality = panelModality;
+ // remove this panel so that it will be reinserted at the front of the stack
+ modalPanels.removeAll(panel);
+ }
+
+ modalPanels.prepend(panel);
+
+ if (!hoverItems.isEmpty()) {
+ // send GraphicsSceneHoverLeave events to newly blocked hoverItems
+ QGraphicsSceneHoverEvent hoverEvent;
+ hoverEvent.setScenePos(lastSceneMousePos);
+ dispatchHoverEvent(&hoverEvent);
+ }
+
+ if (!mouseGrabberItems.isEmpty() && lastMouseGrabberItemHasImplicitMouseGrab) {
+ QGraphicsItem *item = mouseGrabberItems.last();
+ if (item->isBlockedByModalPanel())
+ ungrabMouse(item, /*itemIsDying =*/ false);
+ }
+
+ QEvent windowBlockedEvent(QEvent::WindowBlocked);
+ QEvent windowUnblockedEvent(QEvent::WindowUnblocked);
+ for (int i = 0; i < items.count(); ++i) {
+ QGraphicsItem *item = items.at(i);
+ if (item->isPanel()) {
+ if (!blockedPanels.contains(item) && item->isBlockedByModalPanel()) {
+ // send QEvent::WindowBlocked to newly blocked panels
+ sendEvent(item, &windowBlockedEvent);
+ } else if (blockedPanels.contains(item) && !item->isBlockedByModalPanel()) {
+ // send QEvent::WindowUnblocked to unblocked panels when downgrading
+ // a panel from SceneModal to PanelModal
+ sendEvent(item, &windowUnblockedEvent);
+ }
+ }
+ }
+}
+
+void QGraphicsScenePrivate::leaveModal(QGraphicsItem *panel)
+{
+ Q_Q(QGraphicsScene);
+ Q_ASSERT(panel && panel->isPanel());
+
+ QSet<QGraphicsItem *> blockedPanels;
+ QList<QGraphicsItem *> items = q->items(); // ### same as above
+ for (int i = 0; i < items.count(); ++i) {
+ QGraphicsItem *item = items.at(i);
+ if (item->isPanel() && item->isBlockedByModalPanel())
+ blockedPanels.insert(item);
+ }
+
+ modalPanels.removeAll(panel);
+
+ QEvent e(QEvent::WindowUnblocked);
+ for (int i = 0; i < items.count(); ++i) {
+ QGraphicsItem *item = items.at(i);
+ if (item->isPanel() && blockedPanels.contains(item) && !item->isBlockedByModalPanel())
+ sendEvent(item, &e);
+ }
+
+ // send GraphicsSceneHoverEnter events to newly unblocked items
+ QGraphicsSceneHoverEvent hoverEvent;
+ hoverEvent.setScenePos(lastSceneMousePos);
+ dispatchHoverEvent(&hoverEvent);
+}
+
+#ifndef QT_NO_GESTURES
+void QGraphicsScenePrivate::gestureTargetsAtHotSpots(const QSet<QGesture *> &gestures,
+ Qt::GestureFlag flag,
+ QHash<QGraphicsObject *, QSet<QGesture *> > *targets,
+ QSet<QGraphicsObject *> *itemsSet,
+ QSet<QGesture *> *normal,
+ QSet<QGesture *> *conflicts)
+{
+ QSet<QGesture *> normalGestures; // that are not in conflicted state.
+ foreach (QGesture *gesture, gestures) {
+ if (!gesture->hasHotSpot())
+ continue;
+ const Qt::GestureType gestureType = gesture->gestureType();
+ QList<QGraphicsItem *> items = itemsAtPosition(QPoint(), gesture->d_func()->sceneHotSpot, 0);
+ for (int j = 0; j < items.size(); ++j) {
+ QGraphicsItem *item = items.at(j);
+
+ // Check if the item is blocked by a modal panel and use it as
+ // a target instead of this item.
+ (void) item->isBlockedByModalPanel(&item);
+
+ if (QGraphicsObject *itemobj = item->toGraphicsObject()) {
+ QGraphicsItemPrivate *d = item->QGraphicsItem::d_func();
+ QMap<Qt::GestureType, Qt::GestureFlags>::const_iterator it =
+ d->gestureContext.find(gestureType);
+ if (it != d->gestureContext.end() && (!flag || (it.value() & flag))) {
+ if (normalGestures.contains(gesture)) {
+ normalGestures.remove(gesture);
+ if (conflicts)
+ conflicts->insert(gesture);
+ } else {
+ normalGestures.insert(gesture);
+ }
+ if (targets)
+ (*targets)[itemobj].insert(gesture);
+ if (itemsSet)
+ (*itemsSet).insert(itemobj);
+ }
+ }
+ // Don't propagate through panels.
+ if (item->isPanel())
+ break;
+ }
+ }
+ if (normal)
+ *normal = normalGestures;
+}
+
+void QGraphicsScenePrivate::gestureEventHandler(QGestureEvent *event)
+{
+ QWidget *viewport = event->widget();
+ if (!viewport)
+ return;
+ QGraphicsView *graphicsView = qobject_cast<QGraphicsView *>(viewport->parent());
+ if (!graphicsView)
+ return;
+
+ QList<QGesture *> allGestures = event->gestures();
+ DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:"
+ << "Gestures:" << allGestures;
+
+ QSet<QGesture *> startedGestures;
+ QPoint delta = viewport->mapFromGlobal(QPoint());
+ QTransform toScene = QTransform::fromTranslate(delta.x(), delta.y())
+ * graphicsView->viewportTransform().inverted();
+ foreach (QGesture *gesture, allGestures) {
+ // cache scene coordinates of the hot spot
+ if (gesture->hasHotSpot()) {
+ gesture->d_func()->sceneHotSpot = toScene.map(gesture->hotSpot());
+ } else {
+ gesture->d_func()->sceneHotSpot = QPointF();
+ }
+
+ QGraphicsObject *target = gestureTargets.value(gesture, 0);
+ if (!target) {
+ // when we are not in started mode but don't have a target
+ // then the only one interested in gesture is the view/scene
+ if (gesture->state() == Qt::GestureStarted)
+ startedGestures.insert(gesture);
+ }
+ }
+
+ if (!startedGestures.isEmpty()) {
+ QSet<QGesture *> normalGestures; // that have just one target
+ QSet<QGesture *> conflictedGestures; // that have multiple possible targets
+ gestureTargetsAtHotSpots(startedGestures, Qt::GestureFlag(0), &cachedItemGestures, 0,
+ &normalGestures, &conflictedGestures);
+ cachedTargetItems = cachedItemGestures.keys();
+ qSort(cachedTargetItems.begin(), cachedTargetItems.end(), qt_closestItemFirst);
+ DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:"
+ << "Normal gestures:" << normalGestures
+ << "Conflicting gestures:" << conflictedGestures;
+
+ // deliver conflicted gestures as override events AND remember
+ // initial gesture targets
+ if (!conflictedGestures.isEmpty()) {
+ for (int i = 0; i < cachedTargetItems.size(); ++i) {
+ QWeakPointer<QGraphicsObject> item = cachedTargetItems.at(i);
+
+ // get gestures to deliver to the current item
+ QSet<QGesture *> gestures = conflictedGestures & cachedItemGestures.value(item.data());
+ if (gestures.isEmpty())
+ continue;
+
+ DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:"
+ << "delivering override to"
+ << item.data() << gestures;
+ // send gesture override
+ QGestureEvent ev(gestures.toList());
+ ev.t = QEvent::GestureOverride;
+ ev.setWidget(event->widget());
+ // mark event and individual gestures as ignored
+ ev.ignore();
+ foreach(QGesture *g, gestures)
+ ev.setAccepted(g, false);
+ sendEvent(item.data(), &ev);
+ // mark all accepted gestures to deliver them as normal gesture events
+ foreach (QGesture *g, gestures) {
+ if (ev.isAccepted() || ev.isAccepted(g)) {
+ conflictedGestures.remove(g);
+ // mark the item as a gesture target
+ if (item) {
+ gestureTargets.insert(g, item.data());
+ QHash<QGraphicsObject *, QSet<QGesture *> >::iterator it, e;
+ it = cachedItemGestures.begin();
+ e = cachedItemGestures.end();
+ for(; it != e; ++it)
+ it.value().remove(g);
+ cachedItemGestures[item.data()].insert(g);
+ }
+ DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:"
+ << "override was accepted:"
+ << g << item.data();
+ }
+ // remember the first item that received the override event
+ // as it most likely become a target if no one else accepts
+ // the override event
+ if (!gestureTargets.contains(g) && item)
+ gestureTargets.insert(g, item.data());
+
+ }
+ if (conflictedGestures.isEmpty())
+ break;
+ }
+ }
+ // remember the initial target item for each gesture that was not in
+ // the conflicted state.
+ if (!normalGestures.isEmpty()) {
+ for (int i = 0; i < cachedTargetItems.size() && !normalGestures.isEmpty(); ++i) {
+ QGraphicsObject *item = cachedTargetItems.at(i);
+
+ // get gestures to deliver to the current item
+ foreach (QGesture *g, cachedItemGestures.value(item)) {
+ if (!gestureTargets.contains(g)) {
+ gestureTargets.insert(g, item);
+ normalGestures.remove(g);
+ }
+ }
+ }
+ }
+ }
+
+
+ // deliver all gesture events
+ QSet<QGesture *> undeliveredGestures;
+ QSet<QGesture *> parentPropagatedGestures;
+ foreach (QGesture *gesture, allGestures) {
+ if (QGraphicsObject *target = gestureTargets.value(gesture, 0)) {
+ cachedItemGestures[target].insert(gesture);
+ cachedTargetItems.append(target);
+ undeliveredGestures.insert(gesture);
+ QGraphicsItemPrivate *d = target->QGraphicsItem::d_func();
+ const Qt::GestureFlags flags = d->gestureContext.value(gesture->gestureType());
+ if (flags & Qt::IgnoredGesturesPropagateToParent)
+ parentPropagatedGestures.insert(gesture);
+ } else {
+ DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:"
+ << "no target for" << gesture << "at"
+ << gesture->hotSpot() << gesture->d_func()->sceneHotSpot;
+ }
+ }
+ qSort(cachedTargetItems.begin(), cachedTargetItems.end(), qt_closestItemFirst);
+ for (int i = 0; i < cachedTargetItems.size(); ++i) {
+ QWeakPointer<QGraphicsObject> receiver = cachedTargetItems.at(i);
+ QSet<QGesture *> gestures =
+ undeliveredGestures & cachedItemGestures.value(receiver.data());
+ gestures -= cachedAlreadyDeliveredGestures.value(receiver.data());
+
+ if (gestures.isEmpty())
+ continue;
+
+ cachedAlreadyDeliveredGestures[receiver.data()] += gestures;
+ const bool isPanel = receiver.data()->isPanel();
+
+ DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:"
+ << "delivering to"
+ << receiver.data() << gestures;
+ QGestureEvent ev(gestures.toList());
+ ev.setWidget(event->widget());
+ sendEvent(receiver.data(), &ev);
+ QSet<QGesture *> ignoredGestures;
+ foreach (QGesture *g, gestures) {
+ if (!ev.isAccepted() && !ev.isAccepted(g)) {
+ // if the gesture was ignored by its target, we will update the
+ // targetItems list with a possible target items (items that
+ // want to receive partial gestures).
+ // ### wont' work if the target was destroyed in the event
+ // we will just stop delivering it.
+ if (receiver && receiver.data() == gestureTargets.value(g, 0))
+ ignoredGestures.insert(g);
+ } else {
+ if (receiver && g->state() == Qt::GestureStarted) {
+ // someone accepted the propagated initial GestureStarted
+ // event, let it be the new target for all following events.
+ gestureTargets[g] = receiver.data();
+ }
+ undeliveredGestures.remove(g);
+ }
+ }
+ if (undeliveredGestures.isEmpty())
+ break;
+
+ // ignoredGestures list is only filled when delivering to the gesture
+ // target item, so it is safe to assume item == target.
+ if (!ignoredGestures.isEmpty() && !isPanel) {
+ // look for new potential targets for gestures that were ignored
+ // and should be propagated.
+
+ QSet<QGraphicsObject *> targetsSet = cachedTargetItems.toSet();
+
+ if (receiver) {
+ // first if the gesture should be propagated to parents only
+ for (QSet<QGesture *>::iterator it = ignoredGestures.begin();
+ it != ignoredGestures.end();) {
+ if (parentPropagatedGestures.contains(*it)) {
+ QGesture *gesture = *it;
+ const Qt::GestureType gestureType = gesture->gestureType();
+ QGraphicsItem *item = receiver.data();
+ while (item) {
+ if (QGraphicsObject *obj = item->toGraphicsObject()) {
+ if (item->d_func()->gestureContext.contains(gestureType)) {
+ targetsSet.insert(obj);
+ cachedItemGestures[obj].insert(gesture);
+ }
+ }
+ if (item->isPanel())
+ break;
+ item = item->parentItem();
+ }
+
+ it = ignoredGestures.erase(it);
+ continue;
+ }
+ ++it;
+ }
+ }
+
+ gestureTargetsAtHotSpots(ignoredGestures, Qt::ReceivePartialGestures,
+ &cachedItemGestures, &targetsSet, 0, 0);
+
+ cachedTargetItems = targetsSet.toList();
+ qSort(cachedTargetItems.begin(), cachedTargetItems.end(), qt_closestItemFirst);
+ DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:"
+ << "new targets:" << cachedTargetItems;
+ i = -1; // start delivery again
+ continue;
+ }
+ }
+
+ foreach (QGesture *g, startedGestures) {
+ if (g->gestureCancelPolicy() == QGesture::CancelAllInContext) {
+ DEBUG() << "lets try to cancel some";
+ // find gestures in context in Qt::GestureStarted or Qt::GestureUpdated state and cancel them
+ cancelGesturesForChildren(g);
+ }
+ }
+
+ // forget about targets for gestures that have ended
+ foreach (QGesture *g, allGestures) {
+ switch (g->state()) {
+ case Qt::GestureFinished:
+ case Qt::GestureCanceled:
+ gestureTargets.remove(g);
+ break;
+ default:
+ break;
+ }
+ }
+
+ cachedTargetItems.clear();
+ cachedItemGestures.clear();
+ cachedAlreadyDeliveredGestures.clear();
+}
+
+void QGraphicsScenePrivate::cancelGesturesForChildren(QGesture *original)
+{
+ Q_ASSERT(original);
+ QGraphicsItem *originalItem = gestureTargets.value(original);
+ if (originalItem == 0) // we only act on accepted gestures, which implies it has a target.
+ return;
+
+ // iterate over all active gestures and for each find the owner
+ // if the owner is part of our sub-hierarchy, cancel it.
+
+ QSet<QGesture *> canceledGestures;
+ QHash<QGesture *, QGraphicsObject *>::Iterator iter = gestureTargets.begin();
+ while (iter != gestureTargets.end()) {
+ QGraphicsObject *item = iter.value();
+ // note that we don't touch the gestures for our originalItem
+ if (item != originalItem && originalItem->isAncestorOf(item)) {
+ DEBUG() << " found a gesture to cancel" << iter.key();
+ iter.key()->d_func()->state = Qt::GestureCanceled;
+ canceledGestures << iter.key();
+ }
+ ++iter;
+ }
+
+ // sort them per target item by cherry picking from almostCanceledGestures and delivering
+ QSet<QGesture *> almostCanceledGestures = canceledGestures;
+ QSet<QGesture *>::Iterator setIter;
+ while (!almostCanceledGestures.isEmpty()) {
+ QGraphicsObject *target = 0;
+ QSet<QGesture*> gestures;
+ setIter = almostCanceledGestures.begin();
+ // sort per target item
+ while (setIter != almostCanceledGestures.end()) {
+ QGraphicsObject *item = gestureTargets.value(*setIter);
+ if (target == 0)
+ target = item;
+ if (target == item) {
+ gestures << *setIter;
+ setIter = almostCanceledGestures.erase(setIter);
+ } else {
+ ++setIter;
+ }
+ }
+ Q_ASSERT(target);
+
+ QList<QGesture *> list = gestures.toList();
+ QGestureEvent ev(list);
+ sendEvent(target, &ev);
+
+ foreach (QGesture *g, list) {
+ if (ev.isAccepted() || ev.isAccepted(g))
+ gestures.remove(g);
+ }
+
+ foreach (QGesture *g, gestures) {
+ if (!g->hasHotSpot())
+ continue;
+
+ QList<QGraphicsItem *> items = itemsAtPosition(QPoint(), g->d_func()->sceneHotSpot, 0);
+ for (int j = 0; j < items.size(); ++j) {
+ QGraphicsObject *item = items.at(j)->toGraphicsObject();
+ if (!item)
+ continue;
+ QGraphicsItemPrivate *d = item->QGraphicsItem::d_func();
+ if (d->gestureContext.contains(g->gestureType())) {
+ QList<QGesture *> list;
+ list << g;
+ QGestureEvent ev(list);
+ sendEvent(item, &ev);
+ if (ev.isAccepted() || ev.isAccepted(g))
+ break; // successfully delivered
+ }
+ }
+ }
+ }
+
+ QGestureManager *gestureManager = QApplicationPrivate::instance()->gestureManager;
+ Q_ASSERT(gestureManager); // it would be very odd if we got called without a manager.
+ for (setIter = canceledGestures.begin(); setIter != canceledGestures.end(); ++setIter) {
+ gestureManager->recycle(*setIter);
+ gestureTargets.remove(*setIter);
+ }
+}
+
+void QGraphicsScenePrivate::grabGesture(QGraphicsItem *, Qt::GestureType gesture)
+{
+ (void)QGestureManager::instance(); // create a gesture manager
+ if (!grabbedGestures[gesture]++) {
+ foreach (QGraphicsView *view, views)
+ view->viewport()->grabGesture(gesture);
+ }
+}
+
+void QGraphicsScenePrivate::ungrabGesture(QGraphicsItem *item, Qt::GestureType gesture)
+{
+ // we know this can only be an object
+ Q_ASSERT(item->d_ptr->isObject);
+ QGraphicsObject *obj = static_cast<QGraphicsObject *>(item);
+ QGestureManager::instance()->cleanupCachedGestures(obj, gesture);
+ if (!--grabbedGestures[gesture]) {
+ foreach (QGraphicsView *view, views)
+ view->viewport()->ungrabGesture(gesture);
+ }
+}
+#endif // QT_NO_GESTURES
+
+QT_END_NAMESPACE
+
+#include "moc_qgraphicsscene.cpp"
+
+#endif // QT_NO_GRAPHICSVIEW
diff --git a/src/widgets/graphicsview/qgraphicsscene.h b/src/widgets/graphicsview/qgraphicsscene.h
new file mode 100644
index 0000000000..7895584827
--- /dev/null
+++ b/src/widgets/graphicsview/qgraphicsscene.h
@@ -0,0 +1,329 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGRAPHICSSCENE_H
+#define QGRAPHICSSCENE_H
+
+#include <QtCore/qobject.h>
+#include <QtCore/qpoint.h>
+#include <QtCore/qrect.h>
+#include <QtGui/qbrush.h>
+#include <QtGui/qfont.h>
+#include <QtGui/qtransform.h>
+#include <QtGui/qmatrix.h>
+#include <QtGui/qpen.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW
+
+template<typename T> class QList;
+class QFocusEvent;
+class QFont;
+class QFontMetrics;
+class QGraphicsEllipseItem;
+class QGraphicsItem;
+class QGraphicsItemGroup;
+class QGraphicsLineItem;
+class QGraphicsPathItem;
+class QGraphicsPixmapItem;
+class QGraphicsPolygonItem;
+class QGraphicsProxyWidget;
+class QGraphicsRectItem;
+class QGraphicsSceneContextMenuEvent;
+class QGraphicsSceneDragDropEvent;
+class QGraphicsSceneEvent;
+class QGraphicsSceneHelpEvent;
+class QGraphicsSceneHoverEvent;
+class QGraphicsSceneMouseEvent;
+class QGraphicsSceneWheelEvent;
+class QGraphicsSimpleTextItem;
+class QGraphicsTextItem;
+class QGraphicsView;
+class QGraphicsWidget;
+class QGraphicsSceneIndex;
+class QHelpEvent;
+class QInputMethodEvent;
+class QKeyEvent;
+class QLineF;
+class QPainterPath;
+class QPixmap;
+class QPointF;
+class QPolygonF;
+class QRectF;
+class QSizeF;
+class QStyle;
+class QStyleOptionGraphicsItem;
+
+class QGraphicsScenePrivate;
+class Q_WIDGETS_EXPORT QGraphicsScene : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QBrush backgroundBrush READ backgroundBrush WRITE setBackgroundBrush)
+ Q_PROPERTY(QBrush foregroundBrush READ foregroundBrush WRITE setForegroundBrush)
+ Q_PROPERTY(ItemIndexMethod itemIndexMethod READ itemIndexMethod WRITE setItemIndexMethod)
+ Q_PROPERTY(QRectF sceneRect READ sceneRect WRITE setSceneRect)
+ Q_PROPERTY(int bspTreeDepth READ bspTreeDepth WRITE setBspTreeDepth)
+ Q_PROPERTY(QPalette palette READ palette WRITE setPalette)
+ Q_PROPERTY(QFont font READ font WRITE setFont)
+ Q_PROPERTY(bool sortCacheEnabled READ isSortCacheEnabled WRITE setSortCacheEnabled)
+ Q_PROPERTY(bool stickyFocus READ stickyFocus WRITE setStickyFocus)
+
+public:
+ enum ItemIndexMethod {
+ BspTreeIndex,
+ NoIndex = -1
+ };
+
+ enum SceneLayer {
+ ItemLayer = 0x1,
+ BackgroundLayer = 0x2,
+ ForegroundLayer = 0x4,
+ AllLayers = 0xffff
+ };
+ Q_DECLARE_FLAGS(SceneLayers, SceneLayer)
+
+ QGraphicsScene(QObject *parent = 0);
+ QGraphicsScene(const QRectF &sceneRect, QObject *parent = 0);
+ QGraphicsScene(qreal x, qreal y, qreal width, qreal height, QObject *parent = 0);
+ virtual ~QGraphicsScene();
+
+ QRectF sceneRect() const;
+ inline qreal width() const { return sceneRect().width(); }
+ inline qreal height() const { return sceneRect().height(); }
+ void setSceneRect(const QRectF &rect);
+ inline void setSceneRect(qreal x, qreal y, qreal w, qreal h)
+ { setSceneRect(QRectF(x, y, w, h)); }
+
+ void render(QPainter *painter,
+ const QRectF &target = QRectF(), const QRectF &source = QRectF(),
+ Qt::AspectRatioMode aspectRatioMode = Qt::KeepAspectRatio);
+
+ ItemIndexMethod itemIndexMethod() const;
+ void setItemIndexMethod(ItemIndexMethod method);
+
+ bool isSortCacheEnabled() const;
+ void setSortCacheEnabled(bool enabled);
+
+ int bspTreeDepth() const;
+ void setBspTreeDepth(int depth);
+
+ QRectF itemsBoundingRect() const;
+
+ QList<QGraphicsItem *> items() const;
+ QList<QGraphicsItem *> items(Qt::SortOrder order) const; // ### Qt 5: unify
+
+ QList<QGraphicsItem *> items(const QPointF &pos, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const;
+ QList<QGraphicsItem *> items(const QRectF &rect, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const;
+ QList<QGraphicsItem *> items(const QPolygonF &polygon, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const;
+ QList<QGraphicsItem *> items(const QPainterPath &path, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const;
+
+ QList<QGraphicsItem *> items(const QPointF &pos) const; // ### obsolete
+ QList<QGraphicsItem *> items(const QRectF &rect, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const; // ### obsolete
+ QList<QGraphicsItem *> items(const QPolygonF &polygon, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const; // ### obsolete
+ QList<QGraphicsItem *> items(const QPainterPath &path, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const; // ### obsolete
+
+ QList<QGraphicsItem *> collidingItems(const QGraphicsItem *item, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const;
+
+ QGraphicsItem *itemAt(const QPointF &pos) const; // ### obsolete
+ QGraphicsItem *itemAt(const QPointF &pos, const QTransform &deviceTransform) const;
+
+ inline QList<QGraphicsItem *> items(qreal x, qreal y, qreal w, qreal h, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const
+ { return items(QRectF(x, y, w, h), mode); } // ### obsolete
+ inline QList<QGraphicsItem *> items(qreal x, qreal y, qreal w, qreal h, Qt::ItemSelectionMode mode, Qt::SortOrder order,
+ const QTransform &deviceTransform = QTransform()) const
+ { return items(QRectF(x, y, w, h), mode, order, deviceTransform); }
+ inline QGraphicsItem *itemAt(qreal x, qreal y) const // ### obsolete
+ { return itemAt(QPointF(x, y)); }
+ inline QGraphicsItem *itemAt(qreal x, qreal y, const QTransform &deviceTransform) const
+ { return itemAt(QPointF(x, y), deviceTransform); }
+
+ QList<QGraphicsItem *> selectedItems() const;
+ QPainterPath selectionArea() const;
+ void setSelectionArea(const QPainterPath &path); // ### obsolete
+ void setSelectionArea(const QPainterPath &path, const QTransform &deviceTransform);
+ void setSelectionArea(const QPainterPath &path, Qt::ItemSelectionMode mode); // ### obsolete
+ void setSelectionArea(const QPainterPath &path, Qt::ItemSelectionMode mode, const QTransform &deviceTransform);
+
+ QGraphicsItemGroup *createItemGroup(const QList<QGraphicsItem *> &items);
+ void destroyItemGroup(QGraphicsItemGroup *group);
+
+ void addItem(QGraphicsItem *item);
+ QGraphicsEllipseItem *addEllipse(const QRectF &rect, const QPen &pen = QPen(), const QBrush &brush = QBrush());
+ QGraphicsLineItem *addLine(const QLineF &line, const QPen &pen = QPen());
+ QGraphicsPathItem *addPath(const QPainterPath &path, const QPen &pen = QPen(), const QBrush &brush = QBrush());
+ QGraphicsPixmapItem *addPixmap(const QPixmap &pixmap);
+ QGraphicsPolygonItem *addPolygon(const QPolygonF &polygon, const QPen &pen = QPen(), const QBrush &brush = QBrush());
+ QGraphicsRectItem *addRect(const QRectF &rect, const QPen &pen = QPen(), const QBrush &brush = QBrush());
+ QGraphicsTextItem *addText(const QString &text, const QFont &font = QFont());
+ QGraphicsSimpleTextItem *addSimpleText(const QString &text, const QFont &font = QFont());
+ QGraphicsProxyWidget *addWidget(QWidget *widget, Qt::WindowFlags wFlags = 0);
+ inline QGraphicsEllipseItem *addEllipse(qreal x, qreal y, qreal w, qreal h, const QPen &pen = QPen(), const QBrush &brush = QBrush())
+ { return addEllipse(QRectF(x, y, w, h), pen, brush); }
+ inline QGraphicsLineItem *addLine(qreal x1, qreal y1, qreal x2, qreal y2, const QPen &pen = QPen())
+ { return addLine(QLineF(x1, y1, x2, y2), pen); }
+ inline QGraphicsRectItem *addRect(qreal x, qreal y, qreal w, qreal h, const QPen &pen = QPen(), const QBrush &brush = QBrush())
+ { return addRect(QRectF(x, y, w, h), pen, brush); }
+ void removeItem(QGraphicsItem *item);
+
+ QGraphicsItem *focusItem() const;
+ void setFocusItem(QGraphicsItem *item, Qt::FocusReason focusReason = Qt::OtherFocusReason);
+ bool hasFocus() const;
+ void setFocus(Qt::FocusReason focusReason = Qt::OtherFocusReason);
+ void clearFocus();
+
+ void setStickyFocus(bool enabled);
+ bool stickyFocus() const;
+
+ QGraphicsItem *mouseGrabberItem() const;
+
+ QBrush backgroundBrush() const;
+ void setBackgroundBrush(const QBrush &brush);
+
+ QBrush foregroundBrush() const;
+ void setForegroundBrush(const QBrush &brush);
+
+ virtual QVariant inputMethodQuery(Qt::InputMethodQuery query) const;
+
+ QList <QGraphicsView *> views() const;
+
+ inline void update(qreal x, qreal y, qreal w, qreal h)
+ { update(QRectF(x, y, w, h)); }
+ inline void invalidate(qreal x, qreal y, qreal w, qreal h, SceneLayers layers = AllLayers)
+ { invalidate(QRectF(x, y, w, h), layers); }
+
+ QStyle *style() const;
+ void setStyle(QStyle *style);
+
+ QFont font() const;
+ void setFont(const QFont &font);
+
+ QPalette palette() const;
+ void setPalette(const QPalette &palette);
+
+ bool isActive() const;
+ QGraphicsItem *activePanel() const;
+ void setActivePanel(QGraphicsItem *item);
+ QGraphicsWidget *activeWindow() const;
+ void setActiveWindow(QGraphicsWidget *widget);
+
+ bool sendEvent(QGraphicsItem *item, QEvent *event);
+
+public Q_SLOTS:
+ void update(const QRectF &rect = QRectF());
+ void invalidate(const QRectF &rect = QRectF(), SceneLayers layers = AllLayers);
+ void advance();
+ void clearSelection();
+ void clear();
+
+protected:
+ bool event(QEvent *event);
+ bool eventFilter(QObject *watched, QEvent *event);
+ virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent *event);
+ virtual void dragEnterEvent(QGraphicsSceneDragDropEvent *event);
+ virtual void dragMoveEvent(QGraphicsSceneDragDropEvent *event);
+ virtual void dragLeaveEvent(QGraphicsSceneDragDropEvent *event);
+ virtual void dropEvent(QGraphicsSceneDragDropEvent *event);
+ virtual void focusInEvent(QFocusEvent *event);
+ virtual void focusOutEvent(QFocusEvent *event);
+ virtual void helpEvent(QGraphicsSceneHelpEvent *event);
+ virtual void keyPressEvent(QKeyEvent *event);
+ virtual void keyReleaseEvent(QKeyEvent *event);
+ virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
+ virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
+ virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
+ virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event);
+ virtual void wheelEvent(QGraphicsSceneWheelEvent *event);
+ virtual void inputMethodEvent(QInputMethodEvent *event);
+
+ virtual void drawBackground(QPainter *painter, const QRectF &rect);
+ virtual void drawForeground(QPainter *painter, const QRectF &rect);
+ virtual void drawItems(QPainter *painter, int numItems,
+ QGraphicsItem *items[],
+ const QStyleOptionGraphicsItem options[],
+ QWidget *widget = 0);
+
+protected Q_SLOTS:
+ bool focusNextPrevChild(bool next);
+
+Q_SIGNALS:
+ void changed(const QList<QRectF> &region);
+ void sceneRectChanged(const QRectF &rect);
+ void selectionChanged();
+
+private:
+ Q_DECLARE_PRIVATE(QGraphicsScene)
+ Q_DISABLE_COPY(QGraphicsScene)
+ Q_PRIVATE_SLOT(d_func(), void _q_emitUpdated())
+ Q_PRIVATE_SLOT(d_func(), void _q_polishItems())
+ Q_PRIVATE_SLOT(d_func(), void _q_processDirtyItems())
+ Q_PRIVATE_SLOT(d_func(), void _q_updateScenePosDescendants())
+ friend class QGraphicsItem;
+ friend class QGraphicsItemPrivate;
+ friend class QGraphicsObject;
+ friend class QGraphicsView;
+ friend class QGraphicsViewPrivate;
+ friend class QGraphicsWidget;
+ friend class QGraphicsWidgetPrivate;
+ friend class QGraphicsEffect;
+ friend class QGraphicsSceneIndex;
+ friend class QGraphicsSceneIndexPrivate;
+ friend class QGraphicsSceneBspTreeIndex;
+ friend class QGraphicsSceneBspTreeIndexPrivate;
+ friend class QGraphicsItemEffectSourcePrivate;
+#ifndef QT_NO_GESTURES
+ friend class QGesture;
+#endif
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QGraphicsScene::SceneLayers)
+
+#endif // QT_NO_GRAPHICSVIEW
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/gui/graphicsview/qgraphicsscene_bsp.cpp b/src/widgets/graphicsview/qgraphicsscene_bsp.cpp
index cc8a558ad3..cc8a558ad3 100644
--- a/src/gui/graphicsview/qgraphicsscene_bsp.cpp
+++ b/src/widgets/graphicsview/qgraphicsscene_bsp.cpp
diff --git a/src/gui/graphicsview/qgraphicsscene_bsp_p.h b/src/widgets/graphicsview/qgraphicsscene_bsp_p.h
index 2e8149867b..2e8149867b 100644
--- a/src/gui/graphicsview/qgraphicsscene_bsp_p.h
+++ b/src/widgets/graphicsview/qgraphicsscene_bsp_p.h
diff --git a/src/widgets/graphicsview/qgraphicsscene_p.h b/src/widgets/graphicsview/qgraphicsscene_p.h
new file mode 100644
index 0000000000..8cb24457d6
--- /dev/null
+++ b/src/widgets/graphicsview/qgraphicsscene_p.h
@@ -0,0 +1,359 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGRAPHICSSCENE_P_H
+#define QGRAPHICSSCENE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qgraphicsscene.h"
+
+#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW
+
+#include "qgraphicssceneevent.h"
+#include "qgraphicsview.h"
+#include "qgraphicsview_p.h"
+#include "qgraphicsitem_p.h"
+
+#include <private/qobject_p.h>
+#include <QtCore/qbitarray.h>
+#include <QtCore/qlist.h>
+#include <QtCore/qmap.h>
+#include <QtCore/qset.h>
+#include <QtGui/qfont.h>
+#include <QtGui/qpalette.h>
+#include <QtWidgets/qstyle.h>
+#include <QtWidgets/qstyleoption.h>
+
+QT_BEGIN_NAMESPACE
+
+class QGraphicsSceneIndex;
+class QGraphicsView;
+class QGraphicsWidget;
+
+class Q_AUTOTEST_EXPORT QGraphicsScenePrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QGraphicsScene)
+public:
+ QGraphicsScenePrivate();
+ void init();
+
+ static QGraphicsScenePrivate *get(QGraphicsScene *q);
+
+ int changedSignalIndex;
+ int processDirtyItemsIndex;
+ int polishItemsIndex;
+
+ QGraphicsScene::ItemIndexMethod indexMethod;
+ QGraphicsSceneIndex *index;
+
+ int lastItemCount;
+
+ QRectF sceneRect;
+
+ quint32 hasSceneRect : 1;
+ quint32 dirtyGrowingItemsBoundingRect : 1;
+ quint32 updateAll : 1;
+ quint32 calledEmitUpdated : 1;
+ quint32 processDirtyItemsEmitted : 1;
+ quint32 needSortTopLevelItems : 1;
+ quint32 holesInTopLevelSiblingIndex : 1;
+ quint32 topLevelSequentialOrdering : 1;
+ quint32 scenePosDescendantsUpdatePending : 1;
+ quint32 stickyFocus : 1;
+ quint32 hasFocus : 1;
+ quint32 lastMouseGrabberItemHasImplicitMouseGrab : 1;
+ quint32 allItemsIgnoreHoverEvents : 1;
+ quint32 allItemsUseDefaultCursor : 1;
+ quint32 painterStateProtection : 1;
+ quint32 sortCacheEnabled : 1; // for compatibility
+ quint32 allItemsIgnoreTouchEvents : 1;
+ quint32 padding : 15;
+
+ QRectF growingItemsBoundingRect;
+
+ void _q_emitUpdated();
+ QList<QRectF> updatedRects;
+
+ QPainterPath selectionArea;
+ int selectionChanging;
+ QSet<QGraphicsItem *> selectedItems;
+ QVector<QGraphicsItem *> unpolishedItems;
+ QList<QGraphicsItem *> topLevelItems;
+
+ QMap<QGraphicsItem *, QPointF> movingItemsInitialPositions;
+ void registerTopLevelItem(QGraphicsItem *item);
+ void unregisterTopLevelItem(QGraphicsItem *item);
+ void _q_updateLater();
+ void _q_polishItems();
+
+ void _q_processDirtyItems();
+
+ QSet<QGraphicsItem *> scenePosItems;
+ void setScenePosItemEnabled(QGraphicsItem *item, bool enabled);
+ void registerScenePosItem(QGraphicsItem *item);
+ void unregisterScenePosItem(QGraphicsItem *item);
+ void _q_updateScenePosDescendants();
+
+ void removeItemHelper(QGraphicsItem *item);
+
+ QBrush backgroundBrush;
+ QBrush foregroundBrush;
+
+ quint32 rectAdjust;
+ QGraphicsItem *focusItem;
+ QGraphicsItem *lastFocusItem;
+ QGraphicsItem *passiveFocusItem;
+ QGraphicsWidget *tabFocusFirst;
+ QGraphicsItem *activePanel;
+ QGraphicsItem *lastActivePanel;
+ int activationRefCount;
+ int childExplicitActivation;
+ void setActivePanelHelper(QGraphicsItem *item, bool duringActivationEvent);
+ void setFocusItemHelper(QGraphicsItem *item, Qt::FocusReason focusReason);
+
+ QList<QGraphicsWidget *> popupWidgets;
+ void addPopup(QGraphicsWidget *widget);
+ void removePopup(QGraphicsWidget *widget, bool itemIsDying = false);
+
+ QGraphicsItem *lastMouseGrabberItem;
+ QList<QGraphicsItem *> mouseGrabberItems;
+ void grabMouse(QGraphicsItem *item, bool implicit = false);
+ void ungrabMouse(QGraphicsItem *item, bool itemIsDying = false);
+ void clearMouseGrabber();
+
+ QList<QGraphicsItem *> keyboardGrabberItems;
+ void grabKeyboard(QGraphicsItem *item);
+ void ungrabKeyboard(QGraphicsItem *item, bool itemIsDying = false);
+ void clearKeyboardGrabber();
+
+ QGraphicsItem *dragDropItem;
+ QGraphicsWidget *enterWidget;
+ Qt::DropAction lastDropAction;
+ QList<QGraphicsItem *> cachedItemsUnderMouse;
+ QList<QGraphicsItem *> hoverItems;
+ QPointF lastSceneMousePos;
+ void enableMouseTrackingOnViews();
+ QMap<Qt::MouseButton, QPointF> mouseGrabberButtonDownPos;
+ QMap<Qt::MouseButton, QPointF> mouseGrabberButtonDownScenePos;
+ QMap<Qt::MouseButton, QPoint> mouseGrabberButtonDownScreenPos;
+ QList<QGraphicsItem *> itemsAtPosition(const QPoint &screenPos,
+ const QPointF &scenePos,
+ QWidget *widget) const;
+ void storeMouseButtonsForMouseGrabber(QGraphicsSceneMouseEvent *event);
+
+ QList<QGraphicsView *> views;
+ void addView(QGraphicsView *view);
+ void removeView(QGraphicsView *view);
+
+ QMultiMap<QGraphicsItem *, QGraphicsItem *> sceneEventFilters;
+ void installSceneEventFilter(QGraphicsItem *watched, QGraphicsItem *filter);
+ void removeSceneEventFilter(QGraphicsItem *watched, QGraphicsItem *filter);
+ bool filterDescendantEvent(QGraphicsItem *item, QEvent *event);
+ bool filterEvent(QGraphicsItem *item, QEvent *event);
+ bool sendEvent(QGraphicsItem *item, QEvent *event);
+
+ bool dispatchHoverEvent(QGraphicsSceneHoverEvent *hoverEvent);
+ bool itemAcceptsHoverEvents_helper(const QGraphicsItem *item) const;
+ void leaveScene(QWidget *viewport);
+
+ void cloneDragDropEvent(QGraphicsSceneDragDropEvent *dest,
+ QGraphicsSceneDragDropEvent *source);
+ void sendDragDropEvent(QGraphicsItem *item,
+ QGraphicsSceneDragDropEvent *dragDropEvent);
+ void sendHoverEvent(QEvent::Type type, QGraphicsItem *item,
+ QGraphicsSceneHoverEvent *hoverEvent);
+ void sendMouseEvent(QGraphicsSceneMouseEvent *mouseEvent);
+ void mousePressEventHandler(QGraphicsSceneMouseEvent *mouseEvent);
+ QGraphicsWidget *windowForItem(const QGraphicsItem *item) const;
+
+ void drawItemHelper(QGraphicsItem *item, QPainter *painter,
+ const QStyleOptionGraphicsItem *option, QWidget *widget,
+ bool painterStateProtection);
+
+ void drawItems(QPainter *painter, const QTransform *const viewTransform,
+ QRegion *exposedRegion, QWidget *widget);
+
+ void drawSubtreeRecursive(QGraphicsItem *item, QPainter *painter, const QTransform *const,
+ QRegion *exposedRegion, QWidget *widget, qreal parentOpacity = qreal(1.0),
+ const QTransform *const effectTransform = 0);
+ void draw(QGraphicsItem *, QPainter *, const QTransform *const, const QTransform *const,
+ QRegion *, QWidget *, qreal, const QTransform *const, bool, bool);
+
+ void markDirty(QGraphicsItem *item, const QRectF &rect = QRectF(), bool invalidateChildren = false,
+ bool force = false, bool ignoreOpacity = false, bool removingItemFromScene = false,
+ bool updateBoundingRect = false);
+ void processDirtyItemsRecursive(QGraphicsItem *item, bool dirtyAncestorContainsChildren = false,
+ qreal parentOpacity = qreal(1.0));
+
+ inline void resetDirtyItem(QGraphicsItem *item, bool recursive = false)
+ {
+ Q_ASSERT(item);
+ item->d_ptr->dirty = 0;
+ item->d_ptr->paintedViewBoundingRectsNeedRepaint = 0;
+ item->d_ptr->geometryChanged = 0;
+ if (!item->d_ptr->dirtyChildren)
+ recursive = false;
+ item->d_ptr->dirtyChildren = 0;
+ item->d_ptr->needsRepaint = QRectF();
+ item->d_ptr->allChildrenDirty = 0;
+ item->d_ptr->fullUpdatePending = 0;
+ item->d_ptr->ignoreVisible = 0;
+ item->d_ptr->ignoreOpacity = 0;
+#ifndef QT_NO_GRAPHICSEFFECT
+ QGraphicsEffect::ChangeFlags flags;
+ if (item->d_ptr->notifyBoundingRectChanged) {
+ flags |= QGraphicsEffect::SourceBoundingRectChanged;
+ item->d_ptr->notifyBoundingRectChanged = 0;
+ }
+ if (item->d_ptr->notifyInvalidated) {
+ flags |= QGraphicsEffect::SourceInvalidated;
+ item->d_ptr->notifyInvalidated = 0;
+ }
+#endif //QT_NO_GRAPHICSEFFECT
+ if (recursive) {
+ for (int i = 0; i < item->d_ptr->children.size(); ++i)
+ resetDirtyItem(item->d_ptr->children.at(i), recursive);
+ }
+#ifndef QT_NO_GRAPHICSEFFECT
+ if (flags && item->d_ptr->graphicsEffect)
+ item->d_ptr->graphicsEffect->sourceChanged(flags);
+#endif //QT_NO_GRAPHICSEFFECT
+ }
+
+ inline void ensureSortedTopLevelItems()
+ {
+ if (needSortTopLevelItems) {
+ qSort(topLevelItems.begin(), topLevelItems.end(), qt_notclosestLeaf);
+ topLevelSequentialOrdering = false;
+ needSortTopLevelItems = false;
+ }
+ }
+
+ void ensureSequentialTopLevelSiblingIndexes();
+
+ QStyle *style;
+ QFont font;
+ void setFont_helper(const QFont &font);
+ void resolveFont();
+ void updateFont(const QFont &font);
+ QPalette palette;
+ void setPalette_helper(const QPalette &palette);
+ void resolvePalette();
+ void updatePalette(const QPalette &palette);
+
+ QStyleOptionGraphicsItem styleOptionTmp;
+
+ QMap<int, QTouchEvent::TouchPoint> sceneCurrentTouchPoints;
+ QMap<int, QGraphicsItem *> itemForTouchPointId;
+ static void updateTouchPointsForItem(QGraphicsItem *item, QTouchEvent *touchEvent);
+ int findClosestTouchPointId(const QPointF &scenePos);
+ void touchEventHandler(QTouchEvent *touchEvent);
+ bool sendTouchBeginEvent(QGraphicsItem *item, QTouchEvent *touchEvent);
+ void enableTouchEventsOnViews();
+
+ QList<QGraphicsObject *> cachedTargetItems;
+#ifndef QT_NO_GESTURES
+ QHash<QGraphicsObject *, QSet<QGesture *> > cachedItemGestures;
+ QHash<QGraphicsObject *, QSet<QGesture *> > cachedAlreadyDeliveredGestures;
+ QHash<QGesture *, QGraphicsObject *> gestureTargets;
+ QHash<Qt::GestureType, int> grabbedGestures;
+ void gestureEventHandler(QGestureEvent *event);
+ void gestureTargetsAtHotSpots(const QSet<QGesture *> &gestures,
+ Qt::GestureFlag flag,
+ QHash<QGraphicsObject *, QSet<QGesture *> > *targets,
+ QSet<QGraphicsObject *> *itemsSet = 0,
+ QSet<QGesture *> *normal = 0,
+ QSet<QGesture *> *conflicts = 0);
+ void cancelGesturesForChildren(QGesture *original);
+ void grabGesture(QGraphicsItem *, Qt::GestureType gesture);
+ void ungrabGesture(QGraphicsItem *, Qt::GestureType gesture);
+#endif // QT_NO_GESTURES
+
+ void updateInputMethodSensitivityInViews();
+
+ QList<QGraphicsItem *> modalPanels;
+ void enterModal(QGraphicsItem *item,
+ QGraphicsItem::PanelModality panelModality = QGraphicsItem::NonModal);
+ void leaveModal(QGraphicsItem *item);
+};
+
+// 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 void _q_adjustRect(QRectF *rect)
+{
+ Q_ASSERT(rect);
+ if (!rect->width())
+ rect->adjust(qreal(-0.00001), 0, qreal(0.00001), 0);
+ if (!rect->height())
+ rect->adjust(0, qreal(-0.00001), 0, qreal(0.00001));
+}
+
+static inline QRectF adjustedItemBoundingRect(const QGraphicsItem *item)
+{
+ Q_ASSERT(item);
+ QRectF boundingRect(item->boundingRect());
+ _q_adjustRect(&boundingRect);
+ return boundingRect;
+}
+
+static inline QRectF adjustedItemEffectiveBoundingRect(const QGraphicsItem *item)
+{
+ Q_ASSERT(item);
+ QRectF boundingRect(QGraphicsItemPrivate::get(item)->effectiveBoundingRect());
+ _q_adjustRect(&boundingRect);
+ return boundingRect;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_GRAPHICSVIEW
+
+#endif
diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp b/src/widgets/graphicsview/qgraphicsscenebsptreeindex.cpp
index 979ce6823b..979ce6823b 100644
--- a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp
+++ b/src/widgets/graphicsview/qgraphicsscenebsptreeindex.cpp
diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h b/src/widgets/graphicsview/qgraphicsscenebsptreeindex_p.h
index 0b353c74a4..0b353c74a4 100644
--- a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h
+++ b/src/widgets/graphicsview/qgraphicsscenebsptreeindex_p.h
diff --git a/src/widgets/graphicsview/qgraphicssceneevent.cpp b/src/widgets/graphicsview/qgraphicssceneevent.cpp
new file mode 100644
index 0000000000..97e5ff40c1
--- /dev/null
+++ b/src/widgets/graphicsview/qgraphicssceneevent.cpp
@@ -0,0 +1,1674 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \class QGraphicsSceneEvent
+ \brief The QGraphicsSceneEvent class provides a base class for all
+ graphics view related events.
+ \since 4.2
+ \ingroup graphicsview-api
+
+ When a QGraphicsView receives Qt mouse, keyboard, and drag and
+ drop events (QMouseEvent, QKeyEvent, QDragEvent, etc.), it
+ translates them into instances of QGraphicsSceneEvent subclasses
+ and forwards them to the QGraphicsScene it displays. The scene
+ then forwards the events to the relevant items.
+
+ For example, when a QGraphicsView receives a QMouseEvent of type
+ MousePress as a response to a user click, the view sends a
+ QGraphicsSceneMouseEvent of type GraphicsSceneMousePress to the
+ underlying QGraphicsScene through its
+ \l{QGraphicsScene::}{mousePressEvent()} function. The default
+ QGraphicsScene::mousePressEvent() implementation determines which
+ item was clicked and forwards the event to
+ QGraphicsItem::mousePressEvent().
+
+ \omit ### Beskrive widget() \endomit
+
+ Subclasses such as QGraphicsSceneMouseEvent and
+ QGraphicsSceneContextMenuEvent provide the coordinates from the
+ original QEvent in screen, scene, and item coordinates (see
+ \l{QGraphicsSceneMouseEvent::}{screenPos()},
+ \l{QGraphicsSceneMouseEvent::}{scenePos()}, and
+ \l{QGraphicsSceneMouseEvent::}{pos()}). The item coordinates are
+ set by the QGraphicsScene before it forwards the event to the
+ event to a QGraphicsItem. The mouse events also add the
+ possibility to retrieve the coordinates from the last event
+ received by the view (see
+ \l{QGraphicsSceneMouseEvent::}{lastScreenPos()},
+ \l{QGraphicsSceneMouseEvent::}{lastScenePos()}, and
+ \l{QGraphicsSceneMouseEvent::}{lastPos()}).
+
+ \sa QEvent
+*/
+
+/*!
+ \class QGraphicsSceneMouseEvent
+ \brief The QGraphicsSceneMouseEvent class provides mouse events
+ in the graphics view framework.
+ \since 4.2
+ \ingroup graphicsview-api
+
+ When a QGraphicsView receives a QMouseEvent, it translates it to a
+ QGraphicsSceneMouseEvent. The event is then forwarded to the
+ QGraphicsScene associated with the view. If the event is not
+ handled by the scene, the view may use it, e.g., for the
+ \l{QGraphicsView::}{DragMode}.
+
+ In addition to containing the item, scene, and screen coordinates
+ of the event (as pos(), scenePos(), and screenPos()), mouse
+ events also contain the coordinates of the previous mouse
+ event received by the view. These can be retrieved with
+ lastPos(), lastScreenPos(), and lastScenePos().
+
+ \sa QGraphicsSceneContextMenuEvent,
+ QGraphicsSceneHoverEvent, QGraphicsSceneWheelEvent,
+ QMouseEvent
+*/
+
+/*!
+ \class QGraphicsSceneWheelEvent
+ \brief The QGraphicsSceneWheelEvent class provides wheel events
+ in the graphics view framework.
+ \brief The QGraphicsSceneWheelEvent class provides wheel events in the
+ graphics view framework.
+ \since 4.2
+ \ingroup graphicsview-api
+
+ \l{QWheelEvent}{QWheelEvent}s received by a QGraphicsView are translated
+ into QGraphicsSceneWheelEvents; it translates the QWheelEvent::globalPos()
+ into item, scene, and screen coordinates (pos(), scenePos(), and
+ screenPos()).
+
+ \sa QGraphicsSceneMouseEvent, QGraphicsSceneContextMenuEvent,
+ QGraphicsSceneHoverEvent, QWheelEvent
+*/
+
+/*!
+ \class QGraphicsSceneContextMenuEvent
+ \brief The QGraphicsSceneContextMenuEvent class provides context
+ menu events in the graphics view framework.
+ \since 4.2
+ \ingroup graphicsview-api
+
+ A QContextMenuEvent received by a QGraphicsView is translated
+ into a QGraphicsSceneContextMenuEvent. The
+ QContextMenuEvent::globalPos() is translated into item, scene, and
+ screen coordinates (pos(), scenePos(), and screenPos()).
+
+ \sa QGraphicsSceneMouseEvent, QGraphicsSceneWheelEvent,
+ QContextMenuEvent
+*/
+
+/*!
+ \enum QGraphicsSceneContextMenuEvent::Reason
+
+ This enum describes the reason why the context event was sent.
+
+ \value Mouse The mouse caused the event to be sent. On most
+ platforms, this means the right mouse button was clicked.
+
+ \value Keyboard The keyboard caused this event to be sent. On
+ Windows and Mac OS X, this means the menu button was pressed.
+
+ \value Other The event was sent by some other means (i.e. not
+ by the mouse or keyboard).
+*/
+
+/*!
+ \class QGraphicsSceneHoverEvent
+ \brief The QGraphicsSceneHoverEvent class provides hover events
+ in the graphics view framework.
+ \since 4.2
+ \ingroup graphicsview-api
+
+ When a QGraphicsView receives a QHoverEvent event, it translates
+ it into QGraphicsSceneHoverEvent. The event is then forwarded to
+ the QGraphicsScene associated with the view.
+
+ \sa QGraphicsSceneMouseEvent, QGraphicsSceneContextMenuEvent,
+ QGraphicsSceneWheelEvent, QHoverEvent
+*/
+
+/*!
+ \class QGraphicsSceneHelpEvent
+ \brief The QGraphicsSceneHelpEvent class provides events when a
+ tooltip is requested.
+ \since 4.2
+ \ingroup graphicsview-api
+
+ When a QGraphicsView receives a QEvent of type
+ QEvent::ToolTip, it creates a QGraphicsSceneHelpEvent, which is
+ forwarded to the scene. You can set a tooltip on a QGraphicsItem
+ with \l{QGraphicsItem::}{setToolTip()}; by default QGraphicsScene
+ displays the tooltip of the QGraphicsItem with the highest
+ z-value (i.e, the top-most item) under the mouse position.
+
+ QGraphicsView does not forward events when
+ \l{QWhatsThis}{"What's This"} and \l{QStatusTipEvent}{status tip}
+ help is requested. If you need this, you can reimplement
+ QGraphicsView::viewportEvent() and forward QStatusTipEvent
+ events and \l{QEvent}{QEvents} of type QEvent::WhatsThis to the
+ scene.
+
+ \sa QEvent
+*/
+
+/*!
+ \class QGraphicsSceneDragDropEvent
+ \brief The QGraphicsSceneDragDropEvent class provides events for
+ drag and drop in the graphics view framework.
+ \since 4.2
+ \ingroup graphicsview-api
+
+ QGraphicsView inherits the drag and drop functionality provided
+ by QWidget. When it receives a drag and drop event, it translates
+ it to a QGraphicsSceneDragDropEvent.
+
+ QGraphicsSceneDragDropEvent stores events of type
+ GraphicsSceneDragEnter, GraphicsSceneDragLeave,
+ GraphicsSceneDragMove, or GraphicsSceneDrop.
+
+ QGraphicsSceneDragDropEvent contains the position of the mouse
+ cursor in both item, scene, and screen coordinates; this can be
+ retrieved with pos(), scenePos(), and screenPos().
+
+ The scene sends the event to the first QGraphicsItem under the
+ mouse cursor that accepts drops; a graphics item is set to accept
+ drops with \l{QGraphicsItem::}{setAcceptDrops()}.
+*/
+
+/*!
+ \class QGraphicsSceneResizeEvent
+ \brief The QGraphicsSceneResizeEvent class provides events for widget
+ resizing in the graphics view framework.
+ \since 4.4
+ \ingroup graphicsview-api
+
+ A QGraphicsWidget sends itself a QGraphicsSceneResizeEvent immediately
+ when its geometry changes.
+
+ It's similar to QResizeEvent, but its sizes, oldSize() and newSize(), use
+ QSizeF instead of QSize.
+
+ \sa QGraphicsWidget::setGeometry(), QGraphicsWidget::resize()
+*/
+
+/*!
+ \class QGraphicsSceneMoveEvent
+ \brief The QGraphicsSceneMoveEvent class provides events for widget
+ moving in the graphics view framework.
+ \since 4.4
+ \ingroup graphicsview-api
+
+ A QGraphicsWidget sends itself a QGraphicsSceneMoveEvent immediately when
+ its local position changes. The delivery is implemented as part of
+ QGraphicsItem::itemChange().
+
+ It's similar to QMoveEvent, but its positions, oldPos() and newPos(), use
+ QPointF instead of QPoint.
+
+ \sa QGraphicsItem::setPos(), QGraphicsItem::ItemPositionChange,
+ QGraphicsItem::ItemPositionHasChanged
+*/
+
+#include "qgraphicssceneevent.h"
+
+#ifndef QT_NO_GRAPHICSVIEW
+
+#ifndef QT_NO_DEBUG
+#include <QtCore/qdebug.h>
+#endif
+#include <QtCore/qmap.h>
+#include <QtCore/qpoint.h>
+#include <QtCore/qsize.h>
+#include <QtCore/qstring.h>
+#include "qgraphicsview.h"
+#include "qgraphicsitem.h"
+#include <QtWidgets/qgesture.h>
+#include <private/qevent_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QGraphicsSceneEventPrivate
+{
+public:
+ inline QGraphicsSceneEventPrivate()
+ : widget(0),
+ q_ptr(0)
+ { }
+
+ inline virtual ~QGraphicsSceneEventPrivate()
+ { }
+
+ QWidget *widget;
+ QGraphicsSceneEvent *q_ptr;
+};
+
+/*!
+ \internal
+
+ Constructs a generic graphics scene event of the specified \a type.
+*/
+QGraphicsSceneEvent::QGraphicsSceneEvent(Type type)
+ : QEvent(type), d_ptr(new QGraphicsSceneEventPrivate)
+{
+ d_ptr->q_ptr = this;
+}
+
+/*!
+ \internal
+
+ Constructs a generic graphics scene event.
+*/
+QGraphicsSceneEvent::QGraphicsSceneEvent(QGraphicsSceneEventPrivate &dd, Type type)
+ : QEvent(type), d_ptr(&dd)
+{
+ d_ptr->q_ptr = this;
+}
+
+/*!
+ Destroys the event.
+*/
+QGraphicsSceneEvent::~QGraphicsSceneEvent()
+{
+}
+
+/*!
+ Returns the widget where the event originated, or 0 if the event
+ originates from another application.
+*/
+QWidget *QGraphicsSceneEvent::widget() const
+{
+ return d_ptr->widget;
+}
+
+/*!
+ \internal
+
+ Sets the \a widget related to this event.
+
+ \sa widget()
+*/
+void QGraphicsSceneEvent::setWidget(QWidget *widget)
+{
+ d_ptr->widget = widget;
+}
+
+class QGraphicsSceneMouseEventPrivate : public QGraphicsSceneEventPrivate
+{
+ Q_DECLARE_PUBLIC(QGraphicsSceneMouseEvent)
+public:
+ inline QGraphicsSceneMouseEventPrivate()
+ : button(Qt::NoButton),
+ buttons(0), modifiers(0)
+ { }
+
+ QPointF pos;
+ QPointF scenePos;
+ QPoint screenPos;
+ QPointF lastPos;
+ QPointF lastScenePos;
+ QPoint lastScreenPos;
+ QMap<Qt::MouseButton, QPointF> buttonDownPos;
+ QMap<Qt::MouseButton, QPointF> buttonDownScenePos;
+ QMap<Qt::MouseButton, QPoint> buttonDownScreenPos;
+ Qt::MouseButton button;
+ Qt::MouseButtons buttons;
+ Qt::KeyboardModifiers modifiers;
+};
+
+/*!
+ \internal
+
+ Constructs a generic graphics scene mouse event of the specified \a type.
+*/
+QGraphicsSceneMouseEvent::QGraphicsSceneMouseEvent(Type type)
+ : QGraphicsSceneEvent(*new QGraphicsSceneMouseEventPrivate, type)
+{
+}
+
+/*!
+ Destroys the event.
+*/
+QGraphicsSceneMouseEvent::~QGraphicsSceneMouseEvent()
+{
+}
+
+/*!
+ Returns the mouse cursor position in item coordinates.
+
+ \sa scenePos(), screenPos(), lastPos()
+*/
+QPointF QGraphicsSceneMouseEvent::pos() const
+{
+ Q_D(const QGraphicsSceneMouseEvent);
+ return d->pos;
+}
+
+/*!
+ \internal
+*/
+void QGraphicsSceneMouseEvent::setPos(const QPointF &pos)
+{
+ Q_D(QGraphicsSceneMouseEvent);
+ d->pos = pos;
+}
+
+/*!
+ Returns the mouse cursor position in scene coordinates.
+
+ \sa pos(), screenPos(), lastScenePos()
+*/
+QPointF QGraphicsSceneMouseEvent::scenePos() const
+{
+ Q_D(const QGraphicsSceneMouseEvent);
+ return d->scenePos;
+}
+
+/*!
+ \internal
+*/
+void QGraphicsSceneMouseEvent::setScenePos(const QPointF &pos)
+{
+ Q_D(QGraphicsSceneMouseEvent);
+ d->scenePos = pos;
+}
+
+/*!
+ Returns the mouse cursor position in screen coordinates.
+
+ \sa pos(), scenePos(), lastScreenPos()
+*/
+QPoint QGraphicsSceneMouseEvent::screenPos() const
+{
+ Q_D(const QGraphicsSceneMouseEvent);
+ return d->screenPos;
+}
+
+/*!
+ \internal
+*/
+void QGraphicsSceneMouseEvent::setScreenPos(const QPoint &pos)
+{
+ Q_D(QGraphicsSceneMouseEvent);
+ d->screenPos = pos;
+}
+
+/*!
+ Returns the mouse cursor position in item coordinates where the specified
+ \a button was clicked.
+
+ \sa buttonDownScenePos(), buttonDownScreenPos(), pos()
+*/
+QPointF QGraphicsSceneMouseEvent::buttonDownPos(Qt::MouseButton button) const
+{
+ Q_D(const QGraphicsSceneMouseEvent);
+ return d->buttonDownPos.value(button);
+}
+
+/*!
+ \internal
+*/
+void QGraphicsSceneMouseEvent::setButtonDownPos(Qt::MouseButton button, const QPointF &pos)
+{
+ Q_D(QGraphicsSceneMouseEvent);
+ d->buttonDownPos.insert(button, pos);
+}
+
+/*!
+ Returns the mouse cursor position in scene coordinates where the
+ specified \a button was clicked.
+
+ \sa buttonDownPos(), buttonDownScreenPos(), scenePos()
+*/
+QPointF QGraphicsSceneMouseEvent::buttonDownScenePos(Qt::MouseButton button) const
+{
+ Q_D(const QGraphicsSceneMouseEvent);
+ return d->buttonDownScenePos.value(button);
+}
+
+/*!
+ \internal
+*/
+void QGraphicsSceneMouseEvent::setButtonDownScenePos(Qt::MouseButton button, const QPointF &pos)
+{
+ Q_D(QGraphicsSceneMouseEvent);
+ d->buttonDownScenePos.insert(button, pos);
+}
+
+/*!
+ Returns the mouse cursor position in screen coordinates where the
+ specified \a button was clicked.
+
+ \sa screenPos(), buttonDownPos(), buttonDownScenePos()
+*/
+QPoint QGraphicsSceneMouseEvent::buttonDownScreenPos(Qt::MouseButton button) const
+{
+ Q_D(const QGraphicsSceneMouseEvent);
+ return d->buttonDownScreenPos.value(button);
+}
+
+/*!
+ \internal
+*/
+void QGraphicsSceneMouseEvent::setButtonDownScreenPos(Qt::MouseButton button, const QPoint &pos)
+{
+ Q_D(QGraphicsSceneMouseEvent);
+ d->buttonDownScreenPos.insert(button, pos);
+}
+
+/*!
+ Returns the last recorded mouse cursor position in item
+ coordinates.
+
+ \sa lastScenePos(), lastScreenPos(), pos()
+*/
+QPointF QGraphicsSceneMouseEvent::lastPos() const
+{
+ Q_D(const QGraphicsSceneMouseEvent);
+ return d->lastPos;
+}
+
+/*!
+ \internal
+*/
+void QGraphicsSceneMouseEvent::setLastPos(const QPointF &pos)
+{
+ Q_D(QGraphicsSceneMouseEvent);
+ d->lastPos = pos;
+}
+
+/*!
+ Returns the last recorded mouse cursor position in scene
+ coordinates. The last recorded position is the position of
+ the previous mouse event received by the view that created
+ the event.
+
+ \sa lastPos(), lastScreenPos(), scenePos()
+*/
+QPointF QGraphicsSceneMouseEvent::lastScenePos() const
+{
+ Q_D(const QGraphicsSceneMouseEvent);
+ return d->lastScenePos;
+}
+
+/*!
+ \internal
+*/
+void QGraphicsSceneMouseEvent::setLastScenePos(const QPointF &pos)
+{
+ Q_D(QGraphicsSceneMouseEvent);
+ d->lastScenePos = pos;
+}
+
+/*!
+ Returns the last recorded mouse cursor position in screen
+ coordinates. The last recorded position is the position of
+ the previous mouse event received by the view that created
+ the event.
+
+ \sa lastPos(), lastScenePos(), screenPos()
+*/
+QPoint QGraphicsSceneMouseEvent::lastScreenPos() const
+{
+ Q_D(const QGraphicsSceneMouseEvent);
+ return d->lastScreenPos;
+}
+
+/*!
+ \internal
+*/
+void QGraphicsSceneMouseEvent::setLastScreenPos(const QPoint &pos)
+{
+ Q_D(QGraphicsSceneMouseEvent);
+ d->lastScreenPos = pos;
+}
+
+/*!
+ Returns the combination of mouse buttons that were pressed at the
+ time the event was sent.
+
+ \sa button(), modifiers()
+*/
+Qt::MouseButtons QGraphicsSceneMouseEvent::buttons() const
+{
+ Q_D(const QGraphicsSceneMouseEvent);
+ return d->buttons;
+}
+
+/*!
+ \internal
+*/
+void QGraphicsSceneMouseEvent::setButtons(Qt::MouseButtons buttons)
+{
+ Q_D(QGraphicsSceneMouseEvent);
+ d->buttons = buttons;
+}
+
+/*!
+ Returns the mouse button (if any) that caused the event.
+
+ \sa buttons(), modifiers()
+*/
+Qt::MouseButton QGraphicsSceneMouseEvent::button() const
+{
+ Q_D(const QGraphicsSceneMouseEvent);
+ return d->button;
+}
+
+/*!
+ \internal
+*/
+void QGraphicsSceneMouseEvent::setButton(Qt::MouseButton button)
+{
+ Q_D(QGraphicsSceneMouseEvent);
+ d->button = button;
+}
+
+/*!
+ Returns the keyboard modifiers in use at the time the event was
+ sent.
+
+ \sa buttons(), button()
+*/
+Qt::KeyboardModifiers QGraphicsSceneMouseEvent::modifiers() const
+{
+ Q_D(const QGraphicsSceneMouseEvent);
+ return d->modifiers;
+}
+
+/*!
+ \internal
+*/
+void QGraphicsSceneMouseEvent::setModifiers(Qt::KeyboardModifiers modifiers)
+{
+ Q_D(QGraphicsSceneMouseEvent);
+ d->modifiers = modifiers;
+}
+
+class QGraphicsSceneWheelEventPrivate : public QGraphicsSceneEventPrivate
+{
+ Q_DECLARE_PUBLIC(QGraphicsSceneWheelEvent)
+public:
+ inline QGraphicsSceneWheelEventPrivate()
+ : buttons(0), modifiers(0), delta(0), orientation(Qt::Horizontal)
+ { }
+
+ QPointF pos;
+ QPointF scenePos;
+ QPoint screenPos;
+ Qt::MouseButtons buttons;
+ Qt::KeyboardModifiers modifiers;
+ int delta;
+ Qt::Orientation orientation;
+};
+
+/*!
+ \internal
+
+ Constructs a QGraphicsSceneWheelEvent of type \a type, which
+ is always QEvent::GraphicsSceneWheel.
+*/
+QGraphicsSceneWheelEvent::QGraphicsSceneWheelEvent(Type type)
+ : QGraphicsSceneEvent(*new QGraphicsSceneWheelEventPrivate, type)
+{
+}
+
+/*!
+ Destroys the QGraphicsSceneWheelEvent.
+*/
+QGraphicsSceneWheelEvent::~QGraphicsSceneWheelEvent()
+{
+}
+
+/*!
+ Returns the position of the cursor in item coordinates when the
+ wheel event occurred.
+
+ \sa scenePos(), screenPos()
+*/
+QPointF QGraphicsSceneWheelEvent::pos() const
+{
+ Q_D(const QGraphicsSceneWheelEvent);
+ return d->pos;
+}
+
+/*!
+ \internal
+*/
+void QGraphicsSceneWheelEvent::setPos(const QPointF &pos)
+{
+ Q_D(QGraphicsSceneWheelEvent);
+ d->pos = pos;
+}
+
+/*!
+ Returns the position of the cursor in scene coordinates when the wheel
+ event occurred.
+
+ \sa pos(), screenPos()
+*/
+QPointF QGraphicsSceneWheelEvent::scenePos() const
+{
+ Q_D(const QGraphicsSceneWheelEvent);
+ return d->scenePos;
+}
+
+/*!
+ \internal
+*/
+void QGraphicsSceneWheelEvent::setScenePos(const QPointF &pos)
+{
+ Q_D(QGraphicsSceneWheelEvent);
+ d->scenePos = pos;
+}
+
+/*!
+ Returns the position of the cursor in screen coordinates when the wheel
+ event occurred.
+
+ \sa pos(), scenePos()
+*/
+QPoint QGraphicsSceneWheelEvent::screenPos() const
+{
+ Q_D(const QGraphicsSceneWheelEvent);
+ return d->screenPos;
+}
+
+/*!
+ \internal
+*/
+void QGraphicsSceneWheelEvent::setScreenPos(const QPoint &pos)
+{
+ Q_D(QGraphicsSceneWheelEvent);
+ d->screenPos = pos;
+}
+
+/*!
+ Returns the mouse buttons that were pressed when the wheel event occurred.
+
+ \sa modifiers()
+*/
+Qt::MouseButtons QGraphicsSceneWheelEvent::buttons() const
+{
+ Q_D(const QGraphicsSceneWheelEvent);
+ return d->buttons;
+}
+
+/*!
+ \internal
+*/
+void QGraphicsSceneWheelEvent::setButtons(Qt::MouseButtons buttons)
+{
+ Q_D(QGraphicsSceneWheelEvent);
+ d->buttons = buttons;
+}
+
+/*!
+ Returns the keyboard modifiers that were active when the wheel event
+ occurred.
+
+ \sa buttons()
+*/
+Qt::KeyboardModifiers QGraphicsSceneWheelEvent::modifiers() const
+{
+ Q_D(const QGraphicsSceneWheelEvent);
+ return d->modifiers;
+}
+
+/*!
+ \internal
+*/
+void QGraphicsSceneWheelEvent::setModifiers(Qt::KeyboardModifiers modifiers)
+{
+ Q_D(QGraphicsSceneWheelEvent);
+ d->modifiers = modifiers;
+}
+
+/*!
+ Returns the distance that the wheel is rotated, in eighths (1/8s)
+ of a degree. A positive value indicates that the wheel was
+ rotated forwards away from the user; a negative value indicates
+ that the wheel was rotated backwards toward the user.
+
+ Most mouse types work in steps of 15 degrees, in which case the delta
+ value is a multiple of 120 (== 15 * 8).
+*/
+int QGraphicsSceneWheelEvent::delta() const
+{
+ Q_D(const QGraphicsSceneWheelEvent);
+ return d->delta;
+}
+
+/*!
+ \internal
+*/
+void QGraphicsSceneWheelEvent::setDelta(int delta)
+{
+ Q_D(QGraphicsSceneWheelEvent);
+ d->delta = delta;
+}
+
+/*!
+ Returns the wheel orientation.
+*/
+Qt::Orientation QGraphicsSceneWheelEvent::orientation() const
+{
+ Q_D(const QGraphicsSceneWheelEvent);
+ return d->orientation;
+}
+
+/*!
+ \internal
+*/
+void QGraphicsSceneWheelEvent::setOrientation(Qt::Orientation orientation)
+{
+ Q_D(QGraphicsSceneWheelEvent);
+ d->orientation = orientation;
+}
+
+class QGraphicsSceneContextMenuEventPrivate : public QGraphicsSceneEventPrivate
+{
+ Q_DECLARE_PUBLIC(QGraphicsSceneContextMenuEvent)
+ public:
+ inline QGraphicsSceneContextMenuEventPrivate()
+ : modifiers(0), reason(QGraphicsSceneContextMenuEvent::Other)
+ { }
+
+ QPointF pos;
+ QPointF scenePos;
+ QPoint screenPos;
+ Qt::KeyboardModifiers modifiers;
+ QGraphicsSceneContextMenuEvent::Reason reason;
+};
+
+/*!
+ \internal
+
+ Constructs a graphics scene context menu event of the specified \a type.
+*/
+QGraphicsSceneContextMenuEvent::QGraphicsSceneContextMenuEvent(Type type)
+ : QGraphicsSceneEvent(*new QGraphicsSceneContextMenuEventPrivate, type)
+{
+}
+
+/*!
+ Destroys the event.
+*/
+QGraphicsSceneContextMenuEvent::~QGraphicsSceneContextMenuEvent()
+{
+}
+
+/*!
+ Returns the position of the mouse cursor in item coordinates at the moment
+ the context menu was requested.
+
+ \sa scenePos(), screenPos()
+*/
+QPointF QGraphicsSceneContextMenuEvent::pos() const
+{
+ Q_D(const QGraphicsSceneContextMenuEvent);
+ return d->pos;
+}
+
+/*!
+ \fn void QGraphicsSceneContextMenuEvent::setPos(const QPointF &point)
+ \internal
+
+ Sets the position associated with the context menu to the given \a point
+ in item coordinates.
+*/
+void QGraphicsSceneContextMenuEvent::setPos(const QPointF &pos)
+{
+ Q_D(QGraphicsSceneContextMenuEvent);
+ d->pos = pos;
+}
+
+/*!
+ Returns the position of the mouse cursor in scene coordinates at the moment the
+ the context menu was requested.
+
+ \sa pos(), screenPos()
+*/
+QPointF QGraphicsSceneContextMenuEvent::scenePos() const
+{
+ Q_D(const QGraphicsSceneContextMenuEvent);
+ return d->scenePos;
+}
+
+/*!
+ \fn void QGraphicsSceneContextMenuEvent::setScenePos(const QPointF &point)
+ \internal
+
+ Sets the position associated with the context menu to the given \a point
+ in scene coordinates.
+*/
+void QGraphicsSceneContextMenuEvent::setScenePos(const QPointF &pos)
+{
+ Q_D(QGraphicsSceneContextMenuEvent);
+ d->scenePos = pos;
+}
+
+/*!
+ Returns the position of the mouse cursor in screen coordinates at the moment the
+ the context menu was requested.
+
+ \sa pos(), scenePos()
+*/
+QPoint QGraphicsSceneContextMenuEvent::screenPos() const
+{
+ Q_D(const QGraphicsSceneContextMenuEvent);
+ return d->screenPos;
+}
+
+/*!
+ \fn void QGraphicsSceneContextMenuEvent::setScreenPos(const QPoint &point)
+ \internal
+
+ Sets the position associated with the context menu to the given \a point
+ in screen coordinates.
+*/
+void QGraphicsSceneContextMenuEvent::setScreenPos(const QPoint &pos)
+{
+ Q_D(QGraphicsSceneContextMenuEvent);
+ d->screenPos = pos;
+}
+
+/*!
+ Returns the keyboard modifiers in use when the context menu was requested.
+*/
+Qt::KeyboardModifiers QGraphicsSceneContextMenuEvent::modifiers() const
+{
+ Q_D(const QGraphicsSceneContextMenuEvent);
+ return d->modifiers;
+}
+
+/*!
+ \internal
+
+ Sets the keyboard modifiers associated with the context menu to the \a
+ modifiers specified.
+*/
+void QGraphicsSceneContextMenuEvent::setModifiers(Qt::KeyboardModifiers modifiers)
+{
+ Q_D(QGraphicsSceneContextMenuEvent);
+ d->modifiers = modifiers;
+}
+
+/*!
+ Returns the reason for the context menu event.
+
+ \sa QGraphicsSceneContextMenuEvent::Reason
+*/
+QGraphicsSceneContextMenuEvent::Reason QGraphicsSceneContextMenuEvent::reason() const
+{
+ Q_D(const QGraphicsSceneContextMenuEvent);
+ return d->reason;
+}
+
+/*!
+ \internal
+ Sets the reason for the context menu event to \a reason.
+
+ \sa reason()
+*/
+void QGraphicsSceneContextMenuEvent::setReason(Reason reason)
+{
+ Q_D(QGraphicsSceneContextMenuEvent);
+ d->reason = reason;
+}
+
+class QGraphicsSceneHoverEventPrivate : public QGraphicsSceneEventPrivate
+{
+public:
+ QPointF pos;
+ QPointF scenePos;
+ QPoint screenPos;
+ QPointF lastPos;
+ QPointF lastScenePos;
+ QPoint lastScreenPos;
+ Qt::KeyboardModifiers modifiers;
+};
+
+/*!
+ \internal
+
+ Constructs a graphics scene hover event of the specified \a type.
+*/
+QGraphicsSceneHoverEvent::QGraphicsSceneHoverEvent(Type type)
+ : QGraphicsSceneEvent(*new QGraphicsSceneHoverEventPrivate, type)
+{
+}
+
+/*!
+ Destroys the event.
+*/
+QGraphicsSceneHoverEvent::~QGraphicsSceneHoverEvent()
+{
+}
+
+/*!
+ Returns the position of the mouse cursor in item coordinates at the moment
+ the hover event was sent.
+
+ \sa scenePos(), screenPos()
+*/
+QPointF QGraphicsSceneHoverEvent::pos() const
+{
+ Q_D(const QGraphicsSceneHoverEvent);
+ return d->pos;
+}
+
+/*!
+ \fn void QGraphicsSceneHoverEvent::setPos(const QPointF &point)
+ \internal
+
+ Sets the position associated with the hover event to the given \a point in
+ item coordinates.
+*/
+void QGraphicsSceneHoverEvent::setPos(const QPointF &pos)
+{
+ Q_D(QGraphicsSceneHoverEvent);
+ d->pos = pos;
+}
+
+/*!
+ Returns the position of the mouse cursor in scene coordinates at the
+ moment the hover event was sent.
+
+ \sa pos(), screenPos()
+*/
+QPointF QGraphicsSceneHoverEvent::scenePos() const
+{
+ Q_D(const QGraphicsSceneHoverEvent);
+ return d->scenePos;
+}
+
+/*!
+ \fn void QGraphicsSceneHoverEvent::setScenePos(const QPointF &point)
+ \internal
+
+ Sets the position associated with the hover event to the given \a point in
+ scene coordinates.
+*/
+void QGraphicsSceneHoverEvent::setScenePos(const QPointF &pos)
+{
+ Q_D(QGraphicsSceneHoverEvent);
+ d->scenePos = pos;
+}
+
+/*!
+ Returns the position of the mouse cursor in screen coordinates at the
+ moment the hover event was sent.
+
+ \sa pos(), scenePos()
+*/
+QPoint QGraphicsSceneHoverEvent::screenPos() const
+{
+ Q_D(const QGraphicsSceneHoverEvent);
+ return d->screenPos;
+}
+
+/*!
+ \fn void QGraphicsSceneHoverEvent::setScreenPos(const QPoint &point)
+ \internal
+
+ Sets the position associated with the hover event to the given \a point in
+ screen coordinates.
+*/
+void QGraphicsSceneHoverEvent::setScreenPos(const QPoint &pos)
+{
+ Q_D(QGraphicsSceneHoverEvent);
+ d->screenPos = pos;
+}
+
+/*!
+ \since 4.4
+
+ Returns the last recorded mouse cursor position in item coordinates.
+
+ \sa lastScenePos(), lastScreenPos(), pos()
+*/
+QPointF QGraphicsSceneHoverEvent::lastPos() const
+{
+ Q_D(const QGraphicsSceneHoverEvent);
+ return d->lastPos;
+}
+
+/*!
+ \internal
+*/
+void QGraphicsSceneHoverEvent::setLastPos(const QPointF &pos)
+{
+ Q_D(QGraphicsSceneHoverEvent);
+ d->lastPos = pos;
+}
+
+/*!
+ \since 4.4
+
+ Returns the last recorded, the scene coordinates of the previous mouse or
+ hover event received by the view, that created the event mouse cursor
+ position in scene coordinates.
+
+ \sa lastPos(), lastScreenPos(), scenePos()
+*/
+QPointF QGraphicsSceneHoverEvent::lastScenePos() const
+{
+ Q_D(const QGraphicsSceneHoverEvent);
+ return d->lastScenePos;
+}
+
+/*!
+ \internal
+*/
+void QGraphicsSceneHoverEvent::setLastScenePos(const QPointF &pos)
+{
+ Q_D(QGraphicsSceneHoverEvent);
+ d->lastScenePos = pos;
+}
+
+/*!
+ \since 4.4
+
+ Returns the last recorded mouse cursor position in screen coordinates. The
+ last recorded position is the position of the previous mouse or hover
+ event received by the view that created the event.
+
+ \sa lastPos(), lastScenePos(), screenPos()
+*/
+QPoint QGraphicsSceneHoverEvent::lastScreenPos() const
+{
+ Q_D(const QGraphicsSceneHoverEvent);
+ return d->lastScreenPos;
+}
+
+/*!
+ \internal
+*/
+void QGraphicsSceneHoverEvent::setLastScreenPos(const QPoint &pos)
+{
+ Q_D(QGraphicsSceneHoverEvent);
+ d->lastScreenPos = pos;
+}
+
+/*!
+ \since 4.4
+
+ Returns the keyboard modifiers at the moment the hover event was sent.
+*/
+Qt::KeyboardModifiers QGraphicsSceneHoverEvent::modifiers() const
+{
+ Q_D(const QGraphicsSceneHoverEvent);
+ return d->modifiers;
+}
+
+/*!
+ \fn void QGraphicsSceneHoverEvent::setModifiers(Qt::KeyboardModifiers modifiers)
+ \internal
+
+ Sets the modifiers for the current hover event to \a modifiers.
+*/
+void QGraphicsSceneHoverEvent::setModifiers(Qt::KeyboardModifiers modifiers)
+{
+ Q_D(QGraphicsSceneHoverEvent);
+ d->modifiers = modifiers;
+}
+
+class QGraphicsSceneHelpEventPrivate : public QGraphicsSceneEventPrivate
+{
+public:
+ QPointF scenePos;
+ QPoint screenPos;
+};
+
+/*!
+ \internal
+
+ Constructs a graphics scene help event of the specified \a type.
+*/
+QGraphicsSceneHelpEvent::QGraphicsSceneHelpEvent(Type type)
+ : QGraphicsSceneEvent(*new QGraphicsSceneHelpEventPrivate, type)
+{
+}
+
+/*!
+ Destroys the event.
+*/
+QGraphicsSceneHelpEvent::~QGraphicsSceneHelpEvent()
+{
+}
+
+/*!
+ Returns the position of the mouse cursor in scene coordinates at the
+ moment the help event was sent.
+
+ \sa screenPos()
+*/
+QPointF QGraphicsSceneHelpEvent::scenePos() const
+{
+ Q_D(const QGraphicsSceneHelpEvent);
+ return d->scenePos;
+}
+
+/*!
+ \fn void QGraphicsSceneHelpEvent::setScenePos(const QPointF &point)
+ \internal
+
+ Sets the position associated with the context menu to the given \a point
+ in scene coordinates.
+*/
+void QGraphicsSceneHelpEvent::setScenePos(const QPointF &pos)
+{
+ Q_D(QGraphicsSceneHelpEvent);
+ d->scenePos = pos;
+}
+
+/*!
+ Returns the position of the mouse cursor in screen coordinates at the
+ moment the help event was sent.
+
+ \sa scenePos()
+*/
+QPoint QGraphicsSceneHelpEvent::screenPos() const
+{
+ Q_D(const QGraphicsSceneHelpEvent);
+ return d->screenPos;
+}
+
+/*!
+ \fn void QGraphicsSceneHelpEvent::setScreenPos(const QPoint &point)
+ \internal
+
+ Sets the position associated with the context menu to the given \a point
+ in screen coordinates.
+*/
+void QGraphicsSceneHelpEvent::setScreenPos(const QPoint &pos)
+{
+ Q_D(QGraphicsSceneHelpEvent);
+ d->screenPos = pos;
+}
+
+class QGraphicsSceneDragDropEventPrivate : public QGraphicsSceneEventPrivate
+{
+ Q_DECLARE_PUBLIC(QGraphicsSceneDragDropEvent)
+public:
+ inline QGraphicsSceneDragDropEventPrivate()
+ : source(0), mimeData(0)
+ { }
+
+ QPointF pos;
+ QPointF scenePos;
+ QPoint screenPos;
+ Qt::MouseButtons buttons;
+ Qt::KeyboardModifiers modifiers;
+ Qt::DropActions possibleActions;
+ Qt::DropAction proposedAction;
+ Qt::DropAction dropAction;
+ QWidget *source;
+ const QMimeData *mimeData;
+};
+
+/*!
+ \internal
+
+ Constructs a new QGraphicsSceneDragDropEvent of the
+ specified \a type. The type can be either
+ QEvent::GraphicsSceneDragEnter, QEvent::GraphicsSceneDragLeave,
+ QEvent::GraphicsSceneDragMove, or QEvent::GraphicsSceneDrop.
+*/
+QGraphicsSceneDragDropEvent::QGraphicsSceneDragDropEvent(Type type)
+ : QGraphicsSceneEvent(*new QGraphicsSceneDragDropEventPrivate, type)
+{
+}
+
+/*!
+ Destroys the object.
+*/
+QGraphicsSceneDragDropEvent::~QGraphicsSceneDragDropEvent()
+{
+}
+
+/*!
+ Returns the mouse position of the event relative to the
+ view that sent the event.
+
+ \sa QGraphicsView, screenPos(), scenePos()
+*/
+QPointF QGraphicsSceneDragDropEvent::pos() const
+{
+ Q_D(const QGraphicsSceneDragDropEvent);
+ return d->pos;
+}
+
+/*!
+ \internal
+ Sets the position of the mouse to \a pos; this should be
+ relative to the widget that generated the event, which normally
+ is a QGraphicsView.
+
+ \sa pos(), setScenePos(), setScreenPos()
+*/
+
+void QGraphicsSceneDragDropEvent::setPos(const QPointF &pos)
+{
+ Q_D(QGraphicsSceneDragDropEvent);
+ d->pos = pos;
+}
+
+/*!
+ Returns the position of the mouse in scene coordinates.
+
+ \sa pos(), screenPos()
+*/
+QPointF QGraphicsSceneDragDropEvent::scenePos() const
+{
+ Q_D(const QGraphicsSceneDragDropEvent);
+ return d->scenePos;
+}
+
+/*!
+ \internal
+ Sets the scene position of the mouse to \a pos.
+
+ \sa scenePos(), setScreenPos(), setPos()
+*/
+void QGraphicsSceneDragDropEvent::setScenePos(const QPointF &pos)
+{
+ Q_D(QGraphicsSceneDragDropEvent);
+ d->scenePos = pos;
+}
+
+/*!
+ Returns the position of the mouse relative to the screen.
+
+ \sa pos(), scenePos()
+*/
+QPoint QGraphicsSceneDragDropEvent::screenPos() const
+{
+ Q_D(const QGraphicsSceneDragDropEvent);
+ return d->screenPos;
+}
+
+/*!
+ \internal
+ Sets the mouse position relative to the screen to \a pos.
+
+ \sa screenPos(), setScenePos(), setPos()
+*/
+void QGraphicsSceneDragDropEvent::setScreenPos(const QPoint &pos)
+{
+ Q_D(QGraphicsSceneDragDropEvent);
+ d->screenPos = pos;
+}
+
+/*!
+ Returns a Qt::MouseButtons value indicating which buttons
+ were pressed on the mouse when this mouse event was
+ generated.
+
+ \sa Qt::MouseButtons
+*/
+Qt::MouseButtons QGraphicsSceneDragDropEvent::buttons() const
+{
+ Q_D(const QGraphicsSceneDragDropEvent);
+ return d->buttons;
+}
+
+/*!
+ \internal
+ Sets the mouse buttons that were pressed when the event was
+ created to \a buttons.
+
+ \sa Qt::MouseButtons, buttons()
+*/
+void QGraphicsSceneDragDropEvent::setButtons(Qt::MouseButtons buttons)
+{
+ Q_D(QGraphicsSceneDragDropEvent);
+ d->buttons = buttons;
+}
+
+/*!
+ Returns the keyboard modifiers that were pressed when the drag
+ and drop event was created.
+
+ \sa Qt::KeyboardModifiers
+*/
+Qt::KeyboardModifiers QGraphicsSceneDragDropEvent::modifiers() const
+{
+ Q_D(const QGraphicsSceneDragDropEvent);
+ return d->modifiers;
+}
+
+/*!
+ \internal
+ Sets the keyboard modifiers that were pressed when the event
+ was created to \a modifiers.
+
+ \sa Qt::KeyboardModifiers, modifiers()
+*/
+
+void QGraphicsSceneDragDropEvent::setModifiers(Qt::KeyboardModifiers modifiers)
+{
+ Q_D(QGraphicsSceneDragDropEvent);
+ d->modifiers = modifiers;
+}
+
+/*!
+ Returns the possible drop actions that the drag and
+ drop can result in.
+
+ \sa Qt::DropActions
+*/
+
+Qt::DropActions QGraphicsSceneDragDropEvent::possibleActions() const
+{
+ Q_D(const QGraphicsSceneDragDropEvent);
+ return d->possibleActions;
+}
+
+/*!
+ \internal
+ Sets the possible drop actions that the drag can
+ result in to \a actions.
+
+ \sa Qt::DropActions, possibleActions()
+*/
+void QGraphicsSceneDragDropEvent::setPossibleActions(Qt::DropActions actions)
+{
+ Q_D(QGraphicsSceneDragDropEvent);
+ d->possibleActions = actions;
+}
+
+/*!
+ Returns the drop action that is proposed, i.e., preferred.
+ The action must be one of the possible actions as defined by
+ \c possibleActions().
+
+ \sa Qt::DropAction, possibleActions()
+*/
+
+Qt::DropAction QGraphicsSceneDragDropEvent::proposedAction() const
+{
+ Q_D(const QGraphicsSceneDragDropEvent);
+ return d->proposedAction;
+}
+
+/*!
+ \internal
+ Sets the proposed action to \a action. The proposed action
+ is a Qt::DropAction that is one of the possible actions as
+ given by \c possibleActions().
+
+ \sa proposedAction(), Qt::DropAction, possibleActions()
+*/
+
+void QGraphicsSceneDragDropEvent::setProposedAction(Qt::DropAction action)
+{
+ Q_D(QGraphicsSceneDragDropEvent);
+ d->proposedAction = action;
+}
+
+/*!
+ Sets the proposed action as accepted, i.e, the drop action
+ is set to the proposed action. This is equal to:
+
+ \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicssceneevent.cpp 0
+
+ When using this function, one should not call \c accept().
+
+ \sa dropAction(), setDropAction(), proposedAction()
+*/
+
+void QGraphicsSceneDragDropEvent::acceptProposedAction()
+{
+ Q_D(QGraphicsSceneDragDropEvent);
+ d->dropAction = d->proposedAction;
+}
+
+/*!
+ Returns the action that was performed in this drag and drop.
+ This should be set by the receiver of the drop and is
+ returned by QDrag::exec().
+
+ \sa setDropAction(), acceptProposedAction()
+*/
+
+Qt::DropAction QGraphicsSceneDragDropEvent::dropAction() const
+{
+ Q_D(const QGraphicsSceneDragDropEvent);
+ return d->dropAction;
+}
+
+/*!
+ This function lets the receiver of the drop set the drop
+ action that was performed to \a action, which should be one
+ of the
+ \l{QGraphicsSceneDragDropEvent::possibleActions()}{possible
+ actions}. Call \c accept() in stead of \c
+ acceptProposedAction() if you use this function.
+
+ \sa dropAction(), accept(), possibleActions()
+*/
+void QGraphicsSceneDragDropEvent::setDropAction(Qt::DropAction action)
+{
+ Q_D(QGraphicsSceneDragDropEvent);
+ d->dropAction = action;
+}
+
+/*!
+ This function returns the QGraphicsView that created the
+ QGraphicsSceneDragDropEvent.
+*/
+QWidget *QGraphicsSceneDragDropEvent::source() const
+{
+ Q_D(const QGraphicsSceneDragDropEvent);
+ return d->source;
+}
+
+/*!
+ \internal
+ This function set the source widget, i.e., the widget that
+ created the drop event, to \a source.
+*/
+void QGraphicsSceneDragDropEvent::setSource(QWidget *source)
+{
+ Q_D(QGraphicsSceneDragDropEvent);
+ d->source = source;
+}
+
+/*!
+ This function returns the MIME data of the event.
+*/
+const QMimeData *QGraphicsSceneDragDropEvent::mimeData() const
+{
+ Q_D(const QGraphicsSceneDragDropEvent);
+ return d->mimeData;
+}
+
+/*!
+ \internal
+ This function sets the MIME data for the event.
+*/
+void QGraphicsSceneDragDropEvent::setMimeData(const QMimeData *data)
+{
+ Q_D(QGraphicsSceneDragDropEvent);
+ d->mimeData = data;
+}
+
+class QGraphicsSceneResizeEventPrivate : public QGraphicsSceneEventPrivate
+{
+ Q_DECLARE_PUBLIC(QGraphicsSceneResizeEvent)
+public:
+ inline QGraphicsSceneResizeEventPrivate()
+ { }
+
+ QSizeF oldSize;
+ QSizeF newSize;
+};
+
+/*!
+ Constructs a QGraphicsSceneResizeEvent.
+*/
+QGraphicsSceneResizeEvent::QGraphicsSceneResizeEvent()
+ : QGraphicsSceneEvent(*new QGraphicsSceneResizeEventPrivate, QEvent::GraphicsSceneResize)
+{
+}
+
+/*!
+ Destroys the QGraphicsSceneResizeEvent.
+*/
+QGraphicsSceneResizeEvent::~QGraphicsSceneResizeEvent()
+{
+}
+
+/*!
+ Returns the old size (i.e., the size immediately before the widget was
+ resized).
+
+ \sa newSize(), QGraphicsWidget::resize()
+*/
+QSizeF QGraphicsSceneResizeEvent::oldSize() const
+{
+ Q_D(const QGraphicsSceneResizeEvent);
+ return d->oldSize;
+}
+
+/*!
+ \internal
+*/
+void QGraphicsSceneResizeEvent::setOldSize(const QSizeF &size)
+{
+ Q_D(QGraphicsSceneResizeEvent);
+ d->oldSize = size;
+}
+
+/*!
+ Returns the new size (i.e., the current size).
+
+ \sa oldSize(), QGraphicsWidget::resize()
+*/
+QSizeF QGraphicsSceneResizeEvent::newSize() const
+{
+ Q_D(const QGraphicsSceneResizeEvent);
+ return d->newSize;
+}
+
+/*!
+ \internal
+*/
+void QGraphicsSceneResizeEvent::setNewSize(const QSizeF &size)
+{
+ Q_D(QGraphicsSceneResizeEvent);
+ d->newSize = size;
+}
+
+class QGraphicsSceneMoveEventPrivate : public QGraphicsSceneEventPrivate
+{
+ Q_DECLARE_PUBLIC(QGraphicsSceneMoveEvent)
+public:
+ inline QGraphicsSceneMoveEventPrivate()
+ { }
+
+ QPointF oldPos;
+ QPointF newPos;
+};
+
+/*!
+ Constructs a QGraphicsSceneMoveEvent.
+*/
+QGraphicsSceneMoveEvent::QGraphicsSceneMoveEvent()
+ : QGraphicsSceneEvent(*new QGraphicsSceneMoveEventPrivate, QEvent::GraphicsSceneMove)
+{
+}
+
+/*!
+ Destroys the QGraphicsSceneMoveEvent.
+*/
+QGraphicsSceneMoveEvent::~QGraphicsSceneMoveEvent()
+{
+}
+
+/*!
+ Returns the old position (i.e., the position immediately before the widget
+ was moved).
+
+ \sa newPos(), QGraphicsItem::setPos()
+*/
+QPointF QGraphicsSceneMoveEvent::oldPos() const
+{
+ Q_D(const QGraphicsSceneMoveEvent);
+ return d->oldPos;
+}
+
+/*!
+ \internal
+*/
+void QGraphicsSceneMoveEvent::setOldPos(const QPointF &pos)
+{
+ Q_D(QGraphicsSceneMoveEvent);
+ d->oldPos = pos;
+}
+
+/*!
+ Returns the new position (i.e., the current position).
+
+ \sa oldPos(), QGraphicsItem::setPos()
+*/
+QPointF QGraphicsSceneMoveEvent::newPos() const
+{
+ Q_D(const QGraphicsSceneMoveEvent);
+ return d->newPos;
+}
+
+/*!
+ \internal
+*/
+void QGraphicsSceneMoveEvent::setNewPos(const QPointF &pos)
+{
+ Q_D(QGraphicsSceneMoveEvent);
+ d->newPos = pos;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_GRAPHICSVIEW
diff --git a/src/widgets/graphicsview/qgraphicssceneevent.h b/src/widgets/graphicsview/qgraphicssceneevent.h
new file mode 100644
index 0000000000..f3677fbef8
--- /dev/null
+++ b/src/widgets/graphicsview/qgraphicssceneevent.h
@@ -0,0 +1,326 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGRAPHICSSCENEEVENT_H
+#define QGRAPHICSSCENEEVENT_H
+
+#include <QtCore/qcoreevent.h>
+#include <QtCore/qpoint.h>
+#include <QtCore/qscopedpointer.h>
+#include <QtCore/qrect.h>
+#include <QtGui/qpolygon.h>
+#include <QtCore/qset.h>
+#include <QtCore/qhash.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW
+
+class QMimeData;
+class QPointF;
+class QSizeF;
+class QWidget;
+
+class QGraphicsSceneEventPrivate;
+class Q_WIDGETS_EXPORT QGraphicsSceneEvent : public QEvent
+{
+public:
+ QGraphicsSceneEvent(Type type);
+ ~QGraphicsSceneEvent();
+
+ QWidget *widget() const;
+ void setWidget(QWidget *widget);
+
+protected:
+ QGraphicsSceneEvent(QGraphicsSceneEventPrivate &dd, Type type = None);
+ QScopedPointer<QGraphicsSceneEventPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QGraphicsSceneEvent)
+private:
+ Q_DISABLE_COPY(QGraphicsSceneEvent)
+};
+
+class QGraphicsSceneMouseEventPrivate;
+class Q_WIDGETS_EXPORT QGraphicsSceneMouseEvent : public QGraphicsSceneEvent
+{
+public:
+ QGraphicsSceneMouseEvent(Type type = None);
+ ~QGraphicsSceneMouseEvent();
+
+ QPointF pos() const;
+ void setPos(const QPointF &pos);
+
+ QPointF scenePos() const;
+ void setScenePos(const QPointF &pos);
+
+ QPoint screenPos() const;
+ void setScreenPos(const QPoint &pos);
+
+ QPointF buttonDownPos(Qt::MouseButton button) const;
+ void setButtonDownPos(Qt::MouseButton button, const QPointF &pos);
+
+ QPointF buttonDownScenePos(Qt::MouseButton button) const;
+ void setButtonDownScenePos(Qt::MouseButton button, const QPointF &pos);
+
+ QPoint buttonDownScreenPos(Qt::MouseButton button) const;
+ void setButtonDownScreenPos(Qt::MouseButton button, const QPoint &pos);
+
+ QPointF lastPos() const;
+ void setLastPos(const QPointF &pos);
+
+ QPointF lastScenePos() const;
+ void setLastScenePos(const QPointF &pos);
+
+ QPoint lastScreenPos() const;
+ void setLastScreenPos(const QPoint &pos);
+
+ Qt::MouseButtons buttons() const;
+ void setButtons(Qt::MouseButtons buttons);
+
+ Qt::MouseButton button() const;
+ void setButton(Qt::MouseButton button);
+
+ Qt::KeyboardModifiers modifiers() const;
+ void setModifiers(Qt::KeyboardModifiers modifiers);
+
+private:
+ Q_DECLARE_PRIVATE(QGraphicsSceneMouseEvent)
+ Q_DISABLE_COPY(QGraphicsSceneMouseEvent)
+};
+
+class QGraphicsSceneWheelEventPrivate;
+class Q_WIDGETS_EXPORT QGraphicsSceneWheelEvent : public QGraphicsSceneEvent
+{
+public:
+ QGraphicsSceneWheelEvent(Type type = None);
+ ~QGraphicsSceneWheelEvent();
+
+ QPointF pos() const;
+ void setPos(const QPointF &pos);
+
+ QPointF scenePos() const;
+ void setScenePos(const QPointF &pos);
+
+ QPoint screenPos() const;
+ void setScreenPos(const QPoint &pos);
+
+ Qt::MouseButtons buttons() const;
+ void setButtons(Qt::MouseButtons buttons);
+
+ Qt::KeyboardModifiers modifiers() const;
+ void setModifiers(Qt::KeyboardModifiers modifiers);
+
+ int delta() const;
+ void setDelta(int delta);
+
+ Qt::Orientation orientation() const;
+ void setOrientation(Qt::Orientation orientation);
+
+private:
+ Q_DECLARE_PRIVATE(QGraphicsSceneWheelEvent)
+ Q_DISABLE_COPY(QGraphicsSceneWheelEvent)
+};
+
+class QGraphicsSceneContextMenuEventPrivate;
+class Q_WIDGETS_EXPORT QGraphicsSceneContextMenuEvent : public QGraphicsSceneEvent
+{
+public:
+ enum Reason { Mouse, Keyboard, Other };
+
+ QGraphicsSceneContextMenuEvent(Type type = None);
+ ~QGraphicsSceneContextMenuEvent();
+
+ QPointF pos() const;
+ void setPos(const QPointF &pos);
+
+ QPointF scenePos() const;
+ void setScenePos(const QPointF &pos);
+
+ QPoint screenPos() const;
+ void setScreenPos(const QPoint &pos);
+
+ Qt::KeyboardModifiers modifiers() const;
+ void setModifiers(Qt::KeyboardModifiers modifiers);
+
+ Reason reason() const;
+ void setReason(Reason reason);
+
+private:
+ Q_DECLARE_PRIVATE(QGraphicsSceneContextMenuEvent)
+ Q_DISABLE_COPY(QGraphicsSceneContextMenuEvent)
+};
+
+class QGraphicsSceneHoverEventPrivate;
+class Q_WIDGETS_EXPORT QGraphicsSceneHoverEvent : public QGraphicsSceneEvent
+{
+public:
+ QGraphicsSceneHoverEvent(Type type = None);
+ ~QGraphicsSceneHoverEvent();
+
+ QPointF pos() const;
+ void setPos(const QPointF &pos);
+
+ QPointF scenePos() const;
+ void setScenePos(const QPointF &pos);
+
+ QPoint screenPos() const;
+ void setScreenPos(const QPoint &pos);
+
+ QPointF lastPos() const;
+ void setLastPos(const QPointF &pos);
+
+ QPointF lastScenePos() const;
+ void setLastScenePos(const QPointF &pos);
+
+ QPoint lastScreenPos() const;
+ void setLastScreenPos(const QPoint &pos);
+
+ Qt::KeyboardModifiers modifiers() const;
+ void setModifiers(Qt::KeyboardModifiers modifiers);
+
+private:
+ Q_DECLARE_PRIVATE(QGraphicsSceneHoverEvent)
+ Q_DISABLE_COPY(QGraphicsSceneHoverEvent)
+};
+
+class QGraphicsSceneHelpEventPrivate;
+class Q_WIDGETS_EXPORT QGraphicsSceneHelpEvent : public QGraphicsSceneEvent
+{
+public:
+ QGraphicsSceneHelpEvent(Type type = None);
+ ~QGraphicsSceneHelpEvent();
+
+ QPointF scenePos() const;
+ void setScenePos(const QPointF &pos);
+
+ QPoint screenPos() const;
+ void setScreenPos(const QPoint &pos);
+
+private:
+ Q_DECLARE_PRIVATE(QGraphicsSceneHelpEvent)
+ Q_DISABLE_COPY(QGraphicsSceneHelpEvent)
+};
+
+class QGraphicsSceneDragDropEventPrivate;
+class Q_WIDGETS_EXPORT QGraphicsSceneDragDropEvent : public QGraphicsSceneEvent
+{
+public:
+ QGraphicsSceneDragDropEvent(Type type = None);
+ ~QGraphicsSceneDragDropEvent();
+
+ QPointF pos() const;
+ void setPos(const QPointF &pos);
+
+ QPointF scenePos() const;
+ void setScenePos(const QPointF &pos);
+
+ QPoint screenPos() const;
+ void setScreenPos(const QPoint &pos);
+
+ Qt::MouseButtons buttons() const;
+ void setButtons(Qt::MouseButtons buttons);
+
+ Qt::KeyboardModifiers modifiers() const;
+ void setModifiers(Qt::KeyboardModifiers modifiers);
+
+ Qt::DropActions possibleActions() const;
+ void setPossibleActions(Qt::DropActions actions);
+
+ Qt::DropAction proposedAction() const;
+ void setProposedAction(Qt::DropAction action);
+ void acceptProposedAction();
+
+ Qt::DropAction dropAction() const;
+ void setDropAction(Qt::DropAction action);
+
+ QWidget *source() const;
+ void setSource(QWidget *source);
+
+ const QMimeData *mimeData() const;
+ void setMimeData(const QMimeData *data);
+
+private:
+ Q_DECLARE_PRIVATE(QGraphicsSceneDragDropEvent)
+ Q_DISABLE_COPY(QGraphicsSceneDragDropEvent)
+};
+
+class QGraphicsSceneResizeEventPrivate;
+class Q_WIDGETS_EXPORT QGraphicsSceneResizeEvent : public QGraphicsSceneEvent
+{
+ Q_DECLARE_PRIVATE(QGraphicsSceneResizeEvent)
+ Q_DISABLE_COPY(QGraphicsSceneResizeEvent)
+public:
+ QGraphicsSceneResizeEvent();
+ ~QGraphicsSceneResizeEvent();
+
+ QSizeF oldSize() const;
+ void setOldSize(const QSizeF &size);
+
+ QSizeF newSize() const;
+ void setNewSize(const QSizeF &size);
+};
+
+class QGraphicsSceneMoveEventPrivate;
+class Q_WIDGETS_EXPORT QGraphicsSceneMoveEvent : public QGraphicsSceneEvent
+{
+ Q_DECLARE_PRIVATE(QGraphicsSceneMoveEvent)
+ Q_DISABLE_COPY(QGraphicsSceneMoveEvent)
+public:
+ QGraphicsSceneMoveEvent();
+ ~QGraphicsSceneMoveEvent();
+
+ QPointF oldPos() const;
+ void setOldPos(const QPointF &pos);
+
+ QPointF newPos() const;
+ void setNewPos(const QPointF &pos);
+};
+
+#endif // QT_NO_GRAPHICSVIEW
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/widgets/graphicsview/qgraphicssceneindex.cpp
index d5ca504cae..d5ca504cae 100644
--- a/src/gui/graphicsview/qgraphicssceneindex.cpp
+++ b/src/widgets/graphicsview/qgraphicssceneindex.cpp
diff --git a/src/gui/graphicsview/qgraphicssceneindex_p.h b/src/widgets/graphicsview/qgraphicssceneindex_p.h
index d7e01f64b3..d7e01f64b3 100644
--- a/src/gui/graphicsview/qgraphicssceneindex_p.h
+++ b/src/widgets/graphicsview/qgraphicssceneindex_p.h
diff --git a/src/gui/graphicsview/qgraphicsscenelinearindex.cpp b/src/widgets/graphicsview/qgraphicsscenelinearindex.cpp
index 9a4b3389bc..9a4b3389bc 100644
--- a/src/gui/graphicsview/qgraphicsscenelinearindex.cpp
+++ b/src/widgets/graphicsview/qgraphicsscenelinearindex.cpp
diff --git a/src/widgets/graphicsview/qgraphicsscenelinearindex_p.h b/src/widgets/graphicsview/qgraphicsscenelinearindex_p.h
new file mode 100644
index 0000000000..37ba363c1e
--- /dev/null
+++ b/src/widgets/graphicsview/qgraphicsscenelinearindex_p.h
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGRAPHICSSCENELINEARINDEX_H
+#define QGRAPHICSSCENELINEARINDEX_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qglobal.h>
+
+#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW
+
+#include <QtCore/qrect.h>
+#include <QtCore/qlist.h>
+#include <QtWidgets/qgraphicsitem.h>
+#include <private/qgraphicssceneindex_p.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class Q_AUTOTEST_EXPORT QGraphicsSceneLinearIndex : public QGraphicsSceneIndex
+{
+ Q_OBJECT
+
+public:
+ QGraphicsSceneLinearIndex(QGraphicsScene *scene = 0) : QGraphicsSceneIndex(scene)
+ { }
+
+ QList<QGraphicsItem *> items(Qt::SortOrder order = Qt::DescendingOrder) const
+ { Q_UNUSED(order); return m_items; }
+
+ virtual QList<QGraphicsItem *> estimateItems(const QRectF &rect, Qt::SortOrder order) const
+ {
+ Q_UNUSED(rect);
+ Q_UNUSED(order);
+ return m_items;
+ }
+
+protected :
+ virtual void clear()
+ { m_items.clear(); }
+
+ virtual void addItem(QGraphicsItem *item)
+ { m_items << item; }
+
+ virtual void removeItem(QGraphicsItem *item)
+ { m_items.removeOne(item); }
+
+private:
+ QList<QGraphicsItem*> m_items;
+};
+
+#endif // QT_NO_GRAPHICSVIEW
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QGRAPHICSSCENELINEARINDEX_H
diff --git a/src/gui/graphicsview/qgraphicstransform.cpp b/src/widgets/graphicsview/qgraphicstransform.cpp
index fa56427f36..fa56427f36 100644
--- a/src/gui/graphicsview/qgraphicstransform.cpp
+++ b/src/widgets/graphicsview/qgraphicstransform.cpp
diff --git a/src/widgets/graphicsview/qgraphicstransform.h b/src/widgets/graphicsview/qgraphicstransform.h
new file mode 100644
index 0000000000..4bceecc47c
--- /dev/null
+++ b/src/widgets/graphicsview/qgraphicstransform.h
@@ -0,0 +1,159 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGRAPHICSTRANSFORM_H
+#define QGRAPHICSTRANSFORM_H
+
+#include <QtCore/QObject>
+#include <QtGui/QVector3D>
+#include <QtGui/QTransform>
+#include <QtGui/QMatrix4x4>
+
+#ifndef QT_NO_GRAPHICSVIEW
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QGraphicsItem;
+class QGraphicsTransformPrivate;
+
+class Q_WIDGETS_EXPORT QGraphicsTransform : public QObject
+{
+ Q_OBJECT
+public:
+ QGraphicsTransform(QObject *parent = 0);
+ ~QGraphicsTransform();
+
+ virtual void applyTo(QMatrix4x4 *matrix) const = 0;
+
+protected Q_SLOTS:
+ void update();
+
+protected:
+ QGraphicsTransform(QGraphicsTransformPrivate &p, QObject *parent);
+
+private:
+ friend class QGraphicsItem;
+ friend class QGraphicsItemPrivate;
+ Q_DECLARE_PRIVATE(QGraphicsTransform)
+};
+
+class QGraphicsScalePrivate;
+
+class Q_WIDGETS_EXPORT QGraphicsScale : public QGraphicsTransform
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QVector3D origin READ origin WRITE setOrigin NOTIFY originChanged)
+ Q_PROPERTY(qreal xScale READ xScale WRITE setXScale NOTIFY xScaleChanged)
+ Q_PROPERTY(qreal yScale READ yScale WRITE setYScale NOTIFY yScaleChanged)
+ Q_PROPERTY(qreal zScale READ zScale WRITE setZScale NOTIFY zScaleChanged)
+public:
+ QGraphicsScale(QObject *parent = 0);
+ ~QGraphicsScale();
+
+ QVector3D origin() const;
+ void setOrigin(const QVector3D &point);
+
+ qreal xScale() const;
+ void setXScale(qreal);
+
+ qreal yScale() const;
+ void setYScale(qreal);
+
+ qreal zScale() const;
+ void setZScale(qreal);
+
+ void applyTo(QMatrix4x4 *matrix) const;
+
+Q_SIGNALS:
+ void originChanged();
+ void xScaleChanged();
+ void yScaleChanged();
+ void zScaleChanged();
+ void scaleChanged();
+
+private:
+ Q_DECLARE_PRIVATE(QGraphicsScale)
+};
+
+class QGraphicsRotationPrivate;
+
+class Q_WIDGETS_EXPORT QGraphicsRotation : public QGraphicsTransform
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QVector3D origin READ origin WRITE setOrigin NOTIFY originChanged)
+ Q_PROPERTY(qreal angle READ angle WRITE setAngle NOTIFY angleChanged)
+ Q_PROPERTY(QVector3D axis READ axis WRITE setAxis NOTIFY axisChanged)
+public:
+ QGraphicsRotation(QObject *parent = 0);
+ ~QGraphicsRotation();
+
+ QVector3D origin() const;
+ void setOrigin(const QVector3D &point);
+
+ qreal angle() const;
+ void setAngle(qreal);
+
+ QVector3D axis() const;
+ void setAxis(const QVector3D &axis);
+ void setAxis(Qt::Axis axis);
+
+ void applyTo(QMatrix4x4 *matrix) const;
+
+Q_SIGNALS:
+ void originChanged();
+ void angleChanged();
+ void axisChanged();
+
+private:
+ Q_DECLARE_PRIVATE(QGraphicsRotation)
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+#endif //QT_NO_GRAPHICSVIEW
+
+#endif // QFXTRANSFORM_H
diff --git a/src/gui/graphicsview/qgraphicstransform_p.h b/src/widgets/graphicsview/qgraphicstransform_p.h
index d2b851fe97..d2b851fe97 100644
--- a/src/gui/graphicsview/qgraphicstransform_p.h
+++ b/src/widgets/graphicsview/qgraphicstransform_p.h
diff --git a/src/widgets/graphicsview/qgraphicsview.cpp b/src/widgets/graphicsview/qgraphicsview.cpp
new file mode 100644
index 0000000000..b5ec8a8d5d
--- /dev/null
+++ b/src/widgets/graphicsview/qgraphicsview.cpp
@@ -0,0 +1,3880 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+static const int QGRAPHICSVIEW_REGION_RECT_THRESHOLD = 50;
+
+static const int QGRAPHICSVIEW_PREALLOC_STYLE_OPTIONS = 503; // largest prime < 2^9
+
+/*!
+ \class QGraphicsView
+ \brief The QGraphicsView class provides a widget for displaying the
+ contents of a QGraphicsScene.
+ \since 4.2
+ \ingroup graphicsview-api
+
+
+ QGraphicsView visualizes the contents of a QGraphicsScene in a scrollable
+ viewport. To create a scene with geometrical items, see QGraphicsScene's
+ documentation. QGraphicsView is part of the \l{Graphics View Framework}.
+
+ To visualize a scene, you start by constructing a QGraphicsView object,
+ passing the address of the scene you want to visualize to QGraphicsView's
+ constructor. Alternatively, you can call setScene() to set the scene at a
+ later point. After you call show(), the view will by default scroll to the
+ center of the scene and display any items that are visible at this
+ point. For example:
+
+ \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsview.cpp 0
+
+ You can explicitly scroll to any position on the scene by using the
+ scroll bars, or by calling centerOn(). By passing a point to centerOn(),
+ QGraphicsView will scroll its viewport to ensure that the point is
+ centered in the view. An overload is provided for scrolling to a
+ QGraphicsItem, in which case QGraphicsView will see to that the center of
+ the item is centered in the view. If all you want is to ensure that a
+ certain area is visible, (but not necessarily centered,) you can call
+ ensureVisible() instead.
+
+ QGraphicsView can be used to visualize a whole scene, or only parts of it.
+ The visualized area is by default detected automatically when the view is
+ displayed for the first time (by calling
+ QGraphicsScene::itemsBoundingRect()). To set the visualized area rectangle
+ yourself, you can call setSceneRect(). This will adjust the scroll bars'
+ ranges appropriately. Note that although the scene supports a virtually
+ unlimited size, the range of the scroll bars will never exceed the range of
+ an integer (INT_MIN, INT_MAX).
+
+ QGraphicsView visualizes the scene by calling render(). By default, the
+ items are drawn onto the viewport by using a regular QPainter, and using
+ default render hints. To change the default render hints that
+ QGraphicsView passes to QPainter when painting items, you can call
+ setRenderHints().
+
+ By default, QGraphicsView provides a regular QWidget for the viewport
+ widget. You can access this widget by calling viewport(), or you can
+ replace it by calling setViewport(). To render using OpenGL, simply call
+ setViewport(new QGLWidget). QGraphicsView takes ownership of the viewport
+ widget.
+
+ QGraphicsView supports affine transformations, using QTransform. You can
+ either pass a matrix to setTransform(), or you can call one of the
+ convenience functions rotate(), scale(), translate() or shear(). The most
+ two common transformations are scaling, which is used to implement
+ zooming, and rotation. QGraphicsView keeps the center of the view fixed
+ during a transformation. Because of the scene alignment (setAligment()),
+ translating the view will have no visual impact.
+
+ You can interact with the items on the scene by using the mouse and
+ keyboard. QGraphicsView translates the mouse and key events into \e scene
+ events, (events that inherit QGraphicsSceneEvent,), and forward them to
+ the visualized scene. In the end, it's the individual item that handles
+ the events and reacts to them. For example, if you click on a selectable
+ item, the item will typically let the scene know that it has been
+ selected, and it will also redraw itself to display a selection
+ rectangle. Similiary, if you click and drag the mouse to move a movable
+ item, it's the item that handles the mouse moves and moves itself. Item
+ interaction is enabled by default, and you can toggle it by calling
+ setInteractive().
+
+ You can also provide your own custom scene interaction, by creating a
+ subclass of QGraphicsView, and reimplementing the mouse and key event
+ handlers. To simplify how you programmatically interact with items in the
+ view, QGraphicsView provides the mapping functions mapToScene() and
+ mapFromScene(), and the item accessors items() and itemAt(). These
+ functions allow you to map points, rectangles, polygons and paths between
+ view coordinates and scene coordinates, and to find items on the scene
+ using view coordinates.
+
+ \img graphicsview-view.png
+
+ \sa QGraphicsScene, QGraphicsItem, QGraphicsSceneEvent
+*/
+
+/*!
+ \enum QGraphicsView::ViewportAnchor
+
+ This enums describe the possible anchors that QGraphicsView can
+ use when the user resizes the view or when the view is
+ transformed.
+
+ \value NoAnchor No anchor, i.e. the view leaves the scene's
+ position unchanged.
+ \value AnchorViewCenter The scene point at the center of the view
+ is used as the anchor.
+ \value AnchorUnderMouse The point under the mouse is used as the anchor.
+
+ \sa resizeAnchor, transformationAnchor
+*/
+
+/*!
+ \enum QGraphicsView::ViewportUpdateMode
+
+ \since 4.3
+
+ This enum describes how QGraphicsView updates its viewport when the scene
+ contents change or are exposed.
+
+ \value FullViewportUpdate When any visible part of the scene changes or is
+ reexposed, QGraphicsView will update the entire viewport. This approach is
+ fastest when QGraphicsView spends more time figuring out what to draw than
+ it would spend drawing (e.g., when very many small items are repeatedly
+ updated). This is the preferred update mode for viewports that do not
+ support partial updates, such as QGLWidget, and for viewports that need to
+ disable scroll optimization.
+
+ \value MinimalViewportUpdate QGraphicsView will determine the minimal
+ viewport region that requires a redraw, minimizing the time spent drawing
+ by avoiding a redraw of areas that have not changed. This is
+ QGraphicsView's default mode. Although this approach provides the best
+ performance in general, if there are many small visible changes on the
+ scene, QGraphicsView might end up spending more time finding the minimal
+ approach than it will spend drawing.
+
+ \value SmartViewportUpdate QGraphicsView will attempt to find an optimal
+ update mode by analyzing the areas that require a redraw.
+
+ \value BoundingRectViewportUpdate The bounding rectangle of all changes in
+ the viewport will be redrawn. This mode has the advantage that
+ QGraphicsView searches only one region for changes, minimizing time spent
+ determining what needs redrawing. The disadvantage is that areas that have
+ not changed also need to be redrawn.
+
+ \value NoViewportUpdate QGraphicsView will never update its viewport when
+ the scene changes; the user is expected to control all updates. This mode
+ disables all (potentially slow) item visibility testing in QGraphicsView,
+ and is suitable for scenes that either require a fixed frame rate, or where
+ the viewport is otherwise updated externally.
+
+ \sa viewportUpdateMode
+*/
+
+/*!
+ \enum QGraphicsView::OptimizationFlag
+
+ \since 4.3
+
+ This enum describes flags that you can enable to improve rendering
+ performance in QGraphicsView. By default, none of these flags are set.
+ Note that setting a flag usually imposes a side effect, and this effect
+ can vary between paint devices and platforms.
+
+ \value DontClipPainter This value is obsolete and has no effect.
+
+ \value DontSavePainterState When rendering, QGraphicsView protects the
+ painter state (see QPainter::save()) when rendering the background or
+ foreground, and when rendering each item. This allows you to leave the
+ painter in an altered state (i.e., you can call QPainter::setPen() or
+ QPainter::setBrush() without restoring the state after painting). However,
+ if the items consistently do restore the state, you should enable this
+ flag to prevent QGraphicsView from doing the same.
+
+ \value DontAdjustForAntialiasing Disables QGraphicsView's antialiasing
+ auto-adjustment of exposed areas. Items that render antialiased lines on
+ the boundaries of their QGraphicsItem::boundingRect() can end up rendering
+ parts of the line outside. To prevent rendering artifacts, QGraphicsView
+ expands all exposed regions by 2 pixels in all directions. If you enable
+ this flag, QGraphicsView will no longer perform these adjustments,
+ minimizing the areas that require redrawing, which improves performance. A
+ common side effect is that items that do draw with antialiasing can leave
+ painting traces behind on the scene as they are moved.
+
+ \value IndirectPainting Since Qt 4.6, restore the old painting algorithm
+ that calls QGraphicsView::drawItems() and QGraphicsScene::drawItems().
+ To be used only for compatibility with old code.
+*/
+
+/*!
+ \enum QGraphicsView::CacheModeFlag
+
+ This enum describes the flags that you can set for a QGraphicsView's cache
+ mode.
+
+ \value CacheNone All painting is done directly onto the viewport.
+
+ \value CacheBackground The background is cached. This affects both custom
+ backgrounds, and backgrounds based on the backgroundBrush property. When
+ this flag is enabled, QGraphicsView will allocate one pixmap with the full
+ size of the viewport.
+
+ \sa cacheMode
+*/
+
+/*!
+ \enum QGraphicsView::DragMode
+
+ This enum describes the default action for the view when pressing and
+ dragging the mouse over the viewport.
+
+ \value NoDrag Nothing happens; the mouse event is ignored.
+
+ \value ScrollHandDrag The cursor changes into a pointing hand, and
+ dragging the mouse around will scroll the scrolbars. This mode works both
+ in \l{QGraphicsView::interactive}{interactive} and non-interactive mode.
+
+ \value RubberBandDrag A rubber band will appear. Dragging the mouse will
+ set the rubber band geometry, and all items covered by the rubber band are
+ selected. This mode is disabled for non-interactive views.
+
+ \sa dragMode, QGraphicsScene::setSelectionArea()
+*/
+
+#include "qgraphicsview.h"
+#include "qgraphicsview_p.h"
+
+#ifndef QT_NO_GRAPHICSVIEW
+
+#include "qgraphicsitem.h"
+#include "qgraphicsitem_p.h"
+#include "qgraphicsscene.h"
+#include "qgraphicsscene_p.h"
+#include "qgraphicssceneevent.h"
+#include "qgraphicswidget.h"
+
+#include <QtCore/qdatetime.h>
+#include <QtCore/qdebug.h>
+#include <QtCore/qmath.h>
+#include <QtWidgets/qapplication.h>
+#include <QtWidgets/qdesktopwidget.h>
+#include <QtGui/qevent.h>
+#include <QtWidgets/qlayout.h>
+#include <QtGui/qtransform.h>
+#include <QtGui/qmatrix.h>
+#include <QtGui/qpainter.h>
+#include <QtWidgets/qscrollbar.h>
+#include <QtWidgets/qstyleoption.h>
+#include <QtWidgets/qinputcontext.h>
+#ifdef Q_WS_X11
+#include <QtGui/qpaintengine.h>
+#include <private/qt_x11_p.h>
+#endif
+
+#include <private/qevent_p.h>
+
+QT_BEGIN_NAMESPACE
+
+bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event);
+
+inline int q_round_bound(qreal d) //### (int)(qreal) INT_MAX != INT_MAX for single precision
+{
+ if (d <= (qreal) INT_MIN)
+ return INT_MIN;
+ else if (d >= (qreal) INT_MAX)
+ return INT_MAX;
+ return d >= 0.0 ? int(d + 0.5) : int(d - int(d-1) + 0.5) + int(d-1);
+}
+
+void QGraphicsViewPrivate::translateTouchEvent(QGraphicsViewPrivate *d, QTouchEvent *touchEvent)
+{
+ QList<QTouchEvent::TouchPoint> touchPoints = touchEvent->touchPoints();
+ for (int i = 0; i < touchPoints.count(); ++i) {
+ QTouchEvent::TouchPoint &touchPoint = touchPoints[i];
+ // the scene will set the item local pos, startPos, lastPos, and rect before delivering to
+ // an item, but for now those functions are returning the view's local coordinates
+ touchPoint.setSceneRect(d->mapToScene(touchPoint.rect()));
+ touchPoint.setStartScenePos(d->mapToScene(touchPoint.startPos()));
+ touchPoint.setLastScenePos(d->mapToScene(touchPoint.lastPos()));
+
+ // screenPos, startScreenPos, lastScreenPos, and screenRect are already set
+ }
+
+ touchEvent->setTouchPoints(touchPoints);
+}
+
+/*!
+ \internal
+*/
+QGraphicsViewPrivate::QGraphicsViewPrivate()
+ : renderHints(QPainter::TextAntialiasing),
+ dragMode(QGraphicsView::NoDrag),
+ sceneInteractionAllowed(true), hasSceneRect(false),
+ connectedToScene(false),
+ useLastMouseEvent(false),
+ identityMatrix(true),
+ dirtyScroll(true),
+ accelerateScrolling(true),
+ keepLastCenterPoint(true),
+ transforming(false),
+ handScrolling(false),
+ mustAllocateStyleOptions(false),
+ mustResizeBackgroundPixmap(true),
+ fullUpdatePending(true),
+ hasUpdateClip(false),
+ mousePressButton(Qt::NoButton),
+ leftIndent(0), topIndent(0),
+ lastMouseEvent(QEvent::None, QPointF(), QPointF(), QPointF(), Qt::NoButton, 0, 0),
+ alignment(Qt::AlignCenter),
+ transformationAnchor(QGraphicsView::AnchorViewCenter), resizeAnchor(QGraphicsView::NoAnchor),
+ viewportUpdateMode(QGraphicsView::MinimalViewportUpdate),
+ optimizationFlags(0),
+ scene(0),
+#ifndef QT_NO_RUBBERBAND
+ rubberBanding(false),
+ rubberBandSelectionMode(Qt::IntersectsItemShape),
+#endif
+ handScrollMotions(0), cacheMode(0),
+#ifndef QT_NO_CURSOR
+ hasStoredOriginalCursor(false),
+#endif
+ lastDragDropEvent(0),
+ updateSceneSlotReimplementedChecked(false)
+{
+ styleOptions.reserve(QGRAPHICSVIEW_PREALLOC_STYLE_OPTIONS);
+}
+
+/*!
+ \internal
+*/
+void QGraphicsViewPrivate::recalculateContentSize()
+{
+ Q_Q(QGraphicsView);
+
+ QSize maxSize = q->maximumViewportSize();
+ int width = maxSize.width();
+ int height = maxSize.height();
+ QRectF viewRect = matrix.mapRect(q->sceneRect());
+
+ bool frameOnlyAround = (q->style()->styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents, 0, q));
+ if (frameOnlyAround) {
+ if (hbarpolicy == Qt::ScrollBarAlwaysOn)
+ height -= frameWidth * 2;
+ if (vbarpolicy == Qt::ScrollBarAlwaysOn)
+ width -= frameWidth * 2;
+ }
+
+ // Adjust the maximum width and height of the viewport based on the width
+ // of visible scroll bars.
+ int scrollBarExtent = q->style()->pixelMetric(QStyle::PM_ScrollBarExtent, 0, q);
+ if (frameOnlyAround)
+ scrollBarExtent += frameWidth * 2;
+
+ bool useHorizontalScrollBar = (viewRect.width() > width) && hbarpolicy != Qt::ScrollBarAlwaysOff;
+ bool useVerticalScrollBar = (viewRect.height() > height) && vbarpolicy != Qt::ScrollBarAlwaysOff;
+ if (useHorizontalScrollBar && !useVerticalScrollBar) {
+ if (viewRect.height() > height - scrollBarExtent)
+ useVerticalScrollBar = true;
+ }
+ if (useVerticalScrollBar && !useHorizontalScrollBar) {
+ if (viewRect.width() > width - scrollBarExtent)
+ useHorizontalScrollBar = true;
+ }
+ if (useHorizontalScrollBar && hbarpolicy != Qt::ScrollBarAlwaysOn)
+ height -= scrollBarExtent;
+ if (useVerticalScrollBar && vbarpolicy != Qt::ScrollBarAlwaysOn)
+ width -= scrollBarExtent;
+
+ // Setting the ranges of these scroll bars can/will cause the values to
+ // change, and scrollContentsBy() will be called correspondingly. This
+ // will reset the last center point.
+ QPointF savedLastCenterPoint = lastCenterPoint;
+
+ // Remember the former indent settings
+ qreal oldLeftIndent = leftIndent;
+ qreal oldTopIndent = topIndent;
+
+ // If the whole scene fits horizontally, we center the scene horizontally,
+ // and ignore the horizontal scroll bars.
+ int left = q_round_bound(viewRect.left());
+ int right = q_round_bound(viewRect.right() - width);
+ if (left >= right) {
+ hbar->setRange(0, 0);
+
+ switch (alignment & Qt::AlignHorizontal_Mask) {
+ case Qt::AlignLeft:
+ leftIndent = -viewRect.left();
+ break;
+ case Qt::AlignRight:
+ leftIndent = width - viewRect.width() - viewRect.left() - 1;
+ break;
+ case Qt::AlignHCenter:
+ default:
+ leftIndent = width / 2 - (viewRect.left() + viewRect.right()) / 2;
+ break;
+ }
+ } else {
+ hbar->setRange(left, right);
+ hbar->setPageStep(width);
+ hbar->setSingleStep(width / 20);
+ leftIndent = 0;
+ }
+
+ // If the whole scene fits vertically, we center the scene vertically, and
+ // ignore the vertical scroll bars.
+ int top = q_round_bound(viewRect.top());
+ int bottom = q_round_bound(viewRect.bottom() - height);
+ if (top >= bottom) {
+ vbar->setRange(0, 0);
+
+ switch (alignment & Qt::AlignVertical_Mask) {
+ case Qt::AlignTop:
+ topIndent = -viewRect.top();
+ break;
+ case Qt::AlignBottom:
+ topIndent = height - viewRect.height() - viewRect.top() - 1;
+ break;
+ case Qt::AlignVCenter:
+ default:
+ topIndent = height / 2 - (viewRect.top() + viewRect.bottom()) / 2;
+ break;
+ }
+ } else {
+ vbar->setRange(top, bottom);
+ vbar->setPageStep(height);
+ vbar->setSingleStep(height / 20);
+ topIndent = 0;
+ }
+
+ // Restorethe center point from before the ranges changed.
+ lastCenterPoint = savedLastCenterPoint;
+
+ // Issue a full update if the indents change.
+ // ### If the transform is still the same, we can get away with just a
+ // scroll instead.
+ if (oldLeftIndent != leftIndent || oldTopIndent != topIndent) {
+ dirtyScroll = true;
+ updateAll();
+ } else if (q->isRightToLeft() && !leftIndent) {
+ // In reverse mode, the horizontal scroll always changes after the content
+ // size has changed, as the scroll is calculated by summing the min and
+ // max values of the range and subtracting the current value. In normal
+ // mode the scroll remains unchanged unless the indent has changed.
+ dirtyScroll = true;
+ }
+
+ if (cacheMode & QGraphicsView::CacheBackground) {
+ // Invalidate the background pixmap
+ mustResizeBackgroundPixmap = true;
+ }
+}
+
+/*!
+ \internal
+*/
+void QGraphicsViewPrivate::centerView(QGraphicsView::ViewportAnchor anchor)
+{
+ Q_Q(QGraphicsView);
+ switch (anchor) {
+ case QGraphicsView::AnchorUnderMouse: {
+ if (q->underMouse()) {
+ // Last scene pos: lastMouseMoveScenePoint
+ // Current mouse pos:
+ QPointF transformationDiff = q->mapToScene(viewport->rect().center())
+ - q->mapToScene(viewport->mapFromGlobal(QCursor::pos()));
+ q->centerOn(lastMouseMoveScenePoint + transformationDiff);
+ } else {
+ q->centerOn(lastCenterPoint);
+ }
+ break;
+ }
+ case QGraphicsView::AnchorViewCenter:
+ q->centerOn(lastCenterPoint);
+ break;
+ case QGraphicsView::NoAnchor:
+ break;
+ }
+}
+
+/*!
+ \internal
+*/
+void QGraphicsViewPrivate::updateLastCenterPoint()
+{
+ Q_Q(QGraphicsView);
+ lastCenterPoint = q->mapToScene(viewport->rect().center());
+}
+
+/*!
+ \internal
+
+ Returns the horizontal scroll value (the X value of the left edge of the
+ viewport).
+*/
+qint64 QGraphicsViewPrivate::horizontalScroll() const
+{
+ if (dirtyScroll)
+ const_cast<QGraphicsViewPrivate *>(this)->updateScroll();
+ return scrollX;
+}
+
+/*!
+ \internal
+
+ Returns the vertical scroll value (the X value of the top edge of the
+ viewport).
+*/
+qint64 QGraphicsViewPrivate::verticalScroll() const
+{
+ if (dirtyScroll)
+ const_cast<QGraphicsViewPrivate *>(this)->updateScroll();
+ return scrollY;
+}
+
+/*!
+ \internal
+
+ Maps the given rectangle to the scene using QTransform::mapRect()
+*/
+QRectF QGraphicsViewPrivate::mapRectToScene(const QRect &rect) const
+{
+ if (dirtyScroll)
+ const_cast<QGraphicsViewPrivate *>(this)->updateScroll();
+ QRectF scrolled = QRectF(rect.translated(scrollX, scrollY));
+ return identityMatrix ? scrolled : matrix.inverted().mapRect(scrolled);
+}
+
+
+/*!
+ \internal
+
+ Maps the given rectangle from the scene using QTransform::mapRect()
+*/
+QRectF QGraphicsViewPrivate::mapRectFromScene(const QRectF &rect) const
+{
+ if (dirtyScroll)
+ const_cast<QGraphicsViewPrivate *>(this)->updateScroll();
+ return (identityMatrix ? rect : matrix.mapRect(rect)).translated(-scrollX, -scrollY);
+}
+
+/*!
+ \internal
+*/
+void QGraphicsViewPrivate::updateScroll()
+{
+ Q_Q(QGraphicsView);
+ scrollX = qint64(-leftIndent);
+ if (q->isRightToLeft()) {
+ if (!leftIndent) {
+ scrollX += hbar->minimum();
+ scrollX += hbar->maximum();
+ scrollX -= hbar->value();
+ }
+ } else {
+ scrollX += hbar->value();
+ }
+
+ scrollY = qint64(vbar->value() - topIndent);
+
+ dirtyScroll = false;
+}
+
+/*!
+ \internal
+*/
+void QGraphicsViewPrivate::replayLastMouseEvent()
+{
+ if (!useLastMouseEvent || !scene)
+ return;
+ mouseMoveEventHandler(&lastMouseEvent);
+}
+
+/*!
+ \internal
+*/
+void QGraphicsViewPrivate::storeMouseEvent(QMouseEvent *event)
+{
+ useLastMouseEvent = true;
+ lastMouseEvent = QMouseEvent(QEvent::MouseMove, event->localPos(), event->windowPos(), event->screenPos(),
+ event->button(), event->buttons(), event->modifiers());
+}
+
+void QGraphicsViewPrivate::mouseMoveEventHandler(QMouseEvent *event)
+{
+ Q_Q(QGraphicsView);
+
+ storeMouseEvent(event);
+ lastMouseEvent.setAccepted(false);
+
+ if (!sceneInteractionAllowed)
+ return;
+ if (handScrolling)
+ return;
+ if (!scene)
+ return;
+
+ QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMouseMove);
+ mouseEvent.setWidget(viewport);
+ mouseEvent.setButtonDownScenePos(mousePressButton, mousePressScenePoint);
+ mouseEvent.setButtonDownScreenPos(mousePressButton, mousePressScreenPoint);
+ mouseEvent.setScenePos(q->mapToScene(event->pos()));
+ mouseEvent.setScreenPos(event->globalPos());
+ mouseEvent.setLastScenePos(lastMouseMoveScenePoint);
+ mouseEvent.setLastScreenPos(lastMouseMoveScreenPoint);
+ mouseEvent.setButtons(event->buttons());
+ mouseEvent.setButton(event->button());
+ mouseEvent.setModifiers(event->modifiers());
+ lastMouseMoveScenePoint = mouseEvent.scenePos();
+ lastMouseMoveScreenPoint = mouseEvent.screenPos();
+ mouseEvent.setAccepted(false);
+ if (event->spontaneous())
+ qt_sendSpontaneousEvent(scene, &mouseEvent);
+ else
+ QApplication::sendEvent(scene, &mouseEvent);
+
+ // Remember whether the last event was accepted or not.
+ lastMouseEvent.setAccepted(mouseEvent.isAccepted());
+
+ if (mouseEvent.isAccepted() && mouseEvent.buttons() != 0) {
+ // The event was delivered to a mouse grabber; the press is likely to
+ // have set a cursor, and we must not change it.
+ return;
+ }
+
+#ifndef QT_NO_CURSOR
+ // If all the items ignore hover events, we don't look-up any items
+ // in QGraphicsScenePrivate::dispatchHoverEvent, hence the
+ // cachedItemsUnderMouse list will be empty. We therefore do the look-up
+ // for cursor items here if not all items use the default cursor.
+ if (scene->d_func()->allItemsIgnoreHoverEvents && !scene->d_func()->allItemsUseDefaultCursor
+ && scene->d_func()->cachedItemsUnderMouse.isEmpty()) {
+ scene->d_func()->cachedItemsUnderMouse = scene->d_func()->itemsAtPosition(mouseEvent.screenPos(),
+ mouseEvent.scenePos(),
+ mouseEvent.widget());
+ }
+ // Find the topmost item under the mouse with a cursor.
+ foreach (QGraphicsItem *item, scene->d_func()->cachedItemsUnderMouse) {
+ if (item->hasCursor()) {
+ _q_setViewportCursor(item->cursor());
+ return;
+ }
+ }
+
+ // No items with cursors found; revert to the view cursor.
+ if (hasStoredOriginalCursor) {
+ // Restore the original viewport cursor.
+ hasStoredOriginalCursor = false;
+ viewport->setCursor(originalCursor);
+ }
+#endif
+}
+
+/*!
+ \internal
+*/
+#ifndef QT_NO_RUBBERBAND
+QRegion QGraphicsViewPrivate::rubberBandRegion(const QWidget *widget, const QRect &rect) const
+{
+ QStyleHintReturnMask mask;
+ QStyleOptionRubberBand option;
+ option.initFrom(widget);
+ option.rect = rect;
+ option.opaque = false;
+ option.shape = QRubberBand::Rectangle;
+
+ QRegion tmp;
+ tmp += rect;
+ if (widget->style()->styleHint(QStyle::SH_RubberBand_Mask, &option, widget, &mask))
+ tmp &= mask.region;
+ return tmp;
+}
+#endif
+
+/*!
+ \internal
+*/
+#ifndef QT_NO_CURSOR
+void QGraphicsViewPrivate::_q_setViewportCursor(const QCursor &cursor)
+{
+ if (!hasStoredOriginalCursor) {
+ hasStoredOriginalCursor = true;
+ originalCursor = viewport->cursor();
+ }
+ viewport->setCursor(cursor);
+}
+#endif
+
+/*!
+ \internal
+*/
+#ifndef QT_NO_CURSOR
+void QGraphicsViewPrivate::_q_unsetViewportCursor()
+{
+ Q_Q(QGraphicsView);
+ foreach (QGraphicsItem *item, q->items(lastMouseEvent.pos())) {
+ if (item->hasCursor()) {
+ _q_setViewportCursor(item->cursor());
+ return;
+ }
+ }
+
+ // Restore the original viewport cursor.
+ if (hasStoredOriginalCursor) {
+ hasStoredOriginalCursor = false;
+ if (dragMode == QGraphicsView::ScrollHandDrag)
+ viewport->setCursor(Qt::OpenHandCursor);
+ else
+ viewport->setCursor(originalCursor);
+ }
+}
+#endif
+
+/*!
+ \internal
+*/
+void QGraphicsViewPrivate::storeDragDropEvent(const QGraphicsSceneDragDropEvent *event)
+{
+ delete lastDragDropEvent;
+ lastDragDropEvent = new QGraphicsSceneDragDropEvent(event->type());
+ lastDragDropEvent->setScenePos(event->scenePos());
+ lastDragDropEvent->setScreenPos(event->screenPos());
+ lastDragDropEvent->setButtons(event->buttons());
+ lastDragDropEvent->setModifiers(event->modifiers());
+ lastDragDropEvent->setPossibleActions(event->possibleActions());
+ lastDragDropEvent->setProposedAction(event->proposedAction());
+ lastDragDropEvent->setDropAction(event->dropAction());
+ lastDragDropEvent->setMimeData(event->mimeData());
+ lastDragDropEvent->setWidget(event->widget());
+ lastDragDropEvent->setSource(event->source());
+}
+
+/*!
+ \internal
+*/
+void QGraphicsViewPrivate::populateSceneDragDropEvent(QGraphicsSceneDragDropEvent *dest,
+ QDropEvent *source)
+{
+#ifndef QT_NO_DRAGANDDROP
+ Q_Q(QGraphicsView);
+ dest->setScenePos(q->mapToScene(source->pos()));
+ dest->setScreenPos(q->mapToGlobal(source->pos()));
+ dest->setButtons(source->mouseButtons());
+ dest->setModifiers(source->keyboardModifiers());
+ dest->setPossibleActions(source->possibleActions());
+ dest->setProposedAction(source->proposedAction());
+ dest->setDropAction(source->dropAction());
+ dest->setMimeData(source->mimeData());
+ dest->setWidget(viewport);
+ dest->setSource(qobject_cast<QWidget *>(source->source()));
+#else
+ Q_UNUSED(dest)
+ Q_UNUSED(source)
+#endif
+}
+
+/*!
+ \internal
+*/
+QRect QGraphicsViewPrivate::mapToViewRect(const QGraphicsItem *item, const QRectF &rect) const
+{
+ Q_Q(const QGraphicsView);
+ if (dirtyScroll)
+ const_cast<QGraphicsViewPrivate *>(this)->updateScroll();
+
+ if (item->d_ptr->itemIsUntransformable()) {
+ QTransform itv = item->deviceTransform(q->viewportTransform());
+ return itv.mapRect(rect).toAlignedRect();
+ }
+
+ // Translate-only
+ // COMBINE
+ QPointF offset;
+ const QGraphicsItem *parentItem = item;
+ const QGraphicsItemPrivate *itemd;
+ do {
+ itemd = parentItem->d_ptr.data();
+ if (itemd->transformData)
+ break;
+ offset += itemd->pos;
+ } while ((parentItem = itemd->parent));
+
+ QRectF baseRect = rect.translated(offset.x(), offset.y());
+ if (!parentItem) {
+ if (identityMatrix) {
+ baseRect.translate(-scrollX, -scrollY);
+ return baseRect.toAlignedRect();
+ }
+ return matrix.mapRect(baseRect).translated(-scrollX, -scrollY).toAlignedRect();
+ }
+
+ QTransform tr = parentItem->sceneTransform();
+ if (!identityMatrix)
+ tr *= matrix;
+ QRectF r = tr.mapRect(baseRect);
+ r.translate(-scrollX, -scrollY);
+ return r.toAlignedRect();
+}
+
+/*!
+ \internal
+*/
+QRegion QGraphicsViewPrivate::mapToViewRegion(const QGraphicsItem *item, const QRectF &rect) const
+{
+ Q_Q(const QGraphicsView);
+ if (dirtyScroll)
+ const_cast<QGraphicsViewPrivate *>(this)->updateScroll();
+
+ // Accurate bounding region
+ QTransform itv = item->deviceTransform(q->viewportTransform());
+ return item->boundingRegion(itv) & itv.mapRect(rect).toAlignedRect();
+}
+
+/*!
+ \internal
+*/
+void QGraphicsViewPrivate::processPendingUpdates()
+{
+ if (!scene)
+ return;
+
+ if (fullUpdatePending) {
+ viewport->update();
+ } else if (viewportUpdateMode == QGraphicsView::BoundingRectViewportUpdate) {
+ viewport->update(dirtyBoundingRect);
+ } else {
+ viewport->update(dirtyRegion); // Already adjusted in updateRect/Region.
+ }
+
+ dirtyBoundingRect = QRect();
+ dirtyRegion = QRegion();
+}
+
+static inline bool intersectsViewport(const QRect &r, int width, int height)
+{ return !(r.left() > width) && !(r.right() < 0) && !(r.top() >= height) && !(r.bottom() < 0); }
+
+static inline bool containsViewport(const QRect &r, int width, int height)
+{ return r.left() <= 0 && r.top() <= 0 && r.right() >= width - 1 && r.bottom() >= height - 1; }
+
+static inline void QRect_unite(QRect *rect, const QRect &other)
+{
+ if (rect->isEmpty()) {
+ *rect = other;
+ } else {
+ rect->setCoords(qMin(rect->left(), other.left()), qMin(rect->top(), other.top()),
+ qMax(rect->right(), other.right()), qMax(rect->bottom(), other.bottom()));
+ }
+}
+
+/*
+ Calling this function results in update rects being clipped to the item's
+ bounding rect. Note that updates prior to this function call is not clipped.
+ The clip is removed by passing 0.
+*/
+void QGraphicsViewPrivate::setUpdateClip(QGraphicsItem *item)
+{
+ Q_Q(QGraphicsView);
+ // We simply ignore the request if the update mode is either FullViewportUpdate
+ // or NoViewportUpdate; in that case there's no point in clipping anything.
+ if (!item || viewportUpdateMode == QGraphicsView::NoViewportUpdate
+ || viewportUpdateMode == QGraphicsView::FullViewportUpdate) {
+ hasUpdateClip = false;
+ return;
+ }
+
+ // Calculate the clip (item's bounding rect in view coordinates).
+ // Optimized version of:
+ // QRect clip = item->deviceTransform(q->viewportTransform())
+ // .mapRect(item->boundingRect()).toAlignedRect();
+ QRect clip;
+ if (item->d_ptr->itemIsUntransformable()) {
+ QTransform xform = item->deviceTransform(q->viewportTransform());
+ clip = xform.mapRect(item->boundingRect()).toAlignedRect();
+ } else if (item->d_ptr->sceneTransformTranslateOnly && identityMatrix) {
+ QRectF r(item->boundingRect());
+ r.translate(item->d_ptr->sceneTransform.dx() - horizontalScroll(),
+ item->d_ptr->sceneTransform.dy() - verticalScroll());
+ clip = r.toAlignedRect();
+ } else if (!q->isTransformed()) {
+ clip = item->d_ptr->sceneTransform.mapRect(item->boundingRect()).toAlignedRect();
+ } else {
+ QTransform xform = item->d_ptr->sceneTransform;
+ xform *= q->viewportTransform();
+ clip = xform.mapRect(item->boundingRect()).toAlignedRect();
+ }
+
+ if (hasUpdateClip) {
+ // Intersect with old clip.
+ updateClip &= clip;
+ } else {
+ updateClip = clip;
+ hasUpdateClip = true;
+ }
+}
+
+bool QGraphicsViewPrivate::updateRegion(const QRectF &rect, const QTransform &xform)
+{
+ if (rect.isEmpty())
+ return false;
+
+ if (viewportUpdateMode != QGraphicsView::MinimalViewportUpdate
+ && viewportUpdateMode != QGraphicsView::SmartViewportUpdate) {
+ // No point in updating with QRegion granularity; use the rect instead.
+ return updateRectF(xform.mapRect(rect));
+ }
+
+ // Update mode is either Minimal or Smart, so we have to do a potentially slow operation,
+ // which is clearly documented here: QGraphicsItem::setBoundingRegionGranularity.
+ const QRegion region = xform.map(QRegion(rect.toAlignedRect()));
+ QRect viewRect = region.boundingRect();
+ const bool dontAdjustForAntialiasing = optimizationFlags & QGraphicsView::DontAdjustForAntialiasing;
+ if (dontAdjustForAntialiasing)
+ viewRect.adjust(-1, -1, 1, 1);
+ else
+ viewRect.adjust(-2, -2, 2, 2);
+ if (!intersectsViewport(viewRect, viewport->width(), viewport->height()))
+ return false; // Update region for sure outside viewport.
+
+ const QVector<QRect> &rects = region.rects();
+ for (int i = 0; i < rects.size(); ++i) {
+ viewRect = rects.at(i);
+ if (dontAdjustForAntialiasing)
+ viewRect.adjust(-1, -1, 1, 1);
+ else
+ viewRect.adjust(-2, -2, 2, 2);
+ if (hasUpdateClip)
+ viewRect &= updateClip;
+ dirtyRegion += viewRect;
+ }
+
+ return true;
+}
+
+// NB! Assumes the rect 'r' is already aligned and adjusted for antialiasing.
+// For QRectF use updateRectF(const QRectF &) to ensure proper adjustments.
+bool QGraphicsViewPrivate::updateRect(const QRect &r)
+{
+ if (fullUpdatePending || viewportUpdateMode == QGraphicsView::NoViewportUpdate
+ || !intersectsViewport(r, viewport->width(), viewport->height())) {
+ return false;
+ }
+
+ switch (viewportUpdateMode) {
+ case QGraphicsView::FullViewportUpdate:
+ fullUpdatePending = true;
+ viewport->update();
+ break;
+ case QGraphicsView::BoundingRectViewportUpdate:
+ if (hasUpdateClip)
+ QRect_unite(&dirtyBoundingRect, r & updateClip);
+ else
+ QRect_unite(&dirtyBoundingRect, r);
+ if (containsViewport(dirtyBoundingRect, viewport->width(), viewport->height())) {
+ fullUpdatePending = true;
+ viewport->update();
+ }
+ break;
+ case QGraphicsView::SmartViewportUpdate: // ### DEPRECATE
+ case QGraphicsView::MinimalViewportUpdate:
+ if (hasUpdateClip)
+ dirtyRegion += r & updateClip;
+ else
+ dirtyRegion += r;
+ break;
+ default:
+ break;
+ }
+
+ return true;
+}
+
+QStyleOptionGraphicsItem *QGraphicsViewPrivate::allocStyleOptionsArray(int numItems)
+{
+ if (mustAllocateStyleOptions || (numItems > styleOptions.capacity()))
+ // too many items, let's allocate on-the-fly
+ return new QStyleOptionGraphicsItem[numItems];
+
+ // expand only whenever necessary
+ if (numItems > styleOptions.size())
+ styleOptions.resize(numItems);
+
+ mustAllocateStyleOptions = true;
+ return styleOptions.data();
+}
+
+void QGraphicsViewPrivate::freeStyleOptionsArray(QStyleOptionGraphicsItem *array)
+{
+ mustAllocateStyleOptions = false;
+ if (array != styleOptions.data())
+ delete [] array;
+}
+
+extern QPainterPath qt_regionToPath(const QRegion &region);
+
+/*!
+ ### 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 QTransform &viewTransform) const
+{
+ Q_Q(const QGraphicsView);
+
+ // Step 1) If all items are contained within the expose region, then
+ // return a list of all visible items. ### the scene's growing bounding
+ // rect does not take into account untransformable items.
+ const QRectF exposedRegionSceneBounds = q->mapToScene(exposedRegion.boundingRect().adjusted(-1, -1, 1, 1))
+ .boundingRect();
+ if (exposedRegionSceneBounds.contains(scene->sceneRect())) {
+ Q_ASSERT(allItems);
+ *allItems = true;
+
+ // All items are guaranteed within the exposed region.
+ return scene->items(Qt::AscendingOrder);
+ }
+
+ // 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 = exposedRegion.rectCount() == 1 && matrix.type() <= QTransform::TxScale;
+ if (simpleRectLookup) {
+ return scene->items(exposedRegionSceneBounds,
+ Qt::IntersectsItemBoundingRect,
+ Qt::AscendingOrder, viewTransform);
+ }
+
+ // 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 exposedScenePath(q->mapToScene(qt_regionToPath(adjustedRegion)));
+ return scene->items(exposedScenePath, Qt::IntersectsItemBoundingRect,
+ Qt::AscendingOrder, viewTransform);
+}
+
+/*!
+ \internal
+
+ Enables input methods for the view if and only if the current focus item of
+ the scene accepts input methods. Call function whenever that condition has
+ potentially changed.
+*/
+void QGraphicsViewPrivate::updateInputMethodSensitivity()
+{
+ Q_Q(QGraphicsView);
+ QGraphicsItem *focusItem = 0;
+ bool enabled = scene && (focusItem = scene->focusItem())
+ && (focusItem->d_ptr->flags & QGraphicsItem::ItemAcceptsInputMethod);
+ q->setAttribute(Qt::WA_InputMethodEnabled, enabled);
+ q->viewport()->setAttribute(Qt::WA_InputMethodEnabled, enabled);
+
+ if (!enabled) {
+ q->setInputMethodHints(0);
+ return;
+ }
+
+ QGraphicsProxyWidget *proxy = focusItem->d_ptr->isWidget && focusItem->d_ptr->isProxyWidget()
+ ? static_cast<QGraphicsProxyWidget *>(focusItem) : 0;
+ if (!proxy) {
+ q->setInputMethodHints(focusItem->inputMethodHints());
+ } else if (QWidget *widget = proxy->widget()) {
+ if (QWidget *fw = widget->focusWidget())
+ widget = fw;
+ q->setInputMethodHints(widget->inputMethodHints());
+ } else {
+ q->setInputMethodHints(0);
+ }
+}
+
+/*!
+ Constructs a QGraphicsView. \a parent is passed to QWidget's constructor.
+*/
+QGraphicsView::QGraphicsView(QWidget *parent)
+ : QAbstractScrollArea(*new QGraphicsViewPrivate, parent)
+{
+ setViewport(0);
+ setAcceptDrops(true);
+ setBackgroundRole(QPalette::Base);
+ // Investigate leaving these disabled by default.
+ setAttribute(Qt::WA_InputMethodEnabled);
+ viewport()->setAttribute(Qt::WA_InputMethodEnabled);
+}
+
+/*!
+ Constructs a QGraphicsView and sets the visualized scene to \a
+ scene. \a parent is passed to QWidget's constructor.
+*/
+QGraphicsView::QGraphicsView(QGraphicsScene *scene, QWidget *parent)
+ : QAbstractScrollArea(*new QGraphicsViewPrivate, parent)
+{
+ setScene(scene);
+ setViewport(0);
+ setAcceptDrops(true);
+ setBackgroundRole(QPalette::Base);
+ // Investigate leaving these disabled by default.
+ setAttribute(Qt::WA_InputMethodEnabled);
+ viewport()->setAttribute(Qt::WA_InputMethodEnabled);
+}
+
+/*!
+ \internal
+ */
+QGraphicsView::QGraphicsView(QGraphicsViewPrivate &dd, QWidget *parent)
+ : QAbstractScrollArea(dd, parent)
+{
+ setViewport(0);
+ setAcceptDrops(true);
+ setBackgroundRole(QPalette::Base);
+ // Investigate leaving these disabled by default.
+ setAttribute(Qt::WA_InputMethodEnabled);
+ viewport()->setAttribute(Qt::WA_InputMethodEnabled);
+}
+
+/*!
+ Destructs the QGraphicsView object.
+*/
+QGraphicsView::~QGraphicsView()
+{
+ Q_D(QGraphicsView);
+ if (d->scene)
+ d->scene->d_func()->views.removeAll(this);
+ delete d->lastDragDropEvent;
+}
+
+/*!
+ \reimp
+*/
+QSize QGraphicsView::sizeHint() const
+{
+ Q_D(const QGraphicsView);
+ if (d->scene) {
+ QSizeF baseSize = d->matrix.mapRect(sceneRect()).size();
+ baseSize += QSizeF(d->frameWidth * 2, d->frameWidth * 2);
+ return baseSize.boundedTo((3 * QApplication::desktop()->size()) / 4).toSize();
+ }
+ return QAbstractScrollArea::sizeHint();
+}
+
+/*!
+ \property QGraphicsView::renderHints
+ \brief the default render hints for the view
+
+ These hints are
+ used to initialize QPainter before each visible item is drawn. QPainter
+ uses render hints to toggle rendering features such as antialiasing and
+ smooth pixmap transformation.
+
+ QPainter::TextAntialiasing is enabled by default.
+
+ Example:
+
+ \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsview.cpp 1
+*/
+QPainter::RenderHints QGraphicsView::renderHints() const
+{
+ Q_D(const QGraphicsView);
+ return d->renderHints;
+}
+void QGraphicsView::setRenderHints(QPainter::RenderHints hints)
+{
+ Q_D(QGraphicsView);
+ if (hints == d->renderHints)
+ return;
+ d->renderHints = hints;
+ d->updateAll();
+}
+
+/*!
+ If \a enabled is true, the render hint \a hint is enabled; otherwise it
+ is disabled.
+
+ \sa renderHints
+*/
+void QGraphicsView::setRenderHint(QPainter::RenderHint hint, bool enabled)
+{
+ Q_D(QGraphicsView);
+ QPainter::RenderHints oldHints = d->renderHints;
+ if (enabled)
+ d->renderHints |= hint;
+ else
+ d->renderHints &= ~hint;
+ if (oldHints != d->renderHints)
+ d->updateAll();
+}
+
+/*!
+ \property QGraphicsView::alignment
+ \brief the alignment of the scene in the view when the whole
+ scene is visible.
+
+ If the whole scene is visible in the view, (i.e., there are no visible
+ scroll bars,) the view's alignment will decide where the scene will be
+ rendered in the view. For example, if the alignment is Qt::AlignCenter,
+ which is default, the scene will be centered in the view, and if the
+ alignment is (Qt::AlignLeft | Qt::AlignTop), the scene will be rendered in
+ the top-left corner of the view.
+*/
+Qt::Alignment QGraphicsView::alignment() const
+{
+ Q_D(const QGraphicsView);
+ return d->alignment;
+}
+void QGraphicsView::setAlignment(Qt::Alignment alignment)
+{
+ Q_D(QGraphicsView);
+ if (d->alignment != alignment) {
+ d->alignment = alignment;
+ d->recalculateContentSize();
+ }
+}
+
+/*!
+ \property QGraphicsView::transformationAnchor
+ \brief how the view should position the scene during transformations.
+
+ QGraphicsView uses this property to decide how to position the scene in
+ the viewport when the transformation matrix changes, and the coordinate
+ system of the view is transformed. The default behavior, AnchorViewCenter,
+ ensures that the scene point at the center of the view remains unchanged
+ during transformations (e.g., when rotating, the scene will appear to
+ rotate around the center of the view).
+
+ Note that the effect of this property is noticeable when only a part of the
+ scene is visible (i.e., when there are scroll bars). Otherwise, if the
+ whole scene fits in the view, QGraphicsScene uses the view \l alignment to
+ position the scene in the view.
+
+ \sa alignment, resizeAnchor
+*/
+QGraphicsView::ViewportAnchor QGraphicsView::transformationAnchor() const
+{
+ Q_D(const QGraphicsView);
+ return d->transformationAnchor;
+}
+void QGraphicsView::setTransformationAnchor(ViewportAnchor anchor)
+{
+ Q_D(QGraphicsView);
+ d->transformationAnchor = anchor;
+
+ // Ensure mouse tracking is enabled in the case we are using AnchorUnderMouse
+ // in order to have up-to-date information for centering the view.
+ if (d->transformationAnchor == AnchorUnderMouse)
+ d->viewport->setMouseTracking(true);
+}
+
+/*!
+ \property QGraphicsView::resizeAnchor
+ \brief how the view should position the scene when the view is resized.
+
+ QGraphicsView uses this property to decide how to position the scene in
+ the viewport when the viewport widget's size changes. The default
+ behavior, NoAnchor, leaves the scene's position unchanged during a resize;
+ the top-left corner of the view will appear to be anchored while resizing.
+
+ Note that the effect of this property is noticeable when only a part of the
+ scene is visible (i.e., when there are scroll bars). Otherwise, if the
+ whole scene fits in the view, QGraphicsScene uses the view \l alignment to
+ position the scene in the view.
+
+ \sa alignment, transformationAnchor, Qt::WNorthWestGravity
+*/
+QGraphicsView::ViewportAnchor QGraphicsView::resizeAnchor() const
+{
+ Q_D(const QGraphicsView);
+ return d->resizeAnchor;
+}
+void QGraphicsView::setResizeAnchor(ViewportAnchor anchor)
+{
+ Q_D(QGraphicsView);
+ d->resizeAnchor = anchor;
+
+ // Ensure mouse tracking is enabled in the case we are using AnchorUnderMouse
+ // in order to have up-to-date information for centering the view.
+ if (d->resizeAnchor == AnchorUnderMouse)
+ d->viewport->setMouseTracking(true);
+}
+
+/*!
+ \property QGraphicsView::viewportUpdateMode
+ \brief how the viewport should update its contents.
+
+ \since 4.3
+
+ QGraphicsView uses this property to decide how to update areas of the
+ scene that have been reexposed or changed. Usually you do not need to
+ modify this property, but there are some cases where doing so can improve
+ rendering performance. See the ViewportUpdateMode documentation for
+ specific details.
+
+ The default value is MinimalViewportUpdate, where QGraphicsView will
+ update as small an area of the viewport as possible when the contents
+ change.
+
+ \sa ViewportUpdateMode, cacheMode
+*/
+QGraphicsView::ViewportUpdateMode QGraphicsView::viewportUpdateMode() const
+{
+ Q_D(const QGraphicsView);
+ return d->viewportUpdateMode;
+}
+void QGraphicsView::setViewportUpdateMode(ViewportUpdateMode mode)
+{
+ Q_D(QGraphicsView);
+ d->viewportUpdateMode = mode;
+}
+
+/*!
+ \property QGraphicsView::optimizationFlags
+ \brief flags that can be used to tune QGraphicsView's performance.
+
+ \since 4.3
+
+ QGraphicsView uses clipping, extra bounding rect adjustments, and certain
+ other aids to improve rendering quality and performance for the common
+ case graphics scene. However, depending on the target platform, the scene,
+ and the viewport in use, some of these operations can degrade performance.
+
+ The effect varies from flag to flag; see the OptimizationFlags
+ documentation for details.
+
+ By default, no optimization flags are enabled.
+
+ \sa setOptimizationFlag()
+*/
+QGraphicsView::OptimizationFlags QGraphicsView::optimizationFlags() const
+{
+ Q_D(const QGraphicsView);
+ return d->optimizationFlags;
+}
+void QGraphicsView::setOptimizationFlags(OptimizationFlags flags)
+{
+ Q_D(QGraphicsView);
+ d->optimizationFlags = flags;
+}
+
+/*!
+ Enables \a flag if \a enabled is true; otherwise disables \a flag.
+
+ \sa optimizationFlags
+*/
+void QGraphicsView::setOptimizationFlag(OptimizationFlag flag, bool enabled)
+{
+ Q_D(QGraphicsView);
+ if (enabled)
+ d->optimizationFlags |= flag;
+ else
+ d->optimizationFlags &= ~flag;
+}
+
+/*!
+ \property QGraphicsView::dragMode
+ \brief the behavior for dragging the mouse over the scene while
+ the left mouse button is pressed.
+
+ This property defines what should happen when the user clicks on the scene
+ background and drags the mouse (e.g., scrolling the viewport contents
+ using a pointing hand cursor, or selecting multiple items with a rubber
+ band). The default value, NoDrag, does nothing.
+
+ This behavior only affects mouse clicks that are not handled by any item.
+ You can define a custom behavior by creating a subclass of QGraphicsView
+ and reimplementing mouseMoveEvent().
+*/
+QGraphicsView::DragMode QGraphicsView::dragMode() const
+{
+ Q_D(const QGraphicsView);
+ return d->dragMode;
+}
+void QGraphicsView::setDragMode(DragMode mode)
+{
+ Q_D(QGraphicsView);
+ if (d->dragMode == mode)
+ return;
+
+#ifndef QT_NO_CURSOR
+ if (d->dragMode == ScrollHandDrag)
+ viewport()->unsetCursor();
+#endif
+
+ // If dragMode is unset while dragging, e.g. via a keyEvent, we
+ // don't unset the handScrolling state. When enabling scrolling
+ // again the mouseMoveEvent will automatically start scrolling,
+ // without a mousePress
+ if (d->dragMode == ScrollHandDrag && mode == NoDrag && d->handScrolling)
+ d->handScrolling = false;
+
+ d->dragMode = mode;
+
+#ifndef QT_NO_CURSOR
+ if (d->dragMode == ScrollHandDrag) {
+ // Forget the stored viewport cursor when we enter scroll hand drag mode.
+ d->hasStoredOriginalCursor = false;
+ viewport()->setCursor(Qt::OpenHandCursor);
+ }
+#endif
+}
+
+#ifndef QT_NO_RUBBERBAND
+/*!
+ \property QGraphicsView::rubberBandSelectionMode
+ \brief the behavior for selecting items with a rubber band selection rectangle.
+ \since 4.3
+
+ This property defines how items are selected when using the RubberBandDrag
+ drag mode.
+
+ The default value is Qt::IntersectsItemShape; all items whose shape
+ intersects with or is contained by the rubber band are selected.
+
+ \sa dragMode, items()
+*/
+Qt::ItemSelectionMode QGraphicsView::rubberBandSelectionMode() const
+{
+ Q_D(const QGraphicsView);
+ return d->rubberBandSelectionMode;
+}
+void QGraphicsView::setRubberBandSelectionMode(Qt::ItemSelectionMode mode)
+{
+ Q_D(QGraphicsView);
+ d->rubberBandSelectionMode = mode;
+}
+#endif
+
+/*!
+ \property QGraphicsView::cacheMode
+ \brief which parts of the view are cached
+
+ QGraphicsView can cache pre-rendered content in a QPixmap, which is then
+ drawn onto the viewport. The purpose of such caching is to speed up the
+ total rendering time for areas that are slow to render. Texture, gradient
+ and alpha blended backgrounds, for example, can be notibly slow to render;
+ especially with a transformed view. The CacheBackground flag enables
+ caching of the view's background. For example:
+
+ \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsview.cpp 2
+
+ The cache is invalidated every time the view is transformed. However, when
+ scrolling, only partial invalidation is required.
+
+ By default, nothing is cached.
+
+ \sa resetCachedContent(), QPixmapCache
+*/
+QGraphicsView::CacheMode QGraphicsView::cacheMode() const
+{
+ Q_D(const QGraphicsView);
+ return d->cacheMode;
+}
+void QGraphicsView::setCacheMode(CacheMode mode)
+{
+ Q_D(QGraphicsView);
+ if (mode == d->cacheMode)
+ return;
+ d->cacheMode = mode;
+ resetCachedContent();
+}
+
+/*!
+ Resets any cached content. Calling this function will clear
+ QGraphicsView's cache. If the current cache mode is \l CacheNone, this
+ function does nothing.
+
+ This function is called automatically for you when the backgroundBrush or
+ QGraphicsScene::backgroundBrush properties change; you only need to call
+ this function if you have reimplemented QGraphicsScene::drawBackground()
+ or QGraphicsView::drawBackground() to draw a custom background, and need
+ to trigger a full redraw.
+
+ \sa cacheMode()
+*/
+void QGraphicsView::resetCachedContent()
+{
+ Q_D(QGraphicsView);
+ if (d->cacheMode == CacheNone)
+ return;
+
+ if (d->cacheMode & CacheBackground) {
+ // Background caching is enabled.
+ d->mustResizeBackgroundPixmap = true;
+ d->updateAll();
+ } else if (d->mustResizeBackgroundPixmap) {
+ // Background caching is disabled.
+ // Cleanup, free some resources.
+ d->mustResizeBackgroundPixmap = false;
+ d->backgroundPixmap = QPixmap();
+ d->backgroundPixmapExposed = QRegion();
+ }
+}
+
+/*!
+ Invalidates and schedules a redraw of \a layers inside \a rect. \a rect is
+ in scene coordinates. Any cached content for \a layers inside \a rect is
+ unconditionally invalidated and redrawn.
+
+ You can call this function to notify QGraphicsView of changes to the
+ background or the foreground of the scene. It is commonly used for scenes
+ with tile-based backgrounds to notify changes when QGraphicsView has
+ enabled background caching.
+
+ Note that QGraphicsView currently supports background caching only (see
+ QGraphicsView::CacheBackground). This function is equivalent to calling update() if any
+ layer but QGraphicsScene::BackgroundLayer is passed.
+
+ \sa QGraphicsScene::invalidate(), update()
+*/
+void QGraphicsView::invalidateScene(const QRectF &rect, QGraphicsScene::SceneLayers layers)
+{
+ Q_D(QGraphicsView);
+ if ((layers & QGraphicsScene::BackgroundLayer) && !d->mustResizeBackgroundPixmap) {
+ QRect viewRect = mapFromScene(rect).boundingRect();
+ if (viewport()->rect().intersects(viewRect)) {
+ // The updated background area is exposed; schedule this area for
+ // redrawing.
+ d->backgroundPixmapExposed += viewRect;
+ if (d->scene)
+ d->scene->update(rect);
+ }
+ }
+}
+
+/*!
+ \property QGraphicsView::interactive
+ \brief whether the view allowed scene interaction.
+
+ If enabled, this view is set to allow scene interaction. Otherwise, this
+ view will not allow interaction, and any mouse or key events are ignored
+ (i.e., it will act as a read-only view).
+
+ By default, this property is true.
+*/
+bool QGraphicsView::isInteractive() const
+{
+ Q_D(const QGraphicsView);
+ return d->sceneInteractionAllowed;
+}
+void QGraphicsView::setInteractive(bool allowed)
+{
+ Q_D(QGraphicsView);
+ d->sceneInteractionAllowed = allowed;
+}
+
+/*!
+ Returns a pointer to the scene that is currently visualized in the
+ view. If no scene is currently visualized, 0 is returned.
+
+ \sa setScene()
+*/
+QGraphicsScene *QGraphicsView::scene() const
+{
+ Q_D(const QGraphicsView);
+ return d->scene;
+}
+
+/*!
+ Sets the current scene to \a scene. If \a scene is already being
+ viewed, this function does nothing.
+
+ When a scene is set on a view, the QGraphicsScene::changed() signal
+ is automatically connected to this view's updateScene() slot, and the
+ view's scroll bars are adjusted to fit the size of the scene.
+*/
+void QGraphicsView::setScene(QGraphicsScene *scene)
+{
+ Q_D(QGraphicsView);
+ if (d->scene == scene)
+ return;
+
+ // Always update the viewport when the scene changes.
+ d->updateAll();
+
+ // Remove the previously assigned scene.
+ if (d->scene) {
+ disconnect(d->scene, SIGNAL(changed(QList<QRectF>)),
+ this, SLOT(updateScene(QList<QRectF>)));
+ disconnect(d->scene, SIGNAL(sceneRectChanged(QRectF)),
+ this, SLOT(updateSceneRect(QRectF)));
+ d->scene->d_func()->removeView(this);
+ d->connectedToScene = false;
+
+ if (isActiveWindow() && isVisible()) {
+ QEvent windowDeactivate(QEvent::WindowDeactivate);
+ QApplication::sendEvent(d->scene, &windowDeactivate);
+ }
+ if(hasFocus())
+ d->scene->clearFocus();
+ }
+
+ // Assign the new scene and update the contents (scrollbars, etc.)).
+ if ((d->scene = scene)) {
+ connect(d->scene, SIGNAL(sceneRectChanged(QRectF)),
+ this, SLOT(updateSceneRect(QRectF)));
+ d->updateSceneSlotReimplementedChecked = false;
+ d->scene->d_func()->addView(this);
+ d->recalculateContentSize();
+ d->lastCenterPoint = sceneRect().center();
+ d->keepLastCenterPoint = true;
+ // We are only interested in mouse tracking if items accept
+ // hover events or use non-default cursors.
+ if (!d->scene->d_func()->allItemsIgnoreHoverEvents
+ || !d->scene->d_func()->allItemsUseDefaultCursor) {
+ d->viewport->setMouseTracking(true);
+ }
+
+ // enable touch events if any items is interested in them
+ if (!d->scene->d_func()->allItemsIgnoreTouchEvents)
+ d->viewport->setAttribute(Qt::WA_AcceptTouchEvents);
+
+ if (isActiveWindow() && isVisible()) {
+ QEvent windowActivate(QEvent::WindowActivate);
+ QApplication::sendEvent(d->scene, &windowActivate);
+ }
+ } else {
+ d->recalculateContentSize();
+ }
+
+ d->updateInputMethodSensitivity();
+
+ if (d->scene && hasFocus())
+ d->scene->setFocus();
+}
+
+/*!
+ \property QGraphicsView::sceneRect
+ \brief the area of the scene visualized by this view.
+
+ The scene rectangle defines the extent of the scene, and in the view's case,
+ this means the area of the scene that you can navigate using the scroll
+ bars.
+
+ If unset, or if a null QRectF is set, this property has the same value as
+ QGraphicsScene::sceneRect, and it changes with
+ QGraphicsScene::sceneRect. Otherwise, the view's scene rect is unaffected
+ by the scene.
+
+ Note that, although the scene supports a virtually unlimited size, the
+ range of the scroll bars will never exceed the range of an integer
+ (INT_MIN, INT_MAX). When the scene is larger than the scroll bars' values,
+ you can choose to use translate() to navigate the scene instead.
+
+ By default, this property contains a rectangle at the origin with zero
+ width and height.
+
+ \sa QGraphicsScene::sceneRect
+*/
+QRectF QGraphicsView::sceneRect() const
+{
+ Q_D(const QGraphicsView);
+ if (d->hasSceneRect)
+ return d->sceneRect;
+ if (d->scene)
+ return d->scene->sceneRect();
+ return QRectF();
+}
+void QGraphicsView::setSceneRect(const QRectF &rect)
+{
+ Q_D(QGraphicsView);
+ d->hasSceneRect = !rect.isNull();
+ d->sceneRect = rect;
+ d->recalculateContentSize();
+}
+
+/*!
+ Returns the current transformation matrix for the view. If no current
+ transformation is set, the identity matrix is returned.
+
+ \sa setMatrix(), transform(), rotate(), scale(), shear(), translate()
+*/
+QMatrix QGraphicsView::matrix() const
+{
+ Q_D(const QGraphicsView);
+ return d->matrix.toAffine();
+}
+
+/*!
+ Sets the view's current transformation matrix to \a matrix.
+
+ If \a combine is true, then \a matrix is combined with the current matrix;
+ otherwise, \a matrix \e replaces the current matrix. \a combine is false
+ by default.
+
+ The transformation matrix tranforms the scene into view coordinates. Using
+ the default transformation, provided by the identity matrix, one pixel in
+ the view represents one unit in the scene (e.g., a 10x10 rectangular item
+ is drawn using 10x10 pixels in the view). If a 2x2 scaling matrix is
+ applied, the scene will be drawn in 1:2 (e.g., a 10x10 rectangular item is
+ then drawn using 20x20 pixels in the view).
+
+ Example:
+
+ \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsview.cpp 3
+
+ To simplify interation with items using a transformed view, QGraphicsView
+ provides mapTo... and mapFrom... functions that can translate between
+ scene and view coordinates. For example, you can call mapToScene() to map
+ a view coordinate to a floating point scene coordinate, or mapFromScene()
+ to map from floating point scene coordinates to view coordinates.
+
+ \sa matrix(), setTransform(), rotate(), scale(), shear(), translate()
+*/
+void QGraphicsView::setMatrix(const QMatrix &matrix, bool combine)
+{
+ setTransform(QTransform(matrix), combine);
+}
+
+/*!
+ Resets the view transformation matrix to the identity matrix.
+
+ \sa resetTransform()
+*/
+void QGraphicsView::resetMatrix()
+{
+ resetTransform();
+}
+
+/*!
+ Rotates the current view transformation \a angle degrees clockwise.
+
+ \sa setTransform(), transform(), scale(), shear(), translate()
+*/
+void QGraphicsView::rotate(qreal angle)
+{
+ Q_D(QGraphicsView);
+ QTransform matrix = d->matrix;
+ matrix.rotate(angle);
+ setTransform(matrix);
+}
+
+/*!
+ Scales the current view transformation by (\a sx, \a sy).
+
+ \sa setTransform(), transform(), rotate(), shear(), translate()
+*/
+void QGraphicsView::scale(qreal sx, qreal sy)
+{
+ Q_D(QGraphicsView);
+ QTransform matrix = d->matrix;
+ matrix.scale(sx, sy);
+ setTransform(matrix);
+}
+
+/*!
+ Shears the current view transformation by (\a sh, \a sv).
+
+ \sa setTransform(), transform(), rotate(), scale(), translate()
+*/
+void QGraphicsView::shear(qreal sh, qreal sv)
+{
+ Q_D(QGraphicsView);
+ QTransform matrix = d->matrix;
+ matrix.shear(sh, sv);
+ setTransform(matrix);
+}
+
+/*!
+ Translates the current view transformation by (\a dx, \a dy).
+
+ \sa setTransform(), transform(), rotate(), shear()
+*/
+void QGraphicsView::translate(qreal dx, qreal dy)
+{
+ Q_D(QGraphicsView);
+ QTransform matrix = d->matrix;
+ matrix.translate(dx, dy);
+ setTransform(matrix);
+}
+
+/*!
+ Scrolls the contents of the viewport to ensure that the scene
+ coordinate \a pos, is centered in the view.
+
+ Because \a pos is a floating point coordinate, and the scroll bars operate
+ on integer coordinates, the centering is only an approximation.
+
+ \note If the item is close to or outside the border, it will be visible
+ in the view, but not centered.
+
+ \sa ensureVisible()
+*/
+void QGraphicsView::centerOn(const QPointF &pos)
+{
+ Q_D(QGraphicsView);
+ qreal width = viewport()->width();
+ qreal height = viewport()->height();
+ QPointF viewPoint = d->matrix.map(pos);
+ QPointF oldCenterPoint = pos;
+
+ if (!d->leftIndent) {
+ if (isRightToLeft()) {
+ qint64 horizontal = 0;
+ horizontal += horizontalScrollBar()->minimum();
+ horizontal += horizontalScrollBar()->maximum();
+ horizontal -= int(viewPoint.x() - width / 2.0);
+ horizontalScrollBar()->setValue(horizontal);
+ } else {
+ horizontalScrollBar()->setValue(int(viewPoint.x() - width / 2.0));
+ }
+ }
+ if (!d->topIndent)
+ verticalScrollBar()->setValue(int(viewPoint.y() - height / 2.0));
+ d->lastCenterPoint = oldCenterPoint;
+}
+
+/*!
+ \fn QGraphicsView::centerOn(qreal x, qreal y)
+ \overload
+
+ This function is provided for convenience. It's equivalent to calling
+ centerOn(QPointF(\a x, \a y)).
+*/
+
+/*!
+ \overload
+
+ Scrolls the contents of the viewport to ensure that \a item
+ is centered in the view.
+
+ \sa ensureVisible()
+*/
+void QGraphicsView::centerOn(const QGraphicsItem *item)
+{
+ centerOn(item->sceneBoundingRect().center());
+}
+
+/*!
+ Scrolls the contents of the viewport so that the scene rectangle \a rect
+ is visible, with margins specified in pixels by \a xmargin and \a
+ ymargin. If the specified rect cannot be reached, the contents are
+ scrolled to the nearest valid position. The default value for both margins
+ is 50 pixels.
+
+ \sa centerOn()
+*/
+void QGraphicsView::ensureVisible(const QRectF &rect, int xmargin, int ymargin)
+{
+ Q_D(QGraphicsView);
+ qreal width = viewport()->width();
+ qreal height = viewport()->height();
+ QRectF viewRect = d->matrix.mapRect(rect);
+
+ qreal left = d->horizontalScroll();
+ qreal right = left + width;
+ qreal top = d->verticalScroll();
+ qreal bottom = top + height;
+
+ if (viewRect.left() <= left + xmargin) {
+ // need to scroll from the left
+ if (!d->leftIndent)
+ horizontalScrollBar()->setValue(int(viewRect.left() - xmargin - 0.5));
+ }
+ if (viewRect.right() >= right - xmargin) {
+ // need to scroll from the right
+ if (!d->leftIndent)
+ horizontalScrollBar()->setValue(int(viewRect.right() - width + xmargin + 0.5));
+ }
+ if (viewRect.top() <= top + ymargin) {
+ // need to scroll from the top
+ if (!d->topIndent)
+ verticalScrollBar()->setValue(int(viewRect.top() - ymargin - 0.5));
+ }
+ if (viewRect.bottom() >= bottom - ymargin) {
+ // need to scroll from the bottom
+ if (!d->topIndent)
+ verticalScrollBar()->setValue(int(viewRect.bottom() - height + ymargin + 0.5));
+ }
+}
+
+/*!
+ \fn QGraphicsView::ensureVisible(qreal x, qreal y, qreal w, qreal h,
+ int xmargin, int ymargin)
+ \overload
+
+ This function is provided for convenience. It's equivalent to calling
+ ensureVisible(QRectF(\a x, \a y, \a w, \a h), \a xmargin, \a ymargin).
+*/
+
+/*!
+ \overload
+
+ Scrolls the contents of the viewport so that the center of item \a item is
+ visible, with margins specified in pixels by \a xmargin and \a ymargin. If
+ the specified point cannot be reached, the contents are scrolled to the
+ nearest valid position. The default value for both margins is 50 pixels.
+
+ \sa centerOn()
+*/
+void QGraphicsView::ensureVisible(const QGraphicsItem *item, int xmargin, int ymargin)
+{
+ ensureVisible(item->sceneBoundingRect(), xmargin, ymargin);
+}
+
+/*!
+ Scales the view matrix and scrolls the scroll bars to ensure that the
+ scene rectangle \a rect fits inside the viewport. \a rect must be inside
+ the scene rect; otherwise, fitInView() cannot guarantee that the whole
+ rect is visible.
+
+ This function keeps the view's rotation, translation, or shear. The view
+ is scaled according to \a aspectRatioMode. \a rect will be centered in the
+ view if it does not fit tightly.
+
+ It's common to call fitInView() from inside a reimplementation of
+ resizeEvent(), to ensure that the whole scene, or parts of the scene,
+ scales automatically to fit the new size of the viewport as the view is
+ resized. Note though, that calling fitInView() from inside resizeEvent()
+ can lead to unwanted resize recursion, if the new transformation toggles
+ the automatic state of the scrollbars. You can toggle the scrollbar
+ policies to always on or always off to prevent this (see
+ horizontalScrollBarPolicy() and verticalScrollBarPolicy()).
+
+ If \a rect is empty, or if the viewport is too small, this
+ function will do nothing.
+
+ \sa setTransform(), ensureVisible(), centerOn()
+*/
+void QGraphicsView::fitInView(const QRectF &rect, Qt::AspectRatioMode aspectRatioMode)
+{
+ Q_D(QGraphicsView);
+ if (!d->scene || rect.isNull())
+ return;
+
+ // Reset the view scale to 1:1.
+ QRectF unity = d->matrix.mapRect(QRectF(0, 0, 1, 1));
+ if (unity.isEmpty())
+ return;
+ scale(1 / unity.width(), 1 / unity.height());
+
+ // Find the ideal x / y scaling ratio to fit \a rect in the view.
+ int margin = 2;
+ QRectF viewRect = viewport()->rect().adjusted(margin, margin, -margin, -margin);
+ if (viewRect.isEmpty())
+ return;
+ QRectF sceneRect = d->matrix.mapRect(rect);
+ if (sceneRect.isEmpty())
+ return;
+ qreal xratio = viewRect.width() / sceneRect.width();
+ qreal yratio = viewRect.height() / sceneRect.height();
+
+ // Respect the aspect ratio mode.
+ switch (aspectRatioMode) {
+ case Qt::KeepAspectRatio:
+ xratio = yratio = qMin(xratio, yratio);
+ break;
+ case Qt::KeepAspectRatioByExpanding:
+ xratio = yratio = qMax(xratio, yratio);
+ break;
+ case Qt::IgnoreAspectRatio:
+ break;
+ }
+
+ // Scale and center on the center of \a rect.
+ scale(xratio, yratio);
+ centerOn(rect.center());
+}
+
+/*!
+ \fn void QGraphicsView::fitInView(qreal x, qreal y, qreal w, qreal h,
+ Qt::AspectRatioMode aspectRatioMode = Qt::IgnoreAspectRatio)
+
+ \overload
+
+ This convenience function is equivalent to calling
+ fitInView(QRectF(\a x, \a y, \a w, \a h), \a aspectRatioMode).
+
+ \sa ensureVisible(), centerOn()
+*/
+
+/*!
+ \overload
+
+ Ensures that \a item fits tightly inside the view, scaling the view
+ according to \a aspectRatioMode.
+
+ \sa ensureVisible(), centerOn()
+*/
+void QGraphicsView::fitInView(const QGraphicsItem *item, Qt::AspectRatioMode aspectRatioMode)
+{
+ QPainterPath path = item->isClipped() ? item->clipPath() : item->shape();
+ if (item->d_ptr->hasTranslateOnlySceneTransform()) {
+ path.translate(item->d_ptr->sceneTransform.dx(), item->d_ptr->sceneTransform.dy());
+ fitInView(path.boundingRect(), aspectRatioMode);
+ } else {
+ fitInView(item->d_ptr->sceneTransform.map(path).boundingRect(), aspectRatioMode);
+ }
+}
+
+/*!
+ Renders the \a source rect, which is in view coordinates, from the scene
+ into \a target, which is in paint device coordinates, using \a
+ painter. This function is useful for capturing the contents of the view
+ onto a paint device, such as a QImage (e.g., to take a screenshot), or for
+ printing to QPrinter. For example:
+
+ \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsview.cpp 4
+
+ If \a source is a null rect, this function will use viewport()->rect() to
+ determine what to draw. If \a target is a null rect, the full dimensions
+ of \a painter's paint device (e.g., for a QPrinter, the page size) will be
+ used.
+
+ The source rect contents will be transformed according to \a
+ aspectRatioMode to fit into the target rect. By default, the aspect ratio
+ is kept, and \a source is scaled to fit in \a target.
+
+ \sa QGraphicsScene::render()
+*/
+void QGraphicsView::render(QPainter *painter, const QRectF &target, const QRect &source,
+ Qt::AspectRatioMode aspectRatioMode)
+{
+ // ### Switch to using the recursive rendering algorithm instead.
+
+ Q_D(QGraphicsView);
+ if (!d->scene || !(painter && painter->isActive()))
+ return;
+
+ // Default source rect = viewport rect
+ QRect sourceRect = source;
+ if (source.isNull())
+ sourceRect = viewport()->rect();
+
+ // Default target rect = device rect
+ QRectF targetRect = target;
+ if (target.isNull()) {
+ if (painter->device()->devType() == QInternal::Picture)
+ targetRect = sourceRect;
+ else
+ targetRect.setRect(0, 0, painter->device()->width(), painter->device()->height());
+ }
+
+ // Find the ideal x / y scaling ratio to fit \a source into \a target.
+ qreal xratio = targetRect.width() / sourceRect.width();
+ qreal yratio = targetRect.height() / sourceRect.height();
+
+ // Scale according to the aspect ratio mode.
+ switch (aspectRatioMode) {
+ case Qt::KeepAspectRatio:
+ xratio = yratio = qMin(xratio, yratio);
+ break;
+ case Qt::KeepAspectRatioByExpanding:
+ xratio = yratio = qMax(xratio, yratio);
+ break;
+ case Qt::IgnoreAspectRatio:
+ break;
+ }
+
+ // Find all items to draw, and reverse the list (we want to draw
+ // in reverse order).
+ QPolygonF sourceScenePoly = mapToScene(sourceRect.adjusted(-1, -1, 1, 1));
+ QList<QGraphicsItem *> itemList = d->scene->items(sourceScenePoly,
+ Qt::IntersectsItemBoundingRect);
+ QGraphicsItem **itemArray = new QGraphicsItem *[itemList.size()];
+ int numItems = itemList.size();
+ for (int i = 0; i < numItems; ++i)
+ itemArray[numItems - i - 1] = itemList.at(i);
+ itemList.clear();
+
+ // Setup painter matrix.
+ QTransform moveMatrix = QTransform::fromTranslate(-d->horizontalScroll(), -d->verticalScroll());
+ QTransform painterMatrix = d->matrix * moveMatrix;
+ painterMatrix *= QTransform()
+ .translate(targetRect.left(), targetRect.top())
+ .scale(xratio, yratio)
+ .translate(-sourceRect.left(), -sourceRect.top());
+
+ // Generate the style options
+ QStyleOptionGraphicsItem *styleOptionArray = d->allocStyleOptionsArray(numItems);
+ for (int i = 0; i < numItems; ++i)
+ itemArray[i]->d_ptr->initStyleOption(&styleOptionArray[i], painterMatrix, targetRect.toRect());
+
+ painter->save();
+
+ // Clip in device coordinates to avoid QRegion transformations.
+ painter->setClipRect(targetRect);
+ QPainterPath path;
+ path.addPolygon(sourceScenePoly);
+ path.closeSubpath();
+ painter->setClipPath(painterMatrix.map(path), Qt::IntersectClip);
+
+ // Transform the painter.
+ painter->setTransform(painterMatrix, true);
+
+ // Render the scene.
+ QRectF sourceSceneRect = sourceScenePoly.boundingRect();
+ drawBackground(painter, sourceSceneRect);
+ drawItems(painter, numItems, itemArray, styleOptionArray);
+ drawForeground(painter, sourceSceneRect);
+
+ delete [] itemArray;
+ d->freeStyleOptionsArray(styleOptionArray);
+
+ painter->restore();
+}
+
+/*!
+ Returns a list of all the items in the associated scene, in descending
+ stacking order (i.e., the first item in the returned list is the uppermost
+ item).
+
+ \sa QGraphicsScene::items(), {QGraphicsItem#Sorting}{Sorting}
+*/
+QList<QGraphicsItem *> QGraphicsView::items() const
+{
+ Q_D(const QGraphicsView);
+ if (!d->scene)
+ return QList<QGraphicsItem *>();
+ return d->scene->items();
+}
+
+/*!
+ Returns a list of all the items at the position \a pos in the view. The
+ items are listed in descending stacking order (i.e., the first item in the
+ list is the uppermost item, and the last item is the lowermost item). \a
+ pos is in viewport coordinates.
+
+ This function is most commonly called from within mouse event handlers in
+ a subclass in QGraphicsView. \a pos is in untransformed viewport
+ coordinates, just like QMouseEvent::pos().
+
+ \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsview.cpp 5
+
+ \sa QGraphicsScene::items(), {QGraphicsItem#Sorting}{Sorting}
+*/
+QList<QGraphicsItem *> QGraphicsView::items(const QPoint &pos) const
+{
+ Q_D(const QGraphicsView);
+ if (!d->scene)
+ return QList<QGraphicsItem *>();
+ // ### Unify these two, and use the items(QPointF) version in
+ // QGraphicsScene instead. The scene items function could use the viewport
+ // transform to map the point to a rect/polygon.
+ if ((d->identityMatrix || d->matrix.type() <= QTransform::TxScale)) {
+ // Use the rect version
+ QTransform xinv = viewportTransform().inverted();
+ return d->scene->items(xinv.mapRect(QRectF(pos.x(), pos.y(), 1, 1)),
+ Qt::IntersectsItemShape,
+ Qt::DescendingOrder,
+ viewportTransform());
+ }
+ // Use the polygon version
+ return d->scene->items(mapToScene(pos.x(), pos.y(), 1, 1),
+ Qt::IntersectsItemShape,
+ Qt::DescendingOrder,
+ viewportTransform());
+}
+
+/*!
+ \fn QGraphicsView::items(int x, int y) const
+
+ This function is provided for convenience. It's equivalent to calling
+ items(QPoint(\a x, \a y)).
+*/
+
+/*!
+ \overload
+
+ Returns a list of all the items that, depending on \a mode, are either
+ contained by or intersect with \a rect. \a rect is in viewport
+ coordinates.
+
+ The default value for \a mode is Qt::IntersectsItemShape; all items whose
+ exact shape intersects with or is contained by \a rect are returned.
+
+ The items are sorted in descending stacking order (i.e., the first item in
+ the returned list is the uppermost item).
+
+ \sa itemAt(), items(), mapToScene(), {QGraphicsItem#Sorting}{Sorting}
+*/
+QList<QGraphicsItem *> QGraphicsView::items(const QRect &rect, Qt::ItemSelectionMode mode) const
+{
+ Q_D(const QGraphicsView);
+ if (!d->scene)
+ return QList<QGraphicsItem *>();
+ return d->scene->items(mapToScene(rect), mode, Qt::DescendingOrder, viewportTransform());
+}
+
+/*!
+ \fn QList<QGraphicsItem *> QGraphicsView::items(int x, int y, int w, int h, Qt::ItemSelectionMode mode) const
+ \since 4.3
+
+ This convenience function is equivalent to calling items(QRectF(\a x, \a
+ y, \a w, \a h), \a mode).
+*/
+
+/*!
+ \overload
+
+ Returns a list of all the items that, depending on \a mode, are either
+ contained by or intersect with \a polygon. \a polygon is in viewport
+ coordinates.
+
+ The default value for \a mode is Qt::IntersectsItemShape; all items whose
+ exact shape intersects with or is contained by \a polygon are returned.
+
+ The items are sorted by descending stacking order (i.e., the first item in
+ the returned list is the uppermost item).
+
+ \sa itemAt(), items(), mapToScene(), {QGraphicsItem#Sorting}{Sorting}
+*/
+QList<QGraphicsItem *> QGraphicsView::items(const QPolygon &polygon, Qt::ItemSelectionMode mode) const
+{
+ Q_D(const QGraphicsView);
+ if (!d->scene)
+ return QList<QGraphicsItem *>();
+ return d->scene->items(mapToScene(polygon), mode, Qt::DescendingOrder, viewportTransform());
+}
+
+/*!
+ \overload
+
+ Returns a list of all the items that, depending on \a mode, are either
+ contained by or intersect with \a path. \a path is in viewport
+ coordinates.
+
+ The default value for \a mode is Qt::IntersectsItemShape; all items whose
+ exact shape intersects with or is contained by \a path are returned.
+
+ \sa itemAt(), items(), mapToScene(), {QGraphicsItem#Sorting}{Sorting}
+*/
+QList<QGraphicsItem *> QGraphicsView::items(const QPainterPath &path, Qt::ItemSelectionMode mode) const
+{
+ Q_D(const QGraphicsView);
+ if (!d->scene)
+ return QList<QGraphicsItem *>();
+ return d->scene->items(mapToScene(path), mode, Qt::DescendingOrder, viewportTransform());
+}
+
+/*!
+ Returns the item at position \a pos, which is in viewport coordinates.
+ If there are several items at this position, this function returns
+ the topmost item.
+
+ Example:
+
+ \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsview.cpp 6
+
+ \sa items(), {QGraphicsItem#Sorting}{Sorting}
+*/
+QGraphicsItem *QGraphicsView::itemAt(const QPoint &pos) const
+{
+ Q_D(const QGraphicsView);
+ if (!d->scene)
+ return 0;
+ QList<QGraphicsItem *> itemsAtPos = items(pos);
+ return itemsAtPos.isEmpty() ? 0 : itemsAtPos.first();
+}
+
+/*!
+ \overload
+ \fn QGraphicsItem *QGraphicsView::itemAt(int x, int y) const
+
+ This function is provided for convenience. It's equivalent to
+ calling itemAt(QPoint(\a x, \a y)).
+*/
+
+/*!
+ Returns the viewport coordinate \a point mapped to scene coordinates.
+
+ Note: It can be useful to map the whole rectangle covered by the pixel at
+ \a point instead of the point itself. To do this, you can call
+ mapToScene(QRect(\a point, QSize(2, 2))).
+
+ \sa mapFromScene()
+*/
+QPointF QGraphicsView::mapToScene(const QPoint &point) const
+{
+ Q_D(const QGraphicsView);
+ QPointF p = point;
+ p.rx() += d->horizontalScroll();
+ p.ry() += d->verticalScroll();
+ return d->identityMatrix ? p : d->matrix.inverted().map(p);
+}
+
+/*!
+ \fn QGraphicsView::mapToScene(int x, int y) const
+
+ This function is provided for convenience. It's equivalent to calling
+ mapToScene(QPoint(\a x, \a y)).
+*/
+
+/*!
+ Returns the viewport rectangle \a rect mapped to a scene coordinate
+ polygon.
+
+ \sa mapFromScene()
+*/
+QPolygonF QGraphicsView::mapToScene(const QRect &rect) const
+{
+ Q_D(const QGraphicsView);
+ if (!rect.isValid())
+ return QPolygonF();
+
+ QPointF scrollOffset(d->horizontalScroll(), d->verticalScroll());
+ QRect r = rect.adjusted(0, 0, 1, 1);
+ QPointF tl = scrollOffset + r.topLeft();
+ QPointF tr = scrollOffset + r.topRight();
+ QPointF br = scrollOffset + r.bottomRight();
+ QPointF bl = scrollOffset + r.bottomLeft();
+
+ QPolygonF poly(4);
+ if (!d->identityMatrix) {
+ QTransform x = d->matrix.inverted();
+ poly[0] = x.map(tl);
+ poly[1] = x.map(tr);
+ poly[2] = x.map(br);
+ poly[3] = x.map(bl);
+ } else {
+ poly[0] = tl;
+ poly[1] = tr;
+ poly[2] = br;
+ poly[3] = bl;
+ }
+ return poly;
+}
+
+/*!
+ \fn QGraphicsView::mapToScene(int x, int y, int w, int h) const
+
+ This function is provided for convenience. It's equivalent to calling
+ mapToScene(QRect(\a x, \a y, \a w, \a h)).
+*/
+
+/*!
+ Returns the viewport polygon \a polygon mapped to a scene coordinate
+ polygon.
+
+ \sa mapFromScene()
+*/
+QPolygonF QGraphicsView::mapToScene(const QPolygon &polygon) const
+{
+ QPolygonF poly;
+ foreach (const QPoint &point, polygon)
+ poly << mapToScene(point);
+ return poly;
+}
+
+/*!
+ Returns the viewport painter path \a path mapped to a scene coordinate
+ painter path.
+
+ \sa mapFromScene()
+*/
+QPainterPath QGraphicsView::mapToScene(const QPainterPath &path) const
+{
+ Q_D(const QGraphicsView);
+ QTransform matrix = QTransform::fromTranslate(d->horizontalScroll(), d->verticalScroll());
+ matrix *= d->matrix.inverted();
+ return matrix.map(path);
+}
+
+/*!
+ Returns the scene coordinate \a point to viewport coordinates.
+
+ \sa mapToScene()
+*/
+QPoint QGraphicsView::mapFromScene(const QPointF &point) const
+{
+ Q_D(const QGraphicsView);
+ QPointF p = d->identityMatrix ? point : d->matrix.map(point);
+ p.rx() -= d->horizontalScroll();
+ p.ry() -= d->verticalScroll();
+ return p.toPoint();
+}
+
+/*!
+ \fn QGraphicsView::mapFromScene(qreal x, qreal y) const
+
+ This function is provided for convenience. It's equivalent to
+ calling mapFromScene(QPointF(\a x, \a y)).
+*/
+
+/*!
+ Returns the scene rectangle \a rect to a viewport coordinate
+ polygon.
+
+ \sa mapToScene()
+*/
+QPolygon QGraphicsView::mapFromScene(const QRectF &rect) const
+{
+ Q_D(const QGraphicsView);
+ QPointF tl;
+ QPointF tr;
+ QPointF br;
+ QPointF bl;
+ if (!d->identityMatrix) {
+ const QTransform &x = d->matrix;
+ tl = x.map(rect.topLeft());
+ tr = x.map(rect.topRight());
+ br = x.map(rect.bottomRight());
+ bl = x.map(rect.bottomLeft());
+ } else {
+ tl = rect.topLeft();
+ tr = rect.topRight();
+ br = rect.bottomRight();
+ bl = rect.bottomLeft();
+ }
+ QPointF scrollOffset(d->horizontalScroll(), d->verticalScroll());
+ tl -= scrollOffset;
+ tr -= scrollOffset;
+ br -= scrollOffset;
+ bl -= scrollOffset;
+
+ QPolygon poly(4);
+ poly[0] = tl.toPoint();
+ poly[1] = tr.toPoint();
+ poly[2] = br.toPoint();
+ poly[3] = bl.toPoint();
+ return poly;
+}
+
+/*!
+ \fn QGraphicsView::mapFromScene(qreal x, qreal y, qreal w, qreal h) const
+
+ This function is provided for convenience. It's equivalent to
+ calling mapFromScene(QRectF(\a x, \a y, \a w, \a h)).
+*/
+
+/*!
+ Returns the scene coordinate polygon \a polygon to a viewport coordinate
+ polygon.
+
+ \sa mapToScene()
+*/
+QPolygon QGraphicsView::mapFromScene(const QPolygonF &polygon) const
+{
+ QPolygon poly;
+ foreach (const QPointF &point, polygon)
+ poly << mapFromScene(point);
+ return poly;
+}
+
+/*!
+ Returns the scene coordinate painter path \a path to a viewport coordinate
+ painter path.
+
+ \sa mapToScene()
+*/
+QPainterPath QGraphicsView::mapFromScene(const QPainterPath &path) const
+{
+ Q_D(const QGraphicsView);
+ QTransform matrix = d->matrix;
+ matrix *= QTransform::fromTranslate(-d->horizontalScroll(), -d->verticalScroll());
+ return matrix.map(path);
+}
+
+/*!
+ \reimp
+*/
+QVariant QGraphicsView::inputMethodQuery(Qt::InputMethodQuery query) const
+{
+ Q_D(const QGraphicsView);
+ if (!d->scene)
+ return QVariant();
+
+ QVariant value = d->scene->inputMethodQuery(query);
+ if (value.type() == QVariant::RectF)
+ value = d->mapRectFromScene(value.toRectF());
+ else if (value.type() == QVariant::PointF)
+ value = mapFromScene(value.toPointF());
+ else if (value.type() == QVariant::Rect)
+ value = d->mapRectFromScene(value.toRect()).toRect();
+ else if (value.type() == QVariant::Point)
+ value = mapFromScene(value.toPoint());
+ return value;
+}
+
+/*!
+ \property QGraphicsView::backgroundBrush
+ \brief the background brush of the scene.
+
+ This property sets the background brush for the scene in this view. It is
+ used to override the scene's own background, and defines the behavior of
+ drawBackground(). To provide custom background drawing for this view, you
+ can reimplement drawBackground() instead.
+
+ By default, this property contains a brush with the Qt::NoBrush pattern.
+
+ \sa QGraphicsScene::backgroundBrush, foregroundBrush
+*/
+QBrush QGraphicsView::backgroundBrush() const
+{
+ Q_D(const QGraphicsView);
+ return d->backgroundBrush;
+}
+void QGraphicsView::setBackgroundBrush(const QBrush &brush)
+{
+ Q_D(QGraphicsView);
+ d->backgroundBrush = brush;
+ d->updateAll();
+
+ if (d->cacheMode & CacheBackground) {
+ // Invalidate the background pixmap
+ d->mustResizeBackgroundPixmap = true;
+ }
+}
+
+/*!
+ \property QGraphicsView::foregroundBrush
+ \brief the foreground brush of the scene.
+
+ This property sets the foreground brush for the scene in this view. It is
+ used to override the scene's own foreground, and defines the behavior of
+ drawForeground(). To provide custom foreground drawing for this view, you
+ can reimplement drawForeground() instead.
+
+ By default, this property contains a brush with the Qt::NoBrush pattern.
+
+ \sa QGraphicsScene::foregroundBrush, backgroundBrush
+*/
+QBrush QGraphicsView::foregroundBrush() const
+{
+ Q_D(const QGraphicsView);
+ return d->foregroundBrush;
+}
+void QGraphicsView::setForegroundBrush(const QBrush &brush)
+{
+ Q_D(QGraphicsView);
+ d->foregroundBrush = brush;
+ d->updateAll();
+}
+
+/*!
+ Schedules an update of the scene rectangles \a rects.
+
+ \sa QGraphicsScene::changed()
+*/
+void QGraphicsView::updateScene(const QList<QRectF> &rects)
+{
+ // ### Note: Since 4.5, this slot is only called if the user explicitly
+ // establishes a connection between the scene and the view, as the scene
+ // and view are no longer connected. We need to keep it working (basically
+ // leave it as it is), but the new delivery path is through
+ // QGraphicsScenePrivate::itemUpdate().
+ Q_D(QGraphicsView);
+ if (d->fullUpdatePending || d->viewportUpdateMode == QGraphicsView::NoViewportUpdate)
+ return;
+
+ // Extract and reset dirty scene rect info.
+ QVector<QRect> dirtyViewportRects;
+ const QVector<QRect> &dirtyRects = d->dirtyRegion.rects();
+ for (int i = 0; i < dirtyRects.size(); ++i)
+ dirtyViewportRects += dirtyRects.at(i);
+ d->dirtyRegion = QRegion();
+ d->dirtyBoundingRect = QRect();
+
+ bool fullUpdate = !d->accelerateScrolling || d->viewportUpdateMode == QGraphicsView::FullViewportUpdate;
+ bool boundingRectUpdate = (d->viewportUpdateMode == QGraphicsView::BoundingRectViewportUpdate)
+ || (d->viewportUpdateMode == QGraphicsView::SmartViewportUpdate
+ && ((dirtyViewportRects.size() + rects.size()) >= QGRAPHICSVIEW_REGION_RECT_THRESHOLD));
+
+ QRegion updateRegion;
+ QRect boundingRect;
+ QRect viewportRect = viewport()->rect();
+ bool redraw = false;
+ QTransform transform = viewportTransform();
+
+ // Convert scene rects to viewport rects.
+ foreach (const QRectF &rect, rects) {
+ QRect xrect = transform.mapRect(rect).toAlignedRect();
+ if (!(d->optimizationFlags & DontAdjustForAntialiasing))
+ xrect.adjust(-2, -2, 2, 2);
+ else
+ xrect.adjust(-1, -1, 1, 1);
+ if (!viewportRect.intersects(xrect))
+ continue;
+ dirtyViewportRects << xrect;
+ }
+
+ foreach (const QRect &rect, dirtyViewportRects) {
+ // Add the exposed rect to the update region. In rect update
+ // mode, we only count the bounding rect of items.
+ if (!boundingRectUpdate) {
+ updateRegion += rect;
+ } else {
+ boundingRect |= rect;
+ }
+ redraw = true;
+ if (fullUpdate) {
+ // If fullUpdate is true and we found a visible dirty rect,
+ // we're done.
+ break;
+ }
+ }
+
+ if (!redraw)
+ return;
+
+ if (fullUpdate)
+ viewport()->update();
+ else if (boundingRectUpdate)
+ viewport()->update(boundingRect);
+ else
+ viewport()->update(updateRegion);
+}
+
+/*!
+ Notifies QGraphicsView that the scene's scene rect has changed. \a rect
+ is the new scene rect. If the view already has an explicitly set scene
+ rect, this function does nothing.
+
+ \sa sceneRect, QGraphicsScene::sceneRectChanged()
+*/
+void QGraphicsView::updateSceneRect(const QRectF &rect)
+{
+ Q_D(QGraphicsView);
+ if (!d->hasSceneRect) {
+ d->sceneRect = rect;
+ d->recalculateContentSize();
+ }
+}
+
+/*!
+ This slot is called by QAbstractScrollArea after setViewport() has been
+ called. Reimplement this function in a subclass of QGraphicsView to
+ initialize the new viewport \a widget before it is used.
+
+ \sa setViewport()
+*/
+void QGraphicsView::setupViewport(QWidget *widget)
+{
+ Q_D(QGraphicsView);
+
+ if (!widget) {
+ qWarning("QGraphicsView::setupViewport: cannot initialize null widget");
+ return;
+ }
+
+ const bool isGLWidget = widget->inherits("QGLWidget");
+
+ d->accelerateScrolling = !(isGLWidget);
+
+ widget->setFocusPolicy(Qt::StrongFocus);
+
+ if (!isGLWidget) {
+ // autoFillBackground enables scroll acceleration.
+ widget->setAutoFillBackground(true);
+ }
+
+ // We are only interested in mouse tracking if items
+ // accept hover events or use non-default cursors or if
+ // AnchorUnderMouse is used as transformation or resize anchor.
+ if ((d->scene && (!d->scene->d_func()->allItemsIgnoreHoverEvents
+ || !d->scene->d_func()->allItemsUseDefaultCursor))
+ || d->transformationAnchor == AnchorUnderMouse
+ || d->resizeAnchor == AnchorUnderMouse) {
+ widget->setMouseTracking(true);
+ }
+
+ // enable touch events if any items is interested in them
+ if (d->scene && !d->scene->d_func()->allItemsIgnoreTouchEvents)
+ widget->setAttribute(Qt::WA_AcceptTouchEvents);
+
+#ifndef QT_NO_GESTURES
+ if (d->scene) {
+ foreach (Qt::GestureType gesture, d->scene->d_func()->grabbedGestures.keys())
+ widget->grabGesture(gesture);
+ }
+#endif
+
+ widget->setAcceptDrops(acceptDrops());
+}
+
+/*!
+ \reimp
+*/
+bool QGraphicsView::event(QEvent *event)
+{
+ Q_D(QGraphicsView);
+
+ if (d->sceneInteractionAllowed) {
+ switch (event->type()) {
+ case QEvent::ShortcutOverride:
+ if (d->scene)
+ return QApplication::sendEvent(d->scene, event);
+ break;
+ case QEvent::KeyPress:
+ if (d->scene) {
+ QKeyEvent *k = static_cast<QKeyEvent *>(event);
+ if (k->key() == Qt::Key_Tab || k->key() == Qt::Key_Backtab) {
+ // Send the key events to the scene. This will invoke the
+ // scene's tab focus handling, and if the event is
+ // accepted, we return (prevent further event delivery),
+ // and the base implementation will call QGraphicsView's
+ // focusNextPrevChild() function. If the event is ignored,
+ // we fall back to standard tab focus handling.
+ QApplication::sendEvent(d->scene, event);
+ if (event->isAccepted())
+ return true;
+ // Ensure the event doesn't propagate just because the
+ // scene ignored it. If the event propagates, then tab
+ // handling will be called twice (this and parent).
+ event->accept();
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ return QAbstractScrollArea::event(event);
+}
+
+/*!
+ \reimp
+*/
+bool QGraphicsView::viewportEvent(QEvent *event)
+{
+ Q_D(QGraphicsView);
+ if (!d->scene)
+ return QAbstractScrollArea::viewportEvent(event);
+
+ switch (event->type()) {
+ case QEvent::Enter:
+ QApplication::sendEvent(d->scene, event);
+ break;
+ case QEvent::WindowActivate:
+ QApplication::sendEvent(d->scene, event);
+ break;
+ case QEvent::WindowDeactivate:
+ // ### This is a temporary fix for until we get proper mouse
+ // grab events. mouseGrabberItem should be set to 0 if we lose
+ // the mouse grab.
+ // Remove all popups when the scene loses focus.
+ if (!d->scene->d_func()->popupWidgets.isEmpty())
+ d->scene->d_func()->removePopup(d->scene->d_func()->popupWidgets.first());
+ QApplication::sendEvent(d->scene, event);
+ break;
+ case QEvent::Show:
+ if (d->scene && isActiveWindow()) {
+ QEvent windowActivate(QEvent::WindowActivate);
+ QApplication::sendEvent(d->scene, &windowActivate);
+ }
+ break;
+ case QEvent::Hide:
+ // spontaneous event will generate a WindowDeactivate.
+ if (!event->spontaneous() && d->scene && isActiveWindow()) {
+ QEvent windowDeactivate(QEvent::WindowDeactivate);
+ QApplication::sendEvent(d->scene, &windowDeactivate);
+ }
+ break;
+ case QEvent::Leave:
+ // ### This is a temporary fix for until we get proper mouse grab
+ // events. activeMouseGrabberItem should be set to 0 if we lose the
+ // mouse grab.
+ if ((QApplication::activePopupWidget() && QApplication::activePopupWidget() != window())
+ || (QApplication::activeModalWidget() && QApplication::activeModalWidget() != window())
+ || (QApplication::activeWindow() != window())) {
+ if (!d->scene->d_func()->popupWidgets.isEmpty())
+ d->scene->d_func()->removePopup(d->scene->d_func()->popupWidgets.first());
+ }
+ d->useLastMouseEvent = false;
+ // a hack to pass a viewport pointer to the scene inside the leave event
+ Q_ASSERT(event->d == 0);
+ event->d = reinterpret_cast<QEventPrivate *>(viewport());
+ QApplication::sendEvent(d->scene, event);
+ break;
+#ifndef QT_NO_TOOLTIP
+ case QEvent::ToolTip: {
+ QHelpEvent *toolTip = static_cast<QHelpEvent *>(event);
+ QGraphicsSceneHelpEvent helpEvent(QEvent::GraphicsSceneHelp);
+ helpEvent.setWidget(viewport());
+ helpEvent.setScreenPos(toolTip->globalPos());
+ helpEvent.setScenePos(mapToScene(toolTip->pos()));
+ QApplication::sendEvent(d->scene, &helpEvent);
+ toolTip->setAccepted(helpEvent.isAccepted());
+ return true;
+ }
+#endif
+ case QEvent::Paint:
+ // Reset full update
+ d->fullUpdatePending = false;
+ d->dirtyScrollOffset = QPoint();
+ if (d->scene) {
+ // Check if this view reimplements the updateScene slot; if it
+ // does, we can't do direct update delivery and have to fall back
+ // to connecting the changed signal.
+ if (!d->updateSceneSlotReimplementedChecked) {
+ d->updateSceneSlotReimplementedChecked = true;
+ const QMetaObject *mo = metaObject();
+ if (mo != &QGraphicsView::staticMetaObject) {
+ if (mo->indexOfSlot("updateScene(QList<QRectF>)")
+ != QGraphicsView::staticMetaObject.indexOfSlot("updateScene(QList<QRectF>)")) {
+ connect(d->scene, SIGNAL(changed(QList<QRectF>)),
+ this, SLOT(updateScene(QList<QRectF>)));
+ }
+ }
+ }
+ }
+ break;
+ case QEvent::TouchBegin:
+ case QEvent::TouchUpdate:
+ case QEvent::TouchEnd:
+ {
+ if (!isEnabled())
+ return false;
+
+ if (d->scene && d->sceneInteractionAllowed) {
+ // Convert and deliver the touch event to the scene.
+ QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event);
+ touchEvent->setWidget(viewport());
+ QGraphicsViewPrivate::translateTouchEvent(d, touchEvent);
+ (void) QApplication::sendEvent(d->scene, touchEvent);
+ }
+
+ return true;
+ }
+#ifndef QT_NO_GESTURES
+ case QEvent::Gesture:
+ case QEvent::GestureOverride:
+ {
+ if (!isEnabled())
+ return false;
+
+ if (d->scene && d->sceneInteractionAllowed) {
+ QGestureEvent *gestureEvent = static_cast<QGestureEvent *>(event);
+ gestureEvent->setWidget(viewport());
+ (void) QApplication::sendEvent(d->scene, gestureEvent);
+ }
+ return true;
+ }
+#endif // QT_NO_GESTURES
+ default:
+ break;
+ }
+
+ return QAbstractScrollArea::viewportEvent(event);
+}
+
+#ifndef QT_NO_CONTEXTMENU
+/*!
+ \reimp
+*/
+void QGraphicsView::contextMenuEvent(QContextMenuEvent *event)
+{
+ Q_D(QGraphicsView);
+ if (!d->scene || !d->sceneInteractionAllowed)
+ return;
+
+ d->mousePressViewPoint = event->pos();
+ d->mousePressScenePoint = mapToScene(d->mousePressViewPoint);
+ d->mousePressScreenPoint = event->globalPos();
+ d->lastMouseMoveScenePoint = d->mousePressScenePoint;
+ d->lastMouseMoveScreenPoint = d->mousePressScreenPoint;
+
+ QGraphicsSceneContextMenuEvent contextEvent(QEvent::GraphicsSceneContextMenu);
+ contextEvent.setWidget(viewport());
+ contextEvent.setScenePos(d->mousePressScenePoint);
+ contextEvent.setScreenPos(d->mousePressScreenPoint);
+ contextEvent.setModifiers(event->modifiers());
+ contextEvent.setReason((QGraphicsSceneContextMenuEvent::Reason)(event->reason()));
+ contextEvent.setAccepted(event->isAccepted());
+ QApplication::sendEvent(d->scene, &contextEvent);
+ event->setAccepted(contextEvent.isAccepted());
+}
+#endif // QT_NO_CONTEXTMENU
+
+/*!
+ \reimp
+*/
+void QGraphicsView::dropEvent(QDropEvent *event)
+{
+#ifndef QT_NO_DRAGANDDROP
+ Q_D(QGraphicsView);
+ if (!d->scene || !d->sceneInteractionAllowed)
+ return;
+
+ // Generate a scene event.
+ QGraphicsSceneDragDropEvent sceneEvent(QEvent::GraphicsSceneDrop);
+ d->populateSceneDragDropEvent(&sceneEvent, event);
+
+ // Send it to the scene.
+ QApplication::sendEvent(d->scene, &sceneEvent);
+
+ // Accept the originating event if the scene accepted the scene event.
+ event->setAccepted(sceneEvent.isAccepted());
+ if (sceneEvent.isAccepted())
+ event->setDropAction(sceneEvent.dropAction());
+
+ delete d->lastDragDropEvent;
+ d->lastDragDropEvent = 0;
+
+#else
+ Q_UNUSED(event)
+#endif
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsView::dragEnterEvent(QDragEnterEvent *event)
+{
+#ifndef QT_NO_DRAGANDDROP
+ Q_D(QGraphicsView);
+ if (!d->scene || !d->sceneInteractionAllowed)
+ return;
+
+ // Disable replaying of mouse move events.
+ d->useLastMouseEvent = false;
+
+ // Generate a scene event.
+ QGraphicsSceneDragDropEvent sceneEvent(QEvent::GraphicsSceneDragEnter);
+ d->populateSceneDragDropEvent(&sceneEvent, event);
+
+ // Store it for later use.
+ d->storeDragDropEvent(&sceneEvent);
+
+ // Send it to the scene.
+ QApplication::sendEvent(d->scene, &sceneEvent);
+
+ // Accept the originating event if the scene accepted the scene event.
+ if (sceneEvent.isAccepted()) {
+ event->setAccepted(true);
+ event->setDropAction(sceneEvent.dropAction());
+ }
+#else
+ Q_UNUSED(event)
+#endif
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsView::dragLeaveEvent(QDragLeaveEvent *event)
+{
+#ifndef QT_NO_DRAGANDDROP
+ Q_D(QGraphicsView);
+ if (!d->scene || !d->sceneInteractionAllowed)
+ return;
+ if (!d->lastDragDropEvent) {
+ qWarning("QGraphicsView::dragLeaveEvent: drag leave received before drag enter");
+ return;
+ }
+
+ // Generate a scene event.
+ QGraphicsSceneDragDropEvent sceneEvent(QEvent::GraphicsSceneDragLeave);
+ sceneEvent.setScenePos(d->lastDragDropEvent->scenePos());
+ sceneEvent.setScreenPos(d->lastDragDropEvent->screenPos());
+ sceneEvent.setButtons(d->lastDragDropEvent->buttons());
+ sceneEvent.setModifiers(d->lastDragDropEvent->modifiers());
+ sceneEvent.setPossibleActions(d->lastDragDropEvent->possibleActions());
+ sceneEvent.setProposedAction(d->lastDragDropEvent->proposedAction());
+ sceneEvent.setDropAction(d->lastDragDropEvent->dropAction());
+ sceneEvent.setMimeData(d->lastDragDropEvent->mimeData());
+ sceneEvent.setWidget(d->lastDragDropEvent->widget());
+ sceneEvent.setSource(d->lastDragDropEvent->source());
+ delete d->lastDragDropEvent;
+ d->lastDragDropEvent = 0;
+
+ // Send it to the scene.
+ QApplication::sendEvent(d->scene, &sceneEvent);
+
+ // Accept the originating event if the scene accepted the scene event.
+ if (sceneEvent.isAccepted())
+ event->setAccepted(true);
+#else
+ Q_UNUSED(event)
+#endif
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsView::dragMoveEvent(QDragMoveEvent *event)
+{
+#ifndef QT_NO_DRAGANDDROP
+ Q_D(QGraphicsView);
+ if (!d->scene || !d->sceneInteractionAllowed)
+ return;
+
+ // Generate a scene event.
+ QGraphicsSceneDragDropEvent sceneEvent(QEvent::GraphicsSceneDragMove);
+ d->populateSceneDragDropEvent(&sceneEvent, event);
+
+ // Store it for later use.
+ d->storeDragDropEvent(&sceneEvent);
+
+ // Send it to the scene.
+ QApplication::sendEvent(d->scene, &sceneEvent);
+
+ // Ignore the originating event if the scene ignored the scene event.
+ event->setAccepted(sceneEvent.isAccepted());
+ if (sceneEvent.isAccepted())
+ event->setDropAction(sceneEvent.dropAction());
+#else
+ Q_UNUSED(event)
+#endif
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsView::focusInEvent(QFocusEvent *event)
+{
+ Q_D(QGraphicsView);
+ d->updateInputMethodSensitivity();
+ QAbstractScrollArea::focusInEvent(event);
+ if (d->scene)
+ QApplication::sendEvent(d->scene, event);
+ // Pass focus on if the scene cannot accept focus.
+ if (!d->scene || !event->isAccepted())
+ QAbstractScrollArea::focusInEvent(event);
+}
+
+/*!
+ \reimp
+*/
+bool QGraphicsView::focusNextPrevChild(bool next)
+{
+ return QAbstractScrollArea::focusNextPrevChild(next);
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsView::focusOutEvent(QFocusEvent *event)
+{
+ Q_D(QGraphicsView);
+ QAbstractScrollArea::focusOutEvent(event);
+ if (d->scene)
+ QApplication::sendEvent(d->scene, event);
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsView::keyPressEvent(QKeyEvent *event)
+{
+ Q_D(QGraphicsView);
+ if (!d->scene || !d->sceneInteractionAllowed) {
+ QAbstractScrollArea::keyPressEvent(event);
+ return;
+ }
+ QApplication::sendEvent(d->scene, event);
+ if (!event->isAccepted())
+ QAbstractScrollArea::keyPressEvent(event);
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsView::keyReleaseEvent(QKeyEvent *event)
+{
+ Q_D(QGraphicsView);
+ if (!d->scene || !d->sceneInteractionAllowed)
+ return;
+ QApplication::sendEvent(d->scene, event);
+ if (!event->isAccepted())
+ QAbstractScrollArea::keyReleaseEvent(event);
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsView::mouseDoubleClickEvent(QMouseEvent *event)
+{
+ Q_D(QGraphicsView);
+ if (!d->scene || !d->sceneInteractionAllowed)
+ return;
+
+ d->storeMouseEvent(event);
+ d->mousePressViewPoint = event->pos();
+ d->mousePressScenePoint = mapToScene(d->mousePressViewPoint);
+ d->mousePressScreenPoint = event->globalPos();
+ d->lastMouseMoveScenePoint = d->mousePressScenePoint;
+ d->lastMouseMoveScreenPoint = d->mousePressScreenPoint;
+ d->mousePressButton = event->button();
+
+ QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMouseDoubleClick);
+ mouseEvent.setWidget(viewport());
+ mouseEvent.setButtonDownScenePos(d->mousePressButton, d->mousePressScenePoint);
+ mouseEvent.setButtonDownScreenPos(d->mousePressButton, d->mousePressScreenPoint);
+ mouseEvent.setScenePos(mapToScene(d->mousePressViewPoint));
+ mouseEvent.setScreenPos(d->mousePressScreenPoint);
+ mouseEvent.setLastScenePos(d->lastMouseMoveScenePoint);
+ mouseEvent.setLastScreenPos(d->lastMouseMoveScreenPoint);
+ mouseEvent.setButtons(event->buttons());
+ mouseEvent.setButtons(event->buttons());
+ mouseEvent.setAccepted(false);
+ mouseEvent.setButton(event->button());
+ mouseEvent.setModifiers(event->modifiers());
+ if (event->spontaneous())
+ qt_sendSpontaneousEvent(d->scene, &mouseEvent);
+ else
+ QApplication::sendEvent(d->scene, &mouseEvent);
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsView::mousePressEvent(QMouseEvent *event)
+{
+ Q_D(QGraphicsView);
+
+ // Store this event for replaying, finding deltas, and for
+ // scroll-dragging; even in non-interactive mode, scroll hand dragging is
+ // allowed, so we store the event at the very top of this function.
+ d->storeMouseEvent(event);
+ d->lastMouseEvent.setAccepted(false);
+
+ if (d->sceneInteractionAllowed) {
+ // Store some of the event's button-down data.
+ d->mousePressViewPoint = event->pos();
+ d->mousePressScenePoint = mapToScene(d->mousePressViewPoint);
+ d->mousePressScreenPoint = event->globalPos();
+ d->lastMouseMoveScenePoint = d->mousePressScenePoint;
+ d->lastMouseMoveScreenPoint = d->mousePressScreenPoint;
+ d->mousePressButton = event->button();
+
+ if (d->scene) {
+ // Convert and deliver the mouse event to the scene.
+ QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMousePress);
+ mouseEvent.setWidget(viewport());
+ mouseEvent.setButtonDownScenePos(d->mousePressButton, d->mousePressScenePoint);
+ mouseEvent.setButtonDownScreenPos(d->mousePressButton, d->mousePressScreenPoint);
+ mouseEvent.setScenePos(d->mousePressScenePoint);
+ mouseEvent.setScreenPos(d->mousePressScreenPoint);
+ mouseEvent.setLastScenePos(d->lastMouseMoveScenePoint);
+ mouseEvent.setLastScreenPos(d->lastMouseMoveScreenPoint);
+ mouseEvent.setButtons(event->buttons());
+ mouseEvent.setButton(event->button());
+ mouseEvent.setModifiers(event->modifiers());
+ mouseEvent.setAccepted(false);
+ if (event->spontaneous())
+ qt_sendSpontaneousEvent(d->scene, &mouseEvent);
+ else
+ QApplication::sendEvent(d->scene, &mouseEvent);
+
+ // Update the original mouse event accepted state.
+ bool isAccepted = mouseEvent.isAccepted();
+ event->setAccepted(isAccepted);
+
+ // Update the last mouse event accepted state.
+ d->lastMouseEvent.setAccepted(isAccepted);
+
+ if (isAccepted)
+ return;
+ }
+ }
+
+#ifndef QT_NO_RUBBERBAND
+ if (d->dragMode == QGraphicsView::RubberBandDrag && !d->rubberBanding) {
+ if (d->sceneInteractionAllowed) {
+ // Rubberbanding is only allowed in interactive mode.
+ event->accept();
+ d->rubberBanding = true;
+ d->rubberBandRect = QRect();
+ if (d->scene) {
+ // Initiating a rubber band always clears the selection.
+ d->scene->clearSelection();
+ }
+ }
+ } else
+#endif
+ if (d->dragMode == QGraphicsView::ScrollHandDrag && event->button() == Qt::LeftButton) {
+ // Left-button press in scroll hand mode initiates hand scrolling.
+ event->accept();
+ d->handScrolling = true;
+ d->handScrollMotions = 0;
+#ifndef QT_NO_CURSOR
+ viewport()->setCursor(Qt::ClosedHandCursor);
+#endif
+ }
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsView::mouseMoveEvent(QMouseEvent *event)
+{
+ Q_D(QGraphicsView);
+
+#ifndef QT_NO_RUBBERBAND
+ if (d->dragMode == QGraphicsView::RubberBandDrag && d->sceneInteractionAllowed) {
+ d->storeMouseEvent(event);
+ if (d->rubberBanding) {
+ // Check for enough drag distance
+ if ((d->mousePressViewPoint - event->pos()).manhattanLength()
+ < QApplication::startDragDistance()) {
+ return;
+ }
+
+ // Update old rubberband
+ if (d->viewportUpdateMode != QGraphicsView::NoViewportUpdate && !d->rubberBandRect.isEmpty()) {
+ if (d->viewportUpdateMode != FullViewportUpdate)
+ viewport()->update(d->rubberBandRegion(viewport(), d->rubberBandRect));
+ else
+ d->updateAll();
+ }
+
+ // Stop rubber banding if the user has let go of all buttons (even
+ // if we didn't get the release events).
+ if (!event->buttons()) {
+ d->rubberBanding = false;
+ d->rubberBandRect = QRect();
+ return;
+ }
+
+ // Update rubberband position
+ const QPoint &mp = d->mousePressViewPoint;
+ QPoint ep = event->pos();
+ d->rubberBandRect = QRect(qMin(mp.x(), ep.x()), qMin(mp.y(), ep.y()),
+ qAbs(mp.x() - ep.x()) + 1, qAbs(mp.y() - ep.y()) + 1);
+
+ // Update new rubberband
+ if (d->viewportUpdateMode != QGraphicsView::NoViewportUpdate){
+ if (d->viewportUpdateMode != FullViewportUpdate)
+ viewport()->update(d->rubberBandRegion(viewport(), d->rubberBandRect));
+ else
+ d->updateAll();
+ }
+ // Set the new selection area
+ QPainterPath selectionArea;
+ selectionArea.addPolygon(mapToScene(d->rubberBandRect));
+ selectionArea.closeSubpath();
+ if (d->scene)
+ d->scene->setSelectionArea(selectionArea, d->rubberBandSelectionMode,
+ viewportTransform());
+ return;
+ }
+ } else
+#endif // QT_NO_RUBBERBAND
+ if (d->dragMode == QGraphicsView::ScrollHandDrag) {
+ if (d->handScrolling) {
+ QScrollBar *hBar = horizontalScrollBar();
+ QScrollBar *vBar = verticalScrollBar();
+ QPoint delta = event->pos() - d->lastMouseEvent.pos();
+ hBar->setValue(hBar->value() + (isRightToLeft() ? delta.x() : -delta.x()));
+ vBar->setValue(vBar->value() - delta.y());
+
+ // Detect how much we've scrolled to disambiguate scrolling from
+ // clicking.
+ ++d->handScrollMotions;
+ }
+ }
+
+ d->mouseMoveEventHandler(event);
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsView::mouseReleaseEvent(QMouseEvent *event)
+{
+ Q_D(QGraphicsView);
+
+#ifndef QT_NO_RUBBERBAND
+ if (d->dragMode == QGraphicsView::RubberBandDrag && d->sceneInteractionAllowed && !event->buttons()) {
+ if (d->rubberBanding) {
+ if (d->viewportUpdateMode != QGraphicsView::NoViewportUpdate){
+ if (d->viewportUpdateMode != FullViewportUpdate)
+ viewport()->update(d->rubberBandRegion(viewport(), d->rubberBandRect));
+ else
+ d->updateAll();
+ }
+ d->rubberBanding = false;
+ d->rubberBandRect = QRect();
+ }
+ } else
+#endif
+ if (d->dragMode == QGraphicsView::ScrollHandDrag && event->button() == Qt::LeftButton) {
+#ifndef QT_NO_CURSOR
+ // Restore the open hand cursor. ### There might be items
+ // under the mouse that have a valid cursor at this time, so
+ // we could repeat the steps from mouseMoveEvent().
+ viewport()->setCursor(Qt::OpenHandCursor);
+#endif
+ d->handScrolling = false;
+
+ if (d->scene && d->sceneInteractionAllowed && !d->lastMouseEvent.isAccepted() && d->handScrollMotions <= 6) {
+ // If we've detected very little motion during the hand drag, and
+ // no item accepted the last event, we'll interpret that as a
+ // click to the scene, and reset the selection.
+ d->scene->clearSelection();
+ }
+ }
+
+ d->storeMouseEvent(event);
+
+ if (!d->sceneInteractionAllowed)
+ return;
+
+ if (!d->scene)
+ return;
+
+ QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMouseRelease);
+ mouseEvent.setWidget(viewport());
+ mouseEvent.setButtonDownScenePos(d->mousePressButton, d->mousePressScenePoint);
+ mouseEvent.setButtonDownScreenPos(d->mousePressButton, d->mousePressScreenPoint);
+ mouseEvent.setScenePos(mapToScene(event->pos()));
+ mouseEvent.setScreenPos(event->globalPos());
+ mouseEvent.setLastScenePos(d->lastMouseMoveScenePoint);
+ mouseEvent.setLastScreenPos(d->lastMouseMoveScreenPoint);
+ mouseEvent.setButtons(event->buttons());
+ mouseEvent.setButton(event->button());
+ mouseEvent.setModifiers(event->modifiers());
+ mouseEvent.setAccepted(false);
+ if (event->spontaneous())
+ qt_sendSpontaneousEvent(d->scene, &mouseEvent);
+ else
+ QApplication::sendEvent(d->scene, &mouseEvent);
+
+ // Update the last mouse event selected state.
+ d->lastMouseEvent.setAccepted(mouseEvent.isAccepted());
+
+#ifndef QT_NO_CURSOR
+ if (mouseEvent.isAccepted() && mouseEvent.buttons() == 0 && viewport()->testAttribute(Qt::WA_SetCursor)) {
+ // The last mouse release on the viewport will trigger clearing the cursor.
+ d->_q_unsetViewportCursor();
+ }
+#endif
+}
+
+#ifndef QT_NO_WHEELEVENT
+/*!
+ \reimp
+*/
+void QGraphicsView::wheelEvent(QWheelEvent *event)
+{
+ Q_D(QGraphicsView);
+ if (!d->scene || !d->sceneInteractionAllowed) {
+ QAbstractScrollArea::wheelEvent(event);
+ return;
+ }
+
+ event->ignore();
+
+ QGraphicsSceneWheelEvent wheelEvent(QEvent::GraphicsSceneWheel);
+ wheelEvent.setWidget(viewport());
+ wheelEvent.setScenePos(mapToScene(event->pos()));
+ wheelEvent.setScreenPos(event->globalPos());
+ wheelEvent.setButtons(event->buttons());
+ wheelEvent.setModifiers(event->modifiers());
+ wheelEvent.setDelta(event->delta());
+ wheelEvent.setOrientation(event->orientation());
+ wheelEvent.setAccepted(false);
+ QApplication::sendEvent(d->scene, &wheelEvent);
+ event->setAccepted(wheelEvent.isAccepted());
+ if (!event->isAccepted())
+ QAbstractScrollArea::wheelEvent(event);
+}
+#endif // QT_NO_WHEELEVENT
+
+/*!
+ \reimp
+*/
+void QGraphicsView::paintEvent(QPaintEvent *event)
+{
+ Q_D(QGraphicsView);
+ if (!d->scene) {
+ QAbstractScrollArea::paintEvent(event);
+ return;
+ }
+
+ // Set up painter state protection.
+ d->scene->d_func()->painterStateProtection = !(d->optimizationFlags & DontSavePainterState);
+
+ // Determine the exposed region
+ d->exposedRegion = event->region();
+ QRectF exposedSceneRect = mapToScene(d->exposedRegion.boundingRect()).boundingRect();
+
+ // Set up the painter
+ QPainter painter(viewport());
+#ifndef QT_NO_RUBBERBAND
+ if (d->rubberBanding && !d->rubberBandRect.isEmpty())
+ painter.save();
+#endif
+ // Set up render hints
+ painter.setRenderHints(painter.renderHints(), false);
+ painter.setRenderHints(d->renderHints, true);
+
+ // Set up viewport transform
+ const bool viewTransformed = isTransformed();
+ if (viewTransformed)
+ painter.setWorldTransform(viewportTransform());
+ const QTransform viewTransform = painter.worldTransform();
+
+ // Draw background
+ if ((d->cacheMode & CacheBackground)
+#ifdef Q_WS_X11
+ && X11->use_xrender
+#endif
+ ) {
+ // Recreate the background pixmap, and flag the whole background as
+ // exposed.
+ if (d->mustResizeBackgroundPixmap) {
+ d->backgroundPixmap = QPixmap(viewport()->size());
+ QBrush bgBrush = viewport()->palette().brush(viewport()->backgroundRole());
+ if (!bgBrush.isOpaque())
+ d->backgroundPixmap.fill(Qt::transparent);
+ QPainter p(&d->backgroundPixmap);
+ p.fillRect(0, 0, d->backgroundPixmap.width(), d->backgroundPixmap.height(), bgBrush);
+ d->backgroundPixmapExposed = QRegion(viewport()->rect());
+ d->mustResizeBackgroundPixmap = false;
+ }
+
+ // Redraw exposed areas
+ if (!d->backgroundPixmapExposed.isEmpty()) {
+ QPainter backgroundPainter(&d->backgroundPixmap);
+ backgroundPainter.setClipRegion(d->backgroundPixmapExposed, Qt::ReplaceClip);
+ if (viewTransformed)
+ backgroundPainter.setTransform(viewTransform);
+ QRectF backgroundExposedSceneRect = mapToScene(d->backgroundPixmapExposed.boundingRect()).boundingRect();
+ drawBackground(&backgroundPainter, backgroundExposedSceneRect);
+ d->backgroundPixmapExposed = QRegion();
+ }
+
+ // Blit the background from the background pixmap
+ if (viewTransformed) {
+ painter.setWorldTransform(QTransform());
+ painter.drawPixmap(QPoint(), d->backgroundPixmap);
+ painter.setWorldTransform(viewTransform);
+ } else {
+ painter.drawPixmap(QPoint(), d->backgroundPixmap);
+ }
+ } else {
+ if (!(d->optimizationFlags & DontSavePainterState))
+ painter.save();
+ drawBackground(&painter, exposedSceneRect);
+ if (!(d->optimizationFlags & DontSavePainterState))
+ painter.restore();
+ }
+
+ // Items
+ if (!(d->optimizationFlags & IndirectPainting)) {
+ const quint32 oldRectAdjust = d->scene->d_func()->rectAdjust;
+ if (d->optimizationFlags & QGraphicsView::DontAdjustForAntialiasing)
+ d->scene->d_func()->rectAdjust = 1;
+ else
+ d->scene->d_func()->rectAdjust = 2;
+ d->scene->d_func()->drawItems(&painter, viewTransformed ? &viewTransform : 0,
+ &d->exposedRegion, viewport());
+ d->scene->d_func()->rectAdjust = oldRectAdjust;
+ // Make sure the painter's world transform is restored correctly when
+ // drawing without painter state protection (DontSavePainterState).
+ // We only change the worldTransform() so there's no need to do a full-blown
+ // save() and restore(). Also note that we don't have to do this in case of
+ // IndirectPainting (the else branch), because in that case we always save()
+ // and restore() in QGraphicsScene::drawItems().
+ if (!d->scene->d_func()->painterStateProtection)
+ painter.setOpacity(1.0);
+ painter.setWorldTransform(viewTransform);
+ } else {
+ // Make sure we don't have unpolished items before we draw
+ if (!d->scene->d_func()->unpolishedItems.isEmpty())
+ d->scene->d_func()->_q_polishItems();
+ // We reset updateAll here (after we've issued polish events)
+ // so that we can discard update requests coming from polishEvent().
+ d->scene->d_func()->updateAll = false;
+
+ // Find all exposed items
+ bool allItems = false;
+ QList<QGraphicsItem *> itemList = d->findItems(d->exposedRegion, &allItems, viewTransform);
+ if (!itemList.isEmpty()) {
+ // Generate the style options.
+ const int numItems = itemList.size();
+ QGraphicsItem **itemArray = &itemList[0]; // Relies on QList internals, but is perfectly valid.
+ QStyleOptionGraphicsItem *styleOptionArray = d->allocStyleOptionsArray(numItems);
+ QTransform transform(Qt::Uninitialized);
+ for (int i = 0; i < numItems; ++i) {
+ QGraphicsItem *item = itemArray[i];
+ QGraphicsItemPrivate *itemd = item->d_ptr.data();
+ itemd->initStyleOption(&styleOptionArray[i], viewTransform, d->exposedRegion, allItems);
+ // Cache the item's area in view coordinates.
+ // Note that we have to do this here in case the base class implementation
+ // (QGraphicsScene::drawItems) is not called. If it is, we'll do this
+ // operation twice, but that's the price one has to pay for using indirect
+ // painting :-/.
+ const QRectF brect = adjustedItemEffectiveBoundingRect(item);
+ if (!itemd->itemIsUntransformable()) {
+ transform = item->sceneTransform();
+ if (viewTransformed)
+ transform *= viewTransform;
+ } else {
+ transform = item->deviceTransform(viewTransform);
+ }
+ itemd->paintedViewBoundingRects.insert(d->viewport, transform.mapRect(brect).toRect());
+ }
+ // Draw the items.
+ drawItems(&painter, numItems, itemArray, styleOptionArray);
+ d->freeStyleOptionsArray(styleOptionArray);
+ }
+ }
+
+ // Foreground
+ drawForeground(&painter, exposedSceneRect);
+
+#ifndef QT_NO_RUBBERBAND
+ // Rubberband
+ if (d->rubberBanding && !d->rubberBandRect.isEmpty()) {
+ painter.restore();
+ QStyleOptionRubberBand option;
+ option.initFrom(viewport());
+ option.rect = d->rubberBandRect;
+ option.shape = QRubberBand::Rectangle;
+
+ QStyleHintReturnMask mask;
+ if (viewport()->style()->styleHint(QStyle::SH_RubberBand_Mask, &option, viewport(), &mask)) {
+ // painter clipping for masked rubberbands
+ painter.setClipRegion(mask.region, Qt::IntersectClip);
+ }
+
+ viewport()->style()->drawControl(QStyle::CE_RubberBand, &option, &painter, viewport());
+ }
+#endif
+
+ painter.end();
+
+ // Restore painter state protection.
+ d->scene->d_func()->painterStateProtection = true;
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsView::resizeEvent(QResizeEvent *event)
+{
+ Q_D(QGraphicsView);
+ // Save the last center point - the resize may scroll the view, which
+ // changes the center point.
+ QPointF oldLastCenterPoint = d->lastCenterPoint;
+
+ QAbstractScrollArea::resizeEvent(event);
+ d->recalculateContentSize();
+
+ // Restore the center point again.
+ if (d->resizeAnchor == NoAnchor && !d->keepLastCenterPoint) {
+ d->updateLastCenterPoint();
+ } else {
+ d->lastCenterPoint = oldLastCenterPoint;
+ }
+ d->centerView(d->resizeAnchor);
+ d->keepLastCenterPoint = false;
+
+ if (d->cacheMode & CacheBackground) {
+ // Invalidate the background pixmap
+ d->mustResizeBackgroundPixmap = true;
+ }
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsView::scrollContentsBy(int dx, int dy)
+{
+ Q_D(QGraphicsView);
+ d->dirtyScroll = true;
+ if (d->transforming)
+ return;
+ if (isRightToLeft())
+ dx = -dx;
+
+ if (d->viewportUpdateMode != QGraphicsView::NoViewportUpdate) {
+ if (d->viewportUpdateMode != QGraphicsView::FullViewportUpdate) {
+ if (d->accelerateScrolling) {
+#ifndef QT_NO_RUBBERBAND
+ // 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
+ d->dirtyScrollOffset.rx() += dx;
+ d->dirtyScrollOffset.ry() += dy;
+ d->dirtyRegion.translate(dx, dy);
+ viewport()->scroll(dx, dy);
+ } else {
+ d->updateAll();
+ }
+ } else {
+ d->updateAll();
+ }
+ }
+
+ d->updateLastCenterPoint();
+
+ if ((d->cacheMode & CacheBackground)
+#ifdef Q_WS_X11
+ && X11->use_xrender
+#endif
+ ) {
+ // Scroll the background pixmap
+ QRegion exposed;
+ if (!d->backgroundPixmap.isNull())
+ d->backgroundPixmap.scroll(dx, dy, d->backgroundPixmap.rect(), &exposed);
+
+ // Invalidate the background pixmap
+ d->backgroundPixmapExposed.translate(dx, dy);
+ d->backgroundPixmapExposed += exposed;
+ }
+
+ // Always replay on scroll.
+ if (d->sceneInteractionAllowed)
+ d->replayLastMouseEvent();
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsView::showEvent(QShowEvent *event)
+{
+ Q_D(QGraphicsView);
+ d->recalculateContentSize();
+ d->centerView(d->transformationAnchor);
+ QAbstractScrollArea::showEvent(event);
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsView::inputMethodEvent(QInputMethodEvent *event)
+{
+ Q_D(QGraphicsView);
+ if (d->scene)
+ QApplication::sendEvent(d->scene, event);
+}
+
+/*!
+ Draws the background of the scene using \a painter, before any items and
+ the foreground are drawn. Reimplement this function to provide a custom
+ background for this view.
+
+ If all you want is to define a color, texture or gradient for the
+ background, you can call setBackgroundBrush() instead.
+
+ All painting is done in \e scene coordinates. \a rect is the exposed
+ rectangle.
+
+ The default implementation fills \a rect using the view's backgroundBrush.
+ If no such brush is defined (the default), the scene's drawBackground()
+ function is called instead.
+
+ \sa drawForeground(), QGraphicsScene::drawBackground()
+*/
+void QGraphicsView::drawBackground(QPainter *painter, const QRectF &rect)
+{
+ Q_D(QGraphicsView);
+ if (d->scene && d->backgroundBrush.style() == Qt::NoBrush) {
+ d->scene->drawBackground(painter, rect);
+ return;
+ }
+
+ painter->fillRect(rect, d->backgroundBrush);
+}
+
+/*!
+ Draws the foreground of the scene using \a painter, after the background
+ and all items are drawn. Reimplement this function to provide a custom
+ foreground for this view.
+
+ If all you want is to define a color, texture or gradient for the
+ foreground, you can call setForegroundBrush() instead.
+
+ All painting is done in \e scene coordinates. \a rect is the exposed
+ rectangle.
+
+ The default implementation fills \a rect using the view's foregroundBrush.
+ If no such brush is defined (the default), the scene's drawForeground()
+ function is called instead.
+
+ \sa drawBackground(), QGraphicsScene::drawForeground()
+*/
+void QGraphicsView::drawForeground(QPainter *painter, const QRectF &rect)
+{
+ Q_D(QGraphicsView);
+ if (d->scene && d->foregroundBrush.style() == Qt::NoBrush) {
+ d->scene->drawForeground(painter, rect);
+ return;
+ }
+
+ painter->fillRect(rect, d->foregroundBrush);
+}
+
+/*!
+ \obsolete
+
+ Draws the items \a items in the scene using \a painter, after the
+ background and before the foreground are drawn. \a numItems is the number
+ of items in \a items and options in \a options. \a options is a list of
+ styleoptions; one for each item. Reimplement this function to provide
+ custom item drawing for this view.
+
+ The default implementation calls the scene's drawItems() function.
+
+ Since Qt 4.6, this function is not called anymore unless
+ the QGraphicsView::IndirectPainting flag is given as an Optimization
+ flag.
+
+ \sa drawForeground(), drawBackground(), QGraphicsScene::drawItems()
+*/
+void QGraphicsView::drawItems(QPainter *painter, int numItems,
+ QGraphicsItem *items[],
+ const QStyleOptionGraphicsItem options[])
+{
+ Q_D(QGraphicsView);
+ if (d->scene) {
+ QWidget *widget = painter->device() == viewport() ? viewport() : 0;
+ d->scene->drawItems(painter, numItems, items, options, widget);
+ }
+}
+
+/*!
+ Returns the current transformation matrix for the view. If no current
+ transformation is set, the identity matrix is returned.
+
+ \sa setTransform(), rotate(), scale(), shear(), translate()
+*/
+QTransform QGraphicsView::transform() const
+{
+ Q_D(const QGraphicsView);
+ return d->matrix;
+}
+
+/*!
+ Returns a matrix that maps viewport coordinates to scene coordinates.
+
+ \sa mapToScene(), mapFromScene()
+*/
+QTransform QGraphicsView::viewportTransform() const
+{
+ Q_D(const QGraphicsView);
+ QTransform moveMatrix = QTransform::fromTranslate(-d->horizontalScroll(), -d->verticalScroll());
+ return d->identityMatrix ? moveMatrix : d->matrix * moveMatrix;
+}
+
+/*!
+ \since 4.6
+
+ Returns true if the view is transformed (i.e., a non-identity transform
+ has been assigned, or the scrollbars are adjusted).
+
+ \sa setTransform(), horizontalScrollBar(), verticalScrollBar()
+*/
+bool QGraphicsView::isTransformed() const
+{
+ Q_D(const QGraphicsView);
+ return !d->identityMatrix || d->horizontalScroll() || d->verticalScroll();
+}
+
+/*!
+ Sets the view's current transformation matrix to \a matrix.
+
+ If \a combine is true, then \a matrix is combined with the current matrix;
+ otherwise, \a matrix \e replaces the current matrix. \a combine is false
+ by default.
+
+ The transformation matrix tranforms the scene into view coordinates. Using
+ the default transformation, provided by the identity matrix, one pixel in
+ the view represents one unit in the scene (e.g., a 10x10 rectangular item
+ is drawn using 10x10 pixels in the view). If a 2x2 scaling matrix is
+ applied, the scene will be drawn in 1:2 (e.g., a 10x10 rectangular item is
+ then drawn using 20x20 pixels in the view).
+
+ Example:
+
+ \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsview.cpp 7
+
+ To simplify interation with items using a transformed view, QGraphicsView
+ provides mapTo... and mapFrom... functions that can translate between
+ scene and view coordinates. For example, you can call mapToScene() to map
+ a view coordiate to a floating point scene coordinate, or mapFromScene()
+ to map from floating point scene coordinates to view coordinates.
+
+ \sa transform(), rotate(), scale(), shear(), translate()
+*/
+void QGraphicsView::setTransform(const QTransform &matrix, bool combine )
+{
+ Q_D(QGraphicsView);
+ QTransform oldMatrix = d->matrix;
+ if (!combine)
+ d->matrix = matrix;
+ else
+ d->matrix = matrix * d->matrix;
+ if (oldMatrix == d->matrix)
+ return;
+
+ d->identityMatrix = d->matrix.isIdentity();
+ d->transforming = true;
+ if (d->scene) {
+ d->recalculateContentSize();
+ d->centerView(d->transformationAnchor);
+ } else {
+ d->updateLastCenterPoint();
+ }
+
+ if (d->sceneInteractionAllowed)
+ d->replayLastMouseEvent();
+ d->transforming = false;
+
+ // Any matrix operation requires a full update.
+ d->updateAll();
+}
+
+/*!
+ Resets the view transformation to the identity matrix.
+
+ \sa transform(), setTransform()
+*/
+void QGraphicsView::resetTransform()
+{
+ setTransform(QTransform());
+}
+
+QPointF QGraphicsViewPrivate::mapToScene(const QPointF &point) const
+{
+ QPointF p = point;
+ p.rx() += horizontalScroll();
+ p.ry() += verticalScroll();
+ return identityMatrix ? p : matrix.inverted().map(p);
+}
+
+QRectF QGraphicsViewPrivate::mapToScene(const QRectF &rect) const
+{
+ QPointF scrollOffset(horizontalScroll(), verticalScroll());
+ QPointF tl = scrollOffset + rect.topLeft();
+ QPointF tr = scrollOffset + rect.topRight();
+ QPointF br = scrollOffset + rect.bottomRight();
+ QPointF bl = scrollOffset + rect.bottomLeft();
+
+ QPolygonF poly(4);
+ if (!identityMatrix) {
+ QTransform x = matrix.inverted();
+ poly[0] = x.map(tl);
+ poly[1] = x.map(tr);
+ poly[2] = x.map(br);
+ poly[3] = x.map(bl);
+ } else {
+ poly[0] = tl;
+ poly[1] = tr;
+ poly[2] = br;
+ poly[3] = bl;
+ }
+ return poly.boundingRect();
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qgraphicsview.cpp"
+
+#endif // QT_NO_GRAPHICSVIEW
diff --git a/src/widgets/graphicsview/qgraphicsview.h b/src/widgets/graphicsview/qgraphicsview.h
new file mode 100644
index 0000000000..19b5753938
--- /dev/null
+++ b/src/widgets/graphicsview/qgraphicsview.h
@@ -0,0 +1,316 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGRAPHICSVIEW_H
+#define QGRAPHICSVIEW_H
+
+#include <QtCore/qmetatype.h>
+#include <QtGui/qpainter.h>
+#include <QtWidgets/qscrollarea.h>
+#include <QtWidgets/qgraphicsscene.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW
+
+class QGraphicsItem;
+class QPainterPath;
+class QPolygonF;
+class QStyleOptionGraphicsItem;
+
+class QGraphicsViewPrivate;
+class Q_WIDGETS_EXPORT QGraphicsView : public QAbstractScrollArea
+{
+ Q_OBJECT
+ Q_FLAGS(QPainter::RenderHints CacheMode OptimizationFlags)
+ Q_ENUMS(ViewportAnchor DragMode ViewportUpdateMode)
+ Q_PROPERTY(QBrush backgroundBrush READ backgroundBrush WRITE setBackgroundBrush)
+ Q_PROPERTY(QBrush foregroundBrush READ foregroundBrush WRITE setForegroundBrush)
+ Q_PROPERTY(bool interactive READ isInteractive WRITE setInteractive)
+ Q_PROPERTY(QRectF sceneRect READ sceneRect WRITE setSceneRect)
+ Q_PROPERTY(Qt::Alignment alignment READ alignment WRITE setAlignment)
+ Q_PROPERTY(QPainter::RenderHints renderHints READ renderHints WRITE setRenderHints)
+ Q_PROPERTY(DragMode dragMode READ dragMode WRITE setDragMode)
+ Q_PROPERTY(CacheMode cacheMode READ cacheMode WRITE setCacheMode)
+ Q_PROPERTY(ViewportAnchor transformationAnchor READ transformationAnchor WRITE setTransformationAnchor)
+ Q_PROPERTY(ViewportAnchor resizeAnchor READ resizeAnchor WRITE setResizeAnchor)
+ Q_PROPERTY(ViewportUpdateMode viewportUpdateMode READ viewportUpdateMode WRITE setViewportUpdateMode)
+#ifndef QT_NO_RUBBERBAND
+ Q_PROPERTY(Qt::ItemSelectionMode rubberBandSelectionMode READ rubberBandSelectionMode WRITE setRubberBandSelectionMode)
+#endif
+ Q_PROPERTY(OptimizationFlags optimizationFlags READ optimizationFlags WRITE setOptimizationFlags)
+
+public:
+ enum ViewportAnchor {
+ NoAnchor,
+ AnchorViewCenter,
+ AnchorUnderMouse
+ };
+
+ enum CacheModeFlag {
+ CacheNone = 0x0,
+ CacheBackground = 0x1
+ };
+ Q_DECLARE_FLAGS(CacheMode, CacheModeFlag)
+
+ enum DragMode {
+ NoDrag,
+ ScrollHandDrag,
+ RubberBandDrag
+ };
+
+ enum ViewportUpdateMode {
+ FullViewportUpdate,
+ MinimalViewportUpdate,
+ SmartViewportUpdate,
+ NoViewportUpdate,
+ BoundingRectViewportUpdate
+ };
+
+ enum OptimizationFlag {
+ DontClipPainter = 0x1, // obsolete
+ DontSavePainterState = 0x2,
+ DontAdjustForAntialiasing = 0x4,
+ IndirectPainting = 0x8
+ };
+ Q_DECLARE_FLAGS(OptimizationFlags, OptimizationFlag)
+
+ QGraphicsView(QWidget *parent = 0);
+ QGraphicsView(QGraphicsScene *scene, QWidget *parent = 0);
+ ~QGraphicsView();
+
+ QSize sizeHint() const;
+
+ QPainter::RenderHints renderHints() const;
+ void setRenderHint(QPainter::RenderHint hint, bool enabled = true);
+ void setRenderHints(QPainter::RenderHints hints);
+
+ Qt::Alignment alignment() const;
+ void setAlignment(Qt::Alignment alignment);
+
+ ViewportAnchor transformationAnchor() const;
+ void setTransformationAnchor(ViewportAnchor anchor);
+
+ ViewportAnchor resizeAnchor() const;
+ void setResizeAnchor(ViewportAnchor anchor);
+
+ ViewportUpdateMode viewportUpdateMode() const;
+ void setViewportUpdateMode(ViewportUpdateMode mode);
+
+ OptimizationFlags optimizationFlags() const;
+ void setOptimizationFlag(OptimizationFlag flag, bool enabled = true);
+ void setOptimizationFlags(OptimizationFlags flags);
+
+ DragMode dragMode() const;
+ void setDragMode(DragMode mode);
+
+#ifndef QT_NO_RUBBERBAND
+ Qt::ItemSelectionMode rubberBandSelectionMode() const;
+ void setRubberBandSelectionMode(Qt::ItemSelectionMode mode);
+#endif
+
+ CacheMode cacheMode() const;
+ void setCacheMode(CacheMode mode);
+ void resetCachedContent();
+
+ bool isInteractive() const;
+ void setInteractive(bool allowed);
+
+ QGraphicsScene *scene() const;
+ void setScene(QGraphicsScene *scene);
+
+ QRectF sceneRect() const;
+ void setSceneRect(const QRectF &rect);
+ inline void setSceneRect(qreal x, qreal y, qreal w, qreal h);
+
+ QMatrix matrix() const;
+ void setMatrix(const QMatrix &matrix, bool combine = false);
+ void resetMatrix();
+ QTransform transform() const;
+ QTransform viewportTransform() const;
+ bool isTransformed() const;
+ void setTransform(const QTransform &matrix, bool combine = false);
+ void resetTransform();
+ void rotate(qreal angle);
+ void scale(qreal sx, qreal sy);
+ void shear(qreal sh, qreal sv);
+ void translate(qreal dx, qreal dy);
+
+ void centerOn(const QPointF &pos);
+ inline void centerOn(qreal x, qreal y);
+ void centerOn(const QGraphicsItem *item);
+ void ensureVisible(const QRectF &rect, int xmargin = 50, int ymargin = 50);
+ inline void ensureVisible(qreal x, qreal y, qreal w, qreal h, int xmargin = 50, int ymargin = 50);
+ void ensureVisible(const QGraphicsItem *item, int xmargin = 50, int ymargin = 50);
+ void fitInView(const QRectF &rect, Qt::AspectRatioMode aspectRadioMode = Qt::IgnoreAspectRatio);
+ inline void fitInView(qreal x, qreal y, qreal w, qreal h,
+ Qt::AspectRatioMode aspectRadioMode = Qt::IgnoreAspectRatio);
+ void fitInView(const QGraphicsItem *item,
+ Qt::AspectRatioMode aspectRadioMode = Qt::IgnoreAspectRatio);
+
+ void render(QPainter *painter, const QRectF &target = QRectF(), const QRect &source = QRect(),
+ Qt::AspectRatioMode aspectRatioMode = Qt::KeepAspectRatio);
+
+ QList<QGraphicsItem *> items() const;
+ QList<QGraphicsItem *> items(const QPoint &pos) const;
+ inline QList<QGraphicsItem *> items(int x, int y) const;
+ QList<QGraphicsItem *> items(const QRect &rect, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const;
+ inline QList<QGraphicsItem *> items(int x, int y, int w, int h, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const;
+ QList<QGraphicsItem *> items(const QPolygon &polygon, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const;
+ QList<QGraphicsItem *> items(const QPainterPath &path, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const;
+ QGraphicsItem *itemAt(const QPoint &pos) const;
+ inline QGraphicsItem *itemAt(int x, int y) const;
+
+ QPointF mapToScene(const QPoint &point) const;
+ QPolygonF mapToScene(const QRect &rect) const;
+ QPolygonF mapToScene(const QPolygon &polygon) const;
+ QPainterPath mapToScene(const QPainterPath &path) const;
+ QPoint mapFromScene(const QPointF &point) const;
+ QPolygon mapFromScene(const QRectF &rect) const;
+ QPolygon mapFromScene(const QPolygonF &polygon) const;
+ QPainterPath mapFromScene(const QPainterPath &path) const;
+ inline QPointF mapToScene(int x, int y) const;
+ inline QPolygonF mapToScene(int x, int y, int w, int h) const;
+ inline QPoint mapFromScene(qreal x, qreal y) const;
+ inline QPolygon mapFromScene(qreal x, qreal y, qreal w, qreal h) const;
+
+ QVariant inputMethodQuery(Qt::InputMethodQuery query) const;
+
+ QBrush backgroundBrush() const;
+ void setBackgroundBrush(const QBrush &brush);
+
+ QBrush foregroundBrush() const;
+ void setForegroundBrush(const QBrush &brush);
+
+public Q_SLOTS:
+ void updateScene(const QList<QRectF> &rects);
+ void invalidateScene(const QRectF &rect = QRectF(), QGraphicsScene::SceneLayers layers = QGraphicsScene::AllLayers);
+ void updateSceneRect(const QRectF &rect);
+
+protected Q_SLOTS:
+ void setupViewport(QWidget *widget);
+
+protected:
+ QGraphicsView(QGraphicsViewPrivate &, QWidget *parent = 0);
+ bool event(QEvent *event);
+ bool viewportEvent(QEvent *event);
+
+#ifndef QT_NO_CONTEXTMENU
+ void contextMenuEvent(QContextMenuEvent *event);
+#endif
+ void dragEnterEvent(QDragEnterEvent *event);
+ void dragLeaveEvent(QDragLeaveEvent *event);
+ void dragMoveEvent(QDragMoveEvent *event);
+ void dropEvent(QDropEvent *event);
+ void focusInEvent(QFocusEvent *event);
+ bool focusNextPrevChild(bool next);
+ void focusOutEvent(QFocusEvent *event);
+ void keyPressEvent(QKeyEvent *event);
+ void keyReleaseEvent(QKeyEvent *event);
+ void mouseDoubleClickEvent(QMouseEvent *event);
+ void mousePressEvent(QMouseEvent *event);
+ void mouseMoveEvent(QMouseEvent *event);
+ void mouseReleaseEvent(QMouseEvent *event);
+#ifndef QT_NO_WHEELEVENT
+ void wheelEvent(QWheelEvent *event);
+#endif
+ void paintEvent(QPaintEvent *event);
+ void resizeEvent(QResizeEvent *event);
+ void scrollContentsBy(int dx, int dy);
+ void showEvent(QShowEvent *event);
+ void inputMethodEvent(QInputMethodEvent *event);
+
+ virtual void drawBackground(QPainter *painter, const QRectF &rect);
+ virtual void drawForeground(QPainter *painter, const QRectF &rect);
+ virtual void drawItems(QPainter *painter, int numItems,
+ QGraphicsItem *items[],
+ const QStyleOptionGraphicsItem options[]);
+
+private:
+ Q_DECLARE_PRIVATE(QGraphicsView)
+ Q_DISABLE_COPY(QGraphicsView)
+#ifndef QT_NO_CURSOR
+ Q_PRIVATE_SLOT(d_func(), void _q_setViewportCursor(const QCursor &))
+ Q_PRIVATE_SLOT(d_func(), void _q_unsetViewportCursor())
+#endif
+ friend class QGraphicsSceneWidget;
+ friend class QGraphicsScene;
+ friend class QGraphicsScenePrivate;
+ friend class QGraphicsItemPrivate;
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QGraphicsView::CacheMode)
+Q_DECLARE_OPERATORS_FOR_FLAGS(QGraphicsView::OptimizationFlags)
+
+inline void QGraphicsView::setSceneRect(qreal ax, qreal ay, qreal aw, qreal ah)
+{ setSceneRect(QRectF(ax, ay, aw, ah)); }
+inline void QGraphicsView::centerOn(qreal ax, qreal ay)
+{ centerOn(QPointF(ax, ay)); }
+inline void QGraphicsView::ensureVisible(qreal ax, qreal ay, qreal aw, qreal ah, int xmargin, int ymargin)
+{ ensureVisible(QRectF(ax, ay, aw, ah), xmargin, ymargin); }
+inline void QGraphicsView::fitInView(qreal ax, qreal ay, qreal w, qreal h, Qt::AspectRatioMode mode)
+{ fitInView(QRectF(ax, ay, w, h), mode); }
+inline QList<QGraphicsItem *> QGraphicsView::items(int ax, int ay) const
+{ return items(QPoint(ax, ay)); }
+inline QList<QGraphicsItem *> QGraphicsView::items(int ax, int ay, int w, int h, Qt::ItemSelectionMode mode) const
+{ return items(QRect(ax, ay, w, h), mode); }
+inline QGraphicsItem *QGraphicsView::itemAt(int ax, int ay) const
+{ return itemAt(QPoint(ax, ay)); }
+inline QPointF QGraphicsView::mapToScene(int ax, int ay) const
+{ return mapToScene(QPoint(ax, ay)); }
+inline QPolygonF QGraphicsView::mapToScene(int ax, int ay, int w, int h) const
+{ return mapToScene(QRect(ax, ay, w, h)); }
+inline QPoint QGraphicsView::mapFromScene(qreal ax, qreal ay) const
+{ return mapFromScene(QPointF(ax, ay)); }
+inline QPolygon QGraphicsView::mapFromScene(qreal ax, qreal ay, qreal w, qreal h) const
+{ return mapFromScene(QRectF(ax, ay, w, h)); }
+
+#endif // QT_NO_GRAPHICSVIEW
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QGRAPHICSVIEW_H
diff --git a/src/widgets/graphicsview/qgraphicsview_p.h b/src/widgets/graphicsview/qgraphicsview_p.h
new file mode 100644
index 0000000000..535679f1d8
--- /dev/null
+++ b/src/widgets/graphicsview/qgraphicsview_p.h
@@ -0,0 +1,233 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGRAPHICSVIEW_P_H
+#define QGRAPHICSVIEW_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qgraphicsview.h"
+
+#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW
+
+#include <QtGui/qevent.h>
+#include <QtCore/qcoreapplication.h>
+#include "qgraphicssceneevent.h"
+#include <QtWidgets/qstyleoption.h>
+#include <private/qabstractscrollarea_p.h>
+#include <private/qapplication_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class Q_WIDGETS_EXPORT QGraphicsViewPrivate : public QAbstractScrollAreaPrivate
+{
+ Q_DECLARE_PUBLIC(QGraphicsView)
+public:
+ QGraphicsViewPrivate();
+
+ void recalculateContentSize();
+ void centerView(QGraphicsView::ViewportAnchor anchor);
+
+ QPainter::RenderHints renderHints;
+
+ QGraphicsView::DragMode dragMode;
+
+ quint32 sceneInteractionAllowed : 1;
+ quint32 hasSceneRect : 1;
+ quint32 connectedToScene : 1;
+ quint32 useLastMouseEvent : 1;
+ quint32 identityMatrix : 1;
+ quint32 dirtyScroll : 1;
+ quint32 accelerateScrolling : 1;
+ quint32 keepLastCenterPoint : 1;
+ quint32 transforming : 1;
+ quint32 handScrolling : 1;
+ quint32 mustAllocateStyleOptions : 1;
+ quint32 mustResizeBackgroundPixmap : 1;
+ quint32 fullUpdatePending : 1;
+ quint32 hasUpdateClip : 1;
+ quint32 padding : 18;
+
+ QRectF sceneRect;
+ void updateLastCenterPoint();
+
+ qint64 horizontalScroll() const;
+ qint64 verticalScroll() const;
+
+ QRectF mapRectToScene(const QRect &rect) const;
+ QRectF mapRectFromScene(const QRectF &rect) const;
+
+ QRect updateClip;
+ QPointF mousePressItemPoint;
+ QPointF mousePressScenePoint;
+ QPoint mousePressViewPoint;
+ QPoint mousePressScreenPoint;
+ QPointF lastMouseMoveScenePoint;
+ QPoint lastMouseMoveScreenPoint;
+ QPoint dirtyScrollOffset;
+ Qt::MouseButton mousePressButton;
+ QTransform matrix;
+ qint64 scrollX, scrollY;
+ void updateScroll();
+
+ qreal leftIndent;
+ qreal topIndent;
+
+ // Replaying mouse events
+ QMouseEvent lastMouseEvent;
+ void replayLastMouseEvent();
+ void storeMouseEvent(QMouseEvent *event);
+ void mouseMoveEventHandler(QMouseEvent *event);
+
+ QPointF lastCenterPoint;
+ Qt::Alignment alignment;
+
+ QGraphicsView::ViewportAnchor transformationAnchor;
+ QGraphicsView::ViewportAnchor resizeAnchor;
+ QGraphicsView::ViewportUpdateMode viewportUpdateMode;
+ QGraphicsView::OptimizationFlags optimizationFlags;
+
+ QPointer<QGraphicsScene> scene;
+#ifndef QT_NO_RUBBERBAND
+ QRect rubberBandRect;
+ QRegion rubberBandRegion(const QWidget *widget, const QRect &rect) const;
+ bool rubberBanding;
+ Qt::ItemSelectionMode rubberBandSelectionMode;
+#endif
+ int handScrollMotions;
+
+ QGraphicsView::CacheMode cacheMode;
+
+ QVector<QStyleOptionGraphicsItem> styleOptions;
+ QStyleOptionGraphicsItem *allocStyleOptionsArray(int numItems);
+ void freeStyleOptionsArray(QStyleOptionGraphicsItem *array);
+
+ QBrush backgroundBrush;
+ QBrush foregroundBrush;
+ QPixmap backgroundPixmap;
+ QRegion backgroundPixmapExposed;
+
+#ifndef QT_NO_CURSOR
+ QCursor originalCursor;
+ bool hasStoredOriginalCursor;
+ void _q_setViewportCursor(const QCursor &cursor);
+ void _q_unsetViewportCursor();
+#endif
+
+ QGraphicsSceneDragDropEvent *lastDragDropEvent;
+ void storeDragDropEvent(const QGraphicsSceneDragDropEvent *event);
+ void populateSceneDragDropEvent(QGraphicsSceneDragDropEvent *dest,
+ QDropEvent *source);
+
+ QRect mapToViewRect(const QGraphicsItem *item, const QRectF &rect) const;
+ QRegion mapToViewRegion(const QGraphicsItem *item, const QRectF &rect) const;
+ QRegion dirtyRegion;
+ QRect dirtyBoundingRect;
+ void processPendingUpdates();
+ inline void updateAll()
+ {
+ viewport->update();
+ fullUpdatePending = true;
+ dirtyBoundingRect = QRect();
+ dirtyRegion = QRegion();
+ }
+
+ inline void dispatchPendingUpdateRequests()
+ {
+#ifdef Q_WS_MAC
+ // QWidget::update() works slightly different on the Mac without the raster engine;
+ // it's not part of our backing store so it needs special threatment.
+ if (QApplicationPrivate::graphics_system_name != QLatin1String("raster")) {
+ // At this point either HIViewSetNeedsDisplay (Carbon) or setNeedsDisplay: YES (Cocoa)
+ // is called, which means there's a pending update request. We want to dispatch it
+ // now because otherwise graphics view updates would require two
+ // round-trips in the event loop before the item is painted.
+ extern void qt_mac_dispatchPendingUpdateRequests(QWidget *);
+ qt_mac_dispatchPendingUpdateRequests(viewport->window());
+ } else
+#endif // !Q_WS_MAC
+ {
+ if (qt_widget_private(viewport)->paintOnScreen())
+ QCoreApplication::sendPostedEvents(viewport, QEvent::UpdateRequest);
+ else
+ QCoreApplication::sendPostedEvents(viewport->window(), QEvent::UpdateRequest);
+ }
+ }
+
+ void setUpdateClip(QGraphicsItem *);
+
+ inline bool updateRectF(const QRectF &rect)
+ {
+ if (rect.isEmpty())
+ return false;
+ if (optimizationFlags & QGraphicsView::DontAdjustForAntialiasing)
+ return updateRect(rect.toAlignedRect().adjusted(-1, -1, 1, 1));
+ return updateRect(rect.toAlignedRect().adjusted(-2, -2, 2, 2));
+ }
+
+ bool updateRect(const QRect &rect);
+ bool updateRegion(const QRectF &rect, const QTransform &xform);
+ bool updateSceneSlotReimplementedChecked;
+ QRegion exposedRegion;
+
+ QList<QGraphicsItem *> findItems(const QRegion &exposedRegion, bool *allItems,
+ const QTransform &viewTransform) const;
+
+ QPointF mapToScene(const QPointF &point) const;
+ QRectF mapToScene(const QRectF &rect) const;
+ static void translateTouchEvent(QGraphicsViewPrivate *d, QTouchEvent *touchEvent);
+ void updateInputMethodSensitivity();
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_GRAPHICSVIEW
+
+#endif
diff --git a/src/widgets/graphicsview/qgraphicswidget.cpp b/src/widgets/graphicsview/qgraphicswidget.cpp
new file mode 100644
index 0000000000..813fe9f505
--- /dev/null
+++ b/src/widgets/graphicsview/qgraphicswidget.cpp
@@ -0,0 +1,2425 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qglobal.h"
+
+#ifndef QT_NO_GRAPHICSVIEW
+
+#include "qgraphicswidget.h"
+#include "qgraphicswidget_p.h"
+#include "qgraphicslayout.h"
+#include "qgraphicslayout_p.h"
+#include "qgraphicsscene.h"
+#include "qgraphicssceneevent.h"
+
+#ifndef QT_NO_ACTION
+#include <private/qaction_p.h>
+#endif
+#include <private/qapplication_p.h>
+#include <private/qgraphicsscene_p.h>
+#ifndef QT_NO_SHORTCUT
+#include <private/qshortcutmap_p.h>
+#endif
+#include <QtCore/qmutex.h>
+#include <QtWidgets/qapplication.h>
+#include <QtWidgets/qgraphicsview.h>
+#include <QtWidgets/qgraphicsproxywidget.h>
+#include <QtGui/qpalette.h>
+#include <QtWidgets/qstyleoption.h>
+
+#include <qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QGraphicsWidget
+ \brief The QGraphicsWidget class is the base class for all widget
+ items in a QGraphicsScene.
+ \since 4.4
+ \ingroup graphicsview-api
+
+ QGraphicsWidget is an extended base item that provides extra functionality
+ over QGraphicsItem. It is similar to QWidget in many ways:
+
+ \list
+ \o Provides a \l palette, a \l font and a \l style().
+ \o Has a defined geometry().
+ \o Supports layouts with setLayout() and layout().
+ \o Supports shortcuts and actions with grabShortcut() and insertAction()
+ \endlist
+
+ Unlike QGraphicsItem, QGraphicsWidget is not an abstract class; you can
+ create instances of a QGraphicsWidget without having to subclass it.
+ This approach is useful for widgets that only serve the purpose of
+ organizing child widgets into a layout.
+
+ QGraphicsWidget can be used as a base item for your own custom item if
+ you require advanced input focus handling, e.g., tab focus and activation, or
+ layouts.
+
+ Since QGraphicsWidget resembles QWidget and has similar API, it is
+ easier to port a widget from QWidget to QGraphicsWidget, instead of
+ QGraphicsItem.
+
+ \note QWidget-based widgets can be directly embedded into a
+ QGraphicsScene using QGraphicsProxyWidget.
+
+ Noticeable differences between QGraphicsWidget and QWidget are:
+
+ \table
+ \header \o QGraphicsWidget
+ \o QWidget
+ \row \o Coordinates and geometry are defined with qreals (doubles or
+ floats, depending on the platform).
+ \o QWidget uses integer geometry (QPoint, QRect).
+ \row \o The widget is already visible by default; you do not have to
+ call show() to display the widget.
+ \o QWidget is hidden by default until you call show().
+ \row \o A subset of widget attributes are supported.
+ \o All widget attributes are supported.
+ \row \o A top-level item's style defaults to QGraphicsScene::style
+ \o A top-level widget's style defaults to QApplication::style
+ \row \o Graphics View provides a custom drag and drop framework, different
+ from QWidget.
+ \o Standard drag and drop framework.
+ \row \o Widget items do not support modality.
+ \o Full modality support.
+ \endtable
+
+ QGraphicsWidget supports a subset of Qt's widget attributes,
+ (Qt::WidgetAttribute), as shown in the table below. Any attributes not
+ listed in this table are unsupported, or otherwise unused.
+
+ \table
+ \header \o Widget Attribute \o Usage
+ \row \o Qt::WA_SetLayoutDirection
+ \o Set by setLayoutDirection(), cleared by
+ unsetLayoutDirection(). You can test this attribute to
+ check if the widget has been explicitly assigned a
+ \l{QGraphicsWidget::layoutDirection()}
+ {layoutDirection}. If the attribute is not set, the
+ \l{QGraphicsWidget::layoutDirection()}
+ {layoutDirection()} is inherited.
+ \row \o Qt::WA_RightToLeft
+ \o Toggled by setLayoutDirection(). Inherited from the
+ parent/scene. If set, the widget's layout will order
+ horizontally arranged widgets from right to left.
+ \row \o Qt::WA_SetStyle
+ \o Set and cleared by setStyle(). If this attribute is
+ set, the widget has been explicitly assigned a style.
+ If it is unset, the widget will use the scene's or the
+ application's style.
+ \row \o Qt::WA_Resized
+ \o Set by setGeometry() and resize().
+ \row \o Qt::WA_SetPalette
+ \o Set by setPalette().
+ \row \o Qt::WA_SetFont
+ \o Set by setPalette().
+ \row \o Qt::WA_WindowPropagation
+ \o Enables propagation to window widgets.
+ \endtable
+
+ Although QGraphicsWidget inherits from both QObject and QGraphicsItem,
+ you should use the functions provided by QGraphicsItem, \e not QObject, to
+ manage the relationships between parent and child items. These functions
+ control the stacking order of items as well as their ownership.
+
+ \note The QObject::parent() should always return 0 for QGraphicsWidgets,
+ but this policy is not strictly defined.
+
+ \sa QGraphicsProxyWidget, QGraphicsItem, {Widgets and Layouts}
+*/
+
+/*!
+ Constructs a QGraphicsWidget instance. The optional \a parent argument is
+ passed to QGraphicsItem's constructor. The optional \a wFlags argument
+ specifies the widget's window flags (e.g., whether the widget should be a
+ window, a tool, a popup, etc).
+*/
+QGraphicsWidget::QGraphicsWidget(QGraphicsItem *parent, Qt::WindowFlags wFlags)
+ : QGraphicsObject(*new QGraphicsWidgetPrivate, 0, 0), QGraphicsLayoutItem(0, false)
+{
+ Q_D(QGraphicsWidget);
+ d->init(parent, wFlags);
+}
+
+/*!
+ \internal
+
+ Constructs a new QGraphicsWidget, using \a dd as parent.
+*/
+QGraphicsWidget::QGraphicsWidget(QGraphicsWidgetPrivate &dd, QGraphicsItem *parent, QGraphicsScene *scene, Qt::WindowFlags wFlags)
+ : QGraphicsObject(dd, 0, scene), QGraphicsLayoutItem(0, false)
+{
+ Q_D(QGraphicsWidget);
+ d->init(parent, wFlags);
+}
+
+/*
+ \internal
+ \class QGraphicsWidgetStyles
+
+ We use this thread-safe class to maintain a hash of styles for widgets
+ styles. Note that QApplication::style() itself isn't thread-safe, QStyle
+ isn't thread-safe, and we don't have a thread-safe factory for creating
+ the default style, nor cloning a style.
+*/
+class QGraphicsWidgetStyles
+{
+public:
+ QStyle *styleForWidget(const QGraphicsWidget *widget) const
+ {
+ QMutexLocker locker(&mutex);
+ return styles.value(widget, 0);
+ }
+
+ void setStyleForWidget(QGraphicsWidget *widget, QStyle *style)
+ {
+ QMutexLocker locker(&mutex);
+ if (style)
+ styles[widget] = style;
+ else
+ styles.remove(widget);
+ }
+
+private:
+ QMap<const QGraphicsWidget *, QStyle *> styles;
+ mutable QMutex mutex;
+};
+Q_GLOBAL_STATIC(QGraphicsWidgetStyles, widgetStyles)
+
+/*!
+ Destroys the QGraphicsWidget instance.
+*/
+QGraphicsWidget::~QGraphicsWidget()
+{
+ Q_D(QGraphicsWidget);
+#ifndef QT_NO_ACTION
+ // Remove all actions from this widget
+ for (int i = 0; i < d->actions.size(); ++i) {
+ QActionPrivate *apriv = d->actions.at(i)->d_func();
+ apriv->graphicsWidgets.removeAll(this);
+ }
+ d->actions.clear();
+#endif
+
+ if (QGraphicsScene *scn = scene()) {
+ QGraphicsScenePrivate *sceneD = scn->d_func();
+ if (sceneD->tabFocusFirst == this)
+ sceneD->tabFocusFirst = (d->focusNext == this ? 0 : d->focusNext);
+ }
+ d->focusPrev->d_func()->focusNext = d->focusNext;
+ d->focusNext->d_func()->focusPrev = d->focusPrev;
+
+ // Play it really safe
+ d->focusNext = this;
+ d->focusPrev = this;
+
+ clearFocus();
+
+ //we check if we have a layout previously
+ if (d->layout) {
+ QGraphicsLayout *temp = d->layout;
+ foreach (QGraphicsItem * item, childItems()) {
+ // In case of a custom layout which doesn't remove and delete items, we ensure that
+ // the parent layout item does not point to the deleted layout. This code is here to
+ // avoid regression from 4.4 to 4.5, because according to 4.5 docs it is not really needed.
+ if (item->isWidget()) {
+ QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(item);
+ if (widget->parentLayoutItem() == d->layout)
+ widget->setParentLayoutItem(0);
+ }
+ }
+ d->layout = 0;
+ delete temp;
+ }
+
+ // Remove this graphics widget from widgetStyles
+ widgetStyles()->setStyleForWidget(this, 0);
+}
+
+/*!
+ \property QGraphicsWidget::size
+ \brief the size of the widget
+
+ Calling resize() resizes the widget to a \a size bounded by minimumSize()
+ and maximumSize(). This property only affects the widget's width and
+ height (e.g., its right and bottom edges); the widget's position and
+ top-left corner remains unaffected.
+
+ Resizing a widget triggers the widget to immediately receive a
+ \l{QEvent::GraphicsSceneResize}{GraphicsSceneResize} event with the
+ widget's old and new size. If the widget has a layout assigned when this
+ event arrives, the layout will be activated and it will automatically
+ update any child widgets's geometry.
+
+ This property does not affect any layout of the parent widget. If the
+ widget itself is managed by a parent layout; e.g., it has a parent widget
+ with a layout assigned, that layout will not activate.
+
+ By default, this property contains a size with zero width and height.
+
+ \sa setGeometry(), QGraphicsSceneResizeEvent, QGraphicsLayout
+*/
+QSizeF QGraphicsWidget::size() const
+{
+ return QGraphicsLayoutItem::geometry().size();
+}
+
+void QGraphicsWidget::resize(const QSizeF &size)
+{
+ setGeometry(QRectF(pos(), size));
+}
+
+/*!
+ \fn void QGraphicsWidget::resize(qreal w, qreal h)
+
+ This convenience function is equivalent to calling resize(QSizeF(w, h)).
+
+ \sa setGeometry(), setTransform()
+*/
+
+/*!
+ \property QGraphicsWidget::sizePolicy
+ \brief the size policy for the widget
+ \sa sizePolicy(), setSizePolicy(), QWidget::sizePolicy()
+*/
+
+/*!
+ \fn QGraphicsWidget::geometryChanged()
+
+ This signal gets emitted whenever the geometry is changed in setGeometry().
+*/
+
+/*!
+ \property QGraphicsWidget::geometry
+ \brief the geometry of the widget
+
+ Sets the item's geometry to \a rect. The item's position and size are
+ modified as a result of calling this function. The item is first moved,
+ then resized.
+
+ A side effect of calling this function is that the widget will receive
+ a move event and a resize event. Also, if the widget has a layout
+ assigned, the layout will activate.
+
+ \sa geometry(), resize()
+*/
+void QGraphicsWidget::setGeometry(const QRectF &rect)
+{
+ QGraphicsWidgetPrivate *wd = QGraphicsWidget::d_func();
+ QGraphicsLayoutItemPrivate *d = QGraphicsLayoutItem::d_ptr.data();
+ QRectF newGeom;
+ QPointF oldPos = d->geom.topLeft();
+ 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) {
+ goto relayoutChildrenAndReturn;
+ }
+
+ // setPos triggers ItemPositionChange, which can adjust position
+ wd->inSetGeometry = 1;
+ setPos(newGeom.topLeft());
+ wd->inSetGeometry = 0;
+ newGeom.moveTopLeft(pos());
+
+ if (newGeom == d->geom) {
+ goto relayoutChildrenAndReturn;
+ }
+
+ // 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();
+ if (moved) {
+ // Send move event.
+ QGraphicsSceneMoveEvent event;
+ event.setOldPos(oldPos);
+ event.setNewPos(pos());
+ QApplication::sendEvent(this, &event);
+ if (wd->inSetPos) {
+ //set the new pos
+ d->geom.moveTopLeft(pos());
+ emit geometryChanged();
+ goto relayoutChildrenAndReturn;
+ }
+ }
+ QSizeF oldSize = size();
+ QGraphicsLayoutItem::setGeometry(newGeom);
+ // Send resize event
+ bool resized = newGeom.size() != oldSize;
+ if (resized) {
+ QGraphicsSceneResizeEvent re;
+ re.setOldSize(oldSize);
+ re.setNewSize(newGeom.size());
+ if (oldSize.width() != newGeom.size().width())
+ emit widthChanged();
+ if (oldSize.height() != newGeom.size().height())
+ emit heightChanged();
+ QGraphicsLayout *lay = wd->layout;
+ if (QGraphicsLayout::instantInvalidatePropagation()) {
+ if (!lay || lay->isActivated()) {
+ QApplication::sendEvent(this, &re);
+ }
+ } else {
+ QApplication::sendEvent(this, &re);
+ }
+ }
+ }
+
+ emit geometryChanged();
+relayoutChildrenAndReturn:
+ if (QGraphicsLayout::instantInvalidatePropagation()) {
+ if (QGraphicsLayout *lay = wd->layout) {
+ if (!lay->isActivated()) {
+ QEvent layoutRequest(QEvent::LayoutRequest);
+ QApplication::sendEvent(this, &layoutRequest);
+ }
+ }
+ }
+}
+
+/*!
+ \fn QRectF QGraphicsWidget::rect() const
+
+ Returns the item's local rect as a QRectF. This function is equivalent
+ to QRectF(QPointF(), size()).
+
+ \sa setGeometry(), resize()
+*/
+
+/*!
+ \fn void QGraphicsWidget::setGeometry(qreal x, qreal y, qreal w, qreal h)
+
+ This convenience function is equivalent to calling setGeometry(QRectF(
+ \a x, \a y, \a w, \a h)).
+
+ \sa geometry(), resize()
+*/
+
+/*!
+ \property QGraphicsWidget::minimumSize
+ \brief the minimum size of the widget
+
+ \sa setMinimumSize(), minimumSize(), preferredSize, maximumSize
+*/
+
+/*!
+ \property QGraphicsWidget::preferredSize
+ \brief the preferred size of the widget
+
+ \sa setPreferredSize(), preferredSize(), minimumSize, maximumSize
+*/
+
+/*!
+ \property QGraphicsWidget::maximumSize
+ \brief the maximum size of the widget
+
+ \sa setMaximumSize(), maximumSize(), minimumSize, preferredSize
+*/
+
+/*!
+ Sets the widget's contents margins to \a left, \a top, \a right and \a
+ bottom.
+
+ Contents margins are used by the assigned layout to define the placement
+ of subwidgets and layouts. Margins are particularly useful for widgets
+ that constrain subwidgets to only a section of its own geometry. For
+ example, a group box with a layout will place subwidgets inside its frame,
+ but below the title.
+
+ Changing a widget's contents margins will always trigger an update(), and
+ any assigned layout will be activated automatically. The widget will then
+ receive a \l{QEvent::ContentsRectChange}{ContentsRectChange} event.
+
+ \sa getContentsMargins(), setGeometry()
+*/
+void QGraphicsWidget::setContentsMargins(qreal left, qreal top, qreal right, qreal bottom)
+{
+ Q_D(QGraphicsWidget);
+
+ if (!d->margins && left == 0 && top == 0 && right == 0 && bottom == 0)
+ return;
+ d->ensureMargins();
+ if (left == d->margins[d->Left]
+ && top == d->margins[d->Top]
+ && right == d->margins[d->Right]
+ && bottom == d->margins[d->Bottom])
+ return;
+
+ d->margins[d->Left] = left;
+ d->margins[d->Top] = top;
+ d->margins[d->Right] = right;
+ d->margins[d->Bottom] = bottom;
+
+ if (QGraphicsLayout *l = d->layout)
+ l->invalidate();
+ else
+ updateGeometry();
+
+ QEvent e(QEvent::ContentsRectChange);
+ QApplication::sendEvent(this, &e);
+}
+
+/*!
+ Gets the widget's contents margins. The margins are stored in \a left, \a
+ top, \a right and \a bottom, as pointers to qreals. Each argument can
+ be \e {omitted} by passing 0.
+
+ \sa setContentsMargins()
+*/
+void QGraphicsWidget::getContentsMargins(qreal *left, qreal *top, qreal *right, qreal *bottom) const
+{
+ Q_D(const QGraphicsWidget);
+ if (left || top || right || bottom)
+ d->ensureMargins();
+ if (left)
+ *left = d->margins[d->Left];
+ if (top)
+ *top = d->margins[d->Top];
+ if (right)
+ *right = d->margins[d->Right];
+ if (bottom)
+ *bottom = d->margins[d->Bottom];
+}
+
+/*!
+ Sets the widget's window frame margins to \a left, \a top, \a right and
+ \a bottom. The default frame margins are provided by the style, and they
+ depend on the current window flags.
+
+ If you would like to draw your own window decoration, you can set your
+ own frame margins to override the default margins.
+
+ \sa unsetWindowFrameMargins(), getWindowFrameMargins(), windowFrameRect()
+*/
+void QGraphicsWidget::setWindowFrameMargins(qreal left, qreal top, qreal right, qreal bottom)
+{
+ Q_D(QGraphicsWidget);
+
+ if (!d->windowFrameMargins && left == 0 && top == 0 && right == 0 && bottom == 0)
+ return;
+ d->ensureWindowFrameMargins();
+ bool unchanged =
+ d->windowFrameMargins[d->Left] == left
+ && d->windowFrameMargins[d->Top] == top
+ && d->windowFrameMargins[d->Right] == right
+ && d->windowFrameMargins[d->Bottom] == bottom;
+ if (d->setWindowFrameMargins && unchanged)
+ return;
+ if (!unchanged)
+ prepareGeometryChange();
+ d->windowFrameMargins[d->Left] = left;
+ d->windowFrameMargins[d->Top] = top;
+ d->windowFrameMargins[d->Right] = right;
+ d->windowFrameMargins[d->Bottom] = bottom;
+ d->setWindowFrameMargins = true;
+}
+
+/*!
+ Gets the widget's window frame margins. The margins are stored in \a left,
+ \a top, \a right and \a bottom as pointers to qreals. Each argument can
+ be \e {omitted} by passing 0.
+
+ \sa setWindowFrameMargins(), windowFrameRect()
+*/
+void QGraphicsWidget::getWindowFrameMargins(qreal *left, qreal *top, qreal *right, qreal *bottom) const
+{
+ Q_D(const QGraphicsWidget);
+ if (left || top || right || bottom)
+ d->ensureWindowFrameMargins();
+ if (left)
+ *left = d->windowFrameMargins[d->Left];
+ if (top)
+ *top = d->windowFrameMargins[d->Top];
+ if (right)
+ *right = d->windowFrameMargins[d->Right];
+ if (bottom)
+ *bottom = d->windowFrameMargins[d->Bottom];
+}
+
+/*!
+ Resets the window frame margins to the default value, provided by the style.
+
+ \sa setWindowFrameMargins(), getWindowFrameMargins(), windowFrameRect()
+*/
+void QGraphicsWidget::unsetWindowFrameMargins()
+{
+ Q_D(QGraphicsWidget);
+ if ((d->windowFlags & Qt::Window) && (d->windowFlags & Qt::WindowType_Mask) != Qt::Popup &&
+ (d->windowFlags & Qt::WindowType_Mask) != Qt::ToolTip && !(d->windowFlags & Qt::FramelessWindowHint)) {
+ QStyleOptionTitleBar bar;
+ d->initStyleOptionTitleBar(&bar);
+ QStyle *style = this->style();
+ qreal margin = style->pixelMetric(QStyle::PM_MdiSubWindowFrameWidth);
+ qreal titleBarHeight = d->titleBarHeight(bar);
+ setWindowFrameMargins(margin, titleBarHeight, margin, margin);
+ } else {
+ setWindowFrameMargins(0, 0, 0, 0);
+ }
+ d->setWindowFrameMargins = false;
+}
+
+/*!
+ Returns the widget's geometry in parent coordinates including any window
+ frame.
+
+ \sa windowFrameRect(), getWindowFrameMargins(), setWindowFrameMargins()
+*/
+QRectF QGraphicsWidget::windowFrameGeometry() const
+{
+ Q_D(const QGraphicsWidget);
+ return d->windowFrameMargins
+ ? geometry().adjusted(-d->windowFrameMargins[d->Left], -d->windowFrameMargins[d->Top],
+ d->windowFrameMargins[d->Right], d->windowFrameMargins[d->Bottom])
+ : geometry();
+}
+
+/*!
+ Returns the widget's local rect including any window frame.
+
+ \sa windowFrameGeometry(), getWindowFrameMargins(), setWindowFrameMargins()
+*/
+QRectF QGraphicsWidget::windowFrameRect() const
+{
+ Q_D(const QGraphicsWidget);
+ return d->windowFrameMargins
+ ? rect().adjusted(-d->windowFrameMargins[d->Left], -d->windowFrameMargins[d->Top],
+ d->windowFrameMargins[d->Right], d->windowFrameMargins[d->Bottom])
+ : rect();
+}
+
+/*!
+ Populates a style option object for this widget based on its current
+ state, and stores the output in \a option. The default implementation
+ populates \a option with the following properties.
+
+ \table
+ \header
+ \o Style Option Property
+ \o Value
+ \row
+ \o state & QStyle::State_Enabled
+ \o Corresponds to QGraphicsItem::isEnabled().
+ \row
+ \o state & QStyle::State_HasFocus
+ \o Corresponds to QGraphicsItem::hasFocus().
+ \row
+ \o state & QStyle::State_MouseOver
+ \o Corresponds to QGraphicsItem::isUnderMouse().
+ \row
+ \o direction
+ \o Corresponds to QGraphicsWidget::layoutDirection().
+ \row
+ \o rect
+ \o Corresponds to QGraphicsWidget::rect().toRect().
+ \row
+ \o palette
+ \o Corresponds to QGraphicsWidget::palette().
+ \row
+ \o fontMetrics
+ \o Corresponds to QFontMetrics(QGraphicsWidget::font()).
+ \endtable
+
+ Subclasses of QGraphicsWidget should call the base implementation, and
+ then test the type of \a option using qstyleoption_cast<>() or test
+ QStyleOption::Type before storing widget-specific options.
+
+ For example:
+
+ \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicswidget.cpp 0
+
+ \sa QStyleOption::initFrom()
+*/
+void QGraphicsWidget::initStyleOption(QStyleOption *option) const
+{
+ Q_ASSERT(option);
+
+ option->state = QStyle::State_None;
+ if (isEnabled())
+ option->state |= QStyle::State_Enabled;
+ if (hasFocus())
+ option->state |= QStyle::State_HasFocus;
+ // if (window->testAttribute(Qt::WA_KeyboardFocusChange)) // ### Window
+ // option->state |= QStyle::State_KeyboardFocusChange;
+ if (isUnderMouse())
+ option->state |= QStyle::State_MouseOver;
+ if (QGraphicsWidget *w = window()) {
+ if (w->isActiveWindow())
+ option->state |= QStyle::State_Active;
+ }
+ if (isWindow())
+ option->state |= QStyle::State_Window;
+ /*
+ ###
+#ifdef Q_WS_MAC
+ extern bool qt_mac_can_clickThrough(const QGraphicsWidget *w); //qwidget_mac.cpp
+ if (!(option->state & QStyle::State_Active) && !qt_mac_can_clickThrough(widget))
+ option->state &= ~QStyle::State_Enabled;
+
+ switch (QMacStyle::widgetSizePolicy(widget)) {
+ case QMacStyle::SizeSmall:
+ option->state |= QStyle::State_Small;
+ break;
+ case QMacStyle::SizeMini:
+ option->state |= QStyle::State_Mini;
+ break;
+ default:
+ ;
+ }
+#endif
+#ifdef QT_KEYPAD_NAVIGATION
+ if (widget->hasEditFocus())
+ state |= QStyle::State_HasEditFocus;
+#endif
+ */
+ option->direction = layoutDirection();
+ option->rect = rect().toRect(); // ### truncation!
+ option->palette = palette();
+ if (!isEnabled()) {
+ option->palette.setCurrentColorGroup(QPalette::Disabled);
+ } else if (isActiveWindow()) {
+ option->palette.setCurrentColorGroup(QPalette::Active);
+ } else {
+ option->palette.setCurrentColorGroup(QPalette::Inactive);
+ }
+ option->fontMetrics = QFontMetrics(font());
+}
+
+/*!
+ \reimp
+*/
+QSizeF QGraphicsWidget::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
+{
+ Q_D(const QGraphicsWidget);
+ QSizeF sh;
+ if (d->layout) {
+ QSizeF marginSize(0,0);
+ if (d->margins) {
+ marginSize = QSizeF(d->margins[d->Left] + d->margins[d->Right],
+ d->margins[d->Top] + d->margins[d->Bottom]);
+ }
+ sh = d->layout->effectiveSizeHint(which, constraint - marginSize);
+ sh += marginSize;
+ } else {
+ switch (which) {
+ case Qt::MinimumSize:
+ sh = QSizeF(0, 0);
+ break;
+ case Qt::PreferredSize:
+ sh = QSizeF(50, 50); //rather arbitrary
+ break;
+ case Qt::MaximumSize:
+ sh = QSizeF(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
+ break;
+ default:
+ qWarning("QGraphicsWidget::sizeHint(): Don't know how to handle the value of 'which'");
+ break;
+ }
+ }
+ return sh;
+}
+
+/*!
+ \property QGraphicsWidget::layout
+ \brief The layout of the widget
+
+ Any existing layout manager is deleted before the new layout is assigned. If
+ \a layout is 0, the widget is left without a layout. Existing subwidgets'
+ geometries will remain unaffected.
+
+ QGraphicsWidget takes ownership of \a layout.
+
+ All widgets that are currently managed by \a layout or all of its
+ sublayouts, are automatically reparented to this item. The layout is then
+ invalidated, and the child widget geometries are adjusted according to
+ this item's geometry() and contentsMargins(). Children who are not
+ explicitly managed by \a layout remain unaffected by the layout after
+ it has been assigned to this widget.
+
+ If no layout is currently managing this widget, layout() will return 0.
+
+*/
+
+/*!
+ \fn void QGraphicsWidget::layoutChanged()
+ This signal gets emitted whenever the layout of the item changes
+ \internal
+*/
+
+/*!
+ Returns this widget's layout, or 0 if no layout is currently managing this
+ widget.
+
+ \sa setLayout()
+*/
+QGraphicsLayout *QGraphicsWidget::layout() const
+{
+ Q_D(const QGraphicsWidget);
+ return d->layout;
+}
+
+/*!
+ \fn void QGraphicsWidget::setLayout(QGraphicsLayout *layout)
+
+ Sets the layout for this widget to \a layout. Any existing layout manager
+ is deleted before the new layout is assigned. If \a layout is 0, the
+ widget is left without a layout. Existing subwidgets' geometries will
+ remain unaffected.
+
+ All widgets that are currently managed by \a layout or all of its
+ sublayouts, are automatically reparented to this item. The layout is then
+ invalidated, and the child widget geometries are adjusted according to
+ this item's geometry() and contentsMargins(). Children who are not
+ explicitly managed by \a layout remain unaffected by the layout after
+ it has been assigned to this widget.
+
+ QGraphicsWidget takes ownership of \a layout.
+
+ \sa layout(), QGraphicsLinearLayout::addItem(), QGraphicsLayout::invalidate()
+*/
+void QGraphicsWidget::setLayout(QGraphicsLayout *l)
+{
+ Q_D(QGraphicsWidget);
+ if (d->layout == l)
+ return;
+ d->setLayout_helper(l);
+ if (!l)
+ return;
+
+ // Prevent assigning a layout that is already assigned to another widget.
+ QGraphicsLayoutItem *oldParent = l->parentLayoutItem();
+ if (oldParent && oldParent != this) {
+ qWarning("QGraphicsWidget::setLayout: Attempting to set a layout on %s"
+ " \"%s\", when the layout already has a parent",
+ metaObject()->className(), qPrintable(objectName()));
+ return;
+ }
+
+ // Install and activate the layout.
+ l->setParentLayoutItem(this);
+ l->d_func()->reparentChildItems(this);
+ l->invalidate();
+ emit layoutChanged();
+}
+
+/*!
+ Adjusts the size of the widget to its effective preferred size hint.
+
+ This function is called implicitly when the item is shown for the first
+ time.
+
+ \sa effectiveSizeHint(), Qt::MinimumSize
+*/
+void QGraphicsWidget::adjustSize()
+{
+ QSizeF sz = effectiveSizeHint(Qt::PreferredSize);
+ // What if sz is not valid?!
+ if (sz.isValid())
+ resize(sz);
+}
+
+/*!
+ \property QGraphicsWidget::layoutDirection
+ \brief the layout direction for this widget.
+
+ This property modifies this widget's and all of its descendants'
+ Qt::WA_RightToLeft attribute. It also sets this widget's
+ Qt::WA_SetLayoutDirection attribute.
+
+ The widget's layout direction determines the order in which the layout
+ manager horizontally arranges subwidgets of this widget. The default
+ value depends on the language and locale of the application, and is
+ typically in the same direction as words are read and written. With
+ Qt::LeftToRight, the layout starts placing subwidgets from the left
+ side of this widget towards the right. Qt::RightToLeft does the opposite -
+ the layout will place widgets starting from the right edge moving towards
+ the left.
+
+ Subwidgets inherit their layout direction from the parent. Top-level
+ widget items inherit their layout direction from
+ QGraphicsScene::layoutDirection. If you change a widget's layout direction
+ by calling setLayoutDirection(), the widget will send itself a
+ \l{QEvent::LayoutDirectionChange}{LayoutDirectionChange} event, and then
+ propagate the new layout direction to all its descendants.
+
+ \sa QWidget::layoutDirection, QApplication::layoutDirection
+*/
+Qt::LayoutDirection QGraphicsWidget::layoutDirection() const
+{
+ return testAttribute(Qt::WA_RightToLeft) ? Qt::RightToLeft : Qt::LeftToRight;
+}
+void QGraphicsWidget::setLayoutDirection(Qt::LayoutDirection direction)
+{
+ Q_D(QGraphicsWidget);
+ setAttribute(Qt::WA_SetLayoutDirection, true);
+ d->setLayoutDirection_helper(direction);
+}
+void QGraphicsWidget::unsetLayoutDirection()
+{
+ Q_D(QGraphicsWidget);
+ setAttribute(Qt::WA_SetLayoutDirection, false);
+ d->resolveLayoutDirection();
+}
+
+/*!
+ Returns a pointer to the widget's style. If this widget does not have any
+ explicitly assigned style, the scene's style is returned instead. In turn,
+ if the scene does not have any assigned style, this function returns
+ QApplication::style().
+
+ \sa setStyle()
+*/
+QStyle *QGraphicsWidget::style() const
+{
+ if (QStyle *style = widgetStyles()->styleForWidget(this))
+ return style;
+ // ### This is not thread-safe. QApplication::style() is not thread-safe.
+ return scene() ? scene()->style() : QApplication::style();
+}
+
+/*!
+ Sets the widget's style to \a style. QGraphicsWidget does \e not take
+ ownership of \a style.
+
+ If no style is assigned, or \a style is 0, the widget will use
+ QGraphicsScene::style() (if this has been set). Otherwise the widget will
+ use QApplication::style().
+
+ This function sets the Qt::WA_SetStyle attribute if \a style is not 0;
+ otherwise it clears the attribute.
+
+ \sa style()
+*/
+void QGraphicsWidget::setStyle(QStyle *style)
+{
+ setAttribute(Qt::WA_SetStyle, style != 0);
+ widgetStyles()->setStyleForWidget(this, style);
+
+ // Deliver StyleChange to the widget itself (doesn't propagate).
+ QEvent event(QEvent::StyleChange);
+ QApplication::sendEvent(this, &event);
+}
+
+/*!
+ \property QGraphicsWidget::font
+ \brief the widgets' font
+
+ This property provides the widget's font.
+
+ QFont consists of font properties that have been explicitly defined and
+ properties implicitly inherited from the widget's parent. Hence, font()
+ can return a different font compared to the one set with setFont().
+ This scheme allows you to define single entries in a font without
+ affecting the font's inherited entries.
+
+ When a widget's font changes, it resolves its entries against its
+ parent widget. If the widget does not have a parent widget, it resolves
+ its entries against the scene. The widget then sends itself a
+ \l{QEvent::FontChange}{FontChange} event and notifies all its
+ descendants so that they can resolve their fonts as well.
+
+ By default, this property contains the application's default font.
+
+ \sa QApplication::font(), QGraphicsScene::font, QFont::resolve()
+*/
+QFont QGraphicsWidget::font() const
+{
+ Q_D(const QGraphicsWidget);
+ QFont fnt = d->font;
+ fnt.resolve(fnt.resolve() | d->inheritedFontResolveMask);
+ return fnt;
+}
+void QGraphicsWidget::setFont(const QFont &font)
+{
+ Q_D(QGraphicsWidget);
+ setAttribute(Qt::WA_SetFont, font.resolve() != 0);
+
+ QFont naturalFont = d->naturalWidgetFont();
+ QFont resolvedFont = font.resolve(naturalFont);
+ d->setFont_helper(resolvedFont);
+}
+
+/*!
+ \property QGraphicsWidget::palette
+ \brief the widget's palette
+
+ This property provides the widget's palette. The palette provides colors
+ and brushes for color groups (e.g., QPalette::Button) and states (e.g.,
+ QPalette::Inactive), loosely defining the general look of the widget and
+ its children.
+
+ QPalette consists of color groups that have been explicitly defined, and
+ groups that are implicitly inherited from the widget's parent. Because of
+ this, palette() can return a different palette than what has been set with
+ setPalette(). This scheme allows you to define single entries in a palette
+ without affecting the palette's inherited entries.
+
+ When a widget's palette changes, it resolves its entries against its
+ parent widget, or if it doesn't have a parent widget, it resolves against
+ the scene. It then sends itself a \l{QEvent::PaletteChange}{PaletteChange}
+ event, and notifies all its descendants so they can resolve their palettes
+ as well.
+
+ By default, this property contains the application's default palette.
+
+ \sa QApplication::palette(), QGraphicsScene::palette, QPalette::resolve()
+*/
+QPalette QGraphicsWidget::palette() const
+{
+ Q_D(const QGraphicsWidget);
+ return d->palette;
+}
+void QGraphicsWidget::setPalette(const QPalette &palette)
+{
+ Q_D(QGraphicsWidget);
+ setAttribute(Qt::WA_SetPalette, palette.resolve() != 0);
+
+ QPalette naturalPalette = d->naturalWidgetPalette();
+ QPalette resolvedPalette = palette.resolve(naturalPalette);
+ d->setPalette_helper(resolvedPalette);
+}
+
+/*!
+ \property QGraphicsWidget::autoFillBackground
+ \brief whether the widget background is filled automatically
+ \since 4.7
+
+ If enabled, this property will cause Qt to fill the background of the
+ widget before invoking the paint() method. The color used is defined by the
+ QPalette::Window color role from the widget's \l{QPalette}{palette}.
+
+ In addition, Windows are always filled with QPalette::Window, unless the
+ WA_OpaquePaintEvent or WA_NoSystemBackground attributes are set.
+
+ By default, this property is false.
+
+ \sa Qt::WA_OpaquePaintEvent, Qt::WA_NoSystemBackground,
+*/
+bool QGraphicsWidget::autoFillBackground() const
+{
+ Q_D(const QGraphicsWidget);
+ return d->autoFillBackground;
+}
+void QGraphicsWidget::setAutoFillBackground(bool enabled)
+{
+ Q_D(QGraphicsWidget);
+ if (d->autoFillBackground != enabled) {
+ d->autoFillBackground = enabled;
+ update();
+ }
+}
+
+/*!
+ If this widget is currently managed by a layout, this function notifies
+ the layout that the widget's size hints have changed and the layout
+ may need to resize and reposition the widget accordingly.
+
+ Call this function if the widget's sizeHint() has changed.
+
+ \sa QGraphicsLayout::invalidate()
+*/
+void QGraphicsWidget::updateGeometry()
+{
+ QGraphicsLayoutItem::updateGeometry();
+ QGraphicsLayoutItem *parentItem = parentLayoutItem();
+
+ if (parentItem && parentItem->isLayout()) {
+ if (QGraphicsLayout::instantInvalidatePropagation()) {
+ static_cast<QGraphicsLayout *>(parentItem)->invalidate();
+ } else {
+ parentItem->updateGeometry();
+ }
+ } else {
+ if (parentItem) {
+ // This is for custom layouting
+ QGraphicsWidget *parentWid = parentWidget(); //###
+ if (parentWid->isVisible())
+ QApplication::postEvent(parentWid, new QEvent(QEvent::LayoutRequest));
+ } else {
+ /**
+ * If this is the topmost widget, post a LayoutRequest event to the widget.
+ * When the event is received, it will start flowing all the way down to the leaf
+ * widgets in one go. This will make a relayout flicker-free.
+ */
+ if (QGraphicsLayout::instantInvalidatePropagation())
+ QApplication::postEvent(static_cast<QGraphicsWidget *>(this), new QEvent(QEvent::LayoutRequest));
+ }
+ if (!QGraphicsLayout::instantInvalidatePropagation()) {
+ bool wasResized = testAttribute(Qt::WA_Resized);
+ resize(size()); // this will restrict the size
+ setAttribute(Qt::WA_Resized, wasResized);
+ }
+ }
+}
+
+/*!
+ \reimp
+
+ QGraphicsWidget uses the base implementation of this function to catch and
+ deliver events related to state changes in the item. Because of this, it is
+ very important that subclasses call the base implementation.
+
+ \a change specifies the type of change, and \a value is the new value.
+
+ For example, QGraphicsWidget uses ItemVisibleChange to deliver
+ \l{QEvent::Show} {Show} and \l{QEvent::Hide}{Hide} events,
+ ItemPositionHasChanged to deliver \l{QEvent::Move}{Move} events,
+ and ItemParentChange both to deliver \l{QEvent::ParentChange}
+ {ParentChange} events, and for managing the focus chain.
+
+ QGraphicsWidget enables the ItemSendsGeometryChanges flag by default in
+ order to track position changes.
+
+ \sa QGraphicsItem::itemChange()
+*/
+QVariant QGraphicsWidget::itemChange(GraphicsItemChange change, const QVariant &value)
+{
+ Q_D(QGraphicsWidget);
+ switch (change) {
+ case ItemEnabledHasChanged: {
+ // Send EnabledChange after the enabled state has changed.
+ QEvent event(QEvent::EnabledChange);
+ QApplication::sendEvent(this, &event);
+ break;
+ }
+ case ItemVisibleChange:
+ if (value.toBool()) {
+ // Send Show event before the item has been shown.
+ QShowEvent event;
+ QApplication::sendEvent(this, &event);
+ bool resized = testAttribute(Qt::WA_Resized);
+ if (!resized) {
+ adjustSize();
+ setAttribute(Qt::WA_Resized, false);
+ }
+ }
+ break;
+ case ItemVisibleHasChanged:
+ if (!value.toBool()) {
+ // Send Hide event after the item has been hidden.
+ QHideEvent event;
+ QApplication::sendEvent(this, &event);
+ }
+ break;
+ case ItemPositionHasChanged:
+ d->setGeometryFromSetPos();
+ break;
+ case ItemParentChange: {
+ // Deliver ParentAboutToChange.
+ QEvent event(QEvent::ParentAboutToChange);
+ QApplication::sendEvent(this, &event);
+ break;
+ }
+ case ItemParentHasChanged: {
+ // Deliver ParentChange.
+ QEvent event(QEvent::ParentChange);
+ QApplication::sendEvent(this, &event);
+ break;
+ }
+ case ItemCursorHasChanged: {
+ // Deliver CursorChange.
+ QEvent event(QEvent::CursorChange);
+ QApplication::sendEvent(this, &event);
+ break;
+ }
+ case ItemToolTipHasChanged: {
+ // Deliver ToolTipChange.
+ QEvent event(QEvent::ToolTipChange);
+ QApplication::sendEvent(this, &event);
+ break;
+ }
+ default:
+ break;
+ }
+ return QGraphicsItem::itemChange(change, value);
+}
+
+/*!
+ \internal
+
+ This virtual function is used to notify changes to any property (both
+ dynamic properties, and registered with Q_PROPERTY) in the
+ widget. Depending on the property itself, the notification can be
+ delivered before or after the value has changed.
+
+ \a propertyName is the name of the property (e.g., "size" or "font"), and
+ \a value is the (proposed) new value of the property. The function returns
+ the new value, which may be different from \a value if the notification
+ supports adjusting the property value. The base implementation simply
+ returns \a value for any \a propertyName.
+
+ QGraphicsWidget delivers notifications for the following properties:
+
+ \table \o propertyName \o Property
+ \row \o layoutDirection \o QGraphicsWidget::layoutDirection
+ \row \o size \o QGraphicsWidget::size
+ \row \o font \o QGraphicsWidget::font
+ \row \o palette \o QGraphicsWidget::palette
+ \endtable
+
+ \sa itemChange()
+*/
+QVariant QGraphicsWidget::propertyChange(const QString &propertyName, const QVariant &value)
+{
+ Q_UNUSED(propertyName);
+ return value;
+}
+
+/*!
+ QGraphicsWidget's implementation of sceneEvent() simply passes \a event to
+ QGraphicsWidget::event(). You can handle all events for your widget in
+ event() or in any of the convenience functions; you should not have to
+ reimplement this function in a subclass of QGraphicsWidget.
+
+ \sa QGraphicsItem::sceneEvent()
+*/
+bool QGraphicsWidget::sceneEvent(QEvent *event)
+{
+ return QGraphicsItem::sceneEvent(event);
+}
+
+/*!
+ This event handler, for \a event, receives events for the window frame if
+ this widget is a window. Its base implementation provides support for
+ default window frame interaction such as moving, resizing, etc.
+
+ You can reimplement this handler in a subclass of QGraphicsWidget to
+ provide your own custom window frame interaction support.
+
+ Returns true if \a event has been recognized and processed; otherwise,
+ returns false.
+
+ \sa event()
+*/
+bool QGraphicsWidget::windowFrameEvent(QEvent *event)
+{
+ Q_D(QGraphicsWidget);
+ switch (event->type()) {
+ case QEvent::GraphicsSceneMousePress:
+ d->windowFrameMousePressEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
+ break;
+ case QEvent::GraphicsSceneMouseMove:
+ d->ensureWindowData();
+ if (d->windowData->grabbedSection != Qt::NoSection) {
+ d->windowFrameMouseMoveEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
+ event->accept();
+ }
+ break;
+ case QEvent::GraphicsSceneMouseRelease:
+ d->windowFrameMouseReleaseEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
+ break;
+ case QEvent::GraphicsSceneHoverMove:
+ d->windowFrameHoverMoveEvent(static_cast<QGraphicsSceneHoverEvent *>(event));
+ break;
+ case QEvent::GraphicsSceneHoverLeave:
+ d->windowFrameHoverLeaveEvent(static_cast<QGraphicsSceneHoverEvent *>(event));
+ break;
+ default:
+ break;
+ }
+ return event->isAccepted();
+}
+
+/*!
+ \since 4.4
+
+ Returns the window frame section at position \a pos, or
+ Qt::NoSection if there is no window frame section at this
+ position.
+
+ This function is used in QGraphicsWidget's base implementation for window
+ frame interaction.
+
+ You can reimplement this function if you want to customize how a window
+ can be interactively moved or resized. For instance, if you only want to
+ allow a window to be resized by the bottom right corner, you can
+ reimplement this function to return Qt::NoSection for all sections except
+ Qt::BottomRightSection.
+
+ \sa windowFrameEvent(), paintWindowFrame(), windowFrameGeometry()
+*/
+Qt::WindowFrameSection QGraphicsWidget::windowFrameSectionAt(const QPointF &pos) const
+{
+ Q_D(const QGraphicsWidget);
+
+ const QRectF r = windowFrameRect();
+ if (!r.contains(pos))
+ return Qt::NoSection;
+
+ const qreal left = r.left();
+ const qreal top = r.top();
+ const qreal right = r.right();
+ const qreal bottom = r.bottom();
+ const qreal x = pos.x();
+ const qreal y = pos.y();
+
+ const qreal cornerMargin = 20;
+ //### Not sure of this one, it should be the same value for all edges.
+ const qreal windowFrameWidth = d->windowFrameMargins
+ ? d->windowFrameMargins[d->Left] : 0;
+
+ Qt::WindowFrameSection s = Qt::NoSection;
+ if (x <= left + cornerMargin) {
+ if (y <= top + windowFrameWidth || (x <= left + windowFrameWidth && y <= top + cornerMargin)) {
+ s = Qt::TopLeftSection;
+ } else if (y >= bottom - windowFrameWidth || (x <= left + windowFrameWidth && y >= bottom - windowFrameWidth)) {
+ s = Qt::BottomLeftSection;
+ } else if (x <= left + windowFrameWidth) {
+ s = Qt::LeftSection;
+ }
+ } else if (x >= right - cornerMargin) {
+ if (y <= top + windowFrameWidth || (x >= right - windowFrameWidth && y <= top + cornerMargin)) {
+ s = Qt::TopRightSection;
+ } else if (y >= bottom - windowFrameWidth || (x >= right - windowFrameWidth && y >= bottom - windowFrameWidth)) {
+ s = Qt::BottomRightSection;
+ } else if (x >= right - windowFrameWidth) {
+ s = Qt::RightSection;
+ }
+ } else if (y <= top + windowFrameWidth) {
+ s = Qt::TopSection;
+ } else if (y >= bottom - windowFrameWidth) {
+ s = Qt::BottomSection;
+ }
+ if (s == Qt::NoSection) {
+ QRectF r1 = r;
+ r1.setHeight(d->windowFrameMargins
+ ? d->windowFrameMargins[d->Top] : 0);
+ if (r1.contains(pos))
+ s = Qt::TitleBarArea;
+ }
+ return s;
+}
+
+/*!
+ \reimp
+
+ Handles the \a event. QGraphicsWidget handles the following
+ events:
+
+ \table \o Event \o Usage
+ \row \o Polish
+ \o Delivered to the widget some time after it has been
+ shown.
+ \row \o GraphicsSceneMove
+ \o Delivered to the widget after its local position has
+ changed.
+ \row \o GraphicsSceneResize
+ \o Delivered to the widget after its size has changed.
+ \row \o Show
+ \o Delivered to the widget before it has been shown.
+ \row \o Hide
+ \o Delivered to the widget after it has been hidden.
+ \row \o PaletteChange
+ \o Delivered to the widget after its palette has changed.
+ \row \o FontChange
+ \o Delivered to the widget after its font has changed.
+ \row \o EnabledChange
+ \o Delivered to the widget after its enabled state has
+ changed.
+ \row \o StyleChange
+ \o Delivered to the widget after its style has changed.
+ \row \o LayoutDirectionChange
+ \o Delivered to the widget after its layout direction has
+ changed.
+ \row \o ContentsRectChange
+ \o Delivered to the widget after its contents margins/
+ contents rect has changed.
+ \endtable
+*/
+bool QGraphicsWidget::event(QEvent *event)
+{
+ Q_D(QGraphicsWidget);
+ // Forward the event to the layout first.
+ if (d->layout)
+ d->layout->widgetEvent(event);
+
+ // Handle the event itself.
+ switch (event->type()) {
+ case QEvent::GraphicsSceneMove:
+ moveEvent(static_cast<QGraphicsSceneMoveEvent *>(event));
+ break;
+ case QEvent::GraphicsSceneResize:
+ resizeEvent(static_cast<QGraphicsSceneResizeEvent *>(event));
+ break;
+ case QEvent::Show:
+ showEvent(static_cast<QShowEvent *>(event));
+ break;
+ case QEvent::Hide:
+ hideEvent(static_cast<QHideEvent *>(event));
+ break;
+ case QEvent::Polish:
+ polishEvent();
+ d->polished = true;
+ if (!d->font.isCopyOf(QApplication::font()))
+ d->updateFont(d->font);
+ break;
+ case QEvent::WindowActivate:
+ case QEvent::WindowDeactivate:
+ update();
+ break;
+ // Taken from QWidget::event
+ case QEvent::ActivationChange:
+ case QEvent::EnabledChange:
+ case QEvent::FontChange:
+ case QEvent::StyleChange:
+ case QEvent::PaletteChange:
+ case QEvent::ParentChange:
+ case QEvent::ContentsRectChange:
+ case QEvent::LayoutDirectionChange:
+ changeEvent(event);
+ break;
+ case QEvent::Close:
+ closeEvent((QCloseEvent *)event);
+ break;
+ case QEvent::GrabMouse:
+ grabMouseEvent(event);
+ break;
+ case QEvent::UngrabMouse:
+ ungrabMouseEvent(event);
+ break;
+ case QEvent::GrabKeyboard:
+ grabKeyboardEvent(event);
+ break;
+ case QEvent::UngrabKeyboard:
+ ungrabKeyboardEvent(event);
+ break;
+ case QEvent::GraphicsSceneMousePress:
+ if (d->hasDecoration() && windowFrameEvent(event))
+ return true;
+ case QEvent::GraphicsSceneMouseMove:
+ case QEvent::GraphicsSceneMouseRelease:
+ case QEvent::GraphicsSceneMouseDoubleClick:
+ d->ensureWindowData();
+ if (d->hasDecoration() && d->windowData->grabbedSection != Qt::NoSection)
+ return windowFrameEvent(event);
+ break;
+ case QEvent::GraphicsSceneHoverEnter:
+ case QEvent::GraphicsSceneHoverMove:
+ case QEvent::GraphicsSceneHoverLeave:
+ if (d->hasDecoration()) {
+ windowFrameEvent(event);
+ // Filter out hover events if they were sent to us only because of the
+ // decoration (special case in QGraphicsScenePrivate::dispatchHoverEvent).
+ if (!acceptsHoverEvents())
+ return true;
+ }
+ break;
+ default:
+ break;
+ }
+ return QObject::event(event);
+}
+
+/*!
+ This event handler can be reimplemented to handle state changes.
+
+ The state being changed in this event can be retrieved through \a event.
+
+ Change events include: QEvent::ActivationChange, QEvent::EnabledChange,
+ QEvent::FontChange, QEvent::StyleChange, QEvent::PaletteChange,
+ QEvent::ParentChange, QEvent::LayoutDirectionChange, and
+ QEvent::ContentsRectChange.
+*/
+void QGraphicsWidget::changeEvent(QEvent *event)
+{
+ Q_D(QGraphicsWidget);
+ switch (event->type()) {
+ case QEvent::StyleChange:
+ // ### Don't unset if the margins are explicitly set.
+ unsetWindowFrameMargins();
+ if (d->layout)
+ d->layout->invalidate();
+ case QEvent::FontChange:
+ update();
+ updateGeometry();
+ break;
+ case QEvent::PaletteChange:
+ update();
+ break;
+ case QEvent::ParentChange:
+ d->resolveFont(d->inheritedFontResolveMask);
+ d->resolvePalette(d->inheritedPaletteResolveMask);
+ break;
+ default:
+ break;
+ }
+}
+
+/*!
+ This event handler, for \a event, can be reimplemented in a subclass to
+ receive widget close events. The default implementation accepts the
+ event.
+
+ \sa close(), QCloseEvent
+*/
+void QGraphicsWidget::closeEvent(QCloseEvent *event)
+{
+ event->accept();
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsWidget::focusInEvent(QFocusEvent *event)
+{
+ Q_UNUSED(event);
+ if (focusPolicy() != Qt::NoFocus)
+ update();
+}
+
+/*!
+ Finds a new widget to give the keyboard focus to, as appropriate for Tab
+ and Shift+Tab, and returns true if it can find a new widget; returns false
+ otherwise. If \a next is true, this function searches forward; if \a next
+ is false, it searches backward.
+
+ Sometimes, you will want to reimplement this function to provide special
+ focus handling for your widget and its subwidgets. For example, a web
+ browser might reimplement it to move its current active link forward or
+ backward, and call the base implementation only when it reaches the last
+ or first link on the page.
+
+ Child widgets call focusNextPrevChild() on their parent widgets, but only
+ the window that contains the child widgets decides where to redirect
+ focus. By reimplementing this function for an object, you gain control of
+ focus traversal for all child widgets.
+
+ \sa focusPolicy()
+*/
+bool QGraphicsWidget::focusNextPrevChild(bool next)
+{
+ Q_D(QGraphicsWidget);
+ // Let the parent's focusNextPrevChild implementation decide what to do.
+ QGraphicsWidget *parent = 0;
+ if (!isWindow() && (parent = parentWidget()))
+ return parent->focusNextPrevChild(next);
+ if (!d->scene)
+ return false;
+ if (d->scene->focusNextPrevChild(next))
+ return true;
+ if (isWindow()) {
+ setFocus(next ? Qt::TabFocusReason : Qt::BacktabFocusReason);
+ if (hasFocus())
+ return true;
+ }
+ return false;
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsWidget::focusOutEvent(QFocusEvent *event)
+{
+ Q_UNUSED(event);
+ if (focusPolicy() != Qt::NoFocus)
+ update();
+}
+
+/*!
+ This event handler, for \l{QEvent::Hide}{Hide} events, is delivered after
+ the widget has been hidden, for example, setVisible(false) has been called
+ for the widget or one of its ancestors when the widget was previously
+ shown.
+
+ You can reimplement this event handler to detect when your widget is
+ hidden. Calling QEvent::accept() or QEvent::ignore() on \a event has no
+ effect.
+
+ \sa showEvent(), QWidget::hideEvent(), ItemVisibleChange
+*/
+void QGraphicsWidget::hideEvent(QHideEvent *event)
+{
+ ///### focusNextPrevChild(true), don't lose focus when the focus widget
+ // is hidden.
+ Q_UNUSED(event);
+}
+
+/*!
+ This event handler, for \l{QEvent::GraphicsSceneMove}{GraphicsSceneMove}
+ events, is delivered after the widget has moved (e.g., its local position
+ has changed).
+
+ This event is only delivered when the item is moved locally. Calling
+ setTransform() or moving any of the item's ancestors does not affect the
+ item's local position.
+
+ You can reimplement this event handler to detect when your widget has
+ moved. Calling QEvent::accept() or QEvent::ignore() on \a event has no
+ effect.
+
+ \sa ItemPositionChange, ItemPositionHasChanged
+*/
+void QGraphicsWidget::moveEvent(QGraphicsSceneMoveEvent *event)
+{
+ // ### Last position is always == current position
+ Q_UNUSED(event);
+}
+
+/*!
+ This event is delivered to the item by the scene at some point after it
+ has been constructed, but before it is shown or otherwise accessed through
+ the scene. You can use this event handler to do last-minute initializations
+ of the widget which require the item to be fully constructed.
+
+ The base implementation does nothing.
+*/
+void QGraphicsWidget::polishEvent()
+{
+}
+
+/*!
+ This event handler, for
+ \l{QEvent::GraphicsSceneResize}{GraphicsSceneResize} events, is
+ delivered after the widget has been resized (i.e., its local size has
+ changed). \a event contains both the old and the new size.
+
+ This event is only delivered when the widget is resized locally; calling
+ setTransform() on the widget or any of its ancestors or view, does not
+ affect the widget's local size.
+
+ You can reimplement this event handler to detect when your widget has been
+ resized. Calling QEvent::accept() or QEvent::ignore() on \a event has no
+ effect.
+
+ \sa geometry(), setGeometry()
+*/
+void QGraphicsWidget::resizeEvent(QGraphicsSceneResizeEvent *event)
+{
+ Q_UNUSED(event);
+}
+
+/*!
+ This event handler, for \l{QEvent::Show}{Show} events, is delivered before
+ the widget has been shown, for example, setVisible(true) has been called
+ for the widget or one of its ancestors when the widget was previously
+ hidden.
+
+ You can reimplement this event handler to detect when your widget is
+ shown. Calling QEvent::accept() or QEvent::ignore() on \a event has no
+ effect.
+
+ \sa hideEvent(), QWidget::showEvent(), ItemVisibleChange
+*/
+void QGraphicsWidget::showEvent(QShowEvent *event)
+{
+ Q_UNUSED(event);
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsWidget::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
+{
+ Q_UNUSED(event);
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsWidget::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
+{
+ Q_UNUSED(event);
+}
+
+/*!
+ This event handler, for \a event, can be reimplemented in a subclass to
+ receive notifications for Qt::GrabMouse events.
+
+ \sa grabMouse(), grabKeyboard()
+*/
+void QGraphicsWidget::grabMouseEvent(QEvent *event)
+{
+ Q_UNUSED(event);
+}
+
+/*!
+ This event handler, for \a event, can be reimplemented in a subclass to
+ receive notifications for Qt::UngrabMouse events.
+
+ \sa ungrabMouse(), ungrabKeyboard()
+*/
+void QGraphicsWidget::ungrabMouseEvent(QEvent *event)
+{
+ Q_UNUSED(event);
+}
+
+/*!
+ This event handler, for \a event, can be reimplemented in a subclass to
+ receive notifications for Qt::GrabKeyboard events.
+
+ \sa grabKeyboard(), grabMouse()
+*/
+void QGraphicsWidget::grabKeyboardEvent(QEvent *event)
+{
+ Q_UNUSED(event);
+}
+
+/*!
+ This event handler, for \a event, can be reimplemented in a subclass to
+ receive notifications for Qt::UngrabKeyboard events.
+
+ \sa ungrabKeyboard(), ungrabMouse()
+*/
+void QGraphicsWidget::ungrabKeyboardEvent(QEvent *event)
+{
+ Q_UNUSED(event);
+}
+
+/*!
+ Returns the widgets window type.
+
+ \sa windowFlags(), isWindow(), isPanel()
+*/
+Qt::WindowType QGraphicsWidget::windowType() const
+{
+ return Qt::WindowType(int(windowFlags()) & Qt::WindowType_Mask);
+}
+
+/*!
+ \property QGraphicsWidget::windowFlags
+ \brief the widget's window flags
+
+ Window flags are a combination of a window type (e.g., Qt::Dialog) and
+ several flags giving hints on the behavior of the window. The behavior
+ is platform-dependent.
+
+ By default, this property contains no window flags.
+
+ Windows are panels. If you set the Qt::Window flag, the ItemIsPanel flag
+ will be set automatically. If you clear the Qt::Window flag, the
+ ItemIsPanel flag is also cleared. Note that the ItemIsPanel flag can be
+ set independently of Qt::Window.
+
+ \sa isWindow(), isPanel()
+*/
+Qt::WindowFlags QGraphicsWidget::windowFlags() const
+{
+ Q_D(const QGraphicsWidget);
+ return d->windowFlags;
+}
+void QGraphicsWidget::setWindowFlags(Qt::WindowFlags wFlags)
+{
+ Q_D(QGraphicsWidget);
+ if (d->windowFlags == wFlags)
+ return;
+ bool wasPopup = (d->windowFlags & Qt::WindowType_Mask) == Qt::Popup;
+
+ d->adjustWindowFlags(&wFlags);
+ d->windowFlags = wFlags;
+ if (!d->setWindowFrameMargins)
+ unsetWindowFrameMargins();
+
+ setFlag(ItemIsPanel, d->windowFlags & Qt::Window);
+
+ bool isPopup = (d->windowFlags & Qt::WindowType_Mask) == Qt::Popup;
+ if (d->scene && isVisible() && wasPopup != isPopup) {
+ // Popup state changed; update implicit mouse grab.
+ if (!isPopup)
+ d->scene->d_func()->removePopup(this);
+ else
+ d->scene->d_func()->addPopup(this);
+ }
+
+ if (d->scene && d->scene->d_func()->allItemsIgnoreHoverEvents && d->hasDecoration()) {
+ d->scene->d_func()->allItemsIgnoreHoverEvents = false;
+ d->scene->d_func()->enableMouseTrackingOnViews();
+ }
+}
+
+/*!
+ Returns true if this widget's window is in the active window, or if the
+ widget does not have a window but is in an active scene (i.e., a scene
+ that currently has focus).
+
+ The active window is the window that either contains a child widget that
+ currently has input focus, or that itself has input focus.
+
+ \sa QGraphicsScene::activeWindow(), QGraphicsScene::setActiveWindow(), isActive()
+*/
+bool QGraphicsWidget::isActiveWindow() const
+{
+ return isActive();
+}
+
+/*!
+ \property QGraphicsWidget::windowTitle
+ \brief This property holds the window title (caption).
+
+ This property is only used for windows.
+
+ By default, if no title has been set, this property contains an
+ empty string.
+*/
+void QGraphicsWidget::setWindowTitle(const QString &title)
+{
+ Q_D(QGraphicsWidget);
+ d->ensureWindowData();
+ d->windowData->windowTitle = title;
+}
+QString QGraphicsWidget::windowTitle() const
+{
+ Q_D(const QGraphicsWidget);
+ return d->windowData ? d->windowData->windowTitle : QString();
+}
+
+/*!
+ \property QGraphicsWidget::focusPolicy
+ \brief the way the widget accepts keyboard focus
+
+ The focus policy is Qt::TabFocus if the widget accepts keyboard focus by
+ tabbing, Qt::ClickFocus if the widget accepts focus by clicking,
+ Qt::StrongFocus if it accepts both, and Qt::NoFocus (the default) if it
+ does not accept focus at all.
+
+ You must enable keyboard focus for a widget if it processes keyboard
+ events. This is normally done from the widget's constructor. For instance,
+ the QLineEdit constructor calls setFocusPolicy(Qt::StrongFocus).
+
+ If you enable a focus policy (i.e., not Qt::NoFocus), QGraphicsWidget will
+ automatically enable the ItemIsFocusable flag. Setting Qt::NoFocus on a
+ widget will clear the ItemIsFocusable flag. If the widget currently has
+ keyboard focus, the widget will automatically lose focus.
+
+ \sa focusInEvent(), focusOutEvent(), keyPressEvent(), keyReleaseEvent(), enabled
+*/
+Qt::FocusPolicy QGraphicsWidget::focusPolicy() const
+{
+ Q_D(const QGraphicsWidget);
+ return d->focusPolicy;
+}
+void QGraphicsWidget::setFocusPolicy(Qt::FocusPolicy policy)
+{
+ Q_D(QGraphicsWidget);
+ if (d->focusPolicy == policy)
+ return;
+ d->focusPolicy = policy;
+ if (hasFocus() && policy == Qt::NoFocus)
+ clearFocus();
+ setFlag(ItemIsFocusable, policy != Qt::NoFocus);
+}
+
+/*!
+ If this widget, a child or descendant of this widget currently has input
+ focus, this function will return a pointer to that widget. If
+ no descendant widget has input focus, 0 is returned.
+
+ \sa QGraphicsItem::focusItem(), QWidget::focusWidget()
+*/
+QGraphicsWidget *QGraphicsWidget::focusWidget() const
+{
+ Q_D(const QGraphicsWidget);
+ if (d->subFocusItem && d->subFocusItem->d_ptr->isWidget)
+ return static_cast<QGraphicsWidget *>(d->subFocusItem);
+ return 0;
+}
+
+#ifndef QT_NO_SHORTCUT
+/*!
+ \since 4.5
+
+ Adds a shortcut to Qt's shortcut system that watches for the given key \a
+ sequence in the given \a context. If the \a context is
+ Qt::ApplicationShortcut, the shortcut applies to the application as a
+ whole. Otherwise, it is either local to this widget, Qt::WidgetShortcut,
+ or to the window itself, Qt::WindowShortcut. For widgets that are not part
+ of a window (i.e., top-level widgets and their children),
+ Qt::WindowShortcut shortcuts apply to the scene.
+
+ If the same key \a sequence has been grabbed by several widgets,
+ when the key \a sequence occurs a QEvent::Shortcut event is sent
+ to all the widgets to which it applies in a non-deterministic
+ order, but with the ``ambiguous'' flag set to true.
+
+ \warning You should not normally need to use this function;
+ instead create \l{QAction}s with the shortcut key sequences you
+ require (if you also want equivalent menu options and toolbar
+ buttons), or create \l{QShortcut}s if you just need key sequences.
+ Both QAction and QShortcut handle all the event filtering for you,
+ and provide signals which are triggered when the user triggers the
+ key sequence, so are much easier to use than this low-level
+ function.
+
+ \sa releaseShortcut() setShortcutEnabled() QWidget::grabShortcut()
+*/
+int QGraphicsWidget::grabShortcut(const QKeySequence &sequence, Qt::ShortcutContext context)
+{
+ Q_ASSERT(qApp);
+ if (sequence.isEmpty())
+ return 0;
+ // ### setAttribute(Qt::WA_GrabbedShortcut);
+ return qApp->d_func()->shortcutMap.addShortcut(this, sequence, context);
+}
+
+/*!
+ \since 4.5
+
+ Removes the shortcut with the given \a id from Qt's shortcut
+ system. The widget will no longer receive QEvent::Shortcut events
+ for the shortcut's key sequence (unless it has other shortcuts
+ with the same key sequence).
+
+ \warning You should not normally need to use this function since
+ Qt's shortcut system removes shortcuts automatically when their
+ parent widget is destroyed. It is best to use QAction or
+ QShortcut to handle shortcuts, since they are easier to use than
+ this low-level function. Note also that this is an expensive
+ operation.
+
+ \sa grabShortcut() setShortcutEnabled() , QWidget::releaseShortcut()
+*/
+void QGraphicsWidget::releaseShortcut(int id)
+{
+ Q_ASSERT(qApp);
+ if (id)
+ qApp->d_func()->shortcutMap.removeShortcut(id, this, 0);
+}
+
+/*!
+ \since 4.5
+
+ If \a enabled is true, the shortcut with the given \a id is
+ enabled; otherwise the shortcut is disabled.
+
+ \warning You should not normally need to use this function since
+ Qt's shortcut system enables/disables shortcuts automatically as
+ widgets become hidden/visible and gain or lose focus. It is best
+ to use QAction or QShortcut to handle shortcuts, since they are
+ easier to use than this low-level function.
+
+ \sa grabShortcut() releaseShortcut(), QWidget::setShortcutEnabled()
+*/
+void QGraphicsWidget::setShortcutEnabled(int id, bool enabled)
+{
+ Q_ASSERT(qApp);
+ if (id)
+ qApp->d_func()->shortcutMap.setShortcutEnabled(enabled, id, this, 0);
+}
+
+/*!
+ \since 4.5
+
+ If \a enabled is true, auto repeat of the shortcut with the
+ given \a id is enabled; otherwise it is disabled.
+
+ \sa grabShortcut() releaseShortcut() QWidget::setShortcutAutoRepeat()
+*/
+void QGraphicsWidget::setShortcutAutoRepeat(int id, bool enabled)
+{
+ Q_ASSERT(qApp);
+ if (id)
+ qApp->d_func()->shortcutMap.setShortcutAutoRepeat(enabled, id, this, 0);
+}
+#endif
+
+#ifndef QT_NO_ACTION
+/*!
+ \since 4.5
+
+ Appends the action \a action to this widget's list of actions.
+
+ All QGraphicsWidgets have a list of \l{QAction}s, however they can be
+ represented graphically in many different ways. The default use of the
+ QAction list (as returned by actions()) is to create a context QMenu.
+
+ A QGraphicsWidget should only have one of each action and adding an action
+ it already has will not cause the same action to be in the widget twice.
+
+ \sa removeAction(), insertAction(), actions(), QWidget::addAction()
+*/
+void QGraphicsWidget::addAction(QAction *action)
+{
+ insertAction(0, action);
+}
+
+/*!
+ \since 4.5
+
+ Appends the actions \a actions to this widget's list of actions.
+
+ \sa removeAction(), QMenu, addAction(), QWidget::addActions()
+*/
+void QGraphicsWidget::addActions(QList<QAction *> actions)
+{
+ for (int i = 0; i < actions.count(); ++i)
+ insertAction(0, actions.at(i));
+}
+
+/*!
+ \since 4.5
+
+ Inserts the action \a action to this widget's list of actions,
+ before the action \a before. It appends the action if \a before is 0 or
+ \a before is not a valid action for this widget.
+
+ A QGraphicsWidget should only have one of each action.
+
+ \sa removeAction(), addAction(), QMenu, actions(),
+ QWidget::insertActions()
+*/
+void QGraphicsWidget::insertAction(QAction *before, QAction *action)
+{
+ if (!action) {
+ qWarning("QWidget::insertAction: Attempt to insert null action");
+ return;
+ }
+
+ Q_D(QGraphicsWidget);
+ int index = d->actions.indexOf(action);
+ if (index != -1)
+ d->actions.removeAt(index);
+
+ int pos = d->actions.indexOf(before);
+ if (pos < 0) {
+ before = 0;
+ pos = d->actions.size();
+ }
+ d->actions.insert(pos, action);
+
+ if (index == -1) {
+ QActionPrivate *apriv = action->d_func();
+ apriv->graphicsWidgets.append(this);
+ }
+
+ QActionEvent e(QEvent::ActionAdded, action, before);
+ QApplication::sendEvent(this, &e);
+}
+
+/*!
+ \since 4.5
+
+ Inserts the actions \a actions to this widget's list of actions,
+ before the action \a before. It appends the action if \a before is 0 or
+ \a before is not a valid action for this widget.
+
+ A QGraphicsWidget can have at most one of each action.
+
+ \sa removeAction(), QMenu, insertAction(), QWidget::insertActions()
+*/
+void QGraphicsWidget::insertActions(QAction *before, QList<QAction *> actions)
+{
+ for (int i = 0; i < actions.count(); ++i)
+ insertAction(before, actions.at(i));
+}
+
+/*!
+ \since 4.5
+
+ Removes the action \a action from this widget's list of actions.
+
+ \sa insertAction(), actions(), insertAction(), QWidget::removeAction()
+*/
+void QGraphicsWidget::removeAction(QAction *action)
+{
+ if (!action)
+ return;
+
+ Q_D(QGraphicsWidget);
+
+ QActionPrivate *apriv = action->d_func();
+ apriv->graphicsWidgets.removeAll(this);
+
+ if (d->actions.removeAll(action)) {
+ QActionEvent e(QEvent::ActionRemoved, action);
+ QApplication::sendEvent(this, &e);
+ }
+}
+
+/*!
+ \since 4.5
+
+ Returns the (possibly empty) list of this widget's actions.
+
+ \sa insertAction(), removeAction(), QWidget::actions(),
+ QAction::associatedWidgets(), QAction::associatedGraphicsWidgets()
+*/
+QList<QAction *> QGraphicsWidget::actions() const
+{
+ Q_D(const QGraphicsWidget);
+ return d->actions;
+}
+#endif
+
+/*!
+ Moves the \a second widget around the ring of focus widgets so that
+ keyboard focus moves from the \a first widget to the \a second widget when
+ the Tab key is pressed.
+
+ Note that since the tab order of the \a second widget is changed, you
+ should order a chain like this:
+
+ \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicswidget.cpp 1
+
+ \e not like this:
+
+ \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicswidget.cpp 2
+
+ If \a first is 0, this indicates that \a second should be the first widget
+ to receive input focus should the scene gain Tab focus (i.e., the user
+ hits Tab so that focus passes into the scene). If \a second is 0, this
+ indicates that \a first should be the first widget to gain focus if the
+ scene gained BackTab focus.
+
+ By default, tab order is defined implicitly using widget creation order.
+
+ \sa focusPolicy, {Keyboard Focus}
+*/
+void QGraphicsWidget::setTabOrder(QGraphicsWidget *first, QGraphicsWidget *second)
+{
+ if (!first && !second) {
+ qWarning("QGraphicsWidget::setTabOrder(0, 0) is undefined");
+ return;
+ }
+ if ((first && second) && first->scene() != second->scene()) {
+ qWarning("QGraphicsWidget::setTabOrder: scenes %p and %p are different",
+ first->scene(), second->scene());
+ return;
+ }
+ QGraphicsScene *scene = first ? first->scene() : second->scene();
+ if (!scene && (!first || !second)) {
+ qWarning("QGraphicsWidget::setTabOrder: assigning tab order from/to the"
+ " scene requires the item to be in a scene.");
+ return;
+ }
+
+ // If either first or second are 0, the scene's tabFocusFirst is updated
+ // to point to the first item in the scene's focus chain. Then first or
+ // second are set to point to tabFocusFirst.
+ QGraphicsScenePrivate *sceneD = scene->d_func();
+ if (!first) {
+ sceneD->tabFocusFirst = second;
+ return;
+ }
+ if (!second) {
+ sceneD->tabFocusFirst = first->d_func()->focusNext;
+ return;
+ }
+
+ // Both first and second are != 0.
+ QGraphicsWidget *firstFocusNext = first->d_func()->focusNext;
+ if (firstFocusNext == second) {
+ // Nothing to do.
+ return;
+ }
+
+ // Update the focus chain.
+ QGraphicsWidget *secondFocusPrev = second->d_func()->focusPrev;
+ QGraphicsWidget *secondFocusNext = second->d_func()->focusNext;
+ firstFocusNext->d_func()->focusPrev = second;
+ first->d_func()->focusNext = second;
+ second->d_func()->focusNext = firstFocusNext;
+ second->d_func()->focusPrev = first;
+ secondFocusPrev->d_func()->focusNext = secondFocusNext;
+ secondFocusNext->d_func()->focusPrev = secondFocusPrev;
+
+ Q_ASSERT(first->d_func()->focusNext->d_func()->focusPrev == first);
+ Q_ASSERT(first->d_func()->focusPrev->d_func()->focusNext == first);
+
+ Q_ASSERT(second->d_func()->focusNext->d_func()->focusPrev == second);
+ Q_ASSERT(second->d_func()->focusPrev->d_func()->focusNext == second);
+
+}
+
+/*!
+ If \a on is true, this function enables \a attribute; otherwise
+ \a attribute is disabled.
+
+ See the class documentation for QGraphicsWidget for a complete list of
+ which attributes are supported, and what they are for.
+
+ \sa testAttribute(), QWidget::setAttribute()
+*/
+void QGraphicsWidget::setAttribute(Qt::WidgetAttribute attribute, bool on)
+{
+ Q_D(QGraphicsWidget);
+ // ### most flags require some immediate action
+ // ### we might want to qWarn use of unsupported attributes
+ // ### we might want to not use Qt::WidgetAttribute, but roll our own instead
+ d->setAttribute(attribute, on);
+}
+
+/*!
+ Returns true if \a attribute is enabled for this widget; otherwise,
+ returns false.
+
+ \sa setAttribute()
+*/
+bool QGraphicsWidget::testAttribute(Qt::WidgetAttribute attribute) const
+{
+ Q_D(const QGraphicsWidget);
+ return d->testAttribute(attribute);
+}
+
+/*!
+ \reimp
+*/
+int QGraphicsWidget::type() const
+{
+ return Type;
+}
+
+/*!
+ \reimp
+*/
+void QGraphicsWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+ Q_UNUSED(painter);
+ Q_UNUSED(option);
+ Q_UNUSED(widget);
+}
+
+/*!
+ This virtual function is called by QGraphicsScene to draw the window frame
+ for windows using \a painter, \a option, and \a widget, in local
+ coordinates. The base implementation uses the current style to render the
+ frame and title bar.
+
+ You can reimplement this function in a subclass of QGraphicsWidget to
+ provide custom rendering of the widget's window frame.
+
+ \sa QGraphicsItem::paint()
+*/
+void QGraphicsWidget::paintWindowFrame(QPainter *painter, const QStyleOptionGraphicsItem *option,
+ QWidget *widget)
+{
+ const bool fillBackground = !testAttribute(Qt::WA_OpaquePaintEvent)
+ && !testAttribute(Qt::WA_NoSystemBackground);
+ QGraphicsProxyWidget *proxy = qobject_cast<QGraphicsProxyWidget *>(this);
+ const bool embeddedWidgetFillsOwnBackground = proxy && proxy->widget();
+
+ if (rect().contains(option->exposedRect)) {
+ if (fillBackground && !embeddedWidgetFillsOwnBackground)
+ painter->fillRect(option->exposedRect, palette().window());
+ return;
+ }
+
+ Q_D(QGraphicsWidget);
+
+ QRect windowFrameRect = QRect(QPoint(), windowFrameGeometry().size().toSize());
+ QStyleOptionTitleBar bar;
+ bar.QStyleOption::operator=(*option);
+ d->initStyleOptionTitleBar(&bar); // this clear flags in bar.state
+ d->ensureWindowData();
+ if (d->windowData->buttonMouseOver)
+ bar.state |= QStyle::State_MouseOver;
+ else
+ bar.state &= ~QStyle::State_MouseOver;
+ if (d->windowData->buttonSunken)
+ bar.state |= QStyle::State_Sunken;
+ else
+ bar.state &= ~QStyle::State_Sunken;
+
+ bar.rect = windowFrameRect;
+
+ // translate painter to make the style happy
+ const QPointF styleOrigin = this->windowFrameRect().topLeft();
+ painter->translate(styleOrigin);
+
+#ifdef Q_WS_MAC
+ const QSize pixmapSize = windowFrameRect.size();
+ if (pixmapSize.width() <= 0 || pixmapSize.height() <= 0)
+ return;
+ QPainter *realPainter = painter;
+ QPixmap pm(pixmapSize);
+ painter = new QPainter(&pm);
+#endif
+
+ // Fill background
+ QStyleHintReturnMask mask;
+ bool setMask = style()->styleHint(QStyle::SH_WindowFrame_Mask, &bar, widget, &mask) && !mask.region.isEmpty();
+ bool hasBorder = !style()->styleHint(QStyle::SH_TitleBar_NoBorder, &bar, widget);
+ int frameWidth = style()->pixelMetric(QStyle::PM_MDIFrameWidth, &bar, widget);
+ if (setMask) {
+ painter->save();
+ painter->setClipRegion(mask.region, Qt::IntersectClip);
+ }
+ if (fillBackground) {
+ if (embeddedWidgetFillsOwnBackground) {
+ // Don't fill the background twice.
+ QPainterPath windowFrameBackground;
+ windowFrameBackground.addRect(windowFrameRect);
+ // Adjust with 0.5 to avoid border artifacts between
+ // widget background and frame background.
+ windowFrameBackground.addRect(rect().translated(-styleOrigin).adjusted(0.5, 0.5, -0.5, -0.5));
+ painter->fillPath(windowFrameBackground, palette().window());
+ } else {
+ painter->fillRect(windowFrameRect, palette().window());
+ }
+ }
+ painter->setRenderHint(QPainter::NonCosmeticDefaultPen);
+
+ // Draw title
+ int height = (int)d->titleBarHeight(bar);
+ bar.rect.setHeight(height);
+ if (hasBorder) // Frame is painted by PE_FrameWindow
+ bar.rect.adjust(frameWidth, frameWidth, -frameWidth, 0);
+
+ painter->save();
+ painter->setFont(QApplication::font("QWorkspaceTitleBar"));
+ style()->drawComplexControl(QStyle::CC_TitleBar, &bar, painter, widget);
+ painter->restore();
+ if (setMask)
+ painter->restore();
+ // Draw window frame
+ QStyleOptionFrame frameOptions;
+ frameOptions.QStyleOption::operator=(*option);
+ initStyleOption(&frameOptions);
+ if (!hasBorder)
+ painter->setClipRect(windowFrameRect.adjusted(0, +height, 0, 0), Qt::IntersectClip);
+ if (hasFocus()) {
+ frameOptions.state |= QStyle::State_HasFocus;
+ } else {
+ frameOptions.state &= ~QStyle::State_HasFocus;
+ }
+ bool isActive = isActiveWindow();
+ if (isActive) {
+ frameOptions.state |= QStyle::State_Active;
+ } else {
+ frameOptions.state &= ~QStyle::State_Active;
+ }
+
+ frameOptions.palette.setCurrentColorGroup(isActive ? QPalette::Active : QPalette::Normal);
+ frameOptions.rect = windowFrameRect;
+ frameOptions.lineWidth = style()->pixelMetric(QStyle::PM_MdiSubWindowFrameWidth, 0, widget);
+ frameOptions.midLineWidth = 1;
+ style()->drawPrimitive(QStyle::PE_FrameWindow, &frameOptions, painter, widget);
+
+#ifdef Q_WS_MAC
+ realPainter->drawPixmap(QPoint(), pm);
+ delete painter;
+#endif
+}
+
+/*!
+ \reimp
+*/
+QRectF QGraphicsWidget::boundingRect() const
+{
+ return windowFrameRect();
+}
+
+/*!
+ \reimp
+*/
+QPainterPath QGraphicsWidget::shape() const
+{
+ QPainterPath path;
+ path.addRect(rect());
+ return path;
+}
+
+/*!
+ Call this function to close the widget.
+
+ Returns true if the widget was closed; otherwise returns false.
+ This slot will first send a QCloseEvent to the widget, which may or may
+ not accept the event. If the event was ignored, nothing happens. If the
+ event was accepted, it will hide() the widget.
+
+ If the widget has the Qt::WA_DeleteOnClose attribute set it will be
+ deleted.
+*/
+bool QGraphicsWidget::close()
+{
+ QCloseEvent closeEvent;
+ QApplication::sendEvent(this, &closeEvent);
+ if (!closeEvent.isAccepted()) {
+ return false;
+ }
+ // hide
+ if (isVisible()) {
+ hide();
+ }
+ if (testAttribute(Qt::WA_DeleteOnClose)) {
+ deleteLater();
+ }
+ return true;
+}
+
+#ifdef Q_NO_USING_KEYWORD
+/*!
+ \fn const QObjectList &QGraphicsWidget::children() const
+ \internal
+
+ This function returns the same value as QObject::children(). It's
+ provided to differentiate between the obsolete member
+ QGraphicsItem::children() and QObject::children(). QGraphicsItem now
+ provides childItems() instead.
+*/
+#endif
+
+#if 0
+void QGraphicsWidget::dumpFocusChain()
+{
+ qDebug() << "=========== Dumping focus chain ==============";
+ int i = 0;
+ QGraphicsWidget *next = this;
+ QSet<QGraphicsWidget*> visited;
+ do {
+ if (!next) {
+ qWarning("Found a focus chain that is not circular, (next == 0)");
+ break;
+ }
+ qDebug() << i++ << QString::number(uint(next), 16) << next->className() << next->data(0) << QString::fromAscii("focusItem:%1").arg(next->hasFocus() ? '1' : '0') << QLatin1String("next:") << next->d_func()->focusNext->data(0) << QLatin1String("prev:") << next->d_func()->focusPrev->data(0);
+ if (visited.contains(next)) {
+ qWarning("Already visited this node. However, I expected to dump until I found myself.");
+ break;
+ }
+ visited << next;
+ next = next->d_func()->focusNext;
+ } while (next != this);
+}
+#endif
+
+QT_END_NAMESPACE
+
+#endif //QT_NO_GRAPHICSVIEW
diff --git a/src/widgets/graphicsview/qgraphicswidget.h b/src/widgets/graphicsview/qgraphicswidget.h
new file mode 100644
index 0000000000..8222886411
--- /dev/null
+++ b/src/widgets/graphicsview/qgraphicswidget.h
@@ -0,0 +1,257 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGRAPHICSWIDGET_H
+#define QGRAPHICSWIDGET_H
+
+#include <QtGui/qfont.h>
+#include <QtWidgets/qgraphicslayoutitem.h>
+#include <QtWidgets/qgraphicsitem.h>
+#include <QtGui/qpalette.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QFont;
+class QFontMetrics;
+class QGraphicsLayout;
+class QGraphicsSceneMoveEvent;
+class QGraphicsWidgetPrivate;
+class QGraphicsSceneResizeEvent;
+class QStyle;
+class QStyleOption;
+
+#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW
+
+class QGraphicsWidgetPrivate;
+
+class Q_WIDGETS_EXPORT QGraphicsWidget : public QGraphicsObject, public QGraphicsLayoutItem
+{
+ Q_OBJECT
+ Q_INTERFACES(QGraphicsItem QGraphicsLayoutItem)
+ Q_PROPERTY(QPalette palette READ palette WRITE setPalette)
+ Q_PROPERTY(QFont font READ font WRITE setFont)
+ Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection RESET unsetLayoutDirection)
+ Q_PROPERTY(QSizeF size READ size WRITE resize NOTIFY geometryChanged)
+ Q_PROPERTY(QSizeF minimumSize READ minimumSize WRITE setMinimumSize)
+ Q_PROPERTY(QSizeF preferredSize READ preferredSize WRITE setPreferredSize)
+ Q_PROPERTY(QSizeF maximumSize READ maximumSize WRITE setMaximumSize)
+ Q_PROPERTY(QSizePolicy sizePolicy READ sizePolicy WRITE setSizePolicy)
+ Q_PROPERTY(Qt::FocusPolicy focusPolicy READ focusPolicy WRITE setFocusPolicy)
+ Q_PROPERTY(Qt::WindowFlags windowFlags READ windowFlags WRITE setWindowFlags)
+ Q_PROPERTY(QString windowTitle READ windowTitle WRITE setWindowTitle)
+ Q_PROPERTY(QRectF geometry READ geometry WRITE setGeometry NOTIFY geometryChanged)
+ Q_PROPERTY(bool autoFillBackground READ autoFillBackground WRITE setAutoFillBackground)
+ Q_PROPERTY(QGraphicsLayout* layout READ layout WRITE setLayout NOTIFY layoutChanged)
+public:
+ QGraphicsWidget(QGraphicsItem *parent = 0, Qt::WindowFlags wFlags = 0);
+ ~QGraphicsWidget();
+ QGraphicsLayout *layout() const;
+ void setLayout(QGraphicsLayout *layout);
+ void adjustSize();
+
+ Qt::LayoutDirection layoutDirection() const;
+ void setLayoutDirection(Qt::LayoutDirection direction);
+ void unsetLayoutDirection();
+
+ QStyle *style() const;
+ void setStyle(QStyle *style);
+
+ QFont font() const;
+ void setFont(const QFont &font);
+
+ QPalette palette() const;
+ void setPalette(const QPalette &palette);
+
+ bool autoFillBackground() const;
+ void setAutoFillBackground(bool enabled);
+
+ void resize(const QSizeF &size);
+ inline void resize(qreal w, qreal h) { resize(QSizeF(w, h)); }
+ QSizeF size() const;
+
+ void setGeometry(const QRectF &rect);
+ inline void setGeometry(qreal x, qreal y, qreal w, qreal h);
+ inline QRectF rect() const { return QRectF(QPointF(), size()); }
+
+ void setContentsMargins(qreal left, qreal top, qreal right, qreal bottom);
+ void getContentsMargins(qreal *left, qreal *top, qreal *right, qreal *bottom) const;
+
+ void setWindowFrameMargins(qreal left, qreal top, qreal right, qreal bottom);
+ void getWindowFrameMargins(qreal *left, qreal *top, qreal *right, qreal *bottom) const;
+ void unsetWindowFrameMargins();
+ QRectF windowFrameGeometry() const;
+ QRectF windowFrameRect() const;
+
+ // Window handling
+ Qt::WindowFlags windowFlags() const;
+ Qt::WindowType windowType() const;
+ void setWindowFlags(Qt::WindowFlags wFlags);
+ bool isActiveWindow() const;
+ void setWindowTitle(const QString &title);
+ QString windowTitle() const;
+
+ // Focus handling
+ Qt::FocusPolicy focusPolicy() const;
+ void setFocusPolicy(Qt::FocusPolicy policy);
+ static void setTabOrder(QGraphicsWidget *first, QGraphicsWidget *second);
+ QGraphicsWidget *focusWidget() const;
+
+#ifndef QT_NO_SHORTCUT
+ int grabShortcut(const QKeySequence &sequence, Qt::ShortcutContext context = Qt::WindowShortcut);
+ void releaseShortcut(int id);
+ void setShortcutEnabled(int id, bool enabled = true);
+ void setShortcutAutoRepeat(int id, bool enabled = true);
+#endif
+
+#ifndef QT_NO_ACTION
+ //actions
+ void addAction(QAction *action);
+ void addActions(QList<QAction*> actions);
+ void insertAction(QAction *before, QAction *action);
+ void insertActions(QAction *before, QList<QAction*> actions);
+ void removeAction(QAction *action);
+ QList<QAction*> actions() const;
+#endif
+
+ void setAttribute(Qt::WidgetAttribute attribute, bool on = true);
+ bool testAttribute(Qt::WidgetAttribute attribute) const;
+
+ enum {
+ Type = 11
+ };
+ int type() const;
+
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
+ virtual void paintWindowFrame(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
+ QRectF boundingRect() const;
+ QPainterPath shape() const;
+
+#if 0
+ void dumpFocusChain();
+#endif
+
+ // ### Qt 5: Disambiguate
+#ifdef Q_NO_USING_KEYWORD
+ const QObjectList &children() const { return QObject::children(); }
+#else
+ using QObject::children;
+#endif
+
+Q_SIGNALS:
+ void geometryChanged();
+ void layoutChanged();
+
+public Q_SLOTS:
+ bool close();
+
+protected:
+ virtual void initStyleOption(QStyleOption *option) const;
+
+ QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const;
+ void updateGeometry();
+
+ // Notification
+ QVariant itemChange(GraphicsItemChange change, const QVariant &value);
+ virtual QVariant propertyChange(const QString &propertyName, const QVariant &value);
+
+ // Scene events
+ bool sceneEvent(QEvent *event);
+ virtual bool windowFrameEvent(QEvent *e);
+ virtual Qt::WindowFrameSection windowFrameSectionAt(const QPointF& pos) const;
+
+ // Base event handlers
+ bool event(QEvent *event);
+ //virtual void actionEvent(QActionEvent *event);
+ virtual void changeEvent(QEvent *event);
+ virtual void closeEvent(QCloseEvent *event);
+ //void create(WId window = 0, bool initializeWindow = true, bool destroyOldWindow = true);
+ //void destroy(bool destroyWindow = true, bool destroySubWindows = true);
+ void focusInEvent(QFocusEvent *event);
+ virtual bool focusNextPrevChild(bool next);
+ void focusOutEvent(QFocusEvent *event);
+ virtual void hideEvent(QHideEvent *event);
+ //virtual bool macEvent(EventHandlerCallRef caller, EventRef event);
+ //virtual int metric(PaintDeviceMetric m ) const;
+ virtual void moveEvent(QGraphicsSceneMoveEvent *event);
+ virtual void polishEvent();
+ //virtual bool qwsEvent(QWSEvent *event);
+ //void resetInputContext ();
+ virtual void resizeEvent(QGraphicsSceneResizeEvent *event);
+ virtual void showEvent(QShowEvent *event);
+ //virtual void tabletEvent(QTabletEvent *event);
+ //virtual bool winEvent(MSG *message, long *result);
+ //virtual bool x11Event(XEvent *event);
+ virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *event);
+ virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
+ virtual void grabMouseEvent(QEvent *event);
+ virtual void ungrabMouseEvent(QEvent *event);
+ virtual void grabKeyboardEvent(QEvent *event);
+ virtual void ungrabKeyboardEvent(QEvent *event);
+ QGraphicsWidget(QGraphicsWidgetPrivate &, QGraphicsItem *parent, QGraphicsScene *, Qt::WindowFlags wFlags = 0);
+
+private:
+ Q_DISABLE_COPY(QGraphicsWidget)
+ Q_DECLARE_PRIVATE_D(QGraphicsItem::d_ptr.data(), QGraphicsWidget)
+ friend class QGraphicsScene;
+ friend class QGraphicsScenePrivate;
+ friend class QGraphicsView;
+ friend class QGraphicsItem;
+ friend class QGraphicsItemPrivate;
+ friend class QGraphicsLayout;
+ friend class QWidget;
+ friend class QApplication;
+};
+
+inline void QGraphicsWidget::setGeometry(qreal ax, qreal ay, qreal aw, qreal ah)
+{ setGeometry(QRectF(ax, ay, aw, ah)); }
+
+#endif
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
+
diff --git a/src/widgets/graphicsview/qgraphicswidget_p.cpp b/src/widgets/graphicsview/qgraphicswidget_p.cpp
new file mode 100644
index 0000000000..fd5afaabf4
--- /dev/null
+++ b/src/widgets/graphicsview/qgraphicswidget_p.cpp
@@ -0,0 +1,906 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qglobal.h"
+
+#ifndef QT_NO_GRAPHICSVIEW
+
+#include <QtCore/qdebug.h>
+#include <QtCore/qnumeric.h>
+#include "qgraphicswidget_p.h"
+#include "qgraphicslayoutitem_p.h"
+#include "qgraphicslayout.h"
+#include "qgraphicsscene_p.h"
+#include <QtWidgets/qapplication.h>
+#include <QtWidgets/qgraphicsscene.h>
+#include <QtWidgets/qstyleoption.h>
+#include <QtWidgets/QStyleOptionTitleBar>
+#include <QtWidgets/QGraphicsSceneMouseEvent>
+#if defined(Q_WS_MAC) && !defined(QT_NO_STYLE_MAC)
+# include <QMacStyle>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+void QGraphicsWidgetPrivate::init(QGraphicsItem *parentItem, Qt::WindowFlags wFlags)
+{
+ Q_Q(QGraphicsWidget);
+
+ attributes = 0;
+ isWidget = 1; // QGraphicsItem::isWidget() returns true.
+ focusNext = focusPrev = q;
+ focusPolicy = Qt::NoFocus;
+
+ adjustWindowFlags(&wFlags);
+ windowFlags = wFlags;
+
+ if (parentItem)
+ setParentItemHelper(parentItem, 0, 0);
+
+ q->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred, QSizePolicy::DefaultType));
+ q->setGraphicsItem(q);
+
+ resolveLayoutDirection();
+ q->unsetWindowFrameMargins();
+ flags |= QGraphicsItem::ItemUsesExtendedStyleOption;
+ flags |= QGraphicsItem::ItemSendsGeometryChanges;
+ if (windowFlags & Qt::Window)
+ flags |= QGraphicsItem::ItemIsPanel;
+}
+
+qreal QGraphicsWidgetPrivate::titleBarHeight(const QStyleOptionTitleBar &options) const
+{
+ Q_Q(const QGraphicsWidget);
+ int height = q->style()->pixelMetric(QStyle::PM_TitleBarHeight, &options);
+#if defined(Q_WS_MAC) && !defined(QT_NO_STYLE_MAC)
+ if (qobject_cast<QMacStyle*>(q->style())) {
+ height -=4;
+ }
+#endif
+ return (qreal)height;
+}
+
+/*!
+ \internal
+*/
+QGraphicsWidgetPrivate::~QGraphicsWidgetPrivate()
+{
+ // Remove any lazily allocated data
+ delete[] margins;
+ delete[] windowFrameMargins;
+ delete windowData;
+}
+
+/*!
+ \internal
+
+ Ensures that margins is allocated.
+ This function must be called before any dereferencing.
+*/
+void QGraphicsWidgetPrivate::ensureMargins() const
+{
+ if (!margins) {
+ margins = new qreal[4];
+ for (int i = 0; i < 4; ++i)
+ margins[i] = 0;
+ }
+}
+
+/*!
+ \internal
+
+ Ensures that windowFrameMargins is allocated.
+ This function must be called before any dereferencing.
+*/
+void QGraphicsWidgetPrivate::ensureWindowFrameMargins() const
+{
+ if (!windowFrameMargins) {
+ windowFrameMargins = new qreal[4];
+ for (int i = 0; i < 4; ++i)
+ windowFrameMargins[i] = 0;
+ }
+}
+
+/*!
+ \internal
+
+ Ensures that windowData is allocated.
+ This function must be called before any dereferencing.
+*/
+void QGraphicsWidgetPrivate::ensureWindowData()
+{
+ if (!windowData)
+ windowData = new WindowData;
+}
+
+void QGraphicsWidgetPrivate::setPalette_helper(const QPalette &palette)
+{
+ if (this->palette == palette && this->palette.resolve() == palette.resolve())
+ return;
+ updatePalette(palette);
+}
+
+void QGraphicsWidgetPrivate::resolvePalette(uint inheritedMask)
+{
+ inheritedPaletteResolveMask = inheritedMask;
+ QPalette naturalPalette = naturalWidgetPalette();
+ QPalette resolvedPalette = palette.resolve(naturalPalette);
+ updatePalette(resolvedPalette);
+}
+
+void QGraphicsWidgetPrivate::updatePalette(const QPalette &palette)
+{
+ Q_Q(QGraphicsWidget);
+ // Update local palette setting.
+ this->palette = palette;
+
+ // Calculate new mask.
+ if (q->isWindow() && !q->testAttribute(Qt::WA_WindowPropagation))
+ inheritedPaletteResolveMask = 0;
+ int mask = palette.resolve() | inheritedPaletteResolveMask;
+
+ // Propagate to children.
+ for (int i = 0; i < children.size(); ++i) {
+ QGraphicsItem *item = children.at(i);
+ if (item->isWidget()) {
+ QGraphicsWidget *w = static_cast<QGraphicsWidget *>(item);
+ if (!w->isWindow() || w->testAttribute(Qt::WA_WindowPropagation))
+ w->d_func()->resolvePalette(mask);
+ } else {
+ item->d_ptr->resolvePalette(mask);
+ }
+ }
+
+ // Notify change.
+ QEvent event(QEvent::PaletteChange);
+ QApplication::sendEvent(q, &event);
+}
+
+void QGraphicsWidgetPrivate::setLayoutDirection_helper(Qt::LayoutDirection direction)
+{
+ Q_Q(QGraphicsWidget);
+ if ((direction == Qt::RightToLeft) == (testAttribute(Qt::WA_RightToLeft)))
+ return;
+ q->setAttribute(Qt::WA_RightToLeft, (direction == Qt::RightToLeft));
+
+ // Propagate this change to all children.
+ for (int i = 0; i < children.size(); ++i) {
+ QGraphicsItem *item = children.at(i);
+ if (item->isWidget()) {
+ QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(item);
+ if (widget->parentWidget() && !widget->testAttribute(Qt::WA_SetLayoutDirection))
+ widget->d_func()->setLayoutDirection_helper(direction);
+ }
+ }
+
+ // Send the notification event to this widget item.
+ QEvent e(QEvent::LayoutDirectionChange);
+ QApplication::sendEvent(q, &e);
+}
+
+void QGraphicsWidgetPrivate::resolveLayoutDirection()
+{
+ Q_Q(QGraphicsWidget);
+ if (q->testAttribute(Qt::WA_SetLayoutDirection)) {
+ return;
+ }
+ if (QGraphicsWidget *parentWidget = q->parentWidget()) {
+ setLayoutDirection_helper(parentWidget->layoutDirection());
+ } else if (scene) {
+ // ### shouldn't the scene have a layoutdirection really? how does
+ // ### QGraphicsWidget get changes from QApplication::layoutDirection?
+ setLayoutDirection_helper(QApplication::layoutDirection());
+ } else {
+ setLayoutDirection_helper(QApplication::layoutDirection());
+ }
+}
+
+QPalette QGraphicsWidgetPrivate::naturalWidgetPalette() const
+{
+ Q_Q(const QGraphicsWidget);
+ QPalette palette;
+ if (QGraphicsWidget *parent = q->parentWidget()) {
+ palette = parent->palette();
+ } else if (scene) {
+ palette = scene->palette();
+ }
+ palette.resolve(0);
+ return palette;
+}
+
+void QGraphicsWidgetPrivate::setFont_helper(const QFont &font)
+{
+ if (this->font == font && this->font.resolve() == font.resolve())
+ return;
+ updateFont(font);
+}
+
+void QGraphicsWidgetPrivate::resolveFont(uint inheritedMask)
+{
+ Q_Q(QGraphicsWidget);
+ inheritedFontResolveMask = inheritedMask;
+ if (QGraphicsWidget *p = q->parentWidget())
+ inheritedFontResolveMask |= p->d_func()->inheritedFontResolveMask;
+ QFont naturalFont = naturalWidgetFont();
+ QFont resolvedFont = font.resolve(naturalFont);
+ updateFont(resolvedFont);
+}
+
+void QGraphicsWidgetPrivate::updateFont(const QFont &font)
+{
+ Q_Q(QGraphicsWidget);
+ // Update the local font setting.
+ this->font = font;
+
+ // Calculate new mask.
+ if (q->isWindow() && !q->testAttribute(Qt::WA_WindowPropagation))
+ inheritedFontResolveMask = 0;
+ int mask = font.resolve() | inheritedFontResolveMask;
+
+ // Propagate to children.
+ for (int i = 0; i < children.size(); ++i) {
+ QGraphicsItem *item = children.at(i);
+ if (item->isWidget()) {
+ QGraphicsWidget *w = static_cast<QGraphicsWidget *>(item);
+ if (!w->isWindow() || w->testAttribute(Qt::WA_WindowPropagation))
+ w->d_func()->resolveFont(mask);
+ } else {
+ item->d_ptr->resolveFont(mask);
+ }
+ }
+
+ if (!polished)
+ return;
+ // Notify change.
+ QEvent event(QEvent::FontChange);
+ QApplication::sendEvent(q, &event);
+}
+
+QFont QGraphicsWidgetPrivate::naturalWidgetFont() const
+{
+ Q_Q(const QGraphicsWidget);
+ QFont naturalFont; // ### no application font support
+ if (QGraphicsWidget *parent = q->parentWidget()) {
+ naturalFont = parent->font();
+ } else if (scene) {
+ naturalFont = scene->font();
+ }
+ naturalFont.resolve(0);
+ return naturalFont;
+}
+
+void QGraphicsWidgetPrivate::initStyleOptionTitleBar(QStyleOptionTitleBar *option)
+{
+ Q_Q(QGraphicsWidget);
+ ensureWindowData();
+ q->initStyleOption(option);
+ option->rect.setHeight(titleBarHeight(*option));
+ option->titleBarFlags = windowFlags;
+ option->subControls = QStyle::SC_TitleBarCloseButton | QStyle::SC_TitleBarLabel | QStyle::SC_TitleBarSysMenu;
+ option->activeSubControls = windowData->hoveredSubControl;
+ bool isActive = q->isActiveWindow();
+ if (isActive) {
+ option->state |= QStyle::State_Active;
+ option->titleBarState = Qt::WindowActive;
+ option->titleBarState |= QStyle::State_Active;
+ } else {
+ option->state &= ~QStyle::State_Active;
+ option->titleBarState = Qt::WindowNoState;
+ }
+ QFont windowTitleFont = QApplication::font("QWorkspaceTitleBar");
+ QRect textRect = q->style()->subControlRect(QStyle::CC_TitleBar, option, QStyle::SC_TitleBarLabel, 0);
+ option->text = QFontMetrics(windowTitleFont).elidedText(
+ windowData->windowTitle, Qt::ElideRight, textRect.width());
+}
+
+void QGraphicsWidgetPrivate::adjustWindowFlags(Qt::WindowFlags *flags)
+{
+ bool customize = (*flags & (Qt::CustomizeWindowHint
+ | Qt::FramelessWindowHint
+ | Qt::WindowTitleHint
+ | Qt::WindowSystemMenuHint
+ | Qt::WindowMinimizeButtonHint
+ | Qt::WindowMaximizeButtonHint
+ | Qt::WindowContextHelpButtonHint));
+
+ uint type = (*flags & Qt::WindowType_Mask);
+ if (customize)
+ ;
+ else if (type == Qt::Dialog || type == Qt::Sheet)
+ *flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowContextHelpButtonHint;
+ else if (type == Qt::Tool)
+ *flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint;
+ else if (type == Qt::Window || type == Qt::SubWindow)
+ *flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint
+ | Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint;
+}
+
+void QGraphicsWidgetPrivate::windowFrameMouseReleaseEvent(QGraphicsSceneMouseEvent *event)
+{
+ Q_Q(QGraphicsWidget);
+ ensureWindowData();
+ if (windowData->grabbedSection != Qt::NoSection) {
+ if (windowData->grabbedSection == Qt::TitleBarArea) {
+ windowData->buttonSunken = false;
+ QStyleOptionTitleBar bar;
+ initStyleOptionTitleBar(&bar);
+ // make sure that the coordinates (rect and pos) we send to the style are positive.
+ bar.rect = q->windowFrameRect().toRect();
+ bar.rect.moveTo(0,0);
+ bar.rect.setHeight(q->style()->pixelMetric(QStyle::PM_TitleBarHeight, &bar));
+ QPointF pos = event->pos();
+ if (windowFrameMargins) {
+ pos.rx() += windowFrameMargins[Left];
+ pos.ry() += windowFrameMargins[Top];
+ }
+ bar.subControls = QStyle::SC_TitleBarCloseButton;
+ if (q->style()->subControlRect(QStyle::CC_TitleBar, &bar,
+ QStyle::SC_TitleBarCloseButton,
+ event->widget()).contains(pos.toPoint())) {
+ q->close();
+ }
+ }
+ if (!(static_cast<QGraphicsSceneMouseEvent *>(event)->buttons()))
+ windowData->grabbedSection = Qt::NoSection;
+ event->accept();
+ }
+}
+
+void QGraphicsWidgetPrivate::windowFrameMousePressEvent(QGraphicsSceneMouseEvent *event)
+{
+ Q_Q(QGraphicsWidget);
+ if (event->button() != Qt::LeftButton)
+ return;
+
+ ensureWindowData();
+ windowData->startGeometry = q->geometry();
+ windowData->grabbedSection = q->windowFrameSectionAt(event->pos());
+ ensureWindowData();
+ if (windowData->grabbedSection == Qt::TitleBarArea
+ && windowData->hoveredSubControl == QStyle::SC_TitleBarCloseButton) {
+ windowData->buttonSunken = true;
+ q->update();
+ }
+ event->setAccepted(windowData->grabbedSection != Qt::NoSection);
+}
+
+/*!
+ Used to calculate the
+ Precondition:
+ \a widget should support either hfw or wfh
+
+ If \a heightForWidth is set to false, this function will query the width for height
+ instead. \a width will then be interpreted as height, \a minh and \a maxh will be interpreted
+ as minimum width and maximum width.
+ */
+static qreal minimumHeightForWidth(qreal width, qreal minh, qreal maxh,
+ const QGraphicsWidget *widget,
+ bool heightForWidth = true)
+{
+ qreal minimumHeightForWidth = -1;
+ const bool hasHFW = QGraphicsLayoutItemPrivate::get(widget)->hasHeightForWidth();
+ if (hasHFW == heightForWidth) {
+ minimumHeightForWidth = hasHFW
+ ? widget->effectiveSizeHint(Qt::MinimumSize, QSizeF(width, -1)).height()
+ : widget->effectiveSizeHint(Qt::MinimumSize, QSizeF(-1, width)).width(); //"width" is here height!
+ } else {
+ // widthForHeight
+ const qreal constraint = width;
+ while (maxh - minh > 0.1) {
+ qreal middle = minh + (maxh - minh)/2;
+ // ### really bad, if we are a widget with a layout it will call
+ // layout->effectiveSizeHint(Qt::MiniumumSize), which again will call
+ // sizeHint three times because of how the cache works
+ qreal hfw = hasHFW
+ ? widget->effectiveSizeHint(Qt::MinimumSize, QSizeF(middle, -1)).height()
+ : widget->effectiveSizeHint(Qt::MinimumSize, QSizeF(-1, middle)).width();
+ if (hfw > constraint) {
+ minh = middle;
+ } else if (hfw <= constraint) {
+ maxh = middle;
+ }
+ }
+ minimumHeightForWidth = maxh;
+ }
+ return minimumHeightForWidth;
+}
+
+static qreal minimumWidthForHeight(qreal height, qreal minw, qreal maxw,
+ const QGraphicsWidget *widget)
+{
+ return minimumHeightForWidth(height, minw, maxw, widget, false);
+}
+
+static QSizeF closestAcceptableSize(const QSizeF &proposed,
+ const QGraphicsWidget *widget)
+{
+ const QSizeF current = widget->size();
+
+ qreal minw = proposed.width();
+ qreal maxw = current.width();
+ qreal minh = proposed.height();
+ qreal maxh = current.height();
+
+ qreal middlew = maxw;
+ qreal middleh = maxh;
+ qreal min_hfw;
+ min_hfw = minimumHeightForWidth(maxw, minh, maxh, widget);
+
+ do {
+ if (maxw - minw < 0.1) {
+ // we still havent found anything, cut off binary search
+ minw = maxw;
+ minh = maxh;
+ }
+ middlew = minw + (maxw - minw)/2.0;
+ middleh = minh + (maxh - minh)/2.0;
+
+ min_hfw = minimumHeightForWidth(middlew, minh, maxh, widget);
+
+ if (min_hfw > middleh) {
+ minw = middlew;
+ minh = middleh;
+ } else if (min_hfw <= middleh) {
+ maxw = middlew;
+ maxh = middleh;
+ }
+ } while (maxw != minw);
+
+ min_hfw = minimumHeightForWidth(middlew, minh, maxh, widget);
+
+ QSizeF result;
+ if (min_hfw < maxh) {
+ result = QSizeF(middlew, min_hfw);
+ } else {
+ // Needed because of the cut-off we do above.
+ result = QSizeF(minimumWidthForHeight(maxh, proposed.width(), current.width(), widget), maxh);
+ }
+ return result;
+}
+
+static void _q_boundGeometryToSizeConstraints(const QRectF &startGeometry,
+ QRectF *rect, Qt::WindowFrameSection section,
+ const QSizeF &min, const QSizeF &max,
+ const QGraphicsWidget *widget)
+{
+ const QRectF proposedRect = *rect;
+ qreal width = qBound(min.width(), proposedRect.width(), max.width());
+ qreal height = qBound(min.height(), proposedRect.height(), max.height());
+
+ const bool hasHFW = QGraphicsLayoutItemPrivate::get(widget)->hasHeightForWidth();
+ const bool hasWFH = QGraphicsLayoutItemPrivate::get(widget)->hasWidthForHeight();
+
+ const bool widthChanged = proposedRect.width() != widget->size().width();
+ const bool heightChanged = proposedRect.height() != widget->size().height();
+
+ if (hasHFW || hasWFH) {
+ if (widthChanged || heightChanged) {
+ qreal minExtent;
+ qreal maxExtent;
+ qreal constraint;
+ qreal proposed;
+ if (hasHFW) {
+ minExtent = min.height();
+ maxExtent = max.height();
+ constraint = width;
+ proposed = proposedRect.height();
+ } else {
+ // width for height
+ minExtent = min.width();
+ maxExtent = max.width();
+ constraint = height;
+ proposed = proposedRect.width();
+ }
+ if (minimumHeightForWidth(constraint, minExtent, maxExtent, widget, hasHFW) > proposed) {
+ QSizeF effectiveSize = closestAcceptableSize(QSizeF(width, height), widget);
+ width = effectiveSize.width();
+ height = effectiveSize.height();
+ }
+ }
+ }
+
+ switch (section) {
+ case Qt::LeftSection:
+ rect->setRect(startGeometry.right() - qRound(width), startGeometry.top(),
+ qRound(width), startGeometry.height());
+ break;
+ case Qt::TopLeftSection:
+ rect->setRect(startGeometry.right() - qRound(width), startGeometry.bottom() - qRound(height),
+ qRound(width), qRound(height));
+ break;
+ case Qt::TopSection:
+ rect->setRect(startGeometry.left(), startGeometry.bottom() - qRound(height),
+ startGeometry.width(), qRound(height));
+ break;
+ case Qt::TopRightSection:
+ rect->setTop(rect->bottom() - qRound(height));
+ rect->setWidth(qRound(width));
+ break;
+ case Qt::RightSection:
+ rect->setWidth(qRound(width));
+ break;
+ case Qt::BottomRightSection:
+ rect->setWidth(qRound(width));
+ rect->setHeight(qRound(height));
+ break;
+ case Qt::BottomSection:
+ rect->setHeight(qRound(height));
+ break;
+ case Qt::BottomLeftSection:
+ rect->setRect(startGeometry.right() - qRound(width), startGeometry.top(),
+ qRound(width), qRound(height));
+ break;
+ default:
+ break;
+ }
+}
+
+void QGraphicsWidgetPrivate::windowFrameMouseMoveEvent(QGraphicsSceneMouseEvent *event)
+{
+ Q_Q(QGraphicsWidget);
+ ensureWindowData();
+ if (!(event->buttons() & Qt::LeftButton) || windowData->hoveredSubControl != QStyle::SC_TitleBarLabel)
+ return;
+
+ QLineF delta(q->mapFromScene(event->buttonDownScenePos(Qt::LeftButton)), event->pos());
+ QLineF parentDelta(q->mapToParent(delta.p1()), q->mapToParent(delta.p2()));
+ QLineF parentXDelta(q->mapToParent(QPointF(delta.p1().x(), 0)), q->mapToParent(QPointF(delta.p2().x(), 0)));
+ QLineF parentYDelta(q->mapToParent(QPointF(0, delta.p1().y())), q->mapToParent(QPointF(0, delta.p2().y())));
+
+ QRectF newGeometry;
+ switch (windowData->grabbedSection) {
+ case Qt::LeftSection:
+ newGeometry = QRectF(windowData->startGeometry.topLeft()
+ + QPointF(parentXDelta.dx(), parentXDelta.dy()),
+ windowData->startGeometry.size() - QSizeF(delta.dx(), delta.dy()));
+ break;
+ case Qt::TopLeftSection:
+ newGeometry = QRectF(windowData->startGeometry.topLeft()
+ + QPointF(parentDelta.dx(), parentDelta.dy()),
+ windowData->startGeometry.size() - QSizeF(delta.dx(), delta.dy()));
+ break;
+ case Qt::TopSection:
+ newGeometry = QRectF(windowData->startGeometry.topLeft()
+ + QPointF(parentYDelta.dx(), parentYDelta.dy()),
+ windowData->startGeometry.size() - QSizeF(0, delta.dy()));
+ break;
+ case Qt::TopRightSection:
+ newGeometry = QRectF(windowData->startGeometry.topLeft()
+ + QPointF(parentYDelta.dx(), parentYDelta.dy()),
+ windowData->startGeometry.size() - QSizeF(-delta.dx(), delta.dy()));
+ break;
+ case Qt::RightSection:
+ newGeometry = QRectF(windowData->startGeometry.topLeft(),
+ windowData->startGeometry.size() + QSizeF(delta.dx(), 0));
+ break;
+ case Qt::BottomRightSection:
+ newGeometry = QRectF(windowData->startGeometry.topLeft(),
+ windowData->startGeometry.size() + QSizeF(delta.dx(), delta.dy()));
+ break;
+ case Qt::BottomSection:
+ newGeometry = QRectF(windowData->startGeometry.topLeft(),
+ windowData->startGeometry.size() + QSizeF(0, delta.dy()));
+ break;
+ case Qt::BottomLeftSection:
+ newGeometry = QRectF(windowData->startGeometry.topLeft()
+ + QPointF(parentXDelta.dx(), parentXDelta.dy()),
+ windowData->startGeometry.size() - QSizeF(delta.dx(), -delta.dy()));
+ break;
+ case Qt::TitleBarArea:
+ newGeometry = QRectF(windowData->startGeometry.topLeft()
+ + QPointF(parentDelta.dx(), parentDelta.dy()),
+ windowData->startGeometry.size());
+ break;
+ case Qt::NoSection:
+ break;
+ }
+
+ if (windowData->grabbedSection != Qt::NoSection) {
+ _q_boundGeometryToSizeConstraints(windowData->startGeometry, &newGeometry,
+ windowData->grabbedSection,
+ q->effectiveSizeHint(Qt::MinimumSize),
+ q->effectiveSizeHint(Qt::MaximumSize),
+ q);
+ q->setGeometry(newGeometry);
+ }
+}
+
+void QGraphicsWidgetPrivate::windowFrameHoverMoveEvent(QGraphicsSceneHoverEvent *event)
+{
+ Q_Q(QGraphicsWidget);
+ if (!hasDecoration())
+ return;
+
+ ensureWindowData();
+
+ if (q->rect().contains(event->pos())) {
+ if (windowData->buttonMouseOver || windowData->hoveredSubControl != QStyle::SC_None)
+ windowFrameHoverLeaveEvent(event);
+ return;
+ }
+
+ bool wasMouseOver = windowData->buttonMouseOver;
+ QRect oldButtonRect = windowData->buttonRect;
+ windowData->buttonRect = QRect();
+ windowData->buttonMouseOver = false;
+ QPointF pos = event->pos();
+ QStyleOptionTitleBar bar;
+ // make sure that the coordinates (rect and pos) we send to the style are positive.
+ if (windowFrameMargins) {
+ pos.rx() += windowFrameMargins[Left];
+ pos.ry() += windowFrameMargins[Top];
+ }
+ initStyleOptionTitleBar(&bar);
+ bar.rect = q->windowFrameRect().toRect();
+ bar.rect.moveTo(0,0);
+ bar.rect.setHeight(int(titleBarHeight(bar)));
+
+ Qt::CursorShape cursorShape = Qt::ArrowCursor;
+ bool needsSetCursorCall = true;
+ switch (q->windowFrameSectionAt(event->pos())) {
+ case Qt::TopLeftSection:
+ case Qt::BottomRightSection:
+ cursorShape = Qt::SizeFDiagCursor;
+ break;
+ case Qt::TopRightSection:
+ case Qt::BottomLeftSection:
+ cursorShape = Qt::SizeBDiagCursor;
+ break;
+ case Qt::LeftSection:
+ case Qt::RightSection:
+ cursorShape = Qt::SizeHorCursor;
+ break;
+ case Qt::TopSection:
+ case Qt::BottomSection:
+ cursorShape = Qt::SizeVerCursor;
+ break;
+ case Qt::TitleBarArea:
+ windowData->buttonRect = q->style()->subControlRect(
+ QStyle::CC_TitleBar, &bar, QStyle::SC_TitleBarCloseButton, 0);
+#ifdef Q_WS_MAC
+ // On mac we should hover if we are in the 'area' of the buttons
+ windowData->buttonRect |= q->style()->subControlRect(
+ QStyle::CC_TitleBar, &bar, QStyle::SC_TitleBarMinButton, 0);
+ windowData->buttonRect |= q->style()->subControlRect(
+ QStyle::CC_TitleBar, &bar, QStyle::SC_TitleBarMaxButton, 0);
+#endif
+ if (windowData->buttonRect.contains(pos.toPoint()))
+ windowData->buttonMouseOver = true;
+ event->ignore();
+ break;
+ default:
+ needsSetCursorCall = false;
+ event->ignore();
+ }
+#ifndef QT_NO_CURSOR
+ if (needsSetCursorCall)
+ q->setCursor(cursorShape);
+#endif
+ // update buttons if we hover over them
+ windowData->hoveredSubControl = q->style()->hitTestComplexControl(QStyle::CC_TitleBar, &bar, pos.toPoint(), 0);
+ if (windowData->hoveredSubControl != QStyle::SC_TitleBarCloseButton)
+ windowData->hoveredSubControl = QStyle::SC_TitleBarLabel;
+
+ if (windowData->buttonMouseOver != wasMouseOver) {
+ if (!oldButtonRect.isNull())
+ q->update(QRectF(oldButtonRect).translated(q->windowFrameRect().topLeft()));
+ if (!windowData->buttonRect.isNull())
+ q->update(QRectF(windowData->buttonRect).translated(q->windowFrameRect().topLeft()));
+ }
+}
+
+void QGraphicsWidgetPrivate::windowFrameHoverLeaveEvent(QGraphicsSceneHoverEvent *event)
+{
+ Q_UNUSED(event);
+ Q_Q(QGraphicsWidget);
+ if (hasDecoration()) {
+ // ### restore the cursor, don't override it
+#ifndef QT_NO_CURSOR
+ q->unsetCursor();
+#endif
+
+ ensureWindowData();
+
+ bool needsUpdate = false;
+ if (windowData->hoveredSubControl == QStyle::SC_TitleBarCloseButton
+ || windowData->buttonMouseOver)
+ needsUpdate = true;
+
+ // update the hover state (of buttons etc...)
+ windowData->hoveredSubControl = QStyle::SC_None;
+ windowData->buttonMouseOver = false;
+ windowData->buttonRect = QRect();
+ if (needsUpdate)
+ q->update(windowData->buttonRect);
+ }
+}
+
+bool QGraphicsWidgetPrivate::hasDecoration() const
+{
+ return (windowFlags & Qt::Window) && (windowFlags & Qt::WindowTitleHint);
+}
+
+/**
+ * is called after a reparent has taken place to fix up the focus chain(s)
+ */
+void QGraphicsWidgetPrivate::fixFocusChainBeforeReparenting(QGraphicsWidget *newParent, QGraphicsScene *oldScene, QGraphicsScene *newScene)
+{
+ Q_Q(QGraphicsWidget);
+
+ Q_ASSERT(focusNext && focusPrev);
+
+ QGraphicsWidget *n = q; //last one in 'new' list
+ QGraphicsWidget *o = 0; //last one in 'old' list
+
+ QGraphicsWidget *w = focusNext;
+
+ QGraphicsWidget *firstOld = 0;
+ bool wasPreviousNew = true;
+
+ while (w != q) {
+ bool isCurrentNew = q->isAncestorOf(w);
+ if (isCurrentNew) {
+ if (!wasPreviousNew) {
+ n->d_func()->focusNext = w;
+ w->d_func()->focusPrev = n;
+ }
+ n = w;
+ } else /*if (!isCurrentNew)*/ {
+ if (wasPreviousNew) {
+ if (o) {
+ o->d_func()->focusNext = w;
+ w->d_func()->focusPrev = o;
+ } else {
+ firstOld = w;
+ }
+ }
+ o = w;
+ }
+ w = w->d_func()->focusNext;
+ wasPreviousNew = isCurrentNew;
+ }
+
+ // repair the 'old' chain
+ if (firstOld) {
+ o->d_func()->focusNext = firstOld;
+ firstOld->d_func()->focusPrev = o;
+ }
+
+ // update tabFocusFirst for oldScene if the item is going to be removed from oldScene
+ if (newParent)
+ newScene = newParent->scene();
+
+ if (oldScene && newScene != oldScene)
+ oldScene->d_func()->tabFocusFirst = (firstOld && firstOld->scene() == oldScene) ? firstOld : 0;
+
+ QGraphicsItem *topLevelItem = newParent ? newParent->topLevelItem() : 0;
+ QGraphicsWidget *topLevel = 0;
+ if (topLevelItem && topLevelItem->isWidget())
+ topLevel = static_cast<QGraphicsWidget *>(topLevelItem);
+
+ if (topLevel && newParent) {
+ QGraphicsWidget *last = topLevel->d_func()->focusPrev;
+ // link last with new chain
+ last->d_func()->focusNext = q;
+ focusPrev = last;
+
+ // link last in chain with
+ topLevel->d_func()->focusPrev = n;
+ n->d_func()->focusNext = topLevel;
+ } else {
+ // q is the start of the focus chain
+ n->d_func()->focusNext = q;
+ focusPrev = n;
+ }
+
+}
+
+void QGraphicsWidgetPrivate::setLayout_helper(QGraphicsLayout *l)
+{
+ delete (this->layout);
+ layout = l;
+ if (!l) {
+ Q_Q(QGraphicsWidget);
+ q->updateGeometry();
+ }
+}
+
+qreal QGraphicsWidgetPrivate::width() const
+{
+ Q_Q(const QGraphicsWidget);
+ return q->geometry().width();
+}
+
+void QGraphicsWidgetPrivate::setWidth(qreal w)
+{
+ if (qIsNaN(w))
+ return;
+ Q_Q(QGraphicsWidget);
+ if (q->geometry().width() == w)
+ return;
+
+ q->setGeometry(QRectF(q->x(), q->y(), w, height()));
+}
+
+void QGraphicsWidgetPrivate::resetWidth()
+{
+ Q_Q(QGraphicsWidget);
+ q->setGeometry(QRectF(q->x(), q->y(), 0, height()));
+}
+
+qreal QGraphicsWidgetPrivate::height() const
+{
+ Q_Q(const QGraphicsWidget);
+ return q->geometry().height();
+}
+
+void QGraphicsWidgetPrivate::setHeight(qreal h)
+{
+ if (qIsNaN(h))
+ return;
+ Q_Q(QGraphicsWidget);
+ if (q->geometry().height() == h)
+ return;
+
+ q->setGeometry(QRectF(q->x(), q->y(), width(), h));
+}
+
+void QGraphicsWidgetPrivate::resetHeight()
+{
+ Q_Q(QGraphicsWidget);
+ q->setGeometry(QRectF(q->x(), q->y(), width(), 0));
+}
+
+void QGraphicsWidgetPrivate::setGeometryFromSetPos()
+{
+ if (inSetGeometry)
+ return;
+ Q_Q(QGraphicsWidget);
+ inSetPos = 1;
+ // Ensure setGeometry is called (avoid recursion when setPos is
+ // called from within setGeometry).
+ q->setGeometry(QRectF(pos, q->size()));
+ inSetPos = 0 ;
+}
+
+QT_END_NAMESPACE
+
+#endif //QT_NO_GRAPHICSVIEW
diff --git a/src/widgets/graphicsview/qgraphicswidget_p.h b/src/widgets/graphicsview/qgraphicswidget_p.h
new file mode 100644
index 0000000000..16c5303235
--- /dev/null
+++ b/src/widgets/graphicsview/qgraphicswidget_p.h
@@ -0,0 +1,226 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGRAPHICSWIDGET_P_H
+#define QGRAPHICSWIDGET_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <private/qobject_p.h>
+#include "qgraphicsitem_p.h"
+#include "qgraphicswidget.h"
+#include <QtGui/qfont.h>
+#include <QtGui/qpalette.h>
+#include <QtWidgets/qsizepolicy.h>
+#include <QtWidgets/qstyle.h>
+
+QT_BEGIN_NAMESPACE
+
+class QGraphicsLayout;
+class QStyleOptionTitleBar;
+
+#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW
+
+class QGraphicsWidgetPrivate : public QGraphicsItemPrivate
+{
+ Q_DECLARE_PUBLIC(QGraphicsWidget)
+public:
+ QGraphicsWidgetPrivate()
+ : margins(0),
+ layout(0),
+ inheritedPaletteResolveMask(0),
+ inheritedFontResolveMask(0),
+ inSetGeometry(0),
+ polished(0),
+ inSetPos(0),
+ autoFillBackground(0),
+ focusPolicy(Qt::NoFocus),
+ focusNext(0),
+ focusPrev(0),
+ windowFlags(0),
+ windowData(0),
+ setWindowFrameMargins(false),
+ windowFrameMargins(0)
+ { }
+ virtual ~QGraphicsWidgetPrivate();
+
+ void init(QGraphicsItem *parentItem, Qt::WindowFlags wFlags);
+ qreal titleBarHeight(const QStyleOptionTitleBar &options) const;
+
+ // Margins
+ enum {Left, Top, Right, Bottom};
+ mutable qreal *margins;
+ void ensureMargins() const;
+
+ void fixFocusChainBeforeReparenting(QGraphicsWidget *newParent, QGraphicsScene *oldScene, QGraphicsScene *newScene = 0);
+ void setLayout_helper(QGraphicsLayout *l);
+
+ // Layouts
+ QGraphicsLayout *layout;
+ void setLayoutDirection_helper(Qt::LayoutDirection direction);
+ void resolveLayoutDirection();
+
+ // Style
+ QPalette palette;
+ uint inheritedPaletteResolveMask;
+ void setPalette_helper(const QPalette &palette);
+ void resolvePalette(uint inheritedMask);
+ void updatePalette(const QPalette &palette);
+ QPalette naturalWidgetPalette() const;
+ QFont font;
+ uint inheritedFontResolveMask;
+ void setFont_helper(const QFont &font);
+ void resolveFont(uint inheritedMask);
+ void updateFont(const QFont &font);
+ QFont naturalWidgetFont() const;
+
+ // Window specific
+ void initStyleOptionTitleBar(QStyleOptionTitleBar *option);
+ void adjustWindowFlags(Qt::WindowFlags *wFlags);
+ void windowFrameMouseReleaseEvent(QGraphicsSceneMouseEvent *event);
+ void windowFrameMousePressEvent(QGraphicsSceneMouseEvent *event);
+ void windowFrameMouseMoveEvent(QGraphicsSceneMouseEvent *event);
+ void windowFrameHoverMoveEvent(QGraphicsSceneHoverEvent *event);
+ void windowFrameHoverLeaveEvent(QGraphicsSceneHoverEvent *event);
+ bool hasDecoration() const;
+
+ // Private Properties
+ qreal width() const;
+ void setWidth(qreal);
+ void resetWidth();
+
+ qreal height() const;
+ void setHeight(qreal);
+ void resetHeight();
+ void setGeometryFromSetPos();
+
+ // State
+ inline int attributeToBitIndex(Qt::WidgetAttribute att) const
+ {
+ int bit = -1;
+ switch (att) {
+ case Qt::WA_SetLayoutDirection: bit = 0; break;
+ case Qt::WA_RightToLeft: bit = 1; break;
+ case Qt::WA_SetStyle: bit = 2; break;
+ case Qt::WA_Resized: bit = 3; break;
+ case Qt::WA_DeleteOnClose: bit = 4; break;
+ case Qt::WA_NoSystemBackground: bit = 5; break;
+ case Qt::WA_OpaquePaintEvent: bit = 6; break;
+ case Qt::WA_SetPalette: bit = 7; break;
+ case Qt::WA_SetFont: bit = 8; break;
+ case Qt::WA_WindowPropagation: bit = 9; break;
+ default: break;
+ }
+ return bit;
+ }
+ inline void setAttribute(Qt::WidgetAttribute att, bool value)
+ {
+ int bit = attributeToBitIndex(att);
+ if (bit == -1) {
+ qWarning("QGraphicsWidget::setAttribute: unsupported attribute %d", int(att));
+ return;
+ }
+ if (value)
+ attributes |= (1 << bit);
+ else
+ attributes &= ~(1 << bit);
+ }
+ inline bool testAttribute(Qt::WidgetAttribute att) const
+ {
+ int bit = attributeToBitIndex(att);
+ if (bit == -1)
+ return false;
+ return (attributes & (1 << bit)) != 0;
+ }
+ quint32 attributes : 10;
+ quint32 inSetGeometry : 1;
+ quint32 polished: 1;
+ quint32 inSetPos : 1;
+ quint32 autoFillBackground : 1;
+
+ // Focus
+ Qt::FocusPolicy focusPolicy;
+ QGraphicsWidget *focusNext;
+ QGraphicsWidget *focusPrev;
+
+ // Windows
+ Qt::WindowFlags windowFlags;
+ struct WindowData {
+ QString windowTitle;
+ QStyle::SubControl hoveredSubControl;
+ Qt::WindowFrameSection grabbedSection;
+ uint buttonMouseOver : 1;
+ uint buttonSunken : 1;
+ QRectF startGeometry;
+ QRect buttonRect;
+ WindowData()
+ : hoveredSubControl(QStyle::SC_None)
+ , grabbedSection(Qt::NoSection)
+ , buttonMouseOver(false)
+ , buttonSunken(false)
+ {}
+ } *windowData;
+ void ensureWindowData();
+
+ bool setWindowFrameMargins;
+ mutable qreal *windowFrameMargins;
+ void ensureWindowFrameMargins() const;
+
+#ifndef QT_NO_ACTION
+ QList<QAction *> actions;
+#endif
+};
+
+#endif //!defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW
+
+QT_END_NAMESPACE
+
+#endif //QGRAPHICSWIDGET_P_H
+
diff --git a/src/gui/graphicsview/qgridlayoutengine.cpp b/src/widgets/graphicsview/qgridlayoutengine.cpp
index 66b4a5b6b4..66b4a5b6b4 100644
--- a/src/gui/graphicsview/qgridlayoutengine.cpp
+++ b/src/widgets/graphicsview/qgridlayoutengine.cpp
diff --git a/src/gui/graphicsview/qgridlayoutengine_p.h b/src/widgets/graphicsview/qgridlayoutengine_p.h
index f947d67d5a..f947d67d5a 100644
--- a/src/gui/graphicsview/qgridlayoutengine_p.h
+++ b/src/widgets/graphicsview/qgridlayoutengine_p.h
diff --git a/src/gui/graphicsview/qsimplex_p.cpp b/src/widgets/graphicsview/qsimplex_p.cpp
index eb8bcb8c1f..eb8bcb8c1f 100644
--- a/src/gui/graphicsview/qsimplex_p.cpp
+++ b/src/widgets/graphicsview/qsimplex_p.cpp
diff --git a/src/gui/graphicsview/qsimplex_p.h b/src/widgets/graphicsview/qsimplex_p.h
index 3df82c6ccf..3df82c6ccf 100644
--- a/src/gui/graphicsview/qsimplex_p.h
+++ b/src/widgets/graphicsview/qsimplex_p.h
diff --git a/src/widgets/itemviews/itemviews.pri b/src/widgets/itemviews/itemviews.pri
new file mode 100644
index 0000000000..7ef704546e
--- /dev/null
+++ b/src/widgets/itemviews/itemviews.pri
@@ -0,0 +1,72 @@
+# Qt gui library, itemviews
+
+HEADERS += \
+ itemviews/qabstractitemview.h \
+ itemviews/qabstractitemview_p.h \
+ itemviews/qheaderview.h \
+ itemviews/qidentityproxymodel.h \
+ itemviews/qlistview.h \
+ itemviews/qlistview_p.h \
+ itemviews/qbsptree_p.h \
+ itemviews/qtableview.h \
+ itemviews/qtableview_p.h \
+ itemviews/qtreeview.h \
+ itemviews/qtreeview_p.h \
+ itemviews/qabstractitemdelegate.h \
+ itemviews/qitemdelegate.h \
+ itemviews/qitemselectionmodel.h \
+ itemviews/qitemselectionmodel_p.h \
+ itemviews/qdirmodel.h \
+ itemviews/qlistwidget.h \
+ itemviews/qlistwidget_p.h \
+ itemviews/qtablewidget.h \
+ itemviews/qtablewidget_p.h \
+ itemviews/qtreewidget.h \
+ itemviews/qtreewidget_p.h \
+ itemviews/qwidgetitemdata_p.h \
+ itemviews/qproxymodel.h \
+ itemviews/qproxymodel_p.h \
+ itemviews/qabstractproxymodel.h \
+ itemviews/qabstractproxymodel_p.h \
+ itemviews/qsortfilterproxymodel.h \
+ itemviews/qitemeditorfactory.h \
+ itemviews/qitemeditorfactory_p.h \
+ itemviews/qstandarditemmodel.h \
+ itemviews/qstandarditemmodel_p.h \
+ itemviews/qstringlistmodel.h \
+ itemviews/qtreewidgetitemiterator.h \
+ itemviews/qdatawidgetmapper.h \
+ itemviews/qfileiconprovider.h \
+ itemviews/qcolumnviewgrip_p.h \
+ itemviews/qcolumnview.h \
+ itemviews/qcolumnview_p.h \
+ itemviews/qstyleditemdelegate.h
+
+SOURCES += \
+ itemviews/qabstractitemview.cpp \
+ itemviews/qheaderview.cpp \
+ itemviews/qidentityproxymodel.cpp \
+ itemviews/qlistview.cpp \
+ itemviews/qbsptree.cpp \
+ itemviews/qtableview.cpp \
+ itemviews/qtreeview.cpp \
+ itemviews/qabstractitemdelegate.cpp \
+ itemviews/qitemdelegate.cpp \
+ itemviews/qitemselectionmodel.cpp \
+ itemviews/qdirmodel.cpp \
+ itemviews/qlistwidget.cpp \
+ itemviews/qtablewidget.cpp \
+ itemviews/qtreewidget.cpp \
+ itemviews/qproxymodel.cpp \
+ itemviews/qabstractproxymodel.cpp \
+ itemviews/qsortfilterproxymodel.cpp \
+ itemviews/qitemeditorfactory.cpp \
+ itemviews/qstandarditemmodel.cpp \
+ itemviews/qstringlistmodel.cpp \
+ itemviews/qtreewidgetitemiterator.cpp \
+ itemviews/qdatawidgetmapper.cpp \
+ itemviews/qfileiconprovider.cpp \
+ itemviews/qcolumnview.cpp \
+ itemviews/qcolumnviewgrip.cpp \
+ itemviews/qstyleditemdelegate.cpp
+
diff --git a/src/gui/itemviews/qabstractitemdelegate.cpp b/src/widgets/itemviews/qabstractitemdelegate.cpp
index 34d3a25623..34d3a25623 100644
--- a/src/gui/itemviews/qabstractitemdelegate.cpp
+++ b/src/widgets/itemviews/qabstractitemdelegate.cpp
diff --git a/src/widgets/itemviews/qabstractitemdelegate.h b/src/widgets/itemviews/qabstractitemdelegate.h
new file mode 100644
index 0000000000..f494f0b8c8
--- /dev/null
+++ b/src/widgets/itemviews/qabstractitemdelegate.h
@@ -0,0 +1,134 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QABSTRACTITEMDELEGATE_H
+#define QABSTRACTITEMDELEGATE_H
+
+#include <QtCore/qobject.h>
+#include <QtWidgets/qstyleoption.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_ITEMVIEWS
+
+class QPainter;
+class QModelIndex;
+class QAbstractItemModel;
+class QAbstractItemView;
+class QHelpEvent;
+
+class Q_WIDGETS_EXPORT QAbstractItemDelegate : public QObject
+{
+ Q_OBJECT
+
+public:
+
+ enum EndEditHint {
+ NoHint,
+ EditNextItem,
+ EditPreviousItem,
+ SubmitModelCache,
+ RevertModelCache
+ };
+
+ explicit QAbstractItemDelegate(QObject *parent = 0);
+ virtual ~QAbstractItemDelegate();
+
+ // painting
+ virtual void paint(QPainter *painter,
+ const QStyleOptionViewItem &option,
+ const QModelIndex &index) const = 0;
+
+ virtual QSize sizeHint(const QStyleOptionViewItem &option,
+ const QModelIndex &index) const = 0;
+
+ // editing
+ virtual QWidget *createEditor(QWidget *parent,
+ const QStyleOptionViewItem &option,
+ const QModelIndex &index) const;
+
+ virtual void setEditorData(QWidget *editor, const QModelIndex &index) const;
+
+ virtual void setModelData(QWidget *editor,
+ QAbstractItemModel *model,
+ const QModelIndex &index) const;
+
+ virtual void updateEditorGeometry(QWidget *editor,
+ const QStyleOptionViewItem &option,
+ const QModelIndex &index) const;
+
+ // for non-widget editors
+ virtual bool editorEvent(QEvent *event,
+ QAbstractItemModel *model,
+ const QStyleOptionViewItem &option,
+ const QModelIndex &index);
+
+ static QString elidedText(const QFontMetrics &fontMetrics, int width,
+ Qt::TextElideMode mode, const QString &text);
+
+public Q_SLOTS:
+ bool helpEvent(QHelpEvent *event,
+ QAbstractItemView *view,
+ const QStyleOptionViewItem &option,
+ const QModelIndex &index);
+
+Q_SIGNALS:
+ void commitData(QWidget *editor);
+ void closeEditor(QWidget *editor, QAbstractItemDelegate::EndEditHint hint = NoHint);
+ void sizeHintChanged(const QModelIndex &);
+
+protected:
+ QAbstractItemDelegate(QObjectPrivate &, QObject *parent = 0);
+private:
+ Q_DISABLE_COPY(QAbstractItemDelegate)
+};
+
+#endif // QT_NO_ITEMVIEWS
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QABSTRACTITEMDELEGATE_H
diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp
new file mode 100644
index 0000000000..d6fbb7c953
--- /dev/null
+++ b/src/widgets/itemviews/qabstractitemview.cpp
@@ -0,0 +1,4320 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qabstractitemview.h"
+
+#ifndef QT_NO_ITEMVIEWS
+#include <qpointer.h>
+#include <qapplication.h>
+#include <qclipboard.h>
+#include <qpainter.h>
+#include <qstyle.h>
+#include <qdrag.h>
+#include <qevent.h>
+#include <qscrollbar.h>
+#include <qwhatsthis.h>
+#include <qtooltip.h>
+#include <qdatetime.h>
+#include <qlineedit.h>
+#include <qspinbox.h>
+#include <qstyleditemdelegate.h>
+#include <private/qabstractitemview_p.h>
+#include <private/qabstractitemmodel_p.h>
+#ifndef QT_NO_ACCESSIBILITY
+#include <qaccessible.h>
+#include <qaccessible2.h>
+#endif
+#include <private/qsoftkeymanager_p.h>
+#ifndef QT_NO_GESTURE
+# include <qscroller.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+QAbstractItemViewPrivate::QAbstractItemViewPrivate()
+ : model(QAbstractItemModelPrivate::staticEmptyModel()),
+ itemDelegate(0),
+ selectionModel(0),
+ ctrlDragSelectionFlag(QItemSelectionModel::NoUpdate),
+ noSelectionOnMousePress(false),
+ selectionMode(QAbstractItemView::ExtendedSelection),
+ selectionBehavior(QAbstractItemView::SelectItems),
+ currentlyCommittingEditor(0),
+ pressedModifiers(Qt::NoModifier),
+ pressedPosition(QPoint(-1, -1)),
+ pressedAlreadySelected(false),
+ viewportEnteredNeeded(false),
+ state(QAbstractItemView::NoState),
+ stateBeforeAnimation(QAbstractItemView::NoState),
+ editTriggers(QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed),
+ lastTrigger(QAbstractItemView::NoEditTriggers),
+ tabKeyNavigation(false),
+#ifndef QT_NO_DRAGANDDROP
+ showDropIndicator(true),
+ dragEnabled(false),
+ dragDropMode(QAbstractItemView::NoDragDrop),
+ overwrite(false),
+ dropIndicatorPosition(QAbstractItemView::OnItem),
+ defaultDropAction(Qt::IgnoreAction),
+#endif
+#ifdef QT_SOFTKEYS_ENABLED
+ doneSoftKey(0),
+#endif
+ autoScroll(true),
+ autoScrollMargin(16),
+ autoScrollCount(0),
+ shouldScrollToCurrentOnShow(false),
+ shouldClearStatusTip(false),
+ alternatingColors(false),
+ textElideMode(Qt::ElideRight),
+ verticalScrollMode(QAbstractItemView::ScrollPerItem),
+ horizontalScrollMode(QAbstractItemView::ScrollPerItem),
+ currentIndexSet(false),
+ wrapItemText(false),
+ delayedPendingLayout(true),
+ moveCursorUpdatedView(false)
+{
+ keyboardInputTime.invalidate();
+}
+
+QAbstractItemViewPrivate::~QAbstractItemViewPrivate()
+{
+}
+
+void QAbstractItemViewPrivate::init()
+{
+ Q_Q(QAbstractItemView);
+ q->setItemDelegate(new QStyledItemDelegate(q));
+
+ vbar->setRange(0, 0);
+ hbar->setRange(0, 0);
+
+ QObject::connect(vbar, SIGNAL(actionTriggered(int)),
+ q, SLOT(verticalScrollbarAction(int)));
+ QObject::connect(hbar, SIGNAL(actionTriggered(int)),
+ q, SLOT(horizontalScrollbarAction(int)));
+ QObject::connect(vbar, SIGNAL(valueChanged(int)),
+ q, SLOT(verticalScrollbarValueChanged(int)));
+ QObject::connect(hbar, SIGNAL(valueChanged(int)),
+ q, SLOT(horizontalScrollbarValueChanged(int)));
+
+ viewport->setBackgroundRole(QPalette::Base);
+
+ q->setAttribute(Qt::WA_InputMethodEnabled);
+
+#ifdef QT_SOFTKEYS_ENABLED
+ doneSoftKey = QSoftKeyManager::createKeyedAction(QSoftKeyManager::DoneSoftKey, Qt::Key_Back, q);
+#endif
+}
+
+void QAbstractItemViewPrivate::setHoverIndex(const QPersistentModelIndex &index)
+{
+ Q_Q(QAbstractItemView);
+ if (hover == index)
+ return;
+
+ if (selectionBehavior != QAbstractItemView::SelectRows) {
+ q->update(hover); //update the old one
+ q->update(index); //update the new one
+ } else {
+ QRect oldHoverRect = q->visualRect(hover);
+ QRect newHoverRect = q->visualRect(index);
+ viewport->update(QRect(0, newHoverRect.y(), viewport->width(), newHoverRect.height()));
+ viewport->update(QRect(0, oldHoverRect.y(), viewport->width(), oldHoverRect.height()));
+ }
+ hover = index;
+}
+
+void QAbstractItemViewPrivate::checkMouseMove(const QPersistentModelIndex &index)
+{
+ //we take a persistent model index because the model might change by emitting signals
+ Q_Q(QAbstractItemView);
+ setHoverIndex(index);
+ if (viewportEnteredNeeded || enteredIndex != index) {
+ viewportEnteredNeeded = false;
+
+ if (index.isValid()) {
+ emit q->entered(index);
+#ifndef QT_NO_STATUSTIP
+ QString statustip = model->data(index, Qt::StatusTipRole).toString();
+ if (parent && (shouldClearStatusTip || !statustip.isEmpty())) {
+ QStatusTipEvent tip(statustip);
+ QApplication::sendEvent(parent, &tip);
+ shouldClearStatusTip = !statustip.isEmpty();
+ }
+#endif
+ } else {
+#ifndef QT_NO_STATUSTIP
+ if (parent && shouldClearStatusTip) {
+ QString emptyString;
+ QStatusTipEvent tip( emptyString );
+ QApplication::sendEvent(parent, &tip);
+ }
+#endif
+ emit q->viewportEntered();
+ }
+ enteredIndex = index;
+ }
+}
+
+#ifndef QT_NO_GESTURES
+
+// stores and restores the selection and current item when flicking
+void QAbstractItemViewPrivate::_q_scrollerStateChanged()
+{
+ Q_Q(QAbstractItemView);
+
+ if (QScroller *scroller = QScroller::scroller(viewport)) {
+ switch (scroller->state()) {
+ case QScroller::Pressed:
+ // store the current selection in case we start scrolling
+ if (q->selectionModel()) {
+ oldSelection = q->selectionModel()->selection();
+ oldCurrent = q->selectionModel()->currentIndex();
+ }
+ break;
+
+ case QScroller::Dragging:
+ // restore the old selection if we really start scrolling
+ if (q->selectionModel()) {
+ q->selectionModel()->select(oldSelection, QItemSelectionModel::ClearAndSelect);
+ q->selectionModel()->setCurrentIndex(oldCurrent, QItemSelectionModel::NoUpdate);
+ }
+ // fall through
+
+ default:
+ oldSelection = QItemSelection();
+ oldCurrent = QModelIndex();
+ break;
+ }
+ }
+}
+
+#endif // QT_NO_GESTURES
+
+/*!
+ \class QAbstractItemView
+
+ \brief The QAbstractItemView class provides the basic functionality for
+ item view classes.
+
+ \ingroup model-view
+
+
+ QAbstractItemView class is the base class for every standard view
+ that uses a QAbstractItemModel. QAbstractItemView is an abstract
+ class and cannot itself be instantiated. It provides a standard
+ interface for interoperating with models through the signals and
+ slots mechanism, enabling subclasses to be kept up-to-date with
+ changes to their models. This class provides standard support for
+ keyboard and mouse navigation, viewport scrolling, item editing,
+ and selections. The keyboard navigation implements this
+ functionality:
+
+ \table
+ \header
+ \o Keys
+ \o Functionality
+ \row
+ \o Arrow keys
+ \o Changes the current item and selects it.
+ \row
+ \o Ctrl+Arrow keys
+ \o Changes the current item but does not select it.
+ \row
+ \o Shift+Arrow keys
+ \o Changes the current item and selects it. The previously
+ selected item(s) is not deselected.
+ \row
+ \o Ctr+Space
+ \o Toggles selection of the current item.
+ \row
+ \o Tab/Backtab
+ \o Changes the current item to the next/previous item.
+ \row
+ \o Home/End
+ \o Selects the first/last item in the model.
+ \row
+ \o Page up/Page down
+ \o Scrolls the rows shown up/down by the number of
+ visible rows in the view.
+ \row
+ \o Ctrl+A
+ \o Selects all items in the model.
+ \endtable
+
+ Note that the above table assumes that the
+ \l{selectionMode}{selection mode} allows the operations. For
+ instance, you cannot select items if the selection mode is
+ QAbstractItemView::NoSelection.
+
+ The QAbstractItemView class is one of the \l{Model/View Classes}
+ and is part of Qt's \l{Model/View Programming}{model/view framework}.
+
+ The view classes that inherit QAbstractItemView only need
+ to implement their own view-specific functionality, such as
+ drawing items, returning the geometry of items, finding items,
+ etc.
+
+ QAbstractItemView provides common slots such as edit() and
+ setCurrentIndex(). Many protected slots are also provided, including
+ dataChanged(), rowsInserted(), rowsAboutToBeRemoved(), selectionChanged(),
+ and currentChanged().
+
+ The root item is returned by rootIndex(), and the current item by
+ currentIndex(). To make sure that an item is visible use
+ scrollTo().
+
+ Some of QAbstractItemView's functions are concerned with
+ scrolling, for example setHorizontalScrollMode() and
+ setVerticalScrollMode(). To set the range of the scroll bars, you
+ can, for example, reimplement the view's resizeEvent() function:
+
+ \snippet doc/src/snippets/code/src_gui_itemviews_qabstractitemview.cpp 0
+
+ Note that the range is not updated until the widget is shown.
+
+ Several other functions are concerned with selection control; for
+ example setSelectionMode(), and setSelectionBehavior(). This class
+ provides a default selection model to work with
+ (selectionModel()), but this can be replaced by using
+ setSelectionModel() with an instance of QItemSelectionModel.
+
+ For complete control over the display and editing of items you can
+ specify a delegate with setItemDelegate().
+
+ QAbstractItemView provides a lot of protected functions. Some are
+ concerned with editing, for example, edit(), and commitData(),
+ whilst others are keyboard and mouse event handlers.
+
+ \note If you inherit QAbstractItemView and intend to update the contents
+ of the viewport, you should use viewport->update() instead of
+ \l{QWidget::update()}{update()} as all painting operations take place on the
+ viewport.
+
+ \sa {View Classes}, {Model/View Programming}, QAbstractItemModel, {Chart Example}
+*/
+
+/*!
+ \enum QAbstractItemView::SelectionMode
+
+ This enum indicates how the view responds to user selections:
+
+ \value SingleSelection When the user selects an item, any already-selected
+ item becomes unselected, and the user cannot unselect the selected item by
+ clicking on it.
+
+ \value ContiguousSelection When the user selects an item in the usual way,
+ the selection is cleared and the new item selected. However, if the user
+ presses the Shift key while clicking on an item, all items between the
+ current item and the clicked item are selected or unselected, depending on
+ the state of the clicked item.
+
+ \value ExtendedSelection When the user selects an item in the usual way,
+ the selection is cleared and the new item selected. However, if the user
+ presses the Ctrl key when clicking on an item, the clicked item gets
+ toggled and all other items are left untouched. If the user presses the
+ Shift key while clicking on an item, all items between the current item
+ and the clicked item are selected or unselected, depending on the state of
+ the clicked item. Multiple items can be selected by dragging the mouse over
+ them.
+
+ \value MultiSelection When the user selects an item in the usual way, the
+ selection status of that item is toggled and the other items are left
+ alone. Multiple items can be toggled by dragging the mouse over them.
+
+ \value NoSelection Items cannot be selected.
+
+ The most commonly used modes are SingleSelection and ExtendedSelection.
+*/
+
+/*!
+ \enum QAbstractItemView::SelectionBehavior
+
+ \value SelectItems Selecting single items.
+ \value SelectRows Selecting only rows.
+ \value SelectColumns Selecting only columns.
+*/
+
+/*!
+ \enum QAbstractItemView::ScrollHint
+
+ \value EnsureVisible Scroll to ensure that the item is visible.
+ \value PositionAtTop Scroll to position the item at the top of the
+ viewport.
+ \value PositionAtBottom Scroll to position the item at the bottom of the
+ viewport.
+ \value PositionAtCenter Scroll to position the item at the center of the
+ viewport.
+*/
+
+
+/*!
+ \enum QAbstractItemView::EditTrigger
+
+ This enum describes actions which will initiate item editing.
+
+ \value NoEditTriggers No editing possible.
+ \value CurrentChanged Editing start whenever current item changes.
+ \value DoubleClicked Editing starts when an item is double clicked.
+ \value SelectedClicked Editing starts when clicking on an already selected
+ item.
+ \value EditKeyPressed Editing starts when the platform edit key has been
+ pressed over an item.
+ \value AnyKeyPressed Editing starts when any key is pressed over an item.
+ \value AllEditTriggers Editing starts for all above actions.
+*/
+
+/*!
+ \enum QAbstractItemView::CursorAction
+
+ This enum describes the different ways to navigate between items,
+ \sa moveCursor()
+
+ \value MoveUp Move to the item above the current item.
+ \value MoveDown Move to the item below the current item.
+ \value MoveLeft Move to the item left of the current item.
+ \value MoveRight Move to the item right of the current item.
+ \value MoveHome Move to the top-left corner item.
+ \value MoveEnd Move to the bottom-right corner item.
+ \value MovePageUp Move one page up above the current item.
+ \value MovePageDown Move one page down below the current item.
+ \value MoveNext Move to the item after the current item.
+ \value MovePrevious Move to the item before the current item.
+*/
+
+/*!
+ \enum QAbstractItemView::State
+
+ Describes the different states the view can be in. This is usually
+ only interesting when reimplementing your own view.
+
+ \value NoState The is the default state.
+ \value DraggingState The user is dragging items.
+ \value DragSelectingState The user is selecting items.
+ \value EditingState The user is editing an item in a widget editor.
+ \value ExpandingState The user is opening a branch of items.
+ \value CollapsingState The user is closing a branch of items.
+ \value AnimatingState The item view is performing an animation.
+*/
+
+/*!
+ \since 4.2
+ \enum QAbstractItemView::ScrollMode
+
+ \value ScrollPerItem The view will scroll the contents one item at a time.
+ \value ScrollPerPixel The view will scroll the contents one pixel at a time.
+*/
+
+/*!
+ \fn QRect QAbstractItemView::visualRect(const QModelIndex &index) const = 0
+ Returns the rectangle on the viewport occupied by the item at \a index.
+
+ If your item is displayed in several areas then visualRect should return
+ the primary area that contains index and not the complete area that index
+ might encompasses, touch or cause drawing.
+
+ In the base class this is a pure virtual function.
+
+ \sa indexAt(), visualRegionForSelection()
+*/
+
+/*!
+ \fn void QAbstractItemView::scrollTo(const QModelIndex &index, ScrollHint hint) = 0
+
+ Scrolls the view if necessary to ensure that the item at \a index
+ is visible. The view will try to position the item according to the given \a hint.
+
+ In the base class this is a pure virtual function.
+*/
+
+/*!
+ \fn QModelIndex QAbstractItemView::indexAt(const QPoint &point) const = 0
+
+ Returns the model index of the item at the viewport coordinates \a point.
+
+ In the base class this is a pure virtual function.
+
+ \sa visualRect()
+*/
+
+/*!
+ \fn void QAbstractItemView::activated(const QModelIndex &index)
+
+ This signal is emitted when the item specified by \a index is
+ activated by the user. How to activate items depends on the
+ platform; e.g., by single- or double-clicking the item, or by
+ pressing the Return or Enter key when the item is current.
+
+ \sa clicked(), doubleClicked(), entered(), pressed()
+*/
+
+/*!
+ \fn void QAbstractItemView::entered(const QModelIndex &index)
+
+ This signal is emitted when the mouse cursor enters the item
+ specified by \a index.
+ Mouse tracking needs to be enabled for this feature to work.
+
+ \sa viewportEntered(), activated(), clicked(), doubleClicked(), pressed()
+*/
+
+/*!
+ \fn void QAbstractItemView::viewportEntered()
+
+ This signal is emitted when the mouse cursor enters the viewport.
+ Mouse tracking needs to be enabled for this feature to work.
+
+ \sa entered()
+*/
+
+/*!
+ \fn void QAbstractItemView::pressed(const QModelIndex &index)
+
+ This signal is emitted when a mouse button is pressed. The item
+ the mouse was pressed on is specified by \a index. The signal is
+ only emitted when the index is valid.
+
+ Use the QApplication::mouseButtons() function to get the state
+ of the mouse buttons.
+
+ \sa activated(), clicked(), doubleClicked(), entered()
+*/
+
+/*!
+ \fn void QAbstractItemView::clicked(const QModelIndex &index)
+
+ This signal is emitted when a mouse button is clicked. The item
+ the mouse was clicked on is specified by \a index. The signal is
+ only emitted when the index is valid.
+
+ \sa activated(), doubleClicked(), entered(), pressed()
+*/
+
+/*!
+ \fn void QAbstractItemView::doubleClicked(const QModelIndex &index)
+
+ This signal is emitted when a mouse button is double-clicked. The
+ item the mouse was double-clicked on is specified by \a index.
+ The signal is only emitted when the index is valid.
+
+ \sa clicked(), activated()
+*/
+
+/*!
+ \fn QModelIndex QAbstractItemView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers) = 0
+
+ Returns a QModelIndex object pointing to the next object in the view,
+ based on the given \a cursorAction and keyboard modifiers specified
+ by \a modifiers.
+
+ In the base class this is a pure virtual function.
+*/
+
+/*!
+ \fn int QAbstractItemView::horizontalOffset() const = 0
+
+ Returns the horizontal offset of the view.
+
+ In the base class this is a pure virtual function.
+
+ \sa verticalOffset()
+*/
+
+/*!
+ \fn int QAbstractItemView::verticalOffset() const = 0
+
+ Returns the vertical offset of the view.
+
+ In the base class this is a pure virtual function.
+
+ \sa horizontalOffset()
+*/
+
+/*!
+ \fn bool QAbstractItemView::isIndexHidden(const QModelIndex &index) const
+
+ Returns true if the item referred to by the given \a index is hidden in the view,
+ otherwise returns false.
+
+ Hiding is a view specific feature. For example in TableView a column can be marked
+ as hidden or a row in the TreeView.
+
+ In the base class this is a pure virtual function.
+*/
+
+/*!
+ \fn void QAbstractItemView::setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags flags)
+
+ Applies the selection \a flags to the items in or touched by the
+ rectangle, \a rect.
+
+ When implementing your own itemview setSelection should call
+ selectionModel()->select(selection, flags) where selection
+ is either an empty QModelIndex or a QItemSelection that contains
+ all items that are contained in \a rect.
+
+ \sa selectionCommand(), selectedIndexes()
+*/
+
+/*!
+ \fn QRegion QAbstractItemView::visualRegionForSelection(const QItemSelection &selection) const = 0
+
+ Returns the region from the viewport of the items in the given
+ \a selection.
+
+ In the base class this is a pure virtual function.
+
+ \sa visualRect(), selectedIndexes()
+*/
+
+/*!
+ \fn void QAbstractItemView::update()
+ \internal
+*/
+
+/*!
+ Constructs an abstract item view with the given \a parent.
+*/
+QAbstractItemView::QAbstractItemView(QWidget *parent)
+ : QAbstractScrollArea(*(new QAbstractItemViewPrivate), parent)
+{
+ d_func()->init();
+}
+
+/*!
+ \internal
+*/
+QAbstractItemView::QAbstractItemView(QAbstractItemViewPrivate &dd, QWidget *parent)
+ : QAbstractScrollArea(dd, parent)
+{
+ d_func()->init();
+}
+
+/*!
+ Destroys the view.
+*/
+QAbstractItemView::~QAbstractItemView()
+{
+ Q_D(QAbstractItemView);
+ // stop these timers here before ~QObject
+ d->delayedReset.stop();
+ d->updateTimer.stop();
+ d->delayedEditing.stop();
+ d->delayedAutoScroll.stop();
+ d->autoScrollTimer.stop();
+ d->delayedLayout.stop();
+ d->fetchMoreTimer.stop();
+}
+
+/*!
+ Sets the \a model for the view to present.
+
+ This function will create and set a new selection model, replacing any
+ model that was previously set with setSelectionModel(). However, the old
+ selection model will not be deleted as it may be shared between several
+ views. We recommend that you delete the old selection model if it is no
+ longer required. This is done with the following code:
+
+ \snippet doc/src/snippets/code/src_gui_itemviews_qabstractitemview.cpp 2
+
+ If both the old model and the old selection model do not have parents, or
+ if their parents are long-lived objects, it may be preferable to call their
+ deleteLater() functions to explicitly delete them.
+
+ The view \e{does not} take ownership of the model unless it is the model's
+ parent object because the model may be shared between many different views.
+
+ \sa selectionModel(), setSelectionModel()
+*/
+void QAbstractItemView::setModel(QAbstractItemModel *model)
+{
+ Q_D(QAbstractItemView);
+ if (model == d->model)
+ return;
+ if (d->model && d->model != QAbstractItemModelPrivate::staticEmptyModel()) {
+ disconnect(d->model, SIGNAL(destroyed()),
+ this, SLOT(_q_modelDestroyed()));
+ disconnect(d->model, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
+ this, SLOT(dataChanged(QModelIndex,QModelIndex)));
+ disconnect(d->model, SIGNAL(headerDataChanged(Qt::Orientation,int,int)),
+ this, SLOT(_q_headerDataChanged()));
+ disconnect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)),
+ this, SLOT(rowsInserted(QModelIndex,int,int)));
+ disconnect(d->model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
+ this, SLOT(rowsAboutToBeRemoved(QModelIndex,int,int)));
+ disconnect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
+ this, SLOT(_q_rowsRemoved(QModelIndex,int,int)));
+ disconnect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)),
+ this, SLOT(_q_rowsInserted(QModelIndex,int,int)));
+ disconnect(d->model, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)),
+ this, SLOT(_q_columnsAboutToBeRemoved(QModelIndex,int,int)));
+ disconnect(d->model, SIGNAL(columnsRemoved(QModelIndex,int,int)),
+ this, SLOT(_q_columnsRemoved(QModelIndex,int,int)));
+ disconnect(d->model, SIGNAL(columnsInserted(QModelIndex,int,int)),
+ this, SLOT(_q_columnsInserted(QModelIndex,int,int)));
+
+ disconnect(d->model, SIGNAL(modelReset()), this, SLOT(reset()));
+ disconnect(d->model, SIGNAL(layoutChanged()), this, SLOT(_q_layoutChanged()));
+ }
+ d->model = (model ? model : QAbstractItemModelPrivate::staticEmptyModel());
+
+ // These asserts do basic sanity checking of the model
+ Q_ASSERT_X(d->model->index(0,0) == d->model->index(0,0),
+ "QAbstractItemView::setModel",
+ "A model should return the exact same index "
+ "(including its internal id/pointer) when asked for it twice in a row.");
+ Q_ASSERT_X(!d->model->index(0,0).parent().isValid(),
+ "QAbstractItemView::setModel",
+ "The parent of a top level index should be invalid");
+
+ if (d->model != QAbstractItemModelPrivate::staticEmptyModel()) {
+ connect(d->model, SIGNAL(destroyed()),
+ this, SLOT(_q_modelDestroyed()));
+ connect(d->model, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
+ this, SLOT(dataChanged(QModelIndex,QModelIndex)));
+ connect(d->model, SIGNAL(headerDataChanged(Qt::Orientation,int,int)),
+ this, SLOT(_q_headerDataChanged()));
+ connect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)),
+ this, SLOT(rowsInserted(QModelIndex,int,int)));
+ connect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)),
+ this, SLOT(_q_rowsInserted(QModelIndex,int,int)));
+ connect(d->model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
+ this, SLOT(rowsAboutToBeRemoved(QModelIndex,int,int)));
+ connect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
+ this, SLOT(_q_rowsRemoved(QModelIndex,int,int)));
+ connect(d->model, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)),
+ this, SLOT(_q_columnsAboutToBeRemoved(QModelIndex,int,int)));
+ connect(d->model, SIGNAL(columnsRemoved(QModelIndex,int,int)),
+ this, SLOT(_q_columnsRemoved(QModelIndex,int,int)));
+ connect(d->model, SIGNAL(columnsInserted(QModelIndex,int,int)),
+ this, SLOT(_q_columnsInserted(QModelIndex,int,int)));
+
+ connect(d->model, SIGNAL(modelReset()), this, SLOT(reset()));
+ connect(d->model, SIGNAL(layoutChanged()), this, SLOT(_q_layoutChanged()));
+ }
+
+ QItemSelectionModel *selection_model = new QItemSelectionModel(d->model, this);
+ connect(d->model, SIGNAL(destroyed()), selection_model, SLOT(deleteLater()));
+ setSelectionModel(selection_model);
+
+ reset(); // kill editors, set new root and do layout
+}
+
+/*!
+ Returns the model that this view is presenting.
+*/
+QAbstractItemModel *QAbstractItemView::model() const
+{
+ Q_D(const QAbstractItemView);
+ return (d->model == QAbstractItemModelPrivate::staticEmptyModel() ? 0 : d->model);
+}
+
+/*!
+ Sets the current selection model to the given \a selectionModel.
+
+ Note that, if you call setModel() after this function, the given \a selectionModel
+ will be replaced by one created by the view.
+
+ \note It is up to the application to delete the old selection model if it is no
+ longer needed; i.e., if it is not being used by other views. This will happen
+ automatically when its parent object is deleted. However, if it does not have a
+ parent, or if the parent is a long-lived object, it may be preferable to call its
+ deleteLater() function to explicitly delete it.
+
+ \sa selectionModel(), setModel(), clearSelection()
+*/
+void QAbstractItemView::setSelectionModel(QItemSelectionModel *selectionModel)
+{
+ // ### if the given model is null, we should use the original selection model
+ Q_ASSERT(selectionModel);
+ Q_D(QAbstractItemView);
+
+ if (selectionModel->model() != d->model) {
+ qWarning("QAbstractItemView::setSelectionModel() failed: "
+ "Trying to set a selection model, which works on "
+ "a different model than the view.");
+ return;
+ }
+
+ if (d->selectionModel) {
+ disconnect(d->selectionModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
+ this, SLOT(selectionChanged(QItemSelection,QItemSelection)));
+ disconnect(d->selectionModel, SIGNAL(currentChanged(QModelIndex,QModelIndex)),
+ this, SLOT(currentChanged(QModelIndex,QModelIndex)));
+ }
+
+ d->selectionModel = selectionModel;
+
+ if (d->selectionModel) {
+ connect(d->selectionModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
+ this, SLOT(selectionChanged(QItemSelection,QItemSelection)));
+ connect(d->selectionModel, SIGNAL(currentChanged(QModelIndex,QModelIndex)),
+ this, SLOT(currentChanged(QModelIndex,QModelIndex)));
+ }
+}
+
+/*!
+ Returns the current selection model.
+
+ \sa setSelectionModel(), selectedIndexes()
+*/
+QItemSelectionModel* QAbstractItemView::selectionModel() const
+{
+ Q_D(const QAbstractItemView);
+ return d->selectionModel;
+}
+
+/*!
+ Sets the item delegate for this view and its model to \a delegate.
+ This is useful if you want complete control over the editing and
+ display of items.
+
+ Any existing delegate will be removed, but not deleted. QAbstractItemView
+ does not take ownership of \a delegate.
+
+ \warning You should not share the same instance of a delegate between views.
+ Doing so can cause incorrect or unintuitive editing behavior since each
+ view connected to a given delegate may receive the \l{QAbstractItemDelegate::}{closeEditor()}
+ signal, and attempt to access, modify or close an editor that has already been closed.
+
+ \sa itemDelegate()
+*/
+void QAbstractItemView::setItemDelegate(QAbstractItemDelegate *delegate)
+{
+ Q_D(QAbstractItemView);
+ if (delegate == d->itemDelegate)
+ return;
+
+ if (d->itemDelegate) {
+ if (d->delegateRefCount(d->itemDelegate) == 1) {
+ disconnect(d->itemDelegate, SIGNAL(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)),
+ this, SLOT(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)));
+ disconnect(d->itemDelegate, SIGNAL(commitData(QWidget*)), this, SLOT(commitData(QWidget*)));
+ disconnect(d->itemDelegate, SIGNAL(sizeHintChanged(QModelIndex)), this, SLOT(doItemsLayout()));
+ }
+ }
+
+ if (delegate) {
+ if (d->delegateRefCount(delegate) == 0) {
+ connect(delegate, SIGNAL(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)),
+ this, SLOT(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)));
+ connect(delegate, SIGNAL(commitData(QWidget*)), this, SLOT(commitData(QWidget*)));
+ qRegisterMetaType<QModelIndex>("QModelIndex");
+ connect(delegate, SIGNAL(sizeHintChanged(QModelIndex)), this, SLOT(doItemsLayout()), Qt::QueuedConnection);
+ }
+ }
+ d->itemDelegate = delegate;
+ viewport()->update();
+}
+
+/*!
+ Returns the item delegate used by this view and model. This is
+ either one set with setItemDelegate(), or the default one.
+
+ \sa setItemDelegate()
+*/
+QAbstractItemDelegate *QAbstractItemView::itemDelegate() const
+{
+ return d_func()->itemDelegate;
+}
+
+/*!
+ \reimp
+*/
+QVariant QAbstractItemView::inputMethodQuery(Qt::InputMethodQuery query) const
+{
+ const QModelIndex current = currentIndex();
+ if (!current.isValid() || query != Qt::ImCursorRectangle)
+ return QAbstractScrollArea::inputMethodQuery(query);
+ return visualRect(current);
+}
+
+/*!
+ \since 4.2
+
+ Sets the given item \a delegate used by this view and model for the given
+ \a row. All items on \a row will be drawn and managed by \a delegate
+ instead of using the default delegate (i.e., itemDelegate()).
+
+ Any existing row delegate for \a row will be removed, but not
+ deleted. QAbstractItemView does not take ownership of \a delegate.
+
+ \note If a delegate has been assigned to both a row and a column, the row
+ delegate (i.e., this delegate) will take precedence and manage the
+ intersecting cell index.
+
+ \warning You should not share the same instance of a delegate between views.
+ Doing so can cause incorrect or unintuitive editing behavior since each
+ view connected to a given delegate may receive the \l{QAbstractItemDelegate::}{closeEditor()}
+ signal, and attempt to access, modify or close an editor that has already been closed.
+
+ \sa itemDelegateForRow(), setItemDelegateForColumn(), itemDelegate()
+*/
+void QAbstractItemView::setItemDelegateForRow(int row, QAbstractItemDelegate *delegate)
+{
+ Q_D(QAbstractItemView);
+ if (QAbstractItemDelegate *rowDelegate = d->rowDelegates.value(row, 0)) {
+ if (d->delegateRefCount(rowDelegate) == 1) {
+ disconnect(rowDelegate, SIGNAL(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)),
+ this, SLOT(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)));
+ disconnect(rowDelegate, SIGNAL(commitData(QWidget*)), this, SLOT(commitData(QWidget*)));
+ }
+ d->rowDelegates.remove(row);
+ }
+ if (delegate) {
+ if (d->delegateRefCount(delegate) == 0) {
+ connect(delegate, SIGNAL(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)),
+ this, SLOT(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)));
+ connect(delegate, SIGNAL(commitData(QWidget*)), this, SLOT(commitData(QWidget*)));
+ }
+ d->rowDelegates.insert(row, delegate);
+ }
+ viewport()->update();
+}
+
+/*!
+ \since 4.2
+
+ Returns the item delegate used by this view and model for the given \a row,
+ or 0 if no delegate has been assigned. You can call itemDelegate() to get a
+ pointer to the current delegate for a given index.
+
+ \sa setItemDelegateForRow(), itemDelegateForColumn(), setItemDelegate()
+*/
+QAbstractItemDelegate *QAbstractItemView::itemDelegateForRow(int row) const
+{
+ Q_D(const QAbstractItemView);
+ return d->rowDelegates.value(row, 0);
+}
+
+/*!
+ \since 4.2
+
+ Sets the given item \a delegate used by this view and model for the given
+ \a column. All items on \a column will be drawn and managed by \a delegate
+ instead of using the default delegate (i.e., itemDelegate()).
+
+ Any existing column delegate for \a column will be removed, but not
+ deleted. QAbstractItemView does not take ownership of \a delegate.
+
+ \note If a delegate has been assigned to both a row and a column, the row
+ delegate will take precedence and manage the intersecting cell index.
+
+ \warning You should not share the same instance of a delegate between views.
+ Doing so can cause incorrect or unintuitive editing behavior since each
+ view connected to a given delegate may receive the \l{QAbstractItemDelegate::}{closeEditor()}
+ signal, and attempt to access, modify or close an editor that has already been closed.
+
+ \sa itemDelegateForColumn(), setItemDelegateForRow(), itemDelegate()
+*/
+void QAbstractItemView::setItemDelegateForColumn(int column, QAbstractItemDelegate *delegate)
+{
+ Q_D(QAbstractItemView);
+ if (QAbstractItemDelegate *columnDelegate = d->columnDelegates.value(column, 0)) {
+ if (d->delegateRefCount(columnDelegate) == 1) {
+ disconnect(columnDelegate, SIGNAL(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)),
+ this, SLOT(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)));
+ disconnect(columnDelegate, SIGNAL(commitData(QWidget*)), this, SLOT(commitData(QWidget*)));
+ }
+ d->columnDelegates.remove(column);
+ }
+ if (delegate) {
+ if (d->delegateRefCount(delegate) == 0) {
+ connect(delegate, SIGNAL(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)),
+ this, SLOT(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)));
+ connect(delegate, SIGNAL(commitData(QWidget*)), this, SLOT(commitData(QWidget*)));
+ }
+ d->columnDelegates.insert(column, delegate);
+ }
+ viewport()->update();
+}
+
+/*!
+ \since 4.2
+
+ Returns the item delegate used by this view and model for the given \a
+ column. You can call itemDelegate() to get a pointer to the current delegate
+ for a given index.
+
+ \sa setItemDelegateForColumn(), itemDelegateForRow(), itemDelegate()
+*/
+QAbstractItemDelegate *QAbstractItemView::itemDelegateForColumn(int column) const
+{
+ Q_D(const QAbstractItemView);
+ return d->columnDelegates.value(column, 0);
+}
+
+/*!
+ Returns the item delegate used by this view and model for
+ the given \a index.
+*/
+QAbstractItemDelegate *QAbstractItemView::itemDelegate(const QModelIndex &index) const
+{
+ Q_D(const QAbstractItemView);
+ return d->delegateForIndex(index);
+}
+
+/*!
+ \property QAbstractItemView::selectionMode
+ \brief which selection mode the view operates in
+
+ This property controls whether the user can select one or many items
+ and, in many-item selections, whether the selection must be a
+ continuous range of items.
+
+ \sa SelectionMode SelectionBehavior
+*/
+void QAbstractItemView::setSelectionMode(SelectionMode mode)
+{
+ Q_D(QAbstractItemView);
+ d->selectionMode = mode;
+}
+
+QAbstractItemView::SelectionMode QAbstractItemView::selectionMode() const
+{
+ Q_D(const QAbstractItemView);
+ return d->selectionMode;
+}
+
+/*!
+ \property QAbstractItemView::selectionBehavior
+ \brief which selection behavior the view uses
+
+ This property holds whether selections are done
+ in terms of single items, rows or columns.
+
+ \sa SelectionMode SelectionBehavior
+*/
+
+void QAbstractItemView::setSelectionBehavior(QAbstractItemView::SelectionBehavior behavior)
+{
+ Q_D(QAbstractItemView);
+ d->selectionBehavior = behavior;
+}
+
+QAbstractItemView::SelectionBehavior QAbstractItemView::selectionBehavior() const
+{
+ Q_D(const QAbstractItemView);
+ return d->selectionBehavior;
+}
+
+/*!
+ Sets the current item to be the item at \a index.
+
+ Unless the current selection mode is
+ \l{QAbstractItemView::}{NoSelection}, the item is also be selected.
+ Note that this function also updates the starting position for any
+ new selections the user performs.
+
+ To set an item as the current item without selecting it, call
+
+ \c{selectionModel()->setCurrentIndex(index, QItemSelectionModel::NoUpdate);}
+
+ \sa currentIndex(), currentChanged(), selectionMode
+*/
+void QAbstractItemView::setCurrentIndex(const QModelIndex &index)
+{
+ Q_D(QAbstractItemView);
+ if (d->selectionModel && (!index.isValid() || d->isIndexEnabled(index))) {
+ QItemSelectionModel::SelectionFlags command = selectionCommand(index, 0);
+ d->selectionModel->setCurrentIndex(index, command);
+ d->currentIndexSet = true;
+ if ((command & QItemSelectionModel::Current) == 0)
+ d->pressedPosition = visualRect(currentIndex()).center() + d->offset();
+ }
+}
+
+/*!
+ Returns the model index of the current item.
+
+ \sa setCurrentIndex()
+*/
+QModelIndex QAbstractItemView::currentIndex() const
+{
+ Q_D(const QAbstractItemView);
+ return d->selectionModel ? d->selectionModel->currentIndex() : QModelIndex();
+}
+
+
+/*!
+ Reset the internal state of the view.
+
+ \warning This function will reset open editors, scroll bar positions,
+ selections, etc. Existing changes will not be committed. If you would like
+ to save your changes when resetting the view, you can reimplement this
+ function, commit your changes, and then call the superclass'
+ implementation.
+*/
+void QAbstractItemView::reset()
+{
+ Q_D(QAbstractItemView);
+ d->delayedReset.stop(); //make sure we stop the timer
+ foreach (const QEditorInfo &info, d->indexEditorHash) {
+ if (info.widget)
+ d->releaseEditor(info.widget.data());
+ }
+ d->editorIndexHash.clear();
+ d->indexEditorHash.clear();
+ d->persistent.clear();
+ d->currentIndexSet = false;
+ setState(NoState);
+ setRootIndex(QModelIndex());
+ if (d->selectionModel)
+ d->selectionModel->reset();
+#ifndef QT_NO_ACCESSIBILITY
+#ifdef Q_WS_X11
+ if (QAccessible::isActive()) {
+ QAccessible::queryAccessibleInterface(this)->table2Interface()->modelReset();
+ QAccessible::updateAccessibility(this, 0, QAccessible::TableModelChanged);
+ }
+#endif
+#endif
+}
+
+/*!
+ Sets the root item to the item at the given \a index.
+
+ \sa rootIndex()
+*/
+void QAbstractItemView::setRootIndex(const QModelIndex &index)
+{
+ Q_D(QAbstractItemView);
+ if (index.isValid() && index.model() != d->model) {
+ qWarning("QAbstractItemView::setRootIndex failed : index must be from the currently set model");
+ return;
+ }
+ d->root = index;
+ d->doDelayedItemsLayout();
+}
+
+/*!
+ Returns the model index of the model's root item. The root item is
+ the parent item to the view's toplevel items. The root can be invalid.
+
+ \sa setRootIndex()
+*/
+QModelIndex QAbstractItemView::rootIndex() const
+{
+ return QModelIndex(d_func()->root);
+}
+
+/*!
+ Selects all items in the view.
+ This function will use the selection behavior
+ set on the view when selecting.
+
+ \sa setSelection(), selectedIndexes(), clearSelection()
+*/
+void QAbstractItemView::selectAll()
+{
+ Q_D(QAbstractItemView);
+ SelectionMode mode = d->selectionMode;
+ if (mode == MultiSelection || mode == ExtendedSelection)
+ d->selectAll(QItemSelectionModel::ClearAndSelect
+ |d->selectionBehaviorFlags());
+ else if (mode != SingleSelection)
+ d->selectAll(selectionCommand(d->model->index(0, 0, d->root)));
+}
+
+/*!
+ Starts editing the item corresponding to the given \a index if it is
+ editable.
+
+ Note that this function does not change the current index. Since the current
+ index defines the next and previous items to edit, users may find that
+ keyboard navigation does not work as expected. To provide consistent navigation
+ behavior, call setCurrentIndex() before this function with the same model
+ index.
+
+ \sa QModelIndex::flags()
+*/
+void QAbstractItemView::edit(const QModelIndex &index)
+{
+ Q_D(QAbstractItemView);
+ if (!d->isIndexValid(index))
+ qWarning("edit: index was invalid");
+ if (!edit(index, AllEditTriggers, 0))
+ qWarning("edit: editing failed");
+}
+
+/*!
+ Deselects all selected items. The current index will not be changed.
+
+ \sa setSelection(), selectAll()
+*/
+void QAbstractItemView::clearSelection()
+{
+ Q_D(QAbstractItemView);
+ if (d->selectionModel)
+ d->selectionModel->clearSelection();
+}
+
+/*!
+ \internal
+
+ This function is intended to lay out the items in the view.
+ The default implementation just calls updateGeometries() and updates the viewport.
+*/
+void QAbstractItemView::doItemsLayout()
+{
+ Q_D(QAbstractItemView);
+ d->interruptDelayedItemsLayout();
+ updateGeometries();
+ d->viewport->update();
+}
+
+/*!
+ \property QAbstractItemView::editTriggers
+ \brief which actions will initiate item editing
+
+ This property is a selection of flags defined by
+ \l{EditTrigger}, combined using the OR
+ operator. The view will only initiate the editing of an item if the
+ action performed is set in this property.
+*/
+void QAbstractItemView::setEditTriggers(EditTriggers actions)
+{
+ Q_D(QAbstractItemView);
+ d->editTriggers = actions;
+}
+
+QAbstractItemView::EditTriggers QAbstractItemView::editTriggers() const
+{
+ Q_D(const QAbstractItemView);
+ return d->editTriggers;
+}
+
+/*!
+ \since 4.2
+ \property QAbstractItemView::verticalScrollMode
+ \brief how the view scrolls its contents in the vertical direction
+
+ This property controls how the view scroll its contents vertically.
+ Scrolling can be done either per pixel or per item.
+*/
+
+void QAbstractItemView::setVerticalScrollMode(ScrollMode mode)
+{
+ Q_D(QAbstractItemView);
+ if (mode == d->verticalScrollMode)
+ return;
+ QModelIndex topLeft = indexAt(QPoint(0, 0));
+ d->verticalScrollMode = mode;
+ updateGeometries(); // update the scroll bars
+ scrollTo(topLeft, QAbstractItemView::PositionAtTop);
+}
+
+QAbstractItemView::ScrollMode QAbstractItemView::verticalScrollMode() const
+{
+ Q_D(const QAbstractItemView);
+ return d->verticalScrollMode;
+}
+
+/*!
+ \since 4.2
+ \property QAbstractItemView::horizontalScrollMode
+ \brief how the view scrolls its contents in the horizontal direction
+
+ This property controls how the view scroll its contents horizontally.
+ Scrolling can be done either per pixel or per item.
+*/
+
+void QAbstractItemView::setHorizontalScrollMode(ScrollMode mode)
+{
+ Q_D(QAbstractItemView);
+ d->horizontalScrollMode = mode;
+ updateGeometries(); // update the scroll bars
+}
+
+QAbstractItemView::ScrollMode QAbstractItemView::horizontalScrollMode() const
+{
+ Q_D(const QAbstractItemView);
+ return d->horizontalScrollMode;
+}
+
+#ifndef QT_NO_DRAGANDDROP
+/*!
+ \since 4.2
+ \property QAbstractItemView::dragDropOverwriteMode
+ \brief the view's drag and drop behavior
+
+ If its value is \c true, the selected data will overwrite the
+ existing item data when dropped, while moving the data will clear
+ the item. If its value is \c false, the selected data will be
+ inserted as a new item when the data is dropped. When the data is
+ moved, the item is removed as well.
+
+ The default value is \c false, as in the QListView and QTreeView
+ subclasses. In the QTableView subclass, on the other hand, the
+ property has been set to \c true.
+
+ Note: This is not intended to prevent overwriting of items.
+ The model's implementation of flags() should do that by not
+ returning Qt::ItemIsDropEnabled.
+
+ \sa dragDropMode
+*/
+void QAbstractItemView::setDragDropOverwriteMode(bool overwrite)
+{
+ Q_D(QAbstractItemView);
+ d->overwrite = overwrite;
+}
+
+bool QAbstractItemView::dragDropOverwriteMode() const
+{
+ Q_D(const QAbstractItemView);
+ return d->overwrite;
+}
+#endif
+
+/*!
+ \property QAbstractItemView::autoScroll
+ \brief whether autoscrolling in drag move events is enabled
+
+ If this property is set to true (the default), the
+ QAbstractItemView automatically scrolls the contents of the view
+ if the user drags within 16 pixels of the viewport edge. If the current
+ item changes, then the view will scroll automatically to ensure that the
+ current item is fully visible.
+
+ This property only works if the viewport accepts drops. Autoscroll is
+ switched off by setting this property to false.
+*/
+
+void QAbstractItemView::setAutoScroll(bool enable)
+{
+ Q_D(QAbstractItemView);
+ d->autoScroll = enable;
+}
+
+bool QAbstractItemView::hasAutoScroll() const
+{
+ Q_D(const QAbstractItemView);
+ return d->autoScroll;
+}
+
+/*!
+ \since 4.4
+ \property QAbstractItemView::autoScrollMargin
+ \brief the size of the area when auto scrolling is triggered
+
+ This property controls the size of the area at the edge of the viewport that
+ triggers autoscrolling. The default value is 16 pixels.
+*/
+void QAbstractItemView::setAutoScrollMargin(int margin)
+{
+ Q_D(QAbstractItemView);
+ d->autoScrollMargin = margin;
+}
+
+int QAbstractItemView::autoScrollMargin() const
+{
+ Q_D(const QAbstractItemView);
+ return d->autoScrollMargin;
+}
+
+/*!
+ \property QAbstractItemView::tabKeyNavigation
+ \brief whether item navigation with tab and backtab is enabled.
+*/
+
+void QAbstractItemView::setTabKeyNavigation(bool enable)
+{
+ Q_D(QAbstractItemView);
+ d->tabKeyNavigation = enable;
+}
+
+bool QAbstractItemView::tabKeyNavigation() const
+{
+ Q_D(const QAbstractItemView);
+ return d->tabKeyNavigation;
+}
+
+#ifndef QT_NO_DRAGANDDROP
+/*!
+ \property QAbstractItemView::showDropIndicator
+ \brief whether the drop indicator is shown when dragging items and dropping.
+
+ \sa dragEnabled DragDropMode dragDropOverwriteMode acceptDrops
+*/
+
+void QAbstractItemView::setDropIndicatorShown(bool enable)
+{
+ Q_D(QAbstractItemView);
+ d->showDropIndicator = enable;
+}
+
+bool QAbstractItemView::showDropIndicator() const
+{
+ Q_D(const QAbstractItemView);
+ return d->showDropIndicator;
+}
+
+/*!
+ \property QAbstractItemView::dragEnabled
+ \brief whether the view supports dragging of its own items
+
+ \sa showDropIndicator DragDropMode dragDropOverwriteMode acceptDrops
+*/
+
+void QAbstractItemView::setDragEnabled(bool enable)
+{
+ Q_D(QAbstractItemView);
+ d->dragEnabled = enable;
+}
+
+bool QAbstractItemView::dragEnabled() const
+{
+ Q_D(const QAbstractItemView);
+ return d->dragEnabled;
+}
+
+/*!
+ \since 4.2
+ \enum QAbstractItemView::DragDropMode
+
+ Describes the various drag and drop events the view can act upon.
+ By default the view does not support dragging or dropping (\c
+ NoDragDrop).
+
+ \value NoDragDrop Does not support dragging or dropping.
+ \value DragOnly The view supports dragging of its own items
+ \value DropOnly The view accepts drops
+ \value DragDrop The view supports both dragging and dropping
+ \value InternalMove The view accepts move (\bold{not copy}) operations only
+ from itself.
+
+ Note that the model used needs to provide support for drag and drop operations.
+
+ \sa setDragDropMode() {Using drag and drop with item views}
+*/
+
+/*!
+ \property QAbstractItemView::dragDropMode
+ \brief the drag and drop event the view will act upon
+
+ \since 4.2
+ \sa showDropIndicator dragDropOverwriteMode
+*/
+void QAbstractItemView::setDragDropMode(DragDropMode behavior)
+{
+ Q_D(QAbstractItemView);
+ d->dragDropMode = behavior;
+ setDragEnabled(behavior == DragOnly || behavior == DragDrop || behavior == InternalMove);
+ setAcceptDrops(behavior == DropOnly || behavior == DragDrop || behavior == InternalMove);
+}
+
+QAbstractItemView::DragDropMode QAbstractItemView::dragDropMode() const
+{
+ Q_D(const QAbstractItemView);
+ DragDropMode setBehavior = d->dragDropMode;
+ if (!dragEnabled() && !acceptDrops())
+ return NoDragDrop;
+
+ if (dragEnabled() && !acceptDrops())
+ return DragOnly;
+
+ if (!dragEnabled() && acceptDrops())
+ return DropOnly;
+
+ if (dragEnabled() && acceptDrops()) {
+ if (setBehavior == InternalMove)
+ return setBehavior;
+ else
+ return DragDrop;
+ }
+
+ return NoDragDrop;
+}
+
+/*!
+ \property QAbstractItemView::defaultDropAction
+ \brief the drop action that will be used by default in QAbstractItemView::drag()
+
+ If the property is not set, the drop action is CopyAction when the supported
+ actions support CopyAction.
+
+ \since 4.6
+ \sa showDropIndicator dragDropOverwriteMode
+*/
+void QAbstractItemView::setDefaultDropAction(Qt::DropAction dropAction)
+{
+ Q_D(QAbstractItemView);
+ d->defaultDropAction = dropAction;
+}
+
+Qt::DropAction QAbstractItemView::defaultDropAction() const
+{
+ Q_D(const QAbstractItemView);
+ return d->defaultDropAction;
+}
+
+#endif // QT_NO_DRAGANDDROP
+
+/*!
+ \property QAbstractItemView::alternatingRowColors
+ \brief whether to draw the background using alternating colors
+
+ If this property is true, the item background will be drawn using
+ QPalette::Base and QPalette::AlternateBase; otherwise the background
+ will be drawn using the QPalette::Base color.
+
+ By default, this property is false.
+*/
+void QAbstractItemView::setAlternatingRowColors(bool enable)
+{
+ Q_D(QAbstractItemView);
+ d->alternatingColors = enable;
+ if (isVisible())
+ d->viewport->update();
+}
+
+bool QAbstractItemView::alternatingRowColors() const
+{
+ Q_D(const QAbstractItemView);
+ return d->alternatingColors;
+}
+
+/*!
+ \property QAbstractItemView::iconSize
+ \brief the size of items' icons
+
+ Setting this property when the view is visible will cause the
+ items to be laid out again.
+*/
+void QAbstractItemView::setIconSize(const QSize &size)
+{
+ Q_D(QAbstractItemView);
+ if (size == d->iconSize)
+ return;
+ d->iconSize = size;
+ d->doDelayedItemsLayout();
+}
+
+QSize QAbstractItemView::iconSize() const
+{
+ Q_D(const QAbstractItemView);
+ return d->iconSize;
+}
+
+/*!
+ \property QAbstractItemView::textElideMode
+
+ \brief the position of the "..." in elided text.
+
+ The default value for all item views is Qt::ElideRight.
+*/
+void QAbstractItemView::setTextElideMode(Qt::TextElideMode mode)
+{
+ Q_D(QAbstractItemView);
+ d->textElideMode = mode;
+}
+
+Qt::TextElideMode QAbstractItemView::textElideMode() const
+{
+ return d_func()->textElideMode;
+}
+
+/*!
+ \reimp
+*/
+bool QAbstractItemView::focusNextPrevChild(bool next)
+{
+ Q_D(QAbstractItemView);
+ if (d->tabKeyNavigation && isEnabled() && d->viewport->isEnabled()) {
+ QKeyEvent event(QEvent::KeyPress, next ? Qt::Key_Tab : Qt::Key_Backtab, Qt::NoModifier);
+ keyPressEvent(&event);
+ if (event.isAccepted())
+ return true;
+ }
+ return QAbstractScrollArea::focusNextPrevChild(next);
+}
+
+/*!
+ \reimp
+*/
+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
+ if (d->shouldScrollToCurrentOnShow) {
+ d->shouldScrollToCurrentOnShow = false;
+ const QModelIndex current = currentIndex();
+ if (current.isValid() && (d->state == QAbstractItemView::EditingState || d->autoScroll))
+ scrollTo(current);
+ }
+ break;
+ case QEvent::LocaleChange:
+ viewport()->update();
+ break;
+ case QEvent::LayoutDirectionChange:
+ case QEvent::ApplicationLayoutDirectionChange:
+ updateGeometries();
+ break;
+ case QEvent::StyleChange:
+ doItemsLayout();
+ break;
+ case QEvent::FocusOut:
+ d->checkPersistentEditorFocus();
+ break;
+ case QEvent::FontChange:
+ d->doDelayedItemsLayout(); // the size of the items will change
+ break;
+#ifdef QT_SOFTKEYS_ENABLED
+ case QEvent::LanguageChange:
+ d->doneSoftKey->setText(QSoftKeyManager::standardSoftKeyText(QSoftKeyManager::DoneSoftKey));
+ break;
+#endif
+ default:
+ break;
+ }
+ return QAbstractScrollArea::event(event);
+}
+
+/*!
+ \fn bool QAbstractItemView::viewportEvent(QEvent *event)
+
+ This function is used to handle tool tips, and What's
+ This? mode, if the given \a event is a QEvent::ToolTip,or a
+ QEvent::WhatsThis. It passes all other
+ events on to its base class viewportEvent() handler.
+*/
+bool QAbstractItemView::viewportEvent(QEvent *event)
+{
+ Q_D(QAbstractItemView);
+ switch (event->type()) {
+ case QEvent::HoverMove:
+ case QEvent::HoverEnter:
+ d->setHoverIndex(indexAt(static_cast<QHoverEvent*>(event)->pos()));
+ break;
+ case QEvent::HoverLeave:
+ d->setHoverIndex(QModelIndex());
+ break;
+ case QEvent::Enter:
+ d->viewportEnteredNeeded = true;
+ break;
+ case QEvent::Leave:
+ #ifndef QT_NO_STATUSTIP
+ if (d->shouldClearStatusTip && d->parent) {
+ QString empty;
+ QStatusTipEvent tip(empty);
+ QApplication::sendEvent(d->parent, &tip);
+ d->shouldClearStatusTip = false;
+ }
+ #endif
+ d->enteredIndex = QModelIndex();
+ break;
+ case QEvent::ToolTip:
+ case QEvent::QueryWhatsThis:
+ case QEvent::WhatsThis: {
+ QHelpEvent *he = static_cast<QHelpEvent*>(event);
+ const QModelIndex index = indexAt(he->pos());
+ QStyleOptionViewItemV4 option = d->viewOptionsV4();
+ option.rect = visualRect(index);
+ option.state |= (index == currentIndex() ? QStyle::State_HasFocus : QStyle::State_None);
+ bool retval = false;
+ // ### Qt 5: make this a normal function call to a virtual function
+ QMetaObject::invokeMethod(d->delegateForIndex(index), "helpEvent",
+ Q_RETURN_ARG(bool, retval),
+ Q_ARG(QHelpEvent *, he),
+ Q_ARG(QAbstractItemView *, this),
+ Q_ARG(QStyleOptionViewItem, option),
+ Q_ARG(QModelIndex, index));
+ return retval;
+ }
+ case QEvent::FontChange:
+ d->doDelayedItemsLayout(); // the size of the items will change
+ break;
+ case QEvent::WindowActivate:
+ case QEvent::WindowDeactivate:
+ d->viewport->update();
+ break;
+ case QEvent::ScrollPrepare:
+ executeDelayedItemsLayout();
+#ifndef QT_NO_GESTURES
+ connect(QScroller::scroller(d->viewport), SIGNAL(stateChanged(QScroller::State)), this, SLOT(_q_scrollerStateChanged()), Qt::UniqueConnection);
+#endif
+ break;
+
+ default:
+ break;
+ }
+ return QAbstractScrollArea::viewportEvent(event);
+}
+
+/*!
+ This function is called with the given \a event when a mouse button is pressed
+ while the cursor is inside the widget. If a valid item is pressed on it is made
+ into the current item. This function emits the pressed() signal.
+*/
+void QAbstractItemView::mousePressEvent(QMouseEvent *event)
+{
+ Q_D(QAbstractItemView);
+ d->delayedAutoScroll.stop(); //any interaction with the view cancel the auto scrolling
+ QPoint pos = event->pos();
+ QPersistentModelIndex index = indexAt(pos);
+
+ if (!d->selectionModel
+ || (d->state == EditingState && d->hasEditor(index)))
+ return;
+
+ d->pressedAlreadySelected = d->selectionModel->isSelected(index);
+ d->pressedIndex = index;
+ d->pressedModifiers = event->modifiers();
+ QItemSelectionModel::SelectionFlags command = selectionCommand(index, event);
+ d->noSelectionOnMousePress = command == QItemSelectionModel::NoUpdate || !index.isValid();
+ QPoint offset = d->offset();
+ if ((command & QItemSelectionModel::Current) == 0)
+ d->pressedPosition = pos + offset;
+ else if (!indexAt(d->pressedPosition - offset).isValid())
+ d->pressedPosition = visualRect(currentIndex()).center() + offset;
+
+ if (edit(index, NoEditTriggers, event))
+ return;
+
+ if (index.isValid() && d->isIndexEnabled(index)) {
+ // we disable scrollTo for mouse press so the item doesn't change position
+ // when the user is interacting with it (ie. clicking on it)
+ bool autoScroll = d->autoScroll;
+ d->autoScroll = false;
+ d->selectionModel->setCurrentIndex(index, QItemSelectionModel::NoUpdate);
+ d->autoScroll = autoScroll;
+ QRect rect(d->pressedPosition - offset, pos);
+ if (command.testFlag(QItemSelectionModel::Toggle)) {
+ command &= ~QItemSelectionModel::Toggle;
+ d->ctrlDragSelectionFlag = d->selectionModel->isSelected(index) ? QItemSelectionModel::Deselect : QItemSelectionModel::Select;
+ command |= d->ctrlDragSelectionFlag;
+ }
+ setSelection(rect, command);
+
+ // signal handlers may change the model
+ emit pressed(index);
+ if (d->autoScroll) {
+ //we delay the autoscrolling to filter out double click event
+ //100 is to be sure that there won't be a double-click misinterpreted as a 2 single clicks
+ d->delayedAutoScroll.start(QApplication::doubleClickInterval()+100, this);
+ }
+
+ } else {
+ // Forces a finalize() even if mouse is pressed, but not on a item
+ d->selectionModel->select(QModelIndex(), QItemSelectionModel::Select);
+ }
+}
+
+/*!
+ This function is called with the given \a event when a mouse move event is
+ sent to the widget. If a selection is in progress and new items are moved
+ over the selection is extended; if a drag is in progress it is continued.
+*/
+void QAbstractItemView::mouseMoveEvent(QMouseEvent *event)
+{
+ Q_D(QAbstractItemView);
+ QPoint topLeft;
+ QPoint bottomRight = event->pos();
+
+ if (state() == ExpandingState || state() == CollapsingState)
+ return;
+
+#ifndef QT_NO_DRAGANDDROP
+ if (state() == DraggingState) {
+ topLeft = d->pressedPosition - d->offset();
+ if ((topLeft - bottomRight).manhattanLength() > QApplication::startDragDistance()) {
+ d->pressedIndex = QModelIndex();
+ startDrag(d->model->supportedDragActions());
+ setState(NoState); // the startDrag will return when the dnd operation is done
+ stopAutoScroll();
+ }
+ return;
+ }
+#endif // QT_NO_DRAGANDDROP
+
+ QPersistentModelIndex index = indexAt(bottomRight);
+ QModelIndex buddy = d->model->buddy(d->pressedIndex);
+ if ((state() == EditingState && d->hasEditor(buddy))
+ || edit(index, NoEditTriggers, event))
+ return;
+
+ if (d->selectionMode != SingleSelection)
+ topLeft = d->pressedPosition - d->offset();
+ else
+ topLeft = bottomRight;
+
+ d->checkMouseMove(index);
+
+#ifndef QT_NO_DRAGANDDROP
+ if (d->pressedIndex.isValid()
+ && d->dragEnabled
+ && (state() != DragSelectingState)
+ && (event->buttons() != Qt::NoButton)
+ && !d->selectedDraggableIndexes().isEmpty()) {
+ setState(DraggingState);
+ return;
+ }
+#endif
+
+ if ((event->buttons() & Qt::LeftButton) && d->selectionAllowed(index) && d->selectionModel) {
+ setState(DragSelectingState);
+ QItemSelectionModel::SelectionFlags command = selectionCommand(index, event);
+ if (d->ctrlDragSelectionFlag != QItemSelectionModel::NoUpdate && command.testFlag(QItemSelectionModel::Toggle)) {
+ command &= ~QItemSelectionModel::Toggle;
+ command |= d->ctrlDragSelectionFlag;
+ }
+
+ // Do the normalize ourselves, since QRect::normalized() is flawed
+ QRect selectionRect = QRect(topLeft, bottomRight);
+ setSelection(selectionRect, command);
+
+ // set at the end because it might scroll the view
+ if (index.isValid()
+ && (index != d->selectionModel->currentIndex())
+ && d->isIndexEnabled(index))
+ d->selectionModel->setCurrentIndex(index, QItemSelectionModel::NoUpdate);
+ }
+}
+
+/*!
+ This function is called with the given \a event when a mouse button is released,
+ after a mouse press event on the widget. If a user presses the mouse inside your
+ widget and then drags the mouse to another location before releasing the mouse button,
+ your widget receives the release event. The function will emit the clicked() signal if an
+ item was being pressed.
+*/
+void QAbstractItemView::mouseReleaseEvent(QMouseEvent *event)
+{
+ Q_D(QAbstractItemView);
+
+ QPoint pos = event->pos();
+ QPersistentModelIndex index = indexAt(pos);
+
+ if (state() == EditingState) {
+ if (d->isIndexValid(index)
+ && d->isIndexEnabled(index)
+ && d->sendDelegateEvent(index, event))
+ update(index);
+ return;
+ }
+
+ bool click = (index == d->pressedIndex && index.isValid());
+ bool selectedClicked = click && (event->button() & Qt::LeftButton) && d->pressedAlreadySelected;
+ EditTrigger trigger = (selectedClicked ? SelectedClicked : NoEditTriggers);
+ bool edited = edit(index, trigger, event);
+
+ d->ctrlDragSelectionFlag = QItemSelectionModel::NoUpdate;
+
+ if (d->selectionModel && d->noSelectionOnMousePress) {
+ d->noSelectionOnMousePress = false;
+ d->selectionModel->select(index, selectionCommand(index, event));
+ }
+
+ setState(NoState);
+
+ if (click) {
+ emit clicked(index);
+ if (edited)
+ return;
+ QStyleOptionViewItemV4 option = d->viewOptionsV4();
+ if (d->pressedAlreadySelected)
+ option.state |= QStyle::State_Selected;
+ if (style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick, &option, this))
+ emit activated(index);
+ }
+}
+
+/*!
+ This function is called with the given \a event when a mouse button is
+ double clicked inside the widget. If the double-click is on a valid item it
+ emits the doubleClicked() signal and calls edit() on the item.
+*/
+void QAbstractItemView::mouseDoubleClickEvent(QMouseEvent *event)
+{
+ Q_D(QAbstractItemView);
+
+ QModelIndex index = indexAt(event->pos());
+ if (!index.isValid()
+ || !d->isIndexEnabled(index)
+ || (d->pressedIndex != index)) {
+ QMouseEvent me(QEvent::MouseButtonPress,
+ event->localPos(), event->windowPos(), event->screenPos(),
+ event->button(), event->buttons(), event->modifiers());
+ mousePressEvent(&me);
+ return;
+ }
+ // signal handlers may change the model
+ QPersistentModelIndex persistent = index;
+ emit doubleClicked(persistent);
+ if ((event->button() & Qt::LeftButton) && !edit(persistent, DoubleClicked, event)
+ && !style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick, 0, this))
+ emit activated(persistent);
+}
+
+#ifndef QT_NO_DRAGANDDROP
+
+/*!
+ This function is called with the given \a event when a drag and drop operation enters
+ the widget. If the drag is over a valid dropping place (e.g. over an item that
+ accepts drops), the event is accepted; otherwise it is ignored.
+
+ \sa dropEvent() startDrag()
+*/
+void QAbstractItemView::dragEnterEvent(QDragEnterEvent *event)
+{
+ if (dragDropMode() == InternalMove
+ && (event->source() != this|| !(event->possibleActions() & Qt::MoveAction)))
+ return;
+
+ if (d_func()->canDecode(event)) {
+ event->accept();
+ setState(DraggingState);
+ } else {
+ event->ignore();
+ }
+}
+
+/*!
+ This function is called continuously with the given \a event during a drag and
+ drop operation over the widget. It can cause the view to scroll if, for example,
+ the user drags a selection to view's right or bottom edge. In this case, the
+ event will be accepted; otherwise it will be ignored.
+
+ \sa dropEvent() startDrag()
+*/
+void QAbstractItemView::dragMoveEvent(QDragMoveEvent *event)
+{
+ Q_D(QAbstractItemView);
+ if (dragDropMode() == InternalMove
+ && (event->source() != this || !(event->possibleActions() & Qt::MoveAction)))
+ return;
+
+ // ignore by default
+ event->ignore();
+
+ QModelIndex index = indexAt(event->pos());
+ d->hover = index;
+ if (!d->droppingOnItself(event, index)
+ && d->canDecode(event)) {
+
+ if (index.isValid() && d->showDropIndicator) {
+ QRect rect = visualRect(index);
+ d->dropIndicatorPosition = d->position(event->pos(), rect, index);
+ switch (d->dropIndicatorPosition) {
+ case AboveItem:
+ if (d->isIndexDropEnabled(index.parent())) {
+ d->dropIndicatorRect = QRect(rect.left(), rect.top(), rect.width(), 0);
+ event->accept();
+ } else {
+ d->dropIndicatorRect = QRect();
+ }
+ break;
+ case BelowItem:
+ if (d->isIndexDropEnabled(index.parent())) {
+ d->dropIndicatorRect = QRect(rect.left(), rect.bottom(), rect.width(), 0);
+ event->accept();
+ } else {
+ d->dropIndicatorRect = QRect();
+ }
+ break;
+ case OnItem:
+ if (d->isIndexDropEnabled(index)) {
+ d->dropIndicatorRect = rect;
+ event->accept();
+ } else {
+ d->dropIndicatorRect = QRect();
+ }
+ break;
+ case OnViewport:
+ d->dropIndicatorRect = QRect();
+ if (d->isIndexDropEnabled(rootIndex())) {
+ event->accept(); // allow dropping in empty areas
+ }
+ break;
+ }
+ } else {
+ d->dropIndicatorRect = QRect();
+ d->dropIndicatorPosition = OnViewport;
+ if (d->isIndexDropEnabled(rootIndex())) {
+ event->accept(); // allow dropping in empty areas
+ }
+ }
+ d->viewport->update();
+ } // can decode
+
+ if (d->shouldAutoScroll(event->pos()))
+ startAutoScroll();
+}
+
+/*!
+ \internal
+ Return true if this is a move from ourself and \a index is a child of the selection that
+ is being moved.
+ */
+bool QAbstractItemViewPrivate::droppingOnItself(QDropEvent *event, const QModelIndex &index)
+{
+ Q_Q(QAbstractItemView);
+ Qt::DropAction dropAction = event->dropAction();
+ if (q->dragDropMode() == QAbstractItemView::InternalMove)
+ dropAction = Qt::MoveAction;
+ if (event->source() == q
+ && event->possibleActions() & Qt::MoveAction
+ && dropAction == Qt::MoveAction) {
+ QModelIndexList selectedIndexes = q->selectedIndexes();
+ QModelIndex child = index;
+ while (child.isValid() && child != root) {
+ if (selectedIndexes.contains(child))
+ return true;
+ child = child.parent();
+ }
+ }
+ return false;
+}
+
+/*!
+ \fn void QAbstractItemView::dragLeaveEvent(QDragLeaveEvent *event)
+
+ This function is called when the item being dragged leaves the view.
+ The \a event describes the state of the drag and drop operation.
+*/
+void QAbstractItemView::dragLeaveEvent(QDragLeaveEvent *)
+{
+ Q_D(QAbstractItemView);
+ stopAutoScroll();
+ setState(NoState);
+ d->hover = QModelIndex();
+ d->viewport->update();
+}
+
+/*!
+ This function is called with the given \a event when a drop event occurs over
+ the widget. If the model accepts the even position the drop event is accepted;
+ otherwise it is ignored.
+
+ \sa startDrag()
+*/
+void QAbstractItemView::dropEvent(QDropEvent *event)
+{
+ Q_D(QAbstractItemView);
+ if (dragDropMode() == InternalMove) {
+ if (event->source() != this || !(event->possibleActions() & Qt::MoveAction))
+ return;
+ }
+
+ QModelIndex index;
+ int col = -1;
+ int row = -1;
+ if (d->dropOn(event, &row, &col, &index)) {
+ if (d->model->dropMimeData(event->mimeData(),
+ dragDropMode() == InternalMove ? Qt::MoveAction : event->dropAction(), row, col, index)) {
+ if (dragDropMode() == InternalMove)
+ event->setDropAction(Qt::MoveAction);
+ event->accept();
+ }
+ }
+ stopAutoScroll();
+ setState(NoState);
+ d->viewport->update();
+}
+
+/*!
+ If the event hasn't already been accepted, determines the index to drop on.
+
+ if (row == -1 && col == -1)
+ // append to this drop index
+ else
+ // place at row, col in drop index
+
+ If it returns true a drop can be done, and dropRow, dropCol and dropIndex reflects the position of the drop.
+ \internal
+ */
+bool QAbstractItemViewPrivate::dropOn(QDropEvent *event, int *dropRow, int *dropCol, QModelIndex *dropIndex)
+{
+ Q_Q(QAbstractItemView);
+ if (event->isAccepted())
+ return false;
+
+ QModelIndex index;
+ // rootIndex() (i.e. the viewport) might be a valid index
+ if (viewport->rect().contains(event->pos())) {
+ index = q->indexAt(event->pos());
+ if (!index.isValid() || !q->visualRect(index).contains(event->pos()))
+ index = root;
+ }
+
+ // If we are allowed to do the drop
+ if (model->supportedDropActions() & event->dropAction()) {
+ int row = -1;
+ int col = -1;
+ if (index != root) {
+ dropIndicatorPosition = position(event->pos(), q->visualRect(index), index);
+ switch (dropIndicatorPosition) {
+ case QAbstractItemView::AboveItem:
+ row = index.row();
+ col = index.column();
+ index = index.parent();
+ break;
+ case QAbstractItemView::BelowItem:
+ row = index.row() + 1;
+ col = index.column();
+ index = index.parent();
+ break;
+ case QAbstractItemView::OnItem:
+ case QAbstractItemView::OnViewport:
+ break;
+ }
+ } else {
+ dropIndicatorPosition = QAbstractItemView::OnViewport;
+ }
+ *dropIndex = index;
+ *dropRow = row;
+ *dropCol = col;
+ if (!droppingOnItself(event, index))
+ return true;
+ }
+ return false;
+}
+
+QAbstractItemView::DropIndicatorPosition
+QAbstractItemViewPrivate::position(const QPoint &pos, const QRect &rect, const QModelIndex &index) const
+{
+ QAbstractItemView::DropIndicatorPosition r = QAbstractItemView::OnViewport;
+ if (!overwrite) {
+ const int margin = 2;
+ if (pos.y() - rect.top() < margin) {
+ r = QAbstractItemView::AboveItem;
+ } else if (rect.bottom() - pos.y() < margin) {
+ r = QAbstractItemView::BelowItem;
+ } else if (rect.contains(pos, true)) {
+ r = QAbstractItemView::OnItem;
+ }
+ } else {
+ QRect touchingRect = rect;
+ touchingRect.adjust(-1, -1, 1, 1);
+ if (touchingRect.contains(pos, false)) {
+ r = QAbstractItemView::OnItem;
+ }
+ }
+
+ if (r == QAbstractItemView::OnItem && (!(model->flags(index) & Qt::ItemIsDropEnabled)))
+ r = pos.y() < rect.center().y() ? QAbstractItemView::AboveItem : QAbstractItemView::BelowItem;
+
+ return r;
+}
+
+#endif // QT_NO_DRAGANDDROP
+
+/*!
+ This function is called with the given \a event when the widget obtains the focus.
+ By default, the event is ignored.
+
+ \sa setFocus(), focusOutEvent()
+*/
+void QAbstractItemView::focusInEvent(QFocusEvent *event)
+{
+ Q_D(QAbstractItemView);
+ QAbstractScrollArea::focusInEvent(event);
+
+ const QItemSelectionModel* model = selectionModel();
+ const bool currentIndexValid = currentIndex().isValid();
+
+ if (model
+ && !d->currentIndexSet
+ && !currentIndexValid) {
+ bool autoScroll = d->autoScroll;
+ d->autoScroll = false;
+ QModelIndex index = moveCursor(MoveNext, Qt::NoModifier); // first visible index
+ if (index.isValid() && d->isIndexEnabled(index) && event->reason() != Qt::MouseFocusReason)
+ selectionModel()->setCurrentIndex(index, QItemSelectionModel::NoUpdate);
+ d->autoScroll = autoScroll;
+ }
+
+ if (model && currentIndexValid) {
+ if (currentIndex().flags() != Qt::ItemIsEditable)
+ setAttribute(Qt::WA_InputMethodEnabled, false);
+ else
+ setAttribute(Qt::WA_InputMethodEnabled);
+ }
+
+ if (!currentIndexValid)
+ setAttribute(Qt::WA_InputMethodEnabled, false);
+
+ d->viewport->update();
+}
+
+/*!
+ This function is called with the given \a event when the widget
+ looses the focus. By default, the event is ignored.
+
+ \sa clearFocus(), focusInEvent()
+*/
+void QAbstractItemView::focusOutEvent(QFocusEvent *event)
+{
+ Q_D(QAbstractItemView);
+ QAbstractScrollArea::focusOutEvent(event);
+ d->viewport->update();
+
+#ifdef QT_SOFTKEYS_ENABLED
+ if(!hasEditFocus())
+ removeAction(d->doneSoftKey);
+#endif
+}
+
+/*!
+ This function is called with the given \a event when a key event is sent to
+ the widget. The default implementation handles basic cursor movement, e.g. Up,
+ Down, Left, Right, Home, PageUp, and PageDown; the activated() signal is
+ emitted if the current index is valid and the activation key is pressed
+ (e.g. Enter or Return, depending on the platform).
+ This function is where editing is initiated by key press, e.g. if F2 is
+ pressed.
+
+ \sa edit(), moveCursor(), keyboardSearch(), tabKeyNavigation
+*/
+void QAbstractItemView::keyPressEvent(QKeyEvent *event)
+{
+ Q_D(QAbstractItemView);
+ d->delayedAutoScroll.stop(); //any interaction with the view cancel the auto scrolling
+
+#ifdef QT_KEYPAD_NAVIGATION
+ switch (event->key()) {
+ case Qt::Key_Select:
+ if (QApplication::keypadNavigationEnabled()) {
+ if (!hasEditFocus()) {
+ setEditFocus(true);
+#ifdef QT_SOFTKEYS_ENABLED
+ // If we can't keypad navigate to any direction, there is no sense to add
+ // "Done" softkey, since it basically does nothing when there is
+ // only one widget in screen
+ if(QWidgetPrivate::canKeypadNavigate(Qt::Horizontal)
+ || QWidgetPrivate::canKeypadNavigate(Qt::Vertical))
+ addAction(d->doneSoftKey);
+#endif
+ return;
+ }
+ }
+ break;
+ case Qt::Key_Back:
+ if (QApplication::keypadNavigationEnabled() && hasEditFocus()) {
+#ifdef QT_SOFTKEYS_ENABLED
+ removeAction(d->doneSoftKey);
+#endif
+ setEditFocus(false);
+ } else {
+ event->ignore();
+ }
+ return;
+ case Qt::Key_Down:
+ case Qt::Key_Up:
+ // Let's ignore vertical navigation events, only if there is no other widget
+ // what can take the focus in vertical direction. This means widget can handle navigation events
+ // even the widget don't have edit focus, and there is no other widget in requested direction.
+ if(QApplication::keypadNavigationEnabled() && !hasEditFocus()
+ && QWidgetPrivate::canKeypadNavigate(Qt::Vertical)) {
+ event->ignore();
+ return;
+ }
+ break;
+ case Qt::Key_Left:
+ case Qt::Key_Right:
+ // Similar logic as in up and down events
+ if(QApplication::keypadNavigationEnabled() && !hasEditFocus()
+ && (QWidgetPrivate::canKeypadNavigate(Qt::Horizontal) || QWidgetPrivate::inTabWidget(this))) {
+ event->ignore();
+ return;
+ }
+ break;
+ default:
+ if (QApplication::keypadNavigationEnabled() && !hasEditFocus()) {
+ event->ignore();
+ return;
+ }
+ }
+#endif
+
+#if !defined(QT_NO_CLIPBOARD) && !defined(QT_NO_SHORTCUT)
+ if (event == QKeySequence::Copy) {
+ QVariant variant;
+ if (d->model)
+ variant = d->model->data(currentIndex(), Qt::DisplayRole);
+ if (variant.type() == QVariant::String)
+ QApplication::clipboard()->setText(variant.toString());
+ event->accept();
+ }
+#endif
+
+ QPersistentModelIndex newCurrent;
+ d->moveCursorUpdatedView = false;
+ switch (event->key()) {
+ case Qt::Key_Down:
+ newCurrent = moveCursor(MoveDown, event->modifiers());
+ break;
+ case Qt::Key_Up:
+ newCurrent = moveCursor(MoveUp, event->modifiers());
+ break;
+ case Qt::Key_Left:
+ newCurrent = moveCursor(MoveLeft, event->modifiers());
+ break;
+ case Qt::Key_Right:
+ newCurrent = moveCursor(MoveRight, event->modifiers());
+ break;
+ case Qt::Key_Home:
+ newCurrent = moveCursor(MoveHome, event->modifiers());
+ break;
+ case Qt::Key_End:
+ newCurrent = moveCursor(MoveEnd, event->modifiers());
+ break;
+ case Qt::Key_PageUp:
+ newCurrent = moveCursor(MovePageUp, event->modifiers());
+ break;
+ case Qt::Key_PageDown:
+ newCurrent = moveCursor(MovePageDown, event->modifiers());
+ break;
+ case Qt::Key_Tab:
+ if (d->tabKeyNavigation)
+ newCurrent = moveCursor(MoveNext, event->modifiers());
+ break;
+ case Qt::Key_Backtab:
+ if (d->tabKeyNavigation)
+ newCurrent = moveCursor(MovePrevious, event->modifiers());
+ break;
+ }
+
+ QPersistentModelIndex oldCurrent = currentIndex();
+ if (newCurrent != oldCurrent && newCurrent.isValid() && d->isIndexEnabled(newCurrent)) {
+ if (!hasFocus() && QApplication::focusWidget() == indexWidget(oldCurrent))
+ setFocus();
+ QItemSelectionModel::SelectionFlags command = selectionCommand(newCurrent, event);
+ if (command != QItemSelectionModel::NoUpdate
+ || style()->styleHint(QStyle::SH_ItemView_MovementWithoutUpdatingSelection, 0, this)) {
+ // note that we don't check if the new current index is enabled because moveCursor() makes sure it is
+ if (command & QItemSelectionModel::Current) {
+ d->selectionModel->setCurrentIndex(newCurrent, QItemSelectionModel::NoUpdate);
+ if (!indexAt(d->pressedPosition - d->offset()).isValid())
+ d->pressedPosition = visualRect(oldCurrent).center() + d->offset();
+ QRect rect(d->pressedPosition - d->offset(), visualRect(newCurrent).center());
+ setSelection(rect, command);
+ } else {
+ d->selectionModel->setCurrentIndex(newCurrent, command);
+ d->pressedPosition = visualRect(newCurrent).center() + d->offset();
+ if (newCurrent.isValid()) {
+ // We copy the same behaviour as for mousePressEvent().
+ QRect rect(d->pressedPosition - d->offset(), QSize(1, 1));
+ setSelection(rect, command);
+ }
+ }
+ event->accept();
+ return;
+ }
+ }
+
+ switch (event->key()) {
+ // ignored keys
+ case Qt::Key_Down:
+ case Qt::Key_Up:
+#ifdef QT_KEYPAD_NAVIGATION
+ if (QApplication::keypadNavigationEnabled() && QWidgetPrivate::canKeypadNavigate(Qt::Vertical)) {
+ event->accept(); // don't change focus
+ break;
+ }
+#endif
+ case Qt::Key_Left:
+ case Qt::Key_Right:
+#ifdef QT_KEYPAD_NAVIGATION
+ if (QApplication::navigationMode() == Qt::NavigationModeKeypadDirectional
+ && (QWidgetPrivate::canKeypadNavigate(Qt::Horizontal)
+ || (QWidgetPrivate::inTabWidget(this) && d->model->columnCount(d->root) > 1))) {
+ event->accept(); // don't change focus
+ break;
+ }
+#endif // QT_KEYPAD_NAVIGATION
+ case Qt::Key_Home:
+ case Qt::Key_End:
+ case Qt::Key_PageUp:
+ case Qt::Key_PageDown:
+ case Qt::Key_Escape:
+ case Qt::Key_Shift:
+ case Qt::Key_Control:
+ case Qt::Key_Delete:
+ case Qt::Key_Backspace:
+ event->ignore();
+ break;
+ case Qt::Key_Space:
+ case Qt::Key_Select:
+ if (!edit(currentIndex(), AnyKeyPressed, event) && d->selectionModel)
+ d->selectionModel->select(currentIndex(), selectionCommand(currentIndex(), event));
+#ifdef QT_KEYPAD_NAVIGATION
+ if ( event->key()==Qt::Key_Select ) {
+ // Also do Key_Enter action.
+ if (currentIndex().isValid()) {
+ if (state() != EditingState)
+ emit activated(currentIndex());
+ } else {
+ event->ignore();
+ }
+ }
+#endif
+ break;
+#ifdef Q_WS_MAC
+ case Qt::Key_Enter:
+ case Qt::Key_Return:
+ // Propagate the enter if you couldn't edit the item and there are no
+ // current editors (if there are editors, the event was most likely propagated from it).
+ if (!edit(currentIndex(), EditKeyPressed, event) && d->editorIndexHash.isEmpty())
+ event->ignore();
+ break;
+#else
+ case Qt::Key_F2:
+ if (!edit(currentIndex(), EditKeyPressed, event))
+ event->ignore();
+ break;
+ case Qt::Key_Enter:
+ case Qt::Key_Return:
+ // ### we can't open the editor on enter, becuse
+ // some widgets will forward the enter event back
+ // to the viewport, starting an endless loop
+ if (state() != EditingState || hasFocus()) {
+ if (currentIndex().isValid())
+ emit activated(currentIndex());
+ event->ignore();
+ }
+ break;
+#endif
+ case Qt::Key_A:
+ if (event->modifiers() & Qt::ControlModifier) {
+ selectAll();
+ break;
+ }
+ default: {
+#ifdef Q_WS_MAC
+ if (event->key() == Qt::Key_O && event->modifiers() & Qt::ControlModifier && currentIndex().isValid()) {
+ emit activated(currentIndex());
+ break;
+ }
+#endif
+ bool modified = (event->modifiers() & (Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier));
+ if (!event->text().isEmpty() && !modified && !edit(currentIndex(), AnyKeyPressed, event)) {
+ keyboardSearch(event->text());
+ event->accept();
+ } else {
+ event->ignore();
+ }
+ break; }
+ }
+ if (d->moveCursorUpdatedView)
+ event->accept();
+}
+
+/*!
+ This function is called with the given \a event when a resize event is sent to
+ the widget.
+
+ \sa QWidget::resizeEvent()
+*/
+void QAbstractItemView::resizeEvent(QResizeEvent *event)
+{
+ QAbstractScrollArea::resizeEvent(event);
+ updateGeometries();
+}
+
+/*!
+ This function is called with the given \a event when a timer event is sent
+ to the widget.
+
+ \sa QObject::timerEvent()
+*/
+void QAbstractItemView::timerEvent(QTimerEvent *event)
+{
+ Q_D(QAbstractItemView);
+ if (event->timerId() == d->fetchMoreTimer.timerId())
+ d->fetchMore();
+ else if (event->timerId() == d->delayedReset.timerId())
+ reset();
+ else if (event->timerId() == d->autoScrollTimer.timerId())
+ doAutoScroll();
+ else if (event->timerId() == d->updateTimer.timerId())
+ d->updateDirtyRegion();
+ else if (event->timerId() == d->delayedEditing.timerId()) {
+ d->delayedEditing.stop();
+ edit(currentIndex());
+ } else if (event->timerId() == d->delayedLayout.timerId()) {
+ d->delayedLayout.stop();
+ if (isVisible()) {
+ d->interruptDelayedItemsLayout();
+ doItemsLayout();
+ const QModelIndex current = currentIndex();
+ if (current.isValid() && d->state == QAbstractItemView::EditingState)
+ scrollTo(current);
+ }
+ } else if (event->timerId() == d->delayedAutoScroll.timerId()) {
+ d->delayedAutoScroll.stop();
+ //end of the timer: if the current item is still the same as the one when the mouse press occurred
+ //we only get here if there was no double click
+ if (d->pressedIndex.isValid() && d->pressedIndex == currentIndex())
+ scrollTo(d->pressedIndex);
+ }
+}
+
+/*!
+ \reimp
+*/
+void QAbstractItemView::inputMethodEvent(QInputMethodEvent *event)
+{
+ if (event->commitString().isEmpty() && event->preeditString().isEmpty()) {
+ event->ignore();
+ return;
+ }
+ if (!edit(currentIndex(), AnyKeyPressed, event)) {
+ if (!event->commitString().isEmpty())
+ keyboardSearch(event->commitString());
+ event->ignore();
+ }
+}
+
+#ifndef QT_NO_DRAGANDDROP
+/*!
+ \enum QAbstractItemView::DropIndicatorPosition
+
+ This enum indicates the position of the drop indicator in
+ relation to the index at the current mouse position:
+
+ \value OnItem The item will be dropped on the index.
+
+ \value AboveItem The item will be dropped above the index.
+
+ \value BelowItem The item will be dropped below the index.
+
+ \value OnViewport The item will be dropped onto a region of the viewport with
+ no items. The way each view handles items dropped onto the viewport depends on
+ the behavior of the underlying model in use.
+*/
+
+
+/*!
+ \since 4.1
+
+ Returns the position of the drop indicator in relation to the closest item.
+*/
+QAbstractItemView::DropIndicatorPosition QAbstractItemView::dropIndicatorPosition() const
+{
+ Q_D(const QAbstractItemView);
+ return d->dropIndicatorPosition;
+}
+#endif
+
+/*!
+ This convenience function returns a list of all selected and
+ non-hidden item indexes in the view. The list contains no
+ duplicates, and is not sorted.
+
+ \sa QItemSelectionModel::selectedIndexes()
+*/
+QModelIndexList QAbstractItemView::selectedIndexes() const
+{
+ Q_D(const QAbstractItemView);
+ QModelIndexList indexes;
+ if (d->selectionModel) {
+ indexes = d->selectionModel->selectedIndexes();
+ QList<QModelIndex>::iterator it = indexes.begin();
+ while (it != indexes.end())
+ if (isIndexHidden(*it))
+ it = indexes.erase(it);
+ else
+ ++it;
+ }
+ return indexes;
+}
+
+/*!
+ Starts editing the item at \a index, creating an editor if
+ necessary, and returns true if the view's \l{State} is now
+ EditingState; otherwise returns false.
+
+ The action that caused the editing process is described by
+ \a trigger, and the associated event is specified by \a event.
+
+ Editing can be forced by specifying the \a trigger to be
+ QAbstractItemView::AllEditTriggers.
+
+ \sa closeEditor()
+*/
+bool QAbstractItemView::edit(const QModelIndex &index, EditTrigger trigger, QEvent *event)
+{
+ Q_D(QAbstractItemView);
+
+ if (!d->isIndexValid(index))
+ return false;
+
+ if (QWidget *w = (d->persistent.isEmpty() ? static_cast<QWidget*>(0) : d->editorForIndex(index).widget.data())) {
+ if (w->focusPolicy() == Qt::NoFocus)
+ return false;
+ w->setFocus();
+ return true;
+ }
+
+ if (trigger == DoubleClicked) {
+ d->delayedEditing.stop();
+ d->delayedAutoScroll.stop();
+ } else if (trigger == CurrentChanged) {
+ d->delayedEditing.stop();
+ }
+
+ if (d->sendDelegateEvent(index, event)) {
+ update(index);
+ return true;
+ }
+
+ // save the previous trigger before updating
+ EditTriggers lastTrigger = d->lastTrigger;
+ d->lastTrigger = trigger;
+
+ if (!d->shouldEdit(trigger, d->model->buddy(index)))
+ return false;
+
+ if (d->delayedEditing.isActive())
+ return false;
+
+ // we will receive a mouseButtonReleaseEvent after a
+ // mouseDoubleClickEvent, so we need to check the previous trigger
+ if (lastTrigger == DoubleClicked && trigger == SelectedClicked)
+ return false;
+
+ // we may get a double click event later
+ if (trigger == SelectedClicked)
+ d->delayedEditing.start(QApplication::doubleClickInterval(), this);
+ else
+ d->openEditor(index, d->shouldForwardEvent(trigger, event) ? event : 0);
+
+ return true;
+}
+
+/*!
+ \internal
+ Updates the data shown in the open editor widgets in the view.
+*/
+void QAbstractItemView::updateEditorData()
+{
+ Q_D(QAbstractItemView);
+ d->updateEditorData(QModelIndex(), QModelIndex());
+}
+
+/*!
+ \internal
+ Updates the geometry of the open editor widgets in the view.
+*/
+void QAbstractItemView::updateEditorGeometries()
+{
+ Q_D(QAbstractItemView);
+ if(d->editorIndexHash.isEmpty())
+ return;
+ QStyleOptionViewItemV4 option = d->viewOptionsV4();
+ QEditorIndexHash::iterator it = d->editorIndexHash.begin();
+ QWidgetList editorsToRelease;
+ QWidgetList editorsToHide;
+ while (it != d->editorIndexHash.end()) {
+ QModelIndex index = it.value();
+ QWidget *editor = it.key();
+ if (index.isValid() && editor) {
+ option.rect = visualRect(index);
+ if (option.rect.isValid()) {
+ editor->show();
+ QAbstractItemDelegate *delegate = d->delegateForIndex(index);
+ if (delegate)
+ delegate->updateEditorGeometry(editor, option, index);
+ } else {
+ editorsToHide << editor;
+ }
+ ++it;
+ } else {
+ d->indexEditorHash.remove(it.value());
+ it = d->editorIndexHash.erase(it);
+ editorsToRelease << editor;
+ }
+ }
+
+ //we hide and release the editor outside of the loop because it might change the focus and try
+ //to change the editors hashes.
+ for (int i = 0; i < editorsToHide.count(); ++i) {
+ editorsToHide.at(i)->hide();
+ }
+ for (int i = 0; i < editorsToRelease.count(); ++i) {
+ d->releaseEditor(editorsToRelease.at(i));
+ }
+}
+
+/*!
+ \since 4.4
+
+ Updates the geometry of the child widgets of the view.
+*/
+void QAbstractItemView::updateGeometries()
+{
+ updateEditorGeometries();
+ d_func()->fetchMoreTimer.start(0, this); //fetch more later
+}
+
+/*!
+ \internal
+*/
+void QAbstractItemView::verticalScrollbarValueChanged(int value)
+{
+ Q_D(QAbstractItemView);
+ if (verticalScrollBar()->maximum() == value && d->model->canFetchMore(d->root))
+ d->model->fetchMore(d->root);
+ QPoint posInVp = viewport()->mapFromGlobal(QCursor::pos());
+ if (viewport()->rect().contains(posInVp))
+ d->checkMouseMove(posInVp);
+}
+
+/*!
+ \internal
+*/
+void QAbstractItemView::horizontalScrollbarValueChanged(int value)
+{
+ Q_D(QAbstractItemView);
+ if (horizontalScrollBar()->maximum() == value && d->model->canFetchMore(d->root))
+ d->model->fetchMore(d->root);
+ QPoint posInVp = viewport()->mapFromGlobal(QCursor::pos());
+ if (viewport()->rect().contains(posInVp))
+ d->checkMouseMove(posInVp);
+}
+
+/*!
+ \internal
+*/
+void QAbstractItemView::verticalScrollbarAction(int)
+{
+ //do nothing
+}
+
+/*!
+ \internal
+*/
+void QAbstractItemView::horizontalScrollbarAction(int)
+{
+ //do nothing
+}
+
+/*!
+ Closes the given \a editor, and releases it. The \a hint is
+ used to specify how the view should respond to the end of the editing
+ operation. For example, the hint may indicate that the next item in
+ the view should be opened for editing.
+
+ \sa edit(), commitData()
+*/
+
+void QAbstractItemView::closeEditor(QWidget *editor, QAbstractItemDelegate::EndEditHint hint)
+{
+ Q_D(QAbstractItemView);
+
+ // Close the editor
+ if (editor) {
+ bool isPersistent = d->persistent.contains(editor);
+ bool hadFocus = editor->hasFocus();
+ QModelIndex index = d->indexForEditor(editor);
+ if (!index.isValid())
+ return; // the editor was not registered
+
+ if (!isPersistent) {
+ setState(NoState);
+ QModelIndex index = d->indexForEditor(editor);
+ editor->removeEventFilter(d->delegateForIndex(index));
+ d->removeEditor(editor);
+ }
+ if (hadFocus)
+ setFocus(); // this will send a focusLost event to the editor
+ else
+ d->checkPersistentEditorFocus();
+
+ QPointer<QWidget> ed = editor;
+ QApplication::sendPostedEvents(editor, 0);
+ editor = ed;
+
+ if (!isPersistent && editor)
+ d->releaseEditor(editor);
+ }
+
+ // The EndEditHint part
+ QItemSelectionModel::SelectionFlags flags = QItemSelectionModel::ClearAndSelect
+ | d->selectionBehaviorFlags();
+ switch (hint) {
+ case QAbstractItemDelegate::EditNextItem: {
+ QModelIndex index = moveCursor(MoveNext, Qt::NoModifier);
+ if (index.isValid()) {
+ QPersistentModelIndex persistent(index);
+ d->selectionModel->setCurrentIndex(persistent, flags);
+ // currentChanged signal would have already started editing
+ if (index.flags() & Qt::ItemIsEditable
+ && (!(editTriggers() & QAbstractItemView::CurrentChanged)))
+ edit(persistent);
+ } break; }
+ case QAbstractItemDelegate::EditPreviousItem: {
+ QModelIndex index = moveCursor(MovePrevious, Qt::NoModifier);
+ if (index.isValid()) {
+ QPersistentModelIndex persistent(index);
+ d->selectionModel->setCurrentIndex(persistent, flags);
+ // currentChanged signal would have already started editing
+ if (index.flags() & Qt::ItemIsEditable
+ && (!(editTriggers() & QAbstractItemView::CurrentChanged)))
+ edit(persistent);
+ } break; }
+ case QAbstractItemDelegate::SubmitModelCache:
+ d->model->submit();
+ break;
+ case QAbstractItemDelegate::RevertModelCache:
+ d->model->revert();
+ break;
+ default:
+ break;
+ }
+}
+
+/*!
+ Commit the data in the \a editor to the model.
+
+ \sa closeEditor()
+*/
+void QAbstractItemView::commitData(QWidget *editor)
+{
+ Q_D(QAbstractItemView);
+ if (!editor || !d->itemDelegate || d->currentlyCommittingEditor)
+ return;
+ QModelIndex index = d->indexForEditor(editor);
+ if (!index.isValid())
+ return;
+ d->currentlyCommittingEditor = editor;
+ QAbstractItemDelegate *delegate = d->delegateForIndex(index);
+ editor->removeEventFilter(delegate);
+ delegate->setModelData(editor, d->model, index);
+ editor->installEventFilter(delegate);
+ d->currentlyCommittingEditor = 0;
+}
+
+/*!
+ This function is called when the given \a editor has been destroyed.
+
+ \sa closeEditor()
+*/
+void QAbstractItemView::editorDestroyed(QObject *editor)
+{
+ Q_D(QAbstractItemView);
+ QWidget *w = qobject_cast<QWidget*>(editor);
+ d->removeEditor(w);
+ d->persistent.remove(w);
+ if (state() == EditingState)
+ setState(NoState);
+}
+
+/*!
+ \obsolete
+ Sets the horizontal scroll bar's steps per item to \a steps.
+
+ This is the number of steps used by the horizontal scroll bar to
+ represent the width of an item.
+
+ Note that if the view has a horizontal header, the item steps
+ will be ignored and the header section size will be used instead.
+
+ \sa horizontalStepsPerItem() setVerticalStepsPerItem()
+*/
+void QAbstractItemView::setHorizontalStepsPerItem(int steps)
+{
+ Q_UNUSED(steps)
+ // do nothing
+}
+
+/*!
+ \obsolete
+ Returns the horizontal scroll bar's steps per item.
+
+ \sa setHorizontalStepsPerItem() verticalStepsPerItem()
+*/
+int QAbstractItemView::horizontalStepsPerItem() const
+{
+ return 1;
+}
+
+/*!
+ \obsolete
+ Sets the vertical scroll bar's steps per item to \a steps.
+
+ This is the number of steps used by the vertical scroll bar to
+ represent the height of an item.
+
+ Note that if the view has a vertical header, the item steps
+ will be ignored and the header section size will be used instead.
+
+ \sa verticalStepsPerItem() setHorizontalStepsPerItem()
+*/
+void QAbstractItemView::setVerticalStepsPerItem(int steps)
+{
+ Q_UNUSED(steps)
+ // do nothing
+}
+
+/*!
+ \obsolete
+ Returns the vertical scroll bar's steps per item.
+
+ \sa setVerticalStepsPerItem() horizontalStepsPerItem()
+*/
+int QAbstractItemView::verticalStepsPerItem() const
+{
+ return 1;
+}
+
+/*!
+ Moves to and selects the item best matching the string \a search.
+ If no item is found nothing happens.
+
+ In the default implementation, the search is reset if \a search is empty, or
+ the time interval since the last search has exceeded
+ QApplication::keyboardInputInterval().
+*/
+void QAbstractItemView::keyboardSearch(const QString &search)
+{
+ Q_D(QAbstractItemView);
+ if (!d->model->rowCount(d->root) || !d->model->columnCount(d->root))
+ return;
+
+ QModelIndex start = currentIndex().isValid() ? currentIndex()
+ : d->model->index(0, 0, d->root);
+ bool skipRow = false;
+ bool keyboardTimeWasValid = d->keyboardInputTime.isValid();
+ qint64 keyboardInputTimeElapsed = d->keyboardInputTime.restart();
+ if (search.isEmpty() || !keyboardTimeWasValid
+ || keyboardInputTimeElapsed > QApplication::keyboardInputInterval()) {
+ d->keyboardInput = search;
+ skipRow = currentIndex().isValid(); //if it is not valid we should really start at QModelIndex(0,0)
+ } else {
+ d->keyboardInput += search;
+ }
+
+ // special case for searches with same key like 'aaaaa'
+ bool sameKey = false;
+ if (d->keyboardInput.length() > 1) {
+ int c = d->keyboardInput.count(d->keyboardInput.at(d->keyboardInput.length() - 1));
+ sameKey = (c == d->keyboardInput.length());
+ if (sameKey)
+ skipRow = true;
+ }
+
+ // skip if we are searching for the same key or a new search started
+ if (skipRow) {
+ QModelIndex parent = start.parent();
+ int newRow = (start.row() < d->model->rowCount(parent) - 1) ? start.row() + 1 : 0;
+ start = d->model->index(newRow, start.column(), parent);
+ }
+
+ // search from start with wraparound
+ const QString searchString = sameKey ? QString(d->keyboardInput.at(0)) : d->keyboardInput;
+ QModelIndex current = start;
+ QModelIndexList match;
+ QModelIndex firstMatch;
+ QModelIndex startMatch;
+ QModelIndexList previous;
+ do {
+ match = d->model->match(current, Qt::DisplayRole, searchString);
+ if (match == previous)
+ break;
+ firstMatch = match.value(0);
+ previous = match;
+ if (firstMatch.isValid()) {
+ if (d->isIndexEnabled(firstMatch)) {
+ setCurrentIndex(firstMatch);
+ break;
+ }
+ int row = firstMatch.row() + 1;
+ if (row >= d->model->rowCount(firstMatch.parent()))
+ row = 0;
+ current = firstMatch.sibling(row, firstMatch.column());
+
+ //avoid infinite loop if all the matching items are disabled.
+ if (!startMatch.isValid())
+ startMatch = firstMatch;
+ else if (startMatch == firstMatch)
+ break;
+ }
+ } while (current != start && firstMatch.isValid());
+}
+
+/*!
+ Returns the size hint for the item with the specified \a index or
+ an invalid size for invalid indexes.
+
+ \sa sizeHintForRow(), sizeHintForColumn()
+*/
+QSize QAbstractItemView::sizeHintForIndex(const QModelIndex &index) const
+{
+ Q_D(const QAbstractItemView);
+ if (!d->isIndexValid(index) || !d->itemDelegate)
+ return QSize();
+ return d->delegateForIndex(index)->sizeHint(d->viewOptionsV4(), index);
+}
+
+/*!
+ Returns the height size hint for the specified \a row or -1 if
+ there is no model.
+
+ The returned height is calculated using the size hints of the
+ given \a row's items, i.e. the returned value is the maximum
+ height among the items. Note that to control the height of a row,
+ you must reimplement the QAbstractItemDelegate::sizeHint()
+ function.
+
+ This function is used in views with a vertical header to find the
+ size hint for a header section based on the contents of the given
+ \a row.
+
+ \sa sizeHintForColumn()
+*/
+int QAbstractItemView::sizeHintForRow(int row) const
+{
+ Q_D(const QAbstractItemView);
+
+ if (row < 0 || row >= d->model->rowCount(d->root))
+ return -1;
+
+ ensurePolished();
+
+ QStyleOptionViewItemV4 option = d->viewOptionsV4();
+ int height = 0;
+ int colCount = d->model->columnCount(d->root);
+ QModelIndex index;
+ for (int c = 0; c < colCount; ++c) {
+ index = d->model->index(row, c, d->root);
+ if (QWidget *editor = d->editorForIndex(index).widget.data())
+ height = qMax(height, editor->height());
+ int hint = d->delegateForIndex(index)->sizeHint(option, index).height();
+ height = qMax(height, hint);
+ }
+ return height;
+}
+
+/*!
+ Returns the width size hint for the specified \a column or -1 if there is no model.
+
+ This function is used in views with a horizontal header to find the size hint for
+ a header section based on the contents of the given \a column.
+
+ \sa sizeHintForRow()
+*/
+int QAbstractItemView::sizeHintForColumn(int column) const
+{
+ Q_D(const QAbstractItemView);
+
+ if (column < 0 || column >= d->model->columnCount(d->root))
+ return -1;
+
+ ensurePolished();
+
+ QStyleOptionViewItemV4 option = d->viewOptionsV4();
+ int width = 0;
+ int rows = d->model->rowCount(d->root);
+ QModelIndex index;
+ for (int r = 0; r < rows; ++r) {
+ index = d->model->index(r, column, d->root);
+ if (QWidget *editor = d->editorForIndex(index).widget.data())
+ width = qMax(width, editor->sizeHint().width());
+ int hint = d->delegateForIndex(index)->sizeHint(option, index).width();
+ width = qMax(width, hint);
+ }
+ return width;
+}
+
+/*!
+ Opens a persistent editor on the item at the given \a index.
+ If no editor exists, the delegate will create a new editor.
+
+ \sa closePersistentEditor()
+*/
+void QAbstractItemView::openPersistentEditor(const QModelIndex &index)
+{
+ Q_D(QAbstractItemView);
+ QStyleOptionViewItemV4 options = d->viewOptionsV4();
+ options.rect = visualRect(index);
+ options.state |= (index == currentIndex() ? QStyle::State_HasFocus : QStyle::State_None);
+
+ QWidget *editor = d->editor(index, options);
+ if (editor) {
+ editor->show();
+ d->persistent.insert(editor);
+ }
+}
+
+/*!
+ Closes the persistent editor for the item at the given \a index.
+
+ \sa openPersistentEditor()
+*/
+void QAbstractItemView::closePersistentEditor(const QModelIndex &index)
+{
+ Q_D(QAbstractItemView);
+ if (QWidget *editor = d->editorForIndex(index).widget.data()) {
+ if (index == selectionModel()->currentIndex())
+ closeEditor(editor, QAbstractItemDelegate::RevertModelCache);
+ d->persistent.remove(editor);
+ d->removeEditor(editor);
+ d->releaseEditor(editor);
+ }
+}
+
+/*!
+ \since 4.1
+
+ Sets the given \a widget on the item at the given \a index, passing the
+ ownership of the widget to the viewport.
+
+ If \a index is invalid (e.g., if you pass the root index), this function
+ will do nothing.
+
+ 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 item at the given \a index.
+
+ If index widget A is replaced with index widget B, index widget A will be
+ deleted. For example, in the code snippet below, the QLineEdit object will
+ be deleted.
+
+ \snippet doc/src/snippets/code/src_gui_itemviews_qabstractitemview.cpp 1
+
+ This function should only be used to display static content within the
+ visible area corresponding to an item of data. If you want to display
+ custom dynamic content or implement a custom editor widget, subclass
+ QItemDelegate instead.
+
+ \sa {Delegate Classes}
+*/
+void QAbstractItemView::setIndexWidget(const QModelIndex &index, QWidget *widget)
+{
+ Q_D(QAbstractItemView);
+ if (!d->isIndexValid(index))
+ return;
+ if (QWidget *oldWidget = indexWidget(index)) {
+ d->persistent.remove(oldWidget);
+ d->removeEditor(oldWidget);
+ oldWidget->deleteLater();
+ }
+ if (widget) {
+ widget->setParent(viewport());
+ d->persistent.insert(widget);
+ d->addEditor(index, widget, true);
+ widget->show();
+ dataChanged(index, index); // update the geometry
+ if (!d->delayedPendingLayout)
+ widget->setGeometry(visualRect(index));
+ }
+}
+
+/*!
+ \since 4.1
+
+ Returns the widget for the item at the given \a index.
+*/
+QWidget* QAbstractItemView::indexWidget(const QModelIndex &index) const
+{
+ Q_D(const QAbstractItemView);
+ if (d->isIndexValid(index))
+ if (QWidget *editor = d->editorForIndex(index).widget.data())
+ return editor;
+
+ return 0;
+}
+
+/*!
+ \since 4.1
+
+ Scrolls the view to the top.
+
+ \sa scrollTo(), scrollToBottom()
+*/
+void QAbstractItemView::scrollToTop()
+{
+ verticalScrollBar()->setValue(verticalScrollBar()->minimum());
+}
+
+/*!
+ \since 4.1
+
+ Scrolls the view to the bottom.
+
+ \sa scrollTo(), scrollToTop()
+*/
+void QAbstractItemView::scrollToBottom()
+{
+ Q_D(QAbstractItemView);
+ if (d->delayedPendingLayout) {
+ d->executePostedLayout();
+ updateGeometries();
+ }
+ verticalScrollBar()->setValue(verticalScrollBar()->maximum());
+}
+
+/*!
+ \since 4.3
+
+ Updates the area occupied by the given \a index.
+
+*/
+void QAbstractItemView::update(const QModelIndex &index)
+{
+ Q_D(QAbstractItemView);
+ if (index.isValid()) {
+ const QRect rect = visualRect(index);
+ //this test is important for peformance reason
+ //For example in dataChanged we simply update all the cells without checking
+ //it can be a major bottleneck to update rects that aren't even part of the viewport
+ if (d->viewport->rect().intersects(rect))
+ d->viewport->update(rect);
+ }
+}
+
+/*!
+ This slot is called when items are changed in the model. The
+ changed items are those from \a topLeft to \a bottomRight
+ inclusive. If just one item is changed \a topLeft == \a
+ bottomRight.
+*/
+void QAbstractItemView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
+{
+ // Single item changed
+ Q_D(QAbstractItemView);
+ if (topLeft == bottomRight && topLeft.isValid()) {
+ const QEditorInfo &editorInfo = d->editorForIndex(topLeft);
+ //we don't update the edit data if it is static
+ if (!editorInfo.isStatic && editorInfo.widget) {
+ QAbstractItemDelegate *delegate = d->delegateForIndex(topLeft);
+ if (delegate) {
+ delegate->setEditorData(editorInfo.widget.data(), topLeft);
+ }
+ }
+ if (isVisible() && !d->delayedPendingLayout) {
+ // otherwise the items will be update later anyway
+ update(topLeft);
+ }
+ return;
+ }
+ d->updateEditorData(topLeft, bottomRight);
+ if (!isVisible() || d->delayedPendingLayout)
+ return; // no need to update
+ d->viewport->update();
+}
+
+/*!
+ This slot is called when rows are inserted. The new rows are those
+ under the given \a parent from \a start to \a end inclusive. The
+ base class implementation calls fetchMore() on the model to check
+ for more data.
+
+ \sa rowsAboutToBeRemoved()
+*/
+void QAbstractItemView::rowsInserted(const QModelIndex &, int, int)
+{
+ if (!isVisible())
+ d_func()->fetchMoreTimer.start(0, this); //fetch more later
+ else
+ updateEditorGeometries();
+}
+
+/*!
+ This slot is called when rows are about to be removed. The deleted rows are
+ those under the given \a parent from \a start to \a end inclusive.
+
+ \sa rowsInserted()
+*/
+void QAbstractItemView::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
+{
+ Q_D(QAbstractItemView);
+
+ setState(CollapsingState);
+
+ // Ensure one selected item in single selection mode.
+ QModelIndex current = currentIndex();
+ if (d->selectionMode == SingleSelection
+ && current.isValid()
+ && current.row() >= start
+ && current.row() <= end
+ && current.parent() == parent) {
+ int totalToRemove = end - start + 1;
+ if (d->model->rowCount(parent) <= totalToRemove) { // no more children
+ QModelIndex index = parent;
+ while (index != d->root && !d->isIndexEnabled(index))
+ index = index.parent();
+ if (index != d->root)
+ setCurrentIndex(index);
+ } else {
+ int row = end + 1;
+ QModelIndex next;
+ do { // find the next visible and enabled item
+ next = d->model->index(row++, current.column(), current.parent());
+ } while (next.isValid() && (isIndexHidden(next) || !d->isIndexEnabled(next)));
+ if (row > d->model->rowCount(parent)) {
+ row = start - 1;
+ do { // find the previous visible and enabled item
+ next = d->model->index(row--, current.column(), current.parent());
+ } while (next.isValid() && (isIndexHidden(next) || !d->isIndexEnabled(next)));
+ }
+ setCurrentIndex(next);
+ }
+ }
+
+ // Remove all affected editors; this is more efficient than waiting for updateGeometries() to clean out editors for invalid indexes
+ QEditorIndexHash::iterator i = d->editorIndexHash.begin();
+ while (i != d->editorIndexHash.end()) {
+ const QModelIndex index = i.value();
+ if (index.row() >= start && index.row() <= end && d->model->parent(index) == parent) {
+ QWidget *editor = i.key();
+ QEditorInfo info = d->indexEditorHash.take(index);
+ i = d->editorIndexHash.erase(i);
+ if (info.widget)
+ d->releaseEditor(editor);
+ } else {
+ ++i;
+ }
+ }
+}
+
+/*!
+ \internal
+
+ This slot is called when rows have been removed. The deleted
+ rows are those under the given \a parent from \a start to \a end
+ inclusive.
+*/
+void QAbstractItemViewPrivate::_q_rowsRemoved(const QModelIndex &index, int start, int end)
+{
+ Q_UNUSED(index)
+ Q_UNUSED(start)
+ Q_UNUSED(end)
+
+ Q_Q(QAbstractItemView);
+ if (q->isVisible())
+ q->updateEditorGeometries();
+ q->setState(QAbstractItemView::NoState);
+#ifndef QT_NO_ACCESSIBILITY
+#ifdef Q_WS_X11
+ if (QAccessible::isActive()) {
+ QAccessible::queryAccessibleInterface(q)->table2Interface()->rowsRemoved(index, start, end);
+ QAccessible::updateAccessibility(q, 0, QAccessible::TableModelChanged);
+ }
+#endif
+#endif
+}
+
+/*!
+ \internal
+
+ This slot is called when columns are about to be removed. The deleted
+ columns are those under the given \a parent from \a start to \a end
+ inclusive.
+*/
+void QAbstractItemViewPrivate::_q_columnsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
+{
+ Q_Q(QAbstractItemView);
+
+ q->setState(QAbstractItemView::CollapsingState);
+
+ // Ensure one selected item in single selection mode.
+ QModelIndex current = q->currentIndex();
+ if (current.isValid()
+ && selectionMode == QAbstractItemView::SingleSelection
+ && current.column() >= start
+ && current.column() <= end) {
+ int totalToRemove = end - start + 1;
+ if (model->columnCount(parent) < totalToRemove) { // no more columns
+ QModelIndex index = parent;
+ while (index.isValid() && !isIndexEnabled(index))
+ index = index.parent();
+ if (index.isValid())
+ q->setCurrentIndex(index);
+ } else {
+ int column = end;
+ QModelIndex next;
+ do { // find the next visible and enabled item
+ next = model->index(current.row(), column++, current.parent());
+ } while (next.isValid() && (q->isIndexHidden(next) || !isIndexEnabled(next)));
+ q->setCurrentIndex(next);
+ }
+ }
+
+ // Remove all affected editors; this is more efficient than waiting for updateGeometries() to clean out editors for invalid indexes
+ QEditorIndexHash::iterator it = editorIndexHash.begin();
+ while (it != editorIndexHash.end()) {
+ QModelIndex index = it.value();
+ if (index.column() <= start && index.column() >= end && model->parent(index) == parent) {
+ QWidget *editor = it.key();
+ QEditorInfo info = indexEditorHash.take(it.value());
+ it = editorIndexHash.erase(it);
+ if (info.widget)
+ releaseEditor(editor);
+ } else {
+ ++it;
+ }
+ }
+
+}
+
+/*!
+ \internal
+
+ This slot is called when columns have been removed. The deleted
+ rows are those under the given \a parent from \a start to \a end
+ inclusive.
+*/
+void QAbstractItemViewPrivate::_q_columnsRemoved(const QModelIndex &index, int start, int end)
+{
+ Q_UNUSED(index)
+ Q_UNUSED(start)
+ Q_UNUSED(end)
+
+ Q_Q(QAbstractItemView);
+ if (q->isVisible())
+ q->updateEditorGeometries();
+ q->setState(QAbstractItemView::NoState);
+#ifndef QT_NO_ACCESSIBILITY
+#ifdef Q_WS_X11
+ if (QAccessible::isActive()) {
+ QAccessible::queryAccessibleInterface(q)->table2Interface()->columnsRemoved(index, start, end);
+ QAccessible::updateAccessibility(q, 0, QAccessible::TableModelChanged);
+ }
+#endif
+#endif
+}
+
+
+/*!
+ \internal
+
+ This slot is called when rows have been inserted.
+*/
+void QAbstractItemViewPrivate::_q_rowsInserted(const QModelIndex &index, int start, int end)
+{
+ Q_UNUSED(index)
+ Q_UNUSED(start)
+ Q_UNUSED(end)
+
+ Q_Q(QAbstractItemView);
+#ifndef QT_NO_ACCESSIBILITY
+#ifdef Q_WS_X11
+ if (QAccessible::isActive()) {
+ QAccessible::queryAccessibleInterface(q)->table2Interface()->rowsInserted(index, start, end);
+ QAccessible::updateAccessibility(q, 0, QAccessible::TableModelChanged);
+ }
+#endif
+#endif
+}
+
+/*!
+ \internal
+
+ This slot is called when columns have been inserted.
+*/
+void QAbstractItemViewPrivate::_q_columnsInserted(const QModelIndex &index, int start, int end)
+{
+ Q_UNUSED(index)
+ Q_UNUSED(start)
+ Q_UNUSED(end)
+
+ Q_Q(QAbstractItemView);
+ if (q->isVisible())
+ q->updateEditorGeometries();
+#ifndef QT_NO_ACCESSIBILITY
+#ifdef Q_WS_X11
+ if (QAccessible::isActive()) {
+ QAccessible::queryAccessibleInterface(q)->table2Interface()->columnsInserted(index, start, end);
+ QAccessible::updateAccessibility(q, 0, QAccessible::TableModelChanged);
+ }
+#endif
+#endif
+}
+
+/*!
+ \internal
+*/
+void QAbstractItemViewPrivate::_q_modelDestroyed()
+{
+ model = QAbstractItemModelPrivate::staticEmptyModel();
+ doDelayedReset();
+}
+
+/*!
+ \internal
+
+ This slot is called when the layout is changed.
+*/
+void QAbstractItemViewPrivate::_q_layoutChanged()
+{
+ Q_Q(QAbstractItemView);
+ doDelayedItemsLayout();
+#ifndef QT_NO_ACCESSIBILITY
+#ifdef Q_WS_X11
+ if (QAccessible::isActive()) {
+ QAccessible::queryAccessibleInterface(q)->table2Interface()->modelReset();
+ QAccessible::updateAccessibility(q, 0, QAccessible::TableModelChanged);
+ }
+#endif
+#endif
+}
+
+/*!
+ This slot is called when the selection is changed. The previous
+ selection (which may be empty), is specified by \a deselected, and the
+ new selection by \a selected.
+
+ \sa setSelection()
+*/
+void QAbstractItemView::selectionChanged(const QItemSelection &selected,
+ const QItemSelection &deselected)
+{
+ Q_D(QAbstractItemView);
+ if (isVisible() && updatesEnabled()) {
+ d->viewport->update(visualRegionForSelection(deselected) | visualRegionForSelection(selected));
+ }
+}
+
+/*!
+ This slot is called when a new item becomes the current item.
+ The previous current item is specified by the \a previous index, and the new
+ item by the \a current index.
+
+ If you want to know about changes to items see the
+ dataChanged() signal.
+*/
+void QAbstractItemView::currentChanged(const QModelIndex &current, const QModelIndex &previous)
+{
+ Q_D(QAbstractItemView);
+ Q_ASSERT(d->model);
+
+ if (previous.isValid()) {
+ QModelIndex buddy = d->model->buddy(previous);
+ QWidget *editor = d->editorForIndex(buddy).widget.data();
+ if (editor && !d->persistent.contains(editor)) {
+ commitData(editor);
+ if (current.row() != previous.row())
+ closeEditor(editor, QAbstractItemDelegate::SubmitModelCache);
+ else
+ closeEditor(editor, QAbstractItemDelegate::NoHint);
+ }
+ if (isVisible()) {
+ update(previous);
+ }
+ }
+
+ if (current.isValid() && !d->autoScrollTimer.isActive()) {
+ if (isVisible()) {
+ if (d->autoScroll)
+ scrollTo(current);
+ update(current);
+ edit(current, CurrentChanged, 0);
+ if (current.row() == (d->model->rowCount(d->root) - 1))
+ d->fetchMore();
+ } else {
+ d->shouldScrollToCurrentOnShow = d->autoScroll;
+ }
+ }
+}
+
+#ifndef QT_NO_DRAGANDDROP
+/*!
+ Starts a drag by calling drag->exec() using the given \a supportedActions.
+*/
+void QAbstractItemView::startDrag(Qt::DropActions supportedActions)
+{
+ Q_D(QAbstractItemView);
+ QModelIndexList indexes = d->selectedDraggableIndexes();
+ if (indexes.count() > 0) {
+ QMimeData *data = d->model->mimeData(indexes);
+ if (!data)
+ return;
+ QRect rect;
+ QPixmap pixmap = d->renderToPixmap(indexes, &rect);
+ rect.adjust(horizontalOffset(), verticalOffset(), 0, 0);
+ QDrag *drag = new QDrag(this);
+ drag->setPixmap(pixmap);
+ drag->setMimeData(data);
+ drag->setHotSpot(d->pressedPosition - rect.topLeft());
+ Qt::DropAction defaultDropAction = Qt::IgnoreAction;
+ if (d->defaultDropAction != Qt::IgnoreAction && (supportedActions & d->defaultDropAction))
+ defaultDropAction = d->defaultDropAction;
+ else if (supportedActions & Qt::CopyAction && dragDropMode() != QAbstractItemView::InternalMove)
+ defaultDropAction = Qt::CopyAction;
+ if (drag->exec(supportedActions, defaultDropAction) == Qt::MoveAction)
+ d->clearOrRemove();
+ }
+}
+#endif // QT_NO_DRAGANDDROP
+
+/*!
+ Returns a QStyleOptionViewItem structure populated with the view's
+ palette, font, state, alignments etc.
+*/
+QStyleOptionViewItem QAbstractItemView::viewOptions() const
+{
+ Q_D(const QAbstractItemView);
+ QStyleOptionViewItem option;
+ option.init(this);
+ option.state &= ~QStyle::State_MouseOver;
+ option.font = font();
+
+#ifndef Q_WS_MAC
+ // On mac the focus appearance follows window activation
+ // not widget activation
+ if (!hasFocus())
+ option.state &= ~QStyle::State_Active;
+#endif
+
+ option.state &= ~QStyle::State_HasFocus;
+ if (d->iconSize.isValid()) {
+ option.decorationSize = d->iconSize;
+ } else {
+ int pm = style()->pixelMetric(QStyle::PM_SmallIconSize, 0, this);
+ option.decorationSize = QSize(pm, pm);
+ }
+ option.decorationPosition = QStyleOptionViewItem::Left;
+ option.decorationAlignment = Qt::AlignCenter;
+ option.displayAlignment = Qt::AlignLeft|Qt::AlignVCenter;
+ option.textElideMode = d->textElideMode;
+ option.rect = QRect();
+ option.showDecorationSelected = style()->styleHint(QStyle::SH_ItemView_ShowDecorationSelected, 0, this);
+ return option;
+}
+
+QStyleOptionViewItemV4 QAbstractItemViewPrivate::viewOptionsV4() const
+{
+ Q_Q(const QAbstractItemView);
+ QStyleOptionViewItemV4 option = q->viewOptions();
+ if (wrapItemText)
+ option.features = QStyleOptionViewItemV2::WrapText;
+ option.locale = q->locale();
+ option.locale.setNumberOptions(QLocale::OmitGroupSeparator);
+ option.widget = q;
+ return option;
+}
+
+/*!
+ Returns the item view's state.
+
+ \sa setState()
+*/
+QAbstractItemView::State QAbstractItemView::state() const
+{
+ Q_D(const QAbstractItemView);
+ return d->state;
+}
+
+/*!
+ Sets the item view's state to the given \a state.
+
+ \sa state()
+*/
+void QAbstractItemView::setState(State state)
+{
+ Q_D(QAbstractItemView);
+ d->state = state;
+}
+
+/*!
+ Schedules a layout of the items in the view to be executed when the
+ event processing starts.
+
+ Even if scheduleDelayedItemsLayout() is called multiple times before
+ events are processed, the view will only do the layout once.
+
+ \sa executeDelayedItemsLayout()
+*/
+void QAbstractItemView::scheduleDelayedItemsLayout()
+{
+ Q_D(QAbstractItemView);
+ d->doDelayedItemsLayout();
+}
+
+/*!
+ Executes the scheduled layouts without waiting for the event processing
+ to begin.
+
+ \sa scheduleDelayedItemsLayout()
+*/
+void QAbstractItemView::executeDelayedItemsLayout()
+{
+ Q_D(QAbstractItemView);
+ d->executePostedLayout();
+}
+
+/*!
+ \since 4.1
+
+ Marks the given \a region as dirty and schedules it to be updated.
+ You only need to call this function if you are implementing
+ your own view subclass.
+
+ \sa scrollDirtyRegion(), dirtyRegionOffset()
+*/
+
+void QAbstractItemView::setDirtyRegion(const QRegion &region)
+{
+ Q_D(QAbstractItemView);
+ d->setDirtyRegion(region);
+}
+
+/*!
+ Prepares the view for scrolling by (\a{dx},\a{dy}) pixels by moving the dirty regions in the
+ opposite direction. You only need to call this function if you are implementing a scrolling
+ viewport in your view subclass.
+
+ If you implement scrollContentsBy() in a subclass of QAbstractItemView, call this function
+ before you call QWidget::scroll() on the viewport. Alternatively, just call update().
+
+ \sa scrollContentsBy(), dirtyRegionOffset(), setDirtyRegion()
+*/
+void QAbstractItemView::scrollDirtyRegion(int dx, int dy)
+{
+ Q_D(QAbstractItemView);
+ d->scrollDirtyRegion(dx, dy);
+}
+
+/*!
+ Returns the offset of the dirty regions in the view.
+
+ If you use scrollDirtyRegion() and implement a paintEvent() in a subclass of
+ QAbstractItemView, you should translate the area given by the paint event with
+ the offset returned from this function.
+
+ \sa scrollDirtyRegion(), setDirtyRegion()
+*/
+QPoint QAbstractItemView::dirtyRegionOffset() const
+{
+ Q_D(const QAbstractItemView);
+ return d->scrollDelayOffset;
+}
+
+/*!
+ \internal
+*/
+void QAbstractItemView::startAutoScroll()
+{
+ d_func()->startAutoScroll();
+}
+
+/*!
+ \internal
+*/
+void QAbstractItemView::stopAutoScroll()
+{
+ d_func()->stopAutoScroll();
+}
+
+/*!
+ \internal
+*/
+void QAbstractItemView::doAutoScroll()
+{
+ // find how much we should scroll with
+ Q_D(QAbstractItemView);
+ int verticalStep = verticalScrollBar()->pageStep();
+ int horizontalStep = horizontalScrollBar()->pageStep();
+ if (d->autoScrollCount < qMax(verticalStep, horizontalStep))
+ ++d->autoScrollCount;
+
+ int margin = d->autoScrollMargin;
+ int verticalValue = verticalScrollBar()->value();
+ int horizontalValue = horizontalScrollBar()->value();
+
+ QPoint pos = d->viewport->mapFromGlobal(QCursor::pos());
+ QRect area = static_cast<QAbstractItemView*>(d->viewport)->d_func()->clipRect(); // access QWidget private by bending C++ rules
+
+ // do the scrolling if we are in the scroll margins
+ if (pos.y() - area.top() < margin)
+ verticalScrollBar()->setValue(verticalValue - d->autoScrollCount);
+ else if (area.bottom() - pos.y() < margin)
+ verticalScrollBar()->setValue(verticalValue + d->autoScrollCount);
+ if (pos.x() - area.left() < margin)
+ horizontalScrollBar()->setValue(horizontalValue - d->autoScrollCount);
+ else if (area.right() - pos.x() < margin)
+ horizontalScrollBar()->setValue(horizontalValue + d->autoScrollCount);
+ // if nothing changed, stop scrolling
+ bool verticalUnchanged = (verticalValue == verticalScrollBar()->value());
+ bool horizontalUnchanged = (horizontalValue == horizontalScrollBar()->value());
+ if (verticalUnchanged && horizontalUnchanged) {
+ stopAutoScroll();
+ } else {
+#ifndef QT_NO_DRAGANDDROP
+ d->dropIndicatorRect = QRect();
+ d->dropIndicatorPosition = QAbstractItemView::OnViewport;
+#endif
+ d->viewport->update();
+ }
+}
+
+/*!
+ Returns the SelectionFlags to be used when updating a selection with
+ to include the \a index specified. The \a event is a user input event,
+ such as a mouse or keyboard event.
+
+ Reimplement this function to define your own selection behavior.
+
+ \sa setSelection()
+*/
+QItemSelectionModel::SelectionFlags QAbstractItemView::selectionCommand(const QModelIndex &index,
+ const QEvent *event) const
+{
+ Q_D(const QAbstractItemView);
+ switch (d->selectionMode) {
+ case NoSelection: // Never update selection model
+ return QItemSelectionModel::NoUpdate;
+ case SingleSelection: // ClearAndSelect on valid index otherwise NoUpdate
+ if (event && event->type() == QEvent::MouseButtonRelease)
+ return QItemSelectionModel::NoUpdate;
+ return QItemSelectionModel::ClearAndSelect|d->selectionBehaviorFlags();
+ case MultiSelection:
+ return d->multiSelectionCommand(index, event);
+ case ExtendedSelection:
+ return d->extendedSelectionCommand(index, event);
+ case ContiguousSelection:
+ return d->contiguousSelectionCommand(index, event);
+ }
+ return QItemSelectionModel::NoUpdate;
+}
+
+QItemSelectionModel::SelectionFlags QAbstractItemViewPrivate::multiSelectionCommand(
+ const QModelIndex &index, const QEvent *event) const
+{
+ Q_UNUSED(index)
+
+ if (event) {
+ switch (event->type()) {
+ case QEvent::KeyPress:
+ if (static_cast<const QKeyEvent*>(event)->key() == Qt::Key_Space
+ || static_cast<const QKeyEvent*>(event)->key() == Qt::Key_Select)
+ return QItemSelectionModel::Toggle|selectionBehaviorFlags();
+ break;
+ case QEvent::MouseButtonPress:
+ if (static_cast<const QMouseEvent*>(event)->button() == Qt::LeftButton)
+ return QItemSelectionModel::Toggle|selectionBehaviorFlags(); // toggle
+ break;
+ case QEvent::MouseButtonRelease:
+ if (static_cast<const QMouseEvent*>(event)->button() == Qt::LeftButton)
+ return QItemSelectionModel::NoUpdate|selectionBehaviorFlags(); // finalize
+ break;
+ case QEvent::MouseMove:
+ if (static_cast<const QMouseEvent*>(event)->buttons() & Qt::LeftButton)
+ return QItemSelectionModel::ToggleCurrent|selectionBehaviorFlags(); // toggle drag select
+ default:
+ break;
+ }
+ return QItemSelectionModel::NoUpdate;
+ }
+
+ return QItemSelectionModel::Toggle|selectionBehaviorFlags();
+}
+
+QItemSelectionModel::SelectionFlags QAbstractItemViewPrivate::extendedSelectionCommand(
+ const QModelIndex &index, const QEvent *event) const
+{
+ Qt::KeyboardModifiers modifiers = QApplication::keyboardModifiers();
+ if (event) {
+ switch (event->type()) {
+ case QEvent::MouseMove: {
+ // Toggle on MouseMove
+ modifiers = static_cast<const QMouseEvent*>(event)->modifiers();
+ if (modifiers & Qt::ControlModifier)
+ return QItemSelectionModel::ToggleCurrent|selectionBehaviorFlags();
+ break;
+ }
+ case QEvent::MouseButtonPress: {
+ modifiers = static_cast<const QMouseEvent*>(event)->modifiers();
+ const Qt::MouseButton button = static_cast<const QMouseEvent*>(event)->button();
+ const bool rightButtonPressed = button & Qt::RightButton;
+ const bool shiftKeyPressed = modifiers & Qt::ShiftModifier;
+ const bool controlKeyPressed = modifiers & Qt::ControlModifier;
+ const bool indexIsSelected = selectionModel->isSelected(index);
+ if ((shiftKeyPressed || controlKeyPressed) && rightButtonPressed)
+ return QItemSelectionModel::NoUpdate;
+ if (!shiftKeyPressed && !controlKeyPressed && indexIsSelected)
+ return QItemSelectionModel::NoUpdate;
+ if (!index.isValid() && !rightButtonPressed && !shiftKeyPressed && !controlKeyPressed)
+ return QItemSelectionModel::Clear;
+ if (!index.isValid())
+ return QItemSelectionModel::NoUpdate;
+ break;
+ }
+ case QEvent::MouseButtonRelease: {
+ // ClearAndSelect on MouseButtonRelease if MouseButtonPress on selected item or empty area
+ modifiers = static_cast<const QMouseEvent*>(event)->modifiers();
+ const Qt::MouseButton button = static_cast<const QMouseEvent*>(event)->button();
+ const bool rightButtonPressed = button & Qt::RightButton;
+ const bool shiftKeyPressed = modifiers & Qt::ShiftModifier;
+ const bool controlKeyPressed = modifiers & Qt::ControlModifier;
+ if (((index == pressedIndex && selectionModel->isSelected(index))
+ || !index.isValid()) && state != QAbstractItemView::DragSelectingState
+ && !shiftKeyPressed && !controlKeyPressed && (!rightButtonPressed || !index.isValid()))
+ return QItemSelectionModel::ClearAndSelect|selectionBehaviorFlags();
+ return QItemSelectionModel::NoUpdate;
+ }
+ case QEvent::KeyPress: {
+ // NoUpdate on Key movement and Ctrl
+ modifiers = static_cast<const QKeyEvent*>(event)->modifiers();
+ switch (static_cast<const QKeyEvent*>(event)->key()) {
+ case Qt::Key_Backtab:
+ modifiers = modifiers & ~Qt::ShiftModifier; // special case for backtab
+ case Qt::Key_Down:
+ case Qt::Key_Up:
+ case Qt::Key_Left:
+ case Qt::Key_Right:
+ case Qt::Key_Home:
+ case Qt::Key_End:
+ case Qt::Key_PageUp:
+ case Qt::Key_PageDown:
+ case Qt::Key_Tab:
+ if (modifiers & Qt::ControlModifier
+#ifdef QT_KEYPAD_NAVIGATION
+ // Preserve historical tab order navigation behavior
+ || QApplication::navigationMode() == Qt::NavigationModeKeypadTabOrder
+#endif
+ )
+ return QItemSelectionModel::NoUpdate;
+ break;
+ case Qt::Key_Select:
+ return QItemSelectionModel::Toggle|selectionBehaviorFlags();
+ case Qt::Key_Space:// Toggle on Ctrl-Qt::Key_Space, Select on Space
+ if (modifiers & Qt::ControlModifier)
+ return QItemSelectionModel::Toggle|selectionBehaviorFlags();
+ return QItemSelectionModel::Select|selectionBehaviorFlags();
+ default:
+ break;
+ }
+ }
+ default:
+ break;
+ }
+ }
+
+ if (modifiers & Qt::ShiftModifier)
+ return QItemSelectionModel::SelectCurrent|selectionBehaviorFlags();
+ if (modifiers & Qt::ControlModifier)
+ return QItemSelectionModel::Toggle|selectionBehaviorFlags();
+ if (state == QAbstractItemView::DragSelectingState) {
+ //when drag-selecting we need to clear any previous selection and select the current one
+ return QItemSelectionModel::Clear|QItemSelectionModel::SelectCurrent|selectionBehaviorFlags();
+ }
+
+ return QItemSelectionModel::ClearAndSelect|selectionBehaviorFlags();
+}
+
+QItemSelectionModel::SelectionFlags
+QAbstractItemViewPrivate::contiguousSelectionCommand(const QModelIndex &index,
+ const QEvent *event) const
+{
+ QItemSelectionModel::SelectionFlags flags = extendedSelectionCommand(index, event);
+ const int Mask = QItemSelectionModel::Clear | QItemSelectionModel::Select
+ | QItemSelectionModel::Deselect | QItemSelectionModel::Toggle
+ | QItemSelectionModel::Current;
+
+ switch (flags & Mask) {
+ case QItemSelectionModel::Clear:
+ case QItemSelectionModel::ClearAndSelect:
+ case QItemSelectionModel::SelectCurrent:
+ return flags;
+ case QItemSelectionModel::NoUpdate:
+ if (event &&
+ (event->type() == QEvent::MouseButtonPress
+ || event->type() == QEvent::MouseButtonRelease))
+ return flags;
+ return QItemSelectionModel::ClearAndSelect|selectionBehaviorFlags();
+ default:
+ return QItemSelectionModel::SelectCurrent|selectionBehaviorFlags();
+ }
+}
+
+void QAbstractItemViewPrivate::fetchMore()
+{
+ fetchMoreTimer.stop();
+ if (!model->canFetchMore(root))
+ return;
+ int last = model->rowCount(root) - 1;
+ if (last < 0) {
+ model->fetchMore(root);
+ return;
+ }
+
+ QModelIndex index = model->index(last, 0, root);
+ QRect rect = q_func()->visualRect(index);
+ if (viewport->rect().intersects(rect))
+ model->fetchMore(root);
+}
+
+bool QAbstractItemViewPrivate::shouldEdit(QAbstractItemView::EditTrigger trigger,
+ const QModelIndex &index) const
+{
+ if (!index.isValid())
+ return false;
+ Qt::ItemFlags flags = model->flags(index);
+ if (((flags & Qt::ItemIsEditable) == 0) || ((flags & Qt::ItemIsEnabled) == 0))
+ return false;
+ if (state == QAbstractItemView::EditingState)
+ return false;
+ if (hasEditor(index))
+ return false;
+ if (trigger == QAbstractItemView::AllEditTriggers) // force editing
+ return true;
+ if ((trigger & editTriggers) == QAbstractItemView::SelectedClicked
+ && !selectionModel->isSelected(index))
+ return false;
+ return (trigger & editTriggers);
+}
+
+bool QAbstractItemViewPrivate::shouldForwardEvent(QAbstractItemView::EditTrigger trigger,
+ const QEvent *event) const
+{
+ if (!event || (trigger & editTriggers) != QAbstractItemView::AnyKeyPressed)
+ return false;
+
+ switch (event->type()) {
+ case QEvent::KeyPress:
+ case QEvent::MouseButtonDblClick:
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseMove:
+ return true;
+ default:
+ break;
+ };
+
+ return false;
+}
+
+bool QAbstractItemViewPrivate::shouldAutoScroll(const QPoint &pos) const
+{
+ if (!autoScroll)
+ return false;
+ QRect area = static_cast<QAbstractItemView*>(viewport)->d_func()->clipRect(); // access QWidget private by bending C++ rules
+ return (pos.y() - area.top() < autoScrollMargin)
+ || (area.bottom() - pos.y() < autoScrollMargin)
+ || (pos.x() - area.left() < autoScrollMargin)
+ || (area.right() - pos.x() < autoScrollMargin);
+}
+
+void QAbstractItemViewPrivate::doDelayedItemsLayout(int delay)
+{
+ if (!delayedPendingLayout) {
+ delayedPendingLayout = true;
+ delayedLayout.start(delay, q_func());
+ }
+}
+
+void QAbstractItemViewPrivate::interruptDelayedItemsLayout() const
+{
+ delayedLayout.stop();
+ delayedPendingLayout = false;
+}
+
+
+
+QWidget *QAbstractItemViewPrivate::editor(const QModelIndex &index,
+ const QStyleOptionViewItem &options)
+{
+ Q_Q(QAbstractItemView);
+ QWidget *w = editorForIndex(index).widget.data();
+ if (!w) {
+ QAbstractItemDelegate *delegate = delegateForIndex(index);
+ if (!delegate)
+ return 0;
+ w = delegate->createEditor(viewport, options, index);
+ if (w) {
+ w->installEventFilter(delegate);
+ QObject::connect(w, SIGNAL(destroyed(QObject*)), q, SLOT(editorDestroyed(QObject*)));
+ delegate->updateEditorGeometry(w, options, index);
+ delegate->setEditorData(w, index);
+ addEditor(index, w, false);
+ if (w->parent() == viewport)
+ QWidget::setTabOrder(q, w);
+
+ // Special cases for some editors containing QLineEdit
+ QWidget *focusWidget = w;
+ while (QWidget *fp = focusWidget->focusProxy())
+ focusWidget = fp;
+#ifndef QT_NO_LINEEDIT
+ if (QLineEdit *le = qobject_cast<QLineEdit*>(focusWidget))
+ le->selectAll();
+#endif
+#ifndef QT_NO_SPINBOX
+ if (QSpinBox *sb = qobject_cast<QSpinBox*>(focusWidget))
+ sb->selectAll();
+ else if (QDoubleSpinBox *dsb = qobject_cast<QDoubleSpinBox*>(focusWidget))
+ dsb->selectAll();
+#endif
+ }
+ }
+
+ return w;
+}
+
+void QAbstractItemViewPrivate::updateEditorData(const QModelIndex &tl, const QModelIndex &br)
+{
+ // we are counting on having relatively few editors
+ const bool checkIndexes = tl.isValid() && br.isValid();
+ const QModelIndex parent = tl.parent();
+ QIndexEditorHash::const_iterator it = indexEditorHash.constBegin();
+ for (; it != indexEditorHash.constEnd(); ++it) {
+ QWidget *editor = it.value().widget.data();
+ const QModelIndex index = it.key();
+ if (it.value().isStatic || !editor || !index.isValid() ||
+ (checkIndexes
+ && (index.row() < tl.row() || index.row() > br.row()
+ || index.column() < tl.column() || index.column() > br.column()
+ || index.parent() != parent)))
+ continue;
+
+ QAbstractItemDelegate *delegate = delegateForIndex(index);
+ if (delegate) {
+ delegate->setEditorData(editor, index);
+ }
+ }
+}
+
+/*!
+ \internal
+
+ In DND if something has been moved then this is called.
+ Typically this means you should "remove" the selected item or row,
+ but the behavior is view dependant (table just clears the selected indexes for example).
+
+ Either remove the selected rows or clear them
+*/
+void QAbstractItemViewPrivate::clearOrRemove()
+{
+#ifndef QT_NO_DRAGANDDROP
+ const QItemSelection selection = selectionModel->selection();
+ QList<QItemSelectionRange>::const_iterator it = selection.constBegin();
+
+ if (!overwrite) {
+ for (; it != selection.constEnd(); ++it) {
+ QModelIndex parent = (*it).parent();
+ if ((*it).left() != 0)
+ continue;
+ if ((*it).right() != (model->columnCount(parent) - 1))
+ continue;
+ int count = (*it).bottom() - (*it).top() + 1;
+ model->removeRows((*it).top(), count, parent);
+ }
+ } else {
+ // we can't remove the rows so reset the items (i.e. the view is like a table)
+ QModelIndexList list = selection.indexes();
+ for (int i=0; i < list.size(); ++i) {
+ QModelIndex index = list.at(i);
+ QMap<int, QVariant> roles = model->itemData(index);
+ for (QMap<int, QVariant>::Iterator it = roles.begin(); it != roles.end(); ++it)
+ it.value() = QVariant();
+ model->setItemData(index, roles);
+ }
+ }
+#endif
+}
+
+/*!
+ \internal
+
+ When persistent aeditor gets/loses focus, we need to check
+ and setcorrectly the current index.
+*/
+void QAbstractItemViewPrivate::checkPersistentEditorFocus()
+{
+ Q_Q(QAbstractItemView);
+ if (QWidget *widget = QApplication::focusWidget()) {
+ if (persistent.contains(widget)) {
+ //a persistent editor has gained the focus
+ QModelIndex index = indexForEditor(widget);
+ if (selectionModel->currentIndex() != index)
+ q->setCurrentIndex(index);
+ }
+ }
+}
+
+
+const QEditorInfo & QAbstractItemViewPrivate::editorForIndex(const QModelIndex &index) const
+{
+ static QEditorInfo nullInfo;
+
+ QIndexEditorHash::const_iterator it = indexEditorHash.find(index);
+ if (it == indexEditorHash.end())
+ return nullInfo;
+
+ return it.value();
+}
+
+QModelIndex QAbstractItemViewPrivate::indexForEditor(QWidget *editor) const
+{
+ QEditorIndexHash::const_iterator it = editorIndexHash.find(editor);
+ if (it == editorIndexHash.end())
+ return QModelIndex();
+
+ return it.value();
+}
+
+void QAbstractItemViewPrivate::removeEditor(QWidget *editor)
+{
+ QEditorIndexHash::iterator it = editorIndexHash.find(editor);
+ if (it != editorIndexHash.end())
+ {
+ indexEditorHash.remove(it.value());
+ editorIndexHash.erase(it);
+ }
+}
+
+void QAbstractItemViewPrivate::addEditor(const QModelIndex &index, QWidget *editor, bool isStatic)
+{
+ editorIndexHash.insert(editor, index);
+ indexEditorHash.insert(index, QEditorInfo(editor, isStatic));
+}
+
+bool QAbstractItemViewPrivate::sendDelegateEvent(const QModelIndex &index, QEvent *event) const
+{
+ Q_Q(const QAbstractItemView);
+ QModelIndex buddy = model->buddy(index);
+ QStyleOptionViewItemV4 options = viewOptionsV4();
+ options.rect = q->visualRect(buddy);
+ options.state |= (buddy == q->currentIndex() ? QStyle::State_HasFocus : QStyle::State_None);
+ QAbstractItemDelegate *delegate = delegateForIndex(index);
+ return (event && delegate && delegate->editorEvent(event, model, options, buddy));
+}
+
+bool QAbstractItemViewPrivate::openEditor(const QModelIndex &index, QEvent *event)
+{
+ Q_Q(QAbstractItemView);
+
+ QModelIndex buddy = model->buddy(index);
+ QStyleOptionViewItemV4 options = viewOptionsV4();
+ options.rect = q->visualRect(buddy);
+ options.state |= (buddy == q->currentIndex() ? QStyle::State_HasFocus : QStyle::State_None);
+
+ QWidget *w = editor(buddy, options);
+ if (!w)
+ return false;
+
+ q->setState(QAbstractItemView::EditingState);
+ w->show();
+ w->setFocus();
+
+ if (event)
+ QApplication::sendEvent(w->focusProxy() ? w->focusProxy() : w, event);
+
+ return true;
+}
+
+/*
+ \internal
+
+ returns the pair QRect/QModelIndex that should be painted on the viewports's rect
+*/
+
+QItemViewPaintPairs QAbstractItemViewPrivate::draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const
+{
+ Q_ASSERT(r);
+ Q_Q(const QAbstractItemView);
+ QRect &rect = *r;
+ const QRect viewportRect = viewport->rect();
+ QItemViewPaintPairs ret;
+ for (int i = 0; i < indexes.count(); ++i) {
+ const QModelIndex &index = indexes.at(i);
+ const QRect current = q->visualRect(index);
+ if (current.intersects(viewportRect)) {
+ ret += qMakePair(current, index);
+ rect |= current;
+ }
+ }
+ rect &= viewportRect;
+ return ret;
+}
+
+QPixmap QAbstractItemViewPrivate::renderToPixmap(const QModelIndexList &indexes, QRect *r) const
+{
+ Q_ASSERT(r);
+ QItemViewPaintPairs paintPairs = draggablePaintPairs(indexes, r);
+ if (paintPairs.isEmpty())
+ return QPixmap();
+ QPixmap pixmap(r->size());
+ pixmap.fill(Qt::transparent);
+ QPainter painter(&pixmap);
+ QStyleOptionViewItemV4 option = viewOptionsV4();
+ option.state |= QStyle::State_Selected;
+ for (int j = 0; j < paintPairs.count(); ++j) {
+ option.rect = paintPairs.at(j).first.translated(-r->topLeft());
+ const QModelIndex &current = paintPairs.at(j).second;
+ delegateForIndex(current)->paint(&painter, option, current);
+ }
+ return pixmap;
+}
+
+void QAbstractItemViewPrivate::selectAll(QItemSelectionModel::SelectionFlags command)
+{
+ if (!selectionModel)
+ return;
+
+ QItemSelection selection;
+ QModelIndex tl = model->index(0, 0, root);
+ QModelIndex br = model->index(model->rowCount(root) - 1,
+ model->columnCount(root) - 1,
+ root);
+ selection.append(QItemSelectionRange(tl, br));
+ selectionModel->select(selection, command);
+}
+
+QModelIndexList QAbstractItemViewPrivate::selectedDraggableIndexes() const
+{
+ Q_Q(const QAbstractItemView);
+ QModelIndexList indexes = q->selectedIndexes();
+ for(int i = indexes.count() - 1 ; i >= 0; --i) {
+ if (!isIndexDragEnabled(indexes.at(i)))
+ indexes.removeAt(i);
+ }
+ return indexes;
+}
+
+
+QT_END_NAMESPACE
+
+#include "moc_qabstractitemview.cpp"
+
+#endif // QT_NO_ITEMVIEWS
diff --git a/src/widgets/itemviews/qabstractitemview.h b/src/widgets/itemviews/qabstractitemview.h
new file mode 100644
index 0000000000..8a2e1cb04e
--- /dev/null
+++ b/src/widgets/itemviews/qabstractitemview.h
@@ -0,0 +1,381 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QABSTRACTITEMVIEW_H
+#define QABSTRACTITEMVIEW_H
+
+#include <QtWidgets/qabstractscrollarea.h>
+#include <QtCore/qabstractitemmodel.h>
+#include <QtWidgets/qitemselectionmodel.h>
+#include <QtWidgets/qabstractitemdelegate.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_ITEMVIEWS
+
+class QMenu;
+class QDrag;
+class QEvent;
+class QAbstractItemViewPrivate;
+
+class Q_WIDGETS_EXPORT QAbstractItemView : public QAbstractScrollArea
+{
+ Q_OBJECT
+ Q_ENUMS(SelectionMode SelectionBehavior ScrollHint ScrollMode DragDropMode)
+ Q_FLAGS(EditTriggers)
+ Q_PROPERTY(bool autoScroll READ hasAutoScroll WRITE setAutoScroll)
+ Q_PROPERTY(int autoScrollMargin READ autoScrollMargin WRITE setAutoScrollMargin)
+ Q_PROPERTY(EditTriggers editTriggers READ editTriggers WRITE setEditTriggers)
+ Q_PROPERTY(bool tabKeyNavigation READ tabKeyNavigation WRITE setTabKeyNavigation)
+#ifndef QT_NO_DRAGANDDROP
+ Q_PROPERTY(bool showDropIndicator READ showDropIndicator WRITE setDropIndicatorShown)
+ Q_PROPERTY(bool dragEnabled READ dragEnabled WRITE setDragEnabled)
+ Q_PROPERTY(bool dragDropOverwriteMode READ dragDropOverwriteMode WRITE setDragDropOverwriteMode)
+ Q_PROPERTY(DragDropMode dragDropMode READ dragDropMode WRITE setDragDropMode)
+ Q_PROPERTY(Qt::DropAction defaultDropAction READ defaultDropAction WRITE setDefaultDropAction)
+#endif
+ Q_PROPERTY(bool alternatingRowColors READ alternatingRowColors WRITE setAlternatingRowColors)
+ Q_PROPERTY(SelectionMode selectionMode READ selectionMode WRITE setSelectionMode)
+ Q_PROPERTY(SelectionBehavior selectionBehavior READ selectionBehavior WRITE setSelectionBehavior)
+ Q_PROPERTY(QSize iconSize READ iconSize WRITE setIconSize)
+ Q_PROPERTY(Qt::TextElideMode textElideMode READ textElideMode WRITE setTextElideMode)
+ Q_PROPERTY(ScrollMode verticalScrollMode READ verticalScrollMode WRITE setVerticalScrollMode)
+ Q_PROPERTY(ScrollMode horizontalScrollMode READ horizontalScrollMode WRITE setHorizontalScrollMode)
+
+public:
+ enum SelectionMode {
+ NoSelection,
+ SingleSelection,
+ MultiSelection,
+ ExtendedSelection,
+ ContiguousSelection
+ };
+
+ enum SelectionBehavior {
+ SelectItems,
+ SelectRows,
+ SelectColumns
+ };
+
+ enum ScrollHint {
+ EnsureVisible,
+ PositionAtTop,
+ PositionAtBottom,
+ PositionAtCenter
+ };
+
+ enum EditTrigger {
+ NoEditTriggers = 0,
+ CurrentChanged = 1,
+ DoubleClicked = 2,
+ SelectedClicked = 4,
+ EditKeyPressed = 8,
+ AnyKeyPressed = 16,
+ AllEditTriggers = 31
+ };
+
+ Q_DECLARE_FLAGS(EditTriggers, EditTrigger)
+
+ enum ScrollMode {
+ ScrollPerItem,
+ ScrollPerPixel
+ };
+
+ explicit QAbstractItemView(QWidget *parent = 0);
+ ~QAbstractItemView();
+
+ virtual void setModel(QAbstractItemModel *model);
+ QAbstractItemModel *model() const;
+
+ virtual void setSelectionModel(QItemSelectionModel *selectionModel);
+ QItemSelectionModel *selectionModel() const;
+
+ void setItemDelegate(QAbstractItemDelegate *delegate);
+ QAbstractItemDelegate *itemDelegate() const;
+
+ void setSelectionMode(QAbstractItemView::SelectionMode mode);
+ QAbstractItemView::SelectionMode selectionMode() const;
+
+ void setSelectionBehavior(QAbstractItemView::SelectionBehavior behavior);
+ QAbstractItemView::SelectionBehavior selectionBehavior() const;
+
+ QModelIndex currentIndex() const;
+ QModelIndex rootIndex() const;
+
+ void setEditTriggers(EditTriggers triggers);
+ EditTriggers editTriggers() const;
+
+ void setVerticalScrollMode(ScrollMode mode);
+ ScrollMode verticalScrollMode() const;
+
+ void setHorizontalScrollMode(ScrollMode mode);
+ ScrollMode horizontalScrollMode() const;
+
+ void setAutoScroll(bool enable);
+ bool hasAutoScroll() const;
+
+ void setAutoScrollMargin(int margin);
+ int autoScrollMargin() const;
+
+ void setTabKeyNavigation(bool enable);
+ bool tabKeyNavigation() const;
+
+#ifndef QT_NO_DRAGANDDROP
+ void setDropIndicatorShown(bool enable);
+ bool showDropIndicator() const;
+
+ void setDragEnabled(bool enable);
+ bool dragEnabled() const;
+
+ void setDragDropOverwriteMode(bool overwrite);
+ bool dragDropOverwriteMode() const;
+
+ enum DragDropMode {
+ NoDragDrop,
+ DragOnly,
+ DropOnly,
+ DragDrop,
+ InternalMove
+ };
+
+ void setDragDropMode(DragDropMode behavior);
+ DragDropMode dragDropMode() const;
+
+ void setDefaultDropAction(Qt::DropAction dropAction);
+ Qt::DropAction defaultDropAction() const;
+#endif
+
+ void setAlternatingRowColors(bool enable);
+ bool alternatingRowColors() const;
+
+ void setIconSize(const QSize &size);
+ QSize iconSize() const;
+
+ void setTextElideMode(Qt::TextElideMode mode);
+ Qt::TextElideMode textElideMode() const;
+
+ virtual void keyboardSearch(const QString &search);
+
+ virtual QRect visualRect(const QModelIndex &index) const = 0;
+ virtual void scrollTo(const QModelIndex &index, ScrollHint hint = EnsureVisible) = 0;
+ virtual QModelIndex indexAt(const QPoint &point) const = 0;
+
+ QSize sizeHintForIndex(const QModelIndex &index) const;
+ virtual int sizeHintForRow(int row) const;
+ virtual int sizeHintForColumn(int column) const;
+
+ void openPersistentEditor(const QModelIndex &index);
+ void closePersistentEditor(const QModelIndex &index);
+
+ void setIndexWidget(const QModelIndex &index, QWidget *widget);
+ QWidget *indexWidget(const QModelIndex &index) const;
+
+ void setItemDelegateForRow(int row, QAbstractItemDelegate *delegate);
+ QAbstractItemDelegate *itemDelegateForRow(int row) const;
+
+ void setItemDelegateForColumn(int column, QAbstractItemDelegate *delegate);
+ QAbstractItemDelegate *itemDelegateForColumn(int column) const;
+
+ QAbstractItemDelegate *itemDelegate(const QModelIndex &index) const;
+
+ virtual QVariant inputMethodQuery(Qt::InputMethodQuery query) const;
+
+#ifdef Q_NO_USING_KEYWORD
+ inline void update() { QAbstractScrollArea::update(); }
+#else
+ using QAbstractScrollArea::update;
+#endif
+
+public Q_SLOTS:
+ virtual void reset();
+ virtual void setRootIndex(const QModelIndex &index);
+ virtual void doItemsLayout();
+ virtual void selectAll();
+ void edit(const QModelIndex &index);
+ void clearSelection();
+ void setCurrentIndex(const QModelIndex &index);
+ void scrollToTop();
+ void scrollToBottom();
+ void update(const QModelIndex &index);
+
+protected Q_SLOTS:
+ virtual void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
+ virtual void rowsInserted(const QModelIndex &parent, int start, int end);
+ virtual void rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end);
+ virtual void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
+ virtual void currentChanged(const QModelIndex &current, const QModelIndex &previous);
+ virtual void updateEditorData();
+ virtual void updateEditorGeometries();
+ virtual void updateGeometries();
+ virtual void verticalScrollbarAction(int action);
+ virtual void horizontalScrollbarAction(int action);
+ virtual void verticalScrollbarValueChanged(int value);
+ virtual void horizontalScrollbarValueChanged(int value);
+ virtual void closeEditor(QWidget *editor, QAbstractItemDelegate::EndEditHint hint);
+ virtual void commitData(QWidget *editor);
+ virtual void editorDestroyed(QObject *editor);
+
+Q_SIGNALS:
+ void pressed(const QModelIndex &index);
+ void clicked(const QModelIndex &index);
+ void doubleClicked(const QModelIndex &index);
+
+ void activated(const QModelIndex &index);
+ void entered(const QModelIndex &index);
+ void viewportEntered();
+
+protected:
+ QAbstractItemView(QAbstractItemViewPrivate &, QWidget *parent = 0);
+
+ void setHorizontalStepsPerItem(int steps);
+ int horizontalStepsPerItem() const;
+ void setVerticalStepsPerItem(int steps);
+ int verticalStepsPerItem() const;
+
+ enum CursorAction { MoveUp, MoveDown, MoveLeft, MoveRight,
+ MoveHome, MoveEnd, MovePageUp, MovePageDown,
+ MoveNext, MovePrevious };
+ virtual QModelIndex moveCursor(CursorAction cursorAction,
+ Qt::KeyboardModifiers modifiers) = 0;
+
+ virtual int horizontalOffset() const = 0;
+ virtual int verticalOffset() const = 0;
+
+ virtual bool isIndexHidden(const QModelIndex &index) const = 0;
+
+ virtual void setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags command) = 0;
+ virtual QRegion visualRegionForSelection(const QItemSelection &selection) const = 0;
+ virtual QModelIndexList selectedIndexes() const;
+
+ virtual bool edit(const QModelIndex &index, EditTrigger trigger, QEvent *event);
+
+ virtual QItemSelectionModel::SelectionFlags selectionCommand(const QModelIndex &index,
+ const QEvent *event = 0) const;
+
+#ifndef QT_NO_DRAGANDDROP
+ virtual void startDrag(Qt::DropActions supportedActions);
+#endif
+
+ virtual QStyleOptionViewItem viewOptions() const;
+
+ enum State {
+ NoState,
+ DraggingState,
+ DragSelectingState,
+ EditingState,
+ ExpandingState,
+ CollapsingState,
+ AnimatingState
+ };
+
+ State state() const;
+ void setState(State state);
+
+ void scheduleDelayedItemsLayout();
+ void executeDelayedItemsLayout();
+
+ void setDirtyRegion(const QRegion &region);
+ void scrollDirtyRegion(int dx, int dy);
+ QPoint dirtyRegionOffset() const;
+
+ void startAutoScroll();
+ void stopAutoScroll();
+ void doAutoScroll();
+
+ bool focusNextPrevChild(bool next);
+ bool event(QEvent *event);
+ bool viewportEvent(QEvent *event);
+ void mousePressEvent(QMouseEvent *event);
+ void mouseMoveEvent(QMouseEvent *event);
+ void mouseReleaseEvent(QMouseEvent *event);
+ void mouseDoubleClickEvent(QMouseEvent *event);
+#ifndef QT_NO_DRAGANDDROP
+ void dragEnterEvent(QDragEnterEvent *event);
+ void dragMoveEvent(QDragMoveEvent *event);
+ void dragLeaveEvent(QDragLeaveEvent *event);
+ void dropEvent(QDropEvent *event);
+#endif
+ void focusInEvent(QFocusEvent *event);
+ void focusOutEvent(QFocusEvent *event);
+ void keyPressEvent(QKeyEvent *event);
+ void resizeEvent(QResizeEvent *event);
+ void timerEvent(QTimerEvent *event);
+ void inputMethodEvent(QInputMethodEvent *event);
+
+#ifndef QT_NO_DRAGANDDROP
+ enum DropIndicatorPosition { OnItem, AboveItem, BelowItem, OnViewport };
+ DropIndicatorPosition dropIndicatorPosition() const;
+#endif
+
+private:
+ Q_DECLARE_PRIVATE(QAbstractItemView)
+ Q_DISABLE_COPY(QAbstractItemView)
+ Q_PRIVATE_SLOT(d_func(), void _q_columnsAboutToBeRemoved(const QModelIndex&, int, int))
+ Q_PRIVATE_SLOT(d_func(), void _q_columnsRemoved(const QModelIndex&, int, int))
+ Q_PRIVATE_SLOT(d_func(), void _q_columnsInserted(const QModelIndex&, int, int))
+ Q_PRIVATE_SLOT(d_func(), void _q_rowsInserted(const QModelIndex&, int, int))
+ Q_PRIVATE_SLOT(d_func(), void _q_rowsRemoved(const QModelIndex&, int, int))
+ Q_PRIVATE_SLOT(d_func(), void _q_modelDestroyed())
+ Q_PRIVATE_SLOT(d_func(), void _q_layoutChanged())
+ Q_PRIVATE_SLOT(d_func(), void _q_headerDataChanged())
+#ifndef QT_NO_GESTURES
+ Q_PRIVATE_SLOT(d_func(), void _q_scrollerStateChanged())
+#endif
+
+ friend class QTreeViewPrivate; // needed to compile with MSVC
+ friend class QAccessibleItemRow;
+ friend class QListModeViewBase;
+ friend class QListViewPrivate; // needed to compile for Symbian emulator
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QAbstractItemView::EditTriggers)
+
+#endif // QT_NO_ITEMVIEWS
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QABSTRACTITEMVIEW_H
diff --git a/src/widgets/itemviews/qabstractitemview_p.h b/src/widgets/itemviews/qabstractitemview_p.h
new file mode 100644
index 0000000000..cd15694ffe
--- /dev/null
+++ b/src/widgets/itemviews/qabstractitemview_p.h
@@ -0,0 +1,458 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QABSTRACTITEMVIEW_P_H
+#define QABSTRACTITEMVIEW_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "private/qabstractscrollarea_p.h"
+#include "private/qabstractitemmodel_p.h"
+#include "QtWidgets/qapplication.h"
+#include "QtGui/qevent.h"
+#include "QtGui/qmime.h"
+#include "QtGui/qpainter.h"
+#include "QtCore/qpair.h"
+#include "QtGui/qregion.h"
+#include "QtCore/qdebug.h"
+#include "QtGui/qpainter.h"
+#include "QtCore/qbasictimer.h"
+#include "QtCore/qelapsedtimer.h"
+
+#ifndef QT_NO_ITEMVIEWS
+
+QT_BEGIN_NAMESPACE
+
+struct QEditorInfo {
+ QEditorInfo(QWidget *e, bool s): widget(QWeakPointer<QWidget>(e)), isStatic(s) {}
+ QEditorInfo(): isStatic(false) {}
+
+ QWeakPointer<QWidget> widget;
+ bool isStatic;
+};
+
+// Fast associativity between Persistent editors and indices.
+typedef QHash<QWidget *, QPersistentModelIndex> QEditorIndexHash;
+typedef QHash<QPersistentModelIndex, QEditorInfo> QIndexEditorHash;
+
+typedef QPair<QRect, QModelIndex> QItemViewPaintPair;
+typedef QList<QItemViewPaintPair> QItemViewPaintPairs;
+
+class QEmptyModel : public QAbstractItemModel
+{
+public:
+ explicit QEmptyModel(QObject *parent = 0) : QAbstractItemModel(parent) {}
+ QModelIndex index(int, int, const QModelIndex &) const { return QModelIndex(); }
+ QModelIndex parent(const QModelIndex &) const { return QModelIndex(); }
+ int rowCount(const QModelIndex &) const { return 0; }
+ int columnCount(const QModelIndex &) const { return 0; }
+ bool hasChildren(const QModelIndex &) const { return false; }
+ QVariant data(const QModelIndex &, int) const { return QVariant(); }
+};
+
+class Q_AUTOTEST_EXPORT QAbstractItemViewPrivate : public QAbstractScrollAreaPrivate
+{
+ Q_DECLARE_PUBLIC(QAbstractItemView)
+
+public:
+ QAbstractItemViewPrivate();
+ virtual ~QAbstractItemViewPrivate();
+
+ void init();
+
+ virtual void _q_rowsRemoved(const QModelIndex &parent, int start, int end);
+ virtual void _q_rowsInserted(const QModelIndex &parent, int start, int end);
+ virtual void _q_columnsAboutToBeRemoved(const QModelIndex &parent, int start, int end);
+ virtual void _q_columnsRemoved(const QModelIndex &parent, int start, int end);
+ virtual void _q_columnsInserted(const QModelIndex &parent, int start, int end);
+ virtual void _q_modelDestroyed();
+ virtual void _q_layoutChanged();
+ void _q_headerDataChanged() { doDelayedItemsLayout(); }
+ void _q_scrollerStateChanged();
+
+ void fetchMore();
+
+ bool shouldEdit(QAbstractItemView::EditTrigger trigger, const QModelIndex &index) const;
+ bool shouldForwardEvent(QAbstractItemView::EditTrigger trigger, const QEvent *event) const;
+ bool shouldAutoScroll(const QPoint &pos) const;
+ void doDelayedItemsLayout(int delay = 0);
+ void interruptDelayedItemsLayout() const;
+
+ void startAutoScroll()
+ { // ### it would be nice to make this into a style hint one day
+ int scrollInterval = (verticalScrollMode == QAbstractItemView::ScrollPerItem) ? 150 : 50;
+ autoScrollTimer.start(scrollInterval, q_func());
+ autoScrollCount = 0;
+ }
+ void stopAutoScroll() { autoScrollTimer.stop(); autoScrollCount = 0;}
+
+#ifndef QT_NO_DRAGANDDROP
+ virtual bool dropOn(QDropEvent *event, int *row, int *col, QModelIndex *index);
+#endif
+ bool droppingOnItself(QDropEvent *event, const QModelIndex &index);
+
+ QWidget *editor(const QModelIndex &index, const QStyleOptionViewItem &options);
+ bool sendDelegateEvent(const QModelIndex &index, QEvent *event) const;
+ bool openEditor(const QModelIndex &index, QEvent *event);
+ void updateEditorData(const QModelIndex &topLeft, const QModelIndex &bottomRight);
+
+ QItemSelectionModel::SelectionFlags multiSelectionCommand(const QModelIndex &index,
+ const QEvent *event) const;
+ QItemSelectionModel::SelectionFlags extendedSelectionCommand(const QModelIndex &index,
+ const QEvent *event) const;
+ QItemSelectionModel::SelectionFlags contiguousSelectionCommand(const QModelIndex &index,
+ const QEvent *event) const;
+ virtual void selectAll(QItemSelectionModel::SelectionFlags command);
+
+ void setHoverIndex(const QPersistentModelIndex &index);
+
+ void checkMouseMove(const QPersistentModelIndex &index);
+ inline void checkMouseMove(const QPoint &pos) { checkMouseMove(q_func()->indexAt(pos)); }
+
+ inline QItemSelectionModel::SelectionFlags selectionBehaviorFlags() const
+ {
+ switch (selectionBehavior) {
+ case QAbstractItemView::SelectRows: return QItemSelectionModel::Rows;
+ case QAbstractItemView::SelectColumns: return QItemSelectionModel::Columns;
+ case QAbstractItemView::SelectItems: default: return QItemSelectionModel::NoUpdate;
+ }
+ }
+
+#ifndef QT_NO_DRAGANDDROP
+ virtual QAbstractItemView::DropIndicatorPosition position(const QPoint &pos, const QRect &rect, const QModelIndex &idx) const;
+
+ inline bool canDecode(QDropEvent *e) const {
+ QStringList modelTypes = model->mimeTypes();
+ const QMimeData *mime = e->mimeData();
+ for (int i = 0; i < modelTypes.count(); ++i)
+ if (mime->hasFormat(modelTypes.at(i))
+ && (e->dropAction() & model->supportedDropActions()))
+ return true;
+ return false;
+ }
+
+ inline void paintDropIndicator(QPainter *painter)
+ {
+ if (showDropIndicator && state == QAbstractItemView::DraggingState
+#ifndef QT_NO_CURSOR
+ && viewport->cursor().shape() != Qt::ForbiddenCursor
+#endif
+ ) {
+ QStyleOption opt;
+ opt.init(q_func());
+ opt.rect = dropIndicatorRect;
+ q_func()->style()->drawPrimitive(QStyle::PE_IndicatorItemViewItemDrop, &opt, painter, q_func());
+ }
+ }
+
+#endif
+ virtual QItemViewPaintPairs draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const;
+
+ inline void releaseEditor(QWidget *editor) const {
+ if (editor) {
+ QObject::disconnect(editor, SIGNAL(destroyed(QObject*)),
+ q_func(), SLOT(editorDestroyed(QObject*)));
+ editor->removeEventFilter(itemDelegate);
+ editor->hide();
+ editor->deleteLater();
+ }
+ }
+
+ inline void executePostedLayout() const {
+ if (delayedPendingLayout && state != QAbstractItemView::CollapsingState) {
+ interruptDelayedItemsLayout();
+ const_cast<QAbstractItemView*>(q_func())->doItemsLayout();
+ }
+ }
+
+ inline void setDirtyRegion(const QRegion &visualRegion) {
+ updateRegion += visualRegion;
+ if (!updateTimer.isActive())
+ updateTimer.start(0, q_func());
+ }
+
+ inline void scrollDirtyRegion(int dx, int dy) {
+ scrollDelayOffset = QPoint(-dx, -dy);
+ updateDirtyRegion();
+ scrollDelayOffset = QPoint(0, 0);
+ }
+
+ inline void scrollContentsBy(int dx, int dy) {
+ scrollDirtyRegion(dx, dy);
+ viewport->scroll(dx, dy);
+ }
+
+ void updateDirtyRegion() {
+ updateTimer.stop();
+ viewport->update(updateRegion);
+ updateRegion = QRegion();
+ }
+
+ void clearOrRemove();
+ void checkPersistentEditorFocus();
+
+ QPixmap renderToPixmap(const QModelIndexList &indexes, QRect *r) const;
+
+ inline QPoint offset() const {
+ const Q_Q(QAbstractItemView);
+ return QPoint(q->isRightToLeft() ? -q->horizontalOffset()
+ : q->horizontalOffset(), q->verticalOffset());
+ }
+
+ const QEditorInfo &editorForIndex(const QModelIndex &index) const;
+ inline bool hasEditor(const QModelIndex &index) const {
+ return indexEditorHash.find(index) != indexEditorHash.constEnd();
+ }
+
+ QModelIndex indexForEditor(QWidget *editor) const;
+ void addEditor(const QModelIndex &index, QWidget *editor, bool isStatic);
+ void removeEditor(QWidget *editor);
+
+ inline bool isAnimating() const {
+ return state == QAbstractItemView::AnimatingState;
+ }
+
+ inline QAbstractItemDelegate *delegateForIndex(const QModelIndex &index) const {
+ QAbstractItemDelegate *del;
+ if ((del = rowDelegates.value(index.row(), 0))) return del;
+ if ((del = columnDelegates.value(index.column(), 0))) return del;
+ return itemDelegate;
+ }
+
+ inline bool isIndexValid(const QModelIndex &index) const {
+ return (index.row() >= 0) && (index.column() >= 0) && (index.model() == model);
+ }
+ inline bool isIndexSelectable(const QModelIndex &index) const {
+ return (model->flags(index) & Qt::ItemIsSelectable);
+ }
+ inline bool isIndexEnabled(const QModelIndex &index) const {
+ return (model->flags(index) & Qt::ItemIsEnabled);
+ }
+ inline bool isIndexDropEnabled(const QModelIndex &index) const {
+ return (model->flags(index) & Qt::ItemIsDropEnabled);
+ }
+ inline bool isIndexDragEnabled(const QModelIndex &index) const {
+ return (model->flags(index) & Qt::ItemIsDragEnabled);
+ }
+
+ virtual bool selectionAllowed(const QModelIndex &index) const {
+ // in some views we want to go ahead with selections, even if the index is invalid
+ return isIndexValid(index) && isIndexSelectable(index);
+ }
+
+ // reimplemented from QAbstractScrollAreaPrivate
+ virtual QPoint contentsOffset() const {
+ Q_Q(const QAbstractItemView);
+ return QPoint(q->horizontalOffset(), q->verticalOffset());
+ }
+
+ /**
+ * For now, assume that we have few editors, if we need a more efficient implementation
+ * we should add a QMap<QAbstractItemDelegate*, int> member.
+ */
+ int delegateRefCount(const QAbstractItemDelegate *delegate) const
+ {
+ int ref = 0;
+ if (itemDelegate == delegate)
+ ++ref;
+
+ for (int maps = 0; maps < 2; ++maps) {
+ const QMap<int, QPointer<QAbstractItemDelegate> > *delegates = maps ? &columnDelegates : &rowDelegates;
+ for (QMap<int, QPointer<QAbstractItemDelegate> >::const_iterator it = delegates->begin();
+ it != delegates->end(); ++it) {
+ if (it.value() == delegate) {
+ ++ref;
+ // optimization, we are only interested in the ref count values 0, 1 or >=2
+ if (ref >= 2) {
+ return ref;
+ }
+ }
+ }
+ }
+ return ref;
+ }
+
+ /**
+ * return true if the index is registered as a QPersistentModelIndex
+ */
+ inline bool isPersistent(const QModelIndex &index) const
+ {
+ return static_cast<QAbstractItemModelPrivate *>(model->d_ptr.data())->persistent.indexes.contains(index);
+ }
+
+ QModelIndexList selectedDraggableIndexes() const;
+
+ QStyleOptionViewItemV4 viewOptionsV4() const;
+
+ void doDelayedReset()
+ {
+ //we delay the reset of the timer because some views (QTableView)
+ //with headers can't handle the fact that the model has been destroyed
+ //all _q_modelDestroyed slots must have been called
+ if (!delayedReset.isActive())
+ delayedReset.start(0, q_func());
+ }
+
+ QAbstractItemModel *model;
+ QPointer<QAbstractItemDelegate> itemDelegate;
+ QMap<int, QPointer<QAbstractItemDelegate> > rowDelegates;
+ QMap<int, QPointer<QAbstractItemDelegate> > columnDelegates;
+ QPointer<QItemSelectionModel> selectionModel;
+ QItemSelectionModel::SelectionFlag ctrlDragSelectionFlag;
+ bool noSelectionOnMousePress;
+
+ QAbstractItemView::SelectionMode selectionMode;
+ QAbstractItemView::SelectionBehavior selectionBehavior;
+
+ QEditorIndexHash editorIndexHash;
+ QIndexEditorHash indexEditorHash;
+ QSet<QWidget*> persistent;
+ QWidget *currentlyCommittingEditor;
+
+ QPersistentModelIndex enteredIndex;
+ QPersistentModelIndex pressedIndex;
+ Qt::KeyboardModifiers pressedModifiers;
+ QPoint pressedPosition;
+ bool pressedAlreadySelected;
+
+ //forces the next mouseMoveEvent to send the viewportEntered signal
+ //if the mouse is over the viewport and not over an item
+ bool viewportEnteredNeeded;
+
+ QAbstractItemView::State state;
+ QAbstractItemView::State stateBeforeAnimation;
+ QAbstractItemView::EditTriggers editTriggers;
+ QAbstractItemView::EditTrigger lastTrigger;
+
+ QPersistentModelIndex root;
+ QPersistentModelIndex hover;
+
+ bool tabKeyNavigation;
+
+#ifndef QT_NO_DRAGANDDROP
+ bool showDropIndicator;
+ QRect dropIndicatorRect;
+ bool dragEnabled;
+ QAbstractItemView::DragDropMode dragDropMode;
+ bool overwrite;
+ QAbstractItemView::DropIndicatorPosition dropIndicatorPosition;
+ Qt::DropAction defaultDropAction;
+#endif
+
+#ifdef QT_SOFTKEYS_ENABLED
+ QAction *doneSoftKey;
+#endif
+
+ QString keyboardInput;
+ QElapsedTimer keyboardInputTime;
+
+ bool autoScroll;
+ QBasicTimer autoScrollTimer;
+ int autoScrollMargin;
+ int autoScrollCount;
+ bool shouldScrollToCurrentOnShow; //used to know if we should scroll to current on show event
+ bool shouldClearStatusTip; //if there is a statustip currently shown that need to be cleared when leaving.
+
+ bool alternatingColors;
+
+ QSize iconSize;
+ Qt::TextElideMode textElideMode;
+
+ QRegion updateRegion; // used for the internal update system
+ QPoint scrollDelayOffset;
+
+ QBasicTimer updateTimer;
+ QBasicTimer delayedEditing;
+ QBasicTimer delayedAutoScroll; //used when an item is clicked
+ QBasicTimer delayedReset;
+
+ QAbstractItemView::ScrollMode verticalScrollMode;
+ QAbstractItemView::ScrollMode horizontalScrollMode;
+
+#ifndef QT_NO_GESTURES
+ // the selection before the last mouse down. In case we have to restore it for scrolling
+ QItemSelection oldSelection;
+ QModelIndex oldCurrent;
+#endif
+
+ bool currentIndexSet;
+
+ bool wrapItemText;
+ mutable bool delayedPendingLayout;
+ bool moveCursorUpdatedView;
+
+private:
+ mutable QBasicTimer delayedLayout;
+ mutable QBasicTimer fetchMoreTimer;
+};
+
+QT_BEGIN_INCLUDE_NAMESPACE
+#include <qvector.h>
+QT_END_INCLUDE_NAMESPACE
+
+template <typename T>
+inline int qBinarySearch(const QVector<T> &vec, const T &item, int start, int end)
+{
+ int i = (start + end + 1) >> 1;
+ while (end - start > 0) {
+ if (vec.at(i) > item)
+ end = i - 1;
+ else
+ start = i;
+ i = (start + end + 1) >> 1;
+ }
+ return i;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_ITEMVIEWS
+
+#endif // QABSTRACTITEMVIEW_P_H
diff --git a/src/gui/itemviews/qabstractproxymodel.cpp b/src/widgets/itemviews/qabstractproxymodel.cpp
index 48c84acb56..48c84acb56 100644
--- a/src/gui/itemviews/qabstractproxymodel.cpp
+++ b/src/widgets/itemviews/qabstractproxymodel.cpp
diff --git a/src/widgets/itemviews/qabstractproxymodel.h b/src/widgets/itemviews/qabstractproxymodel.h
new file mode 100644
index 0000000000..a24755b556
--- /dev/null
+++ b/src/widgets/itemviews/qabstractproxymodel.h
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QABSTRACTPROXYMODEL_H
+#define QABSTRACTPROXYMODEL_H
+
+#include <QtCore/qabstractitemmodel.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_PROXYMODEL
+
+class QAbstractProxyModelPrivate;
+class QItemSelection;
+
+class Q_WIDGETS_EXPORT QAbstractProxyModel : public QAbstractItemModel
+{
+ Q_OBJECT
+
+public:
+ QAbstractProxyModel(QObject *parent = 0);
+ ~QAbstractProxyModel();
+
+ virtual void setSourceModel(QAbstractItemModel *sourceModel);
+ QAbstractItemModel *sourceModel() const;
+
+ virtual QModelIndex mapToSource(const QModelIndex &proxyIndex) const = 0;
+ virtual QModelIndex mapFromSource(const QModelIndex &sourceIndex) const = 0;
+
+ virtual QItemSelection mapSelectionToSource(const QItemSelection &selection) const;
+ virtual QItemSelection mapSelectionFromSource(const QItemSelection &selection) const;
+
+ bool submit();
+ void revert();
+
+ QVariant data(const QModelIndex &proxyIndex, int role = Qt::DisplayRole) const;
+ QVariant headerData(int section, Qt::Orientation orientation, int role) const;
+ QMap<int, QVariant> itemData(const QModelIndex &index) const;
+ Qt::ItemFlags flags(const QModelIndex &index) const;
+
+ bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
+ bool setItemData(const QModelIndex& index, const QMap<int, QVariant> &roles);
+ bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role = Qt::EditRole);
+
+ QModelIndex buddy(const QModelIndex &index) const;
+ bool canFetchMore(const QModelIndex &parent) const;
+ void fetchMore(const QModelIndex &parent);
+ void sort(int column, Qt::SortOrder order = Qt::AscendingOrder);
+ QSize span(const QModelIndex &index) const;
+ bool hasChildren(const QModelIndex &parent = QModelIndex()) const;
+
+ QMimeData* mimeData(const QModelIndexList &indexes) const;
+ QStringList mimeTypes() const;
+ Qt::DropActions supportedDropActions() const;
+
+protected:
+ QAbstractProxyModel(QAbstractProxyModelPrivate &, QObject *parent);
+
+private:
+ Q_DECLARE_PRIVATE(QAbstractProxyModel)
+ Q_DISABLE_COPY(QAbstractProxyModel)
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceModelDestroyed())
+};
+
+#endif // QT_NO_PROXYMODEL
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QABSTRACTPROXYMODEL_H
diff --git a/src/gui/itemviews/qabstractproxymodel_p.h b/src/widgets/itemviews/qabstractproxymodel_p.h
index 9bd38d1cdc..9bd38d1cdc 100644
--- a/src/gui/itemviews/qabstractproxymodel_p.h
+++ b/src/widgets/itemviews/qabstractproxymodel_p.h
diff --git a/src/gui/itemviews/qbsptree.cpp b/src/widgets/itemviews/qbsptree.cpp
index 89f98f50f3..89f98f50f3 100644
--- a/src/gui/itemviews/qbsptree.cpp
+++ b/src/widgets/itemviews/qbsptree.cpp
diff --git a/src/gui/itemviews/qbsptree_p.h b/src/widgets/itemviews/qbsptree_p.h
index c98efba6fa..c98efba6fa 100644
--- a/src/gui/itemviews/qbsptree_p.h
+++ b/src/widgets/itemviews/qbsptree_p.h
diff --git a/src/gui/itemviews/qcolumnview.cpp b/src/widgets/itemviews/qcolumnview.cpp
index 2be03a0fe8..2be03a0fe8 100644
--- a/src/gui/itemviews/qcolumnview.cpp
+++ b/src/widgets/itemviews/qcolumnview.cpp
diff --git a/src/widgets/itemviews/qcolumnview.h b/src/widgets/itemviews/qcolumnview.h
new file mode 100644
index 0000000000..b6d8687808
--- /dev/null
+++ b/src/widgets/itemviews/qcolumnview.h
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCOLUMNVIEW_H
+#define QCOLUMNVIEW_H
+
+#include <QtWidgets/qabstractitemview.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_COLUMNVIEW
+
+class QColumnViewPrivate;
+
+class Q_WIDGETS_EXPORT QColumnView : public QAbstractItemView {
+
+Q_OBJECT
+ Q_PROPERTY(bool resizeGripsVisible READ resizeGripsVisible WRITE setResizeGripsVisible)
+
+Q_SIGNALS:
+ void updatePreviewWidget(const QModelIndex &index);
+
+public:
+ explicit QColumnView(QWidget *parent = 0);
+ ~QColumnView();
+
+ // QAbstractItemView overloads
+ QModelIndex indexAt(const QPoint &point) const;
+ void scrollTo(const QModelIndex &index, ScrollHint hint = EnsureVisible);
+ QSize sizeHint() const;
+ QRect visualRect(const QModelIndex &index) const;
+ void setModel(QAbstractItemModel *model);
+ void setSelectionModel(QItemSelectionModel * selectionModel);
+ void setRootIndex(const QModelIndex &index);
+ void selectAll();
+
+ // QColumnView functions
+ void setResizeGripsVisible(bool visible);
+ bool resizeGripsVisible() const;
+
+ QWidget *previewWidget() const;
+ void setPreviewWidget(QWidget *widget);
+
+ void setColumnWidths(const QList<int> &list);
+ QList<int> columnWidths() const;
+
+protected:
+ QColumnView(QColumnViewPrivate &dd, QWidget *parent = 0);
+
+ // QAbstractItemView overloads
+ bool isIndexHidden(const QModelIndex &index) const;
+ QModelIndex moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers);
+ void resizeEvent(QResizeEvent *event);
+ void setSelection(const QRect & rect, QItemSelectionModel::SelectionFlags command);
+ QRegion visualRegionForSelection(const QItemSelection &selection) const;
+ int horizontalOffset() const;
+ int verticalOffset() const;
+ void rowsInserted(const QModelIndex &parent, int start, int end);
+ void currentChanged(const QModelIndex &current, const QModelIndex &previous);
+
+ // QColumnView functions
+ void scrollContentsBy(int dx, int dy);
+ virtual QAbstractItemView* createColumn(const QModelIndex &rootIndex);
+ void initializeColumn(QAbstractItemView *column) const;
+
+private:
+ Q_DECLARE_PRIVATE(QColumnView)
+ Q_DISABLE_COPY(QColumnView)
+ Q_PRIVATE_SLOT(d_func(), void _q_gripMoved(int))
+ Q_PRIVATE_SLOT(d_func(), void _q_changeCurrentColumn())
+ Q_PRIVATE_SLOT(d_func(), void _q_clicked(const QModelIndex &))
+};
+
+#endif // QT_NO_COLUMNVIEW
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QCOLUMNVIEW_H
+
diff --git a/src/widgets/itemviews/qcolumnview_p.h b/src/widgets/itemviews/qcolumnview_p.h
new file mode 100644
index 0000000000..0da719e756
--- /dev/null
+++ b/src/widgets/itemviews/qcolumnview_p.h
@@ -0,0 +1,189 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCOLUMNVIEW_P_H
+#define QCOLUMNVIEW_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qcolumnview.h"
+
+#ifndef QT_NO_QCOLUMNVIEW
+
+#include <private/qabstractitemview_p.h>
+
+#include <QtCore/qabstractitemmodel.h>
+#include <QtCore/qpropertyanimation.h>
+#include <QtWidgets/qabstractitemdelegate.h>
+#include <QtWidgets/qabstractitemview.h>
+#include <QtWidgets/qitemdelegate.h>
+#include <qlistview.h>
+#include <qevent.h>
+#include <qscrollbar.h>
+
+QT_BEGIN_NAMESPACE
+
+class QColumnViewPreviewColumn : public QAbstractItemView {
+
+public:
+ QColumnViewPreviewColumn(QWidget *parent) : QAbstractItemView(parent), previewWidget(0) {
+ }
+
+ void setPreviewWidget(QWidget *widget) {
+ previewWidget = widget;
+ setMinimumWidth(previewWidget->minimumWidth());
+ }
+
+ void resizeEvent(QResizeEvent * event){
+ if (!previewWidget)
+ return;
+ previewWidget->resize(
+ qMax(previewWidget->minimumWidth(), event->size().width()),
+ previewWidget->height());
+ QSize p = viewport()->size();
+ QSize v = previewWidget->size();
+ horizontalScrollBar()->setRange(0, v.width() - p.width());
+ horizontalScrollBar()->setPageStep(p.width());
+ verticalScrollBar()->setRange(0, v.height() - p.height());
+ verticalScrollBar()->setPageStep(p.height());
+
+ QAbstractScrollArea::resizeEvent(event);
+ }
+
+ QRect visualRect(const QModelIndex &) const
+ {
+ return QRect();
+ }
+ void scrollTo(const QModelIndex &, ScrollHint)
+ {
+ }
+ QModelIndex indexAt(const QPoint &) const
+ {
+ return QModelIndex();
+ }
+ QModelIndex moveCursor(CursorAction, Qt::KeyboardModifiers)
+ {
+ return QModelIndex();
+ }
+ int horizontalOffset () const {
+ return 0;
+ }
+ int verticalOffset () const {
+ return 0;
+ }
+ QRegion visualRegionForSelection(const QItemSelection &) const
+ {
+ return QRegion();
+ }
+ bool isIndexHidden(const QModelIndex &) const
+ {
+ return false;
+ }
+ void setSelection(const QRect &, QItemSelectionModel::SelectionFlags)
+ {
+ }
+private:
+ QWidget *previewWidget;
+};
+
+class Q_AUTOTEST_EXPORT QColumnViewPrivate : public QAbstractItemViewPrivate
+{
+ Q_DECLARE_PUBLIC(QColumnView)
+
+public:
+ QColumnViewPrivate();
+ ~QColumnViewPrivate();
+ void initialize();
+
+ QAbstractItemView *createColumn(const QModelIndex &index, bool show);
+
+ void updateScrollbars();
+ void closeColumns(const QModelIndex &parent = QModelIndex(), bool build = false);
+ void doLayout();
+ void setPreviewWidget(QWidget *widget);
+ void checkColumnCreation(const QModelIndex &parent);
+
+
+ void _q_gripMoved(int offset);
+ void _q_changeCurrentColumn();
+ void _q_clicked(const QModelIndex &index);
+ void _q_columnsInserted(const QModelIndex &parent, int start, int end);
+
+ QList<QAbstractItemView*> columns;
+ QVector<int> columnSizes; // used during init and corner moving
+ bool showResizeGrips;
+ int offset;
+#ifndef QT_NO_ANIMATION
+ QPropertyAnimation currentAnimation;
+#endif
+ QWidget *previewWidget;
+ QAbstractItemView *previewColumn;
+};
+
+/*!
+ * This is a delegate that will paint the triangle
+ */
+class QColumnViewDelegate : public QItemDelegate
+{
+
+public:
+ explicit QColumnViewDelegate(QObject *parent = 0) : QItemDelegate(parent) {}
+ ~QColumnViewDelegate() {}
+
+ void paint(QPainter *painter,
+ const QStyleOptionViewItem &option,
+ const QModelIndex &index) const;
+};
+#endif // QT_NO_QCOLUMNVIEW
+
+
+QT_END_NAMESPACE
+#endif //QCOLUMNVIEW_P_H
+
diff --git a/src/gui/itemviews/qcolumnviewgrip.cpp b/src/widgets/itemviews/qcolumnviewgrip.cpp
index 19b8c1aa78..19b8c1aa78 100644
--- a/src/gui/itemviews/qcolumnviewgrip.cpp
+++ b/src/widgets/itemviews/qcolumnviewgrip.cpp
diff --git a/src/gui/itemviews/qcolumnviewgrip_p.h b/src/widgets/itemviews/qcolumnviewgrip_p.h
index 13bdb3694b..13bdb3694b 100644
--- a/src/gui/itemviews/qcolumnviewgrip_p.h
+++ b/src/widgets/itemviews/qcolumnviewgrip_p.h
diff --git a/src/gui/itemviews/qdatawidgetmapper.cpp b/src/widgets/itemviews/qdatawidgetmapper.cpp
index 7d328fcce5..7d328fcce5 100644
--- a/src/gui/itemviews/qdatawidgetmapper.cpp
+++ b/src/widgets/itemviews/qdatawidgetmapper.cpp
diff --git a/src/widgets/itemviews/qdatawidgetmapper.h b/src/widgets/itemviews/qdatawidgetmapper.h
new file mode 100644
index 0000000000..ebb180fa20
--- /dev/null
+++ b/src/widgets/itemviews/qdatawidgetmapper.h
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDATAWIDGETMAPPER_H
+#define QDATAWIDGETMAPPER_H
+
+#include "QtCore/qobject.h"
+
+#ifndef QT_NO_DATAWIDGETMAPPER
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QAbstractItemDelegate;
+class QAbstractItemModel;
+class QModelIndex;
+class QDataWidgetMapperPrivate;
+
+class Q_WIDGETS_EXPORT QDataWidgetMapper: public QObject
+{
+ Q_OBJECT
+
+ Q_ENUMS(SubmitPolicy)
+ Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged)
+ Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation)
+ Q_PROPERTY(SubmitPolicy submitPolicy READ submitPolicy WRITE setSubmitPolicy)
+
+public:
+ QDataWidgetMapper(QObject *parent = 0);
+ ~QDataWidgetMapper();
+
+ void setModel(QAbstractItemModel *model);
+ QAbstractItemModel *model() const;
+
+ void setItemDelegate(QAbstractItemDelegate *delegate);
+ QAbstractItemDelegate *itemDelegate() const;
+
+ void setRootIndex(const QModelIndex &index);
+ QModelIndex rootIndex() const;
+
+ void setOrientation(Qt::Orientation aOrientation);
+ Qt::Orientation orientation() const;
+
+ enum SubmitPolicy { AutoSubmit, ManualSubmit };
+ void setSubmitPolicy(SubmitPolicy policy);
+ SubmitPolicy submitPolicy() const;
+
+ void addMapping(QWidget *widget, int section);
+ void addMapping(QWidget *widget, int section, const QByteArray &propertyName);
+ void removeMapping(QWidget *widget);
+ int mappedSection(QWidget *widget) const;
+ QByteArray mappedPropertyName(QWidget *widget) const;
+ QWidget *mappedWidgetAt(int section) const;
+ void clearMapping();
+
+ int currentIndex() const;
+
+public Q_SLOTS:
+ void revert();
+ bool submit();
+
+ void toFirst();
+ void toLast();
+ void toNext();
+ void toPrevious();
+ virtual void setCurrentIndex(int index);
+ void setCurrentModelIndex(const QModelIndex &index);
+
+Q_SIGNALS:
+ void currentIndexChanged(int index);
+
+private:
+ Q_DECLARE_PRIVATE(QDataWidgetMapper)
+ Q_DISABLE_COPY(QDataWidgetMapper)
+ Q_PRIVATE_SLOT(d_func(), void _q_dataChanged(const QModelIndex &, const QModelIndex &))
+ Q_PRIVATE_SLOT(d_func(), void _q_commitData(QWidget *))
+ Q_PRIVATE_SLOT(d_func(), void _q_closeEditor(QWidget *, QAbstractItemDelegate::EndEditHint))
+ Q_PRIVATE_SLOT(d_func(), void _q_modelDestroyed())
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QT_NO_DATAWIDGETMAPPER
+#endif
+
diff --git a/src/gui/itemviews/qdirmodel.cpp b/src/widgets/itemviews/qdirmodel.cpp
index 70958195f7..70958195f7 100644
--- a/src/gui/itemviews/qdirmodel.cpp
+++ b/src/widgets/itemviews/qdirmodel.cpp
diff --git a/src/widgets/itemviews/qdirmodel.h b/src/widgets/itemviews/qdirmodel.h
new file mode 100644
index 0000000000..4ad89065f9
--- /dev/null
+++ b/src/widgets/itemviews/qdirmodel.h
@@ -0,0 +1,160 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDIRMODEL_H
+#define QDIRMODEL_H
+
+#include <QtCore/qabstractitemmodel.h>
+#include <QtCore/qdir.h>
+#include <QtWidgets/qfileiconprovider.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_DIRMODEL
+
+class QDirModelPrivate;
+
+class Q_WIDGETS_EXPORT QDirModel : public QAbstractItemModel
+{
+ Q_OBJECT
+ Q_PROPERTY(bool resolveSymlinks READ resolveSymlinks WRITE setResolveSymlinks)
+ Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly)
+ Q_PROPERTY(bool lazyChildCount READ lazyChildCount WRITE setLazyChildCount)
+
+public:
+ enum Roles {
+ FileIconRole = Qt::DecorationRole,
+ FilePathRole = Qt::UserRole + 1,
+ FileNameRole
+ };
+
+ QDirModel(const QStringList &nameFilters, QDir::Filters filters,
+ QDir::SortFlags sort, QObject *parent = 0);
+ explicit QDirModel(QObject *parent = 0);
+ ~QDirModel();
+
+ QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
+ QModelIndex parent(const QModelIndex &child) const;
+
+ int rowCount(const QModelIndex &parent = QModelIndex()) const;
+ int columnCount(const QModelIndex &parent = QModelIndex()) const;
+
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+ bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
+
+ QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
+
+ bool hasChildren(const QModelIndex &index = QModelIndex()) const;
+ Qt::ItemFlags flags(const QModelIndex &index) const;
+
+ void sort(int column, Qt::SortOrder order = Qt::AscendingOrder);
+
+ QStringList mimeTypes() const;
+ QMimeData *mimeData(const QModelIndexList &indexes) const;
+ bool dropMimeData(const QMimeData *data, Qt::DropAction action,
+ int row, int column, const QModelIndex &parent);
+ Qt::DropActions supportedDropActions() const;
+
+ // QDirModel specific API
+
+ void setIconProvider(QFileIconProvider *provider);
+ QFileIconProvider *iconProvider() const;
+
+ void setNameFilters(const QStringList &filters);
+ QStringList nameFilters() const;
+
+ void setFilter(QDir::Filters filters);
+ QDir::Filters filter() const;
+
+ void setSorting(QDir::SortFlags sort);
+ QDir::SortFlags sorting() const;
+
+ void setResolveSymlinks(bool enable);
+ bool resolveSymlinks() const;
+
+ void setReadOnly(bool enable);
+ bool isReadOnly() const;
+
+ void setLazyChildCount(bool enable);
+ bool lazyChildCount() const;
+
+ QModelIndex index(const QString &path, int column = 0) const;
+
+ bool isDir(const QModelIndex &index) const;
+ QModelIndex mkdir(const QModelIndex &parent, const QString &name);
+ bool rmdir(const QModelIndex &index);
+ bool remove(const QModelIndex &index);
+
+ QString filePath(const QModelIndex &index) const;
+ QString fileName(const QModelIndex &index) const;
+ QIcon fileIcon(const QModelIndex &index) const;
+ QFileInfo fileInfo(const QModelIndex &index) const;
+
+#ifdef Q_NO_USING_KEYWORD
+ inline QObject *parent() const { return QObject::parent(); }
+#else
+ using QObject::parent;
+#endif
+
+public Q_SLOTS:
+ void refresh(const QModelIndex &parent = QModelIndex());
+
+protected:
+ QDirModel(QDirModelPrivate &, QObject *parent = 0);
+ friend class QFileDialogPrivate;
+
+private:
+ Q_DECLARE_PRIVATE(QDirModel)
+ Q_DISABLE_COPY(QDirModel)
+ Q_PRIVATE_SLOT(d_func(), void _q_refresh())
+};
+
+#endif // QT_NO_DIRMODEL
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QDIRMODEL_H
diff --git a/src/gui/itemviews/qfileiconprovider.cpp b/src/widgets/itemviews/qfileiconprovider.cpp
index 84081c5439..84081c5439 100644
--- a/src/gui/itemviews/qfileiconprovider.cpp
+++ b/src/widgets/itemviews/qfileiconprovider.cpp
diff --git a/src/widgets/itemviews/qfileiconprovider.h b/src/widgets/itemviews/qfileiconprovider.h
new file mode 100644
index 0000000000..fcaaa9f78e
--- /dev/null
+++ b/src/widgets/itemviews/qfileiconprovider.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QFILEICONPROVIDER_H
+#define QFILEICONPROVIDER_H
+
+#include <QtCore/qfileinfo.h>
+#include <QtCore/qscopedpointer.h>
+#include <QtWidgets/qicon.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_FILEICONPROVIDER
+
+class QFileIconProviderPrivate;
+
+class Q_WIDGETS_EXPORT QFileIconProvider
+{
+public:
+ QFileIconProvider();
+ virtual ~QFileIconProvider();
+ enum IconType { Computer, Desktop, Trashcan, Network, Drive, Folder, File };
+ virtual QIcon icon(IconType type) const;
+ virtual QIcon icon(const QFileInfo &info) const;
+ virtual QString type(const QFileInfo &info) const;
+
+private:
+ Q_DECLARE_PRIVATE(QFileIconProvider)
+ QScopedPointer<QFileIconProviderPrivate> d_ptr;
+ Q_DISABLE_COPY(QFileIconProvider)
+};
+
+#endif // QT_NO_FILEICONPROVIDER
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QFILEICONPROVIDER_H
+
diff --git a/src/gui/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp
index 8b3c6e80f7..8b3c6e80f7 100644
--- a/src/gui/itemviews/qheaderview.cpp
+++ b/src/widgets/itemviews/qheaderview.cpp
diff --git a/src/widgets/itemviews/qheaderview.h b/src/widgets/itemviews/qheaderview.h
new file mode 100644
index 0000000000..c9793759a1
--- /dev/null
+++ b/src/widgets/itemviews/qheaderview.h
@@ -0,0 +1,250 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QHEADERVIEW_H
+#define QHEADERVIEW_H
+
+#include <QtWidgets/qabstractitemview.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_ITEMVIEWS
+
+class QHeaderViewPrivate;
+class QStyleOptionHeader;
+
+class Q_WIDGETS_EXPORT QHeaderView : public QAbstractItemView
+{
+ Q_OBJECT
+ Q_PROPERTY(bool showSortIndicator READ isSortIndicatorShown WRITE setSortIndicatorShown)
+ Q_PROPERTY(bool highlightSections READ highlightSections WRITE setHighlightSections)
+ Q_PROPERTY(bool stretchLastSection READ stretchLastSection WRITE setStretchLastSection)
+ Q_PROPERTY(bool cascadingSectionResizes READ cascadingSectionResizes WRITE setCascadingSectionResizes)
+ Q_PROPERTY(int defaultSectionSize READ defaultSectionSize WRITE setDefaultSectionSize)
+ Q_PROPERTY(int minimumSectionSize READ minimumSectionSize WRITE setMinimumSectionSize)
+ Q_PROPERTY(Qt::Alignment defaultAlignment READ defaultAlignment WRITE setDefaultAlignment)
+ Q_ENUMS(ResizeMode)
+
+public:
+
+ enum ResizeMode
+ {
+ Interactive,
+ Stretch,
+ Fixed,
+ ResizeToContents,
+ Custom = Fixed
+ };
+
+ explicit QHeaderView(Qt::Orientation orientation, QWidget *parent = 0);
+ virtual ~QHeaderView();
+
+ void setModel(QAbstractItemModel *model);
+
+ Qt::Orientation orientation() const;
+ int offset() const;
+ int length() const;
+ QSize sizeHint() const;
+ int sectionSizeHint(int logicalIndex) const;
+
+ int visualIndexAt(int position) const;
+ int logicalIndexAt(int position) const;
+
+ inline int logicalIndexAt(int x, int y) const;
+ inline int logicalIndexAt(const QPoint &pos) const;
+
+ int sectionSize(int logicalIndex) const;
+ int sectionPosition(int logicalIndex) const;
+ int sectionViewportPosition(int logicalIndex) const;
+
+ void moveSection(int from, int to);
+ void swapSections(int first, int second);
+ void resizeSection(int logicalIndex, int size);
+ void resizeSections(QHeaderView::ResizeMode mode);
+
+ bool isSectionHidden(int logicalIndex) const;
+ void setSectionHidden(int logicalIndex, bool hide);
+ int hiddenSectionCount() const;
+
+ inline void hideSection(int logicalIndex);
+ inline void showSection(int logicalIndex);
+
+ int count() const;
+ int visualIndex(int logicalIndex) const;
+ int logicalIndex(int visualIndex) const;
+
+ void setMovable(bool movable);
+ bool isMovable() const;
+
+ void setClickable(bool clickable);
+ bool isClickable() const;
+
+ void setHighlightSections(bool highlight);
+ bool highlightSections() const;
+
+ void setResizeMode(ResizeMode mode);
+ void setResizeMode(int logicalIndex, ResizeMode mode);
+ ResizeMode resizeMode(int logicalIndex) const;
+ int stretchSectionCount() const;
+
+ void setSortIndicatorShown(bool show);
+ bool isSortIndicatorShown() const;
+
+ void setSortIndicator(int logicalIndex, Qt::SortOrder order);
+ int sortIndicatorSection() const;
+ Qt::SortOrder sortIndicatorOrder() const;
+
+ bool stretchLastSection() const;
+ void setStretchLastSection(bool stretch);
+
+ bool cascadingSectionResizes() const;
+ void setCascadingSectionResizes(bool enable);
+
+ int defaultSectionSize() const;
+ void setDefaultSectionSize(int size);
+
+ int minimumSectionSize() const;
+ void setMinimumSectionSize(int size);
+
+ Qt::Alignment defaultAlignment() const;
+ void setDefaultAlignment(Qt::Alignment alignment);
+
+ void doItemsLayout();
+ bool sectionsMoved() const;
+ bool sectionsHidden() const;
+
+#ifndef QT_NO_DATASTREAM
+ QByteArray saveState() const;
+ bool restoreState(const QByteArray &state);
+#endif
+
+ void reset();
+
+public Q_SLOTS:
+ void setOffset(int offset);
+ void setOffsetToSectionPosition(int visualIndex);
+ void setOffsetToLastSection();
+ void headerDataChanged(Qt::Orientation orientation, int logicalFirst, int logicalLast);
+
+Q_SIGNALS:
+ void sectionMoved(int logicalIndex, int oldVisualIndex, int newVisualIndex);
+ void sectionResized(int logicalIndex, int oldSize, int newSize);
+ void sectionPressed(int logicalIndex);
+ void sectionClicked(int logicalIndex);
+ void sectionEntered(int logicalIndex);
+ void sectionDoubleClicked(int logicalIndex);
+ void sectionCountChanged(int oldCount, int newCount);
+ void sectionHandleDoubleClicked(int logicalIndex);
+ void sectionAutoResize(int logicalIndex, QHeaderView::ResizeMode mode);
+ void geometriesChanged();
+ void sortIndicatorChanged(int logicalIndex, Qt::SortOrder order);
+
+protected Q_SLOTS:
+ void updateSection(int logicalIndex);
+ void resizeSections();
+ void sectionsInserted(const QModelIndex &parent, int logicalFirst, int logicalLast);
+ void sectionsAboutToBeRemoved(const QModelIndex &parent, int logicalFirst, int logicalLast);
+
+protected:
+ QHeaderView(QHeaderViewPrivate &dd, Qt::Orientation orientation, QWidget *parent = 0);
+ void initialize();
+
+ void initializeSections();
+ void initializeSections(int start, int end);
+ void currentChanged(const QModelIndex &current, const QModelIndex &old);
+
+ bool event(QEvent *e);
+ void paintEvent(QPaintEvent *e);
+ void mousePressEvent(QMouseEvent *e);
+ void mouseMoveEvent(QMouseEvent *e);
+ void mouseReleaseEvent(QMouseEvent *e);
+ void mouseDoubleClickEvent(QMouseEvent *e);
+ bool viewportEvent(QEvent *e);
+
+ virtual void paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const;
+ virtual QSize sectionSizeFromContents(int logicalIndex) const;
+
+ int horizontalOffset() const;
+ int verticalOffset() const;
+ void updateGeometries();
+ void scrollContentsBy(int dx, int dy);
+
+ void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
+ void rowsInserted(const QModelIndex &parent, int start, int end);
+
+ QRect visualRect(const QModelIndex &index) const;
+ void scrollTo(const QModelIndex &index, ScrollHint hint);
+
+ QModelIndex indexAt(const QPoint &p) const;
+ bool isIndexHidden(const QModelIndex &index) const;
+
+ QModelIndex moveCursor(CursorAction, Qt::KeyboardModifiers);
+ void setSelection(const QRect& rect, QItemSelectionModel::SelectionFlags flags);
+ QRegion visualRegionForSelection(const QItemSelection &selection) const;
+ void initStyleOption(QStyleOptionHeader *option) const;
+
+private:
+ Q_PRIVATE_SLOT(d_func(), void _q_sectionsRemoved(const QModelIndex &parent, int logicalFirst, int logicalLast))
+ Q_PRIVATE_SLOT(d_func(), void _q_layoutAboutToBeChanged())
+ Q_DECLARE_PRIVATE(QHeaderView)
+ Q_DISABLE_COPY(QHeaderView)
+};
+
+inline int QHeaderView::logicalIndexAt(int ax, int ay) const
+{ return orientation() == Qt::Horizontal ? logicalIndexAt(ax) : logicalIndexAt(ay); }
+inline int QHeaderView::logicalIndexAt(const QPoint &apos) const
+{ return logicalIndexAt(apos.x(), apos.y()); }
+inline void QHeaderView::hideSection(int alogicalIndex)
+{ setSectionHidden(alogicalIndex, true); }
+inline void QHeaderView::showSection(int alogicalIndex)
+{ setSectionHidden(alogicalIndex, false); }
+
+#endif // QT_NO_ITEMVIEWS
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QHEADERVIEW_H
diff --git a/src/widgets/itemviews/qheaderview_p.h b/src/widgets/itemviews/qheaderview_p.h
new file mode 100644
index 0000000000..b2b8d686b5
--- /dev/null
+++ b/src/widgets/itemviews/qheaderview_p.h
@@ -0,0 +1,366 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QHEADERVIEW_P_H
+#define QHEADERVIEW_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "private/qabstractitemview_p.h"
+
+#ifndef QT_NO_ITEMVIEWS
+
+#include "QtCore/qbitarray.h"
+#include "QtWidgets/qapplication.h"
+#include "QtWidgets/qlabel.h"
+
+QT_BEGIN_NAMESPACE
+
+class QHeaderViewPrivate: public QAbstractItemViewPrivate
+{
+ Q_DECLARE_PUBLIC(QHeaderView)
+
+public:
+ enum StateVersion { VersionMarker = 0xff };
+
+ QHeaderViewPrivate()
+ : state(NoState),
+ offset(0),
+ sortIndicatorOrder(Qt::DescendingOrder),
+ sortIndicatorSection(0),
+ sortIndicatorShown(false),
+ lastPos(-1),
+ firstPos(-1),
+ originalSize(-1),
+ section(-1),
+ target(-1),
+ pressed(-1),
+ hover(-1),
+ length(0),
+ sectionCount(0),
+ movableSections(false),
+ clickableSections(false),
+ highlightSelected(false),
+ stretchLastSection(false),
+ cascadingResizing(false),
+ resizeRecursionBlock(false),
+ stretchSections(0),
+ contentsSections(0),
+ minimumSectionSize(-1),
+ lastSectionSize(0),
+ sectionIndicatorOffset(0),
+ sectionIndicator(0),
+ globalResizeMode(QHeaderView::Interactive)
+ {}
+
+
+ int lastVisibleVisualIndex() const;
+ int sectionHandleAt(int position);
+ void setupSectionIndicator(int section, int position);
+ void updateSectionIndicator(int section, int position);
+ void updateHiddenSections(int logicalFirst, int logicalLast);
+ void resizeSections(QHeaderView::ResizeMode globalMode, bool useGlobalMode = false);
+ void _q_sectionsRemoved(const QModelIndex &,int,int);
+ void _q_layoutAboutToBeChanged();
+ void _q_layoutChanged();
+
+ bool isSectionSelected(int section) const;
+
+ inline bool rowIntersectsSelection(int row) const {
+ return (selectionModel ? selectionModel->rowIntersectsSelection(row, root) : false);
+ }
+
+ inline bool columnIntersectsSelection(int column) const {
+ return (selectionModel ? selectionModel->columnIntersectsSelection(column, root) : false);
+ }
+
+ inline bool sectionIntersectsSelection(int logical) const {
+ return (orientation == Qt::Horizontal ? columnIntersectsSelection(logical) : rowIntersectsSelection(logical));
+ }
+
+ inline bool isRowSelected(int row) const {
+ return (selectionModel ? selectionModel->isRowSelected(row, root) : false);
+ }
+
+ inline bool isColumnSelected(int column) const {
+ return (selectionModel ? selectionModel->isColumnSelected(column, root) : false);
+ }
+
+ inline void prepareSectionSelected() {
+ if (!selectionModel || !selectionModel->hasSelection())
+ sectionSelected.clear();
+ else if (sectionSelected.count() != sectionCount * 2)
+ sectionSelected.fill(false, sectionCount * 2);
+ else sectionSelected.fill(false);
+ }
+
+ inline bool reverse() const {
+ return orientation == Qt::Horizontal && q_func()->isRightToLeft();
+ }
+
+ inline int logicalIndex(int visualIndex) const {
+ return logicalIndices.isEmpty() ? visualIndex : logicalIndices.at(visualIndex);
+ }
+
+ inline int visualIndex(int logicalIndex) const {
+ return visualIndices.isEmpty() ? logicalIndex : visualIndices.at(logicalIndex);
+ }
+
+ inline void setDefaultValues(Qt::Orientation o) {
+ orientation = o;
+ defaultSectionSize = (o == Qt::Horizontal ? 100
+ : qMax(q_func()->minimumSectionSize(), 30));
+ defaultAlignment = (o == Qt::Horizontal
+ ? Qt::Alignment(Qt::AlignCenter)
+ : Qt::AlignLeft|Qt::AlignVCenter);
+ }
+
+ inline bool isVisualIndexHidden(int visual) const {
+ return !sectionHidden.isEmpty() && sectionHidden.at(visual);
+ }
+
+ inline void setVisualIndexHidden(int visual, bool hidden) {
+ if (!sectionHidden.isEmpty()) sectionHidden.setBit(visual, hidden);
+ }
+
+ inline bool hasAutoResizeSections() const {
+ return stretchSections || stretchLastSection || contentsSections;
+ }
+
+ QStyleOptionHeader getStyleOption() const;
+
+ inline void invalidateCachedSizeHint() const {
+ cachedSizeHint = QSize();
+ }
+
+ inline void initializeIndexMapping() const {
+ if (visualIndices.count() != sectionCount
+ || logicalIndices.count() != sectionCount) {
+ visualIndices.resize(sectionCount);
+ logicalIndices.resize(sectionCount);
+ for (int s = 0; s < sectionCount; ++s) {
+ visualIndices[s] = s;
+ logicalIndices[s] = s;
+ }
+ }
+ }
+
+ inline void clearCascadingSections() {
+ firstCascadingSection = sectionCount;
+ lastCascadingSection = 0;
+ cascadingSectionSize.clear();
+ }
+
+ inline void saveCascadingSectionSize(int visual, int size) {
+ if (!cascadingSectionSize.contains(visual)) {
+ cascadingSectionSize.insert(visual, size);
+ firstCascadingSection = qMin(firstCascadingSection, visual);
+ lastCascadingSection = qMax(lastCascadingSection, visual);
+ }
+ }
+
+ inline bool sectionIsCascadable(int visual) const {
+ return headerSectionResizeMode(visual) == QHeaderView::Interactive;
+ }
+
+ inline int modelSectionCount() const {
+ return (orientation == Qt::Horizontal
+ ? model->columnCount(root)
+ : model->rowCount(root));
+ }
+
+ inline bool modelIsEmpty() const {
+ return (model->rowCount(root) == 0 || model->columnCount(root) == 0);
+ }
+
+ inline void doDelayedResizeSections() {
+ if (!delayedResize.isActive())
+ delayedResize.start(0, q_func());
+ }
+
+ inline void executePostedResize() const {
+ if (delayedResize.isActive() && state == NoState) {
+ const_cast<QHeaderView*>(q_func())->resizeSections();
+ }
+ }
+
+ void clear();
+ void flipSortIndicator(int section);
+ void cascadingResize(int visual, int newSize);
+
+ enum State { NoState, ResizeSection, MoveSection, SelectSections, NoClear } state;
+
+ int offset;
+ Qt::Orientation orientation;
+ Qt::SortOrder sortIndicatorOrder;
+ int sortIndicatorSection;
+ bool sortIndicatorShown;
+
+ mutable QVector<int> visualIndices; // visualIndex = visualIndices.at(logicalIndex)
+ mutable QVector<int> logicalIndices; // logicalIndex = row or column in the model
+ mutable QBitArray sectionSelected; // from logical index to bit
+ mutable QBitArray sectionHidden; // from visual index to bit
+ mutable QHash<int, int> hiddenSectionSize; // from logical index to section size
+ mutable QHash<int, int> cascadingSectionSize; // from visual index to section size
+ mutable QSize cachedSizeHint;
+ mutable QBasicTimer delayedResize;
+
+ int firstCascadingSection;
+ int lastCascadingSection;
+
+ int lastPos;
+ int firstPos;
+ int originalSize;
+ int section; // used for resizing and moving sections
+ int target;
+ int pressed;
+ int hover;
+
+ int length;
+ int sectionCount;
+ bool movableSections;
+ bool clickableSections;
+ bool highlightSelected;
+ bool stretchLastSection;
+ bool cascadingResizing;
+ bool resizeRecursionBlock;
+ int stretchSections;
+ int contentsSections;
+ int defaultSectionSize;
+ int minimumSectionSize;
+ int lastSectionSize; // $$$
+ int sectionIndicatorOffset;
+ Qt::Alignment defaultAlignment;
+ QLabel *sectionIndicator;
+ QHeaderView::ResizeMode globalResizeMode;
+ QList<QPersistentModelIndex> persistentHiddenSections;
+
+ // header section spans
+
+ struct SectionSpan {
+ int size;
+ int count;
+ QHeaderView::ResizeMode resizeMode;
+ inline SectionSpan() : size(0), count(0), resizeMode(QHeaderView::Interactive) {}
+ inline SectionSpan(int length, int sections, QHeaderView::ResizeMode mode)
+ : size(length), count(sections), resizeMode(mode) {}
+ inline int sectionSize() const { return (count > 0 ? size / count : 0); }
+#ifndef QT_NO_DATASTREAM
+ inline void write(QDataStream &out) const
+ { out << size; out << count; out << (int)resizeMode; }
+ inline void read(QDataStream &in)
+ { in >> size; in >> count; int m; in >> m; resizeMode = (QHeaderView::ResizeMode)m; }
+#endif
+ };
+
+ QVector<SectionSpan> sectionSpans;
+
+ void createSectionSpan(int start, int end, int size, QHeaderView::ResizeMode mode);
+ void removeSectionsFromSpans(int start, int end);
+ void resizeSectionSpan(int visualIndex, int oldSize, int newSize);
+ void setDefaultSectionSize(int size);
+
+ inline int headerSectionCount() const { // for debugging
+ int count = 0;
+ for (int i = 0; i < sectionSpans.count(); ++i)
+ count += sectionSpans.at(i).count;
+ return count;
+ }
+
+ inline int headerLength() const { // for debugging
+ int len = 0;
+ for (int i = 0; i < sectionSpans.count(); ++i)
+ len += sectionSpans.at(i).size;
+ return len;
+ }
+
+ inline void removeSpans(const QList<int> &spans) {
+ for (int i = spans.count() - 1; i >= 0; --i) {
+ length -= sectionSpans.at(spans.at(i)).size;
+ sectionSpans.remove(spans.at(i));
+ }
+ }
+
+ inline int sectionSpanIndex(int visual) const {
+ int section_start = 0;
+ for (int i = 0; i < sectionSpans.count(); ++i) {
+ int section_end = section_start + sectionSpans.at(i).count - 1;
+ if (visual >= section_start && visual <= section_end)
+ return i;
+ section_start = section_end + 1;
+ }
+ return -1;
+ }
+
+ int headerSectionSize(int visual) const;
+ int headerSectionPosition(int visual) const;
+ int headerVisualIndexAt(int position) const;
+
+ // resize mode
+ void setHeaderSectionResizeMode(int visual, QHeaderView::ResizeMode mode);
+ QHeaderView::ResizeMode headerSectionResizeMode(int visual) const;
+ void setGlobalHeaderResizeMode(QHeaderView::ResizeMode mode);
+
+ // other
+ int viewSectionSizeHint(int logical) const;
+ int adjustedVisualIndex(int visualIndex) const;
+
+#ifndef QT_NO_DATASTREAM
+ void write(QDataStream &out) const;
+ bool read(QDataStream &in);
+#endif
+
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_ITEMVIEWS
+
+#endif // QHEADERVIEW_P_H
diff --git a/src/gui/itemviews/qidentityproxymodel.cpp b/src/widgets/itemviews/qidentityproxymodel.cpp
index ee36b8319f..ee36b8319f 100644
--- a/src/gui/itemviews/qidentityproxymodel.cpp
+++ b/src/widgets/itemviews/qidentityproxymodel.cpp
diff --git a/src/widgets/itemviews/qidentityproxymodel.h b/src/widgets/itemviews/qidentityproxymodel.h
new file mode 100644
index 0000000000..8a8422244f
--- /dev/null
+++ b/src/widgets/itemviews/qidentityproxymodel.h
@@ -0,0 +1,120 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Stephen Kelly <stephen.kelly@kdab.com>
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QIDENTITYPROXYMODEL_H
+#define QIDENTITYPROXYMODEL_H
+
+#include <QtWidgets/qabstractproxymodel.h>
+
+#ifndef QT_NO_IDENTITYPROXYMODEL
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QIdentityProxyModelPrivate;
+
+class Q_WIDGETS_EXPORT QIdentityProxyModel : public QAbstractProxyModel
+{
+ Q_OBJECT
+public:
+ explicit QIdentityProxyModel(QObject* parent = 0);
+ ~QIdentityProxyModel();
+
+ int columnCount(const QModelIndex& parent = QModelIndex()) const;
+ QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const;
+ QModelIndex mapFromSource(const QModelIndex& sourceIndex) const;
+ QModelIndex mapToSource(const QModelIndex& proxyIndex) const;
+ QModelIndex parent(const QModelIndex& child) const;
+ int rowCount(const QModelIndex& parent = QModelIndex()) const;
+ bool dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent);
+
+ QItemSelection mapSelectionFromSource(const QItemSelection& selection) const;
+ QItemSelection mapSelectionToSource(const QItemSelection& selection) const;
+ QModelIndexList match(const QModelIndex& start, int role, const QVariant& value, int hits = 1, Qt::MatchFlags flags = Qt::MatchFlags(Qt::MatchStartsWith|Qt::MatchWrap)) const;
+ void setSourceModel(QAbstractItemModel* sourceModel);
+
+ bool insertColumns(int column, int count, const QModelIndex& parent = QModelIndex());
+ bool insertRows(int row, int count, const QModelIndex& parent = QModelIndex());
+ bool removeColumns(int column, int count, const QModelIndex& parent = QModelIndex());
+ bool removeRows(int row, int count, const QModelIndex& parent = QModelIndex());
+
+protected:
+ QIdentityProxyModel(QIdentityProxyModelPrivate &dd, QObject* parent);
+
+private:
+ Q_DECLARE_PRIVATE(QIdentityProxyModel)
+ Q_DISABLE_COPY(QIdentityProxyModel)
+
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsAboutToBeInserted(QModelIndex,int,int))
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsInserted(QModelIndex,int,int))
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsAboutToBeRemoved(QModelIndex,int,int))
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsRemoved(QModelIndex,int,int))
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int))
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsMoved(QModelIndex,int,int,QModelIndex,int))
+
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsAboutToBeInserted(QModelIndex,int,int))
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsInserted(QModelIndex,int,int))
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsAboutToBeRemoved(QModelIndex,int,int))
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsRemoved(QModelIndex,int,int))
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int))
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsMoved(QModelIndex,int,int,QModelIndex,int))
+
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceDataChanged(QModelIndex,QModelIndex))
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceHeaderDataChanged(Qt::Orientation orientation, int first, int last))
+
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceLayoutAboutToBeChanged())
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceLayoutChanged())
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceModelAboutToBeReset())
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceModelReset())
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QT_NO_IDENTITYPROXYMODEL
+
+#endif // QIDENTITYPROXYMODEL_H
+
diff --git a/src/widgets/itemviews/qitemdelegate.cpp b/src/widgets/itemviews/qitemdelegate.cpp
new file mode 100644
index 0000000000..a2da62ac83
--- /dev/null
+++ b/src/widgets/itemviews/qitemdelegate.cpp
@@ -0,0 +1,1341 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qitemdelegate.h"
+
+#ifndef QT_NO_ITEMVIEWS
+#include <qabstractitemmodel.h>
+#include <qapplication.h>
+#include <qbrush.h>
+#include <qlineedit.h>
+#include <qtextedit.h>
+#include <qplaintextedit.h>
+#include <qpainter.h>
+#include <qpalette.h>
+#include <qpoint.h>
+#include <qrect.h>
+#include <qsize.h>
+#include <qstyle.h>
+#include <qdatetime.h>
+#include <qstyleoption.h>
+#include <qevent.h>
+#include <qpixmap.h>
+#include <qbitmap.h>
+#include <qpixmapcache.h>
+#include <qitemeditorfactory.h>
+#include <qmetaobject.h>
+#include <qtextlayout.h>
+#include <private/qobject_p.h>
+#include <private/qdnd_p.h>
+#include <private/qtextengine_p.h>
+#include <qdebug.h>
+#include <qlocale.h>
+#include <qdialog.h>
+#include <qmath.h>
+
+#include <limits.h>
+
+#ifndef DBL_DIG
+# define DBL_DIG 10
+#endif
+
+QT_BEGIN_NAMESPACE
+
+class QItemDelegatePrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QItemDelegate)
+
+public:
+ QItemDelegatePrivate() : f(0), clipPainting(true) {}
+
+ inline const QItemEditorFactory *editorFactory() const
+ { return f ? f : QItemEditorFactory::defaultFactory(); }
+
+ inline QIcon::Mode iconMode(QStyle::State state) const
+ {
+ if (!(state & QStyle::State_Enabled)) return QIcon::Disabled;
+ if (state & QStyle::State_Selected) return QIcon::Selected;
+ return QIcon::Normal;
+ }
+
+ inline QIcon::State iconState(QStyle::State state) const
+ { return state & QStyle::State_Open ? QIcon::On : QIcon::Off; }
+
+ inline static QString replaceNewLine(QString text)
+ {
+ const QChar nl = QLatin1Char('\n');
+ for (int i = 0; i < text.count(); ++i)
+ if (text.at(i) == nl)
+ text[i] = QChar::LineSeparator;
+ return text;
+ }
+
+ static QString valueToText(const QVariant &value, const QStyleOptionViewItemV4 &option);
+
+ void _q_commitDataAndCloseEditor(QWidget *editor);
+
+ QItemEditorFactory *f;
+ bool clipPainting;
+
+ QRect textLayoutBounds(const QStyleOptionViewItemV2 &options) const;
+ QSizeF doTextLayout(int lineWidth) const;
+ mutable QTextLayout textLayout;
+ mutable QTextOption textOption;
+
+ const QWidget *widget(const QStyleOptionViewItem &option) const
+ {
+ if (const QStyleOptionViewItemV3 *v3 = qstyleoption_cast<const QStyleOptionViewItemV3 *>(&option))
+ return v3->widget;
+
+ return 0;
+ }
+
+ // ### temporary hack until we have QStandardItemDelegate
+ mutable struct Icon {
+ QIcon icon;
+ QIcon::Mode mode;
+ QIcon::State state;
+ } tmp;
+};
+
+void QItemDelegatePrivate::_q_commitDataAndCloseEditor(QWidget *editor)
+{
+ Q_Q(QItemDelegate);
+ emit q->commitData(editor);
+ emit q->closeEditor(editor, QAbstractItemDelegate::SubmitModelCache);
+}
+
+QRect QItemDelegatePrivate::textLayoutBounds(const QStyleOptionViewItemV2 &option) const
+{
+ QRect rect = option.rect;
+ const bool wrapText = option.features & QStyleOptionViewItemV2::WrapText;
+ switch (option.decorationPosition) {
+ case QStyleOptionViewItem::Left:
+ case QStyleOptionViewItem::Right:
+ rect.setWidth(wrapText && rect.isValid() ? rect.width() : (QFIXED_MAX));
+ break;
+ case QStyleOptionViewItem::Top:
+ case QStyleOptionViewItem::Bottom:
+ rect.setWidth(wrapText ? option.decorationSize.width() : (QFIXED_MAX));
+ break;
+ }
+
+ return rect;
+}
+
+QSizeF QItemDelegatePrivate::doTextLayout(int lineWidth) const
+{
+ qreal height = 0;
+ qreal widthUsed = 0;
+ textLayout.beginLayout();
+ while (true) {
+ QTextLine line = textLayout.createLine();
+ if (!line.isValid())
+ break;
+ line.setLineWidth(lineWidth);
+ line.setPosition(QPointF(0, height));
+ height += line.height();
+ widthUsed = qMax(widthUsed, line.naturalTextWidth());
+ }
+ textLayout.endLayout();
+ return QSizeF(widthUsed, height);
+}
+
+/*!
+ \class QItemDelegate
+
+ \brief The QItemDelegate class provides display and editing facilities for
+ data items from a model.
+
+ \ingroup model-view
+
+
+ QItemDelegate can be used to provide custom display features and editor
+ widgets for item views based on QAbstractItemView subclasses. Using a
+ delegate for this purpose allows the display and editing mechanisms to be
+ customized and developed independently from the model and view.
+
+ The QItemDelegate class is one of the \l{Model/View Classes} and
+ is part of Qt's \l{Model/View Programming}{model/view framework}.
+ Note that QStyledItemDelegate has taken over the job of drawing
+ Qt's item views. We recommend the use of QStyledItemDelegate when
+ creating new delegates.
+
+ When displaying items from a custom model in a standard view, it is
+ often sufficient to simply ensure that the model returns appropriate
+ data for each of the \l{Qt::ItemDataRole}{roles} that determine the
+ appearance of items in views. The default delegate used by Qt's
+ standard views uses this role information to display items in most
+ of the common forms expected by users. However, it is sometimes
+ necessary to have even more control over the appearance of items than
+ the default delegate can provide.
+
+ This class provides default implementations of the functions for
+ painting item data in a view and editing data from item models.
+ Default implementations of the paint() and sizeHint() virtual
+ functions, defined in QAbstractItemDelegate, are provided to
+ ensure that the delegate implements the correct basic behavior
+ expected by views. You can reimplement these functions in
+ subclasses to customize the appearance of items.
+
+ When editing data in an item view, QItemDelegate provides an
+ editor widget, which is a widget that is placed on top of the view
+ while editing takes place. Editors are created with a
+ QItemEditorFactory; a default static instance provided by
+ QItemEditorFactory is installed on all item delegates. You can set
+ a custom factory using setItemEditorFactory() or set a new default
+ factory with QItemEditorFactory::setDefaultFactory(). It is the
+ data stored in the item model with the Qt::EditRole that is edited.
+
+ Only the standard editing functions for widget-based delegates are
+ reimplemented here:
+
+ \list
+ \o createEditor() returns the widget used to change data from the model
+ and can be reimplemented to customize editing behavior.
+ \o setEditorData() provides the widget with data to manipulate.
+ \o updateEditorGeometry() ensures that the editor is displayed correctly
+ with respect to the item view.
+ \o setModelData() returns updated data to the model.
+ \endlist
+
+ The closeEditor() signal indicates that the user has completed editing the data,
+ and that the editor widget can be destroyed.
+
+ \section1 Standard Roles and Data Types
+
+ The default delegate used by the standard views supplied with Qt
+ associates each standard role (defined by Qt::ItemDataRole) with certain
+ data types. Models that return data in these types can influence the
+ appearance of the delegate as described in the following table.
+
+ \table
+ \header \o Role \o Accepted Types
+ \omit
+ \row \o \l Qt::AccessibleDescriptionRole \o QString
+ \row \o \l Qt::AccessibleTextRole \o QString
+ \endomit
+ \row \o \l Qt::BackgroundRole \o QBrush
+ \row \o \l Qt::BackgroundColorRole \o QColor (obsolete; use Qt::BackgroundRole instead)
+ \row \o \l Qt::CheckStateRole \o Qt::CheckState
+ \row \o \l Qt::DecorationRole \o QIcon, QPixmap and QColor
+ \row \o \l Qt::DisplayRole \o QString and types with a string representation
+ \row \o \l Qt::EditRole \o See QItemEditorFactory for details
+ \row \o \l Qt::FontRole \o QFont
+ \row \o \l Qt::SizeHintRole \o QSize
+ \omit
+ \row \o \l Qt::StatusTipRole \o
+ \endomit
+ \row \o \l Qt::TextAlignmentRole \o Qt::Alignment
+ \row \o \l Qt::ForegroundRole \o QBrush
+ \row \o \l Qt::TextColorRole \o QColor (obsolete; use Qt::ForegroundRole instead)
+ \omit
+ \row \o \l Qt::ToolTipRole
+ \row \o \l Qt::WhatsThisRole
+ \endomit
+ \endtable
+
+ If the default delegate does not allow the level of customization that
+ you need, either for display purposes or for editing data, it is possible to
+ subclass QItemDelegate to implement the desired behavior.
+
+ \section1 Subclassing
+
+ When subclassing QItemDelegate to create a delegate that displays items
+ using a custom renderer, it is important to ensure that the delegate can
+ render items suitably for all the required states; e.g. selected,
+ disabled, checked. The documentation for the paint() function contains
+ some hints to show how this can be achieved.
+
+ You can provide custom editors by using a QItemEditorFactory. The
+ \l{Color Editor Factory Example} shows how a custom editor can be
+ made available to delegates with the default item editor
+ factory. This way, there is no need to subclass QItemDelegate. An
+ alternative is to reimplement createEditor(), setEditorData(),
+ 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}
+*/
+
+/*!
+ Constructs an item delegate with the given \a parent.
+*/
+
+QItemDelegate::QItemDelegate(QObject *parent)
+ : QAbstractItemDelegate(*new QItemDelegatePrivate(), parent)
+{
+
+}
+
+/*!
+ Destroys the item delegate.
+*/
+
+QItemDelegate::~QItemDelegate()
+{
+}
+
+/*!
+ \property QItemDelegate::clipping
+ \brief if the delegate should clip the paint events
+ \since 4.2
+
+ This property will set the paint clip to the size of the item.
+ The default value is on. It is useful for cases such
+ as when images are larger than the size of the item.
+*/
+
+bool QItemDelegate::hasClipping() const
+{
+ Q_D(const QItemDelegate);
+ return d->clipPainting;
+}
+
+void QItemDelegate::setClipping(bool clip)
+{
+ Q_D(QItemDelegate);
+ d->clipPainting = clip;
+}
+
+QString QItemDelegatePrivate::valueToText(const QVariant &value, const QStyleOptionViewItemV4 &option)
+{
+ QString text;
+ switch (value.userType()) {
+ case QMetaType::Float:
+ text = option.locale.toString(value.toFloat(), 'g');
+ break;
+ case QVariant::Double:
+ text = option.locale.toString(value.toDouble(), 'g', DBL_DIG);
+ break;
+ case QVariant::Int:
+ case QVariant::LongLong:
+ text = option.locale.toString(value.toLongLong());
+ break;
+ case QVariant::UInt:
+ case QVariant::ULongLong:
+ text = option.locale.toString(value.toULongLong());
+ break;
+ case QVariant::Date:
+ text = option.locale.toString(value.toDate(), QLocale::ShortFormat);
+ break;
+ case QVariant::Time:
+ text = option.locale.toString(value.toTime(), QLocale::ShortFormat);
+ break;
+ case QVariant::DateTime:
+ text = option.locale.toString(value.toDateTime().date(), QLocale::ShortFormat);
+ text += QLatin1Char(' ');
+ text += option.locale.toString(value.toDateTime().time(), QLocale::ShortFormat);
+ break;
+ default:
+ text = replaceNewLine(value.toString());
+ break;
+ }
+ return text;
+}
+
+/*!
+ Renders the delegate using the given \a painter and style \a option for
+ the item specified by \a index.
+
+ When reimplementing this function in a subclass, you should update the area
+ held by the option's \l{QStyleOption::rect}{rect} variable, using the
+ option's \l{QStyleOption::state}{state} variable to determine the state of
+ the item to be displayed, and adjust the way it is painted accordingly.
+
+ For example, a selected item may need to be displayed differently to
+ unselected items, as shown in the following code:
+
+ \snippet examples/itemviews/pixelator/pixeldelegate.cpp 2
+ \dots
+
+ After painting, you should ensure that the painter is returned to its
+ the state it was supplied in when this function was called. For example,
+ it may be useful to call QPainter::save() before painting and
+ QPainter::restore() afterwards.
+
+ \sa QStyle::State
+*/
+void QItemDelegate::paint(QPainter *painter,
+ const QStyleOptionViewItem &option,
+ const QModelIndex &index) const
+{
+ Q_D(const QItemDelegate);
+ Q_ASSERT(index.isValid());
+
+ QStyleOptionViewItemV4 opt = setOptions(index, option);
+
+ const QStyleOptionViewItemV2 *v2 = qstyleoption_cast<const QStyleOptionViewItemV2 *>(&option);
+ opt.features = v2 ? v2->features
+ : QStyleOptionViewItemV2::ViewItemFeatures(QStyleOptionViewItemV2::None);
+ const QStyleOptionViewItemV3 *v3 = qstyleoption_cast<const QStyleOptionViewItemV3 *>(&option);
+ opt.locale = v3 ? v3->locale : QLocale();
+ opt.widget = v3 ? v3->widget : 0;
+
+ // prepare
+ painter->save();
+ if (d->clipPainting)
+ painter->setClipRect(opt.rect);
+
+ // get the data and the rectangles
+
+ QVariant value;
+
+ QPixmap pixmap;
+ QRect decorationRect;
+ value = index.data(Qt::DecorationRole);
+ if (value.isValid()) {
+ // ### we need the pixmap to call the virtual function
+ pixmap = decoration(opt, value);
+ if (value.type() == QVariant::Icon) {
+ d->tmp.icon = qvariant_cast<QIcon>(value);
+ d->tmp.mode = d->iconMode(option.state);
+ d->tmp.state = d->iconState(option.state);
+ const QSize size = d->tmp.icon.actualSize(option.decorationSize,
+ d->tmp.mode, d->tmp.state);
+ decorationRect = QRect(QPoint(0, 0), size);
+ } else {
+ d->tmp.icon = QIcon();
+ decorationRect = QRect(QPoint(0, 0), pixmap.size());
+ }
+ } else {
+ d->tmp.icon = QIcon();
+ decorationRect = QRect();
+ }
+
+ QString text;
+ QRect displayRect;
+ value = index.data(Qt::DisplayRole);
+ if (value.isValid() && !value.isNull()) {
+ text = QItemDelegatePrivate::valueToText(value, opt);
+ displayRect = textRectangle(painter, d->textLayoutBounds(opt), opt.font, text);
+ }
+
+ QRect checkRect;
+ Qt::CheckState checkState = Qt::Unchecked;
+ value = index.data(Qt::CheckStateRole);
+ if (value.isValid()) {
+ checkState = static_cast<Qt::CheckState>(value.toInt());
+ checkRect = check(opt, opt.rect, value);
+ }
+
+ // do the layout
+
+ doLayout(opt, &checkRect, &decorationRect, &displayRect, false);
+
+ // draw the item
+
+ drawBackground(painter, opt, index);
+ drawCheck(painter, opt, checkRect, checkState);
+ drawDecoration(painter, opt, decorationRect, pixmap);
+ drawDisplay(painter, opt, displayRect, text);
+ drawFocus(painter, opt, displayRect);
+
+ // done
+ painter->restore();
+}
+
+/*!
+ Returns the size needed by the delegate to display the item
+ specified by \a index, taking into account the style information
+ provided by \a option.
+
+ When reimplementing this function, note that in case of text
+ items, QItemDelegate adds a margin (i.e. 2 *
+ QStyle::PM_FocusFrameHMargin) to the length of the text.
+*/
+
+QSize QItemDelegate::sizeHint(const QStyleOptionViewItem &option,
+ const QModelIndex &index) const
+{
+ QVariant value = index.data(Qt::SizeHintRole);
+ if (value.isValid())
+ return qvariant_cast<QSize>(value);
+ QRect decorationRect = rect(option, index, Qt::DecorationRole);
+ QRect displayRect = rect(option, index, Qt::DisplayRole);
+ QRect checkRect = rect(option, index, Qt::CheckStateRole);
+
+ doLayout(option, &checkRect, &decorationRect, &displayRect, true);
+
+ return (decorationRect|displayRect|checkRect).size();
+}
+
+/*!
+ Returns the widget used to edit the item specified by \a index
+ for editing. The \a parent widget and style \a option are used to
+ control how the editor widget appears.
+
+ \sa QAbstractItemDelegate::createEditor()
+*/
+
+QWidget *QItemDelegate::createEditor(QWidget *parent,
+ const QStyleOptionViewItem &,
+ const QModelIndex &index) const
+{
+ Q_D(const QItemDelegate);
+ if (!index.isValid())
+ return 0;
+ QVariant::Type t = static_cast<QVariant::Type>(index.data(Qt::EditRole).userType());
+ const QItemEditorFactory *factory = d->f;
+ if (factory == 0)
+ factory = QItemEditorFactory::defaultFactory();
+ return factory->createEditor(t, parent);
+}
+
+/*!
+ Sets the data to be displayed and edited by the \a editor from the
+ data model item specified by the model \a index.
+
+ The default implementation stores the data in the \a editor
+ widget's \l {Qt's Property System} {user property}.
+
+ \sa QMetaProperty::isUser()
+*/
+
+void QItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
+{
+#ifdef QT_NO_PROPERTIES
+ Q_UNUSED(editor);
+ Q_UNUSED(index);
+#else
+ Q_D(const QItemDelegate);
+ QVariant v = index.data(Qt::EditRole);
+ QByteArray n = editor->metaObject()->userProperty().name();
+
+ // ### Qt 5: remove
+ // A work-around for missing "USER true" in qdatetimeedit.h for
+ // QTimeEdit's time property and QDateEdit's date property.
+ // It only triggers if the default user property "dateTime" is
+ // reported for QTimeEdit and QDateEdit.
+ if (n == "dateTime") {
+ if (editor->inherits("QTimeEdit"))
+ n = "time";
+ else if (editor->inherits("QDateEdit"))
+ n = "date";
+ }
+
+ // ### Qt 5: give QComboBox a USER property
+ if (n.isEmpty() && editor->inherits("QComboBox"))
+ n = d->editorFactory()->valuePropertyName(static_cast<QVariant::Type>(v.userType()));
+ if (!n.isEmpty()) {
+ if (!v.isValid())
+ v = QVariant(editor->property(n).userType(), (const void *)0);
+ editor->setProperty(n, v);
+ }
+#endif
+}
+
+/*!
+ Gets data from the \a editor widget and stores it in the specified
+ \a model at the item \a index.
+
+ The default implementation gets the value to be stored in the data
+ model from the \a editor widget's \l {Qt's Property System} {user
+ property}.
+
+ \sa QMetaProperty::isUser()
+*/
+
+void QItemDelegate::setModelData(QWidget *editor,
+ QAbstractItemModel *model,
+ const QModelIndex &index) const
+{
+#ifdef QT_NO_PROPERTIES
+ Q_UNUSED(model);
+ Q_UNUSED(editor);
+ Q_UNUSED(index);
+#else
+ Q_D(const QItemDelegate);
+ Q_ASSERT(model);
+ Q_ASSERT(editor);
+ QByteArray n = editor->metaObject()->userProperty().name();
+ if (n.isEmpty())
+ n = d->editorFactory()->valuePropertyName(
+ static_cast<QVariant::Type>(model->data(index, Qt::EditRole).userType()));
+ if (!n.isEmpty())
+ model->setData(index, editor->property(n), Qt::EditRole);
+#endif
+}
+
+/*!
+ Updates the \a editor for the item specified by \a index
+ according to the style \a option given.
+*/
+
+void QItemDelegate::updateEditorGeometry(QWidget *editor,
+ const QStyleOptionViewItem &option,
+ const QModelIndex &index) const
+{
+ if (!editor)
+ return;
+ Q_ASSERT(index.isValid());
+ QPixmap pixmap = decoration(option, index.data(Qt::DecorationRole));
+ QString text = QItemDelegatePrivate::replaceNewLine(index.data(Qt::DisplayRole).toString());
+ QRect pixmapRect = QRect(QPoint(0, 0), option.decorationSize).intersected(pixmap.rect());
+ QRect textRect = textRectangle(0, option.rect, option.font, text);
+ QRect checkRect = check(option, textRect, index.data(Qt::CheckStateRole));
+ QStyleOptionViewItem opt = option;
+ opt.showDecorationSelected = true; // let the editor take up all available space
+ doLayout(opt, &checkRect, &pixmapRect, &textRect, false);
+ editor->setGeometry(textRect);
+}
+
+/*!
+ Returns the editor factory used by the item delegate.
+ If no editor factory is set, the function will return null.
+
+ \sa setItemEditorFactory()
+*/
+QItemEditorFactory *QItemDelegate::itemEditorFactory() const
+{
+ Q_D(const QItemDelegate);
+ return d->f;
+}
+
+/*!
+ Sets the editor factory to be used by the item delegate to be the \a factory
+ specified. If no editor factory is set, the item delegate will use the
+ default editor factory.
+
+ \sa itemEditorFactory()
+*/
+void QItemDelegate::setItemEditorFactory(QItemEditorFactory *factory)
+{
+ Q_D(QItemDelegate);
+ d->f = factory;
+}
+
+/*!
+ Renders the item view \a text within the rectangle specified by \a rect
+ using the given \a painter and style \a option.
+*/
+
+void QItemDelegate::drawDisplay(QPainter *painter, const QStyleOptionViewItem &option,
+ const QRect &rect, const QString &text) const
+{
+ Q_D(const QItemDelegate);
+
+ QPalette::ColorGroup cg = option.state & QStyle::State_Enabled
+ ? QPalette::Normal : QPalette::Disabled;
+ if (cg == QPalette::Normal && !(option.state & QStyle::State_Active))
+ cg = QPalette::Inactive;
+ if (option.state & QStyle::State_Selected) {
+ painter->fillRect(rect, option.palette.brush(cg, QPalette::Highlight));
+ painter->setPen(option.palette.color(cg, QPalette::HighlightedText));
+ } else {
+ painter->setPen(option.palette.color(cg, QPalette::Text));
+ }
+
+ if (text.isEmpty())
+ return;
+
+ if (option.state & QStyle::State_Editing) {
+ painter->save();
+ painter->setPen(option.palette.color(cg, QPalette::Text));
+ painter->drawRect(rect.adjusted(0, 0, -1, -1));
+ painter->restore();
+ }
+
+ const QStyleOptionViewItemV4 opt = option;
+
+ const QWidget *widget = d->widget(option);
+ QStyle *style = widget ? widget->style() : QApplication::style();
+ const int textMargin = style->pixelMetric(QStyle::PM_FocusFrameHMargin, 0, widget) + 1;
+ QRect textRect = rect.adjusted(textMargin, 0, -textMargin, 0); // remove width padding
+ const bool wrapText = opt.features & QStyleOptionViewItemV2::WrapText;
+ d->textOption.setWrapMode(wrapText ? QTextOption::WordWrap : QTextOption::ManualWrap);
+ d->textOption.setTextDirection(option.direction);
+ d->textOption.setAlignment(QStyle::visualAlignment(option.direction, option.displayAlignment));
+ d->textLayout.setTextOption(d->textOption);
+ d->textLayout.setFont(option.font);
+ d->textLayout.setText(QItemDelegatePrivate::replaceNewLine(text));
+
+ QSizeF textLayoutSize = d->doTextLayout(textRect.width());
+
+ if (textRect.width() < textLayoutSize.width()
+ || textRect.height() < textLayoutSize.height()) {
+ QString elided;
+ int start = 0;
+ int end = text.indexOf(QChar::LineSeparator, start);
+ if (end == -1) {
+ elided += option.fontMetrics.elidedText(text, option.textElideMode, textRect.width());
+ } else {
+ while (end != -1) {
+ elided += option.fontMetrics.elidedText(text.mid(start, end - start),
+ option.textElideMode, textRect.width());
+ elided += QChar::LineSeparator;
+ start = end + 1;
+ end = text.indexOf(QChar::LineSeparator, start);
+ }
+ //let's add the last line (after the last QChar::LineSeparator)
+ elided += option.fontMetrics.elidedText(text.mid(start),
+ option.textElideMode, textRect.width());
+ }
+ d->textLayout.setText(elided);
+ textLayoutSize = d->doTextLayout(textRect.width());
+ }
+
+ const QSize layoutSize(textRect.width(), int(textLayoutSize.height()));
+ const QRect layoutRect = QStyle::alignedRect(option.direction, option.displayAlignment,
+ layoutSize, textRect);
+ // if we still overflow even after eliding the text, enable clipping
+ if (!hasClipping() && (textRect.width() < textLayoutSize.width()
+ || textRect.height() < textLayoutSize.height())) {
+ painter->save();
+ painter->setClipRect(layoutRect);
+ d->textLayout.draw(painter, layoutRect.topLeft(), QVector<QTextLayout::FormatRange>(), layoutRect);
+ painter->restore();
+ } else {
+ d->textLayout.draw(painter, layoutRect.topLeft(), QVector<QTextLayout::FormatRange>(), layoutRect);
+ }
+}
+
+/*!
+ Renders the decoration \a pixmap within the rectangle specified by
+ \a rect using the given \a painter and style \a option.
+*/
+void QItemDelegate::drawDecoration(QPainter *painter, const QStyleOptionViewItem &option,
+ const QRect &rect, const QPixmap &pixmap) const
+{
+ Q_D(const QItemDelegate);
+ // if we have an icon, we ignore the pixmap
+ if (!d->tmp.icon.isNull()) {
+ d->tmp.icon.paint(painter, rect, option.decorationAlignment,
+ d->tmp.mode, d->tmp.state);
+ return;
+ }
+
+ if (pixmap.isNull() || !rect.isValid())
+ return;
+ QPoint p = QStyle::alignedRect(option.direction, option.decorationAlignment,
+ pixmap.size(), rect).topLeft();
+ if (option.state & QStyle::State_Selected) {
+ QPixmap *pm = selected(pixmap, option.palette, option.state & QStyle::State_Enabled);
+ painter->drawPixmap(p, *pm);
+ } else {
+ painter->drawPixmap(p, pixmap);
+ }
+}
+
+/*!
+ Renders the region within the rectangle specified by \a rect, indicating
+ that it has the focus, using the given \a painter and style \a option.
+*/
+
+void QItemDelegate::drawFocus(QPainter *painter,
+ const QStyleOptionViewItem &option,
+ const QRect &rect) const
+{
+ Q_D(const QItemDelegate);
+ if ((option.state & QStyle::State_HasFocus) == 0 || !rect.isValid())
+ return;
+ QStyleOptionFocusRect o;
+ o.QStyleOption::operator=(option);
+ o.rect = rect;
+ o.state |= QStyle::State_KeyboardFocusChange;
+ o.state |= QStyle::State_Item;
+ QPalette::ColorGroup cg = (option.state & QStyle::State_Enabled)
+ ? QPalette::Normal : QPalette::Disabled;
+ o.backgroundColor = option.palette.color(cg, (option.state & QStyle::State_Selected)
+ ? QPalette::Highlight : QPalette::Window);
+ const QWidget *widget = d->widget(option);
+ QStyle *style = widget ? widget->style() : QApplication::style();
+ style->drawPrimitive(QStyle::PE_FrameFocusRect, &o, painter, widget);
+}
+
+/*!
+ Renders a check indicator within the rectangle specified by \a
+ rect, using the given \a painter and style \a option, using the
+ given \a state.
+*/
+
+void QItemDelegate::drawCheck(QPainter *painter,
+ const QStyleOptionViewItem &option,
+ const QRect &rect, Qt::CheckState state) const
+{
+ Q_D(const QItemDelegate);
+ if (!rect.isValid())
+ return;
+
+ QStyleOptionViewItem opt(option);
+ opt.rect = rect;
+ opt.state = opt.state & ~QStyle::State_HasFocus;
+
+ switch (state) {
+ case Qt::Unchecked:
+ opt.state |= QStyle::State_Off;
+ break;
+ case Qt::PartiallyChecked:
+ opt.state |= QStyle::State_NoChange;
+ break;
+ case Qt::Checked:
+ opt.state |= QStyle::State_On;
+ break;
+ }
+
+ const QWidget *widget = d->widget(option);
+ QStyle *style = widget ? widget->style() : QApplication::style();
+ style->drawPrimitive(QStyle::PE_IndicatorViewItemCheck, &opt, painter, widget);
+}
+
+/*!
+ \since 4.2
+
+ Renders the item background for the given \a index,
+ using the given \a painter and style \a option.
+*/
+
+void QItemDelegate::drawBackground(QPainter *painter,
+ const QStyleOptionViewItem &option,
+ const QModelIndex &index) const
+{
+ if (option.showDecorationSelected && (option.state & QStyle::State_Selected)) {
+ QPalette::ColorGroup cg = option.state & QStyle::State_Enabled
+ ? QPalette::Normal : QPalette::Disabled;
+ if (cg == QPalette::Normal && !(option.state & QStyle::State_Active))
+ cg = QPalette::Inactive;
+
+ painter->fillRect(option.rect, option.palette.brush(cg, QPalette::Highlight));
+ } else {
+ QVariant value = index.data(Qt::BackgroundRole);
+ if (value.canConvert<QBrush>()) {
+ QPointF oldBO = painter->brushOrigin();
+ painter->setBrushOrigin(option.rect.topLeft());
+ painter->fillRect(option.rect, qvariant_cast<QBrush>(value));
+ painter->setBrushOrigin(oldBO);
+ }
+ }
+}
+
+
+/*!
+ \internal
+
+ Code duplicated in QCommonStylePrivate::viewItemLayout
+*/
+
+void QItemDelegate::doLayout(const QStyleOptionViewItem &option,
+ QRect *checkRect, QRect *pixmapRect, QRect *textRect,
+ bool hint) const
+{
+ Q_ASSERT(checkRect && pixmapRect && textRect);
+ Q_D(const QItemDelegate);
+ const QWidget *widget = d->widget(option);
+ QStyle *style = widget ? widget->style() : QApplication::style();
+ const bool hasCheck = checkRect->isValid();
+ const bool hasPixmap = pixmapRect->isValid();
+ const bool hasText = textRect->isValid();
+ const int textMargin = hasText ? style->pixelMetric(QStyle::PM_FocusFrameHMargin, 0, widget) + 1 : 0;
+ const int pixmapMargin = hasPixmap ? style->pixelMetric(QStyle::PM_FocusFrameHMargin, 0, widget) + 1 : 0;
+ const int checkMargin = hasCheck ? style->pixelMetric(QStyle::PM_FocusFrameHMargin, 0, widget) + 1 : 0;
+ int x = option.rect.left();
+ int y = option.rect.top();
+ int w, h;
+
+ textRect->adjust(-textMargin, 0, textMargin, 0); // add width padding
+ if (textRect->height() == 0 && (!hasPixmap || !hint)) {
+ //if there is no text, we still want to have a decent height for the item sizeHint and the editor size
+ textRect->setHeight(option.fontMetrics.height());
+ }
+
+ QSize pm(0, 0);
+ if (hasPixmap) {
+ pm = pixmapRect->size();
+ pm.rwidth() += 2 * pixmapMargin;
+ }
+ if (hint) {
+ h = qMax(checkRect->height(), qMax(textRect->height(), pm.height()));
+ if (option.decorationPosition == QStyleOptionViewItem::Left
+ || option.decorationPosition == QStyleOptionViewItem::Right) {
+ w = textRect->width() + pm.width();
+ } else {
+ w = qMax(textRect->width(), pm.width());
+ }
+ } else {
+ w = option.rect.width();
+ h = option.rect.height();
+ }
+
+ int cw = 0;
+ QRect check;
+ if (hasCheck) {
+ cw = checkRect->width() + 2 * checkMargin;
+ if (hint) w += cw;
+ if (option.direction == Qt::RightToLeft) {
+ check.setRect(x + w - cw, y, cw, h);
+ } else {
+ check.setRect(x + checkMargin, y, cw, h);
+ }
+ }
+
+ // at this point w should be the *total* width
+
+ QRect display;
+ QRect decoration;
+ switch (option.decorationPosition) {
+ case QStyleOptionViewItem::Top: {
+ if (hasPixmap)
+ pm.setHeight(pm.height() + pixmapMargin); // add space
+ h = hint ? textRect->height() : h - pm.height();
+
+ if (option.direction == Qt::RightToLeft) {
+ decoration.setRect(x, y, w - cw, pm.height());
+ display.setRect(x, y + pm.height(), w - cw, h);
+ } else {
+ decoration.setRect(x + cw, y, w - cw, pm.height());
+ display.setRect(x + cw, y + pm.height(), w - cw, h);
+ }
+ break; }
+ case QStyleOptionViewItem::Bottom: {
+ if (hasText)
+ textRect->setHeight(textRect->height() + textMargin); // add space
+ h = hint ? textRect->height() + pm.height() : h;
+
+ if (option.direction == Qt::RightToLeft) {
+ display.setRect(x, y, w - cw, textRect->height());
+ decoration.setRect(x, y + textRect->height(), w - cw, h - textRect->height());
+ } else {
+ display.setRect(x + cw, y, w - cw, textRect->height());
+ decoration.setRect(x + cw, y + textRect->height(), w - cw, h - textRect->height());
+ }
+ break; }
+ case QStyleOptionViewItem::Left: {
+ if (option.direction == Qt::LeftToRight) {
+ decoration.setRect(x + cw, y, pm.width(), h);
+ display.setRect(decoration.right() + 1, y, w - pm.width() - cw, h);
+ } else {
+ display.setRect(x, y, w - pm.width() - cw, h);
+ decoration.setRect(display.right() + 1, y, pm.width(), h);
+ }
+ break; }
+ case QStyleOptionViewItem::Right: {
+ if (option.direction == Qt::LeftToRight) {
+ display.setRect(x + cw, y, w - pm.width() - cw, h);
+ decoration.setRect(display.right() + 1, y, pm.width(), h);
+ } else {
+ decoration.setRect(x, y, pm.width(), h);
+ display.setRect(decoration.right() + 1, y, w - pm.width() - cw, h);
+ }
+ break; }
+ default:
+ qWarning("doLayout: decoration position is invalid");
+ decoration = *pixmapRect;
+ break;
+ }
+
+ if (!hint) { // we only need to do the internal layout if we are going to paint
+ *checkRect = QStyle::alignedRect(option.direction, Qt::AlignCenter,
+ checkRect->size(), check);
+ *pixmapRect = QStyle::alignedRect(option.direction, option.decorationAlignment,
+ pixmapRect->size(), decoration);
+ // the text takes up all available space, unless the decoration is not shown as selected
+ if (option.showDecorationSelected)
+ *textRect = display;
+ else
+ *textRect = QStyle::alignedRect(option.direction, option.displayAlignment,
+ textRect->size().boundedTo(display.size()), display);
+ } else {
+ *checkRect = check;
+ *pixmapRect = decoration;
+ *textRect = display;
+ }
+}
+
+/*!
+ \internal
+
+ Returns the pixmap used to decorate the root of the item view.
+ The style \a option controls the appearance of the root; the \a variant
+ refers to the data associated with an item.
+*/
+
+QPixmap QItemDelegate::decoration(const QStyleOptionViewItem &option, const QVariant &variant) const
+{
+ Q_D(const QItemDelegate);
+ switch (variant.type()) {
+ case QVariant::Icon: {
+ QIcon::Mode mode = d->iconMode(option.state);
+ QIcon::State state = d->iconState(option.state);
+ return qvariant_cast<QIcon>(variant).pixmap(option.decorationSize, mode, state); }
+ case QVariant::Color: {
+ static QPixmap pixmap(option.decorationSize);
+ pixmap.fill(qvariant_cast<QColor>(variant));
+ return pixmap; }
+ default:
+ break;
+ }
+
+ return qvariant_cast<QPixmap>(variant);
+}
+
+// hacky but faster version of "QString::sprintf("%d-%d", i, enabled)"
+static QString qPixmapSerial(quint64 i, bool enabled)
+{
+ ushort arr[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '-', ushort('0' + enabled) };
+ ushort *ptr = &arr[16];
+
+ while (i > 0) {
+ // hey - it's our internal representation, so use the ascii character after '9'
+ // instead of 'a' for hex
+ *(--ptr) = '0' + i % 16;
+ i >>= 4;
+ }
+
+ return QString((const QChar *)ptr, int(&arr[sizeof(arr) / sizeof(ushort)] - ptr));
+}
+
+/*!
+ \internal
+ Returns the selected version of the given \a pixmap using the given \a palette.
+ The \a enabled argument decides whether the normal or disabled highlight color of
+ the palette is used.
+*/
+QPixmap *QItemDelegate::selected(const QPixmap &pixmap, const QPalette &palette, bool enabled) const
+{
+ QString key = qPixmapSerial(pixmap.cacheKey(), enabled);
+ QPixmap *pm = QPixmapCache::find(key);
+ if (!pm) {
+ QImage img = pixmap.toImage().convertToFormat(QImage::Format_ARGB32_Premultiplied);
+
+ QColor color = palette.color(enabled ? QPalette::Normal : QPalette::Disabled,
+ QPalette::Highlight);
+ color.setAlphaF((qreal)0.3);
+
+ QPainter painter(&img);
+ painter.setCompositionMode(QPainter::CompositionMode_SourceAtop);
+ painter.fillRect(0, 0, img.width(), img.height(), color);
+ painter.end();
+
+ QPixmap selected = QPixmap(QPixmap::fromImage(img));
+ int n = (img.byteCount() >> 10) + 1;
+ if (QPixmapCache::cacheLimit() < n)
+ QPixmapCache::setCacheLimit(n);
+
+ QPixmapCache::insert(key, selected);
+ pm = QPixmapCache::find(key);
+ }
+ return pm;
+}
+
+/*!
+ \internal
+*/
+
+QRect QItemDelegate::rect(const QStyleOptionViewItem &option,
+ const QModelIndex &index, int role) const
+{
+ Q_D(const QItemDelegate);
+ QVariant value = index.data(role);
+ if (role == Qt::CheckStateRole)
+ return check(option, option.rect, value);
+ if (value.isValid() && !value.isNull()) {
+ switch (value.type()) {
+ case QVariant::Invalid:
+ break;
+ case QVariant::Pixmap:
+ return QRect(QPoint(0, 0), qvariant_cast<QPixmap>(value).size());
+ case QVariant::Image:
+ return QRect(QPoint(0, 0), qvariant_cast<QImage>(value).size());
+ case QVariant::Icon: {
+ QIcon::Mode mode = d->iconMode(option.state);
+ QIcon::State state = d->iconState(option.state);
+ QIcon icon = qvariant_cast<QIcon>(value);
+ QSize size = icon.actualSize(option.decorationSize, mode, state);
+ return QRect(QPoint(0, 0), size); }
+ case QVariant::Color:
+ return QRect(QPoint(0, 0), option.decorationSize);
+ case QVariant::String:
+ default: {
+ QString text = QItemDelegatePrivate::valueToText(value, option);
+ value = index.data(Qt::FontRole);
+ QFont fnt = qvariant_cast<QFont>(value).resolve(option.font);
+ return textRectangle(0, d->textLayoutBounds(option), fnt, text); }
+ }
+ }
+ return QRect();
+}
+
+/*!
+ \internal
+
+ Note that on Mac, if /usr/include/AssertMacros.h is included prior
+ to QItemDelegate, and the application is building in debug mode, the
+ check(assertion) will conflict with QItemDelegate::check.
+
+ To avoid this problem, add
+
+ #ifdef check
+ #undef check
+ #endif
+
+ after including AssertMacros.h
+*/
+QRect QItemDelegate::check(const QStyleOptionViewItem &option,
+ const QRect &bounding, const QVariant &value) const
+{
+ if (value.isValid()) {
+ Q_D(const QItemDelegate);
+ QStyleOptionButton opt;
+ opt.QStyleOption::operator=(option);
+ opt.rect = bounding;
+ const QWidget *widget = d->widget(option); // cast
+ QStyle *style = widget ? widget->style() : QApplication::style();
+ return style->subElementRect(QStyle::SE_ViewItemCheckIndicator, &opt, widget);
+ }
+ return QRect();
+}
+
+/*!
+ \internal
+*/
+QRect QItemDelegate::textRectangle(QPainter * /*painter*/, const QRect &rect,
+ const QFont &font, const QString &text) const
+{
+ Q_D(const QItemDelegate);
+ d->textOption.setWrapMode(QTextOption::WordWrap);
+ d->textLayout.setTextOption(d->textOption);
+ d->textLayout.setFont(font);
+ d->textLayout.setText(QItemDelegatePrivate::replaceNewLine(text));
+ QSizeF fpSize = d->doTextLayout(rect.width());
+ const QSize size = QSize(qCeil(fpSize.width()), qCeil(fpSize.height()));
+ // ###: textRectangle should take style option as argument
+ const int textMargin = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1;
+ return QRect(0, 0, size.width() + 2 * textMargin, size.height());
+}
+
+/*!
+ \fn bool QItemDelegate::eventFilter(QObject *editor, QEvent *event)
+
+ Returns true if the given \a editor is a valid QWidget and the
+ given \a event is handled; otherwise returns false. The following
+ key press events are handled by default:
+
+ \list
+ \o \gui Tab
+ \o \gui Backtab
+ \o \gui Enter
+ \o \gui Return
+ \o \gui Esc
+ \endlist
+
+ In the case of \gui Tab, \gui Backtab, \gui Enter and \gui Return
+ key press events, the \a editor's data is comitted to the model
+ and the editor is closed. If the \a event is a \gui Tab key press
+ the view will open an editor on the next item in the
+ view. Likewise, if the \a event is a \gui Backtab key press the
+ view will open an editor on the \e previous item in the view.
+
+ If the event is a \gui Esc key press event, the \a editor is
+ closed \e without committing its data.
+
+ \sa commitData(), closeEditor()
+*/
+
+bool QItemDelegate::eventFilter(QObject *object, QEvent *event)
+{
+ QWidget *editor = qobject_cast<QWidget*>(object);
+ if (!editor)
+ return false;
+ if (event->type() == QEvent::KeyPress) {
+ switch (static_cast<QKeyEvent *>(event)->key()) {
+ case Qt::Key_Tab:
+ emit commitData(editor);
+ emit closeEditor(editor, QAbstractItemDelegate::EditNextItem);
+ return true;
+ case Qt::Key_Backtab:
+ emit commitData(editor);
+ emit closeEditor(editor, QAbstractItemDelegate::EditPreviousItem);
+ return true;
+ case Qt::Key_Enter:
+ case Qt::Key_Return:
+#ifndef QT_NO_TEXTEDIT
+ if (qobject_cast<QTextEdit *>(editor) || qobject_cast<QPlainTextEdit *>(editor))
+ return false; // don't filter enter key events for QTextEdit
+ // We want the editor to be able to process the key press
+ // before committing the data (e.g. so it can do
+ // validation/fixup of the input).
+#endif // QT_NO_TEXTEDIT
+#ifndef QT_NO_LINEEDIT
+ if (QLineEdit *e = qobject_cast<QLineEdit*>(editor))
+ if (!e->hasAcceptableInput())
+ return false;
+#endif // QT_NO_LINEEDIT
+ QMetaObject::invokeMethod(this, "_q_commitDataAndCloseEditor",
+ Qt::QueuedConnection, Q_ARG(QWidget*, editor));
+ return false;
+ case Qt::Key_Escape:
+ // don't commit data
+ emit closeEditor(editor, QAbstractItemDelegate::RevertModelCache);
+ break;
+ default:
+ return false;
+ }
+ if (editor->parentWidget())
+ editor->parentWidget()->setFocus();
+ return true;
+ } else if (event->type() == QEvent::FocusOut || (event->type() == QEvent::Hide && editor->isWindow())) {
+ //the Hide event will take care of he editors that are in fact complete dialogs
+ if (!editor->isActiveWindow() || (QApplication::focusWidget() != editor)) {
+ QWidget *w = QApplication::focusWidget();
+ while (w) { // don't worry about focus changes internally in the editor
+ if (w == editor)
+ return false;
+ w = w->parentWidget();
+ }
+#ifndef QT_NO_DRAGANDDROP
+ // The window may lose focus during an drag operation.
+ // i.e when dragging involves the taskbar on Windows.
+ if (QDragManager::self() && QDragManager::self()->object != 0)
+ return false;
+#endif
+
+ emit commitData(editor);
+ emit closeEditor(editor, NoHint);
+ }
+ } else if (event->type() == QEvent::ShortcutOverride) {
+ if (static_cast<QKeyEvent*>(event)->key() == Qt::Key_Escape) {
+ event->accept();
+ return true;
+ }
+ }
+ return false;
+}
+
+/*!
+ \reimp
+*/
+
+bool QItemDelegate::editorEvent(QEvent *event,
+ QAbstractItemModel *model,
+ const QStyleOptionViewItem &option,
+ const QModelIndex &index)
+{
+ Q_ASSERT(event);
+ Q_ASSERT(model);
+
+ // make sure that the item is checkable
+ Qt::ItemFlags flags = model->flags(index);
+ if (!(flags & Qt::ItemIsUserCheckable) || !(option.state & QStyle::State_Enabled)
+ || !(flags & Qt::ItemIsEnabled))
+ return false;
+
+ // make sure that we have a check state
+ QVariant value = index.data(Qt::CheckStateRole);
+ if (!value.isValid())
+ return false;
+
+ // make sure that we have the right event type
+ if ((event->type() == QEvent::MouseButtonRelease)
+ || (event->type() == QEvent::MouseButtonDblClick)
+ || (event->type() == QEvent::MouseButtonPress)) {
+ QRect checkRect = check(option, option.rect, Qt::Checked);
+ QRect emptyRect;
+ doLayout(option, &checkRect, &emptyRect, &emptyRect, false);
+ QMouseEvent *me = static_cast<QMouseEvent*>(event);
+ if (me->button() != Qt::LeftButton || !checkRect.contains(me->pos()))
+ return false;
+
+ // eat the double click events inside the check rect
+ if ((event->type() == QEvent::MouseButtonPress)
+ || (event->type() == QEvent::MouseButtonDblClick))
+ return true;
+
+ } else if (event->type() == QEvent::KeyPress) {
+ if (static_cast<QKeyEvent*>(event)->key() != Qt::Key_Space
+ && static_cast<QKeyEvent*>(event)->key() != Qt::Key_Select)
+ return false;
+ } else {
+ return false;
+ }
+
+ Qt::CheckState state = (static_cast<Qt::CheckState>(value.toInt()) == Qt::Checked
+ ? Qt::Unchecked : Qt::Checked);
+ return model->setData(index, state, Qt::CheckStateRole);
+}
+
+/*!
+ \internal
+*/
+
+QStyleOptionViewItem QItemDelegate::setOptions(const QModelIndex &index,
+ const QStyleOptionViewItem &option) const
+{
+ QStyleOptionViewItem opt = option;
+
+ // set font
+ QVariant value = index.data(Qt::FontRole);
+ if (value.isValid()){
+ opt.font = qvariant_cast<QFont>(value).resolve(opt.font);
+ opt.fontMetrics = QFontMetrics(opt.font);
+ }
+
+ // set text alignment
+ value = index.data(Qt::TextAlignmentRole);
+ if (value.isValid())
+ opt.displayAlignment = Qt::Alignment(value.toInt());
+
+ // set foreground brush
+ value = index.data(Qt::ForegroundRole);
+ if (value.canConvert<QBrush>())
+ opt.palette.setBrush(QPalette::Text, qvariant_cast<QBrush>(value));
+
+ return opt;
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qitemdelegate.cpp"
+
+#endif // QT_NO_ITEMVIEWS
diff --git a/src/widgets/itemviews/qitemdelegate.h b/src/widgets/itemviews/qitemdelegate.h
new file mode 100644
index 0000000000..97f3cc820e
--- /dev/null
+++ b/src/widgets/itemviews/qitemdelegate.h
@@ -0,0 +1,141 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QITEMDELEGATE_H
+#define QITEMDELEGATE_H
+
+#include <QtWidgets/qabstractitemdelegate.h>
+#include <QtCore/qstring.h>
+#include <QtGui/qpixmap.h>
+#include <QtCore/qvariant.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_ITEMVIEWS
+
+class QItemDelegatePrivate;
+class QItemEditorFactory;
+
+class Q_WIDGETS_EXPORT QItemDelegate : public QAbstractItemDelegate
+{
+ Q_OBJECT
+ Q_PROPERTY(bool clipping READ hasClipping WRITE setClipping)
+
+public:
+ explicit QItemDelegate(QObject *parent = 0);
+ ~QItemDelegate();
+
+ bool hasClipping() const;
+ void setClipping(bool clip);
+
+ // painting
+ void paint(QPainter *painter,
+ const QStyleOptionViewItem &option,
+ const QModelIndex &index) const;
+ QSize sizeHint(const QStyleOptionViewItem &option,
+ const QModelIndex &index) const;
+
+ // editing
+ QWidget *createEditor(QWidget *parent,
+ const QStyleOptionViewItem &option,
+ const QModelIndex &index) const;
+
+ void setEditorData(QWidget *editor, const QModelIndex &index) const;
+ void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
+
+ void updateEditorGeometry(QWidget *editor,
+ const QStyleOptionViewItem &option,
+ const QModelIndex &index) const;
+
+ // editor factory
+ QItemEditorFactory *itemEditorFactory() const;
+ void setItemEditorFactory(QItemEditorFactory *factory);
+
+protected:
+ virtual void drawDisplay(QPainter *painter, const QStyleOptionViewItem &option,
+ const QRect &rect, const QString &text) const;
+ virtual void drawDecoration(QPainter *painter, const QStyleOptionViewItem &option,
+ const QRect &rect, const QPixmap &pixmap) const;
+ virtual void drawFocus(QPainter *painter, const QStyleOptionViewItem &option,
+ const QRect &rect) const;
+ virtual void drawCheck(QPainter *painter, const QStyleOptionViewItem &option,
+ const QRect &rect, Qt::CheckState state) const;
+ void drawBackground(QPainter *painter, const QStyleOptionViewItem &option,
+ const QModelIndex &index) const;
+
+ void doLayout(const QStyleOptionViewItem &option,
+ QRect *checkRect, QRect *iconRect, QRect *textRect, bool hint) const;
+
+ QRect rect(const QStyleOptionViewItem &option, const QModelIndex &index, int role) const;
+
+ bool eventFilter(QObject *object, QEvent *event);
+ bool editorEvent(QEvent *event, QAbstractItemModel *model,
+ const QStyleOptionViewItem &option, const QModelIndex &index);
+
+ QStyleOptionViewItem setOptions(const QModelIndex &index,
+ const QStyleOptionViewItem &option) const;
+
+ QPixmap decoration(const QStyleOptionViewItem &option, const QVariant &variant) const;
+ QPixmap *selected(const QPixmap &pixmap, const QPalette &palette, bool enabled) const;
+
+ QRect check(const QStyleOptionViewItem &option, const QRect &bounding,
+ const QVariant &variant) const;
+ QRect textRectangle(QPainter *painter, const QRect &rect,
+ const QFont &font, const QString &text) const;
+
+private:
+ Q_DECLARE_PRIVATE(QItemDelegate)
+ Q_DISABLE_COPY(QItemDelegate)
+
+ Q_PRIVATE_SLOT(d_func(), void _q_commitDataAndCloseEditor(QWidget*))
+};
+
+#endif // QT_NO_ITEMVIEWS
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QITEMDELEGATE_H
diff --git a/src/gui/itemviews/qitemeditorfactory.cpp b/src/widgets/itemviews/qitemeditorfactory.cpp
index cc9d1399bf..cc9d1399bf 100644
--- a/src/gui/itemviews/qitemeditorfactory.cpp
+++ b/src/widgets/itemviews/qitemeditorfactory.cpp
diff --git a/src/widgets/itemviews/qitemeditorfactory.h b/src/widgets/itemviews/qitemeditorfactory.h
new file mode 100644
index 0000000000..b48cac224f
--- /dev/null
+++ b/src/widgets/itemviews/qitemeditorfactory.h
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QITEMEDITORFACTORY_H
+#define QITEMEDITORFACTORY_H
+
+#include <QtCore/qmetaobject.h>
+#include <QtCore/qbytearray.h>
+#include <QtCore/qhash.h>
+#include <QtCore/qvariant.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_ITEMVIEWS
+
+class QWidget;
+
+class Q_WIDGETS_EXPORT QItemEditorCreatorBase
+{
+public:
+ virtual ~QItemEditorCreatorBase() {}
+
+ virtual QWidget *createWidget(QWidget *parent) const = 0;
+ virtual QByteArray valuePropertyName() const = 0;
+};
+
+template <class T>
+class QItemEditorCreator : public QItemEditorCreatorBase
+{
+public:
+ inline QItemEditorCreator(const QByteArray &valuePropertyName);
+ inline QWidget *createWidget(QWidget *parent) const { return new T(parent); }
+ inline QByteArray valuePropertyName() const { return propertyName; }
+
+private:
+ QByteArray propertyName;
+};
+
+template <class T>
+class QStandardItemEditorCreator: public QItemEditorCreatorBase
+{
+public:
+ inline QStandardItemEditorCreator()
+ : propertyName(T::staticMetaObject.userProperty().name())
+ {}
+ inline QWidget *createWidget(QWidget *parent) const { return new T(parent); }
+ inline QByteArray valuePropertyName() const { return propertyName; }
+
+private:
+ QByteArray propertyName;
+};
+
+
+template <class T>
+Q_INLINE_TEMPLATE QItemEditorCreator<T>::QItemEditorCreator(const QByteArray &avaluePropertyName)
+ : propertyName(avaluePropertyName) {}
+
+class Q_WIDGETS_EXPORT QItemEditorFactory
+{
+public:
+ inline QItemEditorFactory() {}
+ virtual ~QItemEditorFactory();
+
+ virtual QWidget *createEditor(QVariant::Type type, QWidget *parent) const;
+ virtual QByteArray valuePropertyName(QVariant::Type type) const;
+
+ void registerEditor(QVariant::Type type, QItemEditorCreatorBase *creator);
+
+ static const QItemEditorFactory *defaultFactory();
+ static void setDefaultFactory(QItemEditorFactory *factory);
+
+private:
+ QHash<QVariant::Type, QItemEditorCreatorBase *> creatorMap;
+};
+
+#endif // QT_NO_ITEMVIEWS
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QITEMEDITORFACTORY_H
diff --git a/src/gui/itemviews/qitemeditorfactory_p.h b/src/widgets/itemviews/qitemeditorfactory_p.h
index effa6f26a2..effa6f26a2 100644
--- a/src/gui/itemviews/qitemeditorfactory_p.h
+++ b/src/widgets/itemviews/qitemeditorfactory_p.h
diff --git a/src/gui/itemviews/qitemselectionmodel.cpp b/src/widgets/itemviews/qitemselectionmodel.cpp
index 0d0b5b1d42..0d0b5b1d42 100644
--- a/src/gui/itemviews/qitemselectionmodel.cpp
+++ b/src/widgets/itemviews/qitemselectionmodel.cpp
diff --git a/src/widgets/itemviews/qitemselectionmodel.h b/src/widgets/itemviews/qitemselectionmodel.h
new file mode 100644
index 0000000000..5a117c8a1c
--- /dev/null
+++ b/src/widgets/itemviews/qitemselectionmodel.h
@@ -0,0 +1,255 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QITEMSELECTIONMODEL_H
+#define QITEMSELECTIONMODEL_H
+
+#include <QtCore/qset.h>
+#include <QtCore/qvector.h>
+#include <QtCore/qlist.h>
+#include <QtCore/qabstractitemmodel.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_ITEMVIEWS
+
+class Q_WIDGETS_EXPORT QItemSelectionRange
+{
+
+public:
+ inline QItemSelectionRange() {}
+ inline QItemSelectionRange(const QItemSelectionRange &other)
+ : tl(other.tl), br(other.br) {}
+ inline QItemSelectionRange(const QModelIndex &topLeft, const QModelIndex &bottomRight);
+ explicit inline QItemSelectionRange(const QModelIndex &index)
+ { tl = index; br = tl; }
+
+ inline int top() const { return tl.row(); }
+ inline int left() const { return tl.column(); }
+ inline int bottom() const { return br.row(); }
+ inline int right() const { return br.column(); }
+ inline int width() const { return br.column() - tl.column() + 1; }
+ inline int height() const { return br.row() - tl.row() + 1; }
+
+ inline QModelIndex topLeft() const { return QModelIndex(tl); }
+ inline QModelIndex bottomRight() const { return QModelIndex(br); }
+ inline QModelIndex parent() const { return tl.parent(); }
+ inline const QAbstractItemModel *model() const { return tl.model(); }
+
+ inline bool contains(const QModelIndex &index) const
+ {
+ return (parent() == index.parent()
+ && tl.row() <= index.row() && tl.column() <= index.column()
+ && br.row() >= index.row() && br.column() >= index.column());
+ }
+
+ inline bool contains(int row, int column, const QModelIndex &parentIndex) const
+ {
+ return (parent() == parentIndex
+ && tl.row() <= row && tl.column() <= column
+ && br.row() >= row && br.column() >= column);
+ }
+
+ bool intersects(const QItemSelectionRange &other) const;
+ QItemSelectionRange intersect(const QItemSelectionRange &other) const; // ### Qt 5: make QT4_SUPPORT
+ inline QItemSelectionRange intersected(const QItemSelectionRange &other) const
+ { return intersect(other); }
+
+ inline bool operator==(const QItemSelectionRange &other) const
+ { return (tl == other.tl && br == other.br); }
+ inline bool operator!=(const QItemSelectionRange &other) const
+ { return !operator==(other); }
+ inline bool operator<(const QItemSelectionRange &other) const
+ {
+ // Comparing parents will compare the models, but if two equivalent ranges
+ // in two different models have invalid parents, they would appear the same
+ if (other.tl.model() == tl.model()) {
+ // parent has to be calculated, so we only do so once.
+ const QModelIndex topLeftParent = tl.parent();
+ const QModelIndex otherTopLeftParent = other.tl.parent();
+ if (topLeftParent == otherTopLeftParent) {
+ if (other.tl.row() == tl.row()) {
+ if (other.tl.column() == tl.column()) {
+ if (other.br.row() == br.row()) {
+ return br.column() < other.br.column();
+ }
+ return br.row() < other.br.row();
+ }
+ return tl.column() < other.tl.column();
+ }
+ return tl.row() < other.tl.row();
+ }
+ return topLeftParent < otherTopLeftParent;
+ }
+ return tl.model() < other.tl.model();
+ }
+
+ inline bool isValid() const
+ {
+ return (tl.isValid() && br.isValid() && tl.parent() == br.parent()
+ && top() <= bottom() && left() <= right());
+ }
+
+ bool isEmpty() const;
+
+ QModelIndexList indexes() const;
+
+private:
+ QPersistentModelIndex tl, br;
+};
+Q_DECLARE_TYPEINFO(QItemSelectionRange, Q_MOVABLE_TYPE);
+
+inline QItemSelectionRange::QItemSelectionRange(const QModelIndex &atopLeft,
+ const QModelIndex &abottomRight)
+{ tl = atopLeft; br = abottomRight; }
+
+class QItemSelection;
+class QItemSelectionModelPrivate;
+
+class Q_WIDGETS_EXPORT QItemSelectionModel : public QObject
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QItemSelectionModel)
+ Q_FLAGS(SelectionFlags)
+
+public:
+
+ enum SelectionFlag {
+ NoUpdate = 0x0000,
+ Clear = 0x0001,
+ Select = 0x0002,
+ Deselect = 0x0004,
+ Toggle = 0x0008,
+ Current = 0x0010,
+ Rows = 0x0020,
+ Columns = 0x0040,
+ SelectCurrent = Select | Current,
+ ToggleCurrent = Toggle | Current,
+ ClearAndSelect = Clear | Select
+ };
+
+ Q_DECLARE_FLAGS(SelectionFlags, SelectionFlag)
+
+ explicit QItemSelectionModel(QAbstractItemModel *model);
+ explicit QItemSelectionModel(QAbstractItemModel *model, QObject *parent);
+ virtual ~QItemSelectionModel();
+
+ QModelIndex currentIndex() const;
+
+ bool isSelected(const QModelIndex &index) const;
+ bool isRowSelected(int row, const QModelIndex &parent) const;
+ bool isColumnSelected(int column, const QModelIndex &parent) const;
+
+ bool rowIntersectsSelection(int row, const QModelIndex &parent) const;
+ bool columnIntersectsSelection(int column, const QModelIndex &parent) const;
+
+ bool hasSelection() const;
+
+ QModelIndexList selectedIndexes() const;
+ QModelIndexList selectedRows(int column = 0) const;
+ QModelIndexList selectedColumns(int row = 0) const;
+ const QItemSelection selection() const;
+
+ const QAbstractItemModel *model() const;
+
+public Q_SLOTS:
+ void setCurrentIndex(const QModelIndex &index, QItemSelectionModel::SelectionFlags command);
+ virtual void select(const QModelIndex &index, QItemSelectionModel::SelectionFlags command);
+ virtual void select(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command);
+ virtual void clear();
+ virtual void reset();
+
+ void clearSelection();
+
+Q_SIGNALS:
+ void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
+ void currentChanged(const QModelIndex &current, const QModelIndex &previous);
+ void currentRowChanged(const QModelIndex &current, const QModelIndex &previous);
+ void currentColumnChanged(const QModelIndex &current, const QModelIndex &previous);
+
+protected:
+ QItemSelectionModel(QItemSelectionModelPrivate &dd, QAbstractItemModel *model);
+ void emitSelectionChanged(const QItemSelection &newSelection, const QItemSelection &oldSelection);
+
+private:
+ Q_DISABLE_COPY(QItemSelectionModel)
+ Q_PRIVATE_SLOT(d_func(), void _q_columnsAboutToBeRemoved(const QModelIndex&, int, int))
+ Q_PRIVATE_SLOT(d_func(), void _q_rowsAboutToBeRemoved(const QModelIndex&, int, int))
+ Q_PRIVATE_SLOT(d_func(), void _q_columnsAboutToBeInserted(const QModelIndex&, int, int))
+ Q_PRIVATE_SLOT(d_func(), void _q_rowsAboutToBeInserted(const QModelIndex&, int, int))
+ Q_PRIVATE_SLOT(d_func(), void _q_layoutAboutToBeChanged())
+ Q_PRIVATE_SLOT(d_func(), void _q_layoutChanged())
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QItemSelectionModel::SelectionFlags)
+
+// dummy implentation of qHash() necessary for instantiating QList<QItemSelectionRange>::toSet() with MSVC
+inline uint qHash(const QItemSelectionRange &) { return 0; }
+
+class Q_WIDGETS_EXPORT QItemSelection : public QList<QItemSelectionRange>
+{
+public:
+ QItemSelection() {}
+ QItemSelection(const QModelIndex &topLeft, const QModelIndex &bottomRight);
+ void select(const QModelIndex &topLeft, const QModelIndex &bottomRight);
+ bool contains(const QModelIndex &index) const;
+ QModelIndexList indexes() const;
+ void merge(const QItemSelection &other, QItemSelectionModel::SelectionFlags command);
+ static void split(const QItemSelectionRange &range,
+ const QItemSelectionRange &other,
+ QItemSelection *result);
+};
+
+#ifndef QT_NO_DEBUG_STREAM
+Q_WIDGETS_EXPORT QDebug operator<<(QDebug, const QItemSelectionRange &);
+#endif
+
+#endif // QT_NO_ITEMVIEWS
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QITEMSELECTIONMODEL_H
diff --git a/src/gui/itemviews/qitemselectionmodel_p.h b/src/widgets/itemviews/qitemselectionmodel_p.h
index 5eb9ecccda..5eb9ecccda 100644
--- a/src/gui/itemviews/qitemselectionmodel_p.h
+++ b/src/widgets/itemviews/qitemselectionmodel_p.h
diff --git a/src/widgets/itemviews/qlistview.cpp b/src/widgets/itemviews/qlistview.cpp
new file mode 100644
index 0000000000..d879e65c14
--- /dev/null
+++ b/src/widgets/itemviews/qlistview.cpp
@@ -0,0 +1,3225 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qlistview.h"
+
+#ifndef QT_NO_LISTVIEW
+#include <qabstractitemdelegate.h>
+#include <qapplication.h>
+#include <qpainter.h>
+#include <qbitmap.h>
+#include <qdrag.h>
+#include <qvector.h>
+#include <qstyle.h>
+#include <qevent.h>
+#include <qscrollbar.h>
+#include <qrubberband.h>
+#include <private/qlistview_p.h>
+#include <qdebug.h>
+#ifndef QT_NO_ACCESSIBILITY
+#include <qaccessible.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QListView
+
+ \brief The QListView class provides a list or icon view onto a model.
+
+ \ingroup model-view
+ \ingroup advanced
+
+
+ A QListView presents items stored in a model, either as a simple
+ non-hierarchical list, or as a collection of icons. This class is used
+ to provide lists and icon views that were previously provided by the
+ \c QListBox and \c QIconView classes, but using the more flexible
+ approach provided by Qt's model/view architecture.
+
+ The QListView class is one of the \l{Model/View Classes}
+ and is part of Qt's \l{Model/View Programming}{model/view framework}.
+
+ This view does not display horizontal or vertical headers; to display
+ a list of items with a horizontal header, use QTreeView instead.
+
+ QListView implements the interfaces defined by the
+ QAbstractItemView class to allow it to display data provided by
+ models derived from the QAbstractItemModel class.
+
+ Items in a list view can be displayed using one of two view modes:
+ In \l ListMode, the items are displayed in the form of a simple list;
+ in \l IconMode, the list view takes the form of an \e{icon view} in
+ which the items are displayed with icons like files in a file manager.
+ By default, the list view is in \l ListMode. To change the view mode,
+ use the setViewMode() function, and to determine the current view mode,
+ use viewMode().
+
+ Items in these views are laid out in the direction specified by the
+ flow() of the list view. The items may be fixed in place, or allowed
+ to move, depending on the view's movement() state.
+
+ If the items in the model cannot be completely laid out in the
+ direction of flow, they can be wrapped at the boundary of the view
+ widget; this depends on isWrapping(). This property is useful when the
+ items are being represented by an icon view.
+
+ The resizeMode() and layoutMode() govern how and when the items are
+ laid out. Items are spaced according to their spacing(), and can exist
+ within a notional grid of size specified by gridSize(). The items can
+ be rendered as large or small icons depending on their iconSize().
+
+ \table 100%
+ \row \o \inlineimage windowsxp-listview.png Screenshot of a Windows XP style list view
+ \o \inlineimage macintosh-listview.png Screenshot of a Macintosh style table view
+ \o \inlineimage plastique-listview.png Screenshot of a Plastique style table view
+ \row \o A \l{Windows XP Style Widget Gallery}{Windows XP style} list view.
+ \o A \l{Macintosh Style Widget Gallery}{Macintosh style} list view.
+ \o A \l{Plastique Style Widget Gallery}{Plastique style} list view.
+ \endtable
+
+ \section1 Improving Performance
+
+ It is possible to give the view hints about the data it is handling in order
+ to improve its performance when displaying large numbers of items. One approach
+ that can be taken for views that are intended to display items with equal sizes
+ is to set the \l uniformItemSizes property to true.
+
+ \sa {View Classes}, QTreeView, QTableView, QListWidget
+*/
+
+/*!
+ \enum QListView::ViewMode
+
+ \value ListMode The items are laid out using TopToBottom flow, with Small size and Static movement
+ \value IconMode The items are laid out using LeftToRight flow, with Large size and Free movement
+*/
+
+/*!
+ \enum QListView::Movement
+
+ \value Static The items cannot be moved by the user.
+ \value Free The items can be moved freely by the user.
+ \value Snap The items snap to the specified grid when moved; see
+ setGridSize().
+*/
+
+/*!
+ \enum QListView::Flow
+
+ \value LeftToRight The items are laid out in the view from the left
+ to the right.
+ \value TopToBottom The items are laid out in the view from the top
+ to the bottom.
+*/
+
+/*!
+ \enum QListView::ResizeMode
+
+ \value Fixed The items will only be laid out the first time the view is shown.
+ \value Adjust The items will be laid out every time the view is resized.
+*/
+
+/*!
+ \enum QListView::LayoutMode
+
+ \value SinglePass The items are laid out all at once.
+ \value Batched The items are laid out in batches of \l batchSize items.
+ \sa batchSize
+*/
+
+/*!
+ \since 4.2
+ \fn void QListView::indexesMoved(const QModelIndexList &indexes)
+
+ This signal is emitted when the specified \a indexes are moved in the view.
+*/
+
+/*!
+ Creates a new QListView with the given \a parent to view a model.
+ Use setModel() to set the model.
+*/
+QListView::QListView(QWidget *parent)
+ : QAbstractItemView(*new QListViewPrivate, parent)
+{
+ setViewMode(ListMode);
+ setSelectionMode(SingleSelection);
+ setAttribute(Qt::WA_MacShowFocusRect);
+ Q_D(QListView); // We rely on a qobject_cast for PM_DefaultFrameWidth to change
+ d->updateStyledFrameWidths(); // hence we have to force an update now that the object has been constructed
+}
+
+/*!
+ \internal
+*/
+QListView::QListView(QListViewPrivate &dd, QWidget *parent)
+ : QAbstractItemView(dd, parent)
+{
+ setViewMode(ListMode);
+ setSelectionMode(SingleSelection);
+ setAttribute(Qt::WA_MacShowFocusRect);
+ Q_D(QListView); // We rely on a qobject_cast for PM_DefaultFrameWidth to change
+ d->updateStyledFrameWidths(); // hence we have to force an update now that the object has been constructed
+}
+
+/*!
+ Destroys the view.
+*/
+QListView::~QListView()
+{
+}
+
+/*!
+ \property QListView::movement
+ \brief whether the items can be moved freely, are snapped to a
+ grid, or cannot be moved at all.
+
+ This property determines how the user can move the items in the
+ view. \l Static means that the items can't be moved the user. \l
+ Free means that the user can drag and drop the items to any
+ position in the view. \l Snap means that the user can drag and
+ drop the items, but only to the positions in a notional grid
+ signified by the gridSize property.
+
+ Setting this property when the view is visible will cause the
+ items to be laid out again.
+
+ By default, this property is set to \l Static.
+
+ \sa gridSize, resizeMode, viewMode
+*/
+void QListView::setMovement(Movement movement)
+{
+ Q_D(QListView);
+ d->modeProperties |= uint(QListViewPrivate::Movement);
+ d->movement = movement;
+
+#ifndef QT_NO_DRAGANDDROP
+ bool movable = (movement != Static);
+ setDragEnabled(movable);
+ d->viewport->setAcceptDrops(movable);
+#endif
+ d->doDelayedItemsLayout();
+}
+
+QListView::Movement QListView::movement() const
+{
+ Q_D(const QListView);
+ return d->movement;
+}
+
+/*!
+ \property QListView::flow
+ \brief which direction the items layout should flow.
+
+ If this property is \l LeftToRight, the items will be laid out left
+ to right. If the \l isWrapping property is true, the layout will wrap
+ when it reaches the right side of the visible area. If this
+ property is \l TopToBottom, the items will be laid out from the top
+ of the visible area, wrapping when it reaches the bottom.
+
+ Setting this property when the view is visible will cause the
+ items to be laid out again.
+
+ By default, this property is set to \l TopToBottom.
+
+ \sa viewMode
+*/
+void QListView::setFlow(Flow flow)
+{
+ Q_D(QListView);
+ d->modeProperties |= uint(QListViewPrivate::Flow);
+ d->flow = flow;
+ d->doDelayedItemsLayout();
+}
+
+QListView::Flow QListView::flow() const
+{
+ Q_D(const QListView);
+ return d->flow;
+}
+
+/*!
+ \property QListView::isWrapping
+ \brief whether the items layout should wrap.
+
+ This property holds whether the layout should wrap when there is
+ no more space in the visible area. The point at which the layout wraps
+ depends on the \l flow property.
+
+ Setting this property when the view is visible will cause the
+ items to be laid out again.
+
+ By default, this property is false.
+
+ \sa viewMode
+*/
+void QListView::setWrapping(bool enable)
+{
+ Q_D(QListView);
+ d->modeProperties |= uint(QListViewPrivate::Wrap);
+ d->setWrapping(enable);
+ d->doDelayedItemsLayout();
+}
+
+bool QListView::isWrapping() const
+{
+ Q_D(const QListView);
+ return d->isWrapping();
+}
+
+/*!
+ \property QListView::resizeMode
+ \brief whether the items are laid out again when the view is resized.
+
+ If this property is \l Adjust, the items will be laid out again
+ when the view is resized. If the value is \l Fixed, the items will
+ not be laid out when the view is resized.
+
+ By default, this property is set to \l Fixed.
+
+ \sa movement, gridSize, viewMode
+*/
+void QListView::setResizeMode(ResizeMode mode)
+{
+ Q_D(QListView);
+ d->modeProperties |= uint(QListViewPrivate::ResizeMode);
+ d->resizeMode = mode;
+}
+
+QListView::ResizeMode QListView::resizeMode() const
+{
+ Q_D(const QListView);
+ return d->resizeMode;
+}
+
+/*!
+ \property QListView::layoutMode
+ \brief determines whether the layout of items should happen immediately or be delayed.
+
+ This property holds the layout mode for the items. When the mode
+ is \l SinglePass (the default), the items are laid out all in one go.
+ When the mode is \l Batched, the items are laid out in batches of \l batchSize
+ items, while processing events. This makes it possible to
+ instantly view and interact with the visible items while the rest
+ are being laid out.
+
+ \sa viewMode
+*/
+void QListView::setLayoutMode(LayoutMode mode)
+{
+ Q_D(QListView);
+ d->layoutMode = mode;
+}
+
+QListView::LayoutMode QListView::layoutMode() const
+{
+ Q_D(const QListView);
+ return d->layoutMode;
+}
+
+/*!
+ \property QListView::spacing
+ \brief the space around the items in the layout
+
+ This property is the size of the empty space that is padded around
+ an item in the layout.
+
+ Setting this property when the view is visible will cause the
+ items to be laid out again.
+
+ By default, this property contains a value of 0.
+
+ \sa viewMode
+*/
+// ### Qt5: Use same semantic as layouts (spacing is the size of space
+// *between* items)
+void QListView::setSpacing(int space)
+{
+ Q_D(QListView);
+ d->modeProperties |= uint(QListViewPrivate::Spacing);
+ d->setSpacing(space);
+ d->doDelayedItemsLayout();
+}
+
+int QListView::spacing() const
+{
+ Q_D(const QListView);
+ return d->spacing();
+}
+
+/*!
+ \property QListView::batchSize
+ \brief the number of items laid out in each batch if \l layoutMode is
+ set to \l Batched
+
+ The default value is 100.
+
+ \since 4.2
+*/
+
+void QListView::setBatchSize(int batchSize)
+{
+ Q_D(QListView);
+ if (batchSize <= 0) {
+ qWarning("Invalid batchSize (%d)", batchSize);
+ return;
+ }
+ d->batchSize = batchSize;
+}
+
+int QListView::batchSize() const
+{
+ Q_D(const QListView);
+ return d->batchSize;
+}
+
+/*!
+ \property QListView::gridSize
+ \brief the size of the layout grid
+
+ This property is the size of the grid in which the items are laid
+ out. The default is an empty size which means that there is no
+ grid and the layout is not done in a grid. Setting this property
+ to a non-empty size switches on the grid layout. (When a grid
+ layout is in force the \l spacing property is ignored.)
+
+ Setting this property when the view is visible will cause the
+ items to be laid out again.
+
+ \sa viewMode
+*/
+void QListView::setGridSize(const QSize &size)
+{
+ Q_D(QListView);
+ d->modeProperties |= uint(QListViewPrivate::GridSize);
+ d->setGridSize(size);
+ d->doDelayedItemsLayout();
+}
+
+QSize QListView::gridSize() const
+{
+ Q_D(const QListView);
+ return d->gridSize();
+}
+
+/*!
+ \property QListView::viewMode
+ \brief the view mode of the QListView.
+
+ This property will change the other unset properties to conform
+ with the set view mode. QListView-specific properties that have already been set
+ will not be changed, unless clearPropertyFlags() has been called.
+
+ Setting the view mode will enable or disable drag and drop based on the
+ selected movement. For ListMode, the default movement is \l Static
+ (drag and drop disabled); for IconMode, the default movement is
+ \l Free (drag and drop enabled).
+
+ \sa isWrapping, spacing, gridSize, flow, movement, resizeMode
+*/
+void QListView::setViewMode(ViewMode mode)
+{
+ Q_D(QListView);
+ if (d->commonListView && d->viewMode == mode)
+ return;
+ d->viewMode = mode;
+
+ delete d->commonListView;
+ if (mode == ListMode) {
+ d->commonListView = new QListModeViewBase(this, d);
+ if (!(d->modeProperties & QListViewPrivate::Wrap))
+ d->setWrapping(false);
+ if (!(d->modeProperties & QListViewPrivate::Spacing))
+ d->setSpacing(0);
+ if (!(d->modeProperties & QListViewPrivate::GridSize))
+ d->setGridSize(QSize());
+ if (!(d->modeProperties & QListViewPrivate::Flow))
+ d->flow = TopToBottom;
+ if (!(d->modeProperties & QListViewPrivate::Movement))
+ d->movement = Static;
+ if (!(d->modeProperties & QListViewPrivate::ResizeMode))
+ d->resizeMode = Fixed;
+ if (!(d->modeProperties & QListViewPrivate::SelectionRectVisible))
+ d->showElasticBand = false;
+ } else {
+ d->commonListView = new QIconModeViewBase(this, d);
+ if (!(d->modeProperties & QListViewPrivate::Wrap))
+ d->setWrapping(true);
+ if (!(d->modeProperties & QListViewPrivate::Spacing))
+ d->setSpacing(0);
+ if (!(d->modeProperties & QListViewPrivate::GridSize))
+ d->setGridSize(QSize());
+ if (!(d->modeProperties & QListViewPrivate::Flow))
+ d->flow = LeftToRight;
+ if (!(d->modeProperties & QListViewPrivate::Movement))
+ d->movement = Free;
+ if (!(d->modeProperties & QListViewPrivate::ResizeMode))
+ d->resizeMode = Fixed;
+ if (!(d->modeProperties & QListViewPrivate::SelectionRectVisible))
+ d->showElasticBand = true;
+ }
+
+#ifndef QT_NO_DRAGANDDROP
+ bool movable = (d->movement != Static);
+ setDragEnabled(movable);
+ setAcceptDrops(movable);
+#endif
+ d->clear();
+ d->doDelayedItemsLayout();
+}
+
+QListView::ViewMode QListView::viewMode() const
+{
+ Q_D(const QListView);
+ return d->viewMode;
+}
+
+/*!
+ Clears the QListView-specific property flags. See \l{viewMode}.
+
+ Properties inherited from QAbstractItemView are not covered by the
+ property flags. Specifically, \l{QAbstractItemView::dragEnabled}
+ {dragEnabled} and \l{QAbstractItemView::acceptDrops}
+ {acceptsDrops} are computed by QListView when calling
+ setMovement() or setViewMode().
+*/
+void QListView::clearPropertyFlags()
+{
+ Q_D(QListView);
+ d->modeProperties = 0;
+}
+
+/*!
+ Returns true if the \a row is hidden; otherwise returns false.
+*/
+bool QListView::isRowHidden(int row) const
+{
+ Q_D(const QListView);
+ return d->isHidden(row);
+}
+
+/*!
+ If \a hide is true, the given \a row will be hidden; otherwise
+ the \a row will be shown.
+*/
+void QListView::setRowHidden(int row, bool hide)
+{
+ Q_D(QListView);
+ const bool hidden = d->isHidden(row);
+ if (hide && !hidden)
+ d->commonListView->appendHiddenRow(row);
+ else if (!hide && hidden)
+ d->commonListView->removeHiddenRow(row);
+ d->doDelayedItemsLayout();
+ d->viewport->update();
+}
+
+/*!
+ \reimp
+*/
+QRect QListView::visualRect(const QModelIndex &index) const
+{
+ Q_D(const QListView);
+ return d->mapToViewport(rectForIndex(index));
+}
+
+/*!
+ \reimp
+*/
+void QListView::scrollTo(const QModelIndex &index, ScrollHint hint)
+{
+ Q_D(QListView);
+
+ if (index.parent() != d->root || index.column() != d->column)
+ return;
+
+ const QRect rect = visualRect(index);
+ if (hint == EnsureVisible && d->viewport->rect().contains(rect)) {
+ d->viewport->update(rect);
+ return;
+ }
+
+ if (d->flow == QListView::TopToBottom || d->isWrapping()) // vertical
+ verticalScrollBar()->setValue(d->verticalScrollToValue(index, rect, hint));
+
+ if (d->flow == QListView::LeftToRight || d->isWrapping()) // horizontal
+ horizontalScrollBar()->setValue(d->horizontalScrollToValue(index, rect, hint));
+}
+
+int QListViewPrivate::horizontalScrollToValue(const QModelIndex &index, const QRect &rect,
+ QListView::ScrollHint hint) const
+{
+ Q_Q(const QListView);
+ const QRect area = viewport->rect();
+ const bool leftOf = q->isRightToLeft()
+ ? (rect.left() < area.left()) && (rect.right() < area.right())
+ : rect.left() < area.left();
+ const bool rightOf = q->isRightToLeft()
+ ? rect.right() > area.right()
+ : (rect.right() > area.right()) && (rect.left() > area.left());
+ return commonListView->horizontalScrollToValue(q->visualIndex(index), hint, leftOf, rightOf, area, rect);
+}
+
+int QListViewPrivate::verticalScrollToValue(const QModelIndex &index, const QRect &rect,
+ QListView::ScrollHint hint) const
+{
+ Q_Q(const QListView);
+ const QRect area = viewport->rect();
+ const bool above = (hint == QListView::EnsureVisible && rect.top() < area.top());
+ const bool below = (hint == QListView::EnsureVisible && rect.bottom() > area.bottom());
+ return commonListView->verticalScrollToValue(q->visualIndex(index), hint, above, below, area, rect);
+}
+
+void QListViewPrivate::selectAll(QItemSelectionModel::SelectionFlags command)
+{
+ if (!selectionModel)
+ return;
+
+ QItemSelection selection;
+ QModelIndex topLeft;
+ int row = 0;
+ const int colCount = model->columnCount(root);
+ for(; row < model->rowCount(root); ++row) {
+ if (isHidden(row)) {
+ //it might be the end of a selection range
+ if (topLeft.isValid()) {
+ QModelIndex bottomRight = model->index(row - 1, colCount - 1, root);
+ selection.append(QItemSelectionRange(topLeft, bottomRight));
+ topLeft = QModelIndex();
+ }
+ continue;
+ }
+
+ if (!topLeft.isValid()) //start of a new selection range
+ topLeft = model->index(row, 0, root);
+ }
+
+ if (topLeft.isValid()) {
+ //last selected range
+ QModelIndex bottomRight = model->index(row - 1, colCount - 1, root);
+ selection.append(QItemSelectionRange(topLeft, bottomRight));
+ }
+
+ if (!selection.isEmpty())
+ selectionModel->select(selection, command);
+}
+
+/*!
+ \reimp
+
+ We have a QListView way of knowing what elements are on the viewport
+ through the intersectingSet function
+*/
+QItemViewPaintPairs QListViewPrivate::draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const
+{
+ Q_ASSERT(r);
+ Q_Q(const QListView);
+ QRect &rect = *r;
+ const QRect viewportRect = viewport->rect();
+ QItemViewPaintPairs ret;
+ const QSet<QModelIndex> visibleIndexes = intersectingSet(viewportRect).toList().toSet();
+ for (int i = 0; i < indexes.count(); ++i) {
+ const QModelIndex &index = indexes.at(i);
+ if (visibleIndexes.contains(index)) {
+ const QRect current = q->visualRect(index);
+ ret += qMakePair(current, index);
+ rect |= current;
+ }
+ }
+ rect &= viewportRect;
+ return ret;
+}
+
+/*!
+ \internal
+*/
+void QListView::reset()
+{
+ Q_D(QListView);
+ d->clear();
+ d->hiddenRows.clear();
+ QAbstractItemView::reset();
+}
+
+/*!
+ \internal
+*/
+void QListView::setRootIndex(const QModelIndex &index)
+{
+ Q_D(QListView);
+ d->column = qBound(0, d->column, d->model->columnCount(index) - 1);
+ QAbstractItemView::setRootIndex(index);
+ // sometimes we get an update before reset() is called
+ d->clear();
+ d->hiddenRows.clear();
+}
+
+/*!
+ \internal
+
+ Scroll the view contents by \a dx and \a dy.
+*/
+
+void QListView::scrollContentsBy(int dx, int dy)
+{
+ Q_D(QListView);
+ d->delayedAutoScroll.stop(); // auto scroll was canceled by the user scrolling
+ d->commonListView->scrollContentsBy(dx, dy, d->state == QListView::DragSelectingState);
+}
+
+/*!
+ \internal
+
+ Resize the internal contents to \a width and \a height and set the
+ scroll bar ranges accordingly.
+*/
+void QListView::resizeContents(int width, int height)
+{
+ Q_D(QListView);
+ d->setContentsSize(width, height);
+}
+
+/*!
+ \internal
+*/
+QSize QListView::contentsSize() const
+{
+ Q_D(const QListView);
+ return d->contentsSize();
+}
+
+/*!
+ \reimp
+*/
+void QListView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
+{
+ d_func()->commonListView->dataChanged(topLeft, bottomRight);
+ QAbstractItemView::dataChanged(topLeft, bottomRight);
+}
+
+/*!
+ \reimp
+*/
+void QListView::rowsInserted(const QModelIndex &parent, int start, int end)
+{
+ Q_D(QListView);
+ // ### be smarter about inserted items
+ d->clear();
+ d->doDelayedItemsLayout();
+ QAbstractItemView::rowsInserted(parent, start, end);
+}
+
+/*!
+ \reimp
+*/
+void QListView::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
+{
+ Q_D(QListView);
+ // if the parent is above d->root in the tree, nothing will happen
+ QAbstractItemView::rowsAboutToBeRemoved(parent, start, end);
+ if (parent == d->root) {
+ QSet<QPersistentModelIndex>::iterator it = d->hiddenRows.begin();
+ while (it != d->hiddenRows.end()) {
+ int hiddenRow = it->row();
+ if (hiddenRow >= start && hiddenRow <= end) {
+ it = d->hiddenRows.erase(it);
+ } else {
+ ++it;
+ }
+ }
+ }
+ d->clear();
+ d->doDelayedItemsLayout();
+}
+
+/*!
+ \reimp
+*/
+void QListView::mouseMoveEvent(QMouseEvent *e)
+{
+ if (!isVisible())
+ return;
+ Q_D(QListView);
+ QAbstractItemView::mouseMoveEvent(e);
+ if (state() == DragSelectingState
+ && d->showElasticBand
+ && d->selectionMode != SingleSelection
+ && d->selectionMode != NoSelection) {
+ QRect rect(d->pressedPosition, e->pos() + QPoint(horizontalOffset(), verticalOffset()));
+ rect = rect.normalized();
+ d->viewport->update(d->mapToViewport(rect.united(d->elasticBand)));
+ d->elasticBand = rect;
+ }
+}
+
+/*!
+ \reimp
+*/
+void QListView::mouseReleaseEvent(QMouseEvent *e)
+{
+ Q_D(QListView);
+ QAbstractItemView::mouseReleaseEvent(e);
+ // #### move this implementation into a dynamic class
+ if (d->showElasticBand && d->elasticBand.isValid()) {
+ d->viewport->update(d->mapToViewport(d->elasticBand));
+ d->elasticBand = QRect();
+ }
+}
+
+/*!
+ \reimp
+*/
+void QListView::timerEvent(QTimerEvent *e)
+{
+ Q_D(QListView);
+ if (e->timerId() == d->batchLayoutTimer.timerId()) {
+ if (d->doItemsLayout(d->batchSize)) { // layout is done
+ d->batchLayoutTimer.stop();
+ updateGeometries();
+ d->viewport->update();
+ }
+ }
+ QAbstractItemView::timerEvent(e);
+}
+
+/*!
+ \reimp
+*/
+void QListView::resizeEvent(QResizeEvent *e)
+{
+ Q_D(QListView);
+ if (d->delayedPendingLayout)
+ return;
+
+ QSize delta = e->size() - e->oldSize();
+
+ if (delta.isNull())
+ return;
+
+ bool listWrap = (d->viewMode == ListMode) && d->wrapItemText;
+ bool flowDimensionChanged = (d->flow == LeftToRight && delta.width() != 0)
+ || (d->flow == TopToBottom && delta.height() != 0);
+
+ // We post a delayed relayout in the following cases :
+ // - we're wrapping
+ // - the state is NoState, we're adjusting and the size has changed in the flowing direction
+ if (listWrap
+ || (state() == NoState && d->resizeMode == Adjust && flowDimensionChanged)) {
+ d->doDelayedItemsLayout(100); // wait 1/10 sec before starting the layout
+ } else {
+ QAbstractItemView::resizeEvent(e);
+ }
+}
+
+#ifndef QT_NO_DRAGANDDROP
+
+/*!
+ \reimp
+*/
+void QListView::dragMoveEvent(QDragMoveEvent *e)
+{
+ Q_D(QListView);
+ if (!d->commonListView->filterDragMoveEvent(e)) {
+ if (viewMode() == QListView::ListMode && flow() == QListView::LeftToRight)
+ static_cast<QListModeViewBase *>(d->commonListView)->dragMoveEvent(e);
+ else
+ QAbstractItemView::dragMoveEvent(e);
+ }
+}
+
+
+/*!
+ \reimp
+*/
+void QListView::dragLeaveEvent(QDragLeaveEvent *e)
+{
+ if (!d_func()->commonListView->filterDragLeaveEvent(e))
+ QAbstractItemView::dragLeaveEvent(e);
+}
+
+/*!
+ \reimp
+*/
+void QListView::dropEvent(QDropEvent *e)
+{
+ if (!d_func()->commonListView->filterDropEvent(e))
+ QAbstractItemView::dropEvent(e);
+}
+
+/*!
+ \reimp
+*/
+void QListView::startDrag(Qt::DropActions supportedActions)
+{
+ if (!d_func()->commonListView->filterStartDrag(supportedActions))
+ QAbstractItemView::startDrag(supportedActions);
+}
+
+/*!
+ \internal
+
+ Called whenever items from the view is dropped on the viewport.
+ The \a event provides additional information.
+*/
+void QListView::internalDrop(QDropEvent *event)
+{
+ // ### Qt5: remove that function
+ Q_UNUSED(event);
+}
+
+/*!
+ \internal
+
+ Called whenever the user starts dragging items and the items are movable,
+ enabling internal dragging and dropping of items.
+*/
+void QListView::internalDrag(Qt::DropActions supportedActions)
+{
+ // ### Qt5: remove that function
+ Q_UNUSED(supportedActions);
+}
+
+#endif // QT_NO_DRAGANDDROP
+
+/*!
+ \reimp
+*/
+QStyleOptionViewItem QListView::viewOptions() const
+{
+ Q_D(const QListView);
+ QStyleOptionViewItem option = QAbstractItemView::viewOptions();
+ if (!d->iconSize.isValid()) { // otherwise it was already set in abstractitemview
+ int pm = (d->viewMode == ListMode
+ ? style()->pixelMetric(QStyle::PM_ListViewIconSize, 0, this)
+ : style()->pixelMetric(QStyle::PM_IconViewIconSize, 0, this));
+ option.decorationSize = QSize(pm, pm);
+ }
+ if (d->viewMode == IconMode) {
+ option.showDecorationSelected = false;
+ option.decorationPosition = QStyleOptionViewItem::Top;
+ option.displayAlignment = Qt::AlignCenter;
+ } else {
+ option.decorationPosition = QStyleOptionViewItem::Left;
+ }
+ return option;
+}
+
+
+/*!
+ \reimp
+*/
+void QListView::paintEvent(QPaintEvent *e)
+{
+ Q_D(QListView);
+ if (!d->itemDelegate)
+ return;
+ QStyleOptionViewItemV4 option = d->viewOptionsV4();
+ QPainter painter(d->viewport);
+
+ const QVector<QModelIndex> toBeRendered = d->intersectingSet(e->rect().translated(horizontalOffset(), verticalOffset()), false);
+
+ const QModelIndex current = currentIndex();
+ const QModelIndex hover = d->hover;
+ const QAbstractItemModel *itemModel = d->model;
+ const QItemSelectionModel *selections = d->selectionModel;
+ const bool focus = (hasFocus() || d->viewport->hasFocus()) && current.isValid();
+ const bool alternate = d->alternatingColors;
+ const QStyle::State state = option.state;
+ const QAbstractItemView::State viewState = this->state();
+ const bool enabled = (state & QStyle::State_Enabled) != 0;
+
+ bool alternateBase = false;
+ int previousRow = -2; // trigger the alternateBase adjustment on first pass
+
+ int maxSize = (flow() == TopToBottom)
+ ? qMax(viewport()->size().width(), d->contentsSize().width()) - 2 * d->spacing()
+ : qMax(viewport()->size().height(), d->contentsSize().height()) - 2 * d->spacing();
+
+ QVector<QModelIndex>::const_iterator end = toBeRendered.constEnd();
+ for (QVector<QModelIndex>::const_iterator it = toBeRendered.constBegin(); it != end; ++it) {
+ Q_ASSERT((*it).isValid());
+ option.rect = visualRect(*it);
+
+ if (flow() == TopToBottom)
+ option.rect.setWidth(qMin(maxSize, option.rect.width()));
+ else
+ option.rect.setHeight(qMin(maxSize, option.rect.height()));
+
+ option.state = state;
+ if (selections && selections->isSelected(*it))
+ option.state |= QStyle::State_Selected;
+ if (enabled) {
+ QPalette::ColorGroup cg;
+ if ((itemModel->flags(*it) & Qt::ItemIsEnabled) == 0) {
+ option.state &= ~QStyle::State_Enabled;
+ cg = QPalette::Disabled;
+ } else {
+ cg = QPalette::Normal;
+ }
+ option.palette.setCurrentColorGroup(cg);
+ }
+ if (focus && current == *it) {
+ option.state |= QStyle::State_HasFocus;
+ if (viewState == EditingState)
+ option.state |= QStyle::State_Editing;
+ }
+ if (*it == hover)
+ option.state |= QStyle::State_MouseOver;
+ else
+ option.state &= ~QStyle::State_MouseOver;
+
+ if (alternate) {
+ int row = (*it).row();
+ if (row != previousRow + 1) {
+ // adjust alternateBase according to rows in the "gap"
+ if (!d->hiddenRows.isEmpty()) {
+ for (int r = qMax(previousRow + 1, 0); r < row; ++r) {
+ if (!d->isHidden(r))
+ alternateBase = !alternateBase;
+ }
+ } else {
+ alternateBase = (row & 1) != 0;
+ }
+ }
+ if (alternateBase) {
+ option.features |= QStyleOptionViewItemV2::Alternate;
+ } else {
+ option.features &= ~QStyleOptionViewItemV2::Alternate;
+ }
+
+ // draw background of the item (only alternate row). rest of the background
+ // is provided by the delegate
+ QStyle::State oldState = option.state;
+ option.state &= ~QStyle::State_Selected;
+ style()->drawPrimitive(QStyle::PE_PanelItemViewRow, &option, &painter, this);
+ option.state = oldState;
+
+ alternateBase = !alternateBase;
+ previousRow = row;
+ }
+
+ d->delegateForIndex(*it)->paint(&painter, option, *it);
+ }
+
+#ifndef QT_NO_DRAGANDDROP
+ d->commonListView->paintDragDrop(&painter);
+#endif
+
+#ifndef QT_NO_RUBBERBAND
+ // #### move this implementation into a dynamic class
+ if (d->showElasticBand && d->elasticBand.isValid()) {
+ QStyleOptionRubberBand opt;
+ opt.initFrom(this);
+ opt.shape = QRubberBand::Rectangle;
+ opt.opaque = false;
+ opt.rect = d->mapToViewport(d->elasticBand, false).intersected(
+ d->viewport->rect().adjusted(-16, -16, 16, 16));
+ painter.save();
+ style()->drawControl(QStyle::CE_RubberBand, &opt, &painter);
+ painter.restore();
+ }
+#endif
+}
+
+/*!
+ \reimp
+*/
+QModelIndex QListView::indexAt(const QPoint &p) const
+{
+ Q_D(const QListView);
+ QRect rect(p.x() + horizontalOffset(), p.y() + verticalOffset(), 1, 1);
+ const QVector<QModelIndex> intersectVector = d->intersectingSet(rect);
+ QModelIndex index = intersectVector.count() > 0
+ ? intersectVector.last() : QModelIndex();
+ if (index.isValid() && visualRect(index).contains(p))
+ return index;
+ return QModelIndex();
+}
+
+/*!
+ \reimp
+*/
+int QListView::horizontalOffset() const
+{
+ return d_func()->commonListView->horizontalOffset();
+}
+
+/*!
+ \reimp
+*/
+int QListView::verticalOffset() const
+{
+ return d_func()->commonListView->verticalOffset();
+}
+
+/*!
+ \reimp
+*/
+QModelIndex QListView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers)
+{
+ Q_D(QListView);
+ Q_UNUSED(modifiers);
+
+ QModelIndex current = currentIndex();
+ if (!current.isValid()) {
+ int rowCount = d->model->rowCount(d->root);
+ if (!rowCount)
+ return QModelIndex();
+ int row = 0;
+ while (row < rowCount && d->isHiddenOrDisabled(row))
+ ++row;
+ if (row >= rowCount)
+ return QModelIndex();
+ return d->model->index(row, d->column, d->root);
+ }
+
+ const QRect initialRect = rectForIndex(current);
+ QRect rect = initialRect;
+ if (rect.isEmpty()) {
+ return d->model->index(0, d->column, d->root);
+ }
+ if (d->gridSize().isValid()) rect.setSize(d->gridSize());
+
+ QSize contents = d->contentsSize();
+ QVector<QModelIndex> intersectVector;
+
+ switch (cursorAction) {
+ case MoveLeft:
+ while (intersectVector.isEmpty()) {
+ rect.translate(-rect.width(), 0);
+ if (rect.right() <= 0)
+ return current;
+ if (rect.left() < 0)
+ rect.setLeft(0);
+ intersectVector = d->intersectingSet(rect);
+ d->removeCurrentAndDisabled(&intersectVector, current);
+ }
+ return d->closestIndex(initialRect, intersectVector);
+ case MoveRight:
+ while (intersectVector.isEmpty()) {
+ rect.translate(rect.width(), 0);
+ if (rect.left() >= contents.width())
+ return current;
+ if (rect.right() > contents.width())
+ rect.setRight(contents.width());
+ intersectVector = d->intersectingSet(rect);
+ d->removeCurrentAndDisabled(&intersectVector, current);
+ }
+ return d->closestIndex(initialRect, intersectVector);
+ case MovePageUp:
+ // move current by (visibileRowCount - 1) items.
+ // rect.translate(0, -rect.height()); will happen in the switch fallthrough for MoveUp.
+ rect.moveTop(rect.top() - d->viewport->height() + 2 * rect.height());
+ if (rect.top() < rect.height())
+ rect.moveTop(rect.height());
+ case MovePrevious:
+ case MoveUp:
+ while (intersectVector.isEmpty()) {
+ rect.translate(0, -rect.height());
+ if (rect.bottom() <= 0) {
+#ifdef QT_KEYPAD_NAVIGATION
+ if (QApplication::keypadNavigationEnabled()) {
+ int row = d->batchStartRow() - 1;
+ while (row >= 0 && d->isHiddenOrDisabled(row))
+ --row;
+ if (row >= 0)
+ return d->model->index(row, d->column, d->root);
+ }
+#endif
+ return current;
+ }
+ if (rect.top() < 0)
+ rect.setTop(0);
+ intersectVector = d->intersectingSet(rect);
+ d->removeCurrentAndDisabled(&intersectVector, current);
+ }
+ return d->closestIndex(initialRect, intersectVector);
+ case MovePageDown:
+ // move current by (visibileRowCount - 1) items.
+ // rect.translate(0, rect.height()); will happen in the switch fallthrough for MoveDown.
+ rect.moveTop(rect.top() + d->viewport->height() - 2 * rect.height());
+ if (rect.bottom() > contents.height() - rect.height())
+ rect.moveBottom(contents.height() - rect.height());
+ case MoveNext:
+ case MoveDown:
+ while (intersectVector.isEmpty()) {
+ rect.translate(0, rect.height());
+ if (rect.top() >= contents.height()) {
+#ifdef QT_KEYPAD_NAVIGATION
+ if (QApplication::keypadNavigationEnabled()) {
+ int rowCount = d->model->rowCount(d->root);
+ int row = 0;
+ while (row < rowCount && d->isHiddenOrDisabled(row))
+ ++row;
+ if (row < rowCount)
+ return d->model->index(row, d->column, d->root);
+ }
+#endif
+ return current;
+ }
+ if (rect.bottom() > contents.height())
+ rect.setBottom(contents.height());
+ intersectVector = d->intersectingSet(rect);
+ d->removeCurrentAndDisabled(&intersectVector, current);
+ }
+ return d->closestIndex(initialRect, intersectVector);
+ case MoveHome:
+ return d->model->index(0, d->column, d->root);
+ case MoveEnd:
+ return d->model->index(d->batchStartRow() - 1, d->column, d->root);}
+
+ return current;
+}
+
+/*!
+ Returns the rectangle of the item at position \a index in the
+ model. The rectangle is in contents coordinates.
+
+ \sa visualRect()
+*/
+QRect QListView::rectForIndex(const QModelIndex &index) const
+{
+ return d_func()->rectForIndex(index);
+}
+
+/*!
+ \since 4.1
+
+ Sets the contents position of the item at \a index in the model to the given
+ \a position.
+ If the list view's movement mode is Static or its view mode is ListView,
+ this function will have no effect.
+*/
+void QListView::setPositionForIndex(const QPoint &position, const QModelIndex &index)
+{
+ Q_D(QListView);
+ if (d->movement == Static
+ || !d->isIndexValid(index)
+ || index.parent() != d->root
+ || index.column() != d->column)
+ return;
+
+ d->executePostedLayout();
+ d->commonListView->setPositionForIndex(position, index);
+}
+
+/*!
+ \reimp
+*/
+void QListView::setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags command)
+{
+ Q_D(QListView);
+ if (!d->selectionModel)
+ return;
+
+ // if we are wrapping, we can only selecte inside the contents rectangle
+ int w = qMax(d->contentsSize().width(), d->viewport->width());
+ int h = qMax(d->contentsSize().height(), d->viewport->height());
+ if (d->wrap && !QRect(0, 0, w, h).intersects(rect))
+ return;
+
+ QItemSelection selection;
+
+ if (rect.width() == 1 && rect.height() == 1) {
+ const QVector<QModelIndex> intersectVector = d->intersectingSet(rect.translated(horizontalOffset(), verticalOffset()));
+ QModelIndex tl;
+ if (!intersectVector.isEmpty())
+ tl = intersectVector.last(); // special case for mouse press; only select the top item
+ if (tl.isValid() && d->isIndexEnabled(tl))
+ selection.select(tl, tl);
+ } else {
+ if (state() == DragSelectingState) { // visual selection mode (rubberband selection)
+ selection = d->selection(rect.translated(horizontalOffset(), verticalOffset()));
+ } else { // logical selection mode (key and mouse click selection)
+ QModelIndex tl, br;
+ // get the first item
+ const QRect topLeft(rect.left() + horizontalOffset(), rect.top() + verticalOffset(), 1, 1);
+ QVector<QModelIndex> intersectVector = d->intersectingSet(topLeft);
+ if (!intersectVector.isEmpty())
+ tl = intersectVector.last();
+ // get the last item
+ const QRect bottomRight(rect.right() + horizontalOffset(), rect.bottom() + verticalOffset(), 1, 1);
+ intersectVector = d->intersectingSet(bottomRight);
+ if (!intersectVector.isEmpty())
+ br = intersectVector.last();
+
+ // get the ranges
+ if (tl.isValid() && br.isValid()
+ && d->isIndexEnabled(tl)
+ && d->isIndexEnabled(br)) {
+ QRect first = rectForIndex(tl);
+ QRect last = rectForIndex(br);
+ QRect middle;
+ if (d->flow == LeftToRight) {
+ QRect &top = first;
+ QRect &bottom = last;
+ // if bottom is above top, swap them
+ if (top.center().y() > bottom.center().y()) {
+ QRect tmp = top;
+ top = bottom;
+ bottom = tmp;
+ }
+ // if the rect are on differnet lines, expand
+ if (top.top() != bottom.top()) {
+ // top rectangle
+ if (isRightToLeft())
+ top.setLeft(0);
+ else
+ top.setRight(contentsSize().width());
+ // bottom rectangle
+ if (isRightToLeft())
+ bottom.setRight(contentsSize().width());
+ else
+ bottom.setLeft(0);
+ } else if (top.left() > bottom.right()) {
+ if (isRightToLeft())
+ bottom.setLeft(top.right());
+ else
+ bottom.setRight(top.left());
+ } else {
+ if (isRightToLeft())
+ top.setLeft(bottom.right());
+ else
+ top.setRight(bottom.left());
+ }
+ // middle rectangle
+ if (top.bottom() < bottom.top()) {
+ if (gridSize().isValid() && !gridSize().isNull())
+ middle.setTop(top.top() + gridSize().height());
+ else
+ middle.setTop(top.bottom() + 1);
+ middle.setLeft(qMin(top.left(), bottom.left()));
+ middle.setBottom(bottom.top() - 1);
+ middle.setRight(qMax(top.right(), bottom.right()));
+ }
+ } else { // TopToBottom
+ QRect &left = first;
+ QRect &right = last;
+ if (left.center().x() > right.center().x())
+ qSwap(left, right);
+
+ int ch = contentsSize().height();
+ if (left.left() != right.left()) {
+ // left rectangle
+ if (isRightToLeft())
+ left.setTop(0);
+ else
+ left.setBottom(ch);
+
+ // top rectangle
+ if (isRightToLeft())
+ right.setBottom(ch);
+ else
+ right.setTop(0);
+ // only set middle if the
+ middle.setTop(0);
+ middle.setBottom(ch);
+ if (gridSize().isValid() && !gridSize().isNull())
+ middle.setLeft(left.left() + gridSize().width());
+ else
+ middle.setLeft(left.right() + 1);
+ middle.setRight(right.left() - 1);
+ } else if (left.bottom() < right.top()) {
+ left.setBottom(right.top() - 1);
+ } else {
+ right.setBottom(left.top() - 1);
+ }
+ }
+
+ // do the selections
+ QItemSelection topSelection = d->selection(first);
+ QItemSelection middleSelection = d->selection(middle);
+ QItemSelection bottomSelection = d->selection(last);
+ // merge
+ selection.merge(topSelection, QItemSelectionModel::Select);
+ selection.merge(middleSelection, QItemSelectionModel::Select);
+ selection.merge(bottomSelection, QItemSelectionModel::Select);
+ }
+ }
+ }
+
+ d->selectionModel->select(selection, command);
+}
+
+/*!
+ \reimp
+
+ Since 4.7, the returned region only contains rectangles intersecting
+ (or included in) the viewport.
+*/
+QRegion QListView::visualRegionForSelection(const QItemSelection &selection) const
+{
+ Q_D(const QListView);
+ // ### NOTE: this is a potential bottleneck in non-static mode
+ int c = d->column;
+ QRegion selectionRegion;
+ const QRect &viewportRect = d->viewport->rect();
+ for (int i = 0; i < selection.count(); ++i) {
+ if (!selection.at(i).isValid())
+ continue;
+ QModelIndex parent = selection.at(i).topLeft().parent();
+ //we only display the children of the root in a listview
+ //we're not interested in the other model indexes
+ if (parent != d->root)
+ continue;
+ int t = selection.at(i).topLeft().row();
+ int b = selection.at(i).bottomRight().row();
+ if (d->viewMode == IconMode || d->isWrapping()) { // in non-static mode, we have to go through all selected items
+ for (int r = t; r <= b; ++r) {
+ const QRect &rect = visualRect(d->model->index(r, c, parent));
+ if (viewportRect.intersects(rect))
+ selectionRegion += rect;
+ }
+ } else { // in static mode, we can optimize a bit
+ while (t <= b && d->isHidden(t)) ++t;
+ while (b >= t && d->isHidden(b)) --b;
+ const QModelIndex top = d->model->index(t, c, parent);
+ const QModelIndex bottom = d->model->index(b, c, parent);
+ QRect rect(visualRect(top).topLeft(),
+ visualRect(bottom).bottomRight());
+ if (viewportRect.intersects(rect))
+ selectionRegion += rect;
+ }
+ }
+
+ return selectionRegion;
+}
+
+/*!
+ \reimp
+*/
+QModelIndexList QListView::selectedIndexes() const
+{
+ Q_D(const QListView);
+ if (!d->selectionModel)
+ return QModelIndexList();
+
+ QModelIndexList viewSelected = d->selectionModel->selectedIndexes();
+ for (int i = 0; i < viewSelected.count(); ++i) {
+ const QModelIndex &index = viewSelected.at(i);
+ if (!isIndexHidden(index) && index.parent() == d->root && index.column() == d->column)
+ ++i;
+ else
+ viewSelected.removeAt(i);
+ }
+ return viewSelected;
+}
+
+/*!
+ \internal
+
+ Layout the items according to the flow and wrapping properties.
+*/
+void QListView::doItemsLayout()
+{
+ Q_D(QListView);
+ // showing the scroll bars will trigger a resize event,
+ // so we set the state to expanding to avoid
+ // triggering another layout
+ QAbstractItemView::State oldState = state();
+ setState(ExpandingState);
+ if (d->model->columnCount(d->root) > 0) { // no columns means no contents
+ d->resetBatchStartRow();
+ if (layoutMode() == SinglePass)
+ d->doItemsLayout(d->model->rowCount(d->root)); // layout everything
+ else if (!d->batchLayoutTimer.isActive()) {
+ if (!d->doItemsLayout(d->batchSize)) // layout is done
+ d->batchLayoutTimer.start(0, this); // do a new batch as fast as possible
+ }
+ }
+ QAbstractItemView::doItemsLayout();
+ setState(oldState); // restoring the oldState
+}
+
+/*!
+ \reimp
+*/
+void QListView::updateGeometries()
+{
+ Q_D(QListView);
+ if (d->model->rowCount(d->root) <= 0 || d->model->columnCount(d->root) <= 0) {
+ horizontalScrollBar()->setRange(0, 0);
+ verticalScrollBar()->setRange(0, 0);
+ } else {
+ QModelIndex index = d->model->index(0, d->column, d->root);
+ QStyleOptionViewItemV4 option = d->viewOptionsV4();
+ QSize step = d->itemSize(option, index);
+ d->commonListView->updateHorizontalScrollBar(step);
+ d->commonListView->updateVerticalScrollBar(step);
+ }
+
+ QAbstractItemView::updateGeometries();
+
+ // if the scroll bars are turned off, we resize the contents to the viewport
+ if (d->movement == Static && !d->isWrapping()) {
+ const QSize maxSize = maximumViewportSize();
+ if (d->flow == TopToBottom) {
+ if (horizontalScrollBarPolicy() == Qt::ScrollBarAlwaysOff) {
+ d->setContentsSize(maxSize.width(), contentsSize().height());
+ horizontalScrollBar()->setRange(0, 0); // we see all the contents anyway
+ }
+ } else { // LeftToRight
+ if (verticalScrollBarPolicy() == Qt::ScrollBarAlwaysOff) {
+ d->setContentsSize(contentsSize().width(), maxSize.height());
+ verticalScrollBar()->setRange(0, 0); // we see all the contents anyway
+ }
+ }
+ }
+
+}
+
+/*!
+ \reimp
+*/
+bool QListView::isIndexHidden(const QModelIndex &index) const
+{
+ Q_D(const QListView);
+ return (d->isHidden(index.row())
+ && (index.parent() == d->root)
+ && index.column() == d->column);
+}
+
+/*!
+ \property QListView::modelColumn
+ \brief the column in the model that is visible
+
+ By default, this property contains 0, indicating that the first
+ column in the model will be shown.
+*/
+void QListView::setModelColumn(int column)
+{
+ Q_D(QListView);
+ if (column < 0 || column >= d->model->columnCount(d->root))
+ return;
+ d->column = column;
+ d->doDelayedItemsLayout();
+}
+
+int QListView::modelColumn() const
+{
+ Q_D(const QListView);
+ return d->column;
+}
+
+/*!
+ \property QListView::uniformItemSizes
+ \brief whether all items in the listview have the same size
+ \since 4.1
+
+ This property should only be set to true if it is guaranteed that all items
+ in the view have the same size. This enables the view to do some
+ optimizations for performance purposes.
+
+ By default, this property is false.
+*/
+void QListView::setUniformItemSizes(bool enable)
+{
+ Q_D(QListView);
+ d->uniformItemSizes = enable;
+}
+
+bool QListView::uniformItemSizes() const
+{
+ Q_D(const QListView);
+ return d->uniformItemSizes;
+}
+
+/*!
+ \property QListView::wordWrap
+ \brief the item text word-wrapping policy
+ \since 4.2
+
+ If this property is true then the item text is wrapped where
+ necessary at word-breaks; otherwise it is not wrapped at all.
+ This property is false by default.
+
+ Please note that even if wrapping is enabled, the cell will not be
+ expanded to make room for the text. It will print ellipsis for
+ text that cannot be shown, according to the view's
+ \l{QAbstractItemView::}{textElideMode}.
+*/
+void QListView::setWordWrap(bool on)
+{
+ Q_D(QListView);
+ if (d->wrapItemText == on)
+ return;
+ d->wrapItemText = on;
+ d->doDelayedItemsLayout();
+}
+
+bool QListView::wordWrap() const
+{
+ Q_D(const QListView);
+ return d->wrapItemText;
+}
+
+/*!
+ \property QListView::selectionRectVisible
+ \brief if the selection rectangle should be visible
+ \since 4.3
+
+ If this property is true then the selection rectangle is visible;
+ otherwise it will be hidden.
+
+ \note The selection rectangle will only be visible if the selection mode
+ is in a mode where more than one item can be selected; i.e., it will not
+ draw a selection rectangle if the selection mode is
+ QAbstractItemView::SingleSelection.
+
+ By default, this property is false.
+*/
+void QListView::setSelectionRectVisible(bool show)
+{
+ Q_D(QListView);
+ d->modeProperties |= uint(QListViewPrivate::SelectionRectVisible);
+ d->setSelectionRectVisible(show);
+}
+
+bool QListView::isSelectionRectVisible() const
+{
+ Q_D(const QListView);
+ return d->isSelectionRectVisible();
+}
+
+/*!
+ \reimp
+*/
+bool QListView::event(QEvent *e)
+{
+ return QAbstractItemView::event(e);
+}
+
+/*
+ * private object implementation
+ */
+
+QListViewPrivate::QListViewPrivate()
+ : QAbstractItemViewPrivate(),
+ commonListView(0),
+ wrap(false),
+ space(0),
+ flow(QListView::TopToBottom),
+ movement(QListView::Static),
+ resizeMode(QListView::Fixed),
+ layoutMode(QListView::SinglePass),
+ viewMode(QListView::ListMode),
+ modeProperties(0),
+ column(0),
+ uniformItemSizes(false),
+ batchSize(100),
+ showElasticBand(false)
+{
+}
+
+QListViewPrivate::~QListViewPrivate()
+{
+ delete commonListView;
+}
+
+void QListViewPrivate::clear()
+{
+ // initialization of data structs
+ cachedItemSize = QSize();
+ commonListView->clear();
+}
+
+void QListViewPrivate::prepareItemsLayout()
+{
+ Q_Q(QListView);
+ clear();
+
+ //take the size as if there were scrollbar in order to prevent scrollbar to blink
+ layoutBounds = QRect(QPoint(), q->maximumViewportSize());
+
+ int frameAroundContents = 0;
+ if (q->style()->styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents))
+ frameAroundContents = q->style()->pixelMetric(QStyle::PM_DefaultFrameWidth) * 2;
+
+ // maximumViewportSize() already takes scrollbar into account if policy is
+ // Qt::ScrollBarAlwaysOn but scrollbar extent must be deduced if policy
+ // is Qt::ScrollBarAsNeeded
+ int verticalMargin = vbarpolicy==Qt::ScrollBarAsNeeded
+ ? q->style()->pixelMetric(QStyle::PM_ScrollBarExtent, 0, vbar) + frameAroundContents
+ : 0;
+ int horizontalMargin = hbarpolicy==Qt::ScrollBarAsNeeded
+ ? q->style()->pixelMetric(QStyle::PM_ScrollBarExtent, 0, hbar) + frameAroundContents
+ : 0;
+
+ layoutBounds.adjust(0, 0, -verticalMargin, -horizontalMargin);
+
+ int rowCount = model->columnCount(root) <= 0 ? 0 : model->rowCount(root);
+ commonListView->setRowCount(rowCount);
+}
+
+/*!
+ \internal
+*/
+bool QListViewPrivate::doItemsLayout(int delta)
+{
+ int max = model->rowCount(root) - 1;
+ int first = batchStartRow();
+ int last = qMin(first + delta - 1, max);
+
+ if (first == 0) {
+ layoutChildren(); // make sure the viewport has the right size
+ prepareItemsLayout();
+ }
+
+ if (max < 0 || last < first) {
+ return true; // nothing to do
+ }
+
+ QListViewLayoutInfo info;
+ info.bounds = layoutBounds;
+ info.grid = gridSize();
+ info.spacing = (info.grid.isValid() ? 0 : spacing());
+ info.first = first;
+ info.last = last;
+ info.wrap = isWrapping();
+ info.flow = flow;
+ info.max = max;
+
+ return commonListView->doBatchedItemLayout(info, max);
+}
+
+QListViewItem QListViewPrivate::indexToListViewItem(const QModelIndex &index) const
+{
+ if (!index.isValid() || isHidden(index.row()))
+ return QListViewItem();
+
+ return commonListView->indexToListViewItem(index);
+}
+
+QRect QListViewPrivate::mapToViewport(const QRect &rect, bool extend) const
+{
+ Q_Q(const QListView);
+ if (!rect.isValid())
+ return rect;
+
+ QRect result = extend ? commonListView->mapToViewport(rect) : rect;
+ int dx = -q->horizontalOffset();
+ int dy = -q->verticalOffset();
+ return result.adjusted(dx, dy, dx, dy);
+}
+
+QModelIndex QListViewPrivate::closestIndex(const QRect &target,
+ const QVector<QModelIndex> &candidates) const
+{
+ int distance = 0;
+ int shortest = INT_MAX;
+ QModelIndex closest;
+ QVector<QModelIndex>::const_iterator it = candidates.begin();
+
+ for (; it != candidates.end(); ++it) {
+ if (!(*it).isValid())
+ continue;
+
+ const QRect indexRect = indexToListViewItem(*it).rect();
+
+ //if the center x (or y) position of an item is included in the rect of the other item,
+ //we define the distance between them as the difference in x (or y) of their respective center.
+ // Otherwise, we use the nahattan length between the 2 items
+ if ((target.center().x() >= indexRect.x() && target.center().x() < indexRect.right())
+ || (indexRect.center().x() >= target.x() && indexRect.center().x() < target.right())) {
+ //one item's center is at the vertical of the other
+ distance = qAbs(indexRect.center().y() - target.center().y());
+ } else if ((target.center().y() >= indexRect.y() && target.center().y() < indexRect.bottom())
+ || (indexRect.center().y() >= target.y() && indexRect.center().y() < target.bottom())) {
+ //one item's center is at the vertical of the other
+ distance = qAbs(indexRect.center().x() - target.center().x());
+ } else {
+ distance = (indexRect.center() - target.center()).manhattanLength();
+ }
+ if (distance < shortest) {
+ shortest = distance;
+ closest = *it;
+ }
+ }
+ return closest;
+}
+
+QSize QListViewPrivate::itemSize(const QStyleOptionViewItem &option, const QModelIndex &index) const
+{
+ if (!uniformItemSizes) {
+ const QAbstractItemDelegate *delegate = delegateForIndex(index);
+ return delegate ? delegate->sizeHint(option, index) : QSize();
+ }
+ if (!cachedItemSize.isValid()) { // the last item is probaly the largest, so we use its size
+ int row = model->rowCount(root) - 1;
+ QModelIndex sample = model->index(row, column, root);
+ const QAbstractItemDelegate *delegate = delegateForIndex(sample);
+ cachedItemSize = delegate ? delegate->sizeHint(option, sample) : QSize();
+ }
+ return cachedItemSize;
+}
+
+QItemSelection QListViewPrivate::selection(const QRect &rect) const
+{
+ QItemSelection selection;
+ QModelIndex tl, br;
+ const QVector<QModelIndex> intersectVector = intersectingSet(rect);
+ QVector<QModelIndex>::const_iterator it = intersectVector.begin();
+ for (; it != intersectVector.end(); ++it) {
+ if (!tl.isValid() && !br.isValid()) {
+ tl = br = *it;
+ } else if ((*it).row() == (tl.row() - 1)) {
+ tl = *it; // expand current range
+ } else if ((*it).row() == (br.row() + 1)) {
+ br = (*it); // expand current range
+ } else {
+ selection.select(tl, br); // select current range
+ tl = br = *it; // start new range
+ }
+ }
+
+ if (tl.isValid() && br.isValid())
+ selection.select(tl, br);
+ else if (tl.isValid())
+ selection.select(tl, tl);
+ else if (br.isValid())
+ selection.select(br, br);
+
+ return selection;
+}
+
+#ifndef QT_NO_DRAGANDDROP
+QAbstractItemView::DropIndicatorPosition QListViewPrivate::position(const QPoint &pos, const QRect &rect, const QModelIndex &idx) const
+{
+ if (viewMode == QListView::ListMode && flow == QListView::LeftToRight)
+ return static_cast<QListModeViewBase *>(commonListView)->position(pos, rect, idx);
+ else
+ return QAbstractItemViewPrivate::position(pos, rect, idx);
+}
+
+bool QListViewPrivate::dropOn(QDropEvent *event, int *dropRow, int *dropCol, QModelIndex *dropIndex)
+{
+ if (viewMode == QListView::ListMode && flow == QListView::LeftToRight)
+ return static_cast<QListModeViewBase *>(commonListView)->dropOn(event, dropRow, dropCol, dropIndex);
+ else
+ return QAbstractItemViewPrivate::dropOn(event, dropRow, dropCol, dropIndex);
+}
+#endif
+
+/*
+ * Common ListView Implementation
+*/
+
+void QCommonListViewBase::appendHiddenRow(int row)
+{
+ dd->hiddenRows.insert(dd->model->index(row, 0, qq->rootIndex()));
+}
+
+void QCommonListViewBase::removeHiddenRow(int row)
+{
+ dd->hiddenRows.remove(dd->model->index(row, 0, qq->rootIndex()));
+}
+
+void QCommonListViewBase::updateHorizontalScrollBar(const QSize &step)
+{
+ horizontalScrollBar()->setSingleStep(step.width() + spacing());
+ horizontalScrollBar()->setPageStep(viewport()->width());
+ horizontalScrollBar()->setRange(0, contentsSize.width() - viewport()->width());
+}
+
+void QCommonListViewBase::updateVerticalScrollBar(const QSize &step)
+{
+ verticalScrollBar()->setSingleStep(step.height() + spacing());
+ verticalScrollBar()->setPageStep(viewport()->height());
+ verticalScrollBar()->setRange(0, contentsSize.height() - viewport()->height());
+}
+
+void QCommonListViewBase::scrollContentsBy(int dx, int dy, bool /*scrollElasticBand*/)
+{
+ dd->scrollContentsBy(isRightToLeft() ? -dx : dx, dy);
+}
+
+int QCommonListViewBase::verticalScrollToValue(int /*index*/, QListView::ScrollHint hint,
+ bool above, bool below, const QRect &area, const QRect &rect) const
+{
+ int verticalValue = verticalScrollBar()->value();
+ QRect adjusted = rect.adjusted(-spacing(), -spacing(), spacing(), spacing());
+ if (hint == QListView::PositionAtTop || above)
+ verticalValue += adjusted.top();
+ else if (hint == QListView::PositionAtBottom || below)
+ verticalValue += qMin(adjusted.top(), adjusted.bottom() - area.height() + 1);
+ else if (hint == QListView::PositionAtCenter)
+ verticalValue += adjusted.top() - ((area.height() - adjusted.height()) / 2);
+ return verticalValue;
+}
+
+int QCommonListViewBase::horizontalOffset() const
+{
+ return (isRightToLeft() ? horizontalScrollBar()->maximum() - horizontalScrollBar()->value() : horizontalScrollBar()->value());
+}
+
+int QCommonListViewBase::horizontalScrollToValue(const int /*index*/, QListView::ScrollHint hint,
+ bool leftOf, bool rightOf, const QRect &area, const QRect &rect) const
+{
+ int horizontalValue = horizontalScrollBar()->value();
+ if (isRightToLeft()) {
+ if (hint == QListView::PositionAtCenter) {
+ horizontalValue += ((area.width() - rect.width()) / 2) - rect.left();
+ } else {
+ if (leftOf)
+ horizontalValue -= rect.left();
+ else if (rightOf)
+ horizontalValue += qMin(rect.left(), area.width() - rect.right());
+ }
+ } else {
+ if (hint == QListView::PositionAtCenter) {
+ horizontalValue += rect.left() - ((area.width()- rect.width()) / 2);
+ } else {
+ if (leftOf)
+ horizontalValue += rect.left();
+ else if (rightOf)
+ horizontalValue += qMin(rect.left(), rect.right() - area.width());
+ }
+ }
+ return horizontalValue;
+}
+
+/*
+ * ListMode ListView Implementation
+*/
+
+#ifndef QT_NO_DRAGANDDROP
+void QListModeViewBase::paintDragDrop(QPainter *painter)
+{
+ // FIXME: Until the we can provide a proper drop indicator
+ // in IconMode, it makes no sense to show it
+ dd->paintDropIndicator(painter);
+}
+
+QAbstractItemView::DropIndicatorPosition QListModeViewBase::position(const QPoint &pos, const QRect &rect, const QModelIndex &index) const
+{
+ QAbstractItemView::DropIndicatorPosition r = QAbstractItemView::OnViewport;
+ if (!dd->overwrite) {
+ const int margin = 2;
+ if (pos.x() - rect.left() < margin) {
+ r = QAbstractItemView::AboveItem; // Visually, on the left
+ } else if (rect.right() - pos.x() < margin) {
+ r = QAbstractItemView::BelowItem; // Visually, on the right
+ } else if (rect.contains(pos, true)) {
+ r = QAbstractItemView::OnItem;
+ }
+ } else {
+ QRect touchingRect = rect;
+ touchingRect.adjust(-1, -1, 1, 1);
+ if (touchingRect.contains(pos, false)) {
+ r = QAbstractItemView::OnItem;
+ }
+ }
+
+ if (r == QAbstractItemView::OnItem && (!(dd->model->flags(index) & Qt::ItemIsDropEnabled)))
+ r = pos.x() < rect.center().x() ? QAbstractItemView::AboveItem : QAbstractItemView::BelowItem;
+
+ return r;
+}
+
+void QListModeViewBase::dragMoveEvent(QDragMoveEvent *event)
+{
+ if (qq->dragDropMode() == QAbstractItemView::InternalMove
+ && (event->source() != qq || !(event->possibleActions() & Qt::MoveAction)))
+ return;
+
+ // ignore by default
+ event->ignore();
+
+ // can't use indexAt, doesn't account for spacing.
+ QPoint p = event->pos();
+ QRect rect(p.x() + horizontalOffset(), p.y() + verticalOffset(), 1, 1);
+ rect.adjust(-dd->spacing(), -dd->spacing(), dd->spacing(), dd->spacing());
+ const QVector<QModelIndex> intersectVector = dd->intersectingSet(rect);
+ QModelIndex index = intersectVector.count() > 0
+ ? intersectVector.last() : QModelIndex();
+ dd->hover = index;
+ if (!dd->droppingOnItself(event, index)
+ && dd->canDecode(event)) {
+
+ if (index.isValid() && dd->showDropIndicator) {
+ QRect rect = qq->visualRect(index);
+ dd->dropIndicatorPosition = position(event->pos(), rect, index);
+ // if spacing, should try to draw between items, not just next to item.
+ switch (dd->dropIndicatorPosition) {
+ case QAbstractItemView::AboveItem:
+ if (dd->isIndexDropEnabled(index.parent())) {
+ dd->dropIndicatorRect = QRect(rect.left()-dd->spacing(), rect.top(), 0, rect.height());
+ event->accept();
+ } else {
+ dd->dropIndicatorRect = QRect();
+ }
+ break;
+ case QAbstractItemView::BelowItem:
+ if (dd->isIndexDropEnabled(index.parent())) {
+ dd->dropIndicatorRect = QRect(rect.right()+dd->spacing(), rect.top(), 0, rect.height());
+ event->accept();
+ } else {
+ dd->dropIndicatorRect = QRect();
+ }
+ break;
+ case QAbstractItemView::OnItem:
+ if (dd->isIndexDropEnabled(index)) {
+ dd->dropIndicatorRect = rect;
+ event->accept();
+ } else {
+ dd->dropIndicatorRect = QRect();
+ }
+ break;
+ case QAbstractItemView::OnViewport:
+ dd->dropIndicatorRect = QRect();
+ if (dd->isIndexDropEnabled(qq->rootIndex())) {
+ event->accept(); // allow dropping in empty areas
+ }
+ break;
+ }
+ } else {
+ dd->dropIndicatorRect = QRect();
+ dd->dropIndicatorPosition = QAbstractItemView::OnViewport;
+ if (dd->isIndexDropEnabled(qq->rootIndex())) {
+ event->accept(); // allow dropping in empty areas
+ }
+ }
+ dd->viewport->update();
+ } // can decode
+
+ if (dd->shouldAutoScroll(event->pos()))
+ qq->startAutoScroll();
+}
+
+/*!
+ If the event hasn't already been accepted, determines the index to drop on.
+
+ if (row == -1 && col == -1)
+ // append to this drop index
+ else
+ // place at row, col in drop index
+
+ If it returns true a drop can be done, and dropRow, dropCol and dropIndex reflects the position of the drop.
+ \internal
+ */
+bool QListModeViewBase::dropOn(QDropEvent *event, int *dropRow, int *dropCol, QModelIndex *dropIndex)
+{
+ if (event->isAccepted())
+ return false;
+
+ QModelIndex index;
+ if (dd->viewport->rect().contains(event->pos())) {
+ // can't use indexAt, doesn't account for spacing.
+ QPoint p = event->pos();
+ QRect rect(p.x() + horizontalOffset(), p.y() + verticalOffset(), 1, 1);
+ rect.adjust(-dd->spacing(), -dd->spacing(), dd->spacing(), dd->spacing());
+ const QVector<QModelIndex> intersectVector = dd->intersectingSet(rect);
+ index = intersectVector.count() > 0
+ ? intersectVector.last() : QModelIndex();
+ if (!index.isValid())
+ index = dd->root;
+ }
+
+ // If we are allowed to do the drop
+ if (dd->model->supportedDropActions() & event->dropAction()) {
+ int row = -1;
+ int col = -1;
+ if (index != dd->root) {
+ dd->dropIndicatorPosition = position(event->pos(), qq->visualRect(index), index);
+ switch (dd->dropIndicatorPosition) {
+ case QAbstractItemView::AboveItem:
+ row = index.row();
+ col = index.column();
+ index = index.parent();
+ break;
+ case QAbstractItemView::BelowItem:
+ row = index.row() + 1;
+ col = index.column();
+ index = index.parent();
+ break;
+ case QAbstractItemView::OnItem:
+ case QAbstractItemView::OnViewport:
+ break;
+ }
+ } else {
+ dd->dropIndicatorPosition = QAbstractItemView::OnViewport;
+ }
+ *dropIndex = index;
+ *dropRow = row;
+ *dropCol = col;
+ if (!dd->droppingOnItself(event, index))
+ return true;
+ }
+ return false;
+}
+
+#endif //QT_NO_DRAGANDDROP
+
+void QListModeViewBase::updateVerticalScrollBar(const QSize &step)
+{
+ if (verticalScrollMode() == QAbstractItemView::ScrollPerItem
+ && ((flow() == QListView::TopToBottom && !isWrapping())
+ || (flow() == QListView::LeftToRight && isWrapping()))) {
+ const int steps = (flow() == QListView::TopToBottom ? scrollValueMap : segmentPositions).count() - 1;
+ if (steps > 0) {
+ const int pageSteps = perItemScrollingPageSteps(viewport()->height(), contentsSize.height(), isWrapping());
+ verticalScrollBar()->setSingleStep(1);
+ verticalScrollBar()->setPageStep(pageSteps);
+ verticalScrollBar()->setRange(0, steps - pageSteps);
+ } else {
+ verticalScrollBar()->setRange(0, 0);
+ }
+ // } else if (vertical && d->isWrapping() && d->movement == Static) {
+ // ### wrapped scrolling in flow direction
+ } else {
+ QCommonListViewBase::updateVerticalScrollBar(step);
+ }
+}
+
+void QListModeViewBase::updateHorizontalScrollBar(const QSize &step)
+{
+ if (horizontalScrollMode() == QAbstractItemView::ScrollPerItem
+ && ((flow() == QListView::TopToBottom && isWrapping())
+ || (flow() == QListView::LeftToRight && !isWrapping()))) {
+ int steps = (flow() == QListView::TopToBottom ? segmentPositions : scrollValueMap).count() - 1;
+ if (steps > 0) {
+ const int pageSteps = perItemScrollingPageSteps(viewport()->width(), contentsSize.width(), isWrapping());
+ horizontalScrollBar()->setSingleStep(1);
+ horizontalScrollBar()->setPageStep(pageSteps);
+ horizontalScrollBar()->setRange(0, steps - pageSteps);
+ } else {
+ horizontalScrollBar()->setRange(0, 0);
+ }
+ } else {
+ QCommonListViewBase::updateHorizontalScrollBar(step);
+ }
+}
+
+int QListModeViewBase::verticalScrollToValue(int index, QListView::ScrollHint hint,
+ bool above, bool below, const QRect &area, const QRect &rect) const
+{
+ if (verticalScrollMode() == QAbstractItemView::ScrollPerItem) {
+ int value;
+ if (scrollValueMap.isEmpty())
+ value = 0;
+ else
+ value = qBound(0, scrollValueMap.at(verticalScrollBar()->value()), flowPositions.count() - 1);
+ if (above)
+ hint = QListView::PositionAtTop;
+ else if (below)
+ hint = QListView::PositionAtBottom;
+ if (hint == QListView::EnsureVisible)
+ return value;
+
+ return perItemScrollToValue(index, value, area.height(), hint, Qt::Vertical, isWrapping(), rect.height());
+ }
+
+ return QCommonListViewBase::verticalScrollToValue(index, hint, above, below, area, rect);
+}
+
+int QListModeViewBase::horizontalOffset() const
+{
+ if (horizontalScrollMode() == QAbstractItemView::ScrollPerItem) {
+ if (isWrapping()) {
+ if (flow() == QListView::TopToBottom && !segmentPositions.isEmpty()) {
+ const int max = segmentPositions.count() - 1;
+ int currentValue = qBound(0, horizontalScrollBar()->value(), max);
+ int position = segmentPositions.at(currentValue);
+ int maximumValue = qBound(0, horizontalScrollBar()->maximum(), max);
+ int maximum = segmentPositions.at(maximumValue);
+ return (isRightToLeft() ? maximum - position : position);
+ }
+ } else if (flow() == QListView::LeftToRight && !flowPositions.isEmpty()) {
+ int position = flowPositions.at(scrollValueMap.at(horizontalScrollBar()->value()));
+ int maximum = flowPositions.at(scrollValueMap.at(horizontalScrollBar()->maximum()));
+ return (isRightToLeft() ? maximum - position : position);
+ }
+ }
+ return QCommonListViewBase::horizontalOffset();
+}
+
+int QListModeViewBase::verticalOffset() const
+{
+ if (verticalScrollMode() == QAbstractItemView::ScrollPerItem) {
+ if (isWrapping()) {
+ if (flow() == QListView::LeftToRight && !segmentPositions.isEmpty()) {
+ int value = verticalScrollBar()->value();
+ if (value >= segmentPositions.count())
+ return 0;
+ return segmentPositions.at(value) - spacing();
+ }
+ } else if (flow() == QListView::TopToBottom && !flowPositions.isEmpty()) {
+ int value = verticalScrollBar()->value();
+ if (value > scrollValueMap.count())
+ return 0;
+ return flowPositions.at(scrollValueMap.at(value)) - spacing();
+ }
+ }
+ return QCommonListViewBase::verticalOffset();
+}
+
+int QListModeViewBase::horizontalScrollToValue(int index, QListView::ScrollHint hint,
+ bool leftOf, bool rightOf, const QRect &area, const QRect &rect) const
+{
+ if (horizontalScrollMode() != QAbstractItemView::ScrollPerItem)
+ return QCommonListViewBase::horizontalScrollToValue(index, hint, leftOf, rightOf, area, rect);
+
+ int value;
+ if (scrollValueMap.isEmpty())
+ value = 0;
+ else
+ value = qBound(0, scrollValueMap.at(horizontalScrollBar()->value()), flowPositions.count() - 1);
+ if (leftOf)
+ hint = QListView::PositionAtTop;
+ else if (rightOf)
+ hint = QListView::PositionAtBottom;
+ if (hint == QListView::EnsureVisible)
+ return value;
+
+ return perItemScrollToValue(index, value, area.width(), hint, Qt::Horizontal, isWrapping(), rect.width());
+}
+
+void QListModeViewBase::scrollContentsBy(int dx, int dy, bool scrollElasticBand)
+{
+ // ### reorder this logic
+ const int verticalValue = verticalScrollBar()->value();
+ const int horizontalValue = horizontalScrollBar()->value();
+ const bool vertical = (verticalScrollMode() == QAbstractItemView::ScrollPerItem);
+ const bool horizontal = (horizontalScrollMode() == QAbstractItemView::ScrollPerItem);
+
+ if (isWrapping()) {
+ if (segmentPositions.isEmpty())
+ return;
+ const int max = segmentPositions.count() - 1;
+ if (horizontal && flow() == QListView::TopToBottom && dx != 0) {
+ int currentValue = qBound(0, horizontalValue, max);
+ int previousValue = qBound(0, currentValue + dx, max);
+ int currentCoordinate = segmentPositions.at(currentValue) - spacing();
+ int previousCoordinate = segmentPositions.at(previousValue) - spacing();
+ dx = previousCoordinate - currentCoordinate;
+ } else if (vertical && flow() == QListView::LeftToRight && dy != 0) {
+ int currentValue = qBound(0, verticalValue, max);
+ int previousValue = qBound(0, currentValue + dy, max);
+ int currentCoordinate = segmentPositions.at(currentValue) - spacing();
+ int previousCoordinate = segmentPositions.at(previousValue) - spacing();
+ dy = previousCoordinate - currentCoordinate;
+ }
+ } else {
+ if (flowPositions.isEmpty())
+ return;
+ const int max = scrollValueMap.count() - 1;
+ if (vertical && flow() == QListView::TopToBottom && dy != 0) {
+ int currentValue = qBound(0, verticalValue, max);
+ int previousValue = qBound(0, currentValue + dy, max);
+ int currentCoordinate = flowPositions.at(scrollValueMap.at(currentValue));
+ int previousCoordinate = flowPositions.at(scrollValueMap.at(previousValue));
+ dy = previousCoordinate - currentCoordinate;
+ } else if (horizontal && flow() == QListView::LeftToRight && dx != 0) {
+ int currentValue = qBound(0, horizontalValue, max);
+ int previousValue = qBound(0, currentValue + dx, max);
+ int currentCoordinate = flowPositions.at(scrollValueMap.at(currentValue));
+ int previousCoordinate = flowPositions.at(scrollValueMap.at(previousValue));
+ dx = previousCoordinate - currentCoordinate;
+ }
+ }
+ QCommonListViewBase::scrollContentsBy(dx, dy, scrollElasticBand);
+}
+
+bool QListModeViewBase::doBatchedItemLayout(const QListViewLayoutInfo &info, int max)
+{
+ doStaticLayout(info);
+ if (batchStartRow > max) { // stop items layout
+ flowPositions.resize(flowPositions.count());
+ segmentPositions.resize(segmentPositions.count());
+ segmentStartRows.resize(segmentStartRows.count());
+ return true; // done
+ }
+ return false; // not done
+}
+
+QListViewItem QListModeViewBase::indexToListViewItem(const QModelIndex &index) const
+{
+ if (flowPositions.isEmpty()
+ || segmentPositions.isEmpty()
+ || index.row() >= flowPositions.count())
+ return QListViewItem();
+
+ const int segment = qBinarySearch<int>(segmentStartRows, index.row(),
+ 0, segmentStartRows.count() - 1);
+
+
+ QStyleOptionViewItemV4 options = viewOptions();
+ options.rect.setSize(contentsSize);
+ QSize size = (uniformItemSizes() && cachedItemSize().isValid())
+ ? cachedItemSize() : itemSize(options, index);
+
+ QPoint pos;
+ if (flow() == QListView::LeftToRight) {
+ pos.setX(flowPositions.at(index.row()));
+ pos.setY(segmentPositions.at(segment));
+ } else { // TopToBottom
+ pos.setY(flowPositions.at(index.row()));
+ pos.setX(segmentPositions.at(segment));
+ if (isWrapping()) { // make the items as wide as the segment
+ int right = (segment + 1 >= segmentPositions.count()
+ ? contentsSize.width()
+ : segmentPositions.at(segment + 1));
+ size.setWidth(right - pos.x());
+ } else { // make the items as wide as the viewport
+ size.setWidth(qMax(size.width(), viewport()->width()));
+ }
+ }
+
+ return QListViewItem(QRect(pos, size), index.row());
+}
+
+QPoint QListModeViewBase::initStaticLayout(const QListViewLayoutInfo &info)
+{
+ int x, y;
+ if (info.first == 0) {
+ flowPositions.clear();
+ segmentPositions.clear();
+ segmentStartRows.clear();
+ segmentExtents.clear();
+ scrollValueMap.clear();
+ x = info.bounds.left() + info.spacing;
+ y = info.bounds.top() + info.spacing;
+ segmentPositions.append(info.flow == QListView::LeftToRight ? y : x);
+ segmentStartRows.append(0);
+ } else if (info.wrap) {
+ if (info.flow == QListView::LeftToRight) {
+ x = batchSavedPosition;
+ y = segmentPositions.last();
+ } else { // flow == QListView::TopToBottom
+ x = segmentPositions.last();
+ y = batchSavedPosition;
+ }
+ } else { // not first and not wrap
+ if (info.flow == QListView::LeftToRight) {
+ x = batchSavedPosition;
+ y = info.bounds.top() + info.spacing;
+ } else { // flow == QListView::TopToBottom
+ x = info.bounds.left() + info.spacing;
+ y = batchSavedPosition;
+ }
+ }
+ return QPoint(x, y);
+}
+
+/*!
+ \internal
+*/
+void QListModeViewBase::doStaticLayout(const QListViewLayoutInfo &info)
+{
+ const bool useItemSize = !info.grid.isValid();
+ const QPoint topLeft = initStaticLayout(info);
+ QStyleOptionViewItemV4 option = viewOptions();
+ option.rect = info.bounds;
+ option.rect.adjust(info.spacing, info.spacing, -info.spacing, -info.spacing);
+
+ // The static layout data structures are as follows:
+ // One vector contains the coordinate in the direction of layout flow.
+ // Another vector contains the coordinates of the segments.
+ // A third vector contains the index (model row) of the first item
+ // of each segment.
+
+ int segStartPosition;
+ int segEndPosition;
+ int deltaFlowPosition;
+ int deltaSegPosition;
+ int deltaSegHint;
+ int flowPosition;
+ int segPosition;
+
+ if (info.flow == QListView::LeftToRight) {
+ segStartPosition = info.bounds.left();
+ segEndPosition = info.bounds.width();
+ flowPosition = topLeft.x();
+ segPosition = topLeft.y();
+ deltaFlowPosition = info.grid.width(); // dx
+ deltaSegPosition = useItemSize ? batchSavedDeltaSeg : info.grid.height(); // dy
+ deltaSegHint = info.grid.height();
+ } else { // flow == QListView::TopToBottom
+ segStartPosition = info.bounds.top();
+ segEndPosition = info.bounds.height();
+ flowPosition = topLeft.y();
+ segPosition = topLeft.x();
+ deltaFlowPosition = info.grid.height(); // dy
+ deltaSegPosition = useItemSize ? batchSavedDeltaSeg : info.grid.width(); // dx
+ deltaSegHint = info.grid.width();
+ }
+
+ for (int row = info.first; row <= info.last; ++row) {
+ if (isHidden(row)) { // ###
+ flowPositions.append(flowPosition);
+ } else {
+ // if we are not using a grid, we need to find the deltas
+ if (useItemSize) {
+ QSize hint = itemSize(option, modelIndex(row));
+ if (info.flow == QListView::LeftToRight) {
+ deltaFlowPosition = hint.width() + info.spacing;
+ deltaSegHint = hint.height() + info.spacing;
+ } else { // TopToBottom
+ deltaFlowPosition = hint.height() + info.spacing;
+ deltaSegHint = hint.width() + info.spacing;
+ }
+ }
+ // create new segment
+ if (info.wrap && (flowPosition + deltaFlowPosition >= segEndPosition)) {
+ segmentExtents.append(flowPosition);
+ flowPosition = info.spacing + segStartPosition;
+ segPosition += deltaSegPosition;
+ if (info.wrap)
+ segPosition += info.spacing;
+ segmentPositions.append(segPosition);
+ segmentStartRows.append(row);
+ deltaSegPosition = 0;
+ }
+ // save the flow position of this item
+ scrollValueMap.append(flowPositions.count());
+ flowPositions.append(flowPosition);
+ // prepare for the next item
+ deltaSegPosition = qMax(deltaSegHint, deltaSegPosition);
+ flowPosition += info.spacing + deltaFlowPosition;
+ }
+ }
+ // used when laying out next batch
+ batchSavedPosition = flowPosition;
+ batchSavedDeltaSeg = deltaSegPosition;
+ batchStartRow = info.last + 1;
+ if (info.last == info.max)
+ flowPosition -= info.spacing; // remove extra spacing
+ // set the contents size
+ QRect rect = info.bounds;
+ if (info.flow == QListView::LeftToRight) {
+ rect.setRight(segmentPositions.count() == 1 ? flowPosition : info.bounds.right());
+ rect.setBottom(segPosition + deltaSegPosition);
+ } else { // TopToBottom
+ rect.setRight(segPosition + deltaSegPosition);
+ rect.setBottom(segmentPositions.count() == 1 ? flowPosition : info.bounds.bottom());
+ }
+ contentsSize = QSize(rect.right(), rect.bottom());
+ // if it is the last batch, save the end of the segments
+ if (info.last == info.max) {
+ segmentExtents.append(flowPosition);
+ scrollValueMap.append(flowPositions.count());
+ flowPositions.append(flowPosition);
+ segmentPositions.append(info.wrap ? segPosition + deltaSegPosition : INT_MAX);
+ }
+ // if the new items are visble, update the viewport
+ QRect changedRect(topLeft, rect.bottomRight());
+ if (clipRect().intersects(changedRect))
+ viewport()->update();
+}
+
+/*!
+ \internal
+ Finds the set of items intersecting with \a area.
+ In this function, itemsize is counted from topleft to the start of the next item.
+*/
+QVector<QModelIndex> QListModeViewBase::intersectingSet(const QRect &area) const
+{
+ QVector<QModelIndex> ret;
+ int segStartPosition;
+ int segEndPosition;
+ int flowStartPosition;
+ int flowEndPosition;
+ if (flow() == QListView::LeftToRight) {
+ segStartPosition = area.top();
+ segEndPosition = area.bottom();
+ flowStartPosition = area.left();
+ flowEndPosition = area.right();
+ } else {
+ segStartPosition = area.left();
+ segEndPosition = area.right();
+ flowStartPosition = area.top();
+ flowEndPosition = area.bottom();
+ }
+ if (segmentPositions.count() < 2 || flowPositions.isEmpty())
+ return ret;
+ // the last segment position is actually the edge of the last segment
+ const int segLast = segmentPositions.count() - 2;
+ int seg = qBinarySearch<int>(segmentPositions, segStartPosition, 0, segLast + 1);
+ for (; seg <= segLast && segmentPositions.at(seg) <= segEndPosition; ++seg) {
+ int first = segmentStartRows.at(seg);
+ int last = (seg < segLast ? segmentStartRows.at(seg + 1) : batchStartRow) - 1;
+ if (segmentExtents.at(seg) < flowStartPosition)
+ continue;
+ int row = qBinarySearch<int>(flowPositions, flowStartPosition, first, last);
+ for (; row <= last && flowPositions.at(row) <= flowEndPosition; ++row) {
+ if (isHidden(row))
+ continue;
+ QModelIndex index = modelIndex(row);
+ if (index.isValid())
+ ret += index;
+#if 0 // for debugging
+ else
+ qWarning("intersectingSet: row %d was invalid", row);
+#endif
+ }
+ }
+ return ret;
+}
+
+void QListModeViewBase::dataChanged(const QModelIndex &, const QModelIndex &)
+{
+ dd->doDelayedItemsLayout();
+}
+
+
+QRect QListModeViewBase::mapToViewport(const QRect &rect) const
+{
+ if (isWrapping())
+ return rect;
+ // If the listview is in "listbox-mode", the items are as wide as the view.
+ // But we don't shrink the items.
+ QRect result = rect;
+ if (flow() == QListView::TopToBottom) {
+ result.setLeft(spacing());
+ result.setWidth(qMax(rect.width(), qMax(contentsSize.width(), viewport()->width()) - 2 * spacing()));
+ } else { // LeftToRight
+ result.setTop(spacing());
+ result.setHeight(qMax(rect.height(), qMax(contentsSize.height(), viewport()->height()) - 2 * spacing()));
+ }
+ return result;
+}
+
+int QListModeViewBase::perItemScrollingPageSteps(int length, int bounds, bool wrap) const
+{
+ QVector<int> positions;
+ if (wrap)
+ positions = segmentPositions;
+ else if (!flowPositions.isEmpty()) {
+ positions.reserve(scrollValueMap.size());
+ foreach (int itemShown, scrollValueMap)
+ positions.append(flowPositions.at(itemShown));
+ }
+ if (positions.isEmpty() || bounds <= length)
+ return positions.count();
+ if (uniformItemSizes()) {
+ for (int i = 1; i < positions.count(); ++i)
+ if (positions.at(i) > 0)
+ return length / positions.at(i);
+ return 0; // all items had height 0
+ }
+ int pageSteps = 0;
+ int steps = positions.count() - 1;
+ int max = qMax(length, bounds);
+ int min = qMin(length, bounds);
+ int pos = min - (max - positions.last());
+
+ while (pos >= 0 && steps > 0) {
+ pos -= (positions.at(steps) - positions.at(steps - 1));
+ if (pos >= 0) //this item should be visible
+ ++pageSteps;
+ --steps;
+ }
+
+ // at this point we know that positions has at least one entry
+ return qMax(pageSteps, 1);
+}
+
+int QListModeViewBase::perItemScrollToValue(int index, int scrollValue, int viewportSize,
+ QAbstractItemView::ScrollHint hint,
+ Qt::Orientation orientation, bool wrap, int itemExtent) const
+{
+ if (index < 0)
+ return scrollValue;
+ if (!wrap) {
+ int topIndex = index;
+ const int bottomIndex = topIndex;
+ const int bottomCoordinate = flowPositions.at(index);
+
+ while (topIndex > 0 &&
+ (bottomCoordinate - flowPositions.at(topIndex-1) + itemExtent) <= (viewportSize)) {
+ topIndex--;
+ }
+
+ const int itemCount = bottomIndex - topIndex + 1;
+ switch (hint) {
+ case QAbstractItemView::PositionAtTop:
+ return index;
+ case QAbstractItemView::PositionAtBottom:
+ return index - itemCount + 1;
+ case QAbstractItemView::PositionAtCenter:
+ return index - (itemCount / 2);
+ default:
+ break;
+ }
+ } else { // wrapping
+ Qt::Orientation flowOrientation = (flow() == QListView::LeftToRight
+ ? Qt::Horizontal : Qt::Vertical);
+ if (flowOrientation == orientation) { // scrolling in the "flow" direction
+ // ### wrapped scrolling in the flow direction
+ return flowPositions.at(index); // ### always pixel based for now
+ } else if (!segmentStartRows.isEmpty()) { // we are scrolling in the "segment" direction
+ int segment = qBinarySearch<int>(segmentStartRows, index, 0, segmentStartRows.count() - 1);
+ int leftSegment = segment;
+ const int rightSegment = leftSegment;
+ const int bottomCoordinate = segmentPositions.at(segment);
+
+ while (leftSegment > scrollValue &&
+ (bottomCoordinate - segmentPositions.at(leftSegment-1) + itemExtent) <= (viewportSize)) {
+ leftSegment--;
+ }
+
+ const int segmentCount = rightSegment - leftSegment + 1;
+ switch (hint) {
+ case QAbstractItemView::PositionAtTop:
+ return segment;
+ case QAbstractItemView::PositionAtBottom:
+ return segment - segmentCount + 1;
+ case QAbstractItemView::PositionAtCenter:
+ return segment - (segmentCount / 2);
+ default:
+ break;
+ }
+ }
+ }
+ return scrollValue;
+}
+
+void QListModeViewBase::clear()
+{
+ flowPositions.clear();
+ segmentPositions.clear();
+ segmentStartRows.clear();
+ segmentExtents.clear();
+ batchSavedPosition = 0;
+ batchStartRow = 0;
+ batchSavedDeltaSeg = 0;
+}
+
+/*
+ * IconMode ListView Implementation
+*/
+
+void QIconModeViewBase::setPositionForIndex(const QPoint &position, const QModelIndex &index)
+{
+ if (index.row() >= items.count())
+ return;
+ const QSize oldContents = contentsSize;
+ qq->update(index); // update old position
+ moveItem(index.row(), position);
+ qq->update(index); // update new position
+
+ if (contentsSize != oldContents)
+ dd->viewUpdateGeometries(); // update the scroll bars
+}
+
+void QIconModeViewBase::appendHiddenRow(int row)
+{
+ if (row >= 0 && row < items.count()) //remove item
+ tree.removeLeaf(items.at(row).rect(), row);
+ QCommonListViewBase::appendHiddenRow(row);
+}
+
+void QIconModeViewBase::removeHiddenRow(int row)
+{
+ QCommonListViewBase::removeHiddenRow(row);
+ if (row >= 0 && row < items.count()) //insert item
+ tree.insertLeaf(items.at(row).rect(), row);
+}
+
+#ifndef QT_NO_DRAGANDDROP
+void QIconModeViewBase::paintDragDrop(QPainter *painter)
+{
+ if (!draggedItems.isEmpty() && viewport()->rect().contains(draggedItemsPos)) {
+ //we need to draw the items that arre dragged
+ painter->translate(draggedItemsDelta());
+ QStyleOptionViewItemV4 option = viewOptions();
+ option.state &= ~QStyle::State_MouseOver;
+ QVector<QModelIndex>::const_iterator it = draggedItems.begin();
+ QListViewItem item = indexToListViewItem(*it);
+ for (; it != draggedItems.end(); ++it) {
+ item = indexToListViewItem(*it);
+ option.rect = viewItemRect(item);
+ delegate(*it)->paint(painter, option, *it);
+ }
+ }
+}
+
+bool QIconModeViewBase::filterStartDrag(Qt::DropActions supportedActions)
+{
+ // This function does the same thing as in QAbstractItemView::startDrag(),
+ // plus adding viewitems to the draggedItems list.
+ // We need these items to draw the drag items
+ QModelIndexList indexes = dd->selectionModel->selectedIndexes();
+ if (indexes.count() > 0 ) {
+ if (viewport()->acceptDrops()) {
+ QModelIndexList::ConstIterator it = indexes.constBegin();
+ for (; it != indexes.constEnd(); ++it)
+ if (dd->model->flags(*it) & Qt::ItemIsDragEnabled
+ && (*it).column() == dd->column)
+ draggedItems.push_back(*it);
+ }
+ QDrag *drag = new QDrag(qq);
+ drag->setMimeData(dd->model->mimeData(indexes));
+ Qt::DropAction action = drag->exec(supportedActions, Qt::CopyAction);
+ draggedItems.clear();
+ if (action == Qt::MoveAction)
+ dd->clearOrRemove();
+ }
+ return true;
+}
+
+bool QIconModeViewBase::filterDropEvent(QDropEvent *e)
+{
+ if (e->source() != qq)
+ return false;
+
+ const QSize contents = contentsSize;
+ QPoint offset(horizontalOffset(), verticalOffset());
+ QPoint end = e->pos() + offset;
+ if (qq->acceptDrops()) {
+ const Qt::ItemFlags dropableFlags = Qt::ItemIsDropEnabled|Qt::ItemIsEnabled;
+ const QVector<QModelIndex> &dropIndices = intersectingSet(QRect(end, QSize(1, 1)));
+ foreach (const QModelIndex &index, dropIndices)
+ if ((index.flags() & dropableFlags) == dropableFlags)
+ return false;
+ }
+ QPoint start = dd->pressedPosition;
+ QPoint delta = (dd->movement == QListView::Snap ? snapToGrid(end) - snapToGrid(start) : end - start);
+ QList<QModelIndex> indexes = dd->selectionModel->selectedIndexes();
+ for (int i = 0; i < indexes.count(); ++i) {
+ QModelIndex index = indexes.at(i);
+ QRect rect = dd->rectForIndex(index);
+ viewport()->update(dd->mapToViewport(rect, false));
+ QPoint dest = rect.topLeft() + delta;
+ if (qq->isRightToLeft())
+ dest.setX(dd->flipX(dest.x()) - rect.width());
+ moveItem(index.row(), dest);
+ qq->update(index);
+ }
+ dd->stopAutoScroll();
+ draggedItems.clear();
+ dd->emitIndexesMoved(indexes);
+ e->accept(); // we have handled the event
+ // if the size has not grown, we need to check if it has shrinked
+ if (contentsSize != contents) {
+ if ((contentsSize.width() <= contents.width()
+ || contentsSize.height() <= contents.height())) {
+ updateContentsSize();
+ }
+ dd->viewUpdateGeometries();
+ }
+ return true;
+}
+
+bool QIconModeViewBase::filterDragLeaveEvent(QDragLeaveEvent *e)
+{
+ viewport()->update(draggedItemsRect()); // erase the area
+ draggedItemsPos = QPoint(-1, -1); // don't draw the dragged items
+ return QCommonListViewBase::filterDragLeaveEvent(e);
+}
+
+bool QIconModeViewBase::filterDragMoveEvent(QDragMoveEvent *e)
+{
+ if (e->source() != qq || !dd->canDecode(e))
+ return false;
+
+ // ignore by default
+ e->ignore();
+ // get old dragged items rect
+ QRect itemsRect = this->itemsRect(draggedItems);
+ viewport()->update(itemsRect.translated(draggedItemsDelta()));
+ // update position
+ draggedItemsPos = e->pos();
+ // get new items rect
+ viewport()->update(itemsRect.translated(draggedItemsDelta()));
+ // set the item under the cursor to current
+ QModelIndex index;
+ if (movement() == QListView::Snap) {
+ QRect rect(snapToGrid(e->pos() + offset()), gridSize());
+ const QVector<QModelIndex> intersectVector = intersectingSet(rect);
+ index = intersectVector.count() > 0 ? intersectVector.last() : QModelIndex();
+ } else {
+ index = qq->indexAt(e->pos());
+ }
+ // check if we allow drops here
+ if (draggedItems.contains(index))
+ e->accept(); // allow changing item position
+ else if (dd->model->flags(index) & Qt::ItemIsDropEnabled)
+ e->accept(); // allow dropping on dropenabled items
+ else if (!index.isValid())
+ e->accept(); // allow dropping in empty areas
+
+ // the event was treated. do autoscrolling
+ if (dd->shouldAutoScroll(e->pos()))
+ dd->startAutoScroll();
+ return true;
+}
+#endif // QT_NO_DRAGANDDROP
+
+void QIconModeViewBase::setRowCount(int rowCount)
+{
+ tree.create(qMax(rowCount - hiddenCount(), 0));
+}
+
+void QIconModeViewBase::scrollContentsBy(int dx, int dy, bool scrollElasticBand)
+{
+ if (scrollElasticBand)
+ dd->scrollElasticBandBy(isRightToLeft() ? -dx : dx, dy);
+
+ QCommonListViewBase::scrollContentsBy(dx, dy, scrollElasticBand);
+ if (!draggedItems.isEmpty())
+ viewport()->update(draggedItemsRect().translated(dx, dy));
+}
+
+void QIconModeViewBase::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
+{
+ if (column() >= topLeft.column() && column() <= bottomRight.column()) {
+ QStyleOptionViewItemV4 option = viewOptions();
+ int bottom = qMin(items.count(), bottomRight.row() + 1);
+ for (int row = topLeft.row(); row < bottom; ++row)
+ items[row].resize(itemSize(option, modelIndex(row)));
+ }
+}
+
+bool QIconModeViewBase::doBatchedItemLayout(const QListViewLayoutInfo &info, int max)
+{
+ if (info.last >= items.count()) {
+ //first we create the items
+ QStyleOptionViewItemV4 option = viewOptions();
+ for (int row = items.count(); row <= info.last; ++row) {
+ QSize size = itemSize(option, modelIndex(row));
+ QListViewItem item(QRect(0, 0, size.width(), size.height()), row); // default pos
+ items.append(item);
+ }
+ doDynamicLayout(info);
+ }
+ return (batchStartRow > max); // done
+}
+
+QListViewItem QIconModeViewBase::indexToListViewItem(const QModelIndex &index) const
+{
+ if (index.isValid() && index.row() < items.count())
+ return items.at(index.row());
+ return QListViewItem();
+}
+
+void QIconModeViewBase::initBspTree(const QSize &contents)
+{
+ // remove all items from the tree
+ int leafCount = tree.leafCount();
+ for (int l = 0; l < leafCount; ++l)
+ tree.leaf(l).clear();
+ // we have to get the bounding rect of the items before we can initialize the tree
+ QBspTree::Node::Type type = QBspTree::Node::Both; // 2D
+ // simple heuristics to get better bsp
+ if (contents.height() / contents.width() >= 3)
+ type = QBspTree::Node::HorizontalPlane;
+ else if (contents.width() / contents.height() >= 3)
+ type = QBspTree::Node::VerticalPlane;
+ // build tree for the bounding rect (not just the contents rect)
+ tree.init(QRect(0, 0, contents.width(), contents.height()), type);
+}
+
+QPoint QIconModeViewBase::initDynamicLayout(const QListViewLayoutInfo &info)
+{
+ int x, y;
+ if (info.first == 0) {
+ x = info.bounds.x() + info.spacing;
+ y = info.bounds.y() + info.spacing;
+ items.reserve(rowCount() - hiddenCount());
+ } else {
+ int idx = info.first - 1;
+ while (idx > 0 && !items.at(idx).isValid())
+ --idx;
+ const QListViewItem &item = items.at(idx);
+ x = item.x;
+ y = item.y;
+ if (info.flow == QListView::LeftToRight)
+ x += (info.grid.isValid() ? info.grid.width() : item.w) + info.spacing;
+ else
+ y += (info.grid.isValid() ? info.grid.height() : item.h) + info.spacing;
+ }
+ return QPoint(x, y);
+}
+
+/*!
+ \internal
+*/
+void QIconModeViewBase::doDynamicLayout(const QListViewLayoutInfo &info)
+{
+ const bool useItemSize = !info.grid.isValid();
+ const QPoint topLeft = initDynamicLayout(info);
+
+ int segStartPosition;
+ int segEndPosition;
+ int deltaFlowPosition;
+ int deltaSegPosition;
+ int deltaSegHint;
+ int flowPosition;
+ int segPosition;
+
+ if (info.flow == QListView::LeftToRight) {
+ segStartPosition = info.bounds.left() + info.spacing;
+ segEndPosition = info.bounds.right();
+ deltaFlowPosition = info.grid.width(); // dx
+ deltaSegPosition = (useItemSize ? batchSavedDeltaSeg : info.grid.height()); // dy
+ deltaSegHint = info.grid.height();
+ flowPosition = topLeft.x();
+ segPosition = topLeft.y();
+ } else { // flow == QListView::TopToBottom
+ segStartPosition = info.bounds.top() + info.spacing;
+ segEndPosition = info.bounds.bottom();
+ deltaFlowPosition = info.grid.height(); // dy
+ deltaSegPosition = (useItemSize ? batchSavedDeltaSeg : info.grid.width()); // dx
+ deltaSegHint = info.grid.width();
+ flowPosition = topLeft.y();
+ segPosition = topLeft.x();
+ }
+
+ if (moved.count() != items.count())
+ moved.resize(items.count());
+
+ QRect rect(QPoint(), topLeft);
+ QListViewItem *item = 0;
+ for (int row = info.first; row <= info.last; ++row) {
+ item = &items[row];
+ if (isHidden(row)) {
+ item->invalidate();
+ } else {
+ // if we are not using a grid, we need to find the deltas
+ if (useItemSize) {
+ if (info.flow == QListView::LeftToRight)
+ deltaFlowPosition = item->w + info.spacing;
+ else
+ deltaFlowPosition = item->h + info.spacing;
+ } else {
+ item->w = qMin<int>(info.grid.width(), item->w);
+ item->h = qMin<int>(info.grid.height(), item->h);
+ }
+
+ // create new segment
+ if (info.wrap
+ && flowPosition + deltaFlowPosition > segEndPosition
+ && flowPosition > segStartPosition) {
+ flowPosition = segStartPosition;
+ segPosition += deltaSegPosition;
+ if (useItemSize)
+ deltaSegPosition = 0;
+ }
+ // We must delay calculation of the seg adjustment, as this item
+ // may have caused a wrap to occur
+ if (useItemSize) {
+ if (info.flow == QListView::LeftToRight)
+ deltaSegHint = item->h + info.spacing;
+ else
+ deltaSegHint = item->w + info.spacing;
+ deltaSegPosition = qMax(deltaSegPosition, deltaSegHint);
+ }
+
+ // set the position of the item
+ // ### idealy we should have some sort of alignment hint for the item
+ // ### (normally that would be a point between the icon and the text)
+ if (!moved.testBit(row)) {
+ if (info.flow == QListView::LeftToRight) {
+ if (useItemSize) {
+ item->x = flowPosition;
+ item->y = segPosition;
+ } else { // use grid
+ item->x = flowPosition + ((deltaFlowPosition - item->w) / 2);
+ item->y = segPosition;
+ }
+ } else { // TopToBottom
+ if (useItemSize) {
+ item->y = flowPosition;
+ item->x = segPosition;
+ } else { // use grid
+ item->y = flowPosition + ((deltaFlowPosition - item->h) / 2);
+ item->x = segPosition;
+ }
+ }
+ }
+
+ // let the contents contain the new item
+ if (useItemSize)
+ rect |= item->rect();
+ else if (info.flow == QListView::LeftToRight)
+ rect |= QRect(flowPosition, segPosition, deltaFlowPosition, deltaSegPosition);
+ else // flow == TopToBottom
+ rect |= QRect(segPosition, flowPosition, deltaSegPosition, deltaFlowPosition);
+
+ // prepare for next item
+ flowPosition += deltaFlowPosition; // current position + item width + gap
+ }
+ }
+ batchSavedDeltaSeg = deltaSegPosition;
+ batchStartRow = info.last + 1;
+ bool done = (info.last >= rowCount() - 1);
+ // resize the content area
+ if (done || !info.bounds.contains(item->rect())) {
+ contentsSize = rect.size();
+ if (info.flow == QListView::LeftToRight)
+ contentsSize.rheight() += info.spacing;
+ else
+ contentsSize.rwidth() += info.spacing;
+ }
+ if (rect.size().isEmpty())
+ return;
+ // resize tree
+ int insertFrom = info.first;
+ if (done || info.first == 0) {
+ initBspTree(rect.size());
+ insertFrom = 0;
+ }
+ // insert items in tree
+ for (int row = insertFrom; row <= info.last; ++row)
+ tree.insertLeaf(items.at(row).rect(), row);
+ // if the new items are visble, update the viewport
+ QRect changedRect(topLeft, rect.bottomRight());
+ if (clipRect().intersects(changedRect))
+ viewport()->update();
+}
+
+QVector<QModelIndex> QIconModeViewBase::intersectingSet(const QRect &area) const
+{
+ QIconModeViewBase *that = const_cast<QIconModeViewBase*>(this);
+ QBspTree::Data data(static_cast<void*>(that));
+ QVector<QModelIndex> res;
+ that->interSectingVector = &res;
+ that->tree.climbTree(area, &QIconModeViewBase::addLeaf, data);
+ that->interSectingVector = 0;
+ return res;
+}
+
+QRect QIconModeViewBase::itemsRect(const QVector<QModelIndex> &indexes) const
+{
+ QVector<QModelIndex>::const_iterator it = indexes.begin();
+ QListViewItem item = indexToListViewItem(*it);
+ QRect rect(item.x, item.y, item.w, item.h);
+ for (; it != indexes.end(); ++it) {
+ item = indexToListViewItem(*it);
+ rect |= viewItemRect(item);
+ }
+ return rect;
+}
+
+int QIconModeViewBase::itemIndex(const QListViewItem &item) const
+{
+ if (!item.isValid())
+ return -1;
+ int i = item.indexHint;
+ if (i < items.count()) {
+ if (items.at(i) == item)
+ return i;
+ } else {
+ i = items.count() - 1;
+ }
+
+ int j = i;
+ int c = items.count();
+ bool a = true;
+ bool b = true;
+
+ while (a || b) {
+ if (a) {
+ if (items.at(i) == item) {
+ items.at(i).indexHint = i;
+ return i;
+ }
+ a = ++i < c;
+ }
+ if (b) {
+ if (items.at(j) == item) {
+ items.at(j).indexHint = j;
+ return j;
+ }
+ b = --j > -1;
+ }
+ }
+ return -1;
+}
+
+void QIconModeViewBase::addLeaf(QVector<int> &leaf, const QRect &area,
+ uint visited, QBspTree::Data data)
+{
+ QListViewItem *vi;
+ QIconModeViewBase *_this = static_cast<QIconModeViewBase *>(data.ptr);
+ for (int i = 0; i < leaf.count(); ++i) {
+ int idx = leaf.at(i);
+ if (idx < 0 || idx >= _this->items.count())
+ continue;
+ vi = &_this->items[idx];
+ Q_ASSERT(vi);
+ if (vi->isValid() && vi->rect().intersects(area) && vi->visited != visited) {
+ QModelIndex index = _this->dd->listViewItemToIndex(*vi);
+ Q_ASSERT(index.isValid());
+ _this->interSectingVector->append(index);
+ vi->visited = visited;
+ }
+ }
+}
+
+void QIconModeViewBase::moveItem(int index, const QPoint &dest)
+{
+ // does not impact on the bintree itself or the contents rect
+ QListViewItem *item = &items[index];
+ QRect rect = item->rect();
+
+ // move the item without removing it from the tree
+ tree.removeLeaf(rect, index);
+ item->move(dest);
+ tree.insertLeaf(QRect(dest, rect.size()), index);
+
+ // resize the contents area
+ contentsSize = (QRect(QPoint(0, 0), contentsSize)|QRect(dest, rect.size())).size();
+
+ // mark the item as moved
+ if (moved.count() != items.count())
+ moved.resize(items.count());
+ moved.setBit(index, true);
+}
+
+QPoint QIconModeViewBase::snapToGrid(const QPoint &pos) const
+{
+ int x = pos.x() - (pos.x() % gridSize().width());
+ int y = pos.y() - (pos.y() % gridSize().height());
+ return QPoint(x, y);
+}
+
+QPoint QIconModeViewBase::draggedItemsDelta() const
+{
+ if (movement() == QListView::Snap) {
+ QPoint snapdelta = QPoint((offset().x() % gridSize().width()),
+ (offset().y() % gridSize().height()));
+ return snapToGrid(draggedItemsPos + snapdelta) - snapToGrid(pressedPosition()) - snapdelta;
+ }
+ return draggedItemsPos - pressedPosition();
+}
+
+QRect QIconModeViewBase::draggedItemsRect() const
+{
+ QRect rect = itemsRect(draggedItems);
+ rect.translate(draggedItemsDelta());
+ return rect;
+}
+
+void QListViewPrivate::scrollElasticBandBy(int dx, int dy)
+{
+ if (dx > 0) // right
+ elasticBand.moveRight(elasticBand.right() + dx);
+ else if (dx < 0) // left
+ elasticBand.moveLeft(elasticBand.left() - dx);
+ if (dy > 0) // down
+ elasticBand.moveBottom(elasticBand.bottom() + dy);
+ else if (dy < 0) // up
+ elasticBand.moveTop(elasticBand.top() - dy);
+}
+
+void QIconModeViewBase::clear()
+{
+ tree.destroy();
+ items.clear();
+ moved.clear();
+ batchStartRow = 0;
+ batchSavedDeltaSeg = 0;
+}
+
+void QIconModeViewBase::updateContentsSize()
+{
+ QRect bounding;
+ for (int i = 0; i < items.count(); ++i)
+ bounding |= items.at(i).rect();
+ contentsSize = bounding.size();
+}
+
+/*!
+ \reimp
+*/
+void QListView::currentChanged(const QModelIndex &current, const QModelIndex &previous)
+{
+#ifndef QT_NO_ACCESSIBILITY
+ if (QAccessible::isActive()) {
+ if (current.isValid()) {
+ int entry = visualIndex(current) + 1;
+#ifdef Q_WS_X11
+ QAccessible::updateAccessibility(this, entry, QAccessible::Focus);
+#else
+ QAccessible::updateAccessibility(viewport(), entry, QAccessible::Focus);
+#endif
+ }
+ }
+#endif
+ QAbstractItemView::currentChanged(current, previous);
+}
+
+/*!
+ \reimp
+*/
+void QListView::selectionChanged(const QItemSelection &selected,
+ const QItemSelection &deselected)
+{
+#ifndef QT_NO_ACCESSIBILITY
+ if (QAccessible::isActive()) {
+ // ### does not work properly for selection ranges.
+ QModelIndex sel = selected.indexes().value(0);
+ if (sel.isValid()) {
+ int entry = visualIndex(sel) + 1;
+#ifdef Q_WS_X11
+ QAccessible::updateAccessibility(this, entry, QAccessible::Selection);
+#else
+ QAccessible::updateAccessibility(viewport(), entry, QAccessible::Selection);
+#endif
+ }
+ QModelIndex desel = deselected.indexes().value(0);
+ if (desel.isValid()) {
+ int entry = visualIndex(desel) + 1;
+#ifdef Q_WS_X11
+ QAccessible::updateAccessibility(this, entry, QAccessible::SelectionRemove);
+#else
+ QAccessible::updateAccessibility(viewport(), entry, QAccessible::SelectionRemove);
+#endif
+ }
+ }
+#endif
+ QAbstractItemView::selectionChanged(selected, deselected);
+}
+
+int QListView::visualIndex(const QModelIndex &index) const
+{
+ Q_D(const QListView);
+ d->executePostedLayout();
+ QListViewItem itm = d->indexToListViewItem(index);
+ return d->commonListView->itemIndex(itm);
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_LISTVIEW
diff --git a/src/widgets/itemviews/qlistview.h b/src/widgets/itemviews/qlistview.h
new file mode 100644
index 0000000000..49d6583244
--- /dev/null
+++ b/src/widgets/itemviews/qlistview.h
@@ -0,0 +1,203 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QLISTVIEW_H
+#define QLISTVIEW_H
+
+#include <QtWidgets/qabstractitemview.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_LISTVIEW
+
+class QListViewPrivate;
+
+class Q_WIDGETS_EXPORT QListView : public QAbstractItemView
+{
+ Q_OBJECT
+ Q_ENUMS(Movement Flow ResizeMode LayoutMode ViewMode)
+ Q_PROPERTY(Movement movement READ movement WRITE setMovement)
+ Q_PROPERTY(Flow flow READ flow WRITE setFlow)
+ Q_PROPERTY(bool isWrapping READ isWrapping WRITE setWrapping)
+ Q_PROPERTY(ResizeMode resizeMode READ resizeMode WRITE setResizeMode)
+ Q_PROPERTY(LayoutMode layoutMode READ layoutMode WRITE setLayoutMode)
+ Q_PROPERTY(int spacing READ spacing WRITE setSpacing)
+ Q_PROPERTY(QSize gridSize READ gridSize WRITE setGridSize)
+ Q_PROPERTY(ViewMode viewMode READ viewMode WRITE setViewMode)
+ Q_PROPERTY(int modelColumn READ modelColumn WRITE setModelColumn)
+ Q_PROPERTY(bool uniformItemSizes READ uniformItemSizes WRITE setUniformItemSizes)
+ Q_PROPERTY(int batchSize READ batchSize WRITE setBatchSize)
+ Q_PROPERTY(bool wordWrap READ wordWrap WRITE setWordWrap)
+ Q_PROPERTY(bool selectionRectVisible READ isSelectionRectVisible WRITE setSelectionRectVisible)
+
+public:
+ enum Movement { Static, Free, Snap };
+ enum Flow { LeftToRight, TopToBottom };
+ enum ResizeMode { Fixed, Adjust };
+ enum LayoutMode { SinglePass, Batched };
+ enum ViewMode { ListMode, IconMode };
+
+ explicit QListView(QWidget *parent = 0);
+ ~QListView();
+
+ void setMovement(Movement movement);
+ Movement movement() const;
+
+ void setFlow(Flow flow);
+ Flow flow() const;
+
+ void setWrapping(bool enable);
+ bool isWrapping() const;
+
+ void setResizeMode(ResizeMode mode);
+ ResizeMode resizeMode() const;
+
+ void setLayoutMode(LayoutMode mode);
+ LayoutMode layoutMode() const;
+
+ void setSpacing(int space);
+ int spacing() const;
+
+ void setBatchSize(int batchSize);
+ int batchSize() const;
+
+ void setGridSize(const QSize &size);
+ QSize gridSize() const;
+
+ void setViewMode(ViewMode mode);
+ ViewMode viewMode() const;
+
+ void clearPropertyFlags();
+
+ bool isRowHidden(int row) const;
+ void setRowHidden(int row, bool hide);
+
+ void setModelColumn(int column);
+ int modelColumn() const;
+
+ void setUniformItemSizes(bool enable);
+ bool uniformItemSizes() const;
+
+ void setWordWrap(bool on);
+ bool wordWrap() const;
+
+ void setSelectionRectVisible(bool show);
+ bool isSelectionRectVisible() const;
+
+ QRect visualRect(const QModelIndex &index) const;
+ void scrollTo(const QModelIndex &index, ScrollHint hint = EnsureVisible);
+ QModelIndex indexAt(const QPoint &p) const;
+
+ void doItemsLayout();
+ void reset();
+ void setRootIndex(const QModelIndex &index);
+
+Q_SIGNALS:
+ void indexesMoved(const QModelIndexList &indexes);
+
+protected:
+ QListView(QListViewPrivate &, QWidget *parent = 0);
+
+ bool event(QEvent *e);
+
+ void scrollContentsBy(int dx, int dy);
+
+ void resizeContents(int width, int height);
+ QSize contentsSize() const;
+
+ void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
+ void rowsInserted(const QModelIndex &parent, int start, int end);
+ void rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end);
+
+ void mouseMoveEvent(QMouseEvent *e);
+ void mouseReleaseEvent(QMouseEvent *e);
+
+ void timerEvent(QTimerEvent *e);
+ void resizeEvent(QResizeEvent *e);
+#ifndef QT_NO_DRAGANDDROP
+ void dragMoveEvent(QDragMoveEvent *e);
+ void dragLeaveEvent(QDragLeaveEvent *e);
+ void dropEvent(QDropEvent *e);
+ void startDrag(Qt::DropActions supportedActions);
+
+ void internalDrop(QDropEvent *e);
+ void internalDrag(Qt::DropActions supportedActions);
+#endif // QT_NO_DRAGANDDROP
+
+ QStyleOptionViewItem viewOptions() const;
+ void paintEvent(QPaintEvent *e);
+
+ int horizontalOffset() const;
+ int verticalOffset() const;
+ QModelIndex moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers);
+ QRect rectForIndex(const QModelIndex &index) const;
+ void setPositionForIndex(const QPoint &position, const QModelIndex &index);
+
+ void setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags command);
+ QRegion visualRegionForSelection(const QItemSelection &selection) const;
+ QModelIndexList selectedIndexes() const;
+
+ void updateGeometries();
+
+ bool isIndexHidden(const QModelIndex &index) const;
+
+ void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
+ void currentChanged(const QModelIndex &current, const QModelIndex &previous);
+
+private:
+ friend class QAccessibleItemView;
+ int visualIndex(const QModelIndex &index) const;
+
+ Q_DECLARE_PRIVATE(QListView)
+ Q_DISABLE_COPY(QListView)
+};
+
+#endif // QT_NO_LISTVIEW
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QLISTVIEW_H
diff --git a/src/gui/itemviews/qlistview_p.h b/src/widgets/itemviews/qlistview_p.h
index 6a7acf669d..6a7acf669d 100644
--- a/src/gui/itemviews/qlistview_p.h
+++ b/src/widgets/itemviews/qlistview_p.h
diff --git a/src/gui/itemviews/qlistwidget.cpp b/src/widgets/itemviews/qlistwidget.cpp
index 63badec3be..63badec3be 100644
--- a/src/gui/itemviews/qlistwidget.cpp
+++ b/src/widgets/itemviews/qlistwidget.cpp
diff --git a/src/widgets/itemviews/qlistwidget.h b/src/widgets/itemviews/qlistwidget.h
new file mode 100644
index 0000000000..750b85b4c1
--- /dev/null
+++ b/src/widgets/itemviews/qlistwidget.h
@@ -0,0 +1,335 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QLISTWIDGET_H
+#define QLISTWIDGET_H
+
+#include <QtWidgets/qlistview.h>
+#include <QtCore/qvariant.h>
+#include <QtCore/qvector.h>
+#include <QtWidgets/qitemselectionmodel.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_LISTWIDGET
+
+class QListWidget;
+class QListModel;
+class QWidgetItemData;
+class QListWidgetItemPrivate;
+
+class Q_WIDGETS_EXPORT QListWidgetItem
+{
+ friend class QListModel;
+ friend class QListWidget;
+public:
+ enum ItemType { Type = 0, UserType = 1000 };
+ explicit QListWidgetItem(QListWidget *view = 0, int type = Type);
+ explicit QListWidgetItem(const QString &text, QListWidget *view = 0, int type = Type);
+ explicit QListWidgetItem(const QIcon &icon, const QString &text,
+ QListWidget *view = 0, int type = Type);
+ QListWidgetItem(const QListWidgetItem &other);
+ virtual ~QListWidgetItem();
+
+ virtual QListWidgetItem *clone() const;
+
+ inline QListWidget *listWidget() const { return view; }
+
+ inline void setSelected(bool select);
+ inline bool isSelected() const;
+
+ inline void setHidden(bool hide);
+ inline bool isHidden() const;
+
+ inline Qt::ItemFlags flags() const { return itemFlags; }
+ void setFlags(Qt::ItemFlags flags);
+
+ inline QString text() const
+ { return data(Qt::DisplayRole).toString(); }
+ inline void setText(const QString &text);
+
+ inline QIcon icon() const
+ { return qvariant_cast<QIcon>(data(Qt::DecorationRole)); }
+ inline void setIcon(const QIcon &icon);
+
+ inline QString statusTip() const
+ { return data(Qt::StatusTipRole).toString(); }
+ inline void setStatusTip(const QString &statusTip);
+
+#ifndef QT_NO_TOOLTIP
+ inline QString toolTip() const
+ { return data(Qt::ToolTipRole).toString(); }
+ inline void setToolTip(const QString &toolTip);
+#endif
+
+#ifndef QT_NO_WHATSTHIS
+ inline QString whatsThis() const
+ { return data(Qt::WhatsThisRole).toString(); }
+ inline void setWhatsThis(const QString &whatsThis);
+#endif
+
+ inline QFont font() const
+ { return qvariant_cast<QFont>(data(Qt::FontRole)); }
+ inline void setFont(const QFont &font);
+
+ inline int textAlignment() const
+ { return data(Qt::TextAlignmentRole).toInt(); }
+ inline void setTextAlignment(int alignment)
+ { setData(Qt::TextAlignmentRole, alignment); }
+
+ inline QColor backgroundColor() const
+ { return qvariant_cast<QColor>(data(Qt::BackgroundColorRole)); }
+ virtual void setBackgroundColor(const QColor &color)
+ { setData(Qt::BackgroundColorRole, color); }
+
+ inline QBrush background() const
+ { return qvariant_cast<QBrush>(data(Qt::BackgroundRole)); }
+ inline void setBackground(const QBrush &brush)
+ { setData(Qt::BackgroundRole, brush); }
+
+ inline QColor textColor() const
+ { return qvariant_cast<QColor>(data(Qt::TextColorRole)); }
+ inline void setTextColor(const QColor &color)
+ { setData(Qt::TextColorRole, color); }
+
+ inline QBrush foreground() const
+ { return qvariant_cast<QBrush>(data(Qt::ForegroundRole)); }
+ inline void setForeground(const QBrush &brush)
+ { setData(Qt::ForegroundRole, brush); }
+
+ inline Qt::CheckState checkState() const
+ { return static_cast<Qt::CheckState>(data(Qt::CheckStateRole).toInt()); }
+ inline void setCheckState(Qt::CheckState state)
+ { setData(Qt::CheckStateRole, static_cast<int>(state)); }
+
+ inline QSize sizeHint() const
+ { return qvariant_cast<QSize>(data(Qt::SizeHintRole)); }
+ inline void setSizeHint(const QSize &size)
+ { setData(Qt::SizeHintRole, size); }
+
+ virtual QVariant data(int role) const;
+ virtual void setData(int role, const QVariant &value);
+
+ virtual bool operator<(const QListWidgetItem &other) const;
+
+#ifndef QT_NO_DATASTREAM
+ virtual void read(QDataStream &in);
+ virtual void write(QDataStream &out) const;
+#endif
+ QListWidgetItem &operator=(const QListWidgetItem &other);
+
+ inline int type() const { return rtti; }
+
+private:
+ int rtti;
+ QVector<void *> dummy;
+ QListWidget *view;
+ QListWidgetItemPrivate *d;
+ Qt::ItemFlags itemFlags;
+};
+
+inline void QListWidgetItem::setText(const QString &atext)
+{ setData(Qt::DisplayRole, atext); }
+
+inline void QListWidgetItem::setIcon(const QIcon &aicon)
+{ setData(Qt::DecorationRole, aicon); }
+
+inline void QListWidgetItem::setStatusTip(const QString &astatusTip)
+{ setData(Qt::StatusTipRole, astatusTip); }
+
+#ifndef QT_NO_TOOLTIP
+inline void QListWidgetItem::setToolTip(const QString &atoolTip)
+{ setData(Qt::ToolTipRole, atoolTip); }
+#endif
+
+#ifndef QT_NO_WHATSTHIS
+inline void QListWidgetItem::setWhatsThis(const QString &awhatsThis)
+{ setData(Qt::WhatsThisRole, awhatsThis); }
+#endif
+
+inline void QListWidgetItem::setFont(const QFont &afont)
+{ setData(Qt::FontRole, afont); }
+
+#ifndef QT_NO_DATASTREAM
+Q_WIDGETS_EXPORT QDataStream &operator<<(QDataStream &out, const QListWidgetItem &item);
+Q_WIDGETS_EXPORT QDataStream &operator>>(QDataStream &in, QListWidgetItem &item);
+#endif
+
+class QListWidgetPrivate;
+
+class Q_WIDGETS_EXPORT QListWidget : public QListView
+{
+ Q_OBJECT
+ Q_PROPERTY(int count READ count)
+ Q_PROPERTY(int currentRow READ currentRow WRITE setCurrentRow NOTIFY currentRowChanged USER true)
+ Q_PROPERTY(bool sortingEnabled READ isSortingEnabled WRITE setSortingEnabled)
+
+ friend class QListWidgetItem;
+ friend class QListModel;
+public:
+ explicit QListWidget(QWidget *parent = 0);
+ ~QListWidget();
+
+ QListWidgetItem *item(int row) const;
+ int row(const QListWidgetItem *item) const;
+ void insertItem(int row, QListWidgetItem *item);
+ void insertItem(int row, const QString &label);
+ void insertItems(int row, const QStringList &labels);
+ inline void addItem(const QString &label) { insertItem(count(), label); }
+ inline void addItem(QListWidgetItem *item);
+ inline void addItems(const QStringList &labels) { insertItems(count(), labels); }
+ QListWidgetItem *takeItem(int row);
+ int count() const;
+
+ QListWidgetItem *currentItem() const;
+ void setCurrentItem(QListWidgetItem *item);
+ void setCurrentItem(QListWidgetItem *item, QItemSelectionModel::SelectionFlags command);
+
+ int currentRow() const;
+ void setCurrentRow(int row);
+ void setCurrentRow(int row, QItemSelectionModel::SelectionFlags command);
+
+ QListWidgetItem *itemAt(const QPoint &p) const;
+ inline QListWidgetItem *itemAt(int x, int y) const;
+ QRect visualItemRect(const QListWidgetItem *item) const;
+
+ void sortItems(Qt::SortOrder order = Qt::AscendingOrder);
+ void setSortingEnabled(bool enable);
+ bool isSortingEnabled() const;
+
+ void editItem(QListWidgetItem *item);
+ void openPersistentEditor(QListWidgetItem *item);
+ void closePersistentEditor(QListWidgetItem *item);
+
+ QWidget *itemWidget(QListWidgetItem *item) const;
+ void setItemWidget(QListWidgetItem *item, QWidget *widget);
+ inline void removeItemWidget(QListWidgetItem *item);
+
+ bool isItemSelected(const QListWidgetItem *item) const;
+ void setItemSelected(const QListWidgetItem *item, bool select);
+ QList<QListWidgetItem*> selectedItems() const;
+ QList<QListWidgetItem*> findItems(const QString &text, Qt::MatchFlags flags) const;
+
+ bool isItemHidden(const QListWidgetItem *item) const;
+ void setItemHidden(const QListWidgetItem *item, bool hide);
+ void dropEvent(QDropEvent *event);
+
+public Q_SLOTS:
+ void scrollToItem(const QListWidgetItem *item, QAbstractItemView::ScrollHint hint = EnsureVisible);
+ void clear();
+
+Q_SIGNALS:
+ void itemPressed(QListWidgetItem *item);
+ void itemClicked(QListWidgetItem *item);
+ void itemDoubleClicked(QListWidgetItem *item);
+ void itemActivated(QListWidgetItem *item);
+ void itemEntered(QListWidgetItem *item);
+ void itemChanged(QListWidgetItem *item);
+
+ void currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous);
+ void currentTextChanged(const QString &currentText);
+ void currentRowChanged(int currentRow);
+
+ void itemSelectionChanged();
+
+protected:
+ bool event(QEvent *e);
+ virtual QStringList mimeTypes() const;
+ virtual QMimeData *mimeData(const QList<QListWidgetItem*> items) const;
+#ifndef QT_NO_DRAGANDDROP
+ virtual bool dropMimeData(int index, const QMimeData *data, Qt::DropAction action);
+ virtual Qt::DropActions supportedDropActions() const;
+#endif
+ QList<QListWidgetItem*> items(const QMimeData *data) const;
+
+ QModelIndex indexFromItem(QListWidgetItem *item) const;
+ QListWidgetItem *itemFromIndex(const QModelIndex &index) const;
+
+private:
+ void setModel(QAbstractItemModel *model);
+ Qt::SortOrder sortOrder() const;
+
+ Q_DECLARE_PRIVATE(QListWidget)
+ Q_DISABLE_COPY(QListWidget)
+
+ Q_PRIVATE_SLOT(d_func(), void _q_emitItemPressed(const QModelIndex &index))
+ Q_PRIVATE_SLOT(d_func(), void _q_emitItemClicked(const QModelIndex &index))
+ Q_PRIVATE_SLOT(d_func(), void _q_emitItemDoubleClicked(const QModelIndex &index))
+ Q_PRIVATE_SLOT(d_func(), void _q_emitItemActivated(const QModelIndex &index))
+ Q_PRIVATE_SLOT(d_func(), void _q_emitItemEntered(const QModelIndex &index))
+ Q_PRIVATE_SLOT(d_func(), void _q_emitItemChanged(const QModelIndex &index))
+ Q_PRIVATE_SLOT(d_func(), void _q_emitCurrentItemChanged(const QModelIndex &previous, const QModelIndex &current))
+ Q_PRIVATE_SLOT(d_func(), void _q_sort())
+ Q_PRIVATE_SLOT(d_func(), void _q_dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight))
+};
+
+inline void QListWidget::removeItemWidget(QListWidgetItem *aItem)
+{ setItemWidget(aItem, 0); }
+
+inline void QListWidget::addItem(QListWidgetItem *aitem)
+{ insertItem(count(), aitem); }
+
+inline QListWidgetItem *QListWidget::itemAt(int ax, int ay) const
+{ return itemAt(QPoint(ax, ay)); }
+
+inline void QListWidgetItem::setSelected(bool aselect)
+{ if (view) view->setItemSelected(this, aselect); }
+
+inline bool QListWidgetItem::isSelected() const
+{ return (view ? view->isItemSelected(this) : false); }
+
+inline void QListWidgetItem::setHidden(bool ahide)
+{ if (view) view->setItemHidden(this, ahide); }
+
+inline bool QListWidgetItem::isHidden() const
+{ return (view ? view->isItemHidden(this) : false); }
+
+#endif // QT_NO_LISTWIDGET
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QLISTWIDGET_H
diff --git a/src/widgets/itemviews/qlistwidget_p.h b/src/widgets/itemviews/qlistwidget_p.h
new file mode 100644
index 0000000000..2e879cc5d7
--- /dev/null
+++ b/src/widgets/itemviews/qlistwidget_p.h
@@ -0,0 +1,175 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QLISTWIDGET_P_H
+#define QLISTWIDGET_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. This header file may change
+// from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qabstractitemmodel.h>
+#include <QtWidgets/qabstractitemview.h>
+#include <QtWidgets/qlistwidget.h>
+#include <qitemdelegate.h>
+#include <private/qlistview_p.h>
+#include <private/qwidgetitemdata_p.h>
+
+#ifndef QT_NO_LISTWIDGET
+
+QT_BEGIN_NAMESPACE
+
+class QListModelLessThan
+{
+public:
+ inline bool operator()(QListWidgetItem *i1, QListWidgetItem *i2) const
+ { return *i1 < *i2; }
+};
+
+class QListModelGreaterThan
+{
+public:
+ inline bool operator()(QListWidgetItem *i1, QListWidgetItem *i2) const
+ { return *i2 < *i1; }
+};
+
+class Q_AUTOTEST_EXPORT QListModel : public QAbstractListModel
+{
+ Q_OBJECT
+public:
+ QListModel(QListWidget *parent);
+ ~QListModel();
+
+ void clear();
+ QListWidgetItem *at(int row) const;
+ void insert(int row, QListWidgetItem *item);
+ void insert(int row, const QStringList &items);
+ void remove(QListWidgetItem *item);
+ QListWidgetItem *take(int row);
+ void move(int srcRow, int dstRow);
+
+ int rowCount(const QModelIndex &parent = QModelIndex()) const;
+
+ QModelIndex index(QListWidgetItem *item) const;
+ QModelIndex index(int row, int column = 0, const QModelIndex &parent = QModelIndex()) const;
+
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+ bool setData(const QModelIndex &index, const QVariant &value, int role);
+
+ QMap<int, QVariant> itemData(const QModelIndex &index) const;
+
+ bool insertRows(int row, int count = 1, const QModelIndex &parent = QModelIndex());
+ bool removeRows(int row, int count = 1, const QModelIndex &parent = QModelIndex());
+
+ Qt::ItemFlags flags(const QModelIndex &index) const;
+
+ void sort(int column, Qt::SortOrder order);
+ void ensureSorted(int column, Qt::SortOrder order, int start, int end);
+ static bool itemLessThan(const QPair<QListWidgetItem*,int> &left,
+ const QPair<QListWidgetItem*,int> &right);
+ static bool itemGreaterThan(const QPair<QListWidgetItem*,int> &left,
+ const QPair<QListWidgetItem*,int> &right);
+ static QList<QListWidgetItem*>::iterator sortedInsertionIterator(
+ const QList<QListWidgetItem*>::iterator &begin,
+ const QList<QListWidgetItem*>::iterator &end,
+ Qt::SortOrder order, QListWidgetItem *item);
+
+ void itemChanged(QListWidgetItem *item);
+
+ // dnd
+ QStringList mimeTypes() const;
+ QMimeData *mimeData(const QModelIndexList &indexes) const;
+#ifndef QT_NO_DRAGANDDROP
+ bool dropMimeData(const QMimeData *data, Qt::DropAction action,
+ int row, int column, const QModelIndex &parent);
+ Qt::DropActions supportedDropActions() const;
+#endif
+
+ QMimeData *internalMimeData() const;
+private:
+ QList<QListWidgetItem*> items;
+
+ // A cache must be mutable if get-functions should have const modifiers
+ mutable QModelIndexList cachedIndexes;
+};
+
+
+
+class QListWidgetPrivate : public QListViewPrivate
+{
+ Q_DECLARE_PUBLIC(QListWidget)
+public:
+ QListWidgetPrivate() : QListViewPrivate(), sortOrder(Qt::AscendingOrder), sortingEnabled(false) {}
+ inline QListModel *listModel() const { return qobject_cast<QListModel*>(model); }
+ void setup();
+ void _q_emitItemPressed(const QModelIndex &index);
+ void _q_emitItemClicked(const QModelIndex &index);
+ void _q_emitItemDoubleClicked(const QModelIndex &index);
+ void _q_emitItemActivated(const QModelIndex &index);
+ void _q_emitItemEntered(const QModelIndex &index);
+ void _q_emitItemChanged(const QModelIndex &index);
+ void _q_emitCurrentItemChanged(const QModelIndex &current, const QModelIndex &previous);
+ void _q_sort();
+ void _q_dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
+ Qt::SortOrder sortOrder;
+ bool sortingEnabled;
+};
+
+class QListWidgetItemPrivate
+{
+public:
+ QListWidgetItemPrivate(QListWidgetItem *item) : q(item), theid(-1) {}
+ QListWidgetItem *q;
+ QVector<QWidgetItemData> values;
+ int theid;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_LISTWIDGET
+
+#endif // QLISTWIDGET_P_H
diff --git a/src/gui/itemviews/qproxymodel.cpp b/src/widgets/itemviews/qproxymodel.cpp
index 7042f7d0a6..7042f7d0a6 100644
--- a/src/gui/itemviews/qproxymodel.cpp
+++ b/src/widgets/itemviews/qproxymodel.cpp
diff --git a/src/widgets/itemviews/qproxymodel.h b/src/widgets/itemviews/qproxymodel.h
new file mode 100644
index 0000000000..948f9a07c9
--- /dev/null
+++ b/src/widgets/itemviews/qproxymodel.h
@@ -0,0 +1,143 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPROXYMODEL_H
+#define QPROXYMODEL_H
+
+#include <QtCore/qabstractitemmodel.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_PROXYMODEL
+
+class QProxyModelPrivate;
+
+class Q_WIDGETS_EXPORT QProxyModel : public QAbstractItemModel
+{
+ Q_OBJECT
+
+public:
+ explicit QProxyModel(QObject *parent = 0);
+ ~QProxyModel();
+
+ virtual void setModel(QAbstractItemModel *model);
+ QAbstractItemModel *model() const;
+
+ // implementing model interface
+
+ QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
+ QModelIndex parent(const QModelIndex &child) const;
+
+ int rowCount(const QModelIndex &parent = QModelIndex()) const;
+ int columnCount(const QModelIndex &parent = QModelIndex()) const;
+ bool hasChildren(const QModelIndex &parent = QModelIndex()) const;
+
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+ bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
+
+ QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
+ bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value,
+ int role = Qt::EditRole);
+
+ QStringList mimeTypes() const;
+ QMimeData *mimeData(const QModelIndexList &indexes) const;
+ bool dropMimeData(const QMimeData *data, Qt::DropAction action,
+ int row, int column, const QModelIndex &parent);
+ Qt::DropActions supportedDropActions() const;
+
+ bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex());
+ bool insertColumns(int column, int count, const QModelIndex &parent = QModelIndex());
+
+ void fetchMore(const QModelIndex &parent);
+ Qt::ItemFlags flags(const QModelIndex &index) const;
+
+ void sort(int column, Qt::SortOrder order = Qt::AscendingOrder);
+
+ QModelIndexList match(const QModelIndex &start, int role, const QVariant &value,
+ int hits = 1, Qt::MatchFlags flags =
+ Qt::MatchFlags(Qt::MatchStartsWith|Qt::MatchWrap)) const;
+
+ QSize span(const QModelIndex &index) const;
+
+ bool submit();
+ void revert();
+
+#ifdef Q_NO_USING_KEYWORD
+ inline QObject *parent() const { return QObject::parent(); }
+#else
+ using QObject::parent;
+#endif
+
+protected:
+ QProxyModel(QProxyModelPrivate &, QObject *parent = 0);
+
+ QModelIndex setProxyModel(const QModelIndex &source_index) const;
+ QModelIndex setSourceModel(const QModelIndex &proxy_index) const;
+
+ void connectToModel(const QAbstractItemModel *model) const;
+ void disconnectFromModel(const QAbstractItemModel *model) const;
+
+private:
+ Q_DECLARE_PRIVATE(QProxyModel)
+ Q_DISABLE_COPY(QProxyModel)
+
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceDataChanged(const QModelIndex&,const QModelIndex&))
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsAboutToBeInserted(const QModelIndex&,int,int))
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsInserted(const QModelIndex&,int,int))
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsAboutToBeRemoved(const QModelIndex&,int,int))
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsRemoved(const QModelIndex&,int,int))
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsAboutToBeInserted(const QModelIndex&,int,int))
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsInserted(const QModelIndex&,int,int))
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsAboutToBeRemoved(const QModelIndex&,int,int))
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsRemoved(const QModelIndex&,int,int))
+};
+
+#endif // QT_NO_PROXYMODEL
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QPROXYMODEL_H
diff --git a/src/gui/itemviews/qproxymodel_p.h b/src/widgets/itemviews/qproxymodel_p.h
index 0a8668d2f8..0a8668d2f8 100644
--- a/src/gui/itemviews/qproxymodel_p.h
+++ b/src/widgets/itemviews/qproxymodel_p.h
diff --git a/src/gui/itemviews/qsortfilterproxymodel.cpp b/src/widgets/itemviews/qsortfilterproxymodel.cpp
index b749286abe..b749286abe 100644
--- a/src/gui/itemviews/qsortfilterproxymodel.cpp
+++ b/src/widgets/itemviews/qsortfilterproxymodel.cpp
diff --git a/src/widgets/itemviews/qsortfilterproxymodel.h b/src/widgets/itemviews/qsortfilterproxymodel.h
new file mode 100644
index 0000000000..68d92be841
--- /dev/null
+++ b/src/widgets/itemviews/qsortfilterproxymodel.h
@@ -0,0 +1,201 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSORTFILTERPROXYMODEL_H
+#define QSORTFILTERPROXYMODEL_H
+
+#include <QtWidgets/qabstractproxymodel.h>
+
+#ifndef QT_NO_SORTFILTERPROXYMODEL
+
+#include <QtCore/qregexp.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QSortFilterProxyModelPrivate;
+class QSortFilterProxyModelLessThan;
+class QSortFilterProxyModelGreaterThan;
+
+class Q_WIDGETS_EXPORT QSortFilterProxyModel : public QAbstractProxyModel
+{
+ friend class QSortFilterProxyModelLessThan;
+ friend class QSortFilterProxyModelGreaterThan;
+
+ Q_OBJECT
+ Q_PROPERTY(QRegExp filterRegExp READ filterRegExp WRITE setFilterRegExp)
+ Q_PROPERTY(int filterKeyColumn READ filterKeyColumn WRITE setFilterKeyColumn)
+ Q_PROPERTY(bool dynamicSortFilter READ dynamicSortFilter WRITE setDynamicSortFilter)
+ Q_PROPERTY(Qt::CaseSensitivity filterCaseSensitivity READ filterCaseSensitivity WRITE setFilterCaseSensitivity)
+ Q_PROPERTY(Qt::CaseSensitivity sortCaseSensitivity READ sortCaseSensitivity WRITE setSortCaseSensitivity)
+ Q_PROPERTY(bool isSortLocaleAware READ isSortLocaleAware WRITE setSortLocaleAware)
+ Q_PROPERTY(int sortRole READ sortRole WRITE setSortRole)
+ Q_PROPERTY(int filterRole READ filterRole WRITE setFilterRole)
+
+public:
+ QSortFilterProxyModel(QObject *parent = 0);
+ ~QSortFilterProxyModel();
+
+ void setSourceModel(QAbstractItemModel *sourceModel);
+
+ QModelIndex mapToSource(const QModelIndex &proxyIndex) const;
+ QModelIndex mapFromSource(const QModelIndex &sourceIndex) const;
+
+ QItemSelection mapSelectionToSource(const QItemSelection &proxySelection) const;
+ QItemSelection mapSelectionFromSource(const QItemSelection &sourceSelection) const;
+
+ QRegExp filterRegExp() const;
+ void setFilterRegExp(const QRegExp &regExp);
+
+ int filterKeyColumn() const;
+ void setFilterKeyColumn(int column);
+
+ Qt::CaseSensitivity filterCaseSensitivity() const;
+ void setFilterCaseSensitivity(Qt::CaseSensitivity cs);
+
+ Qt::CaseSensitivity sortCaseSensitivity() const;
+ void setSortCaseSensitivity(Qt::CaseSensitivity cs);
+
+ bool isSortLocaleAware() const;
+ void setSortLocaleAware(bool on);
+
+ int sortColumn() const;
+ Qt::SortOrder sortOrder() const;
+
+ bool dynamicSortFilter() const;
+ void setDynamicSortFilter(bool enable);
+
+ int sortRole() const;
+ void setSortRole(int role);
+
+ int filterRole() const;
+ void setFilterRole(int role);
+
+public Q_SLOTS:
+ void setFilterRegExp(const QString &pattern);
+ void setFilterWildcard(const QString &pattern);
+ void setFilterFixedString(const QString &pattern);
+ void clear();
+ void invalidate();
+
+protected:
+ virtual bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const;
+ virtual bool filterAcceptsColumn(int source_column, const QModelIndex &source_parent) const;
+ virtual bool lessThan(const QModelIndex &left, const QModelIndex &right) const;
+
+ void filterChanged();
+ void invalidateFilter();
+
+public:
+#ifdef Q_NO_USING_KEYWORD
+ inline QObject *parent() const { return QObject::parent(); }
+#else
+ using QObject::parent;
+#endif
+
+ QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
+ QModelIndex parent(const QModelIndex &child) const;
+
+ int rowCount(const QModelIndex &parent = QModelIndex()) const;
+ int columnCount(const QModelIndex &parent = QModelIndex()) const;
+ bool hasChildren(const QModelIndex &parent = QModelIndex()) const;
+
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+ bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
+
+ QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
+ bool setHeaderData(int section, Qt::Orientation orientation,
+ const QVariant &value, int role = Qt::EditRole);
+
+ QMimeData *mimeData(const QModelIndexList &indexes) const;
+ bool dropMimeData(const QMimeData *data, Qt::DropAction action,
+ int row, int column, const QModelIndex &parent);
+
+ bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex());
+ bool insertColumns(int column, int count, const QModelIndex &parent = QModelIndex());
+ bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex());
+ bool removeColumns(int column, int count, const QModelIndex &parent = QModelIndex());
+
+ void fetchMore(const QModelIndex &parent);
+ bool canFetchMore(const QModelIndex &parent) const;
+ Qt::ItemFlags flags(const QModelIndex &index) const;
+
+ QModelIndex buddy(const QModelIndex &index) const;
+ QModelIndexList match(const QModelIndex &start, int role,
+ const QVariant &value, int hits = 1,
+ Qt::MatchFlags flags =
+ Qt::MatchFlags(Qt::MatchStartsWith|Qt::MatchWrap)) const;
+ QSize span(const QModelIndex &index) const;
+ void sort(int column, Qt::SortOrder order = Qt::AscendingOrder);
+
+ QStringList mimeTypes() const;
+ Qt::DropActions supportedDropActions() const;
+private:
+ Q_DECLARE_PRIVATE(QSortFilterProxyModel)
+ Q_DISABLE_COPY(QSortFilterProxyModel)
+
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceDataChanged(const QModelIndex &source_top_left, const QModelIndex &source_bottom_right))
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceHeaderDataChanged(Qt::Orientation orientation, int start, int end))
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceAboutToBeReset())
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceReset())
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceLayoutAboutToBeChanged())
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceLayoutChanged())
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsAboutToBeInserted(const QModelIndex &source_parent, int start, int end))
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsInserted(const QModelIndex &source_parent, int start, int end))
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsAboutToBeRemoved(const QModelIndex &source_parent, int start, int end))
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsRemoved(const QModelIndex &source_parent, int start, int end))
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsAboutToBeInserted(const QModelIndex &source_parent, int start, int end))
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsInserted(const QModelIndex &source_parent, int start, int end))
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsAboutToBeRemoved(const QModelIndex &source_parent, int start, int end))
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsRemoved(const QModelIndex &source_parent, int start, int end))
+ Q_PRIVATE_SLOT(d_func(), void _q_clearMapping())
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QT_NO_SORTFILTERPROXYMODEL
+
+#endif // QSORTFILTERPROXYMODEL_H
diff --git a/src/gui/itemviews/qstandarditemmodel.cpp b/src/widgets/itemviews/qstandarditemmodel.cpp
index 1bd5e8861c..1bd5e8861c 100644
--- a/src/gui/itemviews/qstandarditemmodel.cpp
+++ b/src/widgets/itemviews/qstandarditemmodel.cpp
diff --git a/src/widgets/itemviews/qstandarditemmodel.h b/src/widgets/itemviews/qstandarditemmodel.h
new file mode 100644
index 0000000000..b1e70fffad
--- /dev/null
+++ b/src/widgets/itemviews/qstandarditemmodel.h
@@ -0,0 +1,456 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSTANDARDITEMMODEL_H
+#define QSTANDARDITEMMODEL_H
+
+#include <QtCore/qabstractitemmodel.h>
+#include <QtGui/qbrush.h>
+#include <QtGui/qfont.h>
+#include <QtWidgets/qicon.h>
+#ifndef QT_NO_DATASTREAM
+#include <QtCore/qdatastream.h>
+#endif
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_STANDARDITEMMODEL
+
+template <class T> class QList;
+
+class QStandardItemModel;
+
+class QStandardItemPrivate;
+class Q_WIDGETS_EXPORT QStandardItem
+{
+public:
+ QStandardItem();
+ QStandardItem(const QString &text);
+ QStandardItem(const QIcon &icon, const QString &text);
+ explicit QStandardItem(int rows, int columns = 1);
+ virtual ~QStandardItem();
+
+ virtual QVariant data(int role = Qt::UserRole + 1) const;
+ virtual void setData(const QVariant &value, int role = Qt::UserRole + 1);
+
+ inline QString text() const {
+ return qvariant_cast<QString>(data(Qt::DisplayRole));
+ }
+ inline void setText(const QString &text);
+
+ inline QIcon icon() const {
+ return qvariant_cast<QIcon>(data(Qt::DecorationRole));
+ }
+ inline void setIcon(const QIcon &icon);
+
+#ifndef QT_NO_TOOLTIP
+ inline QString toolTip() const {
+ return qvariant_cast<QString>(data(Qt::ToolTipRole));
+ }
+ inline void setToolTip(const QString &toolTip);
+#endif
+
+#ifndef QT_NO_STATUSTIP
+ inline QString statusTip() const {
+ return qvariant_cast<QString>(data(Qt::StatusTipRole));
+ }
+ inline void setStatusTip(const QString &statusTip);
+#endif
+
+#ifndef QT_NO_WHATSTHIS
+ inline QString whatsThis() const {
+ return qvariant_cast<QString>(data(Qt::WhatsThisRole));
+ }
+ inline void setWhatsThis(const QString &whatsThis);
+#endif
+
+ inline QSize sizeHint() const {
+ return qvariant_cast<QSize>(data(Qt::SizeHintRole));
+ }
+ inline void setSizeHint(const QSize &sizeHint);
+
+ inline QFont font() const {
+ return qvariant_cast<QFont>(data(Qt::FontRole));
+ }
+ inline void setFont(const QFont &font);
+
+ inline Qt::Alignment textAlignment() const {
+ return Qt::Alignment(qvariant_cast<int>(data(Qt::TextAlignmentRole)));
+ }
+ inline void setTextAlignment(Qt::Alignment textAlignment);
+
+ inline QBrush background() const {
+ return qvariant_cast<QBrush>(data(Qt::BackgroundRole));
+ }
+ inline void setBackground(const QBrush &brush);
+
+ inline QBrush foreground() const {
+ return qvariant_cast<QBrush>(data(Qt::ForegroundRole));
+ }
+ inline void setForeground(const QBrush &brush);
+
+ inline Qt::CheckState checkState() const {
+ return Qt::CheckState(qvariant_cast<int>(data(Qt::CheckStateRole)));
+ }
+ inline void setCheckState(Qt::CheckState checkState);
+
+ inline QString accessibleText() const {
+ return qvariant_cast<QString>(data(Qt::AccessibleTextRole));
+ }
+ inline void setAccessibleText(const QString &accessibleText);
+
+ inline QString accessibleDescription() const {
+ return qvariant_cast<QString>(data(Qt::AccessibleDescriptionRole));
+ }
+ inline void setAccessibleDescription(const QString &accessibleDescription);
+
+ Qt::ItemFlags flags() const;
+ void setFlags(Qt::ItemFlags flags);
+
+ inline bool isEnabled() const {
+ return (flags() & Qt::ItemIsEnabled) != 0;
+ }
+ void setEnabled(bool enabled);
+
+ inline bool isEditable() const {
+ return (flags() & Qt::ItemIsEditable) != 0;
+ }
+ void setEditable(bool editable);
+
+ inline bool isSelectable() const {
+ return (flags() & Qt::ItemIsSelectable) != 0;
+ }
+ void setSelectable(bool selectable);
+
+ inline bool isCheckable() const {
+ return (flags() & Qt::ItemIsUserCheckable) != 0;
+ }
+ void setCheckable(bool checkable);
+
+ inline bool isTristate() const {
+ return (flags() & Qt::ItemIsTristate) != 0;
+ }
+ void setTristate(bool tristate);
+
+#ifndef QT_NO_DRAGANDDROP
+ inline bool isDragEnabled() const {
+ return (flags() & Qt::ItemIsDragEnabled) != 0;
+ }
+ void setDragEnabled(bool dragEnabled);
+
+ inline bool isDropEnabled() const {
+ return (flags() & Qt::ItemIsDropEnabled) != 0;
+ }
+ void setDropEnabled(bool dropEnabled);
+#endif // QT_NO_DRAGANDDROP
+
+ QStandardItem *parent() const;
+ int row() const;
+ int column() const;
+ QModelIndex index() const;
+ QStandardItemModel *model() const;
+
+ int rowCount() const;
+ void setRowCount(int rows);
+ int columnCount() const;
+ void setColumnCount(int columns);
+
+ bool hasChildren() const;
+ QStandardItem *child(int row, int column = 0) const;
+ void setChild(int row, int column, QStandardItem *item);
+ inline void setChild(int row, QStandardItem *item);
+
+ void insertRow(int row, const QList<QStandardItem*> &items);
+ void insertColumn(int column, const QList<QStandardItem*> &items);
+ void insertRows(int row, const QList<QStandardItem*> &items);
+ void insertRows(int row, int count);
+ void insertColumns(int column, int count);
+
+ void removeRow(int row);
+ void removeColumn(int column);
+ void removeRows(int row, int count);
+ void removeColumns(int column, int count);
+
+ inline void appendRow(const QList<QStandardItem*> &items);
+ inline void appendRows(const QList<QStandardItem*> &items);
+ inline void appendColumn(const QList<QStandardItem*> &items);
+ inline void insertRow(int row, QStandardItem *item);
+ inline void appendRow(QStandardItem *item);
+
+ QStandardItem *takeChild(int row, int column = 0);
+ QList<QStandardItem*> takeRow(int row);
+ QList<QStandardItem*> takeColumn(int column);
+
+ void sortChildren(int column, Qt::SortOrder order = Qt::AscendingOrder);
+
+ virtual QStandardItem *clone() const;
+
+ enum ItemType { Type = 0, UserType = 1000 };
+ virtual int type() const;
+
+#ifndef QT_NO_DATASTREAM
+ virtual void read(QDataStream &in);
+ virtual void write(QDataStream &out) const;
+#endif
+ virtual bool operator<(const QStandardItem &other) const;
+
+protected:
+ QStandardItem(const QStandardItem &other);
+ QStandardItem(QStandardItemPrivate &dd);
+ QStandardItem &operator=(const QStandardItem &other);
+ QScopedPointer<QStandardItemPrivate> d_ptr;
+
+ void emitDataChanged();
+
+private:
+ Q_DECLARE_PRIVATE(QStandardItem)
+ friend class QStandardItemModelPrivate;
+ friend class QStandardItemModel;
+};
+
+inline void QStandardItem::setText(const QString &atext)
+{ setData(atext, Qt::DisplayRole); }
+
+inline void QStandardItem::setIcon(const QIcon &aicon)
+{ setData(aicon, Qt::DecorationRole); }
+
+#ifndef QT_NO_TOOLTIP
+inline void QStandardItem::setToolTip(const QString &atoolTip)
+{ setData(atoolTip, Qt::ToolTipRole); }
+#endif
+
+#ifndef QT_NO_STATUSTIP
+inline void QStandardItem::setStatusTip(const QString &astatusTip)
+{ setData(astatusTip, Qt::StatusTipRole); }
+#endif
+
+#ifndef QT_NO_WHATSTHIS
+inline void QStandardItem::setWhatsThis(const QString &awhatsThis)
+{ setData(awhatsThis, Qt::WhatsThisRole); }
+#endif
+
+inline void QStandardItem::setSizeHint(const QSize &asizeHint)
+{ setData(asizeHint, Qt::SizeHintRole); }
+
+inline void QStandardItem::setFont(const QFont &afont)
+{ setData(afont, Qt::FontRole); }
+
+inline void QStandardItem::setTextAlignment(Qt::Alignment atextAlignment)
+{ setData(int(atextAlignment), Qt::TextAlignmentRole); }
+
+inline void QStandardItem::setBackground(const QBrush &abrush)
+{ setData(abrush, Qt::BackgroundRole); }
+
+inline void QStandardItem::setForeground(const QBrush &abrush)
+{ setData(abrush, Qt::ForegroundRole); }
+
+inline void QStandardItem::setCheckState(Qt::CheckState acheckState)
+{ setData(acheckState, Qt::CheckStateRole); }
+
+inline void QStandardItem::setAccessibleText(const QString &aaccessibleText)
+{ setData(aaccessibleText, Qt::AccessibleTextRole); }
+
+inline void QStandardItem::setAccessibleDescription(const QString &aaccessibleDescription)
+{ setData(aaccessibleDescription, Qt::AccessibleDescriptionRole); }
+
+inline void QStandardItem::setChild(int arow, QStandardItem *aitem)
+{ setChild(arow, 0, aitem); }
+
+inline void QStandardItem::appendRow(const QList<QStandardItem*> &aitems)
+{ insertRow(rowCount(), aitems); }
+
+inline void QStandardItem::appendRows(const QList<QStandardItem*> &aitems)
+{ insertRows(rowCount(), aitems); }
+
+inline void QStandardItem::appendColumn(const QList<QStandardItem*> &aitems)
+{ insertColumn(columnCount(), aitems); }
+
+inline void QStandardItem::insertRow(int arow, QStandardItem *aitem)
+{ insertRow(arow, QList<QStandardItem*>() << aitem); }
+
+inline void QStandardItem::appendRow(QStandardItem *aitem)
+{ insertRow(rowCount(), aitem); }
+
+class QStandardItemModelPrivate;
+
+class Q_WIDGETS_EXPORT QStandardItemModel : public QAbstractItemModel
+{
+ Q_OBJECT
+ Q_PROPERTY(int sortRole READ sortRole WRITE setSortRole)
+
+public:
+ explicit QStandardItemModel(QObject *parent = 0);
+ QStandardItemModel(int rows, int columns, QObject *parent = 0);
+ ~QStandardItemModel();
+
+ QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
+ QModelIndex parent(const QModelIndex &child) const;
+
+ int rowCount(const QModelIndex &parent = QModelIndex()) const;
+ int columnCount(const QModelIndex &parent = QModelIndex()) const;
+ bool hasChildren(const QModelIndex &parent = QModelIndex()) const;
+
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+ bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
+
+ QVariant headerData(int section, Qt::Orientation orientation,
+ int role = Qt::DisplayRole) const;
+ bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value,
+ int role = Qt::EditRole);
+
+ bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex());
+ bool insertColumns(int column, int count, const QModelIndex &parent = QModelIndex());
+ bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex());
+ bool removeColumns(int column, int count, const QModelIndex &parent = QModelIndex());
+
+ Qt::ItemFlags flags(const QModelIndex &index) const;
+ Qt::DropActions supportedDropActions() const;
+
+ QMap<int, QVariant> itemData(const QModelIndex &index) const;
+ bool setItemData(const QModelIndex &index, const QMap<int, QVariant> &roles);
+
+ void clear();
+
+#ifdef Q_NO_USING_KEYWORD
+ inline QObject *parent() const { return QObject::parent(); }
+#else
+ using QObject::parent;
+#endif
+
+ void sort(int column, Qt::SortOrder order = Qt::AscendingOrder);
+
+ QStandardItem *itemFromIndex(const QModelIndex &index) const;
+ QModelIndex indexFromItem(const QStandardItem *item) const;
+
+ QStandardItem *item(int row, int column = 0) const;
+ void setItem(int row, int column, QStandardItem *item);
+ inline void setItem(int row, QStandardItem *item);
+ QStandardItem *invisibleRootItem() const;
+
+ QStandardItem *horizontalHeaderItem(int column) const;
+ void setHorizontalHeaderItem(int column, QStandardItem *item);
+ QStandardItem *verticalHeaderItem(int row) const;
+ void setVerticalHeaderItem(int row, QStandardItem *item);
+
+ void setHorizontalHeaderLabels(const QStringList &labels);
+ void setVerticalHeaderLabels(const QStringList &labels);
+
+ void setRowCount(int rows);
+ void setColumnCount(int columns);
+
+ void appendRow(const QList<QStandardItem*> &items);
+ void appendColumn(const QList<QStandardItem*> &items);
+ inline void appendRow(QStandardItem *item);
+
+ void insertRow(int row, const QList<QStandardItem*> &items);
+ void insertColumn(int column, const QList<QStandardItem*> &items);
+ inline void insertRow(int row, QStandardItem *item);
+
+ inline bool insertRow(int row, const QModelIndex &parent = QModelIndex());
+ inline bool insertColumn(int column, const QModelIndex &parent = QModelIndex());
+
+ QStandardItem *takeItem(int row, int column = 0);
+ QList<QStandardItem*> takeRow(int row);
+ QList<QStandardItem*> takeColumn(int column);
+
+ QStandardItem *takeHorizontalHeaderItem(int column);
+ QStandardItem *takeVerticalHeaderItem(int row);
+
+ const QStandardItem *itemPrototype() const;
+ void setItemPrototype(const QStandardItem *item);
+
+ QList<QStandardItem*> findItems(const QString &text,
+ Qt::MatchFlags flags = Qt::MatchExactly,
+ int column = 0) const;
+
+ int sortRole() const;
+ void setSortRole(int role);
+
+ QStringList mimeTypes() const;
+ QMimeData *mimeData(const QModelIndexList &indexes) const;
+ bool dropMimeData (const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent);
+
+Q_SIGNALS:
+ void itemChanged(QStandardItem *item);
+
+protected:
+ QStandardItemModel(QStandardItemModelPrivate &dd, QObject *parent = 0);
+
+private:
+ friend class QStandardItemPrivate;
+ friend class QStandardItem;
+ Q_DISABLE_COPY(QStandardItemModel)
+ Q_DECLARE_PRIVATE(QStandardItemModel)
+
+ Q_PRIVATE_SLOT(d_func(), void _q_emitItemChanged(const QModelIndex &topLeft,
+ const QModelIndex &bottomRight))
+};
+
+inline void QStandardItemModel::setItem(int arow, QStandardItem *aitem)
+{ setItem(arow, 0, aitem); }
+
+inline void QStandardItemModel::appendRow(QStandardItem *aitem)
+{ appendRow(QList<QStandardItem*>() << aitem); }
+
+inline void QStandardItemModel::insertRow(int arow, QStandardItem *aitem)
+{ insertRow(arow, QList<QStandardItem*>() << aitem); }
+
+inline bool QStandardItemModel::insertRow(int arow, const QModelIndex &aparent)
+{ return QAbstractItemModel::insertRow(arow, aparent); }
+inline bool QStandardItemModel::insertColumn(int acolumn, const QModelIndex &aparent)
+{ return QAbstractItemModel::insertColumn(acolumn, aparent); }
+
+#ifndef QT_NO_DATASTREAM
+Q_WIDGETS_EXPORT QDataStream &operator>>(QDataStream &in, QStandardItem &item);
+Q_WIDGETS_EXPORT QDataStream &operator<<(QDataStream &out, const QStandardItem &item);
+#endif
+
+#endif // QT_NO_STANDARDITEMMODEL
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif //QSTANDARDITEMMODEL_H
diff --git a/src/gui/itemviews/qstandarditemmodel_p.h b/src/widgets/itemviews/qstandarditemmodel_p.h
index dc2b5b9a3f..dc2b5b9a3f 100644
--- a/src/gui/itemviews/qstandarditemmodel_p.h
+++ b/src/widgets/itemviews/qstandarditemmodel_p.h
diff --git a/src/gui/itemviews/qstringlistmodel.cpp b/src/widgets/itemviews/qstringlistmodel.cpp
index 367decc7d8..367decc7d8 100644
--- a/src/gui/itemviews/qstringlistmodel.cpp
+++ b/src/widgets/itemviews/qstringlistmodel.cpp
diff --git a/src/widgets/itemviews/qstringlistmodel.h b/src/widgets/itemviews/qstringlistmodel.h
new file mode 100644
index 0000000000..5efed8753e
--- /dev/null
+++ b/src/widgets/itemviews/qstringlistmodel.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSTRINGLISTMODEL_H
+#define QSTRINGLISTMODEL_H
+
+#include <QtCore/qstringlist.h>
+#include <QtWidgets/qabstractitemview.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_STRINGLISTMODEL
+
+class Q_WIDGETS_EXPORT QStringListModel : public QAbstractListModel
+{
+ Q_OBJECT
+public:
+ explicit QStringListModel(QObject *parent = 0);
+ QStringListModel(const QStringList &strings, QObject *parent = 0);
+
+ int rowCount(const QModelIndex &parent = QModelIndex()) const;
+
+ QVariant data(const QModelIndex &index, int role) const;
+ bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
+
+ Qt::ItemFlags flags(const QModelIndex &index) const;
+
+ bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex());
+ bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex());
+
+ void sort(int column, Qt::SortOrder order = Qt::AscendingOrder);
+
+ QStringList stringList() const;
+ void setStringList(const QStringList &strings);
+
+ Qt::DropActions supportedDropActions() const;
+
+private:
+ Q_DISABLE_COPY(QStringListModel)
+ QStringList lst;
+};
+
+#endif // QT_NO_STRINGLISTMODEL
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QSTRINGLISTMODEL_H
diff --git a/src/gui/itemviews/qstyleditemdelegate.cpp b/src/widgets/itemviews/qstyleditemdelegate.cpp
index 931d870acb..931d870acb 100644
--- a/src/gui/itemviews/qstyleditemdelegate.cpp
+++ b/src/widgets/itemviews/qstyleditemdelegate.cpp
diff --git a/src/widgets/itemviews/qstyleditemdelegate.h b/src/widgets/itemviews/qstyleditemdelegate.h
new file mode 100644
index 0000000000..6dda0041c9
--- /dev/null
+++ b/src/widgets/itemviews/qstyleditemdelegate.h
@@ -0,0 +1,116 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSTYLEDITEMDELEGATE_H
+#define QSTYLEDITEMDELEGATE_H
+
+#include <QtWidgets/qabstractitemdelegate.h>
+#include <QtCore/qstring.h>
+#include <QtGui/qpixmap.h>
+#include <QtCore/qvariant.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_ITEMVIEWS
+
+class QStyledItemDelegatePrivate;
+class QItemEditorFactory;
+
+class Q_WIDGETS_EXPORT QStyledItemDelegate : public QAbstractItemDelegate
+{
+ Q_OBJECT
+
+public:
+ explicit QStyledItemDelegate(QObject *parent = 0);
+ ~QStyledItemDelegate();
+
+ // painting
+ void paint(QPainter *painter,
+ const QStyleOptionViewItem &option, const QModelIndex &index) const;
+ QSize sizeHint(const QStyleOptionViewItem &option,
+ const QModelIndex &index) const;
+
+ // editing
+ QWidget *createEditor(QWidget *parent,
+ const QStyleOptionViewItem &option,
+ const QModelIndex &index) const;
+
+ void setEditorData(QWidget *editor, const QModelIndex &index) const;
+ void setModelData(QWidget *editor,
+ QAbstractItemModel *model,
+ const QModelIndex &index) const;
+
+ void updateEditorGeometry(QWidget *editor,
+ const QStyleOptionViewItem &option,
+ const QModelIndex &index) const;
+
+ // editor factory
+ QItemEditorFactory *itemEditorFactory() const;
+ void setItemEditorFactory(QItemEditorFactory *factory);
+
+ virtual QString displayText(const QVariant &value, const QLocale &locale) const;
+
+protected:
+ virtual void initStyleOption(QStyleOptionViewItem *option,
+ const QModelIndex &index) const;
+
+ bool eventFilter(QObject *object, QEvent *event);
+ bool editorEvent(QEvent *event, QAbstractItemModel *model,
+ const QStyleOptionViewItem &option, const QModelIndex &index);
+
+private:
+ Q_DECLARE_PRIVATE(QStyledItemDelegate)
+ Q_DISABLE_COPY(QStyledItemDelegate)
+
+ Q_PRIVATE_SLOT(d_func(), void _q_commitDataAndCloseEditor(QWidget*))
+};
+
+#endif // QT_NO_ITEMVIEWS
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QSTYLEDITEMDELEGATE_H
diff --git a/src/gui/itemviews/qtableview.cpp b/src/widgets/itemviews/qtableview.cpp
index 6f532eb7c7..6f532eb7c7 100644
--- a/src/gui/itemviews/qtableview.cpp
+++ b/src/widgets/itemviews/qtableview.cpp
diff --git a/src/widgets/itemviews/qtableview.h b/src/widgets/itemviews/qtableview.h
new file mode 100644
index 0000000000..29f3793836
--- /dev/null
+++ b/src/widgets/itemviews/qtableview.h
@@ -0,0 +1,198 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTABLEVIEW_H
+#define QTABLEVIEW_H
+
+#include <QtWidgets/qabstractitemview.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_TABLEVIEW
+
+class QHeaderView;
+class QTableViewPrivate;
+
+class Q_WIDGETS_EXPORT QTableView : public QAbstractItemView
+{
+ Q_OBJECT
+ Q_PROPERTY(bool showGrid READ showGrid WRITE setShowGrid)
+ Q_PROPERTY(Qt::PenStyle gridStyle READ gridStyle WRITE setGridStyle)
+ Q_PROPERTY(bool sortingEnabled READ isSortingEnabled WRITE setSortingEnabled)
+ Q_PROPERTY(bool wordWrap READ wordWrap WRITE setWordWrap)
+ Q_PROPERTY(bool cornerButtonEnabled READ isCornerButtonEnabled WRITE setCornerButtonEnabled)
+
+public:
+ explicit QTableView(QWidget *parent = 0);
+ ~QTableView();
+
+ void setModel(QAbstractItemModel *model);
+ void setRootIndex(const QModelIndex &index);
+ void setSelectionModel(QItemSelectionModel *selectionModel);
+ void doItemsLayout();
+
+ QHeaderView *horizontalHeader() const;
+ QHeaderView *verticalHeader() const;
+ void setHorizontalHeader(QHeaderView *header);
+ void setVerticalHeader(QHeaderView *header);
+
+ int rowViewportPosition(int row) const;
+ int rowAt(int y) const;
+
+ void setRowHeight(int row, int height);
+ int rowHeight(int row) const;
+
+ int columnViewportPosition(int column) const;
+ int columnAt(int x) const;
+
+ void setColumnWidth(int column, int width);
+ int columnWidth(int column) const;
+
+ bool isRowHidden(int row) const;
+ void setRowHidden(int row, bool hide);
+
+ bool isColumnHidden(int column) const;
+ void setColumnHidden(int column, bool hide);
+
+ void setSortingEnabled(bool enable);
+ bool isSortingEnabled() const;
+
+ bool showGrid() const;
+
+ Qt::PenStyle gridStyle() const;
+ void setGridStyle(Qt::PenStyle style);
+
+ void setWordWrap(bool on);
+ bool wordWrap() const;
+
+ void setCornerButtonEnabled(bool enable);
+ bool isCornerButtonEnabled() const;
+
+ QRect visualRect(const QModelIndex &index) const;
+ void scrollTo(const QModelIndex &index, ScrollHint hint = EnsureVisible);
+ QModelIndex indexAt(const QPoint &p) const;
+
+ void setSpan(int row, int column, int rowSpan, int columnSpan);
+ int rowSpan(int row, int column) const;
+ int columnSpan(int row, int column) const;
+ void clearSpans();
+
+ void sortByColumn(int column, Qt::SortOrder order);
+
+public Q_SLOTS:
+ void selectRow(int row);
+ void selectColumn(int column);
+ void hideRow(int row);
+ void hideColumn(int column);
+ void showRow(int row);
+ void showColumn(int column);
+ void resizeRowToContents(int row);
+ void resizeRowsToContents();
+ void resizeColumnToContents(int column);
+ void resizeColumnsToContents();
+ void sortByColumn(int column);
+ void setShowGrid(bool show);
+
+protected Q_SLOTS:
+ void rowMoved(int row, int oldIndex, int newIndex);
+ void columnMoved(int column, int oldIndex, int newIndex);
+ void rowResized(int row, int oldHeight, int newHeight);
+ void columnResized(int column, int oldWidth, int newWidth);
+ void rowCountChanged(int oldCount, int newCount);
+ void columnCountChanged(int oldCount, int newCount);
+
+protected:
+ QTableView(QTableViewPrivate &, QWidget *parent);
+ void scrollContentsBy(int dx, int dy);
+
+ QStyleOptionViewItem viewOptions() const;
+ void paintEvent(QPaintEvent *e);
+
+ void timerEvent(QTimerEvent *event);
+
+ int horizontalOffset() const;
+ int verticalOffset() const;
+ QModelIndex moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers);
+
+ void setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags command);
+ QRegion visualRegionForSelection(const QItemSelection &selection) const;
+ QModelIndexList selectedIndexes() const;
+
+ void updateGeometries();
+
+ int sizeHintForRow(int row) const;
+ int sizeHintForColumn(int column) const;
+
+ void verticalScrollbarAction(int action);
+ void horizontalScrollbarAction(int action);
+
+ bool isIndexHidden(const QModelIndex &index) const;
+
+ void selectionChanged(const QItemSelection &selected,
+ const QItemSelection &deselected);
+ void currentChanged(const QModelIndex &current,
+ const QModelIndex &previous);
+
+private:
+ friend class QAccessibleItemView;
+ int visualIndex(const QModelIndex &index) const;
+
+ Q_DECLARE_PRIVATE(QTableView)
+ Q_DISABLE_COPY(QTableView)
+ Q_PRIVATE_SLOT(d_func(), void _q_selectRow(int))
+ Q_PRIVATE_SLOT(d_func(), void _q_selectColumn(int))
+ Q_PRIVATE_SLOT(d_func(), void _q_updateSpanInsertedRows(QModelIndex,int,int))
+ Q_PRIVATE_SLOT(d_func(), void _q_updateSpanInsertedColumns(QModelIndex,int,int))
+ Q_PRIVATE_SLOT(d_func(), void _q_updateSpanRemovedRows(QModelIndex,int,int))
+ Q_PRIVATE_SLOT(d_func(), void _q_updateSpanRemovedColumns(QModelIndex,int,int))
+};
+
+#endif // QT_NO_TABLEVIEW
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QTABLEVIEW_H
diff --git a/src/gui/itemviews/qtableview_p.h b/src/widgets/itemviews/qtableview_p.h
index dce0ed06ac..dce0ed06ac 100644
--- a/src/gui/itemviews/qtableview_p.h
+++ b/src/widgets/itemviews/qtableview_p.h
diff --git a/src/gui/itemviews/qtablewidget.cpp b/src/widgets/itemviews/qtablewidget.cpp
index 3496327be1..3496327be1 100644
--- a/src/gui/itemviews/qtablewidget.cpp
+++ b/src/widgets/itemviews/qtablewidget.cpp
diff --git a/src/widgets/itemviews/qtablewidget.h b/src/widgets/itemviews/qtablewidget.h
new file mode 100644
index 0000000000..d7332542d2
--- /dev/null
+++ b/src/widgets/itemviews/qtablewidget.h
@@ -0,0 +1,377 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTABLEWIDGET_H
+#define QTABLEWIDGET_H
+
+#include <QtWidgets/qtableview.h>
+#include <QtCore/qvariant.h>
+#include <QtCore/qvector.h>
+//#include <QtWidgets/qitemselectionmodel.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_TABLEWIDGET
+
+class Q_WIDGETS_EXPORT QTableWidgetSelectionRange
+{
+public:
+ QTableWidgetSelectionRange();
+ QTableWidgetSelectionRange(int top, int left, int bottom, int right);
+ QTableWidgetSelectionRange(const QTableWidgetSelectionRange &other);
+ ~QTableWidgetSelectionRange();
+
+ inline int topRow() const { return top; }
+ inline int bottomRow() const { return bottom; }
+ inline int leftColumn() const { return left; }
+ inline int rightColumn() const { return right; }
+ inline int rowCount() const { return bottom - top + 1; }
+ inline int columnCount() const { return right - left + 1; }
+
+private:
+ int top, left, bottom, right;
+};
+
+class QTableWidget;
+class QTableModel;
+class QWidgetItemData;
+class QTableWidgetItemPrivate;
+
+class Q_WIDGETS_EXPORT QTableWidgetItem
+{
+ friend class QTableWidget;
+ friend class QTableModel;
+public:
+ enum ItemType { Type = 0, UserType = 1000 };
+ QTableWidgetItem(int type = Type);
+ explicit QTableWidgetItem(const QString &text, int type = Type);
+ explicit QTableWidgetItem(const QIcon &icon, const QString &text, int type = Type);
+ QTableWidgetItem(const QTableWidgetItem &other);
+ virtual ~QTableWidgetItem();
+
+ virtual QTableWidgetItem *clone() const;
+
+ inline QTableWidget *tableWidget() const { return view; }
+
+ inline int row() const;
+ inline int column() const;
+
+ inline void setSelected(bool select);
+ inline bool isSelected() const;
+
+ inline Qt::ItemFlags flags() const { return itemFlags; }
+ void setFlags(Qt::ItemFlags flags);
+
+ inline QString text() const
+ { return data(Qt::DisplayRole).toString(); }
+ inline void setText(const QString &text);
+
+ inline QIcon icon() const
+ { return qvariant_cast<QIcon>(data(Qt::DecorationRole)); }
+ inline void setIcon(const QIcon &icon);
+
+ inline QString statusTip() const
+ { return data(Qt::StatusTipRole).toString(); }
+ inline void setStatusTip(const QString &statusTip);
+
+#ifndef QT_NO_TOOLTIP
+ inline QString toolTip() const
+ { return data(Qt::ToolTipRole).toString(); }
+ inline void setToolTip(const QString &toolTip);
+#endif
+
+#ifndef QT_NO_WHATSTHIS
+ inline QString whatsThis() const
+ { return data(Qt::WhatsThisRole).toString(); }
+ inline void setWhatsThis(const QString &whatsThis);
+#endif
+
+ inline QFont font() const
+ { return qvariant_cast<QFont>(data(Qt::FontRole)); }
+ inline void setFont(const QFont &font);
+
+ inline int textAlignment() const
+ { return data(Qt::TextAlignmentRole).toInt(); }
+ inline void setTextAlignment(int alignment)
+ { setData(Qt::TextAlignmentRole, alignment); }
+
+ inline QColor backgroundColor() const
+ { return qvariant_cast<QColor>(data(Qt::BackgroundColorRole)); }
+ inline void setBackgroundColor(const QColor &color)
+ { setData(Qt::BackgroundColorRole, color); }
+
+ inline QBrush background() const
+ { return qvariant_cast<QBrush>(data(Qt::BackgroundRole)); }
+ inline void setBackground(const QBrush &brush)
+ { setData(Qt::BackgroundRole, brush); }
+
+ inline QColor textColor() const
+ { return qvariant_cast<QColor>(data(Qt::TextColorRole)); }
+ inline void setTextColor(const QColor &color)
+ { setData(Qt::TextColorRole, color); }
+
+ inline QBrush foreground() const
+ { return qvariant_cast<QBrush>(data(Qt::ForegroundRole)); }
+ inline void setForeground(const QBrush &brush)
+ { setData(Qt::ForegroundRole, brush); }
+
+ inline Qt::CheckState checkState() const
+ { return static_cast<Qt::CheckState>(data(Qt::CheckStateRole).toInt()); }
+ inline void setCheckState(Qt::CheckState state)
+ { setData(Qt::CheckStateRole, state); }
+
+ inline QSize sizeHint() const
+ { return qvariant_cast<QSize>(data(Qt::SizeHintRole)); }
+ inline void setSizeHint(const QSize &size)
+ { setData(Qt::SizeHintRole, size); }
+
+ virtual QVariant data(int role) const;
+ virtual void setData(int role, const QVariant &value);
+
+ virtual bool operator<(const QTableWidgetItem &other) const;
+
+#ifndef QT_NO_DATASTREAM
+ virtual void read(QDataStream &in);
+ virtual void write(QDataStream &out) const;
+#endif
+ QTableWidgetItem &operator=(const QTableWidgetItem &other);
+
+ inline int type() const { return rtti; }
+
+private:
+ int rtti;
+ QVector<QWidgetItemData> values;
+ QTableWidget *view;
+ QTableWidgetItemPrivate *d;
+ Qt::ItemFlags itemFlags;
+};
+
+inline void QTableWidgetItem::setText(const QString &atext)
+{ setData(Qt::DisplayRole, atext); }
+
+inline void QTableWidgetItem::setIcon(const QIcon &aicon)
+{ setData(Qt::DecorationRole, aicon); }
+
+inline void QTableWidgetItem::setStatusTip(const QString &astatusTip)
+{ setData(Qt::StatusTipRole, astatusTip); }
+
+#ifndef QT_NO_TOOLTIP
+inline void QTableWidgetItem::setToolTip(const QString &atoolTip)
+{ setData(Qt::ToolTipRole, atoolTip); }
+#endif
+
+#ifndef QT_NO_WHATSTHIS
+inline void QTableWidgetItem::setWhatsThis(const QString &awhatsThis)
+{ setData(Qt::WhatsThisRole, awhatsThis); }
+#endif
+
+inline void QTableWidgetItem::setFont(const QFont &afont)
+{ setData(Qt::FontRole, afont); }
+
+#ifndef QT_NO_DATASTREAM
+Q_WIDGETS_EXPORT QDataStream &operator>>(QDataStream &in, QTableWidgetItem &item);
+Q_WIDGETS_EXPORT QDataStream &operator<<(QDataStream &out, const QTableWidgetItem &item);
+#endif
+
+class QTableWidgetPrivate;
+
+class Q_WIDGETS_EXPORT QTableWidget : public QTableView
+{
+ Q_OBJECT
+ Q_PROPERTY(int rowCount READ rowCount WRITE setRowCount)
+ Q_PROPERTY(int columnCount READ columnCount WRITE setColumnCount)
+
+ friend class QTableModel;
+public:
+ explicit QTableWidget(QWidget *parent = 0);
+ QTableWidget(int rows, int columns, QWidget *parent = 0);
+ ~QTableWidget();
+
+ void setRowCount(int rows);
+ int rowCount() const;
+
+ void setColumnCount(int columns);
+ int columnCount() const;
+
+ int row(const QTableWidgetItem *item) const;
+ int column(const QTableWidgetItem *item) const;
+
+ QTableWidgetItem *item(int row, int column) const;
+ void setItem(int row, int column, QTableWidgetItem *item);
+ QTableWidgetItem *takeItem(int row, int column);
+
+ QTableWidgetItem *verticalHeaderItem(int row) const;
+ void setVerticalHeaderItem(int row, QTableWidgetItem *item);
+ QTableWidgetItem *takeVerticalHeaderItem(int row);
+
+ QTableWidgetItem *horizontalHeaderItem(int column) const;
+ void setHorizontalHeaderItem(int column, QTableWidgetItem *item);
+ QTableWidgetItem *takeHorizontalHeaderItem(int column);
+ void setVerticalHeaderLabels(const QStringList &labels);
+ void setHorizontalHeaderLabels(const QStringList &labels);
+
+ int currentRow() const;
+ int currentColumn() const;
+ QTableWidgetItem *currentItem() const;
+ void setCurrentItem(QTableWidgetItem *item);
+ void setCurrentItem(QTableWidgetItem *item, QItemSelectionModel::SelectionFlags command);
+ void setCurrentCell(int row, int column);
+ void setCurrentCell(int row, int column, QItemSelectionModel::SelectionFlags command);
+
+ void sortItems(int column, Qt::SortOrder order = Qt::AscendingOrder);
+ void setSortingEnabled(bool enable);
+ bool isSortingEnabled() const;
+
+ void editItem(QTableWidgetItem *item);
+ void openPersistentEditor(QTableWidgetItem *item);
+ void closePersistentEditor(QTableWidgetItem *item);
+
+ QWidget *cellWidget(int row, int column) const;
+ void setCellWidget(int row, int column, QWidget *widget);
+ inline void removeCellWidget(int row, int column);
+
+ bool isItemSelected(const QTableWidgetItem *item) const;
+ void setItemSelected(const QTableWidgetItem *item, bool select);
+ void setRangeSelected(const QTableWidgetSelectionRange &range, bool select);
+
+ QList<QTableWidgetSelectionRange> selectedRanges() const;
+ QList<QTableWidgetItem*> selectedItems();
+ QList<QTableWidgetItem*> findItems(const QString &text, Qt::MatchFlags flags) const;
+
+ int visualRow(int logicalRow) const;
+ int visualColumn(int logicalColumn) const;
+
+ QTableWidgetItem *itemAt(const QPoint &p) const;
+ inline QTableWidgetItem *itemAt(int x, int y) const;
+ QRect visualItemRect(const QTableWidgetItem *item) const;
+
+ const QTableWidgetItem *itemPrototype() const;
+ void setItemPrototype(const QTableWidgetItem *item);
+
+public Q_SLOTS:
+ void scrollToItem(const QTableWidgetItem *item, QAbstractItemView::ScrollHint hint = EnsureVisible);
+ void insertRow(int row);
+ void insertColumn(int column);
+ void removeRow(int row);
+ void removeColumn(int column);
+ void clear();
+ void clearContents();
+
+Q_SIGNALS:
+ void itemPressed(QTableWidgetItem *item);
+ void itemClicked(QTableWidgetItem *item);
+ void itemDoubleClicked(QTableWidgetItem *item);
+
+ void itemActivated(QTableWidgetItem *item);
+ void itemEntered(QTableWidgetItem *item);
+ void itemChanged(QTableWidgetItem *item);
+
+ void currentItemChanged(QTableWidgetItem *current, QTableWidgetItem *previous);
+ void itemSelectionChanged();
+
+ void cellPressed(int row, int column);
+ void cellClicked(int row, int column);
+ void cellDoubleClicked(int row, int column);
+
+ void cellActivated(int row, int column);
+ void cellEntered(int row, int column);
+ void cellChanged(int row, int column);
+
+ void currentCellChanged(int currentRow, int currentColumn, int previousRow, int previousColumn);
+
+protected:
+ bool event(QEvent *e);
+ virtual QStringList mimeTypes() const;
+ virtual QMimeData *mimeData(const QList<QTableWidgetItem*> items) const;
+ virtual bool dropMimeData(int row, int column, const QMimeData *data, Qt::DropAction action);
+ virtual Qt::DropActions supportedDropActions() const;
+ QList<QTableWidgetItem*> items(const QMimeData *data) const;
+
+ QModelIndex indexFromItem(QTableWidgetItem *item) const;
+ QTableWidgetItem *itemFromIndex(const QModelIndex &index) const;
+ void dropEvent(QDropEvent *event);
+
+private:
+ void setModel(QAbstractItemModel *model);
+
+ Q_DECLARE_PRIVATE(QTableWidget)
+ Q_DISABLE_COPY(QTableWidget)
+
+ Q_PRIVATE_SLOT(d_func(), void _q_emitItemPressed(const QModelIndex &index))
+ Q_PRIVATE_SLOT(d_func(), void _q_emitItemClicked(const QModelIndex &index))
+ Q_PRIVATE_SLOT(d_func(), void _q_emitItemDoubleClicked(const QModelIndex &index))
+ Q_PRIVATE_SLOT(d_func(), void _q_emitItemActivated(const QModelIndex &index))
+ Q_PRIVATE_SLOT(d_func(), void _q_emitItemEntered(const QModelIndex &index))
+ Q_PRIVATE_SLOT(d_func(), void _q_emitItemChanged(const QModelIndex &index))
+ Q_PRIVATE_SLOT(d_func(), void _q_emitCurrentItemChanged(const QModelIndex &previous, const QModelIndex &current))
+ Q_PRIVATE_SLOT(d_func(), void _q_sort())
+ Q_PRIVATE_SLOT(d_func(), void _q_dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight))
+};
+
+inline void QTableWidget::removeCellWidget(int arow, int acolumn)
+{ setCellWidget(arow, acolumn, 0); }
+
+inline QTableWidgetItem *QTableWidget::itemAt(int ax, int ay) const
+{ return itemAt(QPoint(ax, ay)); }
+
+inline int QTableWidgetItem::row() const
+{ return (view ? view->row(this) : -1); }
+
+inline int QTableWidgetItem::column() const
+{ return (view ? view->column(this) : -1); }
+
+inline void QTableWidgetItem::setSelected(bool aselect)
+{ if (view) view->setItemSelected(this, aselect); }
+
+inline bool QTableWidgetItem::isSelected() const
+{ return (view ? view->isItemSelected(this) : false); }
+
+#endif // QT_NO_TABLEWIDGET
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QTABLEWIDGET_H
diff --git a/src/gui/itemviews/qtablewidget_p.h b/src/widgets/itemviews/qtablewidget_p.h
index 7b7fc21ce8..7b7fc21ce8 100644
--- a/src/gui/itemviews/qtablewidget_p.h
+++ b/src/widgets/itemviews/qtablewidget_p.h
diff --git a/src/gui/itemviews/qtreeview.cpp b/src/widgets/itemviews/qtreeview.cpp
index 9228ac82a2..9228ac82a2 100644
--- a/src/gui/itemviews/qtreeview.cpp
+++ b/src/widgets/itemviews/qtreeview.cpp
diff --git a/src/widgets/itemviews/qtreeview.h b/src/widgets/itemviews/qtreeview.h
new file mode 100644
index 0000000000..47cac2faed
--- /dev/null
+++ b/src/widgets/itemviews/qtreeview.h
@@ -0,0 +1,242 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTREEVIEW_H
+#define QTREEVIEW_H
+
+#include <QtWidgets/qabstractitemview.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_TREEVIEW
+
+class QTreeViewPrivate;
+class QHeaderView;
+
+class Q_WIDGETS_EXPORT QTreeView : public QAbstractItemView
+{
+ Q_OBJECT
+ Q_PROPERTY(int autoExpandDelay READ autoExpandDelay WRITE setAutoExpandDelay)
+ Q_PROPERTY(int indentation READ indentation WRITE setIndentation)
+ Q_PROPERTY(bool rootIsDecorated READ rootIsDecorated WRITE setRootIsDecorated)
+ Q_PROPERTY(bool uniformRowHeights READ uniformRowHeights WRITE setUniformRowHeights)
+ Q_PROPERTY(bool itemsExpandable READ itemsExpandable WRITE setItemsExpandable)
+ Q_PROPERTY(bool sortingEnabled READ isSortingEnabled WRITE setSortingEnabled)
+ Q_PROPERTY(bool animated READ isAnimated WRITE setAnimated)
+ Q_PROPERTY(bool allColumnsShowFocus READ allColumnsShowFocus WRITE setAllColumnsShowFocus)
+ Q_PROPERTY(bool wordWrap READ wordWrap WRITE setWordWrap)
+ Q_PROPERTY(bool headerHidden READ isHeaderHidden WRITE setHeaderHidden)
+ Q_PROPERTY(bool expandsOnDoubleClick READ expandsOnDoubleClick WRITE setExpandsOnDoubleClick)
+
+public:
+ explicit QTreeView(QWidget *parent = 0);
+ ~QTreeView();
+
+ void setModel(QAbstractItemModel *model);
+ void setRootIndex(const QModelIndex &index);
+ void setSelectionModel(QItemSelectionModel *selectionModel);
+
+ QHeaderView *header() const;
+ void setHeader(QHeaderView *header);
+
+ int autoExpandDelay() const;
+ void setAutoExpandDelay(int delay);
+
+ int indentation() const;
+ void setIndentation(int i);
+
+ bool rootIsDecorated() const;
+ void setRootIsDecorated(bool show);
+
+ bool uniformRowHeights() const;
+ void setUniformRowHeights(bool uniform);
+
+ bool itemsExpandable() const;
+ void setItemsExpandable(bool enable);
+
+ bool expandsOnDoubleClick() const;
+ void setExpandsOnDoubleClick(bool enable);
+
+ int columnViewportPosition(int column) const;
+ int columnWidth(int column) const;
+ void setColumnWidth(int column, int width);
+ int columnAt(int x) const;
+
+ bool isColumnHidden(int column) const;
+ void setColumnHidden(int column, bool hide);
+
+ bool isHeaderHidden() const;
+ void setHeaderHidden(bool hide);
+
+ bool isRowHidden(int row, const QModelIndex &parent) const;
+ void setRowHidden(int row, const QModelIndex &parent, bool hide);
+
+ bool isFirstColumnSpanned(int row, const QModelIndex &parent) const;
+ void setFirstColumnSpanned(int row, const QModelIndex &parent, bool span);
+
+ bool isExpanded(const QModelIndex &index) const;
+ void setExpanded(const QModelIndex &index, bool expand);
+
+ void setSortingEnabled(bool enable);
+ bool isSortingEnabled() const;
+
+ void setAnimated(bool enable);
+ bool isAnimated() const;
+
+ void setAllColumnsShowFocus(bool enable);
+ bool allColumnsShowFocus() const;
+
+ void setWordWrap(bool on);
+ bool wordWrap() const;
+
+ void keyboardSearch(const QString &search);
+
+ QRect visualRect(const QModelIndex &index) const;
+ void scrollTo(const QModelIndex &index, ScrollHint hint = EnsureVisible);
+ QModelIndex indexAt(const QPoint &p) const;
+ QModelIndex indexAbove(const QModelIndex &index) const;
+ QModelIndex indexBelow(const QModelIndex &index) const;
+
+ void doItemsLayout();
+ void reset();
+
+ void sortByColumn(int column, Qt::SortOrder order);
+
+ void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
+ void selectAll();
+
+Q_SIGNALS:
+ void expanded(const QModelIndex &index);
+ void collapsed(const QModelIndex &index);
+
+public Q_SLOTS:
+ void hideColumn(int column);
+ void showColumn(int column);
+ void expand(const QModelIndex &index);
+ void collapse(const QModelIndex &index);
+ void resizeColumnToContents(int column);
+ void sortByColumn(int column);
+ void expandAll();
+ void collapseAll();
+ void expandToDepth(int depth);
+
+protected Q_SLOTS:
+ void columnResized(int column, int oldSize, int newSize);
+ void columnCountChanged(int oldCount, int newCount);
+ void columnMoved();
+ void reexpand();
+ void rowsRemoved(const QModelIndex &parent, int first, int last);
+
+protected:
+ QTreeView(QTreeViewPrivate &dd, QWidget *parent = 0);
+ void scrollContentsBy(int dx, int dy);
+ void rowsInserted(const QModelIndex &parent, int start, int end);
+ void rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end);
+
+ QModelIndex moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers);
+ int horizontalOffset() const;
+ int verticalOffset() const;
+
+ void setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags command);
+ QRegion visualRegionForSelection(const QItemSelection &selection) const;
+ QModelIndexList selectedIndexes() const;
+
+ void timerEvent(QTimerEvent *event);
+ void paintEvent(QPaintEvent *event);
+
+ void drawTree(QPainter *painter, const QRegion &region) const;
+ virtual void drawRow(QPainter *painter,
+ const QStyleOptionViewItem &options,
+ const QModelIndex &index) const;
+ virtual void drawBranches(QPainter *painter,
+ const QRect &rect,
+ const QModelIndex &index) const;
+
+ void mousePressEvent(QMouseEvent *event);
+ void mouseReleaseEvent(QMouseEvent *event);
+ void mouseDoubleClickEvent(QMouseEvent *event);
+ void mouseMoveEvent(QMouseEvent *event);
+ void keyPressEvent(QKeyEvent *event);
+#ifndef QT_NO_DRAGANDDROP
+ void dragMoveEvent(QDragMoveEvent *event);
+#endif
+ bool viewportEvent(QEvent *event);
+
+ void updateGeometries();
+
+ int sizeHintForColumn(int column) const;
+ int indexRowSizeHint(const QModelIndex &index) const;
+ int rowHeight(const QModelIndex &index) const;
+
+ void horizontalScrollbarAction(int action);
+
+ bool isIndexHidden(const QModelIndex &index) const;
+ void selectionChanged(const QItemSelection &selected,
+ const QItemSelection &deselected);
+ void currentChanged(const QModelIndex &current, const QModelIndex &previous);
+
+private:
+ friend class QAccessibleItemView;
+ friend class QAccessibleTable2;
+ friend class QAccessibleTree;
+ friend class QAccessibleTable2Cell;
+ int visualIndex(const QModelIndex &index) const;
+
+ Q_DECLARE_PRIVATE(QTreeView)
+ Q_DISABLE_COPY(QTreeView)
+#ifndef QT_NO_ANIMATION
+ Q_PRIVATE_SLOT(d_func(), void _q_endAnimatedOperation())
+#endif //QT_NO_ANIMATION
+ Q_PRIVATE_SLOT(d_func(), void _q_modelAboutToBeReset())
+ Q_PRIVATE_SLOT(d_func(), void _q_sortIndicatorChanged(int column, Qt::SortOrder order))
+};
+
+#endif // QT_NO_TREEVIEW
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QTREEVIEW_H
diff --git a/src/widgets/itemviews/qtreeview_p.h b/src/widgets/itemviews/qtreeview_p.h
new file mode 100644
index 0000000000..5a90b15389
--- /dev/null
+++ b/src/widgets/itemviews/qtreeview_p.h
@@ -0,0 +1,255 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTREEVIEW_P_H
+#define QTREEVIEW_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "private/qabstractitemview_p.h"
+#include <QtCore/qvariantanimation.h>
+#include <QtCore/qabstractitemmodel.h>
+
+#ifndef QT_NO_TREEVIEW
+
+QT_BEGIN_NAMESPACE
+
+struct QTreeViewItem
+{
+ QTreeViewItem() : parentItem(-1), expanded(false), spanning(false), hasChildren(false),
+ hasMoreSiblings(false), total(0), level(0), height(0) {}
+ QModelIndex index; // we remove items whenever the indexes are invalidated
+ int parentItem; // parent item index in viewItems
+ uint expanded : 1;
+ uint spanning : 1;
+ uint hasChildren : 1; // if the item has visible children (even if collapsed)
+ uint hasMoreSiblings : 1;
+ uint total : 28; // total number of children visible
+ uint level : 16; // indentation
+ int height : 16; // row height
+};
+
+Q_DECLARE_TYPEINFO(QTreeViewItem, Q_MOVABLE_TYPE);
+
+class Q_WIDGETS_EXPORT QTreeViewPrivate : public QAbstractItemViewPrivate
+{
+ Q_DECLARE_PUBLIC(QTreeView)
+public:
+
+ QTreeViewPrivate()
+ : QAbstractItemViewPrivate(),
+ header(0), indent(20), lastViewedItem(0), defaultItemHeight(-1),
+ uniformRowHeights(false), rootDecoration(true),
+ itemsExpandable(true), sortingEnabled(false),
+ expandsOnDoubleClick(true),
+ allColumnsShowFocus(false), current(0), spanning(false),
+ animationsEnabled(false), columnResizeTimerID(0),
+ autoExpandDelay(-1), hoverBranch(-1), geometryRecursionBlock(false), hasRemovedItems(false) {}
+
+ ~QTreeViewPrivate() {}
+ void initialize();
+
+ QItemViewPaintPairs draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const;
+
+#ifndef QT_NO_ANIMATION
+ struct AnimatedOperation : public QVariantAnimation
+ {
+ int item;
+ QPixmap before;
+ QPixmap after;
+ QWidget *viewport;
+ AnimatedOperation() : item(0) { setEasingCurve(QEasingCurve::InOutQuad); }
+ int top() const { return startValue().toInt(); }
+ QRect rect() const { QRect rect = viewport->rect(); rect.moveTop(top()); return rect; }
+ void updateCurrentValue(const QVariant &) { viewport->update(rect()); }
+ void updateState(State state, State) { if (state == Stopped) before = after = QPixmap(); }
+ } animatedOperation;
+ void prepareAnimatedOperation(int item, QVariantAnimation::Direction d);
+ void beginAnimatedOperation();
+ void drawAnimatedOperation(QPainter *painter) const;
+ QPixmap renderTreeToPixmapForAnimation(const QRect &rect) const;
+ void _q_endAnimatedOperation();
+#endif //QT_NO_ANIMATION
+
+ void expand(int item, bool emitSignal);
+ void collapse(int item, bool emitSignal);
+
+ void _q_columnsAboutToBeRemoved(const QModelIndex &, int, int);
+ void _q_columnsRemoved(const QModelIndex &, int, int);
+ void _q_modelAboutToBeReset();
+ void _q_sortIndicatorChanged(int column, Qt::SortOrder order);
+ void _q_modelDestroyed();
+
+ void layout(int item, bool recusiveExpanding = false, bool afterIsUninitialized = false);
+
+ int pageUp(int item) const;
+ int pageDown(int item) const;
+
+ int itemHeight(int item) const;
+ int indentationForItem(int item) const;
+ int coordinateForItem(int item) const;
+ int itemAtCoordinate(int coordinate) const;
+
+ int viewIndex(const QModelIndex &index) const;
+ QModelIndex modelIndex(int i, int column = 0) const;
+
+ void insertViewItems(int pos, int count, const QTreeViewItem &viewItem);
+ void removeViewItems(int pos, int count);
+#if 0
+ bool checkViewItems() const;
+#endif
+
+ int firstVisibleItem(int *offset = 0) const;
+ int columnAt(int x) const;
+ bool hasVisibleChildren( const QModelIndex& parent) const;
+
+ bool expandOrCollapseItemAtPos(const QPoint &pos);
+
+ void updateScrollBars();
+
+ int itemDecorationAt(const QPoint &pos) const;
+ QRect itemDecorationRect(const QModelIndex &index) const;
+
+
+ QList<QPair<int, int> > columnRanges(const QModelIndex &topIndex, const QModelIndex &bottomIndex) const;
+ void select(const QModelIndex &start, const QModelIndex &stop, QItemSelectionModel::SelectionFlags command);
+
+ QPair<int,int> startAndEndColumns(const QRect &rect) const;
+
+ void updateChildCount(const int parentItem, const int delta);
+
+ void paintAlternatingRowColors(QPainter *painter, QStyleOptionViewItemV4 *option, int y, int bottom) const;
+
+ QHeaderView *header;
+ int indent;
+
+ mutable QVector<QTreeViewItem> viewItems;
+ mutable int lastViewedItem;
+ int defaultItemHeight; // this is just a number; contentsHeight() / numItems
+ bool uniformRowHeights; // used when all rows have the same height
+ bool rootDecoration;
+ bool itemsExpandable;
+ bool sortingEnabled;
+ bool expandsOnDoubleClick;
+ bool allColumnsShowFocus;
+
+ // used for drawing
+ mutable QPair<int,int> leftAndRight;
+ mutable int current;
+ mutable bool spanning;
+
+ // used when expanding and collapsing items
+ QSet<QPersistentModelIndex> expandedIndexes;
+ bool animationsEnabled;
+
+ inline bool storeExpanded(const QPersistentModelIndex &idx) {
+ if (expandedIndexes.contains(idx))
+ return false;
+ expandedIndexes.insert(idx);
+ return true;
+ }
+
+ inline bool isIndexExpanded(const QModelIndex &idx) const {
+ //We first check if the idx is a QPersistentModelIndex, because creating QPersistentModelIndex is slow
+ return isPersistent(idx) && expandedIndexes.contains(idx);
+ }
+
+ // used when hiding and showing items
+ QSet<QPersistentModelIndex> hiddenIndexes;
+
+ inline bool isRowHidden(const QModelIndex &idx) const {
+ //We first check if the idx is a QPersistentModelIndex, because creating QPersistentModelIndex is slow
+ return isPersistent(idx) && hiddenIndexes.contains(idx);
+ }
+
+ inline bool isItemHiddenOrDisabled(int i) const {
+ if (i < 0 || i >= viewItems.count())
+ return false;
+ const QModelIndex index = viewItems.at(i).index;
+ return isRowHidden(index) || !isIndexEnabled(index);
+ }
+
+ inline int above(int item) const
+ { int i = item; while (isItemHiddenOrDisabled(--item)){} return item < 0 ? i : item; }
+ inline int below(int item) const
+ { int i = item; while (isItemHiddenOrDisabled(++item)){} return item >= viewItems.count() ? i : item; }
+ inline void invalidateHeightCache(int item) const
+ { viewItems[item].height = 0; }
+
+ inline int accessibleTable2Index(const QModelIndex &index) const {
+ return (viewIndex(index) + (header ? 1 : 0)) * model->columnCount()+index.column() + 1;
+ }
+
+ // used for spanning rows
+ QVector<QPersistentModelIndex> spanningIndexes;
+
+ // used for updating resized columns
+ int columnResizeTimerID;
+ QList<int> columnsToUpdate;
+
+ // used for the automatic opening of nodes during DND
+ int autoExpandDelay;
+ QBasicTimer openTimer;
+
+ // used for drawing hilighted expand/collapse indicators
+ int hoverBranch;
+
+ // used for blocking recursion when calling setViewportMargins from updateGeometries
+ bool geometryRecursionBlock;
+
+ // If we should clean the set
+ bool hasRemovedItems;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_TREEVIEW
+
+#endif // QTREEVIEW_P_H
diff --git a/src/gui/itemviews/qtreewidget.cpp b/src/widgets/itemviews/qtreewidget.cpp
index 5571732254..5571732254 100644
--- a/src/gui/itemviews/qtreewidget.cpp
+++ b/src/widgets/itemviews/qtreewidget.cpp
diff --git a/src/widgets/itemviews/qtreewidget.h b/src/widgets/itemviews/qtreewidget.h
new file mode 100644
index 0000000000..ec4b0d8585
--- /dev/null
+++ b/src/widgets/itemviews/qtreewidget.h
@@ -0,0 +1,432 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTREEWIDGET_H
+#define QTREEWIDGET_H
+
+#include <QtWidgets/qtreeview.h>
+#include <QtWidgets/qtreewidgetitemiterator.h>
+#include <QtCore/qvariant.h>
+#include <QtCore/qvector.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_TREEWIDGET
+
+class QTreeWidget;
+class QTreeModel;
+class QWidgetItemData;
+class QTreeWidgetItemPrivate;
+
+class Q_WIDGETS_EXPORT QTreeWidgetItem
+{
+ friend class QTreeModel;
+ friend class QTreeWidget;
+ friend class QTreeWidgetPrivate;
+ friend class QTreeWidgetItemIterator;
+ friend class QTreeWidgetItemPrivate;
+public:
+ enum ItemType { Type = 0, UserType = 1000 };
+ explicit QTreeWidgetItem(int type = Type);
+ QTreeWidgetItem(const QStringList &strings, int type = Type);
+ explicit QTreeWidgetItem(QTreeWidget *view, int type = Type);
+ QTreeWidgetItem(QTreeWidget *view, const QStringList &strings, int type = Type);
+ QTreeWidgetItem(QTreeWidget *view, QTreeWidgetItem *after, int type = Type);
+ explicit QTreeWidgetItem(QTreeWidgetItem *parent, int type = Type);
+ QTreeWidgetItem(QTreeWidgetItem *parent, const QStringList &strings, int type = Type);
+ QTreeWidgetItem(QTreeWidgetItem *parent, QTreeWidgetItem *after, int type = Type);
+ QTreeWidgetItem(const QTreeWidgetItem &other);
+ virtual ~QTreeWidgetItem();
+
+ virtual QTreeWidgetItem *clone() const;
+
+ inline QTreeWidget *treeWidget() const { return view; }
+
+ inline void setSelected(bool select);
+ inline bool isSelected() const;
+
+ inline void setHidden(bool hide);
+ inline bool isHidden() const;
+
+ inline void setExpanded(bool expand);
+ inline bool isExpanded() const;
+
+ inline void setFirstColumnSpanned(bool span);
+ inline bool isFirstColumnSpanned() const;
+
+ inline void setDisabled(bool disabled);
+ inline bool isDisabled() const;
+
+ enum ChildIndicatorPolicy { ShowIndicator, DontShowIndicator, DontShowIndicatorWhenChildless };
+ void setChildIndicatorPolicy(QTreeWidgetItem::ChildIndicatorPolicy policy);
+ QTreeWidgetItem::ChildIndicatorPolicy childIndicatorPolicy() const;
+
+ Qt::ItemFlags flags() const;
+ void setFlags(Qt::ItemFlags flags);
+
+ inline QString text(int column) const
+ { return data(column, Qt::DisplayRole).toString(); }
+ inline void setText(int column, const QString &text);
+
+ inline QIcon icon(int column) const
+ { return qvariant_cast<QIcon>(data(column, Qt::DecorationRole)); }
+ inline void setIcon(int column, const QIcon &icon);
+
+ inline QString statusTip(int column) const
+ { return data(column, Qt::StatusTipRole).toString(); }
+ inline void setStatusTip(int column, const QString &statusTip);
+
+#ifndef QT_NO_TOOLTIP
+ inline QString toolTip(int column) const
+ { return data(column, Qt::ToolTipRole).toString(); }
+ inline void setToolTip(int column, const QString &toolTip);
+#endif
+
+#ifndef QT_NO_WHATSTHIS
+ inline QString whatsThis(int column) const
+ { return data(column, Qt::WhatsThisRole).toString(); }
+ inline void setWhatsThis(int column, const QString &whatsThis);
+#endif
+
+ inline QFont font(int column) const
+ { return qvariant_cast<QFont>(data(column, Qt::FontRole)); }
+ inline void setFont(int column, const QFont &font);
+
+ inline int textAlignment(int column) const
+ { return data(column, Qt::TextAlignmentRole).toInt(); }
+ inline void setTextAlignment(int column, int alignment)
+ { setData(column, Qt::TextAlignmentRole, alignment); }
+
+ inline QColor backgroundColor(int column) const
+ { return qvariant_cast<QColor>(data(column, Qt::BackgroundColorRole)); }
+ inline void setBackgroundColor(int column, const QColor &color)
+ { setData(column, Qt::BackgroundColorRole, color); }
+
+ inline QBrush background(int column) const
+ { return qvariant_cast<QBrush>(data(column, Qt::BackgroundRole)); }
+ inline void setBackground(int column, const QBrush &brush)
+ { setData(column, Qt::BackgroundRole, brush); }
+
+ inline QColor textColor(int column) const
+ { return qvariant_cast<QColor>(data(column, Qt::TextColorRole)); }
+ inline void setTextColor(int column, const QColor &color)
+ { setData(column, Qt::TextColorRole, color); }
+
+ inline QBrush foreground(int column) const
+ { return qvariant_cast<QBrush>(data(column, Qt::ForegroundRole)); }
+ inline void setForeground(int column, const QBrush &brush)
+ { setData(column, Qt::ForegroundRole, brush); }
+
+ inline Qt::CheckState checkState(int column) const
+ { return static_cast<Qt::CheckState>(data(column, Qt::CheckStateRole).toInt()); }
+ inline void setCheckState(int column, Qt::CheckState state)
+ { setData(column, Qt::CheckStateRole, state); }
+
+ inline QSize sizeHint(int column) const
+ { return qvariant_cast<QSize>(data(column, Qt::SizeHintRole)); }
+ inline void setSizeHint(int column, const QSize &size)
+ { setData(column, Qt::SizeHintRole, size); }
+
+ virtual QVariant data(int column, int role) const;
+ virtual void setData(int column, int role, const QVariant &value);
+
+ virtual bool operator<(const QTreeWidgetItem &other) const;
+
+#ifndef QT_NO_DATASTREAM
+ virtual void read(QDataStream &in);
+ virtual void write(QDataStream &out) const;
+#endif
+ QTreeWidgetItem &operator=(const QTreeWidgetItem &other);
+
+ inline QTreeWidgetItem *parent() const { return par; }
+ inline QTreeWidgetItem *child(int index) const {
+ if (index < 0 || index >= children.size())
+ return 0;
+ executePendingSort();
+ return children.at(index);
+ }
+ inline int childCount() const { return children.count(); }
+ inline int columnCount() const { return values.count(); }
+ inline int indexOfChild(QTreeWidgetItem *child) const;
+
+ void addChild(QTreeWidgetItem *child);
+ void insertChild(int index, QTreeWidgetItem *child);
+ void removeChild(QTreeWidgetItem *child);
+ QTreeWidgetItem *takeChild(int index);
+
+ void addChildren(const QList<QTreeWidgetItem*> &children);
+ void insertChildren(int index, const QList<QTreeWidgetItem*> &children);
+ QList<QTreeWidgetItem*> takeChildren();
+
+ inline int type() const { return rtti; }
+ inline void sortChildren(int column, Qt::SortOrder order)
+ { sortChildren(column, order, false); }
+
+protected:
+ void emitDataChanged();
+
+private:
+ void sortChildren(int column, Qt::SortOrder order, bool climb);
+ QVariant childrenCheckState(int column) const;
+ void itemChanged();
+ void executePendingSort() const;
+
+ int rtti;
+ // One item has a vector of column entries. Each column has a vector of (role, value) pairs.
+ QVector< QVector<QWidgetItemData> > values;
+ QTreeWidget *view;
+ QTreeWidgetItemPrivate *d;
+ QTreeWidgetItem *par;
+ QList<QTreeWidgetItem*> children;
+ Qt::ItemFlags itemFlags;
+};
+
+inline void QTreeWidgetItem::setText(int column, const QString &atext)
+{ setData(column, Qt::DisplayRole, atext); }
+
+inline void QTreeWidgetItem::setIcon(int column, const QIcon &aicon)
+{ setData(column, Qt::DecorationRole, aicon); }
+
+#ifndef QT_NO_STATUSTIP
+inline void QTreeWidgetItem::setStatusTip(int column, const QString &astatusTip)
+{ setData(column, Qt::StatusTipRole, astatusTip); }
+#endif
+
+#ifndef QT_NO_TOOLTIP
+inline void QTreeWidgetItem::setToolTip(int column, const QString &atoolTip)
+{ setData(column, Qt::ToolTipRole, atoolTip); }
+#endif
+
+#ifndef QT_NO_WHATSTHIS
+inline void QTreeWidgetItem::setWhatsThis(int column, const QString &awhatsThis)
+{ setData(column, Qt::WhatsThisRole, awhatsThis); }
+#endif
+
+inline void QTreeWidgetItem::setFont(int column, const QFont &afont)
+{ setData(column, Qt::FontRole, afont); }
+
+inline int QTreeWidgetItem::indexOfChild(QTreeWidgetItem *achild) const
+{ executePendingSort(); return children.indexOf(achild); }
+
+#ifndef QT_NO_DATASTREAM
+Q_WIDGETS_EXPORT QDataStream &operator<<(QDataStream &out, const QTreeWidgetItem &item);
+Q_WIDGETS_EXPORT QDataStream &operator>>(QDataStream &in, QTreeWidgetItem &item);
+#endif
+
+class QTreeWidgetPrivate;
+
+class Q_WIDGETS_EXPORT QTreeWidget : public QTreeView
+{
+ Q_OBJECT
+ Q_PROPERTY(int columnCount READ columnCount WRITE setColumnCount)
+ Q_PROPERTY(int topLevelItemCount READ topLevelItemCount)
+
+ friend class QTreeModel;
+ friend class QTreeWidgetItem;
+public:
+ explicit QTreeWidget(QWidget *parent = 0);
+ ~QTreeWidget();
+
+ int columnCount() const;
+ void setColumnCount(int columns);
+
+ QTreeWidgetItem *invisibleRootItem() const;
+ QTreeWidgetItem *topLevelItem(int index) const;
+ int topLevelItemCount() const;
+ void insertTopLevelItem(int index, QTreeWidgetItem *item);
+ void addTopLevelItem(QTreeWidgetItem *item);
+ QTreeWidgetItem *takeTopLevelItem(int index);
+ int indexOfTopLevelItem(QTreeWidgetItem *item); // ### Qt 5: remove me
+ int indexOfTopLevelItem(QTreeWidgetItem *item) const;
+
+ void insertTopLevelItems(int index, const QList<QTreeWidgetItem*> &items);
+ void addTopLevelItems(const QList<QTreeWidgetItem*> &items);
+
+ QTreeWidgetItem *headerItem() const;
+ void setHeaderItem(QTreeWidgetItem *item);
+ void setHeaderLabels(const QStringList &labels);
+ inline void setHeaderLabel(const QString &label);
+
+ QTreeWidgetItem *currentItem() const;
+ int currentColumn() const;
+ void setCurrentItem(QTreeWidgetItem *item);
+ void setCurrentItem(QTreeWidgetItem *item, int column);
+ void setCurrentItem(QTreeWidgetItem *item, int column, QItemSelectionModel::SelectionFlags command);
+
+ QTreeWidgetItem *itemAt(const QPoint &p) const;
+ inline QTreeWidgetItem *itemAt(int x, int y) const;
+ QRect visualItemRect(const QTreeWidgetItem *item) const;
+
+ int sortColumn() const;
+ void sortItems(int column, Qt::SortOrder order);
+ void setSortingEnabled(bool enable);
+ bool isSortingEnabled() const;
+
+ void editItem(QTreeWidgetItem *item, int column = 0);
+ void openPersistentEditor(QTreeWidgetItem *item, int column = 0);
+ void closePersistentEditor(QTreeWidgetItem *item, int column = 0);
+
+ QWidget *itemWidget(QTreeWidgetItem *item, int column) const;
+ void setItemWidget(QTreeWidgetItem *item, int column, QWidget *widget);
+ inline void removeItemWidget(QTreeWidgetItem *item, int column);
+
+ bool isItemSelected(const QTreeWidgetItem *item) const;
+ void setItemSelected(const QTreeWidgetItem *item, bool select);
+ QList<QTreeWidgetItem*> selectedItems() const;
+ QList<QTreeWidgetItem*> findItems(const QString &text, Qt::MatchFlags flags,
+ int column = 0) const;
+
+ bool isItemHidden(const QTreeWidgetItem *item) const;
+ void setItemHidden(const QTreeWidgetItem *item, bool hide);
+
+ bool isItemExpanded(const QTreeWidgetItem *item) const;
+ void setItemExpanded(const QTreeWidgetItem *item, bool expand);
+
+ bool isFirstItemColumnSpanned(const QTreeWidgetItem *item) const;
+ void setFirstItemColumnSpanned(const QTreeWidgetItem *item, bool span);
+
+ QTreeWidgetItem *itemAbove(const QTreeWidgetItem *item) const;
+ QTreeWidgetItem *itemBelow(const QTreeWidgetItem *item) const;
+
+ void setSelectionModel(QItemSelectionModel *selectionModel);
+
+public Q_SLOTS:
+ void scrollToItem(const QTreeWidgetItem *item,
+ QAbstractItemView::ScrollHint hint = EnsureVisible);
+ void expandItem(const QTreeWidgetItem *item);
+ void collapseItem(const QTreeWidgetItem *item);
+ void clear();
+
+Q_SIGNALS:
+ void itemPressed(QTreeWidgetItem *item, int column);
+ void itemClicked(QTreeWidgetItem *item, int column);
+ void itemDoubleClicked(QTreeWidgetItem *item, int column);
+ void itemActivated(QTreeWidgetItem *item, int column);
+ void itemEntered(QTreeWidgetItem *item, int column);
+ void itemChanged(QTreeWidgetItem *item, int column);
+ void itemExpanded(QTreeWidgetItem *item);
+ void itemCollapsed(QTreeWidgetItem *item);
+ void currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous);
+ void itemSelectionChanged();
+
+protected:
+ bool event(QEvent *e);
+ virtual QStringList mimeTypes() const;
+ virtual QMimeData *mimeData(const QList<QTreeWidgetItem*> items) const;
+ virtual bool dropMimeData(QTreeWidgetItem *parent, int index,
+ const QMimeData *data, Qt::DropAction action);
+ virtual Qt::DropActions supportedDropActions() const;
+ QList<QTreeWidgetItem*> items(const QMimeData *data) const;
+
+ QModelIndex indexFromItem(QTreeWidgetItem *item, int column = 0) const;
+ QTreeWidgetItem *itemFromIndex(const QModelIndex &index) const;
+ void dropEvent(QDropEvent *event);
+
+private:
+ void setModel(QAbstractItemModel *model);
+
+ Q_DECLARE_PRIVATE(QTreeWidget)
+ Q_DISABLE_COPY(QTreeWidget)
+
+ Q_PRIVATE_SLOT(d_func(), void _q_emitItemPressed(const QModelIndex &index))
+ Q_PRIVATE_SLOT(d_func(), void _q_emitItemClicked(const QModelIndex &index))
+ Q_PRIVATE_SLOT(d_func(), void _q_emitItemDoubleClicked(const QModelIndex &index))
+ Q_PRIVATE_SLOT(d_func(), void _q_emitItemActivated(const QModelIndex &index))
+ Q_PRIVATE_SLOT(d_func(), void _q_emitItemEntered(const QModelIndex &index))
+ Q_PRIVATE_SLOT(d_func(), void _q_emitItemChanged(const QModelIndex &index))
+ Q_PRIVATE_SLOT(d_func(), void _q_emitItemExpanded(const QModelIndex &index))
+ Q_PRIVATE_SLOT(d_func(), void _q_emitItemCollapsed(const QModelIndex &index))
+ Q_PRIVATE_SLOT(d_func(), void _q_emitCurrentItemChanged(const QModelIndex &previous, const QModelIndex &current))
+ Q_PRIVATE_SLOT(d_func(), void _q_sort())
+ Q_PRIVATE_SLOT(d_func(), void _q_dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight))
+ Q_PRIVATE_SLOT(d_func(), void _q_selectionChanged(const QItemSelection &selected, const QItemSelection &deselected))
+};
+
+inline void QTreeWidget::removeItemWidget(QTreeWidgetItem *item, int column)
+{ setItemWidget(item, column, 0); }
+
+inline QTreeWidgetItem *QTreeWidget::itemAt(int ax, int ay) const
+{ return itemAt(QPoint(ax, ay)); }
+
+inline void QTreeWidget::setHeaderLabel(const QString &alabel)
+{ setHeaderLabels(QStringList(alabel)); }
+
+inline void QTreeWidgetItem::setSelected(bool aselect)
+{ if (view) view->setItemSelected(this, aselect); }
+
+inline bool QTreeWidgetItem::isSelected() const
+{ return (view ? view->isItemSelected(this) : false); }
+
+inline void QTreeWidgetItem::setHidden(bool ahide)
+{ if (view) view->setItemHidden(this, ahide); }
+
+inline bool QTreeWidgetItem::isHidden() const
+{ return (view ? view->isItemHidden(this) : false); }
+
+inline void QTreeWidgetItem::setExpanded(bool aexpand)
+{ if (view) view->setItemExpanded(this, aexpand); }
+
+inline bool QTreeWidgetItem::isExpanded() const
+{ return (view ? view->isItemExpanded(this) : false); }
+
+inline void QTreeWidgetItem::setFirstColumnSpanned(bool aspan)
+{ if (view) view->setFirstItemColumnSpanned(this, aspan); }
+
+inline bool QTreeWidgetItem::isFirstColumnSpanned() const
+{ return (view ? view->isFirstItemColumnSpanned(this) : false); }
+
+inline void QTreeWidgetItem::setDisabled(bool disabled)
+{ setFlags(disabled ? (flags() & ~Qt::ItemIsEnabled) : flags() | Qt::ItemIsEnabled); }
+
+inline bool QTreeWidgetItem::isDisabled() const
+{ return !(flags() & Qt::ItemIsEnabled); }
+
+#endif // QT_NO_TREEWIDGET
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QTREEWIDGET_H
diff --git a/src/widgets/itemviews/qtreewidget_p.h b/src/widgets/itemviews/qtreewidget_p.h
new file mode 100644
index 0000000000..1ead6837c1
--- /dev/null
+++ b/src/widgets/itemviews/qtreewidget_p.h
@@ -0,0 +1,248 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTREEWIDGET_P_H
+#define QTREEWIDGET_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. This header file may change
+// from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qabstractitemmodel.h>
+#include <private/qabstractitemmodel_p.h>
+#include <QtCore/qpair.h>
+#include <QtCore/qbasictimer.h>
+#include <QtWidgets/qtreewidget.h>
+#include <private/qtreeview_p.h>
+#include <QtWidgets/qheaderview.h>
+
+#ifndef QT_NO_TREEWIDGET
+
+QT_BEGIN_NAMESPACE
+
+class QTreeWidgetItem;
+class QTreeWidgetItemIterator;
+class QTreeModelPrivate;
+
+class QTreeModel : public QAbstractItemModel
+{
+ Q_OBJECT
+ friend class QTreeWidget;
+ friend class QTreeWidgetPrivate;
+ friend class QTreeWidgetItem;
+ friend class QTreeWidgetItemPrivate;
+ friend class QTreeWidgetItemIterator;
+ friend class QTreeWidgetItemIteratorPrivate;
+
+public:
+ explicit QTreeModel(int columns = 0, QTreeWidget *parent = 0);
+ ~QTreeModel();
+
+ inline QTreeWidget *view() const
+ { return qobject_cast<QTreeWidget*>(QObject::parent()); }
+
+ void clear();
+ void setColumnCount(int columns);
+
+ QTreeWidgetItem *item(const QModelIndex &index) const;
+ void itemChanged(QTreeWidgetItem *item);
+
+ QModelIndex index(const QTreeWidgetItem *item, int column) const;
+ QModelIndex index(int row, int column, const QModelIndex &parent) const;
+ QModelIndex parent(const QModelIndex &child) const;
+ int rowCount(const QModelIndex &parent) const;
+ int columnCount(const QModelIndex &parent = QModelIndex()) const;
+ bool hasChildren(const QModelIndex &parent) const;
+
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+ bool setData(const QModelIndex &index, const QVariant &value, int role);
+
+ QMap<int, QVariant> itemData(const QModelIndex &index) const;
+
+ QVariant headerData(int section, Qt::Orientation orientation, int role) const;
+ bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value,
+ int role);
+
+ Qt::ItemFlags flags(const QModelIndex &index) const;
+
+ void sort(int column, Qt::SortOrder order);
+ void ensureSorted(int column, Qt::SortOrder order,
+ int start, int end, const QModelIndex &parent);
+ static bool itemLessThan(const QPair<QTreeWidgetItem*,int> &left,
+ const QPair<QTreeWidgetItem*,int> &right);
+ static bool itemGreaterThan(const QPair<QTreeWidgetItem*,int> &left,
+ const QPair<QTreeWidgetItem*,int> &right);
+ static QList<QTreeWidgetItem*>::iterator sortedInsertionIterator(
+ const QList<QTreeWidgetItem*>::iterator &begin,
+ const QList<QTreeWidgetItem*>::iterator &end,
+ Qt::SortOrder order, QTreeWidgetItem *item);
+
+ bool insertRows(int row, int count, const QModelIndex &);
+ bool insertColumns(int column, int count, const QModelIndex &);
+
+ bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex());
+
+ // dnd
+ QStringList mimeTypes() const;
+ QMimeData *mimeData(const QModelIndexList &indexes) const;
+ bool dropMimeData(const QMimeData *data, Qt::DropAction action,
+ int row, int column, const QModelIndex &parent);
+ Qt::DropActions supportedDropActions() const;
+
+ QMimeData *internalMimeData() const;
+
+ inline QModelIndex createIndexFromItem(int row, int col, QTreeWidgetItem *item) const
+ { return createIndex(row, col, item); }
+
+protected:
+ QTreeModel(QTreeModelPrivate &, QTreeWidget *parent = 0);
+ void emitDataChanged(QTreeWidgetItem *item, int column);
+ void beginInsertItems(QTreeWidgetItem *parent, int row, int count);
+ void endInsertItems();
+ void beginRemoveItems(QTreeWidgetItem *parent, int row, int count);
+ void endRemoveItems();
+ void sortItems(QList<QTreeWidgetItem*> *items, int column, Qt::SortOrder order);
+ void timerEvent(QTimerEvent *);
+
+private:
+ QTreeWidgetItem *rootItem;
+ QTreeWidgetItem *headerItem;
+
+ mutable QModelIndexList cachedIndexes;
+ QList<QTreeWidgetItemIterator*> iterators;
+
+ mutable QBasicTimer sortPendingTimer;
+ mutable bool skipPendingSort; //while doing internal operation we don't care about sorting
+ bool inline executePendingSort() const;
+
+ bool isChanging() const;
+
+private:
+ Q_DECLARE_PRIVATE(QTreeModel)
+public:
+ struct SkipSorting
+ {
+ const QTreeModel * const model;
+ const bool previous;
+ SkipSorting(const QTreeModel *m) : model(m), previous(model->skipPendingSort)
+ { model->skipPendingSort = true; }
+ ~SkipSorting() { model->skipPendingSort = previous; }
+ };
+ friend struct SkipSorting;
+};
+
+QT_BEGIN_INCLUDE_NAMESPACE
+#include "private/qabstractitemmodel_p.h"
+QT_END_INCLUDE_NAMESPACE
+
+class QTreeModelPrivate : public QAbstractItemModelPrivate
+{
+ Q_DECLARE_PUBLIC(QTreeModel)
+};
+
+class QTreeWidgetItemPrivate
+{
+public:
+ QTreeWidgetItemPrivate(QTreeWidgetItem *item)
+ : q(item), disabled(false), selected(false), rowGuess(-1), policy(QTreeWidgetItem::DontShowIndicatorWhenChildless) {}
+ void propagateDisabled(QTreeWidgetItem *item);
+ void sortChildren(int column, Qt::SortOrder order, bool climb);
+ QTreeWidgetItem *q;
+ QVariantList display;
+ uint disabled : 1;
+ uint selected : 1;
+ int rowGuess;
+ QTreeWidgetItem::ChildIndicatorPolicy policy;
+};
+
+
+inline bool QTreeModel::executePendingSort() const
+{
+ if (!skipPendingSort && sortPendingTimer.isActive() && !isChanging()) {
+ sortPendingTimer.stop();
+ int column = view()->header()->sortIndicatorSection();
+ Qt::SortOrder order = view()->header()->sortIndicatorOrder();
+ QTreeModel *that = const_cast<QTreeModel*>(this);
+ that->sort(column, order);
+ return true;
+ }
+ return false;
+}
+
+class QTreeWidgetPrivate : public QTreeViewPrivate
+{
+ friend class QTreeModel;
+ Q_DECLARE_PUBLIC(QTreeWidget)
+public:
+ QTreeWidgetPrivate() : QTreeViewPrivate(), explicitSortColumn(-1) {}
+ inline QTreeModel *treeModel() const { return qobject_cast<QTreeModel*>(model); }
+ inline QModelIndex index(const QTreeWidgetItem *item, int column = 0) const
+ { return treeModel()->index(item, column); }
+ inline QTreeWidgetItem *item(const QModelIndex &index) const
+ { return treeModel()->item(index); }
+ void _q_emitItemPressed(const QModelIndex &index);
+ void _q_emitItemClicked(const QModelIndex &index);
+ void _q_emitItemDoubleClicked(const QModelIndex &index);
+ void _q_emitItemActivated(const QModelIndex &index);
+ void _q_emitItemEntered(const QModelIndex &index);
+ void _q_emitItemChanged(const QModelIndex &index);
+ void _q_emitItemExpanded(const QModelIndex &index);
+ void _q_emitItemCollapsed(const QModelIndex &index);
+ void _q_emitCurrentItemChanged(const QModelIndex &previous, const QModelIndex &index);
+ void _q_sort();
+ void _q_dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
+ void _q_selectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
+
+ // used by QTreeWidgetItem::sortChildren to make sure the column argument is used
+ int explicitSortColumn;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_TREEWIDGET
+
+#endif // QTREEWIDGET_P_H
diff --git a/src/gui/itemviews/qtreewidgetitemiterator.cpp b/src/widgets/itemviews/qtreewidgetitemiterator.cpp
index 579c5acdf6..579c5acdf6 100644
--- a/src/gui/itemviews/qtreewidgetitemiterator.cpp
+++ b/src/widgets/itemviews/qtreewidgetitemiterator.cpp
diff --git a/src/widgets/itemviews/qtreewidgetitemiterator.h b/src/widgets/itemviews/qtreewidgetitemiterator.h
new file mode 100644
index 0000000000..8d27afe2c3
--- /dev/null
+++ b/src/widgets/itemviews/qtreewidgetitemiterator.h
@@ -0,0 +1,159 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTREEWIDGETITEMITERATOR_H
+#define QTREEWIDGETITEMITERATOR_H
+
+#include <QtCore/qglobal.h>
+#include <QtCore/qscopedpointer.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_TREEWIDGET
+
+class QTreeWidget;
+class QTreeWidgetItem;
+class QTreeModel;
+
+class QTreeWidgetItemIteratorPrivate;
+class Q_WIDGETS_EXPORT QTreeWidgetItemIterator
+{
+ friend class QTreeModel;
+
+public:
+ enum IteratorFlag {
+ All = 0x00000000,
+ Hidden = 0x00000001,
+ NotHidden = 0x00000002,
+ Selected = 0x00000004,
+ Unselected = 0x00000008,
+ Selectable = 0x00000010,
+ NotSelectable = 0x00000020,
+ DragEnabled = 0x00000040,
+ DragDisabled = 0x00000080,
+ DropEnabled = 0x00000100,
+ DropDisabled = 0x00000200,
+ HasChildren = 0x00000400,
+ NoChildren = 0x00000800,
+ Checked = 0x00001000,
+ NotChecked = 0x00002000,
+ Enabled = 0x00004000,
+ Disabled = 0x00008000,
+ Editable = 0x00010000,
+ NotEditable = 0x00020000,
+ UserFlag = 0x01000000 // The first flag that can be used by the user.
+ };
+ Q_DECLARE_FLAGS(IteratorFlags, IteratorFlag)
+
+ QTreeWidgetItemIterator(const QTreeWidgetItemIterator &it);
+ explicit QTreeWidgetItemIterator(QTreeWidget *widget, IteratorFlags flags = All);
+ explicit QTreeWidgetItemIterator(QTreeWidgetItem *item, IteratorFlags flags = All);
+ ~QTreeWidgetItemIterator();
+
+ QTreeWidgetItemIterator &operator=(const QTreeWidgetItemIterator &it);
+
+ QTreeWidgetItemIterator &operator++();
+ inline const QTreeWidgetItemIterator operator++(int);
+ inline QTreeWidgetItemIterator &operator+=(int n);
+
+ QTreeWidgetItemIterator &operator--();
+ inline const QTreeWidgetItemIterator operator--(int);
+ inline QTreeWidgetItemIterator &operator-=(int n);
+
+ inline QTreeWidgetItem *operator*() const;
+
+private:
+ bool matchesFlags(const QTreeWidgetItem *item) const;
+ QScopedPointer<QTreeWidgetItemIteratorPrivate> d_ptr;
+ QTreeWidgetItem *current;
+ IteratorFlags flags;
+ Q_DECLARE_PRIVATE(QTreeWidgetItemIterator)
+};
+
+inline const QTreeWidgetItemIterator QTreeWidgetItemIterator::operator++(int)
+{
+ QTreeWidgetItemIterator it = *this;
+ ++(*this);
+ return it;
+}
+
+inline const QTreeWidgetItemIterator QTreeWidgetItemIterator::operator--(int)
+{
+ QTreeWidgetItemIterator it = *this;
+ --(*this);
+ return it;
+}
+
+inline QTreeWidgetItemIterator &QTreeWidgetItemIterator::operator+=(int n)
+{
+ if (n < 0)
+ return (*this) -= (-n);
+ while (current && n--)
+ ++(*this);
+ return *this;
+}
+
+inline QTreeWidgetItemIterator &QTreeWidgetItemIterator::operator-=(int n)
+{
+ if (n < 0)
+ return (*this) += (-n);
+ while (current && n--)
+ --(*this);
+ return *this;
+}
+
+inline QTreeWidgetItem *QTreeWidgetItemIterator::operator*() const
+{
+ return current;
+}
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QTreeWidgetItemIterator::IteratorFlags)
+
+
+QT_END_NAMESPACE
+#endif // QT_NO_TREEWIDGET
+QT_END_HEADER
+
+#endif // QTREEWIDGETITEMITERATOR_H
diff --git a/src/gui/itemviews/qtreewidgetitemiterator_p.h b/src/widgets/itemviews/qtreewidgetitemiterator_p.h
index 5ece7fd7b6..5ece7fd7b6 100644
--- a/src/gui/itemviews/qtreewidgetitemiterator_p.h
+++ b/src/widgets/itemviews/qtreewidgetitemiterator_p.h
diff --git a/src/gui/itemviews/qwidgetitemdata_p.h b/src/widgets/itemviews/qwidgetitemdata_p.h
index e7a08de378..e7a08de378 100644
--- a/src/gui/itemviews/qwidgetitemdata_p.h
+++ b/src/widgets/itemviews/qwidgetitemdata_p.h
diff --git a/src/widgets/kernel/kernel.pri b/src/widgets/kernel/kernel.pri
new file mode 100644
index 0000000000..8fbf968581
--- /dev/null
+++ b/src/widgets/kernel/kernel.pri
@@ -0,0 +1,249 @@
+# Qt kernel module
+
+# Only used on platforms with CONFIG += precompile_header
+PRECOMPILED_HEADER = kernel/qt_gui_pch.h
+
+
+KERNEL_P= kernel
+HEADERS += \
+ kernel/qaction.h \
+ kernel/qaction_p.h \
+ kernel/qactiongroup.h \
+ kernel/qapplication.h \
+ kernel/qapplication_p.h \
+ kernel/qwidgetbackingstore_p.h \
+ kernel/qboxlayout.h \
+ kernel/qdesktopwidget.h \
+ kernel/qformlayout.h \
+ kernel/qgridlayout.h \
+ kernel/qicon.h \
+ kernel/qicon_p.h \
+ kernel/qiconloader_p.h \
+ kernel/qiconengine.h \
+ kernel/qiconengineplugin.h \
+ kernel/qinputcontext.h \
+ kernel/qlayout.h \
+ kernel/qlayout_p.h \
+ kernel/qlayoutengine_p.h \
+ kernel/qlayoutitem.h \
+ kernel/qsizepolicy.h \
+ kernel/qstackedlayout.h \
+ kernel/qtooltip.h \
+ kernel/qwhatsthis.h \
+ kernel/qwidget.h \
+ kernel/qwidget_p.h \
+ kernel/qwidgetaction.h \
+ kernel/qwidgetaction_p.h \
+ kernel/qgesture.h \
+ kernel/qgesture_p.h \
+ kernel/qstandardgestures_p.h \
+ kernel/qgesturerecognizer.h \
+ kernel/qgesturemanager_p.h \
+ kernel/qsoftkeymanager_p.h \
+ kernel/qsoftkeymanager_common_p.h \
+ kernel/qguiplatformplugin_p.h
+
+SOURCES += \
+ kernel/qaction.cpp \
+ kernel/qactiongroup.cpp \
+ kernel/qapplication.cpp \
+ kernel/qwidgetbackingstore.cpp \
+ kernel/qboxlayout.cpp \
+ kernel/qformlayout.cpp \
+ kernel/qgridlayout.cpp \
+ kernel/qicon.cpp \
+ kernel/qiconloader.cpp \
+ kernel/qiconengine.cpp \
+ kernel/qiconengineplugin.cpp \
+ kernel/qinputcontext.cpp \
+ kernel/qlayout.cpp \
+ kernel/qlayoutengine.cpp \
+ kernel/qlayoutitem.cpp \
+ kernel/qstackedlayout.cpp \
+ kernel/qtooltip.cpp \
+ kernel/qwhatsthis.cpp \
+ kernel/qwidget.cpp \
+ kernel/qwidgetaction.cpp \
+ kernel/qgesture.cpp \
+ kernel/qstandardgestures.cpp \
+ kernel/qgesturerecognizer.cpp \
+ kernel/qgesturemanager.cpp \
+ kernel/qsoftkeymanager.cpp \
+ kernel/qdesktopwidget.cpp \
+ kernel/qguiplatformplugin.cpp \
+ kernel/qwidgetsvariant.cpp
+
+win32: DEFINES += QT_NO_DIRECTDRAW
+
+win32:!qpa {
+ HEADERS += \
+ kernel/qwinnativepangesturerecognizer_win_p.h
+
+ SOURCES += \
+ kernel/qapplication_win.cpp \
+ kernel/qclipboard_win.cpp \
+ kernel/qcursor_win.cpp \
+ kernel/qdesktopwidget_win.cpp \
+ kernel/qdnd_win.cpp \
+ kernel/qmime_win.cpp \
+ kernel/qsound_win.cpp \
+ kernel/qwidget_win.cpp \
+ kernel/qole_win.cpp \
+ kernel/qkeymapper_win.cpp \
+ kernel/qwinnativepangesturerecognizer_win.cpp
+
+ !contains(DEFINES, QT_NO_DIRECTDRAW):LIBS += ddraw.lib
+}
+
+symbian {
+ exists($${EPOCROOT}epoc32/include/platform/mw/akntranseffect.h): DEFINES += QT_SYMBIAN_HAVE_AKNTRANSEFFECT_H
+
+ SOURCES += \
+ kernel/qapplication_s60.cpp \
+ kernel/qeventdispatcher_s60.cpp \
+ kernel/qwidget_s60.cpp \
+ kernel/qcursor_s60.cpp \
+ kernel/qdesktopwidget_s60.cpp \
+ kernel/qkeymapper_s60.cpp\
+ kernel/qclipboard_s60.cpp\
+ kernel/qdnd_s60.cpp \
+ kernel/qsound_s60.cpp
+
+ HEADERS += \
+ kernel/qt_s60_p.h \
+ kernel/qeventdispatcher_s60_p.h
+
+ LIBS += -lbafl -lestor
+
+ INCLUDEPATH += $$MW_LAYER_SYSTEMINCLUDE
+ INCLUDEPATH += ../3rdparty/s60
+
+ contains(QT_CONFIG, s60) {
+ SOURCES += kernel/qsoftkeymanager_s60.cpp
+ HEADERS += kernel/qsoftkeymanager_s60_p.h
+ }
+}
+
+
+unix:x11 {
+ INCLUDEPATH += ../3rdparty/xorg
+ HEADERS += \
+ kernel/qx11embed_x11.h \
+ kernel/qx11info_x11.h \
+ kernel/qkde_p.h
+
+ SOURCES += \
+ kernel/qapplication_x11.cpp \
+ kernel/qclipboard_x11.cpp \
+ kernel/qcursor_x11.cpp \
+ kernel/qdnd_x11.cpp \
+ kernel/qdesktopwidget_x11.cpp \
+ kernel/qmotifdnd_x11.cpp \
+ kernel/qsound_x11.cpp \
+ kernel/qwidget_x11.cpp \
+ kernel/qwidgetcreate_x11.cpp \
+ kernel/qx11embed_x11.cpp \
+ kernel/qx11info_x11.cpp \
+ kernel/qkeymapper_x11.cpp \
+ kernel/qkde.cpp
+
+ contains(QT_CONFIG, glib) {
+ SOURCES += \
+ kernel/qguieventdispatcher_glib.cpp
+ HEADERS += \
+ kernel/qguieventdispatcher_glib_p.h
+ QMAKE_CXXFLAGS += $$QT_CFLAGS_GLIB
+ LIBS_PRIVATE +=$$QT_LIBS_GLIB
+ }
+ SOURCES += \
+ kernel/qeventdispatcher_x11.cpp
+ HEADERS += \
+ kernel/qeventdispatcher_x11_p.h
+}
+
+!qpa {
+ HEADERS += \
+ kernel/qsound.h \
+ kernel/qsound_p.h
+
+ SOURCES += \
+ kernel/qsound.cpp
+}
+
+qpa {
+ HEADERS += \
+ kernel/qdesktopwidget_qpa_p.h \
+ kernel/qwidgetwindow_qpa_p.h \
+ kernel/qplatformmenu_qpa.h \
+
+ SOURCES += \
+ kernel/qapplication_qpa.cpp \
+ kernel/qdesktopwidget_qpa.cpp \
+ kernel/qwidget_qpa.cpp \
+ kernel/qwidgetwindow_qpa.cpp \
+ kernel/qplatformmenu_qpa.cpp \
+}
+
+!qpa:!x11:mac {
+ SOURCES += \
+ kernel/qclipboard_mac.cpp \
+ kernel/qmime_mac.cpp \
+ kernel/qt_mac.cpp \
+ kernel/qkeymapper_mac.cpp
+
+ OBJECTIVE_HEADERS += \
+ qcocoawindow_mac_p.h \
+ qcocoapanel_mac_p.h \
+ qcocoawindowdelegate_mac_p.h \
+ qcocoaview_mac_p.h \
+ qcocoaapplication_mac_p.h \
+ qcocoaapplicationdelegate_mac_p.h \
+ qmacgesturerecognizer_mac_p.h \
+ qmultitouch_mac_p.h \
+ qcocoasharedwindowmethods_mac_p.h \
+ qcocoaintrospection_p.h
+
+ OBJECTIVE_SOURCES += \
+ kernel/qcursor_mac.mm \
+ kernel/qdnd_mac.mm \
+ kernel/qsound_mac.mm \
+ kernel/qapplication_mac.mm \
+ kernel/qwidget_mac.mm \
+ kernel/qcocoapanel_mac.mm \
+ kernel/qcocoaview_mac.mm \
+ kernel/qcocoawindow_mac.mm \
+ kernel/qcocoawindowdelegate_mac.mm \
+ kernel/qcocoaapplication_mac.mm \
+ kernel/qcocoaapplicationdelegate_mac.mm \
+ kernel/qt_cocoa_helpers_mac.mm \
+ kernel/qdesktopwidget_mac.mm \
+ kernel/qeventdispatcher_mac.mm \
+ kernel/qcocoawindowcustomthemeframe_mac.mm \
+ kernel/qmacgesturerecognizer_mac.mm \
+ kernel/qmultitouch_mac.mm \
+ kernel/qcocoaintrospection_mac.mm
+
+ HEADERS += \
+ kernel/qt_cocoa_helpers_mac_p.h \
+ kernel/qcocoaapplication_mac_p.h \
+ kernel/qcocoaapplicationdelegate_mac_p.h \
+ kernel/qeventdispatcher_mac_p.h
+
+ MENU_NIB.files = mac/qt_menu.nib
+ MENU_NIB.path = Resources
+ MENU_NIB.version = Versions
+ QMAKE_BUNDLE_DATA += MENU_NIB
+ RESOURCES += mac/macresources.qrc
+
+ LIBS_PRIVATE += -framework AppKit
+}
+
+wince*: {
+ HEADERS += \
+ ../corelib/kernel/qfunctions_wince.h \
+ kernel/qguifunctions_wince.h
+
+ SOURCES += \
+ ../corelib/kernel/qfunctions_wince.cpp \
+ kernel/qguifunctions_wince.cpp
+}
diff --git a/src/widgets/kernel/mac.pri b/src/widgets/kernel/mac.pri
new file mode 100644
index 0000000000..5474a41f15
--- /dev/null
+++ b/src/widgets/kernel/mac.pri
@@ -0,0 +1,4 @@
+!x11::mac {
+ LIBS_PRIVATE += -framework Carbon -framework Cocoa -lz
+ *-mwerks:INCLUDEPATH += compat
+}
diff --git a/src/gui/kernel/qaction.cpp b/src/widgets/kernel/qaction.cpp
index 5b73a4ba7e..5b73a4ba7e 100644
--- a/src/gui/kernel/qaction.cpp
+++ b/src/widgets/kernel/qaction.cpp
diff --git a/src/widgets/kernel/qaction.h b/src/widgets/kernel/qaction.h
new file mode 100644
index 0000000000..da8c24e184
--- /dev/null
+++ b/src/widgets/kernel/qaction.h
@@ -0,0 +1,264 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QACTION_H
+#define QACTION_H
+
+#include <QtGui/qkeysequence.h>
+#include <QtCore/qstring.h>
+#include <QtWidgets/qwidget.h>
+#include <QtCore/qvariant.h>
+#include <QtWidgets/qicon.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_ACTION
+
+class QMenu;
+class QActionGroup;
+class QActionPrivate;
+class QGraphicsWidget;
+
+class Q_WIDGETS_EXPORT QAction : public QObject
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QAction)
+
+ Q_ENUMS(MenuRole)
+ Q_ENUMS(SoftKeyRole)
+ Q_ENUMS(Priority)
+ Q_PROPERTY(bool checkable READ isCheckable WRITE setCheckable NOTIFY changed)
+ Q_PROPERTY(bool checked READ isChecked WRITE setChecked DESIGNABLE isCheckable NOTIFY toggled)
+ Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY changed)
+ Q_PROPERTY(QIcon icon READ icon WRITE setIcon NOTIFY changed)
+ Q_PROPERTY(QString text READ text WRITE setText NOTIFY changed)
+ Q_PROPERTY(QString iconText READ iconText WRITE setIconText NOTIFY changed)
+ Q_PROPERTY(QString toolTip READ toolTip WRITE setToolTip NOTIFY changed)
+ Q_PROPERTY(QString statusTip READ statusTip WRITE setStatusTip NOTIFY changed)
+ Q_PROPERTY(QString whatsThis READ whatsThis WRITE setWhatsThis NOTIFY changed)
+ Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY changed)
+#ifndef QT_NO_SHORTCUT
+ Q_PROPERTY(QKeySequence shortcut READ shortcut WRITE setShortcut NOTIFY changed)
+ Q_PROPERTY(Qt::ShortcutContext shortcutContext READ shortcutContext WRITE setShortcutContext NOTIFY changed)
+ Q_PROPERTY(bool autoRepeat READ autoRepeat WRITE setAutoRepeat NOTIFY changed)
+#endif
+ Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY changed)
+ Q_PROPERTY(MenuRole menuRole READ menuRole WRITE setMenuRole NOTIFY changed)
+ Q_PROPERTY(SoftKeyRole softKeyRole READ softKeyRole WRITE setSoftKeyRole NOTIFY changed)
+ Q_PROPERTY(bool iconVisibleInMenu READ isIconVisibleInMenu WRITE setIconVisibleInMenu NOTIFY changed)
+ Q_PROPERTY(Priority priority READ priority WRITE setPriority)
+
+public:
+ enum MenuRole { NoRole, TextHeuristicRole, ApplicationSpecificRole, AboutQtRole,
+ AboutRole, PreferencesRole, QuitRole };
+ enum SoftKeyRole {
+ NoSoftKey, PositiveSoftKey, NegativeSoftKey, SelectSoftKey };
+ enum Priority { LowPriority = 0,
+ NormalPriority = 128,
+ HighPriority = 256};
+ explicit QAction(QObject* parent);
+ QAction(const QString &text, QObject* parent);
+ QAction(const QIcon &icon, const QString &text, QObject* parent);
+
+#ifdef QT3_SUPPORT
+ QT3_SUPPORT_CONSTRUCTOR QAction(QObject* parent, const char* name);
+ QT3_SUPPORT_CONSTRUCTOR QAction(const QString &text, const QKeySequence &shortcut,
+ QObject* parent, const char* name);
+ QT3_SUPPORT_CONSTRUCTOR QAction(const QIcon &icon, const QString &text,
+ const QKeySequence &shortcut,
+ QObject* parent, const char* name);
+#endif
+ ~QAction();
+
+ void setActionGroup(QActionGroup *group);
+ QActionGroup *actionGroup() const;
+ void setIcon(const QIcon &icon);
+ QIcon icon() const;
+
+ void setText(const QString &text);
+ QString text() const;
+
+ void setIconText(const QString &text);
+ QString iconText() const;
+
+ void setToolTip(const QString &tip);
+ QString toolTip() const;
+
+ void setStatusTip(const QString &statusTip);
+ QString statusTip() const;
+
+ void setWhatsThis(const QString &what);
+ QString whatsThis() const;
+
+ void setPriority(Priority priority);
+ Priority priority() const;
+
+#ifndef QT_NO_MENU
+ QMenu *menu() const;
+ void setMenu(QMenu *menu);
+#endif
+
+ void setSeparator(bool b);
+ bool isSeparator() const;
+
+#ifndef QT_NO_SHORTCUT
+ void setShortcut(const QKeySequence &shortcut);
+ QKeySequence shortcut() const;
+
+ void setShortcuts(const QList<QKeySequence> &shortcuts);
+ void setShortcuts(QKeySequence::StandardKey);
+ QList<QKeySequence> shortcuts() const;
+
+ void setShortcutContext(Qt::ShortcutContext context);
+ Qt::ShortcutContext shortcutContext() const;
+
+ void setAutoRepeat(bool);
+ bool autoRepeat() const;
+#endif
+
+ void setFont(const QFont &font);
+ QFont font() const;
+
+ void setCheckable(bool);
+ bool isCheckable() const;
+
+ QVariant data() const;
+ void setData(const QVariant &var);
+
+ bool isChecked() const;
+
+ bool isEnabled() const;
+
+ bool isVisible() const;
+
+ enum ActionEvent { Trigger, Hover };
+ void activate(ActionEvent event);
+ bool showStatusText(QWidget *widget=0);
+
+ void setMenuRole(MenuRole menuRole);
+ MenuRole menuRole() const;
+
+ void setSoftKeyRole(SoftKeyRole softKeyRole);
+ SoftKeyRole softKeyRole() const;
+
+ void setIconVisibleInMenu(bool visible);
+ bool isIconVisibleInMenu() const;
+
+#ifdef QT3_SUPPORT
+ inline QT3_SUPPORT void setMenuText(const QString &text) { setText(text); }
+ inline QT3_SUPPORT QString menuText() const { return text(); }
+ inline QT3_SUPPORT bool isOn() const { return isChecked(); }
+ inline QT3_SUPPORT bool isToggleAction() const { return isCheckable(); }
+ inline QT3_SUPPORT void setToggleAction(bool b) { setCheckable(b); }
+ inline QT3_SUPPORT void setIconSet(const QIcon &i) { setIcon(i); }
+ inline QT3_SUPPORT QIcon iconSet() const { return icon(); }
+ inline QT3_SUPPORT bool addTo(QWidget *w) { w->addAction(this); return true; }
+ inline QT3_SUPPORT bool removeFrom(QWidget *w) { w->removeAction(this); return true; }
+ inline QT3_SUPPORT void setAccel(const QKeySequence &shortcut) { setShortcut(shortcut); }
+ inline QT3_SUPPORT QKeySequence accel() const { return shortcut(); }
+#endif
+
+ QWidget *parentWidget() const;
+
+ QList<QWidget *> associatedWidgets() const;
+#ifndef QT_NO_GRAPHICSVIEW
+ QList<QGraphicsWidget *> associatedGraphicsWidgets() const; // ### suboptimal
+#endif
+
+protected:
+ bool event(QEvent *);
+ QAction(QActionPrivate &dd, QObject *parent);
+
+public Q_SLOTS:
+#ifdef QT3_SUPPORT
+ inline QT_MOC_COMPAT void setOn(bool b) { setChecked(b); }
+#endif
+ void trigger() { activate(Trigger); }
+ void hover() { activate(Hover); }
+ void setChecked(bool);
+ void toggle();
+ void setEnabled(bool);
+ inline void setDisabled(bool b) { setEnabled(!b); }
+ void setVisible(bool);
+
+Q_SIGNALS:
+ void changed();
+ void triggered(bool checked = false);
+ void hovered();
+ void toggled(bool);
+#ifdef QT3_SUPPORT
+ QT_MOC_COMPAT void activated(int = 0);
+#endif
+
+private:
+ Q_DISABLE_COPY(QAction)
+
+#ifdef QT3_SUPPORT
+ friend class QMenuItem;
+#endif
+ friend class QGraphicsWidget;
+ friend class QWidget;
+ friend class QActionGroup;
+ friend class QMenu;
+ friend class QMenuPrivate;
+ friend class QMenuBar;
+ friend class QShortcutMap;
+ friend class QToolButton;
+#ifdef Q_OS_MAC
+ friend void qt_mac_clear_status_text(QAction *action);
+#endif
+};
+
+QT_BEGIN_INCLUDE_NAMESPACE
+#include <QtWidgets/qactiongroup.h>
+QT_END_INCLUDE_NAMESPACE
+
+#endif // QT_NO_ACTION
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QACTION_H
diff --git a/src/widgets/kernel/qaction_p.h b/src/widgets/kernel/qaction_p.h
new file mode 100644
index 0000000000..e916be47db
--- /dev/null
+++ b/src/widgets/kernel/qaction_p.h
@@ -0,0 +1,144 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QACTION_P_H
+#define QACTION_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "QtWidgets/qaction.h"
+#include "QtWidgets/qmenu.h"
+#include "private/qgraphicswidget_p.h"
+#include "private/qobject_p.h"
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_ACTION
+
+#ifdef QT3_SUPPORT
+class QMenuItemEmitter;
+#endif
+
+class QShortcutMap;
+
+class Q_AUTOTEST_EXPORT QActionPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QAction)
+public:
+ QActionPrivate();
+ ~QActionPrivate();
+
+ static QActionPrivate *get(QAction *q)
+ {
+ return q->d_func();
+ }
+
+ bool showStatusText(QWidget *w, const QString &str);
+
+ QPointer<QActionGroup> group;
+ QString text;
+ QString iconText;
+ QIcon icon;
+ QString tooltip;
+ QString statustip;
+ QString whatsthis;
+#ifndef QT_NO_SHORTCUT
+ QKeySequence shortcut;
+ QList<QKeySequence> alternateShortcuts;
+#endif
+ QVariant userData;
+#ifndef QT_NO_SHORTCUT
+ int shortcutId;
+ QList<int> alternateShortcutIds;
+ Qt::ShortcutContext shortcutContext;
+ uint autorepeat : 1;
+#endif
+ QFont font;
+ QPointer<QMenu> menu;
+ uint enabled : 1, forceDisabled : 1;
+ uint visible : 1, forceInvisible : 1;
+ uint checkable : 1;
+ uint checked : 1;
+ uint separator : 1;
+ uint fontSet : 1;
+
+ //for soft keys management
+ uint forceEnabledInSoftkeys : 1;
+ uint menuActionSoftkeys : 1;
+ int iconVisibleInMenu : 3; // Only has values -1, 0, and 1
+
+ QAction::MenuRole menuRole;
+ QAction::SoftKeyRole softKeyRole;
+ QAction::Priority priority;
+
+ QList<QWidget *> widgets;
+#ifndef QT_NO_GRAPHICSVIEW
+ QList<QGraphicsWidget *> graphicsWidgets;
+#endif
+#ifndef QT_NO_SHORTCUT
+ void redoGrab(QShortcutMap &map);
+ void redoGrabAlternate(QShortcutMap &map);
+ void setShortcutEnabled(bool enable, QShortcutMap &map);
+
+ static QShortcutMap *globalMap;
+#endif // QT_NO_SHORTCUT
+
+#ifdef QT3_SUPPORT //for menubar/menu compat
+ QMenuItemEmitter *act_signal;
+ int id, param;
+#endif
+ void sendDataChanged();
+};
+
+#endif // QT_NO_ACTION
+
+QT_END_NAMESPACE
+
+#endif // QACTION_P_H
diff --git a/src/gui/kernel/qactiongroup.cpp b/src/widgets/kernel/qactiongroup.cpp
index cbab6aa93a..cbab6aa93a 100644
--- a/src/gui/kernel/qactiongroup.cpp
+++ b/src/widgets/kernel/qactiongroup.cpp
diff --git a/src/widgets/kernel/qactiongroup.h b/src/widgets/kernel/qactiongroup.h
new file mode 100644
index 0000000000..deeed061cd
--- /dev/null
+++ b/src/widgets/kernel/qactiongroup.h
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QACTIONGROUP_H
+#define QACTIONGROUP_H
+
+#include <QtWidgets/qaction.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_ACTION
+
+class QActionGroupPrivate;
+
+class Q_WIDGETS_EXPORT QActionGroup : public QObject
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QActionGroup)
+
+ Q_PROPERTY(bool exclusive READ isExclusive WRITE setExclusive)
+ Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled)
+ Q_PROPERTY(bool visible READ isVisible WRITE setVisible)
+
+public:
+ explicit QActionGroup(QObject* parent);
+ ~QActionGroup();
+
+ QAction *addAction(QAction* a);
+ QAction *addAction(const QString &text);
+ QAction *addAction(const QIcon &icon, const QString &text);
+ void removeAction(QAction *a);
+ QList<QAction*> actions() const;
+
+ QAction *checkedAction() const;
+ bool isExclusive() const;
+ bool isEnabled() const;
+ bool isVisible() const;
+
+#ifdef QT3_SUPPORT
+ inline QT3_SUPPORT void add(QAction* a) { addAction(a); }
+ inline QT3_SUPPORT void addSeparator()
+ { QAction *act = new QAction(this); act->setSeparator(true); addAction(act); }
+ inline QT3_SUPPORT bool addTo(QWidget *w) { w->addActions(actions()); return true; }
+#endif
+
+public Q_SLOTS:
+ void setEnabled(bool);
+ inline void setDisabled(bool b) { setEnabled(!b); }
+ void setVisible(bool);
+ void setExclusive(bool);
+
+Q_SIGNALS:
+ void triggered(QAction *);
+ QT_MOC_COMPAT void selected(QAction *);
+ void hovered(QAction *);
+
+private:
+ Q_DISABLE_COPY(QActionGroup)
+ Q_PRIVATE_SLOT(d_func(), void _q_actionTriggered())
+ Q_PRIVATE_SLOT(d_func(), void _q_actionChanged())
+ Q_PRIVATE_SLOT(d_func(), void _q_actionHovered())
+};
+
+#endif // QT_NO_ACTION
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QACTIONGROUP_H
diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp
new file mode 100644
index 0000000000..ff3fd89712
--- /dev/null
+++ b/src/widgets/kernel/qapplication.cpp
@@ -0,0 +1,5613 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qplatformdefs.h"
+#include "qabstracteventdispatcher.h"
+#include "qaccessible.h"
+#include "qapplication.h"
+#include "qclipboard.h"
+#include "qcursor.h"
+#include "qdesktopwidget.h"
+#include "qdir.h"
+#include "qevent.h"
+#include "qfile.h"
+#include "qfileinfo.h"
+#include "qgraphicsscene.h"
+#include "qhash.h"
+#include "qset.h"
+#include "qlayout.h"
+#include "qsessionmanager.h"
+#include "qstyle.h"
+#include "qstylefactory.h"
+#include "qtextcodec.h"
+#include "qtranslator.h"
+#include "qvariant.h"
+#include "qwidget.h"
+#include "private/qdnd_p.h"
+#include "qcolormap.h"
+#include "qdebug.h"
+#include "private/qstylesheetstyle_p.h"
+#include "private/qstyle_p.h"
+#include "qmessagebox.h"
+#include <QtWidgets/qgraphicsproxywidget.h>
+#include <QtGui/qstylehints.h>
+#include <QtGui/qinputpanel.h>
+
+#include "qinputcontext.h"
+#include "private/qkeymapper_p.h"
+
+#ifdef Q_WS_X11
+#include <private/qt_x11_p.h>
+#endif
+
+#if defined(Q_WS_X11) || defined(Q_OS_SYMBIAN)
+#include "qinputcontextfactory.h"
+#endif
+
+#include "qguiplatformplugin_p.h"
+
+#include <qthread.h>
+#include <private/qthread_p.h>
+
+#include <private/qfont_p.h>
+
+#include <stdlib.h>
+
+#if defined(Q_WS_X11) && !defined(QT_NO_EGL)
+#include <link.h>
+#endif
+
+#include "qapplication_p.h"
+#include "private/qevent_p.h"
+#include "qwidget_p.h"
+
+#include "qapplication.h"
+
+#include "qgesture.h"
+#include "private/qgesturemanager_p.h"
+#include "private/qguiapplication_p.h"
+#include "qplatformfontdatabase_qpa.h"
+#ifndef QT_NO_LIBRARY
+#include "qlibrary.h"
+#endif
+
+#ifdef Q_WS_WINCE
+#include "qdatetime.h"
+#include "qguifunctions_wince.h"
+extern bool qt_wince_is_smartphone(); //qguifunctions_wince.cpp
+extern bool qt_wince_is_mobile(); //qguifunctions_wince.cpp
+extern bool qt_wince_is_pocket_pc(); //qguifunctions_wince.cpp
+#endif
+
+#include "qdatetime.h"
+
+#ifdef QT_MAC_USE_COCOA
+#include <private/qt_cocoa_helpers_mac_p.h>
+#endif
+
+//#define ALIEN_DEBUG
+
+#if defined(Q_OS_SYMBIAN)
+#include "qt_s60_p.h"
+#endif
+
+static void initResources()
+{
+#if defined(Q_WS_WINCE)
+ Q_INIT_RESOURCE_EXTERN(qstyle_wince)
+ Q_INIT_RESOURCE(qstyle_wince);
+#elif defined(Q_OS_SYMBIAN)
+ Q_INIT_RESOURCE_EXTERN(qstyle_s60)
+ Q_INIT_RESOURCE(qstyle_s60);
+#else
+ Q_INIT_RESOURCE_EXTERN(qstyle)
+ Q_INIT_RESOURCE(qstyle);
+#endif
+ Q_INIT_RESOURCE_EXTERN(qmessagebox)
+ Q_INIT_RESOURCE(qmessagebox);
+
+}
+
+QT_BEGIN_NAMESPACE
+
+Q_CORE_EXPORT void qt_call_post_routines();
+
+QApplication::Type qt_appType=QApplication::Tty;
+QApplicationPrivate *QApplicationPrivate::self = 0;
+
+QInputContext *QApplicationPrivate::inputContext = 0;
+
+bool QApplicationPrivate::quitOnLastWindowClosed = true;
+
+#ifdef Q_WS_WINCE
+int QApplicationPrivate::autoMaximizeThreshold = -1;
+bool QApplicationPrivate::autoSipEnabled = false;
+#else
+bool QApplicationPrivate::autoSipEnabled = true;
+#endif
+
+QApplicationPrivate::QApplicationPrivate(int &argc, char **argv, QApplication::Type type, int flags)
+ : QApplicationPrivateBase(argc, argv, flags)
+{
+ application_type = type;
+ qt_appType = type;
+
+#ifndef QT_NO_SESSIONMANAGER
+ is_session_restored = false;
+#endif
+
+ quitOnLastWindowClosed = true;
+
+#ifdef QT3_SUPPORT
+ qt_compat_used = 0;
+ qt_compat_resolved = 0;
+ qt_tryAccelEvent = 0;
+ qt_tryComposeUnicode = 0;
+ qt_dispatchAccelEvent = 0;
+#endif
+#if defined(Q_WS_QWS) && !defined(QT_NO_DIRECTPAINTER)
+ directPainters = 0;
+#endif
+
+#ifndef QT_NO_GESTURES
+ gestureManager = 0;
+ gestureWidget = 0;
+#endif // QT_NO_GESTURES
+
+#if defined(Q_WS_X11) || defined(Q_WS_WIN)
+ move_cursor = 0;
+ copy_cursor = 0;
+ link_cursor = 0;
+#endif
+#if defined(Q_WS_WIN)
+ ignore_cursor = 0;
+#endif
+
+ if (!self)
+ self = this;
+}
+
+QApplicationPrivate::~QApplicationPrivate()
+{
+ if (self == this)
+ self = 0;
+}
+
+/*!
+ \class QApplication
+ \brief The QApplication class manages the GUI application's control
+ flow and main settings.
+
+ 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, finalization, and provides session
+ management. In addition, QApplication handles most of the system-wide and
+ application-wide settings.
+
+ For any GUI application using Qt, there is precisely \bold 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
+
+ Since the QApplication object does so much initialization, it \e{must} be
+ created before any other objects related to the user interface are created.
+ QApplication also deals with common command line arguments. Hence, 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
+*/
+
+/*!
+ \enum QApplication::Type
+
+ \value Tty a console application
+ \value GuiClient a GUI client application
+ \value GuiServer a GUI server application (for Qt for Embedded Linux)
+*/
+
+/*!
+ \enum QApplication::ColorSpec
+
+ \value NormalColor the default color allocation policy
+ \value CustomColor the same as NormalColor for X11; allocates colors
+ to a palette on demand under Windows
+ \value ManyColor the right choice for applications that use thousands of
+ colors
+
+ See setColorSpec() for full details.
+*/
+
+/*!
+ \fn QWidget *QApplication::topLevelAt(const QPoint &point)
+
+ 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)
+
+ \overload
+
+ Returns the top-level widget at the point (\a{x}, \a{y}); returns
+ 0 if there is no such widget.
+*/
+
+
+/*
+ The qt_init() and qt_cleanup() functions are implemented in the
+ qapplication_xyz.cpp file.
+*/
+
+void qt_init(QApplicationPrivate *priv, int type
+#ifdef Q_WS_X11
+ , Display *display = 0, Qt::HANDLE visual = 0, Qt::HANDLE colormap = 0
+#endif
+ );
+void qt_cleanup();
+
+Qt::MouseButtons QApplicationPrivate::mouse_buttons = Qt::NoButton;
+Qt::KeyboardModifiers QApplicationPrivate::modifier_buttons = Qt::NoModifier;
+
+QStyle *QApplicationPrivate::app_style = 0; // default application style
+QString QApplicationPrivate::styleOverride; // style override
+
+#ifndef QT_NO_STYLE_STYLESHEET
+QString QApplicationPrivate::styleSheet; // default application stylesheet
+#endif
+QPointer<QWidget> QApplicationPrivate::leaveAfterRelease = 0;
+
+int QApplicationPrivate::app_cspec = QApplication::NormalColor;
+QPalette *QApplicationPrivate::sys_pal = 0; // default system palette
+QPalette *QApplicationPrivate::set_pal = 0; // default palette set by programmer
+
+#ifndef Q_WS_QPA
+Q_GLOBAL_STATIC(QMutex, applicationFontMutex)
+QFont *QApplicationPrivate::app_font = 0; // default application font
+#endif
+QFont *QApplicationPrivate::sys_font = 0; // default system font
+QFont *QApplicationPrivate::set_font = 0; // default font set by programmer
+
+QIcon *QApplicationPrivate::app_icon = 0;
+QWidget *QApplicationPrivate::main_widget = 0; // main application widget
+QWidget *QApplicationPrivate::focus_widget = 0; // has keyboard input focus
+QWidget *QApplicationPrivate::hidden_focus_widget = 0; // will get keyboard input focus after show()
+QWidget *QApplicationPrivate::active_window = 0; // toplevel with keyboard focus
+bool QApplicationPrivate::obey_desktop_settings = true; // use winsys resources
+#ifndef QT_NO_WHEELEVENT
+int QApplicationPrivate::wheel_scroll_lines; // number of lines to scroll
+#endif
+bool qt_is_gui_used;
+bool Q_WIDGETS_EXPORT qt_tab_all_widgets = true;
+bool qt_in_tab_key_event = false;
+int qt_antialiasing_threshold = -1;
+QSize QApplicationPrivate::app_strut = QSize(0,0); // no default application strut
+bool QApplicationPrivate::animate_ui = true;
+bool QApplicationPrivate::animate_menu = false;
+bool QApplicationPrivate::fade_menu = false;
+bool QApplicationPrivate::animate_combo = false;
+bool QApplicationPrivate::animate_tooltip = false;
+bool QApplicationPrivate::fade_tooltip = false;
+bool QApplicationPrivate::animate_toolbox = false;
+bool QApplicationPrivate::widgetCount = false;
+bool QApplicationPrivate::load_testability = false;
+#ifdef QT_KEYPAD_NAVIGATION
+# ifdef Q_OS_SYMBIAN
+Qt::NavigationMode QApplicationPrivate::navigationMode = Qt::NavigationModeKeypadDirectional;
+# else
+Qt::NavigationMode QApplicationPrivate::navigationMode = Qt::NavigationModeKeypadTabOrder;
+# endif
+QWidget *QApplicationPrivate::oldEditFocus = 0;
+#endif
+
+bool qt_tabletChokeMouse = false;
+
+inline bool QApplicationPrivate::isAlien(QWidget *widget)
+{
+ return widget && !widget->isWindow();
+}
+
+// ######## move to QApplicationPrivate
+// Default application palettes and fonts (per widget type)
+Q_GLOBAL_STATIC(PaletteHash, app_palettes)
+PaletteHash *qt_app_palettes_hash()
+{
+ return app_palettes();
+}
+
+Q_GLOBAL_STATIC_WITH_INITIALIZER(FontHash, app_fonts, { *x = QGuiApplicationPrivate::platformIntegration()->fontDatabase()->defaultFonts(); } )
+FontHash *qt_app_fonts_hash()
+{
+ return app_fonts();
+}
+
+QWidgetList *QApplicationPrivate::popupWidgets = 0; // has keyboard input focus
+
+QDesktopWidget *qt_desktopWidget = 0; // root window widgets
+#if !defined(Q_WS_QPA) && !defined(QT_NO_CLIPBOARD)
+QClipboard *qt_clipboard = 0; // global clipboard object
+#endif
+QWidgetList * qt_modal_stack = 0; // stack of modal widgets
+bool app_do_modal = false;
+
+/*!
+ \internal
+*/
+void QApplicationPrivate::process_cmdline()
+{
+ // process platform-indep command line
+ if (!qt_is_gui_used || !argc)
+ return;
+
+ int i, j;
+
+ j = 1;
+ for (i=1; i<argc; i++) { // if you add anything here, modify QCoreApplication::arguments()
+ if (argv[i] && *argv[i] != '-') {
+ argv[j++] = argv[i];
+ continue;
+ }
+ QByteArray arg = argv[i];
+ arg = arg;
+ QString s;
+ if (arg == "-qdevel" || arg == "-qdebug") {
+ // obsolete argument
+ } else if (arg.indexOf("-qmljsdebugger=", 0) != -1) {
+ qmljs_debug_arguments = QString::fromLocal8Bit(arg.right(arg.length() - 15));
+ } else if (arg.indexOf("-style=", 0) != -1) {
+ s = QString::fromLocal8Bit(arg.right(arg.length() - 7).toLower());
+ } else if (arg == "-style" && i < argc-1) {
+ s = QString::fromLocal8Bit(argv[++i]).toLower();
+#ifndef QT_NO_SESSIONMANAGER
+ } else if (arg == "-session" && i < argc-1) {
+ ++i;
+ if (argv[i] && *argv[i]) {
+ session_id = QString::fromLatin1(argv[i]);
+ int p = session_id.indexOf(QLatin1Char('_'));
+ if (p >= 0) {
+ session_key = session_id.mid(p +1);
+ session_id = session_id.left(p);
+ }
+ is_session_restored = true;
+ }
+#endif
+#ifndef QT_NO_STYLE_STYLESHEET
+ } else if (arg == "-stylesheet" && i < argc -1) {
+ styleSheet = QLatin1String("file:///");
+ styleSheet.append(QString::fromLocal8Bit(argv[++i]));
+ } else if (arg.indexOf("-stylesheet=") != -1) {
+ styleSheet = QLatin1String("file:///");
+ styleSheet.append(QString::fromLocal8Bit(arg.right(arg.length() - 12)));
+#endif
+ } else if (qstrcmp(arg, "-widgetcount") == 0) {
+ widgetCount = true;
+ } else if (qstrcmp(arg, "-testability") == 0) {
+ load_testability = true;
+ } else {
+ argv[j++] = argv[i];
+ }
+ if (!s.isEmpty()) {
+ if (app_style) {
+ delete app_style;
+ app_style = 0;
+ }
+ styleOverride = s;
+ }
+ }
+
+ if(j < argc) {
+ argv[j] = 0;
+ argc = j;
+ }
+}
+
+/*!
+ 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 -qmljsdebugger=, activates the QML/JS debugger with a specified port.
+ The value must be of format port:1234[,block], where block is optional
+ and will make the application wait until a debugger connects to it.
+ \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. Note that
+ this option is ignored when Qt is built with fontconfig support enabled.
+ \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
+
+ \section1 X11 Notes
+
+ If QApplication fails to open the X11 display, it will terminate
+ the process. This behavior is consistent with most X11
+ applications.
+
+ \sa arguments()
+*/
+
+QApplication::QApplication(int &argc, char **argv)
+ : QApplicationBase(*new QApplicationPrivate(argc, argv, GuiClient, 0x040000))
+{ Q_D(QApplication); d->construct(); }
+
+QApplication::QApplication(int &argc, char **argv, int _internal)
+ : QApplicationBase(*new QApplicationPrivate(argc, argv, GuiClient, _internal))
+{ Q_D(QApplication); d->construct(); }
+
+
+/*!
+ 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.
+
+ 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 Mac OS, 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.
+
+ \snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 0
+*/
+
+QApplication::QApplication(int &argc, char **argv, bool GUIenabled )
+ : QApplicationBase(*new QApplicationPrivate(argc, argv, GUIenabled ? GuiClient : Tty, 0x040000))
+{ Q_D(QApplication); d->construct(); }
+
+QApplication::QApplication(int &argc, char **argv, bool GUIenabled , int _internal)
+ : QApplicationBase(*new QApplicationPrivate(argc, argv, GUIenabled ? GuiClient : Tty, _internal))
+{ Q_D(QApplication); d->construct();}
+
+
+
+/*!
+ 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.
+
+ 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)
+ : QApplicationBase(*new QApplicationPrivate(argc, argv, type, 0x040000))
+{ Q_D(QApplication); d->construct(); }
+
+QApplication::QApplication(int &argc, char **argv, Type type , int _internal)
+ : QApplicationBase(*new QApplicationPrivate(argc, argv, type, _internal))
+{ Q_D(QApplication); d->construct(); }
+
+#if defined(Q_WS_X11) && !defined(QT_NO_EGL)
+static int qt_matchLibraryName(dl_phdr_info *info, size_t, void *data)
+{
+ const char *name = static_cast<const char *>(data);
+ return strstr(info->dlpi_name, name) != 0;
+}
+#endif
+
+/*!
+ \internal
+*/
+void QApplicationPrivate::construct(
+#ifdef Q_WS_X11
+ Display *dpy, Qt::HANDLE visual, Qt::HANDLE cmap
+#endif
+ )
+{
+ initResources();
+
+ qt_is_gui_used = (qt_appType != QApplication::Tty);
+ process_cmdline();
+
+ // Must be called before initialize()
+ qt_init(this, qt_appType
+#ifdef Q_WS_X11
+ , dpy, visual, cmap
+#endif
+ );
+ initialize();
+ eventDispatcher->startingUp();
+
+#ifdef QT_EVAL
+ extern void qt_gui_eval_init(uint);
+ qt_gui_eval_init(application_type);
+#endif
+
+#if defined(Q_OS_SYMBIAN) && !defined(QT_NO_SYSTEMLOCALE)
+ symbianInit();
+#endif
+
+#ifndef QT_NO_LIBRARY
+ if(load_testability) {
+ QLibrary testLib(QLatin1String("qttestability"));
+ if (testLib.load()) {
+ typedef void (*TasInitialize)(void);
+ TasInitialize initFunction = (TasInitialize)testLib.resolve("qt_testability_init");
+#ifdef Q_OS_SYMBIAN
+ // resolving method by name does not work on Symbian OS so need to use ordinal
+ if(!initFunction) {
+ initFunction = (TasInitialize)testLib.resolve("1");
+ }
+#endif
+ if (initFunction) {
+ initFunction();
+ } else {
+ qCritical("Library qttestability resolve failed!");
+ }
+ } else {
+ qCritical("Library qttestability load failed!");
+ }
+ }
+
+ //make sure the plugin is loaded
+ if (qt_is_gui_used)
+ qt_guiPlatformPlugin();
+#endif
+}
+
+#if defined(Q_WS_X11)
+// ### a string literal is a cont char*
+// ### using it as a char* is wrong and could lead to segfaults
+// ### if aargv is modified someday
+// ########## make it work with argc == argv == 0
+static int aargc = 1;
+static char *aargv[] = { (char*)"unknown", 0 };
+
+/*!
+ \fn QApplication::QApplication(Display* display, Qt::HANDLE visual, Qt::HANDLE colormap)
+
+ 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.
+
+ This function is only available on X11.
+*/
+QApplication::QApplication(Display* dpy, Qt::HANDLE visual, Qt::HANDLE colormap)
+ : QApplicationBase(*new QApplicationPrivate(aargc, aargv, GuiClient, 0x040000))
+{
+ if (! dpy)
+ qWarning("QApplication: Invalid Display* argument");
+ Q_D(QApplication);
+ d->construct(dpy, visual, colormap);
+}
+
+QApplication::QApplication(Display* dpy, Qt::HANDLE visual, Qt::HANDLE colormap, int _internal)
+ : QApplicationBase(*new QApplicationPrivate(aargc, aargv, GuiClient, _internal))
+{
+ if (! dpy)
+ qWarning("QApplication: Invalid Display* argument");
+ Q_D(QApplication);
+ d->construct(dpy, visual, colormap);
+ QApplicationPrivate::app_compile_version = _internal;
+}
+
+/*!
+ \fn QApplication::QApplication(Display *display, int &argc, char **argv,
+ Qt::HANDLE visual, Qt::HANDLE colormap)
+
+ 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 function is only available on X11.
+*/
+QApplication::QApplication(Display *dpy, int &argc, char **argv,
+ Qt::HANDLE visual, Qt::HANDLE colormap)
+ : QApplicationBase(*new QApplicationPrivate(argc, argv, GuiClient, 0x040000))
+{
+ if (! dpy)
+ qWarning("QApplication: Invalid Display* argument");
+ Q_D(QApplication);
+ d->construct(dpy, visual, colormap);
+}
+
+QApplication::QApplication(Display *dpy, int &argc, char **argv,
+ Qt::HANDLE visual, Qt::HANDLE colormap, int _internal)
+ : QApplicationBase(*new QApplicationPrivate(argc, argv, GuiClient, _internal))
+{
+ if (! dpy)
+ qWarning("QApplication: Invalid Display* argument");
+ Q_D(QApplication);
+ d->construct(dpy, visual, colormap);
+ QApplicationPrivate::app_compile_version = _internal;
+}
+
+#endif // Q_WS_X11
+
+#ifndef QT_NO_STATEMACHINE
+extern int qRegisterGuiStateMachine();
+extern int qUnregisterGuiStateMachine();
+#endif
+
+/*!
+ \fn void QApplicationPrivate::initialize()
+
+ Initializes the QApplication object, called from the constructors.
+*/
+void QApplicationPrivate::initialize()
+{
+ QWidgetPrivate::mapper = new QWidgetMapper;
+ QWidgetPrivate::allWidgets = new QWidgetSet;
+
+ if (qt_appType != QApplication::Tty)
+ (void) QApplication::style(); // trigger creation of application style
+#ifndef QT_NO_STATEMACHINE
+ // trigger registering of QStateMachine's GUI types
+ qRegisterGuiStateMachine();
+#endif
+
+ is_app_running = true; // no longer starting up
+
+ Q_Q(QApplication);
+#ifndef QT_NO_SESSIONMANAGER
+ // connect to the session manager
+ session_manager = new QSessionManager(q, session_id, session_key);
+#endif
+
+ if (qgetenv("QT_USE_NATIVE_WINDOWS").toInt() > 0)
+ q->setAttribute(Qt::AA_NativeWindows);
+
+#ifdef Q_WS_WINCE
+#ifdef QT_AUTO_MAXIMIZE_THRESHOLD
+ autoMaximizeThreshold = QT_AUTO_MAXIMIZE_THRESHOLD;
+#else
+ if (qt_wince_is_mobile())
+ autoMaximizeThreshold = 50;
+ else
+ autoMaximizeThreshold = -1;
+#endif //QT_AUTO_MAXIMIZE_THRESHOLD
+#endif //Q_WS_WINCE
+
+#ifndef QT_NO_WHEELEVENT
+ QApplicationPrivate::wheel_scroll_lines = 3;
+#endif
+
+ if (qt_is_gui_used)
+ initializeMultitouch();
+}
+
+/*!
+ Returns the type of application (\l Tty, GuiClient, or
+ GuiServer). The type is set when constructing the QApplication
+ object.
+*/
+QApplication::Type QApplication::type()
+{
+ return qt_appType;
+}
+
+/*****************************************************************************
+ Functions returning the active popup and modal widgets.
+ *****************************************************************************/
+
+/*!
+ 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.
+
+ 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()
+*/
+
+QWidget *QApplication::activePopupWidget()
+{
+ return QApplicationPrivate::popupWidgets && !QApplicationPrivate::popupWidgets->isEmpty() ?
+ QApplicationPrivate::popupWidgets->last() : 0;
+}
+
+
+/*!
+ 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.
+
+ Modal widgets are organized in a stack. This function returns the active
+ modal widget at the top of the stack.
+
+ \sa activePopupWidget(), topLevelWidgets()
+*/
+
+QWidget *QApplication::activeModalWidget()
+{
+ return qt_modal_stack && !qt_modal_stack->isEmpty() ? qt_modal_stack->first() : 0;
+}
+
+/*!
+ Cleans up any window system resources that were allocated by this
+ application. Sets the global variable \c qApp to 0.
+*/
+
+QApplication::~QApplication()
+{
+ Q_D(QApplication);
+
+#if !defined(Q_WS_QPA) && !defined(QT_NO_CLIPBOARD)
+ // flush clipboard contents
+ if (qt_clipboard) {
+ QEvent event(QEvent::Clipboard);
+ QApplication::sendEvent(qt_clipboard, &event);
+ }
+#endif
+
+ //### this should probable be done even later
+ qt_call_post_routines();
+
+ // kill timers before closing down the dispatcher
+ d->toolTipWakeUp.stop();
+ d->toolTipFallAsleep.stop();
+
+#if !defined(Q_WS_QPA)
+ d->eventDispatcher->closingDown();
+ d->eventDispatcher = 0;
+#endif
+ QApplicationPrivate::is_app_closing = true;
+ QApplicationPrivate::is_app_running = false;
+
+ delete QWidgetPrivate::mapper;
+ QWidgetPrivate::mapper = 0;
+
+ // delete all widgets
+ if (QWidgetPrivate::allWidgets) {
+ QWidgetSet *mySet = QWidgetPrivate::allWidgets;
+ QWidgetPrivate::allWidgets = 0;
+ for (QWidgetSet::ConstIterator it = mySet->constBegin(); it != mySet->constEnd(); ++it) {
+ register QWidget *w = *it;
+ if (!w->parent()) // window
+ w->destroy(true, true);
+ }
+ delete mySet;
+ }
+
+ delete qt_desktopWidget;
+ qt_desktopWidget = 0;
+
+#if !defined(Q_WS_QPA) && !defined(QT_NO_CLIPBOARD)
+ delete qt_clipboard;
+ qt_clipboard = 0;
+#endif
+
+#if defined(Q_WS_X11) || defined(Q_WS_WIN)
+ delete d->move_cursor; d->move_cursor = 0;
+ delete d->copy_cursor; d->copy_cursor = 0;
+ delete d->link_cursor; d->link_cursor = 0;
+#endif
+#if defined(Q_WS_WIN)
+ delete d->ignore_cursor; d->ignore_cursor = 0;
+#endif
+
+ delete QApplicationPrivate::app_pal;
+ QApplicationPrivate::app_pal = 0;
+ delete QApplicationPrivate::sys_pal;
+ QApplicationPrivate::sys_pal = 0;
+ delete QApplicationPrivate::set_pal;
+ QApplicationPrivate::set_pal = 0;
+ app_palettes()->clear();
+
+#ifndef Q_WS_QPA
+ {
+ QMutexLocker locker(applicationFontMutex());
+ delete QApplicationPrivate::app_font;
+ QApplicationPrivate::app_font = 0;
+ }
+#endif
+
+ delete QApplicationPrivate::sys_font;
+ QApplicationPrivate::sys_font = 0;
+ delete QApplicationPrivate::set_font;
+ QApplicationPrivate::set_font = 0;
+ app_fonts()->clear();
+
+ delete QApplicationPrivate::app_style;
+ QApplicationPrivate::app_style = 0;
+ delete QApplicationPrivate::app_icon;
+ QApplicationPrivate::app_icon = 0;
+
+#ifndef QT_NO_DRAGANDDROP
+ if (qt_is_gui_used)
+ delete QDragManager::self();
+#endif
+
+ d->cleanupMultitouch();
+
+ qt_cleanup();
+
+ if (QApplicationPrivate::widgetCount)
+ qDebug("Widgets left: %i Max widgets: %i \n", QWidgetPrivate::instanceCounter, QWidgetPrivate::maxInstances);
+#ifndef QT_NO_SESSIONMANAGER
+ delete d->session_manager;
+ d->session_manager = 0;
+#endif //QT_NO_SESSIONMANAGER
+
+ QApplicationPrivate::obey_desktop_settings = true;
+
+ QApplicationPrivate::app_strut = QSize(0, 0);
+ QApplicationPrivate::animate_ui = true;
+ QApplicationPrivate::animate_menu = false;
+ QApplicationPrivate::fade_menu = false;
+ QApplicationPrivate::animate_combo = false;
+ QApplicationPrivate::animate_tooltip = false;
+ QApplicationPrivate::fade_tooltip = false;
+ QApplicationPrivate::widgetCount = false;
+
+#ifndef QT_NO_STATEMACHINE
+ // trigger unregistering of QStateMachine's GUI types
+ qUnregisterGuiStateMachine();
+#endif
+}
+
+
+/*!
+ \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.
+
+ This function can be slow.
+
+ \sa QCursor::pos(), QWidget::grabMouse(), QWidget::grabKeyboard()
+*/
+QWidget *QApplication::widgetAt(const QPoint &p)
+{
+ QWidget *window = QApplication::topLevelAt(p);
+ if (!window)
+ return 0;
+
+ QWidget *child = 0;
+
+ if (!window->testAttribute(Qt::WA_TransparentForMouseEvents))
+ child = window->childAt(window->mapFromGlobal(p));
+
+ if (child)
+ return child;
+
+ if (window->testAttribute(Qt::WA_TransparentForMouseEvents)) {
+ //shoot a hole in the widget and try once again,
+ //suboptimal on Qt for Embedded Linux where we do
+ //know the stacking order of the toplevels.
+ int x = p.x();
+ int y = p.y();
+ QRegion oldmask = window->mask();
+ QPoint wpoint = window->mapFromGlobal(QPoint(x, y));
+ QRegion newmask = (oldmask.isEmpty() ? QRegion(window->rect()) : oldmask)
+ - QRegion(wpoint.x(), wpoint.y(), 1, 1);
+ window->setMask(newmask);
+ QWidget *recurse = 0;
+ if (QApplication::topLevelAt(p) != window) // verify recursion will terminate
+ recurse = widgetAt(x, y);
+ if (oldmask.isEmpty())
+ window->clearMask();
+ else
+ window->setMask(oldmask);
+ return recurse;
+ }
+ return window;
+}
+
+/*!
+ \fn QWidget *QApplication::widgetAt(int x, int y)
+
+ \overload
+
+ Returns the widget at global screen position (\a x, \a y), or 0 if there is
+ no Qt widget there.
+*/
+
+/*!
+ \fn void QApplication::setArgs(int argc, char **argv)
+ \internal
+*/
+
+
+
+/*!
+ \internal
+*/
+bool QApplication::compressEvent(QEvent *event, QObject *receiver, QPostEventList *postedEvents)
+{
+ if ((event->type() == QEvent::UpdateRequest
+#ifdef QT3_SUPPORT
+ || event->type() == QEvent::LayoutHint
+#endif
+ || event->type() == QEvent::LayoutRequest
+ || event->type() == QEvent::Resize
+ || event->type() == QEvent::Move
+ || event->type() == QEvent::LanguageChange
+ || event->type() == QEvent::UpdateSoftKeys
+ || event->type() == QEvent::InputMethod)) {
+ for (QPostEventList::const_iterator it = postedEvents->constBegin(); it != postedEvents->constEnd(); ++it) {
+ const QPostEvent &cur = *it;
+ if (cur.receiver != receiver || cur.event == 0 || cur.event->type() != event->type())
+ continue;
+ if (cur.event->type() == QEvent::LayoutRequest
+#ifdef QT3_SUPPORT
+ || cur.event->type() == QEvent::LayoutHint
+#endif
+ || cur.event->type() == QEvent::UpdateRequest) {
+ ;
+ } else if (cur.event->type() == QEvent::Resize) {
+ ((QResizeEvent *)(cur.event))->s = ((QResizeEvent *)event)->s;
+ } else if (cur.event->type() == QEvent::Move) {
+ ((QMoveEvent *)(cur.event))->p = ((QMoveEvent *)event)->p;
+ } else if (cur.event->type() == QEvent::LanguageChange) {
+ ;
+ } else if (cur.event->type() == QEvent::UpdateSoftKeys) {
+ ;
+ } else if ( cur.event->type() == QEvent::InputMethod ) {
+ *(QInputMethodEvent *)(cur.event) = *(QInputMethodEvent *)event;
+ } else {
+ continue;
+ }
+ delete event;
+ return true;
+ }
+ return false;
+ }
+ return QApplicationBase::compressEvent(event, receiver, postedEvents);
+}
+
+/*!
+ \property QApplication::styleSheet
+ \brief the application style sheet
+ \since 4.2
+
+ By default, this property returns an empty string unless the user specifies
+ the \c{-stylesheet} option on the command line when running the application.
+
+ \sa QWidget::setStyle(), {Qt Style Sheets}
+*/
+
+/*!
+ \property QApplication::autoMaximizeThreshold
+ \since 4.4
+ \brief defines a threshold for auto maximizing widgets
+
+ \bold{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 cause the window to be maximized
+ automatically.
+
+ Setting the threshold to 100 or greater means that the widget will always
+ be maximized. Alternatively, setting the threshold to 50 means that the
+ widget will be maximized only if the vertical minimum size hint is at least
+ 50% of the vertical screen size.
+
+ Setting the threshold to -1 disables the feature.
+
+ On Windows CE the default is -1 (i.e., it is disabled).
+ On Windows Mobile the default is 40.
+*/
+
+/*!
+ \property QApplication::autoSipEnabled
+ \since 4.5
+ \brief toggles automatic SIP (software input panel) visibility
+
+ Set this property to \c true to automatically display the SIP when entering
+ widgets that accept keyboard input. This property only affects widgets with
+ the WA_InputMethodEnabled attribute set, and is typically used to launch
+ a virtual keyboard on devices which have very few or no keys.
+
+ \bold{ The property only has an effect on platforms which use software input
+ panels, such as Windows CE and Symbian.}
+
+ The default is platform dependent.
+*/
+
+#ifdef Q_WS_WINCE
+void QApplication::setAutoMaximizeThreshold(const int threshold)
+{
+ QApplicationPrivate::autoMaximizeThreshold = threshold;
+}
+
+int QApplication::autoMaximizeThreshold() const
+{
+ return QApplicationPrivate::autoMaximizeThreshold;
+}
+#endif
+
+void QApplication::setAutoSipEnabled(const bool enabled)
+{
+ QApplicationPrivate::autoSipEnabled = enabled;
+}
+
+bool QApplication::autoSipEnabled() const
+{
+ return QApplicationPrivate::autoSipEnabled;
+}
+
+#ifndef QT_NO_STYLE_STYLESHEET
+
+QString QApplication::styleSheet() const
+{
+ return QApplicationPrivate::styleSheet;
+}
+
+void QApplication::setStyleSheet(const QString& styleSheet)
+{
+ QApplicationPrivate::styleSheet = styleSheet;
+ QStyleSheetStyle *proxy = qobject_cast<QStyleSheetStyle*>(QApplicationPrivate::app_style);
+ if (styleSheet.isEmpty()) { // application style sheet removed
+ if (!proxy)
+ return; // there was no stylesheet before
+ setStyle(proxy->base);
+ } else if (proxy) { // style sheet update, just repolish
+ proxy->repolish(qApp);
+ } else { // stylesheet set the first time
+ QStyleSheetStyle *newProxy = new QStyleSheetStyle(QApplicationPrivate::app_style);
+ QApplicationPrivate::app_style->setParent(newProxy);
+ setStyle(newProxy);
+ }
+}
+
+#endif // QT_NO_STYLE_STYLESHEET
+
+/*!
+ Returns the application's style object.
+
+ \sa setStyle(), QStyle
+*/
+QStyle *QApplication::style()
+{
+ if (QApplicationPrivate::app_style)
+ return QApplicationPrivate::app_style;
+ if (!qt_is_gui_used) {
+ Q_ASSERT(!"No style available in non-gui applications!");
+ return 0;
+ }
+
+ if (!QApplicationPrivate::app_style) {
+ // Compile-time search for default style
+ //
+ QString style;
+#ifdef QT_BUILD_INTERNAL
+ QString envStyle = QString::fromLocal8Bit(qgetenv("QT_STYLE_OVERRIDE"));
+#else
+ QString envStyle;
+#endif
+ if (!QApplicationPrivate::styleOverride.isEmpty()) {
+ style = QApplicationPrivate::styleOverride;
+ } else if (!envStyle.isEmpty()) {
+ style = envStyle;
+ } else {
+ style = QApplicationPrivate::desktopStyleKey();
+ }
+
+ QStyle *&app_style = QApplicationPrivate::app_style;
+ app_style = QStyleFactory::create(style);
+ if (!app_style) {
+ QStringList styles = QStyleFactory::keys();
+ for (int i = 0; i < styles.size(); ++i) {
+ if ((app_style = QStyleFactory::create(styles.at(i))))
+ break;
+ }
+ }
+ if (!app_style) {
+ Q_ASSERT(!"No styles available!");
+ return 0;
+ }
+ }
+ // take ownership of the style
+ QApplicationPrivate::app_style->setParent(qApp);
+
+ if (!QApplicationPrivate::sys_pal)
+ QApplicationPrivate::setSystemPalette(QApplicationPrivate::app_style->standardPalette());
+ if (QApplicationPrivate::set_pal) // repolish set palette with the new style
+ QApplication::setPalette(*QApplicationPrivate::set_pal);
+
+#ifndef QT_NO_STYLE_STYLESHEET
+ if (!QApplicationPrivate::styleSheet.isEmpty()) {
+ qApp->setStyleSheet(QApplicationPrivate::styleSheet);
+ } else
+#endif
+ QApplicationPrivate::app_style->polish(qApp);
+
+ return QApplicationPrivate::app_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.
+
+ 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.
+
+ 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.
+
+ \sa style(), QStyle, setPalette(), desktopSettingsAware()
+*/
+void QApplication::setStyle(QStyle *style)
+{
+ if (!style || style == QApplicationPrivate::app_style)
+ return;
+
+ QWidgetList all = allWidgets();
+
+ // clean up the old style
+ if (QApplicationPrivate::app_style) {
+ if (QApplicationPrivate::is_app_running && !QApplicationPrivate::is_app_closing) {
+ for (QWidgetList::ConstIterator it = all.constBegin(); it != all.constEnd(); ++it) {
+ register QWidget *w = *it;
+ if (!(w->windowType() == Qt::Desktop) && // except desktop
+ w->testAttribute(Qt::WA_WState_Polished)) { // has been polished
+ QApplicationPrivate::app_style->unpolish(w);
+ }
+ }
+ }
+ QApplicationPrivate::app_style->unpolish(qApp);
+ }
+
+ QStyle *old = QApplicationPrivate::app_style; // save
+
+#ifndef QT_NO_STYLE_STYLESHEET
+ if (!QApplicationPrivate::styleSheet.isEmpty() && !qobject_cast<QStyleSheetStyle *>(style)) {
+ // we have a stylesheet already and a new style is being set
+ QStyleSheetStyle *newProxy = new QStyleSheetStyle(style);
+ style->setParent(newProxy);
+ QApplicationPrivate::app_style = newProxy;
+ } else
+#endif // QT_NO_STYLE_STYLESHEET
+ QApplicationPrivate::app_style = style;
+ QApplicationPrivate::app_style->setParent(qApp); // take ownership
+
+ // take care of possible palette requirements of certain gui
+ // styles. Do it before polishing the application since the style
+ // might call QApplication::setPalette() itself
+ if (QApplicationPrivate::set_pal) {
+ QApplication::setPalette(*QApplicationPrivate::set_pal);
+ } else if (QApplicationPrivate::sys_pal) {
+ QApplicationPrivate::initializeWidgetPaletteHash();
+ QApplicationPrivate::setPalette_helper(*QApplicationPrivate::sys_pal, /*className=*/0, /*clearWidgetPaletteHash=*/false);
+ } else if (!QApplicationPrivate::sys_pal) {
+ // Initialize the sys_pal if it hasn't happened yet...
+ QApplicationPrivate::setSystemPalette(QApplicationPrivate::app_style->standardPalette());
+ }
+
+ // initialize the application with the new style
+ QApplicationPrivate::app_style->polish(qApp);
+
+ // re-polish existing widgets if necessary
+ if (QApplicationPrivate::is_app_running && !QApplicationPrivate::is_app_closing) {
+ for (QWidgetList::ConstIterator it1 = all.constBegin(); it1 != all.constEnd(); ++it1) {
+ register QWidget *w = *it1;
+ if (w->windowType() != Qt::Desktop && w->testAttribute(Qt::WA_WState_Polished)) {
+ if (w->style() == QApplicationPrivate::app_style)
+ QApplicationPrivate::app_style->polish(w); // repolish
+#ifndef QT_NO_STYLE_STYLESHEET
+ else
+ w->setStyleSheet(w->styleSheet()); // touch
+#endif
+ }
+ }
+
+ for (QWidgetList::ConstIterator it2 = all.constBegin(); it2 != all.constEnd(); ++it2) {
+ register QWidget *w = *it2;
+ if (w->windowType() != Qt::Desktop && !w->testAttribute(Qt::WA_SetStyle)) {
+ QEvent e(QEvent::StyleChange);
+ QApplication::sendEvent(w, &e);
+#ifdef QT3_SUPPORT
+ if (old)
+ w->styleChange(*old);
+#endif
+ w->update();
+ }
+ }
+ }
+
+#ifndef QT_NO_STYLE_STYLESHEET
+ if (QStyleSheetStyle *oldProxy = qobject_cast<QStyleSheetStyle *>(old)) {
+ oldProxy->deref();
+ } else
+#endif
+ if (old && old->parent() == qApp) {
+ delete old;
+ }
+
+ if (QApplicationPrivate::focus_widget) {
+ QFocusEvent in(QEvent::FocusIn, Qt::OtherFocusReason);
+ QApplication::sendEvent(QApplicationPrivate::focus_widget->style(), &in);
+ QApplicationPrivate::focus_widget->update();
+ }
+}
+
+/*!
+ \overload
+
+ 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.
+
+ 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.
+*/
+QStyle* QApplication::setStyle(const QString& style)
+{
+ QStyle *s = QStyleFactory::create(style);
+ if (!s)
+ return 0;
+
+ setStyle(s);
+ return s;
+}
+
+/*!
+ Returns the color specification.
+
+ \sa QApplication::setColorSpec()
+*/
+
+int QApplication::colorSpec()
+{
+ return QApplicationPrivate::app_cspec;
+}
+
+/*!
+ 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 the Windows platform, 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
+
+ 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:
+
+ \snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 2
+
+ \sa colorSpec()
+*/
+
+void QApplication::setColorSpec(int spec)
+{
+ if (qApp)
+ qWarning("QApplication::setColorSpec: This function must be "
+ "called before the QApplication object is created");
+ QApplicationPrivate::app_cspec = spec;
+}
+
+/*!
+ \property QApplication::globalStrut
+ \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.
+
+ Example:
+
+ \snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 3
+
+ By default, this property contains a QSize object with zero width and height.
+*/
+QSize QApplication::globalStrut()
+{
+ return QApplicationPrivate::app_strut;
+}
+
+void QApplication::setGlobalStrut(const QSize& strut)
+{
+ QApplicationPrivate::app_strut = strut;
+}
+
+
+/*!
+ \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 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()
+*/
+QPalette QApplication::palette(const QWidget* w)
+{
+ PaletteHash *hash = app_palettes();
+ if (w && hash && hash->size()) {
+ QHash<QByteArray, QPalette>::ConstIterator it = hash->constFind(w->metaObject()->className());
+ if (it != hash->constEnd())
+ return *it;
+ for (it = hash->constBegin(); it != hash->constEnd(); ++it) {
+ if (w->inherits(it.key()))
+ return it.value();
+ }
+ }
+ return palette();
+}
+
+/*!
+ \overload
+
+ Returns the palette for widgets of the given \a className.
+
+ \sa setPalette(), QWidget::palette()
+*/
+QPalette QApplication::palette(const char *className)
+{
+ if (!QApplicationPrivate::app_pal)
+ palette();
+ PaletteHash *hash = app_palettes();
+ if (className && hash && hash->size()) {
+ QHash<QByteArray, QPalette>::ConstIterator it = hash->constFind(className);
+ if (it != hash->constEnd())
+ return *it;
+ }
+ return *QApplicationPrivate::app_pal;
+}
+
+void QApplicationPrivate::setPalette_helper(const QPalette &palette, const char* className, bool clearWidgetPaletteHash)
+{
+ QPalette pal = palette;
+
+ if (QApplicationPrivate::app_style)
+ QApplicationPrivate::app_style->polish(pal); // NB: non-const reference
+
+ bool all = false;
+ PaletteHash *hash = app_palettes();
+ if (!className) {
+ if (QApplicationPrivate::app_pal && pal.isCopyOf(*QApplicationPrivate::app_pal))
+ return;
+ if (!QApplicationPrivate::app_pal)
+ QApplicationPrivate::app_pal = new QPalette(pal);
+ else
+ *QApplicationPrivate::app_pal = pal;
+ if (hash && hash->size()) {
+ all = true;
+ if (clearWidgetPaletteHash)
+ hash->clear();
+ }
+ } else if (hash) {
+ hash->insert(className, pal);
+ }
+
+ if (QApplicationPrivate::is_app_running && !QApplicationPrivate::is_app_closing) {
+ // Send ApplicationPaletteChange to qApp itself, and to the widgets.
+ QEvent e(QEvent::ApplicationPaletteChange);
+ QApplication::sendEvent(QApplication::instance(), &e);
+
+ QWidgetList wids = QApplication::allWidgets();
+ for (QWidgetList::ConstIterator it = wids.constBegin(); it != wids.constEnd(); ++it) {
+ register QWidget *w = *it;
+ if (all || (!className && w->isWindow()) || w->inherits(className)) // matching class
+ QApplication::sendEvent(w, &e);
+ }
+
+ // Send to all scenes as well.
+#ifndef QT_NO_GRAPHICSVIEW
+ QList<QGraphicsScene *> &scenes = qApp->d_func()->scene_list;
+ for (QList<QGraphicsScene *>::ConstIterator it = scenes.constBegin();
+ it != scenes.constEnd(); ++it) {
+ QApplication::sendEvent(*it, &e);
+ }
+#endif //QT_NO_GRAPHICSVIEW
+ }
+ if (!className && (!QApplicationPrivate::sys_pal || !palette.isCopyOf(*QApplicationPrivate::sys_pal))) {
+ if (!QApplicationPrivate::set_pal)
+ QApplicationPrivate::set_pal = new QPalette(palette);
+ else
+ *QApplicationPrivate::set_pal = 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.
+
+ 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".
+
+ \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()
+*/
+
+void QApplication::setPalette(const QPalette &palette, const char* className)
+{
+ QApplicationPrivate::setPalette_helper(palette, className, /*clearWidgetPaletteHash=*/ true);
+}
+
+
+
+void QApplicationPrivate::setSystemPalette(const QPalette &pal)
+{
+ QPalette adjusted;
+
+#if 0
+ // adjust the system palette to avoid dithering
+ QColormap cmap = QColormap::instance();
+ if (cmap.depths() > 4 && cmap.depths() < 24) {
+ for (int g = 0; g < QPalette::NColorGroups; g++)
+ for (int i = 0; i < QPalette::NColorRoles; i++) {
+ QColor color = pal.color((QPalette::ColorGroup)g, (QPalette::ColorRole)i);
+ color = cmap.colorAt(cmap.pixel(color));
+ adjusted.setColor((QPalette::ColorGroup)g, (QPalette::ColorRole) i, color);
+ }
+ }
+#else
+ adjusted = pal;
+#endif
+
+ if (!sys_pal)
+ sys_pal = new QPalette(adjusted);
+ else
+ *sys_pal = adjusted;
+
+
+ if (!QApplicationPrivate::set_pal)
+ QApplication::setPalette(*sys_pal);
+}
+
+/*!
+ Returns the default application font.
+
+ \sa fontMetrics(), QWidget::font()
+*/
+QFont QApplication::font()
+{
+#ifndef Q_WS_QPA
+ QMutexLocker locker(applicationFontMutex());
+ if (!QApplicationPrivate::app_font)
+ QApplicationPrivate::app_font = new QFont(QLatin1String("Helvetica"));
+ return *QApplicationPrivate::app_font;
+#else
+ return QGuiApplication::font();
+#endif
+}
+
+/*!
+ \overload
+
+ Returns the default font for the \a widget.
+
+ \sa fontMetrics(), QWidget::setFont()
+*/
+
+QFont QApplication::font(const QWidget *widget)
+{
+ FontHash *hash = app_fonts();
+
+#ifdef Q_WS_MAC
+ // short circuit for small and mini controls
+ if (widget->testAttribute(Qt::WA_MacSmallSize)) {
+ return hash->value("QSmallFont");
+ } else if (widget->testAttribute(Qt::WA_MacMiniSize)) {
+ return hash->value("QMiniFont");
+ }
+#endif
+ if (widget && hash && hash->size()) {
+ QHash<QByteArray, QFont>::ConstIterator it =
+ hash->constFind(widget->metaObject()->className());
+ if (it != hash->constEnd())
+ return it.value();
+ for (it = hash->constBegin(); it != hash->constEnd(); ++it) {
+ if (widget->inherits(it.key()))
+ return it.value();
+ }
+ }
+ return font();
+}
+
+/*!
+ \overload
+
+ Returns the font for widgets of the given \a className.
+
+ \sa setFont(), QWidget::font()
+*/
+QFont QApplication::font(const char *className)
+{
+ FontHash *hash = app_fonts();
+ if (className && hash && hash->size()) {
+ QHash<QByteArray, QFont>::ConstIterator it = hash->constFind(className);
+ if (it != hash->constEnd())
+ return *it;
+ }
+ return font();
+}
+
+
+/*!
+ 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.
+
+ \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
+ property. To set a bold font for all QPushButtons, set the application
+ styleSheet() as "QPushButton { font: bold }"
+
+ \sa font(), fontMetrics(), QWidget::setFont()
+*/
+
+void QApplication::setFont(const QFont &font, const char *className)
+{
+ bool all = false;
+ FontHash *hash = app_fonts();
+ if (!className) {
+#ifndef Q_WS_QPA
+ QMutexLocker locker(applicationFontMutex());
+ if (!QApplicationPrivate::app_font)
+ QApplicationPrivate::app_font = new QFont(font);
+ else
+ *QApplicationPrivate::app_font = font;
+#else
+ QGuiApplication::setFont(font);
+#endif
+ if (hash && hash->size()) {
+ all = true;
+ hash->clear();
+ }
+ } else if (hash) {
+ hash->insert(className, font);
+ }
+ if (QApplicationPrivate::is_app_running && !QApplicationPrivate::is_app_closing) {
+ // Send ApplicationFontChange to qApp itself, and to the widgets.
+ QEvent e(QEvent::ApplicationFontChange);
+ QApplication::sendEvent(QApplication::instance(), &e);
+
+ QWidgetList wids = QApplication::allWidgets();
+ for (QWidgetList::ConstIterator it = wids.constBegin(); it != wids.constEnd(); ++it) {
+ register QWidget *w = *it;
+ if (all || (!className && w->isWindow()) || w->inherits(className)) // matching class
+ sendEvent(w, &e);
+ }
+
+#ifndef QT_NO_GRAPHICSVIEW
+ // Send to all scenes as well.
+ QList<QGraphicsScene *> &scenes = qApp->d_func()->scene_list;
+ for (QList<QGraphicsScene *>::ConstIterator it = scenes.constBegin();
+ it != scenes.constEnd(); ++it) {
+ QApplication::sendEvent(*it, &e);
+ }
+#endif //QT_NO_GRAPHICSVIEW
+ }
+ if (!className && (!QApplicationPrivate::sys_font || !font.isCopyOf(*QApplicationPrivate::sys_font))) {
+ if (!QApplicationPrivate::set_font)
+ QApplicationPrivate::set_font = new QFont(font);
+ else
+ *QApplicationPrivate::set_font = font;
+ }
+}
+
+/*! \internal
+*/
+void QApplicationPrivate::setSystemFont(const QFont &font)
+{
+ if (!sys_font)
+ sys_font = new QFont(font);
+ else
+ *sys_font = font;
+
+ if (!QApplicationPrivate::set_font)
+ QApplication::setFont(*sys_font);
+}
+
+/*! \internal
+*/
+QString QApplicationPrivate::desktopStyleKey()
+{
+ return qt_guiPlatformPlugin()->styleName();
+}
+
+/*!
+ \property QApplication::windowIcon
+ \brief the default window icon
+
+ \sa QWidget::setWindowIcon(), {Setting the Application Icon}
+*/
+QIcon QApplication::windowIcon()
+{
+ return QApplicationPrivate::app_icon ? *QApplicationPrivate::app_icon : QIcon();
+}
+
+void QApplication::setWindowIcon(const QIcon &icon)
+{
+ if (!QApplicationPrivate::app_icon)
+ QApplicationPrivate::app_icon = new QIcon();
+ *QApplicationPrivate::app_icon = icon;
+ if (QApplicationPrivate::is_app_running && !QApplicationPrivate::is_app_closing) {
+#ifdef Q_WS_MAC
+ void qt_mac_set_app_icon(const QPixmap &); //qapplication_mac.cpp
+ QSize size = QApplicationPrivate::app_icon->actualSize(QSize(128, 128));
+ qt_mac_set_app_icon(QApplicationPrivate::app_icon->pixmap(size));
+#endif
+ QEvent e(QEvent::ApplicationWindowIconChange);
+ QWidgetList all = QApplication::allWidgets();
+ for (QWidgetList::ConstIterator it = all.constBegin(); it != all.constEnd(); ++it) {
+ register QWidget *w = *it;
+ if (w->isWindow())
+ sendEvent(w, &e);
+ }
+ }
+}
+
+/*!
+ Returns a list of the top-level widgets (windows) in the application.
+
+ \note Some of the top-level widgets may be hidden, for example a tooltip if
+ no tooltip is currently shown.
+
+ Example:
+
+ \snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 4
+
+ \sa allWidgets(), QWidget::isWindow(), QWidget::isHidden()
+*/
+QWidgetList QApplication::topLevelWidgets()
+{
+ QWidgetList list;
+ QWidgetList all = allWidgets();
+
+ for (QWidgetList::ConstIterator it = all.constBegin(); it != all.constEnd(); ++it) {
+ QWidget *w = *it;
+ if (w->isWindow() && w->windowType() != Qt::Desktop)
+ list.append(w);
+ }
+ return list;
+}
+
+/*!
+ Returns a list of all the widgets in the application.
+
+ The list is empty (QList::isEmpty()) if there are no widgets.
+
+ \note Some of the widgets may be hidden.
+
+ Example:
+ \snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 5
+
+ \sa topLevelWidgets(), QWidget::isVisible()
+*/
+
+QWidgetList QApplication::allWidgets()
+{
+ if (QWidgetPrivate::allWidgets)
+ return QWidgetPrivate::allWidgets->toList();
+ return QWidgetList();
+}
+
+/*!
+ 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()
+*/
+
+QWidget *QApplication::focusWidget()
+{
+ return QApplicationPrivate::focus_widget;
+}
+
+void QApplicationPrivate::setFocusWidget(QWidget *focus, Qt::FocusReason reason)
+{
+#ifndef QT_NO_GRAPHICSVIEW
+ if (focus && focus->window()->graphicsProxyWidget())
+ return;
+#endif
+
+ hidden_focus_widget = 0;
+
+ if (focus != focus_widget) {
+ if (focus && focus->isHidden()) {
+ hidden_focus_widget = focus;
+ return;
+ }
+
+ if (focus && (reason == Qt::BacktabFocusReason || reason == Qt::TabFocusReason)
+ && qt_in_tab_key_event)
+ focus->window()->setAttribute(Qt::WA_KeyboardFocusChange);
+ else if (focus && reason == Qt::ShortcutFocusReason) {
+ focus->window()->setAttribute(Qt::WA_KeyboardFocusChange);
+ }
+ QWidget *prev = focus_widget;
+ focus_widget = focus;
+#ifndef QT_NO_IM
+ 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);
+ }
+ }
+#endif //QT_NO_IM
+
+ if(focus_widget)
+ focus_widget->d_func()->setFocus_sys();
+
+ if (reason != Qt::NoFocusReason) {
+
+ //send events
+ if (prev) {
+#ifdef QT_KEYPAD_NAVIGATION
+ if (QApplication::keypadNavigationEnabled()) {
+ if (prev->hasEditFocus() && reason != Qt::PopupFocusReason
+#ifdef Q_OS_SYMBIAN
+ && reason != Qt::ActiveWindowFocusReason
+#endif
+ )
+ prev->setEditFocus(false);
+ }
+#endif
+ QFocusEvent out(QEvent::FocusOut, reason);
+ QPointer<QWidget> that = prev;
+ QApplication::sendEvent(prev, &out);
+ if (that)
+ QApplication::sendEvent(that->style(), &out);
+ }
+ if(focus && QApplicationPrivate::focus_widget == focus) {
+#ifndef QT_NO_IM
+ if (focus->testAttribute(Qt::WA_InputMethodEnabled)) {
+ QInputContext *qic = focus->inputContext();
+ if (qic && focus->testAttribute(Qt::WA_WState_Created)
+ && focus->isEnabled())
+ qic->setFocusWidget(focus);
+ }
+#endif //QT_NO_IM
+ QFocusEvent in(QEvent::FocusIn, reason);
+ QPointer<QWidget> that = focus;
+ QApplication::sendEvent(focus, &in);
+ if (that)
+ QApplication::sendEvent(that->style(), &in);
+ }
+ emit qApp->focusChanged(prev, focus_widget);
+ }
+ }
+}
+
+
+/*!
+ 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()
+*/
+
+QWidget *QApplication::activeWindow()
+{
+ return QApplicationPrivate::active_window;
+}
+
+/*!
+ Returns display (screen) font metrics for the application font.
+
+ \sa font(), setFont(), QWidget::fontMetrics(), QPainter::fontMetrics()
+*/
+
+QFontMetrics QApplication::fontMetrics()
+{
+ return desktop()->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:
+
+ \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.
+
+ \sa quitOnLastWindowClosed, lastWindowClosed(), QWidget::close(),
+ QWidget::closeEvent(), lastWindowClosed(), quit(), topLevelWidgets(),
+ QWidget::isWindow()
+*/
+void QApplication::closeAllWindows()
+{
+ bool did_close = true;
+ QWidget *w;
+ while ((w = activeModalWidget()) && did_close) {
+ if (!w->isVisible() || w->data->is_closing)
+ break;
+ did_close = w->close();
+ }
+ QWidgetList list = QApplication::topLevelWidgets();
+ for (int i = 0; did_close && i < list.size(); ++i) {
+ w = list.at(i);
+ if (w->isVisible()
+ && w->windowType() != Qt::Desktop
+ && !w->data->is_closing) {
+ did_close = w->close();
+ list = QApplication::topLevelWidgets();
+ i = -1;
+ }
+ }
+}
+
+/*!
+ 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 function is a convenience slot for QMessageBox::aboutQt().
+*/
+void QApplication::aboutQt()
+{
+#ifndef QT_NO_MESSAGEBOX
+ QMessageBox::aboutQt(
+#ifdef Q_WS_MAC
+ 0
+#else
+ activeWindow()
+#endif // Q_WS_MAC
+ );
+#endif // QT_NO_MESSAGEBOX
+}
+
+
+/*!
+ \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.
+
+ By default,
+
+ \list
+ \o this attribute is set for all widgets except transient windows such
+ as splash screens, tool windows, and popup menus
+
+ \o QApplication implicitly quits when this signal is emitted.
+ \endlist
+
+ This feature can be turned off by setting \l quitOnLastWindowClosed to
+ false.
+
+ \sa QWidget::close()
+*/
+
+/*!
+ \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. 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.
+
+ \sa QWidget::setFocus(), QWidget::clearFocus(), Qt::FocusReason
+*/
+
+/*!\reimp
+
+*/
+bool QApplication::event(QEvent *e)
+{
+ Q_D(QApplication);
+ if(e->type() == QEvent::Close) {
+#if defined(Q_OS_SYMBIAN)
+ // In order to have proper application-exit effects on Symbian, certain
+ // native APIs have to be called _before_ closing/destroying the widgets.
+ bool effectStarted = qt_beginFullScreenEffect();
+#endif
+ QCloseEvent *ce = static_cast<QCloseEvent*>(e);
+ ce->accept();
+ closeAllWindows();
+
+ QWidgetList list = topLevelWidgets();
+ for (int i = 0; i < list.size(); ++i) {
+ QWidget *w = list.at(i);
+ if (w->isVisible() && !(w->windowType() == Qt::Desktop) && !(w->windowType() == Qt::Popup) &&
+ (!(w->windowType() == Qt::Dialog) || !w->parentWidget())) {
+ ce->ignore();
+ break;
+ }
+ }
+ if (ce->isAccepted()) {
+ return true;
+ } else {
+#if defined(Q_OS_SYMBIAN)
+ if (effectStarted)
+ qt_abortFullScreenEffect();
+#endif
+ }
+#ifndef Q_OS_WIN
+ } else if (e->type() == QEvent::LocaleChange) {
+ // on Windows the event propagation is taken care by the
+ // WM_SETTINGCHANGE event handler.
+ QWidgetList list = topLevelWidgets();
+ for (int i = 0; i < list.size(); ++i) {
+ QWidget *w = list.at(i);
+ if (!(w->windowType() == Qt::Desktop)) {
+ if (!w->testAttribute(Qt::WA_SetLocale))
+ w->d_func()->setLocale_helper(QLocale(), true);
+ }
+ }
+#endif
+ } else if (e->type() == QEvent::Timer) {
+ QTimerEvent *te = static_cast<QTimerEvent*>(e);
+ Q_ASSERT(te != 0);
+ if (te->timerId() == d->toolTipWakeUp.timerId()) {
+ d->toolTipWakeUp.stop();
+ if (d->toolTipWidget) {
+ QWidget *w = d->toolTipWidget->window();
+ // show tooltip if WA_AlwaysShowToolTips is set, or if
+ // any ancestor of d->toolTipWidget is the active
+ // window
+ bool showToolTip = w->testAttribute(Qt::WA_AlwaysShowToolTips);
+ while (w && !showToolTip) {
+ showToolTip = w->isActiveWindow();
+ w = w->parentWidget();
+ w = w ? w->window() : 0;
+ }
+ if (showToolTip) {
+ QHelpEvent e(QEvent::ToolTip, d->toolTipPos, d->toolTipGlobalPos);
+ QApplication::sendEvent(d->toolTipWidget, &e);
+ if (e.isAccepted())
+ d->toolTipFallAsleep.start(2000, this);
+ }
+ }
+ } else if (te->timerId() == d->toolTipFallAsleep.timerId()) {
+ d->toolTipFallAsleep.stop();
+ }
+ }
+ return QApplicationBase::event(e);
+
+ if(e->type() == QEvent::LanguageChange) {
+#if defined(QT_MAC_USE_COCOA)
+ qt_mac_post_retranslateAppMenu();
+#endif
+ QWidgetList list = topLevelWidgets();
+ for (int i = 0; i < list.size(); ++i) {
+ QWidget *w = list.at(i);
+ if (!(w->windowType() == Qt::Desktop))
+ postEvent(w, new QEvent(QEvent::LanguageChange));
+ }
+ }
+
+}
+#if !defined(Q_WS_X11)
+
+// The doc and X implementation of this function is in qapplication_x11.cpp
+
+void QApplication::syncX() {} // do nothing
+
+#endif
+
+void QApplicationPrivate::notifyLayoutDirectionChange()
+{
+ Q_Q(QApplication);
+ QWidgetList list = q->topLevelWidgets();
+ for (int i = 0; i < list.size(); ++i) {
+ QWidget *w = list.at(i);
+ QEvent ev(QEvent::ApplicationLayoutDirectionChange);
+ q->sendEvent(w, &ev);
+ }
+}
+
+/*!
+ \fn Qt::WindowsVersion QApplication::winVersion()
+
+ Use \l QSysInfo::WindowsVersion instead.
+*/
+
+/*!
+ \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.
+
+ \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.
+
+ \sa activeWindow(), QWidget::activateWindow()
+*/
+void QApplication::setActiveWindow(QWidget* act)
+{
+ QWidget* window = act?act->window():0;
+
+ if (QApplicationPrivate::active_window == window)
+ return;
+
+#ifndef QT_NO_GRAPHICSVIEW
+ if (window && window->graphicsProxyWidget()) {
+ // Activate the proxy's view->viewport() ?
+ return;
+ }
+#endif
+
+ QWidgetList toBeActivated;
+ QWidgetList toBeDeactivated;
+
+ if (QApplicationPrivate::active_window) {
+ if (style()->styleHint(QStyle::SH_Widget_ShareActivation, 0, QApplicationPrivate::active_window)) {
+ QWidgetList list = topLevelWidgets();
+ for (int i = 0; i < list.size(); ++i) {
+ QWidget *w = list.at(i);
+ if (w->isVisible() && w->isActiveWindow())
+ toBeDeactivated.append(w);
+ }
+ } else {
+ toBeDeactivated.append(QApplicationPrivate::active_window);
+ }
+ }
+
+#if !defined(Q_WS_MAC)
+ QWidget *previousActiveWindow = QApplicationPrivate::active_window;
+#endif
+ QApplicationPrivate::active_window = window;
+
+ if (QApplicationPrivate::active_window) {
+ if (style()->styleHint(QStyle::SH_Widget_ShareActivation, 0, QApplicationPrivate::active_window)) {
+ QWidgetList list = topLevelWidgets();
+ for (int i = 0; i < list.size(); ++i) {
+ QWidget *w = list.at(i);
+ if (w->isVisible() && w->isActiveWindow())
+ toBeActivated.append(w);
+ }
+ } else {
+ toBeActivated.append(QApplicationPrivate::active_window);
+ }
+
+ }
+
+ // first the activation/deactivation events
+ QEvent activationChange(QEvent::ActivationChange);
+ QEvent windowActivate(QEvent::WindowActivate);
+ QEvent windowDeactivate(QEvent::WindowDeactivate);
+
+#if !defined(Q_WS_MAC)
+ if (!previousActiveWindow) {
+ QEvent appActivate(QEvent::ApplicationActivate);
+ sendSpontaneousEvent(qApp, &appActivate);
+ }
+#endif
+
+ for (int i = 0; i < toBeActivated.size(); ++i) {
+ QWidget *w = toBeActivated.at(i);
+ sendSpontaneousEvent(w, &windowActivate);
+ sendSpontaneousEvent(w, &activationChange);
+ }
+
+#ifdef QT_MAC_USE_COCOA
+ // In case the user clicked on a child window, we need to
+ // reestablish the stacking order of the window so
+ // it pops in front of other child windows in cocoa:
+ qt_cocoaStackChildWindowOnTopOfOtherChildren(window);
+#endif
+
+ for(int i = 0; i < toBeDeactivated.size(); ++i) {
+ QWidget *w = toBeDeactivated.at(i);
+ sendSpontaneousEvent(w, &windowDeactivate);
+ sendSpontaneousEvent(w, &activationChange);
+ }
+
+#if !defined(Q_WS_MAC)
+ if (!QApplicationPrivate::active_window) {
+ QEvent appDeactivate(QEvent::ApplicationDeactivate);
+ sendSpontaneousEvent(qApp, &appDeactivate);
+ }
+#endif
+
+ if (QApplicationPrivate::popupWidgets == 0) { // !inPopupMode()
+ // then focus events
+ if (!QApplicationPrivate::active_window && QApplicationPrivate::focus_widget) {
+ QApplicationPrivate::setFocusWidget(0, Qt::ActiveWindowFocusReason);
+ } else if (QApplicationPrivate::active_window) {
+ QWidget *w = QApplicationPrivate::active_window->focusWidget();
+ if (w && w->isVisible() /*&& w->focusPolicy() != QWidget::NoFocus*/)
+ w->setFocus(Qt::ActiveWindowFocusReason);
+ else {
+ w = QApplicationPrivate::focusNextPrevChild_helper(QApplicationPrivate::active_window, true);
+ if (w) {
+ w->setFocus(Qt::ActiveWindowFocusReason);
+ } else {
+ // If the focus widget is not in the activate_window, clear the focus
+ w = QApplicationPrivate::focus_widget;
+ 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);
+ }
+ }
+ }
+ }
+}
+
+/*!internal
+ * Helper function that returns the new focus widget, but does not set the focus reason.
+ * Returns 0 if a new focus widget could not be found.
+ * Shared with QGraphicsProxyWidgetPrivate::findFocusChild()
+*/
+QWidget *QApplicationPrivate::focusNextPrevChild_helper(QWidget *toplevel, bool next)
+{
+ uint focus_flag = qt_tab_all_widgets ? Qt::TabFocus : Qt::StrongFocus;
+
+ QWidget *f = toplevel->focusWidget();
+ if (!f)
+ f = toplevel;
+
+ QWidget *w = f;
+ QWidget *test = f->d_func()->focus_next;
+ while (test && test != f) {
+ if ((test->focusPolicy() & focus_flag) == focus_flag
+ && !(test->d_func()->extra && test->d_func()->extra->focus_proxy)
+ && test->isVisibleTo(toplevel) && test->isEnabled()
+ && !(w->windowType() == Qt::SubWindow && !w->isAncestorOf(test))
+ && (toplevel->windowType() != Qt::SubWindow || toplevel->isAncestorOf(test))) {
+ w = test;
+ if (next)
+ break;
+ }
+ test = test->d_func()->focus_next;
+ }
+ if (w == f) {
+ if (qt_in_tab_key_event) {
+ w->window()->setAttribute(Qt::WA_KeyboardFocusChange);
+ w->update();
+ }
+ return 0;
+ }
+ return w;
+}
+
+/*!
+ \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.
+ */
+void QApplicationPrivate::dispatchEnterLeave(QWidget* enter, QWidget* leave) {
+#if 0
+ if (leave) {
+ QEvent e(QEvent::Leave);
+ QApplication::sendEvent(leave, & e);
+ }
+ if (enter) {
+ QEvent e(QEvent::Enter);
+ QApplication::sendEvent(enter, & e);
+ }
+ return;
+#endif
+
+ QWidget* w ;
+ if ((!enter && !leave) || (enter == leave))
+ return;
+#ifdef ALIEN_DEBUG
+ qDebug() << "QApplicationPrivate::dispatchEnterLeave, ENTER:" << enter << "LEAVE:" << leave;
+#endif
+ QWidgetList leaveList;
+ QWidgetList enterList;
+
+ bool sameWindow = leave && enter && leave->window() == enter->window();
+ if (leave && !sameWindow) {
+ w = leave;
+ do {
+ leaveList.append(w);
+ } while (!w->isWindow() && (w = w->parentWidget()));
+ }
+ if (enter && !sameWindow) {
+ w = enter;
+ do {
+ enterList.prepend(w);
+ } while (!w->isWindow() && (w = w->parentWidget()));
+ }
+ if (sameWindow) {
+ int enterDepth = 0;
+ int leaveDepth = 0;
+ w = enter;
+ while (!w->isWindow() && (w = w->parentWidget()))
+ enterDepth++;
+ w = leave;
+ while (!w->isWindow() && (w = w->parentWidget()))
+ leaveDepth++;
+ QWidget* wenter = enter;
+ QWidget* wleave = leave;
+ while (enterDepth > leaveDepth) {
+ wenter = wenter->parentWidget();
+ enterDepth--;
+ }
+ while (leaveDepth > enterDepth) {
+ wleave = wleave->parentWidget();
+ leaveDepth--;
+ }
+ while (!wenter->isWindow() && wenter != wleave) {
+ wenter = wenter->parentWidget();
+ wleave = wleave->parentWidget();
+ }
+
+ w = leave;
+ while (w != wleave) {
+ leaveList.append(w);
+ w = w->parentWidget();
+ }
+ w = enter;
+ while (w != wenter) {
+ enterList.prepend(w);
+ w = w->parentWidget();
+ }
+ }
+
+ QEvent leaveEvent(QEvent::Leave);
+ for (int i = 0; i < leaveList.size(); ++i) {
+ w = leaveList.at(i);
+ if (!QApplication::activeModalWidget() || QApplicationPrivate::tryModalHelper(w, 0)) {
+#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined(Q_WS_MAC)
+ if (leaveAfterRelease == w)
+ leaveAfterRelease = 0;
+#endif
+ QApplication::sendEvent(w, &leaveEvent);
+ if (w->testAttribute(Qt::WA_Hover) &&
+ (!QApplication::activePopupWidget() || QApplication::activePopupWidget() == w->window())) {
+ Q_ASSERT(instance());
+ QHoverEvent he(QEvent::HoverLeave, QPoint(-1, -1), w->mapFromGlobal(QApplicationPrivate::instance()->hoverGlobalPos),
+ QApplication::keyboardModifiers());
+ qApp->d_func()->notify_helper(w, &he);
+ }
+ }
+ }
+ QPoint posEnter = QCursor::pos();
+ QEvent enterEvent(QEvent::Enter);
+ for (int i = 0; i < enterList.size(); ++i) {
+ w = enterList.at(i);
+ if (!QApplication::activeModalWidget() || QApplicationPrivate::tryModalHelper(w, 0)) {
+ QApplication::sendEvent(w, &enterEvent);
+ if (w->testAttribute(Qt::WA_Hover) &&
+ (!QApplication::activePopupWidget() || QApplication::activePopupWidget() == w->window())) {
+ QHoverEvent he(QEvent::HoverEnter, w->mapFromGlobal(posEnter), QPoint(-1, -1),
+ QApplication::keyboardModifiers());
+ qApp->d_func()->notify_helper(w, &he);
+ }
+ }
+ }
+
+#ifndef QT_NO_CURSOR
+ // Update cursor for alien/graphics widgets.
+
+ const bool enterOnAlien = (enter && (isAlien(enter) || enter->testAttribute(Qt::WA_DontShowOnScreen)));
+#if defined(Q_WS_X11) || defined(Q_WS_QPA)
+ //Whenever we leave an alien widget on X11, we need to reset its nativeParentWidget()'s cursor.
+ // This is not required on Windows as the cursor is reset on every single mouse move.
+ QWidget *parentOfLeavingCursor = 0;
+ for (int i = 0; i < leaveList.size(); ++i) {
+ w = leaveList.at(i);
+ if (!isAlien(w))
+ break;
+ if (w->testAttribute(Qt::WA_SetCursor)) {
+ QWidget *parent = w->parentWidget();
+ while (parent && parent->d_func()->data.in_destructor)
+ parent = parent->parentWidget();
+ parentOfLeavingCursor = parent;
+ //continue looping, we need to find the downest alien widget with a cursor.
+ // (downest on the screen)
+ }
+ }
+ //check that we will not call qt_x11_enforce_cursor twice with the same native widget
+ if (parentOfLeavingCursor && (!enterOnAlien
+ || parentOfLeavingCursor->effectiveWinId() != enter->effectiveWinId())) {
+#ifndef QT_NO_GRAPHICSVIEW
+ if (!parentOfLeavingCursor->window()->graphicsProxyWidget())
+#endif
+ {
+#if defined(Q_WS_X11)
+ qt_x11_enforce_cursor(parentOfLeavingCursor,true);
+#elif defined(Q_WS_QPA)
+ if (enter == QApplication::desktop()) {
+ qt_qpa_set_cursor(enter, true);
+ } else {
+ qt_qpa_set_cursor(parentOfLeavingCursor, true);
+ }
+#endif
+ }
+ }
+#endif
+ if (enterOnAlien) {
+ QWidget *cursorWidget = enter;
+ while (!cursorWidget->isWindow() && !cursorWidget->isEnabled())
+ cursorWidget = cursorWidget->parentWidget();
+
+ if (!cursorWidget)
+ return;
+
+#ifndef QT_NO_GRAPHICSVIEW
+ if (cursorWidget->window()->graphicsProxyWidget()) {
+ QWidgetPrivate::nearestGraphicsProxyWidget(cursorWidget)->setCursor(cursorWidget->cursor());
+ } else
+#endif
+ {
+#if defined(Q_WS_WIN)
+ qt_win_set_cursor(cursorWidget, true);
+#elif defined(Q_WS_X11)
+ qt_x11_enforce_cursor(cursorWidget, true);
+#elif defined(Q_OS_SYMBIAN)
+ qt_symbian_set_cursor(cursorWidget, true);
+#elif defined(Q_WS_QPA)
+ qt_qpa_set_cursor(cursorWidget, true);
+#endif
+ }
+ }
+#endif
+}
+
+/* exported for the benefit of testing tools */
+Q_WIDGETS_EXPORT bool qt_tryModalHelper(QWidget *widget, QWidget **rettop)
+{
+ return QApplicationPrivate::tryModalHelper(widget, rettop);
+}
+
+/*! \internal
+ Returns true if \a widget is blocked by a modal window.
+ */
+bool QApplicationPrivate::isBlockedByModal(QWidget *widget)
+{
+ widget = widget->window();
+ if (!modalState())
+ return false;
+ if (QApplication::activePopupWidget() == widget)
+ return false;
+
+ for (int i = 0; i < qt_modal_stack->size(); ++i) {
+ QWidget *modalWidget = qt_modal_stack->at(i);
+
+ {
+ // check if the active modal widget is our widget or a parent of our widget
+ QWidget *w = widget;
+ while (w) {
+ if (w == modalWidget)
+ return false;
+ w = w->parentWidget();
+ }
+#ifdef Q_WS_WIN
+ if ((widget->testAttribute(Qt::WA_WState_Created) || widget->data->winid)
+ && (modalWidget->testAttribute(Qt::WA_WState_Created) || modalWidget->data->winid)
+ && IsChild(modalWidget->data->winid, widget->data->winid))
+ return false;
+#endif
+ }
+
+ Qt::WindowModality windowModality = modalWidget->windowModality();
+ if (windowModality == Qt::NonModal) {
+ // determine the modality type if it hasn't been set on the
+ // modalWidget, this normally happens when waiting for a
+ // native dialog. use WindowModal if we are the child of a
+ // group leader; otherwise use ApplicationModal.
+ QWidget *m = modalWidget;
+ while (m && !m->testAttribute(Qt::WA_GroupLeader)) {
+ m = m->parentWidget();
+ if (m)
+ m = m->window();
+ }
+ windowModality = (m && m->testAttribute(Qt::WA_GroupLeader))
+ ? Qt::WindowModal
+ : Qt::ApplicationModal;
+ }
+
+ switch (windowModality) {
+ case Qt::ApplicationModal:
+ {
+ QWidget *groupLeaderForWidget = widget;
+ while (groupLeaderForWidget && !groupLeaderForWidget->testAttribute(Qt::WA_GroupLeader))
+ groupLeaderForWidget = groupLeaderForWidget->parentWidget();
+
+ if (groupLeaderForWidget) {
+ // if \a widget has WA_GroupLeader, it can only be blocked by ApplicationModal children
+ QWidget *m = modalWidget;
+ while (m && m != groupLeaderForWidget && !m->testAttribute(Qt::WA_GroupLeader))
+ m = m->parentWidget();
+ if (m == groupLeaderForWidget)
+ return true;
+ } else if (modalWidget != widget) {
+ return true;
+ }
+ break;
+ }
+ case Qt::WindowModal:
+ {
+ QWidget *w = widget;
+ do {
+ QWidget *m = modalWidget;
+ do {
+ if (m == w)
+ return true;
+ m = m->parentWidget();
+ if (m)
+ m = m->window();
+ } while (m);
+ w = w->parentWidget();
+ if (w)
+ w = w->window();
+ } while (w);
+ break;
+ }
+ default:
+ Q_ASSERT_X(false, "QApplication", "internal error, a modal widget cannot be modeless");
+ break;
+ }
+ }
+ return false;
+}
+
+/*!\internal
+ */
+void QApplicationPrivate::enterModal(QWidget *widget)
+{
+ QSet<QWidget*> blocked;
+ QList<QWidget*> windows = QApplication::topLevelWidgets();
+ for (int i = 0; i < windows.count(); ++i) {
+ QWidget *window = windows.at(i);
+ if (window->windowType() != Qt::Tool && isBlockedByModal(window))
+ blocked.insert(window);
+ }
+
+ enterModal_sys(widget);
+
+ windows = QApplication::topLevelWidgets();
+ QEvent e(QEvent::WindowBlocked);
+ for (int i = 0; i < windows.count(); ++i) {
+ QWidget *window = windows.at(i);
+ if (!blocked.contains(window) && window->windowType() != Qt::Tool && isBlockedByModal(window))
+ QApplication::sendEvent(window, &e);
+ }
+}
+
+/*!\internal
+ */
+void QApplicationPrivate::leaveModal(QWidget *widget)
+{
+ QSet<QWidget*> blocked;
+ QList<QWidget*> windows = QApplication::topLevelWidgets();
+ for (int i = 0; i < windows.count(); ++i) {
+ QWidget *window = windows.at(i);
+ if (window->windowType() != Qt::Tool && isBlockedByModal(window))
+ blocked.insert(window);
+ }
+
+ leaveModal_sys(widget);
+
+ windows = QApplication::topLevelWidgets();
+ QEvent e(QEvent::WindowUnblocked);
+ for (int i = 0; i < windows.count(); ++i) {
+ QWidget *window = windows.at(i);
+ if(blocked.contains(window) && window->windowType() != Qt::Tool && !isBlockedByModal(window))
+ QApplication::sendEvent(window, &e);
+ }
+}
+
+
+
+/*!\internal
+
+ Called from qapplication_\e{platform}.cpp, returns true
+ if the widget should accept the event.
+ */
+bool QApplicationPrivate::tryModalHelper(QWidget *widget, QWidget **rettop)
+{
+ QWidget *top = QApplication::activeModalWidget();
+ if (rettop)
+ *rettop = top;
+
+ // the active popup widget always gets the input event
+ if (QApplication::activePopupWidget())
+ return true;
+
+#if defined(Q_WS_MAC) && defined(QT_MAC_USE_COCOA)
+ top = QApplicationPrivate::tryModalHelper_sys(top);
+ if (rettop)
+ *rettop = top;
+#endif
+
+ return !isBlockedByModal(widget->window());
+}
+
+/*
+ \internal
+*/
+QWidget *QApplicationPrivate::pickMouseReceiver(QWidget *candidate, const QPoint &globalPos,
+ QPoint &pos, QEvent::Type type,
+ Qt::MouseButtons buttons, QWidget *buttonDown,
+ QWidget *alienWidget)
+{
+ Q_ASSERT(candidate);
+
+ QWidget *mouseGrabber = QWidget::mouseGrabber();
+ if (((type == QEvent::MouseMove && buttons) || (type == QEvent::MouseButtonRelease))
+ && !buttonDown && !mouseGrabber) {
+ return 0;
+ }
+
+ if (alienWidget && alienWidget->internalWinId())
+ alienWidget = 0;
+
+ QWidget *receiver = candidate;
+
+ if (!mouseGrabber)
+ mouseGrabber = (buttonDown && !isBlockedByModal(buttonDown)) ? buttonDown : alienWidget;
+
+ if (mouseGrabber && mouseGrabber != candidate) {
+ receiver = mouseGrabber;
+ pos = receiver->mapFromGlobal(globalPos);
+#ifdef ALIEN_DEBUG
+ qDebug() << " ** receiver adjusted to:" << receiver << "pos:" << pos;
+#endif
+ }
+
+ return receiver;
+
+}
+
+/*
+ \internal
+*/
+bool QApplicationPrivate::sendMouseEvent(QWidget *receiver, QMouseEvent *event,
+ QWidget *alienWidget, QWidget *nativeWidget,
+ QWidget **buttonDown, QPointer<QWidget> &lastMouseReceiver,
+ bool spontaneous)
+{
+ Q_ASSERT(receiver);
+ Q_ASSERT(event);
+ Q_ASSERT(nativeWidget);
+ Q_ASSERT(buttonDown);
+
+ if (alienWidget && !isAlien(alienWidget))
+ alienWidget = 0;
+
+ QPointer<QWidget> receiverGuard = receiver;
+ QPointer<QWidget> nativeGuard = nativeWidget;
+ QPointer<QWidget> alienGuard = alienWidget;
+ QPointer<QWidget> activePopupWidget = QApplication::activePopupWidget();
+
+ const bool graphicsWidget = nativeWidget->testAttribute(Qt::WA_DontShowOnScreen);
+
+ if (*buttonDown) {
+ if (!graphicsWidget) {
+ // Register the widget that shall receive a leave event
+ // after the last button is released.
+ if ((alienWidget || !receiver->internalWinId()) && !leaveAfterRelease && !QWidget::mouseGrabber())
+ leaveAfterRelease = *buttonDown;
+ if (event->type() == QEvent::MouseButtonRelease && !event->buttons())
+ *buttonDown = 0;
+ }
+ } else if (lastMouseReceiver) {
+ // Dispatch enter/leave if we move:
+ // 1) from an alien widget to another alien widget or
+ // from a native widget to an alien widget (first OR case)
+ // 2) from an alien widget to a native widget (second OR case)
+ if ((alienWidget && alienWidget != lastMouseReceiver)
+ || (isAlien(lastMouseReceiver) && !alienWidget)) {
+ if (activePopupWidget) {
+ if (!QWidget::mouseGrabber())
+ dispatchEnterLeave(alienWidget ? alienWidget : nativeWidget, lastMouseReceiver);
+ } else {
+ dispatchEnterLeave(receiver, lastMouseReceiver);
+ }
+
+ }
+ }
+
+#ifdef ALIEN_DEBUG
+ qDebug() << "QApplicationPrivate::sendMouseEvent: receiver:" << receiver
+ << "pos:" << event->pos() << "alien" << alienWidget << "button down"
+ << *buttonDown << "last" << lastMouseReceiver << "leave after release"
+ << leaveAfterRelease;
+#endif
+
+ // We need this quard in case someone opens a modal dialog / popup. If that's the case
+ // leaveAfterRelease is set to null, but we shall not update lastMouseReceiver.
+ const bool wasLeaveAfterRelease = leaveAfterRelease != 0;
+ bool result;
+ if (spontaneous)
+ result = QApplication::sendSpontaneousEvent(receiver, event);
+ else
+ result = QApplication::sendEvent(receiver, event);
+
+ if (!graphicsWidget && leaveAfterRelease && event->type() == QEvent::MouseButtonRelease
+ && !event->buttons() && QWidget::mouseGrabber() != leaveAfterRelease) {
+ // Dispatch enter/leave if:
+ // 1) the mouse grabber is an alien widget
+ // 2) the button is released on an alien widget
+ QWidget *enter = 0;
+ if (nativeGuard)
+ enter = alienGuard ? alienWidget : nativeWidget;
+ else // The receiver is typically deleted on mouse release with drag'n'drop.
+ enter = QApplication::widgetAt(event->globalPos());
+ dispatchEnterLeave(enter, leaveAfterRelease);
+ leaveAfterRelease = 0;
+ lastMouseReceiver = enter;
+ } else if (!wasLeaveAfterRelease) {
+ if (activePopupWidget) {
+ if (!QWidget::mouseGrabber())
+ lastMouseReceiver = alienGuard ? alienWidget : (nativeGuard ? nativeWidget : 0);
+ } else {
+ lastMouseReceiver = receiverGuard ? receiver : QApplication::widgetAt(event->globalPos());
+ }
+ }
+
+ return result;
+}
+
+#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_WS_MAC) || defined(Q_WS_QPA)
+/*
+ This function should only be called when the widget changes visibility, i.e.
+ when the \a widget is shown, hidden or deleted. This function does nothing
+ if the widget is a top-level or native, i.e. not an alien widget. In that
+ case enter/leave events are genereated by the underlying windowing system.
+*/
+extern QPointer<QWidget> qt_last_mouse_receiver;
+extern QWidget *qt_button_down;
+void QApplicationPrivate::sendSyntheticEnterLeave(QWidget *widget)
+{
+#ifndef QT_NO_CURSOR
+#if defined(Q_WS_QWS) || defined(Q_WS_QPA)
+ if (!widget || widget->isWindow())
+ return;
+#else
+ if (!widget || widget->internalWinId() || widget->isWindow())
+ return;
+#endif
+ const bool widgetInShow = widget->isVisible() && !widget->data->in_destructor;
+ if (!widgetInShow && widget != qt_last_mouse_receiver)
+ return; // Widget was not under the cursor when it was hidden/deleted.
+
+ if (widgetInShow && widget->parentWidget()->data->in_show)
+ return; // Ingore recursive show.
+
+ QWidget *mouseGrabber = QWidget::mouseGrabber();
+ if (mouseGrabber && mouseGrabber != widget)
+ return; // Someone else has the grab; enter/leave should not occur.
+
+ QWidget *tlw = widget->window();
+ if (tlw->data->in_destructor || tlw->data->is_closing)
+ return; // Closing down the business.
+
+ if (widgetInShow && (!qt_last_mouse_receiver || qt_last_mouse_receiver->window() != tlw))
+ return; // Mouse cursor not inside the widget's top-level.
+
+ const QPoint globalPos(QCursor::pos());
+ QPoint windowPos = tlw->mapFromGlobal(globalPos);
+
+ // Find the current widget under the mouse. If this function was called from
+ // the widget's destructor, we have to make sure childAt() doesn't take into
+ // account widgets that are about to be destructed.
+ QWidget *widgetUnderCursor = tlw->d_func()->childAt_helper(windowPos, widget->data->in_destructor);
+ if (!widgetUnderCursor)
+ widgetUnderCursor = tlw;
+ QPoint pos = widgetUnderCursor->mapFrom(tlw, windowPos);
+
+ if (widgetInShow && widgetUnderCursor != widget && !widget->isAncestorOf(widgetUnderCursor))
+ return; // Mouse cursor not inside the widget or any of its children.
+
+ if (widget->data->in_destructor && qt_button_down == widget)
+ qt_button_down = 0;
+
+ // Send enter/leave events followed by a mouse move on the entered widget.
+ QMouseEvent e(QEvent::MouseMove, pos, windowPos, globalPos, Qt::NoButton, Qt::NoButton, Qt::NoModifier);
+ sendMouseEvent(widgetUnderCursor, &e, widgetUnderCursor, tlw, &qt_button_down, qt_last_mouse_receiver);
+#endif // QT_NO_CURSOR
+}
+#endif // Q_WS_WIN || Q_WS_X11 || Q_WS_MAC
+
+/*!
+ Returns the desktop widget (also called the root window).
+
+ 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.
+*/
+QDesktopWidget *QApplication::desktop()
+{
+ if (!qt_desktopWidget || // not created yet
+ !(qt_desktopWidget->windowType() == Qt::Desktop)) { // reparented away
+ qt_desktopWidget = new QDesktopWidget();
+ }
+ return qt_desktopWidget;
+}
+
+#if !defined(Q_WS_QPA) && !defined(QT_NO_CLIPBOARD)
+/*!
+ Returns a pointer to the application global clipboard.
+
+ \note The QApplication object should already be constructed before
+ accessing the clipboard.
+*/
+QClipboard *QApplication::clipboard()
+{
+ if (qt_clipboard == 0) {
+ if (!qApp) {
+ qWarning("QApplication: Must construct a QApplication before accessing a QClipboard");
+ return 0;
+ }
+ qt_clipboard = new QClipboard(0);
+ }
+ return qt_clipboard;
+}
+#endif // Q_WS_QPA && QT_NO_CLIPBOARD
+/*!
+ 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:
+
+ \snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 6
+
+ \sa desktopSettingsAware()
+*/
+void QApplication::setDesktopSettingsAware(bool on)
+{
+ QApplicationPrivate::obey_desktop_settings = on;
+}
+
+/*!
+ Returns true if Qt is set to use the system's standard colors, fonts, etc.;
+ otherwise returns false. The default is true.
+
+ \sa setDesktopSettingsAware()
+*/
+bool QApplication::desktopSettingsAware()
+{
+ return QApplicationPrivate::obey_desktop_settings;
+}
+
+/*!
+ 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.
+
+ \sa mouseButtons(), queryKeyboardModifiers()
+*/
+
+Qt::KeyboardModifiers QApplication::keyboardModifiers()
+{
+ return QApplicationPrivate::modifier_buttons;
+}
+
+/*!
+ \fn Qt::KeyboardModifiers QApplication::queryKeyboardModifiers()
+
+ Queries and returns the state of the modifier keys on the keyboard.
+ Unlike keyboardModifiers, this method returns the actual keys held
+ on the input device at the time of calling the method.
+
+ It does not rely on the keypress events having been received by this
+ process, which makes it possible to check the modifiers while moving
+ a window, for instance. Note that in most cases, you should use
+ keyboardModifiers(), which is faster and more accurate since it contains
+ the state of the modifiers as they were when the currently processed
+ event was received.
+
+ \sa keyboardModifiers()
+
+ \since 4.8
+*/
+
+Qt::KeyboardModifiers QApplication::queryKeyboardModifiers()
+{
+ qWarning("queryKeyboardModifiers() doesn't have a QPA implementation");
+ return QApplicationPrivate::modifier_buttons;
+}
+
+/*!
+ 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 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()
+*/
+
+Qt::MouseButtons QApplication::mouseButtons()
+{
+ return QApplicationPrivate::mouse_buttons;
+}
+
+/*!
+ \fn bool QApplication::isSessionRestored() const
+
+ Returns true if the application has been restored from an earlier
+ \l{Session Management}{session}; otherwise returns false.
+
+ \sa sessionId(), commitData(), saveState()
+*/
+
+
+/*!
+ \fn QString QApplication::sessionId() const
+
+ 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. 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()
+*/
+
+/*!
+ \fn QString QApplication::sessionKey() const
+
+ 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.
+
+ The session key changes with every call of commitData() or saveState().
+
+ \sa isSessionRestored(), sessionId(), commitData(), saveState()
+*/
+#ifndef QT_NO_SESSIONMANAGER
+bool QApplication::isSessionRestored() const
+{
+ Q_D(const QApplication);
+ return d->is_session_restored;
+}
+
+QString QApplication::sessionId() const
+{
+ Q_D(const QApplication);
+ return d->session_id;
+}
+
+QString QApplication::sessionKey() const
+{
+ Q_D(const QApplication);
+ return d->session_key;
+}
+#endif
+
+
+
+/*!
+ \since 4.2
+ \fn void QApplication::commitDataRequest(QSessionManager &manager)
+
+ 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.
+
+ 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.
+
+ \note You should use Qt::DirectConnection when connecting to this signal.
+
+ \sa isSessionRestored(), sessionId(), saveState(), {Session Management}
+*/
+
+/*!
+ 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.
+
+ 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.
+
+ 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}
+*/
+#ifndef QT_NO_SESSIONMANAGER
+void QApplication::commitData(QSessionManager& manager )
+{
+ emit commitDataRequest(manager);
+ if (manager.allowsInteraction()) {
+ QWidgetList done;
+ QWidgetList list = QApplication::topLevelWidgets();
+ bool cancelled = false;
+ for (int i = 0; !cancelled && i < list.size(); ++i) {
+ QWidget* w = list.at(i);
+ if (w->isVisible() && !done.contains(w)) {
+ cancelled = !w->close();
+ if (!cancelled)
+ done.append(w);
+ list = QApplication::topLevelWidgets();
+ i = -1;
+ }
+ }
+ if (cancelled)
+ manager.cancel();
+ }
+}
+
+/*!
+ \since 4.2
+ \fn void QApplication::saveStateRequest(QSessionManager &manager)
+
+ 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.
+
+ 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.
+
+ \note You should use Qt::DirectConnection when connecting to this signal.
+
+ \sa isSessionRestored(), sessionId(), commitData(), {Session Management}
+*/
+
+/*!
+ 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.
+
+ 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.
+
+ \sa isSessionRestored(), sessionId(), commitData(), {Session Management}
+*/
+
+void QApplication::saveState(QSessionManager &manager)
+{
+ emit saveStateRequest(manager);
+}
+#endif //QT_NO_SESSIONMANAGER
+/*
+ Sets the time after which a drag should start to \a ms ms.
+
+ \sa startDragTime()
+*/
+
+void QApplication::setStartDragTime(int ms)
+{
+ Q_UNUSED(ms)
+}
+
+/*!
+ \property QApplication::startDragTime
+ \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.
+
+ Qt also uses this delay internally, e.g. in QTextEdit and QLineEdit, for
+ starting a drag.
+
+ The default value is 500 ms.
+
+ \sa startDragDistance(), {Drag and Drop}
+*/
+
+int QApplication::startDragTime()
+{
+ return qApp->styleHints()->startDragTime();
+}
+
+/*
+ Sets the distance after which a drag should start to \a l pixels.
+
+ \sa startDragDistance()
+*/
+
+void QApplication::setStartDragDistance(int l)
+{
+ Q_UNUSED(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.
+
+ 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
+
+ Qt uses this value internally, e.g. in QFileDialog.
+
+ The default value is 4 pixels.
+
+ \sa startDragTime() QPoint::manhattanLength() {Drag and Drop}
+*/
+
+int QApplication::startDragDistance()
+{
+ return qApp->styleHints()->startDragTime();
+}
+
+/*!
+ \fn void QApplication::setReverseLayout(bool reverse)
+
+ Use setLayoutDirection() instead.
+*/
+
+/*!
+ \fn void QApplication::reverseLayout()
+
+ Use layoutDirection() instead.
+*/
+
+
+/*!
+ \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.
+*/
+
+#ifdef QT3_SUPPORT
+Qt::Alignment QApplication::horizontalAlignment(Qt::Alignment align)
+{
+ return QGuiApplicationPrivate::visualAlignment(layoutDirection(), align);
+}
+#endif
+
+/*!
+ Enters the main event loop and waits until exit() is called, then returns
+ 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.
+
+ 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.
+
+ 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. This is because, on some platforms the
+ QApplication::exec() call may not return. For example, on the Windows
+ platform, when the user logs off, the system terminates the process after Qt
+ closes all top-level windows. Hence, there is \e{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()
+*/
+int QApplication::exec()
+{
+#ifndef QT_NO_ACCESSIBILITY
+ QAccessible::setRootObject(qApp);
+#endif
+ return QApplicationBase::exec();
+}
+
+/*! \reimp
+ */
+bool QApplication::notify(QObject *receiver, QEvent *e)
+{
+ Q_D(QApplication);
+ // no events are delivered after ~QCoreApplication() has started
+ if (QApplicationPrivate::is_app_closing)
+ return true;
+
+ if (receiver == 0) { // serious error
+ qWarning("QApplication::notify: Unexpected null receiver");
+ return true;
+ }
+
+#ifndef QT_NO_DEBUG
+ d->checkReceiverThread(receiver);
+#endif
+
+ // capture the current mouse/keyboard state
+ if(e->spontaneous()) {
+ if (e->type() == QEvent::KeyPress
+ || e->type() == QEvent::KeyRelease) {
+ QKeyEvent *ke = static_cast<QKeyEvent*>(e);
+ QApplicationPrivate::modifier_buttons = ke->modifiers();
+ } else if(e->type() == QEvent::MouseButtonPress
+ || e->type() == QEvent::MouseButtonRelease) {
+ QMouseEvent *me = static_cast<QMouseEvent*>(e);
+ QApplicationPrivate::modifier_buttons = me->modifiers();
+ if(me->type() == QEvent::MouseButtonPress)
+ QApplicationPrivate::mouse_buttons |= me->button();
+ else
+ QApplicationPrivate::mouse_buttons &= ~me->button();
+ }
+#if !defined(QT_NO_WHEELEVENT) || !defined(QT_NO_TABLETEVENT)
+ else if (false
+# ifndef QT_NO_WHEELEVENT
+ || e->type() == QEvent::Wheel
+# endif
+# ifndef QT_NO_TABLETEVENT
+ || e->type() == QEvent::TabletMove
+ || e->type() == QEvent::TabletPress
+ || e->type() == QEvent::TabletRelease
+# endif
+ ) {
+ QInputEvent *ie = static_cast<QInputEvent*>(e);
+ QApplicationPrivate::modifier_buttons = ie->modifiers();
+ }
+#endif // !QT_NO_WHEELEVENT || !QT_NO_TABLETEVENT
+ }
+
+#ifndef QT_NO_GESTURES
+ // walk through parents and check for gestures
+ if (d->gestureManager) {
+ switch (e->type()) {
+ case QEvent::Paint:
+ case QEvent::MetaCall:
+ case QEvent::DeferredDelete:
+ case QEvent::DragEnter: case QEvent::DragMove: case QEvent::DragLeave:
+ case QEvent::Drop: case QEvent::DragResponse:
+ case QEvent::ChildAdded: case QEvent::ChildPolished:
+#ifdef QT3_SUPPORT
+ case QEvent::ChildInsertedRequest:
+ case QEvent::ChildInserted:
+ case QEvent::LayoutHint:
+#endif
+ case QEvent::ChildRemoved:
+ case QEvent::UpdateRequest:
+ case QEvent::UpdateLater:
+ case QEvent::AccessibilityPrepare:
+ case QEvent::LocaleChange:
+ case QEvent::Style:
+ case QEvent::IconDrag:
+ case QEvent::StyleChange:
+ case QEvent::AccessibilityHelp:
+ case QEvent::AccessibilityDescription:
+ case QEvent::GraphicsSceneDragEnter:
+ case QEvent::GraphicsSceneDragMove:
+ case QEvent::GraphicsSceneDragLeave:
+ case QEvent::GraphicsSceneDrop:
+ case QEvent::DynamicPropertyChange:
+ case QEvent::NetworkReplyUpdated:
+ break;
+ default:
+ if (receiver->isWidgetType()) {
+ if (d->gestureManager->filterEvent(static_cast<QWidget *>(receiver), e))
+ return true;
+ } else {
+ // a special case for events that go to QGesture objects.
+ // We pass the object to the gesture manager and it'll figure
+ // out if it's QGesture or not.
+ if (d->gestureManager->filterEvent(receiver, e))
+ return true;
+ }
+ }
+ }
+#endif // QT_NO_GESTURES
+
+ // User input and window activation makes tooltips sleep
+ switch (e->type()) {
+ case QEvent::Wheel:
+ case QEvent::ActivationChange:
+ case QEvent::KeyPress:
+ case QEvent::KeyRelease:
+ case QEvent::FocusOut:
+ case QEvent::FocusIn:
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseButtonDblClick:
+ d->toolTipFallAsleep.stop();
+ // fall-through
+ case QEvent::Leave:
+ d->toolTipWakeUp.stop();
+ default:
+ break;
+ }
+
+ bool res = false;
+ if (!receiver->isWidgetType()) {
+ res = d->notify_helper(receiver, e);
+ } else switch (e->type()) {
+#if defined QT3_SUPPORT && !defined(QT_NO_SHORTCUT)
+ case QEvent::Accel:
+ {
+ if (d->use_compat()) {
+ QKeyEvent* key = static_cast<QKeyEvent*>(e);
+ res = d->notify_helper(receiver, e);
+
+ if (!res && !key->isAccepted())
+ res = d->qt_dispatchAccelEvent(static_cast<QWidget *>(receiver), key);
+
+ // next lines are for compatibility with Qt <= 3.0.x: old
+ // QAccel was listening on toplevel widgets
+ if (!res && !key->isAccepted() && !static_cast<QWidget *>(receiver)->isWindow())
+ res = d->notify_helper(static_cast<QWidget *>(receiver)->window(), e);
+ }
+ break;
+ }
+#endif //QT3_SUPPORT && !QT_NO_SHORTCUT
+ case QEvent::ShortcutOverride:
+ case QEvent::KeyPress:
+ case QEvent::KeyRelease:
+ {
+ bool isWidget = receiver->isWidgetType();
+ bool isGraphicsWidget = false;
+#ifndef QT_NO_GRAPHICSVIEW
+ isGraphicsWidget = !isWidget && qobject_cast<QGraphicsWidget *>(receiver);
+#endif
+ if (!isWidget && !isGraphicsWidget) {
+ res = d->notify_helper(receiver, e);
+ break;
+ }
+
+ QKeyEvent* key = static_cast<QKeyEvent*>(e);
+#if defined QT3_SUPPORT && !defined(QT_NO_SHORTCUT)
+ if (d->use_compat() && d->qt_tryComposeUnicode(static_cast<QWidget*>(receiver), key))
+ break;
+#endif
+ if (key->type()==QEvent::KeyPress) {
+#ifndef QT_NO_SHORTCUT
+ // Try looking for a Shortcut before sending key events
+ if ((res = qApp->d_func()->shortcutMap.tryShortcutEvent(receiver, key)))
+ return res;
+#endif
+ qt_in_tab_key_event = (key->key() == Qt::Key_Backtab
+ || key->key() == Qt::Key_Tab
+ || key->key() == Qt::Key_Left
+ || key->key() == Qt::Key_Up
+ || key->key() == Qt::Key_Right
+ || key->key() == Qt::Key_Down);
+ }
+ bool def = key->isAccepted();
+ QPointer<QObject> pr = receiver;
+ while (receiver) {
+ if (def)
+ key->accept();
+ else
+ key->ignore();
+ res = d->notify_helper(receiver, e);
+ QWidget *w = isWidget ? static_cast<QWidget *>(receiver) : 0;
+#ifndef QT_NO_GRAPHICSVIEW
+ QGraphicsWidget *gw = isGraphicsWidget ? static_cast<QGraphicsWidget *>(receiver) : 0;
+#endif
+
+ if ((res && key->isAccepted())
+ /*
+ QLineEdit will emit a signal on Key_Return, but
+ ignore the event, and sometimes the connected
+ slot deletes the QLineEdit (common in itemview
+ delegates), so we have to check if the widget
+ was destroyed even if the event was ignored (to
+ prevent a crash)
+
+ note that we don't have to reset pw while
+ propagating (because the original receiver will
+ be destroyed if one of its ancestors is)
+ */
+ || !pr
+ || (isWidget && (w->isWindow() || !w->parentWidget()))
+#ifndef QT_NO_GRAPHICSVIEW
+ || (isGraphicsWidget && (gw->isWindow() || !gw->parentWidget()))
+#endif
+ ) {
+ break;
+ }
+
+#ifndef QT_NO_GRAPHICSVIEW
+ receiver = w ? (QObject *)w->parentWidget() : (QObject *)gw->parentWidget();
+#else
+ receiver = w->parentWidget();
+#endif
+ }
+ qt_in_tab_key_event = false;
+ }
+ break;
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseButtonDblClick:
+ case QEvent::MouseMove:
+ {
+ QWidget* w = static_cast<QWidget *>(receiver);
+
+ QMouseEvent* mouse = static_cast<QMouseEvent*>(e);
+ QPoint relpos = mouse->pos();
+
+ if (e->spontaneous()) {
+
+ if (e->type() == QEvent::MouseButtonPress) {
+ QApplicationPrivate::giveFocusAccordingToFocusPolicy(w,
+ Qt::ClickFocus,
+ Qt::MouseFocusReason);
+ }
+
+ // ### Qt 5 These dynamic tool tips should be an OPT-IN feature. Some platforms
+ // like Mac OS X (probably others too), can optimize their views by not
+ // dispatching mouse move events. We have attributes to control hover,
+ // and mouse tracking, but as long as we are deciding to implement this
+ // feature without choice of opting-in or out, you ALWAYS have to have
+ // tracking enabled. Therefore, the other properties give a false sense of
+ // performance enhancement.
+ if (e->type() == QEvent::MouseMove && mouse->buttons() == 0) {
+ d->toolTipWidget = w;
+ d->toolTipPos = relpos;
+ d->toolTipGlobalPos = mouse->globalPos();
+ d->toolTipWakeUp.start(d->toolTipFallAsleep.isActive()?20:700, this);
+ }
+ }
+
+ bool eventAccepted = mouse->isAccepted();
+
+ QPointer<QWidget> pw = w;
+ while (w) {
+ QMouseEvent me(mouse->type(), relpos, mouse->windowPos(), mouse->globalPos(), mouse->button(), mouse->buttons(),
+ mouse->modifiers());
+ me.spont = mouse->spontaneous();
+ me.setTimestamp(mouse->timestamp());
+ // throw away any mouse-tracking-only mouse events
+ if (!w->hasMouseTracking()
+ && mouse->type() == QEvent::MouseMove && mouse->buttons() == 0) {
+ // but still send them through all application event filters (normally done by notify_helper)
+ for (int i = 0; i < d->eventFilters.size(); ++i) {
+ register QObject *obj = d->eventFilters.at(i);
+ if (!obj)
+ continue;
+ if (obj->d_func()->threadData != w->d_func()->threadData) {
+ qWarning("QApplication: Object event filter cannot be in a different thread.");
+ continue;
+ }
+ if (obj->eventFilter(w, w == receiver ? mouse : &me))
+ break;
+ }
+ res = true;
+ } else {
+ w->setAttribute(Qt::WA_NoMouseReplay, false);
+ res = d->notify_helper(w, w == receiver ? mouse : &me);
+ e->spont = false;
+ }
+ eventAccepted = (w == receiver ? mouse : &me)->isAccepted();
+ if (res && eventAccepted)
+ break;
+ if (w->isWindow() || w->testAttribute(Qt::WA_NoMousePropagation))
+ break;
+ relpos += w->pos();
+ w = w->parentWidget();
+ }
+
+ mouse->setAccepted(eventAccepted);
+
+ if (e->type() == QEvent::MouseMove) {
+ if (!pw)
+ break;
+
+ w = static_cast<QWidget *>(receiver);
+ relpos = mouse->pos();
+ QPoint diff = relpos - w->mapFromGlobal(d->hoverGlobalPos);
+ while (w) {
+ if (w->testAttribute(Qt::WA_Hover) &&
+ (!QApplication::activePopupWidget() || QApplication::activePopupWidget() == w->window())) {
+ QHoverEvent he(QEvent::HoverMove, relpos, relpos - diff, mouse->modifiers());
+ d->notify_helper(w, &he);
+ }
+ if (w->isWindow() || w->testAttribute(Qt::WA_NoMousePropagation))
+ break;
+ relpos += w->pos();
+ w = w->parentWidget();
+ }
+ }
+
+ d->hoverGlobalPos = mouse->globalPos();
+ }
+ break;
+#ifndef QT_NO_WHEELEVENT
+ case QEvent::Wheel:
+ {
+ QWidget* w = static_cast<QWidget *>(receiver);
+ QWheelEvent* wheel = static_cast<QWheelEvent*>(e);
+ QPoint relpos = wheel->pos();
+ bool eventAccepted = wheel->isAccepted();
+
+ if (e->spontaneous()) {
+ QApplicationPrivate::giveFocusAccordingToFocusPolicy(w,
+ Qt::WheelFocus,
+ Qt::MouseFocusReason);
+ }
+
+ while (w) {
+ QWheelEvent we(relpos, wheel->globalPos(), wheel->delta(), wheel->buttons(),
+ wheel->modifiers(), wheel->orientation());
+ we.spont = wheel->spontaneous();
+ res = d->notify_helper(w, w == receiver ? wheel : &we);
+ eventAccepted = ((w == receiver) ? wheel : &we)->isAccepted();
+ e->spont = false;
+ if ((res && eventAccepted)
+ || w->isWindow() || w->testAttribute(Qt::WA_NoMousePropagation))
+ break;
+
+ relpos += w->pos();
+ w = w->parentWidget();
+ }
+ wheel->setAccepted(eventAccepted);
+ }
+ break;
+#endif
+#ifndef QT_NO_CONTEXTMENU
+ case QEvent::ContextMenu:
+ {
+ QWidget* w = static_cast<QWidget *>(receiver);
+ QContextMenuEvent *context = static_cast<QContextMenuEvent*>(e);
+ QPoint relpos = context->pos();
+ bool eventAccepted = context->isAccepted();
+ while (w) {
+ QContextMenuEvent ce(context->reason(), relpos, context->globalPos(), context->modifiers());
+ ce.spont = e->spontaneous();
+ res = d->notify_helper(w, w == receiver ? context : &ce);
+ eventAccepted = ((w == receiver) ? context : &ce)->isAccepted();
+ e->spont = false;
+
+ if ((res && eventAccepted)
+ || w->isWindow() || w->testAttribute(Qt::WA_NoMousePropagation))
+ break;
+
+ relpos += w->pos();
+ w = w->parentWidget();
+ }
+ context->setAccepted(eventAccepted);
+ }
+ break;
+#endif // QT_NO_CONTEXTMENU
+#ifndef QT_NO_TABLETEVENT
+ case QEvent::TabletMove:
+ case QEvent::TabletPress:
+ case QEvent::TabletRelease:
+ {
+ QWidget *w = static_cast<QWidget *>(receiver);
+ QTabletEvent *tablet = static_cast<QTabletEvent*>(e);
+ QPoint relpos = tablet->pos();
+ bool eventAccepted = tablet->isAccepted();
+ while (w) {
+ QTabletEvent te(tablet->type(), relpos, tablet->globalPos(),
+ tablet->hiResGlobalPos(), tablet->device(), tablet->pointerType(),
+ tablet->pressure(), tablet->xTilt(), tablet->yTilt(),
+ tablet->tangentialPressure(), tablet->rotation(), tablet->z(),
+ tablet->modifiers(), tablet->uniqueId());
+ te.spont = e->spontaneous();
+ res = d->notify_helper(w, w == receiver ? tablet : &te);
+ eventAccepted = ((w == receiver) ? tablet : &te)->isAccepted();
+ e->spont = false;
+ if ((res && eventAccepted)
+ || w->isWindow()
+ || w->testAttribute(Qt::WA_NoMousePropagation))
+ break;
+
+ relpos += w->pos();
+ w = w->parentWidget();
+ }
+ tablet->setAccepted(eventAccepted);
+ qt_tabletChokeMouse = tablet->isAccepted();
+ }
+ break;
+#endif // QT_NO_TABLETEVENT
+
+#if !defined(QT_NO_TOOLTIP) || !defined(QT_NO_WHATSTHIS)
+ case QEvent::ToolTip:
+ case QEvent::WhatsThis:
+ case QEvent::QueryWhatsThis:
+ {
+ QWidget* w = static_cast<QWidget *>(receiver);
+ QHelpEvent *help = static_cast<QHelpEvent*>(e);
+ QPoint relpos = help->pos();
+ bool eventAccepted = help->isAccepted();
+ while (w) {
+ QHelpEvent he(help->type(), relpos, help->globalPos());
+ he.spont = e->spontaneous();
+ res = d->notify_helper(w, w == receiver ? help : &he);
+ e->spont = false;
+ eventAccepted = (w == receiver ? help : &he)->isAccepted();
+ if ((res && eventAccepted) || w->isWindow())
+ break;
+
+ relpos += w->pos();
+ w = w->parentWidget();
+ }
+ help->setAccepted(eventAccepted);
+ }
+ break;
+#endif
+#if !defined(QT_NO_STATUSTIP) || !defined(QT_NO_WHATSTHIS)
+ case QEvent::StatusTip:
+ case QEvent::WhatsThisClicked:
+ {
+ QWidget *w = static_cast<QWidget *>(receiver);
+ while (w) {
+ res = d->notify_helper(w, e);
+ if ((res && e->isAccepted()) || w->isWindow())
+ break;
+ w = w->parentWidget();
+ }
+ }
+ break;
+#endif
+
+#ifndef QT_NO_DRAGANDDROP
+ case QEvent::DragEnter: {
+ QWidget* w = static_cast<QWidget *>(receiver);
+ QDragEnterEvent *dragEvent = static_cast<QDragEnterEvent *>(e);
+#ifdef Q_WS_MAC
+ // HIView has a slight difference in how it delivers events to children and parents
+ // It will not give a leave to a child's parent when it enters a child.
+ QWidget *currentTarget = QDragManager::self()->currentTarget();
+ if (currentTarget) {
+ // Assume currentTarget did not get a leave
+ QDragLeaveEvent event;
+ QApplication::sendEvent(currentTarget, &event);
+ }
+#endif
+#ifndef QT_NO_GRAPHICSVIEW
+ // QGraphicsProxyWidget handles its own propagation,
+ // and we must not change QDragManagers currentTarget.
+ QWExtra *extra = w->window()->d_func()->extra;
+ if (extra && extra->proxyWidget) {
+ res = d->notify_helper(w, dragEvent);
+ break;
+ }
+#endif
+ while (w) {
+ if (w->isEnabled() && w->acceptDrops()) {
+ res = d->notify_helper(w, dragEvent);
+ if (res && dragEvent->isAccepted()) {
+ QDragManager::self()->setCurrentTarget(w);
+ break;
+ }
+ }
+ if (w->isWindow())
+ break;
+ dragEvent->p = w->mapToParent(dragEvent->p);
+ w = w->parentWidget();
+ }
+ }
+ break;
+ case QEvent::DragMove:
+ case QEvent::Drop:
+ case QEvent::DragLeave: {
+ QWidget* w = static_cast<QWidget *>(receiver);
+#ifndef QT_NO_GRAPHICSVIEW
+ // QGraphicsProxyWidget handles its own propagation,
+ // and we must not change QDragManagers currentTarget.
+ QWExtra *extra = w->window()->d_func()->extra;
+ bool isProxyWidget = extra && extra->proxyWidget;
+ if (!isProxyWidget)
+#endif
+ w = qobject_cast<QWidget *>(QDragManager::self()->currentTarget());
+
+ if (!w) {
+#ifdef Q_WS_MAC
+ // HIView has a slight difference in how it delivers events to children and parents
+ // It will not give an enter to a child's parent when it leaves the child.
+ if (e->type() == QEvent::DragLeave)
+ break;
+ // Assume that w did not get an enter.
+ QDropEvent *dropEvent = static_cast<QDropEvent *>(e);
+ QDragEnterEvent dragEnterEvent(dropEvent->pos(), dropEvent->possibleActions(),
+ dropEvent->mimeData(), dropEvent->mouseButtons(),
+ dropEvent->keyboardModifiers());
+ QApplication::sendEvent(receiver, &dragEnterEvent);
+ w = QDragManager::self()->currentTarget();
+ if (!w)
+#endif
+ break;
+ }
+ if (e->type() == QEvent::DragMove || e->type() == QEvent::Drop) {
+ QDropEvent *dragEvent = static_cast<QDropEvent *>(e);
+ QWidget *origReciver = static_cast<QWidget *>(receiver);
+ while (origReciver && w != origReciver) {
+ dragEvent->p = origReciver->mapToParent(dragEvent->p);
+ origReciver = origReciver->parentWidget();
+ }
+ }
+ res = d->notify_helper(w, e);
+ if (e->type() != QEvent::DragMove
+#ifndef QT_NO_GRAPHICSVIEW
+ && !isProxyWidget
+#endif
+ )
+ QDragManager::self()->setCurrentTarget(0, e->type() == QEvent::Drop);
+ }
+ break;
+#endif
+ case QEvent::TouchBegin:
+ // Note: TouchUpdate and TouchEnd events are never propagated
+ {
+ QWidget *widget = static_cast<QWidget *>(receiver);
+ QTouchEvent *touchEvent = static_cast<QTouchEvent *>(e);
+ bool eventAccepted = touchEvent->isAccepted();
+ if (widget->testAttribute(Qt::WA_AcceptTouchEvents) && e->spontaneous()) {
+ // give the widget focus if the focus policy allows it
+ QApplicationPrivate::giveFocusAccordingToFocusPolicy(widget,
+ Qt::ClickFocus,
+ Qt::MouseFocusReason);
+ }
+
+ while (widget) {
+ // first, try to deliver the touch event
+ bool acceptTouchEvents = widget->testAttribute(Qt::WA_AcceptTouchEvents);
+ touchEvent->setWidget(widget);
+ touchEvent->setAccepted(acceptTouchEvents);
+ QWeakPointer<QWidget> p = widget;
+ res = acceptTouchEvents && d->notify_helper(widget, touchEvent);
+ eventAccepted = touchEvent->isAccepted();
+ if (p.isNull()) {
+ // widget was deleted
+ widget = 0;
+ } else {
+ widget->setAttribute(Qt::WA_WState_AcceptedTouchBeginEvent, res && eventAccepted);
+ }
+ touchEvent->spont = false;
+ if (res && eventAccepted) {
+ // the first widget to accept the TouchBegin gets an implicit grab.
+ for (int i = 0; i < touchEvent->touchPoints().count(); ++i) {
+ const QTouchEvent::TouchPoint &touchPoint = touchEvent->touchPoints().at(i);
+ d->widgetForTouchPointId[touchPoint.id()] = widget;
+ }
+ break;
+ } else if (p.isNull() || widget->isWindow() || widget->testAttribute(Qt::WA_NoMousePropagation)) {
+ break;
+ }
+ QPoint offset = widget->pos();
+ widget = widget->parentWidget();
+ touchEvent->setWidget(widget);
+ for (int i = 0; i < touchEvent->_touchPoints.size(); ++i) {
+ QTouchEvent::TouchPoint &pt = touchEvent->_touchPoints[i];
+ QRectF rect = pt.rect();
+ rect.moveCenter(offset);
+ pt.d->rect = rect;
+ pt.d->startPos = pt.startPos() + offset;
+ pt.d->lastPos = pt.lastPos() + offset;
+ }
+ }
+
+ touchEvent->setAccepted(eventAccepted);
+ break;
+ }
+ case QEvent::RequestSoftwareInputPanel:
+ inputPanel()->show();
+ break;
+ case QEvent::CloseSoftwareInputPanel:
+ inputPanel()->hide();
+ break;
+
+#ifndef QT_NO_GESTURES
+ case QEvent::NativeGesture:
+ {
+ // only propagate the first gesture event (after the GID_BEGIN)
+ QWidget *w = static_cast<QWidget *>(receiver);
+ while (w) {
+ e->ignore();
+ res = d->notify_helper(w, e);
+ if ((res && e->isAccepted()) || w->isWindow())
+ break;
+ w = w->parentWidget();
+ }
+ break;
+ }
+ case QEvent::Gesture:
+ case QEvent::GestureOverride:
+ {
+ if (receiver->isWidgetType()) {
+ QWidget *w = static_cast<QWidget *>(receiver);
+ QGestureEvent *gestureEvent = static_cast<QGestureEvent *>(e);
+ QList<QGesture *> allGestures = gestureEvent->gestures();
+
+ bool eventAccepted = gestureEvent->isAccepted();
+ bool wasAccepted = eventAccepted;
+ while (w) {
+ // send only gestures the widget expects
+ QList<QGesture *> gestures;
+ QWidgetPrivate *wd = w->d_func();
+ for (int i = 0; i < allGestures.size();) {
+ QGesture *g = allGestures.at(i);
+ Qt::GestureType type = g->gestureType();
+ QMap<Qt::GestureType, Qt::GestureFlags>::iterator contextit =
+ wd->gestureContext.find(type);
+ bool deliver = contextit != wd->gestureContext.end() &&
+ (g->state() == Qt::GestureStarted || w == receiver ||
+ (contextit.value() & Qt::ReceivePartialGestures));
+ if (deliver) {
+ allGestures.removeAt(i);
+ gestures.append(g);
+ } else {
+ ++i;
+ }
+ }
+ if (!gestures.isEmpty()) { // we have gestures for this w
+ QGestureEvent ge(gestures);
+ ge.t = gestureEvent->t;
+ ge.spont = gestureEvent->spont;
+ ge.m_accept = wasAccepted;
+ ge.d_func()->accepted = gestureEvent->d_func()->accepted;
+ res = d->notify_helper(w, &ge);
+ gestureEvent->spont = false;
+ eventAccepted = ge.isAccepted();
+ for (int i = 0; i < gestures.size(); ++i) {
+ QGesture *g = gestures.at(i);
+ // Ignore res [event return value] because handling of multiple gestures
+ // packed into a single QEvent depends on not consuming the event
+ if (eventAccepted || ge.isAccepted(g)) {
+ // if the gesture was accepted, mark the target widget for it
+ gestureEvent->d_func()->targetWidgets[g->gestureType()] = w;
+ gestureEvent->setAccepted(g, true);
+ } else {
+ // if the gesture was explicitly ignored by the application,
+ // put it back so a parent can get it
+ allGestures.append(g);
+ }
+ }
+ }
+ if (allGestures.isEmpty()) // everything delivered
+ break;
+ if (w->isWindow())
+ break;
+ w = w->parentWidget();
+ }
+ foreach (QGesture *g, allGestures)
+ gestureEvent->setAccepted(g, false);
+ gestureEvent->m_accept = false; // to make sure we check individual gestures
+ } else {
+ res = d->notify_helper(receiver, e);
+ }
+ break;
+ }
+#endif // QT_NO_GESTURES
+#ifdef QT_MAC_USE_COCOA
+ case QEvent::Enter:
+ if (receiver->isWidgetType()) {
+ QWidget *w = static_cast<QWidget *>(receiver);
+ if (w->testAttribute(Qt::WA_AcceptTouchEvents))
+ qt_widget_private(w)->registerTouchWindow(true);
+ }
+ res = d->notify_helper(receiver, e);
+ break;
+ case QEvent::Leave:
+ if (receiver->isWidgetType()) {
+ QWidget *w = static_cast<QWidget *>(receiver);
+ if (w->testAttribute(Qt::WA_AcceptTouchEvents))
+ qt_widget_private(w)->registerTouchWindow(false);
+ }
+ res = d->notify_helper(receiver, e);
+ break;
+#endif
+ default:
+ res = d->notify_helper(receiver, e);
+ break;
+ }
+
+ return res;
+}
+
+bool QApplicationPrivate::notify_helper(QObject *receiver, QEvent * e)
+{
+ // send to all application event filters
+ if (sendThroughApplicationEventFilters(receiver, e))
+ return true;
+
+ if (receiver->isWidgetType()) {
+ QWidget *widget = static_cast<QWidget *>(receiver);
+
+#if !defined(Q_WS_WINCE) || (defined(GWES_ICONCURS) && !defined(QT_NO_CURSOR))
+ // toggle HasMouse widget state on enter and leave
+ if ((e->type() == QEvent::Enter || e->type() == QEvent::DragEnter) &&
+ (!QApplication::activePopupWidget() || QApplication::activePopupWidget() == widget->window()))
+ widget->setAttribute(Qt::WA_UnderMouse, true);
+ else if (e->type() == QEvent::Leave || e->type() == QEvent::DragLeave)
+ widget->setAttribute(Qt::WA_UnderMouse, false);
+#endif
+
+ if (QLayout *layout=widget->d_func()->layout) {
+ layout->widgetEvent(e);
+ }
+ }
+
+ // send to all receiver event filters
+ if (sendThroughObjectEventFilters(receiver, e))
+ return true;
+
+ // deliver the event
+ bool consumed = receiver->event(e);
+ e->spont = false;
+ return consumed;
+}
+
+
+/*!
+ \class QSessionManager
+ \brief The QSessionManager class provides access to the session manager.
+
+ 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:
+
+ \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 RestartImmediately The application wants to be started immediately
+ whenever it is not running.
+
+ \value RestartNever The application does not want to be restarted
+ automatically.
+
+ The default hint is \c RestartIfRunning.
+*/
+
+
+/*!
+ \fn QString QSessionManager::sessionId() const
+
+ 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 the earlier session.
+
+ \sa sessionKey(), QApplication::sessionId()
+*/
+
+/*!
+ \fn QString QSessionManager::sessionKey() const
+
+ 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.
+
+ The session key changes with every call of commitData() or saveState().
+
+ \sa sessionId(), QApplication::sessionKey()
+*/
+
+/*!
+ \fn void* QSessionManager::handle() const
+
+ \internal
+*/
+
+/*!
+ \fn bool QSessionManager::allowsInteraction()
+
+ 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.
+
+ 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().
+
+ 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
+
+ If an error occurred within the application while saving its data, you may
+ want to try allowsErrorInteraction() instead.
+
+ \sa QApplication::commitData(), release(), cancel()
+*/
+
+
+/*!
+ \fn bool QSessionManager::allowsErrorInteraction()
+
+ 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.
+
+ \sa allowsInteraction(), release(), cancel()
+*/
+
+/*!
+ \fn void QSessionManager::release()
+
+ Releases the session manager's interaction semaphore after an interaction
+ phase.
+
+ \sa allowsInteraction(), allowsErrorInteraction()
+*/
+
+/*!
+ \fn void QSessionManager::cancel()
+
+ 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)
+
+ Sets the application's restart hint to \a hint. On application startup, the
+ hint is set to \c RestartIfRunning.
+
+ \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.
+
+ \sa restartHint()
+*/
+
+/*!
+ \fn QSessionManager::RestartHint QSessionManager::restartHint() const
+
+ Returns the application's current restart hint. The default is
+ \c RestartIfRunning.
+
+ \sa setRestartHint()
+*/
+
+/*!
+ \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
+
+ \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.
+
+ 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()
+*/
+
+/*!
+ \fn QStringList QSessionManager::restartCommand() const
+
+ Returns the currently set restart command.
+
+ To iterate over the list, you can use the \l foreach pseudo-keyword:
+
+ \snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 10
+
+ \sa setRestartCommand(), restartHint()
+*/
+
+/*!
+ \fn void QSessionManager::setDiscardCommand(const QStringList& list)
+
+ Sets the discard command to the given \a list.
+
+ \sa discardCommand(), setRestartCommand()
+*/
+
+
+/*!
+ \fn QStringList QSessionManager::discardCommand() const
+
+ Returns the currently set discard command.
+
+ To iterate over the list, you can use the \l foreach pseudo-keyword:
+
+ \snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 11
+
+ \sa setDiscardCommand(), restartCommand(), setRestartCommand()
+*/
+
+/*!
+ \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.
+
+ The property called \a name has its value set to the string \a 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.
+
+ The property called \a name has its value set to the string list \a value.
+*/
+
+/*!
+ \fn bool QSessionManager::isPhase2() const
+
+ Returns true if the session manager is currently performing a second
+ session management phase; otherwise returns false.
+
+ \sa 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.
+
+ 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 If another application has requested a second phase it may get called
+ before, simultaneously with, or after your application's second phase.
+
+ \sa isPhase2()
+*/
+
+/*****************************************************************************
+ Stubbed session management support
+ *****************************************************************************/
+#ifndef QT_NO_SESSIONMANAGER
+#if defined(Q_WS_WIN) || defined(Q_WS_MAC) || defined(Q_WS_QWS)
+
+#if defined(Q_OS_WINCE)
+HRESULT qt_CoCreateGuid(GUID* guid)
+{
+ // We will use the following information to create the GUID
+ // 1. absolute path to application
+ wchar_t tempFilename[MAX_PATH];
+ if (!GetModuleFileName(0, tempFilename, MAX_PATH))
+ return S_FALSE;
+ unsigned int hash = qHash(QString::fromWCharArray(tempFilename));
+ guid->Data1 = hash;
+ // 2. creation time of file
+ QFileInfo info(QString::fromWCharArray(tempFilename));
+ guid->Data2 = qHash(info.created().toTime_t());
+ // 3. current system time
+ guid->Data3 = qHash(QDateTime::currentDateTime().toTime_t());
+ return S_OK;
+}
+#if !defined(OLE32_MCOMGUID) || defined(QT_WINCE_FORCE_CREATE_GUID)
+#define CoCreateGuid qt_CoCreateGuid
+#endif
+
+#endif
+
+class QSessionManagerPrivate : public QObjectPrivate
+{
+public:
+ QStringList restartCommand;
+ QStringList discardCommand;
+ QString sessionId;
+ QString sessionKey;
+ QSessionManager::RestartHint restartHint;
+};
+
+QSessionManager* qt_session_manager_self = 0;
+QSessionManager::QSessionManager(QApplication * app, QString &id, QString &key)
+ : QObject(*new QSessionManagerPrivate, app)
+{
+ Q_D(QSessionManager);
+ setObjectName(QLatin1String("qt_sessionmanager"));
+ qt_session_manager_self = this;
+#if defined(Q_WS_WIN)
+ wchar_t guidstr[40];
+ GUID guid;
+ CoCreateGuid(&guid);
+ StringFromGUID2(guid, guidstr, 40);
+ id = QString::fromWCharArray(guidstr);
+ CoCreateGuid(&guid);
+ StringFromGUID2(guid, guidstr, 40);
+ key = QString::fromWCharArray(guidstr);
+#endif
+ d->sessionId = id;
+ d->sessionKey = key;
+ d->restartHint = RestartIfRunning;
+}
+
+QSessionManager::~QSessionManager()
+{
+ qt_session_manager_self = 0;
+}
+
+QString QSessionManager::sessionId() const
+{
+ Q_D(const QSessionManager);
+ return d->sessionId;
+}
+
+QString QSessionManager::sessionKey() const
+{
+ Q_D(const QSessionManager);
+ return d->sessionKey;
+}
+
+
+#if defined(Q_WS_X11) || defined(Q_WS_MAC)
+void* QSessionManager::handle() const
+{
+ return 0;
+}
+#endif
+
+#if !defined(Q_WS_WIN)
+bool QSessionManager::allowsInteraction()
+{
+ return true;
+}
+
+bool QSessionManager::allowsErrorInteraction()
+{
+ return true;
+}
+void QSessionManager::release()
+{
+}
+
+void QSessionManager::cancel()
+{
+}
+#endif
+
+
+void QSessionManager::setRestartHint(QSessionManager::RestartHint hint)
+{
+ Q_D(QSessionManager);
+ d->restartHint = hint;
+}
+
+QSessionManager::RestartHint QSessionManager::restartHint() const
+{
+ Q_D(const QSessionManager);
+ return d->restartHint;
+}
+
+void QSessionManager::setRestartCommand(const QStringList& command)
+{
+ Q_D(QSessionManager);
+ d->restartCommand = command;
+}
+
+QStringList QSessionManager::restartCommand() const
+{
+ Q_D(const QSessionManager);
+ return d->restartCommand;
+}
+
+void QSessionManager::setDiscardCommand(const QStringList& command)
+{
+ Q_D(QSessionManager);
+ d->discardCommand = command;
+}
+
+QStringList QSessionManager::discardCommand() const
+{
+ Q_D(const QSessionManager);
+ return d->discardCommand;
+}
+
+void QSessionManager::setManagerProperty(const QString&, const QString&)
+{
+}
+
+void QSessionManager::setManagerProperty(const QString&, const QStringList&)
+{
+}
+
+bool QSessionManager::isPhase2() const
+{
+ return false;
+}
+
+void QSessionManager::requestPhase2()
+{
+}
+
+#endif
+#endif // QT_NO_SESSIONMANAGER
+
+/*!
+ \typedef QApplication::ColorMode
+ \compat
+
+ Use ColorSpec instead.
+*/
+
+/*!
+ \fn Qt::MacintoshVersion QApplication::macVersion()
+
+ Use QSysInfo::MacintoshVersion instead.
+*/
+
+/*!
+ \fn QApplication::ColorMode QApplication::colorMode()
+
+ Use colorSpec() instead, and use ColorSpec as the enum type.
+*/
+
+/*!
+ \fn void QApplication::setColorMode(ColorMode mode)
+
+ Use setColorSpec() instead, and pass a ColorSpec value instead.
+*/
+
+/*!
+ \fn bool QApplication::hasGlobalMouseTracking()
+
+ 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.
+*/
+
+/*!
+ \fn void QApplication::flushX()
+
+ Use flush() instead.
+*/
+
+/*!
+ \fn void QApplication::setWinStyleHighlightColor(const QColor &c)
+
+ Use the palette instead.
+
+ \oldcode
+ app.setWinStyleHighlightColor(color);
+ \newcode
+ QPalette palette(QApplication::palette());
+ palette.setColor(QPalette::Highlight, color);
+ QApplication::setPalette(palette);
+ \endcode
+*/
+
+/*!
+ \fn void QApplication::setPalette(const QPalette &pal, bool b, const char* className = 0)
+
+ Use the two-argument overload instead.
+*/
+
+/*!
+ \fn void QApplication::setFont(const QFont &font, bool b, const char* className = 0)
+
+ Use the two-argument overload instead.
+*/
+
+/*!
+ \fn const QColor &QApplication::winStyleHighlightColor()
+
+ Use QApplication::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:
+
+ \snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 12
+*/
+
+/*!
+ \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:
+
+ \snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 13
+*/
+
+#ifdef QT3_SUPPORT
+QWidget *QApplication::mainWidget()
+{
+ return QApplicationPrivate::main_widget;
+}
+#endif
+bool QApplicationPrivate::inPopupMode() const
+{
+ return QApplicationPrivate::popupWidgets != 0;
+}
+
+/*!
+ \property QApplication::quitOnLastWindowClosed
+
+ \brief whether the application implicitly quits when the last window is
+ closed.
+
+ The default is true.
+
+ If this property is true, the applications quits when the last visible
+ primary window (i.e. window with no parent) with the Qt::WA_QuitOnClose
+ attribute set is closed. By default this attribute is set for all widgets
+ except for sub-windows. Refer to \l{Qt::WindowType} for a detailed list of
+ Qt::Window objects.
+
+ \sa quit(), QWidget::close()
+ */
+
+void QApplication::setQuitOnLastWindowClosed(bool quit)
+{
+ QApplicationPrivate::quitOnLastWindowClosed = quit;
+}
+
+bool QApplication::quitOnLastWindowClosed()
+{
+ return QApplicationPrivate::quitOnLastWindowClosed;
+}
+
+void QApplicationPrivate::emitLastWindowClosed()
+{
+ if (qApp && qApp->d_func()->in_exec) {
+ if (QApplicationPrivate::quitOnLastWindowClosed) {
+ // get ready to quit, this event might be removed if the
+ // event loop is re-entered, however
+ QApplication::postEvent(qApp, new QEvent(QEvent::Quit));
+ }
+ emit qApp->lastWindowClosed();
+ }
+}
+
+/*! \variable QApplication::NormalColors
+ \compat
+
+ Use \l NormalColor instead.
+*/
+
+/*! \variable QApplication::CustomColors
+ \compat
+
+ Use \l CustomColor instead.
+*/
+
+#ifdef QT_KEYPAD_NAVIGATION
+/*!
+ Sets the kind of focus navigation Qt should use to \a mode.
+
+ This feature is available in Qt for Embedded Linux, Symbian and Windows CE
+ only.
+
+ \note On Windows CE this feature is disabled by default for touch device
+ mkspecs. To enable keypad navigation, build Qt with
+ QT_KEYPAD_NAVIGATION defined.
+
+ \note On Symbian, setting the mode to Qt::NavigationModeCursorAuto will enable a
+ virtual mouse cursor on non touchscreen devices, which is controlled
+ by the cursor keys if there is no analog pointer device.
+ On other platforms and on touchscreen devices, it has the same
+ meaning as Qt::NavigationModeNone.
+
+ \since 4.6
+
+ \sa keypadNavigationEnabled()
+*/
+void QApplication::setNavigationMode(Qt::NavigationMode mode)
+{
+#ifdef Q_OS_SYMBIAN
+ QApplicationPrivate::setNavigationMode(mode);
+#else
+ QApplicationPrivate::navigationMode = mode;
+#endif
+}
+
+/*!
+ Returns what kind of focus navigation Qt is using.
+
+ This feature is available in Qt for Embedded Linux, Symbian and Windows CE
+ only.
+
+ \note On Windows CE this feature is disabled by default for touch device
+ mkspecs. To enable keypad navigation, build Qt with
+ QT_KEYPAD_NAVIGATION defined.
+
+ \note On Symbian, the default mode is Qt::NavigationModeNone for touch
+ devices, and Qt::NavigationModeKeypadDirectional.
+
+ \since 4.6
+
+ \sa keypadNavigationEnabled()
+*/
+Qt::NavigationMode QApplication::navigationMode()
+{
+ return QApplicationPrivate::navigationMode;
+}
+
+/*!
+ Sets whether Qt should use focus navigation suitable for use with a
+ minimal keypad.
+
+ This feature is available in Qt for Embedded Linux, Symbian and Windows CE
+ only.
+
+ \note On Windows CE this feature is disabled by default for touch device
+ mkspecs. To enable keypad navigation, build Qt with
+ QT_KEYPAD_NAVIGATION defined.
+
+ \deprecated
+
+ \sa setNavigationMode()
+*/
+void QApplication::setKeypadNavigationEnabled(bool enable)
+{
+ if (enable) {
+#ifdef Q_OS_SYMBIAN
+ QApplication::setNavigationMode(Qt::NavigationModeKeypadDirectional);
+#else
+ QApplication::setNavigationMode(Qt::NavigationModeKeypadTabOrder);
+#endif
+ }
+ else {
+ QApplication::setNavigationMode(Qt::NavigationModeNone);
+ }
+}
+
+/*!
+ Returns true if Qt is set to use keypad navigation; otherwise returns
+ false. The default value is true on Symbian, but false on other platforms.
+
+ This feature is available in Qt for Embedded Linux, Symbian and Windows CE
+ only.
+
+ \note On Windows CE this feature is disabled by default for touch device
+ mkspecs. To enable keypad navigation, build Qt with
+ QT_KEYPAD_NAVIGATION defined.
+
+ \deprecated
+
+ \sa navigationMode()
+*/
+bool QApplication::keypadNavigationEnabled()
+{
+ return QApplicationPrivate::navigationMode == Qt::NavigationModeKeypadTabOrder ||
+ QApplicationPrivate::navigationMode == Qt::NavigationModeKeypadDirectional;
+}
+#endif
+
+/*!
+ \fn void QApplication::alert(QWidget *widget, int msec)
+ \since 4.3
+
+ Causes an alert to be shown for \a widget if the window is not the active
+ window. The alert is shown for \a msec miliseconds. If \a msec is zero (the
+ default), then the alert is shown indefinitely until the window becomes
+ active again.
+
+ Currently this function does nothing on Qt for Embedded Linux.
+
+ 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
+ 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
+ visible in some sort of way) in order for this to work.
+*/
+
+/*!
+ \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 default value on X11 is 1000 milliseconds. On Windows, the
+ \gui{Control Panel} value is used and setting this property sets the cursor
+ flash time for all applications.
+
+ We recommend that widgets do not cache this value as it may change at any
+ time if the user changes the global desktop settings.
+*/
+void QApplication::setCursorFlashTime(int msecs)
+{
+ Q_UNUSED(msecs);
+}
+
+int QApplication::cursorFlashTime()
+{
+ return qApp->styleHints()->cursorFlashTime();
+}
+
+
+/*!
+ \property QApplication::doubleClickInterval
+ \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, the
+ operating system's value is used.
+
+ Setting the interval is not supported anymore in Qt 5.
+*/
+void QApplication::setDoubleClickInterval(int ms)
+{
+ Q_UNUSED(ms);
+}
+
+int QApplication::doubleClickInterval()
+{
+ return qApp->styleHints()->mouseDoubleClickInterval();
+}
+
+/*!
+ \property QApplication::keyboardInputInterval
+ \brief the time limit in milliseconds that distinguishes a key press
+ from two consecutive key presses
+ \since 4.2
+
+ The default value on X11 is 400 milliseconds. On Windows and Mac OS, the
+ operating system's value is used.
+*/
+void QApplication::setKeyboardInputInterval(int ms)
+{
+ Q_UNUSED(ms);
+}
+
+int QApplication::keyboardInputInterval()
+{
+ return qApp->styleHints()->keyboardInputInterval();
+}
+
+/*!
+ \property QApplication::wheelScrollLines
+ \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}.
+
+ By default, this property has a value of 3.
+*/
+
+/*!
+ \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.
+
+ \note All effects are disabled on screens running at less than 16-bit color
+ depth.
+
+ \sa isEffectEnabled(), Qt::UIEffect, setDesktopSettingsAware()
+*/
+
+/*!
+ \fn bool QApplication::isEffectEnabled(Qt::UIEffect effect)
+
+ Returns true if \a effect is enabled; otherwise returns false.
+
+ 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.
+
+ \sa setEffectEnabled(), Qt::UIEffect
+*/
+
+/*!
+ \fn QWidget *QApplication::mainWidget()
+
+ Returns the main application widget, or 0 if there is no main widget.
+*/
+
+/*!
+ \fn void QApplication::setMainWidget(QWidget *mainWidget)
+
+ 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. 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.
+
+ On 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()
+*/
+
+/*!
+ \fn void QApplication::beep()
+
+ Sounds the bell, using the default volume and sound. The function is \e not
+ available in Qt for Embedded Linux.
+*/
+
+/*!
+ \fn void QApplication::setOverrideCursor(const QCursor &cursor)
+
+ 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.
+
+ 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 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()
+*/
+
+/*!
+ \fn void QApplication::restoreOverrideCursor()
+
+ 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.
+
+ \sa setOverrideCursor(), overrideCursor()
+*/
+
+/*!
+ \macro qApp
+ \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.
+
+ Only one application object can be created.
+
+ \sa QCoreApplication::instance()
+*/
+
+#ifndef QT_NO_IM
+// ************************************************************************
+// Input Method support
+// ************************************************************************
+
+/*!
+ This function replaces the QInputContext instance used by the application
+ with \a inputContext.
+
+ Qt takes ownership of the given \a inputContext.
+
+ \sa inputContext()
+*/
+void QApplication::setInputContext(QInputContext *inputContext)
+{
+ if (inputContext == QApplicationPrivate::inputContext)
+ return;
+ if (!inputContext) {
+ qWarning("QApplication::setInputContext: called with 0 input context");
+ return;
+ }
+ delete QApplicationPrivate::inputContext;
+ QApplicationPrivate::inputContext = inputContext;
+ QApplicationPrivate::inputContext->setParent(this);
+}
+
+/*!
+ Returns the QInputContext instance used by the application.
+
+ \sa setInputContext()
+*/
+QInputContext *QApplication::inputContext() const
+{
+ return QApplicationPrivate::inputContext;
+}
+#endif // QT_NO_IM
+
+bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event)
+{
+ return QApplicationBase::sendSpontaneousEvent(receiver, event);
+}
+
+
+void QApplicationPrivate::giveFocusAccordingToFocusPolicy(QWidget *widget,
+ Qt::FocusPolicy focusPolicy,
+ Qt::FocusReason focusReason)
+{
+ QWidget *focusWidget = widget;
+ while (focusWidget) {
+ if (focusWidget->isEnabled()
+ && QApplicationPrivate::shouldSetFocus(focusWidget, focusPolicy)) {
+ focusWidget->setFocus(focusReason);
+ break;
+ }
+ if (focusWidget->isWindow())
+ break;
+ focusWidget = focusWidget->parentWidget();
+ }
+}
+
+bool QApplicationPrivate::shouldSetFocus(QWidget *w, Qt::FocusPolicy policy)
+{
+ QWidget *f = w;
+ while (f->d_func()->extra && f->d_func()->extra->focus_proxy)
+ f = f->d_func()->extra->focus_proxy;
+
+ if ((w->focusPolicy() & policy) != policy)
+ return false;
+ if (w != f && (f->focusPolicy() & policy) != policy)
+ return false;
+ return true;
+}
+
+/*! \fn QDecoration &QApplication::qwsDecoration()
+ Return the QWSDecoration used for decorating windows.
+
+ \warning This method is non-portable. It is only available in
+ Qt for Embedded Linux.
+
+ \sa QDecoration
+*/
+
+/*!
+ \fn void QApplication::qwsSetDecoration(QDecoration *decoration)
+
+ Sets the QDecoration derived class to use for decorating the
+ windows used by Qt for Embedded Linux to the \a decoration
+ specified.
+
+ This method is non-portable. It is only available in Qt for Embedded Linux.
+
+ \sa QDecoration
+*/
+
+/*! \fn QDecoration* QApplication::qwsSetDecoration(const QString &decoration)
+ \overload
+
+ Requests a QDecoration object for \a decoration from the
+ QDecorationFactory.
+
+ The string must be one of the QDecorationFactory::keys(). Keys are case
+ insensitive.
+
+ A later call to the QApplication constructor will override the requested
+ style when a "-style" option is passed in as a commandline parameter.
+
+ Returns 0 if an unknown \a decoration is passed, otherwise the QStyle object
+ returned is set as the application's GUI style.
+*/
+
+/*!
+ \fn bool QApplication::qwsEventFilter(QWSEvent *event)
+
+ This virtual function is only implemented under Qt for Embedded Linux.
+
+ If you create an application that inherits QApplication and
+ reimplement this function, you get direct access to all QWS (Q
+ Window System) events that the are received from the QWS master
+ process. The events are passed in the \a event parameter.
+
+ Return true if you want to stop the event from being processed.
+ Return false for normal event dispatching. The default
+ implementation returns false.
+*/
+
+/*! \fn void QApplication::qwsSetCustomColors(QRgb *colorTable, int start, int numColors)
+ Set Qt for Embedded Linux custom color table.
+
+ Qt for Embedded Linux on 8-bpp displays allocates a standard 216 color cube.
+ The remaining 40 colors may be used by setting a custom color
+ table in the QWS master process before any clients connect.
+
+ \a colorTable is an array of up to 40 custom colors. \a start is
+ the starting index (0-39) and \a numColors is the number of colors
+ to be set (1-40).
+
+ This method is non-portable. It is available \e only in
+ Qt for Embedded Linux.
+
+ \note The custom colors will not be used by the default screen
+ driver. To make use of the new colors, implement a custom screen
+ driver, or use QDirectPainter.
+*/
+
+/*! \fn int QApplication::qwsProcessEvent(QWSEvent* event)
+ \internal
+*/
+
+/*! \fn int QApplication::x11ClientMessage(QWidget* w, XEvent* event, bool passive_only)
+ \internal
+*/
+
+/*! \fn int QApplication::x11ProcessEvent(XEvent* event)
+ This function does the core processing of individual X
+ \a{event}s, normally by dispatching Qt events to the right
+ destination.
+
+ It returns 1 if the event was consumed by special handling, 0 if
+ the \a event was consumed by normal handling, and -1 if the \a
+ event was for an unrecognized widget.
+
+ \sa x11EventFilter()
+*/
+
+/*!
+ \fn bool QApplication::x11EventFilter(XEvent *event)
+
+ \warning This virtual function is only implemented under X11.
+
+ If you create an application that inherits QApplication and
+ reimplement this function, you get direct access to all X events
+ that the are received from the X server. The events are passed in
+ the \a event parameter.
+
+ Return true if you want to stop the event from being processed.
+ Return false for normal event dispatching. The default
+ implementation returns false.
+
+ It is only the directly addressed messages that are filtered.
+ You must install an event filter directly on the event
+ dispatcher, which is returned by
+ QAbstractEventDispatcher::instance(), to handle system wide
+ messages.
+
+ \sa x11ProcessEvent()
+*/
+
+/*! \fn void QApplication::winFocus(QWidget *widget, bool gotFocus)
+ \internal
+ \since 4.1
+
+ If \a gotFocus is true, \a widget will become the active window.
+ Otherwise the active window is reset to 0.
+*/
+
+/*! \fn void QApplication::winMouseButtonUp()
+ \internal
+ */
+
+/*! \fn void QApplication::syncX()
+ Synchronizes with the X server in the X11 implementation.
+ This normally takes some time. Does nothing on other platforms.
+*/
+
+void QApplicationPrivate::updateTouchPointsForWidget(QWidget *widget, QTouchEvent *touchEvent)
+{
+ for (int i = 0; i < touchEvent->touchPoints().count(); ++i) {
+ QTouchEvent::TouchPoint &touchPoint = touchEvent->_touchPoints[i];
+
+ // preserve the sub-pixel resolution
+ QRectF rect = touchPoint.screenRect();
+ const QPointF screenPos = rect.center();
+ const QPointF delta = screenPos - screenPos.toPoint();
+
+ rect.moveCenter(widget->mapFromGlobal(screenPos.toPoint()) + delta);
+ touchPoint.d->rect = rect;
+ if (touchPoint.state() == Qt::TouchPointPressed) {
+ touchPoint.d->startPos = widget->mapFromGlobal(touchPoint.startScreenPos().toPoint()) + delta;
+ touchPoint.d->lastPos = widget->mapFromGlobal(touchPoint.lastScreenPos().toPoint()) + delta;
+ }
+ }
+}
+
+void QApplicationPrivate::initializeMultitouch()
+{
+ widgetForTouchPointId.clear();
+ appCurrentTouchPoints.clear();
+
+ initializeMultitouch_sys();
+}
+
+void QApplicationPrivate::cleanupMultitouch()
+{
+ cleanupMultitouch_sys();
+
+ widgetForTouchPointId.clear();
+ appCurrentTouchPoints.clear();
+}
+
+int QApplicationPrivate::findClosestTouchPointId(const QPointF &screenPos)
+{
+ int closestTouchPointId = -1;
+ qreal closestDistance = qreal(0.);
+ foreach (const QTouchEvent::TouchPoint &touchPoint, appCurrentTouchPoints) {
+ qreal distance = QLineF(screenPos, touchPoint.screenPos()).length();
+ if (closestTouchPointId == -1 || distance < closestDistance) {
+ closestTouchPointId = touchPoint.id();
+ closestDistance = distance;
+ }
+ }
+ return closestTouchPointId;
+}
+
+void QApplicationPrivate::translateRawTouchEvent(QWidget *window,
+ QTouchEvent::DeviceType deviceType,
+ const QList<QTouchEvent::TouchPoint> &touchPoints)
+{
+ QApplicationPrivate *d = self;
+ typedef QPair<Qt::TouchPointStates, QList<QTouchEvent::TouchPoint> > StatesAndTouchPoints;
+ QHash<QWidget *, StatesAndTouchPoints> widgetsNeedingEvents;
+
+ for (int i = 0; i < touchPoints.count(); ++i) {
+ QTouchEvent::TouchPoint touchPoint = touchPoints.at(i);
+ // explicitly detach from the original touch point that we got, so even
+ // if the touchpoint structs are reused, we will make a copy that we'll
+ // deliver to the user (which might want to store the struct for later use).
+ touchPoint.d = touchPoint.d->detach();
+
+ // update state
+ QWeakPointer<QWidget> widget;
+ switch (touchPoint.state()) {
+ case Qt::TouchPointPressed:
+ {
+ if (deviceType == QTouchEvent::TouchPad) {
+ // on touch-pads, send all touch points to the same widget
+ widget = d->widgetForTouchPointId.isEmpty()
+ ? QWeakPointer<QWidget>()
+ : d->widgetForTouchPointId.constBegin().value();
+ }
+
+ if (!widget) {
+ // determine which widget this event will go to
+ if (!window)
+ window = QApplication::topLevelAt(touchPoint.screenPos().toPoint());
+ if (!window)
+ continue;
+ widget = window->childAt(window->mapFromGlobal(touchPoint.screenPos().toPoint()));
+ if (!widget)
+ widget = window;
+ }
+
+ if (deviceType == QTouchEvent::TouchScreen) {
+ int closestTouchPointId = d->findClosestTouchPointId(touchPoint.screenPos());
+ QWidget *closestWidget = d->widgetForTouchPointId.value(closestTouchPointId).data();
+ if (closestWidget
+ && (widget.data()->isAncestorOf(closestWidget) || closestWidget->isAncestorOf(widget.data()))) {
+ widget = closestWidget;
+ }
+ }
+
+ d->widgetForTouchPointId[touchPoint.id()] = widget;
+ touchPoint.d->startScreenPos = touchPoint.screenPos();
+ touchPoint.d->lastScreenPos = touchPoint.screenPos();
+ touchPoint.d->startNormalizedPos = touchPoint.normalizedPos();
+ touchPoint.d->lastNormalizedPos = touchPoint.normalizedPos();
+ if (touchPoint.pressure() < qreal(0.))
+ touchPoint.d->pressure = qreal(1.);
+
+ d->appCurrentTouchPoints.insert(touchPoint.id(), touchPoint);
+ break;
+ }
+ case Qt::TouchPointReleased:
+ {
+ widget = d->widgetForTouchPointId.take(touchPoint.id());
+ if (!widget)
+ continue;
+
+ QTouchEvent::TouchPoint previousTouchPoint = d->appCurrentTouchPoints.take(touchPoint.id());
+ touchPoint.d->startScreenPos = previousTouchPoint.startScreenPos();
+ touchPoint.d->lastScreenPos = previousTouchPoint.screenPos();
+ touchPoint.d->startPos = previousTouchPoint.startPos();
+ touchPoint.d->lastPos = previousTouchPoint.pos();
+ touchPoint.d->startNormalizedPos = previousTouchPoint.startNormalizedPos();
+ touchPoint.d->lastNormalizedPos = previousTouchPoint.normalizedPos();
+ if (touchPoint.pressure() < qreal(0.))
+ touchPoint.d->pressure = qreal(0.);
+ break;
+ }
+ default:
+ widget = d->widgetForTouchPointId.value(touchPoint.id());
+ if (!widget)
+ continue;
+
+ Q_ASSERT(d->appCurrentTouchPoints.contains(touchPoint.id()));
+ QTouchEvent::TouchPoint previousTouchPoint = d->appCurrentTouchPoints.value(touchPoint.id());
+ touchPoint.d->startScreenPos = previousTouchPoint.startScreenPos();
+ touchPoint.d->lastScreenPos = previousTouchPoint.screenPos();
+ touchPoint.d->startPos = previousTouchPoint.startPos();
+ touchPoint.d->lastPos = previousTouchPoint.pos();
+ touchPoint.d->startNormalizedPos = previousTouchPoint.startNormalizedPos();
+ touchPoint.d->lastNormalizedPos = previousTouchPoint.normalizedPos();
+ if (touchPoint.pressure() < qreal(0.))
+ touchPoint.d->pressure = qreal(1.);
+ d->appCurrentTouchPoints[touchPoint.id()] = touchPoint;
+ break;
+ }
+ Q_ASSERT(widget.data() != 0);
+
+ // make the *scene* functions return the same as the *screen* functions
+ touchPoint.d->sceneRect = touchPoint.screenRect();
+ touchPoint.d->startScenePos = touchPoint.startScreenPos();
+ touchPoint.d->lastScenePos = touchPoint.lastScreenPos();
+
+ StatesAndTouchPoints &maskAndPoints = widgetsNeedingEvents[widget.data()];
+ maskAndPoints.first |= touchPoint.state();
+ if (touchPoint.isPrimary())
+ maskAndPoints.first |= Qt::TouchPointPrimary;
+ maskAndPoints.second.append(touchPoint);
+ }
+
+ if (widgetsNeedingEvents.isEmpty())
+ return;
+
+ QHash<QWidget *, StatesAndTouchPoints>::ConstIterator it = widgetsNeedingEvents.constBegin();
+ const QHash<QWidget *, StatesAndTouchPoints>::ConstIterator end = widgetsNeedingEvents.constEnd();
+ for (; it != end; ++it) {
+ QWidget *widget = it.key();
+ if (!QApplicationPrivate::tryModalHelper(widget, 0))
+ continue;
+
+ QEvent::Type eventType;
+ switch (it.value().first & Qt::TouchPointStateMask) {
+ case Qt::TouchPointPressed:
+ eventType = QEvent::TouchBegin;
+ break;
+ case Qt::TouchPointReleased:
+ eventType = QEvent::TouchEnd;
+ break;
+ case Qt::TouchPointStationary:
+ // don't send the event if nothing changed
+ continue;
+ default:
+ eventType = QEvent::TouchUpdate;
+ break;
+ }
+
+ QTouchEvent touchEvent(eventType,
+ deviceType,
+ QApplication::keyboardModifiers(),
+ it.value().first,
+ it.value().second);
+ updateTouchPointsForWidget(widget, &touchEvent);
+
+ switch (touchEvent.type()) {
+ case QEvent::TouchBegin:
+ {
+ // if the TouchBegin handler recurses, we assume that means the event
+ // has been implicitly accepted and continue to send touch events
+ widget->setAttribute(Qt::WA_WState_AcceptedTouchBeginEvent);
+ (void ) QApplication::sendSpontaneousEvent(widget, &touchEvent);
+ break;
+ }
+ default:
+ if (widget->testAttribute(Qt::WA_WState_AcceptedTouchBeginEvent)) {
+ if (touchEvent.type() == QEvent::TouchEnd)
+ widget->setAttribute(Qt::WA_WState_AcceptedTouchBeginEvent, false);
+ (void) QApplication::sendSpontaneousEvent(widget, &touchEvent);
+ }
+ break;
+ }
+ }
+}
+
+Q_WIDGETS_EXPORT void qt_translateRawTouchEvent(QWidget *window,
+ QTouchEvent::DeviceType deviceType,
+ const QList<QTouchEvent::TouchPoint> &touchPoints)
+{
+ QApplicationPrivate::translateRawTouchEvent(window, deviceType, touchPoints);
+}
+
+#ifndef QT_NO_GESTURES
+QGestureManager* QGestureManager::instance()
+{
+ QApplicationPrivate *qAppPriv = QApplicationPrivate::instance();
+ if (!qAppPriv)
+ return 0;
+ if (!qAppPriv->gestureManager)
+ qAppPriv->gestureManager = new QGestureManager(qApp);
+ return qAppPriv->gestureManager;
+}
+#endif // QT_NO_GESTURES
+
+QT_END_NAMESPACE
+
+#include "moc_qapplication.cpp"
diff --git a/src/widgets/kernel/qapplication.h b/src/widgets/kernel/qapplication.h
new file mode 100644
index 0000000000..aec2c07763
--- /dev/null
+++ b/src/widgets/kernel/qapplication.h
@@ -0,0 +1,423 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QAPPLICATION_H
+#define QAPPLICATION_H
+
+#include <QtCore/qcoreapplication.h>
+#include <QtGui/qwindowdefs.h>
+#include <QtCore/qpoint.h>
+#include <QtCore/qsize.h>
+#include <QtGui/qcursor.h>
+#ifdef QT_INCLUDE_COMPAT
+# include <QtWidgets/qdesktopwidget.h>
+#endif
+#ifdef QT3_SUPPORT
+# include <QtWidgets/qwidget.h>
+# include <QtGui/qpalette.h>
+#endif
+#ifdef Q_WS_QWS
+# include <QtGui/qrgb.h>
+# include <QtGui/qtransportauth_qws.h>
+#endif
+#ifdef Q_WS_QPA
+# include <QtGui/qguiapplication.h>
+#endif
+
+QT_BEGIN_HEADER
+
+#if defined(Q_OS_SYMBIAN)
+class CApaApplication;
+#endif
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QSessionManager;
+class QDesktopWidget;
+class QStyle;
+class QEventLoop;
+class QIcon;
+class QInputContext;
+template <typename T> class QList;
+class QLocale;
+#if defined(Q_WS_QWS)
+class QDecoration;
+#elif defined(Q_WS_QPA)
+class QPlatformNativeInterface;
+#endif
+#if defined(Q_OS_SYMBIAN)
+class QSymbianEvent;
+#endif
+
+class QApplication;
+class QApplicationPrivate;
+#if defined(qApp)
+#undef qApp
+#endif
+#define qApp (static_cast<QApplication *>(QCoreApplication::instance()))
+
+#ifdef Q_WS_QPA
+#define QApplicationBase QGuiApplication
+#else
+#define QApplicationBase QCoreApplication
+#endif
+
+class Q_WIDGETS_EXPORT QApplication : public QApplicationBase
+{
+ Q_OBJECT
+ Q_PROPERTY(QIcon windowIcon READ windowIcon WRITE setWindowIcon)
+ Q_PROPERTY(int cursorFlashTime READ cursorFlashTime WRITE setCursorFlashTime)
+ Q_PROPERTY(int doubleClickInterval READ doubleClickInterval WRITE setDoubleClickInterval)
+ Q_PROPERTY(int keyboardInputInterval READ keyboardInputInterval WRITE setKeyboardInputInterval)
+#ifndef QT_NO_WHEELEVENT
+ Q_PROPERTY(int wheelScrollLines READ wheelScrollLines WRITE setWheelScrollLines)
+#endif
+ Q_PROPERTY(QSize globalStrut READ globalStrut WRITE setGlobalStrut)
+ Q_PROPERTY(int startDragTime READ startDragTime WRITE setStartDragTime)
+ Q_PROPERTY(int startDragDistance READ startDragDistance WRITE setStartDragDistance)
+ Q_PROPERTY(bool quitOnLastWindowClosed READ quitOnLastWindowClosed WRITE setQuitOnLastWindowClosed)
+#ifndef QT_NO_STYLE_STYLESHEET
+ Q_PROPERTY(QString styleSheet READ styleSheet WRITE setStyleSheet)
+#endif
+#ifdef Q_WS_WINCE
+ Q_PROPERTY(int autoMaximizeThreshold READ autoMaximizeThreshold WRITE setAutoMaximizeThreshold)
+#endif
+ Q_PROPERTY(bool autoSipEnabled READ autoSipEnabled WRITE setAutoSipEnabled)
+
+public:
+ enum Type { Tty, GuiClient, GuiServer };
+
+#ifdef Q_OS_SYMBIAN
+ typedef CApaApplication * (*QS60MainApplicationFactory)();
+#endif
+
+#ifndef qdoc
+ QApplication(int &argc, char **argv, int = ApplicationFlags);
+ QApplication(int &argc, char **argv, bool GUIenabled, int = ApplicationFlags);
+ QApplication(int &argc, char **argv, Type, int = ApplicationFlags);
+#if defined(Q_WS_X11)
+ QApplication(Display* dpy, Qt::HANDLE visual = 0, Qt::HANDLE cmap = 0, int = ApplicationFlags);
+ QApplication(Display *dpy, int &argc, char **argv, Qt::HANDLE visual = 0, Qt::HANDLE cmap= 0, int = ApplicationFlags);
+#endif
+#if defined(Q_OS_SYMBIAN)
+ QApplication(QApplication::QS60MainApplicationFactory factory, int &argc, char **argv, int = ApplicationFlags);
+#endif
+#endif
+ virtual ~QApplication();
+
+ static Type type();
+
+ static QStyle *style();
+ static void setStyle(QStyle*);
+ static QStyle *setStyle(const QString&);
+ enum ColorSpec { NormalColor=0, CustomColor=1, ManyColor=2 };
+ static int colorSpec();
+ static void setColorSpec(int);
+ // ### Qt4 compatibility, remove?
+ static inline void setGraphicsSystem(const QString &) {}
+
+ using QGuiApplication::palette;
+ static QPalette palette(const QWidget *);
+ static QPalette palette(const char *className);
+ static void setPalette(const QPalette &, const char* className = 0);
+ static QFont font();
+ static QFont font(const QWidget*);
+ static QFont font(const char *className);
+ static void setFont(const QFont &, const char* className = 0);
+ static QFontMetrics fontMetrics();
+
+ static void setWindowIcon(const QIcon &icon);
+ static QIcon windowIcon();
+
+
+#ifdef QT3_SUPPORT
+ static QT3_SUPPORT QWidget *mainWidget();
+ static QT3_SUPPORT void setMainWidget(QWidget *);
+#endif
+
+ static QWidgetList allWidgets();
+ static QWidgetList topLevelWidgets();
+
+ static QDesktopWidget *desktop();
+
+ static QWidget *activePopupWidget();
+ static QWidget *activeModalWidget();
+#if !defined(Q_WS_QPA) && !defined(QT_NO_CLIPBOARD)
+ static QClipboard *clipboard();
+#endif
+ static QWidget *focusWidget();
+
+ static QWidget *activeWindow();
+ static void setActiveWindow(QWidget* act);
+
+ static QWidget *widgetAt(const QPoint &p);
+ static inline QWidget *widgetAt(int x, int y) { return widgetAt(QPoint(x, y)); }
+ static QWidget *topLevelAt(const QPoint &p);
+ static inline QWidget *topLevelAt(int x, int y) { return topLevelAt(QPoint(x, y)); }
+
+ static void syncX();
+ static void beep();
+ static void alert(QWidget *widget, int duration = 0);
+
+ static Qt::KeyboardModifiers keyboardModifiers();
+ static Qt::KeyboardModifiers queryKeyboardModifiers();
+ static Qt::MouseButtons mouseButtons();
+
+ static void setDesktopSettingsAware(bool);
+ static bool desktopSettingsAware();
+
+ static void setCursorFlashTime(int);
+ static int cursorFlashTime();
+
+ static void setDoubleClickInterval(int);
+ static int doubleClickInterval();
+
+ static void setKeyboardInputInterval(int);
+ static int keyboardInputInterval();
+
+#ifndef QT_NO_WHEELEVENT
+ static void setWheelScrollLines(int);
+ static int wheelScrollLines();
+#endif
+ static void setGlobalStrut(const QSize &);
+ static QSize globalStrut();
+
+ static void setStartDragTime(int ms);
+ static int startDragTime();
+ static void setStartDragDistance(int l);
+ static int startDragDistance();
+
+ static bool isEffectEnabled(Qt::UIEffect);
+ static void setEffectEnabled(Qt::UIEffect, bool enable = true);
+
+#if defined(Q_WS_MAC)
+ virtual bool macEventFilter(EventHandlerCallRef, EventRef);
+#endif
+#if defined(Q_WS_X11)
+ virtual bool x11EventFilter(XEvent *);
+ virtual int x11ClientMessage(QWidget*, XEvent*, bool passive_only);
+ int x11ProcessEvent(XEvent*);
+#endif
+#if defined(Q_OS_SYMBIAN)
+ int symbianProcessEvent(const QSymbianEvent *event);
+ virtual bool symbianEventFilter(const QSymbianEvent *event);
+#endif
+#if defined(Q_WS_QWS)
+ virtual bool qwsEventFilter(QWSEvent *);
+ int qwsProcessEvent(QWSEvent*);
+ void qwsSetCustomColors(QRgb *colortable, int start, int numColors);
+#ifndef QT_NO_QWS_MANAGER
+ static QDecoration &qwsDecoration();
+ static void qwsSetDecoration(QDecoration *);
+ static QDecoration *qwsSetDecoration(const QString &decoration);
+#endif
+#endif
+
+#if defined(Q_WS_QPA)
+ static QPlatformNativeInterface *platformNativeInterface();
+#endif
+
+
+#if defined(Q_WS_WIN)
+ void winFocus(QWidget *, bool);
+ static void winMouseButtonUp();
+#endif
+#ifndef QT_NO_SESSIONMANAGER
+ // session management
+ bool isSessionRestored() const;
+ QString sessionId() const;
+ QString sessionKey() const;
+ virtual void commitData(QSessionManager& sm);
+ virtual void saveState(QSessionManager& sm);
+#endif
+
+#ifndef QT_NO_IM
+ void setInputContext(QInputContext *);
+ QInputContext *inputContext() const;
+#endif
+
+ static int exec();
+ bool notify(QObject *, QEvent *);
+
+
+ static void setQuitOnLastWindowClosed(bool quit);
+ static bool quitOnLastWindowClosed();
+
+#ifdef QT_KEYPAD_NAVIGATION
+ static Q_DECL_DEPRECATED void setKeypadNavigationEnabled(bool);
+ static bool keypadNavigationEnabled();
+ static void setNavigationMode(Qt::NavigationMode mode);
+ static Qt::NavigationMode navigationMode();
+#endif
+
+Q_SIGNALS:
+ void lastWindowClosed();
+ void focusChanged(QWidget *old, QWidget *now);
+#ifndef QT_NO_SESSIONMANAGER
+ void commitDataRequest(QSessionManager &sessionManager);
+ void saveStateRequest(QSessionManager &sessionManager);
+#endif
+
+public:
+ QString styleSheet() const;
+public Q_SLOTS:
+#ifndef QT_NO_STYLE_STYLESHEET
+ void setStyleSheet(const QString& sheet);
+#endif
+#ifdef Q_WS_WINCE
+ void setAutoMaximizeThreshold(const int threshold);
+ int autoMaximizeThreshold() const;
+#endif
+ void setAutoSipEnabled(const bool enabled);
+ bool autoSipEnabled() const;
+ static void closeAllWindows();
+ static void aboutQt();
+
+protected:
+#if defined(Q_WS_QWS)
+ void setArgs(int, char **);
+#endif
+ bool event(QEvent *);
+ bool compressEvent(QEvent *, QObject *receiver, QPostEventList *);
+
+#ifdef QT3_SUPPORT
+public:
+ static inline QT3_SUPPORT void setReverseLayout(bool b) { setLayoutDirection(b?Qt::RightToLeft:Qt::LeftToRight); }
+ static inline bool QT3_SUPPORT reverseLayout() { return layoutDirection() == Qt::RightToLeft; }
+ static QT3_SUPPORT Qt::Alignment horizontalAlignment(Qt::Alignment align);
+ typedef int ColorMode;
+ enum { NormalColors = NormalColor, CustomColors = CustomColor };
+ static inline QT3_SUPPORT ColorMode colorMode() { return static_cast<ColorMode>(colorSpec()); }
+ static inline QT3_SUPPORT void setColorMode(ColorMode mode) { setColorSpec(int(mode)); }
+#if defined(Q_OS_WIN32) || defined(Q_OS_CYGWIN)
+ static QT3_SUPPORT Qt::WindowsVersion winVersion() { return (Qt::WindowsVersion)QSysInfo::WindowsVersion; }
+#endif
+#if defined(Q_OS_MAC)
+ static QT3_SUPPORT Qt::MacintoshVersion macVersion() { return (Qt::MacintoshVersion)QSysInfo::MacintoshVersion; }
+#endif
+# ifndef QT_NO_CURSOR
+ inline static QT3_SUPPORT void setOverrideCursor(const QCursor &cursor, bool replace)
+ { if (replace) changeOverrideCursor(cursor); else setOverrideCursor(cursor); }
+# endif
+ inline static QT3_SUPPORT bool hasGlobalMouseTracking() {return true;}
+ inline static QT3_SUPPORT void setGlobalMouseTracking(bool) {}
+ inline static QT3_SUPPORT void flushX() { flush(); }
+ static inline QT3_SUPPORT void setWinStyleHighlightColor(const QColor &c) {
+ QPalette p(palette());
+ p.setColor(QPalette::Highlight, c);
+ setPalette(p);
+ }
+ static inline QT3_SUPPORT const QColor &winStyleHighlightColor()
+ { return palette().color(QPalette::Active, QPalette::Highlight); }
+ static inline QT3_SUPPORT void setPalette(const QPalette &pal, bool, const char* className = 0)
+ { setPalette(pal, className); }
+ static inline QT3_SUPPORT void setFont(const QFont &font, bool, const char* className = 0)
+ { setFont(font, className); }
+
+ static inline QT3_SUPPORT QWidget *widgetAt(int x, int y, bool child)
+ { QWidget *w = widgetAt(x, y); return child ? w : (w ? w->window() : 0); }
+ static inline QT3_SUPPORT QWidget *widgetAt(const QPoint &p, bool child)
+ { QWidget *w = widgetAt(p); return child ? w : (w ? w->window() : 0); }
+#endif // QT3_SUPPORT
+
+#if defined(Q_INTERNAL_QAPP_SRC) || defined(qdoc)
+ QApplication(int &argc, char **argv);
+ QApplication(int &argc, char **argv, bool GUIenabled);
+ QApplication(int &argc, char **argv, Type);
+#if defined(Q_WS_X11)
+ QApplication(Display* dpy, Qt::HANDLE visual = 0, Qt::HANDLE cmap = 0);
+ QApplication(Display *dpy, int &argc, char **argv, Qt::HANDLE visual = 0, Qt::HANDLE cmap= 0);
+#endif
+#if defined(Q_OS_SYMBIAN) || defined(qdoc)
+ QApplication(QApplication::QS60MainApplicationFactory factory, int &argc, char **argv);
+#endif
+#endif
+
+private:
+ Q_DISABLE_COPY(QApplication)
+ Q_DECLARE_PRIVATE(QApplication)
+
+ friend class QGraphicsWidget;
+ friend class QGraphicsItem;
+ friend class QGraphicsScene;
+ friend class QGraphicsScenePrivate;
+ friend class QWidget;
+ friend class QWidgetPrivate;
+ friend class QWidgetWindow;
+ friend class QETWidget;
+ friend class Q3AccelManager;
+ friend class QTranslator;
+ friend class QWidgetAnimator;
+#ifndef QT_NO_SHORTCUT
+ friend class QShortcut;
+ friend class QLineEdit;
+ friend class QWidgetTextControl;
+#endif
+ friend class QAction;
+
+#if defined(Q_WS_QWS)
+ friend class QInputContext;
+ friend class QWSDirectPainterSurface;
+ friend class QDirectPainter;
+ friend class QDirectPainterPrivate;
+#endif
+#ifndef QT_NO_GESTURES
+ friend class QGestureManager;
+#endif
+
+#if defined(Q_WS_MAC) || defined(Q_WS_X11)
+ Q_PRIVATE_SLOT(d_func(), void _q_alertTimeOut())
+#endif
+#if defined(QT_RX71_MULTITOUCH)
+ Q_PRIVATE_SLOT(d_func(), void _q_readRX71MultiTouchEvents())
+#endif
+#if defined(Q_OS_SYMBIAN)
+ Q_PRIVATE_SLOT(d_func(), void _q_aboutToQuit())
+#endif
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QAPPLICATION_H
diff --git a/src/widgets/kernel/qapplication_p.h b/src/widgets/kernel/qapplication_p.h
new file mode 100644
index 0000000000..6efee02195
--- /dev/null
+++ b/src/widgets/kernel/qapplication_p.h
@@ -0,0 +1,632 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QAPPLICATION_P_H
+#define QAPPLICATION_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of qapplication_*.cpp, qwidget*.cpp, qcolor_x11.cpp, qfiledialog.cpp
+// and many other. This header file may change from version to version
+// without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "QtWidgets/qapplication.h"
+#include "QtGui/qevent.h"
+#include "QtGui/qfont.h"
+#include "QtGui/qcursor.h"
+#include "QtGui/qregion.h"
+#include "QtGui/qwindow.h"
+#include "qwidget.h"
+#include "QtGui/qplatformnativeinterface_qpa.h"
+#include "QtCore/qmutex.h"
+#include "QtCore/qtranslator.h"
+#include "QtCore/qbasictimer.h"
+#include "QtCore/qhash.h"
+#include "QtCore/qpointer.h"
+#include "private/qcoreapplication_p.h"
+#include "private/qshortcutmap_p.h"
+#include <private/qthread_p.h>
+#include "QtCore/qpoint.h"
+#include <QTime>
+#ifdef Q_OS_SYMBIAN
+#include <w32std.h>
+#endif
+#ifdef Q_WS_QPA
+#include <QWindowSystemInterface>
+#include "private/qwindowsysteminterface_qpa_p.h"
+#include "QtGui/qplatformintegration_qpa.h"
+#include "private/qguiapplication_p.h"
+#endif
+
+QT_BEGIN_NAMESPACE
+
+class QClipboard;
+class QGraphicsScene;
+class QInputContext;
+class QObject;
+class QWidget;
+class QSocketNotifier;
+#ifndef QT_NO_GESTURES
+class QGestureManager;
+#endif
+
+extern bool qt_is_gui_used;
+#ifndef QT_NO_CLIPBOARD
+extern QClipboard *qt_clipboard;
+#endif
+
+#if defined (Q_OS_WIN32) || defined (Q_OS_CYGWIN) || defined(Q_OS_WINCE)
+extern QSysInfo::WinVersion qt_winver;
+enum { QT_TABLET_NPACKETQSIZE = 128 };
+# ifdef Q_OS_WINCE
+ extern DWORD qt_cever;
+# endif
+#elif defined (Q_OS_MAC)
+extern QSysInfo::MacVersion qt_macver;
+#endif
+#if defined(Q_WS_QWS)
+class QWSManager;
+class QDirectPainter;
+struct QWSServerCleaner { ~QWSServerCleaner(); };
+#endif
+
+#ifndef QT_NO_TABLET
+struct QTabletDeviceData
+{
+#ifndef Q_WS_MAC
+ int minPressure;
+ int maxPressure;
+ int minTanPressure;
+ int maxTanPressure;
+ int minX, maxX, minY, maxY, minZ, maxZ;
+ inline QPointF scaleCoord(int coordX, int coordY, int outOriginX, int outExtentX,
+ int outOriginY, int outExtentY) const;
+#endif
+
+#if defined(Q_WS_X11) || (defined(Q_WS_MAC) && !defined(QT_MAC_USE_COCOA))
+ QPointer<QWidget> widgetToGetPress;
+#endif
+
+#ifdef Q_WS_X11
+ int deviceType;
+ enum {
+ TOTAL_XINPUT_EVENTS = 64
+ };
+ void *device;
+ int eventCount;
+ long unsigned int eventList[TOTAL_XINPUT_EVENTS]; // XEventClass is in fact a long unsigned int
+
+ int xinput_motion;
+ int xinput_key_press;
+ int xinput_key_release;
+ int xinput_button_press;
+ int xinput_button_release;
+ int xinput_proximity_in;
+ int xinput_proximity_out;
+#elif defined(Q_WS_WIN)
+ qint64 llId;
+ int currentDevice;
+ int currentPointerType;
+#elif defined(Q_WS_MAC)
+ quint64 tabletUniqueID;
+ int tabletDeviceType;
+ int tabletPointerType;
+ int capabilityMask;
+#endif
+};
+
+static inline int sign(int x)
+{
+ return x >= 0 ? 1 : -1;
+}
+
+#ifndef Q_WS_MAC
+inline QPointF QTabletDeviceData::scaleCoord(int coordX, int coordY,
+ int outOriginX, int outExtentX,
+ int outOriginY, int outExtentY) const
+{
+ QPointF ret;
+
+ if (sign(outExtentX) == sign(maxX))
+ ret.setX(((coordX - minX) * qAbs(outExtentX) / qAbs(qreal(maxX - minX))) + outOriginX);
+ else
+ ret.setX(((qAbs(maxX) - (coordX - minX)) * qAbs(outExtentX) / qAbs(qreal(maxX - minX)))
+ + outOriginX);
+
+ if (sign(outExtentY) == sign(maxY))
+ ret.setY(((coordY - minY) * qAbs(outExtentY) / qAbs(qreal(maxY - minY))) + outOriginY);
+ else
+ ret.setY(((qAbs(maxY) - (coordY - minY)) * qAbs(outExtentY) / qAbs(qreal(maxY - minY)))
+ + outOriginY);
+
+ return ret;
+}
+#endif
+
+typedef QList<QTabletDeviceData> QTabletDeviceDataList;
+QTabletDeviceDataList *qt_tablet_devices();
+# if defined(Q_WS_MAC)
+typedef QHash<int, QTabletDeviceData> QMacTabletHash;
+QMacTabletHash *qt_mac_tablet_hash();
+# endif
+#endif
+
+#ifdef QT3_SUPPORT
+extern "C" {
+ typedef bool (*Ptrqt_tryAccelEvent)(QWidget *w, QKeyEvent *e);
+ typedef bool (*Ptrqt_tryComposeUnicode)(QWidget *w, QKeyEvent *e);
+ typedef bool (*Ptrqt_dispatchAccelEvent)(QWidget *w, QKeyEvent *e);
+}
+#endif
+
+#if defined(Q_WS_WIN)
+typedef BOOL (WINAPI *PtrRegisterTouchWindow)(HWND, ULONG);
+typedef BOOL (WINAPI *PtrGetTouchInputInfo)(HANDLE, UINT, PVOID, int);
+typedef BOOL (WINAPI *PtrCloseTouchInputHandle)(HANDLE);
+
+#ifndef QT_NO_GESTURES
+typedef BOOL (WINAPI *PtrGetGestureInfo)(HANDLE, PVOID);
+typedef BOOL (WINAPI *PtrGetGestureExtraArgs)(HANDLE, UINT, PBYTE);
+typedef BOOL (WINAPI *PtrCloseGestureInfoHandle)(HANDLE);
+typedef BOOL (WINAPI *PtrSetGestureConfig)(HWND, DWORD, UINT, PVOID, UINT);
+typedef BOOL (WINAPI *PtrGetGestureConfig)(HWND, DWORD, DWORD, PUINT, PVOID, UINT);
+
+typedef BOOL (WINAPI *PtrBeginPanningFeedback)(HWND);
+typedef BOOL (WINAPI *PtrUpdatePanningFeedback)(HWND, LONG, LONG, BOOL);
+typedef BOOL (WINAPI *PtrEndPanningFeedback)(HWND, BOOL);
+
+#ifndef WM_GESTURE
+# define WM_GESTURE 0x0119
+
+# define GID_BEGIN 1
+# define GID_END 2
+# define GID_ZOOM 3
+# define GID_PAN 4
+# define GID_ROTATE 5
+# define GID_TWOFINGERTAP 6
+# define GID_ROLLOVER 7
+
+typedef struct tagGESTUREINFO
+{
+ UINT cbSize;
+ DWORD dwFlags;
+ DWORD dwID;
+ HWND hwndTarget;
+ POINTS ptsLocation;
+ DWORD dwInstanceID;
+ DWORD dwSequenceID;
+ ULONGLONG ullArguments;
+ UINT cbExtraArgs;
+} GESTUREINFO;
+
+# define GC_PAN 0x00000001
+# define GC_PAN_WITH_SINGLE_FINGER_VERTICALLY 0x00000002
+# define GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY 0x00000004
+
+# define GC_ZOOM 0x00000001
+# define GC_ROTATE 0x00000001
+
+typedef struct tagGESTURECONFIG
+{
+ DWORD dwID;
+ DWORD dwWant;
+ DWORD dwBlock;
+} GESTURECONFIG;
+
+# define GID_ROTATE_ANGLE_FROM_ARGUMENT(arg) ((((double)(arg) / 65535.0) * 4.0 * 3.14159265) - 2.0*3.14159265)
+
+#endif // WM_GESTURE
+
+#if defined(Q_WS_WINCE_WM) && defined(QT_WINCE_GESTURES)
+#undef GID_ZOOM
+#define GID_ZOOM 0xf000
+#undef GID_ROTATE
+#define GID_ROTATE 0xf001
+#undef GID_TWOFINGERTAP
+#define GID_TWOFINGERTAP 0xf002
+#undef GID_ROLLOVER
+#define GID_ROLLOVER 0xf003
+#endif
+
+#endif // QT_NO_GESTURES
+
+#endif // Q_WS_WIN
+
+class QScopedLoopLevelCounter
+{
+ QThreadData *threadData;
+public:
+ QScopedLoopLevelCounter(QThreadData *threadData)
+ : threadData(threadData)
+ { ++threadData->loopLevel; }
+ ~QScopedLoopLevelCounter()
+ { --threadData->loopLevel; }
+};
+
+typedef QHash<QByteArray, QFont> FontHash;
+FontHash *qt_app_fonts_hash();
+
+typedef QHash<QByteArray, QPalette> PaletteHash;
+PaletteHash *qt_app_palettes_hash();
+
+#ifdef Q_WS_QPA
+#define QApplicationPrivateBase QGuiApplicationPrivate
+#else
+#define QApplicationPrivateBase QCoreApplicationPrivate
+#endif
+
+class Q_WIDGETS_EXPORT QApplicationPrivate : public QApplicationPrivateBase
+{
+ Q_DECLARE_PUBLIC(QApplication)
+public:
+ QApplicationPrivate(int &argc, char **argv, QApplication::Type type, int flags);
+ ~QApplicationPrivate();
+
+ virtual void notifyLayoutDirectionChange();
+ virtual void notifyActiveWindowChange(QWindow *);
+
+#if defined(Q_WS_X11)
+#ifndef QT_NO_SETTINGS
+ static bool x11_apply_settings();
+#endif
+ static void reset_instance_pointer();
+#elif defined(Q_WS_QWS)
+ static bool qws_apply_settings();
+ static QWidget *findWidget(const QObjectList&, const QPoint &, bool rec);
+#endif
+ static bool quitOnLastWindowClosed;
+ static void emitLastWindowClosed();
+#ifdef Q_WS_WINCE
+ static int autoMaximizeThreshold;
+#endif
+ static bool autoSipEnabled;
+ static QString desktopStyleKey();
+
+
+ void createEventDispatcher();
+ QString appName() const;
+ static void dispatchEnterLeave(QWidget *enter, QWidget *leave);
+
+ //modality
+ static void enterModal(QWidget*);
+ static void leaveModal(QWidget*);
+ static void enterModal_sys(QWidget*);
+ static void leaveModal_sys(QWidget*);
+ static bool isBlockedByModal(QWidget *widget);
+ static bool modalState();
+ static bool tryModalHelper(QWidget *widget, QWidget **rettop = 0);
+#ifdef Q_WS_MAC
+ static QWidget *tryModalHelper_sys(QWidget *top);
+ bool canQuit();
+#endif
+
+ bool notify_helper(QObject *receiver, QEvent * e);
+
+ void construct(
+#ifdef Q_WS_X11
+ Display *dpy = 0, Qt::HANDLE visual = 0, Qt::HANDLE cmap = 0
+#endif
+ );
+ void initialize();
+ void process_cmdline();
+
+#if defined(Q_WS_X11)
+ static void x11_initialize_style();
+#endif
+
+ bool inPopupMode() const;
+ void closePopup(QWidget *popup);
+ void openPopup(QWidget *popup);
+ static void setFocusWidget(QWidget *focus, Qt::FocusReason reason);
+ static QWidget *focusNextPrevChild_helper(QWidget *toplevel, bool next);
+
+#ifndef QT_NO_SESSIONMANAGER
+ QSessionManager *session_manager;
+ QString session_id;
+ QString session_key;
+ bool is_session_restored;
+#endif
+
+#ifndef QT_NO_GRAPHICSVIEW
+ // Maintain a list of all scenes to ensure font and palette propagation to
+ // all scenes.
+ QList<QGraphicsScene *> scene_list;
+#endif
+
+ QBasicTimer toolTipWakeUp, toolTipFallAsleep;
+ QPoint toolTipPos, toolTipGlobalPos, hoverGlobalPos;
+ QPointer<QWidget> toolTipWidget;
+#ifndef QT_NO_SHORTCUT
+ QShortcutMap shortcutMap;
+#endif
+
+#ifdef QT3_SUPPORT
+ bool qt_compat_used;
+ bool qt_compat_resolved;
+ Ptrqt_tryAccelEvent qt_tryAccelEvent;
+ Ptrqt_tryComposeUnicode qt_tryComposeUnicode;
+ Ptrqt_dispatchAccelEvent qt_dispatchAccelEvent;
+
+ bool use_compat() {
+ return qt_tryAccelEvent
+ && qt_tryComposeUnicode
+ && qt_dispatchAccelEvent;
+ }
+#endif
+ static QInputContext *inputContext;
+
+ static Qt::MouseButtons mouse_buttons;
+ static Qt::KeyboardModifiers modifier_buttons;
+
+ static QSize app_strut;
+ static QWidgetList *popupWidgets;
+ static QStyle *app_style;
+ static int app_cspec;
+ static QPalette *sys_pal;
+ static QPalette *set_pal;
+
+private:
+#ifndef Q_WS_QPA
+ static QFont *app_font; // private for a reason! Always use QApplication::font() instead!
+#endif
+public:
+ static QFont *sys_font;
+ static QFont *set_font;
+ static QWidget *main_widget;
+ static QWidget *focus_widget;
+ static QWidget *hidden_focus_widget;
+ static QWidget *active_window;
+ static QIcon *app_icon;
+ static bool obey_desktop_settings;
+#ifndef QT_NO_WHEELEVENT
+ static int wheel_scroll_lines;
+#endif
+
+ static bool animate_ui;
+ static bool animate_menu;
+ static bool animate_tooltip;
+ static bool animate_combo;
+ static bool fade_menu;
+ static bool fade_tooltip;
+ static bool animate_toolbox;
+ static bool widgetCount; // Coupled with -widgetcount switch
+ static bool load_testability; // Coupled with -testability switch
+
+#ifdef Q_WS_MAC
+ static bool native_modal_dialog_active;
+#endif
+
+ static void setSystemPalette(const QPalette &pal);
+ static void setPalette_helper(const QPalette &palette, const char* className, bool clearWidgetPaletteHash);
+ static void initializeWidgetPaletteHash();
+ static void setSystemFont(const QFont &font);
+
+#if defined(Q_WS_X11)
+ static void applyX11SpecificCommandLineArguments(QWidget *main_widget);
+#elif defined(Q_WS_QWS)
+ static void applyQWSSpecificCommandLineArguments(QWidget *main_widget);
+#endif
+
+#ifdef Q_WS_MAC
+ static OSStatus globalEventProcessor(EventHandlerCallRef, EventRef, void *);
+ static OSStatus globalAppleEventProcessor(const AppleEvent *, AppleEvent *, long);
+ static OSStatus tabletProximityCallback(EventHandlerCallRef, EventRef, void *);
+#ifdef QT_MAC_USE_COCOA
+ static void qt_initAfterNSAppStarted();
+ static void setupAppleEvents();
+#endif
+ static bool qt_mac_apply_settings();
+#endif
+
+#ifdef Q_WS_QWS
+ QPointer<QWSManager> last_manager;
+ QWSServerCleaner qwsServerCleaner;
+# ifndef QT_NO_DIRECTPAINTER
+ QMap<WId, QDirectPainter *> *directPainters;
+# endif
+ QRect maxWindowRect(const QScreen *screen) const { return maxWindowRects[screen]; }
+ void setMaxWindowRect(const QScreen *screen, int screenNo, const QRect &rect);
+ void setScreenTransformation(QScreen *screen, int screenNo, int transformation);
+#endif
+
+ static QApplicationPrivate *instance() { return self; }
+
+ static QString styleOverride;
+
+#ifdef QT_KEYPAD_NAVIGATION
+ static QWidget *oldEditFocus;
+ static Qt::NavigationMode navigationMode;
+#endif
+
+#if defined(Q_WS_MAC) || defined(Q_WS_X11)
+ void _q_alertTimeOut();
+ QHash<QWidget *, QTimer *> alertTimerHash;
+#endif
+#ifndef QT_NO_STYLE_STYLESHEET
+ static QString styleSheet;
+#endif
+ static QPointer<QWidget> leaveAfterRelease;
+ static QWidget *pickMouseReceiver(QWidget *candidate, const QPoint &globalPos, QPoint &pos,
+ QEvent::Type type, Qt::MouseButtons buttons,
+ QWidget *buttonDown, QWidget *alienWidget);
+ static bool sendMouseEvent(QWidget *receiver, QMouseEvent *event, QWidget *alienWidget,
+ QWidget *native, QWidget **buttonDown, QPointer<QWidget> &lastMouseReceiver,
+ bool spontaneous = true);
+#ifdef Q_OS_SYMBIAN
+ static void setNavigationMode(Qt::NavigationMode mode);
+ static TUint resolveS60ScanCode(TInt scanCode, TUint keysym);
+ QSet<WId> nativeWindows;
+
+ int symbianProcessWsEvent(const QSymbianEvent *symbianEvent);
+ int symbianHandleCommand(const QSymbianEvent *symbianEvent);
+ int symbianResourceChange(const QSymbianEvent *symbianEvent);
+
+ void _q_aboutToQuit();
+#endif
+#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) || defined(Q_WS_MAC) || defined(Q_WS_QPA)
+ void sendSyntheticEnterLeave(QWidget *widget);
+#endif
+#ifdef Q_OS_WIN
+ static HWND getHWNDForWidget(QWidget *widget)
+ {
+ QWindow *window = widget->windowHandle();
+ return static_cast<HWND> (QGuiApplication::platformNativeInterface()->nativeResourceForWindow("handle", window));
+ }
+#endif
+
+#ifndef QT_NO_GESTURES
+ QGestureManager *gestureManager;
+ QWidget *gestureWidget;
+#endif
+#if defined(Q_WS_X11) || defined(Q_WS_WIN)
+ QPixmap *move_cursor;
+ QPixmap *copy_cursor;
+ QPixmap *link_cursor;
+#endif
+#if defined(Q_WS_WIN)
+ QPixmap *ignore_cursor;
+#endif
+
+ QMap<int, QWeakPointer<QWidget> > widgetForTouchPointId;
+ QMap<int, QTouchEvent::TouchPoint> appCurrentTouchPoints;
+ static void updateTouchPointsForWidget(QWidget *widget, QTouchEvent *touchEvent);
+ void initializeMultitouch();
+ void initializeMultitouch_sys();
+ void cleanupMultitouch();
+ void cleanupMultitouch_sys();
+ int findClosestTouchPointId(const QPointF &screenPos);
+ void appendTouchPoint(const QTouchEvent::TouchPoint &touchPoint);
+ void removeTouchPoint(int touchPointId);
+ static void translateRawTouchEvent(QWidget *widget,
+ QTouchEvent::DeviceType deviceType,
+ const QList<QTouchEvent::TouchPoint> &touchPoints);
+
+#if defined(Q_WS_WIN)
+ static bool HasTouchSupport;
+ static PtrRegisterTouchWindow RegisterTouchWindow;
+ static PtrGetTouchInputInfo GetTouchInputInfo;
+ static PtrCloseTouchInputHandle CloseTouchInputHandle;
+
+ QHash<DWORD, int> touchInputIDToTouchPointID;
+ bool translateTouchEvent(const MSG &msg);
+
+#ifndef QT_NO_GESTURES
+ PtrGetGestureInfo GetGestureInfo;
+ PtrGetGestureExtraArgs GetGestureExtraArgs;
+ PtrCloseGestureInfoHandle CloseGestureInfoHandle;
+ PtrSetGestureConfig SetGestureConfig;
+ PtrGetGestureConfig GetGestureConfig;
+ PtrBeginPanningFeedback BeginPanningFeedback;
+ PtrUpdatePanningFeedback UpdatePanningFeedback;
+ PtrEndPanningFeedback EndPanningFeedback;
+#endif // QT_NO_GESTURES
+#endif
+
+#ifdef QT_RX71_MULTITOUCH
+ bool hasRX71MultiTouch;
+
+ struct RX71TouchPointState {
+ QSocketNotifier *socketNotifier;
+ QTouchEvent::TouchPoint touchPoint;
+
+ int minX, maxX, scaleX;
+ int minY, maxY, scaleY;
+ int minZ, maxZ;
+ };
+ QList<RX71TouchPointState> allRX71TouchPoints;
+
+ bool readRX71MultiTouchEvents(int deviceNumber);
+ void fakeMouseEventFromRX71TouchEvent();
+ void _q_readRX71MultiTouchEvents();
+#endif
+
+#if defined(Q_OS_SYMBIAN)
+ int pressureSupported;
+ int maxTouchPressure;
+ QList<QTouchEvent::TouchPoint> appAllTouchPoints;
+
+ bool useTranslucentEGLSurfaces;
+#endif
+
+private:
+#ifdef Q_WS_QWS
+ QMap<const QScreen*, QRect> maxWindowRects;
+#endif
+
+#ifdef Q_OS_SYMBIAN
+ QHash<TInt, TUint> scanCodeCache;
+#endif
+
+ static QApplicationPrivate *self;
+
+ static void giveFocusAccordingToFocusPolicy(QWidget *w,
+ Qt::FocusPolicy focusPolicy,
+ Qt::FocusReason focusReason);
+ static bool shouldSetFocus(QWidget *w, Qt::FocusPolicy policy);
+
+
+ static bool isAlien(QWidget *);
+};
+
+Q_WIDGETS_EXPORT void qt_translateRawTouchEvent(QWidget *window,
+ QTouchEvent::DeviceType deviceType,
+ const QList<QTouchEvent::TouchPoint> &touchPoints);
+
+#if defined(Q_WS_WIN)
+ extern void qt_win_set_cursor(QWidget *, bool);
+#elif defined(Q_WS_X11)
+ extern void qt_x11_enforce_cursor(QWidget *, bool);
+ extern void qt_x11_enforce_cursor(QWidget *);
+#elif defined(Q_OS_SYMBIAN)
+ extern void qt_symbian_set_cursor(QWidget *, bool);
+#else
+ extern void qt_qpa_set_cursor(QWidget * w, bool force);
+#endif
+
+QT_END_NAMESPACE
+
+#endif // QAPPLICATION_P_H
diff --git a/src/widgets/kernel/qapplication_qpa.cpp b/src/widgets/kernel/qapplication_qpa.cpp
new file mode 100644
index 0000000000..a7c274233d
--- /dev/null
+++ b/src/widgets/kernel/qapplication_qpa.cpp
@@ -0,0 +1,438 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qapplication_p.h"
+#include "qcolormap.h"
+#include "qpixmapcache.h"
+#ifndef QT_NO_CURSOR
+#include "private/qcursor_p.h"
+#endif
+#include "qscreen.h"
+
+#include "private/qwidget_p.h"
+#include "private/qevent_p.h"
+
+#include "qgenericpluginfactory_qpa.h"
+#include "private/qplatformintegrationfactory_qpa_p.h"
+#include <qdesktopwidget.h>
+
+#include <qinputcontext.h>
+#include <QPlatformCursor>
+#include <qdebug.h>
+#include <QWindowSystemInterface>
+#include "private/qwindowsysteminterface_qpa_p.h"
+#include <QPlatformIntegration>
+
+#include "qdesktopwidget_qpa_p.h"
+#include "qwidgetwindow_qpa_p.h"
+
+QT_BEGIN_NAMESPACE
+
+static QString appName;
+static QString appFont;
+static bool popupGrabOk;
+extern bool app_do_modal;
+extern QWidgetList *qt_modal_stack;
+extern QWidget *qt_button_down;
+extern QWidget *qt_popup_down;
+extern bool qt_replay_popup_mouse_event;
+int openPopupCount = 0;
+
+QString QApplicationPrivate::appName() const
+{
+ return QT_PREPEND_NAMESPACE(appName);
+}
+
+void QApplicationPrivate::createEventDispatcher()
+{
+ QGuiApplicationPrivate::createEventDispatcher();
+}
+
+bool qt_try_modal(QWidget *widget, QEvent::Type type)
+{
+ QWidget * top = 0;
+
+ if (QApplicationPrivate::tryModalHelper(widget, &top))
+ return true;
+
+ bool block_event = false;
+ bool paint_event = false;
+
+ switch (type) {
+#if 0
+ case QEvent::Focus:
+ if (!static_cast<QWSFocusEvent*>(event)->simpleData.get_focus)
+ break;
+ // drop through
+#endif
+ case QEvent::MouseButtonPress: // disallow mouse/key events
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseMove:
+ case QEvent::KeyPress:
+ case QEvent::KeyRelease:
+ block_event = true;
+ break;
+ default:
+ break;
+ }
+
+ if ((block_event || paint_event) && top->parentWidget() == 0)
+ top->raise();
+
+ return !block_event;
+}
+
+void QApplicationPrivate::enterModal_sys(QWidget *widget)
+{
+ if (!qt_modal_stack)
+ qt_modal_stack = new QWidgetList;
+ qt_modal_stack->insert(0, widget);
+ app_do_modal = true;
+}
+
+void QApplicationPrivate::leaveModal_sys(QWidget *widget)
+{
+ if (qt_modal_stack && qt_modal_stack->removeAll(widget)) {
+ if (qt_modal_stack->isEmpty()) {
+ delete qt_modal_stack;
+ qt_modal_stack = 0;
+ }
+ }
+ app_do_modal = qt_modal_stack != 0;
+}
+
+bool QApplicationPrivate::modalState()
+{
+ return app_do_modal;
+}
+
+QWidget *qt_tlw_for_window(QWindow *wnd)
+{
+ if (wnd)
+ foreach (QWidget *tlw, qApp->topLevelWidgets())
+ if (tlw->windowHandle() == wnd)
+ return tlw;
+ return 0;
+}
+
+void QApplicationPrivate::notifyActiveWindowChange(QWindow *previous)
+{
+ Q_UNUSED(previous);
+ Q_Q(QApplication);
+ QWindow *wnd = QGuiApplicationPrivate::active_window;
+ if (inPopupMode()) // some delayed focus event to ignore
+ return;
+ QWidget *tlw = qt_tlw_for_window(wnd);
+ q->setActiveWindow(tlw);
+}
+
+static void ungrabKeyboardForPopup(QWidget *popup)
+{
+ if (QWidget::keyboardGrabber())
+ qt_widget_private(QWidget::keyboardGrabber())->stealKeyboardGrab(true);
+ else
+ qt_widget_private(popup)->stealKeyboardGrab(false);
+}
+
+static void ungrabMouseForPopup(QWidget *popup)
+{
+ if (QWidget::mouseGrabber())
+ qt_widget_private(QWidget::mouseGrabber())->stealMouseGrab(true);
+ else
+ qt_widget_private(popup)->stealMouseGrab(false);
+}
+
+static void grabForPopup(QWidget *popup)
+{
+ Q_ASSERT(popup->testAttribute(Qt::WA_WState_Created));
+ popupGrabOk = qt_widget_private(popup)->stealKeyboardGrab(true);
+ if (popupGrabOk) {
+ popupGrabOk = qt_widget_private(popup)->stealMouseGrab(true);
+ if (!popupGrabOk) {
+ // transfer grab back to the keyboard grabber if any
+ ungrabKeyboardForPopup(popup);
+ }
+ }
+}
+
+void QApplicationPrivate::closePopup(QWidget *popup)
+{
+ Q_Q(QApplication);
+ if (!popupWidgets)
+ return;
+ popupWidgets->removeAll(popup);
+
+ if (popup == qt_popup_down) {
+ qt_button_down = 0;
+ qt_popup_down = 0;
+ }
+
+ if (QApplicationPrivate::popupWidgets->count() == 0) { // this was the last popup
+ delete QApplicationPrivate::popupWidgets;
+ QApplicationPrivate::popupWidgets = 0;
+
+ if (popupGrabOk) {
+ popupGrabOk = false;
+
+ if (popup->geometry().contains(QPoint(QGuiApplicationPrivate::mousePressX,
+ QGuiApplicationPrivate::mousePressY))
+ || popup->testAttribute(Qt::WA_NoMouseReplay)) {
+ // mouse release event or inside
+ qt_replay_popup_mouse_event = false;
+ } else { // mouse press event
+ QGuiApplicationPrivate::mousePressTime -= 10000; // avoid double click
+ qt_replay_popup_mouse_event = true;
+ }
+
+ // transfer grab back to mouse grabber if any, otherwise release the grab
+ ungrabMouseForPopup(popup);
+
+ // transfer grab back to keyboard grabber if any, otherwise release the grab
+ ungrabKeyboardForPopup(popup);
+ }
+
+ if (active_window) {
+ if (QWidget *fw = active_window->focusWidget()) {
+ if (fw != QApplication::focusWidget()) {
+ fw->setFocus(Qt::PopupFocusReason);
+ } else {
+ QFocusEvent e(QEvent::FocusIn, Qt::PopupFocusReason);
+ q->sendEvent(fw, &e);
+ }
+ }
+ }
+
+ } else {
+ // A popup was closed, so the previous popup gets the focus.
+ QWidget* aw = QApplicationPrivate::popupWidgets->last();
+ if (QWidget *fw = aw->focusWidget())
+ fw->setFocus(Qt::PopupFocusReason);
+
+ if (QApplicationPrivate::popupWidgets->count() == 1) // grab mouse/keyboard
+ grabForPopup(aw);
+ }
+
+}
+
+void QApplicationPrivate::openPopup(QWidget *popup)
+{
+ openPopupCount++;
+ if (!popupWidgets) // create list
+ popupWidgets = new QWidgetList;
+ popupWidgets->append(popup); // add to end of list
+
+ if (QApplicationPrivate::popupWidgets->count() == 1) // grab mouse/keyboard
+ grabForPopup(popup);
+
+ // popups are not focus-handled by the window system (the first
+ // popup grabbed the keyboard), so we have to do that manually: A
+ // new popup gets the focus
+ if (popup->focusWidget()) {
+ popup->focusWidget()->setFocus(Qt::PopupFocusReason);
+ } else if (popupWidgets->count() == 1) { // this was the first popup
+ if (QWidget *fw = QApplication::focusWidget()) {
+ QFocusEvent e(QEvent::FocusOut, Qt::PopupFocusReason);
+ QApplication::sendEvent(fw, &e);
+ }
+ }
+}
+
+void QApplicationPrivate::initializeMultitouch_sys()
+{
+}
+
+void QApplicationPrivate::cleanupMultitouch_sys()
+{
+}
+
+void QApplicationPrivate::initializeWidgetPaletteHash()
+{
+}
+
+#ifndef QT_NO_WHEELEVENT
+void QApplication::setWheelScrollLines(int lines)
+{
+ QApplicationPrivate::wheel_scroll_lines = lines;
+}
+
+int QApplication::wheelScrollLines()
+{
+ return QApplicationPrivate::wheel_scroll_lines;
+}
+#endif
+
+void QApplication::setEffectEnabled(Qt::UIEffect effect, bool enable)
+{
+ switch (effect) {
+ case Qt::UI_AnimateMenu:
+ QApplicationPrivate::animate_menu = enable;
+ break;
+ case Qt::UI_FadeMenu:
+ if (enable)
+ QApplicationPrivate::animate_menu = true;
+ QApplicationPrivate::fade_menu = enable;
+ break;
+ case Qt::UI_AnimateCombo:
+ QApplicationPrivate::animate_combo = enable;
+ break;
+ case Qt::UI_AnimateTooltip:
+ QApplicationPrivate::animate_tooltip = enable;
+ break;
+ case Qt::UI_FadeTooltip:
+ if (enable)
+ QApplicationPrivate::animate_tooltip = true;
+ QApplicationPrivate::fade_tooltip = enable;
+ break;
+ case Qt::UI_AnimateToolBox:
+ QApplicationPrivate::animate_toolbox = enable;
+ break;
+ default:
+ QApplicationPrivate::animate_ui = enable;
+ break;
+ }
+}
+
+bool QApplication::isEffectEnabled(Qt::UIEffect effect)
+{
+ if (QColormap::instance().depth() < 16 || !QApplicationPrivate::animate_ui)
+ return false;
+
+ switch(effect) {
+ case Qt::UI_AnimateMenu:
+ return QApplicationPrivate::animate_menu;
+ case Qt::UI_FadeMenu:
+ return QApplicationPrivate::fade_menu;
+ case Qt::UI_AnimateCombo:
+ return QApplicationPrivate::animate_combo;
+ case Qt::UI_AnimateTooltip:
+ return QApplicationPrivate::animate_tooltip;
+ case Qt::UI_FadeTooltip:
+ return QApplicationPrivate::fade_tooltip;
+ case Qt::UI_AnimateToolBox:
+ return QApplicationPrivate::animate_toolbox;
+ default:
+ return QApplicationPrivate::animate_ui;
+ }
+}
+
+QWidget *QApplication::topLevelAt(const QPoint &pos)
+{
+ QList<QScreen *> screens = QGuiApplication::screens();
+ QList<QScreen *>::const_iterator screen = screens.constBegin();
+ QList<QScreen *>::const_iterator end = screens.constEnd();
+
+ while (screen != end) {
+ if ((*screen)->geometry().contains(pos)) {
+ QWidgetWindow *w = qobject_cast<QWidgetWindow *>((*screen)->handle()->topLevelAt(pos));
+ return w ? w->widget() : 0;
+ }
+ ++screen;
+ }
+ return 0;
+}
+
+void QApplication::beep()
+{
+}
+
+void QApplication::alert(QWidget *, int)
+{
+}
+
+QPlatformNativeInterface *QApplication::platformNativeInterface()
+{
+ QPlatformIntegration *pi = QGuiApplicationPrivate::platformIntegration();
+ return pi->nativeInterface();
+}
+
+void qt_init(QApplicationPrivate *, int type)
+{
+ Q_UNUSED(type);
+
+ qApp->setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);
+ QColormap::initialize();
+
+ qApp->setObjectName(appName);
+
+#ifndef QT_NO_QWS_INPUTMETHODS
+ qApp->setInputContext(new QInputContext(qApp));
+#endif
+}
+
+#ifdef Q_OS_WIN
+static HDC displayDC = 0; // display device context
+
+Q_WIDGETS_EXPORT HDC qt_win_display_dc() // get display DC
+{
+ Q_ASSERT(qApp && qApp->thread() == QThread::currentThread());
+ if (!displayDC)
+ displayDC = GetDC(0);
+ return displayDC;
+}
+#endif
+
+void qt_cleanup()
+{
+ QPixmapCache::clear();
+ QColormap::cleanup();
+ delete QApplicationPrivate::inputContext;
+ QApplicationPrivate::inputContext = 0;
+
+ QApplicationPrivate::active_window = 0; //### this should not be necessary
+#ifdef Q_OS_WIN
+ if (displayDC) {
+ ReleaseDC(0, displayDC);
+ displayDC = 0;
+ }
+#endif
+}
+
+#ifdef QT3_SUPPORT
+void QApplication::setMainWidget(QWidget *mainWidget)
+{
+ QApplicationPrivate::main_widget = mainWidget;
+ if (QApplicationPrivate::main_widget && windowIcon().isNull()
+ && QApplicationPrivate::main_widget->testAttribute(Qt::WA_SetWindowIcon))
+ setWindowIcon(QApplicationPrivate::main_widget->windowIcon());
+}
+#endif
+
+QT_END_NAMESPACE
diff --git a/src/gui/kernel/qboxlayout.cpp b/src/widgets/kernel/qboxlayout.cpp
index da353dcc01..da353dcc01 100644
--- a/src/gui/kernel/qboxlayout.cpp
+++ b/src/widgets/kernel/qboxlayout.cpp
diff --git a/src/widgets/kernel/qboxlayout.h b/src/widgets/kernel/qboxlayout.h
new file mode 100644
index 0000000000..7c56a32979
--- /dev/null
+++ b/src/widgets/kernel/qboxlayout.h
@@ -0,0 +1,173 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QBOXLAYOUT_H
+#define QBOXLAYOUT_H
+
+#include <QtWidgets/qlayout.h>
+#ifdef QT_INCLUDE_COMPAT
+#include <QtWidgets/qwidget.h>
+#endif
+
+#include <limits.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QBoxLayoutPrivate;
+
+class Q_WIDGETS_EXPORT QBoxLayout : public QLayout
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QBoxLayout)
+public:
+ enum Direction { LeftToRight, RightToLeft, TopToBottom, BottomToTop,
+ Down = TopToBottom, Up = BottomToTop };
+
+ explicit QBoxLayout(Direction, QWidget *parent = 0);
+
+#ifdef QT3_SUPPORT
+ QT3_SUPPORT_CONSTRUCTOR QBoxLayout(QWidget *parent, Direction, int border = 0, int spacing = -1,
+ const char *name = 0);
+ QT3_SUPPORT_CONSTRUCTOR QBoxLayout(QLayout *parentLayout, Direction, int spacing = -1,
+ const char *name = 0);
+ QT3_SUPPORT_CONSTRUCTOR QBoxLayout(Direction, int spacing, const char *name = 0);
+#endif
+ ~QBoxLayout();
+
+ Direction direction() const;
+ void setDirection(Direction);
+
+ void addSpacing(int size);
+ void addStretch(int stretch = 0);
+ void addSpacerItem(QSpacerItem *spacerItem);
+ void addWidget(QWidget *, int stretch = 0, Qt::Alignment alignment = 0);
+ void addLayout(QLayout *layout, int stretch = 0);
+ void addStrut(int);
+ void addItem(QLayoutItem *);
+
+ void insertSpacing(int index, int size);
+ void insertStretch(int index, int stretch = 0);
+ void insertSpacerItem(int index, QSpacerItem *spacerItem);
+ void insertWidget(int index, QWidget *widget, int stretch = 0, Qt::Alignment alignment = 0);
+ void insertLayout(int index, QLayout *layout, int stretch = 0);
+
+ int spacing() const;
+ void setSpacing(int spacing);
+
+ bool setStretchFactor(QWidget *w, int stretch);
+ bool setStretchFactor(QLayout *l, int stretch);
+ void setStretch(int index, int stretch);
+ int stretch(int index) const;
+
+ QSize sizeHint() const;
+ QSize minimumSize() const;
+ QSize maximumSize() const;
+
+ bool hasHeightForWidth() const;
+ int heightForWidth(int) const;
+ int minimumHeightForWidth(int) const;
+
+ Qt::Orientations expandingDirections() const;
+ void invalidate();
+ QLayoutItem *itemAt(int) const;
+ QLayoutItem *takeAt(int);
+ int count() const;
+ void setGeometry(const QRect&);
+#ifdef QT3_SUPPORT
+ inline QT3_SUPPORT int findWidget(QWidget* w) {return indexOf(w);}
+#endif
+protected:
+ // ### Qt 5: make public
+ void insertItem(int index, QLayoutItem *);
+
+private:
+ Q_DISABLE_COPY(QBoxLayout)
+};
+
+class Q_WIDGETS_EXPORT QHBoxLayout : public QBoxLayout
+{
+ Q_OBJECT
+public:
+ QHBoxLayout();
+ explicit QHBoxLayout(QWidget *parent);
+ ~QHBoxLayout();
+
+#ifdef QT3_SUPPORT
+ QT3_SUPPORT_CONSTRUCTOR QHBoxLayout(QWidget *parent, int border,
+ int spacing = -1, const char *name = 0);
+ QT3_SUPPORT_CONSTRUCTOR QHBoxLayout(QLayout *parentLayout,
+ int spacing = -1, const char *name = 0);
+ QT3_SUPPORT_CONSTRUCTOR QHBoxLayout(int spacing, const char *name = 0);
+#endif
+
+private:
+ Q_DISABLE_COPY(QHBoxLayout)
+};
+
+class Q_WIDGETS_EXPORT QVBoxLayout : public QBoxLayout
+{
+ Q_OBJECT
+public:
+ QVBoxLayout();
+ explicit QVBoxLayout(QWidget *parent);
+ ~QVBoxLayout();
+
+#ifdef QT3_SUPPORT
+ QT3_SUPPORT_CONSTRUCTOR QVBoxLayout(QWidget *parent, int border,
+ int spacing = -1, const char *name = 0);
+ QT3_SUPPORT_CONSTRUCTOR QVBoxLayout(QLayout *parentLayout,
+ int spacing = -1, const char *name = 0);
+ QT3_SUPPORT_CONSTRUCTOR QVBoxLayout(int spacing, const char *name = 0);
+#endif
+
+private:
+ Q_DISABLE_COPY(QVBoxLayout)
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QBOXLAYOUT_H
diff --git a/src/gui/kernel/qdesktopwidget.cpp b/src/widgets/kernel/qdesktopwidget.cpp
index 8c25d72f84..8c25d72f84 100644
--- a/src/gui/kernel/qdesktopwidget.cpp
+++ b/src/widgets/kernel/qdesktopwidget.cpp
diff --git a/src/widgets/kernel/qdesktopwidget.h b/src/widgets/kernel/qdesktopwidget.h
new file mode 100644
index 0000000000..e1ed8cfa07
--- /dev/null
+++ b/src/widgets/kernel/qdesktopwidget.h
@@ -0,0 +1,110 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDESKTOPWIDGET_H
+#define QDESKTOPWIDGET_H
+
+#include <QtWidgets/qwidget.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QApplication;
+class QDesktopWidgetPrivate;
+
+class Q_WIDGETS_EXPORT QDesktopWidget : public QWidget
+{
+ Q_OBJECT
+ Q_PROPERTY(bool virtualDesktop READ isVirtualDesktop)
+ Q_PROPERTY(int screenCount READ screenCount NOTIFY screenCountChanged)
+ Q_PROPERTY(int primaryScreen READ primaryScreen)
+public:
+ QDesktopWidget();
+ ~QDesktopWidget();
+
+ bool isVirtualDesktop() const;
+
+ int numScreens() const;
+ int screenCount() const;
+ int primaryScreen() const;
+
+ int screenNumber(const QWidget *widget = 0) const;
+ int screenNumber(const QPoint &) const;
+
+ QWidget *screen(int screen = -1);
+
+ const QRect screenGeometry(int screen = -1) const;
+ const QRect screenGeometry(const QWidget *widget) const;
+ const QRect screenGeometry(const QPoint &point) const
+ { return screenGeometry(screenNumber(point)); }
+
+ const QRect availableGeometry(int screen = -1) const;
+ const QRect availableGeometry(const QWidget *widget) const;
+ const QRect availableGeometry(const QPoint &point) const
+ { return availableGeometry(screenNumber(point)); }
+
+Q_SIGNALS:
+ void resized(int);
+ void workAreaResized(int);
+ void screenCountChanged(int);
+
+protected:
+ void resizeEvent(QResizeEvent *e);
+
+private:
+ Q_DISABLE_COPY(QDesktopWidget)
+ Q_DECLARE_PRIVATE(QDesktopWidget)
+
+ friend class QApplication;
+ friend class QApplicationPrivate;
+};
+
+inline int QDesktopWidget::screenCount() const
+{ return numScreens(); }
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QDESKTOPWIDGET_H
diff --git a/src/gui/kernel/qdesktopwidget.qdoc b/src/widgets/kernel/qdesktopwidget.qdoc
index f71155e117..f71155e117 100644
--- a/src/gui/kernel/qdesktopwidget.qdoc
+++ b/src/widgets/kernel/qdesktopwidget.qdoc
diff --git a/src/widgets/kernel/qdesktopwidget_qpa.cpp b/src/widgets/kernel/qdesktopwidget_qpa.cpp
new file mode 100644
index 0000000000..380daee8c0
--- /dev/null
+++ b/src/widgets/kernel/qdesktopwidget_qpa.cpp
@@ -0,0 +1,171 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdesktopwidget.h"
+#include "qscreen.h"
+#include "private/qapplication_p.h"
+#include <QWidget>
+#include "private/qwidget_p.h"
+#include "private/qdesktopwidget_qpa_p.h"
+QT_BEGIN_NAMESPACE
+
+QT_USE_NAMESPACE
+
+void QDesktopWidgetPrivate::updateScreenList()
+{
+ Q_Q(QDesktopWidget);
+ QList<QScreen *> screenList = QGuiApplication::screens();
+ int targetLength = screenList.length();
+ int currentLength = screens.length();
+
+ // Add or remove screen widgets as necessary
+ if(currentLength > targetLength) {
+ QDesktopScreenWidget *screen;
+ while (currentLength-- > targetLength) {
+ screen = screens.takeLast();
+ delete screen;
+ }
+ }
+ else if (currentLength < targetLength) {
+ QDesktopScreenWidget *screen;
+ while (currentLength < targetLength) {
+ screen = new QDesktopScreenWidget(currentLength++);
+ screens.append(screen);
+ }
+ }
+
+ QRegion virtualGeometry;
+
+ // update the geometry of each screen widget
+ for (int i = 0; i < screens.length(); i++) {
+ QRect screenGeometry = screenList.at(i)->geometry();
+ screens.at(i)->setGeometry(screenGeometry);
+ virtualGeometry += screenGeometry;
+ }
+
+ q->setGeometry(virtualGeometry.boundingRect());
+}
+
+QDesktopWidget::QDesktopWidget()
+ : QWidget(*new QDesktopWidgetPrivate, 0, Qt::Desktop)
+{
+ Q_D(QDesktopWidget);
+ setObjectName(QLatin1String("desktop"));
+ d->updateScreenList();
+}
+
+QDesktopWidget::~QDesktopWidget()
+{
+}
+
+bool QDesktopWidget::isVirtualDesktop() const
+{
+ return QGuiApplication::primaryScreen()->virtualSiblings().size() > 1;
+}
+
+int QDesktopWidget::primaryScreen() const
+{
+ return 0;
+}
+
+int QDesktopWidget::numScreens() const
+{
+ return qMax(QGuiApplication::screens().size(), 1);
+}
+
+QWidget *QDesktopWidget::screen(int screen)
+{
+ Q_D(QDesktopWidget);
+ if (screen < 0 || screen >= d->screens.length())
+ return d->screens.at(0);
+ return d->screens.at(screen);
+}
+
+const QRect QDesktopWidget::availableGeometry(int screenNo) const
+{
+ QList<QScreen *> screens = QGuiApplication::screens();
+ if (screenNo == -1)
+ screenNo = 0;
+ if (screenNo < 0 || screenNo >= screens.size())
+ return QRect();
+ else
+ return screens.at(screenNo)->availableGeometry();
+}
+
+const QRect QDesktopWidget::screenGeometry(int screenNo) const
+{
+ QList<QScreen *> screens = QGuiApplication::screens();
+ if (screenNo == -1)
+ screenNo = 0;
+ if (screenNo < 0 || screenNo >= screens.size())
+ return QRect();
+ else
+ return screens.at(screenNo)->geometry();
+}
+
+int QDesktopWidget::screenNumber(const QWidget *w) const
+{
+ if (!w)
+ return 0;
+
+ QRect frame = w->frameGeometry();
+ if (!w->isWindow())
+ frame.moveTopLeft(w->mapToGlobal(QPoint(0, 0)));
+ const QPoint midpoint = (frame.topLeft() + frame.bottomRight()) / 2;
+ return screenNumber(midpoint);
+}
+
+int QDesktopWidget::screenNumber(const QPoint &p) const
+{
+ QList<QScreen *> screens = QGuiApplication::screens();
+
+ for (int i = 0; i < screens.size(); ++i)
+ if (screens.at(i)->geometry().contains(p))
+ return i;
+
+ return primaryScreen(); //even better would be closest screen
+}
+
+void QDesktopWidget::resizeEvent(QResizeEvent *)
+{
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/kernel/qdesktopwidget_qpa_p.h b/src/widgets/kernel/qdesktopwidget_qpa_p.h
index ddae7f3853..ddae7f3853 100644
--- a/src/gui/kernel/qdesktopwidget_qpa_p.h
+++ b/src/widgets/kernel/qdesktopwidget_qpa_p.h
diff --git a/src/gui/kernel/qformlayout.cpp b/src/widgets/kernel/qformlayout.cpp
index 5c43acfe0a..5c43acfe0a 100644
--- a/src/gui/kernel/qformlayout.cpp
+++ b/src/widgets/kernel/qformlayout.cpp
diff --git a/src/widgets/kernel/qformlayout.h b/src/widgets/kernel/qformlayout.h
new file mode 100644
index 0000000000..05bb57d981
--- /dev/null
+++ b/src/widgets/kernel/qformlayout.h
@@ -0,0 +1,163 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QFORMLAYOUT_H
+#define QFORMLAYOUT_H
+
+#include <QtWidgets/QLayout>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QFormLayoutPrivate;
+
+class Q_WIDGETS_EXPORT QFormLayout : public QLayout
+{
+ Q_OBJECT
+ Q_ENUMS(FormStyle FieldGrowthPolicy RowWrapPolicy ItemRole)
+ Q_DECLARE_PRIVATE(QFormLayout)
+ Q_PROPERTY(FieldGrowthPolicy fieldGrowthPolicy READ fieldGrowthPolicy WRITE setFieldGrowthPolicy RESET resetFieldGrowthPolicy)
+ Q_PROPERTY(RowWrapPolicy rowWrapPolicy READ rowWrapPolicy WRITE setRowWrapPolicy RESET resetRowWrapPolicy)
+ Q_PROPERTY(Qt::Alignment labelAlignment READ labelAlignment WRITE setLabelAlignment RESET resetLabelAlignment)
+ Q_PROPERTY(Qt::Alignment formAlignment READ formAlignment WRITE setFormAlignment RESET resetFormAlignment)
+ Q_PROPERTY(int horizontalSpacing READ horizontalSpacing WRITE setHorizontalSpacing)
+ Q_PROPERTY(int verticalSpacing READ verticalSpacing WRITE setVerticalSpacing)
+
+public:
+ enum FieldGrowthPolicy {
+ FieldsStayAtSizeHint,
+ ExpandingFieldsGrow,
+ AllNonFixedFieldsGrow
+ };
+
+ enum RowWrapPolicy {
+ DontWrapRows,
+ WrapLongRows,
+ WrapAllRows
+ };
+
+ enum ItemRole {
+ LabelRole = 0,
+ FieldRole = 1,
+ SpanningRole = 2
+ };
+
+ explicit QFormLayout(QWidget *parent = 0);
+ ~QFormLayout();
+
+ void setFieldGrowthPolicy(FieldGrowthPolicy policy);
+ FieldGrowthPolicy fieldGrowthPolicy() const;
+ void setRowWrapPolicy(RowWrapPolicy policy);
+ RowWrapPolicy rowWrapPolicy() const;
+ void setLabelAlignment(Qt::Alignment alignment);
+ Qt::Alignment labelAlignment() const;
+ void setFormAlignment(Qt::Alignment alignment);
+ Qt::Alignment formAlignment() const;
+
+ void setHorizontalSpacing(int spacing);
+ int horizontalSpacing() const;
+ void setVerticalSpacing(int spacing);
+ int verticalSpacing() const;
+
+ int spacing() const;
+ void setSpacing(int);
+
+ void addRow(QWidget *label, QWidget *field);
+ void addRow(QWidget *label, QLayout *field);
+ void addRow(const QString &labelText, QWidget *field);
+ void addRow(const QString &labelText, QLayout *field);
+ void addRow(QWidget *widget);
+ void addRow(QLayout *layout);
+
+ void insertRow(int row, QWidget *label, QWidget *field);
+ void insertRow(int row, QWidget *label, QLayout *field);
+ void insertRow(int row, const QString &labelText, QWidget *field);
+ void insertRow(int row, const QString &labelText, QLayout *field);
+ void insertRow(int row, QWidget *widget);
+ void insertRow(int row, QLayout *layout);
+
+ void setItem(int row, ItemRole role, QLayoutItem *item);
+ void setWidget(int row, ItemRole role, QWidget *widget);
+ void setLayout(int row, ItemRole role, QLayout *layout);
+
+ QLayoutItem *itemAt(int row, ItemRole role) const;
+ void getItemPosition(int index, int *rowPtr, ItemRole *rolePtr) const;
+ void getWidgetPosition(QWidget *widget, int *rowPtr, ItemRole *rolePtr) const;
+ void getLayoutPosition(QLayout *layout, int *rowPtr, ItemRole *rolePtr) const;
+ QWidget *labelForField(QWidget *field) const;
+ QWidget *labelForField(QLayout *field) const;
+
+ // reimplemented from QLayout
+ void addItem(QLayoutItem *item);
+ QLayoutItem *itemAt(int index) const;
+ QLayoutItem *takeAt(int index);
+
+ void setGeometry(const QRect &rect);
+ QSize minimumSize() const;
+ QSize sizeHint() const;
+ void invalidate();
+
+ bool hasHeightForWidth() const;
+ int heightForWidth(int width) const;
+ Qt::Orientations expandingDirections() const;
+ int count() const;
+
+ int rowCount() const;
+
+#if 0
+ void dump() const;
+#endif
+
+private:
+ void resetFieldGrowthPolicy();
+ void resetRowWrapPolicy();
+ void resetLabelAlignment();
+ void resetFormAlignment();
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/widgets/kernel/qgesture.cpp b/src/widgets/kernel/qgesture.cpp
new file mode 100644
index 0000000000..92f4c9cfc6
--- /dev/null
+++ b/src/widgets/kernel/qgesture.cpp
@@ -0,0 +1,1118 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qgesture.h"
+#include "private/qgesture_p.h"
+#include "private/qstandardgestures_p.h"
+#include "qgraphicsview.h"
+
+#ifndef QT_NO_GESTURES
+
+QT_BEGIN_NAMESPACE
+
+ /*!
+ \class QGesture
+ \since 4.6
+ \ingroup gestures
+
+ \brief The QGesture class represents a gesture, containing properties that
+ describe the corresponding user input.
+
+ Gesture objects are not constructed directly by developers. They are created by
+ the QGestureRecognizer object that is registered with the application; see
+ QGestureRecognizer::registerRecognizer().
+
+ For an overview of gesture handling in Qt and information on using gestures
+ in your applications, see the \l{Gestures Programming} document.
+
+ \section1 Gesture Properties
+
+ The class has a list of properties that can be queried by the user to get
+ some gesture-specific arguments. For example, the pinch gesture has a scale
+ factor that is exposed as a property.
+
+ Developers of custom gesture recognizers can add additional properties in
+ order to provide additional information about a gesture. This can be done
+ by adding new dynamic properties to a QGesture object, or by subclassing
+ the QGesture class (or one of its subclasses).
+
+ \section1 Lifecycle of a Gesture Object
+
+ A QGesture instance is implicitly created when needed and is owned by Qt.
+ Developers should never destroy them or store them for later use as Qt may
+ destroy particular instances of them and create new ones to replace them.
+
+ The registered gesture recognizer monitors the input events for the target
+ object via its \l{QGestureRecognizer::}{recognize()} function, updating the
+ properties of the gesture object as required.
+
+ The gesture object may be delivered to the target object in a QGestureEvent if
+ the corresponding gesture is active or has just been canceled. Each event that
+ is delivered contains a list of gesture objects, since support for more than
+ one gesture may be enabled for the target object. Due to the way events are
+ handled in Qt, gesture events may be filtered by other objects.
+
+ \sa QGestureEvent, QGestureRecognizer
+*/
+
+/*!
+ Constructs a new gesture object with the given \a parent.
+
+ QGesture objects are created by gesture recognizers in the
+ QGestureRecognizer::create() function.
+*/
+QGesture::QGesture(QObject *parent)
+ : QObject(*new QGesturePrivate, parent)
+{
+ d_func()->gestureType = Qt::CustomGesture;
+}
+
+/*!
+ \internal
+*/
+QGesture::QGesture(QGesturePrivate &dd, QObject *parent)
+ : QObject(dd, parent)
+{
+}
+
+/*!
+ Destroys the gesture object.
+*/
+QGesture::~QGesture()
+{
+}
+
+/*!
+ \property QGesture::state
+ \brief the current state of the gesture
+*/
+
+/*!
+ \property QGesture::gestureType
+ \brief the type of the gesture
+*/
+
+/*!
+ \property QGesture::hotSpot
+
+ \brief The point that is used to find the receiver for the gesture event.
+
+ The hot-spot is a point in the global coordinate system, use
+ QWidget::mapFromGlobal() or QGestureEvent::mapToGraphicsScene() to get a
+ local hot-spot.
+
+ The hot-spot should be set by the gesture recognizer to allow gesture event
+ delivery to a QGraphicsObject.
+*/
+
+/*!
+ \property QGesture::hasHotSpot
+ \brief whether the gesture has a hot-spot
+*/
+
+Qt::GestureType QGesture::gestureType() const
+{
+ return d_func()->gestureType;
+}
+
+Qt::GestureState QGesture::state() const
+{
+ return d_func()->state;
+}
+
+QPointF QGesture::hotSpot() const
+{
+ return d_func()->hotSpot;
+}
+
+void QGesture::setHotSpot(const QPointF &value)
+{
+ Q_D(QGesture);
+ d->hotSpot = value;
+ d->isHotSpotSet = true;
+}
+
+bool QGesture::hasHotSpot() const
+{
+ return d_func()->isHotSpotSet;
+}
+
+void QGesture::unsetHotSpot()
+{
+ d_func()->isHotSpotSet = false;
+}
+
+/*!
+ \property QGesture::gestureCancelPolicy
+ \brief the policy for deciding what happens on accepting a gesture
+
+ On accepting one gesture Qt can automatically cancel other gestures
+ that belong to other targets. The policy is normally set to not cancel
+ any other gestures and can be set to cancel all active gestures in the
+ context. For example for all child widgets.
+*/
+
+/*!
+ \enum QGesture::GestureCancelPolicy
+
+ This enum describes how accepting a gesture can cancel other gestures
+ automatically.
+
+ \value CancelNone On accepting this gesture no other gestures will be affected.
+
+ \value CancelAllInContext On accepting this gesture all gestures that are
+ active in the context (respecting the Qt::GestureFlag that were specified
+ when subscribed to the gesture) will be cancelled.
+*/
+
+void QGesture::setGestureCancelPolicy(GestureCancelPolicy policy)
+{
+ Q_D(QGesture);
+ d->gestureCancelPolicy = static_cast<uint>(policy);
+}
+
+QGesture::GestureCancelPolicy QGesture::gestureCancelPolicy() const
+{
+ Q_D(const QGesture);
+ return static_cast<GestureCancelPolicy>(d->gestureCancelPolicy);
+}
+
+/*!
+ \class QPanGesture
+ \since 4.6
+ \brief The QPanGesture class describes a panning gesture made by the user.
+ \ingroup gestures
+
+ \image pangesture.png
+
+ For an overview of gesture handling in Qt and information on using gestures
+ in your applications, see the \l{Gestures Programming} document.
+
+ \sa QPinchGesture, QSwipeGesture
+*/
+
+/*!
+ \property QPanGesture::lastOffset
+ \brief the last offset recorded for this gesture
+
+ The last offset contains the change in position of the user's input as
+ reported in the \l offset property when a previous gesture event was
+ delivered for this gesture.
+
+ If no previous event was delivered with information about this gesture
+ (i.e., this gesture object contains information about the first movement
+ in the gesture) then this property contains a zero size.
+*/
+
+/*!
+ \property QPanGesture::offset
+ \brief the total offset from the first input position to the current input
+ position
+
+ The offset measures the total change in position of the user's input
+ covered by the gesture on the input device.
+*/
+
+/*!
+ \property QPanGesture::delta
+ \brief the offset from the previous input position to the current input
+
+ This is essentially the same as the difference between offset() and
+ lastOffset().
+*/
+
+/*!
+ \property QPanGesture::acceleration
+ \brief the acceleration in the motion of the touch point for this gesture
+*/
+
+/*!
+ \property QPanGesture::horizontalVelocity
+ \brief the horizontal component of the motion of the touch point for this
+ gesture
+ \since 4.7.1
+ \internal
+
+ \sa verticalVelocity, acceleration
+*/
+
+/*!
+ \property QPanGesture::verticalVelocity
+ \brief the vertical component of the motion of the touch point for this
+ gesture
+ \since 4.7.1
+ \internal
+
+ \sa horizontalVelocity, acceleration
+*/
+
+/*!
+ \internal
+*/
+QPanGesture::QPanGesture(QObject *parent)
+ : QGesture(*new QPanGesturePrivate, parent)
+{
+ d_func()->gestureType = Qt::PanGesture;
+}
+
+
+QPointF QPanGesture::lastOffset() const
+{
+ return d_func()->lastOffset;
+}
+
+QPointF QPanGesture::offset() const
+{
+ return d_func()->offset;
+}
+
+QPointF QPanGesture::delta() const
+{
+ Q_D(const QPanGesture);
+ return d->offset - d->lastOffset;
+}
+
+qreal QPanGesture::acceleration() const
+{
+ return d_func()->acceleration;
+}
+
+void QPanGesture::setLastOffset(const QPointF &value)
+{
+ d_func()->lastOffset = value;
+}
+
+void QPanGesture::setOffset(const QPointF &value)
+{
+ d_func()->offset = value;
+}
+
+void QPanGesture::setAcceleration(qreal value)
+{
+ d_func()->acceleration = value;
+}
+
+/*!
+ \class QPinchGesture
+ \since 4.6
+ \brief The QPinchGesture class describes a pinch gesture made by the user.
+ \ingroup touch
+ \ingroup gestures
+
+ A pinch gesture is a form of touch user input in which the user typically
+ touches two points on the input device with a thumb and finger, before moving
+ them closer together or further apart to change the scale factor, zoom, or level
+ of detail of the user interface.
+
+ For an overview of gesture handling in Qt and information on using gestures
+ in your applications, see the \l{Gestures Programming} document.
+
+ \image pinchgesture.png
+
+ Instead of repeatedly applying the same pinching gesture, the user may
+ continue to touch the input device in one place, and apply a second touch
+ to a new point, continuing the gesture. When this occurs, gesture events
+ will continue to be delivered to the target object, containing an instance
+ of QPinchGesture in the Qt::GestureUpdated state.
+
+ \sa QPanGesture, QSwipeGesture
+*/
+
+/*!
+ \enum QPinchGesture::ChangeFlag
+
+ This enum describes the changes that can occur to the properties of
+ the gesture object.
+
+ \value ScaleFactorChanged The scale factor held by scaleFactor changed.
+ \value RotationAngleChanged The rotation angle held by rotationAngle changed.
+ \value CenterPointChanged The center point held by centerPoint changed.
+
+ \sa changeFlags, totalChangeFlags
+*/
+
+/*!
+ \property QPinchGesture::totalChangeFlags
+ \brief the property of the gesture that has change
+
+ This property indicates which of the other properties has changed since the
+ gesture has started. You can use this information to determine which aspect
+ of your user interface needs to be updated.
+
+ \sa changeFlags, scaleFactor, rotationAngle, centerPoint
+*/
+
+/*!
+ \property QPinchGesture::changeFlags
+ \brief the property of the gesture that has changed in the current step
+
+ This property indicates which of the other properties has changed since
+ the previous gesture event included information about this gesture. You
+ can use this information to determine which aspect of your user interface
+ needs to be updated.
+
+ \sa totalChangeFlags, scaleFactor, rotationAngle, centerPoint
+*/
+
+/*!
+ \property QPinchGesture::totalScaleFactor
+ \brief the total scale factor
+
+ The total scale factor measures the total change in scale factor from the
+ original value to the current scale factor.
+
+ \sa scaleFactor, lastScaleFactor
+*/
+/*!
+ \property QPinchGesture::lastScaleFactor
+ \brief the last scale factor recorded for this gesture
+
+ The last scale factor contains the scale factor reported in the
+ \l scaleFactor property when a previous gesture event included
+ information about this gesture.
+
+ If no previous event was delivered with information about this gesture
+ (i.e., this gesture object contains information about the first movement
+ in the gesture) then this property contains zero.
+
+ \sa scaleFactor, totalScaleFactor
+*/
+/*!
+ \property QPinchGesture::scaleFactor
+ \brief the current scale factor
+
+ The scale factor measures the scale factor associated with the distance
+ between two of the user's inputs on a touch device.
+
+ \sa totalScaleFactor, lastScaleFactor
+*/
+
+/*!
+ \property QPinchGesture::totalRotationAngle
+ \brief the total angle covered by the gesture
+
+ This total angle measures the complete angle covered by the gesture. Usually, this
+ is equal to the value held by the \l rotationAngle property, except in the case where
+ the user performs multiple rotations by removing and repositioning one of the touch
+ points, as described above. In this case, the total angle will be the sum of the
+ rotation angles for the multiple stages of the gesture.
+
+ \sa rotationAngle, lastRotationAngle
+*/
+/*!
+ \property QPinchGesture::lastRotationAngle
+ \brief the last reported angle covered by the gesture motion
+
+ The last rotation angle is the angle as reported in the \l rotationAngle property
+ when a previous gesture event was delivered for this gesture.
+
+ \sa rotationAngle, totalRotationAngle
+*/
+/*!
+ \property QPinchGesture::rotationAngle
+ \brief the angle covered by the gesture motion
+
+ \sa totalRotationAngle, lastRotationAngle
+*/
+
+/*!
+ \property QPinchGesture::startCenterPoint
+ \brief the starting position of the center point
+
+ \sa centerPoint, lastCenterPoint
+*/
+/*!
+ \property QPinchGesture::lastCenterPoint
+ \brief the last position of the center point recorded for this gesture
+
+ \sa centerPoint, startCenterPoint
+*/
+/*!
+ \property QPinchGesture::centerPoint
+ \brief the current center point
+
+ The center point is the midpoint between the two input points in the gesture.
+
+ \sa startCenterPoint, lastCenterPoint
+*/
+
+/*!
+ \internal
+*/
+QPinchGesture::QPinchGesture(QObject *parent)
+ : QGesture(*new QPinchGesturePrivate, parent)
+{
+ d_func()->gestureType = Qt::PinchGesture;
+}
+
+QPinchGesture::ChangeFlags QPinchGesture::totalChangeFlags() const
+{
+ return d_func()->totalChangeFlags;
+}
+
+void QPinchGesture::setTotalChangeFlags(QPinchGesture::ChangeFlags value)
+{
+ d_func()->totalChangeFlags = value;
+}
+
+QPinchGesture::ChangeFlags QPinchGesture::changeFlags() const
+{
+ return d_func()->changeFlags;
+}
+
+void QPinchGesture::setChangeFlags(QPinchGesture::ChangeFlags value)
+{
+ d_func()->changeFlags = value;
+}
+
+QPointF QPinchGesture::startCenterPoint() const
+{
+ return d_func()->startCenterPoint;
+}
+
+QPointF QPinchGesture::lastCenterPoint() const
+{
+ return d_func()->lastCenterPoint;
+}
+
+QPointF QPinchGesture::centerPoint() const
+{
+ return d_func()->centerPoint;
+}
+
+void QPinchGesture::setStartCenterPoint(const QPointF &value)
+{
+ d_func()->startCenterPoint = value;
+}
+
+void QPinchGesture::setLastCenterPoint(const QPointF &value)
+{
+ d_func()->lastCenterPoint = value;
+}
+
+void QPinchGesture::setCenterPoint(const QPointF &value)
+{
+ d_func()->centerPoint = value;
+}
+
+
+qreal QPinchGesture::totalScaleFactor() const
+{
+ return d_func()->totalScaleFactor;
+}
+
+qreal QPinchGesture::lastScaleFactor() const
+{
+ return d_func()->lastScaleFactor;
+}
+
+qreal QPinchGesture::scaleFactor() const
+{
+ return d_func()->scaleFactor;
+}
+
+void QPinchGesture::setTotalScaleFactor(qreal value)
+{
+ d_func()->totalScaleFactor = value;
+}
+
+void QPinchGesture::setLastScaleFactor(qreal value)
+{
+ d_func()->lastScaleFactor = value;
+}
+
+void QPinchGesture::setScaleFactor(qreal value)
+{
+ d_func()->scaleFactor = value;
+}
+
+
+qreal QPinchGesture::totalRotationAngle() const
+{
+ return d_func()->totalRotationAngle;
+}
+
+qreal QPinchGesture::lastRotationAngle() const
+{
+ return d_func()->lastRotationAngle;
+}
+
+qreal QPinchGesture::rotationAngle() const
+{
+ return d_func()->rotationAngle;
+}
+
+void QPinchGesture::setTotalRotationAngle(qreal value)
+{
+ d_func()->totalRotationAngle = value;
+}
+
+void QPinchGesture::setLastRotationAngle(qreal value)
+{
+ d_func()->lastRotationAngle = value;
+}
+
+void QPinchGesture::setRotationAngle(qreal value)
+{
+ d_func()->rotationAngle = value;
+}
+
+/*!
+ \class QSwipeGesture
+ \since 4.6
+ \brief The QSwipeGesture class describes a swipe gesture made by the user.
+ \ingroup gestures
+
+ \image swipegesture.png
+
+ For an overview of gesture handling in Qt and information on using gestures
+ in your applications, see the \l{Gestures Programming} document.
+
+ \sa QPanGesture, QPinchGesture
+*/
+
+/*!
+ \enum QSwipeGesture::SwipeDirection
+
+ This enum describes the possible directions for the gesture's motion
+ along the horizontal and vertical axes.
+
+ \value NoDirection The gesture had no motion associated with it on a particular axis.
+ \value Left The gesture involved a horizontal motion to the left.
+ \value Right The gesture involved a horizontal motion to the right.
+ \value Up The gesture involved an upward vertical motion.
+ \value Down The gesture involved a downward vertical motion.
+*/
+
+/*!
+ \property QSwipeGesture::horizontalDirection
+ \brief the horizontal direction of the gesture
+
+ If the gesture has a horizontal component, the horizontal direction
+ is either Left or Right; otherwise, it is NoDirection.
+
+ \sa verticalDirection, swipeAngle
+*/
+
+/*!
+ \property QSwipeGesture::verticalDirection
+ \brief the vertical direction of the gesture
+
+ If the gesture has a vertical component, the vertical direction
+ is either Up or Down; otherwise, it is NoDirection.
+
+ \sa horizontalDirection, swipeAngle
+*/
+
+/*!
+ \property QSwipeGesture::swipeAngle
+ \brief the angle of the motion associated with the gesture
+
+ If the gesture has either a horizontal or vertical component, the
+ swipe angle describes the angle between the direction of motion and the
+ x-axis as defined using the standard widget
+ \l{Coordinate System}{coordinate system}.
+
+ \sa horizontalDirection, verticalDirection
+*/
+
+/*!
+ \property QSwipeGesture::velocity
+ \since 4.7.1
+ \internal
+*/
+
+/*!
+ \internal
+*/
+QSwipeGesture::QSwipeGesture(QObject *parent)
+ : QGesture(*new QSwipeGesturePrivate, parent)
+{
+ d_func()->gestureType = Qt::SwipeGesture;
+}
+
+QSwipeGesture::SwipeDirection QSwipeGesture::horizontalDirection() const
+{
+ Q_D(const QSwipeGesture);
+ if (d->swipeAngle < 0 || d->swipeAngle == 90 || d->swipeAngle == 270)
+ return QSwipeGesture::NoDirection;
+ else if (d->swipeAngle < 90 || d->swipeAngle > 270)
+ return QSwipeGesture::Right;
+ else
+ return QSwipeGesture::Left;
+}
+
+QSwipeGesture::SwipeDirection QSwipeGesture::verticalDirection() const
+{
+ Q_D(const QSwipeGesture);
+ if (d->swipeAngle <= 0 || d->swipeAngle == 180)
+ return QSwipeGesture::NoDirection;
+ else if (d->swipeAngle < 180)
+ return QSwipeGesture::Up;
+ else
+ return QSwipeGesture::Down;
+}
+
+qreal QSwipeGesture::swipeAngle() const
+{
+ return d_func()->swipeAngle;
+}
+
+void QSwipeGesture::setSwipeAngle(qreal value)
+{
+ d_func()->swipeAngle = value;
+}
+
+/*!
+ \class QTapGesture
+ \since 4.6
+ \brief The QTapGesture class describes a tap gesture made by the user.
+ \ingroup gestures
+
+ For an overview of gesture handling in Qt and information on using gestures
+ in your applications, see the \l{Gestures Programming} document.
+
+ \sa QPanGesture, QPinchGesture
+*/
+
+/*!
+ \property QTapGesture::position
+ \brief the position of the tap
+*/
+
+/*!
+ \internal
+*/
+QTapGesture::QTapGesture(QObject *parent)
+ : QGesture(*new QTapGesturePrivate, parent)
+{
+ d_func()->gestureType = Qt::TapGesture;
+}
+
+QPointF QTapGesture::position() const
+{
+ return d_func()->position;
+}
+
+void QTapGesture::setPosition(const QPointF &value)
+{
+ d_func()->position = value;
+}
+/*!
+ \class QTapAndHoldGesture
+ \since 4.6
+ \brief The QTapAndHoldGesture class describes a tap-and-hold (aka LongTap)
+ gesture made by the user.
+ \ingroup gestures
+
+ For an overview of gesture handling in Qt and information on using gestures
+ in your applications, see the \l{Gestures Programming} document.
+
+ \sa QPanGesture, QPinchGesture
+*/
+
+/*!
+ \property QTapAndHoldGesture::position
+ \brief the position of the tap
+*/
+
+/*!
+ \internal
+*/
+QTapAndHoldGesture::QTapAndHoldGesture(QObject *parent)
+ : QGesture(*new QTapAndHoldGesturePrivate, parent)
+{
+ d_func()->gestureType = Qt::TapAndHoldGesture;
+}
+
+QPointF QTapAndHoldGesture::position() const
+{
+ return d_func()->position;
+}
+
+void QTapAndHoldGesture::setPosition(const QPointF &value)
+{
+ d_func()->position = value;
+}
+
+/*!
+ Set the timeout, in milliseconds, before the gesture triggers.
+
+ The recognizer will detect a touch down and and if \a msecs
+ later the touch is still down, it will trigger the QTapAndHoldGesture.
+ The default value is 700 milliseconds.
+*/
+// static
+void QTapAndHoldGesture::setTimeout(int msecs)
+{
+ QTapAndHoldGesturePrivate::Timeout = msecs;
+}
+
+/*!
+ Gets the timeout, in milliseconds, before the gesture triggers.
+
+ The recognizer will detect a touch down and and if timeout()
+ later the touch is still down, it will trigger the QTapAndHoldGesture.
+ The default value is 700 milliseconds.
+*/
+// static
+int QTapAndHoldGesture::timeout()
+{
+ return QTapAndHoldGesturePrivate::Timeout;
+}
+
+int QTapAndHoldGesturePrivate::Timeout = 700; // in ms
+
+
+/*!
+ \class QGestureEvent
+ \since 4.6
+ \ingroup events
+ \ingroup gestures
+
+ \brief The QGestureEvent class provides the description of triggered gestures.
+
+ The QGestureEvent class contains a list of gestures, which can be obtained using the
+ gestures() function.
+
+ The gestures are either active or canceled. A list of those that are currently being
+ executed can be obtained using the activeGestures() function. A list of those which
+ were previously active and have been canceled can be accessed using the
+ canceledGestures() function. A gesture might be canceled if the current window loses
+ focus, for example, or because of a timeout, or for other reasons.
+
+ If the event handler does not accept the event by calling the generic
+ QEvent::accept() function, all individual QGesture object that were not
+ accepted and in the Qt::GestureStarted state will be propagated up the
+ parent widget chain until a widget accepts them individually, by calling
+ QGestureEvent::accept() for each of them, or an event filter consumes the
+ event.
+
+ \section1 Further Reading
+
+ For an overview of gesture handling in Qt and information on using gestures
+ in your applications, see the \l{Gestures Programming} document.
+
+ \sa QGesture, QGestureRecognizer,
+ QWidget::grabGesture(), QGraphicsObject::grabGesture()
+*/
+
+/*!
+ Creates new QGestureEvent containing a list of \a gestures.
+*/
+QGestureEvent::QGestureEvent(const QList<QGesture *> &gestures)
+ : QEvent(QEvent::Gesture)
+{
+ d = reinterpret_cast<QEventPrivate *>(new QGestureEventPrivate(gestures));
+}
+
+/*!
+ Destroys QGestureEvent.
+*/
+QGestureEvent::~QGestureEvent()
+{
+ delete reinterpret_cast<QGestureEventPrivate *>(d);
+}
+
+/*!
+ Returns all gestures that are delivered in the event.
+*/
+QList<QGesture *> QGestureEvent::gestures() const
+{
+ return d_func()->gestures;
+}
+
+/*!
+ Returns a gesture object by \a type.
+*/
+QGesture *QGestureEvent::gesture(Qt::GestureType type) const
+{
+ const QGestureEventPrivate *d = d_func();
+ for(int i = 0; i < d->gestures.size(); ++i)
+ if (d->gestures.at(i)->gestureType() == type)
+ return d->gestures.at(i);
+ return 0;
+}
+
+/*!
+ Returns a list of active (not canceled) gestures.
+*/
+QList<QGesture *> QGestureEvent::activeGestures() const
+{
+ QList<QGesture *> gestures;
+ foreach (QGesture *gesture, d_func()->gestures) {
+ if (gesture->state() != Qt::GestureCanceled)
+ gestures.append(gesture);
+ }
+ return gestures;
+}
+
+/*!
+ Returns a list of canceled gestures.
+*/
+QList<QGesture *> QGestureEvent::canceledGestures() const
+{
+ QList<QGesture *> gestures;
+ foreach (QGesture *gesture, d_func()->gestures) {
+ if (gesture->state() == Qt::GestureCanceled)
+ gestures.append(gesture);
+ }
+ return gestures;
+}
+
+/*!
+ Sets the accept flag of the given \a gesture object to the specified \a value.
+
+ Setting the accept flag indicates that the event receiver wants the \a gesture.
+ Unwanted gestures may be propagated to the parent widget.
+
+ By default, gestures in events of type QEvent::Gesture are accepted, and
+ gestures in QEvent::GestureOverride events are ignored.
+
+ For convenience, the accept flag can also be set with
+ \l{QGestureEvent::accept()}{accept(gesture)}, and cleared with
+ \l{QGestureEvent::ignore()}{ignore(gesture)}.
+*/
+void QGestureEvent::setAccepted(QGesture *gesture, bool value)
+{
+ if (gesture)
+ setAccepted(gesture->gestureType(), value);
+}
+
+/*!
+ Sets the accept flag of the given \a gesture object, the equivalent of calling
+ \l{QGestureEvent::setAccepted()}{setAccepted(gesture, true)}.
+
+ Setting the accept flag indicates that the event receiver wants the
+ gesture. Unwanted gestures may be propagated to the parent widget.
+
+ \sa QGestureEvent::ignore()
+*/
+void QGestureEvent::accept(QGesture *gesture)
+{
+ if (gesture)
+ setAccepted(gesture->gestureType(), true);
+}
+
+/*!
+ Clears the accept flag parameter of the given \a gesture object, the equivalent
+ of calling \l{QGestureEvent::setAccepted()}{setAccepted(gesture, false)}.
+
+ Clearing the accept flag indicates that the event receiver does not
+ want the gesture. Unwanted gestures may be propagated to the parent widget.
+
+ \sa QGestureEvent::accept()
+*/
+void QGestureEvent::ignore(QGesture *gesture)
+{
+ if (gesture)
+ setAccepted(gesture->gestureType(), false);
+}
+
+/*!
+ Returns true if the \a gesture is accepted; otherwise returns false.
+*/
+bool QGestureEvent::isAccepted(QGesture *gesture) const
+{
+ return gesture ? isAccepted(gesture->gestureType()) : false;
+}
+
+/*!
+ Sets the accept flag of the given \a gestureType object to the specified
+ \a value.
+
+ Setting the accept flag indicates that the event receiver wants to receive
+ gestures of the specified type, \a gestureType. Unwanted gestures may be
+ propagated to the parent widget.
+
+ By default, gestures in events of type QEvent::Gesture are accepted, and
+ gestures in QEvent::GestureOverride events are ignored.
+
+ For convenience, the accept flag can also be set with
+ \l{QGestureEvent::accept()}{accept(gestureType)}, and cleared with
+ \l{QGestureEvent::ignore()}{ignore(gestureType)}.
+*/
+void QGestureEvent::setAccepted(Qt::GestureType gestureType, bool value)
+{
+ setAccepted(false);
+ d_func()->accepted[gestureType] = value;
+}
+
+/*!
+ Sets the accept flag of the given \a gestureType, the equivalent of calling
+ \l{QGestureEvent::setAccepted()}{setAccepted(gestureType, true)}.
+
+ Setting the accept flag indicates that the event receiver wants the
+ gesture. Unwanted gestures may be propagated to the parent widget.
+
+ \sa QGestureEvent::ignore()
+*/
+void QGestureEvent::accept(Qt::GestureType gestureType)
+{
+ setAccepted(gestureType, true);
+}
+
+/*!
+ Clears the accept flag parameter of the given \a gestureType, the equivalent
+ of calling \l{QGestureEvent::setAccepted()}{setAccepted(gesture, false)}.
+
+ Clearing the accept flag indicates that the event receiver does not
+ want the gesture. Unwanted gestures may be propgated to the parent widget.
+
+ \sa QGestureEvent::accept()
+*/
+void QGestureEvent::ignore(Qt::GestureType gestureType)
+{
+ setAccepted(gestureType, false);
+}
+
+/*!
+ Returns true if the gesture of type \a gestureType is accepted; otherwise
+ returns false.
+*/
+bool QGestureEvent::isAccepted(Qt::GestureType gestureType) const
+{
+ return d_func()->accepted.value(gestureType, true);
+}
+
+/*!
+ \internal
+
+ Sets the widget for this event to the \a widget specified.
+*/
+void QGestureEvent::setWidget(QWidget *widget)
+{
+ d_func()->widget = widget;
+}
+
+/*!
+ Returns the widget on which the event occurred.
+*/
+QWidget *QGestureEvent::widget() const
+{
+ return d_func()->widget;
+}
+
+#ifndef QT_NO_GRAPHICSVIEW
+/*!
+ Returns the scene-local coordinates if the \a gesturePoint is inside a
+ graphics view.
+
+ This functional might be useful when the gesture event is delivered to a
+ QGraphicsObject to translate a point in screen coordinates to scene-local
+ coordinates.
+
+ \sa QPointF::isNull().
+*/
+QPointF QGestureEvent::mapToGraphicsScene(const QPointF &gesturePoint) const
+{
+ QWidget *w = widget();
+ if (w) // we get the viewport as widget, not the graphics view
+ w = w->parentWidget();
+ QGraphicsView *view = qobject_cast<QGraphicsView*>(w);
+ if (view) {
+ return view->mapToScene(view->mapFromGlobal(gesturePoint.toPoint()));
+ }
+ return QPointF();
+}
+#endif //QT_NO_GRAPHICSVIEW
+
+/*!
+ \internal
+*/
+QGestureEventPrivate *QGestureEvent::d_func()
+{
+ return reinterpret_cast<QGestureEventPrivate *>(d);
+}
+
+/*!
+ \internal
+*/
+const QGestureEventPrivate *QGestureEvent::d_func() const
+{
+ return reinterpret_cast<const QGestureEventPrivate *>(d);
+}
+
+#ifdef Q_NO_USING_KEYWORD
+/*!
+ \fn void QGestureEvent::setAccepted(bool accepted)
+
+ Sets or clears the event's internal flag that determines whether it should
+ be delivered to other objects.
+
+ Calling this function with a value of true for \a accepted indicates that the
+ caller has accepted the event and that it should not be propagated further.
+ Calling this function with a value of false indicates that the caller has
+ ignored the event and that it should be delivered to other objects.
+
+ For convenience, the accept flag can also be set with accept(), and cleared
+ with ignore().
+
+ \sa QEvent::accepted
+*/
+/*!
+ \fn bool QGestureEvent::isAccepted() const
+
+ Returns true is the event has been accepted; otherwise returns false.
+
+ \sa QEvent::accepted
+*/
+/*!
+ \fn void QGestureEvent::accept()
+
+ Accepts the event, the equivalent of calling setAccepted(true).
+
+ \sa QEvent::accept()
+*/
+/*!
+ \fn void QGestureEvent::ignore()
+
+ Ignores the event, the equivalent of calling setAccepted(false).
+
+ \sa QEvent::ignore()
+*/
+#endif
+
+QT_END_NAMESPACE
+
+#include <moc_qgesture.cpp>
+
+#endif // QT_NO_GESTURES
diff --git a/src/widgets/kernel/qgesture.h b/src/widgets/kernel/qgesture.h
new file mode 100644
index 0000000000..610ae2b9f6
--- /dev/null
+++ b/src/widgets/kernel/qgesture.h
@@ -0,0 +1,328 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGESTURE_H
+#define QGESTURE_H
+
+#include <QtCore/qobject.h>
+#include <QtCore/qlist.h>
+#include <QtCore/qdatetime.h>
+#include <QtCore/qpoint.h>
+#include <QtCore/qrect.h>
+#include <QtCore/qmetatype.h>
+#include <QtGui/qevent.h>
+
+#ifndef QT_NO_GESTURES
+
+QT_BEGIN_HEADER
+
+Q_DECLARE_METATYPE(Qt::GestureState)
+Q_DECLARE_METATYPE(Qt::GestureType)
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QGesturePrivate;
+class Q_WIDGETS_EXPORT QGesture : public QObject
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QGesture)
+
+ Q_PROPERTY(Qt::GestureState state READ state)
+ Q_PROPERTY(Qt::GestureType gestureType READ gestureType)
+ Q_PROPERTY(QGesture::GestureCancelPolicy gestureCancelPolicy READ gestureCancelPolicy WRITE setGestureCancelPolicy)
+ Q_PROPERTY(QPointF hotSpot READ hotSpot WRITE setHotSpot RESET unsetHotSpot)
+ Q_PROPERTY(bool hasHotSpot READ hasHotSpot)
+
+public:
+ explicit QGesture(QObject *parent = 0);
+ ~QGesture();
+
+ Qt::GestureType gestureType() const;
+
+ Qt::GestureState state() const;
+
+ QPointF hotSpot() const;
+ void setHotSpot(const QPointF &value);
+ bool hasHotSpot() const;
+ void unsetHotSpot();
+
+ enum GestureCancelPolicy {
+ CancelNone = 0,
+ CancelAllInContext
+ };
+
+ void setGestureCancelPolicy(GestureCancelPolicy policy);
+ GestureCancelPolicy gestureCancelPolicy() const;
+
+protected:
+ QGesture(QGesturePrivate &dd, QObject *parent);
+
+private:
+ friend class QGestureEvent;
+ friend class QGestureRecognizer;
+ friend class QGestureManager;
+ friend class QGraphicsScenePrivate;
+};
+
+class QPanGesturePrivate;
+class Q_WIDGETS_EXPORT QPanGesture : public QGesture
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QPanGesture)
+
+ Q_PROPERTY(QPointF lastOffset READ lastOffset WRITE setLastOffset)
+ Q_PROPERTY(QPointF offset READ offset WRITE setOffset)
+ Q_PROPERTY(QPointF delta READ delta STORED false)
+ Q_PROPERTY(qreal acceleration READ acceleration WRITE setAcceleration)
+ Q_PRIVATE_PROPERTY(QPanGesture::d_func(), qreal horizontalVelocity READ horizontalVelocity WRITE setHorizontalVelocity)
+ Q_PRIVATE_PROPERTY(QPanGesture::d_func(), qreal verticalVelocity READ verticalVelocity WRITE setVerticalVelocity)
+
+public:
+ QPanGesture(QObject *parent = 0);
+
+ QPointF lastOffset() const;
+ QPointF offset() const;
+ QPointF delta() const;
+ qreal acceleration() const;
+
+ void setLastOffset(const QPointF &value);
+ void setOffset(const QPointF &value);
+ void setAcceleration(qreal value);
+
+ friend class QPanGestureRecognizer;
+ friend class QWinNativePanGestureRecognizer;
+};
+
+class QPinchGesturePrivate;
+class Q_WIDGETS_EXPORT QPinchGesture : public QGesture
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QPinchGesture)
+ Q_FLAGS(ChangeFlags ChangeFlag)
+
+public:
+ enum ChangeFlag {
+ ScaleFactorChanged = 0x1,
+ RotationAngleChanged = 0x2,
+ CenterPointChanged = 0x4
+ };
+ Q_DECLARE_FLAGS(ChangeFlags, ChangeFlag)
+
+ Q_PROPERTY(ChangeFlags totalChangeFlags READ totalChangeFlags WRITE setTotalChangeFlags)
+ Q_PROPERTY(ChangeFlags changeFlags READ changeFlags WRITE setChangeFlags)
+
+ Q_PROPERTY(qreal totalScaleFactor READ totalScaleFactor WRITE setTotalScaleFactor)
+ Q_PROPERTY(qreal lastScaleFactor READ lastScaleFactor WRITE setLastScaleFactor)
+ Q_PROPERTY(qreal scaleFactor READ scaleFactor WRITE setScaleFactor)
+
+ Q_PROPERTY(qreal totalRotationAngle READ totalRotationAngle WRITE setTotalRotationAngle)
+ Q_PROPERTY(qreal lastRotationAngle READ lastRotationAngle WRITE setLastRotationAngle)
+ Q_PROPERTY(qreal rotationAngle READ rotationAngle WRITE setRotationAngle)
+
+ Q_PROPERTY(QPointF startCenterPoint READ startCenterPoint WRITE setStartCenterPoint)
+ Q_PROPERTY(QPointF lastCenterPoint READ lastCenterPoint WRITE setLastCenterPoint)
+ Q_PROPERTY(QPointF centerPoint READ centerPoint WRITE setCenterPoint)
+
+public:
+ QPinchGesture(QObject *parent = 0);
+
+ ChangeFlags totalChangeFlags() const;
+ void setTotalChangeFlags(ChangeFlags value);
+
+ ChangeFlags changeFlags() const;
+ void setChangeFlags(ChangeFlags value);
+
+ QPointF startCenterPoint() const;
+ QPointF lastCenterPoint() const;
+ QPointF centerPoint() const;
+ void setStartCenterPoint(const QPointF &value);
+ void setLastCenterPoint(const QPointF &value);
+ void setCenterPoint(const QPointF &value);
+
+ qreal totalScaleFactor() const;
+ qreal lastScaleFactor() const;
+ qreal scaleFactor() const;
+ void setTotalScaleFactor(qreal value);
+ void setLastScaleFactor(qreal value);
+ void setScaleFactor(qreal value);
+
+ qreal totalRotationAngle() const;
+ qreal lastRotationAngle() const;
+ qreal rotationAngle() const;
+ void setTotalRotationAngle(qreal value);
+ void setLastRotationAngle(qreal value);
+ void setRotationAngle(qreal value);
+
+ friend class QPinchGestureRecognizer;
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QPinchGesture::ChangeFlags)
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QPinchGesture::ChangeFlags)
+
+QT_BEGIN_NAMESPACE
+
+class QSwipeGesturePrivate;
+class Q_WIDGETS_EXPORT QSwipeGesture : public QGesture
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QSwipeGesture)
+ Q_ENUMS(SwipeDirection)
+
+ Q_PROPERTY(SwipeDirection horizontalDirection READ horizontalDirection STORED false)
+ Q_PROPERTY(SwipeDirection verticalDirection READ verticalDirection STORED false)
+ Q_PROPERTY(qreal swipeAngle READ swipeAngle WRITE setSwipeAngle)
+ Q_PRIVATE_PROPERTY(QSwipeGesture::d_func(), qreal velocity READ velocity WRITE setVelocity)
+
+public:
+ enum SwipeDirection { NoDirection, Left, Right, Up, Down };
+ QSwipeGesture(QObject *parent = 0);
+
+ SwipeDirection horizontalDirection() const;
+ SwipeDirection verticalDirection() const;
+
+ qreal swipeAngle() const;
+ void setSwipeAngle(qreal value);
+
+ friend class QSwipeGestureRecognizer;
+};
+
+class QTapGesturePrivate;
+class Q_WIDGETS_EXPORT QTapGesture : public QGesture
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QTapGesture)
+
+ Q_PROPERTY(QPointF position READ position WRITE setPosition)
+
+public:
+ QTapGesture(QObject *parent = 0);
+
+ QPointF position() const;
+ void setPosition(const QPointF &pos);
+
+ friend class QTapGestureRecognizer;
+};
+
+class QTapAndHoldGesturePrivate;
+class Q_WIDGETS_EXPORT QTapAndHoldGesture : public QGesture
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QTapAndHoldGesture)
+
+ Q_PROPERTY(QPointF position READ position WRITE setPosition)
+
+public:
+ QTapAndHoldGesture(QObject *parent = 0);
+
+ QPointF position() const;
+ void setPosition(const QPointF &pos);
+
+ static void setTimeout(int msecs);
+ static int timeout();
+
+ friend class QTapAndHoldGestureRecognizer;
+};
+
+class QGesture;
+class QGestureEventPrivate;
+class Q_WIDGETS_EXPORT QGestureEvent : public QEvent
+{
+public:
+ QGestureEvent(const QList<QGesture *> &gestures);
+ ~QGestureEvent();
+
+ QList<QGesture *> gestures() const;
+ QGesture *gesture(Qt::GestureType type) const;
+
+ QList<QGesture *> activeGestures() const;
+ QList<QGesture *> canceledGestures() const;
+
+#ifdef Q_NO_USING_KEYWORD
+ inline void setAccepted(bool accepted) { QEvent::setAccepted(accepted); }
+ inline bool isAccepted() const { return QEvent::isAccepted(); }
+
+ inline void accept() { QEvent::accept(); }
+ inline void ignore() { QEvent::ignore(); }
+#else
+ using QEvent::setAccepted;
+ using QEvent::isAccepted;
+ using QEvent::accept;
+ using QEvent::ignore;
+#endif
+
+ void setAccepted(QGesture *, bool);
+ void accept(QGesture *);
+ void ignore(QGesture *);
+ bool isAccepted(QGesture *) const;
+
+ void setAccepted(Qt::GestureType, bool);
+ void accept(Qt::GestureType);
+ void ignore(Qt::GestureType);
+ bool isAccepted(Qt::GestureType) const;
+
+ void setWidget(QWidget *widget);
+ QWidget *widget() const;
+
+#ifndef QT_NO_GRAPHICSVIEW
+ QPointF mapToGraphicsScene(const QPointF &gesturePoint) const;
+#endif
+
+private:
+ QGestureEventPrivate *d_func();
+ const QGestureEventPrivate *d_func() const;
+
+ friend class QApplication;
+ friend class QGestureManager;
+};
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QGesture::GestureCancelPolicy)
+QT_END_HEADER
+
+#endif // QT_NO_GESTURES
+
+#endif // QGESTURE_H
diff --git a/src/widgets/kernel/qgesture_p.h b/src/widgets/kernel/qgesture_p.h
new file mode 100644
index 0000000000..85d1c85884
--- /dev/null
+++ b/src/widgets/kernel/qgesture_p.h
@@ -0,0 +1,245 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGESTURE_P_H
+#define QGESTURE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qrect.h"
+#include "qpoint.h"
+#include "qgesture.h"
+#include "qelapsedtimer.h"
+#include "private/qobject_p.h"
+
+#ifndef QT_NO_GESTURES
+
+QT_BEGIN_NAMESPACE
+
+class QGesturePrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QGesture)
+
+public:
+ QGesturePrivate()
+ : gestureType(Qt::CustomGesture), state(Qt::NoGesture),
+ isHotSpotSet(false), gestureCancelPolicy(0)
+ {
+ }
+
+ Qt::GestureType gestureType;
+ Qt::GestureState state;
+ QPointF hotSpot;
+ QPointF sceneHotSpot;
+ uint isHotSpotSet : 1;
+ uint gestureCancelPolicy : 2;
+};
+
+class QPanGesturePrivate : public QGesturePrivate
+{
+ Q_DECLARE_PUBLIC(QPanGesture)
+
+public:
+ QPanGesturePrivate()
+ : acceleration(0), xVelocity(0), yVelocity(0)
+ {
+ }
+
+ qreal horizontalVelocity() const { return xVelocity; }
+ void setHorizontalVelocity(qreal value) { xVelocity = value; }
+ qreal verticalVelocity() const { return yVelocity; }
+ void setVerticalVelocity(qreal value) { yVelocity = value; }
+
+ QPointF lastOffset;
+ QPointF offset;
+ QPoint startPosition;
+ qreal acceleration;
+ qreal xVelocity;
+ qreal yVelocity;
+};
+
+class QPinchGesturePrivate : public QGesturePrivate
+{
+ Q_DECLARE_PUBLIC(QPinchGesture)
+
+public:
+ QPinchGesturePrivate()
+ : totalChangeFlags(0), changeFlags(0),
+ totalScaleFactor(1), lastScaleFactor(1), scaleFactor(1),
+ totalRotationAngle(0), lastRotationAngle(0), rotationAngle(0),
+ isNewSequence(true)
+ {
+ }
+
+ QPinchGesture::ChangeFlags totalChangeFlags;
+ QPinchGesture::ChangeFlags changeFlags;
+
+ QPointF startCenterPoint;
+ QPointF lastCenterPoint;
+ QPointF centerPoint;
+
+ qreal totalScaleFactor;
+ qreal lastScaleFactor;
+ qreal scaleFactor;
+
+ qreal totalRotationAngle;
+ qreal lastRotationAngle;
+ qreal rotationAngle;
+
+ bool isNewSequence;
+ QPointF startPosition[2];
+};
+
+class QSwipeGesturePrivate : public QGesturePrivate
+{
+ Q_DECLARE_PUBLIC(QSwipeGesture)
+
+public:
+ QSwipeGesturePrivate()
+ : horizontalDirection(QSwipeGesture::NoDirection),
+ verticalDirection(QSwipeGesture::NoDirection),
+ swipeAngle(0),
+ started(false), velocityValue(0)
+ {
+ }
+
+ qreal velocity() const { return velocityValue; }
+ void setVelocity(qreal value) { velocityValue = value; }
+
+ QSwipeGesture::SwipeDirection horizontalDirection;
+ QSwipeGesture::SwipeDirection verticalDirection;
+ qreal swipeAngle;
+
+ QPoint lastPositions[3];
+ bool started;
+ qreal velocityValue;
+ QElapsedTimer time;
+};
+
+class QTapGesturePrivate : public QGesturePrivate
+{
+ Q_DECLARE_PUBLIC(QTapGesture)
+
+public:
+ QTapGesturePrivate()
+ {
+ }
+
+ QPointF position;
+};
+
+class QTapAndHoldGesturePrivate : public QGesturePrivate
+{
+ Q_DECLARE_PUBLIC(QTapAndHoldGesture)
+
+public:
+ QTapAndHoldGesturePrivate()
+ : timerId(0)
+ {
+ }
+
+ QPointF position;
+ int timerId;
+ static int Timeout;
+};
+
+#ifndef QT_NO_GESTURES
+class QNativeGestureEvent : public QEvent
+{
+public:
+ enum Type {
+ None,
+ GestureBegin,
+ GestureEnd,
+ Pan,
+ Zoom,
+ Rotate,
+ Swipe
+ };
+
+ QNativeGestureEvent()
+ : QEvent(QEvent::NativeGesture), gestureType(None), percentage(0)
+#ifdef Q_WS_WIN
+ , sequenceId(0), argument(0)
+#endif
+ {
+ }
+
+ Type gestureType;
+ float percentage;
+ QPoint position;
+ float angle;
+#ifdef Q_WS_WIN
+ ulong sequenceId;
+ quint64 argument;
+#endif
+};
+
+class QGestureEventPrivate
+{
+public:
+ inline QGestureEventPrivate(const QList<QGesture *> &list)
+ : gestures(list), widget(0)
+ {
+ }
+
+ QList<QGesture *> gestures;
+ QWidget *widget;
+ QMap<Qt::GestureType, bool> accepted;
+ QMap<Qt::GestureType, QWidget *> targetWidgets;
+};
+#endif // QT_NO_GESTURES
+
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_GESTURES
+
+#endif // QGESTURE_P_H
diff --git a/src/widgets/kernel/qgesturemanager.cpp b/src/widgets/kernel/qgesturemanager.cpp
new file mode 100644
index 0000000000..d3d34c2756
--- /dev/null
+++ b/src/widgets/kernel/qgesturemanager.cpp
@@ -0,0 +1,720 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "private/qgesturemanager_p.h"
+#include "private/qstandardgestures_p.h"
+#include "private/qwidget_p.h"
+#include "private/qgesture_p.h"
+#include "private/qgraphicsitem_p.h"
+#include "private/qevent_p.h"
+#include "private/qapplication_p.h"
+#include "qgesture.h"
+#include "qevent.h"
+#include "qgraphicsitem.h"
+
+#ifdef Q_WS_MAC
+#include "qmacgesturerecognizer_mac_p.h"
+#endif
+#if defined(Q_WS_WIN) && !defined(QT_NO_NATIVE_GESTURES)
+#include "qwinnativepangesturerecognizer_win_p.h"
+#endif
+
+#include "qdebug.h"
+
+// #define GESTURE_DEBUG
+#ifndef GESTURE_DEBUG
+# define DEBUG if (0) qDebug
+#else
+# define DEBUG qDebug
+#endif
+
+#ifndef QT_NO_GESTURES
+
+QT_BEGIN_NAMESPACE
+
+QGestureManager::QGestureManager(QObject *parent)
+ : QObject(parent), state(NotGesture), m_lastCustomGestureId(Qt::CustomGesture)
+{
+ qRegisterMetaType<Qt::GestureState>();
+
+#if defined(Q_WS_MAC)
+ registerGestureRecognizer(new QMacSwipeGestureRecognizer);
+ registerGestureRecognizer(new QMacPinchGestureRecognizer);
+ #if defined(QT_MAC_USE_COCOA)
+ registerGestureRecognizer(new QMacPanGestureRecognizer);
+ #endif
+#else
+ registerGestureRecognizer(new QPanGestureRecognizer);
+ registerGestureRecognizer(new QPinchGestureRecognizer);
+ registerGestureRecognizer(new QSwipeGestureRecognizer);
+ registerGestureRecognizer(new QTapGestureRecognizer);
+#endif
+#if defined(Q_WS_WIN)
+ #if !defined(QT_NO_NATIVE_GESTURES)
+ if (QApplicationPrivate::HasTouchSupport)
+ registerGestureRecognizer(new QWinNativePanGestureRecognizer);
+ #endif
+#else
+ registerGestureRecognizer(new QTapAndHoldGestureRecognizer);
+#endif
+}
+
+QGestureManager::~QGestureManager()
+{
+ qDeleteAll(m_recognizers.values());
+ foreach (QGestureRecognizer *recognizer, m_obsoleteGestures.keys()) {
+ qDeleteAll(m_obsoleteGestures.value(recognizer));
+ delete recognizer;
+ }
+ m_obsoleteGestures.clear();
+}
+
+Qt::GestureType QGestureManager::registerGestureRecognizer(QGestureRecognizer *recognizer)
+{
+ QGesture *dummy = recognizer->create(0);
+ if (!dummy) {
+ qWarning("QGestureManager::registerGestureRecognizer: "
+ "the recognizer fails to create a gesture object, skipping registration.");
+ return Qt::GestureType(0);
+ }
+ Qt::GestureType type = dummy->gestureType();
+ if (type == Qt::CustomGesture) {
+ // generate a new custom gesture id
+ ++m_lastCustomGestureId;
+ type = Qt::GestureType(m_lastCustomGestureId);
+ }
+ m_recognizers.insertMulti(type, recognizer);
+ delete dummy;
+ return type;
+}
+
+void QGestureManager::unregisterGestureRecognizer(Qt::GestureType type)
+{
+ QList<QGestureRecognizer *> list = m_recognizers.values(type);
+ while (QGestureRecognizer *recognizer = m_recognizers.take(type)) {
+ if (!m_obsoleteGestures.contains(recognizer)) {
+ // inserting even an empty QSet will cause the recognizer to be deleted on destruction of the manager
+ m_obsoleteGestures.insert(recognizer, QSet<QGesture *>());
+ }
+ }
+ foreach (QGesture *g, m_gestureToRecognizer.keys()) {
+ QGestureRecognizer *recognizer = m_gestureToRecognizer.value(g);
+ if (list.contains(recognizer)) {
+ m_deletedRecognizers.insert(g, recognizer);
+ }
+ }
+
+ QMap<ObjectGesture, QList<QGesture *> >::const_iterator iter = m_objectGestures.begin();
+ while (iter != m_objectGestures.end()) {
+ ObjectGesture objectGesture = iter.key();
+ if (objectGesture.gesture == type) {
+ foreach (QGesture *g, iter.value()) {
+ if (QGestureRecognizer *recognizer = m_gestureToRecognizer.value(g)) {
+ m_gestureToRecognizer.remove(g);
+ m_obsoleteGestures[recognizer].insert(g);
+ }
+ }
+ }
+ ++iter;
+ }
+}
+
+void QGestureManager::cleanupCachedGestures(QObject *target, Qt::GestureType type)
+{
+ QMap<ObjectGesture, QList<QGesture *> >::Iterator iter = m_objectGestures.begin();
+ while (iter != m_objectGestures.end()) {
+ ObjectGesture objectGesture = iter.key();
+ if (objectGesture.gesture == type && target == objectGesture.object) {
+ QSet<QGesture *> gestures = iter.value().toSet();
+ for (QHash<QGestureRecognizer *, QSet<QGesture *> >::iterator
+ it = m_obsoleteGestures.begin(), e = m_obsoleteGestures.end(); it != e; ++it) {
+ it.value() -= gestures;
+ }
+ foreach (QGesture *g, gestures) {
+ m_deletedRecognizers.remove(g);
+ m_gestureToRecognizer.remove(g);
+ m_maybeGestures.remove(g);
+ m_activeGestures.remove(g);
+ m_gestureOwners.remove(g);
+ m_gestureTargets.remove(g);
+ m_gesturesToDelete.insert(g);
+ }
+
+ iter = m_objectGestures.erase(iter);
+ } else {
+ ++iter;
+ }
+ }
+}
+
+// get or create a QGesture object that will represent the state for a given object, used by the recognizer
+QGesture *QGestureManager::getState(QObject *object, QGestureRecognizer *recognizer, Qt::GestureType type)
+{
+ // if the widget is being deleted we should be careful not to
+ // create a new state, as it will create QWeakPointer which doesn't work
+ // from the destructor.
+ if (object->isWidgetType()) {
+ if (static_cast<QWidget *>(object)->d_func()->data.in_destructor)
+ return 0;
+ } else if (QGesture *g = qobject_cast<QGesture *>(object)) {
+ return g;
+#ifndef QT_NO_GRAPHICSVIEW
+ } else {
+ Q_ASSERT(qobject_cast<QGraphicsObject *>(object));
+ QGraphicsObject *graphicsObject = static_cast<QGraphicsObject *>(object);
+ if (graphicsObject->QGraphicsItem::d_func()->inDestructor)
+ return 0;
+#endif
+ }
+
+ // check if the QGesture for this recognizer has already been created
+ foreach (QGesture *state, m_objectGestures.value(QGestureManager::ObjectGesture(object, type))) {
+ if (m_gestureToRecognizer.value(state) == recognizer)
+ return state;
+ }
+
+ Q_ASSERT(recognizer);
+ QGesture *state = recognizer->create(object);
+ if (!state)
+ return 0;
+ state->setParent(this);
+ if (state->gestureType() == Qt::CustomGesture) {
+ // if the recognizer didn't fill in the gesture type, then this
+ // is a custom gesture with autogenerated id and we fill it.
+ state->d_func()->gestureType = type;
+#if defined(GESTURE_DEBUG)
+ state->setObjectName(QString::number((int)type));
+#endif
+ }
+ m_objectGestures[QGestureManager::ObjectGesture(object, type)].append(state);
+ m_gestureToRecognizer[state] = recognizer;
+ m_gestureOwners[state] = object;
+
+ return state;
+}
+
+bool QGestureManager::filterEventThroughContexts(const QMultiMap<QObject *,
+ Qt::GestureType> &contexts,
+ QEvent *event)
+{
+ QSet<QGesture *> triggeredGestures;
+ QSet<QGesture *> finishedGestures;
+ QSet<QGesture *> newMaybeGestures;
+ QSet<QGesture *> notGestures;
+
+ // TODO: sort contexts by the gesture type and check if one of the contexts
+ // is already active.
+
+ bool consumeEventHint = false;
+
+ // filter the event through recognizers
+ typedef QMultiMap<QObject *, Qt::GestureType>::const_iterator ContextIterator;
+ ContextIterator contextEnd = contexts.end();
+ for (ContextIterator context = contexts.begin(); context != contextEnd; ++context) {
+ Qt::GestureType gestureType = context.value();
+ QMap<Qt::GestureType, QGestureRecognizer *>::const_iterator
+ typeToRecognizerIterator = m_recognizers.lowerBound(gestureType),
+ typeToRecognizerEnd = m_recognizers.upperBound(gestureType);
+ for (; typeToRecognizerIterator != typeToRecognizerEnd; ++typeToRecognizerIterator) {
+ QGestureRecognizer *recognizer = typeToRecognizerIterator.value();
+ QObject *target = context.key();
+ QGesture *state = getState(target, recognizer, gestureType);
+ if (!state)
+ continue;
+ QGestureRecognizer::Result recognizerResult = recognizer->recognize(state, target, event);
+ QGestureRecognizer::Result recognizerState = recognizerResult & QGestureRecognizer::ResultState_Mask;
+ QGestureRecognizer::Result resultHint = recognizerResult & QGestureRecognizer::ResultHint_Mask;
+ if (recognizerState == QGestureRecognizer::TriggerGesture) {
+ DEBUG() << "QGestureManager:Recognizer: gesture triggered: " << state;
+ triggeredGestures << state;
+ } else if (recognizerState == QGestureRecognizer::FinishGesture) {
+ DEBUG() << "QGestureManager:Recognizer: gesture finished: " << state;
+ finishedGestures << state;
+ } else if (recognizerState == QGestureRecognizer::MayBeGesture) {
+ DEBUG() << "QGestureManager:Recognizer: maybe gesture: " << state;
+ newMaybeGestures << state;
+ } else if (recognizerState == QGestureRecognizer::CancelGesture) {
+ DEBUG() << "QGestureManager:Recognizer: not gesture: " << state;
+ notGestures << state;
+ } else if (recognizerState == QGestureRecognizer::Ignore) {
+ DEBUG() << "QGestureManager:Recognizer: ignored the event: " << state;
+ } else {
+ DEBUG() << "QGestureManager:Recognizer: hm, lets assume the recognizer"
+ << "ignored the event: " << state;
+ }
+ if (resultHint & QGestureRecognizer::ConsumeEventHint) {
+ DEBUG() << "QGestureManager: we were asked to consume the event: "
+ << state;
+ consumeEventHint = true;
+ }
+ }
+ }
+ if (triggeredGestures.isEmpty() && finishedGestures.isEmpty()
+ && newMaybeGestures.isEmpty() && notGestures.isEmpty())
+ return consumeEventHint;
+
+ QSet<QGesture *> startedGestures = triggeredGestures - m_activeGestures;
+ triggeredGestures &= m_activeGestures;
+
+ // check if a running gesture switched back to maybe state
+ QSet<QGesture *> activeToMaybeGestures = m_activeGestures & newMaybeGestures;
+
+ // check if a maybe gesture switched to canceled - reset it but don't send an event
+ QSet<QGesture *> maybeToCanceledGestures = m_maybeGestures & notGestures;
+
+ // check if a running gesture switched back to not gesture state,
+ // i.e. were canceled
+ QSet<QGesture *> canceledGestures = m_activeGestures & notGestures;
+
+ // new gestures in maybe state
+ m_maybeGestures += newMaybeGestures;
+
+ // gestures that were in maybe state
+ QSet<QGesture *> notMaybeGestures = (startedGestures | triggeredGestures
+ | finishedGestures | canceledGestures
+ | notGestures);
+ m_maybeGestures -= notMaybeGestures;
+
+ Q_ASSERT((startedGestures & finishedGestures).isEmpty());
+ Q_ASSERT((startedGestures & newMaybeGestures).isEmpty());
+ Q_ASSERT((startedGestures & canceledGestures).isEmpty());
+ Q_ASSERT((finishedGestures & newMaybeGestures).isEmpty());
+ Q_ASSERT((finishedGestures & canceledGestures).isEmpty());
+ Q_ASSERT((canceledGestures & newMaybeGestures).isEmpty());
+
+ QSet<QGesture *> notStarted = finishedGestures - m_activeGestures;
+ if (!notStarted.isEmpty()) {
+ // there are some gestures that claim to be finished, but never started.
+ // probably those are "singleshot" gestures so we'll fake the started state.
+ foreach (QGesture *gesture, notStarted)
+ gesture->d_func()->state = Qt::GestureStarted;
+ QSet<QGesture *> undeliveredGestures;
+ deliverEvents(notStarted, &undeliveredGestures);
+ finishedGestures -= undeliveredGestures;
+ }
+
+ m_activeGestures += startedGestures;
+ // sanity check: all triggered gestures should already be in active gestures list
+ Q_ASSERT((m_activeGestures & triggeredGestures).size() == triggeredGestures.size());
+ m_activeGestures -= finishedGestures;
+ m_activeGestures -= activeToMaybeGestures;
+ m_activeGestures -= canceledGestures;
+
+ // set the proper gesture state on each gesture
+ foreach (QGesture *gesture, startedGestures)
+ gesture->d_func()->state = Qt::GestureStarted;
+ foreach (QGesture *gesture, triggeredGestures)
+ gesture->d_func()->state = Qt::GestureUpdated;
+ foreach (QGesture *gesture, finishedGestures)
+ gesture->d_func()->state = Qt::GestureFinished;
+ foreach (QGesture *gesture, canceledGestures)
+ gesture->d_func()->state = Qt::GestureCanceled;
+ foreach (QGesture *gesture, activeToMaybeGestures)
+ gesture->d_func()->state = Qt::GestureFinished;
+
+ if (!m_activeGestures.isEmpty() || !m_maybeGestures.isEmpty() ||
+ !startedGestures.isEmpty() || !triggeredGestures.isEmpty() ||
+ !finishedGestures.isEmpty() || !canceledGestures.isEmpty()) {
+ DEBUG() << "QGestureManager::filterEventThroughContexts:"
+ << "\n\tactiveGestures:" << m_activeGestures
+ << "\n\tmaybeGestures:" << m_maybeGestures
+ << "\n\tstarted:" << startedGestures
+ << "\n\ttriggered:" << triggeredGestures
+ << "\n\tfinished:" << finishedGestures
+ << "\n\tcanceled:" << canceledGestures
+ << "\n\tmaybe-canceled:" << maybeToCanceledGestures;
+ }
+
+ QSet<QGesture *> undeliveredGestures;
+ deliverEvents(startedGestures+triggeredGestures+finishedGestures+canceledGestures,
+ &undeliveredGestures);
+
+ foreach (QGesture *g, startedGestures) {
+ if (undeliveredGestures.contains(g))
+ continue;
+ if (g->gestureCancelPolicy() == QGesture::CancelAllInContext) {
+ DEBUG() << "lets try to cancel some";
+ // find gestures in context in Qt::GestureStarted or Qt::GestureUpdated state and cancel them
+ cancelGesturesForChildren(g);
+ }
+ }
+
+ m_activeGestures -= undeliveredGestures;
+
+ // reset gestures that ended
+ QSet<QGesture *> endedGestures =
+ finishedGestures + canceledGestures + undeliveredGestures + maybeToCanceledGestures;
+ foreach (QGesture *gesture, endedGestures) {
+ recycle(gesture);
+ m_gestureTargets.remove(gesture);
+ }
+
+ //Clean up the Gestures
+ qDeleteAll(m_gesturesToDelete);
+ m_gesturesToDelete.clear();
+
+ return consumeEventHint;
+}
+
+// Cancel all gestures of children of the widget that original is associated with
+void QGestureManager::cancelGesturesForChildren(QGesture *original)
+{
+ Q_ASSERT(original);
+ QWidget *originatingWidget = m_gestureTargets.value(original);
+ Q_ASSERT(originatingWidget);
+
+ // iterate over all active gestures and all maybe gestures
+ // for each find the owner
+ // if the owner is part of our sub-hierarchy, cancel it.
+
+ QSet<QGesture*> cancelledGestures;
+ QSet<QGesture*>::Iterator iter = m_activeGestures.begin();
+ while (iter != m_activeGestures.end()) {
+ QWidget *widget = m_gestureTargets.value(*iter);
+ // note that we don't touch the gestures for our originatingWidget
+ if (widget != originatingWidget && originatingWidget->isAncestorOf(widget)) {
+ DEBUG() << " found a gesture to cancel" << (*iter);
+ (*iter)->d_func()->state = Qt::GestureCanceled;
+ cancelledGestures << *iter;
+ iter = m_activeGestures.erase(iter);
+ } else {
+ ++iter;
+ }
+ }
+
+ // TODO handle 'maybe' gestures too
+
+ // sort them per target widget by cherry picking from almostCanceledGestures and delivering
+ QSet<QGesture *> almostCanceledGestures = cancelledGestures;
+ while (!almostCanceledGestures.isEmpty()) {
+ QWidget *target = 0;
+ QSet<QGesture*> gestures;
+ iter = almostCanceledGestures.begin();
+ // sort per target widget
+ while (iter != almostCanceledGestures.end()) {
+ QWidget *widget = m_gestureTargets.value(*iter);
+ if (target == 0)
+ target = widget;
+ if (target == widget) {
+ gestures << *iter;
+ iter = almostCanceledGestures.erase(iter);
+ } else {
+ ++iter;
+ }
+ }
+ Q_ASSERT(target);
+
+ QSet<QGesture*> undeliveredGestures;
+ deliverEvents(gestures, &undeliveredGestures);
+ }
+
+ for (iter = cancelledGestures.begin(); iter != cancelledGestures.end(); ++iter)
+ recycle(*iter);
+}
+
+void QGestureManager::cleanupGesturesForRemovedRecognizer(QGesture *gesture)
+{
+ QGestureRecognizer *recognizer = m_deletedRecognizers.value(gesture);
+ if(!recognizer) //The Gesture is removed while in the even loop, so the recognizers for this gestures was removed
+ return;
+ m_deletedRecognizers.remove(gesture);
+ if (m_deletedRecognizers.keys(recognizer).isEmpty()) {
+ // no more active gestures, cleanup!
+ qDeleteAll(m_obsoleteGestures.value(recognizer));
+ m_obsoleteGestures.remove(recognizer);
+ delete recognizer;
+ }
+}
+
+// return true if accepted (consumed)
+bool QGestureManager::filterEvent(QWidget *receiver, QEvent *event)
+{
+ QMap<Qt::GestureType, int> types;
+ QMultiMap<QObject *, Qt::GestureType> contexts;
+ QWidget *w = receiver;
+ typedef QMap<Qt::GestureType, Qt::GestureFlags>::const_iterator ContextIterator;
+ if (!w->d_func()->gestureContext.isEmpty()) {
+ for(ContextIterator it = w->d_func()->gestureContext.begin(),
+ e = w->d_func()->gestureContext.end(); it != e; ++it) {
+ types.insert(it.key(), 0);
+ contexts.insertMulti(w, it.key());
+ }
+ }
+ // find all gesture contexts for the widget tree
+ w = w->isWindow() ? 0 : w->parentWidget();
+ while (w)
+ {
+ for (ContextIterator it = w->d_func()->gestureContext.begin(),
+ e = w->d_func()->gestureContext.end(); it != e; ++it) {
+ if (!(it.value() & Qt::DontStartGestureOnChildren)) {
+ if (!types.contains(it.key())) {
+ types.insert(it.key(), 0);
+ contexts.insertMulti(w, it.key());
+ }
+ }
+ }
+ if (w->isWindow())
+ break;
+ w = w->parentWidget();
+ }
+ return contexts.isEmpty() ? false : filterEventThroughContexts(contexts, event);
+}
+
+#ifndef QT_NO_GRAPHICSVIEW
+bool QGestureManager::filterEvent(QGraphicsObject *receiver, QEvent *event)
+{
+ QMap<Qt::GestureType, int> types;
+ QMultiMap<QObject *, Qt::GestureType> contexts;
+ QGraphicsObject *item = receiver;
+ if (!item->QGraphicsItem::d_func()->gestureContext.isEmpty()) {
+ typedef QMap<Qt::GestureType, Qt::GestureFlags>::const_iterator ContextIterator;
+ for(ContextIterator it = item->QGraphicsItem::d_func()->gestureContext.begin(),
+ e = item->QGraphicsItem::d_func()->gestureContext.end(); it != e; ++it) {
+ types.insert(it.key(), 0);
+ contexts.insertMulti(item, it.key());
+ }
+ }
+ // find all gesture contexts for the graphics object tree
+ item = item->parentObject();
+ while (item)
+ {
+ typedef QMap<Qt::GestureType, Qt::GestureFlags>::const_iterator ContextIterator;
+ for (ContextIterator it = item->QGraphicsItem::d_func()->gestureContext.begin(),
+ e = item->QGraphicsItem::d_func()->gestureContext.end(); it != e; ++it) {
+ if (!(it.value() & Qt::DontStartGestureOnChildren)) {
+ if (!types.contains(it.key())) {
+ types.insert(it.key(), 0);
+ contexts.insertMulti(item, it.key());
+ }
+ }
+ }
+ item = item->parentObject();
+ }
+ return contexts.isEmpty() ? false : filterEventThroughContexts(contexts, event);
+}
+#endif
+
+bool QGestureManager::filterEvent(QObject *receiver, QEvent *event)
+{
+ if (!m_gestureToRecognizer.contains(static_cast<QGesture *>(receiver)))
+ return false;
+ QGesture *state = static_cast<QGesture *>(receiver);
+ QMultiMap<QObject *, Qt::GestureType> contexts;
+ contexts.insert(state, state->gestureType());
+ return filterEventThroughContexts(contexts, event);
+}
+
+void QGestureManager::getGestureTargets(const QSet<QGesture*> &gestures,
+ QMap<QWidget *, QList<QGesture *> > *conflicts,
+ QMap<QWidget *, QList<QGesture *> > *normal)
+{
+ typedef QHash<Qt::GestureType, QHash<QWidget *, QGesture *> > GestureByTypes;
+ GestureByTypes gestureByTypes;
+
+ // sort gestures by types
+ foreach (QGesture *gesture, gestures) {
+ QWidget *receiver = m_gestureTargets.value(gesture, 0);
+ Q_ASSERT(receiver);
+ gestureByTypes[gesture->gestureType()].insert(receiver, gesture);
+ }
+
+ // for each gesture type
+ foreach (Qt::GestureType type, gestureByTypes.keys()) {
+ QHash<QWidget *, QGesture *> gestures = gestureByTypes.value(type);
+ foreach (QWidget *widget, gestures.keys()) {
+ QWidget *w = widget->parentWidget();
+ while (w) {
+ QMap<Qt::GestureType, Qt::GestureFlags>::const_iterator it
+ = w->d_func()->gestureContext.find(type);
+ if (it != w->d_func()->gestureContext.end()) {
+ // i.e. 'w' listens to gesture 'type'
+ if (!(it.value() & Qt::DontStartGestureOnChildren) && w != widget) {
+ // conflicting gesture!
+ (*conflicts)[widget].append(gestures[widget]);
+ break;
+ }
+ }
+ if (w->isWindow()) {
+ w = 0;
+ break;
+ }
+ w = w->parentWidget();
+ }
+ if (!w)
+ (*normal)[widget].append(gestures[widget]);
+ }
+ }
+}
+
+void QGestureManager::deliverEvents(const QSet<QGesture *> &gestures,
+ QSet<QGesture *> *undeliveredGestures)
+{
+ if (gestures.isEmpty())
+ return;
+
+ typedef QMap<QWidget *, QList<QGesture *> > GesturesPerWidget;
+ GesturesPerWidget conflictedGestures;
+ GesturesPerWidget normalStartedGestures;
+
+ QSet<QGesture *> startedGestures;
+ // first figure out the initial receivers of gestures
+ for (QSet<QGesture *>::const_iterator it = gestures.begin(),
+ e = gestures.end(); it != e; ++it) {
+ QGesture *gesture = *it;
+ QWidget *target = m_gestureTargets.value(gesture, 0);
+ if (!target) {
+ // the gesture has just started and doesn't have a target yet.
+ Q_ASSERT(gesture->state() == Qt::GestureStarted);
+ if (gesture->hasHotSpot()) {
+ // guess the target widget using the hotspot of the gesture
+ QPoint pt = gesture->hotSpot().toPoint();
+ if (QWidget *topLevel = qApp->topLevelAt(pt)) {
+ QWidget *child = topLevel->childAt(topLevel->mapFromGlobal(pt));
+ target = child ? child : topLevel;
+ }
+ } else {
+ // or use the context of the gesture
+ QObject *context = m_gestureOwners.value(gesture, 0);
+ if (context->isWidgetType())
+ target = static_cast<QWidget *>(context);
+ }
+ if (target)
+ m_gestureTargets.insert(gesture, target);
+ }
+
+ Qt::GestureType gestureType = gesture->gestureType();
+ Q_ASSERT(gestureType != Qt::CustomGesture);
+ Q_UNUSED(gestureType);
+
+ if (target) {
+ if (gesture->state() == Qt::GestureStarted) {
+ startedGestures.insert(gesture);
+ } else {
+ normalStartedGestures[target].append(gesture);
+ }
+ } else {
+ DEBUG() << "QGestureManager::deliverEvent: could not find the target for gesture"
+ << gesture->gestureType();
+ qWarning("QGestureManager::deliverEvent: could not find the target for gesture");
+ undeliveredGestures->insert(gesture);
+ }
+ }
+
+ getGestureTargets(startedGestures, &conflictedGestures, &normalStartedGestures);
+ DEBUG() << "QGestureManager::deliverEvents:"
+ << "\nstarted: " << startedGestures
+ << "\nconflicted: " << conflictedGestures
+ << "\nnormal: " << normalStartedGestures
+ << "\n";
+
+ // if there are conflicting gestures, send the GestureOverride event
+ for (GesturesPerWidget::const_iterator it = conflictedGestures.begin(),
+ e = conflictedGestures.end(); it != e; ++it) {
+ QWidget *receiver = it.key();
+ QList<QGesture *> gestures = it.value();
+ DEBUG() << "QGestureManager::deliverEvents: sending GestureOverride to"
+ << receiver
+ << "gestures:" << gestures;
+ QGestureEvent event(gestures);
+ event.t = QEvent::GestureOverride;
+ // mark event and individual gestures as ignored
+ event.ignore();
+ foreach(QGesture *g, gestures)
+ event.setAccepted(g, false);
+
+ QApplication::sendEvent(receiver, &event);
+ bool eventAccepted = event.isAccepted();
+ foreach(QGesture *gesture, event.gestures()) {
+ if (eventAccepted || event.isAccepted(gesture)) {
+ QWidget *w = event.d_func()->targetWidgets.value(gesture->gestureType(), 0);
+ Q_ASSERT(w);
+ DEBUG() << "override event: gesture was accepted:" << gesture << w;
+ QList<QGesture *> &gestures = normalStartedGestures[w];
+ gestures.append(gesture);
+ // override the target
+ m_gestureTargets[gesture] = w;
+ } else {
+ DEBUG() << "override event: gesture wasn't accepted. putting back:" << gesture;
+ QList<QGesture *> &gestures = normalStartedGestures[receiver];
+ gestures.append(gesture);
+ }
+ }
+ }
+
+ // delivering gestures that are not in conflicted state
+ for (GesturesPerWidget::const_iterator it = normalStartedGestures.begin(),
+ e = normalStartedGestures.end(); it != e; ++it) {
+ if (!it.value().isEmpty()) {
+ DEBUG() << "QGestureManager::deliverEvents: sending to" << it.key()
+ << "gestures:" << it.value();
+ QGestureEvent event(it.value());
+ QApplication::sendEvent(it.key(), &event);
+ bool eventAccepted = event.isAccepted();
+ foreach (QGesture *gesture, event.gestures()) {
+ if (gesture->state() == Qt::GestureStarted &&
+ (eventAccepted || event.isAccepted(gesture))) {
+ QWidget *w = event.d_func()->targetWidgets.value(gesture->gestureType(), 0);
+ Q_ASSERT(w);
+ DEBUG() << "started gesture was delivered and accepted by" << w;
+ m_gestureTargets[gesture] = w;
+ }
+ }
+ }
+ }
+}
+
+void QGestureManager::recycle(QGesture *gesture)
+{
+ QGestureRecognizer *recognizer = m_gestureToRecognizer.value(gesture, 0);
+ if (recognizer) {
+ gesture->setGestureCancelPolicy(QGesture::CancelNone);
+ recognizer->reset(gesture);
+ m_activeGestures.remove(gesture);
+ } else {
+ cleanupGesturesForRemovedRecognizer(gesture);
+ }
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_GESTURES
+
+#include "moc_qgesturemanager_p.cpp"
diff --git a/src/gui/kernel/qgesturemanager_p.h b/src/widgets/kernel/qgesturemanager_p.h
index 6c8cbb9cd0..6c8cbb9cd0 100644
--- a/src/gui/kernel/qgesturemanager_p.h
+++ b/src/widgets/kernel/qgesturemanager_p.h
diff --git a/src/gui/kernel/qgesturerecognizer.cpp b/src/widgets/kernel/qgesturerecognizer.cpp
index 887617569d..887617569d 100644
--- a/src/gui/kernel/qgesturerecognizer.cpp
+++ b/src/widgets/kernel/qgesturerecognizer.cpp
diff --git a/src/widgets/kernel/qgesturerecognizer.h b/src/widgets/kernel/qgesturerecognizer.h
new file mode 100644
index 0000000000..019f856f09
--- /dev/null
+++ b/src/widgets/kernel/qgesturerecognizer.h
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGESTURERECOGNIZER_H
+#define QGESTURERECOGNIZER_H
+
+#include <QtCore/qglobal.h>
+#include <QtCore/qnamespace.h>
+
+#ifndef QT_NO_GESTURES
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QObject;
+class QEvent;
+class QGesture;
+class Q_WIDGETS_EXPORT QGestureRecognizer
+{
+public:
+ enum ResultFlag
+ {
+ Ignore = 0x0001,
+
+ MayBeGesture = 0x0002,
+ TriggerGesture = 0x0004,
+ FinishGesture = 0x0008,
+ CancelGesture = 0x0010,
+
+ ResultState_Mask = 0x00ff,
+
+ ConsumeEventHint = 0x0100,
+ // StoreEventHint = 0x0200,
+ // ReplayStoredEventsHint = 0x0400,
+ // DiscardStoredEventsHint = 0x0800,
+
+ ResultHint_Mask = 0xff00
+ };
+ Q_DECLARE_FLAGS(Result, ResultFlag)
+
+ QGestureRecognizer();
+ virtual ~QGestureRecognizer();
+
+ virtual QGesture *create(QObject *target);
+ virtual Result recognize(QGesture *state, QObject *watched,
+ QEvent *event) = 0;
+ virtual void reset(QGesture *state);
+
+ static Qt::GestureType registerRecognizer(QGestureRecognizer *recognizer);
+ static void unregisterRecognizer(Qt::GestureType type);
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QGestureRecognizer::Result)
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QT_NO_GESTURES
+
+#endif // QGESTURERECOGNIZER_H
diff --git a/src/gui/kernel/qgridlayout.cpp b/src/widgets/kernel/qgridlayout.cpp
index c237136480..c237136480 100644
--- a/src/gui/kernel/qgridlayout.cpp
+++ b/src/widgets/kernel/qgridlayout.cpp
diff --git a/src/widgets/kernel/qgridlayout.h b/src/widgets/kernel/qgridlayout.h
new file mode 100644
index 0000000000..3e579e3dfd
--- /dev/null
+++ b/src/widgets/kernel/qgridlayout.h
@@ -0,0 +1,176 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGRIDLAYOUT_H
+#define QGRIDLAYOUT_H
+
+#include <QtWidgets/qlayout.h>
+#ifdef QT_INCLUDE_COMPAT
+#include <QtWidgets/qwidget.h>
+#endif
+
+#include <limits.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QGridLayoutPrivate;
+
+class Q_WIDGETS_EXPORT QGridLayout : public QLayout
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QGridLayout)
+ QDOC_PROPERTY(int horizontalSpacing READ horizontalSpacing WRITE setHorizontalSpacing)
+ QDOC_PROPERTY(int verticalSpacing READ verticalSpacing WRITE setVerticalSpacing)
+
+public:
+ explicit QGridLayout(QWidget *parent);
+ QGridLayout();
+
+#ifdef QT3_SUPPORT
+ QT3_SUPPORT_CONSTRUCTOR QGridLayout(QWidget *parent, int nRows , int nCols = 1, int border = 0,
+ int spacing = -1, const char *name = 0);
+ QT3_SUPPORT_CONSTRUCTOR QGridLayout(int nRows , int nCols = 1, int spacing = -1, const char *name = 0);
+ QT3_SUPPORT_CONSTRUCTOR QGridLayout(QLayout *parentLayout, int nRows = 1, int nCols = 1, int spacing = -1,
+ const char *name = 0);
+#endif
+ ~QGridLayout();
+
+ QSize sizeHint() const;
+ QSize minimumSize() const;
+ QSize maximumSize() const;
+
+ void setHorizontalSpacing(int spacing);
+ int horizontalSpacing() const;
+ void setVerticalSpacing(int spacing);
+ int verticalSpacing() const;
+ void setSpacing(int spacing);
+ int spacing() const;
+
+ void setRowStretch(int row, int stretch);
+ void setColumnStretch(int column, int stretch);
+ int rowStretch(int row) const;
+ int columnStretch(int column) const;
+
+ void setRowMinimumHeight(int row, int minSize);
+ void setColumnMinimumWidth(int column, int minSize);
+ int rowMinimumHeight(int row) const;
+ int columnMinimumWidth(int column) const;
+
+ int columnCount() const;
+ int rowCount() const;
+
+ QRect cellRect(int row, int column) const;
+#ifdef QT3_SUPPORT
+ inline QT3_SUPPORT QRect cellGeometry(int row, int column) const {return cellRect(row, column);}
+#endif
+
+ bool hasHeightForWidth() const;
+ int heightForWidth(int) const;
+ int minimumHeightForWidth(int) const;
+
+ Qt::Orientations expandingDirections() const;
+ void invalidate();
+
+ inline void addWidget(QWidget *w) { QLayout::addWidget(w); }
+ void addWidget(QWidget *, int row, int column, Qt::Alignment = 0);
+ void addWidget(QWidget *, int row, int column, int rowSpan, int columnSpan, Qt::Alignment = 0);
+ void addLayout(QLayout *, int row, int column, Qt::Alignment = 0);
+ void addLayout(QLayout *, int row, int column, int rowSpan, int columnSpan, Qt::Alignment = 0);
+
+ void setOriginCorner(Qt::Corner);
+ Qt::Corner originCorner() const;
+
+#ifdef QT3_SUPPORT
+ inline QT3_SUPPORT void setOrigin(Qt::Corner corner) { setOriginCorner(corner); }
+ inline QT3_SUPPORT Qt::Corner origin() const { return originCorner(); }
+#endif
+ QLayoutItem *itemAt(int index) const;
+ QLayoutItem *itemAtPosition(int row, int column) const;
+ QLayoutItem *takeAt(int index);
+ int count() const;
+ void setGeometry(const QRect&);
+
+ void addItem(QLayoutItem *item, int row, int column, int rowSpan = 1, int columnSpan = 1, Qt::Alignment = 0);
+
+ void setDefaultPositioning(int n, Qt::Orientation orient);
+ void getItemPosition(int idx, int *row, int *column, int *rowSpan, int *columnSpan);
+
+protected:
+#ifdef QT3_SUPPORT
+ QT3_SUPPORT bool findWidget(QWidget* w, int *r, int *c);
+#endif
+ void addItem(QLayoutItem *);
+
+private:
+ Q_DISABLE_COPY(QGridLayout)
+
+#ifdef QT3_SUPPORT
+public:
+ QT3_SUPPORT void expand(int rows, int cols);
+ inline QT3_SUPPORT void addRowSpacing(int row, int minsize) { addItem(new QSpacerItem(0,minsize), row, 0); }
+ inline QT3_SUPPORT void addColSpacing(int col, int minsize) { addItem(new QSpacerItem(minsize,0), 0, col); }
+ inline QT3_SUPPORT void addMultiCellWidget(QWidget *w, int fromRow, int toRow, int fromCol, int toCol, Qt::Alignment _align = 0)
+ { addWidget(w, fromRow, fromCol, (toRow < 0) ? -1 : toRow - fromRow + 1, (toCol < 0) ? -1 : toCol - fromCol + 1, _align); }
+ inline QT3_SUPPORT void addMultiCell(QLayoutItem *l, int fromRow, int toRow, int fromCol, int toCol, Qt::Alignment _align = 0)
+ { addItem(l, fromRow, fromCol, (toRow < 0) ? -1 : toRow - fromRow + 1, (toCol < 0) ? -1 : toCol - fromCol + 1, _align); }
+ inline QT3_SUPPORT void addMultiCellLayout(QLayout *layout, int fromRow, int toRow, int fromCol, int toCol, Qt::Alignment _align = 0)
+ { addLayout(layout, fromRow, fromCol, (toRow < 0) ? -1 : toRow - fromRow + 1, (toCol < 0) ? -1 : toCol - fromCol + 1, _align); }
+
+ inline QT3_SUPPORT int numRows() const { return rowCount(); }
+ inline QT3_SUPPORT int numCols() const { return columnCount(); }
+ inline QT3_SUPPORT void setColStretch(int col, int stretch) {setColumnStretch(col, stretch); }
+ inline QT3_SUPPORT int colStretch(int col) const {return columnStretch(col); }
+ inline QT3_SUPPORT void setColSpacing(int col, int minSize) { setColumnMinimumWidth(col, minSize); }
+ inline QT3_SUPPORT int colSpacing(int col) const { return columnMinimumWidth(col); }
+ inline QT3_SUPPORT void setRowSpacing(int row, int minSize) {setRowMinimumHeight(row, minSize); }
+ inline QT3_SUPPORT int rowSpacing(int row) const {return rowMinimumHeight(row); }
+#endif
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QGRIDLAYOUT_H
diff --git a/src/gui/kernel/qguieventdispatcher_glib.cpp b/src/widgets/kernel/qguieventdispatcher_glib.cpp
index 6f9bb8f80d..6f9bb8f80d 100644
--- a/src/gui/kernel/qguieventdispatcher_glib.cpp
+++ b/src/widgets/kernel/qguieventdispatcher_glib.cpp
diff --git a/src/gui/kernel/qguieventdispatcher_glib_p.h b/src/widgets/kernel/qguieventdispatcher_glib_p.h
index ff210b5ca4..ff210b5ca4 100644
--- a/src/gui/kernel/qguieventdispatcher_glib_p.h
+++ b/src/widgets/kernel/qguieventdispatcher_glib_p.h
diff --git a/src/gui/kernel/qguiplatformplugin.cpp b/src/widgets/kernel/qguiplatformplugin.cpp
index 708859d811..708859d811 100644
--- a/src/gui/kernel/qguiplatformplugin.cpp
+++ b/src/widgets/kernel/qguiplatformplugin.cpp
diff --git a/src/widgets/kernel/qguiplatformplugin_p.h b/src/widgets/kernel/qguiplatformplugin_p.h
new file mode 100644
index 0000000000..3fae6a5cbe
--- /dev/null
+++ b/src/widgets/kernel/qguiplatformplugin_p.h
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGUIPLATFORM_P_H
+#define QGUIPLATFORM_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qplugin.h>
+#include <QtCore/qfactoryinterface.h>
+#include <QtWidgets/qdialog.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QStyle;
+class QPalette;
+class QIcon;
+class QFileDialog;
+class QColorDialog;
+class QFileInfo;
+
+struct Q_WIDGETS_EXPORT QGuiPlatformPluginInterface : public QFactoryInterface
+{
+};
+
+#define QGuiPlatformPluginInterface_iid "com.nokia.qt.QGuiPlatformPluginInterface"
+
+Q_DECLARE_INTERFACE(QGuiPlatformPluginInterface, QGuiPlatformPluginInterface_iid)
+
+class Q_WIDGETS_EXPORT QGuiPlatformPlugin : public QObject, public QGuiPlatformPluginInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QGuiPlatformPluginInterface:QFactoryInterface)
+ public:
+ explicit QGuiPlatformPlugin(QObject *parent = 0);
+ ~QGuiPlatformPlugin();
+
+ virtual QStringList keys() const { return QStringList() << QLatin1String("default"); };
+
+ virtual QString styleName();
+ virtual QPalette palette();
+ virtual QString systemIconThemeName();
+ virtual QStringList iconThemeSearchPaths();
+ virtual QIcon fileSystemIcon(const QFileInfo &);
+
+ enum PlatformHint { PH_ToolButtonStyle, PH_ToolBarIconSize, PH_ItemView_ActivateItemOnSingleClick };
+ virtual int platformHint(PlatformHint hint);
+
+
+ virtual void fileDialogDelete(QFileDialog *) {}
+ virtual bool fileDialogSetVisible(QFileDialog *, bool) { return false; }
+ virtual QDialog::DialogCode fileDialogResultCode(QFileDialog *) { return QDialog::Rejected; }
+ virtual void fileDialogSetDirectory(QFileDialog *, const QString &) {}
+ virtual QString fileDialogDirectory(const QFileDialog *) const { return QString(); }
+ virtual void fileDialogSelectFile(QFileDialog *, const QString &) {}
+ virtual QStringList fileDialogSelectedFiles(const QFileDialog *) const { return QStringList(); }
+ virtual void fileDialogSetFilter(QFileDialog *) {}
+ virtual void fileDialogSetNameFilters(QFileDialog *, const QStringList &) {}
+ virtual void fileDialogSelectNameFilter(QFileDialog *, const QString &) {}
+ virtual QString fileDialogSelectedNameFilter(const QFileDialog *) const { return QString(); }
+
+ virtual void colorDialogDelete(QColorDialog *) {}
+ virtual bool colorDialogSetVisible(QColorDialog *, bool) { return false; }
+ virtual void colorDialogSetCurrentColor(QColorDialog *, const QColor &) {}
+};
+
+//internal
+QGuiPlatformPlugin *qt_guiPlatformPlugin();
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif // QGUIPLATFORMPLUGIN_H
diff --git a/src/widgets/kernel/qicon.cpp b/src/widgets/kernel/qicon.cpp
new file mode 100644
index 0000000000..ec8740b7ef
--- /dev/null
+++ b/src/widgets/kernel/qicon.cpp
@@ -0,0 +1,1165 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qicon.h"
+#include "qicon_p.h"
+#include "qiconengine.h"
+#include "qiconengineplugin.h"
+#include "private/qfactoryloader_p.h"
+#include "private/qiconloader_p.h"
+#include "qstyleoption.h"
+#include "qpainter.h"
+#include "qfileinfo.h"
+#include "qstyle.h"
+#include "qpixmapcache.h"
+#include "qvariant.h"
+#include "qcache.h"
+#include "qdebug.h"
+#include "private/qguiplatformplugin_p.h"
+#include "qguiapplication.h"
+
+#ifdef Q_WS_MAC
+#include <private/qt_mac_p.h>
+#include <private/qt_cocoa_helpers_mac_p.h>
+#endif
+
+#ifdef Q_WS_X11
+#include "private/qt_x11_p.h"
+#include "private/qkde_p.h"
+#endif
+
+#include "private/qhexstring_p.h"
+
+#ifndef QT_NO_ICON
+QT_BEGIN_NAMESPACE
+
+/*!
+ \enum QIcon::Mode
+
+ This enum type describes the mode for which a pixmap is intended
+ to be used. The currently defined modes are:
+
+ \value Normal
+ Display the pixmap when the user is
+ not interacting with the icon, but the
+ functionality represented by the icon is available.
+ \value Disabled
+ Display the pixmap when the
+ functionality represented by the icon is not available.
+ \value Active
+ Display the pixmap when the
+ functionality represented by the icon is available and
+ the user is interacting with the icon, for example, moving the
+ mouse over it or clicking it.
+ \value Selected
+ Display the pixmap when the item represented by the icon is
+ selected.
+*/
+
+/*!
+ \enum QIcon::State
+
+ This enum describes the state for which a pixmap is intended to be
+ used. The \e state can be:
+
+ \value Off Display the pixmap when the widget is in an "off" state
+ \value On Display the pixmap when the widget is in an "on" state
+*/
+
+static QBasicAtomicInt serialNumCounter = Q_BASIC_ATOMIC_INITIALIZER(1);
+
+static void qt_cleanup_icon_cache();
+typedef QCache<QString, QIcon> IconCache;
+Q_GLOBAL_STATIC_WITH_INITIALIZER(IconCache, qtIconCache, qAddPostRoutine(qt_cleanup_icon_cache))
+
+static void qt_cleanup_icon_cache()
+{
+ qtIconCache()->clear();
+}
+
+QIconPrivate::QIconPrivate()
+ : engine(0), ref(1),
+ serialNum(serialNumCounter.fetchAndAddRelaxed(1)),
+ detach_no(0),
+ engine_version(2),
+ v1RefCount(0)
+{
+}
+
+QPixmapIconEngine::QPixmapIconEngine()
+{
+}
+
+QPixmapIconEngine::QPixmapIconEngine(const QPixmapIconEngine &other)
+ : QIconEngineV2(other), pixmaps(other.pixmaps)
+{
+}
+
+QPixmapIconEngine::~QPixmapIconEngine()
+{
+}
+
+void QPixmapIconEngine::paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state)
+{
+ QSize pixmapSize = rect.size();
+#if defined(Q_WS_MAC)
+ pixmapSize *= qt_mac_get_scalefactor();
+#endif
+ painter->drawPixmap(rect, pixmap(pixmapSize, mode, state));
+}
+
+static inline int area(const QSize &s) { return s.width() * s.height(); }
+
+// returns the smallest of the two that is still larger than or equal to size.
+static QPixmapIconEngineEntry *bestSizeMatch( const QSize &size, QPixmapIconEngineEntry *pa, QPixmapIconEngineEntry *pb)
+{
+ int s = area(size);
+ if (pa->size == QSize() && pa->pixmap.isNull()) {
+ pa->pixmap = QPixmap(pa->fileName);
+ pa->size = pa->pixmap.size();
+ }
+ int a = area(pa->size);
+ if (pb->size == QSize() && pb->pixmap.isNull()) {
+ pb->pixmap = QPixmap(pb->fileName);
+ pb->size = pb->pixmap.size();
+ }
+ int b = area(pb->size);
+ int res = a;
+ if (qMin(a,b) >= s)
+ res = qMin(a,b);
+ else
+ res = qMax(a,b);
+ if (res == a)
+ return pa;
+ return pb;
+}
+
+QPixmapIconEngineEntry *QPixmapIconEngine::tryMatch(const QSize &size, QIcon::Mode mode, QIcon::State state)
+{
+ QPixmapIconEngineEntry *pe = 0;
+ for (int i = 0; i < pixmaps.count(); ++i)
+ if (pixmaps.at(i).mode == mode && pixmaps.at(i).state == state) {
+ if (pe)
+ pe = bestSizeMatch(size, &pixmaps[i], pe);
+ else
+ pe = &pixmaps[i];
+ }
+ return pe;
+}
+
+
+QPixmapIconEngineEntry *QPixmapIconEngine::bestMatch(const QSize &size, QIcon::Mode mode, QIcon::State state, bool sizeOnly)
+{
+ QPixmapIconEngineEntry *pe = tryMatch(size, mode, state);
+ while (!pe){
+ QIcon::State oppositeState = (state == QIcon::On) ? QIcon::Off : QIcon::On;
+ if (mode == QIcon::Disabled || mode == QIcon::Selected) {
+ QIcon::Mode oppositeMode = (mode == QIcon::Disabled) ? QIcon::Selected : QIcon::Disabled;
+ if ((pe = tryMatch(size, QIcon::Normal, state)))
+ break;
+ if ((pe = tryMatch(size, QIcon::Active, state)))
+ break;
+ if ((pe = tryMatch(size, mode, oppositeState)))
+ break;
+ if ((pe = tryMatch(size, QIcon::Normal, oppositeState)))
+ break;
+ if ((pe = tryMatch(size, QIcon::Active, oppositeState)))
+ break;
+ if ((pe = tryMatch(size, oppositeMode, state)))
+ break;
+ if ((pe = tryMatch(size, oppositeMode, oppositeState)))
+ break;
+ } else {
+ QIcon::Mode oppositeMode = (mode == QIcon::Normal) ? QIcon::Active : QIcon::Normal;
+ if ((pe = tryMatch(size, oppositeMode, state)))
+ break;
+ if ((pe = tryMatch(size, mode, oppositeState)))
+ break;
+ if ((pe = tryMatch(size, oppositeMode, oppositeState)))
+ break;
+ if ((pe = tryMatch(size, QIcon::Disabled, state)))
+ break;
+ if ((pe = tryMatch(size, QIcon::Selected, state)))
+ break;
+ if ((pe = tryMatch(size, QIcon::Disabled, oppositeState)))
+ break;
+ if ((pe = tryMatch(size, QIcon::Selected, oppositeState)))
+ break;
+ }
+
+ if (!pe)
+ return pe;
+ }
+
+ if (sizeOnly ? (pe->size.isNull() || !pe->size.isValid()) : pe->pixmap.isNull()) {
+ pe->pixmap = QPixmap(pe->fileName);
+ if (!pe->pixmap.isNull())
+ pe->size = pe->pixmap.size();
+ }
+
+ return pe;
+}
+
+QPixmap QPixmapIconEngine::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state)
+{
+ QPixmap pm;
+ QPixmapIconEngineEntry *pe = bestMatch(size, mode, state, false);
+ if (pe)
+ pm = pe->pixmap;
+
+ if (pm.isNull()) {
+ int idx = pixmaps.count();
+ while (--idx >= 0) {
+ if (pe == &pixmaps[idx]) {
+ pixmaps.remove(idx);
+ break;
+ }
+ }
+ if (pixmaps.isEmpty())
+ return pm;
+ else
+ return pixmap(size, mode, state);
+ }
+
+ QSize actualSize = pm.size();
+ if (!actualSize.isNull() && (actualSize.width() > size.width() || actualSize.height() > size.height()))
+ actualSize.scale(size, Qt::KeepAspectRatio);
+
+ // #### Qt5 no idea what this really does, but we need to remove the QApp and style references
+// QString key = QLatin1Literal("qt_")
+// % HexString<quint64>(pm.cacheKey())
+// % HexString<uint>(pe->mode)
+// % HexString<quint64>(QApplication::palette().cacheKey())
+// % HexString<uint>(actualSize.width())
+// % HexString<uint>(actualSize.height());
+
+// if (mode == QIcon::Active) {
+// if (QPixmapCache::find(key % HexString<uint>(mode), pm))
+// return pm; // horray
+// if (QPixmapCache::find(key % HexString<uint>(QIcon::Normal), pm)) {
+// QStyleOption opt(0);
+// opt.palette = QApplication::palette();
+// QPixmap active = QApplication::style()->generatedIconPixmap(QIcon::Active, pm, &opt);
+// if (pm.cacheKey() == active.cacheKey())
+// return pm;
+// }
+// }
+
+// if (!QPixmapCache::find(key % HexString<uint>(mode), pm)) {
+ if (pm.size() != actualSize)
+ pm = pm.scaled(actualSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
+// if (pe->mode != mode && mode != QIcon::Normal) {
+// QStyleOption opt(0);
+// opt.palette = QApplication::palette();
+// QPixmap generated = QApplication::style()->generatedIconPixmap(mode, pm, &opt);
+// if (!generated.isNull())
+// pm = generated;
+// }
+// QPixmapCache::insert(key % HexString<uint>(mode), pm);
+// }
+ return pm;
+}
+
+QSize QPixmapIconEngine::actualSize(const QSize &size, QIcon::Mode mode, QIcon::State state)
+{
+ QSize actualSize;
+ if (QPixmapIconEngineEntry *pe = bestMatch(size, mode, state, true))
+ actualSize = pe->size;
+
+ if (actualSize.isNull())
+ return actualSize;
+
+ if (!actualSize.isNull() && (actualSize.width() > size.width() || actualSize.height() > size.height()))
+ actualSize.scale(size, Qt::KeepAspectRatio);
+ return actualSize;
+}
+
+void QPixmapIconEngine::addPixmap(const QPixmap &pixmap, QIcon::Mode mode, QIcon::State state)
+{
+ if (!pixmap.isNull()) {
+ QPixmapIconEngineEntry *pe = tryMatch(pixmap.size(), mode, state);
+ if(pe && pe->size == pixmap.size()) {
+ pe->pixmap = pixmap;
+ pe->fileName.clear();
+ } else {
+ pixmaps += QPixmapIconEngineEntry(pixmap, mode, state);
+ }
+ }
+}
+
+void QPixmapIconEngine::addFile(const QString &fileName, const QSize &_size, QIcon::Mode mode, QIcon::State state)
+{
+ if (!fileName.isEmpty()) {
+ QSize size = _size;
+ QPixmap pixmap;
+
+ QString abs = fileName;
+ if (fileName.at(0) != QLatin1Char(':'))
+ abs = QFileInfo(fileName).absoluteFilePath();
+
+ for (int i = 0; i < pixmaps.count(); ++i) {
+ if (pixmaps.at(i).mode == mode && pixmaps.at(i).state == state) {
+ QPixmapIconEngineEntry *pe = &pixmaps[i];
+ if(size == QSize()) {
+ pixmap = QPixmap(abs);
+ size = pixmap.size();
+ }
+ if (pe->size == QSize() && pe->pixmap.isNull()) {
+ pe->pixmap = QPixmap(pe->fileName);
+ pe->size = pe->pixmap.size();
+ }
+ if(pe->size == size) {
+ pe->pixmap = pixmap;
+ pe->fileName = abs;
+ return;
+ }
+ }
+ }
+ QPixmapIconEngineEntry e(abs, size, mode, state);
+ e.pixmap = pixmap;
+ pixmaps += e;
+ }
+}
+
+QString QPixmapIconEngine::key() const
+{
+ return QLatin1String("QPixmapIconEngine");
+}
+
+QIconEngineV2 *QPixmapIconEngine::clone() const
+{
+ return new QPixmapIconEngine(*this);
+}
+
+bool QPixmapIconEngine::read(QDataStream &in)
+{
+ int num_entries;
+ QPixmap pm;
+ QString fileName;
+ QSize sz;
+ uint mode;
+ uint state;
+
+ in >> num_entries;
+ for (int i=0; i < num_entries; ++i) {
+ if (in.atEnd()) {
+ pixmaps.clear();
+ return false;
+ }
+ in >> pm;
+ in >> fileName;
+ in >> sz;
+ in >> mode;
+ in >> state;
+ if (pm.isNull()) {
+ addFile(fileName, sz, QIcon::Mode(mode), QIcon::State(state));
+ } else {
+ QPixmapIconEngineEntry pe(fileName, sz, QIcon::Mode(mode), QIcon::State(state));
+ pe.pixmap = pm;
+ pixmaps += pe;
+ }
+ }
+ return true;
+}
+
+bool QPixmapIconEngine::write(QDataStream &out) const
+{
+ int num_entries = pixmaps.size();
+ out << num_entries;
+ for (int i=0; i < num_entries; ++i) {
+ if (pixmaps.at(i).pixmap.isNull())
+ out << QPixmap(pixmaps.at(i).fileName);
+ else
+ out << pixmaps.at(i).pixmap;
+ out << pixmaps.at(i).fileName;
+ out << pixmaps.at(i).size;
+ out << (uint) pixmaps.at(i).mode;
+ out << (uint) pixmaps.at(i).state;
+ }
+ return true;
+}
+
+void QPixmapIconEngine::virtual_hook(int id, void *data)
+{
+ switch (id) {
+ case QIconEngineV2::AvailableSizesHook: {
+ QIconEngineV2::AvailableSizesArgument &arg =
+ *reinterpret_cast<QIconEngineV2::AvailableSizesArgument*>(data);
+ arg.sizes.clear();
+ for (int i = 0; i < pixmaps.size(); ++i) {
+ QPixmapIconEngineEntry &pe = pixmaps[i];
+ if (pe.size == QSize() && pe.pixmap.isNull()) {
+ pe.pixmap = QPixmap(pe.fileName);
+ pe.size = pe.pixmap.size();
+ }
+ if (pe.mode == arg.mode && pe.state == arg.state && !pe.size.isEmpty())
+ arg.sizes.push_back(pe.size);
+ }
+ break;
+ }
+ default:
+ QIconEngineV2::virtual_hook(id, data);
+ }
+}
+
+#ifndef QT_NO_LIBRARY
+Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
+ (QIconEngineFactoryInterface_iid, QLatin1String("/iconengines"), Qt::CaseInsensitive))
+Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loaderV2,
+ (QIconEngineFactoryInterfaceV2_iid, QLatin1String("/iconengines"), Qt::CaseInsensitive))
+#endif
+
+
+
+/*!
+ \class QIcon
+
+ \brief The QIcon class provides scalable icons in different modes
+ and states.
+
+ \ingroup painting
+ \ingroup shared
+
+
+ A QIcon can generate smaller, larger, active, and disabled pixmaps
+ from the set of pixmaps it is given. Such pixmaps are used by Qt
+ widgets to show an icon representing a particular action.
+
+ The simplest use of QIcon is to create one from a QPixmap file or
+ resource, and then use it, allowing Qt to work out all the required
+ icon styles and sizes. For example:
+
+ \snippet doc/src/snippets/code/src_gui_image_qicon.cpp 0
+
+ To undo a QIcon, simply set a null icon in its place:
+
+ \snippet doc/src/snippets/code/src_gui_image_qicon.cpp 1
+
+ Use the QImageReader::supportedImageFormats() and
+ QImageWriter::supportedImageFormats() functions to retrieve a
+ complete list of the supported file formats.
+
+ When you retrieve a pixmap using pixmap(QSize, Mode, State), and no
+ pixmap for this given size, mode and state has been added with
+ addFile() or addPixmap(), then QIcon will generate one on the
+ fly. This pixmap generation happens in a QIconEngineV2. The default
+ engine scales pixmaps down if required, but never up, and it uses
+ the current style to calculate a disabled appearance. By using
+ custom icon engines, you can customize every aspect of generated
+ icons. With QIconEnginePluginV2 it is possible to register different
+ icon engines for different file suffixes, making it possible for
+ third parties to provide additional icon engines to those included
+ with Qt.
+
+ \note Since Qt 4.2, an icon engine that supports SVG is included.
+
+ \section1 Making Classes that Use QIcon
+
+ If you write your own widgets that have an option to set a small
+ pixmap, consider allowing a QIcon to be set for that pixmap. The
+ Qt class QToolButton is an example of such a widget.
+
+ Provide a method to set a QIcon, and when you draw the icon, choose
+ whichever pixmap is appropriate for the current state of your widget.
+ For example:
+ \snippet doc/src/snippets/code/src_gui_image_qicon.cpp 2
+
+ You might also make use of the \c Active mode, perhaps making your
+ widget \c Active when the mouse is over the widget (see \l
+ QWidget::enterEvent()), while the mouse is pressed pending the
+ release that will activate the function, or when it is the currently
+ selected item. If the widget can be toggled, the "On" mode might be
+ used to draw a different icon.
+
+ \img icon.png QIcon
+
+ \sa {fowler}{GUI Design Handbook: Iconic Label}, {Icons Example}
+*/
+
+
+/*!
+ Constructs a null icon.
+*/
+QIcon::QIcon()
+ : d(0)
+{
+}
+
+/*!
+ Constructs an icon from a \a pixmap.
+ */
+QIcon::QIcon(const QPixmap &pixmap)
+ :d(0)
+{
+ addPixmap(pixmap);
+}
+
+/*!
+ Constructs a copy of \a other. This is very fast.
+*/
+QIcon::QIcon(const QIcon &other)
+ :d(other.d)
+{
+ if (d)
+ d->ref.ref();
+}
+
+/*!
+ Constructs an icon from the file with the given \a fileName. The
+ file will be loaded on demand.
+
+ If \a fileName contains a relative path (e.g. the filename only)
+ the relevant file must be found relative to the runtime working
+ directory.
+
+ The file name can be either refer to an actual file on disk or to
+ one of the application's embedded resources. See the
+ \l{resources.html}{Resource System} overview for details on how to
+ embed images and other resource files in the application's
+ executable.
+
+ Use the QImageReader::supportedImageFormats() and
+ QImageWriter::supportedImageFormats() functions to retrieve a
+ complete list of the supported file formats.
+*/
+QIcon::QIcon(const QString &fileName)
+ : d(0)
+{
+ addFile(fileName);
+}
+
+
+/*!
+ Creates an icon with a specific icon \a engine. The icon takes
+ ownership of the engine.
+*/
+QIcon::QIcon(QIconEngine *engine)
+ :d(new QIconPrivate)
+{
+ d->engine_version = 1;
+ d->engine = engine;
+ d->v1RefCount = new QAtomicInt(1);
+}
+
+/*!
+ Creates an icon with a specific icon \a engine. The icon takes
+ ownership of the engine.
+*/
+QIcon::QIcon(QIconEngineV2 *engine)
+ :d(new QIconPrivate)
+{
+ d->engine_version = 2;
+ d->engine = engine;
+}
+
+/*!
+ Destroys the icon.
+*/
+QIcon::~QIcon()
+{
+ if (d && !d->ref.deref())
+ delete d;
+}
+
+/*!
+ Assigns the \a other icon to this icon and returns a reference to
+ this icon.
+*/
+QIcon &QIcon::operator=(const QIcon &other)
+{
+ if (other.d)
+ other.d->ref.ref();
+ if (d && !d->ref.deref())
+ delete d;
+ d = other.d;
+ return *this;
+}
+
+/*!
+ \fn void QIcon::swap(QIcon &other)
+ \since 4.8
+
+ Swaps icon \a other with this icon. This operation is very
+ fast and never fails.
+*/
+
+/*!
+ Returns the icon as a QVariant.
+*/
+QIcon::operator QVariant() const
+{
+ return QVariant(QVariant::Icon, this);
+}
+
+/*! \obsolete
+
+ Returns a number that identifies the contents of this
+ QIcon object. Distinct QIcon objects can have
+ the same serial number if they refer to the same contents
+ (but they don't have to). Also, the serial number of
+ a QIcon object may change during its lifetime.
+
+ Use cacheKey() instead.
+
+ A null icon always has a serial number of 0.
+
+ Serial numbers are mostly useful in conjunction with caching.
+
+ \sa QPixmap::serialNumber()
+*/
+
+int QIcon::serialNumber() const
+{
+ return d ? d->serialNum : 0;
+}
+
+/*!
+ Returns a number that identifies the contents of this QIcon
+ object. Distinct QIcon objects can have the same key if
+ they refer to the same contents.
+ \since 4.3
+
+ The cacheKey() will change when the icon is altered via
+ addPixmap() or addFile().
+
+ Cache keys are mostly useful in conjunction with caching.
+
+ \sa QPixmap::cacheKey()
+*/
+qint64 QIcon::cacheKey() const
+{
+ if (!d)
+ return 0;
+ return (((qint64) d->serialNum) << 32) | ((qint64) (d->detach_no));
+}
+
+/*!
+ Returns a pixmap with the requested \a size, \a mode, and \a
+ state, generating one if necessary. The pixmap might be smaller than
+ requested, but never larger.
+
+ \sa actualSize(), paint()
+*/
+QPixmap QIcon::pixmap(const QSize &size, Mode mode, State state) const
+{
+ if (!d)
+ return QPixmap();
+ return d->engine->pixmap(size, mode, state);
+}
+
+/*!
+ \fn QPixmap QIcon::pixmap(int w, int h, Mode mode = Normal, State state = Off) const
+
+ \overload
+
+ Returns a pixmap of size QSize(\a w, \a h). The pixmap might be smaller than
+ requested, but never larger.
+*/
+
+/*!
+ \fn QPixmap QIcon::pixmap(int extent, Mode mode = Normal, State state = Off) const
+
+ \overload
+
+ Returns a pixmap of size QSize(\a extent, \a extent). The pixmap might be smaller
+ than requested, but never larger.
+*/
+
+/*! Returns the actual size of the icon for the requested \a size, \a
+ mode, and \a state. The result might be smaller than requested, but
+ never larger.
+
+ \sa pixmap(), paint()
+*/
+QSize QIcon::actualSize(const QSize &size, Mode mode, State state) const
+{
+ if (!d)
+ return QSize();
+ return d->engine->actualSize(size, mode, state);
+}
+
+
+/*!
+ Uses the \a painter to paint the icon with specified \a alignment,
+ required \a mode, and \a state into the rectangle \a rect.
+
+ \sa actualSize(), pixmap()
+*/
+void QIcon::paint(QPainter *painter, const QRect &rect, Qt::Alignment alignment, Mode mode, State state) const
+{
+ if (!d || !painter)
+ return;
+ QRect alignedRect = QStyle::alignedRect(painter->layoutDirection(), alignment, d->engine->actualSize(rect.size(), mode, state), rect);
+ d->engine->paint(painter, alignedRect, mode, state);
+}
+
+/*!
+ \fn void QIcon::paint(QPainter *painter, int x, int y, int w, int h, Qt::Alignment alignment,
+ Mode mode, State state) const
+
+ \overload
+
+ Paints the icon into the rectangle QRect(\a x, \a y, \a w, \a h).
+*/
+
+/*!
+ Returns true if the icon is empty; otherwise returns false.
+
+ An icon is empty if it has neither a pixmap nor a filename.
+
+ Note: Even a non-null icon might not be able to create valid
+ pixmaps, eg. if the file does not exist or cannot be read.
+*/
+bool QIcon::isNull() const
+{
+ return !d;
+}
+
+/*!\internal
+ */
+bool QIcon::isDetached() const
+{
+ return !d || d->ref == 1;
+}
+
+/*! \internal
+ */
+void QIcon::detach()
+{
+ if (d) {
+ if (d->ref != 1) {
+ QIconPrivate *x = new QIconPrivate;
+ if (d->engine_version > 1) {
+ QIconEngineV2 *engine = static_cast<QIconEngineV2 *>(d->engine);
+ x->engine = engine->clone();
+ } else {
+ x->engine = d->engine;
+ x->v1RefCount = d->v1RefCount;
+ x->v1RefCount->ref();
+ }
+ x->engine_version = d->engine_version;
+ if (!d->ref.deref())
+ delete d;
+ d = x;
+ }
+ ++d->detach_no;
+ }
+}
+
+/*!
+ Adds \a pixmap to the icon, as a specialization for \a mode and
+ \a state.
+
+ Custom icon engines are free to ignore additionally added
+ pixmaps.
+
+ \sa addFile()
+*/
+void QIcon::addPixmap(const QPixmap &pixmap, Mode mode, State state)
+{
+ if (pixmap.isNull())
+ return;
+ if (!d) {
+ d = new QIconPrivate;
+ d->engine = new QPixmapIconEngine;
+ } else {
+ detach();
+ }
+ d->engine->addPixmap(pixmap, mode, state);
+}
+
+
+/*! Adds an image from the file with the given \a fileName to the
+ icon, as a specialization for \a size, \a mode and \a state. The
+ file will be loaded on demand. Note: custom icon engines are free
+ to ignore additionally added pixmaps.
+
+ If \a fileName contains a relative path (e.g. the filename only)
+ the relevant file must be found relative to the runtime working
+ directory.
+
+ The file name can be either refer to an actual file on disk or to
+ one of the application's embedded resources. See the
+ \l{resources.html}{Resource System} overview for details on how to
+ embed images and other resource files in the application's
+ executable.
+
+ Use the QImageReader::supportedImageFormats() and
+ QImageWriter::supportedImageFormats() functions to retrieve a
+ complete list of the supported file formats.
+
+ Note: When you add a non-empty filename to a QIcon, the icon becomes
+ non-null, even if the file doesn't exist or points to a corrupt file.
+
+ \sa addPixmap()
+ */
+void QIcon::addFile(const QString &fileName, const QSize &size, Mode mode, State state)
+{
+ if (fileName.isEmpty())
+ return;
+ if (!d) {
+#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+ QFileInfo info(fileName);
+ QString suffix = info.suffix();
+ if (!suffix.isEmpty()) {
+ // first try version 2 engines..
+ if (QIconEngineFactoryInterfaceV2 *factory = qobject_cast<QIconEngineFactoryInterfaceV2*>(loaderV2()->instance(suffix))) {
+ if (QIconEngine *engine = factory->create(fileName)) {
+ d = new QIconPrivate;
+ d->engine = engine;
+ }
+ }
+ // ..then fall back and try to load version 1 engines
+ if (!d) {
+ if (QIconEngineFactoryInterface *factory = qobject_cast<QIconEngineFactoryInterface*>(loader()->instance(suffix))) {
+ if (QIconEngine *engine = factory->create(fileName)) {
+ d = new QIconPrivate;
+ d->engine = engine;
+ d->engine_version = 1;
+ d->v1RefCount = new QAtomicInt(1);
+ }
+ }
+ }
+ }
+#endif
+ // ...then fall back to the default engine
+ if (!d) {
+ d = new QIconPrivate;
+ d->engine = new QPixmapIconEngine;
+ }
+ } else {
+ detach();
+ }
+ d->engine->addFile(fileName, size, mode, state);
+}
+
+/*!
+ \since 4.5
+
+ Returns a list of available icon sizes for the specified \a mode and
+ \a state.
+*/
+QList<QSize> QIcon::availableSizes(Mode mode, State state) const
+{
+ if (!d || !d->engine || d->engine_version < 2)
+ return QList<QSize>();
+ QIconEngineV2 *engine = static_cast<QIconEngineV2*>(d->engine);
+ return engine->availableSizes(mode, state);
+}
+
+/*!
+ \since 4.7
+
+ Returns the name used to create the icon, if available.
+
+ Depending on the way the icon was created, it may have an associated
+ name. This is the case for icons created with fromTheme() or icons
+ using a QIconEngine which supports the QIconEngineV2::IconNameHook.
+
+ \sa fromTheme(), QIconEngine
+*/
+QString QIcon::name() const
+{
+ if (!d || !d->engine || d->engine_version < 2)
+ return QString();
+ QIconEngineV2 *engine = static_cast<QIconEngineV2*>(d->engine);
+ return engine->iconName();
+}
+
+/*!
+ \since 4.6
+
+ Sets the search paths for icon themes to \a paths.
+ \sa themeSearchPaths(), fromTheme(), setThemeName()
+*/
+void QIcon::setThemeSearchPaths(const QStringList &paths)
+{
+ QIconLoader::instance()->setThemeSearchPath(paths);
+}
+
+/*!
+ \since 4.6
+
+ Returns the search paths for icon themes.
+
+ The default value will depend on the platform:
+
+ On X11, the search path will use the XDG_DATA_DIRS environment
+ variable if available.
+
+ By default all platforms will have the resource directory
+ \c{:\icons} as a fallback. You can use "rcc -project" to generate a
+ resource file from your icon theme.
+
+ \sa setThemeSearchPaths(), fromTheme(), setThemeName()
+*/
+QStringList QIcon::themeSearchPaths()
+{
+ return QIconLoader::instance()->themeSearchPaths();
+}
+
+/*!
+ \since 4.6
+
+ Sets the current icon theme to \a name.
+
+ The \a name should correspond to a directory name in the
+ themeSearchPath() containing an index.theme
+ file describing it's contents.
+
+ \sa themeSearchPaths(), themeName()
+*/
+void QIcon::setThemeName(const QString &name)
+{
+ QIconLoader::instance()->setThemeName(name);
+}
+
+/*!
+ \since 4.6
+
+ Returns the name of the current icon theme.
+
+ On X11, the current icon theme depends on your desktop
+ settings. On other platforms it is not set by default.
+
+ \sa setThemeName(), themeSearchPaths(), fromTheme(),
+ hasThemeIcon()
+*/
+QString QIcon::themeName()
+{
+ return QIconLoader::instance()->themeName();
+}
+
+/*!
+ \since 4.6
+
+ Returns the QIcon corresponding to \a name in the current
+ icon theme. If no such icon is found in the current theme
+ \a fallback is returned instead.
+
+ The latest version of the freedesktop icon specification and naming
+ specification can be obtained here:
+
+ \list
+ \o \l{http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html}
+ \o \l{http://standards.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html}
+ \endlist
+
+ To fetch an icon from the current icon theme:
+
+ \snippet doc/src/snippets/code/src_gui_image_qicon.cpp 3
+
+ Or if you want to provide a guaranteed fallback for platforms that
+ do not support theme icons, you can use the second argument:
+
+ \snippet doc/src/snippets/code/src_gui_image_qicon.cpp 4
+
+ \note By default, only X11 will support themed icons. In order to
+ use themed icons on Mac and Windows, you will have to bundle a
+ compliant theme in one of your themeSearchPaths() and set the
+ appropriate themeName().
+
+ \sa themeName(), setThemeName(), themeSearchPaths()
+*/
+QIcon QIcon::fromTheme(const QString &name, const QIcon &fallback)
+{
+ QIcon icon;
+
+ if (qtIconCache()->contains(name)) {
+ icon = *qtIconCache()->object(name);
+ } else {
+ QIcon *cachedIcon = new QIcon(new QIconLoaderEngine(name));
+ qtIconCache()->insert(name, cachedIcon);
+ icon = *cachedIcon;
+ }
+
+ // Note the qapp check is to allow lazy loading of static icons
+ // Supporting fallbacks will not work for this case.
+ if (qApp && icon.availableSizes().isEmpty())
+ return fallback;
+
+ return icon;
+}
+
+/*!
+ \since 4.6
+
+ Returns true if there is an icon available for \a name in the
+ current icon theme, otherwise returns false.
+
+ \sa themeSearchPaths(), fromTheme(), setThemeName()
+*/
+bool QIcon::hasThemeIcon(const QString &name)
+{
+ QIcon icon = fromTheme(name);
+
+ return !icon.isNull();
+}
+
+
+/*****************************************************************************
+ QIcon stream functions
+ *****************************************************************************/
+#if !defined(QT_NO_DATASTREAM)
+/*!
+ \fn QDataStream &operator<<(QDataStream &stream, const QIcon &icon)
+ \relates QIcon
+ \since 4.2
+
+ Writes the given \a icon to the given \a stream as a PNG
+ image. If the icon contains more than one image, all images will
+ be written to the stream. Note that writing the stream to a file
+ will not produce a valid image file.
+*/
+
+QDataStream &operator<<(QDataStream &s, const QIcon &icon)
+{
+ if (s.version() >= QDataStream::Qt_4_3) {
+ if (icon.isNull()) {
+ s << QString();
+ } else {
+ if (icon.d->engine_version > 1) {
+ QIconEngineV2 *engine = static_cast<QIconEngineV2 *>(icon.d->engine);
+ s << engine->key();
+ engine->write(s);
+ } else {
+ // not really supported
+ qWarning("QIcon: Cannot stream QIconEngine. Use QIconEngineV2 instead.");
+ }
+ }
+ } else if (s.version() == QDataStream::Qt_4_2) {
+ if (icon.isNull()) {
+ s << 0;
+ } else {
+ QPixmapIconEngine *engine = static_cast<QPixmapIconEngine *>(icon.d->engine);
+ int num_entries = engine->pixmaps.size();
+ s << num_entries;
+ for (int i=0; i < num_entries; ++i) {
+ s << engine->pixmaps.at(i).pixmap;
+ s << engine->pixmaps.at(i).fileName;
+ s << engine->pixmaps.at(i).size;
+ s << (uint) engine->pixmaps.at(i).mode;
+ s << (uint) engine->pixmaps.at(i).state;
+ }
+ }
+ } else {
+ s << QPixmap(icon.pixmap(22,22));
+ }
+ return s;
+}
+
+/*!
+ \fn QDataStream &operator>>(QDataStream &stream, QIcon &icon)
+ \relates QIcon
+ \since 4.2
+
+ Reads an image, or a set of images, from the given \a stream into
+ the given \a icon.
+*/
+
+QDataStream &operator>>(QDataStream &s, QIcon &icon)
+{
+ if (s.version() >= QDataStream::Qt_4_3) {
+ icon = QIcon();
+ QString key;
+ s >> key;
+ if (key == QLatin1String("QPixmapIconEngine")) {
+ icon.d = new QIconPrivate;
+ QIconEngineV2 *engine = new QPixmapIconEngine;
+ icon.d->engine = engine;
+ engine->read(s);
+ } else if (key == QLatin1String("QIconLoaderEngine")) {
+ icon.d = new QIconPrivate;
+ QIconEngineV2 *engine = new QIconLoaderEngine();
+ icon.d->engine = engine;
+ engine->read(s);
+#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+ } else if (QIconEngineFactoryInterfaceV2 *factory = qobject_cast<QIconEngineFactoryInterfaceV2*>(loaderV2()->instance(key))) {
+ if (QIconEngineV2 *engine= factory->create()) {
+ icon.d = new QIconPrivate;
+ icon.d->engine = engine;
+ engine->read(s);
+ }
+#endif
+ }
+ } else if (s.version() == QDataStream::Qt_4_2) {
+ icon = QIcon();
+ int num_entries;
+ QPixmap pm;
+ QString fileName;
+ QSize sz;
+ uint mode;
+ uint state;
+
+ s >> num_entries;
+ for (int i=0; i < num_entries; ++i) {
+ s >> pm;
+ s >> fileName;
+ s >> sz;
+ s >> mode;
+ s >> state;
+ if (pm.isNull())
+ icon.addFile(fileName, sz, QIcon::Mode(mode), QIcon::State(state));
+ else
+ icon.addPixmap(pm, QIcon::Mode(mode), QIcon::State(state));
+ }
+ } else {
+ QPixmap pm;
+ s >> pm;
+ icon.addPixmap(pm);
+ }
+ return s;
+}
+
+#endif //QT_NO_DATASTREAM
+
+/*!
+ \fn DataPtr &QIcon::data_ptr()
+ \internal
+*/
+
+/*!
+ \typedef QIcon::DataPtr
+ \internal
+*/
+
+QT_END_NAMESPACE
+#endif //QT_NO_ICON
diff --git a/src/widgets/kernel/qicon.h b/src/widgets/kernel/qicon.h
new file mode 100644
index 0000000000..3c527eb974
--- /dev/null
+++ b/src/widgets/kernel/qicon.h
@@ -0,0 +1,143 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QICON_H
+#define QICON_H
+
+#include <QtCore/qglobal.h>
+#include <QtCore/qsize.h>
+#include <QtCore/qlist.h>
+#include <QtGui/qpixmap.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QIconPrivate;
+class QIconEngine;
+class QIconEngineV2;
+
+class Q_WIDGETS_EXPORT QIcon
+{
+public:
+ enum Mode { Normal, Disabled, Active, Selected };
+ enum State { On, Off };
+
+ QIcon();
+ QIcon(const QPixmap &pixmap);
+ QIcon(const QIcon &other);
+ explicit QIcon(const QString &fileName); // file or resource name
+ explicit QIcon(QIconEngine *engine);
+ explicit QIcon(QIconEngineV2 *engine);
+ ~QIcon();
+ QIcon &operator=(const QIcon &other);
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QIcon &operator=(QIcon &&other)
+ { qSwap(d, other.d); return *this; }
+#endif
+ inline void swap(QIcon &other) { qSwap(d, other.d); }
+
+ operator QVariant() const;
+
+ QPixmap pixmap(const QSize &size, Mode mode = Normal, State state = Off) const;
+ inline QPixmap pixmap(int w, int h, Mode mode = Normal, State state = Off) const
+ { return pixmap(QSize(w, h), mode, state); }
+ inline QPixmap pixmap(int extent, Mode mode = Normal, State state = Off) const
+ { return pixmap(QSize(extent, extent), mode, state); }
+
+ QSize actualSize(const QSize &size, Mode mode = Normal, State state = Off) const;
+
+ QString name() const;
+
+ void paint(QPainter *painter, const QRect &rect, Qt::Alignment alignment = Qt::AlignCenter, Mode mode = Normal, State state = Off) const;
+ inline void paint(QPainter *painter, int x, int y, int w, int h, Qt::Alignment alignment = Qt::AlignCenter, Mode mode = Normal, State state = Off) const
+ { paint(painter, QRect(x, y, w, h), alignment, mode, state); }
+
+ bool isNull() const;
+ bool isDetached() const;
+ void detach();
+
+ int serialNumber() const;
+ qint64 cacheKey() const;
+
+ void addPixmap(const QPixmap &pixmap, Mode mode = Normal, State state = Off);
+ void addFile(const QString &fileName, const QSize &size = QSize(), Mode mode = Normal, State state = Off);
+
+ QList<QSize> availableSizes(Mode mode = Normal, State state = Off) const;
+
+ static QIcon fromTheme(const QString &name, const QIcon &fallback = QIcon());
+ static bool hasThemeIcon(const QString &name);
+
+ static QStringList themeSearchPaths();
+ static void setThemeSearchPaths(const QStringList &searchpath);
+
+ static QString themeName();
+ static void setThemeName(const QString &path);
+
+ Q_DUMMY_COMPARISON_OPERATOR(QIcon)
+
+private:
+ QIconPrivate *d;
+#if !defined(QT_NO_DATASTREAM)
+ friend Q_WIDGETS_EXPORT QDataStream &operator<<(QDataStream &, const QIcon &);
+ friend Q_WIDGETS_EXPORT QDataStream &operator>>(QDataStream &, QIcon &);
+#endif
+
+public:
+ typedef QIconPrivate * DataPtr;
+ inline DataPtr &data_ptr() { return d; }
+};
+
+Q_DECLARE_SHARED(QIcon)
+Q_DECLARE_TYPEINFO(QIcon, Q_MOVABLE_TYPE);
+
+#if !defined(QT_NO_DATASTREAM)
+Q_WIDGETS_EXPORT QDataStream &operator<<(QDataStream &, const QIcon &);
+Q_WIDGETS_EXPORT QDataStream &operator>>(QDataStream &, QIcon &);
+#endif
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QICON_H
diff --git a/src/widgets/kernel/qicon_p.h b/src/widgets/kernel/qicon_p.h
new file mode 100644
index 0000000000..7ba471b002
--- /dev/null
+++ b/src/widgets/kernel/qicon_p.h
@@ -0,0 +1,139 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QICON_P_H
+#define QICON_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qglobal.h>
+#include <QtCore/qsize.h>
+#include <QtCore/qlist.h>
+#include <QtGui/qpixmap.h>
+#include <QtWidgets/qicon.h>
+#include <QtWidgets/qiconengine.h>
+
+#ifndef QT_NO_ICON
+QT_BEGIN_NAMESPACE
+
+class QIconPrivate
+{
+public:
+ QIconPrivate();
+
+ ~QIconPrivate() {
+ if (engine_version == 1) {
+ if (!v1RefCount->deref()) {
+ delete engine;
+ delete v1RefCount;
+ }
+ } else if (engine_version == 2) {
+ delete engine;
+ }
+ }
+
+ QIconEngine *engine;
+
+ QAtomicInt ref;
+ int serialNum;
+ int detach_no;
+ int engine_version;
+
+ QAtomicInt *v1RefCount;
+};
+
+
+struct QPixmapIconEngineEntry
+{
+ QPixmapIconEngineEntry():mode(QIcon::Normal), state(QIcon::Off){}
+ QPixmapIconEngineEntry(const QPixmap &pm, QIcon::Mode m = QIcon::Normal, QIcon::State s = QIcon::Off)
+ :pixmap(pm), size(pm.size()), mode(m), state(s){}
+ QPixmapIconEngineEntry(const QString &file, const QSize &sz = QSize(), QIcon::Mode m = QIcon::Normal, QIcon::State s = QIcon::Off)
+ :fileName(file), size(sz), mode(m), state(s){}
+ QPixmap pixmap;
+ QString fileName;
+ QSize size;
+ QIcon::Mode mode;
+ QIcon::State state;
+ bool isNull() const {return (fileName.isEmpty() && pixmap.isNull()); }
+};
+
+
+
+class QPixmapIconEngine : public QIconEngineV2 {
+public:
+ QPixmapIconEngine();
+ QPixmapIconEngine(const QPixmapIconEngine &);
+ ~QPixmapIconEngine();
+ void paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state);
+ QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state);
+ QPixmapIconEngineEntry *bestMatch(const QSize &size, QIcon::Mode mode, QIcon::State state, bool sizeOnly);
+ QSize actualSize(const QSize &size, QIcon::Mode mode, QIcon::State state);
+ void addPixmap(const QPixmap &pixmap, QIcon::Mode mode, QIcon::State state);
+ void addFile(const QString &fileName, const QSize &size, QIcon::Mode mode, QIcon::State state);
+
+ // v2 functions
+ QString key() const;
+ QIconEngineV2 *clone() const;
+ bool read(QDataStream &in);
+ bool write(QDataStream &out) const;
+ void virtual_hook(int id, void *data);
+
+private:
+ QPixmapIconEngineEntry *tryMatch(const QSize &size, QIcon::Mode mode, QIcon::State state);
+ QVector<QPixmapIconEngineEntry> pixmaps;
+
+ friend QDataStream &operator<<(QDataStream &s, const QIcon &icon);
+ friend class QIconThemeEngine;
+};
+
+QT_END_NAMESPACE
+#endif //QT_NO_ICON
+#endif // QICON_P_H
diff --git a/src/gui/image/qiconengine.cpp b/src/widgets/kernel/qiconengine.cpp
index 8d71e4055a..8d71e4055a 100644
--- a/src/gui/image/qiconengine.cpp
+++ b/src/widgets/kernel/qiconengine.cpp
diff --git a/src/widgets/kernel/qiconengine.h b/src/widgets/kernel/qiconengine.h
new file mode 100644
index 0000000000..63cfcbff5e
--- /dev/null
+++ b/src/widgets/kernel/qiconengine.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QICONENGINE_H
+#define QICONENGINE_H
+
+#include <QtCore/qglobal.h>
+#include <QtCore/qlist.h>
+#include <QtWidgets/qicon.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class Q_WIDGETS_EXPORT QIconEngine
+{
+public:
+ virtual ~QIconEngine();
+ virtual void paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state) = 0;
+ virtual QSize actualSize(const QSize &size, QIcon::Mode mode, QIcon::State state);
+ virtual QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state);
+
+ virtual void addPixmap(const QPixmap &pixmap, QIcon::Mode mode, QIcon::State state);
+ virtual void addFile(const QString &fileName, const QSize &size, QIcon::Mode mode, QIcon::State state);
+
+#if 0
+ virtual int frameCount(QIcon::Mode fromMode, QIcon::State fromState, QIcon::Mode toMode, QIcon::State toState);
+ virtual void paintFrame(QPainter *painter, const QRect &rect, int frameNumber, QIcon::Mode fromMode, QIcon::State fromState, QIcon::Mode toMode, QIcon::State toState);
+#endif
+};
+
+// ### Qt 5: move the below into QIconEngine
+class Q_WIDGETS_EXPORT QIconEngineV2 : public QIconEngine
+{
+public:
+ virtual QString key() const;
+ virtual QIconEngineV2 *clone() const;
+ virtual bool read(QDataStream &in);
+ virtual bool write(QDataStream &out) const;
+ virtual void virtual_hook(int id, void *data);
+
+public:
+ enum IconEngineHook { AvailableSizesHook = 1, IconNameHook };
+
+ struct AvailableSizesArgument
+ {
+ QIcon::Mode mode;
+ QIcon::State state;
+ QList<QSize> sizes;
+ };
+
+ // ### Qt 5: make this function const and virtual.
+ QList<QSize> availableSizes(QIcon::Mode mode = QIcon::Normal,
+ QIcon::State state = QIcon::Off);
+
+ // ### Qt 5: make this function const and virtual.
+ QString iconName();
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QICONENGINE_H
diff --git a/src/gui/image/qiconengineplugin.cpp b/src/widgets/kernel/qiconengineplugin.cpp
index e1389ae726..e1389ae726 100644
--- a/src/gui/image/qiconengineplugin.cpp
+++ b/src/widgets/kernel/qiconengineplugin.cpp
diff --git a/src/widgets/kernel/qiconengineplugin.h b/src/widgets/kernel/qiconengineplugin.h
new file mode 100644
index 0000000000..c228e8666b
--- /dev/null
+++ b/src/widgets/kernel/qiconengineplugin.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QICONENGINEPLUGIN_H
+#define QICONENGINEPLUGIN_H
+
+#include <QtCore/qplugin.h>
+#include <QtCore/qfactoryinterface.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QIconEngine;
+class QIconEngineV2;
+
+struct Q_WIDGETS_EXPORT QIconEngineFactoryInterface : public QFactoryInterface
+{
+ virtual QIconEngine *create(const QString &filename) = 0;
+};
+
+#define QIconEngineFactoryInterface_iid \
+ "com.trolltech.Qt.QIconEngineFactoryInterface"
+Q_DECLARE_INTERFACE(QIconEngineFactoryInterface, QIconEngineFactoryInterface_iid)
+
+class Q_WIDGETS_EXPORT QIconEnginePlugin : public QObject, public QIconEngineFactoryInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QIconEngineFactoryInterface:QFactoryInterface)
+public:
+ QIconEnginePlugin(QObject *parent = 0);
+ ~QIconEnginePlugin();
+
+ virtual QStringList keys() const = 0;
+ virtual QIconEngine *create(const QString &filename) = 0;
+};
+
+// ### Qt 5: remove version 2
+struct Q_WIDGETS_EXPORT QIconEngineFactoryInterfaceV2 : public QFactoryInterface
+{
+ virtual QIconEngineV2 *create(const QString &filename = QString()) = 0;
+};
+
+#define QIconEngineFactoryInterfaceV2_iid \
+ "com.trolltech.Qt.QIconEngineFactoryInterfaceV2"
+Q_DECLARE_INTERFACE(QIconEngineFactoryInterfaceV2, QIconEngineFactoryInterfaceV2_iid)
+
+class Q_WIDGETS_EXPORT QIconEnginePluginV2 : public QObject, public QIconEngineFactoryInterfaceV2
+{
+ Q_OBJECT
+ Q_INTERFACES(QIconEngineFactoryInterfaceV2:QFactoryInterface)
+public:
+ QIconEnginePluginV2(QObject *parent = 0);
+ ~QIconEnginePluginV2();
+
+ virtual QStringList keys() const = 0;
+ virtual QIconEngineV2 *create(const QString &filename = QString()) = 0;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QICONENGINEPLUGIN_H
diff --git a/src/widgets/kernel/qiconloader.cpp b/src/widgets/kernel/qiconloader.cpp
new file mode 100644
index 0000000000..45959c03ef
--- /dev/null
+++ b/src/widgets/kernel/qiconloader.cpp
@@ -0,0 +1,573 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QT_NO_ICON
+#include <private/qiconloader_p.h>
+
+#include <private/qguiapplication_p.h>
+#include <private/qicon_p.h>
+#include <private/qguiplatformplugin_p.h>
+
+#include <QtWidgets/QIconEnginePlugin>
+#include <QtGui/QPixmapCache>
+#include <QtWidgets/QIconEngine>
+#include <QtWidgets/QStyleOption>
+#include <QtCore/QList>
+#include <QtCore/QHash>
+#include <QtCore/QDir>
+#include <QtCore/QSettings>
+#include <QtGui/QPainter>
+
+#ifdef Q_WS_MAC
+#include <private/qt_cocoa_helpers_mac_p.h>
+#endif
+
+#ifdef Q_WS_X11
+#include <private/qt_x11_p.h>
+#endif
+
+#include <private/qhexstring_p.h>
+
+QT_BEGIN_NAMESPACE
+
+Q_GLOBAL_STATIC(QIconLoader, iconLoaderInstance)
+
+/* Theme to use in last resort, if the theme does not have the icon, neither the parents */
+static QString fallbackTheme()
+{
+#ifdef Q_WS_X11
+ if (X11->desktopEnvironment == DE_GNOME) {
+ return QLatin1String("gnome");
+ } else if (X11->desktopEnvironment == DE_KDE) {
+ return X11->desktopVersion >= 4
+ ? QString::fromLatin1("oxygen")
+ : QString::fromLatin1("crystalsvg");
+ } else {
+ return QLatin1String("hicolor");
+ }
+#endif
+ return QString();
+}
+
+QIconLoader::QIconLoader() :
+ m_themeKey(1), m_supportsSvg(false), m_initialized(false)
+{
+}
+
+// We lazily initialize the loader to make static icons
+// work. Though we do not officially support this.
+void QIconLoader::ensureInitialized()
+{
+ if (!m_initialized) {
+ m_initialized = true;
+
+ Q_ASSERT(qApp);
+
+ m_systemTheme = qt_guiPlatformPlugin()->systemIconThemeName();
+ if (m_systemTheme.isEmpty())
+ m_systemTheme = fallbackTheme();
+#ifndef QT_NO_LIBRARY
+ QFactoryLoader iconFactoryLoader(QIconEngineFactoryInterfaceV2_iid,
+ QLatin1String("/iconengines"),
+ Qt::CaseInsensitive);
+ if (iconFactoryLoader.keys().contains(QLatin1String("svg")))
+ m_supportsSvg = true;
+#endif //QT_NO_LIBRARY
+ }
+}
+
+QIconLoader *QIconLoader::instance()
+{
+ return iconLoaderInstance();
+}
+
+// Queries the system theme and invalidates existing
+// icons if the theme has changed.
+void QIconLoader::updateSystemTheme()
+{
+ // Only change if this is not explicitly set by the user
+ if (m_userTheme.isEmpty()) {
+ QString theme = qt_guiPlatformPlugin()->systemIconThemeName();
+ if (theme.isEmpty())
+ theme = fallbackTheme();
+ if (theme != m_systemTheme) {
+ m_systemTheme = theme;
+ invalidateKey();
+ }
+ }
+}
+
+void QIconLoader::setThemeName(const QString &themeName)
+{
+ m_userTheme = themeName;
+ invalidateKey();
+}
+
+void QIconLoader::setThemeSearchPath(const QStringList &searchPaths)
+{
+ m_iconDirs = searchPaths;
+ themeList.clear();
+ invalidateKey();
+}
+
+QStringList QIconLoader::themeSearchPaths() const
+{
+ if (m_iconDirs.isEmpty()) {
+ m_iconDirs = qt_guiPlatformPlugin()->iconThemeSearchPaths();
+ // Always add resource directory as search path
+ m_iconDirs.append(QLatin1String(":/icons"));
+ }
+ return m_iconDirs;
+}
+
+QIconTheme::QIconTheme(const QString &themeName)
+ : m_valid(false)
+{
+ QFile themeIndex;
+
+ QList <QIconDirInfo> keyList;
+ QStringList iconDirs = QIcon::themeSearchPaths();
+ for ( int i = 0 ; i < iconDirs.size() ; ++i) {
+ QDir iconDir(iconDirs[i]);
+ QString themeDir = iconDir.path() + QLatin1Char('/') + themeName;
+ themeIndex.setFileName(themeDir + QLatin1String("/index.theme"));
+ if (themeIndex.exists()) {
+ m_contentDir = themeDir;
+ m_valid = true;
+ break;
+ }
+ }
+#ifndef QT_NO_SETTINGS
+ if (themeIndex.exists()) {
+ const QSettings indexReader(themeIndex.fileName(), QSettings::IniFormat);
+ QStringListIterator keyIterator(indexReader.allKeys());
+ while (keyIterator.hasNext()) {
+
+ const QString key = keyIterator.next();
+ if (key.endsWith(QLatin1String("/Size"))) {
+ // Note the QSettings ini-format does not accept
+ // slashes in key names, hence we have to cheat
+ if (int size = indexReader.value(key).toInt()) {
+ QString directoryKey = key.left(key.size() - 5);
+ QIconDirInfo dirInfo(directoryKey);
+ dirInfo.size = size;
+ QString type = indexReader.value(directoryKey +
+ QLatin1String("/Type")
+ ).toString();
+
+ if (type == QLatin1String("Fixed"))
+ dirInfo.type = QIconDirInfo::Fixed;
+ else if (type == QLatin1String("Scalable"))
+ dirInfo.type = QIconDirInfo::Scalable;
+ else
+ dirInfo.type = QIconDirInfo::Threshold;
+
+ dirInfo.threshold = indexReader.value(directoryKey +
+ QLatin1String("/Threshold"),
+ 2).toInt();
+
+ dirInfo.minSize = indexReader.value(directoryKey +
+ QLatin1String("/MinSize"),
+ size).toInt();
+
+ dirInfo.maxSize = indexReader.value(directoryKey +
+ QLatin1String("/MaxSize"),
+ size).toInt();
+ m_keyList.append(dirInfo);
+ }
+ }
+ }
+
+ // Parent themes provide fallbacks for missing icons
+ m_parents = indexReader.value(
+ QLatin1String("Icon Theme/Inherits")).toStringList();
+
+ // Ensure a default platform fallback for all themes
+ if (m_parents.isEmpty())
+ m_parents.append(fallbackTheme());
+
+ // Ensure that all themes fall back to hicolor
+ if (!m_parents.contains(QLatin1String("hicolor")))
+ m_parents.append(QLatin1String("hicolor"));
+ }
+#endif //QT_NO_SETTINGS
+}
+
+QThemeIconEntries QIconLoader::findIconHelper(const QString &themeName,
+ const QString &iconName,
+ QStringList &visited) const
+{
+ QThemeIconEntries entries;
+ Q_ASSERT(!themeName.isEmpty());
+
+ QPixmap pixmap;
+
+ // Used to protect against potential recursions
+ visited << themeName;
+
+ QIconTheme theme = themeList.value(themeName);
+ if (!theme.isValid()) {
+ theme = QIconTheme(themeName);
+ if (!theme.isValid())
+ theme = QIconTheme(fallbackTheme());
+
+ themeList.insert(themeName, theme);
+ }
+
+ QString contentDir = theme.contentDir() + QLatin1Char('/');
+ QList<QIconDirInfo> subDirs = theme.keyList();
+
+ const QString svgext(QLatin1String(".svg"));
+ const QString pngext(QLatin1String(".png"));
+
+ // Add all relevant files
+ for (int i = 0; i < subDirs.size() ; ++i) {
+ const QIconDirInfo &dirInfo = subDirs.at(i);
+ QString subdir = dirInfo.path;
+ QDir currentDir(contentDir + subdir);
+ if (currentDir.exists(iconName + pngext)) {
+ PixmapEntry *iconEntry = new PixmapEntry;
+ iconEntry->dir = dirInfo;
+ iconEntry->filename = currentDir.filePath(iconName + pngext);
+ // Notice we ensure that pixmap entries always come before
+ // scalable to preserve search order afterwards
+ entries.prepend(iconEntry);
+ } else if (m_supportsSvg &&
+ currentDir.exists(iconName + svgext)) {
+ ScalableEntry *iconEntry = new ScalableEntry;
+ iconEntry->dir = dirInfo;
+ iconEntry->filename = currentDir.filePath(iconName + svgext);
+ entries.append(iconEntry);
+ }
+ }
+
+ if (entries.isEmpty()) {
+ const QStringList parents = theme.parents();
+ // Search recursively through inherited themes
+ for (int i = 0 ; i < parents.size() ; ++i) {
+
+ const QString parentTheme = parents.at(i).trimmed();
+
+ if (!visited.contains(parentTheme)) // guard against recursion
+ entries = findIconHelper(parentTheme, iconName, visited);
+
+ if (!entries.isEmpty()) // success
+ break;
+ }
+ }
+ return entries;
+}
+
+QThemeIconEntries QIconLoader::loadIcon(const QString &name) const
+{
+ if (!themeName().isEmpty()) {
+ QStringList visited;
+ return findIconHelper(themeName(), name, visited);
+ }
+
+ return QThemeIconEntries();
+}
+
+
+// -------- Icon Loader Engine -------- //
+
+
+QIconLoaderEngine::QIconLoaderEngine(const QString& iconName)
+ : m_iconName(iconName), m_key(0)
+{
+}
+
+QIconLoaderEngine::~QIconLoaderEngine()
+{
+ while (!m_entries.isEmpty())
+ delete m_entries.takeLast();
+ Q_ASSERT(m_entries.size() == 0);
+}
+
+QIconLoaderEngine::QIconLoaderEngine(const QIconLoaderEngine &other)
+ : QIconEngineV2(other),
+ m_iconName(other.m_iconName),
+ m_key(0)
+{
+}
+
+QIconEngineV2 *QIconLoaderEngine::clone() const
+{
+ return new QIconLoaderEngine(*this);
+}
+
+bool QIconLoaderEngine::read(QDataStream &in) {
+ in >> m_iconName;
+ return true;
+}
+
+bool QIconLoaderEngine::write(QDataStream &out) const
+{
+ out << m_iconName;
+ return true;
+}
+
+bool QIconLoaderEngine::hasIcon() const
+{
+ return !(m_entries.isEmpty());
+}
+
+// Lazily load the icon
+void QIconLoaderEngine::ensureLoaded()
+{
+
+ iconLoaderInstance()->ensureInitialized();
+
+ if (!(iconLoaderInstance()->themeKey() == m_key)) {
+
+ while (!m_entries.isEmpty())
+ delete m_entries.takeLast();
+
+ Q_ASSERT(m_entries.size() == 0);
+ m_entries = iconLoaderInstance()->loadIcon(m_iconName);
+ m_key = iconLoaderInstance()->themeKey();
+ }
+}
+
+void QIconLoaderEngine::paint(QPainter *painter, const QRect &rect,
+ QIcon::Mode mode, QIcon::State state)
+{
+ QSize pixmapSize = rect.size();
+#if defined(Q_WS_MAC)
+ pixmapSize *= qt_mac_get_scalefactor();
+#endif
+ painter->drawPixmap(rect, pixmap(pixmapSize, mode, state));
+}
+
+/*
+ * This algorithm is defined by the freedesktop spec:
+ * http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html
+ */
+static bool directoryMatchesSize(const QIconDirInfo &dir, int iconsize)
+{
+ if (dir.type == QIconDirInfo::Fixed) {
+ return dir.size == iconsize;
+
+ } else if (dir.type == QIconDirInfo::Scalable) {
+ return dir.size <= dir.maxSize &&
+ iconsize >= dir.minSize;
+
+ } else if (dir.type == QIconDirInfo::Threshold) {
+ return iconsize >= dir.size - dir.threshold &&
+ iconsize <= dir.size + dir.threshold;
+ }
+
+ Q_ASSERT(1); // Not a valid value
+ return false;
+}
+
+/*
+ * This algorithm is defined by the freedesktop spec:
+ * http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html
+ */
+static int directorySizeDistance(const QIconDirInfo &dir, int iconsize)
+{
+ if (dir.type == QIconDirInfo::Fixed) {
+ return qAbs(dir.size - iconsize);
+
+ } else if (dir.type == QIconDirInfo::Scalable) {
+ if (iconsize < dir.minSize)
+ return dir.minSize - iconsize;
+ else if (iconsize > dir.maxSize)
+ return iconsize - dir.maxSize;
+ else
+ return 0;
+
+ } else if (dir.type == QIconDirInfo::Threshold) {
+ if (iconsize < dir.size - dir.threshold)
+ return dir.minSize - iconsize;
+ else if (iconsize > dir.size + dir.threshold)
+ return iconsize - dir.maxSize;
+ else return 0;
+ }
+
+ Q_ASSERT(1); // Not a valid value
+ return INT_MAX;
+}
+
+QIconLoaderEngineEntry *QIconLoaderEngine::entryForSize(const QSize &size)
+{
+ int iconsize = qMin(size.width(), size.height());
+
+ // Note that m_entries are sorted so that png-files
+ // come first
+
+ // Search for exact matches first
+ for (int i = 0; i < m_entries.count(); ++i) {
+ QIconLoaderEngineEntry *entry = m_entries.at(i);
+ if (directoryMatchesSize(entry->dir, iconsize)) {
+ return entry;
+ }
+ }
+
+ // Find the minimum distance icon
+ int minimalSize = INT_MAX;
+ QIconLoaderEngineEntry *closestMatch = 0;
+ for (int i = 0; i < m_entries.count(); ++i) {
+ QIconLoaderEngineEntry *entry = m_entries.at(i);
+ int distance = directorySizeDistance(entry->dir, iconsize);
+ if (distance < minimalSize) {
+ minimalSize = distance;
+ closestMatch = entry;
+ }
+ }
+ return closestMatch;
+}
+
+/*
+ * Returns the actual icon size. For scalable svg's this is equivalent
+ * to the requested size. Otherwise the closest match is returned but
+ * we can never return a bigger size than the requested size.
+ *
+ */
+QSize QIconLoaderEngine::actualSize(const QSize &size, QIcon::Mode mode,
+ QIcon::State state)
+{
+ ensureLoaded();
+
+ QIconLoaderEngineEntry *entry = entryForSize(size);
+ if (entry) {
+ const QIconDirInfo &dir = entry->dir;
+ if (dir.type == QIconDirInfo::Scalable)
+ return size;
+ else {
+ int result = qMin<int>(dir.size, qMin(size.width(), size.height()));
+ return QSize(result, result);
+ }
+ }
+ return QIconEngineV2::actualSize(size, mode, state);
+}
+
+QPixmap PixmapEntry::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state)
+{
+ Q_UNUSED(state);
+
+ // Ensure that basePixmap is lazily initialized before generating the
+ // key, otherwise the cache key is not unique
+ if (basePixmap.isNull())
+ basePixmap.load(filename);
+
+#if 0 // ### Qt5
+ int actualSize = qMin(size.width(), size.height());
+ QString key = QLatin1Literal("$qt_theme_")
+ % HexString<qint64>(basePixmap.cacheKey())
+ % HexString<int>(mode)
+ % HexString<qint64>(qApp->palette().cacheKey())
+ % HexString<int>(actualSize);
+
+ QPixmap cachedPixmap;
+ if (QPixmapCache::find(key, &cachedPixmap)) {
+ return cachedPixmap;
+ } else {
+ QStyleOption opt(0);
+ opt.palette = qApp->palette();
+ cachedPixmap = qApp->style()->generatedIconPixmap(mode, basePixmap, &opt);
+ QPixmapCache::insert(key, cachedPixmap);
+ }
+ return cachedPixmap;
+#else
+ return basePixmap;
+#endif
+}
+
+QPixmap ScalableEntry::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state)
+{
+ if (svgIcon.isNull())
+ svgIcon = QIcon(filename);
+
+ // Simply reuse svg icon engine
+ return svgIcon.pixmap(size, mode, state);
+}
+
+QPixmap QIconLoaderEngine::pixmap(const QSize &size, QIcon::Mode mode,
+ QIcon::State state)
+{
+ ensureLoaded();
+
+ QIconLoaderEngineEntry *entry = entryForSize(size);
+ if (entry)
+ return entry->pixmap(size, mode, state);
+
+ return QPixmap();
+}
+
+QString QIconLoaderEngine::key() const
+{
+ return QLatin1String("QIconLoaderEngine");
+}
+
+void QIconLoaderEngine::virtual_hook(int id, void *data)
+{
+ ensureLoaded();
+
+ switch (id) {
+ case QIconEngineV2::AvailableSizesHook:
+ {
+ QIconEngineV2::AvailableSizesArgument &arg
+ = *reinterpret_cast<QIconEngineV2::AvailableSizesArgument*>(data);
+ const QList<QIconDirInfo> directoryKey = iconLoaderInstance()->theme().keyList();
+ arg.sizes.clear();
+
+ // Gets all sizes from the DirectoryInfo entries
+ for (int i = 0 ; i < m_entries.size() ; ++i) {
+ int size = m_entries.at(i)->dir.size;
+ arg.sizes.append(QSize(size, size));
+ }
+ }
+ break;
+ case QIconEngineV2::IconNameHook:
+ {
+ QString &name = *reinterpret_cast<QString*>(data);
+ name = m_iconName;
+ }
+ break;
+ default:
+ QIconEngineV2::virtual_hook(id, data);
+ }
+}
+
+QT_END_NAMESPACE
+
+#endif //QT_NO_ICON
diff --git a/src/widgets/kernel/qiconloader_p.h b/src/widgets/kernel/qiconloader_p.h
new file mode 100644
index 0000000000..1c6c0cb1a5
--- /dev/null
+++ b/src/widgets/kernel/qiconloader_p.h
@@ -0,0 +1,192 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDESKTOPICON_P_H
+#define QDESKTOPICON_P_H
+
+#ifndef QT_NO_ICON
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtWidgets/QIcon>
+#include <QtWidgets/QIconEngine>
+#include <QtGui/QPixmapCache>
+#include <private/qicon_p.h>
+#include <private/qfactoryloader_p.h>
+#include <QtCore/QHash>
+
+QT_BEGIN_NAMESPACE
+
+class QIconLoader;
+
+struct QIconDirInfo
+{
+ enum Type { Fixed, Scalable, Threshold };
+ QIconDirInfo(const QString &_path = QString()) :
+ path(_path),
+ size(0),
+ maxSize(0),
+ minSize(0),
+ threshold(0),
+ type(Threshold) {}
+ QString path;
+ short size;
+ short maxSize;
+ short minSize;
+ short threshold;
+ Type type : 4;
+};
+
+class QIconLoaderEngineEntry
+ {
+public:
+ virtual ~QIconLoaderEngineEntry() {}
+ virtual QPixmap pixmap(const QSize &size,
+ QIcon::Mode mode,
+ QIcon::State state) = 0;
+ QString filename;
+ QIconDirInfo dir;
+ static int count;
+};
+
+struct ScalableEntry : public QIconLoaderEngineEntry
+{
+ QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state);
+ QIcon svgIcon;
+};
+
+struct PixmapEntry : public QIconLoaderEngineEntry
+{
+ QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state);
+ QPixmap basePixmap;
+};
+
+typedef QList<QIconLoaderEngineEntry*> QThemeIconEntries;
+
+class QIconLoaderEngine : public QIconEngineV2
+{
+public:
+ QIconLoaderEngine(const QString& iconName = QString());
+ ~QIconLoaderEngine();
+
+ void paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state);
+ QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state);
+ QSize actualSize(const QSize &size, QIcon::Mode mode, QIcon::State state);
+ QIconEngineV2 *clone() const;
+ bool read(QDataStream &in);
+ bool write(QDataStream &out) const;
+
+private:
+ QString key() const;
+ bool hasIcon() const;
+ void ensureLoaded();
+ void virtual_hook(int id, void *data);
+ QIconLoaderEngineEntry *entryForSize(const QSize &size);
+ QIconLoaderEngine(const QIconLoaderEngine &other);
+ QThemeIconEntries m_entries;
+ QString m_iconName;
+ uint m_key;
+
+ friend class QIconLoader;
+};
+
+class QIconTheme
+{
+public:
+ QIconTheme(const QString &name);
+ QIconTheme() : m_valid(false) {}
+ QStringList parents() { return m_parents; }
+ QList <QIconDirInfo> keyList() { return m_keyList; }
+ QString contentDir() { return m_contentDir; }
+ bool isValid() { return m_valid; }
+
+private:
+ QString m_contentDir;
+ QList <QIconDirInfo> m_keyList;
+ QStringList m_parents;
+ bool m_valid;
+};
+
+class QIconLoader : public QObject
+{
+public:
+ QIconLoader();
+ QThemeIconEntries loadIcon(const QString &iconName) const;
+ uint themeKey() const { return m_themeKey; }
+
+ QString themeName() const { return m_userTheme.isEmpty() ? m_systemTheme : m_userTheme; }
+ void setThemeName(const QString &themeName);
+ QIconTheme theme() { return themeList.value(themeName()); }
+ void setThemeSearchPath(const QStringList &searchPaths);
+ QStringList themeSearchPaths() const;
+ QIconDirInfo dirInfo(int dirindex);
+ static QIconLoader *instance();
+ void updateSystemTheme();
+ void invalidateKey() { m_themeKey++; }
+ void ensureInitialized();
+
+private:
+ QThemeIconEntries findIconHelper(const QString &themeName,
+ const QString &iconName,
+ QStringList &visited) const;
+ uint m_themeKey;
+ bool m_supportsSvg;
+ bool m_initialized;
+
+ mutable QString m_userTheme;
+ mutable QString m_systemTheme;
+ mutable QStringList m_iconDirs;
+ mutable QHash <QString, QIconTheme> themeList;
+};
+
+QT_END_NAMESPACE
+
+#endif // QDESKTOPICON_P_H
+
+#endif //QT_NO_ICON
diff --git a/src/widgets/kernel/qinputcontext.cpp b/src/widgets/kernel/qinputcontext.cpp
new file mode 100644
index 0000000000..05ed9369f6
--- /dev/null
+++ b/src/widgets/kernel/qinputcontext.cpp
@@ -0,0 +1,406 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/****************************************************************************
+**
+** Implementation of QInputContext class
+**
+** Copyright (C) 2003-2004 immodule for Qt Project. All rights reserved.
+**
+** This file is written to contribute to Nokia Corporation and/or its subsidiary(-ies) under their own
+** license. You may use this file under your Qt license. Following
+** description is copied from their original file headers. Contact
+** immodule-qt@freedesktop.org if any conditions of this licensing are
+** not clear to you.
+**
+****************************************************************************/
+
+//#define QT_NO_IM_PREEDIT_RELOCATION
+
+#include "qinputcontext.h"
+
+#ifndef QT_NO_IM
+
+#include "qplatformdefs.h"
+
+#include "qapplication.h"
+#include "qmenu.h"
+#include "qtextformat.h"
+#include "qpalette.h"
+#include <QtGui/qinputpanel.h>
+#include <QtGui/qevent.h>
+
+#include <stdlib.h>
+#include <limits.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QInputContext
+ \brief The QInputContext class abstracts the input method dependent data and composing state.
+
+ \ingroup i18n
+
+ An input method is responsible for inputting complex text that cannot
+ be inputted via simple keymap. It converts a sequence of input
+ events (typically key events) into a text string through the input
+ method specific converting process. The class of the processes are
+ widely ranging from simple finite state machine to complex text
+ translator that pools a whole paragraph of a text with text
+ editing capability to perform grammar and semantic analysis.
+
+ To abstract such different input method specific intermediate
+ information, Qt offers the QInputContext as base class. The
+ concept is well known as 'input context' in the input method
+ domain. An input context is created for a text widget in response
+ to a demand. It is ensured that an input context is prepared for
+ an input method before input to a text widget.
+
+ Multiple input contexts that belong to a single input method
+ may concurrently coexist. Suppose multi-window text editor. Each
+ text widget of window A and B holds different QInputContext
+ instance which contains different state information such as
+ partially composed text.
+
+ \section1 Groups of Functions
+
+ \table
+ \header \o Context \o Functions
+
+ \row \o Receiving information \o
+ x11FilterEvent(),
+ filterEvent(),
+ mouseHandler()
+
+ \row \o Sending back composed text \o
+ sendEvent()
+
+ \row \o State change notification \o
+ setFocusWidget(),
+ reset()
+
+ \row \o Context information \o
+ identifierName(),
+ language(),
+ font(),
+ isComposing()
+
+ \endtable
+
+ \section1 Licensing Information
+
+ \legalese
+ Copyright (C) 2003-2004 immodule for Qt Project. All rights reserved.
+
+ This file is written to contribute to Nokia Corporation and/or its subsidiary(-ies) under their own
+ license. You may use this file under your Qt license. Following
+ description is copied from their original file headers. Contact
+ immodule-qt@freedesktop.org if any conditions of this licensing are
+ not clear to you.
+ \endlegalese
+
+ \sa QInputContextPlugin, QInputContextFactory, QApplication::setInputContext()
+*/
+
+/*!
+ Constructs an input context with the given \a parent.
+*/
+QInputContext::QInputContext(QObject* parent)
+ : QObject(parent)
+{
+}
+
+
+/*!
+ Destroys the input context.
+*/
+QInputContext::~QInputContext()
+{
+}
+
+/*!
+ Returns the widget that has an input focus for this input
+ context.
+
+ The return value may differ from holderWidget() if the input
+ context is shared between several text widgets.
+
+ \warning To ensure platform independence and support flexible
+ configuration of widgets, ordinary input methods should not call
+ this function directly.
+
+ \sa setFocusWidget()
+*/
+QWidget *QInputContext::focusWidget() const
+{
+ return qobject_cast<QWidget *>(qApp->inputPanel()->inputItem());
+}
+
+
+/*!
+ Sets the \a widget that has an input focus for this input context.
+
+ \warning Ordinary input methods must not call this function
+ directly.
+
+ \sa focusWidget()
+*/
+void QInputContext::setFocusWidget(QWidget *widget)
+{
+ qApp->inputPanel()->setInputItem(widget);
+}
+
+/*!
+ \fn bool QInputContext::isComposing() const
+ \obsolete
+
+ This function indicates whether InputMethodStart event had been
+ sent to the current focus widget. It is ensured that an input
+ context can send InputMethodCompose or InputMethodEnd event safely
+ if this function returned true.
+
+ The state is automatically being tracked through sendEvent().
+
+ \sa sendEvent()
+*/
+
+
+/*!
+ Sends an input method event specified by \a event to the current focus
+ widget. Implementations of QInputContext should call this method to
+ send the generated input method events and not
+ QApplication::sendEvent(), as the events might have to get dispatched
+ to a different application on some platforms.
+
+ Some complex input methods route the handling to several child
+ contexts (e.g. to enable language switching). To account for this,
+ QInputContext will check if the parent object is a QInputContext. If
+ yes, it will call the parents sendEvent() implementation instead of
+ sending the event directly.
+
+ \sa QInputMethodEvent
+*/
+void QInputContext::sendEvent(const QInputMethodEvent &event)
+{
+
+ QObject *focus = qApp->inputPanel()->inputItem();
+ if (!focus)
+ return;
+
+ QInputMethodEvent e(event);
+ QApplication::sendEvent(focus, &e);
+}
+
+
+/*!
+ This function can be reimplemented in a subclass to handle mouse
+ press, release, double-click, and move events within the preedit
+ text. You can use the function to implement mouse-oriented user
+ interface such as text selection or popup menu for candidate
+ selection.
+
+ The \a x parameter is the offset within the string that was sent
+ with the InputMethodCompose event. The alteration boundary of \a
+ x is ensured as character boundary of preedit string accurately.
+
+ The \a event parameter is the event that was sent to the editor
+ widget. The event type is QEvent::MouseButtonPress,
+ QEvent::MouseButtonRelease, QEvent::MouseButtonDblClick or
+ QEvent::MouseMove. The event's button and state indicate
+ the kind of operation that was performed.
+*/
+void QInputContext::mouseHandler(int x, QMouseEvent *event)
+{
+ if (event->type() == QEvent::MouseButtonRelease)
+ qApp->inputPanel()->invokeAction(QInputPanel::Click, x);
+}
+
+
+/*!
+ Returns the font of the current input widget
+*/
+QFont QInputContext::font() const
+{
+ QWidget *focus = focusWidget();
+ if (!focus)
+ return QApplication::font();
+
+ return qvariant_cast<QFont>(focus->inputMethodQuery(Qt::ImFont));
+}
+
+/*!
+ This virtual function is called when a state in the focus widget
+ has changed. QInputContext can then use
+ QWidget::inputMethodQuery() to query the new state of the widget.
+*/
+void QInputContext::update()
+{
+ qApp->inputPanel()->update(Qt::ImQueryAll);
+}
+
+/*!
+ This virtual function is called when the specified \a widget is
+ destroyed. The \a widget is a widget on which this input context
+ is installed.
+*/
+void QInputContext::widgetDestroyed(QWidget *widget)
+{
+ // nothing to be done here, as we use a weak pointer in the input panel
+}
+
+/*!
+ \fn void QInputContext::reset()
+
+ This function can be reimplemented in a subclass to reset the
+ state of the input method.
+
+ This function is called by several widgets to reset input
+ state. For example, a text widget call this function before
+ inserting a text to make widget ready to accept a text.
+
+ Default implementation is sufficient for simple input method. You
+ can override this function to reset external input method engines
+ in complex input method. In the case, call QInputContext::reset()
+ to ensure proper termination of inputting.
+
+ In a reimplementation of reset(), you must not send any
+ QInputMethodEvent containing preedit text. You can only commit
+ string and attributes; otherwise, you risk breaking input state
+ consistency.
+*/
+void QInputContext::reset()
+{
+ qApp->inputPanel()->reset();
+}
+
+
+/*!
+ \fn QString QInputContext::identifierName()
+
+ This function must be implemented in any subclasses to return the
+ identifier name of the input method.
+
+ Return value is the name to identify and specify input methods for
+ the input method switching mechanism and so on. The name has to be
+ consistent with QInputContextPlugin::keys(). The name has to
+ consist of ASCII characters only.
+
+ There are two different names with different responsibility in the
+ input method domain. This function returns one of them. Another
+ name is called 'display name' that stands for the name for
+ endusers appeared in a menu and so on.
+
+ \sa QInputContextPlugin::keys(), QInputContextPlugin::displayName()
+*/
+QString QInputContext::identifierName()
+{
+ return QLatin1String("qpa");
+}
+
+
+/*!
+ \fn QString QInputContext::language()
+
+ This function must be implemented in any subclasses to return a
+ language code (e.g. "zh_CN", "zh_TW", "zh_HK", "ja", "ko", ...)
+ of the input context. If the input context can handle multiple
+ languages, return the currently used one. The name has to be
+ consistent with QInputContextPlugin::language().
+
+ This information will be used by language tagging feature in
+ QInputMethodEvent. It is required to distinguish unified han characters
+ correctly. It enables proper font and character code
+ handling. Suppose CJK-awared multilingual web browser
+ (that automatically modifies fonts in CJK-mixed text) and XML editor
+ (that automatically inserts lang attr).
+*/
+QString QInputContext::language()
+{
+ return QString();
+}
+
+
+/*!
+ This is a preliminary interface for Qt 4.
+*/
+QList<QAction *> QInputContext::actions()
+{
+ return QList<QAction *>();
+}
+
+/*!
+ \enum QInputContext::StandardFormat
+
+ \value PreeditFormat The preedit text.
+ \value SelectionFormat The selection text.
+
+ \sa standardFormat()
+*/
+
+/*!
+ Returns a QTextFormat object that specifies the format for
+ component \a s.
+*/
+QTextFormat QInputContext::standardFormat(StandardFormat s) const
+{
+ QWidget *focus = focusWidget();
+ const QPalette &pal = focus ? focus->palette() : QApplication::palette();
+
+ QTextCharFormat fmt;
+ QColor bg;
+ switch (s) {
+ case QInputContext::PreeditFormat: {
+ fmt.setUnderlineStyle(QTextCharFormat::DashUnderline);
+ break;
+ }
+ case QInputContext::SelectionFormat: {
+ bg = pal.text().color();
+ fmt.setBackground(QBrush(bg));
+ fmt.setForeground(pal.background());
+ break;
+ }
+ }
+ return fmt;
+}
+
+QT_END_NAMESPACE
+
+#endif //Q_NO_IM
diff --git a/src/widgets/kernel/qinputcontext.h b/src/widgets/kernel/qinputcontext.h
new file mode 100644
index 0000000000..4864c5aea6
--- /dev/null
+++ b/src/widgets/kernel/qinputcontext.h
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/****************************************************************************
+**
+** Definition of QInputContext class
+**
+** Copyright (C) 2003-2004 immodule for Qt Project. All rights reserved.
+**
+** This file is written to contribute to Nokia Corporation and/or its subsidiary(-ies) under their own
+** license. You may use this file under your Qt license. Following
+** description is copied from their original file headers. Contact
+** immodule-qt@freedesktop.org if any conditions of this licensing are
+** not clear to you.
+**
+****************************************************************************/
+
+#ifndef QINPUTCONTEXT_H
+#define QINPUTCONTEXT_H
+
+#include <QtCore/qobject.h>
+#include <QtCore/qglobal.h>
+#include <QtGui/qevent.h>
+#include <QtCore/qstring.h>
+#include <QtCore/qlist.h>
+#include <QtWidgets/qaction.h>
+
+#ifndef QT_NO_IM
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QWidget;
+class QFont;
+class QPopupMenu;
+class QInputContextPrivate;
+#ifdef Q_OS_SYMBIAN
+class QSymbianEvent;
+#endif
+
+class Q_WIDGETS_EXPORT QInputContext : public QObject
+{
+ Q_OBJECT
+public:
+ explicit QInputContext(QObject* parent = 0);
+ virtual ~QInputContext();
+
+ virtual QString identifierName();
+ virtual QString language();
+
+ virtual void reset();
+ virtual void update();
+
+ virtual void mouseHandler( int x, QMouseEvent *event);
+ virtual QFont font() const;
+
+ QWidget *focusWidget() const;
+ virtual void setFocusWidget( QWidget *w );
+
+ virtual void widgetDestroyed(QWidget *w);
+
+ virtual QList<QAction *> actions();
+
+ void sendEvent(const QInputMethodEvent &event);
+
+ virtual bool isComposing() const { return false; }
+
+ enum StandardFormat {
+ PreeditFormat,
+ SelectionFormat
+ };
+ QTextFormat standardFormat(StandardFormat s) const;
+private:
+ friend class QWidget;
+ friend class QWidgetPrivate;
+ friend class QInputContextFactory;
+ friend class QApplication;
+private: // Disabled copy constructor and operator=
+ QInputContext( const QInputContext & );
+ QInputContext &operator=( const QInputContext & );
+
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif //Q_NO_IM
+
+#endif // QINPUTCONTEXT_H
diff --git a/src/gui/kernel/qlayout.cpp b/src/widgets/kernel/qlayout.cpp
index 68cd1183d6..68cd1183d6 100644
--- a/src/gui/kernel/qlayout.cpp
+++ b/src/widgets/kernel/qlayout.cpp
diff --git a/src/widgets/kernel/qlayout.h b/src/widgets/kernel/qlayout.h
new file mode 100644
index 0000000000..d9f732bd14
--- /dev/null
+++ b/src/widgets/kernel/qlayout.h
@@ -0,0 +1,245 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QLAYOUT_H
+#define QLAYOUT_H
+
+#include <QtCore/qobject.h>
+#include <QtWidgets/qlayoutitem.h>
+#include <QtWidgets/qsizepolicy.h>
+#include <QtCore/qrect.h>
+#include <QtCore/qmargins.h>
+
+#include <limits.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QLayout;
+class QSize;
+
+#ifdef QT3_SUPPORT
+class Q_WIDGETS_EXPORT QLayoutIterator
+{
+public:
+ inline QT3_SUPPORT_CONSTRUCTOR QLayoutIterator(QLayout *i) : layout(i), index(0) {}
+ inline QLayoutIterator(const QLayoutIterator &i)
+ : layout(i.layout), index(i.index) {}
+ inline QLayoutIterator &operator=(const QLayoutIterator &i) {
+ layout = i.layout;
+ index = i.index;
+ return *this;
+ }
+ inline QT3_SUPPORT QLayoutItem *operator++();
+ inline QT3_SUPPORT QLayoutItem *current();
+ inline QT3_SUPPORT QLayoutItem *takeCurrent();
+ inline QT3_SUPPORT void deleteCurrent();
+
+private:
+ // hack to avoid deprecated warning
+ friend class QLayout;
+ inline QLayoutIterator(QLayout *i, bool) : layout(i), index(0) {}
+ QLayout *layout;
+ int index;
+};
+#endif
+
+class QLayoutPrivate;
+
+class Q_WIDGETS_EXPORT QLayout : public QObject, public QLayoutItem
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QLayout)
+
+ Q_ENUMS(SizeConstraint)
+ Q_PROPERTY(int margin READ margin WRITE setMargin)
+ Q_PROPERTY(int spacing READ spacing WRITE setSpacing)
+ Q_PROPERTY(SizeConstraint sizeConstraint READ sizeConstraint WRITE setSizeConstraint)
+public:
+ enum SizeConstraint {
+ SetDefaultConstraint,
+ SetNoConstraint,
+ SetMinimumSize,
+ SetFixedSize,
+ SetMaximumSize,
+ SetMinAndMaxSize
+#if defined(QT3_SUPPORT) && !defined(Q_MOC_RUN)
+ , Auto = SetDefaultConstraint,
+ FreeResize = SetNoConstraint,
+ Minimum = SetMinimumSize,
+ Fixed = SetFixedSize
+#endif
+ };
+
+ QLayout(QWidget *parent);
+ QLayout();
+ ~QLayout();
+
+ int margin() const;
+ int spacing() const;
+
+ void setMargin(int);
+ void setSpacing(int);
+
+ void setContentsMargins(int left, int top, int right, int bottom);
+ void setContentsMargins(const QMargins &margins);
+ void getContentsMargins(int *left, int *top, int *right, int *bottom) const;
+ QMargins contentsMargins() const;
+ QRect contentsRect() const;
+
+ bool setAlignment(QWidget *w, Qt::Alignment alignment);
+ bool setAlignment(QLayout *l, Qt::Alignment alignment);
+#ifdef Q_NO_USING_KEYWORD
+ inline void setAlignment(Qt::Alignment alignment) { QLayoutItem::setAlignment(alignment); }
+#else
+ using QLayoutItem::setAlignment;
+#endif
+
+ void setSizeConstraint(SizeConstraint);
+ SizeConstraint sizeConstraint() const;
+#ifdef QT3_SUPPORT
+ inline QT3_SUPPORT void setResizeMode(SizeConstraint s) {setSizeConstraint(s);}
+ inline QT3_SUPPORT SizeConstraint resizeMode() const {return sizeConstraint();}
+#endif
+ void setMenuBar(QWidget *w);
+ QWidget *menuBar() const;
+
+ QWidget *parentWidget() const;
+
+ void invalidate();
+ QRect geometry() const;
+ bool activate();
+ void update();
+
+ void addWidget(QWidget *w);
+ virtual void addItem(QLayoutItem *) = 0;
+
+ void removeWidget(QWidget *w);
+ void removeItem(QLayoutItem *);
+
+ Qt::Orientations expandingDirections() const;
+ QSize minimumSize() const;
+ QSize maximumSize() const;
+ virtual void setGeometry(const QRect&);
+ virtual QLayoutItem *itemAt(int index) const = 0;
+ virtual QLayoutItem *takeAt(int index) = 0;
+ virtual int indexOf(QWidget *) const;
+ virtual int count() const = 0;
+ bool isEmpty() const;
+
+ int totalHeightForWidth(int w) const;
+ QSize totalMinimumSize() const;
+ QSize totalMaximumSize() const;
+ QSize totalSizeHint() const;
+ QLayout *layout();
+
+ void setEnabled(bool);
+ bool isEnabled() const;
+
+#ifdef QT3_SUPPORT
+ QT3_SUPPORT void freeze(int w=0, int h=0);
+ QT3_SUPPORT bool isTopLevel() const;
+#endif
+
+ static QSize closestAcceptableSize(const QWidget *w, const QSize &s);
+
+protected:
+ void widgetEvent(QEvent *);
+ void childEvent(QChildEvent *e);
+ void addChildLayout(QLayout *l);
+ void addChildWidget(QWidget *w);
+#ifdef QT3_SUPPORT
+ QT3_SUPPORT void deleteAllItems();
+#endif
+
+ QRect alignmentRect(const QRect&) const;
+protected:
+ QLayout(QLayoutPrivate &d, QLayout*, QWidget*);
+
+private:
+ Q_DISABLE_COPY(QLayout)
+
+ static void activateRecursiveHelper(QLayoutItem *item);
+
+ friend class QApplicationPrivate;
+ friend class QWidget;
+
+#ifdef QT3_SUPPORT
+public:
+ QT3_SUPPORT_CONSTRUCTOR QLayout(QWidget *parent, int margin, int spacing = -1,
+ const char *name = 0);
+ QT3_SUPPORT_CONSTRUCTOR QLayout(QLayout *parentLayout, int spacing = -1, const char *name = 0);
+ QT3_SUPPORT_CONSTRUCTOR QLayout(int spacing, const char *name = 0);
+ inline QT3_SUPPORT QWidget *mainWidget() const { return parentWidget(); }
+ inline QT3_SUPPORT void remove(QWidget *w) { removeWidget(w); }
+ inline QT3_SUPPORT void add(QWidget *w) { addWidget(w); }
+
+ QT3_SUPPORT void setAutoAdd(bool a);
+ QT3_SUPPORT bool autoAdd() const;
+ inline QT3_SUPPORT QLayoutIterator iterator() { return QLayoutIterator(this,true); }
+
+ inline QT3_SUPPORT int defaultBorder() const { return spacing(); }
+#endif
+};
+
+#ifdef QT3_SUPPORT
+inline QLayoutItem *QLayoutIterator::operator++() { return layout->itemAt(++index); }
+inline QLayoutItem *QLayoutIterator::current() { return layout->itemAt(index); }
+inline QLayoutItem *QLayoutIterator::takeCurrent() { return layout->takeAt(index); }
+inline void QLayoutIterator::deleteCurrent() { delete layout->takeAt(index); }
+#endif
+
+//### support old includes
+#if 1 //def QT3_SUPPORT
+QT_BEGIN_INCLUDE_NAMESPACE
+#include <QtWidgets/qboxlayout.h>
+#include <QtWidgets/qgridlayout.h>
+QT_END_INCLUDE_NAMESPACE
+#endif
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QLAYOUT_H
diff --git a/src/widgets/kernel/qlayout_p.h b/src/widgets/kernel/qlayout_p.h
new file mode 100644
index 0000000000..e282360418
--- /dev/null
+++ b/src/widgets/kernel/qlayout_p.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QLAYOUT_P_H
+#define QLAYOUT_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of qlayout*.cpp, and qabstractlayout.cpp. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "private/qobject_p.h"
+#include "qstyle.h"
+#include "qsizepolicy.h"
+
+QT_BEGIN_NAMESPACE
+
+class QWidgetItem;
+class QSpacerItem;
+
+class Q_WIDGETS_EXPORT QLayoutPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QLayout)
+
+public:
+ typedef QWidgetItem * (*QWidgetItemFactoryMethod)(const QLayout *layout, QWidget *widget);
+ typedef QSpacerItem * (*QSpacerItemFactoryMethod)(const QLayout *layout, int w, int h, QSizePolicy::Policy hPolicy, QSizePolicy::Policy);
+
+ QLayoutPrivate();
+
+ void getMargin(int *result, int userMargin, QStyle::PixelMetric pm) const;
+ void doResize(const QSize &);
+ void reparentChildWidgets(QWidget *mw);
+
+ static QWidgetItem *createWidgetItem(const QLayout *layout, QWidget *widget);
+ static QSpacerItem *createSpacerItem(const QLayout *layout, int w, int h, QSizePolicy::Policy hPolicy = QSizePolicy::Minimum, QSizePolicy::Policy vPolicy = QSizePolicy::Minimum);
+
+ static QWidgetItemFactoryMethod widgetItemFactoryMethod;
+ static QSpacerItemFactoryMethod spacerItemFactoryMethod;
+
+ int insideSpacing;
+ int userLeftMargin;
+ int userTopMargin;
+ int userRightMargin;
+ int userBottomMargin;
+ uint topLevel : 1;
+ uint enabled : 1;
+ uint activated : 1;
+ uint autoNewChild : 1;
+ QLayout::SizeConstraint constraint;
+ QRect rect;
+ QWidget *menubar;
+};
+
+QT_END_NAMESPACE
+
+#endif // QLAYOUT_P_H
diff --git a/src/widgets/kernel/qlayoutengine.cpp b/src/widgets/kernel/qlayoutengine.cpp
new file mode 100644
index 0000000000..a7470aabaa
--- /dev/null
+++ b/src/widgets/kernel/qlayoutengine.cpp
@@ -0,0 +1,436 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qlayout.h"
+#include "private/qlayoutengine_p.h"
+
+#include "qvector.h"
+#include "qwidget.h"
+
+#include <qlist.h>
+#include <qalgorithms.h>
+
+#include <qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+//#define QLAYOUT_EXTRA_DEBUG
+
+typedef qint64 Fixed64;
+static inline Fixed64 toFixed(int i) { return (Fixed64)i * 256; }
+static inline int fRound(Fixed64 i) {
+ return (i % 256 < 128) ? i / 256 : 1 + i / 256;
+}
+
+/*
+ This is the main workhorse of the QGridLayout. It portions out
+ available space to the chain's children.
+
+ The calculation is done in fixed point: "fixed" variables are
+ scaled by a factor of 256.
+
+ If the layout runs "backwards" (i.e. RightToLeft or Up) the layout
+ is computed mirror-reversed, and it's the caller's responsibility
+ do reverse the values before use.
+
+ chain contains input and output parameters describing the geometry.
+ count is the count of items in the chain; pos and space give the
+ interval (relative to parentWidget topLeft).
+*/
+void qGeomCalc(QVector<QLayoutStruct> &chain, int start, int count,
+ int pos, int space, int spacer)
+{
+ int cHint = 0;
+ int cMin = 0;
+ int cMax = 0;
+ int sumStretch = 0;
+ int sumSpacing = 0;
+
+ bool wannaGrow = false; // anyone who really wants to grow?
+ // bool canShrink = false; // anyone who could be persuaded to shrink?
+
+ bool allEmptyNonstretch = true;
+ int pendingSpacing = -1;
+ int spacerCount = 0;
+ int i;
+
+ for (i = start; i < start + count; i++) {
+ QLayoutStruct *data = &chain[i];
+
+ data->done = false;
+ cHint += data->smartSizeHint();
+ cMin += data->minimumSize;
+ cMax += data->maximumSize;
+ sumStretch += data->stretch;
+ if (!data->empty) {
+ /*
+ Using pendingSpacing, we ensure that the spacing for the last
+ (non-empty) item is ignored.
+ */
+ if (pendingSpacing >= 0) {
+ sumSpacing += pendingSpacing;
+ ++spacerCount;
+ }
+ pendingSpacing = data->effectiveSpacer(spacer);
+ }
+ wannaGrow = wannaGrow || data->expansive || data->stretch > 0;
+ allEmptyNonstretch = allEmptyNonstretch && !wannaGrow && data->empty;
+ }
+
+ int extraspace = 0;
+
+ if (space < cMin + sumSpacing) {
+ /*
+ Less space than minimumSize; take from the biggest first
+ */
+
+ int minSize = cMin + sumSpacing;
+
+ // shrink the spacers proportionally
+ if (spacer >= 0) {
+ spacer = minSize > 0 ? spacer * space / minSize : 0;
+ sumSpacing = spacer * spacerCount;
+ }
+
+ QList<int> list;
+
+ for (i = start; i < start + count; i++)
+ list << chain.at(i).minimumSize;
+
+ qSort(list);
+
+ int space_left = space - sumSpacing;
+
+ int sum = 0;
+ int idx = 0;
+ int space_used=0;
+ int current = 0;
+ while (idx < count && space_used < space_left) {
+ current = list.at(idx);
+ space_used = sum + current * (count - idx);
+ sum += current;
+ ++idx;
+ }
+ --idx;
+ int deficit = space_used - space_left;
+
+ int items = count - idx;
+ /*
+ * If we truncate all items to "current", we would get "deficit" too many pixels. Therefore, we have to remove
+ * deficit/items from each item bigger than maxval. The actual value to remove is deficitPerItem + remainder/items
+ * "rest" is the accumulated error from using integer arithmetic.
+ */
+ int deficitPerItem = deficit/items;
+ int remainder = deficit % items;
+ int maxval = current - deficitPerItem;
+
+ int rest = 0;
+ for (i = start; i < start + count; i++) {
+ int maxv = maxval;
+ rest += remainder;
+ if (rest >= items) {
+ maxv--;
+ rest-=items;
+ }
+ QLayoutStruct *data = &chain[i];
+ data->size = qMin(data->minimumSize, maxv);
+ data->done = true;
+ }
+ } else if (space < cHint + sumSpacing) {
+ /*
+ Less space than smartSizeHint(), but more than minimumSize.
+ Currently take space equally from each, as in Qt 2.x.
+ Commented-out lines will give more space to stretchier
+ items.
+ */
+ int n = count;
+ int space_left = space - sumSpacing;
+ int overdraft = cHint - space_left;
+
+ // first give to the fixed ones:
+ for (i = start; i < start + count; i++) {
+ QLayoutStruct *data = &chain[i];
+ if (!data->done
+ && data->minimumSize >= data->smartSizeHint()) {
+ data->size = data->smartSizeHint();
+ data->done = true;
+ space_left -= data->smartSizeHint();
+ // sumStretch -= data->stretch;
+ n--;
+ }
+ }
+ bool finished = n == 0;
+ while (!finished) {
+ finished = true;
+ Fixed64 fp_over = toFixed(overdraft);
+ Fixed64 fp_w = 0;
+
+ for (i = start; i < start+count; i++) {
+ QLayoutStruct *data = &chain[i];
+ if (data->done)
+ continue;
+ // if (sumStretch <= 0)
+ fp_w += fp_over / n;
+ // else
+ // fp_w += (fp_over * data->stretch) / sumStretch;
+ int w = fRound(fp_w);
+ data->size = data->smartSizeHint() - w;
+ fp_w -= toFixed(w); // give the difference to the next
+ if (data->size < data->minimumSize) {
+ data->done = true;
+ data->size = data->minimumSize;
+ finished = false;
+ overdraft -= data->smartSizeHint() - data->minimumSize;
+ // sumStretch -= data->stretch;
+ n--;
+ break;
+ }
+ }
+ }
+ } else { // extra space
+ int n = count;
+ int space_left = space - sumSpacing;
+ // first give to the fixed ones, and handle non-expansiveness
+ for (i = start; i < start + count; i++) {
+ QLayoutStruct *data = &chain[i];
+ if (!data->done
+ && (data->maximumSize <= data->smartSizeHint()
+ || (wannaGrow && !data->expansive && data->stretch == 0)
+ || (!allEmptyNonstretch && data->empty &&
+ !data->expansive && data->stretch == 0))) {
+ data->size = data->smartSizeHint();
+ data->done = true;
+ space_left -= data->size;
+ sumStretch -= data->stretch;
+ n--;
+ }
+ }
+ extraspace = space_left;
+
+ /*
+ Do a trial distribution and calculate how much it is off.
+ If there are more deficit pixels than surplus pixels, give
+ the minimum size items what they need, and repeat.
+ Otherwise give to the maximum size items, and repeat.
+
+ Paul Olav Tvete has a wonderful mathematical proof of the
+ correctness of this principle, but unfortunately this
+ comment is too small to contain it.
+ */
+ int surplus, deficit;
+ do {
+ surplus = deficit = 0;
+ Fixed64 fp_space = toFixed(space_left);
+ Fixed64 fp_w = 0;
+ for (i = start; i < start + count; i++) {
+ QLayoutStruct *data = &chain[i];
+ if (data->done)
+ continue;
+ extraspace = 0;
+ if (sumStretch <= 0)
+ fp_w += fp_space / n;
+ else
+ fp_w += (fp_space * data->stretch) / sumStretch;
+ int w = fRound(fp_w);
+ data->size = w;
+ fp_w -= toFixed(w); // give the difference to the next
+ if (w < data->smartSizeHint()) {
+ deficit += data->smartSizeHint() - w;
+ } else if (w > data->maximumSize) {
+ surplus += w - data->maximumSize;
+ }
+ }
+ if (deficit > 0 && surplus <= deficit) {
+ // give to the ones that have too little
+ for (i = start; i < start+count; i++) {
+ QLayoutStruct *data = &chain[i];
+ if (!data->done && data->size < data->smartSizeHint()) {
+ data->size = data->smartSizeHint();
+ data->done = true;
+ space_left -= data->smartSizeHint();
+ sumStretch -= data->stretch;
+ n--;
+ }
+ }
+ }
+ if (surplus > 0 && surplus >= deficit) {
+ // take from the ones that have too much
+ for (i = start; i < start + count; i++) {
+ QLayoutStruct *data = &chain[i];
+ if (!data->done && data->size > data->maximumSize) {
+ data->size = data->maximumSize;
+ data->done = true;
+ space_left -= data->maximumSize;
+ sumStretch -= data->stretch;
+ n--;
+ }
+ }
+ }
+ } while (n > 0 && surplus != deficit);
+ if (n == 0)
+ extraspace = space_left;
+ }
+
+ /*
+ As a last resort, we distribute the unwanted space equally
+ among the spacers (counting the start and end of the chain). We
+ could, but don't, attempt a sub-pixel allocation of the extra
+ space.
+ */
+ int extra = extraspace / (spacerCount + 2);
+ int p = pos + extra;
+ for (i = start; i < start+count; i++) {
+ QLayoutStruct *data = &chain[i];
+ data->pos = p;
+ p += data->size;
+ if (!data->empty)
+ p += data->effectiveSpacer(spacer) + extra;
+ }
+
+#ifdef QLAYOUT_EXTRA_DEBUG
+ qDebug() << "qGeomCalc" << "start" << start << "count" << count << "pos" << pos
+ << "space" << space << "spacer" << spacer;
+ for (i = start; i < start + count; ++i) {
+ qDebug() << i << ':' << chain[i].minimumSize << chain[i].smartSizeHint()
+ << chain[i].maximumSize << "stretch" << chain[i].stretch
+ << "empty" << chain[i].empty << "expansive" << chain[i].expansive
+ << "spacing" << chain[i].spacing;
+ qDebug() << "result pos" << chain[i].pos << "size" << chain[i].size;
+ }
+#endif
+}
+
+Q_WIDGETS_EXPORT QSize qSmartMinSize(const QSize &sizeHint, const QSize &minSizeHint,
+ const QSize &minSize, const QSize &maxSize,
+ const QSizePolicy &sizePolicy)
+{
+ QSize s(0, 0);
+
+ if (sizePolicy.horizontalPolicy() != QSizePolicy::Ignored) {
+ if (sizePolicy.horizontalPolicy() & QSizePolicy::ShrinkFlag)
+ s.setWidth(minSizeHint.width());
+ else
+ s.setWidth(qMax(sizeHint.width(), minSizeHint.width()));
+ }
+
+ if (sizePolicy.verticalPolicy() != QSizePolicy::Ignored) {
+ if (sizePolicy.verticalPolicy() & QSizePolicy::ShrinkFlag) {
+ s.setHeight(minSizeHint.height());
+ } else {
+ s.setHeight(qMax(sizeHint.height(), minSizeHint.height()));
+ }
+ }
+
+ s = s.boundedTo(maxSize);
+ if (minSize.width() > 0)
+ s.setWidth(minSize.width());
+ if (minSize.height() > 0)
+ s.setHeight(minSize.height());
+
+ return s.expandedTo(QSize(0,0));
+}
+
+Q_WIDGETS_EXPORT QSize qSmartMinSize(const QWidgetItem *i)
+{
+ QWidget *w = ((QWidgetItem *)i)->widget();
+ return qSmartMinSize(w->sizeHint(), w->minimumSizeHint(),
+ w->minimumSize(), w->maximumSize(),
+ w->sizePolicy());
+}
+
+Q_WIDGETS_EXPORT QSize qSmartMinSize(const QWidget *w)
+{
+ return qSmartMinSize(w->sizeHint(), w->minimumSizeHint(),
+ w->minimumSize(), w->maximumSize(),
+ w->sizePolicy());
+}
+
+Q_WIDGETS_EXPORT QSize qSmartMaxSize(const QSize &sizeHint,
+ const QSize &minSize, const QSize &maxSize,
+ const QSizePolicy &sizePolicy, Qt::Alignment align)
+{
+ if (align & Qt::AlignHorizontal_Mask && align & Qt::AlignVertical_Mask)
+ return QSize(QLAYOUTSIZE_MAX, QLAYOUTSIZE_MAX);
+ QSize s = maxSize;
+ QSize hint = sizeHint.expandedTo(minSize);
+ if (s.width() == QWIDGETSIZE_MAX && !(align & Qt::AlignHorizontal_Mask))
+ if (!(sizePolicy.horizontalPolicy() & QSizePolicy::GrowFlag))
+ s.setWidth(hint.width());
+
+ if (s.height() == QWIDGETSIZE_MAX && !(align & Qt::AlignVertical_Mask))
+ if (!(sizePolicy.verticalPolicy() & QSizePolicy::GrowFlag))
+ s.setHeight(hint.height());
+
+ if (align & Qt::AlignHorizontal_Mask)
+ s.setWidth(QLAYOUTSIZE_MAX);
+ if (align & Qt::AlignVertical_Mask)
+ s.setHeight(QLAYOUTSIZE_MAX);
+ return s;
+}
+
+Q_WIDGETS_EXPORT QSize qSmartMaxSize(const QWidgetItem *i, Qt::Alignment align)
+{
+ QWidget *w = ((QWidgetItem*)i)->widget();
+
+ return qSmartMaxSize(w->sizeHint().expandedTo(w->minimumSizeHint()), w->minimumSize(), w->maximumSize(),
+ w->sizePolicy(), align);
+}
+
+Q_WIDGETS_EXPORT QSize qSmartMaxSize(const QWidget *w, Qt::Alignment align)
+{
+ return qSmartMaxSize(w->sizeHint().expandedTo(w->minimumSizeHint()), w->minimumSize(), w->maximumSize(),
+ w->sizePolicy(), align);
+}
+
+Q_WIDGETS_EXPORT int qSmartSpacing(const QLayout *layout, QStyle::PixelMetric pm)
+{
+ QObject *parent = layout->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();
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/widgets/kernel/qlayoutengine_p.h b/src/widgets/kernel/qlayoutengine_p.h
new file mode 100644
index 0000000000..9be9ecd321
--- /dev/null
+++ b/src/widgets/kernel/qlayoutengine_p.h
@@ -0,0 +1,140 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QLAYOUTENGINE_P_H
+#define QLAYOUTENGINE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "QtWidgets/qlayoutitem.h"
+#include "QtWidgets/qstyle.h"
+
+QT_BEGIN_NAMESPACE
+
+template <typename T> class QVector;
+
+struct QLayoutStruct
+{
+ inline void init(int stretchFactor = 0, int minSize = 0) {
+ stretch = stretchFactor;
+ minimumSize = sizeHint = minSize;
+ maximumSize = QLAYOUTSIZE_MAX;
+ expansive = false;
+ empty = true;
+ spacing = 0;
+ }
+
+ int smartSizeHint() {
+ return (stretch > 0) ? minimumSize : sizeHint;
+ }
+ int effectiveSpacer(int uniformSpacer) const {
+ Q_ASSERT(uniformSpacer >= 0 || spacing >= 0);
+ return (uniformSpacer >= 0) ? uniformSpacer : spacing;
+ }
+
+ // parameters
+ int stretch;
+ int sizeHint;
+ int maximumSize;
+ int minimumSize;
+ bool expansive;
+ bool empty;
+ int spacing;
+
+ // temporary storage
+ bool done;
+
+ // result
+ int pos;
+ int size;
+};
+
+
+Q_WIDGETS_EXPORT void qGeomCalc(QVector<QLayoutStruct> &chain, int start, int count,
+ int pos, int space, int spacer = -1);
+Q_WIDGETS_EXPORT QSize qSmartMinSize(const QSize &sizeHint, const QSize &minSizeHint,
+ const QSize &minSize, const QSize &maxSize,
+ const QSizePolicy &sizePolicy);
+Q_WIDGETS_EXPORT QSize qSmartMinSize(const QWidgetItem *i);
+Q_WIDGETS_EXPORT QSize qSmartMinSize(const QWidget *w);
+Q_WIDGETS_EXPORT QSize qSmartMaxSize(const QSize &sizeHint,
+ const QSize &minSize, const QSize &maxSize,
+ const QSizePolicy &sizePolicy, Qt::Alignment align = 0);
+Q_WIDGETS_EXPORT QSize qSmartMaxSize(const QWidgetItem *i, Qt::Alignment align = 0);
+Q_WIDGETS_EXPORT QSize qSmartMaxSize(const QWidget *w, Qt::Alignment align = 0);
+
+Q_WIDGETS_EXPORT int qSmartSpacing(const QLayout *layout, QStyle::PixelMetric pm);
+
+/*
+ Modify total maximum (max), total expansion (exp), and total empty
+ when adding boxmax/boxexp.
+
+ Expansive boxes win over non-expansive boxes.
+ Non-empty boxes win over empty boxes.
+*/
+static inline void qMaxExpCalc(int & max, bool &exp, bool &empty,
+ int boxmax, bool boxexp, bool boxempty)
+{
+ if (exp) {
+ if (boxexp)
+ max = qMax(max, boxmax);
+ } else {
+ if (boxexp || (empty && (!boxempty || max == 0)))
+ max = boxmax;
+ else if (empty == boxempty)
+ max = qMin(max, boxmax);
+ }
+ exp = exp || boxexp;
+ empty = empty && boxempty;
+}
+
+QT_END_NAMESPACE
+
+#endif // QLAYOUTENGINE_P_H
diff --git a/src/gui/kernel/qlayoutitem.cpp b/src/widgets/kernel/qlayoutitem.cpp
index e3857454ad..e3857454ad 100644
--- a/src/gui/kernel/qlayoutitem.cpp
+++ b/src/widgets/kernel/qlayoutitem.cpp
diff --git a/src/widgets/kernel/qlayoutitem.h b/src/widgets/kernel/qlayoutitem.h
new file mode 100644
index 0000000000..d03f77654b
--- /dev/null
+++ b/src/widgets/kernel/qlayoutitem.h
@@ -0,0 +1,182 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QLAYOUTITEM_H
+#define QLAYOUTITEM_H
+
+#include <QtWidgets/qsizepolicy.h>
+#include <QtCore/qrect.h>
+
+#include <limits.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+static const int QLAYOUTSIZE_MAX = INT_MAX/256/16;
+
+class QLayout;
+class QLayoutItem;
+class QSpacerItem;
+class QWidget;
+class QSize;
+
+class Q_WIDGETS_EXPORT QLayoutItem
+{
+public:
+ inline explicit QLayoutItem(Qt::Alignment alignment = 0);
+ virtual ~QLayoutItem();
+ virtual QSize sizeHint() const = 0;
+ virtual QSize minimumSize() const = 0;
+ virtual QSize maximumSize() const = 0;
+ virtual Qt::Orientations expandingDirections() const = 0;
+ virtual void setGeometry(const QRect&) = 0;
+ virtual QRect geometry() const = 0;
+ virtual bool isEmpty() const = 0;
+ virtual bool hasHeightForWidth() const;
+ virtual int heightForWidth(int) const;
+ virtual int minimumHeightForWidth(int) const;
+ virtual void invalidate();
+
+ virtual QWidget *widget();
+ virtual QLayout *layout();
+ virtual QSpacerItem *spacerItem();
+
+ Qt::Alignment alignment() const { return align; }
+ void setAlignment(Qt::Alignment a);
+ QSizePolicy::ControlTypes controlTypes() const;
+
+protected:
+ Qt::Alignment align;
+};
+
+inline QLayoutItem::QLayoutItem(Qt::Alignment aalignment)
+ : align(aalignment) { }
+
+class Q_WIDGETS_EXPORT QSpacerItem : public QLayoutItem
+{
+public:
+ QSpacerItem(int w, int h,
+ QSizePolicy::Policy hData = QSizePolicy::Minimum,
+ QSizePolicy::Policy vData = QSizePolicy::Minimum)
+ : width(w), height(h), sizeP(hData, vData) { }
+ void changeSize(int w, int h,
+ QSizePolicy::Policy hData = QSizePolicy::Minimum,
+ QSizePolicy::Policy vData = QSizePolicy::Minimum);
+ QSize sizeHint() const;
+ QSize minimumSize() const;
+ QSize maximumSize() const;
+ Qt::Orientations expandingDirections() const;
+ bool isEmpty() const;
+ void setGeometry(const QRect&);
+ QRect geometry() const;
+ QSpacerItem *spacerItem();
+
+private:
+ int width;
+ int height;
+ QSizePolicy sizeP;
+ QRect rect;
+};
+
+class Q_WIDGETS_EXPORT QWidgetItem : public QLayoutItem
+{
+ Q_DISABLE_COPY(QWidgetItem)
+
+public:
+ explicit QWidgetItem(QWidget *w) : wid(w) { }
+ QSize sizeHint() const;
+ QSize minimumSize() const;
+ QSize maximumSize() const;
+ Qt::Orientations expandingDirections() const;
+ bool isEmpty() const;
+ void setGeometry(const QRect&);
+ QRect geometry() const;
+ virtual QWidget *widget();
+
+ bool hasHeightForWidth() const;
+ int heightForWidth(int) const;
+
+protected:
+ QWidget *wid;
+};
+
+class Q_WIDGETS_EXPORT QWidgetItemV2 : public QWidgetItem
+{
+public:
+ explicit QWidgetItemV2(QWidget *widget);
+ ~QWidgetItemV2();
+
+ QSize sizeHint() const;
+ QSize minimumSize() const;
+ QSize maximumSize() const;
+ int heightForWidth(int width) const;
+
+private:
+ enum { Dirty = -123, HfwCacheMaxSize = 3 };
+
+ inline bool useSizeCache() const;
+ void updateCacheIfNecessary() const;
+ inline void invalidateSizeCache() {
+ q_cachedMinimumSize.setWidth(Dirty);
+ q_hfwCacheSize = 0;
+ }
+
+ mutable QSize q_cachedMinimumSize;
+ mutable QSize q_cachedSizeHint;
+ mutable QSize q_cachedMaximumSize;
+ mutable QSize q_cachedHfws[HfwCacheMaxSize];
+ mutable short q_firstCachedHfw;
+ mutable short q_hfwCacheSize;
+ void *d;
+
+ friend class QWidgetPrivate;
+
+ Q_DISABLE_COPY(QWidgetItemV2)
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QLAYOUTITEM_H
diff --git a/src/widgets/kernel/qplatformmenu_qpa.cpp b/src/widgets/kernel/qplatformmenu_qpa.cpp
new file mode 100644
index 0000000000..57c2613079
--- /dev/null
+++ b/src/widgets/kernel/qplatformmenu_qpa.cpp
@@ -0,0 +1,51 @@
+#include "qplatformmenu_qpa.h"
+
+//
+// QPlatformMenuAction
+//
+
+QPlatformMenuAction::~QPlatformMenuAction()
+{
+
+}
+
+//
+// QPlatformMenu
+//
+QPlatformMenu::QPlatformMenu()
+{
+}
+
+QPlatformMenu::~QPlatformMenu()
+{
+
+}
+
+void QPlatformMenu::setMenuEnabled(bool enable)
+{
+ Q_UNUSED(enable);
+}
+
+void QPlatformMenu::syncSeparatorsCollapsible(bool enable)
+{
+ Q_UNUSED(enable);
+}
+
+//
+// QPlatformMenuBar
+//
+QPlatformMenuBar::QPlatformMenuBar()
+{
+
+}
+
+QPlatformMenuBar::~QPlatformMenuBar()
+{
+
+}
+
+void QPlatformMenuBar::handleReparent(QWidget *newParent)
+{
+ Q_UNUSED(newParent);
+}
+
diff --git a/src/widgets/kernel/qplatformmenu_qpa.h b/src/widgets/kernel/qplatformmenu_qpa.h
new file mode 100644
index 0000000000..e3b816c9fe
--- /dev/null
+++ b/src/widgets/kernel/qplatformmenu_qpa.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+ **
+ ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ ** All rights reserved.
+ ** Contact: Nokia Corporation (qt-info@nokia.com)
+ **
+ ** This file is part of the QtGui module of the Qt Toolkit.
+ **
+ ** $QT_BEGIN_LICENSE:LGPL$
+ ** GNU Lesser General Public License Usage
+ ** This file may be used under the terms of the GNU Lesser General Public
+ ** License version 2.1 as published by the Free Software Foundation and
+ ** appearing in the file LICENSE.LGPL included in the packaging of this
+ ** file. Please review the following information to ensure the GNU Lesser
+ ** General Public License version 2.1 requirements will be met:
+ ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+ **
+ ** In addition, as a special exception, Nokia gives you certain additional
+ ** rights. These rights are described in the Nokia Qt LGPL Exception
+ ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+ **
+ ** 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.
+ **
+ ** Other Usage
+ ** Alternatively, this file may be used in accordance with the terms and
+ ** conditions contained in a signed written agreement between you and Nokia.
+ **
+ **
+ **
+ **
+ **
+ ** $QT_END_LICENSE$
+ **
+ ****************************************************************************/
+
+#ifndef QPLATFORMMENU_H
+#define QPLATFORMMENU_H
+
+#include <qglobal.h>
+#include <qpointer.h>
+#include <QtWidgets/qaction.h>
+
+QT_BEGIN_NAMESPACE
+
+class QMenuPrivate;
+class Q_WIDGETS_EXPORT QPlatformMenuAction
+{
+public:
+ virtual ~QPlatformMenuAction();
+ QPointer<QAction> action;
+};
+
+class Q_WIDGETS_EXPORT QPlatformMenu {
+public:
+ QPlatformMenu();
+ virtual ~QPlatformMenu();
+
+ virtual bool merged(const QAction *action) const = 0;
+
+ virtual void addAction(QAction *action, QAction *before) = 0;
+ virtual void removeAction(QAction *action) = 0;
+ virtual void syncAction(QAction *action) = 0;
+
+ virtual void setMenuEnabled(bool enable);
+ virtual void syncSeparatorsCollapsible(bool enable);
+};
+
+struct Q_WIDGETS_EXPORT QPlatformMenuBar {
+ QPlatformMenuBar();
+ virtual ~QPlatformMenuBar();
+
+ virtual void addAction(QAction *action, QAction *before = 0) = 0;
+ virtual void syncAction(QAction *action) = 0;
+ virtual void removeAction(QAction *action) = 0;
+
+ virtual void handleReparent(QWidget *newParent);
+};
+
+QT_END_NAMESPACE
+
+#endif
+
diff --git a/src/widgets/kernel/qsizepolicy.h b/src/widgets/kernel/qsizepolicy.h
new file mode 100644
index 0000000000..76067604f9
--- /dev/null
+++ b/src/widgets/kernel/qsizepolicy.h
@@ -0,0 +1,244 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSIZEPOLICY_H
+#define QSIZEPOLICY_H
+
+#include <QtCore/qobject.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QVariant;
+
+class Q_WIDGETS_EXPORT QSizePolicy
+{
+ Q_GADGET
+ Q_ENUMS(Policy)
+
+private:
+ enum SizePolicyMasks {
+ HSize = 4,
+ HMask = 0x0f,
+ VMask = HMask << HSize,
+ CTShift = 9,
+ CTSize = 5,
+ CTMask = ((0x1 << CTSize) - 1) << CTShift,
+ WFHShift = CTShift + CTSize,
+ UnusedShift = WFHShift + 1,
+ UnusedSize = 1
+ };
+
+public:
+ enum PolicyFlag {
+ GrowFlag = 1,
+ ExpandFlag = 2,
+ ShrinkFlag = 4,
+ IgnoreFlag = 8
+ };
+
+ enum Policy {
+ Fixed = 0,
+ Minimum = GrowFlag,
+ Maximum = ShrinkFlag,
+ Preferred = GrowFlag | ShrinkFlag,
+ MinimumExpanding = GrowFlag | ExpandFlag,
+ Expanding = GrowFlag | ShrinkFlag | ExpandFlag,
+ Ignored = ShrinkFlag | GrowFlag | IgnoreFlag
+ };
+
+ enum ControlType {
+ DefaultType = 0x00000001,
+ ButtonBox = 0x00000002,
+ CheckBox = 0x00000004,
+ ComboBox = 0x00000008,
+ Frame = 0x00000010,
+ GroupBox = 0x00000020,
+ Label = 0x00000040,
+ Line = 0x00000080,
+ LineEdit = 0x00000100,
+ PushButton = 0x00000200,
+ RadioButton = 0x00000400,
+ Slider = 0x00000800,
+ SpinBox = 0x00001000,
+ TabWidget = 0x00002000,
+ ToolButton = 0x00004000
+ };
+ Q_DECLARE_FLAGS(ControlTypes, ControlType)
+
+ QSizePolicy() : data(0) { }
+
+ // ### Qt 5: merge these two constructors (with type == DefaultType)
+ QSizePolicy(Policy horizontal, Policy vertical)
+ : data(horizontal | (vertical << HSize)) { }
+ QSizePolicy(Policy horizontal, Policy vertical, ControlType type)
+ : data(horizontal | (vertical << HSize)) { setControlType(type); }
+
+ Policy horizontalPolicy() const { return static_cast<Policy>(data & HMask); }
+ Policy verticalPolicy() const { return static_cast<Policy>((data & VMask) >> HSize); }
+ ControlType controlType() const;
+
+ void setHorizontalPolicy(Policy d) { data = (data & ~HMask) | d; }
+ void setVerticalPolicy(Policy d) { data = (data & ~(HMask << HSize)) | (d << HSize); }
+ void setControlType(ControlType type);
+
+ Qt::Orientations expandingDirections() const {
+ Qt::Orientations result;
+ if (verticalPolicy() & ExpandFlag)
+ result |= Qt::Vertical;
+ if (horizontalPolicy() & ExpandFlag)
+ result |= Qt::Horizontal;
+ return result;
+ }
+
+ void setHeightForWidth(bool b) { data = b ? (data | (1 << 2*HSize)) : (data & ~(1 << 2*HSize)); }
+ bool hasHeightForWidth() const { return data & (1 << 2*HSize); }
+ void setWidthForHeight(bool b) { data = b ? (data | (1 << (WFHShift))) : (data & ~(1 << (WFHShift))); }
+ bool hasWidthForHeight() const { return data & (1 << (WFHShift)); }
+
+ bool operator==(const QSizePolicy& s) const { return data == s.data; }
+ bool operator!=(const QSizePolicy& s) const { return data != s.data; }
+ operator QVariant() const; // implemented in qabstractlayout.cpp
+
+ int horizontalStretch() const { return data >> 24; }
+ int verticalStretch() const { return (data >> 16) & 0xff; }
+ void setHorizontalStretch(uchar stretchFactor) { data = (data&0x00ffffff) | (uint(stretchFactor)<<24); }
+ void setVerticalStretch(uchar stretchFactor) { data = (data&0xff00ffff) | (uint(stretchFactor)<<16); }
+
+ void transpose();
+
+#ifdef QT3_SUPPORT
+ typedef Policy SizeType;
+#ifndef qdoc
+ typedef Qt::Orientations ExpandData;
+ enum {
+ NoDirection = 0,
+ Horizontally = 1,
+ Vertically = 2,
+ BothDirections = Horizontally | Vertically
+ };
+#else
+ enum ExpandData {
+ NoDirection = 0x0,
+ Horizontally = 0x1,
+ Vertically = 0x2,
+ BothDirections = 0x3
+ };
+#endif // qdoc
+
+ inline QT3_SUPPORT bool mayShrinkHorizontally() const
+ { return horizontalPolicy() & ShrinkFlag; }
+ inline QT3_SUPPORT bool mayShrinkVertically() const { return verticalPolicy() & ShrinkFlag; }
+ inline QT3_SUPPORT bool mayGrowHorizontally() const { return horizontalPolicy() & GrowFlag; }
+ inline QT3_SUPPORT bool mayGrowVertically() const { return verticalPolicy() & GrowFlag; }
+ inline QT3_SUPPORT Qt::Orientations expanding() const { return expandingDirections(); }
+
+ QT3_SUPPORT_CONSTRUCTOR QSizePolicy(Policy hor, Policy ver, bool hfw)
+ : data(hor | (ver<<HSize) | (hfw ? (1U<<2*HSize) : 0)) { }
+
+ QT3_SUPPORT_CONSTRUCTOR QSizePolicy(Policy hor, Policy ver, uchar hors, uchar vers, bool hfw = false)
+ : data(hor | (ver<<HSize) | (hfw ? (1U<<2*HSize) : 0)) {
+ setHorizontalStretch(hors);
+ setVerticalStretch(vers);
+ }
+
+ inline QT3_SUPPORT Policy horData() const { return static_cast<Policy>(data & HMask); }
+ inline QT3_SUPPORT Policy verData() const { return static_cast<Policy>((data & VMask) >> HSize); }
+ inline QT3_SUPPORT void setHorData(Policy d) { setHorizontalPolicy(d); }
+ inline QT3_SUPPORT void setVerData(Policy d) { setVerticalPolicy(d); }
+
+ inline QT3_SUPPORT uint horStretch() const { return horizontalStretch(); }
+ inline QT3_SUPPORT uint verStretch() const { return verticalStretch(); }
+ inline QT3_SUPPORT void setHorStretch(uchar sf) { setHorizontalStretch(sf); }
+ inline QT3_SUPPORT void setVerStretch(uchar sf) { setVerticalStretch(sf); }
+#endif
+
+private:
+#ifndef QT_NO_DATASTREAM
+ friend Q_WIDGETS_EXPORT QDataStream &operator<<(QDataStream &, const QSizePolicy &);
+ friend Q_WIDGETS_EXPORT QDataStream &operator>>(QDataStream &, QSizePolicy &);
+#endif
+ QSizePolicy(int i) : data(i) { }
+
+ quint32 data;
+/* Qt5: Use bit flags instead, keep it here for improved readability for now.
+ We can maybe change it for Qt4, but we'd have to be careful, since the behaviour
+ is implementation defined. It usually varies between little- and big-endian compilers, but
+ it might also not vary.
+ quint32 horzPolicy : 4;
+ quint32 vertPolicy : 4;
+ quint32 hfw : 1;
+ quint32 ctype : 5;
+ quint32 wfh : 1;
+ quint32 padding : 1; // we cannot use the highest bit
+ quint32 verStretch : 8;
+ quint32 horStretch : 8;
+*/
+
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QSizePolicy::ControlTypes)
+
+#ifndef QT_NO_DATASTREAM
+// implemented in qlayout.cpp
+Q_WIDGETS_EXPORT QDataStream &operator<<(QDataStream &, const QSizePolicy &);
+Q_WIDGETS_EXPORT QDataStream &operator>>(QDataStream &, QSizePolicy &);
+#endif
+
+inline void QSizePolicy::transpose() {
+ Policy hData = horizontalPolicy();
+ Policy vData = verticalPolicy();
+ uchar hStretch = uchar(horizontalStretch());
+ uchar vStretch = uchar(verticalStretch());
+ setHorizontalPolicy(vData);
+ setVerticalPolicy(hData);
+ setHorizontalStretch(vStretch);
+ setVerticalStretch(hStretch);
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QSIZEPOLICY_H
diff --git a/src/gui/kernel/qsizepolicy.qdoc b/src/widgets/kernel/qsizepolicy.qdoc
index 593560ee7f..593560ee7f 100644
--- a/src/gui/kernel/qsizepolicy.qdoc
+++ b/src/widgets/kernel/qsizepolicy.qdoc
diff --git a/src/gui/kernel/qsoftkeymanager.cpp b/src/widgets/kernel/qsoftkeymanager.cpp
index 7d7c56fe84..7d7c56fe84 100644
--- a/src/gui/kernel/qsoftkeymanager.cpp
+++ b/src/widgets/kernel/qsoftkeymanager.cpp
diff --git a/src/gui/kernel/qsoftkeymanager_common_p.h b/src/widgets/kernel/qsoftkeymanager_common_p.h
index bf4c747223..bf4c747223 100644
--- a/src/gui/kernel/qsoftkeymanager_common_p.h
+++ b/src/widgets/kernel/qsoftkeymanager_common_p.h
diff --git a/src/widgets/kernel/qsoftkeymanager_p.h b/src/widgets/kernel/qsoftkeymanager_p.h
new file mode 100644
index 0000000000..d58b546d74
--- /dev/null
+++ b/src/widgets/kernel/qsoftkeymanager_p.h
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSOFTKEYMANAGER_P_H
+#define QSOFTKEYMANAGER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qobject.h>
+#include "QtWidgets/qaction.h"
+
+QT_BEGIN_HEADER
+
+#ifndef QT_NO_SOFTKEYMANAGER
+QT_BEGIN_NAMESPACE
+
+class QSoftKeyManagerPrivate;
+
+class Q_AUTOTEST_EXPORT QSoftKeyManager : public QObject
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QSoftKeyManager)
+
+public:
+
+ enum StandardSoftKey {
+ OkSoftKey,
+ SelectSoftKey,
+ DoneSoftKey,
+ MenuSoftKey,
+ CancelSoftKey
+ };
+
+ static void updateSoftKeys();
+#ifdef Q_WS_S60
+ static bool handleCommand(int);
+#endif
+
+ static QAction *createAction(StandardSoftKey standardKey, QWidget *actionWidget);
+ static QAction *createKeyedAction(StandardSoftKey standardKey, Qt::Key key, QWidget *actionWidget);
+ static QString standardSoftKeyText(StandardSoftKey standardKey);
+ static void setForceEnabledInSoftkeys(QAction *action);
+ static bool isForceEnabledInSofkeys(QAction *action);
+
+protected:
+ bool event(QEvent *e);
+
+private:
+ QSoftKeyManager();
+ static QSoftKeyManager *instance();
+ bool appendSoftkeys(const QWidget &source, int level);
+ QWidget *softkeySource(QWidget *previousSource, bool& recursiveMerging);
+ bool handleUpdateSoftKeys();
+
+private Q_SLOTS:
+ void cleanupHash(QObject* obj);
+ void sendKeyEvent();
+
+private:
+ Q_DISABLE_COPY(QSoftKeyManager)
+};
+
+QT_END_NAMESPACE
+#endif //QT_NO_SOFTKEYMANAGER
+
+QT_END_HEADER
+
+#endif //QSOFTKEYMANAGER_P_H
diff --git a/src/widgets/kernel/qsound.cpp b/src/widgets/kernel/qsound.cpp
new file mode 100644
index 0000000000..255ff5d86d
--- /dev/null
+++ b/src/widgets/kernel/qsound.cpp
@@ -0,0 +1,367 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qsound.h"
+
+#ifndef QT_NO_SOUND
+
+#include "qlist.h"
+#include <private/qobject_p.h>
+#include "qsound_p.h"
+
+QT_BEGIN_NAMESPACE
+
+static QList<QAuServer*> *servers=0;
+
+QAuServer::QAuServer(QObject* parent)
+ : QObject(parent)
+{
+ if (!servers)
+ servers = new QList<QAuServer*>;
+ servers->prepend(this);
+}
+
+QAuServer::~QAuServer()
+{
+ servers->removeAll(this);
+ if (servers->count() == 0) {
+ delete servers;
+ servers = 0;
+ }
+}
+
+void QAuServer::play(const QString& filename)
+{
+ QSound s(filename);
+ play(&s);
+}
+
+extern QAuServer* qt_new_audio_server();
+
+static QAuServer& server()
+{
+ if (!servers) qt_new_audio_server();
+ return *servers->first();
+}
+
+class QSoundPrivate : public QObjectPrivate
+{
+public:
+ QSoundPrivate(const QString& fname)
+ : filename(fname), bucket(0), looprem(0), looptotal(1)
+ {
+ }
+
+ ~QSoundPrivate()
+ {
+ delete bucket;
+ }
+
+ QString filename;
+ QAuBucket* bucket;
+ int looprem;
+ int looptotal;
+};
+
+/*!
+ \class QSound
+ \brief The QSound class provides access to the platform audio facilities.
+
+ \ingroup multimedia
+
+
+ Qt provides the most commonly required audio operation in GUI
+ applications: asynchronously playing a sound file. This is most
+ easily accomplished using the static play() function:
+
+ \snippet doc/src/snippets/code/src_gui_kernel_qsound.cpp 0
+
+ Alternatively, create a QSound object from the sound file first
+ and then call the play() slot:
+
+ \snippet doc/src/snippets/code/src_gui_kernel_qsound.cpp 1
+
+ Once created a QSound object can be queried for its fileName() and
+ total number of loops() (i.e. the number of times the sound will
+ play). The number of repetitions can be altered using the
+ setLoops() function. While playing the sound, the loopsRemaining()
+ function returns the remaining number of repetitions. Use the
+ isFinished() function to determine whether the sound has finished
+ playing.
+
+ Sounds played using a QSound object may use more memory than the
+ static play() function, but it may also play more immediately
+ (depending on the underlying platform audio facilities). Use the
+ static isAvailable() function to determine whether sound
+ facilities exist on the platform. Which facilities that are
+ actually used varies:
+
+ \table
+ \header \o Platform \o Audio Facility
+ \row
+ \o Microsoft Windows
+ \o The underlying multimedia system is used; only WAVE format sound files
+ are supported.
+ \row
+ \o X11
+ \o The \l{ftp://ftp.x.org/contrib/audio/nas/}{Network Audio System}
+ is used if available, otherwise all operations work silently. NAS
+ supports WAVE and AU files.
+ \row
+ \o Mac OS X
+ \o NSSound is used. All formats that NSSound supports, including QuickTime formats,
+ are supported by Qt for Mac OS X.
+ \row
+ \o Qt for Embedded Linux
+ \o A built-in mixing sound server is used, accessing \c /dev/dsp
+ directly. Only the WAVE format is supported.
+ \row
+ \o Symbian
+ \o CMdaAudioPlayerUtility is used. All formats that Symbian OS or devices support
+ are supported also by Qt.
+ \endtable
+
+ Note that QSound does not support \l{resources.html}{resources}.
+ This might be fixed in a future Qt version.
+*/
+
+/*!
+ Plays the sound stored in the file specified by the given \a filename.
+
+ \sa stop(), loopsRemaining(), isFinished()
+*/
+void QSound::play(const QString& filename)
+{
+ server().play(filename);
+}
+
+/*!
+ Constructs a QSound object from the file specified by the given \a
+ filename and with the given \a parent.
+
+ This may use more memory than the static play() function, but it
+ may also play more immediately (depending on the underlying
+ platform audio facilities).
+
+ \sa play()
+*/
+QSound::QSound(const QString& filename, QObject* parent)
+ : QObject(*new QSoundPrivate(filename), parent)
+{
+ server().init(this);
+}
+
+/*!
+ Destroys this sound object. If the sound is not finished playing,
+ the stop() function is called before the sound object is
+ destructed.
+
+ \sa stop(), isFinished()
+*/
+QSound::~QSound()
+{
+ if (!isFinished())
+ stop();
+}
+
+/*!
+ Returns true if the sound has finished playing; otherwise returns false.
+
+ \warning On Windows this function always returns true for unlooped sounds.
+*/
+bool QSound::isFinished() const
+{
+ Q_D(const QSound);
+ return d->looprem == 0;
+}
+
+/*!
+ \overload
+
+ Starts playing the sound specified by this QSound object.
+
+ The function returns immediately. Depending on the platform audio
+ facilities, other sounds may stop or be mixed with the new
+ sound. The sound can be played again at any time, possibly mixing
+ or replacing previous plays of the sound.
+
+ \sa fileName()
+*/
+void QSound::play()
+{
+ Q_D(QSound);
+ d->looprem = d->looptotal;
+ server().play(this);
+}
+
+/*!
+ Returns the number of times the sound will play.
+
+ \sa loopsRemaining(), setLoops()
+*/
+int QSound::loops() const
+{
+ Q_D(const QSound);
+ return d->looptotal;
+}
+
+/*!
+ Returns the remaining number of times the sound will loop (this
+ value decreases each time the sound is played).
+
+ \sa loops(), isFinished()
+*/
+int QSound::loopsRemaining() const
+{
+ Q_D(const QSound);
+ return d->looprem;
+}
+
+/*!
+ \fn void QSound::setLoops(int number)
+
+ Sets the sound to repeat the given \a number of times when it is
+ played.
+
+ Note that passing the value -1 will cause the sound to loop
+ indefinitely.
+
+ \sa loops()
+*/
+void QSound::setLoops(int n)
+{
+ Q_D(QSound);
+ d->looptotal = n;
+}
+
+/*!
+ Returns the filename associated with this QSound object.
+
+ \sa QSound()
+*/
+QString QSound::fileName() const
+{
+ Q_D(const QSound);
+ return d->filename;
+}
+
+/*!
+ Stops the sound playing.
+
+ Note that on Windows the current loop will finish if a sound is
+ played in a loop.
+
+ \sa play()
+*/
+void QSound::stop()
+{
+ Q_D(QSound);
+ server().stop(this);
+ d->looprem = 0;
+}
+
+
+/*!
+ Returns true if sound facilities exist on the platform; otherwise
+ returns false.
+
+ If no sound is available, all QSound operations work silently and
+ quickly. An application may choose either to notify the user if
+ sound is crucial to the application or to operate silently without
+ bothering the user.
+
+ Note: On Windows this always returns true because some sound card
+ drivers do not implement a way to find out whether it is available
+ or not.
+*/
+bool QSound::isAvailable()
+{
+ return server().okay();
+}
+
+/*!
+ Sets the internal bucket record of sound \a s to \a b, deleting
+ any previous setting.
+*/
+void QAuServer::setBucket(QSound* s, QAuBucket* b)
+{
+ delete s->d_func()->bucket;
+ s->d_func()->bucket = b;
+}
+
+/*!
+ Returns the internal bucket record of sound \a s.
+*/
+QAuBucket* QAuServer::bucket(QSound* s)
+{
+ return s->d_func()->bucket;
+}
+
+/*!
+ Decrements the QSound::loopRemaining() value for sound \a s,
+ returning the result.
+*/
+int QAuServer::decLoop(QSound* s)
+{
+ if (s->d_func()->looprem > 0)
+ --s->d_func()->looprem;
+ return s->d_func()->looprem;
+}
+
+/*!
+ Initializes the sound. The default implementation does nothing.
+*/
+void QAuServer::init(QSound*)
+{
+}
+
+QAuBucket::~QAuBucket()
+{
+}
+/*!
+ \fn bool QSound::available()
+
+ Use the isAvailable() function instead.
+*/
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_SOUND
diff --git a/src/widgets/kernel/qsound.h b/src/widgets/kernel/qsound.h
new file mode 100644
index 0000000000..79fd241948
--- /dev/null
+++ b/src/widgets/kernel/qsound.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSOUND_H
+#define QSOUND_H
+
+#include <QtCore/qobject.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_SOUND
+
+class QSoundPrivate;
+
+class Q_WIDGETS_EXPORT QSound : public QObject
+{
+ Q_OBJECT
+
+public:
+ static bool isAvailable();
+ static void play(const QString& filename);
+
+ explicit QSound(const QString& filename, QObject* parent = 0);
+ ~QSound();
+
+ int loops() const;
+ int loopsRemaining() const;
+ void setLoops(int);
+ QString fileName() const;
+
+ bool isFinished() const;
+
+public Q_SLOTS:
+ void play();
+ void stop();
+
+private:
+ Q_DECLARE_PRIVATE(QSound)
+ friend class QAuServer;
+};
+
+#endif // QT_NO_SOUND
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QSOUND_H
diff --git a/src/gui/kernel/qsound_p.h b/src/widgets/kernel/qsound_p.h
index df7147058b..df7147058b 100644
--- a/src/gui/kernel/qsound_p.h
+++ b/src/widgets/kernel/qsound_p.h
diff --git a/src/gui/kernel/qstackedlayout.cpp b/src/widgets/kernel/qstackedlayout.cpp
index c75f430fb8..c75f430fb8 100644
--- a/src/gui/kernel/qstackedlayout.cpp
+++ b/src/widgets/kernel/qstackedlayout.cpp
diff --git a/src/widgets/kernel/qstackedlayout.h b/src/widgets/kernel/qstackedlayout.h
new file mode 100644
index 0000000000..d895d139ab
--- /dev/null
+++ b/src/widgets/kernel/qstackedlayout.h
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSTACKEDLAYOUT_H
+#define QSTACKEDLAYOUT_H
+
+#include <QtWidgets/qlayout.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QStackedLayoutPrivate;
+
+class Q_WIDGETS_EXPORT QStackedLayout : public QLayout
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QStackedLayout)
+ Q_ENUMS(StackingMode)
+ Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentChanged)
+ Q_PROPERTY(StackingMode stackingMode READ stackingMode WRITE setStackingMode)
+ QDOC_PROPERTY(int count READ count)
+
+public:
+ enum StackingMode {
+ StackOne,
+ StackAll
+ };
+
+ QStackedLayout();
+ explicit QStackedLayout(QWidget *parent);
+ explicit QStackedLayout(QLayout *parentLayout);
+ ~QStackedLayout();
+
+ int addWidget(QWidget *w);
+ int insertWidget(int index, QWidget *w);
+
+ QWidget *currentWidget() const;
+ int currentIndex() const;
+#ifdef Q_NO_USING_KEYWORD
+ inline QWidget *widget() { return QLayout::widget(); }
+#else
+ using QLayout::widget;
+#endif
+ QWidget *widget(int) const;
+ int count() const;
+
+ StackingMode stackingMode() const;
+ void setStackingMode(StackingMode stackingMode);
+
+ // abstract virtual functions:
+ void addItem(QLayoutItem *item);
+ QSize sizeHint() const;
+ QSize minimumSize() const;
+ QLayoutItem *itemAt(int) const;
+ QLayoutItem *takeAt(int);
+ void setGeometry(const QRect &rect);
+
+Q_SIGNALS:
+ void widgetRemoved(int index);
+ void currentChanged(int index);
+
+public Q_SLOTS:
+ void setCurrentIndex(int index);
+ void setCurrentWidget(QWidget *w);
+
+private:
+ Q_DISABLE_COPY(QStackedLayout)
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QSTACKEDLAYOUT_H
diff --git a/src/gui/kernel/qstandardgestures.cpp b/src/widgets/kernel/qstandardgestures.cpp
index a557342023..a557342023 100644
--- a/src/gui/kernel/qstandardgestures.cpp
+++ b/src/widgets/kernel/qstandardgestures.cpp
diff --git a/src/gui/kernel/qstandardgestures_p.h b/src/widgets/kernel/qstandardgestures_p.h
index be30d70058..be30d70058 100644
--- a/src/gui/kernel/qstandardgestures_p.h
+++ b/src/widgets/kernel/qstandardgestures_p.h
diff --git a/src/widgets/kernel/qt_gui_pch.h b/src/widgets/kernel/qt_gui_pch.h
new file mode 100644
index 0000000000..012d92ce8c
--- /dev/null
+++ b/src/widgets/kernel/qt_gui_pch.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*
+ * This is a precompiled header file for use in Xcode / Mac GCC /
+ * GCC >= 3.4 / VC to greatly speed the building of Qt. It may also be
+ * of use to people developing their own project, but it is probably
+ * better to define your own header. Use of this header is currently
+ * UNSUPPORTED.
+ */
+
+// from corelib/global/qt_pch.h
+#if defined __cplusplus
+#include <qglobal.h>
+
+
+#ifdef Q_WS_WIN
+# define _POSIX_
+# include <limits.h>
+# undef _POSIX_
+#endif
+
+#include <qcoreapplication.h>
+#include <qlist.h>
+#include <qvariant.h> // All moc genereated code has this include
+#include <qobject.h>
+#include <qregexp.h>
+#include <qstring.h>
+#include <qstringlist.h>
+#include <qtextcodec.h>
+
+#include <qapplication.h>
+#include <qbitmap.h>
+#include <qcursor.h>
+#include <qdesktopwidget.h>
+#include <qevent.h>
+#include <qimage.h>
+#include <qlayout.h>
+#include <qpainter.h>
+#include <qpixmap.h>
+#include <qstyle.h>
+#include <qtimer.h>
+#include <qwidget.h>
+
+#include <stdlib.h>
+
+#endif
diff --git a/src/gui/kernel/qtooltip.cpp b/src/widgets/kernel/qtooltip.cpp
index f880243a7e..f880243a7e 100644
--- a/src/gui/kernel/qtooltip.cpp
+++ b/src/widgets/kernel/qtooltip.cpp
diff --git a/src/widgets/kernel/qtooltip.h b/src/widgets/kernel/qtooltip.h
new file mode 100644
index 0000000000..52fb962edb
--- /dev/null
+++ b/src/widgets/kernel/qtooltip.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTOOLTIP_H
+#define QTOOLTIP_H
+
+#include <QtWidgets/qwidget.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_TOOLTIP
+
+class Q_WIDGETS_EXPORT QToolTip
+{
+ QToolTip();
+public:
+ static void showText(const QPoint &pos, const QString &text, QWidget *w = 0);
+ static void showText(const QPoint &pos, const QString &text, QWidget *w, const QRect &rect);
+ static inline void hideText() { showText(QPoint(), QString()); }
+
+ static bool isVisible();
+ static QString text();
+
+ static QPalette palette();
+ static void setPalette(const QPalette &);
+ static QFont font();
+ static void setFont(const QFont &);
+#ifdef QT3_SUPPORT
+ static inline QT3_SUPPORT void add(QWidget *w, const QString &s) { w->setToolTip(s); }
+ static inline QT3_SUPPORT void add(QWidget *w, const QRect &, const QString &s)
+ { w->setToolTip(s); }
+ static inline QT3_SUPPORT void remove(QWidget *w) { w->setToolTip(QString()); }
+#endif
+};
+
+#endif // QT_NO_TOOLTIP
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QTOOLTIP_H
diff --git a/src/widgets/kernel/qwhatsthis.cpp b/src/widgets/kernel/qwhatsthis.cpp
new file mode 100644
index 0000000000..204a11a3eb
--- /dev/null
+++ b/src/widgets/kernel/qwhatsthis.cpp
@@ -0,0 +1,777 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwhatsthis.h"
+#ifndef QT_NO_WHATSTHIS
+#include "qpointer.h"
+#include "qapplication.h"
+#include "qdesktopwidget.h"
+#include "qevent.h"
+#include "qpixmap.h"
+#include "qpainter.h"
+#include "qtimer.h"
+#include "qhash.h"
+#include "qaction.h"
+#include "qcursor.h"
+#include "qbitmap.h"
+#include "qtextdocument.h"
+#include "private/qtextdocumentlayout_p.h"
+#include "qtoolbutton.h"
+#include "qdebug.h"
+#ifndef QT_NO_ACCESSIBILITY
+#include "qaccessible.h"
+#endif
+#if defined(Q_WS_WIN)
+#include "qt_windows.h"
+#ifndef SPI_GETDROPSHADOW
+#define SPI_GETDROPSHADOW 0x1024
+#endif
+#endif
+#if defined(Q_WS_X11)
+#include "qx11info_x11.h"
+#include <qwidget.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QWhatsThis
+ \brief The QWhatsThis class provides a simple description of any
+ widget, i.e. answering the question "What's This?".
+
+ \ingroup helpsystem
+
+
+ "What's This?" help is part of an application's online help
+ system, and provides users with information about the
+ functionality and usage of a particular widget. "What's This?"
+ help texts are typically longer and more detailed than \link
+ QToolTip tooltips\endlink, but generally provide less information
+ than that supplied by separate help windows.
+
+ QWhatsThis provides a single window with an explanatory text that
+ pops up when the user asks "What's This?". The default way for
+ users to ask the question is to move the focus to the relevant
+ widget and press Shift+F1. The help text appears immediately; it
+ goes away as soon as the user does something else.
+ (Note that if there is a shortcut for Shift+F1, this mechanism
+ will not work.) Some dialogs provide a "?" button that users can
+ click to enter "What's This?" mode; they then click the relevant
+ widget to pop up the "What's This?" window. It is also possible to
+ provide a a menu option or toolbar button to switch into "What's
+ This?" mode.
+
+ To add "What's This?" text to a widget or an action, you simply
+ call QWidget::setWhatsThis() or QAction::setWhatsThis().
+
+ The text can be either rich text or plain text. If you specify a
+ rich text formatted string, it will be rendered using the default
+ stylesheet, making it possible to embed images in the displayed
+ text. To be as fast as possible, the default stylesheet uses a
+ simple method to determine whether the text can be rendered as
+ plain text. See Qt::mightBeRichText() for details.
+
+ \snippet doc/src/snippets/whatsthis/whatsthis.cpp 0
+
+ An alternative way to enter "What's This?" mode is to call
+ createAction(), and add the returned QAction to either a menu or
+ a tool bar. By invoking this context help action (in the picture
+ below, the button with the arrow and question mark icon) the user
+ switches into "What's This?" mode. If they now click on a widget
+ the appropriate help text is shown. The mode is left when help is
+ given or when the user presses Esc.
+
+ \img whatsthis.png
+
+ You can enter "What's This?" mode programmatically with
+ enterWhatsThisMode(), check the mode with inWhatsThisMode(), and
+ return to normal mode with leaveWhatsThisMode().
+
+ If you want to control the "What's This?" behavior of a widget
+ manually see Qt::WA_CustomWhatsThis.
+
+ It is also possible to show different help texts for different
+ regions of a widget, by using a QHelpEvent of type
+ QEvent::WhatsThis. Intercept the help event in your widget's
+ QWidget::event() function and call QWhatsThis::showText() with the
+ text you want to display for the position specified in
+ QHelpEvent::pos(). If the text is rich text and the user clicks
+ on a link, the widget also receives a QWhatsThisClickedEvent with
+ the link's reference as QWhatsThisClickedEvent::href(). If a
+ QWhatsThisClickedEvent is handled (i.e. QWidget::event() returns
+ true), the help window remains visible. Call
+ QWhatsThis::hideText() to hide it explicitly.
+
+ \sa QToolTip
+*/
+
+Q_CORE_EXPORT void qDeleteInEventHandler(QObject *o);
+
+class QWhatsThat : public QWidget
+{
+ Q_OBJECT
+
+public:
+ QWhatsThat(const QString& txt, QWidget* parent, QWidget *showTextFor);
+ ~QWhatsThat() ;
+
+ static QWhatsThat *instance;
+
+protected:
+ void showEvent(QShowEvent *e);
+ void mousePressEvent(QMouseEvent*);
+ void mouseReleaseEvent(QMouseEvent*);
+ void mouseMoveEvent(QMouseEvent*);
+ void keyPressEvent(QKeyEvent*);
+ void paintEvent(QPaintEvent*);
+
+private:
+ QPointer<QWidget>widget;
+ bool pressed;
+ QString text;
+ QTextDocument* doc;
+ QString anchor;
+ QPixmap background;
+};
+
+QWhatsThat *QWhatsThat::instance = 0;
+
+// shadowWidth not const, for XP drop-shadow-fu turns it to 0
+static int shadowWidth = 6; // also used as '5' and '6' and even '8' below
+static const int vMargin = 8;
+static const int hMargin = 12;
+
+QWhatsThat::QWhatsThat(const QString& txt, QWidget* parent, QWidget *showTextFor)
+ : QWidget(parent, Qt::Popup),
+ widget(showTextFor), pressed(false), text(txt)
+{
+ delete instance;
+ instance = this;
+ setAttribute(Qt::WA_DeleteOnClose, true);
+ setAttribute(Qt::WA_NoSystemBackground, true);
+ if (parent)
+ setPalette(parent->palette());
+ setMouseTracking(true);
+ setFocusPolicy(Qt::StrongFocus);
+#ifndef QT_NO_CURSOR
+ setCursor(Qt::ArrowCursor);
+#endif
+ QRect r;
+ doc = 0;
+ ensurePolished(); // Ensures style sheet font before size calc
+ if (Qt::mightBeRichText(text)) {
+ doc = new QTextDocument();
+ doc->setUndoRedoEnabled(false);
+ doc->setDefaultFont(QApplication::font(this));
+#ifdef QT_NO_TEXTHTMLPARSER
+ doc->setPlainText(text);
+#else
+ doc->setHtml(text);
+#endif
+ doc->setUndoRedoEnabled(false);
+ doc->adjustSize();
+ r.setTop(0);
+ r.setLeft(0);
+ r.setSize(doc->size().toSize());
+ }
+ else
+ {
+ int sw = QApplication::desktop()->width() / 3;
+ if (sw < 200)
+ sw = 200;
+ else if (sw > 300)
+ sw = 300;
+
+ r = fontMetrics().boundingRect(0, 0, sw, 1000,
+ Qt::AlignLeft + Qt::AlignTop
+ + Qt::TextWordWrap + Qt::TextExpandTabs,
+ text);
+ }
+#if defined(Q_WS_WIN)
+ if ((QSysInfo::WindowsVersion >= QSysInfo::WV_XP
+ && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based))
+ {
+ BOOL shadow;
+ SystemParametersInfo(SPI_GETDROPSHADOW, 0, &shadow, 0);
+ shadowWidth = shadow ? 0 : 6;
+ }
+#endif
+ resize(r.width() + 2*hMargin + shadowWidth, r.height() + 2*vMargin + shadowWidth);
+}
+
+QWhatsThat::~QWhatsThat()
+{
+ instance = 0;
+ if (doc)
+ delete doc;
+}
+
+void QWhatsThat::showEvent(QShowEvent *)
+{
+ background = QPixmap::grabWindow(QApplication::desktop()->internalWinId(),
+ x(), y(), width(), height());
+}
+
+void QWhatsThat::mousePressEvent(QMouseEvent* e)
+{
+ pressed = true;
+ if (e->button() == Qt::LeftButton && rect().contains(e->pos())) {
+ if (doc)
+ anchor = doc->documentLayout()->anchorAt(e->pos() - QPoint(hMargin, vMargin));
+ return;
+ }
+ close();
+}
+
+void QWhatsThat::mouseReleaseEvent(QMouseEvent* e)
+{
+ if (!pressed)
+ return;
+ if (widget && e->button() == Qt::LeftButton && doc && rect().contains(e->pos())) {
+ QString a = doc->documentLayout()->anchorAt(e->pos() - QPoint(hMargin, vMargin));
+ QString href;
+ if (anchor == a)
+ href = a;
+ anchor.clear();
+ if (!href.isEmpty()) {
+ QWhatsThisClickedEvent e(href);
+ if (QApplication::sendEvent(widget, &e))
+ return;
+ }
+ }
+ close();
+}
+
+void QWhatsThat::mouseMoveEvent(QMouseEvent* e)
+{
+#ifdef QT_NO_CURSOR
+ Q_UNUSED(e);
+#else
+ if (!doc)
+ return;
+ QString a = doc->documentLayout()->anchorAt(e->pos() - QPoint(hMargin, vMargin));
+ if (!a.isEmpty())
+ setCursor(Qt::PointingHandCursor);
+ else
+ setCursor(Qt::ArrowCursor);
+#endif
+}
+
+void QWhatsThat::keyPressEvent(QKeyEvent*)
+{
+ close();
+}
+
+void QWhatsThat::paintEvent(QPaintEvent*)
+{
+ bool drawShadow = true;
+#if defined(Q_WS_WIN)
+ if ((QSysInfo::WindowsVersion >= QSysInfo::WV_XP
+ && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based))
+ {
+ BOOL shadow;
+ SystemParametersInfo(SPI_GETDROPSHADOW, 0, &shadow, 0);
+ drawShadow = !shadow;
+ }
+#elif defined(Q_WS_MAC) || defined(Q_WS_QWS)
+ drawShadow = false; // never draw it on OS X or QWS, as we get it for free
+#endif
+
+ QRect r = rect();
+ r.adjust(0, 0, -1, -1);
+ if (drawShadow)
+ r.adjust(0, 0, -shadowWidth, -shadowWidth);
+ QPainter p(this);
+ p.drawPixmap(0, 0, background);
+ p.setPen(QPen(palette().toolTipText(), 0));
+ p.setBrush(palette().toolTipBase());
+ p.drawRect(r);
+ int w = r.width();
+ int h = r.height();
+ p.setPen(palette().brush(QPalette::Dark).color());
+ p.drawRect(1, 1, w-2, h-2);
+ if (drawShadow) {
+ p.setPen(palette().shadow().color());
+ p.drawPoint(w + 5, 6);
+ p.drawLine(w + 3, 6, w + 5, 8);
+ p.drawLine(w + 1, 6, w + 5, 10);
+ int i;
+ for(i=7; i < h; i += 2)
+ p.drawLine(w, i, w + 5, i + 5);
+ for(i = w - i + h; i > 6; i -= 2)
+ p.drawLine(i, h, i + 5, h + 5);
+ for(; i > 0 ; i -= 2)
+ p.drawLine(6, h + 6 - i, i + 5, h + 5);
+ }
+ r.adjust(0, 0, 1, 1);
+ p.setPen(palette().toolTipText().color());
+ r.adjust(hMargin, vMargin, -hMargin, -vMargin);
+
+ if (doc) {
+ p.translate(r.x(), r.y());
+ QRect rect = r;
+ rect.translate(-r.x(), -r.y());
+ p.setClipRect(rect);
+ QAbstractTextDocumentLayout::PaintContext context;
+ context.palette.setBrush(QPalette::Text, context.palette.toolTipText());
+ doc->documentLayout()->draw(&p, context);
+ }
+ else
+ {
+ p.drawText(r, Qt::AlignLeft + Qt::AlignTop + Qt::TextWordWrap + Qt::TextExpandTabs, text);
+ }
+}
+
+static const char * const button_image[] = {
+"16 16 3 1",
+" c None",
+"o c #000000",
+"a c #000080",
+"o aaaaa ",
+"oo aaa aaa ",
+"ooo aaa aaa",
+"oooo aa aa",
+"ooooo aa aa",
+"oooooo a aaa",
+"ooooooo aaa ",
+"oooooooo aaa ",
+"ooooooooo aaa ",
+"ooooo aaa ",
+"oo ooo ",
+"o ooo aaa ",
+" ooo aaa ",
+" ooo ",
+" ooo ",
+" ooo "};
+
+class QWhatsThisPrivate : public QObject
+{
+ public:
+ QWhatsThisPrivate();
+ ~QWhatsThisPrivate();
+ static QWhatsThisPrivate *instance;
+ bool eventFilter(QObject *, QEvent *);
+ QPointer<QAction> action;
+#ifdef QT3_SUPPORT
+ QPointer<QToolButton> button;
+#endif
+ static void say(QWidget *, const QString &, int x = 0, int y = 0);
+ static void notifyToplevels(QEvent *e);
+ bool leaveOnMouseRelease;
+};
+
+void QWhatsThisPrivate::notifyToplevels(QEvent *e)
+{
+ QWidgetList toplevels = QApplication::topLevelWidgets();
+ for (int i = 0; i < toplevels.count(); ++i) {
+ register QWidget *w = toplevels.at(i);
+ QApplication::sendEvent(w, e);
+ }
+}
+
+QWhatsThisPrivate *QWhatsThisPrivate::instance = 0;
+
+QWhatsThisPrivate::QWhatsThisPrivate()
+ : leaveOnMouseRelease(false)
+{
+ instance = this;
+ qApp->installEventFilter(this);
+
+ QPoint pos = QCursor::pos();
+ if (QWidget *w = QApplication::widgetAt(pos)) {
+ QHelpEvent e(QEvent::QueryWhatsThis, w->mapFromGlobal(pos), pos);
+ bool sentEvent = QApplication::sendEvent(w, &e);
+#ifdef QT_NO_CURSOR
+ Q_UNUSED(sentEvent);
+#else
+ QApplication::setOverrideCursor((!sentEvent || !e.isAccepted())?
+ Qt::ForbiddenCursor:Qt::WhatsThisCursor);
+ } else {
+ QApplication::setOverrideCursor(Qt::WhatsThisCursor);
+#endif
+ }
+#ifndef QT_NO_ACCESSIBILITY
+ QAccessible::updateAccessibility(this, 0, QAccessible::ContextHelpStart);
+#endif
+}
+
+QWhatsThisPrivate::~QWhatsThisPrivate()
+{
+ if (action)
+ action->setChecked(false);
+#ifdef QT3_SUPPORT
+ if (button)
+ button->setChecked(false);
+#endif
+#ifndef QT_NO_CURSOR
+ QApplication::restoreOverrideCursor();
+#endif
+#ifndef QT_NO_ACCESSIBILITY
+ QAccessible::updateAccessibility(this, 0, QAccessible::ContextHelpEnd);
+#endif
+ instance = 0;
+}
+
+bool QWhatsThisPrivate::eventFilter(QObject *o, QEvent *e)
+{
+ if (!o->isWidgetType())
+ return false;
+ QWidget * w = static_cast<QWidget *>(o);
+ bool customWhatsThis = w->testAttribute(Qt::WA_CustomWhatsThis);
+ switch (e->type()) {
+ case QEvent::MouseButtonPress:
+ {
+ QMouseEvent *me = static_cast<QMouseEvent*>(e);
+ if (me->button() == Qt::RightButton || customWhatsThis)
+ return false;
+ QHelpEvent e(QEvent::WhatsThis, me->pos(), me->globalPos());
+ if (!QApplication::sendEvent(w, &e) || !e.isAccepted())
+ leaveOnMouseRelease = true;
+
+ } break;
+
+ case QEvent::MouseMove:
+ {
+ QMouseEvent *me = static_cast<QMouseEvent*>(e);
+ QHelpEvent e(QEvent::QueryWhatsThis, me->pos(), me->globalPos());
+ bool sentEvent = QApplication::sendEvent(w, &e);
+#ifdef QT_NO_CURSOR
+ Q_UNUSED(sentEvent);
+#else
+ QApplication::changeOverrideCursor((!sentEvent || !e.isAccepted())?
+ Qt::ForbiddenCursor:Qt::WhatsThisCursor);
+#endif
+ }
+ // fall through
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseButtonDblClick:
+ if (leaveOnMouseRelease && e->type() == QEvent::MouseButtonRelease)
+ QWhatsThis::leaveWhatsThisMode();
+ if (static_cast<QMouseEvent*>(e)->button() == Qt::RightButton || customWhatsThis)
+ return false; // ignore RMB release
+ break;
+ case QEvent::KeyPress:
+ {
+ QKeyEvent* kev = (QKeyEvent*)e;
+
+ if (kev->key() == Qt::Key_Escape) {
+ QWhatsThis::leaveWhatsThisMode();
+ return true;
+ } else if (customWhatsThis) {
+ return false;
+ } else if (kev->key() == Qt::Key_Menu ||
+ (kev->key() == Qt::Key_F10 &&
+ kev->modifiers() == Qt::ShiftModifier)) {
+ // we don't react to these keys, they are used for context menus
+ return false;
+ } else if (kev->key() != Qt::Key_Shift && kev->key() != Qt::Key_Alt // not a modifier key
+ && kev->key() != Qt::Key_Control && kev->key() != Qt::Key_Meta) {
+ QWhatsThis::leaveWhatsThisMode();
+ }
+ } break;
+ default:
+ return false;
+ }
+ return true;
+}
+
+class QWhatsThisAction: public QAction
+{
+ Q_OBJECT
+
+public:
+ explicit QWhatsThisAction(QObject* parent = 0);
+
+private slots:
+ void actionTriggered();
+};
+
+QWhatsThisAction::QWhatsThisAction(QObject *parent) : QAction(tr("What's This?"), parent)
+{
+#ifndef QT_NO_IMAGEFORMAT_XPM
+ QPixmap p((const char**)button_image);
+ setIcon(p);
+#endif
+ setCheckable(true);
+ connect(this, SIGNAL(triggered()), this, SLOT(actionTriggered()));
+#ifndef QT_NO_SHORTCUT
+ setShortcut(Qt::ShiftModifier + Qt::Key_F1);
+#endif
+}
+
+void QWhatsThisAction::actionTriggered()
+{
+ if (isChecked()) {
+ QWhatsThis::enterWhatsThisMode();
+ QWhatsThisPrivate::instance->action = this;
+ }
+}
+
+QWhatsThis::QWhatsThis()
+{
+}
+
+#ifdef QT3_SUPPORT
+/*!
+ \obsolete
+
+ Sets the What's This text \a s for the widget \a w.
+
+ Use QWidget::setWhatsThis() or QAction::setWhatsThis() instead.
+*/
+void QWhatsThis::add(QWidget *w, const QString &s)
+{
+ w->setWhatsThis(s);
+}
+
+/*!
+ \obsolete
+
+ Remove's the What's This text for the widget \a w.
+
+ Use QWidget::setWhatsThis() or QAction::setWhatsThis() instead.
+*/
+void QWhatsThis::remove(QWidget *w)
+{
+ w->setWhatsThis(QString());
+}
+
+class QWhatsThisButton : public QToolButton
+{
+ Q_OBJECT
+public:
+ QWhatsThisButton(QWidget *p) : QToolButton(p) {
+ setCheckable(true);
+ QPixmap pix( const_cast<const char**>(button_image) );
+ setIcon( pix );
+ QObject::connect(this, SIGNAL(toggled(bool)), this, SLOT(whatToggled(bool)));
+ setAutoRaise(true);
+ setFocusPolicy(Qt::NoFocus);
+ }
+
+public slots:
+ void whatToggled(bool b) {
+ if (b) {
+ QWhatsThis::enterWhatsThisMode();
+ QWhatsThisPrivate::instance->button = this;
+ }
+ }
+};
+
+/*!
+ Returns a new "What's This?" QToolButton with the given \a
+ parent. To do this now, create your own QToolButton and a
+ QWhatsThis object and call the QWhatsThis object's showText()
+ function when the QToolButton is invoked.
+
+ Use createAction() instead.
+*/
+QToolButton * QWhatsThis::whatsThisButton(QWidget * parent)
+{
+ return new QWhatsThisButton(parent);
+}
+#endif
+
+/*!
+ This function switches the user interface into "What's This?"
+ mode. The user interface can be switched back into normal mode by
+ the user (e.g. by them clicking or pressing Esc), or
+ programmatically by calling leaveWhatsThisMode().
+
+ When entering "What's This?" mode, a QEvent of type
+ Qt::EnterWhatsThisMode is sent to all toplevel widgets.
+
+ \sa inWhatsThisMode() leaveWhatsThisMode()
+*/
+void QWhatsThis::enterWhatsThisMode()
+{
+ if (QWhatsThisPrivate::instance)
+ return;
+ (void) new QWhatsThisPrivate;
+ QEvent e(QEvent::EnterWhatsThisMode);
+ QWhatsThisPrivate::notifyToplevels(&e);
+ }
+
+/*!
+ Returns true if the user interface is in "What's This?" mode;
+ otherwise returns false.
+
+ \sa enterWhatsThisMode()
+*/
+bool QWhatsThis::inWhatsThisMode()
+{
+ return (QWhatsThisPrivate::instance != 0);
+}
+
+/*!
+ If the user interface is in "What's This?" mode, this function
+ switches back to normal mode; otherwise it does nothing.
+
+ When leaving "What's This?" mode, a QEvent of type
+ Qt::LeaveWhatsThisMode is sent to all toplevel widgets.
+
+ \sa enterWhatsThisMode() inWhatsThisMode()
+*/
+void QWhatsThis::leaveWhatsThisMode()
+{
+ delete QWhatsThisPrivate::instance;
+ QEvent e(QEvent::LeaveWhatsThisMode);
+ QWhatsThisPrivate::notifyToplevels(&e);
+}
+
+void QWhatsThisPrivate::say(QWidget * widget, const QString &text, int x, int y)
+{
+ if (text.size() == 0)
+ return;
+ // make a fresh widget, and set it up
+ QWhatsThat *whatsThat = new QWhatsThat(
+ text,
+#if defined(Q_WS_X11) && !defined(QT_NO_CURSOR)
+ QApplication::desktop()->screen(widget ? widget->x11Info().screen() : QCursor::x11Screen()),
+#else
+ 0,
+#endif
+ widget
+ );
+
+
+ // okay, now to find a suitable location
+
+ int scr = (widget ?
+ QApplication::desktop()->screenNumber(widget) :
+#if defined(Q_WS_X11) && !defined(QT_NO_CURSOR)
+ QCursor::x11Screen()
+#else
+ QApplication::desktop()->screenNumber(QPoint(x,y))
+#endif // Q_WS_X11
+ );
+ QRect screen = QApplication::desktop()->screenGeometry(scr);
+
+ int w = whatsThat->width();
+ int h = whatsThat->height();
+ int sx = screen.x();
+ int sy = screen.y();
+
+ // first try locating the widget immediately above/below,
+ // with nice alignment if possible.
+ QPoint pos;
+ if (widget)
+ pos = widget->mapToGlobal(QPoint(0,0));
+
+ if (widget && w > widget->width() + 16)
+ x = pos.x() + widget->width()/2 - w/2;
+ else
+ x = x - w/2;
+
+ // squeeze it in if that would result in part of what's this
+ // being only partially visible
+ if (x + w + shadowWidth > sx+screen.width())
+ x = (widget? (qMin(screen.width(),
+ pos.x() + widget->width())
+ ) : screen.width())
+ - w;
+
+ if (x < sx)
+ x = sx;
+
+ if (widget && h > widget->height() + 16) {
+ y = pos.y() + widget->height() + 2; // below, two pixels spacing
+ // what's this is above or below, wherever there's most space
+ if (y + h + 10 > sy+screen.height())
+ y = pos.y() + 2 - shadowWidth - h; // above, overlap
+ }
+ y = y + 2;
+
+ // squeeze it in if that would result in part of what's this
+ // being only partially visible
+ if (y + h + shadowWidth > sy+screen.height())
+ y = (widget ? (qMin(screen.height(),
+ pos.y() + widget->height())
+ ) : screen.height())
+ - h;
+ if (y < sy)
+ y = sy;
+
+ whatsThat->move(x, y);
+ whatsThat->show();
+ whatsThat->grabKeyboard();
+}
+
+/*!
+ Shows \a text as a "What's This?" window, at global position \a
+ pos. The optional widget argument, \a w, is used to determine the
+ appropriate screen on multi-head systems.
+
+ \sa hideText()
+*/
+void QWhatsThis::showText(const QPoint &pos, const QString &text, QWidget *w)
+{
+ leaveWhatsThisMode();
+ QWhatsThisPrivate::say(w, text, pos.x(), pos.y());
+}
+
+/*!
+ If a "What's This?" window is showing, this destroys it.
+
+ \sa showText()
+*/
+void QWhatsThis::hideText()
+{
+ qDeleteInEventHandler(QWhatsThat::instance);
+}
+
+/*!
+ Returns a ready-made QAction, used to invoke "What's This?" context
+ help, with the given \a parent.
+
+ The returned QAction provides a convenient way to let users enter
+ "What's This?" mode.
+*/
+QAction *QWhatsThis::createAction(QObject *parent)
+{
+ return new QWhatsThisAction(parent);
+}
+
+QT_END_NAMESPACE
+
+#include "qwhatsthis.moc"
+
+#endif // QT_NO_WHATSTHIS
diff --git a/src/widgets/kernel/qwhatsthis.h b/src/widgets/kernel/qwhatsthis.h
new file mode 100644
index 0000000000..b975b78e3e
--- /dev/null
+++ b/src/widgets/kernel/qwhatsthis.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWHATSTHIS_H
+#define QWHATSTHIS_H
+
+#include <QtCore/qobject.h>
+#include <QtGui/qcursor.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_WHATSTHIS
+
+class QAction;
+#ifdef QT3_SUPPORT
+class QToolButton;
+#endif
+
+class Q_WIDGETS_EXPORT QWhatsThis
+{
+ QWhatsThis();
+
+public:
+ static void enterWhatsThisMode();
+ static bool inWhatsThisMode();
+ static void leaveWhatsThisMode();
+
+ static void showText(const QPoint &pos, const QString &text, QWidget *w = 0);
+ static void hideText();
+
+ static QAction *createAction(QObject *parent = 0);
+
+#ifdef QT3_SUPPORT
+ static QT3_SUPPORT void add(QWidget *w, const QString &s);
+ static QT3_SUPPORT void remove(QWidget *);
+ static QT3_SUPPORT QToolButton *whatsThisButton(QWidget *parent);
+#endif
+};
+
+#endif // QT_NO_WHATSTHIS
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QWHATSTHIS_H
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
new file mode 100644
index 0000000000..76544d2524
--- /dev/null
+++ b/src/widgets/kernel/qwidget.cpp
@@ -0,0 +1,12610 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qapplication.h"
+#include "qapplication_p.h"
+#include "qbrush.h"
+#include "qcursor.h"
+#include "qdesktopwidget.h"
+#include "qevent.h"
+#include "qhash.h"
+#include "qlayout.h"
+#include "qmenu.h"
+#include "qmetaobject.h"
+#include "qpixmap.h"
+#include "qpointer.h"
+#include "qstack.h"
+#include "qstyle.h"
+#include "qstylefactory.h"
+#include "qvariant.h"
+#include "qwidget.h"
+#include "qstyleoption.h"
+#ifndef QT_NO_ACCESSIBILITY
+# include "qaccessible.h"
+#endif
+#if defined(Q_WS_WIN)
+# include "qt_windows.h"
+#endif
+#ifdef Q_WS_MAC
+# include "qt_mac_p.h"
+# include "qt_cocoa_helpers_mac_p.h"
+# include "qmainwindow.h"
+# include "qtoolbar.h"
+# include <private/qmainwindowlayout_p.h>
+#endif
+#if defined(Q_WS_QPA)
+#include "qplatformwindow_qpa.h"
+#include "private/qwidgetwindow_qpa_p.h"
+#endif
+#include "qpainter.h"
+#include "qtooltip.h"
+#include "qwhatsthis.h"
+#include "qdebug.h"
+#include "private/qstylesheetstyle_p.h"
+#include "private/qstyle_p.h"
+#include "qinputcontext.h"
+#include "qfileinfo.h"
+#include "private/qsoftkeymanager_p.h"
+#include <QtGui/qinputpanel.h>
+
+#include <private/qgraphicseffect_p.h>
+#include <qbackingstore.h>
+#include <private/qwidgetbackingstore_p.h>
+#ifdef Q_WS_MAC
+# include <private/qpaintengine_mac_p.h>
+#endif
+#include <private/qpaintengine_raster_p.h>
+
+#if defined(Q_OS_SYMBIAN)
+#include "private/qt_s60_p.h"
+#endif
+
+#include "qwidget_p.h"
+#include "qaction_p.h"
+#include "qlayout_p.h"
+#include "QtWidgets/qgraphicsproxywidget.h"
+#include "QtWidgets/qgraphicsscene.h"
+#include "private/qgraphicsproxywidget_p.h"
+#include "QtWidgets/qabstractscrollarea.h"
+#include "private/qabstractscrollarea_p.h"
+#include "private/qevent_p.h"
+
+#include "private/qgesturemanager_p.h"
+
+#ifdef QT_KEYPAD_NAVIGATION
+#include "qtabwidget.h" // Needed in inTabWidget()
+#endif // QT_KEYPAD_NAVIGATION
+
+#ifdef Q_WS_S60
+#include <aknappui.h>
+#endif
+
+// widget/widget data creation count
+//#define QWIDGET_EXTRA_DEBUG
+//#define ALIEN_DEBUG
+
+QT_BEGIN_NAMESPACE
+
+static bool qt_enable_backingstore = true;
+#ifdef Q_WS_X11
+// for compatibility with Qt 4.0
+Q_WIDGETS_EXPORT void qt_x11_set_global_double_buffer(bool enable)
+{
+ qt_enable_backingstore = enable;
+}
+#endif
+
+#if defined(QT_MAC_USE_COCOA)
+bool qt_mac_clearDirtyOnWidgetInsideDrawWidget = false;
+#endif
+
+static inline bool qRectIntersects(const QRect &r1, const QRect &r2)
+{
+ return (qMax(r1.left(), r2.left()) <= qMin(r1.right(), r2.right()) &&
+ qMax(r1.top(), r2.top()) <= qMin(r1.bottom(), r2.bottom()));
+}
+
+static inline bool hasBackingStoreSupport()
+{
+ return true;
+}
+
+#ifdef Q_WS_MAC
+# define QT_NO_PAINT_DEBUG
+#endif
+
+extern bool qt_sendSpontaneousEvent(QObject*, QEvent*); // qapplication.cpp
+extern QDesktopWidget *qt_desktopWidget; // qapplication.cpp
+
+/*!
+ \internal
+ \class QWidgetBackingStoreTracker
+ \brief Class which allows tracking of which widgets are using a given backing store
+
+ QWidgetBackingStoreTracker is a thin wrapper around a QWidgetBackingStore pointer,
+ which maintains a list of the QWidgets which are currently using the backing
+ store. This list is modified via the registerWidget and unregisterWidget functions.
+ */
+
+QWidgetBackingStoreTracker::QWidgetBackingStoreTracker()
+ : m_ptr(0)
+{
+
+}
+
+QWidgetBackingStoreTracker::~QWidgetBackingStoreTracker()
+{
+ delete m_ptr;
+}
+
+/*!
+ \internal
+ Destroy the contained QWidgetBackingStore, if not null, and clear the list of
+ widgets using the backing store, then create a new QWidgetBackingStore, providing
+ the QWidget.
+ */
+void QWidgetBackingStoreTracker::create(QWidget *widget)
+{
+ destroy();
+ m_ptr = new QWidgetBackingStore(widget);
+}
+
+/*!
+ \internal
+ Destroy the contained QWidgetBackingStore, if not null, and clear the list of
+ widgets using the backing store.
+ */
+void QWidgetBackingStoreTracker::destroy()
+{
+ delete m_ptr;
+ m_ptr = 0;
+ m_widgets.clear();
+}
+
+/*!
+ \internal
+ Add the widget to the list of widgets currently using the backing store.
+ If the widget was already in the list, this function is a no-op.
+ */
+void QWidgetBackingStoreTracker::registerWidget(QWidget *w)
+{
+ Q_ASSERT(m_ptr);
+ Q_ASSERT(w->internalWinId());
+ Q_ASSERT(qt_widget_private(w)->maybeBackingStore() == m_ptr);
+ m_widgets.insert(w);
+}
+
+/*!
+ \internal
+ Remove the widget from the list of widgets currently using the backing store.
+ If the widget was in the list, and removing it causes the list to be empty,
+ the backing store is deleted.
+ If the widget was not in the list, this function is a no-op.
+ */
+void QWidgetBackingStoreTracker::unregisterWidget(QWidget *w)
+{
+ if (m_widgets.remove(w) && m_widgets.isEmpty()) {
+ delete m_ptr;
+ m_ptr = 0;
+ }
+}
+
+/*!
+ \internal
+ Recursively remove widget and all of its descendents.
+ */
+void QWidgetBackingStoreTracker::unregisterWidgetSubtree(QWidget *widget)
+{
+ unregisterWidget(widget);
+ foreach (QObject *child, widget->children())
+ if (QWidget *childWidget = qobject_cast<QWidget *>(child))
+ unregisterWidgetSubtree(childWidget);
+}
+
+QWidgetPrivate::QWidgetPrivate(int version)
+ : QObjectPrivate(version)
+ , extra(0)
+ , focus_next(0)
+ , focus_prev(0)
+ , focus_child(0)
+ , layout(0)
+ , needsFlush(0)
+ , redirectDev(0)
+ , widgetItem(0)
+ , extraPaintEngine(0)
+ , polished(0)
+ , graphicsEffect(0)
+#if !defined(QT_NO_IM)
+ , imHints(Qt::ImhNone)
+#endif
+ , inheritedFontResolveMask(0)
+ , inheritedPaletteResolveMask(0)
+ , leftmargin(0)
+ , topmargin(0)
+ , rightmargin(0)
+ , bottommargin(0)
+ , leftLayoutItemMargin(0)
+ , topLayoutItemMargin(0)
+ , rightLayoutItemMargin(0)
+ , bottomLayoutItemMargin(0)
+ , hd(0)
+ , size_policy(QSizePolicy::Preferred, QSizePolicy::Preferred)
+ , fg_role(QPalette::NoRole)
+ , bg_role(QPalette::NoRole)
+ , dirtyOpaqueChildren(1)
+ , isOpaque(0)
+ , inDirtyList(0)
+ , isScrolled(0)
+ , isMoved(0)
+ , isGLWidget(0)
+ , usesDoubleBufferedGLContext(0)
+#ifndef QT_NO_IM
+ , inheritsInputMethodHints(0)
+#endif
+ , inSetParent(0)
+#if defined(Q_WS_X11)
+ , picture(0)
+#elif defined(Q_WS_WIN)
+ , noPaintOnScreen(0)
+ #ifndef QT_NO_GESTURES
+ , nativeGesturePanEnabled(0)
+ #endif
+#elif defined(Q_WS_MAC)
+ , needWindowChange(0)
+ , window_event(0)
+ , qd_hd(0)
+#elif defined(Q_OS_SYMBIAN)
+ , symbianScreenNumber(0)
+ , fixNativeOrientationCalled(false)
+#endif
+{
+ if (!qApp) {
+ qFatal("QWidget: Must construct a QApplication before a QPaintDevice");
+ return;
+ }
+
+ if (version != QObjectPrivateVersion)
+ qFatal("Cannot mix incompatible Qt libraries");
+
+ isWidget = true;
+ memset(high_attributes, 0, sizeof(high_attributes));
+#if QT_MAC_USE_COCOA
+ drawRectOriginalAdded = false;
+ originalDrawMethod = true;
+ changeMethods = false;
+ isInUnifiedToolbar = false;
+ unifiedSurface = 0;
+ toolbar_ancestor = 0;
+ flushRequested = false;
+ touchEventsEnabled = false;
+#endif // QT_MAC_USE_COCOA
+#ifdef QWIDGET_EXTRA_DEBUG
+ static int count = 0;
+ qDebug() << "widgets" << ++count;
+#endif
+}
+
+
+QWidgetPrivate::~QWidgetPrivate()
+{
+ if (widgetItem)
+ widgetItem->wid = 0;
+
+ if (extra)
+ deleteExtra();
+
+#ifndef QT_NO_GRAPHICSEFFECT
+ delete graphicsEffect;
+#endif //QT_NO_GRAPHICSEFFECT
+}
+
+/*!
+ \internal
+*/
+void QWidgetPrivate::scrollChildren(int dx, int dy)
+{
+ Q_Q(QWidget);
+ if (q->children().size() > 0) { // scroll children
+ QPoint pd(dx, dy);
+ QObjectList childObjects = q->children();
+ for (int i = 0; i < childObjects.size(); ++i) { // move all children
+ QWidget *w = qobject_cast<QWidget*>(childObjects.at(i));
+ if (w && !w->isWindow()) {
+ QPoint oldp = w->pos();
+ QRect r(w->pos() + pd, w->size());
+ w->data->crect = r;
+ if (w->testAttribute(Qt::WA_WState_Created))
+ w->d_func()->setWSGeometry();
+ w->d_func()->setDirtyOpaqueRegion();
+ QMoveEvent e(r.topLeft(), oldp);
+ QApplication::sendEvent(w, &e);
+ }
+ }
+ }
+}
+
+void QWidgetPrivate::updateWidgetTransform()
+{
+ Q_Q(QWidget);
+ if (q == qApp->inputPanel()->inputItem()) {
+ QTransform t;
+ QPoint p = q->mapTo(q->topLevelWidget(), QPoint(0,0));
+ t.translate(p.x(), p.y());
+ qApp->inputPanel()->setInputItemTransform(t);
+ }
+}
+
+QInputContext *QWidgetPrivate::assignedInputContext() const
+{
+#ifndef QT_NO_IM
+ const QWidget *widget = q_func();
+ while (widget) {
+ if (QInputContext *qic = widget->d_func()->ic)
+ return qic;
+ widget = widget->parentWidget();
+ }
+#endif
+ return 0;
+}
+
+QInputContext *QWidgetPrivate::inputContext() const
+{
+#ifndef QT_NO_IM
+ if (QInputContext *qic = assignedInputContext())
+ return qic;
+ return qApp->inputContext();
+#else
+ return 0;
+#endif
+}
+
+/*!
+ This function returns the QInputContext for this widget. By
+ default the input context is inherited from the widgets
+ parent. For toplevels it is inherited from QApplication.
+
+ You can override this and set a special input context for this
+ widget by using the setInputContext() method.
+
+ \sa setInputContext()
+*/
+QInputContext *QWidget::inputContext()
+{
+ Q_D(QWidget);
+ if (!testAttribute(Qt::WA_InputMethodEnabled))
+ return 0;
+
+ return d->inputContext();
+}
+
+/*!
+ This function sets the input context \a context
+ on this widget.
+
+ Qt takes ownership of the given input \a context.
+
+ \sa inputContext()
+*/
+void QWidget::setInputContext(QInputContext *context)
+{
+ Q_D(QWidget);
+ if (!testAttribute(Qt::WA_InputMethodEnabled))
+ return;
+#ifndef QT_NO_IM
+ if (context == d->ic)
+ return;
+ if (d->ic)
+ delete d->ic;
+ d->ic = context;
+ if (d->ic)
+ d->ic->setParent(this);
+#endif
+}
+
+
+/*!
+ \obsolete
+
+ This function can be called on the widget that currently has focus
+ to reset the input method operating on it.
+
+ 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
+ QInputContext *qic = this->inputContext();
+ if(qic)
+ qic->reset();
+#endif // QT_NO_IM
+}
+
+#ifdef QT_KEYPAD_NAVIGATION
+QPointer<QWidget> QWidgetPrivate::editingWidget;
+
+/*!
+ Returns true if this widget currently has edit focus; otherwise false.
+
+ This feature is only available in Qt for Embedded Linux.
+
+ \sa setEditFocus(), QApplication::keypadNavigationEnabled()
+*/
+bool QWidget::hasEditFocus() const
+{
+ const QWidget* w = this;
+ while (w->d_func()->extra && w->d_func()->extra->focus_proxy)
+ w = w->d_func()->extra->focus_proxy;
+ return QWidgetPrivate::editingWidget == w;
+}
+
+/*!
+ \fn void QWidget::setEditFocus(bool enable)
+
+ If \a enable is true, make this widget have edit focus, in which
+ case Qt::Key_Up and Qt::Key_Down will be delivered to the widget
+ normally; otherwise, Qt::Key_Up and Qt::Key_Down are used to
+ change focus.
+
+ This feature is only available in Qt for Embedded Linux and Qt
+ for Symbian.
+
+ \sa hasEditFocus(), QApplication::keypadNavigationEnabled()
+*/
+void QWidget::setEditFocus(bool on)
+{
+ QWidget *f = this;
+ while (f->d_func()->extra && f->d_func()->extra->focus_proxy)
+ f = f->d_func()->extra->focus_proxy;
+
+ if (QWidgetPrivate::editingWidget && QWidgetPrivate::editingWidget != f)
+ QWidgetPrivate::editingWidget->setEditFocus(false);
+
+ if (on && !f->hasFocus())
+ f->setFocus();
+
+ if ((!on && !QWidgetPrivate::editingWidget)
+ || (on && QWidgetPrivate::editingWidget == f)) {
+ return;
+ }
+
+ if (!on && QWidgetPrivate::editingWidget == f) {
+ QWidgetPrivate::editingWidget = 0;
+ QEvent event(QEvent::LeaveEditFocus);
+ QApplication::sendEvent(f, &event);
+ QApplication::sendEvent(f->style(), &event);
+ } else if (on) {
+ QWidgetPrivate::editingWidget = f;
+ QEvent event(QEvent::EnterEditFocus);
+ QApplication::sendEvent(f, &event);
+ QApplication::sendEvent(f->style(), &event);
+ }
+}
+#endif
+
+/*!
+ \property QWidget::autoFillBackground
+ \brief whether the widget background is filled automatically
+ \since 4.1
+
+ If enabled, this property will cause Qt to fill the background of the
+ widget before invoking the paint event. The color used is defined by the
+ QPalette::Window color role from the widget's \l{QPalette}{palette}.
+
+ In addition, Windows are always filled with QPalette::Window, unless the
+ WA_OpaquePaintEvent or WA_NoSystemBackground attributes are set.
+
+ This property cannot be turned off (i.e., set to false) if a widget's
+ parent has a static gradient for its background.
+
+ \warning Use this property with caution in conjunction with
+ \l{Qt Style Sheets}. When a widget has a style sheet with a valid
+ background or a border-image, this property is automatically disabled.
+
+ By default, this property is false.
+
+ \sa Qt::WA_OpaquePaintEvent, Qt::WA_NoSystemBackground,
+ {QWidget#Transparency and Double Buffering}{Transparency and Double Buffering}
+*/
+bool QWidget::autoFillBackground() const
+{
+ Q_D(const QWidget);
+ return d->extra && d->extra->autoFillBackground;
+}
+
+void QWidget::setAutoFillBackground(bool enabled)
+{
+ Q_D(QWidget);
+ if (!d->extra)
+ d->createExtra();
+ if (d->extra->autoFillBackground == enabled)
+ return;
+
+ d->extra->autoFillBackground = enabled;
+ d->updateIsOpaque();
+ update();
+ d->updateIsOpaque();
+}
+
+/*!
+ \class QWidget
+ \brief The QWidget class is the base class of all user interface objects.
+
+ \ingroup basicwidgets
+
+ The widget is the atom of the user interface: it receives mouse, keyboard
+ and other events from the window system, and paints a representation of
+ itself on the screen. Every widget is rectangular, and they are sorted in a
+ Z-order. A widget is clipped by its parent and by the widgets in front of
+ it.
+
+ A widget that is not embedded in a parent widget is called a window.
+ Usually, windows have a frame and a title bar, although it is also possible
+ to create windows without such decoration using suitable
+ \l{Qt::WindowFlags}{window flags}). In Qt, QMainWindow and the various
+ subclasses of QDialog are the most common window types.
+
+ Every widget's constructor accepts one or two standard arguments:
+
+ \list 1
+ \i \c{QWidget *parent = 0} is the parent of the new widget. If it is 0
+ (the default), the new widget will be a window. If not, it will be
+ a child of \e parent, and be constrained by \e parent's geometry
+ (unless you specify Qt::Window as window flag).
+ \i \c{Qt::WindowFlags f = 0} (where available) sets the window flags;
+ the default is suitable for almost all widgets, but to get, for
+ example, a window without a window system frame, you must use
+ special flags.
+ \endlist
+
+ QWidget has many member functions, but some of them have little direct
+ functionality; for example, QWidget has a font property, but never uses
+ this itself. There are many subclasses which provide real functionality,
+ such as QLabel, QPushButton, QListWidget, and QTabWidget.
+
+
+ \section1 Top-Level and Child Widgets
+
+ A widget without a parent widget is always an independent window (top-level
+ widget). For these widgets, setWindowTitle() and setWindowIcon() set the
+ title bar and icon respectively.
+
+ Non-window widgets are child widgets, displayed within their parent
+ widgets. Most widgets in Qt are mainly useful as child widgets. For
+ example, it is possible to display a button as a top-level window, but most
+ people prefer to put their buttons inside other widgets, such as QDialog.
+
+ \image parent-child-widgets.png A parent widget containing various child widgets.
+
+ The diagram above shows a QGroupBox widget being used to hold various child
+ widgets in a layout provided by QGridLayout. The QLabel child widgets have
+ been outlined to indicate their full sizes.
+
+ If you want to use a QWidget to hold child widgets you will usually want to
+ add a layout to the parent QWidget. See \l{Layout Management} for more
+ information.
+
+
+ \section1 Composite Widgets
+
+ When a widget is used as a container to group a number of child widgets, it
+ is known as a composite widget. These can be created by constructing a
+ widget with the required visual properties - a QFrame, for example - and
+ adding child widgets to it, usually managed by a layout. The above diagram
+ shows such a composite widget that was created using \l{Qt Designer}.
+
+ Composite widgets can also be created by subclassing a standard widget,
+ such as QWidget or QFrame, and adding the necessary layout and child
+ widgets in the constructor of the subclass. Many of the \l{Qt Examples}
+ {examples provided with Qt} use this approach, and it is also covered in
+ the Qt \l{Tutorials}.
+
+
+ \section1 Custom Widgets and Painting
+
+ Since QWidget is a subclass of QPaintDevice, subclasses can be used to
+ display custom content that is composed using a series of painting
+ operations with an instance of the QPainter class. This approach contrasts
+ with the canvas-style approach used by the \l{Graphics View}
+ {Graphics View Framework} where items are added to a scene by the
+ application and are rendered by the framework itself.
+
+ Each widget performs all painting operations from within its paintEvent()
+ function. This is called whenever the widget needs to be redrawn, either
+ as a result of some external change or when requested by the application.
+
+ The \l{widgets/analogclock}{Analog Clock example} shows how a simple widget
+ can handle paint events.
+
+
+ \section1 Size Hints and Size Policies
+
+ When implementing a new widget, it is almost always useful to reimplement
+ sizeHint() to provide a reasonable default size for the widget and to set
+ the correct size policy with setSizePolicy().
+
+ By default, composite widgets which do not provide a size hint will be
+ sized according to the space requirements of their child widgets.
+
+ The size policy lets you supply good default behavior for the layout
+ management system, so that other widgets can contain and manage yours
+ easily. The default size policy indicates that the size hint represents
+ the preferred size of the widget, and this is often good enough for many
+ widgets.
+
+ \note The size of top-level widgets are constrained to 2/3 of the desktop's
+ height and width. You can resize() the widget manually if these bounds are
+ inadequate.
+
+
+ \section1 Events
+
+ Widgets respond to events that are typically caused by user actions. Qt
+ delivers events to widgets by calling specific event handler functions with
+ instances of QEvent subclasses containing information about each event.
+
+ If your widget only contains child widgets, you probably do not need to
+ implement any event handlers. If you want to detect a mouse click in a
+ child widget call the child's underMouse() function inside the widget's
+ mousePressEvent().
+
+ The \l{widgets/scribble}{Scribble example} implements a wider set of
+ events to handle mouse movement, button presses, and window resizing.
+
+ You will need to supply the behavior and content for your own widgets, but
+ here is a brief overview of the events that are relevant to QWidget,
+ starting with the most common ones:
+
+ \list
+ \i paintEvent() is called whenever the widget needs to be repainted.
+ Every widget displaying custom content must implement it. Painting
+ using a QPainter can only take place in a paintEvent() or a
+ function called by a paintEvent().
+ \i resizeEvent() is called when the widget has been resized.
+ \i mousePressEvent() is called when a mouse button is pressed while
+ the mouse cursor is inside the widget, or when the widget has
+ grabbed the mouse using grabMouse(). Pressing the mouse without
+ releasing it is effectively the same as calling grabMouse().
+ \i mouseReleaseEvent() is called when a mouse button is released. A
+ widget receives mouse release events when it has received the
+ corresponding mouse press event. This means that if the user
+ presses the mouse inside \e your widget, then drags the mouse
+ somewhere else before releasing the mouse button, \e your widget
+ receives the release event. There is one exception: if a popup menu
+ appears while the mouse button is held down, this popup immediately
+ steals the mouse events.
+ \i mouseDoubleClickEvent() is called when the user double-clicks in
+ the widget. If the user double-clicks, the widget receives a mouse
+ press event, a mouse release event and finally this event instead
+ of a second mouse press event. (Some mouse move events may also be
+ received if the mouse is not held steady during this operation.) It
+ is \e{not possible} to distinguish a click from a double-click
+ until the second click arrives. (This is one reason why most GUI
+ books recommend that double-clicks be an extension of
+ single-clicks, rather than trigger a different action.)
+ \endlist
+
+ Widgets that accept keyboard input need to reimplement a few more event
+ handlers:
+
+ \list
+ \i keyPressEvent() is called whenever a key is pressed, and again when
+ a key has been held down long enough for it to auto-repeat. The
+ \key Tab and \key Shift+Tab keys are only passed to the widget if
+ they are not used by the focus-change mechanisms. To force those
+ keys to be processed by your widget, you must reimplement
+ QWidget::event().
+ \i focusInEvent() is called when the widget gains keyboard focus
+ (assuming you have called setFocusPolicy()). Well-behaved widgets
+ indicate that they own the keyboard focus in a clear but discreet
+ way.
+ \i focusOutEvent() is called when the widget loses keyboard focus.
+ \endlist
+
+ You may be required to also reimplement some of the less common event
+ handlers:
+
+ \list
+ \i mouseMoveEvent() is called whenever the mouse moves while a mouse
+ button is held down. This can be useful during drag and drop
+ operations. If you call \l{setMouseTracking()}{setMouseTracking}(true),
+ you get mouse move events even when no buttons are held down.
+ (See also the \l{Drag and Drop} guide.)
+ \i keyReleaseEvent() is called whenever a key is released and while it
+ is held down (if the key is auto-repeating). In that case, the
+ widget will receive a pair of key release and key press event for
+ every repeat. The \key Tab and \key Shift+Tab keys are only passed
+ to the widget if they are not used by the focus-change mechanisms.
+ To force those keys to be processed by your widget, you must
+ reimplement QWidget::event().
+ \i wheelEvent() is called whenever the user turns the mouse wheel
+ while the widget has the focus.
+ \i enterEvent() is called when the mouse enters the widget's screen
+ space. (This excludes screen space owned by any of the widget's
+ children.)
+ \i leaveEvent() is called when the mouse leaves the widget's screen
+ space. If the mouse enters a child widget it will not cause a
+ leaveEvent().
+ \i moveEvent() is called when the widget has been moved relative to
+ its parent.
+ \i closeEvent() is called when the user closes the widget (or when
+ close() is called).
+ \endlist
+
+ There are also some rather obscure events described in the documentation
+ for QEvent::Type. To handle these events, you need to reimplement event()
+ directly.
+
+ The default implementation of event() handles \key Tab and \key Shift+Tab
+ (to move the keyboard focus), and passes on most of the other events to
+ one of the more specialized handlers above.
+
+ Events and the mechanism used to deliver them are covered in
+ \l{The Event System}.
+
+ \section1 Groups of Functions and Properties
+
+ \table
+ \header \i Context \i Functions and Properties
+
+ \row \i Window functions \i
+ show(),
+ hide(),
+ raise(),
+ lower(),
+ close().
+
+ \row \i Top-level windows \i
+ \l windowModified, \l windowTitle, \l windowIcon, \l windowIconText,
+ \l isActiveWindow, activateWindow(), \l minimized, showMinimized(),
+ \l maximized, showMaximized(), \l fullScreen, showFullScreen(),
+ showNormal().
+
+ \row \i Window contents \i
+ update(),
+ repaint(),
+ scroll().
+
+ \row \i Geometry \i
+ \l pos, x(), y(), \l rect, \l size, width(), height(), move(), resize(),
+ \l sizePolicy, sizeHint(), minimumSizeHint(),
+ updateGeometry(), layout(),
+ \l frameGeometry, \l geometry, \l childrenRect, \l childrenRegion,
+ adjustSize(),
+ mapFromGlobal(), mapToGlobal(),
+ mapFromParent(), mapToParent(),
+ \l maximumSize, \l minimumSize, \l sizeIncrement,
+ \l baseSize, setFixedSize()
+
+ \row \i Mode \i
+ \l visible, isVisibleTo(),
+ \l enabled, isEnabledTo(),
+ \l modal,
+ isWindow(),
+ \l mouseTracking,
+ \l updatesEnabled,
+ visibleRegion().
+
+ \row \i Look and feel \i
+ style(),
+ setStyle(),
+ \l styleSheet,
+ \l cursor,
+ \l font,
+ \l palette,
+ backgroundRole(), setBackgroundRole(),
+ fontInfo(), fontMetrics().
+
+ \row \i Keyboard focus functions \i
+ \l focus, \l focusPolicy,
+ setFocus(), clearFocus(), setTabOrder(), setFocusProxy(),
+ focusNextChild(), focusPreviousChild().
+
+ \row \i Mouse and keyboard grabbing \i
+ grabMouse(), releaseMouse(),
+ grabKeyboard(), releaseKeyboard(),
+ mouseGrabber(), keyboardGrabber().
+
+ \row \i Event handlers \i
+ event(),
+ mousePressEvent(),
+ mouseReleaseEvent(),
+ mouseDoubleClickEvent(),
+ mouseMoveEvent(),
+ keyPressEvent(),
+ keyReleaseEvent(),
+ focusInEvent(),
+ focusOutEvent(),
+ wheelEvent(),
+ enterEvent(),
+ leaveEvent(),
+ paintEvent(),
+ moveEvent(),
+ resizeEvent(),
+ closeEvent(),
+ dragEnterEvent(),
+ dragMoveEvent(),
+ dragLeaveEvent(),
+ dropEvent(),
+ childEvent(),
+ showEvent(),
+ hideEvent(),
+ customEvent().
+ changeEvent(),
+
+ \row \i System functions \i
+ parentWidget(), window(), setParent(), winId(),
+ find(), metric().
+
+ \row \i Interactive help \i
+ setToolTip(), setWhatsThis()
+
+ \endtable
+
+
+ \section1 Widget Style Sheets
+
+ In addition to the standard widget styles for each platform, widgets can
+ also be styled according to rules specified in a \l{styleSheet}
+ {style sheet}. This feature enables you to customize the appearance of
+ specific widgets to provide visual cues to users about their purpose. For
+ example, a button could be styled in a particular way to indicate that it
+ performs a destructive action.
+
+ The use of widget style sheets is described in more detail in the
+ \l{Qt Style Sheets} document.
+
+
+ \section1 Transparency and Double Buffering
+
+ Since Qt 4.0, QWidget automatically double-buffers its painting, so there
+ is no need to write double-buffering code in paintEvent() to avoid
+ flicker.
+
+ Since Qt 4.1, the Qt::WA_ContentsPropagated widget attribute has been
+ deprecated. Instead, the contents of parent widgets are propagated by
+ default to each of their children as long as Qt::WA_PaintOnScreen is not
+ set. Custom widgets can be written to take advantage of this feature by
+ updating irregular regions (to create non-rectangular child widgets), or
+ painting with colors that have less than full alpha component. The
+ following diagram shows how attributes and properties of a custom widget
+ can be fine-tuned to achieve different effects.
+
+ \image propagation-custom.png
+
+ In the above diagram, a semi-transparent rectangular child widget with an
+ area removed is constructed and added to a parent widget (a QLabel showing
+ a pixmap). Then, different properties and widget attributes are set to
+ achieve different effects:
+
+ \list
+ \i The left widget has no additional properties or widget attributes
+ set. This default state suits most custom widgets using
+ transparency, are irregularly-shaped, or do not paint over their
+ entire area with an opaque brush.
+ \i The center widget has the \l autoFillBackground property set. This
+ property is used with custom widgets that rely on the widget to
+ supply a default background, and do not paint over their entire
+ area with an opaque brush.
+ \i The right widget has the Qt::WA_OpaquePaintEvent widget attribute
+ set. This indicates that the widget will paint over its entire area
+ with opaque colors. The widget's area will initially be
+ \e{uninitialized}, represented in the diagram with a red diagonal
+ grid pattern that shines through the overpainted area. The
+ Qt::WA_OpaquePaintArea attribute is useful for widgets that need to
+ paint their own specialized contents quickly and do not need a
+ default filled background.
+ \endlist
+
+ To rapidly update custom widgets with simple background colors, such as
+ real-time plotting or graphing widgets, it is better to define a suitable
+ background color (using setBackgroundRole() with the
+ QPalette::Window role), set the \l autoFillBackground property, and only
+ implement the necessary drawing functionality in the widget's paintEvent().
+
+ To rapidly update custom widgets that constantly paint over their entire
+ areas with opaque content, e.g., video streaming widgets, it is better to
+ set the widget's Qt::WA_OpaquePaintEvent, avoiding any unnecessary overhead
+ associated with repainting the widget's background.
+
+ If a widget has both the Qt::WA_OpaquePaintEvent widget attribute \e{and}
+ the \l autoFillBackground property set, the Qt::WA_OpaquePaintEvent
+ attribute takes precedence. Depending on your requirements, you should
+ choose either one of them.
+
+ Since Qt 4.1, the contents of parent widgets are also propagated to
+ standard Qt widgets. This can lead to some unexpected results if the
+ parent widget is decorated in a non-standard way, as shown in the diagram
+ below.
+
+ \image propagation-standard.png
+
+ The scope for customizing the painting behavior of standard Qt widgets,
+ without resorting to subclassing, is slightly less than that possible for
+ custom widgets. Usually, the desired appearance of a standard widget can be
+ achieved by setting its \l autoFillBackground property.
+
+
+ \section1 Creating Translucent Windows
+
+ Since Qt 4.5, it has been possible to create windows with translucent regions
+ on window systems that support compositing.
+
+ To enable this feature in a top-level widget, set its Qt::WA_TranslucentBackground
+ attribute with setAttribute() and ensure that its background is painted with
+ non-opaque colors in the regions you want to be partially transparent.
+
+ Platform notes:
+
+ \list
+ \o X11: This feature relies on the use of an X server that supports ARGB visuals
+ and a compositing window manager.
+ \o Windows: The widget needs to have the Qt::FramelessWindowHint window flag set
+ for the translucency to work.
+ \endlist
+
+
+ \section1 Native Widgets vs Alien Widgets
+
+ Introduced in Qt 4.4, alien widgets are widgets unknown to the windowing
+ system. They do not have a native window handle associated with them. This
+ feature significantly speeds up widget painting, resizing, and removes flicker.
+
+ Should you require the old behavior with native windows, you can choose
+ one of the following options:
+
+ \list 1
+ \i Use the \c{QT_USE_NATIVE_WINDOWS=1} in your environment.
+ \i Set the Qt::AA_NativeWindows attribute on your application. All
+ widgets will be native widgets.
+ \i Set the Qt::WA_NativeWindow attribute on widgets: The widget itself
+ and all of its ancestors will become native (unless
+ Qt::WA_DontCreateNativeAncestors is set).
+ \i Call QWidget::winId to enforce a native window (this implies 3).
+ \i Set the Qt::WA_PaintOnScreen attribute to enforce a native window
+ (this implies 3).
+ \endlist
+
+ \sa QEvent, QPainter, QGridLayout, QBoxLayout
+
+ \section1 Softkeys
+
+ Since Qt 4.6, Softkeys are usually physical keys on a device that have a corresponding label or
+ other visual representation on the screen that is generally located next to its
+ physical counterpart. They are most often found on mobile phone platforms. In
+ modern touch based user interfaces it is also possible to have softkeys that do
+ not correspond to any physical keys. Softkeys differ from other onscreen labels
+ in that they are contextual.
+
+ In Qt, contextual softkeys are added to a widget by calling addAction() and
+ passing a \c QAction with a softkey role set on it. When the widget
+ containing the softkey actions has focus, its softkeys should appear in
+ the user interface. Softkeys are discovered by traversing the widget
+ hierarchy so it is possible to define a single set of softkeys that are
+ present at all times by calling addAction() for a given top level widget.
+
+ On some platforms, this concept overlaps with \c QMenuBar such that if no
+ other softkeys are found and the top level widget is a QMainWindow containing
+ a QMenuBar, the menubar actions may appear on one of the softkeys.
+
+ Note: Currently softkeys are only supported on the Symbian Platform.
+
+ \sa addAction(), QAction, QMenuBar
+
+*/
+
+QWidgetMapper *QWidgetPrivate::mapper = 0; // widget with wid
+QWidgetSet *QWidgetPrivate::allWidgets = 0; // widgets with no wid
+
+
+/*****************************************************************************
+ QWidget utility functions
+ *****************************************************************************/
+
+QRegion qt_dirtyRegion(QWidget *widget)
+{
+ if (!widget)
+ return QRegion();
+
+ QWidgetBackingStore *bs = qt_widget_private(widget)->maybeBackingStore();
+ if (!bs)
+ return QRegion();
+
+ return bs->dirtyRegion(widget);
+}
+
+/*****************************************************************************
+ QWidget member functions
+ *****************************************************************************/
+
+/*
+ Widget state flags:
+ \list
+ \i Qt::WA_WState_Created The widget has a valid winId().
+ \i Qt::WA_WState_Visible The widget is currently visible.
+ \i Qt::WA_WState_Hidden The widget is hidden, i.e. it won't
+ become visible unless you call show() on it. Qt::WA_WState_Hidden
+ implies !Qt::WA_WState_Visible.
+ \i Qt::WA_WState_CompressKeys Compress keyboard events.
+ \i Qt::WA_WState_BlockUpdates Repaints and updates are disabled.
+ \i Qt::WA_WState_InPaintEvent Currently processing a paint event.
+ \i Qt::WA_WState_Reparented The widget has been reparented.
+ \i Qt::WA_WState_ConfigPending A configuration (resize/move) event is pending.
+ \i Qt::WA_WState_DND (Deprecated) The widget supports drag and drop, see setAcceptDrops().
+ \endlist
+*/
+
+struct QWidgetExceptionCleaner
+{
+ /* this cleans up when the constructor throws an exception */
+ static inline void cleanup(QWidget *that, QWidgetPrivate *d)
+ {
+#ifdef QT_NO_EXCEPTIONS
+ Q_UNUSED(that);
+ Q_UNUSED(d);
+#else
+ QWidgetPrivate::allWidgets->remove(that);
+ if (d->focus_next != that) {
+ if (d->focus_next)
+ d->focus_next->d_func()->focus_prev = d->focus_prev;
+ if (d->focus_prev)
+ d->focus_prev->d_func()->focus_next = d->focus_next;
+ }
+#endif
+ }
+};
+
+/*!
+ Constructs a widget which is a child of \a parent, with widget
+ flags set to \a f.
+
+ If \a parent is 0, the new widget becomes a window. If
+ \a parent is another widget, this widget becomes a child window
+ inside \a parent. The new widget is deleted when its \a parent is
+ deleted.
+
+ The widget flags argument, \a f, is normally 0, but it can be set
+ to customize the frame of a window (i.e. \a
+ parent must be 0). To customize the frame, use a value composed
+ from the bitwise OR of any of the \l{Qt::WindowFlags}{window flags}.
+
+ If you add a child widget to an already visible widget you must
+ explicitly show the child to make it visible.
+
+ Note that the X11 version of Qt may not be able to deliver all
+ combinations of style flags on all systems. This is because on
+ X11, Qt can only ask the window manager, and the window manager
+ can override the application's settings. On Windows, Qt can set
+ whatever flags you want.
+
+ \sa windowFlags
+*/
+QWidget::QWidget(QWidget *parent, Qt::WindowFlags f)
+ : QObject(*new QWidgetPrivate, 0), QPaintDevice()
+{
+ QT_TRY {
+ d_func()->init(parent, f);
+ } QT_CATCH(...) {
+ QWidgetExceptionCleaner::cleanup(this, d_func());
+ QT_RETHROW;
+ }
+}
+
+#ifdef QT3_SUPPORT
+/*!
+ \overload
+ \obsolete
+ */
+QWidget::QWidget(QWidget *parent, const char *name, Qt::WindowFlags f)
+ : QObject(*new QWidgetPrivate, 0), QPaintDevice()
+{
+ QT_TRY {
+ d_func()->init(parent , f);
+ setObjectName(QString::fromAscii(name));
+ } QT_CATCH(...) {
+ QWidgetExceptionCleaner::cleanup(this, d_func());
+ QT_RETHROW;
+ }
+}
+#endif
+
+/*! \internal
+*/
+QWidget::QWidget(QWidgetPrivate &dd, QWidget* parent, Qt::WindowFlags f)
+ : QObject(dd, 0), QPaintDevice()
+{
+ Q_D(QWidget);
+ QT_TRY {
+ d->init(parent, f);
+ } QT_CATCH(...) {
+ QWidgetExceptionCleaner::cleanup(this, d_func());
+ QT_RETHROW;
+ }
+}
+
+/*!
+ \internal
+*/
+int QWidget::devType() const
+{
+ return QInternal::Widget;
+}
+
+
+//### w is a "this" ptr, passed as a param because QWorkspace needs special logic
+void QWidgetPrivate::adjustFlags(Qt::WindowFlags &flags, QWidget *w)
+{
+ bool customize = (flags & (Qt::CustomizeWindowHint
+ | Qt::FramelessWindowHint
+ | Qt::WindowTitleHint
+ | Qt::WindowSystemMenuHint
+ | Qt::WindowMinimizeButtonHint
+ | Qt::WindowMaximizeButtonHint
+ | Qt::WindowCloseButtonHint
+ | Qt::WindowContextHelpButtonHint));
+
+ uint type = (flags & Qt::WindowType_Mask);
+
+ if ((type == Qt::Widget || type == Qt::SubWindow) && w && !w->parent()) {
+ type = Qt::Window;
+ flags |= Qt::Window;
+ }
+
+ if (flags & Qt::CustomizeWindowHint) {
+ // modify window flags to make them consistent.
+ // Only enable this on non-Mac platforms. Since the old way of doing this would
+ // interpret WindowSystemMenuHint as a close button and we can't change that behavior
+ // we can't just add this in.
+#ifndef Q_WS_MAC
+ if (flags & (Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint | Qt::WindowContextHelpButtonHint)) {
+ flags |= Qt::WindowSystemMenuHint;
+#else
+ if (flags & (Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint
+ | Qt::WindowSystemMenuHint)) {
+#endif
+ flags |= Qt::WindowTitleHint;
+ flags &= ~Qt::FramelessWindowHint;
+ }
+ } else if (customize && !(flags & Qt::FramelessWindowHint)) {
+ // if any of the window hints that affect the titlebar are set
+ // and the window is supposed to have frame, we add a titlebar
+ // and system menu by default.
+ flags |= Qt::WindowSystemMenuHint;
+ flags |= Qt::WindowTitleHint;
+ }
+ if (customize)
+ ; // don't modify window flags if the user explicitly set them.
+ else if (type == Qt::Dialog || type == Qt::Sheet)
+#ifndef Q_WS_WINCE
+ flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowContextHelpButtonHint | Qt::WindowCloseButtonHint;
+#else
+ flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint;
+#endif
+ else if (type == Qt::Tool)
+ flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint;
+ else
+ flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint;
+
+
+}
+
+void QWidgetPrivate::init(QWidget *parentWidget, Qt::WindowFlags f)
+{
+ Q_Q(QWidget);
+ if (QApplication::type() == QApplication::Tty)
+ qFatal("QWidget: Cannot create a QWidget when no GUI is being used");
+
+ Q_ASSERT(allWidgets);
+ if (allWidgets)
+ allWidgets->insert(q);
+
+ QWidget *desktopWidget = 0;
+ if (parentWidget && parentWidget->windowType() == Qt::Desktop) {
+ desktopWidget = parentWidget;
+ parentWidget = 0;
+ }
+
+ q->data = &data;
+
+#ifndef QT_NO_THREAD
+ if (!parent) {
+ Q_ASSERT_X(q->thread() == qApp->thread(), "QWidget",
+ "Widgets must be created in the GUI thread.");
+ }
+#endif
+
+#if defined(Q_WS_X11)
+ if (desktopWidget) {
+ // make sure the widget is created on the same screen as the
+ // programmer specified desktop widget
+ xinfo = desktopWidget->d_func()->xinfo;
+ }
+#elif defined(Q_OS_SYMBIAN)
+ if (desktopWidget) {
+ symbianScreenNumber = qt_widget_private(desktopWidget)->symbianScreenNumber;
+ }
+#elif defined(Q_WS_QPA)
+ if (desktopWidget) {
+ int screen = desktopWidget->d_func()->topData()->screenIndex;
+ q->windowHandle()->setScreen(QGuiApplication::screens().value(screen, 0));
+ }
+#else
+ Q_UNUSED(desktopWidget);
+#endif
+
+ data.fstrut_dirty = true;
+
+ data.winid = 0;
+ data.widget_attributes = 0;
+ data.window_flags = f;
+ data.window_state = 0;
+ data.focus_policy = 0;
+ data.context_menu_policy = Qt::DefaultContextMenu;
+ data.window_modality = Qt::NonModal;
+
+ data.sizehint_forced = 0;
+ data.is_closing = 0;
+ data.in_show = 0;
+ data.in_set_window_state = 0;
+ data.in_destructor = false;
+
+ // Widgets with Qt::MSWindowsOwnDC (typically QGLWidget) must have a window handle.
+ if (f & Qt::MSWindowsOwnDC)
+ q->setAttribute(Qt::WA_NativeWindow);
+
+//#ifdef Q_WS_MAC
+// q->setAttribute(Qt::WA_NativeWindow);
+//#endif
+
+ q->setAttribute(Qt::WA_QuitOnClose); // might be cleared in adjustQuitOnCloseAttribute()
+ adjustQuitOnCloseAttribute();
+
+ q->setAttribute(Qt::WA_WState_Hidden);
+
+ //give potential windows a bigger "pre-initial" size; create_sys() will give them a new size later
+#ifdef Q_OS_SYMBIAN
+ if (isGLWidget) {
+ // Don't waste GPU mem for unnecessary large egl surface until resized by application
+ data.crect = QRect(0,0,1,1);
+ } else {
+ data.crect = parentWidget ? QRect(0,0,100,30) : QRect(0,0,360,640);
+ }
+#else
+ data.crect = parentWidget ? QRect(0,0,100,30) : QRect(0,0,640,480);
+#endif
+
+ focus_next = focus_prev = q;
+
+ if ((f & Qt::WindowType_Mask) == Qt::Desktop)
+ q->create();
+ else if (parentWidget)
+ q->setParent(parentWidget, data.window_flags);
+ else {
+ adjustFlags(data.window_flags, q);
+ resolveLayoutDirection();
+ // opaque system background?
+ const QBrush &background = q->palette().brush(QPalette::Window);
+ setOpaque(q->isWindow() && background.style() != Qt::NoBrush && background.isOpaque());
+ }
+ data.fnt = QFont(data.fnt, q);
+#if defined(Q_WS_X11)
+ data.fnt.x11SetScreen(xinfo.screen());
+#endif // Q_WS_X11
+
+ q->setAttribute(Qt::WA_PendingMoveEvent);
+ q->setAttribute(Qt::WA_PendingResizeEvent);
+
+ if (++QWidgetPrivate::instanceCounter > QWidgetPrivate::maxInstances)
+ QWidgetPrivate::maxInstances = QWidgetPrivate::instanceCounter;
+
+ if (QApplicationPrivate::app_compile_version < 0x040200
+ || QApplicationPrivate::testAttribute(Qt::AA_ImmediateWidgetCreation))
+ q->create();
+
+
+ QEvent e(QEvent::Create);
+ QApplication::sendEvent(q, &e);
+ QApplication::postEvent(q, new QEvent(QEvent::PolishRequest));
+
+ extraPaintEngine = 0;
+
+#ifdef QT_MAC_USE_COCOA
+ // If we add a child to the unified toolbar, we have to redirect the painting.
+ if (parentWidget && parentWidget->d_func() && parentWidget->d_func()->isInUnifiedToolbar) {
+ if (parentWidget->d_func()->unifiedSurface) {
+ QWidget *toolbar = parentWidget->d_func()->toolbar_ancestor;
+ parentWidget->d_func()->unifiedSurface->recursiveRedirect(toolbar, toolbar, toolbar->d_func()->toolbar_offset);
+ }
+ }
+#endif // QT_MAC_USE_COCOA
+}
+
+
+
+void QWidgetPrivate::createRecursively()
+{
+ Q_Q(QWidget);
+ q->create(0, true, true);
+ for (int i = 0; i < children.size(); ++i) {
+ QWidget *child = qobject_cast<QWidget *>(children.at(i));
+ if (child && !child->isHidden() && !child->isWindow() && !child->testAttribute(Qt::WA_WState_Created))
+ child->d_func()->createRecursively();
+ }
+}
+
+
+
+
+/*!
+ Creates a new widget window if \a window is 0, otherwise sets the
+ widget's window to \a window.
+
+ Initializes the window (sets the geometry etc.) if \a
+ initializeWindow is true. If \a initializeWindow is false, no
+ initialization is performed. This parameter only makes sense if \a
+ window is a valid window.
+
+ Destroys the old window if \a destroyOldWindow is true. If \a
+ destroyOldWindow is false, you are responsible for destroying the
+ window yourself (using platform native code).
+
+ The QWidget constructor calls create(0,true,true) to create a
+ window for this widget.
+*/
+
+void QWidget::create(WId window, bool initializeWindow, bool destroyOldWindow)
+{
+ Q_D(QWidget);
+ if (testAttribute(Qt::WA_WState_Created) && window == 0 && internalWinId())
+ return;
+
+ if (d->data.in_destructor)
+ return;
+
+ Qt::WindowType type = windowType();
+ Qt::WindowFlags &flags = data->window_flags;
+
+ if ((type == Qt::Widget || type == Qt::SubWindow) && !parentWidget()) {
+ type = Qt::Window;
+ flags |= Qt::Window;
+ }
+
+ if (QWidget *parent = parentWidget()) {
+ if (type & Qt::Window) {
+ if (!parent->testAttribute(Qt::WA_WState_Created))
+ parent->createWinId();
+ } else if (testAttribute(Qt::WA_NativeWindow) && !parent->internalWinId()
+ && !testAttribute(Qt::WA_DontCreateNativeAncestors)) {
+ // We're about to create a native child widget that doesn't have a native parent;
+ // enforce a native handle for the parent unless the Qt::WA_DontCreateNativeAncestors
+ // attribute is set.
+ d->createWinId(window);
+ // Nothing more to do.
+ Q_ASSERT(testAttribute(Qt::WA_WState_Created));
+ Q_ASSERT(internalWinId());
+ return;
+ }
+ }
+
+#ifdef QT3_SUPPORT
+ if (flags & Qt::WStaticContents)
+ setAttribute(Qt::WA_StaticContents);
+ if (flags & Qt::WDestructiveClose)
+ setAttribute(Qt::WA_DeleteOnClose);
+ if (flags & Qt::WShowModal)
+ setWindowModality(Qt::ApplicationModal);
+ if (flags & Qt::WMouseNoMask)
+ setAttribute(Qt::WA_MouseNoMask);
+ if (flags & Qt::WGroupLeader)
+ setAttribute(Qt::WA_GroupLeader);
+ if (flags & Qt::WNoMousePropagation)
+ setAttribute(Qt::WA_NoMousePropagation);
+#endif
+
+ static int paintOnScreenEnv = -1;
+ if (paintOnScreenEnv == -1)
+ paintOnScreenEnv = qgetenv("QT_ONSCREEN_PAINT").toInt() > 0 ? 1 : 0;
+ if (paintOnScreenEnv == 1)
+ setAttribute(Qt::WA_PaintOnScreen);
+
+ if (QApplicationPrivate::testAttribute(Qt::AA_NativeWindows))
+ setAttribute(Qt::WA_NativeWindow);
+
+#ifdef ALIEN_DEBUG
+ qDebug() << "QWidget::create:" << this << "parent:" << parentWidget()
+ << "Alien?" << !testAttribute(Qt::WA_NativeWindow);
+#endif
+
+#if defined (Q_WS_WIN) && !defined(QT_NO_DRAGANDDROP)
+ // Unregister the dropsite (if already registered) before we
+ // re-create the widget with a native window.
+ if (testAttribute(Qt::WA_WState_Created) && !internalWinId() && testAttribute(Qt::WA_NativeWindow)
+ && d->extra && d->extra->dropTarget) {
+ d->registerDropSite(false);
+ }
+#endif // defined (Q_WS_WIN) && !defined(QT_NO_DRAGANDDROP)
+
+ d->updateIsOpaque();
+
+ setAttribute(Qt::WA_WState_Created); // set created flag
+ d->create_sys(window, initializeWindow, destroyOldWindow);
+
+ // a real toplevel window needs a backing store
+ if (isWindow() && windowType() != Qt::Desktop) {
+ d->topData()->backingStoreTracker.destroy();
+ if (hasBackingStoreSupport())
+ d->topData()->backingStoreTracker.create(this);
+ }
+
+ d->setModal_sys();
+
+ if (!isWindow() && parentWidget() && parentWidget()->testAttribute(Qt::WA_DropSiteRegistered))
+ setAttribute(Qt::WA_DropSiteRegistered, true);
+
+#ifdef QT_EVAL
+ extern void qt_eval_init_widget(QWidget *w);
+ qt_eval_init_widget(this);
+#endif
+
+ // need to force the resting of the icon after changing parents
+ if (testAttribute(Qt::WA_SetWindowIcon))
+ d->setWindowIcon_sys(true);
+ if (isWindow() && !d->topData()->iconText.isEmpty())
+ d->setWindowIconText_helper(d->topData()->iconText);
+ if (isWindow() && !d->topData()->caption.isEmpty())
+ d->setWindowTitle_helper(d->topData()->caption);
+ if (windowType() != Qt::Desktop) {
+ d->updateSystemBackground();
+
+ if (isWindow() && !testAttribute(Qt::WA_SetWindowIcon))
+ d->setWindowIcon_sys();
+ }
+}
+
+/*!
+ Destroys the widget.
+
+ All this widget's children are deleted first. The application
+ exits if this widget is the main widget.
+*/
+
+QWidget::~QWidget()
+{
+ Q_D(QWidget);
+ d->data.in_destructor = true;
+
+#if defined (QT_CHECK_STATE)
+ if (paintingActive())
+ qWarning("QWidget: %s (%s) deleted while being painted", className(), name());
+#endif
+
+#ifndef QT_NO_GESTURES
+ foreach (Qt::GestureType type, d->gestureContext.keys())
+ ungrabGesture(type);
+#endif
+
+ // force acceptDrops false before winId is destroyed.
+ d->registerDropSite(false);
+
+#ifndef QT_NO_ACTION
+ // remove all actions from this widget
+ for (int i = 0; i < d->actions.size(); ++i) {
+ QActionPrivate *apriv = d->actions.at(i)->d_func();
+ apriv->widgets.removeAll(this);
+ }
+ d->actions.clear();
+#endif
+
+#ifndef QT_NO_SHORTCUT
+ // Remove all shortcuts grabbed by this
+ // widget, unless application is closing
+ if (!QApplicationPrivate::is_app_closing && testAttribute(Qt::WA_GrabbedShortcut))
+ qApp->d_func()->shortcutMap.removeShortcut(0, this, QKeySequence());
+#endif
+
+ // delete layout while we still are a valid widget
+ delete d->layout;
+ d->layout = 0;
+ // Remove myself from focus list
+
+ Q_ASSERT(d->focus_next->d_func()->focus_prev == this);
+ Q_ASSERT(d->focus_prev->d_func()->focus_next == this);
+
+ if (d->focus_next != this) {
+ d->focus_next->d_func()->focus_prev = d->focus_prev;
+ d->focus_prev->d_func()->focus_next = d->focus_next;
+ d->focus_next = d->focus_prev = 0;
+ }
+
+#ifdef QT3_SUPPORT
+ if (QApplicationPrivate::main_widget == this) { // reset main widget
+ QApplicationPrivate::main_widget = 0;
+ QApplication::quit();
+ }
+#endif
+
+ QT_TRY {
+ clearFocus();
+ } QT_CATCH(...) {
+ // swallow this problem because we are in a destructor
+ }
+
+ d->setDirtyOpaqueRegion();
+
+ if (isWindow() && isVisible() && internalWinId()) {
+ QT_TRY {
+ d->close_helper(QWidgetPrivate::CloseNoEvent);
+ } QT_CATCH(...) {
+ // if we're out of memory, at least hide the window.
+ QT_TRY {
+ hide();
+ } QT_CATCH(...) {
+ // and if that also doesn't work, then give up
+ }
+ }
+ }
+
+#if defined(Q_WS_WIN) || defined(Q_WS_X11)|| defined(Q_WS_MAC)
+ else if (!internalWinId() && isVisible()) {
+ qApp->d_func()->sendSyntheticEnterLeave(this);
+ }
+#elif defined(Q_WS_QPA)
+ else if (isVisible()) {
+ qApp->d_func()->sendSyntheticEnterLeave(this);
+ }
+#endif
+
+#ifdef Q_OS_SYMBIAN
+ if (d->extra && d->extra->topextra && d->extra->topextra->backingStore) {
+ // Okay, we are about to destroy the top-level window that owns
+ // the backing store. Make sure we delete the backing store right away
+ // before the window handle is invalid. This is important because
+ // the backing store will delete its window surface, which may or may
+ // not have a reference to this widget that will be used later to
+ // notify the window it no longer has a surface.
+ d->extra->topextra->backingStore.destroy();
+ }
+#endif
+ if (QWidgetBackingStore *bs = d->maybeBackingStore()) {
+ bs->removeDirtyWidget(this);
+ if (testAttribute(Qt::WA_StaticContents))
+ bs->removeStaticWidget(this);
+ }
+
+ delete d->needsFlush;
+ d->needsFlush = 0;
+
+ // set all QPointers for this object to zero
+ if (d->hasGuards)
+ QObjectPrivate::clearGuards(this);
+
+ if (d->declarativeData) {
+ QAbstractDeclarativeData::destroyed(d->declarativeData, this);
+ d->declarativeData = 0; // don't activate again in ~QObject
+ }
+
+#ifdef QT_MAC_USE_COCOA
+ // QCocoaView holds a pointer back to this widget. Clear it now
+ // to make sure it's not followed later on. The lifetime of the
+ // QCocoaView might exceed the lifetime of this widget in cases
+ // where Cocoa itself holds references to it.
+ extern void qt_mac_clearCocoaViewQWidgetPointers(QWidget *);
+ qt_mac_clearCocoaViewQWidgetPointers(this);
+#endif
+
+ if (!d->children.isEmpty())
+ d->deleteChildren();
+
+ QApplication::removePostedEvents(this);
+
+ QT_TRY {
+ destroy(); // platform-dependent cleanup
+ } QT_CATCH(...) {
+ // if this fails we can't do anything about it but at least we are not allowed to throw.
+ }
+ --QWidgetPrivate::instanceCounter;
+
+ if (QWidgetPrivate::allWidgets) // might have been deleted by ~QApplication
+ QWidgetPrivate::allWidgets->remove(this);
+
+ QT_TRY {
+ QEvent e(QEvent::Destroy);
+ QCoreApplication::sendEvent(this, &e);
+ } QT_CATCH(const std::exception&) {
+ // if this fails we can't do anything about it but at least we are not allowed to throw.
+ }
+}
+
+int QWidgetPrivate::instanceCounter = 0; // Current number of widget instances
+int QWidgetPrivate::maxInstances = 0; // Maximum number of widget instances
+
+void QWidgetPrivate::setWinId(WId id) // set widget identifier
+{
+ Q_Q(QWidget);
+ // 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);
+ }
+
+ const WId oldWinId = data.winid;
+
+ data.winid = id;
+#if defined(Q_WS_X11)
+ hd = id; // X11: hd == ident
+#endif
+ if (mapper && id && !userDesktopWidget) {
+ mapper->insert(data.winid, q);
+ }
+
+ if(oldWinId != id) {
+ QEvent e(QEvent::WinIdChange);
+ QCoreApplication::sendEvent(q, &e);
+ }
+}
+
+void QWidgetPrivate::createTLExtra()
+{
+ if (!extra)
+ createExtra();
+ if (!extra->topextra) {
+ QTLWExtra* x = extra->topextra = new QTLWExtra;
+ x->icon = 0;
+ x->iconPixmap = 0;
+ x->backingStore = 0;
+ x->sharedPainter = 0;
+ x->incw = x->inch = 0;
+ x->basew = x->baseh = 0;
+ x->frameStrut.setCoords(0, 0, 0, 0);
+ x->normalGeometry = QRect(0,0,-1,-1);
+ x->savedFlags = 0;
+ x->opacity = 255;
+ x->posFromMove = false;
+ x->sizeAdjusted = false;
+ x->inTopLevelResize = false;
+ x->inRepaint = false;
+ x->embedded = 0;
+#ifdef Q_WS_MAC
+#ifdef QT_MAC_USE_COCOA
+ x->wasMaximized = false;
+#endif // QT_MAC_USE_COCOA
+#endif // Q_WS_MAC
+ createTLSysExtra();
+#ifdef QWIDGET_EXTRA_DEBUG
+ static int count = 0;
+ qDebug() << "tlextra" << ++count;
+#endif
+ }
+}
+
+/*!
+ \internal
+ Creates the widget extra data.
+*/
+
+void QWidgetPrivate::createExtra()
+{
+ if (!extra) { // if not exists
+ extra = new QWExtra;
+ extra->glContext = 0;
+ extra->topextra = 0;
+#ifndef QT_NO_GRAPHICSVIEW
+ extra->proxyWidget = 0;
+#endif
+#ifndef QT_NO_CURSOR
+ extra->curs = 0;
+#endif
+ extra->minw = 0;
+ extra->minh = 0;
+ extra->maxw = QWIDGETSIZE_MAX;
+ extra->maxh = QWIDGETSIZE_MAX;
+ extra->customDpiX = 0;
+ extra->customDpiY = 0;
+ extra->explicitMinSize = 0;
+ extra->explicitMaxSize = 0;
+ extra->autoFillBackground = 0;
+ extra->nativeChildrenForced = 0;
+ extra->inRenderWithPainter = 0;
+ extra->hasMask = 0;
+ createSysExtra();
+#ifdef QWIDGET_EXTRA_DEBUG
+ static int count = 0;
+ qDebug() << "extra" << ++count;
+#endif
+ }
+}
+
+
+/*!
+ \internal
+ Deletes the widget extra data.
+*/
+
+void QWidgetPrivate::deleteExtra()
+{
+ if (extra) { // if exists
+#ifndef QT_NO_CURSOR
+ delete extra->curs;
+#endif
+ deleteSysExtra();
+#ifndef QT_NO_STYLE_STYLESHEET
+ // dereference the stylesheet style
+ if (QStyleSheetStyle *proxy = qobject_cast<QStyleSheetStyle *>(extra->style))
+ proxy->deref();
+#endif
+ if (extra->topextra) {
+ deleteTLSysExtra();
+ extra->topextra->backingStoreTracker.destroy();
+ delete extra->topextra->icon;
+ delete extra->topextra->iconPixmap;
+ delete extra->topextra->backingStore;
+ delete extra->topextra;
+ }
+ delete extra;
+ // extra->xic destroyed in QWidget::destroy()
+ extra = 0;
+ }
+}
+
+/*
+ Returns true if there are widgets above this which overlap with
+ \a rect, which is in parent's coordinate system (same as crect).
+*/
+
+bool QWidgetPrivate::isOverlapped(const QRect &rect) const
+{
+ Q_Q(const QWidget);
+
+ const QWidget *w = q;
+ QRect r = rect;
+ while (w) {
+ if (w->isWindow())
+ return false;
+ QWidgetPrivate *pd = w->parentWidget()->d_func();
+ bool above = false;
+ for (int i = 0; i < pd->children.size(); ++i) {
+ QWidget *sibling = qobject_cast<QWidget *>(pd->children.at(i));
+ if (!sibling || !sibling->isVisible() || sibling->isWindow())
+ continue;
+ if (!above) {
+ above = (sibling == w);
+ continue;
+ }
+
+ if (qRectIntersects(sibling->d_func()->effectiveRectFor(sibling->data->crect), r)) {
+ const QWExtra *siblingExtra = sibling->d_func()->extra;
+ if (siblingExtra && siblingExtra->hasMask && !sibling->d_func()->graphicsEffect
+ && !siblingExtra->mask.translated(sibling->data->crect.topLeft()).intersects(r)) {
+ continue;
+ }
+ return true;
+ }
+ }
+ w = w->parentWidget();
+ r.translate(pd->data.crect.topLeft());
+ }
+ return false;
+}
+
+void QWidgetPrivate::syncBackingStore()
+{
+ if (paintOnScreen()) {
+ repaint_sys(dirty);
+ dirty = QRegion();
+ } else if (QWidgetBackingStore *bs = maybeBackingStore()) {
+ bs->sync();
+ }
+}
+
+void QWidgetPrivate::syncBackingStore(const QRegion &region)
+{
+ if (paintOnScreen())
+ repaint_sys(region);
+ else if (QWidgetBackingStore *bs = maybeBackingStore()) {
+ bs->sync(q_func(), region);
+ }
+}
+
+void QWidgetPrivate::setUpdatesEnabled_helper(bool enable)
+{
+ Q_Q(QWidget);
+
+ if (enable && !q->isWindow() && q->parentWidget() && !q->parentWidget()->updatesEnabled())
+ return; // nothing we can do
+
+ if (enable != q->testAttribute(Qt::WA_UpdatesDisabled))
+ return; // nothing to do
+
+ q->setAttribute(Qt::WA_UpdatesDisabled, !enable);
+ if (enable)
+ q->update();
+
+ Qt::WidgetAttribute attribute = enable ? Qt::WA_ForceUpdatesDisabled : Qt::WA_UpdatesDisabled;
+ for (int i = 0; i < children.size(); ++i) {
+ QWidget *w = qobject_cast<QWidget *>(children.at(i));
+ if (w && !w->isWindow() && !w->testAttribute(attribute))
+ w->d_func()->setUpdatesEnabled_helper(enable);
+ }
+}
+
+/*!
+ \internal
+
+ Propagate this widget's palette to all children, except style sheet
+ widgets, and windows that don't enable window propagation (palettes don't
+ normally propagate to windows).
+*/
+void QWidgetPrivate::propagatePaletteChange()
+{
+ Q_Q(QWidget);
+ // Propagate a new inherited mask to all children.
+#ifndef QT_NO_GRAPHICSVIEW
+ if (!q->parentWidget() && extra && extra->proxyWidget) {
+ QGraphicsProxyWidget *p = extra->proxyWidget;
+ inheritedPaletteResolveMask = p->d_func()->inheritedPaletteResolveMask | p->palette().resolve();
+ } else
+#endif //QT_NO_GRAPHICSVIEW
+ if (q->isWindow() && !q->testAttribute(Qt::WA_WindowPropagation)) {
+ inheritedPaletteResolveMask = 0;
+ }
+ int mask = data.pal.resolve() | inheritedPaletteResolveMask;
+
+ QEvent pc(QEvent::PaletteChange);
+ QApplication::sendEvent(q, &pc);
+ for (int i = 0; i < children.size(); ++i) {
+ QWidget *w = qobject_cast<QWidget*>(children.at(i));
+ if (w && !w->testAttribute(Qt::WA_StyleSheet)
+ && (!w->isWindow() || w->testAttribute(Qt::WA_WindowPropagation))) {
+ QWidgetPrivate *wd = w->d_func();
+ wd->inheritedPaletteResolveMask = mask;
+ wd->resolvePalette();
+ }
+ }
+#if defined(QT3_SUPPORT)
+ q->paletteChange(q->palette()); // compatibility
+#endif
+}
+
+/*
+ Returns the widget's clipping rectangle.
+*/
+QRect QWidgetPrivate::clipRect() const
+{
+ Q_Q(const QWidget);
+ const QWidget * w = q;
+ if (!w->isVisible())
+ return QRect();
+ QRect r = effectiveRectFor(q->rect());
+ int ox = 0;
+ int oy = 0;
+ while (w
+ && w->isVisible()
+ && !w->isWindow()
+ && w->parentWidget()) {
+ ox -= w->x();
+ oy -= w->y();
+ w = w->parentWidget();
+ r &= QRect(ox, oy, w->width(), w->height());
+ }
+ return r;
+}
+
+/*
+ Returns the widget's clipping region (without siblings).
+*/
+QRegion QWidgetPrivate::clipRegion() const
+{
+ Q_Q(const QWidget);
+ if (!q->isVisible())
+ return QRegion();
+ QRegion r(q->rect());
+ const QWidget * w = q;
+ const QWidget *ignoreUpTo;
+ int ox = 0;
+ int oy = 0;
+ while (w
+ && w->isVisible()
+ && !w->isWindow()
+ && w->parentWidget()) {
+ ox -= w->x();
+ oy -= w->y();
+ ignoreUpTo = w;
+ w = w->parentWidget();
+ r &= QRegion(ox, oy, w->width(), w->height());
+
+ int i = 0;
+ while(w->d_func()->children.at(i++) != static_cast<const QObject *>(ignoreUpTo))
+ ;
+ for ( ; i < w->d_func()->children.size(); ++i) {
+ if(QWidget *sibling = qobject_cast<QWidget *>(w->d_func()->children.at(i))) {
+ if(sibling->isVisible() && !sibling->isWindow()) {
+ QRect siblingRect(ox+sibling->x(), oy+sibling->y(),
+ sibling->width(), sibling->height());
+ if (qRectIntersects(siblingRect, q->rect()))
+ r -= QRegion(siblingRect);
+ }
+ }
+ }
+ }
+ return r;
+}
+
+#ifndef QT_NO_GRAPHICSEFFECT
+void QWidgetPrivate::invalidateGraphicsEffectsRecursively()
+{
+ Q_Q(QWidget);
+ QWidget *w = q;
+ do {
+ if (w->graphicsEffect()) {
+ QWidgetEffectSourcePrivate *sourced =
+ static_cast<QWidgetEffectSourcePrivate *>(w->graphicsEffect()->source()->d_func());
+ if (!sourced->updateDueToGraphicsEffect)
+ w->graphicsEffect()->source()->d_func()->invalidateCache();
+ }
+ w = w->parentWidget();
+ } while (w);
+}
+#endif //QT_NO_GRAPHICSEFFECT
+
+void QWidgetPrivate::setDirtyOpaqueRegion()
+{
+ Q_Q(QWidget);
+
+ dirtyOpaqueChildren = true;
+
+#ifndef QT_NO_GRAPHICSEFFECT
+ invalidateGraphicsEffectsRecursively();
+#endif //QT_NO_GRAPHICSEFFECT
+
+ if (q->isWindow())
+ return;
+
+ QWidget *parent = q->parentWidget();
+ if (!parent)
+ return;
+
+ // TODO: instead of setting dirtyflag, manipulate the dirtyregion directly?
+ QWidgetPrivate *pd = parent->d_func();
+ if (!pd->dirtyOpaqueChildren)
+ pd->setDirtyOpaqueRegion();
+}
+
+const QRegion &QWidgetPrivate::getOpaqueChildren() const
+{
+ if (!dirtyOpaqueChildren)
+ return opaqueChildren;
+
+ QWidgetPrivate *that = const_cast<QWidgetPrivate*>(this);
+ that->opaqueChildren = QRegion();
+
+ for (int i = 0; i < children.size(); ++i) {
+ QWidget *child = qobject_cast<QWidget *>(children.at(i));
+ if (!child || !child->isVisible() || child->isWindow())
+ continue;
+
+ const QPoint offset = child->geometry().topLeft();
+ QWidgetPrivate *childd = child->d_func();
+ QRegion r = childd->isOpaque ? child->rect() : childd->getOpaqueChildren();
+ if (childd->extra && childd->extra->hasMask)
+ r &= childd->extra->mask;
+ if (r.isEmpty())
+ continue;
+ r.translate(offset);
+ that->opaqueChildren += r;
+ }
+
+ that->opaqueChildren &= q_func()->rect();
+ that->dirtyOpaqueChildren = false;
+
+ return that->opaqueChildren;
+}
+
+void QWidgetPrivate::subtractOpaqueChildren(QRegion &source, const QRect &clipRect) const
+{
+ if (children.isEmpty() || clipRect.isEmpty())
+ return;
+
+ const QRegion &r = getOpaqueChildren();
+ if (!r.isEmpty())
+ source -= (r & clipRect);
+}
+
+//subtract any relatives that are higher up than me --- this is too expensive !!!
+void QWidgetPrivate::subtractOpaqueSiblings(QRegion &sourceRegion, bool *hasDirtySiblingsAbove,
+ bool alsoNonOpaque) const
+{
+ Q_Q(const QWidget);
+ static int disableSubtractOpaqueSiblings = qgetenv("QT_NO_SUBTRACTOPAQUESIBLINGS").toInt();
+ if (disableSubtractOpaqueSiblings || q->isWindow())
+ return;
+
+#ifdef QT_MAC_USE_COCOA
+ if (q->d_func()->isInUnifiedToolbar)
+ return;
+#endif // QT_MAC_USE_COCOA
+
+ QRect clipBoundingRect;
+ bool dirtyClipBoundingRect = true;
+
+ QRegion parentClip;
+ bool dirtyParentClip = true;
+
+ QPoint parentOffset = data.crect.topLeft();
+
+ const QWidget *w = q;
+
+ while (w) {
+ if (w->isWindow())
+ break;
+ QWidgetPrivate *pd = w->parentWidget()->d_func();
+ const int myIndex = pd->children.indexOf(const_cast<QWidget *>(w));
+ const QRect widgetGeometry = w->d_func()->effectiveRectFor(w->data->crect);
+ for (int i = myIndex + 1; i < pd->children.size(); ++i) {
+ QWidget *sibling = qobject_cast<QWidget *>(pd->children.at(i));
+ if (!sibling || !sibling->isVisible() || sibling->isWindow())
+ continue;
+
+ const QRect siblingGeometry = sibling->d_func()->effectiveRectFor(sibling->data->crect);
+ if (!qRectIntersects(siblingGeometry, widgetGeometry))
+ continue;
+
+ if (dirtyClipBoundingRect) {
+ clipBoundingRect = sourceRegion.boundingRect();
+ dirtyClipBoundingRect = false;
+ }
+
+ if (!qRectIntersects(siblingGeometry, clipBoundingRect.translated(parentOffset)))
+ continue;
+
+ if (dirtyParentClip) {
+ parentClip = sourceRegion.translated(parentOffset);
+ dirtyParentClip = false;
+ }
+
+ const QPoint siblingPos(sibling->data->crect.topLeft());
+ const QRect siblingClipRect(sibling->d_func()->clipRect());
+ QRegion siblingDirty(parentClip);
+ siblingDirty &= (siblingClipRect.translated(siblingPos));
+ const bool hasMask = sibling->d_func()->extra && sibling->d_func()->extra->hasMask
+ && !sibling->d_func()->graphicsEffect;
+ if (hasMask)
+ siblingDirty &= sibling->d_func()->extra->mask.translated(siblingPos);
+ if (siblingDirty.isEmpty())
+ continue;
+
+ if (sibling->d_func()->isOpaque || alsoNonOpaque) {
+ if (hasMask) {
+ siblingDirty.translate(-parentOffset);
+ sourceRegion -= siblingDirty;
+ } else {
+ sourceRegion -= siblingGeometry.translated(-parentOffset);
+ }
+ } else {
+ if (hasDirtySiblingsAbove)
+ *hasDirtySiblingsAbove = true;
+ if (sibling->d_func()->children.isEmpty())
+ continue;
+ QRegion opaqueSiblingChildren(sibling->d_func()->getOpaqueChildren());
+ opaqueSiblingChildren.translate(-parentOffset + siblingPos);
+ sourceRegion -= opaqueSiblingChildren;
+ }
+ if (sourceRegion.isEmpty())
+ return;
+
+ dirtyClipBoundingRect = true;
+ dirtyParentClip = true;
+ }
+
+ w = w->parentWidget();
+ parentOffset += pd->data.crect.topLeft();
+ dirtyParentClip = true;
+ }
+}
+
+void QWidgetPrivate::clipToEffectiveMask(QRegion &region) const
+{
+ Q_Q(const QWidget);
+
+ const QWidget *w = q;
+ QPoint offset;
+
+#ifndef QT_NO_GRAPHICSEFFECT
+ if (graphicsEffect) {
+ w = q->parentWidget();
+ offset -= data.crect.topLeft();
+ }
+#endif //QT_NO_GRAPHICSEFFECT
+
+ while (w) {
+ const QWidgetPrivate *wd = w->d_func();
+ if (wd->extra && wd->extra->hasMask)
+ region &= (w != q) ? wd->extra->mask.translated(offset) : wd->extra->mask;
+ if (w->isWindow())
+ return;
+ offset -= wd->data.crect.topLeft();
+ w = w->parentWidget();
+ }
+}
+
+bool QWidgetPrivate::paintOnScreen() const
+{
+#if defined(QT_NO_BACKINGSTORE)
+ return true;
+#else
+ Q_Q(const QWidget);
+ if (q->testAttribute(Qt::WA_PaintOnScreen)
+ || (!q->isWindow() && q->window()->testAttribute(Qt::WA_PaintOnScreen))) {
+ return true;
+ }
+
+ return !qt_enable_backingstore;
+#endif
+}
+
+void QWidgetPrivate::updateIsOpaque()
+{
+ // hw: todo: only needed if opacity actually changed
+ setDirtyOpaqueRegion();
+
+#ifndef QT_NO_GRAPHICSEFFECT
+ if (graphicsEffect) {
+ // ### We should probably add QGraphicsEffect::isOpaque at some point.
+ setOpaque(false);
+ return;
+ }
+#endif //QT_NO_GRAPHICSEFFECT
+
+ Q_Q(QWidget);
+#ifdef Q_WS_X11
+ if (q->testAttribute(Qt::WA_X11OpenGLOverlay)) {
+ setOpaque(false);
+ return;
+ }
+#endif
+
+#ifdef Q_WS_S60
+ if (q->windowType() == Qt::Dialog && q->testAttribute(Qt::WA_TranslucentBackground)
+ && S60->avkonComponentsSupportTransparency) {
+ setOpaque(false);
+ return;
+ }
+#endif
+
+ if (q->testAttribute(Qt::WA_OpaquePaintEvent) || q->testAttribute(Qt::WA_PaintOnScreen)) {
+ setOpaque(true);
+ return;
+ }
+
+ const QPalette &pal = q->palette();
+
+ if (q->autoFillBackground()) {
+ const QBrush &autoFillBrush = pal.brush(q->backgroundRole());
+ if (autoFillBrush.style() != Qt::NoBrush && autoFillBrush.isOpaque()) {
+ setOpaque(true);
+ return;
+ }
+ }
+
+ if (q->isWindow() && !q->testAttribute(Qt::WA_NoSystemBackground)) {
+ const QBrush &windowBrush = q->palette().brush(QPalette::Window);
+ if (windowBrush.style() != Qt::NoBrush && windowBrush.isOpaque()) {
+ setOpaque(true);
+ return;
+ }
+ }
+ setOpaque(false);
+}
+
+void QWidgetPrivate::setOpaque(bool opaque)
+{
+ if (isOpaque == opaque)
+ return;
+ isOpaque = opaque;
+#ifdef Q_WS_MAC
+ macUpdateIsOpaque();
+#endif
+#ifdef Q_WS_X11
+ x11UpdateIsOpaque();
+#endif
+#ifdef Q_WS_WIN
+ winUpdateIsOpaque();
+#endif
+#ifdef Q_OS_SYMBIAN
+ s60UpdateIsOpaque();
+#endif
+}
+
+void QWidgetPrivate::updateIsTranslucent()
+{
+#ifdef Q_WS_MAC
+ macUpdateIsOpaque();
+#endif
+#ifdef Q_WS_X11
+ x11UpdateIsOpaque();
+#endif
+#ifdef Q_WS_WIN
+ winUpdateIsOpaque();
+#endif
+#ifdef Q_OS_SYMBIAN
+ s60UpdateIsOpaque();
+#endif
+}
+
+static inline void fillRegion(QPainter *painter, const QRegion &rgn, const QBrush &brush)
+{
+ Q_ASSERT(painter);
+
+ if (brush.style() == Qt::TexturePattern) {
+#ifdef Q_WS_MAC
+ // Optimize pattern filling on mac by using HITheme directly
+ // when filling with the standard widget background.
+ // Defined in qmacstyle_mac.cpp
+ extern void qt_mac_fill_background(QPainter *painter, const QRegion &rgn, const QBrush &brush);
+ qt_mac_fill_background(painter, rgn, brush);
+#else
+#if !defined(QT_NO_STYLE_S60)
+ // Defined in qs60style.cpp
+ extern bool qt_s60_fill_background(QPainter *painter, const QRegion &rgn, const QBrush &brush);
+ if (!qt_s60_fill_background(painter, rgn, brush))
+#endif // !defined(QT_NO_STYLE_S60)
+ {
+ const QRect rect(rgn.boundingRect());
+ painter->setClipRegion(rgn);
+ painter->drawTiledPixmap(rect, brush.texture(), rect.topLeft());
+ }
+#endif // Q_WS_MAC
+
+ } else if (brush.gradient()
+ && brush.gradient()->coordinateMode() == QGradient::ObjectBoundingMode) {
+ painter->save();
+ painter->setClipRegion(rgn);
+ painter->fillRect(0, 0, painter->device()->width(), painter->device()->height(), brush);
+ painter->restore();
+ } else {
+ const QVector<QRect> &rects = rgn.rects();
+ for (int i = 0; i < rects.size(); ++i)
+ painter->fillRect(rects.at(i), brush);
+ }
+}
+
+void QWidgetPrivate::paintBackground(QPainter *painter, const QRegion &rgn, int flags) const
+{
+ Q_Q(const QWidget);
+
+#ifndef QT_NO_SCROLLAREA
+ bool resetBrushOrigin = false;
+ QPointF oldBrushOrigin;
+ //If we are painting the viewport of a scrollarea, we must apply an offset to the brush in case we are drawing a texture
+ QAbstractScrollArea *scrollArea = qobject_cast<QAbstractScrollArea *>(parent);
+ if (scrollArea && scrollArea->viewport() == q) {
+ QObjectData *scrollPrivate = static_cast<QWidget *>(scrollArea)->d_ptr.data();
+ QAbstractScrollAreaPrivate *priv = static_cast<QAbstractScrollAreaPrivate *>(scrollPrivate);
+ oldBrushOrigin = painter->brushOrigin();
+ resetBrushOrigin = true;
+ painter->setBrushOrigin(-priv->contentsOffset());
+
+ }
+#endif // QT_NO_SCROLLAREA
+
+ const QBrush autoFillBrush = q->palette().brush(q->backgroundRole());
+
+ if ((flags & DrawAsRoot) && !(q->autoFillBackground() && autoFillBrush.isOpaque())) {
+ const QBrush bg = q->palette().brush(QPalette::Window);
+ fillRegion(painter, rgn, bg);
+ }
+
+ if (q->autoFillBackground())
+ fillRegion(painter, rgn, autoFillBrush);
+
+ if (q->testAttribute(Qt::WA_StyledBackground)) {
+ painter->setClipRegion(rgn);
+ QStyleOption opt;
+ opt.initFrom(q);
+ q->style()->drawPrimitive(QStyle::PE_Widget, &opt, painter, q);
+ }
+
+#ifndef QT_NO_SCROLLAREA
+ if (resetBrushOrigin)
+ painter->setBrushOrigin(oldBrushOrigin);
+#endif // QT_NO_SCROLLAREA
+}
+
+/*
+ \internal
+ This function is called when a widget is hidden or destroyed.
+ It resets some application global pointers that should only refer active,
+ visible widgets.
+*/
+
+#ifdef Q_WS_MAC
+ extern QPointer<QWidget> qt_button_down;
+#else
+ extern QWidget *qt_button_down;
+#endif
+
+void QWidgetPrivate::deactivateWidgetCleanup()
+{
+ Q_Q(QWidget);
+ // If this was the active application window, reset it
+ if (QApplication::activeWindow() == q)
+ QApplication::setActiveWindow(0);
+ // If the is the active mouse press widget, reset it
+ if (q == qt_button_down)
+ qt_button_down = 0;
+}
+
+
+/*!
+ Returns a pointer to the widget with window identifer/handle \a
+ id.
+
+ The window identifier type depends on the underlying window
+ system, see \c qwindowdefs.h for the actual definition. If there
+ is no widget with this identifier, 0 is returned.
+*/
+
+QWidget *QWidget::find(WId id)
+{
+ return QWidgetPrivate::mapper ? QWidgetPrivate::mapper->value(id, 0) : 0;
+}
+
+
+
+/*!
+ \fn WId QWidget::internalWinId() const
+ \internal
+ Returns the window system identifier of the widget, or 0 if the widget is not created yet.
+
+*/
+
+/*!
+ \fn WId QWidget::winId() const
+
+ Returns the window system identifier of the widget.
+
+ Portable in principle, but if you use it you are probably about to
+ do something non-portable. Be careful.
+
+ If a widget is non-native (alien) and winId() is invoked on it, that widget
+ will be provided a native handle.
+
+ On Mac OS X, the type returned depends on which framework Qt was linked
+ against. If Qt is using Carbon, the {WId} is actually an HIViewRef. If Qt
+ is using Cocoa, {WId} is a pointer to an NSView.
+
+ This value may change at run-time. An event with type QEvent::WinIdChange
+ will be sent to the widget following a change in window system identifier.
+
+ \sa find()
+*/
+WId QWidget::winId() const
+{
+ if (!testAttribute(Qt::WA_WState_Created) || !internalWinId()) {
+#ifdef ALIEN_DEBUG
+ qDebug() << "QWidget::winId: creating native window for" << this;
+#endif
+ QWidget *that = const_cast<QWidget*>(this);
+ that->setAttribute(Qt::WA_NativeWindow);
+ that->d_func()->createWinId();
+ return that->data->winid;
+ }
+ return data->winid;
+}
+
+
+void QWidgetPrivate::createWinId(WId winid)
+{
+ Q_Q(QWidget);
+
+#ifdef ALIEN_DEBUG
+ qDebug() << "QWidgetPrivate::createWinId for" << q << winid;
+#endif
+ const bool forceNativeWindow = q->testAttribute(Qt::WA_NativeWindow);
+ if (!q->testAttribute(Qt::WA_WState_Created) || (forceNativeWindow && !q->internalWinId())) {
+ if (!q->isWindow()) {
+ QWidget *parent = q->parentWidget();
+ QWidgetPrivate *pd = parent->d_func();
+ if (forceNativeWindow && !q->testAttribute(Qt::WA_DontCreateNativeAncestors))
+ parent->setAttribute(Qt::WA_NativeWindow);
+ if (!parent->internalWinId()) {
+ pd->createWinId();
+ }
+
+ for (int i = 0; i < pd->children.size(); ++i) {
+ QWidget *w = qobject_cast<QWidget *>(pd->children.at(i));
+ if (w && !w->isWindow() && (!w->testAttribute(Qt::WA_WState_Created)
+ || (!w->internalWinId() && w->testAttribute(Qt::WA_NativeWindow)))) {
+ if (w!=q) {
+ w->create();
+ } else {
+ w->create(winid);
+ // if the window has already been created, we
+ // need to raise it to its proper stacking position
+ if (winid)
+ w->raise();
+ }
+ }
+ }
+ } else {
+ q->create();
+ }
+ }
+}
+
+
+/*!
+\internal
+Ensures that the widget has a window system identifier, i.e. that it is known to the windowing system.
+
+*/
+
+void QWidget::createWinId()
+{
+ Q_D(QWidget);
+#ifdef ALIEN_DEBUG
+ qDebug() << "QWidget::createWinId" << this;
+#endif
+// qWarning("QWidget::createWinId is obsolete, please fix your code.");
+ d->createWinId();
+}
+
+/*!
+ \since 4.4
+
+ Returns the effective window system identifier of the widget, i.e. the
+ native parent's window system identifier.
+
+ If the widget is native, this function returns the native widget ID.
+ Otherwise, the window ID of the first native parent widget, i.e., the
+ top-level widget that contains this widget, is returned.
+
+ \note We recommend that you do not store this value as it is likely to
+ change at run-time.
+
+ \sa nativeParentWidget()
+*/
+WId QWidget::effectiveWinId() const
+{
+ WId id = internalWinId();
+ if (id || !testAttribute(Qt::WA_WState_Created))
+ return id;
+ QWidget *realParent = nativeParentWidget();
+ if (!realParent && d_func()->inSetParent) {
+ // In transitional state. This is really just a workaround. The real problem
+ // is that QWidgetPrivate::setParent_sys (platform specific code) first sets
+ // the window id to 0 (setWinId(0)) before it sets the Qt::WA_WState_Created
+ // attribute to false. The correct way is to do it the other way around, and
+ // in that case the Qt::WA_WState_Created logic above will kick in and
+ // return 0 whenever the widget is in a transitional state. However, changing
+ // the original logic for all platforms is far more intrusive and might
+ // break existing applications.
+ // Note: The widget can only be in a transitional state when changing its
+ // parent -- everything else is an internal error -- hence explicitly checking
+ // against 'inSetParent' rather than doing an unconditional return whenever
+ // 'realParent' is 0 (which may cause strange artifacts and headache later).
+ return 0;
+ }
+ // This widget *must* have a native parent widget.
+ Q_ASSERT(realParent);
+ Q_ASSERT(realParent->internalWinId());
+ return realParent->internalWinId();
+}
+
+#ifndef QT_NO_STYLE_STYLESHEET
+
+/*!
+ \property QWidget::styleSheet
+ \brief the widget's style sheet
+ \since 4.2
+
+ The style sheet contains a textual description of customizations to the
+ widget's style, as described in the \l{Qt Style Sheets} document.
+
+ Since Qt 4.5, Qt style sheets fully supports Mac OS X.
+
+ \warning Qt style sheets are currently not supported for custom QStyle
+ subclasses. We plan to address this in some future release.
+
+ \sa setStyle(), QApplication::styleSheet, {Qt Style Sheets}
+*/
+QString QWidget::styleSheet() const
+{
+ Q_D(const QWidget);
+ if (!d->extra)
+ return QString();
+ return d->extra->styleSheet;
+}
+
+void QWidget::setStyleSheet(const QString& styleSheet)
+{
+ Q_D(QWidget);
+ d->createExtra();
+
+ QStyleSheetStyle *proxy = qobject_cast<QStyleSheetStyle *>(d->extra->style);
+ d->extra->styleSheet = styleSheet;
+ if (styleSheet.isEmpty()) { // stylesheet removed
+ if (!proxy)
+ return;
+
+ d->inheritStyle();
+ return;
+ }
+
+ if (proxy) { // style sheet update
+ proxy->repolish(this);
+ return;
+ }
+
+ if (testAttribute(Qt::WA_SetStyle)) {
+ d->setStyle_helper(new QStyleSheetStyle(d->extra->style), true);
+ } else {
+ d->setStyle_helper(new QStyleSheetStyle(0), true);
+ }
+}
+
+#endif // QT_NO_STYLE_STYLESHEET
+
+/*!
+ \sa QWidget::setStyle(), QApplication::setStyle(), QApplication::style()
+*/
+
+QStyle *QWidget::style() const
+{
+ Q_D(const QWidget);
+
+ if (d->extra && d->extra->style)
+ return d->extra->style;
+ return QApplication::style();
+}
+
+/*!
+ Sets the widget's GUI style to \a style. The ownership of the style
+ object is not transferred.
+
+ If no style is set, the widget uses the application's style,
+ QApplication::style() instead.
+
+ Setting a widget's style has no effect on existing or future child
+ widgets.
+
+ \warning This function is particularly useful for demonstration
+ purposes, where you want to show Qt's styling capabilities. Real
+ applications should avoid it and use one consistent GUI style
+ instead.
+
+ \warning Qt style sheets are currently not supported for custom QStyle
+ subclasses. We plan to address this in some future release.
+
+ \sa style(), QStyle, QApplication::style(), QApplication::setStyle()
+*/
+
+void QWidget::setStyle(QStyle *style)
+{
+ Q_D(QWidget);
+ setAttribute(Qt::WA_SetStyle, style != 0);
+ d->createExtra();
+#ifndef QT_NO_STYLE_STYLESHEET
+ if (QStyleSheetStyle *proxy = qobject_cast<QStyleSheetStyle *>(style)) {
+ //if for some reason someone try to set a QStyleSheetStyle, ref it
+ //(this may happen for exemple in QButtonDialogBox which propagates its style)
+ proxy->ref();
+ d->setStyle_helper(style, false);
+ } else if (qobject_cast<QStyleSheetStyle *>(d->extra->style) || !qApp->styleSheet().isEmpty()) {
+ // if we have an application stylesheet or have a proxy already, propagate
+ d->setStyle_helper(new QStyleSheetStyle(style), true);
+ } else
+#endif
+ d->setStyle_helper(style, false);
+}
+
+void QWidgetPrivate::setStyle_helper(QStyle *newStyle, bool propagate, bool
+#ifdef Q_WS_MAC
+ metalHack
+#endif
+ )
+{
+ Q_Q(QWidget);
+ QStyle *oldStyle = q->style();
+#ifndef QT_NO_STYLE_STYLESHEET
+ QWeakPointer<QStyle> origStyle;
+#endif
+
+#ifdef Q_WS_MAC
+ // the metalhack boolean allows Qt/Mac to do a proper re-polish depending
+ // on how the Qt::WA_MacBrushedMetal attribute is set. It is only ever
+ // set when changing that attribute and passes the widget's CURRENT style.
+ // therefore no need to do a reassignment.
+ if (!metalHack)
+#endif
+ {
+ createExtra();
+
+#ifndef QT_NO_STYLE_STYLESHEET
+ origStyle = extra->style.data();
+#endif
+ extra->style = newStyle;
+ }
+
+ // repolish
+ if (q->windowType() != Qt::Desktop) {
+ if (polished) {
+ oldStyle->unpolish(q);
+#ifdef Q_WS_MAC
+ if (metalHack)
+ macUpdateMetalAttribute();
+#endif
+ q->style()->polish(q);
+#ifdef Q_WS_MAC
+ } else if (metalHack) {
+ macUpdateMetalAttribute();
+#endif
+ }
+ }
+
+ if (propagate) {
+ for (int i = 0; i < children.size(); ++i) {
+ QWidget *c = qobject_cast<QWidget*>(children.at(i));
+ if (c)
+ c->d_func()->inheritStyle();
+ }
+ }
+
+#ifndef QT_NO_STYLE_STYLESHEET
+ if (!qobject_cast<QStyleSheetStyle*>(newStyle)) {
+ if (const QStyleSheetStyle* cssStyle = qobject_cast<QStyleSheetStyle*>(origStyle.data())) {
+ cssStyle->clearWidgetFont(q);
+ }
+ }
+#endif
+
+ QEvent e(QEvent::StyleChange);
+ QApplication::sendEvent(q, &e);
+#ifdef QT3_SUPPORT
+ q->styleChange(*oldStyle);
+#endif
+
+#ifndef QT_NO_STYLE_STYLESHEET
+ // dereference the old stylesheet style
+ if (QStyleSheetStyle *proxy = qobject_cast<QStyleSheetStyle *>(origStyle.data()))
+ proxy->deref();
+#endif
+}
+
+// Inherits style from the current parent and propagates it as necessary
+void QWidgetPrivate::inheritStyle()
+{
+#ifndef QT_NO_STYLE_STYLESHEET
+ Q_Q(QWidget);
+
+ QStyleSheetStyle *proxy = extra ? qobject_cast<QStyleSheetStyle *>(extra->style) : 0;
+
+ if (!q->styleSheet().isEmpty()) {
+ Q_ASSERT(proxy);
+ proxy->repolish(q);
+ return;
+ }
+
+ QStyle *origStyle = proxy ? proxy->base : (extra ? (QStyle*)extra->style : 0);
+ QWidget *parent = q->parentWidget();
+ QStyle *parentStyle = (parent && parent->d_func()->extra) ? (QStyle*)parent->d_func()->extra->style : 0;
+ // If we have stylesheet on app or parent has stylesheet style, we need
+ // to be running a proxy
+ if (!qApp->styleSheet().isEmpty() || qobject_cast<QStyleSheetStyle *>(parentStyle)) {
+ QStyle *newStyle = parentStyle;
+ if (q->testAttribute(Qt::WA_SetStyle))
+ newStyle = new QStyleSheetStyle(origStyle);
+ else if (QStyleSheetStyle *newProxy = qobject_cast<QStyleSheetStyle *>(parentStyle))
+ newProxy->ref();
+
+ setStyle_helper(newStyle, true);
+ return;
+ }
+
+ // So, we have no stylesheet on parent/app and we have an empty stylesheet
+ // we just need our original style back
+ if (origStyle == (extra ? (QStyle*)extra->style : 0)) // is it any different?
+ return;
+
+ // We could have inherited the proxy from our parent (which has a custom style)
+ // In such a case we need to start following the application style (i.e revert
+ // the propagation behavior of QStyleSheetStyle)
+ if (!q->testAttribute(Qt::WA_SetStyle))
+ origStyle = 0;
+
+ setStyle_helper(origStyle, true);
+#endif // QT_NO_STYLE_STYLESHEET
+}
+
+#ifdef QT3_SUPPORT
+/*!
+ \overload
+
+ Sets the widget's GUI style to \a style using the QStyleFactory.
+*/
+QStyle* QWidget::setStyle(const QString &style)
+{
+ QStyle *s = QStyleFactory::create(style);
+ setStyle(s);
+ return s;
+}
+#endif
+
+/*!
+ \fn bool QWidget::isWindow() const
+
+ Returns true if the widget is an independent window, otherwise
+ returns false.
+
+ A window is a widget that isn't visually the child of any other
+ widget and that usually has a frame and a
+ \l{QWidget::setWindowTitle()}{window title}.
+
+ A window can have a \l{QWidget::parentWidget()}{parent widget}.
+ It will then be grouped with its parent and deleted when the
+ parent is deleted, minimized when the parent is minimized etc. If
+ supported by the window manager, it will also have a common
+ taskbar entry with its parent.
+
+ QDialog and QMainWindow widgets are by default windows, even if a
+ parent widget is specified in the constructor. This behavior is
+ specified by the Qt::Window flag.
+
+ \sa window(), isModal(), parentWidget()
+*/
+
+/*!
+ \property QWidget::modal
+ \brief whether the widget is a modal widget
+
+ This property only makes sense for windows. A modal widget
+ prevents widgets in all other windows from getting any input.
+
+ By default, this property is false.
+
+ \sa isWindow(), windowModality, QDialog
+*/
+
+/*!
+ \property QWidget::windowModality
+ \brief which windows are blocked by the modal widget
+ \since 4.1
+
+ This property only makes sense for windows. A modal widget
+ prevents widgets in other windows from getting input. The value of
+ this property controls which windows are blocked when the widget
+ is visible. Changing this property while the window is visible has
+ no effect; you must hide() the widget first, then show() it again.
+
+ By default, this property is Qt::NonModal.
+
+ \sa isWindow(), QWidget::modal, QDialog
+*/
+
+Qt::WindowModality QWidget::windowModality() const
+{
+ return static_cast<Qt::WindowModality>(data->window_modality);
+}
+
+void QWidget::setWindowModality(Qt::WindowModality windowModality)
+{
+ data->window_modality = windowModality;
+ // setModal_sys() will be called by setAttribute()
+ setAttribute(Qt::WA_ShowModal, (data->window_modality != Qt::NonModal));
+ setAttribute(Qt::WA_SetWindowModality, true);
+}
+
+/*!
+ \fn bool QWidget::underMouse() const
+
+ Returns true if the widget is under the mouse cursor; otherwise
+ returns false.
+
+ This value is not updated properly during drag and drop
+ operations.
+
+ \sa enterEvent(), leaveEvent()
+*/
+
+/*!
+ \property QWidget::minimized
+ \brief whether this widget is minimized (iconified)
+
+ This property is only relevant for windows.
+
+ By default, this property is false.
+
+ \sa showMinimized(), visible, show(), hide(), showNormal(), maximized
+*/
+bool QWidget::isMinimized() const
+{ return data->window_state & Qt::WindowMinimized; }
+
+/*!
+ Shows the widget minimized, as an icon.
+
+ Calling this function only affects \l{isWindow()}{windows}.
+
+ \sa showNormal(), showMaximized(), show(), hide(), isVisible(),
+ isMinimized()
+*/
+void QWidget::showMinimized()
+{
+ bool isMin = isMinimized();
+ if (isMin && isVisible())
+ return;
+
+ ensurePolished();
+#ifdef QT3_SUPPORT
+ if (parent())
+ QApplication::sendPostedEvents(parent(), QEvent::ChildInserted);
+#endif
+
+ if (!isMin)
+ setWindowState((windowState() & ~Qt::WindowActive) | Qt::WindowMinimized);
+ show();
+}
+
+/*!
+ \property QWidget::maximized
+ \brief whether this widget is maximized
+
+ This property is only relevant for windows.
+
+ \note Due to limitations on some window systems, this does not always
+ report the expected results (e.g., if the user on X11 maximizes the
+ window via the window manager, Qt has no way of distinguishing this
+ from any other resize). This is expected to improve as window manager
+ protocols evolve.
+
+ By default, this property is false.
+
+ \sa windowState(), showMaximized(), visible, show(), hide(), showNormal(), minimized
+*/
+bool QWidget::isMaximized() const
+{ return data->window_state & Qt::WindowMaximized; }
+
+
+
+/*!
+ Returns the current window state. The window state is a OR'ed
+ combination of Qt::WindowState: Qt::WindowMinimized,
+ Qt::WindowMaximized, Qt::WindowFullScreen, and Qt::WindowActive.
+
+ \sa Qt::WindowState setWindowState()
+ */
+Qt::WindowStates QWidget::windowState() const
+{
+ return Qt::WindowStates(data->window_state);
+}
+
+/*!\internal
+
+ The function sets the window state on child widgets similar to
+ setWindowState(). The difference is that the window state changed
+ event has the isOverride() flag set. It exists mainly to keep
+ Q3Workspace working.
+ */
+void QWidget::overrideWindowState(Qt::WindowStates newstate)
+{
+ QWindowStateChangeEvent e(Qt::WindowStates(data->window_state), true);
+ data->window_state = newstate;
+ QApplication::sendEvent(this, &e);
+}
+
+/*!
+ \fn void QWidget::setWindowState(Qt::WindowStates windowState)
+
+ Sets the window state to \a windowState. The window state is a OR'ed
+ combination of Qt::WindowState: Qt::WindowMinimized,
+ Qt::WindowMaximized, Qt::WindowFullScreen, and Qt::WindowActive.
+
+ If the window is not visible (i.e. isVisible() returns false), the
+ window state will take effect when show() is called. For visible
+ windows, the change is immediate. For example, to toggle between
+ full-screen and normal mode, use the following code:
+
+ \snippet doc/src/snippets/code/src_gui_kernel_qwidget.cpp 0
+
+ In order to restore and activate a minimized window (while
+ preserving its maximized and/or full-screen state), use the following:
+
+ \snippet doc/src/snippets/code/src_gui_kernel_qwidget.cpp 1
+
+ Calling this function will hide the widget. You must call show() to make
+ the widget visible again.
+
+ \note On some window systems Qt::WindowActive is not immediate, and may be
+ ignored in certain cases.
+
+ When the window state changes, the widget receives a changeEvent()
+ of type QEvent::WindowStateChange.
+
+ \sa Qt::WindowState windowState()
+*/
+
+/*!
+ \property QWidget::fullScreen
+ \brief whether the widget is shown in full screen mode
+
+ A widget in full screen mode occupies the whole screen area and does not
+ display window decorations, such as a title bar.
+
+ By default, this property is false.
+
+ \sa windowState(), minimized, maximized
+*/
+bool QWidget::isFullScreen() const
+{ return data->window_state & Qt::WindowFullScreen; }
+
+/*!
+ Shows the widget in full-screen mode.
+
+ Calling this function only affects \l{isWindow()}{windows}.
+
+ To return from full-screen mode, call showNormal().
+
+ Full-screen mode works fine under Windows, but has certain
+ problems under X. These problems are due to limitations of the
+ ICCCM protocol that specifies the communication between X11
+ clients and the window manager. ICCCM simply does not understand
+ the concept of non-decorated full-screen windows. Therefore, the
+ best we can do is to request a borderless window and place and
+ resize it to fill the entire screen. Depending on the window
+ manager, this may or may not work. The borderless window is
+ requested using MOTIF hints, which are at least partially
+ supported by virtually all modern window managers.
+
+ An alternative would be to bypass the window manager entirely and
+ create a window with the Qt::X11BypassWindowManagerHint flag. This
+ has other severe problems though, like totally broken keyboard focus
+ and very strange effects on desktop changes or when the user raises
+ other windows.
+
+ X11 window managers that follow modern post-ICCCM specifications
+ support full-screen mode properly.
+
+ \sa showNormal(), showMaximized(), show(), hide(), isVisible()
+*/
+void QWidget::showFullScreen()
+{
+#ifdef Q_WS_MAC
+ // If the unified toolbar is enabled, we have to disable it before going fullscreen.
+ QMainWindow *mainWindow = qobject_cast<QMainWindow*>(this);
+ if (mainWindow && mainWindow->unifiedTitleAndToolBarOnMac()) {
+ mainWindow->setUnifiedTitleAndToolBarOnMac(false);
+ QMainWindowLayout *mainLayout = qobject_cast<QMainWindowLayout*>(mainWindow->layout());
+ mainLayout->activateUnifiedToolbarAfterFullScreen = true;
+ }
+#endif // Q_WS_MAC
+ ensurePolished();
+#ifdef QT3_SUPPORT
+ if (parent())
+ QApplication::sendPostedEvents(parent(), QEvent::ChildInserted);
+#endif
+
+ setWindowState((windowState() & ~(Qt::WindowMinimized | Qt::WindowMaximized))
+ | Qt::WindowFullScreen);
+ show();
+ activateWindow();
+}
+
+/*!
+ Shows the widget maximized.
+
+ Calling this function only affects \l{isWindow()}{windows}.
+
+ On X11, this function may not work properly with certain window
+ managers. See the \l{Window Geometry} documentation for an explanation.
+
+ \sa setWindowState(), showNormal(), showMinimized(), show(), hide(), isVisible()
+*/
+void QWidget::showMaximized()
+{
+ ensurePolished();
+#ifdef QT3_SUPPORT
+ if (parent())
+ QApplication::sendPostedEvents(parent(), QEvent::ChildInserted);
+#endif
+
+ setWindowState((windowState() & ~(Qt::WindowMinimized | Qt::WindowFullScreen))
+ | Qt::WindowMaximized);
+#ifdef Q_WS_MAC
+ // If the unified toolbar was enabled before going fullscreen, we have to enable it back.
+ QMainWindow *mainWindow = qobject_cast<QMainWindow*>(this);
+ if (mainWindow)
+ {
+ QMainWindowLayout *mainLayout = qobject_cast<QMainWindowLayout*>(mainWindow->layout());
+ if (mainLayout->activateUnifiedToolbarAfterFullScreen) {
+ mainWindow->setUnifiedTitleAndToolBarOnMac(true);
+ mainLayout->activateUnifiedToolbarAfterFullScreen = false;
+ }
+ }
+#endif // Q_WS_MAC
+ show();
+}
+
+/*!
+ Restores the widget after it has been maximized or minimized.
+
+ Calling this function only affects \l{isWindow()}{windows}.
+
+ \sa setWindowState(), showMinimized(), showMaximized(), show(), hide(), isVisible()
+*/
+void QWidget::showNormal()
+{
+ ensurePolished();
+#ifdef QT3_SUPPORT
+ if (parent())
+ QApplication::sendPostedEvents(parent(), QEvent::ChildInserted);
+#endif
+
+ setWindowState(windowState() & ~(Qt::WindowMinimized
+ | Qt::WindowMaximized
+ | Qt::WindowFullScreen));
+#ifdef Q_WS_MAC
+ // If the unified toolbar was enabled before going fullscreen, we have to enable it back.
+ QMainWindow *mainWindow = qobject_cast<QMainWindow*>(this);
+ if (mainWindow)
+ {
+ QMainWindowLayout *mainLayout = qobject_cast<QMainWindowLayout*>(mainWindow->layout());
+ if (mainLayout->activateUnifiedToolbarAfterFullScreen) {
+ mainWindow->setUnifiedTitleAndToolBarOnMac(true);
+ mainLayout->activateUnifiedToolbarAfterFullScreen = false;
+ }
+ }
+#endif // Q_WS_MAC
+ show();
+}
+
+/*!
+ Returns true if this widget would become enabled if \a ancestor is
+ enabled; otherwise returns false.
+
+
+
+ This is the case if neither the widget itself nor every parent up
+ to but excluding \a ancestor has been explicitly disabled.
+
+ isEnabledTo(0) is equivalent to isEnabled().
+
+ \sa setEnabled() enabled
+*/
+
+bool QWidget::isEnabledTo(QWidget* ancestor) const
+{
+ const QWidget * w = this;
+ while (!w->testAttribute(Qt::WA_ForceDisabled)
+ && !w->isWindow()
+ && w->parentWidget()
+ && w->parentWidget() != ancestor)
+ w = w->parentWidget();
+ return !w->testAttribute(Qt::WA_ForceDisabled);
+}
+
+#ifndef QT_NO_ACTION
+/*!
+ Appends the action \a action to this widget's list of actions.
+
+ All QWidgets have a list of \l{QAction}s, however they can be
+ represented graphically in many different ways. The default use of
+ the QAction list (as returned by actions()) is to create a context
+ QMenu.
+
+ A QWidget should only have one of each action and adding an action
+ it already has will not cause the same action to be in the widget twice.
+
+ The ownership of \a action is not transferred to this QWidget.
+
+ \sa removeAction(), insertAction(), actions(), QMenu
+*/
+void QWidget::addAction(QAction *action)
+{
+ insertAction(0, action);
+}
+
+/*!
+ Appends the actions \a actions to this widget's list of actions.
+
+ \sa removeAction(), QMenu, addAction()
+*/
+void QWidget::addActions(QList<QAction*> actions)
+{
+ for(int i = 0; i < actions.count(); i++)
+ insertAction(0, actions.at(i));
+}
+
+/*!
+ Inserts the action \a action to this widget's list of actions,
+ before the action \a before. It appends the action if \a before is 0 or
+ \a before is not a valid action for this widget.
+
+ A QWidget should only have one of each action.
+
+ \sa removeAction(), addAction(), QMenu, contextMenuPolicy, actions()
+*/
+void QWidget::insertAction(QAction *before, QAction *action)
+{
+ if(!action) {
+ qWarning("QWidget::insertAction: Attempt to insert null action");
+ return;
+ }
+
+ Q_D(QWidget);
+ if(d->actions.contains(action))
+ removeAction(action);
+
+ int pos = d->actions.indexOf(before);
+ if (pos < 0) {
+ before = 0;
+ pos = d->actions.size();
+ }
+ d->actions.insert(pos, action);
+
+ QActionPrivate *apriv = action->d_func();
+ apriv->widgets.append(this);
+
+ QActionEvent e(QEvent::ActionAdded, action, before);
+ QApplication::sendEvent(this, &e);
+}
+
+/*!
+ Inserts the actions \a actions to this widget's list of actions,
+ before the action \a before. It appends the action if \a before is 0 or
+ \a before is not a valid action for this widget.
+
+ A QWidget can have at most one of each action.
+
+ \sa removeAction(), QMenu, insertAction(), contextMenuPolicy
+*/
+void QWidget::insertActions(QAction *before, QList<QAction*> actions)
+{
+ for(int i = 0; i < actions.count(); ++i)
+ insertAction(before, actions.at(i));
+}
+
+/*!
+ Removes the action \a action from this widget's list of actions.
+ \sa insertAction(), actions(), insertAction()
+*/
+void QWidget::removeAction(QAction *action)
+{
+ if (!action)
+ return;
+
+ Q_D(QWidget);
+
+ QActionPrivate *apriv = action->d_func();
+ apriv->widgets.removeAll(this);
+
+ if (d->actions.removeAll(action)) {
+ QActionEvent e(QEvent::ActionRemoved, action);
+ QApplication::sendEvent(this, &e);
+ }
+}
+
+/*!
+ Returns the (possibly empty) list of this widget's actions.
+
+ \sa contextMenuPolicy, insertAction(), removeAction()
+*/
+QList<QAction*> QWidget::actions() const
+{
+ Q_D(const QWidget);
+ return d->actions;
+}
+#endif // QT_NO_ACTION
+
+/*!
+ \fn bool QWidget::isEnabledToTLW() const
+ \obsolete
+
+ This function is deprecated. It is equivalent to isEnabled()
+*/
+
+/*!
+ \property QWidget::enabled
+ \brief whether the widget is enabled
+
+ An enabled widget handles keyboard and mouse events; a disabled
+ widget does not.
+
+ Some widgets display themselves differently when they are
+ disabled. For example a button might draw its label grayed out. If
+ your widget needs to know when it becomes enabled or disabled, you
+ can use the changeEvent() with type QEvent::EnabledChange.
+
+ Disabling a widget implicitly disables all its children. Enabling
+ respectively enables all child widgets unless they have been
+ explicitly disabled.
+
+ By default, this property is true.
+
+ \sa isEnabledTo(), QKeyEvent, QMouseEvent, changeEvent()
+*/
+void QWidget::setEnabled(bool enable)
+{
+ Q_D(QWidget);
+ setAttribute(Qt::WA_ForceDisabled, !enable);
+ d->setEnabled_helper(enable);
+}
+
+void QWidgetPrivate::setEnabled_helper(bool enable)
+{
+ Q_Q(QWidget);
+
+ if (enable && !q->isWindow() && q->parentWidget() && !q->parentWidget()->isEnabled())
+ return; // nothing we can do
+
+ if (enable != q->testAttribute(Qt::WA_Disabled))
+ return; // nothing to do
+
+ q->setAttribute(Qt::WA_Disabled, !enable);
+ updateSystemBackground();
+
+ if (!enable && q->window()->focusWidget() == q) {
+ bool parentIsEnabled = (!q->parentWidget() || q->parentWidget()->isEnabled());
+ if (!parentIsEnabled || !q->focusNextChild())
+ q->clearFocus();
+ }
+
+ Qt::WidgetAttribute attribute = enable ? Qt::WA_ForceDisabled : Qt::WA_Disabled;
+ for (int i = 0; i < children.size(); ++i) {
+ QWidget *w = qobject_cast<QWidget *>(children.at(i));
+ if (w && !w->testAttribute(attribute))
+ w->d_func()->setEnabled_helper(enable);
+ }
+#if defined(Q_WS_X11)
+ if (q->testAttribute(Qt::WA_SetCursor) || q->isWindow()) {
+ // enforce the windows behavior of clearing the cursor on
+ // disabled widgets
+ qt_x11_enforce_cursor(q);
+ }
+#elif defined(Q_WS_QPA)
+ if (q->testAttribute(Qt::WA_SetCursor) || q->isWindow()) {
+ // enforce the windows behavior of clearing the cursor on
+ // disabled widgets
+ qt_qpa_set_cursor(q, false);
+ }
+#endif
+#if defined(Q_WS_MAC)
+ setEnabled_helper_sys(enable);
+#endif
+#ifndef QT_NO_IM
+ if (q->testAttribute(Qt::WA_InputMethodEnabled) && q->hasFocus()) {
+ QWidget *focusWidget = effectiveFocusWidget();
+ QInputContext *qic = focusWidget->d_func()->inputContext();
+ if (enable) {
+ if (focusWidget->testAttribute(Qt::WA_InputMethodEnabled))
+ qic->setFocusWidget(focusWidget);
+ } else {
+ qic->reset();
+ qic->setFocusWidget(0);
+ }
+ }
+#endif //QT_NO_IM
+ QEvent e(QEvent::EnabledChange);
+ QApplication::sendEvent(q, &e);
+#ifdef QT3_SUPPORT
+ q->enabledChange(!enable); // compatibility
+#endif
+}
+
+/*!
+ \property QWidget::acceptDrops
+ \brief whether drop events are enabled for this widget
+
+ Setting this property to true announces to the system that this
+ widget \e may be able to accept drop events.
+
+ If the widget is the desktop (windowType() == Qt::Desktop), this may
+ fail if another application is using the desktop; you can call
+ acceptDrops() to test if this occurs.
+
+ \warning Do not modify this property in a drag and drop event handler.
+
+ By default, this property is false.
+
+ \sa {Drag and Drop}
+*/
+bool QWidget::acceptDrops() const
+{
+ return testAttribute(Qt::WA_AcceptDrops);
+}
+
+void QWidget::setAcceptDrops(bool on)
+{
+ setAttribute(Qt::WA_AcceptDrops, on);
+
+}
+
+/*!
+ \fn void QWidget::enabledChange(bool)
+
+ \internal
+ \obsolete
+*/
+
+/*!
+ \fn void QWidget::paletteChange(const QPalette &)
+
+ \internal
+ \obsolete
+*/
+
+/*!
+ \fn void QWidget::fontChange(const QFont &)
+
+ \internal
+ \obsolete
+*/
+
+/*!
+ \fn void QWidget::windowActivationChange(bool)
+
+ \internal
+ \obsolete
+*/
+
+/*!
+ \fn void QWidget::languageChange()
+
+ \obsolete
+*/
+
+/*!
+ \fn void QWidget::styleChange(QStyle& style)
+
+ \internal
+ \obsolete
+*/
+
+/*!
+ Disables widget input events if \a disable is true; otherwise
+ enables input events.
+
+ See the \l enabled documentation for more information.
+
+ \sa isEnabledTo(), QKeyEvent, QMouseEvent, changeEvent()
+*/
+void QWidget::setDisabled(bool disable)
+{
+ setEnabled(!disable);
+}
+
+/*!
+ \property QWidget::frameGeometry
+ \brief geometry of the widget relative to its parent including any
+ window frame
+
+ See the \l{Window Geometry} documentation for an overview of geometry
+ issues with windows.
+
+ By default, this property contains a value that depends on the user's
+ platform and screen geometry.
+
+ \sa geometry() x() y() pos()
+*/
+QRect QWidget::frameGeometry() const
+{
+ Q_D(const QWidget);
+ if (isWindow() && ! (windowType() == Qt::Popup)) {
+ QRect fs = d->frameStrut();
+ return QRect(data->crect.x() - fs.left(),
+ data->crect.y() - fs.top(),
+ data->crect.width() + fs.left() + fs.right(),
+ data->crect.height() + fs.top() + fs.bottom());
+ }
+ return data->crect;
+}
+
+/*!
+ \property QWidget::x
+
+ \brief the x coordinate of the widget relative to its parent including
+ any window frame
+
+ See the \l{Window Geometry} documentation for an overview of geometry
+ issues with windows.
+
+ By default, this property has a value of 0.
+
+ \sa frameGeometry, y, pos
+*/
+int QWidget::x() const
+{
+ Q_D(const QWidget);
+ if (isWindow() && ! (windowType() == Qt::Popup))
+ return data->crect.x() - d->frameStrut().left();
+ return data->crect.x();
+}
+
+/*!
+ \property QWidget::y
+ \brief the y coordinate of the widget relative to its parent and
+ including any window frame
+
+ See the \l{Window Geometry} documentation for an overview of geometry
+ issues with windows.
+
+ By default, this property has a value of 0.
+
+ \sa frameGeometry, x, pos
+*/
+int QWidget::y() const
+{
+ Q_D(const QWidget);
+ if (isWindow() && ! (windowType() == Qt::Popup))
+ return data->crect.y() - d->frameStrut().top();
+ return data->crect.y();
+}
+
+/*!
+ \property QWidget::pos
+ \brief the position of the widget within its parent widget
+
+ If the widget is a window, the position is that of the widget on
+ the desktop, including its frame.
+
+ When changing the position, the widget, if visible, receives a
+ move event (moveEvent()) immediately. If the widget is not
+ currently visible, it is guaranteed to receive an event before it
+ is shown.
+
+ By default, this property contains a position that refers to the
+ origin.
+
+ \warning Calling move() or setGeometry() inside moveEvent() can
+ lead to infinite recursion.
+
+ See the \l{Window Geometry} documentation for an overview of geometry
+ issues with windows.
+
+ \sa frameGeometry, size x(), y()
+*/
+QPoint QWidget::pos() const
+{
+ Q_D(const QWidget);
+ if (isWindow() && ! (windowType() == Qt::Popup)) {
+ QRect fs = d->frameStrut();
+ return QPoint(data->crect.x() - fs.left(), data->crect.y() - fs.top());
+ }
+ return data->crect.topLeft();
+}
+
+/*!
+ \property QWidget::geometry
+ \brief the geometry of the widget relative to its parent and
+ excluding the window frame
+
+ When changing the geometry, the widget, if visible, receives a
+ move event (moveEvent()) and/or a resize event (resizeEvent())
+ immediately. If the widget is not currently visible, it is
+ guaranteed to receive appropriate events before it is shown.
+
+ The size component is adjusted if it lies outside the range
+ defined by minimumSize() and maximumSize().
+
+ \warning Calling setGeometry() inside resizeEvent() or moveEvent()
+ can lead to infinite recursion.
+
+ See the \l{Window Geometry} documentation for an overview of geometry
+ issues with windows.
+
+ By default, this property contains a value that depends on the user's
+ platform and screen geometry.
+
+ \sa frameGeometry(), rect(), move(), resize(), moveEvent(),
+ resizeEvent(), minimumSize(), maximumSize()
+*/
+
+/*!
+ \property QWidget::normalGeometry
+
+ \brief the geometry of the widget as it will appear when shown as
+ a normal (not maximized or full screen) top-level widget
+
+ For child widgets this property always holds an empty rectangle.
+
+ By default, this property contains an empty rectangle.
+
+ \sa QWidget::windowState(), QWidget::geometry
+*/
+
+/*!
+ \property QWidget::size
+ \brief the size of the widget excluding any window frame
+
+ If the widget is visible when it is being resized, it receives a resize event
+ (resizeEvent()) immediately. If the widget is not currently
+ visible, it is guaranteed to receive an event before it is shown.
+
+ The size is adjusted if it lies outside the range defined by
+ minimumSize() and maximumSize().
+
+ By default, this property contains a value that depends on the user's
+ platform and screen geometry.
+
+ \warning Calling resize() or setGeometry() inside resizeEvent() can
+ lead to infinite recursion.
+
+ \note Setting the size to \c{QSize(0, 0)} will cause the widget to not
+ appear on screen. This also applies to windows.
+
+ \sa pos, geometry, minimumSize, maximumSize, resizeEvent(), adjustSize()
+*/
+
+/*!
+ \property QWidget::width
+ \brief the width of the widget excluding any window frame
+
+ See the \l{Window Geometry} documentation for an overview of geometry
+ issues with windows.
+
+ \note Do not use this function to find the width of a screen on
+ a \l{QDesktopWidget}{multiple screen desktop}. Read
+ \l{QDesktopWidget#Screen Geometry}{this note} for details.
+
+ By default, this property contains a value that depends on the user's
+ platform and screen geometry.
+
+ \sa geometry, height, size
+*/
+
+/*!
+ \property QWidget::height
+ \brief the height of the widget excluding any window frame
+
+ See the \l{Window Geometry} documentation for an overview of geometry
+ issues with windows.
+
+ \note Do not use this function to find the height of a screen
+ on a \l{QDesktopWidget}{multiple screen desktop}. Read
+ \l{QDesktopWidget#Screen Geometry}{this note} for details.
+
+ By default, this property contains a value that depends on the user's
+ platform and screen geometry.
+
+ \sa geometry, width, size
+*/
+
+/*!
+ \property QWidget::rect
+ \brief the internal geometry of the widget excluding any window
+ frame
+
+ The rect property equals QRect(0, 0, width(), height()).
+
+ See the \l{Window Geometry} documentation for an overview of geometry
+ issues with windows.
+
+ By default, this property contains a value that depends on the user's
+ platform and screen geometry.
+
+ \sa size
+*/
+
+
+QRect QWidget::normalGeometry() const
+{
+ Q_D(const QWidget);
+ if (!d->extra || !d->extra->topextra)
+ return QRect();
+
+ if (!isMaximized() && !isFullScreen())
+ return geometry();
+
+ return d->topData()->normalGeometry;
+}
+
+
+/*!
+ \property QWidget::childrenRect
+ \brief the bounding rectangle of the widget's children
+
+ Hidden children are excluded.
+
+ By default, for a widget with no children, this property contains a
+ rectangle with zero width and height located at the origin.
+
+ \sa childrenRegion() geometry()
+*/
+
+QRect QWidget::childrenRect() const
+{
+ Q_D(const QWidget);
+ QRect r(0, 0, 0, 0);
+ for (int i = 0; i < d->children.size(); ++i) {
+ QWidget *w = qobject_cast<QWidget *>(d->children.at(i));
+ if (w && !w->isWindow() && !w->isHidden())
+ r |= w->geometry();
+ }
+ return r;
+}
+
+/*!
+ \property QWidget::childrenRegion
+ \brief the combined region occupied by the widget's children
+
+ Hidden children are excluded.
+
+ By default, for a widget with no children, this property contains an
+ empty region.
+
+ \sa childrenRect() geometry() mask()
+*/
+
+QRegion QWidget::childrenRegion() const
+{
+ Q_D(const QWidget);
+ QRegion r;
+ for (int i = 0; i < d->children.size(); ++i) {
+ QWidget *w = qobject_cast<QWidget *>(d->children.at(i));
+ if (w && !w->isWindow() && !w->isHidden()) {
+ QRegion mask = w->mask();
+ if (mask.isEmpty())
+ r |= w->geometry();
+ else
+ r |= mask.translated(w->pos());
+ }
+ }
+ return r;
+}
+
+
+/*!
+ \property QWidget::minimumSize
+ \brief the widget's minimum size
+
+ The widget cannot be resized to a smaller size than the minimum
+ widget size. The widget's size is forced to the minimum size if
+ the current size is smaller.
+
+ The minimum size set by this function will override the minimum size
+ defined by QLayout. In order to unset the minimum size, use a
+ value of \c{QSize(0, 0)}.
+
+ By default, this property contains a size with zero width and height.
+
+ \sa minimumWidth, minimumHeight, maximumSize, sizeIncrement
+*/
+
+QSize QWidget::minimumSize() const
+{
+ Q_D(const QWidget);
+ return d->extra ? QSize(d->extra->minw, d->extra->minh) : QSize(0, 0);
+}
+
+/*!
+ \property QWidget::maximumSize
+ \brief the widget's maximum size in pixels
+
+ The widget cannot be resized to a larger size than the maximum
+ widget size.
+
+ By default, this property contains a size in which both width and height
+ have values of 16777215.
+
+ \note The definition of the \c QWIDGETSIZE_MAX macro limits the maximum size
+ of widgets.
+
+ \sa maximumWidth, maximumHeight, minimumSize, sizeIncrement
+*/
+
+QSize QWidget::maximumSize() const
+{
+ Q_D(const QWidget);
+ return d->extra ? QSize(d->extra->maxw, d->extra->maxh)
+ : QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
+}
+
+
+/*!
+ \property QWidget::minimumWidth
+ \brief the widget's minimum width in pixels
+
+ This property corresponds to the width held by the \l minimumSize property.
+
+ By default, this property has a value of 0.
+
+ \sa minimumSize, minimumHeight
+*/
+
+/*!
+ \property QWidget::minimumHeight
+ \brief the widget's minimum height in pixels
+
+ This property corresponds to the height held by the \l minimumSize property.
+
+ By default, this property has a value of 0.
+
+ \sa minimumSize, minimumWidth
+*/
+
+/*!
+ \property QWidget::maximumWidth
+ \brief the widget's maximum width in pixels
+
+ This property corresponds to the width held by the \l maximumSize property.
+
+ By default, this property contains a value of 16777215.
+
+ \note The definition of the \c QWIDGETSIZE_MAX macro limits the maximum size
+ of widgets.
+
+ \sa maximumSize, maximumHeight
+*/
+
+/*!
+ \property QWidget::maximumHeight
+ \brief the widget's maximum height in pixels
+
+ This property corresponds to the height held by the \l maximumSize property.
+
+ By default, this property contains a value of 16777215.
+
+ \note The definition of the \c QWIDGETSIZE_MAX macro limits the maximum size
+ of widgets.
+
+ \sa maximumSize, maximumWidth
+*/
+
+/*!
+ \property QWidget::sizeIncrement
+ \brief the size increment of the widget
+
+ When the user resizes the window, the size will move in steps of
+ sizeIncrement().width() pixels horizontally and
+ sizeIncrement.height() pixels vertically, with baseSize() as the
+ basis. Preferred widget sizes are for non-negative integers \e i
+ and \e j:
+ \snippet doc/src/snippets/code/src_gui_kernel_qwidget.cpp 2
+
+ Note that while you can set the size increment for all widgets, it
+ only affects windows.
+
+ By default, this property contains a size with zero width and height.
+
+ \warning The size increment has no effect under Windows, and may
+ be disregarded by the window manager on X11.
+
+ \sa size, minimumSize, maximumSize
+*/
+QSize QWidget::sizeIncrement() const
+{
+ Q_D(const QWidget);
+ return (d->extra && d->extra->topextra)
+ ? QSize(d->extra->topextra->incw, d->extra->topextra->inch)
+ : QSize(0, 0);
+}
+
+/*!
+ \property QWidget::baseSize
+ \brief the base size of the widget
+
+ The base size is used to calculate a proper widget size if the
+ widget defines sizeIncrement().
+
+ By default, for a newly-created widget, this property contains a size with
+ zero width and height.
+
+ \sa setSizeIncrement()
+*/
+
+QSize QWidget::baseSize() const
+{
+ Q_D(const QWidget);
+ return (d->extra != 0 && d->extra->topextra != 0)
+ ? QSize(d->extra->topextra->basew, d->extra->topextra->baseh)
+ : QSize(0, 0);
+}
+
+bool QWidgetPrivate::setMinimumSize_helper(int &minw, int &minh)
+{
+ Q_Q(QWidget);
+
+ int mw = minw, mh = minh;
+ if (mw == QWIDGETSIZE_MAX)
+ mw = 0;
+ if (mh == QWIDGETSIZE_MAX)
+ mh = 0;
+ if (minw > QWIDGETSIZE_MAX || minh > QWIDGETSIZE_MAX) {
+ qWarning("QWidget::setMinimumSize: (%s/%s) "
+ "The largest allowed size is (%d,%d)",
+ q->objectName().toLocal8Bit().data(), q->metaObject()->className(), QWIDGETSIZE_MAX,
+ QWIDGETSIZE_MAX);
+ minw = mw = qMin<int>(minw, QWIDGETSIZE_MAX);
+ minh = mh = qMin<int>(minh, QWIDGETSIZE_MAX);
+ }
+ if (minw < 0 || minh < 0) {
+ qWarning("QWidget::setMinimumSize: (%s/%s) Negative sizes (%d,%d) "
+ "are not possible",
+ q->objectName().toLocal8Bit().data(), q->metaObject()->className(), minw, minh);
+ minw = mw = qMax(minw, 0);
+ minh = mh = qMax(minh, 0);
+ }
+ createExtra();
+ if (extra->minw == mw && extra->minh == mh)
+ return false;
+ extra->minw = mw;
+ extra->minh = mh;
+ extra->explicitMinSize = (mw ? Qt::Horizontal : 0) | (mh ? Qt::Vertical : 0);
+ return true;
+}
+
+/*!
+ \overload
+
+ This function corresponds to setMinimumSize(QSize(minw, minh)).
+ Sets the minimum width to \a minw and the minimum height to \a
+ minh.
+*/
+
+void QWidget::setMinimumSize(int minw, int minh)
+{
+ Q_D(QWidget);
+ if (!d->setMinimumSize_helper(minw, minh))
+ return;
+
+ if (isWindow())
+ d->setConstraints_sys();
+ if (minw > width() || minh > height()) {
+ bool resized = testAttribute(Qt::WA_Resized);
+ bool maximized = isMaximized();
+ resize(qMax(minw,width()), qMax(minh,height()));
+ setAttribute(Qt::WA_Resized, resized); //not a user resize
+ if (maximized)
+ data->window_state = data->window_state | Qt::WindowMaximized;
+ }
+#ifndef QT_NO_GRAPHICSVIEW
+ if (d->extra) {
+ if (d->extra->proxyWidget)
+ d->extra->proxyWidget->setMinimumSize(minw, minh);
+ }
+#endif
+ d->updateGeometry_helper(d->extra->minw == d->extra->maxw && d->extra->minh == d->extra->maxh);
+}
+
+bool QWidgetPrivate::setMaximumSize_helper(int &maxw, int &maxh)
+{
+ Q_Q(QWidget);
+ if (maxw > QWIDGETSIZE_MAX || maxh > QWIDGETSIZE_MAX) {
+ qWarning("QWidget::setMaximumSize: (%s/%s) "
+ "The largest allowed size is (%d,%d)",
+ q->objectName().toLocal8Bit().data(), q->metaObject()->className(), QWIDGETSIZE_MAX,
+ QWIDGETSIZE_MAX);
+ maxw = qMin<int>(maxw, QWIDGETSIZE_MAX);
+ maxh = qMin<int>(maxh, QWIDGETSIZE_MAX);
+ }
+ if (maxw < 0 || maxh < 0) {
+ qWarning("QWidget::setMaximumSize: (%s/%s) Negative sizes (%d,%d) "
+ "are not possible",
+ q->objectName().toLocal8Bit().data(), q->metaObject()->className(), maxw, maxh);
+ maxw = qMax(maxw, 0);
+ maxh = qMax(maxh, 0);
+ }
+ createExtra();
+ if (extra->maxw == maxw && extra->maxh == maxh)
+ return false;
+ extra->maxw = maxw;
+ extra->maxh = maxh;
+ extra->explicitMaxSize = (maxw != QWIDGETSIZE_MAX ? Qt::Horizontal : 0) |
+ (maxh != QWIDGETSIZE_MAX ? Qt::Vertical : 0);
+ return true;
+}
+
+/*!
+ \overload
+
+ This function corresponds to setMaximumSize(QSize(\a maxw, \a
+ maxh)). Sets the maximum width to \a maxw and the maximum height
+ to \a maxh.
+*/
+void QWidget::setMaximumSize(int maxw, int maxh)
+{
+ Q_D(QWidget);
+ if (!d->setMaximumSize_helper(maxw, maxh))
+ return;
+
+ if (isWindow())
+ d->setConstraints_sys();
+ if (maxw < width() || maxh < height()) {
+ bool resized = testAttribute(Qt::WA_Resized);
+ resize(qMin(maxw,width()), qMin(maxh,height()));
+ setAttribute(Qt::WA_Resized, resized); //not a user resize
+ }
+
+#ifndef QT_NO_GRAPHICSVIEW
+ if (d->extra) {
+ if (d->extra->proxyWidget)
+ d->extra->proxyWidget->setMaximumSize(maxw, maxh);
+ }
+#endif
+
+ d->updateGeometry_helper(d->extra->minw == d->extra->maxw && d->extra->minh == d->extra->maxh);
+}
+
+/*!
+ \overload
+
+ Sets the x (width) size increment to \a w and the y (height) size
+ increment to \a h.
+*/
+void QWidget::setSizeIncrement(int w, int h)
+{
+ Q_D(QWidget);
+ d->createTLExtra();
+ QTLWExtra* x = d->topData();
+ if (x->incw == w && x->inch == h)
+ return;
+ x->incw = w;
+ x->inch = h;
+ if (isWindow())
+ d->setConstraints_sys();
+}
+
+/*!
+ \overload
+
+ This corresponds to setBaseSize(QSize(\a basew, \a baseh)). Sets
+ the widgets base size to width \a basew and height \a baseh.
+*/
+void QWidget::setBaseSize(int basew, int baseh)
+{
+ Q_D(QWidget);
+ d->createTLExtra();
+ QTLWExtra* x = d->topData();
+ if (x->basew == basew && x->baseh == baseh)
+ return;
+ x->basew = basew;
+ x->baseh = baseh;
+ if (isWindow())
+ d->setConstraints_sys();
+}
+
+/*!
+ Sets both the minimum and maximum sizes of the widget to \a s,
+ thereby preventing it from ever growing or shrinking.
+
+ This will override the default size constraints set by QLayout.
+
+ To remove constraints, set the size to QWIDGETSIZE_MAX.
+
+ Alternatively, if you want the widget to have a
+ fixed size based on its contents, you can call
+ QLayout::setSizeConstraint(QLayout::SetFixedSize);
+
+ \sa maximumSize, minimumSize
+*/
+
+void QWidget::setFixedSize(const QSize & s)
+{
+ setFixedSize(s.width(), s.height());
+}
+
+
+/*!
+ \fn void QWidget::setFixedSize(int w, int h)
+ \overload
+
+ Sets the width of the widget to \a w and the height to \a h.
+*/
+
+void QWidget::setFixedSize(int w, int h)
+{
+ Q_D(QWidget);
+ bool minSizeSet = d->setMinimumSize_helper(w, h);
+ bool maxSizeSet = d->setMaximumSize_helper(w, h);
+ if (!minSizeSet && !maxSizeSet)
+ return;
+
+ if (isWindow())
+ d->setConstraints_sys();
+ else
+ d->updateGeometry_helper(true);
+
+ if (w != QWIDGETSIZE_MAX || h != QWIDGETSIZE_MAX)
+ resize(w, h);
+}
+
+void QWidget::setMinimumWidth(int w)
+{
+ Q_D(QWidget);
+ d->createExtra();
+ uint expl = d->extra->explicitMinSize | (w ? Qt::Horizontal : 0);
+ setMinimumSize(w, minimumSize().height());
+ d->extra->explicitMinSize = expl;
+}
+
+void QWidget::setMinimumHeight(int h)
+{
+ Q_D(QWidget);
+ d->createExtra();
+ uint expl = d->extra->explicitMinSize | (h ? Qt::Vertical : 0);
+ setMinimumSize(minimumSize().width(), h);
+ d->extra->explicitMinSize = expl;
+}
+
+void QWidget::setMaximumWidth(int w)
+{
+ Q_D(QWidget);
+ d->createExtra();
+ uint expl = d->extra->explicitMaxSize | (w == QWIDGETSIZE_MAX ? 0 : Qt::Horizontal);
+ setMaximumSize(w, maximumSize().height());
+ d->extra->explicitMaxSize = expl;
+}
+
+void QWidget::setMaximumHeight(int h)
+{
+ Q_D(QWidget);
+ d->createExtra();
+ uint expl = d->extra->explicitMaxSize | (h == QWIDGETSIZE_MAX ? 0 : Qt::Vertical);
+ setMaximumSize(maximumSize().width(), h);
+ d->extra->explicitMaxSize = expl;
+}
+
+/*!
+ Sets both the minimum and maximum width of the widget to \a w
+ without changing the heights. Provided for convenience.
+
+ \sa sizeHint() minimumSize() maximumSize() setFixedSize()
+*/
+
+void QWidget::setFixedWidth(int w)
+{
+ Q_D(QWidget);
+ d->createExtra();
+ uint explMin = d->extra->explicitMinSize | Qt::Horizontal;
+ uint explMax = d->extra->explicitMaxSize | Qt::Horizontal;
+ setMinimumSize(w, minimumSize().height());
+ setMaximumSize(w, maximumSize().height());
+ d->extra->explicitMinSize = explMin;
+ d->extra->explicitMaxSize = explMax;
+}
+
+
+/*!
+ Sets both the minimum and maximum heights of the widget to \a h
+ without changing the widths. Provided for convenience.
+
+ \sa sizeHint() minimumSize() maximumSize() setFixedSize()
+*/
+
+void QWidget::setFixedHeight(int h)
+{
+ Q_D(QWidget);
+ d->createExtra();
+ uint explMin = d->extra->explicitMinSize | Qt::Vertical;
+ uint explMax = d->extra->explicitMaxSize | Qt::Vertical;
+ setMinimumSize(minimumSize().width(), h);
+ setMaximumSize(maximumSize().width(), h);
+ d->extra->explicitMinSize = explMin;
+ d->extra->explicitMaxSize = explMax;
+}
+
+
+/*!
+ Translates the widget coordinate \a pos to the coordinate system
+ of \a parent. The \a parent must not be 0 and must be a parent
+ of the calling widget.
+
+ \sa mapFrom() mapToParent() mapToGlobal() underMouse()
+*/
+
+QPoint QWidget::mapTo(QWidget * parent, const QPoint & pos) const
+{
+ QPoint p = pos;
+ if (parent) {
+ const QWidget * w = this;
+ while (w != parent) {
+ Q_ASSERT_X(w, "QWidget::mapTo(QWidget *parent, const QPoint &pos)",
+ "parent must be in parent hierarchy");
+ p = w->mapToParent(p);
+ w = w->parentWidget();
+ }
+ }
+ return p;
+}
+
+
+/*!
+ Translates the widget coordinate \a pos from the coordinate system
+ of \a parent to this widget's coordinate system. The \a parent
+ must not be 0 and must be a parent of the calling widget.
+
+ \sa mapTo() mapFromParent() mapFromGlobal() underMouse()
+*/
+
+QPoint QWidget::mapFrom(QWidget * parent, const QPoint & pos) const
+{
+ QPoint p(pos);
+ if (parent) {
+ const QWidget * w = this;
+ while (w != parent) {
+ Q_ASSERT_X(w, "QWidget::mapFrom(QWidget *parent, const QPoint &pos)",
+ "parent must be in parent hierarchy");
+
+ p = w->mapFromParent(p);
+ w = w->parentWidget();
+ }
+ }
+ return p;
+}
+
+
+/*!
+ Translates the widget coordinate \a pos to a coordinate in the
+ parent widget.
+
+ Same as mapToGlobal() if the widget has no parent.
+
+ \sa mapFromParent() mapTo() mapToGlobal() underMouse()
+*/
+
+QPoint QWidget::mapToParent(const QPoint &pos) const
+{
+ return pos + data->crect.topLeft();
+}
+
+/*!
+ Translates the parent widget coordinate \a pos to widget
+ coordinates.
+
+ Same as mapFromGlobal() if the widget has no parent.
+
+ \sa mapToParent() mapFrom() mapFromGlobal() underMouse()
+*/
+
+QPoint QWidget::mapFromParent(const QPoint &pos) const
+{
+ return pos - data->crect.topLeft();
+}
+
+
+/*!
+ Returns the window for this widget, i.e. the next ancestor widget
+ that has (or could have) a window-system frame.
+
+ If the widget is a window, the widget itself is returned.
+
+ Typical usage is changing the window title:
+
+ \snippet doc/src/snippets/code/src_gui_kernel_qwidget.cpp 3
+
+ \sa isWindow()
+*/
+
+QWidget *QWidget::window() const
+{
+ QWidget *w = (QWidget *)this;
+ QWidget *p = w->parentWidget();
+ while (!w->isWindow() && p) {
+ w = p;
+ p = p->parentWidget();
+ }
+ return w;
+}
+
+/*!
+ \since 4.4
+
+ Returns the native parent for this widget, i.e. the next ancestor widget
+ that has a system identifier, or 0 if it does not have any native parent.
+
+ \sa effectiveWinId()
+*/
+QWidget *QWidget::nativeParentWidget() const
+{
+ QWidget *parent = parentWidget();
+ while (parent && !parent->internalWinId())
+ parent = parent->parentWidget();
+ return parent;
+}
+
+/*! \fn QWidget *QWidget::topLevelWidget() const
+ \obsolete
+
+ Use window() instead.
+*/
+
+#ifdef QT3_SUPPORT
+/*!
+ Returns the color role used for painting the widget's background.
+
+ Use QPalette(backgroundRole(()) instead.
+*/
+Qt::BackgroundMode QWidget::backgroundMode() const
+{
+ if (testAttribute(Qt::WA_NoSystemBackground))
+ return Qt::NoBackground;
+ switch(backgroundRole()) {
+ case QPalette::WindowText:
+ return Qt::PaletteForeground;
+ case QPalette::Button:
+ return Qt::PaletteButton;
+ case QPalette::Light:
+ return Qt::PaletteLight;
+ case QPalette::Midlight:
+ return Qt::PaletteMidlight;
+ case QPalette::Dark:
+ return Qt::PaletteDark;
+ case QPalette::Mid:
+ return Qt::PaletteMid;
+ case QPalette::Text:
+ return Qt::PaletteText;
+ case QPalette::BrightText:
+ return Qt::PaletteBrightText;
+ case QPalette::Base:
+ return Qt::PaletteBase;
+ case QPalette::Window:
+ return Qt::PaletteBackground;
+ case QPalette::Shadow:
+ return Qt::PaletteShadow;
+ case QPalette::Highlight:
+ return Qt::PaletteHighlight;
+ case QPalette::HighlightedText:
+ return Qt::PaletteHighlightedText;
+ case QPalette::ButtonText:
+ return Qt::PaletteButtonText;
+ case QPalette::Link:
+ return Qt::PaletteLink;
+ case QPalette::LinkVisited:
+ return Qt::PaletteLinkVisited;
+ default:
+ break;
+ }
+ return Qt::NoBackground;
+}
+
+/*!
+ \fn void QWidget::setBackgroundMode(Qt::BackgroundMode
+ widgetBackground, Qt::BackgroundMode paletteBackground)
+
+ Sets the color role used for painting the widget's background to
+ background mode \a widgetBackground. The \a paletteBackground mode
+ parameter is ignored.
+*/
+void QWidget::setBackgroundMode(Qt::BackgroundMode m, Qt::BackgroundMode)
+{
+ Q_D(QWidget);
+ if(m == Qt::NoBackground) {
+ setAttribute(Qt::WA_NoSystemBackground, true);
+ return;
+ }
+ setAttribute(Qt::WA_NoSystemBackground, false);
+ d->fg_role = QPalette::NoRole;
+ QPalette::ColorRole role = d->bg_role;
+ switch(m) {
+ case Qt::FixedColor:
+ case Qt::FixedPixmap:
+ break;
+ case Qt::PaletteForeground:
+ role = QPalette::WindowText;
+ break;
+ case Qt::PaletteButton:
+ role = QPalette::Button;
+ break;
+ case Qt::PaletteLight:
+ role = QPalette::Light;
+ break;
+ case Qt::PaletteMidlight:
+ role = QPalette::Midlight;
+ break;
+ case Qt::PaletteDark:
+ role = QPalette::Dark;
+ break;
+ case Qt::PaletteMid:
+ role = QPalette::Mid;
+ break;
+ case Qt::PaletteText:
+ role = QPalette::Text;
+ break;
+ case Qt::PaletteBrightText:
+ role = QPalette::BrightText;
+ break;
+ case Qt::PaletteBase:
+ role = QPalette::Base;
+ break;
+ case Qt::PaletteBackground:
+ role = QPalette::Window;
+ break;
+ case Qt::PaletteShadow:
+ role = QPalette::Shadow;
+ break;
+ case Qt::PaletteHighlight:
+ role = QPalette::Highlight;
+ break;
+ case Qt::PaletteHighlightedText:
+ role = QPalette::HighlightedText;
+ break;
+ case Qt::PaletteButtonText:
+ role = QPalette::ButtonText;
+ break;
+ case Qt::PaletteLink:
+ role = QPalette::Link;
+ break;
+ case Qt::PaletteLinkVisited:
+ role = QPalette::LinkVisited;
+ break;
+ case Qt::X11ParentRelative:
+ d->fg_role = role = QPalette::NoRole;
+ default:
+ break;
+ }
+ setBackgroundRole(role);
+}
+
+/*!
+ The widget mapper is no longer part of the public API.
+*/
+QT3_SUPPORT QWidgetMapper *QWidget::wmapper() { return QWidgetPrivate::mapper; }
+
+#endif
+
+
+/*!
+ Returns the background role of the widget.
+
+ The background role defines the brush from the widget's \l palette that
+ is used to render the background.
+
+ If no explicit background role is set, the widget inherts its parent
+ widget's background role.
+
+ \sa setBackgroundRole(), foregroundRole()
+ */
+QPalette::ColorRole QWidget::backgroundRole() const
+{
+
+ const QWidget *w = this;
+ do {
+ QPalette::ColorRole role = w->d_func()->bg_role;
+ if (role != QPalette::NoRole)
+ return role;
+ if (w->isWindow() || w->windowType() == Qt::SubWindow)
+ break;
+ w = w->parentWidget();
+ } while (w);
+ return QPalette::Window;
+}
+
+/*!
+ Sets the background role of the widget to \a role.
+
+ The background role defines the brush from the widget's \l palette that
+ is used to render the background.
+
+ If \a role is QPalette::NoRole, then the widget inherits its
+ parent's background role.
+
+ Note that styles are free to choose any color from the palette.
+ You can modify the palette or set a style sheet if you don't
+ achieve the result you want with setBackgroundRole().
+
+ \sa backgroundRole(), foregroundRole()
+ */
+
+void QWidget::setBackgroundRole(QPalette::ColorRole role)
+{
+ Q_D(QWidget);
+ d->bg_role = role;
+ d->updateSystemBackground();
+ d->propagatePaletteChange();
+ d->updateIsOpaque();
+}
+
+/*!
+ Returns the foreground role.
+
+ The foreground role defines the color from the widget's \l palette that
+ is used to draw the foreground.
+
+ If no explicit foreground role is set, the function returns a role
+ that contrasts with the background role.
+
+ \sa setForegroundRole(), backgroundRole()
+ */
+QPalette::ColorRole QWidget::foregroundRole() const
+{
+ Q_D(const QWidget);
+ QPalette::ColorRole rl = QPalette::ColorRole(d->fg_role);
+ if (rl != QPalette::NoRole)
+ return rl;
+ QPalette::ColorRole role = QPalette::WindowText;
+ switch (backgroundRole()) {
+ case QPalette::Button:
+ role = QPalette::ButtonText;
+ break;
+ case QPalette::Base:
+ role = QPalette::Text;
+ break;
+ case QPalette::Dark:
+ case QPalette::Shadow:
+ role = QPalette::Light;
+ break;
+ case QPalette::Highlight:
+ role = QPalette::HighlightedText;
+ break;
+ case QPalette::ToolTipBase:
+ role = QPalette::ToolTipText;
+ break;
+ default:
+ ;
+ }
+ return role;
+}
+
+/*!
+ Sets the foreground role of the widget to \a role.
+
+ The foreground role defines the color from the widget's \l palette that
+ is used to draw the foreground.
+
+ If \a role is QPalette::NoRole, the widget uses a foreground role
+ that contrasts with the background role.
+
+ Note that styles are free to choose any color from the palette.
+ You can modify the palette or set a style sheet if you don't
+ achieve the result you want with setForegroundRole().
+
+ \sa foregroundRole(), backgroundRole()
+ */
+void QWidget::setForegroundRole(QPalette::ColorRole role)
+{
+ Q_D(QWidget);
+ d->fg_role = role;
+ d->updateSystemBackground();
+ d->propagatePaletteChange();
+}
+
+/*!
+ \property QWidget::palette
+ \brief the widget's palette
+
+ This property describes the widget's palette. The palette is used by the
+ widget's style when rendering standard components, and is available as a
+ means to ensure that custom widgets can maintain consistency with the
+ native platform's look and feel. It's common that different platforms, or
+ different styles, have different palettes.
+
+ When you assign a new palette to a widget, the color roles from this
+ palette are combined with the widget's default palette to form the
+ widget's final palette. The palette entry for the widget's background role
+ is used to fill the widget's background (see QWidget::autoFillBackground),
+ and the foreground role initializes QPainter's pen.
+
+ The default depends on the system environment. QApplication maintains a
+ system/theme palette which serves as a default for all widgets. There may
+ also be special palette defaults for certain types of widgets (e.g., on
+ Windows XP and Vista, all classes that derive from QMenuBar have a special
+ default palette). You can also define default palettes for widgets
+ yourself by passing a custom palette and the name of a widget to
+ QApplication::setPalette(). Finally, the style always has the option of
+ polishing the palette as it's assigned (see QStyle::polish()).
+
+ QWidget propagates explicit palette roles from parent to child. If you
+ assign a brush or color to a specific role on a palette and assign that
+ palette to a widget, that role will propagate to all the widget's
+ children, overriding any system defaults for that role. Note that palettes
+ by default don't propagate to windows (see isWindow()) unless the
+ Qt::WA_WindowPropagation attribute is enabled.
+
+ QWidget's palette propagation is similar to its font propagation.
+
+ The current style, which is used to render the content of all standard Qt
+ widgets, is free to choose colors and brushes from the widget palette, or
+ in some cases, to ignore the palette (partially, or completely). In
+ particular, certain styles like GTK style, Mac style, Windows XP, and
+ Vista style, depend on third party APIs to render the content of widgets,
+ and these styles typically do not follow the palette. Because of this,
+ assigning roles to a widget's palette is not guaranteed to change the
+ appearance of the widget. Instead, you may choose to apply a \l
+ styleSheet. You can refer to our Knowledge Base article
+ \l{http://qt.nokia.com/developer/knowledgebase/22}{here} for more
+ information.
+
+ \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".
+
+ \sa QApplication::palette(), QWidget::font()
+*/
+const QPalette &QWidget::palette() const
+{
+ if (!isEnabled()) {
+ data->pal.setCurrentColorGroup(QPalette::Disabled);
+ } else if ((!isVisible() || isActiveWindow())
+#if defined(Q_OS_WIN) && !defined(Q_WS_WINCE)
+ && !QApplicationPrivate::isBlockedByModal(const_cast<QWidget *>(this))
+#endif
+ ) {
+ data->pal.setCurrentColorGroup(QPalette::Active);
+ } else {
+#ifdef Q_WS_MAC
+ extern bool qt_mac_can_clickThrough(const QWidget *); //qwidget_mac.cpp
+ if (qt_mac_can_clickThrough(this))
+ data->pal.setCurrentColorGroup(QPalette::Active);
+ else
+#endif
+ data->pal.setCurrentColorGroup(QPalette::Inactive);
+ }
+ return data->pal;
+}
+
+void QWidget::setPalette(const QPalette &palette)
+{
+ Q_D(QWidget);
+ setAttribute(Qt::WA_SetPalette, palette.resolve() != 0);
+
+ // Determine which palette is inherited from this widget's ancestors and
+ // QApplication::palette, resolve this against \a palette (attributes from
+ // the inherited palette are copied over this widget's palette). Then
+ // propagate this palette to this widget's children.
+ QPalette naturalPalette = d->naturalWidgetPalette(d->inheritedPaletteResolveMask);
+ QPalette resolvedPalette = palette.resolve(naturalPalette);
+ d->setPalette_helper(resolvedPalette);
+}
+
+/*!
+ \internal
+
+ Returns the palette that the widget \a w inherits from its ancestors and
+ QApplication::palette. \a inheritedMask is the combination of the widget's
+ ancestors palette request masks (i.e., which attributes from the parent
+ widget's palette are implicitly imposed on this widget by the user). Note
+ that this font does not take into account the palette set on \a w itself.
+*/
+QPalette QWidgetPrivate::naturalWidgetPalette(uint inheritedMask) const
+{
+ Q_Q(const QWidget);
+ QPalette naturalPalette = QApplication::palette(q);
+ if (!q->testAttribute(Qt::WA_StyleSheet)
+ && (!q->isWindow() || q->testAttribute(Qt::WA_WindowPropagation)
+#ifndef QT_NO_GRAPHICSVIEW
+ || (extra && extra->proxyWidget)
+#endif //QT_NO_GRAPHICSVIEW
+ )) {
+ if (QWidget *p = q->parentWidget()) {
+ if (!p->testAttribute(Qt::WA_StyleSheet)) {
+ if (!naturalPalette.isCopyOf(QApplication::palette())) {
+ QPalette inheritedPalette = p->palette();
+ inheritedPalette.resolve(inheritedMask);
+ naturalPalette = inheritedPalette.resolve(naturalPalette);
+ } else {
+ naturalPalette = p->palette();
+ }
+ }
+ }
+#ifndef QT_NO_GRAPHICSVIEW
+ else if (extra && extra->proxyWidget) {
+ QPalette inheritedPalette = extra->proxyWidget->palette();
+ inheritedPalette.resolve(inheritedMask);
+ naturalPalette = inheritedPalette.resolve(naturalPalette);
+ }
+#endif //QT_NO_GRAPHICSVIEW
+ }
+ naturalPalette.resolve(0);
+ return naturalPalette;
+}
+/*!
+ \internal
+
+ Determine which palette is inherited from this widget's ancestors and
+ QApplication::palette, resolve this against this widget's palette
+ (attributes from the inherited palette are copied over this widget's
+ palette). Then propagate this palette to this widget's children.
+*/
+void QWidgetPrivate::resolvePalette()
+{
+ QPalette naturalPalette = naturalWidgetPalette(inheritedPaletteResolveMask);
+ QPalette resolvedPalette = data.pal.resolve(naturalPalette);
+ setPalette_helper(resolvedPalette);
+}
+
+void QWidgetPrivate::setPalette_helper(const QPalette &palette)
+{
+ Q_Q(QWidget);
+ if (data.pal == palette && data.pal.resolve() == palette.resolve())
+ return;
+ data.pal = palette;
+ updateSystemBackground();
+ propagatePaletteChange();
+ updateIsOpaque();
+ q->update();
+ updateIsOpaque();
+}
+
+/*!
+ \property QWidget::font
+ \brief the font currently set for the widget
+
+ This property describes the widget's requested font. The font is used by
+ the widget's style when rendering standard components, and is available as
+ a means to ensure that custom widgets can maintain consistency with the
+ native platform's look and feel. It's common that different platforms, or
+ different styles, define different fonts for an application.
+
+ When you assign a new font to a widget, the properties from this font are
+ combined with the widget's default font to form the widget's final
+ font. You can call fontInfo() to get a copy of the widget's final
+ font. The final font is also used to initialize QPainter's font.
+
+ The default depends on the system environment. QApplication maintains a
+ system/theme font which serves as a default for all widgets. There may
+ also be special font defaults for certain types of widgets. You can also
+ define default fonts for widgets yourself by passing a custom font and the
+ name of a widget to QApplication::setFont(). Finally, the font is matched
+ against Qt's font database to find the best match.
+
+ QWidget propagates explicit font properties from parent to child. If you
+ change a specific property on a font and assign that font to a widget,
+ that property will propagate to all the widget's children, overriding any
+ system defaults for that property. Note that fonts by default don't
+ propagate to windows (see isWindow()) unless the Qt::WA_WindowPropagation
+ attribute is enabled.
+
+ QWidget's font propagation is similar to its palette propagation.
+
+ The current style, which is used to render the content of all standard Qt
+ widgets, is free to choose to use the widget font, or in some cases, to
+ ignore it (partially, or completely). In particular, certain styles like
+ GTK style, Mac style, Windows XP, and Vista style, apply special
+ modifications to the widget font to match the platform's native look and
+ feel. Because of this, assigning properties to a widget's font is not
+ guaranteed to change the appearance of the widget. Instead, you may choose
+ to apply a \l styleSheet.
+
+ \note If \l{Qt Style Sheets} are used on the same widget as setFont(),
+ style sheets will take precedence if the settings conflict.
+
+ \sa fontInfo(), fontMetrics()
+*/
+
+void QWidget::setFont(const QFont &font)
+{
+ Q_D(QWidget);
+
+#ifndef QT_NO_STYLE_STYLESHEET
+ const QStyleSheetStyle* style;
+ if (d->extra && (style = qobject_cast<const QStyleSheetStyle*>(d->extra->style))) {
+ style->saveWidgetFont(this, font);
+ }
+#endif
+
+ setAttribute(Qt::WA_SetFont, font.resolve() != 0);
+
+ // Determine which font is inherited from this widget's ancestors and
+ // QApplication::font, resolve this against \a font (attributes from the
+ // inherited font are copied over). Then propagate this font to this
+ // widget's children.
+ QFont naturalFont = d->naturalWidgetFont(d->inheritedFontResolveMask);
+ QFont resolvedFont = font.resolve(naturalFont);
+ d->setFont_helper(resolvedFont);
+}
+
+/*
+ \internal
+
+ Returns the font that the widget \a w inherits from its ancestors and
+ QApplication::font. \a inheritedMask is the combination of the widget's
+ ancestors font request masks (i.e., which attributes from the parent
+ widget's font are implicitly imposed on this widget by the user). Note
+ that this font does not take into account the font set on \a w itself.
+
+ ### Stylesheet has a different font propagation mechanism. When a stylesheet
+ is applied, fonts are not propagated anymore
+*/
+QFont QWidgetPrivate::naturalWidgetFont(uint inheritedMask) const
+{
+ Q_Q(const QWidget);
+ QFont naturalFont = QApplication::font(q);
+ if (!q->testAttribute(Qt::WA_StyleSheet)
+ && (!q->isWindow() || q->testAttribute(Qt::WA_WindowPropagation)
+#ifndef QT_NO_GRAPHICSVIEW
+ || (extra && extra->proxyWidget)
+#endif //QT_NO_GRAPHICSVIEW
+ )) {
+ if (QWidget *p = q->parentWidget()) {
+ if (!p->testAttribute(Qt::WA_StyleSheet)) {
+ if (!naturalFont.isCopyOf(QApplication::font())) {
+ QFont inheritedFont = p->font();
+ inheritedFont.resolve(inheritedMask);
+ naturalFont = inheritedFont.resolve(naturalFont);
+ } else {
+ naturalFont = p->font();
+ }
+ }
+ }
+#ifndef QT_NO_GRAPHICSVIEW
+ else if (extra && extra->proxyWidget) {
+ QFont inheritedFont = extra->proxyWidget->font();
+ inheritedFont.resolve(inheritedMask);
+ naturalFont = inheritedFont.resolve(naturalFont);
+ }
+#endif //QT_NO_GRAPHICSVIEW
+ }
+ naturalFont.resolve(0);
+ return naturalFont;
+}
+
+/*!
+ \internal
+
+ Determine which font is implicitly imposed on this widget by its ancestors
+ and QApplication::font, resolve this against its own font (attributes from
+ the implicit font are copied over). Then propagate this font to this
+ widget's children.
+*/
+void QWidgetPrivate::resolveFont()
+{
+ QFont naturalFont = naturalWidgetFont(inheritedFontResolveMask);
+ QFont resolvedFont = data.fnt.resolve(naturalFont);
+ setFont_helper(resolvedFont);
+}
+
+/*!
+ \internal
+
+ Assign \a font to this widget, and propagate it to all children, except
+ style sheet widgets (handled differently) and windows that don't enable
+ window propagation. \a implicitMask is the union of all ancestor widgets'
+ font request masks, and determines which attributes from this widget's
+ font should propagate.
+*/
+void QWidgetPrivate::updateFont(const QFont &font)
+{
+ Q_Q(QWidget);
+#ifndef QT_NO_STYLE_STYLESHEET
+ const QStyleSheetStyle* cssStyle;
+ cssStyle = extra ? qobject_cast<const QStyleSheetStyle*>(extra->style) : 0;
+#endif
+
+#ifdef QT3_SUPPORT
+ QFont old = data.fnt;
+#endif
+ data.fnt = QFont(font, q);
+#if defined(Q_WS_X11)
+ // make sure the font set on this widget is associated with the correct screen
+ data.fnt.x11SetScreen(xinfo.screen());
+#endif
+ // Combine new mask with natural mask and propagate to children.
+#ifndef QT_NO_GRAPHICSVIEW
+ if (!q->parentWidget() && extra && extra->proxyWidget) {
+ QGraphicsProxyWidget *p = extra->proxyWidget;
+ inheritedFontResolveMask = p->d_func()->inheritedFontResolveMask | p->font().resolve();
+ } else
+#endif //QT_NO_GRAPHICSVIEW
+ if (q->isWindow() && !q->testAttribute(Qt::WA_WindowPropagation)) {
+ inheritedFontResolveMask = 0;
+ }
+ uint newMask = data.fnt.resolve() | inheritedFontResolveMask;
+
+ for (int i = 0; i < children.size(); ++i) {
+ QWidget *w = qobject_cast<QWidget*>(children.at(i));
+ if (w) {
+ if (0) {
+#ifndef QT_NO_STYLE_STYLESHEET
+ } else if (w->testAttribute(Qt::WA_StyleSheet)) {
+ // Style sheets follow a different font propagation scheme.
+ if (cssStyle)
+ cssStyle->updateStyleSheetFont(w);
+#endif
+ } else if ((!w->isWindow() || w->testAttribute(Qt::WA_WindowPropagation))) {
+ // Propagate font changes.
+ QWidgetPrivate *wd = w->d_func();
+ wd->inheritedFontResolveMask = newMask;
+ wd->resolveFont();
+ }
+ }
+ }
+
+#ifndef QT_NO_STYLE_STYLESHEET
+ if (cssStyle) {
+ cssStyle->updateStyleSheetFont(q);
+ }
+#endif
+
+ QEvent e(QEvent::FontChange);
+ QApplication::sendEvent(q, &e);
+#ifdef QT3_SUPPORT
+ q->fontChange(old);
+#endif
+}
+
+void QWidgetPrivate::setLayoutDirection_helper(Qt::LayoutDirection direction)
+{
+ Q_Q(QWidget);
+
+ if ( (direction == Qt::RightToLeft) == q->testAttribute(Qt::WA_RightToLeft))
+ return;
+ q->setAttribute(Qt::WA_RightToLeft, (direction == Qt::RightToLeft));
+ if (!children.isEmpty()) {
+ for (int i = 0; i < children.size(); ++i) {
+ QWidget *w = qobject_cast<QWidget*>(children.at(i));
+ if (w && !w->isWindow() && !w->testAttribute(Qt::WA_SetLayoutDirection))
+ w->d_func()->setLayoutDirection_helper(direction);
+ }
+ }
+ QEvent e(QEvent::LayoutDirectionChange);
+ QApplication::sendEvent(q, &e);
+}
+
+void QWidgetPrivate::resolveLayoutDirection()
+{
+ Q_Q(const QWidget);
+ if (!q->testAttribute(Qt::WA_SetLayoutDirection))
+ setLayoutDirection_helper(q->isWindow() ? QApplication::layoutDirection() : q->parentWidget()->layoutDirection());
+}
+
+/*!
+ \property QWidget::layoutDirection
+
+ \brief the layout direction for this widget
+
+ By default, this property is set to Qt::LeftToRight.
+
+ When the layout direction is set on a widget, it will propagate to
+ the widget's children, but not to a child that is a window and not
+ to a child for which setLayoutDirection() has been explicitly
+ called. Also, child widgets added \e after setLayoutDirection()
+ has been called for the parent do not inherit the parent's layout
+ direction.
+
+ This method no longer affects text layout direction since Qt 4.7.
+
+ \sa QApplication::layoutDirection
+*/
+void QWidget::setLayoutDirection(Qt::LayoutDirection direction)
+{
+ Q_D(QWidget);
+
+ if (direction == Qt::LayoutDirectionAuto) {
+ unsetLayoutDirection();
+ return;
+ }
+
+ setAttribute(Qt::WA_SetLayoutDirection);
+ d->setLayoutDirection_helper(direction);
+}
+
+Qt::LayoutDirection QWidget::layoutDirection() const
+{
+ return testAttribute(Qt::WA_RightToLeft) ? Qt::RightToLeft : Qt::LeftToRight;
+}
+
+void QWidget::unsetLayoutDirection()
+{
+ Q_D(QWidget);
+ setAttribute(Qt::WA_SetLayoutDirection, false);
+ d->resolveLayoutDirection();
+}
+
+/*!
+ \fn QFontMetrics QWidget::fontMetrics() const
+
+ Returns the font metrics for the widget's current font.
+ Equivalent to QFontMetrics(widget->font()).
+
+ \sa font(), fontInfo(), setFont()
+*/
+
+/*!
+ \fn QFontInfo QWidget::fontInfo() const
+
+ Returns the font info for the widget's current font.
+ Equivalent to QFontInto(widget->font()).
+
+ \sa font(), fontMetrics(), setFont()
+*/
+
+
+/*!
+ \property QWidget::cursor
+ \brief the cursor shape for this widget
+
+ The mouse cursor will assume this shape when it's over this
+ widget. See the \link Qt::CursorShape list of predefined cursor
+ objects\endlink for a range of useful shapes.
+
+ An editor widget might use an I-beam cursor:
+ \snippet doc/src/snippets/code/src_gui_kernel_qwidget.cpp 6
+
+ If no cursor has been set, or after a call to unsetCursor(), the
+ parent's cursor is used.
+
+ By default, this property contains a cursor with the Qt::ArrowCursor
+ shape.
+
+ Some underlying window implementations will reset the cursor if it
+ leaves a widget even if the mouse is grabbed. If you want to have
+ a cursor set for all widgets, even when outside the window, consider
+ QApplication::setOverrideCursor().
+
+ \sa QApplication::setOverrideCursor()
+*/
+
+#ifndef QT_NO_CURSOR
+QCursor QWidget::cursor() const
+{
+ Q_D(const QWidget);
+ if (testAttribute(Qt::WA_SetCursor))
+ return (d->extra && d->extra->curs)
+ ? *d->extra->curs
+ : QCursor(Qt::ArrowCursor);
+ if (isWindow() || !parentWidget())
+ return QCursor(Qt::ArrowCursor);
+ return parentWidget()->cursor();
+}
+
+void QWidget::setCursor(const QCursor &cursor)
+{
+ Q_D(QWidget);
+// On Mac we must set the cursor even if it is the ArrowCursor.
+#if !defined(Q_WS_MAC)
+ if (cursor.shape() != Qt::ArrowCursor
+ || (d->extra && d->extra->curs))
+#endif
+ {
+ d->createExtra();
+ QCursor *newCursor = new QCursor(cursor);
+ delete d->extra->curs;
+ d->extra->curs = newCursor;
+ }
+ setAttribute(Qt::WA_SetCursor);
+ d->setCursor_sys(cursor);
+
+ QEvent event(QEvent::CursorChange);
+ QApplication::sendEvent(this, &event);
+}
+
+void QWidget::unsetCursor()
+{
+ Q_D(QWidget);
+ if (d->extra) {
+ delete d->extra->curs;
+ d->extra->curs = 0;
+ }
+ if (!isWindow())
+ setAttribute(Qt::WA_SetCursor, false);
+ d->unsetCursor_sys();
+
+ QEvent event(QEvent::CursorChange);
+ QApplication::sendEvent(this, &event);
+}
+
+#endif
+
+/*!
+ \enum QWidget::RenderFlag
+
+ This enum describes how to render the widget when calling QWidget::render().
+
+ \value DrawWindowBackground If you enable this option, the widget's background
+ is rendered into the target even if autoFillBackground is not set. By default,
+ this option is enabled.
+
+ \value DrawChildren If you enable this option, the widget's children
+ are rendered recursively into the target. By default, this option is enabled.
+
+ \value IgnoreMask If you enable this option, the widget's QWidget::mask()
+ is ignored when rendering into the target. By default, this option is disabled.
+
+ \since 4.3
+*/
+
+/*!
+ \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:
+
+ \snippet doc/src/snippets/code/src_gui_kernel_qwidget.cpp 7
+
+ If \a sourceRegion is a null region, this function will use QWidget::rect() as
+ the region, i.e. the entire widget.
+
+ 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
+
+ \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)
+{
+ d_func()->render(target, targetOffset, sourceRegion, renderFlags, false);
+}
+
+/*!
+ \overload
+
+ Renders the widget into the \a painter's QPainter::device().
+
+ Transformations and settings applied to the \a painter will be used
+ when rendering.
+
+ \note The \a painter must be active. On Mac OS X the widget will be
+ rendered into a QPixmap and then drawn by the \a painter.
+
+ \sa QPainter::device()
+*/
+void QWidget::render(QPainter *painter, const QPoint &targetOffset,
+ const QRegion &sourceRegion, RenderFlags renderFlags)
+{
+ if (!painter) {
+ qWarning("QWidget::render: Null pointer to painter");
+ return;
+ }
+
+ if (!painter->isActive()) {
+ qWarning("QWidget::render: Cannot render with an inactive painter");
+ return;
+ }
+
+ const qreal opacity = painter->opacity();
+ if (qFuzzyIsNull(opacity))
+ return; // Fully transparent.
+
+ Q_D(QWidget);
+ const bool inRenderWithPainter = d->extra && d->extra->inRenderWithPainter;
+ const QRegion toBePainted = !inRenderWithPainter ? d->prepareToRender(sourceRegion, renderFlags)
+ : sourceRegion;
+ if (toBePainted.isEmpty())
+ return;
+
+ if (!d->extra)
+ d->createExtra();
+ d->extra->inRenderWithPainter = true;
+
+#ifdef Q_WS_MAC
+ d->render_helper(painter, targetOffset, toBePainted, renderFlags);
+#else
+ QPaintEngine *engine = painter->paintEngine();
+ Q_ASSERT(engine);
+ QPaintEnginePrivate *enginePriv = engine->d_func();
+ Q_ASSERT(enginePriv);
+ QPaintDevice *target = engine->paintDevice();
+ Q_ASSERT(target);
+
+ // Render via a pixmap when dealing with non-opaque painters or printers.
+ if (!inRenderWithPainter && (opacity < 1.0 || (target->devType() == QInternal::Printer))) {
+ d->render_helper(painter, targetOffset, toBePainted, renderFlags);
+ d->extra->inRenderWithPainter = false;
+ return;
+ }
+
+ // Set new shared painter.
+ QPainter *oldPainter = d->sharedPainter();
+ d->setSharedPainter(painter);
+
+ // Save current system clip, viewport and transform,
+ const QTransform oldTransform = enginePriv->systemTransform;
+ const QRegion oldSystemClip = enginePriv->systemClip;
+ const QRegion oldSystemViewport = enginePriv->systemViewport;
+
+ // This ensures that all painting triggered by render() is clipped to the current engine clip.
+ if (painter->hasClipping()) {
+ const QRegion painterClip = painter->deviceTransform().map(painter->clipRegion());
+ enginePriv->setSystemViewport(oldSystemClip.isEmpty() ? painterClip : oldSystemClip & painterClip);
+ } else {
+ enginePriv->setSystemViewport(oldSystemClip);
+ }
+
+ render(target, targetOffset, toBePainted, renderFlags);
+
+ // Restore system clip, viewport and transform.
+ enginePriv->systemClip = oldSystemClip;
+ enginePriv->setSystemViewport(oldSystemViewport);
+ enginePriv->setSystemTransform(oldTransform);
+
+ // Restore shared painter.
+ d->setSharedPainter(oldPainter);
+#endif
+
+ d->extra->inRenderWithPainter = false;
+}
+
+static void sendResizeEvents(QWidget *target)
+{
+ QResizeEvent e(target->size(), QSize());
+ QApplication::sendEvent(target, &e);
+
+ const QObjectList children = target->children();
+ for (int i = 0; i < children.size(); ++i) {
+ QWidget *child = static_cast<QWidget*>(children.at(i));
+ if (child->isWidgetType() && !child->isWindow() && child->testAttribute(Qt::WA_PendingResizeEvent))
+ sendResizeEvents(child);
+ }
+}
+
+/*!
+ \since 5.0
+
+ Renders the widget into a pixmap restricted by the
+ given \a rectangle. If the \a widget has any children, then
+ they are also painted in the appropriate positions.
+
+ If no rectangle is specified (the default) the entire widget is
+ painted.
+
+ Replacement for Qt 4's QPixmap::grabWidget().
+
+ \sa render(), QPixmap
+*/
+
+/* INVOKABLE since used by QPixmap::grabWidget(). */
+QPixmap QWidget::grab(const QRect &rectangle)
+{
+ Q_D(const QWidget);
+ if (testAttribute(Qt::WA_PendingResizeEvent) || !testAttribute(Qt::WA_WState_Created))
+ sendResizeEvents(this);
+
+ QRect r(rectangle);
+ if (r.width() < 0)
+ r.setWidth(width() - rectangle.x());
+ if (r.height() < 0)
+ r.setHeight(height() - rectangle.y());
+
+ if (!r.intersects(rect()))
+ return QPixmap();
+
+ QPixmap res(r.size());
+ if (!d->isOpaque)
+ res.fill(Qt::transparent);
+ render(&res, QPoint(), QRegion(r), QWidget::DrawWindowBackground
+ | QWidget::DrawChildren | QWidget::IgnoreMask);
+ return res;
+}
+
+/*!
+ \brief The graphicsEffect function returns a pointer to the
+ widget's graphics effect.
+
+ If the widget has no graphics effect, 0 is returned.
+
+ \since 4.6
+
+ \sa setGraphicsEffect()
+*/
+#ifndef QT_NO_GRAPHICSEFFECT
+QGraphicsEffect *QWidget::graphicsEffect() const
+{
+ Q_D(const QWidget);
+ return d->graphicsEffect;
+}
+#endif //QT_NO_GRAPHICSEFFECT
+
+/*!
+
+ \brief The setGraphicsEffect function is for setting the widget's graphics effect.
+
+ Sets \a effect as the widget's effect. If there already is an effect installed
+ on this widget, QWidget will delete the existing effect before installing
+ the new \a effect.
+
+ If \a effect is the installed on a different widget, setGraphicsEffect() will remove
+ the effect from the widget and install it on this widget.
+
+ QWidget takes ownership of \a effect.
+
+ \note This function will apply the effect on itself and all its children.
+
+ \since 4.6
+
+ \sa graphicsEffect()
+*/
+#ifndef QT_NO_GRAPHICSEFFECT
+void QWidget::setGraphicsEffect(QGraphicsEffect *effect)
+{
+ Q_D(QWidget);
+ if (d->graphicsEffect == effect)
+ return;
+
+ if (d->graphicsEffect) {
+ d->invalidateBuffer(rect());
+ delete d->graphicsEffect;
+ d->graphicsEffect = 0;
+ }
+
+ if (effect) {
+ // Set new effect.
+ QGraphicsEffectSourcePrivate *sourced = new QWidgetEffectSourcePrivate(this);
+ QGraphicsEffectSource *source = new QGraphicsEffectSource(*sourced);
+ d->graphicsEffect = effect;
+ effect->d_func()->setGraphicsEffectSource(source);
+ update();
+ }
+
+ d->updateIsOpaque();
+}
+#endif //QT_NO_GRAPHICSEFFECT
+
+bool QWidgetPrivate::isAboutToShow() const
+{
+ if (data.in_show)
+ return true;
+
+ Q_Q(const QWidget);
+ if (q->isHidden())
+ return false;
+
+ // The widget will be shown if any of its ancestors are about to show.
+ QWidget *parent = q->parentWidget();
+ return parent ? parent->d_func()->isAboutToShow() : false;
+}
+
+QRegion QWidgetPrivate::prepareToRender(const QRegion &region, QWidget::RenderFlags renderFlags)
+{
+ Q_Q(QWidget);
+ const bool isVisible = q->isVisible();
+
+ // Make sure the widget is laid out correctly.
+ if (!isVisible && !isAboutToShow()) {
+ QWidget *topLevel = q->window();
+ (void)topLevel->d_func()->topData(); // Make sure we at least have top-data.
+ topLevel->ensurePolished();
+
+ // Invalidate the layout of hidden ancestors (incl. myself) and pretend
+ // they're not explicitly hidden.
+ QWidget *widget = q;
+ QWidgetList hiddenWidgets;
+ while (widget) {
+ if (widget->isHidden()) {
+ widget->setAttribute(Qt::WA_WState_Hidden, false);
+ hiddenWidgets.append(widget);
+ if (!widget->isWindow() && widget->parentWidget()->d_func()->layout)
+ widget->d_func()->updateGeometry_helper(true);
+ }
+ widget = widget->parentWidget();
+ }
+
+ // Activate top-level layout.
+ if (topLevel->d_func()->layout)
+ topLevel->d_func()->layout->activate();
+
+ // Adjust size if necessary.
+ QTLWExtra *topLevelExtra = topLevel->d_func()->maybeTopData();
+ if (topLevelExtra && !topLevelExtra->sizeAdjusted
+ && !topLevel->testAttribute(Qt::WA_Resized)) {
+ topLevel->adjustSize();
+ topLevel->setAttribute(Qt::WA_Resized, false);
+ }
+
+ // Activate child layouts.
+ topLevel->d_func()->activateChildLayoutsRecursively();
+
+ // We're not cheating with WA_WState_Hidden anymore.
+ for (int i = 0; i < hiddenWidgets.size(); ++i) {
+ QWidget *widget = hiddenWidgets.at(i);
+ widget->setAttribute(Qt::WA_WState_Hidden);
+ if (!widget->isWindow() && widget->parentWidget()->d_func()->layout)
+ widget->parentWidget()->d_func()->layout->invalidate();
+ }
+ } else if (isVisible) {
+ q->window()->d_func()->sendPendingMoveAndResizeEvents(true, true);
+ }
+
+ // Calculate the region to be painted.
+ QRegion toBePainted = !region.isEmpty() ? region : QRegion(q->rect());
+ if (!(renderFlags & QWidget::IgnoreMask) && extra && extra->hasMask)
+ toBePainted &= extra->mask;
+ return toBePainted;
+}
+
+void QWidgetPrivate::render_helper(QPainter *painter, const QPoint &targetOffset, const QRegion &toBePainted,
+ QWidget::RenderFlags renderFlags)
+{
+ Q_ASSERT(painter);
+ Q_ASSERT(!toBePainted.isEmpty());
+
+ Q_Q(QWidget);
+#ifndef Q_WS_MAC
+ const QTransform originalTransform = painter->worldTransform();
+ const bool useDeviceCoordinates = originalTransform.isScaling();
+ if (!useDeviceCoordinates) {
+#endif
+ // Render via a pixmap.
+ const QRect rect = toBePainted.boundingRect();
+ const QSize size = rect.size();
+ if (size.isNull())
+ return;
+
+ QPixmap pixmap(size);
+ if (!(renderFlags & QWidget::DrawWindowBackground) || !isOpaque)
+ pixmap.fill(Qt::transparent);
+ q->render(&pixmap, QPoint(), toBePainted, renderFlags);
+
+ const bool restore = !(painter->renderHints() & QPainter::SmoothPixmapTransform);
+ painter->setRenderHints(QPainter::SmoothPixmapTransform, true);
+
+ painter->drawPixmap(targetOffset, pixmap);
+
+ if (restore)
+ painter->setRenderHints(QPainter::SmoothPixmapTransform, false);
+
+#ifndef Q_WS_MAC
+ } else {
+ // Render via a pixmap in device coordinates (to avoid pixmap scaling).
+ QTransform transform = originalTransform;
+ transform.translate(targetOffset.x(), targetOffset.y());
+
+ QPaintDevice *device = painter->device();
+ Q_ASSERT(device);
+
+ // Calculate device rect.
+ const QRectF rect(toBePainted.boundingRect());
+ QRect deviceRect = transform.mapRect(QRectF(0, 0, rect.width(), rect.height())).toAlignedRect();
+ deviceRect &= QRect(0, 0, device->width(), device->height());
+
+ QPixmap pixmap(deviceRect.size());
+ pixmap.fill(Qt::transparent);
+
+ // Create a pixmap device coordinate painter.
+ QPainter pixmapPainter(&pixmap);
+ pixmapPainter.setRenderHints(painter->renderHints());
+ transform *= QTransform::fromTranslate(-deviceRect.x(), -deviceRect.y());
+ pixmapPainter.setTransform(transform);
+
+ q->render(&pixmapPainter, QPoint(), toBePainted, renderFlags);
+ pixmapPainter.end();
+
+ // And then draw the pixmap.
+ painter->setTransform(QTransform());
+ painter->drawPixmap(deviceRect.topLeft(), pixmap);
+ painter->setTransform(originalTransform);
+ }
+#endif
+}
+
+void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QPoint &offset, int flags,
+ QPainter *sharedPainter, QWidgetBackingStore *backingStore)
+{
+ if (rgn.isEmpty())
+ return;
+
+#if defined(Q_WS_MAC) && defined(QT_MAC_USE_COCOA)
+ if (qt_mac_clearDirtyOnWidgetInsideDrawWidget)
+ dirtyOnWidget = QRegion();
+
+ // We disable the rendering of QToolBar in the backingStore if
+ // it's supposed to be in the unified toolbar on Mac OS X.
+ if (backingStore && isInUnifiedToolbar)
+ return;
+#endif // Q_WS_MAC && QT_MAC_USE_COCOA
+
+
+ Q_Q(QWidget);
+#ifndef QT_NO_GRAPHICSEFFECT
+ if (graphicsEffect && graphicsEffect->isEnabled()) {
+ QGraphicsEffectSource *source = graphicsEffect->d_func()->source;
+ QWidgetEffectSourcePrivate *sourced = static_cast<QWidgetEffectSourcePrivate *>
+ (source->d_func());
+ if (!sourced->context) {
+ QWidgetPaintContext context(pdev, rgn, offset, flags, sharedPainter, backingStore);
+ sourced->context = &context;
+ if (!sharedPainter) {
+ QPaintEngine *paintEngine = pdev->paintEngine();
+ paintEngine->d_func()->systemClip = rgn.translated(offset);
+ QPainter p(pdev);
+ p.translate(offset);
+ context.painter = &p;
+ graphicsEffect->draw(&p);
+ paintEngine->d_func()->systemClip = QRegion();
+ } else {
+ context.painter = sharedPainter;
+ if (sharedPainter->worldTransform() != sourced->lastEffectTransform) {
+ sourced->invalidateCache();
+ sourced->lastEffectTransform = sharedPainter->worldTransform();
+ }
+ sharedPainter->save();
+ sharedPainter->translate(offset);
+ graphicsEffect->draw(sharedPainter);
+ sharedPainter->restore();
+ }
+ sourced->context = 0;
+ return;
+ }
+ }
+#endif //QT_NO_GRAFFICSEFFECT
+
+ const bool asRoot = flags & DrawAsRoot;
+ const bool alsoOnScreen = flags & DrawPaintOnScreen;
+ const bool recursive = flags & DrawRecursive;
+ const bool alsoInvisible = flags & DrawInvisible;
+
+ Q_ASSERT(sharedPainter ? sharedPainter->isActive() : true);
+
+ QRegion toBePainted(rgn);
+ if (asRoot && !alsoInvisible)
+ toBePainted &= clipRect(); //(rgn & visibleRegion());
+ if (!(flags & DontSubtractOpaqueChildren))
+ subtractOpaqueChildren(toBePainted, q->rect());
+
+ if (!toBePainted.isEmpty()) {
+ bool onScreen = paintOnScreen();
+ if (!onScreen || alsoOnScreen) {
+ //update the "in paint event" flag
+ if (q->testAttribute(Qt::WA_WState_InPaintEvent))
+ qWarning("QWidget::repaint: Recursive repaint detected");
+ q->setAttribute(Qt::WA_WState_InPaintEvent);
+
+ //clip away the new area
+#ifndef QT_NO_PAINT_DEBUG
+ bool flushed = QWidgetBackingStore::flushPaint(q, toBePainted);
+#endif
+ QPaintEngine *paintEngine = pdev->paintEngine();
+ if (paintEngine) {
+ setRedirected(pdev, -offset);
+
+#ifdef Q_WS_MAC
+ // (Alien support) Special case for Mac when redirecting: If the paint device
+ // is of the Widget type we need to set WA_WState_InPaintEvent since painting
+ // outside the paint event is not supported on QWidgets. The attributeis
+ // restored further down.
+ if (pdev->devType() == QInternal::Widget)
+ static_cast<QWidget *>(pdev)->setAttribute(Qt::WA_WState_InPaintEvent);
+
+#endif
+ if (sharedPainter)
+ paintEngine->d_func()->systemClip = toBePainted;
+ else
+ paintEngine->d_func()->systemRect = q->data->crect;
+
+ //paint the background
+ if ((asRoot || q->autoFillBackground() || onScreen || q->testAttribute(Qt::WA_StyledBackground))
+ && !q->testAttribute(Qt::WA_OpaquePaintEvent) && !q->testAttribute(Qt::WA_NoSystemBackground)) {
+ QPainter p(q);
+ paintBackground(&p, toBePainted, (asRoot || onScreen) ? flags | DrawAsRoot : 0);
+ }
+
+ if (!sharedPainter)
+ paintEngine->d_func()->systemClip = toBePainted.translated(offset);
+
+ if (!onScreen && !asRoot && !isOpaque && q->testAttribute(Qt::WA_TintedBackground)) {
+ QPainter p(q);
+ QColor tint = q->palette().window().color();
+ tint.setAlphaF(qreal(.6));
+ p.fillRect(toBePainted.boundingRect(), tint);
+ }
+ }
+
+#if 0
+ qDebug() << "painting" << q << "opaque ==" << isOpaque();
+ qDebug() << "clipping to" << toBePainted << "location == " << offset
+ << "geometry ==" << QRect(q->mapTo(q->window(), QPoint(0, 0)), q->size());
+#endif
+
+ //actually send the paint event
+ QPaintEvent e(toBePainted);
+ QCoreApplication::sendSpontaneousEvent(q, &e);
+#if !defined(Q_WS_QPA)
+ if (backingStore && !onScreen && !asRoot && (q->internalWinId() || !q->nativeParentWidget()->isWindow()))
+ backingStore->markDirtyOnScreen(toBePainted, q, offset);
+#endif
+
+ //restore
+ if (paintEngine) {
+#ifdef Q_WS_MAC
+ if (pdev->devType() == QInternal::Widget)
+ static_cast<QWidget *>(pdev)->setAttribute(Qt::WA_WState_InPaintEvent, false);
+#endif
+ restoreRedirected();
+ if (!sharedPainter)
+ paintEngine->d_func()->systemRect = QRect();
+ else
+ paintEngine->d_func()->currentClipDevice = 0;
+ paintEngine->d_func()->systemClip = QRegion();
+ }
+ q->setAttribute(Qt::WA_WState_InPaintEvent, false);
+ if (q->paintingActive() && !q->testAttribute(Qt::WA_PaintOutsidePaintEvent))
+ qWarning("QWidget::repaint: It is dangerous to leave painters active on a widget outside of the PaintEvent");
+
+ if (paintEngine && paintEngine->autoDestruct()) {
+ delete paintEngine;
+ }
+
+#ifndef QT_NO_PAINT_DEBUG
+ if (flushed)
+ QWidgetBackingStore::unflushPaint(q, toBePainted);
+#endif
+ } else if (q->isWindow()) {
+ QPaintEngine *engine = pdev->paintEngine();
+ if (engine) {
+ QPainter p(pdev);
+ p.setClipRegion(toBePainted);
+ const QBrush bg = q->palette().brush(QPalette::Window);
+ if (bg.style() == Qt::TexturePattern)
+ p.drawTiledPixmap(q->rect(), bg.texture());
+ else
+ p.fillRect(q->rect(), bg);
+
+ if (engine->autoDestruct())
+ delete engine;
+ }
+ }
+ }
+
+ if (recursive && !children.isEmpty()) {
+ paintSiblingsRecursive(pdev, children, children.size() - 1, rgn, offset, flags & ~DrawAsRoot
+ , sharedPainter, backingStore);
+ }
+}
+
+void QWidgetPrivate::render(QPaintDevice *target, const QPoint &targetOffset,
+ const QRegion &sourceRegion, QWidget::RenderFlags renderFlags,
+ bool readyToRender)
+{
+ if (!target) {
+ qWarning("QWidget::render: null pointer to paint device");
+ return;
+ }
+
+ const bool inRenderWithPainter = extra && extra->inRenderWithPainter;
+ QRegion paintRegion = !inRenderWithPainter && !readyToRender
+ ? prepareToRender(sourceRegion, renderFlags)
+ : sourceRegion;
+ if (paintRegion.isEmpty())
+ return;
+
+#ifndef Q_WS_MAC
+ QPainter *oldSharedPainter = inRenderWithPainter ? sharedPainter() : 0;
+
+ // Use the target's shared painter if set (typically set when doing
+ // "other->render(widget);" in the widget's paintEvent.
+ if (target->devType() == QInternal::Widget) {
+ QWidgetPrivate *targetPrivate = static_cast<QWidget *>(target)->d_func();
+ if (targetPrivate->extra && targetPrivate->extra->inRenderWithPainter) {
+ QPainter *targetPainter = targetPrivate->sharedPainter();
+ if (targetPainter && targetPainter->isActive())
+ setSharedPainter(targetPainter);
+ }
+ }
+#endif
+
+ // Use the target's redirected device if set and adjust offset and paint
+ // region accordingly. This is typically the case when people call render
+ // from the paintEvent.
+ QPoint offset = targetOffset;
+ offset -= paintRegion.boundingRect().topLeft();
+ QPoint redirectionOffset;
+ QPaintDevice *redirected = 0;
+
+ if (target->devType() == QInternal::Widget)
+ redirected = static_cast<QWidget *>(target)->d_func()->redirected(&redirectionOffset);
+ if (!redirected)
+ redirected = QPainter::redirected(target, &redirectionOffset);
+
+ if (redirected) {
+ target = redirected;
+ offset -= redirectionOffset;
+ }
+
+ if (!inRenderWithPainter) { // Clip handled by shared painter (in qpainter.cpp).
+ if (QPaintEngine *targetEngine = target->paintEngine()) {
+ const QRegion targetSystemClip = targetEngine->systemClip();
+ if (!targetSystemClip.isEmpty())
+ paintRegion &= targetSystemClip.translated(-offset);
+ }
+ }
+
+ // Set backingstore flags.
+ int flags = DrawPaintOnScreen | DrawInvisible;
+ if (renderFlags & QWidget::DrawWindowBackground)
+ flags |= DrawAsRoot;
+
+ if (renderFlags & QWidget::DrawChildren)
+ flags |= DrawRecursive;
+ else
+ flags |= DontSubtractOpaqueChildren;
+
+ if (target->devType() == QInternal::Printer) {
+ QPainter p(target);
+ render_helper(&p, targetOffset, paintRegion, renderFlags);
+ return;
+ }
+
+#ifndef Q_WS_MAC
+ // Render via backingstore.
+ drawWidget(target, paintRegion, offset, flags, sharedPainter());
+
+ // Restore shared painter.
+ if (oldSharedPainter)
+ setSharedPainter(oldSharedPainter);
+#else
+ // Render via backingstore (no shared painter).
+ drawWidget(target, paintRegion, offset, flags, 0);
+#endif
+}
+
+void QWidgetPrivate::paintSiblingsRecursive(QPaintDevice *pdev, const QObjectList& siblings, int index, const QRegion &rgn,
+ const QPoint &offset, int flags
+ , QPainter *sharedPainter, QWidgetBackingStore *backingStore)
+{
+ QWidget *w = 0;
+ QRect boundingRect;
+ bool dirtyBoundingRect = true;
+ const bool exludeOpaqueChildren = (flags & DontDrawOpaqueChildren);
+ const bool excludeNativeChildren = (flags & DontDrawNativeChildren);
+
+ do {
+ QWidget *x = qobject_cast<QWidget*>(siblings.at(index));
+ if (x && !(exludeOpaqueChildren && x->d_func()->isOpaque) && !x->isHidden() && !x->isWindow()
+ && !(excludeNativeChildren && x->internalWinId())) {
+ if (dirtyBoundingRect) {
+ boundingRect = rgn.boundingRect();
+ dirtyBoundingRect = false;
+ }
+
+ if (qRectIntersects(boundingRect, x->d_func()->effectiveRectFor(x->data->crect))) {
+ w = x;
+ break;
+ }
+ }
+ --index;
+ } while (index >= 0);
+
+ if (!w)
+ return;
+
+ QWidgetPrivate *wd = w->d_func();
+ const QPoint widgetPos(w->data->crect.topLeft());
+ const bool hasMask = wd->extra && wd->extra->hasMask && !wd->graphicsEffect;
+ if (index > 0) {
+ QRegion wr(rgn);
+ if (wd->isOpaque)
+ wr -= hasMask ? wd->extra->mask.translated(widgetPos) : w->data->crect;
+ paintSiblingsRecursive(pdev, siblings, --index, wr, offset, flags
+ , sharedPainter, backingStore);
+ }
+
+ if (w->updatesEnabled()
+#ifndef QT_NO_GRAPHICSVIEW
+ && (!w->d_func()->extra || !w->d_func()->extra->proxyWidget)
+#endif //QT_NO_GRAPHICSVIEW
+ ) {
+ QRegion wRegion(rgn);
+ wRegion &= wd->effectiveRectFor(w->data->crect);
+ wRegion.translate(-widgetPos);
+ if (hasMask)
+ wRegion &= wd->extra->mask;
+ wd->drawWidget(pdev, wRegion, offset + widgetPos, flags, sharedPainter, backingStore);
+ }
+}
+
+#ifndef QT_NO_GRAPHICSEFFECT
+QRectF QWidgetEffectSourcePrivate::boundingRect(Qt::CoordinateSystem system) const
+{
+ if (system != Qt::DeviceCoordinates)
+ return m_widget->rect();
+
+ if (!context) {
+ // Device coordinates without context not yet supported.
+ qWarning("QGraphicsEffectSource::boundingRect: Not yet implemented, lacking device context");
+ return QRectF();
+ }
+
+ return context->painter->worldTransform().mapRect(m_widget->rect());
+}
+
+void QWidgetEffectSourcePrivate::draw(QPainter *painter)
+{
+ if (!context || context->painter != painter) {
+ m_widget->render(painter);
+ return;
+ }
+
+ // The region saved in the context is neither clipped to the rect
+ // nor the mask, so we have to clip it here before calling drawWidget.
+ QRegion toBePainted = context->rgn;
+ toBePainted &= m_widget->rect();
+ QWidgetPrivate *wd = qt_widget_private(m_widget);
+ if (wd->extra && wd->extra->hasMask)
+ toBePainted &= wd->extra->mask;
+
+ wd->drawWidget(context->pdev, toBePainted, context->offset, context->flags,
+ context->sharedPainter, context->backingStore);
+}
+
+QPixmap QWidgetEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QPoint *offset,
+ QGraphicsEffect::PixmapPadMode mode) const
+{
+ const bool deviceCoordinates = (system == Qt::DeviceCoordinates);
+ if (!context && deviceCoordinates) {
+ // Device coordinates without context not yet supported.
+ qWarning("QGraphicsEffectSource::pixmap: Not yet implemented, lacking device context");
+ return QPixmap();
+ }
+
+ QPoint pixmapOffset;
+ QRectF sourceRect = m_widget->rect();
+
+ if (deviceCoordinates) {
+ const QTransform &painterTransform = context->painter->worldTransform();
+ sourceRect = painterTransform.mapRect(sourceRect);
+ pixmapOffset = painterTransform.map(pixmapOffset);
+ }
+
+ QRect effectRect;
+
+ if (mode == QGraphicsEffect::PadToEffectiveBoundingRect)
+ effectRect = m_widget->graphicsEffect()->boundingRectFor(sourceRect).toAlignedRect();
+ else if (mode == QGraphicsEffect::PadToTransparentBorder)
+ effectRect = sourceRect.adjusted(-1, -1, 1, 1).toAlignedRect();
+ else
+ effectRect = sourceRect.toAlignedRect();
+
+ if (offset)
+ *offset = effectRect.topLeft();
+
+ pixmapOffset -= effectRect.topLeft();
+
+ QPixmap pixmap(effectRect.size());
+ pixmap.fill(Qt::transparent);
+ m_widget->render(&pixmap, pixmapOffset, QRegion(), QWidget::DrawChildren);
+ return pixmap;
+}
+#endif //QT_NO_GRAPHICSEFFECT
+
+#ifndef QT_NO_GRAPHICSVIEW
+/*!
+ \internal
+
+ Finds the nearest widget embedded in a graphics proxy widget along the chain formed by this
+ widget and its ancestors. The search starts at \a origin (inclusive).
+ If successful, the function returns the proxy that embeds the widget, or 0 if no embedded
+ widget was found.
+*/
+QGraphicsProxyWidget * QWidgetPrivate::nearestGraphicsProxyWidget(const QWidget *origin)
+{
+ if (origin) {
+ QWExtra *extra = origin->d_func()->extra;
+ if (extra && extra->proxyWidget)
+ return extra->proxyWidget;
+ return nearestGraphicsProxyWidget(origin->parentWidget());
+ }
+ return 0;
+}
+#endif
+
+/*!
+ \property QWidget::locale
+ \brief the widget's locale
+ \since 4.3
+
+ As long as no special locale has been set, this is either
+ the parent's locale or (if this widget is a top level widget),
+ the default locale.
+
+ If the widget displays dates or numbers, these should be formatted
+ using the widget's locale.
+
+ \sa QLocale QLocale::setDefault()
+*/
+
+void QWidgetPrivate::setLocale_helper(const QLocale &loc, bool forceUpdate)
+{
+ Q_Q(QWidget);
+ if (locale == loc && !forceUpdate)
+ return;
+
+ locale = loc;
+
+ if (!children.isEmpty()) {
+ for (int i = 0; i < children.size(); ++i) {
+ QWidget *w = qobject_cast<QWidget*>(children.at(i));
+ if (!w)
+ continue;
+ if (w->testAttribute(Qt::WA_SetLocale))
+ continue;
+ if (w->isWindow() && !w->testAttribute(Qt::WA_WindowPropagation))
+ continue;
+ w->d_func()->setLocale_helper(loc, forceUpdate);
+ }
+ }
+ QEvent e(QEvent::LocaleChange);
+ QApplication::sendEvent(q, &e);
+}
+
+void QWidget::setLocale(const QLocale &locale)
+{
+ Q_D(QWidget);
+
+ setAttribute(Qt::WA_SetLocale);
+ d->setLocale_helper(locale);
+}
+
+QLocale QWidget::locale() const
+{
+ Q_D(const QWidget);
+
+ return d->locale;
+}
+
+void QWidgetPrivate::resolveLocale()
+{
+ Q_Q(const QWidget);
+
+ if (!q->testAttribute(Qt::WA_SetLocale)) {
+ setLocale_helper(q->isWindow()
+ ? QLocale()
+ : q->parentWidget()->locale());
+ }
+}
+
+void QWidget::unsetLocale()
+{
+ Q_D(QWidget);
+ setAttribute(Qt::WA_SetLocale, false);
+ d->resolveLocale();
+}
+
+static QString constructWindowTitleFromFilePath(const QString &filePath)
+{
+ QFileInfo fi(filePath);
+ QString windowTitle = fi.fileName() + QLatin1String("[*]");
+#ifndef Q_WS_MAC
+ QString appName = QApplication::applicationName();
+ if (!appName.isEmpty())
+ windowTitle += QLatin1Char(' ') + QChar(0x2014) + QLatin1Char(' ') + appName;
+#endif
+ return windowTitle;
+}
+
+/*!
+ \property QWidget::windowTitle
+ \brief the window title (caption)
+
+ This property only makes sense for top-level widgets, such as
+ windows and dialogs. If no caption has been set, the title is based of the
+ \l windowFilePath. If neither of these is set, then the title is
+ an empty string.
+
+ If you use the \l windowModified mechanism, the window title must
+ contain a "[*]" placeholder, which indicates where the '*' should
+ appear. Normally, it should appear right after the file name
+ (e.g., "document1.txt[*] - Text Editor"). If the \l
+ windowModified property is false (the default), the placeholder
+ is simply removed.
+
+ \sa windowIcon, windowIconText, windowModified, windowFilePath
+*/
+QString QWidget::windowTitle() const
+{
+ Q_D(const QWidget);
+ if (d->extra && d->extra->topextra) {
+ if (!d->extra->topextra->caption.isEmpty())
+ return d->extra->topextra->caption;
+ if (!d->extra->topextra->filePath.isEmpty())
+ return constructWindowTitleFromFilePath(d->extra->topextra->filePath);
+ }
+ return QString();
+}
+
+/*!
+ Returns a modified window title with the [*] place holder
+ replaced according to the rules described in QWidget::setWindowTitle
+
+ This function assumes that "[*]" can be quoted by another
+ "[*]", so it will replace two place holders by one and
+ a single last one by either "*" or nothing depending on
+ the modified flag.
+
+ \internal
+*/
+QString qt_setWindowTitle_helperHelper(const QString &title, const QWidget *widget)
+{
+ Q_ASSERT(widget);
+
+#ifdef QT_EVAL
+ extern QString qt_eval_adapt_window_title(const QString &title);
+ QString cap = qt_eval_adapt_window_title(title);
+#else
+ QString cap = title;
+#endif
+
+ if (cap.isEmpty())
+ return cap;
+
+ QLatin1String placeHolder("[*]");
+ int placeHolderLength = 3; // QLatin1String doesn't have length()
+
+ int index = cap.indexOf(placeHolder);
+
+ // here the magic begins
+ while (index != -1) {
+ index += placeHolderLength;
+ int count = 1;
+ while (cap.indexOf(placeHolder, index) == index) {
+ ++count;
+ index += placeHolderLength;
+ }
+
+ if (count%2) { // odd number of [*] -> replace last one
+ int lastIndex = cap.lastIndexOf(placeHolder, index - 1);
+ if (widget->isWindowModified()
+ && widget->style()->styleHint(QStyle::SH_TitleBar_ModifyNotification, 0, widget))
+ cap.replace(lastIndex, 3, QWidget::tr("*"));
+ else
+ cap.remove(lastIndex, 3);
+ }
+
+ index = cap.indexOf(placeHolder, index);
+ }
+
+ cap.replace(QLatin1String("[*][*]"), placeHolder);
+
+ return cap;
+}
+
+void QWidgetPrivate::setWindowTitle_helper(const QString &title)
+{
+ Q_Q(QWidget);
+ if (q->testAttribute(Qt::WA_WState_Created))
+ setWindowTitle_sys(qt_setWindowTitle_helperHelper(title, q));
+}
+
+void QWidgetPrivate::setWindowIconText_helper(const QString &title)
+{
+ Q_Q(QWidget);
+ if (q->testAttribute(Qt::WA_WState_Created))
+ setWindowIconText_sys(qt_setWindowTitle_helperHelper(title, q));
+}
+
+void QWidget::setWindowIconText(const QString &iconText)
+{
+ if (QWidget::windowIconText() == iconText)
+ return;
+
+ Q_D(QWidget);
+ d->topData()->iconText = iconText;
+ d->setWindowIconText_helper(iconText);
+
+ QEvent e(QEvent::IconTextChange);
+ QApplication::sendEvent(this, &e);
+}
+
+void QWidget::setWindowTitle(const QString &title)
+{
+ if (QWidget::windowTitle() == title && !title.isEmpty() && !title.isNull())
+ return;
+
+ Q_D(QWidget);
+ d->topData()->caption = title;
+ d->setWindowTitle_helper(title);
+
+ QEvent e(QEvent::WindowTitleChange);
+ QApplication::sendEvent(this, &e);
+}
+
+
+/*!
+ \property QWidget::windowIcon
+ \brief the widget's icon
+
+ This property only makes sense for windows. If no icon
+ has been set, windowIcon() returns the application icon
+ (QApplication::windowIcon()).
+
+ \sa windowIconText, windowTitle
+*/
+QIcon QWidget::windowIcon() const
+{
+ const QWidget *w = this;
+ while (w) {
+ const QWidgetPrivate *d = w->d_func();
+ if (d->extra && d->extra->topextra && d->extra->topextra->icon)
+ return *d->extra->topextra->icon;
+ w = w->parentWidget();
+ }
+ return QApplication::windowIcon();
+}
+
+void QWidgetPrivate::setWindowIcon_helper()
+{
+ QEvent e(QEvent::WindowIconChange);
+ QApplication::sendEvent(q_func(), &e);
+ for (int i = 0; i < children.size(); ++i) {
+ QWidget *w = qobject_cast<QWidget *>(children.at(i));
+ if (w && !w->isWindow())
+ QApplication::sendEvent(w, &e);
+ }
+}
+
+void QWidget::setWindowIcon(const QIcon &icon)
+{
+ Q_D(QWidget);
+
+ setAttribute(Qt::WA_SetWindowIcon, !icon.isNull());
+ d->createTLExtra();
+
+ if (!d->extra->topextra->icon)
+ d->extra->topextra->icon = new QIcon();
+ *d->extra->topextra->icon = icon;
+
+ delete d->extra->topextra->iconPixmap;
+ d->extra->topextra->iconPixmap = 0;
+
+ d->setWindowIcon_sys();
+ d->setWindowIcon_helper();
+}
+
+
+/*!
+ \property QWidget::windowIconText
+ \brief the widget's icon text
+
+ This property only makes sense for windows. If no icon
+ text has been set, this functions returns an empty string.
+
+ \sa windowIcon, windowTitle
+*/
+
+QString QWidget::windowIconText() const
+{
+ Q_D(const QWidget);
+ return (d->extra && d->extra->topextra) ? d->extra->topextra->iconText : QString();
+}
+
+/*!
+ \property QWidget::windowFilePath
+ \since 4.4
+ \brief the file path associated with a widget
+
+ This property only makes sense for windows. It associates a file path with
+ a window. If you set the file path, but have not set the window title, Qt
+ sets the window title to contain a string created using the following
+ components.
+
+ On Mac OS X:
+
+ \list
+ \o The file name of the specified path, obtained using QFileInfo::fileName().
+ \endlist
+
+ On Windows and X11:
+
+ \list
+ \o The file name of the specified path, obtained using QFileInfo::fileName().
+ \o An optional \c{*} character, if the \l windowModified property is set.
+ \o The \c{0x2014} unicode character, padded either side by spaces.
+ \o The application name, obtained from the application's
+ \l{QCoreApplication::}{applicationName} property.
+ \endlist
+
+ If the window title is set at any point, then the window title takes precedence and
+ will be shown instead of the file path string.
+
+ Additionally, on Mac OS X, this has an added benefit that it sets the
+ \l{http://developer.apple.com/documentation/UserExperience/Conceptual/OSXHIGuidelines/XHIGWindows/chapter_17_section_3.html}{proxy icon}
+ for the window, assuming that the file path exists.
+
+ If no file path is set, this property contains an empty string.
+
+ By default, this property contains an empty string.
+
+ \sa windowTitle, windowIcon
+*/
+
+QString QWidget::windowFilePath() const
+{
+ Q_D(const QWidget);
+ return (d->extra && d->extra->topextra) ? d->extra->topextra->filePath : QString();
+}
+
+void QWidget::setWindowFilePath(const QString &filePath)
+{
+ if (filePath == windowFilePath())
+ return;
+
+ Q_D(QWidget);
+
+ d->createTLExtra();
+ d->extra->topextra->filePath = filePath;
+ d->setWindowFilePath_helper(filePath);
+}
+
+void QWidgetPrivate::setWindowFilePath_helper(const QString &filePath)
+{
+ if (extra->topextra && extra->topextra->caption.isEmpty()) {
+#ifdef Q_WS_MAC
+ setWindowTitle_helper(QFileInfo(filePath).fileName());
+#else
+ Q_Q(QWidget);
+ Q_UNUSED(filePath);
+ setWindowTitle_helper(q->windowTitle());
+#endif
+ }
+#ifdef Q_WS_MAC
+ setWindowFilePath_sys(filePath);
+#endif
+}
+
+/*!
+ Returns the window's role, or an empty string.
+
+ \sa windowIcon, windowTitle
+*/
+
+QString QWidget::windowRole() const
+{
+ Q_D(const QWidget);
+ return (d->extra && d->extra->topextra) ? d->extra->topextra->role : QString();
+}
+
+/*!
+ Sets the window's role to \a role. This only makes sense for
+ windows on X11.
+*/
+void QWidget::setWindowRole(const QString &role)
+{
+#if defined(Q_WS_X11)
+ Q_D(QWidget);
+ d->topData()->role = role;
+ d->setWindowRole();
+#else
+ Q_UNUSED(role)
+#endif
+}
+
+/*!
+ \property QWidget::mouseTracking
+ \brief whether mouse tracking is enabled for the widget
+
+ If mouse tracking is disabled (the default), the widget only
+ receives mouse move events when at least one mouse button is
+ pressed while the mouse is being moved.
+
+ If mouse tracking is enabled, the widget receives mouse move
+ events even if no buttons are pressed.
+
+ \sa mouseMoveEvent()
+*/
+
+
+/*!
+ Sets the widget's focus proxy to widget \a w. If \a w is 0, the
+ function resets this widget to have no focus proxy.
+
+ Some widgets can "have focus", but create a child widget, such as
+ QLineEdit, to actually handle the focus. In this case, the widget
+ can set the line edit to be its focus proxy.
+
+ setFocusProxy() sets the widget which will actually get focus when
+ "this widget" gets it. If there is a focus proxy, setFocus() and
+ hasFocus() operate on the focus proxy.
+
+ \sa focusProxy()
+*/
+
+void QWidget::setFocusProxy(QWidget * w)
+{
+ Q_D(QWidget);
+ if (!w && !d->extra)
+ return;
+
+ for (QWidget* fp = w; fp; fp = fp->focusProxy()) {
+ if (fp == this) {
+ qWarning("QWidget: %s (%s) already in focus proxy chain", metaObject()->className(), objectName().toLocal8Bit().constData());
+ return;
+ }
+ }
+
+ d->createExtra();
+ d->extra->focus_proxy = w;
+}
+
+
+/*!
+ Returns the focus proxy, or 0 if there is no focus proxy.
+
+ \sa setFocusProxy()
+*/
+
+QWidget * QWidget::focusProxy() const
+{
+ Q_D(const QWidget);
+ return d->extra ? (QWidget *)d->extra->focus_proxy : 0;
+}
+
+
+/*!
+ \property QWidget::focus
+ \brief whether this widget (or its focus proxy) has the keyboard
+ input focus
+
+ By default, this property is false.
+
+ \note Obtaining the value of this property for a widget is effectively equivalent
+ to checking whether QApplication::focusWidget() refers to the widget.
+
+ \sa setFocus(), clearFocus(), setFocusPolicy(), QApplication::focusWidget()
+*/
+bool QWidget::hasFocus() const
+{
+ const QWidget* w = this;
+ while (w->d_func()->extra && w->d_func()->extra->focus_proxy)
+ w = w->d_func()->extra->focus_proxy;
+ if (QWidget *window = w->window()) {
+#ifndef QT_NO_GRAPHICSVIEW
+ QWExtra *e = window->d_func()->extra;
+ if (e && e->proxyWidget && e->proxyWidget->hasFocus() && window->focusWidget() == w)
+ return true;
+#endif
+ }
+ return (QApplication::focusWidget() == w);
+}
+
+/*!
+ Gives the keyboard input focus to this widget (or its focus
+ proxy) if this widget or one of its parents is the \link
+ isActiveWindow() active window\endlink. The \a reason argument will
+ be passed into any focus event sent from this function, it is used
+ to give an explanation of what caused the widget to get focus.
+ If the window is not active, the widget will be given the focus when
+ the window becomes active.
+
+ First, a focus out event is sent to the focus widget (if any) to
+ tell it that it is about to lose the focus. Then a focus in event
+ is sent to this widget to tell it that it just received the focus.
+ (Nothing happens if the focus in and focus out widgets are the
+ same.)
+
+ \note On embedded platforms, setFocus() will not cause an input panel
+ to be opened by the input method. If you want this to happen, you
+ have to send a QEvent::RequestSoftwareInputPanel event to the
+ widget yourself.
+
+ setFocus() gives focus to a widget regardless of its focus policy,
+ but does not clear any keyboard grab (see grabKeyboard()).
+
+ Be aware that if the widget is hidden, it will not accept focus
+ until it is shown.
+
+ \warning If you call setFocus() in a function which may itself be
+ called from focusOutEvent() or focusInEvent(), you may get an
+ infinite recursion.
+
+ \sa hasFocus(), clearFocus(), focusInEvent(), focusOutEvent(),
+ setFocusPolicy(), focusWidget(), QApplication::focusWidget(), grabKeyboard(),
+ grabMouse(), {Keyboard Focus}, QEvent::RequestSoftwareInputPanel
+*/
+
+void QWidget::setFocus(Qt::FocusReason reason)
+{
+ if (!isEnabled())
+ return;
+
+ QWidget *f = this;
+ while (f->d_func()->extra && f->d_func()->extra->focus_proxy)
+ f = f->d_func()->extra->focus_proxy;
+
+ if (QApplication::focusWidget() == f
+#if defined(Q_WS_WIN)
+ && GetFocus() == f->internalWinId()
+#endif
+ )
+ return;
+
+#ifndef QT_NO_GRAPHICSVIEW
+ QWidget *previousProxyFocus = 0;
+ if (QWExtra *topData = window()->d_func()->extra) {
+ if (topData->proxyWidget && topData->proxyWidget->hasFocus()) {
+ previousProxyFocus = topData->proxyWidget->widget()->focusWidget();
+ if (previousProxyFocus && previousProxyFocus->focusProxy())
+ previousProxyFocus = previousProxyFocus->focusProxy();
+ if (previousProxyFocus == this && !topData->proxyWidget->d_func()->proxyIsGivingFocus)
+ return;
+ }
+ }
+#endif
+
+ QWidget *w = f;
+ if (isHidden()) {
+ while (w && w->isHidden()) {
+ w->d_func()->focus_child = f;
+ w = w->isWindow() ? 0 : w->parentWidget();
+ }
+ } else {
+ while (w) {
+ w->d_func()->focus_child = f;
+ w = w->isWindow() ? 0 : w->parentWidget();
+ }
+ }
+
+#ifndef QT_NO_GRAPHICSVIEW
+ // Update proxy state
+ if (QWExtra *topData = window()->d_func()->extra) {
+ if (topData->proxyWidget && !topData->proxyWidget->hasFocus()) {
+ topData->proxyWidget->d_func()->focusFromWidgetToProxy = 1;
+ topData->proxyWidget->setFocus(reason);
+ topData->proxyWidget->d_func()->focusFromWidgetToProxy = 0;
+ }
+ }
+#endif
+
+ if (f->isActiveWindow()) {
+ QApplicationPrivate::setFocusWidget(f, reason);
+#ifndef QT_NO_ACCESSIBILITY
+# ifdef Q_OS_WIN
+ // The negation of the condition in setFocus_sys
+ if (!(testAttribute(Qt::WA_WState_Created) && window()->windowType() != Qt::Popup && internalWinId()))
+ //setFocusWidget will already post a focus event for us (that the AT client receives) on Windows
+# endif
+# ifdef Q_OS_UNIX
+ // menus update the focus manually and this would create bogus events
+ if (!(f->inherits("QMenuBar") || f->inherits("QMenu") || f->inherits("QMenuItem")))
+# endif
+ QAccessible::updateAccessibility(f, 0, QAccessible::Focus);
+#endif
+#ifndef QT_NO_GRAPHICSVIEW
+ if (QWExtra *topData = window()->d_func()->extra) {
+ if (topData->proxyWidget) {
+ if (previousProxyFocus && previousProxyFocus != f) {
+ // Send event to self
+ QFocusEvent event(QEvent::FocusOut, reason);
+ QPointer<QWidget> that = previousProxyFocus;
+ QApplication::sendEvent(previousProxyFocus, &event);
+ if (that)
+ QApplication::sendEvent(that->style(), &event);
+ }
+ if (!isHidden()) {
+#ifndef QT_NO_GRAPHICSVIEW
+ // Update proxy state
+ if (QWExtra *topData = window()->d_func()->extra)
+ if (topData->proxyWidget && topData->proxyWidget->hasFocus())
+ topData->proxyWidget->d_func()->updateProxyInputMethodAcceptanceFromWidget();
+#endif
+ // Send event to self
+ QFocusEvent event(QEvent::FocusIn, reason);
+ QPointer<QWidget> that = f;
+ QApplication::sendEvent(f, &event);
+ if (that)
+ QApplication::sendEvent(that->style(), &event);
+ }
+ }
+ }
+#endif
+ }
+}
+
+/*!
+ \fn void QWidget::setFocus()
+ \overload
+
+ Gives the keyboard input focus to this widget (or its focus
+ proxy) if this widget or one of its parents is the
+ \l{isActiveWindow()}{active window}.
+*/
+
+/*!
+ Takes keyboard input focus from the widget.
+
+ If the widget has active focus, a \link focusOutEvent() focus out
+ event\endlink is sent to this widget to tell it that it is about
+ to lose the focus.
+
+ This widget must enable focus setting in order to get the keyboard
+ input focus, i.e. it must call setFocusPolicy().
+
+ \sa hasFocus(), setFocus(), focusInEvent(), focusOutEvent(),
+ setFocusPolicy(), QApplication::focusWidget()
+*/
+
+void QWidget::clearFocus()
+{
+ QWidget *w = this;
+ while (w) {
+ if (w->d_func()->focus_child == this)
+ w->d_func()->focus_child = 0;
+ w = w->parentWidget();
+ }
+#ifndef QT_NO_GRAPHICSVIEW
+ QWExtra *topData = d_func()->extra;
+ if (topData && topData->proxyWidget)
+ topData->proxyWidget->clearFocus();
+#endif
+
+ if (hasFocus()) {
+ // Update proxy state
+ QApplicationPrivate::setFocusWidget(0, Qt::OtherFocusReason);
+#if defined(Q_WS_WIN)
+ if (!(windowType() == Qt::Popup) && GetFocus() == internalWinId())
+ SetFocus(0);
+ else
+#endif
+ {
+#ifndef QT_NO_ACCESSIBILITY
+ QAccessible::updateAccessibility(this, 0, QAccessible::Focus);
+#endif
+ }
+ }
+}
+
+
+/*!
+ \fn bool QWidget::focusNextChild()
+
+ Finds a new widget to give the keyboard focus to, as appropriate
+ for \key Tab, and returns true if it can find a new widget, or
+ false if it can't.
+
+ \sa focusPreviousChild()
+*/
+
+/*!
+ \fn bool QWidget::focusPreviousChild()
+
+ Finds a new widget to give the keyboard focus to, as appropriate
+ for \key Shift+Tab, and returns true if it can find a new widget,
+ or false if it can't.
+
+ \sa focusNextChild()
+*/
+
+/*!
+ Finds a new widget to give the keyboard focus to, as appropriate
+ for Tab and Shift+Tab, and returns true if it can find a new
+ widget, or false if it can't.
+
+ If \a next is true, this function searches forward, if \a next
+ is false, it searches backward.
+
+ Sometimes, you will want to reimplement this function. For
+ example, a web browser might reimplement it to move its "current
+ active link" forward or backward, and call
+ focusNextPrevChild() only when it reaches the last or
+ first link on the "page".
+
+ Child widgets call focusNextPrevChild() on their parent widgets,
+ but only the window that contains the child widgets decides where
+ to redirect focus. By reimplementing this function for an object,
+ you thus gain control of focus traversal for all child widgets.
+
+ \sa focusNextChild(), focusPreviousChild()
+*/
+
+bool QWidget::focusNextPrevChild(bool next)
+{
+ Q_D(QWidget);
+ QWidget* p = parentWidget();
+ bool isSubWindow = (windowType() == Qt::SubWindow);
+ if (!isWindow() && !isSubWindow && p)
+ return p->focusNextPrevChild(next);
+#ifndef QT_NO_GRAPHICSVIEW
+ if (d->extra && d->extra->proxyWidget)
+ return d->extra->proxyWidget->focusNextPrevChild(next);
+#endif
+ QWidget *w = QApplicationPrivate::focusNextPrevChild_helper(this, next);
+ if (!w) return false;
+
+ w->setFocus(next ? Qt::TabFocusReason : Qt::BacktabFocusReason);
+ return true;
+}
+
+/*!
+ Returns the last child of this widget that setFocus had been
+ called on. For top level widgets this is the widget that will get
+ focus in case this window gets activated
+
+ This is not the same as QApplication::focusWidget(), which returns
+ the focus widget in the currently active window.
+*/
+
+QWidget *QWidget::focusWidget() const
+{
+ return const_cast<QWidget *>(d_func()->focus_child);
+}
+
+/*!
+ Returns the next widget in this widget's focus chain.
+
+ \sa previousInFocusChain()
+*/
+QWidget *QWidget::nextInFocusChain() const
+{
+ return const_cast<QWidget *>(d_func()->focus_next);
+}
+
+/*!
+ \brief The previousInFocusChain function returns the previous
+ widget in this widget's focus chain.
+
+ \sa nextInFocusChain()
+
+ \since 4.6
+*/
+QWidget *QWidget::previousInFocusChain() const
+{
+ return const_cast<QWidget *>(d_func()->focus_prev);
+}
+
+/*!
+ \property QWidget::isActiveWindow
+ \brief whether this widget's window is the active window
+
+ The active window is the window that contains the widget that has
+ keyboard focus (The window may still have focus if it has no
+ widgets or none of its widgets accepts keyboard focus).
+
+ When popup windows are visible, this property is true for both the
+ active window \e and for the popup.
+
+ By default, this property is false.
+
+ \sa activateWindow(), QApplication::activeWindow()
+*/
+bool QWidget::isActiveWindow() const
+{
+ QWidget *tlw = window();
+ if(tlw == QApplication::activeWindow() || (isVisible() && (tlw->windowType() == Qt::Popup)))
+ return true;
+
+#ifndef QT_NO_GRAPHICSVIEW
+ if (QWExtra *tlwExtra = tlw->d_func()->extra) {
+ if (isVisible() && tlwExtra->proxyWidget)
+ return tlwExtra->proxyWidget->isActiveWindow();
+ }
+#endif
+
+#ifdef Q_WS_MAC
+ extern bool qt_mac_is_macdrawer(const QWidget *); //qwidget_mac.cpp
+ if(qt_mac_is_macdrawer(tlw) &&
+ tlw->parentWidget() && tlw->parentWidget()->isActiveWindow())
+ return true;
+
+ extern bool qt_mac_insideKeyWindow(const QWidget *); //qwidget_mac.cpp
+ if (QApplication::testAttribute(Qt::AA_MacPluginApplication) && qt_mac_insideKeyWindow(tlw))
+ return true;
+#endif
+ if(style()->styleHint(QStyle::SH_Widget_ShareActivation, 0, this)) {
+ if(tlw->windowType() == Qt::Tool &&
+ !tlw->isModal() &&
+ (!tlw->parentWidget() || tlw->parentWidget()->isActiveWindow()))
+ return true;
+ QWidget *w = QApplication::activeWindow();
+ while(w && tlw->windowType() == Qt::Tool &&
+ !w->isModal() && w->parentWidget()) {
+ w = w->parentWidget()->window();
+ if(w == tlw)
+ return true;
+ }
+ }
+#if defined(Q_WS_WIN32)
+ HWND active = GetActiveWindow();
+ if (!tlw->testAttribute(Qt::WA_WState_Created))
+ return false;
+ return active == tlw->internalWinId() || ::IsChild(active, tlw->internalWinId());
+#else
+ return false;
+#endif
+}
+
+/*!
+ Puts the \a second widget after the \a first widget in the focus order.
+
+ Note that since the tab order of the \a second widget is changed, you
+ should order a chain like this:
+
+ \snippet doc/src/snippets/code/src_gui_kernel_qwidget.cpp 9
+
+ \e not like this:
+
+ \snippet doc/src/snippets/code/src_gui_kernel_qwidget.cpp 10
+
+ If \a first or \a second has a focus proxy, setTabOrder()
+ correctly substitutes the proxy.
+
+ \sa setFocusPolicy(), setFocusProxy(), {Keyboard Focus}
+*/
+void QWidget::setTabOrder(QWidget* first, QWidget *second)
+{
+ if (!first || !second || first->focusPolicy() == Qt::NoFocus || second->focusPolicy() == Qt::NoFocus)
+ return;
+
+ if (first->window() != second->window()) {
+ qWarning("QWidget::setTabOrder: 'first' and 'second' must be in the same window");
+ return;
+ }
+
+ QWidget *fp = first->focusProxy();
+ if (fp) {
+ // If first is redirected, set first to the last child of first
+ // that can take keyboard focus so that second is inserted after
+ // that last child, and the focus order within first is (more
+ // likely to be) preserved.
+ QList<QWidget *> l = first->findChildren<QWidget *>();
+ for (int i = l.size()-1; i >= 0; --i) {
+ QWidget * next = l.at(i);
+ if (next->window() == fp->window()) {
+ fp = next;
+ if (fp->focusPolicy() != Qt::NoFocus)
+ break;
+ }
+ }
+ first = fp;
+ }
+
+ if (fp == second)
+ return;
+
+ if (QWidget *sp = second->focusProxy())
+ second = sp;
+
+// QWidget *fp = first->d_func()->focus_prev;
+ QWidget *fn = first->d_func()->focus_next;
+
+ if (fn == second || first == second)
+ return;
+
+ QWidget *sp = second->d_func()->focus_prev;
+ QWidget *sn = second->d_func()->focus_next;
+
+ fn->d_func()->focus_prev = second;
+ first->d_func()->focus_next = second;
+
+ second->d_func()->focus_next = fn;
+ second->d_func()->focus_prev = first;
+
+ sp->d_func()->focus_next = sn;
+ sn->d_func()->focus_prev = sp;
+
+
+ Q_ASSERT(first->d_func()->focus_next->d_func()->focus_prev == first);
+ Q_ASSERT(first->d_func()->focus_prev->d_func()->focus_next == first);
+
+ Q_ASSERT(second->d_func()->focus_next->d_func()->focus_prev == second);
+ Q_ASSERT(second->d_func()->focus_prev->d_func()->focus_next == second);
+}
+
+/*!\internal
+
+ Moves the relevant subwidgets of this widget from the \a oldtlw's
+ tab chain to that of the new parent, if there's anything to move and
+ we're really moving
+
+ This function is called from QWidget::reparent() *after* the widget
+ has been reparented.
+
+ \sa reparent()
+*/
+
+void QWidgetPrivate::reparentFocusWidgets(QWidget * oldtlw)
+{
+ Q_Q(QWidget);
+ if (oldtlw == q->window())
+ return; // nothing to do
+
+ if(focus_child)
+ focus_child->clearFocus();
+
+ // separate the focus chain into new (children of myself) and old (the rest)
+ QWidget *firstOld = 0;
+ //QWidget *firstNew = q; //invariant
+ QWidget *o = 0; // last in the old list
+ QWidget *n = q; // last in the new list
+
+ bool prevWasNew = true;
+ QWidget *w = focus_next;
+
+ //Note: for efficiency, we do not maintain the list invariant inside the loop
+ //we append items to the relevant list, and we optimize by not changing pointers
+ //when subsequent items are going into the same list.
+ while (w != q) {
+ bool currentIsNew = q->isAncestorOf(w);
+ if (currentIsNew) {
+ if (!prevWasNew) {
+ //prev was old -- append to new list
+ n->d_func()->focus_next = w;
+ w->d_func()->focus_prev = n;
+ }
+ n = w;
+ } else {
+ if (prevWasNew) {
+ //prev was new -- append to old list, if there is one
+ if (o) {
+ o->d_func()->focus_next = w;
+ w->d_func()->focus_prev = o;
+ } else {
+ // "create" the old list
+ firstOld = w;
+ }
+ }
+ o = w;
+ }
+ w = w->d_func()->focus_next;
+ prevWasNew = currentIsNew;
+ }
+
+ //repair the old list:
+ if (firstOld) {
+ o->d_func()->focus_next = firstOld;
+ firstOld->d_func()->focus_prev = o;
+ }
+
+ if (!q->isWindow()) {
+ QWidget *topLevel = q->window();
+ //insert new chain into toplevel's chain
+
+ QWidget *prev = topLevel->d_func()->focus_prev;
+
+ topLevel->d_func()->focus_prev = n;
+ prev->d_func()->focus_next = q;
+
+ focus_prev = prev;
+ n->d_func()->focus_next = topLevel;
+ } else {
+ //repair the new list
+ n->d_func()->focus_next = q;
+ focus_prev = n;
+ }
+
+}
+
+/*!\internal
+
+ Measures the shortest distance from a point to a rect.
+
+ This function is called from QDesktopwidget::screen(QPoint) to find the
+ closest screen for a point.
+ In directional KeypadNavigation, it is called to find the closest
+ widget to the current focus widget center.
+*/
+int QWidgetPrivate::pointToRect(const QPoint &p, const QRect &r)
+{
+ int dx = 0;
+ int dy = 0;
+ if (p.x() < r.left())
+ dx = r.left() - p.x();
+ else if (p.x() > r.right())
+ dx = p.x() - r.right();
+ if (p.y() < r.top())
+ dy = r.top() - p.y();
+ else if (p.y() > r.bottom())
+ dy = p.y() - r.bottom();
+ return dx + dy;
+}
+
+/*!
+ \property QWidget::frameSize
+ \brief the size of the widget including any window frame
+
+ By default, this property contains a value that depends on the user's
+ platform and screen geometry.
+*/
+QSize QWidget::frameSize() const
+{
+ Q_D(const QWidget);
+ if (isWindow() && !(windowType() == Qt::Popup)) {
+ QRect fs = d->frameStrut();
+ return QSize(data->crect.width() + fs.left() + fs.right(),
+ data->crect.height() + fs.top() + fs.bottom());
+ }
+ return data->crect.size();
+}
+
+/*! \fn void QWidget::move(int x, int y)
+
+ \overload
+
+ This corresponds to move(QPoint(\a x, \a y)).
+*/
+
+void QWidget::move(const QPoint &p)
+{
+ Q_D(QWidget);
+ setAttribute(Qt::WA_Moved);
+ if (isWindow())
+ d->topData()->posFromMove = true;
+ if (testAttribute(Qt::WA_WState_Created)) {
+ d->setGeometry_sys(p.x() + geometry().x() - QWidget::x(),
+ p.y() + geometry().y() - QWidget::y(),
+ width(), height(), true);
+ d->setDirtyOpaqueRegion();
+ } else {
+ data->crect.moveTopLeft(p); // no frame yet
+ setAttribute(Qt::WA_PendingMoveEvent);
+ }
+}
+
+/*! \fn void QWidget::resize(int w, int h)
+ \overload
+
+ This corresponds to resize(QSize(\a w, \a h)).
+*/
+
+void QWidget::resize(const QSize &s)
+{
+ Q_D(QWidget);
+ setAttribute(Qt::WA_Resized);
+ if (testAttribute(Qt::WA_WState_Created)) {
+ d->setGeometry_sys(geometry().x(), geometry().y(), s.width(), s.height(), false);
+ d->setDirtyOpaqueRegion();
+ } else {
+ data->crect.setSize(s.boundedTo(maximumSize()).expandedTo(minimumSize()));
+ setAttribute(Qt::WA_PendingResizeEvent);
+ }
+}
+
+void QWidget::setGeometry(const QRect &r)
+{
+ Q_D(QWidget);
+ setAttribute(Qt::WA_Resized);
+ setAttribute(Qt::WA_Moved);
+ if (isWindow())
+ d->topData()->posFromMove = false;
+ if (testAttribute(Qt::WA_WState_Created)) {
+ d->setGeometry_sys(r.x(), r.y(), r.width(), r.height(), true);
+ d->setDirtyOpaqueRegion();
+ } else {
+ data->crect.setTopLeft(r.topLeft());
+ data->crect.setSize(r.size().boundedTo(maximumSize()).expandedTo(minimumSize()));
+ setAttribute(Qt::WA_PendingMoveEvent);
+ setAttribute(Qt::WA_PendingResizeEvent);
+ }
+}
+
+/*!
+ \since 4.2
+ Saves the current geometry and state for top-level widgets.
+
+ To save the geometry when the window closes, you can
+ implement a close event like this:
+
+ \snippet doc/src/snippets/code/src_gui_kernel_qwidget.cpp 11
+
+ See the \l{Window Geometry} documentation for an overview of geometry
+ issues with windows.
+
+ Use QMainWindow::saveState() to save the geometry and the state of
+ toolbars and dock widgets.
+
+ \sa restoreGeometry(), QMainWindow::saveState(), QMainWindow::restoreState()
+*/
+QByteArray QWidget::saveGeometry() const
+{
+#ifdef QT_MAC_USE_COCOA
+ // We check if the window was maximized during this invocation. If so, we need to record the
+ // starting position as 0,0.
+ Q_D(const QWidget);
+ QRect newFramePosition = frameGeometry();
+ QRect newNormalPosition = normalGeometry();
+ if(d->topData()->wasMaximized && !(windowState() & Qt::WindowMaximized)) {
+ // Change the starting position
+ newFramePosition.moveTo(0, 0);
+ newNormalPosition.moveTo(0, 0);
+ }
+#endif // QT_MAC_USE_COCOA
+ QByteArray array;
+ QDataStream stream(&array, QIODevice::WriteOnly);
+ stream.setVersion(QDataStream::Qt_4_0);
+ const quint32 magicNumber = 0x1D9D0CB;
+ quint16 majorVersion = 1;
+ quint16 minorVersion = 0;
+ stream << magicNumber
+ << majorVersion
+ << minorVersion
+#ifdef QT_MAC_USE_COCOA
+ << newFramePosition
+ << newNormalPosition
+#else
+ << frameGeometry()
+ << normalGeometry()
+#endif // QT_MAC_USE_COCOA
+ << qint32(QApplication::desktop()->screenNumber(this))
+ << quint8(windowState() & Qt::WindowMaximized)
+ << quint8(windowState() & Qt::WindowFullScreen);
+ return array;
+}
+
+/*!
+ \since 4.2
+
+ Restores the geometry and state top-level widgets stored in the
+ byte array \a geometry. Returns true on success; otherwise
+ returns false.
+
+ If the restored geometry is off-screen, it will be modified to be
+ inside the available screen geometry.
+
+ To restore geometry saved using QSettings, you can use code like
+ this:
+
+ \snippet doc/src/snippets/code/src_gui_kernel_qwidget.cpp 12
+
+ See the \l{Window Geometry} documentation for an overview of geometry
+ issues with windows.
+
+ Use QMainWindow::restoreState() to restore the geometry and the
+ state of toolbars and dock widgets.
+
+ \sa saveGeometry(), QSettings, QMainWindow::saveState(), QMainWindow::restoreState()
+*/
+bool QWidget::restoreGeometry(const QByteArray &geometry)
+{
+ if (geometry.size() < 4)
+ return false;
+ QDataStream stream(geometry);
+ stream.setVersion(QDataStream::Qt_4_0);
+
+ const quint32 magicNumber = 0x1D9D0CB;
+ quint32 storedMagicNumber;
+ stream >> storedMagicNumber;
+ if (storedMagicNumber != magicNumber)
+ return false;
+
+ const quint16 currentMajorVersion = 1;
+ quint16 majorVersion = 0;
+ quint16 minorVersion = 0;
+
+ stream >> majorVersion >> minorVersion;
+
+ if (majorVersion != currentMajorVersion)
+ return false;
+ // (Allow all minor versions.)
+
+ QRect restoredFrameGeometry;
+ QRect restoredNormalGeometry;
+ qint32 restoredScreenNumber;
+ quint8 maximized;
+ quint8 fullScreen;
+
+ stream >> restoredFrameGeometry
+ >> restoredNormalGeometry
+ >> restoredScreenNumber
+ >> maximized
+ >> fullScreen;
+
+ const int frameHeight = 20;
+ if (!restoredFrameGeometry.isValid())
+ restoredFrameGeometry = QRect(QPoint(0,0), sizeHint());
+
+ if (!restoredNormalGeometry.isValid())
+ restoredNormalGeometry = QRect(QPoint(0, frameHeight), sizeHint());
+ if (!restoredNormalGeometry.isValid()) {
+ // use the widget's adjustedSize if the sizeHint() doesn't help
+ restoredNormalGeometry.setSize(restoredNormalGeometry
+ .size()
+ .expandedTo(d_func()->adjustedSize()));
+ }
+
+ const QDesktopWidget * const desktop = QApplication::desktop();
+ if (restoredScreenNumber >= desktop->numScreens())
+ restoredScreenNumber = desktop->primaryScreen();
+
+ const QRect availableGeometry = desktop->availableGeometry(restoredScreenNumber);
+
+ // Modify the restored geometry if we are about to restore to coordinates
+ // that would make the window "lost". This happens if:
+ // - The restored geometry is completely oustside the available geometry
+ // - The title bar is outside the available geometry.
+ // - (Mac only) The window is higher than the available geometry. It must
+ // be possible to bring the size grip on screen by moving the window.
+#ifdef Q_WS_MAC
+ restoredFrameGeometry.setHeight(qMin(restoredFrameGeometry.height(), availableGeometry.height()));
+ restoredNormalGeometry.setHeight(qMin(restoredNormalGeometry.height(), availableGeometry.height() - frameHeight));
+#endif
+
+ if (!restoredFrameGeometry.intersects(availableGeometry)) {
+ restoredFrameGeometry.moveBottom(qMin(restoredFrameGeometry.bottom(), availableGeometry.bottom()));
+ restoredFrameGeometry.moveLeft(qMax(restoredFrameGeometry.left(), availableGeometry.left()));
+ restoredFrameGeometry.moveRight(qMin(restoredFrameGeometry.right(), availableGeometry.right()));
+ }
+ restoredFrameGeometry.moveTop(qMax(restoredFrameGeometry.top(), availableGeometry.top()));
+
+ if (!restoredNormalGeometry.intersects(availableGeometry)) {
+ restoredNormalGeometry.moveBottom(qMin(restoredNormalGeometry.bottom(), availableGeometry.bottom()));
+ restoredNormalGeometry.moveLeft(qMax(restoredNormalGeometry.left(), availableGeometry.left()));
+ restoredNormalGeometry.moveRight(qMin(restoredNormalGeometry.right(), availableGeometry.right()));
+ }
+ restoredNormalGeometry.moveTop(qMax(restoredNormalGeometry.top(), availableGeometry.top() + frameHeight));
+
+ if (maximized || fullScreen) {
+ // set geomerty before setting the window state to make
+ // sure the window is maximized to the right screen.
+ // Skip on windows: the window is restored into a broken
+ // half-maximized state.
+#ifndef Q_WS_WIN
+ setGeometry(restoredNormalGeometry);
+#endif
+ Qt::WindowStates ws = windowState();
+ if (maximized)
+ ws |= Qt::WindowMaximized;
+ if (fullScreen)
+ ws |= Qt::WindowFullScreen;
+ setWindowState(ws);
+ d_func()->topData()->normalGeometry = restoredNormalGeometry;
+ } else {
+ QPoint offset;
+#ifdef Q_WS_X11
+ if (isFullScreen())
+ offset = d_func()->topData()->fullScreenOffset;
+#endif
+ setWindowState(windowState() & ~(Qt::WindowMaximized | Qt::WindowFullScreen));
+ move(restoredFrameGeometry.topLeft() + offset);
+ resize(restoredNormalGeometry.size());
+ }
+ return true;
+}
+
+/*!\fn void QWidget::setGeometry(int x, int y, int w, int h)
+ \overload
+
+ This corresponds to setGeometry(QRect(\a x, \a y, \a w, \a h)).
+*/
+
+/*!
+ Sets the margins around the contents of the widget to have the sizes
+ \a left, \a top, \a right, and \a bottom. The margins are used by
+ the layout system, and may be used by subclasses to specify the area
+ to draw in (e.g. excluding the frame).
+
+ Changing the margins will trigger a resizeEvent().
+
+ \sa contentsRect(), getContentsMargins()
+*/
+void QWidget::setContentsMargins(int left, int top, int right, int bottom)
+{
+ Q_D(QWidget);
+ if (left == d->leftmargin && top == d->topmargin
+ && right == d->rightmargin && bottom == d->bottommargin)
+ return;
+ d->leftmargin = left;
+ d->topmargin = top;
+ d->rightmargin = right;
+ d->bottommargin = bottom;
+
+ if (QLayout *l=d->layout)
+ l->update(); //force activate; will do updateGeometry
+ else
+ updateGeometry();
+
+ // ### Qt 5: compat, remove
+ if (isVisible()) {
+ update();
+ QResizeEvent e(data->crect.size(), data->crect.size());
+ QApplication::sendEvent(this, &e);
+ } else {
+ setAttribute(Qt::WA_PendingResizeEvent, true);
+ }
+
+ QEvent e(QEvent::ContentsRectChange);
+ QApplication::sendEvent(this, &e);
+}
+
+/*!
+ \overload
+ \since 4.6
+
+ \brief The setContentsMargins function sets the margins around the
+ widget's contents.
+
+ Sets the margins around the contents of the widget to have the
+ sizes determined by \a margins. The margins are
+ used by the layout system, and may be used by subclasses to
+ specify the area to draw in (e.g. excluding the frame).
+
+ Changing the margins will trigger a resizeEvent().
+
+ \sa contentsRect(), getContentsMargins()
+*/
+void QWidget::setContentsMargins(const QMargins &margins)
+{
+ setContentsMargins(margins.left(), margins.top(),
+ margins.right(), margins.bottom());
+}
+
+/*!
+ Returns the widget's contents margins for \a left, \a top, \a
+ right, and \a bottom.
+
+ \sa setContentsMargins(), contentsRect()
+ */
+void QWidget::getContentsMargins(int *left, int *top, int *right, int *bottom) const
+{
+ Q_D(const QWidget);
+ if (left)
+ *left = d->leftmargin;
+ if (top)
+ *top = d->topmargin;
+ if (right)
+ *right = d->rightmargin;
+ if (bottom)
+ *bottom = d->bottommargin;
+}
+
+/*!
+ \since 4.6
+
+ \brief The contentsMargins function returns the widget's contents margins.
+
+ \sa getContentsMargins(), setContentsMargins(), contentsRect()
+ */
+QMargins QWidget::contentsMargins() const
+{
+ Q_D(const QWidget);
+ return QMargins(d->leftmargin, d->topmargin, d->rightmargin, d->bottommargin);
+}
+
+
+/*!
+ Returns the area inside the widget's margins.
+
+ \sa setContentsMargins(), getContentsMargins()
+*/
+QRect QWidget::contentsRect() const
+{
+ Q_D(const QWidget);
+ return QRect(QPoint(d->leftmargin, d->topmargin),
+ QPoint(data->crect.width() - 1 - d->rightmargin,
+ data->crect.height() - 1 - d->bottommargin));
+
+}
+
+
+
+/*!
+ \fn void QWidget::customContextMenuRequested(const QPoint &pos)
+
+ This signal is emitted when the widget's \l contextMenuPolicy is
+ Qt::CustomContextMenu, and the user has requested a context menu on
+ the widget. The position \a pos is the position of the context menu
+ event that the widget receives. Normally this is in widget
+ coordinates. The exception to this rule is QAbstractScrollArea and
+ its subclasses that map the context menu event to coordinates of the
+ \link QAbstractScrollArea::viewport() viewport() \endlink .
+
+
+ \sa mapToGlobal() QMenu contextMenuPolicy
+*/
+
+
+/*!
+ \property QWidget::contextMenuPolicy
+ \brief how the widget shows a context menu
+
+ The default value of this property is Qt::DefaultContextMenu,
+ which means the contextMenuEvent() handler is called. Other values
+ are Qt::NoContextMenu, Qt::PreventContextMenu,
+ Qt::ActionsContextMenu, and Qt::CustomContextMenu. With
+ Qt::CustomContextMenu, the signal customContextMenuRequested() is
+ emitted.
+
+ \sa contextMenuEvent(), customContextMenuRequested(), actions()
+*/
+
+Qt::ContextMenuPolicy QWidget::contextMenuPolicy() const
+{
+ return (Qt::ContextMenuPolicy)data->context_menu_policy;
+}
+
+void QWidget::setContextMenuPolicy(Qt::ContextMenuPolicy policy)
+{
+ data->context_menu_policy = (uint) policy;
+}
+
+/*!
+ \property QWidget::focusPolicy
+ \brief the way the widget accepts keyboard focus
+
+ The policy is Qt::TabFocus if the widget accepts keyboard
+ focus by tabbing, Qt::ClickFocus if the widget accepts
+ focus by clicking, Qt::StrongFocus if it accepts both, and
+ Qt::NoFocus (the default) if it does not accept focus at
+ all.
+
+ You must enable keyboard focus for a widget if it processes
+ keyboard events. This is normally done from the widget's
+ constructor. For instance, the QLineEdit constructor calls
+ setFocusPolicy(Qt::StrongFocus).
+
+ If the widget has a focus proxy, then the focus policy will
+ be propagated to it.
+
+ \sa focusInEvent(), focusOutEvent(), keyPressEvent(), keyReleaseEvent(), enabled
+*/
+
+
+Qt::FocusPolicy QWidget::focusPolicy() const
+{
+ return (Qt::FocusPolicy)data->focus_policy;
+}
+
+void QWidget::setFocusPolicy(Qt::FocusPolicy policy)
+{
+ data->focus_policy = (uint) policy;
+ Q_D(QWidget);
+ if (d->extra && d->extra->focus_proxy)
+ d->extra->focus_proxy->setFocusPolicy(policy);
+}
+
+/*!
+ \property QWidget::updatesEnabled
+ \brief whether updates are enabled
+
+ An updates enabled widget receives paint events and has a system
+ background; a disabled widget does not. This also implies that
+ calling update() and repaint() has no effect if updates are
+ disabled.
+
+ By default, this property is true.
+
+ setUpdatesEnabled() is normally used to disable updates for a
+ short period of time, for instance to avoid screen flicker during
+ large changes. In Qt, widgets normally do not generate screen
+ flicker, but on X11 the server might erase regions on the screen
+ when widgets get hidden before they can be replaced by other
+ widgets. Disabling updates solves this.
+
+ Example:
+ \snippet doc/src/snippets/code/src_gui_kernel_qwidget.cpp 13
+
+ Disabling a widget implicitly disables all its children. Enabling a widget
+ enables all child widgets \e except top-level widgets or those that
+ have been explicitly disabled. Re-enabling updates implicitly calls
+ update() on the widget.
+
+ \sa paintEvent()
+*/
+void QWidget::setUpdatesEnabled(bool enable)
+{
+ Q_D(QWidget);
+ setAttribute(Qt::WA_ForceUpdatesDisabled, !enable);
+ d->setUpdatesEnabled_helper(enable);
+}
+
+/*! \fn void QWidget::show()
+
+ Shows the widget and its child widgets. This function is
+ equivalent to setVisible(true).
+
+ \sa raise(), showEvent(), hide(), setVisible(), showMinimized(), showMaximized(),
+ showNormal(), isVisible()
+*/
+
+
+/*! \internal
+
+ Makes the widget visible in the isVisible() meaning of the word.
+ It is only called for toplevels or widgets with visible parents.
+ */
+void QWidgetPrivate::show_recursive()
+{
+ Q_Q(QWidget);
+ // polish if necessary
+
+ if (!q->testAttribute(Qt::WA_WState_Created))
+ createRecursively();
+ q->ensurePolished();
+
+#ifdef QT3_SUPPORT
+ if(sendChildEvents)
+ QApplication::sendPostedEvents(q, QEvent::ChildInserted);
+#endif
+ if (!q->isWindow() && q->parentWidget()->d_func()->layout && !q->parentWidget()->data->in_show)
+ q->parentWidget()->d_func()->layout->activate();
+ // activate our layout before we and our children become visible
+ if (layout)
+ layout->activate();
+
+ show_helper();
+}
+
+void QWidgetPrivate::sendPendingMoveAndResizeEvents(bool recursive, bool disableUpdates)
+{
+ Q_Q(QWidget);
+
+ disableUpdates = disableUpdates && q->updatesEnabled();
+ if (disableUpdates)
+ q->setAttribute(Qt::WA_UpdatesDisabled);
+
+ if (q->testAttribute(Qt::WA_PendingMoveEvent)) {
+ QMoveEvent e(data.crect.topLeft(), data.crect.topLeft());
+ QApplication::sendEvent(q, &e);
+ q->setAttribute(Qt::WA_PendingMoveEvent, false);
+ }
+
+ if (q->testAttribute(Qt::WA_PendingResizeEvent)) {
+ QResizeEvent e(data.crect.size(), QSize());
+ QApplication::sendEvent(q, &e);
+ q->setAttribute(Qt::WA_PendingResizeEvent, false);
+ }
+
+ if (disableUpdates)
+ q->setAttribute(Qt::WA_UpdatesDisabled, false);
+
+ if (!recursive)
+ return;
+
+ for (int i = 0; i < children.size(); ++i) {
+ if (QWidget *child = qobject_cast<QWidget *>(children.at(i)))
+ child->d_func()->sendPendingMoveAndResizeEvents(recursive, disableUpdates);
+ }
+}
+
+void QWidgetPrivate::activateChildLayoutsRecursively()
+{
+ sendPendingMoveAndResizeEvents(false, true);
+
+ for (int i = 0; i < children.size(); ++i) {
+ QWidget *child = qobject_cast<QWidget *>(children.at(i));
+ if (!child || child->isHidden() || child->isWindow())
+ continue;
+
+ child->ensurePolished();
+
+ // Activate child's layout
+ QWidgetPrivate *childPrivate = child->d_func();
+ if (childPrivate->layout)
+ childPrivate->layout->activate();
+
+ // Pretend we're visible.
+ const bool wasVisible = child->isVisible();
+ if (!wasVisible)
+ child->setAttribute(Qt::WA_WState_Visible);
+
+ // Do the same for all my children.
+ childPrivate->activateChildLayoutsRecursively();
+
+ // We're not cheating anymore.
+ if (!wasVisible)
+ child->setAttribute(Qt::WA_WState_Visible, false);
+ }
+}
+
+void QWidgetPrivate::show_helper()
+{
+ Q_Q(QWidget);
+ data.in_show = true; // qws optimization
+ // make sure we receive pending move and resize events
+ sendPendingMoveAndResizeEvents();
+
+ // become visible before showing all children
+ q->setAttribute(Qt::WA_WState_Visible);
+
+ // finally show all children recursively
+ showChildren(false);
+
+#ifdef QT3_SUPPORT
+ if (q->parentWidget() && sendChildEvents)
+ QApplication::sendPostedEvents(q->parentWidget(),
+ QEvent::ChildInserted);
+#endif
+
+
+ // popup handling: new popups and tools need to be raised, and
+ // existing popups must be closed. Also propagate the current
+ // windows's KeyboardFocusChange status.
+ if (q->isWindow()) {
+ if ((q->windowType() == Qt::Tool) || (q->windowType() == Qt::Popup) || q->windowType() == Qt::ToolTip) {
+ q->raise();
+ if (q->parentWidget() && q->parentWidget()->window()->testAttribute(Qt::WA_KeyboardFocusChange))
+ q->setAttribute(Qt::WA_KeyboardFocusChange);
+ } else {
+ while (QApplication::activePopupWidget()) {
+ if (!QApplication::activePopupWidget()->close())
+ break;
+ }
+ }
+ }
+
+ // Automatic embedding of child windows of widgets already embedded into
+ // QGraphicsProxyWidget when they are shown the first time.
+ bool isEmbedded = false;
+#ifndef QT_NO_GRAPHICSVIEW
+ if (q->isWindow()) {
+ isEmbedded = q->graphicsProxyWidget() ? true : false;
+ if (!isEmbedded && !bypassGraphicsProxyWidget(q)) {
+ QGraphicsProxyWidget *ancestorProxy = nearestGraphicsProxyWidget(q->parentWidget());
+ if (ancestorProxy) {
+ isEmbedded = true;
+ ancestorProxy->d_func()->embedSubWindow(q);
+ }
+ }
+ }
+#else
+ Q_UNUSED(isEmbedded);
+#endif
+
+ // On Windows, show the popup now so that our own focus handling
+ // stores the correct old focus widget even if it's stolen in the
+ // showevent
+#if defined(Q_WS_WIN) || defined(Q_WS_MAC) || defined(Q_OS_SYMBIAN)
+ if (!isEmbedded && q->windowType() == Qt::Popup)
+ qApp->d_func()->openPopup(q);
+#endif
+
+ // send the show event before showing the window
+ QShowEvent showEvent;
+ QApplication::sendEvent(q, &showEvent);
+
+ if (!isEmbedded && q->isModal() && q->isWindow())
+ // QApplicationPrivate::enterModal *before* show, otherwise the initial
+ // stacking might be wrong
+ QApplicationPrivate::enterModal(q);
+
+
+ show_sys();
+
+#if !defined(Q_WS_WIN) && !defined(Q_WS_MAC) && !defined(Q_OS_SYMBIAN)
+ if (!isEmbedded && q->windowType() == Qt::Popup)
+ qApp->d_func()->openPopup(q);
+#endif
+
+#ifndef QT_NO_ACCESSIBILITY
+ if (q->windowType() != Qt::ToolTip) // Tooltips are read aloud twice in MS narrator.
+ QAccessible::updateAccessibility(q, 0, QAccessible::ObjectShow);
+#endif
+
+ if (QApplicationPrivate::hidden_focus_widget == q) {
+ QApplicationPrivate::hidden_focus_widget = 0;
+ q->setFocus(Qt::OtherFocusReason);
+ }
+
+ // Process events when showing a Qt::SplashScreen widget before the event loop
+ // is spinnning; otherwise it might not show up on particular platforms.
+ // This makes QSplashScreen behave the same on all platforms.
+ if (!qApp->d_func()->in_exec && q->windowType() == Qt::SplashScreen)
+ QApplication::processEvents();
+
+ data.in_show = false; // reset qws optimization
+}
+
+/*! \fn void QWidget::hide()
+
+ Hides the widget. This function is equivalent to
+ setVisible(false).
+
+
+ \note If you are working with QDialog or its subclasses and you invoke
+ the show() function after this function, the dialog will be displayed in
+ its original position.
+
+ \sa hideEvent(), isHidden(), show(), setVisible(), isVisible(), close()
+*/
+
+/*!\internal
+ */
+void QWidgetPrivate::hide_helper()
+{
+ Q_Q(QWidget);
+
+ bool isEmbedded = false;
+#if !defined QT_NO_GRAPHICSVIEW
+ isEmbedded = q->isWindow() && !bypassGraphicsProxyWidget(q) && nearestGraphicsProxyWidget(q->parentWidget()) != 0;
+#else
+ Q_UNUSED(isEmbedded);
+#endif
+
+ if (!isEmbedded && (q->windowType() == Qt::Popup))
+ qApp->d_func()->closePopup(q);
+
+ // Move test modal here. Otherwise, a modal dialog could get
+ // destroyed and we lose all access to its parent because we haven't
+ // left modality. (Eg. modal Progress Dialog)
+ if (!isEmbedded && q->isModal() && q->isWindow())
+ QApplicationPrivate::leaveModal(q);
+
+#if defined(Q_WS_WIN)
+ if (q->isWindow() && !(q->windowType() == Qt::Popup) && q->parentWidget()
+ && !q->parentWidget()->isHidden() && q->isActiveWindow())
+ q->parentWidget()->activateWindow(); // Activate parent
+#endif
+
+ q->setAttribute(Qt::WA_Mapped, false);
+ hide_sys();
+
+ bool wasVisible = q->testAttribute(Qt::WA_WState_Visible);
+
+ if (wasVisible) {
+ q->setAttribute(Qt::WA_WState_Visible, false);
+
+ }
+
+ QHideEvent hideEvent;
+ QApplication::sendEvent(q, &hideEvent);
+ hideChildren(false);
+
+ // next bit tries to move the focus if the focus widget is now
+ // hidden.
+ if (wasVisible) {
+#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QPA)
+ qApp->d_func()->sendSyntheticEnterLeave(q);
+#endif
+
+ QWidget *fw = QApplication::focusWidget();
+ while (fw && !fw->isWindow()) {
+ if (fw == q) {
+ q->focusNextPrevChild(true);
+ break;
+ }
+ fw = fw->parentWidget();
+ }
+ }
+
+ if (QWidgetBackingStore *bs = maybeBackingStore())
+ bs->removeDirtyWidget(q);
+
+#ifndef QT_NO_ACCESSIBILITY
+ if (wasVisible)
+ QAccessible::updateAccessibility(q, 0, QAccessible::ObjectHide);
+#endif
+}
+
+/*!
+ \fn bool QWidget::isHidden() const
+
+ Returns true if the widget is hidden, otherwise returns false.
+
+ A hidden widget will only become visible when show() is called on
+ it. It will not be automatically shown when the parent is shown.
+
+ To check visibility, use !isVisible() instead (notice the exclamation mark).
+
+ isHidden() implies !isVisible(), but a widget can be not visible
+ and not hidden at the same time. This is the case for widgets that are children of
+ widgets that are not visible.
+
+
+ Widgets are hidden if:
+ \list
+ \o they were created as independent windows,
+ \o they were created as children of visible widgets,
+ \o hide() or setVisible(false) was called.
+ \endlist
+*/
+
+
+void QWidget::setVisible(bool visible)
+{
+ if (visible) { // show
+ if (testAttribute(Qt::WA_WState_ExplicitShowHide) && !testAttribute(Qt::WA_WState_Hidden))
+ return;
+
+ Q_D(QWidget);
+
+ // Designer uses a trick to make grabWidget work without showing
+ if (!isWindow() && parentWidget() && parentWidget()->isVisible()
+ && !parentWidget()->testAttribute(Qt::WA_WState_Created))
+ parentWidget()->window()->d_func()->createRecursively();
+
+ //we have to at least create toplevels before applyX11SpecificCommandLineArguments
+ //but not children of non-visible parents
+ QWidget *pw = parentWidget();
+ if (!testAttribute(Qt::WA_WState_Created)
+ && (isWindow() || pw->testAttribute(Qt::WA_WState_Created))) {
+ create();
+ }
+
+#if defined(Q_WS_X11)
+ if (windowType() == Qt::Window)
+ QApplicationPrivate::applyX11SpecificCommandLineArguments(this);
+#endif
+
+ bool wasResized = testAttribute(Qt::WA_Resized);
+ Qt::WindowStates initialWindowState = windowState();
+
+ // polish if necessary
+ ensurePolished();
+
+ // remember that show was called explicitly
+ setAttribute(Qt::WA_WState_ExplicitShowHide);
+ // whether we need to inform the parent widget immediately
+ bool needUpdateGeometry = !isWindow() && testAttribute(Qt::WA_WState_Hidden);
+ // we are no longer hidden
+ setAttribute(Qt::WA_WState_Hidden, false);
+
+ if (needUpdateGeometry)
+ d->updateGeometry_helper(true);
+
+#ifdef QT3_SUPPORT
+ QApplication::sendPostedEvents(this, QEvent::ChildInserted);
+#endif
+ // activate our layout before we and our children become visible
+ if (d->layout)
+ d->layout->activate();
+
+ if (!isWindow()) {
+ QWidget *parent = parentWidget();
+ while (parent && parent->isVisible() && parent->d_func()->layout && !parent->data->in_show) {
+ parent->d_func()->layout->activate();
+ if (parent->isWindow())
+ break;
+ parent = parent->parentWidget();
+ }
+ if (parent)
+ parent->d_func()->setDirtyOpaqueRegion();
+ }
+
+ // adjust size if necessary
+ if (!wasResized
+ && (isWindow() || !parentWidget()->d_func()->layout)) {
+ if (isWindow()) {
+ adjustSize();
+ if (windowState() != initialWindowState)
+ setWindowState(initialWindowState);
+ } else {
+ adjustSize();
+ }
+ setAttribute(Qt::WA_Resized, false);
+ }
+
+ setAttribute(Qt::WA_KeyboardFocusChange, false);
+
+ if (isWindow() || parentWidget()->isVisible()) {
+ // remove posted quit events when showing a new window
+ QCoreApplication::removePostedEvents(qApp, QEvent::Quit);
+
+ d->show_helper();
+
+#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QPA)
+ qApp->d_func()->sendSyntheticEnterLeave(this);
+#endif
+ }
+
+ QEvent showToParentEvent(QEvent::ShowToParent);
+ QApplication::sendEvent(this, &showToParentEvent);
+ } else { // hide
+ if (testAttribute(Qt::WA_WState_ExplicitShowHide) && testAttribute(Qt::WA_WState_Hidden))
+ return;
+#if defined(Q_WS_WIN)
+ // reset WS_DISABLED style in a Blocked window
+ if(isWindow() && testAttribute(Qt::WA_WState_Created)
+ && QApplicationPrivate::isBlockedByModal(this))
+ {
+ LONG dwStyle = GetWindowLong(winId(), GWL_STYLE);
+ dwStyle &= ~WS_DISABLED;
+ SetWindowLong(winId(), GWL_STYLE, dwStyle);
+ }
+#endif
+ if (QApplicationPrivate::hidden_focus_widget == this)
+ QApplicationPrivate::hidden_focus_widget = 0;
+
+ Q_D(QWidget);
+
+ // hw: The test on getOpaqueRegion() needs to be more intelligent
+ // currently it doesn't work if the widget is hidden (the region will
+ // be clipped). The real check should be testing the cached region
+ // (and dirty flag) directly.
+ if (!isWindow() && parentWidget()) // && !d->getOpaqueRegion().isEmpty())
+ parentWidget()->d_func()->setDirtyOpaqueRegion();
+
+ setAttribute(Qt::WA_WState_Hidden);
+ setAttribute(Qt::WA_WState_ExplicitShowHide);
+ if (testAttribute(Qt::WA_WState_Created))
+ d->hide_helper();
+
+ // invalidate layout similar to updateGeometry()
+ if (!isWindow() && parentWidget()) {
+ if (parentWidget()->d_func()->layout)
+ parentWidget()->d_func()->layout->invalidate();
+ else if (parentWidget()->isVisible())
+ QApplication::postEvent(parentWidget(), new QEvent(QEvent::LayoutRequest));
+ }
+
+ QEvent hideToParentEvent(QEvent::HideToParent);
+ QApplication::sendEvent(this, &hideToParentEvent);
+ }
+}
+
+/*!\fn void QWidget::setHidden(bool hidden)
+
+ Convenience function, equivalent to setVisible(!\a hidden).
+*/
+
+/*!\fn void QWidget::setShown(bool shown)
+
+ Use setVisible(\a shown) instead.
+*/
+
+
+void QWidgetPrivate::_q_showIfNotHidden()
+{
+ Q_Q(QWidget);
+ if ( !(q->isHidden() && q->testAttribute(Qt::WA_WState_ExplicitShowHide)) )
+ q->setVisible(true);
+}
+
+void QWidgetPrivate::showChildren(bool spontaneous)
+{
+ QList<QObject*> childList = children;
+ for (int i = 0; i < childList.size(); ++i) {
+ QWidget *widget = qobject_cast<QWidget*>(childList.at(i));
+ if (!widget
+ || widget->isWindow()
+ || widget->testAttribute(Qt::WA_WState_Hidden))
+ continue;
+ if (spontaneous) {
+ widget->setAttribute(Qt::WA_Mapped);
+ widget->d_func()->showChildren(true);
+ QShowEvent e;
+ QApplication::sendSpontaneousEvent(widget, &e);
+ } else {
+ if (widget->testAttribute(Qt::WA_WState_ExplicitShowHide))
+ widget->d_func()->show_recursive();
+ else
+ widget->show();
+ }
+ }
+}
+
+void QWidgetPrivate::hideChildren(bool spontaneous)
+{
+ QList<QObject*> childList = children;
+ for (int i = 0; i < childList.size(); ++i) {
+ QWidget *widget = qobject_cast<QWidget*>(childList.at(i));
+ if (!widget || widget->isWindow() || widget->testAttribute(Qt::WA_WState_Hidden))
+ continue;
+#ifdef QT_MAC_USE_COCOA
+ // Before doing anything we need to make sure that we don't leave anything in a non-consistent state.
+ // When hiding a widget we need to make sure that no mouse_down events are active, because
+ // the mouse_up event will never be received by a hidden widget or one of its descendants.
+ // The solution is simple, before going through with this we check if there are any mouse_down events in
+ // progress, if so we check if it is related to this widget or not. If so, we just reset the mouse_down and
+ // then we continue.
+ // In X11 and Windows we send a mouse_release event, however we don't do that here because we were already
+ // ignoring that from before. I.e. Carbon did not send the mouse release event, so we will not send the
+ // mouse release event. There are two ways to interpret this:
+ // 1. If we don't send the mouse release event, the widget might get into an inconsistent state, i.e. it
+ // might be waiting for a release event that will never arrive.
+ // 2. If we send the mouse release event, then the widget might decide to trigger an action that is not
+ // supposed to trigger because it is not visible.
+ if(widget == qt_button_down)
+ qt_button_down = 0;
+#endif // QT_MAC_USE_COCOA
+ if (spontaneous)
+ widget->setAttribute(Qt::WA_Mapped, false);
+ else
+ widget->setAttribute(Qt::WA_WState_Visible, false);
+ widget->d_func()->hideChildren(spontaneous);
+ QHideEvent e;
+ if (spontaneous) {
+ QApplication::sendSpontaneousEvent(widget, &e);
+ } else {
+ QApplication::sendEvent(widget, &e);
+ if (widget->internalWinId()
+ && widget->testAttribute(Qt::WA_DontCreateNativeAncestors)) {
+ // hide_sys() on an ancestor won't have any affect on this
+ // widget, so it needs an explicit hide_sys() of its own
+ widget->d_func()->hide_sys();
+ }
+ }
+#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QPA)
+ qApp->d_func()->sendSyntheticEnterLeave(widget);
+#endif
+#ifndef QT_NO_ACCESSIBILITY
+ if (!spontaneous)
+ QAccessible::updateAccessibility(widget, 0, QAccessible::ObjectHide);
+#endif
+ }
+}
+
+bool QWidgetPrivate::close_helper(CloseMode mode)
+{
+ if (data.is_closing)
+ return true;
+
+ Q_Q(QWidget);
+ data.is_closing = 1;
+
+ QPointer<QWidget> that = q;
+ QPointer<QWidget> parentWidget = q->parentWidget();
+
+#ifdef QT3_SUPPORT
+ bool isMain = (QApplicationPrivate::main_widget == q);
+#endif
+ bool quitOnClose = q->testAttribute(Qt::WA_QuitOnClose);
+ if (mode != CloseNoEvent) {
+ QCloseEvent e;
+ if (mode == CloseWithSpontaneousEvent)
+ QApplication::sendSpontaneousEvent(q, &e);
+ else
+ QApplication::sendEvent(q, &e);
+ if (!that.isNull() && !e.isAccepted()) {
+ data.is_closing = 0;
+ return false;
+ }
+ }
+
+ if (!that.isNull() && !q->isHidden())
+ q->hide();
+
+#ifdef QT3_SUPPORT
+ if (isMain)
+ QApplication::quit();
+#endif
+ // Attempt to close the application only if this has WA_QuitOnClose set and a non-visible parent
+ quitOnClose = quitOnClose && (parentWidget.isNull() || !parentWidget->isVisible());
+
+ if (quitOnClose) {
+ /* if there is no non-withdrawn primary window left (except
+ the ones without QuitOnClose), we emit the lastWindowClosed
+ signal */
+ QWidgetList list = QApplication::topLevelWidgets();
+ bool lastWindowClosed = true;
+ for (int i = 0; i < list.size(); ++i) {
+ QWidget *w = list.at(i);
+ if (!w->isVisible() || w->parentWidget() || !w->testAttribute(Qt::WA_QuitOnClose))
+ continue;
+ lastWindowClosed = false;
+ break;
+ }
+ if (lastWindowClosed)
+ QApplicationPrivate::emitLastWindowClosed();
+ }
+
+ if (!that.isNull()) {
+ data.is_closing = 0;
+ if (q->testAttribute(Qt::WA_DeleteOnClose)) {
+ q->setAttribute(Qt::WA_DeleteOnClose, false);
+ q->deleteLater();
+ }
+ }
+ return true;
+}
+
+
+/*!
+ Closes this widget. Returns true if the widget was closed;
+ otherwise returns false.
+
+ First it sends the widget a QCloseEvent. The widget is \link
+ hide() hidden\endlink if it \link QCloseEvent::accept()
+ accepts\endlink the close event. If it \link QCloseEvent::ignore()
+ ignores\endlink the event, nothing happens. The default
+ implementation of QWidget::closeEvent() accepts the close event.
+
+ If the widget has the Qt::WA_DeleteOnClose flag, the widget
+ is also deleted. A close events is delivered to the widget no
+ matter if the widget is visible or not.
+
+ The \l QApplication::lastWindowClosed() signal is emitted when the
+ last visible primary window (i.e. window with no parent) with the
+ Qt::WA_QuitOnClose attribute set is closed. By default this
+ attribute is set for all widgets except transient windows such as
+ splash screens, tool windows, and popup menus.
+
+*/
+
+bool QWidget::close()
+{
+ return d_func()->close_helper(QWidgetPrivate::CloseWithEvent);
+}
+
+/*!
+ \property QWidget::visible
+ \brief whether the widget is visible
+
+ Calling setVisible(true) or show() sets the widget to visible
+ status if all its parent widgets up to the window are visible. If
+ an ancestor is not visible, the widget won't become visible until
+ all its ancestors are shown. If its size or position has changed,
+ Qt guarantees that a widget gets move and resize events just
+ before it is shown. If the widget has not been resized yet, Qt
+ will adjust the widget's size to a useful default using
+ adjustSize().
+
+ Calling setVisible(false) or hide() hides a widget explicitly. An
+ explicitly hidden widget will never become visible, even if all
+ its ancestors become visible, unless you show it.
+
+ A widget receives show and hide events when its visibility status
+ changes. Between a hide and a show event, there is no need to
+ waste CPU cycles preparing or displaying information to the user.
+ A video application, for example, might simply stop generating new
+ frames.
+
+ A widget that happens to be obscured by other windows on the
+ screen is considered to be visible. The same applies to iconified
+ windows and windows that exist on another virtual
+ desktop (on platforms that support this concept). A widget
+ receives spontaneous show and hide events when its mapping status
+ is changed by the window system, e.g. a spontaneous hide event
+ when the user minimizes the window, and a spontaneous show event
+ when the window is restored again.
+
+ You almost never have to reimplement the setVisible() function. If
+ you need to change some settings before a widget is shown, use
+ showEvent() instead. If you need to do some delayed initialization
+ use the Polish event delivered to the event() function.
+
+ \sa show(), hide(), isHidden(), isVisibleTo(), isMinimized(),
+ showEvent(), hideEvent()
+*/
+
+
+/*!
+ Returns true if this widget would become visible if \a ancestor is
+ shown; otherwise returns false.
+
+ The true case occurs if neither the widget itself nor any parent
+ up to but excluding \a ancestor has been explicitly hidden.
+
+ This function will still return true if the widget is obscured by
+ other windows on the screen, but could be physically visible if it
+ or they were to be moved.
+
+ isVisibleTo(0) is identical to isVisible().
+
+ \sa show() hide() isVisible()
+*/
+
+bool QWidget::isVisibleTo(QWidget* ancestor) const
+{
+ if (!ancestor)
+ return isVisible();
+ const QWidget * w = this;
+ while (!w->isHidden()
+ && !w->isWindow()
+ && w->parentWidget()
+ && w->parentWidget() != ancestor)
+ w = w->parentWidget();
+ return !w->isHidden();
+}
+
+#ifdef QT3_SUPPORT
+/*!
+ Use visibleRegion() instead.
+*/
+QRect QWidget::visibleRect() const
+{
+ return d_func()->clipRect();
+}
+#endif
+
+/*!
+ Returns the unobscured region where paint events can occur.
+
+ For visible widgets, this is an approximation of the area not
+ covered by other widgets; otherwise, this is an empty region.
+
+ The repaint() function calls this function if necessary, so in
+ general you do not need to call it.
+
+*/
+QRegion QWidget::visibleRegion() const
+{
+ Q_D(const QWidget);
+
+ QRect clipRect = d->clipRect();
+ if (clipRect.isEmpty())
+ return QRegion();
+ QRegion r(clipRect);
+ d->subtractOpaqueChildren(r, clipRect);
+ d->subtractOpaqueSiblings(r);
+ return r;
+}
+
+
+QSize QWidgetPrivate::adjustedSize() const
+{
+ Q_Q(const QWidget);
+
+ QSize s = q->sizeHint();
+
+ if (q->isWindow()) {
+ Qt::Orientations exp;
+ if (layout) {
+ if (layout->hasHeightForWidth())
+ s.setHeight(layout->totalHeightForWidth(s.width()));
+ exp = layout->expandingDirections();
+ } else
+ {
+ if (q->sizePolicy().hasHeightForWidth())
+ s.setHeight(q->heightForWidth(s.width()));
+ exp = q->sizePolicy().expandingDirections();
+ }
+ if (exp & Qt::Horizontal)
+ s.setWidth(qMax(s.width(), 200));
+ if (exp & Qt::Vertical)
+ s.setHeight(qMax(s.height(), 100));
+#if defined(Q_WS_X11)
+ QRect screen = QApplication::desktop()->screenGeometry(q->x11Info().screen());
+#else // all others
+ QRect screen = QApplication::desktop()->screenGeometry(q->pos());
+#endif
+#if defined (Q_WS_WINCE) || defined (Q_OS_SYMBIAN)
+ s.setWidth(qMin(s.width(), screen.width()));
+ s.setHeight(qMin(s.height(), screen.height()));
+#else
+ s.setWidth(qMin(s.width(), screen.width()*2/3));
+ s.setHeight(qMin(s.height(), screen.height()*2/3));
+#endif
+ if (QTLWExtra *extra = maybeTopData())
+ extra->sizeAdjusted = true;
+ }
+
+ if (!s.isValid()) {
+ QRect r = q->childrenRect(); // get children rectangle
+ if (r.isNull())
+ return s;
+ s = r.size() + QSize(2 * r.x(), 2 * r.y());
+ }
+
+ return s;
+}
+
+/*!
+ Adjusts the size of the widget to fit its contents.
+
+ This function uses sizeHint() if it is valid, i.e., the size hint's width
+ and height are \>= 0. Otherwise, it sets the size to the children
+ rectangle that covers all child widgets (the union of all child widget
+ rectangles).
+
+ For windows, the screen size is also taken into account. If the sizeHint()
+ is less than (200, 100) and the size policy is \l{QSizePolicy::Expanding}
+ {expanding}, the window will be at least (200, 100). The maximum size of
+ a window is 2/3 of the screen's width and height.
+
+ \sa sizeHint(), childrenRect()
+*/
+
+void QWidget::adjustSize()
+{
+ Q_D(QWidget);
+ ensurePolished();
+ QSize s = d->adjustedSize();
+
+ if (d->layout)
+ d->layout->activate();
+
+ if (s.isValid())
+ resize(s);
+}
+
+
+/*!
+ \property QWidget::sizeHint
+ \brief the recommended size for the widget
+
+ If the value of this property is an invalid size, no size is
+ recommended.
+
+ The default implementation of sizeHint() returns an invalid size
+ if there is no layout for this widget, and returns the layout's
+ preferred size otherwise.
+
+ \sa QSize::isValid(), minimumSizeHint(), sizePolicy(),
+ setMinimumSize(), updateGeometry()
+*/
+
+QSize QWidget::sizeHint() const
+{
+ Q_D(const QWidget);
+ if (d->layout)
+ return d->layout->totalSizeHint();
+ return QSize(-1, -1);
+}
+
+/*!
+ \property QWidget::minimumSizeHint
+ \brief the recommended minimum size for the widget
+
+ If the value of this property is an invalid size, no minimum size
+ is recommended.
+
+ The default implementation of minimumSizeHint() returns an invalid
+ size if there is no layout for this widget, and returns the
+ layout's minimum size otherwise. Most built-in widgets reimplement
+ minimumSizeHint().
+
+ \l QLayout will never resize a widget to a size smaller than the
+ minimum size hint unless minimumSize() is set or the size policy is
+ set to QSizePolicy::Ignore. If minimumSize() is set, the minimum
+ size hint will be ignored.
+
+ \sa QSize::isValid(), resize(), setMinimumSize(), sizePolicy()
+*/
+QSize QWidget::minimumSizeHint() const
+{
+ Q_D(const QWidget);
+ if (d->layout)
+ return d->layout->totalMinimumSize();
+ return QSize(-1, -1);
+}
+
+
+/*!
+ \fn QWidget *QWidget::parentWidget() const
+
+ Returns the parent of this widget, or 0 if it does not have any
+ parent widget.
+*/
+
+
+/*!
+ Returns true if this widget is a parent, (or grandparent and so on
+ to any level), of the given \a child, and both widgets are within
+ the same window; otherwise returns false.
+*/
+
+bool QWidget::isAncestorOf(const QWidget *child) const
+{
+ while (child) {
+ if (child == this)
+ return true;
+ if (child->isWindow())
+ return false;
+ child = child->parentWidget();
+ }
+ return false;
+}
+
+#if defined(Q_WS_WIN)
+inline void setDisabledStyle(QWidget *w, bool setStyle)
+{
+ // set/reset WS_DISABLED style.
+ if(w && w->isWindow() && w->isVisible() && w->isEnabled()) {
+ LONG dwStyle = GetWindowLong(w->winId(), GWL_STYLE);
+ LONG newStyle = dwStyle;
+ if (setStyle)
+ newStyle |= WS_DISABLED;
+ else
+ newStyle &= ~WS_DISABLED;
+ if (newStyle != dwStyle) {
+ SetWindowLong(w->winId(), GWL_STYLE, newStyle);
+ // we might need to repaint in some situations (eg. menu)
+ w->repaint();
+ }
+ }
+}
+#endif
+
+/*****************************************************************************
+ QWidget event handling
+ *****************************************************************************/
+
+/*!
+ This is the main event handler; it handles event \a event. You can
+ reimplement this function in a subclass, but we recommend using
+ one of the specialized event handlers instead.
+
+ Key press and release events are treated differently from other
+ events. event() checks for Tab and Shift+Tab and tries to move the
+ focus appropriately. If there is no widget to move the focus to
+ (or the key press is not Tab or Shift+Tab), event() calls
+ keyPressEvent().
+
+ Mouse and tablet event handling is also slightly special: only
+ when the widget is \l enabled, event() will call the specialized
+ handlers such as mousePressEvent(); otherwise it will discard the
+ event.
+
+ This function returns true if the event was recognized, otherwise
+ it returns false. If the recognized event was accepted (see \l
+ QEvent::accepted), any further processing such as event
+ propagation to the parent widget stops.
+
+ \sa closeEvent(), focusInEvent(), focusOutEvent(), enterEvent(),
+ keyPressEvent(), keyReleaseEvent(), leaveEvent(),
+ mouseDoubleClickEvent(), mouseMoveEvent(), mousePressEvent(),
+ mouseReleaseEvent(), moveEvent(), paintEvent(), resizeEvent(),
+ QObject::event(), QObject::timerEvent()
+*/
+
+bool QWidget::event(QEvent *event)
+{
+ Q_D(QWidget);
+
+ // ignore mouse events when disabled
+ if (!isEnabled()) {
+ switch(event->type()) {
+ case QEvent::TabletPress:
+ case QEvent::TabletRelease:
+ case QEvent::TabletMove:
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseButtonDblClick:
+ case QEvent::MouseMove:
+ case QEvent::TouchBegin:
+ case QEvent::TouchUpdate:
+ case QEvent::TouchEnd:
+ case QEvent::ContextMenu:
+#ifndef QT_NO_WHEELEVENT
+ case QEvent::Wheel:
+#endif
+ return false;
+ default:
+ break;
+ }
+ }
+ switch (event->type()) {
+ case QEvent::MouseMove:
+ mouseMoveEvent((QMouseEvent*)event);
+ break;
+
+ case QEvent::MouseButtonPress:
+ // Don't reset input context here. Whether reset or not is
+ // a responsibility of input method. reset() will be
+ // called by mouseHandler() of input method if necessary
+ // via mousePressEvent() of text widgets.
+#if 0
+ resetInputContext();
+#endif
+ mousePressEvent((QMouseEvent*)event);
+ break;
+
+ case QEvent::MouseButtonRelease:
+ mouseReleaseEvent((QMouseEvent*)event);
+ break;
+
+ case QEvent::MouseButtonDblClick:
+ mouseDoubleClickEvent((QMouseEvent*)event);
+ break;
+#ifndef QT_NO_WHEELEVENT
+ case QEvent::Wheel:
+ wheelEvent((QWheelEvent*)event);
+ break;
+#endif
+#ifndef QT_NO_TABLETEVENT
+ case QEvent::TabletMove:
+ case QEvent::TabletPress:
+ case QEvent::TabletRelease:
+ tabletEvent((QTabletEvent*)event);
+ break;
+#endif
+#ifdef QT3_SUPPORT
+ case QEvent::Accel:
+ event->ignore();
+ return false;
+#endif
+ case QEvent::KeyPress: {
+ QKeyEvent *k = (QKeyEvent *)event;
+ bool res = false;
+ if (!(k->modifiers() & (Qt::ControlModifier | Qt::AltModifier))) { //### Add MetaModifier?
+ if (k->key() == Qt::Key_Backtab
+ || (k->key() == Qt::Key_Tab && (k->modifiers() & Qt::ShiftModifier)))
+ res = focusNextPrevChild(false);
+ else if (k->key() == Qt::Key_Tab)
+ res = focusNextPrevChild(true);
+ if (res)
+ break;
+ }
+ keyPressEvent(k);
+#ifdef QT_KEYPAD_NAVIGATION
+ if (!k->isAccepted() && QApplication::keypadNavigationEnabled()
+ && !(k->modifiers() & (Qt::ControlModifier | Qt::AltModifier | Qt::ShiftModifier))) {
+ if (QApplication::navigationMode() == Qt::NavigationModeKeypadTabOrder) {
+ if (k->key() == Qt::Key_Up)
+ res = focusNextPrevChild(false);
+ else if (k->key() == Qt::Key_Down)
+ res = focusNextPrevChild(true);
+ } else if (QApplication::navigationMode() == Qt::NavigationModeKeypadDirectional) {
+ if (k->key() == Qt::Key_Up)
+ res = QWidgetPrivate::navigateToDirection(QWidgetPrivate::DirectionNorth);
+ else if (k->key() == Qt::Key_Right)
+ res = QWidgetPrivate::navigateToDirection(QWidgetPrivate::DirectionEast);
+ else if (k->key() == Qt::Key_Down)
+ res = QWidgetPrivate::navigateToDirection(QWidgetPrivate::DirectionSouth);
+ else if (k->key() == Qt::Key_Left)
+ res = QWidgetPrivate::navigateToDirection(QWidgetPrivate::DirectionWest);
+ }
+ if (res) {
+ k->accept();
+ break;
+ }
+ }
+#endif
+#ifndef QT_NO_WHATSTHIS
+ if (!k->isAccepted()
+ && k->modifiers() & Qt::ShiftModifier && k->key() == Qt::Key_F1
+ && d->whatsThis.size()) {
+ QWhatsThis::showText(mapToGlobal(inputMethodQuery(Qt::ImCursorRectangle).toRect().center()), d->whatsThis, this);
+ k->accept();
+ }
+#endif
+ }
+ break;
+
+ case QEvent::KeyRelease:
+ keyReleaseEvent((QKeyEvent*)event);
+ // fall through
+ case QEvent::ShortcutOverride:
+ break;
+
+ case QEvent::InputMethod:
+ inputMethodEvent((QInputMethodEvent *) event);
+ break;
+
+ case QEvent::InputMethodQuery:
+ if (testAttribute(Qt::WA_InputMethodEnabled)) {
+ QInputMethodQueryEvent *query = static_cast<QInputMethodQueryEvent *>(event);
+ Qt::InputMethodQueries queries = query->queries();
+ for (uint i = 0; i < 32; ++i) {
+ Qt::InputMethodQuery q = (Qt::InputMethodQuery)(int)(queries & (1<<i));
+ if (q) {
+ QVariant v = inputMethodQuery(q);
+ query->setValue(q, v);
+ }
+ }
+ query->accept();
+ break;
+ }
+
+ case QEvent::PolishRequest:
+ ensurePolished();
+ break;
+
+ case QEvent::Polish: {
+ style()->polish(this);
+ setAttribute(Qt::WA_WState_Polished);
+ if (!QApplication::font(this).isCopyOf(QApplication::font()))
+ d->resolveFont();
+ if (!QApplication::palette(this).isCopyOf(QApplication::palette()))
+ d->resolvePalette();
+#ifdef QT3_SUPPORT
+ if(d->sendChildEvents)
+ QApplication::sendPostedEvents(this, QEvent::ChildInserted);
+#endif
+ }
+ break;
+
+ case QEvent::ApplicationWindowIconChange:
+ if (isWindow() && !testAttribute(Qt::WA_SetWindowIcon)) {
+ d->setWindowIcon_sys();
+ d->setWindowIcon_helper();
+ }
+ break;
+ case QEvent::FocusIn:
+#ifdef QT_SOFTKEYS_ENABLED
+ QSoftKeyManager::updateSoftKeys();
+#endif
+ focusInEvent((QFocusEvent*)event);
+ d->updateWidgetTransform();
+ break;
+
+ case QEvent::FocusOut:
+ focusOutEvent((QFocusEvent*)event);
+ break;
+
+ case QEvent::Enter:
+#ifndef QT_NO_STATUSTIP
+ if (d->statusTip.size()) {
+ QStatusTipEvent tip(d->statusTip);
+ QApplication::sendEvent(const_cast<QWidget *>(this), &tip);
+ }
+#endif
+ enterEvent(event);
+ break;
+
+ case QEvent::Leave:
+#ifndef QT_NO_STATUSTIP
+ if (d->statusTip.size()) {
+ QString empty;
+ QStatusTipEvent tip(empty);
+ QApplication::sendEvent(const_cast<QWidget *>(this), &tip);
+ }
+#endif
+ leaveEvent(event);
+ break;
+
+ case QEvent::HoverEnter:
+ case QEvent::HoverLeave:
+ update();
+ break;
+
+ case QEvent::Paint:
+ // At this point the event has to be delivered, regardless
+ // whether the widget isVisible() or not because it
+ // already went through the filters
+ paintEvent((QPaintEvent*)event);
+ break;
+
+ case QEvent::Move:
+ moveEvent((QMoveEvent*)event);
+ d->updateWidgetTransform();
+ break;
+
+ case QEvent::Resize:
+ resizeEvent((QResizeEvent*)event);
+ d->updateWidgetTransform();
+ break;
+
+ case QEvent::Close:
+ closeEvent((QCloseEvent *)event);
+ break;
+
+#ifndef QT_NO_CONTEXTMENU
+ case QEvent::ContextMenu:
+ switch (data->context_menu_policy) {
+ case Qt::PreventContextMenu:
+ break;
+ case Qt::DefaultContextMenu:
+ contextMenuEvent(static_cast<QContextMenuEvent *>(event));
+ break;
+ case Qt::CustomContextMenu:
+ emit customContextMenuRequested(static_cast<QContextMenuEvent *>(event)->pos());
+ break;
+#ifndef QT_NO_MENU
+ case Qt::ActionsContextMenu:
+ if (d->actions.count()) {
+ QMenu::exec(d->actions, static_cast<QContextMenuEvent *>(event)->globalPos(),
+ 0, this);
+ break;
+ }
+ // fall through
+#endif
+ default:
+ event->ignore();
+ break;
+ }
+ break;
+#endif // QT_NO_CONTEXTMENU
+
+#ifndef QT_NO_DRAGANDDROP
+ case QEvent::Drop:
+ dropEvent((QDropEvent*) event);
+ break;
+
+ case QEvent::DragEnter:
+ dragEnterEvent((QDragEnterEvent*) event);
+ break;
+
+ case QEvent::DragMove:
+ dragMoveEvent((QDragMoveEvent*) event);
+ break;
+
+ case QEvent::DragLeave:
+ dragLeaveEvent((QDragLeaveEvent*) event);
+ break;
+#endif
+
+ case QEvent::Show:
+ showEvent((QShowEvent*) event);
+ break;
+
+ case QEvent::Hide:
+ hideEvent((QHideEvent*) event);
+ break;
+
+ case QEvent::ShowWindowRequest:
+ if (!isHidden())
+ d->show_sys();
+ break;
+
+ case QEvent::ApplicationFontChange:
+ d->resolveFont();
+ break;
+ case QEvent::ApplicationPaletteChange:
+ if (!(windowType() == Qt::Desktop))
+ d->resolvePalette();
+ break;
+
+ case QEvent::ToolBarChange:
+ case QEvent::ActivationChange:
+ case QEvent::EnabledChange:
+ case QEvent::FontChange:
+ case QEvent::StyleChange:
+ case QEvent::PaletteChange:
+ case QEvent::WindowTitleChange:
+ case QEvent::IconTextChange:
+ case QEvent::ModifiedChange:
+ case QEvent::MouseTrackingChange:
+ case QEvent::ParentChange:
+ case QEvent::WindowStateChange:
+ case QEvent::LocaleChange:
+ case QEvent::MacSizeChange:
+ case QEvent::ContentsRectChange:
+ changeEvent(event);
+ break;
+
+ case QEvent::WindowActivate:
+ case QEvent::WindowDeactivate: {
+#ifdef QT3_SUPPORT
+ windowActivationChange(event->type() != QEvent::WindowActivate);
+#endif
+ if (isVisible() && !palette().isEqual(QPalette::Active, QPalette::Inactive))
+ update();
+ QList<QObject*> childList = d->children;
+ for (int i = 0; i < childList.size(); ++i) {
+ QWidget *w = qobject_cast<QWidget *>(childList.at(i));
+ if (w && w->isVisible() && !w->isWindow())
+ QApplication::sendEvent(w, event);
+ }
+
+#ifdef QT_SOFTKEYS_ENABLED
+ if (isWindow())
+ QSoftKeyManager::updateSoftKeys();
+#endif
+
+ break; }
+
+ case QEvent::LanguageChange:
+#ifdef QT3_SUPPORT
+ languageChange();
+#endif
+ changeEvent(event);
+ {
+ QList<QObject*> childList = d->children;
+ for (int i = 0; i < childList.size(); ++i) {
+ QObject *o = childList.at(i);
+ if (o)
+ QApplication::sendEvent(o, event);
+ }
+ }
+ update();
+ break;
+
+ case QEvent::ApplicationLayoutDirectionChange:
+ d->resolveLayoutDirection();
+ break;
+
+ case QEvent::LayoutDirectionChange:
+ if (d->layout)
+ d->layout->invalidate();
+ update();
+ changeEvent(event);
+ break;
+ case QEvent::UpdateRequest:
+ d->syncBackingStore();
+ break;
+ case QEvent::UpdateLater:
+ update(static_cast<QUpdateLaterEvent*>(event)->region());
+ break;
+
+ case QEvent::WindowBlocked:
+ case QEvent::WindowUnblocked:
+ {
+ QList<QObject*> childList = d->children;
+ for (int i = 0; i < childList.size(); ++i) {
+ QObject *o = childList.at(i);
+ if (o && o != QApplication::activeModalWidget()) {
+ if (qobject_cast<QWidget *>(o) && static_cast<QWidget *>(o)->isWindow()) {
+ // do not forward the event to child windows,
+ // QApplication does this for us
+ continue;
+ }
+ QApplication::sendEvent(o, event);
+ }
+ }
+#if defined(Q_WS_WIN)
+ setDisabledStyle(this, (event->type() == QEvent::WindowBlocked));
+#endif
+ }
+ break;
+#ifndef QT_NO_TOOLTIP
+ case QEvent::ToolTip:
+ if (!d->toolTip.isEmpty())
+ QToolTip::showText(static_cast<QHelpEvent*>(event)->globalPos(), d->toolTip, this);
+ else
+ event->ignore();
+ break;
+#endif
+#ifndef QT_NO_WHATSTHIS
+ case QEvent::WhatsThis:
+ if (d->whatsThis.size())
+ QWhatsThis::showText(static_cast<QHelpEvent *>(event)->globalPos(), d->whatsThis, this);
+ else
+ event->ignore();
+ break;
+ case QEvent::QueryWhatsThis:
+ if (d->whatsThis.isEmpty())
+ event->ignore();
+ break;
+#endif
+#ifndef QT_NO_ACCESSIBILITY
+ case QEvent::AccessibilityDescription:
+ case QEvent::AccessibilityHelp: {
+ QAccessibleEvent *ev = static_cast<QAccessibleEvent *>(event);
+ if (ev->child())
+ return false;
+ switch (ev->type()) {
+#ifndef QT_NO_TOOLTIP
+ case QEvent::AccessibilityDescription:
+ ev->setValue(d->toolTip);
+ break;
+#endif
+#ifndef QT_NO_WHATSTHIS
+ case QEvent::AccessibilityHelp:
+ ev->setValue(d->whatsThis);
+ break;
+#endif
+ default:
+ return false;
+ }
+ break; }
+#endif
+ case QEvent::EmbeddingControl:
+ d->topData()->frameStrut.setCoords(0 ,0, 0, 0);
+ data->fstrut_dirty = false;
+#if defined(Q_WS_WIN) || defined(Q_WS_X11)
+ d->topData()->embedded = 1;
+#endif
+ break;
+#ifndef QT_NO_ACTION
+ case QEvent::ActionAdded:
+ case QEvent::ActionRemoved:
+ case QEvent::ActionChanged:
+#ifdef QT_SOFTKEYS_ENABLED
+ QSoftKeyManager::updateSoftKeys();
+#endif
+ actionEvent((QActionEvent*)event);
+ break;
+#endif
+
+ case QEvent::KeyboardLayoutChange:
+ {
+ changeEvent(event);
+
+ // inform children of the change
+ QList<QObject*> childList = d->children;
+ for (int i = 0; i < childList.size(); ++i) {
+ QWidget *w = qobject_cast<QWidget *>(childList.at(i));
+ if (w && w->isVisible() && !w->isWindow())
+ QApplication::sendEvent(w, event);
+ }
+ break;
+ }
+#ifdef Q_WS_MAC
+ case QEvent::MacGLWindowChange:
+ d->needWindowChange = false;
+ break;
+#endif
+ case QEvent::TouchBegin:
+ case QEvent::TouchUpdate:
+ case QEvent::TouchEnd:
+ {
+#ifndef Q_WS_MAC
+ QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event);
+ const QTouchEvent::TouchPoint &touchPoint = touchEvent->touchPoints().first();
+ if (touchPoint.isPrimary() || touchEvent->deviceType() == QTouchEvent::TouchPad)
+ break;
+
+ // fake a mouse event!
+ QEvent::Type eventType = QEvent::None;
+ switch (touchEvent->type()) {
+ case QEvent::TouchBegin:
+ eventType = QEvent::MouseButtonPress;
+ break;
+ case QEvent::TouchUpdate:
+ eventType = QEvent::MouseMove;
+ break;
+ case QEvent::TouchEnd:
+ eventType = QEvent::MouseButtonRelease;
+ break;
+ default:
+ Q_ASSERT(!true);
+ break;
+ }
+ if (eventType == QEvent::None)
+ break;
+
+ QMouseEvent mouseEvent(eventType,
+ touchPoint.pos(),
+ touchPoint.scenePos(),
+ touchPoint.screenPos(),
+ Qt::LeftButton,
+ Qt::LeftButton,
+ touchEvent->modifiers());
+ (void) QApplication::sendEvent(this, &mouseEvent);
+#endif // Q_WS_MAC
+ break;
+ }
+#ifndef QT_NO_GESTURES
+ case QEvent::Gesture:
+ event->ignore();
+ break;
+#endif
+#ifndef QT_NO_PROPERTIES
+ case QEvent::DynamicPropertyChange: {
+ const QByteArray &propName = static_cast<QDynamicPropertyChangeEvent *>(event)->propertyName();
+ if (!qstrncmp(propName, "_q_customDpi", 12) && propName.length() == 13) {
+ uint value = property(propName.constData()).toUInt();
+ if (!d->extra)
+ d->createExtra();
+ const char axis = propName.at(12);
+ if (axis == 'X')
+ d->extra->customDpiX = value;
+ else if (axis == 'Y')
+ d->extra->customDpiY = value;
+ d->updateFont(d->data.fnt);
+ }
+ // fall through
+ }
+#endif
+ default:
+ return QObject::event(event);
+ }
+ return true;
+}
+
+/*!
+ This event handler can be reimplemented to handle state changes.
+
+ The state being changed in this event can be retrieved through the \a event
+ supplied.
+
+ Change events include: QEvent::ToolBarChange,
+ QEvent::ActivationChange, QEvent::EnabledChange, QEvent::FontChange,
+ QEvent::StyleChange, QEvent::PaletteChange,
+ QEvent::WindowTitleChange, QEvent::IconTextChange,
+ QEvent::ModifiedChange, QEvent::MouseTrackingChange,
+ QEvent::ParentChange, QEvent::WindowStateChange,
+ QEvent::LanguageChange, QEvent::LocaleChange,
+ QEvent::LayoutDirectionChange.
+
+*/
+void QWidget::changeEvent(QEvent * event)
+{
+ switch(event->type()) {
+ case QEvent::EnabledChange:
+ update();
+#ifndef QT_NO_ACCESSIBILITY
+ QAccessible::updateAccessibility(this, 0, QAccessible::StateChanged);
+#endif
+ break;
+
+ case QEvent::FontChange:
+ case QEvent::StyleChange: {
+ Q_D(QWidget);
+ update();
+ updateGeometry();
+ if (d->layout)
+ d->layout->invalidate();
+ break;
+ }
+
+ case QEvent::PaletteChange:
+ update();
+ break;
+
+#ifdef Q_WS_MAC
+ case QEvent::MacSizeChange:
+ updateGeometry();
+ break;
+ case QEvent::ToolTipChange:
+ case QEvent::MouseTrackingChange:
+ qt_mac_update_mouseTracking(this);
+ break;
+#endif
+
+ default:
+ break;
+ }
+}
+
+/*!
+ This event handler, for event \a event, can be reimplemented in a
+ subclass to receive mouse move events for the widget.
+
+ If mouse tracking is switched off, mouse move events only occur if
+ a mouse button is pressed while the mouse is being moved. If mouse
+ tracking is switched on, mouse move events occur even if no mouse
+ button is pressed.
+
+ QMouseEvent::pos() reports the position of the mouse cursor,
+ relative to this widget. For press and release events, the
+ position is usually the same as the position of the last mouse
+ move event, but it might be different if the user's hand shakes.
+ This is a feature of the underlying window system, not Qt.
+
+ If you want to show a tooltip immediately, while the mouse is
+ moving (e.g., to get the mouse coordinates with QMouseEvent::pos()
+ and show them as a tooltip), you must first enable mouse tracking
+ as described above. Then, to ensure that the tooltip is updated
+ immediately, you must call QToolTip::showText() instead of
+ setToolTip() in your implementation of mouseMoveEvent().
+
+ \sa setMouseTracking(), mousePressEvent(), mouseReleaseEvent(),
+ mouseDoubleClickEvent(), event(), QMouseEvent, {Scribble Example}
+*/
+
+void QWidget::mouseMoveEvent(QMouseEvent *event)
+{
+ event->ignore();
+}
+
+/*!
+ This event handler, for event \a event, can be reimplemented in a
+ subclass to receive mouse press events for the widget.
+
+ If you create new widgets in the mousePressEvent() the
+ mouseReleaseEvent() may not end up where you expect, depending on
+ the underlying window system (or X11 window manager), the widgets'
+ location and maybe more.
+
+ The default implementation implements the closing of popup widgets
+ when you click outside the window. For other widget types it does
+ nothing.
+
+ \sa mouseReleaseEvent(), mouseDoubleClickEvent(),
+ mouseMoveEvent(), event(), QMouseEvent, {Scribble Example}
+*/
+
+void QWidget::mousePressEvent(QMouseEvent *event)
+{
+ event->ignore();
+ if ((windowType() == Qt::Popup)) {
+ event->accept();
+ QWidget* w;
+ while ((w = QApplication::activePopupWidget()) && w != this){
+ w->close();
+ if (QApplication::activePopupWidget() == w) // widget does not want to disappear
+ w->hide(); // hide at least
+ }
+ if (!rect().contains(event->pos())){
+ close();
+ }
+ }
+}
+
+/*!
+ This event handler, for event \a event, can be reimplemented in a
+ subclass to receive mouse release events for the widget.
+
+ \sa mousePressEvent(), mouseDoubleClickEvent(),
+ mouseMoveEvent(), event(), QMouseEvent, {Scribble Example}
+*/
+
+void QWidget::mouseReleaseEvent(QMouseEvent *event)
+{
+ event->ignore();
+}
+
+/*!
+ This event handler, for event \a event, can be reimplemented in a
+ subclass to receive mouse double click events for the widget.
+
+ The default implementation generates a normal mouse press event.
+
+ \note The widget will also receive mouse press and mouse release
+ events in addition to the double click event. It is up to the
+ developer to ensure that the application interprets these events
+ correctly.
+
+ \sa mousePressEvent(), mouseReleaseEvent() mouseMoveEvent(),
+ event(), QMouseEvent
+*/
+
+void QWidget::mouseDoubleClickEvent(QMouseEvent *event)
+{
+ mousePressEvent(event); // try mouse press event
+}
+
+#ifndef QT_NO_WHEELEVENT
+/*!
+ This event handler, for event \a event, can be reimplemented in a
+ subclass to receive wheel events for the widget.
+
+ If you reimplement this handler, it is very important that you
+ \link QWheelEvent ignore()\endlink the event if you do not handle
+ it, so that the widget's parent can interpret it.
+
+ The default implementation ignores the event.
+
+ \sa QWheelEvent::ignore(), QWheelEvent::accept(), event(),
+ QWheelEvent
+*/
+
+void QWidget::wheelEvent(QWheelEvent *event)
+{
+ event->ignore();
+}
+#endif // QT_NO_WHEELEVENT
+
+#ifndef QT_NO_TABLETEVENT
+/*!
+ This event handler, for event \a event, can be reimplemented in a
+ subclass to receive tablet events for the widget.
+
+ If you reimplement this handler, it is very important that you
+ \link QTabletEvent ignore()\endlink the event if you do not handle
+ it, so that the widget's parent can interpret it.
+
+ The default implementation ignores the event.
+
+ \sa QTabletEvent::ignore(), QTabletEvent::accept(), event(),
+ QTabletEvent
+*/
+
+void QWidget::tabletEvent(QTabletEvent *event)
+{
+ event->ignore();
+}
+#endif // QT_NO_TABLETEVENT
+
+/*!
+ This event handler, for event \a event, can be reimplemented in a
+ subclass to receive key press events for the widget.
+
+ A widget must call setFocusPolicy() to accept focus initially and
+ have focus in order to receive a key press event.
+
+ If you reimplement this handler, it is very important that you
+ call the base class implementation if you do not act upon the key.
+
+ The default implementation closes popup widgets if the user
+ presses Esc. Otherwise the event is ignored, so that the widget's
+ parent can interpret it.
+
+ Note that QKeyEvent starts with isAccepted() == true, so you do not
+ need to call QKeyEvent::accept() - just do not call the base class
+ implementation if you act upon the key.
+
+ \sa keyReleaseEvent(), setFocusPolicy(),
+ focusInEvent(), focusOutEvent(), event(), QKeyEvent, {Tetrix Example}
+*/
+
+void QWidget::keyPressEvent(QKeyEvent *event)
+{
+ if ((windowType() == Qt::Popup) && event->key() == Qt::Key_Escape) {
+ event->accept();
+ close();
+ } else {
+ event->ignore();
+ }
+}
+
+/*!
+ This event handler, for event \a event, can be reimplemented in a
+ subclass to receive key release events for the widget.
+
+ A widget must \link setFocusPolicy() accept focus\endlink
+ initially and \link hasFocus() have focus\endlink in order to
+ receive a key release event.
+
+ If you reimplement this handler, it is very important that you
+ call the base class implementation if you do not act upon the key.
+
+ The default implementation ignores the event, so that the widget's
+ parent can interpret it.
+
+ Note that QKeyEvent starts with isAccepted() == true, so you do not
+ need to call QKeyEvent::accept() - just do not call the base class
+ implementation if you act upon the key.
+
+ \sa keyPressEvent(), QKeyEvent::ignore(), setFocusPolicy(),
+ focusInEvent(), focusOutEvent(), event(), QKeyEvent
+*/
+
+void QWidget::keyReleaseEvent(QKeyEvent *event)
+{
+ event->ignore();
+}
+
+/*!
+ \fn void QWidget::focusInEvent(QFocusEvent *event)
+
+ This event handler can be reimplemented in a subclass to receive
+ keyboard focus events (focus received) for the widget. The event
+ is passed in the \a event parameter
+
+ A widget normally must setFocusPolicy() to something other than
+ Qt::NoFocus in order to receive focus events. (Note that the
+ application programmer can call setFocus() on any widget, even
+ those that do not normally accept focus.)
+
+ The default implementation updates the widget (except for windows
+ that do not specify a focusPolicy()).
+
+ \sa focusOutEvent(), setFocusPolicy(), keyPressEvent(),
+ keyReleaseEvent(), event(), QFocusEvent
+*/
+
+void QWidget::focusInEvent(QFocusEvent *)
+{
+ if (focusPolicy() != Qt::NoFocus || !isWindow()) {
+ update();
+ }
+}
+
+/*!
+ \fn void QWidget::focusOutEvent(QFocusEvent *event)
+
+ This event handler can be reimplemented in a subclass to receive
+ keyboard focus events (focus lost) for the widget. The events is
+ passed in the \a event parameter.
+
+ A widget normally must setFocusPolicy() to something other than
+ Qt::NoFocus in order to receive focus events. (Note that the
+ application programmer can call setFocus() on any widget, even
+ those that do not normally accept focus.)
+
+ The default implementation updates the widget (except for windows
+ that do not specify a focusPolicy()).
+
+ \sa focusInEvent(), setFocusPolicy(), keyPressEvent(),
+ keyReleaseEvent(), event(), QFocusEvent
+*/
+
+void QWidget::focusOutEvent(QFocusEvent *)
+{
+ if (focusPolicy() != Qt::NoFocus || !isWindow())
+ update();
+}
+
+/*!
+ \fn void QWidget::enterEvent(QEvent *event)
+
+ This event handler can be reimplemented in a subclass to receive
+ widget enter events which are passed in the \a event parameter.
+
+ An event is sent to the widget when the mouse cursor enters the
+ widget.
+
+ \sa leaveEvent(), mouseMoveEvent(), event()
+*/
+
+void QWidget::enterEvent(QEvent *)
+{
+}
+
+/*!
+ \fn void QWidget::leaveEvent(QEvent *event)
+
+ This event handler can be reimplemented in a subclass to receive
+ widget leave events which are passed in the \a event parameter.
+
+ A leave event is sent to the widget when the mouse cursor leaves
+ the widget.
+
+ \sa enterEvent(), mouseMoveEvent(), event()
+*/
+
+void QWidget::leaveEvent(QEvent *)
+{
+}
+
+/*!
+ \fn void QWidget::paintEvent(QPaintEvent *event)
+
+ This event handler can be reimplemented in a subclass to receive paint
+ events passed in \a event.
+
+ A paint event is a request to repaint all or part of a widget. It can
+ happen for one of the following reasons:
+
+ \list
+ \o repaint() or update() was invoked,
+ \o the widget was obscured and has now been uncovered, or
+ \o many other reasons.
+ \endlist
+
+ Many widgets can simply repaint their entire surface when asked to, but
+ some slow widgets need to optimize by painting only the requested region:
+ QPaintEvent::region(). This speed optimization does not change the result,
+ as painting is clipped to that region during event processing. QListView
+ and QTableView do this, for example.
+
+ Qt also tries to speed up painting by merging multiple paint events into
+ one. When update() is called several times or the window system sends
+ several paint events, Qt merges these events into one event with a larger
+ region (see QRegion::united()). The repaint() function does not permit this
+ optimization, so we suggest using update() whenever possible.
+
+ When the paint event occurs, the update region has normally been erased, so
+ you are painting on the widget's background.
+
+ The background can be set using setBackgroundRole() and setPalette().
+
+ Since Qt 4.0, QWidget automatically double-buffers its painting, so there
+ is no need to write double-buffering code in paintEvent() to avoid flicker.
+
+ \bold{Note for the X11 platform}: It is possible to toggle global double
+ buffering by calling \c qt_x11_set_global_double_buffer(). For example,
+
+ \snippet doc/src/snippets/code/src_gui_kernel_qwidget.cpp 14
+
+ \note Generally, you should refrain from calling update() or repaint()
+ \bold{inside} a paintEvent(). For example, calling update() or repaint() on
+ children inside a paintevent() results in undefined behavior; the child may
+ or may not get a paint event.
+
+ \warning If you are using a custom paint engine without Qt's backingstore,
+ Qt::WA_PaintOnScreen must be set. Otherwise, QWidget::paintEngine() will
+ never be called; the backingstore will be used instead.
+
+ \sa event(), repaint(), update(), QPainter, QPixmap, QPaintEvent,
+ {Analog Clock Example}
+*/
+
+void QWidget::paintEvent(QPaintEvent *)
+{
+}
+
+
+/*!
+ \fn void QWidget::moveEvent(QMoveEvent *event)
+
+ This event handler can be reimplemented in a subclass to receive
+ widget move events which are passed in the \a event parameter.
+ When the widget receives this event, it is already at the new
+ position.
+
+ The old position is accessible through QMoveEvent::oldPos().
+
+ \sa resizeEvent(), event(), move(), QMoveEvent
+*/
+
+void QWidget::moveEvent(QMoveEvent *)
+{
+}
+
+
+/*!
+ This event handler can be reimplemented in a subclass to receive
+ widget resize events which are passed in the \a event parameter.
+ When resizeEvent() is called, the widget already has its new
+ geometry. The old size is accessible through
+ QResizeEvent::oldSize().
+
+ The widget will be erased and receive a paint event immediately
+ after processing the resize event. No drawing need be (or should
+ be) done inside this handler.
+
+
+ \sa moveEvent(), event(), resize(), QResizeEvent, paintEvent(),
+ {Scribble Example}
+*/
+
+void QWidget::resizeEvent(QResizeEvent * /* event */)
+{
+}
+
+#ifndef QT_NO_ACTION
+/*!
+ \fn void QWidget::actionEvent(QActionEvent *event)
+
+ This event handler is called with the given \a event whenever the
+ widget's actions are changed.
+
+ \sa addAction(), insertAction(), removeAction(), actions(), QActionEvent
+*/
+void QWidget::actionEvent(QActionEvent *)
+{
+
+}
+#endif
+
+/*!
+ This event handler is called with the given \a event when Qt receives a window
+ close request for a top-level widget from the window system.
+
+ By default, the event is accepted and the widget is closed. You can reimplement
+ this function to change the way the widget responds to window close requests.
+ For example, you can prevent the window from closing by calling \l{QEvent::}{ignore()}
+ on all events.
+
+ Main window applications typically use reimplementations of this function to check
+ whether the user's work has been saved and ask for permission before closing.
+ For example, the \l{Application Example} uses a helper function to determine whether
+ or not to close the window:
+
+ \snippet mainwindows/application/mainwindow.cpp 3
+ \snippet mainwindows/application/mainwindow.cpp 4
+
+ \sa event(), hide(), close(), QCloseEvent, {Application Example}
+*/
+
+void QWidget::closeEvent(QCloseEvent *event)
+{
+ event->accept();
+}
+
+#ifndef QT_NO_CONTEXTMENU
+/*!
+ This event handler, for event \a event, can be reimplemented in a
+ subclass to receive widget context menu events.
+
+ The handler is called when the widget's \l contextMenuPolicy is
+ Qt::DefaultContextMenu.
+
+ The default implementation ignores the context event.
+ See the \l QContextMenuEvent documentation for more details.
+
+ \sa event(), QContextMenuEvent customContextMenuRequested()
+*/
+
+void QWidget::contextMenuEvent(QContextMenuEvent *event)
+{
+ event->ignore();
+}
+#endif // QT_NO_CONTEXTMENU
+
+
+/*!
+ This event handler, for event \a event, can be reimplemented in a
+ subclass to receive Input Method composition events. This handler
+ is called when the state of the input method changes.
+
+ Note that when creating custom text editing widgets, the
+ Qt::WA_InputMethodEnabled window attribute must be set explicitly
+ (using the setAttribute() function) in order to receive input
+ method events.
+
+ The default implementation calls event->ignore(), which rejects the
+ Input Method event. See the \l QInputMethodEvent documentation for more
+ details.
+
+ \sa event(), QInputMethodEvent
+*/
+void QWidget::inputMethodEvent(QInputMethodEvent *event)
+{
+ event->ignore();
+}
+
+/*!
+ This method is only relevant for input widgets. It is used by the
+ input method to query a set of properties of the widget to be
+ able to support complex input method operations as support for
+ surrounding text and reconversions.
+
+ \a query specifies which property is queried.
+
+ \sa inputMethodEvent(), QInputMethodEvent, QInputContext, inputMethodHints
+*/
+QVariant QWidget::inputMethodQuery(Qt::InputMethodQuery query) const
+{
+ switch(query) {
+ case Qt::ImCursorRectangle:
+ return QRect(width()/2, 0, 1, height());
+ case Qt::ImFont:
+ return font();
+ case Qt::ImAnchorPosition:
+ // Fallback.
+ return inputMethodQuery(Qt::ImCursorPosition);
+ case Qt::ImHints:
+ return (int)inputMethodHints();
+ default:
+ return QVariant();
+ }
+}
+
+/*!
+ \property QWidget::inputMethodHints
+ \brief What input method specific hints the widget has.
+
+ This is only relevant for input widgets. It is used by
+ the input method to retrieve hints as to how the input method
+ should operate. For example, if the Qt::ImhFormattedNumbersOnly flag
+ is set, the input method may change its visual components to reflect
+ that only numbers can be entered.
+
+ \note The flags are only hints, so the particular input method
+ implementation is free to ignore them. If you want to be
+ sure that a certain type of characters are entered,
+ you should also set a QValidator on the widget.
+
+ The default value is Qt::ImhNone.
+
+ \since 4.6
+
+ \sa inputMethodQuery(), QInputContext
+*/
+Qt::InputMethodHints QWidget::inputMethodHints() const
+{
+#ifndef QT_NO_IM
+ const QWidgetPrivate *priv = d_func();
+ while (priv->inheritsInputMethodHints) {
+ priv = priv->q_func()->parentWidget()->d_func();
+ Q_ASSERT(priv);
+ }
+ return priv->imHints;
+#else //QT_NO_IM
+ return 0;
+#endif //QT_NO_IM
+}
+
+void QWidget::setInputMethodHints(Qt::InputMethodHints hints)
+{
+#ifndef QT_NO_IM
+ Q_D(QWidget);
+ d->imHints = hints;
+ // Optimization to update input context only it has already been created.
+ if (d->ic || qApp->d_func()->inputContext) {
+ QInputContext *ic = inputContext();
+ if (ic)
+ ic->update();
+ }
+#endif //QT_NO_IM
+}
+
+
+#ifndef QT_NO_DRAGANDDROP
+
+/*!
+ \fn void QWidget::dragEnterEvent(QDragEnterEvent *event)
+
+ This event handler is called when a drag is in progress and the
+ mouse enters this widget. The event is passed in the \a event parameter.
+
+ If the event is ignored, the widget won't receive any \l{dragMoveEvent()}{drag
+ move events}.
+
+ See the \link dnd.html Drag-and-drop documentation\endlink for an
+ overview of how to provide drag-and-drop in your application.
+
+ \sa QDrag, QDragEnterEvent
+*/
+void QWidget::dragEnterEvent(QDragEnterEvent *)
+{
+}
+
+/*!
+ \fn void QWidget::dragMoveEvent(QDragMoveEvent *event)
+
+ This event handler is called if a drag is in progress, and when
+ any of the following conditions occur: the cursor enters this widget,
+ the cursor moves within this widget, or a modifier key is pressed on
+ the keyboard while this widget has the focus. The event is passed
+ in the \a event parameter.
+
+ See the \link dnd.html Drag-and-drop documentation\endlink for an
+ overview of how to provide drag-and-drop in your application.
+
+ \sa QDrag, QDragMoveEvent
+*/
+void QWidget::dragMoveEvent(QDragMoveEvent *)
+{
+}
+
+/*!
+ \fn void QWidget::dragLeaveEvent(QDragLeaveEvent *event)
+
+ This event handler is called when a drag is in progress and the
+ mouse leaves this widget. The event is passed in the \a event
+ parameter.
+
+ See the \link dnd.html Drag-and-drop documentation\endlink for an
+ overview of how to provide drag-and-drop in your application.
+
+ \sa QDrag, QDragLeaveEvent
+*/
+void QWidget::dragLeaveEvent(QDragLeaveEvent *)
+{
+}
+
+/*!
+ \fn void QWidget::dropEvent(QDropEvent *event)
+
+ This event handler is called when the drag is dropped on this
+ widget. The event is passed in the \a event parameter.
+
+ See the \link dnd.html Drag-and-drop documentation\endlink for an
+ overview of how to provide drag-and-drop in your application.
+
+ \sa QDrag, QDropEvent
+*/
+void QWidget::dropEvent(QDropEvent *)
+{
+}
+
+#endif // QT_NO_DRAGANDDROP
+
+/*!
+ \fn void QWidget::showEvent(QShowEvent *event)
+
+ This event handler can be reimplemented in a subclass to receive
+ widget show events which are passed in the \a event parameter.
+
+ Non-spontaneous show events are sent to widgets immediately
+ before they are shown. The spontaneous show events of windows are
+ delivered afterwards.
+
+ Note: A widget receives spontaneous show and hide events when its
+ mapping status is changed by the window system, e.g. a spontaneous
+ hide event when the user minimizes the window, and a spontaneous
+ show event when the window is restored again. After receiving a
+ spontaneous hide event, a widget is still considered visible in
+ the sense of isVisible().
+
+ \sa visible, event(), QShowEvent
+*/
+void QWidget::showEvent(QShowEvent *)
+{
+}
+
+/*!
+ \fn void QWidget::hideEvent(QHideEvent *event)
+
+ This event handler can be reimplemented in a subclass to receive
+ widget hide events. The event is passed in the \a event parameter.
+
+ Hide events are sent to widgets immediately after they have been
+ hidden.
+
+ Note: A widget receives spontaneous show and hide events when its
+ mapping status is changed by the window system, e.g. a spontaneous
+ hide event when the user minimizes the window, and a spontaneous
+ show event when the window is restored again. After receiving a
+ spontaneous hide event, a widget is still considered visible in
+ the sense of isVisible().
+
+ \sa visible, event(), QHideEvent
+*/
+void QWidget::hideEvent(QHideEvent *)
+{
+}
+
+/*
+ \fn QWidget::x11Event(MSG *)
+
+ This special event handler can be reimplemented in a subclass to receive
+ native X11 events.
+
+ In your reimplementation of this function, if you want to stop Qt from
+ handling the event, return true. If you return false, this native event
+ is passed back to Qt, which translates it into a Qt event and sends it to
+ the widget.
+
+ \note Events are only delivered to this event handler if the widget is
+ native.
+
+ \warning This function is not portable.
+
+ \sa QApplication::x11EventFilter(), QWidget::winId()
+*/
+
+
+#if defined(Q_WS_MAC)
+
+/*!
+ \fn bool QWidget::macEvent(EventHandlerCallRef caller, EventRef event)
+
+ This special event handler can be reimplemented in a subclass to
+ receive native Macintosh events.
+
+ The parameters are a bit different depending if Qt is build against Carbon
+ or Cocoa. In Carbon, \a caller and \a event are the corresponding
+ EventHandlerCallRef and EventRef that correspond to the Carbon event
+ handlers that are installed. In Cocoa, \a caller is always 0 and the
+ EventRef is the EventRef generated from the NSEvent.
+
+ In your reimplementation of this function, if you want to stop the
+ event being handled by Qt, return true. If you return false, this
+ native event is passed back to Qt, which translates the event into
+ a Qt event and sends it to the widget.
+
+ \warning This function is not portable.
+
+ \warning This function was not called inside of Qt until Qt 4.4.
+ If you need compatibility with earlier versions of Qt, consider QApplication::macEventFilter() instead.
+
+ \sa QApplication::macEventFilter()
+*/
+
+bool QWidget::macEvent(EventHandlerCallRef, EventRef)
+{
+ return false;
+}
+
+#endif
+#if defined(Q_WS_WIN)
+
+/*!
+ This special event handler can be reimplemented in a subclass to
+ receive native Windows events which are passed in the \a message
+ parameter.
+
+ In your reimplementation of this function, if you want to stop the
+ event being handled by Qt, return true and set \a result to the value
+ that the window procedure should return. If you return false, this
+ native event is passed back to Qt, which translates the event into
+ a Qt event and sends it to the widget.
+
+ \warning This function is not portable.
+
+ \sa QApplication::winEventFilter()
+*/
+bool QWidget::winEvent(MSG *message, long *result)
+{
+ Q_UNUSED(message);
+ Q_UNUSED(result);
+ return false;
+}
+
+#endif
+#if defined(Q_WS_X11)
+
+/*!
+ \fn bool QWidget::x11Event(XEvent *event)
+
+ This special event handler can be reimplemented in a subclass to receive
+ native X11 events passed in the \a event parameter.
+
+ In your reimplementation of this function, if you want to stop Qt from
+ handling the event, return true. If you return false, this native event
+ is passed back to Qt, which translates it into a Qt event and sends it to
+ the widget.
+
+ \note Events are only delivered to this event handler if the widget is
+ native.
+
+ \warning This function is not portable.
+
+ \sa QApplication::x11EventFilter(), QWidget::winId()
+*/
+bool QWidget::x11Event(XEvent *)
+{
+ return false;
+}
+
+#endif
+
+/*!
+ Ensures that the widget has been polished by QStyle (i.e., has a
+ proper font and palette).
+
+ QWidget calls this function after it has been fully constructed
+ but before it is shown the very first time. You can call this
+ function if you want to ensure that the widget is polished before
+ doing an operation, e.g., the correct font size might be needed in
+ the widget's sizeHint() reimplementation. Note that this function
+ \e is called from the default implementation of sizeHint().
+
+ Polishing is useful for final initialization that must happen after
+ all constructors (from base classes as well as from subclasses)
+ have been called.
+
+ If you need to change some settings when a widget is polished,
+ reimplement event() and handle the QEvent::Polish event type.
+
+ \bold{Note:} The function is declared const so that it can be called from
+ other const functions (e.g., sizeHint()).
+
+ \sa event()
+*/
+void QWidget::ensurePolished() const
+{
+ Q_D(const QWidget);
+
+ const QMetaObject *m = metaObject();
+ if (m == d->polished)
+ return;
+ d->polished = m;
+
+ QEvent e(QEvent::Polish);
+ QCoreApplication::sendEvent(const_cast<QWidget *>(this), &e);
+
+ // polish children after 'this'
+ QList<QObject*> children = d->children;
+ for (int i = 0; i < children.size(); ++i) {
+ QObject *o = children.at(i);
+ if(!o->isWidgetType())
+ continue;
+ if (QWidget *w = qobject_cast<QWidget *>(o))
+ w->ensurePolished();
+ }
+
+ if (d->parent && d->sendChildEvents) {
+ QChildEvent e(QEvent::ChildPolished, const_cast<QWidget *>(this));
+ QCoreApplication::sendEvent(d->parent, &e);
+ }
+#ifdef Q_WS_QPA
+ if (d->extra && d->extra->topextra && d->extra->topextra->window
+ && d->extra->topextra->window->objectName().isEmpty()) {
+ QString on = objectName();
+ if (on.isEmpty()) {
+ on = QString::fromUtf8(metaObject()->className());
+ on += QLatin1String("Class");
+ }
+ on += QLatin1String("Window");
+ d->extra->topextra->window->setObjectName(on);
+ }
+#endif
+}
+
+/*!
+ Returns the mask currently set on a widget. If no mask is set the
+ return value will be an empty region.
+
+ \sa setMask(), clearMask(), QRegion::isEmpty(), {Shaped Clock Example}
+*/
+QRegion QWidget::mask() const
+{
+ Q_D(const QWidget);
+ return d->extra ? d->extra->mask : QRegion();
+}
+
+/*!
+ Returns the layout manager that is installed on this widget, or 0
+ if no layout manager is installed.
+
+ The layout manager sets the geometry of the widget's children
+ that have been added to the layout.
+
+ \sa setLayout(), sizePolicy(), {Layout Management}
+*/
+QLayout *QWidget::layout() const
+{
+ return d_func()->layout;
+}
+
+
+/*!
+ \fn void QWidget::setLayout(QLayout *layout)
+
+ Sets the layout manager for this widget to \a layout.
+
+ If there already is a layout manager installed on this widget,
+ QWidget won't let you install another. You must first delete the
+ existing layout manager (returned by layout()) before you can
+ call setLayout() with the new layout.
+
+ If \a layout is the layout manger on a different widget, setLayout()
+ will reparent the layout and make it the layout manager for this widget.
+
+ Example:
+
+ \snippet examples/uitools/textfinder/textfinder.cpp 3b
+
+ An alternative to calling this function is to pass this widget to
+ the layout's constructor.
+
+ The QWidget will take ownership of \a layout.
+
+ \sa layout(), {Layout Management}
+*/
+
+void QWidget::setLayout(QLayout *l)
+{
+ if (!l) {
+ qWarning("QWidget::setLayout: Cannot set layout to 0");
+ return;
+ }
+ if (layout()) {
+ if (layout() != l)
+ qWarning("QWidget::setLayout: Attempting to set QLayout \"%s\" on %s \"%s\", which already has a"
+ " layout", l->objectName().toLocal8Bit().data(), metaObject()->className(),
+ objectName().toLocal8Bit().data());
+ return;
+ }
+
+ QObject *oldParent = l->parent();
+ if (oldParent && oldParent != this) {
+ if (oldParent->isWidgetType()) {
+ // Steal the layout off a widget parent. Takes effect when
+ // morphing laid-out container widgets in Designer.
+ QWidget *oldParentWidget = static_cast<QWidget *>(oldParent);
+ oldParentWidget->takeLayout();
+ } else {
+ qWarning("QWidget::setLayout: Attempting to set QLayout \"%s\" on %s \"%s\", when the QLayout already has a parent",
+ l->objectName().toLocal8Bit().data(), metaObject()->className(),
+ objectName().toLocal8Bit().data());
+ return;
+ }
+ }
+
+ Q_D(QWidget);
+ l->d_func()->topLevel = true;
+ d->layout = l;
+ if (oldParent != this) {
+ l->setParent(this);
+ l->d_func()->reparentChildWidgets(this);
+ l->invalidate();
+ }
+
+ if (isWindow() && d->maybeTopData())
+ d->topData()->sizeAdjusted = false;
+}
+
+/*!
+ \fn QLayout *QWidget::takeLayout()
+
+ Remove the layout from the widget.
+ \since 4.5
+*/
+
+QLayout *QWidget::takeLayout()
+{
+ Q_D(QWidget);
+ QLayout *l = layout();
+ if (!l)
+ return 0;
+ d->layout = 0;
+ l->setParent(0);
+ return l;
+}
+
+/*!
+ \property QWidget::sizePolicy
+ \brief the default layout behavior of the widget
+
+ If there is a QLayout that manages this widget's children, the
+ size policy specified by that layout is used. If there is no such
+ QLayout, the result of this function is used.
+
+ The default policy is Preferred/Preferred, which means that the
+ widget can be freely resized, but prefers to be the size
+ sizeHint() returns. Button-like widgets set the size policy to
+ specify that they may stretch horizontally, but are fixed
+ vertically. The same applies to lineedit controls (such as
+ QLineEdit, QSpinBox or an editable QComboBox) and other
+ horizontally orientated widgets (such as QProgressBar).
+ QToolButton's are normally square, so they allow growth in both
+ directions. Widgets that support different directions (such as
+ QSlider, QScrollBar or QHeader) specify stretching in the
+ respective direction only. Widgets that can provide scroll bars
+ (usually subclasses of QScrollArea) tend to specify that they can
+ use additional space, and that they can make do with less than
+ sizeHint().
+
+ \sa sizeHint() QLayout QSizePolicy updateGeometry()
+*/
+QSizePolicy QWidget::sizePolicy() const
+{
+ Q_D(const QWidget);
+ return d->size_policy;
+}
+
+void QWidget::setSizePolicy(QSizePolicy policy)
+{
+ Q_D(QWidget);
+ setAttribute(Qt::WA_WState_OwnSizePolicy);
+ if (policy == d->size_policy)
+ return;
+ d->size_policy = policy;
+
+#ifndef QT_NO_GRAPHICSVIEW
+ if (QWExtra *extra = d->extra) {
+ if (extra->proxyWidget)
+ extra->proxyWidget->setSizePolicy(policy);
+ }
+#endif
+
+ updateGeometry();
+
+ if (isWindow() && d->maybeTopData())
+ d->topData()->sizeAdjusted = false;
+}
+
+/*!
+ \fn void QWidget::setSizePolicy(QSizePolicy::Policy horizontal, QSizePolicy::Policy vertical)
+ \overload
+
+ Sets the size policy of the widget to \a horizontal and \a
+ vertical, with standard stretch and no height-for-width.
+
+ \sa QSizePolicy::QSizePolicy()
+*/
+
+/*!
+ Returns the preferred height for this widget, given the width \a w.
+
+ If this widget has a layout, the default implementation returns
+ the layout's preferred height. if there is no layout, the default
+ implementation returns -1 indicating that the preferred height
+ does not depend on the width.
+*/
+
+int QWidget::heightForWidth(int w) const
+{
+ if (layout() && layout()->hasHeightForWidth())
+ return layout()->totalHeightForWidth(w);
+ return -1;
+}
+
+
+/*!
+ \internal
+
+ *virtual private*
+
+ This is a bit hackish, but ideally we would have created a virtual function
+ in the public API (however, too late...) so that subclasses could reimplement
+ their own function.
+ Instead we add a virtual function to QWidgetPrivate.
+ ### Qt5: move to public class and make virtual
+*/
+bool QWidgetPrivate::hasHeightForWidth() const
+{
+ return layout ? layout->hasHeightForWidth() : size_policy.hasHeightForWidth();
+}
+
+/*!
+ \fn QWidget *QWidget::childAt(int x, int y) const
+
+ Returns the visible child widget at the position (\a{x}, \a{y})
+ in the widget's coordinate system. If there is no visible child
+ widget at the specified position, the function returns 0.
+*/
+
+/*!
+ \overload
+
+ Returns the visible child widget at point \a p in the widget's own
+ coordinate system.
+*/
+
+QWidget *QWidget::childAt(const QPoint &p) const
+{
+ return d_func()->childAt_helper(p, false);
+}
+
+QWidget *QWidgetPrivate::childAt_helper(const QPoint &p, bool ignoreChildrenInDestructor) const
+{
+ if (children.isEmpty())
+ return 0;
+
+#ifdef Q_WS_MAC
+ Q_Q(const QWidget);
+ // Unified tool bars on the Mac require special handling since they live outside
+ // QMainWindow's geometry(). See commit: 35667fd45ada49269a5987c235fdedfc43e92bb8
+ bool includeFrame = q->isWindow() && qobject_cast<const QMainWindow *>(q)
+ && static_cast<const QMainWindow *>(q)->unifiedTitleAndToolBarOnMac();
+ if (includeFrame)
+ return childAtRecursiveHelper(p, ignoreChildrenInDestructor, includeFrame);
+#endif
+
+ if (!pointInsideRectAndMask(p))
+ return 0;
+ return childAtRecursiveHelper(p, ignoreChildrenInDestructor);
+}
+
+QWidget *QWidgetPrivate::childAtRecursiveHelper(const QPoint &p, bool ignoreChildrenInDestructor, bool includeFrame) const
+{
+#ifndef Q_WS_MAC
+ Q_UNUSED(includeFrame);
+#endif
+ for (int i = children.size() - 1; i >= 0; --i) {
+ QWidget *child = qobject_cast<QWidget *>(children.at(i));
+ if (!child || child->isWindow() || child->isHidden() || child->testAttribute(Qt::WA_TransparentForMouseEvents)
+ || (ignoreChildrenInDestructor && child->data->in_destructor)) {
+ continue;
+ }
+
+ // Map the point 'p' from parent coordinates to child coordinates.
+ QPoint childPoint = p;
+#ifdef Q_WS_MAC
+ // 'includeFrame' is true if the child's parent is a top-level QMainWindow with an unified tool bar.
+ // An unified tool bar on the Mac lives outside QMainWindow's geometry(), so a normal
+ // QWidget::mapFromParent won't do the trick.
+ if (includeFrame && qobject_cast<QToolBar *>(child))
+ childPoint = qt_mac_nativeMapFromParent(child, p);
+ else
+#endif
+ childPoint -= child->data->crect.topLeft();
+
+ // Check if the point hits the child.
+ if (!child->d_func()->pointInsideRectAndMask(childPoint))
+ continue;
+
+ // Do the same for the child's descendants.
+ if (QWidget *w = child->d_func()->childAtRecursiveHelper(childPoint, ignoreChildrenInDestructor))
+ return w;
+
+ // We have found our target; namely the child at position 'p'.
+ return child;
+ }
+ return 0;
+}
+
+void QWidgetPrivate::updateGeometry_helper(bool forceUpdate)
+{
+ Q_Q(QWidget);
+ if (widgetItem)
+ widgetItem->invalidateSizeCache();
+ QWidget *parent;
+ if (forceUpdate || !extra || extra->minw != extra->maxw || extra->minh != extra->maxh) {
+ if (!q->isWindow() && !q->isHidden() && (parent = q->parentWidget())) {
+ if (parent->d_func()->layout)
+ parent->d_func()->layout->invalidate();
+ else if (parent->isVisible())
+ QApplication::postEvent(parent, new QEvent(QEvent::LayoutRequest));
+ }
+ }
+}
+
+/*!
+ Notifies the layout system that this widget has changed and may
+ need to change geometry.
+
+ Call this function if the sizeHint() or sizePolicy() have changed.
+
+ For explicitly hidden widgets, updateGeometry() is a no-op. The
+ layout system will be notified as soon as the widget is shown.
+*/
+
+void QWidget::updateGeometry()
+{
+ Q_D(QWidget);
+ d->updateGeometry_helper(false);
+}
+
+/*! \property QWidget::windowFlags
+
+ Window flags are a combination of a type (e.g. Qt::Dialog) and
+ zero or more hints to the window system (e.g.
+ Qt::FramelessWindowHint).
+
+ If the widget had type Qt::Widget or Qt::SubWindow and becomes a
+ window (Qt::Window, Qt::Dialog, etc.), it is put at position (0,
+ 0) on the desktop. If the widget is a window and becomes a
+ Qt::Widget or Qt::SubWindow, it is put at position (0, 0)
+ relative to its parent widget.
+
+ \note This function calls setParent() when changing the flags for
+ a window, causing the widget to be hidden. You must call show() to make
+ the widget visible again..
+
+ \sa windowType(), {Window Flags Example}
+*/
+void QWidget::setWindowFlags(Qt::WindowFlags flags)
+{
+ if (data->window_flags == flags)
+ return;
+
+ Q_D(QWidget);
+
+ if ((data->window_flags | flags) & Qt::Window) {
+ // the old type was a window and/or the new type is a window
+ QPoint oldPos = pos();
+ bool visible = isVisible();
+ setParent(parentWidget(), flags);
+
+ // if both types are windows or neither of them are, we restore
+ // the old position
+ if (!((data->window_flags ^ flags) & Qt::Window)
+ && (visible || testAttribute(Qt::WA_Moved))) {
+ move(oldPos);
+ }
+ // for backward-compatibility we change Qt::WA_QuitOnClose attribute value only when the window was recreated.
+ d->adjustQuitOnCloseAttribute();
+ } else {
+ data->window_flags = flags;
+ }
+}
+
+/*!
+ Sets the window flags for the widget to \a flags,
+ \e without telling the window system.
+
+ \warning Do not call this function unless you really know what
+ you're doing.
+
+ \sa setWindowFlags()
+*/
+void QWidget::overrideWindowFlags(Qt::WindowFlags flags)
+{
+ data->window_flags = flags;
+}
+
+/*!
+ \fn Qt::WindowType QWidget::windowType() const
+
+ Returns the window type of this widget. This is identical to
+ windowFlags() & Qt::WindowType_Mask.
+
+ \sa windowFlags
+*/
+
+/*!
+ Sets the parent of the widget to \a parent, and resets the window
+ flags. The widget is moved to position (0, 0) in its new parent.
+
+ If the new parent widget is in a different window, the
+ reparented widget and its children are appended to the end of the
+ \l{setFocusPolicy()}{tab chain} of the new parent
+ widget, in the same internal order as before. If one of the moved
+ widgets had keyboard focus, setParent() calls clearFocus() for that
+ widget.
+
+ If the new parent widget is in the same window as the
+ old parent, setting the parent doesn't change the tab order or
+ keyboard focus.
+
+ If the "new" parent widget is the old parent widget, this function
+ does nothing.
+
+ \note The widget becomes invisible as part of changing its parent,
+ even if it was previously visible. You must call show() to make the
+ widget visible again.
+
+ \warning It is very unlikely that you will ever need this
+ function. If you have a widget that changes its content
+ dynamically, it is far easier to use \l QStackedWidget.
+
+ \sa setWindowFlags()
+*/
+void QWidget::setParent(QWidget *parent)
+{
+ if (parent == parentWidget())
+ return;
+ setParent((QWidget*)parent, windowFlags() & ~Qt::WindowType_Mask);
+}
+
+/*!
+ \overload
+
+ This function also takes widget flags, \a f as an argument.
+*/
+
+void QWidget::setParent(QWidget *parent, Qt::WindowFlags f)
+{
+ Q_D(QWidget);
+ d->inSetParent = true;
+ bool resized = testAttribute(Qt::WA_Resized);
+ bool wasCreated = testAttribute(Qt::WA_WState_Created);
+ QWidget *oldtlw = window();
+
+ QWidget *desktopWidget = 0;
+ if (parent && parent->windowType() == Qt::Desktop)
+ desktopWidget = parent;
+ bool newParent = (parent != parentWidget()) || !wasCreated || desktopWidget;
+
+#if defined(Q_WS_X11) || defined(Q_WS_WIN) || defined(Q_WS_MAC) || defined(Q_OS_SYMBIAN)
+ if (newParent && parent && !desktopWidget) {
+ if (testAttribute(Qt::WA_NativeWindow) && !qApp->testAttribute(Qt::AA_DontCreateNativeWidgetSiblings)
+#if defined(Q_WS_MAC) && defined(QT_MAC_USE_COCOA)
+ // On Mac, toolbars inside the unified title bar will never overlap with
+ // siblings in the content view. So we skip enforce native siblings in that case
+ && !d->isInUnifiedToolbar && parentWidget() && parentWidget()->isWindow()
+#endif // Q_WS_MAC && QT_MAC_USE_COCOA
+ )
+ parent->d_func()->enforceNativeChildren();
+ else if (parent->d_func()->nativeChildrenForced() || parent->testAttribute(Qt::WA_PaintOnScreen))
+ setAttribute(Qt::WA_NativeWindow);
+ }
+#endif
+
+ if (wasCreated) {
+ if (!testAttribute(Qt::WA_WState_Hidden)) {
+ hide();
+ setAttribute(Qt::WA_WState_ExplicitShowHide, false);
+ }
+ if (newParent) {
+ QEvent e(QEvent::ParentAboutToChange);
+ QApplication::sendEvent(this, &e);
+ }
+ }
+ if (newParent && isAncestorOf(focusWidget()))
+ focusWidget()->clearFocus();
+
+ QTLWExtra *oldTopExtra = window()->d_func()->maybeTopData();
+ QWidgetBackingStoreTracker *oldBsTracker = oldTopExtra ? &oldTopExtra->backingStoreTracker : 0;
+
+ d->setParent_sys(parent, f);
+
+ QTLWExtra *topExtra = window()->d_func()->maybeTopData();
+ QWidgetBackingStoreTracker *bsTracker = topExtra ? &topExtra->backingStoreTracker : 0;
+ if (oldBsTracker && oldBsTracker != bsTracker)
+ oldBsTracker->unregisterWidgetSubtree(this);
+
+ if (desktopWidget)
+ parent = 0;
+
+ if (QWidgetBackingStore *oldBs = oldtlw->d_func()->maybeBackingStore()) {
+ if (newParent)
+ oldBs->removeDirtyWidget(this);
+ // Move the widget and all its static children from
+ // the old backing store to the new one.
+ oldBs->moveStaticWidgets(this);
+ }
+
+ if ((QApplicationPrivate::app_compile_version < 0x040200
+ || QApplicationPrivate::testAttribute(Qt::AA_ImmediateWidgetCreation))
+ && !testAttribute(Qt::WA_WState_Created))
+ create();
+
+ d->reparentFocusWidgets(oldtlw);
+ setAttribute(Qt::WA_Resized, resized);
+ if (!testAttribute(Qt::WA_StyleSheet)
+ && (!parent || !parent->testAttribute(Qt::WA_StyleSheet))) {
+ d->resolveFont();
+ d->resolvePalette();
+ }
+ d->resolveLayoutDirection();
+ d->resolveLocale();
+
+ // Note: GL widgets under WGL or EGL will always need a ParentChange
+ // event to handle recreation/rebinding of the GL context, hence the
+ // (f & Qt::MSWindowsOwnDC) clause (which is set on QGLWidgets on all
+ // platforms).
+ if (newParent
+#if defined(Q_WS_WIN) || defined(QT_OPENGL_ES)
+ || (f & Qt::MSWindowsOwnDC)
+#endif
+ ) {
+ // propagate enabled updates enabled state to non-windows
+ if (!isWindow()) {
+ if (!testAttribute(Qt::WA_ForceDisabled))
+ d->setEnabled_helper(parent ? parent->isEnabled() : true);
+ if (!testAttribute(Qt::WA_ForceUpdatesDisabled))
+ d->setUpdatesEnabled_helper(parent ? parent->updatesEnabled() : true);
+ }
+ d->inheritStyle();
+
+ // send and post remaining QObject events
+ if (parent && d->sendChildEvents) {
+ QChildEvent e(QEvent::ChildAdded, this);
+ QApplication::sendEvent(parent, &e);
+#ifdef QT3_SUPPORT
+ if (parent->d_func()->pendingChildInsertedEvents.isEmpty()) {
+ QApplication::postEvent(parent,
+ new QEvent(QEvent::ChildInsertedRequest),
+ Qt::HighEventPriority);
+ }
+ parent->d_func()->pendingChildInsertedEvents.append(this);
+#endif
+ }
+
+//### already hidden above ---> must probably do something smart on the mac
+// #ifdef Q_WS_MAC
+// extern bool qt_mac_is_macdrawer(const QWidget *); //qwidget_mac.cpp
+// if(!qt_mac_is_macdrawer(q)) //special case
+// q->setAttribute(Qt::WA_WState_Hidden);
+// #else
+// q->setAttribute(Qt::WA_WState_Hidden);
+//#endif
+
+ if (parent && d->sendChildEvents && d->polished) {
+ QChildEvent e(QEvent::ChildPolished, this);
+ QCoreApplication::sendEvent(parent, &e);
+ }
+
+ QEvent e(QEvent::ParentChange);
+ QApplication::sendEvent(this, &e);
+ }
+
+ if (!wasCreated) {
+ if (isWindow() || parentWidget()->isVisible())
+ setAttribute(Qt::WA_WState_Hidden, true);
+ else if (!testAttribute(Qt::WA_WState_ExplicitShowHide))
+ setAttribute(Qt::WA_WState_Hidden, false);
+ }
+
+ d->updateIsOpaque();
+
+#ifndef QT_NO_GRAPHICSVIEW
+ // Embed the widget into a proxy if the parent is embedded.
+ // ### Doesn't handle reparenting out of an embedded widget.
+ if (oldtlw->graphicsProxyWidget()) {
+ if (QGraphicsProxyWidget *ancestorProxy = d->nearestGraphicsProxyWidget(oldtlw))
+ ancestorProxy->d_func()->unembedSubWindow(this);
+ }
+ if (isWindow() && parent && !graphicsProxyWidget() && !bypassGraphicsProxyWidget(this)) {
+ if (QGraphicsProxyWidget *ancestorProxy = d->nearestGraphicsProxyWidget(parent))
+ ancestorProxy->d_func()->embedSubWindow(this);
+ }
+#endif
+
+ d->inSetParent = false;
+}
+
+/*!
+ Scrolls the widget including its children \a dx pixels to the
+ right and \a dy downward. Both \a dx and \a dy may be negative.
+
+ After scrolling, the widgets will receive paint events for
+ the areas that need to be repainted. For widgets that Qt knows to
+ be opaque, this is only the newly exposed parts.
+ For example, if an opaque widget is scrolled 8 pixels to the left,
+ only an 8-pixel wide stripe at the right edge needs updating.
+
+ Since widgets propagate the contents of their parents by default,
+ you need to set the \l autoFillBackground property, or use
+ setAttribute() to set the Qt::WA_OpaquePaintEvent attribute, to make
+ a widget opaque.
+
+ For widgets that use contents propagation, a scroll will cause an
+ update of the entire scroll area.
+
+ \sa {Transparency and Double Buffering}
+*/
+
+void QWidget::scroll(int dx, int dy)
+{
+ if ((!updatesEnabled() && children().size() == 0) || !isVisible())
+ return;
+ if (dx == 0 && dy == 0)
+ return;
+ Q_D(QWidget);
+#ifndef QT_NO_GRAPHICSVIEW
+ if (QGraphicsProxyWidget *proxy = QWidgetPrivate::nearestGraphicsProxyWidget(this)) {
+ // Graphics View maintains its own dirty region as a list of rects;
+ // until we can connect item updates directly to the view, we must
+ // separately add a translated dirty region.
+ if (!d->dirty.isEmpty()) {
+ foreach (const QRect &rect, (d->dirty.translated(dx, dy)).rects())
+ proxy->update(rect);
+ }
+ proxy->scroll(dx, dy, proxy->subWidgetRect(this));
+ return;
+ }
+#endif
+ d->setDirtyOpaqueRegion();
+ d->scroll_sys(dx, dy);
+}
+
+/*!
+ \overload
+
+ This version only scrolls \a r and does not move the children of
+ the widget.
+
+ If \a r is empty or invalid, the result is undefined.
+
+ \sa QScrollArea
+*/
+void QWidget::scroll(int dx, int dy, const QRect &r)
+{
+
+ if ((!updatesEnabled() && children().size() == 0) || !isVisible())
+ return;
+ if (dx == 0 && dy == 0)
+ return;
+ Q_D(QWidget);
+#ifndef QT_NO_GRAPHICSVIEW
+ if (QGraphicsProxyWidget *proxy = QWidgetPrivate::nearestGraphicsProxyWidget(this)) {
+ // Graphics View maintains its own dirty region as a list of rects;
+ // until we can connect item updates directly to the view, we must
+ // separately add a translated dirty region.
+ if (!d->dirty.isEmpty()) {
+ foreach (const QRect &rect, (d->dirty.translated(dx, dy) & r).rects())
+ proxy->update(rect);
+ }
+ proxy->scroll(dx, dy, r.translated(proxy->subWidgetRect(this).topLeft().toPoint()));
+ return;
+ }
+#endif
+ d->scroll_sys(dx, dy, r);
+}
+
+/*!
+ Repaints the widget directly by calling paintEvent() immediately,
+ unless updates are disabled or the widget is hidden.
+
+ We suggest only using repaint() if you need an immediate repaint,
+ for example during animation. In almost all circumstances update()
+ is better, as it permits Qt to optimize for speed and minimize
+ flicker.
+
+ \warning If you call repaint() in a function which may itself be
+ called from paintEvent(), you may get infinite recursion. The
+ update() function never causes recursion.
+
+ \sa update(), paintEvent(), setUpdatesEnabled()
+*/
+
+void QWidget::repaint()
+{
+ repaint(rect());
+}
+
+/*! \overload
+
+ This version repaints a rectangle (\a x, \a y, \a w, \a h) inside
+ the widget.
+
+ If \a w is negative, it is replaced with \c{width() - x}, and if
+ \a h is negative, it is replaced width \c{height() - y}.
+*/
+void QWidget::repaint(int x, int y, int w, int h)
+{
+ if (x > data->crect.width() || y > data->crect.height())
+ return;
+
+ if (w < 0)
+ w = data->crect.width() - x;
+ if (h < 0)
+ h = data->crect.height() - y;
+
+ repaint(QRect(x, y, w, h));
+}
+
+/*! \overload
+
+ This version repaints a rectangle \a rect inside the widget.
+*/
+void QWidget::repaint(const QRect &rect)
+{
+ Q_D(QWidget);
+
+ if (testAttribute(Qt::WA_WState_ConfigPending)) {
+ update(rect);
+ return;
+ }
+
+ if (!isVisible() || !updatesEnabled() || rect.isEmpty())
+ return;
+
+ if (hasBackingStoreSupport()) {
+#ifdef QT_MAC_USE_COCOA
+ if (qt_widget_private(this)->isInUnifiedToolbar) {
+ qt_widget_private(this)->unifiedSurface->renderToolbar(this, true);
+ return;
+ }
+#endif // QT_MAC_USE_COCOA
+ QTLWExtra *tlwExtra = window()->d_func()->maybeTopData();
+ if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) {
+ tlwExtra->inRepaint = true;
+ tlwExtra->backingStoreTracker->markDirty(rect, this, true);
+ tlwExtra->inRepaint = false;
+ }
+ } else {
+ d->repaint_sys(rect);
+ }
+}
+
+/*!
+ \overload
+
+ This version repaints a region \a rgn inside the widget.
+*/
+void QWidget::repaint(const QRegion &rgn)
+{
+ Q_D(QWidget);
+
+ if (testAttribute(Qt::WA_WState_ConfigPending)) {
+ update(rgn);
+ return;
+ }
+
+ if (!isVisible() || !updatesEnabled() || rgn.isEmpty())
+ return;
+
+ if (hasBackingStoreSupport()) {
+#ifdef QT_MAC_USE_COCOA
+ if (qt_widget_private(this)->isInUnifiedToolbar) {
+ qt_widget_private(this)->unifiedSurface->renderToolbar(this, true);
+ return;
+ }
+#endif // QT_MAC_USE_COCOA
+ QTLWExtra *tlwExtra = window()->d_func()->maybeTopData();
+ if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) {
+ tlwExtra->inRepaint = true;
+ tlwExtra->backingStoreTracker->markDirty(rgn, this, true);
+ tlwExtra->inRepaint = false;
+ }
+ } else {
+ d->repaint_sys(rgn);
+ }
+}
+
+/*!
+ Updates the widget unless updates are disabled or the widget is
+ hidden.
+
+ This function does not cause an immediate repaint; instead it
+ schedules a paint event for processing when Qt returns to the main
+ event loop. This permits Qt to optimize for more speed and less
+ flicker than a call to repaint() does.
+
+ Calling update() several times normally results in just one
+ paintEvent() call.
+
+ Qt normally erases the widget's area before the paintEvent() call.
+ If the Qt::WA_OpaquePaintEvent widget attribute is set, the widget is
+ responsible for painting all its pixels with an opaque color.
+
+ \sa repaint() paintEvent(), setUpdatesEnabled(), {Analog Clock Example}
+*/
+void QWidget::update()
+{
+ update(rect());
+}
+
+/*! \fn void QWidget::update(int x, int y, int w, int h)
+ \overload
+
+ This version updates a rectangle (\a x, \a y, \a w, \a h) inside
+ the widget.
+*/
+
+/*!
+ \overload
+
+ This version updates a rectangle \a rect inside the widget.
+*/
+void QWidget::update(const QRect &rect)
+{
+ if (!isVisible() || !updatesEnabled() || rect.isEmpty())
+ return;
+
+ if (testAttribute(Qt::WA_WState_InPaintEvent)) {
+ QApplication::postEvent(this, new QUpdateLaterEvent(rect));
+ return;
+ }
+
+ if (hasBackingStoreSupport()) {
+#ifdef QT_MAC_USE_COCOA
+ if (qt_widget_private(this)->isInUnifiedToolbar) {
+ qt_widget_private(this)->unifiedSurface->renderToolbar(this, true);
+ return;
+ }
+#endif // QT_MAC_USE_COCOA
+ QTLWExtra *tlwExtra = window()->d_func()->maybeTopData();
+ if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore)
+ tlwExtra->backingStoreTracker->markDirty(rect, this);
+ } else {
+ d_func()->repaint_sys(rect);
+ }
+}
+
+/*!
+ \overload
+
+ This version repaints a region \a rgn inside the widget.
+*/
+void QWidget::update(const QRegion &rgn)
+{
+ if (!isVisible() || !updatesEnabled() || rgn.isEmpty())
+ return;
+
+ if (testAttribute(Qt::WA_WState_InPaintEvent)) {
+ QApplication::postEvent(this, new QUpdateLaterEvent(rgn));
+ return;
+ }
+
+ if (hasBackingStoreSupport()) {
+#ifdef QT_MAC_USE_COCOA
+ if (qt_widget_private(this)->isInUnifiedToolbar) {
+ qt_widget_private(this)->unifiedSurface->renderToolbar(this, true);
+ return;
+ }
+#endif // QT_MAC_USE_COCOA
+ QTLWExtra *tlwExtra = window()->d_func()->maybeTopData();
+ if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore)
+ tlwExtra->backingStoreTracker->markDirty(rgn, this);
+ } else {
+ d_func()->repaint_sys(rgn);
+ }
+}
+
+#ifdef QT3_SUPPORT
+/*!
+ Clear the rectangle at point (\a x, \a y) of width \a w and height
+ \a h.
+
+ \warning This is best done in a paintEvent().
+*/
+void QWidget::erase_helper(int x, int y, int w, int h)
+{
+ if (testAttribute(Qt::WA_NoSystemBackground) || testAttribute(Qt::WA_UpdatesDisabled) || !testAttribute(Qt::WA_WState_Visible))
+ return;
+ if (w < 0)
+ w = data->crect.width() - x;
+ if (h < 0)
+ h = data->crect.height() - y;
+ if (w != 0 && h != 0) {
+ QPainter p(this);
+ p.eraseRect(QRect(x, y, w, h));
+ }
+}
+
+/*!
+ \overload
+
+ Clear the given region, \a rgn.
+
+ Drawing may only take place in a QPaintEvent. Overload
+ paintEvent() to do your erasing and call update() to schedule a
+ replaint whenever necessary. See also QPainter.
+*/
+void QWidget::erase(const QRegion& rgn)
+{
+ if (testAttribute(Qt::WA_NoSystemBackground) || testAttribute(Qt::WA_UpdatesDisabled) || !testAttribute(Qt::WA_WState_Visible))
+ return;
+
+ QPainter p(this);
+ p.setClipRegion(rgn);
+ p.eraseRect(rgn.boundingRect());
+}
+
+void QWidget::drawText_helper(int x, int y, const QString &str)
+{
+ if(!testAttribute(Qt::WA_WState_Visible))
+ return;
+ QPainter paint(this);
+ paint.drawText(x, y, str);
+}
+
+
+/*!
+ Closes the widget.
+
+ Use the no-argument overload instead.
+*/
+bool QWidget::close(bool alsoDelete)
+{
+ QPointer<QWidget> that = this;
+ bool accepted = close();
+ if (alsoDelete && accepted && that)
+ deleteLater();
+ return accepted;
+}
+
+void QWidget::setIcon(const QPixmap &i)
+{
+ setWindowIcon(i);
+}
+
+/*!
+ Return's the widget's icon.
+
+ Use windowIcon() instead.
+*/
+const QPixmap *QWidget::icon() const
+{
+ Q_D(const QWidget);
+ return (d->extra && d->extra->topextra) ? d->extra->topextra->iconPixmap : 0;
+}
+
+#endif // QT3_SUPPORT
+
+ /*!
+ \internal
+
+ This just sets the corresponding attribute bit to 1 or 0
+ */
+static void setAttribute_internal(Qt::WidgetAttribute attribute, bool on, QWidgetData *data,
+ QWidgetPrivate *d)
+{
+ if (attribute < int(8*sizeof(uint))) {
+ if (on)
+ data->widget_attributes |= (1<<attribute);
+ else
+ data->widget_attributes &= ~(1<<attribute);
+ } else {
+ const int x = attribute - 8*sizeof(uint);
+ const int int_off = x / (8*sizeof(uint));
+ if (on)
+ d->high_attributes[int_off] |= (1<<(x-(int_off*8*sizeof(uint))));
+ else
+ d->high_attributes[int_off] &= ~(1<<(x-(int_off*8*sizeof(uint))));
+ }
+}
+
+/*!
+ Sets the attribute \a attribute on this widget if \a on is true;
+ otherwise clears the attribute.
+
+ \sa testAttribute()
+*/
+void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on)
+{
+ if (testAttribute(attribute) == on)
+ return;
+
+ Q_D(QWidget);
+ Q_ASSERT_X(sizeof(d->high_attributes)*8 >= (Qt::WA_AttributeCount - sizeof(uint)*8),
+ "QWidget::setAttribute(WidgetAttribute, bool)",
+ "QWidgetPrivate::high_attributes[] too small to contain all attributes in WidgetAttribute");
+#ifdef Q_WS_WIN
+ // ### Don't use PaintOnScreen+paintEngine() to do native painting in 5.0
+ if (attribute == Qt::WA_PaintOnScreen && on && !inherits("QGLWidget")) {
+ // see qwidget_win.cpp, ::paintEngine for details
+ paintEngine();
+ if (d->noPaintOnScreen)
+ return;
+ }
+#endif
+
+ setAttribute_internal(attribute, on, data, d);
+
+ switch (attribute) {
+
+#ifndef QT_NO_DRAGANDDROP
+ case Qt::WA_AcceptDrops: {
+ if (on && !testAttribute(Qt::WA_DropSiteRegistered))
+ setAttribute(Qt::WA_DropSiteRegistered, true);
+ else if (!on && (isWindow() || !parentWidget() || !parentWidget()->testAttribute(Qt::WA_DropSiteRegistered)))
+ setAttribute(Qt::WA_DropSiteRegistered, false);
+ QEvent e(QEvent::AcceptDropsChange);
+ QApplication::sendEvent(this, &e);
+ break;
+ }
+ case Qt::WA_DropSiteRegistered: {
+ d->registerDropSite(on);
+ for (int i = 0; i < d->children.size(); ++i) {
+ QWidget *w = qobject_cast<QWidget *>(d->children.at(i));
+ if (w && !w->isWindow() && !w->testAttribute(Qt::WA_AcceptDrops) && w->testAttribute(Qt::WA_DropSiteRegistered) != on)
+ w->setAttribute(Qt::WA_DropSiteRegistered, on);
+ }
+ break;
+ }
+#endif
+
+ case Qt::WA_NoChildEventsForParent:
+ d->sendChildEvents = !on;
+ break;
+ case Qt::WA_NoChildEventsFromChildren:
+ d->receiveChildEvents = !on;
+ break;
+ case Qt::WA_MacBrushedMetal:
+#ifdef Q_WS_MAC
+ d->setStyle_helper(style(), false, true); // Make sure things get unpolished/polished correctly.
+ // fall through since changing the metal attribute affects the opaque size grip.
+ case Qt::WA_MacOpaqueSizeGrip:
+ d->macUpdateOpaqueSizeGrip();
+ break;
+ case Qt::WA_MacShowFocusRect:
+ if (hasFocus()) {
+ clearFocus();
+ setFocus();
+ }
+ break;
+ case Qt::WA_Hover:
+ qt_mac_update_mouseTracking(this);
+ break;
+#endif
+ case Qt::WA_MacAlwaysShowToolWindow:
+#ifdef Q_WS_MAC
+ d->macUpdateHideOnSuspend();
+#endif
+ break;
+ case Qt::WA_MacNormalSize:
+ case Qt::WA_MacSmallSize:
+ case Qt::WA_MacMiniSize:
+#ifdef Q_WS_MAC
+ {
+ // We can only have one of these set at a time
+ const Qt::WidgetAttribute MacSizes[] = { Qt::WA_MacNormalSize, Qt::WA_MacSmallSize,
+ Qt::WA_MacMiniSize };
+ for (int i = 0; i < 3; ++i) {
+ if (MacSizes[i] != attribute)
+ setAttribute_internal(MacSizes[i], false, data, d);
+ }
+ d->macUpdateSizeAttribute();
+ }
+#endif
+ break;
+ case Qt::WA_ShowModal:
+ if (!on) {
+ if (isVisible())
+ QApplicationPrivate::leaveModal(this);
+ // reset modality type to Modeless when clearing WA_ShowModal
+ data->window_modality = Qt::NonModal;
+ } else if (data->window_modality == Qt::NonModal) {
+ // determine the modality type if it hasn't been set prior
+ // to setting WA_ShowModal. set the default to WindowModal
+ // if we are the child of a group leader; otherwise use
+ // ApplicationModal.
+ QWidget *w = parentWidget();
+ if (w)
+ w = w->window();
+ while (w && !w->testAttribute(Qt::WA_GroupLeader)) {
+ w = w->parentWidget();
+ if (w)
+ w = w->window();
+ }
+ data->window_modality = (w && w->testAttribute(Qt::WA_GroupLeader))
+ ? Qt::WindowModal
+ : Qt::ApplicationModal;
+ // Some window managers does not allow us to enter modal after the
+ // window is showing. Therefore, to be consistent, we cannot call
+ // QApplicationPrivate::enterModal(this) here. The window must be
+ // hidden before changing modality.
+ }
+ if (testAttribute(Qt::WA_WState_Created)) {
+ // don't call setModal_sys() before create_sys()
+ d->setModal_sys();
+ }
+ break;
+ case Qt::WA_MouseTracking: {
+ QEvent e(QEvent::MouseTrackingChange);
+ QApplication::sendEvent(this, &e);
+ break; }
+ case Qt::WA_NativeWindow: {
+#if defined(Q_WS_QPA)
+ d->createTLExtra();
+#endif
+#ifndef QT_NO_IM
+ QWidget *focusWidget = d->effectiveFocusWidget();
+ QInputContext *ic = 0;
+ if (on && !internalWinId() && hasFocus()
+ && focusWidget->testAttribute(Qt::WA_InputMethodEnabled)) {
+ ic = focusWidget->d_func()->inputContext();
+ if (ic) {
+ ic->reset();
+ ic->setFocusWidget(0);
+ }
+ }
+ if (!qApp->testAttribute(Qt::AA_DontCreateNativeWidgetSiblings) && parentWidget()
+#if defined(Q_WS_MAC) && defined(QT_MAC_USE_COCOA)
+ // On Mac, toolbars inside the unified title bar will never overlap with
+ // siblings in the content view. So we skip enforce native siblings in that case
+ && !d->isInUnifiedToolbar && parentWidget()->isWindow()
+#endif // Q_WS_MAC && QT_MAC_USE_COCOA
+ )
+ parentWidget()->d_func()->enforceNativeChildren();
+ if (on && !internalWinId() && testAttribute(Qt::WA_WState_Created))
+ d->createWinId();
+ if (ic && isEnabled() && focusWidget->isEnabled()
+ && focusWidget->testAttribute(Qt::WA_InputMethodEnabled)) {
+ ic->setFocusWidget(focusWidget);
+ }
+#endif //QT_NO_IM
+ break;
+ }
+ case Qt::WA_PaintOnScreen:
+ d->updateIsOpaque();
+#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_OS_SYMBIAN)
+ // Recreate the widget if it's already created as an alien widget and
+ // WA_PaintOnScreen is enabled. Paint on screen widgets must have win id.
+ // So must their children.
+ if (on) {
+ setAttribute(Qt::WA_NativeWindow);
+ d->enforceNativeChildren();
+ }
+#endif
+ // fall through
+ case Qt::WA_OpaquePaintEvent:
+ d->updateIsOpaque();
+ break;
+ case Qt::WA_NoSystemBackground:
+ d->updateIsOpaque();
+ // fall through...
+ case Qt::WA_UpdatesDisabled:
+ d->updateSystemBackground();
+ break;
+ case Qt::WA_TransparentForMouseEvents:
+#ifdef Q_WS_MAC
+ d->macUpdateIgnoreMouseEvents();
+#endif
+ break;
+ case Qt::WA_InputMethodEnabled: {
+#ifndef QT_NO_IM
+ QWidget *focusWidget = d->effectiveFocusWidget();
+ QInputContext *ic = focusWidget->d_func()->assignedInputContext();
+ if (!ic && (!on || hasFocus()))
+ ic = focusWidget->d_func()->inputContext();
+ if (ic) {
+ if (on && hasFocus() && ic->focusWidget() != focusWidget && isEnabled()
+ && focusWidget->testAttribute(Qt::WA_InputMethodEnabled)) {
+ ic->setFocusWidget(focusWidget);
+ } else if (!on && ic->focusWidget() == focusWidget) {
+ ic->reset();
+ ic->setFocusWidget(0);
+ }
+ }
+#endif //QT_NO_IM
+ break;
+ }
+ case Qt::WA_WindowPropagation:
+ d->resolvePalette();
+ d->resolveFont();
+ d->resolveLocale();
+ break;
+#ifdef Q_WS_X11
+ case Qt::WA_NoX11EventCompression:
+ if (!d->extra)
+ d->createExtra();
+ d->extra->compress_events = on;
+ break;
+ case Qt::WA_X11OpenGLOverlay:
+ d->updateIsOpaque();
+ break;
+ case Qt::WA_X11DoNotAcceptFocus:
+ if (testAttribute(Qt::WA_WState_Created))
+ d->updateX11AcceptFocus();
+ break;
+#endif
+ case Qt::WA_DontShowOnScreen: {
+ if (on && isVisible()) {
+ // Make sure we keep the current state and only hide the widget
+ // from the desktop. show_sys will only update platform specific
+ // attributes at this point.
+ d->hide_sys();
+ d->show_sys();
+ }
+ break;
+ }
+
+#ifdef Q_WS_X11
+ case Qt::WA_X11NetWmWindowTypeDesktop:
+ case Qt::WA_X11NetWmWindowTypeDock:
+ case Qt::WA_X11NetWmWindowTypeToolBar:
+ case Qt::WA_X11NetWmWindowTypeMenu:
+ case Qt::WA_X11NetWmWindowTypeUtility:
+ case Qt::WA_X11NetWmWindowTypeSplash:
+ case Qt::WA_X11NetWmWindowTypeDialog:
+ case Qt::WA_X11NetWmWindowTypeDropDownMenu:
+ case Qt::WA_X11NetWmWindowTypePopupMenu:
+ case Qt::WA_X11NetWmWindowTypeToolTip:
+ case Qt::WA_X11NetWmWindowTypeNotification:
+ case Qt::WA_X11NetWmWindowTypeCombo:
+ case Qt::WA_X11NetWmWindowTypeDND:
+ if (testAttribute(Qt::WA_WState_Created))
+ d->setNetWmWindowTypes();
+ break;
+#endif
+
+ case Qt::WA_StaticContents:
+ if (QWidgetBackingStore *bs = d->maybeBackingStore()) {
+ if (on)
+ bs->addStaticWidget(this);
+ else
+ bs->removeStaticWidget(this);
+ }
+ break;
+ case Qt::WA_TranslucentBackground:
+ if (on) {
+ setAttribute(Qt::WA_NoSystemBackground);
+ d->updateIsTranslucent();
+ }
+
+ break;
+ case Qt::WA_AcceptTouchEvents:
+#if defined(Q_WS_WIN) || defined(Q_WS_MAC) || defined(Q_OS_SYMBIAN)
+ if (on)
+ d->registerTouchWindow();
+#endif
+ break;
+ case Qt::WA_LockPortraitOrientation:
+ case Qt::WA_LockLandscapeOrientation:
+ case Qt::WA_AutoOrientation: {
+ const Qt::WidgetAttribute orientations[3] = {
+ Qt::WA_LockPortraitOrientation,
+ Qt::WA_LockLandscapeOrientation,
+ Qt::WA_AutoOrientation
+ };
+
+ if (on) {
+ // We can only have one of these set at a time
+ for (int i = 0; i < 3; ++i) {
+ if (orientations[i] != attribute)
+ setAttribute_internal(orientations[i], false, data, d);
+ }
+ }
+
+#ifdef Q_WS_S60
+ CAknAppUiBase* appUi = static_cast<CAknAppUiBase*>(CEikonEnv::Static()->EikAppUi());
+ const CAknAppUiBase::TAppUiOrientation s60orientations[] = {
+ CAknAppUiBase::EAppUiOrientationPortrait,
+ CAknAppUiBase::EAppUiOrientationLandscape,
+ CAknAppUiBase::EAppUiOrientationAutomatic
+ };
+ CAknAppUiBase::TAppUiOrientation s60orientation = CAknAppUiBase::EAppUiOrientationUnspecified;
+ for (int i = 0; i < 3; ++i) {
+ if (testAttribute(orientations[i])) {
+ s60orientation = s60orientations[i];
+ break;
+ }
+ }
+ QT_TRAP_THROWING(appUi->SetOrientationL(s60orientation));
+ S60->orientationSet = true;
+ QSymbianControl *window = static_cast<QSymbianControl *>(internalWinId());
+ if (window)
+ window->ensureFixNativeOrientation();
+#endif
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+/*! \fn bool QWidget::testAttribute(Qt::WidgetAttribute attribute) const
+
+ Returns true if attribute \a attribute is set on this widget;
+ otherwise returns false.
+
+ \sa setAttribute()
+ */
+bool QWidget::testAttribute_helper(Qt::WidgetAttribute attribute) const
+{
+ Q_D(const QWidget);
+ const int x = attribute - 8*sizeof(uint);
+ const int int_off = x / (8*sizeof(uint));
+ return (d->high_attributes[int_off] & (1<<(x-(int_off*8*sizeof(uint)))));
+}
+
+/*!
+ \property QWidget::windowOpacity
+
+ \brief The level of opacity for the window.
+
+ The valid range of opacity is from 1.0 (completely opaque) to
+ 0.0 (completely transparent).
+
+ By default the value of this property is 1.0.
+
+ This feature is available on Embedded Linux, Mac OS X, Windows,
+ and X11 platforms that support the Composite extension.
+
+ This feature is not available on Windows CE.
+
+ Note that under X11 you need to have a composite manager running,
+ and the X11 specific _NET_WM_WINDOW_OPACITY atom needs to be
+ supported by the window manager you are using.
+
+ \warning Changing this property from opaque to transparent might issue a
+ paint event that needs to be processed before the window is displayed
+ correctly. This affects mainly the use of QPixmap::grabWindow(). Also note
+ that semi-transparent windows update and resize significantly slower than
+ opaque windows.
+
+ \sa setMask()
+*/
+qreal QWidget::windowOpacity() const
+{
+ Q_D(const QWidget);
+ return (isWindow() && d->maybeTopData()) ? d->maybeTopData()->opacity / 255. : 1.0;
+}
+
+void QWidget::setWindowOpacity(qreal opacity)
+{
+ Q_D(QWidget);
+ if (!isWindow())
+ return;
+
+ opacity = qBound(qreal(0.0), opacity, qreal(1.0));
+ QTLWExtra *extra = d->topData();
+ extra->opacity = uint(opacity * 255);
+ setAttribute(Qt::WA_WState_WindowOpacitySet);
+
+ if (!testAttribute(Qt::WA_WState_Created))
+ return;
+
+#ifndef QT_NO_GRAPHICSVIEW
+ if (QGraphicsProxyWidget *proxy = graphicsProxyWidget()) {
+ // Avoid invalidating the cache if set.
+ if (proxy->cacheMode() == QGraphicsItem::NoCache)
+ proxy->update();
+ else if (QGraphicsScene *scene = proxy->scene())
+ scene->update(proxy->sceneBoundingRect());
+ return;
+ }
+#endif
+
+ d->setWindowOpacity_sys(opacity);
+}
+
+/*!
+ \property QWidget::windowModified
+ \brief whether the document shown in the window has unsaved changes
+
+ A modified window is a window whose content has changed but has
+ not been saved to disk. This flag will have different effects
+ varied by the platform. On Mac OS X the close button will have a
+ modified look; on other platforms, the window title will have an
+ '*' (asterisk).
+
+ The window title must contain a "[*]" placeholder, which
+ indicates where the '*' should appear. Normally, it should appear
+ right after the file name (e.g., "document1.txt[*] - Text
+ Editor"). If the window isn't modified, the placeholder is simply
+ removed.
+
+ Note that if a widget is set as modified, all its ancestors will
+ also be set as modified. However, if you call \c
+ {setWindowModified(false)} on a widget, this will not propagate to
+ its parent because other children of the parent might have been
+ modified.
+
+ \sa windowTitle, {Application Example}, {SDI Example}, {MDI Example}
+*/
+bool QWidget::isWindowModified() const
+{
+ return testAttribute(Qt::WA_WindowModified);
+}
+
+void QWidget::setWindowModified(bool mod)
+{
+ Q_D(QWidget);
+ setAttribute(Qt::WA_WindowModified, mod);
+
+#ifndef Q_WS_MAC
+ if (!windowTitle().contains(QLatin1String("[*]")) && mod)
+ qWarning("QWidget::setWindowModified: The window title does not contain a '[*]' placeholder");
+#endif
+ d->setWindowTitle_helper(windowTitle());
+ d->setWindowIconText_helper(windowIconText());
+#ifdef Q_WS_MAC
+ d->setWindowModified_sys(mod);
+#endif
+
+ QEvent e(QEvent::ModifiedChange);
+ QApplication::sendEvent(this, &e);
+}
+
+#ifndef QT_NO_TOOLTIP
+/*!
+ \property QWidget::toolTip
+
+ \brief the widget's tooltip
+
+ Note that by default tooltips are only shown for widgets that are
+ children of the active window. You can change this behavior by
+ setting the attribute Qt::WA_AlwaysShowToolTips on the \e window,
+ not on the widget with the tooltip.
+
+ If you want to control a tooltip's behavior, you can intercept the
+ event() function and catch the QEvent::ToolTip event (e.g., if you
+ want to customize the area for which the tooltip should be shown).
+
+ By default, this property contains an empty string.
+
+ \sa QToolTip statusTip whatsThis
+*/
+void QWidget::setToolTip(const QString &s)
+{
+ Q_D(QWidget);
+ d->toolTip = s;
+
+ QEvent event(QEvent::ToolTipChange);
+ QApplication::sendEvent(this, &event);
+}
+
+QString QWidget::toolTip() const
+{
+ Q_D(const QWidget);
+ return d->toolTip;
+}
+#endif // QT_NO_TOOLTIP
+
+
+#ifndef QT_NO_STATUSTIP
+/*!
+ \property QWidget::statusTip
+ \brief the widget's status tip
+
+ By default, this property contains an empty string.
+
+ \sa toolTip whatsThis
+*/
+void QWidget::setStatusTip(const QString &s)
+{
+ Q_D(QWidget);
+ d->statusTip = s;
+}
+
+QString QWidget::statusTip() const
+{
+ Q_D(const QWidget);
+ return d->statusTip;
+}
+#endif // QT_NO_STATUSTIP
+
+#ifndef QT_NO_WHATSTHIS
+/*!
+ \property QWidget::whatsThis
+
+ \brief the widget's What's This help text.
+
+ By default, this property contains an empty string.
+
+ \sa QWhatsThis QWidget::toolTip QWidget::statusTip
+*/
+void QWidget::setWhatsThis(const QString &s)
+{
+ Q_D(QWidget);
+ d->whatsThis = s;
+}
+
+QString QWidget::whatsThis() const
+{
+ Q_D(const QWidget);
+ return d->whatsThis;
+}
+#endif // QT_NO_WHATSTHIS
+
+#ifndef QT_NO_ACCESSIBILITY
+/*!
+ \property QWidget::accessibleName
+
+ \brief the widget's name as seen by assistive technologies
+
+ This property is used by accessible clients to identify, find, or announce
+ the widget for accessible clients.
+
+ By default, this property contains an empty string.
+
+ \sa QAccessibleInterface::text()
+*/
+void QWidget::setAccessibleName(const QString &name)
+{
+ Q_D(QWidget);
+ d->accessibleName = name;
+ QAccessible::updateAccessibility(this, 0, QAccessible::NameChanged);
+}
+
+QString QWidget::accessibleName() const
+{
+ Q_D(const QWidget);
+ return d->accessibleName;
+}
+
+/*!
+ \property QWidget::accessibleDescription
+
+ \brief the widget's description as seen by assistive technologies
+
+ By default, this property contains an empty string.
+
+ \sa QAccessibleInterface::text()
+*/
+void QWidget::setAccessibleDescription(const QString &description)
+{
+ Q_D(QWidget);
+ d->accessibleDescription = description;
+ QAccessible::updateAccessibility(this, 0, QAccessible::DescriptionChanged);
+}
+
+QString QWidget::accessibleDescription() const
+{
+ Q_D(const QWidget);
+ return d->accessibleDescription;
+}
+#endif // QT_NO_ACCESSIBILITY
+
+#ifndef QT_NO_SHORTCUT
+/*!
+ Adds a shortcut to Qt's shortcut system that watches for the given
+ \a key sequence in the given \a context. If the \a context is
+ Qt::ApplicationShortcut, the shortcut applies to the application as a
+ whole. Otherwise, it is either local to this widget, Qt::WidgetShortcut,
+ or to the window itself, Qt::WindowShortcut.
+
+ If the same \a key sequence has been grabbed by several widgets,
+ when the \a key sequence occurs a QEvent::Shortcut event is sent
+ to all the widgets to which it applies in a non-deterministic
+ order, but with the ``ambiguous'' flag set to true.
+
+ \warning You should not normally need to use this function;
+ instead create \l{QAction}s with the shortcut key sequences you
+ require (if you also want equivalent menu options and toolbar
+ buttons), or create \l{QShortcut}s if you just need key sequences.
+ Both QAction and QShortcut handle all the event filtering for you,
+ and provide signals which are triggered when the user triggers the
+ key sequence, so are much easier to use than this low-level
+ function.
+
+ \sa releaseShortcut() setShortcutEnabled()
+*/
+int QWidget::grabShortcut(const QKeySequence &key, Qt::ShortcutContext context)
+{
+ Q_ASSERT(qApp);
+ if (key.isEmpty())
+ return 0;
+ setAttribute(Qt::WA_GrabbedShortcut);
+ return qApp->d_func()->shortcutMap.addShortcut(this, key, context);
+}
+
+/*!
+ Removes the shortcut with the given \a id from Qt's shortcut
+ system. The widget will no longer receive QEvent::Shortcut events
+ for the shortcut's key sequence (unless it has other shortcuts
+ with the same key sequence).
+
+ \warning You should not normally need to use this function since
+ Qt's shortcut system removes shortcuts automatically when their
+ parent widget is destroyed. It is best to use QAction or
+ QShortcut to handle shortcuts, since they are easier to use than
+ this low-level function. Note also that this is an expensive
+ operation.
+
+ \sa grabShortcut() setShortcutEnabled()
+*/
+void QWidget::releaseShortcut(int id)
+{
+ Q_ASSERT(qApp);
+ if (id)
+ qApp->d_func()->shortcutMap.removeShortcut(id, this, 0);
+}
+
+/*!
+ If \a enable is true, the shortcut with the given \a id is
+ enabled; otherwise the shortcut is disabled.
+
+ \warning You should not normally need to use this function since
+ Qt's shortcut system enables/disables shortcuts automatically as
+ widgets become hidden/visible and gain or lose focus. It is best
+ to use QAction or QShortcut to handle shortcuts, since they are
+ easier to use than this low-level function.
+
+ \sa grabShortcut() releaseShortcut()
+*/
+void QWidget::setShortcutEnabled(int id, bool enable)
+{
+ Q_ASSERT(qApp);
+ if (id)
+ qApp->d_func()->shortcutMap.setShortcutEnabled(enable, id, this, 0);
+}
+
+/*!
+ \since 4.2
+
+ If \a enable is true, auto repeat of the shortcut with the
+ given \a id is enabled; otherwise it is disabled.
+
+ \sa grabShortcut() releaseShortcut()
+*/
+void QWidget::setShortcutAutoRepeat(int id, bool enable)
+{
+ Q_ASSERT(qApp);
+ if (id)
+ qApp->d_func()->shortcutMap.setShortcutAutoRepeat(enable, id, this, 0);
+}
+#endif // QT_NO_SHORTCUT
+/*!
+ Updates the widget's micro focus.
+
+ \sa QInputContext
+*/
+void QWidget::updateMicroFocus()
+{
+ Q_D(QWidget);
+ // and optimization to update input context only it has already been created.
+ if (d->assignedInputContext() || qApp->d_func()->inputContext) {
+ QInputContext *ic = inputContext();
+ if (ic)
+ ic->update();
+ }
+#ifndef QT_NO_ACCESSIBILITY
+ if (isVisible()) {
+ // ##### is this correct
+ QAccessible::updateAccessibility(this, 0, QAccessible::StateChanged);
+ }
+#endif
+}
+
+
+#if defined (Q_WS_WIN)
+/*!
+ Returns the window system handle of the widget, for low-level
+ access. Using this function is not portable.
+
+ An HDC acquired with getDC() has to be released with releaseDC().
+
+ \warning Using this function is not portable.
+*/
+HDC QWidget::getDC() const
+{
+ Q_D(const QWidget);
+ if (d->hd)
+ return (HDC) d->hd;
+ return GetDC(winId());
+}
+
+/*!
+ Releases the HDC \a hdc acquired by a previous call to getDC().
+
+ \warning Using this function is not portable.
+*/
+void QWidget::releaseDC(HDC hdc) const
+{
+ Q_D(const QWidget);
+ // If its the widgets own dc, it will be released elsewhere. If
+ // its a different HDC we release it and issue a warning if it
+ // fails.
+ if (hdc != d->hd && !ReleaseDC(winId(), hdc))
+ qErrnoWarning("QWidget::releaseDC(): failed to release HDC");
+}
+#else
+/*!
+ Returns the window system handle of the widget, for low-level
+ access. Using this function is not portable.
+
+ The HANDLE type varies with platform; see \c qwindowdefs.h for
+ details.
+*/
+Qt::HANDLE QWidget::handle() const
+{
+ Q_D(const QWidget);
+ if (!internalWinId() && testAttribute(Qt::WA_WState_Created))
+ (void)winId(); // enforce native window
+ return d->hd;
+}
+#endif
+
+
+/*!
+ Raises this widget to the top of the parent widget's stack.
+
+ After this call the widget will be visually in front of any
+ overlapping sibling widgets.
+
+ \note When using activateWindow(), you can call this function to
+ ensure that the window is stacked on top.
+
+ \sa lower(), stackUnder()
+*/
+
+void QWidget::raise()
+{
+ Q_D(QWidget);
+ if (!isWindow()) {
+ QWidget *p = parentWidget();
+ const int parentChildCount = p->d_func()->children.size();
+ if (parentChildCount < 2)
+ return;
+ const int from = p->d_func()->children.indexOf(this);
+ Q_ASSERT(from >= 0);
+ // Do nothing if the widget is already in correct stacking order _and_ created.
+ if (from != parentChildCount -1)
+ p->d_func()->children.move(from, parentChildCount - 1);
+ if (!testAttribute(Qt::WA_WState_Created) && p->testAttribute(Qt::WA_WState_Created))
+ create();
+ else if (from == parentChildCount - 1)
+ return;
+
+ QRegion region(rect());
+ d->subtractOpaqueSiblings(region);
+ d->invalidateBuffer(region);
+ }
+ if (testAttribute(Qt::WA_WState_Created))
+ d->raise_sys();
+
+ QEvent e(QEvent::ZOrderChange);
+ QApplication::sendEvent(this, &e);
+}
+
+/*!
+ Lowers the widget to the bottom of the parent widget's stack.
+
+ After this call the widget will be visually behind (and therefore
+ obscured by) any overlapping sibling widgets.
+
+ \sa raise(), stackUnder()
+*/
+
+void QWidget::lower()
+{
+ Q_D(QWidget);
+ if (!isWindow()) {
+ QWidget *p = parentWidget();
+ const int parentChildCount = p->d_func()->children.size();
+ if (parentChildCount < 2)
+ return;
+ const int from = p->d_func()->children.indexOf(this);
+ Q_ASSERT(from >= 0);
+ // Do nothing if the widget is already in correct stacking order _and_ created.
+ if (from != 0)
+ p->d_func()->children.move(from, 0);
+ if (!testAttribute(Qt::WA_WState_Created) && p->testAttribute(Qt::WA_WState_Created))
+ create();
+ else if (from == 0)
+ return;
+ }
+ if (testAttribute(Qt::WA_WState_Created))
+ d->lower_sys();
+
+ QEvent e(QEvent::ZOrderChange);
+ QApplication::sendEvent(this, &e);
+}
+
+
+/*!
+ Places the widget under \a w in the parent widget's stack.
+
+ To make this work, the widget itself and \a w must be siblings.
+
+ \sa raise(), lower()
+*/
+void QWidget::stackUnder(QWidget* w)
+{
+ Q_D(QWidget);
+ QWidget *p = parentWidget();
+ if (!w || isWindow() || p != w->parentWidget() || this == w)
+ return;
+ if (p) {
+ int from = p->d_func()->children.indexOf(this);
+ int to = p->d_func()->children.indexOf(w);
+ Q_ASSERT(from >= 0);
+ Q_ASSERT(to >= 0);
+ if (from < to)
+ --to;
+ // Do nothing if the widget is already in correct stacking order _and_ created.
+ if (from != to)
+ p->d_func()->children.move(from, to);
+ if (!testAttribute(Qt::WA_WState_Created) && p->testAttribute(Qt::WA_WState_Created))
+ create();
+ else if (from == to)
+ return;
+ }
+ if (testAttribute(Qt::WA_WState_Created))
+ d->stackUnder_sys(w);
+
+ QEvent e(QEvent::ZOrderChange);
+ QApplication::sendEvent(this, &e);
+}
+
+void QWidget::styleChange(QStyle&) { }
+void QWidget::enabledChange(bool) { } // compat
+void QWidget::paletteChange(const QPalette &) { } // compat
+void QWidget::fontChange(const QFont &) { } // compat
+void QWidget::windowActivationChange(bool) { } // compat
+void QWidget::languageChange() { } // compat
+
+
+/*!
+ \enum QWidget::BackgroundOrigin
+
+ \compat
+
+ \value WidgetOrigin
+ \value ParentOrigin
+ \value WindowOrigin
+ \value AncestorOrigin
+
+*/
+
+/*!
+ \fn bool QWidget::isVisibleToTLW() const
+
+ Use isVisible() instead.
+*/
+
+/*!
+ \fn void QWidget::iconify()
+
+ Use showMinimized() instead.
+*/
+
+/*!
+ \fn void QWidget::constPolish() const
+
+ Use ensurePolished() instead.
+*/
+
+/*!
+ \fn void QWidget::reparent(QWidget *parent, Qt::WindowFlags f, const QPoint &p, bool showIt)
+
+ Use setParent() to change the parent or the widget's widget flags;
+ use move() to move the widget, and use show() to show the widget.
+*/
+
+/*!
+ \fn void QWidget::reparent(QWidget *parent, const QPoint &p, bool showIt)
+
+ Use setParent() to change the parent; use move() to move the
+ widget, and use show() to show the widget.
+*/
+
+/*!
+ \fn void QWidget::recreate(QWidget *parent, Qt::WindowFlags f, const QPoint & p, bool showIt)
+
+ Use setParent() to change the parent or the widget's widget flags;
+ use move() to move the widget, and use show() to show the widget.
+*/
+
+/*!
+ \fn bool QWidget::hasMouse() const
+
+ Use testAttribute(Qt::WA_UnderMouse) instead.
+*/
+
+/*!
+ \fn bool QWidget::ownCursor() const
+
+ Use testAttribute(Qt::WA_SetCursor) instead.
+*/
+
+/*!
+ \fn bool QWidget::ownFont() const
+
+ Use testAttribute(Qt::WA_SetFont) instead.
+*/
+
+/*!
+ \fn void QWidget::unsetFont()
+
+ Use setFont(QFont()) instead.
+*/
+
+/*!
+ \fn bool QWidget::ownPalette() const
+
+ Use testAttribute(Qt::WA_SetPalette) instead.
+*/
+
+/*!
+ \fn void QWidget::unsetPalette()
+
+ Use setPalette(QPalette()) instead.
+*/
+
+/*!
+ \fn void QWidget::setEraseColor(const QColor &color)
+
+ Use the palette instead.
+
+ \oldcode
+ widget->setEraseColor(color);
+ \newcode
+ QPalette palette;
+ palette.setColor(widget->backgroundRole(), color);
+ widget->setPalette(palette);
+ \endcode
+*/
+
+/*!
+ \fn void QWidget::setErasePixmap(const QPixmap &pixmap)
+
+ Use the palette instead.
+
+ \oldcode
+ widget->setErasePixmap(pixmap);
+ \newcode
+ QPalette palette;
+ palette.setBrush(widget->backgroundRole(), QBrush(pixmap));
+ widget->setPalette(palette);
+ \endcode
+*/
+
+/*!
+ \fn void QWidget::setPaletteForegroundColor(const QColor &color)
+
+ Use the palette directly.
+
+ \oldcode
+ widget->setPaletteForegroundColor(color);
+ \newcode
+ QPalette palette;
+ palette.setColor(widget->foregroundRole(), color);
+ widget->setPalette(palette);
+ \endcode
+*/
+
+/*!
+ \fn void QWidget::setPaletteBackgroundColor(const QColor &color)
+
+ Use the palette directly.
+
+ \oldcode
+ widget->setPaletteBackgroundColor(color);
+ \newcode
+ QPalette palette;
+ palette.setColor(widget->backgroundRole(), color);
+ widget->setPalette(palette);
+ \endcode
+*/
+
+/*!
+ \fn void QWidget::setPaletteBackgroundPixmap(const QPixmap &pixmap)
+
+ Use the palette directly.
+
+ \oldcode
+ widget->setPaletteBackgroundPixmap(pixmap);
+ \newcode
+ QPalette palette;
+ palette.setBrush(widget->backgroundRole(), QBrush(pixmap));
+ widget->setPalette(palette);
+ \endcode
+*/
+
+/*!
+ \fn void QWidget::setBackgroundPixmap(const QPixmap &pixmap)
+
+ Use the palette instead.
+
+ \oldcode
+ widget->setBackgroundPixmap(pixmap);
+ \newcode
+ QPalette palette;
+ palette.setBrush(widget->backgroundRole(), QBrush(pixmap));
+ widget->setPalette(palette);
+ \endcode
+*/
+
+/*!
+ \fn void QWidget::setBackgroundColor(const QColor &color)
+
+ Use the palette instead.
+
+ \oldcode
+ widget->setBackgroundColor(color);
+ \newcode
+ QPalette palette;
+ palette.setColor(widget->backgroundRole(), color);
+ widget->setPalette(palette);
+ \endcode
+*/
+
+
+/*!
+ \fn QWidget *QWidget::parentWidget(bool sameWindow) const
+
+ Use the no-argument overload instead.
+*/
+
+/*!
+ \fn void QWidget::setKeyCompression(bool b)
+
+ Use setAttribute(Qt::WA_KeyCompression, b) instead.
+*/
+
+/*!
+ \fn void QWidget::setFont(const QFont &f, bool b)
+
+ Use the single-argument overload instead.
+*/
+
+/*!
+ \fn void QWidget::setPalette(const QPalette &p, bool b)
+
+ Use the single-argument overload instead.
+*/
+
+/*!
+ \fn void QWidget::setBackgroundOrigin(BackgroundOrigin background)
+
+ \obsolete
+*/
+
+/*!
+ \fn BackgroundOrigin QWidget::backgroundOrigin() const
+
+ \obsolete
+
+ Always returns \c WindowOrigin.
+*/
+
+/*!
+ \fn QPoint QWidget::backgroundOffset() const
+
+ \obsolete
+
+ Always returns QPoint().
+*/
+
+/*!
+ \fn void QWidget::repaint(bool b)
+
+ The boolean parameter \a b is ignored. Use the no-argument overload instead.
+*/
+
+/*!
+ \fn void QWidget::repaint(int x, int y, int w, int h, bool b)
+
+ The boolean parameter \a b is ignored. Use the four-argument overload instead.
+*/
+
+/*!
+ \fn void QWidget::repaint(const QRect &r, bool b)
+
+ The boolean parameter \a b is ignored. Use the single rect-argument overload instead.
+*/
+
+/*!
+ \fn void QWidget::repaint(const QRegion &rgn, bool b)
+
+ The boolean parameter \a b is ignored. Use the single region-argument overload instead.
+*/
+
+/*!
+ \fn void QWidget::erase()
+
+ Drawing may only take place in a QPaintEvent. Overload
+ paintEvent() to do your erasing and call update() to schedule a
+ replaint whenever necessary. See also QPainter.
+*/
+
+/*!
+ \fn void QWidget::erase(int x, int y, int w, int h)
+
+ Drawing may only take place in a QPaintEvent. Overload
+ paintEvent() to do your erasing and call update() to schedule a
+ replaint whenever necessary. See also QPainter.
+*/
+
+/*!
+ \fn void QWidget::erase(const QRect &rect)
+
+ Drawing may only take place in a QPaintEvent. Overload
+ paintEvent() to do your erasing and call update() to schedule a
+ replaint whenever necessary. See also QPainter.
+*/
+
+/*!
+ \fn void QWidget::drawText(const QPoint &p, const QString &s)
+
+ Drawing may only take place in a QPaintEvent. Overload
+ paintEvent() to do your drawing and call update() to schedule a
+ replaint whenever necessary. See also QPainter.
+*/
+
+/*!
+ \fn void QWidget::drawText(int x, int y, const QString &s)
+
+ Drawing may only take place in a QPaintEvent. Overload
+ paintEvent() to do your drawing and call update() to schedule a
+ replaint whenever necessary. See also QPainter.
+*/
+
+/*!
+ \fn QWidget *QWidget::childAt(const QPoint &p, bool includeThis) const
+
+ Use the single point argument overload instead.
+*/
+
+/*!
+ \fn void QWidget::setCaption(const QString &c)
+
+ Use setWindowTitle() instead.
+*/
+
+/*!
+ \fn void QWidget::setIcon(const QPixmap &i)
+
+ Use setWindowIcon() instead.
+*/
+
+/*!
+ \fn void QWidget::setIconText(const QString &it)
+
+ Use setWindowIconText() instead.
+*/
+
+/*!
+ \fn QString QWidget::caption() const
+
+ Use windowTitle() instead.
+*/
+
+/*!
+ \fn QString QWidget::iconText() const
+
+ Use windowIconText() instead.
+*/
+
+/*!
+ \fn bool QWidget::isTopLevel() const
+ \obsolete
+
+ Use isWindow() instead.
+*/
+
+/*!
+ \fn bool QWidget::isRightToLeft() const
+ \internal
+*/
+
+/*!
+ \fn bool QWidget::isLeftToRight() const
+ \internal
+*/
+
+/*!
+ \fn void QWidget::setInputMethodEnabled(bool enabled)
+
+ Use setAttribute(Qt::WA_InputMethodEnabled, \a enabled) instead.
+*/
+
+/*!
+ \fn bool QWidget::isInputMethodEnabled() const
+
+ Use testAttribute(Qt::WA_InputMethodEnabled) instead.
+*/
+
+/*!
+ \fn void QWidget::setActiveWindow()
+
+ Use activateWindow() instead.
+*/
+
+/*!
+ \fn bool QWidget::isShown() const
+
+ Use !isHidden() instead (notice the exclamation mark), or use isVisible() to check whether the widget is visible.
+*/
+
+/*!
+ \fn bool QWidget::isDialog() const
+
+ Use windowType() == Qt::Dialog instead.
+*/
+
+/*!
+ \fn bool QWidget::isPopup() const
+
+ Use windowType() == Qt::Popup instead.
+*/
+
+/*!
+ \fn bool QWidget::isDesktop() const
+
+ Use windowType() == Qt::Desktop instead.
+*/
+
+/*!
+ \fn void QWidget::polish()
+
+ Use ensurePolished() instead.
+*/
+
+/*!
+ \fn QWidget *QWidget::childAt(int x, int y, bool includeThis) const
+
+ Use the childAt() overload that doesn't have an \a includeThis parameter.
+
+ \oldcode
+ return widget->childAt(x, y, true);
+ \newcode
+ QWidget *child = widget->childAt(x, y, true);
+ if (child)
+ return child;
+ if (widget->rect().contains(x, y))
+ return widget;
+ \endcode
+*/
+
+/*!
+ \fn void QWidget::setSizePolicy(QSizePolicy::Policy hor, QSizePolicy::Policy ver, bool hfw)
+ \compat
+
+ Use the \l sizePolicy property and heightForWidth() function instead.
+*/
+
+/*!
+ \fn bool QWidget::isUpdatesEnabled() const
+ \compat
+
+ Use the \l updatesEnabled property instead.
+*/
+
+/*!
+ \macro QWIDGETSIZE_MAX
+ \relates QWidget
+
+ Defines the maximum size for a QWidget object.
+
+ The largest allowed size for a widget is QSize(QWIDGETSIZE_MAX,
+ QWIDGETSIZE_MAX), i.e. QSize (16777215,16777215).
+
+ \sa QWidget::setMaximumSize()
+*/
+
+/*!
+ \fn QWidget::setupUi(QWidget *widget)
+
+ Sets up the user interface for the specified \a widget.
+
+ \note This function is available with widgets that derive from user
+ interface descriptions created using \l{uic}.
+
+ \sa {Using a Designer UI File in Your Application}
+*/
+
+QRect QWidgetPrivate::frameStrut() const
+{
+ Q_Q(const QWidget);
+ if (!q->isWindow() || (q->windowType() == Qt::Desktop) || q->testAttribute(Qt::WA_DontShowOnScreen)) {
+ // x2 = x1 + w - 1, so w/h = 1
+ return QRect(0, 0, 1, 1);
+ }
+
+ if (data.fstrut_dirty
+#ifndef Q_WS_WIN
+ // ### Fix properly for 4.3
+ && q->isVisible()
+#endif
+ && q->testAttribute(Qt::WA_WState_Created))
+ const_cast<QWidgetPrivate *>(this)->updateFrameStrut();
+
+ return maybeTopData() ? maybeTopData()->frameStrut : QRect();
+}
+
+#ifdef QT_KEYPAD_NAVIGATION
+/*!
+ \internal
+
+ Changes the focus from the current focusWidget to a widget in
+ the \a direction.
+
+ Returns true, if there was a widget in that direction
+*/
+bool QWidgetPrivate::navigateToDirection(Direction direction)
+{
+ QWidget *targetWidget = widgetInNavigationDirection(direction);
+ if (targetWidget)
+ targetWidget->setFocus();
+ return (targetWidget != 0);
+}
+
+/*!
+ \internal
+
+ Searches for a widget that is positioned in the \a direction, starting
+ from the current focusWidget.
+
+ Returns the pointer to a found widget or 0, if there was no widget in
+ that direction.
+*/
+QWidget *QWidgetPrivate::widgetInNavigationDirection(Direction direction)
+{
+ const QWidget *sourceWidget = QApplication::focusWidget();
+ if (!sourceWidget)
+ return 0;
+ const QRect sourceRect = sourceWidget->rect().translated(sourceWidget->mapToGlobal(QPoint()));
+ const int sourceX =
+ (direction == DirectionNorth || direction == DirectionSouth) ?
+ (sourceRect.left() + (sourceRect.right() - sourceRect.left()) / 2)
+ :(direction == DirectionEast ? sourceRect.right() : sourceRect.left());
+ const int sourceY =
+ (direction == DirectionEast || direction == DirectionWest) ?
+ (sourceRect.top() + (sourceRect.bottom() - sourceRect.top()) / 2)
+ :(direction == DirectionSouth ? sourceRect.bottom() : sourceRect.top());
+ const QPoint sourcePoint(sourceX, sourceY);
+ const QPoint sourceCenter = sourceRect.center();
+ const QWidget *sourceWindow = sourceWidget->window();
+
+ QWidget *targetWidget = 0;
+ int shortestDistance = INT_MAX;
+ foreach(QWidget *targetCandidate, QApplication::allWidgets()) {
+
+ const QRect targetCandidateRect = targetCandidate->rect().translated(targetCandidate->mapToGlobal(QPoint()));
+
+ // For focus proxies, the child widget handling the focus can have keypad navigation focus,
+ // but the owner of the proxy cannot.
+ // Additionally, empty widgets should be ignored.
+ if (targetCandidate->focusProxy() || targetCandidateRect.isEmpty())
+ continue;
+
+ // Only navigate to a target widget that...
+ if ( targetCandidate != sourceWidget
+ // ...takes the focus,
+ && targetCandidate->focusPolicy() & Qt::TabFocus
+ // ...is above if DirectionNorth,
+ && !(direction == DirectionNorth && targetCandidateRect.bottom() > sourceRect.top())
+ // ...is on the right if DirectionEast,
+ && !(direction == DirectionEast && targetCandidateRect.left() < sourceRect.right())
+ // ...is below if DirectionSouth,
+ && !(direction == DirectionSouth && targetCandidateRect.top() < sourceRect.bottom())
+ // ...is on the left if DirectionWest,
+ && !(direction == DirectionWest && targetCandidateRect.right() > sourceRect.left())
+ // ...is enabled,
+ && targetCandidate->isEnabled()
+ // ...is visible,
+ && targetCandidate->isVisible()
+ // ...is in the same window,
+ && targetCandidate->window() == sourceWindow) {
+ const int targetCandidateDistance = pointToRect(sourcePoint, targetCandidateRect);
+ if (targetCandidateDistance < shortestDistance) {
+ shortestDistance = targetCandidateDistance;
+ targetWidget = targetCandidate;
+ }
+ }
+ }
+ return targetWidget;
+}
+
+/*!
+ \internal
+
+ Tells us if it there is currently a reachable widget by keypad navigation in
+ a certain \a orientation.
+ If no navigation is possible, occurring key events in that \a orientation may
+ be used to interact with the value in the focused widget, even though it
+ currently has not the editFocus.
+
+ \sa QWidgetPrivate::widgetInNavigationDirection(), QWidget::hasEditFocus()
+*/
+bool QWidgetPrivate::canKeypadNavigate(Qt::Orientation orientation)
+{
+ return orientation == Qt::Horizontal?
+ (QWidgetPrivate::widgetInNavigationDirection(QWidgetPrivate::DirectionEast)
+ || QWidgetPrivate::widgetInNavigationDirection(QWidgetPrivate::DirectionWest))
+ :(QWidgetPrivate::widgetInNavigationDirection(QWidgetPrivate::DirectionNorth)
+ || QWidgetPrivate::widgetInNavigationDirection(QWidgetPrivate::DirectionSouth));
+}
+/*!
+ \internal
+
+ Checks, if the \a widget is inside a QTabWidget. If is is inside
+ one, left/right key events will be used to switch between tabs in keypad
+ navigation. If there is no QTabWidget, the horizontal key events can be used
+to
+ interact with the value in the focused widget, even though it currently has
+ not the editFocus.
+
+ \sa QWidget::hasEditFocus()
+*/
+bool QWidgetPrivate::inTabWidget(QWidget *widget)
+{
+ for (QWidget *tabWidget = widget; tabWidget; tabWidget = tabWidget->parentWidget())
+ if (qobject_cast<const QTabWidget*>(tabWidget))
+ return true;
+ return false;
+}
+#endif
+
+/*!
+ \since 5.0
+ \internal
+
+ Sets the backing store to be the \a store specified.
+ The QWidget will take ownership of the \a store.
+*/
+void QWidget::setBackingStore(QBackingStore *store)
+{
+ // ### createWinId() ??
+
+ if (!isTopLevel())
+ return;
+
+ Q_D(QWidget);
+
+ QTLWExtra *topData = d->topData();
+ if (topData->backingStore == store)
+ return;
+
+ QBackingStore *oldStore = topData->backingStore;
+ delete topData->backingStore;
+ topData->backingStore = store;
+
+ QWidgetBackingStore *bs = d->maybeBackingStore();
+ if (!bs)
+ return;
+
+ if (isTopLevel()) {
+ if (bs->store != oldStore && bs->store != store)
+ delete bs->store;
+ bs->store = store;
+ }
+}
+
+/*!
+ \since 5.0
+
+ Returns the QBackingStore this widget will be drawn into.
+*/
+QBackingStore *QWidget::backingStore() const
+{
+ Q_D(const QWidget);
+ QTLWExtra *extra = d->maybeTopData();
+ if (extra && extra->backingStore)
+ return extra->backingStore;
+
+ QWidgetBackingStore *bs = d->maybeBackingStore();
+
+ return bs ? bs->store : 0;
+}
+
+void QWidgetPrivate::getLayoutItemMargins(int *left, int *top, int *right, int *bottom) const
+{
+ if (left)
+ *left = (int)leftLayoutItemMargin;
+ if (top)
+ *top = (int)topLayoutItemMargin;
+ if (right)
+ *right = (int)rightLayoutItemMargin;
+ if (bottom)
+ *bottom = (int)bottomLayoutItemMargin;
+}
+
+void QWidgetPrivate::setLayoutItemMargins(int left, int top, int right, int bottom)
+{
+ if (leftLayoutItemMargin == left
+ && topLayoutItemMargin == top
+ && rightLayoutItemMargin == right
+ && bottomLayoutItemMargin == bottom)
+ return;
+
+ Q_Q(QWidget);
+ leftLayoutItemMargin = (signed char)left;
+ topLayoutItemMargin = (signed char)top;
+ rightLayoutItemMargin = (signed char)right;
+ bottomLayoutItemMargin = (signed char)bottom;
+ q->updateGeometry();
+}
+
+void QWidgetPrivate::setLayoutItemMargins(QStyle::SubElement element, const QStyleOption *opt)
+{
+ Q_Q(QWidget);
+ QStyleOption myOpt;
+ if (!opt) {
+ myOpt.initFrom(q);
+ myOpt.rect.setRect(0, 0, 32768, 32768); // arbitrary
+ opt = &myOpt;
+ }
+
+ QRect liRect = q->style()->subElementRect(element, opt, q);
+ if (liRect.isValid()) {
+ leftLayoutItemMargin = (signed char)(opt->rect.left() - liRect.left());
+ topLayoutItemMargin = (signed char)(opt->rect.top() - liRect.top());
+ rightLayoutItemMargin = (signed char)(liRect.right() - opt->rect.right());
+ bottomLayoutItemMargin = (signed char)(liRect.bottom() - opt->rect.bottom());
+ } else {
+ leftLayoutItemMargin = 0;
+ topLayoutItemMargin = 0;
+ rightLayoutItemMargin = 0;
+ bottomLayoutItemMargin = 0;
+ }
+}
+// resets the Qt::WA_QuitOnClose attribute to the default value for transient widgets.
+void QWidgetPrivate::adjustQuitOnCloseAttribute()
+{
+ Q_Q(QWidget);
+
+ if (!q->parentWidget()) {
+ Qt::WindowType type = q->windowType();
+ if (type == Qt::Widget || type == Qt::SubWindow)
+ type = Qt::Window;
+ if (type != Qt::Widget && type != Qt::Window && type != Qt::Dialog)
+ q->setAttribute(Qt::WA_QuitOnClose, false);
+ }
+}
+
+
+
+Q_WIDGETS_EXPORT QWidgetData *qt_qwidget_data(QWidget *widget)
+{
+ return widget->data;
+}
+
+Q_WIDGETS_EXPORT QWidgetPrivate *qt_widget_private(QWidget *widget)
+{
+ return widget->d_func();
+}
+
+
+#ifndef QT_NO_GRAPHICSVIEW
+/*!
+ \since 4.5
+
+ Returns the proxy widget for the corresponding embedded widget in a graphics
+ view; otherwise returns 0.
+
+ \sa QGraphicsProxyWidget::createProxyForChildWidget(),
+ QGraphicsScene::addWidget()
+ */
+QGraphicsProxyWidget *QWidget::graphicsProxyWidget() const
+{
+ Q_D(const QWidget);
+ if (d->extra) {
+ return d->extra->proxyWidget;
+ }
+ return 0;
+}
+#endif
+
+
+/*!
+ \typedef QWidgetList
+ \relates QWidget
+
+ Synonym for QList<QWidget *>.
+*/
+
+#ifndef QT_NO_GESTURES
+/*!
+ Subscribes the widget to a given \a gesture with specific \a flags.
+
+ \sa ungrabGesture(), QGestureEvent
+ \since 4.6
+*/
+void QWidget::grabGesture(Qt::GestureType gesture, Qt::GestureFlags flags)
+{
+ Q_D(QWidget);
+ d->gestureContext.insert(gesture, flags);
+ (void)QGestureManager::instance(); // create a gesture manager
+}
+
+/*!
+ Unsubscribes the widget from a given \a gesture type
+
+ \sa grabGesture(), QGestureEvent
+ \since 4.6
+*/
+void QWidget::ungrabGesture(Qt::GestureType gesture)
+{
+ Q_D(QWidget);
+ if (d->gestureContext.remove(gesture)) {
+ if (QGestureManager *manager = QGestureManager::instance())
+ manager->cleanupCachedGestures(this, gesture);
+ }
+}
+#endif // QT_NO_GESTURES
+
+/*!
+ \typedef WId
+ \relates QWidget
+
+ Platform dependent window identifier.
+*/
+
+/*!
+ \fn void QWidget::destroy(bool destroyWindow, bool destroySubWindows)
+
+ Frees up window system resources. Destroys the widget window if \a
+ destroyWindow is true.
+
+ destroy() calls itself recursively for all the child widgets,
+ passing \a destroySubWindows for the \a destroyWindow parameter.
+ To have more control over destruction of subwidgets, destroy
+ subwidgets selectively first.
+
+ This function is usually called from the QWidget destructor.
+*/
+
+/*!
+ \fn QPaintEngine *QWidget::paintEngine() const
+
+ Returns the widget's paint engine.
+
+ Note that this function should not be called explicitly by the
+ user, since it's meant for reimplementation purposes only. The
+ function is called by Qt internally, and the default
+ implementation may not always return a valid pointer.
+*/
+
+/*!
+ \fn QPoint QWidget::mapToGlobal(const QPoint &pos) const
+
+ Translates the widget coordinate \a pos to global screen
+ coordinates. For example, \c{mapToGlobal(QPoint(0,0))} would give
+ the global coordinates of the top-left pixel of the widget.
+
+ \sa mapFromGlobal() mapTo() mapToParent()
+*/
+
+/*!
+ \fn QPoint QWidget::mapFromGlobal(const QPoint &pos) const
+
+ Translates the global screen coordinate \a pos to widget
+ coordinates.
+
+ \sa mapToGlobal() mapFrom() mapFromParent()
+*/
+
+/*!
+ \fn void QWidget::grabMouse()
+
+ Grabs the mouse input.
+
+ This widget receives all mouse events until releaseMouse() is
+ called; other widgets get no mouse events at all. Keyboard
+ events are not affected. Use grabKeyboard() if you want to grab
+ that.
+
+ \warning Bugs in mouse-grabbing applications very often lock the
+ terminal. Use this function with extreme caution, and consider
+ using the \c -nograb command line option while debugging.
+
+ It is almost never necessary to grab the mouse when using Qt, as
+ Qt grabs and releases it sensibly. In particular, Qt grabs the
+ mouse when a mouse button is pressed and keeps it until the last
+ button is released.
+
+ \note Only visible widgets can grab mouse input. If isVisible()
+ returns false for a widget, that widget cannot call grabMouse().
+
+ \note \bold{(Mac OS X developers)} For \e Cocoa, calling
+ grabMouse() on a widget only works when the mouse is inside the
+ frame of that widget. For \e Carbon, it works outside the widget's
+ frame as well, like for Windows and X11.
+
+ \sa releaseMouse() grabKeyboard() releaseKeyboard()
+*/
+
+/*!
+ \fn void QWidget::grabMouse(const QCursor &cursor)
+ \overload grabMouse()
+
+ Grabs the mouse input and changes the cursor shape.
+
+ The cursor will assume shape \a cursor (for as long as the mouse
+ focus is grabbed) and this widget will be the only one to receive
+ mouse events until releaseMouse() is called().
+
+ \warning Grabbing the mouse might lock the terminal.
+
+ \note \bold{(Mac OS X developers)} See the note in QWidget::grabMouse().
+
+ \sa releaseMouse(), grabKeyboard(), releaseKeyboard(), setCursor()
+*/
+
+/*!
+ \fn void QWidget::releaseMouse()
+
+ Releases the mouse grab.
+
+ \sa grabMouse(), grabKeyboard(), releaseKeyboard()
+*/
+
+/*!
+ \fn void QWidget::grabKeyboard()
+
+ Grabs the keyboard input.
+
+ This widget receives all keyboard events until releaseKeyboard()
+ is called; other widgets get no keyboard events at all. Mouse
+ events are not affected. Use grabMouse() if you want to grab that.
+
+ The focus widget is not affected, except that it doesn't receive
+ any keyboard events. setFocus() moves the focus as usual, but the
+ new focus widget receives keyboard events only after
+ releaseKeyboard() is called.
+
+ If a different widget is currently grabbing keyboard input, that
+ widget's grab is released first.
+
+ \sa releaseKeyboard() grabMouse() releaseMouse() focusWidget()
+*/
+
+/*!
+ \fn void QWidget::releaseKeyboard()
+
+ Releases the keyboard grab.
+
+ \sa grabKeyboard(), grabMouse(), releaseMouse()
+*/
+
+/*!
+ \fn QWidget *QWidget::mouseGrabber()
+
+ Returns the widget that is currently grabbing the mouse input.
+
+ If no widget in this application is currently grabbing the mouse,
+ 0 is returned.
+
+ \sa grabMouse(), keyboardGrabber()
+*/
+
+/*!
+ \fn QWidget *QWidget::keyboardGrabber()
+
+ Returns the widget that is currently grabbing the keyboard input.
+
+ If no widget in this application is currently grabbing the
+ keyboard, 0 is returned.
+
+ \sa grabMouse(), mouseGrabber()
+*/
+
+/*!
+ \fn void QWidget::activateWindow()
+
+ Sets the top-level widget containing this widget to be the active
+ window.
+
+ An active window is a visible top-level window that has the
+ keyboard input focus.
+
+ This function performs the same operation as clicking the mouse on
+ the title bar of a top-level window. On X11, the result depends on
+ the Window Manager. If you want to ensure that the window is
+ stacked on top as well you should also call raise(). Note that the
+ window must be visible, otherwise activateWindow() has no effect.
+
+ On Windows, if you are calling this when the application is not
+ 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
+ does not allow an application to interrupt what the user is currently
+ doing in another application.
+
+ \sa isActiveWindow(), window(), show()
+*/
+
+/*!
+ \fn int QWidget::metric(PaintDeviceMetric m) const
+
+ Internal implementation of the virtual QPaintDevice::metric()
+ function.
+
+ \a m is the metric to get.
+*/
+
+void QWidget::init(QPainter *painter) const
+{
+ const QPalette &pal = palette();
+ painter->d_func()->state->pen = QPen(pal.brush(foregroundRole()), 0);
+ painter->d_func()->state->bgBrush = pal.brush(backgroundRole());
+ QFont f(font(), const_cast<QWidget *>(this));
+ painter->d_func()->state->deviceFont = f;
+ painter->d_func()->state->font = f;
+}
+
+QPaintDevice *QWidget::redirected(QPoint *offset) const
+{
+ return d_func()->redirected(offset);
+}
+
+QPainter *QWidget::sharedPainter() const
+{
+ // Someone sent a paint event directly to the widget
+ if (!d_func()->redirectDev)
+ return 0;
+
+ QPainter *sp = d_func()->sharedPainter();
+ if (!sp || !sp->isActive())
+ return 0;
+
+ if (sp->paintEngine()->paintDevice() != d_func()->redirectDev)
+ return 0;
+
+ return sp;
+}
+
+/*!
+ \fn void QWidget::setMask(const QRegion &region)
+ \overload
+
+ Causes only the parts of the widget which overlap \a region to be
+ visible. If the region includes pixels outside the rect() of the
+ widget, window system controls in that area may or may not be
+ visible, depending on the platform.
+
+ Note that this effect can be slow if the region is particularly
+ complex.
+
+ \sa windowOpacity
+*/
+void QWidget::setMask(const QRegion &newMask)
+{
+ Q_D(QWidget);
+
+ d->createExtra();
+ if (newMask == d->extra->mask)
+ return;
+
+#ifndef QT_NO_BACKINGSTORE
+ const QRegion oldMask(d->extra->mask);
+#endif
+
+ d->extra->mask = newMask;
+ d->extra->hasMask = !newMask.isEmpty();
+
+#ifndef QT_MAC_USE_COCOA
+ if (!testAttribute(Qt::WA_WState_Created))
+ return;
+#endif
+
+ d->setMask_sys(newMask);
+
+#ifndef QT_NO_BACKINGSTORE
+ if (!isVisible())
+ return;
+
+ if (!d->extra->hasMask) {
+ // Mask was cleared; update newly exposed area.
+ QRegion expose(rect());
+ expose -= oldMask;
+ if (!expose.isEmpty()) {
+ d->setDirtyOpaqueRegion();
+ update(expose);
+ }
+ return;
+ }
+
+ if (!isWindow()) {
+ // Update newly exposed area on the parent widget.
+ QRegion parentExpose(rect());
+ parentExpose -= newMask;
+ if (!parentExpose.isEmpty()) {
+ d->setDirtyOpaqueRegion();
+ parentExpose.translate(data->crect.topLeft());
+ parentWidget()->update(parentExpose);
+ }
+
+ // Update newly exposed area on this widget
+ if (!oldMask.isEmpty())
+ update(newMask - oldMask);
+ }
+#endif
+}
+
+/*!
+ \fn void QWidget::setMask(const QBitmap &bitmap)
+
+ Causes only the pixels of the widget for which \a bitmap has a
+ corresponding 1 bit to be visible. If the region includes pixels
+ outside the rect() of the widget, window system controls in that
+ area may or may not be visible, depending on the platform.
+
+ Note that this effect can be slow if the region is particularly
+ complex.
+
+ The following code shows how an image with an alpha channel can be
+ used to generate a mask for a widget:
+
+ \snippet doc/src/snippets/widget-mask/main.cpp 0
+
+ The label shown by this code is masked using the image it contains,
+ giving the appearance that an irregularly-shaped image is being drawn
+ directly onto the screen.
+
+ Masked widgets receive mouse events only on their visible
+ portions.
+
+ \sa clearMask(), windowOpacity(), {Shaped Clock Example}
+*/
+void QWidget::setMask(const QBitmap &bitmap)
+{
+ setMask(QRegion(bitmap));
+}
+
+/*!
+ \fn void QWidget::clearMask()
+
+ Removes any mask set by setMask().
+
+ \sa setMask()
+*/
+void QWidget::clearMask()
+{
+ setMask(QRegion());
+}
+
+/*! \fn const QX11Info &QWidget::x11Info() const
+ Returns information about the configuration of the X display used to display
+ the widget.
+
+ \warning This function is only available on X11.
+*/
+
+/*! \fn Qt::HANDLE QWidget::x11PictureHandle() const
+ Returns the X11 Picture handle of the widget for XRender
+ support. Use of this function is not portable. This function will
+ return 0 if XRender support is not compiled into Qt, if the
+ XRender extension is not supported on the X11 display, or if the
+ handle could not be created.
+*/
+
+#ifdef Q_OS_SYMBIAN
+void QWidgetPrivate::_q_delayedDestroy(WId winId)
+{
+ delete winId;
+}
+#endif
+
+#if QT_MAC_USE_COCOA
+void QWidgetPrivate::syncUnifiedMode() {
+ // The whole purpose of this method is to keep the unifiedToolbar in sync.
+ // That means making sure we either exchange the drawing methods or we let
+ // the toolbar know that it does not require to draw the baseline.
+ Q_Q(QWidget);
+ // This function makes sense only if this is a top level
+ if(!q->isWindow())
+ return;
+ OSWindowRef window = qt_mac_window_for(q);
+ if(changeMethods) {
+ // Ok, we are in documentMode.
+ if(originalDrawMethod)
+ qt_mac_replaceDrawRect(window, this);
+ } else {
+ if(!originalDrawMethod)
+ qt_mac_replaceDrawRectOriginal(window, this);
+ }
+}
+
+#endif // QT_MAC_USE_COCOA
+
+QT_END_NAMESPACE
+
+#include "moc_qwidget.cpp"
+
diff --git a/src/widgets/kernel/qwidget.h b/src/widgets/kernel/qwidget.h
new file mode 100644
index 0000000000..65d5f4701c
--- /dev/null
+++ b/src/widgets/kernel/qwidget.h
@@ -0,0 +1,1093 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWIDGET_H
+#define QWIDGET_H
+
+#include <QtGui/qwindowdefs.h>
+#include <QtCore/qobject.h>
+#include <QtCore/qmargins.h>
+#include <QtGui/qpaintdevice.h>
+#include <QtGui/qpalette.h>
+#include <QtGui/qfont.h>
+#include <QtGui/qfontmetrics.h>
+#include <QtGui/qfontinfo.h>
+#include <QtWidgets/qsizepolicy.h>
+#include <QtGui/qregion.h>
+#include <QtGui/qbrush.h>
+#include <QtGui/qcursor.h>
+#include <QtGui/qkeysequence.h>
+
+#ifdef Q_WS_QPA //should this go somewhere else?
+#include <QtGui/qwindow.h>
+#endif
+
+#ifdef QT_INCLUDE_COMPAT
+#include <QtGui/qevent.h>
+#endif
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QLayout;
+class QWSRegionManager;
+class QStyle;
+class QAction;
+class QVariant;
+
+class QActionEvent;
+class QMouseEvent;
+class QWheelEvent;
+class QHoverEvent;
+class QKeyEvent;
+class QFocusEvent;
+class QPaintEvent;
+class QMoveEvent;
+class QResizeEvent;
+class QCloseEvent;
+class QContextMenuEvent;
+class QInputMethodEvent;
+class QTabletEvent;
+class QDragEnterEvent;
+class QDragMoveEvent;
+class QDragLeaveEvent;
+class QDropEvent;
+class QShowEvent;
+class QHideEvent;
+class QInputContext;
+class QIcon;
+class QBackingStore;
+class QPlatformWindow;
+class QLocale;
+class QGraphicsProxyWidget;
+class QGraphicsEffect;
+class QRasterWindowSurface;
+class QUnifiedToolbarSurface;
+class QPixmap;
+#if defined(Q_WS_X11)
+class QX11Info;
+#endif
+
+class QWidgetData
+{
+public:
+ WId winid;
+ uint widget_attributes;
+ Qt::WindowFlags window_flags;
+ uint window_state : 4;
+ uint focus_policy : 4;
+ uint sizehint_forced :1;
+ uint is_closing :1;
+ uint in_show : 1;
+ uint in_set_window_state : 1;
+ mutable uint fstrut_dirty : 1;
+ uint context_menu_policy : 3;
+ uint window_modality : 2;
+ uint in_destructor : 1;
+ uint unused : 13;
+ QRect crect;
+ mutable QPalette pal;
+ QFont fnt;
+#if defined(Q_WS_QWS)
+// QRegion req_region; // Requested region
+// mutable QRegion paintable_region; // Paintable region
+// mutable bool paintable_region_dirty;// needs to be recalculated
+// mutable QRegion alloc_region; // Allocated region
+// mutable bool alloc_region_dirty; // needs to be recalculated
+// mutable int overlapping_children; // Handle overlapping children
+
+ int alloc_region_index;
+// int alloc_region_revision;
+#endif
+ QRect wrect;
+};
+
+class QWidgetPrivate;
+
+class Q_WIDGETS_EXPORT QWidget : public QObject, public QPaintDevice
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QWidget)
+
+ Q_PROPERTY(bool modal READ isModal)
+ Q_PROPERTY(Qt::WindowModality windowModality READ windowModality WRITE setWindowModality)
+ Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled)
+ Q_PROPERTY(QRect geometry READ geometry WRITE setGeometry)
+ Q_PROPERTY(QRect frameGeometry READ frameGeometry)
+ Q_PROPERTY(QRect normalGeometry READ normalGeometry)
+ Q_PROPERTY(int x READ x)
+ Q_PROPERTY(int y READ y)
+ Q_PROPERTY(QPoint pos READ pos WRITE move DESIGNABLE false STORED false)
+ Q_PROPERTY(QSize frameSize READ frameSize)
+ Q_PROPERTY(QSize size READ size WRITE resize DESIGNABLE false STORED false)
+ Q_PROPERTY(int width READ width)
+ Q_PROPERTY(int height READ height)
+ Q_PROPERTY(QRect rect READ rect)
+ Q_PROPERTY(QRect childrenRect READ childrenRect)
+ Q_PROPERTY(QRegion childrenRegion READ childrenRegion)
+ Q_PROPERTY(QSizePolicy sizePolicy READ sizePolicy WRITE setSizePolicy)
+ Q_PROPERTY(QSize minimumSize READ minimumSize WRITE setMinimumSize)
+ Q_PROPERTY(QSize maximumSize READ maximumSize WRITE setMaximumSize)
+ Q_PROPERTY(int minimumWidth READ minimumWidth WRITE setMinimumWidth STORED false DESIGNABLE false)
+ Q_PROPERTY(int minimumHeight READ minimumHeight WRITE setMinimumHeight STORED false DESIGNABLE false)
+ Q_PROPERTY(int maximumWidth READ maximumWidth WRITE setMaximumWidth STORED false DESIGNABLE false)
+ Q_PROPERTY(int maximumHeight READ maximumHeight WRITE setMaximumHeight STORED false DESIGNABLE false)
+ Q_PROPERTY(QSize sizeIncrement READ sizeIncrement WRITE setSizeIncrement)
+ Q_PROPERTY(QSize baseSize READ baseSize WRITE setBaseSize)
+ Q_PROPERTY(QPalette palette READ palette WRITE setPalette)
+ Q_PROPERTY(QFont font READ font WRITE setFont)
+#ifndef QT_NO_CURSOR
+ Q_PROPERTY(QCursor cursor READ cursor WRITE setCursor RESET unsetCursor)
+#endif
+ Q_PROPERTY(bool mouseTracking READ hasMouseTracking WRITE setMouseTracking)
+ Q_PROPERTY(bool isActiveWindow READ isActiveWindow)
+ Q_PROPERTY(Qt::FocusPolicy focusPolicy READ focusPolicy WRITE setFocusPolicy)
+ Q_PROPERTY(bool focus READ hasFocus)
+ Q_PROPERTY(Qt::ContextMenuPolicy contextMenuPolicy READ contextMenuPolicy WRITE setContextMenuPolicy)
+ Q_PROPERTY(bool updatesEnabled READ updatesEnabled WRITE setUpdatesEnabled DESIGNABLE false)
+ Q_PROPERTY(bool visible READ isVisible WRITE setVisible DESIGNABLE false)
+ Q_PROPERTY(bool minimized READ isMinimized)
+ Q_PROPERTY(bool maximized READ isMaximized)
+ Q_PROPERTY(bool fullScreen READ isFullScreen)
+ Q_PROPERTY(QSize sizeHint READ sizeHint)
+ Q_PROPERTY(QSize minimumSizeHint READ minimumSizeHint)
+ Q_PROPERTY(bool acceptDrops READ acceptDrops WRITE setAcceptDrops)
+ Q_PROPERTY(QString windowTitle READ windowTitle WRITE setWindowTitle DESIGNABLE isWindow)
+ Q_PROPERTY(QIcon windowIcon READ windowIcon WRITE setWindowIcon DESIGNABLE isWindow)
+ Q_PROPERTY(QString windowIconText READ windowIconText WRITE setWindowIconText DESIGNABLE isWindow)
+ Q_PROPERTY(double windowOpacity READ windowOpacity WRITE setWindowOpacity DESIGNABLE isWindow)
+ Q_PROPERTY(bool windowModified READ isWindowModified WRITE setWindowModified DESIGNABLE isWindow)
+#ifndef QT_NO_TOOLTIP
+ Q_PROPERTY(QString toolTip READ toolTip WRITE setToolTip)
+#endif
+#ifndef QT_NO_STATUSTIP
+ Q_PROPERTY(QString statusTip READ statusTip WRITE setStatusTip)
+#endif
+#ifndef QT_NO_WHATSTHIS
+ Q_PROPERTY(QString whatsThis READ whatsThis WRITE setWhatsThis)
+#endif
+#ifndef QT_NO_ACCESSIBILITY
+ Q_PROPERTY(QString accessibleName READ accessibleName WRITE setAccessibleName)
+ Q_PROPERTY(QString accessibleDescription READ accessibleDescription WRITE setAccessibleDescription)
+#endif
+ Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection RESET unsetLayoutDirection)
+ QDOC_PROPERTY(Qt::WindowFlags windowFlags READ windowFlags WRITE setWindowFlags)
+ Q_PROPERTY(bool autoFillBackground READ autoFillBackground WRITE setAutoFillBackground)
+#ifndef QT_NO_STYLE_STYLESHEET
+ Q_PROPERTY(QString styleSheet READ styleSheet WRITE setStyleSheet)
+#endif
+ Q_PROPERTY(QLocale locale READ locale WRITE setLocale RESET unsetLocale)
+ Q_PROPERTY(QString windowFilePath READ windowFilePath WRITE setWindowFilePath DESIGNABLE isWindow)
+ Q_PROPERTY(Qt::InputMethodHints inputMethodHints READ inputMethodHints WRITE setInputMethodHints)
+
+public:
+ enum RenderFlag {
+ DrawWindowBackground = 0x1,
+ DrawChildren = 0x2,
+ IgnoreMask = 0x4
+ };
+ Q_DECLARE_FLAGS(RenderFlags, RenderFlag)
+
+ explicit QWidget(QWidget* parent = 0, Qt::WindowFlags f = 0);
+#ifdef QT3_SUPPORT
+ QT3_SUPPORT_CONSTRUCTOR QWidget(QWidget* parent, const char *name, Qt::WindowFlags f = 0);
+#endif
+ ~QWidget();
+
+ int devType() const;
+
+ WId winId() const;
+ void createWinId(); // internal, going away
+ inline WId internalWinId() const { return data->winid; }
+ WId effectiveWinId() const;
+
+ // GUI style setting
+ QStyle *style() const;
+ void setStyle(QStyle *);
+ // Widget types and states
+
+ bool isTopLevel() const;
+ bool isWindow() const;
+
+ bool isModal() const;
+ Qt::WindowModality windowModality() const;
+ void setWindowModality(Qt::WindowModality windowModality);
+
+ bool isEnabled() const;
+ bool isEnabledTo(QWidget*) const;
+ bool isEnabledToTLW() const;
+
+public Q_SLOTS:
+ void setEnabled(bool);
+ void setDisabled(bool);
+ void setWindowModified(bool);
+
+ // Widget coordinates
+
+public:
+ QRect frameGeometry() const;
+ const QRect &geometry() const;
+ QRect normalGeometry() const;
+
+ int x() const;
+ int y() const;
+ QPoint pos() const;
+ QSize frameSize() const;
+ QSize size() const;
+ inline int width() const;
+ inline int height() const;
+ inline QRect rect() const;
+ QRect childrenRect() const;
+ QRegion childrenRegion() const;
+
+ QSize minimumSize() const;
+ QSize maximumSize() const;
+ int minimumWidth() const;
+ int minimumHeight() const;
+ int maximumWidth() const;
+ int maximumHeight() const;
+ void setMinimumSize(const QSize &);
+ void setMinimumSize(int minw, int minh);
+ void setMaximumSize(const QSize &);
+ void setMaximumSize(int maxw, int maxh);
+ void setMinimumWidth(int minw);
+ void setMinimumHeight(int minh);
+ void setMaximumWidth(int maxw);
+ void setMaximumHeight(int maxh);
+
+#ifdef Q_QDOC
+ void setupUi(QWidget *widget);
+#endif
+
+ QSize sizeIncrement() const;
+ void setSizeIncrement(const QSize &);
+ void setSizeIncrement(int w, int h);
+ QSize baseSize() const;
+ void setBaseSize(const QSize &);
+ void setBaseSize(int basew, int baseh);
+
+ void setFixedSize(const QSize &);
+ void setFixedSize(int w, int h);
+ void setFixedWidth(int w);
+ void setFixedHeight(int h);
+
+ // Widget coordinate mapping
+
+ QPoint mapToGlobal(const QPoint &) const;
+ QPoint mapFromGlobal(const QPoint &) const;
+ QPoint mapToParent(const QPoint &) const;
+ QPoint mapFromParent(const QPoint &) const;
+ QPoint mapTo(QWidget *, const QPoint &) const;
+ QPoint mapFrom(QWidget *, const QPoint &) const;
+
+ QWidget *window() const;
+ QWidget *nativeParentWidget() const;
+ inline QWidget *topLevelWidget() const { return window(); }
+
+ // Widget appearance functions
+ const QPalette &palette() const;
+ void setPalette(const QPalette &);
+
+ void setBackgroundRole(QPalette::ColorRole);
+ QPalette::ColorRole backgroundRole() const;
+
+ void setForegroundRole(QPalette::ColorRole);
+ QPalette::ColorRole foregroundRole() const;
+
+ const QFont &font() const;
+ void setFont(const QFont &);
+ QFontMetrics fontMetrics() const;
+ QFontInfo fontInfo() const;
+
+#ifndef QT_NO_CURSOR
+ QCursor cursor() const;
+ void setCursor(const QCursor &);
+ void unsetCursor();
+#endif
+
+ void setMouseTracking(bool enable);
+ bool hasMouseTracking() const;
+ bool underMouse() const;
+
+ void setMask(const QBitmap &);
+ void setMask(const QRegion &);
+ QRegion mask() const;
+ void clearMask();
+
+ void render(QPaintDevice *target, const QPoint &targetOffset = QPoint(),
+ const QRegion &sourceRegion = QRegion(),
+ RenderFlags renderFlags = RenderFlags(DrawWindowBackground | DrawChildren));
+
+ void render(QPainter *painter, const QPoint &targetOffset = QPoint(),
+ const QRegion &sourceRegion = QRegion(),
+ RenderFlags renderFlags = RenderFlags(DrawWindowBackground | DrawChildren));
+
+ Q_INVOKABLE QPixmap grab(const QRect &rectangle);
+
+#ifndef QT_NO_GRAPHICSEFFECT
+ QGraphicsEffect *graphicsEffect() const;
+ void setGraphicsEffect(QGraphicsEffect *effect);
+#endif //QT_NO_GRAPHICSEFFECT
+
+#ifndef QT_NO_GESTURES
+ void grabGesture(Qt::GestureType type, Qt::GestureFlags flags = Qt::GestureFlags());
+ void ungrabGesture(Qt::GestureType type);
+#endif
+
+public Q_SLOTS:
+ void setWindowTitle(const QString &);
+#ifndef QT_NO_STYLE_STYLESHEET
+ void setStyleSheet(const QString& styleSheet);
+#endif
+public:
+#ifndef QT_NO_STYLE_STYLESHEET
+ QString styleSheet() const;
+#endif
+ QString windowTitle() const;
+ void setWindowIcon(const QIcon &icon);
+ QIcon windowIcon() const;
+ void setWindowIconText(const QString &);
+ QString windowIconText() const;
+ void setWindowRole(const QString &);
+ QString windowRole() const;
+ void setWindowFilePath(const QString &filePath);
+ QString windowFilePath() const;
+
+ void setWindowOpacity(qreal level);
+ qreal windowOpacity() const;
+
+ bool isWindowModified() const;
+#ifndef QT_NO_TOOLTIP
+ void setToolTip(const QString &);
+ QString toolTip() const;
+#endif
+#ifndef QT_NO_STATUSTIP
+ void setStatusTip(const QString &);
+ QString statusTip() const;
+#endif
+#ifndef QT_NO_WHATSTHIS
+ void setWhatsThis(const QString &);
+ QString whatsThis() const;
+#endif
+#ifndef QT_NO_ACCESSIBILITY
+ QString accessibleName() const;
+ void setAccessibleName(const QString &name);
+ QString accessibleDescription() const;
+ void setAccessibleDescription(const QString &description);
+#endif
+
+ void setLayoutDirection(Qt::LayoutDirection direction);
+ Qt::LayoutDirection layoutDirection() const;
+ void unsetLayoutDirection();
+
+ void setLocale(const QLocale &locale);
+ QLocale locale() const;
+ void unsetLocale();
+
+ inline bool isRightToLeft() const { return layoutDirection() == Qt::RightToLeft; }
+ inline bool isLeftToRight() const { return layoutDirection() == Qt::LeftToRight; }
+
+public Q_SLOTS:
+ inline void setFocus() { setFocus(Qt::OtherFocusReason); }
+
+public:
+ bool isActiveWindow() const;
+ void activateWindow();
+ void clearFocus();
+
+ void setFocus(Qt::FocusReason reason);
+ Qt::FocusPolicy focusPolicy() const;
+ void setFocusPolicy(Qt::FocusPolicy policy);
+ bool hasFocus() const;
+ static void setTabOrder(QWidget *, QWidget *);
+ void setFocusProxy(QWidget *);
+ QWidget *focusProxy() const;
+ Qt::ContextMenuPolicy contextMenuPolicy() const;
+ void setContextMenuPolicy(Qt::ContextMenuPolicy policy);
+
+ // Grab functions
+ void grabMouse();
+#ifndef QT_NO_CURSOR
+ void grabMouse(const QCursor &);
+#endif
+ void releaseMouse();
+ void grabKeyboard();
+ void releaseKeyboard();
+#ifndef QT_NO_SHORTCUT
+ int grabShortcut(const QKeySequence &key, Qt::ShortcutContext context = Qt::WindowShortcut);
+ void releaseShortcut(int id);
+ void setShortcutEnabled(int id, bool enable = true);
+ void setShortcutAutoRepeat(int id, bool enable = true);
+#endif
+ static QWidget *mouseGrabber();
+ static QWidget *keyboardGrabber();
+
+ // Update/refresh functions
+ inline bool updatesEnabled() const;
+ void setUpdatesEnabled(bool enable);
+
+#if 0 //def Q_WS_QWS
+ void repaintUnclipped(const QRegion &, bool erase = true);
+#endif
+
+#ifndef QT_NO_GRAPHICSVIEW
+ QGraphicsProxyWidget *graphicsProxyWidget() const;
+#endif
+
+public Q_SLOTS:
+ void update();
+ void repaint();
+
+public:
+ inline void update(int x, int y, int w, int h);
+ void update(const QRect&);
+ void update(const QRegion&);
+
+ void repaint(int x, int y, int w, int h);
+ void repaint(const QRect &);
+ void repaint(const QRegion &);
+
+public Q_SLOTS:
+ // Widget management functions
+
+ virtual void setVisible(bool visible);
+ inline void setHidden(bool hidden) { setVisible(!hidden); }
+#ifndef Q_WS_WINCE
+ inline void show() { setVisible(true); }
+#else
+ void show();
+#endif
+ inline void hide() { setVisible(false); }
+ inline QT_MOC_COMPAT void setShown(bool shown) { setVisible(shown); }
+
+ void showMinimized();
+ void showMaximized();
+ void showFullScreen();
+ void showNormal();
+
+ bool close();
+ void raise();
+ void lower();
+
+public:
+ void stackUnder(QWidget*);
+ void move(int x, int y);
+ void move(const QPoint &);
+ void resize(int w, int h);
+ void resize(const QSize &);
+ inline void setGeometry(int x, int y, int w, int h);
+ void setGeometry(const QRect &);
+ QByteArray saveGeometry() const;
+ bool restoreGeometry(const QByteArray &geometry);
+ void adjustSize();
+ bool isVisible() const;
+ bool isVisibleTo(QWidget*) const;
+ // ### Qt 5: bool isVisibleTo(_const_ QWidget *) const
+ inline bool isHidden() const;
+
+ bool isMinimized() const;
+ bool isMaximized() const;
+ bool isFullScreen() const;
+
+ Qt::WindowStates windowState() const;
+ void setWindowState(Qt::WindowStates state);
+ void overrideWindowState(Qt::WindowStates state);
+
+ virtual QSize sizeHint() const;
+ virtual QSize minimumSizeHint() const;
+
+ QSizePolicy sizePolicy() const;
+ void setSizePolicy(QSizePolicy);
+ inline void setSizePolicy(QSizePolicy::Policy horizontal, QSizePolicy::Policy vertical);
+ virtual int heightForWidth(int) const;
+
+ QRegion visibleRegion() const;
+
+ void setContentsMargins(int left, int top, int right, int bottom);
+ void setContentsMargins(const QMargins &margins);
+ void getContentsMargins(int *left, int *top, int *right, int *bottom) const;
+ QMargins contentsMargins() const;
+
+ QRect contentsRect() const;
+
+public:
+ QLayout *layout() const;
+ void setLayout(QLayout *);
+ void updateGeometry();
+
+ void setParent(QWidget *parent);
+ void setParent(QWidget *parent, Qt::WindowFlags f);
+
+ void scroll(int dx, int dy);
+ void scroll(int dx, int dy, const QRect&);
+
+ // Misc. functions
+
+ QWidget *focusWidget() const;
+ QWidget *nextInFocusChain() const;
+ QWidget *previousInFocusChain() const;
+
+ // drag and drop
+ bool acceptDrops() const;
+ void setAcceptDrops(bool on);
+
+#ifndef QT_NO_ACTION
+ //actions
+ void addAction(QAction *action);
+ void addActions(QList<QAction*> actions);
+ void insertAction(QAction *before, QAction *action);
+ void insertActions(QAction *before, QList<QAction*> actions);
+ void removeAction(QAction *action);
+ QList<QAction*> actions() const;
+#endif
+
+ QWidget *parentWidget() const;
+
+ void setWindowFlags(Qt::WindowFlags type);
+ inline Qt::WindowFlags windowFlags() const;
+ void overrideWindowFlags(Qt::WindowFlags type);
+
+ inline Qt::WindowType windowType() const;
+
+ static QWidget *find(WId);
+#ifdef QT3_SUPPORT
+ static QT3_SUPPORT QWidgetMapper *wmapper();
+#endif
+ inline QWidget *childAt(int x, int y) const;
+ QWidget *childAt(const QPoint &p) const;
+
+#if defined(Q_WS_X11)
+ const QX11Info &x11Info() const;
+ Qt::HANDLE x11PictureHandle() const;
+#endif
+
+#if defined(Q_WS_MAC)
+ Qt::HANDLE macQDHandle() const;
+ Qt::HANDLE macCGHandle() const;
+#endif
+
+#if defined(Q_WS_WIN)
+ HDC getDC() const;
+ void releaseDC(HDC) const;
+#else
+ Qt::HANDLE handle() const;
+#endif
+
+ void setAttribute(Qt::WidgetAttribute, bool on = true);
+ inline bool testAttribute(Qt::WidgetAttribute) const;
+
+ QPaintEngine *paintEngine() const;
+
+ void ensurePolished() const;
+
+ QInputContext *inputContext();
+ void setInputContext(QInputContext *);
+
+ bool isAncestorOf(const QWidget *child) const;
+
+#ifdef QT_KEYPAD_NAVIGATION
+ bool hasEditFocus() const;
+ void setEditFocus(bool on);
+#endif
+
+ bool autoFillBackground() const;
+ void setAutoFillBackground(bool enabled);
+
+ QBackingStore *backingStore() const;
+
+#if defined(Q_WS_QPA)
+ void setWindowHandle(QWindow *window);
+ QWindow *windowHandle() const;
+
+ friend class QDesktopScreenWidget;
+#endif
+
+Q_SIGNALS:
+ void customContextMenuRequested(const QPoint &pos);
+
+protected:
+ // Event handlers
+ bool event(QEvent *);
+ virtual void mousePressEvent(QMouseEvent *);
+ virtual void mouseReleaseEvent(QMouseEvent *);
+ virtual void mouseDoubleClickEvent(QMouseEvent *);
+ virtual void mouseMoveEvent(QMouseEvent *);
+#ifndef QT_NO_WHEELEVENT
+ virtual void wheelEvent(QWheelEvent *);
+#endif
+ virtual void keyPressEvent(QKeyEvent *);
+ virtual void keyReleaseEvent(QKeyEvent *);
+ virtual void focusInEvent(QFocusEvent *);
+ virtual void focusOutEvent(QFocusEvent *);
+ virtual void enterEvent(QEvent *);
+ virtual void leaveEvent(QEvent *);
+ virtual void paintEvent(QPaintEvent *);
+ virtual void moveEvent(QMoveEvent *);
+ virtual void resizeEvent(QResizeEvent *);
+ virtual void closeEvent(QCloseEvent *);
+#ifndef QT_NO_CONTEXTMENU
+ virtual void contextMenuEvent(QContextMenuEvent *);
+#endif
+#ifndef QT_NO_TABLETEVENT
+ virtual void tabletEvent(QTabletEvent *);
+#endif
+#ifndef QT_NO_ACTION
+ virtual void actionEvent(QActionEvent *);
+#endif
+
+#ifndef QT_NO_DRAGANDDROP
+ virtual void dragEnterEvent(QDragEnterEvent *);
+ virtual void dragMoveEvent(QDragMoveEvent *);
+ virtual void dragLeaveEvent(QDragLeaveEvent *);
+ virtual void dropEvent(QDropEvent *);
+#endif
+
+ virtual void showEvent(QShowEvent *);
+ virtual void hideEvent(QHideEvent *);
+
+#if defined(Q_WS_MAC)
+ virtual bool macEvent(EventHandlerCallRef, EventRef);
+#endif
+#if defined(Q_WS_WIN)
+ virtual bool winEvent(MSG *message, long *result);
+#endif
+#if defined(Q_WS_X11)
+ virtual bool x11Event(XEvent *);
+#endif
+#if defined(Q_WS_QWS)
+ virtual bool qwsEvent(QWSEvent *);
+#endif
+
+ // Misc. protected functions
+ virtual void changeEvent(QEvent *);
+
+ int metric(PaintDeviceMetric) const;
+ void init(QPainter *painter) const;
+ QPaintDevice *redirected(QPoint *offset) const;
+ QPainter *sharedPainter() const;
+
+ virtual void inputMethodEvent(QInputMethodEvent *);
+public:
+ virtual QVariant inputMethodQuery(Qt::InputMethodQuery) const;
+
+ Qt::InputMethodHints inputMethodHints() const;
+ void setInputMethodHints(Qt::InputMethodHints hints);
+
+protected:
+ void resetInputContext();
+protected Q_SLOTS:
+ void updateMicroFocus();
+protected:
+
+ void create(WId = 0, bool initializeWindow = true,
+ bool destroyOldWindow = true);
+ void destroy(bool destroyWindow = true,
+ bool destroySubWindows = true);
+
+ virtual bool focusNextPrevChild(bool next);
+ inline bool focusNextChild() { return focusNextPrevChild(true); }
+ inline bool focusPreviousChild() { return focusNextPrevChild(false); }
+
+protected:
+ QWidget(QWidgetPrivate &d, QWidget* parent, Qt::WindowFlags f);
+private:
+ void setBackingStore(QBackingStore *store);
+
+ bool testAttribute_helper(Qt::WidgetAttribute) const;
+
+ QLayout *takeLayout();
+
+ friend class QBackingStoreDevice;
+ friend class QWidgetBackingStore;
+ friend class QApplication;
+ friend class QApplicationPrivate;
+ friend class QGuiApplication;
+ friend class QGuiApplicationPrivate;
+ friend class QBaseApplication;
+ friend class QPainter;
+ friend class QPainterPrivate;
+ friend class QPixmap; // for QPixmap::fill()
+ friend class QFontMetrics;
+ friend class QFontInfo;
+ friend class QETWidget;
+ friend class QLayout;
+ friend class QWidgetItem;
+ friend class QWidgetItemV2;
+ friend class QGLContext;
+ friend class QGLWidget;
+ friend class QGLWindowSurface;
+ friend class QX11PaintEngine;
+ friend class QWin32PaintEngine;
+ friend class QShortcutPrivate;
+ friend class QShortcutMap;
+ friend class QWindowSurface;
+ friend class QGraphicsProxyWidget;
+ friend class QGraphicsProxyWidgetPrivate;
+ friend class QStyleSheetStyle;
+ friend struct QWidgetExceptionCleaner;
+ friend class QWidgetWindow;
+#ifndef QT_NO_GESTURES
+ friend class QGestureManager;
+ friend class QWinNativePanGestureRecognizer;
+#endif // QT_NO_GESTURES
+ friend class QWidgetEffectSourcePrivate;
+
+#ifdef Q_WS_MAC
+ friend class QCoreGraphicsPaintEnginePrivate;
+ friend QPoint qt_mac_posInWindow(const QWidget *w);
+ friend OSWindowRef qt_mac_window_for(const QWidget *w);
+ friend bool qt_mac_is_metal(const QWidget *w);
+ friend OSViewRef qt_mac_nativeview_for(const QWidget *w);
+ friend void qt_event_request_window_change(QWidget *widget);
+ friend bool qt_mac_sendMacEventToWidget(QWidget *widget, EventRef ref);
+ friend class QRasterWindowSurface;
+ friend class QUnifiedToolbarSurface;
+#endif
+#ifdef Q_WS_QWS
+ friend class QWSBackingStore;
+ friend class QWSManager;
+ friend class QWSManagerPrivate;
+ friend class QDecoration;
+ friend class QWSWindowSurface;
+ friend class QScreen;
+ friend class QVNCScreen;
+ friend bool isWidgetOpaque(const QWidget *);
+ friend class QGLWidgetPrivate;
+#endif
+#ifdef Q_OS_SYMBIAN
+ friend class QSymbianControl;
+ friend class QS60WindowSurface;
+#endif
+#ifdef Q_WS_X11
+ friend void qt_net_update_user_time(QWidget *tlw, unsigned long timestamp);
+ friend void qt_net_remove_user_time(QWidget *tlw);
+ friend void qt_set_winid_on_widget(QWidget*, Qt::HANDLE);
+#endif
+
+ friend Q_WIDGETS_EXPORT QWidgetData *qt_qwidget_data(QWidget *widget);
+ friend Q_WIDGETS_EXPORT QWidgetPrivate *qt_widget_private(QWidget *widget);
+
+private:
+ Q_DISABLE_COPY(QWidget)
+ Q_PRIVATE_SLOT(d_func(), void _q_showIfNotHidden())
+#ifdef Q_OS_SYMBIAN
+ Q_PRIVATE_SLOT(d_func(), void _q_delayedDestroy(WId winId))
+#endif
+
+ QWidgetData *data;
+
+#ifdef QT3_SUPPORT
+public:
+ inline QT3_SUPPORT bool isUpdatesEnabled() const { return updatesEnabled(); }
+ QT3_SUPPORT QStyle *setStyle(const QString&);
+ inline QT3_SUPPORT bool isVisibleToTLW() const;
+ QT3_SUPPORT QRect visibleRect() const;
+ inline QT3_SUPPORT void iconify() { showMinimized(); }
+ inline QT3_SUPPORT void constPolish() const { ensurePolished(); }
+ inline QT3_SUPPORT void polish() { ensurePolished(); }
+ inline QT3_SUPPORT void reparent(QWidget *parent, Qt::WindowFlags f, const QPoint &p, bool showIt=false)
+ { setParent(parent, f); setGeometry(p.x(),p.y(),width(),height()); if (showIt) show(); }
+ inline QT3_SUPPORT void reparent(QWidget *parent, const QPoint &p, bool showIt=false)
+ { setParent(parent, windowFlags() & ~Qt::WindowType_Mask); setGeometry(p.x(),p.y(),width(),height()); if (showIt) show(); }
+ inline QT3_SUPPORT void recreate(QWidget *parent, Qt::WindowFlags f, const QPoint & p, bool showIt=false)
+ { setParent(parent, f); setGeometry(p.x(),p.y(),width(),height()); if (showIt) show(); }
+ inline QT3_SUPPORT void setSizePolicy(QSizePolicy::Policy hor, QSizePolicy::Policy ver, bool hfw)
+ { QSizePolicy sp(hor, ver); sp.setHeightForWidth(hfw); setSizePolicy(sp);}
+ inline QT3_SUPPORT bool hasMouse() const { return testAttribute(Qt::WA_UnderMouse); }
+#ifndef QT_NO_CURSOR
+ inline QT3_SUPPORT bool ownCursor() const { return testAttribute(Qt::WA_SetCursor); }
+#endif
+ inline QT3_SUPPORT bool ownFont() const { return testAttribute(Qt::WA_SetFont); }
+ inline QT3_SUPPORT void unsetFont() { setFont(QFont()); }
+ inline QT3_SUPPORT bool ownPalette() const { return testAttribute(Qt::WA_SetPalette); }
+ inline QT3_SUPPORT void unsetPalette() { setPalette(QPalette()); }
+ Qt::BackgroundMode QT3_SUPPORT backgroundMode() const;
+ void QT3_SUPPORT setBackgroundMode(Qt::BackgroundMode, Qt::BackgroundMode = Qt::PaletteBackground);
+ const QT3_SUPPORT QColor &eraseColor() const;
+ void QT3_SUPPORT setEraseColor(const QColor &);
+ const QT3_SUPPORT QColor &foregroundColor() const;
+ const QT3_SUPPORT QPixmap *erasePixmap() const;
+ void QT3_SUPPORT setErasePixmap(const QPixmap &);
+ const QT3_SUPPORT QColor &paletteForegroundColor() const;
+ void QT3_SUPPORT setPaletteForegroundColor(const QColor &);
+ const QT3_SUPPORT QColor &paletteBackgroundColor() const;
+ void QT3_SUPPORT setPaletteBackgroundColor(const QColor &);
+ const QT3_SUPPORT QPixmap *paletteBackgroundPixmap() const;
+ void QT3_SUPPORT setPaletteBackgroundPixmap(const QPixmap &);
+ const QT3_SUPPORT QBrush& backgroundBrush() const;
+ const QT3_SUPPORT QColor &backgroundColor() const;
+ const QT3_SUPPORT QPixmap *backgroundPixmap() const;
+ void QT3_SUPPORT setBackgroundPixmap(const QPixmap &);
+ QT3_SUPPORT void setBackgroundColor(const QColor &);
+ QT3_SUPPORT QWidget *parentWidget(bool sameWindow) const;
+ inline QT3_SUPPORT void setKeyCompression(bool b) { setAttribute(Qt::WA_KeyCompression, b); }
+ inline QT3_SUPPORT void setFont(const QFont &f, bool) { setFont(f); }
+ inline QT3_SUPPORT void setPalette(const QPalette &p, bool) { setPalette(p); }
+ enum BackgroundOrigin { WidgetOrigin, ParentOrigin, WindowOrigin, AncestorOrigin };
+ inline QT3_SUPPORT void setBackgroundOrigin(BackgroundOrigin) {}
+ inline QT3_SUPPORT BackgroundOrigin backgroundOrigin() const { return WindowOrigin; }
+ inline QT3_SUPPORT QPoint backgroundOffset() const { return QPoint(); }
+ inline QT3_SUPPORT void repaint(bool) { repaint(); }
+ inline QT3_SUPPORT void repaint(int x, int y, int w, int h, bool) { repaint(x,y,w,h); }
+ inline QT3_SUPPORT void repaint(const QRect &r, bool) { repaint(r); }
+ inline QT3_SUPPORT void repaint(const QRegion &rgn, bool) { repaint(rgn); }
+ QT3_SUPPORT void erase();
+ inline QT3_SUPPORT void erase(int x, int y, int w, int h) { erase_helper(x, y, w, h); }
+ QT3_SUPPORT void erase(const QRect &);
+ QT3_SUPPORT void erase(const QRegion &);
+ QT3_SUPPORT void drawText(const QPoint &p, const QString &s)
+ { drawText_helper(p.x(), p.y(), s); }
+ inline QT3_SUPPORT void drawText(int x, int y, const QString &s)
+ { drawText_helper(x, y, s); }
+ QT3_SUPPORT bool close(bool);
+ inline QT3_SUPPORT QWidget *childAt(int x, int y, bool includeThis) const
+ {
+ QWidget *w = childAt(x, y);
+ return w ? w : ((includeThis && rect().contains(x,y))?const_cast<QWidget*>(this):0);
+ }
+ inline QT3_SUPPORT QWidget *childAt(const QPoint &p, bool includeThis) const
+ {
+ QWidget *w = childAt(p);
+ return w ? w : ((includeThis && rect().contains(p))?const_cast<QWidget*>(this):0);
+ }
+ inline QT3_SUPPORT void setCaption(const QString &c) { setWindowTitle(c); }
+ QT3_SUPPORT void setIcon(const QPixmap &i);
+ inline QT3_SUPPORT void setIconText(const QString &it) { setWindowIconText(it); }
+ inline QT3_SUPPORT QString caption() const { return windowTitle(); }
+ QT3_SUPPORT const QPixmap *icon() const;
+ inline QT3_SUPPORT QString iconText() const { return windowIconText(); }
+ inline QT3_SUPPORT void setInputMethodEnabled(bool b) { setAttribute(Qt::WA_InputMethodEnabled, b); }
+ inline QT3_SUPPORT bool isInputMethodEnabled() const { return testAttribute(Qt::WA_InputMethodEnabled); }
+ inline QT3_SUPPORT void setActiveWindow() { activateWindow(); }
+ inline QT3_SUPPORT bool isShown() const { return !isHidden(); }
+ inline QT3_SUPPORT bool isDialog() const { return windowType() == Qt::Dialog; }
+ inline QT3_SUPPORT bool isPopup() const { return windowType() == Qt::Popup; }
+ inline QT3_SUPPORT bool isDesktop() const { return windowType() == Qt::Desktop; }
+
+
+private:
+ void drawText_helper(int x, int y, const QString &);
+ void erase_helper(int x, int y, int w, int h);
+#endif // QT3_SUPPORT
+
+protected:
+ virtual void styleChange(QStyle&); // compat
+ virtual void enabledChange(bool); // compat
+ virtual void paletteChange(const QPalette &); // compat
+ virtual void fontChange(const QFont &); // compat
+ virtual void windowActivationChange(bool); // compat
+ virtual void languageChange(); // compat
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QWidget::RenderFlags)
+
+template <> inline QWidget *qobject_cast<QWidget*>(QObject *o)
+{
+ if (!o || !o->isWidgetType()) return 0;
+ return static_cast<QWidget*>(o);
+}
+template <> inline const QWidget *qobject_cast<const QWidget*>(const QObject *o)
+{
+ if (!o || !o->isWidgetType()) return 0;
+ return static_cast<const QWidget*>(o);
+}
+
+inline QWidget *QWidget::childAt(int ax, int ay) const
+{ return childAt(QPoint(ax, ay)); }
+
+inline Qt::WindowType QWidget::windowType() const
+{ return static_cast<Qt::WindowType>(int(data->window_flags & Qt::WindowType_Mask)); }
+inline Qt::WindowFlags QWidget::windowFlags() const
+{ return data->window_flags; }
+
+inline bool QWidget::isTopLevel() const
+{ return (windowType() & Qt::Window); }
+
+inline bool QWidget::isWindow() const
+{ return (windowType() & Qt::Window); }
+
+inline bool QWidget::isEnabled() const
+{ return !testAttribute(Qt::WA_Disabled); }
+
+inline bool QWidget::isModal() const
+{ return data->window_modality != Qt::NonModal; }
+
+inline bool QWidget::isEnabledToTLW() const
+{ return isEnabled(); }
+
+inline int QWidget::minimumWidth() const
+{ return minimumSize().width(); }
+
+inline int QWidget::minimumHeight() const
+{ return minimumSize().height(); }
+
+inline int QWidget::maximumWidth() const
+{ return maximumSize().width(); }
+
+inline int QWidget::maximumHeight() const
+{ return maximumSize().height(); }
+
+inline void QWidget::setMinimumSize(const QSize &s)
+{ setMinimumSize(s.width(),s.height()); }
+
+inline void QWidget::setMaximumSize(const QSize &s)
+{ setMaximumSize(s.width(),s.height()); }
+
+inline void QWidget::setSizeIncrement(const QSize &s)
+{ setSizeIncrement(s.width(),s.height()); }
+
+inline void QWidget::setBaseSize(const QSize &s)
+{ setBaseSize(s.width(),s.height()); }
+
+inline const QFont &QWidget::font() const
+{ return data->fnt; }
+
+inline QFontMetrics QWidget::fontMetrics() const
+{ return QFontMetrics(data->fnt); }
+
+inline QFontInfo QWidget::fontInfo() const
+{ return QFontInfo(data->fnt); }
+
+inline void QWidget::setMouseTracking(bool enable)
+{ setAttribute(Qt::WA_MouseTracking, enable); }
+
+inline bool QWidget::hasMouseTracking() const
+{ return testAttribute(Qt::WA_MouseTracking); }
+
+inline bool QWidget::underMouse() const
+{ return testAttribute(Qt::WA_UnderMouse); }
+
+inline bool QWidget::updatesEnabled() const
+{ return !testAttribute(Qt::WA_UpdatesDisabled); }
+
+inline void QWidget::update(int ax, int ay, int aw, int ah)
+{ update(QRect(ax, ay, aw, ah)); }
+
+inline bool QWidget::isVisible() const
+{ return testAttribute(Qt::WA_WState_Visible); }
+
+inline bool QWidget::isHidden() const
+{ return testAttribute(Qt::WA_WState_Hidden); }
+
+inline void QWidget::move(int ax, int ay)
+{ move(QPoint(ax, ay)); }
+
+inline void QWidget::resize(int w, int h)
+{ resize(QSize(w, h)); }
+
+inline void QWidget::setGeometry(int ax, int ay, int aw, int ah)
+{ setGeometry(QRect(ax, ay, aw, ah)); }
+
+inline QRect QWidget::rect() const
+{ return QRect(0,0,data->crect.width(),data->crect.height()); }
+
+inline const QRect &QWidget::geometry() const
+{ return data->crect; }
+
+inline QSize QWidget::size() const
+{ return data->crect.size(); }
+
+inline int QWidget::width() const
+{ return data->crect.width(); }
+
+inline int QWidget::height() const
+{ return data->crect.height(); }
+
+inline QWidget *QWidget::parentWidget() const
+{ return static_cast<QWidget *>(QObject::parent()); }
+
+inline void QWidget::setSizePolicy(QSizePolicy::Policy hor, QSizePolicy::Policy ver)
+{ setSizePolicy(QSizePolicy(hor, ver)); }
+
+inline bool QWidget::testAttribute(Qt::WidgetAttribute attribute) const
+{
+ if (attribute < int(8*sizeof(uint)))
+ return data->widget_attributes & (1<<attribute);
+ return testAttribute_helper(attribute);
+}
+
+#ifdef QT3_SUPPORT
+inline bool QWidget::isVisibleToTLW() const
+{ return isVisible(); }
+inline QWidget *QWidget::parentWidget(bool sameWindow) const
+{
+ if (sameWindow && isWindow())
+ return 0;
+ return static_cast<QWidget *>(QObject::parent());
+}
+inline void QWidget::setPaletteForegroundColor(const QColor &c)
+{ QPalette p = palette(); p.setColor(foregroundRole(), c); setPalette(p); }
+inline const QBrush& QWidget::backgroundBrush() const { return palette().brush(backgroundRole()); }
+inline void QWidget::setBackgroundPixmap(const QPixmap &pm)
+{ QPalette p = palette(); p.setBrush(backgroundRole(), QBrush(pm)); setPalette(p); }
+inline const QPixmap *QWidget::backgroundPixmap() const { return 0; }
+inline void QWidget::setBackgroundColor(const QColor &c)
+{ QPalette p = palette(); p.setColor(backgroundRole(), c); setPalette(p); }
+inline const QColor & QWidget::backgroundColor() const { return palette().color(backgroundRole()); }
+inline const QColor &QWidget::foregroundColor() const { return palette().color(foregroundRole());}
+inline const QColor &QWidget::eraseColor() const { return palette().color(backgroundRole()); }
+inline void QWidget::setEraseColor(const QColor &c)
+{ QPalette p = palette(); p.setColor(backgroundRole(), c); setPalette(p); }
+inline const QPixmap *QWidget::erasePixmap() const { return 0; }
+inline void QWidget::setErasePixmap(const QPixmap &pm)
+{ QPalette p = palette(); p.setBrush(backgroundRole(), QBrush(pm)); setPalette(p); }
+inline const QColor &QWidget::paletteForegroundColor() const { return palette().color(foregroundRole());}
+inline const QColor &QWidget::paletteBackgroundColor() const { return palette().color(backgroundRole()); }
+inline void QWidget::setPaletteBackgroundColor(const QColor &c)
+{ QPalette p = palette(); p.setColor(backgroundRole(), c); setPalette(p); }
+inline const QPixmap *QWidget::paletteBackgroundPixmap() const
+{ return 0; }
+inline void QWidget::setPaletteBackgroundPixmap(const QPixmap &pm)
+{ QPalette p = palette(); p.setBrush(backgroundRole(), QBrush(pm)); setPalette(p); }
+inline QT3_SUPPORT void QWidget::erase() { erase_helper(0, 0, data->crect.width(), data->crect.height()); }
+inline QT3_SUPPORT void QWidget::erase(const QRect &r) { erase_helper(r.x(), r.y(), r.width(), r.height()); }
+#endif
+
+#define QWIDGETSIZE_MAX ((1<<24)-1)
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QWIDGET_H
diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h
new file mode 100644
index 0000000000..6e1568e0fa
--- /dev/null
+++ b/src/widgets/kernel/qwidget_p.h
@@ -0,0 +1,1018 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWIDGET_P_H
+#define QWIDGET_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "QtWidgets/qwidget.h"
+#include "private/qobject_p.h"
+#include "QtCore/qrect.h"
+#include "QtCore/qlocale.h"
+#include "QtCore/qset.h"
+#include "QtGui/qregion.h"
+#include "QtGui/qinputpanel.h"
+#include "QtWidgets/qsizepolicy.h"
+#include "QtWidgets/qstyle.h"
+#include "QtWidgets/qapplication.h"
+#include <private/qgraphicseffect_p.h>
+#include "QtWidgets/qgraphicsproxywidget.h"
+#include "QtWidgets/qgraphicsscene.h"
+#include "QtWidgets/qgraphicsview.h"
+#include <private/qgesture_p.h>
+
+#ifdef Q_WS_WIN
+#include "QtCore/qt_windows.h"
+#include <private/qdnd_p.h>
+#endif // Q_WS_WIN
+
+#ifdef Q_WS_X11
+#include "QtGui/qx11info_x11.h"
+#endif
+
+#ifdef Q_WS_MAC
+#include <private/qt_mac_p.h>
+#endif
+
+#if defined(Q_WS_QWS)
+#include "QtWidgets/qinputcontext.h"
+#include "QtGui/qscreen_qws.h"
+#endif
+
+#if defined(Q_OS_SYMBIAN)
+class RDrawableWindow;
+class CCoeControl;
+#endif
+
+QT_BEGIN_NAMESPACE
+
+// Extra QWidget data
+// - to minimize memory usage for members that are seldom used.
+// - top-level widgets have extra extra data to reduce cost further
+#if defined(Q_WS_QWS)
+class QWSManager;
+#endif
+#if defined(Q_WS_MAC)
+class QCoreGraphicsPaintEnginePrivate;
+#endif
+#if defined(Q_WS_QPA)
+class QWidgetWindow;
+#endif
+class QPaintEngine;
+class QPixmap;
+class QWidgetBackingStore;
+class QGraphicsProxyWidget;
+class QWidgetItemV2;
+
+class QStyle;
+
+class QUnifiedToolbarSurface;
+
+class Q_AUTOTEST_EXPORT QWidgetBackingStoreTracker
+{
+
+public:
+ QWidgetBackingStoreTracker();
+ ~QWidgetBackingStoreTracker();
+
+ void create(QWidget *tlw);
+ void destroy();
+
+ void registerWidget(QWidget *w);
+ void unregisterWidget(QWidget *w);
+ void unregisterWidgetSubtree(QWidget *w);
+
+ inline QWidgetBackingStore* data()
+ {
+ return m_ptr;
+ }
+
+ inline QWidgetBackingStore* operator->()
+ {
+ return m_ptr;
+ }
+
+ inline QWidgetBackingStore& operator*()
+ {
+ return *m_ptr;
+ }
+
+ inline operator bool() const
+ {
+ return (0 != m_ptr);
+ }
+
+private:
+ Q_DISABLE_COPY(QWidgetBackingStoreTracker)
+
+private:
+ QWidgetBackingStore* m_ptr;
+ QSet<QWidget *> m_widgets;
+};
+
+struct QTLWExtra {
+ // *************************** Cross-platform variables *****************************
+
+ // Regular pointers (keep them together to avoid gaps on 64 bits architectures).
+ QIcon *icon; // widget icon
+ QPixmap *iconPixmap;
+ QWidgetBackingStoreTracker backingStoreTracker;
+ QBackingStore *backingStore;
+ QPainter *sharedPainter;
+
+ // Implicit pointers (shared_null).
+ QString caption; // widget caption
+ QString iconText; // widget icon text
+ QString role; // widget role
+ QString filePath; // widget file path
+
+ // Other variables.
+ short incw, inch; // size increments
+ short basew, baseh; // base sizes
+ // frame strut, don't use these directly, use QWidgetPrivate::frameStrut() instead.
+ QRect frameStrut;
+ QRect normalGeometry; // used by showMin/maximized/FullScreen
+ Qt::WindowFlags savedFlags; // Save widget flags while showing fullscreen
+
+ // *************************** Cross-platform bit fields ****************************
+ uint opacity : 8;
+ uint posFromMove : 1;
+ uint sizeAdjusted : 1;
+ uint inTopLevelResize : 1;
+ uint inRepaint : 1;
+ uint embedded : 1;
+
+ // *************************** Platform specific values (bit fields first) **********
+#if defined(Q_WS_X11) // <----------------------------------------------------------- X11
+ uint spont_unmapped: 1; // window was spontaneously unmapped
+ uint dnd : 1; // DND properties installed
+ uint validWMState : 1; // is WM_STATE valid?
+ uint waitingForMapNotify : 1; // show() has been called, haven't got the MapNotify yet
+ WId parentWinId; // parent window Id (valid after reparenting)
+ WId userTimeWindow; // window id that contains user-time timestamp when WM supports a _NET_WM_USER_TIME_WINDOW atom
+ QPoint fullScreenOffset;
+#ifndef QT_NO_XSYNC
+ WId syncUpdateCounter;
+ ulong syncRequestTimestamp;
+ qint32 newCounterValueHi;
+ quint32 newCounterValueLo;
+#endif
+#elif defined(Q_WS_WIN) // <--------------------------------------------------------- WIN
+ uint hotkeyRegistered: 1; // Hot key from the STARTUPINFO has been registered.
+ HICON winIconBig; // internal big Windows icon
+ HICON winIconSmall; // internal small Windows icon
+#elif defined(Q_WS_MAC) // <--------------------------------------------------------- MAC
+ uint resizer : 4;
+ uint isSetGeometry : 1;
+ uint isMove : 1;
+ quint32 wattr;
+ quint32 wclass;
+ WindowGroupRef group;
+ IconRef windowIcon; // the current window icon, if set with setWindowIcon_sys.
+ quint32 savedWindowAttributesFromMaximized; // Saved attributes from when the calling updateMaximizeButton_sys()
+#ifdef QT_MAC_USE_COCOA
+ // This value is just to make sure we maximize and restore to the right location, yet we allow apps to be maximized and
+ // manually resized.
+ // The name is misleading, since this is set when maximizing the window. It is a hint to saveGeometry(..) to record the
+ // starting position as 0,0 instead of the normal starting position.
+ bool wasMaximized;
+#endif // QT_MAC_USE_COCOA
+
+#elif defined(Q_WS_QWS) // <--------------------------------------------------------- QWS
+#ifndef QT_NO_QWS_MANAGER
+ QWSManager *qwsManager;
+#endif
+#elif defined(Q_OS_SYMBIAN)
+ uint inExpose : 1; // Prevents drawing recursion
+ uint nativeWindowTransparencyEnabled : 1; // Tracks native window transparency
+#elif defined(Q_WS_QPA)
+ QWidgetWindow *window;
+ quint32 screenIndex; // index in qplatformscreenlist
+#endif
+};
+
+struct QWExtra {
+ // *************************** Cross-platform variables *****************************
+
+ // Regular pointers (keep them together to avoid gaps on 64 bits architectures).
+ void *glContext; // if the widget is hijacked by QGLWindowSurface
+ QTLWExtra *topextra; // only useful for TLWs
+#ifndef QT_NO_GRAPHICSVIEW
+ QGraphicsProxyWidget *proxyWidget; // if the widget is embedded
+#endif
+#ifndef QT_NO_CURSOR
+ QCursor *curs;
+#endif
+ QPointer<QStyle> style;
+ QPointer<QWidget> focus_proxy;
+
+ // Implicit pointers (shared_empty/shared_null).
+ QRegion mask; // widget mask
+ QString styleSheet;
+
+ // Other variables.
+ qint32 minw;
+ qint32 minh; // minimum size
+ qint32 maxw;
+ qint32 maxh; // maximum size
+ quint16 customDpiX;
+ quint16 customDpiY;
+ QSize staticContentsSize;
+
+ // *************************** Cross-platform bit fields ****************************
+ uint explicitMinSize : 2;
+ uint explicitMaxSize : 2;
+ uint autoFillBackground : 1;
+ uint nativeChildrenForced : 1;
+ uint inRenderWithPainter : 1;
+ uint hasMask : 1;
+
+ // *************************** Platform specific values (bit fields first) **********
+#if defined(Q_WS_WIN) // <----------------------------------------------------------- WIN
+#ifndef QT_NO_DRAGANDDROP
+ QOleDropTarget *dropTarget; // drop target
+ QList<QPointer<QWidget> > oleDropWidgets;
+#endif
+#elif defined(Q_WS_X11) // <--------------------------------------------------------- X11
+ uint compress_events : 1;
+ WId xDndProxy; // XDND forwarding to embedded windows
+#elif defined(Q_WS_MAC) // <------------------------------------------------------ MAC
+#ifdef QT_MAC_USE_COCOA
+ // Cocoa Mask stuff
+ QImage maskBits;
+ CGImageRef imageMask;
+#endif
+#elif defined(Q_OS_SYMBIAN) // <----------------------------------------------------- Symbian
+ uint activated : 1; // RWindowBase::Activated has been called
+
+ /**
+ * If this bit is set, each native widget receives the signals from the
+ * Symbian control immediately before and immediately after draw ops are
+ * sent to the window server for this control:
+ * void beginNativePaintEvent(const QRect &paintRect);
+ * void endNativePaintEvent(const QRect &paintRect);
+ */
+ uint receiveNativePaintEvents : 1;
+
+ /**
+ * Defines the behaviour of QSymbianControl::Draw.
+ */
+ enum NativePaintMode {
+ /**
+ * Normal drawing mode: blits the required region of the backing store
+ * via WSERV.
+ */
+ Blit,
+
+ /**
+ * Disable drawing for this widget.
+ */
+ Disable,
+
+ /**
+ * Paint zeros into the WSERV framebuffer, using BitGDI APIs. For windows
+ * with an EColor16MU display mode, zero is written only into the R, G and B
+ * channels of the pixel.
+ */
+ ZeroFill,
+
+ /**
+ * Blit backing store, propagating alpha channel into the framebuffer.
+ */
+ BlitWriteAlpha,
+
+ Default = Blit
+ };
+
+ NativePaintMode nativePaintMode;
+
+#endif
+};
+
+/*!
+ \internal
+
+ Returns true if \a p or any of its parents enable the
+ Qt::BypassGraphicsProxyWidget window flag. Used in QWidget::show() and
+ QWidget::setParent() to determine whether it's necessary to embed the
+ widget into a QGraphicsProxyWidget or not.
+*/
+static inline bool bypassGraphicsProxyWidget(const QWidget *p)
+{
+ while (p) {
+ if (p->windowFlags() & Qt::BypassGraphicsProxyWidget)
+ return true;
+ p = p->parentWidget();
+ }
+ return false;
+}
+
+class Q_WIDGETS_EXPORT QWidgetPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QWidget)
+
+public:
+ // *************************** Cross-platform ***************************************
+ enum DrawWidgetFlags {
+ DrawAsRoot = 0x01,
+ DrawPaintOnScreen = 0x02,
+ DrawRecursive = 0x04,
+ DrawInvisible = 0x08,
+ DontSubtractOpaqueChildren = 0x10,
+ DontSetCompositionMode = 0x20,
+ DontDrawOpaqueChildren = 0x40,
+ DontDrawNativeChildren = 0x80
+ };
+
+ enum CloseMode {
+ CloseNoEvent,
+ CloseWithEvent,
+ CloseWithSpontaneousEvent
+ };
+
+ enum Direction {
+ DirectionNorth = 0x01,
+ DirectionEast = 0x10,
+ DirectionSouth = 0x02,
+ DirectionWest = 0x20
+ };
+
+ // Functions.
+ explicit QWidgetPrivate(int version = QObjectPrivateVersion);
+ ~QWidgetPrivate();
+
+ QWExtra *extraData() const;
+ QTLWExtra *topData() const;
+ QTLWExtra *maybeTopData() const;
+ QPainter *sharedPainter() const;
+ void setSharedPainter(QPainter *painter);
+ QWidgetBackingStore *maybeBackingStore() const;
+ void init(QWidget *desktopWidget, Qt::WindowFlags f);
+ void create_sys(WId window, bool initializeWindow, bool destroyOldWindow);
+ void createRecursively();
+ void createWinId(WId id = 0);
+
+ void createTLExtra();
+ void createExtra();
+ void deleteExtra();
+ void createSysExtra();
+ void deleteSysExtra();
+ void createTLSysExtra();
+ void deleteTLSysExtra();
+ void updateSystemBackground();
+ void propagatePaletteChange();
+
+ void setPalette_helper(const QPalette &);
+ void resolvePalette();
+ QPalette naturalWidgetPalette(uint inheritedMask) const;
+
+ void setMask_sys(const QRegion &);
+#ifdef Q_OS_SYMBIAN
+ void setSoftKeys_sys(const QList<QAction*> &softkeys);
+ void activateSymbianWindow(WId wid = 0);
+ void _q_delayedDestroy(WId winId);
+#endif
+
+ void raise_sys();
+ void lower_sys();
+ void stackUnder_sys(QWidget *);
+
+ void setFocus_sys();
+
+ void updateFont(const QFont &);
+ inline void setFont_helper(const QFont &font) {
+ if (data.fnt == font && data.fnt.resolve() == font.resolve())
+ return;
+ updateFont(font);
+ }
+ void resolveFont();
+ QFont naturalWidgetFont(uint inheritedMask) const;
+
+ void setLayoutDirection_helper(Qt::LayoutDirection);
+ void resolveLayoutDirection();
+
+ void setLocale_helper(const QLocale &l, bool forceUpdate = false);
+ void resolveLocale();
+
+ void setStyle_helper(QStyle *newStyle, bool propagate, bool metalHack = false);
+ void inheritStyle();
+
+ void setUpdatesEnabled_helper(bool );
+
+ void paintBackground(QPainter *, const QRegion &, int flags = DrawAsRoot) const;
+ bool isAboutToShow() const;
+ QRegion prepareToRender(const QRegion &region, QWidget::RenderFlags renderFlags);
+ void render_helper(QPainter *painter, const QPoint &targetOffset, const QRegion &sourceRegion,
+ QWidget::RenderFlags renderFlags);
+ void render(QPaintDevice *target, const QPoint &targetOffset, const QRegion &sourceRegion,
+ QWidget::RenderFlags renderFlags, bool readyToRender);
+ void drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QPoint &offset, int flags,
+ QPainter *sharedPainter = 0, QWidgetBackingStore *backingStore = 0);
+
+
+ void paintSiblingsRecursive(QPaintDevice *pdev, const QObjectList& children, int index,
+ const QRegion &rgn, const QPoint &offset, int flags,
+ QPainter *sharedPainter, QWidgetBackingStore *backingStore);
+
+
+ QPainter *beginSharedPainter();
+ bool endSharedPainter();
+#ifndef QT_NO_GRAPHICSVIEW
+ static QGraphicsProxyWidget * nearestGraphicsProxyWidget(const QWidget *origin);
+#endif
+ void repaint_sys(const QRegion &rgn);
+
+ QRect clipRect() const;
+ QRegion clipRegion() const;
+ void subtractOpaqueChildren(QRegion &rgn, const QRect &clipRect) const;
+ void subtractOpaqueSiblings(QRegion &source, bool *hasDirtySiblingsAbove = 0,
+ bool alsoNonOpaque = false) const;
+ void clipToEffectiveMask(QRegion &region) const;
+ void updateIsOpaque();
+ void setOpaque(bool opaque);
+ void updateIsTranslucent();
+ bool paintOnScreen() const;
+#ifndef QT_NO_GRAPHICSEFFECT
+ void invalidateGraphicsEffectsRecursively();
+#endif //QT_NO_GRAPHICSEFFECT
+
+ const QRegion &getOpaqueChildren() const;
+ void setDirtyOpaqueRegion();
+
+ bool close_helper(CloseMode mode);
+
+ void setWindowIcon_helper();
+ void setWindowIcon_sys(bool forceReset = false);
+ void setWindowOpacity_sys(qreal opacity);
+ void adjustQuitOnCloseAttribute();
+
+ void scrollChildren(int dx, int dy);
+ void moveRect(const QRect &, int dx, int dy);
+ void scrollRect(const QRect &, int dx, int dy);
+ void invalidateBuffer_resizeHelper(const QPoint &oldPos, const QSize &oldSize);
+ // ### Qt 4.6: Merge into a template function (after MSVC isn't supported anymore).
+ void invalidateBuffer(const QRegion &);
+ void invalidateBuffer(const QRect &);
+ bool isOverlapped(const QRect&) const;
+ void syncBackingStore();
+ void syncBackingStore(const QRegion &region);
+
+ // tells the input panel about the widgets transform
+ void updateWidgetTransform();
+
+ void reparentFocusWidgets(QWidget *oldtlw);
+
+ static int pointToRect(const QPoint &p, const QRect &r);
+
+ void setWinId(WId);
+ void showChildren(bool spontaneous);
+ void hideChildren(bool spontaneous);
+ void setParent_sys(QWidget *parent, Qt::WindowFlags);
+ void scroll_sys(int dx, int dy);
+ void scroll_sys(int dx, int dy, const QRect &r);
+ void deactivateWidgetCleanup();
+ void setGeometry_sys(int, int, int, int, bool);
+ void sendPendingMoveAndResizeEvents(bool recursive = false, bool disableUpdates = false);
+ void activateChildLayoutsRecursively();
+ void show_recursive();
+ void show_helper();
+ void show_sys();
+ void hide_sys();
+ void hide_helper();
+ void _q_showIfNotHidden();
+
+ void setEnabled_helper(bool);
+ void registerDropSite(bool);
+ static void adjustFlags(Qt::WindowFlags &flags, QWidget *w = 0);
+
+ void updateFrameStrut();
+ QRect frameStrut() const;
+
+#ifdef QT_KEYPAD_NAVIGATION
+ static bool navigateToDirection(Direction direction);
+ static QWidget *widgetInNavigationDirection(Direction direction);
+ static bool canKeypadNavigate(Qt::Orientation orientation);
+ static bool inTabWidget(QWidget *widget);
+#endif
+
+ void setWindowIconText_sys(const QString &cap);
+ void setWindowIconText_helper(const QString &cap);
+ void setWindowTitle_sys(const QString &cap);
+
+#ifndef QT_NO_CURSOR
+ void setCursor_sys(const QCursor &cursor);
+ void unsetCursor_sys();
+#endif
+
+ void setWindowTitle_helper(const QString &cap);
+ void setWindowFilePath_helper(const QString &filePath);
+
+ bool setMinimumSize_helper(int &minw, int &minh);
+ bool setMaximumSize_helper(int &maxw, int &maxh);
+ virtual bool hasHeightForWidth() const;
+ void setConstraints_sys();
+ bool pointInsideRectAndMask(const QPoint &) const;
+ QWidget *childAt_helper(const QPoint &, bool) const;
+ QWidget *childAtRecursiveHelper(const QPoint &p, bool, bool includeFrame = false) const;
+ void updateGeometry_helper(bool forceUpdate);
+
+ void getLayoutItemMargins(int *left, int *top, int *right, int *bottom) const;
+ void setLayoutItemMargins(int left, int top, int right, int bottom);
+ void setLayoutItemMargins(QStyle::SubElement element, const QStyleOption *opt = 0);
+
+ // aboutToDestroy() is called just before the contents of
+ // QWidget::destroy() is executed. It's used to signal QWidget
+ // sub-classes that their internals are about to be released.
+ virtual void aboutToDestroy() {}
+
+ QInputContext *assignedInputContext() const;
+ QInputContext *inputContext() const;
+ inline QWidget *effectiveFocusWidget() {
+ QWidget *w = q_func();
+ while (w->focusProxy())
+ w = w->focusProxy();
+ return w;
+ }
+
+ void setModal_sys();
+
+ // This is an helper function that return the available geometry for
+ // a widget and takes care is this one is in QGraphicsView.
+ // If the widget is not embed in a scene then the geometry available is
+ // null, we let QDesktopWidget decide for us.
+ static QRect screenGeometry(const QWidget *widget)
+ {
+ QRect screen;
+#ifndef QT_NO_GRAPHICSVIEW
+ QGraphicsProxyWidget *ancestorProxy = widget->d_func()->nearestGraphicsProxyWidget(widget);
+ //It's embedded if it has an ancestor
+ if (ancestorProxy) {
+ if (!bypassGraphicsProxyWidget(widget) && ancestorProxy->scene() != 0) {
+ // One view, let be smart and return the viewport rect then the popup is aligned
+ if (ancestorProxy->scene()->views().size() == 1) {
+ QGraphicsView *view = ancestorProxy->scene()->views().at(0);
+ screen = view->mapToScene(view->viewport()->rect()).boundingRect().toRect();
+ } else {
+ screen = ancestorProxy->scene()->sceneRect().toRect();
+ }
+ }
+ }
+#endif
+ return screen;
+ }
+
+ inline void setRedirected(QPaintDevice *replacement, const QPoint &offset)
+ {
+ Q_ASSERT(q_func()->testAttribute(Qt::WA_WState_InPaintEvent));
+ redirectDev = replacement;
+ redirectOffset = offset;
+ }
+
+ inline QPaintDevice *redirected(QPoint *offset) const
+ {
+ if (offset)
+ *offset = redirectDev ? redirectOffset : QPoint();
+ return redirectDev;
+ }
+
+ inline void restoreRedirected()
+ { redirectDev = 0; }
+
+ inline void enforceNativeChildren()
+ {
+ if (!extra)
+ createExtra();
+
+ if (extra->nativeChildrenForced)
+ return;
+ extra->nativeChildrenForced = 1;
+
+ for (int i = 0; i < children.size(); ++i) {
+ if (QWidget *child = qobject_cast<QWidget *>(children.at(i)))
+ child->setAttribute(Qt::WA_NativeWindow);
+ }
+ }
+
+ inline bool nativeChildrenForced() const
+ {
+ return extra ? extra->nativeChildrenForced : false;
+ }
+
+ inline QRect effectiveRectFor(const QRect &rect) const
+ {
+#ifndef QT_NO_GRAPHICSEFFECT
+ if (graphicsEffect && graphicsEffect->isEnabled())
+ return graphicsEffect->boundingRectFor(rect).toAlignedRect();
+#endif //QT_NO_GRAPHICSEFFECT
+ return rect;
+ }
+
+ QSize adjustedSize() const;
+
+ inline void handleSoftwareInputPanel(Qt::MouseButton button, bool clickCausedFocus)
+ {
+ Q_Q(QWidget);
+ if (button == Qt::LeftButton && qApp->autoSipEnabled()) {
+ QStyle::RequestSoftwareInputPanel behavior = QStyle::RequestSoftwareInputPanel(
+ q->style()->styleHint(QStyle::SH_RequestSoftwareInputPanel));
+ if (!clickCausedFocus || behavior == QStyle::RSIP_OnMouseClick) {
+ qApp->inputPanel()->show();
+ }
+ }
+ }
+
+#ifndef Q_WS_QWS // Almost cross-platform :-)
+ void setWSGeometry(bool dontShow=false, const QRect &oldRect = QRect());
+
+ inline QPoint mapToWS(const QPoint &p) const
+ { return p - data.wrect.topLeft(); }
+
+ inline QPoint mapFromWS(const QPoint &p) const
+ { return p + data.wrect.topLeft(); }
+
+ inline QRect mapToWS(const QRect &r) const
+ { QRect rr(r); rr.translate(-data.wrect.topLeft()); return rr; }
+
+ inline QRect mapFromWS(const QRect &r) const
+ { QRect rr(r); rr.translate(data.wrect.topLeft()); return rr; }
+#endif
+
+ // Variables.
+ // Regular pointers (keep them together to avoid gaps on 64 bit architectures).
+ QWExtra *extra;
+ QWidget *focus_next;
+ QWidget *focus_prev;
+ QWidget *focus_child;
+ QLayout *layout;
+ QRegion *needsFlush;
+ QPaintDevice *redirectDev;
+ QWidgetItemV2 *widgetItem;
+ QPaintEngine *extraPaintEngine;
+ mutable const QMetaObject *polished;
+ QGraphicsEffect *graphicsEffect;
+ // All widgets are added into the allWidgets set. Once
+ // they receive a window id they are also added to the mapper.
+ // This should just ensure that all widgets are deleted by QApplication
+ static QWidgetMapper *mapper;
+ static QWidgetSet *allWidgets;
+#if !defined(QT_NO_IM)
+ QPointer<QInputContext> ic;
+ Qt::InputMethodHints imHints;
+#endif
+#ifdef QT_KEYPAD_NAVIGATION
+ static QPointer<QWidget> editingWidget;
+#endif
+
+ // Implicit pointers (shared_null/shared_empty).
+ QRegion opaqueChildren;
+ QRegion dirty;
+#ifndef QT_NO_TOOLTIP
+ QString toolTip;
+#endif
+#ifndef QT_NO_STATUSTIP
+ QString statusTip;
+#endif
+#ifndef QT_NO_WHATSTHIS
+ QString whatsThis;
+#endif
+#ifndef QT_NO_ACCESSIBILITY
+ QString accessibleName;
+ QString accessibleDescription;
+#endif
+
+ // Other variables.
+ uint inheritedFontResolveMask;
+ uint inheritedPaletteResolveMask;
+ short leftmargin;
+ short topmargin;
+ short rightmargin;
+ short bottommargin;
+ signed char leftLayoutItemMargin;
+ signed char topLayoutItemMargin;
+ signed char rightLayoutItemMargin;
+ signed char bottomLayoutItemMargin;
+ static int instanceCounter; // Current number of widget instances
+ static int maxInstances; // Maximum number of widget instances
+ Qt::HANDLE hd;
+ QWidgetData data;
+ QSizePolicy size_policy;
+ QLocale locale;
+ QPoint redirectOffset;
+#ifndef QT_NO_ACTION
+ QList<QAction*> actions;
+#endif
+#ifndef QT_NO_GESTURES
+ QMap<Qt::GestureType, Qt::GestureFlags> gestureContext;
+#endif
+
+ // Bit fields.
+ uint high_attributes[4]; // the low ones are in QWidget::widget_attributes
+ QPalette::ColorRole fg_role : 8;
+ QPalette::ColorRole bg_role : 8;
+ uint dirtyOpaqueChildren : 1;
+ uint isOpaque : 1;
+ uint inDirtyList : 1;
+ uint isScrolled : 1;
+ uint isMoved : 1;
+ uint isGLWidget : 1;
+ uint usesDoubleBufferedGLContext : 1;
+#ifndef QT_NO_IM
+ uint inheritsInputMethodHints : 1;
+#endif
+ uint inSetParent : 1;
+
+ // *************************** Platform specific ************************************
+#if defined(Q_WS_X11) // <----------------------------------------------------------- X11
+ QX11Info xinfo;
+ Qt::HANDLE picture;
+ static QWidget *mouseGrabber;
+ static QWidget *keyboardGrabber;
+
+ void setWindowRole();
+ void sendStartupMessage(const char *message) const;
+ void setNetWmWindowTypes();
+ void x11UpdateIsOpaque();
+ bool isBackgroundInherited() const;
+ void updateX11AcceptFocus();
+ QPoint mapToGlobal(const QPoint &pos) const;
+ QPoint mapFromGlobal(const QPoint &pos) const;
+#elif defined(Q_WS_WIN) // <--------------------------------------------------------- WIN
+ uint noPaintOnScreen : 1; // see qwidget_win.cpp ::paintEngine()
+#ifndef QT_NO_GESTURES
+ uint nativeGesturePanEnabled : 1;
+#endif
+ bool shouldShowMaximizeButton();
+ void winUpdateIsOpaque();
+ void reparentChildren();
+#ifndef QT_NO_DRAGANDDROP
+ QOleDropTarget *registerOleDnd(QWidget *widget);
+ void unregisterOleDnd(QWidget *widget, QOleDropTarget *target);
+#endif
+ void grabMouseWhileInWindow();
+ void registerTouchWindow();
+ void winSetupGestures();
+#elif defined(Q_WS_MAC) // <--------------------------------------------------------- MAC
+ // This is new stuff
+ uint needWindowChange : 1;
+
+ // Each wiget keeps a list of all its child and grandchild OpenGL widgets.
+ // This list is used to update the gl context whenever a parent and a granparent
+ // moves, and also to check for intersections with gl widgets within the window
+ // when a widget moves.
+ struct GlWidgetInfo
+ {
+ GlWidgetInfo(QWidget *widget) : widget(widget), lastUpdateWidget(0) { }
+ bool operator==(const GlWidgetInfo &other) const { return (widget == other.widget); }
+ QWidget * widget;
+ QWidget * lastUpdateWidget;
+ };
+
+ // dirtyOnWidget contains the areas in the widget that needs to be repained,
+ // in the same way as dirtyOnScreen does for the window. Areas are added in
+ // dirtyWidget_sys and cleared in the paint event. In scroll_sys we then use
+ // this information repaint invalid areas when widgets are scrolled.
+ QRegion dirtyOnWidget;
+ EventHandlerRef window_event;
+ QList<GlWidgetInfo> glWidgets;
+
+ //these are here just for code compat (HIViews)
+ Qt::HANDLE qd_hd;
+
+ void macUpdateSizeAttribute();
+ void macUpdateHideOnSuspend();
+ void macUpdateOpaqueSizeGrip();
+ void macUpdateIgnoreMouseEvents();
+ void macUpdateMetalAttribute();
+ void macUpdateIsOpaque();
+ void macSetNeedsDisplay(QRegion region);
+ void setEnabled_helper_sys(bool enable);
+ bool isRealWindow() const;
+ void adjustWithinMaxAndMinSize(int &w, int &h);
+ void applyMaxAndMinSizeOnWindow();
+ void update_sys(const QRect &rect);
+ void update_sys(const QRegion &rgn);
+ void setGeometry_sys_helper(int, int, int, int, bool);
+ void setWindowModified_sys(bool b);
+ void updateMaximizeButton_sys();
+ void setWindowFilePath_sys(const QString &filePath);
+ void createWindow_sys();
+ void recreateMacWindow();
+#ifndef QT_MAC_USE_COCOA
+ void initWindowPtr();
+ void finishCreateWindow_sys_Carbon(OSWindowRef windowRef);
+#else
+ void setSubWindowStacking(bool set);
+ void setWindowLevel();
+ void finishCreateWindow_sys_Cocoa(void * /*NSWindow * */ windowRef);
+ void syncCocoaMask();
+ void finishCocoaMaskSetup();
+ void syncUnifiedMode();
+ // Did we add the drawRectOriginal method?
+ bool drawRectOriginalAdded;
+ // Is the original drawRect method available?
+ bool originalDrawMethod;
+ // Do we need to change the methods?
+ bool changeMethods;
+
+ // Unified toolbar variables
+ bool isInUnifiedToolbar;
+ QUnifiedToolbarSurface *unifiedSurface;
+ QPoint toolbar_offset;
+ QWidget *toolbar_ancestor;
+ bool flushRequested;
+ bool touchEventsEnabled;
+#endif // QT_MAC_USE_COCOA
+ void determineWindowClass();
+ void transferChildren();
+ bool qt_mac_dnd_event(uint, DragRef);
+ void toggleDrawers(bool);
+ //mac event functions
+ static bool qt_create_root_win();
+ static void qt_clean_root_win();
+ static bool qt_mac_update_sizer(QWidget *, int up = 0);
+ static OSStatus qt_window_event(EventHandlerCallRef er, EventRef event, void *);
+ static OSStatus qt_widget_event(EventHandlerCallRef er, EventRef event, void *);
+ static bool qt_widget_rgn(QWidget *, short, RgnHandle, bool);
+ void registerTouchWindow(bool enable = true);
+#elif defined(Q_WS_QPA) // <--------------------------------------------------------- QPA
+ void setMaxWindowState_helper();
+ void setFullScreenSize_helper();
+ bool stealKeyboardGrab(bool grab);
+ bool stealMouseGrab(bool grab);
+#elif defined(Q_OS_SYMBIAN) // <--------------------------------------------------------- SYMBIAN
+ static QWidget *mouseGrabber;
+ static QWidget *keyboardGrabber;
+ int symbianScreenNumber; // only valid for desktop widget and top-levels
+ bool fixNativeOrientationCalled;
+ void s60UpdateIsOpaque();
+ void reparentChildren();
+ void registerTouchWindow();
+#endif
+
+};
+
+struct QWidgetPaintContext
+{
+ inline QWidgetPaintContext(QPaintDevice *d, const QRegion &r, const QPoint &o, int f,
+ QPainter *p, QWidgetBackingStore *b)
+ : pdev(d), rgn(r), offset(o), flags(f), sharedPainter(p), backingStore(b), painter(0) {}
+
+ QPaintDevice *pdev;
+ QRegion rgn;
+ QPoint offset;
+ int flags;
+ QPainter *sharedPainter;
+ QWidgetBackingStore *backingStore;
+ QPainter *painter;
+};
+
+#ifndef QT_NO_GRAPHICSEFFECT
+class QWidgetEffectSourcePrivate : public QGraphicsEffectSourcePrivate
+{
+public:
+ QWidgetEffectSourcePrivate(QWidget *widget)
+ : QGraphicsEffectSourcePrivate(), m_widget(widget), context(0), updateDueToGraphicsEffect(false)
+ {}
+
+ inline void detach()
+ { m_widget->d_func()->graphicsEffect = 0; }
+
+ inline const QGraphicsItem *graphicsItem() const
+ { return 0; }
+
+ inline const QWidget *widget() const
+ { return m_widget; }
+
+ inline void update()
+ {
+ updateDueToGraphicsEffect = true;
+ m_widget->update();
+ updateDueToGraphicsEffect = false;
+ }
+
+ inline bool isPixmap() const
+ { return false; }
+
+ inline void effectBoundingRectChanged()
+ {
+ // ### This function should take a rect parameter; then we can avoid
+ // updating too much on the parent widget.
+ if (QWidget *parent = m_widget->parentWidget())
+ parent->update();
+ else
+ update();
+ }
+
+ inline const QStyleOption *styleOption() const
+ { return 0; }
+
+ inline QRect deviceRect() const
+ { return m_widget->window()->rect(); }
+
+ QRectF boundingRect(Qt::CoordinateSystem system) const;
+ void draw(QPainter *p);
+ QPixmap pixmap(Qt::CoordinateSystem system, QPoint *offset,
+ QGraphicsEffect::PixmapPadMode mode) const;
+
+ QWidget *m_widget;
+ QWidgetPaintContext *context;
+ QTransform lastEffectTransform;
+ bool updateDueToGraphicsEffect;
+};
+#endif //QT_NO_GRAPHICSEFFECT
+
+inline QWExtra *QWidgetPrivate::extraData() const
+{
+ return extra;
+}
+
+inline QTLWExtra *QWidgetPrivate::topData() const
+{
+ const_cast<QWidgetPrivate *>(this)->createTLExtra();
+ return extra->topextra;
+}
+
+inline QTLWExtra *QWidgetPrivate::maybeTopData() const
+{
+ return extra ? extra->topextra : 0;
+}
+
+inline QPainter *QWidgetPrivate::sharedPainter() const
+{
+ Q_Q(const QWidget);
+ QTLWExtra *x = q->window()->d_func()->maybeTopData();
+ return x ? x->sharedPainter : 0;
+}
+
+inline void QWidgetPrivate::setSharedPainter(QPainter *painter)
+{
+ Q_Q(QWidget);
+ QTLWExtra *x = q->window()->d_func()->topData();
+ x->sharedPainter = painter;
+}
+
+inline bool QWidgetPrivate::pointInsideRectAndMask(const QPoint &p) const
+{
+ Q_Q(const QWidget);
+ return q->rect().contains(p) && (!extra || !extra->hasMask || q->testAttribute(Qt::WA_MouseNoMask)
+ || extra->mask.contains(p));
+}
+
+inline QWidgetBackingStore *QWidgetPrivate::maybeBackingStore() const
+{
+ Q_Q(const QWidget);
+ QTLWExtra *x = q->window()->d_func()->maybeTopData();
+ return x ? x->backingStoreTracker.data() : 0;
+}
+
+QT_END_NAMESPACE
+
+#endif // QWIDGET_P_H
diff --git a/src/widgets/kernel/qwidget_qpa.cpp b/src/widgets/kernel/qwidget_qpa.cpp
new file mode 100644
index 0000000000..39f8aa944d
--- /dev/null
+++ b/src/widgets/kernel/qwidget_qpa.cpp
@@ -0,0 +1,925 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "QtWidgets/qwidget.h"
+#include "QtGui/qevent.h"
+#include "QtWidgets/qapplication.h"
+#include "private/qwidgetbackingstore_p.h"
+#include "private/qwidget_p.h"
+#include "private/qwidgetwindow_qpa_p.h"
+#include "private/qapplication_p.h"
+#include "QtWidgets/qdesktopwidget.h"
+#include "QtGui/qplatformwindow_qpa.h"
+#include "QtGui/qsurfaceformat.h"
+#include "QtGui/qplatformopenglcontext_qpa.h"
+#include "QtGui/private/qwindow_p.h"
+
+#include <QtGui/QPlatformCursor>
+#include <QtGui/QGuiApplication>
+#include <QtGui/QScreen>
+
+QT_BEGIN_NAMESPACE
+
+void q_createNativeChildrenAndSetParent(QWindow *parentWindow, const QWidget *parentWidget)
+{
+ QObjectList children = parentWidget->children();
+ for (int i = 0; i < children.size(); i++) {
+ if (children.at(i)->isWidgetType()) {
+ const QWidget *childWidget = qobject_cast<const QWidget *>(children.at(i));
+ if (childWidget) { // should not be necessary
+ if (childWidget->testAttribute(Qt::WA_NativeWindow)) {
+ if (!childWidget->windowHandle())
+ childWidget->winId();
+ if (childWidget->windowHandle()) {
+ if (childWidget->isTopLevel())
+ childWidget->windowHandle()->setTransientParent(parentWindow);
+ else
+ childWidget->windowHandle()->setParent(parentWindow);
+ }
+ } else {
+ q_createNativeChildrenAndSetParent(parentWindow,childWidget);
+ }
+ }
+ }
+ }
+
+}
+
+void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyOldWindow)
+{
+ Q_Q(QWidget);
+
+ Q_UNUSED(window);
+ Q_UNUSED(initializeWindow);
+ Q_UNUSED(destroyOldWindow);
+
+ Qt::WindowFlags flags = data.window_flags;
+
+ if (!q->testAttribute(Qt::WA_NativeWindow) && !q->isWindow())
+ return; // we only care about real toplevels
+
+ QWindow *win = topData()->window;
+ // topData() ensures the extra is created but does not ensure 'window' is non-null
+ // in case the extra was already valid.
+ if (!win) {
+ createTLSysExtra();
+ win = topData()->window;
+ }
+
+ win->setWindowFlags(data.window_flags);
+ win->setGeometry(q->geometry());
+ win->setScreen(QGuiApplication::screens().value(topData()->screenIndex, 0));
+
+ if (q->testAttribute(Qt::WA_TranslucentBackground)) {
+ QSurfaceFormat format;
+ format.setAlphaBufferSize(8);
+ win->setFormat(format);
+ }
+
+ if (QWidget *nativeParent = q->nativeParentWidget()) {
+ if (nativeParent->windowHandle()) {
+ if (flags & Qt::Window) {
+ win->setTransientParent(nativeParent->windowHandle());
+ win->setParent(0);
+ } else {
+ win->setTransientParent(0);
+ win->setParent(nativeParent->windowHandle());
+ }
+ }
+ }
+
+ win->create();
+
+ data.window_flags = win->windowFlags();
+
+ QBackingStore *store = q->backingStore();
+
+ if (!store) {
+ if (win)
+ q->setBackingStore(new QBackingStore(win));
+ else
+ q->setAttribute(Qt::WA_PaintOnScreen, true);
+ }
+
+ setWinId(win->winId());
+
+// first check children. and create them if necessary
+// q_createNativeChildrenAndSetParent(q->windowHandle(),q);
+
+// qDebug() << "create_sys" << q << q->internalWinId();
+}
+
+void QWidget::destroy(bool destroyWindow, bool destroySubWindows)
+{
+ Q_D(QWidget);
+
+ d->aboutToDestroy();
+ if (!isWindow() && parentWidget())
+ parentWidget()->d_func()->invalidateBuffer(d->effectiveRectFor(geometry()));
+ d->deactivateWidgetCleanup();
+
+ if ((windowType() == Qt::Popup))
+ qApp->d_func()->closePopup(this);
+
+ if (this == QApplicationPrivate::active_window)
+ QApplication::setActiveWindow(0);
+
+ setAttribute(Qt::WA_WState_Created, false);
+
+ if (windowType() != Qt::Desktop) {
+ if (destroySubWindows) {
+ QObjectList childList(children());
+ for (int i = 0; i < childList.size(); i++) {
+ QWidget *widget = qobject_cast<QWidget *>(childList.at(i));
+ if (widget && widget->testAttribute(Qt::WA_NativeWindow)) {
+ if (widget->windowHandle()) {
+ widget->destroy();
+ }
+ }
+ }
+ }
+ if (destroyWindow) {
+ d->deleteTLSysExtra();
+ } else {
+ if (parentWidget() && parentWidget()->testAttribute(Qt::WA_WState_Created)) {
+ d->hide_sys();
+ }
+ }
+
+ d->setWinId(0);
+ }
+}
+
+void QWidgetPrivate::setParent_sys(QWidget *newparent, Qt::WindowFlags f)
+{
+ Q_Q(QWidget);
+
+ Qt::WindowFlags oldFlags = data.window_flags;
+ bool wasCreated = q->testAttribute(Qt::WA_WState_Created);
+
+ int targetScreen = -1;
+ // Handle a request to move the widget to a particular screen
+ if (newparent && newparent->windowType() == Qt::Desktop) {
+ // make sure the widget is created on the same screen as the
+ // programmer specified desktop widget
+
+ // get the desktop's screen number
+ targetScreen = newparent->window()->d_func()->topData()->screenIndex;
+ newparent = 0;
+ }
+
+ setWinId(0);
+
+ if (parent != newparent) {
+ QObjectPrivate::setParent_helper(newparent); //### why does this have to be done in the _sys function???
+ if (q->windowHandle()) {
+ q->windowHandle()->setWindowFlags(f);
+ QWidget *parentWithWindow =
+ newparent ? (newparent->windowHandle() ? newparent : newparent->nativeParentWidget()) : 0;
+ if (parentWithWindow) {
+ if (f & Qt::Window) {
+ q->windowHandle()->setTransientParent(parentWithWindow->windowHandle());
+ q->windowHandle()->setParent(0);
+ } else {
+ q->windowHandle()->setTransientParent(0);
+ q->windowHandle()->setParent(parentWithWindow->windowHandle());
+ }
+ } else {
+ q->windowHandle()->setTransientParent(0);
+ q->windowHandle()->setParent(0);
+ }
+ }
+ }
+
+ if (!newparent) {
+ f |= Qt::Window;
+ if (targetScreen == -1) {
+ if (parent)
+ targetScreen = q->parentWidget()->window()->d_func()->topData()->screenIndex;
+ }
+ }
+
+ bool explicitlyHidden = q->testAttribute(Qt::WA_WState_Hidden) && q->testAttribute(Qt::WA_WState_ExplicitShowHide);
+
+ // Reparenting toplevel to child
+ if (!(f&Qt::Window) && (oldFlags&Qt::Window) && !q->testAttribute(Qt::WA_NativeWindow)) {
+ //qDebug() << "setParent_sys() change from toplevel";
+ q->destroy();
+ } else if (newparent && wasCreated) {
+ q->createWinId();
+ }
+
+ adjustFlags(f, q);
+ data.window_flags = f;
+ q->setAttribute(Qt::WA_WState_Created, false);
+ q->setAttribute(Qt::WA_WState_Visible, false);
+ q->setAttribute(Qt::WA_WState_Hidden, false);
+
+ if (q->isWindow() || (!newparent || newparent->isVisible()) || explicitlyHidden)
+ q->setAttribute(Qt::WA_WState_Hidden);
+ q->setAttribute(Qt::WA_WState_ExplicitShowHide, explicitlyHidden);
+
+ // move the window to the selected screen
+ if (!newparent && targetScreen != -1) {
+ if (maybeTopData())
+ maybeTopData()->screenIndex = targetScreen;
+ // only if it is already created
+ if (q->testAttribute(Qt::WA_WState_Created)) {
+ q->windowHandle()->setScreen(QGuiApplication::screens().value(targetScreen, 0));
+ }
+ }
+}
+
+QPoint QWidget::mapToGlobal(const QPoint &pos) const
+{
+ int x = pos.x(), y = pos.y();
+ const QWidget *w = this;
+ while (w) {
+ x += w->data->crect.x();
+ y += w->data->crect.y();
+ w = w->isWindow() ? 0 : w->parentWidget();
+ }
+ return QPoint(x, y);
+}
+
+QPoint QWidget::mapFromGlobal(const QPoint &pos) const
+{
+ int x = pos.x(), y = pos.y();
+ const QWidget *w = this;
+ while (w) {
+ x -= w->data->crect.x();
+ y -= w->data->crect.y();
+ w = w->isWindow() ? 0 : w->parentWidget();
+ }
+ return QPoint(x, y);
+}
+
+void QWidgetPrivate::updateSystemBackground() {}
+
+#ifndef QT_NO_CURSOR
+void QWidgetPrivate::setCursor_sys(const QCursor &cursor)
+{
+ Q_UNUSED(cursor);
+ Q_Q(QWidget);
+ qt_qpa_set_cursor(q, false);
+}
+
+void QWidgetPrivate::unsetCursor_sys()
+{
+ Q_Q(QWidget);
+ qt_qpa_set_cursor(q, false);
+}
+
+#endif //QT_NO_CURSOR
+
+void QWidgetPrivate::setWindowTitle_sys(const QString &caption)
+{
+ Q_Q(QWidget);
+ if (!q->isWindow())
+ return;
+
+ if (QWindow *window = q->windowHandle())
+ window->setWindowTitle(caption);
+
+}
+
+void QWidgetPrivate::setWindowIcon_sys(bool /*forceReset*/)
+{
+}
+
+void QWidgetPrivate::setWindowIconText_sys(const QString &iconText)
+{
+ Q_UNUSED(iconText);
+}
+
+QWidget *qt_pressGrab = 0;
+QWidget *qt_mouseGrb = 0;
+static QWidget *keyboardGrb = 0;
+
+void QWidget::grabMouse()
+{
+ if (qt_mouseGrb)
+ qt_mouseGrb->releaseMouse();
+
+ if (windowHandle())
+ windowHandle()->setMouseGrabEnabled(true);
+
+ qt_mouseGrb = this;
+ qt_pressGrab = 0;
+}
+
+#ifndef QT_NO_CURSOR
+void QWidget::grabMouse(const QCursor &cursor)
+{
+ Q_UNUSED(cursor);
+
+ if (qt_mouseGrb)
+ qt_mouseGrb->releaseMouse();
+
+ if (windowHandle())
+ windowHandle()->setMouseGrabEnabled(true);
+
+ qt_mouseGrb = this;
+ qt_pressGrab = 0;
+}
+#endif
+
+bool QWidgetPrivate::stealMouseGrab(bool grab)
+{
+ // This is like a combination of grab/releaseMouse() but with error checking
+ // and it has no effect on the result of mouseGrabber().
+ Q_Q(QWidget);
+ return q->windowHandle() ? q->windowHandle()->setMouseGrabEnabled(grab) : false;
+}
+
+void QWidget::releaseMouse()
+{
+ if (qt_mouseGrb == this) {
+ if (windowHandle())
+ windowHandle()->setMouseGrabEnabled(false);
+ qt_mouseGrb = 0;
+ }
+}
+
+void QWidget::grabKeyboard()
+{
+ if (keyboardGrb)
+ keyboardGrb->releaseKeyboard();
+ if (windowHandle())
+ windowHandle()->setKeyboardGrabEnabled(true);
+ keyboardGrb = this;
+}
+
+bool QWidgetPrivate::stealKeyboardGrab(bool grab)
+{
+ // This is like a combination of grab/releaseKeyboard() but with error
+ // checking and it has no effect on the result of keyboardGrabber().
+ Q_Q(QWidget);
+ return q->windowHandle() ? q->windowHandle()->setKeyboardGrabEnabled(grab) : false;
+}
+
+void QWidget::releaseKeyboard()
+{
+ if (keyboardGrb == this) {
+ if (windowHandle())
+ windowHandle()->setKeyboardGrabEnabled(false);
+ keyboardGrb = 0;
+ }
+}
+
+QWidget *QWidget::mouseGrabber()
+{
+ if (qt_mouseGrb)
+ return qt_mouseGrb;
+ return qt_pressGrab;
+}
+
+QWidget *QWidget::keyboardGrabber()
+{
+ return keyboardGrb;
+}
+
+void QWidget::activateWindow()
+{
+ if (windowHandle())
+ windowHandle()->requestActivateWindow();
+}
+
+void QWidgetPrivate::show_sys()
+{
+ Q_Q(QWidget);
+ q->setAttribute(Qt::WA_Mapped);
+ if (q->testAttribute(Qt::WA_DontShowOnScreen)) {
+ invalidateBuffer(q->rect());
+ return;
+ }
+
+ QApplication::postEvent(q, new QUpdateLaterEvent(q->rect()));
+
+ if (!q->isWindow() && !q->testAttribute(Qt::WA_NativeWindow))
+ return;
+
+ QWindow *window = q->windowHandle();
+ if (window) {
+ QRect geomRect = q->geometry();
+ if (!q->isWindow()) {
+ QPoint topLeftOfWindow = q->mapTo(q->nativeParentWidget(),QPoint());
+ geomRect.moveTopLeft(topLeftOfWindow);
+ }
+ const QRect windowRect = window->geometry();
+ if (windowRect != geomRect) {
+ window->setGeometry(geomRect);
+ }
+
+ if (QBackingStore *store = q->backingStore()) {
+ if (store->size() != geomRect.size()) {
+ store->resize(geomRect.size());
+ }
+ }
+
+ invalidateBuffer(q->rect());
+
+ if (window)
+ window->setVisible(true);
+ }
+}
+
+
+void QWidgetPrivate::hide_sys()
+{
+ Q_Q(QWidget);
+ q->setAttribute(Qt::WA_Mapped, false);
+ deactivateWidgetCleanup();
+ if (!q->isWindow()) {
+ QWidget *p = q->parentWidget();
+ if (p &&p->isVisible()) {
+ invalidateBuffer(q->rect());
+ }
+ return;
+ }
+ if (QWindow *window = q->windowHandle()) {
+ window->setVisible(false);
+ }
+}
+
+void QWidgetPrivate::setMaxWindowState_helper()
+{
+ setFullScreenSize_helper(); //### decoration size
+}
+
+void QWidgetPrivate::setFullScreenSize_helper()
+{
+ Q_Q(QWidget);
+
+ const uint old_state = data.in_set_window_state;
+ data.in_set_window_state = 1;
+
+ const QRect screen = qApp->desktop()->screenGeometry(qApp->desktop()->screenNumber(q));
+ q->move(screen.topLeft());
+ q->resize(screen.size());
+
+ data.in_set_window_state = old_state;
+}
+
+static Qt::WindowState effectiveState(Qt::WindowStates state)
+ {
+ if (state & Qt::WindowMinimized)
+ return Qt::WindowMinimized;
+ else if (state & Qt::WindowFullScreen)
+ return Qt::WindowFullScreen;
+ else if (state & Qt::WindowMaximized)
+ return Qt::WindowMaximized;
+ return Qt::WindowNoState;
+ }
+
+void QWidget::setWindowState(Qt::WindowStates newstate)
+{
+ Q_D(QWidget);
+ Qt::WindowStates oldstate = windowState();
+ if (oldstate == newstate)
+ return;
+ if (isWindow() && !testAttribute(Qt::WA_WState_Created))
+ create();
+
+ data->window_state = newstate;
+ data->in_set_window_state = 1;
+ bool needShow = false;
+ Qt::WindowState newEffectiveState = effectiveState(newstate);
+ Qt::WindowState oldEffectiveState = effectiveState(oldstate);
+ if (isWindow() && newEffectiveState != oldEffectiveState) {
+ d->createTLExtra();
+ if (oldEffectiveState == Qt::WindowNoState) { //normal
+ d->topData()->normalGeometry = geometry();
+ } else if (oldEffectiveState == Qt::WindowFullScreen) {
+ setParent(0, d->topData()->savedFlags);
+ needShow = true;
+ } else if (oldEffectiveState == Qt::WindowMinimized) {
+ needShow = true;
+ }
+
+ Q_ASSERT(windowHandle());
+ windowHandle()->setWindowState(newEffectiveState);
+ bool supported = windowHandle()->windowState() == newEffectiveState;
+
+ if (!supported) {
+ // emulate the window state
+ if (newEffectiveState == Qt::WindowMinimized) {
+ //### not ideal...
+ hide();
+ needShow = false;
+ } else if (newEffectiveState == Qt::WindowFullScreen) {
+ d->topData()->savedFlags = windowFlags();
+ setParent(0, Qt::FramelessWindowHint | (windowFlags() & Qt::WindowStaysOnTopHint));
+ d->setFullScreenSize_helper();
+ raise();
+ needShow = true;
+ } else if (newEffectiveState == Qt::WindowMaximized) {
+ createWinId();
+ d->setMaxWindowState_helper();
+ } else if (newEffectiveState == Qt::WindowNoState) {
+ // reset old geometry
+ QRect r = d->topData()->normalGeometry;
+ if (r.width() >= 0) {
+ d->topData()->normalGeometry = QRect(0,0,-1,-1);
+ setGeometry(r);
+ }
+ }
+ }
+ }
+ data->in_set_window_state = 0;
+
+ if (needShow)
+ show();
+
+ if (newstate & Qt::WindowActive)
+ activateWindow();
+
+ QWindowStateChangeEvent e(oldstate);
+ QApplication::sendEvent(this, &e);
+}
+
+void QWidgetPrivate::setFocus_sys()
+{
+
+}
+
+void QWidgetPrivate::raise_sys()
+{
+ Q_Q(QWidget);
+ if (q->isWindow()) {
+ q->windowHandle()->raise();
+ }
+}
+
+void QWidgetPrivate::lower_sys()
+{
+ Q_Q(QWidget);
+ if (q->isWindow()) {
+ Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
+ q->windowHandle()->lower();
+ } else if (QWidget *p = q->parentWidget()) {
+ setDirtyOpaqueRegion();
+ p->d_func()->invalidateBuffer(effectiveRectFor(q->geometry()));
+ }
+}
+
+void QWidgetPrivate::stackUnder_sys(QWidget*)
+{
+ Q_Q(QWidget);
+ if (QWidget *p = q->parentWidget()) {
+ setDirtyOpaqueRegion();
+ p->d_func()->invalidateBuffer(effectiveRectFor(q->geometry()));
+ }
+}
+
+void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove)
+{
+ Q_Q(QWidget);
+ if (extra) { // any size restrictions?
+ w = qMin(w,extra->maxw);
+ h = qMin(h,extra->maxh);
+ w = qMax(w,extra->minw);
+ h = qMax(h,extra->minh);
+ }
+
+ QPoint oldp = q->geometry().topLeft();
+ QSize olds = q->size();
+ QRect r(x, y, w, h);
+
+ bool isResize = olds != r.size();
+ isMove = oldp != r.topLeft(); //### why do we have isMove as a parameter?
+
+
+ // We only care about stuff that changes the geometry, or may
+ // cause the window manager to change its state
+ if (r.size() == olds && oldp == r.topLeft())
+ return;
+
+ if (!data.in_set_window_state) {
+ q->data->window_state &= ~Qt::WindowMaximized;
+ q->data->window_state &= ~Qt::WindowFullScreen;
+ if (q->isWindow())
+ topData()->normalGeometry = QRect(0, 0, -1, -1);
+ }
+
+ QPoint oldPos = q->pos();
+ data.crect = r;
+
+ bool needsShow = false;
+
+ if (w == 0 || h == 0) {
+ q->setAttribute(Qt::WA_OutsideWSRange, true);
+ if (q->isVisible() && q->testAttribute(Qt::WA_Mapped))
+ hide_sys();
+ data.crect = QRect(x, y, w, h);
+ } else if (q->isVisible() && q->testAttribute(Qt::WA_OutsideWSRange)) {
+ q->setAttribute(Qt::WA_OutsideWSRange, false);
+ needsShow = true;
+ }
+
+ if (q->isVisible()) {
+ if (!q->testAttribute(Qt::WA_DontShowOnScreen) && !q->testAttribute(Qt::WA_OutsideWSRange)) {
+ if (q->windowHandle()) {
+ if (q->isWindow()) {
+ q->windowHandle()->setGeometry(q->geometry());
+ } else {
+ QPoint posInNativeParent = q->mapTo(q->nativeParentWidget(),QPoint());
+ q->windowHandle()->setGeometry(QRect(posInNativeParent,r.size()));
+ }
+ const QWidgetBackingStore *bs = maybeBackingStore();
+ if (bs->store) {
+ if (isResize)
+ bs->store->resize(r.size());
+ }
+
+ if (needsShow)
+ show_sys();
+ } else {
+ if (isMove && !isResize)
+ moveRect(QRect(oldPos, olds), x - oldPos.x(), y - oldPos.y());
+ else
+ invalidateBuffer_resizeHelper(oldPos, olds);
+ }
+ }
+
+ if (isMove) {
+ QMoveEvent e(q->pos(), oldPos);
+ QApplication::sendEvent(q, &e);
+ }
+ if (isResize) {
+ QResizeEvent e(r.size(), olds);
+ QApplication::sendEvent(q, &e);
+ if (q->windowHandle())
+ q->update();
+ }
+ } else { // not visible
+ if (isMove && q->pos() != oldPos)
+ q->setAttribute(Qt::WA_PendingMoveEvent, true);
+ if (isResize)
+ q->setAttribute(Qt::WA_PendingResizeEvent, true);
+ }
+
+}
+
+void QWidgetPrivate::setConstraints_sys()
+{
+ Q_Q(QWidget);
+ if (extra && q->windowHandle()) {
+ QWindow *win = q->windowHandle();
+ QWindowPrivate *winp = qt_window_private(win);
+
+ winp->minimumSize = QSize(extra->minw, extra->minh);
+ winp->maximumSize = QSize(extra->maxw, extra->maxh);
+
+ if (extra->topextra) {
+ winp->baseSize = QSize(extra->topextra->basew, extra->topextra->baseh);
+ winp->sizeIncrement = QSize(extra->topextra->incw, extra->topextra->inch);
+ }
+
+ if (winp->platformWindow)
+ winp->platformWindow->propagateSizeHints();
+ }
+}
+
+void QWidgetPrivate::scroll_sys(int dx, int dy)
+{
+ Q_Q(QWidget);
+ scrollChildren(dx, dy);
+ scrollRect(q->rect(), dx, dy);
+}
+
+void QWidgetPrivate::scroll_sys(int dx, int dy, const QRect &r)
+{
+ scrollRect(r, dx, dy);
+}
+
+int QWidget::metric(PaintDeviceMetric m) const
+{
+ Q_D(const QWidget);
+
+ QPlatformScreen *screen = 0;
+ if (QWidget *topLevel = window())
+ if (QWindow *topLevelWindow = topLevel->windowHandle())
+ screen = QPlatformScreen::platformScreenForWindow(topLevelWindow);
+ if (!screen && QGuiApplication::primaryScreen())
+ screen = QGuiApplication::primaryScreen()->handle();
+
+ if (!screen) {
+ if (m == PdmDpiX || m == PdmDpiY)
+ return 72;
+ return QPaintDevice::metric(m);
+ }
+ int val;
+ if (m == PdmWidth) {
+ val = data->crect.width();
+ } else if (m == PdmWidthMM) {
+ val = data->crect.width() * screen->physicalSize().width() / screen->geometry().width();
+ } else if (m == PdmHeight) {
+ val = data->crect.height();
+ } else if (m == PdmHeightMM) {
+ val = data->crect.height() * screen->physicalSize().height() / screen->geometry().height();
+ } else if (m == PdmDepth) {
+ return screen->depth();
+ } else if (m == PdmDpiX || m == PdmPhysicalDpiX) {
+ if (d->extra && d->extra->customDpiX)
+ return d->extra->customDpiX;
+ else if (d->parent)
+ return static_cast<QWidget *>(d->parent)->metric(m);
+ return qRound(screen->geometry().width() / double(screen->physicalSize().width() / 25.4));
+ } else if (m == PdmDpiY || m == PdmPhysicalDpiY) {
+ if (d->extra && d->extra->customDpiY)
+ return d->extra->customDpiY;
+ else if (d->parent)
+ return static_cast<QWidget *>(d->parent)->metric(m);
+ return qRound(screen->geometry().height() / double(screen->physicalSize().height() / 25.4));
+ } else {
+ val = QPaintDevice::metric(m);// XXX
+ }
+ return val;
+}
+
+/*!
+ \preliminary
+
+ Returns the QPlatformWindow this widget will be drawn into.
+*/
+QWindow *QWidget::windowHandle() const
+{
+ Q_D(const QWidget);
+ QTLWExtra *extra = d->maybeTopData();
+ if (extra)
+ return extra->window;
+
+ return 0;
+}
+
+void QWidgetPrivate::createSysExtra()
+{
+}
+
+void QWidgetPrivate::deleteSysExtra()
+{
+
+}
+
+void QWidgetPrivate::createTLSysExtra()
+{
+ Q_Q(QWidget);
+ extra->topextra->screenIndex = 0;
+ extra->topextra->window = 0;
+ if (q->testAttribute(Qt::WA_NativeWindow) || q->isWindow())
+ extra->topextra->window = new QWidgetWindow(q);
+}
+
+void QWidgetPrivate::deleteTLSysExtra()
+{
+ if (extra && extra->topextra) {
+ //the toplevel might have a context with a "qglcontext associated with it. We need to
+ //delete the qglcontext before we delete the qplatformopenglcontext.
+ //One unfortunate thing about this is that we potentially create a glContext just to
+ //delete it straight afterwards.
+ if (extra->topextra->window) {
+ extra->topextra->window->destroy();
+ }
+ setWinId(0);
+ //hmmm. should we delete window..
+ delete extra->topextra->window;
+ extra->topextra->window = 0;
+ }
+}
+
+void QWidgetPrivate::registerDropSite(bool on)
+{
+ Q_UNUSED(on);
+}
+
+void QWidgetPrivate::setMask_sys(const QRegion &region)
+{
+ Q_UNUSED(region);
+ // XXX
+}
+
+void QWidgetPrivate::updateFrameStrut()
+{
+ // XXX
+}
+
+void QWidgetPrivate::setWindowOpacity_sys(qreal level)
+{
+ Q_Q(QWidget);
+ if (q->windowHandle())
+ q->windowHandle()->setOpacity(level);
+}
+
+void QWidgetPrivate::setWSGeometry(bool dontShow, const QRect &oldRect)
+{
+ Q_UNUSED(dontShow);
+ Q_UNUSED(oldRect);
+ // XXX
+}
+
+QPaintEngine *QWidget::paintEngine() const
+{
+ qWarning("QWidget::paintEngine: Should no longer be called");
+ return 0; //##### @@@
+}
+
+void QWidgetPrivate::setModal_sys()
+{
+ Q_Q(QWidget);
+ if (q->windowHandle())
+ q->windowHandle()->setWindowModality(q->windowModality());
+}
+
+#ifndef QT_NO_CURSOR
+static void applyCursor(QWidget *w, const QCursor &c)
+{
+ QCursor cc = c;
+ QList<QWeakPointer<QPlatformCursor> > cursors = QPlatformCursorPrivate::getInstances();
+ int cursorCount = cursors.count();
+ for (int i = 0; i < cursorCount; ++i) {
+ const QWeakPointer<QPlatformCursor> &cursor(cursors.at(i));
+ if (cursor)
+ cursor.data()->changeCursor(&cc, w->window()->windowHandle());
+ }
+}
+
+void qt_qpa_set_cursor(QWidget *w, bool force)
+{
+ if (!w->testAttribute(Qt::WA_WState_Created))
+ return;
+
+ static QPointer<QWidget> lastUnderMouse = 0;
+ if (force) {
+ lastUnderMouse = w;
+ } else if (lastUnderMouse && lastUnderMouse->effectiveWinId() == w->effectiveWinId()) {
+ w = lastUnderMouse;
+ } else if (!w->internalWinId()) {
+ return; // The mouse is not under this widget, and it's not native, so don't change it.
+ }
+
+ while (!w->internalWinId() && w->parentWidget() && !w->isWindow()
+ && !w->testAttribute(Qt::WA_SetCursor))
+ w = w->parentWidget();
+
+ QWidget *nativeParent = w;
+ if (!w->internalWinId())
+ nativeParent = w->nativeParentWidget();
+ if (!nativeParent || !nativeParent->internalWinId())
+ return;
+
+ if (w->isWindow() || w->testAttribute(Qt::WA_SetCursor)) {
+ QCursor *oc = QApplication::overrideCursor();
+ if (oc)
+ applyCursor(nativeParent, *oc);
+ else if (w->isEnabled())
+ applyCursor(nativeParent, w->cursor());
+ else
+ // Enforce the windows behavior of clearing the cursor on
+ // disabled widgets.
+ applyCursor(nativeParent, Qt::ArrowCursor);
+ } else {
+ applyCursor(nativeParent, Qt::ArrowCursor);
+ }
+}
+#endif //QT_NO_CURSOR
+
+QT_END_NAMESPACE
diff --git a/src/gui/kernel/qwidgetaction.cpp b/src/widgets/kernel/qwidgetaction.cpp
index 03acb7836b..03acb7836b 100644
--- a/src/gui/kernel/qwidgetaction.cpp
+++ b/src/widgets/kernel/qwidgetaction.cpp
diff --git a/src/widgets/kernel/qwidgetaction.h b/src/widgets/kernel/qwidgetaction.h
new file mode 100644
index 0000000000..31d58a819a
--- /dev/null
+++ b/src/widgets/kernel/qwidgetaction.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWIDGETACTION_H
+#define QWIDGETACTION_H
+
+#include <QtWidgets/qaction.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_ACTION
+
+class QWidgetActionPrivate;
+
+class Q_WIDGETS_EXPORT QWidgetAction : public QAction
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QWidgetAction)
+
+public:
+ explicit QWidgetAction(QObject *parent);
+ virtual ~QWidgetAction();
+
+ void setDefaultWidget(QWidget *w);
+ QWidget *defaultWidget() const;
+
+ QWidget *requestWidget(QWidget *parent);
+ void releaseWidget(QWidget *widget);
+
+protected:
+ virtual bool event(QEvent *);
+ virtual bool eventFilter(QObject *, QEvent *);
+ virtual QWidget *createWidget(QWidget *parent);
+ virtual void deleteWidget(QWidget *widget);
+ QList<QWidget *> createdWidgets() const;
+
+private:
+ Q_DISABLE_COPY(QWidgetAction)
+ Q_PRIVATE_SLOT(d_func(), void _q_widgetDestroyed(QObject *))
+ friend class QToolBar;
+};
+
+#endif // QT_NO_ACTION
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QWIDGETACTION_H
diff --git a/src/gui/kernel/qwidgetaction_p.h b/src/widgets/kernel/qwidgetaction_p.h
index 99439d9919..99439d9919 100644
--- a/src/gui/kernel/qwidgetaction_p.h
+++ b/src/widgets/kernel/qwidgetaction_p.h
diff --git a/src/widgets/kernel/qwidgetbackingstore.cpp b/src/widgets/kernel/qwidgetbackingstore.cpp
new file mode 100644
index 0000000000..d151d5e9e1
--- /dev/null
+++ b/src/widgets/kernel/qwidgetbackingstore.cpp
@@ -0,0 +1,1393 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "qplatformdefs.h"
+
+#include "qwidgetbackingstore_p.h"
+
+#include <QtCore/qglobal.h>
+#include <QtCore/qdebug.h>
+#include <QtCore/qvarlengtharray.h>
+#include <QtGui/qevent.h>
+#include <QtWidgets/qapplication.h>
+#include <QtGui/qpaintengine.h>
+#include <QtWidgets/qgraphicsproxywidget.h>
+
+#include <private/qwidget_p.h>
+#include <private/qapplication_p.h>
+#include <private/qpaintengine_raster_p.h>
+#include <private/qgraphicseffect_p.h>
+
+#ifdef Q_WS_QWS
+#include <QtGui/qwsmanager_qws.h>
+#include <private/qwsmanager_p.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+extern QRegion qt_dirtyRegion(QWidget *);
+
+/*
+ A version of QRect::intersects() that does not normalize the rects.
+*/
+static inline bool qRectIntersects(const QRect &r1, const QRect &r2)
+{
+ return (qMax(r1.left(), r2.left()) <= qMin(r1.right(), r2.right())
+ && qMax(r1.top(), r2.top()) <= qMin(r1.bottom(), r2.bottom()));
+}
+
+/**
+ * Flushes the contents of the \a backingStore into the screen area of \a widget.
+ * \a tlwOffset is the position of the top level widget relative to the window surface.
+ * \a region is the region to be updated in \a widget coordinates.
+ */
+static inline void qt_flush(QWidget *widget, const QRegion &region, QBackingStore *backingStore,
+ QWidget *tlw, const QPoint &tlwOffset)
+{
+ Q_ASSERT(widget);
+ Q_ASSERT(!region.isEmpty());
+ Q_ASSERT(backingStore);
+ Q_ASSERT(tlw);
+
+#if !defined(QT_NO_PAINT_DEBUG)
+ static int flushUpdate = qgetenv("QT_FLUSH_UPDATE").toInt();
+ if (flushUpdate > 0)
+ QWidgetBackingStore::showYellowThing(widget, region, flushUpdate * 10, false);
+#endif
+
+ //The performance hit by doing this should be negligible. However, be aware that
+ //using this FPS when you have > 1 windowsurface can give you inaccurate FPS
+ static bool fpsDebug = qgetenv("QT_DEBUG_FPS").toInt();
+ if (fpsDebug) {
+ static QTime time = QTime::currentTime();
+ static int frames = 0;
+
+ frames++;
+
+ if(time.elapsed() > 5000) {
+ double fps = double(frames * 1000) /time.restart();
+ fprintf(stderr,"FPS: %.1f\n",fps);
+ frames = 0;
+ }
+ }
+ if (widget != tlw)
+ backingStore->flush(region, widget->windowHandle(), tlwOffset + widget->mapTo(tlw, QPoint()));
+ else
+ backingStore->flush(region, widget->windowHandle(), tlwOffset);
+}
+
+#ifndef QT_NO_PAINT_DEBUG
+#ifdef Q_WS_WIN
+static void showYellowThing_win(QWidget *widget, const QRegion &region, int msec)
+{
+ HBRUSH brush;
+ static int i = 0;
+ switch (i) {
+ case 0:
+ brush = CreateSolidBrush(RGB(255, 255, 0));
+ break;
+ case 1:
+ brush = CreateSolidBrush(RGB(255, 200, 55));
+ break;
+ case 2:
+ brush = CreateSolidBrush(RGB(200, 255, 55));
+ break;
+ case 3:
+ brush = CreateSolidBrush(RGB(200, 200, 0));
+ break;
+ }
+ i = (i + 1) & 3;
+
+ HDC hdc = widget->getDC();
+
+ const QVector<QRect> &rects = region.rects();
+ foreach (QRect rect, rects) {
+ RECT winRect;
+ SetRect(&winRect, rect.left(), rect.top(), rect.right(), rect.bottom());
+ FillRect(hdc, &winRect, brush);
+ }
+
+ widget->releaseDC(hdc);
+ ::Sleep(msec);
+}
+#endif
+
+void QWidgetBackingStore::showYellowThing(QWidget *widget, const QRegion &toBePainted, int msec, bool unclipped)
+{
+#ifdef Q_WS_QWS
+ Q_UNUSED(widget);
+ Q_UNUSED(unclipped);
+ static QWSYellowSurface surface(true);
+ surface.setDelay(msec);
+ surface.flush(widget, toBePainted, QPoint());
+#else
+ QRegion paintRegion = toBePainted;
+ QRect widgetRect = widget->rect();
+
+ if (!widget->internalWinId()) {
+ QWidget *nativeParent = widget->nativeParentWidget();
+ const QPoint offset = widget->mapTo(nativeParent, QPoint(0, 0));
+ paintRegion.translate(offset);
+ widgetRect.translate(offset);
+ widget = nativeParent;
+ }
+
+#ifdef Q_WS_WIN
+ Q_UNUSED(unclipped);
+ showYellowThing_win(widget, paintRegion, msec);
+#else
+ //flags to fool painter
+ bool paintUnclipped = widget->testAttribute(Qt::WA_PaintUnclipped);
+ if (unclipped && !widget->d_func()->paintOnScreen())
+ widget->setAttribute(Qt::WA_PaintUnclipped);
+
+ const bool setFlag = !widget->testAttribute(Qt::WA_WState_InPaintEvent);
+ if (setFlag)
+ widget->setAttribute(Qt::WA_WState_InPaintEvent);
+
+ //setup the engine
+ QPaintEngine *pe = widget->paintEngine();
+ if (pe) {
+ pe->setSystemClip(paintRegion);
+ {
+ QPainter p(widget);
+ p.setClipRegion(paintRegion);
+ static int i = 0;
+ switch (i) {
+ case 0:
+ p.fillRect(widgetRect, QColor(255,255,0));
+ break;
+ case 1:
+ p.fillRect(widgetRect, QColor(255,200,55));
+ break;
+ case 2:
+ p.fillRect(widgetRect, QColor(200,255,55));
+ break;
+ case 3:
+ p.fillRect(widgetRect, QColor(200,200,0));
+ break;
+ }
+ i = (i+1) & 3;
+ p.end();
+ }
+ }
+
+ if (setFlag)
+ widget->setAttribute(Qt::WA_WState_InPaintEvent, false);
+
+ //restore
+ widget->setAttribute(Qt::WA_PaintUnclipped, paintUnclipped);
+
+ if (pe)
+ pe->setSystemClip(QRegion());
+
+ QApplication::syncX();
+
+#if defined(Q_OS_UNIX)
+ ::usleep(1000 * msec);
+#endif
+#endif // Q_WS_WIN
+#endif // Q_WS_QWS
+}
+
+bool QWidgetBackingStore::flushPaint(QWidget *widget, const QRegion &rgn)
+{
+ if (!widget)
+ return false;
+
+ int delay = 0;
+ if (widget->testAttribute(Qt::WA_WState_InPaintEvent)) {
+ static int flushPaintEvent = qgetenv("QT_FLUSH_PAINT_EVENT").toInt();
+ if (!flushPaintEvent)
+ return false;
+ delay = flushPaintEvent;
+ } else {
+ static int flushPaint = qgetenv("QT_FLUSH_PAINT").toInt();
+ if (!flushPaint)
+ return false;
+ delay = flushPaint;
+ }
+
+ QWidgetBackingStore::showYellowThing(widget, rgn, delay * 10, true);
+ return true;
+}
+
+void QWidgetBackingStore::unflushPaint(QWidget *widget, const QRegion &rgn)
+{
+ if (widget->d_func()->paintOnScreen() || rgn.isEmpty())
+ return;
+
+ QWidget *tlw = widget->window();
+ QTLWExtra *tlwExtra = tlw->d_func()->maybeTopData();
+ if (!tlwExtra)
+ return;
+
+ const QPoint offset = widget->mapTo(tlw, QPoint());
+ qt_flush(widget, rgn, tlwExtra->backingStoreTracker->store, tlw, offset);
+}
+#endif // QT_NO_PAINT_DEBUG
+
+/*
+ Moves the whole rect by (dx, dy) in widget's coordinate system.
+ Doesn't generate any updates.
+*/
+bool QWidgetBackingStore::bltRect(const QRect &rect, int dx, int dy, QWidget *widget)
+{
+ const QPoint pos(tlwOffset + widget->mapTo(tlw, rect.topLeft()));
+ const QRect tlwRect(QRect(pos, rect.size()));
+ if (fullUpdatePending || dirty.intersects(tlwRect))
+ return false; // We don't want to scroll junk.
+ return store->scroll(tlwRect, dx, dy);
+}
+
+void QWidgetBackingStore::releaseBuffer()
+{
+ if (store)
+ store->resize(QSize());
+}
+
+/*!
+ Prepares the window surface to paint a\ toClean region of the \a widget and
+ updates the BeginPaintInfo struct accordingly.
+
+ The \a toClean region might be clipped by the window surface.
+*/
+void QWidgetBackingStore::beginPaint(QRegion &toClean, QWidget *widget, QBackingStore *backingStore,
+ BeginPaintInfo *returnInfo, bool toCleanIsInTopLevelCoordinates)
+{
+ Q_UNUSED(widget);
+ Q_UNUSED(toCleanIsInTopLevelCoordinates);
+
+ // Always flush repainted areas.
+ dirtyOnScreen += toClean;
+
+#ifdef QT_NO_PAINT_DEBUG
+ backingStore->beginPaint(toClean);
+#else
+ returnInfo->wasFlushed = QWidgetBackingStore::flushPaint(tlw, toClean);
+ // Avoid deadlock with QT_FLUSH_PAINT: the server will wait for
+ // the BackingStore lock, so if we hold that, the server will
+ // never release the Communication lock that we are waiting for in
+ // sendSynchronousCommand
+ if (!returnInfo->wasFlushed)
+ backingStore->beginPaint(toClean);
+#endif
+
+ Q_UNUSED(returnInfo);
+}
+
+void QWidgetBackingStore::endPaint(const QRegion &cleaned, QBackingStore *backingStore,
+ BeginPaintInfo *beginPaintInfo)
+{
+#ifndef QT_NO_PAINT_DEBUG
+ if (!beginPaintInfo->wasFlushed)
+ backingStore->endPaint();
+ else
+ QWidgetBackingStore::unflushPaint(tlw, cleaned);
+#else
+ Q_UNUSED(beginPaintInfo);
+ Q_UNUSED(cleaned);
+ backingStore->endPaint();
+#endif
+
+ flush();
+}
+
+/*!
+ Returns the region (in top-level coordinates) that needs repaint and/or flush.
+
+ If the widget is non-zero, only the dirty region for the widget is returned
+ and the region will be in widget coordinates.
+*/
+QRegion QWidgetBackingStore::dirtyRegion(QWidget *widget) const
+{
+ const bool widgetDirty = widget && widget != tlw;
+ const QRect tlwRect(topLevelRect());
+ const QRect surfaceGeometry(tlwRect.topLeft(), store->size());
+ if (fullUpdatePending || (surfaceGeometry != tlwRect && surfaceGeometry.size() != tlwRect.size())) {
+ if (widgetDirty) {
+ const QRect dirtyTlwRect = QRect(QPoint(), tlwRect.size());
+ const QPoint offset(widget->mapTo(tlw, QPoint()));
+ const QRect dirtyWidgetRect(dirtyTlwRect & widget->rect().translated(offset));
+ return dirtyWidgetRect.translated(-offset);
+ }
+ return QRect(QPoint(), tlwRect.size());
+ }
+
+ // Calculate the region that needs repaint.
+ QRegion r(dirty);
+ for (int i = 0; i < dirtyWidgets.size(); ++i) {
+ QWidget *w = dirtyWidgets.at(i);
+ if (widgetDirty && w != widget && !widget->isAncestorOf(w))
+ continue;
+ r += w->d_func()->dirty.translated(w->mapTo(tlw, QPoint()));
+ }
+
+ // Append the region that needs flush.
+ r += dirtyOnScreen;
+
+ if (dirtyOnScreenWidgets) { // Only in use with native child widgets.
+ for (int i = 0; i < dirtyOnScreenWidgets->size(); ++i) {
+ QWidget *w = dirtyOnScreenWidgets->at(i);
+ if (widgetDirty && w != widget && !widget->isAncestorOf(w))
+ continue;
+ QWidgetPrivate *wd = w->d_func();
+ Q_ASSERT(wd->needsFlush);
+ r += wd->needsFlush->translated(w->mapTo(tlw, QPoint()));
+ }
+ }
+
+ if (widgetDirty) {
+ // Intersect with the widget geometry and translate to its coordinates.
+ const QPoint offset(widget->mapTo(tlw, QPoint()));
+ r &= widget->rect().translated(offset);
+ r.translate(-offset);
+ }
+ return r;
+}
+
+/*!
+ Returns the static content inside the \a parent if non-zero; otherwise the static content
+ for the entire backing store is returned. The content will be clipped to \a withinClipRect
+ if non-empty.
+*/
+QRegion QWidgetBackingStore::staticContents(QWidget *parent, const QRect &withinClipRect) const
+{
+ if (!parent && tlw->testAttribute(Qt::WA_StaticContents)) {
+ const QSize surfaceGeometry(store->size());
+ QRect surfaceRect(0, 0, surfaceGeometry.width(), surfaceGeometry.height());
+ if (!withinClipRect.isEmpty())
+ surfaceRect &= withinClipRect;
+ return QRegion(surfaceRect);
+ }
+
+ QRegion region;
+ if (parent && parent->d_func()->children.isEmpty())
+ return region;
+
+ const bool clipToRect = !withinClipRect.isEmpty();
+ const int count = staticWidgets.count();
+ for (int i = 0; i < count; ++i) {
+ QWidget *w = staticWidgets.at(i);
+ QWidgetPrivate *wd = w->d_func();
+ if (!wd->isOpaque || !wd->extra || wd->extra->staticContentsSize.isEmpty()
+ || !w->isVisible() || (parent && !parent->isAncestorOf(w))) {
+ continue;
+ }
+
+ QRect rect(0, 0, wd->extra->staticContentsSize.width(), wd->extra->staticContentsSize.height());
+ const QPoint offset = w->mapTo(parent ? parent : tlw, QPoint());
+ if (clipToRect)
+ rect &= withinClipRect.translated(-offset);
+ if (rect.isEmpty())
+ continue;
+
+ rect &= wd->clipRect();
+ if (rect.isEmpty())
+ continue;
+
+ QRegion visible(rect);
+ wd->clipToEffectiveMask(visible);
+ if (visible.isEmpty())
+ continue;
+ wd->subtractOpaqueSiblings(visible, 0, /*alsoNonOpaque=*/true);
+
+ visible.translate(offset);
+ region += visible;
+ }
+
+ return region;
+}
+
+static inline void sendUpdateRequest(QWidget *widget, bool updateImmediately)
+{
+ if (!widget)
+ return;
+
+ if (updateImmediately) {
+ QEvent event(QEvent::UpdateRequest);
+ QApplication::sendEvent(widget, &event);
+ } else {
+ QApplication::postEvent(widget, new QEvent(QEvent::UpdateRequest), Qt::LowEventPriority);
+ }
+}
+
+/*!
+ Marks the region of the widget as dirty (if not already marked as dirty) and
+ posts an UpdateRequest event to the top-level widget (if not already posted).
+
+ If updateImmediately is true, the event is sent immediately instead of posted.
+
+ If invalidateBuffer is true, all widgets intersecting with the region will be dirty.
+
+ If the widget paints directly on screen, the event is sent to the widget
+ instead of the top-level widget, and invalidateBuffer is completely ignored.
+
+ ### Qt 4.6: Merge into a template function (after MSVC isn't supported anymore).
+*/
+void QWidgetBackingStore::markDirty(const QRegion &rgn, QWidget *widget, bool updateImmediately,
+ bool invalidateBuffer)
+{
+ Q_ASSERT(tlw->d_func()->extra);
+ Q_ASSERT(tlw->d_func()->extra->topextra);
+ Q_ASSERT(!tlw->d_func()->extra->topextra->inTopLevelResize);
+ Q_ASSERT(widget->isVisible() && widget->updatesEnabled());
+ Q_ASSERT(widget->window() == tlw);
+ Q_ASSERT(!rgn.isEmpty());
+
+#ifndef QT_NO_GRAPHICSEFFECT
+ widget->d_func()->invalidateGraphicsEffectsRecursively();
+#endif //QT_NO_GRAPHICSEFFECT
+
+ if (widget->d_func()->paintOnScreen()) {
+ if (widget->d_func()->dirty.isEmpty()) {
+ widget->d_func()->dirty = rgn;
+ sendUpdateRequest(widget, updateImmediately);
+ return;
+ } else if (qt_region_strictContains(widget->d_func()->dirty, widget->rect())) {
+ if (updateImmediately)
+ sendUpdateRequest(widget, updateImmediately);
+ return; // Already dirty.
+ }
+
+ const bool eventAlreadyPosted = !widget->d_func()->dirty.isEmpty();
+ widget->d_func()->dirty += rgn;
+ if (!eventAlreadyPosted || updateImmediately)
+ sendUpdateRequest(widget, updateImmediately);
+ return;
+ }
+
+ if (fullUpdatePending) {
+ if (updateImmediately)
+ sendUpdateRequest(tlw, updateImmediately);
+ return;
+ }
+
+ const QPoint offset = widget->mapTo(tlw, QPoint());
+ const QRect widgetRect = widget->d_func()->effectiveRectFor(widget->rect());
+ if (qt_region_strictContains(dirty, widgetRect.translated(offset))) {
+ if (updateImmediately)
+ sendUpdateRequest(tlw, updateImmediately);
+ return; // Already dirty.
+ }
+
+ if (invalidateBuffer) {
+ const bool eventAlreadyPosted = !dirty.isEmpty();
+#ifndef QT_NO_GRAPHICSEFFECT
+ if (widget->d_func()->graphicsEffect)
+ dirty += widget->d_func()->effectiveRectFor(rgn.boundingRect()).translated(offset);
+ else
+#endif //QT_NO_GRAPHICSEFFECT
+ dirty += rgn.translated(offset);
+ if (!eventAlreadyPosted || updateImmediately)
+ sendUpdateRequest(tlw, updateImmediately);
+ return;
+ }
+
+ if (dirtyWidgets.isEmpty()) {
+ addDirtyWidget(widget, rgn);
+ sendUpdateRequest(tlw, updateImmediately);
+ return;
+ }
+
+ if (widget->d_func()->inDirtyList) {
+ if (!qt_region_strictContains(widget->d_func()->dirty, widgetRect)) {
+#ifndef QT_NO_GRAPHICSEFFECT
+ if (widget->d_func()->graphicsEffect)
+ widget->d_func()->dirty += widget->d_func()->effectiveRectFor(rgn.boundingRect());
+ else
+#endif //QT_NO_GRAPHICSEFFECT
+ widget->d_func()->dirty += rgn;
+ }
+ } else {
+ addDirtyWidget(widget, rgn);
+ }
+
+ if (updateImmediately)
+ sendUpdateRequest(tlw, updateImmediately);
+}
+
+/*!
+ This function is equivalent to calling markDirty(QRegion(rect), ...), but
+ is more efficient as it eliminates QRegion operations/allocations and can
+ use the rect more precisely for additional cut-offs.
+
+ ### Qt 4.6: Merge into a template function (after MSVC isn't supported anymore).
+*/
+void QWidgetBackingStore::markDirty(const QRect &rect, QWidget *widget, bool updateImmediately,
+ bool invalidateBuffer)
+{
+ Q_ASSERT(tlw->d_func()->extra);
+ Q_ASSERT(tlw->d_func()->extra->topextra);
+ Q_ASSERT(!tlw->d_func()->extra->topextra->inTopLevelResize);
+ Q_ASSERT(widget->isVisible() && widget->updatesEnabled());
+ Q_ASSERT(widget->window() == tlw);
+ Q_ASSERT(!rect.isEmpty());
+
+#ifndef QT_NO_GRAPHICSEFFECT
+ widget->d_func()->invalidateGraphicsEffectsRecursively();
+#endif //QT_NO_GRAPHICSEFFECT
+
+ if (widget->d_func()->paintOnScreen()) {
+ if (widget->d_func()->dirty.isEmpty()) {
+ widget->d_func()->dirty = QRegion(rect);
+ sendUpdateRequest(widget, updateImmediately);
+ return;
+ } else if (qt_region_strictContains(widget->d_func()->dirty, rect)) {
+ if (updateImmediately)
+ sendUpdateRequest(widget, updateImmediately);
+ return; // Already dirty.
+ }
+
+ const bool eventAlreadyPosted = !widget->d_func()->dirty.isEmpty();
+ widget->d_func()->dirty += rect;
+ if (!eventAlreadyPosted || updateImmediately)
+ sendUpdateRequest(widget, updateImmediately);
+ return;
+ }
+
+ if (fullUpdatePending) {
+ if (updateImmediately)
+ sendUpdateRequest(tlw, updateImmediately);
+ return;
+ }
+
+ const QRect widgetRect = widget->d_func()->effectiveRectFor(rect);
+ const QRect translatedRect(widgetRect.translated(widget->mapTo(tlw, QPoint())));
+ if (qt_region_strictContains(dirty, translatedRect)) {
+ if (updateImmediately)
+ sendUpdateRequest(tlw, updateImmediately);
+ return; // Already dirty
+ }
+
+ if (invalidateBuffer) {
+ const bool eventAlreadyPosted = !dirty.isEmpty();
+ dirty += translatedRect;
+ if (!eventAlreadyPosted || updateImmediately)
+ sendUpdateRequest(tlw, updateImmediately);
+ return;
+ }
+
+ if (dirtyWidgets.isEmpty()) {
+ addDirtyWidget(widget, rect);
+ sendUpdateRequest(tlw, updateImmediately);
+ return;
+ }
+
+ if (widget->d_func()->inDirtyList) {
+ if (!qt_region_strictContains(widget->d_func()->dirty, widgetRect))
+ widget->d_func()->dirty += widgetRect;
+ } else {
+ addDirtyWidget(widget, rect);
+ }
+
+ if (updateImmediately)
+ sendUpdateRequest(tlw, updateImmediately);
+}
+
+/*!
+ Marks the \a region of the \a widget as dirty on screen. The \a region will be copied from
+ the backing store to the \a widget's native parent next time flush() is called.
+
+ Paint on screen widgets are ignored.
+*/
+void QWidgetBackingStore::markDirtyOnScreen(const QRegion &region, QWidget *widget, const QPoint &topLevelOffset)
+{
+ if (!widget || widget->d_func()->paintOnScreen() || region.isEmpty())
+ return;
+
+#if defined(Q_WS_QWS) || defined(Q_WS_MAC)
+ if (!widget->testAttribute(Qt::WA_WState_InPaintEvent))
+ dirtyOnScreen += region.translated(topLevelOffset);
+ return;
+#endif
+
+ // Top-level.
+ if (widget == tlw) {
+ if (!widget->testAttribute(Qt::WA_WState_InPaintEvent))
+ dirtyOnScreen += region;
+ return;
+ }
+
+ // Alien widgets.
+ if (!widget->internalWinId() && !widget->isWindow()) {
+ QWidget *nativeParent = widget->nativeParentWidget(); // Alien widgets with the top-level as the native parent (common case).
+ if (nativeParent == tlw) {
+ if (!widget->testAttribute(Qt::WA_WState_InPaintEvent))
+ dirtyOnScreen += region.translated(topLevelOffset);
+ return;
+ }
+
+ // Alien widgets with native parent != tlw.
+ QWidgetPrivate *nativeParentPrivate = nativeParent->d_func();
+ if (!nativeParentPrivate->needsFlush)
+ nativeParentPrivate->needsFlush = new QRegion;
+ const QPoint nativeParentOffset = widget->mapTo(nativeParent, QPoint());
+ *nativeParentPrivate->needsFlush += region.translated(nativeParentOffset);
+ appendDirtyOnScreenWidget(nativeParent);
+ return;
+ }
+
+ // Native child widgets.
+ QWidgetPrivate *widgetPrivate = widget->d_func();
+ if (!widgetPrivate->needsFlush)
+ widgetPrivate->needsFlush = new QRegion;
+ *widgetPrivate->needsFlush += region;
+ appendDirtyOnScreenWidget(widget);
+}
+
+void QWidgetBackingStore::removeDirtyWidget(QWidget *w)
+{
+ if (!w)
+ return;
+
+ dirtyWidgetsRemoveAll(w);
+ dirtyOnScreenWidgetsRemoveAll(w);
+ resetWidget(w);
+
+ QWidgetPrivate *wd = w->d_func();
+ const int n = wd->children.count();
+ for (int i = 0; i < n; ++i) {
+ if (QWidget *child = qobject_cast<QWidget*>(wd->children.at(i)))
+ removeDirtyWidget(child);
+ }
+}
+
+void QWidgetBackingStore::updateLists(QWidget *cur)
+{
+ if (!cur)
+ return;
+
+ QList<QObject*> children = cur->children();
+ for (int i = 0; i < children.size(); ++i) {
+ QWidget *child = qobject_cast<QWidget*>(children.at(i));
+ if (!child)
+ continue;
+
+ updateLists(child);
+ }
+
+ if (cur->testAttribute(Qt::WA_StaticContents))
+ addStaticWidget(cur);
+}
+
+QWidgetBackingStore::QWidgetBackingStore(QWidget *topLevel)
+ : tlw(topLevel), dirtyOnScreenWidgets(0), hasDirtyFromPreviousSync(false)
+ , fullUpdatePending(0)
+{
+ store = tlw->backingStore();
+ Q_ASSERT(store);
+
+ // Ensure all existing subsurfaces and static widgets are added to their respective lists.
+ updateLists(topLevel);
+}
+
+QWidgetBackingStore::~QWidgetBackingStore()
+{
+ for (int c = 0; c < dirtyWidgets.size(); ++c) {
+ resetWidget(dirtyWidgets.at(c));
+ }
+
+ delete dirtyOnScreenWidgets;
+ dirtyOnScreenWidgets = 0;
+}
+
+//parent's coordinates; move whole rect; update parent and widget
+//assume the screen blt has already been done, so we don't need to refresh that part
+void QWidgetPrivate::moveRect(const QRect &rect, int dx, int dy)
+{
+ Q_Q(QWidget);
+ if (!q->isVisible() || (dx == 0 && dy == 0))
+ return;
+
+ QWidget *tlw = q->window();
+ QTLWExtra* x = tlw->d_func()->topData();
+ if (x->inTopLevelResize)
+ return;
+
+ static int accelEnv = -1;
+ if (accelEnv == -1) {
+ accelEnv = qgetenv("QT_NO_FAST_MOVE").toInt() == 0;
+ }
+
+ QWidget *pw = q->parentWidget();
+ QPoint toplevelOffset = pw->mapTo(tlw, QPoint());
+ QWidgetPrivate *pd = pw->d_func();
+ QRect clipR(pd->clipRect());
+#ifdef Q_WS_QWS
+ QWidgetBackingStore *wbs = x->backingStore.data();
+ QWSWindowSurface *surface = static_cast<QWSWindowSurface*>(wbs->windowSurface);
+ clipR = clipR.intersected(surface->clipRegion().translated(-toplevelOffset).boundingRect());
+#endif
+ const QRect newRect(rect.translated(dx, dy));
+ QRect destRect = rect.intersected(clipR);
+ if (destRect.isValid())
+ destRect = destRect.translated(dx, dy).intersected(clipR);
+ const QRect sourceRect(destRect.translated(-dx, -dy));
+ const QRect parentRect(rect & clipR);
+
+ bool accelerateMove = accelEnv && isOpaque
+#ifndef QT_NO_GRAPHICSVIEW
+ // No accelerate move for proxy widgets.
+ && !tlw->d_func()->extra->proxyWidget
+#endif
+ && !isOverlapped(sourceRect) && !isOverlapped(destRect);
+
+ if (!accelerateMove) {
+ QRegion parentR(effectiveRectFor(parentRect));
+ if (!extra || !extra->hasMask) {
+ parentR -= newRect;
+ } else {
+ // invalidateBuffer() excludes anything outside the mask
+ parentR += newRect & clipR;
+ }
+ pd->invalidateBuffer(parentR);
+ invalidateBuffer((newRect & clipR).translated(-data.crect.topLeft()));
+ } else {
+
+ QWidgetBackingStore *wbs = x->backingStoreTracker.data();
+ QRegion childExpose(newRect & clipR);
+
+ if (sourceRect.isValid() && wbs->bltRect(sourceRect, dx, dy, pw))
+ childExpose -= destRect;
+
+ if (!pw->updatesEnabled())
+ return;
+
+ const bool childUpdatesEnabled = q->updatesEnabled();
+ if (childUpdatesEnabled && !childExpose.isEmpty()) {
+ childExpose.translate(-data.crect.topLeft());
+ wbs->markDirty(childExpose, q);
+ isMoved = true;
+ }
+
+ QRegion parentExpose(parentRect);
+ parentExpose -= newRect;
+ if (extra && extra->hasMask)
+ parentExpose += QRegion(newRect) - extra->mask.translated(data.crect.topLeft());
+
+ if (!parentExpose.isEmpty()) {
+ wbs->markDirty(parentExpose, pw);
+ pd->isMoved = true;
+ }
+
+ if (childUpdatesEnabled) {
+ QRegion needsFlush(sourceRect);
+ needsFlush += destRect;
+ wbs->markDirtyOnScreen(needsFlush, pw, toplevelOffset);
+ }
+ }
+}
+
+//widget's coordinates; scroll within rect; only update widget
+void QWidgetPrivate::scrollRect(const QRect &rect, int dx, int dy)
+{
+ Q_Q(QWidget);
+ QWidget *tlw = q->window();
+ QTLWExtra* x = tlw->d_func()->topData();
+ if (x->inTopLevelResize)
+ return;
+
+ QWidgetBackingStore *wbs = x->backingStoreTracker.data();
+ if (!wbs)
+ return;
+
+ static int accelEnv = -1;
+ if (accelEnv == -1) {
+ accelEnv = qgetenv("QT_NO_FAST_SCROLL").toInt() == 0;
+ }
+
+ QRect scrollRect = rect & clipRect();
+ bool overlapped = false;
+ bool accelerateScroll = accelEnv && isOpaque
+ && !(overlapped = isOverlapped(scrollRect.translated(data.crect.topLeft())));
+
+#if defined(Q_WS_QWS)
+ QWSWindowSurface *surface;
+ surface = static_cast<QWSWindowSurface*>(wbs->windowSurface);
+
+ if (accelerateScroll && !surface->isBuffered()) {
+ const QRegion surfaceClip = surface->clipRegion();
+ const QRegion outsideClip = QRegion(rect) - surfaceClip;
+ if (!outsideClip.isEmpty()) {
+ const QVector<QRect> clipped = (surfaceClip & rect).rects();
+ if (clipped.size() < 8) {
+ for (int i = 0; i < clipped.size(); ++i)
+ this->scrollRect(clipped.at(i), dx, dy);
+ return;
+ } else {
+ accelerateScroll = false;
+ }
+ }
+ }
+#endif // Q_WS_QWS
+
+ if (!accelerateScroll) {
+ if (overlapped) {
+ QRegion region(scrollRect);
+ subtractOpaqueSiblings(region);
+ invalidateBuffer(region);
+ }else {
+ invalidateBuffer(scrollRect);
+ }
+ } else {
+ const QPoint toplevelOffset = q->mapTo(tlw, QPoint());
+#ifdef Q_WS_QWS
+ QWSWindowSurface *surface = static_cast<QWSWindowSurface*>(wbs->windowSurface);
+ const QRegion clip = surface->clipRegion().translated(-toplevelOffset) & scrollRect;
+ const QRect clipBoundingRect = clip.boundingRect();
+ scrollRect &= clipBoundingRect;
+#endif
+ const QRect destRect = scrollRect.translated(dx, dy) & scrollRect;
+ const QRect sourceRect = destRect.translated(-dx, -dy);
+
+ QRegion childExpose(scrollRect);
+ if (sourceRect.isValid()) {
+ if (wbs->bltRect(sourceRect, dx, dy, q))
+ childExpose -= destRect;
+ }
+
+ if (inDirtyList) {
+ if (rect == q->rect()) {
+ dirty.translate(dx, dy);
+ } else {
+ QRegion dirtyScrollRegion = dirty.intersected(scrollRect);
+ if (!dirtyScrollRegion.isEmpty()) {
+ dirty -= dirtyScrollRegion;
+ dirtyScrollRegion.translate(dx, dy);
+ dirty += dirtyScrollRegion;
+ }
+ }
+ }
+
+ if (!q->updatesEnabled())
+ return;
+
+ if (!childExpose.isEmpty()) {
+ wbs->markDirty(childExpose, q);
+ isScrolled = true;
+ }
+
+ // Instead of using native scroll-on-screen, we copy from
+ // backingstore, giving only one screen update for each
+ // scroll, and a solid appearance
+ wbs->markDirtyOnScreen(destRect, q, toplevelOffset);
+ }
+}
+
+static inline bool discardSyncRequest(QWidget *tlw, QTLWExtra *tlwExtra)
+{
+ if (!tlw || !tlwExtra)
+ return true;
+
+#ifdef Q_WS_X11
+ // Delay the sync until we get an Expose event from X11 (initial show).
+ // Qt::WA_Mapped is set to true, but the actual mapping has not yet occurred.
+ // However, we must repaint immediately regardless of the state if someone calls repaint().
+ if (tlwExtra->waitingForMapNotify && !tlwExtra->inRepaint)
+ return true;
+#endif
+
+ if (!tlw->testAttribute(Qt::WA_Mapped))
+ return true;
+
+ if (!tlw->isVisible()
+#ifndef Q_WS_X11
+ // If we're minimized on X11, WA_Mapped will be false and we
+ // will return in the case above. Some window managers on X11
+ // sends us the PropertyNotify to change the minimized state
+ // *AFTER* we've received the expose event, which is baaad.
+ || tlw->isMinimized()
+#endif
+ )
+ return true;
+
+ return false;
+}
+
+/*!
+ Synchronizes the \a exposedRegion of the \a exposedWidget with the backing store.
+
+ If there's nothing to repaint, the area is flushed and painting does not occur;
+ otherwise the area is marked as dirty on screen and will be flushed right after
+ we are done with all painting.
+*/
+void QWidgetBackingStore::sync(QWidget *exposedWidget, const QRegion &exposedRegion)
+{
+ QTLWExtra *tlwExtra = tlw->d_func()->maybeTopData();
+ if (discardSyncRequest(tlw, tlwExtra) || tlwExtra->inTopLevelResize)
+ return;
+
+ if (!exposedWidget || !exposedWidget->internalWinId() || !exposedWidget->isVisible()
+ || !exposedWidget->updatesEnabled() || exposedRegion.isEmpty()) {
+ return;
+ }
+
+ // Nothing to repaint.
+ if (!isDirty()) {
+ qt_flush(exposedWidget, exposedRegion, store, tlw, tlwOffset);
+ return;
+ }
+
+ if (exposedWidget != tlw)
+ markDirtyOnScreen(exposedRegion, exposedWidget, exposedWidget->mapTo(tlw, QPoint()));
+ else
+ markDirtyOnScreen(exposedRegion, exposedWidget, QPoint());
+ sync();
+}
+
+/*!
+ Synchronizes the backing store, i.e. dirty areas are repainted and flushed.
+*/
+void QWidgetBackingStore::sync()
+{
+ QTLWExtra *tlwExtra = tlw->d_func()->maybeTopData();
+ if (discardSyncRequest(tlw, tlwExtra)) {
+ // If the top-level is minimized, it's not visible on the screen so we can delay the
+ // update until it's shown again. In order to do that we must keep the dirty states.
+ // These will be cleared when we receive the first expose after showNormal().
+ // However, if the widget is not visible (isVisible() returns false), everything will
+ // be invalidated once the widget is shown again, so clear all dirty states.
+ if (!tlw->isVisible()) {
+ dirty = QRegion();
+ for (int i = 0; i < dirtyWidgets.size(); ++i)
+ resetWidget(dirtyWidgets.at(i));
+ dirtyWidgets.clear();
+ fullUpdatePending = false;
+ }
+ return;
+ }
+
+ const bool updatesDisabled = !tlw->updatesEnabled();
+ bool repaintAllWidgets = false;
+
+ const bool inTopLevelResize = tlwExtra->inTopLevelResize;
+ const QRect tlwRect(topLevelRect());
+ const QRect surfaceGeometry(tlwRect.topLeft(), store->size());
+ if ((fullUpdatePending || inTopLevelResize || surfaceGeometry.size() != tlwRect.size()) && !updatesDisabled) {
+ if (hasStaticContents()) {
+ // Repaint existing dirty area and newly visible area.
+ const QRect clipRect(0, 0, surfaceGeometry.width(), surfaceGeometry.height());
+ const QRegion staticRegion(staticContents(0, clipRect));
+ QRegion newVisible(0, 0, tlwRect.width(), tlwRect.height());
+ newVisible -= staticRegion;
+ dirty += newVisible;
+ store->setStaticContents(staticRegion);
+ } else {
+ // Repaint everything.
+ dirty = QRegion(0, 0, tlwRect.width(), tlwRect.height());
+ for (int i = 0; i < dirtyWidgets.size(); ++i)
+ resetWidget(dirtyWidgets.at(i));
+ dirtyWidgets.clear();
+ repaintAllWidgets = true;
+ }
+ }
+
+ if (inTopLevelResize || surfaceGeometry.size() != tlwRect.size())
+ store->resize(tlwRect.size());
+
+ if (updatesDisabled)
+ return;
+
+ if (hasDirtyFromPreviousSync)
+ dirty += dirtyFromPreviousSync;
+
+ // Contains everything that needs repaint.
+ QRegion toClean(dirty);
+
+ // Loop through all update() widgets and remove them from the list before they are
+ // painted (in case someone calls update() in paintEvent). If the widget is opaque
+ // and does not have transparent overlapping siblings, append it to the
+ // opaqueNonOverlappedWidgets list and paint it directly without composition.
+ QVarLengthArray<QWidget *, 32> opaqueNonOverlappedWidgets;
+ for (int i = 0; i < dirtyWidgets.size(); ++i) {
+ QWidget *w = dirtyWidgets.at(i);
+ QWidgetPrivate *wd = w->d_func();
+ if (wd->data.in_destructor)
+ continue;
+
+ // Clip with mask() and clipRect().
+ wd->dirty &= wd->clipRect();
+ wd->clipToEffectiveMask(wd->dirty);
+
+ // Subtract opaque siblings and children.
+ bool hasDirtySiblingsAbove = false;
+ // We know for sure that the widget isn't overlapped if 'isMoved' is true.
+ if (!wd->isMoved)
+ wd->subtractOpaqueSiblings(wd->dirty, &hasDirtySiblingsAbove);
+ // Scrolled and moved widgets must draw all children.
+ if (!wd->isScrolled && !wd->isMoved)
+ wd->subtractOpaqueChildren(wd->dirty, w->rect());
+
+ if (wd->dirty.isEmpty()) {
+ resetWidget(w);
+ continue;
+ }
+
+ const QRegion widgetDirty(w != tlw ? wd->dirty.translated(w->mapTo(tlw, QPoint()))
+ : wd->dirty);
+ toClean += widgetDirty;
+
+#ifndef QT_NO_GRAPHICSVIEW
+ if (tlw->d_func()->extra->proxyWidget) {
+ resetWidget(w);
+ continue;
+ }
+#endif
+
+ if (!hasDirtySiblingsAbove && wd->isOpaque && !dirty.intersects(widgetDirty.boundingRect())) {
+ opaqueNonOverlappedWidgets.append(w);
+ } else {
+ resetWidget(w);
+ dirty += widgetDirty;
+ }
+ }
+ dirtyWidgets.clear();
+
+ fullUpdatePending = false;
+
+ if (toClean.isEmpty()) {
+ // Nothing to repaint. However, we might have newly exposed areas on the
+ // screen if this function was called from sync(QWidget *, QRegion)), so
+ // we have to make sure those are flushed.
+ flush();
+ return;
+ }
+
+#ifndef QT_NO_GRAPHICSVIEW
+ if (tlw->d_func()->extra->proxyWidget) {
+ updateStaticContentsSize();
+ dirty = QRegion();
+ const QVector<QRect> rects(toClean.rects());
+ for (int i = 0; i < rects.size(); ++i)
+ tlw->d_func()->extra->proxyWidget->update(rects.at(i));
+ return;
+ }
+#endif
+
+ BeginPaintInfo beginPaintInfo;
+ beginPaint(toClean, tlw, store, &beginPaintInfo);
+ if (beginPaintInfo.nothingToPaint) {
+ for (int i = 0; i < opaqueNonOverlappedWidgets.size(); ++i)
+ resetWidget(opaqueNonOverlappedWidgets[i]);
+ dirty = QRegion();
+ return;
+ }
+
+ // Must do this before sending any paint events because
+ // the size may change in the paint event.
+ updateStaticContentsSize();
+ const QRegion dirtyCopy(dirty);
+ dirty = QRegion();
+
+ // Paint opaque non overlapped widgets.
+ for (int i = 0; i < opaqueNonOverlappedWidgets.size(); ++i) {
+ QWidget *w = opaqueNonOverlappedWidgets[i];
+ QWidgetPrivate *wd = w->d_func();
+
+ int flags = QWidgetPrivate::DrawRecursive;
+ // Scrolled and moved widgets must draw all children.
+ if (!wd->isScrolled && !wd->isMoved)
+ flags |= QWidgetPrivate::DontDrawOpaqueChildren;
+ if (w == tlw)
+ flags |= QWidgetPrivate::DrawAsRoot;
+
+ QRegion toBePainted(wd->dirty);
+ resetWidget(w);
+
+ QPoint offset(tlwOffset);
+ if (w != tlw)
+ offset += w->mapTo(tlw, QPoint());
+ wd->drawWidget(store->paintDevice(), toBePainted, offset, flags, 0, this);
+ }
+
+ // Paint the rest with composition.
+ if (repaintAllWidgets || !dirtyCopy.isEmpty()) {
+ const int flags = QWidgetPrivate::DrawAsRoot | QWidgetPrivate::DrawRecursive;
+ tlw->d_func()->drawWidget(store->paintDevice(), dirtyCopy, tlwOffset, flags, 0, this);
+ }
+
+ endPaint(toClean, store, &beginPaintInfo);
+}
+
+/*!
+ Flushes the contents of the backing store into the top-level widget.
+ If the \a widget is non-zero, the content is flushed to the \a widget.
+ If the \a surface is non-zero, the content of the \a surface is flushed.
+*/
+void QWidgetBackingStore::flush(QWidget *widget, QBackingStore *backingStore)
+{
+ if (!dirtyOnScreen.isEmpty()) {
+ QWidget *target = widget ? widget : tlw;
+ QBackingStore *source = store ? store : backingStore;
+ qt_flush(target, dirtyOnScreen, source, tlw, tlwOffset);
+ dirtyOnScreen = QRegion();
+ }
+
+ if (!dirtyOnScreenWidgets || dirtyOnScreenWidgets->isEmpty())
+ return;
+
+ for (int i = 0; i < dirtyOnScreenWidgets->size(); ++i) {
+ QWidget *w = dirtyOnScreenWidgets->at(i);
+ QWidgetPrivate *wd = w->d_func();
+ Q_ASSERT(wd->needsFlush);
+ qt_flush(w, *wd->needsFlush, backingStore, tlw, tlwOffset);
+ *wd->needsFlush = QRegion();
+ }
+ dirtyOnScreenWidgets->clear();
+}
+
+static inline bool discardInvalidateBufferRequest(QWidget *widget, QTLWExtra *tlwExtra)
+{
+ Q_ASSERT(widget);
+ if (QApplication::closingDown())
+ return true;
+
+ if (!tlwExtra || tlwExtra->inTopLevelResize || !tlwExtra->backingStore)
+ return true;
+
+ if (!widget->isVisible() || !widget->updatesEnabled())
+ return true;
+
+ return false;
+}
+
+/*!
+ Invalidates the buffer when the widget is resized.
+ Static areas are never invalidated unless absolutely needed.
+*/
+void QWidgetPrivate::invalidateBuffer_resizeHelper(const QPoint &oldPos, const QSize &oldSize)
+{
+ Q_Q(QWidget);
+ Q_ASSERT(!q->isWindow());
+ Q_ASSERT(q->parentWidget());
+
+ const bool staticContents = q->testAttribute(Qt::WA_StaticContents);
+ const bool sizeDecreased = (data.crect.width() < oldSize.width())
+ || (data.crect.height() < oldSize.height());
+
+ const QPoint offset(data.crect.x() - oldPos.x(), data.crect.y() - oldPos.y());
+ const bool parentAreaExposed = !offset.isNull() || sizeDecreased;
+ const QRect newWidgetRect(q->rect());
+ const QRect oldWidgetRect(0, 0, oldSize.width(), oldSize.height());
+
+ if (!staticContents || graphicsEffect) {
+ QRegion staticChildren;
+ QWidgetBackingStore *bs = 0;
+ if (offset.isNull() && (bs = maybeBackingStore()))
+ staticChildren = bs->staticContents(q, oldWidgetRect);
+ const bool hasStaticChildren = !staticChildren.isEmpty();
+
+ if (hasStaticChildren) {
+ QRegion dirty(newWidgetRect);
+ dirty -= staticChildren;
+ invalidateBuffer(dirty);
+ } else {
+ // Entire widget needs repaint.
+ invalidateBuffer(newWidgetRect);
+ }
+
+ if (!parentAreaExposed)
+ return;
+
+ // Invalidate newly exposed area of the parent.
+ if (!graphicsEffect && extra && extra->hasMask) {
+ QRegion parentExpose(extra->mask.translated(oldPos));
+ parentExpose &= QRect(oldPos, oldSize);
+ if (hasStaticChildren)
+ parentExpose -= data.crect; // Offset is unchanged, safe to do this.
+ q->parentWidget()->d_func()->invalidateBuffer(parentExpose);
+ } else {
+ if (hasStaticChildren && !graphicsEffect) {
+ QRegion parentExpose(QRect(oldPos, oldSize));
+ parentExpose -= data.crect; // Offset is unchanged, safe to do this.
+ q->parentWidget()->d_func()->invalidateBuffer(parentExpose);
+ } else {
+ q->parentWidget()->d_func()->invalidateBuffer(effectiveRectFor(QRect(oldPos, oldSize)));
+ }
+ }
+ return;
+ }
+
+ // Move static content to its new position.
+ if (!offset.isNull()) {
+ if (sizeDecreased) {
+ const QSize minSize(qMin(oldSize.width(), data.crect.width()),
+ qMin(oldSize.height(), data.crect.height()));
+ moveRect(QRect(oldPos, minSize), offset.x(), offset.y());
+ } else {
+ moveRect(QRect(oldPos, oldSize), offset.x(), offset.y());
+ }
+ }
+
+ // Invalidate newly visible area of the widget.
+ if (!sizeDecreased || !oldWidgetRect.contains(newWidgetRect)) {
+ QRegion newVisible(newWidgetRect);
+ newVisible -= oldWidgetRect;
+ invalidateBuffer(newVisible);
+ }
+
+ if (!parentAreaExposed)
+ return;
+
+ // Invalidate newly exposed area of the parent.
+ const QRect oldRect(oldPos, oldSize);
+ if (extra && extra->hasMask) {
+ QRegion parentExpose(oldRect);
+ parentExpose &= extra->mask.translated(oldPos);
+ parentExpose -= (extra->mask.translated(data.crect.topLeft()) & data.crect);
+ q->parentWidget()->d_func()->invalidateBuffer(parentExpose);
+ } else {
+ QRegion parentExpose(oldRect);
+ parentExpose -= data.crect;
+ q->parentWidget()->d_func()->invalidateBuffer(parentExpose);
+ }
+}
+
+/*!
+ Invalidates the \a rgn (in widget's coordinates) of the backing store, i.e.
+ all widgets intersecting with the region will be repainted when the backing store
+ is synced.
+
+ ### Qt 4.6: Merge into a template function (after MSVC isn't supported anymore).
+*/
+void QWidgetPrivate::invalidateBuffer(const QRegion &rgn)
+{
+ Q_Q(QWidget);
+
+ QTLWExtra *tlwExtra = q->window()->d_func()->maybeTopData();
+ if (discardInvalidateBufferRequest(q, tlwExtra) || rgn.isEmpty())
+ return;
+
+ QRegion wrgn(rgn);
+ wrgn &= clipRect();
+ if (!graphicsEffect && extra && extra->hasMask)
+ wrgn &= extra->mask;
+ if (wrgn.isEmpty())
+ return;
+
+ tlwExtra->backingStoreTracker->markDirty(wrgn, q, false, true);
+}
+
+/*!
+ This function is equivalent to calling invalidateBuffer(QRegion(rect), ...), but
+ is more efficient as it eliminates QRegion operations/allocations and can
+ use the rect more precisely for additional cut-offs.
+
+ ### Qt 4.6: Merge into a template function (after MSVC isn't supported anymore).
+*/
+void QWidgetPrivate::invalidateBuffer(const QRect &rect)
+{
+ Q_Q(QWidget);
+
+ QTLWExtra *tlwExtra = q->window()->d_func()->maybeTopData();
+ if (discardInvalidateBufferRequest(q, tlwExtra) || rect.isEmpty())
+ return;
+
+ QRect wRect(rect);
+ wRect &= clipRect();
+ if (wRect.isEmpty())
+ return;
+
+ if (graphicsEffect || !extra || !extra->hasMask) {
+ tlwExtra->backingStoreTracker->markDirty(wRect, q, false, true);
+ return;
+ }
+
+ QRegion wRgn(extra->mask);
+ wRgn &= wRect;
+ if (wRgn.isEmpty())
+ return;
+
+ tlwExtra->backingStoreTracker->markDirty(wRgn, q, false, true);
+}
+
+void QWidgetPrivate::repaint_sys(const QRegion &rgn)
+{
+ if (data.in_destructor)
+ return;
+
+ Q_Q(QWidget);
+ if (q->testAttribute(Qt::WA_StaticContents)) {
+ if (!extra)
+ createExtra();
+ extra->staticContentsSize = data.crect.size();
+ }
+
+ QPaintEngine *engine = q->paintEngine();
+
+ // QGLWidget does not support partial updates if:
+ // 1) The context is double buffered
+ // 2) The context is single buffered and auto-fill background is enabled.
+ const bool noPartialUpdateSupport = (engine && (engine->type() == QPaintEngine::OpenGL
+ || engine->type() == QPaintEngine::OpenGL2))
+ && (usesDoubleBufferedGLContext || q->autoFillBackground());
+ QRegion toBePainted(noPartialUpdateSupport ? q->rect() : rgn);
+
+#ifdef Q_WS_MAC
+ // No difference between update() and repaint() on the Mac.
+ update_sys(toBePainted);
+ return;
+#endif
+
+ toBePainted &= clipRect();
+ clipToEffectiveMask(toBePainted);
+ if (toBePainted.isEmpty())
+ return; // Nothing to repaint.
+
+#ifndef QT_NO_PAINT_DEBUG
+ bool flushed = QWidgetBackingStore::flushPaint(q, toBePainted);
+#endif
+
+ drawWidget(q, toBePainted, QPoint(), QWidgetPrivate::DrawAsRoot | QWidgetPrivate::DrawPaintOnScreen, 0);
+
+#ifndef QT_NO_PAINT_DEBUG
+ if (flushed)
+ QWidgetBackingStore::unflushPaint(q, toBePainted);
+#endif
+
+ if (!q->testAttribute(Qt::WA_PaintOutsidePaintEvent) && q->paintingActive())
+ qWarning("QWidget::repaint: It is dangerous to leave painters active on a widget outside of the PaintEvent");
+}
+
+
+QT_END_NAMESPACE
diff --git a/src/widgets/kernel/qwidgetbackingstore_p.h b/src/widgets/kernel/qwidgetbackingstore_p.h
new file mode 100644
index 0000000000..4d43a90322
--- /dev/null
+++ b/src/widgets/kernel/qwidgetbackingstore_p.h
@@ -0,0 +1,268 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWIDGETBACKINGSTORE_P_H
+#define QWIDGETBACKINGSTORE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QDebug>
+#include <QtWidgets/qwidget.h>
+#include <private/qwidget_p.h>
+#include <QtGui/qbackingstore.h>
+
+QT_BEGIN_NAMESPACE
+
+struct BeginPaintInfo {
+ inline BeginPaintInfo() : wasFlushed(0), nothingToPaint(0), backingStoreRecreated(0) {}
+ uint wasFlushed : 1;
+ uint nothingToPaint : 1;
+ uint backingStoreRecreated : 1;
+};
+
+class Q_AUTOTEST_EXPORT QWidgetBackingStore
+{
+public:
+ QWidgetBackingStore(QWidget *t);
+ ~QWidgetBackingStore();
+
+ static void showYellowThing(QWidget *widget, const QRegion &rgn, int msec, bool);
+
+ void sync(QWidget *exposedWidget, const QRegion &exposedRegion);
+ void sync();
+ void flush(QWidget *widget = 0, QBackingStore *store = 0);
+
+ inline QPoint topLevelOffset() const { return tlwOffset; }
+
+ QBackingStore *backingStore() const { return store; }
+
+ inline bool isDirty() const
+ {
+ return !(dirtyWidgets.isEmpty() && dirty.isEmpty() && !hasDirtyFromPreviousSync
+ && !fullUpdatePending
+#if defined(Q_WS_QWS) && !defined(QT_NO_QWS_MANAGER)
+ && !hasDirtyWindowDecoration()
+#endif
+ );
+ }
+
+ // ### Qt 4.6: Merge into a template function (after MSVC isn't supported anymore).
+ void markDirty(const QRegion &rgn, QWidget *widget, bool updateImmediately = false,
+ bool invalidateBuffer = false);
+ void markDirty(const QRect &rect, QWidget *widget, bool updateImmediately = false,
+ bool invalidateBuffer = false);
+
+private:
+ QWidget *tlw;
+ QRegion dirtyOnScreen; // needsFlush
+ QRegion dirty; // needsRepaint
+ QRegion dirtyFromPreviousSync;
+ QVector<QWidget *> dirtyWidgets;
+ QVector<QWidget *> *dirtyOnScreenWidgets;
+ QList<QWidget *> staticWidgets;
+ QBackingStore *store;
+ uint hasDirtyFromPreviousSync : 1;
+ uint fullUpdatePending : 1;
+
+ QPoint tlwOffset;
+
+ static bool flushPaint(QWidget *widget, const QRegion &rgn);
+ static void unflushPaint(QWidget *widget, const QRegion &rgn);
+
+ bool bltRect(const QRect &rect, int dx, int dy, QWidget *widget);
+ void releaseBuffer();
+
+ void beginPaint(QRegion &toClean, QWidget *widget, QBackingStore *backingStore,
+ BeginPaintInfo *returnInfo, bool toCleanIsInTopLevelCoordinates = true);
+ void endPaint(const QRegion &cleaned, QBackingStore *backingStore, BeginPaintInfo *beginPaintInfo);
+
+ QRegion dirtyRegion(QWidget *widget = 0) const;
+ QRegion staticContents(QWidget *widget = 0, const QRect &withinClipRect = QRect()) const;
+
+ void markDirtyOnScreen(const QRegion &dirtyOnScreen, QWidget *widget, const QPoint &topLevelOffset);
+
+ void removeDirtyWidget(QWidget *w);
+
+#if defined(Q_WS_QWS) && !defined(QT_NO_QWS_MANAGER)
+ bool hasDirtyWindowDecoration() const;
+ void paintWindowDecoration();
+#endif
+ void updateLists(QWidget *widget);
+
+ inline void addDirtyWidget(QWidget *widget, const QRegion &rgn)
+ {
+ if (widget && !widget->d_func()->inDirtyList && !widget->data->in_destructor) {
+ QWidgetPrivate *widgetPrivate = widget->d_func();
+#ifndef QT_NO_GRAPHICSEFFECT
+ if (widgetPrivate->graphicsEffect)
+ widgetPrivate->dirty = widgetPrivate->effectiveRectFor(rgn.boundingRect());
+ else
+#endif //QT_NO_GRAPHICSEFFECT
+ widgetPrivate->dirty = rgn;
+ dirtyWidgets.append(widget);
+ widgetPrivate->inDirtyList = true;
+ }
+ }
+
+ inline void dirtyWidgetsRemoveAll(QWidget *widget)
+ {
+ int i = 0;
+ while (i < dirtyWidgets.size()) {
+ if (dirtyWidgets.at(i) == widget)
+ dirtyWidgets.remove(i);
+ else
+ ++i;
+ }
+ }
+
+ inline void addStaticWidget(QWidget *widget)
+ {
+ if (!widget)
+ return;
+
+ Q_ASSERT(widget->testAttribute(Qt::WA_StaticContents));
+ if (!staticWidgets.contains(widget))
+ staticWidgets.append(widget);
+ }
+
+ inline void removeStaticWidget(QWidget *widget)
+ { staticWidgets.removeAll(widget); }
+
+ // Move the reparented widget and all its static children from this backing store
+ // to the new backing store if reparented into another top-level / backing store.
+ inline void moveStaticWidgets(QWidget *reparented)
+ {
+ Q_ASSERT(reparented);
+ QWidgetBackingStore *newBs = reparented->d_func()->maybeBackingStore();
+ if (newBs == this)
+ return;
+
+ int i = 0;
+ while (i < staticWidgets.size()) {
+ QWidget *w = staticWidgets.at(i);
+ if (reparented == w || reparented->isAncestorOf(w)) {
+ staticWidgets.removeAt(i);
+ if (newBs)
+ newBs->addStaticWidget(w);
+ } else {
+ ++i;
+ }
+ }
+ }
+
+ inline QRect topLevelRect() const
+ {
+#ifdef Q_WS_QWS
+ return tlw->frameGeometry();
+#else
+ return tlw->data->crect;
+#endif
+ }
+
+ inline void appendDirtyOnScreenWidget(QWidget *widget)
+ {
+ if (!widget)
+ return;
+
+ if (!dirtyOnScreenWidgets) {
+ dirtyOnScreenWidgets = new QVector<QWidget *>;
+ dirtyOnScreenWidgets->append(widget);
+ } else if (!dirtyOnScreenWidgets->contains(widget)) {
+ dirtyOnScreenWidgets->append(widget);
+ }
+ }
+
+ inline void dirtyOnScreenWidgetsRemoveAll(QWidget *widget)
+ {
+ if (!widget || !dirtyOnScreenWidgets)
+ return;
+
+ int i = 0;
+ while (i < dirtyOnScreenWidgets->size()) {
+ if (dirtyOnScreenWidgets->at(i) == widget)
+ dirtyOnScreenWidgets->remove(i);
+ else
+ ++i;
+ }
+ }
+
+ inline void resetWidget(QWidget *widget)
+ {
+ if (widget) {
+ widget->d_func()->inDirtyList = false;
+ widget->d_func()->isScrolled = false;
+ widget->d_func()->isMoved = false;
+ widget->d_func()->dirty = QRegion();
+ }
+ }
+
+ inline void updateStaticContentsSize()
+ {
+ for (int i = 0; i < staticWidgets.size(); ++i) {
+ QWidgetPrivate *wd = staticWidgets.at(i)->d_func();
+ if (!wd->extra)
+ wd->createExtra();
+ wd->extra->staticContentsSize = wd->data.crect.size();
+ }
+ }
+
+ inline bool hasStaticContents() const
+ { return !staticWidgets.isEmpty(); }
+
+ friend QRegion qt_dirtyRegion(QWidget *);
+ friend class QWidgetPrivate;
+ friend class QWidget;
+ friend class QETWidget;
+ friend class QBackingStore;
+};
+
+QT_END_NAMESPACE
+
+#endif // QBACKINGSTORE_P_H
diff --git a/src/widgets/kernel/qwidgetsvariant.cpp b/src/widgets/kernel/qwidgetsvariant.cpp
new file mode 100644
index 0000000000..e4a9e0f067
--- /dev/null
+++ b/src/widgets/kernel/qwidgetsvariant.cpp
@@ -0,0 +1,213 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qvariant.h"
+
+#include "qicon.h"
+#include "qsizepolicy.h"
+
+#include "private/qvariant_p.h"
+
+QT_BEGIN_NAMESPACE
+
+
+static void construct(QVariant::Private *x, const void *copy)
+{
+ switch (x->type) {
+#ifndef QT_NO_ICON
+ case QVariant::Icon:
+ v_construct<QIcon>(x, copy);
+ break;
+#endif
+ case QVariant::SizePolicy:
+ v_construct<QSizePolicy>(x, copy);
+ break;
+ default:
+ Q_ASSERT(false);
+ return;
+ }
+ x->is_null = !copy;
+}
+
+static void clear(QVariant::Private *d)
+{
+ switch (d->type) {
+#ifndef QT_NO_ICON
+ case QVariant::Icon:
+ v_clear<QIcon>(d);
+ break;
+#endif
+ case QVariant::SizePolicy:
+ v_clear<QSizePolicy>(d);
+ break;
+ default:
+ Q_ASSERT(false);
+ return;
+ }
+
+ d->type = QVariant::Invalid;
+ d->is_null = true;
+ d->is_shared = false;
+}
+
+
+static bool isNull(const QVariant::Private *d)
+{
+ switch(d->type) {
+#ifndef QT_NO_ICON
+ case QVariant::Icon:
+ return v_cast<QIcon>(d)->isNull();
+#endif
+ default:
+ Q_ASSERT(false);
+ }
+ return true;
+}
+
+static bool compare(const QVariant::Private *a, const QVariant::Private *b)
+{
+ Q_ASSERT(a->type == b->type);
+ switch(a->type) {
+ case QVariant::SizePolicy:
+ return *v_cast<QSizePolicy>(a) == *v_cast<QSizePolicy>(b);
+ default:
+ Q_ASSERT(false);
+ }
+ return false;
+}
+
+
+static const QVariant::Handler widgets_handler = {
+ construct,
+ clear,
+ isNull,
+#ifndef QT_NO_DATASTREAM
+ 0,
+ 0,
+#endif
+ compare,
+ 0,
+ 0,
+#if !defined(QT_NO_DEBUG_STREAM) && !defined(Q_BROKEN_DEBUG_STREAM)
+ 0
+#else
+ 0
+#endif
+};
+
+struct QMetaTypeGuiHelper
+{
+ QMetaType::Constructor constr;
+ QMetaType::Destructor destr;
+#ifndef QT_NO_DATASTREAM
+ QMetaType::SaveOperator saveOp;
+ QMetaType::LoadOperator loadOp;
+#endif
+};
+
+extern Q_CORE_EXPORT const QMetaTypeGuiHelper *qMetaTypeWidgetsHelper;
+
+
+#ifdef QT_NO_DATASTREAM
+# define Q_DECL_METATYPE_HELPER(TYPE) \
+ typedef void *(*QConstruct##TYPE)(const TYPE *); \
+ static const QConstruct##TYPE qConstruct##TYPE = qMetaTypeConstructHelper<TYPE>; \
+ typedef void (*QDestruct##TYPE)(TYPE *); \
+ static const QDestruct##TYPE qDestruct##TYPE = qMetaTypeDeleteHelper<TYPE>;
+#else
+# define Q_DECL_METATYPE_HELPER(TYPE) \
+ typedef void *(*QConstruct##TYPE)(const TYPE *); \
+ static const QConstruct##TYPE qConstruct##TYPE = qMetaTypeConstructHelper<TYPE>; \
+ typedef void (*QDestruct##TYPE)(TYPE *); \
+ static const QDestruct##TYPE qDestruct##TYPE = qMetaTypeDeleteHelper<TYPE>; \
+ typedef void (*QSave##TYPE)(QDataStream &, const TYPE *); \
+ static const QSave##TYPE qSave##TYPE = qMetaTypeSaveHelper<TYPE>; \
+ typedef void (*QLoad##TYPE)(QDataStream &, TYPE *); \
+ static const QLoad##TYPE qLoad##TYPE = qMetaTypeLoadHelper<TYPE>;
+#endif
+
+#ifndef QT_NO_ICON
+Q_DECL_METATYPE_HELPER(QIcon)
+#endif
+Q_DECL_METATYPE_HELPER(QSizePolicy)
+
+#ifdef QT_NO_DATASTREAM
+# define Q_IMPL_METATYPE_HELPER(TYPE) \
+ { reinterpret_cast<QMetaType::Constructor>(qConstruct##TYPE), \
+ reinterpret_cast<QMetaType::Destructor>(qDestruct##TYPE) }
+#else
+# define Q_IMPL_METATYPE_HELPER(TYPE) \
+ { reinterpret_cast<QMetaType::Constructor>(qConstruct##TYPE), \
+ reinterpret_cast<QMetaType::Destructor>(qDestruct##TYPE), \
+ reinterpret_cast<QMetaType::SaveOperator>(qSave##TYPE), \
+ reinterpret_cast<QMetaType::LoadOperator>(qLoad##TYPE) \
+ }
+#endif
+
+static const QMetaTypeGuiHelper qVariantWidgetsHelper[] = {
+#ifdef QT_NO_ICON
+ {0, 0, 0, 0},
+#else
+ Q_IMPL_METATYPE_HELPER(QIcon),
+#endif
+ Q_IMPL_METATYPE_HELPER(QSizePolicy),
+};
+
+Q_WIDGETS_EXPORT const QVariant::Handler *qt_widgets_variant_handler;
+
+int qRegisterWidgetsVariant()
+{
+ qt_widgets_variant_handler = &widgets_handler;
+ qMetaTypeWidgetsHelper = qVariantWidgetsHelper;
+ return 1;
+}
+Q_CONSTRUCTOR_FUNCTION(qRegisterWidgetsVariant)
+
+int qUnregisterWidgetsVariant()
+{
+ qt_widgets_variant_handler = 0;
+ qMetaTypeWidgetsHelper = 0;
+ return 1;
+}
+Q_DESTRUCTOR_FUNCTION(qUnregisterWidgetsVariant)
+
+
+QT_END_NAMESPACE
diff --git a/src/widgets/kernel/qwidgetwindow_qpa.cpp b/src/widgets/kernel/qwidgetwindow_qpa.cpp
new file mode 100644
index 0000000000..42ecfd4e3d
--- /dev/null
+++ b/src/widgets/kernel/qwidgetwindow_qpa.cpp
@@ -0,0 +1,415 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwidgetwindow_qpa_p.h"
+
+#include "private/qwidget_p.h"
+#include "private/qapplication_p.h"
+
+QT_BEGIN_NAMESPACE
+
+QWidget *qt_button_down = 0; // widget got last button-down
+
+// popup control
+QWidget *qt_popup_down = 0; // popup that contains the pressed widget
+extern int openPopupCount;
+bool qt_replay_popup_mouse_event = false;
+extern bool qt_try_modal(QWidget *widget, QEvent::Type type);
+
+QWidgetWindow::QWidgetWindow(QWidget *widget)
+ : m_widget(widget)
+{
+}
+
+bool QWidgetWindow::event(QEvent *event)
+{
+ switch (event->type()) {
+ case QEvent::Close:
+ handleCloseEvent(static_cast<QCloseEvent *>(event));
+ return true;
+
+ case QEvent::Enter:
+ case QEvent::Leave:
+ handleEnterLeaveEvent(event);
+ return true;
+
+ case QEvent::KeyPress:
+ case QEvent::KeyRelease:
+ handleKeyEvent(static_cast<QKeyEvent *>(event));
+ return true;
+
+ case QEvent::MouseMove:
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseButtonDblClick:
+ handleMouseEvent(static_cast<QMouseEvent *>(event));
+ return true;
+
+ case QEvent::TouchBegin:
+ case QEvent::TouchUpdate:
+ case QEvent::TouchEnd:
+ handleTouchEvent(static_cast<QTouchEvent *>(event));
+ return true;
+
+ case QEvent::Move:
+ handleMoveEvent(static_cast<QMoveEvent *>(event));
+ return true;
+
+ case QEvent::Resize:
+ handleResizeEvent(static_cast<QResizeEvent *>(event));
+ return true;
+
+ case QEvent::Wheel:
+ handleWheelEvent(static_cast<QWheelEvent *>(event));
+ return true;
+
+ case QEvent::DragEnter:
+ case QEvent::DragLeave:
+ case QEvent::DragMove:
+ case QEvent::Drop:
+ handleDragEvent(event);
+ break;
+
+ case QEvent::Map:
+ m_widget->setAttribute(Qt::WA_Mapped);
+ return true;
+
+ case QEvent::Unmap:
+ m_widget->setAttribute(Qt::WA_Mapped, false);
+ return true;
+
+ case QEvent::Expose:
+ handleExposeEvent(static_cast<QExposeEvent *>(event));
+ return true;
+
+ case QEvent::WindowStateChange:
+ handleWindowStateChangedEvent(static_cast<QWindowStateChangeEvent *>(event));
+ return true;
+
+ default:
+ break;
+ }
+
+ return m_widget->event(event) || QWindow::event(event);
+}
+
+QPointer<QWidget> qt_last_mouse_receiver = 0;
+
+void QWidgetWindow::handleEnterLeaveEvent(QEvent *event)
+{
+ if (event->type() == QEvent::Leave) {
+ QWidget *leave = qt_last_mouse_receiver ? qt_last_mouse_receiver.data() : m_widget;
+ QApplicationPrivate::dispatchEnterLeave(0, leave);
+ qt_last_mouse_receiver = 0;
+ } else {
+ QApplicationPrivate::dispatchEnterLeave(m_widget, 0);
+ qt_last_mouse_receiver = m_widget;
+ }
+}
+
+void QWidgetWindow::handleMouseEvent(QMouseEvent *event)
+{
+ if (qApp->d_func()->inPopupMode()) {
+ QWidget *activePopupWidget = qApp->activePopupWidget();
+ QWidget *popup = activePopupWidget;
+ QPoint mapped = event->pos();
+ if (popup != m_widget)
+ mapped = popup->mapFromGlobal(event->globalPos());
+ bool releaseAfter = false;
+ QWidget *popupChild = popup->childAt(mapped);
+
+ if (popup != qt_popup_down) {
+ qt_button_down = 0;
+ qt_popup_down = 0;
+ }
+
+ switch (event->type()) {
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonDblClick:
+ qt_button_down = popupChild;
+ qt_popup_down = popup;
+ break;
+ case QEvent::MouseButtonRelease:
+ releaseAfter = true;
+ break;
+ default:
+ break; // nothing for mouse move
+ }
+
+ int oldOpenPopupCount = openPopupCount;
+
+ if (popup->isEnabled()) {
+ // deliver event
+ qt_replay_popup_mouse_event = false;
+ QWidget *receiver = popup;
+ QPoint widgetPos = mapped;
+ if (qt_button_down)
+ receiver = qt_button_down;
+ else if (popupChild)
+ receiver = popupChild;
+ if (receiver != popup)
+ widgetPos = receiver->mapFromGlobal(event->globalPos());
+ QWidget *alien = m_widget->childAt(m_widget->mapFromGlobal(event->globalPos()));
+ QMouseEvent e(event->type(), widgetPos, event->windowPos(), event->screenPos(), event->button(), event->buttons(), event->modifiers());
+ e.setTimestamp(event->timestamp());
+ QApplicationPrivate::sendMouseEvent(receiver, &e, alien, m_widget, &qt_button_down, qt_last_mouse_receiver);
+ } else {
+ // close disabled popups when a mouse button is pressed or released
+ switch (event->type()) {
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonDblClick:
+ case QEvent::MouseButtonRelease:
+ popup->close();
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (qApp->activePopupWidget() != activePopupWidget
+ && qt_replay_popup_mouse_event) {
+ if (m_widget->windowType() != Qt::Popup)
+ qt_button_down = 0;
+ qt_replay_popup_mouse_event = false;
+ } else if (event->type() == QEvent::MouseButtonPress
+ && event->button() == Qt::RightButton
+ && (openPopupCount == oldOpenPopupCount)) {
+ QWidget *popupEvent = popup;
+ if (qt_button_down)
+ popupEvent = qt_button_down;
+ else if(popupChild)
+ popupEvent = popupChild;
+ QContextMenuEvent e(QContextMenuEvent::Mouse, mapped, event->globalPos(), event->modifiers());
+ QApplication::sendSpontaneousEvent(popupEvent, &e);
+ }
+
+ if (releaseAfter) {
+ qt_button_down = 0;
+ qt_popup_down = 0;
+ }
+ return;
+ }
+
+ // modal event handling
+ if (QApplicationPrivate::instance()->modalState() && !qt_try_modal(m_widget, event->type()))
+ return;
+
+ // which child should have it?
+ QWidget *widget = m_widget->childAt(event->pos());
+ QPoint mapped = event->pos();
+
+ if (widget) {
+ mapped = widget->mapFrom(m_widget, event->pos());
+ } else {
+ widget = m_widget;
+ }
+
+ if (event->type() == QEvent::MouseButtonPress && !qt_button_down)
+ qt_button_down = widget;
+
+ QWidget *receiver = QApplicationPrivate::pickMouseReceiver(m_widget, event->globalPos(), mapped, event->type(), event->buttons(),
+ qt_button_down, widget);
+
+ if (!receiver) {
+ if (event->type() == QEvent::MouseButtonRelease)
+ QApplicationPrivate::mouse_buttons &= ~event->button();
+ return;
+ }
+
+ QMouseEvent translated(event->type(), mapped, event->windowPos(), event->screenPos(), event->button(), event->buttons(), event->modifiers());
+ translated.setTimestamp(event->timestamp());
+ QApplicationPrivate::sendMouseEvent(receiver, &translated, widget, m_widget, &qt_button_down,
+ qt_last_mouse_receiver);
+
+ if (event->type() == QEvent::MouseButtonPress && event->button() == Qt::RightButton) {
+ QContextMenuEvent e(QContextMenuEvent::Mouse, mapped, event->globalPos(), event->modifiers());
+ QGuiApplication::sendSpontaneousEvent(receiver, &e);
+ }
+}
+
+void QWidgetWindow::handleTouchEvent(QTouchEvent *event)
+{
+ QApplicationPrivate::translateRawTouchEvent(m_widget, event->deviceType(), event->touchPoints());
+}
+
+void QWidgetWindow::handleKeyEvent(QKeyEvent *event)
+{
+ if (QApplicationPrivate::instance()->modalState() && !qt_try_modal(m_widget, event->type()))
+ return;
+
+ QWidget *widget = m_widget->focusWidget();
+
+ if (!widget)
+ widget = m_widget;
+
+ QGuiApplication::sendSpontaneousEvent(widget, event);
+}
+
+void QWidgetWindow::updateGeometry()
+{
+ if (m_widget->testAttribute(Qt::WA_OutsideWSRange))
+ return;
+
+ QMargins margins = frameMargins();
+
+ m_widget->data->crect = geometry();
+ m_widget->d_func()->topData()->frameStrut.setCoords(margins.left(), margins.top(), margins.right(), margins.bottom());
+}
+
+void QWidgetWindow::handleMoveEvent(QMoveEvent *event)
+{
+ updateGeometry();
+ QGuiApplication::sendSpontaneousEvent(m_widget, event);
+}
+
+void QWidgetWindow::handleResizeEvent(QResizeEvent *event)
+{
+ QSize oldSize = m_widget->data->crect.size();
+
+ updateGeometry();
+ QGuiApplication::sendSpontaneousEvent(m_widget, event);
+
+ if (m_widget->d_func()->paintOnScreen()) {
+ QRegion updateRegion(geometry());
+ if (m_widget->testAttribute(Qt::WA_StaticContents))
+ updateRegion -= QRect(0, 0, oldSize.width(), oldSize.height());
+ m_widget->d_func()->syncBackingStore(updateRegion);
+ } else {
+ m_widget->d_func()->syncBackingStore();
+ }
+}
+
+void QWidgetWindow::handleCloseEvent(QCloseEvent *)
+{
+ m_widget->d_func()->close_helper(QWidgetPrivate::CloseWithSpontaneousEvent);
+}
+
+void QWidgetWindow::handleWheelEvent(QWheelEvent *event)
+{
+ if (QApplicationPrivate::instance()->modalState() && !qt_try_modal(m_widget, event->type()))
+ return;
+
+ // which child should have it?
+ QWidget *widget = m_widget->childAt(event->pos());
+
+ if (!widget)
+ widget = m_widget;
+
+ QPoint mapped = widget->mapFrom(m_widget, event->pos());
+
+ QWheelEvent translated(mapped, event->globalPos(), event->delta(), event->buttons(), event->modifiers(), event->orientation());
+ QGuiApplication::sendSpontaneousEvent(widget, &translated);
+}
+
+void QWidgetWindow::handleDragEvent(QEvent *event)
+{
+ switch (event->type()) {
+ case QEvent::DragEnter:
+ Q_ASSERT(!m_dragTarget);
+ // fall through
+ case QEvent::DragMove:
+ {
+ QDragMoveEvent *de = static_cast<QDragMoveEvent *>(event);
+ QWidget *widget = m_widget->childAt(de->pos());
+ if (!widget)
+ widget = m_widget;
+
+ if (widget != m_dragTarget.data()) {
+ if (m_dragTarget.data()) {
+ QDragLeaveEvent le;
+ QGuiApplication::sendSpontaneousEvent(m_dragTarget.data(), &le);
+ }
+ m_dragTarget = widget;
+ QPoint mapped = widget->mapFrom(m_widget, de->pos());
+ QDragEnterEvent translated(mapped, de->possibleActions(), de->mimeData(), de->mouseButtons(), de->keyboardModifiers());
+ QGuiApplication::sendSpontaneousEvent(widget, &translated);
+ if (translated.isAccepted())
+ event->accept();
+ de->setDropAction(translated.dropAction());
+ } else {
+ Q_ASSERT(event->type() == QEvent::DragMove);
+ QPoint mapped = widget->mapFrom(m_widget, de->pos());
+ QDragMoveEvent translated(mapped, de->possibleActions(), de->mimeData(), de->mouseButtons(), de->keyboardModifiers());
+ translated.setDropAction(de->dropAction());
+ QGuiApplication::sendSpontaneousEvent(widget, &translated);
+ if (translated.isAccepted())
+ event->accept();
+ de->setDropAction(translated.dropAction());
+ }
+ break;
+ }
+ case QEvent::DragLeave:
+ if (m_dragTarget)
+ QGuiApplication::sendSpontaneousEvent(m_dragTarget.data(), event);
+ m_dragTarget = (QWidget *)0;
+ break;
+ case QEvent::Drop:
+ {
+ QDropEvent *de = static_cast<QDropEvent *>(event);
+ QPoint mapped = m_dragTarget.data()->mapFrom(m_widget, de->pos());
+ QDropEvent translated(mapped, de->possibleActions(), de->mimeData(), de->mouseButtons(), de->keyboardModifiers());
+ QGuiApplication::sendSpontaneousEvent(m_dragTarget.data(), &translated);
+ if (translated.isAccepted())
+ event->accept();
+ de->setDropAction(translated.dropAction());
+ m_dragTarget = (QWidget *)0;
+ }
+ default:
+ break;
+ }
+}
+
+void QWidgetWindow::handleExposeEvent(QExposeEvent *event)
+{
+ m_widget->d_func()->syncBackingStore(event->region());
+}
+
+void QWidgetWindow::handleWindowStateChangedEvent(QWindowStateChangeEvent *event)
+{
+ // QWindow does currently not know 'active'.
+ Qt::WindowStates eventState = event->oldState();
+ if (m_widget->windowState() & Qt::WindowActive)
+ eventState |= Qt::WindowActive;
+ QWindowStateChangeEvent widgetEvent(eventState);
+ QGuiApplication::sendSpontaneousEvent(m_widget, &widgetEvent);
+}
+
+QT_END_NAMESPACE
diff --git a/src/widgets/kernel/qwidgetwindow_qpa_p.h b/src/widgets/kernel/qwidgetwindow_qpa_p.h
new file mode 100644
index 0000000000..86290c693a
--- /dev/null
+++ b/src/widgets/kernel/qwidgetwindow_qpa_p.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWIDGETWINDOW_QPA_P_H
+#define QWIDGETWINDOW_QPA_P_H
+
+#include <QtGui/qwindow.h>
+
+#include <QtCore/private/qobject_p.h>
+#include <QtGui/private/qevent_p.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QCloseEvent;
+class QMoveEvent;
+
+class QWidgetWindow : public QWindow
+{
+ Q_OBJECT
+public:
+ QWidgetWindow(QWidget *widget);
+
+ QWidget *widget() const { return m_widget; }
+
+protected:
+ bool event(QEvent *);
+
+ void handleCloseEvent(QCloseEvent *);
+ void handleEnterLeaveEvent(QEvent *);
+ void handleKeyEvent(QKeyEvent *);
+ void handleMouseEvent(QMouseEvent *);
+ void handleTouchEvent(QTouchEvent *);
+ void handleMoveEvent(QMoveEvent *);
+ void handleResizeEvent(QResizeEvent *);
+ void handleWheelEvent(QWheelEvent *);
+ void handleDragEvent(QEvent *);
+ void handleExposeEvent(QExposeEvent *);
+ void handleWindowStateChangedEvent(QWindowStateChangeEvent *event);
+
+private:
+ void updateGeometry();
+
+ QWidget *m_widget;
+ QWeakPointer<QWidget> m_implicit_mouse_grabber;
+ QWeakPointer<QWidget> m_dragTarget;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QWIDGETWINDOW_QPA_P_H
diff --git a/src/gui/kernel/symbian.pri b/src/widgets/kernel/symbian.pri
index 69422dd02e..69422dd02e 100644
--- a/src/gui/kernel/symbian.pri
+++ b/src/widgets/kernel/symbian.pri
diff --git a/src/gui/kernel/win.pri b/src/widgets/kernel/win.pri
index 5ecf4dd94a..5ecf4dd94a 100644
--- a/src/gui/kernel/win.pri
+++ b/src/widgets/kernel/win.pri
diff --git a/src/gui/kernel/x11.pri b/src/widgets/kernel/x11.pri
index 82de1b68af..82de1b68af 100644
--- a/src/gui/kernel/x11.pri
+++ b/src/widgets/kernel/x11.pri
diff --git a/src/widgets/platforms/mac/qapplication_mac.mm b/src/widgets/platforms/mac/qapplication_mac.mm
new file mode 100644
index 0000000000..5868849836
--- /dev/null
+++ b/src/widgets/platforms/mac/qapplication_mac.mm
@@ -0,0 +1,3131 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/****************************************************************************
+**
+** Copyright (c) 2007-2008, Apple, Inc.
+**
+** All rights reserved.
+**
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are met:
+**
+** * Redistributions of source code must retain the above copyright notice,
+** this list of conditions and the following disclaimer.
+**
+** * Redistributions in binary form must reproduce the above copyright notice,
+** this list of conditions and the following disclaimer in the documentation
+** and/or other materials provided with the distribution.
+**
+** * Neither the name of Apple, Inc. nor the names of its contributors
+** may be used to endorse or promote products derived from this software
+** without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+**
+****************************************************************************/
+
+#include <Cocoa/Cocoa.h>
+
+#include "qapplication.h"
+#include "qbitarray.h"
+#include "qclipboard.h"
+#include "qcursor.h"
+#include "qdatastream.h"
+#include "qdatetime.h"
+#include "qdesktopwidget.h"
+#include "qdockwidget.h"
+#include "qevent.h"
+#include "qhash.h"
+#include "qlayout.h"
+#include "qmenubar.h"
+#include "qmessagebox.h"
+#include "qmime.h"
+#include "qpixmapcache.h"
+#include "qpointer.h"
+#include "qsessionmanager.h"
+#include "qsettings.h"
+#include "qsocketnotifier.h"
+#include "qstyle.h"
+#include "qstylefactory.h"
+#include "qtextcodec.h"
+#include "qtoolbar.h"
+#include "qvariant.h"
+#include "qwidget.h"
+#include "qcolormap.h"
+#include "qdir.h"
+#include "qdebug.h"
+#include "qtimer.h"
+#include "qurl.h"
+#include "private/qmacinputcontext_p.h"
+#include "private/qpaintengine_mac_p.h"
+#include "private/qcursor_p.h"
+#include "private/qapplication_p.h"
+#include "private/qcolor_p.h"
+#include "private/qwidget_p.h"
+#include "private/qkeymapper_p.h"
+#include "private/qeventdispatcher_mac_p.h"
+#include "private/qeventdispatcher_unix_p.h"
+#include <private/qcocoamenuloader_mac_p.h>
+#include <private/qcocoaapplication_mac_p.h>
+#include <private/qcocoaapplicationdelegate_mac_p.h>
+#include <private/qt_cocoa_helpers_mac_p.h>
+#include <private/qcocoawindow_mac_p.h>
+#include <private/qpixmap_mac_p.h>
+#include <private/qdesktopwidget_mac_p.h>
+#include <private/qeventdispatcher_mac_p.h>
+#include <qvarlengtharray.h>
+
+#ifndef QT_NO_ACCESSIBILITY
+# include "qaccessible.h"
+#endif
+
+#ifndef QT_NO_THREAD
+# include "qmutex.h"
+#endif
+
+#include <unistd.h>
+#include <string.h>
+#include <sys/time.h>
+#include <sys/select.h>
+
+/*****************************************************************************
+ QApplication debug facilities
+ *****************************************************************************/
+//#define DEBUG_EVENTS //like EventDebug but more specific to Qt
+//#define DEBUG_DROPPED_EVENTS
+//#define DEBUG_MOUSE_MAPS
+//#define DEBUG_MODAL_EVENTS
+//#define DEBUG_PLATFORM_SETTINGS
+
+#define QMAC_SPEAK_TO_ME
+#ifdef QMAC_SPEAK_TO_ME
+#include "qregexp.h"
+#endif
+
+#ifndef kThemeBrushAlternatePrimaryHighlightColor
+#define kThemeBrushAlternatePrimaryHighlightColor -5
+#endif
+
+#define kCMDeviceUnregisteredNotification CFSTR("CMDeviceUnregisteredNotification")
+#define kCMDefaultDeviceNotification CFSTR("CMDefaultDeviceNotification")
+#define kCMDeviceProfilesNotification CFSTR("CMDeviceProfilesNotification")
+#define kCMDefaultDeviceProfileNotification CFSTR("CMDefaultDeviceProfileNotification")
+
+QT_BEGIN_NAMESPACE
+
+//for qt_mac.h
+QPaintDevice *qt_mac_safe_pdev = 0;
+QList<QMacWindowChangeEvent*> *QMacWindowChangeEvent::change_events = 0;
+QPointer<QWidget> topLevelAt_cache = 0;
+
+/*****************************************************************************
+ Internal variables and functions
+ *****************************************************************************/
+static struct {
+ bool use_qt_time_limit;
+ QPointer<QWidget> last_widget;
+ int last_x, last_y;
+ int last_modifiers, last_button;
+ EventTime last_time;
+} qt_mac_dblclick = { false, 0, -1, -1, 0, 0, -2 };
+
+static bool app_do_modal = false; // modal mode
+extern QWidgetList *qt_modal_stack; // stack of modal widgets
+extern bool qt_tab_all_widgets; // from qapplication.cpp
+bool qt_scrollbar_jump_to_pos = false;
+static bool qt_mac_collapse_on_dblclick = true;
+extern int qt_antialiasing_threshold; // from qapplication.cpp
+QWidget * qt_button_down; // widget got last button-down
+QPointer<QWidget> qt_last_mouse_receiver;
+#ifndef QT_MAC_USE_COCOA
+static bool qt_button_down_in_content; // whether the button_down was in the content area.
+static bool qt_mac_previous_press_in_popup_mode = false;
+static bool qt_mac_no_click_through_mode = false;
+static int tablet_button_state = 0;
+#endif
+#if defined(QT_DEBUG)
+static bool appNoGrab = false; // mouse/keyboard grabbing
+#endif
+#ifndef QT_MAC_USE_COCOA
+static EventHandlerRef app_proc_handler = 0;
+static EventHandlerUPP app_proc_handlerUPP = 0;
+#endif
+static AEEventHandlerUPP app_proc_ae_handlerUPP = NULL;
+static EventHandlerRef tablet_proximity_handler = 0;
+static EventHandlerUPP tablet_proximity_UPP = 0;
+bool QApplicationPrivate::native_modal_dialog_active;
+
+Q_GUI_EXPORT bool qt_applefontsmoothing_enabled;
+
+/*****************************************************************************
+ External functions
+ *****************************************************************************/
+extern void qt_mac_beep(); //qsound_mac.mm
+extern Qt::KeyboardModifiers qt_mac_get_modifiers(int keys); //qkeymapper_mac.cpp
+extern bool qt_mac_can_clickThrough(const QWidget *); //qwidget_mac.cpp
+extern bool qt_mac_is_macdrawer(const QWidget *); //qwidget_mac.cpp
+extern OSWindowRef qt_mac_window_for(const QWidget*); //qwidget_mac.cpp
+extern QWidget *qt_mac_find_window(OSWindowRef); //qwidget_mac.cpp
+extern void qt_mac_set_cursor(const QCursor *); //qcursor_mac.cpp
+extern bool qt_mac_is_macsheet(const QWidget *); //qwidget_mac.cpp
+extern QString qt_mac_from_pascal_string(const Str255); //qglobal.cpp
+extern void qt_mac_command_set_enabled(MenuRef, UInt32, bool); //qmenu_mac.cpp
+extern bool qt_sendSpontaneousEvent(QObject *obj, QEvent *event); // qapplication.cpp
+extern void qt_mac_update_cursor(); // qcursor_mac.mm
+
+// Forward Decls
+void onApplicationWindowChangedActivation( QWidget*widget, bool activated );
+void onApplicationChangedActivation( bool activated );
+
+static void qt_mac_read_fontsmoothing_settings()
+{
+ qt_applefontsmoothing_enabled = true;
+ int w = 10, h = 10;
+ QImage image(w, h, QImage::Format_RGB32);
+ image.fill(0xffffffff);
+ QPainter p(&image);
+ p.drawText(0, h, "X\\");
+ p.end();
+
+ const int *bits = (const int *) ((const QImage &) image).bits();
+ int bpl = image.bytesPerLine() / 4;
+ for (int y=0; y<w; ++y) {
+ for (int x=0; x<h; ++x) {
+ int r = qRed(bits[x]);
+ int g = qGreen(bits[x]);
+ int b = qBlue(bits[x]);
+ if (r != g || r != b) {
+ qt_applefontsmoothing_enabled = true;
+ return;
+ }
+ }
+ bits += bpl;
+ }
+ qt_applefontsmoothing_enabled = false;
+}
+
+Q_GUI_EXPORT bool qt_mac_execute_apple_script(const char *script, long script_len, AEDesc *ret) {
+ OSStatus err;
+ AEDesc scriptTextDesc;
+ ComponentInstance theComponent = 0;
+ OSAID scriptID = kOSANullScript, resultID = kOSANullScript;
+
+ // set up locals to a known state
+ AECreateDesc(typeNull, 0, 0, &scriptTextDesc);
+ scriptID = kOSANullScript;
+ resultID = kOSANullScript;
+
+ // open the scripting component
+ theComponent = OpenDefaultComponent(kOSAComponentType, typeAppleScript);
+ if (!theComponent) {
+ err = paramErr;
+ goto bail;
+ }
+
+ // put the script text into an aedesc
+ err = AECreateDesc(typeUTF8Text, script, script_len, &scriptTextDesc);
+ if (err != noErr)
+ goto bail;
+
+ // compile the script
+ err = OSACompile(theComponent, &scriptTextDesc, kOSAModeNull, &scriptID);
+ if (err != noErr)
+ goto bail;
+
+ // run the script
+ err = OSAExecute(theComponent, scriptID, kOSANullScript, kOSAModeNull, &resultID);
+
+ // collect the results - if any
+ if (ret) {
+ AECreateDesc(typeNull, 0, 0, ret);
+ if (err == errOSAScriptError)
+ OSAScriptError(theComponent, kOSAErrorMessage, typeChar, ret);
+ else if (err == noErr && resultID != kOSANullScript)
+ OSADisplay(theComponent, resultID, typeChar, kOSAModeNull, ret);
+ }
+bail:
+ AEDisposeDesc(&scriptTextDesc);
+ if (scriptID != kOSANullScript)
+ OSADispose(theComponent, scriptID);
+ if (resultID != kOSANullScript)
+ OSADispose(theComponent, resultID);
+ if (theComponent)
+ CloseComponent(theComponent);
+ return err == noErr;
+}
+
+Q_GUI_EXPORT bool qt_mac_execute_apple_script(const char *script, AEDesc *ret)
+{
+ return qt_mac_execute_apple_script(script, qstrlen(script), ret);
+}
+
+Q_GUI_EXPORT bool qt_mac_execute_apple_script(const QString &script, AEDesc *ret)
+{
+ const QByteArray l = script.toUtf8(); return qt_mac_execute_apple_script(l.constData(), l.size(), ret);
+}
+
+/* Resolution change magic */
+void qt_mac_display_change_callbk(CGDirectDisplayID, CGDisplayChangeSummaryFlags flags, void *)
+{
+#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
+ const bool resized = flags & kCGDisplayDesktopShapeChangedFlag;
+#else
+ Q_UNUSED(flags);
+ const bool resized = true;
+#endif
+ if (resized && qApp) {
+ if (QDesktopWidget *dw = qApp->desktop()) {
+ QResizeEvent *re = new QResizeEvent(dw->size(), dw->size());
+ QApplication::postEvent(dw, re);
+ QCoreGraphicsPaintEngine::cleanUpMacColorSpaces();
+ }
+ }
+}
+
+#ifdef DEBUG_PLATFORM_SETTINGS
+static void qt_mac_debug_palette(const QPalette &pal, const QPalette &pal2, const QString &where)
+{
+ const char *const groups[] = {"Active", "Disabled", "Inactive" };
+ const char *const roles[] = { "WindowText", "Button", "Light", "Midlight", "Dark", "Mid",
+ "Text", "BrightText", "ButtonText", "Base", "Window", "Shadow",
+ "Highlight", "HighlightedText", "Link", "LinkVisited" };
+ if (!where.isNull())
+ qDebug("qt-internal: %s", where.toLatin1().constData());
+ for(int grp = 0; grp < QPalette::NColorGroups; grp++) {
+ for(int role = 0; role < QPalette::NColorRoles; role++) {
+ QBrush b = pal.brush((QPalette::ColorGroup)grp, (QPalette::ColorRole)role);
+ QPixmap pm = b.texture();
+ qDebug(" %s::%s %d::%d::%d [%p]%s", groups[grp], roles[role], b.color().red(),
+ b.color().green(), b.color().blue(), pm.isNull() ? 0 : &pm,
+ pal2.brush((QPalette::ColorGroup)grp, (QPalette::ColorRole)role) != b ? " (*)" : "");
+ }
+ }
+
+}
+#else
+#define qt_mac_debug_palette(x, y, z)
+#endif
+
+//raise a notification
+#ifndef QT_MAC_USE_COCOA
+static NMRec qt_mac_notification = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+#endif
+void qt_mac_send_notification()
+{
+#ifndef QT_MAC_USE_COCOA
+ //send it
+ qt_mac_notification.nmMark = 1; //non-zero magic number
+ qt_mac_notification.qType = nmType;
+ NMInstall(&qt_mac_notification);
+#else
+ QMacCocoaAutoReleasePool pool;
+ [[NSApplication sharedApplication] requestUserAttention:NSInformationalRequest];
+#endif
+}
+
+void qt_mac_cancel_notification()
+{
+#ifndef QT_MAC_USE_COCOA
+ NMRemove(&qt_mac_notification);
+#else
+ QMacCocoaAutoReleasePool pool;
+ [[NSApplication sharedApplication] cancelUserAttentionRequest:NSInformationalRequest];
+#endif
+}
+
+#ifndef QT_MAC_USE_COCOA
+//find widget (and part) at a given point
+static short qt_mac_window_at(int x, int y, QWidget **w=0)
+{
+ Point p;
+ p.h = x;
+ p.v = y;
+ OSWindowRef wp;
+ WindowPartCode wpc;
+ OSStatus err = FindWindowOfClass(&p, kAllWindowClasses, &wp, &wpc);
+ if(err != noErr) {
+ if(w)
+ (*w) = 0;
+ return wpc;
+ }
+ if(w) {
+ if(wp) {
+ *w = qt_mac_find_window(wp);
+#if 0
+ if(!*w)
+ qWarning("QApplication: qt_mac_window_at: Couldn't find %d",(int)wp);
+#endif
+ } else {
+ *w = 0;
+ }
+ }
+ return wpc;
+}
+
+#endif
+
+void qt_mac_set_app_icon(const QPixmap &pixmap)
+{
+#ifndef QT_MAC_USE_COCOA
+ if(pixmap.isNull()) {
+ RestoreApplicationDockTileImage();
+ } else {
+ CGImageRef img = (CGImageRef)pixmap.macCGHandle();
+ SetApplicationDockTileImage(img);
+ CGImageRelease(img);
+ }
+#else
+ QMacCocoaAutoReleasePool pool;
+ NSImage *image = NULL;
+ if (pixmap.isNull()) {
+ // Get Application icon from bundle
+ image = [[NSImage imageNamed:@"NSApplicationIcon"] retain]; // released below
+ } else {
+ image = static_cast<NSImage *>(qt_mac_create_nsimage(pixmap));
+ }
+
+ [NSApp setApplicationIconImage:image];
+ [image release];
+#endif
+}
+
+Q_GUI_EXPORT void qt_mac_set_press_and_hold_context(bool b)
+{
+ Q_UNUSED(b);
+ qWarning("qt_mac_set_press_and_hold_context: This functionality is no longer available");
+}
+
+bool qt_nograb() // application no-grab option
+{
+#if defined(QT_DEBUG)
+ return appNoGrab;
+#else
+ return false;
+#endif
+}
+
+void qt_mac_update_os_settings()
+{
+ if (!qApp)
+ return;
+ if (!QApplication::startingUp()) {
+ static bool needToPolish = true;
+ if (needToPolish) {
+ QApplication::style()->polish(qApp);
+ needToPolish = false;
+ }
+ }
+ //focus mode
+ /* First worked as of 10.2.3 */
+ QSettings appleSettings(QLatin1String("apple.com"));
+ QVariant appleValue = appleSettings.value(QLatin1String("AppleKeyboardUIMode"), 0);
+ qt_tab_all_widgets = (appleValue.toInt() & 0x2);
+ //paging mode
+ /* First worked as of 10.2.3 */
+ appleValue = appleSettings.value(QLatin1String("AppleScrollerPagingBehavior"), false);
+ qt_scrollbar_jump_to_pos = appleValue.toBool();
+ //collapse
+ /* First worked as of 10.3.3 */
+ appleValue = appleSettings.value(QLatin1String("AppleMiniaturizeOnDoubleClick"), true);
+ qt_mac_collapse_on_dblclick = appleValue.toBool();
+
+ // Anti-aliasing threshold
+ appleValue = appleSettings.value(QLatin1String("AppleAntiAliasingThreshold"));
+ if (appleValue.isValid())
+ qt_antialiasing_threshold = appleValue.toInt();
+
+#ifdef DEBUG_PLATFORM_SETTINGS
+ qDebug("qt_mac_update_os_settings *********************************************************************");
+#endif
+ { // setup the global palette
+ QColor qc;
+ (void) QApplication::style(); // trigger creation of application style and system palettes
+ QPalette pal = *QApplicationPrivate::sys_pal;
+
+ pal.setBrush( QPalette::Active, QPalette::Highlight, qcolorForTheme(kThemeBrushPrimaryHighlightColor) );
+ pal.setBrush( QPalette::Inactive, QPalette::Highlight, qcolorForTheme(kThemeBrushSecondaryHighlightColor) );
+
+ pal.setBrush( QPalette::Disabled, QPalette::Highlight, qcolorForTheme(kThemeBrushSecondaryHighlightColor) );
+ pal.setBrush( QPalette::Active, QPalette::Shadow, qcolorForTheme(kThemeBrushButtonActiveDarkShadow) );
+
+ pal.setBrush( QPalette::Inactive, QPalette::Shadow, qcolorForTheme(kThemeBrushButtonInactiveDarkShadow) );
+ pal.setBrush( QPalette::Disabled, QPalette::Shadow, qcolorForTheme(kThemeBrushButtonInactiveDarkShadow) );
+
+ qc = qcolorForThemeTextColor(kThemeTextColorDialogActive);
+ pal.setColor(QPalette::Active, QPalette::Text, qc);
+ pal.setColor(QPalette::Active, QPalette::WindowText, qc);
+ pal.setColor(QPalette::Active, QPalette::HighlightedText, qc);
+
+ qc = qcolorForThemeTextColor(kThemeTextColorDialogInactive);
+ pal.setColor(QPalette::Inactive, QPalette::Text, qc);
+ pal.setColor(QPalette::Inactive, QPalette::WindowText, qc);
+ pal.setColor(QPalette::Inactive, QPalette::HighlightedText, qc);
+ pal.setColor(QPalette::Disabled, QPalette::Text, qc);
+ pal.setColor(QPalette::Disabled, QPalette::WindowText, qc);
+ pal.setColor(QPalette::Disabled, QPalette::HighlightedText, qc);
+ pal.setBrush(QPalette::ToolTipBase, QColor(255, 255, 199));
+
+ if (!QApplicationPrivate::sys_pal || *QApplicationPrivate::sys_pal != pal) {
+ QApplicationPrivate::setSystemPalette(pal);
+ QApplication::setPalette(pal);
+ }
+#ifdef DEBUG_PLATFORM_SETTINGS
+ qt_mac_debug_palette(pal, QApplication::palette(), "Global Palette");
+#endif
+ }
+
+ QFont fnt = qfontForThemeFont(kThemeApplicationFont);
+#ifdef DEBUG_PLATFORM_SETTINGS
+ qDebug("qt-internal: Font for Application [%s::%d::%d::%d]",
+ fnt.family().toLatin1().constData(), fnt.pointSize(), fnt.bold(), fnt.italic());
+#endif
+ if (!QApplicationPrivate::sys_font || *QApplicationPrivate::sys_font != fnt)
+ QApplicationPrivate::setSystemFont(fnt);
+
+ { //setup the fonts
+ struct FontMap {
+ FontMap(const char *qc, short fk) : qt_class(qc), font_key(fk) { }
+ const char *const qt_class;
+ short font_key;
+ } mac_widget_fonts[] = {
+ FontMap("QPushButton", kThemePushButtonFont),
+ FontMap("QListView", kThemeViewsFont),
+ FontMap("QListBox", kThemeViewsFont),
+ FontMap("QTitleBar", kThemeWindowTitleFont),
+ FontMap("QMenuBar", kThemeMenuTitleFont),
+ FontMap("QMenu", kThemeMenuItemFont),
+ FontMap("QComboMenuItem", kThemeSystemFont),
+ FontMap("QHeaderView", kThemeSmallSystemFont),
+ FontMap("Q3Header", kThemeSmallSystemFont),
+ FontMap("QTipLabel", kThemeSmallSystemFont),
+ FontMap("QLabel", kThemeSystemFont),
+ FontMap("QToolButton", kThemeSmallSystemFont),
+ FontMap("QMenuItem", kThemeMenuItemFont), // It doesn't exist, but its unique.
+ FontMap("QComboLineEdit", kThemeViewsFont), // It doesn't exist, but its unique.
+ FontMap("QSmallFont", kThemeSmallSystemFont), // It doesn't exist, but its unique.
+ FontMap("QMiniFont", kThemeMiniSystemFont), // It doesn't exist, but its unique.
+ FontMap(0, 0) };
+ for(int i = 0; mac_widget_fonts[i].qt_class; i++) {
+ QFont fnt = qfontForThemeFont(mac_widget_fonts[i].font_key);
+ bool set_font = true;
+ FontHash *hash = qt_app_fonts_hash();
+ if (!hash->isEmpty()) {
+ FontHash::const_iterator it
+ = hash->constFind(mac_widget_fonts[i].qt_class);
+ if (it != hash->constEnd())
+ set_font = (fnt != *it);
+ }
+ if (set_font) {
+ QApplication::setFont(fnt, mac_widget_fonts[i].qt_class);
+#ifdef DEBUG_PLATFORM_SETTINGS
+ qDebug("qt-internal: Font for %s [%s::%d::%d::%d]", mac_widget_fonts[i].qt_class,
+ fnt.family().toLatin1().constData(), fnt.pointSize(), fnt.bold(), fnt.italic());
+#endif
+ }
+ }
+ }
+ QApplicationPrivate::initializeWidgetPaletteHash();
+#ifdef DEBUG_PLATFORM_SETTINGS
+ qDebug("qt_mac_update_os_settings END !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
+#endif
+}
+
+void QApplicationPrivate::initializeWidgetPaletteHash()
+{
+ { //setup the palette
+ struct PaletteMap {
+ inline PaletteMap(const char *qc, ThemeBrush a, ThemeBrush i) :
+ qt_class(qc), active(a), inactive(i) { }
+ const char *const qt_class;
+ ThemeBrush active, inactive;
+ } mac_widget_colors[] = {
+ PaletteMap("QToolButton", kThemeTextColorBevelButtonActive, kThemeTextColorBevelButtonInactive),
+ PaletteMap("QAbstractButton", kThemeTextColorPushButtonActive, kThemeTextColorPushButtonInactive),
+ PaletteMap("QHeaderView", kThemeTextColorPushButtonActive, kThemeTextColorPushButtonInactive),
+ PaletteMap("Q3Header", kThemeTextColorPushButtonActive, kThemeTextColorPushButtonInactive),
+ PaletteMap("QComboBox", kThemeTextColorPopupButtonActive, kThemeTextColorPopupButtonInactive),
+ PaletteMap("QAbstractItemView", kThemeTextColorListView, kThemeTextColorDialogInactive),
+ PaletteMap("QMessageBoxLabel", kThemeTextColorAlertActive, kThemeTextColorAlertInactive),
+ PaletteMap("QTabBar", kThemeTextColorTabFrontActive, kThemeTextColorTabFrontInactive),
+ PaletteMap("QLabel", kThemeTextColorPlacardActive, kThemeTextColorPlacardInactive),
+ PaletteMap("QGroupBox", kThemeTextColorPlacardActive, kThemeTextColorPlacardInactive),
+ PaletteMap("QMenu", kThemeTextColorPopupLabelActive, kThemeTextColorPopupLabelInactive),
+ PaletteMap("QTextEdit", 0, 0),
+ PaletteMap("QTextControl", 0, 0),
+ PaletteMap("QLineEdit", 0, 0),
+ PaletteMap(0, 0, 0) };
+ QColor qc;
+ for(int i = 0; mac_widget_colors[i].qt_class; i++) {
+ QPalette pal;
+ if (mac_widget_colors[i].active != 0) {
+ qc = qcolorForThemeTextColor(mac_widget_colors[i].active);
+ pal.setColor(QPalette::Active, QPalette::Text, qc);
+ pal.setColor(QPalette::Active, QPalette::WindowText, qc);
+ pal.setColor(QPalette::Active, QPalette::HighlightedText, qc);
+ qc = qcolorForThemeTextColor(mac_widget_colors[i].inactive);
+ pal.setColor(QPalette::Inactive, QPalette::Text, qc);
+ pal.setColor(QPalette::Disabled, QPalette::Text, qc);
+ pal.setColor(QPalette::Inactive, QPalette::WindowText, qc);
+ pal.setColor(QPalette::Disabled, QPalette::WindowText, qc);
+ pal.setColor(QPalette::Inactive, QPalette::HighlightedText, qc);
+ pal.setColor(QPalette::Disabled, QPalette::HighlightedText, qc);
+ }
+ if (!strcmp(mac_widget_colors[i].qt_class, "QMenu")) {
+ qc = qcolorForThemeTextColor(kThemeTextColorMenuItemActive);
+ pal.setBrush(QPalette::ButtonText, qc);
+ qc = qcolorForThemeTextColor(kThemeTextColorMenuItemSelected);
+ pal.setBrush(QPalette::HighlightedText, qc);
+ qc = qcolorForThemeTextColor(kThemeTextColorMenuItemDisabled);
+ pal.setBrush(QPalette::Disabled, QPalette::Text, qc);
+ } else if (!strcmp(mac_widget_colors[i].qt_class, "QAbstractButton")
+ || !strcmp(mac_widget_colors[i].qt_class, "QHeaderView")
+ || !strcmp(mac_widget_colors[i].qt_class, "Q3Header")) { //special
+ pal.setColor(QPalette::Disabled, QPalette::ButtonText,
+ pal.color(QPalette::Disabled, QPalette::Text));
+ pal.setColor(QPalette::Inactive, QPalette::ButtonText,
+ pal.color(QPalette::Inactive, QPalette::Text));
+ pal.setColor(QPalette::Active, QPalette::ButtonText,
+ pal.color(QPalette::Active, QPalette::Text));
+ } else if (!strcmp(mac_widget_colors[i].qt_class, "QAbstractItemView")) {
+ pal.setBrush(QPalette::Active, QPalette::Highlight,
+ qcolorForTheme(kThemeBrushAlternatePrimaryHighlightColor));
+ qc = qcolorForThemeTextColor(kThemeTextColorMenuItemSelected);
+ pal.setBrush(QPalette::Active, QPalette::HighlightedText, qc);
+#if 1
+ pal.setBrush(QPalette::Inactive, QPalette::Text,
+ pal.brush(QPalette::Active, QPalette::Text));
+ pal.setBrush(QPalette::Inactive, QPalette::HighlightedText,
+ pal.brush(QPalette::Active, QPalette::Text));
+#endif
+ } else if (!strcmp(mac_widget_colors[i].qt_class, "QTextEdit")
+ || !strcmp(mac_widget_colors[i].qt_class, "QTextControl")) {
+ pal.setBrush(QPalette::Inactive, QPalette::Text,
+ pal.brush(QPalette::Active, QPalette::Text));
+ pal.setBrush(QPalette::Inactive, QPalette::HighlightedText,
+ pal.brush(QPalette::Active, QPalette::Text));
+ } else if (!strcmp(mac_widget_colors[i].qt_class, "QLineEdit")) {
+ pal.setBrush(QPalette::Disabled, QPalette::Base,
+ pal.brush(QPalette::Active, QPalette::Base));
+ }
+
+ bool set_palette = true;
+ PaletteHash *phash = qt_app_palettes_hash();
+ if (!phash->isEmpty()) {
+ PaletteHash::const_iterator it
+ = phash->constFind(mac_widget_colors[i].qt_class);
+ if (it != phash->constEnd())
+ set_palette = (pal != *it);
+ }
+ if (set_palette) {
+ QApplication::setPalette(pal, mac_widget_colors[i].qt_class);
+#ifdef DEBUG_PLATFORM_SETTINGS
+ qt_mac_debug_palette(pal, QApplication::palette(), QLatin1String("Palette for ") + QString::fromLatin1(mac_widget_colors[i].qt_class));
+#endif
+ }
+ }
+ }
+}
+
+static void qt_mac_event_release(EventRef &event)
+{
+ ReleaseEvent(event);
+ event = 0;
+}
+#ifndef QT_MAC_USE_COCOA
+static void qt_mac_event_release(QWidget *w, EventRef &event)
+{
+ if (event) {
+ QWidget *widget = 0;
+ if (GetEventParameter(event, kEventParamQWidget, typeQWidget, 0, sizeof(widget), 0, &widget) == noErr
+ && w == widget) {
+ if (IsEventInQueue(GetMainEventQueue(), event))
+ RemoveEventFromQueue(GetMainEventQueue(), event);
+ qt_mac_event_release(event);
+ }
+ }
+}
+
+static bool qt_mac_event_remove(EventRef &event)
+{
+ if (event) {
+ if (IsEventInQueue(GetMainEventQueue(), event))
+ RemoveEventFromQueue(GetMainEventQueue(), event);
+ qt_mac_event_release(event);
+ return true;
+ }
+ return false;
+}
+#endif
+
+/* sheets */
+#ifndef QT_MAC_USE_COCOA
+static EventRef request_showsheet_pending = 0;
+#endif
+void qt_event_request_showsheet(QWidget *w)
+{
+ Q_ASSERT(qt_mac_is_macsheet(w));
+#ifdef QT_MAC_USE_COCOA
+ [NSApp beginSheet:qt_mac_window_for(w) modalForWindow:qt_mac_window_for(w->parentWidget())
+ modalDelegate:nil didEndSelector:nil contextInfo:0];
+#else
+ qt_mac_event_remove(request_showsheet_pending);
+ CreateEvent(0, kEventClassQt, kEventQtRequestShowSheet, GetCurrentEventTime(),
+ kEventAttributeUserEvent, &request_showsheet_pending);
+ SetEventParameter(request_showsheet_pending, kEventParamQWidget, typeQWidget, sizeof(w), &w);
+ PostEventToQueue(GetMainEventQueue(), request_showsheet_pending, kEventPriorityStandard);
+#endif
+}
+
+static void qt_post_window_change_event(QWidget *widget)
+{
+ qt_widget_private(widget)->needWindowChange = true;
+ QEvent *glWindowChangeEvent = new QEvent(QEvent::MacGLWindowChange);
+ QApplication::postEvent(widget, glWindowChangeEvent);
+}
+
+/*
+ Posts updates to all child and grandchild OpenGL widgets for the given widget.
+*/
+static void qt_mac_update_child_gl_widgets(QWidget *widget)
+{
+ // Update all OpenGL child widgets for the given widget.
+ QList<QWidgetPrivate::GlWidgetInfo> &glWidgets = qt_widget_private(widget)->glWidgets;
+ QList<QWidgetPrivate::GlWidgetInfo>::iterator end = glWidgets.end();
+ QList<QWidgetPrivate::GlWidgetInfo>::iterator it = glWidgets.begin();
+
+ for (;it != end; ++it) {
+ qt_post_window_change_event(it->widget);
+ }
+}
+
+/*
+ Sends updates to all child and grandchild gl widgets that have updates pending.
+*/
+void qt_mac_send_posted_gl_updates(QWidget *widget)
+{
+ QList<QWidgetPrivate::GlWidgetInfo> &glWidgets = qt_widget_private(widget)->glWidgets;
+ QList<QWidgetPrivate::GlWidgetInfo>::iterator end = glWidgets.end();
+ QList<QWidgetPrivate::GlWidgetInfo>::iterator it = glWidgets.begin();
+
+ for (;it != end; ++it) {
+ QWidget *glWidget = it->widget;
+ if (qt_widget_private(glWidget)->needWindowChange) {
+ QEvent glChangeEvent(QEvent::MacGLWindowChange);
+ QApplication::sendEvent(glWidget, &glChangeEvent);
+ }
+ }
+}
+
+/*
+ Posts updates to all OpenGL widgets within the window that the given widget intersects.
+*/
+static void qt_mac_update_intersected_gl_widgets(QWidget *widget)
+{
+#ifndef QT_MAC_USE_COCOA
+ QList<QWidgetPrivate::GlWidgetInfo> &glWidgets = qt_widget_private(widget->window())->glWidgets;
+ if (glWidgets.isEmpty())
+ return;
+
+ // Exit if the window has not been created yet (mapToGlobal/size will force create it)
+ if (widget->testAttribute(Qt::WA_WState_Created) == false || HIViewGetWindow(qt_mac_nativeview_for(widget)) == 0)
+ return;
+
+ const QRect globalWidgetRect = QRect(widget->mapToGlobal(QPoint(0, 0)), widget->size());
+
+ QList<QWidgetPrivate::GlWidgetInfo>::iterator end = glWidgets.end();
+ QList<QWidgetPrivate::GlWidgetInfo>::iterator it = glWidgets.begin();
+
+ for (;it != end; ++it){
+ QWidget *glWidget = it->widget;
+ const QRect globalGlWidgetRect = QRect(glWidget->mapToGlobal(QPoint(0, 0)), glWidget->size());
+ if (globalWidgetRect.intersects(globalGlWidgetRect)) {
+ qt_post_window_change_event(glWidget);
+ it->lastUpdateWidget = widget;
+ } else if (it->lastUpdateWidget == widget) {
+ // Update the gl wigets that the widget intersected the last time around,
+ // and that we are not intersecting now. This prevents paint errors when the
+ // intersecting widget leaves a gl widget.
+ qt_post_window_change_event(glWidget);
+ it->lastUpdateWidget = 0;
+ }
+ }
+#else
+ Q_UNUSED(widget);
+#endif
+}
+
+/*
+ Posts a kEventQtRequestWindowChange event to the main Carbon event queue.
+*/
+static EventRef request_window_change_pending = 0;
+Q_GUI_EXPORT void qt_event_request_window_change()
+{
+ if(request_window_change_pending)
+ return;
+
+ CreateEvent(0, kEventClassQt, kEventQtRequestWindowChange, GetCurrentEventTime(),
+ kEventAttributeUserEvent, &request_window_change_pending);
+ PostEventToQueue(GetMainEventQueue(), request_window_change_pending, kEventPriorityHigh);
+}
+
+/* window changing. This is a hack around Apple's missing functionality, pending the toolbox
+ team fix. --Sam */
+Q_GUI_EXPORT void qt_event_request_window_change(QWidget *widget)
+{
+ if (!widget)
+ return;
+
+ // Post a kEventQtRequestWindowChange event. This event is semi-public,
+ // don't remove this line!
+ qt_event_request_window_change();
+
+ // Post update request on gl widgets unconditionally.
+ if (qt_widget_private(widget)->isGLWidget == true) {
+ qt_post_window_change_event(widget);
+ return;
+ }
+
+ qt_mac_update_child_gl_widgets(widget);
+ qt_mac_update_intersected_gl_widgets(widget);
+}
+
+/* activation */
+static struct {
+ QPointer<QWidget> widget;
+ EventRef event;
+ EventLoopTimerRef timer;
+ EventLoopTimerUPP timerUPP;
+} request_activate_pending = { 0, 0, 0, 0 };
+bool qt_event_remove_activate()
+{
+ if (request_activate_pending.timer) {
+ RemoveEventLoopTimer(request_activate_pending.timer);
+ request_activate_pending.timer = 0;
+ }
+ if (request_activate_pending.event)
+ qt_mac_event_release(request_activate_pending.event);
+ return true;
+}
+
+void qt_event_activate_timer_callbk(EventLoopTimerRef r, void *)
+{
+ EventLoopTimerRef otc = request_activate_pending.timer;
+ qt_event_remove_activate();
+ if (r == otc && !request_activate_pending.widget.isNull()) {
+ const QWidget *tlw = request_activate_pending.widget->window();
+ Qt::WindowType wt = tlw->windowType();
+ if (tlw->isVisible()
+ && ((wt != Qt::Desktop && wt != Qt::Popup && wt != Qt::Tool) || tlw->isModal())) {
+ CreateEvent(0, kEventClassQt, kEventQtRequestActivate, GetCurrentEventTime(),
+ kEventAttributeUserEvent, &request_activate_pending.event);
+ PostEventToQueue(GetMainEventQueue(), request_activate_pending.event, kEventPriorityHigh);
+ }
+ }
+}
+
+void qt_event_request_activate(QWidget *w)
+{
+ if (w == request_activate_pending.widget)
+ return;
+
+ /* We put these into a timer because due to order of events being sent we need to be sure this
+ comes from inside of the event loop */
+ qt_event_remove_activate();
+ if (!request_activate_pending.timerUPP)
+ request_activate_pending.timerUPP = NewEventLoopTimerUPP(qt_event_activate_timer_callbk);
+ request_activate_pending.widget = w;
+ InstallEventLoopTimer(GetMainEventLoop(), 0, 0, request_activate_pending.timerUPP, 0, &request_activate_pending.timer);
+}
+
+
+/* menubars */
+#ifndef QT_MAC_USE_COCOA
+static EventRef request_menubarupdate_pending = 0;
+#endif
+void qt_event_request_menubarupdate()
+{
+#ifndef QT_MAC_USE_COCOA
+ if (request_menubarupdate_pending) {
+ if (IsEventInQueue(GetMainEventQueue(), request_menubarupdate_pending))
+ return;
+#ifdef DEBUG_DROPPED_EVENTS
+ qDebug("%s:%d Whoa, we dropped an event on the floor!", __FILE__, __LINE__);
+#endif
+ }
+
+ CreateEvent(0, kEventClassQt, kEventQtRequestMenubarUpdate, GetCurrentEventTime(),
+ kEventAttributeUserEvent, &request_menubarupdate_pending);
+ PostEventToQueue(GetMainEventQueue(), request_menubarupdate_pending, kEventPriorityHigh);
+#else
+ // Just call this. The request has the benefit that we don't call this multiple times, but
+ // we can optimize this.
+ QMenuBar::macUpdateMenuBar();
+#endif
+}
+
+#ifndef QT_MAC_USE_COCOA
+//context menu
+static EventRef request_context_pending = 0;
+static void qt_event_request_context(QWidget *w=0, EventRef *where=0)
+{
+ if (!where)
+ where = &request_context_pending;
+ if (*where)
+ return;
+ CreateEvent(0, kEventClassQt, kEventQtRequestContext, GetCurrentEventTime(),
+ kEventAttributeUserEvent, where);
+ if (w)
+ SetEventParameter(*where, kEventParamQWidget, typeQWidget, sizeof(w), &w);
+ PostEventToQueue(GetMainEventQueue(), *where, kEventPriorityStandard);
+}
+#endif
+
+void QApplicationPrivate::createEventDispatcher()
+{
+ Q_Q(QApplication);
+ if (q->type() != QApplication::Tty)
+ eventDispatcher = new QEventDispatcherMac(q);
+ else
+ eventDispatcher = new QEventDispatcherUNIX(q);
+}
+
+/* clipboard */
+void qt_event_send_clipboard_changed()
+{
+#ifndef QT_MAC_USE_COCOA
+ AppleEvent ae;
+ if (AECreateAppleEvent(kEventClassQt, typeAEClipboardChanged, 0, kAutoGenerateReturnID, kAnyTransactionID, &ae) != noErr)
+ qDebug("Can't happen!!");
+ AppleEvent reply;
+ AESend(&ae, &reply, kAENoReply, kAENormalPriority, kAEDefaultTimeout, 0, 0);
+#endif
+}
+
+/* app menu */
+static QMenu *qt_mac_dock_menu = 0;
+Q_GUI_EXPORT void qt_mac_set_dock_menu(QMenu *menu)
+{
+ qt_mac_dock_menu = menu;
+#ifdef QT_MAC_USE_COCOA
+ [NSApp setDockMenu:menu->macMenu()];
+#else
+ SetApplicationDockTileMenu(menu->macMenu());
+#endif
+}
+
+/* events that hold pointers to widgets, must be cleaned up like this */
+void qt_mac_event_release(QWidget *w)
+{
+ if (w) {
+#ifndef QT_MAC_USE_COCOA
+ qt_mac_event_release(w, request_showsheet_pending);
+ qt_mac_event_release(w, request_context_pending);
+#endif
+ if (w == qt_mac_dock_menu) {
+ qt_mac_dock_menu = 0;
+#ifndef QT_MAC_USE_COCOA
+ SetApplicationDockTileMenu(0);
+#else
+ [NSApp setDockMenu:0];
+#endif
+ }
+ }
+}
+
+struct QMacAppleEventTypeSpec {
+ AEEventClass mac_class;
+ AEEventID mac_id;
+} app_apple_events[] = {
+ { kCoreEventClass, kAEQuitApplication },
+ { kCoreEventClass, kAEOpenDocuments },
+ { kInternetEventClass, kAEGetURL },
+};
+
+#ifndef QT_MAC_USE_COCOA
+
+#if (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5)
+enum
+{
+ kEventMouseScroll = 11,
+ kEventParamMouseWheelSmoothVerticalDelta = 'saxy',
+ kEventParamMouseWheelSmoothHorizontalDelta = 'saxx',
+};
+#endif
+
+/* watched events */
+static EventTypeSpec app_events[] = {
+ { kEventClassQt, kEventQtRequestWindowChange },
+ { kEventClassQt, kEventQtRequestShowSheet },
+ { kEventClassQt, kEventQtRequestContext },
+ { kEventClassQt, kEventQtRequestActivate },
+ { kEventClassQt, kEventQtRequestMenubarUpdate },
+
+ { kEventClassWindow, kEventWindowActivated },
+ { kEventClassWindow, kEventWindowDeactivated },
+
+ { kEventClassMouse, kEventMouseScroll },
+ { kEventClassMouse, kEventMouseWheelMoved },
+ { kEventClassMouse, kEventMouseDown },
+ { kEventClassMouse, kEventMouseUp },
+ { kEventClassMouse, kEventMouseDragged },
+ { kEventClassMouse, kEventMouseMoved },
+
+ { kEventClassTablet, kEventTabletProximity },
+
+ { kEventClassApplication, kEventAppActivated },
+ { kEventClassApplication, kEventAppDeactivated },
+ { kEventClassApplication, kEventAppAvailableWindowBoundsChanged },
+
+ // { kEventClassTextInput, kEventTextInputUnicodeForKeyEvent },
+ { kEventClassKeyboard, kEventRawKeyModifiersChanged },
+ { kEventClassKeyboard, kEventRawKeyRepeat },
+ { kEventClassKeyboard, kEventRawKeyUp },
+ { kEventClassKeyboard, kEventRawKeyDown },
+
+ { kEventClassCommand, kEventCommandProcess },
+
+ { kEventClassAppleEvent, kEventAppleEvent },
+
+ { kAppearanceEventClass, kAEAppearanceChanged }
+};
+
+void qt_init_app_proc_handler()
+{
+ InstallEventHandler(GetApplicationEventTarget(), app_proc_handlerUPP,
+ GetEventTypeCount(app_events), app_events, (void *)qApp,
+ &app_proc_handler);
+}
+#endif // QT_MAC_USE_COCOA
+
+static void qt_init_tablet_proximity_handler()
+{
+ EventTypeSpec tabletProximityEvent = { kEventClassTablet, kEventTabletProximity };
+ InstallEventHandler(GetEventMonitorTarget(), tablet_proximity_UPP,
+ 1, &tabletProximityEvent, qApp, &tablet_proximity_handler);
+}
+
+static void qt_release_tablet_proximity_handler()
+{
+ RemoveEventHandler(tablet_proximity_handler);
+}
+
+QString QApplicationPrivate::appName() const
+{
+ static QString applName;
+ if (applName.isEmpty()) {
+ applName = QCoreApplicationPrivate::macMenuBarName();
+ ProcessSerialNumber psn;
+ if (applName.isEmpty() && qt_is_gui_used && GetCurrentProcess(&psn) == noErr) {
+ QCFString cfstr;
+ CopyProcessName(&psn, &cfstr);
+ applName = cfstr;
+ }
+ }
+ return applName;
+}
+
+void qt_release_app_proc_handler()
+{
+#ifndef QT_MAC_USE_COCOA
+ if (app_proc_handler) {
+ RemoveEventHandler(app_proc_handler);
+ app_proc_handler = 0;
+ }
+#endif
+}
+
+void qt_color_profile_changed(CFNotificationCenterRef, void *, CFStringRef, const void *,
+ CFDictionaryRef)
+{
+ QCoreGraphicsPaintEngine::cleanUpMacColorSpaces();
+}
+/* platform specific implementations */
+void qt_init(QApplicationPrivate *priv, int)
+{
+ if (qt_is_gui_used) {
+ CGDisplayRegisterReconfigurationCallback(qt_mac_display_change_callbk, 0);
+ CFNotificationCenterRef center = CFNotificationCenterGetDistributedCenter();
+ CFNotificationCenterAddObserver(center, qApp, qt_color_profile_changed,
+ kCMDeviceUnregisteredNotification, 0,
+ CFNotificationSuspensionBehaviorDeliverImmediately);
+ CFNotificationCenterAddObserver(center, qApp, qt_color_profile_changed,
+ kCMDefaultDeviceNotification, 0,
+ CFNotificationSuspensionBehaviorDeliverImmediately);
+ CFNotificationCenterAddObserver(center, qApp, qt_color_profile_changed,
+ kCMDeviceProfilesNotification, 0,
+ CFNotificationSuspensionBehaviorDeliverImmediately);
+ CFNotificationCenterAddObserver(center, qApp, qt_color_profile_changed,
+ kCMDefaultDeviceProfileNotification, 0,
+ CFNotificationSuspensionBehaviorDeliverImmediately);
+ ProcessSerialNumber psn;
+ if (GetCurrentProcess(&psn) == noErr) {
+ // Jambi needs to transform itself since most people aren't "used"
+ // to putting things in bundles, but other people may actually not
+ // want to tranform the process (running as a helper or something)
+ // so don't do that for them. This means checking both LSUIElement
+ // and LSBackgroundOnly. If you set them both... well, you
+ // shouldn't do that.
+
+ bool forceTransform = true;
+ CFTypeRef value = CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(),
+ CFSTR("LSUIElement"));
+ if (value) {
+ CFTypeID valueType = CFGetTypeID(value);
+ // Officially it's supposed to be a string, a boolean makes sense, so we'll check.
+ // A number less so, but OK.
+ if (valueType == CFStringGetTypeID())
+ forceTransform = !(QCFString::toQString(static_cast<CFStringRef>(value)).toInt());
+ else if (valueType == CFBooleanGetTypeID())
+ forceTransform = !CFBooleanGetValue(static_cast<CFBooleanRef>(value));
+ else if (valueType == CFNumberGetTypeID()) {
+ int valueAsInt;
+ CFNumberGetValue(static_cast<CFNumberRef>(value), kCFNumberIntType, &valueAsInt);
+ forceTransform = !valueAsInt;
+ }
+ }
+
+ if (forceTransform) {
+ value = CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(),
+ CFSTR("LSBackgroundOnly"));
+ if (value) {
+ CFTypeID valueType = CFGetTypeID(value);
+ if (valueType == CFBooleanGetTypeID())
+ forceTransform = !CFBooleanGetValue(static_cast<CFBooleanRef>(value));
+ else if (valueType == CFStringGetTypeID())
+ forceTransform = !(QCFString::toQString(static_cast<CFStringRef>(value)).toInt());
+ else if (valueType == CFNumberGetTypeID()) {
+ int valueAsInt;
+ CFNumberGetValue(static_cast<CFNumberRef>(value), kCFNumberIntType, &valueAsInt);
+ forceTransform = !valueAsInt;
+ }
+ }
+ }
+
+
+ if (forceTransform) {
+ TransformProcessType(&psn, kProcessTransformToForegroundApplication);
+ }
+ }
+ }
+
+ char **argv = priv->argv;
+
+ // Get command line params
+ if (int argc = priv->argc) {
+ int i, j = 1;
+ QString passed_psn;
+ for(i=1; i < argc; i++) {
+ if (argv[i] && *argv[i] != '-') {
+ argv[j++] = argv[i];
+ continue;
+ }
+ QByteArray arg(argv[i]);
+#if defined(QT_DEBUG)
+ if (arg == "-nograb")
+ appNoGrab = !appNoGrab;
+ else
+#endif // QT_DEBUG
+ if (arg.left(5) == "-psn_") {
+ passed_psn = QString::fromLatin1(arg.mid(6));
+ } else {
+ argv[j++] = argv[i];
+ }
+ }
+ if (j < priv->argc) {
+ priv->argv[j] = 0;
+ priv->argc = j;
+ }
+
+ //special hack to change working directory (for an app bundle) when running from finder
+ if (!passed_psn.isNull() && QDir::currentPath() == QLatin1String("/")) {
+ QCFType<CFURLRef> bundleURL(CFBundleCopyBundleURL(CFBundleGetMainBundle()));
+ QString qbundlePath = QCFString(CFURLCopyFileSystemPath(bundleURL,
+ kCFURLPOSIXPathStyle));
+ if (qbundlePath.endsWith(QLatin1String(".app")))
+ QDir::setCurrent(qbundlePath.section(QLatin1Char('/'), 0, -2));
+ }
+ }
+
+ QMacPasteboardMime::initialize();
+
+ qApp->setObjectName(priv->appName());
+ if (qt_is_gui_used) {
+ QColormap::initialize();
+ QFont::initialize();
+ QCursorData::initialize();
+ QCoreGraphicsPaintEngine::initialize();
+#ifndef QT_NO_ACCESSIBILITY
+ QAccessible::initialize();
+#endif
+ QMacInputContext::initialize();
+ QApplicationPrivate::inputContext = new QMacInputContext;
+
+ if (QApplication::desktopSettingsAware())
+ qt_mac_update_os_settings();
+#ifndef QT_MAC_USE_COCOA
+ if (!app_proc_handler) {
+ app_proc_handlerUPP = NewEventHandlerUPP(QApplicationPrivate::globalEventProcessor);
+ qt_init_app_proc_handler();
+ }
+
+#endif
+ if (!app_proc_ae_handlerUPP && !QApplication::testAttribute(Qt::AA_MacPluginApplication)) {
+ app_proc_ae_handlerUPP = AEEventHandlerUPP(QApplicationPrivate::globalAppleEventProcessor);
+ for(uint i = 0; i < sizeof(app_apple_events) / sizeof(QMacAppleEventTypeSpec); ++i) {
+ // Install apple event handler, but avoid overwriting an already
+ // existing handler (it means a 3rd party application has installed one):
+ SRefCon refCon = 0;
+ AEEventHandlerUPP current_handler = NULL;
+ AEGetEventHandler(app_apple_events[i].mac_class, app_apple_events[i].mac_id, &current_handler, &refCon, false);
+ if (!current_handler)
+ AEInstallEventHandler(app_apple_events[i].mac_class, app_apple_events[i].mac_id,
+ app_proc_ae_handlerUPP, SRefCon(qApp), false);
+ }
+ }
+
+ if (QApplicationPrivate::app_style) {
+ QEvent ev(QEvent::Style);
+ qt_sendSpontaneousEvent(QApplicationPrivate::app_style, &ev);
+ }
+ }
+ if (QApplication::desktopSettingsAware())
+ QApplicationPrivate::qt_mac_apply_settings();
+
+ // Cocoa application delegate
+#ifdef QT_MAC_USE_COCOA
+ NSApplication *cocoaApp = [QNSApplication sharedApplication];
+ qt_redirectNSApplicationSendEvent();
+
+ QMacCocoaAutoReleasePool pool;
+ id oldDelegate = [cocoaApp delegate];
+ QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) *newDelegate = [QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) sharedDelegate];
+ Q_ASSERT(newDelegate);
+ [newDelegate setQtPrivate:priv];
+ // Only do things that make sense to do once, otherwise we crash.
+ if (oldDelegate != newDelegate && !QApplication::testAttribute(Qt::AA_MacPluginApplication)) {
+ [newDelegate setReflectionDelegate:oldDelegate];
+ [cocoaApp setDelegate:newDelegate];
+
+ QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *qtMenuLoader = [[QT_MANGLE_NAMESPACE(QCocoaMenuLoader) alloc] init];
+ if ([NSBundle loadNibNamed:@"qt_menu" owner:qtMenuLoader] == false) {
+ qFatal("Qt internal error: qt_menu.nib could not be loaded. The .nib file"
+ " should be placed in QtGui.framework/Versions/Current/Resources/ "
+ " or in the resources directory of your application bundle.");
+ }
+
+ [cocoaApp setMenu:[qtMenuLoader menu]];
+ [newDelegate setMenuLoader:qtMenuLoader];
+ [qtMenuLoader release];
+ }
+#endif
+ // Register for Carbon tablet proximity events on the event monitor target.
+ // This means that we should receive proximity events even when we aren't the active application.
+ if (!tablet_proximity_handler) {
+ tablet_proximity_UPP = NewEventHandlerUPP(QApplicationPrivate::tabletProximityCallback);
+ qt_init_tablet_proximity_handler();
+ }
+ priv->native_modal_dialog_active = false;
+
+ qt_mac_read_fontsmoothing_settings();
+}
+
+void qt_release_apple_event_handler()
+{
+ if(app_proc_ae_handlerUPP) {
+ for(uint i = 0; i < sizeof(app_apple_events) / sizeof(QMacAppleEventTypeSpec); ++i)
+ AERemoveEventHandler(app_apple_events[i].mac_class, app_apple_events[i].mac_id,
+ app_proc_ae_handlerUPP, true);
+ DisposeAEEventHandlerUPP(app_proc_ae_handlerUPP);
+ app_proc_ae_handlerUPP = 0;
+ }
+}
+
+/*****************************************************************************
+ qt_cleanup() - cleans up when the application is finished
+ *****************************************************************************/
+
+void qt_cleanup()
+{
+ CGDisplayRemoveReconfigurationCallback(qt_mac_display_change_callbk, 0);
+ CFNotificationCenterRef center = CFNotificationCenterGetDistributedCenter();
+ CFNotificationCenterRemoveObserver(center, qApp, kCMDeviceUnregisteredNotification, 0);
+ CFNotificationCenterRemoveObserver(center, qApp, kCMDefaultDeviceNotification, 0);
+ CFNotificationCenterRemoveObserver(center, qApp, kCMDeviceProfilesNotification, 0);
+ CFNotificationCenterRemoveObserver(center, qApp, kCMDefaultDeviceProfileNotification, 0);
+
+#ifndef QT_MAC_USE_COCOA
+ qt_release_app_proc_handler();
+ if (app_proc_handlerUPP) {
+ DisposeEventHandlerUPP(app_proc_handlerUPP);
+ app_proc_handlerUPP = 0;
+ }
+#endif
+ qt_release_apple_event_handler();
+ qt_release_tablet_proximity_handler();
+ if (tablet_proximity_UPP)
+ DisposeEventHandlerUPP(tablet_proximity_UPP);
+
+ QPixmapCache::clear();
+ if (qt_is_gui_used) {
+#ifndef QT_NO_ACCESSIBILITY
+ QAccessible::cleanup();
+#endif
+ QMacInputContext::cleanup();
+ QCursorData::cleanup();
+ QFont::cleanup();
+ QColormap::cleanup();
+ if (qt_mac_safe_pdev) {
+ delete qt_mac_safe_pdev;
+ qt_mac_safe_pdev = 0;
+ }
+ extern void qt_mac_unregister_widget(); // qapplication_mac.cpp
+ qt_mac_unregister_widget();
+ }
+}
+
+/*****************************************************************************
+ Platform specific global and internal functions
+ *****************************************************************************/
+void qt_updated_rootinfo()
+{
+}
+
+bool qt_wstate_iconified(WId)
+{
+ return false;
+}
+
+/*****************************************************************************
+ Platform specific QApplication members
+ *****************************************************************************/
+extern QWidget * mac_mouse_grabber;
+extern QWidget * mac_keyboard_grabber;
+
+#ifdef QT3_SUPPORT
+void QApplication::setMainWidget(QWidget *mainWidget)
+{
+ QApplicationPrivate::main_widget = mainWidget;
+ if (QApplicationPrivate::main_widget && windowIcon().isNull()
+ && QApplicationPrivate::main_widget->testAttribute(Qt::WA_SetWindowIcon))
+ setWindowIcon(QApplicationPrivate::main_widget->windowIcon());
+}
+#endif
+#ifndef QT_NO_CURSOR
+
+/*****************************************************************************
+ QApplication cursor stack
+ *****************************************************************************/
+
+void QApplication::setOverrideCursor(const QCursor &cursor)
+{
+ qApp->d_func()->cursor_list.prepend(cursor);
+
+#ifdef QT_MAC_USE_COCOA
+ qt_mac_update_cursor();
+#else
+ if (qApp && qApp->activeWindow())
+ qt_mac_set_cursor(&qApp->d_func()->cursor_list.first());
+#endif
+}
+
+void QApplication::restoreOverrideCursor()
+{
+ if (qApp->d_func()->cursor_list.isEmpty())
+ return;
+ qApp->d_func()->cursor_list.removeFirst();
+
+#ifdef QT_MAC_USE_COCOA
+ qt_mac_update_cursor();
+#else
+ if (qApp && qApp->activeWindow()) {
+ const QCursor def(Qt::ArrowCursor);
+ qt_mac_set_cursor(qApp->d_func()->cursor_list.isEmpty() ? &def : &qApp->d_func()->cursor_list.first());
+ }
+#endif
+}
+#endif // QT_NO_CURSOR
+
+QWidget *QApplication::topLevelAt(const QPoint &p)
+{
+#ifndef QT_MAC_USE_COCOA
+ QWidget *widget;
+ qt_mac_window_at(p.x(), p.y(), &widget);
+ return widget;
+#else
+ // Use a cache to avoid iterate through the whole list of windows for all
+ // calls to to topLevelAt. We e.g. do this for each and every mouse
+ // move since we need to find the widget under mouse:
+ if (topLevelAt_cache && topLevelAt_cache->frameGeometry().contains(p))
+ return topLevelAt_cache;
+
+ // INVARIANT: Cache miss. Go through the list if windows instead:
+ QMacCocoaAutoReleasePool pool;
+ NSPoint cocoaPoint = flipPoint(p);
+ NSInteger windowCount;
+ NSCountWindows(&windowCount);
+ if (windowCount <= 0)
+ return 0; // There's no window to find!
+
+ QVarLengthArray<NSInteger> windowList(windowCount);
+ NSWindowList(windowCount, windowList.data());
+ int firstQtWindowFound = -1;
+ for (int i = 0; i < windowCount; ++i) {
+ NSWindow *window = [NSApp windowWithWindowNumber:windowList[i]];
+ if (window) {
+ QWidget *candidateWindow = [window QT_MANGLE_NAMESPACE(qt_qwidget)];
+ if (candidateWindow && firstQtWindowFound == -1)
+ firstQtWindowFound = i;
+
+ if (NSPointInRect(cocoaPoint, [window frame])) {
+ // Check to see if there's a hole in the window where the mask is.
+ // If there is, we should just continue to see if there is a window below.
+ if (candidateWindow && !candidateWindow->mask().isEmpty()) {
+ QPoint localPoint = candidateWindow->mapFromGlobal(p);
+ if (!candidateWindow->mask().contains(localPoint))
+ continue;
+ else
+ return candidateWindow;
+ } else {
+ if (i == firstQtWindowFound) {
+ // The cache will only work when the window under mouse is
+ // top most (that is, not partially obscured by other windows.
+ // And we only set it if no mask is present to optimize for the common case:
+ topLevelAt_cache = candidateWindow;
+ }
+ return candidateWindow;
+ }
+ }
+ }
+ }
+
+ topLevelAt_cache = 0;
+ return 0;
+#endif
+}
+
+/*****************************************************************************
+ Main event loop
+ *****************************************************************************/
+
+bool QApplicationPrivate::modalState()
+{
+ return app_do_modal;
+}
+
+#ifdef QT_MAC_USE_COCOA
+#endif
+
+void QApplicationPrivate::enterModal_sys(QWidget *widget)
+{
+#ifdef DEBUG_MODAL_EVENTS
+ Q_ASSERT(widget);
+ qDebug("Entering modal state with %s::%s::%p (%d)", widget->metaObject()->className(), widget->objectName().toLocal8Bit().constData(),
+ widget, qt_modal_stack ? (int)qt_modal_stack->count() : -1);
+#endif
+ if (!qt_modal_stack)
+ qt_modal_stack = new QWidgetList;
+
+ dispatchEnterLeave(0, qt_last_mouse_receiver);
+ qt_last_mouse_receiver = 0;
+
+ qt_modal_stack->insert(0, widget);
+ if (!app_do_modal)
+ qt_event_request_menubarupdate();
+ app_do_modal = true;
+ qt_button_down = 0;
+
+#ifdef QT_MAC_USE_COCOA
+ if (!qt_mac_is_macsheet(widget))
+ QEventDispatcherMacPrivate::beginModalSession(widget);
+#endif
+}
+
+void QApplicationPrivate::leaveModal_sys(QWidget *widget)
+{
+ if (qt_modal_stack && qt_modal_stack->removeAll(widget)) {
+#ifdef DEBUG_MODAL_EVENTS
+ qDebug("Leaving modal state with %s::%s::%p (%d)", widget->metaObject()->className(), widget->objectName().toLocal8Bit().constData(),
+ widget, qt_modal_stack->count());
+#endif
+ if (qt_modal_stack->isEmpty()) {
+ delete qt_modal_stack;
+ qt_modal_stack = 0;
+ QPoint p(QCursor::pos());
+ app_do_modal = false;
+ QWidget* w = 0;
+ if (QWidget *grabber = QWidget::mouseGrabber())
+ w = grabber;
+ else
+ w = QApplication::widgetAt(p.x(), p.y());
+ dispatchEnterLeave(w, qt_last_mouse_receiver); // send synthetic enter event
+ qt_last_mouse_receiver = w;
+ }
+#ifdef QT_MAC_USE_COCOA
+ if (!qt_mac_is_macsheet(widget))
+ QEventDispatcherMacPrivate::endModalSession(widget);
+#endif
+ }
+#ifdef DEBUG_MODAL_EVENTS
+ else qDebug("Failure to remove %s::%s::%p -- %p", widget->metaObject()->className(), widget->objectName().toLocal8Bit().constData(), widget, qt_modal_stack);
+#endif
+ app_do_modal = (qt_modal_stack != 0);
+ if (!app_do_modal)
+ qt_event_request_menubarupdate();
+}
+
+QWidget *QApplicationPrivate::tryModalHelper_sys(QWidget *top)
+{
+#ifndef QT_MAC_USE_COCOA
+ if(top && qt_mac_is_macsheet(top) && !IsWindowVisible(qt_mac_window_for(top))) {
+ if(OSWindowRef wp = GetFrontWindowOfClass(kSheetWindowClass, true)) {
+ if(QWidget *sheet = qt_mac_find_window(wp))
+ top = sheet;
+ }
+ }
+#endif
+ return top;
+}
+
+#ifndef QT_MAC_USE_COCOA
+static bool qt_try_modal(QWidget *widget, EventRef event)
+{
+ QWidget * top = 0;
+
+ if (QApplicationPrivate::tryModalHelper(widget, &top))
+ return true;
+
+ // INVARIANT: widget is modally shaddowed within its
+ // window, and should therefore not handle the event.
+ // However, if the window is not active, the event
+ // might suggest that we should bring it to front:
+
+ bool block_event = false;
+
+ if (event) {
+ switch (GetEventClass(event)) {
+ case kEventClassMouse:
+ case kEventClassKeyboard:
+ block_event = true;
+ break;
+ }
+ }
+
+ QWidget *activeWidget = QApplication::activeWindow();
+ if ((!activeWidget || QApplicationPrivate::isBlockedByModal(activeWidget)) &&
+ top->isWindow() && block_event && !QApplicationPrivate::native_modal_dialog_active)
+ top->raise();
+
+#ifdef DEBUG_MODAL_EVENTS
+ qDebug("%s:%d -- final decision! (%s)", __FILE__, __LINE__, block_event ? "false" : "true");
+#endif
+ return !block_event;
+}
+#endif
+
+OSStatus QApplicationPrivate::tabletProximityCallback(EventHandlerCallRef, EventRef carbonEvent,
+ void *)
+{
+ OSType eventClass = GetEventClass(carbonEvent);
+ UInt32 eventKind = GetEventKind(carbonEvent);
+ if (eventClass != kEventClassTablet || eventKind != kEventTabletProximity)
+ return eventNotHandledErr;
+
+ // Get the current point of the device and its unique ID.
+ ::TabletProximityRec proxRec;
+ GetEventParameter(carbonEvent, kEventParamTabletProximityRec, typeTabletProximityRec, 0,
+ sizeof(proxRec), 0, &proxRec);
+ qt_dispatchTabletProximityEvent(proxRec);
+ return noErr;
+}
+
+OSStatus
+QApplicationPrivate::globalEventProcessor(EventHandlerCallRef er, EventRef event, void *data)
+{
+#ifndef QT_MAC_USE_COCOA
+ QApplication *app = (QApplication *)data;
+ QScopedLoopLevelCounter loopLevelCounter(app->d_func()->threadData);
+ long result;
+ if (app->filterEvent(&event, &result))
+ return result;
+ if(app->macEventFilter(er, event)) //someone else ate it
+ return noErr;
+ QPointer<QWidget> widget;
+
+ /*We assume all events are handled and in
+ the code below we set it to false when we know we didn't handle it, this
+ will let rogue events through (shouldn't really happen, but better safe
+ than sorry) */
+ bool handled_event=true;
+ UInt32 ekind = GetEventKind(event), eclass = GetEventClass(event);
+ switch(eclass)
+ {
+ case kEventClassQt:
+ if(ekind == kEventQtRequestShowSheet) {
+ request_showsheet_pending = 0;
+ QWidget *widget = 0;
+ GetEventParameter(event, kEventParamQWidget, typeQWidget, 0,
+ sizeof(widget), 0, &widget);
+ if(widget) {
+ if (widget->macEvent(er, event))
+ return noErr;
+ WindowPtr window = qt_mac_window_for(widget);
+ bool just_show = !qt_mac_is_macsheet(widget);
+ if(!just_show) {
+ OSStatus err = ShowSheetWindow(window, qt_mac_window_for(widget->parentWidget()));
+ if(err != noErr)
+ qWarning("Qt: QWidget: Unable to show as sheet %s::%s [%ld]", widget->metaObject()->className(),
+ widget->objectName().toLocal8Bit().constData(), long(err));
+ just_show = true;
+ }
+ if(just_show) //at least the window will be visible, but the sheet flag doesn't work sadly (probalby too many sheets)
+ ShowHide(window, true);
+ }
+ } else if(ekind == kEventQtRequestWindowChange) {
+ qt_mac_event_release(request_window_change_pending);
+ } else if(ekind == kEventQtRequestMenubarUpdate) {
+ qt_mac_event_release(request_menubarupdate_pending);
+ QMenuBar::macUpdateMenuBar();
+ } else if(ekind == kEventQtRequestActivate) {
+ qt_mac_event_release(request_activate_pending.event);
+ if(request_activate_pending.widget) {
+ QWidget *tlw = request_activate_pending.widget->window();
+ if (tlw->macEvent(er, event))
+ return noErr;
+ request_activate_pending.widget = 0;
+ tlw->activateWindow();
+ SelectWindow(qt_mac_window_for(tlw));
+ }
+ } else if(ekind == kEventQtRequestContext) {
+ bool send = false;
+ if ((send = (event == request_context_pending)))
+ qt_mac_event_release(request_context_pending);
+ if(send) {
+ //figure out which widget to send it to
+ QPoint where = QCursor::pos();
+ QWidget *widget = 0;
+ GetEventParameter(event, kEventParamQWidget, typeQWidget, 0,
+ sizeof(widget), 0, &widget);
+ if(!widget) {
+ if(qt_button_down)
+ widget = qt_button_down;
+ else
+ widget = QApplication::widgetAt(where.x(), where.y());
+ }
+ if(widget && !isBlockedByModal(widget)) {
+ if (widget->macEvent(er, event))
+ return noErr;
+ QPoint plocal(widget->mapFromGlobal(where));
+ const Qt::KeyboardModifiers keyboardModifiers = qt_mac_get_modifiers(GetCurrentEventKeyModifiers());
+ QContextMenuEvent qme(QContextMenuEvent::Mouse, plocal, where, keyboardModifiers);
+ QApplication::sendEvent(widget, &qme);
+ if(qme.isAccepted()) { //once this happens the events before are pitched
+ qt_button_down = 0;
+ qt_mac_dblclick.last_widget = 0;
+ }
+ } else {
+ handled_event = false;
+ }
+ }
+ } else {
+ handled_event = false;
+ }
+ break;
+ case kEventClassTablet:
+ switch (ekind) {
+ case kEventTabletProximity:
+ // Get the current point of the device and its unique ID.
+ ::TabletProximityRec proxRec;
+ GetEventParameter(event, kEventParamTabletProximityRec, typeTabletProximityRec, 0,
+ sizeof(proxRec), 0, &proxRec);
+ qt_dispatchTabletProximityEvent(proxRec);
+ }
+ break;
+ case kEventClassMouse:
+ {
+ static const int kEventParamQAppSeenMouseEvent = 'QASM';
+ // Check if we've seen the event, if we have we shouldn't process
+ // it again as it may lead to spurious "double events"
+ bool seenEvent;
+ if (GetEventParameter(event, kEventParamQAppSeenMouseEvent,
+ typeBoolean, 0, sizeof(bool), 0, &seenEvent) == noErr) {
+ if (seenEvent)
+ return eventNotHandledErr;
+ }
+ seenEvent = true;
+ SetEventParameter(event, kEventParamQAppSeenMouseEvent, typeBoolean,
+ sizeof(bool), &seenEvent);
+
+ Point where;
+ bool inNonClientArea = false;
+ GetEventParameter(event, kEventParamMouseLocation, typeQDPoint, 0,
+ sizeof(where), 0, &where);
+#if defined(DEBUG_MOUSE_MAPS)
+ const char *edesc = 0;
+ switch(ekind) {
+ case kEventMouseDown: edesc = "MouseButtonPress"; break;
+ case kEventMouseUp: edesc = "MouseButtonRelease"; break;
+ case kEventMouseDragged: case kEventMouseMoved: edesc = "MouseMove"; break;
+ case kEventMouseScroll: edesc = "MouseWheelScroll"; break;
+ case kEventMouseWheelMoved: edesc = "MouseWheelMove"; break;
+ }
+ if(ekind == kEventMouseDown || ekind == kEventMouseUp)
+ qDebug("Handling mouse: %s", edesc);
+#endif
+ QEvent::Type etype = QEvent::None;
+ Qt::KeyboardModifiers modifiers;
+ {
+ UInt32 mac_modifiers = 0;
+ GetEventParameter(event, kEventParamKeyModifiers, typeUInt32, 0,
+ sizeof(mac_modifiers), 0, &mac_modifiers);
+ modifiers = qt_mac_get_modifiers(mac_modifiers);
+ }
+ Qt::MouseButtons buttons;
+ {
+ UInt32 mac_buttons = 0;
+ GetEventParameter(event, kEventParamMouseChord, typeUInt32, 0,
+ sizeof(mac_buttons), 0, &mac_buttons);
+ if (ekind != kEventMouseWheelMoved)
+ buttons = qt_mac_get_buttons(mac_buttons);
+ else
+ buttons = QApplication::mouseButtons();
+ }
+
+ int wheel_deltaX = 0;
+ int wheel_deltaY = 0;
+ static EventRef compatibilityEvent = 0;
+
+ if (ekind == kEventMouseScroll) {
+ // kEventMouseScroll is the new way of dealing with mouse wheel
+ // events (kEventMouseWheelMoved was the old). kEventMouseScroll results
+ // in much smoother scrolling when using Mighty Mouse or TrackPad. For
+ // compatibility with older applications, carbon will also send us
+ // kEventMouseWheelMoved events if we dont eat this event
+ // (actually two events; one for horizontal and one for vertical).
+ // As a results of this, and to make sure we dont't receive duplicate events,
+ // we try to detect when this happend by checking the 'compatibilityEvent'.
+ // Since delta is delivered as pixels rather than degrees, we need to
+ // convert from pixels to degrees in a sensible manner.
+ // It looks like 1/4 degrees per pixel behaves most native.
+ // (NB: Qt expects the unit for delta to be 8 per degree):
+ const int pixelsToDegrees = 2;
+ SInt32 mdelt = 0;
+ GetEventParameter(event, kEventParamMouseWheelSmoothHorizontalDelta, typeSInt32, 0,
+ sizeof(mdelt), 0, &mdelt);
+ wheel_deltaX = mdelt * pixelsToDegrees;
+ mdelt = 0;
+ GetEventParameter(event, kEventParamMouseWheelSmoothVerticalDelta, typeSInt32, 0,
+ sizeof(mdelt), 0, &mdelt);
+ wheel_deltaY = mdelt * pixelsToDegrees;
+ GetEventParameter(event, kEventParamEventRef, typeEventRef, 0,
+ sizeof(compatibilityEvent), 0, &compatibilityEvent);
+ } else if (ekind == kEventMouseWheelMoved) {
+ if (event != compatibilityEvent) {
+ compatibilityEvent = 0;
+ int mdelt = 0;
+ GetEventParameter(event, kEventParamMouseWheelDelta, typeSInt32, 0,
+ sizeof(mdelt), 0, &mdelt);
+ EventMouseWheelAxis axis;
+ GetEventParameter(event, kEventParamMouseWheelAxis, typeMouseWheelAxis, 0,
+ sizeof(axis), 0, &axis);
+
+ // Remove acceleration, and use either -120 or 120 as delta:
+ if (axis == kEventMouseWheelAxisX)
+ wheel_deltaX = qBound(-120, int(mdelt * 10000), 120);
+ else
+ wheel_deltaY = qBound(-120, int(mdelt * 10000), 120);
+ }
+ }
+
+ Qt::MouseButton button = Qt::NoButton;
+ if(ekind == kEventMouseDown || ekind == kEventMouseUp) {
+ EventMouseButton mac_button = 0;
+ GetEventParameter(event, kEventParamMouseButton, typeMouseButton, 0,
+ sizeof(mac_button), 0, &mac_button);
+ button = qt_mac_get_button(mac_button);
+ }
+
+ switch(ekind) {
+ case kEventMouseDown:
+ etype = QEvent::MouseButtonPress;
+ break;
+ case kEventMouseUp:
+ etype = QEvent::MouseButtonRelease;
+ break;
+ case kEventMouseDragged:
+ case kEventMouseMoved:
+ etype = QEvent::MouseMove;
+ break;
+ }
+
+ const bool inPopupMode = app->d_func()->inPopupMode();
+
+ // A click outside a popup closes the popup. Make sure
+ // that no events are generated for the release part of that click.
+ // (The press goes to the popup and closes it.)
+ if (etype == QEvent::MouseButtonPress) {
+ qt_mac_previous_press_in_popup_mode = inPopupMode;
+ } else if (qt_mac_previous_press_in_popup_mode && !inPopupMode && etype == QEvent::MouseButtonRelease) {
+ qt_mac_previous_press_in_popup_mode = false;
+ handled_event = true;
+#if defined(DEBUG_MOUSE_MAPS)
+ qDebug("Bail out early due to qt_mac_previous_press_in_popup_mode");
+#endif
+ break; // break from case kEventClassMouse
+ }
+
+ //figure out which widget to send it to
+ if(inPopupMode) {
+ QWidget *popup = qApp->activePopupWidget();
+ if (qt_button_down && qt_button_down->window() == popup) {
+ widget = qt_button_down;
+ } else {
+ QPoint pos = popup->mapFromGlobal(QPoint(where.h, where.v));
+ widget = popup->childAt(pos);
+ }
+ if(!widget)
+ widget = popup;
+ } else {
+ if(mac_mouse_grabber) {
+ widget = mac_mouse_grabber;
+ } else if (qt_button_down) {
+ widget = qt_button_down;
+ } else {
+ {
+ WindowPtr window = 0;
+ if(GetEventParameter(event, kEventParamWindowRef, typeWindowRef, 0,
+ sizeof(window), 0, &window) != noErr)
+ FindWindowOfClass(&where, kAllWindowClasses, &window, 0);
+ if(window) {
+ HIViewRef hiview;
+ if(HIViewGetViewForMouseEvent(HIViewGetRoot(window), event, &hiview) == noErr) {
+ widget = QWidget::find((WId)hiview);
+ if (widget) {
+ // Make sure we didn't pass over a widget with a "fake hole" in it.
+ QWidget *otherWidget = QApplication::widgetAt(where.h, where.v);
+ if (otherWidget && otherWidget->testAttribute(Qt::WA_MouseNoMask))
+ widget = otherWidget;
+ }
+ }
+ }
+ }
+ if(!widget) //fallback
+ widget = QApplication::widgetAt(where.h, where.v);
+ if(ekind == kEventMouseUp && widget) {
+ short part = qt_mac_window_at(where.h, where.v);
+ if(part == inDrag) {
+ UInt32 count = 0;
+ GetEventParameter(event, kEventParamClickCount, typeUInt32, NULL,
+ sizeof(count), NULL, &count);
+ if(count == 2 && qt_mac_collapse_on_dblclick) {
+ if (widget->macEvent(er, event))
+ return noErr;
+ widget->setWindowState(widget->windowState() | Qt::WindowMinimized);
+ //we send a hide to be like X11/Windows
+ QEvent e(QEvent::Hide);
+ QApplication::sendSpontaneousEvent(widget, &e);
+ break;
+ }
+ }
+ }
+ }
+ }
+ if (widget && widget->macEvent(er, event))
+ return noErr;
+ WindowPartCode wpc = qt_mac_window_at(where.h, where.v, 0);
+ if (wpc == inProxyIcon && modifiers == Qt::ControlModifier && buttons != Qt::NoButton) {
+ QIconDragEvent e;
+ QApplication::sendSpontaneousEvent(widget, &e);
+ if (e.isAccepted()) {
+ return noErr; // IconDrag ate it.
+ }
+ }
+ if (inPopupMode == false
+ && (qt_button_down == 0 || qt_button_down_in_content == false)
+ && (wpc != inContent && wpc != inStructure)) {
+ inNonClientArea = true;
+ switch (etype) {
+ case QEvent::MouseButtonPress: {
+ UInt32 count = 0;
+ GetEventParameter(event, kEventParamClickCount, typeUInt32, 0,
+ sizeof(count), 0, &count);
+ if(count % 2 || count == 0) {
+ etype = QEvent::NonClientAreaMouseButtonPress;
+ } else {
+ etype = QEvent::NonClientAreaMouseButtonDblClick;
+ }} break;
+ case QEvent::MouseButtonRelease:
+ etype = QEvent::NonClientAreaMouseButtonRelease;
+ break;
+ case QEvent::MouseMove:
+ if (widget == 0 || widget->hasMouseTracking())
+ etype = QEvent::NonClientAreaMouseMove;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if(qt_mac_find_window((FrontWindow()))) { //set the cursor up
+ QCursor cursor(Qt::ArrowCursor);
+ QWidget *cursor_widget = widget;
+ if(cursor_widget && cursor_widget == qt_button_down && ekind == kEventMouseUp)
+ cursor_widget = QApplication::widgetAt(where.h, where.v);
+ if(cursor_widget) { //only over the app, do we set a cursor..
+ if(!qApp->d_func()->cursor_list.isEmpty()) {
+ cursor = qApp->d_func()->cursor_list.first();
+ } else {
+ for(; cursor_widget; cursor_widget = cursor_widget->parentWidget()) {
+ QWExtra *extra = cursor_widget->d_func()->extraData();
+ if(extra && extra->curs && cursor_widget->isEnabled()) {
+ cursor = *extra->curs;
+ break;
+ }
+ }
+ }
+ }
+ qt_mac_set_cursor(&cursor);
+ }
+
+ //This mouse button state stuff looks like this on purpose
+ //although it looks hacky it is VERY intentional..
+ if(widget && app_do_modal && !qt_try_modal(widget, event)) {
+ if(ekind == kEventMouseDown && qt_mac_is_macsheet(QApplication::activeModalWidget()))
+ QApplication::activeModalWidget()->parentWidget()->activateWindow(); //sheets have a parent
+ handled_event = false;
+#if defined(DEBUG_MOUSE_MAPS)
+ qDebug("Bail out early due to qt_try_modal");
+#endif
+ break;
+ }
+
+ UInt32 tabletEventType = 0;
+ GetEventParameter(event, kEventParamTabletEventType, typeUInt32, 0,
+ sizeof(tabletEventType), 0, &tabletEventType);
+ if (tabletEventType == kEventTabletPoint) {
+ TabletPointRec tabletPointRec;
+ GetEventParameter(event, kEventParamTabletPointRec, typeTabletPointRec, 0,
+ sizeof(tabletPointRec), 0, &tabletPointRec);
+ QEvent::Type t = QEvent::TabletMove; //default
+ int new_tablet_button_state = tabletPointRec.buttons ? 1 : 0;
+ if (new_tablet_button_state != tablet_button_state)
+ if (new_tablet_button_state)
+ t = QEvent::TabletPress;
+ else
+ t = QEvent::TabletRelease;
+ tablet_button_state = new_tablet_button_state;
+
+ QMacTabletHash *tabletHash = qt_mac_tablet_hash();
+ if (!tabletHash->contains(tabletPointRec.deviceID) && t != QEvent::TabletRelease) {
+ // Never discard TabletRelease events as they may be delivered *after* TabletLeaveProximity events
+ qWarning("handleTabletEvent: This tablet device is unknown"
+ " (received no proximity event for it). Discarding event.");
+ return false;
+ }
+ QTabletDeviceData &deviceData = tabletHash->operator[](tabletPointRec.deviceID);
+ if (t == QEvent::TabletPress) {
+ deviceData.widgetToGetPress = widget;
+ } else if (t == QEvent::TabletRelease && deviceData.widgetToGetPress) {
+ widget = deviceData.widgetToGetPress;
+ deviceData.widgetToGetPress = 0;
+ }
+
+ if (widget) {
+ int tiltX = ((int)tabletPointRec.tiltX)/(32767/64); // 32K -> 60
+ int tiltY = ((int)tabletPointRec.tiltY)/(-32767/64); // 32K -> 60
+ HIPoint hiPoint;
+ GetEventParameter(event, kEventParamMouseLocation, typeHIPoint, 0, sizeof(HIPoint), 0, &hiPoint);
+ QPointF hiRes(hiPoint.x, hiPoint.y);
+ QPoint global(where.h, where.v);
+
+
+
+ QPoint local(widget->mapFromGlobal(global));
+ int z = 0;
+ qreal rotation = 0.0;
+ qreal tp = 0.0;
+ // Again from the Wacom.h header
+
+ if (deviceData.capabilityMask & 0x0200) // Z-axis
+ z = tabletPointRec.absZ;
+
+ if (deviceData.capabilityMask & 0x0800) // Tangential pressure
+ tp = tabletPointRec.tangentialPressure / 32767.0;
+
+ if (deviceData.capabilityMask & 0x2000) // Rotation
+ rotation = qreal(tabletPointRec.rotation) / 64.0;
+
+ QTabletEvent e(t, local, global, hiRes, deviceData.tabletDeviceType,
+ deviceData.tabletPointerType,
+ qreal(tabletPointRec.pressure / qreal(0xffff)), tiltX, tiltY,
+ tp, rotation, z, modifiers, deviceData.tabletUniqueID);
+ QApplication::sendSpontaneousEvent(widget, &e);
+ if (e.isAccepted()) {
+ if (t == QEvent::TabletPress) {
+ qt_button_down = widget;
+ } else if (t == QEvent::TabletRelease) {
+ qt_button_down = 0;
+ }
+#if defined(DEBUG_MOUSE_MAPS)
+ qDebug("Bail out early due to tablet acceptance");
+#endif
+ break;
+ }
+ }
+ }
+
+ if(ekind == kEventMouseDown) {
+ qt_mac_no_click_through_mode = false;
+ const short windowPart = qt_mac_window_at(where.h, where.v, 0);
+ // Menubar almost always wins.
+ if (!inPopupMode && windowPart == inMenuBar) {
+ MenuSelect(where); //allow menu tracking
+ return noErr;
+ }
+
+ if (widget && !(GetCurrentKeyModifiers() & cmdKey)) {
+ extern bool qt_isGenuineQWidget(const QWidget *); // qwidget_mac.cpp
+ QWidget *window = widget->window();
+ bool genuineQtWidget = qt_isGenuineQWidget(widget); // the widget, not the window.
+ window->raise();
+
+ bool needActivate = (window->windowType() != Qt::Desktop)
+ && (window->windowType() != Qt::Popup)
+ && !qt_mac_is_macsheet(window);
+ if (needActivate && (!window->isModal() && qobject_cast<QDockWidget *>(window)))
+ needActivate = false;
+
+ if (genuineQtWidget && needActivate)
+ needActivate = !window->isActiveWindow()
+ || !IsWindowActive(qt_mac_window_for(window));
+
+ if (needActivate) {
+ window->activateWindow();
+ if (!qt_mac_can_clickThrough(widget)) {
+ qt_mac_no_click_through_mode = true;
+ handled_event = false;
+#if defined(DEBUG_MOUSE_MAPS)
+ qDebug("Bail out early due to qt_mac_canClickThrough %s::%s", widget->metaObject()->className(),
+ widget->objectName().toLocal8Bit().constData());
+#endif
+ break;
+ }
+ }
+ }
+
+ if(qt_mac_dblclick.last_widget &&
+ qt_mac_dblclick.last_x != -1 && qt_mac_dblclick.last_y != -1 &&
+ QRect(qt_mac_dblclick.last_x-2, qt_mac_dblclick.last_y-2, 4, 4).contains(QPoint(where.h, where.v))) {
+ if(qt_mac_dblclick.use_qt_time_limit) {
+ EventTime now = GetEventTime(event);
+ if(qt_mac_dblclick.last_time != -2 && qt_mac_dblclick.last_widget == widget &&
+ now - qt_mac_dblclick.last_time <= ((double)QApplicationPrivate::mouse_double_click_time)/1000 &&
+ qt_mac_dblclick.last_button == button)
+ etype = QEvent::MouseButtonDblClick;
+ } else {
+ UInt32 count = 0;
+ GetEventParameter(event, kEventParamClickCount, typeUInt32, 0,
+ sizeof(count), 0, &count);
+ if(!(count % 2) && qt_mac_dblclick.last_modifiers == modifiers &&
+ qt_mac_dblclick.last_widget == widget && qt_mac_dblclick.last_button == button)
+ etype = QEvent::MouseButtonDblClick;
+ }
+ if(etype == QEvent::MouseButtonDblClick)
+ qt_mac_dblclick.last_widget = 0;
+ }
+ if(etype != QEvent::MouseButtonDblClick) {
+ qt_mac_dblclick.last_x = where.h;
+ qt_mac_dblclick.last_y = where.v;
+ } else {
+ qt_mac_dblclick.last_x = qt_mac_dblclick.last_y = -1;
+ }
+ } else if(qt_mac_no_click_through_mode) {
+ if(ekind == kEventMouseUp)
+ qt_mac_no_click_through_mode = false;
+ handled_event = false;
+#if defined(DEBUG_MOUSE_MAPS)
+ qDebug("Bail out early due to qt_mac_no_click_through_mode");
+#endif
+ break;
+ }
+
+ QPointer<QWidget> leaveAfterRelease = 0;
+ switch(ekind) {
+ case kEventMouseUp:
+ if (!buttons) {
+ if (!inPopupMode && !QWidget::mouseGrabber())
+ leaveAfterRelease = qt_button_down;
+ qt_button_down = 0;
+ }
+ break;
+ case kEventMouseDown: {
+ if (!qt_button_down)
+ qt_button_down = widget;
+ WindowPartCode wpc = qt_mac_window_at(where.h, where.v, 0);
+ qt_button_down_in_content = (wpc == inContent || wpc == inStructure);
+ break; }
+ }
+
+ // Check if we should send enter/leave events:
+ switch(ekind) {
+ case kEventMouseDragged:
+ case kEventMouseMoved:
+ case kEventMouseUp:
+ case kEventMouseDown: {
+ // If we are in popup mode, widget will point to the current popup no matter
+ // where the mouse cursor is. In that case find out if the mouse cursor is
+ // really over the popup in order to send correct enter / leave envents.
+ QWidget * const enterLeaveWidget = (inPopupMode || ekind == kEventMouseUp) ?
+ QApplication::widgetAt(where.h, where.v) : static_cast<QWidget*>(widget);
+
+ if ((QWidget *) qt_last_mouse_receiver != enterLeaveWidget || inNonClientArea) {
+#ifdef DEBUG_MOUSE_MAPS
+ qDebug("Entering: %p - %s (%s), Leaving %s (%s)", (QWidget*)enterLeaveWidget,
+ enterLeaveWidget ? enterLeaveWidget->metaObject()->className() : "none",
+ enterLeaveWidget ? enterLeaveWidget->objectName().toLocal8Bit().constData() : "",
+ qt_last_mouse_receiver ? qt_last_mouse_receiver->metaObject()->className() : "none",
+ qt_last_mouse_receiver ? qt_last_mouse_receiver->objectName().toLocal8Bit().constData() : "");
+#endif
+
+ QWidget * const mouseGrabber = QWidget::mouseGrabber();
+
+ if (inPopupMode) {
+ QWidget *enter = enterLeaveWidget;
+ QWidget *leave = qt_last_mouse_receiver;
+ if (mouseGrabber) {
+ QWidget * const popupWidget = qApp->activePopupWidget();
+ if (leave == popupWidget)
+ enter = mouseGrabber;
+ if (enter == popupWidget)
+ leave = mouseGrabber;
+ if ((enter == mouseGrabber && leave == popupWidget)
+ || (leave == mouseGrabber && enter == popupWidget)) {
+ QApplicationPrivate::dispatchEnterLeave(enter, leave);
+ qt_last_mouse_receiver = enter;
+ }
+ } else {
+ QApplicationPrivate::dispatchEnterLeave(enter, leave);
+ qt_last_mouse_receiver = enter;
+ }
+ } else if ((!qt_button_down || !qt_last_mouse_receiver) && !mouseGrabber && !leaveAfterRelease) {
+ QApplicationPrivate::dispatchEnterLeave(enterLeaveWidget, qt_last_mouse_receiver);
+ qt_last_mouse_receiver = enterLeaveWidget;
+ }
+ }
+ break; }
+ }
+
+ if(widget) {
+ QPoint p(where.h, where.v);
+ QPoint plocal(widget->mapFromGlobal(p));
+ if(etype == QEvent::MouseButtonPress) {
+ qt_mac_dblclick.last_widget = widget;
+ qt_mac_dblclick.last_modifiers = modifiers;
+ qt_mac_dblclick.last_button = button;
+ qt_mac_dblclick.last_time = GetEventTime(event);
+ }
+
+ if (wheel_deltaX || wheel_deltaY) {
+#ifndef QT_NO_WHEELEVENT
+ if (wheel_deltaX) {
+ QWheelEvent qwe(plocal, p, wheel_deltaX, buttons, modifiers, Qt::Horizontal);
+ QApplication::sendSpontaneousEvent(widget, &qwe);
+ if (!qwe.isAccepted() && QApplicationPrivate::focus_widget && QApplicationPrivate::focus_widget != widget) {
+ QWheelEvent qwe2(QApplicationPrivate::focus_widget->mapFromGlobal(p), p,
+ wheel_deltaX, buttons, modifiers, Qt::Horizontal);
+ QApplication::sendSpontaneousEvent(QApplicationPrivate::focus_widget, &qwe2);
+ if (!qwe2.isAccepted())
+ handled_event = false;
+ }
+ }
+ if (wheel_deltaY) {
+ QWheelEvent qwe(plocal, p, wheel_deltaY, buttons, modifiers, Qt::Vertical);
+ QApplication::sendSpontaneousEvent(widget, &qwe);
+ if (!qwe.isAccepted() && QApplicationPrivate::focus_widget && QApplicationPrivate::focus_widget != widget) {
+ QWheelEvent qwe2(QApplicationPrivate::focus_widget->mapFromGlobal(p), p,
+ wheel_deltaY, buttons, modifiers, Qt::Vertical);
+ QApplication::sendSpontaneousEvent(QApplicationPrivate::focus_widget, &qwe2);
+ if (!qwe2.isAccepted())
+ handled_event = false;
+ }
+ }
+#endif // QT_NO_WHEELEVENT
+ } else {
+#ifdef QMAC_SPEAK_TO_ME
+ const int speak_keys = Qt::AltModifier | Qt::ShiftModifier;
+ if(etype == QMouseEvent::MouseButtonDblClick && ((modifiers & speak_keys) == speak_keys)) {
+ QVariant v = widget->property("displayText");
+ if(!v.isValid()) v = widget->property("text");
+ if(!v.isValid()) v = widget->property("windowTitle");
+ if(v.isValid()) {
+ QString s = v.toString();
+ s.replace(QRegExp(QString::fromLatin1("(\\&|\\<[^\\>]*\\>)")), QLatin1String(""));
+ SpeechChannel ch;
+ NewSpeechChannel(0, &ch);
+ SpeakText(ch, s.toLatin1().constData(), s.length());
+ DisposeSpeechChannel(ch);
+ }
+ }
+#endif
+ Qt::MouseButton buttonToSend = button;
+ static bool lastButtonTranslated = false;
+ if(ekind == kEventMouseDown &&
+ button == Qt::LeftButton && (modifiers & Qt::MetaModifier)) {
+ buttonToSend = Qt::RightButton;
+ lastButtonTranslated = true;
+ } else if(ekind == kEventMouseUp && lastButtonTranslated) {
+ buttonToSend = Qt::RightButton;
+ lastButtonTranslated = false;
+ }
+ QMouseEvent qme(etype, plocal, p, buttonToSend, buttons, modifiers);
+ QApplication::sendSpontaneousEvent(widget, &qme);
+ if(!qme.isAccepted() || inNonClientArea)
+ handled_event = false;
+ }
+
+ if (leaveAfterRelease) {
+ QWidget *enter = QApplication::widgetAt(where.h, where.v);
+ QApplicationPrivate::dispatchEnterLeave(enter, leaveAfterRelease);
+ qt_last_mouse_receiver = enter;
+ leaveAfterRelease = 0;
+ }
+
+ if(ekind == kEventMouseDown &&
+ ((button == Qt::RightButton) ||
+ (button == Qt::LeftButton && (modifiers & Qt::MetaModifier))))
+ qt_event_request_context();
+
+#ifdef DEBUG_MOUSE_MAPS
+ const char *event_desc = edesc;
+ if(etype == QEvent::MouseButtonDblClick)
+ event_desc = "Double Click";
+ else if(etype == QEvent::NonClientAreaMouseButtonPress)
+ event_desc = "NonClientMousePress";
+ else if(etype == QEvent::NonClientAreaMouseButtonRelease)
+ event_desc = "NonClientMouseRelease";
+ else if(etype == QEvent::NonClientAreaMouseMove)
+ event_desc = "NonClientMouseMove";
+ else if(etype == QEvent::NonClientAreaMouseButtonDblClick)
+ event_desc = "NonClientMouseDblClick";
+ qDebug("%d %d (%d %d) - Would send (%s) event to %p %s %s (%d 0x%08x 0x%08x %d)", p.x(), p.y(),
+ plocal.x(), plocal.y(), event_desc, (QWidget*)widget,
+ widget ? widget->objectName().toLocal8Bit().constData() : "*Unknown*",
+ widget ? widget->metaObject()->className() : "*Unknown*",
+ button, (int)buttons, (int)modifiers, wheel_deltaX);
+#endif
+ } else {
+ handled_event = false;
+ }
+ break;
+ }
+ case kEventClassTextInput:
+ case kEventClassKeyboard: {
+ EventRef key_event = event;
+ if(eclass == kEventClassTextInput) {
+ Q_ASSERT(ekind == kEventTextInputUnicodeForKeyEvent);
+ OSStatus err = GetEventParameter(event, kEventParamTextInputSendKeyboardEvent, typeEventRef, 0,
+ sizeof(key_event), 0, &key_event);
+ Q_ASSERT(err == noErr);
+ Q_UNUSED(err);
+ }
+ const UInt32 key_ekind = GetEventKind(key_event);
+ Q_ASSERT(GetEventClass(key_event) == kEventClassKeyboard);
+
+ if(key_ekind == kEventRawKeyDown)
+ qt_keymapper_private()->updateKeyMap(er, key_event, data);
+ if(mac_keyboard_grabber)
+ widget = mac_keyboard_grabber;
+ else if (app->activePopupWidget())
+ widget = (app->activePopupWidget()->focusWidget() ?
+ app->activePopupWidget()->focusWidget() : app->activePopupWidget());
+ else if(QApplication::focusWidget())
+ widget = QApplication::focusWidget();
+ else
+ widget = app->activeWindow();
+
+ if (widget) {
+ if (widget->macEvent(er, event))
+ return noErr;
+ } else {
+ // Darn, I need to update tho modifier state, even though
+ // Qt itself isn't getting them, otherwise the keyboard state get inconsistent.
+ if (key_ekind == kEventRawKeyModifiersChanged) {
+ UInt32 modifiers = 0;
+ GetEventParameter(key_event, kEventParamKeyModifiers, typeUInt32, 0,
+ sizeof(modifiers), 0, &modifiers);
+ extern void qt_mac_send_modifiers_changed(quint32 modifiers, QObject *object); // qkeymapper_mac.cpp
+ // Just send it to the qApp for the time being.
+ qt_mac_send_modifiers_changed(modifiers, qApp);
+ }
+ handled_event = false;
+ break;
+ }
+
+ if(app_do_modal && !qt_try_modal(widget, key_event))
+ break;
+ if (eclass == kEventClassTextInput) {
+ handled_event = false;
+ } else {
+ handled_event = qt_keymapper_private()->translateKeyEvent(widget, er, key_event, data,
+ widget == mac_keyboard_grabber);
+ }
+ break; }
+ case kEventClassWindow: {
+ WindowRef wid = 0;
+ GetEventParameter(event, kEventParamDirectObject, typeWindowRef, 0,
+ sizeof(WindowRef), 0, &wid);
+ widget = qt_mac_find_window(wid);
+ if (widget && widget->macEvent(er, event))
+ return noErr;
+ if(ekind == kEventWindowActivated) {
+ if(QApplicationPrivate::app_style) {
+ QEvent ev(QEvent::Style);
+ QApplication::sendSpontaneousEvent(QApplicationPrivate::app_style, &ev);
+ }
+
+ if(widget && app_do_modal && !qt_try_modal(widget, event))
+ break;
+
+ if(widget && widget->window()->isVisible()) {
+ QWidget *tlw = widget->window();
+ if(tlw->isWindow() && !(tlw->windowType() == Qt::Popup)
+ && !qt_mac_is_macdrawer(tlw)
+ && (!tlw->parentWidget() || tlw->isModal()
+ || !(tlw->windowType() == Qt::Tool))) {
+ bool just_send_event = false;
+ {
+ WindowActivationScope scope;
+ if(GetWindowActivationScope((WindowRef)wid, &scope) == noErr &&
+ scope == kWindowActivationScopeIndependent) {
+ if(GetFrontWindowOfClass(kAllWindowClasses, true) != wid)
+ just_send_event = true;
+ }
+ }
+ if(just_send_event) {
+ QEvent e(QEvent::WindowActivate);
+ QApplication::sendSpontaneousEvent(widget, &e);
+ } else {
+ app->setActiveWindow(tlw);
+ }
+ }
+ QMenuBar::macUpdateMenuBar();
+ }
+ } else if(ekind == kEventWindowDeactivated) {
+ if(widget && QApplicationPrivate::active_window == widget)
+ app->setActiveWindow(0);
+ } else {
+ handled_event = false;
+ }
+ break; }
+ case kEventClassApplication:
+ if(ekind == kEventAppActivated) {
+ if(QApplication::desktopSettingsAware())
+ qt_mac_update_os_settings();
+ if(qt_clipboard) { //manufacture an event so the clipboard can see if it has changed
+ QEvent ev(QEvent::Clipboard);
+ QApplication::sendSpontaneousEvent(qt_clipboard, &ev);
+ }
+ if(app) {
+ QEvent ev(QEvent::ApplicationActivate);
+ QApplication::sendSpontaneousEvent(app, &ev);
+ }
+ if(!app->activeWindow()) {
+ WindowPtr wp = ActiveNonFloatingWindow();
+ if(QWidget *tmp_w = qt_mac_find_window(wp))
+ app->setActiveWindow(tmp_w);
+ }
+ QMenuBar::macUpdateMenuBar();
+ } else if(ekind == kEventAppDeactivated) {
+ //qt_mac_no_click_through_mode = false;
+ while(app->d_func()->inPopupMode())
+ app->activePopupWidget()->close();
+ if(app) {
+ QEvent ev(QEvent::ApplicationDeactivate);
+ QApplication::sendSpontaneousEvent(app, &ev);
+ }
+ app->setActiveWindow(0);
+ } else if(ekind == kEventAppAvailableWindowBoundsChanged) {
+ QDesktopWidgetImplementation::instance()->onResize();
+ } else {
+ handled_event = false;
+ }
+ break;
+ case kAppearanceEventClass:
+ if(ekind == kAEAppearanceChanged) {
+ if(QApplication::desktopSettingsAware())
+ qt_mac_update_os_settings();
+ if(QApplicationPrivate::app_style) {
+ QEvent ev(QEvent::Style);
+ QApplication::sendSpontaneousEvent(QApplicationPrivate::app_style, &ev);
+ }
+ } else {
+ handled_event = false;
+ }
+ break;
+ case kEventClassAppleEvent:
+ if(ekind == kEventAppleEvent) {
+ EventRecord erec;
+ if(!ConvertEventRefToEventRecord(event, &erec))
+ qDebug("Qt: internal: WH0A, unexpected condition reached. %s:%d", __FILE__, __LINE__);
+ else if(AEProcessAppleEvent(&erec) != noErr)
+ handled_event = false;
+ } else {
+ handled_event = false;
+ }
+ break;
+ case kEventClassCommand:
+ if(ekind == kEventCommandProcess) {
+ HICommand cmd;
+ GetEventParameter(event, kEventParamDirectObject, typeHICommand,
+ 0, sizeof(cmd), 0, &cmd);
+ handled_event = false;
+ if(!cmd.menu.menuRef && GetApplicationDockTileMenu()) {
+ EventRef copy = CopyEvent(event);
+ HICommand copy_cmd;
+ GetEventParameter(event, kEventParamDirectObject, typeHICommand,
+ 0, sizeof(copy_cmd), 0, &copy_cmd);
+ copy_cmd.menu.menuRef = GetApplicationDockTileMenu();
+ SetEventParameter(copy, kEventParamDirectObject, typeHICommand, sizeof(copy_cmd), &copy_cmd);
+ if(SendEventToMenu(copy, copy_cmd.menu.menuRef) == noErr)
+ handled_event = true;
+ }
+ if(!handled_event) {
+ if(cmd.commandID == kHICommandQuit) {
+ // Quitting the application is not Qt's responsibility if
+ // used in a plugin or just embedded into a native application.
+ // In that case, let the event pass down to the native apps event handler.
+ if (!QApplication::testAttribute(Qt::AA_MacPluginApplication)) {
+ handled_event = true;
+ HiliteMenu(0);
+ bool handle_quit = true;
+ if(QApplicationPrivate::modalState()) {
+ int visible = 0;
+ const QWidgetList tlws = QApplication::topLevelWidgets();
+ for(int i = 0; i < tlws.size(); ++i) {
+ if(tlws.at(i)->isVisible())
+ ++visible;
+ }
+ handle_quit = (visible <= 1);
+ }
+ if(handle_quit) {
+ QCloseEvent ev;
+ QApplication::sendSpontaneousEvent(app, &ev);
+ if(ev.isAccepted())
+ app->quit();
+ } else {
+ QApplication::beep();
+ }
+ }
+ } else if(cmd.commandID == kHICommandSelectWindow) {
+ if((GetCurrentKeyModifiers() & cmdKey))
+ handled_event = true;
+ } else if(cmd.commandID == kHICommandAbout) {
+ QMessageBox::aboutQt(0);
+ HiliteMenu(0);
+ handled_event = true;
+ }
+ }
+ }
+ break;
+ }
+
+#ifdef DEBUG_EVENTS
+ qDebug("%shandled event %c%c%c%c %d", handled_event ? "(*) " : "",
+ char(eclass >> 24), char((eclass >> 16) & 255), char((eclass >> 8) & 255),
+ char(eclass & 255), (int)ekind);
+#endif
+ if(!handled_event) //let the event go through
+ return eventNotHandledErr;
+ return noErr; //we eat the event
+#else
+ Q_UNUSED(er);
+ Q_UNUSED(event);
+ Q_UNUSED(data);
+ return eventNotHandledErr;
+#endif
+}
+
+#ifdef QT_MAC_USE_COCOA
+void QApplicationPrivate::qt_initAfterNSAppStarted()
+{
+ setupAppleEvents();
+ qt_mac_update_cursor();
+}
+
+void QApplicationPrivate::setupAppleEvents()
+{
+ // This function is called from the event dispatcher when NSApplication has
+ // finished initialization, which appears to be just after [NSApplication run] has
+ // started to execute. By setting up our apple events handlers this late, we override
+ // the ones set up by NSApplication.
+
+ // If Qt is used as a plugin, we let the 3rd party application handle events
+ // like quit and open file events. Otherwise, if we install our own handlers, we
+ // easily end up breaking functionallity the 3rd party application depend on:
+ if (QApplication::testAttribute(Qt::AA_MacPluginApplication))
+ return;
+
+ QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) *newDelegate = [QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) sharedDelegate];
+ NSAppleEventManager *eventManager = [NSAppleEventManager sharedAppleEventManager];
+ [eventManager setEventHandler:newDelegate andSelector:@selector(appleEventQuit:withReplyEvent:)
+ forEventClass:kCoreEventClass andEventID:kAEQuitApplication];
+ [eventManager setEventHandler:newDelegate andSelector:@selector(getUrl:withReplyEvent:)
+ forEventClass:kInternetEventClass andEventID:kAEGetURL];
+}
+#endif
+
+// In Carbon this is your one stop for apple events.
+// In Cocoa, it ISN'T. This is the catch-all Apple Event handler that exists
+// for the time between instantiating the NSApplication, but before the
+// NSApplication has installed it's OWN Apple Event handler. When Cocoa has
+// that set up, we remove this. So, if you are debugging problems, you likely
+// want to check out QCocoaApplicationDelegate instead.
+OSStatus QApplicationPrivate::globalAppleEventProcessor(const AppleEvent *ae, AppleEvent *, long handlerRefcon)
+{
+ QApplication *app = (QApplication *)handlerRefcon;
+ bool handled_event=false;
+ OSType aeID=typeWildCard, aeClass=typeWildCard;
+ AEGetAttributePtr(ae, keyEventClassAttr, typeType, 0, &aeClass, sizeof(aeClass), 0);
+ AEGetAttributePtr(ae, keyEventIDAttr, typeType, 0, &aeID, sizeof(aeID), 0);
+ if(aeClass == kCoreEventClass) {
+ switch(aeID) {
+ case kAEQuitApplication: {
+ extern bool qt_mac_quit_menu_item_enabled; // qmenu_mac.cpp
+ if (qt_mac_quit_menu_item_enabled) {
+ QCloseEvent ev;
+ QApplication::sendSpontaneousEvent(app, &ev);
+ if(ev.isAccepted()) {
+ handled_event = true;
+ app->quit();
+ }
+ } else {
+ QApplication::beep(); // Sorry, you can't quit right now.
+ }
+ break; }
+ case kAEOpenDocuments: {
+ AEDescList docs;
+ if(AEGetParamDesc(ae, keyDirectObject, typeAEList, &docs) == noErr) {
+ long cnt = 0;
+ AECountItems(&docs, &cnt);
+ UInt8 *str_buffer = NULL;
+ for(int i = 0; i < cnt; i++) {
+ FSRef ref;
+ if(AEGetNthPtr(&docs, i+1, typeFSRef, 0, 0, &ref, sizeof(ref), 0) != noErr)
+ continue;
+ if(!str_buffer)
+ str_buffer = (UInt8 *)malloc(1024);
+ FSRefMakePath(&ref, str_buffer, 1024);
+ QFileOpenEvent ev(QString::fromUtf8((const char *)str_buffer));
+ QApplication::sendSpontaneousEvent(app, &ev);
+ }
+ if(str_buffer)
+ free(str_buffer);
+ }
+ break; }
+ default:
+ break;
+ }
+ } else if (aeClass == kInternetEventClass) {
+ switch (aeID) {
+ case kAEGetURL: {
+ char urlData[1024];
+ Size actualSize;
+ if (AEGetParamPtr(ae, keyDirectObject, typeChar, 0, urlData,
+ sizeof(urlData) - 1, &actualSize) == noErr) {
+ urlData[actualSize] = 0;
+ QFileOpenEvent ev(QUrl(QString::fromUtf8(urlData)));
+ QApplication::sendSpontaneousEvent(app, &ev);
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+#ifdef DEBUG_EVENTS
+ qDebug("Qt: internal: %shandled Apple event! %c%c%c%c %c%c%c%c", handled_event ? "(*)" : "",
+ char(aeID >> 24), char((aeID >> 16) & 255), char((aeID >> 8) & 255),char(aeID & 255),
+ char(aeClass >> 24), char((aeClass >> 16) & 255), char((aeClass >> 8) & 255),char(aeClass & 255));
+#else
+ if(!handled_event) //let the event go through
+ return eventNotHandledErr;
+ return noErr; //we eat the event
+#endif
+}
+
+/*!
+ \fn bool QApplication::macEventFilter(EventHandlerCallRef caller, EventRef event)
+
+ \warning This virtual function is only used under Mac OS X, and behaves different
+ depending on if Qt is based on Carbon or Cocoa.
+
+ For the Carbon port, If you create an application that inherits QApplication and reimplement
+ this function, you get direct access to all Carbon Events that Qt registers
+ for from Mac OS X with this function being called with the \a caller and
+ the \a event.
+
+ For the Cocoa port, If you create an application that inherits QApplication and reimplement
+ this function, you get direct access to all Cocoa Events that Qt receives
+ from Mac OS X with this function being called with the \a caller being 0 and
+ the \a event being an NSEvent pointer:
+
+ NSEvent *e = reinterpret_cast<NSEvent *>(event);
+
+ Return true if you want to stop the event from being processed.
+ Return false for normal event dispatching. The default
+ implementation returns false.
+*/
+bool QApplication::macEventFilter(EventHandlerCallRef, EventRef)
+{
+ return false;
+}
+
+/*!
+ \internal
+*/
+void QApplicationPrivate::openPopup(QWidget *popup)
+{
+ if (!QApplicationPrivate::popupWidgets) // create list
+ QApplicationPrivate::popupWidgets = new QWidgetList;
+ QApplicationPrivate::popupWidgets->append(popup); // add to end of list
+
+ // popups are not focus-handled by the window system (the first
+ // popup grabbed the keyboard), so we have to do that manually: A
+ // new popup gets the focus
+ if (popup->focusWidget()) {
+ popup->focusWidget()->setFocus(Qt::PopupFocusReason);
+ } else if (QApplicationPrivate::popupWidgets->count() == 1) { // this was the first popup
+ popup->setFocus(Qt::PopupFocusReason);
+ }
+}
+
+/*!
+ \internal
+*/
+void QApplicationPrivate::closePopup(QWidget *popup)
+{
+ Q_Q(QApplication);
+ if (!QApplicationPrivate::popupWidgets)
+ return;
+
+ QApplicationPrivate::popupWidgets->removeAll(popup);
+ if (popup == qt_button_down)
+ qt_button_down = 0;
+ if (QApplicationPrivate::popupWidgets->isEmpty()) { // this was the last popup
+ delete QApplicationPrivate::popupWidgets;
+ QApplicationPrivate::popupWidgets = 0;
+
+ // Special case for Tool windows: since they are activated and deactived together
+ // with a normal window they never become the QApplicationPrivate::active_window.
+ QWidget *appFocusWidget = QApplication::focusWidget();
+ if (appFocusWidget && appFocusWidget->window()->windowType() == Qt::Tool) {
+ appFocusWidget->setFocus(Qt::PopupFocusReason);
+ } else if (QApplicationPrivate::active_window) {
+ if (QWidget *fw = QApplicationPrivate::active_window->focusWidget()) {
+ if (fw != QApplication::focusWidget()) {
+ fw->setFocus(Qt::PopupFocusReason);
+ } else {
+ QFocusEvent e(QEvent::FocusIn, Qt::PopupFocusReason);
+ q->sendEvent(fw, &e);
+ }
+ }
+ }
+ } else {
+ // popups are not focus-handled by the window system (the
+ // first popup grabbed the keyboard), so we have to do that
+ // manually: A popup was closed, so the previous popup gets
+ // the focus.
+ QWidget* aw = QApplicationPrivate::popupWidgets->last();
+ if (QWidget *fw = aw->focusWidget())
+ fw->setFocus(Qt::PopupFocusReason);
+ }
+}
+
+void QApplication::beep()
+{
+ qt_mac_beep();
+}
+
+void QApplication::alert(QWidget *widget, int duration)
+{
+ if (!QApplicationPrivate::checkInstance("alert"))
+ return;
+
+ QWidgetList windowsToMark;
+ if (!widget)
+ windowsToMark += topLevelWidgets();
+ else
+ windowsToMark.append(widget->window());
+
+ bool needNotification = false;
+ for (int i = 0; i < windowsToMark.size(); ++i) {
+ QWidget *window = windowsToMark.at(i);
+ if (!window->isActiveWindow() && window->isVisible()) {
+ needNotification = true; // yeah, we may set it multiple times, but that's OK.
+ if (duration != 0) {
+ QTimer *timer = new QTimer(qApp);
+ timer->setSingleShot(true);
+ connect(timer, SIGNAL(timeout()), qApp, SLOT(_q_alertTimeOut()));
+ if (QTimer *oldTimer = qApp->d_func()->alertTimerHash.value(widget)) {
+ qApp->d_func()->alertTimerHash.remove(widget);
+ delete oldTimer;
+ }
+ qApp->d_func()->alertTimerHash.insert(widget, timer);
+ timer->start(duration);
+ }
+ }
+ }
+ if (needNotification)
+ qt_mac_send_notification();
+}
+
+void QApplicationPrivate::_q_alertTimeOut()
+{
+ if (QTimer *timer = qobject_cast<QTimer *>(q_func()->sender())) {
+ QHash<QWidget *, QTimer *>::iterator it = alertTimerHash.begin();
+ while (it != alertTimerHash.end()) {
+ if (it.value() == timer) {
+ alertTimerHash.erase(it);
+ timer->deleteLater();
+ break;
+ }
+ ++it;
+ }
+ if (alertTimerHash.isEmpty()) {
+ qt_mac_cancel_notification();
+ }
+ }
+}
+
+void QApplication::setCursorFlashTime(int msecs)
+{
+ QApplicationPrivate::cursor_flash_time = msecs;
+}
+
+int QApplication::cursorFlashTime()
+{
+ return QApplicationPrivate::cursor_flash_time;
+}
+
+void QApplication::setDoubleClickInterval(int ms)
+{
+ qt_mac_dblclick.use_qt_time_limit = true;
+ QApplicationPrivate::mouse_double_click_time = ms;
+}
+
+int QApplication::doubleClickInterval()
+{
+ if (!qt_mac_dblclick.use_qt_time_limit) { //get it from the system
+ QSettings appleSettings(QLatin1String("apple.com"));
+ /* First worked as of 10.3.3 */
+ double dci = appleSettings.value(QLatin1String("com/apple/mouse/doubleClickThreshold"), 0.5).toDouble();
+ return int(dci * 1000);
+ }
+ return QApplicationPrivate::mouse_double_click_time;
+}
+
+void QApplication::setKeyboardInputInterval(int ms)
+{
+ QApplicationPrivate::keyboard_input_time = ms;
+}
+
+int QApplication::keyboardInputInterval()
+{
+ // FIXME: get from the system
+ return QApplicationPrivate::keyboard_input_time;
+}
+
+#ifndef QT_NO_WHEELEVENT
+void QApplication::setWheelScrollLines(int n)
+{
+ QApplicationPrivate::wheel_scroll_lines = n;
+}
+
+int QApplication::wheelScrollLines()
+{
+ return QApplicationPrivate::wheel_scroll_lines;
+}
+#endif
+
+void QApplication::setEffectEnabled(Qt::UIEffect effect, bool enable)
+{
+ switch (effect) {
+ case Qt::UI_FadeMenu:
+ QApplicationPrivate::fade_menu = enable;
+ break;
+ case Qt::UI_AnimateMenu:
+ QApplicationPrivate::animate_menu = enable;
+ break;
+ case Qt::UI_FadeTooltip:
+ QApplicationPrivate::fade_tooltip = enable;
+ break;
+ case Qt::UI_AnimateTooltip:
+ QApplicationPrivate::animate_tooltip = enable;
+ break;
+ case Qt::UI_AnimateCombo:
+ QApplicationPrivate::animate_combo = enable;
+ break;
+ case Qt::UI_AnimateToolBox:
+ QApplicationPrivate::animate_toolbox = enable;
+ break;
+ case Qt::UI_General:
+ QApplicationPrivate::fade_tooltip = true;
+ break;
+ default:
+ QApplicationPrivate::animate_ui = enable;
+ break;
+ }
+
+ if (enable)
+ QApplicationPrivate::animate_ui = true;
+}
+
+bool QApplication::isEffectEnabled(Qt::UIEffect effect)
+{
+ if (QColormap::instance().depth() < 16 || !QApplicationPrivate::animate_ui)
+ return false;
+
+ switch(effect) {
+ case Qt::UI_AnimateMenu:
+ return QApplicationPrivate::animate_menu;
+ case Qt::UI_FadeMenu:
+ return QApplicationPrivate::fade_menu;
+ case Qt::UI_AnimateCombo:
+ return QApplicationPrivate::animate_combo;
+ case Qt::UI_AnimateTooltip:
+ return QApplicationPrivate::animate_tooltip;
+ case Qt::UI_FadeTooltip:
+ return QApplicationPrivate::fade_tooltip;
+ case Qt::UI_AnimateToolBox:
+ return QApplicationPrivate::animate_toolbox;
+ default:
+ break;
+ }
+ return QApplicationPrivate::animate_ui;
+}
+
+/*!
+ \internal
+*/
+bool QApplicationPrivate::qt_mac_apply_settings()
+{
+ QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
+ settings.beginGroup(QLatin1String("Qt"));
+
+ /*
+ Qt settings. This is how they are written into the datastream.
+ Palette/ * - QPalette
+ font - QFont
+ libraryPath - QStringList
+ style - QString
+ doubleClickInterval - int
+ cursorFlashTime - int
+ wheelScrollLines - int
+ colorSpec - QString
+ defaultCodec - QString
+ globalStrut/width - int
+ globalStrut/height - int
+ GUIEffects - QStringList
+ Font Substitutions/ * - QStringList
+ Font Substitutions/... - QStringList
+ */
+
+ // read library (ie. plugin) path list
+ QString libpathkey =
+ QString::fromLatin1("%1.%2/libraryPath")
+ .arg(QT_VERSION >> 16)
+ .arg((QT_VERSION & 0xff00) >> 8);
+ QStringList pathlist = settings.value(libpathkey).toString().split(QLatin1Char(':'));
+ if (!pathlist.isEmpty()) {
+ QStringList::ConstIterator it = pathlist.begin();
+ while(it != pathlist.end())
+ QApplication::addLibraryPath(*it++);
+ }
+
+ QString defaultcodec = settings.value(QLatin1String("defaultCodec"), QVariant(QLatin1String("none"))).toString();
+ if (defaultcodec != QLatin1String("none")) {
+ QTextCodec *codec = QTextCodec::codecForName(defaultcodec.toLatin1().constData());
+ if (codec)
+ QTextCodec::setCodecForTr(codec);
+ }
+
+ if (qt_is_gui_used) {
+ QString str;
+ QStringList strlist;
+ int num;
+
+ // read new palette
+ int i;
+ QPalette pal(QApplication::palette());
+ strlist = settings.value(QLatin1String("Palette/active")).toStringList();
+ if (strlist.count() == QPalette::NColorRoles) {
+ for (i = 0; i < QPalette::NColorRoles; i++)
+ pal.setColor(QPalette::Active, (QPalette::ColorRole) i,
+ QColor(strlist[i]));
+ }
+ strlist = settings.value(QLatin1String("Palette/inactive")).toStringList();
+ if (strlist.count() == QPalette::NColorRoles) {
+ for (i = 0; i < QPalette::NColorRoles; i++)
+ pal.setColor(QPalette::Inactive, (QPalette::ColorRole) i,
+ QColor(strlist[i]));
+ }
+ strlist = settings.value(QLatin1String("Palette/disabled")).toStringList();
+ if (strlist.count() == QPalette::NColorRoles) {
+ for (i = 0; i < QPalette::NColorRoles; i++)
+ pal.setColor(QPalette::Disabled, (QPalette::ColorRole) i,
+ QColor(strlist[i]));
+ }
+
+ if (pal != QApplication::palette())
+ QApplication::setPalette(pal);
+
+ // read new font
+ QFont font(QApplication::font());
+ str = settings.value(QLatin1String("font")).toString();
+ if (!str.isEmpty()) {
+ font.fromString(str);
+ if (font != QApplication::font())
+ QApplication::setFont(font);
+ }
+
+ // read new QStyle
+ QString stylename = settings.value(QLatin1String("style")).toString();
+ if (! stylename.isNull() && ! stylename.isEmpty()) {
+ QStyle *style = QStyleFactory::create(stylename);
+ if (style)
+ QApplication::setStyle(style);
+ else
+ stylename = QLatin1String("default");
+ } else {
+ stylename = QLatin1String("default");
+ }
+
+ num = settings.value(QLatin1String("doubleClickInterval"),
+ QApplication::doubleClickInterval()).toInt();
+ QApplication::setDoubleClickInterval(num);
+
+ num = settings.value(QLatin1String("cursorFlashTime"),
+ QApplication::cursorFlashTime()).toInt();
+ QApplication::setCursorFlashTime(num);
+
+#ifndef QT_NO_WHEELEVENT
+ num = settings.value(QLatin1String("wheelScrollLines"),
+ QApplication::wheelScrollLines()).toInt();
+ QApplication::setWheelScrollLines(num);
+#endif
+
+ QString colorspec = settings.value(QLatin1String("colorSpec"),
+ QVariant(QLatin1String("default"))).toString();
+ if (colorspec == QLatin1String("normal"))
+ QApplication::setColorSpec(QApplication::NormalColor);
+ else if (colorspec == QLatin1String("custom"))
+ QApplication::setColorSpec(QApplication::CustomColor);
+ else if (colorspec == QLatin1String("many"))
+ QApplication::setColorSpec(QApplication::ManyColor);
+ else if (colorspec != QLatin1String("default"))
+ colorspec = QLatin1String("default");
+
+ int w = settings.value(QLatin1String("globalStrut/width")).toInt();
+ int h = settings.value(QLatin1String("globalStrut/height")).toInt();
+ QSize strut(w, h);
+ if (strut.isValid())
+ QApplication::setGlobalStrut(strut);
+
+ QStringList effects = settings.value(QLatin1String("GUIEffects")).toStringList();
+ if (!effects.isEmpty()) {
+ if (effects.contains(QLatin1String("none")))
+ QApplication::setEffectEnabled(Qt::UI_General, false);
+ if (effects.contains(QLatin1String("general")))
+ QApplication::setEffectEnabled(Qt::UI_General, true);
+ if (effects.contains(QLatin1String("animatemenu")))
+ QApplication::setEffectEnabled(Qt::UI_AnimateMenu, true);
+ if (effects.contains(QLatin1String("fademenu")))
+ QApplication::setEffectEnabled(Qt::UI_FadeMenu, true);
+ if (effects.contains(QLatin1String("animatecombo")))
+ QApplication::setEffectEnabled(Qt::UI_AnimateCombo, true);
+ if (effects.contains(QLatin1String("animatetooltip")))
+ QApplication::setEffectEnabled(Qt::UI_AnimateTooltip, true);
+ if (effects.contains(QLatin1String("fadetooltip")))
+ QApplication::setEffectEnabled(Qt::UI_FadeTooltip, true);
+ if (effects.contains(QLatin1String("animatetoolbox")))
+ QApplication::setEffectEnabled(Qt::UI_AnimateToolBox, true);
+ } else {
+ QApplication::setEffectEnabled(Qt::UI_General, true);
+ }
+
+ settings.beginGroup(QLatin1String("Font Substitutions"));
+ QStringList fontsubs = settings.childKeys();
+ if (!fontsubs.isEmpty()) {
+ QStringList::Iterator it = fontsubs.begin();
+ for (; it != fontsubs.end(); ++it) {
+ QString fam = QString::fromLatin1((*it).toLatin1().constData());
+ QStringList subs = settings.value(fam).toStringList();
+ QFont::insertSubstitutions(fam, subs);
+ }
+ }
+ settings.endGroup();
+ }
+
+ settings.endGroup();
+ return true;
+}
+
+// DRSWAT
+
+bool QApplicationPrivate::canQuit()
+{
+#ifndef QT_MAC_USE_COCOA
+ return true;
+#else
+ Q_Q(QApplication);
+#ifdef QT_MAC_USE_COCOA
+ [[NSApp mainMenu] cancelTracking];
+#else
+ HiliteMenu(0);
+#endif
+
+ bool handle_quit = true;
+ if (QApplicationPrivate::modalState() && [[[[QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) sharedDelegate]
+ menuLoader] quitMenuItem] isEnabled]) {
+ int visible = 0;
+ const QWidgetList tlws = QApplication::topLevelWidgets();
+ for(int i = 0; i < tlws.size(); ++i) {
+ if (tlws.at(i)->isVisible())
+ ++visible;
+ }
+ handle_quit = (visible <= 1);
+ }
+ if (handle_quit) {
+ QCloseEvent ev;
+ QApplication::sendSpontaneousEvent(q, &ev);
+ if (ev.isAccepted()) {
+ return true;
+ }
+ }
+ return false;
+#endif
+}
+
+void onApplicationWindowChangedActivation(QWidget *widget, bool activated)
+{
+#if QT_MAC_USE_COCOA
+ if (!widget)
+ return;
+
+ if (activated) {
+ if (QApplicationPrivate::app_style) {
+ QEvent ev(QEvent::Style);
+ qt_sendSpontaneousEvent(QApplicationPrivate::app_style, &ev);
+ }
+ qApp->setActiveWindow(widget);
+ } else { // deactivated
+ if (QApplicationPrivate::active_window == widget)
+ qApp->setActiveWindow(0);
+ }
+
+ QMenuBar::macUpdateMenuBar();
+ qt_mac_update_cursor();
+#else
+ Q_UNUSED(widget);
+ Q_UNUSED(activated);
+#endif
+}
+
+
+void onApplicationChangedActivation( bool activated )
+{
+#if QT_MAC_USE_COCOA
+ QApplication *app = qApp;
+
+//NSLog(@"App Changed Activation\n");
+
+ if ( activated ) {
+ if (QApplication::desktopSettingsAware())
+ qt_mac_update_os_settings();
+
+ if (qt_clipboard) { //manufacture an event so the clipboard can see if it has changed
+ QEvent ev(QEvent::Clipboard);
+ qt_sendSpontaneousEvent(qt_clipboard, &ev);
+ }
+
+ if (app) {
+ QEvent ev(QEvent::ApplicationActivate);
+ qt_sendSpontaneousEvent(app, &ev);
+ }
+
+ if (!app->activeWindow()) {
+ OSWindowRef wp = [NSApp keyWindow];
+ if (QWidget *tmp_w = qt_mac_find_window(wp))
+ app->setActiveWindow(tmp_w);
+ }
+ QMenuBar::macUpdateMenuBar();
+ qt_mac_update_cursor();
+ } else { // de-activated
+ QApplicationPrivate *priv = [[QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) sharedDelegate] qAppPrivate];
+ while (priv->inPopupMode())
+ app->activePopupWidget()->close();
+ if (app) {
+ QEvent ev(QEvent::ApplicationDeactivate);
+ qt_sendSpontaneousEvent(app, &ev);
+ }
+ app->setActiveWindow(0);
+ }
+#else
+ Q_UNUSED(activated);
+#endif
+}
+
+void QApplicationPrivate::initializeMultitouch_sys()
+{ }
+void QApplicationPrivate::cleanupMultitouch_sys()
+{ }
+
+QT_END_NAMESPACE
diff --git a/src/gui/kernel/qclipboard_mac.cpp b/src/widgets/platforms/mac/qclipboard_mac.cpp
index 002b8da967..002b8da967 100644
--- a/src/gui/kernel/qclipboard_mac.cpp
+++ b/src/widgets/platforms/mac/qclipboard_mac.cpp
diff --git a/src/gui/kernel/qcocoaintrospection_mac.mm b/src/widgets/platforms/mac/qcocoaintrospection_mac.mm
index ed2fbeaeda..ed2fbeaeda 100644
--- a/src/gui/kernel/qcocoaintrospection_mac.mm
+++ b/src/widgets/platforms/mac/qcocoaintrospection_mac.mm
diff --git a/src/gui/kernel/qcocoaintrospection_p.h b/src/widgets/platforms/mac/qcocoaintrospection_p.h
index e18646d063..e18646d063 100644
--- a/src/gui/kernel/qcocoaintrospection_p.h
+++ b/src/widgets/platforms/mac/qcocoaintrospection_p.h
diff --git a/src/gui/kernel/qcocoapanel_mac.mm b/src/widgets/platforms/mac/qcocoapanel_mac.mm
index 5b490cf8b4..5b490cf8b4 100644
--- a/src/gui/kernel/qcocoapanel_mac.mm
+++ b/src/widgets/platforms/mac/qcocoapanel_mac.mm
diff --git a/src/gui/kernel/qcocoapanel_mac_p.h b/src/widgets/platforms/mac/qcocoapanel_mac_p.h
index ad02b16657..ad02b16657 100644
--- a/src/gui/kernel/qcocoapanel_mac_p.h
+++ b/src/widgets/platforms/mac/qcocoapanel_mac_p.h
diff --git a/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h b/src/widgets/platforms/mac/qcocoasharedwindowmethods_mac_p.h
index f5a93d98d2..f5a93d98d2 100644
--- a/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h
+++ b/src/widgets/platforms/mac/qcocoasharedwindowmethods_mac_p.h
diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/widgets/platforms/mac/qcocoaview_mac.mm
index 6c5e05b32a..6c5e05b32a 100644
--- a/src/gui/kernel/qcocoaview_mac.mm
+++ b/src/widgets/platforms/mac/qcocoaview_mac.mm
diff --git a/src/widgets/platforms/mac/qcocoaview_mac_p.h b/src/widgets/platforms/mac/qcocoaview_mac_p.h
new file mode 100644
index 0000000000..963cbe06bf
--- /dev/null
+++ b/src/widgets/platforms/mac/qcocoaview_mac_p.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <qevent.h>
+#ifdef QT_MAC_USE_COCOA
+#import <Cocoa/Cocoa.h>
+
+@class QT_MANGLE_NAMESPACE(QCocoaView);
+QT_FORWARD_DECLARE_CLASS(QWidgetPrivate);
+QT_FORWARD_DECLARE_CLASS(QWidget);
+QT_FORWARD_DECLARE_CLASS(QEvent);
+QT_FORWARD_DECLARE_CLASS(QString);
+QT_FORWARD_DECLARE_CLASS(QStringList);
+
+Q_WIDGETS_EXPORT
+@interface QT_MANGLE_NAMESPACE(QCocoaView) : NSControl <NSTextInput> {
+ QWidget *qwidget;
+ QWidgetPrivate *qwidgetprivate;
+ NSDragOperation supportedActions;
+ bool composing;
+ int composingLength;
+ bool sendKeyEvents;
+ bool fromKeyDownEvent;
+ QString *composingText;
+ @public int alienTouchCount;
+}
+- (id)initWithQWidget:(QWidget *)widget widgetPrivate:(QWidgetPrivate *)widgetprivate;
+- (void) finishInitWithQWidget:(QWidget *)widget widgetPrivate:(QWidgetPrivate *)widgetprivate;
+- (void)frameDidChange:(NSNotification *)note;
+- (void)setSupportedActions:(NSDragOperation)actions;
+- (NSDragOperation)draggingSourceOperationMaskForLocal:(BOOL)isLocal;
+- (void)draggedImage:(NSImage *)anImage endedAt:(NSPoint)aPoint operation:(NSDragOperation)operation;
+- (BOOL)isComposing;
+- (QWidget *)qt_qwidget;
+- (void) qt_clearQWidget;
+
+@end
+#endif
diff --git a/src/gui/kernel/qcocoawindow_mac.mm b/src/widgets/platforms/mac/qcocoawindow_mac.mm
index fba69a3263..fba69a3263 100644
--- a/src/gui/kernel/qcocoawindow_mac.mm
+++ b/src/widgets/platforms/mac/qcocoawindow_mac.mm
diff --git a/src/gui/kernel/qcocoawindow_mac_p.h b/src/widgets/platforms/mac/qcocoawindow_mac_p.h
index 9013f66080..9013f66080 100644
--- a/src/gui/kernel/qcocoawindow_mac_p.h
+++ b/src/widgets/platforms/mac/qcocoawindow_mac_p.h
diff --git a/src/gui/kernel/qcocoawindowcustomthemeframe_mac.mm b/src/widgets/platforms/mac/qcocoawindowcustomthemeframe_mac.mm
index cc255420b5..cc255420b5 100644
--- a/src/gui/kernel/qcocoawindowcustomthemeframe_mac.mm
+++ b/src/widgets/platforms/mac/qcocoawindowcustomthemeframe_mac.mm
diff --git a/src/gui/kernel/qcocoawindowcustomthemeframe_mac_p.h b/src/widgets/platforms/mac/qcocoawindowcustomthemeframe_mac_p.h
index 7ac8a28539..7ac8a28539 100644
--- a/src/gui/kernel/qcocoawindowcustomthemeframe_mac_p.h
+++ b/src/widgets/platforms/mac/qcocoawindowcustomthemeframe_mac_p.h
diff --git a/src/gui/kernel/qcocoawindowdelegate_mac.mm b/src/widgets/platforms/mac/qcocoawindowdelegate_mac.mm
index 772fd2bfc7..772fd2bfc7 100644
--- a/src/gui/kernel/qcocoawindowdelegate_mac.mm
+++ b/src/widgets/platforms/mac/qcocoawindowdelegate_mac.mm
diff --git a/src/gui/kernel/qcocoawindowdelegate_mac_p.h b/src/widgets/platforms/mac/qcocoawindowdelegate_mac_p.h
index a510ae48ed..a510ae48ed 100644
--- a/src/gui/kernel/qcocoawindowdelegate_mac_p.h
+++ b/src/widgets/platforms/mac/qcocoawindowdelegate_mac_p.h
diff --git a/src/gui/painting/qcolormap_mac.cpp b/src/widgets/platforms/mac/qcolormap_mac.cpp
index 0c3fd70468..0c3fd70468 100644
--- a/src/gui/painting/qcolormap_mac.cpp
+++ b/src/widgets/platforms/mac/qcolormap_mac.cpp
diff --git a/src/gui/kernel/qcursor_mac.mm b/src/widgets/platforms/mac/qcursor_mac.mm
index 0b0abaa8c6..0b0abaa8c6 100644
--- a/src/gui/kernel/qcursor_mac.mm
+++ b/src/widgets/platforms/mac/qcursor_mac.mm
diff --git a/src/gui/kernel/qdesktopwidget_mac.mm b/src/widgets/platforms/mac/qdesktopwidget_mac.mm
index 0bf213303e..0bf213303e 100644
--- a/src/gui/kernel/qdesktopwidget_mac.mm
+++ b/src/widgets/platforms/mac/qdesktopwidget_mac.mm
diff --git a/src/gui/kernel/qdesktopwidget_mac_p.h b/src/widgets/platforms/mac/qdesktopwidget_mac_p.h
index e1ca7e7a37..e1ca7e7a37 100644
--- a/src/gui/kernel/qdesktopwidget_mac_p.h
+++ b/src/widgets/platforms/mac/qdesktopwidget_mac_p.h
diff --git a/src/gui/kernel/qdnd_mac.mm b/src/widgets/platforms/mac/qdnd_mac.mm
index 77926bde23..77926bde23 100644
--- a/src/gui/kernel/qdnd_mac.mm
+++ b/src/widgets/platforms/mac/qdnd_mac.mm
diff --git a/src/gui/kernel/qeventdispatcher_mac.mm b/src/widgets/platforms/mac/qeventdispatcher_mac.mm
index f90fb5a1d5..f90fb5a1d5 100644
--- a/src/gui/kernel/qeventdispatcher_mac.mm
+++ b/src/widgets/platforms/mac/qeventdispatcher_mac.mm
diff --git a/src/gui/kernel/qeventdispatcher_mac_p.h b/src/widgets/platforms/mac/qeventdispatcher_mac_p.h
index f4cf16e8a0..f4cf16e8a0 100644
--- a/src/gui/kernel/qeventdispatcher_mac_p.h
+++ b/src/widgets/platforms/mac/qeventdispatcher_mac_p.h
diff --git a/src/gui/text/qfont_mac.cpp b/src/widgets/platforms/mac/qfont_mac.cpp
index 3bbff7f4bb..3bbff7f4bb 100644
--- a/src/gui/text/qfont_mac.cpp
+++ b/src/widgets/platforms/mac/qfont_mac.cpp
diff --git a/src/gui/text/qfontdatabase_mac.cpp b/src/widgets/platforms/mac/qfontdatabase_mac.cpp
index 6876fae630..6876fae630 100644
--- a/src/gui/text/qfontdatabase_mac.cpp
+++ b/src/widgets/platforms/mac/qfontdatabase_mac.cpp
diff --git a/src/gui/text/qfontengine_coretext.mm b/src/widgets/platforms/mac/qfontengine_coretext.mm
index 9943229787..9943229787 100644
--- a/src/gui/text/qfontengine_coretext.mm
+++ b/src/widgets/platforms/mac/qfontengine_coretext.mm
diff --git a/src/gui/text/qfontengine_coretext_p.h b/src/widgets/platforms/mac/qfontengine_coretext_p.h
index d8a3033be6..d8a3033be6 100644
--- a/src/gui/text/qfontengine_coretext_p.h
+++ b/src/widgets/platforms/mac/qfontengine_coretext_p.h
diff --git a/src/gui/text/qfontengine_mac.mm b/src/widgets/platforms/mac/qfontengine_mac.mm
index 6186b2f514..6186b2f514 100644
--- a/src/gui/text/qfontengine_mac.mm
+++ b/src/widgets/platforms/mac/qfontengine_mac.mm
diff --git a/src/gui/text/qfontengine_mac_p.h b/src/widgets/platforms/mac/qfontengine_mac_p.h
index 10561e54d6..10561e54d6 100644
--- a/src/gui/text/qfontengine_mac_p.h
+++ b/src/widgets/platforms/mac/qfontengine_mac_p.h
diff --git a/src/widgets/platforms/mac/qkeymapper_mac.cpp b/src/widgets/platforms/mac/qkeymapper_mac.cpp
new file mode 100644
index 0000000000..e96caf1b9d
--- /dev/null
+++ b/src/widgets/platforms/mac/qkeymapper_mac.cpp
@@ -0,0 +1,1023 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <private/qt_mac_p.h>
+#include <qdebug.h>
+#include <qevent.h>
+#include <private/qevent_p.h>
+#include <qtextcodec.h>
+#include <qapplication.h>
+#include <qinputcontext.h>
+#include <private/qkeymapper_p.h>
+#include <private/qapplication_p.h>
+#include <private/qmacinputcontext_p.h>
+
+QT_BEGIN_NAMESPACE
+
+QT_USE_NAMESPACE
+
+/*****************************************************************************
+ QKeyMapper debug facilities
+ *****************************************************************************/
+//#define DEBUG_KEY_BINDINGS
+//#define DEBUG_KEY_BINDINGS_MODIFIERS
+//#define DEBUG_KEY_MAPS
+
+/*****************************************************************************
+ Internal variables and functions
+ *****************************************************************************/
+bool qt_mac_eat_unicode_key = false;
+extern bool qt_sendSpontaneousEvent(QObject *obj, QEvent *event); //qapplication_mac.cpp
+
+Q_WIDGETS_EXPORT void qt_mac_secure_keyboard(bool b)
+{
+ static bool secure = false;
+ if (b != secure){
+ b ? EnableSecureEventInput() : DisableSecureEventInput();
+ secure = b;
+ }
+}
+
+/*
+ \internal
+ A Mac KeyboardLayoutItem has 8 possible states:
+ 1. Unmodified
+ 2. Shift
+ 3. Control
+ 4. Control + Shift
+ 5. Alt
+ 6. Alt + Shift
+ 7. Alt + Control
+ 8. Alt + Control + Shift
+ 9. Meta
+ 10. Meta + Shift
+ 11. Meta + Control
+ 12. Meta + Control + Shift
+ 13. Meta + Alt
+ 14. Meta + Alt + Shift
+ 15. Meta + Alt + Control
+ 16. Meta + Alt + Control + Shift
+*/
+struct KeyboardLayoutItem {
+ bool dirty;
+ quint32 qtKey[16]; // Can by any Qt::Key_<foo>, or unicode character
+};
+
+// Possible modifier states.
+// NOTE: The order of these states match the order in QKeyMapperPrivate::updatePossibleKeyCodes()!
+static const Qt::KeyboardModifiers ModsTbl[] = {
+ Qt::NoModifier, // 0
+ Qt::ShiftModifier, // 1
+ Qt::ControlModifier, // 2
+ Qt::ControlModifier | Qt::ShiftModifier, // 3
+ Qt::AltModifier, // 4
+ Qt::AltModifier | Qt::ShiftModifier, // 5
+ Qt::AltModifier | Qt::ControlModifier, // 6
+ Qt::AltModifier | Qt::ShiftModifier | Qt::ControlModifier, // 7
+ Qt::MetaModifier, // 8
+ Qt::MetaModifier | Qt::ShiftModifier, // 9
+ Qt::MetaModifier | Qt::ControlModifier, // 10
+ Qt::MetaModifier | Qt::ControlModifier | Qt::ShiftModifier,// 11
+ Qt::MetaModifier | Qt::AltModifier, // 12
+ Qt::MetaModifier | Qt::AltModifier | Qt::ShiftModifier, // 13
+ Qt::MetaModifier | Qt::AltModifier | Qt::ControlModifier, // 14
+ Qt::MetaModifier | Qt::AltModifier | Qt::ShiftModifier | Qt::ControlModifier, // 15
+};
+
+/* key maps */
+struct qt_mac_enum_mapper
+{
+ int mac_code;
+ int qt_code;
+#if defined(DEBUG_KEY_BINDINGS)
+# define QT_MAC_MAP_ENUM(x) x, #x
+ const char *desc;
+#else
+# define QT_MAC_MAP_ENUM(x) x
+#endif
+};
+
+//modifiers
+static qt_mac_enum_mapper qt_mac_modifier_symbols[] = {
+ { shiftKey, QT_MAC_MAP_ENUM(Qt::ShiftModifier) },
+ { rightShiftKey, QT_MAC_MAP_ENUM(Qt::ShiftModifier) },
+ { controlKey, QT_MAC_MAP_ENUM(Qt::MetaModifier) },
+ { rightControlKey, QT_MAC_MAP_ENUM(Qt::MetaModifier) },
+ { cmdKey, QT_MAC_MAP_ENUM(Qt::ControlModifier) },
+ { optionKey, QT_MAC_MAP_ENUM(Qt::AltModifier) },
+ { rightOptionKey, QT_MAC_MAP_ENUM(Qt::AltModifier) },
+ { kEventKeyModifierNumLockMask, QT_MAC_MAP_ENUM(Qt::KeypadModifier) },
+ { 0, QT_MAC_MAP_ENUM(0) }
+};
+Qt::KeyboardModifiers qt_mac_get_modifiers(int keys)
+{
+#ifdef DEBUG_KEY_BINDINGS_MODIFIERS
+ qDebug("Qt: internal: **Mapping modifiers: %d (0x%04x)", keys, keys);
+#endif
+ Qt::KeyboardModifiers ret = Qt::NoModifier;
+ for (int i = 0; qt_mac_modifier_symbols[i].qt_code; i++) {
+ if (keys & qt_mac_modifier_symbols[i].mac_code) {
+#ifdef DEBUG_KEY_BINDINGS_MODIFIERS
+ qDebug("Qt: internal: got modifier: %s", qt_mac_modifier_symbols[i].desc);
+#endif
+ ret |= Qt::KeyboardModifier(qt_mac_modifier_symbols[i].qt_code);
+ }
+ }
+ if (qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)) {
+ Qt::KeyboardModifiers oldModifiers = ret;
+ ret &= ~(Qt::MetaModifier | Qt::ControlModifier);
+ if (oldModifiers & Qt::ControlModifier)
+ ret |= Qt::MetaModifier;
+ if (oldModifiers & Qt::MetaModifier)
+ ret |= Qt::ControlModifier;
+ }
+ return ret;
+}
+static int qt_mac_get_mac_modifiers(Qt::KeyboardModifiers keys)
+{
+#ifdef DEBUG_KEY_BINDINGS_MODIFIERS
+ qDebug("Qt: internal: **Mapping modifiers: %d (0x%04x)", (int)keys, (int)keys);
+#endif
+ int ret = 0;
+ for (int i = 0; qt_mac_modifier_symbols[i].qt_code; i++) {
+ if (keys & qt_mac_modifier_symbols[i].qt_code) {
+#ifdef DEBUG_KEY_BINDINGS_MODIFIERS
+ qDebug("Qt: internal: got modifier: %s", qt_mac_modifier_symbols[i].desc);
+#endif
+ ret |= qt_mac_modifier_symbols[i].mac_code;
+ }
+ }
+
+ if (qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)) {
+ int oldModifiers = ret;
+ ret &= ~(controlKeyBit | cmdKeyBit);
+ if (oldModifiers & controlKeyBit)
+ ret |= cmdKeyBit;
+ if (oldModifiers & cmdKeyBit)
+ ret |= controlKeyBit;
+ }
+ return ret;
+}
+void qt_mac_send_modifiers_changed(quint32 modifiers, QObject *object)
+{
+ static quint32 cachedModifiers = 0;
+ quint32 lastModifiers = cachedModifiers,
+ changedModifiers = lastModifiers ^ modifiers;
+ cachedModifiers = modifiers;
+
+ //check the bits
+ static qt_mac_enum_mapper modifier_key_symbols[] = {
+ { shiftKeyBit, QT_MAC_MAP_ENUM(Qt::Key_Shift) },
+ { rightShiftKeyBit, QT_MAC_MAP_ENUM(Qt::Key_Shift) }, //???
+ { controlKeyBit, QT_MAC_MAP_ENUM(Qt::Key_Meta) },
+ { rightControlKeyBit, QT_MAC_MAP_ENUM(Qt::Key_Meta) }, //???
+ { cmdKeyBit, QT_MAC_MAP_ENUM(Qt::Key_Control) },
+ { optionKeyBit, QT_MAC_MAP_ENUM(Qt::Key_Alt) },
+ { rightOptionKeyBit, QT_MAC_MAP_ENUM(Qt::Key_Alt) }, //???
+ { alphaLockBit, QT_MAC_MAP_ENUM(Qt::Key_CapsLock) },
+ { kEventKeyModifierNumLockBit, QT_MAC_MAP_ENUM(Qt::Key_NumLock) },
+ { 0, QT_MAC_MAP_ENUM(0) } };
+ for (int i = 0; i <= 32; i++) { //just check each bit
+ if (!(changedModifiers & (1 << i)))
+ continue;
+ QEvent::Type etype = QEvent::KeyPress;
+ if (lastModifiers & (1 << i))
+ etype = QEvent::KeyRelease;
+ int key = 0;
+ for (uint x = 0; modifier_key_symbols[x].mac_code; x++) {
+ if (modifier_key_symbols[x].mac_code == i) {
+#ifdef DEBUG_KEY_BINDINGS_MODIFIERS
+ qDebug("got modifier changed: %s", modifier_key_symbols[x].desc);
+#endif
+ key = modifier_key_symbols[x].qt_code;
+ break;
+ }
+ }
+ if (!key) {
+#ifdef DEBUG_KEY_BINDINGS_MODIFIERS
+ qDebug("could not get modifier changed: %d", i);
+#endif
+ continue;
+ }
+#ifdef DEBUG_KEY_BINDINGS_MODIFIERS
+ qDebug("KeyEvent (modif): Sending %s to %s::%s: %d - 0x%08x",
+ etype == QEvent::KeyRelease ? "KeyRelease" : "KeyPress",
+ object ? object->metaObject()->className() : "none",
+ object ? object->objectName().toLatin1().constData() : "",
+ key, (int)modifiers);
+#endif
+ QKeyEvent ke(etype, key, qt_mac_get_modifiers(modifiers ^ (1 << i)), QLatin1String(""));
+ qt_sendSpontaneousEvent(object, &ke);
+ }
+}
+
+//keyboard keys (non-modifiers)
+static qt_mac_enum_mapper qt_mac_keyboard_symbols[] = {
+ { kHomeCharCode, QT_MAC_MAP_ENUM(Qt::Key_Home) },
+ { kEnterCharCode, QT_MAC_MAP_ENUM(Qt::Key_Enter) },
+ { kEndCharCode, QT_MAC_MAP_ENUM(Qt::Key_End) },
+ { kBackspaceCharCode, QT_MAC_MAP_ENUM(Qt::Key_Backspace) },
+ { kTabCharCode, QT_MAC_MAP_ENUM(Qt::Key_Tab) },
+ { kPageUpCharCode, QT_MAC_MAP_ENUM(Qt::Key_PageUp) },
+ { kPageDownCharCode, QT_MAC_MAP_ENUM(Qt::Key_PageDown) },
+ { kReturnCharCode, QT_MAC_MAP_ENUM(Qt::Key_Return) },
+ { kEscapeCharCode, QT_MAC_MAP_ENUM(Qt::Key_Escape) },
+ { kLeftArrowCharCode, QT_MAC_MAP_ENUM(Qt::Key_Left) },
+ { kRightArrowCharCode, QT_MAC_MAP_ENUM(Qt::Key_Right) },
+ { kUpArrowCharCode, QT_MAC_MAP_ENUM(Qt::Key_Up) },
+ { kDownArrowCharCode, QT_MAC_MAP_ENUM(Qt::Key_Down) },
+ { kHelpCharCode, QT_MAC_MAP_ENUM(Qt::Key_Help) },
+ { kDeleteCharCode, QT_MAC_MAP_ENUM(Qt::Key_Delete) },
+//ascii maps, for debug
+ { ':', QT_MAC_MAP_ENUM(Qt::Key_Colon) },
+ { ';', QT_MAC_MAP_ENUM(Qt::Key_Semicolon) },
+ { '<', QT_MAC_MAP_ENUM(Qt::Key_Less) },
+ { '=', QT_MAC_MAP_ENUM(Qt::Key_Equal) },
+ { '>', QT_MAC_MAP_ENUM(Qt::Key_Greater) },
+ { '?', QT_MAC_MAP_ENUM(Qt::Key_Question) },
+ { '@', QT_MAC_MAP_ENUM(Qt::Key_At) },
+ { ' ', QT_MAC_MAP_ENUM(Qt::Key_Space) },
+ { '!', QT_MAC_MAP_ENUM(Qt::Key_Exclam) },
+ { '"', QT_MAC_MAP_ENUM(Qt::Key_QuoteDbl) },
+ { '#', QT_MAC_MAP_ENUM(Qt::Key_NumberSign) },
+ { '$', QT_MAC_MAP_ENUM(Qt::Key_Dollar) },
+ { '%', QT_MAC_MAP_ENUM(Qt::Key_Percent) },
+ { '&', QT_MAC_MAP_ENUM(Qt::Key_Ampersand) },
+ { '\'', QT_MAC_MAP_ENUM(Qt::Key_Apostrophe) },
+ { '(', QT_MAC_MAP_ENUM(Qt::Key_ParenLeft) },
+ { ')', QT_MAC_MAP_ENUM(Qt::Key_ParenRight) },
+ { '*', QT_MAC_MAP_ENUM(Qt::Key_Asterisk) },
+ { '+', QT_MAC_MAP_ENUM(Qt::Key_Plus) },
+ { ',', QT_MAC_MAP_ENUM(Qt::Key_Comma) },
+ { '-', QT_MAC_MAP_ENUM(Qt::Key_Minus) },
+ { '.', QT_MAC_MAP_ENUM(Qt::Key_Period) },
+ { '/', QT_MAC_MAP_ENUM(Qt::Key_Slash) },
+ { '[', QT_MAC_MAP_ENUM(Qt::Key_BracketLeft) },
+ { ']', QT_MAC_MAP_ENUM(Qt::Key_BracketRight) },
+ { '\\', QT_MAC_MAP_ENUM(Qt::Key_Backslash) },
+ { '_', QT_MAC_MAP_ENUM(Qt::Key_Underscore) },
+ { '`', QT_MAC_MAP_ENUM(Qt::Key_QuoteLeft) },
+ { '{', QT_MAC_MAP_ENUM(Qt::Key_BraceLeft) },
+ { '}', QT_MAC_MAP_ENUM(Qt::Key_BraceRight) },
+ { '|', QT_MAC_MAP_ENUM(Qt::Key_Bar) },
+ { '~', QT_MAC_MAP_ENUM(Qt::Key_AsciiTilde) },
+ { '^', QT_MAC_MAP_ENUM(Qt::Key_AsciiCircum) },
+ { 0, QT_MAC_MAP_ENUM(0) }
+};
+
+static qt_mac_enum_mapper qt_mac_keyvkey_symbols[] = { //real scan codes
+ { 122, QT_MAC_MAP_ENUM(Qt::Key_F1) },
+ { 120, QT_MAC_MAP_ENUM(Qt::Key_F2) },
+ { 99, QT_MAC_MAP_ENUM(Qt::Key_F3) },
+ { 118, QT_MAC_MAP_ENUM(Qt::Key_F4) },
+ { 96, QT_MAC_MAP_ENUM(Qt::Key_F5) },
+ { 97, QT_MAC_MAP_ENUM(Qt::Key_F6) },
+ { 98, QT_MAC_MAP_ENUM(Qt::Key_F7) },
+ { 100, QT_MAC_MAP_ENUM(Qt::Key_F8) },
+ { 101, QT_MAC_MAP_ENUM(Qt::Key_F9) },
+ { 109, QT_MAC_MAP_ENUM(Qt::Key_F10) },
+ { 103, QT_MAC_MAP_ENUM(Qt::Key_F11) },
+ { 111, QT_MAC_MAP_ENUM(Qt::Key_F12) },
+ { 105, QT_MAC_MAP_ENUM(Qt::Key_F13) },
+ { 107, QT_MAC_MAP_ENUM(Qt::Key_F14) },
+ { 113, QT_MAC_MAP_ENUM(Qt::Key_F15) },
+ { 106, QT_MAC_MAP_ENUM(Qt::Key_F16) },
+ { 0, QT_MAC_MAP_ENUM(0) }
+};
+
+static qt_mac_enum_mapper qt_mac_private_unicode[] = {
+ { 0xF700, QT_MAC_MAP_ENUM(Qt::Key_Up) }, //NSUpArrowFunctionKey
+ { 0xF701, QT_MAC_MAP_ENUM(Qt::Key_Down) }, //NSDownArrowFunctionKey
+ { 0xF702, QT_MAC_MAP_ENUM(Qt::Key_Left) }, //NSLeftArrowFunctionKey
+ { 0xF703, QT_MAC_MAP_ENUM(Qt::Key_Right) }, //NSRightArrowFunctionKey
+ { 0xF727, QT_MAC_MAP_ENUM(Qt::Key_Insert) }, //NSInsertFunctionKey
+ { 0xF728, QT_MAC_MAP_ENUM(Qt::Key_Delete) }, //NSDeleteFunctionKey
+ { 0xF729, QT_MAC_MAP_ENUM(Qt::Key_Home) }, //NSHomeFunctionKey
+ { 0xF72B, QT_MAC_MAP_ENUM(Qt::Key_End) }, //NSEndFunctionKey
+ { 0xF72C, QT_MAC_MAP_ENUM(Qt::Key_PageUp) }, //NSPageUpFunctionKey
+ { 0xF72D, QT_MAC_MAP_ENUM(Qt::Key_PageDown) }, //NSPageDownFunctionKey
+ { 0xF72F, QT_MAC_MAP_ENUM(Qt::Key_ScrollLock) }, //NSScrollLockFunctionKey
+ { 0xF730, QT_MAC_MAP_ENUM(Qt::Key_Pause) }, //NSPauseFunctionKey
+ { 0xF731, QT_MAC_MAP_ENUM(Qt::Key_SysReq) }, //NSSysReqFunctionKey
+ { 0xF735, QT_MAC_MAP_ENUM(Qt::Key_Menu) }, //NSMenuFunctionKey
+ { 0xF738, QT_MAC_MAP_ENUM(Qt::Key_Print) }, //NSPrintFunctionKey
+ { 0xF73A, QT_MAC_MAP_ENUM(Qt::Key_Clear) }, //NSClearDisplayFunctionKey
+ { 0xF73D, QT_MAC_MAP_ENUM(Qt::Key_Insert) }, //NSInsertCharFunctionKey
+ { 0xF73E, QT_MAC_MAP_ENUM(Qt::Key_Delete) }, //NSDeleteCharFunctionKey
+ { 0xF741, QT_MAC_MAP_ENUM(Qt::Key_Select) }, //NSSelectFunctionKey
+ { 0xF742, QT_MAC_MAP_ENUM(Qt::Key_Execute) }, //NSExecuteFunctionKey
+ { 0xF746, QT_MAC_MAP_ENUM(Qt::Key_Help) }, //NSHelpFunctionKey
+ { 0xF747, QT_MAC_MAP_ENUM(Qt::Key_Mode_switch) }, //NSModeSwitchFunctionKey
+ { 0, QT_MAC_MAP_ENUM(0) }
+};
+
+static int qt_mac_get_key(int modif, const QChar &key, int virtualKey)
+{
+#ifdef DEBUG_KEY_BINDINGS
+ qDebug("**Mapping key: %d (0x%04x) - %d (0x%04x)", key.unicode(), key.unicode(), virtualKey, virtualKey);
+#endif
+
+ if (key == kClearCharCode && virtualKey == 0x47)
+ return Qt::Key_Clear;
+
+ if (key.isDigit()) {
+#ifdef DEBUG_KEY_BINDINGS
+ qDebug("%d: got key: %d", __LINE__, key.digitValue());
+#endif
+ return key.digitValue() + Qt::Key_0;
+ }
+
+ if (key.isLetter()) {
+#ifdef DEBUG_KEY_BINDINGS
+ qDebug("%d: got key: %d", __LINE__, (key.toUpper().unicode() - 'A'));
+#endif
+ return (key.toUpper().unicode() - 'A') + Qt::Key_A;
+ }
+ if (key.isSymbol()) {
+#ifdef DEBUG_KEY_BINDINGS
+ qDebug("%d: got key: %d", __LINE__, (key.unicode()));
+#endif
+ return key.unicode();
+ }
+
+ for (int i = 0; qt_mac_keyboard_symbols[i].qt_code; i++) {
+ if (qt_mac_keyboard_symbols[i].mac_code == key) {
+ /* To work like Qt for X11 we issue Backtab when Shift + Tab are pressed */
+ if (qt_mac_keyboard_symbols[i].qt_code == Qt::Key_Tab && (modif & Qt::ShiftModifier)) {
+#ifdef DEBUG_KEY_BINDINGS
+ qDebug("%d: got key: Qt::Key_Backtab", __LINE__);
+#endif
+ return Qt::Key_Backtab;
+ }
+
+#ifdef DEBUG_KEY_BINDINGS
+ qDebug("%d: got key: %s", __LINE__, qt_mac_keyboard_symbols[i].desc);
+#endif
+ return qt_mac_keyboard_symbols[i].qt_code;
+ }
+ }
+
+ //last ditch try to match the scan code
+ for (int i = 0; qt_mac_keyvkey_symbols[i].qt_code; i++) {
+ if (qt_mac_keyvkey_symbols[i].mac_code == virtualKey) {
+#ifdef DEBUG_KEY_BINDINGS
+ qDebug("%d: got key: %s", __LINE__, qt_mac_keyvkey_symbols[i].desc);
+#endif
+ return qt_mac_keyvkey_symbols[i].qt_code;
+ }
+ }
+
+ // check if they belong to key codes in private unicode range
+ if (key >= 0xf700 && key <= 0xf747) {
+ if (key >= 0xf704 && key <= 0xf726) {
+ return Qt::Key_F1 + (key.unicode() - 0xf704) ;
+ }
+ for (int i = 0; qt_mac_private_unicode[i].qt_code; i++) {
+ if (qt_mac_private_unicode[i].mac_code == key) {
+ return qt_mac_private_unicode[i].qt_code;
+ }
+ }
+
+ }
+
+ //oh well
+#ifdef DEBUG_KEY_BINDINGS
+ qDebug("Unknown case.. %s:%d %d[%d] %d", __FILE__, __LINE__, key.unicode(), key.toLatin1(), virtualKey);
+#endif
+ return Qt::Key_unknown;
+}
+
+static Boolean qt_KeyEventComparatorProc(EventRef inEvent, void *data)
+{
+ UInt32 ekind = GetEventKind(inEvent),
+ eclass = GetEventClass(inEvent);
+ return (eclass == kEventClassKeyboard && (void *)ekind == data);
+}
+
+static bool translateKeyEventInternal(EventHandlerCallRef er, EventRef keyEvent, int *qtKey,
+ QChar *outChar, Qt::KeyboardModifiers *outModifiers, bool *outHandled)
+{
+#if !defined(QT_MAC_USE_COCOA) || defined(Q_OS_MAC64)
+ Q_UNUSED(er);
+ Q_UNUSED(outHandled);
+#endif
+ const UInt32 ekind = GetEventKind(keyEvent);
+ {
+ UInt32 mac_modifiers = 0;
+ GetEventParameter(keyEvent, kEventParamKeyModifiers, typeUInt32, 0,
+ sizeof(mac_modifiers), 0, &mac_modifiers);
+#ifdef DEBUG_KEY_BINDINGS_MODIFIERS
+ qDebug("************ Mapping modifiers and key ***********");
+#endif
+ *outModifiers = qt_mac_get_modifiers(mac_modifiers);
+#ifdef DEBUG_KEY_BINDINGS_MODIFIERS
+ qDebug("------------ Mapping modifiers and key -----------");
+#endif
+ }
+
+ //get keycode
+ UInt32 keyCode = 0;
+ GetEventParameter(keyEvent, kEventParamKeyCode, typeUInt32, 0, sizeof(keyCode), 0, &keyCode);
+
+ //get mac mapping
+ static UInt32 tmp_unused_state = 0L;
+ const UCKeyboardLayout *uchrData = 0;
+#if defined(Q_OS_MAC32)
+ KeyboardLayoutRef keyLayoutRef = 0;
+ KLGetCurrentKeyboardLayout(&keyLayoutRef);
+ OSStatus err;
+ if (keyLayoutRef != 0) {
+ err = KLGetKeyboardLayoutProperty(keyLayoutRef, kKLuchrData,
+ (reinterpret_cast<const void **>(&uchrData)));
+ if (err != noErr) {
+ qWarning("Qt::internal::unable to get keyboardlayout %ld %s:%d",
+ long(err), __FILE__, __LINE__);
+ }
+ }
+#else
+ QCFType<TISInputSourceRef> inputSource = TISCopyCurrentKeyboardInputSource();
+ Q_ASSERT(inputSource != 0);
+ CFDataRef data = static_cast<CFDataRef>(TISGetInputSourceProperty(inputSource,
+ kTISPropertyUnicodeKeyLayoutData));
+ uchrData = data ? reinterpret_cast<const UCKeyboardLayout *>(CFDataGetBytePtr(data)) : 0;
+#endif
+ *qtKey = Qt::Key_unknown;
+ if (uchrData) {
+ // The easy stuff; use the unicode stuff!
+ UniChar string[4];
+ UniCharCount actualLength;
+ UInt32 currentModifiers = GetCurrentEventKeyModifiers();
+ UInt32 currentModifiersWOAltOrControl = currentModifiers & ~(controlKey | optionKey);
+ int keyAction;
+ switch (ekind) {
+ default:
+ case kEventRawKeyDown:
+ keyAction = kUCKeyActionDown;
+ break;
+ case kEventRawKeyUp:
+ keyAction = kUCKeyActionUp;
+ break;
+ case kEventRawKeyRepeat:
+ keyAction = kUCKeyActionAutoKey;
+ break;
+ }
+ OSStatus err = UCKeyTranslate(uchrData, keyCode, keyAction,
+ ((currentModifiersWOAltOrControl >> 8) & 0xff), LMGetKbdType(),
+ kUCKeyTranslateNoDeadKeysMask, &tmp_unused_state, 4, &actualLength,
+ string);
+ if (err == noErr) {
+ *outChar = QChar(string[0]);
+ *qtKey = qt_mac_get_key(*outModifiers, *outChar, keyCode);
+ if (currentModifiersWOAltOrControl != currentModifiers) {
+ // Now get the real char.
+ err = UCKeyTranslate(uchrData, keyCode, keyAction,
+ ((currentModifiers >> 8) & 0xff), LMGetKbdType(),
+ kUCKeyTranslateNoDeadKeysMask, &tmp_unused_state, 4, &actualLength,
+ string);
+ if (err == noErr)
+ *outChar = QChar(string[0]);
+ }
+ } else {
+ qWarning("Qt::internal::UCKeyTranslate is returnining %ld %s:%d",
+ long(err), __FILE__, __LINE__);
+ }
+ }
+#ifdef Q_OS_MAC32
+ else {
+ // The road less travelled; use KeyTranslate
+ const void *keyboard_layout;
+ KeyboardLayoutRef keyLayoutRef = 0;
+ KLGetCurrentKeyboardLayout(&keyLayoutRef);
+ err = KLGetKeyboardLayoutProperty(keyLayoutRef, kKLKCHRData,
+ reinterpret_cast<const void **>(&keyboard_layout));
+
+ int translatedChar = KeyTranslate(keyboard_layout, (GetCurrentEventKeyModifiers() &
+ (kEventKeyModifierNumLockMask|shiftKey|cmdKey|
+ rightShiftKey|alphaLock)) | keyCode,
+ &tmp_unused_state);
+ if (!translatedChar) {
+#ifdef QT_MAC_USE_COCOA
+ if (outHandled) {
+ qt_mac_eat_unicode_key = false;
+ if (er)
+ CallNextEventHandler(er, keyEvent);
+ *outHandled = qt_mac_eat_unicode_key;
+ }
+#endif
+ return false;
+ }
+
+ //map it into qt keys
+ *qtKey = qt_mac_get_key(*outModifiers, QChar(translatedChar), keyCode);
+ if (*outModifiers & (Qt::AltModifier | Qt::ControlModifier)) {
+ if (translatedChar & (1 << 7)) //high ascii
+ translatedChar = 0;
+ } else { //now get the real ascii value
+ UInt32 tmp_mod = 0L;
+ static UInt32 tmp_state = 0L;
+ if (*outModifiers & Qt::ShiftModifier)
+ tmp_mod |= shiftKey;
+ if (*outModifiers & Qt::MetaModifier)
+ tmp_mod |= controlKey;
+ if (*outModifiers & Qt::ControlModifier)
+ tmp_mod |= cmdKey;
+ if (GetCurrentEventKeyModifiers() & alphaLock) //no Qt mapper
+ tmp_mod |= alphaLock;
+ if (*outModifiers & Qt::AltModifier)
+ tmp_mod |= optionKey;
+ if (*outModifiers & Qt::KeypadModifier)
+ tmp_mod |= kEventKeyModifierNumLockMask;
+ translatedChar = KeyTranslate(keyboard_layout, tmp_mod | keyCode, &tmp_state);
+ }
+ {
+ ByteCount unilen = 0;
+ if (GetEventParameter(keyEvent, kEventParamKeyUnicodes, typeUnicodeText, 0, 0, &unilen, 0)
+ == noErr && unilen == 2) {
+ GetEventParameter(keyEvent, kEventParamKeyUnicodes, typeUnicodeText, 0, unilen, 0, outChar);
+ } else if (translatedChar) {
+ static QTextCodec *c = 0;
+ if (!c)
+ c = QTextCodec::codecForName("Apple Roman");
+ char tmpChar = (char)translatedChar; // **sigh**
+ *outChar = c->toUnicode(&tmpChar, 1).at(0);
+ } else {
+ *qtKey = qt_mac_get_key(*outModifiers, QChar(translatedChar), keyCode);
+ }
+ }
+ }
+#endif
+ if (*qtKey == Qt::Key_unknown)
+ *qtKey = qt_mac_get_key(*outModifiers, *outChar, keyCode);
+ return true;
+}
+
+QKeyMapperPrivate::QKeyMapperPrivate()
+{
+ memset(keyLayout, 0, sizeof(keyLayout));
+ keyboard_layout_format.unicode = 0;
+#ifdef Q_OS_MAC32
+ keyboard_mode = NullMode;
+#else
+ currentInputSource = 0;
+#endif
+}
+
+QKeyMapperPrivate::~QKeyMapperPrivate()
+{
+ deleteLayouts();
+}
+
+bool
+QKeyMapperPrivate::updateKeyboard()
+{
+ const UCKeyboardLayout *uchrData = 0;
+#ifdef Q_OS_MAC32
+ KeyboardLayoutRef keyLayoutRef = 0;
+ KLGetCurrentKeyboardLayout(&keyLayoutRef);
+
+ if (keyboard_mode != NullMode && currentKeyboardLayout == keyLayoutRef)
+ return false;
+
+ OSStatus err;
+ if (keyLayoutRef != 0) {
+ err = KLGetKeyboardLayoutProperty(keyLayoutRef, kKLuchrData,
+ const_cast<const void **>(reinterpret_cast<const void **>(&uchrData)));
+ if (err != noErr) {
+ qWarning("Qt::internal::unable to get unicode keyboardlayout %ld %s:%d",
+ long(err), __FILE__, __LINE__);
+ }
+ }
+#else
+ QCFType<TISInputSourceRef> source = TISCopyCurrentKeyboardInputSource();
+ if (keyboard_mode != NullMode && source == currentInputSource) {
+ return false;
+ }
+ Q_ASSERT(source != 0);
+ CFDataRef data = static_cast<CFDataRef>(TISGetInputSourceProperty(source,
+ kTISPropertyUnicodeKeyLayoutData));
+ uchrData = data ? reinterpret_cast<const UCKeyboardLayout *>(CFDataGetBytePtr(data)) : 0;
+#endif
+
+ keyboard_kind = LMGetKbdType();
+ if (uchrData) {
+ keyboard_layout_format.unicode = uchrData;
+ keyboard_mode = UnicodeMode;
+ }
+#ifdef Q_OS_MAC32
+ else {
+ void *happy;
+ err = KLGetKeyboardLayoutProperty(keyLayoutRef, kKLKCHRData,
+ const_cast<const void **>(reinterpret_cast<void **>(&happy)));
+ if (err != noErr) {
+ qFatal("Qt::internal::unable to get non-unicode layout, cannot procede %ld %s:%d",
+ long(err), __FILE__, __LINE__);
+ }
+ keyboard_layout_format.other = happy;
+ keyboard_mode = OtherMode;
+ }
+
+ currentKeyboardLayout = keyLayoutRef;
+#else
+ currentInputSource = source;
+#endif
+ keyboard_dead = 0;
+ CFStringRef iso639Code;
+#ifdef Q_OS_MAC32
+# ifndef kKLLanguageCode
+# define kKLLanguageCode 9
+# endif
+ KLGetKeyboardLayoutProperty(currentKeyboardLayout, kKLLanguageCode,
+ reinterpret_cast<const void **>(&iso639Code));
+#else
+ CFArrayRef array = static_cast<CFArrayRef>(TISGetInputSourceProperty(currentInputSource, kTISPropertyInputSourceLanguages));
+ iso639Code = static_cast<CFStringRef>(CFArrayGetValueAtIndex(array, 0)); // Actually a RFC3066bis, but it's close enough
+#endif
+ if (iso639Code) {
+ keyboardInputLocale = QLocale(QCFString::toQString(iso639Code));
+ keyboardInputDirection = keyboardInputLocale.textDirection();
+ } else {
+ keyboardInputLocale = QLocale::c();
+ keyboardInputDirection = Qt::LeftToRight;
+ }
+ return true;
+}
+
+void
+QKeyMapperPrivate::deleteLayouts()
+{
+ keyboard_mode = NullMode;
+ for (int i = 0; i < 255; ++i) {
+ if (keyLayout[i]) {
+ delete keyLayout[i];
+ keyLayout[i] = 0;
+ }
+ }
+}
+
+void
+QKeyMapperPrivate::clearMappings()
+{
+ deleteLayouts();
+ updateKeyboard();
+}
+
+QList<int>
+QKeyMapperPrivate::possibleKeys(QKeyEvent *e)
+{
+ QList<int> ret;
+
+ KeyboardLayoutItem *kbItem = keyLayout[e->nativeVirtualKey()];
+ if (!kbItem) // Key is not in any keyboard layout (e.g. eisu-key on Japanese keyboard)
+ return ret;
+
+ int baseKey = kbItem->qtKey[0];
+ Qt::KeyboardModifiers keyMods = e->modifiers();
+ ret << int(baseKey + keyMods); // The base key is _always_ valid, of course
+
+ for (int i = 1; i < 8; ++i) {
+ Qt::KeyboardModifiers neededMods = ModsTbl[i];
+ int key = kbItem->qtKey[i];
+ if (key && key != baseKey && ((keyMods & neededMods) == neededMods))
+ ret << int(key + (keyMods & ~neededMods));
+ }
+
+ return ret;
+}
+
+bool QKeyMapperPrivate::translateKeyEvent(QWidget *widget, EventHandlerCallRef er, EventRef event,
+ void *info, bool grab)
+{
+ Q_ASSERT(GetEventClass(event) == kEventClassKeyboard);
+ bool handled_event=true;
+ UInt32 ekind = GetEventKind(event);
+
+ // unfortunately modifiers changed event looks quite different, so I have a separate
+ // code path
+ if (ekind == kEventRawKeyModifiersChanged) {
+ //figure out changed modifiers, wish Apple would just send a delta
+ UInt32 modifiers = 0;
+ GetEventParameter(event, kEventParamKeyModifiers, typeUInt32, 0,
+ sizeof(modifiers), 0, &modifiers);
+ qt_mac_send_modifiers_changed(modifiers, widget);
+ return true;
+ }
+
+ QInputContext *currentContext = qApp->inputContext();
+ if (currentContext && currentContext->isComposing()) {
+ if (ekind == kEventRawKeyDown) {
+ QMacInputContext *context = qobject_cast<QMacInputContext*>(currentContext);
+ if (context)
+ context->setLastKeydownEvent(event);
+ }
+ return false;
+ }
+ // Once we process the key down , we don't need to send the saved event again from
+ // kEventTextInputUnicodeForKeyEvent, so clear it.
+ if (currentContext && ekind == kEventRawKeyDown) {
+ QMacInputContext *context = qobject_cast<QMacInputContext*>(currentContext);
+ if (context)
+ context->setLastKeydownEvent(0);
+ }
+
+ //get modifiers
+ Qt::KeyboardModifiers modifiers;
+ int qtKey;
+ QChar ourChar;
+ if (translateKeyEventInternal(er, event, &qtKey, &ourChar, &modifiers,
+ &handled_event) == false)
+ return handled_event;
+ QString text(ourChar);
+ /* This is actually wrong - but unfortunately it is the best that can be
+ done for now because of the Control/Meta mapping problems */
+ if (modifiers & (Qt::ControlModifier | Qt::MetaModifier)
+ && !qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)) {
+ text = QString();
+ }
+
+
+ if (widget) {
+#ifndef QT_MAC_USE_COCOA
+ Q_UNUSED(info);
+ // Try not to call "other" event handlers if we have a popup,
+ // However, if the key has text
+ // then we should pass it along because otherwise then people
+ // can use input method stuff.
+ if (!qApp->activePopupWidget()
+ || (qApp->activePopupWidget() && !text.isEmpty())) {
+ //Find out if someone else wants the event, namely
+ //is it of use to text services? If so we won't bother
+ //with a QKeyEvent.
+ qt_mac_eat_unicode_key = false;
+ if (er)
+ CallNextEventHandler(er, event);
+ extern bool qt_mac_menubar_is_open();
+ if (qt_mac_eat_unicode_key || qt_mac_menubar_is_open()) {
+ return true;
+ }
+ }
+#endif
+ // Try to compress key events.
+ if (!text.isEmpty() && widget->testAttribute(Qt::WA_KeyCompression)) {
+ EventTime lastTime = GetEventTime(event);
+ for (;;) {
+ EventRef releaseEvent = FindSpecificEventInQueue(GetMainEventQueue(),
+ qt_KeyEventComparatorProc,
+ (void*)kEventRawKeyUp);
+ if (!releaseEvent)
+ break;
+ const EventTime releaseTime = GetEventTime(releaseEvent);
+ if (releaseTime < lastTime)
+ break;
+ lastTime = releaseTime;
+
+ EventRef pressEvent = FindSpecificEventInQueue(GetMainEventQueue(),
+ qt_KeyEventComparatorProc,
+ (void*)kEventRawKeyDown);
+ if (!pressEvent)
+ break;
+ const EventTime pressTime = GetEventTime(pressEvent);
+ if (pressTime < lastTime)
+ break;
+ lastTime = pressTime;
+
+ Qt::KeyboardModifiers compressMod;
+ int compressQtKey = 0;
+ QChar compressChar;
+ if (translateKeyEventInternal(er, pressEvent,
+ &compressQtKey, &compressChar, &compressMod, 0)
+ == false) {
+ break;
+ }
+ // Copied from qapplication_x11.cpp (change both).
+
+ bool stopCompression =
+ // 1) misc keys
+ (compressQtKey >= Qt::Key_Escape && compressQtKey <= Qt::Key_SysReq)
+ // 2) cursor movement
+ || (compressQtKey >= Qt::Key_Home && compressQtKey <= Qt::Key_PageDown)
+ // 3) extra keys
+ || (compressQtKey >= Qt::Key_Super_L && compressQtKey <= Qt::Key_Direction_R)
+ // 4) something that a) doesn't translate to text or b) translates
+ // to newline text
+ || (compressQtKey == 0)
+ || (compressChar == QLatin1Char('\n'))
+ || (compressQtKey == Qt::Key_unknown);
+
+ if (compressMod == modifiers && !compressChar.isNull() && !stopCompression) {
+#ifdef DEBUG_KEY_BINDINGS
+ qDebug("compressing away %c", compressChar.toLatin1());
+#endif
+ text += compressChar;
+ // Clean up
+ RemoveEventFromQueue(GetMainEventQueue(), releaseEvent);
+ RemoveEventFromQueue(GetMainEventQueue(), pressEvent);
+ } else {
+#ifdef DEBUG_KEY_BINDINGS
+ qDebug("stoping compression..");
+#endif
+ break;
+ }
+ }
+ }
+
+ // There is no way to get the scan code from carbon. But we cannot use the value 0, since
+ // it indicates that the event originates from somewhere else than the keyboard
+ UInt32 macScanCode = 1;
+ UInt32 macVirtualKey = 0;
+ GetEventParameter(event, kEventParamKeyCode, typeUInt32, 0, sizeof(macVirtualKey), 0, &macVirtualKey);
+ UInt32 macModifiers = 0;
+ GetEventParameter(event, kEventParamKeyModifiers, typeUInt32, 0,
+ sizeof(macModifiers), 0, &macModifiers);
+#ifdef QT_MAC_USE_COCOA
+ // The unicode characters in the range 0xF700-0xF747 are reserved
+ // by Mac OS X for transient use as keyboard function keys. We
+ // wont send 'text' for such key events. This is done to match
+ // behavior on other platforms.
+ unsigned int *unicodeKey = (unsigned int*)info;
+ if (*unicodeKey >= 0xf700 && *unicodeKey <= 0xf747)
+ text = QString();
+ bool isAccepted;
+#endif
+ handled_event = QKeyMapper::sendKeyEvent(widget, grab,
+ (ekind == kEventRawKeyUp) ? QEvent::KeyRelease : QEvent::KeyPress,
+ qtKey, modifiers, text, ekind == kEventRawKeyRepeat, 0,
+ macScanCode, macVirtualKey, macModifiers
+#ifdef QT_MAC_USE_COCOA
+ ,&isAccepted
+#endif
+ );
+#ifdef QT_MAC_USE_COCOA
+ *unicodeKey = (unsigned int)isAccepted;
+#endif
+ }
+ return handled_event;
+}
+
+void
+QKeyMapperPrivate::updateKeyMap(EventHandlerCallRef, EventRef event, void *
+#if defined(QT_MAC_USE_COCOA)
+ unicodeKey // unicode character from NSEvent (modifiers applied)
+#endif
+ )
+{
+ UInt32 macVirtualKey = 0;
+ GetEventParameter(event, kEventParamKeyCode, typeUInt32, 0, sizeof(macVirtualKey), 0, &macVirtualKey);
+ if (updateKeyboard())
+ QKeyMapper::changeKeyboard();
+ else if (keyLayout[macVirtualKey])
+ return;
+
+ UniCharCount buffer_size = 10;
+ UniChar buffer[buffer_size];
+ keyLayout[macVirtualKey] = new KeyboardLayoutItem;
+ for (int i = 0; i < 16; ++i) {
+ UniCharCount out_buffer_size = 0;
+ keyLayout[macVirtualKey]->qtKey[i] = 0;
+#ifdef Q_WS_MAC32
+ if (keyboard_mode == UnicodeMode) {
+#endif
+ const UInt32 keyModifier = ((qt_mac_get_mac_modifiers(ModsTbl[i]) >> 8) & 0xFF);
+ OSStatus err = UCKeyTranslate(keyboard_layout_format.unicode, macVirtualKey, kUCKeyActionDown, keyModifier,
+ keyboard_kind, 0, &keyboard_dead, buffer_size, &out_buffer_size, buffer);
+ if (err == noErr && out_buffer_size) {
+ const QChar unicode(buffer[0]);
+ int qtkey = qt_mac_get_key(keyModifier, unicode, macVirtualKey);
+ if (qtkey == Qt::Key_unknown)
+ qtkey = unicode.unicode();
+ keyLayout[macVirtualKey]->qtKey[i] = qtkey;
+ }
+#ifndef Q_WS_MAC32
+ else {
+ const QChar unicode(*((UniChar *)unicodeKey));
+ int qtkey = qt_mac_get_key(keyModifier, unicode, macVirtualKey);
+ if (qtkey == Qt::Key_unknown)
+ qtkey = unicode.unicode();
+ keyLayout[macVirtualKey]->qtKey[i] = qtkey;
+ }
+#endif
+#ifdef Q_WS_MAC32
+ } else {
+ const UInt32 keyModifier = (qt_mac_get_mac_modifiers(ModsTbl[i]));
+
+ uchar translatedChar = KeyTranslate(keyboard_layout_format.other, keyModifier | macVirtualKey, &keyboard_dead);
+ if (translatedChar) {
+ static QTextCodec *c = 0;
+ if (!c)
+ c = QTextCodec::codecForName("Apple Roman");
+ const QChar unicode(c->toUnicode((const char *)&translatedChar, 1).at(0));
+ int qtkey = qt_mac_get_key(keyModifier, unicode, macVirtualKey);
+ if (qtkey == Qt::Key_unknown)
+ qtkey = unicode.unicode();
+ keyLayout[macVirtualKey]->qtKey[i] = qtkey;
+ }
+ }
+#endif
+ }
+#ifdef DEBUG_KEY_MAPS
+ qDebug("updateKeyMap for virtual key = 0x%02x!", (uint)macVirtualKey);
+ for (int i = 0; i < 16; ++i) {
+ qDebug(" [%d] (%d,0x%02x,'%c')", i,
+ keyLayout[macVirtualKey]->qtKey[i],
+ keyLayout[macVirtualKey]->qtKey[i],
+ keyLayout[macVirtualKey]->qtKey[i]);
+ }
+#endif
+}
+
+bool
+QKeyMapper::sendKeyEvent(QWidget *widget, bool grab,
+ QEvent::Type type, int code, Qt::KeyboardModifiers modifiers,
+ const QString &text, bool autorepeat, int count,
+ quint32 nativeScanCode, quint32 nativeVirtualKey,
+ quint32 nativeModifiers, bool *isAccepted)
+{
+ Q_UNUSED(count);
+ if (widget && widget->isEnabled()) {
+ bool key_event = true;
+#if defined(QT3_SUPPORT) && !defined(QT_NO_SHORTCUT)
+ if (type == QEvent::KeyPress && !grab
+ && QApplicationPrivate::instance()->use_compat()) {
+ QKeyEventEx accel_ev(type, code, modifiers,
+ text, autorepeat, qMax(1, int(text.length())),
+ nativeScanCode, nativeVirtualKey, nativeModifiers);
+ if (QApplicationPrivate::instance()->qt_tryAccelEvent(widget, &accel_ev)) {
+#if defined(DEBUG_KEY_BINDINGS) || defined(DEBUG_KEY_BINDINGS_MODIFIERS)
+ qDebug("KeyEvent: %s::%s consumed Accel: %s",
+ widget ? widget->metaObject()->className() : "none",
+ widget ? widget->objectName().toLatin1().constData() : "",
+ text.toLatin1().constData());
+#endif
+ key_event = false;
+ } else {
+ if (accel_ev.isAccepted()) {
+#if defined(DEBUG_KEY_BINDINGS) || defined(DEBUG_KEY_BINDINGS_MODIFIERS)
+ qDebug("KeyEvent: %s::%s overrode Accel: %s",
+ widget ? widget->metaObject()->className() : "none",
+ widget ? widget->objectName().toLatin1().constData() : "",
+ text.toLatin1().constData());
+#endif
+ }
+ }
+ }
+#else
+Q_UNUSED(grab);
+#endif // QT3_SUPPORT && !QT_NO_SHORTCUT
+ if (key_event) {
+#if defined(DEBUG_KEY_BINDINGS) || defined(DEBUG_KEY_BINDINGS_MODIFIERS)
+ qDebug("KeyEvent: Sending %s to %s::%s: %s 0x%08x%s",
+ type == QEvent::KeyRelease ? "KeyRelease" : "KeyPress",
+ widget ? widget->metaObject()->className() : "none",
+ widget ? widget->objectName().toLatin1().constData() : "",
+ text.toLatin1().constData(), int(modifiers),
+ autorepeat ? " Repeat" : "");
+#endif
+ QKeyEventEx ke(type, code, modifiers, text, autorepeat, qMax(1, text.length()),
+ nativeScanCode, nativeVirtualKey, nativeModifiers);
+ bool retMe = qt_sendSpontaneousEvent(widget,&ke);
+ if (isAccepted)
+ *isAccepted = ke.isAccepted();
+ return retMe;
+ }
+ }
+ return false;
+}
+
+QT_END_NAMESPACE
diff --git a/src/widgets/platforms/mac/qmacdefines_mac.h b/src/widgets/platforms/mac/qmacdefines_mac.h
new file mode 100644
index 0000000000..d0accf872f
--- /dev/null
+++ b/src/widgets/platforms/mac/qmacdefines_mac.h
@@ -0,0 +1,158 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/****************************************************************************
+**
+** Copyright (c) 2007-2008, Apple, Inc.
+**
+** All rights reserved.
+**
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are met:
+**
+** * Redistributions of source code must retain the above copyright notice,
+** this list of conditions and the following disclaimer.
+**
+** * Redistributions in binary form must reproduce the above copyright notice,
+** this list of conditions and the following disclaimer in the documentation
+** and/or other materials provided with the distribution.
+**
+** * Neither the name of Apple, Inc. nor the names of its contributors
+** may be used to endorse or promote products derived from this software
+** without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+**
+****************************************************************************/
+
+/*
+ * qmacdefines_mac_p.h
+ * All the defines you'll ever need for Qt/Mac :-)
+ */
+
+/* This is just many defines. Therefore it doesn't need things like:
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+Yes, it is an informative comment ;-)
+*/
+
+#include <QtCore/qglobal.h>
+
+#ifdef qDebug
+# define old_qDebug qDebug
+# undef qDebug
+#endif
+
+#ifdef __LP64__
+typedef signed int OSStatus;
+#else
+typedef signed long OSStatus;
+#endif
+
+#ifdef __OBJC__
+# ifdef slots
+# define old_slots slots
+# undef slots
+# endif
+#include <Cocoa/Cocoa.h>
+# ifdef old_slots
+# undef slots
+# define slots
+# undef old_slots
+# endif
+#endif
+ typedef struct OpaqueEventHandlerCallRef * EventHandlerCallRef;
+ typedef struct OpaqueEventRef * EventRef;
+ typedef struct OpaqueMenuRef * MenuRef;
+ typedef struct OpaquePasteboardRef* PasteboardRef;
+ typedef struct OpaqueRgnHandle * RgnHandle;
+ typedef const struct __HIShape *HIShapeRef;
+ typedef struct __HIShape *HIMutableShapeRef;
+ typedef struct CGRect CGRect;
+ typedef struct CGImage *CGImageRef;
+ typedef struct CGContext *CGContextRef;
+ typedef struct GDevice * GDPtr;
+ typedef GDPtr * GDHandle;
+ typedef struct OpaqueIconRef * IconRef;
+# ifdef __OBJC__
+ typedef NSWindow* OSWindowRef;
+ typedef NSView *OSViewRef;
+ typedef NSMenu *OSMenuRef;
+ typedef NSEvent *OSEventRef;
+# else
+ typedef void *OSWindowRef;
+ typedef void *OSViewRef;
+ typedef void *OSMenuRef;
+ typedef void *OSEventRef;
+# endif
+
+typedef PasteboardRef OSPasteboardRef;
+typedef struct AEDesc AEDescList;
+typedef AEDescList AERecord;
+typedef AERecord AppleEvent;
+
+#ifdef check
+#undef check
+#endif
+
+#ifdef old_qDebug
+# undef qDebug
+# define qDebug QT_NO_QDEBUG_MACRO
+# undef old_qDebug
+#endif
diff --git a/src/gui/kernel/qmacgesturerecognizer_mac.mm b/src/widgets/platforms/mac/qmacgesturerecognizer_mac.mm
index 321f4fd38e..321f4fd38e 100644
--- a/src/gui/kernel/qmacgesturerecognizer_mac.mm
+++ b/src/widgets/platforms/mac/qmacgesturerecognizer_mac.mm
diff --git a/src/gui/kernel/qmacgesturerecognizer_mac_p.h b/src/widgets/platforms/mac/qmacgesturerecognizer_mac_p.h
index f6f207336d..f6f207336d 100644
--- a/src/gui/kernel/qmacgesturerecognizer_mac_p.h
+++ b/src/widgets/platforms/mac/qmacgesturerecognizer_mac_p.h
diff --git a/src/gui/inputmethod/qmacinputcontext_mac.cpp b/src/widgets/platforms/mac/qmacinputcontext_mac.cpp
index a98cee714b..a98cee714b 100644
--- a/src/gui/inputmethod/qmacinputcontext_mac.cpp
+++ b/src/widgets/platforms/mac/qmacinputcontext_mac.cpp
diff --git a/src/widgets/platforms/mac/qmacinputcontext_p.h b/src/widgets/platforms/mac/qmacinputcontext_p.h
new file mode 100644
index 0000000000..4fb3eb57b6
--- /dev/null
+++ b/src/widgets/platforms/mac/qmacinputcontext_p.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMACINPUTCONTEXT_P_H
+#define QMACINPUTCONTEXT_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "QtWidgets/qinputcontext.h"
+#include "private/qt_mac_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class Q_WIDGETS_EXPORT QMacInputContext : public QInputContext
+{
+ Q_OBJECT
+ //Q_DECLARE_PRIVATE(QMacInputContext)
+ void createTextDocument();
+public:
+ explicit QMacInputContext(QObject* parent = 0);
+ virtual ~QMacInputContext();
+
+ virtual void setFocusWidget(QWidget *w);
+ virtual QString identifierName() { return QLatin1String("mac"); }
+ virtual QString language();
+
+ virtual void reset();
+
+ virtual bool isComposing() const;
+
+ static OSStatus globalEventProcessor(EventHandlerCallRef, EventRef, void *);
+ static void initialize();
+ static void cleanup();
+
+ EventRef lastKeydownEvent() { return keydownEvent; }
+ void setLastKeydownEvent(EventRef);
+
+protected:
+ void mouseHandler(int pos, QMouseEvent *);
+private:
+ bool composing;
+ bool recursionGuard;
+ TSMDocumentID textDocument;
+ QString currentText;
+ EventRef keydownEvent;
+};
+
+QT_END_NAMESPACE
+
+#endif // QMACINPUTCONTEXT_P_H
diff --git a/src/widgets/platforms/mac/qmime_mac.cpp b/src/widgets/platforms/mac/qmime_mac.cpp
new file mode 100644
index 0000000000..0eaaaa8f2a
--- /dev/null
+++ b/src/widgets/platforms/mac/qmime_mac.cpp
@@ -0,0 +1,1310 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmime.h"
+
+//#define USE_INTERNET_CONFIG
+
+#ifndef USE_INTERNET_CONFIG
+# include "qfile.h"
+# include "qfileinfo.h"
+# include "qtextstream.h"
+# include "qdir.h"
+# include <unistd.h>
+# include <sys/types.h>
+# include <sys/stat.h>
+# include <sys/fcntl.h>
+#endif
+
+#include "qdebug.h"
+#include "qpixmap.h"
+#include "qimagewriter.h"
+#include "qimagereader.h"
+#include "qdatastream.h"
+#include "qbuffer.h"
+#include "qdatetime.h"
+#include "qapplication_p.h"
+#include "qtextcodec.h"
+#include "qregexp.h"
+#include "qurl.h"
+#include "qmap.h"
+#include <private/qt_mac_p.h>
+
+
+#ifdef Q_WS_MAC32
+#include <QuickTime/QuickTime.h>
+#include <qlibrary.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+extern CGImageRef qt_mac_createCGImageFromQImage(const QImage &img, const QImage **imagePtr = 0); // qpaintengine_mac.cpp
+
+typedef QList<QMacPasteboardMime*> MimeList;
+Q_GLOBAL_STATIC(MimeList, globalMimeList)
+
+static void cleanup_mimes()
+{
+ MimeList *mimes = globalMimeList();
+ while (!mimes->isEmpty())
+ delete mimes->takeFirst();
+}
+
+Q_GLOBAL_STATIC(QStringList, globalDraggedTypesList)
+
+/*!
+ \fn void qRegisterDraggedTypes(const QStringList &types)
+ \relates QMacPasteboardMime
+
+ Registers the given \a types as custom pasteboard types.
+
+ This function should be called to enable the Drag and Drop events
+ for custom pasteboard types on Cocoa implementations. This is required
+ in addition to a QMacPasteboardMime subclass implementation. By default
+ drag and drop is enabled for all standard pasteboard types.
+
+ \sa QMacPasteboardMime
+*/
+Q_WIDGETS_EXPORT void qRegisterDraggedTypes(const QStringList &types)
+{
+ (*globalDraggedTypesList()) += types;
+}
+
+const QStringList& qEnabledDraggedTypes()
+{
+ return (*globalDraggedTypesList());
+}
+
+
+/*****************************************************************************
+ QDnD debug facilities
+ *****************************************************************************/
+//#define DEBUG_MIME_MAPS
+
+//functions
+extern QString qt_mac_from_pascal_string(const Str255); //qglobal.cpp
+extern void qt_mac_from_pascal_string(QString, Str255, TextEncoding encoding=0, int len=-1); //qglobal.cpp
+
+ScrapFlavorType qt_mac_mime_type = 'CUTE';
+CFStringRef qt_mac_mime_typeUTI = CFSTR("com.pasteboard.trolltech.marker");
+
+/*!
+ \class QMacPasteboardMime
+ \brief The QMacPasteboardMime class converts between a MIME type and a
+ \l{http://developer.apple.com/macosx/uniformtypeidentifiers.html}{Uniform
+ Type Identifier (UTI)} format.
+ \since 4.2
+
+ \ingroup draganddrop
+
+ Qt's drag and drop and clipboard facilities use the MIME
+ standard. On X11, this maps trivially to the Xdnd protocol. On
+ Mac, although some applications use MIME to describe clipboard
+ contents, it is more common to use Apple's UTI format.
+
+ QMacPasteboardMime's role is to bridge the gap between MIME and UTI;
+ By subclasses this class, one can extend Qt's drag and drop
+ and clipboard handling to convert to and from unsupported, or proprietary, UTI formats.
+
+ A subclass of QMacPasteboardMime will automatically be registered, and active, upon instantiation.
+
+ Qt has predefined support for the following UTIs:
+ \list
+ \i public.utf8-plain-text - converts to "text/plain"
+ \i public.utf16-plain-text - converts to "text/plain"
+ \i public.html - converts to "text/html"
+ \i public.url - converts to "text/uri-list"
+ \i public.file-url - converts to "text/uri-list"
+ \i public.tiff - converts to "application/x-qt-image"
+ \i public.vcard - converts to "text/plain"
+ \i com.apple.traditional-mac-plain-text - converts to "text/plain"
+ \i com.apple.pict - converts to "application/x-qt-image"
+ \endlist
+
+ When working with MIME data, Qt will interate through all instances of QMacPasteboardMime to
+ find an instance that can convert to, or from, a specific MIME type. It will do this by calling
+ canConvert() on each instance, starting with (and choosing) the last created instance first.
+ The actual conversions will be done by using convertToMime() and convertFromMime().
+
+ \note The API uses the term "flavor" in some cases. This is for backwards
+ compatibility reasons, and should now be understood as UTIs.
+*/
+
+/*! \enum QMacPasteboardMime::QMacPasteboardMimeType
+ \internal
+*/
+
+/*!
+ Constructs a new conversion object of type \a t, adding it to the
+ globally accessed list of available convertors.
+*/
+QMacPasteboardMime::QMacPasteboardMime(char t) : type(t)
+{
+ globalMimeList()->append(this);
+}
+
+/*!
+ Destroys a conversion object, removing it from the global
+ list of available convertors.
+*/
+QMacPasteboardMime::~QMacPasteboardMime()
+{
+ if(!QApplication::closingDown())
+ globalMimeList()->removeAll(this);
+}
+
+class QMacPasteboardMimeAny : public QMacPasteboardMime {
+private:
+
+public:
+ QMacPasteboardMimeAny() : QMacPasteboardMime(MIME_QT_CONVERTOR|MIME_ALL) {
+ }
+ ~QMacPasteboardMimeAny() {
+ }
+ QString convertorName();
+
+ QString flavorFor(const QString &mime);
+ QString mimeFor(QString flav);
+ bool canConvert(const QString &mime, QString flav);
+ QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav);
+ QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav);
+};
+
+QString QMacPasteboardMimeAny::convertorName()
+{
+ return QLatin1String("Any-Mime");
+}
+
+QString QMacPasteboardMimeAny::flavorFor(const QString &mime)
+{
+ // do not handle the mime type name in the drag pasteboard
+ if(mime == QLatin1String("application/x-qt-mime-type-name"))
+ return QString();
+ QString ret = QLatin1String("com.trolltech.anymime.") + mime;
+ return ret.replace(QLatin1Char('/'), QLatin1String("--"));
+}
+
+QString QMacPasteboardMimeAny::mimeFor(QString flav)
+{
+ const QString any_prefix = QLatin1String("com.trolltech.anymime.");
+ if(flav.size() > any_prefix.length() && flav.startsWith(any_prefix))
+ return flav.mid(any_prefix.length()).replace(QLatin1String("--"), QLatin1String("/"));
+ return QString();
+}
+
+bool QMacPasteboardMimeAny::canConvert(const QString &mime, QString flav)
+{
+ return mimeFor(flav) == mime;
+}
+
+QVariant QMacPasteboardMimeAny::convertToMime(const QString &mime, QList<QByteArray> data, QString)
+{
+ if(data.count() > 1)
+ qWarning("QMacPasteboardMimeAny: Cannot handle multiple member data");
+ QVariant ret;
+ if (mime == QLatin1String("text/plain"))
+ ret = QString::fromUtf8(data.first());
+ else
+ ret = data.first();
+ return ret;
+}
+
+QList<QByteArray> QMacPasteboardMimeAny::convertFromMime(const QString &mime, QVariant data, QString)
+{
+ QList<QByteArray> ret;
+ if (mime == QLatin1String("text/plain"))
+ ret.append(data.toString().toUtf8());
+ else
+ ret.append(data.toByteArray());
+ return ret;
+}
+
+class QMacPasteboardMimeTypeName : public QMacPasteboardMime {
+private:
+
+public:
+ QMacPasteboardMimeTypeName() : QMacPasteboardMime(MIME_QT_CONVERTOR|MIME_ALL) {
+ }
+ ~QMacPasteboardMimeTypeName() {
+ }
+ QString convertorName();
+
+ QString flavorFor(const QString &mime);
+ QString mimeFor(QString flav);
+ bool canConvert(const QString &mime, QString flav);
+ QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav);
+ QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav);
+};
+
+QString QMacPasteboardMimeTypeName::convertorName()
+{
+ return QLatin1String("Qt-Mime-Type");
+}
+
+QString QMacPasteboardMimeTypeName::flavorFor(const QString &mime)
+{
+ if(mime == QLatin1String("application/x-qt-mime-type-name"))
+ return QLatin1String("com.trolltech.qt.MimeTypeName");
+ return QString();
+}
+
+QString QMacPasteboardMimeTypeName::mimeFor(QString)
+{
+ return QString();
+}
+
+bool QMacPasteboardMimeTypeName::canConvert(const QString &, QString)
+{
+ return false;
+}
+
+QVariant QMacPasteboardMimeTypeName::convertToMime(const QString &, QList<QByteArray>, QString)
+{
+ QVariant ret;
+ return ret;
+}
+
+QList<QByteArray> QMacPasteboardMimeTypeName::convertFromMime(const QString &, QVariant, QString)
+{
+ QList<QByteArray> ret;
+ ret.append(QString("x-qt-mime-type-name").toUtf8());
+ return ret;
+}
+
+class QMacPasteboardMimePlainText : public QMacPasteboardMime {
+public:
+ QMacPasteboardMimePlainText() : QMacPasteboardMime(MIME_ALL) { }
+ QString convertorName();
+
+ QString flavorFor(const QString &mime);
+ QString mimeFor(QString flav);
+ bool canConvert(const QString &mime, QString flav);
+ QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav);
+ QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav);
+};
+
+QString QMacPasteboardMimePlainText::convertorName()
+{
+ return QLatin1String("PlainText");
+}
+
+QString QMacPasteboardMimePlainText::flavorFor(const QString &mime)
+{
+ if (mime == QLatin1String("text/plain"))
+ return QLatin1String("com.apple.traditional-mac-plain-text");
+ return QString();
+}
+
+QString QMacPasteboardMimePlainText::mimeFor(QString flav)
+{
+ if (flav == QLatin1String("com.apple.traditional-mac-plain-text"))
+ return QLatin1String("text/plain");
+ return QString();
+}
+
+bool QMacPasteboardMimePlainText::canConvert(const QString &mime, QString flav)
+{
+ return flavorFor(mime) == flav;
+}
+
+QVariant QMacPasteboardMimePlainText::convertToMime(const QString &mimetype, QList<QByteArray> data, QString flavor)
+{
+ if(data.count() > 1)
+ qWarning("QMacPasteboardMimePlainText: Cannot handle multiple member data");
+ const QByteArray &firstData = data.first();
+ QVariant ret;
+ if(flavor == QCFString(QLatin1String("com.apple.traditional-mac-plain-text"))) {
+ QCFString str(CFStringCreateWithBytes(kCFAllocatorDefault,
+ reinterpret_cast<const UInt8 *>(firstData.constData()),
+ firstData.size(), CFStringGetSystemEncoding(), false));
+ ret = QString(str);
+ } else {
+ qWarning("QMime::convertToMime: unhandled mimetype: %s", qPrintable(mimetype));
+ }
+ return ret;
+}
+
+QList<QByteArray> QMacPasteboardMimePlainText::convertFromMime(const QString &, QVariant data, QString flavor)
+{
+ QList<QByteArray> ret;
+ QString string = data.toString();
+ if(flavor == QCFString(QLatin1String("com.apple.traditional-mac-plain-text")))
+ ret.append(string.toLatin1());
+ return ret;
+}
+
+class QMacPasteboardMimeUnicodeText : public QMacPasteboardMime {
+public:
+ QMacPasteboardMimeUnicodeText() : QMacPasteboardMime(MIME_ALL) { }
+ QString convertorName();
+
+ QString flavorFor(const QString &mime);
+ QString mimeFor(QString flav);
+ bool canConvert(const QString &mime, QString flav);
+ QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav);
+ QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav);
+};
+
+QString QMacPasteboardMimeUnicodeText::convertorName()
+{
+ return QLatin1String("UnicodeText");
+}
+
+QString QMacPasteboardMimeUnicodeText::flavorFor(const QString &mime)
+{
+ if (mime == QLatin1String("text/plain"))
+ return QLatin1String("public.utf16-plain-text");
+ int i = mime.indexOf(QLatin1String("charset="));
+ if (i >= 0) {
+ QString cs(mime.mid(i+8).toLower());
+ i = cs.indexOf(QLatin1Char(';'));
+ if (i>=0)
+ cs = cs.left(i);
+ if (cs == QLatin1String("system"))
+ return QLatin1String("public.utf8-plain-text");
+ else if (cs == QLatin1String("iso-10646-ucs-2")
+ || cs == QLatin1String("utf16"))
+ return QLatin1String("public.utf16-plain-text");
+ }
+ return QString();
+}
+
+QString QMacPasteboardMimeUnicodeText::mimeFor(QString flav)
+{
+ if (flav == QLatin1String("public.utf16-plain-text") || flav == QLatin1String("public.utf8-plain-text"))
+ return QLatin1String("text/plain");
+ return QString();
+}
+
+bool QMacPasteboardMimeUnicodeText::canConvert(const QString &mime, QString flav)
+{
+ return flavorFor(mime) == flav;
+}
+
+QVariant QMacPasteboardMimeUnicodeText::convertToMime(const QString &mimetype, QList<QByteArray> data, QString flavor)
+{
+ if(data.count() > 1)
+ qWarning("QMacPasteboardMimeUnicodeText: Cannot handle multiple member data");
+ const QByteArray &firstData = data.first();
+ // I can only handle two types (system and unicode) so deal with them that way
+ QVariant ret;
+ if(flavor == QLatin1String("public.utf8-plain-text")) {
+ QCFString str(CFStringCreateWithBytes(kCFAllocatorDefault,
+ reinterpret_cast<const UInt8 *>(firstData.constData()),
+ firstData.size(), CFStringGetSystemEncoding(), false));
+ ret = QString(str);
+ } else if (flavor == QLatin1String("public.utf16-plain-text")) {
+ ret = QString(reinterpret_cast<const QChar *>(firstData.constData()),
+ firstData.size() / sizeof(QChar));
+ } else {
+ qWarning("QMime::convertToMime: unhandled mimetype: %s", qPrintable(mimetype));
+ }
+ return ret;
+}
+
+QList<QByteArray> QMacPasteboardMimeUnicodeText::convertFromMime(const QString &, QVariant data, QString flavor)
+{
+ QList<QByteArray> ret;
+ QString string = data.toString();
+ if(flavor == QLatin1String("public.utf8-plain-text"))
+ ret.append(string.toUtf8());
+ else if (flavor == QLatin1String("public.utf16-plain-text"))
+ ret.append(QByteArray((char*)string.utf16(), string.length()*2));
+ return ret;
+}
+
+class QMacPasteboardMimeHTMLText : public QMacPasteboardMime {
+public:
+ QMacPasteboardMimeHTMLText() : QMacPasteboardMime(MIME_ALL) { }
+ QString convertorName();
+
+ QString flavorFor(const QString &mime);
+ QString mimeFor(QString flav);
+ bool canConvert(const QString &mime, QString flav);
+ QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav);
+ QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav);
+};
+
+QString QMacPasteboardMimeHTMLText::convertorName()
+{
+ return QLatin1String("HTML");
+}
+
+QString QMacPasteboardMimeHTMLText::flavorFor(const QString &mime)
+{
+ if (mime == QLatin1String("text/html"))
+ return QLatin1String("public.html");
+ return QString();
+}
+
+QString QMacPasteboardMimeHTMLText::mimeFor(QString flav)
+{
+ if (flav == QLatin1String("public.html"))
+ return QLatin1String("text/html");
+ return QString();
+}
+
+bool QMacPasteboardMimeHTMLText::canConvert(const QString &mime, QString flav)
+{
+ return flavorFor(mime) == flav;
+}
+
+QVariant QMacPasteboardMimeHTMLText::convertToMime(const QString &mimeType, QList<QByteArray> data, QString flavor)
+{
+ if (!canConvert(mimeType, flavor))
+ return QVariant();
+ if (data.count() > 1)
+ qWarning("QMacPasteboardMimeHTMLText: Cannot handle multiple member data");
+ return data.first();
+}
+
+QList<QByteArray> QMacPasteboardMimeHTMLText::convertFromMime(const QString &mime, QVariant data, QString flavor)
+{
+ QList<QByteArray> ret;
+ if (!canConvert(mime, flavor))
+ return ret;
+ ret.append(data.toByteArray());
+ return ret;
+}
+
+
+#ifdef Q_WS_MAC32
+
+// This can be removed once 10.6 is the minimum (or we have to require 64-bit) whichever comes first.
+
+typedef ComponentResult (*PtrGraphicsImportSetDataHandle)(GraphicsImportComponent, Handle);
+typedef ComponentResult (*PtrGraphicsImportCreateCGImage)(GraphicsImportComponent, CGImageRef*, UInt32);
+typedef ComponentResult (*PtrGraphicsExportSetInputCGImage)(GraphicsExportComponent, CGImageRef);
+typedef ComponentResult (*PtrGraphicsExportSetOutputHandle)(GraphicsExportComponent, Handle);
+typedef ComponentResult (*PtrGraphicsExportDoExport)(GraphicsExportComponent, unsigned long *);
+
+static PtrGraphicsImportSetDataHandle ptrGraphicsImportSetDataHandle = 0;
+static PtrGraphicsImportCreateCGImage ptrGraphicsImportCreateCGImage = 0;
+static PtrGraphicsExportSetInputCGImage ptrGraphicsExportSetInputCGImage = 0;
+static PtrGraphicsExportSetOutputHandle ptrGraphicsExportSetOutputHandle = 0;
+static PtrGraphicsExportDoExport ptrGraphicsExportDoExport = 0;
+
+static bool resolveMimeQuickTimeSymbols()
+{
+ if (ptrGraphicsImportSetDataHandle == 0) {
+ QLibrary library(QLatin1String("/System/Library/Frameworks/QuickTime.framework/QuickTime"));
+ ptrGraphicsImportSetDataHandle = reinterpret_cast<PtrGraphicsImportSetDataHandle>(library.resolve("GraphicsImportSetDataHandle"));
+ ptrGraphicsImportCreateCGImage = reinterpret_cast<PtrGraphicsImportCreateCGImage>(library.resolve("GraphicsImportCreateCGImage"));
+ ptrGraphicsExportSetInputCGImage = reinterpret_cast<PtrGraphicsExportSetInputCGImage>(library.resolve("GraphicsExportSetInputCGImage"));
+ ptrGraphicsExportSetOutputHandle = reinterpret_cast<PtrGraphicsExportSetOutputHandle>(library.resolve("GraphicsExportSetOutputHandle"));
+ ptrGraphicsExportDoExport = reinterpret_cast<PtrGraphicsExportDoExport>(library.resolve("GraphicsExportDoExport"));
+ }
+
+ return ptrGraphicsImportSetDataHandle != 0
+ && ptrGraphicsImportCreateCGImage != 0 && ptrGraphicsExportSetInputCGImage != 0
+ && ptrGraphicsExportSetOutputHandle != 0 && ptrGraphicsExportDoExport != 0;
+}
+
+class QMacPasteboardMimePict : public QMacPasteboardMime {
+public:
+ QMacPasteboardMimePict() : QMacPasteboardMime(MIME_ALL) { }
+ QString convertorName();
+
+ QString flavorFor(const QString &mime);
+ QString mimeFor(QString flav);
+ bool canConvert(const QString &mime, QString flav);
+ QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav);
+ QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav);
+};
+
+QString QMacPasteboardMimePict::convertorName()
+{
+ return QLatin1String("Pict");
+}
+
+QString QMacPasteboardMimePict::flavorFor(const QString &mime)
+{
+ if(mime.startsWith(QLatin1String("application/x-qt-image")))
+ return QLatin1String("com.apple.pict");
+ return QString();
+}
+
+QString QMacPasteboardMimePict::mimeFor(QString flav)
+{
+ if(flav == QLatin1String("com.apple.pict"))
+ return QLatin1String("application/x-qt-image");
+ return QString();
+}
+
+bool QMacPasteboardMimePict::canConvert(const QString &mime, QString flav)
+{
+ return flav == QLatin1String("com.apple.pict")
+ && mime == QLatin1String("application/x-qt-image");
+}
+
+
+QVariant QMacPasteboardMimePict::convertToMime(const QString &mime, QList<QByteArray> data, QString flav)
+{
+ if(data.count() > 1)
+ qWarning("QMacPasteboardMimePict: Cannot handle multiple member data");
+ QVariant ret;
+ if (!resolveMimeQuickTimeSymbols())
+ return ret;
+
+ if(!canConvert(mime, flav))
+ return ret;
+ const QByteArray &a = data.first();
+
+ // This function expects the 512 header (just to skip it, so create the extra space for it).
+ Handle pic = NewHandle(a.size() + 512);
+ memcpy(*pic + 512, a.constData(), a.size());
+
+ GraphicsImportComponent graphicsImporter;
+ ComponentResult result = OpenADefaultComponent(GraphicsImporterComponentType,
+ kQTFileTypePicture, &graphicsImporter);
+ QCFType<CGImageRef> cgImage;
+ if (!result)
+ result = ptrGraphicsImportSetDataHandle(graphicsImporter, pic);
+ if (!result)
+ result = ptrGraphicsImportCreateCGImage(graphicsImporter, &cgImage,
+ kGraphicsImportCreateCGImageUsingCurrentSettings);
+ if (!result)
+ ret = QVariant(QPixmap::fromMacCGImageRef(cgImage).toImage());
+ CloseComponent(graphicsImporter);
+ DisposeHandle(pic);
+ return ret;
+}
+
+QList<QByteArray> QMacPasteboardMimePict::convertFromMime(const QString &mime, QVariant variant,
+ QString flav)
+{
+ QList<QByteArray> ret;
+ if (!resolveMimeQuickTimeSymbols())
+ return ret;
+
+ if (!canConvert(mime, flav))
+ return ret;
+ QCFType<CGImageRef> cgimage = qt_mac_createCGImageFromQImage(qvariant_cast<QImage>(variant));
+ Handle pic = NewHandle(0);
+ GraphicsExportComponent graphicsExporter;
+ ComponentResult result = OpenADefaultComponent(GraphicsExporterComponentType,
+ kQTFileTypePicture, &graphicsExporter);
+ if (!result) {
+ unsigned long sizeWritten;
+ result = ptrGraphicsExportSetInputCGImage(graphicsExporter, cgimage);
+ if (!result)
+ result = ptrGraphicsExportSetOutputHandle(graphicsExporter, pic);
+ if (!result)
+ result = ptrGraphicsExportDoExport(graphicsExporter, &sizeWritten);
+
+ CloseComponent(graphicsExporter);
+ }
+
+ int size = GetHandleSize((Handle)pic);
+ // Skip the Picture File header (512 bytes) and feed the raw data
+ QByteArray ar(reinterpret_cast<char *>(*pic + 512), size - 512);
+ ret.append(ar);
+ DisposeHandle(pic);
+ return ret;
+}
+
+
+#endif //Q_WS_MAC32
+
+class QMacPasteboardMimeTiff : public QMacPasteboardMime {
+public:
+ QMacPasteboardMimeTiff() : QMacPasteboardMime(MIME_ALL) { }
+ QString convertorName();
+
+ QString flavorFor(const QString &mime);
+ QString mimeFor(QString flav);
+ bool canConvert(const QString &mime, QString flav);
+ QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav);
+ QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav);
+};
+
+QString QMacPasteboardMimeTiff::convertorName()
+{
+ return QLatin1String("Tiff");
+}
+
+QString QMacPasteboardMimeTiff::flavorFor(const QString &mime)
+{
+ if(mime.startsWith(QLatin1String("application/x-qt-image")))
+ return QLatin1String("public.tiff");
+ return QString();
+}
+
+QString QMacPasteboardMimeTiff::mimeFor(QString flav)
+{
+ if(flav == QLatin1String("public.tiff"))
+ return QLatin1String("application/x-qt-image");
+ return QString();
+}
+
+bool QMacPasteboardMimeTiff::canConvert(const QString &mime, QString flav)
+{
+ return flav == QLatin1String("public.tiff") && mime == QLatin1String("application/x-qt-image");
+}
+
+QVariant QMacPasteboardMimeTiff::convertToMime(const QString &mime, QList<QByteArray> data, QString flav)
+{
+ if(data.count() > 1)
+ qWarning("QMacPasteboardMimeTiff: Cannot handle multiple member data");
+ QVariant ret;
+ if (!canConvert(mime, flav))
+ return ret;
+ const QByteArray &a = data.first();
+ QCFType<CGImageRef> image;
+ QCFType<CFDataRef> tiffData = CFDataCreateWithBytesNoCopy(0,
+ reinterpret_cast<const UInt8 *>(a.constData()),
+ a.size(), kCFAllocatorNull);
+ QCFType<CGImageSourceRef> imageSource = CGImageSourceCreateWithData(tiffData, 0);
+ image = CGImageSourceCreateImageAtIndex(imageSource, 0, 0);
+
+ if (image != 0)
+ ret = QVariant(QPixmap::fromMacCGImageRef(image).toImage());
+ return ret;
+}
+
+QList<QByteArray> QMacPasteboardMimeTiff::convertFromMime(const QString &mime, QVariant variant, QString flav)
+{
+ QList<QByteArray> ret;
+ if (!canConvert(mime, flav))
+ return ret;
+
+ QImage img = qvariant_cast<QImage>(variant);
+ QCFType<CGImageRef> cgimage = qt_mac_createCGImageFromQImage(img);
+#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4)
+ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4) {
+ QCFType<CFMutableDataRef> data = CFDataCreateMutable(0, 0);
+ QCFType<CGImageDestinationRef> imageDestination = CGImageDestinationCreateWithData(data, kUTTypeTIFF, 1, 0);
+ if (imageDestination != 0) {
+ CFTypeRef keys[2];
+ QCFType<CFTypeRef> values[2];
+ QCFType<CFDictionaryRef> options;
+ keys[0] = kCGImagePropertyPixelWidth;
+ keys[1] = kCGImagePropertyPixelHeight;
+ int width = img.width();
+ int height = img.height();
+ values[0] = CFNumberCreate(0, kCFNumberIntType, &width);
+ values[1] = CFNumberCreate(0, kCFNumberIntType, &height);
+ options = CFDictionaryCreate(0, reinterpret_cast<const void **>(keys),
+ reinterpret_cast<const void **>(values), 2,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+ CGImageDestinationAddImage(imageDestination, cgimage, options);
+ CGImageDestinationFinalize(imageDestination);
+ }
+ QByteArray ar(CFDataGetLength(data), 0);
+ CFDataGetBytes(data,
+ CFRangeMake(0, ar.size()),
+ reinterpret_cast<UInt8 *>(ar.data()));
+ ret.append(ar);
+ } else
+#endif
+ {
+#ifdef Q_WS_MAC32
+ Handle tiff = NewHandle(0);
+ if (resolveMimeQuickTimeSymbols()) {
+ GraphicsExportComponent graphicsExporter;
+ ComponentResult result = OpenADefaultComponent(GraphicsExporterComponentType,
+ kQTFileTypeTIFF, &graphicsExporter);
+ if (!result) {
+ unsigned long sizeWritten;
+ result = ptrGraphicsExportSetInputCGImage(graphicsExporter, cgimage);
+ if (!result)
+ result = ptrGraphicsExportSetOutputHandle(graphicsExporter, tiff);
+ if (!result)
+ result = ptrGraphicsExportDoExport(graphicsExporter, &sizeWritten);
+
+ CloseComponent(graphicsExporter);
+ }
+ }
+ int size = GetHandleSize((Handle)tiff);
+ QByteArray ar(reinterpret_cast<char *>(*tiff), size);
+ ret.append(ar);
+ DisposeHandle(tiff);
+#endif
+ }
+ return ret;
+}
+
+
+class QMacPasteboardMimeFileUri : public QMacPasteboardMime {
+public:
+ QMacPasteboardMimeFileUri() : QMacPasteboardMime(MIME_ALL) { }
+ QString convertorName();
+
+ QString flavorFor(const QString &mime);
+ QString mimeFor(QString flav);
+ bool canConvert(const QString &mime, QString flav);
+ QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav);
+ QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav);
+};
+
+QString QMacPasteboardMimeFileUri::convertorName()
+{
+ return QLatin1String("FileURL");
+}
+
+QString QMacPasteboardMimeFileUri::flavorFor(const QString &mime)
+{
+ if (mime == QLatin1String("text/uri-list"))
+ return QCFString(UTTypeCreatePreferredIdentifierForTag(kUTTagClassOSType, CFSTR("furl"), 0));
+ return QString();
+}
+
+QString QMacPasteboardMimeFileUri::mimeFor(QString flav)
+{
+ if (flav == QCFString(UTTypeCreatePreferredIdentifierForTag(kUTTagClassOSType, CFSTR("furl"), 0)))
+ return QLatin1String("text/uri-list");
+ return QString();
+}
+
+bool QMacPasteboardMimeFileUri::canConvert(const QString &mime, QString flav)
+{
+ return mime == QLatin1String("text/uri-list")
+ && flav == QCFString(UTTypeCreatePreferredIdentifierForTag(kUTTagClassOSType, CFSTR("furl"), 0));
+}
+
+QVariant QMacPasteboardMimeFileUri::convertToMime(const QString &mime, QList<QByteArray> data, QString flav)
+{
+ if(!canConvert(mime, flav))
+ return QVariant();
+ QList<QVariant> ret;
+ for(int i = 0; i < data.size(); ++i) {
+ QUrl url = QUrl::fromEncoded(data.at(i));
+ if (url.host().toLower() == QLatin1String("localhost"))
+ url.setHost(QString());
+ url.setPath(url.path().normalized(QString::NormalizationForm_C));
+ ret.append(url);
+ }
+ return QVariant(ret);
+}
+
+QList<QByteArray> QMacPasteboardMimeFileUri::convertFromMime(const QString &mime, QVariant data, QString flav)
+{
+ QList<QByteArray> ret;
+ if (!canConvert(mime, flav))
+ return ret;
+ QList<QVariant> urls = data.toList();
+ for(int i = 0; i < urls.size(); ++i) {
+ QUrl url = urls.at(i).toUrl();
+ if (url.scheme().isEmpty())
+ url.setScheme(QLatin1String("file"));
+ if (url.scheme().toLower() == QLatin1String("file")) {
+ if (url.host().isEmpty())
+ url.setHost(QLatin1String("localhost"));
+ url.setPath(url.path().normalized(QString::NormalizationForm_D));
+ }
+ ret.append(url.toEncoded());
+ }
+ return ret;
+}
+
+class QMacPasteboardMimeUrl : public QMacPasteboardMime {
+public:
+ QMacPasteboardMimeUrl() : QMacPasteboardMime(MIME_ALL) { }
+ QString convertorName();
+
+ QString flavorFor(const QString &mime);
+ QString mimeFor(QString flav);
+ bool canConvert(const QString &mime, QString flav);
+ QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav);
+ QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav);
+};
+
+QString QMacPasteboardMimeUrl::convertorName()
+{
+ return QLatin1String("URL");
+}
+
+QString QMacPasteboardMimeUrl::flavorFor(const QString &mime)
+{
+ if(mime.startsWith(QLatin1String("text/uri-list")))
+ return QLatin1String("public.url");
+ return QString();
+}
+
+QString QMacPasteboardMimeUrl::mimeFor(QString flav)
+{
+ if(flav == QLatin1String("public.url"))
+ return QLatin1String("text/uri-list");
+ return QString();
+}
+
+bool QMacPasteboardMimeUrl::canConvert(const QString &mime, QString flav)
+{
+ return flav == QLatin1String("public.url")
+ && mime == QLatin1String("text/uri-list");
+}
+
+QVariant QMacPasteboardMimeUrl::convertToMime(const QString &mime, QList<QByteArray> data, QString flav)
+{
+ if(!canConvert(mime, flav))
+ return QVariant();
+
+ QList<QVariant> ret;
+ for (int i=0; i<data.size(); ++i) {
+ QUrl url = QUrl::fromEncoded(data.at(i));
+ if (url.host().toLower() == QLatin1String("localhost"))
+ url.setHost(QString());
+ url.setPath(url.path().normalized(QString::NormalizationForm_C));
+ ret.append(url);
+ }
+ return QVariant(ret);
+}
+
+QList<QByteArray> QMacPasteboardMimeUrl::convertFromMime(const QString &mime, QVariant data, QString flav)
+{
+ QList<QByteArray> ret;
+ if (!canConvert(mime, flav))
+ return ret;
+
+ QList<QVariant> urls = data.toList();
+ for(int i=0; i<urls.size(); ++i) {
+ QUrl url = urls.at(i).toUrl();
+ if (url.scheme().isEmpty())
+ url.setScheme(QLatin1String("file"));
+ if (url.scheme().toLower() == QLatin1String("file")) {
+ if (url.host().isEmpty())
+ url.setHost(QLatin1String("localhost"));
+ url.setPath(url.path().normalized(QString::NormalizationForm_D));
+ }
+ ret.append(url.toEncoded());
+ }
+ return ret;
+}
+
+class QMacPasteboardMimeVCard : public QMacPasteboardMime
+{
+public:
+ QMacPasteboardMimeVCard() : QMacPasteboardMime(MIME_ALL){ }
+ QString convertorName();
+
+ QString flavorFor(const QString &mime);
+ QString mimeFor(QString flav);
+ bool canConvert(const QString &mime, QString flav);
+ QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav);
+ QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav);
+};
+
+QString QMacPasteboardMimeVCard::convertorName()
+{
+ return QString("VCard");
+}
+
+bool QMacPasteboardMimeVCard::canConvert(const QString &mime, QString flav)
+{
+ return mimeFor(flav) == mime;
+}
+
+QString QMacPasteboardMimeVCard::flavorFor(const QString &mime)
+{
+ if(mime.startsWith(QLatin1String("text/plain")))
+ return QLatin1String("public.vcard");
+ return QString();
+}
+
+QString QMacPasteboardMimeVCard::mimeFor(QString flav)
+{
+ if (flav == QLatin1String("public.vcard"))
+ return QLatin1String("text/plain");
+ return QString();
+}
+
+QVariant QMacPasteboardMimeVCard::convertToMime(const QString &mime, QList<QByteArray> data, QString)
+{
+ QByteArray cards;
+ if (mime == QLatin1String("text/plain")) {
+ for (int i=0; i<data.size(); ++i)
+ cards += data[i];
+ }
+ return QVariant(cards);
+}
+
+QList<QByteArray> QMacPasteboardMimeVCard::convertFromMime(const QString &mime, QVariant data, QString)
+{
+ QList<QByteArray> ret;
+ if (mime == QLatin1String("text/plain"))
+ ret.append(data.toString().toUtf8());
+ return ret;
+}
+
+#ifdef QT3_SUPPORT
+class QMacPasteboardMimeQt3Any : public QMacPasteboardMime {
+private:
+ int current_max;
+ QFile library_file;
+ QDateTime mime_registry_loaded;
+ QMap<QString, int> mime_registry;
+ int registerMimeType(const QString &mime);
+ bool loadMimeRegistry();
+
+public:
+ QMacPasteboardMimeQt3Any() : QMacPasteboardMime(MIME_QT3_CONVERTOR) {
+ current_max = 'QT00';
+ }
+ ~QMacPasteboardMimeQt3Any() {
+ }
+ QString convertorName();
+
+ QString flavorFor(const QString &mime);
+ QString mimeFor(QString flav);
+ bool canConvert(const QString &mime, QString flav);
+ QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav);
+ QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav);
+};
+
+static bool qt_mac_openMimeRegistry(bool global, QIODevice::OpenMode mode, QFile &file)
+{
+ QString dir = QLatin1String("/Library/Qt");
+ if(!global)
+ dir.prepend(QDir::homePath());
+ file.setFileName(dir + QLatin1String("/.mime_types"));
+ if(mode != QIODevice::ReadOnly) {
+ if(!QFile::exists(dir)) {
+ // Do it with a system call as I don't see much worth in
+ // doing it with QDir since we have to chmod anyway.
+ bool success = ::mkdir(dir.toLocal8Bit().constData(), S_IRUSR | S_IWUSR | S_IXUSR) == 0;
+ if (success)
+ success = ::chmod(dir.toLocal8Bit().constData(), S_IRUSR | S_IWUSR | S_IXUSR
+ | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH) == 0;
+ if (!success)
+ return false;
+ }
+ if (!file.exists()) {
+ // Create the file and chmod it so that everyone can write to it.
+ int fd = ::open(file.fileName().toLocal8Bit().constData(), O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
+ bool success = fd != -1;
+ if (success)
+ success = ::fchmod(fd, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH) == 0;
+ if (fd != -1)
+ ::close(fd);
+ if(!success)
+ return false;
+ }
+ }
+ return file.open(mode);
+}
+
+static void qt_mac_loadMimeRegistry(QFile &file, QMap<QString, int> &registry, int &max)
+{
+ file.reset();
+ QTextStream stream(&file);
+ while(!stream.atEnd()) {
+ QString mime = stream.readLine();
+ int mactype = stream.readLine().toInt();
+ if(mactype > max)
+ max = mactype;
+ registry.insert(mime, mactype);
+ }
+}
+
+bool QMacPasteboardMimeQt3Any::loadMimeRegistry()
+{
+ if(!library_file.isOpen()) {
+ if(!qt_mac_openMimeRegistry(true, QIODevice::ReadWrite, library_file)) {
+ QFile global;
+ if(qt_mac_openMimeRegistry(true, QIODevice::ReadOnly, global)) {
+ qt_mac_loadMimeRegistry(global, mime_registry, current_max);
+ global.close();
+ }
+ if(!qt_mac_openMimeRegistry(false, QIODevice::ReadWrite, library_file)) {
+ qWarning("QMacPasteboardMimeAnyQt3Mime: Failure to open mime resources %s -- %s", library_file.fileName().toLatin1().constData(),
+ library_file.errorString().toLatin1().constData());
+ return false;
+ }
+ }
+ }
+
+ QFileInfo fi(library_file);
+ if(!mime_registry_loaded.isNull() && mime_registry_loaded == fi.lastModified())
+ return true;
+ mime_registry_loaded = fi.lastModified();
+ qt_mac_loadMimeRegistry(library_file, mime_registry, current_max);
+ return true;
+}
+
+int QMacPasteboardMimeQt3Any::registerMimeType(const QString &mime)
+{
+ if(!mime_registry.contains(mime)) {
+ if(!loadMimeRegistry()) {
+ qWarning("QMacPasteboardMimeAnyQt3Mime: Internal error");
+ return 0;
+ }
+ if(!mime_registry.contains(mime)) {
+ if(!library_file.isOpen()) {
+ if(!library_file.open(QIODevice::WriteOnly)) {
+ qWarning("QMacPasteboardMimeAnyQt3Mime: Failure to open %s -- %s", library_file.fileName().toLatin1().constData(),
+ library_file.errorString().toLatin1().constData());
+ return false;
+ }
+ }
+ int ret = ++current_max;
+ mime_registry_loaded = QFileInfo(library_file).lastModified();
+ QTextStream stream(&library_file);
+ stream << mime << endl;
+ stream << ret << endl;
+ mime_registry.insert(mime, ret);
+ library_file.flush(); //flush and set mtime
+ return ret;
+ }
+ }
+ return mime_registry[mime];
+}
+
+QString QMacPasteboardMimeQt3Any::convertorName()
+{
+ return QLatin1String("Qt3-Any-Mime");
+}
+
+QString QMacPasteboardMimeQt3Any::flavorFor(const QString &mime)
+{
+ const int os_flav = registerMimeType(mime);
+ QCFType<CFArrayRef> ids = UTTypeCreateAllIdentifiersForTag(0, kUTTagClassOSType,
+ QCFString(UTCreateStringForOSType(os_flav)));
+ if(ids) {
+ const int type_count = CFArrayGetCount(ids);
+ if(type_count) {
+ if(type_count > 1)
+ qDebug("Can't happen!");
+ return QCFString::toQString((CFStringRef)CFArrayGetValueAtIndex(ids, 0));
+ }
+ }
+ return QString();
+}
+
+QString QMacPasteboardMimeQt3Any::mimeFor(QString flav)
+{
+ loadMimeRegistry();
+ const int os_flav = UTGetOSTypeFromString(UTTypeCopyPreferredTagWithClass(QCFString(flav), kUTTagClassOSType));
+ for(QMap<QString, int>::const_iterator it = mime_registry.constBegin();
+ it != mime_registry.constEnd(); ++it) {
+ if(it.value() == os_flav)
+ return QString::fromLatin1(it.key().toLatin1());
+ }
+ return QString();
+}
+
+bool QMacPasteboardMimeQt3Any::canConvert(const QString &mime, QString flav)
+{
+ loadMimeRegistry();
+ const int os_flav = UTGetOSTypeFromString(UTTypeCopyPreferredTagWithClass(QCFString(flav), kUTTagClassOSType));
+ if(mime_registry.contains(mime) && mime_registry[mime] == os_flav)
+ return true;
+ return false;
+}
+
+QVariant QMacPasteboardMimeQt3Any::convertToMime(const QString &, QList<QByteArray>, QString)
+{
+ qWarning("QMacPasteboardMimeAnyQt3Mime: Cannot write anything!");
+ return QVariant();
+}
+
+QList<QByteArray> QMacPasteboardMimeQt3Any::convertFromMime(const QString &mime, QVariant data, QString)
+{
+ QList<QByteArray> ret;
+ if (mime == QLatin1String("text/plain")) {
+ ret.append(data.toString().toUtf8());
+ } else {
+ ret.append(data.toByteArray());
+ }
+ return ret;
+}
+#endif
+
+/*!
+ \internal
+
+ This is an internal function.
+*/
+void QMacPasteboardMime::initialize()
+{
+ if(globalMimeList()->isEmpty()) {
+ qAddPostRoutine(cleanup_mimes);
+
+ //standard types that we wrap
+ new QMacPasteboardMimeTiff;
+#ifdef Q_WS_MAC32
+ // 10.6 does automatic synthesis to and from PICT to standard image types (like TIFF),
+ // so don't bother doing it ourselves, especially since it's not available in 64-bit.
+ if (QSysInfo::MacintoshVersion < QSysInfo::MV_10_6)
+ new QMacPasteboardMimePict;
+#endif
+ new QMacPasteboardMimeUnicodeText;
+ new QMacPasteboardMimePlainText;
+ new QMacPasteboardMimeHTMLText;
+ new QMacPasteboardMimeFileUri;
+ new QMacPasteboardMimeUrl;
+ new QMacPasteboardMimeTypeName;
+ new QMacPasteboardMimeVCard;
+ //make sure our "non-standard" types are always last! --Sam
+ new QMacPasteboardMimeAny;
+#ifdef QT3_SUPPORT
+ new QMacPasteboardMimeQt3Any;
+#endif
+ }
+}
+
+/*!
+ Returns the most-recently created QMacPasteboardMime of type \a t that can convert
+ between the \a mime and \a flav formats. Returns 0 if no such convertor
+ exists.
+*/
+QMacPasteboardMime*
+QMacPasteboardMime::convertor(uchar t, const QString &mime, QString flav)
+{
+ MimeList *mimes = globalMimeList();
+ for(MimeList::const_iterator it = mimes->constBegin(); it != mimes->constEnd(); ++it) {
+#ifdef DEBUG_MIME_MAPS
+ qDebug("QMacPasteboardMime::convertor: seeing if %s (%d) can convert %s to %d[%c%c%c%c] [%d]",
+ (*it)->convertorName().toLatin1().constData(),
+ (*it)->type & t, mime.toLatin1().constData(),
+ flav, (flav >> 24) & 0xFF, (flav >> 16) & 0xFF, (flav >> 8) & 0xFF, (flav) & 0xFF,
+ (*it)->canConvert(mime,flav));
+ for(int i = 0; i < (*it)->countFlavors(); ++i) {
+ int f = (*it)->flavor(i);
+ qDebug(" %d) %d[%c%c%c%c] [%s]", i, f,
+ (f >> 24) & 0xFF, (f >> 16) & 0xFF, (f >> 8) & 0xFF, (f) & 0xFF,
+ (*it)->convertorName().toLatin1().constData());
+ }
+#endif
+ if(((*it)->type & t) && (*it)->canConvert(mime, flav))
+ return (*it);
+ }
+ return 0;
+}
+/*!
+ Returns a MIME type of type \a t for \a flav, or 0 if none exists.
+*/
+QString QMacPasteboardMime::flavorToMime(uchar t, QString flav)
+{
+ MimeList *mimes = globalMimeList();
+ for(MimeList::const_iterator it = mimes->constBegin(); it != mimes->constEnd(); ++it) {
+#ifdef DEBUG_MIME_MAPS
+ qDebug("QMacMIme::flavorToMime: attempting %s (%d) for flavor %d[%c%c%c%c] [%s]",
+ (*it)->convertorName().toLatin1().constData(),
+ (*it)->type & t, flav, (flav >> 24) & 0xFF, (flav >> 16) & 0xFF, (flav >> 8) & 0xFF, (flav) & 0xFF,
+ (*it)->mimeFor(flav).toLatin1().constData());
+
+#endif
+ if((*it)->type & t) {
+ QString mimeType = (*it)->mimeFor(flav);
+ if(!mimeType.isNull())
+ return mimeType;
+ }
+ }
+ return QString();
+}
+
+/*!
+ Returns a list of all currently defined QMacPasteboardMime objects of type \a t.
+*/
+QList<QMacPasteboardMime*> QMacPasteboardMime::all(uchar t)
+{
+ MimeList ret;
+ MimeList *mimes = globalMimeList();
+ for(MimeList::const_iterator it = mimes->constBegin(); it != mimes->constEnd(); ++it) {
+ if((*it)->type & t)
+ ret.append((*it));
+ }
+ return ret;
+}
+
+
+/*!
+ \fn QString QMacPasteboardMime::convertorName()
+
+ Returns a name for the convertor.
+
+ All subclasses must reimplement this pure virtual function.
+*/
+
+/*!
+ \fn bool QMacPasteboardMime::canConvert(const QString &mime, QString flav)
+
+ Returns true if the convertor can convert (both ways) between
+ \a mime and \a flav; otherwise returns false.
+
+ All subclasses must reimplement this pure virtual function.
+*/
+
+/*!
+ \fn QString QMacPasteboardMime::mimeFor(QString flav)
+
+ Returns the MIME UTI used for Mac flavor \a flav, or 0 if this
+ convertor does not support \a flav.
+
+ All subclasses must reimplement this pure virtual function.
+*/
+
+/*!
+ \fn QString QMacPasteboardMime::flavorFor(const QString &mime)
+
+ Returns the Mac UTI used for MIME type \a mime, or 0 if this
+ convertor does not support \a mime.
+
+ All subclasses must reimplement this pure virtual function.
+*/
+
+/*!
+ \fn QVariant QMacPasteboardMime::convertToMime(const QString &mime, QList<QByteArray> data, QString flav)
+
+ Returns \a data converted from Mac UTI \a flav to MIME type \a
+ mime.
+
+ Note that Mac flavors must all be self-terminating. The input \a
+ data may contain trailing data.
+
+ All subclasses must reimplement this pure virtual function.
+*/
+
+/*!
+ \fn QList<QByteArray> QMacPasteboardMime::convertFromMime(const QString &mime, QVariant data, QString flav)
+
+ Returns \a data converted from MIME type \a mime
+ to Mac UTI \a flav.
+
+ Note that Mac flavors must all be self-terminating. The return
+ value may contain trailing data.
+
+ All subclasses must reimplement this pure virtual function.
+*/
+
+
+QT_END_NAMESPACE
diff --git a/src/gui/kernel/qmultitouch_mac.mm b/src/widgets/platforms/mac/qmultitouch_mac.mm
index 30b0acb388..30b0acb388 100644
--- a/src/gui/kernel/qmultitouch_mac.mm
+++ b/src/widgets/platforms/mac/qmultitouch_mac.mm
diff --git a/src/gui/kernel/qmultitouch_mac_p.h b/src/widgets/platforms/mac/qmultitouch_mac_p.h
index c69c49984a..c69c49984a 100644
--- a/src/gui/kernel/qmultitouch_mac_p.h
+++ b/src/widgets/platforms/mac/qmultitouch_mac_p.h
diff --git a/src/gui/kernel/qnsframeview_mac_p.h b/src/widgets/platforms/mac/qnsframeview_mac_p.h
index 72245c1782..72245c1782 100644
--- a/src/gui/kernel/qnsframeview_mac_p.h
+++ b/src/widgets/platforms/mac/qnsframeview_mac_p.h
diff --git a/src/gui/kernel/qnsthemeframe_mac_p.h b/src/widgets/platforms/mac/qnsthemeframe_mac_p.h
index a1fa4ef1d8..a1fa4ef1d8 100644
--- a/src/gui/kernel/qnsthemeframe_mac_p.h
+++ b/src/widgets/platforms/mac/qnsthemeframe_mac_p.h
diff --git a/src/gui/kernel/qnstitledframe_mac_p.h b/src/widgets/platforms/mac/qnstitledframe_mac_p.h
index 18a6155925..18a6155925 100644
--- a/src/gui/kernel/qnstitledframe_mac_p.h
+++ b/src/widgets/platforms/mac/qnstitledframe_mac_p.h
diff --git a/src/widgets/platforms/mac/qpaintdevice_mac.cpp b/src/widgets/platforms/mac/qpaintdevice_mac.cpp
new file mode 100644
index 0000000000..50bd4b8490
--- /dev/null
+++ b/src/widgets/platforms/mac/qpaintdevice_mac.cpp
@@ -0,0 +1,152 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qpaintdevice.h"
+#include "qpainter.h"
+#include "qwidget.h"
+#include "qbitmap.h"
+#include "qapplication.h"
+#include "qprinter.h"
+#include <qdebug.h>
+#include <private/qt_mac_p.h>
+#include <private/qprintengine_mac_p.h>
+#include <private/qpixmap_mac_p.h>
+#include <private/qpixmap_raster_p.h>
+
+QT_BEGIN_NAMESPACE
+
+/*****************************************************************************
+ Internal variables and functions
+ *****************************************************************************/
+
+/*! \internal */
+float qt_mac_defaultDpi_x()
+{
+ // Mac OS X currently assumes things to be 72 dpi.
+ // (see http://developer.apple.com/releasenotes/GraphicsImaging/RN-ResolutionIndependentUI/)
+ // This may need to be re-worked as we go further in the resolution-independence stuff.
+ return 72;
+}
+
+/*! \internal */
+float qt_mac_defaultDpi_y()
+{
+ // Mac OS X currently assumes things to be 72 dpi.
+ // (see http://developer.apple.com/releasenotes/GraphicsImaging/RN-ResolutionIndependentUI/)
+ // This may need to be re-worked as we go further in the resolution-independence stuff.
+ return 72;
+}
+
+
+/*! \internal
+
+ Returns the QuickDraw CGrafPtr of the paint device. 0 is returned
+ if it can't be obtained. Do not hold the pointer around for long
+ as it can be relocated.
+
+ \warning This function is only available on Mac OS X.
+*/
+
+Q_WIDGETS_EXPORT GrafPtr qt_mac_qd_context(const QPaintDevice *device)
+{
+ if (device->devType() == QInternal::Pixmap) {
+ return static_cast<GrafPtr>(static_cast<const QPixmap *>(device)->macQDHandle());
+ } else if(device->devType() == QInternal::Widget) {
+ return static_cast<GrafPtr>(static_cast<const QWidget *>(device)->macQDHandle());
+ } else if(device->devType() == QInternal::Printer) {
+ QPaintEngine *engine = static_cast<const QPrinter *>(device)->paintEngine();
+ return static_cast<GrafPtr>(static_cast<const QMacPrintEngine *>(engine)->handle());
+ }
+ return 0;
+}
+
+extern CGColorSpaceRef qt_mac_colorSpaceForDeviceType(const QPaintDevice *pdev);
+
+/*! \internal
+
+ Returns the CoreGraphics CGContextRef of the paint device. 0 is
+ returned if it can't be obtained. It is the caller's responsiblity to
+ CGContextRelease the context when finished using it.
+
+ \warning This function is only available on Mac OS X.
+*/
+
+Q_WIDGETS_EXPORT CGContextRef qt_mac_cg_context(const QPaintDevice *pdev)
+{
+ if (pdev->devType() == QInternal::Pixmap) {
+ const QPixmap *pm = static_cast<const QPixmap*>(pdev);
+ CGColorSpaceRef colorspace = qt_mac_colorSpaceForDeviceType(pdev);
+ uint flags = kCGImageAlphaPremultipliedFirst;
+#ifdef kCGBitmapByteOrder32Host //only needed because CGImage.h added symbols in the minor version
+ flags |= kCGBitmapByteOrder32Host;
+#endif
+ CGContextRef ret = 0;
+
+ // It would make sense to put this into a mac #ifdef'ed
+ // virtual function in the QPlatformPixmap at some point
+ if (pm->data->classId() == QPlatformPixmap::MacClass) {
+ const QMacPlatformPixmap *pmData = static_cast<const QMacPlatformPixmap*>(pm->data.data());
+ ret = CGBitmapContextCreate(pmData->pixels, pmData->w, pmData->h,
+ 8, pmData->bytesPerRow, colorspace,
+ flags);
+ if(!ret)
+ qWarning("QPaintDevice: Unable to create context for pixmap (%d/%d/%d)",
+ pmData->w, pmData->h, (pmData->bytesPerRow * pmData->h));
+ } else if (pm->data->classId() == QPlatformPixmap::RasterClass) {
+ QImage *image = pm->data->buffer();
+ ret = CGBitmapContextCreate(image->bits(), image->width(), image->height(),
+ 8, image->bytesPerLine(), colorspace, flags);
+ }
+
+ CGContextTranslateCTM(ret, 0, pm->height());
+ CGContextScaleCTM(ret, 1, -1);
+ return ret;
+ } else if (pdev->devType() == QInternal::Widget) {
+ CGContextRef ret = static_cast<CGContextRef>(static_cast<const QWidget *>(pdev)->macCGHandle());
+ CGContextRetain(ret);
+ return ret;
+ } else if (pdev->devType() == QInternal::MacQuartz) {
+ return static_cast<const QMacQuartzPaintDevice *>(pdev)->cgContext();
+ }
+ return 0;
+}
+
+QT_END_NAMESPACE
diff --git a/src/widgets/platforms/mac/qpaintengine_mac.cpp b/src/widgets/platforms/mac/qpaintengine_mac.cpp
new file mode 100644
index 0000000000..3def016b56
--- /dev/null
+++ b/src/widgets/platforms/mac/qpaintengine_mac.cpp
@@ -0,0 +1,1647 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qbitmap.h>
+#include <qpaintdevice.h>
+#include <private/qpaintengine_mac_p.h>
+#include <qpainterpath.h>
+#include <qpixmapcache.h>
+#include <private/qpaintengine_raster_p.h>
+#include <private/qprintengine_mac_p.h>
+#include <qprinter.h>
+#include <qstack.h>
+#include <qtextcodec.h>
+#include <qwidget.h>
+#include <qvarlengtharray.h>
+#include <qdebug.h>
+#include <qcoreapplication.h>
+#include <qmath.h>
+
+#include <private/qfont_p.h>
+#include <private/qfontengine_p.h>
+#include <private/qfontengine_coretext_p.h>
+#include <private/qfontengine_mac_p.h>
+#include <private/qnumeric_p.h>
+#include <private/qpainter_p.h>
+#include <private/qpainterpath_p.h>
+#include <private/qpixmap_mac_p.h>
+#include <private/qt_mac_p.h>
+#include <private/qtextengine_p.h>
+#include <private/qwidget_p.h>
+#include <private/qt_cocoa_helpers_mac_p.h>
+
+#include <string.h>
+
+QT_BEGIN_NAMESPACE
+
+extern int qt_antialiasing_threshold; // QApplication.cpp
+
+/*****************************************************************************
+ External functions
+ *****************************************************************************/
+extern CGImageRef qt_mac_create_imagemask(const QPixmap &px, const QRectF &sr); //qpixmap_mac.cpp
+extern QPoint qt_mac_posInWindow(const QWidget *w); //qwidget_mac.cpp
+extern OSWindowRef qt_mac_window_for(const QWidget *); //qwidget_mac.cpp
+extern CGContextRef qt_mac_cg_context(const QPaintDevice *); //qpaintdevice_mac.cpp
+extern void qt_mac_dispose_rgn(RgnHandle r); //qregion_mac.cpp
+extern QPixmap qt_pixmapForBrush(int, bool); //qbrush.cpp
+
+void qt_mac_clip_cg(CGContextRef hd, const QRegion &rgn, CGAffineTransform *orig_xform);
+
+
+//Implemented for qt_mac_p.h
+QMacCGContext::QMacCGContext(QPainter *p)
+{
+ QPaintEngine *pe = p->paintEngine();
+ if (pe->type() == QPaintEngine::MacPrinter)
+ pe = static_cast<QMacPrintEngine*>(pe)->paintEngine();
+ pe->syncState();
+ context = 0;
+ if(pe->type() == QPaintEngine::CoreGraphics)
+ context = static_cast<QCoreGraphicsPaintEngine*>(pe)->handle();
+
+ int devType = p->device()->devType();
+ if (pe->type() == QPaintEngine::Raster
+ && (devType == QInternal::Widget ||
+ devType == QInternal::Pixmap ||
+ devType == QInternal::Image)) {
+
+ extern CGColorSpaceRef qt_mac_colorSpaceForDeviceType(const QPaintDevice *paintDevice);
+ CGColorSpaceRef colorspace = qt_mac_colorSpaceForDeviceType(pe->paintDevice());
+ uint flags = kCGImageAlphaPremultipliedFirst;
+#ifdef kCGBitmapByteOrder32Host //only needed because CGImage.h added symbols in the minor version
+ flags |= kCGBitmapByteOrder32Host;
+#endif
+ const QImage *image = (const QImage *) pe->paintDevice();
+
+ context = CGBitmapContextCreate((void *) image->bits(), image->width(), image->height(),
+ 8, image->bytesPerLine(), colorspace, flags);
+
+ CGContextTranslateCTM(context, 0, image->height());
+ CGContextScaleCTM(context, 1, -1);
+
+ if (devType == QInternal::Widget) {
+ QRegion clip = p->paintEngine()->systemClip();
+ QTransform native = p->deviceTransform();
+ QTransform logical = p->combinedTransform();
+
+ if (p->hasClipping()) {
+ QRegion r = p->clipRegion();
+ r.translate(native.dx(), native.dy());
+ if (clip.isEmpty())
+ clip = r;
+ else
+ clip &= r;
+ }
+ qt_mac_clip_cg(context, clip, 0);
+
+ CGContextTranslateCTM(context, native.dx(), native.dy());
+ }
+ } else {
+ CGContextRetain(context);
+ }
+}
+
+
+/*****************************************************************************
+ QCoreGraphicsPaintEngine utility functions
+ *****************************************************************************/
+
+//conversion
+inline static float qt_mac_convert_color_to_cg(int c) { return ((float)c * 1000 / 255) / 1000; }
+inline static int qt_mac_convert_color_from_cg(float c) { return qRound(c * 255); }
+CGAffineTransform qt_mac_convert_transform_to_cg(const QTransform &t) {
+ return CGAffineTransformMake(t.m11(), t.m12(), t.m21(), t.m22(), t.dx(), t.dy());
+}
+
+CGColorSpaceRef qt_mac_colorSpaceForDeviceType(const QPaintDevice *paintDevice)
+{
+ bool isWidget = (paintDevice->devType() == QInternal::Widget);
+ return QCoreGraphicsPaintEngine::macDisplayColorSpace(isWidget ? static_cast<const QWidget *>(paintDevice)
+ : 0);
+}
+
+inline static QCFType<CGColorRef> cgColorForQColor(const QColor &col, QPaintDevice *pdev)
+{
+ CGFloat components[] = {
+ qt_mac_convert_color_to_cg(col.red()),
+ qt_mac_convert_color_to_cg(col.green()),
+ qt_mac_convert_color_to_cg(col.blue()),
+ qt_mac_convert_color_to_cg(col.alpha())
+ };
+ return CGColorCreate(qt_mac_colorSpaceForDeviceType(pdev), components);
+}
+
+// There's architectural problems with using native gradients
+// on the Mac at the moment, so disable them.
+// #define QT_MAC_USE_NATIVE_GRADIENTS
+
+#ifdef QT_MAC_USE_NATIVE_GRADIENTS
+static bool drawGradientNatively(const QGradient *gradient)
+{
+ return gradient->spread() == QGradient::PadSpread;
+}
+
+// gradiant callback
+static void qt_mac_color_gradient_function(void *info, const CGFloat *in, CGFloat *out)
+{
+ QBrush *brush = static_cast<QBrush *>(info);
+ Q_ASSERT(brush && brush->gradient());
+
+ const QGradientStops stops = brush->gradient()->stops();
+ const int n = stops.count();
+ Q_ASSERT(n >= 1);
+ const QGradientStop *begin = stops.constBegin();
+ const QGradientStop *end = begin + n;
+
+ qreal p = in[0];
+ const QGradientStop *i = begin;
+ while (i != end && i->first < p)
+ ++i;
+
+ QRgb c;
+ if (i == begin) {
+ c = begin->second.rgba();
+ } else if (i == end) {
+ c = (end - 1)->second.rgba();
+ } else {
+ const QGradientStop &s1 = *(i - 1);
+ const QGradientStop &s2 = *i;
+ qreal p1 = s1.first;
+ qreal p2 = s2.first;
+ QRgb c1 = s1.second.rgba();
+ QRgb c2 = s2.second.rgba();
+ int idist = 256 * (p - p1) / (p2 - p1);
+ int dist = 256 - idist;
+ c = qRgba(INTERPOLATE_PIXEL_256(qRed(c1), dist, qRed(c2), idist),
+ INTERPOLATE_PIXEL_256(qGreen(c1), dist, qGreen(c2), idist),
+ INTERPOLATE_PIXEL_256(qBlue(c1), dist, qBlue(c2), idist),
+ INTERPOLATE_PIXEL_256(qAlpha(c1), dist, qAlpha(c2), idist));
+ }
+
+ out[0] = qt_mac_convert_color_to_cg(qRed(c));
+ out[1] = qt_mac_convert_color_to_cg(qGreen(c));
+ out[2] = qt_mac_convert_color_to_cg(qBlue(c));
+ out[3] = qt_mac_convert_color_to_cg(qAlpha(c));
+}
+#endif
+
+//clipping handling
+void QCoreGraphicsPaintEnginePrivate::resetClip()
+{
+ static bool inReset = false;
+ if (inReset)
+ return;
+ inReset = true;
+
+ CGAffineTransform old_xform = CGContextGetCTM(hd);
+
+ //setup xforms
+ CGContextConcatCTM(hd, CGAffineTransformInvert(old_xform));
+ while (stackCount > 0) {
+ restoreGraphicsState();
+ }
+ saveGraphicsState();
+ inReset = false;
+ //reset xforms
+ CGContextConcatCTM(hd, CGAffineTransformInvert(CGContextGetCTM(hd)));
+ CGContextConcatCTM(hd, old_xform);
+}
+
+static CGRect qt_mac_compose_rect(const QRectF &r, float off=0)
+{
+ return CGRectMake(r.x()+off, r.y()+off, r.width(), r.height());
+}
+
+static CGMutablePathRef qt_mac_compose_path(const QPainterPath &p, float off=0)
+{
+ CGMutablePathRef ret = CGPathCreateMutable();
+ QPointF startPt;
+ for (int i=0; i<p.elementCount(); ++i) {
+ const QPainterPath::Element &elm = p.elementAt(i);
+ switch (elm.type) {
+ case QPainterPath::MoveToElement:
+ if(i > 0
+ && p.elementAt(i - 1).x == startPt.x()
+ && p.elementAt(i - 1).y == startPt.y())
+ CGPathCloseSubpath(ret);
+ startPt = QPointF(elm.x, elm.y);
+ CGPathMoveToPoint(ret, 0, elm.x+off, elm.y+off);
+ break;
+ case QPainterPath::LineToElement:
+ CGPathAddLineToPoint(ret, 0, elm.x+off, elm.y+off);
+ break;
+ case QPainterPath::CurveToElement:
+ Q_ASSERT(p.elementAt(i+1).type == QPainterPath::CurveToDataElement);
+ Q_ASSERT(p.elementAt(i+2).type == QPainterPath::CurveToDataElement);
+ CGPathAddCurveToPoint(ret, 0,
+ elm.x+off, elm.y+off,
+ p.elementAt(i+1).x+off, p.elementAt(i+1).y+off,
+ p.elementAt(i+2).x+off, p.elementAt(i+2).y+off);
+ i+=2;
+ break;
+ default:
+ qFatal("QCoreGraphicsPaintEngine::drawPath(), unhandled type: %d", elm.type);
+ break;
+ }
+ }
+ if(!p.isEmpty()
+ && p.elementAt(p.elementCount() - 1).x == startPt.x()
+ && p.elementAt(p.elementCount() - 1).y == startPt.y())
+ CGPathCloseSubpath(ret);
+ return ret;
+}
+
+CGColorSpaceRef QCoreGraphicsPaintEngine::m_genericColorSpace = 0;
+QHash<CGDirectDisplayID, CGColorSpaceRef> QCoreGraphicsPaintEngine::m_displayColorSpaceHash;
+bool QCoreGraphicsPaintEngine::m_postRoutineRegistered = false;
+
+CGColorSpaceRef QCoreGraphicsPaintEngine::macGenericColorSpace()
+{
+#if 0
+ if (!m_genericColorSpace) {
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
+ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4) {
+ m_genericColorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
+ } else
+#endif
+ {
+ m_genericColorSpace = CGColorSpaceCreateDeviceRGB();
+ }
+ if (!m_postRoutineRegistered) {
+ m_postRoutineRegistered = true;
+ qAddPostRoutine(QCoreGraphicsPaintEngine::cleanUpMacColorSpaces);
+ }
+ }
+ return m_genericColorSpace;
+#else
+ // Just return the main display colorspace for the moment.
+ return macDisplayColorSpace();
+#endif
+}
+void qt_mac_clip_cg(CGContextRef hd, const QRegion &rgn, CGAffineTransform *orig_xform)
+{
+ CGAffineTransform old_xform = CGAffineTransformIdentity;
+ if(orig_xform) { //setup xforms
+ old_xform = CGContextGetCTM(hd);
+ CGContextConcatCTM(hd, CGAffineTransformInvert(old_xform));
+ CGContextConcatCTM(hd, *orig_xform);
+ }
+
+ //do the clipping
+ CGContextBeginPath(hd);
+ if(rgn.isEmpty()) {
+ CGContextAddRect(hd, CGRectMake(0, 0, 0, 0));
+ } else {
+#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
+ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) {
+ QCFType<HIMutableShapeRef> shape = rgn.toHIMutableShape();
+ Q_ASSERT(!HIShapeIsEmpty(shape));
+ HIShapeReplacePathInCGContext(shape, hd);
+ } else
+#endif
+ {
+ QVector<QRect> rects = rgn.rects();
+ const int count = rects.size();
+ for(int i = 0; i < count; i++) {
+ const QRect &r = rects[i];
+ CGRect mac_r = CGRectMake(r.x(), r.y(), r.width(), r.height());
+ CGContextAddRect(hd, mac_r);
+ }
+ }
+
+ }
+ CGContextClip(hd);
+
+ if(orig_xform) {//reset xforms
+ CGContextConcatCTM(hd, CGAffineTransformInvert(CGContextGetCTM(hd)));
+ CGContextConcatCTM(hd, old_xform);
+ }
+}
+
+
+//pattern handling (tiling)
+#if 1
+# define QMACPATTERN_MASK_MULTIPLIER 32
+#else
+# define QMACPATTERN_MASK_MULTIPLIER 1
+#endif
+class QMacPattern
+{
+public:
+ QMacPattern() : as_mask(false), pdev(0), image(0) { data.bytes = 0; }
+ ~QMacPattern() { CGImageRelease(image); }
+ int width() {
+ if(image)
+ return CGImageGetWidth(image);
+ if(data.bytes)
+ return 8*QMACPATTERN_MASK_MULTIPLIER;
+ return data.pixmap.width();
+ }
+ int height() {
+ if(image)
+ return CGImageGetHeight(image);
+ if(data.bytes)
+ return 8*QMACPATTERN_MASK_MULTIPLIER;
+ return data.pixmap.height();
+ }
+
+ //input
+ QColor foreground;
+ bool as_mask;
+ struct {
+ QPixmap pixmap;
+ const uchar *bytes;
+ } data;
+ QPaintDevice *pdev;
+ //output
+ CGImageRef image;
+};
+static void qt_mac_draw_pattern(void *info, CGContextRef c)
+{
+ QMacPattern *pat = (QMacPattern*)info;
+ int w = 0, h = 0;
+ bool isBitmap = (pat->data.pixmap.depth() == 1);
+ if(!pat->image) { //lazy cache
+ if(pat->as_mask) {
+ Q_ASSERT(pat->data.bytes);
+ w = h = 8;
+#if (QMACPATTERN_MASK_MULTIPLIER == 1)
+ CGDataProviderRef provider = CGDataProviderCreateWithData(0, pat->data.bytes, w*h, 0);
+ pat->image = CGImageMaskCreate(w, h, 1, 1, 1, provider, 0, false);
+ CGDataProviderRelease(provider);
+#else
+ const int numBytes = (w*h)/sizeof(uchar);
+ uchar xor_bytes[numBytes];
+ for(int i = 0; i < numBytes; ++i)
+ xor_bytes[i] = pat->data.bytes[i] ^ 0xFF;
+ CGDataProviderRef provider = CGDataProviderCreateWithData(0, xor_bytes, w*h, 0);
+ CGImageRef swatch = CGImageMaskCreate(w, h, 1, 1, 1, provider, 0, false);
+ CGDataProviderRelease(provider);
+
+ const QColor c0(0, 0, 0, 0), c1(255, 255, 255, 255);
+ QPixmap pm(w*QMACPATTERN_MASK_MULTIPLIER, h*QMACPATTERN_MASK_MULTIPLIER);
+ pm.fill(c0);
+ CGContextRef pm_ctx = qt_mac_cg_context(&pm);
+ CGContextSetFillColorWithColor(c, cgColorForQColor(c1, pat->pdev));
+ CGRect rect = CGRectMake(0, 0, w, h);
+ for(int x = 0; x < QMACPATTERN_MASK_MULTIPLIER; ++x) {
+ rect.origin.x = x * w;
+ for(int y = 0; y < QMACPATTERN_MASK_MULTIPLIER; ++y) {
+ rect.origin.y = y * h;
+ qt_mac_drawCGImage(pm_ctx, &rect, swatch);
+ }
+ }
+ pat->image = qt_mac_create_imagemask(pm, pm.rect());
+ CGImageRelease(swatch);
+ CGContextRelease(pm_ctx);
+ w *= QMACPATTERN_MASK_MULTIPLIER;
+ h *= QMACPATTERN_MASK_MULTIPLIER;
+#endif
+ } else {
+ w = pat->data.pixmap.width();
+ h = pat->data.pixmap.height();
+ if (isBitmap)
+ pat->image = qt_mac_create_imagemask(pat->data.pixmap, pat->data.pixmap.rect());
+ else
+ pat->image = (CGImageRef)pat->data.pixmap.macCGHandle();
+ }
+ } else {
+ w = CGImageGetWidth(pat->image);
+ h = CGImageGetHeight(pat->image);
+ }
+
+ //draw
+ bool needRestore = false;
+ if (CGImageIsMask(pat->image)) {
+ CGContextSaveGState(c);
+ CGContextSetFillColorWithColor(c, cgColorForQColor(pat->foreground, pat->pdev));
+ }
+ CGRect rect = CGRectMake(0, 0, w, h);
+ qt_mac_drawCGImage(c, &rect, pat->image);
+ if(needRestore)
+ CGContextRestoreGState(c);
+}
+static void qt_mac_dispose_pattern(void *info)
+{
+ QMacPattern *pat = (QMacPattern*)info;
+ delete pat;
+}
+
+/*****************************************************************************
+ QCoreGraphicsPaintEngine member functions
+ *****************************************************************************/
+
+inline static QPaintEngine::PaintEngineFeatures qt_mac_cg_features()
+{
+ return QPaintEngine::PaintEngineFeatures(QPaintEngine::AllFeatures & ~QPaintEngine::PaintOutsidePaintEvent
+ & ~QPaintEngine::PerspectiveTransform
+ & ~QPaintEngine::ConicalGradientFill
+ & ~QPaintEngine::LinearGradientFill
+ & ~QPaintEngine::RadialGradientFill
+ & ~QPaintEngine::BrushStroke);
+}
+
+QCoreGraphicsPaintEngine::QCoreGraphicsPaintEngine()
+: QPaintEngine(*(new QCoreGraphicsPaintEnginePrivate), qt_mac_cg_features())
+{
+}
+
+QCoreGraphicsPaintEngine::QCoreGraphicsPaintEngine(QPaintEnginePrivate &dptr)
+: QPaintEngine(dptr, qt_mac_cg_features())
+{
+}
+
+QCoreGraphicsPaintEngine::~QCoreGraphicsPaintEngine()
+{
+}
+
+bool
+QCoreGraphicsPaintEngine::begin(QPaintDevice *pdev)
+{
+ Q_D(QCoreGraphicsPaintEngine);
+ if(isActive()) { // already active painting
+ qWarning("QCoreGraphicsPaintEngine::begin: Painter already active");
+ return false;
+ }
+
+ //initialization
+ d->pdev = pdev;
+ d->complexXForm = false;
+ d->cosmeticPen = QCoreGraphicsPaintEnginePrivate::CosmeticSetPenWidth;
+ d->cosmeticPenSize = 1;
+ d->current.clipEnabled = false;
+ d->pixelSize = QPoint(1,1);
+ d->hd = qt_mac_cg_context(pdev);
+ if(d->hd) {
+ d->saveGraphicsState();
+ d->orig_xform = CGContextGetCTM(d->hd);
+ if (d->shading) {
+ CGShadingRelease(d->shading);
+ d->shading = 0;
+ }
+ d->setClip(0); //clear the context's clipping
+ }
+
+ setActive(true);
+
+ if(d->pdev->devType() == QInternal::Widget) { // device is a widget
+ QWidget *w = (QWidget*)d->pdev;
+ bool unclipped = w->testAttribute(Qt::WA_PaintUnclipped);
+
+ if((w->windowType() == Qt::Desktop)) {
+ if(!unclipped)
+ qWarning("QCoreGraphicsPaintEngine::begin: Does not support clipped desktop on Mac OS X");
+ // ## need to do [qt_mac_window_for(w) makeKeyAndOrderFront]; (need to rename the file)
+ } else if(unclipped) {
+ qWarning("QCoreGraphicsPaintEngine::begin: Does not support unclipped painting");
+ }
+ } else if(d->pdev->devType() == QInternal::Pixmap) { // device is a pixmap
+ QPixmap *pm = (QPixmap*)d->pdev;
+ if(pm->isNull()) {
+ qWarning("QCoreGraphicsPaintEngine::begin: Cannot paint null pixmap");
+ end();
+ return false;
+ }
+ }
+
+ setDirty(QPaintEngine::DirtyPen);
+ setDirty(QPaintEngine::DirtyBrush);
+ setDirty(QPaintEngine::DirtyBackground);
+ setDirty(QPaintEngine::DirtyHints);
+ return true;
+}
+
+bool
+QCoreGraphicsPaintEngine::end()
+{
+ Q_D(QCoreGraphicsPaintEngine);
+ setActive(false);
+ if(d->pdev->devType() == QInternal::Widget && static_cast<QWidget*>(d->pdev)->windowType() == Qt::Desktop) {
+#ifndef QT_MAC_USE_COCOA
+ HideWindow(qt_mac_window_for(static_cast<QWidget*>(d->pdev)));
+#else
+// // ### need to do [qt_mac_window_for(static_cast<QWidget *>(d->pdev)) orderOut]; (need to rename)
+#endif
+
+ }
+ if(d->shading) {
+ CGShadingRelease(d->shading);
+ d->shading = 0;
+ }
+ d->pdev = 0;
+ if(d->hd) {
+ d->restoreGraphicsState();
+ CGContextSynchronize(d->hd);
+ CGContextRelease(d->hd);
+ d->hd = 0;
+ }
+ return true;
+}
+
+void
+QCoreGraphicsPaintEngine::updateState(const QPaintEngineState &state)
+{
+ Q_D(QCoreGraphicsPaintEngine);
+ QPaintEngine::DirtyFlags flags = state.state();
+
+ if (flags & DirtyTransform)
+ updateMatrix(state.transform());
+
+ if (flags & DirtyClipEnabled) {
+ if (state.isClipEnabled())
+ updateClipPath(painter()->clipPath(), Qt::ReplaceClip);
+ else
+ updateClipPath(QPainterPath(), Qt::NoClip);
+ }
+
+ if (flags & DirtyClipPath) {
+ updateClipPath(state.clipPath(), state.clipOperation());
+ } else if (flags & DirtyClipRegion) {
+ updateClipRegion(state.clipRegion(), state.clipOperation());
+ }
+
+ // If the clip has changed we need to update all other states
+ // too, since they are included in the system context on OSX,
+ // and changing the clip resets that context back to scratch.
+ if (flags & (DirtyClipPath | DirtyClipRegion | DirtyClipEnabled))
+ flags |= AllDirty;
+
+ if (flags & DirtyPen)
+ updatePen(state.pen());
+ if (flags & (DirtyBrush|DirtyBrushOrigin))
+ updateBrush(state.brush(), state.brushOrigin());
+ if (flags & DirtyFont)
+ updateFont(state.font());
+ if (flags & DirtyOpacity)
+ updateOpacity(state.opacity());
+ if (flags & DirtyHints)
+ updateRenderHints(state.renderHints());
+ if (flags & DirtyCompositionMode)
+ updateCompositionMode(state.compositionMode());
+
+ if (flags & (DirtyPen | DirtyTransform)) {
+ if (!d->current.pen.isCosmetic()) {
+ d->cosmeticPen = QCoreGraphicsPaintEnginePrivate::CosmeticNone;
+ } else if (d->current.transform.m11() < d->current.transform.m22()-1.0 ||
+ d->current.transform.m11() > d->current.transform.m22()+1.0) {
+ d->cosmeticPen = QCoreGraphicsPaintEnginePrivate::CosmeticTransformPath;
+ d->cosmeticPenSize = d->adjustPenWidth(d->current.pen.widthF());
+ if (!d->cosmeticPenSize)
+ d->cosmeticPenSize = 1.0;
+ } else {
+ d->cosmeticPen = QCoreGraphicsPaintEnginePrivate::CosmeticSetPenWidth;
+ static const float sqrt2 = sqrt(2);
+ qreal width = d->current.pen.widthF();
+ if (!width)
+ width = 1;
+ d->cosmeticPenSize = sqrt(pow(d->pixelSize.y(), 2) + pow(d->pixelSize.x(), 2)) / sqrt2 * width;
+ }
+ }
+}
+
+void
+QCoreGraphicsPaintEngine::updatePen(const QPen &pen)
+{
+ Q_D(QCoreGraphicsPaintEngine);
+ Q_ASSERT(isActive());
+ d->current.pen = pen;
+ d->setStrokePen(pen);
+}
+
+void
+QCoreGraphicsPaintEngine::updateBrush(const QBrush &brush, const QPointF &brushOrigin)
+{
+ Q_D(QCoreGraphicsPaintEngine);
+ Q_ASSERT(isActive());
+ d->current.brush = brush;
+
+#ifdef QT_MAC_USE_NATIVE_GRADIENTS
+ // Quartz supports only pad spread
+ if (const QGradient *gradient = brush.gradient()) {
+ if (drawGradientNatively(gradient)) {
+ gccaps |= QPaintEngine::LinearGradientFill | QPaintEngine::RadialGradientFill;
+ } else {
+ gccaps &= ~(QPaintEngine::LinearGradientFill | QPaintEngine::RadialGradientFill);
+ }
+ }
+#endif
+
+ if (d->shading) {
+ CGShadingRelease(d->shading);
+ d->shading = 0;
+ }
+ d->setFillBrush(brushOrigin);
+}
+
+void
+QCoreGraphicsPaintEngine::updateOpacity(qreal opacity)
+{
+ Q_D(QCoreGraphicsPaintEngine);
+ CGContextSetAlpha(d->hd, opacity);
+}
+
+void
+QCoreGraphicsPaintEngine::updateFont(const QFont &)
+{
+ Q_D(QCoreGraphicsPaintEngine);
+ Q_ASSERT(isActive());
+ updatePen(d->current.pen);
+}
+
+void
+QCoreGraphicsPaintEngine::updateMatrix(const QTransform &transform)
+{
+ Q_D(QCoreGraphicsPaintEngine);
+ Q_ASSERT(isActive());
+
+ if (qt_is_nan(transform.m11()) || qt_is_nan(transform.m12()) || qt_is_nan(transform.m13())
+ || qt_is_nan(transform.m21()) || qt_is_nan(transform.m22()) || qt_is_nan(transform.m23())
+ || qt_is_nan(transform.m31()) || qt_is_nan(transform.m32()) || qt_is_nan(transform.m33()))
+ return;
+
+ d->current.transform = transform;
+ d->setTransform(transform.isIdentity() ? 0 : &transform);
+ d->complexXForm = (transform.m11() != 1 || transform.m22() != 1
+ || transform.m12() != 0 || transform.m21() != 0);
+ d->pixelSize = d->devicePixelSize(d->hd);
+}
+
+void
+QCoreGraphicsPaintEngine::updateClipPath(const QPainterPath &p, Qt::ClipOperation op)
+{
+ Q_D(QCoreGraphicsPaintEngine);
+ Q_ASSERT(isActive());
+ if(op == Qt::NoClip) {
+ if(d->current.clipEnabled) {
+ d->current.clipEnabled = false;
+ d->current.clip = QRegion();
+ d->setClip(0);
+ }
+ } else {
+ if(!d->current.clipEnabled)
+ op = Qt::ReplaceClip;
+ d->current.clipEnabled = true;
+ QRegion clipRegion(p.toFillPolygon().toPolygon(), p.fillRule());
+ if(op == Qt::ReplaceClip) {
+ d->current.clip = clipRegion;
+ d->setClip(0);
+ if(p.isEmpty()) {
+ CGRect rect = CGRectMake(0, 0, 0, 0);
+ CGContextClipToRect(d->hd, rect);
+ } else {
+ CGMutablePathRef path = qt_mac_compose_path(p);
+ CGContextBeginPath(d->hd);
+ CGContextAddPath(d->hd, path);
+ if(p.fillRule() == Qt::WindingFill)
+ CGContextClip(d->hd);
+ else
+ CGContextEOClip(d->hd);
+ CGPathRelease(path);
+ }
+ } else if(op == Qt::IntersectClip) {
+ d->current.clip = d->current.clip.intersected(clipRegion);
+ d->setClip(&d->current.clip);
+ }
+ }
+}
+
+void
+QCoreGraphicsPaintEngine::updateClipRegion(const QRegion &clipRegion, Qt::ClipOperation op)
+{
+ Q_D(QCoreGraphicsPaintEngine);
+ Q_ASSERT(isActive());
+ if(op == Qt::NoClip) {
+ d->current.clipEnabled = false;
+ d->current.clip = QRegion();
+ d->setClip(0);
+ } else {
+ if(!d->current.clipEnabled)
+ op = Qt::ReplaceClip;
+ d->current.clipEnabled = true;
+ if(op == Qt::IntersectClip)
+ d->current.clip = d->current.clip.intersected(clipRegion);
+ else if(op == Qt::ReplaceClip)
+ d->current.clip = clipRegion;
+ d->setClip(&d->current.clip);
+ }
+}
+
+void
+QCoreGraphicsPaintEngine::drawPath(const QPainterPath &p)
+{
+ Q_D(QCoreGraphicsPaintEngine);
+ Q_ASSERT(isActive());
+
+ if (state->compositionMode() == QPainter::CompositionMode_Destination)
+ return;
+
+ CGMutablePathRef path = qt_mac_compose_path(p);
+ uchar ops = QCoreGraphicsPaintEnginePrivate::CGStroke;
+ if(p.fillRule() == Qt::WindingFill)
+ ops |= QCoreGraphicsPaintEnginePrivate::CGFill;
+ else
+ ops |= QCoreGraphicsPaintEnginePrivate::CGEOFill;
+ CGContextBeginPath(d->hd);
+ d->drawPath(ops, path);
+ CGPathRelease(path);
+}
+
+void
+QCoreGraphicsPaintEngine::drawRects(const QRectF *rects, int rectCount)
+{
+ Q_D(QCoreGraphicsPaintEngine);
+ Q_ASSERT(isActive());
+
+ if (state->compositionMode() == QPainter::CompositionMode_Destination)
+ return;
+
+ for (int i=0; i<rectCount; ++i) {
+ QRectF r = rects[i];
+
+ CGMutablePathRef path = CGPathCreateMutable();
+ CGPathAddRect(path, 0, qt_mac_compose_rect(r));
+ d->drawPath(QCoreGraphicsPaintEnginePrivate::CGFill|QCoreGraphicsPaintEnginePrivate::CGStroke,
+ path);
+ CGPathRelease(path);
+ }
+}
+
+void
+QCoreGraphicsPaintEngine::drawPoints(const QPointF *points, int pointCount)
+{
+ Q_D(QCoreGraphicsPaintEngine);
+ Q_ASSERT(isActive());
+
+ if (state->compositionMode() == QPainter::CompositionMode_Destination)
+ return;
+
+ if (d->current.pen.capStyle() == Qt::FlatCap)
+ CGContextSetLineCap(d->hd, kCGLineCapSquare);
+
+ CGMutablePathRef path = CGPathCreateMutable();
+ for(int i=0; i < pointCount; i++) {
+ float x = points[i].x(), y = points[i].y();
+ CGPathMoveToPoint(path, 0, x, y);
+ CGPathAddLineToPoint(path, 0, x+0.001, y);
+ }
+
+ bool doRestore = false;
+ if(d->cosmeticPen == QCoreGraphicsPaintEnginePrivate::CosmeticNone && !(state->renderHints() & QPainter::Antialiasing)) {
+ //we don't want adjusted pens for point rendering
+ doRestore = true;
+ d->saveGraphicsState();
+ CGContextSetLineWidth(d->hd, d->current.pen.widthF());
+ }
+ d->drawPath(QCoreGraphicsPaintEnginePrivate::CGStroke, path);
+ if (doRestore)
+ d->restoreGraphicsState();
+ CGPathRelease(path);
+ if (d->current.pen.capStyle() == Qt::FlatCap)
+ CGContextSetLineCap(d->hd, kCGLineCapButt);
+}
+
+void
+QCoreGraphicsPaintEngine::drawEllipse(const QRectF &r)
+{
+ Q_D(QCoreGraphicsPaintEngine);
+ Q_ASSERT(isActive());
+
+ if (state->compositionMode() == QPainter::CompositionMode_Destination)
+ return;
+
+ CGMutablePathRef path = CGPathCreateMutable();
+ CGAffineTransform transform = CGAffineTransformMakeScale(r.width() / r.height(), 1);
+ CGPathAddArc(path, &transform,(r.x() + (r.width() / 2)) / (r.width() / r.height()),
+ r.y() + (r.height() / 2), r.height() / 2, 0, (2 * M_PI), false);
+ d->drawPath(QCoreGraphicsPaintEnginePrivate::CGFill | QCoreGraphicsPaintEnginePrivate::CGStroke,
+ path);
+ CGPathRelease(path);
+}
+
+void
+QCoreGraphicsPaintEngine::drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode)
+{
+ Q_D(QCoreGraphicsPaintEngine);
+ Q_ASSERT(isActive());
+
+ if (state->compositionMode() == QPainter::CompositionMode_Destination)
+ return;
+
+ CGMutablePathRef path = CGPathCreateMutable();
+ CGPathMoveToPoint(path, 0, points[0].x(), points[0].y());
+ for(int x = 1; x < pointCount; ++x)
+ CGPathAddLineToPoint(path, 0, points[x].x(), points[x].y());
+ if(mode != PolylineMode && points[0] != points[pointCount-1])
+ CGPathAddLineToPoint(path, 0, points[0].x(), points[0].y());
+ uint op = QCoreGraphicsPaintEnginePrivate::CGStroke;
+ if (mode != PolylineMode)
+ op |= mode == OddEvenMode ? QCoreGraphicsPaintEnginePrivate::CGEOFill
+ : QCoreGraphicsPaintEnginePrivate::CGFill;
+ d->drawPath(op, path);
+ CGPathRelease(path);
+}
+
+void
+QCoreGraphicsPaintEngine::drawLines(const QLineF *lines, int lineCount)
+{
+ Q_D(QCoreGraphicsPaintEngine);
+ Q_ASSERT(isActive());
+
+ if (state->compositionMode() == QPainter::CompositionMode_Destination)
+ return;
+
+ CGMutablePathRef path = CGPathCreateMutable();
+ for(int i = 0; i < lineCount; i++) {
+ const QPointF start = lines[i].p1(), end = lines[i].p2();
+ CGPathMoveToPoint(path, 0, start.x(), start.y());
+ CGPathAddLineToPoint(path, 0, end.x(), end.y());
+ }
+ d->drawPath(QCoreGraphicsPaintEnginePrivate::CGStroke, path);
+ CGPathRelease(path);
+}
+
+void QCoreGraphicsPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr)
+{
+ Q_D(QCoreGraphicsPaintEngine);
+ Q_ASSERT(isActive());
+
+ if (state->compositionMode() == QPainter::CompositionMode_Destination)
+ return;
+
+ if(pm.isNull())
+ return;
+
+ bool differentSize = (QRectF(0, 0, pm.width(), pm.height()) != sr), doRestore = false;
+ CGRect rect = CGRectMake(r.x(), r.y(), r.width(), r.height());
+ QCFType<CGImageRef> image;
+ bool isBitmap = (pm.depth() == 1);
+ if (isBitmap) {
+ doRestore = true;
+ d->saveGraphicsState();
+
+ const QColor &col = d->current.pen.color();
+ CGContextSetFillColorWithColor(d->hd, cgColorForQColor(col, d->pdev));
+ image = qt_mac_create_imagemask(pm, sr);
+ } else if (differentSize) {
+ QCFType<CGImageRef> img = pm.toMacCGImageRef();
+ image = CGImageCreateWithImageInRect(img, CGRectMake(qRound(sr.x()), qRound(sr.y()), qRound(sr.width()), qRound(sr.height())));
+ } else {
+ image = (CGImageRef)pm.macCGHandle();
+ }
+ qt_mac_drawCGImage(d->hd, &rect, image);
+ if (doRestore)
+ d->restoreGraphicsState();
+}
+
+void QCoreGraphicsPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRectF &sr,
+ Qt::ImageConversionFlags flags)
+{
+ Q_D(QCoreGraphicsPaintEngine);
+ Q_UNUSED(flags);
+ Q_ASSERT(isActive());
+
+ if (img.isNull() || state->compositionMode() == QPainter::CompositionMode_Destination)
+ return;
+
+ const QImage *image;
+ QCFType<CGImageRef> cgimage = qt_mac_createCGImageFromQImage(img, &image);
+ CGRect rect = CGRectMake(r.x(), r.y(), r.width(), r.height());
+ if (QRectF(0, 0, img.width(), img.height()) != sr)
+ cgimage = CGImageCreateWithImageInRect(cgimage, CGRectMake(sr.x(), sr.y(),
+ sr.width(), sr.height()));
+ qt_mac_drawCGImage(d->hd, &rect, cgimage);
+}
+
+void QCoreGraphicsPaintEngine::initialize()
+{
+}
+
+void QCoreGraphicsPaintEngine::cleanup()
+{
+}
+
+CGContextRef
+QCoreGraphicsPaintEngine::handle() const
+{
+ return d_func()->hd;
+}
+
+void
+QCoreGraphicsPaintEngine::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap,
+ const QPointF &p)
+{
+ Q_D(QCoreGraphicsPaintEngine);
+ Q_ASSERT(isActive());
+
+ if (state->compositionMode() == QPainter::CompositionMode_Destination)
+ return;
+
+ //save the old state
+ d->saveGraphicsState();
+
+ //setup the pattern
+ QMacPattern *qpattern = new QMacPattern;
+ qpattern->data.pixmap = pixmap;
+ qpattern->foreground = d->current.pen.color();
+ qpattern->pdev = d->pdev;
+ CGPatternCallbacks callbks;
+ callbks.version = 0;
+ callbks.drawPattern = qt_mac_draw_pattern;
+ callbks.releaseInfo = qt_mac_dispose_pattern;
+ const int width = qpattern->width(), height = qpattern->height();
+ CGAffineTransform trans = CGContextGetCTM(d->hd);
+ CGPatternRef pat = CGPatternCreate(qpattern, CGRectMake(0, 0, width, height),
+ trans, width, height,
+ kCGPatternTilingNoDistortion, true, &callbks);
+ CGColorSpaceRef cs = CGColorSpaceCreatePattern(0);
+ CGContextSetFillColorSpace(d->hd, cs);
+ CGFloat component = 1.0; //just one
+ CGContextSetFillPattern(d->hd, pat, &component);
+ CGSize phase = CGSizeApplyAffineTransform(CGSizeMake(-(p.x()-r.x()), -(p.y()-r.y())), trans);
+ CGContextSetPatternPhase(d->hd, phase);
+
+ //fill the rectangle
+ CGRect mac_rect = CGRectMake(r.x(), r.y(), r.width(), r.height());
+ CGContextFillRect(d->hd, mac_rect);
+
+ //restore the state
+ d->restoreGraphicsState();
+ //cleanup
+ CGColorSpaceRelease(cs);
+ CGPatternRelease(pat);
+}
+
+void QCoreGraphicsPaintEngine::drawTextItem(const QPointF &pos, const QTextItem &item)
+{
+ Q_D(QCoreGraphicsPaintEngine);
+ if (d->current.transform.type() == QTransform::TxProject
+#ifndef QMAC_NATIVE_GRADIENTS
+ || painter()->pen().brush().gradient() //Just let the base engine "emulate" the gradient
+#endif
+ ) {
+ QPaintEngine::drawTextItem(pos, item);
+ return;
+ }
+
+ if (state->compositionMode() == QPainter::CompositionMode_Destination)
+ return;
+
+ const QTextItemInt &ti = static_cast<const QTextItemInt &>(item);
+
+ QPen oldPen = painter()->pen();
+ QBrush oldBrush = painter()->brush();
+ QPointF oldBrushOrigin = painter()->brushOrigin();
+ updatePen(Qt::NoPen);
+ updateBrush(oldPen.brush(), QPointF(0, 0));
+
+ Q_ASSERT(type() == QPaintEngine::CoreGraphics);
+
+ QFontEngine *fe = ti.fontEngine;
+
+ const bool textAA = state->renderHints() & QPainter::TextAntialiasing && fe->fontDef.pointSize > qt_antialiasing_threshold && !(fe->fontDef.styleStrategy & QFont::NoAntialias);
+ const bool lineAA = state->renderHints() & QPainter::Antialiasing;
+ if(textAA != lineAA)
+ CGContextSetShouldAntialias(d->hd, textAA);
+
+ if (ti.glyphs.numGlyphs) {
+ switch (fe->type()) {
+ case QFontEngine::Mac:
+#ifdef QT_MAC_USE_COCOA
+ static_cast<QCoreTextFontEngine *>(fe)->draw(d->hd, pos.x(), pos.y(), ti, paintDevice()->height());
+#else
+ static_cast<QFontEngineMac *>(fe)->draw(d->hd, pos.x(), pos.y(), ti, paintDevice()->height());
+#endif
+ break;
+ case QFontEngine::Box:
+ d->drawBoxTextItem(pos, ti);
+ break;
+ default:
+ break;
+ }
+ }
+
+ if(textAA != lineAA)
+ CGContextSetShouldAntialias(d->hd, !textAA);
+
+ updatePen(oldPen);
+ updateBrush(oldBrush, oldBrushOrigin);
+}
+
+QPainter::RenderHints
+QCoreGraphicsPaintEngine::supportedRenderHints() const
+{
+ return QPainter::RenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
+}
+enum CGCompositeMode {
+ kCGCompositeModeClear = 0,
+ kCGCompositeModeCopy = 1,
+ kCGCompositeModeSourceOver = 2,
+ kCGCompositeModeSourceIn = 3,
+ kCGCompositeModeSourceOut = 4,
+ kCGCompositeModeSourceAtop = 5,
+ kCGCompositeModeDestinationOver = 6,
+ kCGCompositeModeDestinationIn = 7,
+ kCGCompositeModeDestinationOut = 8,
+ kCGCompositeModeDestinationAtop = 9,
+ kCGCompositeModeXOR = 10,
+ kCGCompositeModePlusDarker = 11, // (max (0, (1-d) + (1-s)))
+ kCGCompositeModePlusLighter = 12, // (min (1, s + d))
+ };
+extern "C" {
+ extern void CGContextSetCompositeOperation(CGContextRef, int);
+} // private function, but is in all versions of OS X.
+void
+QCoreGraphicsPaintEngine::updateCompositionMode(QPainter::CompositionMode mode)
+{
+#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
+ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) {
+ int cg_mode = kCGBlendModeNormal;
+ switch(mode) {
+ case QPainter::CompositionMode_Multiply:
+ cg_mode = kCGBlendModeMultiply;
+ break;
+ case QPainter::CompositionMode_Screen:
+ cg_mode = kCGBlendModeScreen;
+ break;
+ case QPainter::CompositionMode_Overlay:
+ cg_mode = kCGBlendModeOverlay;
+ break;
+ case QPainter::CompositionMode_Darken:
+ cg_mode = kCGBlendModeDarken;
+ break;
+ case QPainter::CompositionMode_Lighten:
+ cg_mode = kCGBlendModeLighten;
+ break;
+ case QPainter::CompositionMode_ColorDodge:
+ cg_mode = kCGBlendModeColorDodge;
+ break;
+ case QPainter::CompositionMode_ColorBurn:
+ cg_mode = kCGBlendModeColorBurn;
+ break;
+ case QPainter::CompositionMode_HardLight:
+ cg_mode = kCGBlendModeHardLight;
+ break;
+ case QPainter::CompositionMode_SoftLight:
+ cg_mode = kCGBlendModeSoftLight;
+ break;
+ case QPainter::CompositionMode_Difference:
+ cg_mode = kCGBlendModeDifference;
+ break;
+ case QPainter::CompositionMode_Exclusion:
+ cg_mode = kCGBlendModeExclusion;
+ break;
+ case QPainter::CompositionMode_Plus:
+ cg_mode = kCGBlendModePlusLighter;
+ break;
+ case QPainter::CompositionMode_SourceOver:
+ cg_mode = kCGBlendModeNormal;
+ break;
+ case QPainter::CompositionMode_DestinationOver:
+ cg_mode = kCGBlendModeDestinationOver;
+ break;
+ case QPainter::CompositionMode_Clear:
+ cg_mode = kCGBlendModeClear;
+ break;
+ case QPainter::CompositionMode_Source:
+ cg_mode = kCGBlendModeCopy;
+ break;
+ case QPainter::CompositionMode_Destination:
+ cg_mode = -1;
+ break;
+ case QPainter::CompositionMode_SourceIn:
+ cg_mode = kCGBlendModeSourceIn;
+ break;
+ case QPainter::CompositionMode_DestinationIn:
+ cg_mode = kCGCompositeModeDestinationIn;
+ break;
+ case QPainter::CompositionMode_SourceOut:
+ cg_mode = kCGBlendModeSourceOut;
+ break;
+ case QPainter::CompositionMode_DestinationOut:
+ cg_mode = kCGBlendModeDestinationOver;
+ break;
+ case QPainter::CompositionMode_SourceAtop:
+ cg_mode = kCGBlendModeSourceAtop;
+ break;
+ case QPainter::CompositionMode_DestinationAtop:
+ cg_mode = kCGBlendModeDestinationAtop;
+ break;
+ case QPainter::CompositionMode_Xor:
+ cg_mode = kCGBlendModeXOR;
+ break;
+ default:
+ break;
+ }
+ if (cg_mode > -1) {
+ CGContextSetBlendMode(d_func()->hd, CGBlendMode(cg_mode));
+ }
+ } else
+#endif
+ // The standard porter duff ops.
+ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_3
+ && mode <= QPainter::CompositionMode_Xor) {
+ int cg_mode = kCGCompositeModeCopy;
+ switch (mode) {
+ case QPainter::CompositionMode_SourceOver:
+ cg_mode = kCGCompositeModeSourceOver;
+ break;
+ case QPainter::CompositionMode_DestinationOver:
+ cg_mode = kCGCompositeModeDestinationOver;
+ break;
+ case QPainter::CompositionMode_Clear:
+ cg_mode = kCGCompositeModeClear;
+ break;
+ default:
+ qWarning("QCoreGraphicsPaintEngine: Unhandled composition mode %d", (int)mode);
+ break;
+ case QPainter::CompositionMode_Source:
+ cg_mode = kCGCompositeModeCopy;
+ break;
+ case QPainter::CompositionMode_Destination:
+ cg_mode = CGCompositeMode(-1);
+ break;
+ case QPainter::CompositionMode_SourceIn:
+ cg_mode = kCGCompositeModeSourceIn;
+ break;
+ case QPainter::CompositionMode_DestinationIn:
+ cg_mode = kCGCompositeModeDestinationIn;
+ break;
+ case QPainter::CompositionMode_SourceOut:
+ cg_mode = kCGCompositeModeSourceOut;
+ break;
+ case QPainter::CompositionMode_DestinationOut:
+ cg_mode = kCGCompositeModeDestinationOut;
+ break;
+ case QPainter::CompositionMode_SourceAtop:
+ cg_mode = kCGCompositeModeSourceAtop;
+ break;
+ case QPainter::CompositionMode_DestinationAtop:
+ cg_mode = kCGCompositeModeDestinationAtop;
+ break;
+ case QPainter::CompositionMode_Xor:
+ cg_mode = kCGCompositeModeXOR;
+ break;
+ }
+ if (cg_mode > -1)
+ CGContextSetCompositeOperation(d_func()->hd, CGCompositeMode(cg_mode));
+ } else {
+#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4)
+ bool needPrivateAPI = false;
+ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4) {
+ int cg_mode = kCGBlendModeNormal;
+ switch (mode) {
+ case QPainter::CompositionMode_Multiply:
+ cg_mode = kCGBlendModeMultiply;
+ break;
+ case QPainter::CompositionMode_Screen:
+ cg_mode = kCGBlendModeScreen;
+ break;
+ case QPainter::CompositionMode_Overlay:
+ cg_mode = kCGBlendModeOverlay;
+ break;
+ case QPainter::CompositionMode_Darken:
+ cg_mode = kCGBlendModeDarken;
+ break;
+ case QPainter::CompositionMode_Lighten:
+ cg_mode = kCGBlendModeLighten;
+ break;
+ case QPainter::CompositionMode_ColorDodge:
+ cg_mode = kCGBlendModeColorDodge;
+ break;
+ case QPainter::CompositionMode_ColorBurn:
+ cg_mode = kCGBlendModeColorBurn;
+ break;
+ case QPainter::CompositionMode_HardLight:
+ cg_mode = kCGBlendModeHardLight;
+ break;
+ case QPainter::CompositionMode_SoftLight:
+ cg_mode = kCGBlendModeSoftLight;
+ break;
+ case QPainter::CompositionMode_Difference:
+ cg_mode = kCGBlendModeDifference;
+ break;
+ case QPainter::CompositionMode_Exclusion:
+ cg_mode = kCGBlendModeExclusion;
+ break;
+ case QPainter::CompositionMode_Plus:
+ needPrivateAPI = true;
+ cg_mode = kCGCompositeModePlusLighter;
+ break;
+ default:
+ break;
+ }
+ if (!needPrivateAPI)
+ CGContextSetBlendMode(d_func()->hd, CGBlendMode(cg_mode));
+ else
+ CGContextSetCompositeOperation(d_func()->hd, CGCompositeMode(cg_mode));
+ }
+#endif
+ }
+}
+
+void
+QCoreGraphicsPaintEngine::updateRenderHints(QPainter::RenderHints hints)
+{
+ Q_D(QCoreGraphicsPaintEngine);
+ CGContextSetShouldAntialias(d->hd, hints & QPainter::Antialiasing);
+ static const CGFloat ScaleFactor = qt_mac_get_scalefactor();
+ if (ScaleFactor > 1.) {
+ CGContextSetInterpolationQuality(d->hd, kCGInterpolationHigh);
+ } else {
+ CGContextSetInterpolationQuality(d->hd, (hints & QPainter::SmoothPixmapTransform) ?
+ kCGInterpolationHigh : kCGInterpolationNone);
+ }
+ bool textAntialiasing = (hints & QPainter::TextAntialiasing) == QPainter::TextAntialiasing;
+ if (!textAntialiasing || d->disabledSmoothFonts) {
+ d->disabledSmoothFonts = !textAntialiasing;
+ CGContextSetShouldSmoothFonts(d->hd, textAntialiasing);
+ }
+}
+
+/*
+ Returns the size of one device pixel in user-space coordinates.
+*/
+QPointF QCoreGraphicsPaintEnginePrivate::devicePixelSize(CGContextRef)
+{
+ QPointF p1 = current.transform.inverted().map(QPointF(0, 0));
+ QPointF p2 = current.transform.inverted().map(QPointF(1, 1));
+ return QPointF(qAbs(p2.x() - p1.x()), qAbs(p2.y() - p1.y()));
+}
+
+/*
+ Adjusts the pen width so we get correct line widths in the
+ non-transformed, aliased case.
+*/
+float QCoreGraphicsPaintEnginePrivate::adjustPenWidth(float penWidth)
+{
+ Q_Q(QCoreGraphicsPaintEngine);
+ float ret = penWidth;
+ if (!complexXForm && !(q->state->renderHints() & QPainter::Antialiasing)) {
+ if (penWidth < 2)
+ ret = 1;
+ else if (penWidth < 3)
+ ret = 1.5;
+ else
+ ret = penWidth -1;
+ }
+ return ret;
+}
+
+void
+QCoreGraphicsPaintEnginePrivate::setStrokePen(const QPen &pen)
+{
+ //pencap
+ CGLineCap cglinecap = kCGLineCapButt;
+ if(pen.capStyle() == Qt::SquareCap)
+ cglinecap = kCGLineCapSquare;
+ else if(pen.capStyle() == Qt::RoundCap)
+ cglinecap = kCGLineCapRound;
+ CGContextSetLineCap(hd, cglinecap);
+ CGContextSetLineWidth(hd, adjustPenWidth(pen.widthF()));
+
+ //join
+ CGLineJoin cglinejoin = kCGLineJoinMiter;
+ if(pen.joinStyle() == Qt::BevelJoin)
+ cglinejoin = kCGLineJoinBevel;
+ else if(pen.joinStyle() == Qt::RoundJoin)
+ cglinejoin = kCGLineJoinRound;
+ CGContextSetLineJoin(hd, cglinejoin);
+// CGContextSetMiterLimit(hd, pen.miterLimit());
+
+ //pen style
+ QVector<CGFloat> linedashes;
+ if(pen.style() == Qt::CustomDashLine) {
+ QVector<qreal> customs = pen.dashPattern();
+ for(int i = 0; i < customs.size(); ++i)
+ linedashes.append(customs.at(i));
+ } else if(pen.style() == Qt::DashLine) {
+ linedashes.append(4);
+ linedashes.append(2);
+ } else if(pen.style() == Qt::DotLine) {
+ linedashes.append(1);
+ linedashes.append(2);
+ } else if(pen.style() == Qt::DashDotLine) {
+ linedashes.append(4);
+ linedashes.append(2);
+ linedashes.append(1);
+ linedashes.append(2);
+ } else if(pen.style() == Qt::DashDotDotLine) {
+ linedashes.append(4);
+ linedashes.append(2);
+ linedashes.append(1);
+ linedashes.append(2);
+ linedashes.append(1);
+ linedashes.append(2);
+ }
+ const CGFloat cglinewidth = pen.widthF() <= 0.0f ? 1.0f : float(pen.widthF());
+ for(int i = 0; i < linedashes.size(); ++i) {
+ linedashes[i] *= cglinewidth;
+ if(cglinewidth < 3 && (cglinecap == kCGLineCapSquare || cglinecap == kCGLineCapRound)) {
+ if((i%2))
+ linedashes[i] += cglinewidth/2;
+ else
+ linedashes[i] -= cglinewidth/2;
+ }
+ }
+ CGContextSetLineDash(hd, pen.dashOffset() * cglinewidth, linedashes.data(), linedashes.size());
+
+ // color
+ CGContextSetStrokeColorWithColor(hd, cgColorForQColor(pen.color(), pdev));
+}
+
+// Add our own patterns here to deal with the fact that the coordinate system
+// is flipped vertically with Quartz2D.
+static const uchar *qt_mac_patternForBrush(int brushStyle)
+{
+ Q_ASSERT(brushStyle > Qt::SolidPattern && brushStyle < Qt::LinearGradientPattern);
+ static const uchar dense1_pat[] = { 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x44, 0x00 };
+ static const uchar dense2_pat[] = { 0x00, 0x22, 0x00, 0x88, 0x00, 0x22, 0x00, 0x88 };
+ static const uchar dense3_pat[] = { 0x11, 0xaa, 0x44, 0xaa, 0x11, 0xaa, 0x44, 0xaa };
+ static const uchar dense4_pat[] = { 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55 };
+ static const uchar dense5_pat[] = { 0xee, 0x55, 0xbb, 0x55, 0xee, 0x55, 0xbb, 0x55 };
+ static const uchar dense6_pat[] = { 0xff, 0xdd, 0xff, 0x77, 0xff, 0xdd, 0xff, 0x77 };
+ static const uchar dense7_pat[] = { 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb, 0xff };
+ static const uchar hor_pat[] = { 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff };
+ static const uchar ver_pat[] = { 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef };
+ static const uchar cross_pat[] = { 0xef, 0xef, 0xef, 0xef, 0x00, 0xef, 0xef, 0xef };
+ static const uchar fdiag_pat[] = { 0x7f, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0xfe };
+ static const uchar bdiag_pat[] = { 0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f };
+ static const uchar dcross_pat[] = { 0x7e, 0xbd, 0xdb, 0xe7, 0xe7, 0xdb, 0xbd, 0x7e };
+ static const uchar *const pat_tbl[] = {
+ dense1_pat, dense2_pat, dense3_pat, dense4_pat, dense5_pat,
+ dense6_pat, dense7_pat,
+ hor_pat, ver_pat, cross_pat, bdiag_pat, fdiag_pat, dcross_pat };
+ return pat_tbl[brushStyle - Qt::Dense1Pattern];
+}
+
+void QCoreGraphicsPaintEnginePrivate::setFillBrush(const QPointF &offset)
+{
+ // pattern
+ Qt::BrushStyle bs = current.brush.style();
+#ifdef QT_MAC_USE_NATIVE_GRADIENTS
+ if (bs == Qt::LinearGradientPattern || bs == Qt::RadialGradientPattern) {
+ const QGradient *grad = static_cast<const QGradient*>(current.brush.gradient());
+ if (drawGradientNatively(grad)) {
+ Q_ASSERT(grad->spread() == QGradient::PadSpread);
+
+ static const CGFloat domain[] = { 0.0f, +1.0f };
+ static const CGFunctionCallbacks callbacks = { 0, qt_mac_color_gradient_function, 0 };
+ CGFunctionRef fill_func = CGFunctionCreate(reinterpret_cast<void *>(&current.brush),
+ 1, domain, 4, 0, &callbacks);
+
+ CGColorSpaceRef colorspace = qt_mac_colorSpaceForDeviceType(pdev);
+ if (bs == Qt::LinearGradientPattern) {
+ const QLinearGradient *linearGrad = static_cast<const QLinearGradient *>(grad);
+ const QPointF start(linearGrad->start());
+ const QPointF stop(linearGrad->finalStop());
+ shading = CGShadingCreateAxial(colorspace, CGPointMake(start.x(), start.y()),
+ CGPointMake(stop.x(), stop.y()), fill_func, true, true);
+ } else {
+ Q_ASSERT(bs == Qt::RadialGradientPattern);
+ const QRadialGradient *radialGrad = static_cast<const QRadialGradient *>(grad);
+ QPointF center(radialGrad->center());
+ QPointF focal(radialGrad->focalPoint());
+ qreal radius = radialGrad->radius();
+ qreal focalRadius = radialGrad->focalRadius();
+ shading = CGShadingCreateRadial(colorspace, CGPointMake(focal.x(), focal.y()),
+ focalRadius, CGPointMake(center.x(), center.y()), radius, fill_func, false, true);
+ }
+
+ CGFunctionRelease(fill_func);
+ }
+ } else
+#endif
+ if(bs != Qt::SolidPattern && bs != Qt::NoBrush
+#ifndef QT_MAC_USE_NATIVE_GRADIENTS
+ && (bs < Qt::LinearGradientPattern || bs > Qt::ConicalGradientPattern)
+#endif
+ )
+ {
+ QMacPattern *qpattern = new QMacPattern;
+ qpattern->pdev = pdev;
+ CGFloat components[4] = { 1.0, 1.0, 1.0, 1.0 };
+ CGColorSpaceRef base_colorspace = 0;
+ if(bs == Qt::TexturePattern) {
+ qpattern->data.pixmap = current.brush.texture();
+ if(qpattern->data.pixmap.isQBitmap()) {
+ const QColor &col = current.brush.color();
+ components[0] = qt_mac_convert_color_to_cg(col.red());
+ components[1] = qt_mac_convert_color_to_cg(col.green());
+ components[2] = qt_mac_convert_color_to_cg(col.blue());
+ base_colorspace = QCoreGraphicsPaintEngine::macGenericColorSpace();
+ }
+ } else {
+ qpattern->as_mask = true;
+
+ qpattern->data.bytes = qt_mac_patternForBrush(bs);
+ const QColor &col = current.brush.color();
+ components[0] = qt_mac_convert_color_to_cg(col.red());
+ components[1] = qt_mac_convert_color_to_cg(col.green());
+ components[2] = qt_mac_convert_color_to_cg(col.blue());
+ base_colorspace = QCoreGraphicsPaintEngine::macGenericColorSpace();
+ }
+ int width = qpattern->width(), height = qpattern->height();
+ qpattern->foreground = current.brush.color();
+
+ CGColorSpaceRef fill_colorspace = CGColorSpaceCreatePattern(base_colorspace);
+ CGContextSetFillColorSpace(hd, fill_colorspace);
+
+ CGAffineTransform xform = CGContextGetCTM(hd);
+ xform = CGAffineTransformConcat(qt_mac_convert_transform_to_cg(current.brush.transform()), xform);
+ xform = CGAffineTransformTranslate(xform, offset.x(), offset.y());
+
+ CGPatternCallbacks callbks;
+ callbks.version = 0;
+ callbks.drawPattern = qt_mac_draw_pattern;
+ callbks.releaseInfo = qt_mac_dispose_pattern;
+ CGPatternRef fill_pattern = CGPatternCreate(qpattern, CGRectMake(0, 0, width, height),
+ xform, width, height, kCGPatternTilingNoDistortion,
+ !base_colorspace, &callbks);
+ CGContextSetFillPattern(hd, fill_pattern, components);
+
+ CGPatternRelease(fill_pattern);
+ CGColorSpaceRelease(fill_colorspace);
+ } else if(bs != Qt::NoBrush) {
+ CGContextSetFillColorWithColor(hd, cgColorForQColor(current.brush.color(), pdev));
+ }
+}
+
+void
+QCoreGraphicsPaintEnginePrivate::setClip(const QRegion *rgn)
+{
+ Q_Q(QCoreGraphicsPaintEngine);
+ if(hd) {
+ resetClip();
+ QRegion sysClip = q->systemClip();
+ if(!sysClip.isEmpty())
+ qt_mac_clip_cg(hd, sysClip, &orig_xform);
+ if(rgn)
+ qt_mac_clip_cg(hd, *rgn, 0);
+ }
+}
+
+struct qt_mac_cg_transform_path {
+ CGMutablePathRef path;
+ CGAffineTransform transform;
+};
+
+void qt_mac_cg_transform_path_apply(void *info, const CGPathElement *element)
+{
+ Q_ASSERT(info && element);
+ qt_mac_cg_transform_path *t = (qt_mac_cg_transform_path*)info;
+ switch(element->type) {
+ case kCGPathElementMoveToPoint:
+ CGPathMoveToPoint(t->path, &t->transform, element->points[0].x, element->points[0].y);
+ break;
+ case kCGPathElementAddLineToPoint:
+ CGPathAddLineToPoint(t->path, &t->transform, element->points[0].x, element->points[0].y);
+ break;
+ case kCGPathElementAddQuadCurveToPoint:
+ CGPathAddQuadCurveToPoint(t->path, &t->transform, element->points[0].x, element->points[0].y,
+ element->points[1].x, element->points[1].y);
+ break;
+ case kCGPathElementAddCurveToPoint:
+ CGPathAddCurveToPoint(t->path, &t->transform, element->points[0].x, element->points[0].y,
+ element->points[1].x, element->points[1].y,
+ element->points[2].x, element->points[2].y);
+ break;
+ case kCGPathElementCloseSubpath:
+ CGPathCloseSubpath(t->path);
+ break;
+ default:
+ qDebug() << "Unhandled path transform type: " << element->type;
+ }
+}
+
+void QCoreGraphicsPaintEnginePrivate::drawPath(uchar ops, CGMutablePathRef path)
+{
+ Q_Q(QCoreGraphicsPaintEngine);
+ Q_ASSERT((ops & (CGFill | CGEOFill)) != (CGFill | CGEOFill)); //can't really happen
+ if((ops & (CGFill | CGEOFill))) {
+ if (shading) {
+ Q_ASSERT(path);
+ CGContextBeginPath(hd);
+ CGContextAddPath(hd, path);
+ saveGraphicsState();
+ if (ops & CGFill)
+ CGContextClip(hd);
+ else if (ops & CGEOFill)
+ CGContextEOClip(hd);
+ if (current.brush.gradient()->coordinateMode() == QGradient::ObjectBoundingMode) {
+ CGRect boundingBox = CGPathGetBoundingBox(path);
+ CGContextConcatCTM(hd,
+ CGAffineTransformMake(boundingBox.size.width, 0,
+ 0, boundingBox.size.height,
+ boundingBox.origin.x, boundingBox.origin.y));
+ }
+ CGContextDrawShading(hd, shading);
+ restoreGraphicsState();
+ ops &= ~CGFill;
+ ops &= ~CGEOFill;
+ } else if (current.brush.style() == Qt::NoBrush) {
+ ops &= ~CGFill;
+ ops &= ~CGEOFill;
+ }
+ }
+ if((ops & CGStroke) && current.pen.style() == Qt::NoPen)
+ ops &= ~CGStroke;
+
+ if(ops & (CGEOFill | CGFill)) {
+ CGContextBeginPath(hd);
+ CGContextAddPath(hd, path);
+ if (ops & CGEOFill) {
+ CGContextEOFillPath(hd);
+ } else {
+ CGContextFillPath(hd);
+ }
+ }
+
+ // Avoid saving and restoring the context if we can.
+ const bool needContextSave = (cosmeticPen != QCoreGraphicsPaintEnginePrivate::CosmeticNone ||
+ !(q->state->renderHints() & QPainter::Antialiasing));
+ if(ops & CGStroke) {
+ if (needContextSave)
+ saveGraphicsState();
+ CGContextBeginPath(hd);
+
+ // Translate a fraction of a pixel size in the y direction
+ // to make sure that primitives painted at pixel borders
+ // fills the right pixel. This is needed since the y xais
+ // in the Quartz coordinate system is inverted compared to Qt.
+ if (!(q->state->renderHints() & QPainter::Antialiasing)) {
+ if (current.pen.style() == Qt::SolidLine || current.pen.width() >= 3)
+ CGContextTranslateCTM(hd, double(pixelSize.x()) * 0.25, double(pixelSize.y()) * 0.25);
+ else if (current.pen.style() == Qt::DotLine && QSysInfo::MacintoshVersion == QSysInfo::MV_10_3)
+ ; // Do nothing.
+ else
+ CGContextTranslateCTM(hd, 0, double(pixelSize.y()) * 0.1);
+ }
+
+ if (cosmeticPen != QCoreGraphicsPaintEnginePrivate::CosmeticNone) {
+ // If antialiazing is enabled, use the cosmetic pen size directly.
+ if (q->state->renderHints() & QPainter::Antialiasing)
+ CGContextSetLineWidth(hd, cosmeticPenSize);
+ else if (current.pen.widthF() <= 1)
+ CGContextSetLineWidth(hd, cosmeticPenSize * 0.9f);
+ else
+ CGContextSetLineWidth(hd, cosmeticPenSize);
+ }
+ if(cosmeticPen == QCoreGraphicsPaintEnginePrivate::CosmeticTransformPath) {
+ qt_mac_cg_transform_path t;
+ t.transform = qt_mac_convert_transform_to_cg(current.transform);
+ t.path = CGPathCreateMutable();
+ CGPathApply(path, &t, qt_mac_cg_transform_path_apply); //transform the path
+ setTransform(0); //unset the context transform
+ CGContextSetLineWidth(hd, cosmeticPenSize);
+ CGContextAddPath(hd, t.path);
+ CGPathRelease(t.path);
+ } else {
+ CGContextAddPath(hd, path);
+ }
+
+ CGContextStrokePath(hd);
+ if (needContextSave)
+ restoreGraphicsState();
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/painting/qpaintengine_mac_p.h b/src/widgets/platforms/mac/qpaintengine_mac_p.h
index 2434011e52..2434011e52 100644
--- a/src/gui/painting/qpaintengine_mac_p.h
+++ b/src/widgets/platforms/mac/qpaintengine_mac_p.h
diff --git a/src/widgets/platforms/mac/qpixmap_mac.cpp b/src/widgets/platforms/mac/qpixmap_mac.cpp
new file mode 100644
index 0000000000..a375eda6a2
--- /dev/null
+++ b/src/widgets/platforms/mac/qpixmap_mac.cpp
@@ -0,0 +1,1174 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qpixmap.h"
+#include "qimage.h"
+#include "qapplication.h"
+#include "qbitmap.h"
+#include "qmatrix.h"
+#include "qtransform.h"
+#include "qlibrary.h"
+#include "qvarlengtharray.h"
+#include "qdebug.h"
+#include <private/qdrawhelper_p.h>
+#include <private/qpixmap_mac_p.h>
+#include <private/qpixmap_raster_p.h>
+#include <private/qpaintengine_mac_p.h>
+#include <private/qt_mac_p.h>
+#include <private/qt_cocoa_helpers_mac_p.h>
+#include <private/qapplication_p.h>
+
+#include <limits.h>
+#include <string.h>
+
+QT_BEGIN_NAMESPACE
+
+/*****************************************************************************
+ Externals
+ *****************************************************************************/
+extern const uchar *qt_get_bitflip_array(); //qimage.cpp
+extern CGContextRef qt_mac_cg_context(const QPaintDevice *pdev); //qpaintdevice_mac.cpp
+extern RgnHandle qt_mac_get_rgn(); //qregion_mac.cpp
+extern void qt_mac_dispose_rgn(RgnHandle r); //qregion_mac.cpp
+extern QRegion qt_mac_convert_mac_region(RgnHandle rgn); //qregion_mac.cpp
+
+static int qt_pixmap_serial = 0;
+
+Q_WIDGETS_EXPORT quint32 *qt_mac_pixmap_get_base(const QPixmap *pix)
+{
+ if (QApplicationPrivate::graphics_system_name == QLatin1String("raster"))
+ return reinterpret_cast<quint32 *>(static_cast<QRasterPlatformPixmap*>(pix->data.data())->buffer()->bits());
+ else
+ return static_cast<QMacPlatformPixmap*>(pix->data.data())->pixels;
+}
+
+Q_WIDGETS_EXPORT int qt_mac_pixmap_get_bytes_per_line(const QPixmap *pix)
+{
+ if (QApplicationPrivate::graphics_system_name == QLatin1String("raster"))
+ return static_cast<QRasterPlatformPixmap*>(pix->data.data())->buffer()->bytesPerLine();
+ else
+ return static_cast<QMacPlatformPixmap*>(pix->data.data())->bytesPerRow;
+}
+
+void qt_mac_cgimage_data_free(void *info, const void *memoryToFree, size_t)
+{
+ QMacPlatformPixmap *pmdata = static_cast<QMacPlatformPixmap *>(info);
+ if (!pmdata) {
+ free(const_cast<void *>(memoryToFree));
+ } else {
+ if (QMacPlatformPixmap::validDataPointers.contains(pmdata) == false) {
+ free(const_cast<void *>(memoryToFree));
+ return;
+ }
+ if (pmdata->pixels == pmdata->pixelsToFree) {
+ // something we aren't expecting, just free it.
+ Q_ASSERT(memoryToFree != pmdata->pixelsToFree);
+ free(const_cast<void *>(memoryToFree));
+ } else {
+ free(pmdata->pixelsToFree);
+ pmdata->pixelsToFree = static_cast<quint32 *>(const_cast<void *>(memoryToFree));
+ }
+ pmdata->cg_dataBeingReleased = 0;
+ }
+}
+
+/*****************************************************************************
+ QPixmap member functions
+ *****************************************************************************/
+
+static inline QRgb qt_conv16ToRgb(ushort c) {
+ static const int qt_rbits = (565/100);
+ static const int qt_gbits = (565/10%10);
+ static const int qt_bbits = (565%10);
+ static const int qt_red_shift = qt_bbits+qt_gbits-(8-qt_rbits);
+ static const int qt_green_shift = qt_bbits-(8-qt_gbits);
+ static const int qt_neg_blue_shift = 8-qt_bbits;
+ static const int qt_blue_mask = (1<<qt_bbits)-1;
+ static const int qt_green_mask = (1<<(qt_gbits+qt_bbits))-((1<<qt_bbits)-1);
+ static const int qt_red_mask = (1<<(qt_rbits+qt_gbits+qt_bbits))-(1<<(qt_gbits+qt_bbits));
+
+ const int r=(c & qt_red_mask);
+ const int g=(c & qt_green_mask);
+ const int b=(c & qt_blue_mask);
+ const int tr = r >> qt_red_shift;
+ const int tg = g >> qt_green_shift;
+ const int tb = b << qt_neg_blue_shift;
+
+ return qRgb(tr,tg,tb);
+}
+
+QSet<QMacPlatformPixmap*> QMacPlatformPixmap::validDataPointers;
+
+QMacPlatformPixmap::QMacPlatformPixmap(PixelType type)
+ : QPlatformPixmap(type, MacClass), has_alpha(0), has_mask(0),
+ uninit(true), pixels(0), pixelsSize(0), pixelsToFree(0),
+ bytesPerRow(0), cg_data(0), cg_dataBeingReleased(0), cg_mask(0),
+ pengine(0)
+{
+}
+
+QPlatformPixmap *QMacPlatformPixmap::createCompatiblePlatformPixmap() const
+{
+ return new QMacPlatformPixmap(pixelType());
+}
+
+#define BEST_BYTE_ALIGNMENT 16
+#define COMPTUE_BEST_BYTES_PER_ROW(bpr) \
+ (((bpr) + (BEST_BYTE_ALIGNMENT - 1)) & ~(BEST_BYTE_ALIGNMENT - 1))
+
+void QMacPlatformPixmap::resize(int width, int height)
+{
+ setSerialNumber(++qt_pixmap_serial);
+
+ w = width;
+ h = height;
+ is_null = (w <= 0 || h <= 0);
+ d = (pixelType() == BitmapType ? 1 : 32);
+ bool make_null = w <= 0 || h <= 0; // create null pixmap
+ if (make_null || d == 0) {
+ w = 0;
+ h = 0;
+ is_null = true;
+ d = 0;
+ if (!make_null)
+ qWarning("Qt: QPixmap: Invalid pixmap parameters");
+ return;
+ }
+
+ if (w < 1 || h < 1)
+ return;
+
+ //create the pixels
+ bytesPerRow = w * sizeof(quint32); // Minimum bytes per row.
+
+ // Quartz2D likes things as a multple of 16 (for now).
+ bytesPerRow = COMPTUE_BEST_BYTES_PER_ROW(bytesPerRow);
+ macCreatePixels();
+}
+
+#undef COMPUTE_BEST_BYTES_PER_ROW
+
+void QMacPlatformPixmap::fromImage(const QImage &img,
+ Qt::ImageConversionFlags flags)
+{
+ setSerialNumber(++qt_pixmap_serial);
+
+ // the conversion code only handles format >=
+ // Format_ARGB32_Premultiplied at the moment..
+ if (img.format() > QImage::Format_ARGB32_Premultiplied) {
+ QImage image;
+ if (img.hasAlphaChannel())
+ image = img.convertToFormat(QImage::Format_ARGB32_Premultiplied);
+ else
+ image = img.convertToFormat(QImage::Format_RGB32);
+ fromImage(image, flags);
+ return;
+ }
+
+ w = img.width();
+ h = img.height();
+ is_null = (w <= 0 || h <= 0);
+ d = (pixelType() == BitmapType ? 1 : img.depth());
+
+ QImage image = img;
+ int dd = QPixmap::defaultDepth();
+ bool force_mono = (dd == 1 ||
+ (flags & Qt::ColorMode_Mask)==Qt::MonoOnly);
+ if (force_mono) { // must be monochrome
+ if (d != 1) {
+ image = image.convertToFormat(QImage::Format_MonoLSB, flags); // dither
+ d = 1;
+ }
+ } else { // can be both
+ bool conv8 = false;
+ if(d > 8 && dd <= 8) { // convert to 8 bit
+ if ((flags & Qt::DitherMode_Mask) == Qt::AutoDither)
+ flags = (flags & ~Qt::DitherMode_Mask)
+ | Qt::PreferDither;
+ conv8 = true;
+ } else if ((flags & Qt::ColorMode_Mask) == Qt::ColorOnly) {
+ conv8 = d == 1; // native depth wanted
+ } else if (d == 1) {
+ if (image.colorCount() == 2) {
+ QRgb c0 = image.color(0); // Auto: convert to best
+ QRgb c1 = image.color(1);
+ conv8 = qMin(c0,c1) != qRgb(0,0,0) || qMax(c0,c1) != qRgb(255,255,255);
+ } else {
+ // eg. 1-color monochrome images (they do exist).
+ conv8 = true;
+ }
+ }
+ if (conv8) {
+ image = image.convertToFormat(QImage::Format_Indexed8, flags);
+ d = 8;
+ }
+ }
+
+ if (image.depth()==1) {
+ image.setColor(0, QColor(Qt::color0).rgba());
+ image.setColor(1, QColor(Qt::color1).rgba());
+ }
+
+ if (d == 16 || d == 24) {
+ image = image.convertToFormat(QImage::Format_RGB32, flags);
+ fromImage(image, flags);
+ return;
+ }
+
+ // different size or depth, make a new pixmap
+ resize(w, h);
+
+ quint32 *dptr = pixels, *drow;
+ const uint dbpr = bytesPerRow;
+
+ const QImage::Format sfmt = image.format();
+ const unsigned short sbpr = image.bytesPerLine();
+
+ // use const_cast to prevent a detach
+ const uchar *sptr = const_cast<const QImage &>(image).bits(), *srow;
+
+ for (int y = 0; y < h; ++y) {
+ drow = dptr + (y * (dbpr / 4));
+ srow = sptr + (y * sbpr);
+ switch(sfmt) {
+ case QImage::Format_MonoLSB:
+ case QImage::Format_Mono:{
+ for (int x = 0; x < w; ++x) {
+ char one_bit = *(srow + (x / 8));
+ if (sfmt == QImage::Format_Mono)
+ one_bit = one_bit >> (7 - (x % 8));
+ else
+ one_bit = one_bit >> (x % 8);
+ if ((one_bit & 0x01))
+ *(drow+x) = 0xFF000000;
+ else
+ *(drow+x) = 0xFFFFFFFF;
+ }
+ break;
+ }
+ case QImage::Format_Indexed8: {
+ int numColors = image.numColors();
+ if (numColors > 0) {
+ for (int x = 0; x < w; ++x) {
+ int index = *(srow + x);
+ *(drow+x) = PREMUL(image.color(qMin(index, numColors)));
+ }
+ }
+ } break;
+ case QImage::Format_RGB32:
+ for (int x = 0; x < w; ++x)
+ *(drow+x) = *(((quint32*)srow) + x) | 0xFF000000;
+ break;
+ case QImage::Format_ARGB32:
+ case QImage::Format_ARGB32_Premultiplied:
+ for (int x = 0; x < w; ++x) {
+ if(sfmt == QImage::Format_RGB32)
+ *(drow+x) = 0xFF000000 | (*(((quint32*)srow) + x) & 0x00FFFFFF);
+ else if(sfmt == QImage::Format_ARGB32_Premultiplied)
+ *(drow+x) = *(((quint32*)srow) + x);
+ else
+ *(drow+x) = PREMUL(*(((quint32*)srow) + x));
+ }
+ break;
+ default:
+ qWarning("Qt: internal: Oops: Forgot a format [%d] %s:%d", sfmt,
+ __FILE__, __LINE__);
+ break;
+ }
+ }
+ if (sfmt != QImage::Format_RGB32) { //setup the alpha
+ bool alphamap = image.depth() == 32;
+ if (sfmt == QImage::Format_Indexed8) {
+ const QVector<QRgb> rgb = image.colorTable();
+ for (int i = 0, count = image.colorCount(); i < count; ++i) {
+ const int alpha = qAlpha(rgb[i]);
+ if (alpha != 0xff) {
+ alphamap = true;
+ break;
+ }
+ }
+ }
+ macSetHasAlpha(alphamap);
+ }
+ uninit = false;
+}
+
+int get_index(QImage * qi,QRgb mycol)
+{
+ int loopc;
+ for(loopc=0;loopc<qi->colorCount();loopc++) {
+ if(qi->color(loopc)==mycol)
+ return loopc;
+ }
+ qi->setColorCount(qi->colorCount()+1);
+ qi->setColor(qi->colorCount(),mycol);
+ return qi->colorCount();
+}
+
+QImage QMacPlatformPixmap::toImage() const
+{
+ QImage::Format format = QImage::Format_MonoLSB;
+ if (d != 1) //Doesn't support index color modes
+ format = (has_alpha ? QImage::Format_ARGB32_Premultiplied :
+ QImage::Format_RGB32);
+
+ QImage image(w, h, format);
+ quint32 *sptr = pixels, *srow;
+ const uint sbpr = bytesPerRow;
+ if (format == QImage::Format_MonoLSB) {
+ image.fill(0);
+ image.setColorCount(2);
+ image.setColor(0, QColor(Qt::color0).rgba());
+ image.setColor(1, QColor(Qt::color1).rgba());
+ for (int y = 0; y < h; ++y) {
+ uchar *scanLine = image.scanLine(y);
+ srow = sptr + (y * (sbpr/4));
+ for (int x = 0; x < w; ++x) {
+ if (!(*(srow + x) & RGB_MASK))
+ scanLine[x >> 3] |= (1 << (x & 7));
+ }
+ }
+ } else {
+ for (int y = 0; y < h; ++y) {
+ srow = sptr + (y * (sbpr / 4));
+ memcpy(image.scanLine(y), srow, w * 4);
+ }
+
+ }
+
+ return image;
+}
+
+void QMacPlatformPixmap::fill(const QColor &fillColor)
+
+{
+ { //we don't know what backend to use so we cannot paint here
+ quint32 *dptr = pixels;
+ Q_ASSERT_X(dptr, "QPixmap::fill", "No dptr");
+ const quint32 colr = PREMUL(fillColor.rgba());
+ const int nbytes = bytesPerRow * h;
+ if (!colr) {
+ memset(dptr, 0, nbytes);
+ } else {
+ for (uint i = 0; i < nbytes / sizeof(quint32); ++i)
+ *(dptr + i) = colr;
+ }
+ }
+
+ // If we had an alpha channel from before, don't
+ // switch it off. Only go from no alpha to alpha:
+ if (fillColor.alpha() != 255)
+ macSetHasAlpha(true);
+}
+
+QPixmap QMacPlatformPixmap::alphaChannel() const
+{
+ if (!has_alpha)
+ return QPixmap();
+
+ QMacPlatformPixmap *alpha = new QMacPlatformPixmap(PixmapType);
+ alpha->resize(w, h);
+ macGetAlphaChannel(alpha, false);
+ return QPixmap(alpha);
+}
+
+void QMacPlatformPixmap::setAlphaChannel(const QPixmap &alpha)
+{
+ has_mask = true;
+ QMacPlatformPixmap *alphaData = static_cast<QMacPlatformPixmap*>(alpha.data.data());
+ macSetAlphaChannel(alphaData, false);
+}
+
+QBitmap QMacPlatformPixmap::mask() const
+{
+ if (!has_mask && !has_alpha)
+ return QBitmap();
+
+ QMacPlatformPixmap *mask = new QMacPlatformPixmap(BitmapType);
+ mask->resize(w, h);
+ macGetAlphaChannel(mask, true);
+ return QPixmap(mask);
+}
+
+void QMacPlatformPixmap::setMask(const QBitmap &mask)
+{
+ if (mask.isNull()) {
+ QMacPlatformPixmap opaque(PixmapType);
+ opaque.resize(w, h);
+ opaque.fill(QColor(255, 255, 255, 255));
+ macSetAlphaChannel(&opaque, true);
+ has_alpha = has_mask = false;
+ return;
+ }
+
+ has_alpha = false;
+ has_mask = true;
+ QMacPlatformPixmap *maskData = static_cast<QMacPlatformPixmap*>(mask.data.data());
+ macSetAlphaChannel(maskData, true);
+}
+
+int QMacPlatformPixmap::metric(QPaintDevice::PaintDeviceMetric theMetric) const
+{
+ switch (theMetric) {
+ case QPaintDevice::PdmWidth:
+ return w;
+ case QPaintDevice::PdmHeight:
+ return h;
+ case QPaintDevice::PdmWidthMM:
+ return qRound(metric(QPaintDevice::PdmWidth) * 25.4 / qreal(metric(QPaintDevice::PdmDpiX)));
+ case QPaintDevice::PdmHeightMM:
+ return qRound(metric(QPaintDevice::PdmHeight) * 25.4 / qreal(metric(QPaintDevice::PdmDpiY)));
+ case QPaintDevice::PdmNumColors:
+ return 1 << d;
+ case QPaintDevice::PdmDpiX:
+ case QPaintDevice::PdmPhysicalDpiX: {
+ extern float qt_mac_defaultDpi_x(); //qpaintdevice_mac.cpp
+ return int(qt_mac_defaultDpi_x());
+ }
+ case QPaintDevice::PdmDpiY:
+ case QPaintDevice::PdmPhysicalDpiY: {
+ extern float qt_mac_defaultDpi_y(); //qpaintdevice_mac.cpp
+ return int(qt_mac_defaultDpi_y());
+ }
+ case QPaintDevice::PdmDepth:
+ return d;
+ default:
+ qWarning("QPixmap::metric: Invalid metric command");
+ }
+ return 0;
+}
+
+QMacPlatformPixmap::~QMacPlatformPixmap()
+{
+ validDataPointers.remove(this);
+ if (cg_mask) {
+ CGImageRelease(cg_mask);
+ cg_mask = 0;
+ }
+
+ delete pengine; // Make sure we aren't drawing on the context anymore.
+ if (cg_data) {
+ CGImageRelease(cg_data);
+ } else if (!cg_dataBeingReleased && pixels != pixelsToFree) {
+ free(pixels);
+ }
+ free(pixelsToFree);
+}
+
+void QMacPlatformPixmap::macSetAlphaChannel(const QMacPlatformPixmap *pix, bool asMask)
+{
+ if (!pixels || !h || !w || pix->w != w || pix->h != h)
+ return;
+
+ quint32 *dptr = pixels, *drow;
+ const uint dbpr = bytesPerRow;
+ const unsigned short sbpr = pix->bytesPerRow;
+ quint32 *sptr = pix->pixels, *srow;
+ for (int y=0; y < h; ++y) {
+ drow = dptr + (y * (dbpr/4));
+ srow = sptr + (y * (sbpr/4));
+ if(d == 1) {
+ for (int x=0; x < w; ++x) {
+ if((*(srow+x) & RGB_MASK))
+ *(drow+x) = 0xFFFFFFFF;
+ }
+ } else if(d == 8) {
+ for (int x=0; x < w; ++x)
+ *(drow+x) = (*(drow+x) & RGB_MASK) | (*(srow+x) << 24);
+ } else if(asMask) {
+ for (int x=0; x < w; ++x) {
+ if(*(srow+x) & RGB_MASK)
+ *(drow+x) = (*(drow+x) & RGB_MASK);
+ else
+ *(drow+x) = (*(drow+x) & RGB_MASK) | 0xFF000000;
+ *(drow+x) = PREMUL(*(drow+x));
+ }
+ } else {
+ for (int x=0; x < w; ++x) {
+ const uchar alpha = qGray(qRed(*(srow+x)), qGreen(*(srow+x)), qBlue(*(srow+x)));
+ const uchar destAlpha = qt_div_255(alpha * qAlpha(*(drow+x)));
+#if 1
+ *(drow+x) = (*(drow+x) & RGB_MASK) | (destAlpha << 24);
+#else
+ *(drow+x) = qRgba(qt_div_255(qRed(*(drow+x) * alpha)),
+ qt_div_255(qGreen(*(drow+x) * alpha)),
+ qt_div_255(qBlue(*(drow+x) * alpha)), destAlpha);
+#endif
+ *(drow+x) = PREMUL(*(drow+x));
+ }
+ }
+ }
+ macSetHasAlpha(true);
+}
+
+void QMacPlatformPixmap::macGetAlphaChannel(QMacPlatformPixmap *pix, bool asMask) const
+{
+ quint32 *dptr = pix->pixels, *drow;
+ const uint dbpr = pix->bytesPerRow;
+ const unsigned short sbpr = bytesPerRow;
+ quint32 *sptr = pixels, *srow;
+ for(int y=0; y < h; ++y) {
+ drow = dptr + (y * (dbpr/4));
+ srow = sptr + (y * (sbpr/4));
+ if(asMask) {
+ for (int x = 0; x < w; ++x) {
+ if (*(srow + x) & qRgba(0, 0, 0, 255))
+ *(drow + x) = 0x00000000;
+ else
+ *(drow + x) = 0xFFFFFFFF;
+ }
+ } else {
+ for (int x = 0; x < w; ++x) {
+ const int alpha = qAlpha(*(srow + x));
+ *(drow + x) = qRgb(alpha, alpha, alpha);
+ }
+ }
+ }
+}
+
+void QMacPlatformPixmap::macSetHasAlpha(bool b)
+{
+ has_alpha = b;
+ macReleaseCGImageRef();
+}
+
+void QMacPlatformPixmap::macCreateCGImageRef()
+{
+ Q_ASSERT(cg_data == 0);
+ //create the cg data
+ CGColorSpaceRef colorspace = QCoreGraphicsPaintEngine::macDisplayColorSpace();
+ QCFType<CGDataProviderRef> provider = CGDataProviderCreateWithData(this,
+ pixels, bytesPerRow * h,
+ qt_mac_cgimage_data_free);
+ validDataPointers.insert(this);
+ uint cgflags = kCGImageAlphaPremultipliedFirst;
+#ifdef kCGBitmapByteOrder32Host //only needed because CGImage.h added symbols in the minor version
+ cgflags |= kCGBitmapByteOrder32Host;
+#endif
+ cg_data = CGImageCreate(w, h, 8, 32, bytesPerRow, colorspace,
+ cgflags, provider, 0, 0, kCGRenderingIntentDefault);
+}
+
+void QMacPlatformPixmap::macReleaseCGImageRef()
+{
+ if (!cg_data)
+ return; // There's nothing we need to do
+
+ cg_dataBeingReleased = cg_data;
+ CGImageRelease(cg_data);
+ cg_data = 0;
+
+ if (pixels != pixelsToFree) {
+ macCreatePixels();
+ } else {
+ pixelsToFree = 0;
+ }
+}
+
+
+// We create our space in memory to paint on here. If we already have existing pixels
+// copy them over. This is to preserve the fact that CGImageRef's are immutable.
+void QMacPlatformPixmap::macCreatePixels()
+{
+ const int numBytes = bytesPerRow * h;
+ quint32 *base_pixels;
+ if (pixelsToFree && pixelsToFree != pixels) {
+ // Reuse unused block of memory lying around from a previous callback.
+ base_pixels = pixelsToFree;
+ pixelsToFree = 0;
+ } else {
+ // We need a block of memory to do stuff with.
+ base_pixels = static_cast<quint32 *>(malloc(numBytes));
+ }
+
+ if (pixels)
+ memcpy(base_pixels, pixels, pixelsSize);
+ pixels = base_pixels;
+ pixelsSize = numBytes;
+}
+
+#if 0
+QPixmap QMacPlatformPixmap::transformed(const QTransform &transform,
+ Qt::TransformationMode mode) const
+{
+ int w, h; // size of target pixmap
+ const int ws = width();
+ const int hs = height();
+
+ QTransform mat(transform.m11(), transform.m12(),
+ transform.m21(), transform.m22(), 0., 0.);
+ if (transform.m12() == 0.0F && transform.m21() == 0.0F &&
+ transform.m11() >= 0.0F && transform.m22() >= 0.0F)
+ {
+ h = int(qAbs(mat.m22()) * hs + 0.9999);
+ w = int(qAbs(mat.m11()) * ws + 0.9999);
+ h = qAbs(h);
+ w = qAbs(w);
+ } else { // rotation or shearing
+ QPolygonF a(QRectF(0,0,ws+1,hs+1));
+ a = mat.map(a);
+ QRectF r = a.boundingRect().normalized();
+ w = int(r.width() + 0.9999);
+ h = int(r.height() + 0.9999);
+ }
+ mat = QPixmap::trueMatrix(mat, ws, hs);
+ if (!h || !w)
+ return QPixmap();
+
+ // create destination
+ QMacPlatformPixmap *pm = new QMacPlatformPixmap(pixelType(), w, h);
+ const quint32 *sptr = pixels;
+ quint32 *dptr = pm->pixels;
+ memset(dptr, 0, (pm->bytesPerRow * pm->h));
+
+ // do the transform
+ if (mode == Qt::SmoothTransformation) {
+#warning QMacPlatformPixmap::transformed not properly implemented
+ qWarning("QMacPlatformPixmap::transformed not properly implemented");
+#if 0
+ QPainter p(&pm);
+ p.setRenderHint(QPainter::Antialiasing);
+ p.setRenderHint(QPainter::SmoothPixmapTransform);
+ p.setTransform(mat);
+ p.drawPixmap(0, 0, *this);
+#endif
+ } else {
+ bool invertible;
+ mat = mat.inverted(&invertible);
+ if (!invertible)
+ return QPixmap();
+
+ const int bpp = 32;
+ const int xbpl = (w * bpp) / 8;
+ if (!qt_xForm_helper(mat, 0, QT_XFORM_TYPE_MSBFIRST, bpp,
+ (uchar*)dptr, xbpl, (pm->bytesPerRow) - xbpl,
+ h, (uchar*)sptr, (bytesPerRow), ws, hs)) {
+ qWarning("QMacPlatformPixmap::transform(): failure");
+ return QPixmap();
+ }
+ }
+
+ // update the alpha
+ pm->macSetHasAlpha(true);
+ return QPixmap(pm);
+}
+#endif
+
+QT_BEGIN_INCLUDE_NAMESPACE
+#include <OpenGL/OpenGL.h>
+#include <OpenGL/gl.h>
+QT_END_INCLUDE_NAMESPACE
+
+// Load and resolve the symbols we need from OpenGL manually so QtGui doesn't have to link against the OpenGL framework.
+typedef CGLError (*PtrCGLChoosePixelFormat)(const CGLPixelFormatAttribute *, CGLPixelFormatObj *, long *);
+typedef CGLError (*PtrCGLClearDrawable)(CGLContextObj);
+typedef CGLError (*PtrCGLCreateContext)(CGLPixelFormatObj, CGLContextObj, CGLContextObj *);
+typedef CGLError (*PtrCGLDestroyContext)(CGLContextObj);
+typedef CGLError (*PtrCGLDestroyPixelFormat)(CGLPixelFormatObj);
+typedef CGLError (*PtrCGLSetCurrentContext)(CGLContextObj);
+typedef CGLError (*PtrCGLSetFullScreen)(CGLContextObj);
+typedef void (*PtrglFinish)();
+typedef void (*PtrglPixelStorei)(GLenum, GLint);
+typedef void (*PtrglReadBuffer)(GLenum);
+typedef void (*PtrglReadPixels)(GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, GLvoid *);
+
+static PtrCGLChoosePixelFormat ptrCGLChoosePixelFormat = 0;
+static PtrCGLClearDrawable ptrCGLClearDrawable = 0;
+static PtrCGLCreateContext ptrCGLCreateContext = 0;
+static PtrCGLDestroyContext ptrCGLDestroyContext = 0;
+static PtrCGLDestroyPixelFormat ptrCGLDestroyPixelFormat = 0;
+static PtrCGLSetCurrentContext ptrCGLSetCurrentContext = 0;
+static PtrCGLSetFullScreen ptrCGLSetFullScreen = 0;
+static PtrglFinish ptrglFinish = 0;
+static PtrglPixelStorei ptrglPixelStorei = 0;
+static PtrglReadBuffer ptrglReadBuffer = 0;
+static PtrglReadPixels ptrglReadPixels = 0;
+
+static bool resolveOpenGLSymbols()
+{
+ if (ptrCGLChoosePixelFormat == 0) {
+ QLibrary library(QLatin1String("/System/Library/Frameworks/OpenGL.framework/OpenGL"));
+ ptrCGLChoosePixelFormat = (PtrCGLChoosePixelFormat)(library.resolve("CGLChoosePixelFormat"));
+ ptrCGLClearDrawable = (PtrCGLClearDrawable)(library.resolve("CGLClearDrawable"));
+ ptrCGLCreateContext = (PtrCGLCreateContext)(library.resolve("CGLCreateContext"));
+ ptrCGLDestroyContext = (PtrCGLDestroyContext)(library.resolve("CGLDestroyContext"));
+ ptrCGLDestroyPixelFormat = (PtrCGLDestroyPixelFormat)(library.resolve("CGLDestroyPixelFormat"));
+ ptrCGLSetCurrentContext = (PtrCGLSetCurrentContext)(library.resolve("CGLSetCurrentContext"));
+ ptrCGLSetFullScreen = (PtrCGLSetFullScreen)(library.resolve("CGLSetFullScreen"));
+ ptrglFinish = (PtrglFinish)(library.resolve("glFinish"));
+ ptrglPixelStorei = (PtrglPixelStorei)(library.resolve("glPixelStorei"));
+ ptrglReadBuffer = (PtrglReadBuffer)(library.resolve("glReadBuffer"));
+ ptrglReadPixels = (PtrglReadPixels)(library.resolve("glReadPixels"));
+ }
+ return ptrCGLChoosePixelFormat && ptrCGLClearDrawable && ptrCGLCreateContext
+ && ptrCGLDestroyContext && ptrCGLDestroyPixelFormat && ptrCGLSetCurrentContext
+ && ptrCGLSetFullScreen && ptrglFinish && ptrglPixelStorei
+ && ptrglReadBuffer && ptrglReadPixels;
+}
+
+// Inverts the given pixmap in the y direction.
+static void qt_mac_flipPixmap(void *data, int rowBytes, int height)
+{
+ int bottom = height - 1;
+ void *base = data;
+ void *buffer = malloc(rowBytes);
+
+ int top = 0;
+ while ( top < bottom )
+ {
+ void *topP = (void *)((top * rowBytes) + (intptr_t)base);
+ void *bottomP = (void *)((bottom * rowBytes) + (intptr_t)base);
+
+ bcopy( topP, buffer, rowBytes );
+ bcopy( bottomP, topP, rowBytes );
+ bcopy( buffer, bottomP, rowBytes );
+
+ ++top;
+ --bottom;
+ }
+ free(buffer);
+}
+
+// Grabs displayRect from display and places it into buffer.
+static void qt_mac_grabDisplayRect(CGDirectDisplayID display, const QRect &displayRect, void *buffer)
+{
+ if (display == kCGNullDirectDisplay)
+ return;
+
+ CGLPixelFormatAttribute attribs[] = {
+ kCGLPFAFullScreen,
+ kCGLPFADisplayMask,
+ (CGLPixelFormatAttribute)0, /* Display mask bit goes here */
+ (CGLPixelFormatAttribute)0
+ };
+
+ attribs[2] = (CGLPixelFormatAttribute)CGDisplayIDToOpenGLDisplayMask(display);
+
+ // Build a full-screen GL context
+ CGLPixelFormatObj pixelFormatObj;
+ long numPixelFormats;
+
+ ptrCGLChoosePixelFormat( attribs, &pixelFormatObj, &numPixelFormats );
+
+ if (!pixelFormatObj) // No full screen context support
+ return;
+
+ CGLContextObj glContextObj;
+ ptrCGLCreateContext(pixelFormatObj, 0, &glContextObj);
+ ptrCGLDestroyPixelFormat(pixelFormatObj) ;
+ if (!glContextObj)
+ return;
+
+ ptrCGLSetCurrentContext(glContextObj);
+ ptrCGLSetFullScreen(glContextObj) ;
+
+ ptrglReadBuffer(GL_FRONT);
+
+ ptrglFinish(); // Finish all OpenGL commands
+ ptrglPixelStorei(GL_PACK_ALIGNMENT, 4); // Force 4-byte alignment
+ ptrglPixelStorei(GL_PACK_ROW_LENGTH, 0);
+ ptrglPixelStorei(GL_PACK_SKIP_ROWS, 0);
+ ptrglPixelStorei(GL_PACK_SKIP_PIXELS, 0);
+
+ // Fetch the data in XRGB format, matching the bitmap context.
+ ptrglReadPixels(GLint(displayRect.x()), GLint(displayRect.y()),
+ GLint(displayRect.width()), GLint(displayRect.height()),
+#ifdef __BIG_ENDIAN__
+ GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, buffer
+#else
+ GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, buffer
+#endif
+ );
+
+ ptrCGLSetCurrentContext(0);
+ ptrCGLClearDrawable(glContextObj); // disassociate from full screen
+ ptrCGLDestroyContext(glContextObj); // and destroy the context
+}
+
+// Returns a pixmap containing the screen contents at rect.
+static QPixmap qt_mac_grabScreenRect(const QRect &rect)
+{
+ if (!resolveOpenGLSymbols())
+ return QPixmap();
+
+ const int maxDisplays = 128; // 128 displays should be enough for everyone.
+ CGDirectDisplayID displays[maxDisplays];
+ CGDisplayCount displayCount;
+ const CGRect cgRect = CGRectMake(rect.x(), rect.y(), rect.width(), rect.height());
+ const CGDisplayErr err = CGGetDisplaysWithRect(cgRect, maxDisplays, displays, &displayCount);
+
+ if (err && displayCount == 0)
+ return QPixmap();
+
+ long bytewidth = rect.width() * 4; // Assume 4 bytes/pixel for now
+ bytewidth = (bytewidth + 3) & ~3; // Align to 4 bytes
+ QVarLengthArray<char> buffer(rect.height() * bytewidth);
+
+ for (uint i = 0; i < displayCount; ++i) {
+ const CGRect bounds = CGDisplayBounds(displays[i]);
+ // Translate to display-local coordinates
+ QRect displayRect = rect.translated(qRound(-bounds.origin.x), qRound(-bounds.origin.y));
+ // Adjust for inverted y axis.
+ displayRect.moveTop(qRound(bounds.size.height) - displayRect.y() - rect.height());
+ qt_mac_grabDisplayRect(displays[i], displayRect, buffer.data());
+ }
+
+ qt_mac_flipPixmap(buffer.data(), bytewidth, rect.height());
+ QCFType<CGContextRef> bitmap = CGBitmapContextCreate(buffer.data(), rect.width(),
+ rect.height(), 8, bytewidth,
+ QCoreGraphicsPaintEngine::macGenericColorSpace(),
+ kCGImageAlphaNoneSkipFirst);
+ QCFType<CGImageRef> image = CGBitmapContextCreateImage(bitmap);
+ return QPixmap::fromMacCGImageRef(image);
+}
+
+#ifndef QT_MAC_USE_COCOA // no QuickDraw in 64-bit mode
+static QPixmap qt_mac_grabScreenRect_10_3(int x, int y, int w, int h, QWidget *widget)
+{
+ QPixmap pm = QPixmap(w, h);
+ extern WindowPtr qt_mac_window_for(const QWidget *); // qwidget_mac.cpp
+ const BitMap *windowPort = 0;
+ if((widget->windowType() == Qt::Desktop)) {
+ GDHandle gdh;
+ if(!(gdh=GetMainDevice()))
+ qDebug("Qt: internal: Unexpected condition reached: %s:%d", __FILE__, __LINE__);
+ windowPort = (BitMap*)(*(*gdh)->gdPMap);
+ } else {
+ windowPort = GetPortBitMapForCopyBits(GetWindowPort(qt_mac_window_for(widget)));
+ }
+ const BitMap *pixmapPort = GetPortBitMapForCopyBits(static_cast<GWorldPtr>(pm.macQDHandle()));
+ Rect macSrcRect, macDstRect;
+ SetRect(&macSrcRect, x, y, x + w, y + h);
+ SetRect(&macDstRect, 0, 0, w, h);
+ CopyBits(windowPort, pixmapPort, &macSrcRect, &macDstRect, srcCopy, 0);
+ return pm;
+}
+#endif
+
+QPixmap QPixmap::grabWindow(WId window, int x, int y, int w, int h)
+{
+ QWidget *widget = QWidget::find(window);
+ if (widget == 0)
+ return QPixmap();
+
+ if(w == -1)
+ w = widget->width() - x;
+ if(h == -1)
+ h = widget->height() - y;
+
+ QPoint globalCoord(0, 0);
+ globalCoord = widget->mapToGlobal(globalCoord);
+ QRect rect(globalCoord.x() + x, globalCoord.y() + y, w, h);
+
+#ifdef QT_MAC_USE_COCOA
+ return qt_mac_grabScreenRect(rect);
+#else
+#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4)
+ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4) {
+ return qt_mac_grabScreenRect(rect);
+ } else
+#endif
+ {
+ return qt_mac_grabScreenRect_10_3(x, y, w, h, widget);
+ }
+#endif // ifdef Q_WS_MAC64
+}
+
+/*! \internal
+
+ Returns the QuickDraw CGrafPtr of the pixmap. 0 is returned if it can't
+ be obtained. Do not hold the pointer around for long as it can be
+ relocated.
+
+ \warning This function is only available on Mac OS X.
+ \warning As of Qt 4.6, this function \e{always} returns zero.
+*/
+
+Qt::HANDLE QPixmap::macQDHandle() const
+{
+ return 0;
+}
+
+/*! \internal
+
+ Returns the QuickDraw CGrafPtr of the pixmap's alpha channel. 0 is
+ returned if it can't be obtained. Do not hold the pointer around for
+ long as it can be relocated.
+
+ \warning This function is only available on Mac OS X.
+ \warning As of Qt 4.6, this function \e{always} returns zero.
+*/
+
+Qt::HANDLE QPixmap::macQDAlphaHandle() const
+{
+ return 0;
+}
+
+/*! \internal
+
+ Returns the CoreGraphics CGContextRef of the pixmap. 0 is returned if
+ it can't be obtained. It is the caller's responsiblity to
+ CGContextRelease the context when finished using it.
+
+ \warning This function is only available on Mac OS X.
+*/
+
+Qt::HANDLE QPixmap::macCGHandle() const
+{
+ if (isNull())
+ return 0;
+
+ if (data->classId() == QPlatformPixmap::MacClass) {
+ QMacPlatformPixmap *d = static_cast<QMacPlatformPixmap *>(data.data());
+ if (!d->cg_data)
+ d->macCreateCGImageRef();
+ CGImageRef ret = d->cg_data;
+ CGImageRetain(ret);
+ return ret;
+ } else if (data->classId() == QPlatformPixmap::RasterClass) {
+ return qt_mac_image_to_cgimage(static_cast<QRasterPlatformPixmap *>(data.data())->image);
+ }
+ return 0;
+}
+
+bool QMacPlatformPixmap::hasAlphaChannel() const
+{
+ return has_alpha;
+}
+
+CGImageRef qt_mac_create_imagemask(const QPixmap &pixmap, const QRectF &sr)
+{
+ QMacPlatformPixmap *px = static_cast<QMacPlatformPixmap*>(pixmap.data.data());
+ if (px->cg_mask) {
+ if (px->cg_mask_rect == sr) {
+ CGImageRetain(px->cg_mask); //reference for the caller
+ return px->cg_mask;
+ }
+ CGImageRelease(px->cg_mask);
+ px->cg_mask = 0;
+ }
+
+ const int sx = qRound(sr.x()), sy = qRound(sr.y()), sw = qRound(sr.width()), sh = qRound(sr.height());
+ const int sbpr = px->bytesPerRow;
+ const uint nbytes = sw * sh;
+ // alpha is always 255 for bitmaps, ignore it in this case.
+ const quint32 mask = px->depth() == 1 ? 0x00ffffff : 0xffffffff;
+ quint8 *dptr = static_cast<quint8 *>(malloc(nbytes));
+ quint32 *sptr = px->pixels, *srow;
+ for(int y = sy, offset=0; y < sh; ++y) {
+ srow = sptr + (y * (sbpr / 4));
+ for(int x = sx; x < sw; ++x)
+ *(dptr+(offset++)) = (*(srow+x) & mask) ? 255 : 0;
+ }
+ QCFType<CGDataProviderRef> provider = CGDataProviderCreateWithData(0, dptr, nbytes, qt_mac_cgimage_data_free);
+ px->cg_mask = CGImageMaskCreate(sw, sh, 8, 8, nbytes / sh, provider, 0, 0);
+ px->cg_mask_rect = sr;
+ CGImageRetain(px->cg_mask); //reference for the caller
+ return px->cg_mask;
+}
+
+#ifndef QT_MAC_USE_COCOA
+IconRef qt_mac_create_iconref(const QPixmap &px)
+{
+ if (px.isNull())
+ return 0;
+
+ //create icon
+ IconFamilyHandle iconFamily = reinterpret_cast<IconFamilyHandle>(NewHandle(0));
+ //create data
+ {
+ struct {
+ OSType mac_type;
+ int width, height, depth;
+ bool mask;
+ } images[] = {
+ { kThumbnail32BitData, 128, 128, 32, false },
+ { kThumbnail8BitMask, 128, 128, 8, true },
+ { 0, 0, 0, 0, false } //end marker
+ };
+ for(int i = 0; images[i].mac_type; i++) {
+ //get QPixmap data
+ QImage scaled_px = px.toImage().scaled(images[i].width, images[i].height);
+
+ quint32 *sptr = (quint32 *) scaled_px.bits();
+ quint32 *srow;
+ uint sbpr = scaled_px.bytesPerLine();
+
+ //get Handle data
+ const int dbpr = images[i].width * (images[i].depth/8);
+ Handle hdl = NewHandle(dbpr*images[i].height);
+ if(!sptr) { //handle null pixmap
+ memset((*hdl), '\0', dbpr*images[i].height);
+ } else if(images[i].mask) {
+ if(images[i].mac_type == kThumbnail8BitMask) {
+ for(int y = 0, hindex = 0; y < images[i].height; ++y) {
+ srow = sptr + (y * (sbpr/4));
+ for(int x = 0; x < images[i].width; ++x)
+ *((*hdl)+(hindex++)) = qAlpha(*(srow+x));
+ }
+ }
+ } else {
+ char *dest = (*hdl);
+#if defined(__i386__)
+ if(images[i].depth == 32) {
+ for(int y = 0; y < images[i].height; ++y) {
+ uint *source = (uint*)((const uchar*)sptr+(sbpr*y));
+ for(int x = 0; x < images[i].width; ++x, dest += 4)
+ *((uint*)dest) = CFSwapInt32(*(source + x));
+ }
+ } else
+#endif
+ {
+ for(int y = 0; y < images[i].height; ++y)
+ memcpy(dest+(y*dbpr), ((const uchar*)sptr+(sbpr*y)), dbpr);
+ }
+ }
+
+ //set the family data to the Handle
+ OSStatus set = SetIconFamilyData(iconFamily, images[i].mac_type, hdl);
+ if(set != noErr)
+ qWarning("%s: %d -- Unable to create icon data[%d]!! %ld",
+ __FILE__, __LINE__, i, long(set));
+ DisposeHandle(hdl);
+ }
+ }
+
+ //acquire and cleanup
+ IconRef ret;
+ static int counter = 0;
+ const OSType kQtCreator = 'CUTE';
+ RegisterIconRefFromIconFamily(kQtCreator, (OSType)counter, iconFamily, &ret);
+ AcquireIconRef(ret);
+ UnregisterIconRef(kQtCreator, (OSType)counter);
+ DisposeHandle(reinterpret_cast<Handle>(iconFamily));
+ counter++;
+ return ret;
+
+}
+#endif
+
+/*! \internal */
+QPaintEngine* QMacPlatformPixmap::paintEngine() const
+{
+ if (!pengine) {
+ QMacPlatformPixmap *that = const_cast<QMacPlatformPixmap*>(this);
+ that->pengine = new QCoreGraphicsPaintEngine();
+ }
+ return pengine;
+}
+
+void QMacPlatformPixmap::copy(const QPlatformPixmap *data, const QRect &rect)
+{
+ if (data->pixelType() == BitmapType) {
+ QBitmap::fromImage(toImage().copy(rect));
+ return;
+ }
+
+ const QMacPlatformPixmap *macData = static_cast<const QMacPlatformPixmap*>(data);
+
+ resize(rect.width(), rect.height());
+
+ has_alpha = macData->has_alpha;
+ has_mask = macData->has_mask;
+ uninit = false;
+
+ const int x = rect.x();
+ const int y = rect.y();
+ char *dest = reinterpret_cast<char*>(pixels);
+ const char *src = reinterpret_cast<const char*>(macData->pixels + x) + y * macData->bytesPerRow;
+ for (int i = 0; i < h; ++i) {
+ memcpy(dest, src, w * 4);
+ dest += bytesPerRow;
+ src += macData->bytesPerRow;
+ }
+
+ has_alpha = macData->has_alpha;
+ has_mask = macData->has_mask;
+}
+
+bool QMacPlatformPixmap::scroll(int dx, int dy, const QRect &rect)
+{
+ Q_UNUSED(dx);
+ Q_UNUSED(dy);
+ Q_UNUSED(rect);
+ return false;
+}
+
+/*!
+ \since 4.2
+
+ Creates a \c CGImageRef equivalent to the QPixmap. Returns the \c CGImageRef handle.
+
+ It is the caller's responsibility to release the \c CGImageRef data
+ after use.
+
+ \warning This function is only available on Mac OS X.
+
+ \sa fromMacCGImageRef()
+*/
+CGImageRef QPixmap::toMacCGImageRef() const
+{
+ return (CGImageRef)macCGHandle();
+}
+
+/*!
+ \since 4.2
+
+ Returns a QPixmap that is equivalent to the given \a image.
+
+ \warning This function is only available on Mac OS X.
+
+ \sa toMacCGImageRef(), {QPixmap#Pixmap Conversion}{Pixmap Conversion}
+*/
+QPixmap QPixmap::fromMacCGImageRef(CGImageRef image)
+{
+ const size_t w = CGImageGetWidth(image),
+ h = CGImageGetHeight(image);
+ QPixmap ret(w, h);
+ ret.fill(Qt::transparent);
+ CGRect rect = CGRectMake(0, 0, w, h);
+ CGContextRef ctx = qt_mac_cg_context(&ret);
+ qt_mac_drawCGImage(ctx, &rect, image);
+ CGContextRelease(ctx);
+ return ret;
+}
+
+QT_END_NAMESPACE
diff --git a/src/widgets/platforms/mac/qpixmap_mac_p.h b/src/widgets/platforms/mac/qpixmap_mac_p.h
new file mode 100644
index 0000000000..4f53160074
--- /dev/null
+++ b/src/widgets/platforms/mac/qpixmap_mac_p.h
@@ -0,0 +1,134 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPIXMAP_MAC_P_H
+#define QPIXMAP_MAC_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtGui/qplatformpixmap_qpa.h>
+#include <QtGui/qplatformpixmapfactory_p.h>
+#include <QtGui/private/qt_mac_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QMacPlatformPixmap : public QPlatformPixmap
+{
+public:
+ QMacPlatformPixmap(PixelType type);
+ ~QMacPlatformPixmap();
+
+ QPlatformPixmap *createCompatiblePlatformPixmap() const;
+
+ void resize(int width, int height);
+ void fromImage(const QImage &image, Qt::ImageConversionFlags flags);
+ void copy(const QPlatformPixmap *data, const QRect &rect);
+ bool scroll(int dx, int dy, const QRect &rect);
+
+ int metric(QPaintDevice::PaintDeviceMetric metric) const;
+ void fill(const QColor &color);
+ QBitmap mask() const;
+ void setMask(const QBitmap &mask);
+ bool hasAlphaChannel() const;
+// QPixmap transformed(const QTransform &matrix,
+// Qt::TransformationMode mode) const;
+ void setAlphaChannel(const QPixmap &alphaChannel);
+ QPixmap alphaChannel() const;
+ QImage toImage() const;
+ QPaintEngine* paintEngine() const;
+
+private:
+
+ uint has_alpha : 1, has_mask : 1, uninit : 1;
+
+ void macSetHasAlpha(bool b);
+ void macGetAlphaChannel(QMacPlatformPixmap *, bool asMask) const;
+ void macSetAlphaChannel(const QMacPlatformPixmap *, bool asMask);
+ void macCreateCGImageRef();
+ void macCreatePixels();
+ void macReleaseCGImageRef();
+ /*
+ pixels stores the pixmap data. pixelsToFree is either 0 or some memory
+ block that was bound to a CGImageRef and released, and for which the
+ release callback has been called. There are two uses to pixelsToFree:
+
+ 1. If pixels == pixelsToFree, then we know that the CGImageRef is done\
+ with the data and we can modify pixels without breaking CGImageRef's
+ mutability invariant.
+
+ 2. If pixels != pixelsToFree and pixelsToFree != 0, then we can reuse
+ pixelsToFree later on instead of malloc'ing memory.
+ */
+ quint32 *pixels;
+ uint pixelsSize;
+ quint32 *pixelsToFree;
+ uint bytesPerRow;
+ QRectF cg_mask_rect;
+ CGImageRef cg_data, cg_dataBeingReleased, cg_mask;
+ static QSet<QMacPlatformPixmap*> validDataPointers;
+
+ QPaintEngine *pengine;
+
+ friend class QPixmap;
+ friend class QRasterBuffer;
+ friend class QRasterPaintEngine;
+ friend class QCoreGraphicsPaintEngine;
+ friend CGImageRef qt_mac_create_imagemask(const QPixmap&, const QRectF&);
+ friend quint32 *qt_mac_pixmap_get_base(const QPixmap*);
+ friend int qt_mac_pixmap_get_bytes_per_line(const QPixmap*);
+ friend void qt_mac_cgimage_data_free(void *, const void*, size_t);
+ friend IconRef qt_mac_create_iconref(const QPixmap&);
+ friend CGContextRef qt_mac_cg_context(const QPaintDevice*);
+ friend QColor qcolorForThemeTextColor(ThemeTextColor themeColor);
+};
+
+QT_END_NAMESPACE
+
+#endif // QPIXMAP_MAC_P_H
diff --git a/src/gui/painting/qprintengine_mac.mm b/src/widgets/platforms/mac/qprintengine_mac.mm
index fb40677e2d..fb40677e2d 100644
--- a/src/gui/painting/qprintengine_mac.mm
+++ b/src/widgets/platforms/mac/qprintengine_mac.mm
diff --git a/src/gui/painting/qprintengine_mac_p.h b/src/widgets/platforms/mac/qprintengine_mac_p.h
index 5c4fe944e0..5c4fe944e0 100644
--- a/src/gui/painting/qprintengine_mac_p.h
+++ b/src/widgets/platforms/mac/qprintengine_mac_p.h
diff --git a/src/gui/painting/qprinterinfo_mac.cpp b/src/widgets/platforms/mac/qprinterinfo_mac.cpp
index 455510d5d3..455510d5d3 100644
--- a/src/gui/painting/qprinterinfo_mac.cpp
+++ b/src/widgets/platforms/mac/qprinterinfo_mac.cpp
diff --git a/src/gui/text/qrawfont_mac.cpp b/src/widgets/platforms/mac/qrawfont_mac.cpp
index 40c719a1af..40c719a1af 100644
--- a/src/gui/text/qrawfont_mac.cpp
+++ b/src/widgets/platforms/mac/qrawfont_mac.cpp
diff --git a/src/widgets/platforms/mac/qregion_mac.cpp b/src/widgets/platforms/mac/qregion_mac.cpp
new file mode 100644
index 0000000000..94805a7f80
--- /dev/null
+++ b/src/widgets/platforms/mac/qregion_mac.cpp
@@ -0,0 +1,286 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <private/qt_mac_p.h>
+#include "qcoreapplication.h"
+#include <qlibrary.h>
+
+QT_BEGIN_NAMESPACE
+
+QRegion::QRegionData QRegion::shared_empty = { Q_BASIC_ATOMIC_INITIALIZER(1), 0 };
+
+#if defined(Q_WS_MAC32) && !defined(QT_MAC_USE_COCOA)
+#define RGN_CACHE_SIZE 200
+#ifdef RGN_CACHE_SIZE
+static bool rgncache_init = false;
+static int rgncache_used;
+static RgnHandle rgncache[RGN_CACHE_SIZE];
+static void qt_mac_cleanup_rgncache()
+{
+ rgncache_init = false;
+ for(int i = 0; i < RGN_CACHE_SIZE; ++i) {
+ if(rgncache[i]) {
+ --rgncache_used;
+ DisposeRgn(rgncache[i]);
+ rgncache[i] = 0;
+ }
+ }
+}
+#endif
+
+Q_WIDGETS_EXPORT RgnHandle qt_mac_get_rgn()
+{
+#ifdef RGN_CACHE_SIZE
+ if(!rgncache_init) {
+ rgncache_used = 0;
+ rgncache_init = true;
+ for(int i = 0; i < RGN_CACHE_SIZE; ++i)
+ rgncache[i] = 0;
+ qAddPostRoutine(qt_mac_cleanup_rgncache);
+ } else if(rgncache_used) {
+ for(int i = 0; i < RGN_CACHE_SIZE; ++i) {
+ if(rgncache[i]) {
+ RgnHandle ret = rgncache[i];
+ SetEmptyRgn(ret);
+ rgncache[i] = 0;
+ --rgncache_used;
+ return ret;
+ }
+ }
+ }
+#endif
+ return NewRgn();
+}
+
+Q_WIDGETS_EXPORT void qt_mac_dispose_rgn(RgnHandle r)
+{
+#ifdef RGN_CACHE_SIZE
+ if(rgncache_init && rgncache_used < RGN_CACHE_SIZE) {
+ for(int i = 0; i < RGN_CACHE_SIZE; ++i) {
+ if(!rgncache[i]) {
+ ++rgncache_used;
+ rgncache[i] = r;
+ return;
+ }
+ }
+ }
+#endif
+ DisposeRgn(r);
+}
+
+static OSStatus qt_mac_get_rgn_rect(UInt16 msg, RgnHandle, const Rect *rect, void *reg)
+{
+ if(msg == kQDRegionToRectsMsgParse) {
+ QRect rct(rect->left, rect->top, (rect->right - rect->left), (rect->bottom - rect->top));
+ if(!rct.isEmpty())
+ *((QRegion *)reg) += rct;
+ }
+ return noErr;
+}
+
+Q_WIDGETS_EXPORT QRegion qt_mac_convert_mac_region(RgnHandle rgn)
+{
+ return QRegion::fromQDRgn(rgn);
+}
+
+QRegion QRegion::fromQDRgn(RgnHandle rgn)
+{
+ QRegion ret;
+ ret.detach();
+ OSStatus oss = QDRegionToRects(rgn, kQDParseRegionFromTopLeft, qt_mac_get_rgn_rect, (void *)&ret);
+ if(oss != noErr)
+ return QRegion();
+ return ret;
+}
+
+/*!
+ \internal
+ Create's a RegionHandle, it's the caller's responsibility to release.
+*/
+RgnHandle QRegion::toQDRgn() const
+{
+ RgnHandle rgnHandle = qt_mac_get_rgn();
+ if(d->qt_rgn && d->qt_rgn->numRects) {
+ RgnHandle tmp_rgn = qt_mac_get_rgn();
+ int n = d->qt_rgn->numRects;
+ const QRect *qt_r = (n == 1) ? &d->qt_rgn->extents : d->qt_rgn->rects.constData();
+ while (n--) {
+ SetRectRgn(tmp_rgn,
+ qMax(SHRT_MIN, qt_r->x()),
+ qMax(SHRT_MIN, qt_r->y()),
+ qMin(SHRT_MAX, qt_r->right() + 1),
+ qMin(SHRT_MAX, qt_r->bottom() + 1));
+ UnionRgn(rgnHandle, tmp_rgn, rgnHandle);
+ ++qt_r;
+ }
+ qt_mac_dispose_rgn(tmp_rgn);
+ }
+ return rgnHandle;
+}
+
+/*!
+ \internal
+ Create's a RegionHandle, it's the caller's responsibility to release.
+ Returns 0 if the QRegion overflows.
+*/
+RgnHandle QRegion::toQDRgnForUpdate_sys() const
+{
+ RgnHandle rgnHandle = qt_mac_get_rgn();
+ if(d->qt_rgn && d->qt_rgn->numRects) {
+ RgnHandle tmp_rgn = qt_mac_get_rgn();
+ int n = d->qt_rgn->numRects;
+ const QRect *qt_r = (n == 1) ? &d->qt_rgn->extents : d->qt_rgn->rects.constData();
+ while (n--) {
+
+ // detect overflow. Tested for use with HIViewSetNeedsDisplayInRegion
+ // in QWidgetPrivate::update_sys().
+ enum { HIViewSetNeedsDisplayInRegionOverflow = 10000 }; // empirically determined conservative value
+ if (qt_r->right() > HIViewSetNeedsDisplayInRegionOverflow || qt_r->bottom() > HIViewSetNeedsDisplayInRegionOverflow) {
+ qt_mac_dispose_rgn(tmp_rgn);
+ qt_mac_dispose_rgn(rgnHandle);
+ return 0;
+ }
+
+ SetRectRgn(tmp_rgn,
+ qMax(SHRT_MIN, qt_r->x()),
+ qMax(SHRT_MIN, qt_r->y()),
+ qMin(SHRT_MAX, qt_r->right() + 1),
+ qMin(SHRT_MAX, qt_r->bottom() + 1));
+ UnionRgn(rgnHandle, tmp_rgn, rgnHandle);
+ ++qt_r;
+ }
+ qt_mac_dispose_rgn(tmp_rgn);
+ }
+ return rgnHandle;
+}
+
+#endif
+
+#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
+OSStatus QRegion::shape2QRegionHelper(int inMessage, HIShapeRef,
+ const CGRect *inRect, void *inRefcon)
+{
+ QRegion *region = static_cast<QRegion *>(inRefcon);
+ if (!region)
+ return paramErr;
+
+ switch (inMessage) {
+ case kHIShapeEnumerateRect:
+ *region += QRect(inRect->origin.x, inRect->origin.y,
+ inRect->size.width, inRect->size.height);
+ break;
+ case kHIShapeEnumerateInit:
+ // Assume the region is already setup correctly
+ case kHIShapeEnumerateTerminate:
+ default:
+ break;
+ }
+ return noErr;
+}
+#endif
+
+/*!
+ \internal
+ Create's a mutable shape, it's the caller's responsibility to release.
+ WARNING: this function clamps the coordinates to SHRT_MIN/MAX on 10.4 and below.
+*/
+HIMutableShapeRef QRegion::toHIMutableShape() const
+{
+ HIMutableShapeRef shape = HIShapeCreateMutable();
+#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
+ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) {
+ if (d->qt_rgn && d->qt_rgn->numRects) {
+ int n = d->qt_rgn->numRects;
+ const QRect *qt_r = (n == 1) ? &d->qt_rgn->extents : d->qt_rgn->rects.constData();
+ while (n--) {
+ CGRect cgRect = CGRectMake(qt_r->x(), qt_r->y(), qt_r->width(), qt_r->height());
+ HIShapeUnionWithRect(shape, &cgRect);
+ ++qt_r;
+ }
+ }
+ } else
+#endif
+ {
+#ifndef QT_MAC_USE_COCOA
+ QCFType<HIShapeRef> qdShape = HIShapeCreateWithQDRgn(QMacSmartQuickDrawRegion(toQDRgn()));
+ HIShapeUnion(qdShape, shape, shape);
+#endif
+ }
+ return shape;
+}
+
+#if !defined(Q_WS_MAC64) && !defined(QT_MAC_USE_COCOA)
+typedef OSStatus (*PtrHIShapeGetAsQDRgn)(HIShapeRef, RgnHandle);
+static PtrHIShapeGetAsQDRgn ptrHIShapeGetAsQDRgn = 0;
+#endif
+
+
+QRegion QRegion::fromHIShapeRef(HIShapeRef shape)
+{
+ QRegion returnRegion;
+ returnRegion.detach();
+ // Begin gratuitous #if-defery
+#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
+# ifndef Q_WS_MAC64
+ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) {
+# endif
+ HIShapeEnumerate(shape, kHIShapeParseFromTopLeft, shape2QRegionHelper, &returnRegion);
+# ifndef Q_WS_MAC64
+ } else
+# endif
+#endif
+ {
+#if !defined(Q_WS_MAC64) && !defined(QT_MAC_USE_COCOA)
+ if (ptrHIShapeGetAsQDRgn == 0) {
+ QLibrary library(QLatin1String("/System/Library/Frameworks/Carbon.framework/Carbon"));
+ library.setLoadHints(QLibrary::ExportExternalSymbolsHint);
+ ptrHIShapeGetAsQDRgn = reinterpret_cast<PtrHIShapeGetAsQDRgn>(library.resolve("HIShapeGetAsQDRgn"));
+ }
+ RgnHandle rgn = qt_mac_get_rgn();
+ ptrHIShapeGetAsQDRgn(shape, rgn);
+ returnRegion = QRegion::fromQDRgn(rgn);
+ qt_mac_dispose_rgn(rgn);
+#endif
+ }
+ return returnRegion;
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/kernel/qsound_mac.mm b/src/widgets/platforms/mac/qsound_mac.mm
index 8c8ac0818b..8c8ac0818b 100644
--- a/src/gui/kernel/qsound_mac.mm
+++ b/src/widgets/platforms/mac/qsound_mac.mm
diff --git a/src/widgets/platforms/mac/qt_cocoa_helpers_mac.mm b/src/widgets/platforms/mac/qt_cocoa_helpers_mac.mm
new file mode 100644
index 0000000000..d1620b1489
--- /dev/null
+++ b/src/widgets/platforms/mac/qt_cocoa_helpers_mac.mm
@@ -0,0 +1,1563 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/****************************************************************************
+**
+** Copyright (c) 2007-2008, Apple, Inc.
+**
+** All rights reserved.
+**
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are met:
+**
+** * Redistributions of source code must retain the above copyright notice,
+** this list of conditions and the following disclaimer.
+**
+** * Redistributions in binary form must reproduce the above copyright notice,
+** this list of conditions and the following disclaimer in the documentation
+** and/or other materials provided with the distribution.
+**
+** * Neither the name of Apple, Inc. nor the names of its contributors
+** may be used to endorse or promote products derived from this software
+** without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+**
+****************************************************************************/
+
+#include <private/qcore_mac_p.h>
+#include <qaction.h>
+#include <qwidget.h>
+#include <qdesktopwidget.h>
+#include <qevent.h>
+#include <qpixmapcache.h>
+#include <qvarlengtharray.h>
+#include <private/qevent_p.h>
+#include <private/qt_cocoa_helpers_mac_p.h>
+#include <private/qt_mac_p.h>
+#include <private/qapplication_p.h>
+#include <private/qcocoaapplication_mac_p.h>
+#include <private/qcocoawindow_mac_p.h>
+#include <private/qcocoaview_mac_p.h>
+#include <private/qkeymapper_p.h>
+#include <private/qwidget_p.h>
+#include <private/qcocoawindow_mac_p.h>
+
+QT_BEGIN_NAMESPACE
+
+#ifdef QT_MAC_USE_COCOA
+// Cmd + left mousebutton should produce a right button
+// press (mainly for mac users with one-button mice):
+static bool qt_leftButtonIsRightButton = false;
+#endif
+
+Q_GLOBAL_STATIC(QMacWindowFader, macwindowFader);
+
+QMacWindowFader::QMacWindowFader()
+ : m_duration(0.250)
+{
+}
+
+QMacWindowFader *QMacWindowFader::currentFader()
+{
+ return macwindowFader();
+}
+
+void QMacWindowFader::registerWindowToFade(QWidget *window)
+{
+ m_windowsToFade.append(window);
+}
+
+void QMacWindowFader::performFade()
+{
+ const QWidgetList myWidgetsToFade = m_windowsToFade;
+ const int widgetCount = myWidgetsToFade.count();
+#if QT_MAC_USE_COCOA
+ QMacCocoaAutoReleasePool pool;
+ [NSAnimationContext beginGrouping];
+ [[NSAnimationContext currentContext] setDuration:NSTimeInterval(m_duration)];
+#endif
+
+ for (int i = 0; i < widgetCount; ++i) {
+ QWidget *widget = m_windowsToFade.at(i);
+ OSWindowRef window = qt_mac_window_for(widget);
+#if QT_MAC_USE_COCOA
+ [[window animator] setAlphaValue:0.0];
+ QTimer::singleShot(qRound(m_duration * 1000), widget, SLOT(hide()));
+#else
+ TransitionWindowOptions options = {0, m_duration, 0, 0};
+ TransitionWindowWithOptions(window, kWindowFadeTransitionEffect, kWindowHideTransitionAction,
+ 0, 1, &options);
+#endif
+ }
+#if QT_MAC_USE_COCOA
+ [NSAnimationContext endGrouping];
+#endif
+ m_duration = 0.250;
+ m_windowsToFade.clear();
+}
+
+extern bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event); // qapplication.cpp;
+extern QWidget * mac_mouse_grabber;
+extern QWidget *qt_button_down; //qapplication_mac.cpp
+extern QPointer<QWidget> qt_last_mouse_receiver;
+extern OSViewRef qt_mac_effectiveview_for(const QWidget *w);
+extern void qt_mac_updateCursorWithWidgetUnderMouse(QWidget *widgetUnderMouse); // qcursor_mac.mm
+
+void macWindowFade(void * /*OSWindowRef*/ window, float durationSeconds)
+{
+#ifdef QT_MAC_USE_COCOA
+ QMacCocoaAutoReleasePool pool;
+#endif
+ OSWindowRef wnd = static_cast<OSWindowRef>(window);
+ if (wnd) {
+ QWidget *widget;
+#if QT_MAC_USE_COCOA
+ widget = [wnd QT_MANGLE_NAMESPACE(qt_qwidget)];
+#else
+ const UInt32 kWidgetCreatorQt = kEventClassQt;
+ enum {
+ kWidgetPropertyQWidget = 'QWId' //QWidget *
+ };
+ if (GetWindowProperty(static_cast<WindowRef>(window), kWidgetCreatorQt, kWidgetPropertyQWidget, sizeof(widget), 0, &widget) != noErr)
+ widget = 0;
+#endif
+ if (widget) {
+ QMacWindowFader::currentFader()->setFadeDuration(durationSeconds);
+ QMacWindowFader::currentFader()->registerWindowToFade(widget);
+ QMacWindowFader::currentFader()->performFade();
+ }
+ }
+}
+struct dndenum_mapper
+{
+ NSDragOperation mac_code;
+ Qt::DropAction qt_code;
+ bool Qt2Mac;
+};
+
+#if defined(QT_MAC_USE_COCOA) && defined(__OBJC__)
+
+static dndenum_mapper dnd_enums[] = {
+ { NSDragOperationLink, Qt::LinkAction, true },
+ { NSDragOperationMove, Qt::MoveAction, true },
+ { NSDragOperationCopy, Qt::CopyAction, true },
+ { NSDragOperationGeneric, Qt::CopyAction, false },
+ { NSDragOperationEvery, Qt::ActionMask, false },
+ { NSDragOperationNone, Qt::IgnoreAction, false }
+};
+
+NSDragOperation qt_mac_mapDropAction(Qt::DropAction action)
+{
+ for (int i=0; dnd_enums[i].qt_code; i++) {
+ if (dnd_enums[i].Qt2Mac && (action & dnd_enums[i].qt_code)) {
+ return dnd_enums[i].mac_code;
+ }
+ }
+ return NSDragOperationNone;
+}
+
+NSDragOperation qt_mac_mapDropActions(Qt::DropActions actions)
+{
+ NSDragOperation nsActions = NSDragOperationNone;
+ for (int i=0; dnd_enums[i].qt_code; i++) {
+ if (dnd_enums[i].Qt2Mac && (actions & dnd_enums[i].qt_code))
+ nsActions |= dnd_enums[i].mac_code;
+ }
+ return nsActions;
+}
+
+Qt::DropAction qt_mac_mapNSDragOperation(NSDragOperation nsActions)
+{
+ Qt::DropAction action = Qt::IgnoreAction;
+ for (int i=0; dnd_enums[i].mac_code; i++) {
+ if (nsActions & dnd_enums[i].mac_code)
+ return dnd_enums[i].qt_code;
+ }
+ return action;
+}
+
+Qt::DropActions qt_mac_mapNSDragOperations(NSDragOperation nsActions)
+{
+ Qt::DropActions actions = Qt::IgnoreAction;
+ for (int i=0; dnd_enums[i].mac_code; i++) {
+ if (nsActions & dnd_enums[i].mac_code)
+ actions |= dnd_enums[i].qt_code;
+ }
+ return actions;
+}
+
+Q_GLOBAL_STATIC(DnDParams, currentDnDParameters);
+DnDParams *macCurrentDnDParameters()
+{
+ return currentDnDParameters();
+}
+#endif
+
+bool macWindowIsTextured( void * /*OSWindowRef*/ window )
+{
+ OSWindowRef wnd = static_cast<OSWindowRef>(window);
+#if QT_MAC_USE_COCOA
+ return ( [wnd styleMask] & NSTexturedBackgroundWindowMask ) ? true : false;
+#else
+ WindowAttributes currentAttributes;
+ GetWindowAttributes(wnd, &currentAttributes);
+ return (currentAttributes & kWindowMetalAttribute) ? true : false;
+#endif
+}
+
+void macWindowToolbarShow(const QWidget *widget, bool show )
+{
+ OSWindowRef wnd = qt_mac_window_for(widget);
+#if QT_MAC_USE_COCOA
+ if (NSToolbar *toolbar = [wnd toolbar]) {
+ QMacCocoaAutoReleasePool pool;
+ if (show != [toolbar isVisible]) {
+ [toolbar setVisible:show];
+ } else {
+ // The toolbar may be in sync, but we are not, update our framestrut.
+ qt_widget_private(const_cast<QWidget *>(widget))->updateFrameStrut();
+ }
+ }
+#else
+ qt_widget_private(const_cast<QWidget *>(widget))->updateFrameStrut();
+ ShowHideWindowToolbar(wnd, show, false);
+#endif
+}
+
+
+void macWindowToolbarSet( void * /*OSWindowRef*/ window, void *toolbarRef )
+{
+ OSWindowRef wnd = static_cast<OSWindowRef>(window);
+#if QT_MAC_USE_COCOA
+ [wnd setToolbar:static_cast<NSToolbar *>(toolbarRef)];
+#else
+ SetWindowToolbar(wnd, static_cast<HIToolbarRef>(toolbarRef));
+#endif
+}
+
+bool macWindowToolbarIsVisible( void * /*OSWindowRef*/ window )
+{
+ OSWindowRef wnd = static_cast<OSWindowRef>(window);
+#if QT_MAC_USE_COCOA
+ if (NSToolbar *toolbar = [wnd toolbar])
+ return [toolbar isVisible];
+ return false;
+#else
+ return IsWindowToolbarVisible(wnd);
+#endif
+}
+
+void macWindowSetHasShadow( void * /*OSWindowRef*/ window, bool hasShadow )
+{
+ OSWindowRef wnd = static_cast<OSWindowRef>(window);
+#if QT_MAC_USE_COCOA
+ [wnd setHasShadow:BOOL(hasShadow)];
+#else
+ if (hasShadow)
+ ChangeWindowAttributes(wnd, 0, kWindowNoShadowAttribute);
+ else
+ ChangeWindowAttributes(wnd, kWindowNoShadowAttribute, 0);
+#endif
+}
+
+void macWindowFlush(void * /*OSWindowRef*/ window)
+{
+ OSWindowRef wnd = static_cast<OSWindowRef>(window);
+#if QT_MAC_USE_COCOA
+ [wnd flushWindowIfNeeded];
+#else
+ HIWindowFlush(wnd);
+#endif
+}
+
+void qt_mac_update_mouseTracking(QWidget *widget)
+{
+#ifdef QT_MAC_USE_COCOA
+ [qt_mac_nativeview_for(widget) updateTrackingAreas];
+#else
+ Q_UNUSED(widget);
+#endif
+}
+
+OSStatus qt_mac_drawCGImage(CGContextRef inContext, const CGRect *inBounds, CGImageRef inImage)
+{
+ // Verbatim copy if HIViewDrawCGImage (as shown on Carbon-Dev)
+ OSStatus err = noErr;
+
+ require_action(inContext != NULL, InvalidContext, err = paramErr);
+ require_action(inBounds != NULL, InvalidBounds, err = paramErr);
+ require_action(inImage != NULL, InvalidImage, err = paramErr);
+
+ CGContextSaveGState( inContext );
+ CGContextTranslateCTM (inContext, 0, inBounds->origin.y + CGRectGetMaxY(*inBounds));
+ CGContextScaleCTM(inContext, 1, -1);
+
+ CGContextDrawImage(inContext, *inBounds, inImage);
+
+ CGContextRestoreGState(inContext);
+InvalidImage:
+InvalidBounds:
+InvalidContext:
+ return err;
+}
+
+bool qt_mac_checkForNativeSizeGrip(const QWidget *widget)
+{
+#ifndef QT_MAC_USE_COCOA
+ OSViewRef nativeSizeGrip = 0;
+ HIViewFindByID(HIViewGetRoot(HIViewGetWindow(HIViewRef(widget->winId()))), kHIViewWindowGrowBoxID, &nativeSizeGrip);
+ return (nativeSizeGrip != 0);
+#else
+ return [[reinterpret_cast<NSView *>(widget->effectiveWinId()) window] showsResizeIndicator];
+#endif
+}
+struct qt_mac_enum_mapper
+{
+ int mac_code;
+ int qt_code;
+#if defined(DEBUG_MOUSE_MAPS)
+# define QT_MAC_MAP_ENUM(x) x, #x
+ const char *desc;
+#else
+# define QT_MAC_MAP_ENUM(x) x
+#endif
+};
+
+//mouse buttons
+static qt_mac_enum_mapper qt_mac_mouse_symbols[] = {
+{ kEventMouseButtonPrimary, QT_MAC_MAP_ENUM(Qt::LeftButton) },
+{ kEventMouseButtonSecondary, QT_MAC_MAP_ENUM(Qt::RightButton) },
+{ kEventMouseButtonTertiary, QT_MAC_MAP_ENUM(Qt::MidButton) },
+{ 4, QT_MAC_MAP_ENUM(Qt::XButton1) },
+{ 5, QT_MAC_MAP_ENUM(Qt::XButton2) },
+{ 0, QT_MAC_MAP_ENUM(0) }
+};
+Qt::MouseButtons qt_mac_get_buttons(int buttons)
+{
+#ifdef DEBUG_MOUSE_MAPS
+ qDebug("Qt: internal: **Mapping buttons: %d (0x%04x)", buttons, buttons);
+#endif
+ Qt::MouseButtons ret = Qt::NoButton;
+ for(int i = 0; qt_mac_mouse_symbols[i].qt_code; i++) {
+ if (buttons & (0x01<<(qt_mac_mouse_symbols[i].mac_code-1))) {
+#ifdef DEBUG_MOUSE_MAPS
+ qDebug("Qt: internal: got button: %s", qt_mac_mouse_symbols[i].desc);
+#endif
+ ret |= Qt::MouseButtons(qt_mac_mouse_symbols[i].qt_code);
+ }
+ }
+ return ret;
+}
+Qt::MouseButton qt_mac_get_button(EventMouseButton button)
+{
+#ifdef DEBUG_MOUSE_MAPS
+ qDebug("Qt: internal: **Mapping button: %d (0x%04x)", button, button);
+#endif
+ Qt::MouseButtons ret = 0;
+ for(int i = 0; qt_mac_mouse_symbols[i].qt_code; i++) {
+ if (button == qt_mac_mouse_symbols[i].mac_code) {
+#ifdef DEBUG_MOUSE_MAPS
+ qDebug("Qt: internal: got button: %s", qt_mac_mouse_symbols[i].desc);
+#endif
+ return Qt::MouseButton(qt_mac_mouse_symbols[i].qt_code);
+ }
+ }
+ return Qt::NoButton;
+}
+
+void macSendToolbarChangeEvent(QWidget *widget)
+{
+ QToolBarChangeEvent ev(!(GetCurrentKeyModifiers() & cmdKey));
+ qt_sendSpontaneousEvent(widget, &ev);
+}
+
+Q_GLOBAL_STATIC(QMacTabletHash, tablet_hash)
+QMacTabletHash *qt_mac_tablet_hash()
+{
+ return tablet_hash();
+}
+
+#ifdef QT_MAC_USE_COCOA
+
+// Clears the QWidget pointer that each QCocoaView holds.
+void qt_mac_clearCocoaViewQWidgetPointers(QWidget *widget)
+{
+ QT_MANGLE_NAMESPACE(QCocoaView) *cocoaView = reinterpret_cast<QT_MANGLE_NAMESPACE(QCocoaView) *>(qt_mac_nativeview_for(widget));
+ if (cocoaView && [cocoaView respondsToSelector:@selector(qt_qwidget)]) {
+ [cocoaView qt_clearQWidget];
+ }
+}
+
+void qt_dispatchTabletProximityEvent(void * /*NSEvent * */ tabletEvent)
+{
+ NSEvent *proximityEvent = static_cast<NSEvent *>(tabletEvent);
+ // simply construct a Carbon proximity record and handle it all in one spot.
+ TabletProximityRec carbonProximityRec = { [proximityEvent vendorID],
+ [proximityEvent tabletID],
+ [proximityEvent pointingDeviceID],
+ [proximityEvent deviceID],
+ [proximityEvent systemTabletID],
+ [proximityEvent vendorPointingDeviceType],
+ [proximityEvent pointingDeviceSerialNumber],
+ [proximityEvent uniqueID],
+ [proximityEvent capabilityMask],
+ [proximityEvent pointingDeviceType],
+ [proximityEvent isEnteringProximity] };
+ qt_dispatchTabletProximityEvent(carbonProximityRec);
+}
+#endif // QT_MAC_USE_COCOA
+
+void qt_dispatchTabletProximityEvent(const ::TabletProximityRec &proxRec)
+{
+ QTabletDeviceData proximityDevice;
+ proximityDevice.tabletUniqueID = proxRec.uniqueID;
+ proximityDevice.capabilityMask = proxRec.capabilityMask;
+
+ switch (proxRec.pointerType) {
+ case NSUnknownPointingDevice:
+ default:
+ proximityDevice.tabletPointerType = QTabletEvent::UnknownPointer;
+ break;
+ case NSPenPointingDevice:
+ proximityDevice.tabletPointerType = QTabletEvent::Pen;
+ break;
+ case NSCursorPointingDevice:
+ proximityDevice.tabletPointerType = QTabletEvent::Cursor;
+ break;
+ case NSEraserPointingDevice:
+ proximityDevice.tabletPointerType = QTabletEvent::Eraser;
+ break;
+ }
+ uint bits = proxRec.vendorPointerType;
+ if (bits == 0 && proximityDevice.tabletUniqueID != 0) {
+ // Fallback. It seems that the driver doesn't always include all the information.
+ // High-End Wacom devices store their "type" in the uper bits of the Unique ID.
+ // I'm not sure how to handle it for consumer devices, but I'll test that in a bit.
+ bits = proximityDevice.tabletUniqueID >> 32;
+ }
+ // Defined in the "EN0056-NxtGenImpGuideX"
+ // on Wacom's Developer Website (www.wacomeng.com)
+ if (((bits & 0x0006) == 0x0002) && ((bits & 0x0F06) != 0x0902)) {
+ proximityDevice.tabletDeviceType = QTabletEvent::Stylus;
+ } else {
+ switch (bits & 0x0F06) {
+ case 0x0802:
+ proximityDevice.tabletDeviceType = QTabletEvent::Stylus;
+ break;
+ case 0x0902:
+ proximityDevice.tabletDeviceType = QTabletEvent::Airbrush;
+ break;
+ case 0x0004:
+ proximityDevice.tabletDeviceType = QTabletEvent::FourDMouse;
+ break;
+ case 0x0006:
+ proximityDevice.tabletDeviceType = QTabletEvent::Puck;
+ break;
+ case 0x0804:
+ proximityDevice.tabletDeviceType = QTabletEvent::RotationStylus;
+ break;
+ default:
+ proximityDevice.tabletDeviceType = QTabletEvent::NoDevice;
+ }
+ }
+ // The deviceID is "unique" while in the proximity, it's a key that we can use for
+ // linking up TabletDeviceData to an event (especially if there are two devices in action).
+ bool entering = proxRec.enterProximity;
+ if (entering) {
+ qt_mac_tablet_hash()->insert(proxRec.deviceID, proximityDevice);
+ } else {
+ qt_mac_tablet_hash()->remove(proxRec.deviceID);
+ }
+
+ QTabletEvent qtabletProximity(entering ? QEvent::TabletEnterProximity
+ : QEvent::TabletLeaveProximity,
+ QPoint(), QPoint(), QPointF(), proximityDevice.tabletDeviceType,
+ proximityDevice.tabletPointerType, 0., 0, 0, 0., 0., 0, 0,
+ proximityDevice.tabletUniqueID);
+
+ qt_sendSpontaneousEvent(qApp, &qtabletProximity);
+}
+
+#ifdef QT_MAC_USE_COCOA
+
+Qt::KeyboardModifiers qt_cocoaModifiers2QtModifiers(ulong modifierFlags)
+{
+ Qt::KeyboardModifiers qtMods =Qt::NoModifier;
+ if (modifierFlags & NSShiftKeyMask)
+ qtMods |= Qt::ShiftModifier;
+ if (modifierFlags & NSControlKeyMask)
+ qtMods |= Qt::MetaModifier;
+ if (modifierFlags & NSAlternateKeyMask)
+ qtMods |= Qt::AltModifier;
+ if (modifierFlags & NSCommandKeyMask)
+ qtMods |= Qt::ControlModifier;
+ if (modifierFlags & NSNumericPadKeyMask)
+ qtMods |= Qt::KeypadModifier;
+ return qtMods;
+}
+
+Qt::KeyboardModifiers qt_cocoaDragOperation2QtModifiers(uint dragOperations)
+{
+ Qt::KeyboardModifiers qtMods =Qt::NoModifier;
+ if (dragOperations & NSDragOperationLink)
+ qtMods |= Qt::MetaModifier;
+ if (dragOperations & NSDragOperationGeneric)
+ qtMods |= Qt::ControlModifier;
+ if (dragOperations & NSDragOperationCopy)
+ qtMods |= Qt::AltModifier;
+ return qtMods;
+}
+
+static inline QEvent::Type cocoaEvent2QtEvent(NSUInteger eventType)
+{
+ // Handle the trivial cases that can be determined from the type.
+ switch (eventType) {
+ case NSKeyDown:
+ return QEvent::KeyPress;
+ case NSKeyUp:
+ return QEvent::KeyRelease;
+ case NSLeftMouseDown:
+ case NSRightMouseDown:
+ case NSOtherMouseDown:
+ return QEvent::MouseButtonPress;
+ case NSLeftMouseUp:
+ case NSRightMouseUp:
+ case NSOtherMouseUp:
+ return QEvent::MouseButtonRelease;
+ case NSMouseMoved:
+ case NSLeftMouseDragged:
+ case NSRightMouseDragged:
+ case NSOtherMouseDragged:
+ return QEvent::MouseMove;
+ case NSScrollWheel:
+ return QEvent::Wheel;
+ }
+ return QEvent::None;
+}
+
+static bool mustUseCocoaKeyEvent()
+{
+ QCFType<TISInputSourceRef> source = TISCopyCurrentKeyboardInputSource();
+ return TISGetInputSourceProperty(source, kTISPropertyUnicodeKeyLayoutData) == 0;
+}
+
+bool qt_dispatchKeyEventWithCocoa(void * /*NSEvent * */ keyEvent, QWidget *widgetToGetEvent)
+{
+ NSEvent *event = static_cast<NSEvent *>(keyEvent);
+ NSString *keyChars = [event charactersIgnoringModifiers];
+ 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;
+
+ // 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 (!ignoreText && !(keyMods & (Qt::ControlModifier | Qt::MetaModifier)))
+ text = QCFString::toQString(reinterpret_cast<CFStringRef>(keyChars));
+
+ UInt32 macScanCode = 1;
+ QKeyEventEx ke(cocoaEvent2QtEvent([event type]), qtKey, keyMods, text, [event isARepeat], qMax(1, keyLength),
+ macScanCode, [event keyCode], [event modifierFlags]);
+ return qt_sendSpontaneousEvent(widgetToGetEvent, &ke) && ke.isAccepted();
+}
+#endif
+
+Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum)
+{
+ if (buttonNum == 0)
+ return Qt::LeftButton;
+ if (buttonNum == 1)
+ return Qt::RightButton;
+ if (buttonNum == 2)
+ return Qt::MidButton;
+ if (buttonNum == 3)
+ return Qt::XButton1;
+ if (buttonNum == 4)
+ return Qt::XButton2;
+ return Qt::NoButton;
+}
+
+bool qt_dispatchKeyEvent(void * /*NSEvent * */ keyEvent, QWidget *widgetToGetEvent)
+{
+#ifndef QT_MAC_USE_COCOA
+ Q_UNUSED(keyEvent);
+ Q_UNUSED(widgetToGetEvent);
+ return false;
+#else
+ NSEvent *event = static_cast<NSEvent *>(keyEvent);
+ EventRef key_event = static_cast<EventRef>(const_cast<void *>([event eventRef]));
+ Q_ASSERT(key_event);
+ unsigned int info = 0;
+
+ if ([event type] == NSKeyDown) {
+ NSString *characters = [event characters];
+ if ([characters length]) {
+ unichar value = [characters characterAtIndex:0];
+ qt_keymapper_private()->updateKeyMap(0, key_event, (void *)&value);
+ info = value;
+ }
+ }
+
+ if (qt_mac_sendMacEventToWidget(widgetToGetEvent, key_event))
+ return true;
+
+ if (mustUseCocoaKeyEvent())
+ return qt_dispatchKeyEventWithCocoa(keyEvent, widgetToGetEvent);
+
+ bool consumed = qt_keymapper_private()->translateKeyEvent(widgetToGetEvent, 0, key_event, &info, true);
+ return consumed && (info != 0);
+#endif
+}
+
+void qt_dispatchModifiersChanged(void * /*NSEvent * */flagsChangedEvent, QWidget *widgetToGetEvent)
+{
+#ifndef QT_MAC_USE_COCOA
+ Q_UNUSED(flagsChangedEvent);
+ Q_UNUSED(widgetToGetEvent);
+#else
+ UInt32 modifiers = 0;
+ // Sync modifiers with Qt
+ NSEvent *event = static_cast<NSEvent *>(flagsChangedEvent);
+ EventRef key_event = static_cast<EventRef>(const_cast<void *>([event eventRef]));
+ Q_ASSERT(key_event);
+ GetEventParameter(key_event, kEventParamKeyModifiers, typeUInt32, 0,
+ sizeof(modifiers), 0, &modifiers);
+ extern void qt_mac_send_modifiers_changed(quint32 modifiers, QObject *object);
+ qt_mac_send_modifiers_changed(modifiers, widgetToGetEvent);
+#endif
+}
+
+QPointF flipPoint(const NSPoint &p)
+{
+ return QPointF(p.x, flipYCoordinate(p.y));
+}
+
+NSPoint flipPoint(const QPoint &p)
+{
+ return NSMakePoint(p.x(), flipYCoordinate(p.y()));
+}
+
+NSPoint flipPoint(const QPointF &p)
+{
+ return NSMakePoint(p.x(), flipYCoordinate(p.y()));
+}
+
+#if QT_MAC_USE_COCOA && __OBJC__
+
+void qt_mac_handleNonClientAreaMouseEvent(NSWindow *window, NSEvent *event)
+{
+ QWidget *widgetToGetEvent = [window QT_MANGLE_NAMESPACE(qt_qwidget)];
+ if (widgetToGetEvent == 0)
+ return;
+
+ NSEventType evtType = [event type];
+ QPoint qlocalPoint;
+ QPoint qglobalPoint;
+ bool processThisEvent = false;
+ bool fakeNCEvents = false;
+ bool fakeMouseEvents = false;
+
+ // Check if this is a mouse event.
+ if (evtType == NSLeftMouseDown || evtType == NSLeftMouseUp
+ || evtType == NSRightMouseDown || evtType == NSRightMouseUp
+ || evtType == NSOtherMouseDown || evtType == NSOtherMouseUp
+ || evtType == NSMouseMoved || evtType == NSLeftMouseDragged
+ || evtType == NSRightMouseDragged || evtType == NSOtherMouseDragged) {
+ // Check if we want to pass this message to another window
+ if (mac_mouse_grabber && mac_mouse_grabber != widgetToGetEvent) {
+ NSWindow *grabWindow = static_cast<NSWindow *>(qt_mac_window_for(mac_mouse_grabber));
+ if (window != grabWindow) {
+ window = grabWindow;
+ widgetToGetEvent = mac_mouse_grabber;
+ fakeNCEvents = true;
+ }
+ }
+ // Dont generate normal NC mouse events for Left Button dragged
+ if(evtType != NSLeftMouseDragged || fakeNCEvents) {
+ NSPoint windowPoint = [event locationInWindow];
+ NSPoint globalPoint = [[event window] convertBaseToScreen:windowPoint];
+ NSRect frameRect = [window frame];
+ if (fakeNCEvents || NSMouseInRect(globalPoint, frameRect, NO)) {
+ NSRect contentRect = [window contentRectForFrameRect:frameRect];
+ qglobalPoint = QPoint(flipPoint(globalPoint).toPoint());
+ QWidget *w = widgetToGetEvent->childAt(widgetToGetEvent->mapFromGlobal(qglobalPoint));
+ // check that the mouse pointer is on the non-client area and
+ // there are not widgets in it.
+ if (fakeNCEvents || (!NSMouseInRect(globalPoint, contentRect, NO) && !w)) {
+ qglobalPoint = QPoint(flipPoint(globalPoint).toPoint());
+ qlocalPoint = widgetToGetEvent->mapFromGlobal(qglobalPoint);
+ processThisEvent = true;
+ }
+ }
+ }
+ }
+ // This is not an NC area mouse message.
+ if (!processThisEvent)
+ return;
+
+ // If the window is frame less, generate fake mouse events instead. (floating QToolBar)
+ // or if someone already got an explicit or implicit grab
+ if (mac_mouse_grabber || qt_button_down ||
+ (fakeNCEvents && (widgetToGetEvent->window()->windowFlags() & Qt::FramelessWindowHint)))
+ fakeMouseEvents = true;
+
+ Qt::MouseButton button;
+ QEvent::Type eventType;
+ // Convert to Qt::Event type
+ switch (evtType) {
+ case NSLeftMouseDown:
+ button = Qt::LeftButton;
+ eventType = (!fakeMouseEvents) ? QEvent::NonClientAreaMouseButtonPress
+ : QEvent::MouseButtonPress;
+ break;
+ case NSLeftMouseUp:
+ button = Qt::LeftButton;
+ eventType = (!fakeMouseEvents) ? QEvent::NonClientAreaMouseButtonRelease
+ : QEvent::MouseButtonRelease;
+ break;
+ case NSRightMouseDown:
+ button = Qt::RightButton;
+ eventType = (!fakeMouseEvents) ? QEvent::NonClientAreaMouseButtonPress
+ : QEvent::MouseButtonPress;
+ break;
+ case NSRightMouseUp:
+ button = Qt::RightButton;
+ eventType = (!fakeMouseEvents) ? QEvent::NonClientAreaMouseButtonRelease
+ : QEvent::MouseButtonRelease;
+ break;
+ case NSOtherMouseDown:
+ button = cocoaButton2QtButton([event buttonNumber]);
+ eventType = (!fakeMouseEvents) ? QEvent::NonClientAreaMouseButtonPress
+ : QEvent::MouseButtonPress;
+ break;
+ case NSOtherMouseUp:
+ button = cocoaButton2QtButton([event buttonNumber]);
+ eventType = (!fakeMouseEvents) ? QEvent::NonClientAreaMouseButtonRelease
+ : QEvent::MouseButtonRelease;
+ break;
+ case NSMouseMoved:
+ button = Qt::NoButton;
+ eventType = (!fakeMouseEvents) ? QEvent::NonClientAreaMouseMove
+ : QEvent::MouseMove;
+ break;
+ case NSLeftMouseDragged:
+ button = Qt::LeftButton;
+ eventType = (!fakeMouseEvents) ? QEvent::NonClientAreaMouseMove
+ : QEvent::MouseMove;
+ break;
+ case NSRightMouseDragged:
+ button = Qt::RightButton;
+ eventType = (!fakeMouseEvents) ? QEvent::NonClientAreaMouseMove
+ : QEvent::MouseMove;
+ break;
+ case NSOtherMouseDragged:
+ button = cocoaButton2QtButton([event buttonNumber]);
+ eventType = (!fakeMouseEvents) ? QEvent::NonClientAreaMouseMove
+ : QEvent::MouseMove;
+ break;
+ default:
+ qWarning("not handled! Non client area mouse message");
+ return;
+ }
+
+ Qt::KeyboardModifiers keyMods = qt_cocoaModifiers2QtModifiers([event modifierFlags]);
+ if (eventType == QEvent::NonClientAreaMouseButtonPress || eventType == QEvent::MouseButtonPress) {
+ NSInteger clickCount = [event clickCount];
+ if (clickCount % 2 == 0)
+ eventType = (!fakeMouseEvents) ? QEvent::NonClientAreaMouseButtonDblClick
+ : QEvent::MouseButtonDblClick;
+ if (button == Qt::LeftButton && (keyMods & Qt::MetaModifier)) {
+ button = Qt::RightButton;
+ qt_leftButtonIsRightButton = true;
+ }
+ } else if (eventType == QEvent::NonClientAreaMouseButtonRelease || eventType == QEvent::MouseButtonRelease) {
+ if (button == Qt::LeftButton && qt_leftButtonIsRightButton) {
+ button = Qt::RightButton;
+ qt_leftButtonIsRightButton = false;
+ }
+ }
+
+ Qt::MouseButtons buttons = 0;
+ {
+ UInt32 mac_buttons;
+ if (GetEventParameter((EventRef)[event eventRef], kEventParamMouseChord, typeUInt32, 0,
+ sizeof(mac_buttons), 0, &mac_buttons) == noErr)
+ buttons = qt_mac_get_buttons(mac_buttons);
+ }
+
+ QMouseEvent qme(eventType, qlocalPoint, qglobalPoint, button, buttons, keyMods);
+ qt_sendSpontaneousEvent(widgetToGetEvent, &qme);
+
+ // We don't need to set the implicit grab widget here because we won't
+ // reach this point if then event type is Press over a Qt widget.
+ // However we might need to unset it if the event is Release.
+ if (eventType == QEvent::MouseButtonRelease)
+ qt_button_down = 0;
+}
+
+QWidget *qt_mac_getTargetForKeyEvent(QWidget *widgetThatReceivedEvent)
+{
+ if (QWidget *popup = QApplication::activePopupWidget()) {
+ QWidget *focusInPopup = popup->focusWidget();
+ return focusInPopup ? focusInPopup : popup;
+ }
+
+ QWidget *widgetToGetKey = qApp->focusWidget();
+ if (!widgetToGetKey)
+ widgetToGetKey = widgetThatReceivedEvent;
+
+ return widgetToGetKey;
+}
+
+// This function will find the widget that should receive the
+// mouse event. Because of explicit/implicit mouse grabs, popups,
+// etc, this might not end up being the same as the widget under
+// the mouse (which is more interresting when handling enter/leave
+// events
+QWidget *qt_mac_getTargetForMouseEvent(
+ // You can call this function without providing an event.
+ NSEvent *event,
+ QEvent::Type eventType,
+ QPoint &returnLocalPoint,
+ QPoint &returnGlobalPoint,
+ QWidget *nativeWidget,
+ QWidget **returnWidgetUnderMouse)
+{
+ Q_UNUSED(event);
+ NSPoint nsglobalpoint = event ? [[event window] convertBaseToScreen:[event locationInWindow]] : [NSEvent mouseLocation];
+ returnGlobalPoint = flipPoint(nsglobalpoint).toPoint();
+ QWidget *mouseGrabber = QWidget::mouseGrabber();
+ bool buttonDownNotBlockedByModal = qt_button_down && !QApplicationPrivate::isBlockedByModal(qt_button_down);
+ QWidget *popup = QApplication::activePopupWidget();
+
+ // Resolve the widget under the mouse:
+ QWidget *widgetUnderMouse = 0;
+ if (popup || qt_button_down || !nativeWidget || !nativeWidget->isVisible()) {
+ // Using QApplication::widgetAt for finding the widget under the mouse
+ // is most safe, since it ignores cocoas own mouse down redirections (which
+ // we need to be prepared for when using nativeWidget as starting point).
+ // (the only exception is for QMacNativeWidget, where QApplication::widgetAt fails).
+ // But it is also slower (I guess), so we try to avoid it and use nativeWidget if we can:
+ widgetUnderMouse = QApplication::widgetAt(returnGlobalPoint);
+ }
+
+ if (!widgetUnderMouse && nativeWidget) {
+ // Entering here should be the common case. We
+ // also handle the QMacNativeWidget fallback case.
+ QPoint p = nativeWidget->mapFromGlobal(returnGlobalPoint);
+ widgetUnderMouse = nativeWidget->childAt(p);
+ if (!widgetUnderMouse && nativeWidget->rect().contains(p))
+ widgetUnderMouse = nativeWidget;
+ }
+
+ if (widgetUnderMouse) {
+ // Check if widgetUnderMouse is blocked by a modal
+ // window, or the mouse if over the frame strut:
+ if (widgetUnderMouse == qt_button_down) {
+ // Small optimization to avoid an extra call to isBlockedByModal:
+ if (buttonDownNotBlockedByModal == false)
+ widgetUnderMouse = 0;
+ } else if (QApplicationPrivate::isBlockedByModal(widgetUnderMouse)) {
+ widgetUnderMouse = 0;
+ }
+
+ if (widgetUnderMouse && widgetUnderMouse->isWindow()) {
+ // Exclude the titlebar (and frame strut) when finding widget under mouse:
+ QPoint p = widgetUnderMouse->mapFromGlobal(returnGlobalPoint);
+ if (!widgetUnderMouse->rect().contains(p))
+ widgetUnderMouse = 0;
+ }
+ }
+ if (returnWidgetUnderMouse)
+ *returnWidgetUnderMouse = widgetUnderMouse;
+
+ // Resolve the target for the mouse event. Default will be
+ // widgetUnderMouse, except if there is a grab (popup/mouse/button-down):
+ if (popup && !mouseGrabber) {
+ // We special case handling of popups, since they have an implicitt mouse grab.
+ QWidget *candidate = buttonDownNotBlockedByModal ? qt_button_down : widgetUnderMouse;
+ if (!popup->isAncestorOf(candidate)) {
+ // INVARIANT: we have a popup, but the candidate is not
+ // in it. But the popup will grab the mouse anyway,
+ // except if the user scrolls:
+ if (eventType == QEvent::Wheel)
+ return 0;
+ returnLocalPoint = popup->mapFromGlobal(returnGlobalPoint);
+ return popup;
+ } else if (popup == candidate) {
+ // INVARIANT: The candidate is the popup itself, and not a child:
+ returnLocalPoint = popup->mapFromGlobal(returnGlobalPoint);
+ return popup;
+ } else {
+ // INVARIANT: The candidate is a child inside the popup:
+ returnLocalPoint = candidate->mapFromGlobal(returnGlobalPoint);
+ return candidate;
+ }
+ }
+
+ QWidget *target = mouseGrabber;
+ if (!target && buttonDownNotBlockedByModal)
+ target = qt_button_down;
+ if (!target)
+ target = widgetUnderMouse;
+ if (!target)
+ return 0;
+
+ returnLocalPoint = target->mapFromGlobal(returnGlobalPoint);
+ return target;
+}
+
+QPointer<QWidget> qt_last_native_mouse_receiver = 0;
+
+static inline void qt_mac_checkEnterLeaveForNativeWidgets(QWidget *maybeEnterWidget)
+{
+ // Dispatch enter/leave for the cases where QApplicationPrivate::sendMouseEvent do
+ // not. This will in general be the cases when alien widgets are not involved:
+ // 1. from a native widget to another native widget or
+ // 2. from a native widget to no widget
+ // 3. from no widget to a native or alien widget
+
+ if (qt_button_down || QWidget::mouseGrabber())
+ return;
+
+ if ((maybeEnterWidget == qt_last_native_mouse_receiver) && qt_last_native_mouse_receiver)
+ return;
+ if (maybeEnterWidget) {
+ if (!qt_last_native_mouse_receiver) {
+ // case 3
+ QApplicationPrivate::dispatchEnterLeave(maybeEnterWidget, 0);
+ qt_last_native_mouse_receiver = maybeEnterWidget->internalWinId() ? maybeEnterWidget : maybeEnterWidget->nativeParentWidget();
+ } else if (maybeEnterWidget->internalWinId()) {
+ // case 1
+ QApplicationPrivate::dispatchEnterLeave(maybeEnterWidget, qt_last_native_mouse_receiver);
+ qt_last_native_mouse_receiver = maybeEnterWidget->internalWinId() ? maybeEnterWidget : maybeEnterWidget->nativeParentWidget();
+ } // else at lest one of the widgets are alien, so enter/leave will be handled in QApplicationPrivate
+ } else {
+ if (qt_last_native_mouse_receiver) {
+ // case 2
+ QApplicationPrivate::dispatchEnterLeave(0, qt_last_native_mouse_receiver);
+ qt_last_mouse_receiver = 0;
+ qt_last_native_mouse_receiver = 0;
+ }
+ }
+}
+
+bool qt_mac_handleMouseEvent(NSEvent *event, QEvent::Type eventType, Qt::MouseButton button, QWidget *nativeWidget)
+{
+ // Give the Input Manager a chance to process the mouse events.
+ NSInputManager *currentIManager = [NSInputManager currentInputManager];
+ if (currentIManager && [currentIManager wantsToHandleMouseEvents]) {
+ [currentIManager handleMouseEvent:event];
+ }
+
+ // Find the widget that should receive the event, and the widget under the mouse. Those
+ // can differ if an implicit or explicit mouse grab is active:
+ QWidget *widgetUnderMouse = 0;
+ QPoint localPoint, globalPoint;
+ QWidget *widgetToGetMouse = qt_mac_getTargetForMouseEvent(event, eventType, localPoint, globalPoint, nativeWidget, &widgetUnderMouse);
+ if (!widgetToGetMouse)
+ return false;
+
+ // From here on, we let nativeWidget actually be the native widget under widgetUnderMouse. The reason
+ // for this, is that qt_mac_getTargetForMouseEvent will set cocoa's mouse event redirection aside when
+ // determining which widget is under the mouse (in other words, it will usually ignore nativeWidget).
+ // nativeWidget will be used in QApplicationPrivate::sendMouseEvent to correctly dispatch enter/leave events.
+ if (widgetUnderMouse)
+ nativeWidget = widgetUnderMouse->internalWinId() ? widgetUnderMouse : widgetUnderMouse->nativeParentWidget();
+ if (!nativeWidget)
+ return false;
+ NSView *view = qt_mac_effectiveview_for(nativeWidget);
+
+ // Handle tablet events (if any) first.
+ if (qt_mac_handleTabletEvent(view, event)) {
+ // Tablet event was handled. In Qt we aren't supposed to send the mouse event.
+ return true;
+ }
+
+ EventRef carbonEvent = static_cast<EventRef>(const_cast<void *>([event eventRef]));
+ if (qt_mac_sendMacEventToWidget(widgetToGetMouse, carbonEvent))
+ return true;
+
+ // Keep previousButton to make sure we don't send double click
+ // events when the user double clicks using two different buttons:
+ static Qt::MouseButton previousButton = Qt::NoButton;
+
+ Qt::KeyboardModifiers keyMods = qt_cocoaModifiers2QtModifiers([event modifierFlags]);
+ NSInteger clickCount = [event clickCount];
+ Qt::MouseButtons buttons = 0;
+ {
+ UInt32 mac_buttons;
+ if (GetEventParameter(carbonEvent, kEventParamMouseChord, typeUInt32, 0,
+ sizeof(mac_buttons), 0, &mac_buttons) == noErr)
+ buttons = qt_mac_get_buttons(mac_buttons);
+ }
+
+ // Send enter/leave events for the cases when QApplicationPrivate::sendMouseEvent do not:
+ qt_mac_checkEnterLeaveForNativeWidgets(widgetUnderMouse);
+
+ switch (eventType) {
+ default:
+ qWarning("not handled! %d", eventType);
+ break;
+ case QEvent::MouseMove:
+ if (button == Qt::LeftButton && qt_leftButtonIsRightButton)
+ button = Qt::RightButton;
+ break;
+ case QEvent::MouseButtonPress:
+ qt_button_down = widgetUnderMouse;
+ if (clickCount % 2 == 0 && (previousButton == Qt::NoButton || previousButton == button))
+ eventType = QEvent::MouseButtonDblClick;
+ if (button == Qt::LeftButton && (keyMods & Qt::MetaModifier)) {
+ button = Qt::RightButton;
+ qt_leftButtonIsRightButton = true;
+ }
+ break;
+ case QEvent::MouseButtonRelease:
+ if (button == Qt::LeftButton && qt_leftButtonIsRightButton) {
+ button = Qt::RightButton;
+ qt_leftButtonIsRightButton = false;
+ }
+ qt_button_down = 0;
+ break;
+ }
+
+ qt_mac_updateCursorWithWidgetUnderMouse(widgetUnderMouse);
+
+ DnDParams *dndParams = currentDnDParameters();
+ dndParams->view = view;
+ dndParams->theEvent = event;
+ dndParams->globalPoint = globalPoint;
+
+ // Send the mouse event:
+ QMouseEvent qme(eventType, localPoint, globalPoint, button, buttons, keyMods);
+ QApplicationPrivate::sendMouseEvent(
+ widgetToGetMouse, &qme, widgetUnderMouse, nativeWidget,
+ &qt_button_down, qt_last_mouse_receiver, true);
+
+ if (eventType == QEvent::MouseButtonPress && button == Qt::RightButton) {
+ QContextMenuEvent qcme(QContextMenuEvent::Mouse, localPoint, globalPoint, keyMods);
+ qt_sendSpontaneousEvent(widgetToGetMouse, &qcme);
+ }
+
+ if (eventType == QEvent::MouseButtonRelease) {
+ // A mouse button was released, which means that the implicit grab was
+ // released. We therefore need to re-check if should send (delayed) enter leave events:
+ // qt_button_down has now become NULL since the call at the top of the function. Also, since
+ // the relase might have closed a window, we dont give the nativeWidget hint
+ qt_mac_getTargetForMouseEvent(0, QEvent::None, localPoint, globalPoint, nativeWidget, &widgetUnderMouse);
+ qt_mac_checkEnterLeaveForNativeWidgets(widgetUnderMouse);
+ }
+
+ previousButton = button;
+ return true;
+}
+#endif
+
+bool qt_mac_handleTabletEvent(void * /*QCocoaView * */view, void * /*NSEvent * */tabletEvent)
+{
+#ifndef QT_MAC_USE_COCOA
+ Q_UNUSED(view);
+ Q_UNUSED(tabletEvent);
+ return false;
+#else
+ QT_MANGLE_NAMESPACE(QCocoaView) *theView = static_cast<QT_MANGLE_NAMESPACE(QCocoaView) *>(view);
+ NSView *theNSView = static_cast<NSView *>(view);
+ NSEvent *theTabletEvent = static_cast<NSEvent *>(tabletEvent);
+
+ NSEventType eventType = [theTabletEvent type];
+ if (eventType != NSTabletPoint && [theTabletEvent subtype] != NSTabletPointEventSubtype)
+ return false; // Not a tablet event.
+
+ NSPoint windowPoint = [theTabletEvent locationInWindow];
+ NSPoint globalPoint = [[theTabletEvent window] convertBaseToScreen:windowPoint];
+
+ QWidget *qwidget = [theView qt_qwidget];
+ QWidget *widgetToGetMouse = qwidget;
+ QWidget *popup = qAppInstance()->activePopupWidget();
+ if (popup && popup != qwidget->window())
+ widgetToGetMouse = popup;
+
+ if (qt_mac_sendMacEventToWidget(widgetToGetMouse,
+ static_cast<EventRef>(const_cast<void *>([theTabletEvent eventRef]))))
+ return true;
+ if (widgetToGetMouse != qwidget) {
+ theNSView = qt_mac_nativeview_for(widgetToGetMouse);
+ windowPoint = [[theNSView window] convertScreenToBase:globalPoint];
+ }
+ NSPoint localPoint = [theNSView convertPoint:windowPoint fromView:nil];
+ // Tablet events do not handle WA_TransparentForMouseEvents ATM
+ // In theory, people who set the WA_TransparentForMouseEvents attribute won't handle
+ // tablet events either in which case they will fall into the mouse event case and get
+ // them passed on. This will NOT handle the raw events, but that might not be a big problem.
+
+ const QMacTabletHash *tabletHash = qt_mac_tablet_hash();
+ if (!tabletHash->contains([theTabletEvent deviceID])) {
+ qWarning("QCocoaView handleTabletEvent: This tablet device is unknown"
+ " (received no proximity event for it). Discarding event.");
+ return false;
+ }
+ const QTabletDeviceData &deviceData = tabletHash->value([theTabletEvent deviceID]);
+
+
+ QEvent::Type qType;
+ switch (eventType) {
+ case NSLeftMouseDown:
+ case NSRightMouseDown:
+ qType = QEvent::TabletPress;
+ break;
+ case NSLeftMouseUp:
+ case NSRightMouseUp:
+ qType = QEvent::TabletRelease;
+ break;
+ case NSMouseMoved:
+ case NSTabletPoint:
+ case NSLeftMouseDragged:
+ case NSRightMouseDragged:
+ default:
+ qType = QEvent::TabletMove;
+ break;
+ }
+
+ qreal pressure;
+ if (eventType != NSMouseMoved) {
+ pressure = [theTabletEvent pressure];
+ } else {
+ pressure = 0.0;
+ }
+
+ NSPoint tilt = [theTabletEvent tilt];
+ int xTilt = qRound(tilt.x * 60.0);
+ int yTilt = qRound(tilt.y * -60.0);
+ qreal tangentialPressure = 0;
+ qreal rotation = 0;
+ int z = 0;
+ if (deviceData.capabilityMask & 0x0200)
+ z = [theTabletEvent absoluteZ];
+
+ if (deviceData.capabilityMask & 0x0800)
+ tangentialPressure = [theTabletEvent tangentialPressure];
+
+ rotation = [theTabletEvent rotation];
+ QPointF hiRes = flipPoint(globalPoint);
+ QTabletEvent qtabletEvent(qType, QPoint(localPoint.x, localPoint.y),
+ hiRes.toPoint(), hiRes,
+ deviceData.tabletDeviceType, deviceData.tabletPointerType,
+ pressure, xTilt, yTilt, tangentialPressure, rotation, z,
+ qt_cocoaModifiers2QtModifiers([theTabletEvent modifierFlags]),
+ deviceData.tabletUniqueID);
+
+ qt_sendSpontaneousEvent(widgetToGetMouse, &qtabletEvent);
+ return qtabletEvent.isAccepted();
+#endif
+}
+
+void qt_mac_updateContentBorderMetricts(void * /*OSWindowRef */window, const ::HIContentBorderMetrics &metrics)
+{
+ OSWindowRef theWindow = static_cast<OSWindowRef>(window);
+#if !defined(QT_MAC_USE_COCOA)
+# if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) {
+ ::HIWindowSetContentBorderThickness(theWindow, &metrics);
+ }
+# else
+ Q_UNUSED(window);
+ Q_UNUSED(metrics);
+# endif
+#else
+ if ([theWindow styleMask] & NSTexturedBackgroundWindowMask)
+ [theWindow setContentBorderThickness:metrics.top forEdge:NSMaxYEdge];
+ [theWindow setContentBorderThickness:metrics.bottom forEdge:NSMinYEdge];
+#endif
+}
+
+#if QT_MAC_USE_COCOA
+void qt_mac_replaceDrawRect(void * /*OSWindowRef */window, QWidgetPrivate *widget)
+{
+ QMacCocoaAutoReleasePool pool;
+ OSWindowRef theWindow = static_cast<OSWindowRef>(window);
+ if(!theWindow)
+ return;
+ id theClass = [[[theWindow contentView] superview] class];
+ // What we do here is basically to add a new selector to NSThemeFrame called
+ // "drawRectOriginal:" which will contain the original implementation of
+ // "drawRect:". After that we get the new implementation from QCocoaWindow
+ // and exchange them. The new implementation is called drawRectSpecial.
+ // We cannot just add the method because it might have been added before and since
+ // we cannot remove a method once it has been added we need to ask QCocoaWindow if
+ // we did the swap or not.
+ if(!widget->drawRectOriginalAdded) {
+ Method m2 = class_getInstanceMethod(theClass, @selector(drawRect:));
+ if(!m2) {
+ // This case is pretty extreme, no drawRect means no drawing!
+ return;
+ }
+ class_addMethod(theClass, @selector(drawRectOriginal:), method_getImplementation(m2), method_getTypeEncoding(m2));
+ widget->drawRectOriginalAdded = true;
+ }
+ if(widget->originalDrawMethod) {
+ Method m0 = class_getInstanceMethod([theWindow class], @selector(drawRectSpecial:));
+ if(!m0) {
+ // Ok, this means the methods were never swapped. Just ignore
+ return;
+ }
+ Method m1 = class_getInstanceMethod(theClass, @selector(drawRect:));
+ if(!m1) {
+ // Ok, this means the methods were never swapped. Just ignore
+ return;
+ }
+ // We have the original method here. Proceed and swap the methods.
+ method_exchangeImplementations(m1, m0);
+ widget->originalDrawMethod = false;
+ [theWindow display];
+ }
+}
+
+void qt_mac_replaceDrawRectOriginal(void * /*OSWindowRef */window, QWidgetPrivate *widget)
+{
+ QMacCocoaAutoReleasePool pool;
+ OSWindowRef theWindow = static_cast<OSWindowRef>(window);
+ id theClass = [[[theWindow contentView] superview] class];
+ // Now we need to revert the methods to their original state.
+ // We cannot remove the method, so we just keep track of it in QCocoaWindow.
+ Method m0 = class_getInstanceMethod([theWindow class], @selector(drawRectSpecial:));
+ if(!m0) {
+ // Ok, this means the methods were never swapped. Just ignore
+ return;
+ }
+ Method m1 = class_getInstanceMethod(theClass, @selector(drawRect:));
+ if(!m1) {
+ // Ok, this means the methods were never swapped. Just ignore
+ return;
+ }
+ method_exchangeImplementations(m1, m0);
+ widget->originalDrawMethod = true;
+ [theWindow display];
+}
+#endif // QT_MAC_USE_COCOA
+
+#if QT_MAC_USE_COCOA
+void qt_mac_showBaseLineSeparator(void * /*OSWindowRef */window, bool show)
+{
+ if(!window)
+ return;
+ QMacCocoaAutoReleasePool pool;
+ OSWindowRef theWindow = static_cast<OSWindowRef>(window);
+ NSToolbar *macToolbar = [theWindow toolbar];
+ [macToolbar setShowsBaselineSeparator:show];
+}
+#endif // QT_MAC_USE_COCOA
+
+QStringList qt_mac_NSArrayToQStringList(void *nsarray)
+{
+ QStringList result;
+ NSArray *array = static_cast<NSArray *>(nsarray);
+ for (NSUInteger i=0; i<[array count]; ++i)
+ result << qt_mac_NSStringToQString([array objectAtIndex:i]);
+ return result;
+}
+
+void *qt_mac_QStringListToNSMutableArrayVoid(const QStringList &list)
+{
+ NSMutableArray *result = [NSMutableArray arrayWithCapacity:list.size()];
+ for (int i=0; i<list.size(); ++i){
+ [result addObject:reinterpret_cast<const NSString *>(QCFString::toCFStringRef(list[i]))];
+ }
+ return result;
+}
+
+#if QT_MAC_USE_COCOA
+void qt_syncCocoaTitleBarButtons(OSWindowRef window, QWidget *widgetForWindow)
+{
+ if (!widgetForWindow)
+ return;
+
+ Qt::WindowFlags flags = widgetForWindow->windowFlags();
+ bool customize = flags & Qt::CustomizeWindowHint;
+
+ NSButton *btn = [window standardWindowButton:NSWindowZoomButton];
+ // BOOL is not an int, so the bitwise AND doesn't work.
+ bool go = uint(customize && !(flags & Qt::WindowMaximizeButtonHint)) == 0;
+ [btn setEnabled:go];
+
+ btn = [window standardWindowButton:NSWindowMiniaturizeButton];
+ go = uint(customize && !(flags & Qt::WindowMinimizeButtonHint)) == 0;
+ [btn setEnabled:go];
+
+ btn = [window standardWindowButton:NSWindowCloseButton];
+ go = uint(customize && !(flags & Qt::WindowSystemMenuHint
+ || flags & Qt::WindowCloseButtonHint)) == 0;
+ [btn setEnabled:go];
+
+ [window setShowsToolbarButton:uint(flags & Qt::MacWindowToolBarButtonHint) != 0];
+}
+#endif // QT_MAC_USE_COCOA
+
+// Carbon: Make sure you call QDEndContext on the context when done with it.
+CGContextRef qt_mac_graphicsContextFor(QWidget *widget)
+{
+ if (!widget)
+ return 0;
+
+#ifndef QT_MAC_USE_COCOA
+ CGContextRef context;
+ CGrafPtr port = GetWindowPort(qt_mac_window_for(widget));
+ QDBeginCGContext(port, &context);
+#else
+ CGContextRef context = (CGContextRef)[[NSGraphicsContext graphicsContextWithWindow:qt_mac_window_for(widget)] graphicsPort];
+#endif
+ return context;
+}
+
+void qt_mac_dispatchPendingUpdateRequests(QWidget *widget)
+{
+ if (!widget)
+ return;
+#ifndef QT_MAC_USE_COCOA
+ HIViewRender(qt_mac_nativeview_for(widget));
+#else
+ [qt_mac_nativeview_for(widget) displayIfNeeded];
+#endif
+}
+
+CGFloat qt_mac_get_scalefactor()
+{
+#ifndef QT_MAC_USE_COCOA
+ return HIGetScaleFactor();
+#else
+ return [[NSScreen mainScreen] userSpaceScaleFactor];
+#endif
+}
+
+QString qt_mac_get_pasteboardString(OSPasteboardRef paste)
+{
+ QMacCocoaAutoReleasePool pool;
+ NSPasteboard *pb = nil;
+ CFStringRef pbname;
+ if (PasteboardCopyName(paste, &pbname) == noErr) {
+ pb = [NSPasteboard pasteboardWithName:const_cast<NSString *>(reinterpret_cast<const NSString *>(pbname))];
+ CFRelease(pbname);
+ } else {
+ pb = [NSPasteboard generalPasteboard];
+ }
+ if (pb) {
+ NSString *text = [pb stringForType:NSStringPboardType];
+ if (text)
+ return qt_mac_NSStringToQString(text);
+ }
+ return QString();
+}
+
+QPixmap qt_mac_convert_iconref(const IconRef icon, int width, int height)
+{
+ QPixmap ret(width, height);
+ ret.fill(QColor(0, 0, 0, 0));
+
+ CGRect rect = CGRectMake(0, 0, width, height);
+
+ CGContextRef ctx = qt_mac_cg_context(&ret);
+ CGAffineTransform old_xform = CGContextGetCTM(ctx);
+ CGContextConcatCTM(ctx, CGAffineTransformInvert(old_xform));
+ CGContextConcatCTM(ctx, CGAffineTransformIdentity);
+
+ ::RGBColor b;
+ b.blue = b.green = b.red = 255*255;
+ PlotIconRefInContext(ctx, &rect, kAlignNone, kTransformNone, &b, kPlotIconRefNormalFlags, icon);
+ CGContextRelease(ctx);
+ return ret;
+}
+
+void qt_mac_constructQIconFromIconRef(const IconRef icon, const IconRef overlayIcon, QIcon *retIcon, QStyle::StandardPixmap standardIcon)
+{
+ int size = 16;
+ while (size <= 128) {
+
+ const QString cacheKey = QLatin1String("qt_mac_constructQIconFromIconRef") + QString::number(standardIcon) + QString::number(size);
+ QPixmap mainIcon;
+ if (standardIcon >= QStyle::SP_CustomBase) {
+ mainIcon = qt_mac_convert_iconref(icon, size, size);
+ } else if (QPixmapCache::find(cacheKey, mainIcon) == false) {
+ mainIcon = qt_mac_convert_iconref(icon, size, size);
+ QPixmapCache::insert(cacheKey, mainIcon);
+ }
+
+ if (overlayIcon) {
+ int littleSize = size / 2;
+ QPixmap overlayPix = qt_mac_convert_iconref(overlayIcon, littleSize, littleSize);
+ QPainter painter(&mainIcon);
+ painter.drawPixmap(size - littleSize, size - littleSize, overlayPix);
+ }
+
+ retIcon->addPixmap(mainIcon);
+ size += size; // 16 -> 32 -> 64 -> 128
+ }
+}
+
+void qt_mac_post_retranslateAppMenu()
+{
+#ifdef QT_MAC_USE_COCOA
+ QMacCocoaAutoReleasePool pool;
+ qt_cocoaPostMessage([NSApp QT_MANGLE_NAMESPACE(qt_qcocoamenuLoader)], @selector(qtTranslateApplicationMenu));
+#endif
+}
+
+QWidgetPrivate *QMacScrollOptimization::_target = 0;
+bool QMacScrollOptimization::_inWheelEvent = false;
+int QMacScrollOptimization::_dx = 0;
+int QMacScrollOptimization::_dy = 0;
+QRect QMacScrollOptimization::_scrollRect = QRect(0, 0, -1, -1);
+
+#ifdef QT_MAC_USE_COCOA
+// This method implements the magic for the drawRectSpecial method.
+// We draw a line at the upper edge of the content view in order to
+// override the title baseline.
+void macDrawRectOnTop(void * /*OSWindowRef */window)
+{
+ OSWindowRef theWindow = static_cast<OSWindowRef>(window);
+ NSView *contentView = [theWindow contentView];
+ if(!contentView)
+ return;
+ // Get coordinates of the content view
+ NSRect contentRect = [contentView frame];
+ // Draw a line on top of the already drawn line.
+ // We need to check if we are active or not to use the proper color.
+ if([theWindow isKeyWindow] || [theWindow isMainWindow]) {
+ [[NSColor colorWithCalibratedRed:1.0 green:1.0 blue:1.0 alpha:1.0] set];
+ } else {
+ [[NSColor colorWithCalibratedRed:1.0 green:1.0 blue:1.0 alpha:1.0] set];
+ }
+ NSPoint origin = NSMakePoint(0, contentRect.size.height);
+ NSPoint end = NSMakePoint(contentRect.size.width, contentRect.size.height);
+ [NSBezierPath strokeLineFromPoint:origin toPoint:end];
+}
+
+// This method will (or at least should) get called only once.
+// Its mission is to find out if we are active or not. If we are active
+// we assume that we were launched via finder, otherwise we assume
+// we were called from the command line. The distinction is important,
+// since in the first case we don't need to trigger a paintEvent, while
+// in the second case we do.
+void macSyncDrawingOnFirstInvocation(void * /*OSWindowRef */window)
+{
+ OSWindowRef theWindow = static_cast<OSWindowRef>(window);
+ NSApplication *application = [NSApplication sharedApplication];
+ NSToolbar *toolbar = [theWindow toolbar];
+ if([application isActive]) {
+ // Launched from finder
+ [toolbar setShowsBaselineSeparator:NO];
+ } else {
+ // Launched from commandline
+ [toolbar setVisible:false];
+ [toolbar setShowsBaselineSeparator:NO];
+ [toolbar setVisible:true];
+ [theWindow display];
+ }
+}
+
+void qt_cocoaStackChildWindowOnTopOfOtherChildren(QWidget *childWidget)
+{
+ if (!childWidget)
+ return;
+
+ QWidget *parent = childWidget->parentWidget();
+ if (childWidget->isWindow() && parent) {
+ if ([[qt_mac_window_for(parent) childWindows] containsObject:qt_mac_window_for(childWidget)]) {
+ QWidgetPrivate *d = qt_widget_private(childWidget);
+ d->setSubWindowStacking(false);
+ d->setSubWindowStacking(true);
+ }
+ }
+}
+
+void qt_mac_display(QWidget *widget)
+{
+ NSView *theNSView = qt_mac_nativeview_for(widget);
+ [theNSView display];
+}
+
+void qt_mac_setNeedsDisplay(QWidget *widget)
+{
+ NSView *theNSView = qt_mac_nativeview_for(widget);
+ [theNSView setNeedsDisplay:YES];
+}
+
+void qt_mac_setNeedsDisplayInRect(QWidget *widget, QRegion region)
+{
+ NSView *theNSView = qt_mac_nativeview_for(widget);
+ if (region.isEmpty()) {
+ [theNSView setNeedsDisplay:YES];
+ return;
+ }
+
+ QVector<QRect> rects = region.rects();
+ for (int i = 0; i < rects.count(); ++i) {
+ const QRect &rect = rects.at(i);
+ NSRect nsrect = NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height());
+ [theNSView setNeedsDisplayInRect:nsrect];
+ }
+
+}
+
+#endif // QT_MAC_USE_COCOA
+
+QT_END_NAMESPACE
diff --git a/src/widgets/platforms/mac/qt_cocoa_helpers_mac_p.h b/src/widgets/platforms/mac/qt_cocoa_helpers_mac_p.h
new file mode 100644
index 0000000000..b46946c121
--- /dev/null
+++ b/src/widgets/platforms/mac/qt_cocoa_helpers_mac_p.h
@@ -0,0 +1,310 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/****************************************************************************
+**
+** Copyright (c) 2007-2008, Apple, Inc.
+**
+** All rights reserved.
+**
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are met:
+**
+** * Redistributions of source code must retain the above copyright notice,
+** this list of conditions and the following disclaimer.
+**
+** * Redistributions in binary form must reproduce the above copyright notice,
+** this list of conditions and the following disclaimer in the documentation
+** and/or other materials provided with the distribution.
+**
+** * Neither the name of Apple, Inc. nor the names of its contributors
+** may be used to endorse or promote products derived from this software
+** without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+**
+****************************************************************************/
+
+#ifndef QT_COCOA_HELPERS_MAC_P_H
+#define QT_COCOA_HELPERS_MAC_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of qapplication_*.cpp, qwidget*.cpp, qcolor_x11.cpp, qfiledialog.cpp
+// and many other. This header file may change from version to version
+// without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <private/qt_mac_p.h>
+
+#include <qapplication.h>
+#include <qdesktopwidget.h>
+#include <qwidget.h>
+#include <qevent.h>
+#include <qhash.h>
+#include <qlabel.h>
+#include <qpointer.h>
+#include <qstyle.h>
+#include <qstyleoption.h>
+#include <qstylepainter.h>
+#include <qtimer.h>
+#include <qtooltip.h>
+#include <private/qeffects_p.h>
+#include <private/qwidget_p.h>
+#include <qtextdocument.h>
+#include <qdebug.h>
+#include <qpoint.h>
+#include "private/qt_mac_p.h"
+
+struct HIContentBorderMetrics;
+
+#ifdef __OBJC__
+ // If the source file including this file also includes e.g. Cocoa/Cocoa.h, typedef-ing NSPoint will
+ // fail since NSPoint will already be a type. So we try to detect this. If the build fails, ensure
+ // that the inclusion of cocoa headers happends before the inclusion of this file.
+ #include <Foundation/NSGeometry.h>
+#else
+ #ifdef Q_WS_MAC32
+ typedef struct _NSPoint NSPoint; // Just redefine here so I don't have to pull in all of Cocoa.
+ #else
+ typedef struct CGPoint NSPoint;
+ #endif
+#endif
+
+QT_BEGIN_NAMESPACE
+
+Qt::MouseButtons qt_mac_get_buttons(int buttons);
+Qt::MouseButton qt_mac_get_button(EventMouseButton button);
+void macWindowFade(void * /*OSWindowRef*/ window, float durationSeconds = 0.15);
+bool macWindowIsTextured(void * /*OSWindowRef*/ window);
+void macWindowToolbarShow(const QWidget *widget, bool show );
+void macWindowToolbarSet( void * /*OSWindowRef*/ window, void* toolbarRef );
+bool macWindowToolbarIsVisible( void * /*OSWindowRef*/ window );
+void macWindowSetHasShadow( void * /*OSWindowRef*/ window, bool hasShadow );
+void macWindowFlush(void * /*OSWindowRef*/ window);
+void macSendToolbarChangeEvent(QWidget *widget);
+void qt_mac_updateContentBorderMetricts(void * /*OSWindowRef */window, const ::HIContentBorderMetrics &metrics);
+void qt_mac_replaceDrawRect(void * /*OSWindowRef */window, QWidgetPrivate *widget);
+void qt_mac_replaceDrawRectOriginal(void * /*OSWindowRef */window, QWidgetPrivate *widget);
+void qt_mac_showBaseLineSeparator(void * /*OSWindowRef */window, bool show);
+void * /*NSImage */qt_mac_create_nsimage(const QPixmap &pm);
+void qt_mac_update_mouseTracking(QWidget *widget);
+OSStatus qt_mac_drawCGImage(CGContextRef cg, const CGRect *inbounds, CGImageRef);
+bool qt_mac_checkForNativeSizeGrip(const QWidget *widget);
+void qt_dispatchTabletProximityEvent(void * /*NSEvent * */ tabletEvent);
+bool qt_dispatchKeyEventWithCocoa(void * /*NSEvent * */ keyEvent, QWidget *widgetToGetEvent);
+// These methods exists only for supporting unified mode.
+void macDrawRectOnTop(void * /*OSWindowRef */ window);
+void macSyncDrawingOnFirstInvocation(void * /*OSWindowRef */window);
+void qt_cocoaStackChildWindowOnTopOfOtherChildren(QWidget *widget);
+bool qt_dispatchKeyEvent(void * /*NSEvent * */ keyEvent, QWidget *widgetToGetEvent);
+void qt_dispatchModifiersChanged(void * /*NSEvent * */flagsChangedEvent, QWidget *widgetToGetEvent);
+bool qt_mac_handleTabletEvent(void * /*QCocoaView * */view, void * /*NSEvent * */event);
+inline QApplication *qAppInstance() { return static_cast<QApplication *>(QCoreApplication::instance()); }
+struct ::TabletProximityRec;
+void qt_dispatchTabletProximityEvent(const ::TabletProximityRec &proxRec);
+Qt::KeyboardModifiers qt_cocoaModifiers2QtModifiers(ulong modifierFlags);
+Qt::KeyboardModifiers qt_cocoaDragOperation2QtModifiers(uint dragOperations);
+QPixmap qt_mac_convert_iconref(const IconRef icon, int width, int height);
+void qt_mac_constructQIconFromIconRef(const IconRef icon, const IconRef overlayIcon, QIcon *retIcon,
+ QStyle::StandardPixmap standardIcon = QStyle::SP_CustomBase);
+
+#ifdef __OBJC__
+struct DnDParams
+{
+ NSView *view;
+ NSEvent *theEvent;
+ QPoint globalPoint;
+ NSDragOperation performedAction;
+};
+
+DnDParams *macCurrentDnDParameters();
+NSDragOperation qt_mac_mapDropAction(Qt::DropAction action);
+NSDragOperation qt_mac_mapDropActions(Qt::DropActions actions);
+Qt::DropAction qt_mac_mapNSDragOperation(NSDragOperation nsActions);
+Qt::DropActions qt_mac_mapNSDragOperations(NSDragOperation nsActions);
+
+QWidget *qt_mac_getTargetForKeyEvent(QWidget *widgetThatReceivedEvent);
+QWidget *qt_mac_getTargetForMouseEvent(NSEvent *event, QEvent::Type eventType,
+ QPoint &returnLocalPoint, QPoint &returnGlobalPoint, QWidget *nativeWidget, QWidget **returnWidgetUnderMouse);
+bool qt_mac_handleMouseEvent(NSEvent *event, QEvent::Type eventType, Qt::MouseButton button, QWidget *nativeWidget);
+void qt_mac_handleNonClientAreaMouseEvent(NSWindow *window, NSEvent *event);
+#endif
+
+inline int flipYCoordinate(int y)
+{
+ return QApplication::desktop()->screenGeometry(0).height() - y;
+}
+
+inline qreal flipYCoordinate(qreal y)
+{
+ return QApplication::desktop()->screenGeometry(0).height() - y;
+}
+
+QPointF flipPoint(const NSPoint &p);
+NSPoint flipPoint(const QPoint &p);
+NSPoint flipPoint(const QPointF &p);
+
+QStringList qt_mac_NSArrayToQStringList(void *nsarray);
+void *qt_mac_QStringListToNSMutableArrayVoid(const QStringList &list);
+
+void qt_syncCocoaTitleBarButtons(OSWindowRef window, QWidget *widgetForWindow);
+
+CGFloat qt_mac_get_scalefactor();
+QString qt_mac_get_pasteboardString(OSPasteboardRef paste);
+
+#ifdef __OBJC__
+inline NSMutableArray *qt_mac_QStringListToNSMutableArray(const QStringList &qstrlist)
+{ return reinterpret_cast<NSMutableArray *>(qt_mac_QStringListToNSMutableArrayVoid(qstrlist)); }
+
+inline QString qt_mac_NSStringToQString(const NSString *nsstr)
+{ return QCFString::toQString(reinterpret_cast<const CFStringRef>(nsstr)); }
+
+inline NSString *qt_mac_QStringToNSString(const QString &qstr)
+{ return [reinterpret_cast<const NSString *>(QCFString::toCFStringRef(qstr)) autorelease]; }
+
+#endif
+
+class QMacScrollOptimization {
+ // This class is made to optimize for the case when the user
+ // scrolls both horizontally and vertically at the same
+ // time. This will result in two QWheelEvents (one for each
+ // direction), which will typically result in two calls to
+ // QWidget::_scroll_sys. Rather than copying pixels twize on
+ // screen because of this, we add this helper class to try to
+ // get away with only one blit.
+ static QWidgetPrivate *_target;
+ static bool _inWheelEvent;
+ static int _dx;
+ static int _dy;
+ static QRect _scrollRect;
+
+public:
+ static void initDelayedScroll()
+ {
+ _inWheelEvent = true;
+ }
+
+ static bool delayScroll(QWidgetPrivate *target, int dx, int dy, const QRect &scrollRect)
+ {
+ if (!_inWheelEvent)
+ return false;
+ if (_target && _target != target)
+ return false;
+ if (_scrollRect.width() != -1 && _scrollRect != scrollRect)
+ return false;
+
+ _target = target;
+ _dx += dx;
+ _dy += dy;
+ _scrollRect = scrollRect;
+ return true;
+ }
+
+ static void performDelayedScroll()
+ {
+ if (!_inWheelEvent)
+ return;
+ _inWheelEvent = false;
+ if (!_target)
+ return;
+
+ _target->scroll_sys(_dx, _dy, _scrollRect);
+
+ _target = 0;
+ _dx = 0;
+ _dy = 0;
+ _scrollRect = QRect(0, 0, -1, -1);
+ }
+};
+
+void qt_mac_post_retranslateAppMenu();
+
+void qt_mac_display(QWidget *widget);
+void qt_mac_setNeedsDisplay(QWidget *widget);
+void qt_mac_setNeedsDisplayInRect(QWidget *widget, QRegion region);
+
+
+// Utility functions to ease the use of Core Graphics contexts.
+
+inline void qt_mac_retain_graphics_context(CGContextRef context)
+{
+ CGContextRetain(context);
+ CGContextSaveGState(context);
+}
+
+inline void qt_mac_release_graphics_context(CGContextRef context)
+{
+ CGContextRestoreGState(context);
+ CGContextRelease(context);
+}
+
+inline void qt_mac_draw_image(CGContextRef context, CGContextRef imageContext, CGRect area, CGRect drawingArea)
+{
+ CGImageRef image = CGBitmapContextCreateImage(imageContext);
+ CGImageRef subImage = CGImageCreateWithImageInRect(image, area);
+
+ CGContextTranslateCTM (context, 0, drawingArea.origin.y + CGRectGetMaxY(drawingArea));
+ CGContextScaleCTM(context, 1, -1);
+ CGContextDrawImage(context, drawingArea, subImage);
+
+ CGImageRelease(subImage);
+ CGImageRelease(image);
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_COCOA_HELPERS_MAC_P_H
diff --git a/src/gui/kernel/qt_mac.cpp b/src/widgets/platforms/mac/qt_mac.cpp
index 339bc82ff5..339bc82ff5 100644
--- a/src/gui/kernel/qt_mac.cpp
+++ b/src/widgets/platforms/mac/qt_mac.cpp
diff --git a/src/widgets/platforms/mac/qt_mac_p.h b/src/widgets/platforms/mac/qt_mac_p.h
new file mode 100644
index 0000000000..80328c3497
--- /dev/null
+++ b/src/widgets/platforms/mac/qt_mac_p.h
@@ -0,0 +1,286 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT_MAC_P_H
+#define QT_MAC_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qmacdefines_mac.h"
+
+#ifdef __OBJC__
+#include <Cocoa/Cocoa.h>
+#ifdef QT_MAC_USE_COCOA
+#include <objc/runtime.h>
+#endif // QT_MAC_USE_COCOA
+#endif
+
+#include <CoreServices/CoreServices.h>
+
+#include "QtCore/qglobal.h"
+#include "QtCore/qvariant.h"
+#include "QtCore/qmimedata.h"
+#include "QtCore/qpointer.h"
+#include "private/qcore_mac_p.h"
+
+
+#include "QtGui/qpainter.h"
+
+#include <Carbon/Carbon.h>
+
+QT_BEGIN_NAMESPACE
+class QWidget;
+class QDragMoveEvent;
+
+/* Event masks */
+// internal Qt types
+
+ // Event class for our own Carbon events.
+#if defined(QT_NAMESPACE) && defined(QT_NAMESPACE_MAC_CRC)
+// Take the CRC we generated at configure time. This *may* result in a
+// collision with another value If that is the case, please change the value
+// here to something other than 'Cute'.
+const UInt32 kEventClassQt = QT_NAMESPACE_MAC_CRC;
+#else
+const UInt32 kEventClassQt = 'Cute';
+#endif
+
+enum {
+ //AE types
+ typeAEClipboardChanged = 1,
+ //types
+ typeQWidget = 1, /* QWidget * */
+ //params
+ kEventParamQWidget = 'qwid', /* typeQWidget */
+ //events
+ kEventQtRequestContext = 13,
+ kEventQtRequestMenubarUpdate = 14,
+ kEventQtRequestShowSheet = 17,
+ kEventQtRequestActivate = 18,
+ kEventQtRequestWindowChange = 20
+};
+
+// Simple class to manage short-lived regions
+class QMacSmartQuickDrawRegion
+{
+ RgnHandle qdRgn;
+ Q_DISABLE_COPY(QMacSmartQuickDrawRegion)
+public:
+ explicit QMacSmartQuickDrawRegion(RgnHandle rgn) : qdRgn(rgn) {}
+ ~QMacSmartQuickDrawRegion() {
+ extern void qt_mac_dispose_rgn(RgnHandle); // qregion_mac.cpp
+ qt_mac_dispose_rgn(qdRgn);
+ }
+ operator RgnHandle() {
+ return qdRgn;
+ }
+};
+
+// Class for chaining to gether a bunch of fades. It pretty much is only used for qmenu fading.
+class QMacWindowFader
+{
+ QWidgetList m_windowsToFade;
+ float m_duration;
+ Q_DISABLE_COPY(QMacWindowFader)
+public:
+ QMacWindowFader(); // PLEASE DON'T CALL THIS.
+ static QMacWindowFader *currentFader();
+ void registerWindowToFade(QWidget *window);
+ void setFadeDuration(float durationInSecs) { m_duration = durationInSecs; }
+ float fadeDuration() const { return m_duration; }
+ void performFade();
+};
+
+class Q_WIDGETS_EXPORT QMacCocoaAutoReleasePool
+{
+private:
+ void *pool;
+public:
+ QMacCocoaAutoReleasePool();
+ ~QMacCocoaAutoReleasePool();
+
+ inline void *handle() const { return pool; }
+};
+
+QString qt_mac_removeMnemonics(const QString &original); //implemented in qmacstyle_mac.cpp
+
+class Q_WIDGETS_EXPORT QMacWindowChangeEvent
+{
+private:
+ static QList<QMacWindowChangeEvent*> *change_events;
+public:
+ QMacWindowChangeEvent() {
+ }
+ virtual ~QMacWindowChangeEvent() {
+ }
+ static inline void exec(bool ) {
+ }
+protected:
+ virtual void windowChanged() = 0;
+ virtual void flushWindowChanged() = 0;
+};
+
+class QMacCGContext
+{
+ CGContextRef context;
+public:
+ QMacCGContext(QPainter *p); //qpaintengine_mac.cpp
+ inline QMacCGContext() { context = 0; }
+ inline QMacCGContext(const QPaintDevice *pdev) {
+ extern CGContextRef qt_mac_cg_context(const QPaintDevice *);
+ context = qt_mac_cg_context(pdev);
+ }
+ inline QMacCGContext(CGContextRef cg, bool takeOwnership=false) {
+ context = cg;
+ if(!takeOwnership)
+ CGContextRetain(context);
+ }
+ inline QMacCGContext(const QMacCGContext &copy) : context(0) { *this = copy; }
+ inline ~QMacCGContext() {
+ if(context)
+ CGContextRelease(context);
+ }
+ inline bool isNull() const { return context; }
+ inline operator CGContextRef() { return context; }
+ inline QMacCGContext &operator=(const QMacCGContext &copy) {
+ if(context)
+ CGContextRelease(context);
+ context = copy.context;
+ CGContextRetain(context);
+ return *this;
+ }
+ inline QMacCGContext &operator=(CGContextRef cg) {
+ if(context)
+ CGContextRelease(context);
+ context = cg;
+ CGContextRetain(context); //we do not take ownership
+ return *this;
+ }
+};
+
+class QMacPasteboardMime;
+class QMimeData;
+
+class QMacPasteboard
+{
+ struct Promise {
+ Promise() : itemId(0), convertor(0) { }
+ Promise(int itemId, QMacPasteboardMime *c, QString m, QVariant d, int o=0) : itemId(itemId), offset(o), convertor(c), mime(m), data(d) { }
+ int itemId, offset;
+ QMacPasteboardMime *convertor;
+ QString mime;
+ QVariant data;
+ };
+ QList<Promise> promises;
+
+ OSPasteboardRef paste;
+ uchar mime_type;
+ mutable QPointer<QMimeData> mime;
+ mutable bool mac_mime_source;
+ static OSStatus promiseKeeper(OSPasteboardRef, PasteboardItemID, CFStringRef, void *);
+ void clear_helper();
+public:
+ QMacPasteboard(OSPasteboardRef p, uchar mime_type=0);
+ QMacPasteboard(uchar mime_type);
+ QMacPasteboard(CFStringRef name=0, uchar mime_type=0);
+ ~QMacPasteboard();
+
+ bool hasFlavor(QString flavor) const;
+ bool hasOSType(int c_flavor) const;
+
+ OSPasteboardRef pasteBoard() const;
+ QMimeData *mimeData() const;
+ void setMimeData(QMimeData *mime);
+
+ QStringList formats() const;
+ bool hasFormat(const QString &format) const;
+ QVariant retrieveData(const QString &format, QVariant::Type) const;
+
+ void clear();
+ bool sync() const;
+};
+
+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
+#endif
+
+QFont qfontForThemeFont(ThemeFontID themeID);
+
+QColor qcolorForTheme(ThemeBrush brush);
+
+QColor qcolorForThemeTextColor(ThemeTextColor themeColor);
+
+struct QMacDndAnswerRecord {
+ QRect rect;
+ 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;
+void qt_mac_copy_answer_rect(const QDragMoveEvent &event);
+bool qt_mac_mouse_inside_answer_rect(QPoint mouse);
+
+QT_END_NAMESPACE
+
+#endif // QT_MAC_P_H
diff --git a/src/gui/text/qtextengine_mac.cpp b/src/widgets/platforms/mac/qtextengine_mac.cpp
index 251d9b5072..251d9b5072 100644
--- a/src/gui/text/qtextengine_mac.cpp
+++ b/src/widgets/platforms/mac/qtextengine_mac.cpp
diff --git a/src/gui/kernel/qwidget_mac.mm b/src/widgets/platforms/mac/qwidget_mac.mm
index 4adaa6b288..4adaa6b288 100644
--- a/src/gui/kernel/qwidget_mac.mm
+++ b/src/widgets/platforms/mac/qwidget_mac.mm
diff --git a/src/widgets/platforms/s60/qapplication_s60.cpp b/src/widgets/platforms/s60/qapplication_s60.cpp
new file mode 100644
index 0000000000..69d321dd65
--- /dev/null
+++ b/src/widgets/platforms/s60/qapplication_s60.cpp
@@ -0,0 +1,2715 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qapplication_p.h"
+#include "qsessionmanager.h"
+#include "qevent.h"
+#include "qsymbianevent.h"
+#include "qeventdispatcher_s60_p.h"
+#include "qwidget.h"
+#include "qdesktopwidget.h"
+#include "private/qbackingstore_p.h"
+#include "qt_s60_p.h"
+#include "private/qevent_p.h"
+#include "qstring.h"
+#include "qdebug.h"
+#include "qimage.h"
+#include "qcombobox.h"
+#include "private/qkeymapper_p.h"
+#include "private/qfont_p.h"
+#ifndef QT_NO_STYLE_S60
+#include "private/qs60style_p.h"
+#endif
+#include "private/qwindowsurface_s60_p.h"
+#include "qpaintengine.h"
+#include "private/qmenubar_p.h"
+#include "private/qsoftkeymanager_p.h"
+#ifdef QT_GRAPHICSSYSTEM_RUNTIME
+#include "private/qgraphicssystem_runtime_p.h"
+#endif
+
+#include "apgwgnam.h" // For CApaWindowGroupName
+#include <mdaaudiotoneplayer.h> // For CMdaAudioToneUtility
+
+#if defined(Q_OS_SYMBIAN)
+# include <private/qs60mainapplication_p.h>
+# include <centralrepository.h>
+# include "qs60mainappui.h"
+# include "qinputcontext.h"
+#endif
+
+#if defined(Q_WS_S60)
+# if !defined(QT_NO_IM)
+# include <private/qcoefepinputcontext_p.h>
+# endif
+#endif
+
+#include "private/qstylesheetstyle_p.h"
+
+#include <hal.h>
+#include <hal_data.h>
+
+#ifdef Q_SYMBIAN_TRANSITION_EFFECTS
+#include <graphics/wstfxconst.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+// Goom Events through Window Server
+static const int KGoomMemoryLowEvent = 0x10282DBF;
+static const int KGoomMemoryGoodEvent = 0x20026790;
+// Split view open/close events from AVKON
+static const int KSplitViewOpenEvent = 0x2001E2C0;
+static const int KSplitViewCloseEvent = 0x2001E2C1;
+
+#if defined(QT_DEBUG)
+static bool appNoGrab = false; // Grabbing enabled
+#endif
+static bool app_do_modal = false; // modal mode
+Q_GLOBAL_STATIC(QS60Data, qt_s60Data);
+
+extern bool qt_sendSpontaneousEvent(QObject*,QEvent*);
+extern QWidgetList *qt_modal_stack; // stack of modal widgets
+extern QDesktopWidget *qt_desktopWidget; // qapplication.cpp
+
+QWidget *qt_button_down = 0; // widget got last button-down
+
+QSymbianControl *QSymbianControl::lastFocusedControl = 0;
+
+QS60Data* qGlobalS60Data()
+{
+ return qt_s60Data();
+}
+
+#ifdef Q_WS_S60
+void QS60Data::setStatusPaneAndButtonGroupVisibility(bool statusPaneVisible, bool buttonGroupVisible)
+{
+ bool buttonGroupVisibilityChanged = false;
+ if (CEikButtonGroupContainer *const b = buttonGroupContainer()) {
+ buttonGroupVisibilityChanged = (b->IsVisible() != buttonGroupVisible);
+ b->MakeVisible(buttonGroupVisible);
+ }
+ bool statusPaneVisibilityChanged = false;
+ if (CEikStatusPane *const s = statusPane()) {
+ statusPaneVisibilityChanged = (s->IsVisible() != statusPaneVisible);
+ s->MakeVisible(statusPaneVisible);
+ }
+ if (buttonGroupVisibilityChanged || statusPaneVisibilityChanged) {
+ const QSize size = qt_TRect2QRect(static_cast<CEikAppUi*>(S60->appUi())->ClientRect()).size();
+ const QSize oldSize; // note that QDesktopWidget::resizeEvent ignores the QResizeEvent contents
+ QResizeEvent event(size, oldSize);
+ QApplication::instance()->sendEvent(QApplication::desktop(), &event);
+ }
+ if (buttonGroupVisibilityChanged && !statusPaneVisibilityChanged && QApplication::activeWindow())
+ // Ensure that control rectangle is updated
+ static_cast<QSymbianControl *>(QApplication::activeWindow()->winId())->handleClientAreaChange();
+}
+
+bool QS60Data::setRecursiveDecorationsVisibility(QWidget *window, Qt::WindowStates newState)
+{
+ // Show statusbar:
+ // Topmost parent: Show unless fullscreen/minimized.
+ // Child windows: Follow topmost parent, unless fullscreen, in which case do not show statusbar
+ // Show CBA:
+ // Topmost parent: Show unless fullscreen/minimized.
+ // Exception: Show if fullscreen with Qt::WindowSoftkeysVisibleHint.
+ // Child windows:
+ // Minimized: Unclear if there is an use case for having focused minimized window at all.
+ // Always follow topmost parent just to be safe.
+ // Maximized and normal: follow topmost parent.
+ // Exception: If topmost parent is not showing CBA, show CBA if any softkey actions are
+ // defined.
+ // Fullscreen: Show only if Qt::WindowSoftkeysVisibleHint set.
+
+ Qt::WindowStates comparisonState = newState;
+ QWidget *parentWindow = window->parentWidget();
+ if (parentWindow) {
+ while (parentWindow->parentWidget())
+ parentWindow = parentWindow->parentWidget();
+ comparisonState = parentWindow->windowState();
+ } else {
+ parentWindow = window;
+ }
+
+ bool decorationsVisible = !(comparisonState & (Qt::WindowFullScreen | Qt::WindowMinimized));
+ const bool parentIsFullscreen = comparisonState & Qt::WindowFullScreen;
+ const bool parentCbaVisibilityHint = parentWindow->windowFlags() & Qt::WindowSoftkeysVisibleHint;
+ bool buttonGroupVisibility = (decorationsVisible || (parentIsFullscreen && parentCbaVisibilityHint));
+
+ // Do extra checking for child windows
+ if (window->parentWidget()) {
+ if (newState & Qt::WindowFullScreen) {
+ decorationsVisible = false;
+ if (window->windowFlags() & Qt::WindowSoftkeysVisibleHint)
+ buttonGroupVisibility = true;
+ else
+ buttonGroupVisibility = false;
+ } else if (!(newState & Qt::WindowMinimized) && !buttonGroupVisibility) {
+ for (int i = 0; i < window->actions().size(); ++i) {
+ if (window->actions().at(i)->softKeyRole() != QAction::NoSoftKey) {
+ buttonGroupVisibility = true;
+ break;
+ }
+ }
+ }
+ }
+
+ S60->setStatusPaneAndButtonGroupVisibility(decorationsVisible, buttonGroupVisibility);
+
+ return decorationsVisible;
+}
+#endif
+
+void QS60Data::controlVisibilityChanged(CCoeControl *control, bool visible)
+{
+ if (QWidgetPrivate::mapper && QWidgetPrivate::mapper->contains(control)) {
+ QWidget *const widget = QWidgetPrivate::mapper->value(control);
+ QWidget *const window = widget->window();
+ if (QTLWExtra *topData = qt_widget_private(window)->maybeTopData()) {
+ QWidgetBackingStoreTracker &backingStore = topData->backingStore;
+ if (visible) {
+ if (backingStore.data()) {
+ backingStore.registerWidget(widget);
+ } else {
+ backingStore.create(window);
+ backingStore.registerWidget(widget);
+ qt_widget_private(widget)->invalidateBuffer(widget->rect());
+ widget->repaint();
+ }
+ } else {
+ // In certain special scenarios we may get an ENotVisible event
+ // without a previous EPartiallyVisible. The backingstore must
+ // still be destroyed, hence the registerWidget() call below.
+ if (backingStore.data() && widget->internalWinId()
+ && qt_widget_private(widget)->maybeBackingStore() == backingStore.data())
+ backingStore.registerWidget(widget);
+ backingStore.unregisterWidget(widget);
+ // In order to ensure that any resources used by the window surface
+ // are immediately freed, we flush the WSERV command buffer.
+ S60->wsSession().Flush();
+ }
+ }
+ }
+}
+
+bool qt_nograb() // application no-grab option
+{
+#if defined(QT_DEBUG)
+ return appNoGrab;
+#else
+ return false;
+#endif
+}
+
+// Modified from http://www3.symbian.com/faq.nsf/0/0F1464EE96E737E780256D5E00503DD1?OpenDocument
+class QS60Beep : public CBase, public MMdaAudioToneObserver
+{
+public:
+ static QS60Beep* NewL(TInt aFrequency, TTimeIntervalMicroSeconds iDuration);
+ void Play();
+ ~QS60Beep();
+private:
+ void ConstructL(TInt aFrequency, TTimeIntervalMicroSeconds iDuration);
+ void MatoPrepareComplete(TInt aError);
+ void MatoPlayComplete(TInt aError);
+private:
+ typedef enum
+ {
+ EBeepNotPrepared,
+ EBeepPrepared,
+ EBeepPlaying
+ } TBeepState;
+private:
+ CMdaAudioToneUtility* iToneUtil;
+ TBeepState iState;
+ TInt iFrequency;
+ TTimeIntervalMicroSeconds iDuration;
+};
+
+static QS60Beep* qt_S60Beep = 0;
+
+QS60Beep::~QS60Beep()
+{
+ if (iToneUtil) {
+ switch (iState) {
+ case EBeepPlaying:
+ iToneUtil->CancelPlay();
+ break;
+ case EBeepNotPrepared:
+ iToneUtil->CancelPrepare();
+ break;
+ }
+ }
+ delete iToneUtil;
+}
+
+QS60Beep* QS60Beep::NewL(TInt aFrequency, TTimeIntervalMicroSeconds aDuration)
+{
+ QS60Beep* self = new (ELeave) QS60Beep();
+ CleanupStack::PushL(self);
+ self->ConstructL(aFrequency, aDuration);
+ CleanupStack::Pop();
+ return self;
+}
+
+void QS60Beep::ConstructL(TInt aFrequency, TTimeIntervalMicroSeconds aDuration)
+{
+ iToneUtil = CMdaAudioToneUtility::NewL(*this);
+ iState = EBeepNotPrepared;
+ iFrequency = aFrequency;
+ iDuration = aDuration;
+ iToneUtil->PrepareToPlayTone(iFrequency, iDuration);
+}
+
+void QS60Beep::Play()
+{
+ if (iState == EBeepPlaying) {
+ iToneUtil->CancelPlay();
+ iState = EBeepPrepared;
+ }
+
+ iToneUtil->Play();
+ iState = EBeepPlaying;
+}
+
+void QS60Beep::MatoPrepareComplete(TInt aError)
+{
+ if (aError == KErrNone) {
+ iState = EBeepPrepared;
+ Play();
+ }
+}
+
+void QS60Beep::MatoPlayComplete(TInt aError)
+{
+ Q_UNUSED(aError);
+ iState = EBeepPrepared;
+}
+
+
+static Qt::KeyboardModifiers mapToQtModifiers(TUint s60Modifiers)
+{
+ Qt::KeyboardModifiers result = Qt::NoModifier;
+
+ if (s60Modifiers & EModifierKeypad)
+ result |= Qt::KeypadModifier;
+ if (s60Modifiers & EModifierShift || s60Modifiers & EModifierLeftShift
+ || s60Modifiers & EModifierRightShift)
+ result |= Qt::ShiftModifier;
+ if (s60Modifiers & EModifierCtrl || s60Modifiers & EModifierLeftCtrl
+ || s60Modifiers & EModifierRightCtrl)
+ result |= Qt::ControlModifier;
+ if (s60Modifiers & EModifierAlt || s60Modifiers & EModifierLeftAlt
+ || s60Modifiers & EModifierRightAlt)
+ result |= Qt::AltModifier;
+
+ return result;
+}
+
+static void mapS60MouseEventTypeToQt(QEvent::Type *type, Qt::MouseButton *button, const TPointerEvent *pEvent)
+{
+ switch (pEvent->iType) {
+ case TPointerEvent::EButton1Down:
+ *type = QEvent::MouseButtonPress;
+ *button = Qt::LeftButton;
+ break;
+ case TPointerEvent::EButton1Up:
+ *type = QEvent::MouseButtonRelease;
+ *button = Qt::LeftButton;
+ break;
+ case TPointerEvent::EButton2Down:
+ *type = QEvent::MouseButtonPress;
+ *button = Qt::MidButton;
+ break;
+ case TPointerEvent::EButton2Up:
+ *type = QEvent::MouseButtonRelease;
+ *button = Qt::MidButton;
+ break;
+ case TPointerEvent::EButton3Down:
+ *type = QEvent::MouseButtonPress;
+ *button = Qt::RightButton;
+ break;
+ case TPointerEvent::EButton3Up:
+ *type = QEvent::MouseButtonRelease;
+ *button = Qt::RightButton;
+ break;
+ case TPointerEvent::EDrag:
+ *type = QEvent::MouseMove;
+ *button = Qt::NoButton;
+ break;
+ case TPointerEvent::EMove:
+ // Qt makes no distinction between move and drag
+ *type = QEvent::MouseMove;
+ *button = Qt::NoButton;
+ break;
+ default:
+ *type = QEvent::None;
+ *button = Qt::NoButton;
+ break;
+ }
+ if (pEvent->iModifiers & EModifierDoubleClick){
+ *type = QEvent::MouseButtonDblClick;
+ }
+
+ if (*type == QEvent::MouseButtonPress || *type == QEvent::MouseButtonDblClick)
+ QApplicationPrivate::mouse_buttons = QApplicationPrivate::mouse_buttons | (*button);
+ else if (*type == QEvent::MouseButtonRelease)
+ QApplicationPrivate::mouse_buttons = QApplicationPrivate::mouse_buttons &(~(*button));
+
+ QApplicationPrivate::mouse_buttons = QApplicationPrivate::mouse_buttons & Qt::MouseButtonMask;
+}
+
+//### Can be replaced with CAknLongTapDetector if animation is required.
+//NOTE: if CAknLongTapDetector is used make sure it gets variated out of 3.1 and 3.2,.
+//also MLongTapObserver needs to be changed to MAknLongTapDetectorCallBack if CAknLongTapDetector is used.
+class QLongTapTimer : public CTimer
+{
+public:
+ static QLongTapTimer* NewL(QAbstractLongTapObserver *observer);
+ QLongTapTimer(QAbstractLongTapObserver *observer);
+ void ConstructL();
+public:
+ void PointerEventL(const TPointerEvent &event);
+ void RunL();
+protected:
+private:
+ QAbstractLongTapObserver *m_observer;
+ TPointerEvent m_event;
+ QPoint m_pressedCoordinates;
+ int m_dragDistance;
+};
+
+QLongTapTimer* QLongTapTimer::NewL(QAbstractLongTapObserver *observer)
+{
+ QLongTapTimer* self = new QLongTapTimer(observer);
+ self->ConstructL();
+ return self;
+}
+void QLongTapTimer::ConstructL()
+{
+ CTimer::ConstructL();
+}
+
+QLongTapTimer::QLongTapTimer(QAbstractLongTapObserver *observer):CTimer(CActive::EPriorityHigh)
+{
+ m_observer = observer;
+ m_dragDistance = qApp->startDragDistance();
+ CActiveScheduler::Add(this);
+}
+
+void QLongTapTimer::PointerEventL(const TPointerEvent& event)
+{
+ if ( event.iType == TPointerEvent::EDrag || event.iType == TPointerEvent::EButtonRepeat)
+ {
+ QPoint diff(QPoint(event.iPosition.iX,event.iPosition.iY) - m_pressedCoordinates);
+ if (diff.manhattanLength() < m_dragDistance)
+ return;
+ }
+ Cancel();
+ m_event = event;
+ if (event.iType == TPointerEvent::EButton1Down)
+ {
+ m_pressedCoordinates = QPoint(event.iPosition.iX,event.iPosition.iY);
+ // must be same as KLongTapDelay in aknlongtapdetector.h
+ After(800000);
+ }
+}
+void QLongTapTimer::RunL()
+{
+ if (m_observer)
+ m_observer->HandleLongTapEventL(m_event.iPosition, m_event.iParentPosition);
+}
+
+QSymbianControl::QSymbianControl(QWidget *w)
+ : CCoeControl()
+ , qwidget(w)
+ , m_longTapDetector(0)
+ , m_ignoreFocusChanged(0)
+ , m_symbianPopupIsOpen(0)
+ , m_inExternalScreenOverride(false)
+ , m_lastStatusPaneVisibility(0)
+{
+}
+
+void QSymbianControl::ConstructL(bool isWindowOwning, bool desktop)
+{
+ if (!desktop)
+ {
+ if (isWindowOwning || !qwidget->parentWidget()
+ || qwidget->parentWidget()->windowType() == Qt::Desktop) {
+ RWindowGroup &wg(S60->windowGroup(qwidget));
+ CreateWindowL(wg);
+ } else {
+ /**
+ * TODO: in order to avoid creating windows for all ancestors of
+ * this widget up to the root window, the parameter passed to
+ * CreateWindowL should be
+ * qwidget->parentWidget()->effectiveWinId(). However, if we do
+ * this, then we need to take care of re-parenting when a window
+ * is created for a widget between this one and the root window.
+ */
+ CreateWindowL(qwidget->parentWidget()->winId());
+ }
+
+ // Necessary in order to be able to track the activation status of
+ // the control's window
+ qwidget->d_func()->createExtra();
+
+ SetFocusing(true);
+ m_longTapDetector = QLongTapTimer::NewL(this);
+ m_doubleClickTimer.invalidate();
+
+ DrawableWindow()->SetPointerGrab(ETrue);
+ }
+
+#ifdef Q_SYMBIAN_TRANSITION_EFFECTS
+ if (OwnsWindow()) {
+ TTfxWindowPurpose windowPurpose(ETfxPurposeNone);
+ switch (qwidget->windowType()) {
+ case Qt::Dialog:
+ windowPurpose = ETfxPurposeDialogWindow;
+ break;
+ case Qt::Popup:
+ windowPurpose = ETfxPurposePopupWindow;
+ break;
+ case Qt::Tool:
+ windowPurpose = ETfxPurposeToolWindow;
+ break;
+ case Qt::ToolTip:
+ windowPurpose = ETfxPurposeToolTipWindow;
+ break;
+ case Qt::SplashScreen:
+ windowPurpose = ETfxPurposeSplashScreenWindow;
+ break;
+ default:
+ windowPurpose = (isWindowOwning || !qwidget->parentWidget() || qwidget->parentWidget()->windowType() == Qt::Desktop)
+ ? ETfxPurposeWindow : ETfxPurposeChildWindow;
+ break;
+ }
+ Window().SetPurpose(windowPurpose);
+ }
+#endif
+}
+
+QSymbianControl::~QSymbianControl()
+{
+ // Ensure backing store is deleted before the top-level
+ // window is destroyed
+ qt_widget_private(qwidget)->topData()->backingStore.destroy();
+
+ if (S60->curWin == this)
+ S60->curWin = 0;
+ if (!QApplicationPrivate::is_app_closing) {
+ QT_TRY {
+ setFocusSafely(false);
+ } QT_CATCH(const std::exception&) {
+ // ignore exceptions, nothing can be done
+ }
+ }
+ S60->appUi()->RemoveFromStack(this);
+ delete m_longTapDetector;
+}
+
+void QSymbianControl::setWidget(QWidget *w)
+{
+ qwidget = w;
+}
+
+QPoint QSymbianControl::translatePointForFixedNativeOrientation(const TPoint &pointerEventPos) const
+{
+ QPoint pos(pointerEventPos.iX, pointerEventPos.iY);
+ if (qwidget->d_func()->fixNativeOrientationCalled) {
+ QSize wsize = qwidget->size();
+ TSize size = Size();
+ if (size.iWidth == wsize.height() && size.iHeight == wsize.width()) {
+ qreal x = pos.x();
+ qreal y = pos.y();
+ pos.setX(size.iHeight - y);
+ pos.setY(x);
+ }
+ }
+ return pos;
+}
+
+TRect QSymbianControl::translateRectForFixedNativeOrientation(const TRect &controlRect) const
+{
+ TRect rect = controlRect;
+ if (qwidget->d_func()->fixNativeOrientationCalled) {
+ QPoint a = translatePointForFixedNativeOrientation(rect.iTl);
+ QPoint b = translatePointForFixedNativeOrientation(rect.iBr);
+ if (a.x() < b.x()) {
+ rect.iTl.iX = a.x();
+ rect.iBr.iX = b.x();
+ } else {
+ rect.iTl.iX = b.x();
+ rect.iBr.iX = a.x();
+ }
+ if (a.y() < b.y()) {
+ rect.iTl.iY = a.y();
+ rect.iBr.iY = b.y();
+ } else {
+ rect.iTl.iY = b.y();
+ rect.iBr.iY = a.y();
+ }
+ }
+ return rect;
+}
+
+void QSymbianControl::HandleLongTapEventL( const TPoint& aPenEventLocation, const TPoint& aPenEventScreenLocation )
+{
+ QWidget *alienWidget;
+ QPoint widgetPos = translatePointForFixedNativeOrientation(aPenEventLocation);
+ QPoint globalPos = translatePointForFixedNativeOrientation(aPenEventScreenLocation);
+ alienWidget = qwidget->childAt(widgetPos);
+ if (!alienWidget)
+ alienWidget = qwidget;
+
+#if !defined(QT_NO_CONTEXTMENU)
+ QContextMenuEvent contextMenuEvent(QContextMenuEvent::Mouse, widgetPos, globalPos, Qt::NoModifier);
+ qt_sendSpontaneousEvent(alienWidget, &contextMenuEvent);
+#endif
+}
+
+#ifdef QT_SYMBIAN_SUPPORTS_ADVANCED_POINTER
+void QSymbianControl::translateAdvancedPointerEvent(const TAdvancedPointerEvent *event)
+{
+ QApplicationPrivate *d = QApplicationPrivate::instance();
+ QPointF screenPos = qwidget->mapToGlobal(translatePointForFixedNativeOrientation(event->iPosition));
+ qreal pressure;
+ if(d->pressureSupported
+ && event->Pressure() > 0) //workaround for misconfigured HAL
+ pressure = event->Pressure() / qreal(d->maxTouchPressure);
+ else
+ pressure = qreal(1.0);
+ processTouchEvent(event->PointerNumber(), event->iType, screenPos, pressure);
+}
+#endif
+
+void QSymbianControl::processTouchEvent(int pointerNumber, TPointerEvent::TType type, QPointF screenPos, qreal pressure)
+{
+ QRect screenGeometry = qApp->desktop()->screenGeometry(qwidget);
+
+ QApplicationPrivate *d = QApplicationPrivate::instance();
+
+ QList<QTouchEvent::TouchPoint> points = d->appAllTouchPoints;
+ while (points.count() <= pointerNumber)
+ points.append(QTouchEvent::TouchPoint(points.count()));
+
+ Qt::TouchPointStates allStates = 0;
+ for (int i = 0; i < points.count(); ++i) {
+ QTouchEvent::TouchPoint &touchPoint = points[i];
+
+ if (touchPoint.id() == pointerNumber) {
+ Qt::TouchPointStates state;
+ switch (type) {
+ case TPointerEvent::EButton1Down:
+#ifdef QT_SYMBIAN_SUPPORTS_ADVANCED_POINTER
+ case TPointerEvent::EEnterHighPressure:
+#endif
+ state = Qt::TouchPointPressed;
+ break;
+ case TPointerEvent::EButton1Up:
+#ifdef QT_SYMBIAN_SUPPORTS_ADVANCED_POINTER
+ case TPointerEvent::EExitCloseProximity:
+#endif
+ state = Qt::TouchPointReleased;
+ break;
+ case TPointerEvent::EDrag:
+ state = Qt::TouchPointMoved;
+ break;
+ default:
+ // how likely is this to happen?
+ state = Qt::TouchPointStationary;
+ break;
+ }
+ if (pointerNumber == 0)
+ state |= Qt::TouchPointPrimary;
+ touchPoint.setState(state);
+
+ touchPoint.setScreenPos(screenPos);
+ touchPoint.setNormalizedPos(QPointF(screenPos.x() / screenGeometry.width(),
+ screenPos.y() / screenGeometry.height()));
+
+ touchPoint.setPressure(pressure);
+ } else if (touchPoint.state() != Qt::TouchPointReleased) {
+ // all other active touch points should be marked as stationary
+ touchPoint.setState(Qt::TouchPointStationary);
+ }
+
+ allStates |= touchPoint.state();
+ }
+
+ if ((allStates & Qt::TouchPointStateMask) == Qt::TouchPointReleased) {
+ // all touch points released
+ d->appAllTouchPoints.clear();
+ } else {
+ d->appAllTouchPoints = points;
+ }
+
+ QApplicationPrivate::translateRawTouchEvent(qwidget,
+ QTouchEvent::TouchScreen,
+ points);
+}
+
+void QSymbianControl::HandlePointerEventL(const TPointerEvent& pEvent)
+{
+#ifdef QT_SYMBIAN_SUPPORTS_ADVANCED_POINTER
+ if (pEvent.IsAdvancedPointerEvent()) {
+ const TAdvancedPointerEvent *advancedPointerEvent = pEvent.AdvancedPointerEvent();
+ translateAdvancedPointerEvent(advancedPointerEvent);
+ if (advancedPointerEvent->PointerNumber() != 0) {
+ // only send mouse events for the first touch point
+ return;
+ }
+ }
+#endif
+
+ m_longTapDetector->PointerEventL(pEvent);
+ QT_TRYCATCH_LEAVING(HandlePointerEvent(pEvent));
+}
+
+void QSymbianControl::HandlePointerEvent(const TPointerEvent& pEvent)
+{
+ QMouseEvent::Type type;
+ Qt::MouseButton button;
+ mapS60MouseEventTypeToQt(&type, &button, &pEvent);
+ Qt::KeyboardModifiers modifiers = mapToQtModifiers(pEvent.iModifiers);
+
+ QPoint widgetPos = translatePointForFixedNativeOrientation(pEvent.iPosition);
+ TPoint controlScreenPos = PositionRelativeToScreen();
+ QPoint globalPos = QPoint(controlScreenPos.iX, controlScreenPos.iY) + widgetPos;
+ S60->lastCursorPos = globalPos;
+ S60->lastPointerEventPos = widgetPos;
+
+ QWidget *mouseGrabber = QWidget::mouseGrabber();
+
+ QWidget *popupWidget = qApp->activePopupWidget();
+ QWidget *popupReceiver = 0;
+ if (popupWidget) {
+ QWidget *popupChild = popupWidget->childAt(popupWidget->mapFromGlobal(globalPos));
+ popupReceiver = popupChild ? popupChild : popupWidget;
+ }
+
+ if (mouseGrabber) {
+ if (popupReceiver) {
+ sendMouseEvent(popupReceiver, type, globalPos, button, modifiers);
+ } else {
+ sendMouseEvent(mouseGrabber, type, globalPos, button, modifiers);
+ }
+ // No Enter/Leave events in grabbing mode.
+ return;
+ }
+
+ QWidget *widgetUnderPointer = qwidget->childAt(widgetPos);
+ if (!widgetUnderPointer)
+ widgetUnderPointer = qwidget;
+
+ QApplicationPrivate::dispatchEnterLeave(widgetUnderPointer, S60->lastPointerEventTarget);
+ S60->lastPointerEventTarget = widgetUnderPointer;
+
+ QWidget *receiver;
+ if (!popupReceiver && S60->mousePressTarget && type != QEvent::MouseButtonPress) {
+ receiver = S60->mousePressTarget;
+ if (type == QEvent::MouseButtonRelease)
+ S60->mousePressTarget = 0;
+ } else {
+ receiver = popupReceiver ? popupReceiver : widgetUnderPointer;
+ if (type == QEvent::MouseButtonPress)
+ S60->mousePressTarget = receiver;
+ }
+
+#if !defined(QT_NO_CURSOR) && !defined(Q_SYMBIAN_FIXED_POINTER_CURSORS)
+ if (S60->brokenPointerCursors)
+ qt_symbian_move_cursor_sprite();
+#endif
+
+//Generate single touch event for S60 5.0 (has touchscreen, does not have advanced pointers)
+#ifndef QT_SYMBIAN_SUPPORTS_ADVANCED_POINTER
+ if (S60->hasTouchscreen) {
+ processTouchEvent(0, pEvent.iType, QPointF(globalPos), 1.0);
+ }
+#endif
+
+ sendMouseEvent(receiver, type, globalPos, button, modifiers);
+}
+
+#ifdef Q_WS_S60
+void QSymbianControl::HandleStatusPaneSizeChange()
+{
+ QS60MainAppUi *s60AppUi = static_cast<QS60MainAppUi *>(S60->appUi());
+ s60AppUi->HandleStatusPaneSizeChange();
+}
+#endif
+
+void QSymbianControl::sendMouseEvent(
+ QWidget *receiver,
+ QEvent::Type type,
+ const QPoint &globalPos,
+ Qt::MouseButton button,
+ Qt::KeyboardModifiers modifiers)
+{
+ Q_ASSERT(receiver);
+ QMouseEvent mEvent(type, receiver->mapFromGlobal(globalPos), globalPos,
+ button, QApplicationPrivate::mouse_buttons, modifiers);
+ QEventDispatcherS60 *dispatcher;
+ // It is theoretically possible for someone to install a different event dispatcher.
+ if ((dispatcher = qobject_cast<QEventDispatcherS60 *>(receiver->d_func()->threadData->eventDispatcher)) != 0) {
+ if (dispatcher->excludeUserInputEvents()) {
+ dispatcher->saveInputEvent(this, receiver, new QMouseEvent(mEvent));
+ return;
+ }
+ }
+
+ sendMouseEvent(receiver, &mEvent);
+}
+
+bool QSymbianControl::sendMouseEvent(QWidget *widget, QMouseEvent *mEvent)
+{
+ return qt_sendSpontaneousEvent(widget, mEvent);
+}
+
+TKeyResponse QSymbianControl::OfferKeyEventL(const TKeyEvent& keyEvent, TEventCode type)
+{
+ TKeyResponse r = EKeyWasNotConsumed;
+ QT_TRYCATCH_LEAVING(r = OfferKeyEvent(keyEvent, type));
+ return r;
+}
+
+TKeyResponse QSymbianControl::OfferKeyEvent(const TKeyEvent& keyEvent, TEventCode type)
+{
+ /*
+ S60 has a confusing way of delivering key events. There are three types of
+ events: EEventKey, EEventKeyDown and EEventKeyUp. When a key is pressed,
+ EEventKeyDown is first generated, followed by EEventKey. Then, when the key is
+ released, EEventKeyUp is generated.
+ However, it is possible that only the EEventKey is generated alone, typically
+ in relation to virtual keyboards. In that case we need to take care to
+ generate both press and release events in Qt, since applications expect that.
+ We do this by having three states for each used scan code, depending on the
+ events received. See the switch below for what happens in each state
+ transition.
+ */
+
+ if (type != EEventKeyDown)
+ if (handleVirtualMouse(keyEvent, type) == EKeyWasConsumed)
+ return EKeyWasConsumed;
+
+ TKeyResponse ret = EKeyWasNotConsumed;
+#define GET_RETURN(x) (ret = ((x) == EKeyWasConsumed) ? EKeyWasConsumed : ret)
+
+ // This top level switch corresponds to the states, and the inner switches
+ // correspond to the transitions.
+ QS60Data::ScanCodeState &scanCodeState = S60->scanCodeStates[keyEvent.iScanCode];
+ switch (scanCodeState) {
+ case QS60Data::Unpressed:
+ switch (type) {
+ case EEventKeyDown:
+ scanCodeState = QS60Data::KeyDown;
+ break;
+ case EEventKey:
+ GET_RETURN(sendSymbianKeyEvent(keyEvent, QEvent::KeyPress));
+ GET_RETURN(sendSymbianKeyEvent(keyEvent, QEvent::KeyRelease));
+ break;
+ case EEventKeyUp:
+ // No action.
+ break;
+ }
+ break;
+ case QS60Data::KeyDown:
+ switch (type) {
+ case EEventKeyDown:
+ // This should never happen, just stay in this state to be safe.
+ break;
+ case EEventKey:
+ GET_RETURN(sendSymbianKeyEvent(keyEvent, QEvent::KeyPress));
+ scanCodeState = QS60Data::KeyDownAndKey;
+ break;
+ case EEventKeyUp:
+ scanCodeState = QS60Data::Unpressed;
+ break;
+ }
+ break;
+ case QS60Data::KeyDownAndKey:
+ switch (type) {
+ case EEventKeyDown:
+ // This should never happen, just stay in this state to be safe.
+ break;
+ case EEventKey:
+ GET_RETURN(sendSymbianKeyEvent(keyEvent, QEvent::KeyRelease));
+ GET_RETURN(sendSymbianKeyEvent(keyEvent, QEvent::KeyPress));
+ break;
+ case EEventKeyUp:
+ GET_RETURN(sendSymbianKeyEvent(keyEvent, QEvent::KeyRelease));
+ scanCodeState = QS60Data::Unpressed;
+ break;
+ }
+ break;
+ }
+ return ret;
+
+#undef GET_RETURN
+}
+
+TKeyResponse QSymbianControl::sendSymbianKeyEvent(const TKeyEvent &keyEvent, QEvent::Type type)
+{
+ // Because S60 does not generate keysyms for EKeyEventDown and EKeyEventUp
+ // events, we need to cache the keysyms from the EKeyEvent events. This is what
+ // resolveS60ScanCode does.
+ TUint s60Keysym = QApplicationPrivate::resolveS60ScanCode(keyEvent.iScanCode,
+ keyEvent.iCode);
+ int keyCode;
+ if (s60Keysym == EKeyNull){ //some key events have 0 in iCode, for them iScanCode should be used
+ keyCode = qt_keymapper_private()->mapS60ScanCodesToQt(keyEvent.iScanCode);
+ } else if (s60Keysym >= 0x20 && s60Keysym < ENonCharacterKeyBase) {
+ // Normal characters keys.
+ keyCode = s60Keysym;
+ } else {
+ // Special S60 keys.
+ keyCode = qt_keymapper_private()->mapS60KeyToQt(s60Keysym);
+ }
+
+ Qt::KeyboardModifiers mods = mapToQtModifiers(keyEvent.iModifiers);
+ QKeyEventEx qKeyEvent(type, keyCode, mods, qt_keymapper_private()->translateKeyEvent(keyCode, mods),
+ (keyEvent.iRepeats != 0), 1, keyEvent.iScanCode, s60Keysym, keyEvent.iModifiers);
+ QWidget *widget;
+ widget = QWidget::keyboardGrabber();
+ if (!widget) {
+ if (QApplicationPrivate::popupWidgets != 0) {
+ widget = QApplication::activePopupWidget()->focusWidget();
+ if (!widget) {
+ widget = QApplication::activePopupWidget();
+ }
+ } else {
+ widget = QApplicationPrivate::focus_widget;
+ if (!widget) {
+ widget = qwidget;
+ }
+ }
+ }
+
+ QEventDispatcherS60 *dispatcher;
+ // It is theoretically possible for someone to install a different event dispatcher.
+ if ((dispatcher = qobject_cast<QEventDispatcherS60 *>(widget->d_func()->threadData->eventDispatcher)) != 0) {
+ if (dispatcher->excludeUserInputEvents()) {
+ dispatcher->saveInputEvent(this, widget, new QKeyEventEx(qKeyEvent));
+ return EKeyWasConsumed;
+ }
+ }
+ return sendKeyEvent(widget, &qKeyEvent);
+}
+
+TKeyResponse QSymbianControl::handleVirtualMouse(const TKeyEvent& keyEvent,TEventCode type)
+{
+#ifndef QT_NO_CURSOR
+ if (S60->mouseInteractionEnabled && S60->virtualMouseRequired) {
+ //translate keys to pointer
+ if ((keyEvent.iScanCode >= EStdKeyLeftArrow && keyEvent.iScanCode <= EStdKeyDownArrow) ||
+ (keyEvent.iScanCode >= EStdKeyDevice10 && keyEvent.iScanCode <= EStdKeyDevice13) ||
+ keyEvent.iScanCode == EStdKeyDevice3) {
+ QPoint pos = QCursor::pos();
+ TPointerEvent fakeEvent;
+ fakeEvent.iType = (TPointerEvent::TType)(-1);
+ fakeEvent.iModifiers = keyEvent.iModifiers;
+ TInt x = pos.x();
+ TInt y = pos.y();
+ if (type == EEventKeyUp) {
+ S60->virtualMouseAccelTimeout.start();
+ switch (keyEvent.iScanCode) {
+ case EStdKeyLeftArrow:
+ S60->virtualMousePressedKeys &= ~QS60Data::Left;
+ break;
+ case EStdKeyRightArrow:
+ S60->virtualMousePressedKeys &= ~QS60Data::Right;
+ break;
+ case EStdKeyUpArrow:
+ S60->virtualMousePressedKeys &= ~QS60Data::Up;
+ break;
+ case EStdKeyDownArrow:
+ S60->virtualMousePressedKeys &= ~QS60Data::Down;
+ break;
+ // diagonal keys (named aliases don't exist in 3.1 SDK)
+ case EStdKeyDevice10:
+ S60->virtualMousePressedKeys &= ~QS60Data::LeftUp;
+ break;
+ case EStdKeyDevice11:
+ S60->virtualMousePressedKeys &= ~QS60Data::RightUp;
+ break;
+ case EStdKeyDevice12:
+ S60->virtualMousePressedKeys &= ~QS60Data::RightDown;
+ break;
+ case EStdKeyDevice13:
+ S60->virtualMousePressedKeys &= ~QS60Data::LeftDown;
+ break;
+ case EStdKeyDevice3: //select
+ if (S60->virtualMousePressedKeys & QS60Data::Select)
+ fakeEvent.iType = TPointerEvent::EButton1Up;
+ S60->virtualMousePressedKeys &= ~QS60Data::Select;
+ break;
+ }
+ }
+ else if (type == EEventKey) {
+ int dx = 0;
+ int dy = 0;
+ if (keyEvent.iScanCode != EStdKeyDevice3) {
+ m_doubleClickTimer.invalidate();
+ //reset mouse accelleration after a short time with no moves
+ const int maxTimeBetweenKeyEventsMs = 500;
+ if (S60->virtualMouseAccelTimeout.isValid() &&
+ S60->virtualMouseAccelTimeout.hasExpired(maxTimeBetweenKeyEventsMs)) {
+ S60->virtualMouseAccelDX = 0;
+ S60->virtualMouseAccelDY = 0;
+ }
+ S60->virtualMouseAccelTimeout.invalidate();
+ }
+ switch (keyEvent.iScanCode) {
+ case EStdKeyLeftArrow:
+ S60->virtualMousePressedKeys |= QS60Data::Left;
+ dx = -1;
+ fakeEvent.iType = TPointerEvent::EMove;
+ break;
+ case EStdKeyRightArrow:
+ S60->virtualMousePressedKeys |= QS60Data::Right;
+ dx = 1;
+ fakeEvent.iType = TPointerEvent::EMove;
+ break;
+ case EStdKeyUpArrow:
+ S60->virtualMousePressedKeys |= QS60Data::Up;
+ dy = -1;
+ fakeEvent.iType = TPointerEvent::EMove;
+ break;
+ case EStdKeyDownArrow:
+ S60->virtualMousePressedKeys |= QS60Data::Down;
+ dy = 1;
+ fakeEvent.iType = TPointerEvent::EMove;
+ break;
+ case EStdKeyDevice10:
+ S60->virtualMousePressedKeys |= QS60Data::LeftUp;
+ dx = -1;
+ dy = -1;
+ fakeEvent.iType = TPointerEvent::EMove;
+ break;
+ case EStdKeyDevice11:
+ S60->virtualMousePressedKeys |= QS60Data::RightUp;
+ dx = 1;
+ dy = -1;
+ fakeEvent.iType = TPointerEvent::EMove;
+ break;
+ case EStdKeyDevice12:
+ S60->virtualMousePressedKeys |= QS60Data::RightDown;
+ dx = 1;
+ dy = 1;
+ fakeEvent.iType = TPointerEvent::EMove;
+ break;
+ case EStdKeyDevice13:
+ S60->virtualMousePressedKeys |= QS60Data::LeftDown;
+ dx = -1;
+ dy = 1;
+ fakeEvent.iType = TPointerEvent::EMove;
+ break;
+ case EStdKeyDevice3:
+ // Platform bug. If you start pressing several keys simultaneously (for
+ // example for drag'n'drop), Symbian starts producing spurious up and
+ // down messages for some keys. Therefore, make sure we have a clean slate
+ // of pressed keys before starting a new button press.
+ if (S60->virtualMousePressedKeys & QS60Data::Select) {
+ return EKeyWasConsumed;
+ } else {
+ S60->virtualMousePressedKeys |= QS60Data::Select;
+ fakeEvent.iType = TPointerEvent::EButton1Down;
+ if (m_doubleClickTimer.isValid()
+ && !m_doubleClickTimer.hasExpired(QApplication::doubleClickInterval())) {
+ fakeEvent.iModifiers |= EModifierDoubleClick;
+ m_doubleClickTimer.invalidate();
+ } else {
+ m_doubleClickTimer.start();
+ }
+ }
+ break;
+ }
+ if (dx) {
+ int cdx = S60->virtualMouseAccelDX;
+ //reset accel on change of sign, else double accel
+ if (dx * cdx <= 0)
+ cdx = dx;
+ else
+ cdx *= 4;
+ //cap accelleration
+ if (dx * cdx > S60->virtualMouseMaxAccel)
+ cdx = dx * S60->virtualMouseMaxAccel;
+ //move mouse position
+ x += cdx;
+ S60->virtualMouseAccelDX = cdx;
+ }
+
+ if (dy) {
+ int cdy = S60->virtualMouseAccelDY;
+ if (dy * cdy <= 0)
+ cdy = dy;
+ else
+ cdy *= 4;
+ if (dy * cdy > S60->virtualMouseMaxAccel)
+ cdy = dy * S60->virtualMouseMaxAccel;
+ y += cdy;
+ S60->virtualMouseAccelDY = cdy;
+ }
+ }
+ //clip to screen size (window server allows a sprite hotspot to be outside the screen)
+ int screenNumber = S60->screenNumberForWidget(qwidget);
+ if (x < 0)
+ x = 0;
+ else if (x >= S60->screenWidthInPixelsForScreen[screenNumber])
+ x = S60->screenWidthInPixelsForScreen[screenNumber] - 1;
+ if (y < 0)
+ y = 0;
+ else if (y >= S60->screenHeightInPixelsForScreen[screenNumber])
+ y = S60->screenHeightInPixelsForScreen[screenNumber] - 1;
+ TPoint epos(x, y);
+ TPoint cpos = epos - PositionRelativeToScreen();
+ fakeEvent.iPosition = cpos;
+ fakeEvent.iParentPosition = epos;
+ if(fakeEvent.iType != -1)
+ HandlePointerEvent(fakeEvent);
+ return EKeyWasConsumed;
+ }
+ }
+#endif
+
+ return EKeyWasNotConsumed;
+}
+
+void QSymbianControl::sendInputEvent(QWidget *widget, QInputEvent *inputEvent)
+{
+ switch (inputEvent->type()) {
+ case QEvent::KeyPress:
+ case QEvent::KeyRelease:
+ sendKeyEvent(widget, static_cast<QKeyEvent *>(inputEvent));
+ break;
+ case QEvent::MouseButtonDblClick:
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseMove:
+ sendMouseEvent(widget, static_cast<QMouseEvent *>(inputEvent));
+ break;
+ default:
+ // Shouldn't get here.
+ Q_ASSERT_X(0 == 1, "QSymbianControl::sendInputEvent()", "inputEvent->type() is unknown");
+ break;
+ }
+}
+
+TKeyResponse QSymbianControl::sendKeyEvent(QWidget *widget, QKeyEvent *keyEvent)
+{
+#if !defined(QT_NO_IM) && defined(Q_WS_S60)
+ if (widget && widget->isEnabled() && widget->testAttribute(Qt::WA_InputMethodEnabled)) {
+ QInputContext *qic = widget->inputContext();
+ if (qic && qic->filterEvent(keyEvent))
+ return EKeyWasConsumed;
+ }
+#endif // !defined(QT_NO_IM) && defined(Q_OS_SYMBIAN)
+
+ if (widget && qt_sendSpontaneousEvent(widget, keyEvent))
+ if (keyEvent->isAccepted())
+ return EKeyWasConsumed;
+
+ return EKeyWasNotConsumed;
+}
+
+#if !defined(QT_NO_IM) && defined(Q_WS_S60)
+TCoeInputCapabilities QSymbianControl::InputCapabilities() const
+{
+ QWidget *w = 0;
+
+ if (qwidget->hasFocus())
+ w = qwidget;
+ else
+ w = qwidget->focusWidget();
+
+ QCoeFepInputContext *ic;
+ if (w && w->isEnabled() && w->testAttribute(Qt::WA_InputMethodEnabled)
+ && (ic = qobject_cast<QCoeFepInputContext *>(w->inputContext()))) {
+ return ic->inputCapabilities();
+ } else {
+ return TCoeInputCapabilities(TCoeInputCapabilities::ENone, 0, 0);
+ }
+}
+#endif
+
+void QSymbianControl::Draw(const TRect& controlRect) const
+{
+ // Set flag to avoid calling DrawNow in window surface
+ QWidget *window = qwidget->window();
+ Q_ASSERT(window);
+ QTLWExtra *topExtra = window->d_func()->maybeTopData();
+ Q_ASSERT(topExtra);
+
+ TRect wcontrolRect = translateRectForFixedNativeOrientation(controlRect);
+
+ if (!topExtra->inExpose) {
+ topExtra->inExpose = true;
+ if (!qwidget->isWindow()) {
+ // If we get here, then it means we have a native child window
+ // Since no content should ever be painted to these windows, we
+ // erase them with a transparent brush when they get an expose.
+ CWindowGc &gc = SystemGc();
+ gc.SetBrushColor(TRgb(0, 0, 0, 0));
+ gc.Clear(controlRect);
+ }
+ QRect exposeRect = qt_TRect2QRect(wcontrolRect);
+ qwidget->d_func()->syncBackingStore(exposeRect);
+ topExtra->inExpose = false;
+ }
+
+ QWindowSurface *surface = qwidget->windowSurface();
+ QPaintEngine *engine = surface ? surface->paintDevice()->paintEngine() : NULL;
+
+ if (!engine)
+ return;
+
+ const bool sendNativePaintEvents = qwidget->d_func()->extraData()->receiveNativePaintEvents;
+ if (sendNativePaintEvents) {
+ const QRect r = qt_TRect2QRect(wcontrolRect);
+ QMetaObject::invokeMethod(qwidget, "beginNativePaintEvent", Qt::DirectConnection, Q_ARG(QRect, r));
+ }
+
+ // Map source rectangle into coordinates of the backing store.
+ const QPoint controlBase(controlRect.iTl.iX, controlRect.iTl.iY);
+ const QPoint backingStoreBase = qwidget->mapTo(qwidget->window(), controlBase);
+ const TRect backingStoreRect(TPoint(backingStoreBase.x(), backingStoreBase.y()), controlRect.Size());
+
+ if (engine->type() == QPaintEngine::Raster) {
+ QS60WindowSurface *s60Surface;
+#ifdef QT_GRAPHICSSYSTEM_RUNTIME
+ if (QApplicationPrivate::runtime_graphics_system) {
+ QRuntimeWindowSurface *rtSurface =
+ static_cast<QRuntimeWindowSurface*>(qwidget->windowSurface());
+ s60Surface = static_cast<QS60WindowSurface *>(rtSurface->m_windowSurface.data());
+ } else
+#endif
+ s60Surface = static_cast<QS60WindowSurface *>(qwidget->windowSurface());
+
+ CFbsBitmap *bitmap = s60Surface->symbianBitmap();
+ CWindowGc &gc = SystemGc();
+
+ QWExtra::NativePaintMode nativePaintMode = qwidget->d_func()->extraData()->nativePaintMode;
+ if(qwidget->d_func()->paintOnScreen())
+ nativePaintMode = QWExtra::Disable;
+
+ switch(nativePaintMode) {
+ case QWExtra::Disable:
+ // Do nothing
+ break;
+ case QWExtra::Blit:
+ case QWExtra::BlitWriteAlpha:
+ if (qwidget->d_func()->isOpaque || nativePaintMode == QWExtra::BlitWriteAlpha)
+ gc.SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha);
+ gc.BitBlt(controlRect.iTl, bitmap, backingStoreRect);
+ break;
+ case QWExtra::ZeroFill:
+ if (Window().DisplayMode() == EColor16MA
+ || Window().DisplayMode() == Q_SYMBIAN_ECOLOR16MAP) {
+ gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
+ gc.SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha);
+ gc.SetBrushColor(TRgb::Color16MA(0));
+ gc.Clear(controlRect);
+ } else {
+ gc.SetBrushColor(TRgb(0x000000));
+ gc.Clear(controlRect);
+ };
+ break;
+ default:
+ Q_ASSERT(false);
+ }
+ }
+
+ if (sendNativePaintEvents) {
+ const QRect r = qt_TRect2QRect(wcontrolRect);
+ // The draw ops aren't actually sent to WSERV until the graphics
+ // context is deactivated, which happens in the function calling
+ // this one. We therefore delay the delivery of endNativePaintEvent,
+ // to ensure that drawing has completed by the time the widget
+ // receives the event. Note that, if the widget needs to ensure
+ // that the draw ops have actually been executed into the output
+ // framebuffer, a call to RWsSession::Flush is required in the
+ // endNativePaintEvent implementation.
+ QMetaObject::invokeMethod(qwidget, "endNativePaintEvent", Qt::QueuedConnection, Q_ARG(QRect, r));
+ }
+}
+
+void QSymbianControl::qwidgetResize_helper(const QSize &newSize)
+{
+ QRect cr = qwidget->geometry();
+ QSize oldSize(cr.size());
+ cr.setSize(newSize);
+ qwidget->data->crect = cr;
+ if (qwidget->isVisible()) {
+ QTLWExtra *tlwExtra = qwidget->d_func()->maybeTopData();
+ bool slowResize = qgetenv("QT_SLOW_TOPLEVEL_RESIZE").toInt();
+ if (!slowResize && tlwExtra)
+ tlwExtra->inTopLevelResize = true;
+ QResizeEvent e(newSize, oldSize);
+ qt_sendSpontaneousEvent(qwidget, &e);
+ if (!qwidget->testAttribute(Qt::WA_StaticContents))
+ qwidget->d_func()->syncBackingStore();
+ if (!slowResize && tlwExtra)
+ tlwExtra->inTopLevelResize = false;
+ } else {
+ if (!qwidget->testAttribute(Qt::WA_PendingResizeEvent)) {
+ QResizeEvent *e = new QResizeEvent(newSize, oldSize);
+ QApplication::postEvent(qwidget, e);
+ }
+ }
+}
+
+void QSymbianControl::SizeChanged()
+{
+ CCoeControl::SizeChanged();
+
+ // When FixNativeOrientation had been called, the RWindow/CCoeControl size
+ // and the surface/QWidget size have nothing to do with each other.
+ if (qwidget->d_func()->fixNativeOrientationCalled)
+ return;
+
+ QSize oldSize = qwidget->size();
+ QSize newSize(Size().iWidth, Size().iHeight);
+
+ if (oldSize != newSize) {
+ // Enforce the proper size for fullscreen widgets on the secondary screen.
+ const bool isFullscreen = qwidget->windowState() & Qt::WindowFullScreen;
+ const int screenNumber = S60->screenNumberForWidget(qwidget);
+ if (!m_inExternalScreenOverride && isFullscreen && screenNumber > 0) {
+ int screenWidth = S60->screenWidthInPixelsForScreen[screenNumber];
+ int screenHeight = S60->screenHeightInPixelsForScreen[screenNumber];
+ TSize screenSize(screenWidth, screenHeight);
+ if (screenWidth > 0 && screenHeight > 0 && screenSize != Size()) {
+ m_inExternalScreenOverride = true;
+ SetExtent(TPoint(0, 0), screenSize);
+ return;
+ }
+ }
+
+ qwidgetResize_helper(newSize);
+ }
+
+ m_inExternalScreenOverride = false;
+
+ // CCoeControl::SetExtent calls SizeChanged, but does not call
+ // PositionChanged, so we call it here to ensure that the widget's
+ // position is updated.
+ PositionChanged();
+}
+
+void QSymbianControl::PositionChanged()
+{
+ CCoeControl::PositionChanged();
+
+ QPoint oldPos = qwidget->geometry().topLeft();
+ QPoint newPos(Position().iX, Position().iY);
+
+ if (oldPos != newPos) {
+ QRect cr = qwidget->geometry();
+ cr.moveTopLeft(newPos);
+ qwidget->data->crect = cr;
+ QTLWExtra *top = qwidget->d_func()->maybeTopData();
+ if (top && (qwidget->windowState() & (~Qt::WindowActive)) == Qt::WindowNoState)
+ top->normalGeometry.moveTopLeft(newPos);
+ if (qwidget->isVisible()) {
+ QMoveEvent e(newPos, oldPos);
+ qt_sendSpontaneousEvent(qwidget, &e);
+ } else {
+ QMoveEvent * e = new QMoveEvent(newPos, oldPos);
+ QApplication::postEvent(qwidget, e);
+ }
+ }
+}
+
+void QSymbianControl::FocusChanged(TDrawNow /* aDrawNow */)
+{
+ if (m_ignoreFocusChanged || (qwidget->windowType() & Qt::WindowType_Mask) == Qt::Desktop)
+ return;
+
+#ifdef Q_WS_S60
+ if (S60->splitViewLastWidget)
+ return;
+#endif
+
+ // Popups never get focused, but still receive the FocusChanged when they are hidden.
+ if (QApplicationPrivate::popupWidgets != 0
+ || (qwidget->windowType() & Qt::Popup) == Qt::Popup)
+ return;
+
+ if (IsFocused() && IsVisible()) {
+ if (m_symbianPopupIsOpen) {
+ QWidget *fw = QApplication::focusWidget();
+ if (fw) {
+ QFocusEvent event(QEvent::FocusIn, Qt::PopupFocusReason);
+ QCoreApplication::sendEvent(fw, &event);
+ }
+ m_symbianPopupIsOpen = false;
+ }
+
+ QApplication::setActiveWindow(qwidget->window());
+ qwidget->d_func()->setWindowIcon_sys(true);
+ qwidget->d_func()->setWindowTitle_sys(qwidget->windowTitle());
+#ifdef Q_WS_S60
+ if (qwidget->isWindow())
+ S60->setRecursiveDecorationsVisibility(qwidget, qwidget->windowState());
+#endif
+ } else if (QApplication::activeWindow() == qwidget->window()) {
+ bool focusedControlFound = false;
+ WId winId = 0;
+ for (QWidget *w = qwidget->parentWidget(); w && (winId = w->internalWinId()); w = w->parentWidget()) {
+ if (winId->IsFocused() && winId->IsVisible()) {
+ focusedControlFound = true;
+ break;
+ } else if (w->isWindow())
+ break;
+ }
+ if (!focusedControlFound) {
+ if (CCoeEnv::Static()->AppUi()->IsDisplayingMenuOrDialog() || S60->menuBeingConstructed) {
+ QWidget *fw = QApplication::focusWidget();
+ if (fw) {
+ QFocusEvent event(QEvent::FocusOut, Qt::PopupFocusReason);
+ QCoreApplication::sendEvent(fw, &event);
+ }
+ m_symbianPopupIsOpen = true;
+ return;
+ }
+
+ QApplication::setActiveWindow(0);
+ }
+ }
+ // else { We don't touch the active window unless we were explicitly activated or deactivated }
+}
+
+void QSymbianControl::handleClientAreaChange()
+{
+ const bool cbaVisibilityHint = qwidget->windowFlags() & Qt::WindowSoftkeysVisibleHint;
+ if (qwidget->isFullScreen() && !cbaVisibilityHint) {
+ SetExtentToWholeScreen();
+ } else if (qwidget->isMaximized() || (qwidget->isFullScreen() && cbaVisibilityHint)) {
+ TRect r = static_cast<CEikAppUi*>(S60->appUi())->ClientRect();
+ SetExtent(r.iTl, r.Size());
+ } else if (!qwidget->isMinimized()) { // Normal geometry
+ if (!qwidget->testAttribute(Qt::WA_Resized)) {
+ qwidget->adjustSize();
+ qwidget->setAttribute(Qt::WA_Resized, false); //not a user resize
+ }
+ if (!qwidget->testAttribute(Qt::WA_Moved) && qwidget->windowType() != Qt::Dialog) {
+ TRect r = static_cast<CEikAppUi*>(S60->appUi())->ClientRect();
+ SetPosition(r.iTl);
+ qwidget->setAttribute(Qt::WA_Moved, false); // not really an explicit position
+ }
+ }
+}
+
+bool QSymbianControl::isSplitViewWidget(QWidget *widget) {
+ bool returnValue = true;
+ //Ignore events sent to non-active windows, not visible widgets and not parents of input widget.
+ if (!qwidget->isActiveWindow()
+ || !qwidget->isVisible()
+ || !qwidget->isAncestorOf(widget)) {
+
+ returnValue = false;
+ }
+ return returnValue;
+}
+
+void QSymbianControl::HandleResourceChange(int resourceType)
+{
+ switch (resourceType) {
+ case KSplitViewCloseEvent: //intentional fall-through
+ case KSplitViewOpenEvent: {
+#if !defined(QT_NO_IM) && defined(Q_WS_S60)
+
+ //Fetch widget getting the text input
+ QWidget *widget = QWidget::keyboardGrabber();
+ if (!widget) {
+ if (QApplicationPrivate::popupWidgets) {
+ widget = QApplication::activePopupWidget()->focusWidget();
+ if (!widget) {
+ widget = QApplication::activePopupWidget();
+ }
+ } else {
+ widget = QApplicationPrivate::focus_widget;
+ if (!widget) {
+ widget = qwidget;
+ }
+ }
+ }
+ if (widget) {
+ QCoeFepInputContext *ic = qobject_cast<QCoeFepInputContext *>(widget->inputContext());
+ if (!ic) {
+ ic = qobject_cast<QCoeFepInputContext *>(qApp->inputContext());
+ }
+ if (ic && isSplitViewWidget(widget)) {
+ if (resourceType == KSplitViewCloseEvent) {
+ ic->resetSplitViewWidget();
+ } else {
+ ic->ensureFocusWidgetVisible(widget);
+ }
+ }
+ }
+#endif // !defined(QT_NO_IM) && defined(Q_WS_S60)
+ }
+ break;
+ case KInternalStatusPaneChange:
+ // When status pane is not visible, only handle client area change if status pane was
+ // previously visible, as size changes to hidden status pane should not affect
+ // client area.
+ if (S60->statusPane() && (S60->statusPane()->IsVisible() || m_lastStatusPaneVisibility)) {
+ m_lastStatusPaneVisibility = S60->statusPane()->IsVisible();
+ handleClientAreaChange();
+ }
+ if (IsFocused() && IsVisible()) {
+ qwidget->d_func()->setWindowIcon_sys(true);
+ qwidget->d_func()->setWindowTitle_sys(qwidget->windowTitle());
+ }
+ break;
+ case KUidValueCoeFontChangeEvent:
+ // font change event
+ break;
+#ifdef Q_WS_S60
+ case KEikDynamicLayoutVariantSwitch:
+ {
+ handleClientAreaChange();
+ // Send resize event to trigger desktopwidget workAreaResized signal
+ if (qt_desktopWidget) {
+ QResizeEvent e(qt_desktopWidget->size(), qt_desktopWidget->size());
+ QApplication::sendEvent(qt_desktopWidget, &e);
+ }
+ break;
+ }
+#endif
+ default:
+ break;
+ }
+
+ CCoeControl::HandleResourceChange(resourceType);
+
+}
+void QSymbianControl::CancelLongTapTimer()
+{
+ m_longTapDetector->Cancel();
+}
+
+TTypeUid::Ptr QSymbianControl::MopSupplyObject(TTypeUid id)
+{
+ if (id.iUid == ETypeId)
+ return id.MakePtr(this);
+
+ return CCoeControl::MopSupplyObject(id);
+}
+
+void QSymbianControl::setFocusSafely(bool focus)
+{
+ // The stack hack in here is very unfortunate, but it is the only way to ensure proper
+ // focus in Symbian. If this is not executed, the control which happens to be on
+ // the top of the stack may randomly be assigned focus by Symbian, for example
+ // when creating new windows (specifically in CCoeAppUi::HandleStackChanged()).
+
+ // Close any popups.
+ CEikonEnv::Static()->EikAppUi()->StopDisplayingMenuBar();
+
+ if (focus) {
+ S60->appUi()->RemoveFromStack(this);
+ // Symbian doesn't automatically remove focus from the last focused control, so we need to
+ // remember it and clear focus ourselves.
+ if (lastFocusedControl && lastFocusedControl != this)
+ lastFocusedControl->SetFocus(false);
+ QT_TRAP_THROWING(S60->appUi()->AddToStackL(this,
+ ECoeStackPriorityDefault + 1, ECoeStackFlagStandard)); // Note the + 1
+ lastFocusedControl = this;
+ this->SetFocus(true);
+ } else {
+ S60->appUi()->RemoveFromStack(this);
+ QT_TRAP_THROWING(S60->appUi()->AddToStackL(this,
+ ECoeStackPriorityDefault, ECoeStackFlagStandard));
+ if(this == lastFocusedControl)
+ lastFocusedControl = 0;
+ this->SetFocus(false);
+ }
+}
+
+bool QSymbianControl::isControlActive()
+{
+ return IsActivated() ? true : false;
+}
+
+void QSymbianControl::ensureFixNativeOrientation()
+{
+#if defined(Q_SYMBIAN_SUPPORTS_FIXNATIVEORIENTATION)
+ if (!qwidget->isWindow() || qwidget->windowType() == Qt::Desktop)
+ return;
+ if (S60->screenNumberForWidget(qwidget) > 0)
+ return;
+ const bool isFixed = qwidget->d_func()->fixNativeOrientationCalled;
+ const bool isFixEnabled = qwidget->testAttribute(Qt::WA_SymbianNoSystemRotation);
+ const bool isFullScreen = qwidget->windowState().testFlag(Qt::WindowFullScreen);
+ if (isFullScreen && isFixEnabled) {
+ const bool surfaceBasedGs =
+ QApplicationPrivate::graphics_system_name == QLatin1String("openvg")
+ || QApplicationPrivate::graphics_system_name == QLatin1String("opengl");
+ if (!surfaceBasedGs)
+ qwidget->setAttribute(Qt::WA_SymbianNoSystemRotation, false);
+ if (!isFixed && surfaceBasedGs) {
+ if (Window().FixNativeOrientation() == KErrNone) {
+ qwidget->d_func()->fixNativeOrientationCalled = true;
+ // The EGL window surface is now fixed to the native orientation
+ // of the device, no matter what size we pass when creating it.
+ // Enforce the same size for the QWidget too. For the underlying
+ // CCoeControl and RWindow it is up to the system to resize them
+ // when the standard auto-rotation mechanism is in use, we must not
+ // change that behavior by forcing any size for those. In practice
+ // this means that the QWidget and the underlying native control
+ // dimensions will be out of sync when FixNativeOrientation was
+ // called and the device is turned to the non-native (typically
+ // landscape) orientation. The pointer event handling and certain
+ // functions like Draw() will need to compensate for this.
+ QSize newSize(S60->nativeScreenWidthInPixels, S60->nativeScreenHeightInPixels);
+ if (qwidget->size() != newSize)
+ qwidgetResize_helper(newSize);
+ } else {
+ qwidget->setAttribute(Qt::WA_SymbianNoSystemRotation, false);
+ }
+ }
+ } else if (isFixed) {
+ qwidget->setAttribute(Qt::WA_SymbianNoSystemRotation, false);
+ qwidget->d_func()->fixNativeOrientationCalled = false;
+ qwidget->hide();
+ qwidget->d_func()->create_sys(0, false, true);
+ qwidget->show();
+ }
+#else
+ qwidget->setAttribute(Qt::WA_SymbianNoSystemRotation, false);
+#endif
+}
+
+/*!
+ \typedef QApplication::QS60MainApplicationFactory
+ \since 4.6
+
+ This is a typedef for a pointer to a function with the following
+ signature:
+
+ \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 47
+
+ \sa QApplication::QApplication()
+*/
+
+/*!
+ \since 4.6
+
+ Creates an application using the application factory given in
+ \a factory, and using \a argc command line arguments in \a argv.
+ \a factory can be leaving, but the error will be converted to a
+ standard exception.
+
+ This function is only available on S60.
+*/
+QApplication::QApplication(QApplication::QS60MainApplicationFactory factory, int &argc, char **argv)
+ : QCoreApplication(*new QApplicationPrivate(argc, argv, GuiClient, 0x040000))
+{
+ Q_D(QApplication);
+ S60->s60ApplicationFactory = factory;
+ d->construct();
+}
+
+QApplication::QApplication(QApplication::QS60MainApplicationFactory factory, int &argc, char **argv, int _internal)
+ : QCoreApplication(*new QApplicationPrivate(argc, argv, GuiClient, _internal))
+{
+ Q_D(QApplication);
+ S60->s60ApplicationFactory = factory;
+ d->construct();
+ QApplicationPrivate::app_compile_version = _internal;
+}
+
+void qt_init(QApplicationPrivate * /* priv */, int)
+{
+ if (!CCoeEnv::Static()) {
+ // The S60 framework creates a new trap handler which will render any existing traps
+ // invalid as long as it is active. This means that all code in main() that occurs after
+ // the QApplication construction needs to be surrounded by a new trap, despite having
+ // an outer one already. To avoid this, we save the original trap handler here, and set
+ // it back after the S60 framework is constructed. Then we restore it right before the S60
+ // framework destruction.
+ TTrapHandler *origTrapHandler = User::TrapHandler();
+
+ // The S60 framework has not been initialized. We need to do it.
+ TApaApplicationFactory factory(S60->s60ApplicationFactory ?
+ S60->s60ApplicationFactory : newS60Application);
+ CApaCommandLine* commandLine = q_check_ptr(QCoreApplicationPrivate::symbianCommandLine());
+ if (commandLine) {
+ // After this construction, CEikonEnv will be available from CEikonEnv::Static().
+ // (much like our qApp).
+ QtEikonEnv* coe = new QtEikonEnv;
+ //not using QT_TRAP_THROWING, because coe owns the cleanupstack so it can't be pushed there.
+ TRAPD(err, coe->ConstructAppFromCommandLineL(factory, *commandLine));
+ if(err != KErrNone) {
+ qWarning() << "qt_init: Eikon application construct failed ("
+ << err
+ << "), maybe missing resource file on S60 3.1?";
+ delete coe;
+ qt_symbian_throwIfError(err);
+ }
+ }
+
+ S60->s60InstalledTrapHandler = User::SetTrapHandler(origTrapHandler);
+
+ S60->qtOwnsS60Environment = true;
+ } else {
+ S60->qtOwnsS60Environment = false;
+ }
+
+#ifdef QT_NO_DEBUG
+ if (!qgetenv("QT_S60_AUTO_FLUSH_WSERV").isEmpty())
+#endif
+ S60->wsSession().SetAutoFlush(ETrue);
+
+#ifdef Q_SYMBIAN_WINDOW_SIZE_CACHE
+ TRAP_IGNORE(S60->wsSession().EnableWindowSizeCacheL());
+#endif
+
+ S60->updateScreenSize();
+
+
+ TDisplayMode mode = S60->screenDevice()->DisplayMode();
+ S60->screenDepth = TDisplayModeUtils::NumDisplayModeBitsPerPixel(mode);
+
+ //NB: RWsSession::GetColorModeList tells you what window modes are supported,
+ //not what bitmap formats.
+ if(QSysInfo::symbianVersion() == QSysInfo::SV_9_2)
+ S60->supportsPremultipliedAlpha = 0;
+ else
+ S60->supportsPremultipliedAlpha = 1;
+
+ RProcess me;
+ TSecureId securId = me.SecureId();
+ S60->uid = securId.operator TUid();
+
+ // enable focus events - used to re-enable mouse after focus changed between mouse and non mouse app,
+ // and for dimming behind modal windows
+ S60->windowGroup().EnableFocusChangeEvents();
+
+ //Check if mouse interaction is supported (either EMouse=1 in the HAL, or EMachineUID is one of the phones known to support this)
+ const TInt KMachineUidSamsungI8510 = 0x2000C51E;
+ // HAL::Get(HALData::EPen, TInt& result) may set 'result' to 1 on some 3.1 systems (e.g. N95).
+ // But we know that S60 systems below 5.0 did not support touch.
+ static const bool touchIsUnsupportedOnSystem =
+ QSysInfo::s60Version() == QSysInfo::SV_S60_3_1
+ || QSysInfo::s60Version() == QSysInfo::SV_S60_3_2;
+ TInt machineUID;
+ TInt mouse;
+ TInt touch;
+ TInt err;
+ err = HAL::Get(HALData::EMouse, mouse);
+ if (err != KErrNone)
+ mouse = 0;
+ err = HAL::Get(HALData::EMachineUid, machineUID);
+ if (err != KErrNone)
+ machineUID = 0;
+ err = HAL::Get(HALData::EPen, touch);
+ if (err != KErrNone || touchIsUnsupportedOnSystem)
+ touch = 0;
+#ifdef __WINS__
+ if(QSysInfo::symbianVersion() <= QSysInfo::SV_9_4) {
+ //for symbian SDK emulator, force values to match typical devices.
+ mouse = 0;
+ touch = touchIsUnsupportedOnSystem ? 0 : 1;
+ }
+#endif
+ if (mouse || machineUID == KMachineUidSamsungI8510) {
+ S60->hasTouchscreen = false;
+ S60->virtualMouseRequired = false;
+ }
+ else if (!touch) {
+ S60->hasTouchscreen = false;
+ S60->virtualMouseRequired = true;
+ }
+ else {
+ S60->hasTouchscreen = true;
+ S60->virtualMouseRequired = false;
+ }
+
+ S60->avkonComponentsSupportTransparency = false;
+ S60->menuBeingConstructed = false;
+
+#ifdef Q_WS_S60
+ TUid KCRUidAvkon = { 0x101F876E };
+ TUint32 KAknAvkonTransparencyEnabled = 0x0000000D;
+
+ CRepository* repository = 0;
+ TRAP(err, repository = CRepository::NewL(KCRUidAvkon));
+
+ if(err == KErrNone) {
+ TInt value = 0;
+ err = repository->Get(KAknAvkonTransparencyEnabled, value);
+ if(err == KErrNone) {
+ S60->avkonComponentsSupportTransparency = (value==1) ? true : false;
+ }
+ }
+ delete repository;
+ repository = 0;
+#endif
+
+ qt_keymapper_private()->updateInputLanguage();
+
+#ifdef QT_KEYPAD_NAVIGATION
+ if (touch) {
+ QApplicationPrivate::navigationMode = Qt::NavigationModeNone;
+ } else {
+ QApplicationPrivate::navigationMode = Qt::NavigationModeKeypadDirectional;
+ }
+#endif
+
+#ifndef QT_NO_CURSOR
+ //Check if window server pointer cursors are supported or not
+#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
+ //In generic binary, use the HAL and OS version
+ //Any other known good phones should be added here.
+ if (machineUID == KMachineUidSamsungI8510 || (QSysInfo::symbianVersion() != QSysInfo::SV_9_4
+ && QSysInfo::symbianVersion() != QSysInfo::SV_9_3 && QSysInfo::symbianVersion()
+ != QSysInfo::SV_9_2)) {
+ S60->brokenPointerCursors = false;
+ qt_symbian_setWindowGroupCursor(Qt::ArrowCursor, S60->windowGroup());
+ }
+ else
+ S60->brokenPointerCursors = true;
+#endif
+
+ if (S60->mouseInteractionEnabled) {
+#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
+ if (S60->brokenPointerCursors) {
+ qt_symbian_set_pointer_sprite(Qt::ArrowCursor);
+ qt_symbian_show_pointer_sprite();
+ }
+ else
+#endif
+ S60->wsSession().SetPointerCursorMode(EPointerCursorNormal);
+ }
+#endif
+
+ QFont systemFont;
+ systemFont.setFamily(systemFont.defaultFamily());
+ QApplicationPrivate::setSystemFont(systemFont);
+
+ QObject::connect(qApp, SIGNAL(aboutToQuit()), qApp, SLOT(_q_aboutToQuit()));
+
+#ifdef Q_SYMBIAN_SEMITRANSPARENT_BG_SURFACE
+ QApplicationPrivate::instance()->useTranslucentEGLSurfaces = true;
+
+ const TUid KIvePropertyCat = {0x2726beef};
+ enum TIvePropertyChipType {
+ EVCBCM2727B1 = 0x00000000,
+ EVCBCM2763A0 = 0x04000100,
+ EVCBCM2763B0 = 0x04000102,
+ EVCBCM2763C0 = 0x04000103,
+ EVCBCM2763C1 = 0x04000104,
+ EVCBCMUnknown = 0x7fffffff
+ };
+
+ TInt chipType = EVCBCMUnknown;
+ if (RProperty::Get(KIvePropertyCat, 0 /*chip type*/, chipType) == KErrNone) {
+ if (chipType == EVCBCM2727B1) {
+ // We have only 32MB GPU memory. Use raster surfaces
+ // for transparent TLWs.
+ QApplicationPrivate::instance()->useTranslucentEGLSurfaces = false;
+ }
+ } else {
+ QApplicationPrivate::instance()->useTranslucentEGLSurfaces = false;
+ }
+ if (QApplicationPrivate::graphics_system_name == QLatin1String("raster"))
+ QApplicationPrivate::instance()->useTranslucentEGLSurfaces = false;
+#else
+ QApplicationPrivate::instance()->useTranslucentEGLSurfaces = false;
+#endif
+/*
+ ### Commented out for now as parameter handling not needed in SOS(yet). Code below will break testlib with -o flag
+ int argc = priv->argc;
+ char **argv = priv->argv;
+
+ // Get command line params
+ int j = argc ? 1 : 0;
+ for (int i=1; i<argc; i++) {
+ if (argv[i] && *argv[i] != '-') {
+ argv[j++] = argv[i];
+ continue;
+ }
+
+#if defined(QT_DEBUG)
+ if (qstrcmp(argv[i], "-nograb") == 0)
+ appNoGrab = !appNoGrab;
+ else
+#endif // QT_DEBUG
+ ;
+ }
+*/
+
+ // Register WId with the metatype system. This is to enable
+ // QWidgetPrivate::create_sys to used delayed slot invocation in order
+ // to destroy WId objects during reparenting.
+ qRegisterMetaType<WId>("WId");
+}
+
+#ifdef QT_NO_FREETYPE
+extern void qt_cleanup_symbianFontDatabase(); // qfontdatabase_s60.cpp
+#endif
+
+/*****************************************************************************
+ qt_cleanup() - cleans up when the application is finished
+ *****************************************************************************/
+void qt_cleanup()
+{
+#ifdef Q_WS_S60
+ S60->setButtonGroupContainer(0);
+#endif
+ if(qt_S60Beep) {
+ delete qt_S60Beep;
+ qt_S60Beep = 0;
+ }
+ QFontCache::cleanup(); // Has to happen now, since QFontEngineS60 has FBS handles
+ QPixmapCache::clear(); // Has to happen now, since QS60PlatformPixmap has FBS handles
+
+#ifdef QT_NO_FREETYPE
+ qt_cleanup_symbianFontDatabase();
+#endif
+// S60 structure and window server session are freed in eventdispatcher destructor as they are needed there
+
+ // It's important that this happens here, before the event dispatcher gets
+ // deleted, because the input context needs the event loop one last time before
+ // it dies.
+ delete QApplicationPrivate::inputContext;
+ QApplicationPrivate::inputContext = 0;
+
+ //Change mouse pointer back
+ S60->wsSession().SetPointerCursorMode(EPointerCursorNone);
+
+#ifdef Q_WS_S60
+ // Clear CBA
+ CEikonEnv::Static()->AppUiFactory()->SwapButtonGroup(0);
+ delete S60->buttonGroupContainer();
+ S60->setButtonGroupContainer(0);
+#endif
+
+ // Call EndFullScreen() to prevent confusing the system effect state machine.
+ qt_endFullScreenEffect();
+
+ if (S60->qtOwnsS60Environment) {
+ // Restore the S60 framework trap handler. See qt_init().
+ User::SetTrapHandler(S60->s60InstalledTrapHandler);
+
+ CEikonEnv* coe = CEikonEnv::Static();
+ coe->PrepareToExit();
+ // The CEikonEnv itself is destroyed in here.
+ coe->DestroyEnvironment();
+ }
+}
+
+void QApplicationPrivate::initializeWidgetPaletteHash()
+{
+ // TODO: Implement QApplicationPrivate::initializeWidgetPaletteHash()
+ // Possibly a task fot the S60Style guys
+}
+
+void QApplicationPrivate::createEventDispatcher()
+{
+ Q_Q(QApplication);
+ eventDispatcher = new QEventDispatcherS60(q);
+}
+
+QString QApplicationPrivate::appName() const
+{
+ return QCoreApplicationPrivate::appName();
+}
+
+bool QApplicationPrivate::modalState()
+{
+ return app_do_modal;
+}
+
+void QApplicationPrivate::enterModal_sys(QWidget *widget)
+{
+#ifdef Q_SYMBIAN_TRANSITION_EFFECTS
+ S60->wsSession().SendEffectCommand(ETfxCmdAppModalModeEnter);
+#endif
+ if (widget) {
+ static_cast<QSymbianControl *>(widget->effectiveWinId())->FadeBehindPopup(ETrue);
+ // Modal partial screen dialogs (like queries) capture pointer events.
+ // ### FixMe: Add specialized behaviour for fullscreen modal dialogs
+ widget->effectiveWinId()->SetGloballyCapturing(ETrue);
+ widget->effectiveWinId()->SetPointerCapture(ETrue);
+ }
+ if (!qt_modal_stack)
+ qt_modal_stack = new QWidgetList;
+ qt_modal_stack->insert(0, widget);
+ app_do_modal = true;
+}
+
+void QApplicationPrivate::leaveModal_sys(QWidget *widget)
+{
+#ifdef Q_SYMBIAN_TRANSITION_EFFECTS
+ S60->wsSession().SendEffectCommand(ETfxCmdAppModalModeExit);
+#endif
+ if (widget) {
+ static_cast<QSymbianControl *>(widget->effectiveWinId())->FadeBehindPopup(EFalse);
+ // ### FixMe: Add specialized behaviour for fullscreen modal dialogs
+ widget->effectiveWinId()->SetGloballyCapturing(EFalse);
+ widget->effectiveWinId()->SetPointerCapture(EFalse);
+ }
+ if (qt_modal_stack && qt_modal_stack->removeAll(widget)) {
+ if (qt_modal_stack->isEmpty()) {
+ delete qt_modal_stack;
+ qt_modal_stack = 0;
+ }
+ }
+ app_do_modal = qt_modal_stack != 0;
+}
+
+void QApplicationPrivate::openPopup(QWidget *popup)
+{
+ if (popup && qobject_cast<QComboBox *>(popup->parentWidget()))
+ static_cast<QSymbianControl *>(popup->effectiveWinId())->FadeBehindPopup(ETrue);
+
+ if (!QApplicationPrivate::popupWidgets)
+ QApplicationPrivate::popupWidgets = new QWidgetList;
+ QApplicationPrivate::popupWidgets->append(popup);
+
+ // Cancel focus widget pointer capture and long tap timer
+ if (QApplication::focusWidget()) {
+ static_cast<QSymbianControl*>(QApplication::focusWidget()->effectiveWinId())->CancelLongTapTimer();
+ QApplication::focusWidget()->effectiveWinId()->SetPointerCapture(false);
+ }
+
+ if (!qt_nograb()) {
+ // Cancel pointer capture and long tap timer for earlier popup
+ int popupCount = QApplicationPrivate::popupWidgets->count();
+ if (popupCount > 1) {
+ QWidget* prevPopup = QApplicationPrivate::popupWidgets->at(popupCount-2);
+ static_cast<QSymbianControl*>(prevPopup->effectiveWinId())->CancelLongTapTimer();
+ prevPopup->effectiveWinId()->SetPointerCapture(false);
+ }
+
+ // Enable pointer capture for this (topmost) popup
+ Q_ASSERT(popup->testAttribute(Qt::WA_WState_Created));
+ WId id = popup->effectiveWinId();
+ id->SetPointerCapture(true);
+ }
+
+ // popups are not focus-handled by the window system (the first
+ // popup grabbed the keyboard), so we have to do that manually: A
+ // new popup gets the focus
+ QWidget *fw = popup->focusWidget();
+ if (fw) {
+ fw->setFocus(Qt::PopupFocusReason);
+ } else if (QApplicationPrivate::popupWidgets->count() == 1) { // this was the first popup
+ fw = QApplication::focusWidget();
+ if (fw) {
+ QFocusEvent e(QEvent::FocusOut, Qt::PopupFocusReason);
+ q_func()->sendEvent(fw, &e);
+ }
+ }
+}
+
+void QApplicationPrivate::closePopup(QWidget *popup)
+{
+ if (popup && qobject_cast<QComboBox *>(popup->parentWidget()))
+ static_cast<QSymbianControl *>(popup->effectiveWinId())->FadeBehindPopup(EFalse);
+
+ if (!QApplicationPrivate::popupWidgets)
+ return;
+ QApplicationPrivate::popupWidgets->removeAll(popup);
+
+ // Cancel pointer capture and long tap for this popup
+ WId id = popup->effectiveWinId();
+ id->SetPointerCapture(false);
+ static_cast<QSymbianControl*>(id)->CancelLongTapTimer();
+
+ if (QApplicationPrivate::popupWidgets->isEmpty()) { // this was the last popup
+ delete QApplicationPrivate::popupWidgets;
+ QApplicationPrivate::popupWidgets = 0;
+ if (!qt_nograb()) { // grabbing not disabled
+ Q_ASSERT(popup->testAttribute(Qt::WA_WState_Created));
+ if (QWidgetPrivate::mouseGrabber != 0)
+ QWidgetPrivate::mouseGrabber->grabMouse();
+
+ if (QWidgetPrivate::keyboardGrabber != 0)
+ QWidgetPrivate::keyboardGrabber->grabKeyboard();
+
+ QWidget *fw = QApplicationPrivate::active_window ? QApplicationPrivate::active_window->focusWidget()
+ : q_func()->focusWidget();
+ if (fw) {
+ if(fw->window()->isModal()) // restore pointer capture for modal window
+ fw->effectiveWinId()->SetPointerCapture(true);
+
+ if (fw != q_func()->focusWidget()) {
+ fw->setFocus(Qt::PopupFocusReason);
+ } else {
+ QFocusEvent e(QEvent::FocusIn, Qt::PopupFocusReason);
+ q_func()->sendEvent(fw, &e);
+ }
+ }
+ }
+ } else {
+
+ // popups are not focus-handled by the window system (the
+ // first popup grabbed the keyboard), so we have to do that
+ // manually: A popup was closed, so the previous popup gets
+ // the focus.
+ QWidget* aw = QApplicationPrivate::popupWidgets->last();
+ if (QWidget *fw = QApplication::focusWidget()) {
+ QFocusEvent e(QEvent::FocusOut, Qt::PopupFocusReason);
+ q_func()->sendEvent(fw, &e);
+ }
+
+ // Enable pointer capture for previous popup
+ if (aw) {
+ aw->effectiveWinId()->SetPointerCapture(true);
+ }
+ }
+}
+
+QWidget * QApplication::topLevelAt(QPoint const& point)
+{
+ QWidget *found = 0;
+ int lowestZ = INT_MAX;
+ QWidgetList list = QApplication::topLevelWidgets();
+ for (int i = 0; i < list.count(); ++i) {
+ QWidget *widget = list.at(i);
+ if (widget->isVisible() && !(widget->windowType() == Qt::Desktop)) {
+ Q_ASSERT(widget->testAttribute(Qt::WA_WState_Created));
+ if (widget->geometry().adjusted(0,0,1,1).contains(point)) {
+ // At this point we know there is a Qt widget under the point.
+ // Now we need to make sure it is the top most in the z-order.
+ RDrawableWindow *const window = widget->effectiveWinId()->DrawableWindow();
+ int z = window->OrdinalPosition();
+ if (z < lowestZ) {
+ lowestZ = z;
+ found = widget;
+ }
+ }
+ }
+ }
+ return found;
+}
+
+void QApplication::alert(QWidget * /* widget */, int /* duration */)
+{
+ // TODO: Implement QApplication::alert(QWidget *widget, int duration)
+}
+
+int QApplication::doubleClickInterval()
+{
+ TTimeIntervalMicroSeconds32 us;
+ TInt distance;
+ S60->wsSession().GetDoubleClickSettings(us, distance);
+ return (us.Int() / 1000);
+}
+
+void QApplication::setDoubleClickInterval(int ms)
+{
+ TTimeIntervalMicroSeconds32 newUs( ms * 1000);
+ TTimeIntervalMicroSeconds32 us;
+ TInt distance;
+ S60->wsSession().GetDoubleClickSettings(us, distance);
+ if (us != newUs)
+ S60->wsSession().SetDoubleClick(newUs, distance);
+}
+
+int QApplication::keyboardInputInterval()
+{
+ return QApplicationPrivate::keyboard_input_time;
+}
+
+void QApplication::setKeyboardInputInterval(int ms)
+{
+ QApplicationPrivate::keyboard_input_time = ms;
+}
+
+int QApplication::cursorFlashTime()
+{
+ return QApplicationPrivate::cursor_flash_time;
+}
+
+void QApplication::setCursorFlashTime(int msecs)
+{
+ QApplicationPrivate::cursor_flash_time = msecs;
+}
+
+void QApplication::beep()
+{
+ if (!qt_S60Beep) {
+ TInt frequency = 880;
+ TTimeIntervalMicroSeconds duration(500000);
+ TRAP_IGNORE(qt_S60Beep=QS60Beep::NewL(frequency, duration));
+ }
+ if (qt_S60Beep)
+ qt_S60Beep->Play();
+}
+
+static inline bool callSymbianEventFilters(const QSymbianEvent *event)
+{
+ long unused;
+ return qApp->filterEvent(const_cast<QSymbianEvent *>(event), &unused);
+}
+
+/*!
+ \warning This function is only available on Symbian.
+ \since 4.6
+
+ This function processes an individual Symbian event
+ \a event. It returns 1 if the event was handled, 0 if
+ the \a event was not handled, and -1 if the event was
+ not handled because the event is not known to Qt.
+ */
+
+int QApplication::symbianProcessEvent(const QSymbianEvent *event)
+{
+ Q_D(QApplication);
+
+ QScopedLoopLevelCounter counter(d->threadData);
+
+ if (d->eventDispatcher->filterEvent(const_cast<QSymbianEvent *>(event)))
+ return 1;
+
+ QWidget *w = qApp ? qApp->focusWidget() : 0;
+ if (w) {
+ QInputContext *ic = w->inputContext();
+ if (ic && ic->symbianFilterEvent(w, event))
+ return 1;
+ }
+
+ if (symbianEventFilter(event))
+ return 1;
+
+ switch (event->type()) {
+ case QSymbianEvent::WindowServerEvent:
+ return d->symbianProcessWsEvent(event);
+ case QSymbianEvent::CommandEvent:
+ return d->symbianHandleCommand(event);
+ case QSymbianEvent::ResourceChangeEvent:
+ return d->symbianResourceChange(event);
+ default:
+ return -1;
+ }
+}
+
+int QApplicationPrivate::symbianProcessWsEvent(const QSymbianEvent *symbianEvent)
+{
+ // Qt event handling. Handle some events regardless of if the handle is in our
+ // widget map or not.
+ const TWsEvent *event = symbianEvent->windowServerEvent();
+ CCoeControl* control = reinterpret_cast<CCoeControl*>(event->Handle());
+ const bool controlInMap = QWidgetPrivate::mapper && QWidgetPrivate::mapper->contains(control);
+ switch (event->Type()) {
+ case EEventPointerEnter:
+ if (controlInMap) {
+ callSymbianEventFilters(symbianEvent);
+ return 1; // Qt::Enter will be generated in HandlePointerL
+ }
+ break;
+ case EEventPointerExit:
+ if (controlInMap) {
+ if (callSymbianEventFilters(symbianEvent))
+ return 1;
+ if (S60) {
+ // mouseEvent outside our window, send leave event to last focused widget
+ QMouseEvent mEvent(QEvent::Leave, S60->lastPointerEventPos, S60->lastCursorPos,
+ Qt::NoButton, QApplicationPrivate::mouse_buttons, Qt::NoModifier);
+ if (S60->lastPointerEventTarget)
+ qt_sendSpontaneousEvent(S60->lastPointerEventTarget,&mEvent);
+ S60->lastPointerEventTarget = 0;
+ }
+ return 1;
+ }
+ break;
+ case EEventScreenDeviceChanged: // fallthrough
+#if defined(Q_SYMBIAN_SUPPORTS_MULTIPLE_SCREENS)
+ case EEventDisplayChanged:
+#endif
+ if (callSymbianEventFilters(symbianEvent))
+ return 1;
+ if (S60)
+ S60->updateScreenSize();
+ if (qt_desktopWidget) {
+ QSize oldSize = qt_desktopWidget->size();
+ qt_desktopWidget->data->crect.setWidth(S60->screenWidthInPixels);
+ qt_desktopWidget->data->crect.setHeight(S60->screenHeightInPixels);
+ QResizeEvent e(qt_desktopWidget->size(), oldSize);
+ QApplication::sendEvent(qt_desktopWidget, &e);
+ }
+ return 0; // Propagate to CONE
+ case EEventWindowVisibilityChanged:
+ if (controlInMap) {
+ if (callSymbianEventFilters(symbianEvent))
+ return 1;
+ const TWsVisibilityChangedEvent *visChangedEvent = event->VisibilityChanged();
+ if (visChangedEvent->iFlags & TWsVisibilityChangedEvent::ENotVisible)
+ S60->controlVisibilityChanged(control, false);
+ else if (visChangedEvent->iFlags & TWsVisibilityChangedEvent::EPartiallyVisible)
+ S60->controlVisibilityChanged(control, true);
+ return 1;
+ }
+ break;
+ case EEventFocusGained:
+ if (callSymbianEventFilters(symbianEvent))
+ return 1;
+#ifndef QT_NO_CURSOR
+ //re-enable mouse interaction
+ if (S60->mouseInteractionEnabled) {
+#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
+ if (S60->brokenPointerCursors)
+ qt_symbian_show_pointer_sprite();
+ else
+#endif
+ S60->wsSession().SetPointerCursorMode(EPointerCursorNormal);
+ }
+#endif
+#ifdef QT_SOFTKEYS_ENABLED
+ if (!CEikonEnv::Static()->EikAppUi()->IsDisplayingMenuOrDialog())
+ QSoftKeyManager::updateSoftKeys();
+#endif
+ break;
+ case EEventFocusLost:
+ if (callSymbianEventFilters(symbianEvent))
+ return 1;
+#ifndef QT_NO_CURSOR
+ //disable mouse as may be moving to application that does not support it
+ if (S60->mouseInteractionEnabled) {
+#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
+ if (S60->brokenPointerCursors)
+ qt_symbian_hide_pointer_sprite();
+ else
+#endif
+ S60->wsSession().SetPointerCursorMode(EPointerCursorNone);
+ }
+#endif
+ break;
+ case KGoomMemoryLowEvent:
+#ifdef QT_DEBUG
+ qDebug() << "QApplicationPrivate::symbianProcessWsEvent - KGoomMemoryLowEvent";
+#endif
+ if (callSymbianEventFilters(symbianEvent))
+ return 1;
+#ifdef QT_GRAPHICSSYSTEM_RUNTIME
+ if(QApplicationPrivate::runtime_graphics_system) {
+ bool switchToSwRendering(false);
+
+ foreach (QWidget *w, QApplication::topLevelWidgets()) {
+ if(w->d_func()->topData()->backingStore) {
+ switchToSwRendering = true;
+ break;
+ }
+ }
+
+ if (switchToSwRendering) {
+ QRuntimeGraphicsSystem *gs =
+ static_cast<QRuntimeGraphicsSystem*>(QApplicationPrivate::graphics_system);
+ gs->setGraphicsSystem(QLatin1String("raster"));
+ }
+ }
+#endif
+ break;
+ case KGoomMemoryGoodEvent:
+#ifdef QT_DEBUG
+ qDebug() << "QApplicationPrivate::symbianProcessWsEvent - KGoomMemoryGoodEvent";
+#endif
+ if (callSymbianEventFilters(symbianEvent))
+ return 1;
+#ifdef QT_GRAPHICSSYSTEM_RUNTIME
+ if(QApplicationPrivate::runtime_graphics_system) {
+ QRuntimeGraphicsSystem *gs =
+ static_cast<QRuntimeGraphicsSystem*>(QApplicationPrivate::graphics_system);
+ gs->setGraphicsSystem(QLatin1String("openvg"));
+ }
+#endif
+ break;
+#ifdef Q_SYMBIAN_SUPPORTS_SURFACES
+ case EEventUser:
+ {
+ // GOOM is looking for candidates to kill so indicate that we are
+ // capable of cleaning up by handling this event
+ TInt32 *data = reinterpret_cast<TInt32 *>(event->EventData());
+ if (data[0] == EApaSystemEventShutdown && data[1] == KGoomMemoryLowEvent)
+ return 1;
+ }
+ break;
+#endif
+
+#ifdef Q_WS_S60
+ case KEikInputLanguageChange:
+ qt_keymapper_private()->updateInputLanguage();
+ break;
+#endif
+
+ default:
+ break;
+ }
+
+ if (!controlInMap)
+ return -1;
+
+ return 0;
+}
+
+/*!
+ \warning This virtual function is only available on Symbian.
+ \since 4.6
+
+ If you create an application that inherits QApplication and reimplement
+ this function, you get direct access to events that the are received
+ from Symbian. The events are passed in the \a event parameter.
+
+ Return true if you want to stop the event from being processed. Return
+ false for normal event dispatching. The default implementation returns
+ false, and does nothing with \a event.
+ */
+bool QApplication::symbianEventFilter(const QSymbianEvent *event)
+{
+ Q_UNUSED(event);
+ return false;
+}
+
+/*!
+ \warning This function is only available on Symbian.
+ \since 4.6
+
+ Handles \a{command}s which are typically handled by
+ CAknAppUi::HandleCommandL(). Qts Ui integration into Symbian is
+ partially achieved by deriving from CAknAppUi. Currently, exit,
+ menu and softkey commands are handled.
+
+ \sa s60EventFilter(), s60ProcessEvent()
+*/
+int QApplicationPrivate::symbianHandleCommand(const QSymbianEvent *symbianEvent)
+{
+ Q_Q(QApplication);
+ int ret = 0;
+
+ if (callSymbianEventFilters(symbianEvent))
+ return 1;
+
+ int command = symbianEvent->command();
+
+ switch (command) {
+#ifdef Q_WS_S60
+ case EAknSoftkeyExit: {
+ QCloseEvent ev;
+ QApplication::sendSpontaneousEvent(q, &ev);
+ if (ev.isAccepted()) {
+ q->quit();
+ ret = 1;
+ }
+ break;
+ }
+#endif
+ case EEikCmdExit:
+ q->quit();
+ ret = 1;
+ break;
+ default:
+#ifdef Q_WS_S60
+ bool handled = QSoftKeyManager::handleCommand(command);
+ if (handled)
+ ret = 1;
+ else
+ ret = QMenuBarPrivate::symbianCommands(command);
+#endif
+ break;
+ }
+
+ return ret;
+}
+
+/*!
+ \warning This function is only available on Symbian.
+ \since 4.6
+
+ Handles the resource change specified by \a type.
+
+ Currently, KEikDynamicLayoutVariantSwitch and
+ KAknsMessageSkinChange are handled.
+ */
+int QApplicationPrivate::symbianResourceChange(const QSymbianEvent *symbianEvent)
+{
+ int ret = 0;
+
+ int type = symbianEvent->resourceChangeType();
+
+ switch (type) {
+#ifdef Q_WS_S60
+ case KEikDynamicLayoutVariantSwitch:
+ {
+ if (callSymbianEventFilters(symbianEvent))
+ return 1;
+ if (S60)
+ S60->updateScreenSize();
+
+#ifndef QT_NO_STYLE_S60
+ QS60Style *s60Style = 0;
+
+#ifndef QT_NO_STYLE_STYLESHEET
+ QStyleSheetStyle *proxy = qobject_cast<QStyleSheetStyle*>(QApplication::style());
+ if (proxy)
+ s60Style = qobject_cast<QS60Style*>(proxy->baseStyle());
+ else
+#endif
+ s60Style = qobject_cast<QS60Style*>(QApplication::style());
+
+ if (s60Style) {
+ s60Style->d_func()->handleDynamicLayoutVariantSwitch();
+ ret = 1;
+ }
+#endif
+ }
+ break;
+
+#ifndef QT_NO_STYLE_S60
+ case KAknsMessageSkinChange:
+ if (callSymbianEventFilters(symbianEvent))
+ return 1;
+ if (QS60Style *s60Style = qobject_cast<QS60Style*>(QApplication::style())) {
+ s60Style->d_func()->handleSkinChange();
+ ret = 1;
+ }
+ break;
+#endif
+#endif // Q_WS_S60
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+#ifndef QT_NO_WHEELEVENT
+int QApplication::wheelScrollLines()
+{
+ return QApplicationPrivate::wheel_scroll_lines;
+}
+
+void QApplication::setWheelScrollLines(int n)
+{
+ QApplicationPrivate::wheel_scroll_lines = n;
+}
+#endif //QT_NO_WHEELEVENT
+
+bool QApplication::isEffectEnabled(Qt::UIEffect /* effect */)
+{
+ // TODO: Implement QApplication::isEffectEnabled(Qt::UIEffect effect)
+ return false;
+}
+
+void QApplication::setEffectEnabled(Qt::UIEffect /* effect */, bool /* enable */)
+{
+ // TODO: Implement QApplication::setEffectEnabled(Qt::UIEffect effect, bool enable)
+}
+
+TUint QApplicationPrivate::resolveS60ScanCode(TInt scanCode, TUint keysym)
+{
+ if (!scanCode)
+ return keysym;
+
+ QApplicationPrivate *d = QApplicationPrivate::instance();
+
+ if (keysym) {
+ // If keysym is specified, cache it.
+ d->scanCodeCache.insert(scanCode, keysym);
+ return keysym;
+ } else {
+ // If not, retrieve the cached version.
+ return d->scanCodeCache[scanCode];
+ }
+}
+
+void QApplicationPrivate::initializeMultitouch_sys()
+{
+#ifdef QT_SYMBIAN_SUPPORTS_ADVANCED_POINTER
+ if (HAL::Get(HALData::EPointer3DPressureSupported, pressureSupported) != KErrNone)
+ pressureSupported = 0;
+ if (HAL::Get(HALData::EPointer3DMaxPressure, maxTouchPressure) != KErrNone)
+ maxTouchPressure = KMaxTInt;
+#else
+ pressureSupported = 0;
+ maxTouchPressure = KMaxTInt;
+#endif
+}
+
+void QApplicationPrivate::cleanupMultitouch_sys()
+{ }
+
+#ifndef QT_NO_SESSIONMANAGER
+QSessionManager::QSessionManager(QApplication * /* app */, QString & /* id */, QString& /* key */)
+{
+
+}
+
+QSessionManager::~QSessionManager()
+{
+
+}
+
+bool QSessionManager::allowsInteraction()
+{
+ return false;
+}
+
+void QSessionManager::cancel()
+{
+
+}
+#endif //QT_NO_SESSIONMANAGER
+
+#ifdef QT_KEYPAD_NAVIGATION
+/*
+ * Show/Hide the mouse cursor depending on phone type and chosen mode
+ */
+void QApplicationPrivate::setNavigationMode(Qt::NavigationMode mode)
+{
+#ifndef QT_NO_CURSOR
+ const bool wasCursorOn = (QApplicationPrivate::navigationMode == Qt::NavigationModeCursorAuto
+ && !S60->hasTouchscreen)
+ || QApplicationPrivate::navigationMode == Qt::NavigationModeCursorForceVisible;
+ const bool isCursorOn = (mode == Qt::NavigationModeCursorAuto
+ && !S60->hasTouchscreen)
+ || mode == Qt::NavigationModeCursorForceVisible;
+
+ if (!wasCursorOn && isCursorOn) {
+ //Show the cursor, when changing from another mode to cursor mode
+ qt_symbian_set_cursor_visible(true);
+ }
+ else if (wasCursorOn && !isCursorOn) {
+ //Hide the cursor, when leaving cursor mode
+ qt_symbian_set_cursor_visible(false);
+ }
+#endif
+ QApplicationPrivate::navigationMode = mode;
+}
+#endif
+
+#ifndef QT_NO_CURSOR
+/*****************************************************************************
+ QApplication cursor stack
+ *****************************************************************************/
+
+void QApplication::setOverrideCursor(const QCursor &cursor)
+{
+ qApp->d_func()->cursor_list.prepend(cursor);
+ qt_symbian_setGlobalCursor(cursor);
+}
+
+void QApplication::restoreOverrideCursor()
+{
+ if (qApp->d_func()->cursor_list.isEmpty())
+ return;
+ qApp->d_func()->cursor_list.removeFirst();
+
+ if (!qApp->d_func()->cursor_list.isEmpty()) {
+ qt_symbian_setGlobalCursor(qApp->d_func()->cursor_list.first());
+ }
+ else {
+ //determine which widget has focus
+ QWidget *w = QApplication::widgetAt(QCursor::pos());
+#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
+ if (S60->brokenPointerCursors) {
+ qt_symbian_set_pointer_sprite(w ? w->cursor() : Qt::ArrowCursor);
+ }
+ else
+#endif
+ {
+ //because of the internals of window server, we need to force the cursor
+ //to be set in all child windows too, otherwise when the cursor is over
+ //the child window it may show a widget cursor or arrow cursor instead,
+ //depending on construction order.
+ QListIterator<WId> iter(QWidgetPrivate::mapper->uniqueKeys());
+ while (iter.hasNext()) {
+ CCoeControl *ctrl = iter.next();
+ if(ctrl->OwnsWindow()) {
+ ctrl->DrawableWindow()->ClearPointerCursor();
+ }
+ }
+ if (w)
+ qt_symbian_setWindowCursor(w->cursor(), w->effectiveWinId());
+ else
+ qt_symbian_setWindowGroupCursor(Qt::ArrowCursor, S60->windowGroup());
+ }
+ }
+}
+
+#endif // QT_NO_CURSOR
+
+void QApplicationPrivate::_q_aboutToQuit()
+{
+ qt_beginFullScreenEffect();
+
+#ifdef Q_SYMBIAN_TRANSITION_EFFECTS
+ // Send the shutdown tfx command
+ S60->wsSession().SendEffectCommand(ETfxCmdAppShutDown);
+#endif
+}
+
+QS60ThreadLocalData::QS60ThreadLocalData()
+{
+ CCoeEnv *env = CCoeEnv::Static();
+ if (env) {
+ //if this is the UI thread, share objects owned by CONE
+ usingCONEinstances = true;
+ wsSession = env->WsSession();
+ screenDevice = env->ScreenDevice();
+ }
+ else {
+ usingCONEinstances = false;
+ qt_symbian_throwIfError(wsSession.Connect(qt_s60GetRFs()));
+ screenDevice = new CWsScreenDevice(wsSession);
+ screenDevice->Construct();
+ }
+}
+
+QS60ThreadLocalData::~QS60ThreadLocalData()
+{
+ for (int i = 0; i < releaseFuncs.count(); ++i)
+ releaseFuncs[i]();
+ releaseFuncs.clear();
+ if (!usingCONEinstances) {
+ delete screenDevice;
+ wsSession.Close();
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/kernel/qclipboard_s60.cpp b/src/widgets/platforms/s60/qclipboard_s60.cpp
index f5314bd9e7..f5314bd9e7 100644
--- a/src/gui/kernel/qclipboard_s60.cpp
+++ b/src/widgets/platforms/s60/qclipboard_s60.cpp
diff --git a/src/widgets/platforms/s60/qcoefepinputcontext_p.h b/src/widgets/platforms/s60/qcoefepinputcontext_p.h
new file mode 100644
index 0000000000..148f092ac5
--- /dev/null
+++ b/src/widgets/platforms/s60/qcoefepinputcontext_p.h
@@ -0,0 +1,176 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCOEFEPINPUTCONTEXT_P_H
+#define QCOEFEPINPUTCONTEXT_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QT_NO_IM
+
+#include "qinputcontext.h"
+#include <qhash.h>
+#include <qtimer.h>
+#include <private/qcore_symbian_p.h>
+#include <private/qt_s60_p.h>
+
+#include <fepbase.h>
+#include <aknedsts.h>
+
+QT_BEGIN_NAMESPACE
+
+class Q_AUTOTEST_EXPORT QCoeFepInputContext : public QInputContext,
+ public MCoeFepAwareTextEditor,
+ public MCoeFepAwareTextEditor_Extension1,
+ public MObjectProvider
+{
+ Q_OBJECT
+
+public:
+ QCoeFepInputContext(QObject *parent = 0);
+ ~QCoeFepInputContext();
+
+ QString identifierName() { return QLatin1String("coefep"); }
+ QString language();
+
+ void reset();
+ void update();
+
+ bool filterEvent(const QEvent *event);
+ bool symbianFilterEvent(QWidget *keyWidget, const QSymbianEvent *event);
+ void mouseHandler( int x, QMouseEvent *event);
+ bool isComposing() const { return !m_preeditString.isEmpty(); }
+
+ void setFocusWidget(QWidget * w);
+ void widgetDestroyed(QWidget *w);
+
+ TCoeInputCapabilities inputCapabilities();
+
+ void resetSplitViewWidget(bool keepInputWidget = false);
+ void ensureFocusWidgetVisible(QWidget *widget);
+
+protected:
+ void timerEvent(QTimerEvent *timerEvent);
+
+private:
+ void commitCurrentString(bool cancelFepTransaction);
+ void updateHints(bool mustUpdateInputCapabilities);
+ void applyHints(Qt::InputMethodHints hints);
+ void applyFormat(QList<QInputMethodEvent::Attribute> *attributes);
+ void queueInputCapabilitiesChanged();
+ bool needsInputPanel();
+ void commitTemporaryPreeditString();
+ bool isWidgetVisible(QWidget *widget, int offset = 0);
+
+private Q_SLOTS:
+ void ensureInputCapabilitiesChanged();
+ void translateInputWidget();
+
+ // From MCoeFepAwareTextEditor
+public:
+ void StartFepInlineEditL(const TDesC& aInitialInlineText, TInt aPositionOfInsertionPointInInlineText,
+ TBool aCursorVisibility, const MFormCustomDraw* aCustomDraw,
+ MFepInlineTextFormatRetriever& aInlineTextFormatRetriever,
+ MFepPointerEventHandlerDuringInlineEdit& aPointerEventHandlerDuringInlineEdit);
+ void UpdateFepInlineTextL(const TDesC& aNewInlineText, TInt aPositionOfInsertionPointInInlineText);
+ void SetInlineEditingCursorVisibilityL(TBool aCursorVisibility);
+ void CancelFepInlineEdit();
+ TInt DocumentLengthForFep() const;
+ TInt DocumentMaximumLengthForFep() const;
+ void SetCursorSelectionForFepL(const TCursorSelection& aCursorSelection);
+ void GetCursorSelectionForFep(TCursorSelection& aCursorSelection) const;
+ void GetEditorContentForFep(TDes& aEditorContent, TInt aDocumentPosition, TInt aLengthToRetrieve) const;
+ void GetFormatForFep(TCharFormat& aFormat, TInt aDocumentPosition) const;
+ void GetScreenCoordinatesForFepL(TPoint& aLeftSideOfBaseLine, TInt& aHeight, TInt& aAscent,
+ TInt aDocumentPosition) const;
+private:
+ void DoCommitFepInlineEditL();
+ MCoeFepAwareTextEditor_Extension1* Extension1(TBool& aSetToTrue);
+ void ReportAknEdStateEvent(MAknEdStateObserver::EAknEdwinStateEvent aEventType);
+
+ // From MCoeFepAwareTextEditor_Extension1
+public:
+ void SetStateTransferingOwnershipL(MCoeFepAwareTextEditor_Extension1::CState* aState, TUid aTypeSafetyUid);
+ MCoeFepAwareTextEditor_Extension1::CState* State(TUid aTypeSafetyUid);
+
+ // From MObjectProvider
+public:
+ TTypeUid::Ptr MopSupplyObject(TTypeUid id);
+ MObjectProvider *MopNext();
+
+private:
+ QSymbianControl *m_parent;
+ CAknEdwinState *m_fepState;
+ QString m_preeditString;
+ Qt::InputMethodHints m_lastImHints;
+ TUint m_textCapabilities;
+ bool m_inDestruction;
+ bool m_pendingInputCapabilitiesChanged;
+ int m_cursorVisibility;
+ int m_inlinePosition;
+ MFepInlineTextFormatRetriever *m_formatRetriever;
+ MFepPointerEventHandlerDuringInlineEdit *m_pointerHandler;
+ QBasicTimer m_tempPreeditStringTimeout;
+ bool m_hasTempPreeditString;
+
+ int m_splitViewResizeBy;
+ Qt::WindowStates m_splitViewPreviousWindowStates;
+ QRectF m_transformation;
+
+ friend class tst_QInputContext;
+};
+
+Q_WIDGETS_EXPORT void qt_s60_setPartialScreenInputMode(bool enable);
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_IM
+
+#endif // QCOEFEPINPUTCONTEXT_P_H
diff --git a/src/widgets/platforms/s60/qcoefepinputcontext_s60.cpp b/src/widgets/platforms/s60/qcoefepinputcontext_s60.cpp
new file mode 100644
index 0000000000..8c215360d8
--- /dev/null
+++ b/src/widgets/platforms/s60/qcoefepinputcontext_s60.cpp
@@ -0,0 +1,1200 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT_NO_IM
+
+#include "qcoefepinputcontext_p.h"
+#include <qapplication.h>
+#include <qtextformat.h>
+#include <qgraphicsview.h>
+#include <qgraphicsscene.h>
+#include <qgraphicswidget.h>
+#include <qsymbianevent.h>
+#include <qlayout.h>
+#include <qdesktopwidget.h>
+#include <private/qcore_symbian_p.h>
+
+#include <fepitfr.h>
+#include <hal.h>
+
+#include <limits.h>
+// You only find these enumerations on SDK 5 onwards, so we need to provide our own
+// to remain compatible with older releases. They won't be called by pre-5.0 SDKs.
+
+// MAknEdStateObserver::EAknCursorPositionChanged
+#define QT_EAknCursorPositionChanged MAknEdStateObserver::EAknEdwinStateEvent(6)
+// MAknEdStateObserver::EAknActivatePenInputRequest
+#define QT_EAknActivatePenInputRequest MAknEdStateObserver::EAknEdwinStateEvent(7)
+
+// EAknEditorFlagSelectionVisible is only valid from 3.2 onwards.
+// Sym^3 AVKON FEP manager expects that this flag is used for FEP-aware editors
+// that support text selection.
+#define QT_EAknEditorFlagSelectionVisible 0x100000
+
+// EAknEditorFlagEnablePartialScreen is only valid from Sym^3 onwards.
+#define QT_EAknEditorFlagEnablePartialScreen 0x200000
+
+QT_BEGIN_NAMESPACE
+
+Q_WIDGETS_EXPORT void qt_s60_setPartialScreenInputMode(bool enable)
+{
+ S60->partial_keyboard = enable;
+
+ QInputContext *ic = 0;
+ if (QApplication::focusWidget()) {
+ ic = QApplication::focusWidget()->inputContext();
+ } else if (qApp && qApp->inputContext()) {
+ ic = qApp->inputContext();
+ }
+ if (ic)
+ ic->update();
+}
+
+QCoeFepInputContext::QCoeFepInputContext(QObject *parent)
+ : QInputContext(parent),
+ m_fepState(q_check_ptr(new CAknEdwinState)), // CBase derived object needs check on new
+ m_lastImHints(Qt::ImhNone),
+ m_textCapabilities(TCoeInputCapabilities::EAllText),
+ m_inDestruction(false),
+ m_pendingInputCapabilitiesChanged(false),
+ m_cursorVisibility(1),
+ m_inlinePosition(0),
+ m_formatRetriever(0),
+ m_pointerHandler(0),
+ m_hasTempPreeditString(false),
+ m_splitViewResizeBy(0),
+ m_splitViewPreviousWindowStates(Qt::WindowNoState)
+{
+ m_fepState->SetObjectProvider(this);
+ int defaultFlags = EAknEditorFlagDefault;
+ if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0) {
+ if (S60->partial_keyboard) {
+ defaultFlags |= QT_EAknEditorFlagEnablePartialScreen;
+ }
+ defaultFlags |= QT_EAknEditorFlagSelectionVisible;
+ }
+ m_fepState->SetFlags(defaultFlags);
+ m_fepState->SetDefaultInputMode( EAknEditorTextInputMode );
+ m_fepState->SetPermittedInputModes( EAknEditorAllInputModes );
+ m_fepState->SetDefaultCase( EAknEditorTextCase );
+ m_fepState->SetPermittedCases( EAknEditorAllCaseModes );
+ m_fepState->SetSpecialCharacterTableResourceId(R_AVKON_SPECIAL_CHARACTER_TABLE_DIALOG);
+ m_fepState->SetNumericKeymap(EAknEditorAlphanumericNumberModeKeymap);
+}
+
+QCoeFepInputContext::~QCoeFepInputContext()
+{
+ m_inDestruction = true;
+
+ // This is to make sure that the FEP manager "forgets" about us,
+ // otherwise we may get callbacks even after we're destroyed.
+ // The call below is essentially equivalent to InputCapabilitiesChanged(),
+ // but is synchronous, rather than asynchronous.
+ CCoeEnv::Static()->SyncNotifyFocusObserversOfChangeInFocus();
+
+ if (m_fepState)
+ delete m_fepState;
+}
+
+void QCoeFepInputContext::reset()
+{
+ commitCurrentString(true);
+}
+
+void QCoeFepInputContext::ReportAknEdStateEvent(MAknEdStateObserver::EAknEdwinStateEvent aEventType)
+{
+ QT_TRAP_THROWING(m_fepState->ReportAknEdStateEventL(aEventType));
+}
+
+void QCoeFepInputContext::update()
+{
+ updateHints(false);
+
+ // For pre-5.0 SDKs, we don't do text updates on S60 side.
+ if (QSysInfo::s60Version() < QSysInfo::SV_S60_5_0) {
+ return;
+ }
+
+ // Don't be fooled (as I was) by the name of this enumeration.
+ // What it really does is tell the virtual keyboard UI that the text has been
+ // updated and it should be reflected in the internal display of the VK.
+ ReportAknEdStateEvent(QT_EAknCursorPositionChanged);
+}
+
+void QCoeFepInputContext::setFocusWidget(QWidget *w)
+{
+ commitCurrentString(true);
+
+ QInputContext::setFocusWidget(w);
+
+ updateHints(true);
+}
+
+void QCoeFepInputContext::widgetDestroyed(QWidget *w)
+{
+ // Make sure that the input capabilities of whatever new widget got focused are queried.
+ CCoeControl *ctrl = w->effectiveWinId();
+ if (ctrl->IsFocused()) {
+ queueInputCapabilitiesChanged();
+ }
+}
+
+QString QCoeFepInputContext::language()
+{
+ TLanguage lang = m_fepState->LocalLanguage();
+ const QByteArray localeName = qt_symbianLocaleName(lang);
+ if (!localeName.isEmpty()) {
+ return QString::fromLatin1(localeName);
+ } else {
+ return QString::fromLatin1("C");
+ }
+}
+
+bool QCoeFepInputContext::needsInputPanel()
+{
+ switch (QSysInfo::s60Version()) {
+ case QSysInfo::SV_S60_3_1:
+ case QSysInfo::SV_S60_3_2:
+ // There are no touch phones for pre-5.0 SDKs.
+ return false;
+#ifdef Q_CC_NOKIAX86
+ default:
+ // For emulator we assume that we need an input panel, since we can't
+ // separate between phone types.
+ return true;
+#else
+ case QSysInfo::SV_S60_5_0: {
+ // For SDK == 5.0, we need phone specific detection, since the HAL API
+ // is no good on most phones. However, all phones at the time of writing use the
+ // input panel, except N97 in landscape mode, but in this mode it refuses to bring
+ // up the panel anyway, so we don't have to care.
+ return true;
+ }
+ default:
+ // For unknown/newer types, we try to use the HAL API.
+ int keyboardEnabled;
+ int keyboardType;
+ int err[2];
+ err[0] = HAL::Get(HAL::EKeyboard, keyboardType);
+ err[1] = HAL::Get(HAL::EKeyboardState, keyboardEnabled);
+ if (err[0] == KErrNone && err[1] == KErrNone
+ && keyboardType != 0 && keyboardEnabled)
+ // Means that we have some sort of keyboard.
+ return false;
+
+ // Fall back to using the input panel.
+ return true;
+#endif // !Q_CC_NOKIAX86
+ }
+}
+
+bool QCoeFepInputContext::filterEvent(const QEvent *event)
+{
+ // The CloseSoftwareInputPanel event is not handled here, because the VK will automatically
+ // close when it discovers that the underlying widget does not have input capabilities.
+
+ if (!focusWidget())
+ return false;
+
+ switch (event->type()) {
+ case QEvent::MouseButtonPress:
+ // Alphanumeric keypad doesn't like it when we click and text is still getting displayed
+ // It ignores the mouse event, so we need to commit and send a selection event (which will get triggered
+ // after the commit)
+ if (!m_preeditString.isEmpty()) {
+ commitCurrentString(true);
+
+ int pos = focusWidget()->inputMethodQuery(Qt::ImCursorPosition).toInt();
+
+ QList<QInputMethodEvent::Attribute> selectAttributes;
+ selectAttributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, pos, 0, QVariant());
+ QInputMethodEvent selectEvent(QLatin1String(""), selectAttributes);
+ sendEvent(selectEvent);
+ }
+ break;
+ case QEvent::KeyPress:
+ commitTemporaryPreeditString();
+ // fall through intended
+ case QEvent::KeyRelease:
+ const QKeyEvent *keyEvent = static_cast<const QKeyEvent *>(event);
+ //If proxy exists, always use hints from proxy.
+ QWidget *proxy = focusWidget()->focusProxy();
+ Qt::InputMethodHints currentHints = proxy ? proxy->inputMethodHints() : focusWidget()->inputMethodHints();
+
+ switch (keyEvent->key()) {
+ case Qt::Key_F20:
+ Q_ASSERT(m_lastImHints == currentHints);
+ if (m_lastImHints & Qt::ImhHiddenText) {
+ // Special case in Symbian. On editors with secret text, F20 is for some reason
+ // considered to be a backspace.
+ QKeyEvent modifiedEvent(keyEvent->type(), Qt::Key_Backspace, keyEvent->modifiers(),
+ keyEvent->text(), keyEvent->isAutoRepeat(), keyEvent->count());
+ QApplication::sendEvent(focusWidget(), &modifiedEvent);
+ return true;
+ }
+ break;
+ case Qt::Key_Select:
+ if (!m_preeditString.isEmpty()) {
+ commitCurrentString(true);
+ return true;
+ }
+ break;
+ default:
+ break;
+ }
+
+ QString widgetText = focusWidget()->inputMethodQuery(Qt::ImSurroundingText).toString();
+ bool validLength;
+ int maxLength = focusWidget()->inputMethodQuery(Qt::ImMaximumTextLength).toInt(&validLength);
+ if (!keyEvent->text().isEmpty() && validLength
+ && widgetText.size() + m_preeditString.size() >= maxLength) {
+ // Don't send key events with string content if the widget is "full".
+ return true;
+ }
+
+ if (keyEvent->type() == QEvent::KeyPress
+ && currentHints & Qt::ImhHiddenText
+ && !keyEvent->text().isEmpty()) {
+ // Send some temporary preedit text in order to make text visible for a moment.
+ m_preeditString = keyEvent->text();
+ QList<QInputMethodEvent::Attribute> attributes;
+ QInputMethodEvent imEvent(m_preeditString, attributes);
+ sendEvent(imEvent);
+ m_tempPreeditStringTimeout.start(1000, this);
+ m_hasTempPreeditString = true;
+ update();
+ return true;
+ }
+ break;
+ }
+
+ if (!needsInputPanel())
+ return false;
+
+ if (event->type() == QEvent::RequestSoftwareInputPanel) {
+ // Notify S60 that we want the virtual keyboard to show up.
+ QSymbianControl *sControl;
+ sControl = focusWidget()->effectiveWinId()->MopGetObject(sControl);
+ Q_ASSERT(sControl);
+
+ // The FEP UI temporarily steals focus when it shows up the first time, causing
+ // all sorts of weird effects on the focused widgets. Since it will immediately give
+ // back focus to us, we temporarily disable focus handling until the job's done.
+ if (sControl) {
+ sControl->setIgnoreFocusChanged(true);
+ }
+
+ ensureInputCapabilitiesChanged();
+ m_fepState->ReportAknEdStateEventL(MAknEdStateObserver::QT_EAknActivatePenInputRequest);
+
+ if (sControl) {
+ sControl->setIgnoreFocusChanged(false);
+ }
+ return true;
+ }
+
+ return false;
+}
+
+bool QCoeFepInputContext::symbianFilterEvent(QWidget *keyWidget, const QSymbianEvent *event)
+{
+ Q_UNUSED(keyWidget);
+ if (event->type() == QSymbianEvent::CommandEvent)
+ // A command basically means the same as a button being pushed. With Qt buttons
+ // that would normally result in a reset of the input method due to the focus change.
+ // This should also happen for commands.
+ reset();
+
+ if (event->type() == QSymbianEvent::WindowServerEvent
+ && event->windowServerEvent()
+ && event->windowServerEvent()->Type() == EEventWindowVisibilityChanged
+ && S60->splitViewLastWidget) {
+
+ QGraphicsView *gv = qobject_cast<QGraphicsView*>(S60->splitViewLastWidget);
+ const bool alwaysResize = (gv && gv->verticalScrollBarPolicy() != Qt::ScrollBarAlwaysOff);
+
+ if (alwaysResize) {
+ TUint visibleFlags = event->windowServerEvent()->VisibilityChanged()->iFlags;
+ if (visibleFlags & TWsVisibilityChangedEvent::EPartiallyVisible)
+ ensureFocusWidgetVisible(S60->splitViewLastWidget);
+ if (visibleFlags & TWsVisibilityChangedEvent::ENotVisible)
+ resetSplitViewWidget(true);
+ }
+ }
+
+ return false;
+}
+
+void QCoeFepInputContext::timerEvent(QTimerEvent *timerEvent)
+{
+ if (timerEvent->timerId() == m_tempPreeditStringTimeout.timerId())
+ commitTemporaryPreeditString();
+}
+
+void QCoeFepInputContext::commitTemporaryPreeditString()
+{
+ if (m_tempPreeditStringTimeout.isActive())
+ m_tempPreeditStringTimeout.stop();
+
+ if (!m_hasTempPreeditString)
+ return;
+
+ commitCurrentString(false);
+}
+
+void QCoeFepInputContext::mouseHandler( int x, QMouseEvent *event)
+{
+ Q_ASSERT(focusWidget());
+
+ if (event->type() == QEvent::MouseButtonPress && event->button() == Qt::LeftButton) {
+ commitCurrentString(true);
+ int pos = focusWidget()->inputMethodQuery(Qt::ImCursorPosition).toInt();
+
+ QList<QInputMethodEvent::Attribute> attributes;
+ attributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, pos + x, 0, QVariant());
+ QInputMethodEvent event(QLatin1String(""), attributes);
+ sendEvent(event);
+ }
+}
+
+TCoeInputCapabilities QCoeFepInputContext::inputCapabilities()
+{
+ if (m_inDestruction || !focusWidget()) {
+ return TCoeInputCapabilities(TCoeInputCapabilities::ENone, 0, 0);
+ }
+
+ return TCoeInputCapabilities(m_textCapabilities, this, 0);
+}
+
+void QCoeFepInputContext::resetSplitViewWidget(bool keepInputWidget)
+{
+ QGraphicsView *gv = qobject_cast<QGraphicsView*>(S60->splitViewLastWidget);
+
+ if (!gv) {
+ return;
+ }
+
+ QSymbianControl *symControl = static_cast<QSymbianControl*>(gv->effectiveWinId());
+ symControl->CancelLongTapTimer();
+
+ const bool alwaysResize = (gv->verticalScrollBarPolicy() != Qt::ScrollBarAlwaysOff);
+ QWidget *windowToMove = gv->window();
+
+ bool userResize = gv->testAttribute(Qt::WA_Resized);
+
+ windowToMove->setUpdatesEnabled(false);
+
+ if (!alwaysResize) {
+ if (gv->scene()) {
+ if (gv->scene()->focusItem()) {
+ // Check if the widget contains cursorPositionChanged signal and disconnect from it.
+ QByteArray signal = QMetaObject::normalizedSignature(SIGNAL(cursorPositionChanged()));
+ int index = gv->scene()->focusItem()->toGraphicsObject()->metaObject()->indexOfSignal(signal.right(signal.length() - 1));
+ if (index != -1)
+ disconnect(gv->scene()->focusItem()->toGraphicsObject(), SIGNAL(cursorPositionChanged()), this, SLOT(translateInputWidget()));
+ }
+
+ QGraphicsItem *rootItem = 0;
+ foreach (QGraphicsItem *item, gv->scene()->items()) {
+ if (!item->parentItem()) {
+ rootItem = item;
+ break;
+ }
+ }
+ if (rootItem)
+ rootItem->resetTransform();
+ }
+ } else {
+ if (m_splitViewResizeBy)
+ gv->resize(gv->rect().width(), m_splitViewResizeBy);
+ }
+ // Resizing might have led to widget losing its original windowstate.
+ // Restore previous window state.
+
+ if (m_splitViewPreviousWindowStates != windowToMove->windowState())
+ windowToMove->setWindowState(m_splitViewPreviousWindowStates);
+
+ windowToMove->setUpdatesEnabled(true);
+
+ gv->setAttribute(Qt::WA_Resized, userResize); //not a user resize
+
+ m_splitViewResizeBy = 0;
+ if (!keepInputWidget) {
+ m_splitViewPreviousWindowStates = Qt::WindowNoState;
+ S60->splitViewLastWidget = 0;
+ }
+}
+
+// Checks if a given widget is visible in the splitview rect. The offset
+// parameter can be used to validate if moving widget upwards or downwards
+// by the offset would make a difference for the visibility.
+
+bool QCoeFepInputContext::isWidgetVisible(QWidget *widget, int offset)
+{
+ bool visible = false;
+ if (widget) {
+ QRect splitViewRect = qt_TRect2QRect(static_cast<CEikAppUi*>(S60->appUi())->ClientRect());
+ QWidget *window = QApplication::activeWindow();
+ QGraphicsView *gv = qobject_cast<QGraphicsView*>(widget);
+ if (gv && window) {
+ if (QGraphicsScene *scene = gv->scene()) {
+ if (QGraphicsItem *focusItem = scene->focusItem()) {
+ QPoint cursorPos = window->mapToGlobal(focusItem->cursor().pos());
+ cursorPos.setY(cursorPos.y() + offset);
+ if (splitViewRect.contains(cursorPos)) {
+ visible = true;
+ }
+ }
+ }
+ }
+ }
+ return visible;
+}
+
+// Ensure that the input widget is visible in the splitview rect.
+
+void QCoeFepInputContext::ensureFocusWidgetVisible(QWidget *widget)
+{
+ // Native side opening and closing its virtual keyboard when it changes the keyboard layout,
+ // has an adverse impact on long tap timer. Cancel the timer when splitview opens to avoid this.
+ QSymbianControl *symControl = static_cast<QSymbianControl*>(widget->effectiveWinId());
+ symControl->CancelLongTapTimer();
+
+ // Graphicsviews that have vertical scrollbars should always be resized to the splitview area.
+ // Graphicsviews without scrollbars should be translated.
+
+ QGraphicsView *gv = qobject_cast<QGraphicsView*>(widget);
+ if (!gv)
+ return;
+
+ const bool alwaysResize = (gv && gv->verticalScrollBarPolicy() != Qt::ScrollBarAlwaysOff);
+ const bool moveWithinVisibleArea = (S60->splitViewLastWidget != 0);
+
+ QWidget *windowToMove = gv ? gv : symControl->widget();
+ if (!windowToMove->isWindow())
+ windowToMove = windowToMove->window();
+ if (!windowToMove) {
+ return;
+ }
+
+ // When opening the keyboard (not moving within the splitview area), save the original
+ // window state. In some cases, ensuring input widget visibility might lead to window
+ // states getting changed.
+
+ if (!moveWithinVisibleArea) {
+ // Check if the widget contains cursorPositionChanged signal and connect to it.
+ QByteArray signal = QMetaObject::normalizedSignature(SIGNAL(cursorPositionChanged()));
+ if (gv->scene() && gv->scene()->focusItem()) {
+ int index = gv->scene()->focusItem()->toGraphicsObject()->metaObject()->indexOfSignal(signal.right(signal.length() - 1));
+ if (index != -1)
+ connect(gv->scene()->focusItem()->toGraphicsObject(), SIGNAL(cursorPositionChanged()), this, SLOT(translateInputWidget()));
+ }
+ S60->splitViewLastWidget = widget;
+ m_splitViewPreviousWindowStates = windowToMove->windowState();
+ }
+
+ int windowTop = widget->window()->pos().y();
+
+ const bool userResize = widget->testAttribute(Qt::WA_Resized);
+
+ QRect splitViewRect = qt_TRect2QRect(static_cast<CEikAppUi*>(S60->appUi())->ClientRect());
+
+
+ // When resizing a window widget, it will lose its maximized window state.
+ // Native applications hide statuspane in splitview state, so lets move to
+ // fullscreen mode. This makes available area slightly bigger, which helps usability
+ // and greatly reduces event passing in orientation switch cases,
+ // as the statuspane size is not changing.
+
+ if (alwaysResize)
+ windowToMove->setUpdatesEnabled(false);
+
+ if (!(windowToMove->windowState() & Qt::WindowFullScreen)) {
+ windowToMove->setWindowState(
+ (windowToMove->windowState() & ~(Qt::WindowMinimized | Qt::WindowFullScreen)) | Qt::WindowFullScreen);
+ }
+
+ if (alwaysResize) {
+ if (!moveWithinVisibleArea) {
+ m_splitViewResizeBy = widget->height();
+ windowTop = widget->geometry().top();
+ widget->resize(widget->width(), splitViewRect.height() - windowTop);
+ }
+
+ if (gv->scene()) {
+ const QRectF microFocusRect = gv->scene()->inputMethodQuery(Qt::ImMicroFocus).toRectF();
+ gv->ensureVisible(microFocusRect);
+ }
+ } else {
+ translateInputWidget();
+ }
+
+ if (alwaysResize)
+ windowToMove->setUpdatesEnabled(true);
+
+ widget->setAttribute(Qt::WA_Resized, userResize); //not a user resize
+}
+
+static QTextCharFormat qt_TCharFormat2QTextCharFormat(const TCharFormat &cFormat, bool validStyleColor)
+{
+ QTextCharFormat qFormat;
+
+ if (validStyleColor) {
+ QBrush foreground(QColor(cFormat.iFontPresentation.iTextColor.Internal()));
+ qFormat.setForeground(foreground);
+ }
+
+ qFormat.setFontStrikeOut(cFormat.iFontPresentation.iStrikethrough == EStrikethroughOn);
+ qFormat.setFontUnderline(cFormat.iFontPresentation.iUnderline == EUnderlineOn);
+
+ return qFormat;
+}
+
+void QCoeFepInputContext::updateHints(bool mustUpdateInputCapabilities)
+{
+ QWidget *w = focusWidget();
+ if (w) {
+ QWidget *proxy = w->focusProxy();
+ Qt::InputMethodHints hints = proxy ? proxy->inputMethodHints() : w->inputMethodHints();
+
+ // Since splitview support works like an input method hint, yet it is private flag,
+ // we need to update its state separately.
+ if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0) {
+ TInt currentFlags = m_fepState->Flags();
+ if (S60->partial_keyboard)
+ currentFlags |= QT_EAknEditorFlagEnablePartialScreen;
+ else
+ currentFlags &= ~QT_EAknEditorFlagEnablePartialScreen;
+ if (currentFlags != m_fepState->Flags())
+ m_fepState->SetFlags(currentFlags);
+ }
+
+ if (hints != m_lastImHints) {
+ m_lastImHints = hints;
+ applyHints(hints);
+ } else if (!mustUpdateInputCapabilities) {
+ // Optimization. Return immediately if there was no change.
+ return;
+ }
+ }
+ queueInputCapabilitiesChanged();
+}
+
+void QCoeFepInputContext::applyHints(Qt::InputMethodHints hints)
+{
+ using namespace Qt;
+
+ commitTemporaryPreeditString();
+
+ const bool anynumbermodes = hints & (ImhDigitsOnly | ImhFormattedNumbersOnly | ImhDialableCharactersOnly);
+ const bool anytextmodes = hints & (ImhUppercaseOnly | ImhLowercaseOnly | ImhEmailCharactersOnly | ImhUrlCharactersOnly);
+ const bool numbersOnly = anynumbermodes && !anytextmodes;
+ const bool noOnlys = !(hints & ImhExclusiveInputMask);
+ // if alphanumeric input, or if multiple incompatible number modes are selected;
+ // then make all symbols available in numeric mode too.
+ const bool needsCharMap= !numbersOnly || ((hints & ImhFormattedNumbersOnly) && (hints & ImhDialableCharactersOnly));
+ TInt flags;
+ Qt::InputMethodHints oldHints = hints;
+
+ // Some sanity checking. Make sure that only one preference is set.
+ InputMethodHints prefs = ImhPreferNumbers | ImhPreferUppercase | ImhPreferLowercase;
+ prefs &= hints;
+ if (prefs != ImhPreferNumbers && prefs != ImhPreferUppercase && prefs != ImhPreferLowercase) {
+ hints &= ~prefs;
+ }
+ if (!noOnlys) {
+ // Make sure that the preference is within the permitted set.
+ if (hints & ImhPreferNumbers && !anynumbermodes) {
+ hints &= ~ImhPreferNumbers;
+ } else if (hints & ImhPreferUppercase && !(hints & ImhUppercaseOnly)) {
+ hints &= ~ImhPreferUppercase;
+ } else if (hints & ImhPreferLowercase && !(hints & ImhLowercaseOnly)) {
+ hints &= ~ImhPreferLowercase;
+ }
+ // If there is no preference, set it to something within the permitted set.
+ if (!(hints & ImhPreferNumbers || hints & ImhPreferUppercase || hints & ImhPreferLowercase)) {
+ if (hints & ImhLowercaseOnly) {
+ hints |= ImhPreferLowercase;
+ } else if (hints & ImhUppercaseOnly) {
+ hints |= ImhPreferUppercase;
+ } else if (numbersOnly) {
+ hints |= ImhPreferNumbers;
+ }
+ }
+ }
+
+ if (hints & ImhPreferNumbers) {
+ m_fepState->SetDefaultInputMode(EAknEditorNumericInputMode);
+ m_fepState->SetCurrentInputMode(EAknEditorNumericInputMode);
+ } else {
+ m_fepState->SetDefaultInputMode(EAknEditorTextInputMode);
+ m_fepState->SetCurrentInputMode(EAknEditorTextInputMode);
+ }
+ flags = 0;
+ if (noOnlys || (anynumbermodes && anytextmodes)) {
+ flags = EAknEditorAllInputModes;
+ }
+ else if (anynumbermodes) {
+ flags |= EAknEditorNumericInputMode;
+ if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0
+ && ((hints & ImhFormattedNumbersOnly) || (hints & ImhDialableCharactersOnly))) {
+ //workaround - the * key does not launch the symbols menu, making it impossible to use these modes unless text mode is enabled.
+ flags |= EAknEditorTextInputMode;
+ }
+ }
+ else if (anytextmodes) {
+ flags |= EAknEditorTextInputMode;
+ }
+ else {
+ flags = EAknEditorAllInputModes;
+ }
+ m_fepState->SetPermittedInputModes(flags);
+ ReportAknEdStateEvent(MAknEdStateObserver::EAknEdwinStateInputModeUpdate);
+
+ if (hints & ImhPreferLowercase) {
+ m_fepState->SetDefaultCase(EAknEditorLowerCase);
+ m_fepState->SetCurrentCase(EAknEditorLowerCase);
+ } else if (hints & ImhPreferUppercase) {
+ m_fepState->SetDefaultCase(EAknEditorUpperCase);
+ m_fepState->SetCurrentCase(EAknEditorUpperCase);
+ } else if (hints & ImhNoAutoUppercase) {
+ m_fepState->SetDefaultCase(EAknEditorLowerCase);
+ m_fepState->SetCurrentCase(EAknEditorLowerCase);
+ } else {
+ m_fepState->SetDefaultCase(EAknEditorTextCase);
+ m_fepState->SetCurrentCase(EAknEditorTextCase);
+ }
+ flags = 0;
+ if (hints & ImhUppercaseOnly) {
+ flags |= EAknEditorUpperCase;
+ }
+ if (hints & ImhLowercaseOnly) {
+ flags |= EAknEditorLowerCase;
+ }
+ if (flags == 0) {
+ flags = EAknEditorAllCaseModes;
+ if (hints & ImhNoAutoUppercase) {
+ flags &= ~EAknEditorTextCase;
+ }
+ }
+ m_fepState->SetPermittedCases(flags);
+ ReportAknEdStateEvent(MAknEdStateObserver::EAknEdwinStateCaseModeUpdate);
+
+ flags = 0;
+ if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0) {
+ if (S60->partial_keyboard)
+ flags |= QT_EAknEditorFlagEnablePartialScreen;
+ flags |= QT_EAknEditorFlagSelectionVisible;
+ }
+ if (hints & ImhUppercaseOnly && !(hints & ImhLowercaseOnly)
+ || hints & ImhLowercaseOnly && !(hints & ImhUppercaseOnly)) {
+ flags |= EAknEditorFlagFixedCase;
+ }
+ // Using T9 and hidden text together may actually crash the FEP, so check for hidden text too.
+ if (hints & ImhNoPredictiveText || hints & ImhHiddenText) {
+ flags |= EAknEditorFlagNoT9;
+ }
+ if (needsCharMap)
+ flags |= EAknEditorFlagUseSCTNumericCharmap;
+ m_fepState->SetFlags(flags);
+ ReportAknEdStateEvent(MAknEdStateObserver::EAknEdwinStateFlagsUpdate);
+
+ if (hints & ImhDialableCharactersOnly) {
+ // This is first, because if (ImhDialableCharactersOnly | ImhFormattedNumbersOnly)
+ // is specified, this one is more natural (# key enters a #)
+ flags = EAknEditorStandardNumberModeKeymap;
+ } else if (hints & ImhFormattedNumbersOnly) {
+ // # key enters decimal point
+ flags = EAknEditorCalculatorNumberModeKeymap;
+ } else if (hints & ImhDigitsOnly) {
+ // This is last, because it is most restrictive (# key is inactive)
+ flags = EAknEditorPlainNumberModeKeymap;
+ } else {
+ flags = EAknEditorStandardNumberModeKeymap;
+ }
+ m_fepState->SetNumericKeymap(static_cast<TAknEditorNumericKeymap>(flags));
+
+ if (hints & ImhUrlCharactersOnly) {
+ // URL characters is everything except space, so a superset of the other restrictions
+ m_fepState->SetSpecialCharacterTableResourceId(R_AVKON_URL_SPECIAL_CHARACTER_TABLE_DIALOG);
+ } else if (hints & ImhEmailCharactersOnly) {
+ m_fepState->SetSpecialCharacterTableResourceId(R_AVKON_EMAIL_ADDR_SPECIAL_CHARACTER_TABLE_DIALOG);
+ } else if (needsCharMap) {
+ m_fepState->SetSpecialCharacterTableResourceId(R_AVKON_SPECIAL_CHARACTER_TABLE_DIALOG);
+ } else if ((hints & ImhFormattedNumbersOnly) || (hints & ImhDialableCharactersOnly)) {
+ m_fepState->SetSpecialCharacterTableResourceId(R_AVKON_SPECIAL_CHARACTER_TABLE_DIALOG);
+ } else {
+ m_fepState->SetSpecialCharacterTableResourceId(0);
+ }
+
+ if (hints & ImhHiddenText) {
+ m_textCapabilities = TCoeInputCapabilities::EAllText | TCoeInputCapabilities::ESecretText;
+ } else {
+ m_textCapabilities = TCoeInputCapabilities::EAllText;
+ }
+}
+
+void QCoeFepInputContext::applyFormat(QList<QInputMethodEvent::Attribute> *attributes)
+{
+ TCharFormat cFormat;
+ QColor styleTextColor;
+ if (QWidget *focused = focusWidget()) {
+ QGraphicsView *gv = qobject_cast<QGraphicsView*>(focused);
+ if (!gv) // could be either the QGV or its viewport that has focus
+ gv = qobject_cast<QGraphicsView*>(focused->parentWidget());
+ if (gv) {
+ if (QGraphicsScene *scene = gv->scene()) {
+ if (QGraphicsItem *focusItem = scene->focusItem()) {
+ if (focusItem->isWidget()) {
+ styleTextColor = static_cast<QGraphicsWidget*>(focusItem)->palette().text().color();
+ }
+ }
+ }
+ } else {
+ styleTextColor = focused->palette().text().color();
+ }
+ } else {
+ styleTextColor = QApplication::palette("QLineEdit").text().color();
+ }
+
+ if (styleTextColor.isValid()) {
+ const TLogicalRgb fontColor(TRgb(styleTextColor.red(), styleTextColor.green(), styleTextColor.blue(), styleTextColor.alpha()));
+ cFormat.iFontPresentation.iTextColor = fontColor;
+ }
+
+ TInt numChars = 0;
+ TInt charPos = 0;
+ int oldSize = attributes->size();
+ while (m_formatRetriever) {
+ m_formatRetriever->GetFormatOfFepInlineText(cFormat, numChars, charPos);
+ if (numChars <= 0) {
+ // This shouldn't happen according to S60 docs, but apparently does sometimes.
+ break;
+ }
+ attributes->append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat,
+ charPos,
+ numChars,
+ QVariant(qt_TCharFormat2QTextCharFormat(cFormat, styleTextColor.isValid()))));
+ charPos += numChars;
+ if (charPos >= m_preeditString.size()) {
+ break;
+ }
+ }
+
+ if (attributes->size() == oldSize) {
+ // S60 didn't provide any format, so let's give our own instead.
+ attributes->append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat,
+ 0,
+ m_preeditString.size(),
+ standardFormat(PreeditFormat)));
+ }
+}
+
+void QCoeFepInputContext::queueInputCapabilitiesChanged()
+{
+ if (m_pendingInputCapabilitiesChanged)
+ return;
+
+ // Call ensureInputCapabilitiesChanged asynchronously. This is done to improve performance
+ // by not updating input capabilities too often. The reason we don't call the Symbian
+ // asynchronous version of InputCapabilitiesChanged is because we need to ensure that it
+ // is synchronous in some specific cases. Those will call ensureInputCapabilitesChanged.
+ QMetaObject::invokeMethod(this, "ensureInputCapabilitiesChanged", Qt::QueuedConnection);
+ m_pendingInputCapabilitiesChanged = true;
+}
+
+void QCoeFepInputContext::ensureInputCapabilitiesChanged()
+{
+ if (!m_pendingInputCapabilitiesChanged)
+ return;
+
+ // The call below is essentially equivalent to InputCapabilitiesChanged(),
+ // but is synchronous, rather than asynchronous.
+ CCoeEnv::Static()->SyncNotifyFocusObserversOfChangeInFocus();
+ m_pendingInputCapabilitiesChanged = false;
+}
+
+void QCoeFepInputContext::translateInputWidget()
+{
+ QGraphicsView *gv = qobject_cast<QGraphicsView *>(S60->splitViewLastWidget);
+ QRect splitViewRect = qt_TRect2QRect(static_cast<CEikAppUi*>(S60->appUi())->ClientRect());
+
+ QRectF cursor = gv->scene()->inputMethodQuery(Qt::ImMicroFocus).toRectF();
+ QPolygon cursorP = gv->mapFromScene(cursor);
+ QRectF vkbRect = QRectF(splitViewRect.bottomLeft(), qApp->desktop()->rect().bottomRight());
+ if (cursor.isEmpty() || vkbRect.isEmpty())
+ return;
+
+ // Fetch root item (i.e. graphicsitem with no parent)
+ QGraphicsItem *rootItem = 0;
+ foreach (QGraphicsItem *item, gv->scene()->items()) {
+ if (!item->parentItem()) {
+ rootItem = item;
+ break;
+ }
+ }
+ if (!rootItem)
+ return;
+
+ m_transformation = (rootItem->transform().isTranslating()) ? QRectF(0,0, gv->width(), rootItem->transform().dy()) : QRectF();
+
+ // Do nothing if the cursor is visible in the splitview area.
+ if (splitViewRect.contains(cursorP.boundingRect()))
+ return;
+
+ // New Y position should be ideally at the center of the splitview area.
+ // If that would expose unpainted canvas, limit the tranformation to the visible scene bottom.
+
+ const qreal maxY = gv->sceneRect().bottom() - splitViewRect.bottom() + m_transformation.height();
+ qreal dy = -(qMin(maxY, (cursor.bottom() - vkbRect.top() / 2)));
+
+ // Do not allow transform above screen top.
+ if (m_transformation.height() + dy > 0)
+ return;
+
+ rootItem->setTransform(QTransform::fromTranslate(0, dy), true);
+}
+
+void QCoeFepInputContext::StartFepInlineEditL(const TDesC& aInitialInlineText,
+ TInt aPositionOfInsertionPointInInlineText, TBool aCursorVisibility, const MFormCustomDraw* /*aCustomDraw*/,
+ MFepInlineTextFormatRetriever& aInlineTextFormatRetriever,
+ MFepPointerEventHandlerDuringInlineEdit& aPointerEventHandlerDuringInlineEdit)
+{
+ QWidget *w = focusWidget();
+ if (!w)
+ return;
+
+ commitTemporaryPreeditString();
+
+ QList<QInputMethodEvent::Attribute> attributes;
+
+ m_cursorVisibility = aCursorVisibility ? 1 : 0;
+ m_inlinePosition = aPositionOfInsertionPointInInlineText;
+ m_preeditString = qt_TDesC2QString(aInitialInlineText);
+
+ m_formatRetriever = &aInlineTextFormatRetriever;
+ m_pointerHandler = &aPointerEventHandlerDuringInlineEdit;
+
+ // With T9 aInitialInlineText is typically empty when StartFepInlineEditL is called,
+ // but FEP requires that selected text is always removed at StartFepInlineEditL.
+ // Let's remove the selected text if aInitialInlineText is empty and there is selected text
+ if (m_preeditString.isEmpty()) {
+ int anchor = w->inputMethodQuery(Qt::ImAnchorPosition).toInt();
+ int cursorPos = w->inputMethodQuery(Qt::ImCursorPosition).toInt();
+ int replacementLength = qAbs(cursorPos-anchor);
+ if (replacementLength > 0) {
+ int replacementStart = cursorPos < anchor ? 0 : -replacementLength;
+ QList<QInputMethodEvent::Attribute> clearSelectionAttributes;
+ QInputMethodEvent clearSelectionEvent(QLatin1String(""), clearSelectionAttributes);
+ clearSelectionEvent.setCommitString(QLatin1String(""), replacementStart, replacementLength);
+ sendEvent(clearSelectionEvent);
+ }
+ }
+
+ applyFormat(&attributes);
+
+ attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor,
+ m_inlinePosition,
+ m_cursorVisibility,
+ QVariant()));
+ QInputMethodEvent event(m_preeditString, attributes);
+ sendEvent(event);
+}
+
+void QCoeFepInputContext::UpdateFepInlineTextL(const TDesC& aNewInlineText,
+ TInt aPositionOfInsertionPointInInlineText)
+{
+ QWidget *w = focusWidget();
+ if (!w)
+ return;
+
+ commitTemporaryPreeditString();
+
+ m_inlinePosition = aPositionOfInsertionPointInInlineText;
+
+ QList<QInputMethodEvent::Attribute> attributes;
+ applyFormat(&attributes);
+ attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor,
+ m_inlinePosition,
+ m_cursorVisibility,
+ QVariant()));
+ QString newPreeditString = qt_TDesC2QString(aNewInlineText);
+ QInputMethodEvent event(newPreeditString, attributes);
+ if (newPreeditString.isEmpty() && m_preeditString.isEmpty()) {
+ // In Symbian world this means "erase last character".
+ event.setCommitString(QLatin1String(""), -1, 1);
+ }
+ m_preeditString = newPreeditString;
+ sendEvent(event);
+}
+
+void QCoeFepInputContext::SetInlineEditingCursorVisibilityL(TBool aCursorVisibility)
+{
+ QWidget *w = focusWidget();
+ if (!w)
+ return;
+
+ m_cursorVisibility = aCursorVisibility ? 1 : 0;
+
+ QList<QInputMethodEvent::Attribute> attributes;
+ attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor,
+ m_inlinePosition,
+ m_cursorVisibility,
+ QVariant()));
+ QInputMethodEvent event(m_preeditString, attributes);
+ sendEvent(event);
+}
+
+void QCoeFepInputContext::CancelFepInlineEdit()
+{
+ // We are not supposed to ever have a tempPreeditString and a real preedit string
+ // from S60 at the same time, so it should be safe to rely on this test to determine
+ // whether we should honor S60's request to clear the text or not.
+ if (m_hasTempPreeditString)
+ return;
+
+ QList<QInputMethodEvent::Attribute> attributes;
+ QInputMethodEvent event(QLatin1String(""), attributes);
+ event.setCommitString(QLatin1String(""), 0, 0);
+ m_preeditString.clear();
+ m_inlinePosition = 0;
+ sendEvent(event);
+}
+
+TInt QCoeFepInputContext::DocumentLengthForFep() const
+{
+ QWidget *w = focusWidget();
+ if (!w)
+ return 0;
+
+ QVariant variant = w->inputMethodQuery(Qt::ImSurroundingText);
+ return variant.value<QString>().size() + m_preeditString.size();
+}
+
+TInt QCoeFepInputContext::DocumentMaximumLengthForFep() const
+{
+ QWidget *w = focusWidget();
+ if (!w)
+ return 0;
+
+ QVariant variant = w->inputMethodQuery(Qt::ImMaximumTextLength);
+ int size;
+ if (variant.isValid()) {
+ size = variant.toInt();
+ } else {
+ size = INT_MAX; // Sensible default for S60.
+ }
+ return size;
+}
+
+void QCoeFepInputContext::SetCursorSelectionForFepL(const TCursorSelection& aCursorSelection)
+{
+ QWidget *w = focusWidget();
+ if (!w)
+ return;
+
+ commitTemporaryPreeditString();
+
+ int pos = aCursorSelection.iAnchorPos;
+ int length = aCursorSelection.iCursorPos - pos;
+
+ QList<QInputMethodEvent::Attribute> attributes;
+ attributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, pos, length, QVariant());
+ QInputMethodEvent event(m_preeditString, attributes);
+ sendEvent(event);
+}
+
+void QCoeFepInputContext::GetCursorSelectionForFep(TCursorSelection& aCursorSelection) const
+{
+ QWidget *w = focusWidget();
+ if (!w) {
+ aCursorSelection.SetSelection(0,0);
+ return;
+ }
+
+ int cursor = w->inputMethodQuery(Qt::ImCursorPosition).toInt() + m_preeditString.size();
+ int anchor = w->inputMethodQuery(Qt::ImAnchorPosition).toInt() + m_preeditString.size();
+ QString text = w->inputMethodQuery(Qt::ImSurroundingText).value<QString>();
+ int combinedSize = text.size() + m_preeditString.size();
+ if (combinedSize < anchor || combinedSize < cursor) {
+ // ### TODO! FIXME! QTBUG-5050
+ // This is a hack to prevent crashing in 4.6 with QLineEdits that use input masks.
+ // The root problem is that cursor position is relative to displayed text instead of the
+ // actual text we get.
+ //
+ // To properly fix this we would need to know the displayText of QLineEdits instead
+ // of just the text, which on itself should be a trivial change. The difficulties start
+ // when we need to commit the changes back to the QLineEdit, which would have to be somehow
+ // able to handle displayText, too.
+ //
+ // Until properly fixed, the cursor and anchor positions will not reflect correct positions
+ // for masked QLineEdits, unless all the masked positions are filled in order so that
+ // cursor position relative to the displayed text matches position relative to actual text.
+ aCursorSelection.iAnchorPos = combinedSize;
+ aCursorSelection.iCursorPos = combinedSize;
+ } else {
+ aCursorSelection.iAnchorPos = anchor;
+ aCursorSelection.iCursorPos = cursor;
+ }
+}
+
+void QCoeFepInputContext::GetEditorContentForFep(TDes& aEditorContent, TInt aDocumentPosition,
+ TInt aLengthToRetrieve) const
+{
+ QWidget *w = focusWidget();
+ if (!w) {
+ aEditorContent.FillZ(aLengthToRetrieve);
+ return;
+ }
+
+ QString text = w->inputMethodQuery(Qt::ImSurroundingText).value<QString>();
+ // FEP expects the preedit string to be part of the editor content, so let's mix it in.
+ int cursor = w->inputMethodQuery(Qt::ImCursorPosition).toInt();
+ text.insert(cursor, m_preeditString);
+ aEditorContent.Copy(qt_QString2TPtrC(text.mid(aDocumentPosition, aLengthToRetrieve)));
+}
+
+void QCoeFepInputContext::GetFormatForFep(TCharFormat& aFormat, TInt /* aDocumentPosition */) const
+{
+ QWidget *w = focusWidget();
+ if (!w) {
+ aFormat = TCharFormat();
+ return;
+ }
+
+ QFont font = w->inputMethodQuery(Qt::ImFont).value<QFont>();
+ QFontMetrics metrics(font);
+ //QString name = font.rawName();
+ QString name = font.defaultFamily(); // TODO! FIXME! Should be the above.
+ QHBufC hBufC(name);
+ aFormat = TCharFormat(hBufC->Des(), metrics.height());
+}
+
+void QCoeFepInputContext::GetScreenCoordinatesForFepL(TPoint& aLeftSideOfBaseLine, TInt& aHeight,
+ TInt& aAscent, TInt /* aDocumentPosition */) const
+{
+ QWidget *w = focusWidget();
+ if (!w) {
+ aLeftSideOfBaseLine = TPoint(0,0);
+ aHeight = 0;
+ aAscent = 0;
+ return;
+ }
+
+ QRect rect = w->inputMethodQuery(Qt::ImMicroFocus).value<QRect>();
+ aLeftSideOfBaseLine.iX = rect.left();
+ aLeftSideOfBaseLine.iY = rect.bottom();
+
+ QFont font = w->inputMethodQuery(Qt::ImFont).value<QFont>();
+ QFontMetrics metrics(font);
+ aHeight = metrics.height();
+ aAscent = metrics.ascent();
+}
+
+void QCoeFepInputContext::DoCommitFepInlineEditL()
+{
+ commitCurrentString(false);
+ if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0)
+ ReportAknEdStateEvent(QT_EAknCursorPositionChanged);
+
+}
+
+void QCoeFepInputContext::commitCurrentString(bool cancelFepTransaction)
+{
+ QList<QInputMethodEvent::Attribute> attributes;
+ QInputMethodEvent event(QLatin1String(""), attributes);
+ event.setCommitString(m_preeditString, 0, 0);
+ m_preeditString.clear();
+ m_inlinePosition = 0;
+ sendEvent(event);
+
+ m_hasTempPreeditString = false;
+
+ if (cancelFepTransaction) {
+ CCoeFep* fep = CCoeEnv::Static()->Fep();
+ if (fep)
+ fep->CancelTransaction();
+ }
+}
+
+MCoeFepAwareTextEditor_Extension1* QCoeFepInputContext::Extension1(TBool& aSetToTrue)
+{
+ aSetToTrue = ETrue;
+ return this;
+}
+
+void QCoeFepInputContext::SetStateTransferingOwnershipL(MCoeFepAwareTextEditor_Extension1::CState* aState,
+ TUid /*aTypeSafetyUid*/)
+{
+ // Note: The S60 docs are wrong! See the State() function.
+ if (m_fepState)
+ delete m_fepState;
+ m_fepState = static_cast<CAknEdwinState *>(aState);
+}
+
+MCoeFepAwareTextEditor_Extension1::CState* QCoeFepInputContext::State(TUid /*aTypeSafetyUid*/)
+{
+ // Note: The S60 docs are horribly wrong when describing the
+ // SetStateTransferingOwnershipL function and this function. They say that the former
+ // sets a CState object identified by the TUid, and the latter retrieves it.
+ // In reality, the CState is expected to always be a CAknEdwinState (even if it was not
+ // previously set), and the TUid is ignored. All in all, there is a single CAknEdwinState
+ // per QCoeFepInputContext, which should be deleted if the SetStateTransferingOwnershipL
+ // function is used to set a new one.
+ return m_fepState;
+}
+
+TTypeUid::Ptr QCoeFepInputContext::MopSupplyObject(TTypeUid /*id*/)
+{
+ return TTypeUid::Null();
+}
+
+MObjectProvider *QCoeFepInputContext::MopNext()
+{
+ QWidget *w = focusWidget();
+ if (w)
+ return w->effectiveWinId();
+ return 0;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_IM
diff --git a/src/gui/painting/qcolormap_s60.cpp b/src/widgets/platforms/s60/qcolormap_s60.cpp
index 9dd5135d29..9dd5135d29 100644
--- a/src/gui/painting/qcolormap_s60.cpp
+++ b/src/widgets/platforms/s60/qcolormap_s60.cpp
diff --git a/src/gui/kernel/qcursor_s60.cpp b/src/widgets/platforms/s60/qcursor_s60.cpp
index 2e9a2bfa33..2e9a2bfa33 100644
--- a/src/gui/kernel/qcursor_s60.cpp
+++ b/src/widgets/platforms/s60/qcursor_s60.cpp
diff --git a/src/gui/kernel/qdesktopwidget_s60.cpp b/src/widgets/platforms/s60/qdesktopwidget_s60.cpp
index 156c9700ed..156c9700ed 100644
--- a/src/gui/kernel/qdesktopwidget_s60.cpp
+++ b/src/widgets/platforms/s60/qdesktopwidget_s60.cpp
diff --git a/src/gui/kernel/qdnd_s60.cpp b/src/widgets/platforms/s60/qdnd_s60.cpp
index 53afa71828..53afa71828 100644
--- a/src/gui/kernel/qdnd_s60.cpp
+++ b/src/widgets/platforms/s60/qdnd_s60.cpp
diff --git a/src/gui/kernel/qeventdispatcher_s60.cpp b/src/widgets/platforms/s60/qeventdispatcher_s60.cpp
index 3f20c08084..3f20c08084 100644
--- a/src/gui/kernel/qeventdispatcher_s60.cpp
+++ b/src/widgets/platforms/s60/qeventdispatcher_s60.cpp
diff --git a/src/widgets/platforms/s60/qeventdispatcher_s60_p.h b/src/widgets/platforms/s60/qeventdispatcher_s60_p.h
new file mode 100644
index 0000000000..8e644a2d06
--- /dev/null
+++ b/src/widgets/platforms/s60/qeventdispatcher_s60_p.h
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QEVENTDISPATCHER_S60_P_H
+#define QEVENTDISPATCHER_S60_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <private/qeventdispatcher_symbian_p.h>
+#include "qt_s60_p.h"
+
+#include <eikenv.h>
+
+QT_BEGIN_NAMESPACE
+
+class QEventDispatcherS60;
+
+class QtEikonEnv : public CEikonEnv
+{
+public:
+ QtEikonEnv();
+ ~QtEikonEnv();
+
+ // from CActive.
+ void RunL();
+ void DoCancel();
+
+ void complete();
+
+private:
+ // Workaround for a BC break from S60 3.2 -> 5.0, where the CEikonEnv override was removed.
+ // To avoid linking to that when we build against 3.2, define an empty body here.
+ // Reserved_*() have been verified to be empty in the S60 code.
+ void Reserved_1() {}
+ void Reserved_2() {}
+
+private:
+ int m_lastIterationCount;
+ TInt m_savedStatusCode;
+ bool m_hasAlreadyRun;
+};
+
+class Q_WIDGETS_EXPORT QEventDispatcherS60 : public QEventDispatcherSymbian
+{
+ Q_OBJECT
+
+public:
+ QEventDispatcherS60(QObject *parent = 0);
+ ~QEventDispatcherS60();
+
+ bool processEvents ( QEventLoop::ProcessEventsFlags flags );
+ bool hasPendingEvents();
+
+ bool excludeUserInputEvents() { return m_noInputEvents; }
+
+ void saveInputEvent(QSymbianControl *control, QWidget *widget, QInputEvent *event);
+
+ void reactivateDeferredActiveObjects();
+
+private:
+ bool sendDeferredInputEvents();
+
+private Q_SLOTS:
+ void removeInputEventsForWidget(QObject *object);
+
+private:
+ bool m_noInputEvents;
+
+ struct DeferredInputEvent
+ {
+ QSymbianControl *control;
+ QWidget *widget;
+ QInputEvent *event;
+ };
+ QList<DeferredInputEvent> m_deferredInputEvents;
+};
+
+QT_END_NAMESPACE
+
+#endif // QEVENTDISPATCHER_S60_P_H
diff --git a/src/gui/text/qfont_s60.cpp b/src/widgets/platforms/s60/qfont_s60.cpp
index e0f4bad527..e0f4bad527 100644
--- a/src/gui/text/qfont_s60.cpp
+++ b/src/widgets/platforms/s60/qfont_s60.cpp
diff --git a/src/gui/text/qfontdatabase_s60.cpp b/src/widgets/platforms/s60/qfontdatabase_s60.cpp
index cfa405dbc1..cfa405dbc1 100644
--- a/src/gui/text/qfontdatabase_s60.cpp
+++ b/src/widgets/platforms/s60/qfontdatabase_s60.cpp
diff --git a/src/gui/text/qfontengine_s60.cpp b/src/widgets/platforms/s60/qfontengine_s60.cpp
index b4de066306..b4de066306 100644
--- a/src/gui/text/qfontengine_s60.cpp
+++ b/src/widgets/platforms/s60/qfontengine_s60.cpp
diff --git a/src/gui/text/qfontengine_s60_p.h b/src/widgets/platforms/s60/qfontengine_s60_p.h
index c4fa9d16fe..c4fa9d16fe 100644
--- a/src/gui/text/qfontengine_s60_p.h
+++ b/src/widgets/platforms/s60/qfontengine_s60_p.h
diff --git a/src/gui/kernel/qkeymapper_s60.cpp b/src/widgets/platforms/s60/qkeymapper_s60.cpp
index 1113b77875..1113b77875 100644
--- a/src/gui/kernel/qkeymapper_s60.cpp
+++ b/src/widgets/platforms/s60/qkeymapper_s60.cpp
diff --git a/src/widgets/platforms/s60/qpaintengine_s60.cpp b/src/widgets/platforms/s60/qpaintengine_s60.cpp
new file mode 100644
index 0000000000..67984008ca
--- /dev/null
+++ b/src/widgets/platforms/s60/qpaintengine_s60.cpp
@@ -0,0 +1,145 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <private/qpaintengine_s60_p.h>
+#include <private/qpixmap_s60_p.h>
+#include <private/qt_s60_p.h>
+#include <private/qvolatileimage_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QS60PaintEnginePrivate : public QRasterPaintEnginePrivate
+{
+public:
+ QS60PaintEnginePrivate() {}
+};
+
+QS60PaintEngine::QS60PaintEngine(QPaintDevice *device, QS60PlatformPixmap *data)
+ : QRasterPaintEngine(*(new QS60PaintEnginePrivate), device), handle(data)
+{
+}
+
+bool QS60PaintEngine::begin(QPaintDevice *device)
+{
+ Q_D(QS60PaintEngine);
+
+ if (handle->classId() == QPlatformPixmap::RasterClass) {
+ handle->beginDataAccess();
+ bool ret = QRasterPaintEngine::begin(device);
+ // Make sure QPaintEngine::paintDevice() returns the proper device.
+ // QRasterPaintEngine changes pdev to QImage in case of RasterClass QPlatformPixmap
+ // which is incorrect in Symbian.
+ d->pdev = device;
+ return ret;
+ }
+
+ return QRasterPaintEngine::begin(device);
+}
+
+bool QS60PaintEngine::end()
+{
+ if (handle->classId() == QPlatformPixmap::RasterClass) {
+ bool ret = QRasterPaintEngine::end();
+ handle->endDataAccess();
+ return ret;
+ }
+ return QRasterPaintEngine::end();
+}
+
+void QS60PaintEngine::drawPixmap(const QPointF &p, const QPixmap &pm)
+{
+ if (pm.handle()->classId() == QPlatformPixmap::RasterClass) {
+ QS60PlatformPixmap *srcData = static_cast<QS60PlatformPixmap *>(pm.handle());
+ srcData->beginDataAccess();
+ QRasterPaintEngine::drawPixmap(p, pm);
+ srcData->endDataAccess();
+ } else {
+ void *nativeData = pm.handle()->toNativeType(QPlatformPixmap::VolatileImage);
+ if (nativeData) {
+ QVolatileImage *img = static_cast<QVolatileImage *>(nativeData);
+ img->beginDataAccess();
+ QRasterPaintEngine::drawImage(p, img->imageRef());
+ img->endDataAccess(true);
+ } else {
+ QRasterPaintEngine::drawPixmap(p, pm);
+ }
+ }
+}
+
+void QS60PaintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr)
+{
+ if (pm.handle()->classId() == QPlatformPixmap::RasterClass) {
+ QS60PlatformPixmap *srcData = static_cast<QS60PlatformPixmap *>(pm.handle());
+ srcData->beginDataAccess();
+ QRasterPaintEngine::drawPixmap(r, pm, sr);
+ srcData->endDataAccess();
+ } else {
+ void *nativeData = pm.handle()->toNativeType(QPlatformPixmap::VolatileImage);
+ if (nativeData) {
+ QVolatileImage *img = static_cast<QVolatileImage *>(nativeData);
+ img->beginDataAccess();
+ QRasterPaintEngine::drawImage(r, img->imageRef(), sr);
+ img->endDataAccess(true);
+ } else {
+ QRasterPaintEngine::drawPixmap(r, pm, sr);
+ }
+ }
+}
+
+void QS60PaintEngine::drawTiledPixmap(const QRectF &r, const QPixmap &pm, const QPointF &sr)
+{
+ if (pm.handle()->classId() == QPlatformPixmap::RasterClass) {
+ QS60PlatformPixmap *srcData = static_cast<QS60PlatformPixmap *>(pm.handle());
+ srcData->beginDataAccess();
+ QRasterPaintEngine::drawTiledPixmap(r, pm, sr);
+ srcData->endDataAccess();
+ } else {
+ QRasterPaintEngine::drawTiledPixmap(r, pm, sr);
+ }
+}
+
+void QS60PaintEngine::prepare(QImage *image)
+{
+ QRasterBuffer *buffer = d_func()->rasterBuffer.data();
+ if (buffer)
+ buffer->prepare(image);
+}
+
+QT_END_NAMESPACE
diff --git a/src/widgets/platforms/s60/qpaintengine_s60_p.h b/src/widgets/platforms/s60/qpaintengine_s60_p.h
new file mode 100644
index 0000000000..4cea87954f
--- /dev/null
+++ b/src/widgets/platforms/s60/qpaintengine_s60_p.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPAINTENGINE_S60_P_H
+#define QPAINTENGINE_S60_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "private/qpaintengine_raster_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QS60PaintEnginePrivate;
+class QS60PlatformPixmap;
+
+class QS60PaintEngine : public QRasterPaintEngine
+{
+ Q_DECLARE_PRIVATE(QS60PaintEngine)
+
+public:
+ QS60PaintEngine(QPaintDevice *device, QS60PlatformPixmap* data);
+ bool begin(QPaintDevice *device);
+ bool end();
+
+ void drawPixmap(const QPointF &p, const QPixmap &pm);
+ void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr);
+ void drawTiledPixmap(const QRectF &r, const QPixmap &pm, const QPointF &sr);
+
+ void prepare(QImage* image);
+
+private:
+ QS60PlatformPixmap *handle;
+};
+
+QT_END_NAMESPACE
+
+#endif // QPAINTENGINE_S60_P_H
diff --git a/src/widgets/platforms/s60/qpixmap_s60.cpp b/src/widgets/platforms/s60/qpixmap_s60.cpp
new file mode 100644
index 0000000000..5e1474546e
--- /dev/null
+++ b/src/widgets/platforms/s60/qpixmap_s60.cpp
@@ -0,0 +1,1040 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <exception>
+#include <w32std.h>
+#include <fbs.h>
+
+#include <private/qapplication_p.h>
+#include <private/qgraphicssystem_p.h>
+#include <private/qt_s60_p.h>
+#include <private/qpaintengine_s60_p.h>
+#include <private/qfont_p.h>
+
+#include "qpixmap.h"
+#include "qpixmap_raster_p.h"
+#include <qwidget.h>
+#include "qpixmap_s60_p.h"
+#include "qnativeimage_p.h"
+#include "qbitmap.h"
+#include "qimage.h"
+#include "qimage_p.h"
+
+#include <fbs.h>
+
+QT_BEGIN_NAMESPACE
+
+const uchar qt_pixmap_bit_mask[] = { 0x01, 0x02, 0x04, 0x08,
+ 0x10, 0x20, 0x40, 0x80 };
+
+static bool cleanup_function_registered = false;
+static QS60PlatformPixmap *firstPixmap = 0;
+
+// static
+void QS60PlatformPixmap::qt_symbian_register_pixmap(QS60PlatformPixmap *pd)
+{
+ if (!cleanup_function_registered) {
+ qAddPostRoutine(qt_symbian_release_pixmaps);
+ cleanup_function_registered = true;
+ }
+
+ pd->next = firstPixmap;
+ pd->prev = 0;
+ if (firstPixmap)
+ firstPixmap->prev = pd;
+ firstPixmap = pd;
+}
+
+// static
+void QS60PlatformPixmap::qt_symbian_unregister_pixmap(QS60PlatformPixmap *pd)
+{
+ if (pd->next)
+ pd->next->prev = pd->prev;
+ if (pd->prev)
+ pd->prev->next = pd->next;
+ else
+ firstPixmap = pd->next;
+}
+
+// static
+void QS60PlatformPixmap::qt_symbian_release_pixmaps()
+{
+ // Scan all QS60PlatformPixmap objects in the system and destroy them.
+ QS60PlatformPixmap *pd = firstPixmap;
+ while (pd != 0) {
+ pd->release();
+ pd = pd->next;
+ }
+}
+
+/*
+ \class QSymbianFbsClient
+ \since 4.6
+ \internal
+
+ Symbian Font And Bitmap server client that is
+ used to lock the global bitmap heap. Only used in
+ S60 v3.1 and S60 v3.2.
+*/
+_LIT(KFBSERVLargeBitmapAccessName,"FbsLargeBitmapAccess");
+class QSymbianFbsClient
+{
+public:
+
+ QSymbianFbsClient() : heapLocked(false)
+ {
+ heapLock.OpenGlobal(KFBSERVLargeBitmapAccessName);
+ }
+
+ ~QSymbianFbsClient()
+ {
+ heapLock.Close();
+ }
+
+ bool lockHeap()
+ {
+ bool wasLocked = heapLocked;
+
+ if (heapLock.Handle() && !heapLocked) {
+ heapLock.Wait();
+ heapLocked = true;
+ }
+
+ return wasLocked;
+ }
+
+ bool unlockHeap()
+ {
+ bool wasLocked = heapLocked;
+
+ if (heapLock.Handle() && heapLocked) {
+ heapLock.Signal();
+ heapLocked = false;
+ }
+
+ return wasLocked;
+ }
+
+
+private:
+
+ RMutex heapLock;
+ bool heapLocked;
+};
+
+Q_GLOBAL_STATIC(QSymbianFbsClient, qt_symbianFbsClient);
+
+
+
+// QSymbianFbsHeapLock
+
+QSymbianFbsHeapLock::QSymbianFbsHeapLock(LockAction a)
+: action(a), wasLocked(false)
+{
+ QSysInfo::SymbianVersion symbianVersion = QSysInfo::symbianVersion();
+ if (symbianVersion == QSysInfo::SV_9_2 || symbianVersion == QSysInfo::SV_9_3)
+ wasLocked = qt_symbianFbsClient()->unlockHeap();
+}
+
+QSymbianFbsHeapLock::~QSymbianFbsHeapLock()
+{
+ // Do nothing
+}
+
+void QSymbianFbsHeapLock::relock()
+{
+ QSysInfo::SymbianVersion symbianVersion = QSysInfo::symbianVersion();
+ if (wasLocked && (symbianVersion == QSysInfo::SV_9_2 || symbianVersion == QSysInfo::SV_9_3))
+ qt_symbianFbsClient()->lockHeap();
+}
+
+/*
+ \class QSymbianBitmapDataAccess
+ \since 4.6
+ \internal
+
+ Data access class that is used to locks/unlocks pixel data
+ when drawing or modifying CFbsBitmap pixel data.
+*/
+class QSymbianBitmapDataAccess
+{
+public:
+
+ static int heapRefCount;
+ QSysInfo::SymbianVersion symbianVersion;
+
+ explicit QSymbianBitmapDataAccess()
+ {
+ symbianVersion = QSysInfo::symbianVersion();
+ };
+
+ ~QSymbianBitmapDataAccess() {};
+
+ inline void beginDataAccess(CFbsBitmap *bitmap)
+ {
+ if (symbianVersion == QSysInfo::SV_9_2) {
+ if (heapRefCount == 0)
+ qt_symbianFbsClient()->lockHeap();
+ } else {
+ bitmap->LockHeap(ETrue);
+ }
+
+ heapRefCount++;
+ }
+
+ inline void endDataAccess(CFbsBitmap *bitmap)
+ {
+ heapRefCount--;
+
+ if (symbianVersion == QSysInfo::SV_9_2) {
+ if (heapRefCount == 0)
+ qt_symbianFbsClient()->unlockHeap();
+ } else {
+ bitmap->UnlockHeap(ETrue);
+ }
+ }
+};
+
+int QSymbianBitmapDataAccess::heapRefCount = 0;
+
+
+#define UPDATE_BUFFER() \
+ { \
+ beginDataAccess(); \
+ endDataAccess(); \
+}
+
+
+static CFbsBitmap* createSymbianCFbsBitmap(const TSize& size, TDisplayMode mode)
+{
+ QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock);
+
+ CFbsBitmap* bitmap = 0;
+ QT_TRAP_THROWING(bitmap = new (ELeave) CFbsBitmap);
+
+ if (bitmap->Create(size, mode) != KErrNone) {
+ delete bitmap;
+ bitmap = 0;
+ }
+
+ lock.relock();
+
+ return bitmap;
+}
+
+static CFbsBitmap* uncompress(CFbsBitmap* bitmap)
+{
+ if(bitmap->IsCompressedInRAM()) {
+ QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock);
+
+ CFbsBitmap *uncompressed = 0;
+ QT_TRAP_THROWING(uncompressed = new (ELeave) CFbsBitmap);
+
+ if (uncompressed->Create(bitmap->SizeInPixels(), bitmap->DisplayMode()) != KErrNone) {
+ delete bitmap;
+ bitmap = 0;
+ lock.relock();
+
+ return bitmap;
+ }
+
+ lock.relock();
+
+ CFbsBitmapDevice* bitmapDevice = 0;
+ CFbsBitGc *bitmapGc = 0;
+ QT_TRAP_THROWING(bitmapDevice = CFbsBitmapDevice::NewL(uncompressed));
+ QT_TRAP_THROWING(bitmapGc = CFbsBitGc::NewL());
+ bitmapGc->Activate(bitmapDevice);
+
+ bitmapGc->BitBlt(TPoint(), bitmap);
+
+ delete bitmapGc;
+ delete bitmapDevice;
+
+ return uncompressed;
+ } else {
+ return bitmap;
+ }
+}
+
+QPixmap QPixmap::grabWindow(WId winId, int x, int y, int w, int h)
+{
+ CWsScreenDevice* screenDevice = S60->screenDevice();
+ TSize screenSize = screenDevice->SizeInPixels();
+
+ TSize srcSize;
+ // Find out if this is one of our windows.
+ QSymbianControl *sControl;
+ sControl = winId->MopGetObject(sControl);
+ if (sControl && sControl->widget()->windowType() == Qt::Desktop) {
+ // Grabbing desktop widget
+ srcSize = screenSize;
+ } else {
+ TPoint relativePos = winId->PositionRelativeToScreen();
+ x += relativePos.iX;
+ y += relativePos.iY;
+ srcSize = winId->Size();
+ }
+
+ TRect srcRect(TPoint(x, y), srcSize);
+ // Clip to the screen
+ srcRect.Intersection(TRect(screenSize));
+
+ if (w > 0 && h > 0) {
+ TRect subRect(TPoint(x, y), TSize(w, h));
+ // Clip to the subRect
+ srcRect.Intersection(subRect);
+ }
+
+ if (srcRect.IsEmpty())
+ return QPixmap();
+
+ CFbsBitmap* temporary = createSymbianCFbsBitmap(srcRect.Size(), screenDevice->DisplayMode());
+
+ QPixmap pix;
+
+ if (temporary && screenDevice->CopyScreenToBitmap(temporary, srcRect) == KErrNone) {
+ pix = QPixmap::fromSymbianCFbsBitmap(temporary);
+ }
+
+ delete temporary;
+ return pix;
+}
+
+/*!
+ \fn CFbsBitmap *QPixmap::toSymbianCFbsBitmap() const
+ \since 4.6
+
+ Creates a \c CFbsBitmap that is equivalent to the QPixmap. Internally this
+ function will try to duplicate the handle instead of copying the data,
+ however in scenarios where this is not possible the data will be copied.
+ If the creation fails or the pixmap is null, then this function returns 0.
+
+ It is the caller's responsibility to release the \c CFbsBitmap data
+ after use either by deleting the bitmap or calling \c Reset().
+
+ \warning On S60 3.1 and S60 3.2, semi-transparent pixmaps are always copied
+ and not duplicated.
+ \warning This function is only available on Symbian OS.
+
+ \sa fromSymbianCFbsBitmap()
+*/
+CFbsBitmap *QPixmap::toSymbianCFbsBitmap() const
+{
+ QPlatformPixmap *data = handle();
+ if (!data || data->isNull())
+ return 0;
+
+ return reinterpret_cast<CFbsBitmap*>(data->toNativeType(QPlatformPixmap::FbsBitmap));
+}
+
+/*!
+ \fn QPixmap QPixmap::fromSymbianCFbsBitmap(CFbsBitmap *bitmap)
+ \since 4.6
+
+ Creates a QPixmap from a \c CFbsBitmap \a bitmap. Internally this function
+ will try to duplicate the bitmap handle instead of copying the data, however
+ in scenarios where this is not possible the data will be copied.
+ To be sure that QPixmap does not modify your original instance, you should
+ make a copy of your \c CFbsBitmap before calling this function.
+ If the CFbsBitmap is not valid this function will return a null QPixmap.
+ For performance reasons it is recommended to use a \a bitmap with a display
+ mode of EColor16MAP or EColor16MU whenever possible.
+
+ \warning This function is only available on Symbian OS.
+
+ \sa toSymbianCFbsBitmap(), {QPixmap#Pixmap Conversion}{Pixmap Conversion}
+*/
+QPixmap QPixmap::fromSymbianCFbsBitmap(CFbsBitmap *bitmap)
+{
+ if (!bitmap)
+ return QPixmap();
+
+ QScopedPointer<QPlatformPixmap> data(QPlatformPixmap::create(0,0, QPlatformPixmap::PixmapType));
+ data->fromNativeType(reinterpret_cast<void*>(bitmap), QPlatformPixmap::FbsBitmap);
+ QPixmap pixmap(data.take());
+ return pixmap;
+}
+
+QS60PlatformPixmap::QS60PlatformPixmap(PixelType type) : QRasterPlatformPixmap(type),
+ symbianBitmapDataAccess(new QSymbianBitmapDataAccess),
+ cfbsBitmap(0),
+ pengine(0),
+ bytes(0),
+ formatLocked(false),
+ next(0),
+ prev(0)
+{
+ qt_symbian_register_pixmap(this);
+}
+
+QS60PlatformPixmap::~QS60PlatformPixmap()
+{
+ release();
+ delete symbianBitmapDataAccess;
+ qt_symbian_unregister_pixmap(this);
+}
+
+void QS60PlatformPixmap::resize(int width, int height)
+{
+ if (width <= 0 || height <= 0) {
+ w = width;
+ h = height;
+ is_null = true;
+
+ release();
+ return;
+ } else if (!cfbsBitmap) {
+ TDisplayMode mode;
+ if (pixelType() == BitmapType)
+ mode = EGray2;
+ else
+ mode = EColor16MU;
+
+ CFbsBitmap* bitmap = createSymbianCFbsBitmap(TSize(width, height), mode);
+ fromSymbianBitmap(bitmap);
+ } else {
+
+ TSize newSize(width, height);
+
+ if(cfbsBitmap->SizeInPixels() != newSize) {
+ cfbsBitmap->Resize(TSize(width, height));
+ if(pengine) {
+ delete pengine;
+ pengine = 0;
+ }
+ }
+
+ UPDATE_BUFFER();
+ }
+}
+
+void QS60PlatformPixmap::release()
+{
+ if (cfbsBitmap) {
+ QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock);
+ delete cfbsBitmap;
+ lock.relock();
+ }
+
+ delete pengine;
+ image = QImage();
+ cfbsBitmap = 0;
+ pengine = 0;
+ bytes = 0;
+}
+
+/*!
+ * Takes ownership of bitmap. Used by window surface
+ */
+void QS60PlatformPixmap::fromSymbianBitmap(CFbsBitmap* bitmap, bool lockFormat)
+{
+ Q_ASSERT(bitmap);
+
+ release();
+
+ cfbsBitmap = bitmap;
+ formatLocked = lockFormat;
+
+ setSerialNumber(cfbsBitmap->Handle());
+
+ UPDATE_BUFFER();
+
+ // Create default palette if needed
+ if (cfbsBitmap->DisplayMode() == EGray2) {
+ image.setColorCount(2);
+ image.setColor(0, QColor(Qt::color0).rgba());
+ image.setColor(1, QColor(Qt::color1).rgba());
+
+ //Symbian thinks set pixels are white/transparent, Qt thinks they are foreground/solid
+ //So invert mono bitmaps so that masks work correctly.
+ image.invertPixels();
+ } else if (cfbsBitmap->DisplayMode() == EGray256) {
+ for (int i=0; i < 256; ++i)
+ image.setColor(i, qRgb(i, i, i));
+ } else if (cfbsBitmap->DisplayMode() == EColor256) {
+ const TColor256Util *palette = TColor256Util::Default();
+ for (int i=0; i < 256; ++i)
+ image.setColor(i, (QRgb)(palette->Color256(i).Value()));
+ }
+}
+
+QImage QS60PlatformPixmap::toImage(const QRect &r) const
+{
+ QS60PlatformPixmap *that = const_cast<QS60PlatformPixmap*>(this);
+ that->beginDataAccess();
+ QImage copy = that->image.copy(r);
+ that->endDataAccess();
+
+ return copy;
+}
+
+void QS60PlatformPixmap::fromImage(const QImage &img, Qt::ImageConversionFlags flags)
+{
+ release();
+
+ QImage sourceImage;
+
+ if (pixelType() == BitmapType) {
+ sourceImage = img.convertToFormat(QImage::Format_MonoLSB);
+ } else {
+ if (img.depth() == 1) {
+ sourceImage = img.hasAlphaChannel()
+ ? img.convertToFormat(QImage::Format_ARGB32_Premultiplied)
+ : img.convertToFormat(QImage::Format_RGB32);
+ } else {
+
+ QImage::Format opaqueFormat = QNativeImage::systemFormat();
+ QImage::Format alphaFormat = QImage::Format_ARGB32_Premultiplied;
+
+ if (!img.hasAlphaChannel()
+ || ((flags & Qt::NoOpaqueDetection) == 0
+ && !const_cast<QImage &>(img).data_ptr()->checkForAlphaPixels())) {
+ sourceImage = img.convertToFormat(opaqueFormat);
+ } else {
+ sourceImage = img.convertToFormat(alphaFormat);
+ }
+ }
+ }
+
+
+ QImage::Format destFormat = sourceImage.format();
+ TDisplayMode mode;
+ switch (destFormat) {
+ case QImage::Format_MonoLSB:
+ mode = EGray2;
+ break;
+ case QImage::Format_RGB32:
+ mode = EColor16MU;
+ break;
+ case QImage::Format_ARGB32_Premultiplied:
+ if (S60->supportsPremultipliedAlpha) {
+ mode = Q_SYMBIAN_ECOLOR16MAP;
+ break;
+ } else {
+ destFormat = QImage::Format_ARGB32;
+ }
+ // Fall through intended
+ case QImage::Format_ARGB32:
+ mode = EColor16MA;
+ break;
+ case QImage::Format_Invalid:
+ return;
+ default:
+ qWarning("Image format not supported: %d", image.format());
+ return;
+ }
+
+ cfbsBitmap = createSymbianCFbsBitmap(TSize(sourceImage.width(), sourceImage.height()), mode);
+ if (!cfbsBitmap) {
+ qWarning("Could not create CFbsBitmap");
+ release();
+ return;
+ }
+
+ setSerialNumber(cfbsBitmap->Handle());
+
+ const uchar *sptr = const_cast<const QImage &>(sourceImage).bits();
+ symbianBitmapDataAccess->beginDataAccess(cfbsBitmap);
+ uchar *dptr = (uchar*)cfbsBitmap->DataAddress();
+ Mem::Copy(dptr, sptr, sourceImage.byteCount());
+ symbianBitmapDataAccess->endDataAccess(cfbsBitmap);
+
+ UPDATE_BUFFER();
+
+ if (destFormat == QImage::Format_MonoLSB) {
+ image.setColorCount(2);
+ image.setColor(0, QColor(Qt::color0).rgba());
+ image.setColor(1, QColor(Qt::color1).rgba());
+ } else {
+ image.setColorTable(sourceImage.colorTable());
+ }
+}
+
+void QS60PlatformPixmap::copy(const QPlatformPixmap *data, const QRect &rect)
+{
+ const QS60PlatformPixmap *s60Data = static_cast<const QS60PlatformPixmap*>(data);
+ fromImage(s60Data->toImage(rect), Qt::AutoColor | Qt::OrderedAlphaDither);
+}
+
+bool QS60PlatformPixmap::scroll(int dx, int dy, const QRect &rect)
+{
+ beginDataAccess();
+ bool res = QRasterPlatformPixmap::scroll(dx, dy, rect);
+ endDataAccess();
+ return res;
+}
+
+int QS60PlatformPixmap::metric(QPaintDevice::PaintDeviceMetric metric) const
+{
+ if (!cfbsBitmap)
+ return 0;
+
+ switch (metric) {
+ case QPaintDevice::PdmWidth:
+ return cfbsBitmap->SizeInPixels().iWidth;
+ case QPaintDevice::PdmHeight:
+ return cfbsBitmap->SizeInPixels().iHeight;
+ case QPaintDevice::PdmWidthMM:
+ return qRound(cfbsBitmap->SizeInPixels().iWidth * 25.4 / qt_defaultDpiX());
+ case QPaintDevice::PdmHeightMM:
+ return qRound(cfbsBitmap->SizeInPixels().iHeight * 25.4 / qt_defaultDpiY());
+ case QPaintDevice::PdmNumColors:
+ return TDisplayModeUtils::NumDisplayModeColors(cfbsBitmap->DisplayMode());
+ case QPaintDevice::PdmDpiX:
+ case QPaintDevice::PdmPhysicalDpiX:
+ return qt_defaultDpiX();
+ case QPaintDevice::PdmDpiY:
+ case QPaintDevice::PdmPhysicalDpiY:
+ return qt_defaultDpiY();
+ case QPaintDevice::PdmDepth:
+ return TDisplayModeUtils::NumDisplayModeBitsPerPixel(cfbsBitmap->DisplayMode());
+ default:
+ qWarning("QPixmap::metric: Invalid metric command");
+ }
+ return 0;
+
+}
+
+void QS60PlatformPixmap::fill(const QColor &color)
+{
+ if (color.alpha() != 255) {
+ QImage im(width(), height(), QImage::Format_ARGB32_Premultiplied);
+ im.fill(PREMUL(color.rgba()));
+ release();
+ fromImage(im, Qt::AutoColor | Qt::OrderedAlphaDither);
+ } else {
+ beginDataAccess();
+ QRasterPlatformPixmap::fill(color);
+ endDataAccess();
+ }
+}
+
+void QS60PlatformPixmap::setMask(const QBitmap &mask)
+{
+ if (mask.size().isEmpty()) {
+ if (image.depth() != 1) {
+ QImage newImage = image.convertToFormat(QImage::Format_RGB32);
+ release();
+ fromImage(newImage, Qt::AutoColor | Qt::OrderedAlphaDither);
+ }
+ } else if (image.depth() == 1) {
+ beginDataAccess();
+ QRasterPlatformPixmap::setMask(mask);
+ endDataAccess();
+ } else {
+ const int w = image.width();
+ const int h = image.height();
+
+ const QImage imageMask = mask.toImage().convertToFormat(QImage::Format_MonoLSB);
+ QImage newImage = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
+ for (int y = 0; y < h; ++y) {
+ const uchar *mscan = imageMask.scanLine(y);
+ QRgb *tscan = (QRgb *)newImage.scanLine(y);
+ for (int x = 0; x < w; ++x) {
+ if (!(mscan[x>>3] & qt_pixmap_bit_mask[x&7]))
+ tscan[x] = 0;
+ }
+ }
+ release();
+ fromImage(newImage, Qt::AutoColor | Qt::OrderedAlphaDither);
+ }
+}
+
+void QS60PlatformPixmap::setAlphaChannel(const QPixmap &alphaChannel)
+{
+ QImage img(toImage());
+ img.setAlphaChannel(alphaChannel.toImage());
+ release();
+ fromImage(img, Qt::OrderedDither | Qt::OrderedAlphaDither);
+}
+
+QImage QS60PlatformPixmap::toImage() const
+{
+ return toImage(QRect());
+}
+
+QPaintEngine* QS60PlatformPixmap::paintEngine() const
+{
+ if (!pengine) {
+ QS60PlatformPixmap *that = const_cast<QS60PlatformPixmap*>(this);
+ that->pengine = new QS60PaintEngine(&that->image, that);
+ }
+ return pengine;
+}
+
+void QS60PlatformPixmap::beginDataAccess()
+{
+ if(!cfbsBitmap)
+ return;
+
+ symbianBitmapDataAccess->beginDataAccess(cfbsBitmap);
+
+ uchar* newBytes = (uchar*)cfbsBitmap->DataAddress();
+
+ TSize size = cfbsBitmap->SizeInPixels();
+
+ if (newBytes == bytes && image.width() == size.iWidth && image.height() == size.iHeight)
+ return;
+
+ bytes = newBytes;
+ TDisplayMode mode = cfbsBitmap->DisplayMode();
+ QImage::Format format = qt_TDisplayMode2Format(mode);
+ // On S60 3.1, premultiplied alpha pixels are stored in a bitmap with 16MA type.
+ // S60 window surface needs backing store pixmap for transparent window in ARGB32 format.
+ // In that case formatLocked is true.
+ if (!formatLocked && format == QImage::Format_ARGB32)
+ format = QImage::Format_ARGB32_Premultiplied; // pixel data is actually in premultiplied format
+
+ QVector<QRgb> savedColorTable;
+ if (!image.isNull())
+ savedColorTable = image.colorTable();
+
+ image = QImage(bytes, size.iWidth, size.iHeight, format);
+
+ // Restore the palette or create a default
+ if (!savedColorTable.isEmpty()) {
+ image.setColorTable(savedColorTable);
+ }
+
+ w = size.iWidth;
+ h = size.iHeight;
+ d = image.depth();
+ is_null = (w <= 0 || h <= 0);
+
+ if (pengine) {
+ QS60PaintEngine *engine = static_cast<QS60PaintEngine *>(pengine);
+ engine->prepare(&image);
+ }
+}
+
+void QS60PlatformPixmap::endDataAccess(bool readOnly) const
+{
+ Q_UNUSED(readOnly);
+
+ if(!cfbsBitmap)
+ return;
+
+ symbianBitmapDataAccess->endDataAccess(cfbsBitmap);
+}
+
+/*!
+ \since 4.6
+
+ Returns a QPixmap that wraps given \a sgImage graphics resource.
+ The data should be valid even when original RSgImage handle has been
+ closed.
+
+ \warning This function is only available on Symbian OS.
+
+ \sa toSymbianRSgImage(), {QPixmap#Pixmap Conversion}{Pixmap Conversion}
+*/
+
+QPixmap QPixmap::fromSymbianRSgImage(RSgImage *sgImage)
+{
+ // It is expected that RSgImage will
+ // CURRENTLY be used in conjuction with
+ // OpenVG graphics system
+ //
+ // Surely things might change in future
+
+ if (!sgImage)
+ return QPixmap();
+
+ QScopedPointer<QPlatformPixmap> data(QPlatformPixmap::create(0,0, QPlatformPixmap::PixmapType));
+ data->fromNativeType(reinterpret_cast<void*>(sgImage), QPlatformPixmap::SgImage);
+ QPixmap pixmap(data.take());
+ return pixmap;
+}
+
+/*!
+\since 4.6
+
+Returns a \c RSgImage that is equivalent to the QPixmap by copying the data.
+
+It is the caller's responsibility to close/delete the \c RSgImage after use.
+
+\warning This function is only available on Symbian OS.
+
+\sa fromSymbianRSgImage()
+*/
+
+RSgImage *QPixmap::toSymbianRSgImage() const
+{
+ // It is expected that RSgImage will
+ // CURRENTLY be used in conjuction with
+ // OpenVG graphics system
+ //
+ // Surely things might change in future
+
+ if (isNull())
+ return 0;
+
+ RSgImage *sgImage = reinterpret_cast<RSgImage*>(handle()->toNativeType(QPlatformPixmap::SgImage));
+
+ return sgImage;
+}
+
+void* QS60PlatformPixmap::toNativeType(NativeType type)
+{
+ if (type == QPlatformPixmap::SgImage) {
+ return 0;
+ } else if (type == QPlatformPixmap::FbsBitmap) {
+
+ if (isNull() || !cfbsBitmap)
+ return 0;
+
+ bool convertToArgb32 = false;
+ bool needsCopy = false;
+
+ if (!(S60->supportsPremultipliedAlpha)) {
+ // Convert argb32_premultiplied to argb32 since Symbian 9.2 does
+ // not support premultipied format.
+
+ if (image.format() == QImage::Format_ARGB32_Premultiplied) {
+ needsCopy = true;
+ convertToArgb32 = true;
+ }
+ }
+
+ CFbsBitmap *bitmap = 0;
+
+ TDisplayMode displayMode = cfbsBitmap->DisplayMode();
+
+ if(displayMode == EGray2) {
+ //Symbian thinks set pixels are white/transparent, Qt thinks they are foreground/solid
+ //So invert mono bitmaps so that masks work correctly.
+ beginDataAccess();
+ image.invertPixels();
+ endDataAccess();
+ needsCopy = true;
+ }
+
+ if (needsCopy) {
+ QImage source;
+
+ if (convertToArgb32) {
+ beginDataAccess();
+ source = image.convertToFormat(QImage::Format_ARGB32);
+ endDataAccess();
+ displayMode = EColor16MA;
+ } else {
+ source = image;
+ }
+
+ CFbsBitmap *newBitmap = createSymbianCFbsBitmap(TSize(source.width(), source.height()), displayMode);
+ const uchar *sptr = source.bits();
+ symbianBitmapDataAccess->beginDataAccess(newBitmap);
+
+ uchar *dptr = (uchar*)newBitmap->DataAddress();
+ Mem::Copy(dptr, sptr, source.byteCount());
+
+ symbianBitmapDataAccess->endDataAccess(newBitmap);
+
+ bitmap = newBitmap;
+ } else {
+
+ QT_TRAP_THROWING(bitmap = new (ELeave) CFbsBitmap);
+
+ TInt err = bitmap->Duplicate(cfbsBitmap->Handle());
+ if (err != KErrNone) {
+ qWarning("Could not duplicate CFbsBitmap");
+ delete bitmap;
+ bitmap = 0;
+ }
+ }
+
+ if(displayMode == EGray2) {
+ // restore pixels
+ beginDataAccess();
+ image.invertPixels();
+ endDataAccess();
+ }
+
+ return reinterpret_cast<void*>(bitmap);
+
+ }
+
+ return 0;
+}
+
+void QS60PlatformPixmap::fromNativeType(void* pixmap, NativeType nativeType)
+{
+ if (nativeType == QPlatformPixmap::SgImage) {
+ return;
+ } else if (nativeType == QPlatformPixmap::FbsBitmap && pixmap) {
+
+ CFbsBitmap *bitmap = reinterpret_cast<CFbsBitmap*>(pixmap);
+
+ bool deleteSourceBitmap = false;
+ bool needsCopy = false;
+
+#ifdef Q_SYMBIAN_HAS_EXTENDED_BITMAP_TYPE
+
+ // Rasterize extended bitmaps
+
+ TUid extendedBitmapType = bitmap->ExtendedBitmapType();
+ if (extendedBitmapType != KNullUid) {
+ CFbsBitmap *rasterBitmap = createSymbianCFbsBitmap(bitmap->SizeInPixels(), EColor16MA);
+
+ CFbsBitmapDevice *rasterBitmapDev = 0;
+ QT_TRAP_THROWING(rasterBitmapDev = CFbsBitmapDevice::NewL(rasterBitmap));
+
+ CFbsBitGc *rasterBitmapGc = 0;
+ TInt err = rasterBitmapDev->CreateContext(rasterBitmapGc);
+ if (err != KErrNone) {
+ delete rasterBitmap;
+ delete rasterBitmapDev;
+ rasterBitmapDev = 0;
+ return;
+ }
+
+ rasterBitmapGc->BitBlt(TPoint( 0, 0), bitmap);
+
+ bitmap = rasterBitmap;
+
+ delete rasterBitmapDev;
+ delete rasterBitmapGc;
+
+ rasterBitmapDev = 0;
+ rasterBitmapGc = 0;
+
+ deleteSourceBitmap = true;
+ }
+#endif
+
+
+ deleteSourceBitmap = bitmap->IsCompressedInRAM();
+ CFbsBitmap *sourceBitmap = uncompress(bitmap);
+
+ TDisplayMode displayMode = sourceBitmap->DisplayMode();
+ QImage::Format format = qt_TDisplayMode2Format(displayMode);
+
+ QImage::Format opaqueFormat = QNativeImage::systemFormat();
+ QImage::Format alphaFormat = QImage::Format_ARGB32_Premultiplied;
+
+ if (format != opaqueFormat && format != alphaFormat && format != QImage::Format_MonoLSB)
+ needsCopy = true;
+
+
+ type = (format != QImage::Format_MonoLSB)
+ ? QPlatformPixmap::PixmapType
+ : QPlatformPixmap::BitmapType;
+
+ if (needsCopy) {
+
+ TSize size = sourceBitmap->SizeInPixels();
+ int bytesPerLine = sourceBitmap->ScanLineLength(size.iWidth, displayMode);
+
+ QSymbianBitmapDataAccess da;
+ da.beginDataAccess(sourceBitmap);
+ uchar *bytes = (uchar*)sourceBitmap->DataAddress();
+ QImage img = QImage(bytes, size.iWidth, size.iHeight, bytesPerLine, format);
+ img = img.copy();
+ da.endDataAccess(sourceBitmap);
+
+ if(displayMode == EGray2) {
+ //Symbian thinks set pixels are white/transparent, Qt thinks they are foreground/solid
+ //So invert mono bitmaps so that masks work correctly.
+ img.invertPixels();
+ } else if(displayMode == EColor16M) {
+ img = img.rgbSwapped(); // EColor16M is BGR
+ }
+
+ fromImage(img, Qt::AutoColor);
+
+ if(deleteSourceBitmap)
+ delete sourceBitmap;
+ } else {
+ CFbsBitmap* duplicate = 0;
+ QT_TRAP_THROWING(duplicate = new (ELeave) CFbsBitmap);
+
+ TInt err = duplicate->Duplicate(sourceBitmap->Handle());
+ if (err != KErrNone) {
+ qWarning("Could not duplicate CFbsBitmap");
+
+ if(deleteSourceBitmap)
+ delete sourceBitmap;
+
+ delete duplicate;
+ return;
+ }
+
+ fromSymbianBitmap(duplicate);
+
+ if(deleteSourceBitmap)
+ delete sourceBitmap;
+ }
+ }
+}
+
+void QS60PlatformPixmap::convertToDisplayMode(int mode)
+{
+ const TDisplayMode displayMode = static_cast<TDisplayMode>(mode);
+ if (!cfbsBitmap || cfbsBitmap->DisplayMode() == displayMode)
+ return;
+ if (image.depth() != TDisplayModeUtils::NumDisplayModeBitsPerPixel(displayMode)) {
+ qWarning("Cannot convert display mode due to depth mismatch");
+ return;
+ }
+
+ const TSize size = cfbsBitmap->SizeInPixels();
+ QScopedPointer<CFbsBitmap> newBitmap(createSymbianCFbsBitmap(size, displayMode));
+
+ const uchar *sptr = const_cast<const QImage &>(image).bits();
+ symbianBitmapDataAccess->beginDataAccess(newBitmap.data());
+ uchar *dptr = (uchar*)newBitmap->DataAddress();
+ Mem::Copy(dptr, sptr, image.byteCount());
+ symbianBitmapDataAccess->endDataAccess(newBitmap.data());
+
+ QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock);
+ delete cfbsBitmap;
+ lock.relock();
+ cfbsBitmap = newBitmap.take();
+ setSerialNumber(cfbsBitmap->Handle());
+ UPDATE_BUFFER();
+}
+
+QPlatformPixmap *QS60PlatformPixmap::createCompatiblePlatformPixmap() const
+{
+ return new QS60PlatformPixmap(pixelType());
+}
+
+QT_END_NAMESPACE
diff --git a/src/widgets/platforms/s60/qpixmap_s60_p.h b/src/widgets/platforms/s60/qpixmap_s60_p.h
new file mode 100644
index 0000000000..2f282e9498
--- /dev/null
+++ b/src/widgets/platforms/s60/qpixmap_s60_p.h
@@ -0,0 +1,141 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPIXMAPDATA_S60_P_H
+#define QPIXMAPDATA_S60_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtGui/private/qpixmap_raster_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class CFbsBitmap;
+class CFbsBitmapDevice;
+class CFbsBitGc;
+
+class QSymbianBitmapDataAccess;
+
+class QSymbianFbsHeapLock
+{
+public:
+
+ enum LockAction {
+ Unlock
+ };
+
+ explicit QSymbianFbsHeapLock(LockAction a);
+ ~QSymbianFbsHeapLock();
+ void relock();
+
+private:
+
+ LockAction action;
+ bool wasLocked;
+};
+
+class QS60PlatformPixmap : public QRasterPlatformPixmap
+{
+public:
+ QS60PlatformPixmap(PixelType type);
+ ~QS60PlatformPixmap();
+
+ QPlatformPixmap *createCompatiblePlatformPixmap() const;
+
+ void resize(int width, int height);
+ void fromImage(const QImage &image, Qt::ImageConversionFlags flags);
+ void copy(const QPlatformPixmap *data, const QRect &rect);
+ bool scroll(int dx, int dy, const QRect &rect);
+
+ int metric(QPaintDevice::PaintDeviceMetric metric) const;
+ void fill(const QColor &color);
+ void setMask(const QBitmap &mask);
+ void setAlphaChannel(const QPixmap &alphaChannel);
+ QImage toImage() const;
+ QPaintEngine* paintEngine() const;
+
+ void beginDataAccess();
+ void endDataAccess(bool readOnly=false) const;
+
+ void* toNativeType(NativeType type);
+ void fromNativeType(void* pixmap, NativeType type);
+
+ void convertToDisplayMode(int mode);
+
+private:
+ void release();
+ void fromSymbianBitmap(CFbsBitmap* bitmap, bool lockFormat=false);
+ QImage toImage(const QRect &r) const;
+
+ QSymbianBitmapDataAccess *symbianBitmapDataAccess;
+
+ CFbsBitmap *cfbsBitmap;
+ QPaintEngine *pengine;
+ uchar* bytes;
+
+ bool formatLocked;
+
+ QS60PlatformPixmap *next;
+ QS60PlatformPixmap *prev;
+
+ static void qt_symbian_register_pixmap(QS60PlatformPixmap *pd);
+ static void qt_symbian_unregister_pixmap(QS60PlatformPixmap *pd);
+ static void qt_symbian_release_pixmaps();
+
+ friend class QPixmap;
+ friend class QS60WindowSurface;
+ friend class QS60PaintEngine;
+ friend class QS60Data;
+};
+
+QT_END_NAMESPACE
+
+#endif // QPIXMAPDATA_S60_P_H
+
diff --git a/src/gui/painting/qregion_s60.cpp b/src/widgets/platforms/s60/qregion_s60.cpp
index bd5b701ca8..bd5b701ca8 100644
--- a/src/gui/painting/qregion_s60.cpp
+++ b/src/widgets/platforms/s60/qregion_s60.cpp
diff --git a/src/gui/kernel/qsoftkeymanager_s60.cpp b/src/widgets/platforms/s60/qsoftkeymanager_s60.cpp
index a7f83aaa43..a7f83aaa43 100644
--- a/src/gui/kernel/qsoftkeymanager_s60.cpp
+++ b/src/widgets/platforms/s60/qsoftkeymanager_s60.cpp
diff --git a/src/gui/kernel/qsoftkeymanager_s60_p.h b/src/widgets/platforms/s60/qsoftkeymanager_s60_p.h
index a16a8ca2ac..a16a8ca2ac 100644
--- a/src/gui/kernel/qsoftkeymanager_s60_p.h
+++ b/src/widgets/platforms/s60/qsoftkeymanager_s60_p.h
diff --git a/src/gui/kernel/qsound_s60.cpp b/src/widgets/platforms/s60/qsound_s60.cpp
index 1ed2ef3131..1ed2ef3131 100644
--- a/src/gui/kernel/qsound_s60.cpp
+++ b/src/widgets/platforms/s60/qsound_s60.cpp
diff --git a/src/gui/kernel/qt_s60_p.h b/src/widgets/platforms/s60/qt_s60_p.h
index aa60d16fab..aa60d16fab 100644
--- a/src/gui/kernel/qt_s60_p.h
+++ b/src/widgets/platforms/s60/qt_s60_p.h
diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/widgets/platforms/s60/qwidget_s60.cpp
index d0b1299898..d0b1299898 100644
--- a/src/gui/kernel/qwidget_s60.cpp
+++ b/src/widgets/platforms/s60/qwidget_s60.cpp
diff --git a/src/widgets/platforms/win/qapplication_win.cpp b/src/widgets/platforms/win/qapplication_win.cpp
new file mode 100644
index 0000000000..72b8870fe1
--- /dev/null
+++ b/src/widgets/platforms/win/qapplication_win.cpp
@@ -0,0 +1,4248 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifdef Q_WS_WINCE
+#include "qguifunctions_wince.h"
+#include "qmenubar.h"
+extern bool qt_wince_is_mobile(); //defined in qguifunctions_wince.cpp
+extern bool qt_wince_is_high_dpi(); //defined in qguifunctions_wince.cpp
+extern bool qt_wince_is_smartphone(); //defined in qguifunctions_wince.cpp
+extern bool qt_wince_is_pocket_pc(); //defined in qguifunctions_wince.cpp
+extern void qt_wince_hide_taskbar(HWND hwnd); //defined in qguifunctions_wince.cpp
+#endif
+#ifdef Q_WS_WINCE_WM
+#include <windowsm.h>
+#include <tpcshell.h>
+#ifdef QT_WINCE_GESTURES
+#ifndef QT_NO_GESTURES
+#include <gesture.h>
+#endif
+#endif
+#endif
+
+#include "qapplication.h"
+#include "qdesktopwidget.h"
+#include "qevent.h"
+#include "private/qeventdispatcher_win_p.h"
+#include "qeventloop.h"
+#include "qclipboard.h"
+#include "qcursor.h"
+#include "qdatetime.h"
+#include "qpointer.h"
+#include "qhash.h"
+#include "qmetaobject.h"
+#include "qmime.h"
+#include "qpainter.h"
+#include "qpixmapcache.h"
+#include "qsessionmanager.h"
+#include "qstyle.h"
+#include "qwhatsthis.h" // ######## dependency
+#include "qwidget.h"
+#include "qcolormap.h"
+#include "qlayout.h"
+#include "qtooltip.h"
+#include "qt_windows.h"
+#include "qscrollbar.h"
+#if defined(QT_NON_COMMERCIAL)
+#include "qnc_win.h"
+#endif
+#include "private/qwininputcontext_p.h"
+#include "private/qcursor_p.h"
+#include "private/qmath_p.h"
+#include "private/qapplication_p.h"
+#include "private/qbackingstore_p.h"
+#include "private/qwindowsurface_raster_p.h"
+#include "qdebug.h"
+#include <private/qkeymapper_p.h>
+#include <private/qlocale_p.h>
+#include <private/qsystemlibrary_p.h>
+#include "qevent_p.h"
+
+//#define ALIEN_DEBUG
+
+#ifndef QT_NO_THREAD
+#include "qmutex.h"
+#endif
+
+#ifndef QT_NO_ACCESSIBILITY
+#include "qaccessible.h"
+
+#include <oleacc.h>
+#ifndef WM_GETOBJECT
+#define WM_GETOBJECT 0x003D
+#endif
+#endif // QT_NO_ACCESSIBILITY
+
+#if !defined(WINABLEAPI)
+# if defined(Q_WS_WINCE)
+# include <bldver.h>
+# endif
+# if !defined(Q_WS_WINCE)
+# include <winable.h>
+# endif
+#endif
+
+#ifndef QT_NO_GESTURES
+# ifndef GID_ZOOM
+# define GID_ZOOM 3
+# define GID_TWOFINGERTAP 6
+# define GID_PRESSANDTAP 7
+# define GID_ROLLOVER GID_PRESSANDTAP
+# endif
+#endif
+
+#ifndef WM_TOUCH
+# define WM_TOUCH 0x0240
+#endif
+
+#ifndef TOUCHEVENTF_MOVE
+# define TOUCHEVENTF_MOVE 0x0001
+# define TOUCHEVENTF_DOWN 0x0002
+# define TOUCHEVENTF_UP 0x0004
+# define TOUCHEVENTF_INRANGE 0x0008
+# define TOUCHEVENTF_PRIMARY 0x0010
+# define TOUCHEVENTF_NOCOALESCE 0x0020
+# define TOUCHEVENTF_PEN 0x0040
+# define TOUCHEVENTF_PALM 0x0080
+
+# define TOUCHINPUTMASKF_TIMEFROMSYSTEM 0x0001
+# define TOUCHINPUTMASKF_EXTRAINFO 0x0002
+# define TOUCHINPUTMASKF_CONTACTAREA 0x0004
+
+typedef struct tagTOUCHINPUT
+{
+ LONG x;
+ LONG y;
+ HANDLE hSource;
+ DWORD dwID;
+ DWORD dwFlags;
+ DWORD dwMask;
+ DWORD dwTime;
+ ULONG_PTR dwExtraInfo;
+ DWORD cxContact;
+ DWORD cyContact;
+} TOUCHINPUT, *PTOUCHINPUT;
+
+#endif
+
+#include <windowsx.h>
+#include <limits.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <math.h>
+
+#define PACKETDATA (PK_X | PK_Y | PK_BUTTONS | PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE \
+ | PK_ORIENTATION | PK_CURSOR | PK_Z)
+#define PACKETMODE 0
+
+#include <wintab.h>
+#ifndef CSR_TYPE
+#define CSR_TYPE 20 // Some old Wacom wintab.h may not provide this constant.
+#endif
+#include <pktdef.h>
+
+#if defined(__CYGWIN32__)
+#define __INSIDE_CYGWIN32__
+#include <mywinsock.h>
+#endif
+
+#ifndef IMR_RECONVERTSTRING
+#define IMR_RECONVERTSTRING 4
+#endif
+
+#ifndef IMR_CONFIRMRECONVERTSTRING
+#define IMR_CONFIRMRECONVERTSTRING 0x0005
+#endif
+QT_BEGIN_NAMESPACE
+
+#ifdef Q_WS_WINCE
+#ifndef SHRG_RETURNCMD
+struct SHRGINFO {
+ DWORD cbSize;
+ HWND hwndClient;
+ POINT ptDown;
+ DWORD dwFlags;
+};
+#define GN_CONTEXTMENU 1000
+#define SHRG_RETURNCMD 0x00000001
+#define SHRG_NOANIMATION 0x00000010
+#endif
+
+#ifndef SPI_SETSIPINFO
+#define SPI_SETSIPINFO 224
+#endif
+
+#ifndef QT_NO_GESTURES
+typedef DWORD (API *AygRecognizeGesture)(SHRGINFO*);
+static AygRecognizeGesture ptrRecognizeGesture = 0;
+static bool aygResolved = false;
+static void resolveAygLibs()
+{
+ if (!aygResolved) {
+ aygResolved = true;
+ QSystemLibrary ayglib(QLatin1String("aygshell"));
+ ptrRecognizeGesture = (AygRecognizeGesture) ayglib.resolve("SHRecognizeGesture");
+ }
+}
+#endif // QT_NO_GESTURES
+
+#endif
+
+#ifndef SPI_SETFONTSMOOTHINGTYPE
+# define SPI_SETFONTSMOOTHINGTYPE 0x200B
+#endif
+#ifndef SPI_GETFONTSMOOTHINGTYPE
+# define SPI_GETFONTSMOOTHINGTYPE 0x200A
+#endif
+#ifndef FE_FONTSMOOTHINGCLEARTYPE
+# define FE_FONTSMOOTHINGCLEARTYPE 0x0002
+#endif
+
+Q_WIDGETS_EXPORT qreal qt_fontsmoothing_gamma;
+Q_WIDGETS_EXPORT bool qt_cleartype_enabled;
+Q_WIDGETS_EXPORT bool qt_win_owndc_required; // CS_OWNDC is required if we use the GL graphicssystem as default
+
+typedef HCTX (API *PtrWTOpen)(HWND, LPLOGCONTEXT, BOOL);
+typedef BOOL (API *PtrWTClose)(HCTX);
+typedef UINT (API *PtrWTInfo)(UINT, UINT, LPVOID);
+typedef BOOL (API *PtrWTEnable)(HCTX, BOOL);
+typedef BOOL (API *PtrWTOverlap)(HCTX, BOOL);
+typedef int (API *PtrWTPacketsGet)(HCTX, int, LPVOID);
+typedef BOOL (API *PtrWTGet)(HCTX, LPLOGCONTEXT);
+typedef int (API *PtrWTQueueSizeGet)(HCTX);
+typedef BOOL (API *PtrWTQueueSizeSet)(HCTX, int);
+
+static PtrWTInfo ptrWTInfo = 0;
+static PtrWTEnable ptrWTEnable = 0;
+static PtrWTOverlap ptrWTOverlap = 0;
+static PtrWTPacketsGet ptrWTPacketsGet = 0;
+static PtrWTGet ptrWTGet = 0;
+
+static PACKET localPacketBuf[QT_TABLET_NPACKETQSIZE]; // our own tablet packet queue.
+HCTX qt_tablet_context; // the hardware context for the tablet (like a window handle)
+bool qt_tablet_tilt_support;
+
+#ifndef QT_NO_TABLETEVENT
+static void tabletInit(const quint64 uniqueId, const UINT csr_type, HCTX hTab);
+static void tabletUpdateCursor(QTabletDeviceData &tdd, const UINT currentCursor);
+static void initWinTabFunctions(); // resolve the WINTAB api functions
+#endif // QT_NO_TABLETEVENT
+
+
+#ifndef QT_NO_ACCESSIBILITY
+extern IAccessible *qt_createWindowsAccessible(QAccessibleInterface *object);
+#endif // QT_NO_ACCESSIBILITY
+
+extern bool qt_tabletChokeMouse;
+extern QWidget* qt_get_tablet_widget();
+extern bool qt_sendSpontaneousEvent(QObject*, QEvent*);
+extern QRegion qt_dirtyRegion(QWidget *);
+
+typedef QHash<quint64, QTabletDeviceData> QTabletCursorInfo;
+Q_GLOBAL_STATIC(QTabletCursorInfo, tCursorInfo)
+QTabletDeviceData currentTabletPointer;
+
+// from qregion_win.cpp
+extern HRGN qt_tryCreateRegion(QRegion::RegionType type, int left, int top, int right, int bottom);
+
+// support for on-the-fly changes of the XP theme engine
+#ifndef WM_THEMECHANGED
+#define WM_THEMECHANGED 0x031A
+#endif
+#ifndef COLOR_MENUHILIGHT
+#define COLOR_MENUHILIGHT 29
+#define COLOR_MENUBAR 30
+#endif
+
+// support for xbuttons
+#ifndef WM_XBUTTONDOWN
+#define WM_XBUTTONDOWN 0x020B
+#define WM_XBUTTONUP 0x020C
+#define WM_XBUTTONDBLCLK 0x020D
+#endif
+#ifndef GET_KEYSTATE_WPARAM
+#define GET_KEYSTATE_WPARAM(wParam) (LOWORD(wParam))
+#define GET_XBUTTON_WPARAM(wParam) (HIWORD(wParam))
+#define XBUTTON1 0x0001
+#define XBUTTON2 0x0002
+#endif
+#ifndef MK_XBUTTON1
+#define MK_XBUTTON1 0x0020
+#define MK_XBUTTON2 0x0040
+#endif
+
+// support for multi-media-keys
+#ifndef WM_APPCOMMAND
+#define WM_APPCOMMAND 0x0319
+#endif
+
+#ifndef FAPPCOMMAND_MOUSE
+#define FAPPCOMMAND_MOUSE 0x8000
+#define FAPPCOMMAND_KEY 0
+#define FAPPCOMMAND_OEM 0x1000
+#define FAPPCOMMAND_MASK 0xF000
+#define GET_APPCOMMAND_LPARAM(lParam) ((short)(HIWORD(lParam) & ~FAPPCOMMAND_MASK))
+#define GET_DEVICE_LPARAM(lParam) ((WORD)(HIWORD(lParam) & FAPPCOMMAND_MASK))
+#define GET_MOUSEORKEY_LPARAM GET_DEVICE_LPARAM
+#define GET_FLAGS_LPARAM(lParam) (LOWORD(lParam))
+#define GET_KEYSTATE_LPARAM(lParam) GET_FLAGS_LPARAM(lParam)
+
+#define APPCOMMAND_BROWSER_BACKWARD 1
+#define APPCOMMAND_BROWSER_FORWARD 2
+#define APPCOMMAND_BROWSER_REFRESH 3
+#define APPCOMMAND_BROWSER_STOP 4
+#define APPCOMMAND_BROWSER_SEARCH 5
+#define APPCOMMAND_BROWSER_FAVORITES 6
+#define APPCOMMAND_BROWSER_HOME 7
+#define APPCOMMAND_VOLUME_MUTE 8
+#define APPCOMMAND_VOLUME_DOWN 9
+#define APPCOMMAND_VOLUME_UP 10
+#define APPCOMMAND_MEDIA_NEXTTRACK 11
+#define APPCOMMAND_MEDIA_PREVIOUSTRACK 12
+#define APPCOMMAND_MEDIA_STOP 13
+#define APPCOMMAND_MEDIA_PLAY_PAUSE 14
+#define APPCOMMAND_LAUNCH_MAIL 15
+#define APPCOMMAND_LAUNCH_MEDIA_SELECT 16
+#define APPCOMMAND_LAUNCH_APP1 17
+#define APPCOMMAND_LAUNCH_APP2 18
+#define APPCOMMAND_BASS_DOWN 19
+#define APPCOMMAND_BASS_BOOST 20
+#define APPCOMMAND_BASS_UP 21
+#define APPCOMMAND_TREBLE_DOWN 22
+#define APPCOMMAND_TREBLE_UP 23
+#endif // FAPPCOMMAND_MOUSE
+
+// New commands from Windows XP (some even Sp1)
+#ifndef APPCOMMAND_MICROPHONE_VOLUME_MUTE
+#define APPCOMMAND_MICROPHONE_VOLUME_MUTE 24
+#define APPCOMMAND_MICROPHONE_VOLUME_DOWN 25
+#define APPCOMMAND_MICROPHONE_VOLUME_UP 26
+#define APPCOMMAND_HELP 27
+#define APPCOMMAND_FIND 28
+#define APPCOMMAND_NEW 29
+#define APPCOMMAND_OPEN 30
+#define APPCOMMAND_CLOSE 31
+#define APPCOMMAND_SAVE 32
+#define APPCOMMAND_PRINT 33
+#define APPCOMMAND_UNDO 34
+#define APPCOMMAND_REDO 35
+#define APPCOMMAND_COPY 36
+#define APPCOMMAND_CUT 37
+#define APPCOMMAND_PASTE 38
+#define APPCOMMAND_REPLY_TO_MAIL 39
+#define APPCOMMAND_FORWARD_MAIL 40
+#define APPCOMMAND_SEND_MAIL 41
+#define APPCOMMAND_SPELL_CHECK 42
+#define APPCOMMAND_DICTATE_OR_COMMAND_CONTROL_TOGGLE 43
+#define APPCOMMAND_MIC_ON_OFF_TOGGLE 44
+#define APPCOMMAND_CORRECTION_LIST 45
+#define APPCOMMAND_MEDIA_PLAY 46
+#define APPCOMMAND_MEDIA_PAUSE 47
+#define APPCOMMAND_MEDIA_RECORD 48
+#define APPCOMMAND_MEDIA_FAST_FORWARD 49
+#define APPCOMMAND_MEDIA_REWIND 50
+#define APPCOMMAND_MEDIA_CHANNEL_UP 51
+#define APPCOMMAND_MEDIA_CHANNEL_DOWN 52
+#endif // APPCOMMAND_MICROPHONE_VOLUME_MUTE
+
+#if (_WIN32_WINNT < 0x0400)
+// This struct is defined in winuser.h if the _WIN32_WINNT >= 0x0400 -- in the
+// other cases we have to define it on our own.
+typedef struct tagTRACKMOUSEEVENT {
+ DWORD cbSize;
+ DWORD dwFlags;
+ HWND hwndTrack;
+ DWORD dwHoverTime;
+} TRACKMOUSEEVENT, *LPTRACKMOUSEEVENT;
+#endif
+#ifndef WM_MOUSELEAVE
+#define WM_MOUSELEAVE 0x02A3
+#endif
+
+QT_BEGIN_INCLUDE_NAMESPACE
+#include "private/qwidget_p.h"
+QT_END_INCLUDE_NAMESPACE
+
+static int translateButtonState(int s, int type, int button);
+
+// ##### get rid of this!
+QRgb qt_colorref2qrgb(COLORREF col)
+{
+ return qRgb(GetRValue(col),GetGValue(col),GetBValue(col));
+}
+
+
+/*****************************************************************************
+ Internal variables and functions
+ *****************************************************************************/
+
+static HWND curWin = 0; // current window
+static HDC displayDC = 0; // display device context
+
+// Session management
+static bool sm_blockUserInput = false;
+static bool sm_smActive = false;
+extern QSessionManager* qt_session_manager_self;
+static bool sm_cancel;
+
+static bool replayPopupMouseEvent = false; // replay handling when popups close
+
+// ignore the next release event if return from a modal widget
+Q_WIDGETS_EXPORT bool qt_win_ignoreNextMouseReleaseEvent = false;
+
+
+#if defined(QT_DEBUG)
+static bool appNoGrab = false; // mouse/keyboard grabbing
+#endif
+
+static bool app_do_modal = false; // modal mode
+extern QWidgetList *qt_modal_stack;
+extern QDesktopWidget *qt_desktopWidget;
+static QPointer<QWidget> popupButtonFocus;
+static bool qt_try_modal(QWidget *, MSG *, int& ret);
+
+QWidget *qt_button_down = 0; // widget got last button-down
+QPointer<QWidget> qt_last_mouse_receiver = 0;
+
+static HWND autoCaptureWnd = 0;
+static HWND imeParentWnd = 0;
+static void setAutoCapture(HWND); // automatic capture
+static void releaseAutoCapture();
+
+static void unregWinClasses();
+
+extern QCursor *qt_grab_cursor();
+
+#if defined(Q_WS_WIN)
+#define __export
+#endif
+
+extern "C" LRESULT QT_WIN_CALLBACK QtWndProc(HWND, UINT, WPARAM, LPARAM);
+
+class QETWidget : public QWidget // event translator widget
+{
+public:
+ QWExtra *xtra() { return d_func()->extraData(); }
+ QTLWExtra *topData() { return d_func()->topData(); }
+ QTLWExtra *maybeTopData() { return d_func()->maybeTopData(); }
+ void syncBackingStore(const QRegion &rgn) { d_func()->syncBackingStore(rgn); }
+ void syncBackingStore() { d_func()->syncBackingStore(); }
+ QWidgetData *dataPtr() { return data; }
+ QWidgetPrivate *dptr() { return d_func(); }
+ QRect frameStrut() const { return d_func()->frameStrut(); }
+ bool winEvent(MSG *m, long *r) { return QWidget::winEvent(m, r); }
+ void markFrameStrutDirty() { data->fstrut_dirty = 1; }
+ bool translateMouseEvent(const MSG &msg);
+ bool translateWheelEvent(const MSG &msg);
+ bool translatePaintEvent(const MSG &msg);
+ bool translateConfigEvent(const MSG &msg);
+ bool translateCloseEvent(const MSG &msg);
+ bool translateTabletEvent(const MSG &msg, PACKET *localPacketBuf, int numPackets);
+#ifndef QT_NO_GESTURES
+ bool translateGestureEvent(const MSG &msg, const GESTUREINFO &gi);
+#endif
+ void repolishStyle(QStyle &style);
+ inline void showChildren(bool spontaneous) { d_func()->showChildren(spontaneous); }
+ inline void hideChildren(bool spontaneous) { d_func()->hideChildren(spontaneous); }
+ inline uint testWindowState(uint teststate){ return dataPtr()->window_state & teststate; }
+ inline void setWindowTitle_helper(const QString &title) { d_func()->setWindowTitle_helper(title); }
+ inline void forceUpdate() {
+ QTLWExtra *tlwExtra = window()->d_func()->maybeTopData();
+ if (tlwExtra && tlwExtra->backingStore)
+ tlwExtra->backingStore->markDirty(rect(), this, true, true);
+ }
+};
+
+// need to get default font?
+extern bool qt_app_has_font;
+
+extern QFont qt_LOGFONTtoQFont(LOGFONT& lf,bool scale);
+
+static void qt_set_windows_color_resources()
+{
+ // Do the color settings
+ QPalette pal;
+ pal.setColor(QPalette::WindowText,
+ QColor(qt_colorref2qrgb(GetSysColor(COLOR_WINDOWTEXT))));
+ pal.setColor(QPalette::Button,
+ QColor(qt_colorref2qrgb(GetSysColor(COLOR_BTNFACE))));
+ pal.setColor(QPalette::Light,
+ QColor(qt_colorref2qrgb(GetSysColor(COLOR_BTNHIGHLIGHT))));
+ pal.setColor(QPalette::Dark,
+ QColor(qt_colorref2qrgb(GetSysColor(COLOR_BTNSHADOW))));
+ pal.setColor(QPalette::Mid, pal.button().color().darker(150));
+ pal.setColor(QPalette::Text,
+ QColor(qt_colorref2qrgb(GetSysColor(COLOR_WINDOWTEXT))));
+ pal.setColor(QPalette::BrightText,
+ QColor(qt_colorref2qrgb(GetSysColor(COLOR_BTNHIGHLIGHT))));
+ pal.setColor(QPalette::Base,
+ QColor(qt_colorref2qrgb(GetSysColor(COLOR_WINDOW))));
+ pal.setColor(QPalette::Window,
+ QColor(qt_colorref2qrgb(GetSysColor(COLOR_BTNFACE))));
+ pal.setColor(QPalette::ButtonText,
+ QColor(qt_colorref2qrgb(GetSysColor(COLOR_BTNTEXT))));
+ pal.setColor(QPalette::Midlight,
+ QColor(qt_colorref2qrgb(GetSysColor(COLOR_3DLIGHT))));
+ pal.setColor(QPalette::Shadow,
+ QColor(qt_colorref2qrgb(GetSysColor(COLOR_3DDKSHADOW))));
+ pal.setColor(QPalette::Highlight,
+ QColor(qt_colorref2qrgb(GetSysColor(COLOR_HIGHLIGHT))));
+ pal.setColor(QPalette::HighlightedText,
+ QColor(qt_colorref2qrgb(GetSysColor(COLOR_HIGHLIGHTTEXT))));
+
+#if defined(Q_WS_WINCE)
+ // ### hardcoded until I find out how to get it from the system settings.
+ pal.setColor(QPalette::LinkVisited, pal.highlight().color().dark(150));
+ pal.setColor(QPalette::Link, pal.highlight().color().light(130));
+ // Background == Base on Windows CE
+ if (qt_wince_is_smartphone() || qt_wince_is_pocket_pc())
+ pal.setColor(QPalette::Background, pal.base().color());
+#else
+ pal.setColor(QPalette::Link, Qt::blue);
+ pal.setColor(QPalette::LinkVisited, Qt::magenta);
+#endif
+
+
+
+ pal.setColor(QPalette::Inactive, QPalette::Button, pal.button().color());
+ pal.setColor(QPalette::Inactive, QPalette::Window, pal.background().color());
+ pal.setColor(QPalette::Inactive, QPalette::Light, pal.light().color());
+ pal.setColor(QPalette::Inactive, QPalette::Dark, pal.dark().color());
+
+ if (pal.midlight() == pal.button())
+ pal.setColor(QPalette::Midlight, pal.button().color().lighter(110));
+ if (pal.background() != pal.base()) {
+ pal.setColor(QPalette::Inactive, QPalette::Highlight, pal.color(QPalette::Inactive, QPalette::Window));
+ pal.setColor(QPalette::Inactive, QPalette::HighlightedText, pal.color(QPalette::Inactive, QPalette::Text));
+ }
+
+ const QColor bg = pal.background().color();
+ const QColor fg = pal.foreground().color(), btn = pal.button().color();
+ QColor disabled((fg.red()+btn.red())/2,(fg.green()+btn.green())/2,
+ (fg.blue()+btn.blue())/2);
+ pal.setColorGroup(QPalette::Disabled, pal.foreground(), pal.button(), pal.light(),
+ pal.dark(), pal.mid(), pal.text(), pal.brightText(), pal.base(), pal.background() );
+ pal.setColor(QPalette::Disabled, QPalette::WindowText, disabled);
+ pal.setColor(QPalette::Disabled, QPalette::Text, disabled);
+ pal.setColor(QPalette::Disabled, QPalette::ButtonText, disabled);
+ pal.setColor(QPalette::Disabled, QPalette::Highlight,
+ QColor(qt_colorref2qrgb(GetSysColor(COLOR_HIGHLIGHT))));
+ pal.setColor(QPalette::Disabled, QPalette::HighlightedText,
+ QColor(qt_colorref2qrgb(GetSysColor(COLOR_HIGHLIGHTTEXT))));
+ pal.setColor(QPalette::Disabled, QPalette::Base, bg);
+
+ QApplicationPrivate::setSystemPalette(pal);
+
+ QApplicationPrivate::initializeWidgetPaletteHash();
+
+ QColor ttip(qt_colorref2qrgb(GetSysColor(COLOR_INFOBK)));
+
+ QColor ttipText(qt_colorref2qrgb(GetSysColor(COLOR_INFOTEXT)));
+ {
+#ifndef QT_NO_TOOLTIP
+ QPalette tiplabel(pal);
+ tiplabel.setColor(QPalette::All, QPalette::Button, ttip);
+ tiplabel.setColor(QPalette::All, QPalette::Window, ttip);
+ tiplabel.setColor(QPalette::All, QPalette::Text, ttipText);
+ tiplabel.setColor(QPalette::All, QPalette::WindowText, ttipText);
+ tiplabel.setColor(QPalette::All, QPalette::ButtonText, ttipText);
+ tiplabel.setColor(QPalette::All, QPalette::Button, ttip);
+ tiplabel.setColor(QPalette::All, QPalette::Window, ttip);
+ tiplabel.setColor(QPalette::All, QPalette::Text, ttipText);
+ tiplabel.setColor(QPalette::All, QPalette::WindowText, ttipText);
+ tiplabel.setColor(QPalette::All, QPalette::ButtonText, ttipText);
+ const QColor fg = tiplabel.foreground().color(), btn = tiplabel.button().color();
+ QColor disabled((fg.red()+btn.red())/2,(fg.green()+btn.green())/2,
+ (fg.blue()+btn.blue())/2);
+ tiplabel.setColor(QPalette::Disabled, QPalette::WindowText, disabled);
+ tiplabel.setColor(QPalette::Disabled, QPalette::Text, disabled);
+ tiplabel.setColor(QPalette::Disabled, QPalette::Base, Qt::white);
+ tiplabel.setColor(QPalette::Disabled, QPalette::BrightText, Qt::white);
+ QToolTip::setPalette(tiplabel);
+#endif //QT_NO_TOOLTIP
+ }
+}
+
+static void qt_set_windows_font_resources()
+{
+#ifndef Q_WS_WINCE
+ NONCLIENTMETRICS ncm;
+ ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICS, lfMessageFont) + sizeof(LOGFONT);
+ SystemParametersInfo(SPI_GETNONCLIENTMETRICS, ncm.cbSize , &ncm, 0);
+
+ QFont menuFont = qt_LOGFONTtoQFont(ncm.lfMenuFont, true);
+ QFont messageFont = qt_LOGFONTtoQFont(ncm.lfMessageFont, true);
+ QFont statusFont = qt_LOGFONTtoQFont(ncm.lfStatusFont, true);
+ QFont titleFont = qt_LOGFONTtoQFont(ncm.lfCaptionFont, true);
+
+ LOGFONT lfIconTitleFont;
+ SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lfIconTitleFont), &lfIconTitleFont, 0);
+ QFont iconTitleFont = qt_LOGFONTtoQFont(lfIconTitleFont, true);
+
+ QApplication::setFont(menuFont, "QMenu");
+ QApplication::setFont(menuFont, "QMenuBar");
+ QApplication::setFont(messageFont, "QMessageBox");
+ QApplication::setFont(statusFont, "QTipLabel");
+ QApplication::setFont(statusFont, "QStatusBar");
+ QApplication::setFont(titleFont, "Q3TitleBar");
+ QApplication::setFont(titleFont, "QWorkspaceTitleBar");
+ QApplication::setFont(iconTitleFont, "QAbstractItemView");
+ QApplication::setFont(iconTitleFont, "QDockWidgetTitle");
+
+#else
+ LOGFONT lf;
+ HGDIOBJ stockFont = GetStockObject(SYSTEM_FONT);
+ GetObject(stockFont, sizeof(lf), &lf);
+ QFont systemFont = qt_LOGFONTtoQFont(lf, true);
+ QApplicationPrivate::setSystemFont(systemFont);
+ QFont smallerFont = systemFont;
+ if (qt_wince_is_mobile()) {
+ smallerFont.setPointSize(systemFont.pointSize()-1);
+ QApplication::setFont(smallerFont, "QTabBar");
+ smallerFont.setBold(true);
+ QApplication::setFont(smallerFont, "QAbstractButton");
+ }
+#endif// Q_WS_WINCE
+}
+
+static void qt_win_read_cleartype_settings()
+{
+ UINT result = 0;
+#ifdef Q_OS_WINCE
+ if (SystemParametersInfo(SPI_GETFONTSMOOTHING, 0, &result, 0))
+ qt_cleartype_enabled = result;
+#else
+ if (SystemParametersInfo(SPI_GETFONTSMOOTHINGTYPE, 0, &result, 0))
+ qt_cleartype_enabled = (result == FE_FONTSMOOTHINGCLEARTYPE);
+#endif
+
+ int winSmooth;
+ if (SystemParametersInfo(0x200C /* SPI_GETFONTSMOOTHINGCONTRAST */, 0, &winSmooth, 0)) {
+ qt_fontsmoothing_gamma = winSmooth / qreal(1000.0);
+ } else {
+ qt_fontsmoothing_gamma = 1.0;
+ }
+
+ // Safeguard ourselves against corrupt registry values...
+ if (qt_fontsmoothing_gamma > 5 || qt_fontsmoothing_gamma < 1)
+ qt_fontsmoothing_gamma = qreal(1.4);
+}
+
+static void qt_set_windows_resources()
+{
+ if (QApplication::type() != QApplication::Tty)
+ (void) QApplication::style(); // trigger creation of application style
+ qt_set_windows_font_resources();
+ qt_set_windows_color_resources();
+}
+
+void QApplicationPrivate::initializeWidgetPaletteHash()
+{
+ QPalette pal = *QApplicationPrivate::sys_pal;
+ QColor menuCol(qt_colorref2qrgb(GetSysColor(COLOR_MENU)));
+ QColor menuText(qt_colorref2qrgb(GetSysColor(COLOR_MENUTEXT)));
+ BOOL isFlat = false;
+ if ((QSysInfo::WindowsVersion >= QSysInfo::WV_XP
+ && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based))
+ SystemParametersInfo(SPI_GETFLATMENU, 0, &isFlat, 0);
+ QPalette menu(pal);
+ // we might need a special color group for the menu.
+ menu.setColor(QPalette::Active, QPalette::Button, menuCol);
+ menu.setColor(QPalette::Active, QPalette::Text, menuText);
+ menu.setColor(QPalette::Active, QPalette::WindowText, menuText);
+ menu.setColor(QPalette::Active, QPalette::ButtonText, menuText);
+ const QColor fg = menu.foreground().color(), btn = menu.button().color();
+ QColor disabled(qt_colorref2qrgb(GetSysColor(COLOR_GRAYTEXT)));
+ menu.setColor(QPalette::Disabled, QPalette::WindowText, disabled);
+ menu.setColor(QPalette::Disabled, QPalette::Text, disabled);
+ menu.setColor(QPalette::Disabled, QPalette::Highlight,
+ QColor(qt_colorref2qrgb(GetSysColor(
+ (QSysInfo::WindowsVersion >= QSysInfo::WV_XP
+ && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)
+ && isFlat ? COLOR_MENUHILIGHT : COLOR_HIGHLIGHT))));
+ menu.setColor(QPalette::Disabled, QPalette::HighlightedText, disabled);
+ menu.setColor(QPalette::Disabled, QPalette::Button,
+ menu.color(QPalette::Active, QPalette::Button));
+ menu.setColor(QPalette::Inactive, QPalette::Button,
+ menu.color(QPalette::Active, QPalette::Button));
+ menu.setColor(QPalette::Inactive, QPalette::Text,
+ menu.color(QPalette::Active, QPalette::Text));
+ menu.setColor(QPalette::Inactive, QPalette::WindowText,
+ menu.color(QPalette::Active, QPalette::WindowText));
+ menu.setColor(QPalette::Inactive, QPalette::ButtonText,
+ menu.color(QPalette::Active, QPalette::ButtonText));
+ menu.setColor(QPalette::Inactive, QPalette::Highlight,
+ menu.color(QPalette::Active, QPalette::Highlight));
+ menu.setColor(QPalette::Inactive, QPalette::HighlightedText,
+ menu.color(QPalette::Active, QPalette::HighlightedText));
+ menu.setColor(QPalette::Inactive, QPalette::ButtonText,
+ pal.color(QPalette::Inactive, QPalette::Dark));
+ QApplication::setPalette(menu, "QMenu");
+
+ if ((QSysInfo::WindowsVersion >= QSysInfo::WV_XP
+ && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based) && isFlat) {
+ QColor menubar(qt_colorref2qrgb(GetSysColor(COLOR_MENUBAR)));
+ menu.setColor(QPalette::Active, QPalette::Button, menubar);
+ menu.setColor(QPalette::Disabled, QPalette::Button, menubar);
+ menu.setColor(QPalette::Inactive, QPalette::Button, menubar);
+ }
+ QApplication::setPalette(menu, "QMenuBar");
+}
+
+static void qt_set_windows_updateScrollBar(QWidget *widget)
+{
+ QList<QObject*> children = widget->children();
+ for (int i = 0; i < children.size(); ++i) {
+ QObject *o = children.at(i);
+ if(!o->isWidgetType())
+ continue;
+ if (QWidget *w = static_cast<QWidget *>(o))
+ qt_set_windows_updateScrollBar(w);
+ }
+#ifndef QT_NO_SCROLLBAR
+ if (qobject_cast<QScrollBar*>(widget))
+ widget->updateGeometry();
+#endif
+}
+
+
+/*****************************************************************************
+ qt_init() - initializes Qt for Windows
+ *****************************************************************************/
+
+typedef BOOL (WINAPI *PtrSetProcessDPIAware) (VOID);
+static PtrSetProcessDPIAware ptrSetProcessDPIAware = 0;
+PtrUpdateLayeredWindow ptrUpdateLayeredWindow = 0;
+PtrUpdateLayeredWindowIndirect ptrUpdateLayeredWindowIndirect = 0;
+static BOOL WINAPI qt_updateLayeredWindowIndirect(HWND hwnd, const Q_UPDATELAYEREDWINDOWINFO *info)
+{
+ return (*ptrUpdateLayeredWindow)(hwnd, info->hdcDst, info->pptDst, info->psize, info->hdcSrc,
+ info->pptSrc, info->crKey, info->pblend, info->dwFlags);
+}
+
+void qt_init(QApplicationPrivate *priv, int)
+{
+
+ int argc = priv->argc;
+ char **argv = priv->argv;
+ int i, j;
+
+ // Get command line params
+
+ j = argc ? 1 : 0;
+ for (i=1; i<argc; i++) {
+ if (argv[i] && *argv[i] != '-') {
+ argv[j++] = argv[i];
+ continue;
+ }
+#if defined(QT_DEBUG)
+ if (qstrcmp(argv[i], "-nograb") == 0)
+ appNoGrab = !appNoGrab;
+ else
+#endif // QT_DEBUG
+ argv[j++] = argv[i];
+ }
+ if(j < priv->argc) {
+ priv->argv[j] = 0;
+ priv->argc = j;
+ }
+
+#ifndef Q_WS_WINCE
+ // No message boxes but important ones
+ SetErrorMode(SetErrorMode(0) | SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX);
+#endif
+
+#ifndef Q_WS_WINCE
+ // Initialize OLE/COM
+ // S_OK means success and S_FALSE means that it has already
+ // been initialized
+ HRESULT r;
+ r = OleInitialize(0);
+ if (r != S_OK && r != S_FALSE) {
+ qWarning("Qt: Could not initialize OLE (error %x)", (unsigned int)r);
+ }
+#endif
+
+ // Misc. initialization
+#if defined(QT_DEBUG) && !defined(Q_WS_WINCE)
+ GdiSetBatchLimit(1);
+#endif
+
+ // initialize key mapper
+ QKeyMapper::changeKeyboard();
+
+ QColormap::initialize();
+ QFont::initialize();
+#ifndef QT_NO_CURSOR
+ QCursorData::initialize();
+#endif
+ qApp->setObjectName(priv->appName());
+
+ // default font
+#ifndef Q_WS_WINCE
+ HGDIOBJ stockFont = GetStockObject(DEFAULT_GUI_FONT);
+#else
+ HGDIOBJ stockFont = GetStockObject(SYSTEM_FONT);
+#endif
+
+ LOGFONT lf;
+ GetObject(stockFont, sizeof(lf), &lf);
+ QFont systemFont = qt_LOGFONTtoQFont(lf, true);
+
+#ifndef Q_WS_WINCE
+ if (systemFont.family() == QLatin1String("MS Shell Dlg")) {
+ systemFont.setFamily(QLatin1String("MS Shell Dlg 2"));
+ }
+#endif
+
+ QApplicationPrivate::setSystemFont(systemFont);
+
+ // QFont::locale_init(); ### Uncomment when it does something on Windows
+
+ if (QApplication::desktopSettingsAware())
+ qt_set_windows_resources();
+
+#ifndef QT_NO_TABLETEVENT
+ initWinTabFunctions();
+#endif // QT_NO_TABLETEVENT
+ QApplicationPrivate::inputContext = new QWinInputContext(0);
+
+ // Read the initial cleartype settings...
+ qt_win_read_cleartype_settings();
+ qt_win_owndc_required = false;
+
+ extern void qt_win_initialize_directdraw();
+ qt_win_initialize_directdraw();
+
+#ifndef Q_OS_WINCE
+ ptrUpdateLayeredWindowIndirect =
+ (PtrUpdateLayeredWindowIndirect) QSystemLibrary::resolve(QLatin1String("user32"),
+ "UpdateLayeredWindowIndirect");
+ ptrUpdateLayeredWindow =
+ (PtrUpdateLayeredWindow) QSystemLibrary::resolve(QLatin1String("user32"),
+ "UpdateLayeredWindow");
+
+ if (ptrUpdateLayeredWindow && !ptrUpdateLayeredWindowIndirect)
+ ptrUpdateLayeredWindowIndirect = qt_updateLayeredWindowIndirect;
+
+ // Notify Vista and Windows 7 that we support highter DPI settings
+ ptrSetProcessDPIAware = (PtrSetProcessDPIAware)
+ QSystemLibrary::resolve(QLatin1String("user32"), "SetProcessDPIAware");
+ if (ptrSetProcessDPIAware)
+ ptrSetProcessDPIAware();
+#endif
+
+#ifndef QT_NO_GESTURES
+ priv->GetGestureInfo = 0;
+ priv->GetGestureExtraArgs = 0;
+ priv->CloseGestureInfoHandle = 0;
+ priv->SetGestureConfig = 0;
+ priv->GetGestureConfig = 0;
+ priv->BeginPanningFeedback = 0;
+ priv->UpdatePanningFeedback = 0;
+ priv->EndPanningFeedback = 0;
+
+#if defined(Q_WS_WINCE_WM) && defined(QT_WINCE_GESTURES)
+ priv->GetGestureInfo = (PtrGetGestureInfo) &TKGetGestureInfo;
+ priv->GetGestureExtraArgs = (PtrGetGestureExtraArgs) &TKGetGestureExtraArguments;
+#elif !defined(Q_WS_WINCE)
+ #if !defined(QT_NO_NATIVE_GESTURES)
+ priv->GetGestureInfo =
+ (PtrGetGestureInfo)QSystemLibrary::resolve(QLatin1String("user32"),
+ "GetGestureInfo");
+ priv->GetGestureExtraArgs =
+ (PtrGetGestureExtraArgs)QSystemLibrary::resolve(QLatin1String("user32"),
+ "GetGestureExtraArgs");
+ priv->CloseGestureInfoHandle =
+ (PtrCloseGestureInfoHandle)QSystemLibrary::resolve(QLatin1String("user32"),
+ "CloseGestureInfoHandle");
+ priv->SetGestureConfig =
+ (PtrSetGestureConfig)QSystemLibrary::resolve(QLatin1String("user32"),
+ "SetGestureConfig");
+ priv->GetGestureConfig =
+ (PtrGetGestureConfig)QSystemLibrary::resolve(QLatin1String("user32"),
+ "GetGestureConfig");
+ #endif // QT_NO_NATIVE_GESTURES
+ QSystemLibrary libTheme(QLatin1String("uxtheme"));
+ priv->BeginPanningFeedback =
+ (PtrBeginPanningFeedback)libTheme.resolve("BeginPanningFeedback");
+ priv->UpdatePanningFeedback =
+ (PtrUpdatePanningFeedback)libTheme.resolve("UpdatePanningFeedback");
+ priv->EndPanningFeedback =
+ (PtrEndPanningFeedback)libTheme.resolve("EndPanningFeedback");
+#endif
+#endif // QT_NO_GESTURES
+}
+
+/*****************************************************************************
+ qt_cleanup() - cleans up when the application is finished
+ *****************************************************************************/
+
+void qt_cleanup()
+{
+ unregWinClasses();
+ QPixmapCache::clear();
+
+#ifndef QT_NO_CURSOR
+ QCursorData::cleanup();
+#endif
+ QFont::cleanup();
+ QColormap::cleanup();
+ if (displayDC) {
+ ReleaseDC(0, displayDC);
+ displayDC = 0;
+ }
+
+ delete QApplicationPrivate::inputContext;
+ QApplicationPrivate::inputContext = 0;
+
+#ifndef Q_WS_WINCE
+ // Deinitialize OLE/COM
+ OleUninitialize();
+#endif
+}
+
+
+/*****************************************************************************
+ Platform specific global and internal functions
+ *****************************************************************************/
+
+Q_WIDGETS_EXPORT HDC qt_win_display_dc() // get display DC
+{
+ Q_ASSERT(qApp && qApp->thread() == QThread::currentThread());
+ if (!displayDC)
+ displayDC = GetDC(0);
+ return displayDC;
+}
+
+bool qt_nograb() // application no-grab option
+{
+#if defined(QT_DEBUG)
+ return appNoGrab;
+#else
+ return false;
+#endif
+}
+
+typedef QHash<QString, int> WinClassNameHash;
+Q_GLOBAL_STATIC(WinClassNameHash, winclassNames)
+
+//
+// If 0 is passed as the widget pointer, register a window class
+// for QWidget as default. This is used in QGLTemporaryContext
+// during GL initialization, where we don't want to use temporary
+// QWidgets or QGLWidgets, neither do we want to have separate code
+// to register window classes.
+//
+const QString qt_reg_winclass(QWidget *w) // register window class
+{
+ Qt::WindowFlags flags = w ? w->windowFlags() : (Qt::WindowFlags)0;
+ Qt::WindowFlags type = flags & Qt::WindowType_Mask;
+
+ uint style;
+ bool icon;
+ QString cname;
+ if (w && qt_widget_private(w)->isGLWidget) {
+ cname = QLatin1String("QGLWidget");
+ style = CS_DBLCLKS;
+#ifndef Q_WS_WINCE
+ style |= CS_OWNDC;
+#endif
+ icon = true;
+ } else if (w && (flags & Qt::MSWindowsOwnDC)) {
+ cname = QLatin1String("QWidgetOwnDC");
+ style = CS_DBLCLKS;
+#ifndef Q_WS_WINCE
+ style |= CS_OWNDC;
+#endif
+ icon = true;
+ } else if (w && (type == Qt::Tool || type == Qt::ToolTip)) {
+ style = CS_DBLCLKS;
+ if (w->inherits("QTipLabel") || w->inherits("QAlphaWidget")) {
+ if ((QSysInfo::WindowsVersion >= QSysInfo::WV_XP
+ && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)) {
+ style |= CS_DROPSHADOW;
+ }
+ cname = QLatin1String("QToolTip");
+ } else {
+ cname = QLatin1String("QTool");
+ }
+#ifndef Q_WS_WINCE
+ style |= CS_SAVEBITS;
+#endif
+ icon = false;
+ } else if (w && (type == Qt::Popup)) {
+ cname = QLatin1String("QPopup");
+ style = CS_DBLCLKS;
+#ifndef Q_WS_WINCE
+ style |= CS_SAVEBITS;
+#endif
+ if ((QSysInfo::WindowsVersion >= QSysInfo::WV_XP
+ && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based))
+ style |= CS_DROPSHADOW;
+ icon = false;
+ } else {
+ cname = QLatin1String("QWidget");
+ style = CS_DBLCLKS;
+ icon = true;
+ }
+
+#ifndef Q_WS_WINCE
+ // force CS_OWNDC when the GL graphics system is
+ // used as the default renderer
+ if (qt_win_owndc_required)
+ style |= CS_OWNDC;
+#endif
+
+#ifdef Q_OS_WINCE
+ // We need to register the classes with the
+ // unique ID on WinCE to make sure we can
+ // move the windows to the front when starting
+ // a second instance.
+ wchar_t uniqueAppID[MAX_PATH];
+ GetModuleFileName(0, uniqueAppID, MAX_PATH);
+ cname = QString::number(RegisterWindowMessage(
+ (const wchar_t *) QString::fromWCharArray(uniqueAppID).toLower().replace(QLatin1Char('\\'),
+ QLatin1Char('_')).utf16()));
+#endif
+
+ // since multiple Qt versions can be used in one process
+ // each one has to have window class names with a unique name
+ // The first instance gets the unmodified name; if the class
+ // has already been registered by another instance of Qt then
+ // add an instance-specific ID, the address of the window proc.
+ static int classExists = -1;
+
+ if (classExists == -1) {
+ WNDCLASS wcinfo;
+ classExists = GetClassInfo((HINSTANCE)qWinAppInst(), (wchar_t*)cname.utf16(), &wcinfo);
+ classExists = classExists && wcinfo.lpfnWndProc != QtWndProc;
+ }
+
+ if (classExists)
+ cname += QString::number((quintptr)QtWndProc);
+
+ if (winclassNames()->contains(cname)) // already registered in our list
+ return cname;
+
+#ifndef Q_WS_WINCE
+ WNDCLASSEX wc;
+ wc.cbSize = sizeof(WNDCLASSEX);
+#else
+ WNDCLASS wc;
+#endif
+ wc.style = style;
+ wc.lpfnWndProc = (WNDPROC)QtWndProc;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = 0;
+ wc.hInstance = qWinAppInst();
+ if (icon) {
+ wc.hIcon = (HICON)LoadImage(qWinAppInst(), L"IDI_ICON1", IMAGE_ICON, 0, 0, LR_DEFAULTSIZE);
+#ifndef Q_WS_WINCE
+ if (wc.hIcon) {
+ int sw = GetSystemMetrics(SM_CXSMICON);
+ int sh = GetSystemMetrics(SM_CYSMICON);
+ wc.hIconSm = (HICON)LoadImage(qWinAppInst(), L"IDI_ICON1", IMAGE_ICON, sw, sh, 0);
+ } else {
+ wc.hIcon = (HICON)LoadImage(0, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
+ wc.hIconSm = 0;
+ }
+#endif
+ } else {
+ wc.hIcon = 0;
+#ifndef Q_WS_WINCE
+ wc.hIconSm = 0;
+#endif
+ }
+ wc.hCursor = 0;
+#ifndef Q_WS_WINCE
+ HBRUSH brush = 0;
+ if (w && !qt_widget_private(w)->isGLWidget)
+ brush = (HBRUSH)GetSysColorBrush(COLOR_WINDOW);
+ wc.hbrBackground = brush;
+#else
+ wc.hbrBackground = 0;
+#endif
+ wc.lpszMenuName = 0;
+ wc.lpszClassName = (wchar_t*)cname.utf16();
+
+#ifndef Q_WS_WINCE
+ ATOM atom = RegisterClassEx(&wc);
+#else
+ ATOM atom = RegisterClass(&wc);
+#endif
+
+#ifndef QT_NO_DEBUG
+ if (!atom)
+ qErrnoWarning("QApplication::regClass: Registering window class failed.");
+#else
+ Q_UNUSED(atom);
+#endif
+
+ winclassNames()->insert(cname, 1);
+ return cname;
+}
+
+Q_WIDGETS_EXPORT const QString qt_getRegisteredWndClass()
+{
+ return qt_reg_winclass(0);
+}
+
+static void unregWinClasses()
+{
+ WinClassNameHash *hash = winclassNames();
+ QHash<QString, int>::ConstIterator it = hash->constBegin();
+ while (it != hash->constEnd()) {
+ UnregisterClass((wchar_t*)it.key().utf16(), qWinAppInst());
+ ++it;
+ }
+ hash->clear();
+}
+
+
+/*****************************************************************************
+ Safe configuration (move,resize,setGeometry) mechanism to avoid
+ recursion when processing messages.
+ *****************************************************************************/
+
+struct QWinConfigRequest {
+ WId id; // widget to be configured
+ int req; // 0=move, 1=resize, 2=setGeo
+ int x, y, w, h; // request parameters
+};
+
+static QList<QWinConfigRequest*> *configRequests = 0;
+
+void qWinRequestConfig(WId id, int req, int x, int y, int w, int h)
+{
+ if (!configRequests) // create queue
+ configRequests = new QList<QWinConfigRequest*>;
+ QWinConfigRequest *r = new QWinConfigRequest;
+ r->id = id; // create new request
+ r->req = req;
+ r->x = x;
+ r->y = y;
+ r->w = w;
+ r->h = h;
+ configRequests->append(r); // store request in queue
+}
+
+static void qWinProcessConfigRequests() // perform requests in queue
+{
+ if (!configRequests)
+ return;
+ QWinConfigRequest *r;
+ for (;;) {
+ if (configRequests->isEmpty())
+ break;
+ r = configRequests->takeLast();
+ QWidget *w = QWidget::find(r->id);
+ QRect rect(r->x, r->y, r->w, r->h);
+ int req = r->req;
+ delete r;
+
+ if ( w ) { // widget exists
+ if (w->testAttribute(Qt::WA_WState_ConfigPending))
+ return; // biting our tail
+ if (req == 0)
+ w->move(rect.topLeft());
+ else if (req == 1)
+ w->resize(rect.size());
+ else
+ w->setGeometry(rect);
+ }
+ }
+ delete configRequests;
+ configRequests = 0;
+}
+
+
+/*****************************************************************************
+ GUI event dispatcher
+ *****************************************************************************/
+
+class QGuiEventDispatcherWin32 : public QEventDispatcherWin32
+{
+ Q_DECLARE_PRIVATE(QEventDispatcherWin32)
+public:
+ QGuiEventDispatcherWin32(QObject *parent = 0);
+ bool processEvents(QEventLoop::ProcessEventsFlags flags);
+};
+
+QGuiEventDispatcherWin32::QGuiEventDispatcherWin32(QObject *parent)
+ : QEventDispatcherWin32(parent)
+{
+ createInternalHwnd();
+}
+
+bool QGuiEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags)
+{
+ if (!QEventDispatcherWin32::processEvents(flags))
+ return false;
+
+ if (configRequests) // any pending configs?
+ qWinProcessConfigRequests();
+
+ return true;
+}
+
+void QApplicationPrivate::createEventDispatcher()
+{
+ Q_Q(QApplication);
+ if (q->type() != QApplication::Tty)
+ eventDispatcher = new QGuiEventDispatcherWin32(q);
+ else
+ eventDispatcher = new QEventDispatcherWin32(q);
+}
+
+/*****************************************************************************
+ Platform specific QApplication members
+ *****************************************************************************/
+
+#ifdef QT3_SUPPORT
+void QApplication::setMainWidget(QWidget *mainWidget)
+{
+ QApplicationPrivate::main_widget = mainWidget;
+ if (QApplicationPrivate::main_widget && windowIcon().isNull()
+ && QApplicationPrivate::main_widget->testAttribute(Qt::WA_SetWindowIcon))
+ setWindowIcon(QApplicationPrivate::main_widget->windowIcon());
+}
+#endif
+
+#ifndef QT_NO_CURSOR
+
+/*****************************************************************************
+ QApplication cursor stack
+ *****************************************************************************/
+
+void QApplication::setOverrideCursor(const QCursor &cursor)
+{
+ qApp->d_func()->cursor_list.prepend(cursor);
+ SetCursor(qApp->d_func()->cursor_list.first().handle());
+}
+
+void QApplication::restoreOverrideCursor()
+{
+ if (qApp->d_func()->cursor_list.isEmpty())
+ return;
+ qApp->d_func()->cursor_list.removeFirst();
+
+ if (!qApp->d_func()->cursor_list.isEmpty()) {
+ SetCursor(qApp->d_func()->cursor_list.first().handle());
+ } else {
+ QWidget *w = QWidget::find(curWin);
+ if (w)
+ SetCursor(w->cursor().handle());
+ else
+ SetCursor(QCursor(Qt::ArrowCursor).handle());
+ }
+}
+
+#endif
+
+/*
+ Internal function called from QWidget::setCursor()
+ force is true if this function is called from dispatchEnterLeave, it means that the
+ mouse is actually directly under this widget.
+*/
+
+#ifndef QT_NO_CURSOR
+void qt_win_set_cursor(QWidget *w, bool force)
+{
+ static QPointer<QWidget> lastUnderMouse = 0;
+ if (force) {
+ lastUnderMouse = w;
+ } else if (w->testAttribute(Qt::WA_WState_Created) && lastUnderMouse
+ && lastUnderMouse->effectiveWinId() == w->effectiveWinId()) {
+ w = lastUnderMouse;
+ }
+
+ if (!curWin && w && w->internalWinId())
+ return;
+ QWidget* cW = w && !w->internalWinId() ? w : QWidget::find(curWin);
+ if (!cW || cW->window() != w->window() ||
+ !cW->isVisible() || !cW->underMouse() || QApplication::overrideCursor())
+ return;
+
+ SetCursor(cW->cursor().handle());
+}
+#endif // QT_NO_CURSOR
+
+Qt::KeyboardModifiers qt_win_getKeyboardModifiers()
+{
+ Qt::KeyboardModifiers modifiers = Qt::NoModifier;
+ if (GetKeyState(VK_SHIFT) < 0)
+ modifiers |= Qt::ShiftModifier;
+ if (GetKeyState(VK_CONTROL) < 0)
+ modifiers |= Qt::ControlModifier;
+ if (GetKeyState(VK_MENU) < 0)
+ modifiers |= Qt::AltModifier;
+ return modifiers;
+}
+
+/*****************************************************************************
+ Routines to find a Qt widget from a screen position
+ *****************************************************************************/
+
+QWidget *QApplication::topLevelAt(const QPoint &pos)
+{
+ POINT p;
+ HWND win;
+ QWidget *w;
+ p.x = pos.x();
+ p.y = pos.y();
+ win = WindowFromPoint(p);
+ if (!win)
+ return 0;
+
+ w = QWidget::find(win);
+ while (!w && win) {
+ win = GetParent(win);
+ w = QWidget::find(win);
+ }
+ return w ? w->window() : 0;
+}
+
+void QApplication::beep()
+{
+ MessageBeep(MB_OK);
+}
+
+static void alert_widget(QWidget *widget, int duration)
+{
+#ifdef Q_OS_WINCE
+ Q_UNUSED(widget);
+ Q_UNUSED(duration);
+#else
+ bool stopFlash = duration < 0;
+
+ if (widget && (!widget->isActiveWindow() || stopFlash)) {
+ DWORD timeOut = GetCaretBlinkTime();
+ if (timeOut <= 0)
+ timeOut = 250;
+
+ UINT flashCount;
+ if (duration == 0)
+ flashCount = 10;
+ else
+ flashCount = duration/timeOut;
+
+ FLASHWINFO info;
+ info.cbSize = sizeof(info);
+ info.hwnd = widget->window()->winId();
+ info.dwFlags = stopFlash ? FLASHW_STOP : FLASHW_TRAY;
+ info.dwTimeout = stopFlash ? 0 : timeOut;
+ info.uCount = stopFlash ? 0 : flashCount;
+
+ FlashWindowEx(&info);
+ }
+#endif
+}
+
+void QApplication::alert(QWidget *widget, int duration)
+{
+ if (!QApplicationPrivate::checkInstance("alert"))
+ return;
+
+ if (widget) {
+ alert_widget(widget, duration);
+ } else {
+ const QWidgetList toplevels(topLevelWidgets());
+ for (int i = 0; i < toplevels.count(); ++i) {
+ QWidget *topLevel = toplevels.at(i);
+ alert_widget(topLevel, duration);
+ }
+ }
+}
+
+QString QApplicationPrivate::appName() const
+{
+ return QCoreApplicationPrivate::appName();
+}
+
+
+/*****************************************************************************
+ Main event loop
+ *****************************************************************************/
+
+extern uint qGlobalPostedEventsCount();
+
+void QApplication::winFocus(QWidget *widget, bool gotFocus)
+{
+ if (d_func()->inPopupMode()) // some delayed focus event to ignore
+ return;
+ if (gotFocus) {
+ setActiveWindow(widget);
+ if (QApplicationPrivate::active_window
+ && (QApplicationPrivate::active_window->windowType() == Qt::Dialog)) {
+ // raise the entire application, not just the dialog
+ QWidget* mw = QApplicationPrivate::active_window;
+#ifndef Q_WS_WINCE
+ while(mw->parentWidget() && (mw->windowType() == Qt::Dialog))
+ mw = mw->parentWidget()->window();
+ if (mw->testAttribute(Qt::WA_WState_Created) && mw != QApplicationPrivate::active_window)
+ SetWindowPos(mw->internalWinId(), HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
+#else
+ // On Desktop Windows, we set the first parent of the dialog on top
+ // Child windows will be automatically set above again.
+ // On Windows CE we pass no parent in CreateWindowEx as otherwise
+ // dialogs get embedded into the parent window. Thus we need to
+ // manually iterate and reactivate all windows from bottom up.
+ QList<QWidget*> raiseList;
+ raiseList.push_back(mw);
+ while(mw->parentWidget() && (mw->windowType() == Qt::Dialog)) {
+ mw = mw->parentWidget()->window();
+ raiseList.push_back(mw);
+ }
+ while(!raiseList.isEmpty()) {
+ mw = raiseList.takeLast();
+ if (mw->testAttribute(Qt::WA_WState_Created)) {
+ HWND state = HWND_TOP;
+ if (mw->windowFlags() & Qt::WindowStaysOnBottomHint)
+ state = HWND_BOTTOM;
+ else if (mw->windowFlags() & Qt::WindowStaysOnTopHint)
+ state = HWND_TOPMOST;
+ SetWindowPos(mw->internalWinId(), state, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
+ }
+ }
+#endif
+ }
+ } else {
+ setActiveWindow(0);
+ }
+}
+
+
+//
+// QtWndProc() receives all messages from the main event loop
+//
+
+static bool inLoop = false;
+static int inputcharset = CP_ACP;
+
+#define RETURN(x) { inLoop=false;return x; }
+
+static bool qt_is_translatable_mouse_event(UINT message)
+{
+ return (((message >= WM_MOUSEFIRST && message <= WM_MOUSELAST) ||
+ (message >= WM_XBUTTONDOWN && message <= WM_XBUTTONDBLCLK))
+ && message != WM_MOUSEWHEEL
+ && message != WM_MOUSEHWHEEL)
+
+#ifndef Q_WS_WINCE
+ || (message >= WM_NCMOUSEMOVE && message <= WM_NCMBUTTONDBLCLK)
+#endif
+ ;
+}
+
+extern "C" LRESULT QT_WIN_CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ bool result = true;
+ QEvent::Type evt_type = QEvent::None;
+ QETWidget *widget = 0;
+
+ // there is no need to process pakcets from tablet unless
+ // it is actually on the tablet, a flag to let us know...
+ int nPackets; // the number of packets we get from the queue
+
+ long res = 0;
+ if (!qApp) // unstable app state
+ RETURN(QWinInputContext::DefWindowProc(hwnd,message,wParam,lParam))
+
+ QScopedLoopLevelCounter loopLevelCounter(QThreadData::get2(qApp->thread()));
+
+#if 0
+ // make sure we update widgets also when the user resizes
+ if (inLoop && qApp->loopLevel())
+ qApp->sendPostedEvents(0, QEvent::Paint);
+#endif
+
+ inLoop = true;
+
+ MSG msg;
+ msg.hwnd = hwnd; // create MSG structure
+ msg.message = message; // time and pt fields ignored
+ msg.wParam = wParam;
+ msg.lParam = lParam;
+ msg.pt.x = GET_X_LPARAM(lParam);
+ msg.pt.y = GET_Y_LPARAM(lParam);
+ // If it's a non-client-area message the coords are screen coords, otherwise they are
+ // client coords.
+#ifndef Q_WS_WINCE
+ if (message < WM_NCMOUSEMOVE || message > WM_NCMBUTTONDBLCLK)
+#endif
+ ClientToScreen(msg.hwnd, &msg.pt);
+
+ /*
+ // sometimes the autograb is not released, so the clickevent is sent
+ // to the wrong window. We ignore this for now, because it doesn't
+ // cause any problems.
+ if (msg.message == WM_LBUTTONDOWN || msg.message == WM_RBUTTONDOWN || msg.message == WM_MBUTTONDOWN) {
+ HWND handle = WindowFromPoint(msg.pt);
+ if (msg.hwnd != handle) {
+ msg.hwnd = handle;
+ hwnd = handle;
+ }
+ }
+ */
+
+#if defined(QT_NON_COMMERCIAL)
+ QT_NC_WNDPROC
+#endif
+
+ // send through app filter
+ if (qApp->filterEvent(&msg, &res))
+ return res;
+
+ // close any opened ime candidate window (enabled only on a popup widget)
+ if (imeParentWnd && QApplication::activePopupWidget()
+ && (message == WM_MBUTTONDOWN || message == WM_XBUTTONDOWN
+ || message == WM_LBUTTONDOWN || message == WM_RBUTTONDOWN
+#ifndef Q_WS_WINCE
+ || message == WM_NCMBUTTONDOWN || message == WM_NCLBUTTONDOWN
+ || message == WM_NCRBUTTONDOWN)) {
+#else
+ )) {
+#endif
+ ::SendMessage(imeParentWnd, WM_IME_ENDCOMPOSITION, 0, 0);
+ }
+
+ switch (message) {
+#ifndef Q_WS_WINCE
+#ifndef QT_NO_SESSIONMANAGER
+ case WM_QUERYENDSESSION: {
+ if (sm_smActive) // bogus message from windows
+ RETURN(true);
+
+ sm_smActive = true;
+ sm_blockUserInput = true; // prevent user-interaction outside interaction windows
+ sm_cancel = false;
+ if (qt_session_manager_self)
+ qApp->commitData(*qt_session_manager_self);
+ if (lParam & ENDSESSION_LOGOFF) {
+ _flushall();
+ }
+ RETURN(!sm_cancel);
+ }
+ case WM_ENDSESSION: {
+ sm_smActive = false;
+ sm_blockUserInput = false;
+ bool endsession = (bool) wParam;
+
+ // we receive the message for each toplevel window included internal hidden ones,
+ // but the aboutToQuit signal should be emitted only once.
+ QApplicationPrivate *qAppPriv = QApplicationPrivate::instance();
+ if (endsession && !qAppPriv->aboutToQuitEmitted) {
+ qAppPriv->aboutToQuitEmitted = true;
+ int index = QApplication::staticMetaObject.indexOfSignal("aboutToQuit()");
+ qApp->qt_metacall(QMetaObject::InvokeMetaMethod, index,0);
+ // since the process will be killed immediately quit() has no real effect
+ QApplication::quit();
+ }
+
+ RETURN(0);
+ }
+#endif
+ case WM_DISPLAYCHANGE:
+ if (QApplication::type() == QApplication::Tty)
+ break;
+ if (qt_desktopWidget) {
+ qt_desktopWidget->move(GetSystemMetrics(76), GetSystemMetrics(77));
+ QSize sz(GetSystemMetrics(78), GetSystemMetrics(79));
+ if (sz == qt_desktopWidget->size()) {
+ // a screen resized without changing size of the virtual desktop
+ QResizeEvent rs(sz, qt_desktopWidget->size());
+ QApplication::sendEvent(qt_desktopWidget, &rs);
+ } else {
+ qt_desktopWidget->resize(sz);
+ }
+ }
+ break;
+#endif
+
+ case WM_SETTINGCHANGE:
+#ifdef Q_WS_WINCE
+ // CE SIP hide/show
+ if (qt_desktopWidget && wParam == SPI_SETSIPINFO) {
+ QResizeEvent re(QSize(0, 0), QSize(0, 0)); // Calculated by QDesktopWidget
+ QApplication::sendEvent(qt_desktopWidget, &re);
+ break;
+ }
+#endif
+ // ignore spurious XP message when user logs in again after locking
+ if (QApplication::type() == QApplication::Tty)
+ break;
+ if (QApplication::desktopSettingsAware() && wParam != SPI_SETWORKAREA) {
+ widget = (QETWidget*)QWidget::find(hwnd);
+ if (widget) {
+ if (wParam == SPI_SETNONCLIENTMETRICS)
+ widget->markFrameStrutDirty();
+ }
+ }
+ else if (qt_desktopWidget && wParam == SPI_SETWORKAREA) {
+ qt_desktopWidget->move(GetSystemMetrics(76), GetSystemMetrics(77));
+ QSize sz(GetSystemMetrics(78), GetSystemMetrics(79));
+ if (sz == qt_desktopWidget->size()) {
+ // a screen resized without changing size of the virtual desktop
+ QResizeEvent rs(sz, qt_desktopWidget->size());
+ QApplication::sendEvent(qt_desktopWidget, &rs);
+ } else {
+ qt_desktopWidget->resize(sz);
+ }
+ }
+
+ if (wParam == SPI_SETFONTSMOOTHINGTYPE) {
+ qt_win_read_cleartype_settings();
+ foreach (QWidget *w, QApplication::topLevelWidgets()) {
+ if (!w->isVisible())
+ continue;
+ ((QETWidget *) w)->forceUpdate();
+ }
+ }
+
+ break;
+ case WM_SYSCOLORCHANGE:
+ if (QApplication::type() == QApplication::Tty)
+ break;
+ if (QApplication::desktopSettingsAware()) {
+ widget = (QETWidget*)QWidget::find(hwnd);
+ if (widget && !widget->parentWidget())
+ qt_set_windows_color_resources();
+ }
+ break;
+
+ case WM_LBUTTONDOWN:
+ case WM_MBUTTONDOWN:
+ case WM_RBUTTONDOWN:
+ case WM_XBUTTONDOWN:
+ case WM_LBUTTONDBLCLK:
+ case WM_RBUTTONDBLCLK:
+ case WM_MBUTTONDBLCLK:
+ case WM_XBUTTONDBLCLK:
+ if (qt_win_ignoreNextMouseReleaseEvent)
+ qt_win_ignoreNextMouseReleaseEvent = false;
+ break;
+
+ case WM_LBUTTONUP:
+ case WM_MBUTTONUP:
+ case WM_RBUTTONUP:
+ case WM_XBUTTONUP:
+ if (qt_win_ignoreNextMouseReleaseEvent) {
+ qt_win_ignoreNextMouseReleaseEvent = false;
+ if (qt_button_down && qt_button_down->internalWinId() == autoCaptureWnd) {
+ releaseAutoCapture();
+ qt_button_down = 0;
+ }
+
+ RETURN(0);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if (!widget)
+ widget = (QETWidget*)QWidget::find(hwnd);
+ if (!widget) // don't know this widget
+ goto do_default;
+
+ if (app_do_modal) { // modal event handling
+ int ret = 0;
+ if (!qt_try_modal(widget, &msg, ret))
+ RETURN(ret);
+ }
+
+ res = 0;
+ if (widget->winEvent(&msg, &res)) // send through widget filter
+ RETURN(res);
+
+ if (qt_is_translatable_mouse_event(message)) {
+ if (QApplication::activePopupWidget() != 0) { // in popup mode
+ POINT curPos = msg.pt;
+ QWidget* w = QApplication::widgetAt(curPos.x, curPos.y);
+ if (w)
+ widget = (QETWidget*)w;
+ }
+
+ if (!qt_tabletChokeMouse) {
+ result = widget->translateMouseEvent(msg); // mouse event
+#if defined(Q_WS_WINCE) && !defined(QT_NO_CONTEXTMENU)
+ if (message == WM_LBUTTONDOWN && widget != QApplication::activePopupWidget()) {
+ QWidget* alienWidget = widget;
+ if ((alienWidget != QApplication::activePopupWidget()) && (alienWidget->contextMenuPolicy() != Qt::PreventContextMenu)) {
+ QPoint pos(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
+ QPoint globalPos(msg.pt.x, msg.pt.y);
+ // In case we are using Alien, then the widget to
+ // send the context menu event is a different one
+ if (!alienWidget->testAttribute(Qt::WA_NativeWindow) && !alienWidget->testAttribute(Qt::WA_PaintOnScreen)) {
+ alienWidget = QApplication::widgetAt(globalPos);
+ if (alienWidget)
+ pos = alienWidget->mapFromGlobal(globalPos);
+ }
+ if (alienWidget) {
+ SHRGINFO shrg;
+ shrg.cbSize = sizeof(shrg);
+ shrg.hwndClient = hwnd;
+ shrg.ptDown.x = GET_X_LPARAM(lParam);
+ shrg.ptDown.y = GET_Y_LPARAM(lParam);
+ shrg.dwFlags = SHRG_RETURNCMD | SHRG_NOANIMATION;
+ resolveAygLibs();
+#ifndef QT_NO_GESTURES
+ if (ptrRecognizeGesture && (ptrRecognizeGesture(&shrg) == GN_CONTEXTMENU)) {
+ if (QApplication::activePopupWidget())
+ QApplication::activePopupWidget()->close();
+ QContextMenuEvent e(QContextMenuEvent::Mouse, pos, globalPos);
+ result = qt_sendSpontaneousEvent(alienWidget, &e);
+ }
+#endif // QT_NO_GESTURES
+ }
+ }
+ }
+#endif
+ } else {
+ // Sometimes we only get a WM_MOUSEMOVE message
+ // and sometimes we get both a WM_MOUSEMOVE and
+ // a WM_LBUTTONDOWN/UP, this creates a spurious mouse
+ // press/release event, using the PeekMessage
+ // will help us fix this. This leaves us with a
+ // question:
+ // This effectively kills using the mouse AND the
+ // tablet simultaneously, well creates wacky input.
+ // Is this going to be a problem? (probably not)
+ bool next_is_button = false;
+ bool is_mouse_move = (message == WM_MOUSEMOVE);
+ if (is_mouse_move) {
+ MSG msg1;
+ if (PeekMessage(&msg1, msg.hwnd, WM_MOUSEFIRST,
+ WM_MOUSELAST, PM_NOREMOVE))
+ next_is_button = (msg1.message == WM_LBUTTONUP
+ || msg1.message == WM_LBUTTONDOWN);
+ }
+ if (!is_mouse_move || (is_mouse_move && !next_is_button))
+ qt_tabletChokeMouse = false;
+ }
+ } else {
+ switch (message) {
+ case WM_TOUCH:
+ result = QApplicationPrivate::instance()->translateTouchEvent(msg);
+ break;
+ case WM_KEYDOWN: // keyboard event
+ case WM_SYSKEYDOWN:
+ qt_keymapper_private()->updateKeyMap(msg);
+ // fall-through intended
+ case WM_KEYUP:
+ case WM_SYSKEYUP:
+#if Q_OS_WINCE_WM
+ case WM_HOTKEY:
+ if(HIWORD(msg.lParam) == VK_TBACK) {
+ const bool hotKeyDown = !(LOWORD(msg.lParam) & MOD_KEYUP);
+ msg.lParam = 0x69 << 16;
+ msg.wParam = VK_BACK;
+ if (hotKeyDown) {
+ msg.message = WM_KEYDOWN;
+ qt_keymapper_private()->updateKeyMap(msg);
+ } else {
+ msg.message = WM_KEYUP;
+ }
+ }
+ // fall-through intended
+#endif
+ case WM_IME_CHAR:
+ case WM_IME_KEYDOWN:
+ case WM_CHAR: {
+ MSG msg1;
+ bool anyMsg = PeekMessage(&msg1, msg.hwnd, 0, 0, PM_NOREMOVE);
+ if (anyMsg && msg1.message == WM_DEADCHAR) {
+ result = true; // consume event since there is a dead char next
+ break;
+ }
+ QWidget *g = QWidget::keyboardGrabber();
+ if (g && qt_get_tablet_widget() && hwnd == qt_get_tablet_widget()->winId()) {
+ // if we get an event for the internal tablet widget,
+ // then don't send it to the keyboard grabber, but
+ // send it to the widget itself (we don't use it right
+ // now, just in case).
+ g = 0;
+ }
+ if (g)
+ widget = (QETWidget*)g;
+ else if (QApplication::activePopupWidget())
+ widget = (QETWidget*)QApplication::activePopupWidget()->focusWidget()
+ ? (QETWidget*)QApplication::activePopupWidget()->focusWidget()
+ : (QETWidget*)QApplication::activePopupWidget();
+ else if (QApplication::focusWidget())
+ widget = (QETWidget*)QApplication::focusWidget();
+ else if (!widget || widget->internalWinId() == GetFocus()) // We faked the message to go to exactly that widget.
+ widget = (QETWidget*)widget->window();
+ if (widget->isEnabled())
+ result = sm_blockUserInput
+ ? true
+ : qt_keymapper_private()->translateKeyEvent(widget, msg, g != 0);
+ break;
+ }
+ case WM_SYSCHAR:
+ result = true; // consume event
+ break;
+
+ case WM_MOUSEWHEEL:
+ case WM_MOUSEHWHEEL:
+ result = widget->translateWheelEvent(msg);
+ break;
+
+ case WM_APPCOMMAND:
+ {
+ uint cmd = GET_APPCOMMAND_LPARAM(lParam);
+ uint uDevice = GET_DEVICE_LPARAM(lParam);
+ uint dwKeys = GET_KEYSTATE_LPARAM(lParam);
+
+ int state = translateButtonState(dwKeys, QEvent::KeyPress, 0);
+
+ switch (uDevice) {
+ case FAPPCOMMAND_KEY:
+ {
+ int key = 0;
+
+ switch(cmd) {
+ case APPCOMMAND_BASS_BOOST:
+ key = Qt::Key_BassBoost;
+ break;
+ case APPCOMMAND_BASS_DOWN:
+ key = Qt::Key_BassDown;
+ break;
+ case APPCOMMAND_BASS_UP:
+ key = Qt::Key_BassUp;
+ break;
+ case APPCOMMAND_TREBLE_DOWN:
+ key = Qt::Key_TrebleDown;
+ break;
+ case APPCOMMAND_TREBLE_UP:
+ key = Qt::Key_TrebleUp;
+ break;
+ case APPCOMMAND_HELP:
+ key = Qt::Key_Help;
+ break;
+ case APPCOMMAND_FIND:
+ key = Qt::Key_Search;
+ break;
+ default:
+ break;
+ }
+ if (key) {
+ bool res = false;
+ QWidget *g = QWidget::keyboardGrabber();
+ if (g)
+ widget = (QETWidget*)g;
+ else if (QApplication::focusWidget())
+ widget = (QETWidget*)QApplication::focusWidget();
+ else
+ widget = (QETWidget*)widget->window();
+ if (widget->isEnabled()) {
+ res = QKeyMapper::sendKeyEvent(widget, g != 0, QEvent::KeyPress, key,
+ Qt::KeyboardModifier(state),
+ QString(), false, 0, 0, 0, 0);
+ }
+ if (res)
+ return true;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ result = false;
+ }
+ break;
+
+#ifndef Q_WS_WINCE
+ case WM_NCHITTEST:
+ if (widget->isWindow()) {
+ QPoint pos = widget->mapFromGlobal(QPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)));
+ // don't show resize-cursors for fixed-size widgets
+ QRect fs = widget->frameStrut();
+ if (!widget->isMinimized()) {
+ if (widget->minimumHeight() == widget->maximumHeight()) {
+ if (pos.y() < -(fs.top() - fs.left()))
+ return HTCAPTION;
+ if (pos.y() >= widget->height())
+ return HTBORDER;
+ }
+ if (widget->minimumWidth() == widget->maximumWidth() && (pos.x() < 0 || pos.x() >= widget->width()))
+ return HTBORDER;
+ }
+ }
+
+ result = false;
+ break;
+#endif
+
+ case WM_SYSCOMMAND: {
+#ifndef Q_WS_WINCE
+ bool window_state_change = false;
+ Qt::WindowStates oldstate = Qt::WindowStates(widget->dataPtr()->window_state);
+ // MSDN:In WM_SYSCOMMAND messages, the four low-order bits of the wParam parameter are
+ // used internally by the system. To obtain the correct result when testing the value of
+ // wParam, an application must combine the value 0xFFF0 with the wParam value by using
+ // the bitwise AND operator.
+ switch(0xfff0 & wParam) {
+ case SC_CONTEXTHELP:
+#ifndef QT_NO_WHATSTHIS
+ QWhatsThis::enterWhatsThisMode();
+#endif
+ DefWindowProc(hwnd, WM_NCPAINT, 1, 0);
+ break;
+#if defined(QT_NON_COMMERCIAL)
+ QT_NC_SYSCOMMAND
+#endif
+ case SC_MINIMIZE:
+ window_state_change = true;
+ widget->dataPtr()->window_state |= Qt::WindowMinimized;
+ if (widget->isVisible()) {
+ QHideEvent e;
+ qt_sendSpontaneousEvent(widget, &e);
+ widget->hideChildren(true);
+ const QString title = widget->windowIconText();
+ if (!title.isEmpty())
+ widget->setWindowTitle_helper(title);
+ }
+ result = false;
+ break;
+ case SC_MAXIMIZE:
+ if(widget->isWindow())
+ widget->topData()->normalGeometry = widget->geometry();
+ case SC_RESTORE:
+ window_state_change = true;
+ if ((0xfff0 & wParam) == SC_MAXIMIZE)
+ widget->dataPtr()->window_state |= Qt::WindowMaximized;
+ else if (!widget->isMinimized())
+ widget->dataPtr()->window_state &= ~Qt::WindowMaximized;
+
+ if (widget->isMinimized()) {
+ widget->dataPtr()->window_state &= ~Qt::WindowMinimized;
+ widget->showChildren(true);
+ QShowEvent e;
+ qt_sendSpontaneousEvent(widget, &e);
+ const QString title = widget->windowTitle();
+ if (!title.isEmpty())
+ widget->setWindowTitle_helper(title);
+ }
+ result = false;
+ break;
+ default:
+ result = false;
+ break;
+ }
+
+ if (window_state_change) {
+ QWindowStateChangeEvent e(oldstate);
+ qt_sendSpontaneousEvent(widget, &e);
+ }
+#endif // #ifndef Q_OS_WINCE
+
+ break;
+ }
+
+ case WM_SETTINGCHANGE:
+ if ( QApplication::type() == QApplication::Tty )
+ break;
+
+ if (!msg.wParam) {
+#ifdef Q_WS_WINCE
+ // On Windows CE, lParam parameter is a constant, not a char pointer.
+ if (msg.lParam == INI_INTL) {
+#else
+ QString area = QString::fromWCharArray((wchar_t*)msg.lParam);
+ if (area == QLatin1String("intl")) {
+#endif
+ QLocalePrivate::updateSystemPrivate();
+ if (!widget->testAttribute(Qt::WA_SetLocale))
+ widget->dptr()->setLocale_helper(QLocale(), true);
+ QEvent e(QEvent::LocaleChange);
+ QApplication::sendEvent(qApp, &e);
+ }
+ }
+ else if (msg.wParam == SPI_SETICONTITLELOGFONT) {
+ if (QApplication::desktopSettingsAware()) {
+ widget = (QETWidget*)QWidget::find(hwnd);
+ if (widget && !widget->parentWidget()) {
+ qt_set_windows_font_resources();
+ }
+ }
+ }
+ else if (msg.wParam == SPI_SETNONCLIENTMETRICS) {
+ widget = (QETWidget*)QWidget::find(hwnd);
+ if (widget && !widget->parentWidget()) {
+ qt_set_windows_updateScrollBar(widget);
+ QEvent e(QEvent::LayoutRequest);
+ QApplication::sendEvent(widget, &e);
+ }
+ }
+
+ break;
+
+ case WM_PAINT: // paint event
+ case WM_ERASEBKGND: // erase window background
+ result = widget->translatePaintEvent(msg);
+ break;
+
+#ifndef Q_WS_WINCE
+ case WM_ENTERSIZEMOVE:
+ autoCaptureWnd = hwnd;
+ break;
+ case WM_EXITSIZEMOVE:
+ autoCaptureWnd = 0;
+ break;
+#endif
+ case WM_MOVE: // move window
+ case WM_SIZE: // resize window
+ result = widget->translateConfigEvent(msg);
+ break;
+
+ case WM_ACTIVATEAPP:
+ if (wParam == FALSE) {
+ QApplication::setActiveWindow(0);
+ // Another application was activated while our popups are open,
+ // then close all popups. In case some popup refuses to close,
+ // we give up after 1024 attempts (to avoid an infinite loop).
+ int maxiter = 1024;
+ QWidget *popup;
+ while ((popup=QApplication::activePopupWidget()) && maxiter--)
+ popup->close();
+ }
+ break;
+
+ case WM_ACTIVATE:
+ if ( QApplication::type() == QApplication::Tty )
+ break;
+
+ if (ptrWTOverlap && ptrWTEnable) {
+ // cooperate with other tablet applications, but when
+ // we get focus, I want to use the tablet...
+ if (qt_tablet_context && GET_WM_ACTIVATE_STATE(wParam, lParam)) {
+ if (ptrWTEnable(qt_tablet_context, true))
+ ptrWTOverlap(qt_tablet_context, true);
+ }
+ }
+ if (QApplication::activePopupWidget() && LOWORD(wParam) == WA_INACTIVE &&
+ QWidget::find((HWND)lParam) == 0) {
+ // Another application was activated while our popups are open,
+ // then close all popups. In case some popup refuses to close,
+ // we give up after 1024 attempts (to avoid an infinite loop).
+ int maxiter = 1024;
+ QWidget *popup;
+ while ((popup=QApplication::activePopupWidget()) && maxiter--)
+ popup->close();
+ }
+
+ if (LOWORD(wParam) != WA_INACTIVE) {
+ // WM_ACTIVATEAPP handles the "true" false case, as this is only when the application
+ // loses focus. Doing it here would result in the widget getting focus to not know
+ // where it got it from; it would simply get a 0 value as the old focus widget.
+#ifdef Q_WS_WINCE
+ {
+#ifdef Q_WS_WINCE_WM
+ // On Windows mobile we do not receive WM_SYSCOMMAND / SC_MINIMIZE messages.
+ // Thus we have to unset the minimized state explicitly. We must do this for all
+ // top-level widgets, because we get the HWND of a random widget here.
+ foreach (QWidget* tlw, QApplication::topLevelWidgets()) {
+ if (tlw->isMinimized())
+ tlw->setWindowState(tlw->windowState() & ~Qt::WindowMinimized);
+ }
+#else
+ // On Windows CE we do not receive WM_SYSCOMMAND / SC_MINIMIZE messages.
+ // Thus we have to unset the minimized state explicitly.
+ if (widget->windowState() & Qt::WindowMinimized)
+ widget->setWindowState(widget->windowState() & ~Qt::WindowMinimized);
+#endif // Q_WS_WINCE_WM
+
+#else
+ if (!(widget->windowState() & Qt::WindowMinimized)) {
+#endif
+ // Ignore the activate message send by WindowsXP to a minimized window
+#ifdef Q_WS_WINCE_WM
+ if (widget->windowState() & Qt::WindowFullScreen)
+ qt_wince_hide_taskbar(widget->winId());
+#endif
+ qApp->winFocus(widget, true);
+ // reset any window alert flashes
+ alert_widget(widget, -1);
+ }
+ }
+
+ // Windows tries to activate a modally blocked window.
+ // This happens when restoring an application after "Show Desktop"
+ if (app_do_modal && LOWORD(wParam) == WA_ACTIVE) {
+ QWidget *top = 0;
+ if (!QApplicationPrivate::tryModalHelper(widget, &top) && top && widget != top) {
+ if (top->isVisible()) {
+ top->activateWindow();
+ } else {
+ // This is the case when native file dialogs are shown
+ QWidget *p = (top->parentWidget() ? top->parentWidget()->window() : 0);
+ if (p && p->isVisible())
+ p->activateWindow();
+ }
+ }
+ }
+ break;
+
+#ifndef Q_WS_WINCE
+ case WM_MOUSEACTIVATE:
+ if (widget->window()->windowType() == Qt::Tool) {
+ QWidget *w = widget;
+ if (!w->window()->focusWidget()) {
+ while (w && (w->focusPolicy() & Qt::ClickFocus) == 0) {
+ if (w->isWindow()) {
+ QWidget *fw = w;
+ while ((fw = fw->nextInFocusChain()) != w && fw->focusPolicy() == Qt::NoFocus)
+ ;
+ if (fw != w)
+ break;
+ QWidget *pw = w->parentWidget();
+ while (pw) {
+ pw = pw->window();
+ if (pw && pw->isVisible() && pw->focusWidget()) {
+ Q_ASSERT(pw->testAttribute(Qt::WA_WState_Created));
+ SetWindowPos(pw->internalWinId(), HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
+ break;
+ }
+ pw = pw->parentWidget();
+ }
+ RETURN(MA_NOACTIVATE);
+ }
+ w = w->parentWidget();
+ }
+ }
+ }
+ RETURN(MA_ACTIVATE);
+ break;
+#endif
+ case WM_SHOWWINDOW:
+ if (lParam == SW_PARENTOPENING) {
+ if (widget->testAttribute(Qt::WA_WState_Hidden))
+ RETURN(0);
+ }
+ if (widget->isWindow() && widget->testAttribute(Qt::WA_WState_Visible)
+ && !widget->testWindowState(Qt::WindowMinimized)) {
+ if (lParam == SW_PARENTOPENING) {
+ QShowEvent e;
+ qt_sendSpontaneousEvent(widget, &e);
+ widget->showChildren(true);
+ } else if (lParam == SW_PARENTCLOSING) {
+ QHideEvent e;
+ qt_sendSpontaneousEvent(widget, &e);
+ widget->hideChildren(true);
+ }
+ }
+ if (!wParam && autoCaptureWnd == widget->internalWinId())
+ releaseAutoCapture();
+ result = false;
+ break;
+
+ case WM_PALETTECHANGED: // our window changed palette
+ if (QColormap::hPal() && (WId)wParam == widget->internalWinId())
+ RETURN(0); // otherwise: FALL THROUGH!
+ // FALL THROUGH
+ case WM_QUERYNEWPALETTE: // realize own palette
+ if (QColormap::hPal()) {
+ Q_ASSERT(widget->testAttribute(Qt::WA_WState_Created));
+ HDC hdc = GetDC(widget->internalWinId());
+ HPALETTE hpalOld = SelectPalette(hdc, QColormap::hPal(), FALSE);
+ uint n = RealizePalette(hdc);
+ if (n)
+ InvalidateRect(widget->internalWinId(), 0, TRUE);
+ SelectPalette(hdc, hpalOld, TRUE);
+ RealizePalette(hdc);
+ ReleaseDC(widget->internalWinId(), hdc);
+ RETURN(n);
+ }
+ break;
+ case WM_CLOSE: // close window
+ widget->translateCloseEvent(msg);
+ RETURN(0); // always handled
+
+ case WM_DESTROY: // destroy window
+ if (hwnd == curWin) {
+ QWidget *enter = QWidget::mouseGrabber();
+ if (enter == widget)
+ enter = 0;
+ QApplicationPrivate::dispatchEnterLeave(enter, widget);
+ curWin = enter ? enter->effectiveWinId() : 0;
+ qt_last_mouse_receiver = enter;
+ }
+ if (widget == popupButtonFocus)
+ popupButtonFocus = 0;
+ result = false;
+ break;
+
+#ifndef Q_WS_WINCE
+ case WM_WINDOWPOSCHANGING:
+ {
+ result = false;
+ if (widget->isWindow()) {
+ WINDOWPOS *winPos = (WINDOWPOS *)lParam;
+ if (widget->layout() && widget->layout()->hasHeightForWidth()
+ && !(winPos->flags & (SWP_NOCOPYBITS | SWP_NOSIZE))) {
+ QRect fs = widget->frameStrut();
+ QRect rect = widget->geometry();
+ QRect newRect = QRect(winPos->x + fs.left(),
+ winPos->y + fs.top(),
+ winPos->cx - fs.left() - fs.right(),
+ winPos->cy - fs.top() - fs.bottom());
+
+ QSize newSize = QLayout::closestAcceptableSize(widget, newRect.size());
+
+ int dh = newSize.height() - newRect.height();
+ int dw = newSize.width() - newRect.width();
+ if (!dw && ! dh)
+ break; // Size OK
+
+ if (rect.y() != newRect.y()) {
+ newRect.setTop(newRect.top() - dh);
+ } else {
+ newRect.setBottom(newRect.bottom() + dh);
+ }
+
+ if (rect.x() != newRect.x()) {
+ newRect.setLeft(newRect.left() - dw);
+ } else {
+ newRect.setRight(newRect.right() + dw);
+ }
+
+ winPos->x = newRect.x() - fs.left();
+ winPos->y = newRect.y() - fs.top();
+ winPos->cx = newRect.width() + fs.left() + fs.right();
+ winPos->cy = newRect.height() + fs.top() + fs.bottom();
+
+ RETURN(0);
+ }
+ if (widget->windowFlags() & Qt::WindowStaysOnBottomHint) {
+ winPos->hwndInsertAfter = HWND_BOTTOM;
+ }
+ }
+ }
+ break;
+
+ case WM_GETMINMAXINFO:
+ if (widget->xtra()) {
+ MINMAXINFO *mmi = (MINMAXINFO *)lParam;
+ QWExtra *x = widget->xtra();
+ QRect fs = widget->frameStrut();
+ if ( x->minw > 0 )
+ mmi->ptMinTrackSize.x = x->minw + fs.right() + fs.left();
+ if ( x->minh > 0 )
+ mmi->ptMinTrackSize.y = x->minh + fs.top() + fs.bottom();
+ qint32 maxw = (x->maxw >= x->minw) ? x->maxw : x->minw;
+ qint32 maxh = (x->maxh >= x->minh) ? x->maxh : x->minh;
+ if ( maxw < QWIDGETSIZE_MAX ) {
+ mmi->ptMaxTrackSize.x = maxw + fs.right() + fs.left();
+ // windows with title bar have an implicit size limit of 112 pixels
+ if (widget->windowFlags() & Qt::WindowTitleHint)
+ mmi->ptMaxTrackSize.x = qMax<long>(mmi->ptMaxTrackSize.x, 112);
+ }
+ if ( maxh < QWIDGETSIZE_MAX )
+ mmi->ptMaxTrackSize.y = maxh + fs.top() + fs.bottom();
+ RETURN(0);
+ }
+ break;
+
+#ifndef QT_NO_CONTEXTMENU
+ case WM_CONTEXTMENU:
+ {
+ // it's not VK_APPS or Shift+F10, but a click in the NC area
+ if (lParam != (int)0xffffffff) {
+ result = false;
+ break;
+ }
+
+ QWidget *fw = QWidget::keyboardGrabber();
+ if (!fw) {
+ if (QApplication::activePopupWidget())
+ fw = (QApplication::activePopupWidget()->focusWidget()
+ ? QApplication::activePopupWidget()->focusWidget()
+ : QApplication::activePopupWidget());
+ else if (QApplication::focusWidget())
+ fw = QApplication::focusWidget();
+ else if (widget)
+ fw = widget->window();
+ }
+ if (fw && fw->isEnabled()) {
+ QPoint pos = fw->inputMethodQuery(Qt::ImMicroFocus).toRect().center();
+ QContextMenuEvent e(QContextMenuEvent::Keyboard, pos, fw->mapToGlobal(pos),
+ qt_win_getKeyboardModifiers());
+ result = qt_sendSpontaneousEvent(fw, &e);
+ }
+ }
+ break;
+#endif
+#endif
+
+ case WM_IME_STARTCOMPOSITION:
+ case WM_IME_ENDCOMPOSITION:
+ case WM_IME_COMPOSITION: {
+ QWidget *fw = QApplication::focusWidget();
+ QWinInputContext *im = fw ? qobject_cast<QWinInputContext *>(fw->inputContext()) : 0;
+ if (fw && im) {
+ if(message == WM_IME_STARTCOMPOSITION)
+ result = im->startComposition();
+ else if (message == WM_IME_ENDCOMPOSITION)
+ result = im->endComposition();
+ else if (message == WM_IME_COMPOSITION)
+ result = im->composition(lParam);
+ }
+ break;
+ }
+ case WM_IME_REQUEST: {
+ QWidget *fw = QApplication::focusWidget();
+ QWinInputContext *im = fw ? qobject_cast<QWinInputContext *>(fw->inputContext()) : 0;
+ if (fw && im) {
+ if(wParam == IMR_RECONVERTSTRING) {
+ int ret = im->reconvertString((RECONVERTSTRING *)lParam);
+ if (ret == -1) {
+ result = false;
+ } else {
+ return ret;
+ }
+ } else if (wParam == IMR_CONFIRMRECONVERTSTRING) {
+ RETURN(TRUE);
+ } else {
+ // in all other cases, call DefWindowProc()
+ result = false;
+ }
+ }
+ break;
+ }
+#ifndef Q_WS_WINCE
+ case WM_CHANGECBCHAIN:
+ case WM_DRAWCLIPBOARD:
+#endif
+ case WM_RENDERFORMAT:
+ case WM_RENDERALLFORMATS:
+#ifndef QT_NO_CLIPBOARD
+ case WM_DESTROYCLIPBOARD:
+ if (qt_clipboard) {
+ QClipboardEvent e(reinterpret_cast<QEventPrivate *>(&msg));
+ qt_sendSpontaneousEvent(qt_clipboard, &e);
+ RETURN(0);
+ }
+ result = false;
+ break;
+#endif //QT_NO_CLIPBOARD
+#ifndef QT_NO_ACCESSIBILITY
+ case WM_GETOBJECT:
+ {
+ /* On Win64, lParam can be 0x00000000fffffffc or 0xfffffffffffffffc (!),
+ but MSDN says that lParam should be converted to a DWORD
+ before its compared against OBJID_CLIENT
+ */
+ const DWORD dwObjId = (DWORD)lParam;
+ // Ignoring all requests while starting up
+ if (QApplication::startingUp() || QApplication::closingDown() || dwObjId != OBJID_CLIENT) {
+ result = false;
+ break;
+ }
+
+ typedef LRESULT (WINAPI *PtrLresultFromObject)(REFIID, WPARAM, LPUNKNOWN);
+ static PtrLresultFromObject ptrLresultFromObject = 0;
+ static bool oleaccChecked = false;
+
+ if (!oleaccChecked) {
+ oleaccChecked = true;
+#if !defined(Q_OS_WINCE)
+ ptrLresultFromObject = (PtrLresultFromObject)QSystemLibrary::resolve(QLatin1String("oleacc"), "LresultFromObject");
+#endif
+ }
+ if (ptrLresultFromObject) {
+ QAccessibleInterface *acc = QAccessible::queryAccessibleInterface(widget);
+ if (!acc) {
+ result = false;
+ break;
+ }
+
+ // and get an instance of the IAccessibile implementation
+ IAccessible *iface = qt_createWindowsAccessible(acc);
+ res = ptrLresultFromObject(IID_IAccessible, wParam, iface); // ref == 2
+ iface->Release(); // the client will release the object again, and then it will destroy itself
+
+ if (res > 0)
+ RETURN(res);
+ }
+ }
+ result = false;
+ break;
+ case WM_GETTEXT:
+ if (!widget->isWindow()) {
+ int ret = 0;
+ QAccessibleInterface *acc = QAccessible::queryAccessibleInterface(widget);
+ if (acc) {
+ QString text = acc->text(QAccessible::Name, 0);
+ if (text.isEmpty())
+ text = widget->objectName();
+ ret = qMin<int>(wParam - 1, text.size());
+ text.resize(ret);
+ memcpy((void *)lParam, text.utf16(), (text.size() + 1) * sizeof(ushort));
+ delete acc;
+ }
+ if (!ret) {
+ result = false;
+ break;
+ }
+ RETURN(ret);
+ }
+ result = false;
+ break;
+#endif
+ case WT_PACKET:
+ if (ptrWTPacketsGet) {
+ if ((nPackets = ptrWTPacketsGet(qt_tablet_context, QT_TABLET_NPACKETQSIZE, &localPacketBuf))) {
+ result = widget->translateTabletEvent(msg, localPacketBuf, nPackets);
+ }
+ }
+ break;
+ case WT_PROXIMITY:
+
+ #ifndef QT_NO_TABLETEVENT
+ if (ptrWTPacketsGet && ptrWTInfo) {
+ const bool enteredProximity = LOWORD(lParam) != 0;
+ PACKET proximityBuffer[1]; // we are only interested in the first packet in this case
+ const int totalPacks = ptrWTPacketsGet(qt_tablet_context, 1, proximityBuffer);
+ if (totalPacks > 0) {
+ const UINT currentCursor = proximityBuffer[0].pkCursor;
+
+ UINT csr_physid;
+ ptrWTInfo(WTI_CURSORS + currentCursor, CSR_PHYSID, &csr_physid);
+ UINT csr_type;
+ ptrWTInfo(WTI_CURSORS + currentCursor, CSR_TYPE, &csr_type);
+ const UINT deviceIdMask = 0xFF6; // device type mask && device color mask
+ quint64 uniqueId = (csr_type & deviceIdMask);
+ uniqueId = (uniqueId << 32) | csr_physid;
+
+ // initialising and updating the cursor should be done in response to
+ // WT_CSRCHANGE. We do it in WT_PROXIMITY because some wintab never send
+ // the event WT_CSRCHANGE even if asked with CXO_CSRMESSAGES
+ const QTabletCursorInfo *const globalCursorInfo = tCursorInfo();
+ if (!globalCursorInfo->contains(uniqueId))
+ tabletInit(uniqueId, csr_type, qt_tablet_context);
+
+ currentTabletPointer = globalCursorInfo->value(uniqueId);
+ tabletUpdateCursor(currentTabletPointer, currentCursor);
+ }
+ qt_tabletChokeMouse = false;
+
+ QTabletEvent tabletProximity(enteredProximity ? QEvent::TabletEnterProximity
+ : QEvent::TabletLeaveProximity,
+ QPoint(), QPoint(), QPointF(), currentTabletPointer.currentDevice, currentTabletPointer.currentPointerType, 0, 0,
+ 0, 0, 0, 0, 0, currentTabletPointer.llId);
+ QApplication::sendEvent(qApp, &tabletProximity);
+ }
+ #endif // QT_NO_TABLETEVENT
+
+ break;
+#ifdef Q_WS_WINCE_WM
+ case WM_SETFOCUS: {
+ HIMC hC;
+ hC = ImmGetContext(hwnd);
+ ImmSetOpenStatus(hC, TRUE);
+ ImmEscape(NULL, hC, IME_ESC_SET_MODE, (LPVOID)IM_SPELL);
+ result = false;
+ }
+ break;
+#endif
+ case WM_KILLFOCUS:
+ if (!QWidget::find((HWND)wParam)) { // we don't get focus, so unset it now
+ if (!widget->hasFocus()) // work around Windows bug after minimizing/restoring
+ widget = (QETWidget*)QApplication::focusWidget();
+ HWND focus = ::GetFocus();
+ //if there is a current widget and the new widget belongs to the same toplevel window
+ //or if the current widget was embedded into non-qt window (i.e. we won't get WM_ACTIVATEAPP)
+ //then we clear the focus on the widget
+ //in case the new widget belongs to a different widget hierarchy, clearing the focus
+ //will be handled because the active window will change
+ const bool embedded = widget && ((QETWidget*)widget->window())->topData()->embedded;
+ if (widget && (embedded || ::IsChild(widget->window()->internalWinId(), focus))) {
+ widget->clearFocus();
+ result = true;
+ } else {
+ result = false;
+ }
+ } else {
+ result = false;
+ }
+ break;
+ case WM_THEMECHANGED:
+ if ((widget->windowType() == Qt::Desktop) || !qApp || QApplication::closingDown()
+ || QApplication::type() == QApplication::Tty)
+ break;
+
+ if (widget->testAttribute(Qt::WA_WState_Polished))
+ QApplication::style()->unpolish(widget);
+
+ if (widget->testAttribute(Qt::WA_WState_Polished))
+ QApplication::style()->polish(widget);
+ widget->repolishStyle(*QApplication::style());
+ if (widget->isVisible())
+ widget->update();
+ break;
+
+#ifndef Q_WS_WINCE
+ case WM_INPUTLANGCHANGE: {
+ wchar_t info[7];
+ if (!GetLocaleInfo(MAKELCID(lParam, SORT_DEFAULT), LOCALE_IDEFAULTANSICODEPAGE, info, 6)) {
+ inputcharset = CP_ACP;
+ } else {
+ inputcharset = QString::fromWCharArray(info).toInt();
+ }
+ QKeyMapper::changeKeyboard();
+ break;
+ }
+#else
+ case WM_COMMAND: {
+ bool OkCommand = (LOWORD(wParam) == 0x1);
+ bool CancelCommand = (LOWORD(wParam) == 0x2);
+ if (OkCommand)
+ QApplication::postEvent(widget, new QEvent(QEvent::OkRequest));
+ if (CancelCommand)
+ widget->showMinimized();
+ else
+#ifndef QT_NO_MENUBAR
+ QMenuBar::wceCommands(LOWORD(wParam));
+#endif
+ result = true;
+ }
+ break;
+ case WM_HELP:
+ QApplication::postEvent(widget, new QEvent(QEvent::HelpRequest));
+ result = true;
+ break;
+#endif
+
+ case WM_MOUSELEAVE:
+ // We receive a mouse leave for curWin, meaning
+ // the mouse was moved outside our widgets
+ if (widget->internalWinId() == curWin) {
+ bool dispatch = !widget->underMouse();
+ // hasMouse is updated when dispatching enter/leave,
+ // so test if it is actually up-to-date
+ if (!dispatch) {
+ QRect geom = widget->geometry();
+ if (widget->parentWidget() && !widget->isWindow()) {
+ QPoint gp = widget->parentWidget()->mapToGlobal(widget->pos());
+ geom.setX(gp.x());
+ geom.setY(gp.y());
+ }
+ QPoint cpos = QCursor::pos();
+ dispatch = !geom.contains(cpos);
+ if ( !dispatch && !QWidget::mouseGrabber()) {
+ QWidget *hittest = QApplication::widgetAt(cpos);
+ dispatch = !hittest || hittest->internalWinId() != curWin;
+ }
+ if (!dispatch) {
+ HRGN hrgn = qt_tryCreateRegion(QRegion::Rectangle, 0,0,0,0);
+ if (GetWindowRgn(curWin, hrgn) != ERROR) {
+ QPoint lcpos = widget->mapFromGlobal(cpos);
+ dispatch = !PtInRegion(hrgn, lcpos.x(), lcpos.y());
+ }
+ DeleteObject(hrgn);
+ }
+ }
+ if (dispatch) {
+ if (qt_last_mouse_receiver && !qt_last_mouse_receiver->internalWinId())
+ QApplicationPrivate::dispatchEnterLeave(0, qt_last_mouse_receiver);
+ else
+ QApplicationPrivate::dispatchEnterLeave(0, QWidget::find((WId)curWin));
+ curWin = 0;
+ qt_last_mouse_receiver = 0;
+ }
+ }
+ break;
+
+ case WM_CANCELMODE:
+ {
+ // this goes through QMenuBar's event filter
+ QEvent e(QEvent::ActivationChange);
+ QApplication::sendEvent(qApp, &e);
+ }
+ break;
+
+ case WM_IME_NOTIFY:
+ // special handling for ime, only for widgets in a popup
+ if (wParam == IMN_OPENCANDIDATE) {
+ imeParentWnd = hwnd;
+ if (QApplication::activePopupWidget()) {
+ // temporarily disable the mouse grab to allow mouse input in
+ // the ime candidate window. The actual handle is untouched
+ if (autoCaptureWnd)
+ ReleaseCapture();
+ }
+ } else if (wParam == IMN_CLOSECANDIDATE) {
+ imeParentWnd = 0;
+ if (QApplication::activePopupWidget()) {
+ // undo the action above, when candidate window is closed
+ if (autoCaptureWnd)
+ SetCapture(autoCaptureWnd);
+ }
+ }
+ result = false;
+ break;
+#ifndef QT_NO_GESTURES
+#if !defined(Q_WS_WINCE) || defined(QT_WINCE_GESTURES)
+ case WM_GESTURE: {
+ GESTUREINFO gi;
+ memset(&gi, 0, sizeof(GESTUREINFO));
+ gi.cbSize = sizeof(GESTUREINFO);
+
+ QApplicationPrivate *qAppPriv = QApplicationPrivate::instance();
+ BOOL bResult = false;
+ if (qAppPriv->GetGestureInfo)
+ bResult = qAppPriv->GetGestureInfo((HANDLE)msg.lParam, &gi);
+ if (bResult) {
+ if (gi.dwID == GID_BEGIN) {
+ // find the alien widget for the gesture position.
+ // This might not be accurate as the position is the center
+ // point of two fingers for multi-finger gestures.
+ QPoint pt(gi.ptsLocation.x, gi.ptsLocation.y);
+ QWidget *w = widget->childAt(widget->mapFromGlobal(pt));
+ qAppPriv->gestureWidget = w ? w : widget;
+ }
+ if (qAppPriv->gestureWidget)
+ static_cast<QETWidget*>(qAppPriv->gestureWidget)->translateGestureEvent(msg, gi);
+ if (qAppPriv->CloseGestureInfoHandle)
+ qAppPriv->CloseGestureInfoHandle((HANDLE)msg.lParam);
+ if (gi.dwID == GID_END)
+ qAppPriv->gestureWidget = 0;
+ } else {
+ DWORD dwErr = GetLastError();
+ if (dwErr > 0)
+ qWarning() << "translateGestureEvent: error = " << dwErr;
+ }
+ result = true;
+ break;
+ }
+#endif // !defined(Q_WS_WINCE) || defined(QT_WINCE_GESTURES)
+#endif // QT_NO_GESTURES
+#ifndef QT_NO_CURSOR
+ case WM_SETCURSOR: {
+ QCursor *ovr = QApplication::overrideCursor();
+ if (ovr) {
+ SetCursor(ovr->handle());
+ RETURN(TRUE);
+ }
+ result = false;
+ break;
+ }
+#endif
+ default:
+ result = false; // event was not processed
+ break;
+ }
+ }
+
+ if (evt_type != QEvent::None) { // simple event
+ QEvent e(evt_type);
+ result = qt_sendSpontaneousEvent(widget, &e);
+ }
+
+ if (result)
+ RETURN(false);
+
+do_default:
+ RETURN(QWinInputContext::DefWindowProc(hwnd,message,wParam,lParam))
+}
+
+
+/*****************************************************************************
+ Modal widgets; We have implemented our own modal widget mechanism
+ to get total control.
+ A modal widget without a parent becomes application-modal.
+ A modal widget with a parent becomes modal to its parent and grandparents..
+
+ QApplicationPrivate::enterModal()
+ Enters modal state
+ Arguments:
+ QWidget *widget A modal widget
+
+ QApplicationPrivate::leaveModal()
+ Leaves modal state for a widget
+ Arguments:
+ QWidget *widget A modal widget
+ *****************************************************************************/
+
+bool QApplicationPrivate::modalState()
+{
+ return app_do_modal;
+}
+
+void QApplicationPrivate::enterModal_sys(QWidget *widget)
+{
+ if (!qt_modal_stack)
+ qt_modal_stack = new QWidgetList;
+
+ releaseAutoCapture();
+ ClipCursor(0);
+ QWidget *leave = qt_last_mouse_receiver;
+ if (!leave)
+ leave = QWidget::find((WId)curWin);
+ QApplicationPrivate::dispatchEnterLeave(0, leave);
+ qt_modal_stack->insert(0, widget);
+ app_do_modal = true;
+ curWin = 0;
+ qt_last_mouse_receiver = 0;
+ qt_win_ignoreNextMouseReleaseEvent = false;
+}
+
+void QApplicationPrivate::leaveModal_sys(QWidget *widget)
+{
+ if (qt_modal_stack && qt_modal_stack->removeAll(widget)) {
+ if (qt_modal_stack->isEmpty()) {
+ delete qt_modal_stack;
+ qt_modal_stack = 0;
+ QPoint p(QCursor::pos());
+ app_do_modal = false; // necessary, we may get recursively into qt_try_modal below
+ QWidget* w = QApplication::widgetAt(p.x(), p.y());
+ QWidget *leave = qt_last_mouse_receiver;
+ if (!leave)
+ leave = QWidget::find((WId)curWin);
+ if (QWidget *grabber = QWidget::mouseGrabber()) {
+ w = grabber;
+ if (leave == w)
+ leave = 0;
+ }
+ QApplicationPrivate::dispatchEnterLeave(w, leave); // send synthetic enter event
+ curWin = w ? w->effectiveWinId() : 0;
+ qt_last_mouse_receiver = w;
+ }
+ qt_win_ignoreNextMouseReleaseEvent = true;
+ }
+ app_do_modal = qt_modal_stack != 0;
+}
+
+bool qt_try_modal(QWidget *widget, MSG *msg, int& ret)
+{
+#if defined(Q_OS_WINCE)
+ Q_UNUSED(ret);
+#endif
+ QWidget * top = 0;
+
+ if (QApplicationPrivate::tryModalHelper(widget, &top))
+ return true;
+
+ int type = msg->message;
+
+ bool block_event = false;
+#ifndef Q_WS_WINCE
+ if (type != WM_NCHITTEST) {
+#endif
+ if ((type >= WM_MOUSEFIRST && type <= WM_MOUSELAST) ||
+ type == WM_MOUSEWHEEL || type == WM_MOUSEHWHEEL ||
+ type == WM_MOUSELEAVE ||
+ (type >= WM_KEYFIRST && type <= WM_KEYLAST)
+#ifndef Q_WS_WINCE
+ || type == WM_NCMOUSEMOVE
+#endif
+ ) {
+ if (type == WM_MOUSEMOVE
+#ifndef Q_WS_WINCE
+ || type == WM_NCMOUSEMOVE
+#endif
+ ) {
+#ifndef QT_NO_CURSOR
+ QCursor *c = qt_grab_cursor();
+ if (!c)
+ c = QApplication::overrideCursor();
+ if (c) // application cursor defined
+ SetCursor(c->handle());
+ else
+ SetCursor(QCursor(Qt::ArrowCursor).handle());
+#endif // QT_NO_CURSOR
+ }
+ block_event = true;
+ } else if (type == WM_CLOSE) {
+ block_event = true;
+ }
+#ifndef Q_WS_WINCE
+ else if (type == WM_MOUSEACTIVATE || type == WM_NCLBUTTONDOWN){
+ if (!top->isActiveWindow()) {
+ top->activateWindow();
+ } else {
+ QApplication::beep();
+ }
+ block_event = true;
+ ret = MA_NOACTIVATEANDEAT;
+ } else if (type == WM_SYSCOMMAND) {
+ if (!(msg->wParam == SC_RESTORE && widget->isMinimized()))
+ block_event = true;
+ }
+ }
+#endif
+
+ return !block_event;
+}
+
+
+/*****************************************************************************
+ Popup widget mechanism
+
+ openPopup()
+ Adds a widget to the list of popup widgets
+ Arguments:
+ QWidget *widget The popup widget to be added
+
+ closePopup()
+ Removes a widget from the list of popup widgets
+ Arguments:
+ QWidget *widget The popup widget to be removed
+ *****************************************************************************/
+
+void QApplicationPrivate::openPopup(QWidget *popup)
+{
+ if (!QApplicationPrivate::popupWidgets)
+ QApplicationPrivate::popupWidgets = new QWidgetList;
+ QApplicationPrivate::popupWidgets->append(popup);
+ if (!popup->isEnabled())
+ return;
+
+ // close any opened 'ime candidate window'
+ if (imeParentWnd)
+ ::SendMessage(imeParentWnd, WM_IME_ENDCOMPOSITION, 0, 0);
+
+ if (QApplicationPrivate::popupWidgets->count() == 1 && !qt_nograb()) {
+ Q_ASSERT(popup->testAttribute(Qt::WA_WState_Created));
+ setAutoCapture(popup->internalWinId()); // grab mouse/keyboard
+ }
+ // Popups are not focus-handled by the window system (the first
+ // popup grabbed the keyboard), so we have to do that manually: A
+ // new popup gets the focus
+ if (popup->focusWidget()) {
+ popup->focusWidget()->setFocus(Qt::PopupFocusReason);
+ } else if (QApplicationPrivate::popupWidgets->count() == 1) { // this was the first popup
+ if (QWidget *fw = QApplication::focusWidget()) {
+ QFocusEvent e(QEvent::FocusOut, Qt::PopupFocusReason);
+ QApplication::sendEvent(fw, &e);
+ }
+ }
+}
+
+void QApplicationPrivate::closePopup(QWidget *popup)
+{
+ if (!QApplicationPrivate::popupWidgets)
+ return;
+ QApplicationPrivate::popupWidgets->removeAll(popup);
+ POINT curPos;
+ GetCursorPos(&curPos);
+
+ // close any opened 'ime candidate window'
+ if (imeParentWnd)
+ ::SendMessage(imeParentWnd, WM_IME_ENDCOMPOSITION, 0, 0);
+
+ if (QApplicationPrivate::popupWidgets->isEmpty()) { // this was the last popup
+ delete QApplicationPrivate::popupWidgets;
+ QApplicationPrivate::popupWidgets = 0;
+ replayPopupMouseEvent = (!popup->geometry().contains(QPoint(curPos.x, curPos.y))
+ && !popup->testAttribute(Qt::WA_NoMouseReplay));
+ if (!popup->isEnabled())
+ return;
+ if (!qt_nograb()) // grabbing not disabled
+ releaseAutoCapture();
+ QWidget *fw = QApplicationPrivate::active_window ? QApplicationPrivate::active_window->focusWidget()
+ : QApplication::focusWidget();
+ if (fw) {
+ if (fw != QApplication::focusWidget()) {
+ fw->setFocus(Qt::PopupFocusReason);
+ } else {
+ QFocusEvent e(QEvent::FocusIn, Qt::PopupFocusReason);
+ QApplication::sendEvent(fw, &e);
+ }
+ }
+ } else {
+ // Popups are not focus-handled by the window system (the
+ // first popup grabbed the keyboard), so we have to do that
+ // manually: A popup was closed, so the previous popup gets
+ // the focus.
+ QWidget* aw = QApplicationPrivate::popupWidgets->last();
+ if (QApplicationPrivate::popupWidgets->count() == 1) {
+ Q_ASSERT(aw->testAttribute(Qt::WA_WState_Created));
+ setAutoCapture(aw->internalWinId());
+ }
+ if (QWidget *fw = aw->focusWidget())
+ fw->setFocus(Qt::PopupFocusReason);
+ }
+}
+
+
+
+
+/*****************************************************************************
+ Event translation; translates Windows events to Qt events
+ *****************************************************************************/
+
+//
+// Auto-capturing for mouse press and mouse release
+//
+
+static void setAutoCapture(HWND h)
+{
+ if (autoCaptureWnd)
+ releaseAutoCapture();
+ autoCaptureWnd = h;
+ SetCapture(h);
+}
+
+static void releaseAutoCapture()
+{
+ if (autoCaptureWnd) {
+ ReleaseCapture();
+ autoCaptureWnd = 0;
+ }
+}
+
+
+//
+// Mouse event translation
+//
+// Non-client mouse messages are not translated
+//
+
+static const ushort mouseTbl[] = {
+ WM_MOUSEMOVE, QEvent::MouseMove, 0,
+ WM_LBUTTONDOWN, QEvent::MouseButtonPress, Qt::LeftButton,
+ WM_LBUTTONUP, QEvent::MouseButtonRelease, Qt::LeftButton,
+ WM_LBUTTONDBLCLK, QEvent::MouseButtonDblClick, Qt::LeftButton,
+ WM_RBUTTONDOWN, QEvent::MouseButtonPress, Qt::RightButton,
+ WM_RBUTTONUP, QEvent::MouseButtonRelease, Qt::RightButton,
+ WM_RBUTTONDBLCLK, QEvent::MouseButtonDblClick, Qt::RightButton,
+ WM_MBUTTONDOWN, QEvent::MouseButtonPress, Qt::MidButton,
+ WM_MBUTTONUP, QEvent::MouseButtonRelease, Qt::MidButton,
+ WM_MBUTTONDBLCLK, QEvent::MouseButtonDblClick, Qt::MidButton,
+ // use XButton1 for now, the real X button is decided later
+ WM_XBUTTONDOWN, QEvent::MouseButtonPress, Qt::XButton1,
+ WM_XBUTTONUP, QEvent::MouseButtonRelease, Qt::XButton1,
+ WM_XBUTTONDBLCLK, QEvent::MouseButtonDblClick, Qt::XButton1,
+
+#ifndef Q_WS_WINCE
+ WM_NCMOUSEMOVE, QEvent::NonClientAreaMouseMove, 0,
+ WM_NCLBUTTONDOWN, QEvent::NonClientAreaMouseButtonPress, Qt::LeftButton,
+ WM_NCLBUTTONUP, QEvent::NonClientAreaMouseButtonRelease, Qt::LeftButton,
+ WM_NCLBUTTONDBLCLK, QEvent::NonClientAreaMouseButtonDblClick, Qt::LeftButton,
+ WM_NCRBUTTONDOWN, QEvent::NonClientAreaMouseButtonPress, Qt::RightButton,
+ WM_NCRBUTTONUP, QEvent::NonClientAreaMouseButtonRelease, Qt::RightButton,
+ WM_NCRBUTTONDBLCLK, QEvent::NonClientAreaMouseButtonDblClick, Qt::RightButton,
+ WM_NCMBUTTONDOWN, QEvent::NonClientAreaMouseButtonPress, Qt::MidButton,
+ WM_NCMBUTTONUP, QEvent::NonClientAreaMouseButtonRelease, Qt::MidButton,
+ WM_NCMBUTTONDBLCLK, QEvent::NonClientAreaMouseButtonDblClick, Qt::MidButton,
+#endif
+
+ 0, 0, 0
+};
+
+static int translateButtonState(int s, int type, int button)
+{
+ Q_UNUSED(type);
+ Q_UNUSED(button);
+ int bst = 0;
+ if (s & MK_LBUTTON)
+ bst |= Qt::LeftButton;
+ if (s & MK_MBUTTON)
+ bst |= Qt::MidButton;
+ if (s & MK_RBUTTON)
+ bst |= Qt::RightButton;
+ if (s & MK_SHIFT)
+ bst |= Qt::ShiftModifier;
+ if (s & MK_CONTROL)
+ bst |= Qt::ControlModifier;
+
+ if (s & MK_XBUTTON1)
+ bst |= Qt::XButton1;
+ if (s & MK_XBUTTON2)
+ bst |= Qt::XButton2;
+
+ if (GetKeyState(VK_MENU) < 0)
+ bst |= Qt::AltModifier;
+
+ if ((GetKeyState(VK_LWIN) < 0) ||
+ (GetKeyState(VK_RWIN) < 0))
+ bst |= Qt::MetaModifier;
+
+ return bst;
+}
+
+void qt_win_eatMouseMove()
+{
+ // after closing a windows dialog with a double click (i.e. open a file)
+ // the message queue still contains a dubious WM_MOUSEMOVE message where
+ // the left button is reported to be down (wParam != 0).
+ // remove all those messages (usually 1) and post the last one with a
+ // reset button state
+
+ MSG msg = {0, 0, 0, 0, 0, {0, 0} };
+ while (PeekMessage(&msg, 0, WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE))
+ ;
+ if (msg.message == WM_MOUSEMOVE)
+ PostMessage(msg.hwnd, msg.message, 0, msg.lParam);
+}
+
+// In DnD, the mouse release event never appears, so the
+// mouse button state machine must be manually reset
+void QApplication::winMouseButtonUp()
+{
+ qt_button_down = 0;
+ releaseAutoCapture();
+}
+
+void QETWidget::repolishStyle(QStyle &)
+{
+ QEvent e(QEvent::StyleChange);
+ QApplication::sendEvent(this, &e);
+}
+
+bool QETWidget::translateMouseEvent(const MSG &msg)
+{
+ if (!isWindow() && testAttribute(Qt::WA_NativeWindow))
+ Q_ASSERT(internalWinId());
+
+ static QPoint pos;
+ static POINT gpos={-1,-1};
+ QEvent::Type type; // event parameters
+ int button;
+ int state;
+ int i;
+
+ if (sm_blockUserInput) //block user interaction during session management
+ return true;
+
+ // Compress mouse move events
+ if (msg.message == WM_MOUSEMOVE) {
+ MSG mouseMsg;
+ while (PeekMessage(&mouseMsg, msg.hwnd, WM_MOUSEFIRST,
+ WM_MOUSELAST, PM_NOREMOVE)) {
+ if (mouseMsg.message == WM_MOUSEMOVE) {
+#define PEEKMESSAGE_IS_BROKEN 1
+#ifdef PEEKMESSAGE_IS_BROKEN
+ // Since the Windows PeekMessage() function doesn't
+ // correctly return the wParam for WM_MOUSEMOVE events
+ // if there is a key release event in the queue
+ // _before_ the mouse event, we have to also consider
+ // key release events (kls 2003-05-13):
+ MSG keyMsg;
+ bool done = false;
+ while (PeekMessage(&keyMsg, 0, WM_KEYFIRST, WM_KEYLAST,
+ PM_NOREMOVE)) {
+ if (keyMsg.time < mouseMsg.time) {
+ if ((keyMsg.lParam & 0xC0000000) == 0x40000000) {
+ PeekMessage(&keyMsg, 0, keyMsg.message,
+ keyMsg.message, PM_REMOVE);
+ } else {
+ done = true;
+ break;
+ }
+ } else {
+ break; // no key event before the WM_MOUSEMOVE event
+ }
+ }
+ if (done)
+ break;
+#else
+ // Actually the following 'if' should work instead of
+ // the above key event checking, but apparently
+ // PeekMessage() is broken :-(
+ if (mouseMsg.wParam != msg.wParam)
+ break; // leave the message in the queue because
+ // the key state has changed
+#endif
+ MSG *msgPtr = (MSG *)(&msg);
+ // Update the passed in MSG structure with the
+ // most recent one.
+ msgPtr->lParam = mouseMsg.lParam;
+ msgPtr->wParam = mouseMsg.wParam;
+ // Extract the x,y coordinates from the lParam as we do in the WndProc
+ msgPtr->pt.x = GET_X_LPARAM(mouseMsg.lParam);
+ msgPtr->pt.y = GET_Y_LPARAM(mouseMsg.lParam);
+ ClientToScreen(msg.hwnd, &(msgPtr->pt));
+ // Remove the mouse move message
+ PeekMessage(&mouseMsg, msg.hwnd, WM_MOUSEMOVE,
+ WM_MOUSEMOVE, PM_REMOVE);
+ } else {
+ break; // there was no more WM_MOUSEMOVE event
+ }
+ }
+ }
+
+ for (i=0; (UINT)mouseTbl[i] != msg.message && mouseTbl[i]; i += 3)
+ ;
+ if (!mouseTbl[i])
+ return false;
+ type = (QEvent::Type)mouseTbl[++i]; // event type
+ button = mouseTbl[++i]; // which button
+ if (button == Qt::XButton1) {
+ switch(GET_XBUTTON_WPARAM(msg.wParam)) {
+ case XBUTTON1:
+ button = Qt::XButton1;
+ break;
+ case XBUTTON2:
+ button = Qt::XButton2;
+ break;
+ }
+ }
+#ifndef Q_OS_WINCE
+ static bool trackMouseEventLookup = false;
+ typedef BOOL (WINAPI *PtrTrackMouseEvent)(LPTRACKMOUSEEVENT);
+ static PtrTrackMouseEvent ptrTrackMouseEvent = 0;
+#endif
+ state = translateButtonState(msg.wParam, type, button); // button state
+ const QPoint widgetPos = mapFromGlobal(QPoint(msg.pt.x, msg.pt.y));
+ QWidget *alienWidget = !internalWinId() ? this : childAt(widgetPos);
+ if (alienWidget && alienWidget->internalWinId())
+ alienWidget = 0;
+
+ if (type == QEvent::MouseMove || type == QEvent::NonClientAreaMouseMove
+ || type == QEvent::TabletMove) {
+
+ if (!(state & Qt::MouseButtonMask))
+ qt_button_down = 0;
+#ifndef QT_NO_CURSOR
+ QCursor *c = qt_grab_cursor();
+ if (!c)
+ c = QApplication::overrideCursor();
+ if (c) // application cursor defined
+ SetCursor(c->handle());
+ else if (type != QEvent::NonClientAreaMouseMove && !qt_button_down) {
+ // use widget cursor if widget is enabled
+ QWidget *w = alienWidget ? alienWidget : this;
+ while (!w->isWindow() && !w->isEnabled())
+ w = w->parentWidget();
+ SetCursor(w->cursor().handle());
+ }
+#endif // QT_NO_CURSOR
+
+ HWND id = effectiveWinId();
+ QWidget *mouseGrabber = QWidget::mouseGrabber();
+ QWidget *activePopupWidget = QApplication::activePopupWidget();
+ if (mouseGrabber) {
+ if (!activePopupWidget || (activePopupWidget == this && !rect().contains(widgetPos)))
+ id = mouseGrabber->effectiveWinId();
+ } else if (type == QEvent::NonClientAreaMouseMove) {
+ id = 0;
+ }
+
+ if (curWin != id) { // new current window
+ if (id == 0) {
+ QWidget *leave = qt_last_mouse_receiver;
+ if (!leave)
+ leave = QWidget::find(curWin);
+ QApplicationPrivate::dispatchEnterLeave(0, leave);
+ qt_last_mouse_receiver = 0;
+ curWin = 0;
+ } else {
+ QWidget *leave = 0;
+ if (curWin && qt_last_mouse_receiver)
+ leave = qt_last_mouse_receiver;
+ else
+ leave = QWidget::find(curWin);
+ QWidget *enter = alienWidget ? alienWidget : this;
+ if (mouseGrabber && activePopupWidget) {
+ if (leave != mouseGrabber)
+ enter = mouseGrabber;
+ else
+ enter = activePopupWidget == this ? this : mouseGrabber;
+ }
+ QApplicationPrivate::dispatchEnterLeave(enter, leave);
+ qt_last_mouse_receiver = enter;
+ curWin = enter ? enter->effectiveWinId() : 0;
+ }
+#ifndef Q_OS_WINCE
+
+ if (curWin != 0) {
+ if (!trackMouseEventLookup) {
+ trackMouseEventLookup = true;
+ ptrTrackMouseEvent = (PtrTrackMouseEvent)QSystemLibrary::resolve(QLatin1String("comctl32"), "_TrackMouseEvent");
+ }
+ if (ptrTrackMouseEvent && !qApp->d_func()->inPopupMode()) {
+ // We always have to set the tracking, since
+ // Windows detects more leaves than we do..
+ TRACKMOUSEEVENT tme;
+ tme.cbSize = sizeof(TRACKMOUSEEVENT);
+ tme.dwFlags = 0x00000002; // TME_LEAVE
+ tme.hwndTrack = curWin; // Track on window receiving msgs
+ tme.dwHoverTime = (DWORD)-1; // HOVER_DEFAULT
+ ptrTrackMouseEvent(&tme);
+ }
+ }
+#endif // Q_OS_WINCE
+ }
+
+ POINT curPos = msg.pt;
+ if (curPos.x == gpos.x && curPos.y == gpos.y)
+ return true; // same global position
+ gpos = curPos;
+
+ Q_ASSERT(testAttribute(Qt::WA_WState_Created));
+ ScreenToClient(internalWinId(), &curPos);
+
+ pos.rx() = curPos.x;
+ pos.ry() = curPos.y;
+ pos = d_func()->mapFromWS(pos);
+ } else {
+ gpos = msg.pt;
+ pos = mapFromGlobal(QPoint(gpos.x, gpos.y));
+
+ // mouse button pressed
+ if (!qt_button_down && (type == QEvent::MouseButtonPress || type == QEvent::MouseButtonDblClick)) {
+ QWidget *tlw = window();
+ if (QWidget *child = tlw->childAt(mapTo(tlw, pos)))
+ qt_button_down = child;
+ else
+ qt_button_down = this;
+ }
+ }
+
+ bool res = false;
+
+ bool nonClientAreaEvent = type >= QEvent::NonClientAreaMouseMove
+ && type <= QEvent::NonClientAreaMouseButtonDblClick;
+
+ if (qApp->d_func()->inPopupMode()) { // in popup mode
+
+ if (nonClientAreaEvent)
+ return false;
+
+ replayPopupMouseEvent = false;
+ QWidget* activePopupWidget = QApplication::activePopupWidget();
+ QWidget *target = activePopupWidget;
+ const QPoint globalPos(gpos.x, gpos.y);
+
+ if (target != this) {
+ if ((windowType() == Qt::Popup) && rect().contains(pos) && 0)
+ target = this;
+ else // send to last popup
+ pos = target->mapFromGlobal(globalPos);
+ }
+ QWidget *popupChild = target->childAt(pos);
+ bool releaseAfter = false;
+ switch (type) {
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonDblClick:
+ popupButtonFocus = popupChild;
+ break;
+ case QEvent::MouseButtonRelease:
+ case QEvent::TabletRelease:
+
+ releaseAfter = true;
+ break;
+ default:
+ break; // nothing for mouse move
+ }
+
+ if (target->isEnabled()) {
+ if (popupButtonFocus) {
+ target = popupButtonFocus;
+ } else if (popupChild) {
+ target = popupChild;
+ }
+
+ pos = target->mapFromGlobal(globalPos);
+ QMouseEvent e(type, pos, globalPos,
+ Qt::MouseButton(button),
+ Qt::MouseButtons(state & Qt::MouseButtonMask),
+ Qt::KeyboardModifiers(state & Qt::KeyboardModifierMask));
+ res = QApplicationPrivate::sendMouseEvent(target, &e, alienWidget, this, &qt_button_down,
+ qt_last_mouse_receiver);
+ res = res && e.isAccepted();
+ } else {
+ // close disabled popups when a mouse button is pressed or released
+ switch (type) {
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonDblClick:
+ case QEvent::MouseButtonRelease:
+ target->close();
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (releaseAfter) {
+ popupButtonFocus = 0;
+ qt_button_down = 0;
+ }
+
+#ifndef Q_OS_WINCE
+ if (type == QEvent::MouseButtonPress
+ && QApplication::activePopupWidget() != activePopupWidget
+ && ptrTrackMouseEvent
+ && curWin) {
+ // Since curWin is already the window we clicked on,
+ // we have to setup the mouse tracking here.
+ TRACKMOUSEEVENT tme;
+ tme.cbSize = sizeof(TRACKMOUSEEVENT);
+ tme.dwFlags = 0x00000002; // TME_LEAVE
+ tme.hwndTrack = curWin; // Track on window receiving msgs
+ tme.dwHoverTime = (DWORD)-1; // HOVER_DEFAULT
+ ptrTrackMouseEvent(&tme);
+ }
+#endif
+ if (type == QEvent::MouseButtonPress
+ && QApplication::activePopupWidget() != activePopupWidget
+ && replayPopupMouseEvent) {
+ // the popup disappeared. Replay the event
+ QWidget* w = QApplication::widgetAt(gpos.x, gpos.y);
+ if (w && !QApplicationPrivate::isBlockedByModal(w)) {
+ Q_ASSERT(w->testAttribute(Qt::WA_WState_Created));
+ HWND hwndTarget = w->effectiveWinId();
+ if (QWidget::mouseGrabber() == 0)
+ setAutoCapture(hwndTarget);
+ if (!w->isActiveWindow())
+ w->activateWindow();
+ POINT widgetpt = gpos;
+ ScreenToClient(hwndTarget, &widgetpt);
+ LPARAM lParam = MAKELPARAM(widgetpt.x, widgetpt.y);
+ PostMessage(hwndTarget, msg.message, msg.wParam, lParam);
+ }
+ } else if (type == QEvent::MouseButtonRelease && button == Qt::RightButton
+ && QApplication::activePopupWidget() == activePopupWidget) {
+ // popup still alive and received right-button-release
+#if !defined(QT_NO_CONTEXTMENU)
+ QContextMenuEvent e2(QContextMenuEvent::Mouse, pos, globalPos,
+ qt_win_getKeyboardModifiers());
+ bool res2 = QApplication::sendSpontaneousEvent( target, &e2 );
+ if (!res) // RMB not accepted
+ res = res2 && e2.isAccepted();
+#endif
+ }
+ } else { // not popup mode
+ int bs = state & Qt::MouseButtonMask;
+ if ((type == QEvent::MouseButtonPress ||
+ type == QEvent::MouseButtonDblClick) && bs == button) {
+ Q_ASSERT(testAttribute(Qt::WA_WState_Created));
+ if (QWidget::mouseGrabber() == 0)
+ setAutoCapture(internalWinId());
+ } else if (type == QEvent::MouseButtonRelease && bs == 0) {
+ if (QWidget::mouseGrabber() == 0)
+ releaseAutoCapture();
+ }
+
+ const QPoint globalPos(gpos.x,gpos.y);
+ QWidget *widget = QApplicationPrivate::pickMouseReceiver(this, globalPos, pos, type,
+ Qt::MouseButtons(bs),
+ qt_button_down, alienWidget);
+ if (!widget)
+ return false; // don't send event
+
+ QMouseEvent e(type, pos, globalPos, Qt::MouseButton(button),
+ Qt::MouseButtons(state & Qt::MouseButtonMask),
+ Qt::KeyboardModifiers(state & Qt::KeyboardModifierMask));
+
+ res = QApplicationPrivate::sendMouseEvent(widget, &e, alienWidget, this, &qt_button_down,
+ qt_last_mouse_receiver);
+
+ // non client area events are only informational, you cannot "handle" them
+ res = res && e.isAccepted() && !nonClientAreaEvent;
+#if !defined(QT_NO_CONTEXTMENU)
+ if (type == QEvent::MouseButtonRelease && button == Qt::RightButton) {
+ QContextMenuEvent e2(QContextMenuEvent::Mouse, pos, globalPos,
+ qt_win_getKeyboardModifiers());
+ bool res2 = QApplication::sendSpontaneousEvent(widget, &e2);
+ if (!res)
+ res = res2 && e2.isAccepted();
+ }
+#endif
+
+ if (type != QEvent::MouseMove)
+ pos.rx() = pos.ry() = -9999; // init for move compression
+ }
+ return res;
+}
+
+bool QETWidget::translateWheelEvent(const MSG &msg)
+{
+ int state = 0;
+
+ if (sm_blockUserInput) // block user interaction during session management
+ return true;
+
+ state = translateButtonState(GET_KEYSTATE_WPARAM(msg.wParam), 0, 0);
+
+ int delta;
+ if (msg.message == WM_MOUSEWHEEL || msg.message == WM_MOUSEHWHEEL)
+ delta = (short) HIWORD (msg.wParam);
+ else
+ delta = (int) msg.wParam;
+
+ Qt::Orientation orient = (msg.message == WM_MOUSEHWHEEL || state&Qt::AltModifier
+#if 0
+ // disabled for now - Trenton's one-wheel mouse makes trouble...
+ // "delta" for usual wheels is +-120. +-240 seems to indicate
+ // the second wheel see more recent MSDN for WM_MOUSEWHEEL
+
+ ( // <- parantheses added to make update happy, remove if the
+ // #if 0 is removed
+ || delta == 240 || delta == -240)?Qt::Horizontal:Vertical;
+ if (delta == 240 || delta == -240)
+ delta /= 2;
+#endif
+ ) ? Qt::Horizontal : Qt::Vertical;
+
+ // according to the MSDN documentation on WM_MOUSEHWHEEL:
+ // a positive value indicates that the wheel was rotated to the right;
+ // a negative value indicates that the wheel was rotated to the left.
+ // Qt defines this value as the exact opposite, so we have to flip the value!
+ if (msg.message == WM_MOUSEHWHEEL)
+ delta = -delta;
+
+ QPoint globalPos;
+
+ globalPos.rx() = (short)LOWORD (msg.lParam);
+ globalPos.ry() = (short)HIWORD (msg.lParam);
+
+
+ // if there is a widget under the mouse and it is not shadowed
+ // by modality, we send the event to it first
+ int ret = 0;
+ QWidget* w = QApplication::widgetAt(globalPos);
+ if (!w || !qt_try_modal(w, (MSG*)&msg, ret)) {
+ //synaptics touchpad shows its own widget at this position
+ //so widgetAt() will fail with that HWND, try child of this widget
+ w = this->childAt(this->mapFromGlobal(globalPos));
+ if (!w)
+ w = this;
+ }
+
+ // send the event to the widget or its ancestors
+ {
+ QWidget* popup = QApplication::activePopupWidget();
+ if (popup && w->window() != popup)
+ popup->close();
+#ifndef QT_NO_WHEELEVENT
+ QWheelEvent e(w->mapFromGlobal(globalPos), globalPos, delta,
+ Qt::MouseButtons(state & Qt::MouseButtonMask),
+ Qt::KeyboardModifier(state & Qt::KeyboardModifierMask), orient);
+
+ if (QApplication::sendSpontaneousEvent(w, &e))
+#else
+ Q_UNUSED(orient);
+#endif //QT_NO_WHEELEVENT
+ return true;
+ }
+
+ // send the event to the widget that has the focus or its ancestors, if different
+ if (w != QApplication::focusWidget() && (w = QApplication::focusWidget())) {
+ QWidget* popup = QApplication::activePopupWidget();
+ if (popup && w->window() != popup)
+ popup->close();
+#ifndef QT_NO_WHEELEVENT
+ QWheelEvent e(w->mapFromGlobal(globalPos), globalPos, delta,
+ Qt::MouseButtons(state & Qt::MouseButtonMask),
+ Qt::KeyboardModifier(state & Qt::KeyboardModifierMask), orient);
+ if (QApplication::sendSpontaneousEvent(w, &e))
+#endif //QT_NO_WHEELEVENT
+ return true;
+ }
+ return false;
+}
+
+
+//
+// Windows Wintab to QTabletEvent translation
+//
+
+// the following is adapted from the wintab syspress example (public domain)
+/* -------------------------------------------------------------------------- */
+// Initialize the "static" information of a cursor device (pen, airbrush, etc).
+// The QTabletDeviceData is initialized with the data that do not change in time
+// (number of button, type of device, etc) but do not initialize the variable data
+// (e.g.: pen or eraser)
+#ifndef QT_NO_TABLETEVENT
+
+static void tabletInit(const quint64 uniqueId, const UINT csr_type, HCTX hTab)
+{
+ Q_ASSERT(ptrWTInfo);
+ Q_ASSERT(ptrWTGet);
+
+ Q_ASSERT(!tCursorInfo()->contains(uniqueId));
+
+ /* browse WinTab's many info items to discover pressure handling. */
+ AXIS np;
+ LOGCONTEXT lc;
+
+ /* get the current context for its device variable. */
+ ptrWTGet(hTab, &lc);
+
+ /* get the size of the pressure axis. */
+ QTabletDeviceData tdd;
+ tdd.llId = uniqueId;
+
+ ptrWTInfo(WTI_DEVICES + lc.lcDevice, DVC_NPRESSURE, &np);
+ tdd.minPressure = int(np.axMin);
+ tdd.maxPressure = int(np.axMax);
+
+ ptrWTInfo(WTI_DEVICES + lc.lcDevice, DVC_TPRESSURE, &np);
+ tdd.minTanPressure = int(np.axMin);
+ tdd.maxTanPressure = int(np.axMax);
+
+ LOGCONTEXT lcMine;
+
+ /* get default region */
+ ptrWTInfo(WTI_DEFCONTEXT, 0, &lcMine);
+
+ tdd.minX = 0;
+ tdd.maxX = int(lcMine.lcInExtX) - int(lcMine.lcInOrgX);
+
+ tdd.minY = 0;
+ tdd.maxY = int(lcMine.lcInExtY) - int(lcMine.lcInOrgY);
+
+ tdd.minZ = 0;
+ tdd.maxZ = int(lcMine.lcInExtZ) - int(lcMine.lcInOrgZ);
+
+ const uint cursorTypeBitMask = 0x0F06; // bitmask to find the specific cursor type (see Wacom FAQ)
+ if (((csr_type & 0x0006) == 0x0002) && ((csr_type & cursorTypeBitMask) != 0x0902)) {
+ tdd.currentDevice = QTabletEvent::Stylus;
+ } else {
+ switch (csr_type & cursorTypeBitMask) {
+ case 0x0802:
+ tdd.currentDevice = QTabletEvent::Stylus;
+ break;
+ case 0x0902:
+ tdd.currentDevice = QTabletEvent::Airbrush;
+ break;
+ case 0x0004:
+ tdd.currentDevice = QTabletEvent::FourDMouse;
+ break;
+ case 0x0006:
+ tdd.currentDevice = QTabletEvent::Puck;
+ break;
+ case 0x0804:
+ tdd.currentDevice = QTabletEvent::RotationStylus;
+ break;
+ default:
+ tdd.currentDevice = QTabletEvent::NoDevice;
+ }
+ }
+ tCursorInfo()->insert(uniqueId, tdd);
+}
+#endif // QT_NO_TABLETEVENT
+
+// Update the "dynamic" information of a cursor device (pen, airbrush, etc).
+// The dynamic information is the information of QTabletDeviceData that can change
+// in time (eraser or pen if a device is turned around).
+#ifndef QT_NO_TABLETEVENT
+
+static void tabletUpdateCursor(QTabletDeviceData &tdd, const UINT currentCursor)
+{
+ switch (currentCursor % 3) { // %3 for dual track
+ case 0:
+ tdd.currentPointerType = QTabletEvent::Cursor;
+ break;
+ case 1:
+ tdd.currentPointerType = QTabletEvent::Pen;
+ break;
+ case 2:
+ tdd.currentPointerType = QTabletEvent::Eraser;
+ break;
+ default:
+ tdd.currentPointerType = QTabletEvent::UnknownPointer;
+ }
+}
+#endif // QT_NO_TABLETEVENT
+
+bool QETWidget::translateTabletEvent(const MSG &msg, PACKET *localPacketBuf,
+ int numPackets)
+{
+ Q_UNUSED(msg);
+ POINT ptNew;
+ static DWORD btnNew, btnOld, btnChange;
+ qreal prsNew;
+ ORIENTATION ort;
+ static bool button_pressed = false;
+ int i,
+ tiltX,
+ tiltY;
+ bool sendEvent = false;
+ QEvent::Type t;
+ int z = 0;
+ qreal rotation = 0.0;
+ qreal tangentialPressure;
+
+ // the most common event that we get...
+ t = QEvent::TabletMove;
+ for (i = 0; i < numPackets; i++) {
+ // get the unique ID of the device...
+ btnOld = btnNew;
+ btnNew = localPacketBuf[i].pkButtons;
+ btnChange = btnOld ^ btnNew;
+
+ if (btnNew & btnChange) {
+ button_pressed = true;
+ t = QEvent::TabletPress;
+ }
+ ptNew.x = UINT(localPacketBuf[i].pkX);
+ ptNew.y = UINT(localPacketBuf[i].pkY);
+#ifndef QT_NO_TABLETEVENT
+ z = (currentTabletPointer.currentDevice == QTabletEvent::FourDMouse) ? UINT(localPacketBuf[i].pkZ) : 0;
+#else
+ Q_UNUSED(z);
+#endif // QT_NO_TABLETEVENT
+ prsNew = 0.0;
+ QRect desktopArea = QApplication::desktop()->geometry();
+ QPointF hiResGlobal = currentTabletPointer.scaleCoord(ptNew.x, ptNew.y, desktopArea.left(),
+ desktopArea.width(), desktopArea.top(),
+ desktopArea.height());
+
+ if (btnNew) {
+#ifndef QT_NO_TABLETEVENT
+ if (currentTabletPointer.currentPointerType == QTabletEvent::Pen || currentTabletPointer.currentPointerType == QTabletEvent::Eraser)
+ prsNew = localPacketBuf[i].pkNormalPressure
+ / qreal(currentTabletPointer.maxPressure
+ - currentTabletPointer.minPressure);
+ else
+#endif // QT_NO_TABLETEVENT
+ prsNew = 0;
+ } else if (button_pressed) {
+ // One button press, should only give one button release
+ t = QEvent::TabletRelease;
+ button_pressed = false;
+ }
+ QPoint globalPos(qRound(hiResGlobal.x()), qRound(hiResGlobal.y()));
+
+ if (t == QEvent::TabletPress)
+ {
+ qt_button_down = QApplication::widgetAt(globalPos);
+ }
+
+ // make sure the tablet event get's sent to the proper widget...
+ QWidget *w = 0;
+
+ if (qt_button_down)
+ w = qt_button_down; // Pass it to the thing that's grabbed it.
+ else
+ w = QApplication::widgetAt(globalPos);
+
+ if (!w)
+ w = this;
+
+ if (t == QEvent::TabletRelease)
+ {
+ if (qt_win_ignoreNextMouseReleaseEvent) {
+ qt_win_ignoreNextMouseReleaseEvent = false;
+ if (qt_button_down && qt_button_down->internalWinId() == autoCaptureWnd) {
+ releaseAutoCapture();
+ qt_button_down = 0;
+ }
+ }
+
+ }
+
+ QPoint localPos = w->mapFromGlobal(globalPos);
+#ifndef QT_NO_TABLETEVENT
+ if (currentTabletPointer.currentDevice == QTabletEvent::Airbrush) {
+ tangentialPressure = localPacketBuf[i].pkTangentPressure
+ / qreal(currentTabletPointer.maxTanPressure
+ - currentTabletPointer.minTanPressure);
+ } else {
+ tangentialPressure = 0.0;
+ }
+#else
+ tangentialPressure = 0.0;
+#endif // QT_NO_TABLETEVENT
+
+ if (!qt_tablet_tilt_support) {
+ tiltX = tiltY = 0;
+ rotation = 0.0;
+ } else {
+ ort = localPacketBuf[i].pkOrientation;
+ // convert from azimuth and altitude to x tilt and y tilt
+ // what follows is the optimized version. Here are the equations
+ // I used to get to this point (in case things change :)
+ // X = sin(azimuth) * cos(altitude)
+ // Y = cos(azimuth) * cos(altitude)
+ // Z = sin(altitude)
+ // X Tilt = arctan(X / Z)
+ // Y Tilt = arctan(Y / Z)
+ double radAzim = (ort.orAzimuth / 10) * (Q_PI / 180);
+ //double radAlt = abs(ort.orAltitude / 10) * (Q_PI / 180);
+ double tanAlt = tan((abs(ort.orAltitude / 10)) * (Q_PI / 180));
+
+ double degX = atan(sin(radAzim) / tanAlt);
+ double degY = atan(cos(radAzim) / tanAlt);
+ tiltX = int(degX * (180 / Q_PI));
+ tiltY = int(-degY * (180 / Q_PI));
+ rotation = ort.orTwist;
+ }
+#ifndef QT_NO_TABLETEVENT
+ QTabletEvent e(t, localPos, globalPos, hiResGlobal, currentTabletPointer.currentDevice,
+ currentTabletPointer.currentPointerType, prsNew, tiltX, tiltY,
+ tangentialPressure, rotation, z, QApplication::keyboardModifiers(), currentTabletPointer.llId);
+ sendEvent = QApplication::sendSpontaneousEvent(w, &e);
+#endif // QT_NO_TABLETEVENT
+ }
+ return sendEvent;
+}
+
+extern bool qt_is_gui_used;
+
+
+#ifndef QT_NO_TABLETEVENT
+
+static void initWinTabFunctions()
+{
+#if defined(Q_OS_WINCE)
+ return;
+#else
+ if (!qt_is_gui_used)
+ return;
+
+ QSystemLibrary library(QLatin1String("wintab32"));
+ ptrWTInfo = (PtrWTInfo)library.resolve("WTInfoW");
+ ptrWTGet = (PtrWTGet)library.resolve("WTGetW");
+ ptrWTEnable = (PtrWTEnable)library.resolve("WTEnable");
+ ptrWTOverlap = (PtrWTEnable)library.resolve("WTOverlap");
+ ptrWTPacketsGet = (PtrWTPacketsGet)library.resolve("WTPacketsGet");
+#endif // Q_OS_WINCE
+}
+#endif // QT_NO_TABLETEVENT
+
+
+//
+// Paint event translation
+//
+bool QETWidget::translatePaintEvent(const MSG &msg)
+{
+ if (!isWindow() && testAttribute(Qt::WA_NativeWindow))
+ Q_ASSERT(internalWinId());
+
+ Q_ASSERT(testAttribute(Qt::WA_WState_Created));
+ if (!GetUpdateRect(internalWinId(), 0, FALSE)) { // The update bounding rect is invalid
+ d_func()->hd = 0;
+ setAttribute(Qt::WA_PendingUpdate, false);
+ return false;
+ }
+
+ if (msg.message == WM_ERASEBKGND)
+ return true;
+
+ setAttribute(Qt::WA_PendingUpdate, false);
+
+ if (d_func()->isGLWidget) {
+ if (d_func()->usesDoubleBufferedGLContext)
+ InvalidateRect(internalWinId(), 0, false);
+ } else {
+ const QRegion dirtyInBackingStore(qt_dirtyRegion(this));
+ // Make sure the invalidated region contains the region we're about to repaint.
+ // BeginPaint will set the clip to the invalidated region and it is impossible
+ // to enlarge it afterwards (only shrink it). Using GetDCEx is not suffient
+ // as it may return an invalid context (especially on Windows Vista).
+ if (!dirtyInBackingStore.isEmpty())
+ InvalidateRgn(internalWinId(), dirtyInBackingStore.handle(), false);
+ }
+ PAINTSTRUCT ps;
+ d_func()->hd = BeginPaint(internalWinId(), &ps);
+
+ const QRect updateRect(QPoint(ps.rcPaint.left, ps.rcPaint.top),
+ QPoint(ps.rcPaint.right, ps.rcPaint.bottom));
+
+ // Mapping region from system to qt (32 bit) coordinate system.
+ d_func()->syncBackingStore(updateRect.translated(data->wrect.topLeft()));
+
+ d_func()->hd = 0;
+ EndPaint(internalWinId(), &ps);
+
+ return true;
+}
+
+//
+// Window move and resize (configure) events
+//
+
+bool QETWidget::translateConfigEvent(const MSG &msg)
+{
+ if (!testAttribute(Qt::WA_WState_Created)) // in QWidget::create()
+ return true;
+ if (testAttribute(Qt::WA_WState_ConfigPending))
+ return true;
+ if (testAttribute(Qt::WA_DontShowOnScreen))
+ return true;
+ if (!isWindow())
+ return true;
+ setAttribute(Qt::WA_WState_ConfigPending); // set config flag
+ QRect cr = geometry();
+ if (msg.message == WM_SIZE) { // resize event
+ WORD a = LOWORD(msg.lParam);
+ WORD b = HIWORD(msg.lParam);
+ QSize oldSize = size();
+ QSize newSize(a, b);
+#ifdef Q_WS_WINCE_WM
+ if (isFullScreen() && (oldSize.width() == newSize.height()) && (oldSize.height() == newSize.width()))
+ qt_wince_hide_taskbar(internalWinId());
+#endif
+ cr.setSize(newSize);
+ if (msg.wParam != SIZE_MINIMIZED)
+ data->crect = cr;
+ if (isWindow()) { // update title/icon text
+ d_func()->createTLExtra();
+ // Capture SIZE_MINIMIZED without preceding WM_SYSCOMMAND
+ // (like Windows+M)
+ if (msg.wParam == SIZE_MINIMIZED && !isMinimized()) {
+#ifndef Q_WS_WINCE
+ const QString title = windowIconText();
+ if (!title.isEmpty())
+ d_func()->setWindowTitle_helper(title);
+#endif
+ data->window_state |= Qt::WindowMinimized;
+ if (isVisible()) {
+ QHideEvent e;
+ QApplication::sendSpontaneousEvent(this, &e);
+ hideChildren(true);
+ }
+ } else if (msg.wParam != SIZE_MINIMIZED) {
+ bool window_state_changed = false;
+ Qt::WindowStates oldstate = Qt::WindowStates(dataPtr()->window_state);
+ if (isMinimized()) {
+#ifndef Q_WS_WINCE
+ const QString title = windowTitle();
+ if (!title.isEmpty())
+ d_func()->setWindowTitle_helper(title);
+#endif
+ data->window_state &= ~Qt::WindowMinimized;
+ showChildren(true);
+ QShowEvent e;
+ QApplication::sendSpontaneousEvent(this, &e);
+ // Capture SIZE_MAXIMIZED and SIZE_RESTORED without preceding WM_SYSCOMMAND
+ // (Aero Snap on Win7)
+ } else if (msg.wParam == SIZE_MAXIMIZED && !isMaximized()) {
+ data->window_state |= Qt::WindowMaximized;
+ window_state_changed = true;
+ } else if (msg.wParam == SIZE_RESTORED && isMaximized()) {
+ data->window_state &= ~(Qt::WindowMaximized);
+ window_state_changed = true;
+ }
+ if (window_state_changed) {
+ QWindowStateChangeEvent e(oldstate);
+ QApplication::sendSpontaneousEvent(this, &e);
+ }
+ }
+ }
+ if (msg.wParam != SIZE_MINIMIZED && oldSize != newSize) {
+ if (isVisible()) {
+ QTLWExtra *tlwExtra = maybeTopData();
+ static bool slowResize = qgetenv("QT_SLOW_TOPLEVEL_RESIZE").toInt();
+ const bool hasStaticContents = tlwExtra && tlwExtra->backingStore
+ && tlwExtra->backingStore->hasStaticContents();
+ // If we have a backing store with static contents, we have to disable the top-level
+ // resize optimization in order to get invalidated regions for resized widgets.
+ // The optimization discards all invalidateBuffer() calls since we're going to
+ // repaint everything anyways, but that's not the case with static contents.
+ if (!slowResize && tlwExtra && !hasStaticContents)
+ tlwExtra->inTopLevelResize = true;
+ QResizeEvent e(newSize, oldSize);
+ QApplication::sendSpontaneousEvent(this, &e);
+ if (d_func()->paintOnScreen()) {
+ QRegion updateRegion(rect());
+ if (testAttribute(Qt::WA_StaticContents))
+ updateRegion -= QRect(0, 0, oldSize.width(), oldSize.height());
+ d_func()->syncBackingStore(updateRegion);
+ } else {
+ d_func()->syncBackingStore();
+ }
+ if (!slowResize && tlwExtra)
+ tlwExtra->inTopLevelResize = false;
+ } else {
+ QResizeEvent *e = new QResizeEvent(newSize, oldSize);
+ QApplication::postEvent(this, e);
+ }
+ }
+ } else if (msg.message == WM_MOVE) { // move event
+ int a = (int) (short) LOWORD(msg.lParam);
+ int b = (int) (short) HIWORD(msg.lParam);
+ QPoint oldPos = geometry().topLeft();
+ QPoint newCPos(a, b);
+ // Ignore silly Windows move event to wild pos after iconify.
+#if !defined(Q_WS_WINCE)
+ if (!IsIconic(internalWinId()) && newCPos != oldPos) {
+#endif
+ cr.moveTopLeft(newCPos);
+ data->crect = cr;
+ if (isVisible()) {
+ QMoveEvent e(newCPos, oldPos); // cpos (client position)
+ QApplication::sendSpontaneousEvent(this, &e);
+ } else {
+ QMoveEvent * e = new QMoveEvent(newCPos, oldPos);
+ QApplication::postEvent(this, e);
+ }
+#if !defined(Q_WS_WINCE)
+ }
+#endif
+ }
+ setAttribute(Qt::WA_WState_ConfigPending, false); // clear config flag
+ return true;
+}
+
+
+//
+// Close window event translation.
+//
+// This class is a friend of QApplication because it needs to emit the
+// lastWindowClosed() signal when the last top level widget is closed.
+//
+
+bool QETWidget::translateCloseEvent(const MSG &)
+{
+ return d_func()->close_helper(QWidgetPrivate::CloseWithSpontaneousEvent);
+}
+
+#ifndef QT_NO_GESTURES
+bool QETWidget::translateGestureEvent(const MSG &, const GESTUREINFO &gi)
+{
+ const QPoint widgetPos = QPoint(gi.ptsLocation.x, gi.ptsLocation.y);
+ QWidget *alienWidget = !internalWinId() ? this : childAt(widgetPos);
+ if (alienWidget && alienWidget->internalWinId())
+ alienWidget = 0;
+ QWidget *widget = alienWidget ? alienWidget : this;
+
+ QNativeGestureEvent event;
+ event.sequenceId = gi.dwSequenceID;
+ event.position = QPoint(gi.ptsLocation.x, gi.ptsLocation.y);
+ event.argument = gi.ullArguments;
+
+ switch (gi.dwID) {
+ case GID_BEGIN:
+ event.gestureType = QNativeGestureEvent::GestureBegin;
+ break;
+ case GID_END:
+ event.gestureType = QNativeGestureEvent::GestureEnd;
+ break;
+ case GID_ZOOM:
+ event.gestureType = QNativeGestureEvent::Zoom;
+ break;
+ case GID_PAN:
+ event.gestureType = QNativeGestureEvent::Pan;
+ break;
+ case GID_ROTATE:
+ event.gestureType = QNativeGestureEvent::Rotate;
+ break;
+ case GID_TWOFINGERTAP:
+ case GID_ROLLOVER:
+ default:
+ break;
+ }
+ if (event.gestureType != QNativeGestureEvent::None)
+ qt_sendSpontaneousEvent(widget, &event);
+ return true;
+}
+#endif // QT_NO_GESTURES
+
+void QApplication::setCursorFlashTime(int msecs)
+{
+ SetCaretBlinkTime(msecs / 2);
+ QApplicationPrivate::cursor_flash_time = msecs;
+}
+
+
+int QApplication::cursorFlashTime()
+{
+ int blink = (int)GetCaretBlinkTime();
+ if (!blink)
+ return QApplicationPrivate::cursor_flash_time;
+ if (blink > 0)
+ return 2*blink;
+ return 0;
+}
+
+
+void QApplication::setDoubleClickInterval(int ms)
+{
+#ifndef Q_WS_WINCE
+ SetDoubleClickTime(ms);
+#endif
+ QApplicationPrivate::mouse_double_click_time = ms;
+}
+
+int QApplication::doubleClickInterval()
+{
+ int ms = GetDoubleClickTime();
+ if (ms != 0)
+ return ms;
+ return QApplicationPrivate::mouse_double_click_time;
+}
+
+
+void QApplication::setKeyboardInputInterval(int ms)
+{
+ QApplicationPrivate::keyboard_input_time = ms;
+}
+
+int QApplication::keyboardInputInterval()
+{
+ // FIXME: get from the system
+ return QApplicationPrivate::keyboard_input_time;
+}
+
+#ifndef QT_NO_WHEELEVENT
+void QApplication::setWheelScrollLines(int n)
+{
+#ifdef SPI_SETWHEELSCROLLLINES
+ if (n < 0)
+ n = 0;
+ SystemParametersInfo(SPI_SETWHEELSCROLLLINES, (uint)n, 0, 0);
+#else
+ QApplicationPrivate::wheel_scroll_lines = n;
+#endif
+}
+
+int QApplication::wheelScrollLines()
+{
+#ifdef SPI_GETWHEELSCROLLLINES
+ uint i = 3;
+ SystemParametersInfo(SPI_GETWHEELSCROLLLINES, sizeof(uint), &i, 0);
+ if (i > INT_MAX)
+ i = INT_MAX;
+ return i;
+#else
+ return QApplicationPrivate::wheel_scroll_lines;
+#endif
+}
+#endif //QT_NO_WHEELEVENT
+
+static bool effect_override = false;
+
+void QApplication::setEffectEnabled(Qt::UIEffect effect, bool enable)
+{
+ effect_override = true;
+ switch (effect) {
+ case Qt::UI_AnimateMenu:
+ QApplicationPrivate::animate_menu = enable;
+ break;
+ case Qt::UI_FadeMenu:
+ QApplicationPrivate::fade_menu = enable;
+ break;
+ case Qt::UI_AnimateCombo:
+ QApplicationPrivate::animate_combo = enable;
+ break;
+ case Qt::UI_AnimateTooltip:
+ QApplicationPrivate::animate_tooltip = enable;
+ break;
+ case Qt::UI_FadeTooltip:
+ QApplicationPrivate::fade_tooltip = enable;
+ break;
+ case Qt::UI_AnimateToolBox:
+ QApplicationPrivate::animate_toolbox = enable;
+ break;
+ default:
+ QApplicationPrivate::animate_ui = enable;
+ break;
+ }
+}
+
+bool QApplication::isEffectEnabled(Qt::UIEffect effect)
+{
+ if (QColormap::instance().depth() < 16)
+ return false;
+
+ if (!effect_override && desktopSettingsAware()) {
+ // we know that they can be used when we are here
+ BOOL enabled = false;
+ UINT api;
+ switch (effect) {
+ case Qt::UI_AnimateMenu:
+ api = SPI_GETMENUANIMATION;
+ break;
+ case Qt::UI_FadeMenu:
+ api = SPI_GETMENUFADE;
+ break;
+ case Qt::UI_AnimateCombo:
+ api = SPI_GETCOMBOBOXANIMATION;
+ break;
+ case Qt::UI_AnimateTooltip:
+ api = SPI_GETTOOLTIPANIMATION;
+ break;
+ case Qt::UI_FadeTooltip:
+ api = SPI_GETTOOLTIPFADE;
+ break;
+ default:
+ api = SPI_GETUIEFFECTS;
+ break;
+ }
+ SystemParametersInfo(api, 0, &enabled, 0);
+ return enabled;
+ }
+
+ switch(effect) {
+ case Qt::UI_AnimateMenu:
+ return QApplicationPrivate::animate_menu;
+ case Qt::UI_FadeMenu:
+ return QApplicationPrivate::fade_menu;
+ case Qt::UI_AnimateCombo:
+ return QApplicationPrivate::animate_combo;
+ case Qt::UI_AnimateTooltip:
+ return QApplicationPrivate::animate_tooltip;
+ case Qt::UI_FadeTooltip:
+ return QApplicationPrivate::fade_tooltip;
+ case Qt::UI_AnimateToolBox:
+ return QApplicationPrivate::animate_toolbox;
+ default:
+ return QApplicationPrivate::animate_ui;
+ }
+}
+
+#ifndef QT_NO_SESSIONMANAGER
+
+bool QSessionManager::allowsInteraction()
+{
+ sm_blockUserInput = false;
+ return true;
+}
+
+bool QSessionManager::allowsErrorInteraction()
+{
+ sm_blockUserInput = false;
+ return true;
+}
+
+void QSessionManager::release()
+{
+ if (sm_smActive)
+ sm_blockUserInput = true;
+}
+
+void QSessionManager::cancel()
+{
+ sm_cancel = true;
+}
+
+#endif //QT_NO_SESSIONMANAGER
+
+
+bool QApplicationPrivate::HasTouchSupport = false;
+PtrRegisterTouchWindow QApplicationPrivate::RegisterTouchWindow = 0;
+PtrGetTouchInputInfo QApplicationPrivate::GetTouchInputInfo = 0;
+PtrCloseTouchInputHandle QApplicationPrivate::CloseTouchInputHandle = 0;
+
+void QApplicationPrivate::initializeMultitouch_sys()
+{
+ if (QSysInfo::windowsVersion() >= QSysInfo::WV_WINDOWS7) {
+ static const int QT_SM_DIGITIZER = 94;
+ int value = GetSystemMetrics(QT_SM_DIGITIZER);
+ static const int QT_NID_INTEGRATED_TOUCH = 0x01;
+ static const int QT_NID_EXTERNAL_TOUCH = 0x02;
+ static const int QT_NID_MULTI_INPUT = 0x40;
+ QApplicationPrivate::HasTouchSupport =
+ value & (QT_NID_INTEGRATED_TOUCH | QT_NID_EXTERNAL_TOUCH | QT_NID_MULTI_INPUT);
+ }
+
+ QSystemLibrary library(QLatin1String("user32"));
+ // MinGW (g++ 3.4.5) accepts only C casts.
+ RegisterTouchWindow = (PtrRegisterTouchWindow)(library.resolve("RegisterTouchWindow"));
+ GetTouchInputInfo = (PtrGetTouchInputInfo)(library.resolve("GetTouchInputInfo"));
+ CloseTouchInputHandle = (PtrCloseTouchInputHandle)(library.resolve("CloseTouchInputHandle"));
+
+ touchInputIDToTouchPointID.clear();
+}
+
+void QApplicationPrivate::cleanupMultitouch_sys()
+{
+ touchInputIDToTouchPointID.clear();
+}
+
+bool QApplicationPrivate::translateTouchEvent(const MSG &msg)
+{
+ QWidget *widgetForHwnd = QWidget::find(msg.hwnd);
+ if (!widgetForHwnd)
+ return false;
+
+ QRect screenGeometry = QApplication::desktop()->screenGeometry(widgetForHwnd);
+
+ QList<QTouchEvent::TouchPoint> touchPoints;
+
+ QVector<TOUCHINPUT> winTouchInputs(msg.wParam);
+ memset(winTouchInputs.data(), 0, sizeof(TOUCHINPUT) * winTouchInputs.count());
+ Qt::TouchPointStates allStates = 0;
+ QApplicationPrivate::GetTouchInputInfo((HANDLE) msg.lParam, msg.wParam, winTouchInputs.data(), sizeof(TOUCHINPUT));
+ for (int i = 0; i < winTouchInputs.count(); ++i) {
+ const TOUCHINPUT &touchInput = winTouchInputs.at(i);
+
+ int touchPointID = touchInputIDToTouchPointID.value(touchInput.dwID, -1);
+ if (touchPointID == -1) {
+ touchPointID = touchInputIDToTouchPointID.count();
+ touchInputIDToTouchPointID.insert(touchInput.dwID, touchPointID);
+ }
+
+ QTouchEvent::TouchPoint touchPoint(touchPointID);
+
+ // update state
+ QPointF screenPos(qreal(touchInput.x) / qreal(100.), qreal(touchInput.y) / qreal(100.));
+ QRectF screenRect;
+ if (touchInput.dwMask & TOUCHINPUTMASKF_CONTACTAREA)
+ screenRect.setSize(QSizeF(qreal(touchInput.cxContact) / qreal(100.),
+ qreal(touchInput.cyContact) / qreal(100.)));
+ screenRect.moveCenter(screenPos);
+
+ Qt::TouchPointStates state;
+ if (touchInput.dwFlags & TOUCHEVENTF_DOWN) {
+ state = Qt::TouchPointPressed;
+ } else if (touchInput.dwFlags & TOUCHEVENTF_UP) {
+ state = Qt::TouchPointReleased;
+ } else {
+ state = (screenPos == touchPoint.screenPos()
+ ? Qt::TouchPointStationary
+ : Qt::TouchPointMoved);
+ }
+ if (touchInput.dwFlags & TOUCHEVENTF_PRIMARY)
+ state |= Qt::TouchPointPrimary;
+ touchPoint.setState(state);
+ touchPoint.setScreenRect(screenRect);
+ touchPoint.setNormalizedPos(QPointF(screenPos.x() / screenGeometry.width(),
+ screenPos.y() / screenGeometry.height()));
+
+ allStates |= state;
+
+ touchPoints.append(touchPoint);
+ }
+ QApplicationPrivate::CloseTouchInputHandle((HANDLE) msg.lParam);
+
+ if ((allStates & Qt::TouchPointStateMask) == Qt::TouchPointReleased) {
+ // all touch points released, forget the ids we've seen, they may not be reused
+ touchInputIDToTouchPointID.clear();
+ }
+
+ translateRawTouchEvent(widgetForHwnd, QTouchEvent::TouchScreen, touchPoints);
+ return true;
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/kernel/qclipboard_win.cpp b/src/widgets/platforms/win/qclipboard_win.cpp
index 841eea1e34..841eea1e34 100644
--- a/src/gui/kernel/qclipboard_win.cpp
+++ b/src/widgets/platforms/win/qclipboard_win.cpp
diff --git a/src/gui/painting/qcolormap_win.cpp b/src/widgets/platforms/win/qcolormap_win.cpp
index 4a95977438..4a95977438 100644
--- a/src/gui/painting/qcolormap_win.cpp
+++ b/src/widgets/platforms/win/qcolormap_win.cpp
diff --git a/src/gui/kernel/qcursor_win.cpp b/src/widgets/platforms/win/qcursor_win.cpp
index cef83f5a1b..cef83f5a1b 100644
--- a/src/gui/kernel/qcursor_win.cpp
+++ b/src/widgets/platforms/win/qcursor_win.cpp
diff --git a/src/gui/kernel/qdesktopwidget_win.cpp b/src/widgets/platforms/win/qdesktopwidget_win.cpp
index f77cc1f847..f77cc1f847 100644
--- a/src/gui/kernel/qdesktopwidget_win.cpp
+++ b/src/widgets/platforms/win/qdesktopwidget_win.cpp
diff --git a/src/gui/kernel/qdnd_win.cpp b/src/widgets/platforms/win/qdnd_win.cpp
index 073937fc45..073937fc45 100644
--- a/src/gui/kernel/qdnd_win.cpp
+++ b/src/widgets/platforms/win/qdnd_win.cpp
diff --git a/src/gui/text/qfont_win.cpp b/src/widgets/platforms/win/qfont_win.cpp
index 7a0f234ca6..7a0f234ca6 100644
--- a/src/gui/text/qfont_win.cpp
+++ b/src/widgets/platforms/win/qfont_win.cpp
diff --git a/src/gui/text/qfontdatabase_win.cpp b/src/widgets/platforms/win/qfontdatabase_win.cpp
index 788eb307c3..788eb307c3 100644
--- a/src/gui/text/qfontdatabase_win.cpp
+++ b/src/widgets/platforms/win/qfontdatabase_win.cpp
diff --git a/src/gui/text/qfontengine_win.cpp b/src/widgets/platforms/win/qfontengine_win.cpp
index fc11387367..fc11387367 100644
--- a/src/gui/text/qfontengine_win.cpp
+++ b/src/widgets/platforms/win/qfontengine_win.cpp
diff --git a/src/gui/text/qfontengine_win_p.h b/src/widgets/platforms/win/qfontengine_win_p.h
index ebcafffceb..ebcafffceb 100644
--- a/src/gui/text/qfontengine_win_p.h
+++ b/src/widgets/platforms/win/qfontengine_win_p.h
diff --git a/src/gui/kernel/qguifunctions_wince.cpp b/src/widgets/platforms/win/qguifunctions_wince.cpp
index 78dc469b88..78dc469b88 100644
--- a/src/gui/kernel/qguifunctions_wince.cpp
+++ b/src/widgets/platforms/win/qguifunctions_wince.cpp
diff --git a/src/gui/kernel/qguifunctions_wince.h b/src/widgets/platforms/win/qguifunctions_wince.h
index 6384e4ac62..6384e4ac62 100644
--- a/src/gui/kernel/qguifunctions_wince.h
+++ b/src/widgets/platforms/win/qguifunctions_wince.h
diff --git a/src/widgets/platforms/win/qkeymapper_win.cpp b/src/widgets/platforms/win/qkeymapper_win.cpp
new file mode 100644
index 0000000000..78389c1160
--- /dev/null
+++ b/src/widgets/platforms/win/qkeymapper_win.cpp
@@ -0,0 +1,1207 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qkeymapper_p.h"
+
+#include <qt_windows.h>
+#include <qdebug.h>
+#include <private/qevent_p.h>
+#include <private/qlocale_p.h>
+#include <private/qapplication_p.h>
+#include <qwidget.h>
+#include <qapplication.h>
+#include <ctype.h>
+
+QT_BEGIN_NAMESPACE
+
+// Uncommend, to show debugging information for the keymapper
+//#define DEBUG_KEYMAPPER
+
+// Implemented elsewhere
+extern "C" LRESULT QT_WIN_CALLBACK QtWndProc(HWND, UINT, WPARAM, LPARAM);
+
+extern Q_CORE_EXPORT QLocale qt_localeFromLCID(LCID id);
+#ifndef LANG_PASHTO
+#define LANG_PASHTO 0x63
+#endif
+#ifndef LANG_SYRIAC
+#define LANG_SYRIAC 0x5a
+#endif
+#ifndef LANG_DIVEHI
+#define LANG_DIVEHI 0x65
+#endif
+#ifndef VK_OEM_PLUS
+#define VK_OEM_PLUS 0xBB
+#endif
+#ifndef VK_OEM_3
+#define VK_OEM_3 0xC0
+#endif
+
+#if defined(Q_OS_WINCE)
+bool GetKeyboardState(unsigned char* kbuffer)
+{
+ for (int i=0; i< 256; ++i)
+ kbuffer[i] = GetAsyncKeyState(i);
+ return true;
+}
+#endif
+// Key recorder ------------------------------------------------------------------------[ start ] --
+struct KeyRecord {
+ KeyRecord(int c, int a, int s, const QString &t) : code(c), ascii(a), state(s), text(t) {}
+ KeyRecord() {}
+
+ int code;
+ int ascii;
+ int state;
+ QString text;
+};
+
+static const int QT_MAX_KEY_RECORDINGS = 64; // User has LOTS of fingers...
+struct KeyRecorder
+{
+ KeyRecorder() : nrecs(0) {}
+
+ inline KeyRecord *findKey(int code, bool remove);
+ inline void storeKey(int code, int ascii, int state, const QString& text);
+ inline void clearKeys();
+
+ int nrecs;
+ KeyRecord deleted_record; // A copy of last entry removed from records[]
+ KeyRecord records[QT_MAX_KEY_RECORDINGS];
+};
+static KeyRecorder key_recorder;
+
+KeyRecord *KeyRecorder::findKey(int code, bool remove)
+{
+ KeyRecord *result = 0;
+ for (int i = 0; i < nrecs; ++i) {
+ if (records[i].code == code) {
+ if (remove) {
+ deleted_record = records[i];
+ // Move rest down, and decrease count
+ while (i + 1 < nrecs) {
+ records[i] = records[i + 1];
+ ++i;
+ }
+ --nrecs;
+ result = &deleted_record;
+ } else {
+ result = &records[i];
+ }
+ break;
+ }
+ }
+ return result;
+}
+
+void KeyRecorder::storeKey(int code, int ascii, int state, const QString& text)
+{
+ Q_ASSERT_X(nrecs != QT_MAX_KEY_RECORDINGS,
+ "Internal KeyRecorder",
+ "Keyboard recorder buffer overflow, consider increasing QT_MAX_KEY_RECORDINGS");
+
+ if (nrecs == QT_MAX_KEY_RECORDINGS) {
+ qWarning("Qt: Internal keyboard buffer overflow");
+ return;
+ }
+ records[nrecs++] = KeyRecord(code,ascii,state,text);
+}
+
+void KeyRecorder::clearKeys()
+{
+ nrecs = 0;
+}
+// Key recorder --------------------------------------------------------------------------[ end ] --
+
+
+// Key translation ---------------------------------------------------------------------[ start ] --
+// Meaning of values:
+// 0 = Character output key, needs keyboard driver mapping
+// Key_unknown = Unknown Virtual Key, no translation possible, ignore
+static const uint KeyTbl[] = { // Keyboard mapping table
+ // Dec | Hex | Windows Virtual key
+ Qt::Key_unknown, // 0 0x00
+ Qt::Key_unknown, // 1 0x01 VK_LBUTTON | Left mouse button
+ Qt::Key_unknown, // 2 0x02 VK_RBUTTON | Right mouse button
+ Qt::Key_Cancel, // 3 0x03 VK_CANCEL | Control-Break processing
+ Qt::Key_unknown, // 4 0x04 VK_MBUTTON | Middle mouse button
+ Qt::Key_unknown, // 5 0x05 VK_XBUTTON1 | X1 mouse button
+ Qt::Key_unknown, // 6 0x06 VK_XBUTTON2 | X2 mouse button
+ Qt::Key_unknown, // 7 0x07 -- unassigned --
+ Qt::Key_Backspace, // 8 0x08 VK_BACK | BackSpace key
+ Qt::Key_Tab, // 9 0x09 VK_TAB | Tab key
+ Qt::Key_unknown, // 10 0x0A -- reserved --
+ Qt::Key_unknown, // 11 0x0B -- reserved --
+ Qt::Key_Clear, // 12 0x0C VK_CLEAR | Clear key
+ Qt::Key_Return, // 13 0x0D VK_RETURN | Enter key
+ Qt::Key_unknown, // 14 0x0E -- unassigned --
+ Qt::Key_unknown, // 15 0x0F -- unassigned --
+ Qt::Key_Shift, // 16 0x10 VK_SHIFT | Shift key
+ Qt::Key_Control, // 17 0x11 VK_CONTROL | Ctrl key
+ Qt::Key_Alt, // 18 0x12 VK_MENU | Alt key
+ Qt::Key_Pause, // 19 0x13 VK_PAUSE | Pause key
+ Qt::Key_CapsLock, // 20 0x14 VK_CAPITAL | Caps-Lock
+ Qt::Key_unknown, // 21 0x15 VK_KANA / VK_HANGUL | IME Kana or Hangul mode
+ Qt::Key_unknown, // 22 0x16 -- unassigned --
+ Qt::Key_unknown, // 23 0x17 VK_JUNJA | IME Junja mode
+ Qt::Key_unknown, // 24 0x18 VK_FINAL | IME final mode
+ Qt::Key_unknown, // 25 0x19 VK_HANJA / VK_KANJI | IME Hanja or Kanji mode
+ Qt::Key_unknown, // 26 0x1A -- unassigned --
+ Qt::Key_Escape, // 27 0x1B VK_ESCAPE | Esc key
+ Qt::Key_unknown, // 28 0x1C VK_CONVERT | IME convert
+ Qt::Key_unknown, // 29 0x1D VK_NONCONVERT | IME non-convert
+ Qt::Key_unknown, // 30 0x1E VK_ACCEPT | IME accept
+ Qt::Key_Mode_switch,// 31 0x1F VK_MODECHANGE | IME mode change request
+ Qt::Key_Space, // 32 0x20 VK_SPACE | Spacebar
+ Qt::Key_PageUp, // 33 0x21 VK_PRIOR | Page Up key
+ Qt::Key_PageDown, // 34 0x22 VK_NEXT | Page Down key
+ Qt::Key_End, // 35 0x23 VK_END | End key
+ Qt::Key_Home, // 36 0x24 VK_HOME | Home key
+ Qt::Key_Left, // 37 0x25 VK_LEFT | Left arrow key
+ Qt::Key_Up, // 38 0x26 VK_UP | Up arrow key
+ Qt::Key_Right, // 39 0x27 VK_RIGHT | Right arrow key
+ Qt::Key_Down, // 40 0x28 VK_DOWN | Down arrow key
+ Qt::Key_Select, // 41 0x29 VK_SELECT | Select key
+ Qt::Key_Printer, // 42 0x2A VK_PRINT | Print key
+ Qt::Key_Execute, // 43 0x2B VK_EXECUTE | Execute key
+ Qt::Key_Print, // 44 0x2C VK_SNAPSHOT | Print Screen key
+ Qt::Key_Insert, // 45 0x2D VK_INSERT | Ins key
+ Qt::Key_Delete, // 46 0x2E VK_DELETE | Del key
+ Qt::Key_Help, // 47 0x2F VK_HELP | Help key
+ 0, // 48 0x30 (VK_0) | 0 key
+ 0, // 49 0x31 (VK_1) | 1 key
+ 0, // 50 0x32 (VK_2) | 2 key
+ 0, // 51 0x33 (VK_3) | 3 key
+ 0, // 52 0x34 (VK_4) | 4 key
+ 0, // 53 0x35 (VK_5) | 5 key
+ 0, // 54 0x36 (VK_6) | 6 key
+ 0, // 55 0x37 (VK_7) | 7 key
+ 0, // 56 0x38 (VK_8) | 8 key
+ 0, // 57 0x39 (VK_9) | 9 key
+ Qt::Key_unknown, // 58 0x3A -- unassigned --
+ Qt::Key_unknown, // 59 0x3B -- unassigned --
+ Qt::Key_unknown, // 60 0x3C -- unassigned --
+ Qt::Key_unknown, // 61 0x3D -- unassigned --
+ Qt::Key_unknown, // 62 0x3E -- unassigned --
+ Qt::Key_unknown, // 63 0x3F -- unassigned --
+ Qt::Key_unknown, // 64 0x40 -- unassigned --
+ 0, // 65 0x41 (VK_A) | A key
+ 0, // 66 0x42 (VK_B) | B key
+ 0, // 67 0x43 (VK_C) | C key
+ 0, // 68 0x44 (VK_D) | D key
+ 0, // 69 0x45 (VK_E) | E key
+ 0, // 70 0x46 (VK_F) | F key
+ 0, // 71 0x47 (VK_G) | G key
+ 0, // 72 0x48 (VK_H) | H key
+ 0, // 73 0x49 (VK_I) | I key
+ 0, // 74 0x4A (VK_J) | J key
+ 0, // 75 0x4B (VK_K) | K key
+ 0, // 76 0x4C (VK_L) | L key
+ 0, // 77 0x4D (VK_M) | M key
+ 0, // 78 0x4E (VK_N) | N key
+ 0, // 79 0x4F (VK_O) | O key
+ 0, // 80 0x50 (VK_P) | P key
+ 0, // 81 0x51 (VK_Q) | Q key
+ 0, // 82 0x52 (VK_R) | R key
+ 0, // 83 0x53 (VK_S) | S key
+ 0, // 84 0x54 (VK_T) | T key
+ 0, // 85 0x55 (VK_U) | U key
+ 0, // 86 0x56 (VK_V) | V key
+ 0, // 87 0x57 (VK_W) | W key
+ 0, // 88 0x58 (VK_X) | X key
+ 0, // 89 0x59 (VK_Y) | Y key
+ 0, // 90 0x5A (VK_Z) | Z key
+ Qt::Key_Meta, // 91 0x5B VK_LWIN | Left Windows - MS Natural kbd
+ Qt::Key_Meta, // 92 0x5C VK_RWIN | Right Windows - MS Natural kbd
+ Qt::Key_Menu, // 93 0x5D VK_APPS | Application key-MS Natural kbd
+ Qt::Key_unknown, // 94 0x5E -- reserved --
+ Qt::Key_Sleep, // 95 0x5F VK_SLEEP
+ Qt::Key_0, // 96 0x60 VK_NUMPAD0 | Numeric keypad 0 key
+ Qt::Key_1, // 97 0x61 VK_NUMPAD1 | Numeric keypad 1 key
+ Qt::Key_2, // 98 0x62 VK_NUMPAD2 | Numeric keypad 2 key
+ Qt::Key_3, // 99 0x63 VK_NUMPAD3 | Numeric keypad 3 key
+ Qt::Key_4, // 100 0x64 VK_NUMPAD4 | Numeric keypad 4 key
+ Qt::Key_5, // 101 0x65 VK_NUMPAD5 | Numeric keypad 5 key
+ Qt::Key_6, // 102 0x66 VK_NUMPAD6 | Numeric keypad 6 key
+ Qt::Key_7, // 103 0x67 VK_NUMPAD7 | Numeric keypad 7 key
+ Qt::Key_8, // 104 0x68 VK_NUMPAD8 | Numeric keypad 8 key
+ Qt::Key_9, // 105 0x69 VK_NUMPAD9 | Numeric keypad 9 key
+ Qt::Key_Asterisk, // 106 0x6A VK_MULTIPLY | Multiply key
+ Qt::Key_Plus, // 107 0x6B VK_ADD | Add key
+ Qt::Key_Comma, // 108 0x6C VK_SEPARATOR | Separator key
+ Qt::Key_Minus, // 109 0x6D VK_SUBTRACT | Subtract key
+ Qt::Key_Period, // 110 0x6E VK_DECIMAL | Decimal key
+ Qt::Key_Slash, // 111 0x6F VK_DIVIDE | Divide key
+ Qt::Key_F1, // 112 0x70 VK_F1 | F1 key
+ Qt::Key_F2, // 113 0x71 VK_F2 | F2 key
+ Qt::Key_F3, // 114 0x72 VK_F3 | F3 key
+ Qt::Key_F4, // 115 0x73 VK_F4 | F4 key
+ Qt::Key_F5, // 116 0x74 VK_F5 | F5 key
+ Qt::Key_F6, // 117 0x75 VK_F6 | F6 key
+ Qt::Key_F7, // 118 0x76 VK_F7 | F7 key
+ Qt::Key_F8, // 119 0x77 VK_F8 | F8 key
+ Qt::Key_F9, // 120 0x78 VK_F9 | F9 key
+ Qt::Key_F10, // 121 0x79 VK_F10 | F10 key
+ Qt::Key_F11, // 122 0x7A VK_F11 | F11 key
+ Qt::Key_F12, // 123 0x7B VK_F12 | F12 key
+ Qt::Key_F13, // 124 0x7C VK_F13 | F13 key
+ Qt::Key_F14, // 125 0x7D VK_F14 | F14 key
+ Qt::Key_F15, // 126 0x7E VK_F15 | F15 key
+ Qt::Key_F16, // 127 0x7F VK_F16 | F16 key
+ Qt::Key_F17, // 128 0x80 VK_F17 | F17 key
+ Qt::Key_F18, // 129 0x81 VK_F18 | F18 key
+ Qt::Key_F19, // 130 0x82 VK_F19 | F19 key
+ Qt::Key_F20, // 131 0x83 VK_F20 | F20 key
+ Qt::Key_F21, // 132 0x84 VK_F21 | F21 key
+ Qt::Key_F22, // 133 0x85 VK_F22 | F22 key
+ Qt::Key_F23, // 134 0x86 VK_F23 | F23 key
+ Qt::Key_F24, // 135 0x87 VK_F24 | F24 key
+ Qt::Key_unknown, // 136 0x88 -- unassigned --
+ Qt::Key_unknown, // 137 0x89 -- unassigned --
+ Qt::Key_unknown, // 138 0x8A -- unassigned --
+ Qt::Key_unknown, // 139 0x8B -- unassigned --
+ Qt::Key_unknown, // 140 0x8C -- unassigned --
+ Qt::Key_unknown, // 141 0x8D -- unassigned --
+ Qt::Key_unknown, // 142 0x8E -- unassigned --
+ Qt::Key_unknown, // 143 0x8F -- unassigned --
+ Qt::Key_NumLock, // 144 0x90 VK_NUMLOCK | Num Lock key
+ Qt::Key_ScrollLock, // 145 0x91 VK_SCROLL | Scroll Lock key
+ // Fujitsu/OASYS kbd --------------------
+ 0, //Qt::Key_Jisho, // 146 0x92 VK_OEM_FJ_JISHO | 'Dictionary' key /
+ // VK_OEM_NEC_EQUAL = key on numpad on NEC PC-9800 kbd
+ Qt::Key_Massyo, // 147 0x93 VK_OEM_FJ_MASSHOU | 'Unregister word' key
+ Qt::Key_Touroku, // 148 0x94 VK_OEM_FJ_TOUROKU | 'Register word' key
+ 0, //Qt::Key_Oyayubi_Left,//149 0x95 VK_OEM_FJ_LOYA | 'Left OYAYUBI' key
+ 0, //Qt::Key_Oyayubi_Right,//150 0x96 VK_OEM_FJ_ROYA | 'Right OYAYUBI' key
+ Qt::Key_unknown, // 151 0x97 -- unassigned --
+ Qt::Key_unknown, // 152 0x98 -- unassigned --
+ Qt::Key_unknown, // 153 0x99 -- unassigned --
+ Qt::Key_unknown, // 154 0x9A -- unassigned --
+ Qt::Key_unknown, // 155 0x9B -- unassigned --
+ Qt::Key_unknown, // 156 0x9C -- unassigned --
+ Qt::Key_unknown, // 157 0x9D -- unassigned --
+ Qt::Key_unknown, // 158 0x9E -- unassigned --
+ Qt::Key_unknown, // 159 0x9F -- unassigned --
+ Qt::Key_Shift, // 160 0xA0 VK_LSHIFT | Left Shift key
+ Qt::Key_Shift, // 161 0xA1 VK_RSHIFT | Right Shift key
+ Qt::Key_Control, // 162 0xA2 VK_LCONTROL | Left Ctrl key
+ Qt::Key_Control, // 163 0xA3 VK_RCONTROL | Right Ctrl key
+ Qt::Key_Alt, // 164 0xA4 VK_LMENU | Left Menu key
+ Qt::Key_Alt, // 165 0xA5 VK_RMENU | Right Menu key
+ Qt::Key_Back, // 166 0xA6 VK_BROWSER_BACK | Browser Back key
+ Qt::Key_Forward, // 167 0xA7 VK_BROWSER_FORWARD | Browser Forward key
+ Qt::Key_Refresh, // 168 0xA8 VK_BROWSER_REFRESH | Browser Refresh key
+ Qt::Key_Stop, // 169 0xA9 VK_BROWSER_STOP | Browser Stop key
+ Qt::Key_Search, // 170 0xAA VK_BROWSER_SEARCH | Browser Search key
+ Qt::Key_Favorites, // 171 0xAB VK_BROWSER_FAVORITES| Browser Favorites key
+ Qt::Key_HomePage, // 172 0xAC VK_BROWSER_HOME | Browser Start and Home key
+ Qt::Key_VolumeMute, // 173 0xAD VK_VOLUME_MUTE | Volume Mute key
+ Qt::Key_VolumeDown, // 174 0xAE VK_VOLUME_DOWN | Volume Down key
+ Qt::Key_VolumeUp, // 175 0xAF VK_VOLUME_UP | Volume Up key
+ Qt::Key_MediaNext, // 176 0xB0 VK_MEDIA_NEXT_TRACK | Next Track key
+ Qt::Key_MediaPrevious, //177 0xB1 VK_MEDIA_PREV_TRACK | Previous Track key
+ Qt::Key_MediaStop, // 178 0xB2 VK_MEDIA_STOP | Stop Media key
+ Qt::Key_MediaPlay, // 179 0xB3 VK_MEDIA_PLAY_PAUSE | Play/Pause Media key
+ Qt::Key_LaunchMail, // 180 0xB4 VK_LAUNCH_MAIL | Start Mail key
+ Qt::Key_LaunchMedia,// 181 0xB5 VK_LAUNCH_MEDIA_SELECT Select Media key
+ Qt::Key_Launch0, // 182 0xB6 VK_LAUNCH_APP1 | Start Application 1 key
+ Qt::Key_Launch1, // 183 0xB7 VK_LAUNCH_APP2 | Start Application 2 key
+ Qt::Key_unknown, // 184 0xB8 -- reserved --
+ Qt::Key_unknown, // 185 0xB9 -- reserved --
+ 0, // 186 0xBA VK_OEM_1 | ';:' for US
+ 0, // 187 0xBB VK_OEM_PLUS | '+' any country
+ 0, // 188 0xBC VK_OEM_COMMA | ',' any country
+ 0, // 189 0xBD VK_OEM_MINUS | '-' any country
+ 0, // 190 0xBE VK_OEM_PERIOD | '.' any country
+ 0, // 191 0xBF VK_OEM_2 | '/?' for US
+ 0, // 192 0xC0 VK_OEM_3 | '`~' for US
+ Qt::Key_unknown, // 193 0xC1 -- reserved --
+ Qt::Key_unknown, // 194 0xC2 -- reserved --
+ Qt::Key_unknown, // 195 0xC3 -- reserved --
+ Qt::Key_unknown, // 196 0xC4 -- reserved --
+ Qt::Key_unknown, // 197 0xC5 -- reserved --
+ Qt::Key_unknown, // 198 0xC6 -- reserved --
+ Qt::Key_unknown, // 199 0xC7 -- reserved --
+ Qt::Key_unknown, // 200 0xC8 -- reserved --
+ Qt::Key_unknown, // 201 0xC9 -- reserved --
+ Qt::Key_unknown, // 202 0xCA -- reserved --
+ Qt::Key_unknown, // 203 0xCB -- reserved --
+ Qt::Key_unknown, // 204 0xCC -- reserved --
+ Qt::Key_unknown, // 205 0xCD -- reserved --
+ Qt::Key_unknown, // 206 0xCE -- reserved --
+ Qt::Key_unknown, // 207 0xCF -- reserved --
+ Qt::Key_unknown, // 208 0xD0 -- reserved --
+ Qt::Key_unknown, // 209 0xD1 -- reserved --
+ Qt::Key_unknown, // 210 0xD2 -- reserved --
+ Qt::Key_unknown, // 211 0xD3 -- reserved --
+ Qt::Key_unknown, // 212 0xD4 -- reserved --
+ Qt::Key_unknown, // 213 0xD5 -- reserved --
+ Qt::Key_unknown, // 214 0xD6 -- reserved --
+ Qt::Key_unknown, // 215 0xD7 -- reserved --
+ Qt::Key_unknown, // 216 0xD8 -- unassigned --
+ Qt::Key_unknown, // 217 0xD9 -- unassigned --
+ Qt::Key_unknown, // 218 0xDA -- unassigned --
+ 0, // 219 0xDB VK_OEM_4 | '[{' for US
+ 0, // 220 0xDC VK_OEM_5 | '\|' for US
+ 0, // 221 0xDD VK_OEM_6 | ']}' for US
+ 0, // 222 0xDE VK_OEM_7 | ''"' for US
+ 0, // 223 0xDF VK_OEM_8
+ Qt::Key_unknown, // 224 0xE0 -- reserved --
+ Qt::Key_unknown, // 225 0xE1 VK_OEM_AX | 'AX' key on Japanese AX kbd
+ Qt::Key_unknown, // 226 0xE2 VK_OEM_102 | "<>" or "\|" on RT 102-key kbd
+ Qt::Key_unknown, // 227 0xE3 VK_ICO_HELP | Help key on ICO
+ Qt::Key_unknown, // 228 0xE4 VK_ICO_00 | 00 key on ICO
+ Qt::Key_unknown, // 229 0xE5 VK_PROCESSKEY | IME Process key
+ Qt::Key_unknown, // 230 0xE6 VK_ICO_CLEAR |
+ Qt::Key_unknown, // 231 0xE7 VK_PACKET | Unicode char as keystrokes
+ Qt::Key_unknown, // 232 0xE8 -- unassigned --
+ // Nokia/Ericsson definitions ---------------
+ Qt::Key_unknown, // 233 0xE9 VK_OEM_RESET
+ Qt::Key_unknown, // 234 0xEA VK_OEM_JUMP
+ Qt::Key_unknown, // 235 0xEB VK_OEM_PA1
+ Qt::Key_unknown, // 236 0xEC VK_OEM_PA2
+ Qt::Key_unknown, // 237 0xED VK_OEM_PA3
+ Qt::Key_unknown, // 238 0xEE VK_OEM_WSCTRL
+ Qt::Key_unknown, // 239 0xEF VK_OEM_CUSEL
+ Qt::Key_unknown, // 240 0xF0 VK_OEM_ATTN
+ Qt::Key_unknown, // 241 0xF1 VK_OEM_FINISH
+ Qt::Key_unknown, // 242 0xF2 VK_OEM_COPY
+ Qt::Key_unknown, // 243 0xF3 VK_OEM_AUTO
+ Qt::Key_unknown, // 244 0xF4 VK_OEM_ENLW
+ Qt::Key_unknown, // 245 0xF5 VK_OEM_BACKTAB
+ Qt::Key_unknown, // 246 0xF6 VK_ATTN | Attn key
+ Qt::Key_unknown, // 247 0xF7 VK_CRSEL | CrSel key
+ Qt::Key_unknown, // 248 0xF8 VK_EXSEL | ExSel key
+ Qt::Key_unknown, // 249 0xF9 VK_EREOF | Erase EOF key
+ Qt::Key_Play, // 250 0xFA VK_PLAY | Play key
+ Qt::Key_Zoom, // 251 0xFB VK_ZOOM | Zoom key
+ Qt::Key_unknown, // 252 0xFC VK_NONAME | Reserved
+ Qt::Key_unknown, // 253 0xFD VK_PA1 | PA1 key
+ Qt::Key_Clear, // 254 0xFE VK_OEM_CLEAR | Clear key
+ 0
+};
+
+// Possible modifier states.
+// NOTE: The order of these states match the order in QKeyMapperPrivate::updatePossibleKeyCodes()!
+static const Qt::KeyboardModifiers ModsTbl[] = {
+ Qt::NoModifier, // 0
+ Qt::ShiftModifier, // 1
+ Qt::ControlModifier, // 2
+ Qt::ControlModifier | Qt::ShiftModifier, // 3
+ Qt::AltModifier, // 4
+ Qt::AltModifier | Qt::ShiftModifier, // 5
+ Qt::AltModifier | Qt::ControlModifier, // 6
+ Qt::AltModifier | Qt::ShiftModifier | Qt::ControlModifier, // 7
+ Qt::NoModifier, // Fall-back to raw Key_*
+};
+
+/**
+ Remap return or action key to select key for windows mobile.
+*/
+inline int winceKeyBend(int keyCode)
+{
+#if defined(Q_OS_WINCE_WM) && defined(QT_KEYPAD_NAVIGATION)
+ // remap return or action key to select key for windows mobile.
+ // will be changed to a table remapping function in the next version (4.6/7).
+ if (keyCode == VK_RETURN && QApplication::keypadNavigationEnabled())
+ return Qt::Key_Select;
+ else
+ return KeyTbl[keyCode];
+#else
+ return KeyTbl[keyCode];
+#endif
+}
+
+#if defined(Q_OS_WINCE)
+ // Use the KeyTbl to resolve a Qt::Key out of the virtual keys.
+ // In case it is not resolvable, continue using the virtual key itself.
+
+QT_BEGIN_INCLUDE_NAMESPACE
+
+int ToUnicode(UINT vk, int /*scancode*/, unsigned char* /*kbdBuffer*/, LPWSTR unicodeBuffer, int, int)
+{
+ QT_USE_NAMESPACE
+ QChar* buf = reinterpret_cast< QChar*>(unicodeBuffer);
+ if (KeyTbl[vk] == 0) {
+ buf[0] = vk;
+ return 1;
+ }
+ return 0;
+}
+
+int ToAscii(UINT vk, int scancode, unsigned char *kbdBuffer, LPWORD unicodeBuffer, int flag)
+{
+ return ToUnicode(vk, scancode, kbdBuffer, (LPWSTR) unicodeBuffer, 0, flag);
+
+}
+QT_END_INCLUDE_NAMESPACE
+
+#endif
+
+// Translate a VK into a Qt key code, or unicode character
+static inline int toKeyOrUnicode(int vk, int scancode, unsigned char *kbdBuffer, bool *isDeadkey = 0)
+{
+ Q_ASSERT(vk > 0 && vk < 256);
+ int code = 0;
+ QChar unicodeBuffer[5];
+ int res = ToUnicode(vk, scancode, kbdBuffer, reinterpret_cast<LPWSTR>(unicodeBuffer), 5, 0);
+ if (res)
+ code = unicodeBuffer[0].toUpper().unicode();
+
+ // Qt::Key_*'s are not encoded below 0x20, so try again, and DEL keys (0x7f) is encoded with a
+ // proper Qt::Key_ code
+ if (code < 0x20 || code == 0x7f) // Handles res==0 too
+ code = winceKeyBend(vk);
+
+ if (isDeadkey)
+ *isDeadkey = (res == -1);
+
+ return code == Qt::Key_unknown ? 0 : code;
+}
+
+Q_WIDGETS_EXPORT int qt_translateKeyCode(int vk)
+{
+ int code = winceKeyBend((vk < 0 || vk > 255) ? 0 : vk);
+ return code == Qt::Key_unknown ? 0 : code;
+}
+
+static inline int asciiToKeycode(char a, int state)
+{
+ if (a >= 'a' && a <= 'z')
+ a = toupper(a);
+ if ((state & Qt::ControlModifier) != 0) {
+ if (a >= 0 && a <= 31) // Ctrl+@..Ctrl+A..CTRL+Z..Ctrl+_
+ a += '@'; // to @..A..Z.._
+ }
+ return a & 0xff;
+}
+
+static inline bool isModifierKey(int code)
+{
+ return (code >= Qt::Key_Shift) && (code <= Qt::Key_ScrollLock);
+}
+// Key translation -----------------------------------------------------------------------[ end ]---
+
+
+static void qt_show_system_menu(QWidget* tlw)
+{
+ Q_ASSERT(tlw->testAttribute(Qt::WA_WState_Created));
+ HMENU menu = GetSystemMenu(tlw->internalWinId(), FALSE);
+ if (!menu)
+ return; // no menu for this window
+
+#define enabled (MF_BYCOMMAND | MF_ENABLED)
+#define disabled (MF_BYCOMMAND | MF_GRAYED)
+
+#ifndef Q_OS_WINCE
+ EnableMenuItem(menu, SC_MINIMIZE, (tlw->windowFlags() & Qt::WindowMinimizeButtonHint)?enabled:disabled);
+ bool maximized = IsZoomed(tlw->internalWinId());
+
+ EnableMenuItem(menu, SC_MAXIMIZE, ! (tlw->windowFlags() & Qt::WindowMaximizeButtonHint) || maximized?disabled:enabled);
+ EnableMenuItem(menu, SC_RESTORE, maximized?enabled:disabled);
+
+ // We should _not_ check with the setFixedSize(x,y) case here, since Windows is not able to check
+ // this and our menu here would be out-of-sync with the menu produced by mouse-click on the
+ // System Menu, or right-click on the title bar.
+ EnableMenuItem(menu, SC_SIZE, (tlw->windowFlags() & Qt::MSWindowsFixedSizeDialogHint) || maximized?disabled:enabled);
+ EnableMenuItem(menu, SC_MOVE, maximized?disabled:enabled);
+ EnableMenuItem(menu, SC_CLOSE, enabled);
+ // Set bold on close menu item
+ MENUITEMINFO closeItem;
+ closeItem.cbSize = sizeof(MENUITEMINFO);
+ closeItem.fMask = MIIM_STATE;
+ closeItem.fState = MFS_DEFAULT;
+ SetMenuItemInfo(menu, SC_CLOSE, FALSE, &closeItem);
+#endif
+
+#undef enabled
+#undef disabled
+ int ret = TrackPopupMenuEx(menu,
+ TPM_LEFTALIGN | TPM_TOPALIGN | TPM_NONOTIFY | TPM_RETURNCMD,
+ tlw->geometry().x(), tlw->geometry().y(),
+ tlw->internalWinId(),
+ 0);
+ if (ret)
+ QtWndProc(tlw->internalWinId(), WM_SYSCOMMAND, ret, 0);
+}
+
+
+// QETWidget class is only for accessing the sendSpontaneousEvent function in QApplication
+class QETWidget : public QWidget {
+public:
+ static bool sendSpontaneousEvent(QObject *r, QEvent *e)
+ { return QApplication::sendSpontaneousEvent(r, e); }
+};
+
+
+// Keyboard map private ----------------------------------------------------------------[ start ]---
+
+/*
+ \internal
+ A Windows KeyboardLayoutItem has 8 possible states:
+ 1. Unmodified
+ 2. Shift
+ 3. Control
+ 4. Control + Shift
+ 5. Alt
+ 6. Alt + Shift
+ 7. Alt + Control
+ 8. Alt + Control + Shift
+*/
+struct KeyboardLayoutItem {
+ bool dirty;
+ quint8 deadkeys;
+ quint32 qtKey[9]; // Can by any Qt::Key_<foo>, or unicode character
+};
+
+QKeyMapperPrivate::QKeyMapperPrivate()
+{
+ memset(keyLayout, 0, sizeof(keyLayout));
+}
+
+QKeyMapperPrivate::~QKeyMapperPrivate()
+{
+ deleteLayouts();
+}
+
+void QKeyMapperPrivate::deleteLayouts()
+{
+ for (int i = 0; i < 255; ++i) {
+ if (keyLayout[i]) {
+ delete keyLayout[i];
+ keyLayout[i] = 0;
+ }
+ }
+}
+
+void QKeyMapperPrivate::clearMappings()
+{
+ deleteLayouts();
+
+ /* MAKELCID()'s first argument is a WORD, and GetKeyboardLayout()
+ * returns a DWORD. */
+
+ LCID newLCID = MAKELCID((quintptr)GetKeyboardLayout(0), SORT_DEFAULT);
+// keyboardInputLocale = qt_localeFromLCID(newLCID);
+
+ bool bidi = false;
+ wchar_t LCIDFontSig[16];
+ if (GetLocaleInfo(newLCID, LOCALE_FONTSIGNATURE, LCIDFontSig, sizeof(LCIDFontSig) / sizeof(wchar_t))
+ && (LCIDFontSig[7] & (wchar_t)0x0800))
+ bidi = true;
+
+ keyboardInputDirection = bidi ? Qt::RightToLeft : Qt::LeftToRight;
+}
+
+void QKeyMapperPrivate::clearRecordedKeys()
+{
+ key_recorder.clearKeys();
+}
+
+
+inline void setKbdState(unsigned char *kbd, bool shift, bool ctrl, bool alt)
+{
+ kbd[VK_LSHIFT ] = (shift ? 0x80 : 0);
+ kbd[VK_SHIFT ] = (shift ? 0x80 : 0);
+ kbd[VK_LCONTROL] = (ctrl ? 0x80 : 0);
+ kbd[VK_CONTROL ] = (ctrl ? 0x80 : 0);
+ kbd[VK_RMENU ] = (alt ? 0x80 : 0);
+ kbd[VK_MENU ] = (alt ? 0x80 : 0);
+}
+
+void QKeyMapperPrivate::updateKeyMap(const MSG &msg)
+{
+ unsigned char kbdBuffer[256]; // Will hold the complete keyboard state
+ GetKeyboardState(kbdBuffer);
+ quint32 scancode = (msg.lParam >> 16) & 0xfff;
+ updatePossibleKeyCodes(kbdBuffer, scancode, msg.wParam);
+}
+
+void QKeyMapperPrivate::updatePossibleKeyCodes(unsigned char *kbdBuffer, quint32 scancode,
+ quint32 vk_key)
+{
+ if (!vk_key || (keyLayout[vk_key] && !keyLayout[vk_key]->dirty))
+ return;
+
+ if (!keyLayout[vk_key])
+ keyLayout[vk_key] = new KeyboardLayoutItem;
+
+ // Copy keyboard state, so we can modify and query output for each possible permutation
+ unsigned char buffer[256];
+ memcpy(buffer, kbdBuffer, sizeof(buffer));
+ // Always 0, as Windows doesn't treat these as modifiers;
+ buffer[VK_LWIN ] = 0;
+ buffer[VK_RWIN ] = 0;
+ buffer[VK_CAPITAL ] = 0;
+ buffer[VK_NUMLOCK ] = 0;
+ buffer[VK_SCROLL ] = 0;
+ // Always 0, since we'll only change the other versions
+ buffer[VK_RSHIFT ] = 0;
+ buffer[VK_RCONTROL] = 0;
+ buffer[VK_LMENU ] = 0; // Use right Alt, since left Ctrl + right Alt is considered AltGraph
+
+ bool isDeadKey = false;
+ keyLayout[vk_key]->deadkeys = 0;
+ keyLayout[vk_key]->dirty = false;
+ setKbdState(buffer, false, false, false);
+ keyLayout[vk_key]->qtKey[0] = toKeyOrUnicode(vk_key, scancode, buffer, &isDeadKey);
+ keyLayout[vk_key]->deadkeys |= isDeadKey ? 0x01 : 0;
+ setKbdState(buffer, true, false, false);
+ keyLayout[vk_key]->qtKey[1] = toKeyOrUnicode(vk_key, scancode, buffer, &isDeadKey);
+ keyLayout[vk_key]->deadkeys |= isDeadKey ? 0x02 : 0;
+ setKbdState(buffer, false, true, false);
+ keyLayout[vk_key]->qtKey[2] = toKeyOrUnicode(vk_key, scancode, buffer, &isDeadKey);
+ keyLayout[vk_key]->deadkeys |= isDeadKey ? 0x04 : 0;
+ setKbdState(buffer, true, true, false);
+ keyLayout[vk_key]->qtKey[3] = toKeyOrUnicode(vk_key, scancode, buffer, &isDeadKey);
+ keyLayout[vk_key]->deadkeys |= isDeadKey ? 0x08 : 0;
+ setKbdState(buffer, false, false, true);
+ keyLayout[vk_key]->qtKey[4] = toKeyOrUnicode(vk_key, scancode, buffer, &isDeadKey);
+ keyLayout[vk_key]->deadkeys |= isDeadKey ? 0x10 : 0;
+ setKbdState(buffer, true, false, true);
+ keyLayout[vk_key]->qtKey[5] = toKeyOrUnicode(vk_key, scancode, buffer, &isDeadKey);
+ keyLayout[vk_key]->deadkeys |= isDeadKey ? 0x20 : 0;
+ setKbdState(buffer, false, true, true);
+ keyLayout[vk_key]->qtKey[6] = toKeyOrUnicode(vk_key, scancode, buffer, &isDeadKey);
+ keyLayout[vk_key]->deadkeys |= isDeadKey ? 0x40 : 0;
+ setKbdState(buffer, true, true, true);
+ keyLayout[vk_key]->qtKey[7] = toKeyOrUnicode(vk_key, scancode, buffer, &isDeadKey);
+ keyLayout[vk_key]->deadkeys |= isDeadKey ? 0x80 : 0;
+ // Add a fall back key for layouts which don't do composition and show non-latin1 characters
+ int fallbackKey = winceKeyBend(vk_key);
+ if (!fallbackKey || fallbackKey == Qt::Key_unknown) {
+ fallbackKey = 0;
+ if (vk_key != keyLayout[vk_key]->qtKey[0] && vk_key < 0x5B && vk_key > 0x2F)
+ fallbackKey = vk_key;
+ }
+ keyLayout[vk_key]->qtKey[8] = fallbackKey;
+
+ // If this vk_key a Dead Key
+ if (MapVirtualKey(vk_key, 2) & 0x80000000) {
+ // Push a Space, then the original key through the low-level ToAscii functions.
+ // We do this because these functions (ToAscii / ToUnicode) will alter the internal state of
+ // the keyboard driver By doing the following, we set the keyboard driver state back to what
+ // it was before we wrecked it with the code above.
+ // We need to push the space with an empty keystate map, since the driver checks the map for
+ // transitions in modifiers, so this helps us capture all possible deadkeys.
+ unsigned char emptyBuffer[256];
+ memset(emptyBuffer, 0, sizeof(emptyBuffer));
+ ::ToAscii(VK_SPACE, 0, emptyBuffer, reinterpret_cast<LPWORD>(&buffer), 0);
+ ::ToAscii(vk_key, scancode, kbdBuffer, reinterpret_cast<LPWORD>(&buffer), 0);
+ }
+
+#ifdef DEBUG_KEYMAPPER
+ qDebug("updatePossibleKeyCodes for virtual key = 0x%02x!", vk_key);
+ for (int i = 0; i < 9; ++i) {
+ qDebug(" [%d] (%d,0x%02x,'%c') %s", i,
+ keyLayout[vk_key]->qtKey[i],
+ keyLayout[vk_key]->qtKey[i],
+ keyLayout[vk_key]->qtKey[i] ? keyLayout[vk_key]->qtKey[i] : 0x03,
+ keyLayout[vk_key]->deadkeys & (1<<i) ? "deadkey" : "");
+ }
+#endif // DEBUG_KEYMAPPER
+}
+
+bool QKeyMapperPrivate::isADeadKey(unsigned int vk_key, unsigned int modifiers)
+{
+ if (keyLayout && (vk_key < 256) && keyLayout[vk_key]) {
+ for(register int i = 0; i < 9; ++i) {
+ if (uint(ModsTbl[i]) == modifiers)
+ return bool(keyLayout[vk_key]->deadkeys & 1<<i);
+ }
+ }
+ return false;
+}
+
+extern bool qt_use_rtl_extensions;
+
+QList<int> QKeyMapperPrivate::possibleKeys(QKeyEvent *e)
+{
+ QList<int> result;
+
+ KeyboardLayoutItem *kbItem = keyLayout[e->nativeVirtualKey()];
+ if(!kbItem)
+ return result;
+
+ quint32 baseKey = kbItem->qtKey[0];
+ Qt::KeyboardModifiers keyMods = e->modifiers();
+ if (baseKey == Qt::Key_Return && (e->nativeModifiers() & ExtendedKey)) {
+ result << int(Qt::Key_Enter + keyMods);
+ return result;
+ }
+ result << int(baseKey + keyMods); // The base key is _always_ valid, of course
+
+ for(int i = 1; i < 9; ++i) {
+ Qt::KeyboardModifiers neededMods = ModsTbl[i];
+ quint32 key = kbItem->qtKey[i];
+ if (key && key != baseKey && ((keyMods & neededMods) == neededMods))
+ result << int(key + (keyMods & ~neededMods));
+ }
+
+ return result;
+}
+
+bool QKeyMapperPrivate::translateKeyEvent(QWidget *widget, const MSG &msg, bool grab)
+{
+ Q_Q(QKeyMapper);
+ Q_UNUSED(q); // Strange, but the compiler complains on q not being referenced, even if it is..
+ bool k0 = false;
+ bool k1 = false;
+ int msgType = msg.message;
+
+ quint32 scancode = (msg.lParam >> 16) & 0xfff;
+ quint32 vk_key = MapVirtualKey(scancode, 1);
+ bool isNumpad = (msg.wParam >= VK_NUMPAD0 && msg.wParam <= VK_NUMPAD9);
+ quint32 nModifiers = 0;
+
+#if defined(Q_OS_WINCE)
+ nModifiers |= (GetKeyState(VK_SHIFT ) < 0 ? ShiftAny : 0);
+ nModifiers |= (GetKeyState(VK_CONTROL) < 0 ? ControlAny : 0);
+ nModifiers |= (GetKeyState(VK_MENU ) < 0 ? AltAny : 0);
+ nModifiers |= (GetKeyState(VK_LWIN ) < 0 ? MetaLeft : 0);
+ nModifiers |= (GetKeyState(VK_RWIN ) < 0 ? MetaRight : 0);
+#else
+ // Map native modifiers to some bit representation
+ nModifiers |= (GetKeyState(VK_LSHIFT ) & 0x80 ? ShiftLeft : 0);
+ nModifiers |= (GetKeyState(VK_RSHIFT ) & 0x80 ? ShiftRight : 0);
+ nModifiers |= (GetKeyState(VK_LCONTROL) & 0x80 ? ControlLeft : 0);
+ nModifiers |= (GetKeyState(VK_RCONTROL) & 0x80 ? ControlRight : 0);
+ nModifiers |= (GetKeyState(VK_LMENU ) & 0x80 ? AltLeft : 0);
+ nModifiers |= (GetKeyState(VK_RMENU ) & 0x80 ? AltRight : 0);
+ nModifiers |= (GetKeyState(VK_LWIN ) & 0x80 ? MetaLeft : 0);
+ nModifiers |= (GetKeyState(VK_RWIN ) & 0x80 ? MetaRight : 0);
+ // Add Lock keys to the same bits
+ nModifiers |= (GetKeyState(VK_CAPITAL ) & 0x01 ? CapsLock : 0);
+ nModifiers |= (GetKeyState(VK_NUMLOCK ) & 0x01 ? NumLock : 0);
+ nModifiers |= (GetKeyState(VK_SCROLL ) & 0x01 ? ScrollLock : 0);
+#endif // Q_OS_WINCE
+
+ if (msg.lParam & ExtendedKey)
+ nModifiers |= msg.lParam & ExtendedKey;
+
+ // Get the modifier states (may be altered later, depending on key code)
+ int state = 0;
+ state |= (nModifiers & ShiftAny ? Qt::ShiftModifier : 0);
+ state |= (nModifiers & ControlAny ? Qt::ControlModifier : 0);
+ state |= (nModifiers & AltAny ? Qt::AltModifier : 0);
+ state |= (nModifiers & MetaAny ? Qt::MetaModifier : 0);
+
+ // Now we know enough to either have MapVirtualKey or our own keymap tell us if it's a deadkey
+ bool isDeadKey = isADeadKey(msg.wParam, state)
+ || MapVirtualKey(msg.wParam, 2) & 0x80000000;
+
+ // A multi-character key not found by our look-ahead
+ if (msgType == WM_CHAR) {
+ QString s;
+ QChar ch = QChar((ushort)msg.wParam);
+ if (!ch.isNull())
+ s += ch;
+
+ k0 = q->sendKeyEvent(widget, grab, QEvent::KeyPress, 0, Qt::KeyboardModifier(state), s, false, 0, scancode, vk_key, nModifiers);
+ k1 = q->sendKeyEvent(widget, grab, QEvent::KeyRelease, 0, Qt::KeyboardModifier(state), s, false, 0, scancode, vk_key, nModifiers);
+ }
+
+ // Input method characters not found by our look-ahead
+ else if (msgType == WM_IME_CHAR) {
+ QString s;
+ QChar ch = QChar((ushort)msg.wParam);
+ if (!ch.isNull())
+ s += ch;
+
+ k0 = q->sendKeyEvent(widget, grab, QEvent::KeyPress, 0, Qt::KeyboardModifier(state), s, false, 0, scancode, vk_key, nModifiers);
+ k1 = q->sendKeyEvent(widget, grab, QEvent::KeyRelease, 0, Qt::KeyboardModifier(state), s, false, 0, scancode, vk_key, nModifiers);
+ }
+
+ else {
+ // handle Directionality changes (BiDi) with RTL extensions
+ if (qt_use_rtl_extensions) {
+ static int dirStatus = 0;
+ if (!dirStatus && state == Qt::ControlModifier
+ && msg.wParam == VK_CONTROL
+ && msgType == WM_KEYDOWN) {
+ if (GetKeyState(VK_LCONTROL) < 0)
+ dirStatus = VK_LCONTROL;
+ else if (GetKeyState(VK_RCONTROL) < 0)
+ dirStatus = VK_RCONTROL;
+ } else if (dirStatus) {
+ if (msgType == WM_KEYDOWN) {
+ if (msg.wParam == VK_SHIFT) {
+ if (dirStatus == VK_LCONTROL && GetKeyState(VK_LSHIFT) < 0)
+ dirStatus = VK_LSHIFT;
+ else if (dirStatus == VK_RCONTROL && GetKeyState(VK_RSHIFT) < 0)
+ dirStatus = VK_RSHIFT;
+ } else {
+ dirStatus = 0;
+ }
+ } else if (msgType == WM_KEYUP) {
+ if (dirStatus == VK_LSHIFT
+ && ((msg.wParam == VK_SHIFT && GetKeyState(VK_LCONTROL))
+ || (msg.wParam == VK_CONTROL && GetKeyState(VK_LSHIFT)))) {
+ k0 = q->sendKeyEvent(widget, grab, QEvent::KeyPress, Qt::Key_Direction_L, 0,
+ QString(), false, 0,
+ scancode, msg.wParam, nModifiers);
+ k1 = q->sendKeyEvent(widget, grab, QEvent::KeyRelease, Qt::Key_Direction_L, 0,
+ QString(), false, 0,
+ scancode, msg.wParam, nModifiers);
+ dirStatus = 0;
+ } else if (dirStatus == VK_RSHIFT
+ && ( (msg.wParam == VK_SHIFT && GetKeyState(VK_RCONTROL))
+ || (msg.wParam == VK_CONTROL && GetKeyState(VK_RSHIFT)))) {
+ k0 = q->sendKeyEvent(widget, grab, QEvent::KeyPress, Qt::Key_Direction_R,
+ 0, QString(), false, 0,
+ scancode, msg.wParam, nModifiers);
+ k1 = q->sendKeyEvent(widget, grab, QEvent::KeyRelease, Qt::Key_Direction_R,
+ 0, QString(), false, 0,
+ scancode, msg.wParam, nModifiers);
+ dirStatus = 0;
+ } else {
+ dirStatus = 0;
+ }
+ } else {
+ dirStatus = 0;
+ }
+ }
+ }
+
+ // IME will process these keys, so simply return
+ if(msg.wParam == VK_PROCESSKEY)
+ return true;
+
+ // Ignore invalid virtual keycodes (see bugs 127424, QTBUG-3630)
+ if (msg.wParam == 0 || msg.wParam == 0xFF)
+ return true;
+
+ // Translate VK_* (native) -> Key_* (Qt) keys
+ // If it's a dead key, we cannot use the toKeyOrUnicode() function, since that will change
+ // the internal state of the keyboard driver, resulting in that dead keys no longer works.
+ // ..also if we're typing numbers on the keypad, while holding down the Alt modifier.
+ int code = 0;
+ if (isNumpad && (nModifiers & AltAny)) {
+ code = winceKeyBend(msg.wParam);
+ } else if (!isDeadKey) {
+ unsigned char kbdBuffer[256]; // Will hold the complete keyboard state
+ GetKeyboardState(kbdBuffer);
+ code = toKeyOrUnicode(msg.wParam, scancode, kbdBuffer);
+ }
+
+ // Invert state logic:
+ // If the key actually pressed is a modifier key, then we remove its modifier key from the
+ // state, since a modifier-key can't have itself as a modifier
+ if (code == Qt::Key_Control)
+ state = state ^ Qt::ControlModifier;
+ else if (code == Qt::Key_Shift)
+ state = state ^ Qt::ShiftModifier;
+ else if (code == Qt::Key_Alt)
+ state = state ^ Qt::AltModifier;
+
+ // If the bit 24 of lParm is set you received a enter,
+ // otherwise a Return. (This is the extended key bit)
+ if ((code == Qt::Key_Return) && (msg.lParam & 0x1000000))
+ code = Qt::Key_Enter;
+
+ // All cursor keys without extended bit
+ if (!(msg.lParam & 0x1000000)) {
+ switch (code) {
+ case Qt::Key_Left:
+ case Qt::Key_Right:
+ case Qt::Key_Up:
+ case Qt::Key_Down:
+ case Qt::Key_PageUp:
+ case Qt::Key_PageDown:
+ case Qt::Key_Home:
+ case Qt::Key_End:
+ case Qt::Key_Insert:
+ case Qt::Key_Delete:
+ case Qt::Key_Asterisk:
+ case Qt::Key_Plus:
+ case Qt::Key_Minus:
+ case Qt::Key_Period:
+ case Qt::Key_0:
+ case Qt::Key_1:
+ case Qt::Key_2:
+ case Qt::Key_3:
+ case Qt::Key_4:
+ case Qt::Key_5:
+ case Qt::Key_6:
+ case Qt::Key_7:
+ case Qt::Key_8:
+ case Qt::Key_9:
+ state |= ((msg.wParam >= '0' && msg.wParam <= '9')
+ || (msg.wParam >= VK_OEM_PLUS && msg.wParam <= VK_OEM_3))
+ ? 0 : Qt::KeypadModifier;
+ default:
+ if ((uint)msg.lParam == 0x004c0001 || (uint)msg.lParam == 0xc04c0001)
+ state |= Qt::KeypadModifier;
+ break;
+ }
+ }
+ // Other keys with with extended bit
+ else {
+ switch (code) {
+ case Qt::Key_Enter:
+ case Qt::Key_Slash:
+ case Qt::Key_NumLock:
+ state |= Qt::KeypadModifier;
+ default:
+ break;
+ }
+ }
+
+ // KEYDOWN ---------------------------------------------------------------------------------
+ if (msgType == WM_KEYDOWN || msgType == WM_IME_KEYDOWN || msgType == WM_SYSKEYDOWN) {
+ // Get the last record of this key press, so we can validate the current state
+ // The record is not removed from the list
+ KeyRecord *rec = key_recorder.findKey(msg.wParam, false);
+
+ // If rec's state doesn't match the current state, something has changed behind our back
+ // (Consumed by modal widget is one possibility) So, remove the record from the list
+ // This will stop the auto-repeat of the key, should a modifier change, for example
+ if (rec && rec->state != state) {
+ key_recorder.findKey(msg.wParam, true);
+ rec = 0;
+ }
+
+ // Find unicode character from Windows Message Queue
+ MSG wm_char;
+ UINT charType = (msgType == WM_KEYDOWN
+ ? WM_CHAR
+ : msgType == WM_IME_KEYDOWN ? WM_IME_CHAR : WM_SYSCHAR);
+
+ QChar uch;
+ if (PeekMessage(&wm_char, 0, charType, charType, PM_REMOVE)) {
+ // Found a ?_CHAR
+ uch = QChar((ushort)wm_char.wParam);
+ if (msgType == WM_SYSKEYDOWN && uch.isLetter() && (msg.lParam & KF_ALTDOWN))
+ uch = uch.toLower(); // (See doc of WM_SYSCHAR) Alt-letter
+ if (!code && !uch.row())
+ code = asciiToKeycode(uch.cell(), state);
+ }
+
+ // Special handling for the WM_IME_KEYDOWN message. Microsoft IME (Korean) will not
+ // generate a WM_IME_CHAR message corresponding to this message. We might get wrong
+ // results, if we map this virtual key-code directly (for eg '?' US layouts). So try
+ // to find the correct key using the current message parameters & keyboard state.
+ if (uch.isNull() && msgType == WM_IME_KEYDOWN) {
+ BYTE keyState[256];
+ wchar_t newKey[3] = {0};
+ GetKeyboardState(keyState);
+ int val = ToUnicode(vk_key, scancode, keyState, newKey, 2, 0);
+ if (val == 1) {
+ uch = QChar(newKey[0]);
+ } else {
+ // If we are still not able to find a unicode key, pass the WM_IME_KEYDOWN
+ // message to DefWindowProc() for generating a proper WM_KEYDOWN.
+ return false;
+ }
+ }
+
+ // If no ?_CHAR was found in the queue; deduct character from the ?_KEYDOWN parameters
+ if (uch.isNull()) {
+ if (msg.wParam == VK_DELETE) {
+ uch = QChar(QLatin1Char(0x7f)); // Windows doesn't know this one.
+ } else {
+ if (msgType != WM_SYSKEYDOWN || !code) {
+ UINT map = MapVirtualKey(msg.wParam, 2);
+ // If the high bit of the return value is set, it's a deadkey
+ if (!(map & 0x80000000))
+ uch = QChar((ushort)map);
+ }
+ }
+ if (!code && !uch.row())
+ code = asciiToKeycode(uch.cell(), state);
+ }
+
+ // Special handling of global Windows hotkeys
+ if (state == Qt::AltModifier) {
+ switch (code) {
+ case Qt::Key_Escape:
+ case Qt::Key_Tab:
+ case Qt::Key_Enter:
+ case Qt::Key_F4:
+ return false; // Send the event on to Windows
+ case Qt::Key_Space:
+ // do not pass this key to windows, we will process it ourselves
+ qt_show_system_menu(widget->window());
+ return true;
+ default:
+ break;
+ }
+ }
+
+ // Map SHIFT + Tab to SHIFT + BackTab, QShortcutMap knows about this translation
+ if (code == Qt::Key_Tab && (state & Qt::ShiftModifier) == Qt::ShiftModifier)
+ code = Qt::Key_Backtab;
+
+ // If we have a record, it means that the key is already pressed, the state is the same
+ // so, we have an auto-repeating key
+ if (rec) {
+ if (code < Qt::Key_Shift || code > Qt::Key_ScrollLock) {
+ k0 = q->sendKeyEvent(widget, grab, QEvent::KeyRelease, code,
+ Qt::KeyboardModifier(state), rec->text, true, 0,
+ scancode, msg.wParam, nModifiers);
+ k1 = q->sendKeyEvent(widget, grab, QEvent::KeyPress, code,
+ Qt::KeyboardModifier(state), rec->text, true, 0,
+ scancode, msg.wParam, nModifiers);
+ }
+ }
+ // No record of the key being previous pressed, so we now send a QEvent::KeyPress event,
+ // and store the key data into our records.
+ else {
+ QString text;
+ if (!uch.isNull())
+ text += uch;
+ char a = uch.row() ? 0 : uch.cell();
+ key_recorder.storeKey(msg.wParam, a, state, text);
+ k0 = q->sendKeyEvent(widget, grab, QEvent::KeyPress, code, Qt::KeyboardModifier(state),
+ text, false, 0, scancode, msg.wParam, nModifiers);
+
+ bool store = true;
+ // Alt+<alphanumerical> go to the Win32 menu system if unhandled by Qt
+#if !defined(Q_OS_WINCE)
+ if (msgType == WM_SYSKEYDOWN && !k0 && a) {
+ HWND parent = GetParent(widget->internalWinId());
+ while (parent) {
+ if (GetMenu(parent)) {
+ SendMessage(parent, WM_SYSCOMMAND, SC_KEYMENU, a);
+ store = false;
+ k0 = true;
+ break;
+ }
+ parent = GetParent(parent);
+ }
+ }
+#endif
+ if (!store)
+ key_recorder.findKey(msg.wParam, true);
+ }
+ }
+
+ // KEYUP -----------------------------------------------------------------------------------
+ else {
+ // Try to locate the key in our records, and remove it if it exists.
+ // The key may not be in our records if, for example, the down event was handled by
+ // win32 natively, or our window gets focus while a key is already press, but now gets
+ // the key release event.
+ KeyRecord* rec = key_recorder.findKey(msg.wParam, true);
+ if (!rec && !(code == Qt::Key_Shift
+ || code == Qt::Key_Control
+ || code == Qt::Key_Meta
+ || code == Qt::Key_Alt)) {
+ // Someone ate the key down event
+ } else {
+ if (!code)
+ code = asciiToKeycode(rec->ascii ? rec->ascii : msg.wParam, state);
+
+ // Map SHIFT + Tab to SHIFT + BackTab, QShortcutMap knows about this translation
+ if (code == Qt::Key_Tab && (state & Qt::ShiftModifier) == Qt::ShiftModifier)
+ code = Qt::Key_Backtab;
+
+ k0 = q->sendKeyEvent(widget, grab, QEvent::KeyRelease, code, Qt::KeyboardModifier(state),
+ (rec ? rec->text : QString()), false, 0, scancode, msg.wParam, nModifiers);
+
+ // don't pass Alt to Windows unless we are embedded in a non-Qt window
+#if !defined(Q_OS_WINCE)
+ if (code == Qt::Key_Alt) {
+ k0 = true;
+ HWND parent = GetParent(widget->internalWinId());
+ while (parent) {
+ if (!QWidget::find(parent) && GetMenu(parent)) {
+ k0 = false;
+ break;
+ }
+ parent = GetParent(parent);
+ }
+ }
+#endif
+ }
+ }
+ }
+
+ // Return true, if a QKeyEvent was sent to a widget
+ return k0 || k1;
+}
+
+
+// QKeyMapper (Windows) implementation -------------------------------------------------[ start ]---
+
+bool QKeyMapper::sendKeyEvent(QWidget *widget, bool grab,
+ QEvent::Type type, int code, Qt::KeyboardModifiers modifiers,
+ const QString &text, bool autorepeat, int count,
+ quint32 nativeScanCode, quint32 nativeVirtualKey, quint32 nativeModifiers,
+ bool *)
+{
+#if defined(Q_OS_WINCE)
+ Q_UNUSED(grab);
+#endif
+ Q_UNUSED(count);
+#if defined QT3_SUPPORT && !defined(QT_NO_SHORTCUT)
+ if (type == QEvent::KeyPress
+ && !grab
+ && QApplicationPrivate::instance()->use_compat()) {
+ // send accel events if the keyboard is not grabbed
+ QKeyEventEx a(type, code, modifiers,
+ text, autorepeat, qMax(1, int(text.length())),
+ nativeScanCode, nativeVirtualKey, nativeModifiers);
+ if (QApplicationPrivate::instance()->qt_tryAccelEvent(widget, &a))
+ return true;
+ }
+#else
+ Q_UNUSED(grab);
+#endif
+ if (!widget->isEnabled())
+ return false;
+
+ QKeyEventEx e(type, code, modifiers,
+ text, autorepeat, qMax(1, int(text.length())),
+ nativeScanCode, nativeVirtualKey, nativeModifiers);
+ QETWidget::sendSpontaneousEvent(widget, &e);
+
+ if (!isModifierKey(code)
+ && modifiers == Qt::AltModifier
+ && ((code >= Qt::Key_A && code <= Qt::Key_Z) || (code >= Qt::Key_0 && code <= Qt::Key_9))
+ && type == QEvent::KeyPress
+ && !e.isAccepted())
+ QApplication::beep(); // Emulate windows behavior
+
+ return e.isAccepted();
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/kernel/qmime_win.cpp b/src/widgets/platforms/win/qmime_win.cpp
index c974d53163..c974d53163 100644
--- a/src/gui/kernel/qmime_win.cpp
+++ b/src/widgets/platforms/win/qmime_win.cpp
diff --git a/src/gui/kernel/qole_win.cpp b/src/widgets/platforms/win/qole_win.cpp
index 1e1a672ac5..1e1a672ac5 100644
--- a/src/gui/kernel/qole_win.cpp
+++ b/src/widgets/platforms/win/qole_win.cpp
diff --git a/src/gui/painting/qpaintdevice_win.cpp b/src/widgets/platforms/win/qpaintdevice_win.cpp
index a6d79d8341..a6d79d8341 100644
--- a/src/gui/painting/qpaintdevice_win.cpp
+++ b/src/widgets/platforms/win/qpaintdevice_win.cpp
diff --git a/src/widgets/platforms/win/qpixmap_win.cpp b/src/widgets/platforms/win/qpixmap_win.cpp
new file mode 100644
index 0000000000..c5adb48f5d
--- /dev/null
+++ b/src/widgets/platforms/win/qpixmap_win.cpp
@@ -0,0 +1,477 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qpixmap.h"
+#include "qpixmap_raster_p.h"
+
+#include "qbitmap.h"
+#include "qimage.h"
+#include "qwidget.h"
+#include "qpainter.h"
+#include "qdatastream.h"
+#include "qbuffer.h"
+#include "qapplication.h"
+#include "qevent.h"
+#include "qfile.h"
+#include "qfileinfo.h"
+#include "qdatetime.h"
+#include "qpixmapcache.h"
+#include "qimagereader.h"
+#include "qimagewriter.h"
+#include "qdebug.h"
+#include "qt_windows.h"
+
+#if defined(Q_WS_WINCE)
+#include <winbase.h>
+#include "qguifunctions_wince.h"
+extern bool qt_wince_is_high_dpi();
+extern bool qt_wince_is_pocket_pc();
+#endif
+
+#ifndef CAPTUREBLT
+#define CAPTUREBLT ((DWORD)0x40000000)
+#endif
+
+QT_BEGIN_NAMESPACE
+
+QPixmap QPixmap::grabWindow(WId winId, int x, int y, int w, int h )
+{
+ RECT r;
+ GetClientRect(winId, &r);
+
+ if (w < 0) w = r.right - r.left;
+ if (h < 0) h = r.bottom - r.top;
+
+#ifdef Q_WS_WINCE_WM
+ if (qt_wince_is_pocket_pc()) {
+ QWidget *widget = QWidget::find(winId);
+ if (qobject_cast<QDesktopWidget *>(widget)) {
+ RECT rect = {0,0,0,0};
+ AdjustWindowRectEx(&rect, WS_BORDER | WS_CAPTION, FALSE, 0);
+ int magicNumber = qt_wince_is_high_dpi() ? 4 : 2;
+ y += rect.top - magicNumber;
+ }
+ }
+#endif
+
+ // Create and setup bitmap
+ HDC display_dc = GetDC(0);
+ HDC bitmap_dc = CreateCompatibleDC(display_dc);
+ HBITMAP bitmap = CreateCompatibleBitmap(display_dc, w, h);
+ HGDIOBJ null_bitmap = SelectObject(bitmap_dc, bitmap);
+
+ // copy data
+ HDC window_dc = GetDC(winId);
+ BitBlt(bitmap_dc, 0, 0, w, h, window_dc, x, y, SRCCOPY
+#ifndef Q_WS_WINCE
+ | CAPTUREBLT
+#endif
+ );
+
+ // clean up all but bitmap
+ ReleaseDC(winId, window_dc);
+ SelectObject(bitmap_dc, null_bitmap);
+ DeleteDC(bitmap_dc);
+
+ QPixmap pixmap = QPixmap::fromWinHBITMAP(bitmap);
+
+ DeleteObject(bitmap);
+ ReleaseDC(0, display_dc);
+
+ return pixmap;
+}
+
+HBITMAP QPixmap::toWinHBITMAP(HBitmapFormat format) const
+{
+ if (isNull())
+ return 0;
+
+ HBITMAP bitmap = 0;
+ if (data->classId() == QPlatformPixmap::RasterClass) {
+ QRasterPlatformPixmap* d = static_cast<QRasterPlatformPixmap*>(data.data());
+ int w = d->image.width();
+ int h = d->image.height();
+
+ HDC display_dc = GetDC(0);
+
+ // Define the header
+ BITMAPINFO bmi;
+ memset(&bmi, 0, sizeof(bmi));
+ bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bmi.bmiHeader.biWidth = w;
+ bmi.bmiHeader.biHeight = -h;
+ bmi.bmiHeader.biPlanes = 1;
+ bmi.bmiHeader.biBitCount = 32;
+ bmi.bmiHeader.biCompression = BI_RGB;
+ bmi.bmiHeader.biSizeImage = w * h * 4;
+
+ // Create the pixmap
+ uchar *pixels = 0;
+ bitmap = CreateDIBSection(display_dc, &bmi, DIB_RGB_COLORS, (void **) &pixels, 0, 0);
+ ReleaseDC(0, display_dc);
+ if (!bitmap) {
+ qErrnoWarning("QPixmap::toWinHBITMAP(), failed to create dibsection");
+ return 0;
+ }
+ if (!pixels) {
+ qErrnoWarning("QPixmap::toWinHBITMAP(), did not allocate pixel data");
+ return 0;
+ }
+
+ // Copy over the data
+ QImage::Format imageFormat = QImage::Format_ARGB32;
+ if (format == NoAlpha)
+ imageFormat = QImage::Format_RGB32;
+ else if (format == PremultipliedAlpha)
+ imageFormat = QImage::Format_ARGB32_Premultiplied;
+ const QImage image = d->image.convertToFormat(imageFormat);
+ int bytes_per_line = w * 4;
+ for (int y=0; y<h; ++y)
+ memcpy(pixels + y * bytes_per_line, image.scanLine(y), bytes_per_line);
+
+ } else {
+ QPlatformPixmap *data = new QRasterPlatformPixmap(depth() == 1 ?
+ QPlatformPixmap::BitmapType : QPlatformPixmap::PixmapType);
+ data->fromImage(toImage(), Qt::AutoColor);
+ return QPixmap(data).toWinHBITMAP(format);
+ }
+ return bitmap;
+}
+
+QPixmap QPixmap::fromWinHBITMAP(HBITMAP bitmap, HBitmapFormat format)
+{
+ // Verify size
+ BITMAP bitmap_info;
+ memset(&bitmap_info, 0, sizeof(BITMAP));
+
+ int res = GetObject(bitmap, sizeof(BITMAP), &bitmap_info);
+ if (!res) {
+ qErrnoWarning("QPixmap::fromWinHBITMAP(), failed to get bitmap info");
+ return QPixmap();
+ }
+ int w = bitmap_info.bmWidth;
+ int h = bitmap_info.bmHeight;
+
+ BITMAPINFO bmi;
+ memset(&bmi, 0, sizeof(bmi));
+ bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bmi.bmiHeader.biWidth = w;
+ bmi.bmiHeader.biHeight = -h;
+ bmi.bmiHeader.biPlanes = 1;
+ bmi.bmiHeader.biBitCount = 32;
+ bmi.bmiHeader.biCompression = BI_RGB;
+ bmi.bmiHeader.biSizeImage = w * h * 4;
+
+ QImage result;
+ // Get bitmap bits
+ uchar *data = (uchar *) qMalloc(bmi.bmiHeader.biSizeImage);
+
+ HDC display_dc = GetDC(0);
+ if (GetDIBits(display_dc, bitmap, 0, h, data, &bmi, DIB_RGB_COLORS)) {
+
+ QImage::Format imageFormat = QImage::Format_ARGB32_Premultiplied;
+ uint mask = 0;
+ if (format == NoAlpha) {
+ imageFormat = QImage::Format_RGB32;
+ mask = 0xff000000;
+ }
+
+ // Create image and copy data into image.
+ QImage image(w, h, imageFormat);
+ if (!image.isNull()) { // failed to alloc?
+ int bytes_per_line = w * sizeof(QRgb);
+ for (int y=0; y<h; ++y) {
+ QRgb *dest = (QRgb *) image.scanLine(y);
+ const QRgb *src = (const QRgb *) (data + y * bytes_per_line);
+ for (int x=0; x<w; ++x) {
+ const uint pixel = src[x];
+ if ((pixel & 0xff000000) == 0 && (pixel & 0x00ffffff) != 0)
+ dest[x] = pixel | 0xff000000;
+ else
+ dest[x] = pixel | mask;
+ }
+ }
+ }
+ result = image;
+ } else {
+ qWarning("QPixmap::fromWinHBITMAP(), failed to get bitmap bits");
+ }
+ ReleaseDC(0, display_dc);
+ qFree(data);
+ return fromImage(result);
+}
+
+HBITMAP qt_createIconMask(const QBitmap &bitmap)
+{
+ QImage bm = bitmap.toImage().convertToFormat(QImage::Format_Mono);
+ int w = bm.width();
+ int h = bm.height();
+ int bpl = ((w+15)/16)*2; // bpl, 16 bit alignment
+ uchar *bits = new uchar[bpl*h];
+ bm.invertPixels();
+ for (int y=0; y<h; y++)
+ memcpy(bits+y*bpl, bm.scanLine(y), bpl);
+ HBITMAP hbm = CreateBitmap(w, h, 1, 1, bits);
+ delete [] bits;
+ return hbm;
+}
+
+HICON QPixmap::toWinHICON() const
+{
+ QBitmap maskBitmap = mask();
+ if (maskBitmap.isNull()) {
+ maskBitmap= QBitmap(size());
+ maskBitmap.fill(Qt::color1);
+ }
+
+ ICONINFO ii;
+ ii.fIcon = true;
+ ii.hbmMask = qt_createIconMask(maskBitmap);
+ ii.hbmColor = toWinHBITMAP(QPixmap::Alpha);
+ ii.xHotspot = 0;
+ ii.yHotspot = 0;
+
+ HICON hIcon = CreateIconIndirect(&ii);
+
+ DeleteObject(ii.hbmColor);
+ DeleteObject(ii.hbmMask);
+
+ return hIcon;
+}
+
+#ifdef Q_WS_WIN
+#ifndef Q_WS_WINCE
+
+static QImage qt_fromWinHBITMAP(HDC hdc, HBITMAP bitmap, int w, int h)
+{
+ BITMAPINFO bmi;
+ memset(&bmi, 0, sizeof(bmi));
+ bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bmi.bmiHeader.biWidth = w;
+ bmi.bmiHeader.biHeight = -h;
+ bmi.bmiHeader.biPlanes = 1;
+ bmi.bmiHeader.biBitCount = 32;
+ bmi.bmiHeader.biCompression = BI_RGB;
+ bmi.bmiHeader.biSizeImage = w * h * 4;
+
+ QImage image(w, h, QImage::Format_ARGB32_Premultiplied);
+ if (image.isNull())
+ return image;
+
+ // Get bitmap bits
+ uchar *data = (uchar *) qMalloc(bmi.bmiHeader.biSizeImage);
+
+ if (GetDIBits(hdc, bitmap, 0, h, data, &bmi, DIB_RGB_COLORS)) {
+ // Create image and copy data into image.
+ for (int y=0; y<h; ++y) {
+ void *dest = (void *) image.scanLine(y);
+ void *src = data + y * image.bytesPerLine();
+ memcpy(dest, src, image.bytesPerLine());
+ }
+ } else {
+ qWarning("qt_fromWinHBITMAP(), failed to get bitmap bits");
+ }
+ qFree(data);
+
+ return image;
+}
+
+QPixmap QPixmap::fromWinHICON(HICON icon)
+{
+ bool foundAlpha = false;
+ HDC screenDevice = GetDC(0);
+ HDC hdc = CreateCompatibleDC(screenDevice);
+ ReleaseDC(0, screenDevice);
+
+ ICONINFO iconinfo;
+ bool result = GetIconInfo(icon, &iconinfo); //x and y Hotspot describes the icon center
+ if (!result)
+ qWarning("QPixmap::fromWinHICON(), failed to GetIconInfo()");
+
+ int w = iconinfo.xHotspot * 2;
+ int h = iconinfo.yHotspot * 2;
+
+ BITMAPINFOHEADER bitmapInfo;
+ bitmapInfo.biSize = sizeof(BITMAPINFOHEADER);
+ bitmapInfo.biWidth = w;
+ bitmapInfo.biHeight = h;
+ bitmapInfo.biPlanes = 1;
+ bitmapInfo.biBitCount = 32;
+ bitmapInfo.biCompression = BI_RGB;
+ bitmapInfo.biSizeImage = 0;
+ bitmapInfo.biXPelsPerMeter = 0;
+ bitmapInfo.biYPelsPerMeter = 0;
+ bitmapInfo.biClrUsed = 0;
+ bitmapInfo.biClrImportant = 0;
+ DWORD* bits;
+
+ HBITMAP winBitmap = CreateDIBSection(hdc, (BITMAPINFO*)&bitmapInfo, DIB_RGB_COLORS, (VOID**)&bits, NULL, 0);
+ HGDIOBJ oldhdc = (HBITMAP)SelectObject(hdc, winBitmap);
+ DrawIconEx( hdc, 0, 0, icon, iconinfo.xHotspot * 2, iconinfo.yHotspot * 2, 0, 0, DI_NORMAL);
+ QImage image = qt_fromWinHBITMAP(hdc, winBitmap, w, h);
+
+ for (int y = 0 ; y < h && !foundAlpha ; y++) {
+ QRgb *scanLine= reinterpret_cast<QRgb *>(image.scanLine(y));
+ for (int x = 0; x < w ; x++) {
+ if (qAlpha(scanLine[x]) != 0) {
+ foundAlpha = true;
+ break;
+ }
+ }
+ }
+ if (!foundAlpha) {
+ //If no alpha was found, we use the mask to set alpha values
+ DrawIconEx( hdc, 0, 0, icon, w, h, 0, 0, DI_MASK);
+ QImage mask = qt_fromWinHBITMAP(hdc, winBitmap, w, h);
+
+ for (int y = 0 ; y < h ; y++){
+ QRgb *scanlineImage = reinterpret_cast<QRgb *>(image.scanLine(y));
+ QRgb *scanlineMask = mask.isNull() ? 0 : reinterpret_cast<QRgb *>(mask.scanLine(y));
+ for (int x = 0; x < w ; x++){
+ if (scanlineMask && qRed(scanlineMask[x]) != 0)
+ scanlineImage[x] = 0; //mask out this pixel
+ else
+ scanlineImage[x] |= 0xff000000; // set the alpha channel to 255
+ }
+ }
+ }
+ //dispose resources created by iconinfo call
+ DeleteObject(iconinfo.hbmMask);
+ DeleteObject(iconinfo.hbmColor);
+
+ SelectObject(hdc, oldhdc); //restore state
+ DeleteObject(winBitmap);
+ DeleteDC(hdc);
+ return QPixmap::fromImage(image);
+}
+#else //ifndef Q_WS_WINCE
+QPixmap QPixmap::fromWinHICON(HICON icon)
+{
+ HDC screenDevice = GetDC(0);
+ HDC hdc = CreateCompatibleDC(screenDevice);
+ ReleaseDC(0, screenDevice);
+
+ ICONINFO iconinfo;
+ bool result = GetIconInfo(icon, &iconinfo);
+ if (!result)
+ qWarning("QPixmap::fromWinHICON(), failed to GetIconInfo()");
+
+ int w = 0;
+ int h = 0;
+ if (!iconinfo.xHotspot || !iconinfo.yHotspot) {
+ // We could not retrieve the icon size via GetIconInfo,
+ // so we try again using the icon bitmap.
+ BITMAP bm;
+ int result = GetObject(iconinfo.hbmColor, sizeof(BITMAP), &bm);
+ if (!result) result = GetObject(iconinfo.hbmMask, sizeof(BITMAP), &bm);
+ if (!result) {
+ qWarning("QPixmap::fromWinHICON(), failed to retrieve icon size");
+ return QPixmap();
+ }
+ w = bm.bmWidth;
+ h = bm.bmHeight;
+ } else {
+ // x and y Hotspot describes the icon center
+ w = iconinfo.xHotspot * 2;
+ h = iconinfo.yHotspot * 2;
+ }
+ const DWORD dwImageSize = w * h * 4;
+
+ BITMAPINFO bmi;
+ memset(&bmi, 0, sizeof(bmi));
+ bmi.bmiHeader.biSize = sizeof(BITMAPINFO);
+ bmi.bmiHeader.biWidth = w;
+ bmi.bmiHeader.biHeight = -h;
+ bmi.bmiHeader.biPlanes = 1;
+ bmi.bmiHeader.biBitCount = 32;
+ bmi.bmiHeader.biCompression = BI_RGB;
+ bmi.bmiHeader.biSizeImage = dwImageSize;
+
+ uchar* bits;
+
+ HBITMAP winBitmap = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, (void**) &bits, 0, 0);
+ if (winBitmap )
+ memset(bits, 0xff, dwImageSize);
+ if (!winBitmap) {
+ qWarning("QPixmap::fromWinHICON(), failed to CreateDIBSection()");
+ return QPixmap();
+ }
+
+ HGDIOBJ oldhdc = (HBITMAP)SelectObject(hdc, winBitmap);
+ if (!DrawIconEx( hdc, 0, 0, icon, w, h, 0, 0, DI_NORMAL))
+ qWarning("QPixmap::fromWinHICON(), failed to DrawIcon()");
+
+ uint mask = 0xff000000;
+ // Create image and copy data into image.
+ QImage image(w, h, QImage::Format_ARGB32);
+
+ if (!image.isNull()) { // failed to alloc?
+ int bytes_per_line = w * sizeof(QRgb);
+ for (int y=0; y < h; ++y) {
+ QRgb *dest = (QRgb *) image.scanLine(y);
+ const QRgb *src = (const QRgb *) (bits + y * bytes_per_line);
+ for (int x=0; x < w; ++x) {
+ dest[x] = src[x];
+ }
+ }
+ }
+ if (!DrawIconEx( hdc, 0, 0, icon, w, h, 0, 0, DI_MASK))
+ qWarning("QPixmap::fromWinHICON(), failed to DrawIcon()");
+ if (!image.isNull()) { // failed to alloc?
+ int bytes_per_line = w * sizeof(QRgb);
+ for (int y=0; y < h; ++y) {
+ QRgb *dest = (QRgb *) image.scanLine(y);
+ const QRgb *src = (const QRgb *) (bits + y * bytes_per_line);
+ for (int x=0; x < w; ++x) {
+ if (!src[x])
+ dest[x] = dest[x] | mask;
+ }
+ }
+ }
+ SelectObject(hdc, oldhdc); //restore state
+ DeleteObject(winBitmap);
+ DeleteDC(hdc);
+ return QPixmap::fromImage(image);
+}
+#endif //ifndef Q_WS_WINCE
+#endif //ifdef Q_WS_WIN
+
+QT_END_NAMESPACE
diff --git a/src/gui/painting/qprintengine_win.cpp b/src/widgets/platforms/win/qprintengine_win.cpp
index 5ba33c043c..5ba33c043c 100644
--- a/src/gui/painting/qprintengine_win.cpp
+++ b/src/widgets/platforms/win/qprintengine_win.cpp
diff --git a/src/gui/painting/qprintengine_win_p.h b/src/widgets/platforms/win/qprintengine_win_p.h
index eeb097fd17..eeb097fd17 100644
--- a/src/gui/painting/qprintengine_win_p.h
+++ b/src/widgets/platforms/win/qprintengine_win_p.h
diff --git a/src/gui/painting/qprinterinfo_win.cpp b/src/widgets/platforms/win/qprinterinfo_win.cpp
index cc0cd0232d..cc0cd0232d 100644
--- a/src/gui/painting/qprinterinfo_win.cpp
+++ b/src/widgets/platforms/win/qprinterinfo_win.cpp
diff --git a/src/gui/text/qrawfont_win.cpp b/src/widgets/platforms/win/qrawfont_win.cpp
index d8aa557975..d8aa557975 100644
--- a/src/gui/text/qrawfont_win.cpp
+++ b/src/widgets/platforms/win/qrawfont_win.cpp
diff --git a/src/gui/painting/qregion_win.cpp b/src/widgets/platforms/win/qregion_win.cpp
index 57fd0858e0..57fd0858e0 100644
--- a/src/gui/painting/qregion_win.cpp
+++ b/src/widgets/platforms/win/qregion_win.cpp
diff --git a/src/gui/kernel/qsound_win.cpp b/src/widgets/platforms/win/qsound_win.cpp
index 3c77dacf2a..3c77dacf2a 100644
--- a/src/gui/kernel/qsound_win.cpp
+++ b/src/widgets/platforms/win/qsound_win.cpp
diff --git a/src/gui/kernel/qwidget_win.cpp b/src/widgets/platforms/win/qwidget_win.cpp
index 60446ddb08..60446ddb08 100644
--- a/src/gui/kernel/qwidget_win.cpp
+++ b/src/widgets/platforms/win/qwidget_win.cpp
diff --git a/src/gui/kernel/qwidget_wince.cpp b/src/widgets/platforms/win/qwidget_wince.cpp
index b16be300e7..b16be300e7 100644
--- a/src/gui/kernel/qwidget_wince.cpp
+++ b/src/widgets/platforms/win/qwidget_wince.cpp
diff --git a/src/widgets/platforms/win/qwininputcontext_p.h b/src/widgets/platforms/win/qwininputcontext_p.h
new file mode 100644
index 0000000000..c0a6ac6b6f
--- /dev/null
+++ b/src/widgets/platforms/win/qwininputcontext_p.h
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWININPUTCONTEXT_P_H
+#define QWININPUTCONTEXT_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of qinputcontext.cpp. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "QtWidgets/qinputcontext.h"
+#include "QtCore/qt_windows.h"
+
+#if !defined(IMR_RECONVERTSTRING)
+typedef struct tagRECONVERTSTRING {
+ DWORD dwSize;
+ DWORD dwVersion;
+ DWORD dwStrLen;
+ DWORD dwStrOffset;
+ DWORD dwCompStrLen;
+ DWORD dwCompStrOffset;
+ DWORD dwTargetStrLen;
+ DWORD dwTargetStrOffset;
+} RECONVERTSTRING, *PRECONVERTSTRING;
+#endif
+
+QT_BEGIN_NAMESPACE
+
+class QWinInputContext : public QInputContext
+{
+ Q_OBJECT
+public:
+ explicit QWinInputContext(QObject* parent = 0);
+ virtual ~QWinInputContext();
+
+ virtual QString identifierName() { return QLatin1String("win"); }
+ virtual QString language();
+
+ virtual void reset();
+ virtual void update();
+
+ virtual void mouseHandler(int x, QMouseEvent *event);
+ virtual bool isComposing() const;
+
+ virtual void setFocusWidget(QWidget *w);
+
+ bool startComposition();
+ bool endComposition();
+ bool composition(LPARAM lparam);
+ int reconvertString(RECONVERTSTRING *reconv);
+
+ static void TranslateMessage(const MSG *msg);
+ static LRESULT DefWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+
+ static void updateImeStatus(QWidget *w, bool hasFocus);
+ static void enablePopupChild(QWidget *w, bool e);
+ static void enable(QWidget *w, bool e);
+
+private:
+ void init();
+ bool recursionGuard;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWININPUTCONTEXT_P_H
diff --git a/src/gui/inputmethod/qwininputcontext_win.cpp b/src/widgets/platforms/win/qwininputcontext_win.cpp
index 9ec9942af8..9ec9942af8 100644
--- a/src/gui/inputmethod/qwininputcontext_win.cpp
+++ b/src/widgets/platforms/win/qwininputcontext_win.cpp
diff --git a/src/gui/kernel/qwinnativepangesturerecognizer_win.cpp b/src/widgets/platforms/win/qwinnativepangesturerecognizer_win.cpp
index 85ef0a949f..85ef0a949f 100644
--- a/src/gui/kernel/qwinnativepangesturerecognizer_win.cpp
+++ b/src/widgets/platforms/win/qwinnativepangesturerecognizer_win.cpp
diff --git a/src/gui/kernel/qwinnativepangesturerecognizer_win_p.h b/src/widgets/platforms/win/qwinnativepangesturerecognizer_win_p.h
index 4f15a82b7e..4f15a82b7e 100644
--- a/src/gui/kernel/qwinnativepangesturerecognizer_win_p.h
+++ b/src/widgets/platforms/win/qwinnativepangesturerecognizer_win_p.h
diff --git a/src/widgets/platforms/x11/qapplication_x11.cpp b/src/widgets/platforms/x11/qapplication_x11.cpp
new file mode 100644
index 0000000000..4a392d2a19
--- /dev/null
+++ b/src/widgets/platforms/x11/qapplication_x11.cpp
@@ -0,0 +1,6239 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// ### 4.0: examine Q_EXPORT's below. The respective symbols had all
+// been in use (e.g. in the KDE wm) before the introduction of a version
+// map. One might want to turn some of them into proper public API and
+// provide a proper alternative for others. See also the exports in
+// qapplication_win.cpp, which suggest a unification.
+
+#include "qplatformdefs.h"
+
+#include "qcolormap.h"
+#include "qdesktopwidget.h"
+#include "qapplication.h"
+#include "qapplication_p.h"
+#include "qcursor.h"
+#include "qwidget.h"
+#include "qbitarray.h"
+#include "qpainter.h"
+#include "qfile.h"
+#include "qpixmapcache.h"
+#include "qdatetime.h"
+#include "qtextcodec.h"
+#include "qdatastream.h"
+#include "qbuffer.h"
+#include "qsocketnotifier.h"
+#include "qsessionmanager.h"
+#include "qclipboard.h"
+#include "qwhatsthis.h"
+#include "qsettings.h"
+#include "qstylefactory.h"
+#include "qfileinfo.h"
+#include "qdir.h"
+#include "qhash.h"
+#include "qevent.h"
+#include "qevent_p.h"
+#include "qvarlengtharray.h"
+#include "qdebug.h"
+#include <private/qcrashhandler_p.h>
+#include <private/qcolor_p.h>
+#include <private/qcursor_p.h>
+#include <private/qiconloader_p.h>
+#include <qgtkstyle.h>
+#include "qstyle.h"
+#include "qmetaobject.h"
+#include "qtimer.h"
+#include "qlibrary.h"
+#include <private/qgraphicssystemfactory_p.h>
+#include "qguiplatformplugin_p.h"
+#include "qkde_p.h"
+
+#if !defined (QT_NO_TABLET)
+extern "C" {
+# define class c_class //XIproto.h has a name member named 'class' which the c++ compiler doesn't like
+# include <wacomcfg.h>
+# undef class
+}
+#endif
+
+#ifndef QT_GUI_DOUBLE_CLICK_RADIUS
+#define QT_GUI_DOUBLE_CLICK_RADIUS 5
+#endif
+
+
+//#define ALIEN_DEBUG
+
+#if !defined(QT_NO_GLIB)
+# include "qguieventdispatcher_glib_p.h"
+#endif
+#include "qeventdispatcher_x11_p.h"
+#include <private/qpaintengine_x11_p.h>
+
+#include <private/qkeymapper_p.h>
+
+// Input method stuff
+#ifndef QT_NO_IM
+#include "qinputcontext.h"
+#include "qinputcontextfactory.h"
+#endif // QT_NO_IM
+
+#ifndef QT_NO_XFIXES
+#include <X11/extensions/Xfixes.h>
+#endif // QT_NO_XFIXES
+
+#include "qt_x11_p.h"
+#include "qx11info_x11.h"
+
+#define XK_MISCELLANY
+#include <X11/keysymdef.h>
+#if !defined(QT_NO_XINPUT)
+#include <X11/extensions/XI.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <locale.h>
+
+#include "qwidget_p.h"
+
+#include <private/qbackingstore_p.h>
+
+#ifdef QT_RX71_MULTITOUCH
+# include <qsocketnotifier.h>
+# include <linux/input.h>
+# include <errno.h>
+#endif
+
+#if _POSIX_VERSION+0 < 200112L && !defined(Q_OS_BSD4)
+# define QT_NO_UNSETENV
+#endif
+
+QT_BEGIN_NAMESPACE
+
+//#define X_NOT_BROKEN
+#ifdef X_NOT_BROKEN
+// Some X libraries are built with setlocale #defined to _Xsetlocale,
+// even though library users are then built WITHOUT such a definition.
+// This creates a problem - Qt might setlocale() one value, but then
+// X looks and doesn't see the value Qt set. The solution here is to
+// implement _Xsetlocale just in case X calls it - redirecting it to
+// the real libC version.
+//
+# ifndef setlocale
+extern "C" char *_Xsetlocale(int category, const char *locale);
+char *_Xsetlocale(int category, const char *locale)
+{
+ //qDebug("_Xsetlocale(%d,%s),category,locale");
+ return setlocale(category,locale);
+}
+# endif // setlocale
+#endif // X_NOT_BROKEN
+
+/* Warning: if you modify this string, modify the list of atoms in qt_x11_p.h as well! */
+static const char * x11_atomnames = {
+ // window-manager <-> client protocols
+ "WM_PROTOCOLS\0"
+ "WM_DELETE_WINDOW\0"
+ "WM_TAKE_FOCUS\0"
+ "_NET_WM_PING\0"
+ "_NET_WM_CONTEXT_HELP\0"
+ "_NET_WM_SYNC_REQUEST\0"
+ "_NET_WM_SYNC_REQUEST_COUNTER\0"
+
+ // ICCCM window state
+ "WM_STATE\0"
+ "WM_CHANGE_STATE\0"
+
+ // Session management
+ "WM_CLIENT_LEADER\0"
+ "WM_WINDOW_ROLE\0"
+ "SM_CLIENT_ID\0"
+
+ // Clipboard
+ "CLIPBOARD\0"
+ "INCR\0"
+ "TARGETS\0"
+ "MULTIPLE\0"
+ "TIMESTAMP\0"
+ "SAVE_TARGETS\0"
+ "CLIP_TEMPORARY\0"
+ "_QT_SELECTION\0"
+ "_QT_CLIPBOARD_SENTINEL\0"
+ "_QT_SELECTION_SENTINEL\0"
+ "CLIPBOARD_MANAGER\0"
+
+ "RESOURCE_MANAGER\0"
+
+ "_XSETROOT_ID\0"
+
+ "_QT_SCROLL_DONE\0"
+ "_QT_INPUT_ENCODING\0"
+
+ "_MOTIF_WM_HINTS\0"
+
+ "DTWM_IS_RUNNING\0"
+ "ENLIGHTENMENT_DESKTOP\0"
+ "_DT_SAVE_MODE\0"
+ "_SGI_DESKS_MANAGER\0"
+
+ // EWMH (aka NETWM)
+ "_NET_SUPPORTED\0"
+ "_NET_VIRTUAL_ROOTS\0"
+ "_NET_WORKAREA\0"
+
+ "_NET_MOVERESIZE_WINDOW\0"
+ "_NET_WM_MOVERESIZE\0"
+
+ "_NET_WM_NAME\0"
+ "_NET_WM_ICON_NAME\0"
+ "_NET_WM_ICON\0"
+
+ "_NET_WM_PID\0"
+
+ "_NET_WM_WINDOW_OPACITY\0"
+
+ "_NET_WM_STATE\0"
+ "_NET_WM_STATE_ABOVE\0"
+ "_NET_WM_STATE_BELOW\0"
+ "_NET_WM_STATE_FULLSCREEN\0"
+ "_NET_WM_STATE_MAXIMIZED_HORZ\0"
+ "_NET_WM_STATE_MAXIMIZED_VERT\0"
+ "_NET_WM_STATE_MODAL\0"
+ "_NET_WM_STATE_STAYS_ON_TOP\0"
+ "_NET_WM_STATE_DEMANDS_ATTENTION\0"
+
+ "_NET_WM_USER_TIME\0"
+ "_NET_WM_USER_TIME_WINDOW\0"
+ "_NET_WM_FULL_PLACEMENT\0"
+
+ "_NET_WM_WINDOW_TYPE\0"
+ "_NET_WM_WINDOW_TYPE_DESKTOP\0"
+ "_NET_WM_WINDOW_TYPE_DOCK\0"
+ "_NET_WM_WINDOW_TYPE_TOOLBAR\0"
+ "_NET_WM_WINDOW_TYPE_MENU\0"
+ "_NET_WM_WINDOW_TYPE_UTILITY\0"
+ "_NET_WM_WINDOW_TYPE_SPLASH\0"
+ "_NET_WM_WINDOW_TYPE_DIALOG\0"
+ "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU\0"
+ "_NET_WM_WINDOW_TYPE_POPUP_MENU\0"
+ "_NET_WM_WINDOW_TYPE_TOOLTIP\0"
+ "_NET_WM_WINDOW_TYPE_NOTIFICATION\0"
+ "_NET_WM_WINDOW_TYPE_COMBO\0"
+ "_NET_WM_WINDOW_TYPE_DND\0"
+ "_NET_WM_WINDOW_TYPE_NORMAL\0"
+ "_KDE_NET_WM_WINDOW_TYPE_OVERRIDE\0"
+
+ "_KDE_NET_WM_FRAME_STRUT\0"
+
+ "_NET_STARTUP_INFO\0"
+ "_NET_STARTUP_INFO_BEGIN\0"
+
+ "_NET_SUPPORTING_WM_CHECK\0"
+
+ "_NET_WM_CM_S0\0"
+
+ "_NET_SYSTEM_TRAY_VISUAL\0"
+
+ "_NET_ACTIVE_WINDOW\0"
+
+ // Property formats
+ "COMPOUND_TEXT\0"
+ "TEXT\0"
+ "UTF8_STRING\0"
+
+ // xdnd
+ "XdndEnter\0"
+ "XdndPosition\0"
+ "XdndStatus\0"
+ "XdndLeave\0"
+ "XdndDrop\0"
+ "XdndFinished\0"
+ "XdndTypeList\0"
+ "XdndActionList\0"
+
+ "XdndSelection\0"
+
+ "XdndAware\0"
+ "XdndProxy\0"
+
+ "XdndActionCopy\0"
+ "XdndActionLink\0"
+ "XdndActionMove\0"
+ "XdndActionPrivate\0"
+
+ // Motif DND
+ "_MOTIF_DRAG_AND_DROP_MESSAGE\0"
+ "_MOTIF_DRAG_INITIATOR_INFO\0"
+ "_MOTIF_DRAG_RECEIVER_INFO\0"
+ "_MOTIF_DRAG_WINDOW\0"
+ "_MOTIF_DRAG_TARGETS\0"
+
+ "XmTRANSFER_SUCCESS\0"
+ "XmTRANSFER_FAILURE\0"
+
+ // Xkb
+ "_XKB_RULES_NAMES\0"
+
+ // XEMBED
+ "_XEMBED\0"
+ "_XEMBED_INFO\0"
+
+ // Wacom old. (before version 0.10)
+ "Wacom Stylus\0"
+ "Wacom Cursor\0"
+ "Wacom Eraser\0"
+
+ // Tablet
+ "STYLUS\0"
+ "ERASER\0"
+};
+
+Q_WIDGETS_EXPORT QX11Data *qt_x11Data = 0;
+
+/*****************************************************************************
+ Internal variables and functions
+ *****************************************************************************/
+static const char *appName = 0; // application name
+static const char *appClass = 0; // application class
+static const char *appFont = 0; // application font
+static const char *appBGCol = 0; // application bg color
+static const char *appFGCol = 0; // application fg color
+static const char *appBTNCol = 0; // application btn color
+static const char *mwGeometry = 0; // main widget geometry
+static const char *mwTitle = 0; // main widget title
+char *qt_ximServer = 0; // XIM Server will connect to
+static bool appSync = false; // X11 synchronization
+#if defined(QT_DEBUG)
+static bool appNoGrab = false; // X11 grabbing enabled
+static bool appDoGrab = false; // X11 grabbing override (gdb)
+#endif
+static bool app_save_rootinfo = false; // save root info
+static bool app_do_modal = false; // modal mode
+static Window curWin = 0; // current window
+
+
+// function to update the workarea of the screen - in qdesktopwidget_x11.cpp
+extern void qt_desktopwidget_update_workarea();
+
+// Function to change the window manager state (from qwidget_x11.cpp)
+extern void qt_change_net_wm_state(const QWidget *w, bool set, Atom one, Atom two = 0);
+
+// modifier masks for alt, meta, super, hyper, and mode_switch - detected when the application starts
+// and/or keyboard layout changes
+uchar qt_alt_mask = 0;
+uchar qt_meta_mask = 0;
+uchar qt_super_mask = 0;
+uchar qt_hyper_mask = 0;
+uchar qt_mode_switch_mask = 0;
+
+// flags for extensions for special Languages, currently only for RTL languages
+bool qt_use_rtl_extensions = false;
+
+static Window mouseActWindow = 0; // window where mouse is
+static Qt::MouseButton mouseButtonPressed = Qt::NoButton; // last mouse button pressed
+static Qt::MouseButtons mouseButtonState = Qt::NoButton; // mouse button state
+static Time mouseButtonPressTime = 0; // when was a button pressed
+static short mouseXPos, mouseYPos; // mouse pres position in act window
+static short mouseGlobalXPos, mouseGlobalYPos; // global mouse press position
+
+extern QWidgetList *qt_modal_stack; // stack of modal widgets
+
+// window where mouse buttons have been pressed
+static Window pressed_window = XNone;
+
+// popup control
+static bool replayPopupMouseEvent = false;
+static bool popupGrabOk;
+
+bool qt_sm_blockUserInput = false; // session management
+
+Q_WIDGETS_EXPORT int qt_xfocusout_grab_counter = 0;
+
+#if !defined (QT_NO_TABLET)
+Q_GLOBAL_STATIC(QTabletDeviceDataList, tablet_devices)
+QTabletDeviceDataList *qt_tablet_devices()
+{
+ return tablet_devices();
+}
+
+extern bool qt_tabletChokeMouse;
+#endif
+
+typedef bool(*QX11FilterFunction)(XEvent *event);
+
+Q_GLOBAL_STATIC(QList<QX11FilterFunction>, x11Filters)
+
+Q_WIDGETS_EXPORT void qt_installX11EventFilter(QX11FilterFunction func)
+{
+ Q_ASSERT(func);
+
+ if (QList<QX11FilterFunction> *list = x11Filters())
+ list->append(func);
+}
+
+Q_WIDGETS_EXPORT void qt_removeX11EventFilter(QX11FilterFunction func)
+{
+ Q_ASSERT(func);
+
+ if (QList<QX11FilterFunction> *list = x11Filters())
+ list->removeOne(func);
+}
+
+
+static bool qt_x11EventFilter(XEvent* ev)
+{
+ long unused;
+ if (qApp->filterEvent(ev, &unused))
+ return true;
+ if (const QList<QX11FilterFunction> *list = x11Filters()) {
+ for (QList<QX11FilterFunction>::const_iterator it = list->constBegin(); it != list->constEnd(); ++it) {
+ if ((*it)(ev))
+ return true;
+ }
+ }
+
+ return qApp->x11EventFilter(ev);
+}
+
+#if !defined(QT_NO_XIM)
+XIMStyle qt_xim_preferred_style = 0;
+#endif
+int qt_ximComposingKeycode=0;
+QTextCodec * qt_input_mapper = 0;
+
+extern bool qt_check_clipboard_sentinel(); //def in qclipboard_x11.cpp
+extern bool qt_check_selection_sentinel(); //def in qclipboard_x11.cpp
+extern bool qt_xfixes_clipboard_changed(Window clipboardOwner, Time timestamp); //def in qclipboard_x11.cpp
+extern bool qt_xfixes_selection_changed(Window selectionOwner, Time timestamp); //def in qclipboard_x11.cpp
+
+static void qt_save_rootinfo();
+Q_WIDGETS_EXPORT bool qt_try_modal(QWidget *, XEvent *);
+
+QWidget *qt_button_down = 0; // last widget to be pressed with the mouse
+QPointer<QWidget> qt_last_mouse_receiver = 0;
+static QWidget *qt_popup_down = 0; // popup that contains the pressed widget
+
+extern bool qt_xdnd_dragging;
+
+// gui or non-gui from qapplication.cpp
+extern bool qt_is_gui_used;
+
+/*!
+ \internal
+ Try to resolve a \a symbol from \a library with the version specified
+ by \a vernum.
+
+ Note that, in the case of the Xfixes library, \a vernum is not the same as
+ \c XFIXES_MAJOR - it is a part of soname and may differ from the Xfixes
+ version.
+*/
+static void* qt_load_library_runtime(const char *library, int vernum,
+ int highestVernum, const char *symbol)
+{
+ QList<int> versions;
+ // we try to load in the following order:
+ // explicit version -> the default one -> (from the highest (highestVernum) to the lowest (vernum) )
+ if (vernum != -1)
+ versions << vernum;
+ versions << -1;
+ if (vernum != -1) {
+ for(int i = highestVernum; i > vernum; --i)
+ versions << i;
+ }
+ Q_FOREACH(int version, versions) {
+ QLatin1String libName(library);
+ QLibrary xfixesLib(libName, version);
+ void *ptr = xfixesLib.resolve(symbol);
+ if (ptr)
+ return ptr;
+ }
+ return 0;
+}
+
+#ifndef QT_NO_XINPUT
+# ifdef QT_RUNTIME_XINPUT
+# define XINPUT_LOAD_RUNTIME(vernum, symbol, symbol_type) \
+ (symbol_type)qt_load_library_runtime("libXi", vernum, 6, #symbol);
+# define XINPUT_LOAD(symbol) \
+ XINPUT_LOAD_RUNTIME(1, symbol, Ptr##symbol)
+# else // not runtime XInput
+# define XINPUT_LOAD(symbol) symbol
+# endif // QT_RUNTIME_XINPUT
+#else // not using Xinput at all
+# define XINPUT_LOAD(symbol) 0
+#endif // QT_NO_XINPUT
+
+#ifndef QT_NO_XFIXES
+# ifdef QT_RUNTIME_XFIXES
+# define XFIXES_LOAD_RUNTIME(vernum, symbol, symbol_type) \
+ (symbol_type)qt_load_library_runtime("libXfixes", vernum, 4, #symbol);
+# define XFIXES_LOAD_V1(symbol) \
+ XFIXES_LOAD_RUNTIME(1, symbol, Ptr##symbol)
+# define XFIXES_LOAD_V2(symbol) \
+ XFIXES_LOAD_RUNTIME(2, symbol, Ptr##symbol)
+
+# else // not runtime Xfixes
+
+# if XFIXES_MAJOR >= 2
+# define XFIXES_LOAD_V1(symbol) symbol
+# define XFIXES_LOAD_V2(symbol) symbol
+# elif XFIXES_MAJOR >= 1
+# define XFIXES_LOAD_V1(symbol) symbol
+# define XFIXES_LOAD_V2(symbol) 0
+# else
+# error Unsupported version of Xfixes
+# endif
+# endif // QT_RUNTIME_XFIXES
+#else // not using Xfixes at all
+# define XFIXES_LOAD_V1(symbol) 0
+# define XFIXES_LOAD_V2(symbol) 0
+#endif // QT_NO_XFIXES
+
+#ifndef QT_NO_XFIXES
+
+struct qt_xfixes_selection_event_data
+{
+ // which selection to filter out.
+ Atom selection;
+};
+
+#if defined(Q_C_CALLBACKS)
+extern "C" {
+#endif
+
+static Bool qt_xfixes_scanner(Display*, XEvent *event, XPointer arg)
+{
+ qt_xfixes_selection_event_data *data =
+ reinterpret_cast<qt_xfixes_selection_event_data*>(arg);
+ if (event->type == X11->xfixes_eventbase + XFixesSelectionNotify) {
+ XFixesSelectionNotifyEvent *xfixes_event = reinterpret_cast<XFixesSelectionNotifyEvent*>(event);
+ if (xfixes_event->selection == data->selection)
+ return true;
+ }
+ return false;
+}
+
+#if defined(Q_C_CALLBACKS)
+}
+#endif
+
+#endif // QT_NO_XFIXES
+
+class QETWidget : public QWidget // event translator widget
+{
+public:
+ QWidgetPrivate* d_func() { return QWidget::d_func(); }
+ bool translateMouseEvent(const XEvent *);
+ void translatePaintEvent(const XEvent *);
+ bool translateConfigEvent(const XEvent *);
+ bool translateCloseEvent(const XEvent *);
+ bool translateScrollDoneEvent(const XEvent *);
+ bool translateWheelEvent(int global_x, int global_y, int delta, Qt::MouseButtons buttons,
+ Qt::KeyboardModifiers modifiers, Qt::Orientation orient);
+#if !defined (QT_NO_TABLET)
+ bool translateXinputEvent(const XEvent*, QTabletDeviceData *tablet);
+#endif
+ bool translatePropertyEvent(const XEvent *);
+
+ void doDeferredMap()
+ {
+ Q_ASSERT(testAttribute(Qt::WA_WState_Created));
+ if (!testAttribute(Qt::WA_Resized)) {
+ adjustSize();
+ setAttribute(Qt::WA_Resized, false);
+ }
+
+ /*
+ workaround for WM's that throw away ConfigureRequests from the following:
+
+ window->hide();
+ window->move(x, y); // could also be resize(), move()+resize(), or setGeometry()
+ window->show();
+ */
+ QRect r = geometry();
+
+ XMoveResizeWindow(X11->display,
+ internalWinId(),
+ r.x(),
+ r.y(),
+ r.width(),
+ r.height());
+
+ // static gravity!
+ XSizeHints sh;
+ long unused;
+ XGetWMNormalHints(X11->display, internalWinId(), &sh, &unused);
+ sh.flags |= USPosition | PPosition | USSize | PSize | PWinGravity;
+ sh.x = r.x();
+ sh.y = r.y();
+ sh.width = r.width();
+ sh.height = r.height();
+ sh.win_gravity = StaticGravity;
+ XSetWMNormalHints(X11->display, internalWinId(), &sh);
+
+ setAttribute(Qt::WA_Mapped);
+ if (testAttribute(Qt::WA_DontShowOnScreen))
+ return;
+ d_func()->topData()->waitingForMapNotify = 1;
+ XMapWindow(X11->display, internalWinId());
+ }
+};
+
+
+void QApplicationPrivate::createEventDispatcher()
+{
+ Q_Q(QApplication);
+#if !defined(QT_NO_GLIB)
+ if (qgetenv("QT_NO_GLIB").isEmpty() && QEventDispatcherGlib::versionSupported())
+ eventDispatcher = (q->type() != QApplication::Tty
+ ? new QGuiEventDispatcherGlib(q)
+ : new QEventDispatcherGlib(q));
+ else
+#endif
+ eventDispatcher = (q->type() != QApplication::Tty
+ ? new QEventDispatcherX11(q)
+ : new QEventDispatcherUNIX(q));
+}
+
+/*****************************************************************************
+ Default X error handlers
+ *****************************************************************************/
+
+#if defined(Q_C_CALLBACKS)
+extern "C" {
+#endif
+
+static int (*original_x_errhandler)(Display *dpy, XErrorEvent *);
+static int (*original_xio_errhandler)(Display *dpy);
+
+static int qt_x_errhandler(Display *dpy, XErrorEvent *err)
+{
+ if (X11->display != dpy) {
+ // only handle X errors for our display
+ return 0;
+ }
+
+ switch (err->error_code) {
+ case BadAtom:
+ if (err->request_code == 20 /* X_GetProperty */
+ && (err->resourceid == XA_RESOURCE_MANAGER
+ || err->resourceid == XA_RGB_DEFAULT_MAP
+ || err->resourceid == ATOM(_NET_SUPPORTED)
+ || err->resourceid == ATOM(_NET_SUPPORTING_WM_CHECK)
+ || err->resourceid == ATOM(XdndProxy)
+ || err->resourceid == ATOM(XdndAware))) {
+ // Perhaps we're running under SECURITY reduction? :/
+ return 0;
+ }
+ break;
+
+ case BadWindow:
+ if (err->request_code == 2 /* X_ChangeWindowAttributes */
+ || err->request_code == 38 /* X_QueryPointer */) {
+ for (int i = 0; i < ScreenCount(dpy); ++i) {
+ if (err->resourceid == RootWindow(dpy, i)) {
+ // Perhaps we're running under SECURITY reduction? :/
+ return 0;
+ }
+ }
+ }
+ X11->seen_badwindow = true;
+ if (err->request_code == 25 /* X_SendEvent */) {
+ for (int i = 0; i < ScreenCount(dpy); ++i) {
+ if (err->resourceid == RootWindow(dpy, i)) {
+ // Perhaps we're running under SECURITY reduction? :/
+ return 0;
+ }
+ }
+ if (X11->xdndHandleBadwindow()) {
+ qDebug("xdndHandleBadwindow returned true");
+ return 0;
+ }
+ }
+ if (X11->ignore_badwindow)
+ return 0;
+ break;
+
+ default:
+#if !defined(QT_NO_XINPUT)
+ if (err->request_code == X11->xinput_major
+ && err->error_code == (X11->xinput_errorbase + XI_BadDevice)
+ && err->minor_code == 3 /* X_OpenDevice */) {
+ return 0;
+ }
+#endif
+ break;
+ }
+
+ char errstr[256];
+ XGetErrorText( dpy, err->error_code, errstr, 256 );
+ char buffer[256];
+ char request_str[256];
+ qsnprintf(buffer, 256, "%d", err->request_code);
+ XGetErrorDatabaseText(dpy, "XRequest", buffer, "", request_str, 256);
+ if (err->request_code < 128) {
+ // X error for a normal protocol request
+ qWarning( "X Error: %s %d\n"
+ " Major opcode: %d (%s)\n"
+ " Resource id: 0x%lx",
+ errstr, err->error_code,
+ err->request_code,
+ request_str,
+ err->resourceid );
+ } else {
+ // X error for an extension request
+ const char *extensionName = 0;
+ if (err->request_code == X11->xrender_major)
+ extensionName = "RENDER";
+ else if (err->request_code == X11->xrandr_major)
+ extensionName = "RANDR";
+ else if (err->request_code == X11->xinput_major)
+ extensionName = "XInputExtension";
+ else if (err->request_code == X11->mitshm_major)
+ extensionName = "MIT-SHM";
+#ifndef QT_NO_XKB
+ else if(err->request_code == X11->xkb_major)
+ extensionName = "XKEYBOARD";
+#endif
+
+ char minor_str[256];
+ if (extensionName) {
+ qsnprintf(buffer, 256, "%s.%d", extensionName, err->minor_code);
+ XGetErrorDatabaseText(dpy, "XRequest", buffer, "", minor_str, 256);
+ } else {
+ extensionName = "Uknown extension";
+ qsnprintf(minor_str, 256, "Unknown request");
+ }
+ qWarning( "X Error: %s %d\n"
+ " Extension: %d (%s)\n"
+ " Minor opcode: %d (%s)\n"
+ " Resource id: 0x%lx",
+ errstr, err->error_code,
+ err->request_code,
+ extensionName,
+ err->minor_code,
+ minor_str,
+ err->resourceid );
+ }
+
+ // ### we really should distinguish between severe, non-severe and
+ // ### application specific errors
+
+ return 0;
+}
+
+
+static int qt_xio_errhandler(Display *)
+{
+ qWarning("%s: Fatal IO error: client killed", appName);
+ QApplicationPrivate::reset_instance_pointer();
+ exit(1);
+ //### give the application a chance for a proper shutdown instead,
+ //### exit(1) doesn't help.
+ return 0;
+}
+
+#if defined(Q_C_CALLBACKS)
+}
+#endif
+
+#ifndef QT_NO_XSYNC
+struct qt_sync_request_event_data
+{
+ WId window;
+};
+
+#if defined(Q_C_CALLBACKS)
+extern "C" {
+#endif
+
+static Bool qt_sync_request_scanner(Display*, XEvent *event, XPointer arg)
+{
+ qt_sync_request_event_data *data =
+ reinterpret_cast<qt_sync_request_event_data*>(arg);
+ if (event->type == ClientMessage &&
+ event->xany.window == data->window &&
+ event->xclient.message_type == ATOM(WM_PROTOCOLS) &&
+ (Atom)event->xclient.data.l[0] == ATOM(_NET_WM_SYNC_REQUEST)) {
+ QWidget *w = QWidget::find(event->xany.window);
+ if (QTLWExtra *tlw = ((QETWidget*)w)->d_func()->maybeTopData()) {
+ const ulong timestamp = (const ulong) event->xclient.data.l[1];
+ if (timestamp > X11->time)
+ X11->time = timestamp;
+ if (timestamp == CurrentTime || timestamp > tlw->syncRequestTimestamp) {
+ tlw->syncRequestTimestamp = timestamp;
+ tlw->newCounterValueLo = event->xclient.data.l[2];
+ tlw->newCounterValueHi = event->xclient.data.l[3];
+ }
+ }
+ return true;
+ }
+ return false;
+}
+
+#if defined(Q_C_CALLBACKS)
+}
+#endif
+#endif // QT_NO_XSYNC
+
+static void qt_x11_create_intern_atoms()
+{
+ const char *names[QX11Data::NAtoms];
+ const char *ptr = x11_atomnames;
+
+ int i = 0;
+ while (*ptr) {
+ names[i++] = ptr;
+ while (*ptr)
+ ++ptr;
+ ++ptr;
+ }
+
+ Q_ASSERT(i == QX11Data::NPredefinedAtoms);
+
+ QByteArray settings_atom_name("_QT_SETTINGS_TIMESTAMP_");
+ settings_atom_name += XDisplayName(X11->displayName);
+ names[i++] = settings_atom_name;
+
+ Q_ASSERT(i == QX11Data::NAtoms);
+#if defined(XlibSpecificationRelease) && (XlibSpecificationRelease >= 6)
+ XInternAtoms(X11->display, (char **)names, i, False, X11->atoms);
+#else
+ for (i = 0; i < QX11Data::NAtoms; ++i)
+ X11->atoms[i] = XInternAtom(X11->display, (char *)names[i], False);
+#endif
+}
+
+Q_WIDGETS_EXPORT void qt_x11_apply_settings_in_all_apps()
+{
+ QByteArray stamp;
+ QDataStream s(&stamp, QIODevice::WriteOnly);
+ s << QDateTime::currentDateTime();
+
+ XChangeProperty(QX11Info::display(), QX11Info::appRootWindow(0),
+ ATOM(_QT_SETTINGS_TIMESTAMP), ATOM(_QT_SETTINGS_TIMESTAMP), 8,
+ PropModeReplace, (unsigned char *)stamp.data(), stamp.size());
+}
+
+/*! \internal
+ apply the settings to the application
+*/
+bool QApplicationPrivate::x11_apply_settings()
+{
+ QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
+
+ settings.beginGroup(QLatin1String("Qt"));
+
+ /*
+ Qt settings. This is now they are written into the datastream.
+
+ Palette / * - QPalette
+ font - QFont
+ libraryPath - QStringList
+ style - QString
+ doubleClickInterval - int
+ keyboardInputInterval - int
+ cursorFlashTime - int
+ wheelScrollLines - int
+ colorSpec - QString
+ defaultCodec - QString
+ globalStrut/width - int
+ globalStrut/height - int
+ GUIEffects - QStringList
+ Font Substitutions/ * - QStringList
+ Font Substitutions/... - QStringList
+ */
+
+ QStringList strlist;
+ int i;
+ QPalette pal(Qt::black);
+ int groupCount = 0;
+ strlist = settings.value(QLatin1String("Palette/active")).toStringList();
+ if (!strlist.isEmpty()) {
+ ++groupCount;
+ for (i = 0; i < qMin(strlist.count(), int(QPalette::NColorRoles)); i++)
+ pal.setColor(QPalette::Active, (QPalette::ColorRole) i,
+ QColor(strlist[i]));
+ }
+ strlist = settings.value(QLatin1String("Palette/inactive")).toStringList();
+ if (!strlist.isEmpty()) {
+ ++groupCount;
+ for (i = 0; i < qMin(strlist.count(), int(QPalette::NColorRoles)); i++)
+ pal.setColor(QPalette::Inactive, (QPalette::ColorRole) i,
+ QColor(strlist[i]));
+ }
+ strlist = settings.value(QLatin1String("Palette/disabled")).toStringList();
+ if (!strlist.isEmpty()) {
+ ++groupCount;
+ for (i = 0; i < qMin(strlist.count(), int(QPalette::NColorRoles)); i++)
+ pal.setColor(QPalette::Disabled, (QPalette::ColorRole) i,
+ QColor(strlist[i]));
+ }
+
+ // ### Fix properly for 4.6
+ bool usingGtkSettings = QApplicationPrivate::app_style && QApplicationPrivate::app_style->inherits("QGtkStyle");
+ if (!usingGtkSettings) {
+ if (groupCount == QPalette::NColorGroups)
+ QApplicationPrivate::setSystemPalette(pal);
+ }
+
+ if (!appFont) {
+ // ### Fix properly for 4.6
+ if (!usingGtkSettings) {
+ QFont font(QApplication::font());
+ QString fontDescription;
+ // Override Qt font if KDE4 settings can be used
+ if (X11->desktopVersion == 4) {
+ QSettings kdeSettings(QKde::kdeHome() + QLatin1String("/share/config/kdeglobals"), QSettings::IniFormat);
+ fontDescription = kdeSettings.value(QLatin1String("font")).toString();
+ if (fontDescription.isEmpty()) {
+ // KDE stores fonts without quotes
+ fontDescription = kdeSettings.value(QLatin1String("font")).toStringList().join(QLatin1String(","));
+ }
+ }
+ if (fontDescription.isEmpty())
+ fontDescription = settings.value(QLatin1String("font")).toString();
+ if (!fontDescription .isEmpty()) {
+ font.fromString(fontDescription );
+ QApplicationPrivate::setSystemFont(font);
+ }
+ }
+ }
+
+ // read library (ie. plugin) path list
+ QString libpathkey =
+ QString::fromLatin1("%1.%2/libraryPath")
+ .arg(QT_VERSION >> 16)
+ .arg((QT_VERSION & 0xff00) >> 8);
+ QStringList pathlist = settings.value(libpathkey).toString().split(QLatin1Char(':'));
+ if (! pathlist.isEmpty()) {
+ QStringList::ConstIterator it = pathlist.constBegin();
+ while (it != pathlist.constEnd())
+ QApplication::addLibraryPath(*it++);
+ }
+
+ // read new QStyle
+ QString stylename = settings.value(QLatin1String("style")).toString();
+
+ if (stylename.isEmpty() && QApplicationPrivate::styleOverride.isNull() && X11->use_xrender) {
+ stylename = qt_guiPlatformPlugin()->styleName();
+ }
+
+ static QString currentStyleName = stylename;
+ if (QCoreApplication::startingUp()) {
+ if (!stylename.isEmpty() && QApplicationPrivate::styleOverride.isNull())
+ QApplicationPrivate::styleOverride = stylename;
+ } else {
+ if (currentStyleName != stylename) {
+ currentStyleName = stylename;
+ QApplication::setStyle(stylename);
+ }
+ }
+
+ int num =
+ settings.value(QLatin1String("doubleClickInterval"),
+ QApplication::doubleClickInterval()).toInt();
+ QApplication::setDoubleClickInterval(num);
+
+ num =
+ settings.value(QLatin1String("cursorFlashTime"),
+ QApplication::cursorFlashTime()).toInt();
+ QApplication::setCursorFlashTime(num);
+
+#ifndef QT_NO_WHEELEVENT
+ num =
+ settings.value(QLatin1String("wheelScrollLines"),
+ QApplication::wheelScrollLines()).toInt();
+ QApplication::setWheelScrollLines(num);
+#endif
+
+ QString colorspec = settings.value(QLatin1String("colorSpec"),
+ QVariant(QLatin1String("default"))).toString();
+ if (colorspec == QLatin1String("normal"))
+ QApplication::setColorSpec(QApplication::NormalColor);
+ else if (colorspec == QLatin1String("custom"))
+ QApplication::setColorSpec(QApplication::CustomColor);
+ else if (colorspec == QLatin1String("many"))
+ QApplication::setColorSpec(QApplication::ManyColor);
+ else if (colorspec != QLatin1String("default"))
+ colorspec = QLatin1String("default");
+
+ QString defaultcodec = settings.value(QLatin1String("defaultCodec"),
+ QVariant(QLatin1String("none"))).toString();
+ if (defaultcodec != QLatin1String("none")) {
+ QTextCodec *codec = QTextCodec::codecForName(defaultcodec.toLatin1());
+ if (codec)
+ QTextCodec::setCodecForTr(codec);
+ }
+
+ int w = settings.value(QLatin1String("globalStrut/width")).toInt();
+ int h = settings.value(QLatin1String("globalStrut/height")).toInt();
+ QSize strut(w, h);
+ if (strut.isValid())
+ QApplication::setGlobalStrut(strut);
+
+ QStringList effects = settings.value(QLatin1String("GUIEffects")).toStringList();
+ QApplication::setEffectEnabled(Qt::UI_General,
+ effects.contains(QLatin1String("general")));
+ QApplication::setEffectEnabled(Qt::UI_AnimateMenu,
+ effects.contains(QLatin1String("animatemenu")));
+ QApplication::setEffectEnabled(Qt::UI_FadeMenu,
+ effects.contains(QLatin1String("fademenu")));
+ QApplication::setEffectEnabled(Qt::UI_AnimateCombo,
+ effects.contains(QLatin1String("animatecombo")));
+ QApplication::setEffectEnabled(Qt::UI_AnimateTooltip,
+ effects.contains(QLatin1String("animatetooltip")));
+ QApplication::setEffectEnabled(Qt::UI_FadeTooltip,
+ effects.contains(QLatin1String("fadetooltip")));
+ QApplication::setEffectEnabled(Qt::UI_AnimateToolBox,
+ effects.contains(QLatin1String("animatetoolbox")));
+
+ if (!X11->has_fontconfig) {
+ settings.beginGroup(QLatin1String("Font Substitutions"));
+ QStringList fontsubs = settings.childKeys();
+ if (!fontsubs.isEmpty()) {
+ QStringList::Iterator it = fontsubs.begin();
+ for (; it != fontsubs.end(); ++it) {
+ QString fam = *it;
+ QStringList subs = settings.value(fam).toStringList();
+ QFont::insertSubstitutions(fam, subs);
+ }
+ }
+ settings.endGroup();
+ }
+
+ qt_use_rtl_extensions =
+ settings.value(QLatin1String("useRtlExtensions"), false).toBool();
+
+#ifndef QT_NO_XIM
+ if (qt_xim_preferred_style == 0) {
+ QString ximInputStyle = settings.value(QLatin1String("XIMInputStyle"),
+ QVariant(QLatin1String("on the spot"))).toString().toLower();
+ if (ximInputStyle == QLatin1String("on the spot"))
+ qt_xim_preferred_style = XIMPreeditCallbacks | XIMStatusNothing;
+ else if (ximInputStyle == QLatin1String("over the spot"))
+ qt_xim_preferred_style = XIMPreeditPosition | XIMStatusNothing;
+ else if (ximInputStyle == QLatin1String("off the spot"))
+ qt_xim_preferred_style = XIMPreeditArea | XIMStatusArea;
+ else if (ximInputStyle == QLatin1String("root"))
+ qt_xim_preferred_style = XIMPreeditNothing | XIMStatusNothing;
+ }
+#endif
+ QStringList inputMethods = QInputContextFactory::keys();
+ if (inputMethods.size() > 2 && inputMethods.contains(QLatin1String("imsw-multi"))) {
+ X11->default_im = QLatin1String("imsw-multi");
+ } else {
+ X11->default_im = settings.value(QLatin1String("DefaultInputMethod"),
+ QLatin1String("xim")).toString();
+ }
+
+ settings.endGroup(); // Qt
+
+ return true;
+}
+
+
+/*! \internal
+ Resets the QApplication::instance() pointer to zero
+*/
+void QApplicationPrivate::reset_instance_pointer()
+{ QApplication::self = 0; }
+
+
+// read the _QT_INPUT_ENCODING property and apply the settings to
+// the application
+static void qt_set_input_encoding()
+{
+ Atom type;
+ int format;
+ ulong nitems, after = 1;
+ unsigned char *data = 0;
+
+ int e = XGetWindowProperty(X11->display, QX11Info::appRootWindow(),
+ ATOM(_QT_INPUT_ENCODING), 0, 1024,
+ False, XA_STRING, &type, &format, &nitems,
+ &after, &data);
+ if (e != Success || !nitems || type == XNone) {
+ // Always use the locale codec, since we have no examples of non-local
+ // XIMs, and since we cannot get a sensible answer about the encoding
+ // from the XIM.
+ qt_input_mapper = QTextCodec::codecForLocale();
+
+ } else {
+ if (!qstricmp((char *)data, "locale"))
+ qt_input_mapper = QTextCodec::codecForLocale();
+ else
+ qt_input_mapper = QTextCodec::codecForName((char *)data);
+ // make sure we have an input codec
+ if(!qt_input_mapper)
+ qt_input_mapper = QTextCodec::codecForName("ISO 8859-1");
+ }
+ if (qt_input_mapper && qt_input_mapper->mibEnum() == 11) // 8859-8
+ qt_input_mapper = QTextCodec::codecForName("ISO 8859-8-I");
+ if(data)
+ XFree((char *)data);
+}
+
+// set font, foreground and background from x11 resources. The
+// arguments may override the resource settings.
+static void qt_set_x11_resources(const char* font = 0, const char* fg = 0,
+ const char* bg = 0, const char* button = 0)
+{
+
+ QString resFont, resFG, resBG, resButton, resEF, sysFont, selectBackground, selectForeground;
+
+ QApplication::setEffectEnabled(Qt::UI_General, false);
+ QApplication::setEffectEnabled(Qt::UI_AnimateMenu, false);
+ QApplication::setEffectEnabled(Qt::UI_FadeMenu, false);
+ QApplication::setEffectEnabled(Qt::UI_AnimateCombo, false);
+ QApplication::setEffectEnabled(Qt::UI_AnimateTooltip, false);
+ QApplication::setEffectEnabled(Qt::UI_FadeTooltip, false);
+ QApplication::setEffectEnabled(Qt::UI_AnimateToolBox, false);
+
+ bool paletteAlreadySet = false;
+ if (QApplication::desktopSettingsAware()) {
+ // first, read from settings
+ QApplicationPrivate::x11_apply_settings();
+ // the call to QApplication::style() below creates the system
+ // palette, which breaks the logic after the RESOURCE_MANAGER
+ // loop... so I have to save this value to be able to use it later
+ paletteAlreadySet = (QApplicationPrivate::sys_pal != 0);
+
+ // second, parse the RESOURCE_MANAGER property
+ int format;
+ ulong nitems, after = 1;
+ QString res;
+ long offset = 0;
+ Atom type = XNone;
+
+ while (after > 0) {
+ uchar *data = 0;
+ if (XGetWindowProperty(X11->display, QX11Info::appRootWindow(0),
+ ATOM(RESOURCE_MANAGER),
+ offset, 8192, False, AnyPropertyType,
+ &type, &format, &nitems, &after,
+ &data) != Success) {
+ res = QString();
+ break;
+ }
+ if (type == XA_STRING)
+ res += QString::fromLatin1((char*)data);
+ else
+ res += QString::fromLocal8Bit((char*)data);
+ offset += 2048; // offset is in 32bit quantities... 8192/4 == 2048
+ if (data)
+ XFree((char *)data);
+ }
+
+ QString key, value;
+ int l = 0, r;
+ QString apn = QString::fromLocal8Bit(appName);
+ QString apc = QString::fromLocal8Bit(appClass);
+ int apnl = apn.length();
+ int apcl = apc.length();
+ int resl = res.length();
+
+ while (l < resl) {
+ r = res.indexOf(QLatin1Char('\n'), l);
+ if (r < 0)
+ r = resl;
+ while (res.at(l).isSpace())
+ l++;
+ bool mine = false;
+ QChar sc = res.at(l + 1);
+ if (res.at(l) == QLatin1Char('*') &&
+ (sc == QLatin1Char('f') || sc == QLatin1Char('b') || sc == QLatin1Char('g') ||
+ sc == QLatin1Char('F') || sc == QLatin1Char('B') || sc == QLatin1Char('G') ||
+ sc == QLatin1Char('s') || sc == QLatin1Char('S')
+ // capital T only, since we're looking for "Text.selectSomething"
+ || sc == QLatin1Char('T'))) {
+ // OPTIMIZED, since we only want "*[fbgsT].."
+ QString item = res.mid(l, r - l).simplified();
+ int i = item.indexOf(QLatin1Char(':'));
+ key = item.left(i).trimmed().mid(1).toLower();
+ value = item.right(item.length() - i - 1).trimmed();
+ mine = true;
+ } else if ((apnl && res.at(l) == apn.at(0)) || (appClass && apcl && res.at(l) == apc.at(0))) {
+ if (res.mid(l,apnl) == apn && (res.at(l+apnl) == QLatin1Char('.')
+ || res.at(l+apnl) == QLatin1Char('*'))) {
+ QString item = res.mid(l, r - l).simplified();
+ int i = item.indexOf(QLatin1Char(':'));
+ key = item.left(i).trimmed().mid(apnl+1).toLower();
+ value = item.right(item.length() - i - 1).trimmed();
+ mine = true;
+ } else if (res.mid(l,apcl) == apc && (res.at(l+apcl) == QLatin1Char('.')
+ || res.at(l+apcl) == QLatin1Char('*'))) {
+ QString item = res.mid(l, r - l).simplified();
+ int i = item.indexOf(QLatin1Char(':'));
+ key = item.left(i).trimmed().mid(apcl+1).toLower();
+ value = item.right(item.length() - i - 1).trimmed();
+ mine = true;
+ }
+ }
+
+ if (mine) {
+ if (!font && key == QLatin1String("systemfont"))
+ sysFont = value.left(value.lastIndexOf(QLatin1Char(':')));
+ if (!font && key == QLatin1String("font"))
+ resFont = value;
+ else if (!fg && !paletteAlreadySet) {
+ if (key == QLatin1String("foreground"))
+ resFG = value;
+ else if (!bg && key == QLatin1String("background"))
+ resBG = value;
+ else if (!bg && !button && key == QLatin1String("button.background"))
+ resButton = value;
+ else if (key == QLatin1String("text.selectbackground")) {
+ selectBackground = value;
+ } else if (key == QLatin1String("text.selectforeground")) {
+ selectForeground = value;
+ }
+ } else if (key == QLatin1String("guieffects"))
+ resEF = value;
+ // NOTE: if you add more, change the [fbg] stuff above
+ }
+
+ l = r + 1;
+ }
+ }
+ if (!sysFont.isEmpty())
+ resFont = sysFont;
+ if (resFont.isEmpty())
+ resFont = QString::fromLocal8Bit(font);
+ if (resFG.isEmpty())
+ resFG = QString::fromLocal8Bit(fg);
+ if (resBG.isEmpty())
+ resBG = QString::fromLocal8Bit(bg);
+ if (resButton.isEmpty())
+ resButton = QString::fromLocal8Bit(button);
+ if (!resFont.isEmpty()
+ && !X11->has_fontconfig
+ && !QApplicationPrivate::sys_font) {
+ // set application font
+ QFont fnt;
+ fnt.setRawName(resFont);
+
+ // the font we get may actually be an alias for another font,
+ // so we reset the application font to the real font info.
+ if (! fnt.exactMatch()) {
+ QFontInfo fontinfo(fnt);
+ fnt.setFamily(fontinfo.family());
+ fnt.setRawMode(fontinfo.rawMode());
+
+ if (! fnt.rawMode()) {
+ fnt.setItalic(fontinfo.italic());
+ fnt.setWeight(fontinfo.weight());
+ fnt.setUnderline(fontinfo.underline());
+ fnt.setStrikeOut(fontinfo.strikeOut());
+ fnt.setStyleHint(fontinfo.styleHint());
+
+ if (fnt.pointSize() <= 0 && fnt.pixelSize() <= 0) {
+ // size is all wrong... fix it
+ qreal pointSize = fontinfo.pixelSize() * 72. / (float) QX11Info::appDpiY();
+ if (pointSize <= 0)
+ pointSize = 12;
+ fnt.setPointSize(qRound(pointSize));
+ }
+ }
+ }
+
+ QApplicationPrivate::setSystemFont(fnt);
+ }
+ // QGtkStyle sets it's own system palette
+ bool gtkStyle = QApplicationPrivate::app_style && QApplicationPrivate::app_style->inherits("QGtkStyle");
+ bool kdeColors = (QApplication::desktopSettingsAware() && X11->desktopEnvironment == DE_KDE);
+ if (!gtkStyle && (kdeColors || (button || !resBG.isEmpty() || !resFG.isEmpty()))) {// set app colors
+ bool allowX11ColorNames = QColor::allowX11ColorNames();
+ QColor::setAllowX11ColorNames(true);
+
+ (void) QApplication::style(); // trigger creation of application style and system palettes
+ QColor btn;
+ QColor bg;
+ QColor fg;
+ QColor bfg;
+ QColor wfg;
+ if (!resBG.isEmpty())
+ bg = QColor(resBG);
+ if (!bg.isValid())
+ bg = QApplicationPrivate::sys_pal->color(QPalette::Active, QPalette::Window);
+
+ if (!resFG.isEmpty())
+ fg = QColor(resFG);
+ if (!fg.isValid())
+ fg = QApplicationPrivate::sys_pal->color(QPalette::Active, QPalette::WindowText);
+
+ if (!resButton.isEmpty())
+ btn = QColor(resButton);
+ else if (!resBG.isEmpty())
+ btn = bg;
+ if (!btn.isValid())
+ btn = QApplicationPrivate::sys_pal->color(QPalette::Active, QPalette::Button);
+
+ int h,s,v;
+ fg.getHsv(&h,&s,&v);
+ QColor base = Qt::white;
+ bool bright_mode = false;
+ if (v >= 255 - 50) {
+ base = btn.darker(150);
+ bright_mode = true;
+ }
+
+ QPalette pal(fg, btn, btn.lighter(125), btn.darker(130), btn.darker(120), wfg.isValid() ? wfg : fg, Qt::white, base, bg);
+ QColor disabled((fg.red() + btn.red()) / 2,
+ (fg.green() + btn.green())/ 2,
+ (fg.blue() + btn.blue()) / 2);
+ pal.setColorGroup(QPalette::Disabled, disabled, btn, btn.lighter(125),
+ btn.darker(130), btn.darker(150), disabled, Qt::white, Qt::white, bg);
+
+ QColor highlight, highlightText;
+ if (!selectBackground.isEmpty() && !selectForeground.isEmpty()) {
+ highlight = QColor(selectBackground);
+ highlightText = QColor(selectForeground);
+ }
+
+ if (highlight.isValid() && highlightText.isValid()) {
+ pal.setColor(QPalette::Highlight, highlight);
+ pal.setColor(QPalette::HighlightedText, highlightText);
+
+ // calculate disabled colors by removing saturation
+ highlight.setHsv(highlight.hue(), 0, highlight.value(), highlight.alpha());
+ highlightText.setHsv(highlightText.hue(), 0, highlightText.value(), highlightText.alpha());
+ pal.setColor(QPalette::Disabled, QPalette::Highlight, highlight);
+ pal.setColor(QPalette::Disabled, QPalette::HighlightedText, highlightText);
+ } else if (bright_mode) {
+ pal.setColor(QPalette::HighlightedText, base);
+ pal.setColor(QPalette::Highlight, Qt::white);
+ pal.setColor(QPalette::Disabled, QPalette::HighlightedText, base);
+ pal.setColor(QPalette::Disabled, QPalette::Highlight, Qt::white);
+ } else {
+ pal.setColor(QPalette::HighlightedText, Qt::white);
+ pal.setColor(QPalette::Highlight, Qt::darkBlue);
+ pal.setColor(QPalette::Disabled, QPalette::HighlightedText, Qt::white);
+ pal.setColor(QPalette::Disabled, QPalette::Highlight, Qt::darkBlue);
+ }
+
+ pal = qt_guiPlatformPlugin()->palette().resolve(pal);
+ QApplicationPrivate::setSystemPalette(pal);
+ QColor::setAllowX11ColorNames(allowX11ColorNames);
+ }
+
+ if (!resEF.isEmpty()) {
+ QStringList effects = resEF.split(QLatin1Char(' '));
+ QApplication::setEffectEnabled(Qt::UI_General, effects.contains(QLatin1String("general")));
+ QApplication::setEffectEnabled(Qt::UI_AnimateMenu,
+ effects.contains(QLatin1String("animatemenu")));
+ QApplication::setEffectEnabled(Qt::UI_FadeMenu,
+ effects.contains(QLatin1String("fademenu")));
+ QApplication::setEffectEnabled(Qt::UI_AnimateCombo,
+ effects.contains(QLatin1String("animatecombo")));
+ QApplication::setEffectEnabled(Qt::UI_AnimateTooltip,
+ effects.contains(QLatin1String("animatetooltip")));
+ QApplication::setEffectEnabled(Qt::UI_FadeTooltip,
+ effects.contains(QLatin1String("fadetooltip")));
+ QApplication::setEffectEnabled(Qt::UI_AnimateToolBox,
+ effects.contains(QLatin1String("animatetoolbox")));
+ }
+
+ QIconLoader::instance()->updateSystemTheme();
+}
+
+
+// update the supported array
+static void qt_get_net_supported()
+{
+ Atom type;
+ int format;
+ long offset = 0;
+ unsigned long nitems, after;
+ unsigned char *data = 0;
+
+ int e = XGetWindowProperty(X11->display, QX11Info::appRootWindow(),
+ ATOM(_NET_SUPPORTED), 0, 0,
+ False, XA_ATOM, &type, &format, &nitems, &after, &data);
+ if (data)
+ XFree(data);
+
+ if (X11->net_supported_list)
+ delete [] X11->net_supported_list;
+ X11->net_supported_list = 0;
+
+ if (e == Success && type == XA_ATOM && format == 32) {
+ QBuffer ts;
+ ts.open(QIODevice::WriteOnly);
+
+ while (after > 0) {
+ XGetWindowProperty(X11->display, QX11Info::appRootWindow(),
+ ATOM(_NET_SUPPORTED), offset, 1024,
+ False, XA_ATOM, &type, &format, &nitems, &after, &data);
+
+ if (type == XA_ATOM && format == 32) {
+ ts.write(reinterpret_cast<char *>(data), nitems * sizeof(long));
+ offset += nitems;
+ } else
+ after = 0;
+ if (data)
+ XFree(data);
+ }
+
+ // compute nitems
+ QByteArray buffer(ts.buffer());
+ nitems = buffer.size() / sizeof(Atom);
+ X11->net_supported_list = new Atom[nitems + 1];
+ Atom *a = (Atom *) buffer.data();
+ uint i;
+ for (i = 0; i < nitems; i++)
+ X11->net_supported_list[i] = a[i];
+ X11->net_supported_list[nitems] = 0;
+ }
+}
+
+
+bool QX11Data::isSupportedByWM(Atom atom)
+{
+ if (!X11->net_supported_list)
+ return false;
+
+ bool supported = false;
+ int i = 0;
+ while (X11->net_supported_list[i] != 0) {
+ if (X11->net_supported_list[i++] == atom) {
+ supported = true;
+ break;
+ }
+ }
+
+ return supported;
+}
+
+
+// update the virtual roots array
+static void qt_get_net_virtual_roots()
+{
+ if (X11->net_virtual_root_list)
+ delete [] X11->net_virtual_root_list;
+ X11->net_virtual_root_list = 0;
+
+ if (!X11->isSupportedByWM(ATOM(_NET_VIRTUAL_ROOTS)))
+ return;
+
+ Atom type;
+ int format;
+ long offset = 0;
+ unsigned long nitems, after;
+ unsigned char *data;
+
+ int e = XGetWindowProperty(X11->display, QX11Info::appRootWindow(),
+ ATOM(_NET_VIRTUAL_ROOTS), 0, 0,
+ False, XA_ATOM, &type, &format, &nitems, &after, &data);
+ if (data)
+ XFree(data);
+
+ if (e == Success && type == XA_ATOM && format == 32) {
+ QBuffer ts;
+ ts.open(QIODevice::WriteOnly);
+
+ while (after > 0) {
+ XGetWindowProperty(X11->display, QX11Info::appRootWindow(),
+ ATOM(_NET_VIRTUAL_ROOTS), offset, 1024,
+ False, XA_ATOM, &type, &format, &nitems, &after, &data);
+
+ if (type == XA_ATOM && format == 32) {
+ ts.write(reinterpret_cast<char *>(data), nitems * 4);
+ offset += nitems;
+ } else
+ after = 0;
+ if (data)
+ XFree(data);
+ }
+
+ // compute nitems
+ QByteArray buffer(ts.buffer());
+ nitems = buffer.size() / sizeof(Window);
+ X11->net_virtual_root_list = new Window[nitems + 1];
+ Window *a = (Window *) buffer.data();
+ uint i;
+ for (i = 0; i < nitems; i++)
+ X11->net_virtual_root_list[i] = a[i];
+ X11->net_virtual_root_list[nitems] = 0;
+ }
+}
+
+void qt_net_remove_user_time(QWidget *tlw)
+{
+ Q_ASSERT(tlw);
+ QTLWExtra *extra = tlw->d_func()->maybeTopData();
+ if (extra && extra->userTimeWindow) {
+ Q_ASSERT(tlw->internalWinId());
+ XDeleteProperty(X11->display, tlw->internalWinId(), ATOM(_NET_WM_USER_TIME_WINDOW));
+ XDestroyWindow(X11->display, extra->userTimeWindow);
+ extra->userTimeWindow = 0;
+ }
+}
+
+void qt_net_update_user_time(QWidget *tlw, unsigned long timestamp)
+{
+ Q_ASSERT(tlw);
+ Q_ASSERT(tlw->isWindow());
+ Q_ASSERT(tlw->testAttribute(Qt::WA_WState_Created));
+ QTLWExtra *extra = tlw->d_func()->topData();
+ WId wid = tlw->internalWinId();
+ const bool isSupportedByWM = X11->isSupportedByWM(ATOM(_NET_WM_USER_TIME_WINDOW));
+ if (extra->userTimeWindow || isSupportedByWM) {
+ if (!extra->userTimeWindow) {
+ extra->userTimeWindow = XCreateSimpleWindow(X11->display,
+ tlw->internalWinId(),
+ -1, -1, 1, 1, 0, 0, 0);
+ wid = extra->userTimeWindow;
+ XChangeProperty(X11->display, tlw->internalWinId(), ATOM(_NET_WM_USER_TIME_WINDOW),
+ XA_WINDOW, 32, PropModeReplace,
+ (unsigned char *)&wid, 1);
+ XDeleteProperty(X11->display, tlw->internalWinId(), ATOM(_NET_WM_USER_TIME));
+ } else if (!isSupportedByWM) {
+ // WM no longer supports it, then we should remove the
+ // _NET_WM_USER_TIME_WINDOW atom.
+ qt_net_remove_user_time(tlw);
+ } else {
+ wid = extra->userTimeWindow;
+ }
+ }
+ XChangeProperty(X11->display, wid, ATOM(_NET_WM_USER_TIME),
+ XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &timestamp, 1);
+}
+
+static void qt_check_focus_model()
+{
+ Window fw = XNone;
+ int unused;
+ XGetInputFocus(X11->display, &fw, &unused);
+ if (fw == PointerRoot)
+ X11->focus_model = QX11Data::FM_PointerRoot;
+ else
+ X11->focus_model = QX11Data::FM_Other;
+}
+
+#ifndef QT_NO_TABLET
+
+#if !defined (Q_OS_IRIX)
+// from include/Xwacom.h
+# define XWACOM_PARAM_TOOLID 322
+# define XWACOM_PARAM_TOOLSERIAL 323
+
+typedef WACOMCONFIG * (*PtrWacomConfigInit) (Display*, WACOMERRORFUNC);
+typedef WACOMDEVICE * (*PtrWacomConfigOpenDevice) (WACOMCONFIG*, const char*);
+typedef int *(*PtrWacomConfigGetRawParam) (WACOMDEVICE*, int, int*, int, unsigned*);
+typedef int (*PtrWacomConfigCloseDevice) (WACOMDEVICE *);
+typedef void (*PtrWacomConfigTerm) (WACOMCONFIG *);
+
+static PtrWacomConfigInit ptrWacomConfigInit = 0;
+static PtrWacomConfigOpenDevice ptrWacomConfigOpenDevice = 0;
+static PtrWacomConfigGetRawParam ptrWacomConfigGetRawParam = 0;
+static PtrWacomConfigCloseDevice ptrWacomConfigCloseDevice = 0;
+static PtrWacomConfigTerm ptrWacomConfigTerm = 0;
+Q_GLOBAL_STATIC(QByteArray, wacomDeviceName)
+#endif
+
+#endif
+
+/*****************************************************************************
+ qt_init() - initializes Qt for X11
+ *****************************************************************************/
+
+#if !defined(QT_NO_FONTCONFIG)
+static void getXDefault(const char *group, const char *key, int *val)
+{
+ char *str = XGetDefault(X11->display, group, key);
+ if (str) {
+ char *end = 0;
+ int v = strtol(str, &end, 0);
+ if (str != end)
+ *val = v;
+ // otherwise use fontconfig to convert the string to integer
+ else
+ FcNameConstant((FcChar8 *) str, val);
+ }
+}
+
+static void getXDefault(const char *group, const char *key, double *val)
+{
+ char *str = XGetDefault(X11->display, group, key);
+ if (str) {
+ bool ok;
+ double v = QByteArray(str).toDouble(&ok);
+ if (ok)
+ *val = v;
+ }
+}
+
+static void getXDefault(const char *group, const char *key, bool *val)
+{
+ char *str = XGetDefault(X11->display, group, key);
+ if (str) {
+ char c = str[0];
+ if (isupper((int)c))
+ c = tolower(c);
+ if (c == 't' || c == 'y' || c == '1')
+ *val = true;
+ else if (c == 'f' || c == 'n' || c == '0')
+ *val = false;
+ if (c == 'o') {
+ c = str[1];
+ if (isupper((int)c))
+ c = tolower(c);
+ if (c == 'n')
+ *val = true;
+ if (c == 'f')
+ *val = false;
+ }
+ }
+}
+#endif
+
+// ### This should be static but it isn't because of the friend declaration
+// ### in qpaintdevice.h which then should have a static too but can't have
+// ### it because "storage class specifiers invalid in friend function
+// ### declarations" :-) Ideas anyone?
+void qt_init(QApplicationPrivate *priv, int,
+ Display *display, Qt::HANDLE visual, Qt::HANDLE colormap)
+{
+ X11 = new QX11Data;
+ X11->display = display;
+ X11->displayName = 0;
+ X11->foreignDisplay = (display != 0);
+ X11->focus_model = -1;
+
+ // RANDR
+ X11->use_xrandr = false;
+ X11->xrandr_major = 0;
+ X11->xrandr_eventbase = 0;
+ X11->xrandr_errorbase = 0;
+
+ // RENDER
+ X11->use_xrender = false;
+ X11->xrender_major = 0;
+ X11->xrender_version = 0;
+
+ // XFIXES
+ X11->use_xfixes = false;
+ X11->xfixes_major = 0;
+ X11->xfixes_eventbase = 0;
+ X11->xfixes_errorbase = 0;
+
+ // XInputExtension
+ X11->use_xinput = false;
+ X11->xinput_major = 0;
+ X11->xinput_eventbase = 0;
+ X11->xinput_errorbase = 0;
+
+ X11->use_xkb = false;
+ X11->xkb_major = 0;
+ X11->xkb_eventbase = 0;
+ X11->xkb_errorbase = 0;
+
+ // MIT-SHM
+ X11->use_mitshm = false;
+ X11->use_mitshm_pixmaps = false;
+ X11->mitshm_major = 0;
+
+ X11->sip_serial = 0;
+ X11->net_supported_list = 0;
+ X11->net_virtual_root_list = 0;
+ X11->wm_client_leader = 0;
+ X11->screens = 0;
+ X11->argbVisuals = 0;
+ X11->argbColormaps = 0;
+ X11->screenCount = 0;
+ X11->time = CurrentTime;
+ X11->userTime = CurrentTime;
+ X11->ignore_badwindow = false;
+ X11->seen_badwindow = false;
+
+ X11->motifdnd_active = false;
+
+ X11->default_im = QLatin1String("imsw-multi");
+ priv->inputContext = 0;
+
+ // colormap control
+ X11->visual_class = -1;
+ X11->visual_id = -1;
+ X11->color_count = 0;
+ X11->custom_cmap = false;
+
+ // outside visual/colormap
+ X11->visual = reinterpret_cast<Visual *>(visual);
+ X11->colormap = colormap;
+
+ // Fontconfig
+ X11->has_fontconfig = false;
+#if !defined(QT_NO_FONTCONFIG)
+ if (qgetenv("QT_X11_NO_FONTCONFIG").isNull())
+ X11->has_fontconfig = FcInit();
+ X11->fc_antialias = true;
+#endif
+
+#ifndef QT_NO_XRENDER
+ memset(X11->solid_fills, 0, sizeof(X11->solid_fills));
+ for (int i = 0; i < X11->solid_fill_count; ++i)
+ X11->solid_fills[i].screen = -1;
+ memset(X11->pattern_fills, 0, sizeof(X11->pattern_fills));
+ for (int i = 0; i < X11->pattern_fill_count; ++i)
+ X11->pattern_fills[i].screen = -1;
+#endif
+
+ X11->startupId = 0;
+
+ int argc = priv->argc;
+ char **argv = priv->argv;
+
+ if (X11->display) {
+ // Qt part of other application
+
+ // Set application name and class
+ appName = qstrdup("Qt-subapplication");
+ char *app_class = 0;
+ if (argv) {
+ const char* p = strrchr(argv[0], '/');
+ app_class = qstrdup(p ? p + 1 : argv[0]);
+ if (app_class[0])
+ app_class[0] = toupper(app_class[0]);
+ }
+ appClass = app_class;
+ } else {
+ // Qt controls everything (default)
+
+ // With the threaded QML renderer, we always need this.
+ XInitThreads();
+
+ // Set application name and class
+ char *app_class = 0;
+ if (argv && argv[0]) {
+ const char *p = strrchr(argv[0], '/');
+ appName = p ? p + 1 : argv[0];
+ app_class = qstrdup(appName);
+ if (app_class[0])
+ app_class[0] = toupper(app_class[0]);
+ }
+ appClass = app_class;
+ }
+
+ // Install default error handlers
+ original_x_errhandler = XSetErrorHandler(qt_x_errhandler);
+ original_xio_errhandler = XSetIOErrorHandler(qt_xio_errhandler);
+
+ // Get command line params
+ int j = argc ? 1 : 0;
+ for (int i=1; i<argc; i++) {
+ if (argv[i] && *argv[i] != '-') {
+ argv[j++] = argv[i];
+ continue;
+ }
+ QByteArray arg(argv[i]);
+ if (arg == "-display") {
+ if (++i < argc && !X11->display)
+ X11->displayName = argv[i];
+ } else if (arg == "-fn" || arg == "-font") {
+ if (++i < argc)
+ appFont = argv[i];
+ } else if (arg == "-bg" || arg == "-background") {
+ if (++i < argc)
+ appBGCol = argv[i];
+ } else if (arg == "-btn" || arg == "-button") {
+ if (++i < argc)
+ appBTNCol = argv[i];
+ } else if (arg == "-fg" || arg == "-foreground") {
+ if (++i < argc)
+ appFGCol = argv[i];
+ } else if (arg == "-name") {
+ if (++i < argc)
+ appName = argv[i];
+ } else if (arg == "-title") {
+ if (++i < argc)
+ mwTitle = argv[i];
+ } else if (arg == "-geometry") {
+ if (++i < argc)
+ mwGeometry = argv[i];
+ } else if (arg == "-im") {
+ if (++i < argc)
+ qt_ximServer = argv[i];
+ } else if (arg == "-ncols") { // xv and netscape use this name
+ if (++i < argc)
+ X11->color_count = qMax(0,atoi(argv[i]));
+ } else if (arg == "-visual") { // xv and netscape use this name
+ if (++i < argc && !X11->visual) {
+ QString s = QString::fromLocal8Bit(argv[i]).toLower();
+ if (s == QLatin1String("staticgray"))
+ X11->visual_class = StaticGray;
+ else if (s == QLatin1String("grayscale"))
+ X11->visual_class = XGrayScale;
+ else if (s == QLatin1String("staticcolor"))
+ X11->visual_class = StaticColor;
+ else if (s == QLatin1String("pseudocolor"))
+ X11->visual_class = PseudoColor;
+ else if (s == QLatin1String("truecolor"))
+ X11->visual_class = TrueColor;
+ else if (s == QLatin1String("directcolor"))
+ X11->visual_class = DirectColor;
+ else
+ X11->visual_id = static_cast<int>(strtol(argv[i], 0, 0));
+ }
+#ifndef QT_NO_XIM
+ } else if (arg == "-inputstyle") {
+ if (++i < argc) {
+ QString s = QString::fromLocal8Bit(argv[i]).toLower();
+ if (s == QLatin1String("onthespot"))
+ qt_xim_preferred_style = XIMPreeditCallbacks |
+ XIMStatusNothing;
+ else if (s == QLatin1String("overthespot"))
+ qt_xim_preferred_style = XIMPreeditPosition |
+ XIMStatusNothing;
+ else if (s == QLatin1String("offthespot"))
+ qt_xim_preferred_style = XIMPreeditArea |
+ XIMStatusArea;
+ else if (s == QLatin1String("root"))
+ qt_xim_preferred_style = XIMPreeditNothing |
+ XIMStatusNothing;
+ }
+#endif
+ } else if (arg == "-cmap") { // xv uses this name
+ if (!X11->colormap)
+ X11->custom_cmap = true;
+ }
+ else if (arg == "-sync")
+ appSync = !appSync;
+#if defined(QT_DEBUG)
+ else if (arg == "-nograb")
+ appNoGrab = !appNoGrab;
+ else if (arg == "-dograb")
+ appDoGrab = !appDoGrab;
+#endif
+ else
+ argv[j++] = argv[i];
+ }
+
+ priv->argc = j;
+
+#if defined(QT_DEBUG) && defined(Q_OS_LINUX)
+ if (!appNoGrab && !appDoGrab) {
+ QString s;
+ s.sprintf("/proc/%d/cmdline", getppid());
+ QFile f(s);
+ if (f.open(QIODevice::ReadOnly)) {
+ s.clear();
+ char c;
+ while (f.getChar(&c) && c) {
+ if (c == '/')
+ s.clear();
+ else
+ s += QLatin1Char(c);
+ }
+ if (s == QLatin1String("gdb")) {
+ appNoGrab = true;
+ qDebug("Qt: gdb: -nograb added to command-line options.\n"
+ "\t Use the -dograb option to enforce grabbing.");
+ }
+ f.close();
+ }
+ }
+#endif
+
+ // Connect to X server
+ if (qt_is_gui_used && !X11->display) {
+ if ((X11->display = XOpenDisplay(X11->displayName)) == 0) {
+ qWarning("%s: cannot connect to X server %s", appName,
+ XDisplayName(X11->displayName));
+ QApplicationPrivate::reset_instance_pointer();
+ exit(1);
+ }
+
+ if (appSync) // if "-sync" argument
+ XSynchronize(X11->display, true);
+ }
+
+ // Common code, regardless of whether display is foreign.
+
+ // Get X parameters
+
+ if (qt_is_gui_used) {
+ X11->defaultScreen = DefaultScreen(X11->display);
+ X11->screenCount = ScreenCount(X11->display);
+
+ X11->screens = new QX11InfoData[X11->screenCount];
+ X11->argbVisuals = new Visual *[X11->screenCount];
+ X11->argbColormaps = new Colormap[X11->screenCount];
+
+ for (int s = 0; s < X11->screenCount; s++) {
+ QX11InfoData *screen = X11->screens + s;
+ screen->ref = 1; // ensures it doesn't get deleted
+ screen->screen = s;
+
+ int widthMM = DisplayWidthMM(X11->display, s);
+ if (widthMM != 0) {
+ screen->dpiX = (DisplayWidth(X11->display, s) * 254 + widthMM * 5) / (widthMM * 10);
+ } else {
+ screen->dpiX = 72;
+ }
+
+ int heightMM = DisplayHeightMM(X11->display, s);
+ if (heightMM != 0) {
+ screen->dpiY = (DisplayHeight(X11->display, s) * 254 + heightMM * 5) / (heightMM * 10);
+ } else {
+ screen->dpiY = 72;
+ }
+
+ X11->argbVisuals[s] = 0;
+ X11->argbColormaps[s] = 0;
+ }
+
+
+#ifndef QT_NO_XRENDER
+ int xrender_eventbase, xrender_errorbase;
+ // See if XRender is supported on the connected display
+ if (XQueryExtension(X11->display, "RENDER", &X11->xrender_major,
+ &xrender_eventbase, &xrender_errorbase)
+ && XRenderQueryExtension(X11->display, &xrender_eventbase,
+ &xrender_errorbase)) {
+ // Check the version as well - we need v0.4 or higher
+ int major = 0;
+ int minor = 0;
+ XRenderQueryVersion(X11->display, &major, &minor);
+ if (qgetenv("QT_X11_NO_XRENDER").isNull()) {
+ X11->use_xrender = (major >= 0 && minor >= 5);
+ X11->xrender_version = major*100+minor;
+ // workaround for broken XServer on Ubuntu Breezy (6.8 compiled with 7.0
+ // protocol headers)
+ if (X11->xrender_version == 10
+ && VendorRelease(X11->display) < 60900000
+ && QByteArray(ServerVendor(X11->display)).contains("X.Org"))
+ X11->xrender_version = 9;
+ }
+ }
+#endif // QT_NO_XRENDER
+
+#ifndef QT_NO_MITSHM
+ int mitshm_minor;
+ int mitshm_major;
+ int mitshm_eventbase;
+ int mitshm_errorbase;
+ int mitshm_pixmaps;
+ if (XQueryExtension(X11->display, "MIT-SHM", &X11->mitshm_major,
+ &mitshm_eventbase, &mitshm_errorbase)
+ && XShmQueryVersion(X11->display, &mitshm_major, &mitshm_minor,
+ &mitshm_pixmaps))
+ {
+ QString displayName = QLatin1String(XDisplayName(NULL));
+
+ // MITSHM only works for local displays, so do a quick check here
+ // to determine whether the display is local or not (not 100 % accurate).
+ // BGR server layouts are not supported either, since it requires the raster
+ // engine to work on a QImage with BGR layout.
+ bool local = displayName.isEmpty() || displayName.lastIndexOf(QLatin1Char(':')) == 0;
+ if (local && (qgetenv("QT_X11_NO_MITSHM").toInt() == 0)) {
+ Visual *defaultVisual = DefaultVisual(X11->display, DefaultScreen(X11->display));
+ X11->use_mitshm = ((defaultVisual->red_mask == 0xff0000
+ || defaultVisual->red_mask == 0xf800)
+ && (defaultVisual->green_mask == 0xff00
+ || defaultVisual->green_mask == 0x7e0)
+ && (defaultVisual->blue_mask == 0xff
+ || defaultVisual->blue_mask == 0x1f));
+ X11->use_mitshm_pixmaps = X11->use_mitshm && mitshm_pixmaps;
+ }
+ }
+#endif // QT_NO_MITSHM
+
+ // initialize the graphics system - order is imporant here - it must be done before
+ // the QColormap::initialize() call
+ QApplicationPrivate::graphics_system = QGraphicsSystemFactory::create(QApplicationPrivate::graphics_system_name);
+ QColormap::initialize();
+
+ // Support protocols
+ X11->xdndSetup();
+
+ // Finally create all atoms
+ qt_x11_create_intern_atoms();
+
+ // initialize NET lists
+ qt_get_net_supported();
+ qt_get_net_virtual_roots();
+
+#ifndef QT_NO_XRANDR
+ // See if XRandR is supported on the connected display
+ if (XQueryExtension(X11->display, "RANDR", &X11->xrandr_major,
+ &X11->xrandr_eventbase, &X11->xrandr_errorbase)) {
+
+# ifdef QT_RUNTIME_XRANDR
+ X11->ptrXRRSelectInput = 0;
+ X11->ptrXRRUpdateConfiguration = 0;
+ X11->ptrXRRRootToScreen = 0;
+ X11->ptrXRRQueryExtension = 0;
+ QLibrary xrandrLib(QLatin1String("Xrandr"), 2);
+ if (!xrandrLib.load()) { // try without the version number
+ xrandrLib.setFileName(QLatin1String("Xrandr"));
+ xrandrLib.load();
+ }
+ if (xrandrLib.isLoaded()) {
+ X11->ptrXRRSelectInput =
+ (PtrXRRSelectInput) xrandrLib.resolve("XRRSelectInput");
+ X11->ptrXRRUpdateConfiguration =
+ (PtrXRRUpdateConfiguration) xrandrLib.resolve("XRRUpdateConfiguration");
+ X11->ptrXRRRootToScreen =
+ (PtrXRRRootToScreen) xrandrLib.resolve("XRRRootToScreen");
+ X11->ptrXRRQueryExtension =
+ (PtrXRRQueryExtension) xrandrLib.resolve("XRRQueryExtension");
+ X11->ptrXRRSizes =
+ (PtrXRRSizes) xrandrLib.resolve("XRRSizes");
+ }
+# else
+ X11->ptrXRRSelectInput = XRRSelectInput;
+ X11->ptrXRRUpdateConfiguration = XRRUpdateConfiguration;
+ X11->ptrXRRRootToScreen = XRRRootToScreen;
+ X11->ptrXRRQueryExtension = XRRQueryExtension;
+ X11->ptrXRRSizes = XRRSizes;
+# endif
+
+ if (X11->ptrXRRQueryExtension
+ && X11->ptrXRRQueryExtension(X11->display, &X11->xrandr_eventbase, &X11->xrandr_errorbase)) {
+ // XRandR is supported
+ X11->use_xrandr = true;
+ }
+ }
+#endif // QT_NO_XRANDR
+
+#ifndef QT_NO_XRENDER
+ if (X11->use_xrender) {
+ // XRender is supported, let's see if we have a PictFormat for the
+ // default visual
+ XRenderPictFormat *format =
+ XRenderFindVisualFormat(X11->display,
+ (Visual *) QX11Info::appVisual(X11->defaultScreen));
+
+ if (!format) {
+ X11->use_xrender = false;
+ }
+ }
+#endif // QT_NO_XRENDER
+
+#ifndef QT_NO_XFIXES
+ // See if Xfixes is supported on the connected display
+ if (XQueryExtension(X11->display, "XFIXES", &X11->xfixes_major,
+ &X11->xfixes_eventbase, &X11->xfixes_errorbase)) {
+ X11->ptrXFixesQueryExtension = XFIXES_LOAD_V1(XFixesQueryExtension);
+ X11->ptrXFixesQueryVersion = XFIXES_LOAD_V1(XFixesQueryVersion);
+ X11->ptrXFixesSetCursorName = XFIXES_LOAD_V2(XFixesSetCursorName);
+ X11->ptrXFixesSelectSelectionInput = XFIXES_LOAD_V2(XFixesSelectSelectionInput);
+
+ if(X11->ptrXFixesQueryExtension && X11->ptrXFixesQueryVersion
+ && X11->ptrXFixesQueryExtension(X11->display, &X11->xfixes_eventbase,
+ &X11->xfixes_errorbase)) {
+ // Xfixes is supported.
+ // Note: the XFixes protocol version is negotiated using QueryVersion.
+ // We supply the highest version we support, the X server replies with
+ // the highest version it supports, but no higher than the version we
+ // asked for. The version sent back is the protocol version the X server
+ // will use to talk us. If this call is removed, the behavior of the
+ // X server when it receives an XFixes request is undefined.
+ int major = 3;
+ int minor = 0;
+ X11->ptrXFixesQueryVersion(X11->display, &major, &minor);
+ X11->use_xfixes = (major >= 1);
+ X11->xfixes_major = major;
+ }
+ }
+#endif // QT_NO_XFIXES
+
+#ifndef QT_NO_XCURSOR
+#ifdef QT_RUNTIME_XCURSOR
+ X11->ptrXcursorLibraryLoadCursor = 0;
+ QLibrary xcursorLib(QLatin1String("Xcursor"), 1);
+ bool xcursorFound = xcursorLib.load();
+ if (!xcursorFound) { //try without the version number
+ xcursorLib.setFileName(QLatin1String("Xcursor"));
+ xcursorFound = xcursorLib.load();
+ }
+ if (xcursorFound) {
+ X11->ptrXcursorLibraryLoadCursor =
+ (PtrXcursorLibraryLoadCursor) xcursorLib.resolve("XcursorLibraryLoadCursor");
+ }
+#else
+ X11->ptrXcursorLibraryLoadCursor = XcursorLibraryLoadCursor;
+#endif // QT_RUNTIME_XCURSOR
+#endif // QT_NO_XCURSOR
+
+#ifndef QT_NO_XSYNC
+ int xsync_evbase, xsync_errbase;
+ int major, minor;
+ if (XSyncQueryExtension(X11->display, &xsync_evbase, &xsync_errbase))
+ XSyncInitialize(X11->display, &major, &minor);
+#endif // QT_NO_XSYNC
+
+#ifndef QT_NO_XINERAMA
+#ifdef QT_RUNTIME_XINERAMA
+ X11->ptrXineramaQueryExtension = 0;
+ X11->ptrXineramaIsActive = 0;
+ X11->ptrXineramaQueryScreens = 0;
+ QLibrary xineramaLib(QLatin1String("Xinerama"), 1);
+ bool xineramaFound = xineramaLib.load();
+ if (!xineramaFound) { //try without the version number
+ xineramaLib.setFileName(QLatin1String("Xinerama"));
+ xineramaFound = xineramaLib.load();
+ }
+ if (xineramaFound) {
+ X11->ptrXineramaQueryExtension =
+ (PtrXineramaQueryExtension) xineramaLib.resolve("XineramaQueryExtension");
+ X11->ptrXineramaIsActive =
+ (PtrXineramaIsActive) xineramaLib.resolve("XineramaIsActive");
+ X11->ptrXineramaQueryScreens =
+ (PtrXineramaQueryScreens) xineramaLib.resolve("XineramaQueryScreens");
+ }
+#else
+ X11->ptrXineramaQueryScreens = XineramaQueryScreens;
+ X11->ptrXineramaIsActive = XineramaIsActive;
+ X11->ptrXineramaQueryExtension = XineramaQueryExtension;
+#endif // QT_RUNTIME_XINERAMA
+#endif // QT_NO_XINERAMA
+
+#ifndef QT_NO_XINPUT
+ // See if Xinput is supported on the connected display
+ X11->ptrXCloseDevice = 0;
+ X11->ptrXListInputDevices = 0;
+ X11->ptrXOpenDevice = 0;
+ X11->ptrXFreeDeviceList = 0;
+ X11->ptrXSelectExtensionEvent = 0;
+ X11->use_xinput = XQueryExtension(X11->display, "XInputExtension", &X11->xinput_major,
+ &X11->xinput_eventbase, &X11->xinput_errorbase);
+ if (X11->use_xinput) {
+ X11->ptrXCloseDevice = XINPUT_LOAD(XCloseDevice);
+ X11->ptrXListInputDevices = XINPUT_LOAD(XListInputDevices);
+ X11->ptrXOpenDevice = XINPUT_LOAD(XOpenDevice);
+ X11->ptrXFreeDeviceList = XINPUT_LOAD(XFreeDeviceList);
+ X11->ptrXSelectExtensionEvent = XINPUT_LOAD(XSelectExtensionEvent);
+ }
+#endif // QT_NO_XINPUT
+
+#ifndef QT_NO_XKB
+ int xkblibMajor = XkbMajorVersion;
+ int xkblibMinor = XkbMinorVersion;
+ X11->use_xkb = XkbQueryExtension(X11->display,
+ &X11->xkb_major,
+ &X11->xkb_eventbase,
+ &X11->xkb_errorbase,
+ &xkblibMajor,
+ &xkblibMinor);
+ if (X11->use_xkb) {
+ // If XKB is detected, set the GrabsUseXKBState option so input method
+ // compositions continue to work (ie. deadkeys)
+ unsigned int state = XkbPCF_GrabsUseXKBStateMask;
+ (void) XkbSetPerClientControls(X11->display, state, &state);
+
+ // select for group change events
+ XkbSelectEventDetails(X11->display,
+ XkbUseCoreKbd,
+ XkbStateNotify,
+ XkbAllStateComponentsMask,
+ XkbGroupStateMask);
+
+ // current group state is queried when creating the keymapper, no need to do it here
+ }
+#endif
+
+
+#if !defined(QT_NO_FONTCONFIG)
+ int dpi = 0;
+ getXDefault("Xft", FC_DPI, &dpi);
+ if (dpi) {
+ for (int s = 0; s < ScreenCount(X11->display); ++s) {
+ QX11Info::setAppDpiX(s, dpi);
+ QX11Info::setAppDpiY(s, dpi);
+ }
+ }
+ double fc_scale = 1.;
+ getXDefault("Xft", FC_SCALE, &fc_scale);
+ X11->fc_scale = fc_scale;
+ for (int s = 0; s < ScreenCount(X11->display); ++s) {
+ int subpixel = FC_RGBA_UNKNOWN;
+#if !defined(QT_NO_XRENDER) && (RENDER_MAJOR > 0 || RENDER_MINOR >= 6)
+ if (X11->use_xrender) {
+ int rsp = XRenderQuerySubpixelOrder(X11->display, s);
+ switch (rsp) {
+ default:
+ case SubPixelUnknown:
+ subpixel = FC_RGBA_UNKNOWN;
+ break;
+ case SubPixelHorizontalRGB:
+ subpixel = FC_RGBA_RGB;
+ break;
+ case SubPixelHorizontalBGR:
+ subpixel = FC_RGBA_BGR;
+ break;
+ case SubPixelVerticalRGB:
+ subpixel = FC_RGBA_VRGB;
+ break;
+ case SubPixelVerticalBGR:
+ subpixel = FC_RGBA_VBGR;
+ break;
+ case SubPixelNone:
+ subpixel = FC_RGBA_NONE;
+ break;
+ }
+ }
+#endif
+
+ char *rgba = XGetDefault(X11->display, "Xft", FC_RGBA);
+ if (rgba) {
+ char *end = 0;
+ int v = strtol(rgba, &end, 0);
+ if (rgba != end) {
+ subpixel = v;
+ } else if (qstrncmp(rgba, "unknown", 7) == 0) {
+ subpixel = FC_RGBA_UNKNOWN;
+ } else if (qstrncmp(rgba, "rgb", 3) == 0) {
+ subpixel = FC_RGBA_RGB;
+ } else if (qstrncmp(rgba, "bgr", 3) == 0) {
+ subpixel = FC_RGBA_BGR;
+ } else if (qstrncmp(rgba, "vrgb", 4) == 0) {
+ subpixel = FC_RGBA_VRGB;
+ } else if (qstrncmp(rgba, "vbgr", 4) == 0) {
+ subpixel = FC_RGBA_VBGR;
+ } else if (qstrncmp(rgba, "none", 4) == 0) {
+ subpixel = FC_RGBA_NONE;
+ }
+ }
+ X11->screens[s].subpixel = subpixel;
+ }
+ getXDefault("Xft", FC_ANTIALIAS, &X11->fc_antialias);
+#ifdef FC_HINT_STYLE
+ X11->fc_hint_style = -1;
+ getXDefault("Xft", FC_HINT_STYLE, &X11->fc_hint_style);
+#endif
+#if 0
+ // ###### these are implemented by Xft, not sure we need them
+ getXDefault("Xft", FC_AUTOHINT, &X11->fc_autohint);
+ getXDefault("Xft", FC_HINTING, &X11->fc_autohint);
+ getXDefault("Xft", FC_MINSPACE, &X11->fc_autohint);
+#endif
+#endif // QT_NO_XRENDER
+
+ // initialize key mapper
+ QKeyMapper::changeKeyboard();
+
+ // Misc. initialization
+#if 0 //disabled for now..
+ QSegfaultHandler::initialize(priv->argv, priv->argc);
+#endif
+ QCursorData::initialize();
+ }
+ QFont::initialize();
+
+ if(qt_is_gui_used) {
+ qApp->setObjectName(QString::fromLocal8Bit(appName));
+
+ int screen;
+ for (screen = 0; screen < X11->screenCount; ++screen) {
+ XSelectInput(X11->display, QX11Info::appRootWindow(screen),
+ KeymapStateMask | EnterWindowMask | LeaveWindowMask | PropertyChangeMask);
+
+#ifndef QT_NO_XRANDR
+ if (X11->use_xrandr)
+ X11->ptrXRRSelectInput(X11->display, QX11Info::appRootWindow(screen), True);
+#endif // QT_NO_XRANDR
+ }
+ }
+
+ if (qt_is_gui_used) {
+ // Attempt to determine the current running X11 Desktop Enviornment
+ // Use dbus if/when we can, but fall back to using windowManagerName() for now
+
+#ifndef QT_NO_XFIXES
+ if (X11->ptrXFixesSelectSelectionInput)
+ X11->ptrXFixesSelectSelectionInput(X11->display, QX11Info::appRootWindow(), ATOM(_NET_WM_CM_S0),
+ XFixesSetSelectionOwnerNotifyMask
+ | XFixesSelectionWindowDestroyNotifyMask
+ | XFixesSelectionClientCloseNotifyMask);
+#endif // QT_NO_XFIXES
+ X11->compositingManagerRunning = XGetSelectionOwner(X11->display,
+ ATOM(_NET_WM_CM_S0));
+ X11->desktopEnvironment = DE_UNKNOWN;
+ X11->desktopVersion = 0;
+
+ Atom type;
+ int format;
+ unsigned long length, after;
+ uchar *data = 0;
+ int rc;
+
+ do {
+ if (!qgetenv("KDE_FULL_SESSION").isEmpty()) {
+ X11->desktopEnvironment = DE_KDE;
+ X11->desktopVersion = qgetenv("KDE_SESSION_VERSION").toInt();
+ break;
+ }
+
+ if (qgetenv("DESKTOP_SESSION") == "gnome") {
+ X11->desktopEnvironment = DE_GNOME;
+ break;
+ }
+
+ // GNOME_DESKTOP_SESSION_ID is deprecated for some reason, but still check it
+ if (!qgetenv("GNOME_DESKTOP_SESSION_ID").isEmpty()) {
+ X11->desktopEnvironment = DE_GNOME;
+ break;
+ }
+
+ rc = XGetWindowProperty(X11->display, QX11Info::appRootWindow(), ATOM(_DT_SAVE_MODE),
+ 0, 2, False, XA_STRING, &type, &format, &length,
+ &after, &data);
+ if (rc == Success && length) {
+ if (!strcmp(reinterpret_cast<char *>(data), "xfce4")) {
+ // Pretend that xfce4 is gnome, as it uses the same libraries.
+ // The detection above is stolen from xdg-open.
+ X11->desktopEnvironment = DE_GNOME;
+ break;
+ }
+
+ // We got the property but it wasn't xfce4. Free data before it gets overwritten.
+ XFree(data);
+ data = 0;
+ }
+
+ rc = XGetWindowProperty(X11->display, QX11Info::appRootWindow(), ATOM(DTWM_IS_RUNNING),
+ 0, 1, False, AnyPropertyType, &type, &format, &length,
+ &after, &data);
+ if (rc == Success && length) {
+ // DTWM is running, meaning most likely CDE is running...
+ X11->desktopEnvironment = DE_CDE;
+ break;
+ }
+
+ rc = XGetWindowProperty(X11->display, QX11Info::appRootWindow(),
+ ATOM(_SGI_DESKS_MANAGER), 0, 1, False, XA_WINDOW,
+ &type, &format, &length, &after, &data);
+ if (rc == Success && length) {
+ X11->desktopEnvironment = DE_4DWM;
+ break;
+ }
+
+ if (XGetWindowProperty(X11->display, QX11Info::appRootWindow(),
+ ATOM(_NET_SUPPORTING_WM_CHECK),
+ 0, 1024, False, XA_WINDOW, &type,
+ &format, &length, &after, &data) == Success) {
+ if (type == XA_WINDOW && format == 32) {
+ Window windowManagerWindow = *((Window*) data);
+ XFree(data);
+ data = 0;
+
+ if (windowManagerWindow != XNone) {
+ Atom utf8atom = ATOM(UTF8_STRING);
+ if (XGetWindowProperty(QX11Info::display(), windowManagerWindow, ATOM(_NET_WM_NAME),
+ 0, 1024, False, utf8atom, &type,
+ &format, &length, &after, &data) == Success) {
+ if (type == utf8atom && format == 8) {
+ if (qstrcmp((const char *)data, "MCompositor") == 0)
+ X11->desktopEnvironment = DE_MEEGO_COMPOSITOR;
+ }
+ }
+ }
+ }
+ }
+
+ } while(0);
+
+ if (data)
+ XFree((char *)data);
+
+#if !defined(QT_NO_STYLE_GTK)
+ if (X11->desktopEnvironment == DE_GNOME) {
+ static bool menusHaveIcons = QGtkStyle::getGConfBool(QLatin1String("/desktop/gnome/interface/menus_have_icons"), true);
+ QApplication::setAttribute(Qt::AA_DontShowIconsInMenus, !menusHaveIcons);
+ }
+#endif
+ qt_set_input_encoding();
+
+ qt_set_x11_resources(appFont, appFGCol, appBGCol, appBTNCol);
+
+ // be smart about the size of the default font. most X servers have helvetica
+ // 12 point available at 2 resolutions:
+ // 75dpi (12 pixels) and 100dpi (17 pixels).
+ // At 95 DPI, a 12 point font should be 16 pixels tall - in which case a 17
+ // pixel font is a closer match than a 12 pixel font
+ int ptsz = (X11->use_xrender
+ ? 9
+ : (int) (((QX11Info::appDpiY() >= 95 ? 17. : 12.) *
+ 72. / (float) QX11Info::appDpiY()) + 0.5));
+
+ if (!QApplicationPrivate::sys_font) {
+ // no font from settings or RESOURCE_MANAGER, provide a fallback
+ QFont f(X11->has_fontconfig ? QLatin1String("Sans Serif") : QLatin1String("Helvetica"),
+ ptsz);
+ QApplicationPrivate::setSystemFont(f);
+ }
+
+#if !defined (QT_NO_TABLET)
+ if (X11->use_xinput) {
+ int ndev,
+ i,
+ j;
+ bool gotStylus,
+ gotEraser;
+ XDeviceInfo *devices = 0, *devs;
+ XInputClassInfo *ip;
+ XAnyClassPtr any;
+ XValuatorInfoPtr v;
+ XAxisInfoPtr a;
+ XDevice *dev = 0;
+
+ if (X11->ptrXListInputDevices) {
+ devices = X11->ptrXListInputDevices(X11->display, &ndev);
+ if (!devices)
+ qWarning("QApplication: Failed to get list of tablet devices");
+ }
+ if (!devices)
+ ndev = -1;
+ QTabletEvent::TabletDevice deviceType;
+ for (devs = devices, i = 0; i < ndev && devs; i++, devs++) {
+ dev = 0;
+ deviceType = QTabletEvent::NoDevice;
+ gotStylus = false;
+ gotEraser = false;
+
+#if defined(Q_OS_IRIX)
+ QString devName = QString::fromLocal8Bit(devs->name).toLower();
+ if (devName == QLatin1String(WACOM_NAME)) {
+ deviceType = QTabletEvent::Stylus;
+ gotStylus = true;
+ }
+#else
+ if (devs->type == ATOM(XWacomStylus) || devs->type == ATOM(XTabletStylus)) {
+ deviceType = QTabletEvent::Stylus;
+ if (wacomDeviceName()->isEmpty())
+ wacomDeviceName()->append(devs->name);
+ gotStylus = true;
+ } else if (devs->type == ATOM(XWacomEraser) || devs->type == ATOM(XTabletEraser)) {
+ deviceType = QTabletEvent::XFreeEraser;
+ gotEraser = true;
+ }
+#endif
+ if (deviceType == QTabletEvent::NoDevice)
+ continue;
+
+ if (gotStylus || gotEraser) {
+ if (X11->ptrXOpenDevice)
+ dev = X11->ptrXOpenDevice(X11->display, devs->id);
+
+ if (!dev)
+ continue;
+
+ QTabletDeviceData device_data;
+ device_data.deviceType = deviceType;
+ device_data.eventCount = 0;
+ device_data.device = dev;
+ device_data.xinput_motion = -1;
+ device_data.xinput_key_press = -1;
+ device_data.xinput_key_release = -1;
+ device_data.xinput_button_press = -1;
+ device_data.xinput_button_release = -1;
+ device_data.xinput_proximity_in = -1;
+ device_data.xinput_proximity_out = -1;
+ device_data.widgetToGetPress = 0;
+
+ if (dev->num_classes > 0) {
+ for (ip = dev->classes, j = 0; j < dev->num_classes;
+ ip++, j++) {
+ switch (ip->input_class) {
+ case KeyClass:
+ DeviceKeyPress(dev, device_data.xinput_key_press,
+ device_data.eventList[device_data.eventCount]);
+ if (device_data.eventList[device_data.eventCount])
+ ++device_data.eventCount;
+ DeviceKeyRelease(dev, device_data.xinput_key_release,
+ device_data.eventList[device_data.eventCount]);
+ if (device_data.eventList[device_data.eventCount])
+ ++device_data.eventCount;
+ break;
+ case ButtonClass:
+ DeviceButtonPress(dev, device_data.xinput_button_press,
+ device_data.eventList[device_data.eventCount]);
+ if (device_data.eventList[device_data.eventCount])
+ ++device_data.eventCount;
+ DeviceButtonRelease(dev, device_data.xinput_button_release,
+ device_data.eventList[device_data.eventCount]);
+ if (device_data.eventList[device_data.eventCount])
+ ++device_data.eventCount;
+ break;
+ case ValuatorClass:
+ // I'm only going to be interested in motion when the
+ // stylus is already down anyway!
+ DeviceMotionNotify(dev, device_data.xinput_motion,
+ device_data.eventList[device_data.eventCount]);
+ if (device_data.eventList[device_data.eventCount])
+ ++device_data.eventCount;
+ ProximityIn(dev, device_data.xinput_proximity_in, device_data.eventList[device_data.eventCount]);
+ if (device_data.eventList[device_data.eventCount])
+ ++device_data.eventCount;
+ ProximityOut(dev, device_data.xinput_proximity_out, device_data.eventList[device_data.eventCount]);
+ if (device_data.eventList[device_data.eventCount])
+ ++device_data.eventCount;
+ default:
+ break;
+ }
+ }
+ }
+
+ // get the min/max value for pressure!
+ any = (XAnyClassPtr) (devs->inputclassinfo);
+ for (j = 0; j < devs->num_classes; j++) {
+ if (any->c_class == ValuatorClass) {
+ v = (XValuatorInfoPtr) any;
+ a = (XAxisInfoPtr) ((char *) v +
+ sizeof (XValuatorInfo));
+#if defined (Q_OS_IRIX)
+ // I'm not exaclty wild about this, but the
+ // dimensions of the tablet are more relevant here
+ // than the min and max values from the axis
+ // (actually it seems to be 2/3 or what is in the
+ // axis. So we'll try to parse it from this
+ // string. --tws
+ char returnString[SGIDeviceRtrnLen];
+ int tmp;
+ if (XSGIMiscQueryExtension(X11->display, &tmp, &tmp)
+ && XSGIDeviceQuery(X11->display, devs->id,
+ "dimensions", returnString)) {
+ QString str = QLatin1String(returnString);
+ int comma = str.indexOf(',');
+ device_data.minX = 0;
+ device_data.minY = 0;
+ device_data.maxX = str.left(comma).toInt();
+ device_data.maxY = str.mid(comma + 1).toInt();
+ } else {
+ device_data.minX = a[WAC_XCOORD_I].min_value;
+ device_data.maxX = a[WAC_XCOORD_I].max_value;
+ device_data.minY = a[WAC_YCOORD_I].min_value;
+ device_data.maxY = a[WAC_YCOORD_I].max_value;
+ }
+ device_data.minPressure = a[WAC_PRESSURE_I].min_value;
+ device_data.maxPressure = a[WAC_PRESSURE_I].max_value;
+ device_data.minTanPressure = a[WAC_TAN_PRESSURE_I].min_value;
+ device_data.maxTanPressure = a[WAC_TAN_PRESSURE_I].max_value;
+ device_data.minZ = a[WAC_ZCOORD_I].min_value;
+ device_data.maxZ = a[WAC_ZCOORD_I].max_value;
+#else
+ device_data.minX = a[0].min_value;
+ device_data.maxX = a[0].max_value;
+ device_data.minY = a[1].min_value;
+ device_data.maxY = a[1].max_value;
+ device_data.minPressure = a[2].min_value;
+ device_data.maxPressure = a[2].max_value;
+ device_data.minTanPressure = 0;
+ device_data.maxTanPressure = 0;
+ device_data.minZ = 0;
+ device_data.maxZ = 0;
+#endif
+
+ // got the max pressure no need to go further...
+ break;
+ }
+ any = (XAnyClassPtr) ((char *) any + any->length);
+ } // end of for loop
+
+ tablet_devices()->append(device_data);
+ } // if (gotStylus || gotEraser)
+ }
+ if (X11->ptrXFreeDeviceList)
+ X11->ptrXFreeDeviceList(devices);
+ }
+#endif // QT_NO_TABLET
+
+ X11->startupId = getenv("DESKTOP_STARTUP_ID");
+ if (X11->startupId) {
+#ifndef QT_NO_UNSETENV
+ unsetenv("DESKTOP_STARTUP_ID");
+#else
+ // it's a small memory leak, however we won't crash if Qt is
+ // unloaded and someones tries to use the envoriment.
+ putenv(strdup("DESKTOP_STARTUP_ID="));
+#endif
+ }
+ } else {
+ // read some non-GUI settings when not using the X server...
+
+ if (QApplication::desktopSettingsAware()) {
+ QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
+ settings.beginGroup(QLatin1String("Qt"));
+
+ // read library (ie. plugin) path list
+ QString libpathkey = QString::fromLatin1("%1.%2/libraryPath")
+ .arg(QT_VERSION >> 16)
+ .arg((QT_VERSION & 0xff00) >> 8);
+ QStringList pathlist =
+ settings.value(libpathkey).toString().split(QLatin1Char(':'));
+ if (! pathlist.isEmpty()) {
+ QStringList::ConstIterator it = pathlist.constBegin();
+ while (it != pathlist.constEnd())
+ QApplication::addLibraryPath(*it++);
+ }
+
+ QString defaultcodec = settings.value(QLatin1String("defaultCodec"),
+ QVariant(QLatin1String("none"))).toString();
+ if (defaultcodec != QLatin1String("none")) {
+ QTextCodec *codec = QTextCodec::codecForName(defaultcodec.toLatin1());
+ if (codec)
+ QTextCodec::setCodecForTr(codec);
+ }
+
+ settings.endGroup(); // Qt
+ }
+ }
+
+#if !defined (Q_OS_IRIX) && !defined (QT_NO_TABLET)
+ QLibrary wacom(QString::fromLatin1("wacomcfg"), 0); // version 0 is the latest release at time of writing this.
+ // NOTE: C casts instead of reinterpret_cast for GCC 3.3.x
+ ptrWacomConfigInit = (PtrWacomConfigInit)wacom.resolve("WacomConfigInit");
+ ptrWacomConfigOpenDevice = (PtrWacomConfigOpenDevice)wacom.resolve("WacomConfigOpenDevice");
+ ptrWacomConfigGetRawParam = (PtrWacomConfigGetRawParam)wacom.resolve("WacomConfigGetRawParam");
+ ptrWacomConfigCloseDevice = (PtrWacomConfigCloseDevice)wacom.resolve("WacomConfigCloseDevice");
+ ptrWacomConfigTerm = (PtrWacomConfigTerm)wacom.resolve("WacomConfigTerm");
+
+ if (ptrWacomConfigInit == 0 || ptrWacomConfigOpenDevice == 0 || ptrWacomConfigGetRawParam == 0
+ || ptrWacomConfigCloseDevice == 0 || ptrWacomConfigTerm == 0) { // either we have all, or we have none.
+ ptrWacomConfigInit = 0;
+ ptrWacomConfigOpenDevice = 0;
+ ptrWacomConfigGetRawParam = 0;
+ ptrWacomConfigCloseDevice = 0;
+ ptrWacomConfigTerm = 0;
+ }
+#endif
+}
+
+void QApplicationPrivate::initializeWidgetPaletteHash()
+{
+}
+
+/*****************************************************************************
+ qt_cleanup() - cleans up when the application is finished
+ *****************************************************************************/
+
+void qt_cleanup()
+{
+ if (app_save_rootinfo) // root window must keep state
+ qt_save_rootinfo();
+
+ if (qt_is_gui_used) {
+ QPixmapCache::clear();
+ QCursorData::cleanup();
+ QFont::cleanup();
+ QColormap::cleanup();
+
+#if !defined (QT_NO_TABLET)
+ QTabletDeviceDataList *devices = qt_tablet_devices();
+ if (X11->ptrXCloseDevice)
+ for (int i = 0; i < devices->size(); ++i)
+ X11->ptrXCloseDevice(X11->display, (XDevice*)devices->at(i).device);
+ devices->clear();
+#endif
+ }
+
+#ifndef QT_NO_XRENDER
+ for (int i = 0; i < X11->solid_fill_count; ++i) {
+ if (X11->solid_fills[i].picture)
+ XRenderFreePicture(X11->display, X11->solid_fills[i].picture);
+ }
+ for (int i = 0; i < X11->pattern_fill_count; ++i) {
+ if (X11->pattern_fills[i].picture)
+ XRenderFreePicture(X11->display, X11->pattern_fills[i].picture);
+ }
+#endif
+
+#if !defined(QT_NO_IM)
+ delete QApplicationPrivate::inputContext;
+ QApplicationPrivate::inputContext = 0;
+#endif
+
+ // Reset the error handlers
+ if (qt_is_gui_used)
+ XSync(X11->display, False); // sync first to process all possible errors
+ XSetErrorHandler(original_x_errhandler);
+ XSetIOErrorHandler(original_xio_errhandler);
+
+ if (X11->argbColormaps) {
+ for (int s = 0; s < X11->screenCount; s++) {
+ if (X11->argbColormaps[s])
+ XFreeColormap(X11->display, X11->argbColormaps[s]);
+ }
+ }
+
+ if (qt_is_gui_used && !X11->foreignDisplay)
+ XCloseDisplay(X11->display); // close X display
+ X11->display = 0;
+
+ delete [] X11->screens;
+ delete [] X11->argbVisuals;
+ delete [] X11->argbColormaps;
+
+ if (X11->foreignDisplay) {
+ delete [] (char *)appName;
+ appName = 0;
+ }
+
+ delete [] (char *)appClass;
+ appClass = 0;
+
+ if (X11->net_supported_list)
+ delete [] X11->net_supported_list;
+ X11->net_supported_list = 0;
+
+ if (X11->net_virtual_root_list)
+ delete [] X11->net_virtual_root_list;
+ X11->net_virtual_root_list = 0;
+
+ delete X11;
+ X11 = 0;
+}
+
+
+/*****************************************************************************
+ Platform specific global and internal functions
+ *****************************************************************************/
+
+void qt_save_rootinfo() // save new root info
+{
+ Atom type;
+ int format;
+ unsigned long length, after;
+ uchar *data = 0;
+
+ if (ATOM(_XSETROOT_ID)) { // kill old pixmap
+ if (XGetWindowProperty(X11->display, QX11Info::appRootWindow(),
+ ATOM(_XSETROOT_ID), 0, 1,
+ True, AnyPropertyType, &type, &format,
+ &length, &after, &data) == Success) {
+ if (type == XA_PIXMAP && format == 32 && length == 1 &&
+ after == 0 && data) {
+ XKillClient(X11->display, *((Pixmap*)data));
+ }
+ Pixmap dummy = XCreatePixmap(X11->display, QX11Info::appRootWindow(),
+ 1, 1, 1);
+ XChangeProperty(X11->display, QX11Info::appRootWindow(),
+ ATOM(_XSETROOT_ID), XA_PIXMAP, 32,
+ PropModeReplace, (uchar *)&dummy, 1);
+ XSetCloseDownMode(X11->display, RetainPermanent);
+ }
+ }
+ if (data)
+ XFree((char *)data);
+}
+
+void qt_updated_rootinfo()
+{
+ app_save_rootinfo = true;
+}
+
+// ### Cleanup, this function is not in use!
+bool qt_wstate_iconified(WId winid)
+{
+ Atom type;
+ int format;
+ unsigned long length, after;
+ uchar *data = 0;
+ int r = XGetWindowProperty(X11->display, winid, ATOM(WM_STATE), 0, 2,
+ False, AnyPropertyType, &type, &format,
+ &length, &after, &data);
+ bool iconic = false;
+ if (r == Success && data && format == 32) {
+ // quint32 *wstate = (quint32*)data;
+ unsigned long *wstate = (unsigned long *) data;
+ iconic = (*wstate == IconicState);
+ XFree((char *)data);
+ }
+ return iconic;
+}
+
+QString QApplicationPrivate::appName() const
+{
+ return QString::fromLocal8Bit(QT_PREPEND_NAMESPACE(appName));
+}
+
+const char *QX11Info::appClass() // get application class
+{
+ return QT_PREPEND_NAMESPACE(appClass);
+}
+
+bool qt_nograb() // application no-grab option
+{
+#if defined(QT_DEBUG)
+ return appNoGrab;
+#else
+ return false;
+#endif
+}
+
+
+/*****************************************************************************
+ Platform specific QApplication members
+ *****************************************************************************/
+
+#ifdef QT3_SUPPORT
+void QApplication::setMainWidget(QWidget *mainWidget)
+{
+#ifndef QT_NO_DEBUG
+ if (mainWidget && mainWidget->parentWidget() && mainWidget->isWindow())
+ qWarning("QApplication::setMainWidget: New main widget (%s/%s) "
+ "has a parent",
+ mainWidget->metaObject()->className(), mainWidget->objectName().toLocal8Bit().constData());
+#endif
+ if (mainWidget)
+ mainWidget->d_func()->createWinId();
+ QApplicationPrivate::main_widget = mainWidget;
+ if (QApplicationPrivate::main_widget) // give WM command line
+ QApplicationPrivate::applyX11SpecificCommandLineArguments(QApplicationPrivate::main_widget);
+}
+#endif
+
+void QApplicationPrivate::applyX11SpecificCommandLineArguments(QWidget *main_widget)
+{
+ static bool beenHereDoneThat = false;
+ if (beenHereDoneThat)
+ return;
+ beenHereDoneThat = true;
+ Q_ASSERT(main_widget->testAttribute(Qt::WA_WState_Created));
+ if (mwTitle) {
+ XStoreName(X11->display, main_widget->effectiveWinId(), (char*)mwTitle);
+ QByteArray net_wm_name = QString::fromLocal8Bit(mwTitle).toUtf8();
+ XChangeProperty(X11->display, main_widget->effectiveWinId(), ATOM(_NET_WM_NAME), ATOM(UTF8_STRING), 8,
+ PropModeReplace, (unsigned char *)net_wm_name.data(), net_wm_name.size());
+ }
+ if (mwGeometry) { // parse geometry
+ int x, y;
+ int w, h;
+ int m = XParseGeometry((char*)mwGeometry, &x, &y, (uint*)&w, (uint*)&h);
+ QSize minSize = main_widget->minimumSize();
+ QSize maxSize = main_widget->maximumSize();
+ if ((m & XValue) == 0)
+ x = main_widget->geometry().x();
+ if ((m & YValue) == 0)
+ y = main_widget->geometry().y();
+ if ((m & WidthValue) == 0)
+ w = main_widget->width();
+ if ((m & HeightValue) == 0)
+ h = main_widget->height();
+ w = qMin(w,maxSize.width());
+ h = qMin(h,maxSize.height());
+ w = qMax(w,minSize.width());
+ h = qMax(h,minSize.height());
+ if ((m & XNegative)) {
+ x = QApplication::desktop()->width() + x - w;
+ }
+ if ((m & YNegative)) {
+ y = QApplication::desktop()->height() + y - h;
+ }
+ main_widget->setGeometry(x, y, w, h);
+ }
+}
+
+#ifndef QT_NO_CURSOR
+
+/*****************************************************************************
+ QApplication cursor stack
+ *****************************************************************************/
+
+void QApplication::setOverrideCursor(const QCursor &cursor)
+{
+ qApp->d_func()->cursor_list.prepend(cursor);
+
+ QWidgetList all = allWidgets();
+ for (QWidgetList::ConstIterator it = all.constBegin(); it != all.constEnd(); ++it) {
+ register QWidget *w = *it;
+ if ((w->testAttribute(Qt::WA_SetCursor) || w->isWindow()) && (w->windowType() != Qt::Desktop))
+ qt_x11_enforce_cursor(w);
+ }
+ XFlush(X11->display); // make X execute it NOW
+}
+
+void QApplication::restoreOverrideCursor()
+{
+ if (qApp->d_func()->cursor_list.isEmpty())
+ return;
+ qApp->d_func()->cursor_list.removeFirst();
+
+ if (QWidgetPrivate::mapper != 0 && !closingDown()) {
+ QWidgetList all = allWidgets();
+ for (QWidgetList::ConstIterator it = all.constBegin(); it != all.constEnd(); ++it) {
+ register QWidget *w = *it;
+ if ((w->testAttribute(Qt::WA_SetCursor) || w->isWindow()) && (w->windowType() != Qt::Desktop))
+ qt_x11_enforce_cursor(w);
+ }
+ XFlush(X11->display);
+ }
+}
+
+#endif
+
+
+/*****************************************************************************
+ Routines to find a Qt widget from a screen position
+ *****************************************************************************/
+
+Window QX11Data::findClientWindow(Window win, Atom property, bool leaf)
+{
+ Atom type = XNone;
+ int format, i;
+ ulong nitems, after;
+ uchar *data = 0;
+ Window root, parent, target=0, *children=0;
+ uint nchildren;
+ if (XGetWindowProperty(X11->display, win, property, 0, 0, false, AnyPropertyType,
+ &type, &format, &nitems, &after, &data) == Success) {
+ if (data)
+ XFree((char *)data);
+ if (type)
+ return win;
+ }
+ if (!XQueryTree(X11->display,win,&root,&parent,&children,&nchildren)) {
+ if (children)
+ XFree((char *)children);
+ return 0;
+ }
+ for (i=nchildren-1; !target && i >= 0; i--)
+ target = X11->findClientWindow(children[i], property, leaf);
+ if (children)
+ XFree((char *)children);
+ return target;
+}
+
+QWidget *QApplication::topLevelAt(const QPoint &p)
+{
+#ifdef QT_NO_CURSOR
+ Q_UNUSED(p);
+ return 0;
+#else
+ int screen = QCursor::x11Screen();
+ int unused;
+
+ int x = p.x();
+ int y = p.y();
+ Window target;
+ if (!XTranslateCoordinates(X11->display,
+ QX11Info::appRootWindow(screen),
+ QX11Info::appRootWindow(screen),
+ x, y, &unused, &unused, &target)) {
+ return 0;
+ }
+ if (!target || target == QX11Info::appRootWindow(screen))
+ return 0;
+ QWidget *w;
+ w = QWidget::find((WId)target);
+
+ if (!w) {
+ X11->ignoreBadwindow();
+ target = X11->findClientWindow(target, ATOM(WM_STATE), true);
+ if (X11->badwindow())
+ return 0;
+ w = QWidget::find((WId)target);
+ if (!w) {
+ // Perhaps the widget at (x,y) is inside a foreign application?
+ // Search all toplevel widgets to see if one is within target
+ QWidgetList list = QApplication::topLevelWidgets();
+ for (int i = 0; i < list.count(); ++i) {
+ QWidget *widget = list.at(i);
+ Window ctarget = target;
+ if (widget->isVisible() && !(widget->windowType() == Qt::Desktop)) {
+ Q_ASSERT(widget->testAttribute(Qt::WA_WState_Created));
+ Window wid = widget->internalWinId();
+ while (ctarget && !w) {
+ X11->ignoreBadwindow();
+ if (!XTranslateCoordinates(X11->display,
+ QX11Info::appRootWindow(screen),
+ ctarget, x, y, &unused, &unused, &ctarget)
+ || X11->badwindow())
+ break;
+ if (ctarget == wid) {
+ // Found!
+ w = widget;
+ break;
+ }
+ }
+ }
+ if (w)
+ break;
+ }
+ }
+ }
+ return w ? w->window() : 0;
+#endif
+}
+
+void QApplication::syncX()
+{
+ if (X11->display)
+ XSync(X11->display, False); // don't discard events
+}
+
+
+void QApplication::beep()
+{
+ if (X11->display)
+ XBell(X11->display, 0);
+ else
+ printf("\7");
+}
+
+void QApplication::alert(QWidget *widget, int msec)
+{
+ if (!QApplicationPrivate::checkInstance("alert"))
+ return;
+
+ QWidgetList windowsToMark;
+ if (!widget) {
+ windowsToMark += topLevelWidgets();
+ } else {
+ windowsToMark.append(widget->window());
+ }
+
+ for (int i = 0; i < windowsToMark.size(); ++i) {
+ QWidget *window = windowsToMark.at(i);
+ if (!window->isActiveWindow()) {
+ qt_change_net_wm_state(window, true, ATOM(_NET_WM_STATE_DEMANDS_ATTENTION));
+ if (msec != 0) {
+ QTimer *timer = new QTimer(qApp);
+ timer->setSingleShot(true);
+ connect(timer, SIGNAL(timeout()), qApp, SLOT(_q_alertTimeOut()));
+ if (QTimer *oldTimer = qApp->d_func()->alertTimerHash.value(window)) {
+ qApp->d_func()->alertTimerHash.remove(window);
+ delete oldTimer;
+ }
+ qApp->d_func()->alertTimerHash.insert(window, timer);
+ timer->start(msec);
+ }
+ }
+ }
+}
+
+void QApplicationPrivate::_q_alertTimeOut()
+{
+ if (QTimer *timer = qobject_cast<QTimer *>(q_func()->sender())) {
+ QHash<QWidget *, QTimer *>::iterator it = alertTimerHash.begin();
+ while (it != alertTimerHash.end()) {
+ if (it.value() == timer) {
+ QWidget *window = it.key();
+ qt_change_net_wm_state(window, false, ATOM(_NET_WM_STATE_DEMANDS_ATTENTION));
+ alertTimerHash.erase(it);
+ timer->deleteLater();
+ break;
+ }
+ ++it;
+ }
+ }
+}
+
+/*****************************************************************************
+ Special lookup functions for windows that have been reparented recently
+ *****************************************************************************/
+
+static QWidgetMapper *wPRmapper = 0; // alternative widget mapper
+
+void qPRCreate(const QWidget *widget, Window oldwin)
+{ // QWidget::reparent mechanism
+ if (!wPRmapper)
+ wPRmapper = new QWidgetMapper;
+
+ QETWidget *w = static_cast<QETWidget *>(const_cast<QWidget *>(widget));
+ wPRmapper->insert((int)oldwin, w); // add old window to mapper
+ w->setAttribute(Qt::WA_WState_Reparented); // set reparented flag
+}
+
+void qPRCleanup(QWidget *widget)
+{
+ QETWidget *etw = static_cast<QETWidget *>(const_cast<QWidget *>(widget));
+ if (!(wPRmapper && widget->testAttribute(Qt::WA_WState_Reparented)))
+ return; // not a reparented widget
+ QWidgetMapper::Iterator it = wPRmapper->begin();
+ while (it != wPRmapper->constEnd()) {
+ QWidget *w = *it;
+ if (w == etw) { // found widget
+ etw->setAttribute(Qt::WA_WState_Reparented, false); // clear flag
+ it = wPRmapper->erase(it);// old window no longer needed
+ } else {
+ ++it;
+ }
+ }
+ if (wPRmapper->size() == 0) { // became empty
+ delete wPRmapper; // then reset alt mapper
+ wPRmapper = 0;
+ }
+}
+
+static QETWidget *qPRFindWidget(Window oldwin)
+{
+ return wPRmapper ? (QETWidget*)wPRmapper->value((int)oldwin, 0) : 0;
+}
+
+int QApplication::x11ClientMessage(QWidget* w, XEvent* event, bool passive_only)
+{
+ if (w && !w->internalWinId())
+ return 0;
+ QETWidget *widget = (QETWidget*)w;
+ if (event->xclient.format == 32 && event->xclient.message_type) {
+ if (event->xclient.message_type == ATOM(WM_PROTOCOLS)) {
+ Atom a = event->xclient.data.l[0];
+ if (a == ATOM(WM_DELETE_WINDOW)) {
+ if (passive_only) return 0;
+ widget->translateCloseEvent(event);
+ }
+ else if (a == ATOM(WM_TAKE_FOCUS)) {
+ if ((ulong) event->xclient.data.l[1] > X11->time)
+ X11->time = event->xclient.data.l[1];
+ QWidget *amw = activeModalWidget();
+ if (amw && amw->testAttribute(Qt::WA_X11DoNotAcceptFocus))
+ amw = 0;
+ if (amw && !QApplicationPrivate::tryModalHelper(widget, 0)) {
+ QWidget *p = amw->parentWidget();
+ while (p && p != widget)
+ p = p->parentWidget();
+ if (!p || !X11->net_supported_list)
+ amw->raise(); // help broken window managers
+ amw->activateWindow();
+ }
+#ifndef QT_NO_WHATSTHIS
+ } else if (a == ATOM(_NET_WM_CONTEXT_HELP)) {
+ QWhatsThis::enterWhatsThisMode();
+#endif // QT_NO_WHATSTHIS
+ } else if (a == ATOM(_NET_WM_PING)) {
+ // avoid send/reply loops
+ Window root = RootWindow(X11->display, w->x11Info().screen());
+ if (event->xclient.window != root) {
+ event->xclient.window = root;
+ XSendEvent(event->xclient.display, event->xclient.window,
+ False, SubstructureNotifyMask|SubstructureRedirectMask, event);
+ }
+#ifndef QT_NO_XSYNC
+ } else if (a == ATOM(_NET_WM_SYNC_REQUEST)) {
+ const ulong timestamp = (const ulong) event->xclient.data.l[1];
+ if (timestamp > X11->time)
+ X11->time = timestamp;
+ if (QTLWExtra *tlw = w->d_func()->maybeTopData()) {
+ if (timestamp == CurrentTime || timestamp > tlw->syncRequestTimestamp) {
+ tlw->syncRequestTimestamp = timestamp;
+ tlw->newCounterValueLo = event->xclient.data.l[2];
+ tlw->newCounterValueHi = event->xclient.data.l[3];
+ }
+ }
+#endif
+ }
+ } else if (event->xclient.message_type == ATOM(_QT_SCROLL_DONE)) {
+ widget->translateScrollDoneEvent(event);
+ } else if (event->xclient.message_type == ATOM(XdndPosition)) {
+ X11->xdndHandlePosition(widget, event, passive_only);
+ } else if (event->xclient.message_type == ATOM(XdndEnter)) {
+ X11->xdndHandleEnter(widget, event, passive_only);
+ } else if (event->xclient.message_type == ATOM(XdndStatus)) {
+ X11->xdndHandleStatus(widget, event, passive_only);
+ } else if (event->xclient.message_type == ATOM(XdndLeave)) {
+ X11->xdndHandleLeave(widget, event, passive_only);
+ } else if (event->xclient.message_type == ATOM(XdndDrop)) {
+ X11->xdndHandleDrop(widget, event, passive_only);
+ } else if (event->xclient.message_type == ATOM(XdndFinished)) {
+ X11->xdndHandleFinished(widget, event, passive_only);
+ } else {
+ if (passive_only) return 0;
+ // All other are interactions
+ }
+ } else {
+ X11->motifdndHandle(widget, event, passive_only);
+ }
+
+ return 0;
+}
+
+int QApplication::x11ProcessEvent(XEvent* event)
+{
+ Q_D(QApplication);
+ QScopedLoopLevelCounter loopLevelCounter(d->threadData);
+
+#ifdef ALIEN_DEBUG
+ //qDebug() << "QApplication::x11ProcessEvent:" << event->type;
+#endif
+ switch (event->type) {
+ case ButtonPress:
+ pressed_window = event->xbutton.window;
+ X11->userTime = event->xbutton.time;
+ // fallthrough intended
+ case ButtonRelease:
+ X11->time = event->xbutton.time;
+ break;
+ case MotionNotify:
+ X11->time = event->xmotion.time;
+ break;
+ case XKeyPress:
+ X11->userTime = event->xkey.time;
+ // fallthrough intended
+ case XKeyRelease:
+ X11->time = event->xkey.time;
+ break;
+ case PropertyNotify:
+ X11->time = event->xproperty.time;
+ break;
+ case EnterNotify:
+ case LeaveNotify:
+ X11->time = event->xcrossing.time;
+ break;
+ case SelectionClear:
+ X11->time = event->xselectionclear.time;
+ break;
+ default:
+ break;
+ }
+#ifndef QT_NO_XFIXES
+ if (X11->use_xfixes && event->type == (X11->xfixes_eventbase + XFixesSelectionNotify)) {
+ XFixesSelectionNotifyEvent *req =
+ reinterpret_cast<XFixesSelectionNotifyEvent *>(event);
+ X11->time = req->selection_timestamp;
+ if (req->selection == ATOM(_NET_WM_CM_S0))
+ X11->compositingManagerRunning = req->owner;
+ }
+#endif
+
+ QETWidget *widget = (QETWidget*)QWidget::find((WId)event->xany.window);
+
+ if (wPRmapper) { // just did a widget reparent?
+ if (widget == 0) { // not in std widget mapper
+ switch (event->type) { // only for mouse/key events
+ case ButtonPress:
+ case ButtonRelease:
+ case MotionNotify:
+ case XKeyPress:
+ case XKeyRelease:
+ widget = qPRFindWidget(event->xany.window);
+ break;
+ }
+ }
+ else if (widget->testAttribute(Qt::WA_WState_Reparented))
+ qPRCleanup(widget); // remove from alt mapper
+ }
+
+ QETWidget *keywidget=0;
+ bool grabbed=false;
+ if (event->type==XKeyPress || event->type==XKeyRelease) {
+ keywidget = (QETWidget*)QWidget::keyboardGrabber();
+ if (keywidget) {
+ grabbed = true;
+ } else if (!keywidget) {
+ if (d->inPopupMode()) // no focus widget, see if we have a popup
+ keywidget = (QETWidget*) (activePopupWidget()->focusWidget() ? activePopupWidget()->focusWidget() : activePopupWidget());
+ else if (QApplicationPrivate::focus_widget)
+ keywidget = (QETWidget*)QApplicationPrivate::focus_widget;
+ else if (widget)
+ keywidget = (QETWidget*)widget->window();
+ }
+ }
+
+#ifndef QT_NO_IM
+ // Filtering input events by the input context. It has to be taken
+ // place before any other key event consumers such as eventfilters
+ // and accelerators because some input methods require quite
+ // various key combination and sequences. It often conflicts with
+ // accelerators and so on, so we must give the input context the
+ // filtering opportunity first to ensure all input methods work
+ // properly regardless of application design.
+
+ if(keywidget && keywidget->isEnabled() && keywidget->testAttribute(Qt::WA_InputMethodEnabled)) {
+ // block user interaction during session management
+ if((event->type==XKeyPress || event->type==XKeyRelease) && qt_sm_blockUserInput)
+ return true;
+
+ // for XIM handling
+ QInputContext *qic = keywidget->inputContext();
+ if(qic && qic->x11FilterEvent(keywidget, event))
+ return true;
+
+ // filterEvent() accepts QEvent *event rather than preexpanded
+ // key event attribute values. This is intended to pass other
+ // QInputEvent in future. Other non IM-related events should
+ // not be forwarded to input contexts to prevent weird event
+ // handling.
+ if ((event->type == XKeyPress || event->type == XKeyRelease)) {
+ int code = -1;
+ int count = 0;
+ Qt::KeyboardModifiers modifiers;
+ QEvent::Type type;
+ QString text;
+ KeySym keySym;
+
+ qt_keymapper_private()->translateKeyEventInternal(keywidget, event, keySym, count,
+ text, modifiers, code, type, false);
+
+ // both key press/release is required for some complex
+ // input methods. don't eliminate anything.
+ QKeyEventEx keyevent(type, code, modifiers, text, false, qMax(qMax(count, 1), text.length()),
+ event->xkey.keycode, keySym, event->xkey.state);
+ if(qic && qic->filterEvent(&keyevent))
+ return true;
+ }
+ } else
+#endif // QT_NO_IM
+ {
+ if (XFilterEvent(event, XNone))
+ return true;
+ }
+
+ if (qt_x11EventFilter(event)) // send through app filter
+ return 1;
+
+ if (event->type == MappingNotify) {
+ // keyboard mapping changed
+ XRefreshKeyboardMapping(&event->xmapping);
+
+ QKeyMapper::changeKeyboard();
+ return 0;
+ }
+#ifndef QT_NO_XKB
+ else if (X11->use_xkb && event->type == X11->xkb_eventbase) {
+ XkbAnyEvent *xkbevent = (XkbAnyEvent *) event;
+ switch (xkbevent->xkb_type) {
+ case XkbStateNotify:
+ {
+ XkbStateNotifyEvent *xkbstateevent = (XkbStateNotifyEvent *) xkbevent;
+ if ((xkbstateevent->changed & XkbGroupStateMask) != 0) {
+ qt_keymapper_private()->xkb_currentGroup = xkbstateevent->group;
+ QKeyMapper::changeKeyboard();
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+#endif
+
+ if (!widget) { // don't know this windows
+ QWidget* popup = QApplication::activePopupWidget();
+ if (popup) {
+
+ /*
+ That is more than suboptimal. The real solution should
+ do some keyevent and buttonevent translation, so that
+ the popup still continues to work as the user expects.
+ Unfortunately this translation is currently only
+ possible with a known widget. I'll change that soon
+ (Matthias).
+ */
+
+ // Danger - make sure we don't lock the server
+ switch (event->type) {
+ case ButtonPress:
+ case ButtonRelease:
+ case XKeyPress:
+ case XKeyRelease:
+ do {
+ popup->close();
+ } while ((popup = qApp->activePopupWidget()));
+ return 1;
+ }
+ }
+ return -1;
+ }
+
+ if (event->type == XKeyPress || event->type == XKeyRelease)
+ widget = keywidget; // send XKeyEvents through keywidget->x11Event()
+
+ if (app_do_modal) // modal event handling
+ if (!qt_try_modal(widget, event)) {
+ if (event->type == ClientMessage && !widget->x11Event(event))
+ x11ClientMessage(widget, event, true);
+ return 1;
+ }
+
+
+ if (widget->x11Event(event)) // send through widget filter
+ return 1;
+#if !defined (QT_NO_TABLET)
+ if (!qt_xdnd_dragging) {
+ QTabletDeviceDataList *tablets = qt_tablet_devices();
+ for (int i = 0; i < tablets->size(); ++i) {
+ QTabletDeviceData &tab = tablets->operator [](i);
+ if (event->type == tab.xinput_motion
+ || event->type == tab.xinput_button_release
+ || event->type == tab.xinput_button_press
+ || event->type == tab.xinput_proximity_in
+ || event->type == tab.xinput_proximity_out) {
+ widget->translateXinputEvent(event, &tab);
+ return 0;
+ }
+ }
+ }
+#endif
+
+#ifndef QT_NO_XRANDR
+ if (X11->use_xrandr && event->type == (X11->xrandr_eventbase + RRScreenChangeNotify)) {
+ // update Xlib internals with the latest screen configuration
+ X11->ptrXRRUpdateConfiguration(event);
+
+ // update the size for desktop widget
+ int scr = X11->ptrXRRRootToScreen(X11->display, event->xany.window);
+ 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));
+ QResizeEvent e(w->size(), oldSize);
+ QApplication::sendEvent(w, &e);
+ if (w != desktop)
+ QApplication::sendEvent(desktop, &e);
+ }
+#endif // QT_NO_XRANDR
+
+#ifndef QT_NO_XFIXES
+ if (X11->use_xfixes && event->type == (X11->xfixes_eventbase + XFixesSelectionNotify)) {
+ XFixesSelectionNotifyEvent *req = reinterpret_cast<XFixesSelectionNotifyEvent *>(event);
+
+ // compress all XFixes events related to this selection
+ // we don't want to handle old SelectionNotify events.
+ qt_xfixes_selection_event_data xfixes_event;
+ xfixes_event.selection = req->selection;
+ for (XEvent ev;;) {
+ if (!XCheckIfEvent(X11->display, &ev, &qt_xfixes_scanner, (XPointer)&xfixes_event))
+ break;
+ }
+
+ if (req->selection == ATOM(CLIPBOARD)) {
+ if (qt_xfixes_clipboard_changed(req->owner, req->selection_timestamp)) {
+ emit clipboard()->changed(QClipboard::Clipboard);
+ emit clipboard()->dataChanged();
+ }
+ } else if (req->selection == XA_PRIMARY) {
+ if (qt_xfixes_selection_changed(req->owner, req->selection_timestamp)) {
+ emit clipboard()->changed(QClipboard::Selection);
+ emit clipboard()->selectionChanged();
+ }
+ }
+ }
+#endif // QT_NO_XFIXES
+
+ switch (event->type) {
+
+ case ButtonRelease: // mouse event
+ if (!d->inPopupMode() && !QWidget::mouseGrabber() && pressed_window != widget->internalWinId()
+ && (widget = (QETWidget*) QWidget::find((WId)pressed_window)) == 0)
+ break;
+ // fall through intended
+ case ButtonPress:
+ if (event->xbutton.root != RootWindow(X11->display, widget->x11Info().screen())
+ && ! qt_xdnd_dragging) {
+ while (activePopupWidget())
+ activePopupWidget()->close();
+ return 1;
+ }
+ if (event->type == ButtonPress)
+ qt_net_update_user_time(widget->window(), X11->userTime);
+ // fall through intended
+ case MotionNotify:
+#if !defined(QT_NO_TABLET)
+ if (!qt_tabletChokeMouse) {
+#endif
+ if (widget->testAttribute(Qt::WA_TransparentForMouseEvents)) {
+ QPoint pos(event->xbutton.x, event->xbutton.y);
+ pos = widget->d_func()->mapFromWS(pos);
+ QWidget *window = widget->window();
+ pos = widget->mapTo(window, pos);
+ if (QWidget *child = window->childAt(pos)) {
+ widget = static_cast<QETWidget *>(child);
+ pos = child->mapFrom(window, pos);
+ event->xbutton.x = pos.x();
+ event->xbutton.y = pos.y();
+ }
+ }
+ widget->translateMouseEvent(event);
+#if !defined(QT_NO_TABLET)
+ } else {
+ qt_tabletChokeMouse = false;
+ }
+#endif
+ break;
+
+ case XKeyPress: // keyboard event
+ qt_net_update_user_time(widget->window(), X11->userTime);
+ // fallthrough intended
+ case XKeyRelease:
+ {
+ if (keywidget && keywidget->isEnabled()) { // should always exist
+ // qDebug("sending key event");
+ qt_keymapper_private()->translateKeyEvent(keywidget, event, grabbed);
+ }
+ break;
+ }
+
+ case GraphicsExpose:
+ case Expose: // paint event
+ widget->translatePaintEvent(event);
+ break;
+
+ case ConfigureNotify: // window move/resize event
+ if (event->xconfigure.event == event->xconfigure.window)
+ widget->translateConfigEvent(event);
+ break;
+
+ case XFocusIn: { // got focus
+ if ((widget->windowType() == Qt::Desktop))
+ break;
+ if (d->inPopupMode()) // some delayed focus event to ignore
+ break;
+ if (!widget->isWindow())
+ break;
+ if (event->xfocus.detail != NotifyAncestor &&
+ event->xfocus.detail != NotifyInferior &&
+ event->xfocus.detail != NotifyNonlinear)
+ break;
+ setActiveWindow(widget);
+ if (X11->focus_model == QX11Data::FM_PointerRoot) {
+ // We got real input focus from somewhere, but we were in PointerRoot
+ // mode, so we don't trust this event. Check the focus model to make
+ // sure we know what focus mode we are using...
+ qt_check_focus_model();
+ }
+ }
+ break;
+
+ case XFocusOut: // lost focus
+ if ((widget->windowType() == Qt::Desktop))
+ break;
+ if (!widget->isWindow())
+ break;
+ if (event->xfocus.mode == NotifyGrab) {
+ qt_xfocusout_grab_counter++;
+ break;
+ }
+ if (event->xfocus.detail != NotifyAncestor &&
+ event->xfocus.detail != NotifyNonlinearVirtual &&
+ event->xfocus.detail != NotifyNonlinear)
+ break;
+ if (!d->inPopupMode() && widget == QApplicationPrivate::active_window) {
+ XEvent ev;
+ bool focus_will_change = false;
+ if (XCheckTypedEvent(X11->display, XFocusIn, &ev)) {
+ // we're about to get an XFocusIn, if we know we will
+ // get a new active window, we don't want to set the
+ // active window to 0 now
+ QWidget *w2 = QWidget::find(ev.xany.window);
+ if (w2
+ && w2->windowType() != Qt::Desktop
+ && !d->inPopupMode() // some delayed focus event to ignore
+ && w2->isWindow()
+ && (ev.xfocus.detail == NotifyAncestor
+ || ev.xfocus.detail == NotifyInferior
+ || ev.xfocus.detail == NotifyNonlinear))
+ focus_will_change = true;
+
+ XPutBackEvent(X11->display, &ev);
+ }
+ if (!focus_will_change)
+ setActiveWindow(0);
+ }
+ break;
+
+ case EnterNotify: { // enter window
+ if (QWidget::mouseGrabber() && (!d->inPopupMode() || widget->window() != activePopupWidget()))
+ break;
+ if ((event->xcrossing.mode != NotifyNormal
+ && event->xcrossing.mode != NotifyUngrab)
+ || event->xcrossing.detail == NotifyVirtual
+ || event->xcrossing.detail == NotifyNonlinearVirtual)
+ break;
+ if (event->xcrossing.focus &&
+ !(widget->windowType() == Qt::Desktop) && !widget->isActiveWindow()) {
+ if (X11->focus_model == QX11Data::FM_Unknown) // check focus model
+ qt_check_focus_model();
+ if (X11->focus_model == QX11Data::FM_PointerRoot) // PointerRoot mode
+ setActiveWindow(widget);
+ }
+
+ if (qt_button_down && !d->inPopupMode())
+ break;
+
+ QWidget *alien = widget->childAt(widget->d_func()->mapFromWS(QPoint(event->xcrossing.x,
+ event->xcrossing.y)));
+ QWidget *enter = alien ? alien : widget;
+ QWidget *leave = 0;
+ if (qt_last_mouse_receiver && !qt_last_mouse_receiver->internalWinId())
+ leave = qt_last_mouse_receiver;
+ else
+ leave = QWidget::find(curWin);
+
+ // ### Alien: enter/leave might be wrong here with overlapping siblings
+ // if the enter widget is native and stacked under a non-native widget.
+ QApplicationPrivate::dispatchEnterLeave(enter, leave);
+ curWin = widget->internalWinId();
+ qt_last_mouse_receiver = enter;
+ if (!d->inPopupMode() || widget->window() == activePopupWidget())
+ widget->translateMouseEvent(event); //we don't get MotionNotify, emulate it
+ }
+ break;
+ case LeaveNotify: { // leave window
+ QWidget *mouseGrabber = QWidget::mouseGrabber();
+ if (mouseGrabber && !d->inPopupMode())
+ break;
+ if (curWin && widget->internalWinId() != curWin)
+ break;
+ if ((event->xcrossing.mode != NotifyNormal
+ && event->xcrossing.mode != NotifyUngrab)
+ || event->xcrossing.detail == NotifyInferior)
+ break;
+ if (!(widget->windowType() == Qt::Desktop))
+ widget->translateMouseEvent(event); //we don't get MotionNotify, emulate it
+
+ QWidget* enter = 0;
+ QPoint enterPoint;
+ XEvent ev;
+ while (XCheckMaskEvent(X11->display, EnterWindowMask | LeaveWindowMask , &ev)
+ && !qt_x11EventFilter(&ev)) {
+ QWidget* event_widget = QWidget::find(ev.xcrossing.window);
+ if(event_widget && event_widget->x11Event(&ev))
+ break;
+ if (ev.type == LeaveNotify
+ || (ev.xcrossing.mode != NotifyNormal
+ && ev.xcrossing.mode != NotifyUngrab)
+ || ev.xcrossing.detail == NotifyVirtual
+ || ev.xcrossing.detail == NotifyNonlinearVirtual)
+ continue;
+ enter = event_widget;
+ if (enter)
+ enterPoint = enter->d_func()->mapFromWS(QPoint(ev.xcrossing.x, ev.xcrossing.y));
+ if (ev.xcrossing.focus &&
+ enter && !(enter->windowType() == Qt::Desktop) && !enter->isActiveWindow()) {
+ if (X11->focus_model == QX11Data::FM_Unknown) // check focus model
+ qt_check_focus_model();
+ if (X11->focus_model == QX11Data::FM_PointerRoot) // PointerRoot mode
+ setActiveWindow(enter);
+ }
+ break;
+ }
+
+ if ((! enter || (enter->windowType() == Qt::Desktop)) &&
+ event->xcrossing.focus && widget == QApplicationPrivate::active_window &&
+ X11->focus_model == QX11Data::FM_PointerRoot // PointerRoot mode
+ ) {
+ setActiveWindow(0);
+ }
+
+ if (qt_button_down && !d->inPopupMode())
+ break;
+
+ if (!curWin)
+ QApplicationPrivate::dispatchEnterLeave(widget, 0);
+
+ if (enter) {
+ QWidget *alienEnter = enter->childAt(enterPoint);
+ if (alienEnter)
+ enter = alienEnter;
+ }
+
+ QWidget *leave = qt_last_mouse_receiver ? qt_last_mouse_receiver : widget;
+ QWidget *activePopupWidget = qApp->activePopupWidget();
+
+ if (mouseGrabber && activePopupWidget && leave == activePopupWidget)
+ enter = mouseGrabber;
+ else if (enter != widget && mouseGrabber) {
+ if (!widget->rect().contains(widget->d_func()->mapFromWS(QPoint(event->xcrossing.x,
+ event->xcrossing.y))))
+ break;
+ }
+
+ QApplicationPrivate::dispatchEnterLeave(enter, leave);
+ qt_last_mouse_receiver = enter;
+
+ if (enter && QApplicationPrivate::tryModalHelper(enter, 0)) {
+ QWidget *nativeEnter = enter->internalWinId() ? enter : enter->nativeParentWidget();
+ curWin = nativeEnter->internalWinId();
+ static_cast<QETWidget *>(nativeEnter)->translateMouseEvent(&ev); //we don't get MotionNotify, emulate it
+ } else {
+ curWin = 0;
+ qt_last_mouse_receiver = 0;
+ }
+ }
+ break;
+
+ case UnmapNotify: // window hidden
+ if (widget->isWindow()) {
+ Q_ASSERT(widget->testAttribute(Qt::WA_WState_Created));
+ widget->d_func()->topData()->waitingForMapNotify = 0;
+
+ if (widget->windowType() != Qt::Popup && !widget->testAttribute(Qt::WA_DontShowOnScreen)) {
+ widget->setAttribute(Qt::WA_Mapped, false);
+ if (widget->isVisible()) {
+ widget->d_func()->topData()->spont_unmapped = 1;
+ QHideEvent e;
+ QApplication::sendSpontaneousEvent(widget, &e);
+ widget->d_func()->hideChildren(true);
+ }
+ }
+
+ if (!widget->d_func()->topData()->validWMState && X11->deferred_map.removeAll(widget))
+ widget->doDeferredMap();
+ }
+ break;
+
+ case MapNotify: // window shown
+ if (widget->isWindow()) {
+ // if we got a MapNotify when we were not waiting for it, it most
+ // likely means the user has already asked to hide the window before
+ // it ever being shown, so we try to withdraw a window after sending
+ // the QShowEvent.
+ bool pendingHide = widget->testAttribute(Qt::WA_WState_ExplicitShowHide) && widget->testAttribute(Qt::WA_WState_Hidden);
+ widget->d_func()->topData()->waitingForMapNotify = 0;
+
+ if (widget->windowType() != Qt::Popup) {
+ widget->setAttribute(Qt::WA_Mapped);
+ if (widget->d_func()->topData()->spont_unmapped) {
+ widget->d_func()->topData()->spont_unmapped = 0;
+ widget->d_func()->showChildren(true);
+ QShowEvent e;
+ QApplication::sendSpontaneousEvent(widget, &e);
+
+ // show() must have been called on this widget in
+ // order to reach this point, but we could have
+ // cleared these 2 attributes in case something
+ // previously forced us into WithdrawnState
+ // (e.g. kdocker)
+ widget->setAttribute(Qt::WA_WState_ExplicitShowHide, true);
+ widget->setAttribute(Qt::WA_WState_Visible, true);
+ }
+ }
+ if (pendingHide) // hide the window
+ XWithdrawWindow(X11->display, widget->internalWinId(), widget->x11Info().screen());
+ }
+ break;
+
+ case ClientMessage: // client message
+ return x11ClientMessage(widget,event,False);
+
+ case ReparentNotify: { // window manager reparents
+ // compress old reparent events to self
+ XEvent ev;
+ while (XCheckTypedWindowEvent(X11->display,
+ widget->effectiveWinId(),
+ ReparentNotify,
+ &ev)) {
+ if (ev.xreparent.window != ev.xreparent.event) {
+ XPutBackEvent(X11->display, &ev);
+ break;
+ }
+ }
+ if (widget->isWindow()) {
+ QTLWExtra *topData = widget->d_func()->topData();
+
+ // store the parent. Useful for many things, embedding for instance.
+ topData->parentWinId = event->xreparent.parent;
+
+ // the widget frame strut should also be invalidated
+ widget->data->fstrut_dirty = 1;
+
+ // work around broken window managers... if we get a
+ // ReparentNotify before the MapNotify, we assume that
+ // we're being managed by a reparenting window
+ // manager.
+ //
+ // however, the WM_STATE property may not have been set
+ // yet, but we are going to assume that it will
+ // be... otherwise we could try to map again after getting
+ // an UnmapNotify... which could then, in turn, trigger a
+ // race in the window manager which causes the window to
+ // disappear when it really should be hidden.
+ if (topData->waitingForMapNotify && !topData->validWMState) {
+ topData->waitingForMapNotify = 0;
+ topData->validWMState = 1;
+ }
+
+ if (X11->focus_model != QX11Data::FM_Unknown) {
+ // toplevel reparented...
+ QWidget *newparent = QWidget::find(event->xreparent.parent);
+ if (! newparent || (newparent->windowType() == Qt::Desktop)) {
+ // we don't know about the new parent (or we've been
+ // reparented to root), perhaps a window manager
+ // has been (re)started? reset the focus model to unknown
+ X11->focus_model = QX11Data::FM_Unknown;
+ }
+ }
+ }
+ break;
+ }
+ case SelectionRequest: {
+ XSelectionRequestEvent *req = &event->xselectionrequest;
+ if (! req)
+ break;
+
+ if (ATOM(XdndSelection) && req->selection == ATOM(XdndSelection)) {
+ X11->xdndHandleSelectionRequest(req);
+
+ } else if (qt_clipboard) {
+ QClipboardEvent e(reinterpret_cast<QEventPrivate*>(event));
+ QApplication::sendSpontaneousEvent(qt_clipboard, &e);
+ }
+ break;
+ }
+ case SelectionClear: {
+ XSelectionClearEvent *req = &event->xselectionclear;
+ // don't deliver dnd events to the clipboard, it gets confused
+ if (! req || (ATOM(XdndSelection) && req->selection == ATOM(XdndSelection)))
+ break;
+
+ if (qt_clipboard && !X11->use_xfixes) {
+ QClipboardEvent e(reinterpret_cast<QEventPrivate*>(event));
+ QApplication::sendSpontaneousEvent(qt_clipboard, &e);
+ }
+ break;
+ }
+
+ case SelectionNotify: {
+ XSelectionEvent *req = &event->xselection;
+ // don't deliver dnd events to the clipboard, it gets confused
+ if (! req || (ATOM(XdndSelection) && req->selection == ATOM(XdndSelection)))
+ break;
+
+ if (qt_clipboard) {
+ QClipboardEvent e(reinterpret_cast<QEventPrivate*>(event));
+ QApplication::sendSpontaneousEvent(qt_clipboard, &e);
+ }
+ break;
+ }
+ case PropertyNotify:
+ // some properties changed
+ if (event->xproperty.window == QX11Info::appRootWindow(0)) {
+ // root properties for the first screen
+ if (!X11->use_xfixes && event->xproperty.atom == ATOM(_QT_CLIPBOARD_SENTINEL)) {
+ if (qt_check_clipboard_sentinel()) {
+ emit clipboard()->changed(QClipboard::Clipboard);
+ emit clipboard()->dataChanged();
+ }
+ } else if (!X11->use_xfixes && event->xproperty.atom == ATOM(_QT_SELECTION_SENTINEL)) {
+ if (qt_check_selection_sentinel()) {
+ emit clipboard()->changed(QClipboard::Selection);
+ emit clipboard()->selectionChanged();
+ }
+ } else if (QApplicationPrivate::obey_desktop_settings) {
+ if (event->xproperty.atom == ATOM(RESOURCE_MANAGER))
+ qt_set_x11_resources();
+ else if (event->xproperty.atom == ATOM(_QT_SETTINGS_TIMESTAMP))
+ qt_set_x11_resources();
+ }
+ }
+ if (event->xproperty.window == QX11Info::appRootWindow()) {
+ // root properties for the default screen
+ if (event->xproperty.atom == ATOM(_QT_INPUT_ENCODING)) {
+ qt_set_input_encoding();
+ } else if (event->xproperty.atom == ATOM(_NET_SUPPORTED)) {
+ qt_get_net_supported();
+ } else if (event->xproperty.atom == ATOM(_NET_VIRTUAL_ROOTS)) {
+ qt_get_net_virtual_roots();
+ } else if (event->xproperty.atom == ATOM(_NET_WORKAREA)) {
+ qt_desktopwidget_update_workarea();
+
+ // emit the workAreaResized() signal
+ QDesktopWidget *desktop = QApplication::desktop();
+ int numScreens = desktop->numScreens();
+ for (int i = 0; i < numScreens; ++i)
+ emit desktop->workAreaResized(i);
+ }
+ } else if (widget) {
+ widget->translatePropertyEvent(event);
+ } else {
+ return -1; // don't know this window
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+bool QApplication::x11EventFilter(XEvent *)
+{
+ return false;
+}
+
+
+
+/*****************************************************************************
+ Modal widgets; Since Xlib has little support for this we roll our own
+ modal widget mechanism.
+ A modal widget without a parent becomes application-modal.
+ A modal widget with a parent becomes modal to its parent and grandparents..
+
+ QApplicationPrivate::enterModal()
+ Enters modal state
+ Arguments:
+ QWidget *widget A modal widget
+
+ QApplicationPrivate::leaveModal()
+ Leaves modal state for a widget
+ Arguments:
+ QWidget *widget A modal widget
+ *****************************************************************************/
+
+bool QApplicationPrivate::modalState()
+{
+ return app_do_modal;
+}
+
+void QApplicationPrivate::enterModal_sys(QWidget *widget)
+{
+ if (!qt_modal_stack)
+ qt_modal_stack = new QWidgetList;
+
+ QWidget *leave = qt_last_mouse_receiver;
+ if (!leave)
+ leave = QWidget::find((WId)curWin);
+ QApplicationPrivate::dispatchEnterLeave(0, leave);
+ qt_modal_stack->insert(0, widget);
+ app_do_modal = true;
+ curWin = 0;
+ qt_last_mouse_receiver = 0;
+}
+
+void QApplicationPrivate::leaveModal_sys(QWidget *widget)
+{
+ if (qt_modal_stack && qt_modal_stack->removeAll(widget)) {
+ if (qt_modal_stack->isEmpty()) {
+ delete qt_modal_stack;
+ qt_modal_stack = 0;
+ QPoint p(QCursor::pos());
+ QWidget* w = QApplication::widgetAt(p.x(), p.y());
+ QWidget *leave = qt_last_mouse_receiver;
+ if (!leave)
+ leave = QWidget::find((WId)curWin);
+ if (QWidget *grabber = QWidget::mouseGrabber()) {
+ w = grabber;
+ if (leave == w)
+ leave = 0;
+ }
+ QApplicationPrivate::dispatchEnterLeave(w, leave); // send synthetic enter event
+ curWin = w ? w->effectiveWinId() : 0;
+ qt_last_mouse_receiver = w;
+ }
+ }
+ app_do_modal = qt_modal_stack != 0;
+}
+
+bool qt_try_modal(QWidget *widget, XEvent *event)
+{
+ if (qt_xdnd_dragging) {
+ // allow mouse events while DnD is active
+ switch (event->type) {
+ case ButtonPress:
+ case ButtonRelease:
+ case MotionNotify:
+ return true;
+ default:
+ break;
+ }
+ }
+
+ // allow mouse release events to be sent to widgets that have been pressed
+ if (event->type == ButtonRelease) {
+ QWidget *alienWidget = widget->childAt(widget->mapFromGlobal(QPoint(event->xbutton.x_root,
+ event->xbutton.y_root)));
+ if (widget == qt_button_down || (alienWidget && alienWidget == qt_button_down))
+ return true;
+ }
+
+ if (QApplicationPrivate::tryModalHelper(widget))
+ return true;
+
+ // disallow mouse/key events
+ switch (event->type) {
+ case ButtonPress:
+ case ButtonRelease:
+ case MotionNotify:
+ case XKeyPress:
+ case XKeyRelease:
+ case EnterNotify:
+ case LeaveNotify:
+ case ClientMessage:
+ return false;
+ default:
+ break;
+ }
+
+ return true;
+}
+
+
+/*****************************************************************************
+ Popup widget mechanism
+
+ openPopup()
+ Adds a widget to the list of popup widgets
+ Arguments:
+ QWidget *widget The popup widget to be added
+
+ closePopup()
+ Removes a widget from the list of popup widgets
+ Arguments:
+ QWidget *widget The popup widget to be removed
+ *****************************************************************************/
+
+
+static int openPopupCount = 0;
+void QApplicationPrivate::openPopup(QWidget *popup)
+{
+ Q_Q(QApplication);
+ openPopupCount++;
+ if (!QApplicationPrivate::popupWidgets) { // create list
+ QApplicationPrivate::popupWidgets = new QWidgetList;
+ }
+ QApplicationPrivate::popupWidgets->append(popup); // add to end of list
+ Display *dpy = X11->display;
+ if (QApplicationPrivate::popupWidgets->count() == 1 && !qt_nograb()){ // grab mouse/keyboard
+ Q_ASSERT(popup->testAttribute(Qt::WA_WState_Created));
+ int r = XGrabKeyboard(dpy, popup->effectiveWinId(), false,
+ GrabModeAsync, GrabModeAsync, X11->time);
+ if ((popupGrabOk = (r == GrabSuccess))) {
+ r = XGrabPointer(dpy, popup->effectiveWinId(), true,
+ (ButtonPressMask | ButtonReleaseMask | ButtonMotionMask
+ | EnterWindowMask | LeaveWindowMask | PointerMotionMask),
+ GrabModeAsync, GrabModeAsync, XNone, XNone, X11->time);
+ if (!(popupGrabOk = (r == GrabSuccess))) {
+ // transfer grab back to the keyboard grabber if any
+ if (QWidgetPrivate::keyboardGrabber != 0)
+ QWidgetPrivate::keyboardGrabber->grabKeyboard();
+ else
+ XUngrabKeyboard(dpy, X11->time);
+ }
+ }
+ }
+
+ // popups are not focus-handled by the window system (the first
+ // popup grabbed the keyboard), so we have to do that manually: A
+ // new popup gets the focus
+ if (popup->focusWidget()) {
+ popup->focusWidget()->setFocus(Qt::PopupFocusReason);
+ } else if (QApplicationPrivate::popupWidgets->count() == 1) { // this was the first popup
+ if (QWidget *fw = QApplication::focusWidget()) {
+ QFocusEvent e(QEvent::FocusOut, Qt::PopupFocusReason);
+ q->sendEvent(fw, &e);
+ }
+ }
+}
+
+void QApplicationPrivate::closePopup(QWidget *popup)
+{
+ Q_Q(QApplication);
+ if (!QApplicationPrivate::popupWidgets)
+ return;
+ QApplicationPrivate::popupWidgets->removeAll(popup);
+ if (popup == qt_popup_down) {
+ qt_button_down = 0;
+ qt_popup_down = 0;
+ }
+ if (QApplicationPrivate::popupWidgets->count() == 0) { // this was the last popup
+ delete QApplicationPrivate::popupWidgets;
+ QApplicationPrivate::popupWidgets = 0;
+ if (!qt_nograb() && popupGrabOk) { // grabbing not disabled
+ Display *dpy = X11->display;
+ if (popup->geometry().contains(QPoint(mouseGlobalXPos, mouseGlobalYPos))
+ || popup->testAttribute(Qt::WA_NoMouseReplay)) {
+ // mouse release event or inside
+ replayPopupMouseEvent = false;
+ } else { // mouse press event
+ mouseButtonPressTime -= 10000; // avoid double click
+ replayPopupMouseEvent = true;
+ }
+ // transfer grab back to mouse grabber if any, otherwise release the grab
+ if (QWidgetPrivate::mouseGrabber != 0)
+ QWidgetPrivate::mouseGrabber->grabMouse();
+ else
+ XUngrabPointer(dpy, X11->time);
+
+ // transfer grab back to keyboard grabber if any, otherwise release the grab
+ if (QWidgetPrivate::keyboardGrabber != 0)
+ QWidgetPrivate::keyboardGrabber->grabKeyboard();
+ else
+ XUngrabKeyboard(dpy, X11->time);
+
+ XFlush(dpy);
+ }
+ if (QApplicationPrivate::active_window) {
+ if (QWidget *fw = QApplicationPrivate::active_window->focusWidget()) {
+ if (fw != QApplication::focusWidget()) {
+ fw->setFocus(Qt::PopupFocusReason);
+ } else {
+ QFocusEvent e(QEvent::FocusIn, Qt::PopupFocusReason);
+ q->sendEvent(fw, &e);
+ }
+ }
+ }
+ } else {
+ // popups are not focus-handled by the window system (the
+ // first popup grabbed the keyboard), so we have to do that
+ // manually: A popup was closed, so the previous popup gets
+ // the focus.
+ QWidget* aw = QApplicationPrivate::popupWidgets->last();
+ if (QWidget *fw = aw->focusWidget())
+ fw->setFocus(Qt::PopupFocusReason);
+
+ // regrab the keyboard and mouse in case 'popup' lost the grab
+ if (QApplicationPrivate::popupWidgets->count() == 1 && !qt_nograb()){ // grab mouse/keyboard
+ Display *dpy = X11->display;
+ Q_ASSERT(aw->testAttribute(Qt::WA_WState_Created));
+ int r = XGrabKeyboard(dpy, aw->effectiveWinId(), false,
+ GrabModeAsync, GrabModeAsync, X11->time);
+ if ((popupGrabOk = (r == GrabSuccess))) {
+ r = XGrabPointer(dpy, aw->effectiveWinId(), true,
+ (ButtonPressMask | ButtonReleaseMask | ButtonMotionMask
+ | EnterWindowMask | LeaveWindowMask | PointerMotionMask),
+ GrabModeAsync, GrabModeAsync, XNone, XNone, X11->time);
+ if (!(popupGrabOk = (r == GrabSuccess))) {
+ // transfer grab back to keyboard grabber
+ if (QWidgetPrivate::keyboardGrabber != 0)
+ QWidgetPrivate::keyboardGrabber->grabKeyboard();
+ else
+ XUngrabKeyboard(dpy, X11->time);
+ }
+ }
+ }
+ }
+}
+
+/*****************************************************************************
+ Event translation; translates X11 events to Qt events
+ *****************************************************************************/
+
+//
+// Mouse event translation
+//
+// Xlib doesn't give mouse double click events, so we generate them by
+// comparing window, time and position between two mouse press events.
+//
+
+static Qt::MouseButtons translateMouseButtons(int s)
+{
+ Qt::MouseButtons ret = 0;
+ if (s & Button1Mask)
+ ret |= Qt::LeftButton;
+ if (s & Button2Mask)
+ ret |= Qt::MidButton;
+ if (s & Button3Mask)
+ ret |= Qt::RightButton;
+ return ret;
+}
+
+Qt::KeyboardModifiers QX11Data::translateModifiers(int s)
+{
+ Qt::KeyboardModifiers ret = 0;
+ if (s & ShiftMask)
+ ret |= Qt::ShiftModifier;
+ if (s & ControlMask)
+ ret |= Qt::ControlModifier;
+ if (s & qt_alt_mask)
+ ret |= Qt::AltModifier;
+ if (s & qt_meta_mask)
+ ret |= Qt::MetaModifier;
+ if (s & qt_mode_switch_mask)
+ ret |= Qt::GroupSwitchModifier;
+ return ret;
+}
+
+bool QETWidget::translateMouseEvent(const XEvent *event)
+{
+ if (!isWindow() && testAttribute(Qt::WA_NativeWindow))
+ Q_ASSERT(internalWinId());
+
+ Q_D(QWidget);
+ QEvent::Type type; // event parameters
+ QPoint pos;
+ QPoint globalPos;
+ Qt::MouseButton button = Qt::NoButton;
+ Qt::MouseButtons buttons;
+ Qt::KeyboardModifiers modifiers;
+ XEvent nextEvent;
+
+ if (qt_sm_blockUserInput) // block user interaction during session management
+ return true;
+
+ if (event->type == MotionNotify) { // mouse move
+ if (event->xmotion.root != RootWindow(X11->display, x11Info().screen()) &&
+ ! qt_xdnd_dragging)
+ return false;
+
+ XMotionEvent lastMotion = event->xmotion;
+ while(XPending(X11->display)) { // compress mouse moves
+ XNextEvent(X11->display, &nextEvent);
+ if (nextEvent.type == ConfigureNotify
+ || nextEvent.type == PropertyNotify
+ || nextEvent.type == Expose
+ || nextEvent.type == GraphicsExpose
+ || nextEvent.type == NoExpose
+ || nextEvent.type == KeymapNotify
+ || ((nextEvent.type == EnterNotify || nextEvent.type == LeaveNotify)
+ && qt_button_down == this)
+ || (nextEvent.type == ClientMessage
+ && (nextEvent.xclient.message_type == ATOM(_QT_SCROLL_DONE) ||
+ (nextEvent.xclient.message_type == ATOM(WM_PROTOCOLS) &&
+ (Atom)nextEvent.xclient.data.l[0] == ATOM(_NET_WM_SYNC_REQUEST))))) {
+ qApp->x11ProcessEvent(&nextEvent);
+ continue;
+ } else if (nextEvent.type != MotionNotify ||
+ nextEvent.xmotion.window != event->xmotion.window ||
+ nextEvent.xmotion.state != event->xmotion.state) {
+ XPutBackEvent(X11->display, &nextEvent);
+ break;
+ }
+ if (!qt_x11EventFilter(&nextEvent)
+ && !x11Event(&nextEvent)) // send event through filter
+ lastMotion = nextEvent.xmotion;
+ else
+ break;
+ }
+ type = QEvent::MouseMove;
+ pos.rx() = lastMotion.x;
+ pos.ry() = lastMotion.y;
+ pos = d->mapFromWS(pos);
+ globalPos.rx() = lastMotion.x_root;
+ globalPos.ry() = lastMotion.y_root;
+ buttons = translateMouseButtons(lastMotion.state);
+ modifiers = X11->translateModifiers(lastMotion.state);
+ if (qt_button_down && !buttons)
+ qt_button_down = 0;
+ } else if (event->type == EnterNotify || event->type == LeaveNotify) {
+ XEvent *xevent = (XEvent *)event;
+ //unsigned int xstate = event->xcrossing.state;
+ type = QEvent::MouseMove;
+ pos.rx() = xevent->xcrossing.x;
+ pos.ry() = xevent->xcrossing.y;
+ pos = d->mapFromWS(pos);
+ globalPos.rx() = xevent->xcrossing.x_root;
+ globalPos.ry() = xevent->xcrossing.y_root;
+ buttons = translateMouseButtons(xevent->xcrossing.state);
+ modifiers = X11->translateModifiers(xevent->xcrossing.state);
+ if (qt_button_down && !buttons)
+ qt_button_down = 0;
+ if (qt_button_down)
+ return true;
+ } else { // button press or release
+ pos.rx() = event->xbutton.x;
+ pos.ry() = event->xbutton.y;
+ pos = d->mapFromWS(pos);
+ globalPos.rx() = event->xbutton.x_root;
+ globalPos.ry() = event->xbutton.y_root;
+ buttons = translateMouseButtons(event->xbutton.state);
+ modifiers = X11->translateModifiers(event->xbutton.state);
+ switch (event->xbutton.button) {
+ case Button1: button = Qt::LeftButton; break;
+ case Button2: button = Qt::MidButton; break;
+ case Button3: button = Qt::RightButton; break;
+ case Button4:
+ case Button5:
+ case 6:
+ case 7:
+ // the fancy mouse wheel.
+
+ // We are only interested in ButtonPress.
+ if (event->type == ButtonPress){
+ // compress wheel events (the X Server will simply
+ // send a button press for each single notch,
+ // regardless whether the application can catch up
+ // or not)
+ int delta = 1;
+ XEvent xevent;
+ while (XCheckTypedWindowEvent(X11->display, effectiveWinId(), ButtonPress, &xevent)){
+ if (xevent.xbutton.button != event->xbutton.button){
+ XPutBackEvent(X11->display, &xevent);
+ break;
+ }
+ delta++;
+ }
+
+ // the delta is defined as multiples of
+ // WHEEL_DELTA, which is set to 120. Future wheels
+ // may offer a finer-resolution. A positive delta
+ // indicates forward rotation, a negative one
+ // backward rotation respectively.
+ int btn = event->xbutton.button;
+ delta *= 120 * ((btn == Button4 || btn == 6) ? 1 : -1);
+ bool hor = (((btn == Button4 || btn == Button5) && (modifiers & Qt::AltModifier)) ||
+ (btn == 6 || btn == 7));
+ translateWheelEvent(globalPos.x(), globalPos.y(), delta, buttons,
+ modifiers, (hor) ? Qt::Horizontal: Qt::Vertical);
+ }
+ return true;
+ case 8: button = Qt::XButton1; break;
+ case 9: button = Qt::XButton2; break;
+ }
+ if (event->type == ButtonPress) { // mouse button pressed
+ buttons |= button;
+#if defined(Q_OS_IRIX) && !defined(QT_NO_TABLET)
+ QTabletDeviceDataList *tablets = qt_tablet_devices();
+ for (int i = 0; i < tablets->size(); ++i) {
+ QTabletDeviceData &tab = tablets->operator[](i);
+ XEvent myEv;
+ if (XCheckTypedEvent(X11->display, tab.xinput_button_press, &myEv)) {
+ if (translateXinputEvent(&myEv, &tab)) {
+ //Spontaneous event sent. Check if we need to continue.
+ if (qt_tabletChokeMouse) {
+ qt_tabletChokeMouse = false;
+ return false;
+ }
+ }
+ }
+ }
+#endif
+ if (!qt_button_down) {
+ qt_button_down = childAt(pos); //magic for masked widgets
+ if (!qt_button_down)
+ qt_button_down = this;
+ }
+ if (mouseActWindow == event->xbutton.window &&
+ mouseButtonPressed == button &&
+ (long)event->xbutton.time -(long)mouseButtonPressTime
+ < QApplication::doubleClickInterval() &&
+ qAbs(event->xbutton.x - mouseXPos) < QT_GUI_DOUBLE_CLICK_RADIUS &&
+ qAbs(event->xbutton.y - mouseYPos) < QT_GUI_DOUBLE_CLICK_RADIUS) {
+ type = QEvent::MouseButtonDblClick;
+ mouseButtonPressTime -= 2000; // no double-click next time
+ } else {
+ type = QEvent::MouseButtonPress;
+ mouseButtonPressTime = event->xbutton.time;
+ }
+ mouseButtonPressed = button; // save event params for
+ mouseXPos = event->xbutton.x; // future double click tests
+ mouseYPos = event->xbutton.y;
+ mouseGlobalXPos = globalPos.x();
+ mouseGlobalYPos = globalPos.y();
+ } else { // mouse button released
+ buttons &= ~button;
+#if defined(Q_OS_IRIX) && !defined(QT_NO_TABLET)
+ QTabletDeviceDataList *tablets = qt_tablet_devices();
+ for (int i = 0; i < tablets->size(); ++i) {
+ QTabletDeviceData &tab = tablets->operator[](i);
+ XEvent myEv;
+ if (XCheckTypedEvent(X11->display, tab.xinput_button_press, &myEv)) {
+ if (translateXinputEvent(&myEv, &tab)) {
+ //Spontaneous event sent. Check if we need to continue.
+ if (qt_tabletChokeMouse) {
+ qt_tabletChokeMouse = false;
+ return false;
+ }
+ }
+ }
+ }
+#endif
+ type = QEvent::MouseButtonRelease;
+ }
+ }
+ mouseActWindow = effectiveWinId(); // save some event params
+ mouseButtonState = buttons;
+ if (type == 0) // don't send event
+ return false;
+
+ if (qApp->d_func()->inPopupMode()) { // in popup mode
+ QWidget *activePopupWidget = qApp->activePopupWidget();
+ QWidget *popup = qApp->activePopupWidget();
+ if (popup != this) {
+ if (event->type == LeaveNotify)
+ return false;
+ if ((windowType() == Qt::Popup) && rect().contains(pos) && 0)
+ popup = this;
+ else // send to last popup
+ pos = popup->mapFromGlobal(globalPos);
+ }
+ bool releaseAfter = false;
+ QWidget *popupChild = popup->childAt(pos);
+
+ if (popup != qt_popup_down){
+ qt_button_down = 0;
+ qt_popup_down = 0;
+ }
+
+ switch (type) {
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonDblClick:
+ qt_button_down = popupChild;
+ qt_popup_down = popup;
+ break;
+ case QEvent::MouseButtonRelease:
+ releaseAfter = true;
+ break;
+ default:
+ break; // nothing for mouse move
+ }
+
+ int oldOpenPopupCount = openPopupCount;
+
+ if (popup->isEnabled()) {
+ // deliver event
+ replayPopupMouseEvent = false;
+ QWidget *receiver = popup;
+ QPoint widgetPos = pos;
+ if (qt_button_down)
+ receiver = qt_button_down;
+ else if (popupChild)
+ receiver = popupChild;
+ if (receiver != popup)
+ widgetPos = receiver->mapFromGlobal(globalPos);
+ QWidget *alien = childAt(mapFromGlobal(globalPos));
+ QMouseEvent e(type, widgetPos, globalPos, button, buttons, modifiers);
+ QApplicationPrivate::sendMouseEvent(receiver, &e, alien, this, &qt_button_down, qt_last_mouse_receiver);
+ } else {
+ // close disabled popups when a mouse button is pressed or released
+ switch (type) {
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonDblClick:
+ case QEvent::MouseButtonRelease:
+ popup->close();
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (qApp->activePopupWidget() != activePopupWidget
+ && replayPopupMouseEvent) {
+ // the active popup was closed, replay the mouse event
+ if (!(windowType() == Qt::Popup)) {
+#if 1
+ qt_button_down = 0;
+#else
+ if (buttons == button)
+ qt_button_down = this;
+ QMouseEvent e(type, mapFromGlobal(globalPos), globalPos, button,
+ buttons, modifiers);
+ QApplication::sendSpontaneousEvent(this, &e);
+
+ if (type == QEvent::MouseButtonPress
+ && button == Qt::RightButton
+ && (openPopupCount == oldOpenPopupCount)) {
+ QContextMenuEvent e(QContextMenuEvent::Mouse, mapFromGlobal(globalPos),
+ globalPos, modifiers);
+ QApplication::sendSpontaneousEvent(this, &e);
+ }
+#endif
+ }
+ replayPopupMouseEvent = false;
+ } else if (type == QEvent::MouseButtonPress
+ && button == Qt::RightButton
+ && (openPopupCount == oldOpenPopupCount)) {
+ QWidget *popupEvent = popup;
+ if (qt_button_down)
+ popupEvent = qt_button_down;
+ else if(popupChild)
+ popupEvent = popupChild;
+ QContextMenuEvent e(QContextMenuEvent::Mouse, pos, globalPos, modifiers);
+ QApplication::sendSpontaneousEvent(popupEvent, &e);
+ }
+
+ if (releaseAfter) {
+ qt_button_down = 0;
+ qt_popup_down = 0;
+ }
+ } else {
+ QWidget *alienWidget = childAt(pos);
+ QWidget *widget = QApplicationPrivate::pickMouseReceiver(this, globalPos, pos, type, buttons,
+ qt_button_down, alienWidget);
+ if (!widget) {
+ if (type == QEvent::MouseButtonRelease)
+ QApplicationPrivate::mouse_buttons &= ~button;
+ return false; // don't send event
+ }
+
+ int oldOpenPopupCount = openPopupCount;
+ QMouseEvent e(type, pos, globalPos, button, buttons, modifiers);
+ QApplicationPrivate::sendMouseEvent(widget, &e, alienWidget, this, &qt_button_down,
+ qt_last_mouse_receiver);
+ if (type == QEvent::MouseButtonPress
+ && button == Qt::RightButton
+ && (openPopupCount == oldOpenPopupCount)) {
+ QContextMenuEvent e(QContextMenuEvent::Mouse, pos, globalPos, modifiers);
+ QApplication::sendSpontaneousEvent(widget, &e);
+ }
+ }
+ return true;
+}
+
+
+//
+// Wheel event translation
+//
+bool QETWidget::translateWheelEvent(int global_x, int global_y, int delta,
+ Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers,
+ Qt::Orientation orient)
+{
+ const QPoint globalPos = QPoint(global_x, global_y);
+ QPoint pos = mapFromGlobal(globalPos);
+ QWidget *widget = childAt(pos);
+ if (!widget)
+ widget = this;
+ else if (!widget->internalWinId())
+ pos = widget->mapFromGlobal(globalPos);
+
+#ifdef ALIEN_DEBUG
+ qDebug() << "QETWidget::translateWheelEvent: receiver:" << widget << "pos:" << pos;
+#endif
+
+ // send the event to the widget or its ancestors
+ {
+ QWidget* popup = qApp->activePopupWidget();
+ if (popup && window() != popup)
+ popup->close();
+#ifndef QT_NO_WHEELEVENT
+ QWheelEvent e(pos, globalPos, delta, buttons, modifiers, orient);
+ if (QApplication::sendSpontaneousEvent(widget, &e))
+#endif
+ return true;
+ }
+
+ // send the event to the widget that has the focus or its ancestors, if different
+ if (widget != qApp->focusWidget() && (widget = qApp->focusWidget())) {
+ if (widget && !widget->internalWinId())
+ pos = widget->mapFromGlobal(globalPos);
+ QWidget* popup = qApp->activePopupWidget();
+ if (popup && widget != popup)
+ popup->hide();
+#ifndef QT_NO_WHEELEVENT
+ QWheelEvent e(pos, globalPos, delta, buttons, modifiers, orient);
+ if (QApplication::sendSpontaneousEvent(widget, &e))
+#endif
+ return true;
+ }
+ return false;
+}
+
+
+//
+// XInput Translation Event
+//
+#if !defined (QT_NO_TABLET)
+
+#if !defined (Q_OS_IRIX)
+void fetchWacomToolId(int &deviceType, qint64 &serialId)
+{
+ if (ptrWacomConfigInit == 0) // we actually have the lib
+ return;
+ WACOMCONFIG *config = ptrWacomConfigInit(X11->display, 0);
+ if (config == 0)
+ return;
+ WACOMDEVICE *device = ptrWacomConfigOpenDevice (config, wacomDeviceName()->constData());
+ if (device == 0)
+ return;
+ unsigned keys[1];
+ int serialInt;
+ ptrWacomConfigGetRawParam (device, XWACOM_PARAM_TOOLSERIAL, &serialInt, 1, keys);
+ serialId = serialInt;
+ int toolId;
+ ptrWacomConfigGetRawParam (device, XWACOM_PARAM_TOOLID, &toolId, 1, keys);
+ switch(toolId) {
+ case 0x007: /* Mouse 4D and 2D */
+ case 0x017: /* Intuos3 2D Mouse */
+ case 0x094:
+ case 0x09c:
+ deviceType = QTabletEvent::FourDMouse;
+ break;
+ case 0x096: /* Lens cursor */
+ case 0x097: /* Intuos3 Lens cursor */
+ deviceType = QTabletEvent::Puck;
+ break;
+ case 0x0fa:
+ case 0x81b: /* Intuos3 Classic Pen Eraser */
+ case 0x82a: /* Eraser */
+ case 0x82b: /* Intuos3 Grip Pen Eraser */
+ case 0x85a:
+ case 0x91a:
+ case 0x91b: /* Intuos3 Airbrush Eraser */
+ case 0xd1a:
+ deviceType = QTabletEvent::XFreeEraser;
+ break;
+ case 0x112:
+ case 0x912:
+ case 0x913: /* Intuos3 Airbrush */
+ case 0xd12:
+ deviceType = QTabletEvent::Airbrush;
+ break;
+ case 0x012:
+ case 0x022:
+ case 0x032:
+ case 0x801: /* Intuos3 Inking pen */
+ case 0x812: /* Inking pen */
+ case 0x813: /* Intuos3 Classic Pen */
+ case 0x822: /* Pen */
+ case 0x823: /* Intuos3 Grip Pen */
+ case 0x832: /* Stroke pen */
+ case 0x842:
+ case 0x852:
+ case 0x885: /* Intuos3 Marker Pen */
+ default: /* Unknown tool */
+ deviceType = QTabletEvent::Stylus;
+ }
+
+ /* Close device and return */
+ ptrWacomConfigCloseDevice (device);
+ ptrWacomConfigTerm(config);
+}
+#endif
+
+struct qt_tablet_motion_data
+{
+ bool filterByWidget;
+ const QWidget *widget;
+ const QWidget *etWidget;
+ int tabletMotionType;
+ bool error; // found a reason to stop searching
+};
+
+static Bool qt_mouseMotion_scanner(Display *, XEvent *event, XPointer arg)
+{
+ qt_tablet_motion_data *data = (qt_tablet_motion_data *) arg;
+ if (data->error)
+ return false;
+
+ if (event->type == MotionNotify)
+ return true;
+
+ data->error = event->type != data->tabletMotionType; // we stop compression when another event gets in between.
+ return false;
+}
+
+static Bool qt_tabletMotion_scanner(Display *, XEvent *event, XPointer arg)
+{
+ qt_tablet_motion_data *data = (qt_tablet_motion_data *) arg;
+ if (data->error)
+ return false;
+ if (event->type == data->tabletMotionType) {
+ const XDeviceMotionEvent *const motion = reinterpret_cast<const XDeviceMotionEvent*>(event);
+ if (data->filterByWidget) {
+ const QPoint curr(motion->x, motion->y);
+ const QWidget *w = data->etWidget;
+ const QWidget *const child = w->childAt(curr);
+ if (child) {
+ w = child;
+ }
+ if (w == data->widget)
+ return true;
+ } else {
+ return true;
+ }
+ }
+
+ data->error = event->type != MotionNotify; // we stop compression when another event gets in between.
+ return false;
+}
+
+bool QETWidget::translateXinputEvent(const XEvent *ev, QTabletDeviceData *tablet)
+{
+#if defined (Q_OS_IRIX)
+ // Wacom has put defines in their wacom.h file so it would be quite wise
+ // to use them, need to think of a decent way of not using
+ // it when it doesn't exist...
+ XDeviceState *s;
+ XInputClass *iClass;
+ XValuatorState *vs;
+ int j;
+#endif
+
+ Q_ASSERT(tablet != 0);
+
+ QWidget *w = this;
+ QPoint global,
+ curr;
+ QPointF hiRes;
+ qreal pressure = 0;
+ int xTilt = 0,
+ yTilt = 0,
+ z = 0;
+ qreal tangentialPressure = 0;
+ qreal rotation = 0;
+ int deviceType = QTabletEvent::NoDevice;
+ int pointerType = QTabletEvent::UnknownPointer;
+ const XDeviceMotionEvent *motion = 0;
+ XDeviceButtonEvent *button = 0;
+ const XProximityNotifyEvent *proximity = 0;
+ QEvent::Type t;
+ Qt::KeyboardModifiers modifiers = 0;
+#if !defined (Q_OS_IRIX)
+ XID device_id;
+#endif
+
+ if (ev->type == tablet->xinput_motion) {
+ motion = reinterpret_cast<const XDeviceMotionEvent*>(ev);
+ t = QEvent::TabletMove;
+ global = QPoint(motion->x_root, motion->y_root);
+ curr = QPoint(motion->x, motion->y);
+#if !defined (Q_OS_IRIX)
+ device_id = motion->deviceid;
+#endif
+ } else if (ev->type == tablet->xinput_button_press || ev->type == tablet->xinput_button_release) {
+ if (ev->type == tablet->xinput_button_press) {
+ t = QEvent::TabletPress;
+ } else {
+ t = QEvent::TabletRelease;
+ }
+ button = (XDeviceButtonEvent*)ev;
+
+ global = QPoint(button->x_root, button->y_root);
+ curr = QPoint(button->x, button->y);
+#if !defined (Q_OS_IRIX)
+ device_id = button->deviceid;
+#endif
+ } else { // Proximity
+ if (ev->type == tablet->xinput_proximity_in)
+ t = QEvent::TabletEnterProximity;
+ else
+ t = QEvent::TabletLeaveProximity;
+ proximity = (const XProximityNotifyEvent*)ev;
+#if !defined (Q_OS_IRIX)
+ device_id = proximity->deviceid;
+#endif
+ }
+
+ qint64 uid = 0;
+#if defined (Q_OS_IRIX)
+ QRect screenArea = qApp->desktop()->screenGeometry(this);
+ s = XQueryDeviceState(X11->display, static_cast<XDevice *>(tablet->device));
+ if (!s)
+ return false;
+ iClass = s->data;
+ for (j = 0; j < s->num_classes; j++) {
+ if (iClass->c_class == ValuatorClass) {
+ vs = reinterpret_cast<XValuatorState *>(iClass);
+ // figure out what device we have, based on bitmasking...
+ if (vs->valuators[WAC_TRANSDUCER_I]
+ & WAC_TRANSDUCER_PROX_MSK) {
+ switch (vs->valuators[WAC_TRANSDUCER_I]
+ & WAC_TRANSDUCER_MSK) {
+ case WAC_PUCK_ID:
+ pointerType = QTabletEvent::Puck;
+ break;
+ case WAC_STYLUS_ID:
+ pointerType = QTabletEvent::Pen;
+ break;
+ case WAC_ERASER_ID:
+ pointerType = QTabletEvent::Eraser;
+ break;
+ }
+ // Get a Unique Id for the device, Wacom gives us this ability
+ uid = vs->valuators[WAC_TRANSDUCER_I] & WAC_TRANSDUCER_ID_MSK;
+ uid = (uid << 24) | vs->valuators[WAC_SERIAL_NUM_I];
+ switch (WAC_TRANSDUCER_I & 0x0F0600) {
+ case 0x080200:
+ deviceType = QTabletEvent::Stylus;
+ break;
+ case 0x090200:
+ deviceType = QTabletEvent::Airbrush;
+ break;
+ case 0x000400:
+ deviceType = QTabletEvent::FourDMouse;
+ break;
+ case 0x000600:
+ deviceType = QTabletEvent::Puck;
+ break;
+ case 0x080400:
+ deviceType = QTabletEvent::RotationStylus;
+ break;
+ }
+ } else {
+ pointerType = QTabletEvent::UnknownPointer;
+ deviceType = QTabletEvent::NoDevice;
+ uid = 0;
+ }
+
+ if (!proximity) {
+ // apparently Wacom needs a cast for the +/- values to make sense
+ xTilt = short(vs->valuators[WAC_XTILT_I]);
+ yTilt = short(vs->valuators[WAC_YTILT_I]);
+ pressure = vs->valuators[WAC_PRESSURE_I];
+ if (deviceType == QTabletEvent::FourDMouse
+ || deviceType == QTabletEvent::RotationStylus) {
+ rotation = vs->valuators[WAC_ROTATION_I] / 64.0;
+ if (deviceType == QTabletEvent::FourDMouse)
+ z = vs->valuators[WAC_ZCOORD_I];
+ } else if (deviceType == QTabletEvent::Airbrush) {
+ tangentialPressure = vs->valuators[WAC_TAN_PRESSURE_I]
+ / qreal(tablet->maxTanPressure - tablet->minTanPressure);
+ }
+
+ hiRes = tablet->scaleCoord(vs->valuators[WAC_XCOORD_I], vs->valuators[WAC_YCOORD_I],
+ screenArea.x(), screenArea.width(),
+ screenArea.y(), screenArea.height());
+ }
+ break;
+ }
+ iClass = reinterpret_cast<XInputClass*>(reinterpret_cast<char*>(iClass) + iClass->length);
+ }
+ XFreeDeviceState(s);
+#else
+ QTabletDeviceDataList *tablet_list = qt_tablet_devices();
+ for (int i = 0; i < tablet_list->size(); ++i) {
+ const QTabletDeviceData &t = tablet_list->at(i);
+ if (device_id == static_cast<XDevice *>(t.device)->device_id) {
+ deviceType = t.deviceType;
+ if (t.deviceType == QTabletEvent::XFreeEraser) {
+ deviceType = QTabletEvent::Stylus;
+ pointerType = QTabletEvent::Eraser;
+ } else if (t.deviceType == QTabletEvent::Stylus) {
+ pointerType = QTabletEvent::Pen;
+ }
+ break;
+ }
+ }
+
+ fetchWacomToolId(deviceType, uid);
+
+ QRect screenArea = qApp->desktop()->rect();
+ if (motion) {
+ xTilt = (short) motion->axis_data[3];
+ yTilt = (short) motion->axis_data[4];
+ rotation = ((short) motion->axis_data[5]) / 64.0;
+ pressure = (short) motion->axis_data[2];
+ modifiers = X11->translateModifiers(motion->state);
+ hiRes = tablet->scaleCoord(motion->axis_data[0], motion->axis_data[1],
+ screenArea.x(), screenArea.width(),
+ screenArea.y(), screenArea.height());
+ } else if (button) {
+ xTilt = (short) button->axis_data[3];
+ yTilt = (short) button->axis_data[4];
+ rotation = ((short) button->axis_data[5]) / 64.0;
+ pressure = (short) button->axis_data[2];
+ modifiers = X11->translateModifiers(button->state);
+ hiRes = tablet->scaleCoord(button->axis_data[0], button->axis_data[1],
+ screenArea.x(), screenArea.width(),
+ screenArea.y(), screenArea.height());
+ } else if (proximity) {
+ pressure = 0;
+ modifiers = 0;
+ }
+ if (deviceType == QTabletEvent::Airbrush) {
+ tangentialPressure = rotation;
+ rotation = 0.;
+ }
+#endif
+
+ if (tablet->widgetToGetPress) {
+ w = tablet->widgetToGetPress;
+ } else {
+ QWidget *child = w->childAt(curr);
+ if (child)
+ w = child;
+ }
+ curr = w->mapFromGlobal(global);
+
+ if (t == QEvent::TabletPress) {
+ tablet->widgetToGetPress = w;
+ } else if (t == QEvent::TabletRelease && tablet->widgetToGetPress) {
+ w = tablet->widgetToGetPress;
+ curr = w->mapFromGlobal(global);
+ tablet->widgetToGetPress = 0;
+ }
+
+ QTabletEvent e(t, curr, global, hiRes,
+ deviceType, pointerType,
+ qreal(pressure / qreal(tablet->maxPressure - tablet->minPressure)),
+ xTilt, yTilt, tangentialPressure, rotation, z, modifiers, uid);
+ if (proximity) {
+ QApplication::sendSpontaneousEvent(qApp, &e);
+ } else {
+ QApplication::sendSpontaneousEvent(w, &e);
+ const bool accepted = e.isAccepted();
+ if (!accepted && ev->type == tablet->xinput_motion) {
+ // If the widget does not accept tablet events, we drop the next ones from the event queue
+ // for this widget so it is not overloaded with the numerous tablet events.
+ qt_tablet_motion_data tabletMotionData;
+ tabletMotionData.tabletMotionType = tablet->xinput_motion;
+ tabletMotionData.widget = w;
+ tabletMotionData.etWidget = this;
+ // if nothing is pressed, the events are filtered by position
+ tabletMotionData.filterByWidget = (tablet->widgetToGetPress == 0);
+
+ bool reinsertMouseEvent = false;
+ XEvent mouseMotionEvent;
+ while (true) {
+ // Find first mouse event since we expect them in pairs inside Qt
+ tabletMotionData.error =false;
+ if (XCheckIfEvent(X11->display, &mouseMotionEvent, &qt_mouseMotion_scanner, (XPointer) &tabletMotionData)) {
+ reinsertMouseEvent = true;
+ } else {
+ break;
+ }
+
+ // Now discard any duplicate tablet events.
+ tabletMotionData.error = false;
+ XEvent dummy;
+ while (XCheckIfEvent(X11->display, &dummy, &qt_tabletMotion_scanner, (XPointer) &tabletMotionData)) {
+ // just discard the event
+ }
+ }
+
+ if (reinsertMouseEvent) {
+ XPutBackEvent(X11->display, &mouseMotionEvent);
+ }
+ }
+ }
+ return true;
+}
+#endif
+
+bool QETWidget::translatePropertyEvent(const XEvent *event)
+{
+ Q_D(QWidget);
+ if (!isWindow()) return true;
+
+ Atom ret;
+ int format, e;
+ unsigned char *data = 0;
+ unsigned long nitems, after;
+
+ if (event->xproperty.atom == ATOM(_KDE_NET_WM_FRAME_STRUT)) {
+ this->data->fstrut_dirty = 1;
+
+ if (event->xproperty.state == PropertyNewValue) {
+ e = XGetWindowProperty(X11->display, event->xproperty.window, ATOM(_KDE_NET_WM_FRAME_STRUT),
+ 0, 4, // struts are 4 longs
+ False, XA_CARDINAL, &ret, &format, &nitems, &after, &data);
+
+ if (e == Success && ret == XA_CARDINAL &&
+ format == 32 && nitems == 4) {
+ long *strut = (long *) data;
+ d->topData()->frameStrut.setCoords(strut[0], strut[2], strut[1], strut[3]);
+ this->data->fstrut_dirty = 0;
+ }
+ }
+ } else if (event->xproperty.atom == ATOM(_NET_WM_STATE)) {
+ bool max = false;
+ bool full = false;
+ Qt::WindowStates oldState = Qt::WindowStates(this->data->window_state);
+
+ if (event->xproperty.state == PropertyNewValue) {
+ // using length of 1024 should be safe for all current and
+ // possible NET states...
+ e = XGetWindowProperty(X11->display, event->xproperty.window, ATOM(_NET_WM_STATE), 0, 1024,
+ False, XA_ATOM, &ret, &format, &nitems, &after, &data);
+
+ if (e == Success && ret == XA_ATOM && format == 32 && nitems > 0) {
+ Atom *states = (Atom *) data;
+
+ unsigned long i;
+ uint maximized = 0;
+ for (i = 0; i < nitems; i++) {
+ if (states[i] == ATOM(_NET_WM_STATE_MAXIMIZED_VERT))
+ maximized |= 1;
+ else if (states[i] == ATOM(_NET_WM_STATE_MAXIMIZED_HORZ))
+ maximized |= 2;
+ else if (states[i] == ATOM(_NET_WM_STATE_FULLSCREEN))
+ full = true;
+ }
+ if (maximized == 3) {
+ // only set maximized if both horizontal and vertical properties are set
+ max = true;
+ }
+ }
+ }
+
+ bool send_event = false;
+
+ if (X11->isSupportedByWM(ATOM(_NET_WM_STATE_MAXIMIZED_VERT))
+ && X11->isSupportedByWM(ATOM(_NET_WM_STATE_MAXIMIZED_HORZ))) {
+ if (max && !isMaximized()) {
+ this->data->window_state = this->data->window_state | Qt::WindowMaximized;
+ send_event = true;
+ } else if (!max && isMaximized()) {
+ this->data->window_state &= ~Qt::WindowMaximized;
+ send_event = true;
+ }
+ }
+
+ if (X11->isSupportedByWM(ATOM(_NET_WM_STATE_FULLSCREEN))) {
+ if (full && !isFullScreen()) {
+ this->data->window_state = this->data->window_state | Qt::WindowFullScreen;
+ send_event = true;
+ } else if (!full && isFullScreen()) {
+ this->data->window_state &= ~Qt::WindowFullScreen;
+ send_event = true;
+ }
+ }
+
+ if (send_event) {
+ QWindowStateChangeEvent e(oldState);
+ QApplication::sendSpontaneousEvent(this, &e);
+ }
+ } else if (event->xproperty.atom == ATOM(WM_STATE)) {
+ // the widget frame strut should also be invalidated
+ this->data->fstrut_dirty = 1;
+
+ if (event->xproperty.state == PropertyDelete) {
+ // the window manager has removed the WM State property,
+ // so it is now in the withdrawn state (ICCCM 4.1.3.1) and
+ // we are free to reuse this window
+ d->topData()->parentWinId = 0;
+ d->topData()->validWMState = 0;
+ // map the window if we were waiting for a transition to
+ // withdrawn
+ if (X11->deferred_map.removeAll(this)) {
+ doDeferredMap();
+ } else if (isVisible()
+ && !testAttribute(Qt::WA_Mapped)
+ && !testAttribute(Qt::WA_OutsideWSRange)) {
+ // so that show() will work again. As stated in the
+ // ICCCM section 4.1.4: "Only the client can effect a
+ // transition into or out of the Withdrawn state.",
+ // but apparently this particular window manager
+ // doesn't seem to care
+ setAttribute(Qt::WA_WState_ExplicitShowHide, false);
+ setAttribute(Qt::WA_WState_Visible, false);
+ }
+ } else {
+ // the window manager has changed the WM State property...
+ // we are wanting to see if we are withdrawn so that we
+ // can reuse this window...
+ e = XGetWindowProperty(X11->display, internalWinId(), ATOM(WM_STATE), 0, 2, False,
+ ATOM(WM_STATE), &ret, &format, &nitems, &after, &data);
+
+ if (e == Success && ret == ATOM(WM_STATE) && format == 32 && nitems > 0) {
+ long *state = (long *) data;
+ switch (state[0]) {
+ case WithdrawnState:
+ // if we are in the withdrawn state, we are free
+ // to reuse this window provided we remove the
+ // WM_STATE property (ICCCM 4.1.3.1)
+ XDeleteProperty(X11->display, internalWinId(), ATOM(WM_STATE));
+
+ // set the parent id to zero, so that show() will
+ // work again
+ d->topData()->parentWinId = 0;
+ d->topData()->validWMState = 0;
+ // map the window if we were waiting for a
+ // transition to withdrawn
+ if (X11->deferred_map.removeAll(this)) {
+ doDeferredMap();
+ } else if (isVisible()
+ && !testAttribute(Qt::WA_Mapped)
+ && !testAttribute(Qt::WA_OutsideWSRange)) {
+ // so that show() will work again. As stated
+ // in the ICCCM section 4.1.4: "Only the
+ // client can effect a transition into or out
+ // of the Withdrawn state.", but apparently
+ // this particular window manager doesn't seem
+ // to care
+ setAttribute(Qt::WA_WState_ExplicitShowHide, false);
+ setAttribute(Qt::WA_WState_Visible, false);
+ }
+ break;
+
+ case IconicState:
+ d->topData()->validWMState = 1;
+ if (!isMinimized()) {
+ // window was minimized
+ this->data->window_state = this->data->window_state | Qt::WindowMinimized;
+ QWindowStateChangeEvent e(Qt::WindowStates(this->data->window_state & ~Qt::WindowMinimized));
+ QApplication::sendSpontaneousEvent(this, &e);
+ }
+ break;
+
+ default:
+ d->topData()->validWMState = 1;
+ if (isMinimized()) {
+ // window was un-minimized
+ this->data->window_state &= ~Qt::WindowMinimized;
+ QWindowStateChangeEvent e(Qt::WindowStates(this->data->window_state | Qt::WindowMinimized));
+ QApplication::sendSpontaneousEvent(this, &e);
+ }
+ break;
+ }
+ }
+ }
+ } else if (event->xproperty.atom == ATOM(_NET_WM_WINDOW_OPACITY)) {
+ // the window opacity was changed
+ if (event->xproperty.state == PropertyNewValue) {
+ e = XGetWindowProperty(event->xclient.display,
+ event->xclient.window,
+ ATOM(_NET_WM_WINDOW_OPACITY),
+ 0, 1, False, XA_CARDINAL,
+ &ret, &format, &nitems, &after, &data);
+
+ if (e == Success && ret == XA_CARDINAL && format == 32 && nitems == 1
+ && after == 0 && data) {
+ ulong value = *(ulong*)(data);
+ d->topData()->opacity = uint(value >> 24);
+ }
+ } else
+ d->topData()->opacity = 255;
+ }
+
+ if (data)
+ XFree(data);
+
+ return true;
+}
+
+
+//
+// Paint event translation
+//
+// When receiving many expose events, we compress them (union of all expose
+// rectangles) into one event which is sent to the widget.
+
+struct PaintEventInfo {
+ Window window;
+};
+
+#if defined(Q_C_CALLBACKS)
+extern "C" {
+#endif
+
+static Bool isPaintOrScrollDoneEvent(Display *, XEvent *ev, XPointer a)
+{
+ PaintEventInfo *info = (PaintEventInfo *)a;
+ if (ev->type == Expose || ev->type == GraphicsExpose
+ || (ev->type == ClientMessage && ev->xclient.message_type == ATOM(_QT_SCROLL_DONE)))
+ {
+ if (ev->xexpose.window == info->window)
+ return True;
+ }
+ return False;
+}
+
+#if defined(Q_C_CALLBACKS)
+}
+#endif
+
+
+
+static
+bool translateBySips(QWidget* that, QRect& paintRect)
+{
+ int dx=0, dy=0;
+ int sips=0;
+ for (int i = 0; i < X11->sip_list.size(); ++i) {
+ const QX11Data::ScrollInProgress &sip = X11->sip_list.at(i);
+ if (sip.scrolled_widget == that) {
+ if (sips) {
+ dx += sip.dx;
+ dy += sip.dy;
+ }
+ sips++;
+ }
+ }
+ if (sips > 1) {
+ paintRect.translate(dx, dy);
+ return true;
+ }
+ return false;
+}
+
+void QETWidget::translatePaintEvent(const XEvent *event)
+{
+ if (!isWindow() && testAttribute(Qt::WA_NativeWindow))
+ Q_ASSERT(internalWinId());
+
+ Q_D(QWidget);
+ QRect paintRect(event->xexpose.x, event->xexpose.y,
+ event->xexpose.width, event->xexpose.height);
+ XEvent xevent;
+ PaintEventInfo info;
+ info.window = internalWinId();
+ translateBySips(this, paintRect);
+ paintRect = d->mapFromWS(paintRect);
+
+ QRegion paintRegion = paintRect;
+
+ // WARNING: this is O(number_of_events * number_of_matching_events)
+ while (XCheckIfEvent(X11->display,&xevent,isPaintOrScrollDoneEvent,
+ (XPointer)&info) &&
+ !qt_x11EventFilter(&xevent) &&
+ !x11Event(&xevent)) // send event through filter
+ {
+ if (xevent.type == Expose || xevent.type == GraphicsExpose) {
+ QRect exposure(xevent.xexpose.x,
+ xevent.xexpose.y,
+ xevent.xexpose.width,
+ xevent.xexpose.height);
+ translateBySips(this, exposure);
+ exposure = d->mapFromWS(exposure);
+ paintRegion |= exposure;
+ } else {
+ translateScrollDoneEvent(&xevent);
+ }
+ }
+
+ if (!paintRegion.isEmpty() && !testAttribute(Qt::WA_WState_ConfigPending))
+ d->syncBackingStore(paintRegion);
+}
+
+//
+// Scroll-done event translation.
+//
+
+bool QETWidget::translateScrollDoneEvent(const XEvent *event)
+{
+ long id = event->xclient.data.l[0];
+
+ // Remove any scroll-in-progress record for the given id.
+ for (int i = 0; i < X11->sip_list.size(); ++i) {
+ const QX11Data::ScrollInProgress &sip = X11->sip_list.at(i);
+ if (sip.id == id) {
+ X11->sip_list.removeAt(i);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+//
+// ConfigureNotify (window move and resize) event translation
+
+bool QETWidget::translateConfigEvent(const XEvent *event)
+{
+ Q_ASSERT((!isWindow() && !testAttribute(Qt::WA_NativeWindow)) ? internalWinId() : true);
+
+ Q_D(QWidget);
+ bool wasResize = testAttribute(Qt::WA_WState_ConfigPending); // set in QWidget::setGeometry_sys()
+ setAttribute(Qt::WA_WState_ConfigPending, false);
+
+ if (testAttribute(Qt::WA_OutsideWSRange)) {
+ // discard events for windows that have a geometry X can't handle
+ XEvent xevent;
+ while (XCheckTypedWindowEvent(X11->display,internalWinId(), ConfigureNotify,&xevent) &&
+ !qt_x11EventFilter(&xevent) &&
+ !x11Event(&xevent)) // send event through filter
+ ;
+ return true;
+ }
+
+ const QSize oldSize = size();
+
+ if (isWindow()) {
+ QPoint newCPos(geometry().topLeft());
+ QSize newSize(event->xconfigure.width, event->xconfigure.height);
+
+ bool trust = isVisible()
+ && (d->topData()->parentWinId == XNone ||
+ d->topData()->parentWinId == QX11Info::appRootWindow());
+ bool isCPos = false;
+
+ if (event->xconfigure.send_event || trust) {
+ // if a ConfigureNotify comes from a real sendevent request, we can
+ // trust its values.
+ newCPos.rx() = event->xconfigure.x + event->xconfigure.border_width;
+ newCPos.ry() = event->xconfigure.y + event->xconfigure.border_width;
+ isCPos = true;
+ }
+ if (isVisible())
+ QApplication::syncX();
+
+ if (d->extra->compress_events) {
+ // ConfigureNotify compression for faster opaque resizing
+ XEvent otherEvent;
+ while (XCheckTypedWindowEvent(X11->display, internalWinId(), ConfigureNotify,
+ &otherEvent)) {
+ if (qt_x11EventFilter(&otherEvent))
+ continue;
+
+ if (x11Event(&otherEvent))
+ continue;
+
+ if (otherEvent.xconfigure.event != otherEvent.xconfigure.window)
+ continue;
+
+ newSize.setWidth(otherEvent.xconfigure.width);
+ newSize.setHeight(otherEvent.xconfigure.height);
+
+ if (otherEvent.xconfigure.send_event || trust) {
+ newCPos.rx() = otherEvent.xconfigure.x +
+ otherEvent.xconfigure.border_width;
+ newCPos.ry() = otherEvent.xconfigure.y +
+ otherEvent.xconfigure.border_width;
+ isCPos = true;
+ }
+ }
+#ifndef QT_NO_XSYNC
+ qt_sync_request_event_data sync_event;
+ sync_event.window = internalWinId();
+ for (XEvent ev;;) {
+ if (!XCheckIfEvent(X11->display, &ev, &qt_sync_request_scanner, (XPointer)&sync_event))
+ break;
+ }
+#endif // QT_NO_XSYNC
+ }
+
+ if (!isCPos) {
+ // we didn't get an updated position of the toplevel.
+ // either we haven't moved or there is a bug in the window manager.
+ // anyway, let's query the position to be certain.
+ int x, y;
+ Window child;
+ XTranslateCoordinates(X11->display, internalWinId(),
+ QApplication::desktop()->screen(d->xinfo.screen())->internalWinId(),
+ 0, 0, &x, &y, &child);
+ newCPos.rx() = x;
+ newCPos.ry() = y;
+ }
+
+ QRect cr (geometry());
+ if (newCPos != cr.topLeft()) { // compare with cpos (exluding frame)
+ QPoint oldPos = geometry().topLeft();
+ cr.moveTopLeft(newCPos);
+ data->crect = cr;
+ if (isVisible()) {
+ QMoveEvent e(newCPos, oldPos); // pos (including frame), not cpos
+ QApplication::sendSpontaneousEvent(this, &e);
+ } else {
+ setAttribute(Qt::WA_PendingMoveEvent, true);
+ }
+ }
+ if (newSize != cr.size()) { // size changed
+ cr.setSize(newSize);
+ data->crect = cr;
+
+ uint old_state = data->window_state;
+ if (!X11->isSupportedByWM(ATOM(_NET_WM_STATE_MAXIMIZED_VERT))
+ && !X11->isSupportedByWM(ATOM(_NET_WM_STATE_MAXIMIZED_HORZ)))
+ data->window_state &= ~Qt::WindowMaximized;
+ if (!X11->isSupportedByWM(ATOM(_NET_WM_STATE_FULLSCREEN)))
+ data->window_state &= ~Qt::WindowFullScreen;
+
+ if (old_state != data->window_state) {
+ QWindowStateChangeEvent e((Qt::WindowStates) old_state);
+ QApplication::sendEvent(this, &e);
+ }
+
+ if (!isVisible())
+ setAttribute(Qt::WA_PendingResizeEvent, true);
+ wasResize = true;
+ }
+
+ } else {
+ XEvent xevent;
+ while (XCheckTypedWindowEvent(X11->display,internalWinId(), ConfigureNotify,&xevent) &&
+ !qt_x11EventFilter(&xevent) &&
+ !x11Event(&xevent)) // send event through filter
+ ;
+ }
+
+ if (wasResize) {
+ if (isVisible() && data->crect.size() != oldSize) {
+ Q_ASSERT(d->extra->topextra);
+ QWidgetBackingStore *bs = d->extra->topextra->backingStore.data();
+ const bool hasStaticContents = bs && bs->hasStaticContents();
+ // If we have a backing store with static contents, we have to disable the top-level
+ // resize optimization in order to get invalidated regions for resized widgets.
+ // The optimization discards all invalidateBuffer() calls since we're going to
+ // repaint everything anyways, but that's not the case with static contents.
+ if (!hasStaticContents)
+ d->extra->topextra->inTopLevelResize = true;
+ QResizeEvent e(data->crect.size(), oldSize);
+ QApplication::sendSpontaneousEvent(this, &e);
+ }
+
+ const bool waitingForMapNotify = d->extra->topextra && d->extra->topextra->waitingForMapNotify;
+ if (!waitingForMapNotify) {
+ if (d->paintOnScreen()) {
+ QRegion updateRegion(rect());
+ if (testAttribute(Qt::WA_StaticContents))
+ updateRegion -= QRect(0, 0, oldSize.width(), oldSize.height());
+ d->syncBackingStore(updateRegion);
+ } else {
+ d->syncBackingStore();
+ }
+ }
+
+ if (d->extra && d->extra->topextra)
+ d->extra->topextra->inTopLevelResize = false;
+ }
+#ifndef QT_NO_XSYNC
+ if (QTLWExtra *tlwExtra = d->maybeTopData()) {
+ if (tlwExtra->newCounterValueLo != 0 || tlwExtra->newCounterValueHi != 0) {
+ XSyncValue value;
+ XSyncIntsToValue(&value,
+ tlwExtra->newCounterValueLo,
+ tlwExtra->newCounterValueHi);
+
+ XSyncSetCounter(X11->display, tlwExtra->syncUpdateCounter, value);
+ tlwExtra->newCounterValueHi = 0;
+ tlwExtra->newCounterValueLo = 0;
+ }
+ }
+#endif
+ return true;
+}
+
+//
+// Close window event translation.
+//
+bool QETWidget::translateCloseEvent(const XEvent *)
+{
+ Q_D(QWidget);
+ return d->close_helper(QWidgetPrivate::CloseWithSpontaneousEvent);
+}
+
+
+void QApplication::setCursorFlashTime(int msecs)
+{
+ QApplicationPrivate::cursor_flash_time = msecs;
+}
+
+int QApplication::cursorFlashTime()
+{
+ return QApplicationPrivate::cursor_flash_time;
+}
+
+void QApplication::setDoubleClickInterval(int ms)
+{
+ QApplicationPrivate::mouse_double_click_time = ms;
+}
+
+int QApplication::doubleClickInterval()
+{
+ return QApplicationPrivate::mouse_double_click_time;
+}
+
+void QApplication::setKeyboardInputInterval(int ms)
+{
+ QApplicationPrivate::keyboard_input_time = ms;
+}
+
+int QApplication::keyboardInputInterval()
+{
+ return QApplicationPrivate::keyboard_input_time;
+}
+
+#ifndef QT_NO_WHEELEVENT
+void QApplication::setWheelScrollLines(int n)
+{
+ QApplicationPrivate::wheel_scroll_lines = n;
+}
+
+int QApplication::wheelScrollLines()
+{
+ return QApplicationPrivate::wheel_scroll_lines;
+}
+#endif
+
+void QApplication::setEffectEnabled(Qt::UIEffect effect, bool enable)
+{
+ switch (effect) {
+ case Qt::UI_AnimateMenu:
+ if (enable) QApplicationPrivate::fade_menu = false;
+ QApplicationPrivate::animate_menu = enable;
+ break;
+ case Qt::UI_FadeMenu:
+ if (enable)
+ QApplicationPrivate::animate_menu = true;
+ QApplicationPrivate::fade_menu = enable;
+ break;
+ case Qt::UI_AnimateCombo:
+ QApplicationPrivate::animate_combo = enable;
+ break;
+ case Qt::UI_AnimateTooltip:
+ if (enable) QApplicationPrivate::fade_tooltip = false;
+ QApplicationPrivate::animate_tooltip = enable;
+ break;
+ case Qt::UI_FadeTooltip:
+ if (enable)
+ QApplicationPrivate::animate_tooltip = true;
+ QApplicationPrivate::fade_tooltip = enable;
+ break;
+ case Qt::UI_AnimateToolBox:
+ QApplicationPrivate::animate_toolbox = enable;
+ break;
+ default:
+ QApplicationPrivate::animate_ui = enable;
+ break;
+ }
+}
+
+bool QApplication::isEffectEnabled(Qt::UIEffect effect)
+{
+ if (QColormap::instance().depth() < 16 || !QApplicationPrivate::animate_ui)
+ return false;
+
+ switch(effect) {
+ case Qt::UI_AnimateMenu:
+ return QApplicationPrivate::animate_menu;
+ case Qt::UI_FadeMenu:
+ return QApplicationPrivate::fade_menu;
+ case Qt::UI_AnimateCombo:
+ return QApplicationPrivate::animate_combo;
+ case Qt::UI_AnimateTooltip:
+ return QApplicationPrivate::animate_tooltip;
+ case Qt::UI_FadeTooltip:
+ return QApplicationPrivate::fade_tooltip;
+ case Qt::UI_AnimateToolBox:
+ return QApplicationPrivate::animate_toolbox;
+ default:
+ return QApplicationPrivate::animate_ui;
+ }
+}
+
+/*****************************************************************************
+ Session management support
+ *****************************************************************************/
+
+#ifndef QT_NO_SESSIONMANAGER
+
+QT_BEGIN_INCLUDE_NAMESPACE
+#include <X11/SM/SMlib.h>
+QT_END_INCLUDE_NAMESPACE
+
+class QSessionManagerPrivate : public QObjectPrivate
+{
+public:
+ QSessionManagerPrivate(QSessionManager* mgr, QString& id, QString& key)
+ : QObjectPrivate(), sm(mgr), sessionId(id), sessionKey(key),
+ restartHint(QSessionManager::RestartIfRunning), eventLoop(0) {}
+ QSessionManager* sm;
+ QStringList restartCommand;
+ QStringList discardCommand;
+ QString& sessionId;
+ QString& sessionKey;
+ QSessionManager::RestartHint restartHint;
+ QEventLoop *eventLoop;
+};
+
+class QSmSocketReceiver : public QObject
+{
+ Q_OBJECT
+public:
+ QSmSocketReceiver(int socket)
+ {
+ QSocketNotifier* sn = new QSocketNotifier(socket, QSocketNotifier::Read, this);
+ connect(sn, SIGNAL(activated(int)), this, SLOT(socketActivated(int)));
+ }
+
+public slots:
+ void socketActivated(int);
+};
+
+
+static SmcConn smcConnection = 0;
+static bool sm_interactionActive;
+static bool sm_smActive;
+static int sm_interactStyle;
+static int sm_saveType;
+static bool sm_cancel;
+// static bool sm_waitingForPhase2; ### never used?!?
+static bool sm_waitingForInteraction;
+static bool sm_isshutdown;
+// static bool sm_shouldbefast; ### never used?!?
+static bool sm_phase2;
+static bool sm_in_phase2;
+
+static QSmSocketReceiver* sm_receiver = 0;
+
+static void resetSmState();
+static void sm_setProperty(const char* name, const char* type,
+ int num_vals, SmPropValue* vals);
+static void sm_saveYourselfCallback(SmcConn smcConn, SmPointer clientData,
+ int saveType, Bool shutdown , int interactStyle, Bool fast);
+static void sm_saveYourselfPhase2Callback(SmcConn smcConn, SmPointer clientData) ;
+static void sm_dieCallback(SmcConn smcConn, SmPointer clientData) ;
+static void sm_shutdownCancelledCallback(SmcConn smcConn, SmPointer clientData);
+static void sm_saveCompleteCallback(SmcConn smcConn, SmPointer clientData);
+static void sm_interactCallback(SmcConn smcConn, SmPointer clientData);
+static void sm_performSaveYourself(QSessionManagerPrivate*);
+
+static void resetSmState()
+{
+// sm_waitingForPhase2 = false; ### never used?!?
+ sm_waitingForInteraction = false;
+ sm_interactionActive = false;
+ sm_interactStyle = SmInteractStyleNone;
+ sm_smActive = false;
+ qt_sm_blockUserInput = false;
+ sm_isshutdown = false;
+// sm_shouldbefast = false; ### never used?!?
+ sm_phase2 = false;
+ sm_in_phase2 = false;
+}
+
+
+// theoretically it's possible to set several properties at once. For
+// simplicity, however, we do just one property at a time
+static void sm_setProperty(const char* name, const char* type,
+ int num_vals, SmPropValue* vals)
+{
+ if (num_vals) {
+ SmProp prop;
+ prop.name = (char*)name;
+ prop.type = (char*)type;
+ prop.num_vals = num_vals;
+ prop.vals = vals;
+
+ SmProp* props[1];
+ props[0] = &prop;
+ SmcSetProperties(smcConnection, 1, props);
+ }
+ else {
+ char* names[1];
+ names[0] = (char*) name;
+ SmcDeleteProperties(smcConnection, 1, names);
+ }
+}
+
+static void sm_setProperty(const QString& name, const QString& value)
+{
+ QByteArray v = value.toUtf8();
+ SmPropValue prop;
+ prop.length = v.length();
+ prop.value = (SmPointer) v.constData();
+ sm_setProperty(name.toLatin1().data(), SmARRAY8, 1, &prop);
+}
+
+static void sm_setProperty(const QString& name, const QStringList& value)
+{
+ SmPropValue *prop = new SmPropValue[value.count()];
+ int count = 0;
+ QList<QByteArray> vl;
+ for (QStringList::ConstIterator it = value.begin(); it != value.end(); ++it) {
+ prop[count].length = (*it).length();
+ vl.append((*it).toUtf8());
+ prop[count].value = (char*)vl.last().data();
+ ++count;
+ }
+ sm_setProperty(name.toLatin1().data(), SmLISTofARRAY8, count, prop);
+ delete [] prop;
+}
+
+
+// workaround for broken libsm, see below
+struct QT_smcConn {
+ unsigned int save_yourself_in_progress : 1;
+ unsigned int shutdown_in_progress : 1;
+};
+
+static void sm_saveYourselfCallback(SmcConn smcConn, SmPointer clientData,
+ int saveType, Bool shutdown , int interactStyle, Bool /*fast*/)
+{
+ if (smcConn != smcConnection)
+ return;
+ sm_cancel = false;
+ sm_smActive = true;
+ sm_isshutdown = shutdown;
+ sm_saveType = saveType;
+ sm_interactStyle = interactStyle;
+// sm_shouldbefast = fast; ### never used?!?
+
+ // ugly workaround for broken libSM. libSM should do that _before_
+ // actually invoking the callback in sm_process.c
+ ((QT_smcConn*)smcConn)->save_yourself_in_progress = true;
+ if (sm_isshutdown)
+ ((QT_smcConn*)smcConn)->shutdown_in_progress = true;
+
+ sm_performSaveYourself((QSessionManagerPrivate*) clientData);
+ if (!sm_isshutdown) // we cannot expect a confirmation message in that case
+ resetSmState();
+}
+
+static void sm_performSaveYourself(QSessionManagerPrivate* smd)
+{
+ if (sm_isshutdown)
+ qt_sm_blockUserInput = true;
+
+ QSessionManager* sm = smd->sm;
+
+ // generate a new session key
+ timeval tv;
+ gettimeofday(&tv, 0);
+ smd->sessionKey = QString::number(qulonglong(tv.tv_sec)) + QLatin1Char('_') + QString::number(qulonglong(tv.tv_usec));
+
+ QStringList arguments = qApp->arguments();
+ QString argument0 = arguments.isEmpty() ? qApp->applicationFilePath() : arguments.at(0);
+
+ // tell the session manager about our program in best POSIX style
+ sm_setProperty(QString::fromLatin1(SmProgram), argument0);
+ // tell the session manager about our user as well.
+ struct passwd *entryPtr = 0;
+#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) && (_POSIX_THREAD_SAFE_FUNCTIONS - 0 > 0)
+ QVarLengthArray<char, 1024> buf(qMax<long>(sysconf(_SC_GETPW_R_SIZE_MAX), 1024L));
+ struct passwd entry;
+ while (getpwuid_r(geteuid(), &entry, buf.data(), buf.size(), &entryPtr) == ERANGE) {
+ if (buf.size() >= 32768) {
+ // too big already, fail
+ static char badusername[] = "";
+ entryPtr = &entry;
+ entry.pw_name = badusername;
+ break;
+ }
+
+ // retry with a bigger buffer
+ buf.resize(buf.size() * 2);
+ }
+#else
+ entryPtr = getpwuid(geteuid());
+#endif
+ if (entryPtr)
+ sm_setProperty(QString::fromLatin1(SmUserID), QString::fromLatin1(entryPtr->pw_name));
+
+ // generate a restart and discard command that makes sense
+ QStringList restart;
+ restart << argument0 << QLatin1String("-session")
+ << smd->sessionId + QLatin1Char('_') + smd->sessionKey;
+ if (qstricmp(appName, QX11Info::appClass()) != 0)
+ restart << QLatin1String("-name") << qAppName();
+ sm->setRestartCommand(restart);
+ QStringList discard;
+ sm->setDiscardCommand(discard);
+
+ switch (sm_saveType) {
+ case SmSaveBoth:
+ qApp->commitData(*sm);
+ if (sm_isshutdown && sm_cancel)
+ break; // we cancelled the shutdown, no need to save state
+ // fall through
+ case SmSaveLocal:
+ qApp->saveState(*sm);
+ break;
+ case SmSaveGlobal:
+ qApp->commitData(*sm);
+ break;
+ default:
+ break;
+ }
+
+ if (sm_phase2 && !sm_in_phase2) {
+ SmcRequestSaveYourselfPhase2(smcConnection, sm_saveYourselfPhase2Callback, (SmPointer*) smd);
+ qt_sm_blockUserInput = false;
+ }
+ else {
+ // close eventual interaction monitors and cancel the
+ // shutdown, if required. Note that we can only cancel when
+ // performing a shutdown, it does not work for checkpoints
+ if (sm_interactionActive) {
+ SmcInteractDone(smcConnection, sm_isshutdown && sm_cancel);
+ sm_interactionActive = false;
+ }
+ else if (sm_cancel && sm_isshutdown) {
+ if (sm->allowsErrorInteraction()) {
+ SmcInteractDone(smcConnection, True);
+ sm_interactionActive = false;
+ }
+ }
+
+ // set restart and discard command in session manager
+ sm_setProperty(QString::fromLatin1(SmRestartCommand), sm->restartCommand());
+ sm_setProperty(QString::fromLatin1(SmDiscardCommand), sm->discardCommand());
+
+ // set the restart hint
+ SmPropValue prop;
+ prop.length = sizeof(int);
+ int value = sm->restartHint();
+ prop.value = (SmPointer) &value;
+ sm_setProperty(SmRestartStyleHint, SmCARD8, 1, &prop);
+
+ // we are done
+ SmcSaveYourselfDone(smcConnection, !sm_cancel);
+ }
+}
+
+static void sm_dieCallback(SmcConn smcConn, SmPointer /* clientData */)
+{
+ if (smcConn != smcConnection)
+ return;
+ resetSmState();
+ QEvent quitEvent(QEvent::Quit);
+ QApplication::sendEvent(qApp, &quitEvent);
+}
+
+static void sm_shutdownCancelledCallback(SmcConn smcConn, SmPointer clientData)
+{
+ if (smcConn != smcConnection)
+ return;
+ if (sm_waitingForInteraction)
+ ((QSessionManagerPrivate *) clientData)->eventLoop->exit();
+ resetSmState();
+}
+
+static void sm_saveCompleteCallback(SmcConn smcConn, SmPointer /*clientData */)
+{
+ if (smcConn != smcConnection)
+ return;
+ resetSmState();
+}
+
+static void sm_interactCallback(SmcConn smcConn, SmPointer clientData)
+{
+ if (smcConn != smcConnection)
+ return;
+ if (sm_waitingForInteraction)
+ ((QSessionManagerPrivate *) clientData)->eventLoop->exit();
+}
+
+static void sm_saveYourselfPhase2Callback(SmcConn smcConn, SmPointer clientData)
+{
+ if (smcConn != smcConnection)
+ return;
+ sm_in_phase2 = true;
+ sm_performSaveYourself((QSessionManagerPrivate*) clientData);
+}
+
+
+void QSmSocketReceiver::socketActivated(int)
+{
+ IceProcessMessages(SmcGetIceConnection(smcConnection), 0, 0);
+}
+
+
+#undef Bool
+QT_BEGIN_INCLUDE_NAMESPACE
+#include "qapplication_x11.moc"
+QT_END_INCLUDE_NAMESPACE
+
+QSessionManager::QSessionManager(QApplication * app, QString &id, QString& key)
+ : QObject(*new QSessionManagerPrivate(this, id, key), app)
+{
+ Q_D(QSessionManager);
+ d->restartHint = RestartIfRunning;
+
+ resetSmState();
+ char cerror[256];
+ char* myId = 0;
+ QByteArray b_id = id.toLatin1();
+ char* prevId = b_id.data();
+
+ SmcCallbacks cb;
+ cb.save_yourself.callback = sm_saveYourselfCallback;
+ cb.save_yourself.client_data = (SmPointer) d;
+ cb.die.callback = sm_dieCallback;
+ cb.die.client_data = (SmPointer) d;
+ cb.save_complete.callback = sm_saveCompleteCallback;
+ cb.save_complete.client_data = (SmPointer) d;
+ cb.shutdown_cancelled.callback = sm_shutdownCancelledCallback;
+ cb.shutdown_cancelled.client_data = (SmPointer) d;
+
+ // avoid showing a warning message below
+ if (qgetenv("SESSION_MANAGER").isEmpty())
+ return;
+
+ smcConnection = SmcOpenConnection(0, 0, 1, 0,
+ SmcSaveYourselfProcMask |
+ SmcDieProcMask |
+ SmcSaveCompleteProcMask |
+ SmcShutdownCancelledProcMask,
+ &cb,
+ prevId,
+ &myId,
+ 256, cerror);
+
+ id = QString::fromLatin1(myId);
+ ::free(myId); // it was allocated by C
+
+ QString error = QString::fromLocal8Bit(cerror);
+ if (!smcConnection) {
+ qWarning("Qt: Session management error: %s", qPrintable(error));
+ }
+ else {
+ sm_receiver = new QSmSocketReceiver(IceConnectionNumber(SmcGetIceConnection(smcConnection)));
+ }
+}
+
+QSessionManager::~QSessionManager()
+{
+ if (smcConnection)
+ SmcCloseConnection(smcConnection, 0, 0);
+ smcConnection = 0;
+ delete sm_receiver;
+}
+
+QString QSessionManager::sessionId() const
+{
+ Q_D(const QSessionManager);
+ return d->sessionId;
+}
+
+QString QSessionManager::sessionKey() const
+{
+ Q_D(const QSessionManager);
+ return d->sessionKey;
+}
+
+
+void* QSessionManager::handle() const
+{
+ return (void*) smcConnection;
+}
+
+
+bool QSessionManager::allowsInteraction()
+{
+ Q_D(QSessionManager);
+ if (sm_interactionActive)
+ return true;
+
+ if (sm_waitingForInteraction)
+ return false;
+
+ if (sm_interactStyle == SmInteractStyleAny) {
+ sm_waitingForInteraction = SmcInteractRequest(smcConnection, SmDialogNormal,
+ sm_interactCallback, (SmPointer*) d);
+ }
+ if (sm_waitingForInteraction) {
+ QEventLoop eventLoop;
+ d->eventLoop = &eventLoop;
+ (void) eventLoop.exec();
+ d->eventLoop = 0;
+
+ sm_waitingForInteraction = false;
+ if (sm_smActive) { // not cancelled
+ sm_interactionActive = true;
+ qt_sm_blockUserInput = false;
+ return true;
+ }
+ }
+ return false;
+}
+
+bool QSessionManager::allowsErrorInteraction()
+{
+ Q_D(QSessionManager);
+ if (sm_interactionActive)
+ return true;
+
+ if (sm_waitingForInteraction)
+ return false;
+
+ if (sm_interactStyle == SmInteractStyleAny || sm_interactStyle == SmInteractStyleErrors) {
+ sm_waitingForInteraction = SmcInteractRequest(smcConnection, SmDialogError,
+ sm_interactCallback, (SmPointer*) d);
+ }
+ if (sm_waitingForInteraction) {
+ QEventLoop eventLoop;
+ d->eventLoop = &eventLoop;
+ (void) eventLoop.exec();
+ d->eventLoop = 0;
+
+ sm_waitingForInteraction = false;
+ if (sm_smActive) { // not cancelled
+ sm_interactionActive = true;
+ qt_sm_blockUserInput = false;
+ return true;
+ }
+ }
+ return false;
+}
+
+void QSessionManager::release()
+{
+ if (sm_interactionActive) {
+ SmcInteractDone(smcConnection, False);
+ sm_interactionActive = false;
+ if (sm_smActive && sm_isshutdown)
+ qt_sm_blockUserInput = true;
+ }
+}
+
+void QSessionManager::cancel()
+{
+ sm_cancel = true;
+}
+
+void QSessionManager::setRestartHint(QSessionManager::RestartHint hint)
+{
+ Q_D(QSessionManager);
+ d->restartHint = hint;
+}
+
+QSessionManager::RestartHint QSessionManager::restartHint() const
+{
+ Q_D(const QSessionManager);
+ return d->restartHint;
+}
+
+void QSessionManager::setRestartCommand(const QStringList& command)
+{
+ Q_D(QSessionManager);
+ d->restartCommand = command;
+}
+
+QStringList QSessionManager::restartCommand() const
+{
+ Q_D(const QSessionManager);
+ return d->restartCommand;
+}
+
+void QSessionManager::setDiscardCommand(const QStringList& command)
+{
+ Q_D(QSessionManager);
+ d->discardCommand = command;
+}
+
+QStringList QSessionManager::discardCommand() const
+{
+ Q_D(const QSessionManager);
+ return d->discardCommand;
+}
+
+void QSessionManager::setManagerProperty(const QString& name, const QString& value)
+{
+ sm_setProperty(name, value);
+}
+
+void QSessionManager::setManagerProperty(const QString& name, const QStringList& value)
+{
+ sm_setProperty(name, value);
+}
+
+bool QSessionManager::isPhase2() const
+{
+ return sm_in_phase2;
+}
+
+void QSessionManager::requestPhase2()
+{
+ sm_phase2 = true;
+}
+
+#endif // QT_NO_SESSIONMANAGER
+
+#if defined(QT_RX71_MULTITOUCH)
+
+static inline int testBit(const char *array, int bit)
+{
+ return (array[bit/8] & (1<<(bit%8)));
+}
+
+static int openRX71Device(const QByteArray &deviceName)
+{
+ int fd = open(deviceName, O_RDONLY | O_NONBLOCK);
+ if (fd == -1) {
+ fd = -errno;
+ return fd;
+ }
+
+ // fetch the event type mask and check that the device reports absolute coordinates
+ char eventTypeMask[(EV_MAX + sizeof(char) - 1) * sizeof(char) + 1];
+ memset(eventTypeMask, 0, sizeof(eventTypeMask));
+ if (ioctl(fd, EVIOCGBIT(0, sizeof(eventTypeMask)), eventTypeMask) < 0) {
+ close(fd);
+ return -1;
+ }
+ if (!testBit(eventTypeMask, EV_ABS)) {
+ close(fd);
+ return -1;
+ }
+
+ // make sure that we can get the absolute X and Y positions from the device
+ char absMask[(ABS_MAX + sizeof(char) - 1) * sizeof(char) + 1];
+ memset(absMask, 0, sizeof(absMask));
+ if (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absMask)), absMask) < 0) {
+ close(fd);
+ return -1;
+ }
+ if (!testBit(absMask, ABS_X) || !testBit(absMask, ABS_Y)) {
+ close(fd);
+ return -1;
+ }
+
+ return fd;
+}
+
+void QApplicationPrivate::initializeMultitouch_sys()
+{
+ Q_Q(QApplication);
+
+ QByteArray deviceName = QByteArray("/dev/input/event");
+ int currentDeviceNumber = 0;
+ for (;;) {
+ int fd = openRX71Device(QByteArray(deviceName + QByteArray::number(currentDeviceNumber++)));
+ if (fd == -ENOENT) {
+ // no more devices
+ break;
+ }
+ if (fd < 0) {
+ // not a touch device
+ continue;
+ }
+
+ struct input_absinfo abs_x, abs_y, abs_z;
+ ioctl(fd, EVIOCGABS(ABS_X), &abs_x);
+ ioctl(fd, EVIOCGABS(ABS_Y), &abs_y);
+ ioctl(fd, EVIOCGABS(ABS_Z), &abs_z);
+
+ int deviceNumber = allRX71TouchPoints.count();
+
+ QSocketNotifier *socketNotifier = new QSocketNotifier(fd, QSocketNotifier::Read, q);
+ QObject::connect(socketNotifier, SIGNAL(activated(int)), q, SLOT(_q_readRX71MultiTouchEvents()));
+
+ RX71TouchPointState touchPointState = {
+ socketNotifier,
+ QTouchEvent::TouchPoint(deviceNumber),
+
+ abs_x.minimum, abs_x.maximum, q->desktop()->screenGeometry().width(),
+ abs_y.minimum, abs_y.maximum, q->desktop()->screenGeometry().height(),
+ abs_z.minimum, abs_z.maximum
+ };
+ allRX71TouchPoints.append(touchPointState);
+ }
+
+ hasRX71MultiTouch = allRX71TouchPoints.count() > 1;
+ if (!hasRX71MultiTouch) {
+ for (int i = 0; i < allRX71TouchPoints.count(); ++i) {
+ QSocketNotifier *socketNotifier = allRX71TouchPoints.at(i).socketNotifier;
+ close(socketNotifier->socket());
+ delete socketNotifier;
+ }
+ allRX71TouchPoints.clear();
+ }
+}
+
+void QApplicationPrivate::cleanupMultitouch_sys()
+{
+ hasRX71MultiTouch = false;
+ for (int i = 0; i < allRX71TouchPoints.count(); ++i) {
+ QSocketNotifier *socketNotifier = allRX71TouchPoints.at(i).socketNotifier;
+ close(socketNotifier->socket());
+ delete socketNotifier;
+ }
+ allRX71TouchPoints.clear();
+}
+
+bool QApplicationPrivate::readRX71MultiTouchEvents(int deviceNumber)
+{
+ RX71TouchPointState &touchPointState = allRX71TouchPoints[deviceNumber];
+ QSocketNotifier *socketNotifier = touchPointState.socketNotifier;
+ int fd = socketNotifier->socket();
+
+ QTouchEvent::TouchPoint &touchPoint = touchPointState.touchPoint;
+
+ bool down = touchPoint.state() != Qt::TouchPointReleased;
+ if (down)
+ touchPoint.setState(Qt::TouchPointStationary);
+
+ bool changed = false;
+ for (;;) {
+ struct input_event inputEvent;
+ int bytesRead = read(fd, &inputEvent, sizeof(inputEvent));
+ if (bytesRead <= 0)
+ break;
+ if (bytesRead != sizeof(inputEvent)) {
+ qWarning("Qt: INTERNAL ERROR: short read in readRX71MultiTouchEvents()");
+ return false;
+ }
+
+ switch (inputEvent.type) {
+ case EV_SYN:
+ changed = true;
+ switch (touchPoint.state()) {
+ case Qt::TouchPointPressed:
+ case Qt::TouchPointReleased:
+ // make sure we don't compress pressed and releases with any other events
+ return changed;
+ default:
+ break;
+ }
+ continue;
+ case EV_KEY:
+ case EV_ABS:
+ break;
+ default:
+ qWarning("Qt: WARNING: unknown event type %d on multitouch device", inputEvent.type);
+ continue;
+ }
+
+ QPointF screenPos = touchPoint.screenPos();
+ switch (inputEvent.code) {
+ case BTN_TOUCH:
+ if (!down && inputEvent.value != 0)
+ touchPoint.setState(Qt::TouchPointPressed);
+ else if (down && inputEvent.value == 0)
+ touchPoint.setState(Qt::TouchPointReleased);
+ break;
+ case ABS_TOOL_WIDTH:
+ case ABS_VOLUME:
+ case ABS_PRESSURE:
+ // ignore for now
+ break;
+ case ABS_X:
+ {
+ qreal newValue = ((qreal(inputEvent.value - touchPointState.minX)
+ / qreal(touchPointState.maxX - touchPointState.minX))
+ * touchPointState.scaleX);
+ screenPos.rx() = newValue;
+ touchPoint.setScreenPos(screenPos);
+ break;
+ }
+ case ABS_Y:
+ {
+ qreal newValue = ((qreal(inputEvent.value - touchPointState.minY)
+ / qreal(touchPointState.maxY - touchPointState.minY))
+ * touchPointState.scaleY);
+ screenPos.ry() = newValue;
+ touchPoint.setScreenPos(screenPos);
+ break;
+ }
+ case ABS_Z:
+ {
+ // map Z (signal strength) to pressure for now
+ qreal newValue = (qreal(inputEvent.value - touchPointState.minZ)
+ / qreal(touchPointState.maxZ - touchPointState.minZ));
+ touchPoint.setPressure(newValue);
+ break;
+ }
+ default:
+ qWarning("Qt: WARNING: unknown event code %d on multitouch device", inputEvent.code);
+ continue;
+ }
+ }
+
+ if (down && touchPoint.state() != Qt::TouchPointReleased)
+ touchPoint.setState(changed ? Qt::TouchPointMoved : Qt::TouchPointStationary);
+
+ return changed;
+}
+
+void QApplicationPrivate::_q_readRX71MultiTouchEvents()
+{
+ // read touch events from all devices
+ bool changed = false;
+ for (int i = 0; i < allRX71TouchPoints.count(); ++i)
+ changed = readRX71MultiTouchEvents(i) || changed;
+ if (!changed)
+ return;
+
+ QList<QTouchEvent::TouchPoint> touchPoints;
+ for (int i = 0; i < allRX71TouchPoints.count(); ++i)
+ touchPoints.append(allRX71TouchPoints.at(i).touchPoint);
+
+ translateRawTouchEvent(0, QTouchEvent::TouchScreen, touchPoints);
+}
+
+#else // !QT_RX71_MULTITOUCH
+
+void QApplicationPrivate::initializeMultitouch_sys()
+{ }
+void QApplicationPrivate::cleanupMultitouch_sys()
+{ }
+
+#endif // QT_RX71_MULTITOUCH
+
+QT_END_NAMESPACE
diff --git a/src/gui/kernel/qclipboard_x11.cpp b/src/widgets/platforms/x11/qclipboard_x11.cpp
index 97e076cbc2..97e076cbc2 100644
--- a/src/gui/kernel/qclipboard_x11.cpp
+++ b/src/widgets/platforms/x11/qclipboard_x11.cpp
diff --git a/src/gui/painting/qcolormap_x11.cpp b/src/widgets/platforms/x11/qcolormap_x11.cpp
index 1d6d7b8adb..1d6d7b8adb 100644
--- a/src/gui/painting/qcolormap_x11.cpp
+++ b/src/widgets/platforms/x11/qcolormap_x11.cpp
diff --git a/src/widgets/platforms/x11/qcursor_x11.cpp b/src/widgets/platforms/x11/qcursor_x11.cpp
new file mode 100644
index 0000000000..1132d3737d
--- /dev/null
+++ b/src/widgets/platforms/x11/qcursor_x11.cpp
@@ -0,0 +1,640 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qdebug.h>
+#include <qdatastream.h>
+#include <private/qcursor_p.h>
+#include <private/qt_x11_p.h>
+#include <private/qapplication_p.h>
+#include <qbitmap.h>
+#include <qcursor.h>
+#include <X11/cursorfont.h>
+
+#include <qlibrary.h>
+
+#ifndef QT_NO_XCURSOR
+# include <X11/Xcursor/Xcursor.h>
+#endif // QT_NO_XCURSOR
+
+#ifndef QT_NO_XFIXES
+#ifndef Status
+#define Status int
+#endif
+# include <X11/extensions/Xfixes.h>
+#endif // QT_NO_XFIXES
+
+#include "qx11info_x11.h"
+#include <private/qpixmap_x11_p.h>
+
+QT_BEGIN_NAMESPACE
+
+// Define QT_USE_APPROXIMATE_CURSORS when compiling if you REALLY want to
+// use the ugly X11 cursors.
+
+/*****************************************************************************
+ Internal QCursorData class
+ *****************************************************************************/
+
+QCursorData::QCursorData(Qt::CursorShape s)
+ : cshape(s), bm(0), bmm(0), hx(0), hy(0), hcurs(0), pm(0), pmm(0)
+{
+ ref = 1;
+}
+
+QCursorData::~QCursorData()
+{
+ Display *dpy = X11 ? X11->display : (Display*)0;
+
+ // Add in checking for the display too as on HP-UX
+ // we seem to get a core dump as the cursor data is
+ // deleted again from main() on exit...
+ if (hcurs && dpy)
+ XFreeCursor(dpy, hcurs);
+ if (pm && dpy)
+ XFreePixmap(dpy, pm);
+ if (pmm && dpy)
+ XFreePixmap(dpy, pmm);
+ delete bm;
+ delete bmm;
+}
+
+#ifndef QT_NO_CURSOR
+QCursor::QCursor(Qt::HANDLE cursor)
+{
+ if (!QCursorData::initialized)
+ QCursorData::initialize();
+ d = new QCursorData(Qt::CustomCursor);
+ d->hcurs = cursor;
+}
+
+#endif
+
+QCursorData *QCursorData::setBitmap(const QBitmap &bitmap, const QBitmap &mask, int hotX, int hotY)
+{
+ if (!QCursorData::initialized)
+ QCursorData::initialize();
+ if (bitmap.depth() != 1 || mask.depth() != 1 || bitmap.size() != mask.size()) {
+ qWarning("QCursor: Cannot create bitmap cursor; invalid bitmap(s)");
+ QCursorData *c = qt_cursorTable[0];
+ c->ref.ref();
+ return c;
+ }
+ QCursorData *d = new QCursorData;
+ d->ref = 1;
+
+ extern QPixmap qt_toX11Pixmap(const QPixmap &pixmap); // qpixmap_x11.cpp
+ d->bm = new QBitmap(qt_toX11Pixmap(bitmap));
+ d->bmm = new QBitmap(qt_toX11Pixmap(mask));
+
+ d->hcurs = 0;
+ d->cshape = Qt::BitmapCursor;
+ d->hx = hotX >= 0 ? hotX : bitmap.width() / 2;
+ d->hy = hotY >= 0 ? hotY : bitmap.height() / 2;
+ d->fg.red = 0x0000;
+ d->fg.green = 0x0000;
+ d->fg.blue = 0x0000;
+ d->bg.red = 0xffff;
+ d->bg.green = 0xffff;
+ d->bg.blue = 0xffff;
+ return d;
+}
+
+
+
+#ifndef QT_NO_CURSOR
+Qt::HANDLE QCursor::handle() const
+{
+ if (!QCursorData::initialized)
+ QCursorData::initialize();
+ if (!d->hcurs)
+ d->update();
+ return d->hcurs;
+}
+#endif
+
+QPoint QCursor::pos()
+{
+ Window root;
+ Window child;
+ int root_x, root_y, win_x, win_y;
+ uint buttons;
+ Display* dpy = X11->display;
+ for (int i = 0; i < ScreenCount(dpy); ++i) {
+ if (XQueryPointer(dpy, QX11Info::appRootWindow(i), &root, &child, &root_x, &root_y,
+ &win_x, &win_y, &buttons))
+
+ return QPoint(root_x, root_y);
+ }
+ return QPoint();
+}
+
+/*! \internal
+*/
+#ifndef QT_NO_CURSOR
+int QCursor::x11Screen()
+{
+ Window root;
+ Window child;
+ int root_x, root_y, win_x, win_y;
+ uint buttons;
+ Display* dpy = X11->display;
+ for (int i = 0; i < ScreenCount(dpy); ++i) {
+ if (XQueryPointer(dpy, QX11Info::appRootWindow(i), &root, &child, &root_x, &root_y,
+ &win_x, &win_y, &buttons))
+ return i;
+ }
+ return -1;
+}
+#endif
+
+void QCursor::setPos(int x, int y)
+{
+ QPoint current, target(x, y);
+
+ // this is copied from pos(), since we need the screen number for the correct
+ // root window in the XWarpPointer call
+ Window root;
+ Window child;
+ int root_x, root_y, win_x, win_y;
+ uint buttons;
+ Display* dpy = X11->display;
+ int screen;
+ for (screen = 0; screen < ScreenCount(dpy); ++screen) {
+ if (XQueryPointer(dpy, QX11Info::appRootWindow(screen), &root, &child, &root_x, &root_y,
+ &win_x, &win_y, &buttons)) {
+ current = QPoint(root_x, root_y);
+ break;
+ }
+ }
+
+ if (screen >= ScreenCount(dpy))
+ return;
+
+ // Need to check, since some X servers generate null mouse move
+ // events, causing looping in applications which call setPos() on
+ // every mouse move event.
+ //
+ if (current == target)
+ return;
+
+ XWarpPointer(X11->display, XNone, QX11Info::appRootWindow(screen), 0, 0, 0, 0, x, y);
+}
+
+
+/*!
+ \internal
+
+ Creates the cursor.
+*/
+
+void QCursorData::update()
+{
+ if (!QCursorData::initialized)
+ QCursorData::initialize();
+ if (hcurs)
+ return;
+
+ Display *dpy = X11->display;
+ Window rootwin = QX11Info::appRootWindow();
+
+ if (cshape == Qt::BitmapCursor) {
+ extern QPixmap qt_toX11Pixmap(const QPixmap &pixmap); // qpixmap_x11.cpp
+#ifndef QT_NO_XRENDER
+ if (!pixmap.isNull() && X11->use_xrender) {
+ pixmap = qt_toX11Pixmap(pixmap);
+ hcurs = XRenderCreateCursor (X11->display, pixmap.x11PictureHandle(), hx, hy);
+ } else
+#endif
+ {
+ hcurs = XCreatePixmapCursor(dpy, bm->handle(), bmm->handle(), &fg, &bg, hx, hy);
+ }
+ return;
+ }
+
+ static const char *cursorNames[] = {
+ "left_ptr",
+ "up_arrow",
+ "cross",
+ "wait",
+ "ibeam",
+ "size_ver",
+ "size_hor",
+ "size_bdiag",
+ "size_fdiag",
+ "size_all",
+ "blank",
+ "split_v",
+ "split_h",
+ "pointing_hand",
+ "forbidden",
+ "whats_this",
+ "left_ptr_watch",
+ "openhand",
+ "closedhand",
+ "copy",
+ "move",
+ "link"
+ };
+
+#ifndef QT_NO_XCURSOR
+ if (X11->ptrXcursorLibraryLoadCursor) {
+ // special case for non-standard dnd-* cursors
+ switch (cshape) {
+ case Qt::DragCopyCursor:
+ hcurs = X11->ptrXcursorLibraryLoadCursor(dpy, "dnd-copy");
+ break;
+ case Qt::DragMoveCursor:
+ hcurs = X11->ptrXcursorLibraryLoadCursor(dpy, "dnd-move");
+ break;
+ case Qt::DragLinkCursor:
+ hcurs = X11->ptrXcursorLibraryLoadCursor(dpy, "dnd-link");
+ break;
+ default:
+ break;
+ }
+ if (!hcurs)
+ hcurs = X11->ptrXcursorLibraryLoadCursor(dpy, cursorNames[cshape]);
+ }
+ if (hcurs)
+ return;
+#endif // QT_NO_XCURSOR
+
+ static const uchar cur_blank_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+ // Non-standard X11 cursors are created from bitmaps
+
+#ifndef QT_USE_APPROXIMATE_CURSORS
+ static const uchar cur_ver_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0xf0, 0x0f,
+ 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0xf0, 0x0f,
+ 0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01, 0x00, 0x00 };
+ static const uchar mcur_ver_bits[] = {
+ 0x00, 0x00, 0x80, 0x03, 0xc0, 0x07, 0xe0, 0x0f, 0xf0, 0x1f, 0xf8, 0x3f,
+ 0xfc, 0x7f, 0xc0, 0x07, 0xc0, 0x07, 0xc0, 0x07, 0xfc, 0x7f, 0xf8, 0x3f,
+ 0xf0, 0x1f, 0xe0, 0x0f, 0xc0, 0x07, 0x80, 0x03 };
+ static const uchar cur_hor_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x08, 0x30, 0x18,
+ 0x38, 0x38, 0xfc, 0x7f, 0xfc, 0x7f, 0x38, 0x38, 0x30, 0x18, 0x20, 0x08,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ static const uchar mcur_hor_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x40, 0x04, 0x60, 0x0c, 0x70, 0x1c, 0x78, 0x3c,
+ 0xfc, 0x7f, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfc, 0x7f, 0x78, 0x3c,
+ 0x70, 0x1c, 0x60, 0x0c, 0x40, 0x04, 0x00, 0x00 };
+ static const uchar cur_bdiag_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x3e, 0x00, 0x3c, 0x00, 0x3e,
+ 0x00, 0x37, 0x88, 0x23, 0xd8, 0x01, 0xf8, 0x00, 0x78, 0x00, 0xf8, 0x00,
+ 0xf8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ static const uchar mcur_bdiag_bits[] = {
+ 0x00, 0x00, 0xc0, 0x7f, 0x80, 0x7f, 0x00, 0x7f, 0x00, 0x7e, 0x04, 0x7f,
+ 0x8c, 0x7f, 0xdc, 0x77, 0xfc, 0x63, 0xfc, 0x41, 0xfc, 0x00, 0xfc, 0x01,
+ 0xfc, 0x03, 0xfc, 0x07, 0x00, 0x00, 0x00, 0x00 };
+ static const uchar cur_fdiag_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x01, 0xf8, 0x00, 0x78, 0x00,
+ 0xf8, 0x00, 0xd8, 0x01, 0x88, 0x23, 0x00, 0x37, 0x00, 0x3e, 0x00, 0x3c,
+ 0x00, 0x3e, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00 };
+ static const uchar mcur_fdiag_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0xfc, 0x07, 0xfc, 0x03, 0xfc, 0x01, 0xfc, 0x00,
+ 0xfc, 0x41, 0xfc, 0x63, 0xdc, 0x77, 0x8c, 0x7f, 0x04, 0x7f, 0x00, 0x7e,
+ 0x00, 0x7f, 0x80, 0x7f, 0xc0, 0x7f, 0x00, 0x00 };
+ static const uchar *cursor_bits16[] = {
+ cur_ver_bits, mcur_ver_bits, cur_hor_bits, mcur_hor_bits,
+ cur_bdiag_bits, mcur_bdiag_bits, cur_fdiag_bits, mcur_fdiag_bits,
+ 0, 0, cur_blank_bits, cur_blank_bits };
+
+ static const uchar vsplit_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xe0, 0x03, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xff, 0x7f, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x7f, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00,
+ 0x00, 0xc0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ static const uchar vsplitm_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0xc0, 0x01, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x00, 0xf0, 0x07, 0x00,
+ 0x00, 0xf8, 0x0f, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00,
+ 0x00, 0xc0, 0x01, 0x00, 0x80, 0xff, 0xff, 0x00, 0x80, 0xff, 0xff, 0x00,
+ 0x80, 0xff, 0xff, 0x00, 0x80, 0xff, 0xff, 0x00, 0x80, 0xff, 0xff, 0x00,
+ 0x80, 0xff, 0xff, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00,
+ 0x00, 0xc0, 0x01, 0x00, 0x00, 0xf8, 0x0f, 0x00, 0x00, 0xf0, 0x07, 0x00,
+ 0x00, 0xe0, 0x03, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ static const uchar hsplit_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00,
+ 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00,
+ 0x00, 0x41, 0x82, 0x00, 0x80, 0x41, 0x82, 0x01, 0xc0, 0x7f, 0xfe, 0x03,
+ 0x80, 0x41, 0x82, 0x01, 0x00, 0x41, 0x82, 0x00, 0x00, 0x40, 0x02, 0x00,
+ 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00,
+ 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ static const uchar hsplitm_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00,
+ 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe2, 0x47, 0x00, 0x00, 0xe3, 0xc7, 0x00,
+ 0x80, 0xe3, 0xc7, 0x01, 0xc0, 0xff, 0xff, 0x03, 0xe0, 0xff, 0xff, 0x07,
+ 0xc0, 0xff, 0xff, 0x03, 0x80, 0xe3, 0xc7, 0x01, 0x00, 0xe3, 0xc7, 0x00,
+ 0x00, 0xe2, 0x47, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00,
+ 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ static const uchar whatsthis_bits[] = {
+ 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0xf0, 0x07, 0x00,
+ 0x09, 0x18, 0x0e, 0x00, 0x11, 0x1c, 0x0e, 0x00, 0x21, 0x1c, 0x0e, 0x00,
+ 0x41, 0x1c, 0x0e, 0x00, 0x81, 0x1c, 0x0e, 0x00, 0x01, 0x01, 0x07, 0x00,
+ 0x01, 0x82, 0x03, 0x00, 0xc1, 0xc7, 0x01, 0x00, 0x49, 0xc0, 0x01, 0x00,
+ 0x95, 0xc0, 0x01, 0x00, 0x93, 0xc0, 0x01, 0x00, 0x21, 0x01, 0x00, 0x00,
+ 0x20, 0xc1, 0x01, 0x00, 0x40, 0xc2, 0x01, 0x00, 0x40, 0x02, 0x00, 0x00,
+ 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
+ static const uchar whatsthism_bits[] = {
+ 0x01, 0x00, 0x00, 0x00, 0x03, 0xf0, 0x07, 0x00, 0x07, 0xf8, 0x0f, 0x00,
+ 0x0f, 0xfc, 0x1f, 0x00, 0x1f, 0x3e, 0x1f, 0x00, 0x3f, 0x3e, 0x1f, 0x00,
+ 0x7f, 0x3e, 0x1f, 0x00, 0xff, 0x3e, 0x1f, 0x00, 0xff, 0x9d, 0x0f, 0x00,
+ 0xff, 0xc3, 0x07, 0x00, 0xff, 0xe7, 0x03, 0x00, 0x7f, 0xe0, 0x03, 0x00,
+ 0xf7, 0xe0, 0x03, 0x00, 0xf3, 0xe0, 0x03, 0x00, 0xe1, 0xe1, 0x03, 0x00,
+ 0xe0, 0xe1, 0x03, 0x00, 0xc0, 0xe3, 0x03, 0x00, 0xc0, 0xe3, 0x03, 0x00,
+ 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
+ static const uchar busy_bits[] = {
+ 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
+ 0x09, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
+ 0x41, 0xe0, 0xff, 0x00, 0x81, 0x20, 0x80, 0x00, 0x01, 0xe1, 0xff, 0x00,
+ 0x01, 0x42, 0x40, 0x00, 0xc1, 0x47, 0x40, 0x00, 0x49, 0x40, 0x55, 0x00,
+ 0x95, 0x80, 0x2a, 0x00, 0x93, 0x00, 0x15, 0x00, 0x21, 0x01, 0x0a, 0x00,
+ 0x20, 0x01, 0x11, 0x00, 0x40, 0x82, 0x20, 0x00, 0x40, 0x42, 0x44, 0x00,
+ 0x80, 0x41, 0x4a, 0x00, 0x00, 0x40, 0x55, 0x00, 0x00, 0xe0, 0xff, 0x00,
+ 0x00, 0x20, 0x80, 0x00, 0x00, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+ static const uchar busym_bits[] = {
+ 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
+ 0x0f, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00,
+ 0x7f, 0xe0, 0xff, 0x00, 0xff, 0xe0, 0xff, 0x00, 0xff, 0xe1, 0xff, 0x00,
+ 0xff, 0xc3, 0x7f, 0x00, 0xff, 0xc7, 0x7f, 0x00, 0x7f, 0xc0, 0x7f, 0x00,
+ 0xf7, 0x80, 0x3f, 0x00, 0xf3, 0x00, 0x1f, 0x00, 0xe1, 0x01, 0x0e, 0x00,
+ 0xe0, 0x01, 0x1f, 0x00, 0xc0, 0x83, 0x3f, 0x00, 0xc0, 0xc3, 0x7f, 0x00,
+ 0x80, 0xc1, 0x7f, 0x00, 0x00, 0xc0, 0x7f, 0x00, 0x00, 0xe0, 0xff, 0x00,
+ 0x00, 0xe0, 0xff, 0x00, 0x00, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+ static const uchar * const cursor_bits32[] = {
+ vsplit_bits, vsplitm_bits, hsplit_bits, hsplitm_bits,
+ 0, 0, 0, 0, whatsthis_bits, whatsthism_bits, busy_bits, busym_bits
+ };
+
+ static const uchar forbidden_bits[] = {
+ 0x00,0x00,0x00,0x80,0x1f,0x00,0xe0,0x7f,0x00,0xf0,0xf0,0x00,0x38,0xc0,0x01,
+ 0x7c,0x80,0x03,0xec,0x00,0x03,0xce,0x01,0x07,0x86,0x03,0x06,0x06,0x07,0x06,
+ 0x06,0x0e,0x06,0x06,0x1c,0x06,0x0e,0x38,0x07,0x0c,0x70,0x03,0x1c,0xe0,0x03,
+ 0x38,0xc0,0x01,0xf0,0xe0,0x00,0xe0,0x7f,0x00,0x80,0x1f,0x00,0x00,0x00,0x00 };
+
+ static const uchar forbiddenm_bits[] = {
+ 0x80,0x1f,0x00,0xe0,0x7f,0x00,0xf0,0xff,0x00,0xf8,0xff,0x01,0xfc,0xf0,0x03,
+ 0xfe,0xc0,0x07,0xfe,0x81,0x07,0xff,0x83,0x0f,0xcf,0x07,0x0f,0x8f,0x0f,0x0f,
+ 0x0f,0x1f,0x0f,0x0f,0x3e,0x0f,0x1f,0xfc,0x0f,0x1e,0xf8,0x07,0x3e,0xf0,0x07,
+ 0xfc,0xe0,0x03,0xf8,0xff,0x01,0xf0,0xff,0x00,0xe0,0x7f,0x00,0x80,0x1f,0x00};
+
+ static const uchar openhand_bits[] = {
+ 0x80,0x01,0x58,0x0e,0x64,0x12,0x64,0x52,0x48,0xb2,0x48,0x92,
+ 0x16,0x90,0x19,0x80,0x11,0x40,0x02,0x40,0x04,0x40,0x04,0x20,
+ 0x08,0x20,0x10,0x10,0x20,0x10,0x00,0x00};
+ static const uchar openhandm_bits[] = {
+ 0x80,0x01,0xd8,0x0f,0xfc,0x1f,0xfc,0x5f,0xf8,0xff,0xf8,0xff,
+ 0xf6,0xff,0xff,0xff,0xff,0x7f,0xfe,0x7f,0xfc,0x7f,0xfc,0x3f,
+ 0xf8,0x3f,0xf0,0x1f,0xe0,0x1f,0x00,0x00};
+ static const uchar closedhand_bits[] = {
+ 0x00,0x00,0x00,0x00,0x00,0x00,0xb0,0x0d,0x48,0x32,0x08,0x50,
+ 0x10,0x40,0x18,0x40,0x04,0x40,0x04,0x20,0x08,0x20,0x10,0x10,
+ 0x20,0x10,0x20,0x10,0x00,0x00,0x00,0x00};
+ static const uchar closedhandm_bits[] = {
+ 0x00,0x00,0x00,0x00,0x00,0x00,0xb0,0x0d,0xf8,0x3f,0xf8,0x7f,
+ 0xf0,0x7f,0xf8,0x7f,0xfc,0x7f,0xfc,0x3f,0xf8,0x3f,0xf0,0x1f,
+ 0xe0,0x1f,0xe0,0x1f,0x00,0x00,0x00,0x00};
+
+ static const uchar * const cursor_bits20[] = {
+ forbidden_bits, forbiddenm_bits
+ };
+
+ if ((cshape >= Qt::SizeVerCursor && cshape < Qt::SizeAllCursor)
+ || cshape == Qt::BlankCursor) {
+ XColor bg, fg;
+ bg.red = 255 << 8;
+ bg.green = 255 << 8;
+ bg.blue = 255 << 8;
+ fg.red = 0;
+ fg.green = 0;
+ fg.blue = 0;
+ int i = (cshape - Qt::SizeVerCursor) * 2;
+ pm = XCreateBitmapFromData(dpy, rootwin, reinterpret_cast<const char*>(cursor_bits16[i]), 16, 16);
+ pmm = XCreateBitmapFromData(dpy, rootwin, reinterpret_cast<const char*>(cursor_bits16[i + 1]), 16, 16);
+ hcurs = XCreatePixmapCursor(dpy, pm, pmm, &fg, &bg, 8, 8);
+ } else if ((cshape >= Qt::SplitVCursor && cshape <= Qt::SplitHCursor)
+ || cshape == Qt::WhatsThisCursor || cshape == Qt::BusyCursor) {
+ XColor bg, fg;
+ bg.red = 255 << 8;
+ bg.green = 255 << 8;
+ bg.blue = 255 << 8;
+ fg.red = 0;
+ fg.green = 0;
+ fg.blue = 0;
+ int i = (cshape - Qt::SplitVCursor) * 2;
+ pm = XCreateBitmapFromData(dpy, rootwin, reinterpret_cast<const char *>(cursor_bits32[i]), 32, 32);
+ pmm = XCreateBitmapFromData(dpy, rootwin, reinterpret_cast<const char *>(cursor_bits32[i + 1]), 32, 32);
+ int hs = (cshape == Qt::PointingHandCursor || cshape == Qt::WhatsThisCursor
+ || cshape == Qt::BusyCursor) ? 0 : 16;
+ hcurs = XCreatePixmapCursor(dpy, pm, pmm, &fg, &bg, hs, hs);
+ } else if (cshape == Qt::ForbiddenCursor) {
+ XColor bg, fg;
+ bg.red = 255 << 8;
+ bg.green = 255 << 8;
+ bg.blue = 255 << 8;
+ fg.red = 0;
+ fg.green = 0;
+ fg.blue = 0;
+ int i = (cshape - Qt::ForbiddenCursor) * 2;
+ pm = XCreateBitmapFromData(dpy, rootwin, reinterpret_cast<const char *>(cursor_bits20[i]), 20, 20);
+ pmm = XCreateBitmapFromData(dpy, rootwin, reinterpret_cast<const char *>(cursor_bits20[i + 1]), 20, 20);
+ hcurs = XCreatePixmapCursor(dpy, pm, pmm, &fg, &bg, 10, 10);
+ } else if (cshape == Qt::OpenHandCursor || cshape == Qt::ClosedHandCursor) {
+ XColor bg, fg;
+ bg.red = 255 << 8;
+ bg.green = 255 << 8;
+ bg.blue = 255 << 8;
+ fg.red = 0;
+ fg.green = 0;
+ fg.blue = 0;
+ bool open = cshape == Qt::OpenHandCursor;
+ pm = XCreateBitmapFromData(dpy, rootwin, reinterpret_cast<const char *>(open ? openhand_bits : closedhand_bits), 16, 16);
+ pmm = XCreateBitmapFromData(dpy, rootwin, reinterpret_cast<const char *>(open ? openhandm_bits : closedhandm_bits), 16, 16);
+ hcurs = XCreatePixmapCursor(dpy, pm, pmm, &fg, &bg, 8, 8);
+ } else if (cshape == Qt::DragCopyCursor || cshape == Qt::DragMoveCursor
+ || cshape == Qt::DragLinkCursor) {
+ XColor bg, fg;
+ bg.red = 255 << 8;
+ bg.green = 255 << 8;
+ bg.blue = 255 << 8;
+ fg.red = 0;
+ fg.green = 0;
+ fg.blue = 0;
+ QImage image = QApplicationPrivate::instance()->getPixmapCursor(cshape).toImage();
+ pm = QX11PlatformPixmap::createBitmapFromImage(image);
+ pmm = QX11PlatformPixmap::createBitmapFromImage(image.createAlphaMask().convertToFormat(QImage::Format_MonoLSB));
+ hcurs = XCreatePixmapCursor(dpy, pm, pmm, &fg, &bg, 8, 8);
+ }
+
+ if (hcurs)
+ {
+#ifndef QT_NO_XFIXES
+ if (X11->use_xfixes && X11->ptrXFixesSetCursorName)
+ X11->ptrXFixesSetCursorName(dpy, hcurs, cursorNames[cshape]);
+#endif /* ! QT_NO_XFIXES */
+ return;
+ }
+
+#endif /* ! QT_USE_APPROXIMATE_CURSORS */
+
+ uint sh;
+ switch (cshape) { // map Q cursor to X cursor
+ case Qt::ArrowCursor:
+ sh = XC_left_ptr;
+ break;
+ case Qt::UpArrowCursor:
+ sh = XC_center_ptr;
+ break;
+ case Qt::CrossCursor:
+ sh = XC_crosshair;
+ break;
+ case Qt::WaitCursor:
+ sh = XC_watch;
+ break;
+ case Qt::IBeamCursor:
+ sh = XC_xterm;
+ break;
+ case Qt::SizeAllCursor:
+ sh = XC_fleur;
+ break;
+ case Qt::PointingHandCursor:
+ sh = XC_hand2;
+ break;
+#ifdef QT_USE_APPROXIMATE_CURSORS
+ case Qt::SizeBDiagCursor:
+ sh = XC_top_right_corner;
+ break;
+ case Qt::SizeFDiagCursor:
+ sh = XC_bottom_right_corner;
+ break;
+ case Qt::BlankCursor:
+ XColor bg, fg;
+ bg.red = 255 << 8;
+ bg.green = 255 << 8;
+ bg.blue = 255 << 8;
+ fg.red = 0;
+ fg.green = 0;
+ fg.blue = 0;
+ pm = XCreateBitmapFromData(dpy, rootwin, cur_blank_bits, 16, 16);
+ pmm = XCreateBitmapFromData(dpy, rootwin, cur_blank_bits, 16, 16);
+ hcurs = XCreatePixmapCursor(dpy, pm, pmm, &fg, &bg, 8, 8);
+ return;
+ break;
+ case Qt::SizeVerCursor:
+ case Qt::SplitVCursor:
+ sh = XC_sb_v_double_arrow;
+ break;
+ case Qt::SizeHorCursor:
+ case Qt::SplitHCursor:
+ sh = XC_sb_h_double_arrow;
+ break;
+ case Qt::WhatsThisCursor:
+ sh = XC_question_arrow;
+ break;
+ case Qt::ForbiddenCursor:
+ sh = XC_circle;
+ break;
+ case Qt::BusyCursor:
+ sh = XC_watch;
+ break;
+ case Qt::DragCopyCursor:
+ sh = XC_tcross;
+ break;
+ case Qt::DragLinkCursor:
+ sh = XC_center_ptr;
+ break;
+ case Qt::DragMoveCursor:
+ sh = XC_top_left_arrow;
+ break;
+#endif /* QT_USE_APPROXIMATE_CURSORS */
+ default:
+ qWarning("QCursor::update: Invalid cursor shape %d", cshape);
+ return;
+ }
+ hcurs = XCreateFontCursor(dpy, sh);
+
+#ifndef QT_NO_XFIXES
+ if (X11->use_xfixes && X11->ptrXFixesSetCursorName)
+ X11->ptrXFixesSetCursorName(dpy, hcurs, cursorNames[cshape]);
+#endif /* ! QT_NO_XFIXES */
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/kernel/qdesktopwidget_x11.cpp b/src/widgets/platforms/x11/qdesktopwidget_x11.cpp
index 52d3be18e9..52d3be18e9 100644
--- a/src/gui/kernel/qdesktopwidget_x11.cpp
+++ b/src/widgets/platforms/x11/qdesktopwidget_x11.cpp
diff --git a/src/widgets/platforms/x11/qdnd_x11.cpp b/src/widgets/platforms/x11/qdnd_x11.cpp
new file mode 100644
index 0000000000..2718853920
--- /dev/null
+++ b/src/widgets/platforms/x11/qdnd_x11.cpp
@@ -0,0 +1,2072 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qplatformdefs.h"
+
+#include "qapplication.h"
+
+#ifndef QT_NO_DRAGANDDROP
+
+#include "qwidget.h"
+#include "qpainter.h"
+#include "qpixmap.h"
+#include "qbitmap.h"
+#include "qdesktopwidget.h"
+#include "qevent.h"
+#include "qiodevice.h"
+#include "qpointer.h"
+#include "qcursor.h"
+#include "qelapsedtimer.h"
+#include "qvariant.h"
+#include "qvector.h"
+#include "qurl.h"
+#include "qdebug.h"
+#include "qimagewriter.h"
+#include "qbuffer.h"
+#include "qtextcodec.h"
+
+#include "qdnd_p.h"
+#include "qapplication_p.h"
+#include "qt_x11_p.h"
+#include "qx11info_x11.h"
+
+#include "qwidget_p.h"
+#include "qcursor_p.h"
+
+QT_BEGIN_NAMESPACE
+
+// #define DND_DEBUG
+#ifdef DND_DEBUG
+#define DEBUG qDebug
+#else
+#define DEBUG if(0) qDebug
+#endif
+
+#ifdef DND_DEBUG
+#define DNDDEBUG qDebug()
+#else
+#define DNDDEBUG if(0) qDebug()
+#endif
+
+static int findXdndDropTransactionByWindow(Window window)
+{
+ int at = -1;
+ for (int i = 0; i < X11->dndDropTransactions.count(); ++i) {
+ const QXdndDropTransaction &t = X11->dndDropTransactions.at(i);
+ if (t.target == window || t.proxy_target == window) {
+ at = i;
+ break;
+ }
+ }
+ return at;
+}
+
+static int findXdndDropTransactionByTime(Time timestamp)
+{
+ int at = -1;
+ for (int i = 0; i < X11->dndDropTransactions.count(); ++i) {
+ const QXdndDropTransaction &t = X11->dndDropTransactions.at(i);
+ if (t.timestamp == timestamp) {
+ at = i;
+ break;
+ }
+ }
+ return at;
+}
+
+// timer used to discard old XdndDrop transactions
+static int transaction_expiry_timer = -1;
+enum { XdndDropTransactionTimeout = 5000 }; // 5 seconds
+
+static void restartXdndDropExpiryTimer()
+{
+ if (transaction_expiry_timer != -1)
+ QDragManager::self()->killTimer(transaction_expiry_timer);
+ transaction_expiry_timer = QDragManager::self()->startTimer(XdndDropTransactionTimeout);
+}
+
+
+// find an ancestor with XdndAware on it
+static Window findXdndAwareParent(Window window)
+{
+ Window target = 0;
+ forever {
+ // check if window has XdndAware
+ Atom type = 0;
+ int f;
+ unsigned long n, a;
+ unsigned char *data = 0;
+ if (XGetWindowProperty(X11->display, window, ATOM(XdndAware), 0, 0, False,
+ AnyPropertyType, &type, &f,&n,&a,&data) == Success) {
+ if (data)
+ XFree(data);
+ if (type) {
+ target = window;
+ break;
+ }
+ }
+
+ // try window's parent
+ Window root;
+ Window parent;
+ Window *children;
+ uint unused;
+ if (!XQueryTree(X11->display, window, &root, &parent, &children, &unused))
+ break;
+ if (children)
+ XFree(children);
+ if (window == root)
+ break;
+ window = parent;
+ }
+ return target;
+}
+
+
+
+
+// and all this stuff is copied -into- qapp_x11.cpp
+
+static void handle_xdnd_position(QWidget *, const XEvent *, bool);
+static void handle_xdnd_status(QWidget * w, const XEvent * xe, bool /*passive*/);
+
+const int xdnd_version = 5;
+
+static Qt::DropAction xdndaction_to_qtaction(Atom atom)
+{
+ if (atom == ATOM(XdndActionCopy) || atom == 0)
+ return Qt::CopyAction;
+ if (atom == ATOM(XdndActionLink))
+ return Qt::LinkAction;
+ if (atom == ATOM(XdndActionMove))
+ return Qt::MoveAction;
+ return Qt::CopyAction;
+}
+
+static int qtaction_to_xdndaction(Qt::DropAction a)
+{
+ switch (a) {
+ case Qt::CopyAction:
+ return ATOM(XdndActionCopy);
+ case Qt::LinkAction:
+ return ATOM(XdndActionLink);
+ case Qt::MoveAction:
+ case Qt::TargetMoveAction:
+ return ATOM(XdndActionMove);
+ case Qt::IgnoreAction:
+ return XNone;
+ default:
+ return ATOM(XdndActionCopy);
+ }
+}
+
+// clean up the stuff used.
+static void qt_xdnd_cleanup();
+
+static void qt_xdnd_send_leave();
+
+// real variables:
+// xid of current drag source
+static Atom qt_xdnd_dragsource_xid = 0;
+
+// the types in this drop. 100 is no good, but at least it's big.
+const int qt_xdnd_max_type = 100;
+static Atom qt_xdnd_types[qt_xdnd_max_type + 1];
+
+// timer used when target wants "continuous" move messages (eg. scroll)
+static int heartbeat = -1;
+// rectangle in which the answer will be the same
+static QRect qt_xdnd_source_sameanswer;
+// top-level window we sent position to last.
+static Window qt_xdnd_current_target;
+// window to send events to (always valid if qt_xdnd_current_target)
+static Window qt_xdnd_current_proxy_target;
+static Time qt_xdnd_source_current_time;
+
+// widget we forwarded position to last, and local position
+static QPointer<QWidget> qt_xdnd_current_widget;
+static QPoint qt_xdnd_current_position;
+// timestamp from the XdndPosition and XdndDrop
+static Time qt_xdnd_target_current_time;
+// screen number containing the pointer... -1 means default
+static int qt_xdnd_current_screen = -1;
+// state of dragging... true if dragging, false if not
+bool qt_xdnd_dragging = false;
+
+static bool waiting_for_status = false;
+
+// used to preset each new QDragMoveEvent
+static Qt::DropAction last_target_accepted_action = Qt::IgnoreAction;
+
+// Shift/Ctrl handling, and final drop status
+static Qt::DropAction global_accepted_action = Qt::CopyAction;
+static Qt::DropActions possible_actions = Qt::IgnoreAction;
+
+// for embedding only
+static QWidget* current_embedding_widget = 0;
+static XEvent last_enter_event;
+
+// cursors
+static QCursor *noDropCursor = 0;
+static QCursor *moveCursor = 0;
+static QCursor *copyCursor = 0;
+static QCursor *linkCursor = 0;
+
+static QPixmap *defaultPm = 0;
+
+static const int default_pm_hotx = -2;
+static const int default_pm_hoty = -16;
+static const char* const default_pm[] = {
+"13 9 3 1",
+". c None",
+" c #000000",
+"X c #FFFFFF",
+"X X X X X X X",
+" X X X X X X ",
+"X ......... X",
+" X.........X ",
+"X ......... X",
+" X.........X ",
+"X ......... X",
+" X X X X X X ",
+"X X X X X X X"
+};
+
+class QShapedPixmapWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ QShapedPixmapWidget(QWidget* w) :
+ QWidget(w,
+ Qt::Tool | Qt::FramelessWindowHint
+ | Qt::X11BypassWindowManagerHint
+ | Qt::BypassGraphicsProxyWidget)
+ {
+ setAttribute(Qt::WA_X11NetWmWindowTypeDND);
+ }
+
+ void setPixmap(const QPixmap &pm)
+ {
+ QBitmap mask = pm.mask();
+ if (!mask.isNull()) {
+ setMask(mask);
+ } else {
+ clearMask();
+ }
+ resize(pm.width(),pm.height());
+ pixmap = pm;
+ update();
+ }
+ QPoint pm_hot;
+
+protected:
+ QPixmap pixmap;
+ void paintEvent(QPaintEvent*)
+ {
+ QPainter p(this);
+ p.drawPixmap(0, 0, pixmap);
+ }
+};
+
+#include "qdnd_x11.moc"
+
+struct XdndData {
+ QShapedPixmapWidget *deco;
+ QWidget* desktop_proxy;
+};
+
+static XdndData xdnd_data = { 0, 0 };
+
+class QExtraWidget : public QWidget
+{
+ Q_DECLARE_PRIVATE(QWidget)
+public:
+ inline QWExtra* extraData();
+ inline QTLWExtra* topData();
+};
+
+inline QWExtra* QExtraWidget::extraData() { return d_func()->extraData(); }
+inline QTLWExtra* QExtraWidget::topData() { return d_func()->topData(); }
+
+
+static WId xdndProxy(WId w)
+{
+ Atom type = XNone;
+ int f;
+ unsigned long n, a;
+ unsigned char *retval = 0;
+ XGetWindowProperty(X11->display, w, ATOM(XdndProxy), 0, 1, False,
+ XA_WINDOW, &type, &f,&n,&a,&retval);
+ WId *proxy_id_ptr = (WId *)retval;
+ WId proxy_id = 0;
+ if (type == XA_WINDOW && proxy_id_ptr) {
+ proxy_id = *proxy_id_ptr;
+ XFree(proxy_id_ptr);
+ proxy_id_ptr = 0;
+ // Already exists. Real?
+ X11->ignoreBadwindow();
+ XGetWindowProperty(X11->display, proxy_id, ATOM(XdndProxy), 0, 1, False,
+ XA_WINDOW, &type, &f,&n,&a,&retval);
+ proxy_id_ptr = (WId *)retval;
+ if (X11->badwindow() || type != XA_WINDOW || !proxy_id_ptr || *proxy_id_ptr != proxy_id)
+ // Bogus - we will overwrite.
+ proxy_id = 0;
+ }
+ if (proxy_id_ptr)
+ XFree(proxy_id_ptr);
+ return proxy_id;
+}
+
+static bool xdndEnable(QWidget* w, bool on)
+{
+ DNDDEBUG << "xdndEnable" << w << on;
+ if (on) {
+ QWidget * xdnd_widget = 0;
+ if ((w->windowType() == Qt::Desktop)) {
+ if (xdnd_data.desktop_proxy) // *WE* already have one.
+ return false;
+
+ // As per Xdnd4, use XdndProxy
+ XGrabServer(X11->display);
+ Q_ASSERT(w->testAttribute(Qt::WA_WState_Created));
+ WId proxy_id = xdndProxy(w->effectiveWinId());
+
+ if (!proxy_id) {
+ xdnd_widget = xdnd_data.desktop_proxy = new QWidget;
+ proxy_id = xdnd_data.desktop_proxy->effectiveWinId();
+ XChangeProperty (X11->display, w->effectiveWinId(), ATOM(XdndProxy),
+ XA_WINDOW, 32, PropModeReplace, (unsigned char *)&proxy_id, 1);
+ XChangeProperty (X11->display, proxy_id, ATOM(XdndProxy),
+ XA_WINDOW, 32, PropModeReplace, (unsigned char *)&proxy_id, 1);
+ }
+
+ XUngrabServer(X11->display);
+ } else {
+ xdnd_widget = w->window();
+ }
+ if (xdnd_widget) {
+ DNDDEBUG << "setting XdndAware for" << xdnd_widget << xdnd_widget->effectiveWinId();
+ Atom atm = (Atom)xdnd_version;
+ Q_ASSERT(xdnd_widget->testAttribute(Qt::WA_WState_Created));
+ XChangeProperty(X11->display, xdnd_widget->effectiveWinId(), ATOM(XdndAware),
+ XA_ATOM, 32, PropModeReplace, (unsigned char *)&atm, 1);
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ if ((w->windowType() == Qt::Desktop)) {
+ XDeleteProperty(X11->display, w->internalWinId(), ATOM(XdndProxy));
+ delete xdnd_data.desktop_proxy;
+ xdnd_data.desktop_proxy = 0;
+ } else {
+ DNDDEBUG << "not deleting XDndAware";
+ }
+ return true;
+ }
+}
+
+QByteArray QX11Data::xdndAtomToString(Atom a)
+{
+ if (!a) return 0;
+
+ if (a == XA_STRING || a == ATOM(UTF8_STRING)) {
+ return "text/plain"; // some Xdnd clients are dumb
+ }
+ char *atom = XGetAtomName(display, a);
+ QByteArray result = atom;
+ XFree(atom);
+ return result;
+}
+
+Atom QX11Data::xdndStringToAtom(const char *mimeType)
+{
+ if (!mimeType || !*mimeType)
+ return 0;
+ return XInternAtom(display, mimeType, False);
+}
+
+//$$$
+QString QX11Data::xdndMimeAtomToString(Atom a)
+{
+ QString atomName;
+ if (a) {
+ char *atom = XGetAtomName(display, a);
+ atomName = QString::fromLatin1(atom);
+ XFree(atom);
+ }
+ return atomName;
+}
+
+//$$$
+Atom QX11Data::xdndMimeStringToAtom(const QString &mimeType)
+{
+ if (mimeType.isEmpty())
+ return 0;
+ return XInternAtom(display, mimeType.toLatin1().constData(), False);
+}
+
+//$$$ replace ccxdndAtomToString()
+QStringList QX11Data::xdndMimeFormatsForAtom(Atom a)
+{
+ QStringList formats;
+ if (a) {
+ QString atomName = xdndMimeAtomToString(a);
+ formats.append(atomName);
+
+ // special cases for string type
+ if (a == ATOM(UTF8_STRING) || a == XA_STRING
+ || a == ATOM(TEXT) || a == ATOM(COMPOUND_TEXT))
+ formats.append(QLatin1String("text/plain"));
+
+ // special cases for uris
+ if (atomName == QLatin1String("text/x-moz-url"))
+ formats.append(QLatin1String("text/uri-list"));
+
+ // special case for images
+ if (a == XA_PIXMAP)
+ formats.append(QLatin1String("image/ppm"));
+ }
+ return formats;
+}
+
+//$$$
+bool QX11Data::xdndMimeDataForAtom(Atom a, QMimeData *mimeData, QByteArray *data, Atom *atomFormat, int *dataFormat)
+{
+ bool ret = false;
+ *atomFormat = a;
+ *dataFormat = 8;
+ QString atomName = xdndMimeAtomToString(a);
+ if (QInternalMimeData::hasFormatHelper(atomName, mimeData)) {
+ *data = QInternalMimeData::renderDataHelper(atomName, mimeData);
+ if (atomName == QLatin1String("application/x-color"))
+ *dataFormat = 16;
+ ret = true;
+ } else {
+ if ((a == ATOM(UTF8_STRING) || a == XA_STRING
+ || a == ATOM(TEXT) || a == ATOM(COMPOUND_TEXT))
+ && QInternalMimeData::hasFormatHelper(QLatin1String("text/plain"), mimeData)) {
+ if (a == ATOM(UTF8_STRING)){
+ *data = QInternalMimeData::renderDataHelper(QLatin1String("text/plain"), mimeData);
+ ret = true;
+ } else if (a == XA_STRING) {
+ *data = QString::fromUtf8(QInternalMimeData::renderDataHelper(
+ QLatin1String("text/plain"), mimeData)).toLocal8Bit();
+ ret = true;
+ } else if (a == ATOM(TEXT) || a == ATOM(COMPOUND_TEXT)) {
+ // the ICCCM states that TEXT and COMPOUND_TEXT are in the
+ // encoding of choice, so we choose the encoding of the locale
+ QByteArray strData = QString::fromUtf8(QInternalMimeData::renderDataHelper(
+ QLatin1String("text/plain"), mimeData)).toLocal8Bit();
+ char *list[] = { strData.data(), NULL };
+
+ XICCEncodingStyle style = (a == ATOM(COMPOUND_TEXT))
+ ? XCompoundTextStyle : XStdICCTextStyle;
+ XTextProperty textprop;
+ if (list[0] != NULL
+ && XmbTextListToTextProperty(X11->display, list, 1, style,
+ &textprop) == Success) {
+ *atomFormat = textprop.encoding;
+ *dataFormat = textprop.format;
+ *data = QByteArray((const char *) textprop.value, textprop.nitems * textprop.format / 8);
+ ret = true;
+
+ DEBUG(" textprop type %lx\n"
+ " textprop name '%s'\n"
+ " format %d\n"
+ " %ld items\n"
+ " %d bytes\n",
+ textprop.encoding,
+ X11->xdndMimeAtomToString(textprop.encoding).toLatin1().data(),
+ textprop.format, textprop.nitems, data->size());
+
+ XFree(textprop.value);
+ }
+ }
+ } else if (atomName == QLatin1String("text/x-moz-url") &&
+ QInternalMimeData::hasFormatHelper(QLatin1String("text/uri-list"), mimeData)) {
+ QByteArray uri = QInternalMimeData::renderDataHelper(
+ QLatin1String("text/uri-list"), mimeData).split('\n').first();
+ QString mozUri = QString::fromLatin1(uri, uri.size());
+ mozUri += QLatin1Char('\n');
+ *data = QByteArray(reinterpret_cast<const char *>(mozUri.utf16()), mozUri.length() * 2);
+ ret = true;
+ } else if ((a == XA_PIXMAP || a == XA_BITMAP) && mimeData->hasImage()) {
+ QPixmap pm = qvariant_cast<QPixmap>(mimeData->imageData());
+ if (a == XA_BITMAP && pm.depth() != 1) {
+ QImage img = pm.toImage();
+ img = img.convertToFormat(QImage::Format_MonoLSB);
+ pm = QPixmap::fromImage(img);
+ }
+ QDragManager *dm = QDragManager::self();
+ if (dm) {
+ Pixmap handle = pm.handle();
+ *data = QByteArray((const char *) &handle, sizeof(Pixmap));
+ dm->xdndMimeTransferedPixmap[dm->xdndMimeTransferedPixmapIndex] = pm;
+ dm->xdndMimeTransferedPixmapIndex =
+ (dm->xdndMimeTransferedPixmapIndex + 1) % 2;
+ ret = true;
+ }
+ } else {
+ DEBUG("QClipboard: xdndMimeDataForAtom(): converting to type '%s' is not supported", qPrintable(atomName));
+ }
+ }
+ return ret && data != 0;
+}
+
+//$$$
+QList<Atom> QX11Data::xdndMimeAtomsForFormat(const QString &format)
+{
+ QList<Atom> atoms;
+ atoms.append(xdndMimeStringToAtom(format));
+
+ // special cases for strings
+ if (format == QLatin1String("text/plain")) {
+ atoms.append(ATOM(UTF8_STRING));
+ atoms.append(XA_STRING);
+ atoms.append(ATOM(TEXT));
+ atoms.append(ATOM(COMPOUND_TEXT));
+ }
+
+ // special cases for uris
+ if (format == QLatin1String("text/uri-list")) {
+ atoms.append(xdndMimeStringToAtom(QLatin1String("text/x-moz-url")));
+ }
+
+ //special cases for images
+ if (format == QLatin1String("image/ppm"))
+ atoms.append(XA_PIXMAP);
+ if (format == QLatin1String("image/pbm"))
+ atoms.append(XA_BITMAP);
+
+ return atoms;
+}
+
+//$$$
+QVariant QX11Data::xdndMimeConvertToFormat(Atom a, const QByteArray &data, const QString &format, QVariant::Type requestedType, const QByteArray &encoding)
+{
+ QString atomName = xdndMimeAtomToString(a);
+ if (atomName == format)
+ return data;
+
+ if (!encoding.isEmpty()
+ && atomName == format + QLatin1String(";charset=") + QString::fromLatin1(encoding)) {
+
+ if (requestedType == QVariant::String) {
+ QTextCodec *codec = QTextCodec::codecForName(encoding);
+ if (codec)
+ return codec->toUnicode(data);
+ }
+
+ return data;
+ }
+
+ // special cases for string types
+ if (format == QLatin1String("text/plain")) {
+ if (a == ATOM(UTF8_STRING))
+ return QString::fromUtf8(data);
+ if (a == XA_STRING)
+ return QString::fromLatin1(data);
+ if (a == ATOM(TEXT) || a == ATOM(COMPOUND_TEXT))
+ // #### might be wrong for COMPUND_TEXT
+ return QString::fromLocal8Bit(data, data.size());
+ }
+
+ // special case for uri types
+ if (format == QLatin1String("text/uri-list")) {
+ if (atomName == QLatin1String("text/x-moz-url")) {
+ // we expect this as utf16 <url><space><title>
+ // the first part is a url that should only contain ascci char
+ // so it should be safe to check that the second char is 0
+ // to verify that it is utf16
+ if (data.size() > 1 && data.at(1) == 0)
+ return QString::fromRawData((const QChar *)data.constData(),
+ data.size() / 2).split(QLatin1Char('\n')).first().toLatin1();
+ }
+ }
+
+ // special cas for images
+ if (format == QLatin1String("image/ppm")) {
+ if (a == XA_PIXMAP && data.size() == sizeof(Pixmap)) {
+ Pixmap xpm = *((Pixmap*)data.data());
+ if (!xpm)
+ return QByteArray();
+ QPixmap qpm = QPixmap::fromX11Pixmap(xpm);
+ QImageWriter imageWriter;
+ imageWriter.setFormat("PPMRAW");
+ QImage imageToWrite = qpm.toImage();
+ QBuffer buf;
+ buf.open(QIODevice::WriteOnly);
+ imageWriter.setDevice(&buf);
+ imageWriter.write(imageToWrite);
+ return buf.buffer();
+ }
+ }
+ return QVariant();
+}
+
+//$$$ middle of xdndObtainData
+Atom QX11Data::xdndMimeAtomForFormat(const QString &format, QVariant::Type requestedType, const QList<Atom> &atoms, QByteArray *encoding)
+{
+ encoding->clear();
+
+ // find matches for string types
+ if (format == QLatin1String("text/plain")) {
+ if (atoms.contains(ATOM(UTF8_STRING)))
+ return ATOM(UTF8_STRING);
+ if (atoms.contains(ATOM(COMPOUND_TEXT)))
+ return ATOM(COMPOUND_TEXT);
+ if (atoms.contains(ATOM(TEXT)))
+ return ATOM(TEXT);
+ if (atoms.contains(XA_STRING))
+ return XA_STRING;
+ }
+
+ // find matches for uri types
+ if (format == QLatin1String("text/uri-list")) {
+ Atom a = xdndMimeStringToAtom(format);
+ if (a && atoms.contains(a))
+ return a;
+ a = xdndMimeStringToAtom(QLatin1String("text/x-moz-url"));
+ if (a && atoms.contains(a))
+ return a;
+ }
+
+ // find match for image
+ if (format == QLatin1String("image/ppm")) {
+ if (atoms.contains(XA_PIXMAP))
+ return XA_PIXMAP;
+ }
+
+ // for string/text requests try to use a format with a well-defined charset
+ // first to avoid encoding problems
+ if (requestedType == QVariant::String
+ && format.startsWith(QLatin1String("text/"))
+ && !format.contains(QLatin1String("charset="))) {
+
+ QString formatWithCharset = format;
+ formatWithCharset.append(QLatin1String(";charset=utf-8"));
+
+ Atom a = xdndMimeStringToAtom(formatWithCharset);
+ if (a && atoms.contains(a)) {
+ *encoding = "utf-8";
+ return a;
+ }
+ }
+
+ Atom a = xdndMimeStringToAtom(format);
+ if (a && atoms.contains(a))
+ return a;
+
+ return 0;
+}
+
+void QX11Data::xdndSetup() {
+ QCursorData::initialize();
+ qAddPostRoutine(qt_xdnd_cleanup);
+}
+
+
+void qt_xdnd_cleanup()
+{
+ delete noDropCursor;
+ noDropCursor = 0;
+ delete copyCursor;
+ copyCursor = 0;
+ delete moveCursor;
+ moveCursor = 0;
+ delete linkCursor;
+ linkCursor = 0;
+ delete defaultPm;
+ defaultPm = 0;
+ delete xdnd_data.desktop_proxy;
+ xdnd_data.desktop_proxy = 0;
+ delete xdnd_data.deco;
+ xdnd_data.deco = 0;
+}
+
+
+static QWidget *find_child(QWidget *tlw, QPoint & p)
+{
+ QWidget *widget = tlw;
+
+ p = widget->mapFromGlobal(p);
+ bool done = false;
+ while (!done) {
+ done = true;
+ if (((QExtraWidget*)widget)->extraData() &&
+ ((QExtraWidget*)widget)->extraData()->xDndProxy != 0)
+ break; // stop searching for widgets under the mouse cursor if found widget is a proxy.
+ QObjectList children = widget->children();
+ if (!children.isEmpty()) {
+ for(int i = children.size(); i > 0;) {
+ --i;
+ QWidget *w = qobject_cast<QWidget *>(children.at(i));
+ if (!w)
+ continue;
+ if (w->testAttribute(Qt::WA_TransparentForMouseEvents))
+ continue;
+ if (w->isVisible() &&
+ w->geometry().contains(p) &&
+ !w->isWindow()) {
+ widget = w;
+ done = false;
+ p = widget->mapFromParent(p);
+ break;
+ }
+ }
+ }
+ }
+ return widget;
+}
+
+
+static bool checkEmbedded(QWidget* w, const XEvent* xe)
+{
+ if (!w)
+ return false;
+
+ if (current_embedding_widget != 0 && current_embedding_widget != w) {
+ qt_xdnd_current_target = ((QExtraWidget*)current_embedding_widget)->extraData()->xDndProxy;
+ qt_xdnd_current_proxy_target = qt_xdnd_current_target;
+ qt_xdnd_send_leave();
+ qt_xdnd_current_target = 0;
+ qt_xdnd_current_proxy_target = 0;
+ current_embedding_widget = 0;
+ }
+
+ QWExtra* extra = ((QExtraWidget*)w)->extraData();
+ if (extra && extra->xDndProxy != 0) {
+
+ if (current_embedding_widget != w) {
+
+ last_enter_event.xany.window = extra->xDndProxy;
+ XSendEvent(X11->display, extra->xDndProxy, False, NoEventMask, &last_enter_event);
+ current_embedding_widget = w;
+ }
+
+ ((XEvent*)xe)->xany.window = extra->xDndProxy;
+ XSendEvent(X11->display, extra->xDndProxy, False, NoEventMask, (XEvent*)xe);
+ if (qt_xdnd_current_widget != w) {
+ qt_xdnd_current_widget = w;
+ }
+ return true;
+ }
+ current_embedding_widget = 0;
+ return false;
+}
+
+void QX11Data::xdndHandleEnter(QWidget *, const XEvent * xe, bool /*passive*/)
+{
+ motifdnd_active = false;
+
+ last_enter_event.xclient = xe->xclient;
+
+ const long *l = xe->xclient.data.l;
+ int version = (int)(((unsigned long)(l[1])) >> 24);
+
+ if (version > xdnd_version)
+ return;
+
+ qt_xdnd_dragsource_xid = l[0];
+
+ int j = 0;
+ if (l[1] & 1) {
+ // get the types from XdndTypeList
+ Atom type = XNone;
+ int f;
+ unsigned long n, a;
+ unsigned char *retval = 0;
+ XGetWindowProperty(X11->display, qt_xdnd_dragsource_xid, ATOM(XdndTypelist), 0,
+ qt_xdnd_max_type, False, XA_ATOM, &type, &f,&n,&a,&retval);
+ if (retval) {
+ Atom *data = (Atom *)retval;
+ for (; j<qt_xdnd_max_type && j < (int)n; j++) {
+ qt_xdnd_types[j] = data[j];
+ }
+ XFree((uchar*)data);
+ }
+ } else {
+ // get the types from the message
+ int i;
+ for(i=2; i < 5; i++) {
+ qt_xdnd_types[j++] = l[i];
+ }
+ }
+ qt_xdnd_types[j] = 0;
+}
+
+static void handle_xdnd_position(QWidget *w, const XEvent * xe, bool passive)
+{
+ const unsigned long *l = (const unsigned long *)xe->xclient.data.l;
+
+ QPoint p((l[2] & 0xffff0000) >> 16, l[2] & 0x0000ffff);
+ QWidget * c = find_child(w, p); // changes p to to c-local coordinates
+
+ if (!passive && checkEmbedded(c, xe))
+ return;
+
+ if (!c || (!c->acceptDrops() && (c->windowType() == Qt::Desktop)))
+ return;
+
+ if (l[0] != qt_xdnd_dragsource_xid) {
+ DEBUG("xdnd drag position from unexpected source (%08lx not %08lx)", l[0], qt_xdnd_dragsource_xid);
+ return;
+ }
+
+ // timestamp from the source
+ if (l[3] != 0) {
+ // Some X server/client combination swallow the first 32 bit and
+ // interpret a set bit 31 as negative sign.
+ qt_xdnd_target_current_time = X11->userTime =
+ ((sizeof(Time) == 8 && xe->xclient.data.l[3] < 0)
+ ? uint(l[3])
+ : l[3]);
+ }
+
+ QDragManager *manager = QDragManager::self();
+ QMimeData *dropData = manager->object ? manager->dragPrivate()->data : manager->dropData;
+
+ XClientMessageEvent response;
+ response.type = ClientMessage;
+ response.window = qt_xdnd_dragsource_xid;
+ response.format = 32;
+ response.message_type = ATOM(XdndStatus);
+ response.data.l[0] = w->effectiveWinId();
+ response.data.l[1] = 0; // flags
+ response.data.l[2] = 0; // x, y
+ response.data.l[3] = 0; // w, h
+ response.data.l[4] = 0; // action
+
+ if (!passive) { // otherwise just reject
+ while (c && !c->acceptDrops() && !c->isWindow()) {
+ p = c->mapToParent(p);
+ c = c->parentWidget();
+ }
+ QWidget *target_widget = c && c->acceptDrops() ? c : 0;
+
+ QRect answerRect(c->mapToGlobal(p), QSize(1,1));
+
+ if (manager->object) {
+ possible_actions = manager->dragPrivate()->possible_actions;
+ } else {
+ possible_actions = Qt::DropActions(xdndaction_to_qtaction(l[4]));
+// possible_actions |= Qt::CopyAction;
+ }
+ QDragMoveEvent me(p, possible_actions, dropData, QApplication::mouseButtons(), QApplication::keyboardModifiers());
+
+ Qt::DropAction accepted_action = Qt::IgnoreAction;
+
+
+ if (target_widget != qt_xdnd_current_widget) {
+ if (qt_xdnd_current_widget) {
+ QDragLeaveEvent e;
+ QApplication::sendEvent(qt_xdnd_current_widget, &e);
+ }
+ if (qt_xdnd_current_widget != target_widget) {
+ qt_xdnd_current_widget = target_widget;
+ }
+ if (target_widget) {
+ qt_xdnd_current_position = p;
+
+ last_target_accepted_action = Qt::IgnoreAction;
+ QDragEnterEvent de(p, possible_actions, dropData, QApplication::mouseButtons(), QApplication::keyboardModifiers());
+ QApplication::sendEvent(target_widget, &de);
+ if (de.isAccepted() && de.dropAction() != Qt::IgnoreAction)
+ last_target_accepted_action = de.dropAction();
+ }
+ }
+
+ DEBUG() << "qt_handle_xdnd_position action=" << X11->xdndAtomToString(l[4]);
+ if (!target_widget) {
+ answerRect = QRect(p, QSize(1, 1));
+ } else {
+ qt_xdnd_current_widget = c;
+ qt_xdnd_current_position = p;
+
+ if (last_target_accepted_action != Qt::IgnoreAction) {
+ me.setDropAction(last_target_accepted_action);
+ me.accept();
+ }
+ QApplication::sendEvent(c, &me);
+ if (me.isAccepted()) {
+ response.data.l[1] = 1; // yes
+ accepted_action = me.dropAction();
+ last_target_accepted_action = accepted_action;
+ } else {
+ response.data.l[0] = 0;
+ last_target_accepted_action = Qt::IgnoreAction;
+ }
+ answerRect = me.answerRect().intersected(c->rect());
+ }
+ answerRect = QRect(c->mapToGlobal(answerRect.topLeft()), answerRect.size());
+
+ if (answerRect.left() < 0)
+ answerRect.setLeft(0);
+ if (answerRect.right() > 4096)
+ answerRect.setRight(4096);
+ if (answerRect.top() < 0)
+ answerRect.setTop(0);
+ if (answerRect.bottom() > 4096)
+ answerRect.setBottom(4096);
+ if (answerRect.width() < 0)
+ answerRect.setWidth(0);
+ if (answerRect.height() < 0)
+ answerRect.setHeight(0);
+
+ response.data.l[2] = (answerRect.x() << 16) + answerRect.y();
+ response.data.l[3] = (answerRect.width() << 16) + answerRect.height();
+ response.data.l[4] = qtaction_to_xdndaction(accepted_action);
+ }
+
+ // reset
+ qt_xdnd_target_current_time = CurrentTime;
+
+ QWidget * source = QWidget::find(qt_xdnd_dragsource_xid);
+ if (source && (source->windowType() == Qt::Desktop) && !source->acceptDrops())
+ source = 0;
+
+ DEBUG() << "sending XdndStatus";
+ if (source)
+ handle_xdnd_status(source, (const XEvent *)&response, passive);
+ else
+ XSendEvent(X11->display, qt_xdnd_dragsource_xid, False, NoEventMask, (XEvent*)&response);
+}
+
+static Bool xdnd_position_scanner(Display *, XEvent *event, XPointer)
+{
+ if (event->type != ClientMessage)
+ return false;
+ XClientMessageEvent *ev = &event->xclient;
+
+ if (ev->message_type == ATOM(XdndPosition))
+ return true;
+
+ return false;
+}
+
+void QX11Data::xdndHandlePosition(QWidget * w, const XEvent * xe, bool passive)
+{
+ DEBUG("xdndHandlePosition");
+ while (XCheckIfEvent(X11->display, (XEvent *)xe, xdnd_position_scanner, 0))
+ ;
+
+ handle_xdnd_position(w, xe, passive);
+}
+
+
+static void handle_xdnd_status(QWidget *, const XEvent * xe, bool)
+{
+ const unsigned long *l = (const unsigned long *)xe->xclient.data.l;
+ // ignore late status messages
+ if (l[0] && l[0] != qt_xdnd_current_proxy_target)
+ return;
+ Qt::DropAction newAction = (l[1] & 0x1) ? xdndaction_to_qtaction(l[4]) : Qt::IgnoreAction;
+
+ if ((int)(l[1] & 2) == 0) {
+ QPoint p((l[2] & 0xffff0000) >> 16, l[2] & 0x0000ffff);
+ QSize s((l[3] & 0xffff0000) >> 16, l[3] & 0x0000ffff);
+ qt_xdnd_source_sameanswer = QRect(p, s);
+ } else {
+ qt_xdnd_source_sameanswer = QRect();
+ }
+ QDragManager *manager = QDragManager::self();
+ manager->willDrop = (l[1] & 0x1);
+ if (global_accepted_action != newAction)
+ manager->emitActionChanged(newAction);
+ global_accepted_action = newAction;
+ manager->updateCursor();
+ waiting_for_status = false;
+}
+
+static Bool xdnd_status_scanner(Display *, XEvent *event, XPointer)
+{
+ if (event->type != ClientMessage)
+ return false;
+ XClientMessageEvent *ev = &event->xclient;
+
+ if (ev->message_type == ATOM(XdndStatus))
+ return true;
+
+ return false;
+}
+
+void QX11Data::xdndHandleStatus(QWidget * w, const XEvent * xe, bool passive)
+{
+ DEBUG("xdndHandleStatus");
+ while (XCheckIfEvent(X11->display, (XEvent *)xe, xdnd_status_scanner, 0))
+ ;
+
+ handle_xdnd_status(w, xe, passive);
+ DEBUG("xdndHandleStatus end");
+}
+
+void QX11Data::xdndHandleLeave(QWidget *w, const XEvent * xe, bool /*passive*/)
+{
+ DEBUG("xdnd leave");
+ if (!qt_xdnd_current_widget ||
+ w->window() != qt_xdnd_current_widget->window()) {
+ return; // sanity
+ }
+
+ if (checkEmbedded(current_embedding_widget, xe)) {
+ current_embedding_widget = 0;
+ qt_xdnd_current_widget = 0;
+ return;
+ }
+
+ const unsigned long *l = (const unsigned long *)xe->xclient.data.l;
+
+ QDragLeaveEvent e;
+ QApplication::sendEvent(qt_xdnd_current_widget, &e);
+
+ if (l[0] != qt_xdnd_dragsource_xid) {
+ // This often happens - leave other-process window quickly
+ DEBUG("xdnd drag leave from unexpected source (%08lx not %08lx", l[0], qt_xdnd_dragsource_xid);
+ qt_xdnd_current_widget = 0;
+ return;
+ }
+
+ qt_xdnd_dragsource_xid = 0;
+ qt_xdnd_types[0] = 0;
+ qt_xdnd_current_widget = 0;
+}
+
+
+void qt_xdnd_send_leave()
+{
+ if (!qt_xdnd_current_target)
+ return;
+
+ QDragManager *manager = QDragManager::self();
+
+ XClientMessageEvent leave;
+ leave.type = ClientMessage;
+ leave.window = qt_xdnd_current_target;
+ leave.format = 32;
+ leave.message_type = ATOM(XdndLeave);
+ leave.data.l[0] = manager->dragPrivate()->source->effectiveWinId();
+ leave.data.l[1] = 0; // flags
+ leave.data.l[2] = 0; // x, y
+ leave.data.l[3] = 0; // w, h
+ leave.data.l[4] = 0; // just null
+
+ QWidget * w = QWidget::find(qt_xdnd_current_proxy_target);
+
+ if (w && (w->windowType() == Qt::Desktop) && !w->acceptDrops())
+ w = 0;
+
+ if (w)
+ X11->xdndHandleLeave(w, (const XEvent *)&leave, false);
+ else
+ XSendEvent(X11->display, qt_xdnd_current_proxy_target, False,
+ NoEventMask, (XEvent*)&leave);
+
+ // reset the drag manager state
+ manager->willDrop = false;
+ if (global_accepted_action != Qt::IgnoreAction)
+ manager->emitActionChanged(Qt::IgnoreAction);
+ global_accepted_action = Qt::IgnoreAction;
+ manager->updateCursor();
+ qt_xdnd_current_target = 0;
+ qt_xdnd_current_proxy_target = 0;
+ qt_xdnd_source_current_time = 0;
+ waiting_for_status = false;
+}
+
+// TODO: remove and use QApplication::currentKeyboardModifiers() in Qt 4.8.
+static Qt::KeyboardModifiers currentKeyboardModifiers()
+{
+ Window root;
+ Window child;
+ int root_x, root_y, win_x, win_y;
+ uint keybstate;
+ for (int i = 0; i < ScreenCount(X11->display); ++i) {
+ if (XQueryPointer(X11->display, QX11Info::appRootWindow(i), &root, &child,
+ &root_x, &root_y, &win_x, &win_y, &keybstate))
+ return X11->translateModifiers(keybstate & 0x00ff);
+ }
+ return 0;
+}
+
+void QX11Data::xdndHandleDrop(QWidget *, const XEvent * xe, bool passive)
+{
+ DEBUG("xdndHandleDrop");
+ if (!qt_xdnd_current_widget) {
+ qt_xdnd_dragsource_xid = 0;
+ return; // sanity
+ }
+
+ if (!passive && checkEmbedded(qt_xdnd_current_widget, xe)){
+ current_embedding_widget = 0;
+ qt_xdnd_dragsource_xid = 0;
+ qt_xdnd_current_widget = 0;
+ return;
+ }
+ const unsigned long *l = (const unsigned long *)xe->xclient.data.l;
+
+ QDragManager *manager = QDragManager::self();
+ DEBUG("xdnd drop");
+
+ if (l[0] != qt_xdnd_dragsource_xid) {
+ DEBUG("xdnd drop from unexpected source (%08lx not %08lx", l[0], qt_xdnd_dragsource_xid);
+ return;
+ }
+
+ // update the "user time" from the timestamp in the event.
+ if (l[2] != 0) {
+ // Some X server/client combination swallow the first 32 bit and
+ // interpret a set bit 31 as negative sign.
+ qt_xdnd_target_current_time = X11->userTime =
+ ((sizeof(Time) == 8 && xe->xclient.data.l[2] < 0)
+ ? uint(l[2])
+ : l[2]);
+ }
+
+ if (!passive) {
+ // this could be a same-application drop, just proxied due to
+ // some XEMBEDding, so try to find the real QMimeData used
+ // based on the timestamp for this drop.
+ QMimeData *dropData = 0;
+ int at = findXdndDropTransactionByTime(qt_xdnd_target_current_time);
+ if (at != -1)
+ dropData = QDragManager::dragPrivate(X11->dndDropTransactions.at(at).object)->data;
+ // if we can't find it, then use the data in the drag manager
+ if (!dropData)
+ dropData = (manager->object) ? manager->dragPrivate()->data : manager->dropData;
+
+ // Drop coming from another app? Update keyboard modifiers.
+ if (!qt_xdnd_dragging) {
+ QApplicationPrivate::modifier_buttons = currentKeyboardModifiers();
+ }
+
+ QDropEvent de(qt_xdnd_current_position, possible_actions, dropData,
+ QApplication::mouseButtons(), QApplication::keyboardModifiers());
+ QApplication::sendEvent(qt_xdnd_current_widget, &de);
+ if (!de.isAccepted()) {
+ // Ignore a failed drag
+ global_accepted_action = Qt::IgnoreAction;
+ } else {
+ global_accepted_action = de.dropAction();
+ }
+ XClientMessageEvent finished;
+ finished.type = ClientMessage;
+ finished.window = qt_xdnd_dragsource_xid;
+ finished.format = 32;
+ finished.message_type = ATOM(XdndFinished);
+ DNDDEBUG << "xdndHandleDrop"
+ << "qt_xdnd_current_widget" << qt_xdnd_current_widget
+ << (qt_xdnd_current_widget ? qt_xdnd_current_widget->effectiveWinId() : 0)
+ << "t_xdnd_current_widget->window()"
+ << (qt_xdnd_current_widget ? qt_xdnd_current_widget->window() : 0)
+ << (qt_xdnd_current_widget ? qt_xdnd_current_widget->window()->internalWinId() : 0);
+ finished.data.l[0] = qt_xdnd_current_widget?qt_xdnd_current_widget->window()->internalWinId():0;
+ finished.data.l[1] = de.isAccepted() ? 1 : 0; // flags
+ finished.data.l[2] = qtaction_to_xdndaction(global_accepted_action);
+ XSendEvent(X11->display, qt_xdnd_dragsource_xid, False,
+ NoEventMask, (XEvent*)&finished);
+ } else {
+ QDragLeaveEvent e;
+ QApplication::sendEvent(qt_xdnd_current_widget, &e);
+ }
+ qt_xdnd_dragsource_xid = 0;
+ qt_xdnd_current_widget = 0;
+ waiting_for_status = false;
+
+ // reset
+ qt_xdnd_target_current_time = CurrentTime;
+}
+
+
+void QX11Data::xdndHandleFinished(QWidget *, const XEvent * xe, bool passive)
+{
+ DEBUG("xdndHandleFinished");
+ const unsigned long *l = (const unsigned long *)xe->xclient.data.l;
+
+ DNDDEBUG << "xdndHandleFinished, l[0]" << l[0]
+ << "qt_xdnd_current_target" << qt_xdnd_current_target
+ << "qt_xdnd_current_proxy_targe" << qt_xdnd_current_proxy_target;
+
+ if (l[0]) {
+ int at = findXdndDropTransactionByWindow(l[0]);
+ if (at != -1) {
+ restartXdndDropExpiryTimer();
+
+ QXdndDropTransaction t = X11->dndDropTransactions.takeAt(at);
+ QDragManager *manager = QDragManager::self();
+
+ Window target = qt_xdnd_current_target;
+ Window proxy_target = qt_xdnd_current_proxy_target;
+ QWidget *embedding_widget = current_embedding_widget;
+ QDrag *currentObject = manager->object;
+
+ qt_xdnd_current_target = t.target;
+ qt_xdnd_current_proxy_target = t.proxy_target;
+ current_embedding_widget = t.embedding_widget;
+ manager->object = t.object;
+
+ if (!passive)
+ (void) checkEmbedded(qt_xdnd_current_widget, xe);
+
+ current_embedding_widget = 0;
+ qt_xdnd_current_target = 0;
+ qt_xdnd_current_proxy_target = 0;
+
+ if (t.object)
+ t.object->deleteLater();
+
+ qt_xdnd_current_target = target;
+ qt_xdnd_current_proxy_target = proxy_target;
+ current_embedding_widget = embedding_widget;
+ manager->object = currentObject;
+ }
+ }
+ waiting_for_status = false;
+}
+
+
+void QDragManager::timerEvent(QTimerEvent* e)
+{
+ if (e->timerId() == heartbeat && qt_xdnd_source_sameanswer.isNull()) {
+ move(QCursor::pos());
+ } else if (e->timerId() == transaction_expiry_timer) {
+ for (int i = 0; i < X11->dndDropTransactions.count(); ++i) {
+ const QXdndDropTransaction &t = X11->dndDropTransactions.at(i);
+ if (t.targetWidget) {
+ // dnd within the same process, don't delete these
+ continue;
+ }
+ t.object->deleteLater();
+ X11->dndDropTransactions.removeAt(i--);
+ }
+
+ killTimer(transaction_expiry_timer);
+ transaction_expiry_timer = -1;
+ }
+}
+
+bool QDragManager::eventFilter(QObject * o, QEvent * e)
+{
+ if (beingCancelled) {
+ if (e->type() == QEvent::KeyRelease && ((QKeyEvent*)e)->key() == Qt::Key_Escape) {
+ qApp->removeEventFilter(this);
+ Q_ASSERT(object == 0);
+ beingCancelled = false;
+ eventLoop->exit();
+ return true; // block the key release
+ }
+ return false;
+ }
+
+ Q_ASSERT(object != 0);
+
+ if (!o->isWidgetType())
+ return false;
+
+ if (e->type() == QEvent::MouseMove) {
+ QMouseEvent* me = (QMouseEvent *)e;
+ move(me->globalPos());
+ return true;
+ } else if (e->type() == QEvent::MouseButtonRelease) {
+ DEBUG("pre drop");
+ qApp->removeEventFilter(this);
+ if (willDrop)
+ drop();
+ else
+ cancel();
+ DEBUG("drop, resetting object");
+ beingCancelled = false;
+ eventLoop->exit();
+ return true;
+ }
+
+ if (e->type() == QEvent::ShortcutOverride) {
+ // prevent accelerators from firing while dragging
+ e->accept();
+ return true;
+ }
+
+ if (e->type() == QEvent::KeyPress || e->type() == QEvent::KeyRelease) {
+ QKeyEvent *ke = ((QKeyEvent*)e);
+ if (ke->key() == Qt::Key_Escape && e->type() == QEvent::KeyPress) {
+ cancel();
+ qApp->removeEventFilter(this);
+ beingCancelled = false;
+ eventLoop->exit();
+ } else {
+ qt_xdnd_source_sameanswer = QRect(); // force move
+ move(QCursor::pos());
+ }
+ return true; // Eat all key events
+ }
+
+ // ### We bind modality to widgets, so we have to do this
+ // ### "manually".
+ // DnD is modal - eat all other interactive events
+ switch (e->type()) {
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseButtonDblClick:
+ case QEvent::MouseMove:
+ case QEvent::KeyPress:
+ case QEvent::KeyRelease:
+ case QEvent::Wheel:
+ case QEvent::ShortcutOverride:
+ return true;
+ default:
+ return false;
+ }
+}
+
+void QDragManager::updateCursor()
+{
+ if (!noDropCursor) {
+#ifndef QT_NO_CURSOR
+ noDropCursor = new QCursor(Qt::ForbiddenCursor);
+ moveCursor = new QCursor(Qt::DragMoveCursor);
+ copyCursor = new QCursor(Qt::DragCopyCursor);
+ linkCursor = new QCursor(Qt::DragLinkCursor);
+#endif
+ }
+
+ QCursor *c;
+ if (willDrop) {
+ if (global_accepted_action == Qt::CopyAction) {
+ c = copyCursor;
+ } else if (global_accepted_action == Qt::LinkAction) {
+ c = linkCursor;
+ } else {
+ c = moveCursor;
+ }
+ if (xdnd_data.deco) {
+ xdnd_data.deco->show();
+ xdnd_data.deco->raise();
+ }
+ } else {
+ c = noDropCursor;
+ //if (qt_xdnd_deco)
+ // qt_xdnd_deco->hide();
+ }
+#ifndef QT_NO_CURSOR
+ if (c)
+ qApp->changeOverrideCursor(*c);
+#endif
+}
+
+
+void QDragManager::cancel(bool deleteSource)
+{
+ DEBUG("QDragManager::cancel");
+ Q_ASSERT(heartbeat != -1);
+ killTimer(heartbeat);
+ heartbeat = -1;
+ beingCancelled = true;
+ qt_xdnd_dragging = false;
+
+ if (qt_xdnd_current_target)
+ qt_xdnd_send_leave();
+
+#ifndef QT_NO_CURSOR
+ if (restoreCursor) {
+ QApplication::restoreOverrideCursor();
+ restoreCursor = false;
+ }
+#endif
+
+ if (deleteSource && object)
+ object->deleteLater();
+ object = 0;
+ qDeleteInEventHandler(xdnd_data.deco);
+ xdnd_data.deco = 0;
+
+ global_accepted_action = Qt::IgnoreAction;
+}
+
+static
+Window findRealWindow(const QPoint & pos, Window w, int md)
+{
+ if (xdnd_data.deco && w == xdnd_data.deco->effectiveWinId())
+ return 0;
+
+ if (md) {
+ X11->ignoreBadwindow();
+ XWindowAttributes attr;
+ XGetWindowAttributes(X11->display, w, &attr);
+ if (X11->badwindow())
+ return 0;
+
+ if (attr.map_state == IsViewable
+ && QRect(attr.x,attr.y,attr.width,attr.height).contains(pos)) {
+ {
+ Atom type = XNone;
+ int f;
+ unsigned long n, a;
+ unsigned char *data;
+
+ XGetWindowProperty(X11->display, w, ATOM(XdndAware), 0, 0, False,
+ AnyPropertyType, &type, &f,&n,&a,&data);
+ if (data) XFree(data);
+ if (type)
+ return w;
+ }
+
+ Window r, p;
+ Window* c;
+ uint nc;
+ if (XQueryTree(X11->display, w, &r, &p, &c, &nc)) {
+ r=0;
+ for (uint i=nc; !r && i--;) {
+ r = findRealWindow(pos-QPoint(attr.x,attr.y),
+ c[i], md-1);
+ }
+ XFree(c);
+ if (r)
+ return r;
+
+ // We didn't find a client window! Just use the
+ // innermost window.
+ }
+
+ // No children!
+ return w;
+ }
+ }
+ return 0;
+}
+
+void QDragManager::move(const QPoint & globalPos)
+{
+#ifdef QT_NO_CURSOR
+ Q_UNUSED(globalPos);
+ return;
+#else
+ DEBUG() << "QDragManager::move enter";
+ if (!object) {
+ // perhaps the target crashed?
+ return;
+ }
+
+ int screen = QCursor::x11Screen();
+ if ((qt_xdnd_current_screen == -1 && screen != X11->defaultScreen) || (screen != qt_xdnd_current_screen)) {
+ // recreate the pixmap on the new screen...
+ delete xdnd_data.deco;
+ QWidget* parent = object->source()->window()->x11Info().screen() == screen
+ ? object->source()->window() : QApplication::desktop()->screen(screen);
+ xdnd_data.deco = new QShapedPixmapWidget(parent);
+ if (!QWidget::mouseGrabber()) {
+ updatePixmap();
+ xdnd_data.deco->grabMouse();
+ }
+ }
+ xdnd_data.deco->move(QCursor::pos() - xdnd_data.deco->pm_hot);
+
+ if (qt_xdnd_source_sameanswer.contains(globalPos) && qt_xdnd_source_sameanswer.isValid())
+ return;
+
+ qt_xdnd_current_screen = screen;
+ Window rootwin = QX11Info::appRootWindow(qt_xdnd_current_screen);
+ Window target = 0;
+ int lx = 0, ly = 0;
+ if (!XTranslateCoordinates(X11->display, rootwin, rootwin, globalPos.x(), globalPos.y(), &lx, &ly, &target))
+ // some weird error...
+ return;
+
+ if (target == rootwin) {
+ // Ok.
+ } else if (target) {
+ //me
+ Window src = rootwin;
+ while (target != 0) {
+ DNDDEBUG << "checking target for XdndAware" << QWidget::find(target) << target;
+ int lx2, ly2;
+ Window t;
+ // translate coordinates
+ if (!XTranslateCoordinates(X11->display, src, target, lx, ly, &lx2, &ly2, &t)) {
+ target = 0;
+ break;
+ }
+ lx = lx2;
+ ly = ly2;
+ src = target;
+
+ // check if it has XdndAware
+ Atom type = 0;
+ int f;
+ unsigned long n, a;
+ unsigned char *data = 0;
+ XGetWindowProperty(X11->display, target, ATOM(XdndAware), 0, 0, False,
+ AnyPropertyType, &type, &f,&n,&a,&data);
+ if (data)
+ XFree(data);
+ if (type) {
+ DNDDEBUG << "Found XdndAware on " << QWidget::find(target) << target;
+ break;
+ }
+
+ // find child at the coordinates
+ if (!XTranslateCoordinates(X11->display, src, src, lx, ly, &lx2, &ly2, &target)) {
+ target = 0;
+ break;
+ }
+ }
+ if (xdnd_data.deco && (!target || target == xdnd_data.deco->effectiveWinId())) {
+ DNDDEBUG << "need to find real window";
+ target = findRealWindow(globalPos, rootwin, 6);
+ DNDDEBUG << "real window found" << QWidget::find(target) << target;
+ }
+ }
+
+ QWidget* w;
+ if (target) {
+ w = QWidget::find((WId)target);
+ if (w && (w->windowType() == Qt::Desktop) && !w->acceptDrops())
+ w = 0;
+ } else {
+ w = 0;
+ target = rootwin;
+ }
+
+ DNDDEBUG << "and the final target is " << QWidget::find(target) << target;
+ DNDDEBUG << "the widget w is" << w;
+
+ WId proxy_target = xdndProxy(target);
+ if (!proxy_target)
+ proxy_target = target;
+ int target_version = 1;
+
+ if (proxy_target) {
+ Atom type = XNone;
+ int r, f;
+ unsigned long n, a;
+ unsigned char *retval;
+ X11->ignoreBadwindow();
+ r = XGetWindowProperty(X11->display, proxy_target, ATOM(XdndAware), 0,
+ 1, False, AnyPropertyType, &type, &f,&n,&a,&retval);
+ int *tv = (int *)retval;
+ if (r != Success || X11->badwindow()) {
+ target = 0;
+ } else {
+ target_version = qMin(xdnd_version,tv ? *tv : 1);
+ if (tv)
+ XFree(tv);
+// if (!(!X11->badwindow() && type))
+// target = 0;
+ }
+ }
+
+ if (target != qt_xdnd_current_target) {
+ if (qt_xdnd_current_target)
+ qt_xdnd_send_leave();
+
+ qt_xdnd_current_target = target;
+ qt_xdnd_current_proxy_target = proxy_target;
+ if (target) {
+ QVector<Atom> types;
+ int flags = target_version << 24;
+ QStringList fmts = QInternalMimeData::formatsHelper(dragPrivate()->data);
+ for (int i = 0; i < fmts.size(); ++i) {
+ QList<Atom> atoms = X11->xdndMimeAtomsForFormat(fmts.at(i));
+ for (int j = 0; j < atoms.size(); ++j) {
+ if (!types.contains(atoms.at(j)))
+ types.append(atoms.at(j));
+ }
+ }
+ if (types.size() > 3) {
+ XChangeProperty(X11->display,
+ dragPrivate()->source->effectiveWinId(), ATOM(XdndTypelist),
+ XA_ATOM, 32, PropModeReplace,
+ (unsigned char *)types.data(),
+ types.size());
+ flags |= 0x0001;
+ }
+ XClientMessageEvent enter;
+ enter.type = ClientMessage;
+ enter.window = target;
+ enter.format = 32;
+ enter.message_type = ATOM(XdndEnter);
+ enter.data.l[0] = dragPrivate()->source->effectiveWinId();
+ enter.data.l[1] = flags;
+ enter.data.l[2] = types.size()>0 ? types.at(0) : 0;
+ enter.data.l[3] = types.size()>1 ? types.at(1) : 0;
+ enter.data.l[4] = types.size()>2 ? types.at(2) : 0;
+ // provisionally set the rectangle to 5x5 pixels...
+ qt_xdnd_source_sameanswer = QRect(globalPos.x() - 2,
+ globalPos.y() -2 , 5, 5);
+
+ DEBUG("sending Xdnd enter");
+ if (w)
+ X11->xdndHandleEnter(w, (const XEvent *)&enter, false);
+ else if (target)
+ XSendEvent(X11->display, proxy_target, False, NoEventMask, (XEvent*)&enter);
+ waiting_for_status = false;
+ }
+ }
+ if (waiting_for_status)
+ return;
+
+ if (target) {
+ waiting_for_status = true;
+
+ XClientMessageEvent move;
+ move.type = ClientMessage;
+ move.window = target;
+ move.format = 32;
+ move.message_type = ATOM(XdndPosition);
+ move.window = target;
+ move.data.l[0] = dragPrivate()->source->effectiveWinId();
+ move.data.l[1] = 0; // flags
+ move.data.l[2] = (globalPos.x() << 16) + globalPos.y();
+ move.data.l[3] = X11->time;
+ move.data.l[4] = qtaction_to_xdndaction(defaultAction(dragPrivate()->possible_actions, QApplication::keyboardModifiers()));
+ DEBUG("sending Xdnd position");
+
+ qt_xdnd_source_current_time = X11->time;
+
+ if (w)
+ handle_xdnd_position(w, (const XEvent *)&move, false);
+ else
+ XSendEvent(X11->display, proxy_target, False, NoEventMask,
+ (XEvent*)&move);
+ } else {
+ if (willDrop) {
+ willDrop = false;
+ updateCursor();
+ }
+ }
+ DEBUG() << "QDragManager::move leave";
+#endif
+}
+
+
+void QDragManager::drop()
+{
+ Q_ASSERT(heartbeat != -1);
+ killTimer(heartbeat);
+ heartbeat = -1;
+ qt_xdnd_dragging = false;
+
+ if (!qt_xdnd_current_target)
+ return;
+
+ qDeleteInEventHandler(xdnd_data.deco);
+ xdnd_data.deco = 0;
+
+ XClientMessageEvent drop;
+ drop.type = ClientMessage;
+ drop.window = qt_xdnd_current_target;
+ drop.format = 32;
+ drop.message_type = ATOM(XdndDrop);
+ drop.data.l[0] = dragPrivate()->source->effectiveWinId();
+ drop.data.l[1] = 0; // flags
+ drop.data.l[2] = X11->time;
+
+ drop.data.l[3] = 0;
+ drop.data.l[4] = 0;
+
+ QWidget * w = QWidget::find(qt_xdnd_current_proxy_target);
+
+ if (w && (w->windowType() == Qt::Desktop) && !w->acceptDrops())
+ w = 0;
+
+ QXdndDropTransaction t = {
+ X11->time,
+ qt_xdnd_current_target,
+ qt_xdnd_current_proxy_target,
+ w,
+ current_embedding_widget,
+ object
+ };
+ X11->dndDropTransactions.append(t);
+ restartXdndDropExpiryTimer();
+
+ if (w)
+ X11->xdndHandleDrop(w, (const XEvent *)&drop, false);
+ else
+ XSendEvent(X11->display, qt_xdnd_current_proxy_target, False,
+ NoEventMask, (XEvent*)&drop);
+
+ qt_xdnd_current_target = 0;
+ qt_xdnd_current_proxy_target = 0;
+ qt_xdnd_source_current_time = 0;
+ current_embedding_widget = 0;
+ object = 0;
+
+#ifndef QT_NO_CURSOR
+ if (restoreCursor) {
+ QApplication::restoreOverrideCursor();
+ restoreCursor = false;
+ }
+#endif
+}
+
+
+
+bool QX11Data::xdndHandleBadwindow()
+{
+ if (qt_xdnd_current_target) {
+ QDragManager *manager = QDragManager::self();
+ if (manager->object) {
+ qt_xdnd_current_target = 0;
+ qt_xdnd_current_proxy_target = 0;
+ manager->object->deleteLater();
+ manager->object = 0;
+ delete xdnd_data.deco;
+ xdnd_data.deco = 0;
+ return true;
+ }
+ }
+ if (qt_xdnd_dragsource_xid) {
+ qt_xdnd_dragsource_xid = 0;
+ if (qt_xdnd_current_widget) {
+ QApplication::postEvent(qt_xdnd_current_widget, new QDragLeaveEvent);
+ qt_xdnd_current_widget = 0;
+ }
+ return true;
+ }
+ return false;
+}
+
+void QX11Data::xdndHandleSelectionRequest(const XSelectionRequestEvent * req)
+{
+ if (!req)
+ return;
+ XEvent evt;
+ evt.xselection.type = SelectionNotify;
+ evt.xselection.display = req->display;
+ evt.xselection.requestor = req->requestor;
+ evt.xselection.selection = req->selection;
+ evt.xselection.target = XNone;
+ evt.xselection.property = XNone;
+ evt.xselection.time = req->time;
+
+ QDragManager *manager = QDragManager::self();
+ QDrag *currentObject = manager->object;
+
+ // which transaction do we use? (note: -2 means use current manager->object)
+ int at = -1;
+
+ // figure out which data the requestor is really interested in
+ if (manager->object && req->time == qt_xdnd_source_current_time) {
+ // requestor wants the current drag data
+ at = -2;
+ } else {
+ // if someone has requested data in response to XdndDrop, find the corresponding transaction. the
+ // spec says to call XConvertSelection() using the timestamp from the XdndDrop
+ at = findXdndDropTransactionByTime(req->time);
+ if (at == -1) {
+ // no dice, perhaps the client was nice enough to use the same window id in XConvertSelection()
+ // that we sent the XdndDrop event to.
+ at = findXdndDropTransactionByWindow(req->requestor);
+ }
+ if (at == -1 && req->time == CurrentTime) {
+ // previous Qt versions always requested the data on a child of the target window
+ // using CurrentTime... but it could be asking for either drop data or the current drag's data
+ Window target = findXdndAwareParent(req->requestor);
+ if (target) {
+ if (qt_xdnd_current_target && qt_xdnd_current_target == target)
+ at = -2;
+ else
+ at = findXdndDropTransactionByWindow(target);
+ }
+ }
+ }
+ if (at >= 0) {
+ restartXdndDropExpiryTimer();
+
+ // use the drag object from an XdndDrop tansaction
+ manager->object = X11->dndDropTransactions.at(at).object;
+ } else if (at != -2) {
+ // no transaction found, we'll have to reject the request
+ manager->object = 0;
+ }
+ if (manager->object) {
+ Atom atomFormat = req->target;
+ int dataFormat = 0;
+ QByteArray data;
+ if (X11->xdndMimeDataForAtom(req->target, manager->dragPrivate()->data,
+ &data, &atomFormat, &dataFormat)) {
+ int dataSize = data.size() / (dataFormat / 8);
+ XChangeProperty (X11->display, req->requestor, req->property,
+ atomFormat, dataFormat, PropModeReplace,
+ (unsigned char *)data.data(), dataSize);
+ evt.xselection.property = req->property;
+ evt.xselection.target = atomFormat;
+ }
+ }
+
+ // reset manager->object in case we modified it above
+ manager->object = currentObject;
+
+ // ### this can die if req->requestor crashes at the wrong
+ // ### moment
+ XSendEvent(X11->display, req->requestor, False, 0, &evt);
+}
+
+static QVariant xdndObtainData(const char *format, QVariant::Type requestedType)
+{
+ QByteArray result;
+
+ QWidget* w;
+ QDragManager *manager = QDragManager::self();
+ if (qt_xdnd_dragsource_xid && manager->object &&
+ (w=QWidget::find(qt_xdnd_dragsource_xid))
+ && (!(w->windowType() == Qt::Desktop) || w->acceptDrops()))
+ {
+ QDragPrivate * o = QDragManager::self()->dragPrivate();
+ if (o->data->hasFormat(QLatin1String(format)))
+ result = o->data->data(QLatin1String(format));
+ return result;
+ }
+
+ QList<Atom> atoms;
+ int i = 0;
+ while ((qt_xdnd_types[i])) {
+ atoms.append(qt_xdnd_types[i]);
+ ++i;
+ }
+ QByteArray encoding;
+ Atom a = X11->xdndMimeAtomForFormat(QLatin1String(format), requestedType, atoms, &encoding);
+ if (!a)
+ return result;
+
+ if (XGetSelectionOwner(X11->display, ATOM(XdndSelection)) == XNone)
+ return result; // should never happen?
+
+ QWidget* tw = qt_xdnd_current_widget;
+ if (!qt_xdnd_current_widget || (qt_xdnd_current_widget->windowType() == Qt::Desktop))
+ tw = new QWidget;
+
+ XConvertSelection(X11->display, ATOM(XdndSelection), a, ATOM(XdndSelection), tw->effectiveWinId(),
+ qt_xdnd_target_current_time);
+ XFlush(X11->display);
+
+ XEvent xevent;
+ bool got=X11->clipboardWaitForEvent(tw->effectiveWinId(), SelectionNotify, &xevent, 5000);
+ if (got) {
+ Atom type;
+
+ if (X11->clipboardReadProperty(tw->effectiveWinId(), ATOM(XdndSelection), true, &result, 0, &type, 0)) {
+ if (type == ATOM(INCR)) {
+ int nbytes = result.size() >= 4 ? *((int*)result.data()) : 0;
+ result = X11->clipboardReadIncrementalProperty(tw->effectiveWinId(), ATOM(XdndSelection), nbytes, false);
+ } else if (type != a && type != XNone) {
+ DEBUG("Qt clipboard: unknown atom %ld", type);
+ }
+ }
+ }
+ if (!qt_xdnd_current_widget || (qt_xdnd_current_widget->windowType() == Qt::Desktop))
+ delete tw;
+
+ return X11->xdndMimeConvertToFormat(a, result, QLatin1String(format), requestedType, encoding);
+}
+
+
+/*
+ Enable drag and drop for widget w by installing the proper
+ properties on w's toplevel widget.
+*/
+bool QX11Data::dndEnable(QWidget* w, bool on)
+{
+ w = w->window();
+
+ if (bool(((QExtraWidget*)w)->topData()->dnd) == on)
+ return true; // been there, done that
+ ((QExtraWidget*)w)->topData()->dnd = on ? 1 : 0;
+
+ motifdndEnable(w, on);
+ return xdndEnable(w, on);
+}
+
+Qt::DropAction QDragManager::drag(QDrag * o)
+{
+ if (object == o || !o || !o->d_func()->source)
+ return Qt::IgnoreAction;
+
+ if (object) {
+ cancel();
+ qApp->removeEventFilter(this);
+ beingCancelled = false;
+ }
+
+ if (object) {
+ // the last drag and drop operation hasn't finished, so we are going to wait
+ // for one second to see if it does... if the finish message comes after this,
+ // then we could still have problems, but this is highly unlikely
+ QApplication::flush();
+
+ QElapsedTimer timer;
+ timer.start();
+ do {
+ XEvent event;
+ if (XCheckTypedEvent(X11->display, ClientMessage, &event))
+ qApp->x11ProcessEvent(&event);
+
+ // sleep 50 ms, so we don't use up CPU cycles all the time.
+ struct timeval usleep_tv;
+ usleep_tv.tv_sec = 0;
+ usleep_tv.tv_usec = 50000;
+ select(0, 0, 0, 0, &usleep_tv);
+ } while (object && timer.hasExpired(1000));
+ }
+
+ object = o;
+ object->d_func()->target = 0;
+ xdnd_data.deco = new QShapedPixmapWidget(object->source()->window());
+
+ willDrop = false;
+
+ updatePixmap();
+
+ qApp->installEventFilter(this);
+ XSetSelectionOwner(X11->display, ATOM(XdndSelection), dragPrivate()->source->window()->internalWinId(), X11->time);
+ global_accepted_action = Qt::CopyAction;
+ qt_xdnd_source_sameanswer = QRect();
+#ifndef QT_NO_CURSOR
+ // set the override cursor (must be done here, since it is updated
+ // in the call to move() below)
+ qApp->setOverrideCursor(Qt::ArrowCursor);
+ restoreCursor = true;
+#endif
+ move(QCursor::pos());
+ heartbeat = startTimer(200);
+
+ qt_xdnd_dragging = true;
+
+ if (!QWidget::mouseGrabber())
+ xdnd_data.deco->grabMouse();
+
+ eventLoop = new QEventLoop;
+ (void) eventLoop->exec();
+ delete eventLoop;
+ eventLoop = 0;
+
+#ifndef QT_NO_CURSOR
+ if (restoreCursor) {
+ qApp->restoreOverrideCursor();
+ restoreCursor = false;
+ }
+#endif
+
+ // delete cursors as they may be different next drag.
+ delete noDropCursor;
+ noDropCursor = 0;
+ delete copyCursor;
+ copyCursor = 0;
+ delete moveCursor;
+ moveCursor = 0;
+ delete linkCursor;
+ linkCursor = 0;
+
+ delete xdnd_data.deco;
+ xdnd_data.deco = 0;
+ if (heartbeat != -1)
+ killTimer(heartbeat);
+ heartbeat = -1;
+ qt_xdnd_current_screen = -1;
+ qt_xdnd_dragging = false;
+
+ return global_accepted_action;
+ // object persists until we get an xdnd_finish message
+}
+
+void QDragManager::updatePixmap()
+{
+ if (xdnd_data.deco) {
+ QPixmap pm;
+ QPoint pm_hot(default_pm_hotx,default_pm_hoty);
+ if (object) {
+ pm = dragPrivate()->pixmap;
+ if (!pm.isNull())
+ pm_hot = dragPrivate()->hotspot;
+ }
+ if (pm.isNull()) {
+ if (!defaultPm)
+ defaultPm = new QPixmap(default_pm);
+ pm = *defaultPm;
+ }
+ xdnd_data.deco->pm_hot = pm_hot;
+ xdnd_data.deco->setPixmap(pm);
+ xdnd_data.deco->move(QCursor::pos()-pm_hot);
+ xdnd_data.deco->show();
+ }
+}
+
+QVariant QDropData::retrieveData_sys(const QString &mimetype, QVariant::Type requestedType) const
+{
+ QByteArray mime = mimetype.toLatin1();
+ QVariant data = X11->motifdnd_active
+ ? X11->motifdndObtainData(mime)
+ : xdndObtainData(mime, requestedType);
+ return data;
+}
+
+bool QDropData::hasFormat_sys(const QString &format) const
+{
+ return formats().contains(format);
+}
+
+QStringList QDropData::formats_sys() const
+{
+ QStringList formats;
+ if (X11->motifdnd_active) {
+ int i = 0;
+ QByteArray fmt;
+ while (!(fmt = X11->motifdndFormat(i)).isEmpty()) {
+ formats.append(QLatin1String(fmt));
+ ++i;
+ }
+ } else {
+ int i = 0;
+ while ((qt_xdnd_types[i])) {
+ QStringList formatsForAtom = X11->xdndMimeFormatsForAtom(qt_xdnd_types[i]);
+ for (int j = 0; j < formatsForAtom.size(); ++j) {
+ if (!formats.contains(formatsForAtom.at(j)))
+ formats.append(formatsForAtom.at(j));
+ }
+ ++i;
+ }
+ }
+ return formats;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_DRAGANDDROP
diff --git a/src/gui/kernel/qeventdispatcher_x11.cpp b/src/widgets/platforms/x11/qeventdispatcher_x11.cpp
index e31d8ed301..e31d8ed301 100644
--- a/src/gui/kernel/qeventdispatcher_x11.cpp
+++ b/src/widgets/platforms/x11/qeventdispatcher_x11.cpp
diff --git a/src/gui/kernel/qeventdispatcher_x11_p.h b/src/widgets/platforms/x11/qeventdispatcher_x11_p.h
index 1b6620d90f..1b6620d90f 100644
--- a/src/gui/kernel/qeventdispatcher_x11_p.h
+++ b/src/widgets/platforms/x11/qeventdispatcher_x11_p.h
diff --git a/src/widgets/platforms/x11/qfont_x11.cpp b/src/widgets/platforms/x11/qfont_x11.cpp
new file mode 100644
index 0000000000..ba69871855
--- /dev/null
+++ b/src/widgets/platforms/x11/qfont_x11.cpp
@@ -0,0 +1,368 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#define QT_FATAL_ASSERT
+
+#include "qplatformdefs.h"
+
+#include "qfont.h"
+#include "qapplication.h"
+#include "qfontinfo.h"
+#include "qfontdatabase.h"
+#include "qfontmetrics.h"
+#include "qpaintdevice.h"
+#include "qtextcodec.h"
+#include "qiodevice.h"
+#include "qhash.h"
+
+#include <private/qunicodetables_p.h>
+#include "qfont_p.h"
+#include "qfontengine_p.h"
+#include "qfontengine_x11_p.h"
+#include "qtextengine_p.h"
+
+#include <private/qt_x11_p.h>
+#include "qx11info_x11.h"
+
+#include <time.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#define QFONTLOADER_DEBUG
+#define QFONTLOADER_DEBUG_VERBOSE
+
+QT_BEGIN_NAMESPACE
+
+double qt_pixelSize(double pointSize, int dpi)
+{
+ if (pointSize < 0)
+ return -1.;
+ if (dpi == 75) // the stupid 75 dpi setting on X11
+ dpi = 72;
+ return (pointSize * dpi) /72.;
+}
+
+double qt_pointSize(double pixelSize, int dpi)
+{
+ if (pixelSize < 0)
+ return -1.;
+ if (dpi == 75) // the stupid 75 dpi setting on X11
+ dpi = 72;
+ return pixelSize * 72. / ((double) dpi);
+}
+
+/*
+ Removes wildcards from an XLFD.
+
+ Returns \a xlfd with all wildcards removed if a match for \a xlfd is
+ found, otherwise it returns \a xlfd.
+*/
+static QByteArray qt_fixXLFD(const QByteArray &xlfd)
+{
+ QByteArray ret = xlfd;
+ int count = 0;
+ char **fontNames =
+ XListFonts(QX11Info::display(), xlfd, 32768, &count);
+ if (count > 0)
+ ret = fontNames[0];
+ XFreeFontNames(fontNames);
+ return ret ;
+}
+
+typedef QHash<int, QString> FallBackHash;
+Q_GLOBAL_STATIC(FallBackHash, fallBackHash)
+
+// Returns the user-configured fallback family for the specified script.
+QString qt_fallback_font_family(int script)
+{
+ FallBackHash *hash = fallBackHash();
+ return hash->value(script);
+}
+
+// Sets the fallback family for the specified script.
+Q_WIDGETS_EXPORT void qt_x11_set_fallback_font_family(int script, const QString &family)
+{
+ FallBackHash *hash = fallBackHash();
+ if (!family.isEmpty())
+ hash->insert(script, family);
+ else
+ hash->remove(script);
+}
+
+int QFontPrivate::defaultEncodingID = -1;
+
+void QFont::initialize()
+{
+ extern int qt_encoding_id_for_mib(int mib); // from qfontdatabase_x11.cpp
+ QTextCodec *codec = QTextCodec::codecForLocale();
+ // determine the default encoding id using the locale, otherwise
+ // fallback to latin1 (mib == 4)
+ int mib = codec ? codec->mibEnum() : 4;
+
+ // for asian locales, use the mib for the font codec instead of the locale codec
+ switch (mib) {
+ case 38: // eucKR
+ mib = 36;
+ break;
+
+ case 2025: // GB2312
+ mib = 57;
+ break;
+
+ case 113: // GBK
+ mib = -113;
+ break;
+
+ case 114: // GB18030
+ mib = -114;
+ break;
+
+ case 2026: // Big5
+ mib = -2026;
+ break;
+
+ case 2101: // Big5-HKSCS
+ mib = -2101;
+ break;
+
+ case 16: // JIS7
+ mib = 15;
+ break;
+
+ case 17: // SJIS
+ case 18: // eucJP
+ mib = 63;
+ break;
+ }
+
+ // get the default encoding id for the locale encoding...
+ QFontPrivate::defaultEncodingID = qt_encoding_id_for_mib(mib);
+}
+
+void QFont::cleanup()
+{
+ QFontCache::cleanup();
+}
+
+/*!
+ \internal
+ X11 Only: Returns the screen with which this font is associated.
+*/
+int QFont::x11Screen() const
+{
+ return d->screen;
+}
+
+/*! \internal
+ X11 Only: Associate the font with the specified \a screen.
+*/
+void QFont::x11SetScreen(int screen)
+{
+ if (screen < 0) // assume default
+ screen = QX11Info::appScreen();
+
+ if (screen == d->screen)
+ return; // nothing to do
+
+ detach();
+ d->screen = screen;
+}
+
+Qt::HANDLE QFont::handle() const
+{
+ QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
+ Q_ASSERT(engine != 0);
+ if (engine->type() == QFontEngine::Multi)
+ engine = static_cast<QFontEngineMulti *>(engine)->engine(0);
+ if (engine->type() == QFontEngine::XLFD)
+ return static_cast<QFontEngineXLFD *>(engine)->fontStruct()->fid;
+ return 0;
+}
+
+
+FT_Face QFont::freetypeFace() const
+{
+#ifndef QT_NO_FREETYPE
+ QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
+ if (engine->type() == QFontEngine::Multi)
+ engine = static_cast<QFontEngineMulti *>(engine)->engine(0);
+#ifndef QT_NO_FONTCONFIG
+ if (engine->type() == QFontEngine::Freetype) {
+ const QFontEngineFT *ft = static_cast<const QFontEngineFT *>(engine);
+ return ft->non_locked_face();
+ } else
+#endif
+ if (engine->type() == QFontEngine::XLFD) {
+ const QFontEngineXLFD *xlfd = static_cast<const QFontEngineXLFD *>(engine);
+ return xlfd->non_locked_face();
+ }
+#endif
+ return 0;
+}
+
+QString QFont::rawName() const
+{
+ QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
+ Q_ASSERT(engine != 0);
+ if (engine->type() == QFontEngine::Multi)
+ engine = static_cast<QFontEngineMulti *>(engine)->engine(0);
+ if (engine->type() == QFontEngine::XLFD)
+ return QString::fromLatin1(engine->name());
+ return QString();
+}
+struct QtFontDesc;
+
+void QFont::setRawName(const QString &name)
+{
+ detach();
+
+ // from qfontdatabase_x11.cpp
+ extern bool qt_fillFontDef(const QByteArray &xlfd, QFontDef *fd, int dpi, QtFontDesc *desc);
+
+ if (!qt_fillFontDef(qt_fixXLFD(name.toLatin1()), &d->request, d->dpi, 0)) {
+ qWarning("QFont::setRawName: Invalid XLFD: \"%s\"", name.toLatin1().constData());
+
+ setFamily(name);
+ setRawMode(true);
+ } else {
+ resolve_mask = QFont::AllPropertiesResolved;
+ }
+}
+
+QString QFont::lastResortFamily() const
+{
+ return QString::fromLatin1("Helvetica");
+}
+
+QString QFont::defaultFamily() const
+{
+ switch (d->request.styleHint) {
+ case QFont::Times:
+ return QString::fromLatin1("Times");
+
+ case QFont::Courier:
+ return QString::fromLatin1("Courier");
+
+ case QFont::Monospace:
+ return QString::fromLatin1("Courier New");
+
+ case QFont::Cursive:
+ return QString::fromLatin1("Comic Sans MS");
+
+ case QFont::Fantasy:
+ return QString::fromLatin1("Impact");
+
+ case QFont::Decorative:
+ return QString::fromLatin1("Old English");
+
+ case QFont::Helvetica:
+ case QFont::System:
+ default:
+ return QString::fromLatin1("Helvetica");
+ }
+}
+
+/*
+ Returns a last resort raw font name for the font matching algorithm.
+ This is used if even the last resort family is not available. It
+ returns \e something, almost no matter what. The current
+ implementation tries a wide variety of common fonts, returning the
+ first one it finds. The implementation may change at any time.
+*/
+static const char * const tryFonts[] = {
+ "-*-helvetica-medium-r-*-*-*-120-*-*-*-*-*-*",
+ "-*-courier-medium-r-*-*-*-120-*-*-*-*-*-*",
+ "-*-times-medium-r-*-*-*-120-*-*-*-*-*-*",
+ "-*-lucida-medium-r-*-*-*-120-*-*-*-*-*-*",
+ "-*-helvetica-*-*-*-*-*-120-*-*-*-*-*-*",
+ "-*-courier-*-*-*-*-*-120-*-*-*-*-*-*",
+ "-*-times-*-*-*-*-*-120-*-*-*-*-*-*",
+ "-*-lucida-*-*-*-*-*-120-*-*-*-*-*-*",
+ "-*-helvetica-*-*-*-*-*-*-*-*-*-*-*-*",
+ "-*-courier-*-*-*-*-*-*-*-*-*-*-*-*",
+ "-*-times-*-*-*-*-*-*-*-*-*-*-*-*",
+ "-*-lucida-*-*-*-*-*-*-*-*-*-*-*-*",
+ "-*-fixed-*-*-*-*-*-*-*-*-*-*-*-*",
+ "6x13",
+ "7x13",
+ "8x13",
+ "9x15",
+ "fixed",
+ 0
+};
+
+// Returns true if the font exists, false otherwise
+static bool fontExists(const QString &fontName)
+{
+ int count;
+ char **fontNames = XListFonts(QX11Info::display(), (char*)fontName.toLatin1().constData(), 32768, &count);
+ if (fontNames) XFreeFontNames(fontNames);
+
+ return count != 0;
+}
+
+QString QFont::lastResortFont() const
+{
+ static QString last;
+
+ // already found
+ if (! last.isNull())
+ return last;
+
+ int i = 0;
+ const char* f;
+
+ while ((f = tryFonts[i])) {
+ last = QString::fromLatin1(f);
+
+ if (fontExists(last))
+ return last;
+
+ i++;
+ }
+
+#if defined(CHECK_NULL)
+ qFatal("QFontPrivate::lastResortFont: Cannot find any reasonable font");
+#endif
+ return last;
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/text/qfontdatabase_x11.cpp b/src/widgets/platforms/x11/qfontdatabase_x11.cpp
index 922a97f3aa..922a97f3aa 100644
--- a/src/gui/text/qfontdatabase_x11.cpp
+++ b/src/widgets/platforms/x11/qfontdatabase_x11.cpp
diff --git a/src/widgets/platforms/x11/qfontengine_x11.cpp b/src/widgets/platforms/x11/qfontengine_x11.cpp
new file mode 100644
index 0000000000..be421976fa
--- /dev/null
+++ b/src/widgets/platforms/x11/qfontengine_x11.cpp
@@ -0,0 +1,1205 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbitmap.h"
+
+// #define FONTENGINE_DEBUG
+
+#include <qapplication.h>
+#include <qbytearray.h>
+#include <qdebug.h>
+#include <qtextcodec.h>
+#include <qthread.h>
+
+#include "qfontdatabase.h"
+#include "qpaintdevice.h"
+#include "qpainter.h"
+#include "qvarlengtharray.h"
+#include "qwidget.h"
+#include "qsettings.h"
+#include "qfile.h"
+
+#include <private/qpaintengine_x11_p.h>
+#include "qfont.h"
+#include "qfont_p.h"
+#include "qfontengine_p.h"
+#include <qhash.h>
+
+#include <private/qpainter_p.h>
+#include <private/qunicodetables_p.h>
+
+#include <private/qt_x11_p.h>
+#include <private/qpixmap_x11_p.h>
+#include "qx11info_x11.h"
+#include "qfontengine_x11_p.h"
+
+#include <limits.h>
+
+#include <ft2build.h>
+#if defined(FT_LCD_FILTER_H)
+#include FT_LCD_FILTER_H
+#endif
+
+#if defined(FC_LCD_FILTER)
+
+#ifndef FC_LCD_FILTER_NONE
+#define FC_LCD_FILTER_NONE FC_LCD_NONE
+#endif
+
+#ifndef FC_LCD_FILTER_DEFAULT
+#define FC_LCD_FILTER_DEFAULT FC_LCD_DEFAULT
+#endif
+
+#ifndef FC_LCD_FILTER_LIGHT
+#define FC_LCD_FILTER_LIGHT FC_LCD_LIGHT
+#endif
+
+#ifndef FC_LCD_FILTER_LEGACY
+#define FC_LCD_FILTER_LEGACY FC_LCD_LEGACY
+#endif
+
+#endif
+
+QT_BEGIN_NAMESPACE
+
+
+// ------------------------------------------------------------------
+// Multi XLFD engine
+// ------------------------------------------------------------------
+
+QFontEngineMultiXLFD::QFontEngineMultiXLFD(const QFontDef &r, const QList<int> &l, int s)
+ : QFontEngineMulti(l.size()), encodings(l), screen(s), request(r)
+{
+ loadEngine(0);
+ fontDef = engines[0]->fontDef;
+}
+
+QFontEngineMultiXLFD::~QFontEngineMultiXLFD()
+{ }
+
+void QFontEngineMultiXLFD::loadEngine(int at)
+{
+ Q_ASSERT(at < engines.size());
+ Q_ASSERT(engines.at(at) == 0);
+ const int encoding = encodings.at(at);
+ QFontEngine *fontEngine = QFontDatabase::loadXlfd(0, QUnicodeTables::Common, request, encoding);
+ Q_ASSERT(fontEngine != 0);
+ fontEngine->ref.ref();
+ engines[at] = fontEngine;
+}
+
+// ------------------------------------------------------------------
+// Xlfd font engine
+// ------------------------------------------------------------------
+
+#ifndef QT_NO_FREETYPE
+
+static QStringList *qt_fontpath = 0;
+
+static QStringList fontPath()
+{
+ if (qt_fontpath)
+ return *qt_fontpath;
+
+ // append qsettings fontpath
+ QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
+ settings.beginGroup(QLatin1String("Qt"));
+
+ QStringList fontpath;
+
+ int npaths;
+ char** font_path;
+ font_path = XGetFontPath(X11->display, &npaths);
+ bool xfsconfig_read = false;
+ for (int i=0; i<npaths; i++) {
+ // If we're using xfs, append font paths from /etc/X11/fs/config
+ // can't hurt, and chances are we'll get all fonts that way.
+ if (((font_path[i])[0] != '/') && !xfsconfig_read) {
+ // We're using xfs -> read its config
+ bool finished = false;
+ QFile f(QLatin1String("/etc/X11/fs/config"));
+ if (!f.exists())
+ f.setFileName(QLatin1String("/usr/X11R6/lib/X11/fs/config"));
+ if (!f.exists())
+ f.setFileName(QLatin1String("/usr/X11/lib/X11/fs/config"));
+ if (f.exists()) {
+ f.open(QIODevice::ReadOnly);
+ while (f.error()==QFile::NoError && !finished) {
+ QString fs = QString::fromLocal8Bit(f.readLine(1024));
+ fs=fs.trimmed();
+ if (fs.left(9)==QLatin1String("catalogue") && fs.contains(QLatin1Char('='))) {
+ fs = fs.mid(fs.indexOf(QLatin1Char('=')) + 1).trimmed();
+ bool end = false;
+ while (f.error()==QFile::NoError && !end) {
+ if (fs[int(fs.length())-1] == QLatin1Char(','))
+ fs = fs.left(fs.length()-1);
+ else
+ end = true;
+
+ fs = fs.left(fs.indexOf(QLatin1String(":unscaled")));
+ if (fs[0] != QLatin1Char('#'))
+ fontpath += fs;
+ fs = QLatin1String(f.readLine(1024));
+ fs = fs.trimmed();
+ if (fs.isEmpty())
+ end = true;
+ }
+ finished = true;
+ }
+ }
+ f.close();
+ }
+ xfsconfig_read = true;
+ } else {
+ QString fs = QString::fromLocal8Bit(font_path[i]);
+ fontpath += fs.left(fs.indexOf(QLatin1String(":unscaled")));
+ }
+ }
+ XFreeFontPath(font_path);
+
+ // append qsettings fontpath
+ QStringList fp = settings.value(QLatin1String("fontPath")).toStringList();
+ if (!fp.isEmpty())
+ fontpath += fp;
+
+ qt_fontpath = new QStringList(fontpath);
+ return fontpath;
+}
+
+static QFontEngine::FaceId fontFile(const QByteArray &_xname, QFreetypeFace **freetype, int *synth)
+{
+ *freetype = 0;
+ *synth = 0;
+
+ QByteArray xname = _xname.toLower();
+
+ int pos = 0;
+ int minus = 0;
+ while (minus < 5 && (pos = xname.indexOf('-', pos + 1)))
+ ++minus;
+ QByteArray searchname = xname.left(pos);
+ while (minus < 12 && (pos = xname.indexOf('-', pos + 1)))
+ ++minus;
+ QByteArray encoding = xname.mid(pos + 1);
+ //qDebug("xname='%s', searchname='%s', encoding='%s'", xname.data(), searchname.data(), encoding.data());
+ QStringList fontpath = fontPath();
+ QFontEngine::FaceId face_id;
+ face_id.index = 0;
+
+ QByteArray best_mapping;
+
+ for (QStringList::ConstIterator it = fontpath.constBegin(); it != fontpath.constEnd(); ++it) {
+ if (!(*it).startsWith(QLatin1Char('/')))
+ continue; // not a path name, a font server
+ QString fontmapname;
+ int num = 0;
+ // search font.dir and font.scale for the right file
+ while (num < 2) {
+ if (num == 0)
+ fontmapname = (*it) + QLatin1String("/fonts.scale");
+ else
+ fontmapname = (*it) + QLatin1String("/fonts.dir");
+ ++num;
+ //qWarning(fontmapname);
+ QFile fontmap(fontmapname);
+ if (!fontmap.open(QIODevice::ReadOnly))
+ continue;
+ while (!fontmap.atEnd()) {
+ QByteArray mapping = fontmap.readLine();
+ QByteArray lmapping = mapping.toLower();
+
+ //qWarning(xfontname);
+ //qWarning(mapping);
+ if (!lmapping.contains(searchname))
+ continue;
+ int index = mapping.indexOf(' ');
+ QByteArray ffn = mapping.mid(0,index);
+ // remove bitmap formats freetype can't handle
+ if (ffn.contains(".spd") || ffn.contains(".phont"))
+ continue;
+ bool best_match = false;
+ if (!best_mapping.isEmpty()) {
+ if (lmapping.contains("-0-0-0-0-")) { // scalable font
+ best_match = true;
+ goto found;
+ }
+ if (lmapping.contains(encoding) && !best_mapping.toLower().contains(encoding))
+ goto found;
+ continue;
+ }
+
+ found:
+ int colon = ffn.lastIndexOf(':');
+ if (colon != -1) {
+ QByteArray s = ffn.left(colon);
+ ffn = ffn.mid(colon + 1);
+ if (s.contains("ds="))
+ *synth |= QFontEngine::SynthesizedBold;
+ if (s.contains("ai="))
+ *synth |= QFontEngine::SynthesizedItalic;
+ }
+ face_id.filename = (*it).toLocal8Bit() + '/' + ffn;
+ best_mapping = mapping;
+ if (best_match)
+ goto end;
+ }
+ }
+ }
+end:
+// qDebug("fontfile for %s is from '%s'\n got %s synth=%d", xname.data(),
+// best_mapping.data(), face_id.filename.data(), *synth);
+ *freetype = QFreetypeFace::getFace(face_id);
+ if (!*freetype) {
+ face_id.index = 0;
+ face_id.filename = QByteArray();
+ }
+ return face_id;
+}
+
+#endif // QT_NO_FREETYPE
+
+// defined in qfontdatabase_x11.cpp
+extern int qt_mib_for_xlfd_encoding(const char *encoding);
+extern int qt_xlfd_encoding_id(const char *encoding);
+
+static inline XCharStruct *charStruct(XFontStruct *xfs, uint ch)
+{
+ XCharStruct *xcs = 0;
+ unsigned char r = ch>>8;
+ unsigned char c = ch&0xff;
+ if (xfs->per_char &&
+ r >= xfs->min_byte1 &&
+ r <= xfs->max_byte1 &&
+ c >= xfs->min_char_or_byte2 &&
+ c <= xfs->max_char_or_byte2) {
+ xcs = xfs->per_char + ((r - xfs->min_byte1) *
+ (xfs->max_char_or_byte2 -
+ xfs->min_char_or_byte2 + 1)) +
+ (c - xfs->min_char_or_byte2);
+ if (xcs->width == 0 && xcs->ascent == 0 && xcs->descent == 0)
+ xcs = 0;
+ }
+ return xcs;
+}
+
+QFontEngineXLFD::QFontEngineXLFD(XFontStruct *fs, const QByteArray &name, int mib)
+ : _fs(fs), _name(name), _codec(0), _cmap(mib)
+{
+ if (_cmap) _codec = QTextCodec::codecForMib(_cmap);
+
+ cache_cost = (((fs->max_byte1 - fs->min_byte1) *
+ (fs->max_char_or_byte2 - fs->min_char_or_byte2 + 1)) +
+ fs->max_char_or_byte2 - fs->min_char_or_byte2);
+ cache_cost = ((fs->max_bounds.ascent + fs->max_bounds.descent) *
+ (fs->max_bounds.width * cache_cost / 8));
+ lbearing = SHRT_MIN;
+ rbearing = SHRT_MIN;
+ face_id.index = -1;
+ freetype = 0;
+ synth = 0;
+}
+
+QFontEngineXLFD::~QFontEngineXLFD()
+{
+ XFreeFont(QX11Info::display(), _fs);
+ _fs = 0;
+#ifndef QT_NO_FREETYPE
+ if (freetype)
+ freetype->release(face_id);
+#endif
+}
+
+bool QFontEngineXLFD::stringToCMap(const QChar *s, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const
+{
+ if (*nglyphs < len) {
+ *nglyphs = len;
+ return false;
+ }
+
+ // filter out surrogates, we can't handle them anyway with XLFD fonts
+ QVarLengthArray<ushort> _s(len);
+ QChar *str = (QChar *)_s.data();
+ for (int i = 0; i < len; ++i) {
+ if (i < len - 1
+ && s[i].unicode() >= 0xd800 && s[i].unicode() < 0xdc00
+ && s[i+1].unicode() >= 0xdc00 && s[i].unicode() < 0xe000) {
+ *str = QChar();
+ ++i;
+ } else {
+ *str = s[i];
+ }
+ ++str;
+ }
+
+ len = str - (QChar *)_s.data();
+ str = (QChar *)_s.data();
+
+ bool mirrored = flags & QTextEngine::RightToLeft;
+ if (_codec) {
+ bool haveNbsp = false;
+ for (int i = 0; i < len; i++)
+ if (str[i].unicode() == 0xa0) {
+ haveNbsp = true;
+ break;
+ }
+
+ QVarLengthArray<unsigned short> ch(len);
+ QChar *chars = (QChar *)ch.data();
+ if (haveNbsp || mirrored) {
+ for (int i = 0; i < len; i++)
+ chars[i] = (str[i].unicode() == 0xa0 ? 0x20 :
+ (mirrored ? QChar::mirroredChar(str[i].unicode()) : str[i].unicode()));
+ } else {
+ for (int i = 0; i < len; i++)
+ chars[i] = str[i].unicode();
+ }
+ QTextCodec::ConverterState state;
+ state.flags = QTextCodec::ConvertInvalidToNull;
+ QByteArray ba = _codec->fromUnicode(chars, len, &state);
+ if (ba.length() == 2*len) {
+ // double byte encoding
+ const uchar *data = (const uchar *)ba.constData();
+ for (int i = 0; i < len; i++) {
+ glyphs->glyphs[i] = ((ushort)data[0] << 8) + data[1];
+ data += 2;
+ }
+ } else {
+ const uchar *data = (const uchar *)ba.constData();
+ for (int i = 0; i < len; i++)
+ glyphs->glyphs[i] = (ushort)data[i];
+ }
+ } else {
+ int i = len;
+ const QChar *c = str + len;
+ if (mirrored) {
+ while (c != str)
+ glyphs->glyphs[--i] = (--c)->unicode() == 0xa0 ? 0x20 : QChar::mirroredChar(c->unicode());
+ } else {
+ while (c != str)
+ glyphs->glyphs[--i] = (--c)->unicode() == 0xa0 ? 0x20 : c->unicode();
+ }
+ }
+ *nglyphs = len;
+ glyphs->numGlyphs = len;
+
+ if (!(flags & QTextEngine::GlyphIndicesOnly))
+ recalcAdvances(glyphs, flags);
+ return true;
+}
+
+void QFontEngineXLFD::recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFlags /*flags*/) const
+{
+ int i = glyphs->numGlyphs;
+ XCharStruct *xcs;
+ // inlined for better performance
+ if (!_fs->per_char) {
+ xcs = &_fs->min_bounds;
+ while (i != 0) {
+ --i;
+ const unsigned char r = glyphs->glyphs[i] >> 8;
+ const unsigned char c = glyphs->glyphs[i] & 0xff;
+ if (r >= _fs->min_byte1 &&
+ r <= _fs->max_byte1 &&
+ c >= _fs->min_char_or_byte2 &&
+ c <= _fs->max_char_or_byte2) {
+ glyphs->advances_x[i] = xcs->width;
+ } else {
+ glyphs->glyphs[i] = 0;
+ }
+ }
+ }
+ else if (!_fs->max_byte1) {
+ XCharStruct *base = _fs->per_char - _fs->min_char_or_byte2;
+ while (i != 0) {
+ unsigned int gl = glyphs->glyphs[--i];
+ xcs = (gl >= _fs->min_char_or_byte2 && gl <= _fs->max_char_or_byte2) ?
+ base + gl : 0;
+ if (!xcs || (!xcs->width && !xcs->ascent && !xcs->descent)) {
+ glyphs->glyphs[i] = 0;
+ } else {
+ glyphs->advances_x[i] = xcs->width;
+ }
+ }
+ }
+ else {
+ while (i != 0) {
+ xcs = charStruct(_fs, glyphs->glyphs[--i]);
+ if (!xcs) {
+ glyphs->glyphs[i] = 0;
+ } else {
+ glyphs->advances_x[i] = xcs->width;
+ }
+ }
+ }
+}
+
+glyph_metrics_t QFontEngineXLFD::boundingBox(const QGlyphLayout &glyphs)
+{
+ int i;
+
+ glyph_metrics_t overall;
+ // initialize with line height, we get the same behaviour on all platforms
+ overall.y = -ascent();
+ overall.height = ascent() + descent() + 1;
+ QFixed ymax;
+ QFixed xmax;
+ for (i = 0; i < glyphs.numGlyphs; i++) {
+ XCharStruct *xcs = charStruct(_fs, glyphs.glyphs[i]);
+ if (xcs) {
+ QFixed x = overall.xoff + glyphs.offsets[i].x + xcs->lbearing;
+ QFixed y = overall.yoff + glyphs.offsets[i].y - xcs->ascent;
+ overall.x = qMin(overall.x, x);
+ overall.y = qMin(overall.y, y);
+ // XCharStruct::rbearing is defined as distance from left edge to rightmost pixel
+ xmax = qMax(xmax, overall.xoff + glyphs.offsets[i].x + xcs->rbearing);
+ ymax = qMax(ymax, y + xcs->ascent + xcs->descent);
+ overall.xoff += glyphs.advances_x[i] + QFixed::fromFixed(glyphs.justifications[i].space_18d6);
+ } else {
+ QFixed size = _fs->ascent;
+ overall.x = qMin(overall.x, overall.xoff);
+ overall.y = qMin(overall.y, overall.yoff - size);
+ ymax = qMax(ymax, overall.yoff);
+ overall.xoff += size;
+ xmax = qMax(xmax, overall.xoff);
+ }
+ }
+ overall.height = qMax(overall.height, ymax - overall.y);
+ overall.width = xmax - overall.x;
+
+ return overall;
+}
+
+glyph_metrics_t QFontEngineXLFD::boundingBox(glyph_t glyph)
+{
+ glyph_metrics_t gm;
+ XCharStruct *xcs = charStruct(_fs, glyph);
+ if (xcs) {
+ // XCharStruct::rbearing is defined as distance from left edge to rightmost pixel
+ // XCharStruct::width is defined as the advance
+ gm = glyph_metrics_t(xcs->lbearing, -xcs->ascent, xcs->rbearing- xcs->lbearing, xcs->ascent + xcs->descent,
+ xcs->width, 0);
+ } else {
+ QFixed size = ascent();
+ gm = glyph_metrics_t(0, size, size, size, size, 0);
+ }
+ return gm;
+}
+
+QFixed QFontEngineXLFD::ascent() const
+{
+ return _fs->ascent;
+}
+
+QFixed QFontEngineXLFD::descent() const
+{
+ return (_fs->descent-1);
+}
+
+QFixed QFontEngineXLFD::leading() const
+{
+ QFixed l = QFixed(qMin<int>(_fs->ascent, _fs->max_bounds.ascent)
+ + qMin<int>(_fs->descent, _fs->max_bounds.descent)) * QFixed::fromReal(0.15);
+ return l.ceil();
+}
+
+qreal QFontEngineXLFD::maxCharWidth() const
+{
+ return _fs->max_bounds.width;
+}
+
+
+// Loads the font for the specified script
+static inline int maxIndex(XFontStruct *f) {
+ return (((f->max_byte1 - f->min_byte1) *
+ (f->max_char_or_byte2 - f->min_char_or_byte2 + 1)) +
+ f->max_char_or_byte2 - f->min_char_or_byte2);
+}
+
+qreal QFontEngineXLFD::minLeftBearing() const
+{
+ if (lbearing == SHRT_MIN) {
+ if (_fs->per_char) {
+ XCharStruct *cs = _fs->per_char;
+ int nc = maxIndex(_fs) + 1;
+ int mx = cs->lbearing;
+
+ for (int c = 1; c < nc; c++) {
+ // ignore the bearings for characters whose ink is
+ // completely outside the normal bounding box
+ if ((cs[c].lbearing <= 0 && cs[c].rbearing <= 0) ||
+ (cs[c].lbearing >= cs[c].width && cs[c].rbearing >= cs[c].width))
+ continue;
+
+ int nmx = cs[c].lbearing;
+
+ if (nmx < mx)
+ mx = nmx;
+ }
+
+ ((QFontEngineXLFD *)this)->lbearing = mx;
+ } else
+ ((QFontEngineXLFD *)this)->lbearing = _fs->min_bounds.lbearing;
+ }
+ return lbearing;
+}
+
+qreal QFontEngineXLFD::minRightBearing() const
+{
+ if (rbearing == SHRT_MIN) {
+ if (_fs->per_char) {
+ XCharStruct *cs = _fs->per_char;
+ int nc = maxIndex(_fs) + 1;
+ int mx = cs->rbearing;
+
+ for (int c = 1; c < nc; c++) {
+ // ignore the bearings for characters whose ink is
+ // completely outside the normal bounding box
+ if ((cs[c].lbearing <= 0 && cs[c].rbearing <= 0) ||
+ (cs[c].lbearing >= cs[c].width && cs[c].rbearing >= cs[c].width))
+ continue;
+
+ int nmx = cs[c].rbearing;
+
+ if (nmx < mx)
+ mx = nmx;
+ }
+
+ ((QFontEngineXLFD *)this)->rbearing = mx;
+ } else
+ ((QFontEngineXLFD *)this)->rbearing = _fs->min_bounds.rbearing;
+ }
+ return rbearing;
+}
+
+const char *QFontEngineXLFD::name() const
+{
+ return _name;
+}
+
+bool QFontEngineXLFD::canRender(const QChar *string, int len)
+{
+ QVarLengthGlyphLayoutArray glyphs(len);
+ int nglyphs = len;
+ if (stringToCMap(string, len, &glyphs, &nglyphs, 0) == false) {
+ glyphs.resize(nglyphs);
+ stringToCMap(string, len, &glyphs, &nglyphs, 0);
+ }
+
+ bool allExist = true;
+ for (int i = 0; i < nglyphs; i++) {
+ if (!glyphs.glyphs[i] || !charStruct(_fs, glyphs.glyphs[i])) {
+ allExist = false;
+ break;
+ }
+ }
+
+ return allExist;
+}
+
+QBitmap QFontEngineXLFD::bitmapForGlyphs(const QGlyphLayout &glyphs, const glyph_metrics_t &metrics, QTextItem::RenderFlags flags)
+{
+ int w = metrics.width.toInt();
+ int h = metrics.height.toInt();
+ if (w <= 0 || h <= 0)
+ return QBitmap();
+
+ QPlatformPixmap *data = new QX11PlatformPixmap(QPlatformPixmap::BitmapType);
+ data->resize(w, h);
+ QPixmap bm(data);
+ QPainter p(&bm);
+ p.fillRect(0, 0, w, h, Qt::color0);
+ p.setPen(Qt::color1);
+
+ QTextItemInt item;
+ item.flags = flags;
+ item.ascent = -metrics.y;
+ item.descent = metrics.height - item.ascent;
+ item.width = metrics.width;
+ item.chars = 0;
+ item.num_chars = 0;
+ item.logClusters = 0;
+ item.glyphs = glyphs;
+ item.fontEngine = this;
+ item.f = 0;
+
+ p.drawTextItem(QPointF(-metrics.x.toReal(), item.ascent.toReal()), item);
+ p.end();
+
+ return QBitmap(bm);
+}
+
+void QFontEngineXLFD::addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs, QPainterPath *path, QTextItem::RenderFlags flags)
+{
+ // cannot use QFontEngine::addBitmapFontToPath(), since we don't
+ // have direct access to the glyph bitmaps, so we have to draw
+ // onto a QBitmap, then convert to QImage, then to path
+ glyph_metrics_t metrics = boundingBox(glyphs);
+
+ QImage image = bitmapForGlyphs(glyphs, metrics, flags).toImage();
+ if (image.isNull())
+ return;
+
+ image = image.convertToFormat(QImage::Format_Mono);
+ const uchar *image_data = image.bits();
+ uint bpl = image.bytesPerLine();
+ // from qfontengine.cpp
+ extern void qt_addBitmapToPath(qreal x0, qreal y0, const uchar *image_data,
+ int bpl, int w, int h, QPainterPath *path);
+ qt_addBitmapToPath(x, y + metrics.y.toReal(), image_data, bpl, image.width(), image.height(), path);
+}
+
+QFontEngine::FaceId QFontEngineXLFD::faceId() const
+{
+#ifndef QT_NO_FREETYPE
+ if (face_id.index == -1) {
+ face_id = fontFile(_name, &freetype, &synth);
+ if (_codec)
+ face_id.encoding = _codec->mibEnum();
+ if (freetype) {
+ const_cast<QFontEngineXLFD *>(this)->fsType = freetype->fsType();
+ } else {
+ face_id.index = 0;
+ face_id.filename = '-' + QFontEngine::properties().postscriptName;
+ }
+ }
+#endif
+
+ return face_id;
+}
+
+QFontEngine::Properties QFontEngineXLFD::properties() const
+{
+ if (face_id.index == -1)
+ (void)faceId();
+
+#ifndef QT_NO_FREETYPE
+ if (freetype)
+ return freetype->properties();
+#endif
+ return QFontEngine::properties();
+}
+
+void QFontEngineXLFD::getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics)
+{
+ if (face_id.index == -1)
+ (void)faceId();
+#ifndef QT_NO_FREETYPE
+ if (!freetype)
+#endif
+ {
+ QFontEngine::getUnscaledGlyph(glyph, path, metrics);
+ return;
+ }
+
+#ifndef QT_NO_FREETYPE
+ freetype->lock();
+
+ FT_Face face = freetype->face;
+ FT_Set_Char_Size(face, face->units_per_EM << 6, face->units_per_EM << 6, 0, 0);
+ freetype->xsize = face->units_per_EM << 6;
+ freetype->ysize = face->units_per_EM << 6;
+ FT_Set_Transform(face, 0, 0);
+ glyph = glyphIndexToFreetypeGlyphIndex(glyph);
+ FT_Load_Glyph(face, glyph, FT_LOAD_NO_BITMAP);
+
+ int left = face->glyph->metrics.horiBearingX;
+ int right = face->glyph->metrics.horiBearingX + face->glyph->metrics.width;
+ int top = face->glyph->metrics.horiBearingY;
+ int bottom = face->glyph->metrics.horiBearingY - face->glyph->metrics.height;
+
+ QFixedPoint p;
+ p.x = 0;
+ p.y = 0;
+ metrics->width = QFixed::fromFixed(right-left);
+ metrics->height = QFixed::fromFixed(top-bottom);
+ metrics->x = QFixed::fromFixed(left);
+ metrics->y = QFixed::fromFixed(-top);
+ metrics->xoff = QFixed::fromFixed(face->glyph->advance.x);
+
+ if (!FT_IS_SCALABLE(freetype->face))
+ QFreetypeFace::addBitmapToPath(face->glyph, p, path);
+ else
+ QFreetypeFace::addGlyphToPath(face, face->glyph, p, path, face->units_per_EM << 6, face->units_per_EM << 6);
+
+ FT_Set_Transform(face, &freetype->matrix, 0);
+ freetype->unlock();
+#endif // QT_NO_FREETYPE
+}
+
+
+bool QFontEngineXLFD::getSfntTableData(uint tag, uchar *buffer, uint *length) const
+{
+#ifndef QT_NO_FREETYPE
+ if (face_id.index == -1)
+ (void)faceId();
+ if (!freetype)
+ return false;
+ return freetype->getSfntTable(tag, buffer, length);
+#else
+ Q_UNUSED(tag);
+ Q_UNUSED(buffer);
+ Q_UNUSED(length);
+ return false;
+#endif
+}
+
+int QFontEngineXLFD::synthesized() const
+{
+ return synth;
+}
+
+QImage QFontEngineXLFD::alphaMapForGlyph(glyph_t glyph)
+{
+ glyph_metrics_t metrics = boundingBox(glyph);
+
+/*
+ printf("a) w=%.2f, h=%.2f, xoff=%.2f, yoff=%.2f, x=%.2f, y=%.2f\n",
+ metrics.width.toReal(),
+ metrics.height.toReal(),
+ metrics.xoff.toReal(),
+ metrics.yoff.toReal(),
+ metrics.x.toReal(),
+ metrics.y.toReal());
+*/
+
+ QGlyphLayoutArray<1> glyphs;
+ glyphs.glyphs[0] = glyph;
+
+ QImage image = bitmapForGlyphs(glyphs, metrics).toImage();
+//image.save(QString::fromLatin1("x11cache-%1.png").arg((int)glyph));
+
+ image = image.convertToFormat(QImage::Format_Indexed8);
+ QVector<QRgb> colors(256);
+ for (int i = 0; i < 256; ++i)
+ colors[i] = qRgba(0, 0, 0, i);
+ image.setColorTable(colors);
+
+ int width = image.width();
+ int height = image.height();
+ for (int y = 0; y < height; ++y) {
+ uchar *bits = image.scanLine(y);
+ for (int x = 0; x < width; ++x)
+ bits[x] = ~(bits[x]-1);
+ }
+
+ return image;
+}
+
+#ifndef QT_NO_FREETYPE
+
+FT_Face QFontEngineXLFD::non_locked_face() const
+{
+ return freetype ? freetype->face : 0;
+}
+
+uint QFontEngineXLFD::toUnicode(glyph_t g) const
+{
+ if (_codec) {
+ QTextCodec::ConverterState state;
+ state.flags = QTextCodec::ConvertInvalidToNull;
+ uchar data[2];
+ int l = 1;
+ if (g > 255) {
+ data[0] = (g >> 8);
+ data[1] = (g & 255);
+ l = 2;
+ } else {
+ data[0] = g;
+ }
+ QString s = _codec->toUnicode((char *)data, l, &state);
+ Q_ASSERT(s.length() == 1);
+ g = s.at(0).unicode();
+ }
+ return g;
+}
+
+glyph_t QFontEngineXLFD::glyphIndexToFreetypeGlyphIndex(glyph_t g) const
+{
+ return FT_Get_Char_Index(freetype->face, toUnicode(g));
+}
+#endif
+
+#ifndef QT_NO_FONTCONFIG
+
+// ------------------------------------------------------------------
+// Multi FT engine
+// ------------------------------------------------------------------
+
+static QFontEngine *engineForPattern(FcPattern *match, const QFontDef &request, int screen)
+{
+ QFontEngineX11FT *engine = new QFontEngineX11FT(match, request, screen);
+ if (!engine->invalid())
+ return engine;
+
+ delete engine;
+ QFontEngine *fe = new QFontEngineBox(request.pixelSize);
+ fe->fontDef = request;
+ return fe;
+}
+
+QFontEngineMultiFT::QFontEngineMultiFT(QFontEngine *fe, FcPattern *matchedPattern, FcPattern *p, int s, const QFontDef &req)
+ : QFontEngineMulti(2), request(req), pattern(p), fontSet(0), screen(s)
+{
+ firstEnginePattern = FcPatternDuplicate(matchedPattern);
+ engines[0] = fe;
+ engines.at(0)->ref.ref();
+ fontDef = engines[0]->fontDef;
+ cache_cost = 100;
+ firstFontIndex = 1;
+}
+
+QFontEngineMultiFT::~QFontEngineMultiFT()
+{
+ extern QMutex *qt_fontdatabase_mutex();
+ QMutexLocker locker(qt_fontdatabase_mutex());
+
+ FcPatternDestroy(pattern);
+ if (firstEnginePattern)
+ FcPatternDestroy(firstEnginePattern);
+ if (fontSet)
+ FcFontSetDestroy(fontSet);
+}
+
+
+void QFontEngineMultiFT::loadEngine(int at)
+{
+ extern QMutex *qt_fontdatabase_mutex();
+ QMutexLocker locker(qt_fontdatabase_mutex());
+
+ extern QFontDef qt_FcPatternToQFontDef(FcPattern *pattern, const QFontDef &);
+ extern FcFontSet *qt_fontSetForPattern(FcPattern *pattern, const QFontDef &request);
+
+ Q_ASSERT(at > 0);
+ if (!fontSet) {
+ fontSet = qt_fontSetForPattern(pattern, request);
+
+ // it may happen that the fontset of fallbacks consists of only one font. In this case we
+ // have to fall back to the box fontengine as we cannot render the glyph.
+ if (fontSet->nfont == 1 && at == 1 && engines.size() == 2) {
+ Q_ASSERT(engines.at(at) == 0);
+ QFontEngine *fe = new QFontEngineBox(request.pixelSize);
+ fe->fontDef = request;
+ engines[at] = fe;
+ return;
+ }
+
+ if (firstEnginePattern) {
+
+ if (!FcPatternEqual(firstEnginePattern, fontSet->fonts[0]))
+ firstFontIndex = 0;
+
+ FcPatternDestroy(firstEnginePattern);
+ firstEnginePattern = 0;
+ }
+
+ engines.resize(fontSet->nfont + 1 - firstFontIndex);
+ }
+ Q_ASSERT(at < engines.size());
+ Q_ASSERT(engines.at(at) == 0);
+
+ FcPattern *match = FcFontRenderPrepare(NULL, pattern, fontSet->fonts[at + firstFontIndex - 1]);
+ QFontDef fontDef = qt_FcPatternToQFontDef(match, this->request);
+
+ // note: we use -1 for the script to make sure that we keep real
+ // FT engines separate from Multi engines in the font cache
+ QFontCache::Key key(fontDef, -1, screen);
+ QFontEngine *fontEngine = QFontCache::instance()->findEngine(key);
+ if (!fontEngine) {
+ fontEngine = engineForPattern(match, request, screen);
+ QFontCache::instance()->insertEngine(key, fontEngine);
+ }
+ FcPatternDestroy(match);
+ fontEngine->ref.ref();
+ engines[at] = fontEngine;
+}
+
+// ------------------------------------------------------------------
+// X11 FT engine
+// ------------------------------------------------------------------
+
+
+
+Q_WIDGETS_EXPORT void qt_x11ft_convert_pattern(FcPattern *pattern, QByteArray *file_name, int *index, bool *antialias)
+{
+ FcChar8 *fileName;
+ FcPatternGetString(pattern, FC_FILE, 0, &fileName);
+ *file_name = (const char *)fileName;
+ if (!FcPatternGetInteger(pattern, FC_INDEX, 0, index))
+ index = 0;
+ FcBool b;
+ if (FcPatternGetBool(pattern, FC_ANTIALIAS, 0, &b) == FcResultMatch)
+ *antialias = b;
+}
+
+
+QFontEngineX11FT::QFontEngineX11FT(FcPattern *pattern, const QFontDef &fd, int screen)
+ : QFontEngineFT(fd)
+{
+// FcPatternPrint(pattern);
+
+ bool antialias = X11->fc_antialias;
+ QByteArray file_name;
+ int face_index;
+ qt_x11ft_convert_pattern(pattern, &file_name, &face_index, &antialias);
+ QFontEngine::FaceId face_id;
+ face_id.filename = file_name;
+ face_id.index = face_index;
+
+ canUploadGlyphsToServer = QApplication::testAttribute(Qt::AA_X11InitThreads) || (qApp->thread() == QThread::currentThread());
+
+ subpixelType = Subpixel_None;
+ if (antialias) {
+ int subpixel = X11->display ? X11->screens[screen].subpixel : FC_RGBA_UNKNOWN;
+ if (subpixel == FC_RGBA_UNKNOWN)
+ (void) FcPatternGetInteger(pattern, FC_RGBA, 0, &subpixel);
+ if (!antialias || subpixel == FC_RGBA_UNKNOWN)
+ subpixel = FC_RGBA_NONE;
+
+ switch (subpixel) {
+ case FC_RGBA_NONE: subpixelType = Subpixel_None; break;
+ case FC_RGBA_RGB: subpixelType = Subpixel_RGB; break;
+ case FC_RGBA_BGR: subpixelType = Subpixel_BGR; break;
+ case FC_RGBA_VRGB: subpixelType = Subpixel_VRGB; break;
+ case FC_RGBA_VBGR: subpixelType = Subpixel_VBGR; break;
+ default: break;
+ }
+ }
+
+ if (fd.hintingPreference != QFont::PreferDefaultHinting) {
+ switch (fd.hintingPreference) {
+ case QFont::PreferNoHinting:
+ default_hint_style = HintNone;
+ break;
+ case QFont::PreferVerticalHinting:
+ default_hint_style = HintLight;
+ break;
+ case QFont::PreferFullHinting:
+ default:
+ default_hint_style = HintFull;
+ break;
+ }
+ }
+#ifdef FC_HINT_STYLE
+ else {
+ int hint_style = 0;
+ // Try to use Xft.hintstyle from XDefaults first if running in GNOME, to match
+ // the behavior of cairo
+ if (X11->fc_hint_style > -1 && X11->desktopEnvironment == DE_GNOME)
+ hint_style = X11->fc_hint_style;
+ else if (FcPatternGetInteger (pattern, FC_HINT_STYLE, 0, &hint_style) == FcResultNoMatch
+ && X11->fc_hint_style > -1)
+ hint_style = X11->fc_hint_style;
+
+ switch (hint_style) {
+ case FC_HINT_NONE:
+ default_hint_style = HintNone;
+ break;
+ case FC_HINT_SLIGHT:
+ default_hint_style = HintLight;
+ break;
+ case FC_HINT_MEDIUM:
+ default_hint_style = HintMedium;
+ break;
+ default:
+ default_hint_style = HintFull;
+ break;
+ }
+ }
+#endif
+
+#if defined(FC_AUTOHINT) && defined(FT_LOAD_FORCE_AUTOHINT)
+ {
+ bool autohint = false;
+
+ FcBool b;
+ if (FcPatternGetBool(pattern, FC_AUTOHINT, 0, &b) == FcResultMatch)
+ autohint = b;
+
+ if (autohint)
+ default_load_flags |= FT_LOAD_FORCE_AUTOHINT;
+ }
+#endif
+
+#if defined(FC_LCD_FILTER) && defined(FT_LCD_FILTER_H)
+ {
+ int filter = FC_LCD_FILTER_NONE;
+ if (FcPatternGetInteger(pattern, FC_LCD_FILTER, 0, &filter) == FcResultMatch) {
+ switch (filter) {
+ case FC_LCD_FILTER_NONE:
+ lcdFilterType = FT_LCD_FILTER_NONE;
+ break;
+ case FC_LCD_FILTER_DEFAULT:
+ lcdFilterType = FT_LCD_FILTER_DEFAULT;
+ break;
+ case FC_LCD_FILTER_LIGHT:
+ lcdFilterType = FT_LCD_FILTER_LIGHT;
+ break;
+ case FC_LCD_FILTER_LEGACY:
+ lcdFilterType = FT_LCD_FILTER_LEGACY;
+ break;
+ default:
+ // new unknown lcd filter type?!
+ break;
+ }
+ }
+ }
+#endif
+
+#ifdef FC_EMBEDDED_BITMAP
+ {
+ FcBool b;
+ if (FcPatternGetBool(pattern, FC_EMBEDDED_BITMAP, 0, &b) == FcResultMatch)
+ embeddedbitmap = b;
+ }
+#endif
+
+ GlyphFormat defaultFormat = Format_None;
+
+#ifndef QT_NO_XRENDER
+ if (X11->use_xrender) {
+ int format = PictStandardA8;
+ if (!antialias)
+ format = PictStandardA1;
+ else if (subpixelType == Subpixel_RGB
+ || subpixelType == Subpixel_BGR
+ || subpixelType == Subpixel_VRGB
+ || subpixelType == Subpixel_VBGR)
+ format = PictStandardARGB32;
+ xglyph_format = format;
+
+ if (subpixelType != QFontEngineFT::Subpixel_None)
+ defaultFormat = Format_A32;
+ else if (antialias)
+ defaultFormat = Format_A8;
+ else
+ defaultFormat = Format_Mono;
+ }
+#endif
+
+ if (!init(face_id, antialias, defaultFormat))
+ return;
+
+ if (!freetype->charset) {
+ FcCharSet *cs;
+ FcPatternGetCharSet (pattern, FC_CHARSET, 0, &cs);
+ freetype->charset = FcCharSetCopy(cs);
+ }
+}
+
+QFontEngineX11FT::~QFontEngineX11FT()
+{
+ freeGlyphSets();
+}
+
+unsigned long QFontEngineX11FT::allocateServerGlyphSet()
+{
+#ifndef QT_NO_XRENDER
+ if (!canUploadGlyphsToServer || !X11->use_xrender)
+ return 0;
+ return XRenderCreateGlyphSet(X11->display, XRenderFindStandardFormat(X11->display, xglyph_format));
+#else
+ return 0;
+#endif
+}
+
+void QFontEngineX11FT::freeServerGlyphSet(unsigned long id)
+{
+#ifndef QT_NO_XRENDER
+ if (!id)
+ return;
+ XRenderFreeGlyphSet(X11->display, id);
+#endif
+}
+
+bool QFontEngineX11FT::uploadGlyphToServer(QGlyphSet *set, uint glyphid, Glyph *g, GlyphInfo *info, int glyphDataSize) const
+{
+#ifndef QT_NO_XRENDER
+ if (!canUploadGlyphsToServer)
+ return false;
+ if (g->format == Format_Mono) {
+ /*
+ * swap bit order around; FreeType is always MSBFirst
+ */
+ if (BitmapBitOrder(X11->display) != MSBFirst) {
+ unsigned char *line = g->data;
+ int i = glyphDataSize;
+ while (i--) {
+ unsigned char c;
+ c = *line;
+ c = ((c << 1) & 0xaa) | ((c >> 1) & 0x55);
+ c = ((c << 2) & 0xcc) | ((c >> 2) & 0x33);
+ c = ((c << 4) & 0xf0) | ((c >> 4) & 0x0f);
+ *line++ = c;
+ }
+ }
+ }
+
+ ::Glyph xglyph = glyphid;
+ XRenderAddGlyphs (X11->display, set->id, &xglyph, info, 1, (const char *)g->data, glyphDataSize);
+ delete [] g->data;
+ g->data = 0;
+ g->format = Format_None;
+ g->uploadedToServer = true;
+ return true;
+#else
+ return false;
+#endif
+}
+
+QFontEngine *QFontEngineX11FT::cloneWithSize(qreal pixelSize) const
+{
+ QFontDef fontDef;
+ fontDef.pixelSize = pixelSize;
+ QFontEngineX11FT *fe = new QFontEngineX11FT(fontDef);
+ if (!fe->initFromFontEngine(this)) {
+ delete fe;
+ return 0;
+ } else {
+#ifndef QT_NO_XRENDER
+ fe->xglyph_format = xglyph_format;
+#endif
+ return fe;
+ }
+}
+
+#endif // QT_NO_FONTCONFIG
+
+QT_END_NAMESPACE
diff --git a/src/widgets/platforms/x11/qfontengine_x11_p.h b/src/widgets/platforms/x11/qfontengine_x11_p.h
new file mode 100644
index 0000000000..b12fbc28d4
--- /dev/null
+++ b/src/widgets/platforms/x11/qfontengine_x11_p.h
@@ -0,0 +1,180 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QFONTENGINE_X11_P_H
+#define QFONTENGINE_X11_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+#include <private/qt_x11_p.h>
+
+#include <private/qfontengine_ft_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QFreetypeFace;
+
+// --------------------------------------------------------------------------
+
+class QFontEngineMultiXLFD : public QFontEngineMulti
+{
+public:
+ QFontEngineMultiXLFD(const QFontDef &r, const QList<int> &l, int s);
+ ~QFontEngineMultiXLFD();
+
+ void loadEngine(int at);
+
+private:
+ QList<int> encodings;
+ int screen;
+ QFontDef request;
+};
+
+/**
+ * \internal The font engine for X Logical Font Description (XLFD) fonts, which is for X11 systems without freetype.
+ */
+class QFontEngineXLFD : public QFontEngine
+{
+public:
+ QFontEngineXLFD(XFontStruct *f, const QByteArray &name, int mib);
+ ~QFontEngineXLFD();
+
+ virtual QFontEngine::FaceId faceId() const;
+ QFontEngine::Properties properties() const;
+ virtual void getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics);
+ virtual bool getSfntTableData(uint tag, uchar *buffer, uint *length) const;
+ virtual int synthesized() const;
+
+ virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs,
+ QTextEngine::ShaperFlags flags) const;
+ virtual void recalcAdvances(QGlyphLayout *, QTextEngine::ShaperFlags) const;
+
+ virtual glyph_metrics_t boundingBox(const QGlyphLayout &glyphs);
+ virtual glyph_metrics_t boundingBox(glyph_t glyph);
+
+ virtual void addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs, QPainterPath *path, QTextItem::RenderFlags);
+ virtual QFixed ascent() const;
+ virtual QFixed descent() const;
+ virtual QFixed leading() const;
+ virtual qreal maxCharWidth() const;
+ virtual qreal minLeftBearing() const;
+ virtual qreal minRightBearing() const;
+ virtual QImage alphaMapForGlyph(glyph_t);
+
+ virtual inline Type type() const
+ { return QFontEngine::XLFD; }
+
+ virtual bool canRender(const QChar *string, int len);
+ virtual const char *name() const;
+
+ inline XFontStruct *fontStruct() const
+ { return _fs; }
+
+#ifndef QT_NO_FREETYPE
+ FT_Face non_locked_face() const;
+ glyph_t glyphIndexToFreetypeGlyphIndex(glyph_t g) const;
+#endif
+ uint toUnicode(glyph_t g) const;
+
+private:
+ QBitmap bitmapForGlyphs(const QGlyphLayout &glyphs, const glyph_metrics_t &metrics, QTextItem::RenderFlags flags = 0);
+
+ XFontStruct *_fs;
+ QByteArray _name;
+ QTextCodec *_codec;
+ int _cmap;
+ int lbearing, rbearing;
+ mutable QFontEngine::FaceId face_id;
+ mutable QFreetypeFace *freetype;
+ mutable int synth;
+};
+
+#ifndef QT_NO_FONTCONFIG
+
+class Q_WIDGETS_EXPORT QFontEngineMultiFT : public QFontEngineMulti
+{
+public:
+ QFontEngineMultiFT(QFontEngine *fe, FcPattern *firstEnginePattern, FcPattern *p, int s, const QFontDef &request);
+ ~QFontEngineMultiFT();
+
+ void loadEngine(int at);
+
+private:
+ QFontDef request;
+ FcPattern *pattern;
+ FcPattern *firstEnginePattern;
+ FcFontSet *fontSet;
+ int screen;
+ int firstFontIndex; // first font in fontset
+};
+
+class Q_WIDGETS_EXPORT QFontEngineX11FT : public QFontEngineFT
+{
+public:
+ explicit QFontEngineX11FT(const QFontDef &fontDef) : QFontEngineFT(fontDef) {}
+ explicit QFontEngineX11FT(FcPattern *pattern, const QFontDef &fd, int screen);
+ ~QFontEngineX11FT();
+
+ QFontEngine *cloneWithSize(qreal pixelSize) const;
+
+#ifndef QT_NO_XRENDER
+ int xglyph_format;
+#endif
+
+protected:
+ virtual bool uploadGlyphToServer(QGlyphSet *set, uint glyphid, Glyph *g, GlyphInfo *info, int glyphDataSize) const;
+ virtual unsigned long allocateServerGlyphSet();
+ virtual void freeServerGlyphSet(unsigned long id);
+};
+
+#endif // QT_NO_FONTCONFIG
+
+QT_END_NAMESPACE
+
+#endif // QFONTENGINE_X11_P_H
diff --git a/src/gui/kernel/qkde.cpp b/src/widgets/platforms/x11/qkde.cpp
index b89951b5cd..b89951b5cd 100644
--- a/src/gui/kernel/qkde.cpp
+++ b/src/widgets/platforms/x11/qkde.cpp
diff --git a/src/widgets/platforms/x11/qkde_p.h b/src/widgets/platforms/x11/qkde_p.h
new file mode 100644
index 0000000000..5abe824a72
--- /dev/null
+++ b/src/widgets/platforms/x11/qkde_p.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QKDE_H
+#define QKDE_H
+
+#include <QtCore/qglobal.h>
+#include <QtGui/QPalette>
+#include <QtWidgets/QIcon>
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+#if defined(Q_WS_X11)
+
+
+QT_BEGIN_NAMESPACE
+
+/*!\internal
+ This namespace contains helper function to help KDE integration
+ They are only used if we detect the use of KDE and the KDE platform plugin is not found (old KDE version)
+ Or if the detected KDE version is KDE3
+*/
+namespace QKde {
+ QString kdeHome();
+ QString kdeStyle();
+ QPalette kdePalette();
+ int kdeToolButtonStyle();
+ int kdeToolBarIconSize();
+}
+
+
+QT_END_NAMESPACE
+
+#endif // Q_WS_X11
+#endif // QKDE_H
diff --git a/src/gui/kernel/qkeymapper_x11.cpp b/src/widgets/platforms/x11/qkeymapper_x11.cpp
index 455840f8b2..455840f8b2 100644
--- a/src/gui/kernel/qkeymapper_x11.cpp
+++ b/src/widgets/platforms/x11/qkeymapper_x11.cpp
diff --git a/src/gui/kernel/qkeymapper_x11_p.cpp b/src/widgets/platforms/x11/qkeymapper_x11_p.cpp
index 80352ee797..80352ee797 100644
--- a/src/gui/kernel/qkeymapper_x11_p.cpp
+++ b/src/widgets/platforms/x11/qkeymapper_x11_p.cpp
diff --git a/src/gui/kernel/qmotifdnd_x11.cpp b/src/widgets/platforms/x11/qmotifdnd_x11.cpp
index 77f6ce5827..77f6ce5827 100644
--- a/src/gui/kernel/qmotifdnd_x11.cpp
+++ b/src/widgets/platforms/x11/qmotifdnd_x11.cpp
diff --git a/src/widgets/platforms/x11/qpaintdevice_x11.cpp b/src/widgets/platforms/x11/qpaintdevice_x11.cpp
new file mode 100644
index 0000000000..d7ecb06885
--- /dev/null
+++ b/src/widgets/platforms/x11/qpaintdevice_x11.cpp
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qpaintdevice.h"
+#include "qpainter.h"
+#include "qwidget.h"
+#include "qbitmap.h"
+#include "qapplication.h"
+#include <private/qt_x11_p.h>
+#include "qx11info_x11.h"
+
+QT_BEGIN_NAMESPACE
+
+/*! \internal
+
+ Returns the X11 Drawable of the paint device. 0 is returned if it
+ can't be obtained.
+*/
+
+Drawable Q_WIDGETS_EXPORT qt_x11Handle(const QPaintDevice *pd)
+{
+ if (!pd) return 0;
+ if (pd->devType() == QInternal::Widget)
+ return static_cast<const QWidget *>(pd)->handle();
+ else if (pd->devType() == QInternal::Pixmap)
+ return static_cast<const QPixmap *>(pd)->handle();
+ return 0;
+}
+
+/*!
+ \relates QPaintDevice
+
+ Returns the QX11Info structure for the \a pd paint device. 0 is
+ returned if it can't be obtained.
+*/
+const Q_WIDGETS_EXPORT QX11Info *qt_x11Info(const QPaintDevice *pd)
+{
+ if (!pd) return 0;
+ if (pd->devType() == QInternal::Widget)
+ return &static_cast<const QWidget *>(pd)->x11Info();
+ else if (pd->devType() == QInternal::Pixmap)
+ return &static_cast<const QPixmap *>(pd)->x11Info();
+ return 0;
+}
+
+QT_END_NAMESPACE
diff --git a/src/widgets/platforms/x11/qpaintengine_x11.cpp b/src/widgets/platforms/x11/qpaintengine_x11.cpp
new file mode 100644
index 0000000000..3cb3e3caf7
--- /dev/null
+++ b/src/widgets/platforms/x11/qpaintengine_x11.cpp
@@ -0,0 +1,2499 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qplatformdefs.h"
+
+#include "private/qpixmap_x11_p.h"
+
+#include "qapplication.h"
+#include "qdebug.h"
+#include "qfont.h"
+#include "qwidget.h"
+#include "qbitmap.h"
+#include "qpixmapcache.h"
+#include "qtextcodec.h"
+#include "qcoreevent.h"
+#include "qiodevice.h"
+#include <qmath.h>
+
+#include "qpainter_p.h"
+#include <qtextlayout.h>
+#include <qvarlengtharray.h>
+#include <private/qfont_p.h>
+#include <private/qtextengine_p.h>
+#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"
+#include "qcolormap.h"
+
+#include <private/qpaintengine_p.h>
+#include "qpaintengine_x11_p.h"
+
+#include <private/qt_x11_p.h>
+#include <private/qnumeric_p.h>
+#include <limits.h>
+
+#ifndef QT_NO_XRENDER
+#include <private/qtessellator_p.h>
+#endif
+
+#include <private/qhexstring_p.h>
+
+QT_BEGIN_NAMESPACE
+
+extern Drawable qt_x11Handle(const QPaintDevice *pd);
+extern const QX11Info *qt_x11Info(const QPaintDevice *pd);
+extern QPixmap qt_pixmapForBrush(int brushStyle, bool invert); //in qbrush.cpp
+extern QPixmap qt_toX11Pixmap(const QPixmap &pixmap);
+
+// use the same rounding as in qrasterizer.cpp (6 bit fixed point)
+static const qreal aliasedCoordinateDelta = 0.5 - 0.015625;
+
+#undef X11 // defined in qt_x11_p.h
+/*!
+ Returns the X11 specific pen GC for the painter \a p. Note that
+ QPainter::begin() must be called before this function returns a
+ valid GC.
+*/
+Q_WIDGETS_EXPORT GC qt_x11_get_pen_gc(QPainter *p)
+{
+ if (p && p->paintEngine()
+ && p->paintEngine()->isActive()
+ && p->paintEngine()->type() == QPaintEngine::X11) {
+ return static_cast<QX11PaintEngine *>(p->paintEngine())->d_func()->gc;
+ }
+ return 0;
+}
+
+/*!
+ Returns the X11 specific brush GC for the painter \a p. Note that
+ QPainter::begin() must be called before this function returns a
+ valid GC.
+*/
+Q_WIDGETS_EXPORT GC qt_x11_get_brush_gc(QPainter *p)
+{
+ if (p && p->paintEngine()
+ && p->paintEngine()->isActive()
+ && p->paintEngine()->type() == QPaintEngine::X11) {
+ return static_cast<QX11PaintEngine *>(p->paintEngine())->d_func()->gc_brush;
+ }
+ return 0;
+}
+#define X11 qt_x11Data
+
+#ifndef QT_NO_XRENDER
+static const int compositionModeToRenderOp[QPainter::CompositionMode_Xor + 1] = {
+ PictOpOver, //CompositionMode_SourceOver,
+ PictOpOverReverse, //CompositionMode_DestinationOver,
+ PictOpClear, //CompositionMode_Clear,
+ PictOpSrc, //CompositionMode_Source,
+ PictOpDst, //CompositionMode_Destination,
+ PictOpIn, //CompositionMode_SourceIn,
+ PictOpInReverse, //CompositionMode_DestinationIn,
+ PictOpOut, //CompositionMode_SourceOut,
+ PictOpOutReverse, //CompositionMode_DestinationOut,
+ PictOpAtop, //CompositionMode_SourceAtop,
+ PictOpAtopReverse, //CompositionMode_DestinationAtop,
+ PictOpXor //CompositionMode_Xor
+};
+
+static inline int qpainterOpToXrender(QPainter::CompositionMode mode)
+{
+ Q_ASSERT(mode <= QPainter::CompositionMode_Xor);
+ return compositionModeToRenderOp[mode];
+}
+#endif
+
+// hack, so we don't have to make QRegion::clipRectangles() public or include
+// X11 headers in qregion.h
+Q_WIDGETS_EXPORT void *qt_getClipRects(const QRegion &r, int &num)
+{
+ return r.clipRectangles(num);
+}
+
+static inline void x11SetClipRegion(Display *dpy, GC gc, GC gc2,
+#ifndef QT_NO_XRENDER
+ Picture picture,
+#else
+ Qt::HANDLE picture,
+#endif
+ const QRegion &r)
+{
+ int num;
+ XRectangle *rects = (XRectangle *)qt_getClipRects(r, num);
+
+ if (gc)
+ XSetClipRectangles( dpy, gc, 0, 0, rects, num, YXBanded );
+ if (gc2)
+ XSetClipRectangles( dpy, gc2, 0, 0, rects, num, YXBanded );
+
+#ifndef QT_NO_XRENDER
+ if (picture)
+ XRenderSetPictureClipRectangles(dpy, picture, 0, 0, rects, num);
+#else
+ Q_UNUSED(picture);
+#endif // QT_NO_XRENDER
+}
+
+
+static inline void x11ClearClipRegion(Display *dpy, GC gc, GC gc2,
+#ifndef QT_NO_XRENDER
+ Picture picture
+#else
+ Qt::HANDLE picture
+#endif
+ )
+{
+ if (gc)
+ XSetClipMask(dpy, gc, XNone);
+ if (gc2)
+ XSetClipMask(dpy, gc2, XNone);
+
+#ifndef QT_NO_XRENDER
+ if (picture) {
+ XRenderPictureAttributes attrs;
+ attrs.clip_mask = XNone;
+ XRenderChangePicture (dpy, picture, CPClipMask, &attrs);
+ }
+#else
+ Q_UNUSED(picture);
+#endif // QT_NO_XRENDER
+}
+
+
+#define DITHER_SIZE 16
+static const uchar base_dither_matrix[DITHER_SIZE][DITHER_SIZE] = {
+ { 0,192, 48,240, 12,204, 60,252, 3,195, 51,243, 15,207, 63,255 },
+ { 128, 64,176,112,140, 76,188,124,131, 67,179,115,143, 79,191,127 },
+ { 32,224, 16,208, 44,236, 28,220, 35,227, 19,211, 47,239, 31,223 },
+ { 160, 96,144, 80,172,108,156, 92,163, 99,147, 83,175,111,159, 95 },
+ { 8,200, 56,248, 4,196, 52,244, 11,203, 59,251, 7,199, 55,247 },
+ { 136, 72,184,120,132, 68,180,116,139, 75,187,123,135, 71,183,119 },
+ { 40,232, 24,216, 36,228, 20,212, 43,235, 27,219, 39,231, 23,215 },
+ { 168,104,152, 88,164,100,148, 84,171,107,155, 91,167,103,151, 87 },
+ { 2,194, 50,242, 14,206, 62,254, 1,193, 49,241, 13,205, 61,253 },
+ { 130, 66,178,114,142, 78,190,126,129, 65,177,113,141, 77,189,125 },
+ { 34,226, 18,210, 46,238, 30,222, 33,225, 17,209, 45,237, 29,221 },
+ { 162, 98,146, 82,174,110,158, 94,161, 97,145, 81,173,109,157, 93 },
+ { 10,202, 58,250, 6,198, 54,246, 9,201, 57,249, 5,197, 53,245 },
+ { 138, 74,186,122,134, 70,182,118,137, 73,185,121,133, 69,181,117 },
+ { 42,234, 26,218, 38,230, 22,214, 41,233, 25,217, 37,229, 21,213 },
+ { 170,106,154, 90,166,102,150, 86,169,105,153, 89,165,101,149, 85 }
+};
+
+static QPixmap qt_patternForAlpha(uchar alpha, int screen)
+{
+ QPixmap pm;
+ QString key = QLatin1Literal("$qt-alpha-brush$")
+ % HexString<uchar>(alpha)
+ % HexString<int>(screen);
+
+ if (!QPixmapCache::find(key, pm)) {
+ // #### why not use a mono image here????
+ QImage pattern(DITHER_SIZE, DITHER_SIZE, QImage::Format_ARGB32);
+ pattern.fill(0xffffffff);
+ for (int y = 0; y < DITHER_SIZE; ++y) {
+ for (int x = 0; x < DITHER_SIZE; ++x) {
+ if (base_dither_matrix[x][y] <= alpha)
+ pattern.setPixel(x, y, 0x00000000);
+ }
+ }
+ pm = QBitmap::fromImage(pattern);
+ pm.x11SetScreen(screen);
+ QPixmapCache::insert(key, pm);
+ }
+ return pm;
+}
+
+#if !defined(QT_NO_XRENDER)
+
+class QXRenderTessellator : public QTessellator
+{
+public:
+ QXRenderTessellator() : traps(0), allocated(0), size(0) {}
+ ~QXRenderTessellator() { free(traps); }
+ XTrapezoid *traps;
+ int allocated;
+ int size;
+ void addTrap(const Trapezoid &trap);
+ QRect tessellate(const QPointF *points, int nPoints, bool winding) {
+ size = 0;
+ setWinding(winding);
+ return QTessellator::tessellate(points, nPoints).toRect();
+ }
+ void done() {
+ if (allocated > 64) {
+ free(traps);
+ traps = 0;
+ allocated = 0;
+ }
+ }
+};
+
+void QXRenderTessellator::addTrap(const Trapezoid &trap)
+{
+ if (size == allocated) {
+ allocated = qMax(2*allocated, 64);
+ traps = q_check_ptr((XTrapezoid *)realloc(traps, allocated * sizeof(XTrapezoid)));
+ }
+ traps[size].top = Q27Dot5ToXFixed(trap.top);
+ traps[size].bottom = Q27Dot5ToXFixed(trap.bottom);
+ traps[size].left.p1.x = Q27Dot5ToXFixed(trap.topLeft->x);
+ traps[size].left.p1.y = Q27Dot5ToXFixed(trap.topLeft->y);
+ traps[size].left.p2.x = Q27Dot5ToXFixed(trap.bottomLeft->x);
+ traps[size].left.p2.y = Q27Dot5ToXFixed(trap.bottomLeft->y);
+ traps[size].right.p1.x = Q27Dot5ToXFixed(trap.topRight->x);
+ traps[size].right.p1.y = Q27Dot5ToXFixed(trap.topRight->y);
+ traps[size].right.p2.x = Q27Dot5ToXFixed(trap.bottomRight->x);
+ traps[size].right.p2.y = Q27Dot5ToXFixed(trap.bottomRight->y);
+ ++size;
+}
+
+#endif // !defined(QT_NO_XRENDER)
+
+
+#ifndef QT_NO_XRENDER
+static Picture getPatternFill(int screen, const QBrush &b)
+{
+ if (!X11->use_xrender)
+ return XNone;
+
+ XRenderColor color = X11->preMultiply(b.color());
+ XRenderColor bg_color;
+
+ bg_color = X11->preMultiply(QColor(0, 0, 0, 0));
+
+ for (int i = 0; i < X11->pattern_fill_count; ++i) {
+ if (X11->pattern_fills[i].screen == screen
+ && X11->pattern_fills[i].opaque == false
+ && X11->pattern_fills[i].style == b.style()
+ && X11->pattern_fills[i].color.alpha == color.alpha
+ && X11->pattern_fills[i].color.red == color.red
+ && X11->pattern_fills[i].color.green == color.green
+ && X11->pattern_fills[i].color.blue == color.blue
+ && X11->pattern_fills[i].bg_color.alpha == bg_color.alpha
+ && X11->pattern_fills[i].bg_color.red == bg_color.red
+ && X11->pattern_fills[i].bg_color.green == bg_color.green
+ && X11->pattern_fills[i].bg_color.blue == bg_color.blue)
+ return X11->pattern_fills[i].picture;
+ }
+ // none found, replace one
+ int i = qrand() % 16;
+
+ if (X11->pattern_fills[i].screen != screen && X11->pattern_fills[i].picture) {
+ XRenderFreePicture (X11->display, X11->pattern_fills[i].picture);
+ X11->pattern_fills[i].picture = 0;
+ }
+
+ if (!X11->pattern_fills[i].picture) {
+ Pixmap pixmap = XCreatePixmap (X11->display, RootWindow (X11->display, screen), 8, 8, 32);
+ XRenderPictureAttributes attrs;
+ attrs.repeat = True;
+ X11->pattern_fills[i].picture = XRenderCreatePicture (X11->display, pixmap,
+ XRenderFindStandardFormat(X11->display, PictStandardARGB32),
+ CPRepeat, &attrs);
+ XFreePixmap (X11->display, pixmap);
+ }
+
+ X11->pattern_fills[i].screen = screen;
+ X11->pattern_fills[i].color = color;
+ X11->pattern_fills[i].bg_color = bg_color;
+ X11->pattern_fills[i].opaque = false;
+ X11->pattern_fills[i].style = b.style();
+
+ XRenderFillRectangle(X11->display, PictOpSrc, X11->pattern_fills[i].picture, &bg_color, 0, 0, 8, 8);
+
+ QPixmap pattern(qt_pixmapForBrush(b.style(), true));
+ XRenderPictureAttributes attrs;
+ attrs.repeat = true;
+ XRenderChangePicture(X11->display, pattern.x11PictureHandle(), CPRepeat, &attrs);
+
+ Picture fill_fg = X11->getSolidFill(screen, b.color());
+ XRenderComposite(X11->display, PictOpOver, fill_fg, pattern.x11PictureHandle(),
+ X11->pattern_fills[i].picture,
+ 0, 0, 0, 0, 0, 0, 8, 8);
+
+ return X11->pattern_fills[i].picture;
+}
+
+static void qt_render_bitmap(Display *dpy, int scrn, Picture src, Picture dst,
+ int sx, int sy, int x, int y, int sw, int sh,
+ const QPen &pen)
+{
+ Picture fill_fg = X11->getSolidFill(scrn, pen.color());
+ XRenderComposite(dpy, PictOpOver,
+ fill_fg, src, dst, sx, sy, sx, sy, x, y, sw, sh);
+}
+#endif
+
+void QX11PaintEnginePrivate::init()
+{
+ dpy = 0;
+ scrn = 0;
+ hd = 0;
+ picture = 0;
+ xinfo = 0;
+#ifndef QT_NO_XRENDER
+ current_brush = 0;
+ composition_mode = PictOpOver;
+ tessellator = new QXRenderTessellator;
+#endif
+}
+
+void QX11PaintEnginePrivate::setupAdaptedOrigin(const QPoint &p)
+{
+ if (adapted_pen_origin)
+ XSetTSOrigin(dpy, gc, p.x(), p.y());
+ if (adapted_brush_origin)
+ XSetTSOrigin(dpy, gc_brush, p.x(), p.y());
+}
+
+void QX11PaintEnginePrivate::resetAdaptedOrigin()
+{
+ if (adapted_pen_origin)
+ XSetTSOrigin(dpy, gc, 0, 0);
+ if (adapted_brush_origin)
+ XSetTSOrigin(dpy, gc_brush, 0, 0);
+}
+
+void QX11PaintEnginePrivate::clipPolygon_dev(const QPolygonF &poly, QPolygonF *clipped_poly)
+{
+ int clipped_count = 0;
+ qt_float_point *clipped_points = 0;
+ polygonClipper.clipPolygon((qt_float_point *) poly.data(), poly.size(),
+ &clipped_points, &clipped_count);
+ clipped_poly->resize(clipped_count);
+ for (int i=0; i<clipped_count; ++i)
+ (*clipped_poly)[i] = *((QPointF *)(&clipped_points[i]));
+}
+
+void QX11PaintEnginePrivate::systemStateChanged()
+{
+ Q_Q(QX11PaintEngine);
+ QPainter *painter = q->state ? static_cast<QPainterState *>(q->state)->painter : 0;
+ if (painter && painter->hasClipping()) {
+ if (q->testDirty(QPaintEngine::DirtyTransform))
+ q->updateMatrix(q->state->transform());
+ QPolygonF clip_poly_dev(matrix.map(painter->clipPath().toFillPolygon()));
+ QPolygonF clipped_poly_dev;
+ clipPolygon_dev(clip_poly_dev, &clipped_poly_dev);
+ q->updateClipRegion_dev(QRegion(clipped_poly_dev.toPolygon()), Qt::ReplaceClip);
+ } else {
+ q->updateClipRegion_dev(QRegion(), Qt::NoClip);
+ }
+}
+
+static QPaintEngine::PaintEngineFeatures qt_decide_features()
+{
+ QPaintEngine::PaintEngineFeatures features =
+ QPaintEngine::PrimitiveTransform
+ | QPaintEngine::PatternBrush
+ | QPaintEngine::AlphaBlend
+ | QPaintEngine::PainterPaths
+ | QPaintEngine::RasterOpModes;
+
+ if (X11->use_xrender) {
+ features |= QPaintEngine::Antialiasing;
+ features |= QPaintEngine::PorterDuff;
+ features |= QPaintEngine::MaskedBrush;
+#if 0
+ if (X11->xrender_version > 10) {
+ features |= QPaintEngine::LinearGradientFill;
+ // ###
+ }
+#endif
+ }
+
+ return features;
+}
+
+/*
+ * QX11PaintEngine members
+ */
+
+QX11PaintEngine::QX11PaintEngine()
+ : QPaintEngine(*(new QX11PaintEnginePrivate), qt_decide_features())
+{
+ d_func()->init();
+}
+
+QX11PaintEngine::QX11PaintEngine(QX11PaintEnginePrivate &dptr)
+ : QPaintEngine(dptr, qt_decide_features())
+{
+ d_func()->init();
+}
+
+QX11PaintEngine::~QX11PaintEngine()
+{
+#ifndef QT_NO_XRENDER
+ Q_D(QX11PaintEngine);
+ delete d->tessellator;
+#endif
+}
+
+bool QX11PaintEngine::begin(QPaintDevice *pdev)
+{
+ Q_D(QX11PaintEngine);
+ d->xinfo = qt_x11Info(pdev);
+ QWidget *w = d->pdev->devType() == QInternal::Widget ? static_cast<QWidget *>(d->pdev) : 0;
+ const bool isAlienWidget = w && !w->internalWinId() && w->testAttribute(Qt::WA_WState_Created);
+#ifndef QT_NO_XRENDER
+ if (w) {
+ if (isAlienWidget)
+ d->picture = (::Picture)w->nativeParentWidget()->x11PictureHandle();
+ else
+ d->picture = (::Picture)w->x11PictureHandle();
+ } else if (pdev->devType() == QInternal::Pixmap) {
+ const QPixmap *pm = static_cast<const QPixmap *>(pdev);
+ QX11PlatformPixmap *data = static_cast<QX11PlatformPixmap*>(pm->data.data());
+ if (X11->use_xrender && data->depth() != 32 && data->x11_mask)
+ data->convertToARGB32();
+ d->picture = (::Picture)static_cast<const QPixmap *>(pdev)->x11PictureHandle();
+ }
+#else
+ d->picture = 0;
+#endif
+ d->hd = !isAlienWidget ? qt_x11Handle(pdev) : qt_x11Handle(w->nativeParentWidget());
+
+ Q_ASSERT(d->xinfo != 0);
+ d->dpy = d->xinfo->display(); // get display variable
+ d->scrn = d->xinfo->screen(); // get screen variable
+
+ d->crgn = QRegion();
+ d->gc = XCreateGC(d->dpy, d->hd, 0, 0);
+ d->gc_brush = XCreateGC(d->dpy, d->hd, 0, 0);
+ d->has_alpha_brush = false;
+ d->has_alpha_pen = false;
+ d->has_clipping = false;
+ d->has_complex_xform = false;
+ d->has_scaling_xform = false;
+ d->has_non_scaling_xform = true;
+ d->xform_scale = 1;
+ d->has_custom_pen = false;
+ d->matrix = QTransform();
+ d->pdev_depth = d->pdev->depth();
+ d->render_hints = 0;
+ d->txop = QTransform::TxNone;
+ d->use_path_fallback = false;
+#if !defined(QT_NO_XRENDER)
+ d->composition_mode = PictOpOver;
+#endif
+ d->xlibMaxLinePoints = 32762; // a safe number used to avoid, call to XMaxRequestSize(d->dpy) - 3;
+ d->opacity = 1;
+
+ // Set up the polygon clipper. Note: This will only work in
+ // polyline mode as long as we have a buffer zone, since a
+ // polyline may be clipped into several non-connected polylines.
+ const int BUFFERZONE = 1000;
+ QRect devClipRect(-BUFFERZONE, -BUFFERZONE,
+ pdev->width() + 2*BUFFERZONE, pdev->height() + 2*BUFFERZONE);
+ d->polygonClipper.setBoundingRect(devClipRect);
+
+ if (isAlienWidget) {
+ // Set system clip for alien widgets painting outside the paint event.
+ // This is not a problem with native windows since the windowing system
+ // will handle the clip.
+ QWidgetPrivate *wd = w->d_func();
+ QRegion widgetClip(wd->clipRect());
+ wd->clipToEffectiveMask(widgetClip);
+ wd->subtractOpaqueSiblings(widgetClip);
+ widgetClip.translate(w->mapTo(w->nativeParentWidget(), QPoint()));
+ setSystemClip(widgetClip);
+ }
+
+ QPixmap::x11SetDefaultScreen(d->xinfo->screen());
+
+ if (w && w->testAttribute(Qt::WA_PaintUnclipped)) { // paint direct on device
+ updatePen(QPen(Qt::black));
+ updateBrush(QBrush(Qt::white), QPoint());
+ XSetSubwindowMode(d->dpy, d->gc, IncludeInferiors);
+ XSetSubwindowMode(d->dpy, d->gc_brush, IncludeInferiors);
+#ifndef QT_NO_XRENDER
+ XRenderPictureAttributes attrs;
+ attrs.subwindow_mode = IncludeInferiors;
+ XRenderChangePicture(d->dpy, d->picture, CPSubwindowMode, &attrs);
+#endif
+ }
+
+ setDirty(QPaintEngine::DirtyClipRegion);
+ setDirty(QPaintEngine::DirtyPen);
+ setDirty(QPaintEngine::DirtyBrush);
+ setDirty(QPaintEngine::DirtyBackground);
+
+ return true;
+}
+
+bool QX11PaintEngine::end()
+{
+ Q_D(QX11PaintEngine);
+
+#if !defined(QT_NO_XRENDER)
+ if (d->picture) {
+ // reset clipping/subwindow mode on our render picture
+ XRenderPictureAttributes attrs;
+ attrs.subwindow_mode = ClipByChildren;
+ attrs.clip_mask = XNone;
+ XRenderChangePicture(d->dpy, d->picture, CPClipMask|CPSubwindowMode, &attrs);
+ }
+#endif
+
+ if (d->gc_brush && d->pdev->painters < 2) {
+ XFreeGC(d->dpy, d->gc_brush);
+ d->gc_brush = 0;
+ }
+
+ if (d->gc && d->pdev->painters < 2) {
+ XFreeGC(d->dpy, d->gc);
+ d->gc = 0;
+ }
+
+ // Restore system clip for alien widgets painting outside the paint event.
+ if (d->pdev->devType() == QInternal::Widget && !static_cast<QWidget *>(d->pdev)->internalWinId())
+ setSystemClip(QRegion());
+
+ return true;
+}
+
+static bool clipLine(QLineF *line, const QRect &rect)
+{
+ qreal x1 = line->x1();
+ qreal x2 = line->x2();
+ qreal y1 = line->y1();
+ qreal y2 = line->y2();
+
+ qreal left = rect.x();
+ qreal right = rect.x() + rect.width() - 1;
+ qreal top = rect.y();
+ qreal bottom = rect.y() + rect.height() - 1;
+
+ enum { Left, Right, Top, Bottom };
+ // clip the lines, after cohen-sutherland, see e.g. http://www.nondot.org/~sabre/graphpro/line6.html
+ int p1 = ((x1 < left) << Left)
+ | ((x1 > right) << Right)
+ | ((y1 < top) << Top)
+ | ((y1 > bottom) << Bottom);
+ int p2 = ((x2 < left) << Left)
+ | ((x2 > right) << Right)
+ | ((y2 < top) << Top)
+ | ((y2 > bottom) << Bottom);
+
+ if (p1 & p2)
+ // completely outside
+ return false;
+
+ if (p1 | p2) {
+ qreal dx = x2 - x1;
+ qreal dy = y2 - y1;
+
+ // clip x coordinates
+ if (x1 < left) {
+ y1 += dy/dx * (left - x1);
+ x1 = left;
+ } else if (x1 > right) {
+ y1 -= dy/dx * (x1 - right);
+ x1 = right;
+ }
+ if (x2 < left) {
+ y2 += dy/dx * (left - x2);
+ x2 = left;
+ } else if (x2 > right) {
+ y2 -= dy/dx * (x2 - right);
+ x2 = right;
+ }
+ p1 = ((y1 < top) << Top)
+ | ((y1 > bottom) << Bottom);
+ p2 = ((y2 < top) << Top)
+ | ((y2 > bottom) << Bottom);
+ if (p1 & p2)
+ return false;
+ // clip y coordinates
+ if (y1 < top) {
+ x1 += dx/dy * (top - y1);
+ y1 = top;
+ } else if (y1 > bottom) {
+ x1 -= dx/dy * (y1 - bottom);
+ y1 = bottom;
+ }
+ if (y2 < top) {
+ x2 += dx/dy * (top - y2);
+ y2 = top;
+ } else if (y2 > bottom) {
+ x2 -= dx/dy * (y2 - bottom);
+ y2 = bottom;
+ }
+ *line = QLineF(QPointF(x1, y1), QPointF(x2, y2));
+ }
+ return true;
+}
+
+void QX11PaintEngine::drawLines(const QLine *lines, int lineCount)
+{
+ Q_ASSERT(lines);
+ Q_ASSERT(lineCount);
+ Q_D(QX11PaintEngine);
+ if (d->has_alpha_brush
+ || d->has_alpha_pen
+ || d->has_custom_pen
+ || (d->cpen.widthF() > 0 && d->has_complex_xform
+ && !d->has_non_scaling_xform)
+ || (d->render_hints & QPainter::Antialiasing)) {
+ for (int i = 0; i < lineCount; ++i) {
+ QPainterPath path(lines[i].p1());
+ path.lineTo(lines[i].p2());
+ drawPath(path);
+ }
+ return;
+ }
+
+ if (d->has_pen) {
+ for (int i = 0; i < lineCount; ++i) {
+ QLineF linef;
+ if (d->txop == QTransform::TxNone) {
+ linef = lines[i];
+ } else {
+ linef = d->matrix.map(QLineF(lines[i]));
+ }
+ if (clipLine(&linef, d->polygonClipper.boundingRect())) {
+ int x1 = qRound(linef.x1() + aliasedCoordinateDelta);
+ int y1 = qRound(linef.y1() + aliasedCoordinateDelta);
+ int x2 = qRound(linef.x2() + aliasedCoordinateDelta);
+ int y2 = qRound(linef.y2() + aliasedCoordinateDelta);
+
+ XDrawLine(d->dpy, d->hd, d->gc, x1, y1, x2, y2);
+ }
+ }
+ }
+}
+
+void QX11PaintEngine::drawLines(const QLineF *lines, int lineCount)
+{
+ Q_ASSERT(lines);
+ Q_ASSERT(lineCount);
+ Q_D(QX11PaintEngine);
+ if (d->has_alpha_brush
+ || d->has_alpha_pen
+ || d->has_custom_pen
+ || (d->cpen.widthF() > 0 && d->has_complex_xform
+ && !d->has_non_scaling_xform)
+ || (d->render_hints & QPainter::Antialiasing)) {
+ for (int i = 0; i < lineCount; ++i) {
+ QPainterPath path(lines[i].p1());
+ path.lineTo(lines[i].p2());
+ drawPath(path);
+ }
+ return;
+ }
+
+ if (d->has_pen) {
+ for (int i = 0; i < lineCount; ++i) {
+ QLineF linef = d->matrix.map(lines[i]);
+ if (clipLine(&linef, d->polygonClipper.boundingRect())) {
+ int x1 = qRound(linef.x1() + aliasedCoordinateDelta);
+ int y1 = qRound(linef.y1() + aliasedCoordinateDelta);
+ int x2 = qRound(linef.x2() + aliasedCoordinateDelta);
+ int y2 = qRound(linef.y2() + aliasedCoordinateDelta);
+
+ XDrawLine(d->dpy, d->hd, d->gc, x1, y1, x2, y2);
+ }
+ }
+ }
+}
+
+static inline QLine clipStraightLine(const QRect &clip, const QLine &l)
+{
+ if (l.p1().x() == l.p2().x()) {
+ int x = qBound(clip.left(), l.p1().x(), clip.right());
+ int y1 = qBound(clip.top(), l.p1().y(), clip.bottom());
+ int y2 = qBound(clip.top(), l.p2().y(), clip.bottom());
+
+ return QLine(x, y1, x, y2);
+ } else {
+ Q_ASSERT(l.p1().y() == l.p2().y());
+
+ int x1 = qBound(clip.left(), l.p1().x(), clip.right());
+ int x2 = qBound(clip.left(), l.p2().x(), clip.right());
+ int y = qBound(clip.top(), l.p1().y(), clip.bottom());
+
+ return QLine(x1, y, x2, y);
+ }
+}
+
+void QX11PaintEngine::drawRects(const QRectF *rects, int rectCount)
+{
+ Q_D(QX11PaintEngine);
+ Q_ASSERT(rects);
+ Q_ASSERT(rectCount);
+
+ if (rectCount != 1
+ || d->has_pen
+ || d->has_alpha_brush
+ || d->has_complex_xform
+ || d->has_custom_pen
+ || d->cbrush.style() != Qt::SolidPattern)
+ {
+ QPaintEngine::drawRects(rects, rectCount);
+ return;
+ }
+
+ QPoint alignedOffset;
+ if (d->txop == QTransform::TxTranslate) {
+ QPointF offset(d->matrix.dx(), d->matrix.dy());
+ alignedOffset = offset.toPoint();
+ if (offset != QPointF(alignedOffset)) {
+ QPaintEngine::drawRects(rects, rectCount);
+ return;
+ }
+ }
+
+ const QRectF& r = rects[0];
+ QRect alignedRect = r.toAlignedRect();
+ if (r != QRectF(alignedRect)) {
+ QPaintEngine::drawRects(rects, rectCount);
+ return;
+ }
+ alignedRect.translate(alignedOffset);
+
+ QRect clip(d->polygonClipper.boundingRect());
+ alignedRect = alignedRect.intersected(clip);
+ if (alignedRect.isEmpty())
+ return;
+
+ // simple-case:
+ // the rectangle is pixel-aligned
+ // the fill brush is just a solid non-alpha color
+ // the painter transform is only integer translation
+ // ignore: antialiasing and just XFillRectangles directly
+ XRectangle xrect;
+ xrect.x = short(alignedRect.x());
+ xrect.y = short(alignedRect.y());
+ xrect.width = ushort(alignedRect.width());
+ xrect.height = ushort(alignedRect.height());
+ XFillRectangles(d->dpy, d->hd, d->gc_brush, &xrect, 1);
+}
+
+void QX11PaintEngine::drawRects(const QRect *rects, int rectCount)
+{
+ Q_D(QX11PaintEngine);
+ Q_ASSERT(rects);
+ Q_ASSERT(rectCount);
+
+ if (d->has_alpha_pen
+ || d->has_complex_xform
+ || d->has_custom_pen
+ || (d->render_hints & QPainter::Antialiasing))
+ {
+ for (int i = 0; i < rectCount; ++i) {
+ QPainterPath path;
+ path.addRect(rects[i]);
+ drawPath(path);
+ }
+ return;
+ }
+
+ QRect clip(d->polygonClipper.boundingRect());
+ QPoint offset(qRound(d->matrix.dx()), qRound(d->matrix.dy()));
+#if !defined(QT_NO_XRENDER)
+ ::Picture pict = d->picture;
+
+ if (X11->use_xrender && pict && d->has_brush && d->pdev_depth != 1
+ && (d->has_texture || d->has_alpha_brush))
+ {
+ XRenderColor xc;
+ if (!d->has_texture && !d->has_pattern)
+ xc = X11->preMultiply(d->cbrush.color());
+
+ for (int i = 0; i < rectCount; ++i) {
+ QRect r(rects[i]);
+ if (d->txop == QTransform::TxTranslate)
+ r.translate(offset);
+
+ if (r.width() == 0 || r.height() == 0) {
+ if (d->has_pen) {
+ const QLine l = clipStraightLine(clip, QLine(r.left(), r.top(), r.left() + r.width(), r.top() + r.height()));
+ XDrawLine(d->dpy, d->hd, d->gc, l.p1().x(), l.p1().y(), l.p2().x(), l.p2().y());
+ }
+ continue;
+ }
+
+ r = r.intersected(clip);
+ if (r.isEmpty())
+ continue;
+ if (d->has_texture || d->has_pattern) {
+ XRenderComposite(d->dpy, d->composition_mode, d->current_brush, 0, pict,
+ qRound(r.x() - d->bg_origin.x()), qRound(r.y() - d->bg_origin.y()),
+ 0, 0, r.x(), r.y(), r.width(), r.height());
+ } else {
+ XRenderFillRectangle(d->dpy, d->composition_mode, pict, &xc, r.x(), r.y(), r.width(), r.height());
+ }
+ if (d->has_pen)
+ XDrawRectangle(d->dpy, d->hd, d->gc, r.x(), r.y(), r.width(), r.height());
+ }
+ } else
+#endif // !QT_NO_XRENDER
+ {
+ if (d->has_brush && d->has_pen) {
+ for (int i = 0; i < rectCount; ++i) {
+ QRect r(rects[i]);
+ if (d->txop == QTransform::TxTranslate)
+ r.translate(offset);
+
+ if (r.width() == 0 || r.height() == 0) {
+ const QLine l = clipStraightLine(clip, QLine(r.left(), r.top(), r.left() + r.width(), r.top() + r.height()));
+ XDrawLine(d->dpy, d->hd, d->gc, l.p1().x(), l.p1().y(), l.p2().x(), l.p2().y());
+ continue;
+ }
+
+ r = r.intersected(clip);
+ if (r.isEmpty())
+ continue;
+ d->setupAdaptedOrigin(r.topLeft());
+ XFillRectangle(d->dpy, d->hd, d->gc_brush, r.x(), r.y(), r.width(), r.height());
+ XDrawRectangle(d->dpy, d->hd, d->gc, r.x(), r.y(), r.width(), r.height());
+ }
+ d->resetAdaptedOrigin();
+ } else {
+ QVarLengthArray<XRectangle> xrects(rectCount);
+ int numClipped = rectCount;
+ for (int i = 0; i < rectCount; ++i) {
+ QRect r(rects[i]);
+ if (d->txop == QTransform::TxTranslate)
+ r.translate(offset);
+
+ if (r.width() == 0 || r.height() == 0) {
+ --numClipped;
+ if (d->has_pen) {
+ const QLine l = clipStraightLine(clip, QLine(r.left(), r.top(), r.left() + r.width(), r.top() + r.height()));
+ XDrawLine(d->dpy, d->hd, d->gc, l.p1().x(), l.p1().y(), l.p2().x(), l.p2().y());
+ }
+ continue;
+ }
+
+ r = r.intersected(clip);
+ if (r.isEmpty()) {
+ --numClipped;
+ continue;
+ }
+ xrects[i].x = short(r.x());
+ xrects[i].y = short(r.y());
+ xrects[i].width = ushort(r.width());
+ xrects[i].height = ushort(r.height());
+ }
+ if (numClipped) {
+ d->setupAdaptedOrigin(rects[0].topLeft());
+ if (d->has_brush)
+ XFillRectangles(d->dpy, d->hd, d->gc_brush, xrects.data(), numClipped);
+ else if (d->has_pen)
+ XDrawRectangles(d->dpy, d->hd, d->gc, xrects.data(), numClipped);
+ d->resetAdaptedOrigin();
+ }
+ }
+ }
+}
+
+static inline void setCapStyle(int cap_style, GC gc)
+{
+ ulong mask = GCCapStyle;
+ XGCValues vals;
+ vals.cap_style = cap_style;
+ XChangeGC(X11->display, gc, mask, &vals);
+}
+
+void QX11PaintEngine::drawPoints(const QPoint *points, int pointCount)
+{
+ Q_ASSERT(points);
+ Q_ASSERT(pointCount);
+ Q_D(QX11PaintEngine);
+
+ if (!d->has_pen)
+ return;
+
+ // use the same test here as in drawPath to ensure that we don't use the path fallback
+ // and end up in XDrawLines for pens with width <= 1
+ if (d->cpen.widthF() > 1.0f
+ || (X11->use_xrender && (d->has_alpha_pen || (d->render_hints & QPainter::Antialiasing)))
+ || (!d->cpen.isCosmetic() && d->txop > QTransform::TxTranslate))
+ {
+ Qt::PenCapStyle capStyle = d->cpen.capStyle();
+ if (capStyle == Qt::FlatCap) {
+ setCapStyle(CapProjecting, d->gc);
+ d->cpen.setCapStyle(Qt::SquareCap);
+ }
+ const QPoint *end = points + pointCount;
+ while (points < end) {
+ QPainterPath path;
+ path.moveTo(*points);
+ path.lineTo(points->x()+.005, points->y());
+ drawPath(path);
+ ++points;
+ }
+
+ if (capStyle == Qt::FlatCap) {
+ setCapStyle(CapButt, d->gc);
+ d->cpen.setCapStyle(capStyle);
+ }
+ return;
+ }
+
+ static const int BUF_SIZE = 1024;
+ XPoint xPoints[BUF_SIZE];
+ int i = 0, j = 0;
+ while (i < pointCount) {
+ while (i < pointCount && j < BUF_SIZE) {
+ const QPoint &xformed = d->matrix.map(points[i]);
+ int x = xformed.x();
+ int y = xformed.y();
+ if (x >= SHRT_MIN && y >= SHRT_MIN && x < SHRT_MAX && y < SHRT_MAX) {
+ xPoints[j].x = x;
+ xPoints[j].y = y;
+ ++j;
+ }
+ ++i;
+ }
+ if (j)
+ XDrawPoints(d->dpy, d->hd, d->gc, xPoints, j, CoordModeOrigin);
+
+ j = 0;
+ }
+}
+
+void QX11PaintEngine::drawPoints(const QPointF *points, int pointCount)
+{
+ Q_ASSERT(points);
+ Q_ASSERT(pointCount);
+ Q_D(QX11PaintEngine);
+
+ if (!d->has_pen)
+ return;
+
+ // use the same test here as in drawPath to ensure that we don't use the path fallback
+ // and end up in XDrawLines for pens with width <= 1
+ if (d->cpen.widthF() > 1.0f
+ || (X11->use_xrender && (d->has_alpha_pen || (d->render_hints & QPainter::Antialiasing)))
+ || (!d->cpen.isCosmetic() && d->txop > QTransform::TxTranslate))
+ {
+ Qt::PenCapStyle capStyle = d->cpen.capStyle();
+ if (capStyle == Qt::FlatCap) {
+ setCapStyle(CapProjecting, d->gc);
+ d->cpen.setCapStyle(Qt::SquareCap);
+ }
+
+ const QPointF *end = points + pointCount;
+ while (points < end) {
+ QPainterPath path;
+ path.moveTo(*points);
+ path.lineTo(points->x() + 0.005, points->y());
+ drawPath(path);
+ ++points;
+ }
+ if (capStyle == Qt::FlatCap) {
+ setCapStyle(CapButt, d->gc);
+ d->cpen.setCapStyle(capStyle);
+ }
+ return;
+ }
+
+ static const int BUF_SIZE = 1024;
+ XPoint xPoints[BUF_SIZE];
+ int i = 0, j = 0;
+ while (i < pointCount) {
+ while (i < pointCount && j < BUF_SIZE) {
+ const QPointF &xformed = d->matrix.map(points[i]);
+ int x = qFloor(xformed.x());
+ int y = qFloor(xformed.y());
+
+ if (x >= SHRT_MIN && y >= SHRT_MIN && x < SHRT_MAX && y < SHRT_MAX) {
+ xPoints[j].x = x;
+ xPoints[j].y = y;
+ ++j;
+ }
+ ++i;
+ }
+ if (j)
+ XDrawPoints(d->dpy, d->hd, d->gc, xPoints, j, CoordModeOrigin);
+
+ j = 0;
+ }
+}
+
+QPainter::RenderHints QX11PaintEngine::supportedRenderHints() const
+{
+#if !defined(QT_NO_XRENDER)
+ if (X11->use_xrender)
+ return QPainter::Antialiasing;
+#endif
+ return QFlag(0);
+}
+
+void QX11PaintEngine::updateState(const QPaintEngineState &state)
+{
+ Q_D(QX11PaintEngine);
+ QPaintEngine::DirtyFlags flags = state.state();
+
+
+ if (flags & DirtyOpacity) {
+ d->opacity = state.opacity();
+ // Force update pen/brush as to get proper alpha colors propagated
+ flags |= DirtyPen;
+ flags |= DirtyBrush;
+ }
+
+ if (flags & DirtyTransform) updateMatrix(state.transform());
+ if (flags & DirtyPen) updatePen(state.pen());
+ if (flags & (DirtyBrush | DirtyBrushOrigin)) updateBrush(state.brush(), state.brushOrigin());
+ if (flags & DirtyFont) updateFont(state.font());
+
+ if (state.state() & DirtyClipEnabled) {
+ if (state.isClipEnabled()) {
+ QPolygonF clip_poly_dev(d->matrix.map(painter()->clipPath().toFillPolygon()));
+ QPolygonF clipped_poly_dev;
+ d->clipPolygon_dev(clip_poly_dev, &clipped_poly_dev);
+ updateClipRegion_dev(QRegion(clipped_poly_dev.toPolygon()), Qt::ReplaceClip);
+ } else {
+ updateClipRegion_dev(QRegion(), Qt::NoClip);
+ }
+ }
+
+ if (flags & DirtyClipPath) {
+ QPolygonF clip_poly_dev(d->matrix.map(state.clipPath().toFillPolygon()));
+ QPolygonF clipped_poly_dev;
+ d->clipPolygon_dev(clip_poly_dev, &clipped_poly_dev);
+ updateClipRegion_dev(QRegion(clipped_poly_dev.toPolygon(), state.clipPath().fillRule()),
+ state.clipOperation());
+ } else if (flags & DirtyClipRegion) {
+ extern QPainterPath qt_regionToPath(const QRegion &region);
+ QPainterPath clip_path = qt_regionToPath(state.clipRegion());
+ QPolygonF clip_poly_dev(d->matrix.map(clip_path.toFillPolygon()));
+ QPolygonF clipped_poly_dev;
+ d->clipPolygon_dev(clip_poly_dev, &clipped_poly_dev);
+ updateClipRegion_dev(QRegion(clipped_poly_dev.toPolygon()), state.clipOperation());
+ }
+ if (flags & DirtyHints) updateRenderHints(state.renderHints());
+ if (flags & DirtyCompositionMode) {
+ int function = GXcopy;
+ if (state.compositionMode() >= QPainter::RasterOp_SourceOrDestination) {
+ switch (state.compositionMode()) {
+ case QPainter::RasterOp_SourceOrDestination:
+ function = GXor;
+ break;
+ case QPainter::RasterOp_SourceAndDestination:
+ function = GXand;
+ break;
+ case QPainter::RasterOp_SourceXorDestination:
+ function = GXxor;
+ break;
+ case QPainter::RasterOp_NotSourceAndNotDestination:
+ function = GXnor;
+ break;
+ case QPainter::RasterOp_NotSourceOrNotDestination:
+ function = GXnand;
+ break;
+ case QPainter::RasterOp_NotSourceXorDestination:
+ function = GXequiv;
+ break;
+ case QPainter::RasterOp_NotSource:
+ function = GXcopyInverted;
+ break;
+ case QPainter::RasterOp_SourceAndNotDestination:
+ function = GXandReverse;
+ break;
+ case QPainter::RasterOp_NotSourceAndDestination:
+ function = GXandInverted;
+ break;
+ default:
+ function = GXcopy;
+ }
+ }
+#if !defined(QT_NO_XRENDER)
+ else {
+ d->composition_mode =
+ qpainterOpToXrender(state.compositionMode());
+ }
+#endif
+ XSetFunction(X11->display, d->gc, function);
+ XSetFunction(X11->display, d->gc_brush, function);
+ }
+ d->decidePathFallback();
+ d->decideCoordAdjust();
+}
+
+void QX11PaintEngine::updateRenderHints(QPainter::RenderHints hints)
+{
+ Q_D(QX11PaintEngine);
+ d->render_hints = hints;
+
+#if !defined(QT_NO_XRENDER)
+ if (X11->use_xrender && d->picture) {
+ XRenderPictureAttributes attrs;
+ attrs.poly_edge = (hints & QPainter::Antialiasing) ? PolyEdgeSmooth : PolyEdgeSharp;
+ XRenderChangePicture(d->dpy, d->picture, CPPolyEdge, &attrs);
+ }
+#endif
+}
+
+void QX11PaintEngine::updatePen(const QPen &pen)
+{
+ Q_D(QX11PaintEngine);
+ d->cpen = pen;
+ int cp = CapButt;
+ int jn = JoinMiter;
+ int ps = pen.style();
+
+ if (d->opacity < 1.0) {
+ QColor c = d->cpen.color();
+ c.setAlpha(qRound(c.alpha()*d->opacity));
+ d->cpen.setColor(c);
+ }
+
+ d->has_pen = (ps != Qt::NoPen);
+ d->has_alpha_pen = (pen.color().alpha() != 255);
+
+ switch (pen.capStyle()) {
+ case Qt::SquareCap:
+ cp = CapProjecting;
+ break;
+ case Qt::RoundCap:
+ cp = CapRound;
+ break;
+ case Qt::FlatCap:
+ default:
+ cp = CapButt;
+ break;
+ }
+ switch (pen.joinStyle()) {
+ case Qt::BevelJoin:
+ jn = JoinBevel;
+ break;
+ case Qt::RoundJoin:
+ jn = JoinRound;
+ break;
+ case Qt::MiterJoin:
+ default:
+ jn = JoinMiter;
+ break;
+ }
+
+ d->adapted_pen_origin = false;
+
+ char dashes[10]; // custom pen dashes
+ int dash_len = 0; // length of dash list
+ int xStyle = LineSolid;
+
+ /*
+ We are emulating Windows here. Windows treats cpen.width() == 1
+ (or 0) as a very special case. The fudge variable unifies this
+ case with the general case.
+ */
+ qreal pen_width = pen.widthF();
+ int scale = qRound(pen_width < 1 ? 1 : pen_width);
+ int space = (pen_width < 1 && pen_width > 0 ? 1 : (2 * scale));
+ int dot = 1 * scale;
+ int dash = 4 * scale;
+
+ d->has_custom_pen = false;
+
+ switch (ps) {
+ case Qt::NoPen:
+ case Qt::SolidLine:
+ xStyle = LineSolid;
+ break;
+ case Qt::DashLine:
+ dashes[0] = dash;
+ dashes[1] = space;
+ dash_len = 2;
+ xStyle = LineOnOffDash;
+ break;
+ case Qt::DotLine:
+ dashes[0] = dot;
+ dashes[1] = space;
+ dash_len = 2;
+ xStyle = LineOnOffDash;
+ break;
+ case Qt::DashDotLine:
+ dashes[0] = dash;
+ dashes[1] = space;
+ dashes[2] = dot;
+ dashes[3] = space;
+ dash_len = 4;
+ xStyle = LineOnOffDash;
+ break;
+ case Qt::DashDotDotLine:
+ dashes[0] = dash;
+ dashes[1] = space;
+ dashes[2] = dot;
+ dashes[3] = space;
+ dashes[4] = dot;
+ dashes[5] = space;
+ dash_len = 6;
+ xStyle = LineOnOffDash;
+ break;
+ case Qt::CustomDashLine:
+ d->has_custom_pen = true;
+ break;
+ }
+
+ ulong mask = GCForeground | GCBackground | GCGraphicsExposures | GCLineWidth
+ | GCCapStyle | GCJoinStyle | GCLineStyle;
+ XGCValues vals;
+ vals.graphics_exposures = false;
+ if (d->pdev_depth == 1) {
+ vals.foreground = qGray(pen.color().rgb()) > 127 ? 0 : 1;
+ vals.background = qGray(QColor(Qt::transparent).rgb()) > 127 ? 0 : 1;
+ } else if (d->pdev->devType() == QInternal::Pixmap && d->pdev_depth == 32
+ && X11->use_xrender) {
+ vals.foreground = pen.color().rgba();
+ vals.background = QColor(Qt::transparent).rgba();
+ } else {
+ QColormap cmap = QColormap::instance(d->scrn);
+ vals.foreground = cmap.pixel(pen.color());
+ vals.background = cmap.pixel(QColor(Qt::transparent));
+ }
+
+
+ vals.line_width = qRound(pen.widthF());
+ vals.cap_style = cp;
+ vals.join_style = jn;
+ vals.line_style = xStyle;
+
+ XChangeGC(d->dpy, d->gc, mask, &vals);
+
+ if (dash_len) { // make dash list
+ XSetDashes(d->dpy, d->gc, 0, dashes, dash_len);
+ }
+
+ if (!d->has_clipping) { // if clipping is set the paintevent clip region is merged with the clip region
+ QRegion sysClip = systemClip();
+ if (!sysClip.isEmpty())
+ x11SetClipRegion(d->dpy, d->gc, 0, d->picture, sysClip);
+ else
+ x11ClearClipRegion(d->dpy, d->gc, 0, d->picture);
+ }
+}
+
+void QX11PaintEngine::updateBrush(const QBrush &brush, const QPointF &origin)
+{
+ Q_D(QX11PaintEngine);
+ d->cbrush = brush;
+ d->bg_origin = origin;
+ d->adapted_brush_origin = false;
+#if !defined(QT_NO_XRENDER)
+ d->current_brush = 0;
+#endif
+ if (d->opacity < 1.0) {
+ QColor c = d->cbrush.color();
+ c.setAlpha(qRound(c.alpha()*d->opacity));
+ d->cbrush.setColor(c);
+ }
+
+ int s = FillSolid;
+ int bs = d->cbrush.style();
+ d->has_brush = (bs != Qt::NoBrush);
+ d->has_pattern = bs >= Qt::Dense1Pattern && bs <= Qt::DiagCrossPattern;
+ d->has_texture = bs == Qt::TexturePattern;
+ d->has_alpha_brush = brush.color().alpha() != 255;
+ d->has_alpha_texture = d->has_texture && d->cbrush.texture().hasAlphaChannel();
+
+ ulong mask = GCForeground | GCBackground | GCGraphicsExposures
+ | GCLineStyle | GCCapStyle | GCJoinStyle | GCFillStyle;
+ XGCValues vals;
+ vals.graphics_exposures = false;
+ if (d->pdev_depth == 1) {
+ vals.foreground = qGray(d->cbrush.color().rgb()) > 127 ? 0 : 1;
+ vals.background = qGray(QColor(Qt::transparent).rgb()) > 127 ? 0 : 1;
+ } else if (X11->use_xrender && d->pdev->devType() == QInternal::Pixmap
+ && d->pdev_depth == 32) {
+ vals.foreground = d->cbrush.color().rgba();
+ vals.background = QColor(Qt::transparent).rgba();
+ } else {
+ QColormap cmap = QColormap::instance(d->scrn);
+ vals.foreground = cmap.pixel(d->cbrush.color());
+ vals.background = cmap.pixel(QColor(Qt::transparent));
+
+ if (!X11->use_xrender && d->has_brush && !d->has_pattern && !brush.isOpaque()) {
+ QPixmap pattern = qt_patternForAlpha(brush.color().alpha(), d->scrn);
+ mask |= GCStipple;
+ vals.stipple = pattern.handle();
+ s = FillStippled;
+ d->adapted_brush_origin = true;
+ }
+ }
+ vals.cap_style = CapButt;
+ vals.join_style = JoinMiter;
+ vals.line_style = LineSolid;
+
+ if (d->has_pattern || d->has_texture) {
+ if (bs == Qt::TexturePattern) {
+ d->brush_pm = qt_toX11Pixmap(d->cbrush.texture());
+#if !defined(QT_NO_XRENDER)
+ if (X11->use_xrender) {
+ XRenderPictureAttributes attrs;
+ attrs.repeat = true;
+ XRenderChangePicture(d->dpy, d->brush_pm.x11PictureHandle(), CPRepeat, &attrs);
+ QX11PlatformPixmap *data = static_cast<QX11PlatformPixmap*>(d->brush_pm.data.data());
+ if (data->mask_picture)
+ XRenderChangePicture(d->dpy, data->mask_picture, CPRepeat, &attrs);
+ }
+#endif
+ } else {
+ d->brush_pm = qt_toX11Pixmap(qt_pixmapForBrush(bs, true));
+ }
+ d->brush_pm.x11SetScreen(d->scrn);
+ if (d->brush_pm.depth() == 1) {
+ mask |= GCStipple;
+ vals.stipple = d->brush_pm.handle();
+ s = FillStippled;
+#if !defined(QT_NO_XRENDER)
+ if (X11->use_xrender) {
+ d->bitmap_texture = QPixmap(d->brush_pm.size());
+ d->bitmap_texture.fill(Qt::transparent);
+ d->bitmap_texture = qt_toX11Pixmap(d->bitmap_texture);
+ d->bitmap_texture.x11SetScreen(d->scrn);
+
+ ::Picture src = X11->getSolidFill(d->scrn, d->cbrush.color());
+ XRenderComposite(d->dpy, PictOpSrc, src, d->brush_pm.x11PictureHandle(),
+ d->bitmap_texture.x11PictureHandle(),
+ 0, 0, d->brush_pm.width(), d->brush_pm.height(),
+ 0, 0, d->brush_pm.width(), d->brush_pm.height());
+
+ XRenderPictureAttributes attrs;
+ attrs.repeat = true;
+ XRenderChangePicture(d->dpy, d->bitmap_texture.x11PictureHandle(), CPRepeat, &attrs);
+
+ d->current_brush = d->bitmap_texture.x11PictureHandle();
+ }
+#endif
+ } else {
+ mask |= GCTile;
+#ifndef QT_NO_XRENDER
+ if (d->pdev_depth == 32 && d->brush_pm.depth() != 32) {
+ d->brush_pm.detach();
+ QX11PlatformPixmap *brushData = static_cast<QX11PlatformPixmap*>(d->brush_pm.data.data());
+ brushData->convertToARGB32();
+ }
+#endif
+ vals.tile = (d->brush_pm.depth() == d->pdev_depth
+ ? d->brush_pm.handle()
+ : static_cast<QX11PlatformPixmap*>(d->brush_pm.data.data())->x11ConvertToDefaultDepth());
+ s = FillTiled;
+#if !defined(QT_NO_XRENDER)
+ d->current_brush = d->cbrush.texture().x11PictureHandle();
+#endif
+ }
+
+ mask |= GCTileStipXOrigin | GCTileStipYOrigin;
+ vals.ts_x_origin = qRound(origin.x());
+ vals.ts_y_origin = qRound(origin.y());
+ }
+#if !defined(QT_NO_XRENDER)
+ else if (d->has_alpha_brush) {
+ d->current_brush = X11->getSolidFill(d->scrn, d->cbrush.color());
+ }
+#endif
+
+ vals.fill_style = s;
+ XChangeGC(d->dpy, d->gc_brush, mask, &vals);
+ if (!d->has_clipping) {
+ QRegion sysClip = systemClip();
+ if (!sysClip.isEmpty())
+ x11SetClipRegion(d->dpy, d->gc_brush, 0, d->picture, sysClip);
+ else
+ x11ClearClipRegion(d->dpy, d->gc_brush, 0, d->picture);
+ }
+}
+
+void QX11PaintEngine::drawEllipse(const QRectF &rect)
+{
+ QRect aligned = rect.toAlignedRect();
+ if (aligned == rect)
+ drawEllipse(aligned);
+ else
+ QPaintEngine::drawEllipse(rect);
+}
+
+void QX11PaintEngine::drawEllipse(const QRect &rect)
+{
+ if (rect.isEmpty()) {
+ drawRects(&rect, 1);
+ return;
+ }
+
+ Q_D(QX11PaintEngine);
+ QRect devclip(SHRT_MIN, SHRT_MIN, SHRT_MAX*2 - 1, SHRT_MAX*2 - 1);
+ QRect r(rect);
+ if (d->txop < QTransform::TxRotate) {
+ r = d->matrix.mapRect(rect);
+ } else if (d->txop == QTransform::TxRotate && rect.width() == rect.height()) {
+ QPainterPath path;
+ path.addEllipse(rect);
+ r = d->matrix.map(path).boundingRect().toRect();
+ }
+
+ if (d->has_alpha_brush || d->has_alpha_pen || d->has_custom_pen || (d->render_hints & QPainter::Antialiasing)
+ || d->has_alpha_texture || devclip.intersected(r) != r
+ || (d->has_complex_xform
+ && !(d->has_non_scaling_xform && rect.width() == rect.height())))
+ {
+ QPainterPath path;
+ path.addEllipse(rect);
+ drawPath(path);
+ return;
+ }
+
+ int x = r.x();
+ int y = r.y();
+ int w = r.width();
+ int h = r.height();
+ if (w < 1 || h < 1)
+ return;
+ if (w == 1 && h == 1) {
+ XDrawPoint(d->dpy, d->hd, d->has_pen ? d->gc : d->gc_brush, x, y);
+ return;
+ }
+ d->setupAdaptedOrigin(rect.topLeft());
+ 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);
+ }
+ if (d->has_pen) // draw outline
+ XDrawArc(d->dpy, d->hd, d->gc, x, y, w, h, 0, 360*64);
+ d->resetAdaptedOrigin();
+}
+
+
+
+void QX11PaintEnginePrivate::fillPolygon_translated(const QPointF *polygonPoints, int pointCount,
+ QX11PaintEnginePrivate::GCMode gcMode,
+ QPaintEngine::PolygonDrawMode mode)
+{
+
+ QVarLengthArray<QPointF> translated_points(pointCount);
+ QPointF offset(matrix.dx(), matrix.dy());
+
+ qreal offs = adjust_coords ? aliasedCoordinateDelta : 0.0;
+ if (!X11->use_xrender || !(render_hints & QPainter::Antialiasing))
+ offset += QPointF(aliasedCoordinateDelta, aliasedCoordinateDelta);
+
+ for (int i = 0; i < pointCount; ++i) {
+ translated_points[i] = polygonPoints[i] + offset;
+
+ translated_points[i].rx() = qRound(translated_points[i].x()) + offs;
+ translated_points[i].ry() = qRound(translated_points[i].y()) + offs;
+ }
+
+ fillPolygon_dev(translated_points.data(), pointCount, gcMode, mode);
+}
+
+#ifndef QT_NO_XRENDER
+static void qt_XRenderCompositeTrapezoids(Display *dpy,
+ int op,
+ Picture src,
+ Picture dst,
+ _Xconst XRenderPictFormat *maskFormat,
+ int xSrc,
+ int ySrc,
+ const XTrapezoid *traps, int size)
+{
+ const int MAX_TRAPS = 50000;
+ while (size) {
+ int to_draw = size;
+ if (to_draw > MAX_TRAPS)
+ to_draw = MAX_TRAPS;
+ XRenderCompositeTrapezoids(dpy, op, src, dst,
+ maskFormat,
+ xSrc, ySrc,
+ traps, to_draw);
+ size -= to_draw;
+ traps += to_draw;
+ }
+}
+#endif
+
+void QX11PaintEnginePrivate::fillPolygon_dev(const QPointF *polygonPoints, int pointCount,
+ QX11PaintEnginePrivate::GCMode gcMode,
+ QPaintEngine::PolygonDrawMode mode)
+{
+ Q_Q(QX11PaintEngine);
+
+ int clippedCount = 0;
+ qt_float_point *clippedPoints = 0;
+
+#ifndef QT_NO_XRENDER
+ //can change if we switch to pen if gcMode != BrushGC
+ bool has_fill_texture = has_texture;
+ bool has_fill_pattern = has_pattern;
+ ::Picture src;
+#endif
+ QBrush fill;
+ GC fill_gc;
+ if (gcMode == BrushGC) {
+ fill = cbrush;
+ fill_gc = gc_brush;
+#ifndef QT_NO_XRENDER
+ if (current_brush)
+ src = current_brush;
+ else
+ src = X11->getSolidFill(scrn, fill.color());
+#endif
+ } else {
+ fill = QBrush(cpen.brush());
+ fill_gc = gc;
+#ifndef QT_NO_XRENDER
+ //we use the pens brush
+ has_fill_texture = (fill.style() == Qt::TexturePattern);
+ has_fill_pattern = (fill.style() >= Qt::Dense1Pattern && fill.style() <= Qt::DiagCrossPattern);
+ if (has_fill_texture)
+ src = fill.texture().x11PictureHandle();
+ else if (has_fill_pattern)
+ src = getPatternFill(scrn, fill);
+ else
+ src = X11->getSolidFill(scrn, fill.color());
+#endif
+ }
+
+ polygonClipper.clipPolygon((qt_float_point *) polygonPoints, pointCount,
+ &clippedPoints, &clippedCount);
+
+#ifndef QT_NO_XRENDER
+ bool solid_fill = fill.color().alpha() == 255;
+ if (has_fill_texture && fill.texture().depth() == 1 && solid_fill) {
+ has_fill_texture = false;
+ has_fill_pattern = true;
+ }
+
+ bool antialias = render_hints & QPainter::Antialiasing;
+
+ if (X11->use_xrender
+ && picture
+ && !has_fill_pattern
+ && (clippedCount > 0)
+ && (fill.style() != Qt::NoBrush)
+ && ((has_fill_texture && fill.texture().hasAlpha()) || antialias || !solid_fill || has_alpha_pen != has_alpha_brush))
+ {
+ if (tessellator->size > 0) {
+ XRenderPictureAttributes attrs;
+ attrs.poly_edge = antialias ? PolyEdgeSmooth : PolyEdgeSharp;
+ XRenderChangePicture(dpy, picture, CPPolyEdge, &attrs);
+ int x_offset = int(XFixedToDouble(tessellator->traps[0].left.p1.x) - bg_origin.x());
+ int y_offset = int(XFixedToDouble(tessellator->traps[0].left.p1.y) - bg_origin.y());
+ qt_XRenderCompositeTrapezoids(dpy, composition_mode, src, picture,
+ antialias
+ ? XRenderFindStandardFormat(dpy, PictStandardA8)
+ : XRenderFindStandardFormat(dpy, PictStandardA1),
+ x_offset, y_offset,
+ tessellator->traps, tessellator->size);
+ tessellator->done();
+ }
+ } else
+#endif
+ if (fill.style() != Qt::NoBrush) {
+ if (clippedCount > 200000) {
+ QPolygon poly;
+ for (int i = 0; i < clippedCount; ++i)
+ poly << QPoint(qFloor(clippedPoints[i].x), qFloor(clippedPoints[i].y));
+
+ const QRect bounds = poly.boundingRect();
+ const QRect aligned = bounds
+ & QRect(QPoint(), QSize(pdev->width(), pdev->height()));
+
+ QImage img(aligned.size(), QImage::Format_ARGB32_Premultiplied);
+ img.fill(0);
+
+ QPainter painter(&img);
+ painter.translate(-aligned.x(), -aligned.y());
+ painter.setPen(Qt::NoPen);
+ painter.setBrush(fill);
+ if (gcMode == BrushGC)
+ painter.setBrushOrigin(q->painter()->brushOrigin());
+ painter.drawPolygon(poly);
+ painter.end();
+
+ q->drawImage(aligned, img, img.rect(), Qt::AutoColor);
+ } else if (clippedCount > 0) {
+ QVarLengthArray<XPoint> xpoints(clippedCount);
+ for (int i = 0; i < clippedCount; ++i) {
+ xpoints[i].x = qFloor(clippedPoints[i].x);
+ xpoints[i].y = qFloor(clippedPoints[i].y);
+ }
+ if (mode == QPaintEngine::WindingMode)
+ XSetFillRule(dpy, fill_gc, WindingRule);
+ setupAdaptedOrigin(QPoint(xpoints[0].x, xpoints[0].y));
+ XFillPolygon(dpy, hd, fill_gc,
+ xpoints.data(), clippedCount,
+ mode == QPaintEngine::ConvexMode ? Convex : Complex, CoordModeOrigin);
+ resetAdaptedOrigin();
+ if (mode == QPaintEngine::WindingMode)
+ XSetFillRule(dpy, fill_gc, EvenOddRule);
+ }
+ }
+}
+
+void QX11PaintEnginePrivate::strokePolygon_translated(const QPointF *polygonPoints, int pointCount, bool close)
+{
+ QVarLengthArray<QPointF> translated_points(pointCount);
+ QPointF offset(matrix.dx(), matrix.dy());
+ for (int i = 0; i < pointCount; ++i)
+ translated_points[i] = polygonPoints[i] + offset;
+ strokePolygon_dev(translated_points.data(), pointCount, close);
+}
+
+void QX11PaintEnginePrivate::strokePolygon_dev(const QPointF *polygonPoints, int pointCount, bool close)
+{
+ int clippedCount = 0;
+ qt_float_point *clippedPoints = 0;
+ polygonClipper.clipPolygon((qt_float_point *) polygonPoints, pointCount,
+ &clippedPoints, &clippedCount, close);
+
+ if (clippedCount > 0) {
+ QVarLengthArray<XPoint> xpoints(clippedCount);
+ for (int i = 0; i < clippedCount; ++i) {
+ xpoints[i].x = qRound(clippedPoints[i].x + aliasedCoordinateDelta);
+ xpoints[i].y = qRound(clippedPoints[i].y + aliasedCoordinateDelta);
+ }
+ uint numberPoints = qMin(clippedCount, xlibMaxLinePoints);
+ XPoint *pts = xpoints.data();
+ XDrawLines(dpy, hd, gc, pts, numberPoints, CoordModeOrigin);
+ pts += numberPoints;
+ clippedCount -= numberPoints;
+ numberPoints = qMin(clippedCount, xlibMaxLinePoints-1);
+ while (clippedCount) {
+ XDrawLines(dpy, hd, gc, pts-1, numberPoints+1, CoordModeOrigin);
+ pts += numberPoints;
+ clippedCount -= numberPoints;
+ numberPoints = qMin(clippedCount, xlibMaxLinePoints-1);
+ }
+ }
+}
+
+void QX11PaintEngine::drawPolygon(const QPointF *polygonPoints, int pointCount, PolygonDrawMode mode)
+{
+ Q_D(QX11PaintEngine);
+ if (d->use_path_fallback) {
+ QPainterPath path(polygonPoints[0]);
+ for (int i = 1; i < pointCount; ++i)
+ path.lineTo(polygonPoints[i]);
+ if (mode == PolylineMode) {
+ QBrush oldBrush = d->cbrush;
+ d->cbrush = QBrush(Qt::NoBrush);
+ path.setFillRule(Qt::WindingFill);
+ drawPath(path);
+ d->cbrush = oldBrush;
+ } else {
+ path.setFillRule(mode == OddEvenMode ? Qt::OddEvenFill : Qt::WindingFill);
+ path.closeSubpath();
+ drawPath(path);
+ }
+ return;
+ }
+ if (mode != PolylineMode && d->has_brush)
+ d->fillPolygon_translated(polygonPoints, pointCount, QX11PaintEnginePrivate::BrushGC, mode);
+
+ if (d->has_pen)
+ d->strokePolygon_translated(polygonPoints, pointCount, mode != PolylineMode);
+}
+
+
+void QX11PaintEnginePrivate::fillPath(const QPainterPath &path, QX11PaintEnginePrivate::GCMode gc_mode, bool transform)
+{
+ qreal offs = adjust_coords ? aliasedCoordinateDelta : 0.0;
+
+ QPainterPath clippedPath;
+ QPainterPath clipPath;
+ clipPath.addRect(polygonClipper.boundingRect());
+
+ if (transform)
+ clippedPath = (path*matrix).intersected(clipPath);
+ else
+ clippedPath = path.intersected(clipPath);
+
+ QList<QPolygonF> polys = clippedPath.toFillPolygons();
+ for (int i = 0; i < polys.size(); ++i) {
+ QVarLengthArray<QPointF> translated_points(polys.at(i).size());
+
+ for (int j = 0; j < polys.at(i).size(); ++j) {
+ translated_points[j] = polys.at(i).at(j);
+ if (!X11->use_xrender || !(render_hints & QPainter::Antialiasing)) {
+ translated_points[j].rx() = qRound(translated_points[j].rx() + aliasedCoordinateDelta) + offs;
+ translated_points[j].ry() = qRound(translated_points[j].ry() + aliasedCoordinateDelta) + offs;
+ }
+ }
+
+ fillPolygon_dev(translated_points.data(), polys.at(i).size(), gc_mode,
+ path.fillRule() == Qt::OddEvenFill ? QPaintEngine::OddEvenMode : QPaintEngine::WindingMode);
+ }
+}
+
+void QX11PaintEngine::drawPath(const QPainterPath &path)
+{
+ Q_D(QX11PaintEngine);
+ if (path.isEmpty())
+ return;
+
+ if (d->has_brush)
+ d->fillPath(path, QX11PaintEnginePrivate::BrushGC, true);
+ if (d->has_pen
+ && ((X11->use_xrender && (d->has_alpha_pen || (d->render_hints & QPainter::Antialiasing)))
+ || (!d->cpen.isCosmetic() && d->txop > QTransform::TxTranslate
+ && !d->has_non_scaling_xform)
+ || (d->cpen.style() == Qt::CustomDashLine))) {
+ QPainterPathStroker stroker;
+ if (d->cpen.style() == Qt::CustomDashLine) {
+ stroker.setDashPattern(d->cpen.dashPattern());
+ stroker.setDashOffset(d->cpen.dashOffset());
+ } else {
+ stroker.setDashPattern(d->cpen.style());
+ }
+ stroker.setCapStyle(d->cpen.capStyle());
+ stroker.setJoinStyle(d->cpen.joinStyle());
+ 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) {
+ 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;
+ stroke.setFillRule(Qt::WindingFill);
+ 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;
+ stroke.setFillRule(Qt::WindingFill);
+ d->fillPath(stroke, QX11PaintEnginePrivate::PenGC, true);
+ }
+ } else if (d->has_pen) {
+ // if we have a cosmetic pen - use XDrawLine() for speed
+ QList<QPolygonF> polys = path.toSubpathPolygons(d->matrix);
+ for (int i = 0; i < polys.size(); ++i)
+ d->strokePolygon_dev(polys.at(i).data(), polys.at(i).size(), false);
+ }
+}
+
+Q_WIDGETS_EXPORT void qt_x11_drawImage(const QRect &rect, const QPoint &pos, const QImage &image,
+ Drawable hd, GC gc, Display *dpy, Visual *visual, int depth)
+{
+ Q_ASSERT(image.format() == QImage::Format_RGB32);
+ Q_ASSERT(image.depth() == 32);
+
+ XImage *xi;
+ // Note: this code assumes either RGB or BGR, 8 bpc server layouts
+ const uint red_mask = (uint) visual->red_mask;
+ bool bgr_layout = (red_mask == 0xff);
+
+ const int w = rect.width();
+ const int h = rect.height();
+
+ QImage im;
+ int image_byte_order = ImageByteOrder(X11->display);
+ if ((QSysInfo::ByteOrder == QSysInfo::BigEndian && ((image_byte_order == LSBFirst) || bgr_layout))
+ || (image_byte_order == MSBFirst && QSysInfo::ByteOrder == QSysInfo::LittleEndian)
+ || (image_byte_order == LSBFirst && bgr_layout))
+ {
+ im = image.copy(rect);
+ const int iw = im.bytesPerLine() / 4;
+ uint *data = (uint *)im.bits();
+ for (int i=0; i < h; i++) {
+ uint *p = data;
+ uint *end = p + w;
+ if (bgr_layout && image_byte_order == MSBFirst && QSysInfo::ByteOrder == QSysInfo::LittleEndian) {
+ while (p < end) {
+ *p = ((*p << 8) & 0xffffff00) | ((*p >> 24) & 0x000000ff);
+ p++;
+ }
+ } else if ((image_byte_order == LSBFirst && QSysInfo::ByteOrder == QSysInfo::BigEndian)
+ || (image_byte_order == MSBFirst && QSysInfo::ByteOrder == QSysInfo::LittleEndian)) {
+ while (p < end) {
+ *p = ((*p << 24) & 0xff000000) | ((*p << 8) & 0x00ff0000)
+ | ((*p >> 8) & 0x0000ff00) | ((*p >> 24) & 0x000000ff);
+ p++;
+ }
+ } else if ((image_byte_order == MSBFirst && QSysInfo::ByteOrder == QSysInfo::BigEndian)
+ || (image_byte_order == LSBFirst && bgr_layout))
+ {
+ while (p < end) {
+ *p = ((*p << 16) & 0x00ff0000) | ((*p >> 16) & 0x000000ff)
+ | ((*p ) & 0xff00ff00);
+ p++;
+ }
+ }
+ data += iw;
+ }
+ xi = XCreateImage(dpy, visual, depth, ZPixmap,
+ 0, (char *) im.bits(), w, h, 32, im.bytesPerLine());
+ } else {
+ xi = XCreateImage(dpy, visual, depth, ZPixmap,
+ 0, (char *) image.scanLine(rect.y())+rect.x()*sizeof(uint), w, h, 32, image.bytesPerLine());
+ }
+ XPutImage(dpy, hd, gc, xi, 0, 0, pos.x(), pos.y(), w, h);
+ xi->data = 0; // QImage owns these bits
+ XDestroyImage(xi);
+}
+
+void QX11PaintEngine::drawImage(const QRectF &r, const QImage &image, const QRectF &sr, Qt::ImageConversionFlags flags)
+{
+ Q_D(QX11PaintEngine);
+
+ if (image.format() == QImage::Format_RGB32
+ && d->pdev_depth >= 24 && image.depth() == 32
+ && r.size() == sr.size())
+ {
+ int sx = qRound(sr.x());
+ int sy = qRound(sr.y());
+ int x = qRound(r.x());
+ int y = qRound(r.y());
+ int w = qRound(r.width());
+ int h = qRound(r.height());
+
+ qt_x11_drawImage(QRect(sx, sy, w, h), QPoint(x, y), image, d->hd, d->gc, d->dpy,
+ (Visual *)d->xinfo->visual(), d->pdev_depth);
+ } else {
+ QPaintEngine::drawImage(r, image, sr, flags);
+ }
+}
+
+void QX11PaintEngine::drawPixmap(const QRectF &r, const QPixmap &px, const QRectF &_sr)
+{
+ Q_D(QX11PaintEngine);
+ QRectF sr = _sr;
+ int x = qRound(r.x());
+ int y = qRound(r.y());
+ int sx = qRound(sr.x());
+ int sy = qRound(sr.y());
+ int sw = qRound(sr.width());
+ int sh = qRound(sr.height());
+
+ QPixmap pixmap = qt_toX11Pixmap(px);
+ if(pixmap.isNull())
+ return;
+
+ if ((d->xinfo && d->xinfo->screen() != pixmap.x11Info().screen())
+ || (pixmap.x11Info().screen() != DefaultScreen(X11->display))) {
+ QPixmap* p = const_cast<QPixmap *>(&pixmap);
+ p->x11SetScreen(d->xinfo ? d->xinfo->screen() : DefaultScreen(X11->display));
+ }
+
+ QPixmap::x11SetDefaultScreen(pixmap.x11Info().screen());
+
+#ifndef QT_NO_XRENDER
+ ::Picture src_pict = static_cast<QX11PlatformPixmap*>(pixmap.data.data())->picture;
+ if (src_pict && d->picture) {
+ const int pDepth = pixmap.depth();
+ if (pDepth == 1 && (d->has_alpha_pen)) {
+ qt_render_bitmap(d->dpy, d->scrn, src_pict, d->picture,
+ sx, sy, x, y, sw, sh, d->cpen);
+ return;
+ } else if (pDepth != 1 && (pDepth == 32 || pDepth != d->pdev_depth)) {
+ XRenderComposite(d->dpy, d->composition_mode,
+ src_pict, 0, d->picture, sx, sy, 0, 0, x, y, sw, sh);
+ return;
+ }
+ }
+#endif
+
+ bool mono_src = pixmap.depth() == 1;
+ bool mono_dst = d->pdev_depth == 1;
+ bool restore_clip = false;
+
+ if (static_cast<QX11PlatformPixmap*>(pixmap.data.data())->x11_mask) { // pixmap has a mask
+ QBitmap comb(sw, sh);
+ GC cgc = XCreateGC(d->dpy, comb.handle(), 0, 0);
+ XSetForeground(d->dpy, cgc, 0);
+ XFillRectangle(d->dpy, comb.handle(), cgc, 0, 0, sw, sh);
+ XSetBackground(d->dpy, cgc, 0);
+ XSetForeground(d->dpy, cgc, 1);
+ if (!d->crgn.isEmpty()) {
+ int num;
+ XRectangle *rects = (XRectangle *)qt_getClipRects(d->crgn, num);
+ XSetClipRectangles(d->dpy, cgc, -x, -y, rects, num, Unsorted);
+ } else if (d->has_clipping) {
+ XSetClipRectangles(d->dpy, cgc, 0, 0, 0, 0, Unsorted);
+ }
+ XSetFillStyle(d->dpy, cgc, FillOpaqueStippled);
+ XSetTSOrigin(d->dpy, cgc, -sx, -sy);
+ XSetStipple(d->dpy, cgc,
+ static_cast<QX11PlatformPixmap*>(pixmap.data.data())->x11_mask);
+ XFillRectangle(d->dpy, comb.handle(), cgc, 0, 0, sw, sh);
+ XFreeGC(d->dpy, cgc);
+
+ XSetClipOrigin(d->dpy, d->gc, x, y);
+ XSetClipMask(d->dpy, d->gc, comb.handle());
+ restore_clip = true;
+ }
+
+ if (mono_src) {
+ if (!d->crgn.isEmpty()) {
+ Pixmap comb = XCreatePixmap(d->dpy, d->hd, sw, sh, 1);
+ GC cgc = XCreateGC(d->dpy, comb, 0, 0);
+ XSetForeground(d->dpy, cgc, 0);
+ XFillRectangle(d->dpy, comb, cgc, 0, 0, sw, sh);
+ int num;
+ XRectangle *rects = (XRectangle *)qt_getClipRects(d->crgn, num);
+ XSetClipRectangles(d->dpy, cgc, -x, -y, rects, num, Unsorted);
+ XCopyArea(d->dpy, pixmap.handle(), comb, cgc, sx, sy, sw, sh, 0, 0);
+ XFreeGC(d->dpy, cgc);
+
+ XSetClipMask(d->dpy, d->gc, comb);
+ XSetClipOrigin(d->dpy, d->gc, x, y);
+ XFreePixmap(d->dpy, comb);
+ } else {
+ XSetClipMask(d->dpy, d->gc, pixmap.handle());
+ XSetClipOrigin(d->dpy, d->gc, x - sx, y - sy);
+ }
+
+ if (mono_dst) {
+ XSetForeground(d->dpy, d->gc, qGray(d->cpen.color().rgb()) > 127 ? 0 : 1);
+ } else {
+ QColormap cmap = QColormap::instance(d->scrn);
+ XSetForeground(d->dpy, d->gc, cmap.pixel(d->cpen.color()));
+ }
+ XFillRectangle(d->dpy, d->hd, d->gc, x, y, sw, sh);
+ restore_clip = true;
+ } else if (mono_dst && !mono_src) {
+ QBitmap bitmap(pixmap);
+ XCopyArea(d->dpy, bitmap.handle(), d->hd, d->gc, sx, sy, sw, sh, x, y);
+ } else {
+ XCopyArea(d->dpy, pixmap.handle(), d->hd, d->gc, sx, sy, sw, sh, x, y);
+ }
+
+ if (d->pdev->devType() == QInternal::Pixmap) {
+ const QPixmap *px = static_cast<const QPixmap*>(d->pdev);
+ Pixmap src_mask = static_cast<QX11PlatformPixmap*>(pixmap.data.data())->x11_mask;
+ Pixmap dst_mask = static_cast<QX11PlatformPixmap*>(px->data.data())->x11_mask;
+ if (dst_mask) {
+ GC cgc = XCreateGC(d->dpy, dst_mask, 0, 0);
+ if (src_mask) { // copy src mask into dst mask
+ XCopyArea(d->dpy, src_mask, dst_mask, cgc, sx, sy, sw, sh, x, y);
+ } else { // no src mask, but make sure the area copied is opaque in dest
+ XSetBackground(d->dpy, cgc, 0);
+ XSetForeground(d->dpy, cgc, 1);
+ XFillRectangle(d->dpy, dst_mask, cgc, x, y, sw, sh);
+ }
+ XFreeGC(d->dpy, cgc);
+ }
+ }
+
+ if (restore_clip) {
+ XSetClipOrigin(d->dpy, d->gc, 0, 0);
+ int num;
+ XRectangle *rects = (XRectangle *)qt_getClipRects(d->crgn, num);
+ if (num == 0)
+ XSetClipMask(d->dpy, d->gc, XNone);
+ else
+ XSetClipRectangles(d->dpy, d->gc, 0, 0, rects, num, Unsorted);
+ }
+}
+
+void QX11PaintEngine::updateMatrix(const QTransform &mtx)
+{
+ Q_D(QX11PaintEngine);
+ d->txop = mtx.type();
+ d->matrix = mtx;
+
+ d->has_complex_xform = (d->txop > QTransform::TxTranslate);
+
+ extern bool qt_scaleForTransform(const QTransform &transform, qreal *scale);
+ bool scaling = qt_scaleForTransform(d->matrix, &d->xform_scale);
+ d->has_scaling_xform = scaling && d->xform_scale != 1.0;
+ d->has_non_scaling_xform = scaling && d->xform_scale == 1.0;
+}
+
+/*
+ NB! the clip region is expected to be in dev coordinates
+*/
+void QX11PaintEngine::updateClipRegion_dev(const QRegion &clipRegion, Qt::ClipOperation op)
+{
+ Q_D(QX11PaintEngine);
+ QRegion sysClip = systemClip();
+ if (op == Qt::NoClip) {
+ d->has_clipping = false;
+ d->crgn = sysClip;
+ if (!sysClip.isEmpty()) {
+ x11SetClipRegion(d->dpy, d->gc, d->gc_brush, d->picture, sysClip);
+ } else {
+ x11ClearClipRegion(d->dpy, d->gc, d->gc_brush, d->picture);
+ }
+ return;
+ }
+
+ switch (op) {
+ case Qt::IntersectClip:
+ if (d->has_clipping) {
+ d->crgn &= clipRegion;
+ break;
+ }
+ // fall through
+ case Qt::ReplaceClip:
+ if (!sysClip.isEmpty())
+ d->crgn = clipRegion.intersected(sysClip);
+ else
+ d->crgn = clipRegion;
+ break;
+ default:
+ break;
+ }
+ d->has_clipping = true;
+ x11SetClipRegion(d->dpy, d->gc, d->gc_brush, d->picture, d->crgn);
+}
+
+void QX11PaintEngine::updateFont(const QFont &)
+{
+}
+
+Qt::HANDLE QX11PaintEngine::handle() const
+{
+ Q_D(const QX11PaintEngine);
+ Q_ASSERT(isActive());
+ Q_ASSERT(d->hd);
+ return d->hd;
+}
+
+extern void qt_draw_tile(QPaintEngine *, qreal, qreal, qreal, qreal, const QPixmap &,
+ qreal, qreal);
+
+void QX11PaintEngine::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &p)
+{
+ int x = qRound(r.x());
+ int y = qRound(r.y());
+ int w = qRound(r.width());
+ int h = qRound(r.height());
+ int sx = qRound(p.x());
+ int sy = qRound(p.y());
+
+ bool mono_src = pixmap.depth() == 1;
+ Q_D(QX11PaintEngine);
+
+ if ((d->xinfo && d->xinfo->screen() != pixmap.x11Info().screen())
+ || (pixmap.x11Info().screen() != DefaultScreen(X11->display))) {
+ QPixmap* p = const_cast<QPixmap *>(&pixmap);
+ p->x11SetScreen(d->xinfo ? d->xinfo->screen() : DefaultScreen(X11->display));
+ }
+
+ QPixmap::x11SetDefaultScreen(pixmap.x11Info().screen());
+
+#ifndef QT_NO_XRENDER
+ if (X11->use_xrender && d->picture && pixmap.x11PictureHandle()) {
+#if 0
+ // ### Qt 5: enable this
+ XRenderPictureAttributes attrs;
+ attrs.repeat = true;
+ XRenderChangePicture(d->dpy, pixmap.x11PictureHandle(), CPRepeat, &attrs);
+
+ if (mono_src) {
+ qt_render_bitmap(d->dpy, d->scrn, pixmap.x11PictureHandle(), d->picture,
+ sx, sy, x, y, w, h, d->cpen);
+ } else {
+ XRenderComposite(d->dpy, d->composition_mode,
+ pixmap.x11PictureHandle(), XNone, d->picture,
+ sx, sy, 0, 0, x, y, w, h);
+ }
+#else
+ const int numTiles = (w / pixmap.width()) * (h / pixmap.height());
+ if (numTiles < 100) {
+ // this is essentially qt_draw_tile(), inlined for
+ // the XRenderComposite call
+ int yPos, xPos, drawH, drawW, yOff, xOff;
+ yPos = y;
+ yOff = sy;
+ while(yPos < y + h) {
+ drawH = pixmap.height() - yOff; // Cropping first row
+ if (yPos + drawH > y + h) // Cropping last row
+ drawH = y + h - yPos;
+ xPos = x;
+ xOff = sx;
+ while(xPos < x + w) {
+ drawW = pixmap.width() - xOff; // Cropping first column
+ if (xPos + drawW > x + w) // Cropping last column
+ drawW = x + w - xPos;
+ if (mono_src) {
+ qt_render_bitmap(d->dpy, d->scrn, pixmap.x11PictureHandle(), d->picture,
+ xOff, yOff, xPos, yPos, drawW, drawH, d->cpen);
+ } else {
+ XRenderComposite(d->dpy, d->composition_mode,
+ pixmap.x11PictureHandle(), XNone, d->picture,
+ xOff, yOff, 0, 0, xPos, yPos, drawW, drawH);
+ }
+ xPos += drawW;
+ xOff = 0;
+ }
+ yPos += drawH;
+ yOff = 0;
+ }
+ } else {
+ w = qMin(w, d->pdev->width() - x);
+ h = qMin(h, d->pdev->height() - y);
+ if (w <= 0 || h <= 0)
+ return;
+
+ const int pw = w + sx;
+ const int ph = h + sy;
+ QPixmap pm(pw, ph);
+ if (pixmap.hasAlpha() || mono_src)
+ pm.fill(Qt::transparent);
+
+ const int mode = pixmap.hasAlpha() ? PictOpOver : PictOpSrc;
+ const ::Picture pmPicture = pm.x11PictureHandle();
+
+ // first tile
+ XRenderComposite(d->dpy, mode,
+ pixmap.x11PictureHandle(), XNone, pmPicture,
+ 0, 0, 0, 0, 0, 0, qMin(pw, pixmap.width()), qMin(ph, pixmap.height()));
+
+ // first row of tiles
+ int xPos = pixmap.width();
+ const int sh = qMin(ph, pixmap.height());
+ while (xPos < pw) {
+ const int sw = qMin(xPos, pw - xPos);
+ XRenderComposite(d->dpy, mode,
+ pmPicture, XNone, pmPicture,
+ 0, 0, 0, 0, xPos, 0, sw, sh);
+ xPos *= 2;
+ }
+
+ // remaining rows
+ int yPos = pixmap.height();
+ const int sw = pw;
+ while (yPos < ph) {
+ const int sh = qMin(yPos, ph - yPos);
+ XRenderComposite(d->dpy, mode,
+ pmPicture, XNone, pmPicture,
+ 0, 0, 0, 0, 0, yPos, sw, sh);
+ yPos *= 2;
+ }
+
+ // composite
+ if (mono_src)
+ qt_render_bitmap(d->dpy, d->scrn, pmPicture, d->picture,
+ sx, sy, x, y, w, h, d->cpen);
+ else
+ XRenderComposite(d->dpy, d->composition_mode,
+ pmPicture, XNone, d->picture,
+ sx, sy, 0, 0, x, y, w, h);
+ }
+#endif
+ } else
+#endif // !QT_NO_XRENDER
+ if (pixmap.depth() > 1 && !static_cast<QX11PlatformPixmap*>(pixmap.data.data())->x11_mask) {
+ XSetTile(d->dpy, d->gc, pixmap.handle());
+ XSetFillStyle(d->dpy, d->gc, FillTiled);
+ XSetTSOrigin(d->dpy, d->gc, x-sx, y-sy);
+ XFillRectangle(d->dpy, d->hd, d->gc, x, y, w, h);
+ XSetTSOrigin(d->dpy, d->gc, 0, 0);
+ XSetFillStyle(d->dpy, d->gc, FillSolid);
+ } else {
+ qt_draw_tile(this, x, y, w, h, pixmap, sx, sy);
+ }
+}
+
+void QX11PaintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem)
+{
+ const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem);
+
+ switch(ti.fontEngine->type()) {
+ case QFontEngine::TestFontEngine:
+ case QFontEngine::Box:
+ d_func()->drawBoxTextItem(p, ti);
+ break;
+ case QFontEngine::XLFD:
+ drawXLFD(p, ti);
+ break;
+#ifndef QT_NO_FONTCONFIG
+ case QFontEngine::Freetype:
+ drawFreetype(p, ti);
+ break;
+#endif
+ default:
+ Q_ASSERT(false);
+ }
+}
+
+void QX11PaintEngine::drawXLFD(const QPointF &p, const QTextItemInt &ti)
+{
+ Q_D(QX11PaintEngine);
+
+ if (d->txop > QTransform::TxTranslate) {
+ // XServer or font don't support server side transformations, need to do it by hand
+ QPaintEngine::drawTextItem(p, ti);
+ return;
+ }
+
+ if (!ti.glyphs.numGlyphs)
+ return;
+
+ QVarLengthArray<QFixedPoint> positions;
+ QVarLengthArray<glyph_t> glyphs;
+ QTransform matrix = d->matrix;
+ matrix.translate(p.x(), p.y());
+ ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions);
+ if (glyphs.size() == 0)
+ return;
+
+ QFontEngineXLFD *xlfd = static_cast<QFontEngineXLFD *>(ti.fontEngine);
+ Qt::HANDLE font_id = xlfd->fontStruct()->fid;
+
+ XSetFont(d->dpy, d->gc, font_id);
+
+ const QFixed offs = QFixed::fromReal(aliasedCoordinateDelta);
+ for (int i = 0; i < glyphs.size(); i++) {
+ int xp = qRound(positions[i].x + offs);
+ int yp = qRound(positions[i].y + offs);
+ if (xp < SHRT_MAX && xp > SHRT_MIN && yp > SHRT_MIN && yp < SHRT_MAX) {
+ XChar2b ch;
+ ch.byte1 = glyphs[i] >> 8;
+ ch.byte2 = glyphs[i] & 0xff;
+ XDrawString16(d->dpy, d->hd, d->gc, xp, yp, &ch, 1);
+ }
+ }
+}
+
+#ifndef QT_NO_FONTCONFIG
+static QPainterPath path_for_glyphs(const QVarLengthArray<glyph_t> &glyphs,
+ const QVarLengthArray<QFixedPoint> &positions,
+ const QFontEngineFT *ft)
+{
+ QPainterPath path;
+ path.setFillRule(Qt::WindingFill);
+ ft->lockFace();
+ int i = 0;
+ while (i < glyphs.size()) {
+ QFontEngineFT::Glyph *glyph = ft->loadGlyph(glyphs[i], QFontEngineFT::Format_Mono);
+ // #### fix case where we don't get a glyph
+ if (!glyph)
+ break;
+
+ Q_ASSERT(glyph->format == QFontEngineFT::Format_Mono);
+ int n = 0;
+ int h = glyph->height;
+ int xp = qRound(positions[i].x);
+ int yp = qRound(positions[i].y);
+
+ xp += glyph->x;
+ yp += -glyph->y + glyph->height;
+ int pitch = ((glyph->width + 31) & ~31) >> 3;
+
+ uchar *src = glyph->data;
+ while (h--) {
+ for (int x = 0; x < glyph->width; ++x) {
+ bool set = src[x >> 3] & (0x80 >> (x & 7));
+ if (set) {
+ QRect r(xp + x, yp - h, 1, 1);
+ while (x < glyph->width-1 && src[(x+1) >> 3] & (0x80 >> ((x+1) & 7))) {
+ ++x;
+ r.setRight(r.right()+1);
+ }
+
+ path.addRect(r);
+ ++n;
+ }
+ }
+ src += pitch;
+ }
+ ++i;
+ }
+ ft->unlockFace();
+ return path;
+}
+
+void QX11PaintEngine::drawFreetype(const QPointF &p, const QTextItemInt &ti)
+{
+ Q_D(QX11PaintEngine);
+ if (!ti.glyphs.numGlyphs)
+ return;
+
+ QFontEngineX11FT *ft = static_cast<QFontEngineX11FT *>(ti.fontEngine);
+
+ if (!d->cpen.isSolid()) {
+ QPaintEngine::drawTextItem(p, ti);
+ return;
+ }
+
+ const bool xrenderPath = (X11->use_xrender
+ && !(d->pdev->devType() == QInternal::Pixmap
+ && static_cast<const QPixmap *>(d->pdev)->data->pixelType() == QPlatformPixmap::BitmapType));
+
+ QVarLengthArray<QFixedPoint> positions;
+ QVarLengthArray<glyph_t> glyphs;
+ QTransform matrix;
+
+ if (xrenderPath)
+ matrix = d->matrix;
+ matrix.translate(p.x(), p.y());
+ ft->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions);
+ if (glyphs.count() == 0)
+ return;
+
+#ifndef QT_NO_XRENDER
+ QFontEngineFT::QGlyphSet *set = ft->defaultGlyphs();
+ if (d->txop >= QTransform::TxScale && xrenderPath)
+ set = ft->loadTransformedGlyphSet(d->matrix);
+
+ if (!set || set->outline_drawing
+ || !ft->loadGlyphs(set, glyphs.constData(), glyphs.size(), positions.constData(), QFontEngineFT::Format_Render))
+ {
+ QPaintEngine::drawTextItem(p, ti);
+ return;
+ }
+
+ if (xrenderPath) {
+ GlyphSet glyphSet = set->id;
+ const QColor &pen = d->cpen.color();
+ ::Picture src = X11->getSolidFill(d->scrn, pen);
+ XRenderPictFormat *maskFormat = 0;
+ if (ft->xglyph_format != PictStandardA1)
+ maskFormat = XRenderFindStandardFormat(X11->display, ft->xglyph_format);
+
+ enum { t_min = SHRT_MIN, t_max = SHRT_MAX };
+
+ int i = 0;
+ for (; i < glyphs.size()
+ && (positions[i].x < t_min || positions[i].x > t_max
+ || positions[i].y < t_min || positions[i].y > t_max);
+ ++i)
+ ;
+
+ if (i >= glyphs.size())
+ return;
+ ++i;
+
+ QFixed xp = positions[i - 1].x;
+ QFixed yp = positions[i - 1].y;
+ QFixed offs = QFixed::fromReal(aliasedCoordinateDelta);
+
+ XGlyphElt32 elt;
+ elt.glyphset = glyphSet;
+ elt.chars = &glyphs[i - 1];
+ elt.nchars = 1;
+ elt.xOff = qRound(xp + offs);
+ elt.yOff = qRound(yp + offs);
+ for (; i < glyphs.size(); ++i) {
+ if (positions[i].x < t_min || positions[i].x > t_max
+ || positions[i].y < t_min || positions[i].y > t_max) {
+ break;
+ }
+ QFontEngineFT::Glyph *g = ft->cachedGlyph(glyphs[i - 1]);
+ if (g
+ && positions[i].x == xp + g->advance
+ && positions[i].y == yp
+ && elt.nchars < 253 // don't draw more than 253 characters as some X servers
+ // hang with it
+ ) {
+ elt.nchars++;
+ xp += g->advance;
+ } else {
+ xp = positions[i].x;
+ yp = positions[i].y;
+
+ XRenderCompositeText32(X11->display, PictOpOver, src, d->picture,
+ maskFormat, 0, 0, 0, 0,
+ &elt, 1);
+ elt.chars = &glyphs[i];
+ elt.nchars = 1;
+ elt.xOff = qRound(xp + offs);
+ elt.yOff = qRound(yp + offs);
+ }
+ }
+ XRenderCompositeText32(X11->display, PictOpOver, src, d->picture,
+ maskFormat, 0, 0, 0, 0,
+ &elt, 1);
+
+ return;
+
+ }
+#endif
+
+ QPainterPath path = path_for_glyphs(glyphs, positions, ft);
+ if (path.elementCount() <= 1)
+ return;
+ Q_ASSERT((path.elementCount() % 5) == 0);
+ if (d->txop >= QTransform::TxScale) {
+ painter()->save();
+ painter()->setBrush(d->cpen.brush());
+ painter()->setPen(Qt::NoPen);
+ painter()->drawPath(path);
+ painter()->restore();
+ return;
+ }
+
+ const int rectcount = 256;
+ XRectangle rects[rectcount];
+ int num_rects = 0;
+
+ QPoint delta(qRound(d->matrix.dx()), qRound(d->matrix.dy()));
+ QRect clip(d->polygonClipper.boundingRect());
+ for (int i=0; i < path.elementCount(); i+=5) {
+ int x = qRound(path.elementAt(i).x);
+ int y = qRound(path.elementAt(i).y);
+ int w = qRound(path.elementAt(i+1).x) - x;
+ int h = qRound(path.elementAt(i+2).y) - y;
+
+ QRect rect = QRect(x + delta.x(), y + delta.y(), w, h);
+ rect = rect.intersected(clip);
+ if (rect.isEmpty())
+ continue;
+
+ rects[num_rects].x = short(rect.x());
+ rects[num_rects].y = short(rect.y());
+ rects[num_rects].width = ushort(rect.width());
+ rects[num_rects].height = ushort(rect.height());
+ ++num_rects;
+ if (num_rects == rectcount) {
+ XFillRectangles(d->dpy, d->hd, d->gc, rects, num_rects);
+ num_rects = 0;
+ }
+ }
+ if (num_rects > 0)
+ XFillRectangles(d->dpy, d->hd, d->gc, rects, num_rects);
+
+}
+#endif // !QT_NO_XRENDER
+
+QT_END_NAMESPACE
diff --git a/src/widgets/platforms/x11/qpaintengine_x11_p.h b/src/widgets/platforms/x11/qpaintengine_x11_p.h
new file mode 100644
index 0000000000..2ff339bbe1
--- /dev/null
+++ b/src/widgets/platforms/x11/qpaintengine_x11_p.h
@@ -0,0 +1,246 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPAINTENGINE_X11_P_H
+#define QPAINTENGINE_X11_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "QtGui/qpaintengine.h"
+#include "QtGui/qregion.h"
+#include "QtGui/qpen.h"
+#include "QtCore/qpoint.h"
+#include "private/qpaintengine_p.h"
+#include "private/qpainter_p.h"
+#include "private/qpolygonclipper_p.h"
+
+typedef unsigned long Picture;
+
+QT_BEGIN_NAMESPACE
+
+class QX11PaintEnginePrivate;
+class QFontEngineFT;
+class QXRenderTessellator;
+
+struct qt_float_point
+{
+ qreal x, y;
+};
+
+class QX11PaintEngine : public QPaintEngine
+{
+ Q_DECLARE_PRIVATE(QX11PaintEngine)
+public:
+ QX11PaintEngine();
+ ~QX11PaintEngine();
+
+ bool begin(QPaintDevice *pdev);
+ bool end();
+
+ void updateState(const QPaintEngineState &state);
+
+ void updatePen(const QPen &pen);
+ void updateBrush(const QBrush &brush, const QPointF &pt);
+ void updateRenderHints(QPainter::RenderHints hints);
+ void updateFont(const QFont &font);
+ void updateMatrix(const QTransform &matrix);
+ void updateClipRegion_dev(const QRegion &region, Qt::ClipOperation op);
+
+ void drawLines(const QLine *lines, int lineCount);
+ void drawLines(const QLineF *lines, int lineCount);
+
+ void drawRects(const QRect *rects, int rectCount);
+ void drawRects(const QRectF *rects, int rectCount);
+
+ void drawPoints(const QPoint *points, int pointCount);
+ void drawPoints(const QPointF *points, int pointCount);
+
+ void drawEllipse(const QRect &r);
+ void drawEllipse(const QRectF &r);
+
+ virtual void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode);
+ inline void drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode)
+ { QPaintEngine::drawPolygon(points, pointCount, mode); }
+
+ void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr);
+ void drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s);
+ void drawPath(const QPainterPath &path);
+ void drawTextItem(const QPointF &p, const QTextItem &textItem);
+ void drawImage(const QRectF &r, const QImage &img, const QRectF &sr,
+ Qt::ImageConversionFlags flags = Qt::AutoColor);
+
+ virtual Qt::HANDLE handle() const;
+ inline Type type() const { return QPaintEngine::X11; }
+
+ QPainter::RenderHints supportedRenderHints() const;
+
+protected:
+ QX11PaintEngine(QX11PaintEnginePrivate &dptr);
+
+ void drawXLFD(const QPointF &p, const QTextItemInt &si);
+#ifndef QT_NO_FONTCONFIG
+ void drawFreetype(const QPointF &p, const QTextItemInt &si);
+#endif
+
+ friend class QPixmap;
+ friend class QFontEngineBox;
+ friend Q_WIDGETS_EXPORT GC qt_x11_get_pen_gc(QPainter *);
+ friend Q_WIDGETS_EXPORT GC qt_x11_get_brush_gc(QPainter *);
+
+private:
+ Q_DISABLE_COPY(QX11PaintEngine)
+};
+
+class QX11PaintEnginePrivate : public QPaintEnginePrivate
+{
+ Q_DECLARE_PUBLIC(QX11PaintEngine)
+public:
+ QX11PaintEnginePrivate()
+ {
+ scrn = -1;
+ hd = 0;
+ picture = 0;
+ gc = gc_brush = 0;
+ dpy = 0;
+ xinfo = 0;
+ txop = QTransform::TxNone;
+ has_clipping = false;
+ render_hints = 0;
+ xform_scale = 1;
+#ifndef QT_NO_XRENDER
+ tessellator = 0;
+#endif
+ }
+ enum GCMode {
+ PenGC,
+ BrushGC
+ };
+
+ void init();
+ void fillPolygon_translated(const QPointF *points, int pointCount, GCMode gcMode,
+ QPaintEngine::PolygonDrawMode mode);
+ void fillPolygon_dev(const QPointF *points, int pointCount, GCMode gcMode,
+ QPaintEngine::PolygonDrawMode mode);
+ void fillPath(const QPainterPath &path, GCMode gcmode, bool transform);
+ void strokePolygon_dev(const QPointF *points, int pointCount, bool close);
+ void strokePolygon_translated(const QPointF *points, int pointCount, bool close);
+ void setupAdaptedOrigin(const QPoint &p);
+ void resetAdaptedOrigin();
+ void decidePathFallback() {
+ use_path_fallback = has_alpha_brush
+ || has_alpha_pen
+ || has_custom_pen
+ || has_complex_xform
+ || (render_hints & QPainter::Antialiasing);
+ }
+ void decideCoordAdjust() {
+ adjust_coords = !(render_hints & QPainter::Antialiasing)
+ && (has_alpha_pen
+ || (has_alpha_brush && has_pen && !has_alpha_pen)
+ || (cpen.style() > Qt::SolidLine));
+ }
+ void clipPolygon_dev(const QPolygonF &poly, QPolygonF *clipped_poly);
+ void systemStateChanged();
+
+ Display *dpy;
+ int scrn;
+ int pdev_depth;
+ Qt::HANDLE hd;
+ QPixmap brush_pm;
+#if !defined (QT_NO_XRENDER)
+ Qt::HANDLE picture;
+ Qt::HANDLE current_brush;
+ QPixmap bitmap_texture;
+ int composition_mode;
+#else
+ Qt::HANDLE picture;
+#endif
+ GC gc;
+ GC gc_brush;
+
+ QPen cpen;
+ QBrush cbrush;
+ QRegion crgn;
+ QTransform matrix;
+ qreal opacity;
+
+ uint has_complex_xform : 1;
+ uint has_scaling_xform : 1;
+ uint has_non_scaling_xform : 1;
+ uint has_custom_pen : 1;
+ uint use_path_fallback : 1;
+ uint adjust_coords : 1;
+ uint has_clipping : 1;
+ uint adapted_brush_origin : 1;
+ uint adapted_pen_origin : 1;
+ uint has_pen : 1;
+ uint has_brush : 1;
+ uint has_texture : 1;
+ uint has_alpha_texture : 1;
+ uint has_pattern : 1;
+ uint has_alpha_pen : 1;
+ uint has_alpha_brush : 1;
+ uint render_hints;
+
+ const QX11Info *xinfo;
+ QPointF bg_origin;
+ QTransform::TransformationType txop;
+ qreal xform_scale;
+ QPolygonClipper<qt_float_point, qt_float_point, float> polygonClipper;
+
+ int xlibMaxLinePoints;
+#ifndef QT_NO_XRENDER
+ QXRenderTessellator *tessellator;
+#endif
+};
+
+QT_END_NAMESPACE
+
+#endif // QPAINTENGINE_X11_P_H
diff --git a/src/widgets/platforms/x11/qpixmap_x11.cpp b/src/widgets/platforms/x11/qpixmap_x11.cpp
new file mode 100644
index 0000000000..500d1e3ddf
--- /dev/null
+++ b/src/widgets/platforms/x11/qpixmap_x11.cpp
@@ -0,0 +1,2419 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// Uncomment the next line to enable the MIT Shared Memory extension
+//
+// WARNING: This has some problems:
+//
+// 1. Consumes a 800x600 pixmap
+// 2. Qt does not handle the ShmCompletion message, so you will
+// get strange effects if you xForm() repeatedly.
+//
+// #define QT_MITSHM
+
+#if defined(Q_OS_WIN32) && defined(QT_MITSHM)
+#undef QT_MITSHM
+#endif
+
+#include "qplatformdefs.h"
+
+#include "qdebug.h"
+#include "qiodevice.h"
+#include "qpixmap_x11_p.h"
+#include "qbitmap.h"
+#include "qcolormap.h"
+#include "qimage.h"
+#include "qmatrix.h"
+#include "qapplication.h"
+#include <private/qpaintengine_x11_p.h>
+#include <private/qt_x11_p.h>
+#include "qx11info_x11.h"
+#include <private/qdrawhelper_p.h>
+#include <private/qimage_p.h>
+#include <private/qimagepixmapcleanuphooks_p.h>
+
+#include <stdlib.h>
+
+#if defined(Q_CC_MIPS)
+# define for if(0){}else for
+#endif
+
+QT_BEGIN_NAMESPACE
+
+QPixmap qt_toX11Pixmap(const QImage &image)
+{
+ QPlatformPixmap *data =
+ new QX11PlatformPixmap(image.depth() == 1
+ ? QPlatformPixmap::BitmapType
+ : QPlatformPixmap::PixmapType);
+
+ data->fromImage(image, Qt::AutoColor);
+
+ return QPixmap(data);
+}
+
+QPixmap qt_toX11Pixmap(const QPixmap &pixmap)
+{
+ if (pixmap.isNull())
+ return QPixmap();
+
+ if (QPixmap(pixmap).data_ptr()->classId() == QPlatformPixmap::X11Class)
+ return pixmap;
+
+ return qt_toX11Pixmap(pixmap.toImage());
+}
+
+// For thread-safety:
+// image->data does not belong to X11, so we must free it ourselves.
+
+inline static void qSafeXDestroyImage(XImage *x)
+{
+ if (x->data) {
+ free(x->data);
+ x->data = 0;
+ }
+ XDestroyImage(x);
+}
+
+QBitmap QX11PlatformPixmap::mask_to_bitmap(int screen) const
+{
+ if (!x11_mask)
+ return QBitmap();
+ QPixmap::x11SetDefaultScreen(screen);
+ QBitmap bm(w, h);
+ GC gc = XCreateGC(X11->display, bm.handle(), 0, 0);
+ XCopyArea(X11->display, x11_mask, bm.handle(), gc, 0, 0,
+ bm.data->width(), bm.data->height(), 0, 0);
+ XFreeGC(X11->display, gc);
+ return bm;
+}
+
+Qt::HANDLE QX11PlatformPixmap::bitmap_to_mask(const QBitmap &bitmap, int screen)
+{
+ if (bitmap.isNull())
+ return 0;
+ QBitmap bm = bitmap;
+ bm.x11SetScreen(screen);
+
+ Pixmap mask = XCreatePixmap(X11->display, RootWindow(X11->display, screen),
+ bm.data->width(), bm.data->height(), 1);
+ GC gc = XCreateGC(X11->display, mask, 0, 0);
+ XCopyArea(X11->display, bm.handle(), mask, gc, 0, 0,
+ bm.data->width(), bm.data->height(), 0, 0);
+ XFreeGC(X11->display, gc);
+ return mask;
+}
+
+
+/*****************************************************************************
+ MIT Shared Memory Extension support: makes xForm noticeably (~20%) faster.
+ *****************************************************************************/
+
+#if defined(QT_MITSHM)
+
+static bool xshminit = false;
+static XShmSegmentInfo xshminfo;
+static XImage *xshmimg = 0;
+static Pixmap xshmpm = 0;
+
+static void qt_cleanup_mitshm()
+{
+ if (xshmimg == 0)
+ return;
+ Display *dpy = QX11Info::appDisplay();
+ if (xshmpm) {
+ XFreePixmap(dpy, xshmpm);
+ xshmpm = 0;
+ }
+ XShmDetach(dpy, &xshminfo); xshmimg->data = 0;
+ qSafeXDestroyImage(xshmimg); xshmimg = 0;
+ shmdt(xshminfo.shmaddr);
+ shmctl(xshminfo.shmid, IPC_RMID, 0);
+}
+
+static bool qt_create_mitshm_buffer(const QPaintDevice* dev, int w, int h)
+{
+ static int major, minor;
+ static Bool pixmaps_ok;
+ Display *dpy = dev->data->xinfo->display();
+ int dd = dev->x11Depth();
+ Visual *vis = (Visual*)dev->x11Visual();
+
+ if (xshminit) {
+ qt_cleanup_mitshm();
+ } else {
+ if (!XShmQueryVersion(dpy, &major, &minor, &pixmaps_ok))
+ return false; // MIT Shm not supported
+ qAddPostRoutine(qt_cleanup_mitshm);
+ xshminit = true;
+ }
+
+ xshmimg = XShmCreateImage(dpy, vis, dd, ZPixmap, 0, &xshminfo, w, h);
+ if (!xshmimg)
+ return false;
+
+ bool ok;
+ xshminfo.shmid = shmget(IPC_PRIVATE,
+ xshmimg->bytes_per_line * xshmimg->height,
+ IPC_CREAT | 0777);
+ ok = xshminfo.shmid != -1;
+ if (ok) {
+ xshmimg->data = (char*)shmat(xshminfo.shmid, 0, 0);
+ xshminfo.shmaddr = xshmimg->data;
+ ok = (xshminfo.shmaddr != (char*)-1);
+ }
+ xshminfo.readOnly = false;
+ if (ok)
+ ok = XShmAttach(dpy, &xshminfo);
+ if (!ok) {
+ qSafeXDestroyImage(xshmimg);
+ xshmimg = 0;
+ if (xshminfo.shmaddr)
+ shmdt(xshminfo.shmaddr);
+ if (xshminfo.shmid != -1)
+ shmctl(xshminfo.shmid, IPC_RMID, 0);
+ return false;
+ }
+ if (pixmaps_ok)
+ xshmpm = XShmCreatePixmap(dpy, DefaultRootWindow(dpy), xshmimg->data,
+ &xshminfo, w, h, dd);
+
+ return true;
+}
+
+#else
+
+// If extern, need a dummy.
+//
+// static bool qt_create_mitshm_buffer(QPaintDevice*, int, int)
+// {
+// return false;
+// }
+
+#endif // QT_MITSHM
+
+
+/*****************************************************************************
+ Internal functions
+ *****************************************************************************/
+
+extern const uchar *qt_get_bitflip_array(); // defined in qimage.cpp
+
+// Returns position of highest bit set or -1 if none
+static int highest_bit(uint v)
+{
+ int i;
+ uint b = (uint)1 << 31;
+ for (i=31; ((b & v) == 0) && i>=0; i--)
+ b >>= 1;
+ return i;
+}
+
+// Returns position of lowest set bit in 'v' as an integer (0-31), or -1
+static int lowest_bit(uint v)
+{
+ int i;
+ ulong lb;
+ lb = 1;
+ for (i=0; ((v & lb) == 0) && i<32; i++, lb<<=1) {}
+ return i==32 ? -1 : i;
+}
+
+// Counts the number of bits set in 'v'
+static uint n_bits(uint v)
+{
+ int i = 0;
+ while (v) {
+ v = v & (v - 1);
+ i++;
+ }
+ return i;
+}
+
+static uint *red_scale_table = 0;
+static uint *green_scale_table = 0;
+static uint *blue_scale_table = 0;
+
+static void cleanup_scale_tables()
+{
+ delete[] red_scale_table;
+ delete[] green_scale_table;
+ delete[] blue_scale_table;
+}
+
+/*
+ Could do smart bitshifting, but the "obvious" algorithm only works for
+ nBits >= 4. This is more robust.
+*/
+static void build_scale_table(uint **table, uint nBits)
+{
+ if (nBits > 7) {
+ qWarning("build_scale_table: internal error, nBits = %i", nBits);
+ return;
+ }
+ if (!*table) {
+ static bool firstTable = true;
+ if (firstTable) {
+ qAddPostRoutine(cleanup_scale_tables);
+ firstTable = false;
+ }
+ *table = new uint[256];
+ }
+ int maxVal = (1 << nBits) - 1;
+ int valShift = 8 - nBits;
+ int i;
+ for(i = 0 ; i < maxVal + 1 ; i++)
+ (*table)[i << valShift] = i*255/maxVal;
+}
+
+static int defaultScreen = -1;
+
+/*****************************************************************************
+ QPixmap member functions
+ *****************************************************************************/
+
+QBasicAtomicInt qt_pixmap_serial = Q_BASIC_ATOMIC_INITIALIZER(0);
+int Q_WIDGETS_EXPORT qt_x11_preferred_pixmap_depth = 0;
+
+QX11PlatformPixmap::QX11PlatformPixmap(PixelType type)
+ : QPlatformPixmap(type, X11Class), gl_surface(0), hd(0),
+ flags(Uninitialized), x11_mask(0), picture(0), mask_picture(0), hd2(0),
+ share_mode(QPixmap::ImplicitlyShared), pengine(0)
+{
+}
+
+QPlatformPixmap *QX11PlatformPixmap::createCompatiblePlatformPixmap() const
+{
+ return new QX11PlatformPixmap(pixelType());
+}
+
+void QX11PlatformPixmap::resize(int width, int height)
+{
+ setSerialNumber(qt_pixmap_serial.fetchAndAddRelaxed(1));
+
+ w = width;
+ h = height;
+ is_null = (w <= 0 || h <= 0);
+
+ if (defaultScreen >= 0 && defaultScreen != xinfo.screen()) {
+ QX11InfoData* xd = xinfo.getX11Data(true);
+ xd->screen = defaultScreen;
+ xd->depth = QX11Info::appDepth(xd->screen);
+ xd->cells = QX11Info::appCells(xd->screen);
+ xd->colormap = QX11Info::appColormap(xd->screen);
+ xd->defaultColormap = QX11Info::appDefaultColormap(xd->screen);
+ xd->visual = (Visual *)QX11Info::appVisual(xd->screen);
+ xd->defaultVisual = QX11Info::appDefaultVisual(xd->screen);
+ xinfo.setX11Data(xd);
+ }
+
+ int dd = xinfo.depth();
+
+ if (qt_x11_preferred_pixmap_depth)
+ dd = qt_x11_preferred_pixmap_depth;
+
+ bool make_null = w <= 0 || h <= 0; // create null pixmap
+ d = (pixelType() == BitmapType ? 1 : dd);
+ if (make_null || d == 0) {
+ w = 0;
+ h = 0;
+ is_null = true;
+ hd = 0;
+ picture = 0;
+ d = 0;
+ if (!make_null)
+ qWarning("QPixmap: Invalid pixmap parameters");
+ return;
+ }
+ hd = (Qt::HANDLE)XCreatePixmap(X11->display,
+ RootWindow(X11->display, xinfo.screen()),
+ w, h, d);
+#ifndef QT_NO_XRENDER
+ if (X11->use_xrender) {
+ XRenderPictFormat *format = d == 1
+ ? XRenderFindStandardFormat(X11->display, PictStandardA1)
+ : XRenderFindVisualFormat(X11->display, (Visual *)xinfo.visual());
+ picture = XRenderCreatePicture(X11->display, hd, format, 0, 0);
+ }
+#endif // QT_NO_XRENDER
+}
+
+struct QX11AlphaDetector
+{
+ bool hasAlpha() const {
+ if (checked)
+ return has;
+ // Will implicitly also check format and return quickly for opaque types...
+ checked = true;
+ has = image->isNull() ? false : const_cast<QImage *>(image)->data_ptr()->checkForAlphaPixels();
+ return has;
+ }
+
+ bool hasXRenderAndAlpha() const {
+ if (!X11->use_xrender)
+ return false;
+ return hasAlpha();
+ }
+
+ QX11AlphaDetector(const QImage *i, Qt::ImageConversionFlags flags)
+ : image(i), checked(false), has(false)
+ {
+ if (flags & Qt::NoOpaqueDetection) {
+ checked = true;
+ has = image->hasAlphaChannel();
+ }
+ }
+
+ const QImage *image;
+ mutable bool checked;
+ mutable bool has;
+};
+
+void QX11PlatformPixmap::fromImage(const QImage &img,
+ Qt::ImageConversionFlags flags)
+{
+ setSerialNumber(qt_pixmap_serial.fetchAndAddRelaxed(1));
+
+ w = img.width();
+ h = img.height();
+ d = img.depth();
+ is_null = (w <= 0 || h <= 0);
+
+ if (is_null) {
+ w = h = 0;
+ return;
+ }
+
+ if (defaultScreen >= 0 && defaultScreen != xinfo.screen()) {
+ QX11InfoData* xd = xinfo.getX11Data(true);
+ xd->screen = defaultScreen;
+ xd->depth = QX11Info::appDepth(xd->screen);
+ xd->cells = QX11Info::appCells(xd->screen);
+ xd->colormap = QX11Info::appColormap(xd->screen);
+ xd->defaultColormap = QX11Info::appDefaultColormap(xd->screen);
+ xd->visual = (Visual *)QX11Info::appVisual(xd->screen);
+ xd->defaultVisual = QX11Info::appDefaultVisual(xd->screen);
+ xinfo.setX11Data(xd);
+ }
+
+ if (pixelType() == BitmapType) {
+ bitmapFromImage(img);
+ return;
+ }
+
+ if (uint(w) >= 32768 || uint(h) >= 32768) {
+ w = h = 0;
+ is_null = true;
+ return;
+ }
+
+ QX11AlphaDetector alphaCheck(&img, flags);
+ int dd = alphaCheck.hasXRenderAndAlpha() ? 32 : xinfo.depth();
+
+ if (qt_x11_preferred_pixmap_depth)
+ dd = qt_x11_preferred_pixmap_depth;
+
+ QImage image = img;
+
+ // must be monochrome
+ if (dd == 1 || (flags & Qt::ColorMode_Mask) == Qt::MonoOnly) {
+ if (d != 1) {
+ // dither
+ image = image.convertToFormat(QImage::Format_MonoLSB, flags);
+ d = 1;
+ }
+ } else { // can be both
+ bool conv8 = false;
+ if (d > 8 && dd <= 8) { // convert to 8 bit
+ if ((flags & Qt::DitherMode_Mask) == Qt::AutoDither)
+ flags = (flags & ~Qt::DitherMode_Mask)
+ | Qt::PreferDither;
+ conv8 = true;
+ } else if ((flags & Qt::ColorMode_Mask) == Qt::ColorOnly) {
+ conv8 = (d == 1); // native depth wanted
+ } else if (d == 1) {
+ if (image.colorCount() == 2) {
+ QRgb c0 = image.color(0); // Auto: convert to best
+ QRgb c1 = image.color(1);
+ conv8 = qMin(c0,c1) != qRgb(0,0,0) || qMax(c0,c1) != qRgb(255,255,255);
+ } else {
+ // eg. 1-color monochrome images (they do exist).
+ conv8 = true;
+ }
+ }
+ if (conv8) {
+ image = image.convertToFormat(QImage::Format_Indexed8, flags);
+ d = 8;
+ }
+ }
+
+ if (d == 1 || d == 16 || d == 24) {
+ image = image.convertToFormat(QImage::Format_RGB32, flags);
+ fromImage(image, Qt::AutoColor);
+ return;
+ }
+
+ Display *dpy = X11->display;
+ Visual *visual = (Visual *)xinfo.visual();
+ XImage *xi = 0;
+ bool trucol = (visual->c_class >= TrueColor);
+ int nbytes = image.byteCount();
+ uchar *newbits= 0;
+
+#ifndef QT_NO_XRENDER
+ if (alphaCheck.hasXRenderAndAlpha()) {
+ const QImage &cimage = image;
+
+ d = 32;
+
+ if (QX11Info::appDepth() != d) {
+ if (xinfo.x11data) {
+ xinfo.x11data->depth = d;
+ } else {
+ QX11InfoData *xd = xinfo.getX11Data(true);
+ xd->screen = QX11Info::appScreen();
+ xd->depth = d;
+ xd->cells = QX11Info::appCells();
+ xd->colormap = QX11Info::appColormap();
+ xd->defaultColormap = QX11Info::appDefaultColormap();
+ xd->visual = (Visual *)QX11Info::appVisual();
+ xd->defaultVisual = QX11Info::appDefaultVisual();
+ xinfo.setX11Data(xd);
+ }
+ }
+
+ hd = (Qt::HANDLE)XCreatePixmap(dpy, RootWindow(dpy, xinfo.screen()),
+ w, h, d);
+ picture = XRenderCreatePicture(X11->display, hd,
+ XRenderFindStandardFormat(X11->display, PictStandardARGB32), 0, 0);
+
+ xi = XCreateImage(dpy, visual, d, ZPixmap, 0, 0, w, h, 32, 0);
+ Q_CHECK_PTR(xi);
+ newbits = (uchar *)malloc(xi->bytes_per_line*h);
+ Q_CHECK_PTR(newbits);
+ xi->data = (char *)newbits;
+
+ switch(cimage.format()) {
+ case QImage::Format_Indexed8: {
+ QVector<QRgb> colorTable = cimage.colorTable();
+ uint *xidata = (uint *)xi->data;
+ for (int y = 0; y < h; ++y) {
+ const uchar *p = cimage.scanLine(y);
+ for (int x = 0; x < w; ++x) {
+ const QRgb rgb = colorTable[p[x]];
+ const int a = qAlpha(rgb);
+ if (a == 0xff)
+ *xidata = rgb;
+ else
+ // RENDER expects premultiplied alpha
+ *xidata = qRgba(qt_div_255(qRed(rgb) * a),
+ qt_div_255(qGreen(rgb) * a),
+ qt_div_255(qBlue(rgb) * a),
+ a);
+ ++xidata;
+ }
+ }
+ }
+ break;
+ case QImage::Format_RGB32: {
+ uint *xidata = (uint *)xi->data;
+ for (int y = 0; y < h; ++y) {
+ const QRgb *p = (const QRgb *) cimage.scanLine(y);
+ for (int x = 0; x < w; ++x)
+ *xidata++ = p[x] | 0xff000000;
+ }
+ }
+ break;
+ case QImage::Format_ARGB32: {
+ uint *xidata = (uint *)xi->data;
+ for (int y = 0; y < h; ++y) {
+ const QRgb *p = (const QRgb *) cimage.scanLine(y);
+ for (int x = 0; x < w; ++x) {
+ const QRgb rgb = p[x];
+ const int a = qAlpha(rgb);
+ if (a == 0xff)
+ *xidata = rgb;
+ else
+ // RENDER expects premultiplied alpha
+ *xidata = qRgba(qt_div_255(qRed(rgb) * a),
+ qt_div_255(qGreen(rgb) * a),
+ qt_div_255(qBlue(rgb) * a),
+ a);
+ ++xidata;
+ }
+ }
+
+ }
+ break;
+ case QImage::Format_ARGB32_Premultiplied: {
+ uint *xidata = (uint *)xi->data;
+ for (int y = 0; y < h; ++y) {
+ const QRgb *p = (const QRgb *) cimage.scanLine(y);
+ memcpy(xidata, p, w*sizeof(QRgb));
+ xidata += w;
+ }
+ }
+ break;
+ default:
+ Q_ASSERT(false);
+ }
+
+ if ((xi->byte_order == MSBFirst) != (QSysInfo::ByteOrder == QSysInfo::BigEndian)) {
+ uint *xidata = (uint *)xi->data;
+ uint *xiend = xidata + w*h;
+ while (xidata < xiend) {
+ *xidata = (*xidata >> 24)
+ | ((*xidata >> 8) & 0xff00)
+ | ((*xidata << 8) & 0xff0000)
+ | (*xidata << 24);
+ ++xidata;
+ }
+ }
+
+ GC gc = XCreateGC(dpy, hd, 0, 0);
+ XPutImage(dpy, hd, gc, xi, 0, 0, 0, 0, w, h);
+ XFreeGC(dpy, gc);
+
+ qSafeXDestroyImage(xi);
+
+ return;
+ }
+#endif // QT_NO_XRENDER
+
+ if (trucol) { // truecolor display
+ if (image.format() == QImage::Format_ARGB32_Premultiplied)
+ image = image.convertToFormat(QImage::Format_ARGB32);
+
+ const QImage &cimage = image;
+ QRgb pix[256]; // pixel translation table
+ const bool d8 = (d == 8);
+ const uint red_mask = (uint)visual->red_mask;
+ const uint green_mask = (uint)visual->green_mask;
+ const uint blue_mask = (uint)visual->blue_mask;
+ const int red_shift = highest_bit(red_mask) - 7;
+ const int green_shift = highest_bit(green_mask) - 7;
+ const int blue_shift = highest_bit(blue_mask) - 7;
+ const uint rbits = highest_bit(red_mask) - lowest_bit(red_mask) + 1;
+ const uint gbits = highest_bit(green_mask) - lowest_bit(green_mask) + 1;
+ const uint bbits = highest_bit(blue_mask) - lowest_bit(blue_mask) + 1;
+
+ if (d8) { // setup pixel translation
+ QVector<QRgb> ctable = cimage.colorTable();
+ for (int i=0; i < cimage.colorCount(); i++) {
+ int r = qRed (ctable[i]);
+ int g = qGreen(ctable[i]);
+ int b = qBlue (ctable[i]);
+ r = red_shift > 0 ? r << red_shift : r >> -red_shift;
+ g = green_shift > 0 ? g << green_shift : g >> -green_shift;
+ b = blue_shift > 0 ? b << blue_shift : b >> -blue_shift;
+ pix[i] = (b & blue_mask) | (g & green_mask) | (r & red_mask)
+ | ~(blue_mask | green_mask | red_mask);
+ }
+ }
+
+ xi = XCreateImage(dpy, visual, dd, ZPixmap, 0, 0, w, h, 32, 0);
+ Q_CHECK_PTR(xi);
+ newbits = (uchar *)malloc(xi->bytes_per_line*h);
+ Q_CHECK_PTR(newbits);
+ if (!newbits) // no memory
+ return;
+ int bppc = xi->bits_per_pixel;
+
+ bool contig_bits = n_bits(red_mask) == rbits &&
+ n_bits(green_mask) == gbits &&
+ n_bits(blue_mask) == bbits;
+ bool dither_tc =
+ // Want it?
+ (flags & Qt::Dither_Mask) != Qt::ThresholdDither &&
+ (flags & Qt::DitherMode_Mask) != Qt::AvoidDither &&
+ // Need it?
+ bppc < 24 && !d8 &&
+ // Can do it? (Contiguous bits?)
+ contig_bits;
+
+ static bool init=false;
+ static int D[16][16];
+ if (dither_tc && !init) {
+ // I also contributed this code to XV - WWA.
+ /*
+ The dither matrix, D, is obtained with this formula:
+
+ D2 = [0 2]
+ [3 1]
+
+
+ D2*n = [4*Dn 4*Dn+2*Un]
+ [4*Dn+3*Un 4*Dn+1*Un]
+ */
+ int n,i,j;
+ init=1;
+
+ /* Set D2 */
+ D[0][0]=0;
+ D[1][0]=2;
+ D[0][1]=3;
+ D[1][1]=1;
+
+ /* Expand using recursive definition given above */
+ for (n=2; n<16; n*=2) {
+ for (i=0; i<n; i++) {
+ for (j=0; j<n; j++) {
+ D[i][j]*=4;
+ D[i+n][j]=D[i][j]+2;
+ D[i][j+n]=D[i][j]+3;
+ D[i+n][j+n]=D[i][j]+1;
+ }
+ }
+ }
+ init=true;
+ }
+
+ enum { BPP8,
+ BPP16_565, BPP16_555,
+ BPP16_MSB, BPP16_LSB,
+ BPP24_888,
+ BPP24_MSB, BPP24_LSB,
+ BPP32_8888,
+ BPP32_MSB, BPP32_LSB
+ } mode = BPP8;
+
+ bool same_msb_lsb = (xi->byte_order == MSBFirst) == (QSysInfo::ByteOrder == QSysInfo::BigEndian);
+
+ if(bppc == 8) // 8 bit
+ mode = BPP8;
+ else if(bppc == 16) { // 16 bit MSB/LSB
+ if(red_shift == 8 && green_shift == 3 && blue_shift == -3 && !d8 && same_msb_lsb)
+ mode = BPP16_565;
+ else if(red_shift == 7 && green_shift == 2 && blue_shift == -3 && !d8 && same_msb_lsb)
+ mode = BPP16_555;
+ else
+ mode = (xi->byte_order == LSBFirst) ? BPP16_LSB : BPP16_MSB;
+ } else if(bppc == 24) { // 24 bit MSB/LSB
+ if (red_shift == 16 && green_shift == 8 && blue_shift == 0 && !d8 && same_msb_lsb)
+ mode = BPP24_888;
+ else
+ mode = (xi->byte_order == LSBFirst) ? BPP24_LSB : BPP24_MSB;
+ } else if(bppc == 32) { // 32 bit MSB/LSB
+ if(red_shift == 16 && green_shift == 8 && blue_shift == 0 && !d8 && same_msb_lsb)
+ mode = BPP32_8888;
+ else
+ mode = (xi->byte_order == LSBFirst) ? BPP32_LSB : BPP32_MSB;
+ } else
+ qFatal("Logic error 3");
+
+#define GET_PIXEL \
+ uint pixel; \
+ if (d8) pixel = pix[*src++]; \
+ else { \
+ int r = qRed (*p); \
+ int g = qGreen(*p); \
+ int b = qBlue (*p++); \
+ r = red_shift > 0 \
+ ? r << red_shift : r >> -red_shift; \
+ g = green_shift > 0 \
+ ? g << green_shift : g >> -green_shift; \
+ b = blue_shift > 0 \
+ ? b << blue_shift : b >> -blue_shift; \
+ pixel = (r & red_mask)|(g & green_mask) | (b & blue_mask) \
+ | ~(blue_mask | green_mask | red_mask); \
+ }
+
+#define GET_PIXEL_DITHER_TC \
+ int r = qRed (*p); \
+ int g = qGreen(*p); \
+ int b = qBlue (*p++); \
+ const int thres = D[x%16][y%16]; \
+ if (r <= (255-(1<<(8-rbits))) && ((r<<rbits) & 255) \
+ > thres) \
+ r += (1<<(8-rbits)); \
+ if (g <= (255-(1<<(8-gbits))) && ((g<<gbits) & 255) \
+ > thres) \
+ g += (1<<(8-gbits)); \
+ if (b <= (255-(1<<(8-bbits))) && ((b<<bbits) & 255) \
+ > thres) \
+ b += (1<<(8-bbits)); \
+ r = red_shift > 0 \
+ ? r << red_shift : r >> -red_shift; \
+ g = green_shift > 0 \
+ ? g << green_shift : g >> -green_shift; \
+ b = blue_shift > 0 \
+ ? b << blue_shift : b >> -blue_shift; \
+ uint pixel = (r & red_mask)|(g & green_mask) | (b & blue_mask);
+
+// again, optimized case
+// can't be optimized that much :(
+#define GET_PIXEL_DITHER_TC_OPT(red_shift,green_shift,blue_shift,red_mask,green_mask,blue_mask, \
+ rbits,gbits,bbits) \
+ const int thres = D[x%16][y%16]; \
+ int r = qRed (*p); \
+ if (r <= (255-(1<<(8-rbits))) && ((r<<rbits) & 255) \
+ > thres) \
+ r += (1<<(8-rbits)); \
+ int g = qGreen(*p); \
+ if (g <= (255-(1<<(8-gbits))) && ((g<<gbits) & 255) \
+ > thres) \
+ g += (1<<(8-gbits)); \
+ int b = qBlue (*p++); \
+ if (b <= (255-(1<<(8-bbits))) && ((b<<bbits) & 255) \
+ > thres) \
+ b += (1<<(8-bbits)); \
+ uint pixel = ((r red_shift) & red_mask) \
+ | ((g green_shift) & green_mask) \
+ | ((b blue_shift) & blue_mask);
+
+#define CYCLE(body) \
+ for (int y=0; y<h; y++) { \
+ const uchar* src = cimage.scanLine(y); \
+ uchar* dst = newbits + xi->bytes_per_line*y; \
+ const QRgb* p = (const QRgb *)src; \
+ body \
+ }
+
+ if (dither_tc) {
+ switch (mode) {
+ case BPP16_565:
+ CYCLE(
+ quint16* dst16 = (quint16*)dst;
+ for (int x=0; x<w; x++) {
+ GET_PIXEL_DITHER_TC_OPT(<<8,<<3,>>3,0xf800,0x7e0,0x1f,5,6,5)
+ *dst16++ = pixel;
+ }
+ )
+ break;
+ case BPP16_555:
+ CYCLE(
+ quint16* dst16 = (quint16*)dst;
+ for (int x=0; x<w; x++) {
+ GET_PIXEL_DITHER_TC_OPT(<<7,<<2,>>3,0x7c00,0x3e0,0x1f,5,5,5)
+ *dst16++ = pixel;
+ }
+ )
+ break;
+ case BPP16_MSB: // 16 bit MSB
+ CYCLE(
+ for (int x=0; x<w; x++) {
+ GET_PIXEL_DITHER_TC
+ *dst++ = (pixel >> 8);
+ *dst++ = pixel;
+ }
+ )
+ break;
+ case BPP16_LSB: // 16 bit LSB
+ CYCLE(
+ for (int x=0; x<w; x++) {
+ GET_PIXEL_DITHER_TC
+ *dst++ = pixel;
+ *dst++ = pixel >> 8;
+ }
+ )
+ break;
+ default:
+ qFatal("Logic error");
+ }
+ } else {
+ switch (mode) {
+ case BPP8: // 8 bit
+ CYCLE(
+ Q_UNUSED(p);
+ for (int x=0; x<w; x++)
+ *dst++ = pix[*src++];
+ )
+ break;
+ case BPP16_565:
+ CYCLE(
+ quint16* dst16 = (quint16*)dst;
+ for (int x = 0; x < w; x++) {
+ *dst16++ = ((*p >> 8) & 0xf800)
+ | ((*p >> 5) & 0x7e0)
+ | ((*p >> 3) & 0x1f);
+ ++p;
+ }
+ )
+ break;
+ case BPP16_555:
+ CYCLE(
+ quint16* dst16 = (quint16*)dst;
+ for (int x=0; x<w; x++) {
+ *dst16++ = ((*p >> 9) & 0x7c00)
+ | ((*p >> 6) & 0x3e0)
+ | ((*p >> 3) & 0x1f);
+ ++p;
+ }
+ )
+ break;
+ case BPP16_MSB: // 16 bit MSB
+ CYCLE(
+ for (int x=0; x<w; x++) {
+ GET_PIXEL
+ *dst++ = (pixel >> 8);
+ *dst++ = pixel;
+ }
+ )
+ break;
+ case BPP16_LSB: // 16 bit LSB
+ CYCLE(
+ for (int x=0; x<w; x++) {
+ GET_PIXEL
+ *dst++ = pixel;
+ *dst++ = pixel >> 8;
+ }
+ )
+ break;
+ case BPP24_888: // 24 bit MSB
+ CYCLE(
+ for (int x=0; x<w; x++) {
+ *dst++ = qRed (*p);
+ *dst++ = qGreen(*p);
+ *dst++ = qBlue (*p++);
+ }
+ )
+ break;
+ case BPP24_MSB: // 24 bit MSB
+ CYCLE(
+ for (int x=0; x<w; x++) {
+ GET_PIXEL
+ *dst++ = pixel >> 16;
+ *dst++ = pixel >> 8;
+ *dst++ = pixel;
+ }
+ )
+ break;
+ case BPP24_LSB: // 24 bit LSB
+ CYCLE(
+ for (int x=0; x<w; x++) {
+ GET_PIXEL
+ *dst++ = pixel;
+ *dst++ = pixel >> 8;
+ *dst++ = pixel >> 16;
+ }
+ )
+ break;
+ case BPP32_8888:
+ CYCLE(
+ memcpy(dst, p, w * 4);
+ )
+ break;
+ case BPP32_MSB: // 32 bit MSB
+ CYCLE(
+ for (int x=0; x<w; x++) {
+ GET_PIXEL
+ *dst++ = pixel >> 24;
+ *dst++ = pixel >> 16;
+ *dst++ = pixel >> 8;
+ *dst++ = pixel;
+ }
+ )
+ break;
+ case BPP32_LSB: // 32 bit LSB
+ CYCLE(
+ for (int x=0; x<w; x++) {
+ GET_PIXEL
+ *dst++ = pixel;
+ *dst++ = pixel >> 8;
+ *dst++ = pixel >> 16;
+ *dst++ = pixel >> 24;
+ }
+ )
+ break;
+ default:
+ qFatal("Logic error 2");
+ }
+ }
+ xi->data = (char *)newbits;
+ }
+
+ if (d == 8 && !trucol) { // 8 bit pixmap
+ int pop[256]; // pixel popularity
+
+ if (image.colorCount() == 0)
+ image.setColorCount(1);
+
+ const QImage &cimage = image;
+ memset(pop, 0, sizeof(int)*256); // reset popularity array
+ for (int i = 0; i < h; i++) { // for each scanline...
+ const uchar* p = cimage.scanLine(i);
+ const uchar *end = p + w;
+ while (p < end) // compute popularity
+ pop[*p++]++;
+ }
+
+ newbits = (uchar *)malloc(nbytes); // copy image into newbits
+ Q_CHECK_PTR(newbits);
+ if (!newbits) // no memory
+ return;
+ uchar* p = newbits;
+ memcpy(p, cimage.bits(), nbytes); // copy image data into newbits
+
+ /*
+ * The code below picks the most important colors. It is based on the
+ * diversity algorithm, implemented in XV 3.10. XV is (C) by John Bradley.
+ */
+
+ struct PIX { // pixel sort element
+ uchar r,g,b,n; // color + pad
+ int use; // popularity
+ int index; // index in colormap
+ int mindist;
+ };
+ int ncols = 0;
+ for (int i=0; i< cimage.colorCount(); i++) { // compute number of colors
+ if (pop[i] > 0)
+ ncols++;
+ }
+ for (int i = cimage.colorCount(); i < 256; i++) // ignore out-of-range pixels
+ pop[i] = 0;
+
+ // works since we make sure above to have at least
+ // one color in the image
+ if (ncols == 0)
+ ncols = 1;
+
+ PIX pixarr[256]; // pixel array
+ PIX pixarr_sorted[256]; // pixel array (sorted)
+ memset(pixarr, 0, ncols*sizeof(PIX));
+ PIX *px = &pixarr[0];
+ int maxpop = 0;
+ int maxpix = 0;
+ uint j = 0;
+ QVector<QRgb> ctable = cimage.colorTable();
+ for (int i = 0; i < 256; i++) { // init pixel array
+ if (pop[i] > 0) {
+ px->r = qRed (ctable[i]);
+ px->g = qGreen(ctable[i]);
+ px->b = qBlue (ctable[i]);
+ px->n = 0;
+ px->use = pop[i];
+ if (pop[i] > maxpop) { // select most popular entry
+ maxpop = pop[i];
+ maxpix = j;
+ }
+ px->index = i;
+ px->mindist = 1000000;
+ px++;
+ j++;
+ }
+ }
+ pixarr_sorted[0] = pixarr[maxpix];
+ pixarr[maxpix].use = 0;
+
+ for (int i = 1; i < ncols; i++) { // sort pixels
+ int minpix = -1, mindist = -1;
+ px = &pixarr_sorted[i-1];
+ int r = px->r;
+ int g = px->g;
+ int b = px->b;
+ int dist;
+ if ((i & 1) || i<10) { // sort on max distance
+ for (int j=0; j<ncols; j++) {
+ px = &pixarr[j];
+ if (px->use) {
+ dist = (px->r - r)*(px->r - r) +
+ (px->g - g)*(px->g - g) +
+ (px->b - b)*(px->b - b);
+ if (px->mindist > dist)
+ px->mindist = dist;
+ if (px->mindist > mindist) {
+ mindist = px->mindist;
+ minpix = j;
+ }
+ }
+ }
+ } else { // sort on max popularity
+ for (int j=0; j<ncols; j++) {
+ px = &pixarr[j];
+ if (px->use) {
+ dist = (px->r - r)*(px->r - r) +
+ (px->g - g)*(px->g - g) +
+ (px->b - b)*(px->b - b);
+ if (px->mindist > dist)
+ px->mindist = dist;
+ if (px->use > mindist) {
+ mindist = px->use;
+ minpix = j;
+ }
+ }
+ }
+ }
+ pixarr_sorted[i] = pixarr[minpix];
+ pixarr[minpix].use = 0;
+ }
+
+ QColormap cmap = QColormap::instance(xinfo.screen());
+ uint pix[256]; // pixel translation table
+ px = &pixarr_sorted[0];
+ for (int i = 0; i < ncols; i++) { // allocate colors
+ QColor c(px->r, px->g, px->b);
+ pix[px->index] = cmap.pixel(c);
+ px++;
+ }
+
+ p = newbits;
+ for (int i = 0; i < nbytes; i++) { // translate pixels
+ *p = pix[*p];
+ p++;
+ }
+ }
+
+ if (!xi) { // X image not created
+ xi = XCreateImage(dpy, visual, dd, ZPixmap, 0, 0, w, h, 32, 0);
+ if (xi->bits_per_pixel == 16) { // convert 8 bpp ==> 16 bpp
+ ushort *p2;
+ int p2inc = xi->bytes_per_line/sizeof(ushort);
+ ushort *newerbits = (ushort *)malloc(xi->bytes_per_line * h);
+ Q_CHECK_PTR(newerbits);
+ if (!newerbits) // no memory
+ return;
+ uchar* p = newbits;
+ for (int y = 0; y < h; y++) { // OOPS: Do right byte order!!
+ p2 = newerbits + p2inc*y;
+ for (int x = 0; x < w; x++)
+ *p2++ = *p++;
+ }
+ free(newbits);
+ newbits = (uchar *)newerbits;
+ } else if (xi->bits_per_pixel != 8) {
+ qWarning("QPixmap::fromImage: Display not supported "
+ "(bpp=%d)", xi->bits_per_pixel);
+ }
+ xi->data = (char *)newbits;
+ }
+
+ hd = (Qt::HANDLE)XCreatePixmap(X11->display,
+ RootWindow(X11->display, xinfo.screen()),
+ w, h, dd);
+
+ GC gc = XCreateGC(dpy, hd, 0, 0);
+ XPutImage(dpy, hd, gc, xi, 0, 0, 0, 0, w, h);
+ XFreeGC(dpy, gc);
+
+ qSafeXDestroyImage(xi);
+ d = dd;
+
+#ifndef QT_NO_XRENDER
+ if (X11->use_xrender) {
+ XRenderPictFormat *format = d == 1
+ ? XRenderFindStandardFormat(X11->display, PictStandardA1)
+ : XRenderFindVisualFormat(X11->display, (Visual *)xinfo.visual());
+ picture = XRenderCreatePicture(X11->display, hd, format, 0, 0);
+ }
+#endif
+
+ if (alphaCheck.hasAlpha()) {
+ QBitmap m = QBitmap::fromImage(image.createAlphaMask(flags));
+ setMask(m);
+ }
+}
+
+Qt::HANDLE QX11PlatformPixmap::createBitmapFromImage(const QImage &image)
+{
+ QImage img = image.convertToFormat(QImage::Format_MonoLSB);
+ const QRgb c0 = QColor(Qt::black).rgb();
+ const QRgb c1 = QColor(Qt::white).rgb();
+ if (img.color(0) == c0 && img.color(1) == c1) {
+ img.invertPixels();
+ img.setColor(0, c1);
+ img.setColor(1, c0);
+ }
+
+ char *bits;
+ uchar *tmp_bits;
+ int w = img.width();
+ int h = img.height();
+ int bpl = (w + 7) / 8;
+ int ibpl = img.bytesPerLine();
+ if (bpl != ibpl) {
+ tmp_bits = new uchar[bpl*h];
+ bits = (char *)tmp_bits;
+ uchar *p, *b;
+ int y;
+ b = tmp_bits;
+ p = img.scanLine(0);
+ for (y = 0; y < h; y++) {
+ memcpy(b, p, bpl);
+ b += bpl;
+ p += ibpl;
+ }
+ } else {
+ bits = (char *)img.bits();
+ tmp_bits = 0;
+ }
+ Qt::HANDLE hd = (Qt::HANDLE)XCreateBitmapFromData(X11->display,
+ QX11Info::appRootWindow(),
+ bits, w, h);
+ if (tmp_bits) // Avoid purify complaint
+ delete [] tmp_bits;
+ return hd;
+}
+
+void QX11PlatformPixmap::bitmapFromImage(const QImage &image)
+{
+ w = image.width();
+ h = image.height();
+ d = 1;
+ is_null = (w <= 0 || h <= 0);
+ hd = createBitmapFromImage(image);
+#ifndef QT_NO_XRENDER
+ if (X11->use_xrender)
+ picture = XRenderCreatePicture(X11->display, hd,
+ XRenderFindStandardFormat(X11->display, PictStandardA1), 0, 0);
+#endif // QT_NO_XRENDER
+}
+
+void QX11PlatformPixmap::fill(const QColor &fillColor)
+{
+ if (fillColor.alpha() != 255) {
+#ifndef QT_NO_XRENDER
+ if (X11->use_xrender) {
+ if (!picture || d != 32)
+ convertToARGB32(/*preserveContents = */false);
+
+ ::Picture src = X11->getSolidFill(xinfo.screen(), fillColor);
+ XRenderComposite(X11->display, PictOpSrc, src, 0, picture,
+ 0, 0, width(), height(),
+ 0, 0, width(), height());
+ } else
+#endif
+ {
+ QImage im(width(), height(), QImage::Format_ARGB32_Premultiplied);
+ im.fill(PREMUL(fillColor.rgba()));
+ release();
+ fromImage(im, Qt::AutoColor | Qt::OrderedAlphaDither);
+ }
+ return;
+ }
+
+ GC gc = XCreateGC(X11->display, hd, 0, 0);
+ if (depth() == 1) {
+ XSetForeground(X11->display, gc, qGray(fillColor.rgb()) > 127 ? 0 : 1);
+ } else if (X11->use_xrender && d >= 24) {
+ XSetForeground(X11->display, gc, fillColor.rgba());
+ } else {
+ XSetForeground(X11->display, gc,
+ QColormap::instance(xinfo.screen()).pixel(fillColor));
+ }
+ XFillRectangle(X11->display, hd, gc, 0, 0, width(), height());
+ XFreeGC(X11->display, gc);
+}
+
+QX11PlatformPixmap::~QX11PlatformPixmap()
+{
+ // Cleanup hooks have to be called before the handles are freed
+ if (is_cached) {
+ QImagePixmapCleanupHooks::executePlatformPixmapDestructionHooks(this);
+ is_cached = false;
+ }
+
+ release();
+}
+
+void QX11PlatformPixmap::release()
+{
+ delete pengine;
+ pengine = 0;
+
+ if (!X11) {
+ // At this point, the X server will already have freed our resources,
+ // so there is nothing to do.
+ return;
+ }
+
+ if (x11_mask) {
+#ifndef QT_NO_XRENDER
+ if (mask_picture)
+ XRenderFreePicture(X11->display, mask_picture);
+ mask_picture = 0;
+#endif
+ XFreePixmap(X11->display, x11_mask);
+ x11_mask = 0;
+ }
+
+ if (hd) {
+#ifndef QT_NO_XRENDER
+ if (picture) {
+ XRenderFreePicture(X11->display, picture);
+ picture = 0;
+ }
+#endif // QT_NO_XRENDER
+
+ if (hd2) {
+ XFreePixmap(xinfo.display(), hd2);
+ hd2 = 0;
+ }
+ if (!(flags & Readonly))
+ XFreePixmap(xinfo.display(), hd);
+ hd = 0;
+ }
+}
+
+QPixmap QX11PlatformPixmap::alphaChannel() const
+{
+ if (!hasAlphaChannel()) {
+ QPixmap pm(w, h);
+ pm.fill(Qt::white);
+ return pm;
+ }
+ QImage im(toImage());
+ return QPixmap::fromImage(im.alphaChannel(), Qt::OrderedDither);
+}
+
+void QX11PlatformPixmap::setAlphaChannel(const QPixmap &alpha)
+{
+ QImage image(toImage());
+ image.setAlphaChannel(alpha.toImage());
+ release();
+ fromImage(image, Qt::OrderedDither | Qt::OrderedAlphaDither);
+}
+
+
+QBitmap QX11PlatformPixmap::mask() const
+{
+ QBitmap mask;
+#ifndef QT_NO_XRENDER
+ if (picture && d == 32) {
+ // #### slow - there must be a better way..
+ mask = QBitmap::fromImage(toImage().createAlphaMask());
+ } else
+#endif
+ if (d == 1) {
+ QX11PlatformPixmap *that = const_cast<QX11PlatformPixmap*>(this);
+ mask = QPixmap(that);
+ } else {
+ mask = mask_to_bitmap(xinfo.screen());
+ }
+ return mask;
+}
+
+/*!
+ Sets a mask bitmap.
+
+ The \a newmask bitmap defines the clip mask for this pixmap. Every
+ pixel in \a newmask corresponds to a pixel in this pixmap. Pixel
+ value 1 means opaque and pixel value 0 means transparent. The mask
+ must have the same size as this pixmap.
+
+ \warning Setting the mask on a pixmap will cause any alpha channel
+ data to be cleared. For example:
+ \snippet doc/src/snippets/image/image.cpp 2
+ Now, alpha and alphacopy are visually different.
+
+ Setting a null mask resets the mask.
+
+ The effect of this function is undefined when the pixmap is being
+ painted on.
+
+ \sa mask(), {QPixmap#Pixmap Transformations}{Pixmap
+ Transformations}, QBitmap
+*/
+void QX11PlatformPixmap::setMask(const QBitmap &newmask)
+{
+ if (newmask.isNull()) { // clear mask
+#ifndef QT_NO_XRENDER
+ if (picture && d == 32) {
+ QX11PlatformPixmap newData(pixelType());
+ newData.resize(w, h);
+ newData.fill(Qt::black);
+ XRenderComposite(X11->display, PictOpOver,
+ picture, 0, newData.picture,
+ 0, 0, 0, 0, 0, 0, w, h);
+ release();
+ *this = newData;
+ // the new QX11PlatformPixmap object isn't referenced yet, so
+ // ref it
+ ref.ref();
+
+ // the below is to make sure the QX11PlatformPixmap destructor
+ // doesn't delete our newly created render picture
+ newData.hd = 0;
+ newData.x11_mask = 0;
+ newData.picture = 0;
+ newData.mask_picture = 0;
+ newData.hd2 = 0;
+ } else
+#endif
+ if (x11_mask) {
+#ifndef QT_NO_XRENDER
+ if (picture) {
+ XRenderPictureAttributes attrs;
+ attrs.alpha_map = 0;
+ XRenderChangePicture(X11->display, picture, CPAlphaMap,
+ &attrs);
+ }
+ if (mask_picture)
+ XRenderFreePicture(X11->display, mask_picture);
+ mask_picture = 0;
+#endif
+ XFreePixmap(X11->display, x11_mask);
+ x11_mask = 0;
+ }
+ return;
+ }
+
+#ifndef QT_NO_XRENDER
+ if (picture && d == 32) {
+ XRenderComposite(X11->display, PictOpSrc,
+ picture, newmask.x11PictureHandle(),
+ picture, 0, 0, 0, 0, 0, 0, w, h);
+ } else
+#endif
+ if (depth() == 1) {
+ XGCValues vals;
+ vals.function = GXand;
+ GC gc = XCreateGC(X11->display, hd, GCFunction, &vals);
+ XCopyArea(X11->display, newmask.handle(), hd, gc, 0, 0,
+ width(), height(), 0, 0);
+ XFreeGC(X11->display, gc);
+ } else {
+ // ##### should or the masks together
+ if (x11_mask) {
+ XFreePixmap(X11->display, x11_mask);
+#ifndef QT_NO_XRENDER
+ if (mask_picture)
+ XRenderFreePicture(X11->display, mask_picture);
+#endif
+ }
+ x11_mask = QX11PlatformPixmap::bitmap_to_mask(newmask, xinfo.screen());
+#ifndef QT_NO_XRENDER
+ if (picture) {
+ mask_picture = XRenderCreatePicture(X11->display, x11_mask,
+ XRenderFindStandardFormat(X11->display, PictStandardA1), 0, 0);
+ XRenderPictureAttributes attrs;
+ attrs.alpha_map = mask_picture;
+ XRenderChangePicture(X11->display, picture, CPAlphaMap, &attrs);
+ }
+#endif
+ }
+}
+
+int QX11PlatformPixmap::metric(QPaintDevice::PaintDeviceMetric metric) const
+{
+ switch (metric) {
+ case QPaintDevice::PdmWidth:
+ return w;
+ case QPaintDevice::PdmHeight:
+ return h;
+ case QPaintDevice::PdmNumColors:
+ return 1 << d;
+ case QPaintDevice::PdmDepth:
+ return d;
+ case QPaintDevice::PdmWidthMM: {
+ const int screen = xinfo.screen();
+ const int mm = DisplayWidthMM(X11->display, screen) * w
+ / DisplayWidth(X11->display, screen);
+ return mm;
+ }
+ case QPaintDevice::PdmHeightMM: {
+ const int screen = xinfo.screen();
+ const int mm = (DisplayHeightMM(X11->display, screen) * h)
+ / DisplayHeight(X11->display, screen);
+ return mm;
+ }
+ case QPaintDevice::PdmDpiX:
+ case QPaintDevice::PdmPhysicalDpiX:
+ return QX11Info::appDpiX(xinfo.screen());
+ case QPaintDevice::PdmDpiY:
+ case QPaintDevice::PdmPhysicalDpiY:
+ return QX11Info::appDpiY(xinfo.screen());
+ default:
+ qWarning("QX11PlatformPixmap::metric(): Invalid metric");
+ return 0;
+ }
+}
+
+struct QXImageWrapper
+{
+ XImage *xi;
+};
+
+bool QX11PlatformPixmap::canTakeQImageFromXImage(const QXImageWrapper &xiWrapper) const
+{
+ XImage *xi = xiWrapper.xi;
+
+ // ARGB32_Premultiplied
+ if (picture && depth() == 32)
+ return true;
+
+ Visual *visual = (Visual *)xinfo.visual();
+
+ // RGB32
+ if (depth() == 24 && xi->bits_per_pixel == 32 && visual->red_mask == 0xff0000
+ && visual->green_mask == 0xff00 && visual->blue_mask == 0xff)
+ return true;
+
+ // RGB16
+ if (depth() == 16 && xi->bits_per_pixel == 16 && visual->red_mask == 0xf800
+ && visual->green_mask == 0x7e0 && visual->blue_mask == 0x1f)
+ return true;
+
+ return false;
+}
+
+QImage QX11PlatformPixmap::takeQImageFromXImage(const QXImageWrapper &xiWrapper) const
+{
+ XImage *xi = xiWrapper.xi;
+
+ QImage::Format format = QImage::Format_ARGB32_Premultiplied;
+ if (depth() == 24)
+ format = QImage::Format_RGB32;
+ else if (depth() == 16)
+ format = QImage::Format_RGB16;
+
+ QImage image((uchar *)xi->data, xi->width, xi->height, xi->bytes_per_line, format);
+ // take ownership
+ image.data_ptr()->own_data = true;
+ xi->data = 0;
+
+ // we may have to swap the byte order
+ if ((QSysInfo::ByteOrder == QSysInfo::LittleEndian && xi->byte_order == MSBFirst)
+ || (QSysInfo::ByteOrder == QSysInfo::BigEndian && xi->byte_order == LSBFirst))
+ {
+ for (int i=0; i < image.height(); i++) {
+ if (depth() == 16) {
+ ushort *p = (ushort*)image.scanLine(i);
+ ushort *end = p + image.width();
+ while (p < end) {
+ *p = ((*p << 8) & 0xff00) | ((*p >> 8) & 0x00ff);
+ p++;
+ }
+ } else {
+ uint *p = (uint*)image.scanLine(i);
+ uint *end = p + image.width();
+ while (p < end) {
+ *p = ((*p << 24) & 0xff000000) | ((*p << 8) & 0x00ff0000)
+ | ((*p >> 8) & 0x0000ff00) | ((*p >> 24) & 0x000000ff);
+ p++;
+ }
+ }
+ }
+ }
+
+ // fix-up alpha channel
+ if (format == QImage::Format_RGB32) {
+ QRgb *p = (QRgb *)image.bits();
+ for (int y = 0; y < xi->height; ++y) {
+ for (int x = 0; x < xi->width; ++x)
+ p[x] |= 0xff000000;
+ p += xi->bytes_per_line / 4;
+ }
+ }
+
+ XDestroyImage(xi);
+ return image;
+}
+
+QImage QX11PlatformPixmap::toImage(const QRect &rect) const
+{
+ QXImageWrapper xiWrapper;
+ xiWrapper.xi = XGetImage(X11->display, hd, rect.x(), rect.y(), rect.width(), rect.height(),
+ AllPlanes, (depth() == 1) ? XYPixmap : ZPixmap);
+
+ Q_CHECK_PTR(xiWrapper.xi);
+ if (!xiWrapper.xi)
+ return QImage();
+
+ if (!x11_mask && canTakeQImageFromXImage(xiWrapper))
+ return takeQImageFromXImage(xiWrapper);
+
+ QImage image = toImage(xiWrapper, rect);
+ qSafeXDestroyImage(xiWrapper.xi);
+ return image;
+}
+
+/*!
+ Converts the pixmap to a QImage. Returns a null image if the
+ conversion fails.
+
+ If the pixmap has 1-bit depth, the returned image will also be 1
+ bit deep. If the pixmap has 2- to 8-bit depth, the returned image
+ has 8-bit depth. If the pixmap has greater than 8-bit depth, the
+ returned image has 32-bit depth.
+
+ Note that for the moment, alpha masks on monochrome images are
+ ignored.
+
+ \sa fromImage(), {QImage#Image Formats}{Image Formats}
+*/
+
+QImage QX11PlatformPixmap::toImage() const
+{
+ return toImage(QRect(0, 0, w, h));
+}
+
+QImage QX11PlatformPixmap::toImage(const QXImageWrapper &xiWrapper, const QRect &rect) const
+{
+ XImage *xi = xiWrapper.xi;
+
+ int d = depth();
+ Visual *visual = (Visual *)xinfo.visual();
+ bool trucol = (visual->c_class >= TrueColor) && d > 1;
+
+ QImage::Format format = QImage::Format_Mono;
+ if (d > 1 && d <= 8) {
+ d = 8;
+ format = QImage::Format_Indexed8;
+ }
+ // we could run into the situation where d == 8 AND trucol is true, which can
+ // cause problems when converting to and from images. in this case, always treat
+ // the depth as 32...
+ if (d > 8 || trucol) {
+ d = 32;
+ format = QImage::Format_RGB32;
+ }
+
+ if (d == 1 && xi->bitmap_bit_order == LSBFirst)
+ format = QImage::Format_MonoLSB;
+ if (x11_mask && format == QImage::Format_RGB32)
+ format = QImage::Format_ARGB32;
+
+ QImage image(xi->width, xi->height, format);
+ if (image.isNull()) // could not create image
+ return image;
+
+ QImage alpha;
+ if (x11_mask) {
+ if (rect.contains(QRect(0, 0, w, h)))
+ alpha = mask().toImage();
+ else
+ alpha = mask().toImage().copy(rect);
+ }
+ bool ale = alpha.format() == QImage::Format_MonoLSB;
+
+ if (trucol) { // truecolor
+ const uint red_mask = (uint)visual->red_mask;
+ const uint green_mask = (uint)visual->green_mask;
+ const uint blue_mask = (uint)visual->blue_mask;
+ const int red_shift = highest_bit(red_mask) - 7;
+ const int green_shift = highest_bit(green_mask) - 7;
+ const int blue_shift = highest_bit(blue_mask) - 7;
+
+ const uint red_bits = n_bits(red_mask);
+ const uint green_bits = n_bits(green_mask);
+ const uint blue_bits = n_bits(blue_mask);
+
+ static uint red_table_bits = 0;
+ static uint green_table_bits = 0;
+ static uint blue_table_bits = 0;
+
+ if (red_bits < 8 && red_table_bits != red_bits) {
+ build_scale_table(&red_scale_table, red_bits);
+ red_table_bits = red_bits;
+ }
+ if (blue_bits < 8 && blue_table_bits != blue_bits) {
+ build_scale_table(&blue_scale_table, blue_bits);
+ blue_table_bits = blue_bits;
+ }
+ if (green_bits < 8 && green_table_bits != green_bits) {
+ build_scale_table(&green_scale_table, green_bits);
+ green_table_bits = green_bits;
+ }
+
+ int r, g, b;
+
+ QRgb *dst;
+ uchar *src;
+ uint pixel;
+ int bppc = xi->bits_per_pixel;
+
+ if (bppc > 8 && xi->byte_order == LSBFirst)
+ bppc++;
+
+ for (int y = 0; y < xi->height; ++y) {
+ uchar* asrc = x11_mask ? alpha.scanLine(y) : 0;
+ dst = (QRgb *)image.scanLine(y);
+ src = (uchar *)xi->data + xi->bytes_per_line*y;
+ for (int x = 0; x < xi->width; x++) {
+ switch (bppc) {
+ case 8:
+ pixel = *src++;
+ break;
+ case 16: // 16 bit MSB
+ pixel = src[1] | (uint)src[0] << 8;
+ src += 2;
+ break;
+ case 17: // 16 bit LSB
+ pixel = src[0] | (uint)src[1] << 8;
+ src += 2;
+ break;
+ case 24: // 24 bit MSB
+ pixel = src[2] | (uint)src[1] << 8 | (uint)src[0] << 16;
+ src += 3;
+ break;
+ case 25: // 24 bit LSB
+ pixel = src[0] | (uint)src[1] << 8 | (uint)src[2] << 16;
+ src += 3;
+ break;
+ case 32: // 32 bit MSB
+ pixel = src[3] | (uint)src[2] << 8 | (uint)src[1] << 16 | (uint)src[0] << 24;
+ src += 4;
+ break;
+ case 33: // 32 bit LSB
+ pixel = src[0] | (uint)src[1] << 8 | (uint)src[2] << 16 | (uint)src[3] << 24;
+ src += 4;
+ break;
+ default: // should not really happen
+ x = xi->width; // leave loop
+ y = xi->height;
+ pixel = 0; // eliminate compiler warning
+ qWarning("QPixmap::convertToImage: Invalid depth %d", bppc);
+ }
+ if (red_shift > 0)
+ r = (pixel & red_mask) >> red_shift;
+ else
+ r = (pixel & red_mask) << -red_shift;
+ if (green_shift > 0)
+ g = (pixel & green_mask) >> green_shift;
+ else
+ g = (pixel & green_mask) << -green_shift;
+ if (blue_shift > 0)
+ b = (pixel & blue_mask) >> blue_shift;
+ else
+ b = (pixel & blue_mask) << -blue_shift;
+
+ if (red_bits < 8)
+ r = red_scale_table[r];
+ if (green_bits < 8)
+ g = green_scale_table[g];
+ if (blue_bits < 8)
+ b = blue_scale_table[b];
+
+ if (x11_mask) {
+ if (ale) {
+ *dst++ = (asrc[x >> 3] & (1 << (x & 7))) ? qRgba(r, g, b, 0xff) : 0;
+ } else {
+ *dst++ = (asrc[x >> 3] & (0x80 >> (x & 7))) ? qRgba(r, g, b, 0xff) : 0;
+ }
+ } else {
+ *dst++ = qRgb(r, g, b);
+ }
+ }
+ }
+ } else if (xi->bits_per_pixel == d) { // compatible depth
+ char *xidata = xi->data; // copy each scanline
+ int bpl = qMin(image.bytesPerLine(),xi->bytes_per_line);
+ for (int y=0; y<xi->height; y++) {
+ memcpy(image.scanLine(y), xidata, bpl);
+ xidata += xi->bytes_per_line;
+ }
+ } else {
+ /* Typically 2 or 4 bits display depth */
+ qWarning("QPixmap::convertToImage: Display not supported (bpp=%d)",
+ xi->bits_per_pixel);
+ return QImage();
+ }
+
+ if (d == 1) { // bitmap
+ image.setColorCount(2);
+ image.setColor(0, qRgb(255,255,255));
+ image.setColor(1, qRgb(0,0,0));
+ } else if (!trucol) { // pixmap with colormap
+ register uchar *p;
+ uchar *end;
+ uchar use[256]; // pixel-in-use table
+ uchar pix[256]; // pixel translation table
+ int ncols, bpl;
+ memset(use, 0, 256);
+ memset(pix, 0, 256);
+ bpl = image.bytesPerLine();
+
+ if (x11_mask) { // which pixels are used?
+ for (int i = 0; i < xi->height; i++) {
+ uchar* asrc = alpha.scanLine(i);
+ p = image.scanLine(i);
+ if (ale) {
+ for (int x = 0; x < xi->width; x++) {
+ if (asrc[x >> 3] & (1 << (x & 7)))
+ use[*p] = 1;
+ ++p;
+ }
+ } else {
+ for (int x = 0; x < xi->width; x++) {
+ if (asrc[x >> 3] & (0x80 >> (x & 7)))
+ use[*p] = 1;
+ ++p;
+ }
+ }
+ }
+ } else {
+ for (int i = 0; i < xi->height; i++) {
+ p = image.scanLine(i);
+ end = p + bpl;
+ while (p < end)
+ use[*p++] = 1;
+ }
+ }
+ ncols = 0;
+ for (int i = 0; i < 256; i++) { // build translation table
+ if (use[i])
+ pix[i] = ncols++;
+ }
+ for (int i = 0; i < xi->height; i++) { // translate pixels
+ p = image.scanLine(i);
+ end = p + bpl;
+ while (p < end) {
+ *p = pix[*p];
+ p++;
+ }
+ }
+ if (x11_mask) {
+ int trans;
+ if (ncols < 256) {
+ trans = ncols++;
+ image.setColorCount(ncols); // create color table
+ image.setColor(trans, 0x00000000);
+ } else {
+ image.setColorCount(ncols); // create color table
+ // oh dear... no spare "transparent" pixel.
+ // use first pixel in image (as good as any).
+ trans = image.scanLine(0)[0];
+ }
+ for (int i = 0; i < xi->height; i++) {
+ uchar* asrc = alpha.scanLine(i);
+ p = image.scanLine(i);
+ if (ale) {
+ for (int x = 0; x < xi->width; x++) {
+ if (!(asrc[x >> 3] & (1 << (x & 7))))
+ *p = trans;
+ ++p;
+ }
+ } else {
+ for (int x = 0; x < xi->width; x++) {
+ if (!(asrc[x >> 3] & (1 << (7 -(x & 7)))))
+ *p = trans;
+ ++p;
+ }
+ }
+ }
+ } else {
+ image.setColorCount(ncols); // create color table
+ }
+ QVector<QColor> colors = QColormap::instance(xinfo.screen()).colormap();
+ int j = 0;
+ for (int i=0; i<colors.size(); i++) { // translate pixels
+ if (use[i])
+ image.setColor(j++, 0xff000000 | colors.at(i).rgb());
+ }
+ }
+
+ return image;
+}
+
+/*!
+ Returns a copy of the pixmap that is transformed using the given
+ transformation \a matrix and transformation \a mode. The original
+ pixmap is not changed.
+
+ The transformation \a matrix is internally adjusted to compensate
+ for unwanted translation; i.e. the pixmap produced is the smallest
+ pixmap that contains all the transformed points of the original
+ pixmap. Use the trueMatrix() function to retrieve the actual
+ matrix used for transforming the pixmap.
+
+ This function is slow because it involves transformation to a
+ QImage, non-trivial computations and a transformation back to a
+ QPixmap.
+
+ \sa trueMatrix(), {QPixmap#Pixmap Transformations}{Pixmap
+ Transformations}
+*/
+QPixmap QX11PlatformPixmap::transformed(const QTransform &transform,
+ Qt::TransformationMode mode ) const
+{
+ if (mode == Qt::SmoothTransformation || transform.type() >= QTransform::TxProject) {
+ QImage image = toImage();
+ return QPixmap::fromImage(image.transformed(transform, mode));
+ }
+
+ uint w = 0;
+ uint h = 0; // size of target pixmap
+ uint ws, hs; // size of source pixmap
+ uchar *dptr; // data in target pixmap
+ uint dbpl, dbytes; // bytes per line/bytes total
+ uchar *sptr; // data in original pixmap
+ int sbpl; // bytes per line in original
+ int bpp; // bits per pixel
+ bool depth1 = depth() == 1;
+ Display *dpy = X11->display;
+
+ ws = width();
+ hs = height();
+
+ QTransform mat(transform.m11(), transform.m12(), transform.m13(),
+ transform.m21(), transform.m22(), transform.m23(),
+ 0., 0., 1);
+ bool complex_xform = false;
+ qreal scaledWidth;
+ qreal scaledHeight;
+
+ if (mat.type() <= QTransform::TxScale) {
+ scaledHeight = qAbs(mat.m22()) * hs + 0.9999;
+ scaledWidth = qAbs(mat.m11()) * ws + 0.9999;
+ h = qAbs(int(scaledHeight));
+ w = qAbs(int(scaledWidth));
+ } else { // rotation or shearing
+ QPolygonF a(QRectF(0, 0, ws, hs));
+ a = mat.map(a);
+ QRect r = a.boundingRect().toAlignedRect();
+ w = r.width();
+ h = r.height();
+ scaledWidth = w;
+ scaledHeight = h;
+ complex_xform = true;
+ }
+ mat = QPixmap::trueMatrix(mat, ws, hs); // true matrix
+
+ bool invertible;
+ mat = mat.inverted(&invertible); // invert matrix
+
+ if (h == 0 || w == 0 || !invertible
+ || qAbs(scaledWidth) >= 32768 || qAbs(scaledHeight) >= 32768 )
+ // error, return null pixmap
+ return QPixmap();
+
+#if defined(QT_MITSHM)
+ static bool try_once = true;
+ if (try_once) {
+ try_once = false;
+ if (!xshminit)
+ qt_create_mitshm_buffer(this, 800, 600);
+ }
+
+ bool use_mitshm = xshmimg && !depth1 &&
+ xshmimg->width >= w && xshmimg->height >= h;
+#endif
+ XImage *xi = XGetImage(X11->display, handle(), 0, 0, ws, hs, AllPlanes,
+ depth1 ? XYPixmap : ZPixmap);
+
+ if (!xi)
+ return QPixmap();
+
+ sbpl = xi->bytes_per_line;
+ sptr = (uchar *)xi->data;
+ bpp = xi->bits_per_pixel;
+
+ if (depth1)
+ dbpl = (w+7)/8;
+ else
+ dbpl = ((w*bpp+31)/32)*4;
+ dbytes = dbpl*h;
+
+#if defined(QT_MITSHM)
+ if (use_mitshm) {
+ dptr = (uchar *)xshmimg->data;
+ uchar fillbyte = bpp == 8 ? white.pixel() : 0xff;
+ for (int y=0; y<h; y++)
+ memset(dptr + y*xshmimg->bytes_per_line, fillbyte, dbpl);
+ } else {
+#endif
+ dptr = (uchar *)malloc(dbytes); // create buffer for bits
+ Q_CHECK_PTR(dptr);
+ if (depth1) // fill with zeros
+ memset(dptr, 0, dbytes);
+ else if (bpp == 8) // fill with background color
+ memset(dptr, WhitePixel(X11->display, xinfo.screen()), dbytes);
+ else
+ memset(dptr, 0, dbytes);
+#if defined(QT_MITSHM)
+ }
+#endif
+
+ // #define QT_DEBUG_XIMAGE
+#if defined(QT_DEBUG_XIMAGE)
+ qDebug("----IMAGE--INFO--------------");
+ qDebug("width............. %d", xi->width);
+ qDebug("height............ %d", xi->height);
+ qDebug("xoffset........... %d", xi->xoffset);
+ qDebug("format............ %d", xi->format);
+ qDebug("byte order........ %d", xi->byte_order);
+ qDebug("bitmap unit....... %d", xi->bitmap_unit);
+ qDebug("bitmap bit order.. %d", xi->bitmap_bit_order);
+ qDebug("depth............. %d", xi->depth);
+ qDebug("bytes per line.... %d", xi->bytes_per_line);
+ qDebug("bits per pixel.... %d", xi->bits_per_pixel);
+#endif
+
+ int type;
+ if (xi->bitmap_bit_order == MSBFirst)
+ type = QT_XFORM_TYPE_MSBFIRST;
+ else
+ type = QT_XFORM_TYPE_LSBFIRST;
+ int xbpl, p_inc;
+ if (depth1) {
+ xbpl = (w+7)/8;
+ p_inc = dbpl - xbpl;
+ } else {
+ xbpl = (w*bpp)/8;
+ p_inc = dbpl - xbpl;
+#if defined(QT_MITSHM)
+ if (use_mitshm)
+ p_inc = xshmimg->bytes_per_line - xbpl;
+#endif
+ }
+
+ if (!qt_xForm_helper(mat, xi->xoffset, type, bpp, dptr, xbpl, p_inc, h, sptr, sbpl, ws, hs)){
+ qWarning("QPixmap::transform: display not supported (bpp=%d)",bpp);
+ QPixmap pm;
+ return pm;
+ }
+
+ qSafeXDestroyImage(xi);
+
+ if (depth1) { // mono bitmap
+ QBitmap bm = QBitmap::fromData(QSize(w, h), dptr,
+ BitmapBitOrder(X11->display) == MSBFirst
+ ? QImage::Format_Mono
+ : QImage::Format_MonoLSB);
+ free(dptr);
+ return bm;
+ } else { // color pixmap
+ QX11PlatformPixmap *x11Data = new QX11PlatformPixmap(QPlatformPixmap::PixmapType);
+ QPixmap pm(x11Data);
+ x11Data->flags &= ~QX11PlatformPixmap::Uninitialized;
+ x11Data->xinfo = xinfo;
+ x11Data->d = d;
+ x11Data->w = w;
+ x11Data->h = h;
+ x11Data->is_null = (w <= 0 || h <= 0);
+ x11Data->hd = (Qt::HANDLE)XCreatePixmap(X11->display,
+ RootWindow(X11->display, xinfo.screen()),
+ w, h, d);
+ x11Data->setSerialNumber(qt_pixmap_serial.fetchAndAddRelaxed(1));
+
+#ifndef QT_NO_XRENDER
+ if (X11->use_xrender) {
+ XRenderPictFormat *format = x11Data->d == 32
+ ? XRenderFindStandardFormat(X11->display, PictStandardARGB32)
+ : XRenderFindVisualFormat(X11->display, (Visual *) x11Data->xinfo.visual());
+ x11Data->picture = XRenderCreatePicture(X11->display, x11Data->hd, format, 0, 0);
+ }
+#endif // QT_NO_XRENDER
+
+ GC gc = XCreateGC(X11->display, x11Data->hd, 0, 0);
+#if defined(QT_MITSHM)
+ if (use_mitshm) {
+ XCopyArea(dpy, xshmpm, x11Data->hd, gc, 0, 0, w, h, 0, 0);
+ } else
+#endif
+ {
+ xi = XCreateImage(dpy, (Visual*)x11Data->xinfo.visual(),
+ x11Data->d,
+ ZPixmap, 0, (char *)dptr, w, h, 32, 0);
+ XPutImage(dpy, pm.handle(), gc, xi, 0, 0, 0, 0, w, h);
+ qSafeXDestroyImage(xi);
+ }
+ XFreeGC(X11->display, gc);
+
+ if (x11_mask) { // xform mask, too
+ pm.setMask(mask_to_bitmap(xinfo.screen()).transformed(transform));
+ } else if (d != 32 && complex_xform) { // need a mask!
+ QBitmap mask(ws, hs);
+ mask.fill(Qt::color1);
+ pm.setMask(mask.transformed(transform));
+ }
+ return pm;
+ }
+}
+
+int QPixmap::x11SetDefaultScreen(int screen)
+{
+ int old = defaultScreen;
+ defaultScreen = screen;
+ return old;
+}
+
+void QPixmap::x11SetScreen(int screen)
+{
+ if (paintingActive()) {
+ qWarning("QPixmap::x11SetScreen(): Cannot change screens during painting");
+ return;
+ }
+
+ if (isNull())
+ return;
+
+ if (data->classId() != QPlatformPixmap::X11Class)
+ return;
+
+ if (screen < 0)
+ screen = QX11Info::appScreen();
+
+ QX11PlatformPixmap *x11Data = static_cast<QX11PlatformPixmap*>(data.data());
+ if (screen == x11Data->xinfo.screen())
+ return; // nothing to do
+
+ if (isNull()) {
+ QX11InfoData* xd = x11Data->xinfo.getX11Data(true);
+ xd->screen = screen;
+ xd->depth = QX11Info::appDepth(screen);
+ xd->cells = QX11Info::appCells(screen);
+ xd->colormap = QX11Info::appColormap(screen);
+ xd->defaultColormap = QX11Info::appDefaultColormap(screen);
+ xd->visual = (Visual *)QX11Info::appVisual(screen);
+ xd->defaultVisual = QX11Info::appDefaultVisual(screen);
+ x11Data->xinfo.setX11Data(xd);
+ return;
+ }
+#if 0
+ qDebug("QPixmap::x11SetScreen for %p from %d to %d. Size is %d/%d", x11Data, x11Data->xinfo.screen(), screen, width(), height());
+#endif
+
+ x11SetDefaultScreen(screen);
+ *this = qt_toX11Pixmap(toImage());
+}
+
+QPixmap QPixmap::grabWindow(WId window, int x, int y, int w, int h)
+{
+ if (w == 0 || h == 0)
+ return QPixmap();
+
+ Display *dpy = X11->display;
+ XWindowAttributes window_attr;
+ if (!XGetWindowAttributes(dpy, window, &window_attr))
+ return QPixmap();
+
+ if (w < 0)
+ w = window_attr.width - x;
+ if (h < 0)
+ h = window_attr.height - y;
+
+ // determine the screen
+ int scr;
+ for (scr = 0; scr < ScreenCount(dpy); ++scr) {
+ if (window_attr.root == RootWindow(dpy, scr)) // found it
+ break;
+ }
+ if (scr >= ScreenCount(dpy)) // sanity check
+ return QPixmap();
+
+
+ // get the depth of the root window
+ XWindowAttributes root_attr;
+ if (!XGetWindowAttributes(dpy, window_attr.root, &root_attr))
+ return QPixmap();
+
+ if (window_attr.depth == root_attr.depth) {
+ // if the depth of the specified window and the root window are the
+ // same, grab pixels from the root window (so that we get the any
+ // overlapping windows and window manager frames)
+
+ // map x and y to the root window
+ WId unused;
+ if (!XTranslateCoordinates(dpy, window, window_attr.root, x, y,
+ &x, &y, &unused))
+ return QPixmap();
+
+ window = window_attr.root;
+ window_attr = root_attr;
+ }
+
+ QX11PlatformPixmap *data = new QX11PlatformPixmap(QPlatformPixmap::PixmapType);
+
+ void qt_x11_getX11InfoForWindow(QX11Info * xinfo, const XWindowAttributes &a);
+ qt_x11_getX11InfoForWindow(&data->xinfo,window_attr);
+
+ data->resize(w, h);
+
+ QPixmap pm(data);
+
+ data->flags &= ~QX11PlatformPixmap::Uninitialized;
+ pm.x11SetScreen(scr);
+
+ GC gc = XCreateGC(dpy, pm.handle(), 0, 0);
+ XSetSubwindowMode(dpy, gc, IncludeInferiors);
+ XCopyArea(dpy, window, pm.handle(), gc, x, y, w, h, 0, 0);
+ XFreeGC(dpy, gc);
+
+ return pm;
+}
+
+bool QX11PlatformPixmap::hasAlphaChannel() const
+{
+ return d == 32;
+}
+
+const QX11Info &QPixmap::x11Info() const
+{
+ if (data && data->classId() == QPlatformPixmap::X11Class)
+ return static_cast<QX11PlatformPixmap*>(data.data())->xinfo;
+ else {
+ static QX11Info nullX11Info;
+ return nullX11Info;
+ }
+}
+
+#if !defined(QT_NO_XRENDER)
+static XRenderPictFormat *qt_renderformat_for_depth(const QX11Info &xinfo, int depth)
+{
+ if (depth == 1)
+ return XRenderFindStandardFormat(X11->display, PictStandardA1);
+ else if (depth == 32)
+ return XRenderFindStandardFormat(X11->display, PictStandardARGB32);
+ else
+ return XRenderFindVisualFormat(X11->display, (Visual *)xinfo.visual());
+}
+#endif
+
+QPaintEngine* QX11PlatformPixmap::paintEngine() const
+{
+ QX11PlatformPixmap *that = const_cast<QX11PlatformPixmap*>(this);
+
+ if ((flags & Readonly) && share_mode == QPixmap::ImplicitlyShared) {
+ // if someone wants to draw onto us, copy the shared contents
+ // and turn it into a fully fledged QPixmap
+ ::Pixmap hd_copy = XCreatePixmap(X11->display, RootWindow(X11->display, xinfo.screen()),
+ w, h, d);
+#if !defined(QT_NO_XRENDER)
+ XRenderPictFormat *format = qt_renderformat_for_depth(xinfo, d);
+ ::Picture picture_copy = XRenderCreatePicture(X11->display, hd_copy, format, 0, 0);
+
+ if (picture && d == 32) {
+ XRenderComposite(X11->display, PictOpSrc, picture, 0, picture_copy,
+ 0, 0, 0, 0, 0, 0, w, h);
+ XRenderFreePicture(X11->display, picture);
+ that->picture = picture_copy;
+ } else
+#endif
+ {
+ GC gc = XCreateGC(X11->display, hd_copy, 0, 0);
+ XCopyArea(X11->display, hd, hd_copy, gc, 0, 0, w, h, 0, 0);
+ XFreeGC(X11->display, gc);
+ }
+ that->hd = hd_copy;
+ that->flags &= ~QX11PlatformPixmap::Readonly;
+ }
+
+ if (!that->pengine)
+ that->pengine = new QX11PaintEngine;
+ return that->pengine;
+}
+
+Qt::HANDLE QPixmap::x11PictureHandle() const
+{
+#ifndef QT_NO_XRENDER
+ if (data && data->classId() == QPlatformPixmap::X11Class)
+ return static_cast<const QX11PlatformPixmap*>(data.data())->picture;
+ else
+ return 0;
+#else
+ return 0;
+#endif // QT_NO_XRENDER
+}
+
+Qt::HANDLE QX11PlatformPixmap::x11ConvertToDefaultDepth()
+{
+#ifndef QT_NO_XRENDER
+ if (d == QX11Info::appDepth() || !X11->use_xrender)
+ return hd;
+ if (!hd2) {
+ hd2 = XCreatePixmap(xinfo.display(), hd, w, h, QX11Info::appDepth());
+ XRenderPictFormat *format = XRenderFindVisualFormat(xinfo.display(),
+ (Visual*) xinfo.visual());
+ Picture pic = XRenderCreatePicture(xinfo.display(), hd2, format, 0, 0);
+ XRenderComposite(xinfo.display(), PictOpSrc, picture,
+ XNone, pic, 0, 0, 0, 0, 0, 0, w, h);
+ XRenderFreePicture(xinfo.display(), pic);
+ }
+ return hd2;
+#else
+ return hd;
+#endif
+}
+
+void QX11PlatformPixmap::copy(const QPlatformPixmap *data, const QRect &rect)
+{
+ if (data->pixelType() == BitmapType) {
+ fromImage(data->toImage().copy(rect), Qt::AutoColor);
+ return;
+ }
+
+ const QX11PlatformPixmap *x11Data = static_cast<const QX11PlatformPixmap*>(data);
+
+ setSerialNumber(qt_pixmap_serial.fetchAndAddRelaxed(1));
+
+ flags &= ~Uninitialized;
+ xinfo = x11Data->xinfo;
+ d = x11Data->d;
+ w = rect.width();
+ h = rect.height();
+ is_null = (w <= 0 || h <= 0);
+ hd = (Qt::HANDLE)XCreatePixmap(X11->display,
+ RootWindow(X11->display, x11Data->xinfo.screen()),
+ w, h, d);
+#ifndef QT_NO_XRENDER
+ if (X11->use_xrender) {
+ XRenderPictFormat *format = d == 32
+ ? XRenderFindStandardFormat(X11->display, PictStandardARGB32)
+ : XRenderFindVisualFormat(X11->display, (Visual *)xinfo.visual());
+ picture = XRenderCreatePicture(X11->display, hd, format, 0, 0);
+ }
+#endif // QT_NO_XRENDER
+ if (x11Data->x11_mask) {
+ x11_mask = XCreatePixmap(X11->display, hd, w, h, 1);
+#ifndef QT_NO_XRENDER
+ if (X11->use_xrender) {
+ mask_picture = XRenderCreatePicture(X11->display, x11_mask,
+ XRenderFindStandardFormat(X11->display, PictStandardA1), 0, 0);
+ XRenderPictureAttributes attrs;
+ attrs.alpha_map = x11Data->mask_picture;
+ XRenderChangePicture(X11->display, x11Data->picture, CPAlphaMap, &attrs);
+ }
+#endif
+ }
+
+#if !defined(QT_NO_XRENDER)
+ if (x11Data->picture && x11Data->d == 32) {
+ XRenderComposite(X11->display, PictOpSrc,
+ x11Data->picture, 0, picture,
+ rect.x(), rect.y(), 0, 0, 0, 0, w, h);
+ } else
+#endif
+ {
+ GC gc = XCreateGC(X11->display, hd, 0, 0);
+ XCopyArea(X11->display, x11Data->hd, hd, gc,
+ rect.x(), rect.y(), w, h, 0, 0);
+ if (x11Data->x11_mask) {
+ GC monogc = XCreateGC(X11->display, x11_mask, 0, 0);
+ XCopyArea(X11->display, x11Data->x11_mask, x11_mask, monogc,
+ rect.x(), rect.y(), w, h, 0, 0);
+ XFreeGC(X11->display, monogc);
+ }
+ XFreeGC(X11->display, gc);
+ }
+}
+
+bool QX11PlatformPixmap::scroll(int dx, int dy, const QRect &rect)
+{
+ GC gc = XCreateGC(X11->display, hd, 0, 0);
+ XCopyArea(X11->display, hd, hd, gc,
+ rect.left(), rect.top(), rect.width(), rect.height(),
+ rect.left() + dx, rect.top() + dy);
+ XFreeGC(X11->display, gc);
+ return true;
+}
+
+#if !defined(QT_NO_XRENDER)
+void QX11PlatformPixmap::convertToARGB32(bool preserveContents)
+{
+ if (!X11->use_xrender)
+ return;
+
+ // Q_ASSERT(count == 1);
+ if ((flags & Readonly) && share_mode == QPixmap::ExplicitlyShared)
+ return;
+
+ Pixmap pm = XCreatePixmap(X11->display, RootWindow(X11->display, xinfo.screen()),
+ w, h, 32);
+ Picture p = XRenderCreatePicture(X11->display, pm,
+ XRenderFindStandardFormat(X11->display, PictStandardARGB32), 0, 0);
+ if (picture) {
+ if (preserveContents)
+ XRenderComposite(X11->display, PictOpSrc, picture, 0, p, 0, 0, 0, 0, 0, 0, w, h);
+ if (!(flags & Readonly))
+ XRenderFreePicture(X11->display, picture);
+ }
+ if (hd && !(flags & Readonly))
+ XFreePixmap(X11->display, hd);
+ if (x11_mask) {
+ XFreePixmap(X11->display, x11_mask);
+ if (mask_picture)
+ XRenderFreePicture(X11->display, mask_picture);
+ x11_mask = 0;
+ mask_picture = 0;
+ }
+ hd = pm;
+ picture = p;
+ d = 32;
+}
+#endif
+
+QPixmap QPixmap::fromX11Pixmap(Qt::HANDLE pixmap, QPixmap::ShareMode mode)
+{
+ Window root;
+ int x;
+ int y;
+ uint width;
+ uint height;
+ uint border_width;
+ uint depth;
+ XWindowAttributes win_attribs;
+ int num_screens = ScreenCount(X11->display);
+ int screen = 0;
+
+ XGetGeometry(X11->display, pixmap, &root, &x, &y, &width, &height, &border_width, &depth);
+ XGetWindowAttributes(X11->display, root, &win_attribs);
+
+ for (; screen < num_screens; ++screen) {
+ if (win_attribs.screen == ScreenOfDisplay(X11->display, screen))
+ break;
+ }
+
+ QX11PlatformPixmap *data = new QX11PlatformPixmap(depth == 1 ? QPlatformPixmap::BitmapType : QPlatformPixmap::PixmapType);
+ data->setSerialNumber(qt_pixmap_serial.fetchAndAddRelaxed(1));
+ data->flags = QX11PlatformPixmap::Readonly;
+ data->share_mode = mode;
+ data->w = width;
+ data->h = height;
+ data->is_null = (width <= 0 || height <= 0);
+ data->d = depth;
+ data->hd = pixmap;
+
+ if (defaultScreen >= 0 && defaultScreen != screen) {
+ QX11InfoData* xd = data->xinfo.getX11Data(true);
+ xd->screen = defaultScreen;
+ xd->depth = QX11Info::appDepth(xd->screen);
+ xd->cells = QX11Info::appCells(xd->screen);
+ xd->colormap = QX11Info::appColormap(xd->screen);
+ xd->defaultColormap = QX11Info::appDefaultColormap(xd->screen);
+ xd->visual = (Visual *)QX11Info::appVisual(xd->screen);
+ xd->defaultVisual = QX11Info::appDefaultVisual(xd->screen);
+ data->xinfo.setX11Data(xd);
+ }
+
+#ifndef QT_NO_XRENDER
+ if (X11->use_xrender) {
+ XRenderPictFormat *format = qt_renderformat_for_depth(data->xinfo, depth);
+ data->picture = XRenderCreatePicture(X11->display, data->hd, format, 0, 0);
+ }
+#endif // QT_NO_XRENDER
+
+ return QPixmap(data);
+}
+
+
+QT_END_NAMESPACE
diff --git a/src/widgets/platforms/x11/qpixmap_x11_p.h b/src/widgets/platforms/x11/qpixmap_x11_p.h
new file mode 100644
index 0000000000..fce32cbe3e
--- /dev/null
+++ b/src/widgets/platforms/x11/qpixmap_x11_p.h
@@ -0,0 +1,156 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPIXMAPDATA_X11_P_H
+#define QPIXMAPDATA_X11_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtGui/qplatformpixmap_qpa.h>
+#include <QtGui/qplatformpixmapfactory_p.h>
+
+#include "QtGui/qx11info_x11.h"
+
+QT_BEGIN_NAMESPACE
+
+class QX11PaintEngine;
+
+struct QXImageWrapper;
+
+class Q_WIDGETS_EXPORT QX11PlatformPixmap : public QPlatformPixmap
+{
+public:
+ QX11PlatformPixmap(PixelType type);
+// QX11PlatformPixmap(PixelType type, int width, int height);
+// QX11PlatformPixmap(PixelType type, const QImage &image,
+// Qt::ImageConversionFlags flags);
+ ~QX11PlatformPixmap();
+
+ QPlatformPixmap *createCompatiblePlatformPixmap() const;
+
+ void resize(int width, int height);
+ void fromImage(const QImage &image, Qt::ImageConversionFlags flags);
+ void copy(const QPlatformPixmap *data, const QRect &rect);
+ bool scroll(int dx, int dy, const QRect &rect);
+
+ void fill(const QColor &color);
+ QBitmap mask() const;
+ void setMask(const QBitmap &mask);
+ bool hasAlphaChannel() const;
+ void setAlphaChannel(const QPixmap &alphaChannel);
+ QPixmap alphaChannel() const;
+ QPixmap transformed(const QTransform &transform,
+ Qt::TransformationMode mode) const;
+ QImage toImage() const;
+ QImage toImage(const QRect &rect) const;
+ QPaintEngine* paintEngine() const;
+
+ Qt::HANDLE handle() const { return hd; }
+ Qt::HANDLE x11ConvertToDefaultDepth();
+
+ static Qt::HANDLE createBitmapFromImage(const QImage &image);
+
+ void* gl_surface;
+#ifndef QT_NO_XRENDER
+ void convertToARGB32(bool preserveContents = true);
+#endif
+
+protected:
+ int metric(QPaintDevice::PaintDeviceMetric metric) const;
+
+private:
+ friend class QPixmap;
+ friend class QBitmap;
+ friend class QX11PaintEngine;
+ friend class QX11WindowSurface;
+ friend class QRasterWindowSurface;
+ friend class QGLContextPrivate; // Needs to access xinfo, gl_surface & flags
+ friend class QEglContext; // Needs gl_surface
+ friend class QGLContext; // Needs gl_surface
+ friend class QX11GLPlatformPixmap; // Needs gl_surface
+ friend class QMeeGoLivePlatformPixmap; // Needs gl_surface and flags
+ friend bool qt_createEGLSurfaceForPixmap(QPlatformPixmap*, bool); // Needs gl_surface
+
+ void release();
+
+ QImage toImage(const QXImageWrapper &xi, const QRect &rect) const;
+
+ QBitmap mask_to_bitmap(int screen) const;
+ static Qt::HANDLE bitmap_to_mask(const QBitmap &, int screen);
+ void bitmapFromImage(const QImage &image);
+
+ bool canTakeQImageFromXImage(const QXImageWrapper &xi) const;
+ QImage takeQImageFromXImage(const QXImageWrapper &xi) const;
+
+ Qt::HANDLE hd;
+
+ enum Flag {
+ NoFlags = 0x0,
+ Uninitialized = 0x1,
+ Readonly = 0x2,
+ InvertedWhenBoundToTexture = 0x4,
+ GlSurfaceCreatedWithAlpha = 0x8
+ };
+ uint flags;
+
+ QX11Info xinfo;
+ Qt::HANDLE x11_mask;
+ Qt::HANDLE picture;
+ Qt::HANDLE mask_picture;
+ Qt::HANDLE hd2; // sorted in the default display depth
+ QPixmap::ShareMode share_mode;
+
+ QX11PaintEngine *pengine;
+};
+
+QT_END_NAMESPACE
+
+#endif // QPIXMAPDATA_X11_P_H
+
diff --git a/src/gui/painting/qregion_x11.cpp b/src/widgets/platforms/x11/qregion_x11.cpp
index a96ec6dc96..a96ec6dc96 100644
--- a/src/gui/painting/qregion_x11.cpp
+++ b/src/widgets/platforms/x11/qregion_x11.cpp
diff --git a/src/gui/kernel/qsound_x11.cpp b/src/widgets/platforms/x11/qsound_x11.cpp
index c83c26a027..c83c26a027 100644
--- a/src/gui/kernel/qsound_x11.cpp
+++ b/src/widgets/platforms/x11/qsound_x11.cpp
diff --git a/src/widgets/platforms/x11/qt_x11_p.h b/src/widgets/platforms/x11/qt_x11_p.h
new file mode 100644
index 0000000000..ea808fb8a2
--- /dev/null
+++ b/src/widgets/platforms/x11/qt_x11_p.h
@@ -0,0 +1,757 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT_X11_P_H
+#define QT_X11_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "QtGui/qwindowdefs.h"
+#include "QtCore/qlist.h"
+#include "QtCore/qvariant.h"
+
+// the following is necessary to work around breakage in many versions
+// of XFree86's Xlib.h still in use
+// ### which versions?
+#if defined(_XLIB_H_) // crude hack, but...
+#error "cannot include <X11/Xlib.h> before this file"
+#endif
+#define XRegisterIMInstantiateCallback qt_XRegisterIMInstantiateCallback
+#define XUnregisterIMInstantiateCallback qt_XUnregisterIMInstantiateCallback
+#define XSetIMValues qt_XSetIMValues
+#include <X11/Xlib.h>
+#undef XRegisterIMInstantiateCallback
+#undef XUnregisterIMInstantiateCallback
+#undef XSetIMValues
+
+#include <X11/Xutil.h>
+#include <X11/Xos.h>
+#ifdef index
+# undef index
+#endif
+#ifdef rindex
+# undef rindex
+#endif
+#ifdef Q_OS_VXWORS
+# ifdef open
+# undef open
+# endif
+# ifdef getpid
+# undef getpid
+# endif
+#endif // Q_OS_VXWORKS
+#include <X11/Xatom.h>
+
+//#define QT_NO_SHAPE
+#ifdef QT_NO_SHAPE
+# define XShapeCombineRegion(a,b,c,d,e,f,g)
+# define XShapeCombineMask(a,b,c,d,e,f,g)
+#else
+# include <X11/extensions/shape.h>
+#endif // QT_NO_SHAPE
+
+
+#if !defined (QT_NO_TABLET)
+# include <X11/extensions/XInput.h>
+#if defined (Q_OS_IRIX)
+# include <X11/extensions/SGIMisc.h>
+# include <wacom.h>
+#endif
+#endif // QT_NO_TABLET
+
+
+// #define QT_NO_XINERAMA
+#ifndef QT_NO_XINERAMA
+# if 0 // ### Xsun, but how to detect it?
+// Xinerama is only supported in Solaris 7 with patches 107648/108376 and
+// Solaris 8 or above which introduce the X11R6.4 Xserver.
+// To switch the Xinerama functionality on, you need to add the "+xinerama"
+// argument to the Xsun start line.
+// At least Solaris 7 and 8 are missing Xinerama system headers and function
+// declarations (bug 4284701).
+// The Xinerama API is not documented. In theory it could change but it
+// probably won't because Sun are using it in at least dtlogin (bug 4221829).
+extern "C" Bool XPanoramiXQueryExtension(
+ Display*,
+ int*,
+ int*
+);
+extern "C" Status XPanoramiXQueryVersion(
+ Display*,
+ int*,
+ int*
+);
+extern "C" Status XPanoramiXGetState(
+ Display*,
+ Drawable,
+ XPanoramiXInfo*
+);
+extern "C" Status XPanoramiXGetScreenCount(
+ Display *,
+ Drawable,
+ XPanoramiXInfo*
+);
+extern "C" Status XPanoramiXGetScreenSize(
+ Display*,
+ Drawable,
+ int,
+ XPanoramiXInfo*
+);
+# else // XFree86
+// XFree86 does not C++ify Xinerama (at least up to XFree86 4.0.3).
+extern "C" {
+# include <X11/extensions/Xinerama.h>
+}
+# endif
+#endif // QT_NO_XINERAMA
+
+// #define QT_NO_XRANDR
+#ifndef QT_NO_XRANDR
+# include <X11/extensions/Xrandr.h>
+#endif // QT_NO_XRANDR
+
+// #define QT_NO_XRENDER
+#ifndef QT_NO_XRENDER
+# include <X11/extensions/Xrender.h>
+#endif // QT_NO_XRENDER
+
+#ifndef QT_NO_XSYNC
+extern "C" {
+# include "X11/extensions/sync.h"
+}
+#endif
+
+// #define QT_NO_XKB
+#ifndef QT_NO_XKB
+# include <X11/XKBlib.h>
+#endif // QT_NO_XKB
+
+
+#if !defined(XlibSpecificationRelease)
+# define X11R4
+typedef char *XPointer;
+#else
+# undef X11R4
+#endif
+
+// #define QT_NO_XIM
+#if defined(X11R4)
+// X11R4 does not have XIM
+#define QT_NO_XIM
+#elif defined(Q_OS_OSF) && (XlibSpecificationRelease < 6)
+// broken in Xlib up to OSF/1 3.2
+#define QT_NO_XIM
+#elif defined(Q_OS_AIX)
+// broken in Xlib up to what version of AIX?
+#define QT_NO_XIM
+#elif defined(QT_NO_DEBUG) && defined(Q_OS_IRIX)
+// XmbLookupString broken on IRIX
+// XCreateIC broken when compiling -64 on IRIX 6.5.2
+#define QT_NO_XIM
+#elif defined(Q_OS_HPUX) && defined(__LP64__)
+// XCreateIC broken when compiling 64-bit ELF on HP-UX 11.0
+#define QT_NO_XIM
+#elif defined(Q_OS_SCO)
+// ### suggested by user...
+// ### #define QT_NO_XIM
+#endif // QT_NO_XIM
+
+#ifndef QT_NO_XFIXES
+typedef Bool (*PtrXFixesQueryExtension)(Display *, int *, int *);
+typedef Status (*PtrXFixesQueryVersion)(Display *, int *, int *);
+typedef void (*PtrXFixesSetCursorName)(Display *dpy, Cursor cursor, const char *name);
+typedef void (*PtrXFixesSelectSelectionInput)(Display *dpy, Window win, Atom selection, unsigned long eventMask);
+#endif // QT_NO_XFIXES
+
+#ifndef QT_NO_XCURSOR
+#include <X11/Xcursor/Xcursor.h>
+typedef Cursor (*PtrXcursorLibraryLoadCursor)(Display *, const char *);
+#endif // QT_NO_XCURSOR
+
+#ifndef QT_NO_XINERAMA
+typedef Bool (*PtrXineramaQueryExtension)(Display *dpy, int *event_base, int *error_base);
+typedef Bool (*PtrXineramaIsActive)(Display *dpy);
+typedef XineramaScreenInfo *(*PtrXineramaQueryScreens)(Display *dpy, int *number);
+#endif // QT_NO_XINERAMA
+
+#ifndef QT_NO_XRANDR
+typedef void (*PtrXRRSelectInput)(Display *, Window, int);
+typedef int (*PtrXRRUpdateConfiguration)(XEvent *);
+typedef int (*PtrXRRRootToScreen)(Display *, Window);
+typedef Bool (*PtrXRRQueryExtension)(Display *, int *, int *);
+typedef XRRScreenSize *(*PtrXRRSizes)(Display *, int, int *);
+#endif // QT_NO_XRANDR
+
+#ifndef QT_NO_XINPUT
+typedef int (*PtrXCloseDevice)(Display *, XDevice *);
+typedef XDeviceInfo* (*PtrXListInputDevices)(Display *, int *);
+typedef XDevice* (*PtrXOpenDevice)(Display *, XID);
+typedef void (*PtrXFreeDeviceList)(XDeviceInfo *);
+typedef int (*PtrXSelectExtensionEvent)(Display *, Window, XEventClass *, int);
+#endif // QT_NO_XINPUT
+
+/*
+ * Solaris patch 108652-47 and higher fixes crases in
+ * XRegisterIMInstantiateCallback, but the function doesn't seem to
+ * work.
+ *
+ * Instead, we disabled R6 input, and open the input method
+ * immediately at application start.
+ */
+#if !defined(QT_NO_XIM) && (XlibSpecificationRelease >= 6) && \
+ !defined(Q_OS_SOLARIS)
+#define USE_X11R6_XIM
+
+//######### XFree86 has wrong declarations for XRegisterIMInstantiateCallback
+//######### and XUnregisterIMInstantiateCallback in at least version 3.3.2.
+//######### Many old X11R6 header files lack XSetIMValues.
+//######### Therefore, we have to declare these functions ourselves.
+
+extern "C" Bool XRegisterIMInstantiateCallback(
+ Display*,
+ struct _XrmHashBucketRec*,
+ char*,
+ char*,
+ XIMProc, //XFree86 has XIDProc, which has to be wrong
+ XPointer
+);
+
+extern "C" Bool XUnregisterIMInstantiateCallback(
+ Display*,
+ struct _XrmHashBucketRec*,
+ char*,
+ char*,
+ XIMProc, //XFree86 has XIDProc, which has to be wrong
+ XPointer
+);
+
+extern "C" char *XSetIMValues(XIM /* im */, ...);
+
+#endif
+
+#ifndef QT_NO_FONTCONFIG
+#include <fontconfig/fontconfig.h>
+#endif
+
+#ifndef QT_NO_XIM
+// some platforms (eg. Solaris 2.51) don't have these defines in Xlib.h
+#ifndef XNResetState
+#define XNResetState "resetState"
+#endif
+#ifndef XIMPreserveState
+#define XIMPreserveState (1L<<1)
+#endif
+#endif
+
+
+#ifndef X11R4
+# include <X11/Xlocale.h>
+#endif // X11R4
+
+
+#ifndef QT_NO_MITSHM
+# include <X11/extensions/XShm.h>
+#endif // QT_NO_MITSHM
+
+QT_BEGIN_NAMESPACE
+
+class QWidget;
+
+struct QX11InfoData {
+ uint ref;
+ int screen;
+ int dpiX;
+ int dpiY;
+ int depth;
+ int cells;
+ Colormap colormap;
+ Visual *visual;
+ bool defaultColormap;
+ bool defaultVisual;
+ int subpixel;
+};
+
+class QDrag;
+struct QXdndDropTransaction
+{
+ Time timestamp;
+ Window target;
+ Window proxy_target;
+ QWidget *targetWidget;
+ QWidget *embedding_widget;
+ QDrag *object;
+};
+
+class QMimeData;
+
+struct QX11Data;
+extern Q_WIDGETS_EXPORT QX11Data *qt_x11Data;
+
+enum DesktopEnvironment {
+ DE_UNKNOWN,
+ DE_KDE,
+ DE_GNOME,
+ DE_CDE,
+ DE_MEEGO_COMPOSITOR,
+ DE_4DWM
+};
+
+struct QX11Data
+{
+ static Qt::KeyboardModifiers translateModifiers(int s);
+
+ Window findClientWindow(Window, Atom, bool);
+
+ // from qclipboard_x11.cpp
+ bool clipboardWaitForEvent(Window win, int type, XEvent *event, int timeout);
+ bool clipboardReadProperty(Window win, Atom property, bool deleteProperty,
+ QByteArray *buffer, int *size, Atom *type, int *format);
+ QByteArray clipboardReadIncrementalProperty(Window win, Atom property, int nbytes, bool nullterm);
+
+ // from qdnd_x11.cpp
+ bool dndEnable(QWidget* w, bool on);
+ static void xdndSetup();
+ void xdndHandleEnter(QWidget *, const XEvent *, bool);
+ void xdndHandlePosition(QWidget *, const XEvent *, bool);
+ void xdndHandleStatus(QWidget *, const XEvent *, bool);
+ void xdndHandleLeave(QWidget *, const XEvent *, bool);
+ void xdndHandleDrop(QWidget *, const XEvent *, bool);
+ void xdndHandleFinished(QWidget *, const XEvent *, bool);
+ void xdndHandleSelectionRequest(const XSelectionRequestEvent *);
+ static bool xdndHandleBadwindow();
+ QByteArray xdndAtomToString(Atom a);
+ Atom xdndStringToAtom(const char *);
+
+ QString xdndMimeAtomToString(Atom a);
+ Atom xdndMimeStringToAtom(const QString &mimeType);
+ QStringList xdndMimeFormatsForAtom(Atom a);
+ bool xdndMimeDataForAtom(Atom a, QMimeData *mimeData, QByteArray *data, Atom *atomFormat, int *dataFormat);
+ QList<Atom> xdndMimeAtomsForFormat(const QString &format);
+ QVariant xdndMimeConvertToFormat(Atom a, const QByteArray &data, const QString &format, QVariant::Type requestedType, const QByteArray &encoding);
+ Atom xdndMimeAtomForFormat(const QString &format, QVariant::Type requestedType, const QList<Atom> &atoms, QByteArray *requestedEncoding);
+
+ QList<QXdndDropTransaction> dndDropTransactions;
+
+ // from qmotifdnd_x11.cpp
+ void motifdndHandle(QWidget *, const XEvent *, bool);
+ void motifdndEnable(QWidget *, bool);
+ QVariant motifdndObtainData(const char *format);
+ QByteArray motifdndFormat(int n);
+ bool motifdnd_active;
+
+ Display *display;
+ char *displayName;
+ bool foreignDisplay;
+ // current focus model
+ enum {
+ FM_Unknown = -1,
+ FM_Other = 0,
+ FM_PointerRoot = 1
+ };
+ int focus_model;
+
+ // true if Qt is compiled w/ RANDR support and RANDR is supported on the connected Display
+ bool use_xrandr;
+ int xrandr_major;
+ int xrandr_eventbase;
+ int xrandr_errorbase;
+
+ // true if Qt is compiled w/ RENDER support and RENDER is supported on the connected Display
+ bool use_xrender;
+ int xrender_major;
+ int xrender_version;
+
+ // true if Qt is compiled w/ XFIXES support and XFIXES is supported on the connected Display
+ bool use_xfixes;
+ int xfixes_major;
+ int xfixes_eventbase;
+ int xfixes_errorbase;
+
+#ifndef QT_NO_XFIXES
+ PtrXFixesQueryExtension ptrXFixesQueryExtension;
+ PtrXFixesQueryVersion ptrXFixesQueryVersion;
+ PtrXFixesSetCursorName ptrXFixesSetCursorName;
+ PtrXFixesSelectSelectionInput ptrXFixesSelectSelectionInput;
+#endif
+
+#ifndef QT_NO_XINPUT
+ PtrXCloseDevice ptrXCloseDevice;
+ PtrXListInputDevices ptrXListInputDevices;
+ PtrXOpenDevice ptrXOpenDevice;
+ PtrXFreeDeviceList ptrXFreeDeviceList;
+ PtrXSelectExtensionEvent ptrXSelectExtensionEvent;
+#endif // QT_NO_XINPUT
+
+
+ // true if Qt is compiled w/ MIT-SHM support and MIT-SHM is supported on the connected Display
+ bool use_mitshm;
+ bool use_mitshm_pixmaps;
+ int mitshm_major;
+
+ // true if Qt is compiled w/ Tablet support and we have a tablet.
+ bool use_xinput;
+ int xinput_major;
+ int xinput_eventbase;
+ int xinput_errorbase;
+
+ // for XKEYBOARD support
+ bool use_xkb;
+ int xkb_major;
+ int xkb_eventbase;
+ int xkb_errorbase;
+
+ QList<QWidget *> deferred_map;
+ struct ScrollInProgress {
+ long id;
+ QWidget* scrolled_widget;
+ int dx, dy;
+ };
+ long sip_serial;
+ QList<ScrollInProgress> sip_list;
+
+ // window managers list of supported "stuff"
+ Atom *net_supported_list;
+ // list of virtual root windows
+ Window *net_virtual_root_list;
+ // client leader window
+ Window wm_client_leader;
+
+ QX11InfoData *screens;
+ Visual **argbVisuals;
+ Colormap *argbColormaps;
+ int screenCount;
+ int defaultScreen;
+
+ Time time;
+ Time userTime;
+
+ QString default_im;
+
+ // starts to ignore bad window errors from X
+ static inline void ignoreBadwindow() {
+ qt_x11Data->ignore_badwindow = true;
+ qt_x11Data->seen_badwindow = false;
+ }
+
+ // ends ignoring bad window errors and returns whether an error had happened.
+ static inline bool badwindow() {
+ qt_x11Data->ignore_badwindow = false;
+ return qt_x11Data->seen_badwindow;
+ }
+
+ bool ignore_badwindow;
+ bool seen_badwindow;
+
+ // options
+ int visual_class;
+ int visual_id;
+ int color_count;
+ bool custom_cmap;
+
+ // outside visual/colormap
+ Visual *visual;
+ Colormap colormap;
+
+#ifndef QT_NO_XRENDER
+ enum { solid_fill_count = 16 };
+ struct SolidFills {
+ XRenderColor color;
+ int screen;
+ Picture picture;
+ } solid_fills[solid_fill_count];
+ enum { pattern_fill_count = 16 };
+ struct PatternFills {
+ XRenderColor color;
+ XRenderColor bg_color;
+ int screen;
+ int style;
+ bool opaque;
+ Picture picture;
+ } pattern_fills[pattern_fill_count];
+ Picture getSolidFill(int screen, const QColor &c);
+ XRenderColor preMultiply(const QColor &c);
+#endif
+
+ bool has_fontconfig;
+ qreal fc_scale;
+ bool fc_antialias;
+ int fc_hint_style;
+
+ char *startupId;
+
+ DesktopEnvironment desktopEnvironment : 8;
+ uint desktopVersion : 8; /* Used only for KDE */
+
+ /* Warning: if you modify this list, modify the names of atoms in qapplication_x11.cpp as well! */
+ enum X11Atom {
+ // window-manager <-> client protocols
+ WM_PROTOCOLS,
+ WM_DELETE_WINDOW,
+ WM_TAKE_FOCUS,
+ _NET_WM_PING,
+ _NET_WM_CONTEXT_HELP,
+ _NET_WM_SYNC_REQUEST,
+ _NET_WM_SYNC_REQUEST_COUNTER,
+
+ // ICCCM window state
+ WM_STATE,
+ WM_CHANGE_STATE,
+
+ // Session management
+ WM_CLIENT_LEADER,
+ WM_WINDOW_ROLE,
+ SM_CLIENT_ID,
+
+ // Clipboard
+ CLIPBOARD,
+ INCR,
+ TARGETS,
+ MULTIPLE,
+ TIMESTAMP,
+ SAVE_TARGETS,
+ CLIP_TEMPORARY,
+ _QT_SELECTION,
+ _QT_CLIPBOARD_SENTINEL,
+ _QT_SELECTION_SENTINEL,
+ CLIPBOARD_MANAGER,
+
+ RESOURCE_MANAGER,
+
+ _XSETROOT_ID,
+
+ _QT_SCROLL_DONE,
+ _QT_INPUT_ENCODING,
+
+ _MOTIF_WM_HINTS,
+
+ DTWM_IS_RUNNING,
+ ENLIGHTENMENT_DESKTOP,
+ _DT_SAVE_MODE,
+ _SGI_DESKS_MANAGER,
+
+ // EWMH (aka NETWM)
+ _NET_SUPPORTED,
+ _NET_VIRTUAL_ROOTS,
+ _NET_WORKAREA,
+
+ _NET_MOVERESIZE_WINDOW,
+ _NET_WM_MOVERESIZE,
+
+ _NET_WM_NAME,
+ _NET_WM_ICON_NAME,
+ _NET_WM_ICON,
+
+ _NET_WM_PID,
+
+ _NET_WM_WINDOW_OPACITY,
+
+ _NET_WM_STATE,
+ _NET_WM_STATE_ABOVE,
+ _NET_WM_STATE_BELOW,
+ _NET_WM_STATE_FULLSCREEN,
+ _NET_WM_STATE_MAXIMIZED_HORZ,
+ _NET_WM_STATE_MAXIMIZED_VERT,
+ _NET_WM_STATE_MODAL,
+ _NET_WM_STATE_STAYS_ON_TOP,
+ _NET_WM_STATE_DEMANDS_ATTENTION,
+
+ _NET_WM_USER_TIME,
+ _NET_WM_USER_TIME_WINDOW,
+ _NET_WM_FULL_PLACEMENT,
+
+ _NET_WM_WINDOW_TYPE,
+ _NET_WM_WINDOW_TYPE_DESKTOP,
+ _NET_WM_WINDOW_TYPE_DOCK,
+ _NET_WM_WINDOW_TYPE_TOOLBAR,
+ _NET_WM_WINDOW_TYPE_MENU,
+ _NET_WM_WINDOW_TYPE_UTILITY,
+ _NET_WM_WINDOW_TYPE_SPLASH,
+ _NET_WM_WINDOW_TYPE_DIALOG,
+ _NET_WM_WINDOW_TYPE_DROPDOWN_MENU,
+ _NET_WM_WINDOW_TYPE_POPUP_MENU,
+ _NET_WM_WINDOW_TYPE_TOOLTIP,
+ _NET_WM_WINDOW_TYPE_NOTIFICATION,
+ _NET_WM_WINDOW_TYPE_COMBO,
+ _NET_WM_WINDOW_TYPE_DND,
+ _NET_WM_WINDOW_TYPE_NORMAL,
+ _KDE_NET_WM_WINDOW_TYPE_OVERRIDE,
+
+ _KDE_NET_WM_FRAME_STRUT,
+
+ _NET_STARTUP_INFO,
+ _NET_STARTUP_INFO_BEGIN,
+
+ _NET_SUPPORTING_WM_CHECK,
+
+ _NET_WM_CM_S0,
+
+ _NET_SYSTEM_TRAY_VISUAL,
+
+ _NET_ACTIVE_WINDOW,
+
+ // Property formats
+ COMPOUND_TEXT,
+ TEXT,
+ UTF8_STRING,
+
+ // Xdnd
+ XdndEnter,
+ XdndPosition,
+ XdndStatus,
+ XdndLeave,
+ XdndDrop,
+ XdndFinished,
+ XdndTypelist,
+ XdndActionList,
+
+ XdndSelection,
+
+ XdndAware,
+ XdndProxy,
+
+ XdndActionCopy,
+ XdndActionLink,
+ XdndActionMove,
+ XdndActionPrivate,
+
+ // Motif DND
+ _MOTIF_DRAG_AND_DROP_MESSAGE,
+ _MOTIF_DRAG_INITIATOR_INFO,
+ _MOTIF_DRAG_RECEIVER_INFO,
+ _MOTIF_DRAG_WINDOW,
+ _MOTIF_DRAG_TARGETS,
+
+ XmTRANSFER_SUCCESS,
+ XmTRANSFER_FAILURE,
+
+ // Xkb
+ _XKB_RULES_NAMES,
+
+ // XEMBED
+ _XEMBED,
+ _XEMBED_INFO,
+
+ XWacomStylus,
+ XWacomCursor,
+ XWacomEraser,
+
+ XTabletStylus,
+ XTabletEraser,
+
+ NPredefinedAtoms,
+
+ _QT_SETTINGS_TIMESTAMP = NPredefinedAtoms,
+ NAtoms
+ };
+ Atom atoms[NAtoms];
+
+ bool isSupportedByWM(Atom atom);
+
+ bool compositingManagerRunning;
+
+#ifndef QT_NO_XCURSOR
+ PtrXcursorLibraryLoadCursor ptrXcursorLibraryLoadCursor;
+#endif // QT_NO_XCURSOR
+
+#ifndef QT_NO_XINERAMA
+ PtrXineramaQueryExtension ptrXineramaQueryExtension;
+ PtrXineramaIsActive ptrXineramaIsActive;
+ PtrXineramaQueryScreens ptrXineramaQueryScreens;
+#endif // QT_NO_XINERAMA
+
+#ifndef QT_NO_XRANDR
+ PtrXRRSelectInput ptrXRRSelectInput;
+ PtrXRRUpdateConfiguration ptrXRRUpdateConfiguration;
+ PtrXRRRootToScreen ptrXRRRootToScreen;
+ PtrXRRQueryExtension ptrXRRQueryExtension;
+ PtrXRRSizes ptrXRRSizes;
+#endif // QT_NO_XRANDR
+};
+
+extern QX11Data *qt_x11Data;
+#define ATOM(x) qt_x11Data->atoms[QX11Data::x]
+#define X11 qt_x11Data
+
+// rename a couple of X defines to get rid of name clashes
+// resolve the conflict between X11's FocusIn and QEvent::FocusIn
+enum {
+ XFocusOut = FocusOut,
+ XFocusIn = FocusIn,
+ XKeyPress = KeyPress,
+ XKeyRelease = KeyRelease,
+ XNone = None,
+ XRevertToParent = RevertToParent,
+ XGrayScale = GrayScale,
+ XCursorShape = CursorShape
+};
+#undef FocusOut
+#undef FocusIn
+#undef KeyPress
+#undef KeyRelease
+#undef None
+#undef RevertToParent
+#undef GrayScale
+#undef CursorShape
+
+#ifdef FontChange
+#undef FontChange
+#endif
+
+Q_DECLARE_TYPEINFO(XPoint, Q_PRIMITIVE_TYPE);
+Q_DECLARE_TYPEINFO(XRectangle, Q_PRIMITIVE_TYPE);
+Q_DECLARE_TYPEINFO(XChar2b, Q_PRIMITIVE_TYPE);
+#ifndef QT_NO_XRENDER
+Q_DECLARE_TYPEINFO(XGlyphElt32, Q_PRIMITIVE_TYPE);
+#endif
+
+
+QT_END_NAMESPACE
+
+#endif // QT_X11_P_H
diff --git a/src/widgets/platforms/x11/qwidget_x11.cpp b/src/widgets/platforms/x11/qwidget_x11.cpp
new file mode 100644
index 0000000000..5bb59b26c9
--- /dev/null
+++ b/src/widgets/platforms/x11/qwidget_x11.cpp
@@ -0,0 +1,3149 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qevent.h"
+#include "qwidget.h"
+#include "qdesktopwidget.h"
+#include "qapplication.h"
+#include "qapplication_p.h"
+#include "qnamespace.h"
+#include "qpainter.h"
+#include "qbitmap.h"
+#include "qlayout.h"
+#include "qtextcodec.h"
+#include "qelapsedtimer.h"
+#include "qcursor.h"
+#include "qstack.h"
+#include "qcolormap.h"
+#include "qdebug.h"
+#include "qmenu.h"
+#include "private/qmenu_p.h"
+#include "private/qbackingstore_p.h"
+#include "private/qwindowsurface_x11_p.h"
+
+//extern bool qt_sendSpontaneousEvent(QObject *, QEvent *); //qapplication_x11.cpp
+
+#include <private/qpixmap_x11_p.h>
+#include <private/qpaintengine_x11_p.h>
+#include "qt_x11_p.h"
+#include "qx11info_x11.h"
+
+#include <stdlib.h>
+
+//#define ALIEN_DEBUG
+
+// defined in qapplication_x11.cpp
+//bool qt_wstate_iconified(WId);
+//void qt_updated_rootinfo();
+
+
+#if !defined(QT_NO_IM)
+#include "qinputcontext.h"
+#include "qinputcontextfactory.h"
+#endif
+
+#include "qwidget_p.h"
+
+#define XCOORD_MAX 16383
+#define WRECT_MAX 8191
+
+QT_BEGIN_NAMESPACE
+
+extern bool qt_nograb();
+
+QWidget *QWidgetPrivate::mouseGrabber = 0;
+QWidget *QWidgetPrivate::keyboardGrabber = 0;
+
+void qt_net_remove_user_time(QWidget *tlw);
+void qt_net_update_user_time(QWidget *tlw, unsigned long timestamp);
+
+int qt_x11_create_desktop_on_screen = -1;
+
+extern void qt_net_update_user_time(QWidget *tlw, unsigned long timestamp);
+
+// MWM support
+struct QtMWMHints {
+ ulong flags, functions, decorations;
+ long input_mode;
+ ulong status;
+};
+
+enum {
+ MWM_HINTS_FUNCTIONS = (1L << 0),
+
+ MWM_FUNC_ALL = (1L << 0),
+ MWM_FUNC_RESIZE = (1L << 1),
+ MWM_FUNC_MOVE = (1L << 2),
+ MWM_FUNC_MINIMIZE = (1L << 3),
+ MWM_FUNC_MAXIMIZE = (1L << 4),
+ MWM_FUNC_CLOSE = (1L << 5),
+
+ MWM_HINTS_DECORATIONS = (1L << 1),
+
+ MWM_DECOR_ALL = (1L << 0),
+ MWM_DECOR_BORDER = (1L << 1),
+ MWM_DECOR_RESIZEH = (1L << 2),
+ MWM_DECOR_TITLE = (1L << 3),
+ MWM_DECOR_MENU = (1L << 4),
+ MWM_DECOR_MINIMIZE = (1L << 5),
+ MWM_DECOR_MAXIMIZE = (1L << 6),
+
+ MWM_HINTS_INPUT_MODE = (1L << 2),
+
+ MWM_INPUT_MODELESS = 0L,
+ MWM_INPUT_PRIMARY_APPLICATION_MODAL = 1L,
+ MWM_INPUT_FULL_APPLICATION_MODAL = 3L
+};
+
+
+static QtMWMHints getMWMHints(Display *display, Window window)
+{
+ QtMWMHints mwmhints;
+
+ Atom type;
+ int format;
+ ulong nitems, bytesLeft;
+ uchar *data = 0;
+ if ((XGetWindowProperty(display, window, ATOM(_MOTIF_WM_HINTS), 0, 5, false,
+ ATOM(_MOTIF_WM_HINTS), &type, &format, &nitems, &bytesLeft,
+ &data) == Success)
+ && (type == ATOM(_MOTIF_WM_HINTS)
+ && format == 32
+ && nitems >= 5)) {
+ mwmhints = *(reinterpret_cast<QtMWMHints *>(data));
+ } else {
+ mwmhints.flags = 0L;
+ mwmhints.functions = MWM_FUNC_ALL;
+ mwmhints.decorations = MWM_DECOR_ALL;
+ mwmhints.input_mode = 0L;
+ mwmhints.status = 0L;
+ }
+
+ if (data)
+ XFree(data);
+
+ return mwmhints;
+}
+
+static void SetMWMHints(Display *display, Window window, const QtMWMHints &mwmhints)
+{
+ if (mwmhints.flags != 0l) {
+ XChangeProperty(display, window, ATOM(_MOTIF_WM_HINTS), ATOM(_MOTIF_WM_HINTS), 32,
+ PropModeReplace, (unsigned char *) &mwmhints, 5);
+ } else {
+ XDeleteProperty(display, window, ATOM(_MOTIF_WM_HINTS));
+ }
+}
+
+// Returns true if we should set WM_TRANSIENT_FOR on \a w
+static inline bool isTransient(const QWidget *w)
+{
+ return ((w->windowType() == Qt::Dialog
+ || w->windowType() == Qt::Sheet
+ || w->windowType() == Qt::Tool
+ || w->windowType() == Qt::SplashScreen
+ || w->windowType() == Qt::ToolTip
+ || w->windowType() == Qt::Drawer
+ || w->windowType() == Qt::Popup)
+ && !w->testAttribute(Qt::WA_X11BypassTransientForHint));
+}
+
+static void do_size_hints(QWidget* widget, QWExtra *x);
+
+/*****************************************************************************
+ QWidget member functions
+ *****************************************************************************/
+
+const uint stdWidgetEventMask = // X event mask
+ (uint)(
+ KeyPressMask | KeyReleaseMask |
+ ButtonPressMask | ButtonReleaseMask |
+ KeymapStateMask |
+ ButtonMotionMask | PointerMotionMask |
+ EnterWindowMask | LeaveWindowMask |
+ FocusChangeMask |
+ ExposureMask |
+ PropertyChangeMask |
+ StructureNotifyMask
+ );
+
+const uint stdDesktopEventMask = // X event mask
+ (uint)(
+ KeymapStateMask |
+ EnterWindowMask | LeaveWindowMask |
+ PropertyChangeMask
+ );
+
+
+/*
+ The qt_ functions below are implemented in qwidgetcreate_x11.cpp.
+*/
+
+Window qt_XCreateWindow(const QWidget *creator,
+ Display *display, Window parent,
+ int x, int y, uint w, uint h,
+ int borderwidth, int depth,
+ uint windowclass, Visual *visual,
+ ulong valuemask, XSetWindowAttributes *attributes);
+Window qt_XCreateSimpleWindow(const QWidget *creator,
+ Display *display, Window parent,
+ int x, int y, uint w, uint h, int borderwidth,
+ ulong border, ulong background);
+void qt_XDestroyWindow(const QWidget *destroyer,
+ Display *display, Window window);
+
+
+static void qt_insert_sip(QWidget* scrolled_widget, int dx, int dy)
+{
+ if (!scrolled_widget->isWindow() && !scrolled_widget->internalWinId())
+ return;
+ QX11Data::ScrollInProgress sip = { X11->sip_serial++, scrolled_widget, dx, dy };
+ X11->sip_list.append(sip);
+
+ XClientMessageEvent client_message;
+ client_message.type = ClientMessage;
+ client_message.window = scrolled_widget->internalWinId();
+ client_message.format = 32;
+ client_message.message_type = ATOM(_QT_SCROLL_DONE);
+ client_message.data.l[0] = sip.id;
+
+ XSendEvent(X11->display, scrolled_widget->internalWinId(), False, NoEventMask,
+ (XEvent*)&client_message);
+}
+
+static int qt_sip_count(QWidget* scrolled_widget)
+{
+ int sips=0;
+
+ for (int i = 0; i < X11->sip_list.size(); ++i) {
+ const QX11Data::ScrollInProgress &sip = X11->sip_list.at(i);
+ if (sip.scrolled_widget == scrolled_widget)
+ sips++;
+ }
+
+ return sips;
+}
+
+static void create_wm_client_leader()
+{
+ if (X11->wm_client_leader) return;
+
+ X11->wm_client_leader =
+ XCreateSimpleWindow(X11->display,
+ QX11Info::appRootWindow(),
+ 0, 0, 1, 1, 0, 0, 0);
+
+ // set client leader property to itself
+ XChangeProperty(X11->display,
+ X11->wm_client_leader, ATOM(WM_CLIENT_LEADER),
+ XA_WINDOW, 32, PropModeReplace,
+ (unsigned char *)&X11->wm_client_leader, 1);
+
+#ifndef QT_NO_SESSIONMANAGER
+ // If we are session managed, inform the window manager about it
+ QByteArray session = qApp->sessionId().toLatin1();
+ if (!session.isEmpty()) {
+ XChangeProperty(X11->display,
+ X11->wm_client_leader, ATOM(SM_CLIENT_ID),
+ XA_STRING, 8, PropModeReplace,
+ (unsigned char *)session.data(), session.size());
+ }
+#endif
+}
+
+/*!
+ \internal
+ Update the X11 cursor of the widget w.
+ \a force is true if this function is called from dispatchEnterLeave, it means that the
+ mouse is actually directly under this widget.
+ */
+void qt_x11_enforce_cursor(QWidget * w, bool force)
+{
+ if (!w->testAttribute(Qt::WA_WState_Created))
+ return;
+
+ static QPointer<QWidget> lastUnderMouse = 0;
+ if (force) {
+ lastUnderMouse = w;
+ } else if (lastUnderMouse && lastUnderMouse->effectiveWinId() == w->effectiveWinId()) {
+ w = lastUnderMouse;
+ } else if (!w->internalWinId()) {
+ return; //the mouse is not under this widget, and it's not native, so don't change it
+ }
+
+ while (!w->internalWinId() && w->parentWidget() && !w->isWindow() && !w->testAttribute(Qt::WA_SetCursor))
+ w = w->parentWidget();
+
+ QWidget *nativeParent = w;
+ if (!w->internalWinId())
+ nativeParent = w->nativeParentWidget();
+ // This does the same as effectiveWinId(), but since it is possible
+ // to not have a native parent widget due to a special hack in
+ // qwidget for reparenting widgets to a different X11 screen,
+ // added additional check to make sure native parent widget exists.
+ if (!nativeParent || !nativeParent->internalWinId())
+ return;
+ WId winid = nativeParent->internalWinId();
+
+ if (w->isWindow() || w->testAttribute(Qt::WA_SetCursor)) {
+#ifndef QT_NO_CURSOR
+ QCursor *oc = QApplication::overrideCursor();
+ if (oc) {
+ XDefineCursor(X11->display, winid, oc->handle());
+ } else if (w->isEnabled()) {
+ XDefineCursor(X11->display, winid, w->cursor().handle());
+ } else {
+ // enforce the windows behavior of clearing the cursor on
+ // disabled widgets
+ XDefineCursor(X11->display, winid, XNone);
+ }
+#endif
+ } else {
+ XDefineCursor(X11->display, winid, XNone);
+ }
+}
+
+Q_WIDGETS_EXPORT void qt_x11_enforce_cursor(QWidget * w)
+{
+ qt_x11_enforce_cursor(w, false);
+}
+
+void qt_x11_wait_for_window_manager(QWidget *w, bool sendPostedEvents)
+{
+ if (!w || (!w->isWindow() && !w->internalWinId()))
+ return;
+ QApplication::flush();
+ XEvent ev;
+ QElapsedTimer t;
+ t.start();
+ static const int maximumWaitTime = 2000;
+ if (!w->testAttribute(Qt::WA_WState_Created))
+ return;
+
+ WId winid = w->internalWinId();
+
+ // first deliver events that are already in the local queue
+ if (sendPostedEvents)
+ QApplication::sendPostedEvents();
+
+ // the normal sequence is:
+ // ... ConfigureNotify ... ReparentNotify ... MapNotify ... Expose
+ // with X11BypassWindowManagerHint:
+ // ConfigureNotify ... MapNotify ... Expose
+
+ enum State {
+ Initial, Mapped
+ } state = Initial;
+
+ do {
+ if (XEventsQueued(X11->display, QueuedAlready)) {
+ XNextEvent(X11->display, &ev);
+ qApp->x11ProcessEvent(&ev);
+
+ switch (state) {
+ case Initial:
+ if (ev.type == MapNotify && ev.xany.window == winid)
+ state = Mapped;
+ break;
+ case Mapped:
+ if (ev.type == Expose && ev.xany.window == winid)
+ return;
+ break;
+ }
+ } else {
+ if (!XEventsQueued(X11->display, QueuedAfterFlush))
+ qApp->syncX(); // non-busy wait
+ }
+ if (t.elapsed() > maximumWaitTime)
+ return;
+ } while(1);
+}
+
+Q_WIDGETS_EXPORT void qt_x11_wait_for_window_manager(QWidget *w)
+{
+ qt_x11_wait_for_window_manager(w, true);
+}
+
+void qt_change_net_wm_state(const QWidget* w, bool set, Atom one, Atom two = 0)
+{
+ if (!w->isVisible()) // not managed by the window manager
+ return;
+
+ XEvent e;
+ e.xclient.type = ClientMessage;
+ e.xclient.message_type = ATOM(_NET_WM_STATE);
+ e.xclient.display = X11->display;
+ e.xclient.window = w->internalWinId();
+ e.xclient.format = 32;
+ e.xclient.data.l[0] = set ? 1 : 0;
+ e.xclient.data.l[1] = one;
+ e.xclient.data.l[2] = two;
+ e.xclient.data.l[3] = 0;
+ e.xclient.data.l[4] = 0;
+ XSendEvent(X11->display, RootWindow(X11->display, w->x11Info().screen()),
+ false, (SubstructureNotifyMask | SubstructureRedirectMask), &e);
+}
+
+struct QX11WindowAttributes {
+ const XWindowAttributes *att;
+};
+
+void qt_x11_getX11InfoForWindow(QX11Info * xinfo, const XWindowAttributes &a)
+{
+ QX11WindowAttributes att;
+ att.att = &a;
+ qt_x11_getX11InfoForWindow(xinfo,att);
+}
+
+
+static QVector<Atom> getNetWmState(QWidget *w)
+{
+ QVector<Atom> returnValue;
+
+ // Don't read anything, just get the size of the property data
+ Atom actualType;
+ int actualFormat;
+ ulong propertyLength;
+ ulong bytesLeft;
+ uchar *propertyData = 0;
+ if (XGetWindowProperty(X11->display, w->internalWinId(), ATOM(_NET_WM_STATE), 0, 0,
+ False, XA_ATOM, &actualType, &actualFormat,
+ &propertyLength, &bytesLeft, &propertyData) == Success
+ && actualType == XA_ATOM && actualFormat == 32) {
+ returnValue.resize(bytesLeft / 4);
+ XFree((char*) propertyData);
+ propertyData = 0;
+
+ // fetch all data
+ if (XGetWindowProperty(X11->display, w->internalWinId(), ATOM(_NET_WM_STATE), 0,
+ returnValue.size(), False, XA_ATOM, &actualType, &actualFormat,
+ &propertyLength, &bytesLeft, &propertyData) != Success) {
+ returnValue.clear();
+ } else if (propertyLength != (ulong)returnValue.size()) {
+ returnValue.resize(propertyLength);
+ }
+
+ // put it into netWmState
+ if (!returnValue.isEmpty()) {
+ memcpy(returnValue.data(), propertyData, returnValue.size() * sizeof(Atom));
+ }
+ if (propertyData)
+ XFree((char*) propertyData);
+ }
+
+ return returnValue;
+}
+
+void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyOldWindow)
+{
+ Q_Q(QWidget);
+ Qt::WindowType type = q->windowType();
+ Qt::WindowFlags &flags = data.window_flags;
+ QWidget *parentWidget = q->parentWidget();
+
+ if (type == Qt::ToolTip)
+ flags |= Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint;
+ if (type == Qt::Popup)
+ flags |= Qt::X11BypassWindowManagerHint;
+
+ bool topLevel = (flags & Qt::Window);
+ bool popup = (type == Qt::Popup);
+ bool desktop = (type == Qt::Desktop);
+ bool tool = (type == Qt::Tool || type == Qt::SplashScreen
+ || type == Qt::ToolTip || type == Qt::Drawer);
+
+#ifdef ALIEN_DEBUG
+ qDebug() << "QWidgetPrivate::create_sys START:" << q << "topLevel?" << topLevel << "WId:"
+ << window << "initializeWindow:" << initializeWindow << "destroyOldWindow" << destroyOldWindow;
+#endif
+ if (topLevel) {
+ if (parentWidget) { // if our parent stays on top, so must we
+ QWidget *ptl = parentWidget->window();
+ if(ptl && (ptl->windowFlags() & Qt::WindowStaysOnTopHint))
+ flags |= Qt::WindowStaysOnTopHint;
+ }
+
+ if (type == Qt::SplashScreen) {
+ if (X11->isSupportedByWM(ATOM(_NET_WM_WINDOW_TYPE_SPLASH))) {
+ flags &= ~Qt::X11BypassWindowManagerHint;
+ } else {
+ flags |= Qt::X11BypassWindowManagerHint | Qt::FramelessWindowHint;
+ }
+ }
+ // All these buttons depend on the system menu, so we enable it
+ if (flags & (Qt::WindowMinimizeButtonHint
+ | Qt::WindowMaximizeButtonHint
+ | Qt::WindowContextHelpButtonHint))
+ flags |= Qt::WindowSystemMenuHint;
+ }
+
+
+ Window parentw, destroyw = 0;
+ WId id = 0;
+
+ // always initialize
+ if (!window)
+ initializeWindow = true;
+
+ QX11Info *parentXinfo = parentWidget ? &parentWidget->d_func()->xinfo : 0;
+
+ if (desktop &&
+ qt_x11_create_desktop_on_screen >= 0 &&
+ qt_x11_create_desktop_on_screen != xinfo.screen()) {
+ // desktop on a certain screen other than the default requested
+ QX11InfoData *xd = &X11->screens[qt_x11_create_desktop_on_screen];
+ xinfo.setX11Data(xd);
+ } else if (parentXinfo && (parentXinfo->screen() != xinfo.screen()
+ || (parentXinfo->visual() != xinfo.visual()
+ && !q->inherits("QGLWidget"))))
+ {
+ // QGLWidgets have to be excluded here as they have a
+ // specially crafted QX11Info structure which can't be swapped
+ // out with the parent widgets QX11Info. The parent visual,
+ // for instance, might not even be GL capable.
+ xinfo = *parentXinfo;
+ }
+
+ //get display, screen number, root window and desktop geometry for
+ //the current screen
+ Display *dpy = X11->display;
+ int scr = xinfo.screen();
+ Window root_win = RootWindow(dpy, scr);
+ int sw = DisplayWidth(dpy,scr);
+ int sh = DisplayHeight(dpy,scr);
+
+ if (desktop) { // desktop widget
+ popup = false; // force these flags off
+ data.crect.setRect(0, 0, sw, sh);
+ } else if (topLevel && !q->testAttribute(Qt::WA_Resized)) {
+ QDesktopWidget *desktopWidget = qApp->desktop();
+ if (desktopWidget->isVirtualDesktop()) {
+ QRect r = desktopWidget->screenGeometry();
+ sw = r.width();
+ sh = r.height();
+ }
+
+ int width = sw / 2;
+ int height = 4 * sh / 10;
+ if (extra) {
+ width = qMax(qMin(width, extra->maxw), extra->minw);
+ height = qMax(qMin(height, extra->maxh), extra->minh);
+ }
+ data.crect.setSize(QSize(width, height));
+ }
+
+ parentw = topLevel ? root_win : parentWidget->effectiveWinId();
+
+ XSetWindowAttributes wsa;
+
+ if (window) { // override the old window
+ if (destroyOldWindow) {
+ if (topLevel)
+ X11->dndEnable(q, false);
+ destroyw = data.winid;
+ }
+ id = window;
+ setWinId(window);
+ XWindowAttributes a;
+ XGetWindowAttributes(dpy, window, &a);
+ data.crect.setRect(a.x, a.y, a.width, a.height);
+
+ if (a.map_state == IsUnmapped)
+ q->setAttribute(Qt::WA_WState_Visible, false);
+ else
+ q->setAttribute(Qt::WA_WState_Visible);
+
+ qt_x11_getX11InfoForWindow(&xinfo,a);
+
+ } else if (desktop) { // desktop widget
+#ifdef QWIDGET_EXTRA_DEBUG
+ qDebug() << "create desktop";
+#endif
+ id = (WId)parentw; // id = root window
+// QWidget *otherDesktop = find(id); // is there another desktop?
+// if (otherDesktop && otherDesktop->testWFlags(Qt::WPaintDesktop)) {
+// otherDesktop->d->setWinId(0); // remove id from widget mapper
+// d->setWinId(id); // make sure otherDesktop is
+// otherDesktop->d->setWinId(id); // found first
+// } else {
+ setWinId(id);
+// }
+ } else if (topLevel || q->testAttribute(Qt::WA_NativeWindow) || paintOnScreen()) {
+#ifdef QWIDGET_EXTRA_DEBUG
+ static int topLevels = 0;
+ static int children = 0;
+ if (parentw == root_win)
+ qDebug() << "create toplevel" << ++topLevels;
+ else
+ qDebug() << "create child" << ++children;
+#endif
+ QRect safeRect = data.crect; //##### must handle huge sizes as well.... i.e. wrect
+ if (safeRect.width() < 1|| safeRect.height() < 1) {
+ if (topLevel) {
+ // top-levels must be at least 1x1
+ safeRect.setSize(safeRect.size().expandedTo(QSize(1, 1)));
+ } else {
+ // create it way off screen, and rely on
+ // setWSGeometry() to do the right thing with it later
+ safeRect = QRect(-1000,-1000,1,1);
+ }
+ }
+#ifndef QT_NO_XRENDER
+ int screen = xinfo.screen();
+ if (topLevel && X11->use_xrender
+ && xinfo.depth() != 32 && X11->argbVisuals[screen]
+ && q->testAttribute(Qt::WA_TranslucentBackground))
+ {
+ QX11InfoData *xd = xinfo.getX11Data(true);
+
+ xd->screen = screen;
+ xd->visual = X11->argbVisuals[screen];
+ xd->colormap = X11->argbColormaps[screen];
+ xd->depth = 32;
+ xd->defaultVisual = false;
+ xd->defaultColormap = false;
+ xd->cells = xd->visual->map_entries;
+ xinfo.setX11Data(xd);
+ }
+#endif
+ if (xinfo.defaultVisual() && xinfo.defaultColormap()) {
+ id = (WId)qt_XCreateSimpleWindow(q, dpy, parentw,
+ safeRect.left(), safeRect.top(),
+ safeRect.width(), safeRect.height(),
+ 0,
+ BlackPixel(dpy, xinfo.screen()),
+ WhitePixel(dpy, xinfo.screen()));
+ } else {
+ wsa.background_pixel = WhitePixel(dpy, xinfo.screen());
+ wsa.border_pixel = BlackPixel(dpy, xinfo.screen());
+ wsa.colormap = xinfo.colormap();
+ id = (WId)qt_XCreateWindow(q, dpy, parentw,
+ safeRect.left(), safeRect.top(),
+ safeRect.width(), safeRect.height(),
+ 0, xinfo.depth(), InputOutput,
+ (Visual *) xinfo.visual(),
+ CWBackPixel|CWBorderPixel|CWColormap,
+ &wsa);
+ }
+
+ setWinId(id); // set widget id/handle + hd
+ }
+
+#ifndef QT_NO_XRENDER
+ if (picture) {
+ XRenderFreePicture(X11->display, picture);
+ picture = 0;
+ }
+
+ if (X11->use_xrender && !desktop && q->internalWinId()) {
+ XRenderPictFormat *format = XRenderFindVisualFormat(dpy, (Visual *) xinfo.visual());
+ if (format)
+ picture = XRenderCreatePicture(dpy, id, format, 0, 0);
+ }
+#endif // QT_NO_XRENDER
+
+ QtMWMHints mwmhints;
+ mwmhints.flags = 0L;
+ mwmhints.functions = 0L;
+ mwmhints.decorations = 0;
+ mwmhints.input_mode = 0L;
+ mwmhints.status = 0L;
+
+ if (topLevel) {
+ ulong wsa_mask = 0;
+ if (type != Qt::SplashScreen) { // && customize) {
+ mwmhints.flags |= MWM_HINTS_DECORATIONS;
+
+ bool customize = flags & Qt::CustomizeWindowHint;
+ if (!(flags & Qt::FramelessWindowHint) && !(customize && !(flags & Qt::WindowTitleHint))) {
+ mwmhints.decorations |= MWM_DECOR_BORDER;
+ mwmhints.decorations |= MWM_DECOR_RESIZEH;
+
+ if (flags & Qt::WindowTitleHint)
+ mwmhints.decorations |= MWM_DECOR_TITLE;
+
+ if (flags & Qt::WindowSystemMenuHint)
+ mwmhints.decorations |= MWM_DECOR_MENU;
+
+ if (flags & Qt::WindowMinimizeButtonHint) {
+ mwmhints.decorations |= MWM_DECOR_MINIMIZE;
+ mwmhints.functions |= MWM_FUNC_MINIMIZE;
+ }
+
+ if (flags & Qt::WindowMaximizeButtonHint) {
+ mwmhints.decorations |= MWM_DECOR_MAXIMIZE;
+ mwmhints.functions |= MWM_FUNC_MAXIMIZE;
+ }
+
+ if (flags & Qt::WindowCloseButtonHint)
+ mwmhints.functions |= MWM_FUNC_CLOSE;
+ }
+ } else {
+ // if type == Qt::SplashScreen
+ mwmhints.decorations = MWM_DECOR_ALL;
+ }
+
+ if (tool) {
+ wsa.save_under = True;
+ wsa_mask |= CWSaveUnder;
+ }
+
+ if (flags & Qt::X11BypassWindowManagerHint) {
+ wsa.override_redirect = True;
+ wsa_mask |= CWOverrideRedirect;
+ }
+
+ if (wsa_mask && initializeWindow) {
+ Q_ASSERT(id);
+ XChangeWindowAttributes(dpy, id, wsa_mask, &wsa);
+ }
+
+ if (mwmhints.functions != 0) {
+ mwmhints.flags |= MWM_HINTS_FUNCTIONS;
+ mwmhints.functions |= MWM_FUNC_MOVE | MWM_FUNC_RESIZE;
+ } else {
+ mwmhints.functions = MWM_FUNC_ALL;
+ }
+
+ if (!(flags & Qt::FramelessWindowHint)
+ && flags & Qt::CustomizeWindowHint
+ && flags & Qt::WindowTitleHint
+ && !(flags &
+ (Qt::WindowMinimizeButtonHint
+ | Qt::WindowMaximizeButtonHint
+ | Qt::WindowCloseButtonHint))) {
+ // a special case - only the titlebar without any button
+ mwmhints.flags = MWM_HINTS_FUNCTIONS;
+ mwmhints.functions = MWM_FUNC_MOVE | MWM_FUNC_RESIZE;
+ mwmhints.decorations = 0;
+ }
+ }
+
+ if (!initializeWindow) {
+ // do no initialization
+ } else if (popup) { // popup widget
+ // set EWMH window types
+ setNetWmWindowTypes();
+
+ wsa.override_redirect = True;
+ wsa.save_under = True;
+ Q_ASSERT(id);
+ XChangeWindowAttributes(dpy, id, CWOverrideRedirect | CWSaveUnder,
+ &wsa);
+ } else if (topLevel && !desktop) { // top-level widget
+ if (!X11->wm_client_leader)
+ create_wm_client_leader();
+
+ // note: WM_TRANSIENT_FOR is set in QWidgetPrivate::show_sys()
+
+ XSizeHints size_hints;
+ size_hints.flags = USSize | PSize | PWinGravity;
+ size_hints.x = data.crect.left();
+ size_hints.y = data.crect.top();
+ size_hints.width = data.crect.width();
+ size_hints.height = data.crect.height();
+ size_hints.win_gravity =
+ QApplication::isRightToLeft() ? NorthEastGravity : NorthWestGravity;
+
+ XWMHints wm_hints; // window manager hints
+ memset(&wm_hints, 0, sizeof(wm_hints)); // make valgrind happy
+ wm_hints.flags = InputHint | StateHint | WindowGroupHint;
+ wm_hints.input = q->testAttribute(Qt::WA_X11DoNotAcceptFocus) ? False : True;
+ wm_hints.initial_state = NormalState;
+ wm_hints.window_group = X11->wm_client_leader;
+
+ XClassHint class_hint;
+ QByteArray appName = qAppName().toLatin1();
+ class_hint.res_name = appName.data(); // application name
+ class_hint.res_class = const_cast<char *>(QX11Info::appClass()); // application class
+
+ XSetWMProperties(dpy, id, 0, 0,
+ qApp->d_func()->argv, qApp->d_func()->argc,
+ &size_hints, &wm_hints, &class_hint);
+
+ XResizeWindow(dpy, id,
+ qBound(1, data.crect.width(), XCOORD_MAX),
+ qBound(1, data.crect.height(), XCOORD_MAX));
+ XStoreName(dpy, id, appName.data());
+ Atom protocols[5];
+ int n = 0;
+ protocols[n++] = ATOM(WM_DELETE_WINDOW); // support del window protocol
+ protocols[n++] = ATOM(WM_TAKE_FOCUS); // support take focus window protocol
+ protocols[n++] = ATOM(_NET_WM_PING); // support _NET_WM_PING protocol
+#ifndef QT_NO_XSYNC
+ protocols[n++] = ATOM(_NET_WM_SYNC_REQUEST); // support _NET_WM_SYNC_REQUEST protocol
+#endif // QT_NO_XSYNC
+ if (flags & Qt::WindowContextHelpButtonHint)
+ protocols[n++] = ATOM(_NET_WM_CONTEXT_HELP);
+ XSetWMProtocols(dpy, id, protocols, n);
+
+ // set mwm hints
+ SetMWMHints(dpy, id, mwmhints);
+
+ // set EWMH window types
+ setNetWmWindowTypes();
+
+ // set _NET_WM_PID
+ long curr_pid = getpid();
+ XChangeProperty(dpy, id, ATOM(_NET_WM_PID), XA_CARDINAL, 32, PropModeReplace,
+ (unsigned char *) &curr_pid, 1);
+
+ // when we create a toplevel widget, the frame strut should be dirty
+ data.fstrut_dirty = 1;
+
+ // declare the widget's window role
+ if (QTLWExtra *topData = maybeTopData()) {
+ if (!topData->role.isEmpty()) {
+ QByteArray windowRole = topData->role.toUtf8();
+ XChangeProperty(dpy, id,
+ ATOM(WM_WINDOW_ROLE), XA_STRING, 8, PropModeReplace,
+ (unsigned char *)windowRole.constData(), windowRole.length());
+ }
+ }
+
+ // set client leader property
+ XChangeProperty(dpy, id, ATOM(WM_CLIENT_LEADER),
+ XA_WINDOW, 32, PropModeReplace,
+ (unsigned char *)&X11->wm_client_leader, 1);
+ } else {
+ // non-toplevel widgets don't have a frame, so no need to
+ // update the strut
+ data.fstrut_dirty = 0;
+ }
+
+ if (initializeWindow && q->internalWinId()) {
+ // don't erase when resizing
+ wsa.bit_gravity = QApplication::isRightToLeft() ? NorthEastGravity : NorthWestGravity;
+ Q_ASSERT(id);
+ XChangeWindowAttributes(dpy, id, CWBitGravity, &wsa);
+ }
+
+ // set X11 event mask
+ if (desktop) {
+// QWidget* main_desktop = find(id);
+// if (main_desktop->testWFlags(Qt::WPaintDesktop))
+// XSelectInput(dpy, id, stdDesktopEventMask | ExposureMask);
+// else
+ XSelectInput(dpy, id, stdDesktopEventMask);
+ } else if (q->internalWinId()) {
+ XSelectInput(dpy, id, stdWidgetEventMask);
+#if !defined (QT_NO_TABLET)
+ QTabletDeviceDataList *tablet_list = qt_tablet_devices();
+ if (X11->ptrXSelectExtensionEvent) {
+ for (int i = 0; i < tablet_list->size(); ++i) {
+ QTabletDeviceData tablet = tablet_list->at(i);
+ X11->ptrXSelectExtensionEvent(dpy, id, reinterpret_cast<XEventClass*>(tablet.eventList),
+ tablet.eventCount);
+ }
+ }
+#endif
+ }
+
+ if (desktop) {
+ q->setAttribute(Qt::WA_WState_Visible);
+ } else if (topLevel) { // set X cursor
+ if (initializeWindow) {
+ qt_x11_enforce_cursor(q);
+
+ if (QTLWExtra *topData = maybeTopData())
+ if (!topData->caption.isEmpty())
+ setWindowTitle_helper(topData->caption);
+
+ //always enable dnd: it's not worth the effort to maintain the state
+ // NOTE: this always creates topData()
+ X11->dndEnable(q, true);
+
+ if (maybeTopData() && maybeTopData()->opacity != 255)
+ q->setWindowOpacity(maybeTopData()->opacity/255.);
+
+ }
+ } else if (q->internalWinId()) {
+ qt_x11_enforce_cursor(q);
+ if (QWidget *p = q->parentWidget()) // reset the cursor on the native parent
+ qt_x11_enforce_cursor(p);
+ }
+
+ if (extra && !extra->mask.isEmpty() && q->internalWinId())
+ XShapeCombineRegion(X11->display, q->internalWinId(), ShapeBounding, 0, 0,
+ extra->mask.handle(), ShapeSet);
+
+ if (q->hasFocus() && q->testAttribute(Qt::WA_InputMethodEnabled)) {
+ QInputContext *inputContext = q->inputContext();
+ if (inputContext)
+ inputContext->setFocusWidget(q);
+ }
+
+ if (destroyw) {
+ qt_XDestroyWindow(q, dpy, destroyw);
+ if (QTLWExtra *topData = maybeTopData()) {
+#ifndef QT_NO_XSYNC
+ if (topData->syncUpdateCounter)
+ XSyncDestroyCounter(dpy, topData->syncUpdateCounter);
+#endif
+ // we destroyed our old window - reset the top-level state
+ createTLSysExtra();
+ }
+ }
+
+ // newly created windows are positioned at the window system's
+ // (0,0) position. If the parent uses wrect mapping to expand the
+ // coordinate system, we must also adjust this widget's window
+ // system position
+ if (!topLevel && !parentWidget->data->wrect.topLeft().isNull())
+ setWSGeometry();
+ else if (topLevel && (data.crect.width() == 0 || data.crect.height() == 0))
+ q->setAttribute(Qt::WA_OutsideWSRange, true);
+
+ if (!topLevel && q->testAttribute(Qt::WA_NativeWindow) && q->testAttribute(Qt::WA_Mapped)) {
+ Q_ASSERT(q->internalWinId());
+ XMapWindow(X11->display, q->internalWinId());
+ // Ensure that mapped alien widgets are flushed immediately when re-created as native widgets.
+ if (QWindowSurface *surface = q->windowSurface())
+ surface->flush(q, q->rect(), q->mapTo(surface->window(), QPoint()));
+ }
+
+#ifdef ALIEN_DEBUG
+ qDebug() << "QWidgetPrivate::create_sys END:" << q;
+#endif
+}
+
+static void qt_x11_recreateWidget(QWidget *widget)
+{
+ if (widget->inherits("QGLWidget")) {
+ // We send QGLWidgets a ParentChange event which causes them to
+ // recreate their GL context, which in turn causes them to choose
+ // their visual again. Now that WA_TranslucentBackground is set,
+ // QGLContext::chooseVisual will select an ARGB visual.
+
+ // QGLWidget expects a ParentAboutToChange to be sent first
+ QEvent aboutToChangeEvent(QEvent::ParentAboutToChange);
+ QApplication::sendEvent(widget, &aboutToChangeEvent);
+
+ QEvent parentChangeEvent(QEvent::ParentChange);
+ QApplication::sendEvent(widget, &parentChangeEvent);
+ } else {
+ // For regular widgets, reparent them with their parent which
+ // also triggers a recreation of the native window
+ QPoint pos = widget->pos();
+ bool visible = widget->isVisible();
+ if (visible)
+ widget->hide();
+
+ widget->setParent(widget->parentWidget(), widget->windowFlags());
+ widget->move(pos);
+ if (visible)
+ widget->show();
+ }
+}
+
+static void qt_x11_recreateNativeWidgetsRecursive(QWidget *widget)
+{
+ if (widget->internalWinId())
+ qt_x11_recreateWidget(widget);
+
+ const QObjectList &children = widget->children();
+ for (int i = 0; i < children.size(); ++i) {
+ QWidget *child = qobject_cast<QWidget*>(children.at(i));
+ if (child)
+ qt_x11_recreateNativeWidgetsRecursive(child);
+ }
+}
+
+void QWidgetPrivate::x11UpdateIsOpaque()
+{
+#ifndef QT_NO_XRENDER
+ Q_Q(QWidget);
+ if (!q->testAttribute(Qt::WA_WState_Created) || !q->testAttribute(Qt::WA_TranslucentBackground))
+ return;
+
+ bool topLevel = (data.window_flags & Qt::Window);
+ int screen = xinfo.screen();
+ if (topLevel && X11->use_xrender
+ && X11->argbVisuals[screen] && xinfo.depth() != 32)
+ {
+ qt_x11_recreateNativeWidgetsRecursive(q);
+ }
+#endif
+}
+
+/*
+ Returns true if the background is inherited; otherwise returns
+ false.
+
+ Mainly used in the paintOnScreen case.
+*/
+bool QWidgetPrivate::isBackgroundInherited() const
+{
+ Q_Q(const QWidget);
+
+ // windows do not inherit their background
+ if (q->isWindow() || q->windowType() == Qt::SubWindow)
+ return false;
+
+ if (q->testAttribute(Qt::WA_NoSystemBackground) || q->testAttribute(Qt::WA_OpaquePaintEvent))
+ return false;
+
+ const QPalette &pal = q->palette();
+ QPalette::ColorRole bg = q->backgroundRole();
+ QBrush brush = pal.brush(bg);
+
+ // non opaque brushes leaves us no choice, we must inherit
+ if (!q->autoFillBackground() || !brush.isOpaque())
+ return true;
+
+ if (brush.style() == Qt::SolidPattern) {
+ // the background is just a solid color. If there is no
+ // propagated contents, then we claim as performance
+ // optimization that it was not inheritet. This is the normal
+ // case in standard Windows or Motif style.
+ const QWidget *w = q->parentWidget();
+ if (!w->d_func()->isBackgroundInherited())
+ return false;
+ }
+
+ return true;
+}
+
+void QWidget::destroy(bool destroyWindow, bool destroySubWindows)
+{
+ Q_D(QWidget);
+ d->aboutToDestroy();
+ if (!isWindow() && parentWidget())
+ parentWidget()->d_func()->invalidateBuffer(d->effectiveRectFor(geometry()));
+ d->deactivateWidgetCleanup();
+ if (testAttribute(Qt::WA_WState_Created)) {
+ setAttribute(Qt::WA_WState_Created, false);
+ QObjectList childList = children();
+ for (int i = 0; i < childList.size(); ++i) { // destroy all widget children
+ register QObject *obj = childList.at(i);
+ if (obj->isWidgetType())
+ static_cast<QWidget*>(obj)->destroy(destroySubWindows,
+ destroySubWindows);
+ }
+ if (QWidgetPrivate::mouseGrabber == this)
+ releaseMouse();
+ if (QWidgetPrivate::keyboardGrabber == this)
+ releaseKeyboard();
+ if (isWindow())
+ X11->deferred_map.removeAll(this);
+ if (isModal()) {
+ // just be sure we leave modal
+ QApplicationPrivate::leaveModal(this);
+ }
+ else if ((windowType() == Qt::Popup))
+ qApp->d_func()->closePopup(this);
+
+#ifndef QT_NO_XRENDER
+ if (d->picture) {
+ if (destroyWindow)
+ XRenderFreePicture(X11->display, d->picture);
+ d->picture = 0;
+ }
+#endif // QT_NO_XRENDER
+
+ // delete the _NET_WM_USER_TIME_WINDOW
+ qt_net_remove_user_time(this);
+
+ if ((windowType() == Qt::Desktop)) {
+ if (acceptDrops())
+ X11->dndEnable(this, false);
+ } else {
+ if (isWindow())
+ X11->dndEnable(this, false);
+ if (destroyWindow)
+ qt_XDestroyWindow(this, X11->display, data->winid);
+ }
+ QT_TRY {
+ d->setWinId(0);
+ } QT_CATCH (const std::bad_alloc &) {
+ // swallow - destructors must not throw
+ }
+
+ extern void qPRCleanup(QWidget *widget); // from qapplication_x11.cpp
+ if (testAttribute(Qt::WA_WState_Reparented))
+ qPRCleanup(this);
+
+ if(d->ic) {
+ delete d->ic;
+ } else {
+ // release previous focus information participating with
+ // preedit preservation of qic
+ QInputContext *qic = QApplicationPrivate::inputContext;
+ if (qic)
+ qic->widgetDestroyed(this);
+ }
+ }
+}
+
+void QWidgetPrivate::setParent_sys(QWidget *parent, Qt::WindowFlags f)
+{
+ Q_Q(QWidget);
+#ifdef ALIEN_DEBUG
+ qDebug() << "QWidgetPrivate::setParent_sys START" << q << "parent:" << parent;
+#endif
+ QX11Info old_xinfo = xinfo;
+ if (parent && parent->windowType() == Qt::Desktop) {
+ // make sure the widget is created on the same screen as the
+ // programmer specified desktop widget
+ xinfo = parent->d_func()->xinfo;
+ parent = 0;
+ }
+
+ QTLWExtra *topData = maybeTopData();
+ bool wasCreated = q->testAttribute(Qt::WA_WState_Created);
+ if (q->isVisible() && q->parentWidget() && parent != q->parentWidget())
+ q->parentWidget()->d_func()->invalidateBuffer(effectiveRectFor(q->geometry()));
+ extern void qPRCreate(const QWidget *, Window);
+#ifndef QT_NO_CURSOR
+ QCursor oldcurs;
+#endif
+
+ // dnd unregister (we will register again below)
+ if (q->testAttribute(Qt::WA_DropSiteRegistered))
+ q->setAttribute(Qt::WA_DropSiteRegistered, false);
+
+ // if we are a top then remove our dnd prop for now
+ // it will get rest later
+ if (q->isWindow() && wasCreated)
+ X11->dndEnable(q, false);
+
+ if (topData)
+ qt_net_remove_user_time(q);
+
+// QWidget *oldparent = q->parentWidget();
+ WId old_winid = wasCreated ? data.winid : 0;
+ if ((q->windowType() == Qt::Desktop))
+ old_winid = 0;
+ setWinId(0);
+
+#ifndef QT_NO_XRENDER
+ if (picture) {
+ XRenderFreePicture(X11->display, picture);
+ picture = 0;
+ }
+#endif
+
+ // hide and reparent our own window away. Otherwise we might get
+ // destroyed when emitting the child remove event below. See QWorkspace.
+ if (wasCreated && old_winid) {
+ XUnmapWindow(X11->display, old_winid);
+ if (!old_xinfo.screen() != xinfo.screen())
+ XReparentWindow(X11->display, old_winid, RootWindow(X11->display, xinfo.screen()), 0, 0);
+ }
+ if (topData) {
+ topData->parentWinId = 0;
+ // zero the frame strut and mark it dirty
+ topData->frameStrut.setCoords(0, 0, 0, 0);
+
+ // reparenting from top-level, make sure show() works again
+ topData->waitingForMapNotify = 0;
+ topData->validWMState = 0;
+ }
+ data.fstrut_dirty = (!parent || (f & Qt::Window)); // toplevels get a dirty framestrut
+
+ QObjectPrivate::setParent_helper(parent);
+ bool explicitlyHidden = q->testAttribute(Qt::WA_WState_Hidden) && q->testAttribute(Qt::WA_WState_ExplicitShowHide);
+
+ data.window_flags = f;
+ q->setAttribute(Qt::WA_WState_Created, false);
+ q->setAttribute(Qt::WA_WState_Visible, false);
+ q->setAttribute(Qt::WA_WState_Hidden, false);
+ adjustFlags(data.window_flags, q);
+ // keep compatibility with previous versions, we need to preserve the created state
+ // (but we recreate the winId for the widget being reparented, again for compatibility)
+ if (wasCreated)
+ createWinId();
+ if (q->isWindow() || (!parent || parent->isVisible()) || explicitlyHidden)
+ q->setAttribute(Qt::WA_WState_Hidden);
+ q->setAttribute(Qt::WA_WState_ExplicitShowHide, explicitlyHidden);
+
+ if (wasCreated) {
+ QObjectList chlist = q->children();
+ for (int i = 0; i < chlist.size(); ++i) { // reparent children
+ QObject *obj = chlist.at(i);
+ if (obj->isWidgetType()) {
+ QWidget *w = (QWidget *)obj;
+ if (!w->testAttribute(Qt::WA_WState_Created))
+ continue;
+ if (xinfo.screen() != w->d_func()->xinfo.screen()) {
+ // ### force setParent() to not shortcut out (because
+ // ### we're setting the parent to the current parent)
+ // ### setParent will add child back to the list
+ // ### of children so we need to make sure the
+ // ### widget won't be added twice.
+ w->d_func()->parent = 0;
+ this->children.removeOne(w);
+ w->setParent(q);
+ } else if (!w->isWindow()) {
+ w->d_func()->invalidateBuffer(w->rect());
+ if (w->internalWinId()) {
+ if (w->testAttribute(Qt::WA_NativeWindow)) {
+ QWidget *nativeParentWidget = w->nativeParentWidget();
+ // Qt::WA_NativeWindow ensures that we always have a nativeParentWidget
+ Q_ASSERT(nativeParentWidget != 0);
+ QPoint p = w->mapTo(nativeParentWidget, QPoint());
+ XReparentWindow(X11->display,
+ w->internalWinId(),
+ nativeParentWidget->internalWinId(),
+ p.x(), p.y());
+ } else {
+ w->d_func()->setParent_sys(q, w->data->window_flags);
+ }
+ }
+ } else if (isTransient(w)) {
+ /*
+ when reparenting toplevel windows with toplevel-transient children,
+ we need to make sure that the window manager gets the updated
+ WM_TRANSIENT_FOR information... unfortunately, some window managers
+ don't handle changing WM_TRANSIENT_FOR before the toplevel window is
+ visible, so we unmap and remap all toplevel-transient children *after*
+ the toplevel parent has been mapped. thankfully, this is easy in Qt :)
+
+ note that the WM_TRANSIENT_FOR hint is actually updated in
+ QWidgetPrivate::show_sys()
+ */
+ if (w->internalWinId())
+ XUnmapWindow(X11->display, w->internalWinId());
+ QApplication::postEvent(w, new QEvent(QEvent::ShowWindowRequest));
+ }
+ }
+ }
+ qPRCreate(q, old_winid);
+ updateSystemBackground();
+
+ if (old_winid) {
+ Window *cmwret;
+ int count;
+ if (XGetWMColormapWindows(X11->display, old_winid, &cmwret, &count)) {
+ Window *cmw;
+ int cmw_size = sizeof(Window)*count;
+ cmw = new Window[count];
+ memcpy((char *)cmw, (char *)cmwret, cmw_size);
+ XFree((char *)cmwret);
+ int i;
+ for (i=0; i<count; i++) {
+ if (cmw[i] == old_winid) {
+ cmw[i] = q->internalWinId();
+ break;
+ }
+ }
+ int top_count;
+ if (XGetWMColormapWindows(X11->display, q->window()->internalWinId(),
+ &cmwret, &top_count))
+ {
+ Window *merged_cmw = new Window[count + top_count];
+ memcpy((char *)merged_cmw, (char *)cmw, cmw_size);
+ memcpy((char *)merged_cmw + cmw_size, (char *)cmwret, sizeof(Window)*top_count);
+ delete [] cmw;
+ XFree((char *)cmwret);
+ cmw = merged_cmw;
+ count += top_count;
+ }
+
+ XSetWMColormapWindows(X11->display, q->window()->internalWinId(), cmw, count);
+ delete [] cmw;
+ }
+
+ qt_XDestroyWindow(q, X11->display, old_winid);
+ }
+ }
+
+ // check if we need to register our dropsite
+ if (q->testAttribute(Qt::WA_AcceptDrops)
+ || (!q->isWindow() && q->parentWidget() && q->parentWidget()->testAttribute(Qt::WA_DropSiteRegistered))) {
+ q->setAttribute(Qt::WA_DropSiteRegistered, true);
+ }
+#if !defined(QT_NO_IM)
+ ic = 0;
+#endif
+ invalidateBuffer(q->rect());
+#ifdef ALIEN_DEBUG
+ qDebug() << "QWidgetPrivate::setParent_sys END" << q;
+#endif
+}
+
+QPoint QWidgetPrivate::mapToGlobal(const QPoint &pos) const
+{
+ Q_Q(const QWidget);
+ if (!q->testAttribute(Qt::WA_WState_Created) || !q->internalWinId()) {
+ QPoint p = pos + q->data->crect.topLeft();
+ //cannot trust that !isWindow() implies parentWidget() before create
+ return (q->isWindow() || !q->parentWidget()) ? p : q->parentWidget()->d_func()->mapToGlobal(p);
+ }
+ int x, y;
+ Window child;
+ QPoint p = mapToWS(pos);
+ XTranslateCoordinates(X11->display, q->internalWinId(),
+ QApplication::desktop()->screen(xinfo.screen())->internalWinId(),
+ p.x(), p.y(), &x, &y, &child);
+ return QPoint(x, y);
+}
+
+QPoint QWidgetPrivate::mapFromGlobal(const QPoint &pos) const
+{
+ Q_Q(const QWidget);
+ if (!q->testAttribute(Qt::WA_WState_Created) || !q->internalWinId()) {
+ //cannot trust that !isWindow() implies parentWidget() before create
+ QPoint p = (q->isWindow() || !q->parentWidget()) ? pos : q->parentWidget()->d_func()->mapFromGlobal(pos);
+ return p - q->data->crect.topLeft();
+ }
+ int x, y;
+ Window child;
+ XTranslateCoordinates(X11->display,
+ QApplication::desktop()->screen(xinfo.screen())->internalWinId(),
+ q->internalWinId(), pos.x(), pos.y(), &x, &y, &child);
+ return mapFromWS(QPoint(x, y));
+}
+
+QPoint QWidget::mapToGlobal(const QPoint &pos) const
+{
+ Q_D(const QWidget);
+ QPoint offset = data->crect.topLeft();
+ const QWidget *w = this;
+ const QWidget *p = w->parentWidget();
+ while (!w->isWindow() && p) {
+ w = p;
+ p = p->parentWidget();
+ offset += w->data->crect.topLeft();
+ }
+
+ const QWidgetPrivate *wd = w->d_func();
+ QTLWExtra *tlw = wd->topData();
+ if (!tlw->embedded)
+ return pos + offset;
+
+ return d->mapToGlobal(pos);
+}
+
+QPoint QWidget::mapFromGlobal(const QPoint &pos) const
+{
+ Q_D(const QWidget);
+ QPoint offset = data->crect.topLeft();
+ const QWidget *w = this;
+ const QWidget *p = w->parentWidget();
+ while (!w->isWindow() && p) {
+ w = p;
+ p = p->parentWidget();
+ offset += w->data->crect.topLeft();
+ }
+
+ const QWidgetPrivate *wd = w->d_func();
+ QTLWExtra *tlw = wd->topData();
+ if (!tlw->embedded)
+ return pos - offset;
+
+ return d->mapFromGlobal(pos);
+}
+
+void QWidgetPrivate::updateSystemBackground()
+{
+ Q_Q(QWidget);
+ if (!q->testAttribute(Qt::WA_WState_Created) || !q->internalWinId())
+ return;
+ QBrush brush = q->palette().brush(QPalette::Active, q->backgroundRole());
+ Qt::WindowType type = q->windowType();
+ if (brush.style() == Qt::NoBrush
+ || q->testAttribute(Qt::WA_NoSystemBackground)
+ || q->testAttribute(Qt::WA_UpdatesDisabled)
+ || type == Qt::Popup || type == Qt::ToolTip) {
+ if (QX11Info::isCompositingManagerRunning()
+ && q->testAttribute(Qt::WA_TranslucentBackground)
+ && !(q->parent()))
+ XSetWindowBackground(X11->display, q->internalWinId(),
+ QColormap::instance(xinfo.screen()).pixel(Qt::transparent));
+ else
+ XSetWindowBackgroundPixmap(X11->display, q->internalWinId(), XNone);
+ }
+ else if (brush.style() == Qt::SolidPattern && brush.isOpaque())
+ XSetWindowBackground(X11->display, q->internalWinId(),
+ QColormap::instance(xinfo.screen()).pixel(brush.color()));
+ else if (isBackgroundInherited())
+ XSetWindowBackgroundPixmap(X11->display, q->internalWinId(), ParentRelative);
+ else if (brush.style() == Qt::TexturePattern) {
+ extern QPixmap qt_toX11Pixmap(const QPixmap &pixmap); // qpixmap_x11.cpp
+ XSetWindowBackgroundPixmap(X11->display, q->internalWinId(),
+ static_cast<QX11PlatformPixmap*>(qt_toX11Pixmap(brush.texture()).data.data())->x11ConvertToDefaultDepth());
+ } else
+ XSetWindowBackground(X11->display, q->internalWinId(),
+ QColormap::instance(xinfo.screen()).pixel(brush.color()));
+}
+
+#ifndef QT_NO_CURSOR
+void QWidgetPrivate::setCursor_sys(const QCursor &)
+{
+ Q_Q(QWidget);
+ qt_x11_enforce_cursor(q);
+ XFlush(X11->display);
+}
+
+void QWidgetPrivate::unsetCursor_sys()
+{
+ Q_Q(QWidget);
+ qt_x11_enforce_cursor(q);
+ XFlush(X11->display);
+}
+#endif
+
+static XTextProperty*
+qstring_to_xtp(const QString& s)
+{
+ static XTextProperty tp = { 0, 0, 0, 0 };
+ static bool free_prop = true; // we can't free tp.value in case it references
+ // the data of the static QCString below.
+ if (tp.value) {
+ if (free_prop)
+ XFree(tp.value);
+ tp.value = 0;
+ free_prop = true;
+ }
+
+ static const QTextCodec* mapper = QTextCodec::codecForLocale();
+ int errCode = 0;
+ if (mapper) {
+ QByteArray mapped = mapper->fromUnicode(s);
+ char* tl[2];
+ tl[0] = mapped.data();
+ tl[1] = 0;
+ errCode = XmbTextListToTextProperty(X11->display, tl, 1, XStdICCTextStyle, &tp);
+#if defined(QT_DEBUG)
+ if (errCode < 0)
+ qDebug("qstring_to_xtp result code %d", errCode);
+#endif
+ }
+ if (!mapper || errCode < 0) {
+ static QByteArray qcs;
+ qcs = s.toAscii();
+ tp.value = (uchar*)qcs.data();
+ tp.encoding = XA_STRING;
+ tp.format = 8;
+ tp.nitems = qcs.length();
+ free_prop = false;
+ }
+
+ // ### If we knew WM could understand unicode, we could use
+ // ### a much simpler, cheaper encoding...
+ /*
+ tp.value = (XChar2b*)s.unicode();
+ tp.encoding = XA_UNICODE; // wish
+ tp.format = 16;
+ tp.nitems = s.length();
+ */
+
+ return &tp;
+}
+
+void QWidgetPrivate::setWindowTitle_sys(const QString &caption)
+{
+ Q_Q(QWidget);
+ Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
+ if (!q->internalWinId())
+ return;
+ XSetWMName(X11->display, q->internalWinId(), qstring_to_xtp(caption));
+
+ QByteArray net_wm_name = caption.toUtf8();
+ XChangeProperty(X11->display, q->internalWinId(), ATOM(_NET_WM_NAME), ATOM(UTF8_STRING), 8,
+ PropModeReplace, (unsigned char *)net_wm_name.data(), net_wm_name.size());
+}
+
+void QWidgetPrivate::setWindowIcon_sys(bool forceReset)
+{
+ Q_Q(QWidget);
+ if (!q->testAttribute(Qt::WA_WState_Created))
+ return;
+ QTLWExtra *topData = this->topData();
+ if (topData->iconPixmap && !forceReset)
+ // already been set
+ return;
+
+ // preparing images to set the _NET_WM_ICON property
+ QIcon icon = q->windowIcon();
+ QVector<long> icon_data;
+ Qt::HANDLE pixmap_handle = 0;
+ if (!icon.isNull()) {
+ QList<QSize> availableSizes = icon.availableSizes();
+ if(availableSizes.isEmpty()) {
+ // try to use default sizes since the icon can be a scalable image like svg.
+ availableSizes.push_back(QSize(16,16));
+ availableSizes.push_back(QSize(32,32));
+ availableSizes.push_back(QSize(64,64));
+ availableSizes.push_back(QSize(128,128));
+ }
+ for(int i = 0; i < availableSizes.size(); ++i) {
+ QSize size = availableSizes.at(i);
+ QPixmap pixmap = icon.pixmap(size);
+ if (!pixmap.isNull()) {
+ QImage image = pixmap.toImage().convertToFormat(QImage::Format_ARGB32);
+ int pos = icon_data.size();
+ icon_data.resize(pos + 2 + image.width()*image.height());
+ icon_data[pos++] = image.width();
+ icon_data[pos++] = image.height();
+ if (sizeof(long) == sizeof(quint32)) {
+ memcpy(icon_data.data() + pos, image.scanLine(0), image.byteCount());
+ } else {
+ for (int y = 0; y < image.height(); ++y) {
+ uint *scanLine = reinterpret_cast<uint *>(image.scanLine(y));
+ for (int x = 0; x < image.width(); ++x)
+ icon_data[pos + y*image.width() + x] = scanLine[x];
+ }
+ }
+ }
+ }
+ if (!icon_data.isEmpty()) {
+ extern QPixmap qt_toX11Pixmap(const QPixmap &pixmap);
+ /*
+ if the app is running on an unknown desktop, or it is not
+ using the default visual, convert the icon to 1bpp as stated
+ in the ICCCM section 4.1.2.4; otherwise, create the icon pixmap
+ in the default depth (even though this violates the ICCCM)
+ */
+ if (X11->desktopEnvironment == DE_UNKNOWN
+ || !QX11Info::appDefaultVisual(xinfo.screen())
+ || !QX11Info::appDefaultColormap(xinfo.screen())) {
+ // unknown DE or non-default visual/colormap, use 1bpp bitmap
+ if (!forceReset || !topData->iconPixmap)
+ topData->iconPixmap = new QPixmap(qt_toX11Pixmap(QBitmap(icon.pixmap(QSize(64,64)))));
+ pixmap_handle = topData->iconPixmap->handle();
+ } else {
+ // default depth, use a normal pixmap (even though this
+ // violates the ICCCM), since this works on all DEs known to Qt
+ if (!forceReset || !topData->iconPixmap)
+ topData->iconPixmap = new QPixmap(qt_toX11Pixmap(icon.pixmap(QSize(64,64))));
+ pixmap_handle = static_cast<QX11PlatformPixmap*>(topData->iconPixmap->data.data())->x11ConvertToDefaultDepth();
+ }
+ }
+ }
+
+ if (!q->internalWinId())
+ return;
+
+ if (!icon_data.isEmpty()) {
+ XChangeProperty(X11->display, q->internalWinId(), ATOM(_NET_WM_ICON), XA_CARDINAL, 32,
+ PropModeReplace, (unsigned char *) icon_data.data(),
+ icon_data.size());
+ } else {
+ XDeleteProperty(X11->display, q->internalWinId(), ATOM(_NET_WM_ICON));
+ }
+
+ XWMHints *h = XGetWMHints(X11->display, q->internalWinId());
+ XWMHints wm_hints;
+ if (!h) {
+ memset(&wm_hints, 0, sizeof(wm_hints)); // make valgrind happy
+ h = &wm_hints;
+ }
+
+ if (pixmap_handle) {
+ h->icon_pixmap = pixmap_handle;
+ h->flags |= IconPixmapHint;
+ } else {
+ h->icon_pixmap = 0;
+ h->flags &= ~(IconPixmapHint | IconMaskHint);
+ }
+
+ XSetWMHints(X11->display, q->internalWinId(), h);
+ if (h != &wm_hints)
+ XFree((char *)h);
+}
+
+void QWidgetPrivate::setWindowIconText_sys(const QString &iconText)
+{
+ Q_Q(QWidget);
+ if (!q->internalWinId())
+ return;
+ Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
+ XSetWMIconName(X11->display, q->internalWinId(), qstring_to_xtp(iconText));
+
+ QByteArray icon_name = iconText.toUtf8();
+ XChangeProperty(X11->display, q->internalWinId(), ATOM(_NET_WM_ICON_NAME), ATOM(UTF8_STRING), 8,
+ PropModeReplace, (unsigned char *) icon_name.constData(), icon_name.size());
+}
+
+
+void QWidget::grabMouse()
+{
+ if (isVisible() && !qt_nograb()) {
+ if (QWidgetPrivate::mouseGrabber && QWidgetPrivate::mouseGrabber != this)
+ QWidgetPrivate::mouseGrabber->releaseMouse();
+ Q_ASSERT(testAttribute(Qt::WA_WState_Created));
+#ifndef QT_NO_DEBUG
+ int status =
+#endif
+ XGrabPointer(X11->display, effectiveWinId(), False,
+ (uint)(ButtonPressMask | ButtonReleaseMask |
+ PointerMotionMask | EnterWindowMask |
+ LeaveWindowMask),
+ GrabModeAsync, GrabModeAsync,
+ XNone, XNone, X11->time);
+#ifndef QT_NO_DEBUG
+ if (status) {
+ const char *s =
+ status == GrabNotViewable ? "\"GrabNotViewable\"" :
+ status == AlreadyGrabbed ? "\"AlreadyGrabbed\"" :
+ status == GrabFrozen ? "\"GrabFrozen\"" :
+ status == GrabInvalidTime ? "\"GrabInvalidTime\"" :
+ "<?>";
+ qWarning("QWidget::grabMouse: Failed with %s", s);
+ }
+#endif
+ QWidgetPrivate::mouseGrabber = this;
+ }
+}
+
+
+#ifndef QT_NO_CURSOR
+void QWidget::grabMouse(const QCursor &cursor)
+{
+ if (!qt_nograb()) {
+ if (QWidgetPrivate::mouseGrabber && QWidgetPrivate::mouseGrabber != this)
+ QWidgetPrivate::mouseGrabber->releaseMouse();
+ Q_ASSERT(testAttribute(Qt::WA_WState_Created));
+#ifndef QT_NO_DEBUG
+ int status =
+#endif
+ XGrabPointer(X11->display, effectiveWinId(), False,
+ (uint)(ButtonPressMask | ButtonReleaseMask |
+ PointerMotionMask | EnterWindowMask | LeaveWindowMask),
+ GrabModeAsync, GrabModeAsync,
+ XNone, cursor.handle(), X11->time);
+#ifndef QT_NO_DEBUG
+ if (status) {
+ const char *s =
+ status == GrabNotViewable ? "\"GrabNotViewable\"" :
+ status == AlreadyGrabbed ? "\"AlreadyGrabbed\"" :
+ status == GrabFrozen ? "\"GrabFrozen\"" :
+ status == GrabInvalidTime ? "\"GrabInvalidTime\"" :
+ "<?>";
+ qWarning("QWidget::grabMouse: Failed with %s", s);
+ }
+#endif
+ QWidgetPrivate::mouseGrabber = this;
+ }
+}
+#endif
+
+
+void QWidget::releaseMouse()
+{
+ if (!qt_nograb() && QWidgetPrivate::mouseGrabber == this) {
+ XUngrabPointer(X11->display, X11->time);
+ XFlush(X11->display);
+ QWidgetPrivate::mouseGrabber = 0;
+ }
+}
+
+
+void QWidget::grabKeyboard()
+{
+ if (!qt_nograb()) {
+ if (QWidgetPrivate::keyboardGrabber && QWidgetPrivate::keyboardGrabber != this)
+ QWidgetPrivate::keyboardGrabber->releaseKeyboard();
+ XGrabKeyboard(X11->display, effectiveWinId(), False, GrabModeAsync, GrabModeAsync,
+ X11->time);
+ QWidgetPrivate::keyboardGrabber = this;
+ }
+}
+
+
+void QWidget::releaseKeyboard()
+{
+ if (!qt_nograb() && QWidgetPrivate::keyboardGrabber == this) {
+ XUngrabKeyboard(X11->display, X11->time);
+ QWidgetPrivate::keyboardGrabber = 0;
+ }
+}
+
+
+QWidget *QWidget::mouseGrabber()
+{
+ return QWidgetPrivate::mouseGrabber;
+}
+
+
+QWidget *QWidget::keyboardGrabber()
+{
+ return QWidgetPrivate::keyboardGrabber;
+}
+
+void QWidget::activateWindow()
+{
+ QWidget *tlw = window();
+ if (tlw->isVisible() && !tlw->d_func()->topData()->embedded && !X11->deferred_map.contains(tlw)) {
+ if (X11->userTime == 0)
+ X11->userTime = X11->time;
+ qt_net_update_user_time(tlw, X11->userTime);
+
+ if (X11->isSupportedByWM(ATOM(_NET_ACTIVE_WINDOW))
+ && !(tlw->windowFlags() & Qt::X11BypassWindowManagerHint)) {
+ XEvent e;
+ e.xclient.type = ClientMessage;
+ e.xclient.message_type = ATOM(_NET_ACTIVE_WINDOW);
+ e.xclient.display = X11->display;
+ e.xclient.window = tlw->internalWinId();
+ e.xclient.format = 32;
+ e.xclient.data.l[0] = 1; // 1 == application
+ e.xclient.data.l[1] = X11->userTime;
+ if (QWidget *aw = QApplication::activeWindow())
+ e.xclient.data.l[2] = aw->internalWinId();
+ else
+ e.xclient.data.l[2] = XNone;
+ e.xclient.data.l[3] = 0;
+ e.xclient.data.l[4] = 0;
+ XSendEvent(X11->display, RootWindow(X11->display, tlw->x11Info().screen()),
+ false, SubstructureNotifyMask | SubstructureRedirectMask, &e);
+ } else {
+ if (!qt_widget_private(tlw)->topData()->waitingForMapNotify)
+ XSetInputFocus(X11->display, tlw->internalWinId(), XRevertToParent, X11->time);
+ }
+ }
+}
+
+void QWidget::setWindowState(Qt::WindowStates newstate)
+{
+ Q_D(QWidget);
+ bool needShow = false;
+ Qt::WindowStates oldstate = windowState();
+ if (oldstate == newstate)
+ return;
+ if (isWindow()) {
+ // Ensure the initial size is valid, since we store it as normalGeometry below.
+ if (!testAttribute(Qt::WA_Resized) && !isVisible())
+ adjustSize();
+
+ QTLWExtra *top = d->topData();
+
+ if ((oldstate & Qt::WindowMaximized) != (newstate & Qt::WindowMaximized)) {
+ if (X11->isSupportedByWM(ATOM(_NET_WM_STATE_MAXIMIZED_HORZ))
+ && X11->isSupportedByWM(ATOM(_NET_WM_STATE_MAXIMIZED_VERT))) {
+ if ((newstate & Qt::WindowMaximized) && !(oldstate & Qt::WindowFullScreen))
+ top->normalGeometry = geometry();
+ qt_change_net_wm_state(this, (newstate & Qt::WindowMaximized),
+ ATOM(_NET_WM_STATE_MAXIMIZED_HORZ),
+ ATOM(_NET_WM_STATE_MAXIMIZED_VERT));
+ } else if (! (newstate & Qt::WindowFullScreen)) {
+ if (newstate & Qt::WindowMaximized) {
+ // save original geometry
+ const QRect normalGeometry = geometry();
+
+ if (isVisible()) {
+ data->fstrut_dirty = true;
+ const QRect maxRect = QApplication::desktop()->availableGeometry(this);
+ const QRect r = top->normalGeometry;
+ const QRect fs = d->frameStrut();
+ setGeometry(maxRect.x() + fs.left(),
+ maxRect.y() + fs.top(),
+ maxRect.width() - fs.left() - fs.right(),
+ maxRect.height() - fs.top() - fs.bottom());
+ top->normalGeometry = r;
+ }
+
+ if (top->normalGeometry.width() < 0)
+ top->normalGeometry = normalGeometry;
+ } else {
+ // restore original geometry
+ setGeometry(top->normalGeometry);
+ }
+ }
+ }
+
+ if ((oldstate & Qt::WindowFullScreen) != (newstate & Qt::WindowFullScreen)) {
+ if (X11->isSupportedByWM(ATOM(_NET_WM_STATE_FULLSCREEN))) {
+ if (newstate & Qt::WindowFullScreen) {
+ top->normalGeometry = geometry();
+ top->fullScreenOffset = d->frameStrut().topLeft();
+ }
+ qt_change_net_wm_state(this, (newstate & Qt::WindowFullScreen),
+ ATOM(_NET_WM_STATE_FULLSCREEN));
+ } else {
+ needShow = isVisible();
+
+ if (newstate & Qt::WindowFullScreen) {
+ data->fstrut_dirty = true;
+ const QRect normalGeometry = geometry();
+ const QPoint fullScreenOffset = d->frameStrut().topLeft();
+
+ top->savedFlags = windowFlags();
+ setParent(0, Qt::Window | Qt::FramelessWindowHint);
+ const QRect r = top->normalGeometry;
+ setGeometry(qApp->desktop()->screenGeometry(this));
+ top->normalGeometry = r;
+
+ if (top->normalGeometry.width() < 0) {
+ top->normalGeometry = normalGeometry;
+ top->fullScreenOffset = fullScreenOffset;
+ }
+ } else {
+ setParent(0, top->savedFlags);
+
+ if (newstate & Qt::WindowMaximized) {
+ // from fullscreen to maximized
+ data->fstrut_dirty = true;
+ const QRect maxRect = QApplication::desktop()->availableGeometry(this);
+ const QRect r = top->normalGeometry;
+ const QRect fs = d->frameStrut();
+ setGeometry(maxRect.x() + fs.left(),
+ maxRect.y() + fs.top(),
+ maxRect.width() - fs.left() - fs.right(),
+ maxRect.height() - fs.top() - fs.bottom());
+ top->normalGeometry = r;
+ } else {
+ // restore original geometry
+ setGeometry(top->normalGeometry.adjusted(-top->fullScreenOffset.x(),
+ -top->fullScreenOffset.y(),
+ -top->fullScreenOffset.x(),
+ -top->fullScreenOffset.y()));
+ }
+ }
+ }
+ }
+
+ createWinId();
+ Q_ASSERT(testAttribute(Qt::WA_WState_Created));
+ if ((oldstate & Qt::WindowMinimized) != (newstate & Qt::WindowMinimized)) {
+ if (isVisible()) {
+ if (newstate & Qt::WindowMinimized) {
+ XEvent e;
+ e.xclient.type = ClientMessage;
+ e.xclient.message_type = ATOM(WM_CHANGE_STATE);
+ e.xclient.display = X11->display;
+ e.xclient.window = data->winid;
+ e.xclient.format = 32;
+ e.xclient.data.l[0] = IconicState;
+ e.xclient.data.l[1] = 0;
+ e.xclient.data.l[2] = 0;
+ e.xclient.data.l[3] = 0;
+ e.xclient.data.l[4] = 0;
+ XSendEvent(X11->display,
+ RootWindow(X11->display,d->xinfo.screen()),
+ False, (SubstructureNotifyMask|SubstructureRedirectMask), &e);
+ } else {
+ setAttribute(Qt::WA_Mapped);
+ XMapWindow(X11->display, effectiveWinId());
+ }
+ }
+
+ needShow = false;
+ }
+ }
+
+ data->window_state = newstate;
+
+ if (needShow)
+ show();
+
+ if (newstate & Qt::WindowActive)
+ activateWindow();
+
+ QWindowStateChangeEvent e(oldstate);
+ QApplication::sendEvent(this, &e);
+}
+
+/*!
+ \internal
+ Platform-specific part of QWidget::show().
+*/
+
+void QWidgetPrivate::show_sys()
+{
+ Q_Q(QWidget);
+ Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
+
+ if (q->testAttribute(Qt::WA_DontShowOnScreen)) {
+ invalidateBuffer(q->rect());
+ q->setAttribute(Qt::WA_Mapped);
+ if (QTLWExtra *tlwExtra = maybeTopData())
+ tlwExtra->waitingForMapNotify = 0;
+ return;
+ }
+
+ if (q->isWindow()) {
+ XWMHints *h = XGetWMHints(X11->display, q->internalWinId());
+ XWMHints wm_hints;
+ bool got_hints = h != 0;
+ if (!got_hints) {
+ memset(&wm_hints, 0, sizeof(wm_hints)); // make valgrind happy
+ h = &wm_hints;
+ }
+ h->initial_state = q->isMinimized() ? IconicState : NormalState;
+ h->flags |= StateHint;
+ XSetWMHints(X11->display, q->internalWinId(), h);
+ if (got_hints)
+ XFree((char *)h);
+
+ // update WM_NORMAL_HINTS
+ do_size_hints(q, extra);
+
+ // udpate WM_TRANSIENT_FOR
+ if (isTransient(q)) {
+ QWidget *p = q->parentWidget();
+
+#ifndef QT_NO_MENU
+ // hackish ... try to find the main window related to this QMenu
+ if (qobject_cast<QMenu *>(q)) {
+ p = static_cast<QMenuPrivate*>(this)->causedPopup.widget;
+ if (!p)
+ p = q->parentWidget();
+ if (!p)
+ p = QApplication::widgetAt(q->pos());
+ if (!p)
+ p = qApp->activeWindow();
+ }
+#endif
+ if (p)
+ p = p->window();
+ if (p) {
+ // transient for window
+ XSetTransientForHint(X11->display, q->internalWinId(), p->internalWinId());
+ } else {
+ // transient for group
+ XSetTransientForHint(X11->display, q->internalWinId(), X11->wm_client_leader);
+ }
+ }
+
+ // update _MOTIF_WM_HINTS
+ QtMWMHints mwmhints = GetMWMHints(X11->display, q->internalWinId());
+
+ if (data.window_modality != Qt::NonModal) {
+ switch (data.window_modality) {
+ case Qt::WindowModal:
+ mwmhints.input_mode = MWM_INPUT_PRIMARY_APPLICATION_MODAL;
+ break;
+ case Qt::ApplicationModal:
+ default:
+ mwmhints.input_mode = MWM_INPUT_FULL_APPLICATION_MODAL;
+ break;
+ }
+ mwmhints.flags |= MWM_HINTS_INPUT_MODE;
+ } else {
+ mwmhints.input_mode = MWM_INPUT_MODELESS;
+ mwmhints.flags &= ~MWM_HINTS_INPUT_MODE;
+ }
+
+ if (q->minimumSize() == q->maximumSize()) {
+ // fixed size, remove the resize handle (since mwm/dtwm
+ // isn't smart enough to do it itself)
+ mwmhints.flags |= MWM_HINTS_FUNCTIONS;
+ if (mwmhints.functions == MWM_FUNC_ALL) {
+ mwmhints.functions = MWM_FUNC_MOVE;
+ } else {
+ mwmhints.functions &= ~MWM_FUNC_RESIZE;
+ }
+
+ if (mwmhints.decorations == MWM_DECOR_ALL) {
+ mwmhints.flags |= MWM_HINTS_DECORATIONS;
+ mwmhints.decorations = (MWM_DECOR_BORDER
+ | MWM_DECOR_TITLE
+ | MWM_DECOR_MENU);
+ } else {
+ mwmhints.decorations &= ~MWM_DECOR_RESIZEH;
+ }
+
+ 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;
+ }
+ if (q->windowFlags() & Qt::WindowCloseButtonHint)
+ mwmhints.functions |= MWM_FUNC_CLOSE;
+ }
+
+ SetMWMHints(X11->display, q->internalWinId(), mwmhints);
+
+ // update _NET_WM_STATE
+ QVector<Atom> netWmState = getNetWmState(q);
+
+ Qt::WindowFlags flags = q->windowFlags();
+ if (flags & Qt::WindowStaysOnTopHint) {
+ if (flags & Qt::WindowStaysOnBottomHint)
+ qWarning() << "QWidget: Incompatible window flags: the window can't be on top and on bottom at the same time";
+ if (!netWmState.contains(ATOM(_NET_WM_STATE_ABOVE)))
+ netWmState.append(ATOM(_NET_WM_STATE_ABOVE));
+ if (!netWmState.contains(ATOM(_NET_WM_STATE_STAYS_ON_TOP)))
+ netWmState.append(ATOM(_NET_WM_STATE_STAYS_ON_TOP));
+ } else if (flags & Qt::WindowStaysOnBottomHint) {
+ if (!netWmState.contains(ATOM(_NET_WM_STATE_BELOW)))
+ netWmState.append(ATOM(_NET_WM_STATE_BELOW));
+ }
+ if (q->isFullScreen()) {
+ if (!netWmState.contains(ATOM(_NET_WM_STATE_FULLSCREEN)))
+ netWmState.append(ATOM(_NET_WM_STATE_FULLSCREEN));
+ }
+ if (q->isMaximized()) {
+ if (!netWmState.contains(ATOM(_NET_WM_STATE_MAXIMIZED_HORZ)))
+ netWmState.append(ATOM(_NET_WM_STATE_MAXIMIZED_HORZ));
+ if (!netWmState.contains(ATOM(_NET_WM_STATE_MAXIMIZED_VERT)))
+ netWmState.append(ATOM(_NET_WM_STATE_MAXIMIZED_VERT));
+ }
+ if (data.window_modality != Qt::NonModal) {
+ if (!netWmState.contains(ATOM(_NET_WM_STATE_MODAL)))
+ netWmState.append(ATOM(_NET_WM_STATE_MODAL));
+ }
+
+ if (!netWmState.isEmpty()) {
+ XChangeProperty(X11->display, q->internalWinId(),
+ ATOM(_NET_WM_STATE), XA_ATOM, 32, PropModeReplace,
+ (unsigned char *) netWmState.data(), netWmState.size());
+ } else {
+ XDeleteProperty(X11->display, q->internalWinId(), ATOM(_NET_WM_STATE));
+ }
+
+ // set _NET_WM_USER_TIME
+ Time userTime = X11->userTime;
+ bool setUserTime = false;
+ if (q->testAttribute(Qt::WA_ShowWithoutActivating)) {
+ userTime = 0;
+ setUserTime = true;
+ } else if (userTime != CurrentTime) {
+ setUserTime = true;
+ }
+ if (setUserTime)
+ qt_net_update_user_time(q, userTime);
+
+#ifndef QT_NO_XSYNC
+ if (!topData()->syncUpdateCounter) {
+ XSyncValue value;
+ XSyncIntToValue(&value, 0);
+ topData()->syncUpdateCounter = XSyncCreateCounter(X11->display, value);
+
+ XChangeProperty(X11->display, q->internalWinId(),
+ ATOM(_NET_WM_SYNC_REQUEST_COUNTER),
+ XA_CARDINAL,
+ 32, PropModeReplace,
+ (uchar *) &topData()->syncUpdateCounter, 1);
+
+ topData()->newCounterValueHi = 0;
+ topData()->newCounterValueLo = 0;
+ }
+#endif
+
+ if (!topData()->embedded
+ && (topData()->validWMState || topData()->waitingForMapNotify)
+ && !q->isMinimized()) {
+ X11->deferred_map.append(q);
+ return;
+ }
+
+ if (q->isMaximized() && !q->isFullScreen()
+ && !(X11->isSupportedByWM(ATOM(_NET_WM_STATE_MAXIMIZED_HORZ))
+ && X11->isSupportedByWM(ATOM(_NET_WM_STATE_MAXIMIZED_VERT)))) {
+ XMapWindow(X11->display, q->internalWinId());
+ data.fstrut_dirty = true;
+ qt_x11_wait_for_window_manager(q);
+
+ // if the wm was not smart enough to adjust our size, do that manually
+ QRect maxRect = QApplication::desktop()->availableGeometry(q);
+
+ QTLWExtra *top = topData();
+ QRect normalRect = top->normalGeometry;
+ const QRect fs = frameStrut();
+
+ q->setGeometry(maxRect.x() + fs.left(),
+ maxRect.y() + fs.top(),
+ maxRect.width() - fs.left() - fs.right(),
+ maxRect.height() - fs.top() - fs.bottom());
+
+ // restore the original normalGeometry
+ top->normalGeometry = normalRect;
+ // internalSetGeometry() clears the maximized flag... make sure we set it back
+ data.window_state = data.window_state | Qt::WindowMaximized;
+ q->setAttribute(Qt::WA_Mapped);
+ return;
+ }
+
+ if (q->isFullScreen() && !X11->isSupportedByWM(ATOM(_NET_WM_STATE_FULLSCREEN))) {
+ XMapWindow(X11->display, q->internalWinId());
+ qt_x11_wait_for_window_manager(q);
+ q->setAttribute(Qt::WA_Mapped);
+ return;
+ }
+ }
+
+ invalidateBuffer(q->rect());
+
+ if (q->testAttribute(Qt::WA_OutsideWSRange))
+ return;
+ q->setAttribute(Qt::WA_Mapped);
+ if (q->isWindow())
+ topData()->waitingForMapNotify = 1;
+
+ if (!q->isWindow()
+ && (!q->autoFillBackground()
+ || q->palette().brush(q->backgroundRole()).style() == Qt::LinearGradientPattern)) {
+ if (q->internalWinId()) {
+ XSetWindowBackgroundPixmap(X11->display, q->internalWinId(), XNone);
+ XMapWindow(X11->display, q->internalWinId());
+ updateSystemBackground();
+ }
+ return;
+ }
+
+ if (q->internalWinId())
+ XMapWindow(X11->display, q->internalWinId());
+
+ // Freedesktop.org Startup Notification
+ if (X11->startupId && q->isWindow()) {
+ QByteArray message("remove: ID=");
+ message.append(X11->startupId);
+ sendStartupMessage(message.constData());
+ X11->startupId = 0;
+ }
+}
+
+/*!
+ \internal
+ Platform-specific part of QWidget::show().
+*/
+
+void QWidgetPrivate::sendStartupMessage(const char *message) const
+{
+ Q_Q(const QWidget);
+
+ if (!message)
+ return;
+
+ XEvent xevent;
+ xevent.xclient.type = ClientMessage;
+ xevent.xclient.message_type = ATOM(_NET_STARTUP_INFO_BEGIN);
+ xevent.xclient.display = X11->display;
+ xevent.xclient.window = q->internalWinId();
+ xevent.xclient.format = 8;
+
+ Window rootWindow = RootWindow(X11->display, DefaultScreen(X11->display));
+ uint sent = 0;
+ uint length = strlen(message) + 1;
+ do {
+ if (sent == 20)
+ xevent.xclient.message_type = ATOM(_NET_STARTUP_INFO);
+
+ for (uint i = 0; i < 20 && i + sent <= length; i++)
+ xevent.xclient.data.b[i] = message[i + sent++];
+
+ XSendEvent(X11->display, rootWindow, false, PropertyChangeMask, &xevent);
+ } while (sent <= length);
+}
+
+void QWidgetPrivate::setNetWmWindowTypes()
+{
+ Q_Q(QWidget);
+ Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
+
+ if (!q->isWindow()) {
+ if (q->internalWinId())
+ XDeleteProperty(X11->display, q->internalWinId(), ATOM(_NET_WM_WINDOW_TYPE));
+ return;
+ }
+
+ QVector<long> windowTypes;
+
+ // manual selection 1 (these are never set by Qt and take precedence)
+ if (q->testAttribute(Qt::WA_X11NetWmWindowTypeDesktop))
+ windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_DESKTOP));
+ if (q->testAttribute(Qt::WA_X11NetWmWindowTypeDock))
+ windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_DOCK));
+ if (q->testAttribute(Qt::WA_X11NetWmWindowTypeNotification))
+ windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_NOTIFICATION));
+
+ // manual selection 2 (Qt uses these during auto selection);
+ if (q->testAttribute(Qt::WA_X11NetWmWindowTypeUtility))
+ windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_UTILITY));
+ if (q->testAttribute(Qt::WA_X11NetWmWindowTypeSplash))
+ windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_SPLASH));
+ if (q->testAttribute(Qt::WA_X11NetWmWindowTypeDialog))
+ windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_DIALOG));
+ if (q->testAttribute(Qt::WA_X11NetWmWindowTypeToolTip))
+ windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_TOOLTIP));
+
+ // manual selection 3 (these can be set by Qt, but don't have a
+ // corresponding Qt::WindowType). note that order of the *MENU
+ // atoms is important
+ if (q->testAttribute(Qt::WA_X11NetWmWindowTypeMenu))
+ windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_MENU));
+ if (q->testAttribute(Qt::WA_X11NetWmWindowTypeDropDownMenu))
+ windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_DROPDOWN_MENU));
+ if (q->testAttribute(Qt::WA_X11NetWmWindowTypePopupMenu))
+ windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_POPUP_MENU));
+ if (q->testAttribute(Qt::WA_X11NetWmWindowTypeToolBar))
+ windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_TOOLBAR));
+ if (q->testAttribute(Qt::WA_X11NetWmWindowTypeCombo))
+ windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_COMBO));
+ if (q->testAttribute(Qt::WA_X11NetWmWindowTypeDND))
+ windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_DND));
+
+ // automatic selection
+ switch (q->windowType()) {
+ case Qt::Dialog:
+ case Qt::Sheet:
+ // dialog netwm type
+ windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_DIALOG));
+ break;
+
+ case Qt::Tool:
+ case Qt::Drawer:
+ // utility netwm type
+ windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_UTILITY));
+ break;
+
+ case Qt::ToolTip:
+ // tooltip netwm type
+ windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_TOOLTIP));
+ break;
+
+ case Qt::SplashScreen:
+ // splash netwm type
+ windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_SPLASH));
+ break;
+
+ default:
+ break;
+ }
+
+ if (q->windowFlags() & Qt::FramelessWindowHint) {
+ // override netwm type - quick and easy for KDE noborder
+ windowTypes.append(ATOM(_KDE_NET_WM_WINDOW_TYPE_OVERRIDE));
+ }
+
+ // normal netwm type - default
+ windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_NORMAL));
+
+ if (!windowTypes.isEmpty()) {
+ XChangeProperty(X11->display, q->winId(), ATOM(_NET_WM_WINDOW_TYPE), XA_ATOM, 32,
+ PropModeReplace, (unsigned char *) windowTypes.constData(),
+ windowTypes.count());
+ } else {
+ XDeleteProperty(X11->display, q->winId(), ATOM(_NET_WM_WINDOW_TYPE));
+ }
+}
+
+/*!
+ \internal
+ Platform-specific part of QWidget::hide().
+*/
+
+void QWidgetPrivate::hide_sys()
+{
+ Q_Q(QWidget);
+ Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
+ deactivateWidgetCleanup();
+ if (q->isWindow()) {
+ X11->deferred_map.removeAll(q);
+ if (q->internalWinId()) // in nsplugin, may be 0
+ XWithdrawWindow(X11->display, q->internalWinId(), xinfo.screen());
+ XFlush(X11->display);
+ } else {
+ invalidateBuffer(q->rect());
+ if (q->internalWinId()) // in nsplugin, may be 0
+ XUnmapWindow(X11->display, q->internalWinId());
+ }
+ q->setAttribute(Qt::WA_Mapped, false);
+}
+
+void QWidgetPrivate::setFocus_sys()
+{
+
+}
+
+
+void QWidgetPrivate::raise_sys()
+{
+ Q_Q(QWidget);
+ Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
+ if (q->internalWinId())
+ XRaiseWindow(X11->display, q->internalWinId());
+}
+
+void QWidgetPrivate::lower_sys()
+{
+ Q_Q(QWidget);
+ Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
+ if (q->internalWinId())
+ XLowerWindow(X11->display, q->internalWinId());
+ if(!q->isWindow())
+ invalidateBuffer(q->rect());
+}
+
+void QWidgetPrivate::stackUnder_sys(QWidget* w)
+{
+ Q_Q(QWidget);
+ Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
+ if (q->internalWinId() && w->internalWinId()) {
+ Window stack[2];
+ stack[0] = w->internalWinId();;
+ stack[1] = q->internalWinId();
+ XRestackWindows(X11->display, stack, 2);
+ }
+ if(!q->isWindow() || !w->internalWinId())
+ invalidateBuffer(q->rect());
+}
+
+
+static void do_size_hints(QWidget* widget, QWExtra *x)
+{
+ Q_ASSERT(widget->testAttribute(Qt::WA_WState_Created));
+ XSizeHints s;
+ s.flags = 0;
+ if (x) {
+ QRect g = widget->geometry();
+ s.x = g.x();
+ s.y = g.y();
+ s.width = g.width();
+ s.height = g.height();
+ if (x->minw > 0 || x->minh > 0) {
+ // add minimum size hints
+ s.flags |= PMinSize;
+ s.min_width = qMin(XCOORD_MAX, x->minw);
+ s.min_height = qMin(XCOORD_MAX, x->minh);
+ }
+ if (x->maxw < QWIDGETSIZE_MAX || x->maxh < QWIDGETSIZE_MAX) {
+ // add maximum size hints
+ s.flags |= PMaxSize;
+ s.max_width = qMin(XCOORD_MAX, x->maxw);
+ s.max_height = qMin(XCOORD_MAX, x->maxh);
+ }
+ if (x->topextra &&
+ (x->topextra->incw > 0 || x->topextra->inch > 0)) {
+ // add resize increment hints
+ s.flags |= PResizeInc | PBaseSize;
+ s.width_inc = x->topextra->incw;
+ s.height_inc = x->topextra->inch;
+ s.base_width = x->topextra->basew;
+ s.base_height = x->topextra->baseh;
+ }
+ }
+ if (widget->testAttribute(Qt::WA_Moved)) {
+ // user (i.e. command-line) specified position
+ s.flags |= USPosition;
+ s.flags |= PPosition;
+ }
+ if (widget->testAttribute(Qt::WA_Resized)) {
+ // user (i.e. command-line) specified size
+ s.flags |= USSize;
+ s.flags |= PSize;
+ }
+ s.flags |= PWinGravity;
+ if (widget->testAttribute(Qt::WA_Moved) && x && x->topextra && !x->topextra->posFromMove) {
+ // position came from setGeometry(), tell the WM that we don't
+ // want our window gravity-shifted
+ s.win_gravity = StaticGravity;
+ } else {
+ // position came from move()
+ s.x = widget->x();
+ s.y = widget->y();
+ s.win_gravity = QApplication::isRightToLeft() ? NorthEastGravity : NorthWestGravity;
+ }
+ if (widget->internalWinId())
+ XSetWMNormalHints(X11->display, widget->internalWinId(), &s);
+}
+
+
+/*
+ Helper function for non-toplevel widgets. Helps to map Qt's 32bit
+ coordinate system to X11's 16bit coordinate system.
+
+ Sets the geometry of the widget to data.crect, but clipped to sizes
+ that X can handle. Unmaps widgets that are completely outside the
+ valid range.
+
+ Maintains data.wrect, which is the geometry of the X widget,
+ measured in this widget's coordinate system.
+
+ if the parent is not clipped, parentWRect is empty, otherwise
+ parentWRect is the geometry of the parent's X rect, measured in
+ parent's coord sys
+ */
+void QWidgetPrivate::setWSGeometry(bool dontShow, const QRect &)
+{
+ Q_Q(QWidget);
+ Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
+
+ /*
+ There are up to four different coordinate systems here:
+ Qt coordinate system for this widget.
+ X coordinate system for this widget (relative to wrect).
+ Qt coordinate system for parent
+ X coordinate system for parent (relative to parent's wrect).
+ */
+ Display *dpy = xinfo.display();
+ QRect validRange(-XCOORD_MAX,-XCOORD_MAX, 2*XCOORD_MAX, 2*XCOORD_MAX);
+ QRect wrectRange(-WRECT_MAX,-WRECT_MAX, 2*WRECT_MAX, 2*WRECT_MAX);
+ QRect wrect;
+ //xrect is the X geometry of my X widget. (starts out in parent's Qt coord sys, and ends up in parent's X coord sys)
+ QRect xrect = data.crect;
+
+ const QWidget *const parent = q->parentWidget();
+ QRect parentWRect = parent->data->wrect;
+
+ if (parentWRect.isValid()) {
+ // parent is clipped, and we have to clip to the same limit as parent
+ if (!parentWRect.contains(xrect)) {
+ xrect &= parentWRect;
+ wrect = xrect;
+ //translate from parent's to my Qt coord sys
+ wrect.translate(-data.crect.topLeft());
+ }
+ //translate from parent's Qt coords to parent's X coords
+ xrect.translate(-parentWRect.topLeft());
+
+ } else {
+ // parent is not clipped, we may or may not have to clip
+
+ if (data.wrect.isValid() && QRect(QPoint(),data.crect.size()).contains(data.wrect)) {
+ // This is where the main optimization is: we are already
+ // clipped, and if our clip is still valid, we can just
+ // move our window, and do not need to move or clip
+ // children
+
+ QRect vrect = xrect & parent->rect();
+ vrect.translate(-data.crect.topLeft()); //the part of me that's visible through parent, in my Qt coords
+ if (data.wrect.contains(vrect)) {
+ xrect = data.wrect;
+ xrect.translate(data.crect.topLeft());
+ if (data.winid)
+ XMoveWindow(dpy, data.winid, xrect.x(), xrect.y());
+ return;
+ }
+ }
+
+ if (!validRange.contains(xrect)) {
+ // we are too big, and must clip
+ xrect &=wrectRange;
+ wrect = xrect;
+ wrect.translate(-data.crect.topLeft());
+ //parent's X coord system is equal to parent's Qt coord
+ //sys, so we don't need to map xrect.
+ }
+
+ }
+
+ // unmap if we are outside the valid window system coord system
+ bool outsideRange = !xrect.isValid();
+ bool mapWindow = false;
+ if (q->testAttribute(Qt::WA_OutsideWSRange) != outsideRange) {
+ q->setAttribute(Qt::WA_OutsideWSRange, outsideRange);
+ if (outsideRange) {
+ if (data.winid)
+ XUnmapWindow(dpy, data.winid);
+ q->setAttribute(Qt::WA_Mapped, false);
+ } else if (!q->isHidden()) {
+ mapWindow = true;
+ }
+ }
+
+ if (outsideRange)
+ return;
+
+ bool jump = (data.wrect != wrect);
+ data.wrect = wrect;
+
+
+ // and now recursively for all children...
+ // ### can be optimized
+ for (int i = 0; i < children.size(); ++i) {
+ QObject *object = children.at(i);
+ if (object->isWidgetType()) {
+ QWidget *w = static_cast<QWidget *>(object);
+ if (!w->isWindow() && w->testAttribute(Qt::WA_WState_Created))
+ w->d_func()->setWSGeometry(jump);
+ }
+ }
+
+ if (data.winid) {
+ // move ourselves to the new position and map (if necessary) after
+ // the movement. Rationale: moving unmapped windows is much faster
+ // than moving mapped windows
+ if (jump) //avoid flicker when jumping
+ XSetWindowBackgroundPixmap(dpy, data.winid, XNone);
+ if (!parent->internalWinId())
+ xrect.translate(parent->mapTo(q->nativeParentWidget(), QPoint(0, 0)));
+ XMoveResizeWindow(dpy, data.winid, xrect.x(), xrect.y(), xrect.width(), xrect.height());
+ }
+
+ //to avoid flicker, we have to show children after the helper widget has moved
+ if (jump) {
+ for (int i = 0; i < children.size(); ++i) {
+ QObject *object = children.at(i);
+ if (object->isWidgetType()) {
+ QWidget *w = static_cast<QWidget *>(object);
+ if (!w->testAttribute(Qt::WA_OutsideWSRange) && !w->testAttribute(Qt::WA_Mapped) && !w->isHidden()) {
+ w->setAttribute(Qt::WA_Mapped);
+ if (w->internalWinId())
+ XMapWindow(dpy, w->data->winid);
+ }
+ }
+ }
+ }
+
+
+ if (jump && data.winid)
+ XClearArea(dpy, data.winid, 0, 0, wrect.width(), wrect.height(), True);
+
+ if (mapWindow && !dontShow) {
+ q->setAttribute(Qt::WA_Mapped);
+ if (data.winid)
+ XMapWindow(dpy, data.winid);
+ }
+}
+
+void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove)
+{
+ Q_Q(QWidget);
+ Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
+ Display *dpy = X11->display;
+
+ if ((q->windowType() == Qt::Desktop))
+ return;
+ if (q->isWindow()) {
+ if (!X11->isSupportedByWM(ATOM(_NET_WM_STATE_MAXIMIZED_VERT))
+ && !X11->isSupportedByWM(ATOM(_NET_WM_STATE_MAXIMIZED_HORZ)))
+ data.window_state &= ~Qt::WindowMaximized;
+ if (!X11->isSupportedByWM(ATOM(_NET_WM_STATE_FULLSCREEN)))
+ data.window_state &= ~Qt::WindowFullScreen;
+ if (QTLWExtra *topData = maybeTopData())
+ topData->normalGeometry = QRect(0,0,-1,-1);
+ } else {
+ uint s = data.window_state;
+ s &= ~(Qt::WindowMaximized | Qt::WindowFullScreen);
+ data.window_state = s;
+ }
+ if (extra) { // any size restrictions?
+ w = qMin(w,extra->maxw);
+ h = qMin(h,extra->maxh);
+ w = qMax(w,extra->minw);
+ h = qMax(h,extra->minh);
+ }
+ QPoint oldPos(q->pos());
+ QSize oldSize(q->size());
+ QRect oldGeom(data.crect);
+ QRect r(x, y, w, h);
+
+ // We only care about stuff that changes the geometry, or may
+ // cause the window manager to change its state
+ if (!q->isWindow() && oldGeom == r)
+ return;
+
+ data.crect = r;
+ bool isResize = q->size() != oldSize;
+
+ if (q->isWindow()) {
+ if (w == 0 || h == 0) {
+ q->setAttribute(Qt::WA_OutsideWSRange, true);
+ if (q->isVisible() && q->testAttribute(Qt::WA_Mapped))
+ hide_sys();
+ } else if (q->isVisible() && q->testAttribute(Qt::WA_OutsideWSRange)) {
+ q->setAttribute(Qt::WA_OutsideWSRange, false);
+
+ // put the window in its place and show it
+ if (data.winid)
+ XMoveResizeWindow(dpy, data.winid, x, y, w, h);
+ topData()->posFromMove = false; // force StaticGravity
+ do_size_hints(q, extra);
+ show_sys();
+ } else {
+ q->setAttribute(Qt::WA_OutsideWSRange, false);
+ if (!q->isVisible())
+ do_size_hints(q, extra);
+ if (isMove) {
+ if ((data.window_flags & Qt::X11BypassWindowManagerHint) == Qt::X11BypassWindowManagerHint
+ // work around 4Dwm's incompliance with ICCCM 4.1.5
+ || X11->desktopEnvironment == DE_4DWM) {
+ if (data.winid)
+ XMoveResizeWindow(dpy, data.winid, x, y, w, h);
+ } else if (q->isVisible()
+ && topData()->validWMState
+ && X11->isSupportedByWM(ATOM(_NET_MOVERESIZE_WINDOW))) {
+ XEvent e;
+ e.xclient.type = ClientMessage;
+ e.xclient.message_type = ATOM(_NET_MOVERESIZE_WINDOW);
+ e.xclient.display = X11->display;
+ e.xclient.window = q->internalWinId();
+ e.xclient.format = 32;
+ e.xclient.data.l[0] = StaticGravity | 1<<8 | 1<<9 | 1<<10 | 1<<11 | 1<<12;
+ e.xclient.data.l[1] = x;
+ e.xclient.data.l[2] = y;
+ e.xclient.data.l[3] = w;
+ e.xclient.data.l[4] = h;
+ XSendEvent(X11->display, RootWindow(X11->display, q->x11Info().screen()),
+ false, (SubstructureNotifyMask | SubstructureRedirectMask), &e);
+ } else if (data.winid) {
+ // pos() is right according to ICCCM 4.1.5
+ XMoveResizeWindow(dpy, data.winid, q->pos().x(), q->pos().y(), w, h);
+ }
+ } else if (isResize && data.winid) {
+ if (!q->isVisible()
+ && topData()->validWMState
+ && !q->testAttribute(Qt::WA_PendingMoveEvent)) {
+ /*
+ even though we've not visible, we could be in a
+ race w/ the window manager, and it may ignore
+ our ConfigureRequest. setting posFromMove to
+ false makes sure that doDeferredMap() in
+ qapplication_x11.cpp keeps the window in the
+ right place
+ */
+ topData()->posFromMove = false;
+ }
+ XResizeWindow(dpy, data.winid, w, h);
+ }
+ }
+ if (isResize && !q->testAttribute(Qt::WA_DontShowOnScreen)) // set config pending only on resize, see qapplication_x11.cpp, translateConfigEvent()
+ q->setAttribute(Qt::WA_WState_ConfigPending);
+
+ } else {
+ QTLWExtra *tlwExtra = q->window()->d_func()->maybeTopData();
+ const bool inTopLevelResize = tlwExtra ? tlwExtra->inTopLevelResize : false;
+ const bool disableInTopLevelResize = inTopLevelResize && q->internalWinId();
+ if (disableInTopLevelResize) {
+ // Top-level resize optimization does not work for native child widgets;
+ // disable it for this particular widget.
+ tlwExtra->inTopLevelResize = false;
+ }
+
+ if (!isResize && (!inTopLevelResize || disableInTopLevelResize) && q->isVisible()) {
+ moveRect(QRect(oldPos, oldSize), x - oldPos.x(), y - oldPos.y());
+ }
+ if (q->testAttribute(Qt::WA_WState_Created))
+ setWSGeometry();
+
+ if (isResize && (!inTopLevelResize || disableInTopLevelResize) && q->isVisible())
+ invalidateBuffer_resizeHelper(oldPos, oldSize);
+
+ if (disableInTopLevelResize)
+ tlwExtra->inTopLevelResize = true;
+ }
+
+ if (q->isVisible()) {
+ if (isMove && q->pos() != oldPos) {
+ if (X11->desktopEnvironment != DE_4DWM) {
+ // pos() is right according to ICCCM 4.1.5
+ QMoveEvent e(q->pos(), oldPos);
+ QApplication::sendEvent(q, &e);
+ } else {
+ // work around 4Dwm's incompliance with ICCCM 4.1.5
+ QMoveEvent e(data.crect.topLeft(), oldGeom.topLeft());
+ QApplication::sendEvent(q, &e);
+ }
+ }
+ if (isResize) {
+ static bool slowResize = qgetenv("QT_SLOW_TOPLEVEL_RESIZE").toInt();
+ // If we have a backing store with static contents, we have to disable the top-level
+ // resize optimization in order to get invalidated regions for resized widgets.
+ // The optimization discards all invalidateBuffer() calls since we're going to
+ // repaint everything anyways, but that's not the case with static contents.
+ const bool setTopLevelResize = !slowResize && q->isWindow() && extra && extra->topextra
+ && !extra->topextra->inTopLevelResize
+ && (!extra->topextra->backingStore
+ || !extra->topextra->backingStore->hasStaticContents());
+ if (setTopLevelResize)
+ extra->topextra->inTopLevelResize = true;
+ QResizeEvent e(q->size(), oldSize);
+ QApplication::sendEvent(q, &e);
+ if (setTopLevelResize)
+ extra->topextra->inTopLevelResize = false;
+ }
+ } else {
+ if (isMove && q->pos() != oldPos)
+ q->setAttribute(Qt::WA_PendingMoveEvent, true);
+ if (isResize)
+ q->setAttribute(Qt::WA_PendingResizeEvent, true);
+ }
+}
+
+void QWidgetPrivate::setConstraints_sys()
+{
+ Q_Q(QWidget);
+#ifdef ALIEN_DEBUG
+ qDebug() << "QWidgetPrivate::setConstraints_sys START" << q;
+#endif
+ if (q->testAttribute(Qt::WA_WState_Created))
+ do_size_hints(q, extra);
+#ifdef ALIEN_DEBUG
+ qDebug() << "QWidgetPrivate::setConstraints_sys END" << q;
+#endif
+}
+
+void QWidgetPrivate::scroll_sys(int dx, int dy)
+{
+ Q_Q(QWidget);
+
+ scrollChildren(dx, dy);
+ if (!paintOnScreen()) {
+ scrollRect(q->rect(), dx, dy);
+ } else {
+ scroll_sys(dx, dy, QRect());
+ }
+}
+
+void QWidgetPrivate::scroll_sys(int dx, int dy, const QRect &r)
+{
+ Q_Q(QWidget);
+
+ if (!paintOnScreen()) {
+ scrollRect(r, dx, dy);
+ return;
+ }
+ bool valid_rect = r.isValid();
+ bool just_update = qAbs(dx) > q->width() || qAbs(dy) > q->height();
+ QRect sr = valid_rect ? r : clipRect();
+ if (just_update)
+ q->update();
+ else if (!valid_rect)
+ dirty.translate(dx, dy);
+
+ int x1, y1, x2, y2, w = sr.width(), h = sr.height();
+ if (dx > 0) {
+ x1 = sr.x();
+ x2 = x1+dx;
+ w -= dx;
+ } else {
+ x2 = sr.x();
+ x1 = x2-dx;
+ w += dx;
+ }
+ if (dy > 0) {
+ y1 = sr.y();
+ y2 = y1+dy;
+ h -= dy;
+ } else {
+ y2 = sr.y();
+ y1 = y2-dy;
+ h += dy;
+ }
+
+ if (dx == 0 && dy == 0)
+ return;
+
+ Display *dpy = X11->display;
+ // Want expose events
+ if (w > 0 && h > 0 && !just_update && q->internalWinId()) {
+ GC gc = XCreateGC(dpy, q->internalWinId(), 0, 0);
+ XSetGraphicsExposures(dpy, gc, True);
+ XCopyArea(dpy, q->internalWinId(), q->internalWinId(), gc, x1, y1, w, h, x2, y2);
+ XFreeGC(dpy, gc);
+ }
+
+ if (!valid_rect && !children.isEmpty()) { // scroll children
+ QPoint pd(dx, dy);
+ for (int i = 0; i < children.size(); ++i) { // move all children
+ register QObject *object = children.at(i);
+ if (object->isWidgetType()) {
+ QWidget *w = static_cast<QWidget *>(object);
+ if (!w->isWindow())
+ w->move(w->pos() + pd);
+ }
+ }
+ }
+
+ if (just_update)
+ return;
+
+ // Don't let the server be bogged-down with repaint events
+ bool repaint_immediately = (qt_sip_count(q) < 3 && !q->testAttribute(Qt::WA_WState_InPaintEvent));
+
+ if (dx) {
+ int x = x2 == sr.x() ? sr.x()+w : sr.x();
+ if (repaint_immediately)
+ q->repaint(x, sr.y(), qAbs(dx), sr.height());
+ else if (q->internalWinId())
+ XClearArea(dpy, data.winid, x, sr.y(), qAbs(dx), sr.height(), True);
+ }
+ if (dy) {
+ int y = y2 == sr.y() ? sr.y()+h : sr.y();
+ if (repaint_immediately)
+ q->repaint(sr.x(), y, sr.width(), qAbs(dy));
+ else if (q->internalWinId())
+ XClearArea(dpy, data.winid, sr.x(), y, sr.width(), qAbs(dy), True);
+ }
+
+ qt_insert_sip(q, dx, dy); // #### ignores r
+}
+
+int QWidget::metric(PaintDeviceMetric m) const
+{
+ Q_D(const QWidget);
+ int val;
+ if (m == PdmWidth) {
+ val = data->crect.width();
+ } else if (m == PdmHeight) {
+ val = data->crect.height();
+ } else {
+ Display *dpy = X11->display;
+ int scr = d->xinfo.screen();
+ switch (m) {
+ case PdmDpiX:
+ case PdmPhysicalDpiX:
+ if (d->extra && d->extra->customDpiX)
+ val = d->extra->customDpiX;
+ else if (d->parent)
+ val = static_cast<QWidget *>(d->parent)->metric(m);
+ else
+ val = QX11Info::appDpiX(scr);
+ break;
+ case PdmDpiY:
+ case PdmPhysicalDpiY:
+ if (d->extra && d->extra->customDpiY)
+ val = d->extra->customDpiY;
+ else if (d->parent)
+ val = static_cast<QWidget *>(d->parent)->metric(m);
+ else
+ val = QX11Info::appDpiY(scr);
+ break;
+ case PdmWidthMM:
+ val = (DisplayWidthMM(dpy,scr)*data->crect.width())/
+ DisplayWidth(dpy,scr);
+ break;
+ case PdmHeightMM:
+ val = (DisplayHeightMM(dpy,scr)*data->crect.height())/
+ DisplayHeight(dpy,scr);
+ break;
+ case PdmNumColors:
+ val = d->xinfo.cells();
+ break;
+ case PdmDepth:
+ val = d->xinfo.depth();
+ break;
+ default:
+ val = 0;
+ qWarning("QWidget::metric: Invalid metric command");
+ }
+ }
+ return val;
+}
+
+void QWidgetPrivate::createSysExtra()
+{
+ extra->compress_events = true;
+ extra->xDndProxy = 0;
+}
+
+void QWidgetPrivate::deleteSysExtra()
+{
+}
+
+void QWidgetPrivate::createTLSysExtra()
+{
+ extra->topextra->spont_unmapped = 0;
+ extra->topextra->dnd = 0;
+ extra->topextra->validWMState = 0;
+ extra->topextra->waitingForMapNotify = 0;
+ extra->topextra->parentWinId = 0;
+ extra->topextra->userTimeWindow = 0;
+#ifndef QT_NO_XSYNC
+ extra->topextra->syncUpdateCounter = 0;
+ extra->topextra->syncRequestTimestamp = 0;
+ extra->topextra->newCounterValueHi = 0;
+ extra->topextra->newCounterValueLo = 0;
+#endif
+}
+
+void QWidgetPrivate::deleteTLSysExtra()
+{
+ // don't destroy input context here. it will be destroyed in
+ // QWidget::destroy() destroyInputContext();
+}
+
+void QWidgetPrivate::registerDropSite(bool on)
+{
+ Q_UNUSED(on);
+}
+
+void QWidgetPrivate::setMask_sys(const QRegion &region)
+{
+ Q_Q(QWidget);
+ if (!q->internalWinId())
+ return;
+
+ if (region.isEmpty()) {
+ XShapeCombineMask(X11->display, q->internalWinId(), ShapeBounding, 0, 0,
+ XNone, ShapeSet);
+ } else {
+ XShapeCombineRegion(X11->display, q->internalWinId(), ShapeBounding, 0, 0,
+ region.handle(), ShapeSet);
+ }
+}
+
+/*!
+ \internal
+
+ Computes the frame rectangle when needed. This is an internal function, you
+ should never call this.
+*/
+
+void QWidgetPrivate::updateFrameStrut()
+{
+ Q_Q(QWidget);
+
+ QTLWExtra *top = topData();
+ if (!top->validWMState) {
+ return;
+ }
+ if (!q->isWindow() && !q->internalWinId()) {
+ data.fstrut_dirty = false;
+ return;
+ }
+
+ Atom type_ret;
+ Window l = q->effectiveWinId(), w = l, p, r; // target window, its parent, root
+ Window *c;
+ int i_unused;
+ unsigned int nc;
+ unsigned char *data_ret;
+ unsigned long l_unused;
+
+ while (XQueryTree(X11->display, w, &r, &p, &c, &nc)) {
+ if (c && nc > 0)
+ XFree(c);
+
+ if (! p) {
+ qWarning("QWidget::updateFrameStrut: No parent");
+ return;
+ }
+
+ // if the parent window is the root window, an Enlightenment virtual root or
+ // a NET WM virtual root window, stop here
+ data_ret = 0;
+ if (p == r ||
+ (XGetWindowProperty(X11->display, p,
+ ATOM(ENLIGHTENMENT_DESKTOP), 0, 1, False, XA_CARDINAL,
+ &type_ret, &i_unused, &l_unused, &l_unused,
+ &data_ret) == Success &&
+ type_ret == XA_CARDINAL)) {
+ if (data_ret)
+ XFree(data_ret);
+
+ break;
+ } else if (X11->isSupportedByWM(ATOM(_NET_VIRTUAL_ROOTS)) && X11->net_virtual_root_list) {
+ int i = 0;
+ while (X11->net_virtual_root_list[i] != 0) {
+ if (X11->net_virtual_root_list[i++] == p)
+ break;
+ }
+ }
+
+ l = w;
+ w = p;
+ }
+
+ // we have our window
+ int transx, transy;
+ XWindowAttributes wattr;
+ if (XTranslateCoordinates(X11->display, l, w,
+ 0, 0, &transx, &transy, &p) &&
+ XGetWindowAttributes(X11->display, w, &wattr)) {
+ top->frameStrut.setCoords(transx,
+ transy,
+ wattr.width - data.crect.width() - transx,
+ wattr.height - data.crect.height() - transy);
+
+ // add the border_width for the window managers frame... some window managers
+ // do not use a border_width of zero for their frames, and if we the left and
+ // top strut, we ensure that pos() is absolutely correct. frameGeometry()
+ // will still be incorrect though... perhaps i should have foffset as well, to
+ // indicate the frame offset (equal to the border_width on X).
+ // - Brad
+ top->frameStrut.adjust(wattr.border_width,
+ wattr.border_width,
+ wattr.border_width,
+ wattr.border_width);
+ }
+
+ data.fstrut_dirty = false;
+}
+
+void QWidgetPrivate::setWindowOpacity_sys(qreal opacity)
+{
+ Q_Q(QWidget);
+ ulong value = ulong(opacity * 0xffffffff);
+ XChangeProperty(QX11Info::display(), q->internalWinId(), ATOM(_NET_WM_WINDOW_OPACITY), XA_CARDINAL,
+ 32, PropModeReplace, (uchar*)&value, 1);
+}
+
+const QX11Info &QWidget::x11Info() const
+{
+ Q_D(const QWidget);
+ return d->xinfo;
+}
+
+void QWidgetPrivate::setWindowRole()
+{
+ Q_Q(QWidget);
+ if (!q->internalWinId())
+ return;
+ QByteArray windowRole = topData()->role.toUtf8();
+ XChangeProperty(X11->display, q->internalWinId(),
+ ATOM(WM_WINDOW_ROLE), XA_STRING, 8, PropModeReplace,
+ (unsigned char *)windowRole.constData(), windowRole.length());
+}
+
+Q_GLOBAL_STATIC(QX11PaintEngine, qt_widget_paintengine)
+QPaintEngine *QWidget::paintEngine() const
+{
+ Q_D(const QWidget);
+ if (qt_widget_paintengine()->isActive()) {
+ if (d->extraPaintEngine)
+ return d->extraPaintEngine;
+ QWidget *self = const_cast<QWidget *>(this);
+ self->d_func()->extraPaintEngine = new QX11PaintEngine();
+ return d->extraPaintEngine;
+ }
+ return qt_widget_paintengine();
+}
+
+QWindowSurface *QWidgetPrivate::createDefaultWindowSurface_sys()
+{
+ return new QX11WindowSurface(q_func());
+}
+
+Qt::HANDLE QWidget::x11PictureHandle() const
+{
+#ifndef QT_NO_XRENDER
+ Q_D(const QWidget);
+ if (!internalWinId() && testAttribute(Qt::WA_WState_Created))
+ (void)winId(); // enforce native window
+ return d->picture;
+#else
+ return 0;
+#endif // QT_NO_XRENDER
+}
+
+#ifndef QT_NO_XRENDER
+XRenderColor QX11Data::preMultiply(const QColor &c)
+{
+ XRenderColor color;
+ const uint A = c.alpha(),
+ R = c.red(),
+ G = c.green(),
+ B = c.blue();
+ color.alpha = (A | A << 8);
+ color.red = (R | R << 8) * color.alpha / 0x10000;
+ color.green = (G | G << 8) * color.alpha / 0x10000;
+ color.blue = (B | B << 8) * color.alpha / 0x10000;
+ return color;
+}
+Picture QX11Data::getSolidFill(int screen, const QColor &c)
+{
+ if (!X11->use_xrender)
+ return XNone;
+
+ XRenderColor color = preMultiply(c);
+ for (int i = 0; i < X11->solid_fill_count; ++i) {
+ if (X11->solid_fills[i].screen == screen
+ && X11->solid_fills[i].color.alpha == color.alpha
+ && X11->solid_fills[i].color.red == color.red
+ && X11->solid_fills[i].color.green == color.green
+ && X11->solid_fills[i].color.blue == color.blue)
+ return X11->solid_fills[i].picture;
+ }
+ // none found, replace one
+ int i = qrand() % 16;
+
+ if (X11->solid_fills[i].screen != screen && X11->solid_fills[i].picture) {
+ XRenderFreePicture (X11->display, X11->solid_fills[i].picture);
+ X11->solid_fills[i].picture = 0;
+ }
+
+ if (!X11->solid_fills[i].picture) {
+ Pixmap pixmap = XCreatePixmap (X11->display, RootWindow (X11->display, screen), 1, 1, 32);
+ XRenderPictureAttributes attrs;
+ attrs.repeat = True;
+ X11->solid_fills[i].picture = XRenderCreatePicture (X11->display, pixmap,
+ XRenderFindStandardFormat(X11->display, PictStandardARGB32),
+ CPRepeat, &attrs);
+ XFreePixmap (X11->display, pixmap);
+ }
+
+ X11->solid_fills[i].color = color;
+ X11->solid_fills[i].screen = screen;
+ XRenderFillRectangle (X11->display, PictOpSrc, X11->solid_fills[i].picture, &color, 0, 0, 1, 1);
+ return X11->solid_fills[i].picture;
+}
+#endif
+
+void QWidgetPrivate::setModal_sys()
+{
+}
+
+void qt_x11_getX11InfoForWindow(QX11Info * xinfo, const QX11WindowAttributes &att)
+{
+ QX11InfoData* xd = xinfo->getX11Data(true);
+ const XWindowAttributes &a = *(att.att);
+ // find which screen the window is on...
+ xd->screen = QX11Info::appScreen(); // by default, use the default :)
+ int i;
+ for (i = 0; i < ScreenCount(X11->display); i++) {
+ if (RootWindow(X11->display, i) == a.root) {
+ xd->screen = i;
+ break;
+ }
+ }
+
+ xd->depth = a.depth;
+ xd->cells = DisplayCells(X11->display, xd->screen);
+ xd->visual = a.visual;
+ xd->defaultVisual = (XVisualIDFromVisual((Visual *) a.visual) ==
+ XVisualIDFromVisual((Visual *) QX11Info::appVisual(xinfo->screen())));
+ xd->colormap = a.colormap;
+ xd->defaultColormap = (a.colormap == QX11Info::appColormap(xinfo->screen()));
+ xinfo->setX11Data(xd);
+}
+
+void QWidgetPrivate::updateX11AcceptFocus()
+{
+ Q_Q(QWidget);
+ if (!q->isWindow() || !q->internalWinId())
+ return;
+
+ XWMHints *h = XGetWMHints(X11->display, q->internalWinId());
+ XWMHints wm_hints;
+ if (!h) {
+ memset(&wm_hints, 0, sizeof(wm_hints)); // make valgrind happy
+ h = &wm_hints;
+ }
+ h->flags |= InputHint;
+ h->input = q->testAttribute(Qt::WA_X11DoNotAcceptFocus) ? False : True;
+
+ XSetWMHints(X11->display, q->internalWinId(), h);
+ if (h != &wm_hints)
+ XFree((char *)h);
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/kernel/qwidgetcreate_x11.cpp b/src/widgets/platforms/x11/qwidgetcreate_x11.cpp
index 0a0656dd2b..0a0656dd2b 100644
--- a/src/gui/kernel/qwidgetcreate_x11.cpp
+++ b/src/widgets/platforms/x11/qwidgetcreate_x11.cpp
diff --git a/src/gui/kernel/qx11embed_x11.cpp b/src/widgets/platforms/x11/qx11embed_x11.cpp
index 1fa658d0df..1fa658d0df 100644
--- a/src/gui/kernel/qx11embed_x11.cpp
+++ b/src/widgets/platforms/x11/qx11embed_x11.cpp
diff --git a/src/widgets/platforms/x11/qx11embed_x11.h b/src/widgets/platforms/x11/qx11embed_x11.h
new file mode 100644
index 0000000000..fcf94b60a2
--- /dev/null
+++ b/src/widgets/platforms/x11/qx11embed_x11.h
@@ -0,0 +1,132 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QX11EMBED_X11_H
+#define QX11EMBED_X11_H
+
+#include <QtWidgets/qwidget.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QX11EmbedWidgetPrivate;
+class Q_WIDGETS_EXPORT QX11EmbedWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ QX11EmbedWidget(QWidget *parent = 0);
+ ~QX11EmbedWidget();
+
+ void embedInto(WId id);
+ WId containerWinId() const;
+
+ enum Error {
+ Unknown,
+ Internal,
+ InvalidWindowID
+ };
+ Error error() const;
+
+Q_SIGNALS:
+ void embedded();
+ void containerClosed();
+ void error(QX11EmbedWidget::Error error);
+
+protected:
+ bool x11Event(XEvent *);
+ bool eventFilter(QObject *, QEvent *);
+ bool event(QEvent *);
+ void resizeEvent(QResizeEvent *);
+
+private:
+ Q_DECLARE_PRIVATE(QX11EmbedWidget)
+ Q_DISABLE_COPY(QX11EmbedWidget)
+};
+
+class QX11EmbedContainerPrivate;
+class Q_WIDGETS_EXPORT QX11EmbedContainer : public QWidget
+{
+ Q_OBJECT
+public:
+ QX11EmbedContainer(QWidget *parent = 0);
+ ~QX11EmbedContainer();
+
+ void embedClient(WId id);
+ void discardClient();
+
+ WId clientWinId() const;
+
+ QSize minimumSizeHint() const;
+
+ enum Error {
+ Unknown,
+ Internal,
+ InvalidWindowID
+ };
+ Error error() const;
+
+Q_SIGNALS:
+ void clientIsEmbedded();
+ void clientClosed();
+ void error(QX11EmbedContainer::Error);
+
+protected:
+ bool x11Event(XEvent *);
+ bool eventFilter(QObject *, QEvent *);
+ void paintEvent(QPaintEvent *e);
+ void resizeEvent(QResizeEvent *);
+ void showEvent(QShowEvent *);
+ void hideEvent(QHideEvent *);
+ bool event(QEvent *);
+
+private:
+ Q_DECLARE_PRIVATE(QX11EmbedContainer)
+ Q_DISABLE_COPY(QX11EmbedContainer)
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QX11EMBED_X11_H
diff --git a/src/gui/kernel/qx11info_x11.cpp b/src/widgets/platforms/x11/qx11info_x11.cpp
index f359b610e1..f359b610e1 100644
--- a/src/gui/kernel/qx11info_x11.cpp
+++ b/src/widgets/platforms/x11/qx11info_x11.cpp
diff --git a/src/widgets/platforms/x11/qx11info_x11.h b/src/widgets/platforms/x11/qx11info_x11.h
new file mode 100644
index 0000000000..60cd0e9e92
--- /dev/null
+++ b/src/widgets/platforms/x11/qx11info_x11.h
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QX11INFO_X11_H
+#define QX11INFO_X11_H
+
+#include <QtCore/qnamespace.h>
+
+typedef struct _XDisplay Display;
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+struct QX11InfoData;
+class QX11Info;
+class QPaintDevice;
+class QApplicationPrivate;
+class QX11InfoPrivate;
+struct QX11WindowAttributes;
+
+void qt_x11_getX11InfoForWindow(QX11Info * xinfo, const QX11WindowAttributes &a);
+class Q_WIDGETS_EXPORT QX11Info
+{
+public:
+ QX11Info();
+ ~QX11Info();
+ QX11Info(const QX11Info &other);
+ QX11Info &operator=(const QX11Info &other);
+
+ static Display *display();
+ static const char *appClass();
+ int screen() const;
+ int depth() const;
+ int cells() const;
+ Qt::HANDLE colormap() const;
+ bool defaultColormap() const;
+ void *visual() const;
+ bool defaultVisual() const;
+
+ static int appScreen();
+ static int appDepth(int screen = -1);
+ static int appCells(int screen = -1);
+ static Qt::HANDLE appColormap(int screen = -1);
+ static void *appVisual(int screen = -1);
+ static Qt::HANDLE appRootWindow(int screen = -1);
+ static bool appDefaultColormap(int screen = -1);
+ static bool appDefaultVisual(int screen = -1);
+ static int appDpiX(int screen = -1);
+ static int appDpiY(int screen = -1);
+ static void setAppDpiX(int screen, int dpi);
+ static void setAppDpiY(int screen, int dpi);
+ static unsigned long appTime();
+ static unsigned long appUserTime();
+ static void setAppTime(unsigned long time);
+ static void setAppUserTime(unsigned long time);
+ static bool isCompositingManagerRunning();
+
+protected:
+ void copyX11Data(const QPaintDevice *);
+ void cloneX11Data(const QPaintDevice *);
+ void setX11Data(const QX11InfoData *);
+ QX11InfoData* getX11Data(bool def = false) const;
+
+ QX11InfoData *x11data;
+
+ friend class QX11PaintEngine;
+ friend class QPixmap;
+ friend class QX11PlatformPixmap;
+ friend class QWidget;
+ friend class QWidgetPrivate;
+ friend class QGLWidget;
+ friend void qt_init(QApplicationPrivate *priv, int, Display *display, Qt::HANDLE visual,
+ Qt::HANDLE colormap);
+ friend void qt_cleanup();
+ friend void qt_x11_getX11InfoForWindow(QX11Info * xinfo, const QX11WindowAttributes &a);
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QX11INFO_X11_H
diff --git a/src/widgets/platforms/x11/qximinputcontext_p.h b/src/widgets/platforms/x11/qximinputcontext_p.h
new file mode 100644
index 0000000000..47c6f78ff9
--- /dev/null
+++ b/src/widgets/platforms/x11/qximinputcontext_p.h
@@ -0,0 +1,142 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/****************************************************************************
+**
+** Definition of QXIMInputContext class
+**
+** Copyright (C) 2003-2004 immodule for Qt Project. All rights reserved.
+**
+** This file is written to contribute to Nokia Corporation and/or its subsidiary(-ies) under their own
+** license. You may use this file under your Qt license. Following
+** description is copied from their original file headers. Contact
+** immodule-qt@freedesktop.org if any conditions of this licensing are
+** not clear to you.
+**
+****************************************************************************/
+
+#ifndef QXIMINPUTCONTEXT_P_H
+#define QXIMINPUTCONTEXT_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#if !defined(Q_NO_IM)
+
+#include "QtCore/qglobal.h"
+#include "QtWidgets/qinputcontext.h"
+#include "QtGui/qfont.h"
+#include "QtCore/qhash.h"
+#ifdef Q_WS_X11
+#include "QtCore/qlist.h"
+#include "QtCore/qbitarray.h"
+#include "QtGui/qwindowdefs.h"
+#include "private/qt_x11_p.h"
+#endif
+
+QT_BEGIN_NAMESPACE
+
+class QKeyEvent;
+class QWidget;
+class QFont;
+class QString;
+
+class QXIMInputContext : public QInputContext
+{
+ Q_OBJECT
+public:
+ struct ICData {
+ XIC ic;
+ XFontSet fontset;
+ QWidget *widget;
+ QString text;
+ QBitArray selectedChars;
+ bool composing;
+ bool preeditEmpty;
+ void clear();
+ };
+
+ QXIMInputContext();
+ ~QXIMInputContext();
+
+ QString identifierName();
+ QString language();
+
+ void reset();
+
+ void mouseHandler( int x, QMouseEvent *event);
+ bool isComposing() const;
+
+ void setFocusWidget( QWidget *w );
+ void widgetDestroyed(QWidget *w);
+
+ void create_xim();
+ void close_xim();
+
+ void update();
+
+ ICData *icData() const;
+protected:
+ bool x11FilterEvent( QWidget *keywidget, XEvent *event );
+
+private:
+ static XIMStyle xim_style;
+
+ QString _language;
+ XIM xim;
+ QHash<WId, ICData *> ximData;
+
+ ICData *createICData(QWidget *w);
+};
+
+QT_END_NAMESPACE
+
+#endif // Q_NO_IM
+
+#endif // QXIMINPUTCONTEXT_P_H
diff --git a/src/gui/inputmethod/qximinputcontext_x11.cpp b/src/widgets/platforms/x11/qximinputcontext_x11.cpp
index de1212c556..de1212c556 100644
--- a/src/gui/inputmethod/qximinputcontext_x11.cpp
+++ b/src/widgets/platforms/x11/qximinputcontext_x11.cpp
diff --git a/src/gui/s60framework/qs60mainapplication.cpp b/src/widgets/s60framework/qs60mainapplication.cpp
index 9217ba80be..9217ba80be 100644
--- a/src/gui/s60framework/qs60mainapplication.cpp
+++ b/src/widgets/s60framework/qs60mainapplication.cpp
diff --git a/src/widgets/s60framework/qs60mainapplication.h b/src/widgets/s60framework/qs60mainapplication.h
new file mode 100644
index 0000000000..2e06181b86
--- /dev/null
+++ b/src/widgets/s60framework/qs60mainapplication.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Symbian application wrapper of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QS60MAINAPPLICATION_H
+#define QS60MAINAPPLICATION_H
+
+#include <QtCore/qglobal.h>
+
+#ifdef Q_OS_SYMBIAN
+
+#ifdef Q_WS_S60
+#include <aknapp.h>
+typedef CAknApplication QS60MainApplicationBase;
+#else
+#include <eikapp.h>
+typedef CEikApplication QS60MainApplicationBase;
+#endif
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class Q_WIDGETS_EXPORT QS60MainApplication : public QS60MainApplicationBase
+{
+public:
+ QS60MainApplication();
+ // The virtuals are for qdoc.
+ virtual ~QS60MainApplication();
+
+ virtual TUid AppDllUid() const;
+
+ virtual TFileName ResourceFileName() const;
+
+public:
+
+ virtual void PreDocConstructL();
+
+ virtual CDictionaryStore *OpenIniFileLC(RFs &aFs) const;
+
+ virtual void NewAppServerL(CApaAppServer *&aAppServer);
+
+protected:
+
+ virtual CApaDocument *CreateDocumentL();
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // Q_OS_SYMBIAN
+
+#endif // QS60MAINAPPLICATION_H
diff --git a/src/gui/s60framework/qs60mainapplication_p.h b/src/widgets/s60framework/qs60mainapplication_p.h
index 3568f6d475..3568f6d475 100644
--- a/src/gui/s60framework/qs60mainapplication_p.h
+++ b/src/widgets/s60framework/qs60mainapplication_p.h
diff --git a/src/widgets/s60framework/qs60mainappui.cpp b/src/widgets/s60framework/qs60mainappui.cpp
new file mode 100644
index 0000000000..05e538e65a
--- /dev/null
+++ b/src/widgets/s60framework/qs60mainappui.cpp
@@ -0,0 +1,430 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Symbian application wrapper of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// INCLUDE FILES
+#include <exception>
+#include <qglobal.h>
+#ifdef Q_WS_S60
+#include <avkon.hrh>
+#include <eikmenub.h>
+#include <eikmenup.h>
+#include <avkon.rsg>
+#endif
+#include <barsread.h>
+#include <coeutils.h>
+#include <qconfig.h>
+
+#include "qs60mainappui.h"
+#include <QtWidgets/qapplication.h>
+#include <QtWidgets/qsymbianevent.h>
+#include <QtWidgets/qmenu.h>
+#include <private/qmenu_p.h>
+#include <private/qt_s60_p.h>
+#include <qdebug.h>
+
+//Animated wallpapers in Qt applications are not supported.
+const TInt KAknDisableAnimationBackground = 0x02000000;
+const TInt KAknSingleClickCompatible = 0x01000000;
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QS60MainAppUi
+ \since 4.6
+ \brief The QS60MainAppUi class is a helper class for S60 migration.
+
+ \warning This class is provided only to get access to S60 specific
+ functionality in the application framework classes. It is not
+ portable. We strongly recommend against using it in new applications.
+
+ The QS60MainAppUi provides a helper class for use in migrating from
+ existing S60 based applications to Qt based applications. It is used
+ in the exact same way as the \c CAknAppUi class from Symbian, but
+ internally provides extensions used by Qt.
+
+ When modifying old S60 applications that rely on implementing
+ functions in \c CAknAppUi, the class should be modified to inherit
+ from this class instead of \c CAknAppUi. Then the application can
+ choose to override only certain functions.
+
+ For more information on \c CAknAppUi, please see the S60
+ documentation.
+
+ Unlike other Qt classes, QS60MainAppUi behaves like an S60 class,
+ and can throw Symbian leaves.
+
+ \sa QS60MainDocument, QS60MainApplication
+ */
+
+/*!
+ * \brief Second phase Symbian constructor.
+ *
+ * Constructs all the elements of the class that can cause a leave to happen.
+ *
+ * If you override this function, you should call the base class implementation as well.
+ */
+void QS60MainAppUi::ConstructL()
+{
+ // Cone's heap and handle checks on app destruction are not suitable for Qt apps, as many
+ // objects can still exist in static data at that point. Instead we will print relevant information
+ // so that comparative checks may be made for memory leaks, using ~SPrintExitInfo in corelib.
+ iEikonEnv->DisableExitChecks(ETrue);
+
+ // Initialise app UI with standard value.
+ // ENoAppResourceFile and ENonStandardResourceFile makes UI to work without
+ // resource files in most SDKs. S60 3rd FP1 public seems to require resource file
+ // even these flags are defined
+ TInt flags = CEikAppUi::ENoScreenFurniture
+ | CEikAppUi::ENonStandardResourceFile;
+#ifdef Q_WS_S60
+ flags |= CAknAppUi::EAknEnableSkin;
+ // After 5th Edition S60, native side supports animated wallpapers.
+ // However, there is no support for that feature on Qt side, so indicate to
+ // native UI framework that this application will not support background animations.
+
+ // Also, add support for single touch for post 5th edition platforms.
+ // This has only impact when launching native dialogs/menus from inside QApplication.
+ if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0) {
+ flags |= (KAknDisableAnimationBackground | KAknSingleClickCompatible);
+ }
+#endif
+ BaseConstructL(flags);
+}
+
+/*!
+ * \brief Contructs an instance of QS60MainAppUi.
+ */
+QS60MainAppUi::QS60MainAppUi()
+{
+ // No implementation required
+}
+
+/*!
+ * \brief Destroys the QS60MainAppUi.
+ */
+QS60MainAppUi::~QS60MainAppUi()
+{
+}
+
+/*!
+ * \brief Handles commands produced by the S60 framework.
+ *
+ * \a command holds the ID of the command to handle, and is S60 specific.
+ *
+ * If you override this function, you should call the base class implementation if you do not
+ * handle the command.
+ */
+void QS60MainAppUi::HandleCommandL(TInt command)
+{
+ if (qApp) {
+ QSymbianEvent event(QSymbianEvent::CommandEvent, command);
+ QT_TRYCATCH_LEAVING(qApp->symbianProcessEvent(&event));
+ }
+}
+
+/*!
+ * \brief Handles a resource change in the S60 framework.
+ *
+ * Resource changes include layout switches. \a type holds the type of resource change that
+ * occurred.
+ *
+ * If you override this function, you should call the base class implementation if you do not
+ * handle the resource change.
+ */
+void QS60MainAppUi::HandleResourceChangeL(TInt type)
+{
+ QS60MainAppUiBase::HandleResourceChangeL(type);
+
+ if (qApp) {
+ QSymbianEvent event(QSymbianEvent::ResourceChangeEvent, type);
+ QT_TRYCATCH_LEAVING(qApp->symbianProcessEvent(&event));
+ }
+}
+
+/*!
+ * \brief Handles raw window server events.
+ *
+ * The event type and information is passed in \a wsEvent, while the receiving control is passed in
+ * \a destination.
+ *
+ * If you override this function, you should call the base class implementation if you do not
+ * handle the event.
+ */
+void QS60MainAppUi::HandleWsEventL(const TWsEvent &wsEvent, CCoeControl *destination)
+{
+ int result = 0;
+ if (qApp) {
+ QSymbianEvent event(&wsEvent);
+ QT_TRYCATCH_LEAVING(
+ result = qApp->symbianProcessEvent(&event)
+ );
+ }
+
+ if (result <= 0)
+ QS60MainAppUiBase::HandleWsEventL(wsEvent, destination);
+}
+
+
+/*!
+ * \brief Handles changes to the status pane size.
+ *
+ * Called by the framework when the application status pane size is changed.
+ *
+ * If you override this function, you should call the base class implementation if you do not
+ * handle the size change.
+ */
+void QS60MainAppUi::HandleStatusPaneSizeChange()
+{
+ TRAP_IGNORE(HandleResourceChangeL(KInternalStatusPaneChange));
+ HandleStackedControlsResourceChange(KInternalStatusPaneChange);
+}
+
+/*!
+ * \brief Dynamically initializes a menu bar.
+ *
+ * The resource associated with the menu is given in \a resourceId, and the actual menu bar is
+ * passed in \a menuBar.
+ *
+ * If you override this function, you should call the base class implementation as well.
+ */
+void QS60MainAppUi::DynInitMenuBarL(TInt /* resourceId */, CEikMenuBar * /* menuBar */)
+{
+}
+
+/*!
+ * \brief Dynamically initializes a menu pane.
+ *
+ * The resource associated with the menu is given in \a resourceId, and the actual menu pane is
+ * passed in \a menuPane.
+ *
+ * If you override this function, you should call the base class implementation as well.
+ */
+void QS60MainAppUi::DynInitMenuPaneL(TInt resourceId, CEikMenuPane *menuPane)
+{
+#ifdef Q_WS_S60
+ if (resourceId == R_AVKON_MENUPANE_EMPTY) {
+ if (menuPane->NumberOfItemsInPane() <= 1)
+ QT_TRYCATCH_LEAVING(qt_symbian_show_toplevel(menuPane));
+
+ } else if (resourceId != R_AVKON_MENUPANE_FEP_DEFAULT
+ && resourceId != R_AVKON_MENUPANE_EDITTEXT_DEFAULT
+ && resourceId != R_AVKON_MENUPANE_LANGUAGE_DEFAULT) {
+ QT_TRYCATCH_LEAVING(qt_symbian_show_submenu(menuPane, resourceId));
+ }
+#else
+ QS60MainAppUiBase::DynInitMenuPaneL(resourceId, menuPane);
+#endif
+}
+
+/*!
+ * \brief Restores a menu window.
+ *
+ * The menu window to restore is given in \a menuWindow. The resource ID and type of menu is given
+ * in \a resourceId and \a menuType, respectively.
+ *
+ * If you override this function, you should call the base class implementation as well.
+ */
+void QS60MainAppUi::RestoreMenuL(CCoeControl *menuWindow, TInt resourceId, TMenuType menuType)
+{
+#ifdef Q_WS_S60
+ if (resourceId >= QT_SYMBIAN_FIRST_MENU_ITEM && resourceId <= QT_SYMBIAN_LAST_MENU_ITEM) {
+ if (menuType == EMenuPane)
+ DynInitMenuPaneL(resourceId, (CEikMenuPane*)menuWindow);
+ else
+ DynInitMenuBarL(resourceId, (CEikMenuBar*)menuWindow);
+ } else if(resourceId == R_AVKON_MENUPANE_EMPTY) {
+ CEikMenuBarTitle *title = new(ELeave) CEikMenuBarTitle;
+ CleanupStack::PushL(title);
+
+ title->iData.iMenuPaneResourceId = R_AVKON_MENUPANE_EMPTY;
+ title->iTitleFlags = 0;
+
+ S60->menuBar()->TitleArray()->AddTitleL(title);
+ CleanupStack::Pop( title );
+ }
+ else
+#endif
+ {
+ QS60MainAppUiBase::RestoreMenuL(menuWindow, resourceId, menuType);
+ }
+}
+
+/*!
+ \internal
+*/
+void QS60MainAppUi::Exit()
+{
+ QS60MainAppUiBase::Exit();
+}
+
+/*!
+ \internal
+*/
+void QS60MainAppUi::SetFadedL(TBool aFaded)
+{
+ QS60MainAppUiBase::SetFadedL(aFaded);
+}
+
+/*!
+ \internal
+*/
+TRect QS60MainAppUi::ApplicationRect() const
+{
+ return QS60MainAppUiBase::ApplicationRect();
+}
+
+/*!
+ \internal
+*/
+void QS60MainAppUi::HandleScreenDeviceChangedL()
+{
+ QS60MainAppUiBase::HandleScreenDeviceChangedL();
+}
+
+/*!
+ \internal
+*/
+void QS60MainAppUi::HandleApplicationSpecificEventL(TInt aType, const TWsEvent &aEvent)
+{
+ QS60MainAppUiBase::HandleApplicationSpecificEventL(aType, aEvent);
+}
+
+/*!
+ \internal
+*/
+TTypeUid::Ptr QS60MainAppUi::MopSupplyObject(TTypeUid aId)
+{
+ return QS60MainAppUiBase::MopSupplyObject(aId);
+}
+
+/*!
+ \internal
+*/
+void QS60MainAppUi::ProcessCommandL(TInt aCommand)
+{
+ QS60MainAppUiBase::ProcessCommandL(aCommand);
+}
+
+/*!
+ \internal
+*/
+TErrorHandlerResponse QS60MainAppUi::HandleError (TInt aError, const SExtendedError &aExtErr, TDes &aErrorText, TDes &aContextText)
+{
+ return QS60MainAppUiBase::HandleError(aError, aExtErr, aErrorText, aContextText);
+}
+
+/*!
+ \internal
+*/
+void QS60MainAppUi::HandleViewDeactivation(const TVwsViewId &aViewIdToBeDeactivated, const TVwsViewId &aNewlyActivatedViewId)
+{
+ QS60MainAppUiBase::HandleViewDeactivation(aViewIdToBeDeactivated, aNewlyActivatedViewId);
+}
+
+/*!
+ \internal
+*/
+void QS60MainAppUi::PrepareToExit()
+{
+ QS60MainAppUiBase::PrepareToExit();
+}
+
+/*!
+ \internal
+*/
+void QS60MainAppUi::HandleTouchPaneSizeChange()
+{
+ QS60MainAppUiBase::HandleTouchPaneSizeChange();
+}
+
+/*!
+ \internal
+*/
+void QS60MainAppUi::HandleSystemEventL(const TWsEvent &aEvent)
+{
+ QS60MainAppUiBase::HandleSystemEventL(aEvent);
+}
+
+/*!
+ \internal
+*/
+void QS60MainAppUi::Reserved_MtsmPosition()
+{
+ QS60MainAppUiBase::Reserved_MtsmPosition();
+}
+
+/*!
+ \internal
+*/
+void QS60MainAppUi::Reserved_MtsmObject()
+{
+ QS60MainAppUiBase::Reserved_MtsmObject();
+}
+
+/*!
+ \internal
+*/
+void QS60MainAppUi::HandleForegroundEventL(TBool aForeground)
+{
+ QS60MainAppUiBase::HandleForegroundEventL(aForeground);
+}
+
+/*!
+ \internal
+*/
+TBool QS60MainAppUi::ProcessCommandParametersL(TApaCommand /*aCommand*/, TFileName &/*aDocumentName*/, const TDesC8 &/*aTail*/)
+{
+ // bypass CEikAppUi::ProcessCommandParametersL(..) which modifies aDocumentName, preventing apparc document opening from working.
+ // The return value is effectively unused in Qt apps (see QS60MainDocument::OpenFileL)
+ return EFalse;
+}
+
+#ifndef Q_WS_S60
+
+void QS60StubAknAppUi::HandleViewDeactivation(const TVwsViewId &, const TVwsViewId &) {}
+void QS60StubAknAppUi::HandleTouchPaneSizeChange() {}
+void QS60StubAknAppUi::HandleStatusPaneSizeChange() {}
+void QS60StubAknAppUi::Reserved_MtsmPosition() {}
+void QS60StubAknAppUi::Reserved_MtsmObject() {}
+
+#endif
+
+QT_END_NAMESPACE
diff --git a/src/widgets/s60framework/qs60mainappui.h b/src/widgets/s60framework/qs60mainappui.h
new file mode 100644
index 0000000000..7d5a265a2a
--- /dev/null
+++ b/src/widgets/s60framework/qs60mainappui.h
@@ -0,0 +1,152 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Symbian application wrapper of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QS60MAINAPPUI_H
+#define QS60MAINAPPUI_H
+
+#include <QtCore/qglobal.h>
+
+#ifdef Q_OS_SYMBIAN
+
+#ifdef Q_WS_S60
+#include <aknappui.h>
+typedef CAknAppUi QS60MainAppUiBase;
+#else
+#include <eikappui.h>
+// these stub classes simulate the structure of CAknAppUi, to help binary compatibility between Qt configured with and without S60/Avkon
+class QS60StubAknAppUiBase : public CEikAppUi
+{
+private:
+ int qS60StubAknAppUiBaseSpace[4];
+};
+
+class QS60StubMEikStatusPaneObserver
+{
+public:
+ virtual void HandleStatusPaneSizeChange() = 0;
+};
+
+class QS60StubMAknTouchPaneObserver
+{
+public:
+ virtual void HandleTouchPaneSizeChange() = 0;
+};
+
+class QS60StubAknAppUi : public QS60StubAknAppUiBase, QS60StubMEikStatusPaneObserver,
+ public MCoeViewDeactivationObserver,
+ public QS60StubMAknTouchPaneObserver
+{
+public: // MCoeViewDeactivationObserver
+ virtual void HandleViewDeactivation(const TVwsViewId&, const TVwsViewId &);
+
+public: // from MAknTouchPaneObserver
+ virtual void HandleTouchPaneSizeChange();
+
+protected: // from MEikStatusPaneObserver
+ virtual void HandleStatusPaneSizeChange();
+
+protected: // from CAknAppUi
+ virtual void Reserved_MtsmPosition();
+ virtual void Reserved_MtsmObject();
+
+private:
+ int qS60StubAknAppUiSpace[4];
+};
+
+typedef QS60StubAknAppUi QS60MainAppUiBase;
+#endif
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class Q_WIDGETS_EXPORT QS60MainAppUi : public QS60MainAppUiBase
+{
+public:
+ QS60MainAppUi();
+ // The virtuals are for qdoc.
+ virtual ~QS60MainAppUi();
+
+ virtual void ConstructL();
+
+ virtual void RestoreMenuL(CCoeControl *menuWindow,TInt resourceId,TMenuType menuType);
+ virtual void DynInitMenuBarL(TInt resourceId, CEikMenuBar *menuBar);
+ virtual void DynInitMenuPaneL(TInt resourceId, CEikMenuPane *menuPane);
+
+ virtual void HandleCommandL( TInt command );
+
+ virtual void HandleResourceChangeL(TInt type);
+
+ virtual void HandleStatusPaneSizeChange();
+
+protected:
+ virtual void HandleWsEventL(const TWsEvent &event, CCoeControl *destination);
+
+public:
+ virtual void Exit();
+ virtual void SetFadedL(TBool aFaded);
+ virtual TRect ApplicationRect() const;
+ virtual void ProcessCommandL(TInt aCommand);
+ virtual TErrorHandlerResponse HandleError (TInt aError, const SExtendedError &aExtErr, TDes &aErrorText, TDes &aContextText);
+ virtual void HandleViewDeactivation(const TVwsViewId &aViewIdToBeDeactivated, const TVwsViewId &aNewlyActivatedViewId);
+ virtual void PrepareToExit();
+ virtual void HandleTouchPaneSizeChange();
+ virtual TBool ProcessCommandParametersL(TApaCommand aCommand, TFileName &aDocumentName, const TDesC8 &aTail);
+
+protected:
+ virtual void HandleScreenDeviceChangedL();
+ virtual void HandleApplicationSpecificEventL(TInt aType, const TWsEvent &aEvent);
+ virtual TTypeUid::Ptr MopSupplyObject(TTypeUid aId);
+ virtual void HandleSystemEventL(const TWsEvent &aEvent);
+ virtual void Reserved_MtsmPosition();
+ virtual void Reserved_MtsmObject();
+ virtual void HandleForegroundEventL(TBool aForeground);
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // Q_OS_SYMBIAN
+
+#endif // QS60MAINAPPUI_H
diff --git a/src/gui/s60framework/qs60maindocument.cpp b/src/widgets/s60framework/qs60maindocument.cpp
index eb1d87c9dc..eb1d87c9dc 100644
--- a/src/gui/s60framework/qs60maindocument.cpp
+++ b/src/widgets/s60framework/qs60maindocument.cpp
diff --git a/src/widgets/s60framework/qs60maindocument.h b/src/widgets/s60framework/qs60maindocument.h
new file mode 100644
index 0000000000..6a8e9a52f7
--- /dev/null
+++ b/src/widgets/s60framework/qs60maindocument.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Symbian application wrapper of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QS60MAINDOCUMENT_H
+#define QS60MAINDOCUMENT_H
+
+#include <QtCore/qglobal.h>
+
+#ifdef Q_OS_SYMBIAN
+
+#ifdef Q_WS_S60
+#include <AknDoc.h>
+typedef CAknDocument QS60MainDocumentBase;
+#else
+#include <eikdoc.h>
+typedef CEikDocument QS60MainDocumentBase;
+#endif
+
+class CEikApplication;
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QS60MainAppUi;
+
+class Q_WIDGETS_EXPORT QS60MainDocument : public QS60MainDocumentBase
+{
+public:
+
+ QS60MainDocument(CEikApplication &mainApplication);
+ // The virtuals are for qdoc.
+ virtual ~QS60MainDocument();
+
+public:
+
+ virtual CEikAppUi *CreateAppUiL();
+
+public:
+
+ virtual CFileStore *OpenFileL(TBool aDoOpen, const TDesC &aFilename, RFs &aFs);
+
+ virtual void OpenFileL(CFileStore *&aFileStore, RFile &aFile);
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // Q_OS_SYMBIAN
+
+#endif // QS60MAINDOCUMENT_H
diff --git a/src/gui/s60framework/s60framework.pri b/src/widgets/s60framework/s60framework.pri
index 19525b7fdb..19525b7fdb 100644
--- a/src/gui/s60framework/s60framework.pri
+++ b/src/widgets/s60framework/s60framework.pri
diff --git a/src/gui/s60framework/s60main.rss b/src/widgets/s60framework/s60main.rss
index 799dc09794..799dc09794 100644
--- a/src/gui/s60framework/s60main.rss
+++ b/src/widgets/s60framework/s60main.rss
diff --git a/src/gui/statemachine/qbasickeyeventtransition.cpp b/src/widgets/statemachine/qbasickeyeventtransition.cpp
index 615e642a7e..615e642a7e 100644
--- a/src/gui/statemachine/qbasickeyeventtransition.cpp
+++ b/src/widgets/statemachine/qbasickeyeventtransition.cpp
diff --git a/src/gui/statemachine/qbasickeyeventtransition_p.h b/src/widgets/statemachine/qbasickeyeventtransition_p.h
index 6a51260155..6a51260155 100644
--- a/src/gui/statemachine/qbasickeyeventtransition_p.h
+++ b/src/widgets/statemachine/qbasickeyeventtransition_p.h
diff --git a/src/gui/statemachine/qbasicmouseeventtransition.cpp b/src/widgets/statemachine/qbasicmouseeventtransition.cpp
index 0edf430af6..0edf430af6 100644
--- a/src/gui/statemachine/qbasicmouseeventtransition.cpp
+++ b/src/widgets/statemachine/qbasicmouseeventtransition.cpp
diff --git a/src/gui/statemachine/qbasicmouseeventtransition_p.h b/src/widgets/statemachine/qbasicmouseeventtransition_p.h
index 3a608cb0af..3a608cb0af 100644
--- a/src/gui/statemachine/qbasicmouseeventtransition_p.h
+++ b/src/widgets/statemachine/qbasicmouseeventtransition_p.h
diff --git a/src/widgets/statemachine/qguistatemachine.cpp b/src/widgets/statemachine/qguistatemachine.cpp
new file mode 100644
index 0000000000..7a498eb77f
--- /dev/null
+++ b/src/widgets/statemachine/qguistatemachine.cpp
@@ -0,0 +1,494 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qstatemachine.h>
+
+#ifndef QT_NO_STATEMACHINE
+
+#include <private/qstatemachine_p.h>
+#include <QtGui/qevent.h>
+#include <QtWidgets/qgraphicssceneevent.h>
+
+QT_BEGIN_NAMESPACE
+
+Q_CORE_EXPORT const QStateMachinePrivate::Handler *qcoreStateMachineHandler();
+
+static QEvent *cloneEvent(QEvent *e)
+{
+ switch (e->type()) {
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseButtonDblClick:
+ case QEvent::MouseMove:
+ return new QMouseEvent(*static_cast<QMouseEvent*>(e));
+ case QEvent::KeyPress:
+ case QEvent::KeyRelease:
+ return new QKeyEvent(*static_cast<QKeyEvent*>(e));
+ case QEvent::FocusIn:
+ case QEvent::FocusOut:
+ return new QFocusEvent(*static_cast<QFocusEvent*>(e));
+ case QEvent::Enter:
+ return new QEvent(*e);
+ case QEvent::Leave:
+ return new QEvent(*e);
+ break;
+ case QEvent::Paint:
+ Q_ASSERT_X(false, "cloneEvent()", "not implemented");
+ break;
+ case QEvent::Move:
+ return new QMoveEvent(*static_cast<QMoveEvent*>(e));
+ case QEvent::Resize:
+ return new QResizeEvent(*static_cast<QResizeEvent*>(e));
+ case QEvent::Create:
+ Q_ASSERT_X(false, "cloneEvent()", "not implemented");
+ break;
+ case QEvent::Destroy:
+ Q_ASSERT_X(false, "cloneEvent()", "not implemented");
+ break;
+ case QEvent::Show:
+ return new QShowEvent(*static_cast<QShowEvent*>(e));
+ case QEvent::Hide:
+ return new QHideEvent(*static_cast<QHideEvent*>(e));
+ case QEvent::Close:
+ return new QCloseEvent(*static_cast<QCloseEvent*>(e));
+ case QEvent::Quit:
+ return new QEvent(*e);
+ case QEvent::ParentChange:
+ return new QEvent(*e);
+ case QEvent::ParentAboutToChange:
+ return new QEvent(*e);
+ case QEvent::ThreadChange:
+ return new QEvent(*e);
+
+ case QEvent::WindowActivate:
+ case QEvent::WindowDeactivate:
+ return new QEvent(*e);
+
+ case QEvent::ShowToParent:
+ return new QEvent(*e);
+ case QEvent::HideToParent:
+ return new QEvent(*e);
+#ifndef QT_NO_WHEELEVENT
+ case QEvent::Wheel:
+ return new QWheelEvent(*static_cast<QWheelEvent*>(e));
+#endif //QT_NO_WHEELEVENT
+ case QEvent::WindowTitleChange:
+ return new QEvent(*e);
+ case QEvent::WindowIconChange:
+ return new QEvent(*e);
+ case QEvent::ApplicationWindowIconChange:
+ return new QEvent(*e);
+ case QEvent::ApplicationFontChange:
+ return new QEvent(*e);
+ case QEvent::ApplicationLayoutDirectionChange:
+ return new QEvent(*e);
+ case QEvent::ApplicationPaletteChange:
+ return new QEvent(*e);
+ case QEvent::PaletteChange:
+ return new QEvent(*e);
+ case QEvent::Clipboard:
+ Q_ASSERT_X(false, "cloneEvent()", "not implemented");
+ break;
+ case QEvent::Speech:
+ Q_ASSERT_X(false, "cloneEvent()", "not implemented");
+ break;
+ case QEvent::MetaCall:
+ Q_ASSERT_X(false, "cloneEvent()", "not implemented");
+ break;
+ case QEvent::SockAct:
+ return new QEvent(*e);
+ case QEvent::WinEventAct:
+ return new QEvent(*e);
+ case QEvent::DeferredDelete:
+ return new QEvent(*e);
+#ifndef QT_NO_DRAGANDDROP
+ case QEvent::DragEnter:
+ return new QDragEnterEvent(*static_cast<QDragEnterEvent*>(e));
+ case QEvent::DragMove:
+ return new QDragMoveEvent(*static_cast<QDragMoveEvent*>(e));
+ case QEvent::DragLeave:
+ return new QDragLeaveEvent(*static_cast<QDragLeaveEvent*>(e));
+ case QEvent::Drop:
+ return new QDropEvent(*static_cast<QDragMoveEvent*>(e));
+#endif
+ case QEvent::ChildAdded:
+ return new QChildEvent(*static_cast<QChildEvent*>(e));
+ case QEvent::ChildPolished:
+ return new QChildEvent(*static_cast<QChildEvent*>(e));
+ case QEvent::ChildRemoved:
+ return new QChildEvent(*static_cast<QChildEvent*>(e));
+ case QEvent::ShowWindowRequest:
+ return new QEvent(*e);
+ case QEvent::PolishRequest:
+ return new QEvent(*e);
+ case QEvent::Polish:
+ return new QEvent(*e);
+ case QEvent::LayoutRequest:
+ return new QEvent(*e);
+ case QEvent::UpdateRequest:
+ return new QEvent(*e);
+ case QEvent::UpdateLater:
+ return new QEvent(*e);
+
+ case QEvent::EmbeddingControl:
+ return new QEvent(*e);
+ case QEvent::ActivateControl:
+ return new QEvent(*e);
+ case QEvent::DeactivateControl:
+ return new QEvent(*e);
+
+#ifndef QT_NO_CONTEXTMENU
+ case QEvent::ContextMenu:
+ return new QContextMenuEvent(*static_cast<QContextMenuEvent*>(e));
+#endif
+ case QEvent::InputMethod:
+ return new QInputMethodEvent(*static_cast<QInputMethodEvent*>(e));
+ case QEvent::AccessibilityPrepare:
+ return new QEvent(*e);
+#ifndef QT_NO_TABLETEVENT
+ case QEvent::TabletMove:
+ return new QTabletEvent(*static_cast<QTabletEvent*>(e));
+#endif //QT_NO_TABLETEVENT
+ case QEvent::LocaleChange:
+ return new QEvent(*e);
+ case QEvent::LanguageChange:
+ return new QEvent(*e);
+ case QEvent::LayoutDirectionChange:
+ return new QEvent(*e);
+ case QEvent::Style:
+ return new QEvent(*e);
+#ifndef QT_NO_TABLETEVENT
+ case QEvent::TabletPress:
+ return new QTabletEvent(*static_cast<QTabletEvent*>(e));
+ case QEvent::TabletRelease:
+ return new QTabletEvent(*static_cast<QTabletEvent*>(e));
+#endif //QT_NO_TABLETEVENT
+ case QEvent::OkRequest:
+ return new QEvent(*e);
+ case QEvent::HelpRequest:
+ return new QEvent(*e);
+
+ case QEvent::IconDrag:
+ return new QIconDragEvent(*static_cast<QIconDragEvent*>(e));
+
+ case QEvent::FontChange:
+ return new QEvent(*e);
+ case QEvent::EnabledChange:
+ return new QEvent(*e);
+ case QEvent::ActivationChange:
+ return new QEvent(*e);
+ case QEvent::StyleChange:
+ return new QEvent(*e);
+ case QEvent::IconTextChange:
+ return new QEvent(*e);
+ case QEvent::ModifiedChange:
+ return new QEvent(*e);
+ case QEvent::MouseTrackingChange:
+ return new QEvent(*e);
+
+ case QEvent::WindowBlocked:
+ return new QEvent(*e);
+ case QEvent::WindowUnblocked:
+ return new QEvent(*e);
+ case QEvent::WindowStateChange:
+ return new QWindowStateChangeEvent(*static_cast<QWindowStateChangeEvent*>(e));
+
+ case QEvent::ToolTip:
+ return new QHelpEvent(*static_cast<QHelpEvent*>(e));
+ case QEvent::WhatsThis:
+ return new QHelpEvent(*static_cast<QHelpEvent*>(e));
+#ifndef QT_NO_STATUSTIP
+ case QEvent::StatusTip:
+ return new QStatusTipEvent(*static_cast<QStatusTipEvent*>(e));
+#endif //QT_NO_STATUSTIP
+#ifndef QT_NO_ACTION
+ case QEvent::ActionChanged:
+ case QEvent::ActionAdded:
+ case QEvent::ActionRemoved:
+ return new QActionEvent(*static_cast<QActionEvent*>(e));
+#endif
+ case QEvent::FileOpen:
+ return new QFileOpenEvent(*static_cast<QFileOpenEvent*>(e));
+
+#ifndef QT_NO_SHORTCUT
+ case QEvent::Shortcut:
+ return new QShortcutEvent(*static_cast<QShortcutEvent*>(e));
+#endif //QT_NO_SHORTCUT
+ case QEvent::ShortcutOverride:
+ return new QKeyEvent(*static_cast<QKeyEvent*>(e));
+
+#ifndef QT_NO_WHATSTHIS
+ case QEvent::WhatsThisClicked:
+ return new QWhatsThisClickedEvent(*static_cast<QWhatsThisClickedEvent*>(e));
+#endif //QT_NO_WHATSTHIS
+
+#ifndef QT_NO_TOOLBAR
+ case QEvent::ToolBarChange:
+ return new QToolBarChangeEvent(*static_cast<QToolBarChangeEvent*>(e));
+#endif //QT_NO_TOOLBAR
+
+ case QEvent::ApplicationActivate:
+ return new QEvent(*e);
+ case QEvent::ApplicationDeactivate:
+ return new QEvent(*e);
+
+ case QEvent::QueryWhatsThis:
+ return new QHelpEvent(*static_cast<QHelpEvent*>(e));
+ case QEvent::EnterWhatsThisMode:
+ return new QEvent(*e);
+ case QEvent::LeaveWhatsThisMode:
+ return new QEvent(*e);
+
+ case QEvent::ZOrderChange:
+ return new QEvent(*e);
+
+ case QEvent::HoverEnter:
+ case QEvent::HoverLeave:
+ case QEvent::HoverMove:
+ return new QHoverEvent(*static_cast<QHoverEvent*>(e));
+
+ case QEvent::AccessibilityHelp:
+ Q_ASSERT_X(false, "cloneEvent()", "not implemented");
+ break;
+ case QEvent::AccessibilityDescription:
+ Q_ASSERT_X(false, "cloneEvent()", "not implemented");
+ break;
+
+#ifdef QT_KEYPAD_NAVIGATION
+ case QEvent::EnterEditFocus:
+ return new QEvent(*e);
+ case QEvent::LeaveEditFocus:
+ return new QEvent(*e);
+#endif
+ case QEvent::AcceptDropsChange:
+ return new QEvent(*e);
+
+ case QEvent::ZeroTimerEvent:
+ Q_ASSERT_X(false, "cloneEvent()", "not implemented");
+ break;
+#ifndef QT_NO_GRAPHICSVIEW
+ case QEvent::GraphicsSceneMouseMove:
+ case QEvent::GraphicsSceneMousePress:
+ case QEvent::GraphicsSceneMouseRelease:
+ case QEvent::GraphicsSceneMouseDoubleClick: {
+ QGraphicsSceneMouseEvent *me = static_cast<QGraphicsSceneMouseEvent*>(e);
+ QGraphicsSceneMouseEvent *me2 = new QGraphicsSceneMouseEvent(me->type());
+ me2->setWidget(me->widget());
+ me2->setPos(me->pos());
+ me2->setScenePos(me->scenePos());
+ me2->setScreenPos(me->screenPos());
+// ### for all buttons
+ me2->setButtonDownPos(Qt::LeftButton, me->buttonDownPos(Qt::LeftButton));
+ me2->setButtonDownPos(Qt::RightButton, me->buttonDownPos(Qt::RightButton));
+ me2->setButtonDownScreenPos(Qt::LeftButton, me->buttonDownScreenPos(Qt::LeftButton));
+ me2->setButtonDownScreenPos(Qt::RightButton, me->buttonDownScreenPos(Qt::RightButton));
+ me2->setLastPos(me->lastPos());
+ me2->setLastScenePos(me->lastScenePos());
+ me2->setLastScreenPos(me->lastScreenPos());
+ me2->setButtons(me->buttons());
+ me2->setButton(me->button());
+ me2->setModifiers(me->modifiers());
+ return me2;
+ }
+
+ case QEvent::GraphicsSceneContextMenu: {
+ QGraphicsSceneContextMenuEvent *me = static_cast<QGraphicsSceneContextMenuEvent*>(e);
+ QGraphicsSceneContextMenuEvent *me2 = new QGraphicsSceneContextMenuEvent(me->type());
+ me2->setWidget(me->widget());
+ me2->setPos(me->pos());
+ me2->setScenePos(me->scenePos());
+ me2->setScreenPos(me->screenPos());
+ me2->setModifiers(me->modifiers());
+ me2->setReason(me->reason());
+ return me2;
+ }
+
+ case QEvent::GraphicsSceneHoverEnter:
+ case QEvent::GraphicsSceneHoverMove:
+ case QEvent::GraphicsSceneHoverLeave: {
+ QGraphicsSceneHoverEvent *he = static_cast<QGraphicsSceneHoverEvent*>(e);
+ QGraphicsSceneHoverEvent *he2 = new QGraphicsSceneHoverEvent(he->type());
+ he2->setPos(he->pos());
+ he2->setScenePos(he->scenePos());
+ he2->setScreenPos(he->screenPos());
+ he2->setLastPos(he->lastPos());
+ he2->setLastScenePos(he->lastScenePos());
+ he2->setLastScreenPos(he->lastScreenPos());
+ he2->setModifiers(he->modifiers());
+ return he2;
+ }
+ case QEvent::GraphicsSceneHelp:
+ return new QHelpEvent(*static_cast<QHelpEvent*>(e));
+ case QEvent::GraphicsSceneDragEnter:
+ case QEvent::GraphicsSceneDragMove:
+ case QEvent::GraphicsSceneDragLeave:
+ case QEvent::GraphicsSceneDrop: {
+ QGraphicsSceneDragDropEvent *dde = static_cast<QGraphicsSceneDragDropEvent*>(e);
+ QGraphicsSceneDragDropEvent *dde2 = new QGraphicsSceneDragDropEvent(dde->type());
+ dde2->setPos(dde->pos());
+ dde2->setScenePos(dde->scenePos());
+ dde2->setScreenPos(dde->screenPos());
+ dde2->setButtons(dde->buttons());
+ dde2->setModifiers(dde->modifiers());
+ return dde2;
+ }
+ case QEvent::GraphicsSceneWheel: {
+ QGraphicsSceneWheelEvent *we = static_cast<QGraphicsSceneWheelEvent*>(e);
+ QGraphicsSceneWheelEvent *we2 = new QGraphicsSceneWheelEvent(we->type());
+ we2->setPos(we->pos());
+ we2->setScenePos(we->scenePos());
+ we2->setScreenPos(we->screenPos());
+ we2->setButtons(we->buttons());
+ we2->setModifiers(we->modifiers());
+ we2->setOrientation(we->orientation());
+ we2->setDelta(we->delta());
+ return we2;
+ }
+#endif
+ case QEvent::KeyboardLayoutChange:
+ return new QEvent(*e);
+
+ case QEvent::DynamicPropertyChange:
+ return new QDynamicPropertyChangeEvent(*static_cast<QDynamicPropertyChangeEvent*>(e));
+
+#ifndef QT_NO_TABLETEVENT
+ case QEvent::TabletEnterProximity:
+ case QEvent::TabletLeaveProximity:
+ return new QTabletEvent(*static_cast<QTabletEvent*>(e));
+#endif //QT_NO_TABLETEVENT
+
+ case QEvent::NonClientAreaMouseMove:
+ case QEvent::NonClientAreaMouseButtonPress:
+ case QEvent::NonClientAreaMouseButtonRelease:
+ case QEvent::NonClientAreaMouseButtonDblClick:
+ return new QMouseEvent(*static_cast<QMouseEvent*>(e));
+
+ case QEvent::MacSizeChange:
+ return new QEvent(*e);
+
+ case QEvent::ContentsRectChange:
+ return new QEvent(*e);
+
+ case QEvent::MacGLWindowChange:
+ return new QEvent(*e);
+
+ case QEvent::FutureCallOut:
+ Q_ASSERT_X(false, "cloneEvent()", "not implemented");
+ break;
+#ifndef QT_NO_GRAPHICSVIEW
+ case QEvent::GraphicsSceneResize: {
+ QGraphicsSceneResizeEvent *re = static_cast<QGraphicsSceneResizeEvent*>(e);
+ QGraphicsSceneResizeEvent *re2 = new QGraphicsSceneResizeEvent();
+ re2->setOldSize(re->oldSize());
+ re2->setNewSize(re->newSize());
+ return re2;
+ }
+ case QEvent::GraphicsSceneMove: {
+ QGraphicsSceneMoveEvent *me = static_cast<QGraphicsSceneMoveEvent*>(e);
+ QGraphicsSceneMoveEvent *me2 = new QGraphicsSceneMoveEvent();
+ me2->setWidget(me->widget());
+ me2->setNewPos(me->newPos());
+ me2->setOldPos(me->oldPos());
+ return me2;
+ }
+#endif
+ case QEvent::CursorChange:
+ return new QEvent(*e);
+ case QEvent::ToolTipChange:
+ return new QEvent(*e);
+
+ case QEvent::NetworkReplyUpdated:
+ Q_ASSERT_X(false, "cloneEvent()", "not implemented");
+ break;
+
+ case QEvent::GrabMouse:
+ case QEvent::UngrabMouse:
+ case QEvent::GrabKeyboard:
+ case QEvent::UngrabKeyboard:
+ return new QEvent(*e);
+
+ case QEvent::TouchBegin:
+ case QEvent::TouchUpdate:
+ case QEvent::TouchEnd:
+ return new QTouchEvent(*static_cast<QTouchEvent*>(e));
+
+#ifndef QT_NO_GESTURES
+ case QEvent::NativeGesture:
+ Q_ASSERT_X(false, "cloneEvent()", "not implemented");
+ break;
+#endif
+
+ case QEvent::UpdateSoftKeys:
+ return new QEvent(*e);
+
+ case QEvent::User:
+ case QEvent::MaxUser:
+ Q_ASSERT_X(false, "cloneEvent()", "not implemented");
+ break;
+ default:
+ ;
+ }
+ return qcoreStateMachineHandler()->cloneEvent(e);
+}
+
+const QStateMachinePrivate::Handler qt_gui_statemachine_handler = {
+ cloneEvent
+};
+
+static const QStateMachinePrivate::Handler *qt_guistatemachine_last_handler = 0;
+int qRegisterGuiStateMachine()
+{
+ qt_guistatemachine_last_handler = QStateMachinePrivate::handler;
+ QStateMachinePrivate::handler = &qt_gui_statemachine_handler;
+ return 1;
+}
+Q_CONSTRUCTOR_FUNCTION(qRegisterGuiStateMachine)
+
+int qUnregisterGuiStateMachine()
+{
+ QStateMachinePrivate::handler = qt_guistatemachine_last_handler;
+ return 1;
+}
+Q_DESTRUCTOR_FUNCTION(qUnregisterGuiStateMachine)
+
+QT_END_NAMESPACE
+
+#endif //QT_NO_STATEMACHINE
diff --git a/src/gui/statemachine/qkeyeventtransition.cpp b/src/widgets/statemachine/qkeyeventtransition.cpp
index 3a4292628e..3a4292628e 100644
--- a/src/gui/statemachine/qkeyeventtransition.cpp
+++ b/src/widgets/statemachine/qkeyeventtransition.cpp
diff --git a/src/widgets/statemachine/qkeyeventtransition.h b/src/widgets/statemachine/qkeyeventtransition.h
new file mode 100644
index 0000000000..7862bd41d7
--- /dev/null
+++ b/src/widgets/statemachine/qkeyeventtransition.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QKEYEVENTTRANSITION_H
+#define QKEYEVENTTRANSITION_H
+
+#include <QtCore/qeventtransition.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_STATEMACHINE
+
+class QKeyEventTransitionPrivate;
+class Q_WIDGETS_EXPORT QKeyEventTransition : public QEventTransition
+{
+ Q_OBJECT
+ Q_PROPERTY(int key READ key WRITE setKey)
+ Q_PROPERTY(Qt::KeyboardModifiers modifierMask READ modifierMask WRITE setModifierMask)
+public:
+ QKeyEventTransition(QState *sourceState = 0);
+ QKeyEventTransition(QObject *object, QEvent::Type type, int key,
+ QState *sourceState = 0);
+ ~QKeyEventTransition();
+
+ int key() const;
+ void setKey(int key);
+
+ Qt::KeyboardModifiers modifierMask() const;
+ void setModifierMask(Qt::KeyboardModifiers modifiers);
+
+protected:
+ void onTransition(QEvent *event);
+ bool eventTest(QEvent *event);
+
+private:
+ Q_DISABLE_COPY(QKeyEventTransition)
+ Q_DECLARE_PRIVATE(QKeyEventTransition)
+};
+
+#endif //QT_NO_STATEMACHINE
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/gui/statemachine/qmouseeventtransition.cpp b/src/widgets/statemachine/qmouseeventtransition.cpp
index 9440a25f37..9440a25f37 100644
--- a/src/gui/statemachine/qmouseeventtransition.cpp
+++ b/src/widgets/statemachine/qmouseeventtransition.cpp
diff --git a/src/widgets/statemachine/qmouseeventtransition.h b/src/widgets/statemachine/qmouseeventtransition.h
new file mode 100644
index 0000000000..7255a968ac
--- /dev/null
+++ b/src/widgets/statemachine/qmouseeventtransition.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMOUSEEVENTTRANSITION_H
+#define QMOUSEEVENTTRANSITION_H
+
+#include <QtCore/qeventtransition.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_STATEMACHINE
+
+class QMouseEventTransitionPrivate;
+class QPainterPath;
+class Q_WIDGETS_EXPORT QMouseEventTransition : public QEventTransition
+{
+ Q_OBJECT
+ Q_PROPERTY(Qt::MouseButton button READ button WRITE setButton)
+ Q_PROPERTY(Qt::KeyboardModifiers modifierMask READ modifierMask WRITE setModifierMask)
+public:
+ QMouseEventTransition(QState *sourceState = 0);
+ QMouseEventTransition(QObject *object, QEvent::Type type,
+ Qt::MouseButton button, QState *sourceState = 0);
+ ~QMouseEventTransition();
+
+ Qt::MouseButton button() const;
+ void setButton(Qt::MouseButton button);
+
+ Qt::KeyboardModifiers modifierMask() const;
+ void setModifierMask(Qt::KeyboardModifiers modifiers);
+
+ QPainterPath hitTestPath() const;
+ void setHitTestPath(const QPainterPath &path);
+
+protected:
+ void onTransition(QEvent *event);
+ bool eventTest(QEvent *event);
+
+private:
+ Q_DISABLE_COPY(QMouseEventTransition)
+ Q_DECLARE_PRIVATE(QMouseEventTransition)
+};
+
+#endif //QT_NO_STATEMACHINE
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/gui/statemachine/statemachine.pri b/src/widgets/statemachine/statemachine.pri
index 2eb1e05be6..2eb1e05be6 100644
--- a/src/gui/statemachine/statemachine.pri
+++ b/src/widgets/statemachine/statemachine.pri
diff --git a/src/gui/styles/images/cdr-128.png b/src/widgets/styles/images/cdr-128.png
index c5daa15fc8..c5daa15fc8 100644
--- a/src/gui/styles/images/cdr-128.png
+++ b/src/widgets/styles/images/cdr-128.png
Binary files differ
diff --git a/src/gui/styles/images/cdr-16.png b/src/widgets/styles/images/cdr-16.png
index 82d7533bd1..82d7533bd1 100644
--- a/src/gui/styles/images/cdr-16.png
+++ b/src/widgets/styles/images/cdr-16.png
Binary files differ
diff --git a/src/gui/styles/images/cdr-32.png b/src/widgets/styles/images/cdr-32.png
index dcfb085da5..dcfb085da5 100644
--- a/src/gui/styles/images/cdr-32.png
+++ b/src/widgets/styles/images/cdr-32.png
Binary files differ
diff --git a/src/gui/styles/images/closedock-16.png b/src/widgets/styles/images/closedock-16.png
index ab9d669eee..ab9d669eee 100644
--- a/src/gui/styles/images/closedock-16.png
+++ b/src/widgets/styles/images/closedock-16.png
Binary files differ
diff --git a/src/gui/styles/images/closedock-down-16.png b/src/widgets/styles/images/closedock-down-16.png
index c1791dd2cc..c1791dd2cc 100644
--- a/src/gui/styles/images/closedock-down-16.png
+++ b/src/widgets/styles/images/closedock-down-16.png
Binary files differ
diff --git a/src/gui/styles/images/computer-16.png b/src/widgets/styles/images/computer-16.png
index 43fb0bb581..43fb0bb581 100644
--- a/src/gui/styles/images/computer-16.png
+++ b/src/widgets/styles/images/computer-16.png
Binary files differ
diff --git a/src/gui/styles/images/computer-32.png b/src/widgets/styles/images/computer-32.png
index 6d750ce89b..6d750ce89b 100644
--- a/src/gui/styles/images/computer-32.png
+++ b/src/widgets/styles/images/computer-32.png
Binary files differ
diff --git a/src/gui/styles/images/defaults60theme.blob b/src/widgets/styles/images/defaults60theme.blob
index f3a59528d6..f3a59528d6 100644
--- a/src/gui/styles/images/defaults60theme.blob
+++ b/src/widgets/styles/images/defaults60theme.blob
Binary files differ
diff --git a/src/gui/styles/images/desktop-16.png b/src/widgets/styles/images/desktop-16.png
index d612dfb0fc..d612dfb0fc 100644
--- a/src/gui/styles/images/desktop-16.png
+++ b/src/widgets/styles/images/desktop-16.png
Binary files differ
diff --git a/src/gui/styles/images/desktop-32.png b/src/widgets/styles/images/desktop-32.png
index ad85b48d3a..ad85b48d3a 100644
--- a/src/gui/styles/images/desktop-32.png
+++ b/src/widgets/styles/images/desktop-32.png
Binary files differ
diff --git a/src/gui/styles/images/dirclosed-128.png b/src/widgets/styles/images/dirclosed-128.png
index e4fa843162..e4fa843162 100644
--- a/src/gui/styles/images/dirclosed-128.png
+++ b/src/widgets/styles/images/dirclosed-128.png
Binary files differ
diff --git a/src/gui/styles/images/dirclosed-16.png b/src/widgets/styles/images/dirclosed-16.png
index 333fe8eaac..333fe8eaac 100644
--- a/src/gui/styles/images/dirclosed-16.png
+++ b/src/widgets/styles/images/dirclosed-16.png
Binary files differ
diff --git a/src/gui/styles/images/dirclosed-32.png b/src/widgets/styles/images/dirclosed-32.png
index 3add907ed5..3add907ed5 100644
--- a/src/gui/styles/images/dirclosed-32.png
+++ b/src/widgets/styles/images/dirclosed-32.png
Binary files differ
diff --git a/src/gui/styles/images/dirlink-128.png b/src/widgets/styles/images/dirlink-128.png
index ec299f8e52..ec299f8e52 100644
--- a/src/gui/styles/images/dirlink-128.png
+++ b/src/widgets/styles/images/dirlink-128.png
Binary files differ
diff --git a/src/gui/styles/images/dirlink-16.png b/src/widgets/styles/images/dirlink-16.png
index 9f16cd3520..9f16cd3520 100644
--- a/src/gui/styles/images/dirlink-16.png
+++ b/src/widgets/styles/images/dirlink-16.png
Binary files differ
diff --git a/src/gui/styles/images/dirlink-32.png b/src/widgets/styles/images/dirlink-32.png
index 776536d131..776536d131 100644
--- a/src/gui/styles/images/dirlink-32.png
+++ b/src/widgets/styles/images/dirlink-32.png
Binary files differ
diff --git a/src/gui/styles/images/diropen-128.png b/src/widgets/styles/images/diropen-128.png
index b91c4af72a..b91c4af72a 100644
--- a/src/gui/styles/images/diropen-128.png
+++ b/src/widgets/styles/images/diropen-128.png
Binary files differ
diff --git a/src/gui/styles/images/diropen-16.png b/src/widgets/styles/images/diropen-16.png
index 95f0771d06..95f0771d06 100644
--- a/src/gui/styles/images/diropen-16.png
+++ b/src/widgets/styles/images/diropen-16.png
Binary files differ
diff --git a/src/gui/styles/images/diropen-32.png b/src/widgets/styles/images/diropen-32.png
index af5f7e7e81..af5f7e7e81 100644
--- a/src/gui/styles/images/diropen-32.png
+++ b/src/widgets/styles/images/diropen-32.png
Binary files differ
diff --git a/src/gui/styles/images/dockdock-16.png b/src/widgets/styles/images/dockdock-16.png
index 4ac9483176..4ac9483176 100644
--- a/src/gui/styles/images/dockdock-16.png
+++ b/src/widgets/styles/images/dockdock-16.png
Binary files differ
diff --git a/src/gui/styles/images/dockdock-down-16.png b/src/widgets/styles/images/dockdock-down-16.png
index 2e85a679be..2e85a679be 100644
--- a/src/gui/styles/images/dockdock-down-16.png
+++ b/src/widgets/styles/images/dockdock-down-16.png
Binary files differ
diff --git a/src/gui/styles/images/down-128.png b/src/widgets/styles/images/down-128.png
index 09dfe43a93..09dfe43a93 100644
--- a/src/gui/styles/images/down-128.png
+++ b/src/widgets/styles/images/down-128.png
Binary files differ
diff --git a/src/gui/styles/images/down-16.png b/src/widgets/styles/images/down-16.png
index c60a174e25..c60a174e25 100644
--- a/src/gui/styles/images/down-16.png
+++ b/src/widgets/styles/images/down-16.png
Binary files differ
diff --git a/src/gui/styles/images/down-32.png b/src/widgets/styles/images/down-32.png
index 46eadb8e12..46eadb8e12 100644
--- a/src/gui/styles/images/down-32.png
+++ b/src/widgets/styles/images/down-32.png
Binary files differ
diff --git a/src/gui/styles/images/dvd-128.png b/src/widgets/styles/images/dvd-128.png
index 9ed9dc1e55..9ed9dc1e55 100644
--- a/src/gui/styles/images/dvd-128.png
+++ b/src/widgets/styles/images/dvd-128.png
Binary files differ
diff --git a/src/gui/styles/images/dvd-16.png b/src/widgets/styles/images/dvd-16.png
index 623386d4ca..623386d4ca 100644
--- a/src/gui/styles/images/dvd-16.png
+++ b/src/widgets/styles/images/dvd-16.png
Binary files differ
diff --git a/src/gui/styles/images/dvd-32.png b/src/widgets/styles/images/dvd-32.png
index 089b72accb..089b72accb 100644
--- a/src/gui/styles/images/dvd-32.png
+++ b/src/widgets/styles/images/dvd-32.png
Binary files differ
diff --git a/src/gui/styles/images/file-128.png b/src/widgets/styles/images/file-128.png
index 46e6ceb49a..46e6ceb49a 100644
--- a/src/gui/styles/images/file-128.png
+++ b/src/widgets/styles/images/file-128.png
Binary files differ
diff --git a/src/gui/styles/images/file-16.png b/src/widgets/styles/images/file-16.png
index 664b56356b..664b56356b 100644
--- a/src/gui/styles/images/file-16.png
+++ b/src/widgets/styles/images/file-16.png
Binary files differ
diff --git a/src/gui/styles/images/file-32.png b/src/widgets/styles/images/file-32.png
index 83e5c3d311..83e5c3d311 100644
--- a/src/gui/styles/images/file-32.png
+++ b/src/widgets/styles/images/file-32.png
Binary files differ
diff --git a/src/gui/styles/images/filecontents-128.png b/src/widgets/styles/images/filecontents-128.png
index 50e0a838e2..50e0a838e2 100644
--- a/src/gui/styles/images/filecontents-128.png
+++ b/src/widgets/styles/images/filecontents-128.png
Binary files differ
diff --git a/src/gui/styles/images/filecontents-16.png b/src/widgets/styles/images/filecontents-16.png
index b9399ccf2e..b9399ccf2e 100644
--- a/src/gui/styles/images/filecontents-16.png
+++ b/src/widgets/styles/images/filecontents-16.png
Binary files differ
diff --git a/src/gui/styles/images/filecontents-32.png b/src/widgets/styles/images/filecontents-32.png
index 3761f70690..3761f70690 100644
--- a/src/gui/styles/images/filecontents-32.png
+++ b/src/widgets/styles/images/filecontents-32.png
Binary files differ
diff --git a/src/gui/styles/images/fileinfo-128.png b/src/widgets/styles/images/fileinfo-128.png
index 8c5b331876..8c5b331876 100644
--- a/src/gui/styles/images/fileinfo-128.png
+++ b/src/widgets/styles/images/fileinfo-128.png
Binary files differ
diff --git a/src/gui/styles/images/fileinfo-16.png b/src/widgets/styles/images/fileinfo-16.png
index 729be4d5f2..729be4d5f2 100644
--- a/src/gui/styles/images/fileinfo-16.png
+++ b/src/widgets/styles/images/fileinfo-16.png
Binary files differ
diff --git a/src/gui/styles/images/fileinfo-32.png b/src/widgets/styles/images/fileinfo-32.png
index ca795aa49b..ca795aa49b 100644
--- a/src/gui/styles/images/fileinfo-32.png
+++ b/src/widgets/styles/images/fileinfo-32.png
Binary files differ
diff --git a/src/gui/styles/images/filelink-128.png b/src/widgets/styles/images/filelink-128.png
index be86a82901..be86a82901 100644
--- a/src/gui/styles/images/filelink-128.png
+++ b/src/widgets/styles/images/filelink-128.png
Binary files differ
diff --git a/src/gui/styles/images/filelink-16.png b/src/widgets/styles/images/filelink-16.png
index 6643f2c428..6643f2c428 100644
--- a/src/gui/styles/images/filelink-16.png
+++ b/src/widgets/styles/images/filelink-16.png
Binary files differ
diff --git a/src/gui/styles/images/filelink-32.png b/src/widgets/styles/images/filelink-32.png
index 1e46fdc13c..1e46fdc13c 100644
--- a/src/gui/styles/images/filelink-32.png
+++ b/src/widgets/styles/images/filelink-32.png
Binary files differ
diff --git a/src/gui/styles/images/floppy-128.png b/src/widgets/styles/images/floppy-128.png
index fa7a3e1334..fa7a3e1334 100644
--- a/src/gui/styles/images/floppy-128.png
+++ b/src/widgets/styles/images/floppy-128.png
Binary files differ
diff --git a/src/gui/styles/images/floppy-16.png b/src/widgets/styles/images/floppy-16.png
index 91c59c567d..91c59c567d 100644
--- a/src/gui/styles/images/floppy-16.png
+++ b/src/widgets/styles/images/floppy-16.png
Binary files differ
diff --git a/src/gui/styles/images/floppy-32.png b/src/widgets/styles/images/floppy-32.png
index e63b3213bf..e63b3213bf 100644
--- a/src/gui/styles/images/floppy-32.png
+++ b/src/widgets/styles/images/floppy-32.png
Binary files differ
diff --git a/src/gui/styles/images/fontbitmap-16.png b/src/widgets/styles/images/fontbitmap-16.png
index 03efc9cbab..03efc9cbab 100644
--- a/src/gui/styles/images/fontbitmap-16.png
+++ b/src/widgets/styles/images/fontbitmap-16.png
Binary files differ
diff --git a/src/gui/styles/images/fonttruetype-16.png b/src/widgets/styles/images/fonttruetype-16.png
index 25205021e9..25205021e9 100644
--- a/src/gui/styles/images/fonttruetype-16.png
+++ b/src/widgets/styles/images/fonttruetype-16.png
Binary files differ
diff --git a/src/gui/styles/images/harddrive-128.png b/src/widgets/styles/images/harddrive-128.png
index 0b73d9de1e..0b73d9de1e 100644
--- a/src/gui/styles/images/harddrive-128.png
+++ b/src/widgets/styles/images/harddrive-128.png
Binary files differ
diff --git a/src/gui/styles/images/harddrive-16.png b/src/widgets/styles/images/harddrive-16.png
index 45d592baa3..45d592baa3 100644
--- a/src/gui/styles/images/harddrive-16.png
+++ b/src/widgets/styles/images/harddrive-16.png
Binary files differ
diff --git a/src/gui/styles/images/harddrive-32.png b/src/widgets/styles/images/harddrive-32.png
index 7041452b68..7041452b68 100644
--- a/src/gui/styles/images/harddrive-32.png
+++ b/src/widgets/styles/images/harddrive-32.png
Binary files differ
diff --git a/src/gui/styles/images/left-128.png b/src/widgets/styles/images/left-128.png
index a26a5195f8..a26a5195f8 100644
--- a/src/gui/styles/images/left-128.png
+++ b/src/widgets/styles/images/left-128.png
Binary files differ
diff --git a/src/gui/styles/images/left-16.png b/src/widgets/styles/images/left-16.png
index 110dd90f2d..110dd90f2d 100644
--- a/src/gui/styles/images/left-16.png
+++ b/src/widgets/styles/images/left-16.png
Binary files differ
diff --git a/src/gui/styles/images/left-32.png b/src/widgets/styles/images/left-32.png
index ec4107b372..ec4107b372 100644
--- a/src/gui/styles/images/left-32.png
+++ b/src/widgets/styles/images/left-32.png
Binary files differ
diff --git a/src/gui/styles/images/media-pause-16.png b/src/widgets/styles/images/media-pause-16.png
index 6cb1fd7f63..6cb1fd7f63 100644
--- a/src/gui/styles/images/media-pause-16.png
+++ b/src/widgets/styles/images/media-pause-16.png
Binary files differ
diff --git a/src/gui/styles/images/media-pause-32.png b/src/widgets/styles/images/media-pause-32.png
index 3f172a04d6..3f172a04d6 100644
--- a/src/gui/styles/images/media-pause-32.png
+++ b/src/widgets/styles/images/media-pause-32.png
Binary files differ
diff --git a/src/gui/styles/images/media-play-16.png b/src/widgets/styles/images/media-play-16.png
index d7ee3ccbe3..d7ee3ccbe3 100644
--- a/src/gui/styles/images/media-play-16.png
+++ b/src/widgets/styles/images/media-play-16.png
Binary files differ
diff --git a/src/gui/styles/images/media-play-32.png b/src/widgets/styles/images/media-play-32.png
index af8d2f7ba5..af8d2f7ba5 100644
--- a/src/gui/styles/images/media-play-32.png
+++ b/src/widgets/styles/images/media-play-32.png
Binary files differ
diff --git a/src/gui/styles/images/media-seek-backward-16.png b/src/widgets/styles/images/media-seek-backward-16.png
index b8a8ea42d1..b8a8ea42d1 100644
--- a/src/gui/styles/images/media-seek-backward-16.png
+++ b/src/widgets/styles/images/media-seek-backward-16.png
Binary files differ
diff --git a/src/gui/styles/images/media-seek-backward-32.png b/src/widgets/styles/images/media-seek-backward-32.png
index a21d1372fe..a21d1372fe 100644
--- a/src/gui/styles/images/media-seek-backward-32.png
+++ b/src/widgets/styles/images/media-seek-backward-32.png
Binary files differ
diff --git a/src/gui/styles/images/media-seek-forward-16.png b/src/widgets/styles/images/media-seek-forward-16.png
index 3c900dcb62..3c900dcb62 100644
--- a/src/gui/styles/images/media-seek-forward-16.png
+++ b/src/widgets/styles/images/media-seek-forward-16.png
Binary files differ
diff --git a/src/gui/styles/images/media-seek-forward-32.png b/src/widgets/styles/images/media-seek-forward-32.png
index 4f8d370fa1..4f8d370fa1 100644
--- a/src/gui/styles/images/media-seek-forward-32.png
+++ b/src/widgets/styles/images/media-seek-forward-32.png
Binary files differ
diff --git a/src/gui/styles/images/media-skip-backward-16.png b/src/widgets/styles/images/media-skip-backward-16.png
index f5b3f4f56d..f5b3f4f56d 100644
--- a/src/gui/styles/images/media-skip-backward-16.png
+++ b/src/widgets/styles/images/media-skip-backward-16.png
Binary files differ
diff --git a/src/gui/styles/images/media-skip-backward-32.png b/src/widgets/styles/images/media-skip-backward-32.png
index 1d338035ef..1d338035ef 100644
--- a/src/gui/styles/images/media-skip-backward-32.png
+++ b/src/widgets/styles/images/media-skip-backward-32.png
Binary files differ
diff --git a/src/gui/styles/images/media-skip-forward-16.png b/src/widgets/styles/images/media-skip-forward-16.png
index 27e205b02f..27e205b02f 100644
--- a/src/gui/styles/images/media-skip-forward-16.png
+++ b/src/widgets/styles/images/media-skip-forward-16.png
Binary files differ
diff --git a/src/gui/styles/images/media-skip-forward-32.png b/src/widgets/styles/images/media-skip-forward-32.png
index a583fa1b11..a583fa1b11 100644
--- a/src/gui/styles/images/media-skip-forward-32.png
+++ b/src/widgets/styles/images/media-skip-forward-32.png
Binary files differ
diff --git a/src/gui/styles/images/media-stop-16.png b/src/widgets/styles/images/media-stop-16.png
index 9ce035d696..9ce035d696 100644
--- a/src/gui/styles/images/media-stop-16.png
+++ b/src/widgets/styles/images/media-stop-16.png
Binary files differ
diff --git a/src/gui/styles/images/media-stop-32.png b/src/widgets/styles/images/media-stop-32.png
index aae24ba925..aae24ba925 100644
--- a/src/gui/styles/images/media-stop-32.png
+++ b/src/widgets/styles/images/media-stop-32.png
Binary files differ
diff --git a/src/gui/styles/images/media-volume-16.png b/src/widgets/styles/images/media-volume-16.png
index ad258340f2..ad258340f2 100644
--- a/src/gui/styles/images/media-volume-16.png
+++ b/src/widgets/styles/images/media-volume-16.png
Binary files differ
diff --git a/src/gui/styles/images/media-volume-muted-16.png b/src/widgets/styles/images/media-volume-muted-16.png
index 06bded21e7..06bded21e7 100644
--- a/src/gui/styles/images/media-volume-muted-16.png
+++ b/src/widgets/styles/images/media-volume-muted-16.png
Binary files differ
diff --git a/src/gui/styles/images/networkdrive-128.png b/src/widgets/styles/images/networkdrive-128.png
index fd4a59c6bd..fd4a59c6bd 100644
--- a/src/gui/styles/images/networkdrive-128.png
+++ b/src/widgets/styles/images/networkdrive-128.png
Binary files differ
diff --git a/src/gui/styles/images/networkdrive-16.png b/src/widgets/styles/images/networkdrive-16.png
index 1bc62f766a..1bc62f766a 100644
--- a/src/gui/styles/images/networkdrive-16.png
+++ b/src/widgets/styles/images/networkdrive-16.png
Binary files differ
diff --git a/src/gui/styles/images/networkdrive-32.png b/src/widgets/styles/images/networkdrive-32.png
index 6a389dcae4..6a389dcae4 100644
--- a/src/gui/styles/images/networkdrive-32.png
+++ b/src/widgets/styles/images/networkdrive-32.png
Binary files differ
diff --git a/src/gui/styles/images/newdirectory-128.png b/src/widgets/styles/images/newdirectory-128.png
index fdbee27688..fdbee27688 100644
--- a/src/gui/styles/images/newdirectory-128.png
+++ b/src/widgets/styles/images/newdirectory-128.png
Binary files differ
diff --git a/src/gui/styles/images/newdirectory-16.png b/src/widgets/styles/images/newdirectory-16.png
index 6c9f80318b..6c9f80318b 100644
--- a/src/gui/styles/images/newdirectory-16.png
+++ b/src/widgets/styles/images/newdirectory-16.png
Binary files differ
diff --git a/src/gui/styles/images/newdirectory-32.png b/src/widgets/styles/images/newdirectory-32.png
index 4fd0329216..4fd0329216 100644
--- a/src/gui/styles/images/newdirectory-32.png
+++ b/src/widgets/styles/images/newdirectory-32.png
Binary files differ
diff --git a/src/gui/styles/images/parentdir-128.png b/src/widgets/styles/images/parentdir-128.png
index 84d14ab079..84d14ab079 100644
--- a/src/gui/styles/images/parentdir-128.png
+++ b/src/widgets/styles/images/parentdir-128.png
Binary files differ
diff --git a/src/gui/styles/images/parentdir-16.png b/src/widgets/styles/images/parentdir-16.png
index 665f8280f2..665f8280f2 100644
--- a/src/gui/styles/images/parentdir-16.png
+++ b/src/widgets/styles/images/parentdir-16.png
Binary files differ
diff --git a/src/gui/styles/images/parentdir-32.png b/src/widgets/styles/images/parentdir-32.png
index 44f3c4876d..44f3c4876d 100644
--- a/src/gui/styles/images/parentdir-32.png
+++ b/src/widgets/styles/images/parentdir-32.png
Binary files differ
diff --git a/src/gui/styles/images/refresh-24.png b/src/widgets/styles/images/refresh-24.png
index 4c9b72c489..4c9b72c489 100644
--- a/src/gui/styles/images/refresh-24.png
+++ b/src/widgets/styles/images/refresh-24.png
Binary files differ
diff --git a/src/gui/styles/images/refresh-32.png b/src/widgets/styles/images/refresh-32.png
index eecde4b8f9..eecde4b8f9 100644
--- a/src/gui/styles/images/refresh-32.png
+++ b/src/widgets/styles/images/refresh-32.png
Binary files differ
diff --git a/src/gui/styles/images/right-128.png b/src/widgets/styles/images/right-128.png
index 14b1cfd8eb..14b1cfd8eb 100644
--- a/src/gui/styles/images/right-128.png
+++ b/src/widgets/styles/images/right-128.png
Binary files differ
diff --git a/src/gui/styles/images/right-16.png b/src/widgets/styles/images/right-16.png
index 81ca628ff6..81ca628ff6 100644
--- a/src/gui/styles/images/right-16.png
+++ b/src/widgets/styles/images/right-16.png
Binary files differ
diff --git a/src/gui/styles/images/right-32.png b/src/widgets/styles/images/right-32.png
index 0f6ba8608b..0f6ba8608b 100644
--- a/src/gui/styles/images/right-32.png
+++ b/src/widgets/styles/images/right-32.png
Binary files differ
diff --git a/src/gui/styles/images/standardbutton-apply-128.png b/src/widgets/styles/images/standardbutton-apply-128.png
index 85f07a57ef..85f07a57ef 100644
--- a/src/gui/styles/images/standardbutton-apply-128.png
+++ b/src/widgets/styles/images/standardbutton-apply-128.png
Binary files differ
diff --git a/src/gui/styles/images/standardbutton-apply-16.png b/src/widgets/styles/images/standardbutton-apply-16.png
index 8f11ce6504..8f11ce6504 100644
--- a/src/gui/styles/images/standardbutton-apply-16.png
+++ b/src/widgets/styles/images/standardbutton-apply-16.png
Binary files differ
diff --git a/src/gui/styles/images/standardbutton-apply-32.png b/src/widgets/styles/images/standardbutton-apply-32.png
index e8f7853a1e..e8f7853a1e 100644
--- a/src/gui/styles/images/standardbutton-apply-32.png
+++ b/src/widgets/styles/images/standardbutton-apply-32.png
Binary files differ
diff --git a/src/gui/styles/images/standardbutton-cancel-128.png b/src/widgets/styles/images/standardbutton-cancel-128.png
index 16d857030f..16d857030f 100644
--- a/src/gui/styles/images/standardbutton-cancel-128.png
+++ b/src/widgets/styles/images/standardbutton-cancel-128.png
Binary files differ
diff --git a/src/gui/styles/images/standardbutton-cancel-16.png b/src/widgets/styles/images/standardbutton-cancel-16.png
index 7bd25bd7c7..7bd25bd7c7 100644
--- a/src/gui/styles/images/standardbutton-cancel-16.png
+++ b/src/widgets/styles/images/standardbutton-cancel-16.png
Binary files differ
diff --git a/src/gui/styles/images/standardbutton-cancel-32.png b/src/widgets/styles/images/standardbutton-cancel-32.png
index 64a78727a1..64a78727a1 100644
--- a/src/gui/styles/images/standardbutton-cancel-32.png
+++ b/src/widgets/styles/images/standardbutton-cancel-32.png
Binary files differ
diff --git a/src/gui/styles/images/standardbutton-clear-128.png b/src/widgets/styles/images/standardbutton-clear-128.png
index 107aea2234..107aea2234 100644
--- a/src/gui/styles/images/standardbutton-clear-128.png
+++ b/src/widgets/styles/images/standardbutton-clear-128.png
Binary files differ
diff --git a/src/gui/styles/images/standardbutton-clear-16.png b/src/widgets/styles/images/standardbutton-clear-16.png
index 5359134c72..5359134c72 100644
--- a/src/gui/styles/images/standardbutton-clear-16.png
+++ b/src/widgets/styles/images/standardbutton-clear-16.png
Binary files differ
diff --git a/src/gui/styles/images/standardbutton-clear-32.png b/src/widgets/styles/images/standardbutton-clear-32.png
index 8b85d6b7b3..8b85d6b7b3 100644
--- a/src/gui/styles/images/standardbutton-clear-32.png
+++ b/src/widgets/styles/images/standardbutton-clear-32.png
Binary files differ
diff --git a/src/gui/styles/images/standardbutton-close-128.png b/src/widgets/styles/images/standardbutton-close-128.png
index 571aeae2bd..571aeae2bd 100644
--- a/src/gui/styles/images/standardbutton-close-128.png
+++ b/src/widgets/styles/images/standardbutton-close-128.png
Binary files differ
diff --git a/src/gui/styles/images/standardbutton-close-16.png b/src/widgets/styles/images/standardbutton-close-16.png
index e9e481987a..e9e481987a 100644
--- a/src/gui/styles/images/standardbutton-close-16.png
+++ b/src/widgets/styles/images/standardbutton-close-16.png
Binary files differ
diff --git a/src/gui/styles/images/standardbutton-close-32.png b/src/widgets/styles/images/standardbutton-close-32.png
index 47e5733062..47e5733062 100644
--- a/src/gui/styles/images/standardbutton-close-32.png
+++ b/src/widgets/styles/images/standardbutton-close-32.png
Binary files differ
diff --git a/src/gui/styles/images/standardbutton-closetab-16.png b/src/widgets/styles/images/standardbutton-closetab-16.png
index 540694eae3..540694eae3 100644
--- a/src/gui/styles/images/standardbutton-closetab-16.png
+++ b/src/widgets/styles/images/standardbutton-closetab-16.png
Binary files differ
diff --git a/src/gui/styles/images/standardbutton-closetab-down-16.png b/src/widgets/styles/images/standardbutton-closetab-down-16.png
index ccec241652..ccec241652 100644
--- a/src/gui/styles/images/standardbutton-closetab-down-16.png
+++ b/src/widgets/styles/images/standardbutton-closetab-down-16.png
Binary files differ
diff --git a/src/gui/styles/images/standardbutton-closetab-hover-16.png b/src/widgets/styles/images/standardbutton-closetab-hover-16.png
index b22a0ffaf0..b22a0ffaf0 100644
--- a/src/gui/styles/images/standardbutton-closetab-hover-16.png
+++ b/src/widgets/styles/images/standardbutton-closetab-hover-16.png
Binary files differ
diff --git a/src/gui/styles/images/standardbutton-delete-128.png b/src/widgets/styles/images/standardbutton-delete-128.png
index 11947ba681..11947ba681 100644
--- a/src/gui/styles/images/standardbutton-delete-128.png
+++ b/src/widgets/styles/images/standardbutton-delete-128.png
Binary files differ
diff --git a/src/gui/styles/images/standardbutton-delete-16.png b/src/widgets/styles/images/standardbutton-delete-16.png
index 63fe93fe98..63fe93fe98 100644
--- a/src/gui/styles/images/standardbutton-delete-16.png
+++ b/src/widgets/styles/images/standardbutton-delete-16.png
Binary files differ
diff --git a/src/gui/styles/images/standardbutton-delete-32.png b/src/widgets/styles/images/standardbutton-delete-32.png
index 336d965d1c..336d965d1c 100644
--- a/src/gui/styles/images/standardbutton-delete-32.png
+++ b/src/widgets/styles/images/standardbutton-delete-32.png
Binary files differ
diff --git a/src/gui/styles/images/standardbutton-help-128.png b/src/widgets/styles/images/standardbutton-help-128.png
index aa38e6fdfb..aa38e6fdfb 100644
--- a/src/gui/styles/images/standardbutton-help-128.png
+++ b/src/widgets/styles/images/standardbutton-help-128.png
Binary files differ
diff --git a/src/gui/styles/images/standardbutton-help-16.png b/src/widgets/styles/images/standardbutton-help-16.png
index e8299418da..e8299418da 100644
--- a/src/gui/styles/images/standardbutton-help-16.png
+++ b/src/widgets/styles/images/standardbutton-help-16.png
Binary files differ
diff --git a/src/gui/styles/images/standardbutton-help-32.png b/src/widgets/styles/images/standardbutton-help-32.png
index 310056a632..310056a632 100644
--- a/src/gui/styles/images/standardbutton-help-32.png
+++ b/src/widgets/styles/images/standardbutton-help-32.png
Binary files differ
diff --git a/src/gui/styles/images/standardbutton-no-128.png b/src/widgets/styles/images/standardbutton-no-128.png
index 491c048ebd..491c048ebd 100644
--- a/src/gui/styles/images/standardbutton-no-128.png
+++ b/src/widgets/styles/images/standardbutton-no-128.png
Binary files differ
diff --git a/src/gui/styles/images/standardbutton-no-16.png b/src/widgets/styles/images/standardbutton-no-16.png
index 812d3f57dd..812d3f57dd 100644
--- a/src/gui/styles/images/standardbutton-no-16.png
+++ b/src/widgets/styles/images/standardbutton-no-16.png
Binary files differ
diff --git a/src/gui/styles/images/standardbutton-no-32.png b/src/widgets/styles/images/standardbutton-no-32.png
index 9548d59196..9548d59196 100644
--- a/src/gui/styles/images/standardbutton-no-32.png
+++ b/src/widgets/styles/images/standardbutton-no-32.png
Binary files differ
diff --git a/src/gui/styles/images/standardbutton-ok-128.png b/src/widgets/styles/images/standardbutton-ok-128.png
index 63cc5279ae..63cc5279ae 100644
--- a/src/gui/styles/images/standardbutton-ok-128.png
+++ b/src/widgets/styles/images/standardbutton-ok-128.png
Binary files differ
diff --git a/src/gui/styles/images/standardbutton-ok-16.png b/src/widgets/styles/images/standardbutton-ok-16.png
index fb4b4dbf96..fb4b4dbf96 100644
--- a/src/gui/styles/images/standardbutton-ok-16.png
+++ b/src/widgets/styles/images/standardbutton-ok-16.png
Binary files differ
diff --git a/src/gui/styles/images/standardbutton-ok-32.png b/src/widgets/styles/images/standardbutton-ok-32.png
index 2dadd7a690..2dadd7a690 100644
--- a/src/gui/styles/images/standardbutton-ok-32.png
+++ b/src/widgets/styles/images/standardbutton-ok-32.png
Binary files differ
diff --git a/src/gui/styles/images/standardbutton-open-128.png b/src/widgets/styles/images/standardbutton-open-128.png
index 8a052e829d..8a052e829d 100644
--- a/src/gui/styles/images/standardbutton-open-128.png
+++ b/src/widgets/styles/images/standardbutton-open-128.png
Binary files differ
diff --git a/src/gui/styles/images/standardbutton-open-16.png b/src/widgets/styles/images/standardbutton-open-16.png
index 08cdc2b91f..08cdc2b91f 100644
--- a/src/gui/styles/images/standardbutton-open-16.png
+++ b/src/widgets/styles/images/standardbutton-open-16.png
Binary files differ
diff --git a/src/gui/styles/images/standardbutton-open-32.png b/src/widgets/styles/images/standardbutton-open-32.png
index db33c79852..db33c79852 100644
--- a/src/gui/styles/images/standardbutton-open-32.png
+++ b/src/widgets/styles/images/standardbutton-open-32.png
Binary files differ
diff --git a/src/gui/styles/images/standardbutton-save-128.png b/src/widgets/styles/images/standardbutton-save-128.png
index fc6fd7ce1d..fc6fd7ce1d 100644
--- a/src/gui/styles/images/standardbutton-save-128.png
+++ b/src/widgets/styles/images/standardbutton-save-128.png
Binary files differ
diff --git a/src/gui/styles/images/standardbutton-save-16.png b/src/widgets/styles/images/standardbutton-save-16.png
index dd4e228280..dd4e228280 100644
--- a/src/gui/styles/images/standardbutton-save-16.png
+++ b/src/widgets/styles/images/standardbutton-save-16.png
Binary files differ
diff --git a/src/gui/styles/images/standardbutton-save-32.png b/src/widgets/styles/images/standardbutton-save-32.png
index 177678c963..177678c963 100644
--- a/src/gui/styles/images/standardbutton-save-32.png
+++ b/src/widgets/styles/images/standardbutton-save-32.png
Binary files differ
diff --git a/src/gui/styles/images/standardbutton-yes-128.png b/src/widgets/styles/images/standardbutton-yes-128.png
index 79c8296016..79c8296016 100644
--- a/src/gui/styles/images/standardbutton-yes-128.png
+++ b/src/widgets/styles/images/standardbutton-yes-128.png
Binary files differ
diff --git a/src/gui/styles/images/standardbutton-yes-16.png b/src/widgets/styles/images/standardbutton-yes-16.png
index cc16dbbec3..cc16dbbec3 100644
--- a/src/gui/styles/images/standardbutton-yes-16.png
+++ b/src/widgets/styles/images/standardbutton-yes-16.png
Binary files differ
diff --git a/src/gui/styles/images/standardbutton-yes-32.png b/src/widgets/styles/images/standardbutton-yes-32.png
index e3340c6453..e3340c6453 100644
--- a/src/gui/styles/images/standardbutton-yes-32.png
+++ b/src/widgets/styles/images/standardbutton-yes-32.png
Binary files differ
diff --git a/src/gui/styles/images/stop-24.png b/src/widgets/styles/images/stop-24.png
index 99856e9640..99856e9640 100644
--- a/src/gui/styles/images/stop-24.png
+++ b/src/widgets/styles/images/stop-24.png
Binary files differ
diff --git a/src/gui/styles/images/stop-32.png b/src/widgets/styles/images/stop-32.png
index 4f4952bb2a..4f4952bb2a 100644
--- a/src/gui/styles/images/stop-32.png
+++ b/src/widgets/styles/images/stop-32.png
Binary files differ
diff --git a/src/gui/styles/images/trash-128.png b/src/widgets/styles/images/trash-128.png
index 334fe5b6f3..334fe5b6f3 100644
--- a/src/gui/styles/images/trash-128.png
+++ b/src/widgets/styles/images/trash-128.png
Binary files differ
diff --git a/src/gui/styles/images/trash-16.png b/src/widgets/styles/images/trash-16.png
index c471791ee8..c471791ee8 100644
--- a/src/gui/styles/images/trash-16.png
+++ b/src/widgets/styles/images/trash-16.png
Binary files differ
diff --git a/src/gui/styles/images/trash-32.png b/src/widgets/styles/images/trash-32.png
index 68625cf698..68625cf698 100644
--- a/src/gui/styles/images/trash-32.png
+++ b/src/widgets/styles/images/trash-32.png
Binary files differ
diff --git a/src/gui/styles/images/up-128.png b/src/widgets/styles/images/up-128.png
index c10df10677..c10df10677 100644
--- a/src/gui/styles/images/up-128.png
+++ b/src/widgets/styles/images/up-128.png
Binary files differ
diff --git a/src/gui/styles/images/up-16.png b/src/widgets/styles/images/up-16.png
index 33e939db8f..33e939db8f 100644
--- a/src/gui/styles/images/up-16.png
+++ b/src/widgets/styles/images/up-16.png
Binary files differ
diff --git a/src/gui/styles/images/up-32.png b/src/widgets/styles/images/up-32.png
index d7157c9476..d7157c9476 100644
--- a/src/gui/styles/images/up-32.png
+++ b/src/widgets/styles/images/up-32.png
Binary files differ
diff --git a/src/gui/styles/images/viewdetailed-128.png b/src/widgets/styles/images/viewdetailed-128.png
index 363937a857..363937a857 100644
--- a/src/gui/styles/images/viewdetailed-128.png
+++ b/src/widgets/styles/images/viewdetailed-128.png
Binary files differ
diff --git a/src/gui/styles/images/viewdetailed-16.png b/src/widgets/styles/images/viewdetailed-16.png
index 44a14b923a..44a14b923a 100644
--- a/src/gui/styles/images/viewdetailed-16.png
+++ b/src/widgets/styles/images/viewdetailed-16.png
Binary files differ
diff --git a/src/gui/styles/images/viewdetailed-32.png b/src/widgets/styles/images/viewdetailed-32.png
index fac1a3e683..fac1a3e683 100644
--- a/src/gui/styles/images/viewdetailed-32.png
+++ b/src/widgets/styles/images/viewdetailed-32.png
Binary files differ
diff --git a/src/gui/styles/images/viewlist-128.png b/src/widgets/styles/images/viewlist-128.png
index cc301059c1..cc301059c1 100644
--- a/src/gui/styles/images/viewlist-128.png
+++ b/src/widgets/styles/images/viewlist-128.png
Binary files differ
diff --git a/src/gui/styles/images/viewlist-16.png b/src/widgets/styles/images/viewlist-16.png
index 9132877ff6..9132877ff6 100644
--- a/src/gui/styles/images/viewlist-16.png
+++ b/src/widgets/styles/images/viewlist-16.png
Binary files differ
diff --git a/src/gui/styles/images/viewlist-32.png b/src/widgets/styles/images/viewlist-32.png
index fae3c24536..fae3c24536 100644
--- a/src/gui/styles/images/viewlist-32.png
+++ b/src/widgets/styles/images/viewlist-32.png
Binary files differ
diff --git a/src/gui/styles/qcdestyle.cpp b/src/widgets/styles/qcdestyle.cpp
index bb97b8a8a1..bb97b8a8a1 100644
--- a/src/gui/styles/qcdestyle.cpp
+++ b/src/widgets/styles/qcdestyle.cpp
diff --git a/src/widgets/styles/qcdestyle.h b/src/widgets/styles/qcdestyle.h
new file mode 100644
index 0000000000..854bfc6c69
--- /dev/null
+++ b/src/widgets/styles/qcdestyle.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QCDESTYLE_H
+#define QCDESTYLE_H
+
+#include <QtWidgets/qmotifstyle.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#if !defined(QT_NO_STYLE_CDE)
+
+class Q_WIDGETS_EXPORT QCDEStyle : public QMotifStyle
+{
+ Q_OBJECT
+public:
+ explicit QCDEStyle(bool useHighlightCols = false);
+ virtual ~QCDEStyle();
+
+ int pixelMetric(PixelMetric metric, const QStyleOption *option = 0,
+ const QWidget *widget = 0) const;
+ void drawControl(ControlElement element, const QStyleOption *opt, QPainter *p,
+ const QWidget *w = 0) const;
+ void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p,
+ const QWidget *w = 0) const;
+ QPalette standardPalette() const;
+
+protected Q_SLOTS:
+ QIcon standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *opt = 0,
+ const QWidget *widget = 0) const;
+};
+
+#endif // QT_NO_STYLE_CDE
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QCDESTYLE_H
diff --git a/src/gui/styles/qcleanlooksstyle.cpp b/src/widgets/styles/qcleanlooksstyle.cpp
index 6da0e9177e..6da0e9177e 100644
--- a/src/gui/styles/qcleanlooksstyle.cpp
+++ b/src/widgets/styles/qcleanlooksstyle.cpp
diff --git a/src/widgets/styles/qcleanlooksstyle.h b/src/widgets/styles/qcleanlooksstyle.h
new file mode 100644
index 0000000000..1b35aa7969
--- /dev/null
+++ b/src/widgets/styles/qcleanlooksstyle.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCLEANLOOKSSTYLE_H
+#define QCLEANLOOKSSTYLE_H
+
+#include <QtWidgets/qwindowsstyle.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#if !defined(QT_NO_STYLE_CLEANLOOKS)
+
+class QCleanlooksStylePrivate;
+class Q_WIDGETS_EXPORT QCleanlooksStyle : public QWindowsStyle
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QCleanlooksStyle)
+
+public:
+ QCleanlooksStyle();
+ ~QCleanlooksStyle();
+
+ QPalette standardPalette () const;
+ void drawPrimitive(PrimitiveElement elem,
+ const QStyleOption *option,
+ QPainter *painter, const QWidget *widget = 0) const;
+ void drawControl(ControlElement ce, const QStyleOption *option, QPainter *painter,
+ const QWidget *widget) const;
+ int pixelMetric(PixelMetric metric, const QStyleOption *option = 0, const QWidget *widget = 0) const;
+ void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option,
+ QPainter *painter, const QWidget *widget) const;
+ QRect subElementRect(SubElement r, const QStyleOption *opt, const QWidget *widget = 0) const;
+ QSize sizeFromContents(ContentsType type, const QStyleOption *option,
+ const QSize &size, const QWidget *widget) const;
+ SubControl hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt,
+ const QPoint &pt, const QWidget *w = 0) const;
+ QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt,
+ SubControl sc, const QWidget *widget) const;
+ QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap,
+ const QStyleOption *opt) const;
+ int styleHint(StyleHint hint, const QStyleOption *option = 0, const QWidget *widget = 0,
+ QStyleHintReturn *returnData = 0) const;
+ QRect itemPixmapRect(const QRect &r, int flags, const QPixmap &pixmap) const;
+ QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt,
+ const QWidget *widget = 0) const;
+ void drawItemPixmap(QPainter *painter, const QRect &rect,
+ int alignment, const QPixmap &pixmap) const;
+ void drawItemText(QPainter *painter, const QRect &rect,
+ int flags, const QPalette &pal, bool enabled,
+ const QString &text, QPalette::ColorRole textRole = QPalette::NoRole) const;
+ void polish(QWidget *widget);
+ void polish(QApplication *app);
+ void polish(QPalette &pal);
+ void unpolish(QWidget *widget);
+ void unpolish(QApplication *app);
+
+protected Q_SLOTS:
+ QIcon standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *option,
+ const QWidget *widget = 0) const;
+
+protected:
+ QCleanlooksStyle(QCleanlooksStylePrivate &dd);
+
+};
+
+#endif // QT_NO_STYLE_CLEANLOOKS
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QCLEANLOOKSSTYLE_H
diff --git a/src/gui/styles/qcleanlooksstyle_p.h b/src/widgets/styles/qcleanlooksstyle_p.h
index 4df13c8a43..4df13c8a43 100644
--- a/src/gui/styles/qcleanlooksstyle_p.h
+++ b/src/widgets/styles/qcleanlooksstyle_p.h
diff --git a/src/gui/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp
index 327bedfdba..327bedfdba 100644
--- a/src/gui/styles/qcommonstyle.cpp
+++ b/src/widgets/styles/qcommonstyle.cpp
diff --git a/src/widgets/styles/qcommonstyle.h b/src/widgets/styles/qcommonstyle.h
new file mode 100644
index 0000000000..a4a7ac11c5
--- /dev/null
+++ b/src/widgets/styles/qcommonstyle.h
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCOMMONSTYLE_H
+#define QCOMMONSTYLE_H
+
+#include <QtWidgets/qstyle.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+QT_MODULE(Gui)
+
+class QCommonStylePrivate;
+
+class Q_WIDGETS_EXPORT QCommonStyle: public QStyle
+{
+ Q_OBJECT
+
+public:
+ QCommonStyle();
+ ~QCommonStyle();
+
+ void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p,
+ const QWidget *w = 0) const;
+ void drawControl(ControlElement element, const QStyleOption *opt, QPainter *p,
+ const QWidget *w = 0) const;
+ QRect subElementRect(SubElement r, const QStyleOption *opt, const QWidget *widget = 0) const;
+ void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p,
+ const QWidget *w = 0) const;
+ SubControl hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt,
+ const QPoint &pt, const QWidget *w = 0) const;
+ QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc,
+ const QWidget *w = 0) const;
+ QSize sizeFromContents(ContentsType ct, const QStyleOption *opt,
+ const QSize &contentsSize, const QWidget *widget = 0) const;
+
+ int pixelMetric(PixelMetric m, const QStyleOption *opt = 0, const QWidget *widget = 0) const;
+
+ int styleHint(StyleHint sh, const QStyleOption *opt = 0, const QWidget *w = 0,
+ QStyleHintReturn *shret = 0) const;
+
+ QPixmap standardPixmap(StandardPixmap sp, const QStyleOption *opt = 0,
+ const QWidget *widget = 0) const;
+
+ QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap,
+ const QStyleOption *opt) const;
+
+ void polish(QPalette &);
+ void polish(QApplication *app);
+ void polish(QWidget *widget);
+ void unpolish(QWidget *widget);
+ void unpolish(QApplication *application);
+
+protected Q_SLOTS:
+ QIcon standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *opt = 0,
+ const QWidget *widget = 0) const;
+
+protected:
+ QCommonStyle(QCommonStylePrivate &dd);
+
+private:
+ Q_DECLARE_PRIVATE(QCommonStyle)
+ Q_DISABLE_COPY(QCommonStyle)
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QCOMMONSTYLE_H
diff --git a/src/gui/styles/qcommonstyle_p.h b/src/widgets/styles/qcommonstyle_p.h
index 554a8130f6..554a8130f6 100644
--- a/src/gui/styles/qcommonstyle_p.h
+++ b/src/widgets/styles/qcommonstyle_p.h
diff --git a/src/gui/styles/qcommonstylepixmaps_p.h b/src/widgets/styles/qcommonstylepixmaps_p.h
index 93cd837fb7..93cd837fb7 100644
--- a/src/gui/styles/qcommonstylepixmaps_p.h
+++ b/src/widgets/styles/qcommonstylepixmaps_p.h
diff --git a/src/widgets/styles/qdrawutil.cpp b/src/widgets/styles/qdrawutil.cpp
new file mode 100644
index 0000000000..94cec208d0
--- /dev/null
+++ b/src/widgets/styles/qdrawutil.cpp
@@ -0,0 +1,1053 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdrawutil.h"
+#include "qbitmap.h"
+#include "qpixmapcache.h"
+#include "qpainter.h"
+#include "qpalette.h"
+#include <private/qpaintengineex_p.h>
+#include <qvarlengtharray.h>
+#include <qmath.h>
+#include <private/qhexstring_p.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \headerfile <qdrawutil.h>
+ \title Drawing Utility Functions
+
+ \sa QPainter
+*/
+
+/*!
+ \fn void qDrawShadeLine(QPainter *painter, int x1, int y1, int x2, int y2,
+ const QPalette &palette, bool sunken,
+ int lineWidth, int midLineWidth)
+ \relates <qdrawutil.h>
+
+ Draws a horizontal (\a y1 == \a y2) or vertical (\a x1 == \a x2)
+ shaded line using the given \a painter. Note that nothing is
+ drawn if \a y1 != \a y2 and \a x1 != \a x2 (i.e. the line is
+ neither horizontal nor vertical).
+
+ The provided \a palette specifies the shading colors (\l
+ {QPalette::light()}{light}, \l {QPalette::dark()}{dark} and \l
+ {QPalette::mid()}{middle} colors). The given \a lineWidth
+ specifies the line width for each of the lines; it is not the
+ total line width. The given \a midLineWidth specifies the width of
+ a middle line drawn in the QPalette::mid() color.
+
+ The line appears sunken if \a sunken is true, otherwise raised.
+
+ \warning This function does not look at QWidget::style() or
+ QApplication::style(). Use the drawing functions in QStyle to
+ make widgets that follow the current GUI style.
+
+
+ Alternatively you can use a QFrame widget and apply the
+ QFrame::setFrameStyle() function to display a shaded line:
+
+ \snippet doc/src/snippets/code/src_gui_painting_qdrawutil.cpp 0
+
+ \sa qDrawShadeRect(), qDrawShadePanel(), QStyle
+*/
+
+void qDrawShadeLine(QPainter *p, int x1, int y1, int x2, int y2,
+ const QPalette &pal, bool sunken,
+ int lineWidth, int midLineWidth)
+{
+ if (!(p && lineWidth >= 0 && midLineWidth >= 0)) {
+ qWarning("qDrawShadeLine: Invalid parameters");
+ return;
+ }
+ int tlw = lineWidth*2 + midLineWidth; // total line width
+ QPen oldPen = p->pen(); // save pen
+ if (sunken)
+ p->setPen(pal.color(QPalette::Dark));
+ else
+ p->setPen(pal.light().color());
+ QPolygon a;
+ int i;
+ if (y1 == y2) { // horizontal line
+ int y = y1 - tlw/2;
+ if (x1 > x2) { // swap x1 and x2
+ int t = x1;
+ x1 = x2;
+ x2 = t;
+ }
+ x2--;
+ for (i=0; i<lineWidth; i++) { // draw top shadow
+ a.setPoints(3, x1+i, y+tlw-1-i,
+ x1+i, y+i,
+ x2-i, y+i);
+ p->drawPolyline(a);
+ }
+ if (midLineWidth > 0) {
+ p->setPen(pal.mid().color());
+ for (i=0; i<midLineWidth; i++) // draw lines in the middle
+ p->drawLine(x1+lineWidth, y+lineWidth+i,
+ x2-lineWidth, y+lineWidth+i);
+ }
+ if (sunken)
+ p->setPen(pal.light().color());
+ else
+ p->setPen(pal.dark().color());
+ for (i=0; i<lineWidth; i++) { // draw bottom shadow
+ a.setPoints(3, x1+i, y+tlw-i-1,
+ x2-i, y+tlw-i-1,
+ x2-i, y+i+1);
+ p->drawPolyline(a);
+ }
+ }
+ else if (x1 == x2) { // vertical line
+ int x = x1 - tlw/2;
+ if (y1 > y2) { // swap y1 and y2
+ int t = y1;
+ y1 = y2;
+ y2 = t;
+ }
+ y2--;
+ for (i=0; i<lineWidth; i++) { // draw left shadow
+ a.setPoints(3, x+i, y2,
+ x+i, y1+i,
+ x+tlw-1, y1+i);
+ p->drawPolyline(a);
+ }
+ if (midLineWidth > 0) {
+ p->setPen(pal.mid().color());
+ for (i=0; i<midLineWidth; i++) // draw lines in the middle
+ p->drawLine(x+lineWidth+i, y1+lineWidth, x+lineWidth+i, y2);
+ }
+ if (sunken)
+ p->setPen(pal.light().color());
+ else
+ p->setPen(pal.dark().color());
+ for (i=0; i<lineWidth; i++) { // draw right shadow
+ a.setPoints(3, x+lineWidth, y2-i,
+ x+tlw-i-1, y2-i,
+ x+tlw-i-1, y1+lineWidth);
+ p->drawPolyline(a);
+ }
+ }
+ p->setPen(oldPen);
+}
+
+/*!
+ \fn void qDrawShadeRect(QPainter *painter, int x, int y, int width, int height,
+ const QPalette &palette, bool sunken,
+ int lineWidth, int midLineWidth,
+ const QBrush *fill)
+ \relates <qdrawutil.h>
+
+ Draws the shaded rectangle beginning at (\a x, \a y) with the
+ given \a width and \a height using the provided \a painter.
+
+ The provide \a palette specifies the shading colors (\l
+ {QPalette::light()}{light}, \l {QPalette::dark()}{dark} and \l
+ {QPalette::mid()}{middle} colors. The given \a lineWidth
+ specifies the line width for each of the lines; it is not the
+ total line width. The \a midLineWidth specifies the width of a
+ middle line drawn in the QPalette::mid() color. The rectangle's
+ interior is filled with the \a fill brush unless \a fill is 0.
+
+ The rectangle appears sunken if \a sunken is true, otherwise
+ raised.
+
+ \warning This function does not look at QWidget::style() or
+ QApplication::style(). Use the drawing functions in QStyle to make
+ widgets that follow the current GUI style.
+
+ Alternatively you can use a QFrame widget and apply the
+ QFrame::setFrameStyle() function to display a shaded rectangle:
+
+ \snippet doc/src/snippets/code/src_gui_painting_qdrawutil.cpp 1
+
+ \sa qDrawShadeLine(), qDrawShadePanel(), qDrawPlainRect(), QStyle
+*/
+
+void qDrawShadeRect(QPainter *p, int x, int y, int w, int h,
+ const QPalette &pal, bool sunken,
+ int lineWidth, int midLineWidth,
+ const QBrush *fill)
+{
+ if (w == 0 || h == 0)
+ return;
+ if (! (w > 0 && h > 0 && lineWidth >= 0 && midLineWidth >= 0)) {
+ qWarning("qDrawShadeRect: Invalid parameters");
+ return;
+ }
+ QPen oldPen = p->pen();
+ if (sunken)
+ p->setPen(pal.dark().color());
+ else
+ p->setPen(pal.light().color());
+ int x1=x, y1=y, x2=x+w-1, y2=y+h-1;
+
+ if (lineWidth == 1 && midLineWidth == 0) {// standard shade rectangle
+ p->drawRect(x1, y1, w-2, h-2);
+ if (sunken)
+ p->setPen(pal.light().color());
+ else
+ p->setPen(pal.dark().color());
+ QLineF lines[4] = { QLineF(x1+1, y1+1, x2-2, y1+1),
+ QLineF(x1+1, y1+2, x1+1, y2-2),
+ QLineF(x1, y2, x2, y2),
+ QLineF(x2,y1, x2,y2-1) };
+ p->drawLines(lines, 4); // draw bottom/right lines
+ } else { // more complicated
+ int m = lineWidth+midLineWidth;
+ int i, j=0, k=m;
+ for (i=0; i<lineWidth; i++) { // draw top shadow
+ QLineF lines[4] = { QLineF(x1+i, y2-i, x1+i, y1+i),
+ QLineF(x1+i, y1+i, x2-i, y1+i),
+ QLineF(x1+k, y2-k, x2-k, y2-k),
+ QLineF(x2-k, y2-k, x2-k, y1+k) };
+ p->drawLines(lines, 4);
+ k++;
+ }
+ p->setPen(pal.mid().color());
+ j = lineWidth*2;
+ for (i=0; i<midLineWidth; i++) { // draw lines in the middle
+ p->drawRect(x1+lineWidth+i, y1+lineWidth+i, w-j-1, h-j-1);
+ j += 2;
+ }
+ if (sunken)
+ p->setPen(pal.light().color());
+ else
+ p->setPen(pal.dark().color());
+ k = m;
+ for (i=0; i<lineWidth; i++) { // draw bottom shadow
+ QLineF lines[4] = { QLineF(x1+1+i, y2-i, x2-i, y2-i),
+ QLineF(x2-i, y2-i, x2-i, y1+i+1),
+ QLineF(x1+k, y2-k, x1+k, y1+k),
+ QLineF(x1+k, y1+k, x2-k, y1+k) };
+ p->drawLines(lines, 4);
+ k++;
+ }
+ }
+ if (fill) {
+ QBrush oldBrush = p->brush();
+ int tlw = lineWidth + midLineWidth;
+ p->setPen(Qt::NoPen);
+ p->setBrush(*fill);
+ p->drawRect(x+tlw, y+tlw, w-2*tlw, h-2*tlw);
+ p->setBrush(oldBrush);
+ }
+ p->setPen(oldPen); // restore pen
+}
+
+
+/*!
+ \fn void qDrawShadePanel(QPainter *painter, int x, int y, int width, int height,
+ const QPalette &palette, bool sunken,
+ int lineWidth, const QBrush *fill)
+ \relates <qdrawutil.h>
+
+ Draws the shaded panel beginning at (\a x, \a y) with the given \a
+ width and \a height using the provided \a painter and the given \a
+ lineWidth.
+
+ The given \a palette specifies the shading colors (\l
+ {QPalette::light()}{light}, \l {QPalette::dark()}{dark} and \l
+ {QPalette::mid()}{middle} colors). The panel's interior is filled
+ with the \a fill brush unless \a fill is 0.
+
+ The panel appears sunken if \a sunken is true, otherwise raised.
+
+ \warning This function does not look at QWidget::style() or
+ QApplication::style(). Use the drawing functions in QStyle to make
+ widgets that follow the current GUI style.
+
+ Alternatively you can use a QFrame widget and apply the
+ QFrame::setFrameStyle() function to display a shaded panel:
+
+ \snippet doc/src/snippets/code/src_gui_painting_qdrawutil.cpp 2
+
+ \sa qDrawWinPanel(), qDrawShadeLine(), qDrawShadeRect(), QStyle
+*/
+
+void qDrawShadePanel(QPainter *p, int x, int y, int w, int h,
+ const QPalette &pal, bool sunken,
+ int lineWidth, const QBrush *fill)
+{
+ if (w == 0 || h == 0)
+ return;
+ if (!(w > 0 && h > 0 && lineWidth >= 0)) {
+ qWarning("qDrawShadePanel: Invalid parameters");
+ }
+ QColor shade = pal.dark().color();
+ QColor light = pal.light().color();
+ if (fill) {
+ if (fill->color() == shade)
+ shade = pal.shadow().color();
+ if (fill->color() == light)
+ light = pal.midlight().color();
+ }
+ QPen oldPen = p->pen(); // save pen
+ QVector<QLineF> lines;
+ lines.reserve(2*lineWidth);
+
+ if (sunken)
+ p->setPen(shade);
+ else
+ p->setPen(light);
+ int x1, y1, x2, y2;
+ int i;
+ x1 = x;
+ y1 = y2 = y;
+ x2 = x+w-2;
+ for (i=0; i<lineWidth; i++) { // top shadow
+ lines << QLineF(x1, y1++, x2--, y2++);
+ }
+ x2 = x1;
+ y1 = y+h-2;
+ for (i=0; i<lineWidth; i++) { // left shado
+ lines << QLineF(x1++, y1, x2++, y2--);
+ }
+ p->drawLines(lines);
+ lines.clear();
+ if (sunken)
+ p->setPen(light);
+ else
+ p->setPen(shade);
+ x1 = x;
+ y1 = y2 = y+h-1;
+ x2 = x+w-1;
+ for (i=0; i<lineWidth; i++) { // bottom shadow
+ lines << QLineF(x1++, y1--, x2, y2--);
+ }
+ x1 = x2;
+ y1 = y;
+ y2 = y+h-lineWidth-1;
+ for (i=0; i<lineWidth; i++) { // right shadow
+ lines << QLineF(x1--, y1++, x2--, y2);
+ }
+ p->drawLines(lines);
+ if (fill) // fill with fill color
+ p->fillRect(x+lineWidth, y+lineWidth, w-lineWidth*2, h-lineWidth*2, *fill);
+ p->setPen(oldPen); // restore pen
+}
+
+
+/*!
+ \internal
+ This function draws a rectangle with two pixel line width.
+ It is called from qDrawWinButton() and qDrawWinPanel().
+
+ c1..c4 and fill are used:
+
+ 1 1 1 1 1 2
+ 1 3 3 3 4 2
+ 1 3 F F 4 2
+ 1 3 F F 4 2
+ 1 4 4 4 4 2
+ 2 2 2 2 2 2
+*/
+
+static void qDrawWinShades(QPainter *p,
+ int x, int y, int w, int h,
+ const QColor &c1, const QColor &c2,
+ const QColor &c3, const QColor &c4,
+ const QBrush *fill)
+{
+ if (w < 2 || h < 2) // can't do anything with that
+ return;
+ QPen oldPen = p->pen();
+ QPoint a[3] = { QPoint(x, y+h-2), QPoint(x, y), QPoint(x+w-2, y) };
+ p->setPen(c1);
+ p->drawPolyline(a, 3);
+ QPoint b[3] = { QPoint(x, y+h-1), QPoint(x+w-1, y+h-1), QPoint(x+w-1, y) };
+ p->setPen(c2);
+ p->drawPolyline(b, 3);
+ if (w > 4 && h > 4) {
+ QPoint c[3] = { QPoint(x+1, y+h-3), QPoint(x+1, y+1), QPoint(x+w-3, y+1) };
+ p->setPen(c3);
+ p->drawPolyline(c, 3);
+ QPoint d[3] = { QPoint(x+1, y+h-2), QPoint(x+w-2, y+h-2), QPoint(x+w-2, y+1) };
+ p->setPen(c4);
+ p->drawPolyline(d, 3);
+ if (fill)
+ p->fillRect(QRect(x+2, y+2, w-4, h-4), *fill);
+ }
+ p->setPen(oldPen);
+}
+
+
+/*!
+ \fn void qDrawWinButton(QPainter *painter, int x, int y, int width, int height,
+ const QPalette &palette, bool sunken,
+ const QBrush *fill)
+ \relates <qdrawutil.h>
+
+ Draws the Windows-style button specified by the given point (\a x,
+ \a y}, \a width and \a height using the provided \a painter with a
+ line width of 2 pixels. The button's interior is filled with the
+ \a{fill} brush unless \a fill is 0.
+
+ The given \a palette specifies the shading colors (\l
+ {QPalette::light()}{light}, \l {QPalette::dark()}{dark} and \l
+ {QPalette::mid()}{middle} colors).
+
+ The button appears sunken if \a sunken is true, otherwise raised.
+
+ \warning This function does not look at QWidget::style() or
+ QApplication::style()-> Use the drawing functions in QStyle to make
+ widgets that follow the current GUI style.
+
+ \sa qDrawWinPanel(), QStyle
+*/
+
+void qDrawWinButton(QPainter *p, int x, int y, int w, int h,
+ const QPalette &pal, bool sunken,
+ const QBrush *fill)
+{
+ if (sunken)
+ qDrawWinShades(p, x, y, w, h,
+ pal.shadow().color(), pal.light().color(), pal.dark().color(),
+ pal.button().color(), fill);
+ else
+ qDrawWinShades(p, x, y, w, h,
+ pal.light().color(), pal.shadow().color(), pal.button().color(),
+ pal.dark().color(), fill);
+}
+
+/*!
+ \fn void qDrawWinPanel(QPainter *painter, int x, int y, int width, int height,
+ const QPalette &palette, bool sunken,
+ const QBrush *fill)
+ \relates <qdrawutil.h>
+
+ Draws the Windows-style panel specified by the given point(\a x,
+ \a y), \a width and \a height using the provided \a painter with a
+ line width of 2 pixels. The button's interior is filled with the
+ \a fill brush unless \a fill is 0.
+
+ The given \a palette specifies the shading colors. The panel
+ appears sunken if \a sunken is true, otherwise raised.
+
+ \warning This function does not look at QWidget::style() or
+ QApplication::style(). Use the drawing functions in QStyle to make
+ widgets that follow the current GUI style.
+
+ Alternatively you can use a QFrame widget and apply the
+ QFrame::setFrameStyle() function to display a shaded panel:
+
+ \snippet doc/src/snippets/code/src_gui_painting_qdrawutil.cpp 3
+
+ \sa qDrawShadePanel(), qDrawWinButton(), QStyle
+*/
+
+void qDrawWinPanel(QPainter *p, int x, int y, int w, int h,
+ const QPalette &pal, bool sunken,
+ const QBrush *fill)
+{
+ if (sunken)
+ qDrawWinShades(p, x, y, w, h,
+ pal.dark().color(), pal.light().color(), pal.shadow().color(),
+ pal.midlight().color(), fill);
+ else
+ qDrawWinShades(p, x, y, w, h,
+ pal.light().color(), pal.shadow().color(), pal.midlight().color(),
+ pal.dark().color(), fill);
+}
+
+/*!
+ \fn void qDrawPlainRect(QPainter *painter, int x, int y, int width, int height, const QColor &lineColor,
+ int lineWidth, const QBrush *fill)
+ \relates <qdrawutil.h>
+
+ Draws the plain rectangle beginning at (\a x, \a y) with the given
+ \a width and \a height, using the specified \a painter, \a lineColor
+ and \a lineWidth. The rectangle's interior is filled with the \a
+ fill brush unless \a fill is 0.
+
+ \warning This function does not look at QWidget::style() or
+ QApplication::style(). Use the drawing functions in QStyle to make
+ widgets that follow the current GUI style.
+
+ Alternatively you can use a QFrame widget and apply the
+ QFrame::setFrameStyle() function to display a plain rectangle:
+
+ \snippet doc/src/snippets/code/src_gui_painting_qdrawutil.cpp 4
+
+ \sa qDrawShadeRect(), QStyle
+*/
+
+void qDrawPlainRect(QPainter *p, int x, int y, int w, int h, const QColor &c,
+ int lineWidth, const QBrush *fill)
+{
+ if (w == 0 || h == 0)
+ return;
+ if (!(w > 0 && h > 0 && lineWidth >= 0)) {
+ qWarning("qDrawPlainRect: Invalid parameters");
+ }
+ QPen oldPen = p->pen();
+ QBrush oldBrush = p->brush();
+ p->setPen(c);
+ p->setBrush(Qt::NoBrush);
+ for (int i=0; i<lineWidth; i++)
+ p->drawRect(x+i, y+i, w-i*2 - 1, h-i*2 - 1);
+ if (fill) { // fill with fill color
+ p->setPen(Qt::NoPen);
+ p->setBrush(*fill);
+ p->drawRect(x+lineWidth, y+lineWidth, w-lineWidth*2, h-lineWidth*2);
+ }
+ p->setPen(oldPen);
+ p->setBrush(oldBrush);
+}
+
+/*****************************************************************************
+ Overloaded functions.
+ *****************************************************************************/
+
+/*!
+ \fn void qDrawShadeLine(QPainter *painter, const QPoint &p1, const QPoint &p2,
+ const QPalette &palette, bool sunken, int lineWidth, int midLineWidth)
+ \relates <qdrawutil.h>
+ \overload
+
+ Draws a horizontal or vertical shaded line between \a p1 and \a p2
+ using the given \a painter. Note that nothing is drawn if the line
+ between the points would be neither horizontal nor vertical.
+
+ The provided \a palette specifies the shading colors (\l
+ {QPalette::light()}{light}, \l {QPalette::dark()}{dark} and \l
+ {QPalette::mid()}{middle} colors). The given \a lineWidth
+ specifies the line width for each of the lines; it is not the
+ total line width. The given \a midLineWidth specifies the width of
+ a middle line drawn in the QPalette::mid() color.
+
+ The line appears sunken if \a sunken is true, otherwise raised.
+
+ \warning This function does not look at QWidget::style() or
+ QApplication::style(). Use the drawing functions in QStyle to
+ make widgets that follow the current GUI style.
+
+
+ Alternatively you can use a QFrame widget and apply the
+ QFrame::setFrameStyle() function to display a shaded line:
+
+ \snippet doc/src/snippets/code/src_gui_painting_qdrawutil.cpp 5
+
+ \sa qDrawShadeRect(), qDrawShadePanel(), QStyle
+*/
+
+void qDrawShadeLine(QPainter *p, const QPoint &p1, const QPoint &p2,
+ const QPalette &pal, bool sunken,
+ int lineWidth, int midLineWidth)
+{
+ qDrawShadeLine(p, p1.x(), p1.y(), p2.x(), p2.y(), pal, sunken,
+ lineWidth, midLineWidth);
+}
+
+/*!
+ \fn void qDrawShadeRect(QPainter *painter, const QRect &rect, const QPalette &palette,
+ bool sunken, int lineWidth, int midLineWidth, const QBrush *fill)
+ \relates <qdrawutil.h>
+ \overload
+
+ Draws the shaded rectangle specified by \a rect using the given \a painter.
+
+ The provide \a palette specifies the shading colors (\l
+ {QPalette::light()}{light}, \l {QPalette::dark()}{dark} and \l
+ {QPalette::mid()}{middle} colors. The given \a lineWidth
+ specifies the line width for each of the lines; it is not the
+ total line width. The \a midLineWidth specifies the width of a
+ middle line drawn in the QPalette::mid() color. The rectangle's
+ interior is filled with the \a fill brush unless \a fill is 0.
+
+ The rectangle appears sunken if \a sunken is true, otherwise
+ raised.
+
+ \warning This function does not look at QWidget::style() or
+ QApplication::style(). Use the drawing functions in QStyle to make
+ widgets that follow the current GUI style.
+
+ Alternatively you can use a QFrame widget and apply the
+ QFrame::setFrameStyle() function to display a shaded rectangle:
+
+ \snippet doc/src/snippets/code/src_gui_painting_qdrawutil.cpp 6
+
+ \sa qDrawShadeLine(), qDrawShadePanel(), qDrawPlainRect(), QStyle
+*/
+
+void qDrawShadeRect(QPainter *p, const QRect &r,
+ const QPalette &pal, bool sunken,
+ int lineWidth, int midLineWidth,
+ const QBrush *fill)
+{
+ qDrawShadeRect(p, r.x(), r.y(), r.width(), r.height(), pal, sunken,
+ lineWidth, midLineWidth, fill);
+}
+
+/*!
+ \fn void qDrawShadePanel(QPainter *painter, const QRect &rect, const QPalette &palette,
+ bool sunken, int lineWidth, const QBrush *fill)
+ \relates <qdrawutil.h>
+ \overload
+
+ Draws the shaded panel at the rectangle specified by \a rect using the
+ given \a painter and the given \a lineWidth.
+
+ The given \a palette specifies the shading colors (\l
+ {QPalette::light()}{light}, \l {QPalette::dark()}{dark} and \l
+ {QPalette::mid()}{middle} colors). The panel's interior is filled
+ with the \a fill brush unless \a fill is 0.
+
+ The panel appears sunken if \a sunken is true, otherwise raised.
+
+ \warning This function does not look at QWidget::style() or
+ QApplication::style(). Use the drawing functions in QStyle to make
+ widgets that follow the current GUI style.
+
+ Alternatively you can use a QFrame widget and apply the
+ QFrame::setFrameStyle() function to display a shaded panel:
+
+ \snippet doc/src/snippets/code/src_gui_painting_qdrawutil.cpp 7
+
+ \sa qDrawWinPanel(), qDrawShadeLine(), qDrawShadeRect(), QStyle
+*/
+
+void qDrawShadePanel(QPainter *p, const QRect &r,
+ const QPalette &pal, bool sunken,
+ int lineWidth, const QBrush *fill)
+{
+ qDrawShadePanel(p, r.x(), r.y(), r.width(), r.height(), pal, sunken,
+ lineWidth, fill);
+}
+
+/*!
+ \fn void qDrawWinButton(QPainter *painter, const QRect &rect, const QPalette &palette,
+ bool sunken, const QBrush *fill)
+ \relates <qdrawutil.h>
+ \overload
+
+ Draws the Windows-style button at the rectangle specified by \a rect using
+ the given \a painter with a line width of 2 pixels. The button's interior
+ is filled with the \a{fill} brush unless \a fill is 0.
+
+ The given \a palette specifies the shading colors (\l
+ {QPalette::light()}{light}, \l {QPalette::dark()}{dark} and \l
+ {QPalette::mid()}{middle} colors).
+
+ The button appears sunken if \a sunken is true, otherwise raised.
+
+ \warning This function does not look at QWidget::style() or
+ QApplication::style()-> Use the drawing functions in QStyle to make
+ widgets that follow the current GUI style.
+
+ \sa qDrawWinPanel(), QStyle
+*/
+
+void qDrawWinButton(QPainter *p, const QRect &r,
+ const QPalette &pal, bool sunken, const QBrush *fill)
+{
+ qDrawWinButton(p, r.x(), r.y(), r.width(), r.height(), pal, sunken, fill);
+}
+
+/*!
+ \fn void qDrawWinPanel(QPainter *painter, const QRect &rect, const QPalette &palette,
+ bool sunken, const QBrush *fill)
+ \overload
+
+ Draws the Windows-style panel at the rectangle specified by \a rect using
+ the given \a painter with a line width of 2 pixels. The button's interior
+ is filled with the \a fill brush unless \a fill is 0.
+
+ The given \a palette specifies the shading colors. The panel
+ appears sunken if \a sunken is true, otherwise raised.
+
+ \warning This function does not look at QWidget::style() or
+ QApplication::style(). Use the drawing functions in QStyle to make
+ widgets that follow the current GUI style.
+
+ Alternatively you can use a QFrame widget and apply the
+ QFrame::setFrameStyle() function to display a shaded panel:
+
+ \snippet doc/src/snippets/code/src_gui_painting_qdrawutil.cpp 8
+
+ \sa qDrawShadePanel(), qDrawWinButton(), QStyle
+*/
+
+void qDrawWinPanel(QPainter *p, const QRect &r,
+ const QPalette &pal, bool sunken, const QBrush *fill)
+{
+ qDrawWinPanel(p, r.x(), r.y(), r.width(), r.height(), pal, sunken, fill);
+}
+
+/*!
+ \fn void qDrawPlainRect(QPainter *painter, const QRect &rect, const QColor &lineColor, int lineWidth, const QBrush *fill)
+ \relates <qdrawutil.h>
+ \overload
+
+ Draws the plain rectangle specified by \a rect using the given \a painter,
+ \a lineColor and \a lineWidth. The rectangle's interior is filled with the
+ \a fill brush unless \a fill is 0.
+
+ \warning This function does not look at QWidget::style() or
+ QApplication::style(). Use the drawing functions in QStyle to make
+ widgets that follow the current GUI style.
+
+ Alternatively you can use a QFrame widget and apply the
+ QFrame::setFrameStyle() function to display a plain rectangle:
+
+ \snippet doc/src/snippets/code/src_gui_painting_qdrawutil.cpp 9
+
+ \sa qDrawShadeRect(), QStyle
+*/
+
+void qDrawPlainRect(QPainter *p, const QRect &r, const QColor &c,
+ int lineWidth, const QBrush *fill)
+{
+ qDrawPlainRect(p, r.x(), r.y(), r.width(), r.height(), c,
+ lineWidth, fill);
+}
+
+
+/*!
+ \class QTileRules
+ \since 4.6
+
+ Holds the rules used to draw a pixmap or image split into nine segments,
+ similar to \l{http://www.w3.org/TR/css3-background/}{CSS3 border-images}.
+
+ \sa Qt::TileRule, QMargins
+*/
+
+/*! \fn QTileRules::QTileRules(Qt::TileRule horizontalRule, Qt::TileRule verticalRule)
+ Constructs a QTileRules with the given \a horizontalRule and
+ \a verticalRule.
+ */
+
+/*! \fn QTileRules::QTileRules(Qt::TileRule rule)
+ Constructs a QTileRules with the given \a rule used for both
+ the horizontal rule and the vertical rule.
+ */
+
+/*!
+ \fn void qDrawBorderPixmap(QPainter *painter, const QRect &target, const QMargins &margins, const QPixmap &pixmap)
+ \relates <qdrawutil.h>
+ \since 4.6
+ \overload
+
+ \brief The qDrawBorderPixmap function is for drawing a pixmap into
+ the margins of a rectangle.
+
+ Draws the given \a pixmap into the given \a target rectangle, using the
+ given \a painter. The pixmap will be split into nine segments and drawn
+ according to the \a margins structure.
+*/
+
+typedef QVarLengthArray<QPainter::PixmapFragment, 16> QPixmapFragmentsArray;
+
+/*!
+ \since 4.6
+
+ Draws the indicated \a sourceRect rectangle from the given \a pixmap into
+ the given \a targetRect rectangle, using the given \a painter. The pixmap
+ will be split into nine segments according to the given \a targetMargins
+ and \a sourceMargins structures. Finally, the pixmap will be drawn
+ according to the given \a rules.
+
+ This function is used to draw a scaled pixmap, similar to
+ \l{http://www.w3.org/TR/css3-background/}{CSS3 border-images}
+
+ \sa Qt::TileRule, QTileRules, QMargins
+*/
+
+void qDrawBorderPixmap(QPainter *painter, const QRect &targetRect, const QMargins &targetMargins,
+ const QPixmap &pixmap, const QRect &sourceRect,const QMargins &sourceMargins,
+ const QTileRules &rules, QDrawBorderPixmap::DrawingHints hints)
+{
+ QPainter::PixmapFragment d;
+ d.opacity = 1.0;
+ d.rotation = 0.0;
+
+ QPixmapFragmentsArray opaqueData;
+ QPixmapFragmentsArray translucentData;
+
+ // source center
+ const int sourceCenterTop = sourceRect.top() + sourceMargins.top();
+ const int sourceCenterLeft = sourceRect.left() + sourceMargins.left();
+ const int sourceCenterBottom = sourceRect.bottom() - sourceMargins.bottom() + 1;
+ const int sourceCenterRight = sourceRect.right() - sourceMargins.right() + 1;
+ const int sourceCenterWidth = sourceCenterRight - sourceCenterLeft;
+ const int sourceCenterHeight = sourceCenterBottom - sourceCenterTop;
+ // target center
+ const int targetCenterTop = targetRect.top() + targetMargins.top();
+ const int targetCenterLeft = targetRect.left() + targetMargins.left();
+ const int targetCenterBottom = targetRect.bottom() - targetMargins.bottom() + 1;
+ const int targetCenterRight = targetRect.right() - targetMargins.right() + 1;
+ const int targetCenterWidth = targetCenterRight - targetCenterLeft;
+ const int targetCenterHeight = targetCenterBottom - targetCenterTop;
+
+ QVarLengthArray<qreal, 16> xTarget; // x-coordinates of target rectangles
+ QVarLengthArray<qreal, 16> yTarget; // y-coordinates of target rectangles
+
+ int columns = 3;
+ int rows = 3;
+ if (rules.horizontal != Qt::StretchTile && sourceCenterWidth != 0)
+ columns = qMax(3, 2 + qCeil(targetCenterWidth / qreal(sourceCenterWidth)));
+ if (rules.vertical != Qt::StretchTile && sourceCenterHeight != 0)
+ rows = qMax(3, 2 + qCeil(targetCenterHeight / qreal(sourceCenterHeight)));
+
+ xTarget.resize(columns + 1);
+ yTarget.resize(rows + 1);
+
+ bool oldAA = painter->testRenderHint(QPainter::Antialiasing);
+ if (painter->paintEngine()->type() != QPaintEngine::OpenGL
+ && painter->paintEngine()->type() != QPaintEngine::OpenGL2
+ && oldAA && painter->combinedTransform().type() != QTransform::TxNone) {
+ painter->setRenderHint(QPainter::Antialiasing, false);
+ }
+
+ xTarget[0] = targetRect.left();
+ xTarget[1] = targetCenterLeft;
+ xTarget[columns - 1] = targetCenterRight;
+ xTarget[columns] = targetRect.left() + targetRect.width();
+
+ yTarget[0] = targetRect.top();
+ yTarget[1] = targetCenterTop;
+ yTarget[rows - 1] = targetCenterBottom;
+ yTarget[rows] = targetRect.top() + targetRect.height();
+
+ qreal dx = targetCenterWidth;
+ qreal dy = targetCenterHeight;
+
+ switch (rules.horizontal) {
+ case Qt::StretchTile:
+ dx = targetCenterWidth;
+ break;
+ case Qt::RepeatTile:
+ dx = sourceCenterWidth;
+ break;
+ case Qt::RoundTile:
+ dx = targetCenterWidth / qreal(columns - 2);
+ break;
+ }
+
+ for (int i = 2; i < columns - 1; ++i)
+ xTarget[i] = xTarget[i - 1] + dx;
+
+ switch (rules.vertical) {
+ case Qt::StretchTile:
+ dy = targetCenterHeight;
+ break;
+ case Qt::RepeatTile:
+ dy = sourceCenterHeight;
+ break;
+ case Qt::RoundTile:
+ dy = targetCenterHeight / qreal(rows - 2);
+ break;
+ }
+
+ for (int i = 2; i < rows - 1; ++i)
+ yTarget[i] = yTarget[i - 1] + dy;
+
+ // corners
+ if (targetMargins.top() > 0 && targetMargins.left() > 0 && sourceMargins.top() > 0 && sourceMargins.left() > 0) { // top left
+ d.x = (0.5 * (xTarget[1] + xTarget[0]));
+ d.y = (0.5 * (yTarget[1] + yTarget[0]));
+ d.sourceLeft = sourceRect.left();
+ d.sourceTop = sourceRect.top();
+ d.width = sourceMargins.left();
+ d.height = sourceMargins.top();
+ d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.width;
+ d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.height;
+ if (hints & QDrawBorderPixmap::OpaqueTopLeft)
+ opaqueData.append(d);
+ else
+ translucentData.append(d);
+ }
+ if (targetMargins.top() > 0 && targetMargins.right() > 0 && sourceMargins.top() > 0 && sourceMargins.right() > 0) { // top right
+ d.x = (0.5 * (xTarget[columns] + xTarget[columns - 1]));
+ d.y = (0.5 * (yTarget[1] + yTarget[0]));
+ d.sourceLeft = sourceCenterRight;
+ d.sourceTop = sourceRect.top();
+ d.width = sourceMargins.right();
+ d.height = sourceMargins.top();
+ d.scaleX = qreal(xTarget[columns] - xTarget[columns - 1]) / d.width;
+ d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.height;
+ if (hints & QDrawBorderPixmap::OpaqueTopRight)
+ opaqueData.append(d);
+ else
+ translucentData.append(d);
+ }
+ if (targetMargins.bottom() > 0 && targetMargins.left() > 0 && sourceMargins.bottom() > 0 && sourceMargins.left() > 0) { // bottom left
+ d.x = (0.5 * (xTarget[1] + xTarget[0]));
+ d.y =(0.5 * (yTarget[rows] + yTarget[rows - 1]));
+ d.sourceLeft = sourceRect.left();
+ d.sourceTop = sourceCenterBottom;
+ d.width = sourceMargins.left();
+ d.height = sourceMargins.bottom();
+ d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.width;
+ d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.height;
+ if (hints & QDrawBorderPixmap::OpaqueBottomLeft)
+ opaqueData.append(d);
+ else
+ translucentData.append(d);
+ }
+ if (targetMargins.bottom() > 0 && targetMargins.right() > 0 && sourceMargins.bottom() > 0 && sourceMargins.right() > 0) { // bottom right
+ d.x = (0.5 * (xTarget[columns] + xTarget[columns - 1]));
+ d.y = (0.5 * (yTarget[rows] + yTarget[rows - 1]));
+ d.sourceLeft = sourceCenterRight;
+ d.sourceTop = sourceCenterBottom;
+ d.width = sourceMargins.right();
+ d.height = sourceMargins.bottom();
+ d.scaleX = qreal(xTarget[columns] - xTarget[columns - 1]) / d.width;
+ d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.height;
+ if (hints & QDrawBorderPixmap::OpaqueBottomRight)
+ opaqueData.append(d);
+ else
+ translucentData.append(d);
+ }
+
+ // horizontal edges
+ if (targetCenterWidth > 0 && sourceCenterWidth > 0) {
+ if (targetMargins.top() > 0 && sourceMargins.top() > 0) { // top
+ QPixmapFragmentsArray &data = hints & QDrawBorderPixmap::OpaqueTop ? opaqueData : translucentData;
+ d.sourceLeft = sourceCenterLeft;
+ d.sourceTop = sourceRect.top();
+ d.width = sourceCenterWidth;
+ d.height = sourceMargins.top();
+ d.y = (0.5 * (yTarget[1] + yTarget[0]));
+ d.scaleX = dx / d.width;
+ d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.height;
+ for (int i = 1; i < columns - 1; ++i) {
+ d.x = (0.5 * (xTarget[i + 1] + xTarget[i]));
+ data.append(d);
+ }
+ if (rules.horizontal == Qt::RepeatTile)
+ data[data.size() - 1].width = ((xTarget[columns - 1] - xTarget[columns - 2]) / d.scaleX);
+ }
+ if (targetMargins.bottom() > 0 && sourceMargins.bottom() > 0) { // bottom
+ QPixmapFragmentsArray &data = hints & QDrawBorderPixmap::OpaqueBottom ? opaqueData : translucentData;
+ d.sourceLeft = sourceCenterLeft;
+ d.sourceTop = sourceCenterBottom;
+ d.width = sourceCenterWidth;
+ d.height = sourceMargins.bottom();
+ d.y = (0.5 * (yTarget[rows] + yTarget[rows - 1]));
+ d.scaleX = dx / d.width;
+ d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.height;
+ for (int i = 1; i < columns - 1; ++i) {
+ d.x = (0.5 * (xTarget[i + 1] + xTarget[i]));
+ data.append(d);
+ }
+ if (rules.horizontal == Qt::RepeatTile)
+ data[data.size() - 1].width = ((xTarget[columns - 1] - xTarget[columns - 2]) / d.scaleX);
+ }
+ }
+
+ // vertical edges
+ if (targetCenterHeight > 0 && sourceCenterHeight > 0) {
+ if (targetMargins.left() > 0 && sourceMargins.left() > 0) { // left
+ QPixmapFragmentsArray &data = hints & QDrawBorderPixmap::OpaqueLeft ? opaqueData : translucentData;
+ d.sourceLeft = sourceRect.left();
+ d.sourceTop = sourceCenterTop;
+ d.width = sourceMargins.left();
+ d.height = sourceCenterHeight;
+ d.x = (0.5 * (xTarget[1] + xTarget[0]));
+ d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.width;
+ d.scaleY = dy / d.height;
+ for (int i = 1; i < rows - 1; ++i) {
+ d.y = (0.5 * (yTarget[i + 1] + yTarget[i]));
+ data.append(d);
+ }
+ if (rules.vertical == Qt::RepeatTile)
+ data[data.size() - 1].height = ((yTarget[rows - 1] - yTarget[rows - 2]) / d.scaleY);
+ }
+ if (targetMargins.right() > 0 && sourceMargins.right() > 0) { // right
+ QPixmapFragmentsArray &data = hints & QDrawBorderPixmap::OpaqueRight ? opaqueData : translucentData;
+ d.sourceLeft = sourceCenterRight;
+ d.sourceTop = sourceCenterTop;
+ d.width = sourceMargins.right();
+ d.height = sourceCenterHeight;
+ d.x = (0.5 * (xTarget[columns] + xTarget[columns - 1]));
+ d.scaleX = qreal(xTarget[columns] - xTarget[columns - 1]) / d.width;
+ d.scaleY = dy / d.height;
+ for (int i = 1; i < rows - 1; ++i) {
+ d.y = (0.5 * (yTarget[i + 1] + yTarget[i]));
+ data.append(d);
+ }
+ if (rules.vertical == Qt::RepeatTile)
+ data[data.size() - 1].height = ((yTarget[rows - 1] - yTarget[rows - 2]) / d.scaleY);
+ }
+ }
+
+ // center
+ if (targetCenterWidth > 0 && targetCenterHeight > 0 && sourceCenterWidth > 0 && sourceCenterHeight > 0) {
+ QPixmapFragmentsArray &data = hints & QDrawBorderPixmap::OpaqueCenter ? opaqueData : translucentData;
+ d.sourceLeft = sourceCenterLeft;
+ d.sourceTop = sourceCenterTop;
+ d.width = sourceCenterWidth;
+ d.height = sourceCenterHeight;
+ d.scaleX = dx / d.width;
+ d.scaleY = dy / d.height;
+
+ qreal repeatWidth = (xTarget[columns - 1] - xTarget[columns - 2]) / d.scaleX;
+ qreal repeatHeight = (yTarget[rows - 1] - yTarget[rows - 2]) / d.scaleY;
+
+ for (int j = 1; j < rows - 1; ++j) {
+ d.y = (0.5 * (yTarget[j + 1] + yTarget[j]));
+ for (int i = 1; i < columns - 1; ++i) {
+ d.x = (0.5 * (xTarget[i + 1] + xTarget[i]));
+ data.append(d);
+ }
+ if (rules.horizontal == Qt::RepeatTile)
+ data[data.size() - 1].width = repeatWidth;
+ }
+ if (rules.vertical == Qt::RepeatTile) {
+ for (int i = 1; i < columns - 1; ++i)
+ data[data.size() - i].height = repeatHeight;
+ }
+ }
+
+ if (opaqueData.size())
+ painter->drawPixmapFragments(opaqueData.data(), opaqueData.size(), pixmap, QPainter::OpaqueHint);
+ if (translucentData.size())
+ painter->drawPixmapFragments(translucentData.data(), translucentData.size(), pixmap);
+
+ if (oldAA)
+ painter->setRenderHint(QPainter::Antialiasing, true);
+}
+
+QT_END_NAMESPACE
diff --git a/src/widgets/styles/qdrawutil.h b/src/widgets/styles/qdrawutil.h
new file mode 100644
index 0000000000..2f35d236b7
--- /dev/null
+++ b/src/widgets/styles/qdrawutil.h
@@ -0,0 +1,175 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDRAWUTIL_H
+#define QDRAWUTIL_H
+
+#include <QtCore/qnamespace.h>
+#include <QtCore/qstring.h> // char*->QString conversion
+#include <QtCore/qmargins.h>
+#include <QtGui/qpixmap.h>
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QPainter;
+class QPalette;
+class QPoint;
+class QColor;
+class QBrush;
+class QRect;
+
+//
+// Standard shade drawing
+//
+
+Q_WIDGETS_EXPORT void qDrawShadeLine(QPainter *p, int x1, int y1, int x2, int y2,
+ const QPalette &pal, bool sunken = true,
+ int lineWidth = 1, int midLineWidth = 0);
+
+Q_WIDGETS_EXPORT void qDrawShadeLine(QPainter *p, const QPoint &p1, const QPoint &p2,
+ const QPalette &pal, bool sunken = true,
+ int lineWidth = 1, int midLineWidth = 0);
+
+Q_WIDGETS_EXPORT void qDrawShadeRect(QPainter *p, int x, int y, int w, int h,
+ const QPalette &pal, bool sunken = false,
+ int lineWidth = 1, int midLineWidth = 0,
+ const QBrush *fill = 0);
+
+Q_WIDGETS_EXPORT void qDrawShadeRect(QPainter *p, const QRect &r,
+ const QPalette &pal, bool sunken = false,
+ int lineWidth = 1, int midLineWidth = 0,
+ const QBrush *fill = 0);
+
+Q_WIDGETS_EXPORT void qDrawShadePanel(QPainter *p, int x, int y, int w, int h,
+ const QPalette &pal, bool sunken = false,
+ int lineWidth = 1, const QBrush *fill = 0);
+
+Q_WIDGETS_EXPORT void qDrawShadePanel(QPainter *p, const QRect &r,
+ const QPalette &pal, bool sunken = false,
+ int lineWidth = 1, const QBrush *fill = 0);
+
+Q_WIDGETS_EXPORT void qDrawWinButton(QPainter *p, int x, int y, int w, int h,
+ const QPalette &pal, bool sunken = false,
+ const QBrush *fill = 0);
+
+Q_WIDGETS_EXPORT void qDrawWinButton(QPainter *p, const QRect &r,
+ const QPalette &pal, bool sunken = false,
+ const QBrush *fill = 0);
+
+Q_WIDGETS_EXPORT void qDrawWinPanel(QPainter *p, int x, int y, int w, int h,
+ const QPalette &pal, bool sunken = false,
+ const QBrush *fill = 0);
+
+Q_WIDGETS_EXPORT void qDrawWinPanel(QPainter *p, const QRect &r,
+ const QPalette &pal, bool sunken = false,
+ const QBrush *fill = 0);
+
+Q_WIDGETS_EXPORT void qDrawPlainRect(QPainter *p, int x, int y, int w, int h, const QColor &,
+ int lineWidth = 1, const QBrush *fill = 0);
+
+Q_WIDGETS_EXPORT void qDrawPlainRect(QPainter *p, const QRect &r, const QColor &,
+ int lineWidth = 1, const QBrush *fill = 0);
+
+
+
+struct QTileRules
+{
+ inline QTileRules(Qt::TileRule horizontalRule, Qt::TileRule verticalRule)
+ : horizontal(horizontalRule), vertical(verticalRule) {}
+ inline QTileRules(Qt::TileRule rule = Qt::StretchTile)
+ : horizontal(rule), vertical(rule) {}
+ Qt::TileRule horizontal;
+ Qt::TileRule vertical;
+};
+
+#ifndef Q_QDOC
+// For internal use only.
+namespace QDrawBorderPixmap
+{
+ enum DrawingHint
+ {
+ OpaqueTopLeft = 0x0001,
+ OpaqueTop = 0x0002,
+ OpaqueTopRight = 0x0004,
+ OpaqueLeft = 0x0008,
+ OpaqueCenter = 0x0010,
+ OpaqueRight = 0x0020,
+ OpaqueBottomLeft = 0x0040,
+ OpaqueBottom = 0x0080,
+ OpaqueBottomRight = 0x0100,
+ OpaqueCorners = OpaqueTopLeft | OpaqueTopRight | OpaqueBottomLeft | OpaqueBottomRight,
+ OpaqueEdges = OpaqueTop | OpaqueLeft | OpaqueRight | OpaqueBottom,
+ OpaqueFrame = OpaqueCorners | OpaqueEdges,
+ OpaqueAll = OpaqueCenter | OpaqueFrame
+ };
+
+ Q_DECLARE_FLAGS(DrawingHints, DrawingHint)
+}
+#endif
+
+Q_WIDGETS_EXPORT void qDrawBorderPixmap(QPainter *painter,
+ const QRect &targetRect,
+ const QMargins &targetMargins,
+ const QPixmap &pixmap,
+ const QRect &sourceRect,
+ const QMargins &sourceMargins,
+ const QTileRules &rules = QTileRules()
+#ifndef Q_QDOC
+ , QDrawBorderPixmap::DrawingHints hints = 0
+#endif
+ );
+
+inline void qDrawBorderPixmap(QPainter *painter,
+ const QRect &target,
+ const QMargins &margins,
+ const QPixmap &pixmap)
+{
+ qDrawBorderPixmap(painter, target, margins, pixmap, pixmap.rect(), margins);
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QDRAWUTIL_H
diff --git a/src/widgets/styles/qgtkpainter.cpp b/src/widgets/styles/qgtkpainter.cpp
new file mode 100644
index 0000000000..373732f924
--- /dev/null
+++ b/src/widgets/styles/qgtkpainter.cpp
@@ -0,0 +1,716 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qgtkpainter_p.h"
+
+#include <QtCore/qglobal.h>
+#if !defined(QT_NO_STYLE_GTK)
+
+// This class is primarily a wrapper around the gtk painter functions
+// and takes care of converting all such calls into cached Qt pixmaps.
+
+#include <private/qstylehelper_p.h>
+#include <QtWidgets/QWidget>
+#include <QtWidgets/QStyleOption>
+#include <QtGui/QPixmapCache>
+
+QT_BEGIN_NAMESPACE
+
+#undef GTK_OBJECT_FLAGS
+#define GTK_OBJECT_FLAGS(obj)(((GtkObject*)(obj))->flags)
+
+#if Q_BYTE_ORDER == Q_BIG_ENDIAN
+# define QT_RED 3
+# define QT_GREEN 2
+# define QT_BLUE 1
+# define QT_ALPHA 0
+#else
+# define QT_RED 0
+# define QT_GREEN 1
+# define QT_BLUE 2
+# define QT_ALPHA 3
+#endif
+# define GTK_RED 2
+# define GTK_GREEN 1
+# define GTK_BLUE 0
+# define GTK_ALPHA 3
+
+// To recover alpha we apply the gtk painting function two times to
+// white, and black window backgrounds. This can be used to
+// recover the premultiplied alpha channel
+QPixmap QGtkPainter::renderTheme(uchar *bdata, uchar *wdata, const QRect &rect)
+{
+ const int bytecount = rect.width() * rect.height() * 4;
+ for (int index = 0; index < bytecount ; index += 4) {
+ uchar val = bdata[index + GTK_BLUE];
+ if (m_alpha) {
+ int alphaval = qMax(bdata[index + GTK_BLUE] - wdata[index + GTK_BLUE],
+ bdata[index + GTK_GREEN] - wdata[index + GTK_GREEN]);
+ alphaval = qMax(alphaval, bdata[index + GTK_RED] - wdata[index + GTK_RED]) + 255;
+ bdata[index + QT_ALPHA] = alphaval;
+ }
+ bdata[index + QT_RED] = bdata[index + GTK_RED];
+ bdata[index + QT_GREEN] = bdata[index + GTK_GREEN];
+ bdata[index + QT_BLUE] = val;
+ }
+ QImage converted((const uchar*)bdata, rect.width(), rect.height(), m_alpha ?
+ QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32);
+
+ if (m_hflipped || m_vflipped) {
+ return QPixmap::fromImage(converted.mirrored(m_hflipped, m_vflipped));
+ } else {
+ // on raster graphicssystem we need to do a copy here, because
+ // we intend to deallocate the qimage bits shortly after...
+ return QPixmap::fromImage(converted.copy());
+ }
+}
+
+// This macro is responsible for painting any GtkStyle painting function onto a QPixmap
+#define DRAW_TO_CACHE(draw_func) \
+ if (rect.width() > QWIDGETSIZE_MAX || rect.height() > QWIDGETSIZE_MAX) \
+ return; \
+ QRect pixmapRect(0, 0, rect.width(), rect.height()); \
+ { \
+ GdkPixmap *pixmap = QGtkStylePrivate::gdk_pixmap_new((GdkDrawable*)(m_window->window), \
+ rect.width(), rect.height(), -1); \
+ if (!pixmap) \
+ return; \
+ style = QGtkStylePrivate::gtk_style_attach (style, m_window->window); \
+ QGtkStylePrivate::gdk_draw_rectangle(pixmap, m_alpha ? style->black_gc : *style->bg_gc, true, \
+ 0, 0, rect.width(), rect.height()); \
+ draw_func; \
+ GdkPixbuf *imgb = QGtkStylePrivate::gdk_pixbuf_new(GDK_COLORSPACE_RGB, true, 8, rect.width(), rect.height());\
+ if (!imgb) \
+ return; \
+ imgb = QGtkStylePrivate::gdk_pixbuf_get_from_drawable(imgb, pixmap, NULL, 0, 0, 0, 0, \
+ rect.width(), rect.height()); \
+ uchar* bdata = (uchar*)QGtkStylePrivate::gdk_pixbuf_get_pixels(imgb); \
+ if (m_alpha) { \
+ QGtkStylePrivate::gdk_draw_rectangle(pixmap, style->white_gc, true, 0, 0, rect.width(), rect.height()); \
+ draw_func; \
+ GdkPixbuf *imgw = QGtkStylePrivate::gdk_pixbuf_new(GDK_COLORSPACE_RGB, true, 8, rect. \
+ width(), rect.height()); \
+ if (!imgw) \
+ return; \
+ imgw = QGtkStylePrivate::gdk_pixbuf_get_from_drawable(imgw, pixmap, NULL, 0, 0, 0, 0, \
+ rect.width(), rect.height()); \
+ uchar* wdata = (uchar*)QGtkStylePrivate::gdk_pixbuf_get_pixels(imgw); \
+ cache = renderTheme(bdata, wdata, rect); \
+ QGtkStylePrivate::gdk_pixbuf_unref(imgw); \
+ } else { \
+ cache = renderTheme(bdata, 0, rect); \
+ } \
+ QGtkStylePrivate::gdk_drawable_unref(pixmap); \
+ QGtkStylePrivate::gdk_pixbuf_unref(imgb); \
+ }
+
+QGtkPainter::QGtkPainter(QPainter *_painter)
+ : m_window(QGtkStylePrivate::gtkWidget("GtkWindow"))
+ , m_painter(_painter)
+ , m_alpha(true)
+ , m_hflipped(false)
+ , m_vflipped(false)
+ , m_usePixmapCache(true)
+{}
+
+
+static QString uniqueName(const QString &key, GtkStateType state, GtkShadowType shadow,
+ const QSize &size, GtkWidget *widget = 0)
+{
+ // Note the widget arg should ideally use the widget path, though would compromise performance
+ QString tmp = key
+ % HexString<uint>(state)
+ % HexString<uint>(shadow)
+ % HexString<uint>(size.width())
+ % HexString<uint>(size.height())
+ % HexString<quint64>(quint64(widget));
+ return tmp;
+}
+
+
+GtkStateType QGtkPainter::gtkState(const QStyleOption *option)
+
+{
+ GtkStateType state = GTK_STATE_NORMAL;
+ if (!(option->state & QStyle::State_Enabled))
+ state = GTK_STATE_INSENSITIVE;
+ else if (option->state & QStyle::State_MouseOver)
+ state = GTK_STATE_PRELIGHT;
+
+ return state;
+}
+
+
+GtkStyle* QGtkPainter::getStyle(GtkWidget *gtkWidget)
+
+{
+ Q_ASSERT(gtkWidget);
+ GtkStyle* style = gtkWidget->style;
+ Q_ASSERT(style);
+ return style;
+}
+
+QPixmap QGtkPainter::getIcon(const char* iconName, GtkIconSize size)
+{
+ GtkStyle *style = QGtkStylePrivate::gtkStyle();
+ GtkIconSet* iconSet = QGtkStylePrivate::gtk_icon_factory_lookup_default (iconName);
+ GdkPixbuf* icon = QGtkStylePrivate::gtk_icon_set_render_icon(iconSet,
+ style,
+ GTK_TEXT_DIR_LTR,
+ GTK_STATE_NORMAL,
+ size,
+ NULL,
+ "button");
+ uchar* data = (uchar*)QGtkStylePrivate::gdk_pixbuf_get_pixels(icon);
+ int width = QGtkStylePrivate::gdk_pixbuf_get_width(icon);
+ int height = QGtkStylePrivate::gdk_pixbuf_get_height(icon);
+ QImage converted(width, height, QImage::Format_ARGB32);
+ uchar* tdata = (uchar*)converted.bits();
+
+ for ( int index = 0 ; index < height * width*4 ; index +=4 ) {
+ //int index = y * rowstride + x;
+ tdata[index + QT_RED] = data[index + GTK_RED];
+ tdata[index + QT_GREEN] = data[index + GTK_GREEN];
+ tdata[index + QT_BLUE] = data[index + GTK_BLUE];
+ tdata[index + QT_ALPHA] = data[index + GTK_ALPHA];
+ }
+
+ QGtkStylePrivate::gdk_pixbuf_unref(icon);
+
+ // should we free iconset?
+ return QPixmap::fromImage(converted);
+
+}
+
+// Note currently painted without alpha for performance reasons
+void QGtkPainter::paintBoxGap(GtkWidget *gtkWidget, const gchar* part,
+ const QRect &paintRect, GtkStateType state,
+ GtkShadowType shadow, GtkPositionType gap_side,
+ gint x, gint width,
+ GtkStyle *style)
+{
+ if (!paintRect.isValid())
+ return;
+
+ QPixmap cache;
+ QRect rect = paintRect;
+
+ // To avoid exhausting cache on large tabframes we cheat a bit by
+ // tiling the center part.
+
+ const int maxHeight = 256;
+ const int border = 16;
+ if (rect.height() > maxHeight && (gap_side == GTK_POS_TOP || gap_side == GTK_POS_BOTTOM))
+ rect.setHeight(2 * border + 1);
+
+ QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size(), gtkWidget)
+ % HexString<uchar>(gap_side)
+ % HexString<gint>(width)
+ % HexString<gint>(x);
+
+ if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
+ DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_box_gap (style,
+ pixmap,
+ state,
+ shadow,
+ NULL,
+ gtkWidget,
+ (gchar*)part,
+ 0, 0,
+ rect.width(),
+ rect.height(),
+ gap_side,
+ x,
+ width));
+ if (m_usePixmapCache)
+ QPixmapCache::insert(pixmapName, cache);
+ }
+ if (rect.size() != paintRect.size()) {
+ // We assume we can stretch the middle tab part
+ // Note: the side effect of this is that pinstripe patterns will get fuzzy
+ const QSize size = cache.size();
+ // top part
+ m_painter->drawPixmap(QRect(paintRect.left(), paintRect.top(),
+ paintRect.width(), border), cache,
+ QRect(0, 0, size.width(), border));
+
+ // tiled center part
+ QPixmap tilePart(cache.width(), 1);
+ QPainter scanLinePainter(&tilePart);
+ scanLinePainter.drawPixmap(QRect(0, 0, tilePart.width(), tilePart.height()), cache, QRect(0, border, size.width(), 1));
+ scanLinePainter.end();
+ m_painter->drawTiledPixmap(QRect(paintRect.left(), paintRect.top() + border,
+ paintRect.width(), paintRect.height() - 2*border), tilePart);
+
+ // bottom part
+ m_painter->drawPixmap(QRect(paintRect.left(), paintRect.top() + paintRect.height() - border,
+ paintRect.width(), border), cache,
+ QRect(0, size.height() - border, size.width(), border));
+ } else
+ m_painter->drawPixmap(paintRect.topLeft(), cache);
+}
+
+void QGtkPainter::paintBox(GtkWidget *gtkWidget, const gchar* part,
+ const QRect &paintRect, GtkStateType state,
+ GtkShadowType shadow, GtkStyle *style,
+ const QString &pmKey)
+{
+ if (!paintRect.isValid())
+ return;
+
+ QPixmap cache;
+ QRect rect = paintRect;
+
+ // To avoid exhausting cache on large tabframes we cheat a bit by
+ // tiling the center part.
+
+ const int maxHeight = 256;
+ const int maxArea = 256*512;
+ const int border = 32;
+ if (rect.height() > maxHeight && (rect.width()*rect.height() > maxArea))
+ rect.setHeight(2 * border + 1);
+
+ QString pixmapName = uniqueName(QLS(part), state, shadow,
+ rect.size(), gtkWidget) % pmKey;
+
+ if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
+ DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_box (style,
+ pixmap,
+ state,
+ shadow,
+ NULL,
+ gtkWidget,
+ part,
+ 0, 0,
+ rect.width(),
+ rect.height()));
+ if (m_usePixmapCache)
+ QPixmapCache::insert(pixmapName, cache);
+ }
+ if (rect.size() != paintRect.size()) {
+ // We assume we can stretch the middle tab part
+ // Note: the side effect of this is that pinstripe patterns will get fuzzy
+ const QSize size = cache.size();
+ // top part
+ m_painter->drawPixmap(QRect(paintRect.left(), paintRect.top(),
+ paintRect.width(), border), cache,
+ QRect(0, 0, size.width(), border));
+
+ // tiled center part
+ QPixmap tilePart(cache.width(), 1);
+ QPainter scanLinePainter(&tilePart);
+ scanLinePainter.drawPixmap(QRect(0, 0, tilePart.width(), tilePart.height()), cache, QRect(0, border, size.width(), 1));
+ scanLinePainter.end();
+ m_painter->drawTiledPixmap(QRect(paintRect.left(), paintRect.top() + border,
+ paintRect.width(), paintRect.height() - 2*border), tilePart);
+
+ // bottom part
+ m_painter->drawPixmap(QRect(paintRect.left(), paintRect.top() + paintRect.height() - border,
+ paintRect.width(), border), cache,
+ QRect(0, size.height() - border, size.width(), border));
+ } else
+ m_painter->drawPixmap(paintRect.topLeft(), cache);
+}
+
+void QGtkPainter::paintHline(GtkWidget *gtkWidget, const gchar* part,
+ const QRect &rect, GtkStateType state,
+ GtkStyle *style, int x1, int x2, int y,
+ const QString &pmKey)
+{
+ if (!rect.isValid())
+ return;
+
+ QPixmap cache;
+ QString pixmapName = uniqueName(QLS(part), state, GTK_SHADOW_NONE, rect.size(), gtkWidget)
+ % HexString<int>(x1)
+ % HexString<int>(x2)
+ % HexString<int>(y)
+ % pmKey;
+ if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
+ DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_hline (style,
+ pixmap,
+ state,
+ NULL,
+ gtkWidget,
+ part,
+ x1, x2, y));
+ if (m_usePixmapCache)
+ QPixmapCache::insert(pixmapName, cache);
+ }
+
+ m_painter->drawPixmap(rect.topLeft(), cache);
+}
+
+void QGtkPainter::paintVline(GtkWidget *gtkWidget, const gchar* part,
+ const QRect &rect, GtkStateType state,
+ GtkStyle *style, int y1, int y2, int x,
+ const QString &pmKey)
+{
+ if (!rect.isValid())
+ return;
+
+ QPixmap cache;
+ QString pixmapName = uniqueName(QLS(part), state, GTK_SHADOW_NONE, rect.size(), gtkWidget)
+ % HexString<int>(y1)
+ % HexString<int>(y2)
+ % HexString<int>(x)
+ % pmKey;
+
+ if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
+ DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_vline (style,
+ pixmap,
+ state,
+ NULL,
+ gtkWidget,
+ part,
+ y1, y2,
+ x));
+ if (m_usePixmapCache)
+ QPixmapCache::insert(pixmapName, cache);
+ }
+ m_painter->drawPixmap(rect.topLeft(), cache);
+}
+
+
+void QGtkPainter::paintExpander(GtkWidget *gtkWidget,
+ const gchar* part, const QRect &rect,
+ GtkStateType state, GtkExpanderStyle expander_state,
+ GtkStyle *style, const QString &pmKey)
+{
+ if (!rect.isValid())
+ return;
+
+ QPixmap cache;
+ QString pixmapName = uniqueName(QLS(part), state, GTK_SHADOW_NONE, rect.size(), gtkWidget)
+ % HexString<uchar>(expander_state)
+ % pmKey;
+
+ if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
+ DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_expander (style, pixmap,
+ state, NULL,
+ gtkWidget, part,
+ rect.width()/2,
+ rect.height()/2,
+ expander_state));
+ if (m_usePixmapCache)
+ QPixmapCache::insert(pixmapName, cache);
+ }
+
+ m_painter->drawPixmap(rect.topLeft(), cache);
+}
+
+void QGtkPainter::paintFocus(GtkWidget *gtkWidget, const gchar* part,
+ const QRect &rect, GtkStateType state,
+ GtkStyle *style, const QString &pmKey)
+{
+ if (!rect.isValid())
+ return;
+
+ QPixmap cache;
+ QString pixmapName = uniqueName(QLS(part), state, GTK_SHADOW_NONE, rect.size(), gtkWidget) % pmKey;
+ if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
+ DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_focus (style, pixmap, state, NULL,
+ gtkWidget,
+ part,
+ 0, 0,
+ rect.width(),
+ rect.height()));
+ if (m_usePixmapCache)
+ QPixmapCache::insert(pixmapName, cache);
+ }
+
+ m_painter->drawPixmap(rect.topLeft(), cache);
+}
+
+
+void QGtkPainter::paintResizeGrip(GtkWidget *gtkWidget, const gchar* part,
+ const QRect &rect, GtkStateType state,
+ GtkShadowType shadow, GdkWindowEdge edge,
+ GtkStyle *style, const QString &pmKey)
+{
+ if (!rect.isValid())
+ return;
+
+ QPixmap cache;
+ QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size(), gtkWidget) % pmKey;
+ if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
+ DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_resize_grip (style, pixmap, state,
+ NULL, gtkWidget,
+ part, edge, 0, 0,
+ rect.width(),
+ rect.height()));
+ if (m_usePixmapCache)
+ QPixmapCache::insert(pixmapName, cache);
+ }
+
+ m_painter->drawPixmap(rect.topLeft(), cache);
+}
+
+
+void QGtkPainter::paintArrow(GtkWidget *gtkWidget, const gchar* part,
+ const QRect &arrowrect, GtkArrowType arrow_type,
+ GtkStateType state, GtkShadowType shadow,
+ gboolean fill, GtkStyle *style, const QString &pmKey)
+{
+ QRect rect = m_cliprect.isValid() ? m_cliprect : arrowrect;
+ if (!rect.isValid())
+ return;
+
+ QPixmap cache;
+ QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size())
+ % HexString<uchar>(arrow_type)
+ % pmKey;
+
+ GdkRectangle gtkCliprect = {0, 0, rect.width(), rect.height()};
+ int xOffset = m_cliprect.isValid() ? arrowrect.x() - m_cliprect.x() : 0;
+ int yOffset = m_cliprect.isValid() ? arrowrect.y() - m_cliprect.y() : 0;
+ if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
+ DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_arrow (style, pixmap, state, shadow,
+ &gtkCliprect,
+ gtkWidget,
+ part,
+ arrow_type, fill,
+ xOffset, yOffset,
+ arrowrect.width(),
+ arrowrect.height()))
+ if (m_usePixmapCache)
+ QPixmapCache::insert(pixmapName, cache);
+ }
+
+ m_painter->drawPixmap(rect.topLeft(), cache);
+}
+
+
+void QGtkPainter::paintHandle(GtkWidget *gtkWidget, const gchar* part, const QRect &rect,
+ GtkStateType state, GtkShadowType shadow,
+ GtkOrientation orientation, GtkStyle *style)
+{
+ if (!rect.isValid())
+ return;
+
+ QPixmap cache;
+ QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size())
+ % HexString<uchar>(orientation);
+
+ if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
+ DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_handle (style,
+ pixmap,
+ state,
+ shadow,
+ NULL,
+ gtkWidget,
+ part, 0, 0,
+ rect.width(),
+ rect.height(),
+ orientation));
+ if (m_usePixmapCache)
+ QPixmapCache::insert(pixmapName, cache);
+ }
+ m_painter->drawPixmap(rect.topLeft(), cache);
+}
+
+
+void QGtkPainter::paintSlider(GtkWidget *gtkWidget, const gchar* part, const QRect &rect,
+ GtkStateType state, GtkShadowType shadow,
+ GtkStyle *style, GtkOrientation orientation,
+ const QString &pmKey)
+{
+ if (!rect.isValid())
+ return;
+
+ QPixmap cache;
+ QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size(), gtkWidget) % pmKey;
+ if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
+ DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_slider (style,
+ pixmap,
+ state,
+ shadow,
+ NULL,
+ gtkWidget,
+ part,
+ 0, 0,
+ rect.width(),
+ rect.height(),
+ orientation));
+ if (m_usePixmapCache)
+ QPixmapCache::insert(pixmapName, cache);
+ }
+ m_painter->drawPixmap(rect.topLeft(), cache);
+}
+
+
+void QGtkPainter::paintShadow(GtkWidget *gtkWidget, const gchar* part,
+ const QRect &rect, GtkStateType state,
+ GtkShadowType shadow, GtkStyle *style,
+ const QString &pmKey)
+
+{
+ if (!rect.isValid())
+ return;
+
+ QPixmap cache;
+ QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size()) % pmKey;
+ if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
+ DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_shadow(style, pixmap, state, shadow, NULL,
+ gtkWidget, part, 0, 0, rect.width(), rect.height()));
+ if (m_usePixmapCache)
+ QPixmapCache::insert(pixmapName, cache);
+ }
+ m_painter->drawPixmap(rect.topLeft(), cache);
+}
+
+void QGtkPainter::paintFlatBox(GtkWidget *gtkWidget, const gchar* part,
+ const QRect &rect, GtkStateType state,
+ GtkShadowType shadow, GtkStyle *style,
+ const QString &pmKey)
+{
+ if (!rect.isValid())
+ return;
+ QPixmap cache;
+ QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size()) % pmKey;
+ if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
+ DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_flat_box (style,
+ pixmap,
+ state,
+ shadow,
+ NULL,
+ gtkWidget,
+ part, 0, 0,
+ rect.width(),
+ rect.height()));
+ if (m_usePixmapCache)
+ QPixmapCache::insert(pixmapName, cache);
+ }
+ m_painter->drawPixmap(rect.topLeft(), cache);
+}
+
+void QGtkPainter::paintExtention(GtkWidget *gtkWidget,
+ const gchar *part, const QRect &rect,
+ GtkStateType state, GtkShadowType shadow,
+ GtkPositionType gap_pos, GtkStyle *style)
+{
+ if (!rect.isValid())
+ return;
+
+ QPixmap cache;
+ QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size(), gtkWidget)
+ % HexString<uchar>(gap_pos);
+
+ if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
+ DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_extension (style, pixmap, state, shadow,
+ NULL, gtkWidget,
+ (gchar*)part, 0, 0,
+ rect.width(),
+ rect.height(),
+ gap_pos));
+ if (m_usePixmapCache)
+ QPixmapCache::insert(pixmapName, cache);
+ }
+
+ m_painter->drawPixmap(rect.topLeft(), cache);
+}
+
+void QGtkPainter::paintOption(GtkWidget *gtkWidget, const QRect &radiorect,
+ GtkStateType state, GtkShadowType shadow,
+ GtkStyle *style, const QString &detail)
+
+{
+ QRect rect = m_cliprect.isValid() ? m_cliprect : radiorect;
+ if (!rect.isValid())
+ return;
+
+ QPixmap cache;
+ QString pixmapName = uniqueName(detail, state, shadow, rect.size());
+ GdkRectangle gtkCliprect = {0, 0, rect.width(), rect.height()};
+ int xOffset = m_cliprect.isValid() ? radiorect.x() - m_cliprect.x() : 0;
+ int yOffset = m_cliprect.isValid() ? radiorect.y() - m_cliprect.y() : 0;
+ if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
+ DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_option(style, pixmap,
+ state, shadow,
+ &gtkCliprect,
+ gtkWidget,
+ detail.toLatin1(),
+ xOffset, yOffset,
+ radiorect.width(),
+ radiorect.height()));
+
+ if (m_usePixmapCache)
+ QPixmapCache::insert(pixmapName, cache);
+ }
+
+ m_painter->drawPixmap(rect.topLeft(), cache);
+}
+
+void QGtkPainter::paintCheckbox(GtkWidget *gtkWidget, const QRect &checkrect,
+ GtkStateType state, GtkShadowType shadow,
+ GtkStyle *style, const QString &detail)
+
+{
+ QRect rect = m_cliprect.isValid() ? m_cliprect : checkrect;
+ if (!rect.isValid())
+ return;
+
+ QPixmap cache;
+ QString pixmapName = uniqueName(detail, state, shadow, rect.size());
+ GdkRectangle gtkCliprect = {0, 0, rect.width(), rect.height()};
+ int xOffset = m_cliprect.isValid() ? checkrect.x() - m_cliprect.x() : 0;
+ int yOffset = m_cliprect.isValid() ? checkrect.y() - m_cliprect.y() : 0;
+ if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
+ DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_check (style,
+ pixmap,
+ state,
+ shadow,
+ &gtkCliprect,
+ gtkWidget,
+ detail.toLatin1(),
+ xOffset, yOffset,
+ checkrect.width(),
+ checkrect.height()));
+ if (m_usePixmapCache)
+ QPixmapCache::insert(pixmapName, cache);
+ }
+
+ m_painter->drawPixmap(rect.topLeft(), cache);
+}
+
+QT_END_NAMESPACE
+
+#endif //!defined(QT_NO_STYLE_GTK)
diff --git a/src/widgets/styles/qgtkpainter_p.h b/src/widgets/styles/qgtkpainter_p.h
new file mode 100644
index 0000000000..a9d4dc0dcd
--- /dev/null
+++ b/src/widgets/styles/qgtkpainter_p.h
@@ -0,0 +1,129 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGTKPAINTER_H
+#define QGTKPAINTER_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qglobal.h>
+#if !defined(QT_NO_STYLE_GTK)
+
+#include <QtWidgets/QCleanlooksStyle>
+#include <QtGui/QPainter>
+#include <QtGui/QPalette>
+#include <QtGui/QFont>
+#include <private/qgtkstyle_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QGtkPainter
+{
+
+public:
+ QGtkPainter(QPainter *painter);
+ GtkStyle *getStyle(GtkWidget *gtkWidget);
+ GtkStateType gtkState(const QStyleOption *option);
+
+ void setAlphaSupport(bool value) { m_alpha = value; }
+ void setClipRect(const QRect &rect) { m_cliprect = rect; }
+ void setFlipHorizontal(bool value) { m_hflipped = value; }
+ void setFlipVertical(bool value) { m_vflipped = value; }
+ void setUsePixmapCache(bool value) { m_usePixmapCache = value; }
+
+ void paintBoxGap(GtkWidget *gtkWidget, const gchar* part, const QRect &rect,
+ GtkStateType state, GtkShadowType shadow, GtkPositionType gap_side, gint x,
+ gint width, GtkStyle *style);
+ void paintBox(GtkWidget *gtkWidget, const gchar* part,
+ const QRect &rect, GtkStateType state, GtkShadowType shadow, GtkStyle *style,
+ const QString &pmKey = QString());
+ void paintHline(GtkWidget *gtkWidget, const gchar* part, const QRect &rect, GtkStateType state, GtkStyle *style,
+ int x1, int x2, int y, const QString &pmKey = QString());
+ void paintVline(GtkWidget *gtkWidget, const gchar* part, const QRect &rect, GtkStateType state, GtkStyle *style,
+ int y1, int y2, int x, const QString &pmKey = QString());
+ void paintExpander(GtkWidget *gtkWidget, const gchar* part, const QRect &rect, GtkStateType state,
+ GtkExpanderStyle expander_state, GtkStyle *style, const QString &pmKey = QString());
+ void paintFocus(GtkWidget *gtkWidget, const gchar* part, const QRect &rect, GtkStateType state, GtkStyle *style,
+ const QString &pmKey = QString());
+ void paintResizeGrip(GtkWidget *gtkWidget, const gchar* part, const QRect &rect, GtkStateType state, GtkShadowType shadow,
+ GdkWindowEdge edge, GtkStyle *style, const QString &pmKey = QString());
+ void paintArrow(GtkWidget *gtkWidget, const gchar* part, const QRect &arrowrect, GtkArrowType arrow_type, GtkStateType state, GtkShadowType shadow,
+ gboolean fill, GtkStyle *style, const QString &pmKey = QString());
+ void paintHandle(GtkWidget *gtkWidget, const gchar* part, const QRect &rect,
+ GtkStateType state, GtkShadowType shadow, GtkOrientation orientation, GtkStyle *style);
+ void paintSlider(GtkWidget *gtkWidget, const gchar* part, const QRect &rect, GtkStateType state, GtkShadowType shadow,
+ GtkStyle *style, GtkOrientation orientation, const QString &pmKey = QString());
+ void paintShadow(GtkWidget *gtkWidget, const gchar* part, const QRect &rect, GtkStateType state, GtkShadowType shadow,
+ GtkStyle *style, const QString &pmKey = QString());
+ void paintFlatBox(GtkWidget *gtkWidget, const gchar* part, const QRect &rect, GtkStateType state, GtkShadowType shadow, GtkStyle *style, const QString & = QString());
+ void paintExtention(GtkWidget *gtkWidget, const gchar *part, const QRect &rect, GtkStateType state, GtkShadowType shadow,
+ GtkPositionType gap_pos, GtkStyle *style);
+ void paintOption(GtkWidget *gtkWidget, const QRect &rect, GtkStateType state, GtkShadowType shadow, GtkStyle *style, const QString &detail);
+ void paintCheckbox(GtkWidget *gtkWidget, const QRect &rect, GtkStateType state, GtkShadowType shadow, GtkStyle *style, const QString &detail);
+
+ static QPixmap getIcon(const char* iconName, GtkIconSize size = GTK_ICON_SIZE_BUTTON);
+private:
+ QPixmap renderTheme(uchar *bdata, uchar *wdata, const QRect&);
+
+ GtkWidget *m_window;
+ QPainter *m_painter;
+ bool m_alpha;
+ bool m_hflipped;
+ bool m_vflipped;
+ bool m_usePixmapCache;
+ QRect m_cliprect;
+
+};
+
+QT_END_NAMESPACE
+
+#endif //!defined(QT_NO_STYLE_QGTK)
+
+#endif // QGTKPAINTER_H
diff --git a/src/widgets/styles/qgtkstyle.cpp b/src/widgets/styles/qgtkstyle.cpp
new file mode 100644
index 0000000000..32e04928da
--- /dev/null
+++ b/src/widgets/styles/qgtkstyle.cpp
@@ -0,0 +1,3560 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "qgtkstyle.h"
+
+#if !defined(QT_NO_STYLE_GTK)
+
+#include <private/qapplication_p.h>
+#include <QtCore/QLibrary>
+#include <QtCore/QSettings>
+#include <QtWidgets/QDialogButtonBox>
+#include <QtWidgets/QStatusBar>
+#include <QtWidgets/QLineEdit>
+#include <QtWidgets/QWidget>
+#include <QtWidgets/QListView>
+#include <QtWidgets/QApplication>
+#include <QtWidgets/QStyleOption>
+#include <QtWidgets/QPushButton>
+#include <QtGui/QPainter>
+#include <QtWidgets/QMainWindow>
+#include <QtWidgets/QToolBar>
+#include <QtWidgets/QHeaderView>
+#include <QtWidgets/QMenuBar>
+#include <QtWidgets/QComboBox>
+#include <QtWidgets/QSpinBox>
+#include <QtWidgets/QScrollBar>
+#include <QtWidgets/QAbstractButton>
+#include <QtWidgets/QToolButton>
+#include <QtWidgets/QGroupBox>
+#include <QtWidgets/QRadioButton>
+#include <QtWidgets/QCheckBox>
+#include <QtWidgets/QTreeView>
+#include <QtWidgets/QStyledItemDelegate>
+#include <qpixmapcache.h>
+#undef signals // Collides with GTK stymbols
+#include <private/qgtkpainter_p.h>
+#include <private/qstylehelper_p.h>
+#include <private/qgtkstyle_p.h>
+#include <private/qcleanlooksstyle_p.h>
+
+
+QT_BEGIN_NAMESPACE
+
+static const char * const dock_widget_close_xpm[] =
+ {
+ "11 13 5 1",
+ " c None",
+ ". c #D5CFCB",
+ "+ c #6C6A67",
+ "@ c #6C6A67",
+ "$ c #B5B0AC",
+ " ",
+ " @@@@@@@@@ ",
+ "@+ +@",
+ "@ +@ @+ @",
+ "@ @@@ @@@ @",
+ "@ @@@@@ @",
+ "@ @@@ @",
+ "@ @@@@@ @",
+ "@ @@@ @@@ @",
+ "@ +@ @+ @",
+ "@+ +@",
+ " @@@@@@@@@ ",
+ " "
+ };
+
+static const char * const dock_widget_restore_xpm[] =
+ {
+ "11 13 5 1",
+ " c None",
+ ". c #D5CFCB",
+ "+ c #6C6A67",
+ "@ c #6C6A67",
+ "# c #6C6A67",
+ " ",
+ " @@@@@@@@@ ",
+ "@+ +@",
+ "@ #@@@# @",
+ "@ @ @ @",
+ "@ #@@@# @ @",
+ "@ @ @ @ @",
+ "@ @ @@@ @",
+ "@ @ @ @",
+ "@ #@@@@ @",
+ "@+ +@",
+ " @@@@@@@@@ ",
+ " "
+ };
+
+static const int groupBoxBottomMargin = 2; // space below the groupbox
+static const int groupBoxTitleMargin = 6; // space between contents and title
+static const int groupBoxTopMargin = 2;
+
+/*!
+ Returns the configuration string for \a value.
+ Returns \a fallback if \a value is not found.
+ */
+QString QGtkStyle::getGConfString(const QString &value, const QString &fallback)
+{
+ return QGtkStylePrivate::getGConfString(value, fallback);
+}
+
+/*!
+ Returns the configuration boolean for \a key.
+ Returns \a fallback if \a key is not found.
+ */
+bool QGtkStyle::getGConfBool(const QString &key, bool fallback)
+{
+ return QGtkStylePrivate::getGConfBool(key, fallback);
+}
+
+static QColor mergedColors(const QColor &colorA, const QColor &colorB, int factor = 50)
+{
+ const int maxFactor = 100;
+ QColor tmp = colorA;
+ tmp.setRed((tmp.red() * factor) / maxFactor + (colorB.red() * (maxFactor - factor)) / maxFactor);
+ tmp.setGreen((tmp.green() * factor) / maxFactor + (colorB.green() * (maxFactor - factor)) / maxFactor);
+ tmp.setBlue((tmp.blue() * factor) / maxFactor + (colorB.blue() * (maxFactor - factor)) / maxFactor);
+ return tmp;
+}
+
+static GdkColor fromQColor(const QColor &color)
+{
+ GdkColor retval;
+ retval.red = color.red() * 255;
+ retval.green = color.green() * 255;
+ retval.blue = color.blue() * 255;
+ return retval;
+}
+
+/*!
+ \class QGtkStyle
+ \brief The QGtkStyle class provides a widget style rendered by GTK+
+ \since 4.5
+
+ The QGtkStyle style provides a look and feel that integrates well
+ into GTK-based desktop environments such as the XFCe and GNOME.
+
+ It does this by making use of the GTK+ theme engine, ensuring
+ that Qt applications look and feel native on these platforms.
+
+ Note: The style requires GTK+ version 2.10 or later.
+ The Qt3-based "Qt" GTK+ theme engine will not work with QGtkStyle.
+
+ \sa {Cleanlooks Style Widget Gallery}, QWindowsXPStyle, QMacStyle, QWindowsStyle,
+ QCDEStyle, QMotifStyle, QPlastiqueStyle, QCleanlooksStyle
+*/
+
+/*!
+ Constructs a QGtkStyle object.
+*/
+QGtkStyle::QGtkStyle()
+ : QCleanlooksStyle(*new QGtkStylePrivate)
+{
+ Q_D(QGtkStyle);
+ d->init();
+}
+
+/*!
+ \internal
+
+ Constructs a QGtkStyle object.
+*/
+QGtkStyle::QGtkStyle(QGtkStylePrivate &dd)
+ : QCleanlooksStyle(dd)
+{
+ Q_D(QGtkStyle);
+ d->init();
+}
+
+
+/*!
+ Destroys the QGtkStyle object.
+*/
+QGtkStyle::~QGtkStyle()
+{
+}
+
+/*!
+ \reimp
+*/
+QPalette QGtkStyle::standardPalette() const
+{
+ Q_D(const QGtkStyle);
+
+ QPalette palette = QCleanlooksStyle::standardPalette();
+ if (d->isThemeAvailable()) {
+ GtkStyle *style = d->gtkStyle();
+ GtkWidget *gtkButton = d->gtkWidget("GtkButton");
+ GtkWidget *gtkEntry = d->getTextColorWidget();
+ GdkColor gdkBg, gdkBase, gdkText, gdkForeground, gdkSbg, gdkSfg, gdkaSbg, gdkaSfg;
+ QColor bg, base, text, fg, highlight, highlightText, inactiveHighlight, inactiveHighlightedTExt;
+ gdkBg = style->bg[GTK_STATE_NORMAL];
+ gdkForeground = gtkButton->style->fg[GTK_STATE_NORMAL];
+
+ // Our base and selected color is primarily used for text
+ // so we assume a gtkEntry will have the most correct value
+ gdkBase = gtkEntry->style->base[GTK_STATE_NORMAL];
+ gdkText = gtkEntry->style->text[GTK_STATE_NORMAL];
+ gdkSbg = gtkEntry->style->base[GTK_STATE_SELECTED];
+ gdkSfg = gtkEntry->style->text[GTK_STATE_SELECTED];
+
+ // The ACTIVE base color is really used for inactive windows
+ gdkaSbg = gtkEntry->style->base[GTK_STATE_ACTIVE];
+ gdkaSfg = gtkEntry->style->text[GTK_STATE_ACTIVE];
+
+ bg = QColor(gdkBg.red>>8, gdkBg.green>>8, gdkBg.blue>>8);
+ text = QColor(gdkText.red>>8, gdkText.green>>8, gdkText.blue>>8);
+ fg = QColor(gdkForeground.red>>8, gdkForeground.green>>8, gdkForeground.blue>>8);
+ base = QColor(gdkBase.red>>8, gdkBase.green>>8, gdkBase.blue>>8);
+ highlight = QColor(gdkSbg.red>>8, gdkSbg.green>>8, gdkSbg.blue>>8);
+ highlightText = QColor(gdkSfg.red>>8, gdkSfg.green>>8, gdkSfg.blue>>8);
+ inactiveHighlight = QColor(gdkaSbg.red>>8, gdkaSbg.green>>8, gdkaSbg.blue>>8);
+ inactiveHighlightedTExt = QColor(gdkaSfg.red>>8, gdkaSfg.green>>8, gdkaSfg.blue>>8);
+
+ palette.setColor(QPalette::HighlightedText, highlightText);
+
+
+ palette.setColor(QPalette::Light, bg.lighter(125));
+ palette.setColor(QPalette::Shadow, bg.darker(130));
+ palette.setColor(QPalette::Dark, bg.darker(120));
+ palette.setColor(QPalette::Text, text);
+ palette.setColor(QPalette::WindowText, fg);
+ palette.setColor(QPalette::ButtonText, fg);
+ palette.setColor(QPalette::Base, base);
+
+ QColor alternateRowColor = palette.base().color().lighter(93); // ref gtkstyle.c draw_flat_box
+ GtkWidget *gtkTreeView = d->gtkWidget("GtkTreeView");
+ GdkColor *gtkAltBase = NULL;
+ d->gtk_widget_style_get(gtkTreeView, "odd-row-color", &gtkAltBase, NULL);
+ if (gtkAltBase) {
+ alternateRowColor = QColor(gtkAltBase->red>>8, gtkAltBase->green>>8, gtkAltBase->blue>>8);
+ d->gdk_color_free(gtkAltBase);
+ }
+ palette.setColor(QPalette::AlternateBase, alternateRowColor);
+
+ palette.setColor(QPalette::Window, bg);
+ palette.setColor(QPalette::Button, bg);
+ palette.setColor(QPalette::Background, bg);
+ QColor disabled((fg.red() + bg.red()) / 2,
+ (fg.green() + bg.green())/ 2,
+ (fg.blue() + bg.blue()) / 2);
+ palette.setColor(QPalette::Disabled, QPalette::Text, disabled);
+ palette.setColor(QPalette::Disabled, QPalette::WindowText, disabled);
+ palette.setColor(QPalette::Disabled, QPalette::Foreground, disabled);
+ palette.setColor(QPalette::Disabled, QPalette::ButtonText, disabled);
+ palette.setColor(QPalette::Highlight, highlight);
+ // calculate disabled colors by removing saturation
+ highlight.setHsv(highlight.hue(), 0, highlight.value(), highlight.alpha());
+ highlightText.setHsv(highlightText.hue(), 0, highlightText.value(), highlightText.alpha());
+ palette.setColor(QPalette::Disabled, QPalette::Highlight, highlight);
+ palette.setColor(QPalette::Disabled, QPalette::HighlightedText, highlightText);
+
+ palette.setColor(QPalette::Inactive, QPalette::HighlightedText, inactiveHighlightedTExt);
+ palette.setColor(QPalette::Inactive, QPalette::Highlight, inactiveHighlight);
+
+ style = d->gtk_rc_get_style_by_paths(d->gtk_settings_get_default(), "gtk-tooltips", "GtkWindow",
+ d->gtk_window_get_type());
+ if (style) {
+ gdkText = style->fg[GTK_STATE_NORMAL];
+ text = QColor(gdkText.red>>8, gdkText.green>>8, gdkText.blue>>8);
+ palette.setColor(QPalette::ToolTipText, text);
+ }
+ }
+ return palette;
+}
+
+/*!
+ \reimp
+*/
+void QGtkStyle::polish(QPalette &palette)
+{
+ Q_D(QGtkStyle);
+
+ // QCleanlooksStyle will alter the palette, hence we do
+ // not want to polish the palette unless we are using it as
+ // the fallback
+ if (!d->isThemeAvailable())
+ QCleanlooksStyle::polish(palette);
+ else
+ palette = palette.resolve(standardPalette());
+}
+
+/*!
+ \reimp
+*/
+void QGtkStyle::polish(QApplication *app)
+{
+ Q_D(QGtkStyle);
+
+ QCleanlooksStyle::polish(app);
+ // Custom fonts and palettes with QtConfig are intentionally
+ // not supported as these should be entirely determined by
+ // current Gtk settings
+ if (app->desktopSettingsAware() && d->isThemeAvailable()) {
+ QApplicationPrivate::setSystemPalette(standardPalette());
+ QApplicationPrivate::setSystemFont(d->getThemeFont());
+ d->applyCustomPaletteHash();
+ if (!d->isKDE4Session()) {
+ qt_filedialog_open_filename_hook = &QGtkStylePrivate::openFilename;
+ qt_filedialog_save_filename_hook = &QGtkStylePrivate::saveFilename;
+ qt_filedialog_open_filenames_hook = &QGtkStylePrivate::openFilenames;
+ qt_filedialog_existing_directory_hook = &QGtkStylePrivate::openDirectory;
+ qApp->installEventFilter(&d->filter);
+ }
+ }
+}
+
+/*!
+ \reimp
+*/
+void QGtkStyle::unpolish(QApplication *app)
+{
+ Q_D(QGtkStyle);
+
+ QCleanlooksStyle::unpolish(app);
+ QPixmapCache::clear();
+
+ if (app->desktopSettingsAware() && d->isThemeAvailable()
+ && !d->isKDE4Session()) {
+ qt_filedialog_open_filename_hook = 0;
+ qt_filedialog_save_filename_hook = 0;
+ qt_filedialog_open_filenames_hook = 0;
+ qt_filedialog_existing_directory_hook = 0;
+ qApp->removeEventFilter(&d->filter);
+ }
+}
+
+/*!
+ \reimp
+*/
+
+void QGtkStyle::polish(QWidget *widget)
+{
+ Q_D(QGtkStyle);
+
+ QCleanlooksStyle::polish(widget);
+ if (!d->isThemeAvailable())
+ return;
+ if (qobject_cast<QAbstractButton*>(widget)
+ || qobject_cast<QToolButton*>(widget)
+ || qobject_cast<QComboBox*>(widget)
+ || qobject_cast<QGroupBox*>(widget)
+ || qobject_cast<QScrollBar*>(widget)
+ || qobject_cast<QSlider*>(widget)
+ || qobject_cast<QAbstractSpinBox*>(widget)
+ || qobject_cast<QSpinBox*>(widget)
+ || qobject_cast<QHeaderView*>(widget))
+ widget->setAttribute(Qt::WA_Hover);
+ else if (QTreeView *tree = qobject_cast<QTreeView *> (widget))
+ tree->viewport()->setAttribute(Qt::WA_Hover);
+}
+
+/*!
+ \reimp
+*/
+void QGtkStyle::unpolish(QWidget *widget)
+{
+ QCleanlooksStyle::unpolish(widget);
+}
+
+/*!
+ \reimp
+*/
+int QGtkStyle::pixelMetric(PixelMetric metric,
+ const QStyleOption *option,
+ const QWidget *widget) const
+{
+ Q_D(const QGtkStyle);
+
+ if (!d->isThemeAvailable())
+ return QCleanlooksStyle::pixelMetric(metric, option, widget);
+
+ switch (metric) {
+ case PM_DefaultFrameWidth:
+ if (qobject_cast<const QFrame*>(widget)) {
+ if (GtkStyle *style =
+ d->gtk_rc_get_style_by_paths(d->gtk_settings_get_default(),
+ "*.GtkScrolledWindow",
+ "*.GtkScrolledWindow",
+ d->gtk_window_get_type()))
+ return qMax(style->xthickness, style->ythickness);
+ }
+ return 2;
+
+ case PM_MenuButtonIndicator:
+ return 20;
+
+ case PM_TabBarBaseOverlap:
+ return 1;
+
+ case PM_ToolBarSeparatorExtent:
+ return 11;
+
+ case PM_ToolBarFrameWidth:
+ return 1;
+
+ case PM_ToolBarItemSpacing:
+ return 0;
+
+ case PM_ButtonShiftHorizontal: {
+ GtkWidget *gtkButton = d->gtkWidget("GtkButton");
+ guint horizontal_shift;
+ d->gtk_widget_style_get(gtkButton, "child-displacement-x", &horizontal_shift, NULL);
+ return horizontal_shift;
+ }
+
+ case PM_ButtonShiftVertical: {
+ GtkWidget *gtkButton = d->gtkWidget("GtkButton");
+ guint vertical_shift;
+ d->gtk_widget_style_get(gtkButton, "child-displacement-y", &vertical_shift, NULL);
+ return vertical_shift;
+ }
+
+ case PM_MenuBarPanelWidth:
+ return 0;
+
+ case PM_MenuPanelWidth: {
+ GtkWidget *gtkMenu = d->gtkWidget("GtkMenu");
+ guint horizontal_padding = 0;
+ // horizontal-padding is used by Maemo to get thicker borders
+ if (!d->gtk_check_version(2, 10, 0))
+ d->gtk_widget_style_get(gtkMenu, "horizontal-padding", &horizontal_padding, NULL);
+ int padding = qMax<int>(gtkMenu->style->xthickness, horizontal_padding);
+ return padding;
+ }
+
+ case PM_ButtonIconSize: {
+ int retVal = 24;
+ GtkSettings *settings = d->gtk_settings_get_default();
+ gchararray icon_sizes;
+ g_object_get(settings, "gtk-icon-sizes", &icon_sizes, NULL);
+ QStringList values = QString(QLS(icon_sizes)).split(QLatin1Char(':'));
+ g_free(icon_sizes);
+ QChar splitChar(QLatin1Char(','));
+ foreach (const QString &value, values) {
+ if (value.startsWith(QLS("gtk-button="))) {
+ QString iconSize = value.right(value.size() - 11);
+
+ if (iconSize.contains(splitChar))
+ retVal = iconSize.split(splitChar)[0].toInt();
+ break;
+ }
+ }
+ return retVal;
+ }
+
+ case PM_MenuVMargin:
+
+ case PM_MenuHMargin:
+ return 0;
+
+ case PM_DockWidgetTitleMargin:
+ return 0;
+
+ case PM_DockWidgetTitleBarButtonMargin:
+ return 5;
+
+ case PM_TabBarTabVSpace:
+ return 12;
+
+ case PM_TabBarTabHSpace:
+ return 14;
+
+ case PM_TabBarTabShiftVertical:
+ return 2;
+
+ case PM_ToolBarHandleExtent:
+ return 9;
+
+ case PM_SplitterWidth:
+ return 6;
+
+ case PM_SliderThickness:
+ case PM_SliderControlThickness: {
+ GtkWidget *gtkScale = d->gtkWidget("GtkHScale");
+ gint val;
+ d->gtk_widget_style_get(gtkScale, "slider-width", &val, NULL);
+ if (metric == PM_SliderControlThickness)
+ return val + 2*gtkScale->style->ythickness;
+ return val;
+ }
+
+ case PM_ScrollBarExtent: {
+ gint sliderLength;
+ gint trough_border;
+ GtkWidget *hScrollbar = d->gtkWidget("GtkHScrollbar");
+ d->gtk_widget_style_get(hScrollbar,
+ "trough-border", &trough_border,
+ "slider-width", &sliderLength,
+ NULL);
+ return sliderLength + trough_border*2;
+ }
+
+ case PM_ScrollBarSliderMin:
+ return 34;
+
+ case PM_SliderLength:
+ gint val;
+ d->gtk_widget_style_get(d->gtkWidget("GtkHScale"), "slider-length", &val, NULL);
+ return val;
+
+ case PM_ExclusiveIndicatorWidth:
+ case PM_ExclusiveIndicatorHeight:
+ case PM_IndicatorWidth:
+ case PM_IndicatorHeight: {
+ GtkWidget *gtkCheckButton = d->gtkWidget("GtkCheckButton");
+ gint size, spacing;
+ d->gtk_widget_style_get(gtkCheckButton, "indicator-spacing", &spacing, "indicator-size", &size, NULL);
+ return size + 2 * spacing;
+ }
+
+ case PM_MenuBarVMargin: {
+ GtkWidget *gtkMenubar = d->gtkWidget("GtkMenuBar");
+ return qMax(0, gtkMenubar->style->ythickness);
+ }
+ case PM_ScrollView_ScrollBarSpacing:
+ {
+ gint spacing = 3;
+ GtkWidget *gtkScrollWindow = d->gtkWidget("GtkScrolledWindow");
+ Q_ASSERT(gtkScrollWindow);
+ d->gtk_widget_style_get(gtkScrollWindow, "scrollbar-spacing", &spacing, NULL);
+ return spacing;
+ }
+ case PM_SubMenuOverlap: {
+ gint offset = 0;
+ GtkWidget *gtkMenu = d->gtkWidget("GtkMenu");
+ d->gtk_widget_style_get(gtkMenu, "horizontal-offset", &offset, NULL);
+ return offset;
+ }
+ default:
+ return QCleanlooksStyle::pixelMetric(metric, option, widget);
+ }
+}
+
+/*!
+ \reimp
+*/
+int QGtkStyle::styleHint(StyleHint hint, const QStyleOption *option, const QWidget *widget,
+
+ QStyleHintReturn *returnData = 0) const
+{
+ Q_D(const QGtkStyle);
+
+ if (!d->isThemeAvailable())
+ return QCleanlooksStyle::styleHint(hint, option, widget, returnData);
+
+ switch (hint) {
+
+ case SH_DialogButtonLayout: {
+ int ret = QDialogButtonBox::GnomeLayout;
+ gboolean alternateOrder = 0;
+ GtkSettings *settings = d->gtk_settings_get_default();
+ g_object_get(settings, "gtk-alternative-button-order", &alternateOrder, NULL);
+
+ if (alternateOrder)
+ ret = QDialogButtonBox::WinLayout;
+
+ return ret;
+ }
+
+ break;
+
+ case SH_ToolButtonStyle:
+ {
+ if (d->isKDE4Session())
+ return QCleanlooksStyle::styleHint(hint, option, widget, returnData);
+ GtkWidget *gtkToolbar = d->gtkWidget("GtkToolbar");
+ GtkToolbarStyle toolbar_style = GTK_TOOLBAR_ICONS;
+ g_object_get(gtkToolbar, "toolbar-style", &toolbar_style, NULL);
+ switch (toolbar_style) {
+ case GTK_TOOLBAR_TEXT:
+ return Qt::ToolButtonTextOnly;
+ case GTK_TOOLBAR_BOTH:
+ return Qt::ToolButtonTextUnderIcon;
+ case GTK_TOOLBAR_BOTH_HORIZ:
+ return Qt::ToolButtonTextBesideIcon;
+ case GTK_TOOLBAR_ICONS:
+ default:
+ return Qt::ToolButtonIconOnly;
+ }
+ }
+ break;
+ case SH_SpinControls_DisableOnBounds:
+ return int(true);
+
+ case SH_DitherDisabledText:
+ return int(false);
+
+ case SH_ComboBox_Popup: {
+ GtkWidget *gtkComboBox = d->gtkWidget("GtkComboBox");
+ gboolean appears_as_list;
+ d->gtk_widget_style_get((GtkWidget*)gtkComboBox, "appears-as-list", &appears_as_list, NULL);
+ return appears_as_list ? 0 : 1;
+ }
+
+ case SH_MenuBar_AltKeyNavigation:
+ return int(false);
+
+ case SH_EtchDisabledText:
+ return int(false);
+
+ case SH_Menu_SubMenuPopupDelay: {
+ gint delay = 225;
+ GtkSettings *settings = d->gtk_settings_get_default();
+ g_object_get(settings, "gtk-menu-popup-delay", &delay, NULL);
+ return delay;
+ }
+
+ case SH_ScrollView_FrameOnlyAroundContents: {
+ gboolean scrollbars_within_bevel = false;
+ if (widget && widget->isWindow())
+ scrollbars_within_bevel = true;
+ else if (!d->gtk_check_version(2, 12, 0)) {
+ GtkWidget *gtkScrollWindow = d->gtkWidget("GtkScrolledWindow");
+ d->gtk_widget_style_get(gtkScrollWindow, "scrollbars-within-bevel", &scrollbars_within_bevel, NULL);
+ }
+ return !scrollbars_within_bevel;
+ }
+
+ case SH_DialogButtonBox_ButtonsHaveIcons: {
+ static bool buttonsHaveIcons = d->getGConfBool(QLS("/desktop/gnome/interface/buttons_have_icons"));
+ return buttonsHaveIcons;
+ }
+
+ case SH_UnderlineShortcut: {
+ gboolean underlineShortcut = true;
+ if (!d->gtk_check_version(2, 12, 0)) {
+ GtkSettings *settings = d->gtk_settings_get_default();
+ g_object_get(settings, "gtk-enable-mnemonics", &underlineShortcut, NULL);
+ }
+ return underlineShortcut;
+ }
+
+ default:
+ return QCleanlooksStyle::styleHint(hint, option, widget, returnData);
+ }
+}
+
+/*!
+ \reimp
+*/
+void QGtkStyle::drawPrimitive(PrimitiveElement element,
+ const QStyleOption *option,
+ QPainter *painter,
+ const QWidget *widget) const
+{
+ Q_D(const QGtkStyle);
+
+ if (!d->isThemeAvailable()) {
+ QCleanlooksStyle::drawPrimitive(element, option, painter, widget);
+ return;
+ }
+
+ GtkStyle* style = d->gtkStyle();
+ QGtkPainter gtkPainter(painter);
+
+ switch (element) {
+ case PE_Frame: {
+ if (widget && widget->inherits("QComboBoxPrivateContainer")){
+ QStyleOption copy = *option;
+ copy.state |= State_Raised;
+ proxy()->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 = proxy()->pixelMetric(PM_DefaultFrameWidth, option, widget);
+ const QString pmKey = QLatin1Literal("windowframe") % HexString<uint>(option->state);
+
+ QPixmap pixmap;
+ QRect pmRect(QPoint(0,0), QSize(pmSize, pmSize));
+
+ // Only draw through style once
+ if (!QPixmapCache::find(pmKey, pixmap)) {
+ 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 = d->gtk_rc_get_style_by_paths(d->gtk_settings_get_default(),
+ "*.GtkScrolledWindow", "*.GtkScrolledWindow", d->gtk_window_get_type());
+ if (style)
+ gtkFramePainter.paintShadow(d->gtkWidget("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 = d->gtkWidget("GtkWindow"); // The Murrine Engine currently assumes a widget is passed
+ style = d->gtk_rc_get_style_by_paths(d->gtk_settings_get_default(), "gtk-tooltips", "GtkWindow",
+ d->gtk_window_get_type());
+ gtkPainter.paintFlatBox(gtkWindow, "tooltip", option->rect, GTK_STATE_NORMAL, GTK_SHADOW_NONE, style);
+ }
+ break;
+
+ case PE_PanelStatusBar: {
+ if (widget && widget->testAttribute(Qt::WA_SetPalette) &&
+ option->palette.resolve() & (1 << QPalette::Window)) {
+ // Respect custom palette
+ painter->fillRect(option->rect, option->palette.window());
+ break;
+ }
+ GtkShadowType shadow_type;
+ GtkWidget *gtkStatusbarFrame = d->gtkWidget("GtkStatusbar.GtkFrame");
+ d->gtk_widget_style_get(gtkStatusbarFrame->parent, "shadow-type", &shadow_type, NULL);
+ gtkPainter.paintShadow(gtkStatusbarFrame, "frame", option->rect, GTK_STATE_NORMAL,
+ shadow_type, gtkStatusbarFrame->style);
+ }
+ break;
+
+ case PE_IndicatorHeaderArrow:
+ if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
+ GtkWidget *gtkTreeHeader = d->gtkWidget("GtkTreeView.GtkButton");
+ GtkStateType state = gtkPainter.gtkState(option);
+ style = gtkTreeHeader->style;
+ GtkArrowType type = GTK_ARROW_UP;
+ QImage arrow;
+ // This sorting indicator inversion is intentional, and follows the GNOME HIG.
+ // See http://library.gnome.org/devel/hig-book/stable/controls-lists.html.en#controls-lists-sortable
+ if (header->sortIndicator & QStyleOptionHeader::SortUp)
+ type = GTK_ARROW_UP;
+ else if (header->sortIndicator & QStyleOptionHeader::SortDown)
+ type = GTK_ARROW_DOWN;
+
+ gtkPainter.paintArrow(gtkTreeHeader, "button", option->rect.adjusted(1, 1, -1, -1), type, state,
+ GTK_SHADOW_NONE, FALSE, style);
+ }
+ break;
+
+ case PE_FrameFocusRect:
+ if (!widget || qobject_cast<const QAbstractItemView*>(widget))
+ QCleanlooksStyle::drawPrimitive(element, option, painter, widget);
+ else {
+ // ### this mess should move to subcontrolrect
+ QRect frameRect = option->rect.adjusted(1, 1, -1, -2);
+
+ if (qobject_cast<const QTabBar*>(widget)) {
+ GtkWidget *gtkNotebook = d->gtkWidget("GtkNotebook");
+ style = gtkPainter.getStyle(gtkNotebook);
+ gtkPainter.paintFocus(gtkNotebook, "tab", frameRect.adjusted(-1, 1, 1, 1), GTK_STATE_ACTIVE, style);
+ } else {
+ gtkPainter.paintFocus(NULL, "tab", frameRect, GTK_STATE_ACTIVE, style);
+ }
+ }
+ break;
+
+ case PE_IndicatorBranch:
+ if (option->state & State_Children) {
+ QRect rect = option->rect;
+ rect = QRect(0, 0, 12, 12);
+ rect.moveCenter(option->rect.center());
+ rect.translate(2, 0);
+ GtkExpanderStyle openState = GTK_EXPANDER_EXPANDED;
+ GtkExpanderStyle closedState = GTK_EXPANDER_COLLAPSED;
+ GtkWidget *gtkTreeView = d->gtkWidget("GtkTreeView");
+
+ GtkStateType state = GTK_STATE_NORMAL;
+ if (!(option->state & State_Enabled))
+ state = GTK_STATE_INSENSITIVE;
+ else if (option->state & State_MouseOver)
+ state = GTK_STATE_PRELIGHT;
+
+ gtkPainter.paintExpander(gtkTreeView, "treeview", rect, state,
+ option->state & State_Open ? openState : closedState , gtkTreeView->style);
+ }
+ break;
+
+ case PE_PanelItemViewRow:
+ // This primitive is only used to draw selection behind selected expander arrows.
+ // We try not to decorate the tree branch background unless you inherit from StyledItemDelegate
+ // The reason for this is that a lot of code that relies on custom item delegates will look odd having
+ // a gradient on the branch but a flat shaded color on the item itself.
+ QCommonStyle::drawPrimitive(element, option, painter, widget);
+ if (!option->state & State_Selected) {
+ break;
+ } else {
+ if (const QAbstractItemView *view = qobject_cast<const QAbstractItemView*>(widget)) {
+ if (!qobject_cast<QStyledItemDelegate*>(view->itemDelegate()))
+ break;
+ }
+ } // fall through
+
+ case PE_PanelItemViewItem:
+ if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(option)) {
+ uint resolve_mask = vopt->palette.resolve();
+ if (vopt->backgroundBrush.style() != Qt::NoBrush
+ || (resolve_mask & (1 << QPalette::Base)))
+ {
+ QPointF oldBO = painter->brushOrigin();
+ painter->setBrushOrigin(vopt->rect.topLeft());
+ painter->fillRect(vopt->rect, vopt->backgroundBrush);
+ painter->setBrushOrigin(oldBO);
+ if (!(option->state & State_Selected))
+ break;
+ }
+ if (GtkWidget *gtkTreeView = d->gtkWidget("GtkTreeView")) {
+ const char *detail = "cell_even_ruled";
+ if (vopt && vopt->features & QStyleOptionViewItemV2::Alternate)
+ detail = "cell_odd_ruled";
+ bool isActive = option->state & State_Active;
+ QString key;
+ if (isActive ) {
+ // Required for active/non-active window appearance
+ key = QLS("a");
+ GTK_WIDGET_SET_FLAGS(gtkTreeView, GTK_HAS_FOCUS);
+ }
+ bool isEnabled = (widget ? widget->isEnabled() : (vopt->state & QStyle::State_Enabled));
+ gtkPainter.paintFlatBox(gtkTreeView, detail, option->rect,
+ option->state & State_Selected ? GTK_STATE_SELECTED :
+ isEnabled ? GTK_STATE_NORMAL : GTK_STATE_INSENSITIVE,
+ GTK_SHADOW_OUT, gtkTreeView->style, key);
+ if (isActive )
+ GTK_WIDGET_UNSET_FLAGS(gtkTreeView, GTK_HAS_FOCUS);
+ }
+ }
+ break;
+ case PE_IndicatorToolBarSeparator:
+ {
+ const int margin = 6;
+ GtkWidget *gtkSeparator = d->gtkWidget("GtkToolbar.GtkSeparatorToolItem");
+ if (option->state & State_Horizontal) {
+ const int offset = option->rect.width()/2;
+ QRect rect = option->rect.adjusted(offset, margin, 0, -margin);
+ painter->setPen(QPen(option->palette.background().color().darker(110)));
+ gtkPainter.paintVline( gtkSeparator, "vseparator",
+ rect, GTK_STATE_NORMAL, gtkSeparator->style,
+ 0, rect.height(), 0);
+ } else { //Draw vertical separator
+ const int offset = option->rect.height()/2;
+ QRect rect = option->rect.adjusted(margin, offset, -margin, 0);
+ painter->setPen(QPen(option->palette.background().color().darker(110)));
+ gtkPainter.paintHline( gtkSeparator, "hseparator",
+ rect, GTK_STATE_NORMAL, gtkSeparator->style,
+ 0, rect.width(), 0);
+ }
+ }
+ break;
+
+ case PE_IndicatorToolBarHandle: {
+ GtkWidget *gtkToolbar = d->gtkWidget("GtkToolbar");
+ GtkShadowType shadow_type;
+ d->gtk_widget_style_get(gtkToolbar, "shadow-type", &shadow_type, NULL);
+ //Note when the toolbar is horizontal, the handle is vertical
+ painter->setClipRect(option->rect);
+ gtkPainter.paintHandle(gtkToolbar, "toolbar", option->rect.adjusted(-1, -1 ,0 ,1),
+ GTK_STATE_NORMAL, shadow_type, !(option->state & State_Horizontal) ?
+ GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL, gtkToolbar->style);
+ }
+ break;
+
+ case PE_IndicatorArrowUp:
+ case PE_IndicatorArrowDown:
+ case PE_IndicatorArrowLeft:
+ case PE_IndicatorArrowRight: {
+
+
+ GtkArrowType type = GTK_ARROW_UP;
+
+ switch (element) {
+
+ case PE_IndicatorArrowDown:
+ type = GTK_ARROW_DOWN;
+ break;
+
+ case PE_IndicatorArrowLeft:
+ type = GTK_ARROW_LEFT;
+ break;
+
+ case PE_IndicatorArrowRight:
+ type = GTK_ARROW_RIGHT;
+ break;
+
+ default:
+ break;
+ }
+ int size = qMin(option->rect.height(), option->rect.width());
+ int border = (size > 9) ? (size/4) : 0; //Allow small arrows to have exact dimensions
+ int bsx = 0, bsy = 0;
+ if (option->state & State_Sunken) {
+ bsx = proxy()->pixelMetric(PM_ButtonShiftHorizontal);
+ bsy = proxy()->pixelMetric(PM_ButtonShiftVertical);
+ }
+ QRect arrowRect = option->rect.adjusted(border + bsx, border + bsy, -border + bsx, -border + bsy);
+ GtkShadowType shadow = option->state & State_Sunken ? GTK_SHADOW_IN : GTK_SHADOW_OUT;
+ GtkStateType state = gtkPainter.gtkState(option);
+
+ QColor arrowColor = option->palette.buttonText().color();
+ GtkWidget *gtkArrow = d->gtkWidget("GtkArrow");
+ GdkColor color = fromQColor(arrowColor);
+ d->gtk_widget_modify_fg (gtkArrow, state, &color);
+ gtkPainter.paintArrow(gtkArrow, "button", arrowRect,
+ type, state, shadow, FALSE, gtkArrow->style,
+ QString::number(arrowColor.rgba(), 16));
+ // Passing NULL will revert the color change
+ d->gtk_widget_modify_fg (gtkArrow, state, NULL);
+ }
+ break;
+
+ case PE_FrameGroupBox:
+ // Do nothing here, the GNOME groupboxes are flat
+ break;
+
+ case PE_PanelMenu: {
+ GtkWidget *gtkMenu = d->gtkWidget("GtkMenu");
+ gtkPainter.setAlphaSupport(false); // Note, alpha disabled for performance reasons
+ gtkPainter.paintBox(gtkMenu, "menu", option->rect, GTK_STATE_NORMAL, GTK_SHADOW_OUT, gtkMenu->style, QString());
+ }
+ break;
+
+ case PE_FrameMenu:
+ //This is actually done by PE_Widget due to a clipping issue
+ //Otherwise Menu items will not be able to span the entire menu width
+
+ // This is only used by floating tool bars
+ if (qobject_cast<const QToolBar *>(widget)) {
+ GtkWidget *gtkMenubar = d->gtkWidget("GtkMenuBar");
+ gtkPainter.paintBox( gtkMenubar, "toolbar", option->rect,
+ GTK_STATE_NORMAL, GTK_SHADOW_OUT, style);
+ gtkPainter.paintBox( gtkMenubar, "menu", option->rect,
+ GTK_STATE_NORMAL, GTK_SHADOW_OUT, style);
+ }
+ break;
+
+ case PE_FrameLineEdit: {
+ GtkWidget *gtkEntry = d->gtkWidget("GtkEntry");
+
+
+ gboolean interior_focus;
+ gint focus_line_width;
+ QRect rect = option->rect;
+ d->gtk_widget_style_get(gtkEntry,
+ "interior-focus", &interior_focus,
+ "focus-line-width", &focus_line_width, NULL);
+
+ // See https://bugzilla.mozilla.org/show_bug.cgi?id=405421 for info about this hack
+ g_object_set_data(G_OBJECT(gtkEntry), "transparent-bg-hint", GINT_TO_POINTER(TRUE));
+
+ if (!interior_focus && option->state & State_HasFocus)
+ rect.adjust(focus_line_width, focus_line_width, -focus_line_width, -focus_line_width);
+
+ if (option->state & State_HasFocus)
+ GTK_WIDGET_SET_FLAGS(gtkEntry, GTK_HAS_FOCUS);
+ gtkPainter.paintShadow(gtkEntry, "entry", rect, option->state & State_Enabled ?
+ GTK_STATE_NORMAL : GTK_STATE_INSENSITIVE,
+ GTK_SHADOW_IN, gtkEntry->style,
+ option->state & State_HasFocus ? QLS("focus") : QString());
+ if (!interior_focus && option->state & State_HasFocus)
+ gtkPainter.paintShadow(gtkEntry, "entry", option->rect, option->state & State_Enabled ?
+ GTK_STATE_ACTIVE : GTK_STATE_INSENSITIVE,
+ GTK_SHADOW_IN, gtkEntry->style, QLS("GtkEntryShadowIn"));
+
+ if (option->state & State_HasFocus)
+ GTK_WIDGET_UNSET_FLAGS(gtkEntry, GTK_HAS_FOCUS);
+ }
+ break;
+
+ case PE_PanelLineEdit:
+ if (const QStyleOptionFrame *panel = qstyleoption_cast<const QStyleOptionFrame *>(option)) {
+ GtkWidget *gtkEntry = d->gtkWidget("GtkEntry");
+ if (panel->lineWidth > 0)
+ proxy()->drawPrimitive(PE_FrameLineEdit, option, painter, widget);
+ uint resolve_mask = option->palette.resolve();
+ QRect textRect = option->rect.adjusted(gtkEntry->style->xthickness, gtkEntry->style->ythickness,
+ -gtkEntry->style->xthickness, -gtkEntry->style->ythickness);
+
+ if (widget && widget->testAttribute(Qt::WA_SetPalette) &&
+ resolve_mask & (1 << QPalette::Base)) // Palette overridden by user
+ 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);
+ }
+ break;
+
+ case PE_FrameTabWidget:
+ if (const QStyleOptionTabWidgetFrame *frame = qstyleoption_cast<const QStyleOptionTabWidgetFrame*>(option)) {
+ GtkWidget *gtkNotebook = d->gtkWidget("GtkNotebook");
+ style = gtkPainter.getStyle(gtkNotebook);
+ gtkPainter.setAlphaSupport(false);
+ GtkShadowType shadow = GTK_SHADOW_OUT;
+ GtkStateType state = GTK_STATE_NORMAL; // Only state supported by gtknotebook
+ bool reverse = (option->direction == Qt::RightToLeft);
+ QGtkStylePrivate::gtk_widget_set_direction(gtkNotebook, reverse ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR);
+ if (const QStyleOptionTabWidgetFrameV2 *tabframe = qstyleoption_cast<const QStyleOptionTabWidgetFrameV2*>(option)) {
+ GtkPositionType frameType = GTK_POS_TOP;
+ QTabBar::Shape shape = frame->shape;
+ int gapStart = 0;
+ int gapSize = 0;
+ if (shape == QTabBar::RoundedNorth || shape == QTabBar::RoundedSouth) {
+ frameType = (shape == QTabBar::RoundedNorth) ? GTK_POS_TOP : GTK_POS_BOTTOM;
+ gapStart = tabframe->selectedTabRect.left();
+ gapSize = tabframe->selectedTabRect.width();
+ } else {
+ frameType = (shape == QTabBar::RoundedWest) ? GTK_POS_LEFT : GTK_POS_RIGHT;
+ gapStart = tabframe->selectedTabRect.y();
+ gapSize = tabframe->selectedTabRect.height();
+ }
+ gtkPainter.paintBoxGap(gtkNotebook, "notebook", option->rect, state, shadow, frameType,
+ gapStart, gapSize, style);
+ break; // done
+ }
+
+ // Note this is only the fallback option
+ gtkPainter.paintBox(gtkNotebook, "notebook", option->rect, state, shadow, style);
+ }
+ break;
+
+ case PE_PanelButtonCommand:
+ case PE_PanelButtonTool: {
+ bool isDefault = false;
+ bool isTool = (element == PE_PanelButtonTool);
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton*>(option))
+ isDefault = btn->features & QStyleOptionButton::DefaultButton;
+
+ // don't draw a frame for tool buttons that have the autoRaise flag and are not enabled or on
+ if (isTool && !(option->state & State_Enabled || option->state & State_On) && (option->state & State_AutoRaise))
+ break;
+ // don't draw a frame for dock widget buttons, unless we are hovering
+ if (widget && widget->inherits("QDockWidgetTitleButton") && !(option->state & State_MouseOver))
+ break;
+
+ GtkStateType state = gtkPainter.gtkState(option);
+ if (option->state & State_On || option->state & State_Sunken)
+ state = GTK_STATE_ACTIVE;
+ GtkWidget *gtkButton = isTool ? d->gtkWidget("GtkToolButton.GtkButton") : d->gtkWidget("GtkButton");
+ gint focusWidth, focusPad;
+ gboolean interiorFocus = false;
+ d->gtk_widget_style_get (gtkButton,
+ "focus-line-width", &focusWidth,
+ "focus-padding", &focusPad,
+ "interior-focus", &interiorFocus, NULL);
+
+ style = gtkButton->style;
+
+ QRect buttonRect = option->rect;
+
+ QString key;
+ if (isDefault) {
+ key += QLS("def");
+ GTK_WIDGET_SET_FLAGS(gtkButton, GTK_HAS_DEFAULT);
+ gtkPainter.paintBox(gtkButton, "buttondefault", buttonRect, state, GTK_SHADOW_IN,
+ style, isDefault ? QLS("d") : QString());
+ }
+
+ bool hasFocus = option->state & State_HasFocus;
+
+ if (hasFocus) {
+ key += QLS("def");
+ GTK_WIDGET_SET_FLAGS(gtkButton, GTK_HAS_FOCUS);
+ }
+
+ if (!interiorFocus)
+ buttonRect = buttonRect.adjusted(focusWidth, focusWidth, -focusWidth, -focusWidth);
+
+ GtkShadowType shadow = (option->state & State_Sunken || option->state & State_On ) ?
+ GTK_SHADOW_IN : GTK_SHADOW_OUT;
+
+ gtkPainter.paintBox(gtkButton, "button", buttonRect, state, shadow,
+ style, key);
+ if (isDefault)
+ GTK_WIDGET_UNSET_FLAGS(gtkButton, GTK_HAS_DEFAULT);
+ if (hasFocus)
+ GTK_WIDGET_UNSET_FLAGS(gtkButton, GTK_HAS_FOCUS);
+ }
+ break;
+
+ case PE_IndicatorRadioButton: {
+ GtkShadowType shadow = GTK_SHADOW_OUT;
+ GtkStateType state = gtkPainter.gtkState(option);
+
+ if (option->state & State_Sunken)
+ state = GTK_STATE_ACTIVE;
+
+ if (option->state & State_NoChange)
+ shadow = GTK_SHADOW_ETCHED_IN;
+ else if (option->state & State_On)
+ shadow = GTK_SHADOW_IN;
+ else
+ shadow = GTK_SHADOW_OUT;
+
+ GtkWidget *gtkRadioButton = d->gtkWidget("GtkRadioButton");
+ gint spacing;
+ d->gtk_widget_style_get(gtkRadioButton, "indicator-spacing", &spacing, NULL);
+ QRect buttonRect = option->rect.adjusted(spacing, spacing, -spacing, -spacing);
+ gtkPainter.setClipRect(option->rect);
+ // ### Note: Ubuntulooks breaks when the proper widget is passed
+ // Murrine engine requires a widget not to get RGBA check - warnings
+ GtkWidget *gtkCheckButton = d->gtkWidget("GtkCheckButton");
+ QString key(QLS("radiobutton"));
+ if (option->state & State_HasFocus) { // Themes such as Nodoka check this flag
+ key += QLatin1Char('f');
+ GTK_WIDGET_SET_FLAGS(gtkCheckButton, GTK_HAS_FOCUS);
+ }
+ gtkPainter.paintOption(gtkCheckButton , buttonRect, state, shadow, gtkRadioButton->style, key);
+ if (option->state & State_HasFocus)
+ GTK_WIDGET_UNSET_FLAGS(gtkCheckButton, GTK_HAS_FOCUS);
+ }
+ break;
+
+ case PE_IndicatorCheckBox: {
+ GtkShadowType shadow = GTK_SHADOW_OUT;
+ GtkStateType state = gtkPainter.gtkState(option);
+
+ if (option->state & State_Sunken)
+ state = GTK_STATE_ACTIVE;
+
+ if (option->state & State_NoChange)
+ shadow = GTK_SHADOW_ETCHED_IN;
+ else if (option->state & State_On)
+ shadow = GTK_SHADOW_IN;
+ else
+ shadow = GTK_SHADOW_OUT;
+
+ int spacing;
+
+ GtkWidget *gtkCheckButton = d->gtkWidget("GtkCheckButton");
+ QString key(QLS("checkbutton"));
+ if (option->state & State_HasFocus) { // Themes such as Nodoka checks this flag
+ key += QLatin1Char('f');
+ GTK_WIDGET_SET_FLAGS(gtkCheckButton, GTK_HAS_FOCUS);
+ }
+
+ // Some styles such as aero-clone assume they can paint in the spacing area
+ gtkPainter.setClipRect(option->rect);
+
+ d->gtk_widget_style_get(gtkCheckButton, "indicator-spacing", &spacing, NULL);
+
+ QRect checkRect = option->rect.adjusted(spacing, spacing, -spacing, -spacing);
+
+ gtkPainter.paintCheckbox(gtkCheckButton, checkRect, state, shadow, gtkCheckButton->style,
+ key);
+ if (option->state & State_HasFocus)
+ GTK_WIDGET_UNSET_FLAGS(gtkCheckButton, GTK_HAS_FOCUS);
+
+ }
+ break;
+
+#ifndef QT_NO_TABBAR
+
+ case PE_FrameTabBarBase:
+ if (const QStyleOptionTabBarBase *tbb
+ = qstyleoption_cast<const QStyleOptionTabBarBase *>(option)) {
+ QRect tabRect = tbb->rect;
+ painter->save();
+ painter->setPen(QPen(option->palette.dark().color().dark(110), 0));
+ switch (tbb->shape) {
+
+ case QTabBar::RoundedNorth:
+ painter->drawLine(tabRect.topLeft(), tabRect.topRight());
+ break;
+
+ case QTabBar::RoundedWest:
+ painter->drawLine(tabRect.left(), tabRect.top(), tabRect.left(), tabRect.bottom());
+ break;
+
+ case QTabBar::RoundedSouth:
+ painter->drawLine(tbb->rect.left(), tbb->rect.bottom(),
+ tabRect.right(), tabRect.bottom());
+ break;
+
+ case QTabBar::RoundedEast:
+ painter->drawLine(tabRect.topRight(), tabRect.bottomRight());
+ break;
+
+ case QTabBar::TriangularNorth:
+ case QTabBar::TriangularEast:
+ case QTabBar::TriangularWest:
+ case QTabBar::TriangularSouth:
+ painter->restore();
+ QWindowsStyle::drawPrimitive(element, option, painter, widget);
+ return;
+ }
+
+ painter->restore();
+ }
+ return;
+
+#endif // QT_NO_TABBAR
+
+ case PE_Widget:
+ break;
+
+ default:
+ QCleanlooksStyle::drawPrimitive(element, option, painter, widget);
+ }
+}
+
+/*!
+ \reimp
+*/
+void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionComplex *option,
+
+ QPainter *painter, const QWidget *widget) const
+{
+ Q_D(const QGtkStyle);
+
+ if (!d->isThemeAvailable()) {
+ QCleanlooksStyle::drawComplexControl(control, option, painter, widget);
+ return;
+ }
+
+ GtkStyle* style = d->gtkStyle();
+ QGtkPainter gtkPainter(painter);
+ QColor button = option->palette.button().color();
+ QColor dark;
+ QColor grooveColor;
+ QColor darkOutline;
+ dark.setHsv(button.hue(),
+ qMin(255, (int)(button.saturation()*1.9)),
+ qMin(255, (int)(button.value()*0.7)));
+ grooveColor.setHsv(button.hue(),
+ qMin(255, (int)(button.saturation()*2.6)),
+ qMin(255, (int)(button.value()*0.9)));
+ darkOutline.setHsv(button.hue(),
+ qMin(255, (int)(button.saturation()*3.0)),
+ qMin(255, (int)(button.value()*0.6)));
+
+ QColor alphaCornerColor;
+
+ if (widget)
+ alphaCornerColor = mergedColors(option->palette.color(widget->backgroundRole()), darkOutline);
+ else
+ alphaCornerColor = mergedColors(option->palette.background().color(), darkOutline);
+
+ switch (control) {
+
+ case CC_TitleBar:
+ if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(option)) {
+ // Since this is drawn by metacity and not Gtk we
+ // have to rely on Cleanlooks for a fallback
+ QStyleOptionTitleBar copyOpt = *tb;
+ QPalette pal = copyOpt.palette;
+ // Bg color is closer to the window selection than
+ // the base selection color
+ GdkColor gdkBg = style->bg[GTK_STATE_SELECTED];
+ QColor bgColor(gdkBg.red>>8, gdkBg.green>>8, gdkBg.blue>>8);
+ pal.setBrush(QPalette::Active, QPalette::Highlight, bgColor);
+ copyOpt.palette = pal;
+ QCleanlooksStyle::drawComplexControl(control, &copyOpt, painter, widget);
+ }
+ break;
+
+#ifndef QT_NO_GROUPBOX
+
+ case CC_GroupBox:
+ painter->save();
+
+ if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(option)) {
+ QRect textRect = proxy()->subControlRect(CC_GroupBox, groupBox, SC_GroupBoxLabel, widget);
+ QRect checkBoxRect = proxy()->subControlRect(CC_GroupBox, groupBox, SC_GroupBoxCheckBox, widget);
+ // Draw title
+
+ if ((groupBox->subControls & QStyle::SC_GroupBoxLabel) && !groupBox->text.isEmpty()) {
+ // Draw prelight background
+ GtkWidget *gtkCheckButton = d->gtkWidget("GtkCheckButton");
+
+ if (option->state & State_MouseOver) {
+ QRect bgRect = textRect | checkBoxRect;
+ gtkPainter.paintFlatBox(gtkCheckButton, "checkbutton", bgRect.adjusted(0, 0, 0, -2),
+ GTK_STATE_PRELIGHT, GTK_SHADOW_ETCHED_OUT, gtkCheckButton->style);
+ }
+
+ if (!groupBox->text.isEmpty()) {
+ int alignment = int(groupBox->textAlignment);
+ if (!proxy()->styleHint(QStyle::SH_UnderlineShortcut, option, widget))
+ alignment |= Qt::TextHideMnemonic;
+ QColor textColor = groupBox->textColor; // Note: custom textColor is currently ignored
+ int labelState = GTK_STATE_INSENSITIVE;
+
+ if (option->state & State_Enabled)
+ labelState = (option->state & State_MouseOver) ? GTK_STATE_PRELIGHT : GTK_STATE_NORMAL;
+
+ GdkColor gdkText = gtkCheckButton->style->fg[labelState];
+ textColor = QColor(gdkText.red>>8, gdkText.green>>8, gdkText.blue>>8);
+ painter->setPen(textColor);
+ QFont font = painter->font();
+ font.setBold(true);
+ painter->setFont(font);
+ painter->drawText(textRect, Qt::TextShowMnemonic | Qt::AlignLeft| alignment, groupBox->text);
+
+ if (option->state & State_HasFocus)
+ gtkPainter.paintFocus( NULL, "tab", textRect.adjusted(-4, -1, 0, -3), GTK_STATE_ACTIVE, style);
+ }
+ }
+
+ if (groupBox->subControls & SC_GroupBoxCheckBox) {
+ QStyleOptionButton box;
+ box.QStyleOption::operator=(*groupBox);
+ box.rect = checkBoxRect;
+ proxy()->drawPrimitive(PE_IndicatorCheckBox, &box, painter, widget);
+ }
+ }
+
+ painter->restore();
+ break;
+#endif // QT_NO_GROUPBOX
+
+#ifndef QT_NO_COMBOBOX
+
+ case CC_ComboBox:
+ // See: http://live.gnome.org/GnomeArt/Tutorials/GtkThemes/GtkComboBox
+ // and http://live.gnome.org/GnomeArt/Tutorials/GtkThemes/GtkComboBoxEntry
+ if (const QStyleOptionComboBox *comboBox = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
+ bool sunken = comboBox->state & State_On; // play dead, if combobox has no items
+ BEGIN_STYLE_PIXMAPCACHE(QString::fromLatin1("cb-%0-%1").arg(sunken).arg(comboBox->editable));
+ QGtkPainter gtkCachedPainter(p);
+ gtkCachedPainter.setUsePixmapCache(false); // cached externally
+
+ bool isEnabled = (comboBox->state & State_Enabled);
+ bool focus = isEnabled && (comboBox->state & State_HasFocus);
+ GtkStateType state = gtkPainter.gtkState(option);
+ int appears_as_list = !proxy()->styleHint(QStyle::SH_ComboBox_Popup, comboBox, widget);
+ QStyleOptionComboBox comboBoxCopy = *comboBox;
+ comboBoxCopy.rect = option->rect;
+
+ bool reverse = (option->direction == Qt::RightToLeft);
+ QRect rect = option->rect;
+ QRect arrowButtonRect = proxy()->subControlRect(CC_ComboBox, &comboBoxCopy,
+ SC_ComboBoxArrow, widget);
+
+ GtkShadowType shadow = (option->state & State_Sunken || option->state & State_On ) ?
+ GTK_SHADOW_IN : GTK_SHADOW_OUT;
+ const QHashableLatin1Literal comboBoxPath = comboBox->editable ? QHashableLatin1Literal("GtkComboBoxEntry") : QHashableLatin1Literal("GtkComboBox");
+
+ // We use the gtk widget to position arrows and separators for us
+ GtkWidget *gtkCombo = d->gtkWidget(comboBoxPath);
+ GtkAllocation geometry = {0, 0, option->rect.width(), option->rect.height()};
+ d->gtk_widget_set_direction(gtkCombo, reverse ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR);
+ d->gtk_widget_size_allocate(gtkCombo, &geometry);
+
+ QHashableLatin1Literal buttonPath = comboBox->editable ? QHashableLatin1Literal("GtkComboBoxEntry.GtkToggleButton")
+ : QHashableLatin1Literal("GtkComboBox.GtkToggleButton");
+ GtkWidget *gtkToggleButton = d->gtkWidget(buttonPath);
+ d->gtk_widget_set_direction(gtkToggleButton, reverse ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR);
+ if (gtkToggleButton && (appears_as_list || comboBox->editable)) {
+ if (focus)
+ GTK_WIDGET_SET_FLAGS(gtkToggleButton, GTK_HAS_FOCUS);
+ // Draw the combo box as a line edit with a button next to it
+ if (comboBox->editable || appears_as_list) {
+ GtkStateType frameState = (state == GTK_STATE_PRELIGHT) ? GTK_STATE_NORMAL : state;
+ QHashableLatin1Literal entryPath = comboBox->editable ? QHashableLatin1Literal("GtkComboBoxEntry.GtkEntry") : QHashableLatin1Literal("GtkComboBox.GtkFrame");
+ GtkWidget *gtkEntry = d->gtkWidget(entryPath);
+ d->gtk_widget_set_direction(gtkEntry, reverse ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR);
+ QRect frameRect = option->rect;
+
+ if (reverse)
+ frameRect.setLeft(arrowButtonRect.right());
+ else
+ frameRect.setRight(arrowButtonRect.left());
+
+ // Fill the line edit background
+ // We could have used flat_box with "entry_bg" but that is probably not worth the overhead
+ uint resolve_mask = option->palette.resolve();
+ int xt = gtkEntry->style->xthickness;
+ int yt = gtkEntry->style->ythickness;
+ QRect contentRect = frameRect.adjusted(xt, yt, -xt, -yt);
+ // Required for inner blue highlight with clearlooks
+ if (focus)
+ GTK_WIDGET_SET_FLAGS(gtkEntry, GTK_HAS_FOCUS);
+
+ if (widget && widget->testAttribute(Qt::WA_SetPalette) &&
+ resolve_mask & (1 << QPalette::Base)) // Palette overridden by user
+ p->fillRect(contentRect, option->palette.base().color());
+ else {
+ gtkCachedPainter.paintFlatBox(gtkEntry, "entry_bg", contentRect,
+ option->state & State_Enabled ? GTK_STATE_NORMAL : GTK_STATE_INSENSITIVE,
+ GTK_SHADOW_NONE, gtkEntry->style, entryPath.toString() + QString::number(focus));
+ }
+
+ gtkCachedPainter.paintShadow(gtkEntry, comboBox->editable ? "entry" : "frame", frameRect, frameState,
+ GTK_SHADOW_IN, gtkEntry->style, entryPath.toString() +
+ QString::number(focus) + QString::number(comboBox->editable) +
+ QString::number(option->direction));
+ if (focus)
+ GTK_WIDGET_UNSET_FLAGS(gtkEntry, GTK_HAS_FOCUS);
+ }
+
+ GtkStateType buttonState = GTK_STATE_NORMAL;
+
+ if (!(option->state & State_Enabled))
+ buttonState = GTK_STATE_INSENSITIVE;
+ else if (option->state & State_Sunken || option->state & State_On)
+ buttonState = GTK_STATE_ACTIVE;
+ else if (option->state & State_MouseOver && comboBox->activeSubControls & SC_ComboBoxArrow)
+ buttonState = GTK_STATE_PRELIGHT;
+
+ Q_ASSERT(gtkToggleButton);
+ gtkCachedPainter.paintBox( gtkToggleButton, "button", arrowButtonRect, buttonState,
+ shadow, gtkToggleButton->style, buttonPath.toString() +
+ QString::number(focus) + QString::number(option->direction));
+ if (focus)
+ GTK_WIDGET_UNSET_FLAGS(gtkToggleButton, GTK_HAS_FOCUS);
+ } else {
+ // Draw combo box as a button
+ QRect buttonRect = option->rect;
+
+ if (focus) // Clearlooks actually check the widget for the default state
+ GTK_WIDGET_SET_FLAGS(gtkToggleButton, GTK_HAS_FOCUS);
+ gtkCachedPainter.paintBox(gtkToggleButton, "button",
+ buttonRect, state,
+ shadow, gtkToggleButton->style,
+ buttonPath.toString() + QString::number(focus));
+ if (focus)
+ GTK_WIDGET_UNSET_FLAGS(gtkToggleButton, GTK_HAS_FOCUS);
+
+
+ // Draw the separator between label and arrows
+ QHashableLatin1Literal vSeparatorPath = comboBox->editable
+ ? QHashableLatin1Literal("GtkComboBoxEntry.GtkToggleButton.GtkHBox.GtkVSeparator")
+ : QHashableLatin1Literal("GtkComboBox.GtkToggleButton.GtkHBox.GtkVSeparator");
+
+ if (GtkWidget *gtkVSeparator = d->gtkWidget(vSeparatorPath)) {
+ QRect vLineRect(gtkVSeparator->allocation.x,
+ gtkVSeparator->allocation.y,
+ gtkVSeparator->allocation.width,
+ gtkVSeparator->allocation.height);
+
+ gtkCachedPainter.paintVline( gtkVSeparator, "vseparator",
+ vLineRect, state, gtkVSeparator->style,
+ 0, vLineRect.height(), 0, vSeparatorPath.toString());
+
+
+ gint interiorFocus = true;
+ d->gtk_widget_style_get(gtkToggleButton, "interior-focus", &interiorFocus, NULL);
+ int xt = interiorFocus ? gtkToggleButton->style->xthickness : 0;
+ int yt = interiorFocus ? gtkToggleButton->style->ythickness : 0;
+ if (focus && ((option->state & State_KeyboardFocusChange) || styleHint(SH_UnderlineShortcut, option, widget)))
+ gtkCachedPainter.paintFocus(gtkToggleButton, "button",
+ option->rect.adjusted(xt, yt, -xt, -yt),
+ option->state & State_Sunken ? GTK_STATE_ACTIVE : GTK_STATE_NORMAL,
+ gtkToggleButton->style);
+ }
+ }
+
+ if (comboBox->subControls & SC_ComboBoxArrow) {
+ if (!isEnabled)
+ state = GTK_STATE_INSENSITIVE;
+ else if (sunken)
+ state = GTK_STATE_ACTIVE;
+ else if (option->state & State_MouseOver)
+ state = GTK_STATE_PRELIGHT;
+ else
+ state = GTK_STATE_NORMAL;
+
+ QHashableLatin1Literal arrowPath("");
+ if (comboBox->editable) {
+ if (appears_as_list)
+ arrowPath = QHashableLatin1Literal("GtkComboBoxEntry.GtkToggleButton.GtkArrow");
+ else
+ arrowPath = QHashableLatin1Literal("GtkComboBoxEntry.GtkToggleButton.GtkHBox.GtkArrow");
+ } else {
+ if (appears_as_list)
+ arrowPath = QHashableLatin1Literal("GtkComboBox.GtkToggleButton.GtkArrow");
+ else
+ arrowPath = QHashableLatin1Literal("GtkComboBox.GtkToggleButton.GtkHBox.GtkArrow");
+ }
+
+ GtkWidget *gtkArrow = d->gtkWidget(arrowPath);
+ gfloat scale = 0.7;
+ gint minSize = 15;
+ QRect arrowWidgetRect;
+
+ if (gtkArrow && !d->gtk_check_version(2, 12, 0)) {
+ d->gtk_widget_style_get(gtkArrow, "arrow-scaling", &scale, NULL);
+ d->gtk_widget_style_get(gtkCombo, "arrow-size", &minSize, NULL);
+ }
+ if (gtkArrow) {
+ arrowWidgetRect = QRect(gtkArrow->allocation.x, gtkArrow->allocation.y,
+ gtkArrow->allocation.width, gtkArrow->allocation.height);
+ style = gtkArrow->style;
+ }
+
+ // Note that for some reason the arrow-size is not properly respected with Hildon
+ // Hence we enforce the minimum "arrow-size" ourselves
+ int arrowSize = qMax(qMin(rect.height() - gtkCombo->style->ythickness * 2, minSize),
+ qMin(arrowWidgetRect.width(), arrowWidgetRect.height()));
+ QRect arrowRect(0, 0, static_cast<int>(arrowSize * scale), static_cast<int>(arrowSize * scale));
+
+ arrowRect.moveCenter(arrowWidgetRect.center());
+
+ if (sunken) {
+ int xoff, yoff;
+ const QHashableLatin1Literal toggleButtonPath = comboBox->editable
+ ? QHashableLatin1Literal("GtkComboBoxEntry.GtkToggleButton")
+ : QHashableLatin1Literal("GtkComboBox.GtkToggleButton");
+
+ GtkWidget *gtkButton = d->gtkWidget(toggleButtonPath);
+ d->gtk_widget_style_get(gtkButton, "child-displacement-x", &xoff, NULL);
+ d->gtk_widget_style_get(gtkButton, "child-displacement-y", &yoff, NULL);
+ arrowRect = arrowRect.adjusted(xoff, yoff, xoff, yoff);
+ }
+
+ // Some styles such as Nimbus paint outside the arrowRect
+ // hence we have provide the whole widget as the cliprect
+ if (gtkArrow) {
+ gtkCachedPainter.setClipRect(option->rect);
+ gtkCachedPainter.paintArrow( gtkArrow, "arrow", arrowRect,
+ GTK_ARROW_DOWN, state, GTK_SHADOW_NONE, TRUE,
+ style, arrowPath.toString() + QString::number(option->direction));
+ }
+ }
+ END_STYLE_PIXMAPCACHE;
+ }
+ break;
+#endif // QT_NO_COMBOBOX
+#ifndef QT_NO_TOOLBUTTON
+
+ case CC_ToolButton:
+ if (const QStyleOptionToolButton *toolbutton
+ = qstyleoption_cast<const QStyleOptionToolButton *>(option)) {
+ QRect button, menuarea;
+ button = proxy()->subControlRect(control, toolbutton, SC_ToolButton, widget);
+ menuarea = proxy()->subControlRect(control, toolbutton, SC_ToolButtonMenu, widget);
+ State bflags = toolbutton->state & ~(State_Sunken | State_MouseOver);
+
+ if (bflags & State_AutoRaise)
+ if (!(bflags & State_MouseOver))
+ bflags &= ~State_Raised;
+
+ State mflags = bflags;
+
+ if (toolbutton->state & State_Sunken) {
+ if (toolbutton->activeSubControls & SC_ToolButton)
+ bflags |= State_Sunken;
+ if (toolbutton->activeSubControls & SC_ToolButtonMenu)
+ mflags |= State_Sunken;
+ } else if (toolbutton->state & State_MouseOver) {
+ if (toolbutton->activeSubControls & SC_ToolButton)
+ bflags |= State_MouseOver;
+ if (toolbutton->activeSubControls & SC_ToolButtonMenu)
+ mflags |= State_MouseOver;
+ }
+
+ QStyleOption tool(0);
+
+ tool.palette = toolbutton->palette;
+
+ if (toolbutton->subControls & SC_ToolButton) {
+ if (bflags & (State_Sunken | State_On | State_Raised | State_MouseOver)) {
+ tool.rect = button;
+ tool.state = bflags;
+ proxy()->drawPrimitive(PE_PanelButtonTool, &tool, painter, widget);
+ }
+ }
+
+ bool drawMenuArrow = toolbutton->features & QStyleOptionToolButton::HasMenu &&
+ !(toolbutton->features & QStyleOptionToolButton::MenuButtonPopup);
+ int popupArrowSize = drawMenuArrow ? 7 : 0;
+
+ if (toolbutton->state & State_HasFocus) {
+ QStyleOptionFocusRect fr;
+ fr.QStyleOption::operator=(*toolbutton);
+ fr.rect = proxy()->subControlRect(CC_ToolButton, toolbutton, SC_ToolButton, widget);
+ fr.rect.adjust(1, 1, -1, -1);
+ proxy()->drawPrimitive(PE_FrameFocusRect, &fr, painter, widget);
+ }
+
+ QStyleOptionToolButton label = *toolbutton;
+ label.state = bflags;
+ GtkWidget *gtkButton = d->gtkWidget("GtkToolButton.GtkButton");
+ QPalette pal = toolbutton->palette;
+ if (option->state & State_Enabled &&
+ option->state & State_MouseOver && !(widget && widget->testAttribute(Qt::WA_SetPalette))) {
+ GdkColor gdkText = gtkButton->style->fg[GTK_STATE_PRELIGHT];
+ QColor textColor = QColor(gdkText.red>>8, gdkText.green>>8, gdkText.blue>>8);
+ pal.setBrush(QPalette::All, QPalette::ButtonText, textColor);
+ label.palette = pal;
+ }
+ label.rect = button.adjusted(style->xthickness, style->ythickness,
+ -style->xthickness - popupArrowSize, -style->ythickness);
+ proxy()->drawControl(CE_ToolButtonLabel, &label, painter, widget);
+
+ if (toolbutton->subControls & SC_ToolButtonMenu) {
+ tool.rect = menuarea;
+ tool.state = mflags;
+ if ((mflags & State_Enabled && (mflags & (State_Sunken | State_Raised | State_MouseOver))) || !(mflags & State_AutoRaise))
+ proxy()->drawPrimitive(PE_IndicatorButtonDropDown, &tool, painter, widget);
+
+ proxy()->drawPrimitive(PE_IndicatorArrowDown, &tool, painter, widget);
+
+ } else if (drawMenuArrow) {
+ QRect ir = toolbutton->rect;
+ QStyleOptionToolButton newBtn = *toolbutton;
+ newBtn.rect = QRect(ir.right() - popupArrowSize - style->xthickness - 3, ir.height()/2 - 1, popupArrowSize, popupArrowSize);
+ proxy()->drawPrimitive(PE_IndicatorArrowDown, &newBtn, painter, widget);
+ }
+ }
+ break;
+
+#endif // QT_NO_TOOLBUTTON
+#ifndef QT_NO_SCROLLBAR
+
+ case CC_ScrollBar:
+ if (const QStyleOptionSlider *scrollBar = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
+ GtkWidget *gtkHScrollBar = d->gtkWidget("GtkHScrollbar");
+ GtkWidget *gtkVScrollBar = d->gtkWidget("GtkVScrollbar");
+
+ // Fill background in case the scrollbar is partially transparent
+ painter->fillRect(option->rect, option->palette.background());
+
+ QRect rect = scrollBar->rect;
+ QRect scrollBarSubLine = proxy()->subControlRect(control, scrollBar, SC_ScrollBarSubLine, widget);
+ QRect scrollBarAddLine = proxy()->subControlRect(control, scrollBar, SC_ScrollBarAddLine, widget);
+ QRect scrollBarSlider = proxy()->subControlRect(control, scrollBar, SC_ScrollBarSlider, widget);
+ QRect grooveRect = proxy()->subControlRect(control, scrollBar, SC_ScrollBarGroove, widget);
+ bool horizontal = scrollBar->orientation == Qt::Horizontal;
+ GtkWidget * scrollbarWidget = horizontal ? gtkHScrollBar : gtkVScrollBar;
+ style = scrollbarWidget->style;
+ gboolean trough_under_steppers = true;
+ gboolean trough_side_details = false;
+ gboolean activate_slider = false;
+ gboolean stepper_size = 14;
+ gint trough_border = 1;
+ if (!d->gtk_check_version(2, 10, 0)) {
+ d->gtk_widget_style_get((GtkWidget*)(scrollbarWidget),
+ "trough-border", &trough_border,
+ "trough-side-details", &trough_side_details,
+ "trough-under-steppers", &trough_under_steppers,
+ "activate-slider", &activate_slider,
+ "stepper-size", &stepper_size, NULL);
+ }
+ if (trough_under_steppers) {
+ scrollBarAddLine.adjust(trough_border, trough_border, -trough_border, -trough_border);
+ scrollBarSubLine.adjust(trough_border, trough_border, -trough_border, -trough_border);
+ scrollBarSlider.adjust(horizontal ? -trough_border : 0, horizontal ? 0 : -trough_border,
+ horizontal ? trough_border : 0, horizontal ? 0 : trough_border);
+ }
+
+ // Some styles check the position of scrollbars in order to determine
+ // if lines should be painted when the scrollbar is in max or min positions.
+ int maximum = 2;
+ int fakePos = 0;
+ bool reverse = (option->direction == Qt::RightToLeft);
+ if (scrollBar->minimum == scrollBar->maximum)
+ maximum = 0;
+ if (scrollBar->sliderPosition == scrollBar->maximum)
+ fakePos = maximum;
+ else if (scrollBar->sliderPosition > scrollBar->minimum)
+ fakePos = maximum - 1;
+
+
+ GtkRange *range = (GtkRange*)(horizontal ? gtkHScrollBar : gtkVScrollBar);
+ GtkAdjustment *adjustment = d->gtk_range_get_adjustment(range);
+
+ if (adjustment) {
+ d->gtk_adjustment_configure(adjustment, fakePos, 0, maximum, 0, 0, 0);
+ } else {
+ adjustment = (GtkAdjustment*)d->gtk_adjustment_new(fakePos, 0, maximum, 0, 0, 0);
+ d->gtk_range_set_adjustment(range, adjustment);
+ }
+
+ if (scrollBar->subControls & SC_ScrollBarGroove) {
+ GtkStateType state = GTK_STATE_ACTIVE;
+
+ if (!(option->state & State_Enabled))
+ state = GTK_STATE_INSENSITIVE;
+
+ if (trough_under_steppers)
+ grooveRect = option->rect;
+
+ gtkPainter.paintBox( scrollbarWidget, "trough", grooveRect, state, GTK_SHADOW_IN, style);
+ }
+
+ //paint slider
+ if (scrollBar->subControls & SC_ScrollBarSlider) {
+ GtkStateType state = GTK_STATE_NORMAL;
+
+ if (!(option->state & State_Enabled))
+ state = GTK_STATE_INSENSITIVE;
+ else if (activate_slider &&
+ option->state & State_Sunken && (scrollBar->activeSubControls & SC_ScrollBarSlider))
+ state = GTK_STATE_ACTIVE;
+ else if (option->state & State_MouseOver && (scrollBar->activeSubControls & SC_ScrollBarSlider))
+ state = GTK_STATE_PRELIGHT;
+
+ GtkShadowType shadow = GTK_SHADOW_OUT;
+
+ if (trough_under_steppers) {
+ if (!horizontal)
+ scrollBarSlider.adjust(trough_border, 0, -trough_border, 0);
+ else
+ scrollBarSlider.adjust(0, trough_border, 0, -trough_border);
+ }
+
+ gtkPainter.paintSlider( scrollbarWidget, "slider", scrollBarSlider, state, shadow, style,
+
+ horizontal ? GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL, QString(QLS("%0%1")).arg(fakePos).arg(maximum));
+ }
+
+ if (scrollBar->subControls & SC_ScrollBarAddLine) {
+ gtkVScrollBar->allocation.y = scrollBarAddLine.top();
+ gtkVScrollBar->allocation.height = scrollBarAddLine.height() - rect.height() + 6;
+ gtkHScrollBar->allocation.x = scrollBarAddLine.right();
+ gtkHScrollBar->allocation.width = scrollBarAddLine.width() - rect.width();
+
+ GtkShadowType shadow = GTK_SHADOW_OUT;
+ GtkStateType state = GTK_STATE_NORMAL;
+
+ if (!(option->state & State_Enabled) || (fakePos == maximum))
+ state = GTK_STATE_INSENSITIVE;
+ else if (option->state & State_Sunken && (scrollBar->activeSubControls & SC_ScrollBarAddLine)) {
+ state = GTK_STATE_ACTIVE;
+ shadow = GTK_SHADOW_IN;
+
+ } else if (option->state & State_MouseOver && (scrollBar->activeSubControls & SC_ScrollBarAddLine))
+ state = GTK_STATE_PRELIGHT;
+
+ gtkPainter.paintBox( scrollbarWidget,
+ horizontal ? "hscrollbar" : "vscrollbar", scrollBarAddLine,
+ state, shadow, style, QLS("add"));
+
+ gtkPainter.paintArrow( scrollbarWidget, horizontal ? "hscrollbar" : "vscrollbar", scrollBarAddLine.adjusted(4, 4, -4, -4),
+ horizontal ? (reverse ? GTK_ARROW_LEFT : GTK_ARROW_RIGHT) :
+ GTK_ARROW_DOWN, state, GTK_SHADOW_NONE, FALSE, style);
+ }
+
+ if (scrollBar->subControls & SC_ScrollBarSubLine) {
+ gtkVScrollBar->allocation.y = 0;
+ gtkVScrollBar->allocation.height = scrollBarSubLine.height();
+ gtkHScrollBar->allocation.x = 0;
+ gtkHScrollBar->allocation.width = scrollBarSubLine.width();
+
+ GtkShadowType shadow = GTK_SHADOW_OUT;
+ GtkStateType state = GTK_STATE_NORMAL;
+
+ if (!(option->state & State_Enabled) || (fakePos == 0))
+ state = GTK_STATE_INSENSITIVE;
+ else if (option->state & State_Sunken && (scrollBar->activeSubControls & SC_ScrollBarSubLine)) {
+ shadow = GTK_SHADOW_IN;
+ state = GTK_STATE_ACTIVE;
+
+ } else if (option->state & State_MouseOver && (scrollBar->activeSubControls & SC_ScrollBarSubLine))
+ state = GTK_STATE_PRELIGHT;
+
+ gtkPainter.paintBox(scrollbarWidget, horizontal ? "hscrollbar" : "vscrollbar", scrollBarSubLine,
+ state, shadow, style, QLS("sub"));
+
+ gtkPainter.paintArrow(scrollbarWidget, horizontal ? "hscrollbar" : "vscrollbar", scrollBarSubLine.adjusted(4, 4, -4, -4),
+ horizontal ? (reverse ? GTK_ARROW_RIGHT : GTK_ARROW_LEFT) :
+ GTK_ARROW_UP, state, GTK_SHADOW_NONE, FALSE, style);
+ }
+ }
+ break;
+
+#endif //QT_NO_SCROLLBAR
+#ifndef QT_NO_SPINBOX
+
+ case CC_SpinBox:
+ if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
+
+ GtkWidget *gtkSpinButton = spinBox->buttonSymbols == QAbstractSpinBox::NoButtons
+ ? d->gtkWidget("GtkEntry")
+ : d->gtkWidget("GtkSpinButton");
+ bool isEnabled = (spinBox->state & State_Enabled);
+ bool hover = isEnabled && (spinBox->state & State_MouseOver);
+ bool sunken = (spinBox->state & State_Sunken);
+ bool upIsActive = (spinBox->activeSubControls == SC_SpinBoxUp);
+ bool downIsActive = (spinBox->activeSubControls == SC_SpinBoxDown);
+ bool reverse = (spinBox->direction == Qt::RightToLeft);
+
+ QRect editArea = option->rect;
+ QRect editRect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxEditField, widget);
+ QRect upRect, downRect, buttonRect;
+ if (spinBox->buttonSymbols != QAbstractSpinBox::NoButtons) {
+ upRect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxUp, widget);
+ downRect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxDown, widget);
+
+ //### Move this to subControlRect
+ upRect.setTop(option->rect.top());
+
+ if (reverse)
+ upRect.setLeft(option->rect.left());
+ else
+ upRect.setRight(option->rect.right());
+
+ downRect.setBottom(option->rect.bottom());
+
+ if (reverse)
+ downRect.setLeft(option->rect.left());
+ else
+ downRect.setRight(option->rect.right());
+
+ buttonRect = upRect | downRect;
+
+ if (reverse)
+ editArea.setLeft(upRect.right());
+ else
+ editArea.setRight(upRect.left());
+ }
+ if (spinBox->frame) {
+ GtkStateType state = gtkPainter.gtkState(option);
+
+ if (!(option->state & State_Enabled))
+ state = GTK_STATE_INSENSITIVE;
+ else if (option->state & State_HasFocus)
+ state = GTK_STATE_NORMAL;
+ else if (state == GTK_STATE_PRELIGHT)
+ state = GTK_STATE_NORMAL;
+
+ style = gtkPainter.getStyle(gtkSpinButton);
+
+
+ QString key;
+
+ if (option->state & State_HasFocus) {
+ key += QLatin1Char('f');
+ GTK_WIDGET_SET_FLAGS(gtkSpinButton, GTK_HAS_FOCUS);
+ }
+
+ uint resolve_mask = option->palette.resolve();
+
+ if (resolve_mask & (1 << QPalette::Base)) // Palette overridden by user
+ painter->fillRect(editRect, option->palette.base().color());
+ else
+ gtkPainter.paintFlatBox(gtkSpinButton, "entry_bg", editArea.adjusted(style->xthickness, style->ythickness,
+ -style->xthickness, -style->ythickness),
+ option->state & State_Enabled ?
+ GTK_STATE_NORMAL : GTK_STATE_INSENSITIVE, GTK_SHADOW_NONE, style, key);
+
+ gtkPainter.paintShadow(gtkSpinButton, "entry", editArea, state, GTK_SHADOW_IN, gtkSpinButton->style, key);
+ if (spinBox->buttonSymbols != QAbstractSpinBox::NoButtons) {
+ gtkPainter.paintBox(gtkSpinButton, "spinbutton", buttonRect, state, GTK_SHADOW_IN, style, key);
+
+ upRect.setSize(downRect.size());
+ if (!(option->state & State_Enabled))
+ gtkPainter.paintBox( gtkSpinButton, "spinbutton_up", upRect, GTK_STATE_INSENSITIVE, GTK_SHADOW_IN, style, key);
+ else if (upIsActive && sunken)
+ gtkPainter.paintBox( gtkSpinButton, "spinbutton_up", upRect, GTK_STATE_ACTIVE, GTK_SHADOW_IN, style, key);
+ else if (upIsActive && hover)
+ gtkPainter.paintBox( gtkSpinButton, "spinbutton_up", upRect, GTK_STATE_PRELIGHT, GTK_SHADOW_OUT, style, key);
+ else
+ gtkPainter.paintBox( gtkSpinButton, "spinbutton_up", upRect, GTK_STATE_NORMAL, GTK_SHADOW_OUT, style, key);
+
+ if (!(option->state & State_Enabled))
+ gtkPainter.paintBox( gtkSpinButton, "spinbutton_down", downRect, GTK_STATE_INSENSITIVE, GTK_SHADOW_IN, style, key);
+ else if (downIsActive && sunken)
+ gtkPainter.paintBox( gtkSpinButton, "spinbutton_down", downRect, GTK_STATE_ACTIVE, GTK_SHADOW_IN, style, key);
+ else if (downIsActive && hover)
+ gtkPainter.paintBox( gtkSpinButton, "spinbutton_down", downRect, GTK_STATE_PRELIGHT, GTK_SHADOW_OUT, style, key);
+ else
+ gtkPainter.paintBox( gtkSpinButton, "spinbutton_down", downRect, GTK_STATE_NORMAL, GTK_SHADOW_OUT, style, key);
+
+ if (option->state & State_HasFocus)
+ GTK_WIDGET_UNSET_FLAGS(gtkSpinButton, GTK_HAS_FOCUS);
+ }
+ }
+
+ if (spinBox->buttonSymbols == QAbstractSpinBox::PlusMinus) {
+ int centerX = upRect.center().x();
+ int centerY = upRect.center().y();
+ // plus/minus
+
+ if (spinBox->activeSubControls == SC_SpinBoxUp && sunken) {
+ painter->drawLine(1 + centerX - 2, 1 + centerY, 1 + centerX + 2, 1 + centerY);
+ painter->drawLine(1 + centerX, 1 + centerY - 2, 1 + centerX, 1 + centerY + 2);
+
+ } else {
+ painter->drawLine(centerX - 2, centerY, centerX + 2, centerY);
+ painter->drawLine(centerX, centerY - 2, centerX, centerY + 2);
+ }
+ centerX = downRect.center().x();
+ centerY = downRect.center().y();
+
+ if (spinBox->activeSubControls == SC_SpinBoxDown && sunken) {
+ painter->drawLine(1 + centerX - 2, 1 + centerY, 1 + centerX + 2, 1 + centerY);
+ } else {
+ painter->drawLine(centerX - 2, centerY, centerX + 2, centerY);
+ }
+
+ } else if (spinBox->buttonSymbols == QAbstractSpinBox::UpDownArrows) {
+ int size = d->getSpinboxArrowSize();
+ int w = size / 2 - 1;
+ w -= w % 2 - 1; // force odd
+ int h = (w + 1)/2;
+ QRect arrowRect(0, 0, w, h);
+ arrowRect.moveCenter(upRect.center());
+ // arrows
+ GtkStateType state = GTK_STATE_NORMAL;
+
+ if (!(option->state & State_Enabled) || !(spinBox->stepEnabled & QAbstractSpinBox::StepUpEnabled))
+ state = GTK_STATE_INSENSITIVE;
+
+ gtkPainter.paintArrow( gtkSpinButton, "spinbutton", arrowRect, GTK_ARROW_UP, state,
+ GTK_SHADOW_NONE, FALSE, style);
+
+ arrowRect.moveCenter(downRect.center());
+
+ if (!(option->state & State_Enabled) || !(spinBox->stepEnabled & QAbstractSpinBox::StepDownEnabled))
+ state = GTK_STATE_INSENSITIVE;
+
+ gtkPainter.paintArrow( gtkSpinButton, "spinbutton", arrowRect, GTK_ARROW_DOWN, state,
+ GTK_SHADOW_NONE, FALSE, style);
+ }
+ }
+ break;
+
+#endif // QT_NO_SPINBOX
+
+#ifndef QT_NO_SLIDER
+
+ case CC_Slider:
+ if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
+ GtkWidget *hScaleWidget = d->gtkWidget("GtkHScale");
+ GtkWidget *vScaleWidget = d->gtkWidget("GtkVScale");
+
+ QRect groove = proxy()->subControlRect(CC_Slider, option, SC_SliderGroove, widget);
+ QRect handle = proxy()->subControlRect(CC_Slider, option, SC_SliderHandle, widget);
+
+ bool horizontal = slider->orientation == Qt::Horizontal;
+ bool ticksAbove = slider->tickPosition & QSlider::TicksAbove;
+ bool ticksBelow = slider->tickPosition & QSlider::TicksBelow;
+
+ QBrush oldBrush = painter->brush();
+ QPen oldPen = painter->pen();
+
+ QColor shadowAlpha(Qt::black);
+ shadowAlpha.setAlpha(10);
+ QColor highlightAlpha(Qt::white);
+ highlightAlpha.setAlpha(80);
+
+ QGtkStylePrivate::gtk_widget_set_direction(hScaleWidget, slider->upsideDown ?
+ GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR);
+ GtkWidget *scaleWidget = horizontal ? hScaleWidget : vScaleWidget;
+ style = scaleWidget->style;
+
+ if ((option->subControls & SC_SliderGroove) && groove.isValid()) {
+
+ GtkRange *range = (GtkRange*)scaleWidget;
+ GtkAdjustment *adjustment = d->gtk_range_get_adjustment(range);
+ if (adjustment) {
+ d->gtk_adjustment_configure(adjustment,
+ slider->sliderPosition,
+ slider->minimum,
+ slider->maximum,
+ slider->singleStep,
+ slider->singleStep,
+ slider->pageStep);
+ } else {
+ adjustment = (GtkAdjustment*)d->gtk_adjustment_new(slider->sliderPosition,
+ slider->minimum,
+ slider->maximum,
+ slider->singleStep,
+ slider->singleStep,
+ slider->pageStep);
+ d->gtk_range_set_adjustment(range, adjustment);
+ }
+
+ int outerSize;
+ d->gtk_range_set_inverted(range, !horizontal);
+ d->gtk_widget_style_get(scaleWidget, "trough-border", &outerSize, NULL);
+ outerSize++;
+
+ GtkStateType state = gtkPainter.gtkState(option);
+ int focusFrameMargin = 2;
+ QRect grooveRect = option->rect.adjusted(focusFrameMargin, outerSize + focusFrameMargin,
+ -focusFrameMargin, -outerSize - focusFrameMargin);
+
+ gboolean trough_side_details = false; // Indicates if the upper or lower scale background differs
+ if (!d->gtk_check_version(2, 10, 0))
+ d->gtk_widget_style_get((GtkWidget*)(scaleWidget), "trough-side-details", &trough_side_details, NULL);
+
+ if (!trough_side_details) {
+ gtkPainter.paintBox( scaleWidget, "trough", grooveRect, state,
+ GTK_SHADOW_IN, style, QString(QLS("p%0")).arg(slider->sliderPosition));
+ } else {
+ QRect upperGroove = grooveRect;
+ QRect lowerGroove = grooveRect;
+
+ if (horizontal) {
+ if (slider->upsideDown) {
+ lowerGroove.setLeft(handle.center().x());
+ upperGroove.setRight(handle.center().x());
+ } else {
+ upperGroove.setLeft(handle.center().x());
+ lowerGroove.setRight(handle.center().x());
+ }
+ } else {
+ if (!slider->upsideDown) {
+ lowerGroove.setBottom(handle.center().y());
+ upperGroove.setTop(handle.center().y());
+ } else {
+ upperGroove.setBottom(handle.center().y());
+ lowerGroove.setTop(handle.center().y());
+ }
+ }
+
+ gtkPainter.paintBox( scaleWidget, "trough-upper", upperGroove, state,
+ GTK_SHADOW_IN, style, QString(QLS("p%0")).arg(slider->sliderPosition));
+ gtkPainter.paintBox( scaleWidget, "trough-lower", lowerGroove, state,
+ GTK_SHADOW_IN, style, QString(QLS("p%0")).arg(slider->sliderPosition));
+ }
+ }
+
+ if (option->subControls & SC_SliderTickmarks) {
+ painter->setPen(darkOutline);
+ int tickSize = proxy()->pixelMetric(PM_SliderTickmarkOffset, option, widget);
+ int available = proxy()->pixelMetric(PM_SliderSpaceAvailable, slider, widget);
+ int interval = slider->tickInterval;
+
+ if (interval <= 0) {
+ interval = slider->singleStep;
+
+ if (QStyle::sliderPositionFromValue(slider->minimum, slider->maximum, interval,
+ available)
+ - QStyle::sliderPositionFromValue(slider->minimum, slider->maximum,
+ 0, available) < 3)
+ interval = slider->pageStep;
+ }
+
+ if (interval <= 0)
+ interval = 1;
+
+ int v = slider->minimum;
+ int len = proxy()->pixelMetric(PM_SliderLength, slider, widget);
+ while (v <= slider->maximum + 1) {
+ if (v == slider->maximum + 1 && interval == 1)
+ break;
+ const int v_ = qMin(v, slider->maximum);
+ int pos = sliderPositionFromValue(slider->minimum, slider->maximum,
+ v_, (horizontal
+ ? slider->rect.width()
+ : slider->rect.height()) - len,
+ slider->upsideDown) + len / 2;
+ int extra = 2 - ((v_ == slider->minimum || v_ == slider->maximum) ? 1 : 0);
+ if (horizontal) {
+ if (ticksAbove)
+ painter->drawLine(pos, slider->rect.top() + extra,
+ pos, slider->rect.top() + tickSize);
+ if (ticksBelow)
+ painter->drawLine(pos, slider->rect.bottom() - extra,
+ pos, slider->rect.bottom() - tickSize);
+
+ } else {
+ if (ticksAbove)
+ painter->drawLine(slider->rect.left() + extra, pos,
+ slider->rect.left() + tickSize, pos);
+ if (ticksBelow)
+ painter->drawLine(slider->rect.right() - extra, pos,
+ slider->rect.right() - tickSize, pos);
+ }
+
+ // In the case where maximum is max int
+ int nextInterval = v + interval;
+ if (nextInterval < v)
+ break;
+ v = nextInterval;
+ }
+ }
+
+ // Draw slider handle
+ if (option->subControls & SC_SliderHandle) {
+ GtkShadowType shadow = GTK_SHADOW_OUT;
+ GtkStateType state = GTK_STATE_NORMAL;
+
+ if (!(option->state & State_Enabled))
+ state = GTK_STATE_INSENSITIVE;
+ else if (option->state & State_MouseOver && option->activeSubControls & SC_SliderHandle)
+ state = GTK_STATE_PRELIGHT;
+
+ bool horizontal = option->state & State_Horizontal;
+
+ if (slider->state & State_HasFocus) {
+ QStyleOptionFocusRect fropt;
+ fropt.QStyleOption::operator=(*slider);
+ fropt.rect = slider->rect.adjusted(-1, -1 ,1, 1);
+
+ if (horizontal) {
+ fropt.rect.setTop(handle.top() - 3);
+ fropt.rect.setBottom(handle.bottom() + 4);
+
+ } else {
+ fropt.rect.setLeft(handle.left() - 3);
+ fropt.rect.setRight(handle.right() + 3);
+ }
+ proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget);
+ }
+ gtkPainter.paintSlider( scaleWidget, horizontal ? "hscale" : "vscale", handle, state, shadow, style,
+
+ horizontal ? GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL);
+ }
+ painter->setBrush(oldBrush);
+ painter->setPen(oldPen);
+ }
+ break;
+
+#endif // QT_NO_SLIDER
+
+ default:
+ QCleanlooksStyle::drawComplexControl(control, option, painter, widget);
+
+ break;
+ }
+}
+
+
+/*!
+ \reimp
+*/
+void QGtkStyle::drawControl(ControlElement element,
+ const QStyleOption *option,
+ QPainter *painter,
+ const QWidget *widget) const
+{
+ Q_D(const QGtkStyle);
+
+ if (!d->isThemeAvailable()) {
+ QCleanlooksStyle::drawControl(element, option, painter, widget);
+ return;
+ }
+
+ GtkStyle* style = d->gtkStyle();
+ QGtkPainter gtkPainter(painter);
+
+ switch (element) {
+ case CE_ProgressBarLabel:
+ if (const QStyleOptionProgressBar *bar = qstyleoption_cast<const QStyleOptionProgressBar *>(option)) {
+ GtkWidget *gtkProgressBar = d->gtkWidget("GtkProgressBar");
+ if (!gtkProgressBar)
+ return;
+
+ QRect leftRect;
+ QRect rect = bar->rect;
+ GdkColor gdkText = gtkProgressBar->style->fg[GTK_STATE_NORMAL];
+ QColor textColor = QColor(gdkText.red>>8, gdkText.green>>8, gdkText.blue>>8);
+ gdkText = gtkProgressBar->style->fg[GTK_STATE_PRELIGHT];
+ QColor alternateTextColor= QColor(gdkText.red>>8, gdkText.green>>8, gdkText.blue>>8);
+
+ painter->save();
+ bool vertical = false, inverted = false;
+ if (const QStyleOptionProgressBarV2 *bar2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option)) {
+ vertical = (bar2->orientation == Qt::Vertical);
+ inverted = bar2->invertedAppearance;
+ }
+ if (vertical)
+ rect = QRect(rect.left(), rect.top(), rect.height(), rect.width()); // flip width and height
+ const int progressIndicatorPos = (bar->progress - qreal(bar->minimum)) * rect.width() /
+ qMax(qreal(1.0), qreal(bar->maximum) - bar->minimum);
+ if (progressIndicatorPos >= 0 && progressIndicatorPos <= rect.width())
+ leftRect = QRect(rect.left(), rect.top(), progressIndicatorPos, rect.height());
+ if (vertical)
+ leftRect.translate(rect.width() - progressIndicatorPos, 0);
+
+ bool flip = (!vertical && (((bar->direction == Qt::RightToLeft) && !inverted) ||
+ ((bar->direction == Qt::LeftToRight) && inverted)));
+
+ QRegion rightRect = rect;
+ rightRect = rightRect.subtracted(leftRect);
+ painter->setClipRegion(rightRect);
+ painter->setPen(flip ? alternateTextColor : textColor);
+ painter->drawText(rect, bar->text, QTextOption(Qt::AlignAbsolute | Qt::AlignHCenter | Qt::AlignVCenter));
+ if (!leftRect.isNull()) {
+ painter->setPen(flip ? textColor : alternateTextColor);
+ painter->setClipRect(leftRect);
+ painter->drawText(rect, bar->text, QTextOption(Qt::AlignAbsolute | Qt::AlignHCenter | Qt::AlignVCenter));
+ }
+ painter->restore();
+ }
+ break;
+ case CE_PushButtonLabel:
+ if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
+ QRect ir = button->rect;
+ uint tf = Qt::AlignVCenter | Qt::TextShowMnemonic;
+ QPoint buttonShift;
+
+ if (option->state & State_Sunken)
+ buttonShift = QPoint(pixelMetric(PM_ButtonShiftHorizontal, option, widget),
+ proxy()->pixelMetric(PM_ButtonShiftVertical, option, widget));
+
+ if (proxy()->styleHint(SH_UnderlineShortcut, button, widget))
+ tf |= Qt::TextShowMnemonic;
+ else
+ tf |= Qt::TextHideMnemonic;
+
+ if (!button->icon.isNull()) {
+ //Center both icon and text
+ QPoint point;
+
+ QIcon::Mode mode = button->state & State_Enabled ? QIcon::Normal : QIcon::Disabled;
+ if (mode == QIcon::Normal && button->state & State_HasFocus)
+ mode = QIcon::Active;
+
+ QIcon::State state = QIcon::Off;
+
+ if (button->state & State_On)
+ state = QIcon::On;
+
+ QPixmap pixmap = button->icon.pixmap(button->iconSize, mode, state);
+ int w = pixmap.width();
+ int h = pixmap.height();
+
+ if (!button->text.isEmpty())
+ w += button->fontMetrics.boundingRect(option->rect, tf, button->text).width() + 4;
+
+ point = QPoint(ir.x() + ir.width() / 2 - w / 2,
+ ir.y() + ir.height() / 2 - h / 2);
+
+ if (button->direction == Qt::RightToLeft)
+ point.rx() += pixmap.width();
+
+ painter->drawPixmap(visualPos(button->direction, button->rect, point + buttonShift), pixmap);
+
+ if (button->direction == Qt::RightToLeft)
+ ir.translate(-point.x() - 2, 0);
+ else
+ ir.translate(point.x() + pixmap.width() + 2, 0);
+
+ // left-align text if there is
+ if (!button->text.isEmpty())
+ tf |= Qt::AlignLeft;
+
+ } else {
+ tf |= Qt::AlignHCenter;
+ }
+
+ ir.translate(buttonShift);
+
+ if (button->features & QStyleOptionButton::HasMenu)
+ ir = ir.adjusted(0, 0, -pixelMetric(PM_MenuButtonIndicator, button, widget), 0);
+
+ GtkWidget *gtkButton = d->gtkWidget("GtkButton");
+ QPalette pal = button->palette;
+ int labelState = GTK_STATE_INSENSITIVE;
+ if (option->state & State_Enabled)
+ labelState = (option->state & State_MouseOver && !(option->state & State_Sunken)) ?
+ GTK_STATE_PRELIGHT : GTK_STATE_NORMAL;
+
+ GdkColor gdkText = gtkButton->style->fg[labelState];
+ QColor textColor = QColor(gdkText.red>>8, gdkText.green>>8, gdkText.blue>>8);
+ pal.setBrush(QPalette::ButtonText, textColor);
+ proxy()->drawItemText(painter, ir, tf, pal, (button->state & State_Enabled),
+ button->text, QPalette::ButtonText);
+ }
+ break;
+
+ case CE_RadioButton: // Fall through
+ case CE_CheckBox:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
+ bool isRadio = (element == CE_RadioButton);
+
+ // Draw prelight background
+ GtkWidget *gtkRadioButton = d->gtkWidget("GtkRadioButton");
+
+ if (option->state & State_MouseOver) {
+ gtkPainter.paintFlatBox(gtkRadioButton, "checkbutton", option->rect,
+ GTK_STATE_PRELIGHT, GTK_SHADOW_ETCHED_OUT, gtkRadioButton->style);
+ }
+
+ QStyleOptionButton subopt = *btn;
+ subopt.rect = subElementRect(isRadio ? SE_RadioButtonIndicator
+ : SE_CheckBoxIndicator, btn, widget);
+ proxy()->drawPrimitive(isRadio ? PE_IndicatorRadioButton : PE_IndicatorCheckBox,
+ &subopt, painter, widget);
+ subopt.rect = subElementRect(isRadio ? SE_RadioButtonContents
+ : SE_CheckBoxContents, btn, widget);
+ // Get label text color
+ QPalette pal = subopt.palette;
+ int labelState = GTK_STATE_INSENSITIVE;
+ if (option->state & State_Enabled)
+ labelState = (option->state & State_MouseOver) ? GTK_STATE_PRELIGHT : GTK_STATE_NORMAL;
+
+ GdkColor gdkText = gtkRadioButton->style->fg[labelState];
+ QColor textColor = QColor(gdkText.red>>8, gdkText.green>>8, gdkText.blue>>8);
+ pal.setBrush(QPalette::WindowText, textColor);
+ subopt.palette = pal;
+ proxy()->drawControl(isRadio ? CE_RadioButtonLabel : CE_CheckBoxLabel, &subopt, painter, widget);
+
+ if (btn->state & State_HasFocus) {
+ QStyleOptionFocusRect fropt;
+ fropt.QStyleOption::operator=(*btn);
+ fropt.rect = subElementRect(isRadio ? SE_RadioButtonFocusRect
+ : SE_CheckBoxFocusRect, btn, widget);
+ proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget);
+ }
+ }
+ break;
+
+#ifndef QT_NO_COMBOBOX
+
+ case CE_ComboBoxLabel:
+ if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
+ QRect editRect = proxy()->subControlRect(CC_ComboBox, cb, SC_ComboBoxEditField, widget);
+ bool appearsAsList = !proxy()->styleHint(QStyle::SH_ComboBox_Popup, cb, widget);
+ painter->save();
+ painter->setClipRect(editRect);
+
+ if (!cb->currentIcon.isNull()) {
+ QIcon::Mode mode = cb->state & State_Enabled ? QIcon::Normal
+ : QIcon::Disabled;
+ QPixmap pixmap = cb->currentIcon.pixmap(cb->iconSize, mode);
+ QRect iconRect(editRect);
+ iconRect.setWidth(cb->iconSize.width() + 4);
+
+ iconRect = alignedRect(cb->direction,
+ Qt::AlignLeft | Qt::AlignVCenter,
+ iconRect.size(), editRect);
+
+ if (cb->editable)
+ painter->fillRect(iconRect, option->palette.brush(QPalette::Base));
+
+ proxy()->drawItemPixmap(painter, iconRect, Qt::AlignCenter, pixmap);
+
+ if (cb->direction == Qt::RightToLeft)
+ editRect.translate(-4 - cb->iconSize.width(), 0);
+ else
+ editRect.translate(cb->iconSize.width() + 4, 0);
+ }
+
+ if (!cb->currentText.isEmpty() && !cb->editable) {
+ GtkWidget *gtkCombo = d->gtkWidget("GtkComboBox");
+ QPalette pal = cb->palette;
+ int labelState = GTK_STATE_INSENSITIVE;
+
+ if (option->state & State_Enabled)
+ labelState = (option->state & State_MouseOver && !appearsAsList) ? GTK_STATE_PRELIGHT : GTK_STATE_NORMAL;
+
+ GdkColor gdkText = gtkCombo->style->fg[labelState];
+
+ QColor textColor = QColor(gdkText.red>>8, gdkText.green>>8, gdkText.blue>>8);
+
+ pal.setBrush(QPalette::ButtonText, textColor);
+
+ proxy()->drawItemText(painter, editRect.adjusted(1, 0, -1, 0),
+ visualAlignment(cb->direction, Qt::AlignLeft | Qt::AlignVCenter),
+ pal, cb->state & State_Enabled, cb->currentText, QPalette::ButtonText);
+ }
+
+ painter->restore();
+ }
+ break;
+
+#endif // QT_NO_COMBOBOX
+
+ case CE_DockWidgetTitle:
+ painter->save();
+ if (const QStyleOptionDockWidget *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(option)) {
+ const QStyleOptionDockWidgetV2 *v2
+ = qstyleoption_cast<const QStyleOptionDockWidgetV2*>(dwOpt);
+ bool verticalTitleBar = v2 == 0 ? false : v2->verticalTitleBar;
+
+ QRect rect = dwOpt->rect;
+ QRect titleRect = subElementRect(SE_DockWidgetTitleBarText, option, widget).adjusted(-2, 0, -2, 0);
+ QRect r = rect.adjusted(0, 0, -1, -1);
+ if (verticalTitleBar)
+ r.adjust(0, 0, 0, -1);
+
+ if (verticalTitleBar) {
+ QRect r = rect;
+ QSize s = r.size();
+ s.transpose();
+ r.setSize(s);
+
+ titleRect = QRect(r.left() + rect.bottom()
+ - titleRect.bottom(),
+ r.top() + titleRect.left() - rect.left(),
+ titleRect.height(), titleRect.width());
+
+ painter->translate(r.left(), r.top() + r.width());
+ painter->rotate(-90);
+ painter->translate(-r.left(), -r.top());
+
+ rect = r;
+ }
+
+ if (!dwOpt->title.isEmpty()) {
+ QString titleText
+ = painter->fontMetrics().elidedText(dwOpt->title,
+ Qt::ElideRight, titleRect.width());
+ proxy()->drawItemText(painter,
+ titleRect,
+ Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic, dwOpt->palette,
+ dwOpt->state & State_Enabled, titleText,
+ QPalette::WindowText);
+ }
+ }
+ painter->restore();
+ break;
+
+
+
+ case CE_HeaderSection:
+ painter->save();
+
+ // Draws the header in tables.
+ if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
+ Q_UNUSED(header);
+ GtkWidget *gtkTreeView = d->gtkWidget("GtkTreeView");
+ // Get the middle column
+ GtkTreeViewColumn *column = d->gtk_tree_view_get_column((GtkTreeView*)gtkTreeView, 1);
+ Q_ASSERT(column);
+
+ GtkWidget *gtkTreeHeader = column->button;
+ GtkStateType state = gtkPainter.gtkState(option);
+ GtkShadowType shadow = GTK_SHADOW_OUT;
+
+ if (option->state & State_Sunken)
+ shadow = GTK_SHADOW_IN;
+
+ gtkPainter.paintBox(gtkTreeHeader, "button", option->rect.adjusted(-1, 0, 0, 0), state, shadow, gtkTreeHeader->style);
+ }
+
+ painter->restore();
+ break;
+
+#ifndef QT_NO_SIZEGRIP
+
+ case CE_SizeGrip: {
+ GtkWidget *gtkStatusbar = d->gtkWidget("GtkStatusbar.GtkFrame");
+ QRect gripRect = option->rect.adjusted(0, 0, -gtkStatusbar->style->xthickness, -gtkStatusbar->style->ythickness);
+ gtkPainter.paintResizeGrip( gtkStatusbar, "statusbar", gripRect, GTK_STATE_NORMAL,
+ GTK_SHADOW_OUT, QApplication::isRightToLeft() ?
+ GDK_WINDOW_EDGE_SOUTH_WEST : GDK_WINDOW_EDGE_SOUTH_EAST,
+ gtkStatusbar->style);
+ }
+ break;
+
+#endif // QT_NO_SIZEGRIP
+
+ case CE_MenuBarEmptyArea: {
+ GtkWidget *gtkMenubar = d->gtkWidget("GtkMenuBar");
+ GdkColor gdkBg = gtkMenubar->style->bg[GTK_STATE_NORMAL]; // Theme can depend on transparency
+ painter->fillRect(option->rect, QColor(gdkBg.red>>8, gdkBg.green>>8, gdkBg.blue>>8));
+ if (widget) { // See CE_MenuBarItem
+ QRect menuBarRect = widget->rect();
+ QPixmap pixmap(menuBarRect.size());
+ pixmap.fill(Qt::transparent);
+ QPainter pmPainter(&pixmap);
+ QGtkPainter gtkMenuBarPainter(&pmPainter);
+ GtkShadowType shadow_type;
+ d->gtk_widget_style_get(gtkMenubar, "shadow-type", &shadow_type, NULL);
+ gtkMenuBarPainter.paintBox( gtkMenubar, "menubar", menuBarRect,
+ GTK_STATE_NORMAL, shadow_type, gtkMenubar->style);
+ pmPainter.end();
+ painter->drawPixmap(option->rect, pixmap, option->rect);
+ }
+ }
+ break;
+
+ case CE_MenuBarItem:
+ painter->save();
+
+ if (const QStyleOptionMenuItem *mbi = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
+ GtkWidget *gtkMenubarItem = d->gtkWidget("GtkMenuBar.GtkMenuItem");
+ GtkWidget *gtkMenubar = d->gtkWidget("GtkMenuBar");
+
+ style = gtkMenubarItem->style;
+
+ if (widget) {
+ // Since Qt does not currently allow filling the entire background
+ // we use a hack for this by making a complete menubar each time and
+ // paint with the correct offset inside it. Pixmap caching should resolve
+ // most of the performance penalty.
+ QRect menuBarRect = widget->rect();
+ QPixmap pixmap(menuBarRect.size());
+ pixmap.fill(Qt::transparent);
+ QPainter pmPainter(&pixmap);
+ QGtkPainter menubarPainter(&pmPainter);
+ GtkShadowType shadow_type;
+ d->gtk_widget_style_get(gtkMenubar, "shadow-type", &shadow_type, NULL);
+ GdkColor gdkBg = gtkMenubar->style->bg[GTK_STATE_NORMAL]; // Theme can depend on transparency
+ painter->fillRect(option->rect, QColor(gdkBg.red>>8, gdkBg.green>>8, gdkBg.blue>>8));
+ menubarPainter.paintBox(gtkMenubar, "menubar", menuBarRect,
+ GTK_STATE_NORMAL, shadow_type, gtkMenubar->style);
+ pmPainter.end();
+ painter->drawPixmap(option->rect, pixmap, option->rect);
+ }
+
+ QStyleOptionMenuItem item = *mbi;
+ bool act = mbi->state & State_Selected && mbi->state & State_Sunken;
+ bool dis = !(mbi->state & State_Enabled);
+ item.rect = mbi->rect;
+ GdkColor gdkText = gtkMenubarItem->style->fg[dis ? GTK_STATE_INSENSITIVE : GTK_STATE_NORMAL];
+ GdkColor gdkHText = gtkMenubarItem->style->fg[GTK_STATE_PRELIGHT];
+ QColor normalTextColor = QColor(gdkText.red>>8, gdkText.green>>8, gdkText.blue>>8);
+ QColor highlightedTextColor = QColor(gdkHText.red>>8, gdkHText.green>>8, gdkHText.blue>>8);
+ item.palette.setBrush(QPalette::HighlightedText, highlightedTextColor);
+ item.palette.setBrush(QPalette::Text, normalTextColor);
+ item.palette.setBrush(QPalette::ButtonText, normalTextColor);
+ QCommonStyle::drawControl(element, &item, painter, widget);
+
+ if (act) {
+ GtkShadowType shadowType = GTK_SHADOW_NONE;
+ d->gtk_widget_style_get (gtkMenubarItem, "selected-shadow-type", &shadowType, NULL);
+ gtkPainter.paintBox(gtkMenubarItem, "menuitem", option->rect.adjusted(0, 0, 0, 3),
+ GTK_STATE_PRELIGHT, shadowType, gtkMenubarItem->style);
+ //draw text
+ QPalette::ColorRole textRole = dis ? QPalette::Text : QPalette::HighlightedText;
+ uint alignment = Qt::AlignCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
+
+ if (!proxy()->styleHint(SH_UnderlineShortcut, mbi, widget))
+ alignment |= Qt::TextHideMnemonic;
+
+ proxy()->drawItemText(painter, item.rect, alignment, item.palette, mbi->state & State_Enabled, mbi->text, textRole);
+ }
+ }
+ painter->restore();
+ break;
+
+ case CE_Splitter: {
+ GtkWidget *gtkWindow = d->gtkWidget("GtkWindow"); // The Murrine Engine currently assumes a widget is passed
+ gtkPainter.paintHandle(gtkWindow, "splitter", option->rect, gtkPainter.gtkState(option), GTK_SHADOW_NONE,
+ !(option->state & State_Horizontal) ? GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL,
+ style);
+ }
+ break;
+
+#ifndef QT_NO_TOOLBAR
+
+ case CE_ToolBar:
+ if (const QStyleOptionToolBar *toolbar = qstyleoption_cast<const QStyleOptionToolBar *>(option)) {
+ // Reserve the beveled appearance only for mainwindow toolbars
+ if (!(widget && qobject_cast<const QMainWindow*> (widget->parentWidget())))
+ break;
+
+ QRect rect = option->rect;
+ // There is a 1 pixel gap between toolbar lines in some styles (i.e Human)
+ if (toolbar->positionWithinLine != QStyleOptionToolBar::End)
+ rect.adjust(0, 0, 1, 0);
+
+ GtkWidget *gtkToolbar = d->gtkWidget("GtkToolbar");
+ GtkShadowType shadow_type = GTK_SHADOW_NONE;
+ d->gtk_widget_style_get(gtkToolbar, "shadow-type", &shadow_type, NULL);
+ gtkPainter.paintBox( gtkToolbar, "toolbar", rect,
+ GTK_STATE_NORMAL, shadow_type, gtkToolbar->style);
+ }
+ break;
+
+#endif // QT_NO_TOOLBAR
+
+ case CE_MenuItem:
+ painter->save();
+
+ // Draws one item in a popup menu.
+ if (const QStyleOptionMenuItem *menuItem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
+ const int windowsItemFrame = 2; // menu item frame width
+ const int windowsItemHMargin = 3; // menu item hor text margin
+ const int windowsItemVMargin = 26; // menu item ver text margin
+ const int windowsRightBorder = 15; // right border on windows
+ GtkWidget *gtkMenuItem = menuItem->checked ? d->gtkWidget("GtkMenu.GtkCheckMenuItem") :
+ d->gtkWidget("GtkMenu.GtkMenuItem");
+
+ style = gtkPainter.getStyle(gtkMenuItem);
+ QColor shadow = option->palette.dark().color();
+
+ if (menuItem->menuItemType == QStyleOptionMenuItem::Separator) {
+ GtkWidget *gtkMenuSeparator = d->gtkWidget("GtkMenu.GtkSeparatorMenuItem");
+ painter->setPen(shadow.lighter(106));
+ gboolean wide_separators = 0;
+ gint separator_height = 0;
+ guint horizontal_padding = 3;
+ QRect separatorRect = option->rect;
+ if (!d->gtk_check_version(2, 10, 0)) {
+ d->gtk_widget_style_get(gtkMenuSeparator,
+ "wide-separators", &wide_separators,
+ "separator-height", &separator_height,
+ "horizontal-padding", &horizontal_padding,
+ NULL);
+ }
+ separatorRect.setHeight(option->rect.height() - 2 * gtkMenuSeparator->style->ythickness);
+ separatorRect.setWidth(option->rect.width() - 2 * (horizontal_padding + gtkMenuSeparator->style->xthickness));
+ separatorRect.moveCenter(option->rect.center());
+ if (wide_separators)
+ gtkPainter.paintBox( gtkMenuSeparator, "hseparator",
+ separatorRect, GTK_STATE_NORMAL, GTK_SHADOW_NONE, gtkMenuSeparator->style);
+ else
+ gtkPainter.paintHline( gtkMenuSeparator, "hseparator",
+ separatorRect, GTK_STATE_NORMAL, gtkMenuSeparator->style,
+ 0, option->rect.right() - 1, 1);
+ painter->restore();
+ break;
+ }
+
+ bool selected = menuItem->state & State_Selected && menuItem->state & State_Enabled;
+
+ if (selected) {
+ QRect rect = option->rect;
+#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);
+ }
+
+ bool checkable = menuItem->checkType != QStyleOptionMenuItem::NotCheckable;
+ bool checked = menuItem->checked;
+ bool enabled = menuItem->state & State_Enabled;
+ bool ignoreCheckMark = false;
+
+ gint checkSize;
+ d->gtk_widget_style_get(d->gtkWidget("GtkMenu.GtkCheckMenuItem"), "indicator-size", &checkSize, NULL);
+
+ int checkcol = qMax(menuItem->maxIconWidth, qMax(20, checkSize));
+
+#ifndef QT_NO_COMBOBOX
+
+ if (qobject_cast<const QComboBox*>(widget))
+ ignoreCheckMark = true; // Ignore the checkmarks provided by the QComboMenuDelegate
+
+#endif
+ if (!ignoreCheckMark) {
+ // Check
+ QRect checkRect(option->rect.left() + 7, option->rect.center().y() - checkSize/2 + 1, checkSize, checkSize);
+ checkRect = visualRect(menuItem->direction, menuItem->rect, checkRect);
+
+ if (checkable && menuItem->icon.isNull()) {
+ // Some themes such as aero-clone draw slightly outside the paint rect
+ int spacing = 1; // ### Consider using gtkCheckBox : "indicator-spacing" instead
+
+ if (menuItem->checkType & QStyleOptionMenuItem::Exclusive) {
+ // Radio button
+ GtkShadowType shadow = GTK_SHADOW_OUT;
+ GtkStateType state = gtkPainter.gtkState(option);
+
+ if (selected)
+ state = GTK_STATE_PRELIGHT;
+ if (checked)
+ shadow = GTK_SHADOW_IN;
+
+ gtkPainter.setClipRect(checkRect.adjusted(-spacing, -spacing, spacing, spacing));
+ gtkPainter.paintOption(gtkMenuItem, checkRect.translated(-spacing, -spacing), state, shadow,
+ gtkMenuItem->style, QLS("option"));
+ gtkPainter.setClipRect(QRect());
+
+ } else {
+ // Check box
+ if (menuItem->icon.isNull()) {
+ GtkShadowType shadow = GTK_SHADOW_OUT;
+ GtkStateType state = gtkPainter.gtkState(option);
+
+ if (selected)
+ state = GTK_STATE_PRELIGHT;
+ if (checked)
+ shadow = GTK_SHADOW_IN;
+
+ gtkPainter.setClipRect(checkRect.adjusted(-spacing, -spacing, -spacing, -spacing));
+ gtkPainter.paintCheckbox(gtkMenuItem, checkRect.translated(-spacing, -spacing), state, shadow,
+ gtkMenuItem->style, QLS("check"));
+ gtkPainter.setClipRect(QRect());
+ }
+ }
+ }
+
+ } else {
+ // Ignore checkmark
+ if (menuItem->icon.isNull())
+ checkcol = 0;
+ else
+ checkcol = menuItem->maxIconWidth;
+ }
+
+ bool dis = !(menuItem->state & State_Enabled);
+ bool act = menuItem->state & State_Selected;
+ const QStyleOption *opt = option;
+ const QStyleOptionMenuItem *menuitem = menuItem;
+ QPainter *p = painter;
+ QRect vCheckRect = visualRect(opt->direction, menuitem->rect,
+ QRect(menuitem->rect.x() + 3, menuitem->rect.y(),
+ checkcol, menuitem->rect.height()));
+
+ if (!menuItem->icon.isNull()) {
+ QIcon::Mode mode = dis ? QIcon::Disabled : QIcon::Normal;
+
+ if (act && !dis)
+ mode = QIcon::Active;
+
+ QPixmap pixmap;
+ int smallIconSize = proxy()->pixelMetric(PM_SmallIconSize, option, widget);
+ QSize iconSize(smallIconSize, smallIconSize);
+
+#ifndef QT_NO_COMBOBOX
+ if (const QComboBox *combo = qobject_cast<const QComboBox*>(widget))
+ iconSize = combo->iconSize();
+
+#endif // QT_NO_COMBOBOX
+ if (checked)
+ pixmap = menuItem->icon.pixmap(iconSize, mode, QIcon::On);
+ else
+ pixmap = menuItem->icon.pixmap(iconSize, mode);
+
+ int pixw = pixmap.width();
+ int pixh = pixmap.height();
+ QRect pmr(0, 0, pixw, pixh);
+ pmr.moveCenter(vCheckRect.center() - QPoint(0, 1));
+ painter->setPen(menuItem->palette.text().color());
+ if (!ignoreCheckMark && checkable && checked) {
+ QStyleOption opt = *option;
+
+ if (act) {
+ QColor activeColor = mergedColors(option->palette.background().color(),
+ option->palette.highlight().color());
+ opt.palette.setBrush(QPalette::Button, activeColor);
+ }
+ opt.state |= State_Sunken;
+ opt.rect = vCheckRect;
+ proxy()->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);
+ else
+ painter->setPen(textColor);
+
+ int x, y, w, h;
+ menuitem->rect.getRect(&x, &y, &w, &h);
+ int tab = menuitem->tabWidth;
+ int xm = windowsItemFrame + checkcol + windowsItemHMargin;
+ int xpos = menuitem->rect.x() + xm + 1;
+ QRect textRect(xpos, y + windowsItemVMargin, w - xm - windowsRightBorder - tab + 1, h - 2 * windowsItemVMargin);
+ QRect vTextRect = visualRect(opt->direction, menuitem->rect, textRect);
+ QString s = menuitem->text;
+
+ if (!s.isEmpty()) { // Draw text
+ p->save();
+ int t = s.indexOf(QLatin1Char('\t'));
+ int text_flags = Qt::AlignVCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
+
+ if (!proxy()->styleHint(SH_UnderlineShortcut, menuitem, widget))
+ text_flags |= Qt::TextHideMnemonic;
+
+ // Draw shortcut right aligned
+ text_flags |= Qt::AlignRight;
+
+ if (t >= 0) {
+ int rightMargin = 12; // Hardcode for now
+ QRect vShortcutRect = visualRect(opt->direction, menuitem->rect,
+ QRect(textRect.topRight(), QPoint(menuitem->rect.right() - rightMargin, textRect.bottom())));
+
+ if (dis)
+ p->setPen(disabledTextColor);
+ p->drawText(vShortcutRect, text_flags , s.mid(t + 1));
+ s = s.left(t);
+ }
+
+ text_flags &= ~Qt::AlignRight;
+ text_flags |= Qt::AlignLeft;
+ QFont font = menuitem->font;
+ if (menuitem->menuItemType == QStyleOptionMenuItem::DefaultItem)
+ font.setBold(true);
+ p->setFont(font);
+
+ if (dis)
+ p->setPen(disabledTextColor);
+ p->drawText(vTextRect, text_flags, s.left(t));
+ p->restore();
+ }
+
+ // Arrow
+ if (menuItem->menuItemType == QStyleOptionMenuItem::SubMenu) {// draw sub menu arrow
+
+ QFontMetrics fm(menuitem->font);
+ int arrow_size = fm.ascent() + fm.descent() - 2 * gtkMenuItem->style->ythickness;
+ gfloat arrow_scaling = 0.8;
+ int extra = 0;
+ if (!d->gtk_check_version(2, 16, 0)) {
+ // "arrow-scaling" is actually hardcoded and fails on hardy (see gtk+-2.12/gtkmenuitem.c)
+ // though the current documentation states otherwise
+ d->gtk_widget_style_get(gtkMenuItem, "arrow-scaling", &arrow_scaling, NULL);
+ // in versions < 2.16 ythickness was previously subtracted from the arrow_size
+ extra = 2 * gtkMenuItem->style->ythickness;
+ }
+
+ int horizontal_padding;
+ d->gtk_widget_style_get(gtkMenuItem, "horizontal-padding", &horizontal_padding, NULL);
+
+ const int dim = static_cast<int>(arrow_size * arrow_scaling) + extra;
+ int xpos = menuItem->rect.left() + menuItem->rect.width() - horizontal_padding - dim;
+ QRect vSubMenuRect = visualRect(option->direction, menuItem->rect,
+ QRect(xpos, menuItem->rect.top() +
+ menuItem->rect.height() / 2 - dim / 2, dim, dim));
+ GtkStateType state = enabled ? (act ? GTK_STATE_PRELIGHT: GTK_STATE_NORMAL) : GTK_STATE_INSENSITIVE;
+ GtkShadowType shadowType = (state == GTK_STATE_PRELIGHT) ? GTK_SHADOW_OUT : GTK_SHADOW_IN;
+ gtkPainter.paintArrow(gtkMenuItem, "menuitem", vSubMenuRect, QApplication::isRightToLeft() ? GTK_ARROW_LEFT : GTK_ARROW_RIGHT, state,
+ shadowType, FALSE, style);
+ }
+ }
+ painter->restore();
+ break;
+
+ case CE_PushButton:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
+ GtkWidget *gtkButton = d->gtkWidget("GtkButton");
+ proxy()->drawControl(CE_PushButtonBevel, btn, painter, widget);
+ QStyleOptionButton subopt = *btn;
+ subopt.rect = subElementRect(SE_PushButtonContents, btn, widget);
+ gint interiorFocus = true;
+ d->gtk_widget_style_get(gtkButton, "interior-focus", &interiorFocus, NULL);
+ int xt = interiorFocus ? gtkButton->style->xthickness : 0;
+ int yt = interiorFocus ? gtkButton->style->ythickness : 0;
+
+ if (btn->features & QStyleOptionButton::Flat && btn->state & State_HasFocus)
+ // The normal button focus rect does not work well for flat buttons in Clearlooks
+ proxy()->drawPrimitive(PE_FrameFocusRect, option, painter, widget);
+ else if (btn->state & State_HasFocus)
+ gtkPainter.paintFocus(gtkButton, "button",
+ option->rect.adjusted(xt, yt, -xt, -yt),
+ btn->state & State_Sunken ? GTK_STATE_ACTIVE : GTK_STATE_NORMAL,
+ gtkButton->style);
+
+ proxy()->drawControl(CE_PushButtonLabel, &subopt, painter, widget);
+ }
+ break;
+
+#ifndef QT_NO_TABBAR
+
+ case CE_TabBarTabShape:
+ if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(option)) {
+ GtkWidget *gtkNotebook = d->gtkWidget("GtkNotebook");
+ style = gtkPainter.getStyle(gtkNotebook);
+
+ QRect rect = option->rect;
+ GtkShadowType shadow = GTK_SHADOW_OUT;
+ GtkStateType state = GTK_STATE_ACTIVE;
+ if (tab->state & State_Selected)
+ state = GTK_STATE_NORMAL;
+
+ bool selected = (tab->state & State_Selected);
+ 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;
+ }
+ int topIndent = 3;
+ int bottomIndent = 1;
+ int tabOverlap = 1;
+ painter->save();
+
+ switch (tab->shape) {
+ case QTabBar::RoundedNorth:
+ if (!selected)
+ rect.adjust(first ? 0 : -tabOverlap, topIndent, last ? 0 : tabOverlap, -bottomIndent);
+ gtkPainter.paintExtention( gtkNotebook, "tab", rect,
+ state, shadow, GTK_POS_BOTTOM, style);
+ break;
+
+ case QTabBar::RoundedSouth:
+ if (!selected)
+ rect.adjust(first ? 0 : -tabOverlap, 0, last ? 0 : tabOverlap, -topIndent);
+ gtkPainter.paintExtention( gtkNotebook, "tab", rect.adjusted(0, 1, 0, 0),
+ state, shadow, GTK_POS_TOP, style);
+ break;
+
+ case QTabBar::RoundedWest:
+ if (!selected)
+ rect.adjust(topIndent, 0, -bottomIndent, 0);
+ gtkPainter.paintExtention( gtkNotebook, "tab", rect, state, shadow, GTK_POS_RIGHT, style);
+ break;
+
+ case QTabBar::RoundedEast:
+ if (!selected)
+ rect.adjust(bottomIndent, 0, -topIndent, 0);
+ gtkPainter.paintExtention( gtkNotebook, "tab", rect, state, shadow, GTK_POS_LEFT, style);
+ break;
+
+ default:
+ QCleanlooksStyle::drawControl(element, option, painter, widget);
+ break;
+ }
+
+ painter->restore();
+ }
+
+ break;
+
+#endif //QT_NO_TABBAR
+
+ case CE_ProgressBarGroove:
+ if (const QStyleOptionProgressBar *bar = qstyleoption_cast<const QStyleOptionProgressBar *>(option)) {
+ Q_UNUSED(bar);
+ GtkWidget *gtkProgressBar = d->gtkWidget("GtkProgressBar");
+ GtkStateType state = gtkPainter.gtkState(option);
+ gtkPainter.paintBox( gtkProgressBar, "trough", option->rect, state, GTK_SHADOW_IN, gtkProgressBar->style);
+ }
+
+ break;
+
+ case CE_ProgressBarContents:
+ if (const QStyleOptionProgressBar *bar = qstyleoption_cast<const QStyleOptionProgressBar *>(option)) {
+ GtkStateType state = option->state & State_Enabled ? GTK_STATE_NORMAL : GTK_STATE_INSENSITIVE;
+ GtkWidget *gtkProgressBar = d->gtkWidget("GtkProgressBar");
+ style = gtkProgressBar->style;
+ gtkPainter.paintBox( gtkProgressBar, "trough", option->rect, state, GTK_SHADOW_IN, style);
+ int xt = style->xthickness;
+ int yt = style->ythickness;
+ QRect rect = bar->rect.adjusted(xt, yt, -xt, -yt);
+ bool vertical = false;
+ bool inverted = false;
+ bool indeterminate = (bar->minimum == 0 && bar->maximum == 0);
+ // Get extra style options if version 2
+
+ if (const QStyleOptionProgressBarV2 *bar2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option)) {
+ vertical = (bar2->orientation == Qt::Vertical);
+ inverted = bar2->invertedAppearance;
+ }
+
+ // If the orientation is vertical, we use a transform to rotate
+ // the progress bar 90 degrees clockwise. This way we can use the
+ // same rendering code for both orientations.
+ if (vertical) {
+ rect.translate(xt, -yt * 2);
+ rect = QRect(rect.left(), rect.top(), rect.height(), rect.width()); // Flip width and height
+ QTransform m = QTransform::fromTranslate(rect.height(), 0);
+ m.rotate(90.0);
+ painter->setTransform(m);
+ }
+
+ int maxWidth = rect.width();
+ int minWidth = 4;
+
+ qint64 progress = (qint64)qMax(bar->progress, bar->minimum); // Workaround for bug in QProgressBar
+ double vc6_workaround = ((progress - qint64(bar->minimum)) / double(qint64(bar->maximum) - qint64(bar->minimum))) * maxWidth;
+ int progressBarWidth = (int(vc6_workaround) > minWidth ) ? int(vc6_workaround) : minWidth;
+ int width = indeterminate ? maxWidth : progressBarWidth;
+ bool reverse = (!vertical && (bar->direction == Qt::RightToLeft)) || vertical;
+
+ if (inverted)
+ reverse = !reverse;
+
+ int maximum = 2;
+ int fakePos = 0;
+ if (bar->minimum == bar->maximum)
+ maximum = 0;
+ if (bar->progress == bar->maximum)
+ fakePos = maximum;
+ else if (bar->progress > bar->minimum)
+ fakePos = maximum - 1;
+
+ d->gtk_progress_configure((GtkProgress*)gtkProgressBar, fakePos, 0, maximum);
+
+ QRect progressBar;
+
+ if (!indeterminate) {
+ if (!reverse)
+ progressBar.setRect(rect.left(), rect.top(), width, rect.height());
+ else
+ progressBar.setRect(rect.right() - width, rect.top(), width, rect.height());
+
+ } else {
+ Q_D(const QGtkStyle);
+ int slideWidth = ((rect.width() - 4) * 2) / 3;
+ int step = ((d->animateStep * slideWidth) / d->animationFps) % slideWidth;
+ if ((((d->animateStep * slideWidth) / d->animationFps) % (2 * slideWidth)) >= slideWidth)
+ step = slideWidth - step;
+ progressBar.setRect(rect.left() + step, rect.top(), slideWidth / 2, rect.height());
+ }
+
+ QString key = QString(QLS("%0")).arg(fakePos);
+ if (inverted) {
+ key += QLatin1String("inv");
+ gtkPainter.setFlipHorizontal(true);
+ }
+ gtkPainter.paintBox( gtkProgressBar, "bar", progressBar, GTK_STATE_SELECTED, GTK_SHADOW_OUT, style, key);
+ }
+
+ break;
+
+ default:
+ QCleanlooksStyle::drawControl(element, option, painter, widget);
+ }
+}
+
+/*!
+ \reimp
+*/
+QRect QGtkStyle::subControlRect(ComplexControl control, const QStyleOptionComplex *option,
+ SubControl subControl, const QWidget *widget) const
+{
+ Q_D(const QGtkStyle);
+
+ QRect rect = QWindowsStyle::subControlRect(control, option, subControl, widget);
+ if (!d->isThemeAvailable())
+ return QCleanlooksStyle::subControlRect(control, option, subControl, widget);
+
+ switch (control) {
+ case CC_TitleBar:
+ return QCleanlooksStyle::subControlRect(control, option, subControl, widget);
+
+ case CC_Slider:
+ if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
+ // Reserve space for outside focus rect
+ QStyleOptionSlider sliderCopy = *slider;
+ sliderCopy.rect = option->rect.adjusted(2, 2, -2, -2);
+ return QCleanlooksStyle::subControlRect(control, &sliderCopy, subControl, widget);
+ }
+
+ break;
+
+#ifndef QT_NO_GROUPBOX
+
+ case CC_GroupBox:
+ if (qstyleoption_cast<const QStyleOptionGroupBox *>(option)) {
+ rect = option->rect.adjusted(0, groupBoxTopMargin, 0, -groupBoxBottomMargin);
+ int topMargin = 0;
+ int topHeight = 0;
+ topHeight = 10;
+ QRect frameRect = rect;
+ frameRect.setTop(topMargin);
+
+ if (subControl == SC_GroupBoxFrame)
+ return rect;
+ else if (subControl == SC_GroupBoxContents) {
+ int margin = 0;
+ int leftMarginExtension = 8;
+ return frameRect.adjusted(leftMarginExtension + margin, margin + topHeight + groupBoxTitleMargin, -margin, -margin);
+ }
+
+ if (const QGroupBox *groupBoxWidget = qobject_cast<const QGroupBox *>(widget)) {
+ //Prepare metrics for a bold font
+ QFont font = widget->font();
+ font.setBold(true);
+ QFontMetrics fontMetrics(font);
+ QSize textRect = fontMetrics.boundingRect(groupBoxWidget->title()).size() + QSize(4, 4);
+ int indicatorWidth = proxy()->pixelMetric(PM_IndicatorWidth, option, widget);
+ int indicatorHeight = proxy()->pixelMetric(PM_IndicatorHeight, option, widget);
+
+ if (subControl == SC_GroupBoxCheckBox) {
+ rect.setWidth(indicatorWidth);
+ rect.setHeight(indicatorHeight);
+ rect.moveTop((textRect.height() - indicatorHeight) / 2);
+
+ } else if (subControl == SC_GroupBoxLabel) {
+ if (groupBoxWidget->isCheckable())
+ rect.adjust(indicatorWidth + 4, 0, 0, 0);
+ rect.setSize(textRect);
+ }
+ rect = visualRect(option->direction, option->rect, rect);
+ }
+ }
+
+ return rect;
+
+#endif
+#ifndef QT_NO_SPINBOX
+
+ case CC_SpinBox:
+ if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
+ GtkWidget *gtkSpinButton = d->gtkWidget("GtkSpinButton");
+ int center = spinbox->rect.height() / 2;
+ int xt = spinbox->frame ? gtkSpinButton->style->xthickness : 0;
+ int yt = spinbox->frame ? gtkSpinButton->style->ythickness : 0;
+ int y = yt;
+
+ QSize bs;
+ bs.setHeight(qMax(8, spinbox->rect.height()/2 - y));
+ bs.setWidth(d->getSpinboxArrowSize());
+ int x, lx, rx;
+ x = spinbox->rect.width() - y - bs.width() + 2;
+ lx = xt;
+ rx = x - xt;
+
+ switch (subControl) {
+
+ case SC_SpinBoxUp:
+ if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons)
+ return QRect();
+ rect = QRect(x, xt, bs.width(), center - yt);
+ break;
+
+ case SC_SpinBoxDown:
+ if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons)
+ return QRect();
+ rect = QRect(x, center, bs.width(), spinbox->rect.bottom() - center - yt + 1);
+ break;
+
+ case SC_SpinBoxEditField:
+ if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons)
+ rect = QRect(lx, yt, spinbox->rect.width() - 2*xt, spinbox->rect.height() - 2*yt);
+ else
+ rect = QRect(lx, yt, rx - qMax(xt - 1, 0), spinbox->rect.height() - 2*yt);
+ break;
+
+ case SC_SpinBoxFrame:
+ rect = spinbox->rect;
+
+ default:
+ break;
+ }
+
+ rect = visualRect(spinbox->direction, spinbox->rect, rect);
+ }
+
+ break;
+
+#endif // Qt_NO_SPINBOX
+#ifndef QT_NO_COMBOBOX
+
+ case CC_ComboBox:
+ if (const QStyleOptionComboBox *box = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
+ // We employ the gtk widget to position arrows and separators for us
+ GtkWidget *gtkCombo = box->editable ? d->gtkWidget("GtkComboBoxEntry")
+ : d->gtkWidget("GtkComboBox");
+ d->gtk_widget_set_direction(gtkCombo, (option->direction == Qt::RightToLeft) ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR);
+ GtkAllocation geometry = {0, 0, qMax(0, option->rect.width()), qMax(0, option->rect.height())};
+ d->gtk_widget_size_allocate(gtkCombo, &geometry);
+ int appears_as_list = !proxy()->styleHint(QStyle::SH_ComboBox_Popup, option, widget);
+ QHashableLatin1Literal arrowPath("GtkComboBoxEntry.GtkToggleButton");
+ if (!box->editable) {
+ if (appears_as_list)
+ arrowPath = "GtkComboBox.GtkToggleButton";
+ else
+ arrowPath = "GtkComboBox.GtkToggleButton.GtkHBox.GtkArrow";
+ }
+
+ GtkWidget *arrowWidget = d->gtkWidget(arrowPath);
+ if (!arrowWidget)
+ return QCleanlooksStyle::subControlRect(control, option, subControl, widget);
+
+ QRect buttonRect(option->rect.left() + arrowWidget->allocation.x,
+ option->rect.top() + arrowWidget->allocation.y,
+ arrowWidget->allocation.width, arrowWidget->allocation.height);
+
+ switch (subControl) {
+
+ case SC_ComboBoxArrow: // Note: this indicates the arrowbutton for editable combos
+ rect = buttonRect;
+ break;
+
+ case SC_ComboBoxEditField: {
+ rect = visualRect(option->direction, option->rect, rect);
+ int xMargin = box->editable ? 1 : 4, yMargin = 2;
+ rect.setRect(option->rect.left() + gtkCombo->style->xthickness + xMargin,
+ option->rect.top() + gtkCombo->style->ythickness + yMargin,
+ option->rect.width() - buttonRect.width() - 2*(gtkCombo->style->xthickness + xMargin),
+ option->rect.height() - 2*(gtkCombo->style->ythickness + yMargin));
+ rect = visualRect(option->direction, option->rect, rect);
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+
+ break;
+
+#endif // QT_NO_COMBOBOX
+
+ default:
+ break;
+ }
+
+ return rect;
+}
+
+/*!
+ \reimp
+*/
+QSize QGtkStyle::sizeFromContents(ContentsType type, const QStyleOption *option,
+ const QSize &size, const QWidget *widget) const
+{
+ Q_D(const QGtkStyle);
+
+ QSize newSize = QCleanlooksStyle::sizeFromContents(type, option, size, widget);
+ if (!d->isThemeAvailable())
+ return newSize;
+
+ switch (type) {
+
+ case CT_ToolButton:
+ if (const QStyleOptionToolButton *toolbutton = qstyleoption_cast<const QStyleOptionToolButton *>(option)) {
+ GtkWidget *gtkButton = d->gtkWidget("GtkToolButton.GtkButton");
+ newSize = size + QSize(2 * gtkButton->style->xthickness, 2 + 2 * gtkButton->style->ythickness);
+ if (widget && qobject_cast<QToolBar *>(widget->parentWidget())) {
+ QSize minSize(0, 25);
+ if (toolbutton->toolButtonStyle != Qt::ToolButtonTextOnly)
+ minSize = toolbutton->iconSize + QSize(12, 12);
+ newSize = newSize.expandedTo(minSize);
+ }
+
+ if (toolbutton->features & QStyleOptionToolButton::HasMenu)
+ newSize += QSize(6, 0);
+ }
+ break;
+ case CT_MenuItem:
+ if (const QStyleOptionMenuItem *menuItem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
+ int textMargin = 8;
+
+ if (menuItem->menuItemType == QStyleOptionMenuItem::Separator) {
+ GtkWidget *gtkMenuSeparator = d->gtkWidget("GtkMenu.GtkSeparatorMenuItem");
+ GtkRequisition sizeReq = {0, 0};
+ d->gtk_widget_size_request(gtkMenuSeparator, &sizeReq);
+ newSize = QSize(size.width(), sizeReq.height);
+ break;
+ }
+
+ GtkWidget *gtkMenuItem = d->gtkWidget("GtkMenu.GtkCheckMenuItem");
+ GtkStyle* style = gtkMenuItem->style;
+
+ // Note we get the perfect height for the default font since we
+ // set a fake text label on the gtkMenuItem
+ // But if custom fonts are used on the widget we need a minimum size
+ GtkRequisition sizeReq = {0, 0};
+ d->gtk_widget_size_request(gtkMenuItem, &sizeReq);
+ newSize.setHeight(qMax(newSize.height() - 4, sizeReq.height));
+ newSize += QSize(textMargin + style->xthickness - 1, 0);
+
+ // Cleanlooks assumes a check column of 20 pixels so we need to
+ // expand it a bit
+ gint checkSize;
+ d->gtk_widget_style_get(gtkMenuItem, "indicator-size", &checkSize, NULL);
+ newSize.setWidth(newSize.width() + qMax(0, checkSize - 20));
+ }
+
+ break;
+
+ case CT_SpinBox:
+ // QSpinBox does some nasty things that depends on CT_LineEdit
+ newSize = size + QSize(0, -d->gtkWidget("GtkSpinButton")->style->ythickness * 2);
+ break;
+
+ case CT_PushButton:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
+ GtkWidget *gtkButton = d->gtkWidget("GtkButton");
+ gint focusPadding, focusWidth;
+ d->gtk_widget_style_get(gtkButton, "focus-padding", &focusPadding, NULL);
+ d->gtk_widget_style_get(gtkButton, "focus-line-width", &focusWidth, NULL);
+ newSize = size;
+ newSize += QSize(2*gtkButton->style->xthickness + 4, 2*gtkButton->style->ythickness);
+ newSize += QSize(2*(focusWidth + focusPadding + 2), 2*(focusWidth + focusPadding));
+
+ GtkWidget *gtkButtonBox = d->gtkWidget("GtkHButtonBox");
+ gint minWidth = 85, minHeight = 0;
+ d->gtk_widget_style_get(gtkButtonBox, "child-min-width", &minWidth,
+ "child-min-height", &minHeight, NULL);
+ if (!btn->text.isEmpty() && newSize.width() < minWidth)
+ newSize.setWidth(minWidth);
+ if (newSize.height() < minHeight)
+ newSize.setHeight(minHeight);
+ }
+
+ break;
+
+ case CT_Slider: {
+ GtkWidget *gtkSlider = d->gtkWidget("GtkHScale");
+ newSize = size + QSize(2*gtkSlider->style->xthickness, 2*gtkSlider->style->ythickness);
+ }
+ break;
+
+ case CT_LineEdit: {
+ GtkWidget *gtkEntry = d->gtkWidget("GtkEntry");
+ newSize = size + QSize(2*gtkEntry->style->xthickness, 2 + 2*gtkEntry->style->ythickness);
+ }
+ break;
+
+ case CT_ItemViewItem:
+ newSize += QSize(0, 2);
+ break;
+
+ case CT_ComboBox:
+ if (const QStyleOptionComboBox *combo = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
+ GtkWidget *gtkCombo = d->gtkWidget("GtkComboBox");
+ QRect arrowButtonRect = proxy()->subControlRect(CC_ComboBox, combo, SC_ComboBoxArrow, widget);
+ newSize = size + QSize(12 + arrowButtonRect.width() + 2*gtkCombo->style->xthickness, 4 + 2*gtkCombo->style->ythickness);
+
+ if (!(widget && qobject_cast<QToolBar *>(widget->parentWidget())))
+ newSize += QSize(0, 2);
+ }
+ break;
+
+ case CT_GroupBox:
+ newSize += QSize(4, groupBoxBottomMargin + groupBoxTopMargin + groupBoxTitleMargin); // Add some space below the groupbox
+ break;
+
+ case CT_TabBarTab:
+ if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(option)) {
+ if (!tab->icon.isNull())
+ newSize += QSize(6, 0);
+ }
+ newSize += QSize(1, 1);
+ break;
+
+ default:
+ break;
+ }
+
+ return newSize;
+}
+
+
+/*! \reimp */
+QPixmap QGtkStyle::standardPixmap(StandardPixmap sp, const QStyleOption *option,
+ const QWidget *widget) const
+{
+ Q_D(const QGtkStyle);
+
+ if (!d->isThemeAvailable())
+ return QCleanlooksStyle::standardPixmap(sp, option, widget);
+
+ QPixmap pixmap;
+ switch (sp) {
+
+ case SP_TitleBarNormalButton: {
+ QImage restoreButton((const char **)dock_widget_restore_xpm);
+ QColor alphaCorner = restoreButton.color(2);
+ alphaCorner.setAlpha(80);
+ restoreButton.setColor(2, alphaCorner.rgba());
+ alphaCorner.setAlpha(180);
+ restoreButton.setColor(4, alphaCorner.rgba());
+ return QPixmap::fromImage(restoreButton);
+ }
+ break;
+
+ case SP_TitleBarCloseButton: // Fall through
+ case SP_DockWidgetCloseButton: {
+
+ QImage closeButton((const char **)dock_widget_close_xpm);
+ QColor alphaCorner = closeButton.color(2);
+ alphaCorner.setAlpha(80);
+ closeButton.setColor(2, alphaCorner.rgba());
+ return QPixmap::fromImage(closeButton);
+ }
+ break;
+
+ case SP_DialogDiscardButton:
+ return QGtkPainter::getIcon(GTK_STOCK_DELETE);
+ case SP_DialogOkButton:
+ return QGtkPainter::getIcon(GTK_STOCK_OK);
+ case SP_DialogCancelButton:
+ return QGtkPainter::getIcon(GTK_STOCK_CANCEL);
+ case SP_DialogYesButton:
+ return QGtkPainter::getIcon(GTK_STOCK_YES);
+ case SP_DialogNoButton:
+ return QGtkPainter::getIcon(GTK_STOCK_NO);
+ case SP_DialogOpenButton:
+ return QGtkPainter::getIcon(GTK_STOCK_OPEN);
+ case SP_DialogCloseButton:
+ return QGtkPainter::getIcon(GTK_STOCK_CLOSE);
+ case SP_DialogApplyButton:
+ return QGtkPainter::getIcon(GTK_STOCK_APPLY);
+ case SP_DialogSaveButton:
+ return QGtkPainter::getIcon(GTK_STOCK_SAVE);
+ case SP_MessageBoxWarning:
+ return QGtkPainter::getIcon(GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_DIALOG);
+ case SP_MessageBoxQuestion:
+ return QGtkPainter::getIcon(GTK_STOCK_DIALOG_QUESTION, GTK_ICON_SIZE_DIALOG);
+ case SP_MessageBoxInformation:
+ return QGtkPainter::getIcon(GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_DIALOG);
+ case SP_MessageBoxCritical:
+ return QGtkPainter::getIcon(GTK_STOCK_DIALOG_ERROR, GTK_ICON_SIZE_DIALOG);
+ default:
+ return QCleanlooksStyle::standardPixmap(sp, option, widget);
+ }
+ return pixmap;
+}
+
+/*!
+ \internal
+*/
+QIcon QGtkStyle::standardIconImplementation(StandardPixmap standardIcon,
+ const QStyleOption *option,
+ const QWidget *widget) const
+{
+ Q_D(const QGtkStyle);
+
+ if (!d->isThemeAvailable())
+ return QCleanlooksStyle::standardIconImplementation(standardIcon, option, widget);
+ switch (standardIcon) {
+ case SP_DialogDiscardButton:
+ return QGtkPainter::getIcon(GTK_STOCK_DELETE);
+ case SP_DialogOkButton:
+ return QGtkPainter::getIcon(GTK_STOCK_OK);
+ case SP_DialogCancelButton:
+ return QGtkPainter::getIcon(GTK_STOCK_CANCEL);
+ case SP_DialogYesButton:
+ return QGtkPainter::getIcon(GTK_STOCK_YES);
+ case SP_DialogNoButton:
+ return QGtkPainter::getIcon(GTK_STOCK_NO);
+ case SP_DialogOpenButton:
+ return QGtkPainter::getIcon(GTK_STOCK_OPEN);
+ case SP_DialogCloseButton:
+ return QGtkPainter::getIcon(GTK_STOCK_CLOSE);
+ case SP_DialogApplyButton:
+ return QGtkPainter::getIcon(GTK_STOCK_APPLY);
+ case SP_DialogSaveButton:
+ return QGtkPainter::getIcon(GTK_STOCK_SAVE);
+ case SP_MessageBoxWarning:
+ return QGtkPainter::getIcon(GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_DIALOG);
+ case SP_MessageBoxQuestion:
+ return QGtkPainter::getIcon(GTK_STOCK_DIALOG_QUESTION, GTK_ICON_SIZE_DIALOG);
+ case SP_MessageBoxInformation:
+ return QGtkPainter::getIcon(GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_DIALOG);
+ case SP_MessageBoxCritical:
+ return QGtkPainter::getIcon(GTK_STOCK_DIALOG_ERROR, GTK_ICON_SIZE_DIALOG);
+ default:
+ return QCleanlooksStyle::standardIconImplementation(standardIcon, option, widget);
+ }
+}
+
+
+/*! \reimp */
+QRect QGtkStyle::subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const
+{
+ Q_D(const QGtkStyle);
+
+ QRect r = QCleanlooksStyle::subElementRect(element, option, widget);
+ if (!d->isThemeAvailable())
+ return r;
+
+ switch (element) {
+ case SE_ProgressBarLabel:
+ case SE_ProgressBarContents:
+ case SE_ProgressBarGroove:
+ return option->rect;
+ case SE_PushButtonContents:
+ if (!d->gtk_check_version(2, 10, 0)) {
+ GtkWidget *gtkButton = d->gtkWidget("GtkButton");
+ GtkBorder *border = 0;
+ d->gtk_widget_style_get(gtkButton, "inner-border", &border, NULL);
+ if (border) {
+ r = option->rect.adjusted(border->left, border->top, -border->right, -border->bottom);
+ d->gtk_border_free(border);
+ } else {
+ r = option->rect.adjusted(1, 1, -1, -1);
+ }
+ r = visualRect(option->direction, option->rect, r);
+ }
+ break;
+ default:
+ break;
+ }
+
+ return r;
+}
+
+/*!
+ \reimp
+*/
+QRect QGtkStyle::itemPixmapRect(const QRect &r, int flags, const QPixmap &pixmap) const
+{
+ return QCleanlooksStyle::itemPixmapRect(r, flags, pixmap);
+}
+
+/*!
+ \reimp
+*/
+void QGtkStyle::drawItemPixmap(QPainter *painter, const QRect &rect,
+ int alignment, const QPixmap &pixmap) const
+{
+ QCleanlooksStyle::drawItemPixmap(painter, rect, alignment, pixmap);
+}
+
+/*!
+ \reimp
+*/
+QStyle::SubControl QGtkStyle::hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt,
+ const QPoint &pt, const QWidget *w) const
+{
+ return QCleanlooksStyle::hitTestComplexControl(cc, opt, pt, w);
+}
+
+/*!
+ \reimp
+*/
+QPixmap QGtkStyle::generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap,
+ const QStyleOption *opt) const
+{
+ return QCleanlooksStyle::generatedIconPixmap(iconMode, pixmap, opt);
+}
+
+/*!
+ \reimp
+*/
+void QGtkStyle::drawItemText(QPainter *painter, const QRect &rect, int alignment, const QPalette &pal,
+ bool enabled, const QString& text, QPalette::ColorRole textRole) const
+{
+ return QCleanlooksStyle::drawItemText(painter, rect, alignment, pal, enabled, text, textRole);
+}
+
+QT_END_NAMESPACE
+
+#endif //!defined(QT_NO_STYLE_QGTK)
diff --git a/src/widgets/styles/qgtkstyle.h b/src/widgets/styles/qgtkstyle.h
new file mode 100644
index 0000000000..1ca6e3cc85
--- /dev/null
+++ b/src/widgets/styles/qgtkstyle.h
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGTKSTYLE_H
+#define QGTKSTYLE_H
+
+#include <QtWidgets/QCleanlooksStyle>
+#include <QtGui/QPalette>
+#include <QtGui/QFont>
+#include <QtWidgets/QFileDialog>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#if !defined(QT_NO_STYLE_GTK)
+
+class QPainterPath;
+class QGtkStylePrivate;
+
+class Q_WIDGETS_EXPORT QGtkStyle : public QCleanlooksStyle
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QGtkStyle)
+
+public:
+ QGtkStyle();
+ QGtkStyle(QGtkStylePrivate &dd);
+
+ ~QGtkStyle();
+
+ QPalette standardPalette() const;
+
+ void drawPrimitive(PrimitiveElement element, const QStyleOption *option,
+ QPainter *painter, const QWidget *widget) const;
+ void drawControl(ControlElement control, const QStyleOption *option,
+ QPainter *painter, const QWidget *widget) const;
+ void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option,
+ QPainter *painter, const QWidget *widget) const;
+ void drawItemPixmap(QPainter *painter, const QRect &rect, int alignment,
+ const QPixmap &pixmap) const;
+ void drawItemText(QPainter *painter, const QRect &rect, int alignment, const QPalette &pal,
+ bool enabled, const QString& text, QPalette::ColorRole textRole) const;
+
+ int pixelMetric(PixelMetric metric, const QStyleOption *option = 0,
+ const QWidget *widget = 0) const;
+ int styleHint(StyleHint hint, const QStyleOption *option,
+ const QWidget *widget, QStyleHintReturn *returnData) const;
+
+ QStyle::SubControl hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt,
+ const QPoint &pt, const QWidget *w) const;
+
+ QRect subControlRect(ComplexControl control, const QStyleOptionComplex *option,
+ SubControl subControl, const QWidget *widget) const;
+ QRect subElementRect(SubElement sr, const QStyleOption *opt, const QWidget *w) const;
+ QRect itemPixmapRect(const QRect &r, int flags, const QPixmap &pixmap) const;
+
+
+ QSize sizeFromContents(ContentsType type, const QStyleOption *option,
+ const QSize &size, const QWidget *widget) const;
+ QPixmap standardPixmap(StandardPixmap sp, const QStyleOption *option,
+ const QWidget *widget) const;
+ QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap,
+ const QStyleOption *opt) const;
+
+ void polish(QWidget *widget);
+ void polish(QApplication *app);
+ void polish(QPalette &palette);
+
+ void unpolish(QWidget *widget);
+ void unpolish(QApplication *app);
+
+ static bool getGConfBool(const QString &key, bool fallback = 0);
+ static QString getGConfString(const QString &key, const QString &fallback = QString());
+
+
+protected Q_SLOTS:
+ QIcon standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *option,
+ const QWidget *widget = 0) const;
+};
+
+#endif //!defined(QT_NO_STYLE_QGTK)
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif //QGTKSTYLE_H
diff --git a/src/widgets/styles/qgtkstyle_p.cpp b/src/widgets/styles/qgtkstyle_p.cpp
new file mode 100644
index 0000000000..35f022bac4
--- /dev/null
+++ b/src/widgets/styles/qgtkstyle_p.cpp
@@ -0,0 +1,1146 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qgtkstyle_p.h"
+
+// This file is responsible for resolving all GTK functions we use
+// dynamically. This is done to avoid link-time dependancy on GTK
+// as well as crashes occurring due to usage of the GTK_QT engines
+//
+// Additionally we create a map of common GTK widgets that we can pass
+// to the GTK theme engine as many engines resort to querying the
+// actual widget pointers for details that are not covered by the
+// state flags
+
+#include <QtCore/qglobal.h>
+#if !defined(QT_NO_STYLE_GTK)
+
+#include <QtCore/QEvent>
+#include <QtCore/QFile>
+#include <QtCore/QStringList>
+#include <QtCore/QTextStream>
+#include <QtCore/QHash>
+#include <QtCore/QUrl>
+#include <QtCore/QLibrary>
+#include <QtCore/QDebug>
+
+#include <private/qapplication_p.h>
+#include <private/qiconloader_p.h>
+
+#include <QtWidgets/QMenu>
+#include <QtWidgets/QStyle>
+#include <QtWidgets/QApplication>
+#include <QtGui/QPixmapCache>
+#include <QtWidgets/QStatusBar>
+#include <QtWidgets/QMenuBar>
+#include <QtWidgets/QToolBar>
+#include <QtWidgets/QToolButton>
+#include <QtWidgets/QX11Info>
+
+#include <private/qt_x11_p.h>
+
+QT_BEGIN_NAMESPACE
+
+static bool displayDepth = -1;
+Q_GLOBAL_STATIC(QGtkStyleUpdateScheduler, styleScheduler)
+
+Ptr_gtk_container_forall QGtkStylePrivate::gtk_container_forall = 0;
+Ptr_gtk_init QGtkStylePrivate::gtk_init = 0;
+Ptr_gtk_style_attach QGtkStylePrivate::gtk_style_attach = 0;
+Ptr_gtk_window_new QGtkStylePrivate::gtk_window_new = 0;
+Ptr_gtk_widget_destroy QGtkStylePrivate::gtk_widget_destroy = 0;
+Ptr_gtk_widget_realize QGtkStylePrivate::gtk_widget_realize = 0;
+Ptr_gtk_widget_set_default_direction QGtkStylePrivate::gtk_widget_set_default_direction = 0;
+Ptr_gtk_widget_modify_color QGtkStylePrivate::gtk_widget_modify_fg = 0;
+Ptr_gtk_widget_modify_color QGtkStylePrivate::gtk_widget_modify_bg = 0;
+Ptr_gtk_arrow_new QGtkStylePrivate::gtk_arrow_new = 0;
+Ptr_gtk_menu_item_new_with_label QGtkStylePrivate::gtk_menu_item_new_with_label = 0;
+Ptr_gtk_check_menu_item_new_with_label QGtkStylePrivate::gtk_check_menu_item_new_with_label = 0;
+Ptr_gtk_menu_bar_new QGtkStylePrivate::gtk_menu_bar_new = 0;
+Ptr_gtk_menu_new QGtkStylePrivate::gtk_menu_new = 0;
+Ptr_gtk_button_new QGtkStylePrivate::gtk_button_new = 0;
+Ptr_gtk_tool_button_new QGtkStylePrivate::gtk_tool_button_new = 0;
+Ptr_gtk_hbutton_box_new QGtkStylePrivate::gtk_hbutton_box_new = 0;
+Ptr_gtk_check_button_new QGtkStylePrivate::gtk_check_button_new = 0;
+Ptr_gtk_radio_button_new QGtkStylePrivate::gtk_radio_button_new = 0;
+Ptr_gtk_spin_button_new QGtkStylePrivate::gtk_spin_button_new = 0;
+Ptr_gtk_frame_new QGtkStylePrivate::gtk_frame_new = 0;
+Ptr_gtk_expander_new QGtkStylePrivate::gtk_expander_new = 0;
+Ptr_gtk_statusbar_new QGtkStylePrivate::gtk_statusbar_new = 0;
+Ptr_gtk_entry_new QGtkStylePrivate::gtk_entry_new = 0;
+Ptr_gtk_hscale_new QGtkStylePrivate::gtk_hscale_new = 0;
+Ptr_gtk_vscale_new QGtkStylePrivate::gtk_vscale_new = 0;
+Ptr_gtk_hscrollbar_new QGtkStylePrivate::gtk_hscrollbar_new = 0;
+Ptr_gtk_vscrollbar_new QGtkStylePrivate::gtk_vscrollbar_new = 0;
+Ptr_gtk_scrolled_window_new QGtkStylePrivate::gtk_scrolled_window_new = 0;
+Ptr_gtk_notebook_new QGtkStylePrivate::gtk_notebook_new = 0;
+Ptr_gtk_toolbar_new QGtkStylePrivate::gtk_toolbar_new = 0;
+Ptr_gtk_toolbar_insert QGtkStylePrivate::gtk_toolbar_insert = 0;
+Ptr_gtk_separator_tool_item_new QGtkStylePrivate::gtk_separator_tool_item_new = 0;
+Ptr_gtk_tree_view_new QGtkStylePrivate::gtk_tree_view_new = 0;
+Ptr_gtk_combo_box_new QGtkStylePrivate::gtk_combo_box_new = 0;
+Ptr_gtk_combo_box_entry_new QGtkStylePrivate::gtk_combo_box_entry_new = 0;
+Ptr_gtk_progress_bar_new QGtkStylePrivate::gtk_progress_bar_new = 0;
+Ptr_gtk_container_add QGtkStylePrivate::gtk_container_add = 0;
+Ptr_gtk_menu_shell_append QGtkStylePrivate::gtk_menu_shell_append = 0;
+Ptr_gtk_progress_configure QGtkStylePrivate::gtk_progress_configure = 0;
+Ptr_gtk_range_get_adjustment QGtkStylePrivate::gtk_range_get_adjustment = 0;
+Ptr_gtk_range_set_adjustment QGtkStylePrivate::gtk_range_set_adjustment = 0;
+Ptr_gtk_range_set_inverted QGtkStylePrivate::gtk_range_set_inverted = 0;
+Ptr_gtk_icon_factory_lookup_default QGtkStylePrivate::gtk_icon_factory_lookup_default = 0;
+Ptr_gtk_icon_theme_get_default QGtkStylePrivate::gtk_icon_theme_get_default = 0;
+Ptr_gtk_widget_style_get QGtkStylePrivate::gtk_widget_style_get = 0;
+Ptr_gtk_icon_set_render_icon QGtkStylePrivate::gtk_icon_set_render_icon = 0;
+Ptr_gtk_fixed_new QGtkStylePrivate::gtk_fixed_new = 0;
+Ptr_gtk_tree_view_column_new QGtkStylePrivate::gtk_tree_view_column_new = 0;
+Ptr_gtk_tree_view_get_column QGtkStylePrivate::gtk_tree_view_get_column = 0;
+Ptr_gtk_tree_view_append_column QGtkStylePrivate::gtk_tree_view_append_column = 0;
+Ptr_gtk_paint_check QGtkStylePrivate::gtk_paint_check = 0;
+Ptr_gtk_paint_box QGtkStylePrivate::gtk_paint_box = 0;
+Ptr_gtk_paint_box_gap QGtkStylePrivate::gtk_paint_box_gap = 0;
+Ptr_gtk_paint_flat_box QGtkStylePrivate::gtk_paint_flat_box = 0;
+Ptr_gtk_paint_option QGtkStylePrivate::gtk_paint_option = 0;
+Ptr_gtk_paint_extension QGtkStylePrivate::gtk_paint_extension = 0;
+Ptr_gtk_paint_slider QGtkStylePrivate::gtk_paint_slider = 0;
+Ptr_gtk_paint_shadow QGtkStylePrivate::gtk_paint_shadow = 0;
+Ptr_gtk_paint_resize_grip QGtkStylePrivate::gtk_paint_resize_grip = 0;
+Ptr_gtk_paint_focus QGtkStylePrivate::gtk_paint_focus = 0;
+Ptr_gtk_paint_arrow QGtkStylePrivate::gtk_paint_arrow = 0;
+Ptr_gtk_paint_handle QGtkStylePrivate::gtk_paint_handle = 0;
+Ptr_gtk_paint_expander QGtkStylePrivate::gtk_paint_expander = 0;
+Ptr_gtk_adjustment_configure QGtkStylePrivate::gtk_adjustment_configure = 0;
+Ptr_gtk_adjustment_new QGtkStylePrivate::gtk_adjustment_new = 0;
+Ptr_gtk_paint_hline QGtkStylePrivate::gtk_paint_hline = 0;
+Ptr_gtk_paint_vline QGtkStylePrivate::gtk_paint_vline = 0;
+Ptr_gtk_menu_item_set_submenu QGtkStylePrivate::gtk_menu_item_set_submenu = 0;
+Ptr_gtk_settings_get_default QGtkStylePrivate::gtk_settings_get_default = 0;
+Ptr_gtk_separator_menu_item_new QGtkStylePrivate::gtk_separator_menu_item_new = 0;
+Ptr_gtk_widget_size_allocate QGtkStylePrivate::gtk_widget_size_allocate = 0;
+Ptr_gtk_widget_size_request QGtkStylePrivate::gtk_widget_size_request = 0;
+Ptr_gtk_widget_set_direction QGtkStylePrivate::gtk_widget_set_direction = 0;
+Ptr_gtk_widget_path QGtkStylePrivate::gtk_widget_path = 0;
+Ptr_gtk_container_get_type QGtkStylePrivate::gtk_container_get_type = 0;
+Ptr_gtk_window_get_type QGtkStylePrivate::gtk_window_get_type = 0;
+Ptr_gtk_widget_get_type QGtkStylePrivate::gtk_widget_get_type = 0;
+Ptr_gtk_rc_get_style_by_paths QGtkStylePrivate::gtk_rc_get_style_by_paths = 0;
+Ptr_gtk_check_version QGtkStylePrivate::gtk_check_version = 0;
+Ptr_gtk_border_free QGtkStylePrivate::gtk_border_free = 0;
+Ptr_pango_font_description_get_size QGtkStylePrivate::pango_font_description_get_size = 0;
+Ptr_pango_font_description_get_weight QGtkStylePrivate::pango_font_description_get_weight = 0;
+Ptr_pango_font_description_get_family QGtkStylePrivate::pango_font_description_get_family = 0;
+Ptr_pango_font_description_get_style QGtkStylePrivate::pango_font_description_get_style = 0;
+
+Ptr_gtk_file_filter_new QGtkStylePrivate::gtk_file_filter_new = 0;
+Ptr_gtk_file_filter_set_name QGtkStylePrivate::gtk_file_filter_set_name = 0;
+Ptr_gtk_file_filter_add_pattern QGtkStylePrivate::gtk_file_filter_add_pattern = 0;
+Ptr_gtk_file_chooser_add_filter QGtkStylePrivate::gtk_file_chooser_add_filter = 0;
+Ptr_gtk_file_chooser_set_filter QGtkStylePrivate::gtk_file_chooser_set_filter = 0;
+Ptr_gtk_file_chooser_get_filter QGtkStylePrivate::gtk_file_chooser_get_filter = 0;
+Ptr_gtk_file_chooser_dialog_new QGtkStylePrivate::gtk_file_chooser_dialog_new = 0;
+Ptr_gtk_file_chooser_set_current_folder QGtkStylePrivate::gtk_file_chooser_set_current_folder = 0;
+Ptr_gtk_file_chooser_get_filename QGtkStylePrivate::gtk_file_chooser_get_filename = 0;
+Ptr_gtk_file_chooser_get_filenames QGtkStylePrivate::gtk_file_chooser_get_filenames = 0;
+Ptr_gtk_file_chooser_set_current_name QGtkStylePrivate::gtk_file_chooser_set_current_name = 0;
+Ptr_gtk_dialog_run QGtkStylePrivate::gtk_dialog_run = 0;
+Ptr_gtk_file_chooser_set_filename QGtkStylePrivate::gtk_file_chooser_set_filename = 0;
+
+Ptr_gdk_pixbuf_get_pixels QGtkStylePrivate::gdk_pixbuf_get_pixels = 0;
+Ptr_gdk_pixbuf_get_width QGtkStylePrivate::gdk_pixbuf_get_width = 0;
+Ptr_gdk_pixbuf_get_height QGtkStylePrivate::gdk_pixbuf_get_height = 0;
+Ptr_gdk_pixmap_new QGtkStylePrivate::gdk_pixmap_new = 0;
+Ptr_gdk_pixbuf_new QGtkStylePrivate::gdk_pixbuf_new = 0;
+Ptr_gdk_pixbuf_get_from_drawable QGtkStylePrivate::gdk_pixbuf_get_from_drawable = 0;
+Ptr_gdk_draw_rectangle QGtkStylePrivate::gdk_draw_rectangle = 0;
+Ptr_gdk_pixbuf_unref QGtkStylePrivate::gdk_pixbuf_unref = 0;
+Ptr_gdk_drawable_unref QGtkStylePrivate::gdk_drawable_unref = 0;
+Ptr_gdk_drawable_get_depth QGtkStylePrivate::gdk_drawable_get_depth = 0;
+Ptr_gdk_color_free QGtkStylePrivate::gdk_color_free = 0;
+Ptr_gdk_x11_window_set_user_time QGtkStylePrivate::gdk_x11_window_set_user_time = 0;
+Ptr_gdk_x11_drawable_get_xid QGtkStylePrivate::gdk_x11_drawable_get_xid = 0;
+Ptr_gdk_x11_drawable_get_xdisplay QGtkStylePrivate::gdk_x11_drawable_get_xdisplay = 0;
+
+Ptr_gconf_client_get_default QGtkStylePrivate::gconf_client_get_default = 0;
+Ptr_gconf_client_get_string QGtkStylePrivate::gconf_client_get_string = 0;
+Ptr_gconf_client_get_bool QGtkStylePrivate::gconf_client_get_bool = 0;
+
+Ptr_gnome_icon_lookup_sync QGtkStylePrivate::gnome_icon_lookup_sync = 0;
+Ptr_gnome_vfs_init QGtkStylePrivate::gnome_vfs_init = 0;
+
+typedef int (*x11ErrorHandler)(Display*, XErrorEvent*);
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QGtkStylePrivate*);
+
+QT_BEGIN_NAMESPACE
+
+static void gtkStyleSetCallback(GtkWidget*)
+{
+ qRegisterMetaType<QGtkStylePrivate *>();
+
+ // 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);
+}
+
+static void update_toolbar_style(GtkWidget *gtkToolBar, GParamSpec *, gpointer)
+{
+ GtkToolbarStyle toolbar_style = GTK_TOOLBAR_ICONS;
+ g_object_get(gtkToolBar, "toolbar-style", &toolbar_style, NULL);
+ QWidgetList widgets = QApplication::allWidgets();
+ for (int i = 0; i < widgets.size(); ++i) {
+ QWidget *widget = widgets.at(i);
+ if (qobject_cast<QToolButton*>(widget)) {
+ QEvent event(QEvent::StyleChange);
+ QApplication::sendEvent(widget, &event);
+ }
+ }
+}
+
+static QHashableLatin1Literal classPath(GtkWidget *widget)
+{
+ char *class_path;
+ QGtkStylePrivate::gtk_widget_path (widget, NULL, &class_path, NULL);
+
+ char *copy = class_path;
+ if (strncmp(copy, "GtkWindow.", 10) == 0)
+ copy += 10;
+ if (strncmp(copy, "GtkFixed.", 9) == 0)
+ copy += 9;
+
+ copy = strdup(copy);
+
+ g_free(class_path);
+
+ return QHashableLatin1Literal::fromData(copy);
+}
+
+
+
+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
+ if (!qt_app_palettes_hash() || qt_app_palettes_hash()->isEmpty()) {
+ stylePrivate->applyCustomPaletteHash();
+ }
+ }
+ return QObject::eventFilter(obj, e);
+}
+
+QList<QGtkStylePrivate *> QGtkStylePrivate::instances;
+QGtkStylePrivate::WidgetMap *QGtkStylePrivate::widgetMap = 0;
+
+QGtkStylePrivate::QGtkStylePrivate()
+ : QCleanlooksStylePrivate()
+ , filter(this)
+{
+ instances.append(this);
+}
+
+QGtkStylePrivate::~QGtkStylePrivate()
+{
+ instances.removeOne(this);
+}
+
+void QGtkStylePrivate::init()
+{
+ resolveGtk();
+ initGtkWidgets();
+}
+
+GtkWidget* QGtkStylePrivate::gtkWidget(const QHashableLatin1Literal &path)
+{
+ GtkWidget *widget = gtkWidgetMap()->value(path);
+ if (!widget) {
+ // Theme might have rearranged widget internals
+ widget = gtkWidgetMap()->value(path);
+ }
+ return widget;
+}
+
+GtkStyle* QGtkStylePrivate::gtkStyle(const QHashableLatin1Literal &path)
+{
+ if (GtkWidget *w = gtkWidgetMap()->value(path))
+ return w->style;
+ return 0;
+}
+
+/*! \internal
+ * Get references to gtk functions after we dynamically load the library.
+ */
+void QGtkStylePrivate::resolveGtk() const
+{
+ // enforce the "0" suffix, so we'll open libgtk-x11-2.0.so.0
+ QLibrary libgtk(QLS("gtk-x11-2.0"), 0, 0);
+
+ gtk_init = (Ptr_gtk_init)libgtk.resolve("gtk_init");
+ gtk_window_new = (Ptr_gtk_window_new)libgtk.resolve("gtk_window_new");
+ gtk_style_attach = (Ptr_gtk_style_attach)libgtk.resolve("gtk_style_attach");
+ gtk_widget_destroy = (Ptr_gtk_widget_destroy)libgtk.resolve("gtk_widget_destroy");
+ gtk_widget_realize = (Ptr_gtk_widget_realize)libgtk.resolve("gtk_widget_realize");
+
+ gtk_file_chooser_set_current_folder = (Ptr_gtk_file_chooser_set_current_folder)libgtk.resolve("gtk_file_chooser_set_current_folder");
+ gtk_file_filter_new = (Ptr_gtk_file_filter_new)libgtk.resolve("gtk_file_filter_new");
+ gtk_file_filter_set_name = (Ptr_gtk_file_filter_set_name)libgtk.resolve("gtk_file_filter_set_name");
+ gtk_file_filter_add_pattern = (Ptr_gtk_file_filter_add_pattern)libgtk.resolve("gtk_file_filter_add_pattern");
+ gtk_file_chooser_add_filter = (Ptr_gtk_file_chooser_add_filter)libgtk.resolve("gtk_file_chooser_add_filter");
+ gtk_file_chooser_set_filter = (Ptr_gtk_file_chooser_set_filter)libgtk.resolve("gtk_file_chooser_set_filter");
+ gtk_file_chooser_get_filter = (Ptr_gtk_file_chooser_get_filter)libgtk.resolve("gtk_file_chooser_get_filter");
+ gtk_file_chooser_dialog_new = (Ptr_gtk_file_chooser_dialog_new)libgtk.resolve("gtk_file_chooser_dialog_new");
+ gtk_file_chooser_set_current_folder = (Ptr_gtk_file_chooser_set_current_folder)libgtk.resolve("gtk_file_chooser_set_current_folder");
+ gtk_file_chooser_get_filename = (Ptr_gtk_file_chooser_get_filename)libgtk.resolve("gtk_file_chooser_get_filename");
+ gtk_file_chooser_get_filenames = (Ptr_gtk_file_chooser_get_filenames)libgtk.resolve("gtk_file_chooser_get_filenames");
+ gtk_file_chooser_set_current_name = (Ptr_gtk_file_chooser_set_current_name)libgtk.resolve("gtk_file_chooser_set_current_name");
+ gtk_dialog_run = (Ptr_gtk_dialog_run)libgtk.resolve("gtk_dialog_run");
+ gtk_file_chooser_set_filename = (Ptr_gtk_file_chooser_set_filename)libgtk.resolve("gtk_file_chooser_set_filename");
+
+ gdk_pixbuf_get_pixels = (Ptr_gdk_pixbuf_get_pixels)libgtk.resolve("gdk_pixbuf_get_pixels");
+ gdk_pixbuf_get_width = (Ptr_gdk_pixbuf_get_width)libgtk.resolve("gdk_pixbuf_get_width");
+ gdk_pixbuf_get_height = (Ptr_gdk_pixbuf_get_height)libgtk.resolve("gdk_pixbuf_get_height");
+ gdk_pixmap_new = (Ptr_gdk_pixmap_new)libgtk.resolve("gdk_pixmap_new");
+ gdk_pixbuf_new = (Ptr_gdk_pixbuf_new)libgtk.resolve("gdk_pixbuf_new");
+ gdk_pixbuf_get_from_drawable = (Ptr_gdk_pixbuf_get_from_drawable)libgtk.resolve("gdk_pixbuf_get_from_drawable");
+ gdk_draw_rectangle = (Ptr_gdk_draw_rectangle)libgtk.resolve("gdk_draw_rectangle");
+ gdk_pixbuf_unref = (Ptr_gdk_pixbuf_unref)libgtk.resolve("gdk_pixbuf_unref");
+ gdk_drawable_unref = (Ptr_gdk_drawable_unref)libgtk.resolve("gdk_drawable_unref");
+ gdk_drawable_get_depth = (Ptr_gdk_drawable_get_depth)libgtk.resolve("gdk_drawable_get_depth");
+ gdk_color_free = (Ptr_gdk_color_free)libgtk.resolve("gdk_color_free");
+ gdk_x11_window_set_user_time = (Ptr_gdk_x11_window_set_user_time)libgtk.resolve("gdk_x11_window_set_user_time");
+ gdk_x11_drawable_get_xid = (Ptr_gdk_x11_drawable_get_xid)libgtk.resolve("gdk_x11_drawable_get_xid");
+ gdk_x11_drawable_get_xdisplay = (Ptr_gdk_x11_drawable_get_xdisplay)libgtk.resolve("gdk_x11_drawable_get_xdisplay");
+
+ gtk_widget_set_default_direction = (Ptr_gtk_widget_set_default_direction)libgtk.resolve("gtk_widget_set_default_direction");
+ gtk_widget_modify_fg = (Ptr_gtk_widget_modify_color)libgtk.resolve("gtk_widget_modify_fg");
+ gtk_widget_modify_bg = (Ptr_gtk_widget_modify_color)libgtk.resolve("gtk_widget_modify_bg");
+ gtk_arrow_new = (Ptr_gtk_arrow_new)libgtk.resolve("gtk_arrow_new");
+ gtk_menu_item_new_with_label = (Ptr_gtk_menu_item_new_with_label)libgtk.resolve("gtk_menu_item_new_with_label");
+ gtk_check_menu_item_new_with_label = (Ptr_gtk_check_menu_item_new_with_label)libgtk.resolve("gtk_check_menu_item_new_with_label");
+ gtk_menu_bar_new = (Ptr_gtk_menu_bar_new)libgtk.resolve("gtk_menu_bar_new");
+ gtk_menu_new = (Ptr_gtk_menu_new)libgtk.resolve("gtk_menu_new");
+ gtk_toolbar_new = (Ptr_gtk_toolbar_new)libgtk.resolve("gtk_toolbar_new");
+ gtk_separator_tool_item_new = (Ptr_gtk_separator_tool_item_new)libgtk.resolve("gtk_separator_tool_item_new");
+ gtk_toolbar_insert = (Ptr_gtk_toolbar_insert)libgtk.resolve("gtk_toolbar_insert");
+ gtk_button_new = (Ptr_gtk_button_new)libgtk.resolve("gtk_button_new");
+ gtk_tool_button_new = (Ptr_gtk_tool_button_new)libgtk.resolve("gtk_tool_button_new");
+ gtk_hbutton_box_new = (Ptr_gtk_hbutton_box_new)libgtk.resolve("gtk_hbutton_box_new");
+ gtk_check_button_new = (Ptr_gtk_check_button_new)libgtk.resolve("gtk_check_button_new");
+ gtk_radio_button_new = (Ptr_gtk_radio_button_new)libgtk.resolve("gtk_radio_button_new");
+ gtk_notebook_new = (Ptr_gtk_notebook_new)libgtk.resolve("gtk_notebook_new");
+ gtk_progress_bar_new = (Ptr_gtk_progress_bar_new)libgtk.resolve("gtk_progress_bar_new");
+ gtk_spin_button_new = (Ptr_gtk_spin_button_new)libgtk.resolve("gtk_spin_button_new");
+ gtk_hscale_new = (Ptr_gtk_hscale_new)libgtk.resolve("gtk_hscale_new");
+ gtk_vscale_new = (Ptr_gtk_vscale_new)libgtk.resolve("gtk_vscale_new");
+ gtk_hscrollbar_new = (Ptr_gtk_hscrollbar_new)libgtk.resolve("gtk_hscrollbar_new");
+ gtk_vscrollbar_new = (Ptr_gtk_vscrollbar_new)libgtk.resolve("gtk_vscrollbar_new");
+ gtk_scrolled_window_new = (Ptr_gtk_scrolled_window_new)libgtk.resolve("gtk_scrolled_window_new");
+ gtk_menu_shell_append = (Ptr_gtk_menu_shell_append)libgtk.resolve("gtk_menu_shell_append");
+ gtk_entry_new = (Ptr_gtk_entry_new)libgtk.resolve("gtk_entry_new");
+ gtk_tree_view_new = (Ptr_gtk_tree_view_new)libgtk.resolve("gtk_tree_view_new");
+ gtk_combo_box_new = (Ptr_gtk_combo_box_new)libgtk.resolve("gtk_combo_box_new");
+ gtk_progress_configure = (Ptr_gtk_progress_configure)libgtk.resolve("gtk_progress_configure");
+ gtk_range_get_adjustment = (Ptr_gtk_range_get_adjustment)libgtk.resolve("gtk_range_get_adjustment");
+ gtk_range_set_adjustment = (Ptr_gtk_range_set_adjustment)libgtk.resolve("gtk_range_set_adjustment");
+ gtk_range_set_inverted = (Ptr_gtk_range_set_inverted)libgtk.resolve("gtk_range_set_inverted");
+ gtk_container_add = (Ptr_gtk_container_add)libgtk.resolve("gtk_container_add");
+ gtk_icon_factory_lookup_default = (Ptr_gtk_icon_factory_lookup_default)libgtk.resolve("gtk_icon_factory_lookup_default");
+ gtk_icon_theme_get_default = (Ptr_gtk_icon_theme_get_default)libgtk.resolve("gtk_icon_theme_get_default");
+ gtk_widget_style_get = (Ptr_gtk_widget_style_get)libgtk.resolve("gtk_widget_style_get");
+ gtk_icon_set_render_icon = (Ptr_gtk_icon_set_render_icon)libgtk.resolve("gtk_icon_set_render_icon");
+ gtk_fixed_new = (Ptr_gtk_fixed_new)libgtk.resolve("gtk_fixed_new");
+ gtk_tree_view_column_new = (Ptr_gtk_tree_view_column_new)libgtk.resolve("gtk_tree_view_column_new");
+ gtk_tree_view_append_column= (Ptr_gtk_tree_view_append_column )libgtk.resolve("gtk_tree_view_append_column");
+ gtk_tree_view_get_column = (Ptr_gtk_tree_view_get_column )libgtk.resolve("gtk_tree_view_get_column");
+ gtk_paint_check = (Ptr_gtk_paint_check)libgtk.resolve("gtk_paint_check");
+ gtk_paint_box = (Ptr_gtk_paint_box)libgtk.resolve("gtk_paint_box");
+ gtk_paint_flat_box = (Ptr_gtk_paint_flat_box)libgtk.resolve("gtk_paint_flat_box");
+ gtk_paint_check = (Ptr_gtk_paint_check)libgtk.resolve("gtk_paint_check");
+ gtk_paint_box = (Ptr_gtk_paint_box)libgtk.resolve("gtk_paint_box");
+ gtk_paint_resize_grip = (Ptr_gtk_paint_resize_grip)libgtk.resolve("gtk_paint_resize_grip");
+ gtk_paint_focus = (Ptr_gtk_paint_focus)libgtk.resolve("gtk_paint_focus");
+ gtk_paint_shadow = (Ptr_gtk_paint_shadow)libgtk.resolve("gtk_paint_shadow");
+ gtk_paint_slider = (Ptr_gtk_paint_slider)libgtk.resolve("gtk_paint_slider");
+ gtk_paint_expander = (Ptr_gtk_paint_expander)libgtk.resolve("gtk_paint_expander");
+ gtk_paint_handle = (Ptr_gtk_paint_handle)libgtk.resolve("gtk_paint_handle");
+ gtk_paint_option = (Ptr_gtk_paint_option)libgtk.resolve("gtk_paint_option");
+ gtk_paint_arrow = (Ptr_gtk_paint_arrow)libgtk.resolve("gtk_paint_arrow");
+ gtk_paint_box_gap = (Ptr_gtk_paint_box_gap)libgtk.resolve("gtk_paint_box_gap");
+ gtk_paint_extension = (Ptr_gtk_paint_extension)libgtk.resolve("gtk_paint_extension");
+ gtk_paint_hline = (Ptr_gtk_paint_hline)libgtk.resolve("gtk_paint_hline");
+ gtk_paint_vline = (Ptr_gtk_paint_vline)libgtk.resolve("gtk_paint_vline");
+ gtk_adjustment_configure = (Ptr_gtk_adjustment_configure)libgtk.resolve("gtk_adjustment_configure");
+ gtk_adjustment_new = (Ptr_gtk_adjustment_new)libgtk.resolve("gtk_adjustment_new");
+ gtk_menu_item_set_submenu = (Ptr_gtk_menu_item_set_submenu)libgtk.resolve("gtk_menu_item_set_submenu");
+ gtk_settings_get_default = (Ptr_gtk_settings_get_default)libgtk.resolve("gtk_settings_get_default");
+ gtk_separator_menu_item_new = (Ptr_gtk_separator_menu_item_new)libgtk.resolve("gtk_separator_menu_item_new");
+ gtk_frame_new = (Ptr_gtk_frame_new)libgtk.resolve("gtk_frame_new");
+ gtk_expander_new = (Ptr_gtk_expander_new)libgtk.resolve("gtk_expander_new");
+ gtk_statusbar_new = (Ptr_gtk_statusbar_new)libgtk.resolve("gtk_statusbar_new");
+ gtk_combo_box_entry_new = (Ptr_gtk_combo_box_entry_new)libgtk.resolve("gtk_combo_box_entry_new");
+ gtk_container_forall = (Ptr_gtk_container_forall)libgtk.resolve("gtk_container_forall");
+ gtk_widget_size_allocate =(Ptr_gtk_widget_size_allocate)libgtk.resolve("gtk_widget_size_allocate");
+ gtk_widget_size_request =(Ptr_gtk_widget_size_request)libgtk.resolve("gtk_widget_size_request");
+ gtk_widget_set_direction =(Ptr_gtk_widget_set_direction)libgtk.resolve("gtk_widget_set_direction");
+ gtk_widget_path =(Ptr_gtk_widget_path)libgtk.resolve("gtk_widget_path");
+ gtk_container_get_type =(Ptr_gtk_container_get_type)libgtk.resolve("gtk_container_get_type");
+ gtk_window_get_type =(Ptr_gtk_window_get_type)libgtk.resolve("gtk_window_get_type");
+ gtk_widget_get_type =(Ptr_gtk_widget_get_type)libgtk.resolve("gtk_widget_get_type");
+
+ gtk_rc_get_style_by_paths =(Ptr_gtk_rc_get_style_by_paths)libgtk.resolve("gtk_rc_get_style_by_paths");
+ gtk_check_version =(Ptr_gtk_check_version)libgtk.resolve("gtk_check_version");
+ gtk_border_free =(Ptr_gtk_border_free)libgtk.resolve("gtk_border_free");
+ pango_font_description_get_size = (Ptr_pango_font_description_get_size)libgtk.resolve("pango_font_description_get_size");
+ pango_font_description_get_weight = (Ptr_pango_font_description_get_weight)libgtk.resolve("pango_font_description_get_weight");
+ pango_font_description_get_family = (Ptr_pango_font_description_get_family)libgtk.resolve("pango_font_description_get_family");
+ pango_font_description_get_style = (Ptr_pango_font_description_get_style)libgtk.resolve("pango_font_description_get_style");
+
+ gnome_icon_lookup_sync = (Ptr_gnome_icon_lookup_sync)QLibrary::resolve(QLS("gnomeui-2"), 0, "gnome_icon_lookup_sync");
+ gnome_vfs_init= (Ptr_gnome_vfs_init)QLibrary::resolve(QLS("gnomevfs-2"), 0, "gnome_vfs_init");
+}
+
+/* \internal
+ * Initializes a number of gtk menu widgets.
+ * The widgets are cached.
+ */
+void QGtkStylePrivate::initGtkMenu() const
+{
+ // Create menubar
+ GtkWidget *gtkMenuBar = QGtkStylePrivate::gtk_menu_bar_new();
+ setupGtkWidget(gtkMenuBar);
+
+ GtkWidget *gtkMenuBarItem = QGtkStylePrivate::gtk_menu_item_new_with_label("X");
+ gtk_menu_shell_append((GtkMenuShell*)(gtkMenuBar), gtkMenuBarItem);
+ gtk_widget_realize(gtkMenuBarItem);
+
+ // Create menu
+ GtkWidget *gtkMenu = QGtkStylePrivate::gtk_menu_new();
+ gtk_menu_item_set_submenu((GtkMenuItem*)(gtkMenuBarItem), gtkMenu);
+ gtk_widget_realize(gtkMenu);
+
+ GtkWidget *gtkMenuItem = QGtkStylePrivate::gtk_menu_item_new_with_label("X");
+ gtk_menu_shell_append((GtkMenuShell*)gtkMenu, gtkMenuItem);
+ gtk_widget_realize(gtkMenuItem);
+
+ GtkWidget *gtkCheckMenuItem = QGtkStylePrivate::gtk_check_menu_item_new_with_label("X");
+ gtk_menu_shell_append((GtkMenuShell*)gtkMenu, gtkCheckMenuItem);
+ gtk_widget_realize(gtkCheckMenuItem);
+
+ GtkWidget *gtkMenuSeparator = QGtkStylePrivate::gtk_separator_menu_item_new();
+ gtk_menu_shell_append((GtkMenuShell*)gtkMenu, gtkMenuSeparator);
+
+ addAllSubWidgets(gtkMenuBar);
+ addAllSubWidgets(gtkMenu);
+}
+
+
+void QGtkStylePrivate::initGtkTreeview() const
+{
+ GtkWidget *gtkTreeView = gtk_tree_view_new();
+ gtk_tree_view_append_column((GtkTreeView*)gtkTreeView, gtk_tree_view_column_new());
+ gtk_tree_view_append_column((GtkTreeView*)gtkTreeView, gtk_tree_view_column_new());
+ gtk_tree_view_append_column((GtkTreeView*)gtkTreeView, gtk_tree_view_column_new());
+ addWidget(gtkTreeView);
+}
+
+
+/* \internal
+ * Initializes a number of gtk widgets that we can later on use to determine some of our styles.
+ * The widgets are cached.
+ */
+void QGtkStylePrivate::initGtkWidgets() const
+{
+ // From gtkmain.c
+ uid_t ruid = getuid ();
+ uid_t rgid = getgid ();
+ uid_t euid = geteuid ();
+ uid_t egid = getegid ();
+ if (ruid != euid || rgid != egid) {
+ qWarning("\nThis process is currently running setuid or setgid.\nGTK+ does not allow this "
+ "therefore Qt cannot use the GTK+ integration.\nTry launching your app using \'gksudo\', "
+ "\'kdesudo\' or a similar tool.\n\n"
+ "See http://www.gtk.org/setuid.html for more information.\n");
+ return;
+ }
+
+ static QString themeName;
+ if (!gtkWidgetMap()->contains("GtkWindow") && themeName.isEmpty()) {
+ themeName = getThemeName();
+
+ if (themeName.isEmpty()) {
+ qWarning("QGtkStyle was unable to detect the current GTK+ theme.");
+ return;
+ } else if (themeName == QLS("Qt") || themeName == QLS("Qt4")) {
+ // Due to namespace conflicts with Qt3 and obvious recursion with Qt4,
+ // we cannot support the GTK_Qt Gtk engine
+ qWarning("QGtkStyle cannot be used together with the GTK_Qt engine.");
+ return;
+ }
+ }
+
+ if (QGtkStylePrivate::gtk_init) {
+ // Gtk will set the Qt error handler so we have to reset it afterwards
+ x11ErrorHandler qt_x_errhandler = XSetErrorHandler(0);
+ QGtkStylePrivate::gtk_init (NULL, NULL);
+ XSetErrorHandler(qt_x_errhandler);
+
+ // make a window
+ GtkWidget* gtkWindow = QGtkStylePrivate::gtk_window_new(GTK_WINDOW_POPUP);
+ QGtkStylePrivate::gtk_widget_realize(gtkWindow);
+ if (displayDepth == -1)
+ displayDepth = QGtkStylePrivate::gdk_drawable_get_depth(gtkWindow->window);
+ QHashableLatin1Literal widgetPath = QHashableLatin1Literal::fromData(strdup("GtkWindow"));
+ removeWidgetFromMap(widgetPath);
+ gtkWidgetMap()->insert(widgetPath, gtkWindow);
+
+
+ // Make all other widgets. respect the text direction
+ if (qApp->layoutDirection() == Qt::RightToLeft)
+ QGtkStylePrivate::gtk_widget_set_default_direction(GTK_TEXT_DIR_RTL);
+
+ if (!gtkWidgetMap()->contains("GtkButton")) {
+ GtkWidget *gtkButton = QGtkStylePrivate::gtk_button_new();
+ addWidget(gtkButton);
+ g_signal_connect(gtkButton, "style-set", G_CALLBACK(gtkStyleSetCallback), 0);
+ addWidget(QGtkStylePrivate::gtk_tool_button_new(NULL, "Qt"));
+ addWidget(QGtkStylePrivate::gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_NONE));
+ addWidget(QGtkStylePrivate::gtk_hbutton_box_new());
+ addWidget(QGtkStylePrivate::gtk_check_button_new());
+ addWidget(QGtkStylePrivate::gtk_radio_button_new(NULL));
+ addWidget(QGtkStylePrivate::gtk_combo_box_new());
+ addWidget(QGtkStylePrivate::gtk_combo_box_entry_new());
+ addWidget(QGtkStylePrivate::gtk_entry_new());
+ addWidget(QGtkStylePrivate::gtk_frame_new(NULL));
+ addWidget(QGtkStylePrivate::gtk_expander_new(""));
+ addWidget(QGtkStylePrivate::gtk_statusbar_new());
+ addWidget(QGtkStylePrivate::gtk_hscale_new((GtkAdjustment*)(QGtkStylePrivate::gtk_adjustment_new(1, 0, 1, 0, 0, 0))));
+ addWidget(QGtkStylePrivate::gtk_hscrollbar_new(NULL));
+ addWidget(QGtkStylePrivate::gtk_scrolled_window_new(NULL, NULL));
+
+ initGtkMenu();
+ addWidget(QGtkStylePrivate::gtk_notebook_new());
+ addWidget(QGtkStylePrivate::gtk_progress_bar_new());
+ addWidget(QGtkStylePrivate::gtk_spin_button_new((GtkAdjustment*)
+ (QGtkStylePrivate::gtk_adjustment_new(1, 0, 1, 0, 0, 0)), 0.1, 3));
+ GtkWidget *toolbar = gtk_toolbar_new();
+ g_signal_connect (toolbar, "notify::toolbar-style", G_CALLBACK (update_toolbar_style), toolbar);
+ gtk_toolbar_insert((GtkToolbar*)toolbar, gtk_separator_tool_item_new(), -1);
+ addWidget(toolbar);
+ initGtkTreeview();
+ addWidget(gtk_vscale_new((GtkAdjustment*)(QGtkStylePrivate::gtk_adjustment_new(1, 0, 1, 0, 0, 0))));
+ addWidget(gtk_vscrollbar_new(NULL));
+ }
+ else // Rebuild map
+ {
+ // When styles change subwidgets can get rearranged
+ // as with the combo box. We need to update the widget map
+ // to reflect this;
+ QHash<QHashableLatin1Literal, GtkWidget*> oldMap = *gtkWidgetMap();
+ gtkWidgetMap()->clear();
+ QHashIterator<QHashableLatin1Literal, GtkWidget*> it(oldMap);
+ while (it.hasNext()) {
+ it.next();
+ if (!strchr(it.key().data(), '.')) {
+ addAllSubWidgets(it.value());
+ }
+ free(const_cast<char *>(it.key().data()));
+ }
+ }
+ } else {
+ qWarning("QGtkStyle could not resolve GTK. Make sure you have installed the proper libraries.");
+ }
+}
+
+/*! \internal
+ * destroys all previously buffered widgets.
+ */
+void QGtkStylePrivate::cleanupGtkWidgets()
+{
+ if (!widgetMap)
+ return;
+ if (widgetMap->contains("GtkWindow")) // Gtk will destroy all children
+ gtk_widget_destroy(widgetMap->value("GtkWindow"));
+ for (QHash<QHashableLatin1Literal, GtkWidget *>::const_iterator it = widgetMap->constBegin();
+ it != widgetMap->constEnd(); ++it)
+ free(const_cast<char *>(it.key().data()));
+}
+
+static bool resolveGConf()
+{
+ if (!QGtkStylePrivate::gconf_client_get_default) {
+ QGtkStylePrivate::gconf_client_get_default = (Ptr_gconf_client_get_default)QLibrary::resolve(QLS("gconf-2"), 4, "gconf_client_get_default");
+ QGtkStylePrivate::gconf_client_get_string = (Ptr_gconf_client_get_string)QLibrary::resolve(QLS("gconf-2"), 4, "gconf_client_get_string");
+ QGtkStylePrivate::gconf_client_get_bool = (Ptr_gconf_client_get_bool)QLibrary::resolve(QLS("gconf-2"), 4, "gconf_client_get_bool");
+ }
+ return (QGtkStylePrivate::gconf_client_get_default !=0);
+}
+
+QString QGtkStylePrivate::getGConfString(const QString &value, const QString &fallback)
+{
+ QString retVal = fallback;
+ if (resolveGConf()) {
+ g_type_init();
+ GConfClient* client = gconf_client_get_default();
+ GError *err = 0;
+ char *str = gconf_client_get_string(client, qPrintable(value), &err);
+ if (!err) {
+ retVal = QString::fromUtf8(str);
+ g_free(str);
+ }
+ g_object_unref(client);
+ if (err)
+ g_error_free (err);
+ }
+ return retVal;
+}
+
+bool QGtkStylePrivate::getGConfBool(const QString &key, bool fallback)
+{
+ bool retVal = fallback;
+ if (resolveGConf()) {
+ g_type_init();
+ GConfClient* client = gconf_client_get_default();
+ GError *err = 0;
+ bool result = gconf_client_get_bool(client, qPrintable(key), &err);
+ g_object_unref(client);
+ if (!err)
+ retVal = result;
+ else
+ g_error_free (err);
+ }
+ return retVal;
+}
+
+QString QGtkStylePrivate::getThemeName()
+{
+ QString themeName;
+ // We try to parse the gtkrc file first
+ // primarily to avoid resolving Gtk functions if
+ // the KDE 3 "Qt" style is currently in use
+ QString rcPaths = QString::fromLocal8Bit(qgetenv("GTK2_RC_FILES"));
+ if (!rcPaths.isEmpty()) {
+ QStringList paths = rcPaths.split(QLS(":"));
+ foreach (const QString &rcPath, paths) {
+ if (!rcPath.isEmpty()) {
+ QFile rcFile(rcPath);
+ if (rcFile.exists() && rcFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ QTextStream in(&rcFile);
+ while(!in.atEnd()) {
+ QString line = in.readLine();
+ if (line.contains(QLS("gtk-theme-name"))) {
+ line = line.right(line.length() - line.indexOf(QLatin1Char('=')) - 1);
+ line.remove(QLatin1Char('\"'));
+ line = line.trimmed();
+ themeName = line;
+ break;
+ }
+ }
+ }
+ }
+ if (!themeName.isEmpty())
+ break;
+ }
+ }
+
+ // Fall back to gconf
+ if (themeName.isEmpty() && resolveGConf())
+ themeName = getGConfString(QLS("/desktop/gnome/interface/gtk_theme"));
+
+ return themeName;
+}
+
+// Get size of the arrow controls in a GtkSpinButton
+int QGtkStylePrivate::getSpinboxArrowSize() const
+{
+ const int MIN_ARROW_WIDTH = 6;
+ GtkWidget *spinButton = gtkWidget("GtkSpinButton");
+ GtkStyle *style = spinButton->style;
+ gint size = pango_font_description_get_size (style->font_desc);
+ gint arrow_size;
+ arrow_size = qMax(PANGO_PIXELS (size), MIN_ARROW_WIDTH) + style->xthickness;
+ arrow_size += arrow_size%2 + 1;
+ return arrow_size;
+}
+
+
+bool QGtkStylePrivate::isKDE4Session()
+{
+ static int version = -1;
+ if (version == -1)
+ version = qgetenv("KDE_SESSION_VERSION").toInt();
+ return (version == 4);
+}
+
+void QGtkStylePrivate::applyCustomPaletteHash()
+{
+ QPalette menuPal = gtkWidgetPalette("GtkMenu");
+ GdkColor gdkBg = gtkWidget("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 toolbarPal = gtkWidgetPalette("GtkToolbar");
+ qApp->setPalette(toolbarPal, "QToolBar");
+
+ QPalette menuBarPal = gtkWidgetPalette("GtkMenuBar");
+ qApp->setPalette(menuBarPal, "QMenuBar");
+}
+
+/*! \internal
+ * Returns the gtk Widget that should be used to determine text foreground and background colors.
+*/
+GtkWidget* QGtkStylePrivate::getTextColorWidget() const
+{
+ return gtkWidget("GtkEntry");
+}
+
+void QGtkStylePrivate::setupGtkWidget(GtkWidget* widget)
+{
+ if (Q_GTK_IS_WIDGET(widget)) {
+ static GtkWidget* protoLayout = 0;
+ if (!protoLayout) {
+ protoLayout = QGtkStylePrivate::gtk_fixed_new();
+ QGtkStylePrivate::gtk_container_add((GtkContainer*)(gtkWidgetMap()->value("GtkWindow")), protoLayout);
+ }
+ Q_ASSERT(protoLayout);
+
+ if (!widget->parent && !GTK_WIDGET_TOPLEVEL(widget))
+ QGtkStylePrivate::gtk_container_add((GtkContainer*)(protoLayout), widget);
+ QGtkStylePrivate::gtk_widget_realize(widget);
+ }
+}
+
+void QGtkStylePrivate::removeWidgetFromMap(const QHashableLatin1Literal &path)
+{
+ WidgetMap *map = gtkWidgetMap();
+ WidgetMap::iterator it = map->find(path);
+ if (it != map->end()) {
+ free(const_cast<char *>(it.key().data()));
+ map->erase(it);
+ }
+}
+
+void QGtkStylePrivate::addWidgetToMap(GtkWidget *widget)
+{
+ if (Q_GTK_IS_WIDGET(widget)) {
+ gtk_widget_realize(widget);
+ QHashableLatin1Literal widgetPath = classPath(widget);
+
+ removeWidgetFromMap(widgetPath);
+ gtkWidgetMap()->insert(widgetPath, widget);
+#ifdef DUMP_GTK_WIDGET_TREE
+ qWarning("Inserted Gtk Widget: %s", widgetPath.data());
+#endif
+ }
+ }
+
+void QGtkStylePrivate::addAllSubWidgets(GtkWidget *widget, gpointer v)
+{
+ Q_UNUSED(v);
+ addWidgetToMap(widget);
+ if (GTK_CHECK_TYPE ((widget), gtk_container_get_type()))
+ gtk_container_forall((GtkContainer*)widget, addAllSubWidgets, NULL);
+}
+
+// Updates window/windowtext palette based on the indicated gtk widget
+QPalette QGtkStylePrivate::gtkWidgetPalette(const QHashableLatin1Literal &gtkWidgetName) const
+{
+ GtkWidget *gtkWidget = QGtkStylePrivate::gtkWidget(gtkWidgetName);
+ Q_ASSERT(gtkWidget);
+ 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];
+ QColor bgColor(gdkBg.red>>8, gdkBg.green>>8, gdkBg.blue>>8);
+ QColor textColor(gdkText.red>>8, gdkText.green>>8, gdkText.blue>>8);
+ QColor disabledTextColor(gdkDisabledText.red>>8, gdkDisabledText.green>>8, gdkDisabledText.blue>>8);
+ pal.setBrush(QPalette::Window, bgColor);
+ pal.setBrush(QPalette::Button, bgColor);
+ pal.setBrush(QPalette::All, QPalette::WindowText, textColor);
+ pal.setBrush(QPalette::Disabled, QPalette::WindowText, disabledTextColor);
+ pal.setBrush(QPalette::All, QPalette::ButtonText, textColor);
+ pal.setBrush(QPalette::Disabled, QPalette::ButtonText, disabledTextColor);
+ return pal;
+}
+
+
+void QGtkStyleUpdateScheduler::updateTheme()
+{
+ static QString oldTheme(QLS("qt_not_set"));
+ QPixmapCache::clear();
+
+ QFont font = QGtkStylePrivate::getThemeFont();
+ if (QApplication::font() != font)
+ qApp->setFont(font);
+
+ if (oldTheme != QGtkStylePrivate::getThemeName()) {
+ oldTheme = QGtkStylePrivate::getThemeName();
+ QPalette newPalette = qApp->style()->standardPalette();
+ QApplicationPrivate::setSystemPalette(newPalette);
+ QApplication::setPalette(newPalette);
+ if (!QGtkStylePrivate::instances.isEmpty()) {
+ QGtkStylePrivate::instances.last()->initGtkWidgets();
+ QGtkStylePrivate::instances.last()->applyCustomPaletteHash();
+ }
+ QList<QWidget*> widgets = QApplication::allWidgets();
+ // Notify all widgets that size metrics might have changed
+ foreach (QWidget *widget, widgets) {
+ QEvent e(QEvent::StyleChange);
+ QApplication::sendEvent(widget, &e);
+ }
+ }
+ QIconLoader::instance()->updateSystemTheme();
+}
+
+void QGtkStylePrivate::addWidget(GtkWidget *widget)
+{
+ if (widget) {
+ setupGtkWidget(widget);
+ addAllSubWidgets(widget);
+ }
+}
+
+
+// Fetch the application font from the pango font description
+// contained in the theme.
+QFont QGtkStylePrivate::getThemeFont()
+{
+ QFont font;
+ GtkStyle *style = gtkStyle();
+ if (style && qApp->desktopSettingsAware())
+ {
+ PangoFontDescription *gtk_font = style->font_desc;
+ font.setPointSizeF((float)(pango_font_description_get_size(gtk_font))/PANGO_SCALE);
+
+ QString family = QString::fromLatin1(pango_font_description_get_family(gtk_font));
+ if (!family.isEmpty())
+ font.setFamily(family);
+
+ int weight = pango_font_description_get_weight(gtk_font);
+ if (weight >= PANGO_WEIGHT_HEAVY)
+ font.setWeight(QFont::Black);
+ else if (weight >= PANGO_WEIGHT_BOLD)
+ font.setWeight(QFont::Bold);
+ else if (weight >= PANGO_WEIGHT_SEMIBOLD)
+ font.setWeight(QFont::DemiBold);
+ else if (weight >= PANGO_WEIGHT_NORMAL)
+ font.setWeight(QFont::Normal);
+ else
+ font.setWeight(QFont::Light);
+
+ PangoStyle fontstyle = pango_font_description_get_style(gtk_font);
+ if (fontstyle == PANGO_STYLE_ITALIC)
+ font.setStyle(QFont::StyleItalic);
+ else if (fontstyle == PANGO_STYLE_OBLIQUE)
+ font.setStyle(QFont::StyleOblique);
+ else
+ font.setStyle(QFont::StyleNormal);
+ }
+ return font;
+}
+
+
+// ----------- Native file dialogs -----------
+
+// Extract filter list from expressions of type: foo (*.a *.b *.c)"
+QStringList QGtkStylePrivate::extract_filter(const QString &rawFilter)
+{
+ QString result = rawFilter;
+ QRegExp r(QString::fromLatin1("^([^()]*)\\(([a-zA-Z0-9_.*? +;#\\-\\[\\]@\\{\\}/!<>\\$%&=^~:\\|]*)\\)$"));
+ int index = r.indexIn(result);
+ if (index >= 0)
+ result = r.cap(2);
+ return result.split(QLatin1Char(' '));
+}
+
+extern QStringList qt_make_filter_list(const QString &filter);
+
+void QGtkStylePrivate::setupGtkFileChooser(GtkWidget* gtkFileChooser, QWidget *parent,
+ const QString &dir, const QString &filter, QString *selectedFilter,
+ QFileDialog::Options options, bool isSaveDialog,
+ QMap<GtkFileFilter *, QString> *filterMap)
+{
+ g_object_set(gtkFileChooser, "do-overwrite-confirmation", gboolean(!(options & QFileDialog::DontConfirmOverwrite)), NULL);
+ g_object_set(gtkFileChooser, "local_only", gboolean(true), NULL);
+ if (!filter.isEmpty()) {
+ QStringList filters = qt_make_filter_list(filter);
+ foreach (const QString &rawfilter, filters) {
+ GtkFileFilter *gtkFilter = QGtkStylePrivate::gtk_file_filter_new ();
+ QString name = rawfilter.left(rawfilter.indexOf(QLatin1Char('(')));
+ QStringList extensions = extract_filter(rawfilter);
+ QGtkStylePrivate::gtk_file_filter_set_name(gtkFilter, qPrintable(name.isEmpty() ? extensions.join(QLS(", ")) : name));
+
+ foreach (const QString &fileExtension, extensions) {
+ // Note Gtk file dialogs are by default case sensitive
+ // and only supports basic glob syntax so we
+ // rewrite .xyz to .[xX][yY][zZ]
+ QString caseInsensitive;
+ for (int i = 0 ; i < fileExtension.length() ; ++i) {
+ QChar ch = fileExtension.at(i);
+ if (ch.isLetter()) {
+ caseInsensitive.append(
+ QLatin1Char('[') +
+ ch.toLower() +
+ ch.toUpper() +
+ QLatin1Char(']'));
+ } else {
+ caseInsensitive.append(ch);
+ }
+ }
+ QGtkStylePrivate::gtk_file_filter_add_pattern (gtkFilter, qPrintable(caseInsensitive));
+
+ }
+ if (filterMap)
+ filterMap->insert(gtkFilter, rawfilter);
+ QGtkStylePrivate::gtk_file_chooser_add_filter((GtkFileChooser*)gtkFileChooser, gtkFilter);
+ if (selectedFilter && (rawfilter == *selectedFilter))
+ QGtkStylePrivate::gtk_file_chooser_set_filter((GtkFileChooser*)gtkFileChooser, gtkFilter);
+ }
+ }
+
+ // Using the currently active window is not entirely correct, however
+ // it gives more sensible behavior for applications that do not provide a
+ // parent
+ QWidget *modalFor = parent ? parent->window() : qApp->activeWindow();
+ if (modalFor) {
+ QGtkStylePrivate::gtk_widget_realize(gtkFileChooser); // Creates X window
+ XSetTransientForHint(QGtkStylePrivate::gdk_x11_drawable_get_xdisplay(gtkFileChooser->window),
+ QGtkStylePrivate::gdk_x11_drawable_get_xid(gtkFileChooser->window),
+ modalFor->winId());
+ QGtkStylePrivate::gdk_x11_window_set_user_time (gtkFileChooser->window, QX11Info::appUserTime());
+
+ }
+
+ QFileInfo fileinfo(dir);
+ if (dir.isEmpty())
+ fileinfo.setFile(QDir::currentPath());
+ fileinfo.makeAbsolute();
+ if (fileinfo.isDir()) {
+ QGtkStylePrivate::gtk_file_chooser_set_current_folder((GtkFileChooser*)gtkFileChooser, qPrintable(dir));
+ } else if (isSaveDialog) {
+ QGtkStylePrivate::gtk_file_chooser_set_current_folder((GtkFileChooser*)gtkFileChooser, qPrintable(fileinfo.absolutePath()));
+ QGtkStylePrivate::gtk_file_chooser_set_current_name((GtkFileChooser*)gtkFileChooser, qPrintable(fileinfo.fileName()));
+ } else {
+ QGtkStylePrivate::gtk_file_chooser_set_filename((GtkFileChooser*)gtkFileChooser, qPrintable(dir));
+ }
+}
+
+QString QGtkStylePrivate::openFilename(QWidget *parent, const QString &caption, const QString &dir, const QString &filter,
+ QString *selectedFilter, QFileDialog::Options options)
+{
+ QMap<GtkFileFilter *, QString> filterMap;
+ GtkWidget *gtkFileChooser = QGtkStylePrivate::gtk_file_chooser_dialog_new (qPrintable(caption),
+ NULL,
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
+ NULL);
+
+ setupGtkFileChooser(gtkFileChooser, parent, dir, filter, selectedFilter, options, false, &filterMap);
+
+ QWidget modal_widget;
+ modal_widget.setAttribute(Qt::WA_NoChildEventsForParent, true);
+ modal_widget.setParent(parent, Qt::Window);
+ QApplicationPrivate::enterModal(&modal_widget);
+
+ QString filename;
+ if (QGtkStylePrivate::gtk_dialog_run ((GtkDialog*)gtkFileChooser) == GTK_RESPONSE_ACCEPT) {
+ char *gtk_filename = QGtkStylePrivate::gtk_file_chooser_get_filename ((GtkFileChooser*)gtkFileChooser);
+ filename = QString::fromUtf8(gtk_filename);
+ g_free (gtk_filename);
+ if (selectedFilter) {
+ GtkFileFilter *gtkFilter = QGtkStylePrivate::gtk_file_chooser_get_filter ((GtkFileChooser*)gtkFileChooser);
+ *selectedFilter = filterMap.value(gtkFilter);
+ }
+ }
+
+ QApplicationPrivate::leaveModal(&modal_widget);
+ gtk_widget_destroy (gtkFileChooser);
+ return filename;
+}
+
+
+QString QGtkStylePrivate::openDirectory(QWidget *parent, const QString &caption, const QString &dir, QFileDialog::Options options)
+{
+ QMap<GtkFileFilter *, QString> filterMap;
+ GtkWidget *gtkFileChooser = QGtkStylePrivate::gtk_file_chooser_dialog_new (qPrintable(caption),
+ NULL,
+ GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
+ NULL);
+
+ setupGtkFileChooser(gtkFileChooser, parent, dir, QString(), 0, options);
+ QWidget modal_widget;
+ modal_widget.setAttribute(Qt::WA_NoChildEventsForParent, true);
+ modal_widget.setParent(parent, Qt::Window);
+ QApplicationPrivate::enterModal(&modal_widget);
+
+ QString filename;
+ if (QGtkStylePrivate::gtk_dialog_run ((GtkDialog*)gtkFileChooser) == GTK_RESPONSE_ACCEPT) {
+ char *gtk_filename = QGtkStylePrivate::gtk_file_chooser_get_filename ((GtkFileChooser*)gtkFileChooser);
+ filename = QString::fromUtf8(gtk_filename);
+ g_free (gtk_filename);
+ }
+
+ QApplicationPrivate::leaveModal(&modal_widget);
+ gtk_widget_destroy (gtkFileChooser);
+ return filename;
+}
+
+QStringList QGtkStylePrivate::openFilenames(QWidget *parent, const QString &caption, const QString &dir, const QString &filter,
+ QString *selectedFilter, QFileDialog::Options options)
+{
+ QStringList filenames;
+ QMap<GtkFileFilter *, QString> filterMap;
+ GtkWidget *gtkFileChooser = QGtkStylePrivate::gtk_file_chooser_dialog_new (qPrintable(caption),
+ NULL,
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
+ NULL);
+
+ setupGtkFileChooser(gtkFileChooser, parent, dir, filter, selectedFilter, options, false, &filterMap);
+ g_object_set(gtkFileChooser, "select-multiple", gboolean(true), NULL);
+
+ QWidget modal_widget;
+ modal_widget.setAttribute(Qt::WA_NoChildEventsForParent, true);
+ modal_widget.setParent(parent, Qt::Window);
+ QApplicationPrivate::enterModal(&modal_widget);
+
+ if (gtk_dialog_run ((GtkDialog*)gtkFileChooser) == GTK_RESPONSE_ACCEPT) {
+ GSList *gtk_file_names = QGtkStylePrivate::gtk_file_chooser_get_filenames((GtkFileChooser*)gtkFileChooser);
+ for (GSList *iterator = gtk_file_names ; iterator; iterator = iterator->next)
+ filenames << QString::fromUtf8((const char*)iterator->data);
+ g_slist_free(gtk_file_names);
+ if (selectedFilter) {
+ GtkFileFilter *gtkFilter = QGtkStylePrivate::gtk_file_chooser_get_filter ((GtkFileChooser*)gtkFileChooser);
+ *selectedFilter = filterMap.value(gtkFilter);
+ }
+ }
+
+ QApplicationPrivate::leaveModal(&modal_widget);
+ gtk_widget_destroy (gtkFileChooser);
+ return filenames;
+}
+
+QString QGtkStylePrivate::saveFilename(QWidget *parent, const QString &caption, const QString &dir, const QString &filter,
+ QString *selectedFilter, QFileDialog::Options options)
+{
+ QMap<GtkFileFilter *, QString> filterMap;
+ GtkWidget *gtkFileChooser = QGtkStylePrivate::gtk_file_chooser_dialog_new (qPrintable(caption),
+ NULL,
+ GTK_FILE_CHOOSER_ACTION_SAVE,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
+ NULL);
+ setupGtkFileChooser(gtkFileChooser, parent, dir, filter, selectedFilter, options, true, &filterMap);
+
+ QWidget modal_widget;
+ modal_widget.setAttribute(Qt::WA_NoChildEventsForParent, true);
+ modal_widget.setParent(parent, Qt::Window);
+ QApplicationPrivate::enterModal(&modal_widget);
+
+ QString filename;
+ if (QGtkStylePrivate::gtk_dialog_run ((GtkDialog*)gtkFileChooser) == GTK_RESPONSE_ACCEPT) {
+ char *gtk_filename = QGtkStylePrivate::gtk_file_chooser_get_filename ((GtkFileChooser*)gtkFileChooser);
+ filename = QString::fromUtf8(gtk_filename);
+ g_free (gtk_filename);
+ if (selectedFilter) {
+ GtkFileFilter *gtkFilter = QGtkStylePrivate::gtk_file_chooser_get_filter ((GtkFileChooser*)gtkFileChooser);
+ *selectedFilter = filterMap.value(gtkFilter);
+ }
+ }
+
+ QApplicationPrivate::leaveModal(&modal_widget);
+ gtk_widget_destroy (gtkFileChooser);
+ return filename;
+}
+
+QIcon QGtkStylePrivate::getFilesystemIcon(const QFileInfo &info)
+{
+ QIcon icon;
+ if (gnome_vfs_init && gnome_icon_lookup_sync) {
+ gnome_vfs_init();
+ GtkIconTheme *theme = gtk_icon_theme_get_default();
+ QByteArray fileurl = QUrl::fromLocalFile(info.absoluteFilePath()).toEncoded();
+ char * icon_name = gnome_icon_lookup_sync(theme,
+ NULL,
+ fileurl.data(),
+ NULL,
+ GNOME_ICON_LOOKUP_FLAGS_NONE,
+ NULL);
+ QString iconName = QString::fromUtf8(icon_name);
+ g_free(icon_name);
+ if (iconName.startsWith(QLatin1Char('/')))
+ return QIcon(iconName);
+ return QIcon::fromTheme(iconName);
+ }
+ return icon;
+}
+
+bool operator==(const QHashableLatin1Literal &l1, const QHashableLatin1Literal &l2)
+{
+ return l1.size() == l2.size() || qstrcmp(l1.data(), l2.data()) == 0;
+}
+
+// copied from qHash.cpp
+uint qHash(const QHashableLatin1Literal &key)
+{
+ int n = key.size();
+ const uchar *p = reinterpret_cast<const uchar *>(key.data());
+ uint h = 0;
+ uint g;
+
+ while (n--) {
+ h = (h << 4) + *p++;
+ if ((g = (h & 0xf0000000)) != 0)
+ h ^= g >> 23;
+ h &= ~g;
+ }
+ return h;
+}
+
+QT_END_NAMESPACE
+
+#endif // !defined(QT_NO_STYLE_GTK)
diff --git a/src/widgets/styles/qgtkstyle_p.h b/src/widgets/styles/qgtkstyle_p.h
new file mode 100644
index 0000000000..55089268b3
--- /dev/null
+++ b/src/widgets/styles/qgtkstyle_p.h
@@ -0,0 +1,531 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGTKSTYLE_P_H
+#define QGTKSTYLE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qglobal.h>
+#if !defined(QT_NO_STYLE_GTK)
+
+#include <QtCore/qstring.h>
+#include <QtCore/qstringbuilder.h>
+#include <QtCore/qcoreapplication.h>
+
+#include <QtWidgets/QFileDialog>
+
+#include <QtWidgets/QGtkStyle>
+#include <private/qcleanlooksstyle_p.h>
+
+#undef signals // Collides with GTK stymbols
+#include <gtk/gtk.h>
+
+typedef unsigned long XID;
+
+#undef GTK_OBJECT_FLAGS
+#define GTK_OBJECT_FLAGS(obj)(((GtkObject*)(obj))->flags)
+#define Q_GTK_IS_WIDGET(widget) widget && GTK_CHECK_TYPE ((widget), QGtkStylePrivate::gtk_widget_get_type())
+
+#define QLS(x) QLatin1String(x)
+
+QT_BEGIN_NAMESPACE
+
+// ### Qt 4.7 - merge with QLatin1Literal
+class QHashableLatin1Literal
+{
+public:
+ int size() const { return m_size; }
+ const char *data() const { return m_data; }
+
+#ifdef __SUNPRO_CC
+ QHashableLatin1Literal(const char* str)
+ : m_size(strlen(str)), m_data(str) {}
+#else
+ template <int N>
+ QHashableLatin1Literal(const char (&str)[N])
+ : m_size(N - 1), m_data(str) {}
+#endif
+
+ QHashableLatin1Literal(const QHashableLatin1Literal &other)
+ : m_size(other.m_size), m_data(other.m_data)
+ {}
+
+ QHashableLatin1Literal &operator=(const QHashableLatin1Literal &other)
+ {
+ if (this == &other)
+ return *this;
+ *const_cast<int *>(&m_size) = other.m_size;
+ *const_cast<char **>(&m_data) = const_cast<char *>(other.m_data);
+ return *this;
+ }
+
+ QString toString() const { return QString::fromLatin1(m_data, m_size); }
+
+ static QHashableLatin1Literal fromData(const char *str)
+ {
+ return QHashableLatin1Literal(str, qstrlen(str));
+ }
+
+private:
+ QHashableLatin1Literal(const char *str, int length)
+ : m_size(length), m_data(str)
+ {}
+
+ const int m_size;
+ const char *m_data;
+};
+
+bool operator==(const QHashableLatin1Literal &l1, const QHashableLatin1Literal &l2);
+inline bool operator!=(const QHashableLatin1Literal &l1, const QHashableLatin1Literal &l2) { return !operator==(l1, l2); }
+uint qHash(const QHashableLatin1Literal &key);
+
+QT_END_NAMESPACE
+
+class GConf;
+class GConfClient;
+
+typedef GConfClient* (*Ptr_gconf_client_get_default)();
+typedef char* (*Ptr_gconf_client_get_string)(GConfClient*, const char*, GError **);
+typedef bool (*Ptr_gconf_client_get_bool)(GConfClient*, const char*, GError **);
+
+typedef void (*Ptr_gtk_init)(int *, char ***);
+typedef GtkWidget* (*Ptr_gtk_window_new) (GtkWindowType);
+typedef GtkStyle* (*Ptr_gtk_style_attach)(GtkStyle *, GdkWindow *);
+typedef void (*Ptr_gtk_widget_destroy) (GtkWidget *);
+typedef void (*Ptr_gtk_widget_realize) (GtkWidget *);
+typedef void (*Ptr_gtk_widget_set_default_direction) (GtkTextDirection);
+typedef void (*Ptr_gtk_widget_modify_color)(GtkWidget *widget, GtkStateType state, const GdkColor *color);
+typedef GtkWidget* (*Ptr_gtk_arrow_new)(GtkArrowType, GtkShadowType);
+typedef GtkWidget* (*Ptr_gtk_menu_item_new_with_label)(const gchar *);
+typedef GtkWidget* (*Ptr_gtk_separator_menu_item_new)(void);
+typedef GtkWidget* (*Ptr_gtk_check_menu_item_new_with_label)(const gchar *);
+typedef GtkWidget* (*Ptr_gtk_menu_bar_new)(void);
+typedef GtkWidget* (*Ptr_gtk_menu_new)(void);
+typedef GtkWidget* (*Ptr_gtk_combo_box_entry_new)(void);
+typedef GtkWidget* (*Ptr_gtk_toolbar_new)(void);
+typedef GtkWidget* (*Ptr_gtk_spin_button_new)(GtkAdjustment*, double, int);
+typedef GtkWidget* (*Ptr_gtk_button_new)(void);
+typedef GtkWidget* (*Ptr_gtk_tool_button_new)(GtkWidget *, const gchar *);
+typedef GtkWidget* (*Ptr_gtk_hbutton_box_new)(void);
+typedef GtkWidget* (*Ptr_gtk_check_button_new)(void);
+typedef GtkWidget* (*Ptr_gtk_radio_button_new)(GSList *);
+typedef GtkWidget* (*Ptr_gtk_notebook_new)(void);
+typedef GtkWidget* (*Ptr_gtk_progress_bar_new)(void);
+typedef GtkWidget* (*Ptr_gtk_hscale_new)(GtkAdjustment*);
+typedef GtkWidget* (*Ptr_gtk_vscale_new)(GtkAdjustment*);
+typedef GtkWidget* (*Ptr_gtk_hscrollbar_new)(GtkAdjustment*);
+typedef GtkWidget* (*Ptr_gtk_vscrollbar_new)(GtkAdjustment*);
+typedef GtkWidget* (*Ptr_gtk_scrolled_window_new)(GtkAdjustment*, GtkAdjustment*);
+typedef gchar* (*Ptr_gtk_check_version)(guint, guint, guint);
+typedef GtkToolItem* (*Ptr_gtk_separator_tool_item_new) (void);
+typedef GtkWidget* (*Ptr_gtk_entry_new)(void);
+typedef GtkWidget* (*Ptr_gtk_tree_view_new)(void);
+typedef GtkTreeViewColumn* (*Ptr_gtk_tree_view_get_column)(GtkTreeView *, gint);
+typedef GtkWidget* (*Ptr_gtk_combo_box_new)(void);
+typedef GtkWidget* (*Ptr_gtk_frame_new)(const gchar *);
+typedef GtkWidget* (*Ptr_gtk_expander_new)(const gchar*);
+typedef GtkWidget* (*Ptr_gtk_statusbar_new)(void);
+typedef GtkSettings* (*Ptr_gtk_settings_get_default)(void);
+typedef GtkAdjustment* (*Ptr_gtk_range_get_adjustment)(GtkRange *);
+typedef void (*Ptr_gtk_range_set_adjustment)(GtkRange *, GtkAdjustment *);
+typedef void (*Ptr_gtk_progress_configure)(GtkProgress *, double, double, double);
+typedef void (*Ptr_gtk_range_set_inverted)(GtkRange*, bool);
+typedef void (*Ptr_gtk_container_add)(GtkContainer *container, GtkWidget *widget);
+typedef GtkIconSet* (*Ptr_gtk_icon_factory_lookup_default) (const gchar*);
+typedef GtkIconTheme* (*Ptr_gtk_icon_theme_get_default) (void);
+typedef void (*Ptr_gtk_widget_style_get)(GtkWidget *, const gchar *first_property_name, ...);
+typedef GtkTreeViewColumn* (*Ptr_gtk_tree_view_column_new)(void);
+typedef GtkWidget* (*Ptr_gtk_fixed_new)(void);
+typedef GdkPixbuf* (*Ptr_gtk_icon_set_render_icon)(GtkIconSet *, GtkStyle *, GtkTextDirection, GtkStateType, GtkIconSize, GtkWidget *,const char *);
+typedef void (*Ptr_gtk_tree_view_append_column) (GtkTreeView*, GtkTreeViewColumn*);
+typedef void (*Ptr_gtk_paint_check) (GtkStyle*,GdkWindow*, GtkStateType, GtkShadowType, const GdkRectangle *, GtkWidget *, const gchar *, gint , gint , gint , gint);
+typedef void (*Ptr_gtk_paint_box) (GtkStyle*,GdkWindow*, GtkStateType, GtkShadowType, const GdkRectangle *, GtkWidget *, const gchar *, gint , gint , gint , gint);
+typedef void (*Ptr_gtk_paint_box_gap) (GtkStyle*,GdkWindow*, GtkStateType, GtkShadowType, const GdkRectangle *, GtkWidget *, const gchar *, gint, gint, gint , gint, GtkPositionType, gint gap_x, gint gap_width);
+typedef void (*Ptr_gtk_paint_resize_grip) (GtkStyle*,GdkWindow*, GtkStateType, const GdkRectangle *, GtkWidget *, const gchar *, GdkWindowEdge, gint , gint , gint , gint);
+typedef void (*Ptr_gtk_paint_focus) (GtkStyle*,GdkWindow*, GtkStateType, const GdkRectangle *, GtkWidget *, const gchar *, gint , gint , gint , gint);
+typedef void (*Ptr_gtk_paint_shadow) (GtkStyle*,GdkWindow*, GtkStateType, GtkShadowType, const GdkRectangle *, GtkWidget *, const gchar *, gint , gint , gint , gint);
+typedef void (*Ptr_gtk_paint_slider) (GtkStyle*,GdkWindow*, GtkStateType, GtkShadowType, const GdkRectangle *, GtkWidget *, const gchar *, gint , gint , gint , gint, GtkOrientation);
+typedef void (*Ptr_gtk_paint_expander) (GtkStyle*,GdkWindow*, GtkStateType, const GdkRectangle *, GtkWidget *, const gchar *, gint , gint , GtkExpanderStyle );
+typedef void (*Ptr_gtk_paint_handle) (GtkStyle*,GdkWindow*, GtkStateType, GtkShadowType, const GdkRectangle *, GtkWidget *, const gchar *, gint , gint , gint , gint, GtkOrientation);
+typedef void (*Ptr_gtk_paint_arrow) (GtkStyle*,GdkWindow*, GtkStateType, GtkShadowType, const GdkRectangle *, GtkWidget *, const gchar *, GtkArrowType, gboolean, gint , gint , gint , gint);
+typedef void (*Ptr_gtk_paint_option) (GtkStyle*,GdkWindow*, GtkStateType, GtkShadowType, const GdkRectangle *, GtkWidget *, const gchar *, gint , gint , gint , gint);
+typedef void (*Ptr_gtk_paint_flat_box) (GtkStyle*,GdkWindow*, GtkStateType, GtkShadowType, const GdkRectangle *, GtkWidget *, const gchar *, gint , gint , gint , gint);
+typedef void (*Ptr_gtk_paint_extension) (GtkStyle *, GdkWindow *, GtkStateType, GtkShadowType, const GdkRectangle *, GtkWidget *, const gchar *, gint, gint, gint, gint, GtkPositionType);
+typedef void (*Ptr_gtk_adjustment_configure) (GtkAdjustment *, double, double, double, double, double, double);
+typedef GtkObject* (*Ptr_gtk_adjustment_new) (double, double, double, double, double, double);
+typedef void (*Ptr_gtk_paint_hline) (GtkStyle *, GdkWindow *, GtkStateType, const GdkRectangle *, GtkWidget *, const gchar *, gint, gint, gint y);
+typedef void (*Ptr_gtk_paint_vline) (GtkStyle *, GdkWindow *, GtkStateType, const GdkRectangle *, GtkWidget *, const gchar *, gint, gint, gint);
+typedef void (*Ptr_gtk_menu_item_set_submenu) (GtkMenuItem *, GtkWidget *);
+typedef void (*Ptr_gtk_container_forall) (GtkContainer *, GtkCallback, gpointer);
+typedef void (*Ptr_gtk_widget_size_allocate) (GtkWidget *, GtkAllocation*);
+typedef void (*Ptr_gtk_widget_size_request) (GtkWidget *widget, GtkRequisition *requisition);
+typedef void (*Ptr_gtk_widget_set_direction) (GtkWidget *, GtkTextDirection);
+typedef void (*Ptr_gtk_widget_path) (GtkWidget *, guint *, gchar **, gchar**);
+
+typedef void (*Ptr_gtk_toolbar_insert) (GtkToolbar *toolbar, GtkToolItem *item, int pos);
+typedef void (*Ptr_gtk_menu_shell_append)(GtkMenuShell *, GtkWidget *);
+typedef GtkType (*Ptr_gtk_container_get_type) (void);
+typedef GtkType (*Ptr_gtk_window_get_type) (void);
+typedef GtkType (*Ptr_gtk_widget_get_type) (void);
+typedef GtkStyle* (*Ptr_gtk_rc_get_style_by_paths) (GtkSettings *, const char *, const char *, GType);
+typedef gint (*Ptr_pango_font_description_get_size) (const PangoFontDescription *);
+typedef PangoWeight (*Ptr_pango_font_description_get_weight) (const PangoFontDescription *);
+typedef const char* (*Ptr_pango_font_description_get_family) (const PangoFontDescription *);
+typedef PangoStyle (*Ptr_pango_font_description_get_style) (const PangoFontDescription *desc);
+typedef gboolean (*Ptr_gtk_file_chooser_set_current_folder)(GtkFileChooser *, const gchar *);
+typedef GtkFileFilter* (*Ptr_gtk_file_filter_new)(void);
+typedef void (*Ptr_gtk_file_filter_set_name)(GtkFileFilter *, const gchar *);
+typedef void (*Ptr_gtk_file_filter_add_pattern)(GtkFileFilter *filter, const gchar *pattern);
+typedef void (*Ptr_gtk_file_chooser_add_filter)(GtkFileChooser *chooser, GtkFileFilter *filter);
+typedef void (*Ptr_gtk_file_chooser_set_filter)(GtkFileChooser *chooser, GtkFileFilter *filter);
+typedef GtkFileFilter* (*Ptr_gtk_file_chooser_get_filter)(GtkFileChooser *chooser);
+typedef gchar* (*Ptr_gtk_file_chooser_get_filename)(GtkFileChooser *chooser);
+typedef GSList* (*Ptr_gtk_file_chooser_get_filenames)(GtkFileChooser *chooser);
+typedef GtkWidget* (*Ptr_gtk_file_chooser_dialog_new)(const gchar *title,
+ GtkWindow *parent,
+ GtkFileChooserAction action,
+ const gchar *first_button_text,
+ ...);
+typedef void (*Ptr_gtk_file_chooser_set_current_name) (GtkFileChooser *, const gchar *);
+typedef gboolean (*Ptr_gtk_file_chooser_set_filename) (GtkFileChooser *chooser, const gchar *name);
+typedef gint (*Ptr_gtk_dialog_run) (GtkDialog*);
+typedef void (*Ptr_gtk_border_free)(GtkBorder *);
+
+typedef guchar* (*Ptr_gdk_pixbuf_get_pixels) (const GdkPixbuf *pixbuf);
+typedef int (*Ptr_gdk_pixbuf_get_width) (const GdkPixbuf *pixbuf);
+typedef void (*Ptr_gdk_color_free) (const GdkColor *);
+typedef int (*Ptr_gdk_pixbuf_get_height) (const GdkPixbuf *pixbuf);
+typedef GdkPixbuf* (*Ptr_gdk_pixbuf_get_from_drawable) (GdkPixbuf *dest, GdkDrawable *src,
+ GdkColormap *cmap, int src_x,
+ int src_y, int dest_x, int dest_y,
+ int width, int height);
+typedef GdkPixmap* (*Ptr_gdk_pixmap_new) (GdkDrawable *drawable, gint width, gint height, gint depth);
+typedef GdkPixbuf* (*Ptr_gdk_pixbuf_new) (GdkColorspace colorspace, gboolean has_alpha,
+ int bits_per_sample, int width, int height);
+typedef void (*Ptr_gdk_draw_rectangle) (GdkDrawable *drawable, GdkGC *gc,
+ gboolean filled, gint x, gint y, gint width, gint height);
+typedef void (*Ptr_gdk_pixbuf_unref)(GdkPixbuf *);
+typedef void (*Ptr_gdk_drawable_unref)(GdkDrawable *);
+typedef gint (*Ptr_gdk_drawable_get_depth)(GdkDrawable *);
+typedef void (*Ptr_gdk_x11_window_set_user_time) (GdkWindow *window, guint32);
+typedef XID (*Ptr_gdk_x11_drawable_get_xid) (GdkDrawable *);
+typedef Display* (*Ptr_gdk_x11_drawable_get_xdisplay) ( GdkDrawable *);
+
+
+QT_BEGIN_NAMESPACE
+
+typedef QStringList (*_qt_filedialog_open_filenames_hook)(QWidget * parent, const QString &caption, const QString &dir,
+ const QString &filter, QString *selectedFilter, QFileDialog::Options options);
+typedef QString (*_qt_filedialog_open_filename_hook) (QWidget * parent, const QString &caption, const QString &dir,
+ const QString &filter, QString *selectedFilter, QFileDialog::Options options);
+typedef QString (*_qt_filedialog_save_filename_hook) (QWidget * parent, const QString &caption, const QString &dir,
+ const QString &filter, QString *selectedFilter, QFileDialog::Options options);
+typedef QString (*_qt_filedialog_existing_directory_hook)(QWidget *parent, const QString &caption, const QString &dir,
+ QFileDialog::Options options);
+
+extern Q_WIDGETS_EXPORT _qt_filedialog_open_filename_hook qt_filedialog_open_filename_hook;
+extern Q_WIDGETS_EXPORT _qt_filedialog_open_filenames_hook qt_filedialog_open_filenames_hook;
+extern Q_WIDGETS_EXPORT _qt_filedialog_save_filename_hook qt_filedialog_save_filename_hook;
+extern Q_WIDGETS_EXPORT _qt_filedialog_existing_directory_hook qt_filedialog_existing_directory_hook;
+
+class QGtkStylePrivate;
+
+class QGtkStyleFilter : public QObject
+{
+public:
+ QGtkStyleFilter(QGtkStylePrivate* sp)
+ : stylePrivate(sp)
+ {}
+private:
+ QGtkStylePrivate* stylePrivate;
+ bool eventFilter(QObject *obj, QEvent *e);
+};
+
+typedef enum {
+ GNOME_ICON_LOOKUP_FLAGS_NONE = 0,
+ GNOME_ICON_LOOKUP_FLAGS_EMBEDDING_TEXT = 1<<0,
+ GNOME_ICON_LOOKUP_FLAGS_SHOW_SMALL_IMAGES_AS_THEMSELVES = 1<<1,
+ GNOME_ICON_LOOKUP_FLAGS_ALLOW_SVG_AS_THEMSELVES = 1<<2
+} GnomeIconLookupFlags;
+
+typedef enum {
+ GNOME_ICON_LOOKUP_RESULT_FLAGS_NONE = 0,
+ GNOME_ICON_LOOKUP_RESULT_FLAGS_THUMBNAIL = 1<<0
+} GnomeIconLookupResultFlags;
+
+struct GnomeThumbnailFactory;
+typedef gboolean (*Ptr_gnome_vfs_init) (void);
+typedef char* (*Ptr_gnome_icon_lookup_sync) (
+ GtkIconTheme *icon_theme,
+ GnomeThumbnailFactory *,
+ const char *file_uri,
+ const char *custom_icon,
+ GnomeIconLookupFlags flags,
+ GnomeIconLookupResultFlags *result);
+
+class QGtkStylePrivate : public QCleanlooksStylePrivate
+{
+ Q_DECLARE_PUBLIC(QGtkStyle)
+public:
+ QGtkStylePrivate();
+ ~QGtkStylePrivate();
+
+ QGtkStyleFilter filter;
+
+ static GtkWidget* gtkWidget(const QHashableLatin1Literal &path);
+ static GtkStyle* gtkStyle(const QHashableLatin1Literal &path = QHashableLatin1Literal("GtkWindow"));
+
+ virtual void resolveGtk() const;
+ virtual void initGtkMenu() const;
+ virtual void initGtkTreeview() const;
+ virtual void initGtkWidgets() const;
+
+ static void cleanupGtkWidgets();
+
+ static bool isKDE4Session();
+ void applyCustomPaletteHash();
+ static QFont getThemeFont();
+ static bool isThemeAvailable() { return gtkStyle() != 0; }
+
+ static bool getGConfBool(const QString &key, bool fallback = 0);
+ static QString getGConfString(const QString &key, const QString &fallback = QString());
+
+ static QString getThemeName();
+ virtual int getSpinboxArrowSize() const;
+
+ static void setupGtkFileChooser(GtkWidget* gtkFileChooser, QWidget *parent,
+ const QString &dir, const QString &filter, QString *selectedFilter,
+ QFileDialog::Options options, bool isSaveDialog = false,
+ QMap<GtkFileFilter *, QString> *filterMap = 0);
+
+ static QString openFilename(QWidget *parent, const QString &caption, const QString &dir, const QString &filter,
+ QString *selectedFilter, QFileDialog::Options options);
+ static QString saveFilename(QWidget *parent, const QString &caption, const QString &dir, const QString &filter,
+ QString *selectedFilter, QFileDialog::Options options);
+ static QString openDirectory(QWidget *parent, const QString &caption, const QString &dir, QFileDialog::Options options);
+ static QStringList openFilenames(QWidget *parent, const QString &caption, const QString &dir, const QString &filter,
+ QString *selectedFilter, QFileDialog::Options options);
+ static QIcon getFilesystemIcon(const QFileInfo &);
+
+ static Ptr_gtk_container_forall gtk_container_forall;
+ static Ptr_gtk_init gtk_init;
+ static Ptr_gtk_style_attach gtk_style_attach;
+ static Ptr_gtk_window_new gtk_window_new;
+ static Ptr_gtk_widget_destroy gtk_widget_destroy;
+ static Ptr_gtk_widget_realize gtk_widget_realize;
+ static Ptr_gtk_widget_set_default_direction gtk_widget_set_default_direction;
+ static Ptr_gtk_widget_modify_color gtk_widget_modify_fg;
+ static Ptr_gtk_widget_modify_color gtk_widget_modify_bg;
+ static Ptr_gtk_menu_item_new_with_label gtk_menu_item_new_with_label;
+ static Ptr_gtk_arrow_new gtk_arrow_new;
+ static Ptr_gtk_check_menu_item_new_with_label gtk_check_menu_item_new_with_label;
+ static Ptr_gtk_menu_bar_new gtk_menu_bar_new;
+ static Ptr_gtk_menu_new gtk_menu_new;
+ static Ptr_gtk_expander_new gtk_expander_new;
+ static Ptr_gtk_button_new gtk_button_new;
+ static Ptr_gtk_tool_button_new gtk_tool_button_new;
+ static Ptr_gtk_hbutton_box_new gtk_hbutton_box_new;
+ static Ptr_gtk_check_button_new gtk_check_button_new;
+ static Ptr_gtk_radio_button_new gtk_radio_button_new;
+ static Ptr_gtk_spin_button_new gtk_spin_button_new;
+ static Ptr_gtk_separator_tool_item_new gtk_separator_tool_item_new;
+ static Ptr_gtk_toolbar_insert gtk_toolbar_insert;
+ static Ptr_gtk_frame_new gtk_frame_new;
+ static Ptr_gtk_statusbar_new gtk_statusbar_new;
+ static Ptr_gtk_entry_new gtk_entry_new;
+ static Ptr_gtk_hscale_new gtk_hscale_new;
+ static Ptr_gtk_vscale_new gtk_vscale_new;
+ static Ptr_gtk_hscrollbar_new gtk_hscrollbar_new;
+ static Ptr_gtk_vscrollbar_new gtk_vscrollbar_new;
+ static Ptr_gtk_scrolled_window_new gtk_scrolled_window_new;
+ static Ptr_gtk_notebook_new gtk_notebook_new;
+ static Ptr_gtk_toolbar_new gtk_toolbar_new;
+ static Ptr_gtk_tree_view_new gtk_tree_view_new;
+ static Ptr_gtk_tree_view_get_column gtk_tree_view_get_column;
+ static Ptr_gtk_combo_box_new gtk_combo_box_new;
+ static Ptr_gtk_combo_box_entry_new gtk_combo_box_entry_new;
+ static Ptr_gtk_progress_bar_new gtk_progress_bar_new;
+ static Ptr_gtk_container_add gtk_container_add;
+ static Ptr_gtk_menu_shell_append gtk_menu_shell_append;
+ static Ptr_gtk_progress_configure gtk_progress_configure;
+ static Ptr_gtk_range_get_adjustment gtk_range_get_adjustment;
+ static Ptr_gtk_range_set_adjustment gtk_range_set_adjustment;
+ static Ptr_gtk_range_set_inverted gtk_range_set_inverted;
+ static Ptr_gtk_icon_factory_lookup_default gtk_icon_factory_lookup_default;
+ static Ptr_gtk_icon_theme_get_default gtk_icon_theme_get_default;
+ static Ptr_gtk_widget_style_get gtk_widget_style_get;
+ static Ptr_gtk_icon_set_render_icon gtk_icon_set_render_icon;
+ static Ptr_gtk_fixed_new gtk_fixed_new;
+ static Ptr_gtk_tree_view_column_new gtk_tree_view_column_new;
+ static Ptr_gtk_tree_view_append_column gtk_tree_view_append_column;
+ static Ptr_gtk_paint_check gtk_paint_check;
+ static Ptr_gtk_paint_box gtk_paint_box;
+ static Ptr_gtk_paint_box_gap gtk_paint_box_gap;
+ static Ptr_gtk_paint_flat_box gtk_paint_flat_box;
+ static Ptr_gtk_paint_option gtk_paint_option;
+ static Ptr_gtk_paint_extension gtk_paint_extension;
+ static Ptr_gtk_paint_slider gtk_paint_slider;
+ static Ptr_gtk_paint_shadow gtk_paint_shadow;
+ static Ptr_gtk_paint_resize_grip gtk_paint_resize_grip;
+ static Ptr_gtk_paint_focus gtk_paint_focus;
+ static Ptr_gtk_paint_arrow gtk_paint_arrow;
+ static Ptr_gtk_paint_handle gtk_paint_handle;
+ static Ptr_gtk_paint_expander gtk_paint_expander;
+ static Ptr_gtk_adjustment_configure gtk_adjustment_configure;
+ static Ptr_gtk_adjustment_new gtk_adjustment_new;
+ static Ptr_gtk_paint_vline gtk_paint_vline;
+ static Ptr_gtk_paint_hline gtk_paint_hline;
+ static Ptr_gtk_menu_item_set_submenu gtk_menu_item_set_submenu;
+ static Ptr_gtk_settings_get_default gtk_settings_get_default;
+ static Ptr_gtk_separator_menu_item_new gtk_separator_menu_item_new;
+ static Ptr_gtk_widget_size_allocate gtk_widget_size_allocate;
+ static Ptr_gtk_widget_size_request gtk_widget_size_request;
+ static Ptr_gtk_widget_set_direction gtk_widget_set_direction;
+ static Ptr_gtk_widget_path gtk_widget_path;
+ static Ptr_gtk_container_get_type gtk_container_get_type;
+ static Ptr_gtk_window_get_type gtk_window_get_type;
+ static Ptr_gtk_widget_get_type gtk_widget_get_type;
+ static Ptr_gtk_rc_get_style_by_paths gtk_rc_get_style_by_paths;
+ static Ptr_gtk_check_version gtk_check_version;
+ static Ptr_gtk_border_free gtk_border_free;
+
+ static Ptr_pango_font_description_get_size pango_font_description_get_size;
+ static Ptr_pango_font_description_get_weight pango_font_description_get_weight;
+ static Ptr_pango_font_description_get_family pango_font_description_get_family;
+ static Ptr_pango_font_description_get_style pango_font_description_get_style;
+
+ static Ptr_gtk_file_filter_new gtk_file_filter_new;
+ static Ptr_gtk_file_filter_set_name gtk_file_filter_set_name;
+ static Ptr_gtk_file_filter_add_pattern gtk_file_filter_add_pattern;
+ static Ptr_gtk_file_chooser_add_filter gtk_file_chooser_add_filter;
+ static Ptr_gtk_file_chooser_set_filter gtk_file_chooser_set_filter;
+ static Ptr_gtk_file_chooser_get_filter gtk_file_chooser_get_filter;
+ static Ptr_gtk_file_chooser_dialog_new gtk_file_chooser_dialog_new;
+ static Ptr_gtk_file_chooser_set_current_folder gtk_file_chooser_set_current_folder;
+ static Ptr_gtk_file_chooser_get_filename gtk_file_chooser_get_filename;
+ static Ptr_gtk_file_chooser_get_filenames gtk_file_chooser_get_filenames;
+ static Ptr_gtk_file_chooser_set_current_name gtk_file_chooser_set_current_name;
+ static Ptr_gtk_dialog_run gtk_dialog_run;
+ static Ptr_gtk_file_chooser_set_filename gtk_file_chooser_set_filename;
+
+ static Ptr_gdk_pixbuf_get_pixels gdk_pixbuf_get_pixels;
+ static Ptr_gdk_pixbuf_get_width gdk_pixbuf_get_width;
+ static Ptr_gdk_pixbuf_get_height gdk_pixbuf_get_height;
+ static Ptr_gdk_pixmap_new gdk_pixmap_new;
+ static Ptr_gdk_pixbuf_new gdk_pixbuf_new;
+ static Ptr_gdk_pixbuf_get_from_drawable gdk_pixbuf_get_from_drawable;
+ static Ptr_gdk_draw_rectangle gdk_draw_rectangle;
+ static Ptr_gdk_pixbuf_unref gdk_pixbuf_unref;
+ static Ptr_gdk_drawable_unref gdk_drawable_unref;
+ static Ptr_gdk_drawable_get_depth gdk_drawable_get_depth;
+ static Ptr_gdk_color_free gdk_color_free;
+ static Ptr_gdk_x11_window_set_user_time gdk_x11_window_set_user_time;
+ static Ptr_gdk_x11_drawable_get_xid gdk_x11_drawable_get_xid;
+ static Ptr_gdk_x11_drawable_get_xdisplay gdk_x11_drawable_get_xdisplay;
+
+ static Ptr_gconf_client_get_default gconf_client_get_default;
+ static Ptr_gconf_client_get_string gconf_client_get_string;
+ static Ptr_gconf_client_get_bool gconf_client_get_bool;
+
+ static Ptr_gnome_icon_lookup_sync gnome_icon_lookup_sync;
+ static Ptr_gnome_vfs_init gnome_vfs_init;
+
+ virtual QPalette gtkWidgetPalette(const QHashableLatin1Literal &gtkWidgetName) const;
+
+protected:
+ typedef QHash<QHashableLatin1Literal, GtkWidget*> WidgetMap;
+
+ static inline void destroyWidgetMap()
+ {
+ cleanupGtkWidgets();
+ delete widgetMap;
+ widgetMap = 0;
+ }
+
+ static inline WidgetMap *gtkWidgetMap()
+ {
+ if (!widgetMap) {
+ widgetMap = new WidgetMap();
+ qAddPostRoutine(destroyWidgetMap);
+ }
+ return widgetMap;
+ }
+
+ static QStringList extract_filter(const QString &rawFilter);
+
+ virtual GtkWidget* getTextColorWidget() const;
+ static void setupGtkWidget(GtkWidget* widget);
+ static void addWidgetToMap(GtkWidget* widget);
+ static void addAllSubWidgets(GtkWidget *widget, gpointer v = 0);
+ static void addWidget(GtkWidget *widget);
+ static void removeWidgetFromMap(const QHashableLatin1Literal &path);
+
+ virtual void init();
+
+private:
+ static QList<QGtkStylePrivate *> instances;
+ static WidgetMap *widgetMap;
+ friend class QGtkStyleUpdateScheduler;
+};
+
+// 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
+#endif // QGTKSTYLE_P_H
diff --git a/src/gui/styles/qmacstyle.qdoc b/src/widgets/styles/qmacstyle.qdoc
index e6cb79cc53..e6cb79cc53 100644
--- a/src/gui/styles/qmacstyle.qdoc
+++ b/src/widgets/styles/qmacstyle.qdoc
diff --git a/src/widgets/styles/qmacstyle_mac.h b/src/widgets/styles/qmacstyle_mac.h
new file mode 100644
index 0000000000..44940bd2b7
--- /dev/null
+++ b/src/widgets/styles/qmacstyle_mac.h
@@ -0,0 +1,148 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMACSTYLE_MAC_H
+#define QMACSTYLE_MAC_H
+
+#include <QtWidgets/qwindowsstyle.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#if defined(Q_WS_MAC) && !defined(QT_NO_STYLE_MAC)
+
+class QPalette;
+
+#if defined(QT_PLUGIN)
+#define Q_WIDGETS_EXPORT_STYLE_MAC
+#else
+#define Q_WIDGETS_EXPORT_STYLE_MAC Q_WIDGETS_EXPORT
+#endif
+
+class QPushButton;
+class QStyleOptionButton;
+class QMacStylePrivate;
+class Q_WIDGETS_EXPORT_STYLE_MAC QMacStyle : public QWindowsStyle
+{
+ Q_OBJECT
+public:
+ QMacStyle();
+ virtual ~QMacStyle();
+
+ void polish(QWidget *w);
+ void unpolish(QWidget *w);
+
+ void polish(QApplication*);
+ void unpolish(QApplication*);
+
+ void polish(QPalette &pal);
+
+ void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p,
+ const QWidget *w = 0) const;
+ void drawControl(ControlElement element, const QStyleOption *opt, QPainter *p,
+ const QWidget *w = 0) const;
+ QRect subElementRect(SubElement r, const QStyleOption *opt, const QWidget *widget = 0) const;
+ void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p,
+ const QWidget *w = 0) const;
+ SubControl hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt,
+ const QPoint &pt, const QWidget *w = 0) const;
+ QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc,
+ const QWidget *w = 0) const;
+ QSize sizeFromContents(ContentsType ct, const QStyleOption *opt,
+ const QSize &contentsSize, const QWidget *w = 0) const;
+
+ int pixelMetric(PixelMetric pm, const QStyleOption *opt = 0, const QWidget *widget = 0) const;
+
+ QPalette standardPalette() const;
+
+ virtual int styleHint(StyleHint sh, const QStyleOption *opt = 0, const QWidget *w = 0,
+ QStyleHintReturn *shret = 0) const;
+
+ enum FocusRectPolicy { FocusEnabled, FocusDisabled, FocusDefault };
+ static void setFocusRectPolicy(QWidget *w, FocusRectPolicy policy);
+ static FocusRectPolicy focusRectPolicy(const QWidget *w);
+
+ enum WidgetSizePolicy { SizeSmall, SizeLarge, SizeMini, SizeDefault
+#ifdef QT3_SUPPORT
+ , SizeNone = SizeDefault
+#endif
+ };
+ static void setWidgetSizePolicy(const QWidget *w, WidgetSizePolicy policy);
+ static WidgetSizePolicy widgetSizePolicy(const QWidget *w);
+
+ QPixmap standardPixmap(StandardPixmap sp, const QStyleOption *opt,
+ const QWidget *widget = 0) const;
+
+ QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap,
+ const QStyleOption *opt) const;
+
+ virtual void drawItemText(QPainter *p, const QRect &r, int flags, const QPalette &pal,
+ bool enabled, const QString &text, QPalette::ColorRole textRole = QPalette::NoRole) const;
+
+ bool event(QEvent *e);
+
+protected Q_SLOTS:
+ QIcon standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *opt = 0,
+ const QWidget *widget = 0) const;
+ int layoutSpacingImplementation(QSizePolicy::ControlType control1,
+ QSizePolicy::ControlType control2,
+ Qt::Orientation orientation,
+ const QStyleOption *option = 0,
+ const QWidget *widget = 0) const;
+
+private:
+ Q_DISABLE_COPY(QMacStyle)
+
+ QMacStylePrivate *d;
+
+ friend bool qt_mac_buttonIsRenderedFlat(const QPushButton *pushButton, const QStyleOptionButton *option);
+};
+
+#endif // Q_WS_MAC
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QMACSTYLE_H
diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm
new file mode 100644
index 0000000000..86b30cf7e0
--- /dev/null
+++ b/src/widgets/styles/qmacstyle_mac.mm
@@ -0,0 +1,6019 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*
+ Note: The qdoc comments for QMacStyle are contained in
+ .../doc/src/qstyles.qdoc.
+*/
+
+#include "qmacstyle_mac.h"
+
+#if defined(Q_WS_MAC) && !defined(QT_NO_STYLE_MAC)
+#define QMAC_QAQUASTYLE_SIZE_CONSTRAIN
+//#define DEBUG_SIZE_CONSTRAINT
+
+#include <private/qapplication_p.h>
+#include <private/qcombobox_p.h>
+#include <private/qmacstylepixmaps_mac_p.h>
+#include <private/qpaintengine_mac_p.h>
+#include <private/qpainter_p.h>
+#include <private/qprintengine_mac_p.h>
+#include <qapplication.h>
+#include <qbitmap.h>
+#include <qcheckbox.h>
+#include <qcombobox.h>
+#include <qdialogbuttonbox.h>
+#include <qdockwidget.h>
+#include <qevent.h>
+#include <qfocusframe.h>
+#include <qformlayout.h>
+#include <qgroupbox.h>
+#include <qhash.h>
+#include <qheaderview.h>
+#include <qlayout.h>
+#include <qlineedit.h>
+#include <qlistview.h>
+#include <qmainwindow.h>
+#include <qmap.h>
+#include <qmenubar.h>
+#include <qpaintdevice.h>
+#include <qpainter.h>
+#include <qpixmapcache.h>
+#include <qpointer.h>
+#include <qprogressbar.h>
+#include <qpushbutton.h>
+#include <qradiobutton.h>
+#include <qrubberband.h>
+#include <qsizegrip.h>
+#include <qspinbox.h>
+#include <qsplitter.h>
+#include <qstyleoption.h>
+#include <qtextedit.h>
+#include <qtextstream.h>
+#include <qtoolbar.h>
+#include <qtoolbutton.h>
+#include <qtreeview.h>
+#include <qtableview.h>
+#include <qwizard.h>
+#include <qdebug.h>
+#include <qlibrary.h>
+#include <qdatetimeedit.h>
+#include <qmath.h>
+#include <QtGui/qgraphicsproxywidget.h>
+#include <QtGui/qgraphicsview.h>
+#include <private/qt_cocoa_helpers_mac_p.h>
+#include "qmacstyle_mac_p.h"
+#include <private/qstylehelper_p.h>
+
+QT_BEGIN_NAMESPACE
+
+// The following constants are used for adjusting the size
+// of push buttons so that they are drawn inside their bounds.
+const int QMacStylePrivate::PushButtonLeftOffset = 6;
+const int QMacStylePrivate::PushButtonTopOffset = 4;
+const int QMacStylePrivate::PushButtonRightOffset = 12;
+const int QMacStylePrivate::PushButtonBottomOffset = 12;
+const int QMacStylePrivate::MiniButtonH = 26;
+const int QMacStylePrivate::SmallButtonH = 30;
+const int QMacStylePrivate::BevelButtonW = 50;
+const int QMacStylePrivate::BevelButtonH = 22;
+const int QMacStylePrivate::PushButtonContentPadding = 6;
+
+// These colors specify the titlebar gradient colors on
+// Leopard. Ideally we should get them from the system.
+static const QColor titlebarGradientActiveBegin(220, 220, 220);
+static const QColor titlebarGradientActiveEnd(151, 151, 151);
+static const QColor titlebarSeparatorLineActive(111, 111, 111);
+static const QColor titlebarGradientInactiveBegin(241, 241, 241);
+static const QColor titlebarGradientInactiveEnd(207, 207, 207);
+static const QColor titlebarSeparatorLineInactive(131, 131, 131);
+
+// Gradient colors used for the dock widget title bar and
+// non-unifed tool bar bacground.
+static const QColor mainWindowGradientBegin(240, 240, 240);
+static const QColor mainWindowGradientEnd(200, 200, 200);
+
+static const int DisclosureOffset = 4;
+
+// Resolve these at run-time, since the functions was moved in Leopard.
+typedef HIRect * (*PtrHIShapeGetBounds)(HIShapeRef, HIRect *);
+static PtrHIShapeGetBounds ptrHIShapeGetBounds = 0;
+
+static int closeButtonSize = 12;
+
+extern QRegion qt_mac_convert_mac_region(RgnHandle); //qregion_mac.cpp
+
+static bool isVerticalTabs(const QTabBar::Shape shape) {
+ return (shape == QTabBar::RoundedEast
+ || shape == QTabBar::TriangularEast
+ || shape == QTabBar::RoundedWest
+ || shape == QTabBar::TriangularWest);
+}
+
+void drawTabCloseButton(QPainter *p, bool hover, bool active, bool selected)
+{
+ // draw background circle
+ p->setRenderHints(QPainter::Antialiasing);
+ QRect rect(0, 0, closeButtonSize, closeButtonSize);
+ QColor background;
+ if (hover) {
+ background = QColor(124, 124, 124);
+ } else {
+ if (active) {
+ if (selected)
+ background = QColor(104, 104, 104);
+ else
+ background = QColor(83, 83, 83);
+ } else {
+ if (selected)
+ background = QColor(144, 144, 144);
+ else
+ background = QColor(114, 114, 114);
+ }
+ }
+ p->setPen(Qt::transparent);
+ p->setBrush(background);
+ p->drawEllipse(rect);
+
+ // draw cross
+ int min = 3;
+ int max = 9;
+ QPen crossPen;
+ crossPen.setColor(QColor(194, 194, 194));
+ crossPen.setWidthF(1.3);
+ crossPen.setCapStyle(Qt::FlatCap);
+ p->setPen(crossPen);
+ p->drawLine(min, min, max, max);
+ p->drawLine(min, max, max, min);
+}
+
+QRect rotateTabPainter(QPainter *p, QTabBar::Shape shape, QRect tabRect)
+{
+ if (isVerticalTabs(shape)) {
+ int newX, newY, newRot;
+ if (shape == QTabBar::RoundedEast
+ || shape == QTabBar::TriangularEast) {
+ newX = tabRect.width();
+ newY = tabRect.y();
+ newRot = 90;
+ } else {
+ newX = 0;
+ newY = tabRect.y() + tabRect.height();
+ newRot = -90;
+ }
+ tabRect.setRect(0, 0, tabRect.height(), tabRect.width());
+ QMatrix m;
+ m.translate(newX, newY);
+ m.rotate(newRot);
+ p->setMatrix(m, true);
+ }
+ return tabRect;
+}
+
+void drawTabShape(QPainter *p, const QStyleOptionTabV3 *tabOpt)
+{
+ QRect r = tabOpt->rect;
+ p->translate(tabOpt->rect.x(), tabOpt->rect.y());
+ r.moveLeft(0);
+ r.moveTop(0);
+ QRect tabRect = rotateTabPainter(p, tabOpt->shape, r);
+
+ int width = tabRect.width();
+ int height = 20;
+ bool active = (tabOpt->state & QStyle::State_Active);
+ bool selected = (tabOpt->state & QStyle::State_Selected);
+
+ if (selected) {
+ QRect rect(1, 0, width - 2, height);
+
+ // fill body
+ if (active) {
+ int d = (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_6) ? 16 : 0;
+ p->fillRect(rect, QColor(151 + d, 151 + d, 151 + d));
+ } else {
+ int d = (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_6) ? 9 : 0;
+ QLinearGradient gradient(rect.topLeft(), rect.bottomLeft());
+ gradient.setColorAt(0, QColor(207 + d, 207 + d, 207 + d));
+ gradient.setColorAt(0.5, QColor(206 + d, 206 + d, 206 + d));
+ gradient.setColorAt(1, QColor(201 + d, 201 + d, 201 + d));
+ p->fillRect(rect, gradient);
+ }
+
+ // draw border
+ QColor borderSides;
+ QColor borderBottom;
+ if (active) {
+ borderSides = QColor(88, 88, 88);
+ borderBottom = QColor(88, 88, 88);
+ } else {
+ borderSides = QColor(121, 121, 121);
+ borderBottom = QColor(116, 116, 116);
+ }
+
+ p->setPen(borderSides);
+
+ int bottom = height;
+ // left line
+ p->drawLine(0, 1, 0, bottom-2);
+ // right line
+ p->drawLine(width-1, 1, width-1, bottom-2);
+
+ // bottom line
+ if (active) {
+ p->setPen(QColor(168, 168, 168));
+ p->drawLine(3, bottom-1, width-3, bottom-1);
+ }
+ p->setPen(borderBottom);
+ p->drawLine(2, bottom, width-2, bottom);
+
+ int w = 3;
+ QRectF rectangleLeft(1, height - w, w, w);
+ QRectF rectangleRight(width - 2, height - 1, w, w);
+ int startAngle = 180 * 16;
+ int spanAngle = 90 * 16;
+ p->setRenderHint(QPainter::Antialiasing);
+ p->drawArc(rectangleLeft, startAngle, spanAngle);
+ p->drawArc(rectangleRight, startAngle, -spanAngle);
+ } else {
+ // when the mouse is over non selected tabs they get a new color
+ bool hover = (tabOpt->state & QStyle::State_MouseOver);
+ if (hover) {
+ QRect rect(1, 2, width - 1, height - 1);
+ p->fillRect(rect, QColor(110, 110, 110));
+ }
+
+ // seperator lines between tabs
+ bool west = (tabOpt->shape == QTabBar::RoundedWest || tabOpt->shape == QTabBar::TriangularWest);
+ bool drawOnRight = !west;
+ if ((!drawOnRight && tabOpt->selectedPosition != QStyleOptionTab::NextIsSelected)
+ || (drawOnRight && tabOpt->selectedPosition != QStyleOptionTab::NextIsSelected)) {
+ QColor borderColor;
+ QColor borderHighlightColor;
+ if (active) {
+ borderColor = QColor(64, 64, 64);
+ borderHighlightColor = QColor(140, 140, 140);
+ } else {
+ borderColor = QColor(135, 135, 135);
+ borderHighlightColor = QColor(178, 178, 178);
+ }
+
+ int x = drawOnRight ? width : 0;
+
+ // tab seperator line
+ p->setPen(borderColor);
+ p->drawLine(x, 2, x, height + 1);
+
+ // tab seperator highlight
+ p->setPen(borderHighlightColor);
+ p->drawLine(x-1, 2, x-1, height + 1);
+ p->drawLine(x+1, 2, x+1, height + 1);
+ }
+ }
+}
+
+void drawTabBase(QPainter *p, const QStyleOptionTabBarBaseV2 *tbb, const QWidget *w)
+{
+ QRect r = tbb->rect;
+ if (isVerticalTabs(tbb->shape)) {
+ r.setWidth(w->width());
+ } else {
+ r.setHeight(w->height());
+ }
+ QRect tabRect = rotateTabPainter(p, tbb->shape, r);
+ int width = tabRect.width();
+ int height = tabRect.height();
+ bool active = (tbb->state & QStyle::State_Active);
+
+ // top border lines
+ QColor borderHighlightTop;
+ QColor borderTop;
+ if (active) {
+ borderTop = QColor(64, 64, 64);
+ borderHighlightTop = QColor(174, 174, 174);
+ } else {
+ borderTop = QColor(135, 135, 135);
+ borderHighlightTop = QColor(207, 207, 207);
+ }
+ p->setPen(borderHighlightTop);
+ p->drawLine(tabRect.x(), 0, width, 0);
+ p->setPen(borderTop);
+ p->drawLine(tabRect.x(), 1, width, 1);
+
+ // center block
+ QRect centralRect(tabRect.x(), 2, width, height - 2);
+ if (active) {
+ QColor mainColor = QColor(120, 120, 120);
+ p->fillRect(centralRect, mainColor);
+ } else {
+ QLinearGradient gradient(centralRect.topLeft(), centralRect.bottomLeft());
+ gradient.setColorAt(0, QColor(165, 165, 165));
+ gradient.setColorAt(0.5, QColor(164, 164, 164));
+ gradient.setColorAt(1, QColor(158, 158, 158));
+ p->fillRect(centralRect, gradient);
+ }
+
+ // bottom border lines
+ QColor borderHighlightBottom;
+ QColor borderBottom;
+ if (active) {
+ borderHighlightBottom = QColor(153, 153, 153);
+ borderBottom = QColor(64, 64, 64);
+ } else {
+ borderHighlightBottom = QColor(177, 177, 177);
+ borderBottom = QColor(127, 127, 127);
+ }
+ p->setPen(borderHighlightBottom);
+ p->drawLine(tabRect.x(), height - 2, width, height - 2);
+ p->setPen(borderBottom);
+ p->drawLine(tabRect.x(), height - 1, width, height - 1);
+}
+
+static int getControlSize(const QStyleOption *option, const QWidget *widget)
+{
+ if (option) {
+ if (option->state & (QStyle::State_Small | QStyle::State_Mini))
+ return (option->state & QStyle::State_Mini) ? QAquaSizeMini : QAquaSizeSmall;
+ } else if (widget) {
+ switch (QMacStyle::widgetSizePolicy(widget)) {
+ case QMacStyle::SizeSmall:
+ return QAquaSizeSmall;
+ case QMacStyle::SizeMini:
+ return QAquaSizeMini;
+ default:
+ break;
+ }
+ }
+ return QAquaSizeLarge;
+}
+
+
+static inline bool isTreeView(const QWidget *widget)
+{
+ return (widget && widget->parentWidget() &&
+ (qobject_cast<const QTreeView *>(widget->parentWidget())
+#ifdef QT3_SUPPORT
+ || widget->parentWidget()->inherits("Q3ListView")
+#endif
+ ));
+}
+
+static inline ThemeTabDirection getTabDirection(QTabBar::Shape shape)
+{
+ ThemeTabDirection ttd;
+ switch (shape) {
+ case QTabBar::RoundedSouth:
+ case QTabBar::TriangularSouth:
+ ttd = kThemeTabSouth;
+ break;
+ default: // Added to remove the warning, since all values are taken care of, really!
+ case QTabBar::RoundedNorth:
+ case QTabBar::TriangularNorth:
+ ttd = kThemeTabNorth;
+ break;
+ case QTabBar::RoundedWest:
+ case QTabBar::TriangularWest:
+ ttd = kThemeTabWest;
+ break;
+ case QTabBar::RoundedEast:
+ case QTabBar::TriangularEast:
+ ttd = kThemeTabEast;
+ break;
+ }
+ return ttd;
+}
+
+QT_BEGIN_INCLUDE_NAMESPACE
+#include "moc_qmacstyle_mac.cpp"
+#include "moc_qmacstyle_mac_p.cpp"
+QT_END_INCLUDE_NAMESPACE
+
+/*****************************************************************************
+ External functions
+ *****************************************************************************/
+extern CGContextRef qt_mac_cg_context(const QPaintDevice *); //qpaintdevice_mac.cpp
+extern QRegion qt_mac_convert_mac_region(HIShapeRef); //qregion_mac.cpp
+void qt_mac_dispose_rgn(RgnHandle r); //qregion_mac.cpp
+extern QPaintDevice *qt_mac_safe_pdev; //qapplication_mac.cpp
+
+/*****************************************************************************
+ QMacCGStyle globals
+ *****************************************************************************/
+const int qt_mac_hitheme_version = 0; //the HITheme version we speak
+const int macItemFrame = 2; // menu item frame width
+const int macItemHMargin = 3; // menu item hor text margin
+const int macItemVMargin = 2; // menu item ver text margin
+const int macRightBorder = 12; // right border on mac
+const ThemeWindowType QtWinType = kThemeDocumentWindow; // Window type we use for QTitleBar.
+QPixmap *qt_mac_backgroundPattern = 0; // stores the standard widget background.
+
+/*****************************************************************************
+ QMacCGStyle utility functions
+ *****************************************************************************/
+static inline int qt_mac_hitheme_tab_version()
+{
+ return 1;
+}
+
+static inline HIRect qt_hirectForQRect(const QRect &convertRect, const QRect &rect = QRect())
+{
+ return CGRectMake(convertRect.x() + rect.x(), convertRect.y() + rect.y(),
+ convertRect.width() - rect.width(), convertRect.height() - rect.height());
+}
+
+static inline const QRect qt_qrectForHIRect(const HIRect &hirect)
+{
+ return QRect(QPoint(int(hirect.origin.x), int(hirect.origin.y)),
+ QSize(int(hirect.size.width), int(hirect.size.height)));
+}
+
+inline bool qt_mac_is_metal(const QWidget *w)
+{
+ for (; w; w = w->parentWidget()) {
+ if (w->testAttribute(Qt::WA_MacBrushedMetal))
+ return true;
+ if (w->isWindow() && w->testAttribute(Qt::WA_WState_Created)) { // If not created will fall through to the opaque check and be fine anyway.
+ return macWindowIsTextured(qt_mac_window_for(w));
+ }
+ if (w->d_func()->isOpaque)
+ break;
+ }
+ return false;
+}
+
+static int qt_mac_aqua_get_metric(ThemeMetric met)
+{
+ SInt32 ret;
+ GetThemeMetric(met, &ret);
+ return ret;
+}
+
+static QSize qt_aqua_get_known_size(QStyle::ContentsType ct, const QWidget *widg, QSize szHint,
+ QAquaWidgetSize sz)
+{
+ QSize ret(-1, -1);
+ if (sz != QAquaSizeSmall && sz != QAquaSizeLarge && sz != QAquaSizeMini) {
+ qDebug("Not sure how to return this...");
+ return ret;
+ }
+ if ((widg && widg->testAttribute(Qt::WA_SetFont)) || !QApplication::desktopSettingsAware()) {
+ // If you're using a custom font and it's bigger than the default font,
+ // then no constraints for you. If you are smaller, we can try to help you out
+ QFont font = qt_app_fonts_hash()->value(widg->metaObject()->className(), QFont());
+ if (widg->font().pointSize() > font.pointSize())
+ return ret;
+ }
+
+ if (ct == QStyle::CT_CustomBase && widg) {
+ if (qobject_cast<const QPushButton *>(widg))
+ ct = QStyle::CT_PushButton;
+ else if (qobject_cast<const QRadioButton *>(widg))
+ ct = QStyle::CT_RadioButton;
+ else if (qobject_cast<const QCheckBox *>(widg))
+ ct = QStyle::CT_CheckBox;
+ else if (qobject_cast<const QComboBox *>(widg))
+ ct = QStyle::CT_ComboBox;
+ else if (qobject_cast<const QToolButton *>(widg))
+ ct = QStyle::CT_ToolButton;
+ else if (qobject_cast<const QSlider *>(widg))
+ ct = QStyle::CT_Slider;
+ else if (qobject_cast<const QProgressBar *>(widg))
+ ct = QStyle::CT_ProgressBar;
+ else if (qobject_cast<const QLineEdit *>(widg))
+ ct = QStyle::CT_LineEdit;
+ else if (qobject_cast<const QHeaderView *>(widg)
+#ifdef QT3_SUPPORT
+ || widg->inherits("Q3Header")
+#endif
+ )
+ ct = QStyle::CT_HeaderSection;
+ else if (qobject_cast<const QMenuBar *>(widg)
+#ifdef QT3_SUPPORT
+ || widg->inherits("Q3MenuBar")
+#endif
+ )
+ ct = QStyle::CT_MenuBar;
+ else if (qobject_cast<const QSizeGrip *>(widg))
+ ct = QStyle::CT_SizeGrip;
+ else
+ return ret;
+ }
+
+ switch (ct) {
+ case QStyle::CT_PushButton: {
+ const QPushButton *psh = qobject_cast<const QPushButton *>(widg);
+ // If this comparison is false, then the widget was not a push button.
+ // This is bad and there's very little we can do since we were requested to find a
+ // sensible size for a widget that pretends to be a QPushButton but is not.
+ if(psh) {
+ QString buttonText = qt_mac_removeMnemonics(psh->text());
+ if (buttonText.contains(QLatin1Char('\n')))
+ ret = QSize(-1, -1);
+ else if (sz == QAquaSizeLarge)
+ ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricPushButtonHeight));
+ else if (sz == QAquaSizeSmall)
+ ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricSmallPushButtonHeight));
+ else if (sz == QAquaSizeMini)
+ ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricMiniPushButtonHeight));
+
+ if (!psh->icon().isNull()){
+ // If the button got an icon, and the icon is larger than the
+ // button, we can't decide on a default size
+ ret.setWidth(-1);
+ if (ret.height() < psh->iconSize().height())
+ ret.setHeight(-1);
+ }
+ else if (buttonText == QLatin1String("OK") || buttonText == QLatin1String("Cancel")){
+ // Aqua Style guidelines restrict the size of OK and Cancel buttons to 68 pixels.
+ // However, this doesn't work for German, therefore only do it for English,
+ // I suppose it would be better to do some sort of lookups for languages
+ // that like to have really long words.
+ ret.setWidth(77 - 8);
+ }
+ } else {
+ // The only sensible thing to do is to return whatever the style suggests...
+ if (sz == QAquaSizeLarge)
+ ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricPushButtonHeight));
+ else if (sz == QAquaSizeSmall)
+ ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricSmallPushButtonHeight));
+ else if (sz == QAquaSizeMini)
+ ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricMiniPushButtonHeight));
+ else
+ // Since there's no default size we return the large size...
+ ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricPushButtonHeight));
+ }
+#if 0 //Not sure we are applying the rules correctly for RadioButtons/CheckBoxes --Sam
+ } else if (ct == QStyle::CT_RadioButton) {
+ QRadioButton *rdo = static_cast<QRadioButton *>(widg);
+ // Exception for case where multiline radio button text requires no size constrainment
+ if (rdo->text().find('\n') != -1)
+ return ret;
+ if (sz == QAquaSizeLarge)
+ ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricRadioButtonHeight));
+ else if (sz == QAquaSizeSmall)
+ ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricSmallRadioButtonHeight));
+ else if (sz == QAquaSizeMini)
+ ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricMiniRadioButtonHeight));
+ } else if (ct == QStyle::CT_CheckBox) {
+ if (sz == QAquaSizeLarge)
+ ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricCheckBoxHeight));
+ else if (sz == QAquaSizeSmall)
+ ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricSmallCheckBoxHeight));
+ else if (sz == QAquaSizeMini)
+ ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricMiniCheckBoxHeight));
+#endif
+ break;
+ }
+ case QStyle::CT_SizeGrip:
+ if (sz == QAquaSizeLarge || sz == QAquaSizeSmall) {
+ HIRect r;
+ HIPoint p = { 0, 0 };
+ HIThemeGrowBoxDrawInfo gbi;
+ gbi.version = 0;
+ gbi.state = kThemeStateActive;
+ gbi.kind = kHIThemeGrowBoxKindNormal;
+ gbi.direction = QApplication::isRightToLeft() ? kThemeGrowLeft | kThemeGrowDown
+ : kThemeGrowRight | kThemeGrowDown;
+ gbi.size = sz == QAquaSizeSmall ? kHIThemeGrowBoxSizeSmall : kHIThemeGrowBoxSizeNormal;
+ if (HIThemeGetGrowBoxBounds(&p, &gbi, &r) == noErr)
+ ret = QSize(r.size.width, r.size.height);
+ }
+ break;
+ case QStyle::CT_ComboBox:
+ switch (sz) {
+ case QAquaSizeLarge:
+ ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricPopupButtonHeight));
+ break;
+ case QAquaSizeSmall:
+ ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricSmallPopupButtonHeight));
+ break;
+ case QAquaSizeMini:
+ ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricMiniPopupButtonHeight));
+ break;
+ default:
+ break;
+ }
+ break;
+ case QStyle::CT_ToolButton:
+ if (sz == QAquaSizeSmall) {
+ int width = 0, height = 0;
+ if (szHint == QSize(-1, -1)) { //just 'guess'..
+ const QToolButton *bt = qobject_cast<const QToolButton *>(widg);
+ // If this conversion fails then the widget was not what it claimed to be.
+ if(bt) {
+ if (!bt->icon().isNull()) {
+ QSize iconSize = bt->iconSize();
+ QSize pmSize = bt->icon().actualSize(QSize(32, 32), QIcon::Normal);
+ width = qMax(width, qMax(iconSize.width(), pmSize.width()));
+ height = qMax(height, qMax(iconSize.height(), pmSize.height()));
+ }
+ if (!bt->text().isNull() && bt->toolButtonStyle() != Qt::ToolButtonIconOnly) {
+ int text_width = bt->fontMetrics().width(bt->text()),
+ text_height = bt->fontMetrics().height();
+ if (bt->toolButtonStyle() == Qt::ToolButtonTextUnderIcon) {
+ width = qMax(width, text_width);
+ height += text_height;
+ } else {
+ width += text_width;
+ width = qMax(height, text_height);
+ }
+ }
+ } else {
+ // Let's return the size hint...
+ width = szHint.width();
+ height = szHint.height();
+ }
+ } else {
+ width = szHint.width();
+ height = szHint.height();
+ }
+ width = qMax(20, width + 5); //border
+ height = qMax(20, height + 5); //border
+ ret = QSize(width, height);
+ }
+ break;
+ case QStyle::CT_Slider: {
+ int w = -1;
+ const QSlider *sld = qobject_cast<const QSlider *>(widg);
+ // If this conversion fails then the widget was not what it claimed to be.
+ if(sld) {
+ if (sz == QAquaSizeLarge) {
+ if (sld->orientation() == Qt::Horizontal) {
+ w = qt_mac_aqua_get_metric(kThemeMetricHSliderHeight);
+ if (sld->tickPosition() != QSlider::NoTicks)
+ w += qt_mac_aqua_get_metric(kThemeMetricHSliderTickHeight);
+ } else {
+ w = qt_mac_aqua_get_metric(kThemeMetricVSliderWidth);
+ if (sld->tickPosition() != QSlider::NoTicks)
+ w += qt_mac_aqua_get_metric(kThemeMetricVSliderTickWidth);
+ }
+ } else if (sz == QAquaSizeSmall) {
+ if (sld->orientation() == Qt::Horizontal) {
+ w = qt_mac_aqua_get_metric(kThemeMetricSmallHSliderHeight);
+ if (sld->tickPosition() != QSlider::NoTicks)
+ w += qt_mac_aqua_get_metric(kThemeMetricSmallHSliderTickHeight);
+ } else {
+ w = qt_mac_aqua_get_metric(kThemeMetricSmallVSliderWidth);
+ if (sld->tickPosition() != QSlider::NoTicks)
+ w += qt_mac_aqua_get_metric(kThemeMetricSmallVSliderTickWidth);
+ }
+ } else if (sz == QAquaSizeMini) {
+ if (sld->orientation() == Qt::Horizontal) {
+ w = qt_mac_aqua_get_metric(kThemeMetricMiniHSliderHeight);
+ if (sld->tickPosition() != QSlider::NoTicks)
+ w += qt_mac_aqua_get_metric(kThemeMetricMiniHSliderTickHeight);
+ } else {
+ w = qt_mac_aqua_get_metric(kThemeMetricMiniVSliderWidth);
+ if (sld->tickPosition() != QSlider::NoTicks)
+ w += qt_mac_aqua_get_metric(kThemeMetricMiniVSliderTickWidth);
+ }
+ }
+ } else {
+ // This is tricky, we were requested to find a size for a slider which is not
+ // a slider. We don't know if this is vertical or horizontal or if we need to
+ // have tick marks or not.
+ // For this case we will return an horizontal slider without tick marks.
+ w = qt_mac_aqua_get_metric(kThemeMetricHSliderHeight);
+ w += qt_mac_aqua_get_metric(kThemeMetricHSliderTickHeight);
+ }
+ if (sld->orientation() == Qt::Horizontal)
+ ret.setHeight(w);
+ else
+ ret.setWidth(w);
+ break;
+ }
+ case QStyle::CT_ProgressBar: {
+ int finalValue = -1;
+ Qt::Orientation orient = Qt::Horizontal;
+ if (const QProgressBar *pb = qobject_cast<const QProgressBar *>(widg))
+ orient = pb->orientation();
+
+ if (sz == QAquaSizeLarge)
+ finalValue = qt_mac_aqua_get_metric(kThemeMetricLargeProgressBarThickness)
+ + qt_mac_aqua_get_metric(kThemeMetricProgressBarShadowOutset);
+ else
+ finalValue = qt_mac_aqua_get_metric(kThemeMetricNormalProgressBarThickness)
+ + qt_mac_aqua_get_metric(kThemeMetricSmallProgressBarShadowOutset);
+ if (orient == Qt::Horizontal)
+ ret.setHeight(finalValue);
+ else
+ ret.setWidth(finalValue);
+ break;
+ }
+ case QStyle::CT_LineEdit:
+ if (!widg || !qobject_cast<QComboBox *>(widg->parentWidget())) {
+ //should I take into account the font dimentions of the lineedit? -Sam
+ if (sz == QAquaSizeLarge)
+ ret = QSize(-1, 22);
+ else
+ ret = QSize(-1, 19);
+ }
+ break;
+ case QStyle::CT_HeaderSection:
+ if (isTreeView(widg))
+ ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricListHeaderHeight));
+ break;
+ case QStyle::CT_MenuBar:
+ if (sz == QAquaSizeLarge) {
+#ifndef QT_MAC_USE_COCOA
+ SInt16 size;
+ if (!GetThemeMenuBarHeight(&size))
+ ret = QSize(-1, size);
+#else
+ ret = QSize(-1, [[NSApp mainMenu] menuBarHeight]);
+ // In the qt_mac_set_native_menubar(false) case,
+ // we come it here with a zero-height main menu,
+ // preventing the in-window menu from displaying.
+ // Use 22 pixels for the height, by observation.
+ if (ret.height() <= 0)
+ ret.setHeight(22);
+#endif
+ }
+ break;
+ default:
+ break;
+ }
+ return ret;
+}
+
+
+#if defined(QMAC_QAQUASTYLE_SIZE_CONSTRAIN) || defined(DEBUG_SIZE_CONSTRAINT)
+static QAquaWidgetSize qt_aqua_guess_size(const QWidget *widg, QSize large, QSize small, QSize mini)
+{
+ if (large == QSize(-1, -1)) {
+ if (small != QSize(-1, -1))
+ return QAquaSizeSmall;
+ if (mini != QSize(-1, -1))
+ return QAquaSizeMini;
+ return QAquaSizeUnknown;
+ } else if (small == QSize(-1, -1)) {
+ if (mini != QSize(-1, -1))
+ return QAquaSizeMini;
+ return QAquaSizeLarge;
+ } else if (mini == QSize(-1, -1)) {
+ return QAquaSizeLarge;
+ }
+
+#ifndef QT_NO_MAINWINDOW
+ if (qobject_cast<QDockWidget *>(widg->window()) || !qgetenv("QWIDGET_ALL_SMALL").isNull()) {
+ //if (small.width() != -1 || small.height() != -1)
+ return QAquaSizeSmall;
+ } else if (!qgetenv("QWIDGET_ALL_MINI").isNull()) {
+ return QAquaSizeMini;
+ }
+#endif
+
+#if 0
+ /* Figure out which size we're closer to, I just hacked this in, I haven't
+ tested it as it would probably look pretty strange to have some widgets
+ big and some widgets small in the same window?? -Sam */
+ int large_delta=0;
+ if (large.width() != -1) {
+ int delta = large.width() - widg->width();
+ large_delta += delta * delta;
+ }
+ if (large.height() != -1) {
+ int delta = large.height() - widg->height();
+ large_delta += delta * delta;
+ }
+ int small_delta=0;
+ if (small.width() != -1) {
+ int delta = small.width() - widg->width();
+ small_delta += delta * delta;
+ }
+ if (small.height() != -1) {
+ int delta = small.height() - widg->height();
+ small_delta += delta * delta;
+ }
+ int mini_delta=0;
+ if (mini.width() != -1) {
+ int delta = mini.width() - widg->width();
+ mini_delta += delta * delta;
+ }
+ if (mini.height() != -1) {
+ int delta = mini.height() - widg->height();
+ mini_delta += delta * delta;
+ }
+ if (mini_delta < small_delta && mini_delta < large_delta)
+ return QAquaSizeMini;
+ else if (small_delta < large_delta)
+ return QAquaSizeSmall;
+#endif
+ return QAquaSizeLarge;
+}
+#endif
+
+QAquaWidgetSize QMacStylePrivate::aquaSizeConstrain(const QStyleOption *option, const QWidget *widg,
+ QStyle::ContentsType ct, QSize szHint, QSize *insz) const
+{
+#if defined(QMAC_QAQUASTYLE_SIZE_CONSTRAIN) || defined(DEBUG_SIZE_CONSTRAINT)
+ if (option) {
+ if (option->state & QStyle::State_Small)
+ return QAquaSizeSmall;
+ if (option->state & QStyle::State_Mini)
+ return QAquaSizeMini;
+ }
+
+ if (!widg) {
+ if (insz)
+ *insz = QSize();
+ if (!qgetenv("QWIDGET_ALL_SMALL").isNull())
+ return QAquaSizeSmall;
+ if (!qgetenv("QWIDGET_ALL_MINI").isNull())
+ return QAquaSizeMini;
+ return QAquaSizeUnknown;
+ }
+ QSize large = qt_aqua_get_known_size(ct, widg, szHint, QAquaSizeLarge),
+ small = qt_aqua_get_known_size(ct, widg, szHint, QAquaSizeSmall),
+ mini = qt_aqua_get_known_size(ct, widg, szHint, QAquaSizeMini);
+ bool guess_size = false;
+ QAquaWidgetSize ret = QAquaSizeUnknown;
+ QMacStyle::WidgetSizePolicy wsp = q->widgetSizePolicy(widg);
+ if (wsp == QMacStyle::SizeDefault)
+ guess_size = true;
+ else if (wsp == QMacStyle::SizeMini)
+ ret = QAquaSizeMini;
+ else if (wsp == QMacStyle::SizeSmall)
+ ret = QAquaSizeSmall;
+ else if (wsp == QMacStyle::SizeLarge)
+ ret = QAquaSizeLarge;
+ if (guess_size)
+ ret = qt_aqua_guess_size(widg, large, small, mini);
+
+ QSize *sz = 0;
+ if (ret == QAquaSizeSmall)
+ sz = &small;
+ else if (ret == QAquaSizeLarge)
+ sz = &large;
+ else if (ret == QAquaSizeMini)
+ sz = &mini;
+ if (insz)
+ *insz = sz ? *sz : QSize(-1, -1);
+#ifdef DEBUG_SIZE_CONSTRAINT
+ if (sz) {
+ const char *size_desc = "Unknown";
+ if (sz == &small)
+ size_desc = "Small";
+ else if (sz == &large)
+ size_desc = "Large";
+ else if (sz == &mini)
+ size_desc = "Mini";
+ qDebug("%s - %s: %s taken (%d, %d) [%d, %d]",
+ widg ? widg->objectName().toLatin1().constData() : "*Unknown*",
+ widg ? widg->metaObject()->className() : "*Unknown*", size_desc, widg->width(), widg->height(),
+ sz->width(), sz->height());
+ }
+#endif
+ return ret;
+#else
+ if (insz)
+ *insz = QSize();
+ Q_UNUSED(widg);
+ Q_UNUSED(ct);
+ Q_UNUSED(szHint);
+ return QAquaSizeUnknown;
+#endif
+}
+
+/**
+ Returns the free space awailable for contents inside the
+ button (and not the size of the contents itself)
+*/
+HIRect QMacStylePrivate::pushButtonContentBounds(const QStyleOptionButton *btn,
+ const HIThemeButtonDrawInfo *bdi) const
+{
+ HIRect outerBounds = qt_hirectForQRect(btn->rect);
+ // Adjust the bounds to correct for
+ // carbon not calculating the content bounds fully correct
+ if (bdi->kind == kThemePushButton || bdi->kind == kThemePushButtonSmall){
+ outerBounds.origin.y += QMacStylePrivate::PushButtonTopOffset;
+ outerBounds.size.height -= QMacStylePrivate::PushButtonBottomOffset;
+ } else if (bdi->kind == kThemePushButtonMini) {
+ outerBounds.origin.y += QMacStylePrivate::PushButtonTopOffset;
+ }
+
+ HIRect contentBounds;
+ HIThemeGetButtonContentBounds(&outerBounds, bdi, &contentBounds);
+ return contentBounds;
+}
+
+/**
+ Calculates the size of the button contents.
+ This includes both the text and the icon.
+*/
+QSize QMacStylePrivate::pushButtonSizeFromContents(const QStyleOptionButton *btn) const
+{
+ QSize csz(0, 0);
+ QSize iconSize = btn->icon.isNull() ? QSize(0, 0)
+ : (btn->iconSize + QSize(QMacStylePrivate::PushButtonContentPadding, 0));
+ QRect textRect = btn->text.isEmpty() ? QRect(0, 0, 1, 1)
+ : btn->fontMetrics.boundingRect(QRect(), Qt::AlignCenter, btn->text);
+ csz.setWidth(iconSize.width() + textRect.width()
+ + ((btn->features & QStyleOptionButton::HasMenu)
+ ? q->proxy()->pixelMetric(QStyle::PM_MenuButtonIndicator, btn, 0) : 0));
+ csz.setHeight(qMax(iconSize.height(), textRect.height()));
+ return csz;
+}
+
+/**
+ Checks if the actual contents of btn fits inside the free content bounds of
+ 'buttonKindToCheck'. Meant as a helper function for 'initHIThemePushButton'
+ for determining which button kind to use for drawing.
+*/
+bool QMacStylePrivate::contentFitsInPushButton(const QStyleOptionButton *btn,
+ HIThemeButtonDrawInfo *bdi,
+ ThemeButtonKind buttonKindToCheck) const
+{
+ ThemeButtonKind tmp = bdi->kind;
+ bdi->kind = buttonKindToCheck;
+ QSize contentSize = pushButtonSizeFromContents(btn);
+ QRect freeContentRect = qt_qrectForHIRect(pushButtonContentBounds(btn, bdi));
+ bdi->kind = tmp;
+ return freeContentRect.contains(QRect(freeContentRect.x(), freeContentRect.y(),
+ contentSize.width(), contentSize.height()));
+}
+
+/**
+ Creates a HIThemeButtonDrawInfo structure that specifies the correct button
+ kind and other details to use for drawing the given push button. Which
+ button kind depends on the size of the button, the size of the contents,
+ explicit user style settings, etc.
+*/
+void QMacStylePrivate::initHIThemePushButton(const QStyleOptionButton *btn,
+ const QWidget *widget,
+ const ThemeDrawState tds,
+ HIThemeButtonDrawInfo *bdi) const
+{
+ bool drawColorless = btn->palette.currentColorGroup() == QPalette::Active;
+ ThemeDrawState tdsModified = tds;
+ if (btn->state & QStyle::State_On)
+ tdsModified = kThemeStatePressed;
+ bdi->version = qt_mac_hitheme_version;
+ bdi->state = tdsModified;
+ bdi->value = kThemeButtonOff;
+
+ if (drawColorless && tdsModified == kThemeStateInactive)
+ bdi->state = kThemeStateActive;
+ if (btn->state & QStyle::State_HasFocus)
+ bdi->adornment = kThemeAdornmentFocus;
+ else
+ bdi->adornment = kThemeAdornmentNone;
+
+
+ if (btn->features & (QStyleOptionButton::Flat)) {
+ bdi->kind = kThemeBevelButton;
+ } else {
+ switch (aquaSizeConstrain(btn, widget)) {
+ case QAquaSizeSmall:
+ bdi->kind = kThemePushButtonSmall;
+ break;
+ case QAquaSizeMini:
+ bdi->kind = kThemePushButtonMini;
+ break;
+ case QAquaSizeLarge:
+ // ... We should honor if the user is explicit about using the
+ // large button. But right now Qt will specify the large button
+ // as default rather than QAquaSizeUnknown.
+ // So we treat it like QAquaSizeUnknown
+ // to get the dynamic choosing of button kind.
+ case QAquaSizeUnknown:
+ // Choose the button kind that closest match the button rect, but at the
+ // same time displays the button contents without clipping.
+ bdi->kind = kThemeBevelButton;
+ if (btn->rect.width() >= QMacStylePrivate::BevelButtonW && btn->rect.height() >= QMacStylePrivate::BevelButtonH){
+ if (widget && widget->testAttribute(Qt::WA_MacVariableSize)) {
+ if (btn->rect.height() <= QMacStylePrivate::MiniButtonH){
+ if (contentFitsInPushButton(btn, bdi, kThemePushButtonMini))
+ bdi->kind = kThemePushButtonMini;
+ } else if (btn->rect.height() <= QMacStylePrivate::SmallButtonH){
+ if (contentFitsInPushButton(btn, bdi, kThemePushButtonSmall))
+ bdi->kind = kThemePushButtonSmall;
+ } else if (contentFitsInPushButton(btn, bdi, kThemePushButton)) {
+ bdi->kind = kThemePushButton;
+ }
+ } else {
+ bdi->kind = kThemePushButton;
+ }
+ }
+ }
+ }
+}
+
+bool qt_mac_buttonIsRenderedFlat(const QPushButton *pushButton, const QStyleOptionButton *option)
+{
+ QMacStyle *macStyle = qobject_cast<QMacStyle *>(pushButton->style());
+ if (!macStyle)
+ return false;
+ HIThemeButtonDrawInfo bdi;
+ macStyle->d->initHIThemePushButton(option, pushButton, kThemeStateActive, &bdi);
+ return bdi.kind == kThemeBevelButton;
+}
+
+/**
+ Creates a HIThemeButtonDrawInfo structure that specifies the correct button
+ kind and other details to use for drawing the given combobox. Which button
+ kind depends on the size of the combo, wether or not it is editable,
+ explicit user style settings, etc.
+*/
+void QMacStylePrivate::initComboboxBdi(const QStyleOptionComboBox *combo, HIThemeButtonDrawInfo *bdi,
+ const QWidget *widget, const ThemeDrawState &tds)
+{
+ bdi->version = qt_mac_hitheme_version;
+ bdi->adornment = kThemeAdornmentArrowLeftArrow;
+ bdi->value = kThemeButtonOff;
+ if (combo->state & QStyle::State_HasFocus)
+ bdi->adornment = kThemeAdornmentFocus;
+ bool drawColorless = combo->palette.currentColorGroup() == QPalette::Active && tds == kThemeStateInactive;
+ if (combo->activeSubControls & QStyle::SC_ComboBoxArrow)
+ bdi->state = kThemeStatePressed;
+ else if (drawColorless)
+ bdi->state = kThemeStateActive;
+ else
+ bdi->state = tds;
+
+ QAquaWidgetSize aSize = aquaSizeConstrain(combo, widget);
+ switch (aSize) {
+ case QAquaSizeMini:
+ bdi->kind = combo->editable ? ThemeButtonKind(kThemeComboBoxMini)
+ : ThemeButtonKind(kThemePopupButtonMini);
+ break;
+ case QAquaSizeSmall:
+ bdi->kind = combo->editable ? ThemeButtonKind(kThemeComboBoxSmall)
+ : ThemeButtonKind(kThemePopupButtonSmall);
+ break;
+ case QAquaSizeUnknown:
+ case QAquaSizeLarge:
+ // Unless the user explicitly specified large buttons, determine the
+ // kind by looking at the combox size.
+ // ... specifying small and mini-buttons it not a current feature of
+ // Qt (e.g. QWidget::getAttribute(WA_ButtonSize)). But when it is, add
+ // an extra check here before using the mini and small buttons.
+ int h = combo->rect.size().height();
+ if (combo->editable){
+ if (h < 21)
+ bdi->kind = kThemeComboBoxMini;
+ else if (h < 26)
+ bdi->kind = kThemeComboBoxSmall;
+ else
+ bdi->kind = kThemeComboBox;
+ } else {
+ // Even if we specify that we want the kThemePopupButton, Carbon
+ // will use the kThemePopupButtonSmall if the size matches. So we
+ // do the same size check explicit to have the size of the inner
+ // text field be correct. Therefore, do this even if the user specifies
+ // the use of LargeButtons explicit.
+ if (h < 21)
+ bdi->kind = kThemePopupButtonMini;
+ else if (h < 26)
+ bdi->kind = kThemePopupButtonSmall;
+ else
+ bdi->kind = kThemePopupButton;
+ }
+ break;
+ }
+}
+
+/**
+ Carbon draws comboboxes (and other views) outside the rect given as argument. Use this function to obtain
+ the corresponding inner rect for drawing the same combobox so that it stays inside the given outerBounds.
+*/
+HIRect QMacStylePrivate::comboboxInnerBounds(const HIRect &outerBounds, int buttonKind)
+{
+ HIRect innerBounds = outerBounds;
+ // Carbon draw parts of the view outside the rect.
+ // So make the rect a bit smaller to compensate
+ // (I wish HIThemeGetButtonBackgroundBounds worked)
+ switch (buttonKind){
+ case kThemePopupButton:
+ innerBounds.origin.x += 2;
+ innerBounds.origin.y += 3;
+ innerBounds.size.width -= 5;
+ innerBounds.size.height -= 6;
+ break;
+ case kThemePopupButtonSmall:
+ innerBounds.origin.x += 3;
+ innerBounds.origin.y += 3;
+ innerBounds.size.width -= 6;
+ innerBounds.size.height -= 7;
+ break;
+ case kThemePopupButtonMini:
+ innerBounds.origin.x += 2;
+ innerBounds.origin.y += 2;
+ innerBounds.size.width -= 5;
+ innerBounds.size.height -= 6;
+ break;
+ case kThemeComboBox:
+ innerBounds.origin.x += 3;
+ innerBounds.origin.y += 3;
+ innerBounds.size.width -= 6;
+ innerBounds.size.height -= 6;
+ break;
+ case kThemeComboBoxSmall:
+ innerBounds.origin.x += 3;
+ innerBounds.origin.y += 3;
+ innerBounds.size.width -= 7;
+ innerBounds.size.height -= 8;
+ break;
+ case kThemeComboBoxMini:
+ innerBounds.origin.x += 3;
+ innerBounds.origin.y += 3;
+ innerBounds.size.width -= 4;
+ innerBounds.size.height -= 8;
+ break;
+ default:
+ break;
+ }
+ return innerBounds;
+}
+
+/**
+ Inside a combobox Qt places a line edit widget. The size of this widget should depend on the kind
+ of combobox we choose to draw. This function calculates and returns this size.
+*/
+QRect QMacStylePrivate::comboboxEditBounds(const QRect &outerBounds, const HIThemeButtonDrawInfo &bdi)
+{
+ QRect ret = outerBounds;
+ switch (bdi.kind){
+ case kThemeComboBox:
+ ret.adjust(5, 8, -21, -4);
+ break;
+ case kThemeComboBoxSmall:
+ ret.adjust(4, 5, -18, 0);
+ ret.setHeight(16);
+ break;
+ case kThemeComboBoxMini:
+ ret.adjust(4, 5, -16, 0);
+ ret.setHeight(13);
+ break;
+ case kThemePopupButton:
+ ret.adjust(10, 3, -23, -3);
+ break;
+ case kThemePopupButtonSmall:
+ ret.adjust(9, 3, -20, -3);
+ break;
+ case kThemePopupButtonMini:
+ ret.adjust(8, 3, -19, 0);
+ ret.setHeight(13);
+ break;
+ }
+ return ret;
+}
+
+/**
+ Carbon comboboxes don't scale (sight). If the size of the combo suggest a scaled version,
+ create it manually by drawing a small Carbon combo onto a pixmap (use pixmap cache), chop
+ it up, and copy it back onto the widget. Othervise, draw the combobox supplied by Carbon directly.
+*/
+void QMacStylePrivate::drawCombobox(const HIRect &outerBounds, const HIThemeButtonDrawInfo &bdi, QPainter *p)
+{
+ if (!(bdi.kind == kThemeComboBox && outerBounds.size.height > 28)){
+ // We have an unscaled combobox, or popup-button; use Carbon directly.
+ HIRect innerBounds = QMacStylePrivate::comboboxInnerBounds(outerBounds, bdi.kind);
+ HIThemeDrawButton(&innerBounds, &bdi, QMacCGContext(p), kHIThemeOrientationNormal, 0);
+ } else {
+ QPixmap buffer;
+ QString key = QString(QLatin1String("$qt_cbox%1-%2")).arg(int(bdi.state)).arg(int(bdi.adornment));
+ if (!QPixmapCache::find(key, buffer)) {
+ HIRect innerBoundsSmallCombo = {{3, 3}, {29, 25}};
+ buffer = QPixmap(35, 28);
+ buffer.fill(Qt::transparent);
+ QPainter buffPainter(&buffer);
+ HIThemeDrawButton(&innerBoundsSmallCombo, &bdi, QMacCGContext(&buffPainter), kHIThemeOrientationNormal, 0);
+ buffPainter.end();
+ QPixmapCache::insert(key, buffer);
+ }
+
+ const int bwidth = 20;
+ const int fwidth = 10;
+ const int fheight = 10;
+ int w = qRound(outerBounds.size.width);
+ int h = qRound(outerBounds.size.height);
+ int bstart = w - bwidth;
+ int blower = fheight + 1;
+ int flower = h - fheight;
+ int sheight = flower - fheight;
+ int center = qRound(outerBounds.size.height + outerBounds.origin.y) / 2;
+
+ // Draw upper and lower gap
+ p->drawPixmap(fwidth, 0, bstart - fwidth, fheight, buffer, fwidth, 0, 1, fheight);
+ p->drawPixmap(fwidth, flower, bstart - fwidth, fheight, buffer, fwidth, buffer.height() - fheight, 1, fheight);
+ // Draw left and right gap. Right gap is drawn top and bottom separatly
+ p->drawPixmap(0, fheight, fwidth, sheight, buffer, 0, fheight, fwidth, 1);
+ p->drawPixmap(bstart, fheight, bwidth, center - fheight, buffer, buffer.width() - bwidth, fheight - 1, bwidth, 1);
+ p->drawPixmap(bstart, center, bwidth, sheight / 2, buffer, buffer.width() - bwidth, fheight + 6, bwidth, 1);
+ // Draw arrow
+ p->drawPixmap(bstart, center - 4, bwidth - 3, 6, buffer, buffer.width() - bwidth, fheight, bwidth - 3, 6);
+ // Draw corners
+ p->drawPixmap(0, 0, fwidth, fheight, buffer, 0, 0, fwidth, fheight);
+ p->drawPixmap(bstart, 0, bwidth, fheight, buffer, buffer.width() - bwidth, 0, bwidth, fheight);
+ p->drawPixmap(0, flower, fwidth, fheight, buffer, 0, buffer.height() - fheight, fwidth, fheight);
+ p->drawPixmap(bstart, h - blower, bwidth, blower, buffer, buffer.width() - bwidth, buffer.height() - blower, bwidth, blower);
+ }
+}
+
+/**
+ Carbon tableheaders don't scale (sight). So create it manually by drawing a small Carbon header
+ onto a pixmap (use pixmap cache), chop it up, and copy it back onto the widget.
+*/
+void QMacStylePrivate::drawTableHeader(const HIRect &outerBounds,
+ bool drawTopBorder, bool drawLeftBorder, const HIThemeButtonDrawInfo &bdi, QPainter *p)
+{
+ static SInt32 headerHeight = 0;
+ static OSStatus err = GetThemeMetric(kThemeMetricListHeaderHeight, &headerHeight);
+ Q_UNUSED(err);
+
+ QPixmap buffer;
+ QString key = QString(QLatin1String("$qt_tableh%1-%2-%3")).arg(int(bdi.state)).arg(int(bdi.adornment)).arg(int(bdi.value));
+ if (!QPixmapCache::find(key, buffer)) {
+ HIRect headerNormalRect = {{0., 0.}, {16., CGFloat(headerHeight)}};
+ buffer = QPixmap(headerNormalRect.size.width, headerNormalRect.size.height);
+ buffer.fill(Qt::transparent);
+ QPainter buffPainter(&buffer);
+ HIThemeDrawButton(&headerNormalRect, &bdi, QMacCGContext(&buffPainter), kHIThemeOrientationNormal, 0);
+ buffPainter.end();
+ QPixmapCache::insert(key, buffer);
+ }
+ const int buttonw = qRound(outerBounds.size.width);
+ const int buttonh = qRound(outerBounds.size.height);
+ const int framew = 1;
+ const int frameh_n = 4;
+ const int frameh_s = 3;
+ const int transh = buffer.height() - frameh_n - frameh_s;
+ int center = buttonh - frameh_s - int(transh / 2.0f) + 1; // Align bottom;
+
+ int skipTopBorder = 0;
+ if (!drawTopBorder)
+ skipTopBorder = 1;
+
+ p->translate(outerBounds.origin.x, outerBounds.origin.y);
+
+ p->drawPixmap(QRect(QRect(0, -skipTopBorder, buttonw - framew , frameh_n)), buffer, QRect(framew, 0, 1, frameh_n));
+ p->drawPixmap(QRect(0, buttonh - frameh_s, buttonw - framew, frameh_s), buffer, QRect(framew, buffer.height() - frameh_s, 1, frameh_s));
+ // Draw upper and lower center blocks
+ p->drawPixmap(QRect(0, frameh_n - skipTopBorder, buttonw - framew, center - frameh_n + skipTopBorder), buffer, QRect(framew, frameh_n, 1, 1));
+ p->drawPixmap(QRect(0, center, buttonw - framew, buttonh - center - frameh_s), buffer, QRect(framew, buffer.height() - frameh_s, 1, 1));
+ // Draw right center block borders
+ p->drawPixmap(QRect(buttonw - framew, frameh_n - skipTopBorder, framew, center - frameh_n), buffer, QRect(buffer.width() - framew, frameh_n, framew, 1));
+ p->drawPixmap(QRect(buttonw - framew, center, framew, buttonh - center - 1), buffer, QRect(buffer.width() - framew, buffer.height() - frameh_s, framew, 1));
+ // Draw right corners
+ p->drawPixmap(QRect(buttonw - framew, -skipTopBorder, framew, frameh_n), buffer, QRect(buffer.width() - framew, 0, framew, frameh_n));
+ p->drawPixmap(QRect(buttonw - framew, buttonh - frameh_s, framew, frameh_s), buffer, QRect(buffer.width() - framew, buffer.height() - frameh_s, framew, frameh_s));
+ // Draw center transition block
+ p->drawPixmap(QRect(0, center - qRound(transh / 2.0f), buttonw - framew, buffer.height() - frameh_n - frameh_s), buffer, QRect(framew, frameh_n + 1, 1, transh));
+ // Draw right center transition block border
+ p->drawPixmap(QRect(buttonw - framew, center - qRound(transh / 2.0f), framew, buffer.height() - frameh_n - frameh_s), buffer, QRect(buffer.width() - framew, frameh_n + 1, framew, transh));
+ if (drawLeftBorder){
+ // Draw left center block borders
+ p->drawPixmap(QRect(0, frameh_n - skipTopBorder, framew, center - frameh_n + skipTopBorder), buffer, QRect(0, frameh_n, framew, 1));
+ p->drawPixmap(QRect(0, center, framew, buttonh - center - 1), buffer, QRect(0, buffer.height() - frameh_s, framew, 1));
+ // Draw left corners
+ p->drawPixmap(QRect(0, -skipTopBorder, framew, frameh_n), buffer, QRect(0, 0, framew, frameh_n));
+ p->drawPixmap(QRect(0, buttonh - frameh_s, framew, frameh_s), buffer, QRect(0, buffer.height() - frameh_s, framew, frameh_s));
+ // Draw left center transition block border
+ p->drawPixmap(QRect(0, center - qRound(transh / 2.0f), framew, buffer.height() - frameh_n - frameh_s), buffer, QRect(0, frameh_n + 1, framew, transh));
+ }
+
+ p->translate(-outerBounds.origin.x, -outerBounds.origin.y);
+}
+
+/*
+ Returns cutoff sizes for scroll bars.
+ thumbIndicatorCutoff is the smallest size where the thumb indicator is drawn.
+ scrollButtonsCutoff is the smallest size where the up/down buttons is drawn.
+*/
+enum ScrollBarCutoffType { thumbIndicatorCutoff = 0, scrollButtonsCutoff = 1 };
+static int scrollButtonsCutoffSize(ScrollBarCutoffType cutoffType, QMacStyle::WidgetSizePolicy widgetSize)
+{
+ // Mini scroll bars do not exist as of version 10.4.
+ if (widgetSize == QMacStyle::SizeMini)
+ return 0;
+
+ const int sizeIndex = (widgetSize == QMacStyle::SizeSmall) ? 1 : 0;
+ static const int sizeTable[2][2] = { { 61, 56 }, { 49, 44 } };
+ return sizeTable[sizeIndex][cutoffType];
+}
+
+void QMacStylePrivate::getSliderInfo(QStyle::ComplexControl cc, const QStyleOptionSlider *slider,
+ HIThemeTrackDrawInfo *tdi, const QWidget *needToRemoveMe)
+{
+ memset(tdi, 0, sizeof(HIThemeTrackDrawInfo)); // We don't get it all for some reason or another...
+ tdi->version = qt_mac_hitheme_version;
+ tdi->reserved = 0;
+ tdi->filler1 = 0;
+ bool isScrollbar = (cc == QStyle::CC_ScrollBar);
+ switch (aquaSizeConstrain(0, needToRemoveMe)) {
+ case QAquaSizeUnknown:
+ case QAquaSizeLarge:
+ if (isScrollbar)
+ tdi->kind = kThemeMediumScrollBar;
+ else
+ tdi->kind = kThemeMediumSlider;
+ break;
+ case QAquaSizeMini:
+ if (isScrollbar)
+ tdi->kind = kThemeSmallScrollBar; // should be kThemeMiniScrollBar, but not implemented
+ else
+ tdi->kind = kThemeMiniSlider;
+ break;
+ case QAquaSizeSmall:
+ if (isScrollbar)
+ tdi->kind = kThemeSmallScrollBar;
+ else
+ tdi->kind = kThemeSmallSlider;
+ break;
+ }
+ tdi->bounds = qt_hirectForQRect(slider->rect);
+ tdi->min = slider->minimum;
+ tdi->max = slider->maximum;
+ tdi->value = slider->sliderPosition;
+ tdi->attributes = kThemeTrackShowThumb;
+ if (slider->upsideDown)
+ tdi->attributes |= kThemeTrackRightToLeft;
+ if (slider->orientation == Qt::Horizontal) {
+ tdi->attributes |= kThemeTrackHorizontal;
+ if (isScrollbar && slider->direction == Qt::RightToLeft) {
+ if (!slider->upsideDown)
+ tdi->attributes |= kThemeTrackRightToLeft;
+ else
+ tdi->attributes &= ~kThemeTrackRightToLeft;
+ }
+ }
+
+ // Tiger broke reverse scroll bars so put them back and "fake it"
+ if (isScrollbar && (tdi->attributes & kThemeTrackRightToLeft)) {
+ tdi->attributes &= ~kThemeTrackRightToLeft;
+ tdi->value = tdi->max - slider->sliderPosition;
+ }
+
+ tdi->enableState = (slider->state & QStyle::State_Enabled) ? kThemeTrackActive
+ : kThemeTrackDisabled;
+ if (!(slider->state & QStyle::State_Active))
+ tdi->enableState = kThemeTrackInactive;
+ if (!isScrollbar) {
+ if (slider->state & QStyle::QStyle::State_HasFocus)
+ tdi->attributes |= kThemeTrackHasFocus;
+ if (slider->tickPosition == QSlider::NoTicks || slider->tickPosition == QSlider::TicksBothSides)
+ tdi->trackInfo.slider.thumbDir = kThemeThumbPlain;
+ else if (slider->tickPosition == QSlider::TicksAbove)
+ tdi->trackInfo.slider.thumbDir = kThemeThumbUpward;
+ else
+ tdi->trackInfo.slider.thumbDir = kThemeThumbDownward;
+ } else {
+ tdi->trackInfo.scrollbar.viewsize = slider->pageStep;
+ }
+}
+#endif
+
+QMacStylePrivate::QMacStylePrivate(QMacStyle *style)
+ : timerID(-1), progressFrame(0), q(style), mouseDown(false)
+{
+ defaultButtonStart = CFAbsoluteTimeGetCurrent();
+ memset(&buttonState, 0, sizeof(ButtonState));
+
+ if (ptrHIShapeGetBounds == 0) {
+ QLibrary library(QLatin1String("/System/Library/Frameworks/Carbon.framework/Carbon"));
+ library.setLoadHints(QLibrary::ExportExternalSymbolsHint);
+ ptrHIShapeGetBounds = reinterpret_cast<PtrHIShapeGetBounds>(library.resolve("HIShapeGetBounds"));
+ }
+
+}
+
+bool QMacStylePrivate::animatable(QMacStylePrivate::Animates as, const QWidget *w) const
+{
+ if (!w)
+ return false;
+
+ if (as == AquaPushButton) {
+ QPushButton *pb = const_cast<QPushButton *>(static_cast<const QPushButton *>(w));
+ 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);
+ const_cast<QMacStylePrivate *>(this)->startAnimate(as, pb);
+ }
+ return true;
+ }
+ } else if (as == AquaProgressBar) {
+ if (progressBars.contains((const_cast<QWidget *>(w))))
+ return true;
+ }
+ return false;
+}
+
+void QMacStylePrivate::stopAnimate(QMacStylePrivate::Animates as, QWidget *w)
+{
+ if (as == AquaPushButton && defaultButton) {
+ QPushButton *tmp = defaultButton;
+ defaultButton = 0;
+ tmp->update();
+ } else if (as == AquaProgressBar) {
+ progressBars.removeAll(w);
+ }
+}
+
+void QMacStylePrivate::startAnimate(QMacStylePrivate::Animates as, QWidget *w)
+{
+ if (as == AquaPushButton)
+ defaultButton = static_cast<QPushButton *>(w);
+ else if (as == AquaProgressBar)
+ progressBars.append(w);
+ startAnimationTimer();
+}
+
+void QMacStylePrivate::startAnimationTimer()
+{
+ if ((defaultButton || !progressBars.isEmpty()) && timerID <= -1)
+ timerID = startTimer(animateSpeed(AquaListViewItemOpen));
+}
+
+bool QMacStylePrivate::addWidget(QWidget *w)
+{
+ //already knew of it
+ if (static_cast<QPushButton*>(w) == defaultButton
+ || progressBars.contains(static_cast<QProgressBar*>(w)))
+ return false;
+
+ if (QPushButton *btn = qobject_cast<QPushButton *>(w)) {
+ btn->installEventFilter(this);
+ if (btn->isDefault() || (btn->autoDefault() && btn->hasFocus()))
+ startAnimate(AquaPushButton, btn);
+ return true;
+ } else {
+ bool isProgressBar = (qobject_cast<QProgressBar *>(w)
+#ifdef QT3_SUPPORT
+ || w->inherits("Q3ProgressBar")
+#endif
+ );
+ if (isProgressBar) {
+ w->installEventFilter(this);
+ startAnimate(AquaProgressBar, w);
+ return true;
+ }
+ }
+ if (w->isWindow()) {
+ w->installEventFilter(this);
+ return true;
+ }
+ return false;
+}
+
+void QMacStylePrivate::removeWidget(QWidget *w)
+{
+ QPushButton *btn = qobject_cast<QPushButton *>(w);
+ if (btn && btn == defaultButton) {
+ stopAnimate(AquaPushButton, btn);
+ } else if (qobject_cast<QProgressBar *>(w)
+#ifdef QT3_SUPPORT
+ || w->inherits("Q3ProgressBar")
+#endif
+ ) {
+ stopAnimate(AquaProgressBar, w);
+ }
+}
+
+ThemeDrawState QMacStylePrivate::getDrawState(QStyle::State flags)
+{
+ ThemeDrawState tds = kThemeStateActive;
+ if (flags & QStyle::State_Sunken) {
+ tds = kThemeStatePressed;
+ } else if (flags & QStyle::State_Active) {
+ if (!(flags & QStyle::State_Enabled))
+ tds = kThemeStateUnavailable;
+ } else {
+ if (flags & QStyle::State_Enabled)
+ tds = kThemeStateInactive;
+ else
+ tds = kThemeStateUnavailableInactive;
+ }
+ return tds;
+}
+
+void QMacStylePrivate::timerEvent(QTimerEvent *)
+{
+ int animated = 0;
+ if (defaultButton && defaultButton->isEnabled() && defaultButton->window()->isActiveWindow()
+ && defaultButton->isVisibleTo(0) && (defaultButton->isDefault()
+ || (defaultButton->autoDefault() && defaultButton->hasFocus()))
+ && doAnimate(AquaPushButton)) {
+ ++animated;
+ defaultButton->update();
+ }
+ if (!progressBars.isEmpty()) {
+ int i = 0;
+ while (i < progressBars.size()) {
+ QWidget *maybeProgress = progressBars.at(i);
+ if (!maybeProgress) {
+ progressBars.removeAt(i);
+ } else {
+ if (QProgressBar *pb = qobject_cast<QProgressBar *>(maybeProgress)) {
+ if (pb->maximum() == 0 || (pb->value() > 0 && pb->value() < pb->maximum())) {
+ if (doAnimate(AquaProgressBar))
+ pb->update();
+ }
+ }
+#ifdef QT3_SUPPORT
+ else {
+ // Watch me now...
+ QVariant progress = maybeProgress->property("progress");
+ QVariant totalSteps = maybeProgress->property("totalSteps");
+ if (progress.isValid() && totalSteps.isValid()) {
+ int intProgress = progress.toInt();
+ int intTotalSteps = totalSteps.toInt();
+ if (intTotalSteps == 0 || intProgress > 0 && intProgress < intTotalSteps) {
+ if (doAnimate(AquaProgressBar))
+ maybeProgress->update();
+ }
+ }
+ }
+#endif
+ ++i;
+ }
+ }
+ if (i > 0) {
+ ++progressFrame;
+ animated += i;
+ }
+ }
+ if (animated <= 0) {
+ killTimer(timerID);
+ timerID = -1;
+ }
+}
+
+bool QMacStylePrivate::eventFilter(QObject *o, QEvent *e)
+{
+ //animate
+ if (QProgressBar *pb = qobject_cast<QProgressBar *>(o)) {
+ switch (e->type()) {
+ default:
+ break;
+ case QEvent::Show:
+ if (!progressBars.contains(pb))
+ startAnimate(AquaProgressBar, pb);
+ break;
+ case QEvent::Destroy:
+ case QEvent::Hide:
+ progressBars.removeAll(pb);
+ }
+ } else if (QPushButton *btn = qobject_cast<QPushButton *>(o)) {
+ switch (e->type()) {
+ default:
+ break;
+ case QEvent::FocusIn:
+ if (btn->autoDefault())
+ startAnimate(AquaPushButton, btn);
+ break;
+ case QEvent::Destroy:
+ case QEvent::Hide:
+ if (btn == defaultButton)
+ stopAnimate(AquaPushButton, btn);
+ 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::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 = btn->window()->findChildren<QPushButton *>();
+ for (int i = 0; i < list.size(); ++i) {
+ QPushButton *pBtn = list.at(i);
+ if ((e->type() == QEvent::FocusOut
+ && (pBtn->isDefault() || (pBtn->autoDefault() && pBtn->hasFocus()))
+ && pBtn != btn)
+ || ((e->type() == QEvent::Show || e->type() == QEvent::MouseButtonRelease
+ || e->type() == QEvent::WindowActivate)
+ && pBtn->isDefault())) {
+ if (pBtn->window()->isActiveWindow()) {
+ startAnimate(AquaPushButton, pBtn);
+ }
+ break;
+ }
+ }
+ break; }
+ }
+ }
+ return false;
+}
+
+bool QMacStylePrivate::doAnimate(QMacStylePrivate::Animates as)
+{
+ if (as == AquaPushButton) {
+ } else if (as == AquaProgressBar) {
+ // something for later...
+ } else if (as == AquaListViewItemOpen) {
+ // To be revived later...
+ }
+ return true;
+}
+
+void QMacStylePrivate::drawColorlessButton(const HIRect &macRect, HIThemeButtonDrawInfo *bdi,
+ QPainter *p, const QStyleOption *opt) const
+{
+ int xoff = 0,
+ yoff = 0,
+ extraWidth = 0,
+ extraHeight = 0,
+ finalyoff = 0;
+
+ const QStyleOptionComboBox *combo = qstyleoption_cast<const QStyleOptionComboBox *>(opt);
+ int width = int(macRect.size.width) + extraWidth;
+ int height = int(macRect.size.height) + extraHeight;
+
+ if (width <= 0 || height <= 0)
+ return; // nothing to draw
+
+ QString key = QLatin1String("$qt_mac_style_ctb_") + QString::number(bdi->kind) + QLatin1Char('_')
+ + QString::number(bdi->value) + QLatin1Char('_') + QString::number(width)
+ + QLatin1Char('_') + QString::number(height);
+ QPixmap pm;
+ if (!QPixmapCache::find(key, pm)) {
+ QPixmap activePixmap(width, height);
+ activePixmap.fill(Qt::transparent);
+ {
+ if (combo){
+ // Carbon combos don't scale. Therefore we draw it
+ // ourselves, if a scaled version is needed.
+ QPainter tmpPainter(&activePixmap);
+ QMacStylePrivate::drawCombobox(macRect, *bdi, &tmpPainter);
+ }
+ else {
+ QMacCGContext cg(&activePixmap);
+ HIRect newRect = CGRectMake(xoff, yoff, macRect.size.width, macRect.size.height);
+ HIThemeDrawButton(&newRect, bdi, cg, kHIThemeOrientationNormal, 0);
+ }
+ }
+
+ if (!combo && bdi->value == kThemeButtonOff) {
+ pm = activePixmap;
+ } else if (combo) {
+ QImage image = activePixmap.toImage();
+
+ for (int y = 0; y < height; ++y) {
+ QRgb *scanLine = reinterpret_cast<QRgb *>(image.scanLine(y));
+
+ for (int x = 0; x < width; ++x) {
+ QRgb &pixel = scanLine[x];
+
+ int darkest = qRed(pixel);
+ int mid = qGreen(pixel);
+ int lightest = qBlue(pixel);
+
+ if (darkest > mid)
+ qSwap(darkest, mid);
+ if (mid > lightest)
+ qSwap(mid, lightest);
+ if (darkest > mid)
+ qSwap(darkest, mid);
+
+ int gray = (mid + 2 * lightest) / 3;
+ pixel = qRgba(gray, gray, gray, qAlpha(pixel));
+ }
+ }
+ pm = QPixmap::fromImage(image);
+ } else {
+ QImage activeImage = activePixmap.toImage();
+ QImage colorlessImage;
+ {
+ QPixmap colorlessPixmap(width, height);
+ colorlessPixmap.fill(Qt::transparent);
+
+ QMacCGContext cg(&colorlessPixmap);
+ HIRect newRect = CGRectMake(xoff, yoff, macRect.size.width, macRect.size.height);
+ int oldValue = bdi->value;
+ bdi->value = kThemeButtonOff;
+ HIThemeDrawButton(&newRect, bdi, cg, kHIThemeOrientationNormal, 0);
+ bdi->value = oldValue;
+ colorlessImage = colorlessPixmap.toImage();
+ }
+
+ for (int y = 0; y < height; ++y) {
+ QRgb *colorlessScanLine = reinterpret_cast<QRgb *>(colorlessImage.scanLine(y));
+ const QRgb *activeScanLine = reinterpret_cast<const QRgb *>(activeImage.scanLine(y));
+
+ for (int x = 0; x < width; ++x) {
+ QRgb &colorlessPixel = colorlessScanLine[x];
+ QRgb activePixel = activeScanLine[x];
+
+ if (activePixel != colorlessPixel) {
+ int max = qMax(qMax(qRed(activePixel), qGreen(activePixel)),
+ qBlue(activePixel));
+ QRgb newPixel = qRgba(max, max, max, qAlpha(activePixel));
+ if (qGray(newPixel) < qGray(colorlessPixel)
+ || qAlpha(newPixel) > qAlpha(colorlessPixel))
+ colorlessPixel = newPixel;
+ }
+ }
+ }
+ pm = QPixmap::fromImage(colorlessImage);
+ }
+ QPixmapCache::insert(key, pm);
+ }
+ p->drawPixmap(int(macRect.origin.x), int(macRect.origin.y) + finalyoff, width, height, pm);
+}
+
+QMacStyle::QMacStyle()
+ : QWindowsStyle()
+{
+ d = new QMacStylePrivate(this);
+}
+
+QMacStyle::~QMacStyle()
+{
+ delete qt_mac_backgroundPattern;
+ qt_mac_backgroundPattern = 0;
+ delete d;
+}
+
+/*! \internal
+ Generates the standard widget background pattern.
+*/
+QPixmap QMacStylePrivate::generateBackgroundPattern() const
+{
+ QPixmap px(4, 4);
+ QMacCGContext cg(&px);
+ HIThemeSetFill(kThemeBrushDialogBackgroundActive, 0, cg, kHIThemeOrientationNormal);
+ const CGRect cgRect = CGRectMake(0, 0, px.width(), px.height());
+ CGContextFillRect(cg, cgRect);
+ return px;
+}
+
+/*! \internal
+ Fills the given \a rect with the pattern stored in \a brush. As an optimization,
+ HIThemeSetFill us used directly if we are filling with the standard background.
+*/
+void qt_mac_fill_background(QPainter *painter, const QRegion &rgn, const QBrush &brush)
+{
+ QPoint dummy;
+ const QPaintDevice *target = painter->device();
+ const QPaintDevice *redirected = QPainter::redirected(target, &dummy);
+ const bool usePainter = redirected && redirected != target;
+
+ if (!usePainter && qt_mac_backgroundPattern
+ && qt_mac_backgroundPattern->cacheKey() == brush.texture().cacheKey()) {
+
+ painter->setClipRegion(rgn);
+
+ QCFType<CGContextRef> cg = qt_mac_cg_context(target);
+ CGContextSaveGState(cg);
+ HIThemeSetFill(kThemeBrushDialogBackgroundActive, 0, cg, kHIThemeOrientationInverted);
+
+ const QVector<QRect> &rects = rgn.rects();
+ for (int i = 0; i < rects.size(); ++i) {
+ const QRect rect(rects.at(i));
+ // Anchor the pattern to the top so it stays put when the window is resized.
+ CGContextSetPatternPhase(cg, CGSizeMake(rect.width(), rect.height()));
+ CGRect mac_rect = CGRectMake(rect.x(), rect.y(), rect.width(), rect.height());
+ CGContextFillRect(cg, mac_rect);
+ }
+
+ CGContextRestoreGState(cg);
+ } else {
+ const QRect rect(rgn.boundingRect());
+ painter->setClipRegion(rgn);
+ painter->drawTiledPixmap(rect, brush.texture(), rect.topLeft());
+ }
+}
+
+void QMacStyle::polish(QPalette &pal)
+{
+ if (!qt_mac_backgroundPattern) {
+ if (!qApp)
+ return;
+ qt_mac_backgroundPattern = new QPixmap(d->generateBackgroundPattern());
+ }
+
+ QColor pc(Qt::black);
+ pc = qcolorForTheme(kThemeBrushDialogBackgroundActive);
+ QBrush background(pc, *qt_mac_backgroundPattern);
+ pal.setBrush(QPalette::All, QPalette::Window, background);
+ pal.setBrush(QPalette::All, QPalette::Button, background);
+
+ QCFString theme;
+ const OSErr err = CopyThemeIdentifier(&theme);
+ if (err == noErr && CFStringCompare(theme, kThemeAppearanceAquaGraphite, 0) == kCFCompareEqualTo) {
+ pal.setBrush(QPalette::All, QPalette::AlternateBase, QColor(240, 240, 240));
+ } else {
+ pal.setBrush(QPalette::All, QPalette::AlternateBase, QColor(237, 243, 254));
+ }
+}
+
+void QMacStyle::polish(QApplication *)
+{
+}
+
+void QMacStyle::unpolish(QApplication *)
+{
+}
+
+void QMacStyle::polish(QWidget* w)
+{
+ d->addWidget(w);
+ if (qt_mac_is_metal(w) && !w->testAttribute(Qt::WA_SetPalette)) {
+ // Set a clear brush so that the metal shines through.
+ QPalette pal = w->palette();
+ QBrush background(Qt::transparent);
+ pal.setBrush(QPalette::All, QPalette::Window, background);
+ pal.setBrush(QPalette::All, QPalette::Button, background);
+ w->setPalette(pal);
+ w->setAttribute(Qt::WA_SetPalette, false);
+ }
+
+ if (qobject_cast<QMenu*>(w) || qobject_cast<QComboBoxPrivateContainer *>(w)) {
+ w->setWindowOpacity(QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5 ? 0.985 : 0.94);
+ if (!w->testAttribute(Qt::WA_SetPalette)) {
+ QPixmap px(64, 64);
+ px.fill(Qt::white);
+ HIThemeMenuDrawInfo mtinfo;
+ mtinfo.version = qt_mac_hitheme_version;
+ mtinfo.menuType = kThemeMenuTypePopUp;
+ HIRect rect = CGRectMake(0, 0, px.width(), px.height());
+ HIThemeDrawMenuBackground(&rect, &mtinfo, QCFType<CGContextRef>(qt_mac_cg_context(&px)),
+ kHIThemeOrientationNormal);
+ QPalette pal = w->palette();
+ QBrush background(px);
+ pal.setBrush(QPalette::All, QPalette::Window, background);
+ pal.setBrush(QPalette::All, QPalette::Button, background);
+ w->setPalette(pal);
+ w->setAttribute(Qt::WA_SetPalette, false);
+ }
+ }
+
+ if (QTabBar *tb = qobject_cast<QTabBar*>(w)) {
+ if (tb->documentMode()) {
+ w->setAttribute(Qt::WA_Hover);
+ w->setFont(qt_app_fonts_hash()->value("QSmallFont", QFont()));
+ QPalette p = w->palette();
+ p.setColor(QPalette::WindowText, QColor(17, 17, 17));
+ w->setPalette(p);
+ }
+ }
+
+ QWindowsStyle::polish(w);
+
+ if (QRubberBand *rubber = qobject_cast<QRubberBand*>(w)) {
+ rubber->setWindowOpacity(0.25);
+ rubber->setAttribute(Qt::WA_PaintOnScreen, false);
+ rubber->setAttribute(Qt::WA_NoSystemBackground, false);
+ }
+}
+
+void QMacStyle::unpolish(QWidget* w)
+{
+ d->removeWidget(w);
+ if ((qobject_cast<QMenu*>(w) || qt_mac_is_metal(w)) && !w->testAttribute(Qt::WA_SetPalette)) {
+ QPalette pal = qApp->palette(w);
+ w->setPalette(pal);
+ w->setAttribute(Qt::WA_SetPalette, false);
+ w->setWindowOpacity(1.0);
+ }
+
+ if (QComboBox *combo = qobject_cast<QComboBox *>(w)) {
+ if (!combo->isEditable()) {
+ if (QWidget *widget = combo->findChild<QComboBoxPrivateContainer *>())
+ widget->setWindowOpacity(1.0);
+ }
+ }
+
+ if (QRubberBand *rubber = ::qobject_cast<QRubberBand*>(w)) {
+ rubber->setWindowOpacity(1.0);
+ rubber->setAttribute(Qt::WA_PaintOnScreen, true);
+ rubber->setAttribute(Qt::WA_NoSystemBackground, true);
+ }
+
+ if (QFocusFrame *frame = qobject_cast<QFocusFrame *>(w))
+ frame->setAttribute(Qt::WA_NoSystemBackground, true);
+
+ QWindowsStyle::unpolish(w);
+}
+
+int QMacStyle::pixelMetric(PixelMetric metric, const QStyleOption *opt, const QWidget *widget) const
+{
+ int controlSize = getControlSize(opt, widget);
+ SInt32 ret = 0;
+
+ switch (metric) {
+ case PM_TabCloseIndicatorWidth:
+ case PM_TabCloseIndicatorHeight:
+ ret = closeButtonSize;
+ break;
+ case PM_ToolBarIconSize:
+ ret = proxy()->pixelMetric(PM_LargeIconSize);
+ break;
+ case PM_FocusFrameVMargin:
+ case PM_FocusFrameHMargin:
+ GetThemeMetric(kThemeMetricFocusRectOutset, &ret);
+ break;
+ case PM_DialogButtonsSeparator:
+ ret = -5;
+ break;
+ case PM_DialogButtonsButtonHeight: {
+ QSize sz;
+ ret = d->aquaSizeConstrain(opt, 0, QStyle::CT_PushButton, QSize(-1, -1), &sz);
+ if (sz == QSize(-1, -1))
+ ret = 32;
+ else
+ ret = sz.height();
+ break; }
+ case PM_CheckListButtonSize: {
+ switch (d->aquaSizeConstrain(opt, widget)) {
+ case QAquaSizeUnknown:
+ case QAquaSizeLarge:
+ GetThemeMetric(kThemeMetricCheckBoxWidth, &ret);
+ break;
+ case QAquaSizeMini:
+ GetThemeMetric(kThemeMetricMiniCheckBoxWidth, &ret);
+ break;
+ case QAquaSizeSmall:
+ GetThemeMetric(kThemeMetricSmallCheckBoxWidth, &ret);
+ break;
+ }
+ break; }
+ case PM_DialogButtonsButtonWidth: {
+ QSize sz;
+ ret = d->aquaSizeConstrain(opt, 0, QStyle::CT_PushButton, QSize(-1, -1), &sz);
+ if (sz == QSize(-1, -1))
+ ret = 70;
+ else
+ ret = sz.width();
+ break; }
+
+ case PM_MenuBarHMargin:
+ ret = 8;
+ break;
+
+ case PM_MenuBarVMargin:
+ ret = 0;
+ break;
+
+ case QStyle::PM_MenuDesktopFrameWidth:
+ ret = 5;
+ break;
+
+ case PM_CheckBoxLabelSpacing:
+ case PM_RadioButtonLabelSpacing:
+ ret = 2;
+ break;
+ case PM_MenuScrollerHeight:
+#if 0
+ SInt16 ash, asw;
+ GetThemeMenuItemExtra(kThemeMenuItemScrollUpArrow, &ash, &asw);
+ ret = ash;
+#else
+ ret = 15; // I hate having magic numbers in here...
+#endif
+ break;
+ case PM_DefaultFrameWidth:
+#ifndef QT_NO_MAINWINDOW
+ if (widget && (widget->isWindow() || !widget->parentWidget()
+ || (qobject_cast<const QMainWindow*>(widget->parentWidget())
+ && static_cast<QMainWindow *>(widget->parentWidget())->centralWidget() == widget))
+ && (qobject_cast<const QAbstractScrollArea *>(widget)
+#ifdef QT3_SUPPORT
+ || widget->inherits("QScrollView")
+#endif
+ || widget->inherits("QWorkspaceChild")))
+ ret = 0;
+ else
+#endif
+ // The combo box popup has no frame.
+ if (qstyleoption_cast<const QStyleOptionComboBox *>(opt) != 0)
+ ret = 0;
+ // Frame of mac style line edits is two pixels on top and one on the bottom
+ else if (qobject_cast<const QLineEdit *>(widget) != 0)
+ ret = 2;
+ else
+ ret = 1;
+ break;
+ case PM_MaximumDragDistance:
+ ret = -1;
+ break;
+ case PM_ScrollBarSliderMin:
+ ret = 24;
+ break;
+ case PM_SpinBoxFrameWidth:
+ GetThemeMetric(kThemeMetricEditTextFrameOutset, &ret);
+ switch (d->aquaSizeConstrain(opt, widget)) {
+ default:
+ ret += 2;
+ break;
+ case QAquaSizeMini:
+ ret += 1;
+ break;
+ }
+ break;
+ case PM_ButtonShiftHorizontal:
+ case PM_ButtonShiftVertical:
+ ret = 0;
+ break;
+ case PM_SliderLength:
+ ret = 17;
+ break;
+ case PM_ButtonDefaultIndicator:
+ ret = 0;
+ break;
+ case PM_TitleBarHeight:
+ if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) {
+ HIThemeWindowDrawInfo wdi;
+ wdi.version = qt_mac_hitheme_version;
+ wdi.state = kThemeStateActive;
+ wdi.windowType = QtWinType;
+ if (tb->titleBarState)
+ wdi.attributes = kThemeWindowHasFullZoom | kThemeWindowHasCloseBox
+ | kThemeWindowHasCollapseBox;
+ else if (tb->titleBarFlags & Qt::WindowSystemMenuHint)
+ wdi.attributes = kThemeWindowHasCloseBox;
+ else
+ wdi.attributes = 0;
+ wdi.titleHeight = tb->rect.height();
+ wdi.titleWidth = tb->rect.width();
+ QCFType<HIShapeRef> region;
+ HIRect hirect = qt_hirectForQRect(tb->rect);
+ if (hirect.size.width <= 0)
+ hirect.size.width = 100;
+ if (hirect.size.height <= 0)
+ hirect.size.height = 30;
+
+ HIThemeGetWindowShape(&hirect, &wdi, kWindowTitleBarRgn, &region);
+ HIRect rect;
+ ptrHIShapeGetBounds(region, &rect);
+ ret = int(rect.size.height);
+ ret += 4;
+ }
+ break;
+ case PM_TabBarTabVSpace:
+ ret = 4;
+ break;
+ case PM_TabBarTabShiftHorizontal:
+ case PM_TabBarTabShiftVertical:
+ ret = 0;
+ break;
+ case PM_TabBarBaseHeight:
+ ret = 0;
+ break;
+ case PM_TabBarTabOverlap:
+ ret = 0;
+ break;
+ case PM_TabBarBaseOverlap:
+ switch (d->aquaSizeConstrain(opt, widget)) {
+ case QAquaSizeUnknown:
+ case QAquaSizeLarge:
+ ret = 11;
+ break;
+ case QAquaSizeSmall:
+ ret = 8;
+ break;
+ case QAquaSizeMini:
+ ret = 7;
+ break;
+ }
+ break;
+ case PM_ScrollBarExtent: {
+ switch (d->aquaSizeConstrain(opt, widget)) {
+ case QAquaSizeUnknown:
+ case QAquaSizeLarge:
+ GetThemeMetric(kThemeMetricScrollBarWidth, &ret);
+ break;
+ case QAquaSizeMini:
+ case QAquaSizeSmall:
+ GetThemeMetric(kThemeMetricSmallScrollBarWidth, &ret);
+ break;
+ }
+ break; }
+ case PM_IndicatorHeight: {
+ switch (d->aquaSizeConstrain(opt, widget)) {
+ case QAquaSizeUnknown:
+ case QAquaSizeLarge:
+ GetThemeMetric(kThemeMetricCheckBoxHeight, &ret);
+ break;
+ case QAquaSizeMini:
+ GetThemeMetric(kThemeMetricMiniCheckBoxHeight, &ret);
+ break;
+ case QAquaSizeSmall:
+ GetThemeMetric(kThemeMetricSmallCheckBoxHeight, &ret);
+ break;
+ }
+ break; }
+ case PM_IndicatorWidth: {
+ switch (d->aquaSizeConstrain(opt, widget)) {
+ case QAquaSizeUnknown:
+ case QAquaSizeLarge:
+ GetThemeMetric(kThemeMetricCheckBoxWidth, &ret);
+ break;
+ case QAquaSizeMini:
+ GetThemeMetric(kThemeMetricMiniCheckBoxWidth, &ret);
+ break;
+ case QAquaSizeSmall:
+ GetThemeMetric(kThemeMetricSmallCheckBoxWidth, &ret);
+ break;
+ }
+ ++ret;
+ break; }
+ case PM_ExclusiveIndicatorHeight: {
+ switch (d->aquaSizeConstrain(opt, widget)) {
+ case QAquaSizeUnknown:
+ case QAquaSizeLarge:
+ GetThemeMetric(kThemeMetricRadioButtonHeight, &ret);
+ break;
+ case QAquaSizeMini:
+ GetThemeMetric(kThemeMetricMiniRadioButtonHeight, &ret);
+ break;
+ case QAquaSizeSmall:
+ GetThemeMetric(kThemeMetricSmallRadioButtonHeight, &ret);
+ break;
+ }
+ break; }
+ case PM_ExclusiveIndicatorWidth: {
+ switch (d->aquaSizeConstrain(opt, widget)) {
+ case QAquaSizeUnknown:
+ case QAquaSizeLarge:
+ GetThemeMetric(kThemeMetricRadioButtonWidth, &ret);
+ break;
+ case QAquaSizeMini:
+ GetThemeMetric(kThemeMetricMiniRadioButtonWidth, &ret);
+ break;
+ case QAquaSizeSmall:
+ GetThemeMetric(kThemeMetricSmallRadioButtonWidth, &ret);
+ break;
+ }
+ ++ret;
+ break; }
+ case PM_MenuVMargin:
+ ret = 4;
+ break;
+ case PM_MenuPanelWidth:
+ ret = 0;
+ break;
+ case PM_ToolTipLabelFrameWidth:
+ ret = 0;
+ break;
+ case PM_SizeGripSize: {
+ QAquaWidgetSize aSize;
+ if (widget && widget->window()->windowType() == Qt::Tool)
+ aSize = QAquaSizeSmall;
+ else
+ aSize = QAquaSizeLarge;
+ const QSize size = qt_aqua_get_known_size(CT_SizeGrip, widget, QSize(), aSize);
+ ret = size.width();
+ break; }
+ case PM_MdiSubWindowFrameWidth:
+ ret = 1;
+ break;
+ case PM_DockWidgetFrameWidth:
+ ret = 2;
+ break;
+ case PM_DockWidgetTitleMargin:
+ ret = 0;
+ break;
+ case PM_DockWidgetSeparatorExtent:
+ ret = 1;
+ break;
+ case PM_ToolBarHandleExtent:
+ ret = 11;
+ break;
+ case PM_ToolBarItemMargin:
+ ret = 0;
+ break;
+ case PM_ToolBarItemSpacing:
+ ret = 4;
+ break;
+ case PM_SplitterWidth:
+ ret = qMax(7, QApplication::globalStrut().width());
+ break;
+ case PM_LayoutLeftMargin:
+ case PM_LayoutTopMargin:
+ case PM_LayoutRightMargin:
+ case PM_LayoutBottomMargin:
+ {
+ bool isWindow = false;
+ if (opt) {
+ isWindow = (opt->state & State_Window);
+ } else if (widget) {
+ isWindow = widget->isWindow();
+ }
+
+ if (isWindow) {
+ bool isMetal = widget && widget->testAttribute(Qt::WA_MacBrushedMetal);
+ if (isMetal) {
+ if (metric == PM_LayoutTopMargin) {
+ return_SIZE(9 /* AHIG */, 6 /* guess */, 6 /* guess */);
+ } else if (metric == PM_LayoutBottomMargin) {
+ return_SIZE(18 /* AHIG */, 15 /* guess */, 13 /* guess */);
+ } else {
+ return_SIZE(14 /* AHIG */, 11 /* guess */, 9 /* guess */);
+ }
+ } else {
+ /*
+ AHIG would have (20, 8, 10) here but that makes
+ no sense. It would also have 14 for the top margin
+ but this contradicts both Builder and most
+ applications.
+ */
+ return_SIZE(20, 10, 10); // AHIG
+ }
+ } else {
+ // hack to detect QTabWidget
+ if (widget && widget->parentWidget()
+ && widget->parentWidget()->sizePolicy().controlType() == QSizePolicy::TabWidget) {
+ if (metric == PM_LayoutTopMargin) {
+ /*
+ Builder would have 14 (= 20 - 6) instead of 12,
+ but that makes the tab look disproportionate.
+ */
+ return_SIZE(12, 6, 6); // guess
+ } else {
+ return_SIZE(20 /* Builder */, 8 /* guess */, 8 /* guess */);
+ }
+ } else {
+ /*
+ Child margins are highly inconsistent in AHIG and Builder.
+ */
+ return_SIZE(12, 8, 6); // guess
+ }
+ }
+ }
+ case PM_LayoutHorizontalSpacing:
+ case PM_LayoutVerticalSpacing:
+ return -1;
+ case QStyle::PM_TabBarTabHSpace:
+ switch (d->aquaSizeConstrain(opt, widget)) {
+ case QAquaSizeLarge:
+ case QAquaSizeUnknown:
+ ret = QWindowsStyle::pixelMetric(metric, opt, widget);
+ break;
+ case QAquaSizeSmall:
+ ret = 20;
+ break;
+ case QAquaSizeMini:
+ ret = 16;
+ break;
+ }
+ break;
+ case PM_MenuHMargin:
+ ret = 0;
+ break;
+ case PM_ToolBarFrameWidth:
+ ret = 1;
+ if (widget) {
+ if (QMainWindow * mainWindow = qobject_cast<QMainWindow *>(widget->parent()))
+ if (mainWindow->unifiedTitleAndToolBarOnMac())
+ ret = 0;
+ }
+ break;
+ default:
+ ret = QWindowsStyle::pixelMetric(metric, opt, widget);
+ break;
+ }
+ return ret;
+}
+
+QPalette QMacStyle::standardPalette() const
+{
+ QPalette pal = QWindowsStyle::standardPalette();
+ pal.setColor(QPalette::Disabled, QPalette::Dark, QColor(191, 191, 191));
+ pal.setColor(QPalette::Active, QPalette::Dark, QColor(191, 191, 191));
+ pal.setColor(QPalette::Inactive, QPalette::Dark, QColor(191, 191, 191));
+ return pal;
+}
+
+int QMacStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *w,
+ QStyleHintReturn *hret) const
+{
+ SInt32 ret = 0;
+ switch (sh) {
+ case SH_Menu_SelectionWrap:
+ ret = false;
+ break;
+ case SH_Menu_KeyboardSearch:
+ ret = true;
+ break;
+ case SH_Menu_SpaceActivatesItem:
+ ret = true;
+ break;
+ case SH_Slider_AbsoluteSetButtons:
+ ret = Qt::LeftButton|Qt::MidButton;
+ break;
+ case SH_Slider_PageSetButtons:
+ ret = 0;
+ break;
+ case SH_ScrollBar_ContextMenu:
+ ret = false;
+ break;
+ case SH_TitleBar_AutoRaise:
+ ret = true;
+ break;
+ case SH_Menu_AllowActiveAndDisabled:
+ ret = false;
+ break;
+ case SH_Menu_SubMenuPopupDelay:
+ ret = 100;
+ break;
+ case SH_ScrollBar_LeftClickAbsolutePosition: {
+ extern bool qt_scrollbar_jump_to_pos; //qapplication_mac.cpp
+ if(QApplication::keyboardModifiers() & Qt::AltModifier)
+ ret = !qt_scrollbar_jump_to_pos;
+ else
+ ret = qt_scrollbar_jump_to_pos;
+ break; }
+ case SH_TabBar_PreferNoArrows:
+ ret = true;
+ break;
+ case SH_LineEdit_PasswordCharacter:
+ ret = kBulletUnicode;
+ break;
+ /*
+ case SH_DialogButtons_DefaultButton:
+ ret = QDialogButtons::Reject;
+ break;
+ */
+ case SH_Menu_SloppySubMenus:
+ ret = true;
+ break;
+ case SH_GroupBox_TextLabelVerticalAlignment:
+ ret = Qt::AlignTop;
+ break;
+ case SH_ScrollView_FrameOnlyAroundContents:
+ if (w && (w->isWindow() || !w->parentWidget() || w->parentWidget()->isWindow())
+ && (w->inherits("QWorkspaceChild")
+#ifdef QT3_SUPPORT
+ || w->inherits("QScrollView")
+#endif
+ ))
+ ret = true;
+ else
+ ret = QWindowsStyle::styleHint(sh, opt, w, hret);
+ break;
+ case SH_Menu_FillScreenWithScroll:
+ ret = false;
+ break;
+ case SH_Menu_Scrollable:
+ ret = true;
+ break;
+ case SH_RichText_FullWidthSelection:
+ ret = true;
+ break;
+ case SH_BlinkCursorWhenTextSelected:
+ ret = false;
+ break;
+ case SH_ScrollBar_StopMouseOverSlider:
+ ret = true;
+ break;
+ case SH_Q3ListViewExpand_SelectMouseType:
+ ret = QEvent::MouseButtonRelease;
+ break;
+ case SH_TabBar_SelectMouseType:
+ if (const QStyleOptionTabBarBaseV2 *opt2 = qstyleoption_cast<const QStyleOptionTabBarBaseV2 *>(opt)) {
+ ret = opt2->documentMode ? QEvent::MouseButtonPress : QEvent::MouseButtonRelease;
+ } else {
+ ret = QEvent::MouseButtonRelease;
+ }
+ break;
+ case SH_ComboBox_Popup:
+ if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(opt))
+ ret = !cmb->editable;
+ else
+ ret = 0;
+ break;
+ case SH_Workspace_FillSpaceOnMaximize:
+ ret = true;
+ break;
+ case SH_Widget_ShareActivation:
+ ret = true;
+ break;
+ case SH_Header_ArrowAlignment:
+ ret = Qt::AlignRight;
+ break;
+ case SH_TabBar_Alignment: {
+ if (const QTabWidget *tab = qobject_cast<const QTabWidget*>(w)) {
+ if (tab->documentMode()) {
+ ret = Qt::AlignLeft;
+ break;
+ }
+ }
+ if (const QTabBar *tab = qobject_cast<const QTabBar*>(w)) {
+ if (tab->documentMode()) {
+ ret = Qt::AlignLeft;
+ break;
+ }
+ }
+ ret = Qt::AlignCenter;
+ } break;
+ case SH_UnderlineShortcut:
+ ret = false;
+ break;
+ case SH_ToolTipLabel_Opacity:
+ ret = 242; // About 95%
+ break;
+ case SH_Button_FocusPolicy:
+ ret = Qt::TabFocus;
+ break;
+ case SH_EtchDisabledText:
+ ret = false;
+ break;
+ case SH_FocusFrame_Mask: {
+ ret = true;
+ if(QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask*>(hret)) {
+ const uchar fillR = 192, fillG = 191, fillB = 190;
+ QImage img;
+
+ QSize pixmapSize = opt->rect.size();
+ if (pixmapSize.isValid()) {
+ QPixmap pix(pixmapSize);
+ pix.fill(QColor(fillR, fillG, fillB));
+ QPainter pix_paint(&pix);
+ proxy()->drawControl(CE_FocusFrame, opt, &pix_paint, w);
+ pix_paint.end();
+ img = pix.toImage();
+ }
+
+ const QRgb *sptr = (QRgb*)img.bits(), *srow;
+ const int sbpl = img.bytesPerLine();
+ const int w = sbpl/4, h = img.height();
+
+ QImage img_mask(img.width(), img.height(), QImage::Format_ARGB32);
+ QRgb *dptr = (QRgb*)img_mask.bits(), *drow;
+ const int dbpl = img_mask.bytesPerLine();
+
+ for (int y = 0; y < h; ++y) {
+ srow = sptr+((y*sbpl)/4);
+ drow = dptr+((y*dbpl)/4);
+ for (int x = 0; x < w; ++x) {
+ const int diff = (((qRed(*srow)-fillR)*(qRed(*srow)-fillR)) +
+ ((qGreen(*srow)-fillG)*((qGreen(*srow)-fillG))) +
+ ((qBlue(*srow)-fillB)*((qBlue(*srow)-fillB))));
+ (*drow++) = (diff < 100) ? 0xffffffff : 0xff000000;
+ ++srow;
+ }
+ }
+ QBitmap qmask = QBitmap::fromImage(img_mask);
+ mask->region = QRegion(qmask);
+ }
+ break; }
+ case SH_TitleBar_NoBorder:
+ ret = 1;
+ break;
+ case SH_RubberBand_Mask:
+ ret = 0;
+ break;
+ case SH_ComboBox_LayoutDirection:
+ ret = Qt::LeftToRight;
+ break;
+ case SH_ItemView_EllipsisLocation:
+ ret = Qt::AlignHCenter;
+ break;
+ case SH_ItemView_ShowDecorationSelected:
+ ret = true;
+ break;
+ case SH_TitleBar_ModifyNotification:
+ ret = false;
+ break;
+ case SH_ScrollBar_RollBetweenButtons:
+ ret = true;
+ break;
+ case SH_WindowFrame_Mask:
+ ret = 1;
+ if (QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask *>(hret)) {
+ mask->region = opt->rect;
+ mask->region -= QRect(opt->rect.left(), opt->rect.top(), 5, 1);
+ mask->region -= QRect(opt->rect.left(), opt->rect.top() + 1, 3, 1);
+ mask->region -= QRect(opt->rect.left(), opt->rect.top() + 2, 2, 1);
+ mask->region -= QRect(opt->rect.left(), opt->rect.top() + 3, 1, 2);
+
+ mask->region -= QRect(opt->rect.right() - 4, opt->rect.top(), 5, 1);
+ mask->region -= QRect(opt->rect.right() - 2, opt->rect.top() + 1, 3, 1);
+ mask->region -= QRect(opt->rect.right() - 1, opt->rect.top() + 2, 2, 1);
+ mask->region -= QRect(opt->rect.right() , opt->rect.top() + 3, 1, 2);
+ }
+ break;
+ case SH_TabBar_ElideMode:
+ ret = Qt::ElideRight;
+ break;
+ case SH_DialogButtonLayout:
+ ret = QDialogButtonBox::MacLayout;
+ break;
+ case SH_FormLayoutWrapPolicy:
+ ret = QFormLayout::DontWrapRows;
+ break;
+ case SH_FormLayoutFieldGrowthPolicy:
+ ret = QFormLayout::FieldsStayAtSizeHint;
+ break;
+ case SH_FormLayoutFormAlignment:
+ ret = Qt::AlignHCenter | Qt::AlignTop;
+ break;
+ case SH_FormLayoutLabelAlignment:
+ ret = Qt::AlignRight;
+ break;
+ case SH_ComboBox_PopupFrameStyle:
+ ret = QFrame::NoFrame | QFrame::Plain;
+ break;
+ case SH_MessageBox_TextInteractionFlags:
+ ret = Qt::TextSelectableByMouse | Qt::LinksAccessibleByMouse | Qt::TextSelectableByKeyboard;
+ break;
+ case SH_SpellCheckUnderlineStyle:
+ ret = QTextCharFormat::DashUnderline;
+ break;
+ case SH_MessageBox_CenterButtons:
+ ret = false;
+ break;
+ case SH_MenuBar_AltKeyNavigation:
+ ret = false;
+ break;
+ case SH_ItemView_MovementWithoutUpdatingSelection:
+ ret = false;
+ break;
+ case SH_FocusFrame_AboveWidget:
+ ret = true;
+ break;
+ case SH_WizardStyle:
+ ret = QWizard::MacStyle;
+ break;
+ case SH_ItemView_ArrowKeysNavigateIntoChildren:
+ ret = false;
+ break;
+ case SH_Menu_FlashTriggeredItem:
+ ret = true;
+ break;
+ case SH_Menu_FadeOutOnHide:
+ ret = true;
+ break;
+ case SH_Menu_Mask:
+ if (opt) {
+ if (QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask*>(hret)) {
+ ret = true;
+ HIRect menuRect = CGRectMake(opt->rect.x(), opt->rect.y() + 4,
+ opt->rect.width(), opt->rect.height() - 8);
+ HIThemeMenuDrawInfo mdi;
+ mdi.version = 0;
+ if (w && qobject_cast<QMenu *>(w->parentWidget()))
+ mdi.menuType = kThemeMenuTypeHierarchical;
+ else
+ mdi.menuType = kThemeMenuTypePopUp;
+ QCFType<HIShapeRef> shape;
+ HIThemeGetMenuBackgroundShape(&menuRect, &mdi, &shape);
+ mask->region = QRegion::fromHIShapeRef(shape);
+ }
+ }
+ break;
+ case SH_ItemView_PaintAlternatingRowColorsForEmptyArea:
+ ret = true;
+ break;
+ case SH_TabBar_CloseButtonPosition:
+ ret = QTabBar::LeftSide;
+ break;
+ case SH_DockWidget_ButtonsHaveFrame:
+ ret = false;
+ break;
+ default:
+ ret = QWindowsStyle::styleHint(sh, opt, w, hret);
+ break;
+ }
+ return ret;
+}
+
+QPixmap QMacStyle::generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap,
+ const QStyleOption *opt) const
+{
+ switch (iconMode) {
+ case QIcon::Disabled: {
+ QImage img = pixmap.toImage().convertToFormat(QImage::Format_ARGB32);
+ int imgh = img.height();
+ int imgw = img.width();
+ QRgb pixel;
+ for (int y = 0; y < imgh; ++y) {
+ for (int x = 0; x < imgw; ++x) {
+ pixel = img.pixel(x, y);
+ img.setPixel(x, y, qRgba(qRed(pixel), qGreen(pixel), qBlue(pixel),
+ qAlpha(pixel) / 2));
+ }
+ }
+ return QPixmap::fromImage(img);
+ }
+ default:
+ ;
+ }
+ return QWindowsStyle::generatedIconPixmap(iconMode, pixmap, opt);
+}
+
+
+QPixmap QMacStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt,
+ const QWidget *widget) const
+{
+ // The default implementation of QStyle::standardIconImplementation() is to call standardPixmap()
+ // I don't want infinite recursion so if we do get in that situation, just return the Window's
+ // standard pixmap instead (since there is no mac-specific icon then). This should be fine until
+ // someone changes how Windows standard
+ // pixmap works.
+ static bool recursionGuard = false;
+
+ if (recursionGuard)
+ return QWindowsStyle::standardPixmap(standardPixmap, opt, widget);
+
+ recursionGuard = true;
+ QIcon icon = standardIconImplementation(standardPixmap, opt, widget);
+ recursionGuard = false;
+ int size;
+ switch (standardPixmap) {
+ default:
+ size = 32;
+ break;
+ case SP_MessageBoxCritical:
+ case SP_MessageBoxQuestion:
+ case SP_MessageBoxInformation:
+ case SP_MessageBoxWarning:
+ size = 64;
+ break;
+ }
+ return icon.pixmap(size, size);
+}
+
+void QMacStyle::setFocusRectPolicy(QWidget *w, FocusRectPolicy policy)
+{
+ switch (policy) {
+ case FocusDefault:
+ break;
+ case FocusEnabled:
+ case FocusDisabled:
+ w->setAttribute(Qt::WA_MacShowFocusRect, policy == FocusEnabled);
+ break;
+ }
+}
+
+QMacStyle::FocusRectPolicy QMacStyle::focusRectPolicy(const QWidget *w)
+{
+ return w->testAttribute(Qt::WA_MacShowFocusRect) ? FocusEnabled : FocusDisabled;
+}
+
+void QMacStyle::setWidgetSizePolicy(const QWidget *widget, WidgetSizePolicy policy)
+{
+ QWidget *wadget = const_cast<QWidget *>(widget);
+ wadget->setAttribute(Qt::WA_MacNormalSize, policy == SizeLarge);
+ wadget->setAttribute(Qt::WA_MacSmallSize, policy == SizeSmall);
+ wadget->setAttribute(Qt::WA_MacMiniSize, policy == SizeMini);
+}
+
+QMacStyle::WidgetSizePolicy QMacStyle::widgetSizePolicy(const QWidget *widget)
+{
+ while (widget) {
+ if (widget->testAttribute(Qt::WA_MacMiniSize)) {
+ return SizeMini;
+ } else if (widget->testAttribute(Qt::WA_MacSmallSize)) {
+ return SizeSmall;
+ } else if (widget->testAttribute(Qt::WA_MacNormalSize)) {
+ return SizeLarge;
+ }
+ widget = widget->parentWidget();
+ }
+ return SizeDefault;
+}
+
+void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p,
+ const QWidget *w) const
+{
+ ThemeDrawState tds = d->getDrawState(opt->state);
+ QMacCGContext cg(p);
+ switch (pe) {
+ case PE_IndicatorArrowUp:
+ case PE_IndicatorArrowDown:
+ case PE_IndicatorArrowRight:
+ case PE_IndicatorArrowLeft: {
+ p->save();
+ p->setRenderHint(QPainter::Antialiasing);
+ int xOffset = opt->direction == Qt::LeftToRight ? 2 : -1;
+ QMatrix matrix;
+ matrix.translate(opt->rect.center().x() + xOffset, opt->rect.center().y() + 2);
+ QPainterPath path;
+ switch(pe) {
+ default:
+ case PE_IndicatorArrowDown:
+ break;
+ case PE_IndicatorArrowUp:
+ matrix.rotate(180);
+ break;
+ case PE_IndicatorArrowLeft:
+ matrix.rotate(90);
+ break;
+ case PE_IndicatorArrowRight:
+ matrix.rotate(-90);
+ break;
+ }
+ path.moveTo(0, 5);
+ path.lineTo(-4, -3);
+ path.lineTo(4, -3);
+ p->setMatrix(matrix);
+ p->setPen(Qt::NoPen);
+ p->setBrush(QColor(0, 0, 0, 135));
+ p->drawPath(path);
+ p->restore();
+ break; }
+ case PE_FrameTabBarBase:
+ if (const QStyleOptionTabBarBaseV2 *tbb
+ = qstyleoption_cast<const QStyleOptionTabBarBaseV2 *>(opt)) {
+ if (tbb->documentMode) {
+ p->save();
+ drawTabBase(p, tbb, w);
+ p->restore();
+ return;
+ }
+
+ QRegion region(tbb->rect);
+ region -= tbb->tabBarRect;
+ p->save();
+ p->setClipRegion(region);
+ QStyleOptionTabWidgetFrame twf;
+ twf.QStyleOption::operator=(*tbb);
+ twf.shape = tbb->shape;
+ switch (getTabDirection(twf.shape)) {
+ case kThemeTabNorth:
+ twf.rect = twf.rect.adjusted(0, 0, 0, 10);
+ break;
+ case kThemeTabSouth:
+ twf.rect = twf.rect.adjusted(0, -10, 0, 0);
+ break;
+ case kThemeTabWest:
+ twf.rect = twf.rect.adjusted(0, 0, 10, 0);
+ break;
+ case kThemeTabEast:
+ twf.rect = twf.rect.adjusted(0, -10, 0, 0);
+ break;
+ }
+ proxy()->drawPrimitive(PE_FrameTabWidget, &twf, p, w);
+ p->restore();
+ }
+ break;
+ case PE_PanelTipLabel:
+ p->fillRect(opt->rect, opt->palette.brush(QPalette::ToolTipBase));
+ break;
+ case PE_FrameGroupBox:
+ if (const QStyleOptionFrame *groupBox = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
+ const QStyleOptionFrameV2 *frame2 = qstyleoption_cast<const QStyleOptionFrameV2 *>(opt);
+ if (frame2 && frame2->features & QStyleOptionFrameV2::Flat) {
+ QWindowsStyle::drawPrimitive(pe, groupBox, p, w);
+ } else {
+ HIThemeGroupBoxDrawInfo gdi;
+ gdi.version = qt_mac_hitheme_version;
+ gdi.state = tds;
+ if (w && qobject_cast<QGroupBox *>(w->parentWidget()))
+ gdi.kind = kHIThemeGroupBoxKindSecondary;
+ else
+ gdi.kind = kHIThemeGroupBoxKindPrimary;
+ HIRect hirect = qt_hirectForQRect(opt->rect);
+ HIThemeDrawGroupBox(&hirect, &gdi, cg, kHIThemeOrientationNormal);
+ }
+ }
+ break;
+ case PE_IndicatorToolBarSeparator: {
+ QPainterPath path;
+ if (opt->state & State_Horizontal) {
+ int xpoint = opt->rect.center().x();
+ path.moveTo(xpoint + 0.5, opt->rect.top() + 1);
+ path.lineTo(xpoint + 0.5, opt->rect.bottom());
+ } else {
+ int ypoint = opt->rect.center().y();
+ path.moveTo(opt->rect.left() + 2 , ypoint + 0.5);
+ path.lineTo(opt->rect.right() + 1, ypoint + 0.5);
+ }
+ QPainterPathStroker theStroker;
+ theStroker.setCapStyle(Qt::FlatCap);
+ theStroker.setDashPattern(QVector<qreal>() << 1 << 2);
+ path = theStroker.createStroke(path);
+ p->fillPath(path, QColor(0, 0, 0, 119));
+ }
+ break;
+ case PE_FrameWindow:
+ break;
+ case PE_IndicatorDockWidgetResizeHandle: {
+ // The docwidget resize handle is drawn as a one-pixel wide line.
+ p->save();
+ if (opt->state & State_Horizontal) {
+ p->setPen(QColor(160, 160, 160));
+ p->drawLine(opt->rect.topLeft(), opt->rect.topRight());
+ } else {
+ p->setPen(QColor(145, 145, 145));
+ p->drawLine(opt->rect.topRight(), opt->rect.bottomRight());
+ }
+ p->restore();
+ } break;
+ case PE_IndicatorToolBarHandle: {
+ p->save();
+ QPainterPath path;
+ int x = opt->rect.x() + 6;
+ int y = opt->rect.y() + 5;
+ static const int RectHeight = 2;
+ if (opt->state & State_Horizontal) {
+ while (y < opt->rect.height() - RectHeight - 6) {
+ path.moveTo(x, y);
+ path.addRect(x, y, RectHeight, RectHeight);
+ y += 6;
+ }
+ } else {
+ while (x < opt->rect.width() - RectHeight - 6) {
+ path.moveTo(x, y);
+ path.addRect(x, y, RectHeight, RectHeight);
+ x += 6;
+ }
+ }
+ p->setPen(Qt::NoPen);
+ QColor dark = opt->palette.dark().color();
+ dark.setAlphaF(0.75);
+ QColor light = opt->palette.light().color();
+ light.setAlphaF(0.6);
+ p->fillPath(path, light);
+ p->save();
+ p->translate(1, 1);
+ p->fillPath(path, dark);
+ p->restore();
+ p->translate(3, 3);
+ p->fillPath(path, light);
+ p->translate(1, 1);
+ p->fillPath(path, dark);
+ p->restore();
+
+ break;
+ }
+ case PE_IndicatorHeaderArrow:
+ if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
+ // In HITheme, up is down, down is up and hamburgers eat people.
+ if (header->sortIndicator != QStyleOptionHeader::None)
+ proxy()->drawPrimitive(
+ (header->sortIndicator == QStyleOptionHeader::SortDown) ?
+ PE_IndicatorArrowUp : PE_IndicatorArrowDown, header, p, w);
+ }
+ break;
+ case PE_IndicatorMenuCheckMark: {
+ const int checkw = 8;
+ const int checkh = 8;
+ const int xoff = qMax(0, (opt->rect.width() - checkw) / 2);
+ const int yoff = qMax(0, (opt->rect.width() - checkh) / 2);
+ const int x1 = xoff + opt->rect.x();
+ const int y1 = yoff + opt->rect.y() + checkw/2;
+ const int x2 = xoff + opt->rect.x() + checkw/4;
+ const int y2 = yoff + opt->rect.y() + checkh;
+ const int x3 = xoff + opt->rect.x() + checkw;
+ const int y3 = yoff + opt->rect.y();
+
+ QVector<QLineF> a(2);
+ a << QLineF(x1, y1, x2, y2);
+ a << QLineF(x2, y2, x3, y3);
+ if (opt->palette.currentColorGroup() == QPalette::Active)
+ p->setPen(QPen(Qt::white, 3));
+ else
+ p->setPen(QPen(QColor(100, 100, 100), 3));
+ p->save();
+ p->setRenderHint(QPainter::Antialiasing);
+ p->drawLines(a);
+ p->restore();
+ break; }
+ case PE_IndicatorViewItemCheck:
+ case PE_Q3CheckListExclusiveIndicator:
+ case PE_Q3CheckListIndicator:
+ case PE_IndicatorRadioButton:
+ case PE_IndicatorCheckBox: {
+ bool drawColorless = (!(opt->state & State_Active))
+ && opt->palette.currentColorGroup() == QPalette::Active;
+ HIThemeButtonDrawInfo bdi;
+ bdi.version = qt_mac_hitheme_version;
+ bdi.state = tds;
+ if (drawColorless && tds == kThemeStateInactive)
+ bdi.state = kThemeStateActive;
+ bdi.adornment = kThemeDrawIndicatorOnly;
+ if (opt->state & State_HasFocus)
+ bdi.adornment |= kThemeAdornmentFocus;
+ bool isRadioButton = (pe == PE_Q3CheckListExclusiveIndicator
+ || pe == PE_IndicatorRadioButton);
+ switch (d->aquaSizeConstrain(opt, w)) {
+ case QAquaSizeUnknown:
+ case QAquaSizeLarge:
+ if (isRadioButton)
+ bdi.kind = kThemeRadioButton;
+ else
+ bdi.kind = kThemeCheckBox;
+ break;
+ case QAquaSizeMini:
+ if (isRadioButton)
+ bdi.kind = kThemeMiniRadioButton;
+ else
+ bdi.kind = kThemeMiniCheckBox;
+ break;
+ case QAquaSizeSmall:
+ if (isRadioButton)
+ bdi.kind = kThemeSmallRadioButton;
+ else
+ bdi.kind = kThemeSmallCheckBox;
+ break;
+ }
+ if (opt->state & State_NoChange)
+ bdi.value = kThemeButtonMixed;
+ else if (opt->state & State_On)
+ bdi.value = kThemeButtonOn;
+ else
+ bdi.value = kThemeButtonOff;
+ HIRect macRect;
+ if (pe == PE_Q3CheckListExclusiveIndicator || pe == PE_Q3CheckListIndicator)
+ macRect = qt_hirectForQRect(opt->rect);
+ else
+ macRect = qt_hirectForQRect(opt->rect);
+ if (!drawColorless)
+ HIThemeDrawButton(&macRect, &bdi, cg, kHIThemeOrientationNormal, 0);
+ else
+ d->drawColorlessButton(macRect, &bdi, p, opt);
+ break; }
+ case PE_FrameFocusRect:
+ // Use the our own focus widget stuff.
+ break;
+ case PE_IndicatorBranch: {
+ if (!(opt->state & State_Children))
+ break;
+ HIThemeButtonDrawInfo bi;
+ bi.version = qt_mac_hitheme_version;
+ bi.state = tds;
+ if (tds == kThemeStateInactive && opt->palette.currentColorGroup() == QPalette::Active)
+ bi.state = kThemeStateActive;
+ if (opt->state & State_Sunken)
+ bi.state |= kThemeStatePressed;
+ bi.kind = kThemeDisclosureButton;
+ if (opt->state & State_Open)
+ bi.value = kThemeDisclosureDown;
+ else
+ bi.value = opt->direction == Qt::LeftToRight ? kThemeDisclosureRight : kThemeDisclosureLeft;
+ bi.adornment = kThemeAdornmentNone;
+ HIRect hirect = qt_hirectForQRect(opt->rect.adjusted(DisclosureOffset,0,-DisclosureOffset,0));
+ HIThemeDrawButton(&hirect, &bi, cg, kHIThemeOrientationNormal, 0);
+ break; }
+
+ case PE_Frame: {
+ QPen oldPen = p->pen();
+ p->setPen(opt->palette.base().color().darker(140));
+ p->drawRect(opt->rect.adjusted(0, 0, -1, -1));
+ p->setPen(opt->palette.base().color().darker(180));
+ p->drawLine(opt->rect.topLeft(), opt->rect.topRight());
+ p->setPen(oldPen);
+ break; }
+
+ case PE_FrameLineEdit:
+ if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
+ if (frame->state & State_Sunken) {
+ QColor baseColor(frame->palette.background().color());
+ HIThemeFrameDrawInfo fdi;
+ fdi.version = qt_mac_hitheme_version;
+ fdi.state = tds;
+ SInt32 frame_size;
+ if (pe == PE_FrameLineEdit) {
+ fdi.kind = kHIThemeFrameTextFieldSquare;
+ GetThemeMetric(kThemeMetricEditTextFrameOutset, &frame_size);
+ if ((frame->state & State_ReadOnly) || !(frame->state & State_Enabled))
+ fdi.state = kThemeStateInactive;
+ } else {
+ baseColor = QColor(150, 150, 150); //hardcoded since no query function --Sam
+ fdi.kind = kHIThemeFrameListBox;
+ GetThemeMetric(kThemeMetricListBoxFrameOutset, &frame_size);
+ }
+ fdi.isFocused = (frame->state & State_HasFocus);
+ int lw = frame->lineWidth;
+ if (lw <= 0)
+ lw = proxy()->pixelMetric(PM_DefaultFrameWidth, frame, w);
+ { //clear to base color
+ p->save();
+ p->setPen(QPen(baseColor, lw));
+ p->setBrush(Qt::NoBrush);
+ p->drawRect(frame->rect);
+ p->restore();
+ }
+ HIRect hirect = qt_hirectForQRect(frame->rect,
+ QRect(frame_size, frame_size,
+ frame_size * 2, frame_size * 2));
+
+ HIThemeDrawFrame(&hirect, &fdi, cg, kHIThemeOrientationNormal);
+ } else {
+ QWindowsStyle::drawPrimitive(pe, opt, p, w);
+ }
+ }
+ break;
+ case PE_PanelLineEdit:
+ QWindowsStyle::drawPrimitive(pe, opt, p, w);
+ // Draw the focus frame for widgets other than QLineEdit (e.g. for line edits in Webkit).
+ // Focus frame is drawn outside the rectangle passed in the option-rect.
+ if (const QStyleOptionFrame *panel = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
+ if ((opt->state & State_HasFocus) && !qobject_cast<const QLineEdit*>(w)) {
+ int vmargin = pixelMetric(QStyle::PM_FocusFrameVMargin);
+ int hmargin = pixelMetric(QStyle::PM_FocusFrameHMargin);
+ QStyleOptionFrame focusFrame = *panel;
+ focusFrame.rect = panel->rect.adjusted(-hmargin, -vmargin, hmargin, vmargin);
+ drawControl(CE_FocusFrame, &focusFrame, p, w);
+ }
+ }
+
+ break;
+ case PE_FrameTabWidget:
+ if (const QStyleOptionTabWidgetFrame *twf
+ = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
+ HIRect hirect = qt_hirectForQRect(twf->rect);
+ HIThemeTabPaneDrawInfo tpdi;
+ tpdi.version = qt_mac_hitheme_tab_version();
+ tpdi.state = tds;
+ tpdi.direction = getTabDirection(twf->shape);
+ tpdi.size = kHIThemeTabSizeNormal;
+ tpdi.kind = kHIThemeTabKindNormal;
+ tpdi.adornment = kHIThemeTabPaneAdornmentNormal;
+ HIThemeDrawTabPane(&hirect, &tpdi, cg, kHIThemeOrientationNormal);
+ }
+ break;
+ case PE_PanelScrollAreaCorner: {
+ const QBrush brush(opt->palette.brush(QPalette::Base));
+ p->fillRect(opt->rect, brush);
+ p->setPen(QPen(QColor(217, 217, 217)));
+ p->drawLine(opt->rect.topLeft(), opt->rect.topRight());
+ p->drawLine(opt->rect.topLeft(), opt->rect.bottomLeft());
+ } break;
+ case PE_FrameStatusBarItem:
+ break;
+ case PE_IndicatorTabClose: {
+ bool hover = (opt->state & State_MouseOver);
+ bool selected = (opt->state & State_Selected);
+ bool active = (opt->state & State_Active);
+ drawTabCloseButton(p, hover, active, selected);
+ } break;
+ case PE_PanelStatusBar: {
+ if (QSysInfo::MacintoshVersion <= QSysInfo::MV_10_4) {
+ QWindowsStyle::drawPrimitive(pe, opt, p, w);
+ break;
+ }
+ // Use the Leopard style only if the status bar is the status bar for a
+ // QMainWindow with a unifed toolbar.
+ if (w == 0 || w->parent() == 0 || qobject_cast<QMainWindow *>(w->parent()) == 0 ||
+ qobject_cast<QMainWindow *>(w->parent())->unifiedTitleAndToolBarOnMac() == false ) {
+ QWindowsStyle::drawPrimitive(pe, opt, p, w);
+ break;
+ }
+
+ // Fill the status bar with the titlebar gradient.
+ QLinearGradient linearGrad(0, opt->rect.top(), 0, opt->rect.bottom());
+ if (opt->state & QStyle::State_Active) {
+ linearGrad.setColorAt(0, titlebarGradientActiveBegin);
+ linearGrad.setColorAt(1, titlebarGradientActiveEnd);
+ } else {
+ linearGrad.setColorAt(0, titlebarGradientInactiveBegin);
+ linearGrad.setColorAt(1, titlebarGradientInactiveEnd);
+ }
+ p->fillRect(opt->rect, linearGrad);
+
+ // Draw the black separator line at the top of the status bar.
+ if (opt->state & QStyle::State_Active)
+ p->setPen(titlebarSeparatorLineActive);
+ else
+ p->setPen(titlebarSeparatorLineInactive);
+ p->drawLine(opt->rect.left(), opt->rect.top(), opt->rect.right(), opt->rect.top());
+
+ break;
+ }
+
+ default:
+ QWindowsStyle::drawPrimitive(pe, opt, p, w);
+ break;
+ }
+}
+
+static inline QPixmap darkenPixmap(const QPixmap &pixmap)
+{
+ QImage img = pixmap.toImage().convertToFormat(QImage::Format_ARGB32);
+ int imgh = img.height();
+ int imgw = img.width();
+ int h, s, v, a;
+ QRgb pixel;
+ for (int y = 0; y < imgh; ++y) {
+ for (int x = 0; x < imgw; ++x) {
+ pixel = img.pixel(x, y);
+ a = qAlpha(pixel);
+ QColor hsvColor(pixel);
+ hsvColor.getHsv(&h, &s, &v);
+ s = qMin(100, s * 2);
+ v = v / 2;
+ hsvColor.setHsv(h, s, v);
+ pixel = hsvColor.rgb();
+ img.setPixel(x, y, qRgba(qRed(pixel), qGreen(pixel), qBlue(pixel), a));
+ }
+ }
+ return QPixmap::fromImage(img);
+}
+
+
+
+void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter *p,
+ const QWidget *w) const
+{
+ ThemeDrawState tds = d->getDrawState(opt->state);
+ QMacCGContext cg(p);
+ switch (ce) {
+ case CE_HeaderSection:
+ if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
+ HIThemeButtonDrawInfo bdi;
+ bdi.version = qt_mac_hitheme_version;
+ State flags = header->state;
+ QRect ir = header->rect;
+ bdi.kind = kThemeListHeaderButton;
+ bdi.adornment = kThemeAdornmentNone;
+ bdi.state = kThemeStateActive;
+
+ if (flags & State_On)
+ bdi.value = kThemeButtonOn;
+ else
+ bdi.value = kThemeButtonOff;
+
+ if (header->orientation == Qt::Horizontal){
+ switch (header->position) {
+ case QStyleOptionHeader::Beginning:
+ ir.adjust(-1, -1, 0, 0);
+ break;
+ case QStyleOptionHeader::Middle:
+ ir.adjust(-1, -1, 0, 0);
+ break;
+ case QStyleOptionHeader::OnlyOneSection:
+ case QStyleOptionHeader::End:
+ ir.adjust(-1, -1, 1, 0);
+ break;
+ default:
+ break;
+ }
+
+ if (header->position != QStyleOptionHeader::Beginning
+ && header->position != QStyleOptionHeader::OnlyOneSection) {
+ bdi.adornment = header->direction == Qt::LeftToRight
+ ? kThemeAdornmentHeaderButtonLeftNeighborSelected
+ : kThemeAdornmentHeaderButtonRightNeighborSelected;
+ }
+ }
+
+ if (flags & State_Active) {
+ if (!(flags & State_Enabled))
+ bdi.state = kThemeStateUnavailable;
+ else if (flags & State_Sunken)
+ bdi.state = kThemeStatePressed;
+ } else {
+ if (flags & State_Enabled)
+ bdi.state = kThemeStateInactive;
+ else
+ bdi.state = kThemeStateUnavailableInactive;
+ }
+
+ if (header->sortIndicator != QStyleOptionHeader::None) {
+ bdi.value = kThemeButtonOn;
+ if (header->sortIndicator == QStyleOptionHeader::SortDown)
+ bdi.adornment = kThemeAdornmentHeaderButtonSortUp;
+ }
+ if (flags & State_HasFocus)
+ bdi.adornment = kThemeAdornmentFocus;
+
+ ir = visualRect(header->direction, header->rect, ir);
+ HIRect bounds = qt_hirectForQRect(ir);
+
+ bool noVerticalHeader = true;
+ if (w)
+ if (const QTableView *table = qobject_cast<const QTableView *>(w->parentWidget()))
+ noVerticalHeader = !table->verticalHeader()->isVisible();
+
+ bool drawTopBorder = header->orientation == Qt::Horizontal;
+ bool drawLeftBorder = header->orientation == Qt::Vertical
+ || header->position == QStyleOptionHeader::OnlyOneSection
+ || (header->position == QStyleOptionHeader::Beginning && noVerticalHeader);
+ d->drawTableHeader(bounds, drawTopBorder, drawLeftBorder, bdi, p);
+ }
+ break;
+ case CE_HeaderLabel:
+ if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
+ QRect textr = header->rect;
+ if (!header->icon.isNull()) {
+ QIcon::Mode mode = QIcon::Disabled;
+ if (opt->state & State_Enabled)
+ mode = QIcon::Normal;
+ QPixmap pixmap = header->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize), mode);
+
+ QRect pixr = header->rect;
+ pixr.setY(header->rect.center().y() - (pixmap.height() - 1) / 2);
+ proxy()->drawItemPixmap(p, pixr, Qt::AlignVCenter, pixmap);
+ textr.translate(pixmap.width() + 2, 0);
+ }
+
+ proxy()->drawItemText(p, textr, header->textAlignment | Qt::AlignVCenter, header->palette,
+ header->state & State_Enabled, header->text, QPalette::ButtonText);
+ }
+ break;
+ case CE_ToolButtonLabel:
+ if (const QStyleOptionToolButton *tb = qstyleoption_cast<const QStyleOptionToolButton *>(opt)) {
+ QStyleOptionToolButton myTb = *tb;
+ myTb.state &= ~State_AutoRaise;
+ if (w && qobject_cast<QToolBar *>(w->parentWidget())) {
+ QRect cr = tb->rect;
+ int shiftX = 0;
+ int shiftY = 0;
+ bool needText = false;
+ int alignment = 0;
+ bool down = tb->state & (State_Sunken | State_On);
+ if (down) {
+ shiftX = proxy()->pixelMetric(PM_ButtonShiftHorizontal, tb, w);
+ shiftY = proxy()->pixelMetric(PM_ButtonShiftVertical, tb, w);
+ }
+ // The down state is special for QToolButtons in a toolbar on the Mac
+ // The text is a bit bolder and gets a drop shadow and the icons are also darkened.
+ // This doesn't really fit into any particular case in QIcon, so we
+ // do the majority of the work ourselves.
+ if (!(tb->features & QStyleOptionToolButton::Arrow)) {
+ Qt::ToolButtonStyle tbstyle = tb->toolButtonStyle;
+ if (tb->icon.isNull() && !tb->text.isEmpty())
+ tbstyle = Qt::ToolButtonTextOnly;
+
+ switch (tbstyle) {
+ case Qt::ToolButtonTextOnly: {
+ needText = true;
+ alignment = Qt::AlignCenter;
+ break; }
+ case Qt::ToolButtonIconOnly:
+ case Qt::ToolButtonTextBesideIcon:
+ case Qt::ToolButtonTextUnderIcon: {
+ QRect pr = cr;
+ QIcon::Mode iconMode = (tb->state & State_Enabled) ? QIcon::Normal
+ : QIcon::Disabled;
+ QIcon::State iconState = (tb->state & State_On) ? QIcon::On
+ : QIcon::Off;
+ QPixmap pixmap = tb->icon.pixmap(tb->rect.size().boundedTo(tb->iconSize), iconMode, iconState);
+
+ // Draw the text if it's needed.
+ if (tb->toolButtonStyle != Qt::ToolButtonIconOnly) {
+ needText = true;
+ if (tb->toolButtonStyle == Qt::ToolButtonTextUnderIcon) {
+ QMainWindow *mw = qobject_cast<QMainWindow *>(w->window());
+ if (mw && mw->unifiedTitleAndToolBarOnMac()) {
+ pr.setHeight(pixmap.size().height());
+ cr.adjust(0, pr.bottom() + 1, 0, 1);
+ } else {
+ pr.setHeight(pixmap.size().height() + 6);
+ cr.adjust(0, pr.bottom(), 0, -3);
+ }
+ alignment |= Qt::AlignCenter;
+ } else {
+ pr.setWidth(pixmap.width() + 8);
+ cr.adjust(pr.right(), 0, 0, 0);
+ alignment |= Qt::AlignLeft | Qt::AlignVCenter;
+ }
+ }
+ if (opt->state & State_Sunken) {
+ pr.translate(shiftX, shiftY);
+ pixmap = darkenPixmap(pixmap);
+ }
+ proxy()->drawItemPixmap(p, pr, Qt::AlignCenter, pixmap);
+ break; }
+ default:
+ Q_ASSERT(false);
+ break;
+ }
+
+ if (needText) {
+ QPalette pal = tb->palette;
+ QPalette::ColorRole role = QPalette::NoRole;
+ if (!proxy()->styleHint(SH_UnderlineShortcut, tb, w))
+ alignment |= Qt::TextHideMnemonic;
+ if (down)
+ cr.translate(shiftX, shiftY);
+ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5
+ && (tbstyle == Qt::ToolButtonTextOnly
+ || (tbstyle != Qt::ToolButtonTextOnly && !down))) {
+ QPen pen = p->pen();
+ QColor light = down ? Qt::black : Qt::white;
+ light.setAlphaF(0.375f);
+ p->setPen(light);
+ p->drawText(cr.adjusted(0, 1, 0, 1), alignment, tb->text);
+ p->setPen(pen);
+ if (down && tbstyle == Qt::ToolButtonTextOnly) {
+ pal = QApplication::palette("QMenu");
+ pal.setCurrentColorGroup(tb->palette.currentColorGroup());
+ role = QPalette::HighlightedText;
+ }
+ }
+ proxy()->drawItemText(p, cr, alignment, pal,
+ tb->state & State_Enabled, tb->text, role);
+ if (QSysInfo::MacintoshVersion < QSysInfo::MV_10_5 &&
+ (tb->state & State_Sunken)) {
+ // Draw a "drop shadow" in earlier versions.
+ proxy()->drawItemText(p, cr.adjusted(0, 1, 0, 1), alignment,
+ tb->palette, tb->state & State_Enabled, tb->text);
+ }
+ }
+ } else {
+ QWindowsStyle::drawControl(ce, &myTb, p, w);
+ }
+ } else {
+ QWindowsStyle::drawControl(ce, &myTb, p, w);
+ }
+ }
+ break;
+ case CE_ToolBoxTabShape:
+ QCommonStyle::drawControl(ce, opt, p, w);
+ break;
+ case CE_PushButtonBevel:
+ if (const QStyleOptionButton *btn = ::qstyleoption_cast<const QStyleOptionButton *>(opt)) {
+ if (!(btn->state & (State_Raised | State_Sunken | State_On)))
+ break;
+
+ if (btn->features & QStyleOptionButton::CommandLinkButton) {
+ QWindowsStyle::drawControl(ce, opt, p, w);
+ break;
+ }
+
+ HIThemeButtonDrawInfo bdi;
+ d->initHIThemePushButton(btn, w, tds, &bdi);
+ if (btn->features & QStyleOptionButton::DefaultButton
+ && d->animatable(QMacStylePrivate::AquaPushButton, w)) {
+ bdi.adornment |= kThemeAdornmentDefault;
+ bdi.animation.time.start = d->defaultButtonStart;
+ bdi.animation.time.current = CFAbsoluteTimeGetCurrent();
+ if (d->timerID <= -1)
+ QMetaObject::invokeMethod(d, "startAnimationTimer", Qt::QueuedConnection);
+ }
+ // Unlike Carbon, we want the button to always be drawn inside its bounds.
+ // Therefore, make the button a bit smaller, so that even if it got focus,
+ // the focus 'shadow' will be inside.
+ HIRect newRect = qt_hirectForQRect(btn->rect);
+ if (bdi.kind == kThemePushButton || bdi.kind == kThemePushButtonSmall) {
+ newRect.origin.x += QMacStylePrivate::PushButtonLeftOffset;
+ newRect.origin.y += QMacStylePrivate::PushButtonTopOffset;
+ newRect.size.width -= QMacStylePrivate::PushButtonRightOffset;
+ newRect.size.height -= QMacStylePrivate::PushButtonBottomOffset;
+ } else if (bdi.kind == kThemePushButtonMini) {
+ newRect.origin.x += QMacStylePrivate::PushButtonLeftOffset - 2;
+ newRect.origin.y += QMacStylePrivate::PushButtonTopOffset;
+ newRect.size.width -= QMacStylePrivate::PushButtonRightOffset - 4;
+ }
+ HIThemeDrawButton(&newRect, &bdi, cg, kHIThemeOrientationNormal, 0);
+
+ if (btn->features & QStyleOptionButton::HasMenu) {
+ int mbi = proxy()->pixelMetric(QStyle::PM_MenuButtonIndicator, btn, w);
+ QRect ir = btn->rect;
+ HIRect arrowRect = CGRectMake(ir.right() - mbi - QMacStylePrivate::PushButtonRightOffset,
+ ir.height() / 2 - 4, mbi, ir.height() / 2);
+ bool drawColorless = btn->palette.currentColorGroup() == QPalette::Active;
+ if (drawColorless && tds == kThemeStateInactive)
+ tds = kThemeStateActive;
+
+ HIThemePopupArrowDrawInfo pdi;
+ pdi.version = qt_mac_hitheme_version;
+ pdi.state = tds;
+ pdi.orientation = kThemeArrowDown;
+ if (arrowRect.size.width < 8.)
+ pdi.size = kThemeArrow5pt;
+ else
+ pdi.size = kThemeArrow9pt;
+ HIThemeDrawPopupArrow(&arrowRect, &pdi, cg, kHIThemeOrientationNormal);
+ }
+ }
+ break;
+ case CE_PushButtonLabel:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
+ // We really don't want the label to be drawn the same as on
+ // windows style if it has an icon and text, then it should be more like a
+ // tab. So, cheat a little here. However, if it *is* only an icon
+ // the windows style works great, so just use that implementation.
+ bool hasMenu = btn->features & QStyleOptionButton::HasMenu;
+ bool hasIcon = !btn->icon.isNull();
+ bool hasText = !btn->text.isEmpty();
+ if (!hasIcon && !hasMenu) {
+ // ### this is really overly difficult, simplify.
+ // It basically tries to get the right font for "small" and "mini" icons.
+ QFont oldFont = p->font();
+ QFont newFont = qt_app_fonts_hash()->value("QPushButton", QFont());
+ ThemeFontID themeId = kThemePushButtonFont;
+ if (oldFont == newFont) { // Yes, use HITheme to draw the text for small sizes.
+ switch (d->aquaSizeConstrain(opt, w)) {
+ default:
+ break;
+ case QAquaSizeSmall:
+ themeId = kThemeSmallSystemFont;
+ break;
+ case QAquaSizeMini:
+ themeId = kThemeMiniSystemFont;
+ break;
+ }
+ }
+ if (themeId == kThemePushButtonFont) {
+ QWindowsStyle::drawControl(ce, btn, p, w);
+ } else {
+ p->save();
+ CGContextSetShouldAntialias(cg, true);
+ CGContextSetShouldSmoothFonts(cg, true);
+ HIThemeTextInfo tti;
+ tti.version = qt_mac_hitheme_version;
+ tti.state = tds;
+ QColor textColor = btn->palette.buttonText().color();
+ CGFloat colorComp[] = { textColor.redF(), textColor.greenF(),
+ textColor.blueF(), textColor.alphaF() };
+ CGContextSetFillColorSpace(cg, QCoreGraphicsPaintEngine::macGenericColorSpace());
+ CGContextSetFillColor(cg, colorComp);
+ tti.fontID = themeId;
+ tti.horizontalFlushness = kHIThemeTextHorizontalFlushCenter;
+ tti.verticalFlushness = kHIThemeTextVerticalFlushCenter;
+ tti.options = kHIThemeTextBoxOptionNone;
+ tti.truncationPosition = kHIThemeTextTruncationNone;
+ tti.truncationMaxLines = 1 + btn->text.count(QLatin1Char('\n'));
+ QCFString buttonText = qt_mac_removeMnemonics(btn->text);
+ QRect r = btn->rect;
+ HIRect bounds = qt_hirectForQRect(r);
+ HIThemeDrawTextBox(buttonText, &bounds, &tti,
+ cg, kHIThemeOrientationNormal);
+ p->restore();
+ }
+ } else {
+ if (hasIcon && !hasText) {
+ QWindowsStyle::drawControl(ce, btn, p, w);
+ } else {
+ QRect freeContentRect = btn->rect;
+ QRect textRect = itemTextRect(
+ btn->fontMetrics, freeContentRect, Qt::AlignCenter, btn->state & State_Enabled, btn->text);
+ if (hasMenu)
+ textRect.adjust(-1, 0, -1, 0);
+ // Draw the icon:
+ if (hasIcon) {
+ int contentW = textRect.width();
+ if (hasMenu)
+ contentW += proxy()->pixelMetric(PM_MenuButtonIndicator) + 4;
+ QIcon::Mode mode = btn->state & State_Enabled ? QIcon::Normal : QIcon::Disabled;
+ if (mode == QIcon::Normal && btn->state & State_HasFocus)
+ mode = QIcon::Active;
+ // Decide if the icon is should be on or off:
+ QIcon::State state = QIcon::Off;
+ if (btn->state & State_On)
+ state = QIcon::On;
+ QPixmap pixmap = btn->icon.pixmap(btn->iconSize, mode, state);
+ contentW += pixmap.width() + QMacStylePrivate::PushButtonContentPadding;
+ int iconLeftOffset = freeContentRect.x() + (freeContentRect.width() - contentW) / 2;
+ int iconTopOffset = freeContentRect.y() + (freeContentRect.height() - pixmap.height()) / 2;
+ QRect iconDestRect(iconLeftOffset, iconTopOffset, pixmap.width(), pixmap.height());
+ QRect visualIconDestRect = visualRect(btn->direction, freeContentRect, iconDestRect);
+ proxy()->drawItemPixmap(p, visualIconDestRect, Qt::AlignLeft | Qt::AlignVCenter, pixmap);
+ int newOffset = iconDestRect.x() + iconDestRect.width()
+ + QMacStylePrivate::PushButtonContentPadding - textRect.x();
+ textRect.adjust(newOffset, 0, newOffset, 0);
+ }
+ // Draw the text:
+ if (hasText) {
+ textRect = visualRect(btn->direction, freeContentRect, textRect);
+ proxy()->drawItemText(p, textRect, Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic, btn->palette,
+ (btn->state & State_Enabled), btn->text, QPalette::ButtonText);
+ }
+ }
+ }
+ }
+ break;
+ case CE_ComboBoxLabel:
+ if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
+ QStyleOptionComboBox comboCopy = *cb;
+ comboCopy.direction = Qt::LeftToRight;
+ QWindowsStyle::drawControl(CE_ComboBoxLabel, &comboCopy, p, w);
+ }
+ break;
+ case CE_TabBarTabShape:
+ 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;
+ }
+ }
+ HIThemeTabDrawInfo tdi;
+ tdi.version = 1;
+ tdi.style = kThemeTabNonFront;
+ tdi.direction = getTabDirection(tabOpt->shape);
+ switch (d->aquaSizeConstrain(opt, w)) {
+ default:
+ case QAquaSizeUnknown:
+ case QAquaSizeLarge:
+ tdi.size = kHIThemeTabSizeNormal;
+ break;
+ case QAquaSizeSmall:
+ tdi.size = kHIThemeTabSizeSmall;
+ break;
+ case QAquaSizeMini:
+ tdi.size = kHIThemeTabSizeMini;
+ break;
+ }
+ bool verticalTabs = tdi.direction == kThemeTabWest || tdi.direction == kThemeTabEast;
+ QRect tabRect = tabOpt->rect;
+
+ bool selected = tabOpt->state & State_Selected;
+ if (selected) {
+ if (!(tabOpt->state & State_Active))
+ tdi.style = kThemeTabFrontUnavailable;
+ else if (!(tabOpt->state & State_Enabled))
+ tdi.style = kThemeTabFrontInactive;
+ else
+ tdi.style = kThemeTabFront;
+ } else if (!(tabOpt->state & State_Active)) {
+ tdi.style = kThemeTabNonFrontUnavailable;
+ } else if (!(tabOpt->state & State_Enabled)) {
+ tdi.style = kThemeTabNonFrontInactive;
+ } else if (tabOpt->state & State_Sunken) {
+ tdi.style = kThemeTabFrontInactive; // (should be kThemeTabNonFrontPressed)
+ }
+ if (tabOpt->state & State_HasFocus)
+ tdi.adornment = kHIThemeTabAdornmentFocus;
+ else
+ tdi.adornment = kHIThemeTabAdornmentNone;
+ tdi.kind = kHIThemeTabKindNormal;
+ if (!verticalTabs)
+ tabRect.setY(tabRect.y() - 1);
+ else
+ tabRect.setX(tabRect.x() - 1);
+ QStyleOptionTab::TabPosition tp = tabOpt->position;
+ QStyleOptionTab::SelectedPosition sp = tabOpt->selectedPosition;
+ if (tabOpt->direction == Qt::RightToLeft && !verticalTabs) {
+ if (sp == QStyleOptionTab::NextIsSelected)
+ sp = QStyleOptionTab::PreviousIsSelected;
+ else if (sp == QStyleOptionTab::PreviousIsSelected)
+ sp = QStyleOptionTab::NextIsSelected;
+ switch (tp) {
+ case QStyleOptionTab::Beginning:
+ tp = QStyleOptionTab::End;
+ break;
+ case QStyleOptionTab::End:
+ tp = QStyleOptionTab::Beginning;
+ break;
+ default:
+ break;
+ }
+ }
+ bool stretchTabs = (!verticalTabs && tabRect.height() > 22) || (verticalTabs && tabRect.width() > 22);
+
+ switch (tp) {
+ case QStyleOptionTab::Beginning:
+ tdi.position = kHIThemeTabPositionFirst;
+ if (sp != QStyleOptionTab::NextIsSelected || stretchTabs)
+ tdi.adornment |= kHIThemeTabAdornmentTrailingSeparator;
+ break;
+ case QStyleOptionTab::Middle:
+ tdi.position = kHIThemeTabPositionMiddle;
+ if (selected)
+ tdi.adornment |= kHIThemeTabAdornmentLeadingSeparator;
+ if (sp != QStyleOptionTab::NextIsSelected || stretchTabs) // Also when we're selected.
+ tdi.adornment |= kHIThemeTabAdornmentTrailingSeparator;
+ break;
+ case QStyleOptionTab::End:
+ tdi.position = kHIThemeTabPositionLast;
+ if (selected)
+ tdi.adornment |= kHIThemeTabAdornmentLeadingSeparator;
+ break;
+ case QStyleOptionTab::OnlyOneTab:
+ tdi.position = kHIThemeTabPositionOnly;
+ break;
+ }
+ // HITheme doesn't stretch its tabs. Therefore we have to cheat and do the job ourselves.
+ if (stretchTabs) {
+ HIRect hirect = CGRectMake(0, 0, 23, 23);
+ QPixmap pm(23, 23);
+ pm.fill(Qt::transparent);
+ {
+ QMacCGContext pmcg(&pm);
+ HIThemeDrawTab(&hirect, &tdi, pmcg, kHIThemeOrientationNormal, 0);
+ }
+ QStyleHelper::drawBorderPixmap(pm, p, tabRect, 7, 7, 7, 7);
+ } else {
+ HIRect hirect = qt_hirectForQRect(tabRect);
+ HIThemeDrawTab(&hirect, &tdi, cg, kHIThemeOrientationNormal, 0);
+ }
+ }
+ break;
+ case CE_TabBarTabLabel:
+ if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
+ QStyleOptionTabV3 myTab = *tab;
+ ThemeTabDirection ttd = getTabDirection(myTab.shape);
+ bool verticalTabs = ttd == kThemeTabWest || ttd == kThemeTabEast;
+
+ // Check to see if we use have the same as the system font
+ // (QComboMenuItem is internal and should never be seen by the
+ // outside world, unless they read the source, in which case, it's
+ // their own fault).
+ bool nonDefaultFont = p->font() != qt_app_fonts_hash()->value("QComboMenuItem");
+ if (verticalTabs || nonDefaultFont || !tab->icon.isNull()
+ || !myTab.leftButtonSize.isNull() || !myTab.rightButtonSize.isNull()) {
+ int heightOffset = 0;
+ if (verticalTabs) {
+ heightOffset = -1;
+ } else if (nonDefaultFont) {
+ if (p->fontMetrics().height() == myTab.rect.height())
+ heightOffset = 2;
+ }
+ myTab.rect.setHeight(myTab.rect.height() + heightOffset);
+
+ if (myTab.documentMode) {
+ p->save();
+ rotateTabPainter(p, myTab.shape, myTab.rect);
+
+ QPalette np = tab->palette;
+ np.setColor(QPalette::WindowText, QColor(255, 255, 255, 75));
+ QRect nr = subElementRect(SE_TabBarTabText, opt, w);
+ nr.moveTop(-1);
+ int alignment = Qt::AlignCenter | Qt::TextShowMnemonic | Qt::TextHideMnemonic;
+ proxy()->drawItemText(p, nr, alignment, np, tab->state & State_Enabled,
+ tab->text, QPalette::WindowText);
+ p->restore();
+ }
+
+ QCommonStyle::drawControl(ce, &myTab, p, w);
+ } else {
+ p->save();
+ CGContextSetShouldAntialias(cg, true);
+ CGContextSetShouldSmoothFonts(cg, true);
+ HIThemeTextInfo tti;
+ tti.version = qt_mac_hitheme_version;
+ tti.state = tds;
+ QColor textColor = myTab.palette.windowText().color();
+ CGFloat colorComp[] = { textColor.redF(), textColor.greenF(),
+ textColor.blueF(), textColor.alphaF() };
+ CGContextSetFillColorSpace(cg, QCoreGraphicsPaintEngine::macGenericColorSpace());
+ CGContextSetFillColor(cg, colorComp);
+ switch (d->aquaSizeConstrain(opt, w)) {
+ default:
+ case QAquaSizeUnknown:
+ case QAquaSizeLarge:
+ tti.fontID = kThemeSystemFont;
+ break;
+ case QAquaSizeSmall:
+ tti.fontID = kThemeSmallSystemFont;
+ break;
+ case QAquaSizeMini:
+ tti.fontID = kThemeMiniSystemFont;
+ break;
+ }
+ tti.horizontalFlushness = kHIThemeTextHorizontalFlushCenter;
+ tti.verticalFlushness = kHIThemeTextVerticalFlushCenter;
+ tti.options = verticalTabs ? kHIThemeTextBoxOptionStronglyVertical : kHIThemeTextBoxOptionNone;
+ tti.truncationPosition = kHIThemeTextTruncationNone;
+ tti.truncationMaxLines = 1 + myTab.text.count(QLatin1Char('\n'));
+ QCFString tabText = qt_mac_removeMnemonics(myTab.text);
+ QRect r = myTab.rect.adjusted(0, 0, 0, -1);
+ HIRect bounds = qt_hirectForQRect(r);
+ HIThemeDrawTextBox(tabText, &bounds, &tti, cg, kHIThemeOrientationNormal);
+ p->restore();
+ }
+ }
+ break;
+ case CE_DockWidgetTitle:
+ if (const QDockWidget *dockWidget = qobject_cast<const QDockWidget *>(w)) {
+ bool floating = dockWidget->isFloating();
+ if (floating) {
+ ThemeDrawState tds = d->getDrawState(opt->state);
+ HIThemeWindowDrawInfo wdi;
+ wdi.version = qt_mac_hitheme_version;
+ wdi.state = tds;
+ wdi.windowType = kThemeMovableDialogWindow;
+ wdi.titleHeight = opt->rect.height();
+ wdi.titleWidth = opt->rect.width();
+ wdi.attributes = 0;
+
+ HIRect titleBarRect;
+ HIRect tmpRect = qt_hirectForQRect(opt->rect);
+ {
+ QCFType<HIShapeRef> titleRegion;
+ QRect newr = opt->rect.adjusted(0, 0, 2, 0);
+ HIThemeGetWindowShape(&tmpRect, &wdi, kWindowTitleBarRgn, &titleRegion);
+ ptrHIShapeGetBounds(titleRegion, &tmpRect);
+ newr.translate(newr.x() - int(tmpRect.origin.x), newr.y() - int(tmpRect.origin.y));
+ titleBarRect = qt_hirectForQRect(newr);
+ }
+ QMacCGContext cg(p);
+ HIThemeDrawWindowFrame(&titleBarRect, &wdi, cg, kHIThemeOrientationNormal, 0);
+ } else {
+ // fill title bar background
+ QLinearGradient linearGrad(0, opt->rect.top(), 0, opt->rect.bottom());
+ linearGrad.setColorAt(0, mainWindowGradientBegin);
+ linearGrad.setColorAt(1, mainWindowGradientEnd);
+ p->fillRect(opt->rect, linearGrad);
+
+ // draw horizontal lines at top and bottom
+ p->save();
+ p->setPen(mainWindowGradientBegin.lighter(114));
+ p->drawLine(opt->rect.topLeft(), opt->rect.topRight());
+ p->setPen(mainWindowGradientEnd.darker(114));
+ p->drawLine(opt->rect.bottomLeft(), opt->rect.bottomRight());
+ p->restore();
+ }
+ }
+
+ // Draw the text...
+ if (const QStyleOptionDockWidget *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(opt)) {
+ if (!dwOpt->title.isEmpty()) {
+ const QStyleOptionDockWidgetV2 *v2
+ = qstyleoption_cast<const QStyleOptionDockWidgetV2*>(dwOpt);
+ bool verticalTitleBar = v2 == 0 ? false : v2->verticalTitleBar;
+
+ QRect titleRect = subElementRect(SE_DockWidgetTitleBarText, opt, w);
+ if (verticalTitleBar) {
+ QRect rect = dwOpt->rect;
+ QRect r = rect;
+ QSize s = r.size();
+ s.transpose();
+ r.setSize(s);
+
+ titleRect = QRect(r.left() + rect.bottom()
+ - titleRect.bottom(),
+ r.top() + titleRect.left() - rect.left(),
+ titleRect.height(), titleRect.width());
+
+ p->translate(r.left(), r.top() + r.width());
+ p->rotate(-90);
+ p->translate(-r.left(), -r.top());
+ }
+
+ QFont oldFont = p->font();
+ p->setFont(qt_app_fonts_hash()->value("QToolButton", p->font()));
+ QString text = p->fontMetrics().elidedText(dwOpt->title, Qt::ElideRight,
+ titleRect.width());
+ drawItemText(p, titleRect,
+ Qt::AlignCenter | Qt::TextShowMnemonic, dwOpt->palette,
+ dwOpt->state & State_Enabled, text,
+ QPalette::WindowText);
+ p->setFont(oldFont);
+ }
+ }
+ break;
+ case CE_FocusFrame: {
+ int xOff = proxy()->pixelMetric(PM_FocusFrameHMargin, opt, w) + 1;
+ int yOff = proxy()->pixelMetric(PM_FocusFrameVMargin, opt, w) + 1;
+ HIRect hirect = CGRectMake(xOff+opt->rect.x(), yOff+opt->rect.y(), opt->rect.width() - 2 * xOff,
+ opt->rect.height() - 2 * yOff);
+ HIThemeDrawFocusRect(&hirect, true, QMacCGContext(p), kHIThemeOrientationNormal);
+ break; }
+ case CE_MenuItem:
+ case CE_MenuEmptyArea:
+ if (const QStyleOptionMenuItem *mi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
+ p->fillRect(mi->rect, opt->palette.background());
+ QAquaWidgetSize widgetSize = d->aquaSizeConstrain(opt, w);
+ int tabwidth = mi->tabWidth;
+ int maxpmw = mi->maxIconWidth;
+ bool active = mi->state & State_Selected;
+ bool enabled = mi->state & State_Enabled;
+ HIRect menuRect = qt_hirectForQRect(mi->menuRect);
+ HIRect itemRect = qt_hirectForQRect(mi->rect);
+ HIThemeMenuItemDrawInfo mdi;
+ mdi.version = qt_mac_hitheme_version;
+ mdi.itemType = kThemeMenuItemPlain;
+ if (!mi->icon.isNull())
+ mdi.itemType |= kThemeMenuItemHasIcon;
+ if (mi->menuItemType == QStyleOptionMenuItem::SubMenu)
+ mdi.itemType |= kThemeMenuItemHierarchical | kThemeMenuItemHierBackground;
+ else
+ mdi.itemType |= kThemeMenuItemPopUpBackground;
+ if (enabled)
+ mdi.state = kThemeMenuActive;
+ else
+ mdi.state = kThemeMenuDisabled;
+ if (active)
+ mdi.state |= kThemeMenuSelected;
+ QRect contentRect;
+ if (mi->menuItemType == QStyleOptionMenuItem::Separator) {
+ // First arg should be &menurect, but wacky stuff happens then.
+ HIThemeDrawMenuSeparator(&itemRect, &itemRect, &mdi,
+ cg, kHIThemeOrientationNormal);
+ break;
+ } else {
+ HIRect cr;
+ bool needAlpha = mi->palette.color(QPalette::Button) == Qt::transparent;
+ if (needAlpha) {
+ needAlpha = true;
+ CGContextSaveGState(cg);
+ CGContextSetAlpha(cg, 0.0);
+ }
+ HIThemeDrawMenuItem(&menuRect, &itemRect, &mdi,
+ cg, kHIThemeOrientationNormal, &cr);
+ if (needAlpha)
+ CGContextRestoreGState(cg);
+ if (ce == CE_MenuEmptyArea)
+ break;
+ contentRect = qt_qrectForHIRect(cr);
+ }
+ int xpos = contentRect.x() + 18;
+ int checkcol = maxpmw;
+ if (!enabled)
+ p->setPen(mi->palette.text().color());
+ else if (active)
+ p->setPen(mi->palette.highlightedText().color());
+ else
+ p->setPen(mi->palette.buttonText().color());
+
+ if (mi->checked) {
+ // Use the HIThemeTextInfo foo to draw the check mark correctly, if we do it,
+ // we somehow need to use a special encoding as it doesn't look right with our
+ // drawText().
+ p->save();
+ CGContextSetShouldAntialias(cg, true);
+ CGContextSetShouldSmoothFonts(cg, true);
+ QColor textColor = p->pen().color();
+ CGFloat colorComp[] = { textColor.redF(), textColor.greenF(),
+ textColor.blueF(), textColor.alphaF() };
+ CGContextSetFillColorSpace(cg, QCoreGraphicsPaintEngine::macGenericColorSpace());
+ CGContextSetFillColor(cg, colorComp);
+ HIThemeTextInfo tti;
+ tti.version = qt_mac_hitheme_version;
+ tti.state = tds;
+ if (active && enabled)
+ tti.state = kThemeStatePressed;
+ switch (widgetSize) {
+ case QAquaSizeUnknown:
+ case QAquaSizeLarge:
+ tti.fontID = kThemeMenuItemMarkFont;
+ break;
+ case QAquaSizeSmall:
+ tti.fontID = kThemeSmallSystemFont;
+ break;
+ case QAquaSizeMini:
+ tti.fontID = kThemeMiniSystemFont;
+ break;
+ }
+ tti.horizontalFlushness = kHIThemeTextHorizontalFlushLeft;
+ tti.verticalFlushness = kHIThemeTextVerticalFlushCenter;
+ tti.options = kHIThemeTextBoxOptionNone;
+ tti.truncationPosition = kHIThemeTextTruncationNone;
+ tti.truncationMaxLines = 1;
+ QCFString checkmark;
+#if 0
+ if (mi->checkType == QStyleOptionMenuItem::Exclusive)
+ checkmark = QString(QChar(kDiamondUnicode));
+ else
+#endif
+ checkmark = QString(QChar(kCheckUnicode));
+ int mw = checkcol + macItemFrame;
+ int mh = contentRect.height() - 2 * macItemFrame;
+ int xp = contentRect.x();
+ xp += macItemFrame;
+ CGFloat outWidth, outHeight, outBaseline;
+ HIThemeGetTextDimensions(checkmark, 0, &tti, &outWidth, &outHeight,
+ &outBaseline);
+ if (widgetSize == QAquaSizeMini)
+ outBaseline += 1;
+ QRect r(xp, contentRect.y(), mw, mh);
+ r.translate(0, p->fontMetrics().ascent() - int(outBaseline) + 1);
+ HIRect bounds = qt_hirectForQRect(r);
+ HIThemeDrawTextBox(checkmark, &bounds, &tti,
+ cg, kHIThemeOrientationNormal);
+ p->restore();
+ }
+ if (!mi->icon.isNull()) {
+ QIcon::Mode mode = (mi->state & State_Enabled) ? QIcon::Normal
+ : QIcon::Disabled;
+ // Always be normal or disabled to follow the Mac style.
+ int smallIconSize = proxy()->pixelMetric(PM_SmallIconSize);
+ QSize iconSize(smallIconSize, smallIconSize);
+ if (const QComboBox *comboBox = qobject_cast<const QComboBox *>(w)) {
+ iconSize = comboBox->iconSize();
+ }
+ QPixmap pixmap = mi->icon.pixmap(iconSize, mode);
+ int pixw = pixmap.width();
+ int pixh = pixmap.height();
+ QRect cr(xpos, contentRect.y(), checkcol, contentRect.height());
+ QRect pmr(0, 0, pixw, pixh);
+ pmr.moveCenter(cr.center());
+ p->drawPixmap(pmr.topLeft(), pixmap);
+ xpos += pixw + 6;
+ }
+
+ QString s = mi->text;
+ if (!s.isEmpty()) {
+ int t = s.indexOf(QLatin1Char('\t'));
+ int text_flags = Qt::AlignRight | Qt::AlignVCenter | Qt::TextHideMnemonic
+ | Qt::TextSingleLine | Qt::AlignAbsolute;
+ int yPos = contentRect.y();
+ if (widgetSize == QAquaSizeMini)
+ yPos += 1;
+ p->save();
+ if (t >= 0) {
+ p->setFont(qt_app_fonts_hash()->value("QMenuItem", p->font()));
+ int xp = contentRect.right() - tabwidth - macRightBorder
+ - macItemHMargin - macItemFrame + 1;
+ p->drawText(xp, yPos, tabwidth, contentRect.height(), text_flags,
+ s.mid(t + 1));
+ s = s.left(t);
+ }
+
+ const int xm = macItemFrame + maxpmw + macItemHMargin;
+ QFont myFont = mi->font;
+ // myFont may not have any "hard" flags set. We override
+ // the point size so that when it is resolved against the device, this font will win.
+ // This is mainly to handle cases where someone sets the font on the window
+ // and then the combo inherits it and passes it onward. At that point the resolve mask
+ // is very, very weak. This makes it stonger.
+ myFont.setPointSizeF(QFontInfo(mi->font).pointSizeF());
+ p->setFont(myFont);
+ p->drawText(xpos, yPos, contentRect.width() - xm - tabwidth + 1,
+ contentRect.height(), text_flags ^ Qt::AlignRight, s);
+ p->restore();
+ }
+ }
+ break;
+ case CE_MenuHMargin:
+ case CE_MenuVMargin:
+ case CE_MenuTearoff:
+ case CE_MenuScroller:
+ if (const QStyleOptionMenuItem *mi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
+ p->fillRect(mi->rect, opt->palette.background());
+
+ HIRect menuRect = qt_hirectForQRect(mi->menuRect);
+ HIRect itemRect = qt_hirectForQRect(mi->rect);
+ HIThemeMenuItemDrawInfo mdi;
+ mdi.version = qt_mac_hitheme_version;
+ if (!(opt->state & State_Enabled))
+ mdi.state = kThemeMenuDisabled;
+ else if (opt->state & State_Selected)
+ mdi.state = kThemeMenuSelected;
+ else
+ mdi.state = kThemeMenuActive;
+ if (ce == CE_MenuScroller) {
+ if (opt->state & State_DownArrow)
+ mdi.itemType = kThemeMenuItemScrollDownArrow;
+ else
+ mdi.itemType = kThemeMenuItemScrollUpArrow;
+ } else {
+ mdi.itemType = kThemeMenuItemPlain;
+ }
+ HIThemeDrawMenuItem(&menuRect, &itemRect, &mdi,
+ cg,
+ kHIThemeOrientationNormal, 0);
+ if (ce == CE_MenuTearoff) {
+ p->setPen(QPen(mi->palette.dark().color(), 1, Qt::DashLine));
+ p->drawLine(mi->rect.x() + 2, mi->rect.y() + mi->rect.height() / 2 - 1,
+ mi->rect.x() + mi->rect.width() - 4,
+ mi->rect.y() + mi->rect.height() / 2 - 1);
+ p->setPen(QPen(mi->palette.light().color(), 1, Qt::DashLine));
+ p->drawLine(mi->rect.x() + 2, mi->rect.y() + mi->rect.height() / 2,
+ mi->rect.x() + mi->rect.width() - 4,
+ mi->rect.y() + mi->rect.height() / 2);
+ }
+ }
+ break;
+ case CE_MenuBarItem:
+ if (const QStyleOptionMenuItem *mi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
+ HIRect menuRect = qt_hirectForQRect(mi->menuRect);
+ HIRect itemRect = qt_hirectForQRect(mi->rect);
+
+ if ((opt->state & State_Selected) && (opt->state & State_Enabled) && (opt->state & State_Sunken)){
+ // Draw a selected menu item background:
+ HIThemeMenuItemDrawInfo mdi;
+ mdi.version = qt_mac_hitheme_version;
+ mdi.state = kThemeMenuSelected;
+ mdi.itemType = kThemeMenuItemPlain;
+ HIThemeDrawMenuItem(&menuRect, &itemRect, &mdi, cg, kHIThemeOrientationNormal, 0);
+ } else {
+ // Draw the toolbar background:
+ HIThemeMenuBarDrawInfo bdi;
+ bdi.version = qt_mac_hitheme_version;
+ bdi.state = kThemeMenuBarNormal;
+ bdi.attributes = 0;
+ HIThemeDrawMenuBarBackground(&menuRect, &bdi, cg, kHIThemeOrientationNormal);
+ }
+
+ if (!mi->icon.isNull()) {
+ drawItemPixmap(p, mi->rect,
+ Qt::AlignCenter | Qt::TextHideMnemonic | Qt::TextDontClip
+ | Qt::TextSingleLine,
+ mi->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize),
+ (mi->state & State_Enabled) ? QIcon::Normal : QIcon::Disabled));
+ } else {
+ drawItemText(p, mi->rect,
+ Qt::AlignCenter | Qt::TextHideMnemonic | Qt::TextDontClip
+ | Qt::TextSingleLine,
+ mi->palette, mi->state & State_Enabled,
+ mi->text, QPalette::ButtonText);
+ }
+ }
+ break;
+ case CE_MenuBarEmptyArea:
+ if (const QStyleOptionMenuItem *mi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
+ HIThemeMenuBarDrawInfo bdi;
+ bdi.version = qt_mac_hitheme_version;
+ bdi.state = kThemeMenuBarNormal;
+ bdi.attributes = 0;
+ HIRect hirect = qt_hirectForQRect(mi->rect);
+ HIThemeDrawMenuBarBackground(&hirect, &bdi, cg,
+ kHIThemeOrientationNormal);
+ break;
+ }
+ case CE_ProgressBarContents:
+ if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) {
+ HIThemeTrackDrawInfo tdi;
+ tdi.version = qt_mac_hitheme_version;
+ tdi.reserved = 0;
+ bool isIndeterminate = (pb->minimum == 0 && pb->maximum == 0);
+ bool vertical = false;
+ bool inverted = false;
+ if (const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(opt)) {
+ vertical = (pb2->orientation == Qt::Vertical);
+ inverted = pb2->invertedAppearance;
+ }
+ bool reverse = (!vertical && (pb->direction == Qt::RightToLeft));
+ if (inverted)
+ reverse = !reverse;
+ switch (d->aquaSizeConstrain(opt, w)) {
+ case QAquaSizeUnknown:
+ case QAquaSizeLarge:
+ tdi.kind = !isIndeterminate ? kThemeLargeProgressBar
+ : kThemeLargeIndeterminateBar;
+ break;
+ case QAquaSizeMini:
+ case QAquaSizeSmall:
+ tdi.kind = !isIndeterminate ? kThemeProgressBar : kThemeIndeterminateBar;
+ break;
+ }
+ tdi.bounds = qt_hirectForQRect(pb->rect);
+ tdi.max = pb->maximum;
+ tdi.min = pb->minimum;
+ tdi.value = pb->progress;
+ tdi.attributes = vertical ? 0 : kThemeTrackHorizontal;
+ tdi.trackInfo.progress.phase = d->progressFrame;
+ if (!(pb->state & State_Active))
+ tdi.enableState = kThemeTrackInactive;
+ else if (!(pb->state & State_Enabled))
+ tdi.enableState = kThemeTrackDisabled;
+ else
+ tdi.enableState = kThemeTrackActive;
+ HIThemeOrientation drawOrientation = kHIThemeOrientationNormal;
+ if (reverse) {
+ if (vertical) {
+ drawOrientation = kHIThemeOrientationInverted;
+ } else {
+ CGContextSaveGState(cg);
+ CGContextTranslateCTM(cg, pb->rect.width(), 0);
+ CGContextScaleCTM(cg, -1, 1);
+ }
+ }
+ HIThemeDrawTrack(&tdi, 0, cg, drawOrientation);
+ if (reverse && !vertical)
+ CGContextRestoreGState(cg);
+ }
+ break;
+ case CE_ProgressBarLabel:
+ case CE_ProgressBarGroove:
+ break;
+ case CE_SizeGrip: {
+ if (w && w->testAttribute(Qt::WA_MacOpaqueSizeGrip)) {
+ HIThemeGrowBoxDrawInfo gdi;
+ gdi.version = qt_mac_hitheme_version;
+ gdi.state = tds;
+ gdi.kind = kHIThemeGrowBoxKindNormal;
+ gdi.direction = kThemeGrowRight | kThemeGrowDown;
+ gdi.size = kHIThemeGrowBoxSizeNormal;
+ HIPoint pt = CGPointMake(opt->rect.x(), opt->rect.y());
+ HIThemeDrawGrowBox(&pt, &gdi, cg, kHIThemeOrientationNormal);
+ } else {
+ // It isn't possible to draw a transparent size grip with the
+ // native API, so we do it ourselves here.
+ const bool metal = qt_mac_is_metal(w);
+ QPen lineColor = metal ? QColor(236, 236, 236) : QColor(82, 82, 82, 192);
+ QPen metalHighlight = QColor(5, 5, 5, 192);
+ lineColor.setWidth(1);
+ p->save();
+ p->setRenderHint(QPainter::Antialiasing);
+ p->setPen(lineColor);
+ const Qt::LayoutDirection layoutDirection = w ? w->layoutDirection() : qApp->layoutDirection();
+ const int NumLines = metal ? 4 : 3;
+ for (int l = 0; l < NumLines; ++l) {
+ const int offset = (l * 4 + (metal ? 2 : 3));
+ QPoint start, end;
+ if (layoutDirection == Qt::LeftToRight) {
+ start = QPoint(opt->rect.width() - offset, opt->rect.height() - 1);
+ end = QPoint(opt->rect.width() - 1, opt->rect.height() - offset);
+ } else {
+ start = QPoint(offset, opt->rect.height() - 1);
+ end = QPoint(1, opt->rect.height() - offset);
+ }
+ p->drawLine(start, end);
+ if (metal) {
+ p->setPen(metalHighlight);
+ p->setRenderHint(QPainter::Antialiasing, false);
+ p->drawLine(start + QPoint(0, -1), end + QPoint(0, -1));
+ p->setRenderHint(QPainter::Antialiasing, true);
+ p->setPen(lineColor);
+ }
+ }
+ p->restore();
+ }
+ break;
+ }
+ case CE_Splitter: {
+ HIThemeSplitterDrawInfo sdi;
+ sdi.version = qt_mac_hitheme_version;
+ sdi.state = tds;
+ sdi.adornment = qt_mac_is_metal(w) ? kHIThemeSplitterAdornmentMetal
+ : kHIThemeSplitterAdornmentNone;
+ HIRect hirect = qt_hirectForQRect(opt->rect);
+ HIThemeDrawPaneSplitter(&hirect, &sdi, cg, kHIThemeOrientationNormal);
+ break; }
+ case CE_RubberBand:
+ if (const QStyleOptionRubberBand *rubber = qstyleoption_cast<const QStyleOptionRubberBand *>(opt)) {
+ QColor fillColor(opt->palette.color(QPalette::Disabled, QPalette::Highlight));
+ if (!rubber->opaque) {
+ QColor strokeColor;
+ // I retrieved these colors from the Carbon-Dev mailing list
+ strokeColor.setHsvF(0, 0, 0.86, 1.0);
+ fillColor.setHsvF(0, 0, 0.53, 0.25);
+ if (opt->rect.width() * opt->rect.height() <= 3) {
+ p->fillRect(opt->rect, strokeColor);
+ } else {
+ QPen oldPen = p->pen();
+ QBrush oldBrush = p->brush();
+ QPen pen(strokeColor);
+ p->setPen(pen);
+ p->setBrush(fillColor);
+ p->drawRect(opt->rect.adjusted(0, 0, -1, -1));
+ p->setPen(oldPen);
+ p->setBrush(oldBrush);
+ }
+ } else {
+ p->fillRect(opt->rect, fillColor);
+ }
+ }
+ break;
+ case CE_ToolBar: {
+ // For unified tool bars, draw nothing.
+ if (w) {
+ if (QMainWindow * mainWindow = qobject_cast<QMainWindow *>(w->window())) {
+ if (mainWindow->unifiedTitleAndToolBarOnMac())
+ break;
+ }
+ }
+
+ // draw background gradient
+ QLinearGradient linearGrad;
+ if (opt->state & State_Horizontal)
+ linearGrad = QLinearGradient(0, opt->rect.top(), 0, opt->rect.bottom());
+ else
+ linearGrad = QLinearGradient(opt->rect.left(), 0, opt->rect.right(), 0);
+
+ linearGrad.setColorAt(0, mainWindowGradientBegin);
+ linearGrad.setColorAt(1, mainWindowGradientEnd);
+ p->fillRect(opt->rect, linearGrad);
+
+ p->save();
+ if (opt->state & State_Horizontal) {
+ p->setPen(mainWindowGradientBegin.lighter(114));
+ p->drawLine(opt->rect.topLeft(), opt->rect.topRight());
+ p->setPen(mainWindowGradientEnd.darker(114));
+ p->drawLine(opt->rect.bottomLeft(), opt->rect.bottomRight());
+
+ } else {
+ p->setPen(mainWindowGradientBegin.lighter(114));
+ p->drawLine(opt->rect.topLeft(), opt->rect.bottomLeft());
+ p->setPen(mainWindowGradientEnd.darker(114));
+ p->drawLine(opt->rect.topRight(), opt->rect.bottomRight());
+ }
+ p->restore();
+
+
+ } break;
+ default:
+ QWindowsStyle::drawControl(ce, opt, p, w);
+ break;
+ }
+}
+
+static void setLayoutItemMargins(int left, int top, int right, int bottom, QRect *rect, Qt::LayoutDirection dir)
+{
+ if (dir == Qt::RightToLeft) {
+ rect->adjust(-right, top, -left, bottom);
+ } else {
+ rect->adjust(left, top, right, bottom);
+ }
+}
+
+QRect QMacStyle::subElementRect(SubElement sr, const QStyleOption *opt,
+ const QWidget *widget) const
+{
+ QRect rect;
+ int controlSize = getControlSize(opt, widget);
+
+ switch (sr) {
+ case SE_ItemViewItemText:
+ if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(opt)) {
+ int fw = proxy()->pixelMetric(PM_FocusFrameHMargin, opt, widget);
+ // We add the focusframeargin between icon and text in commonstyle
+ rect = QCommonStyle::subElementRect(sr, opt, widget);
+ if (vopt->features & QStyleOptionViewItemV2::HasDecoration)
+ rect.adjust(-fw, 0, 0, 0);
+ }
+ break;
+ case SE_ToolBoxTabContents:
+ rect = QCommonStyle::subElementRect(sr, opt, widget);
+ break;
+ case SE_PushButtonContents:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
+ // Unlike Carbon, we want the button to always be drawn inside its bounds.
+ // Therefore, the button is a bit smaller, so that even if it got focus,
+ // the focus 'shadow' will be inside. Adjust the content rect likewise.
+ HIThemeButtonDrawInfo bdi;
+ d->initHIThemePushButton(btn, widget, d->getDrawState(opt->state), &bdi);
+ HIRect contentRect = d->pushButtonContentBounds(btn, &bdi);
+ rect = qt_qrectForHIRect(contentRect);
+ }
+ break;
+ case SE_HeaderLabel:
+ if (qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
+ rect = QWindowsStyle::subElementRect(sr, opt, widget);
+ if (widget && widget->height() <= 22){
+ // We need to allow the text a bit more space when the header is
+ // small, otherwise it gets clipped:
+ rect.setY(0);
+ rect.setHeight(widget->height());
+ }
+ }
+ break;
+ case SE_ProgressBarGroove:
+ case SE_ProgressBarLabel:
+ break;
+ case SE_ProgressBarContents:
+ rect = opt->rect;
+ break;
+ case SE_TreeViewDisclosureItem: {
+ HIRect inRect = CGRectMake(opt->rect.x(), opt->rect.y(),
+ opt->rect.width(), opt->rect.height());
+ HIThemeButtonDrawInfo bdi;
+ bdi.version = qt_mac_hitheme_version;
+ bdi.state = kThemeStateActive;
+ bdi.kind = kThemeDisclosureButton;
+ bdi.value = kThemeDisclosureRight;
+ bdi.adornment = kThemeAdornmentNone;
+ HIRect contentRect;
+ HIThemeGetButtonContentBounds(&inRect, &bdi, &contentRect);
+ QCFType<HIShapeRef> shape;
+ HIRect outRect;
+ HIThemeGetButtonShape(&inRect, &bdi, &shape);
+ ptrHIShapeGetBounds(shape, &outRect);
+ rect = QRect(int(outRect.origin.x + DisclosureOffset), int(outRect.origin.y),
+ int(contentRect.origin.x - outRect.origin.x + DisclosureOffset),
+ int(outRect.size.height));
+ break;
+ }
+ case SE_TabWidgetLeftCorner:
+ if (const QStyleOptionTabWidgetFrame *twf
+ = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
+ switch (twf->shape) {
+ case QTabBar::RoundedNorth:
+ case QTabBar::TriangularNorth:
+ rect = QRect(QPoint(0, 0), twf->leftCornerWidgetSize);
+ break;
+ case QTabBar::RoundedSouth:
+ case QTabBar::TriangularSouth:
+ rect = QRect(QPoint(0, twf->rect.height() - twf->leftCornerWidgetSize.height()),
+ twf->leftCornerWidgetSize);
+ break;
+ default:
+ break;
+ }
+ rect = visualRect(twf->direction, twf->rect, rect);
+ }
+ break;
+ case SE_TabWidgetRightCorner:
+ if (const QStyleOptionTabWidgetFrame *twf
+ = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
+ switch (twf->shape) {
+ case QTabBar::RoundedNorth:
+ case QTabBar::TriangularNorth:
+ rect = QRect(QPoint(twf->rect.width() - twf->rightCornerWidgetSize.width(), 0),
+ twf->rightCornerWidgetSize);
+ break;
+ case QTabBar::RoundedSouth:
+ case QTabBar::TriangularSouth:
+ rect = QRect(QPoint(twf->rect.width() - twf->rightCornerWidgetSize.width(),
+ twf->rect.height() - twf->rightCornerWidgetSize.height()),
+ twf->rightCornerWidgetSize);
+ break;
+ default:
+ break;
+ }
+ rect = visualRect(twf->direction, twf->rect, rect);
+ }
+ break;
+ case SE_TabWidgetTabContents:
+ rect = QWindowsStyle::subElementRect(sr, opt, widget);
+ if (const QStyleOptionTabWidgetFrame *twf
+ = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
+ if (twf->lineWidth != 0) {
+ switch (getTabDirection(twf->shape)) {
+ case kThemeTabNorth:
+ rect.adjust(+1, +14, -1, -1);
+ break;
+ case kThemeTabSouth:
+ rect.adjust(+1, +1, -1, -14);
+ break;
+ case kThemeTabWest:
+ rect.adjust(+14, +1, -1, -1);
+ break;
+ case kThemeTabEast:
+ rect.adjust(+1, +1, -14, -1);
+ }
+ }
+ }
+ break;
+ case SE_LineEditContents:
+ rect = QWindowsStyle::subElementRect(sr, opt, widget);
+ if(widget->parentWidget() && qobject_cast<const QComboBox*>(widget->parentWidget()))
+ rect.adjust(-1, -2, 0, 0);
+ else
+ rect.adjust(-1, 0, 0, +1);
+ break;
+ case SE_CheckBoxLayoutItem:
+ rect = opt->rect;
+ if (controlSize == QAquaSizeLarge) {
+ setLayoutItemMargins(+2, +3, -9, -4, &rect, opt->direction);
+ } else if (controlSize == QAquaSizeSmall) {
+ setLayoutItemMargins(+1, +5, 0 /* fix */, -6, &rect, opt->direction);
+ } else {
+ setLayoutItemMargins(0, +7, 0 /* fix */, -6, &rect, opt->direction);
+ }
+ break;
+ case SE_ComboBoxLayoutItem:
+ if (widget && qobject_cast<QToolBar *>(widget->parentWidget())) {
+ // Do nothing, because QToolbar needs the entire widget rect.
+ // Otherwise it will be clipped. Equivalent to
+ // widget->setAttribute(Qt::WA_LayoutUsesWidgetRect), but without
+ // all the hassle.
+ } else {
+ rect = opt->rect;
+ if (controlSize == QAquaSizeLarge) {
+ rect.adjust(+3, +2, -3, -4);
+ } else if (controlSize == QAquaSizeSmall) {
+ setLayoutItemMargins(+2, +1, -3, -4, &rect, opt->direction);
+ } else {
+ setLayoutItemMargins(+1, 0, -2, 0, &rect, opt->direction);
+ }
+ }
+ break;
+ case SE_LabelLayoutItem:
+ rect = opt->rect;
+ setLayoutItemMargins(+1, 0 /* SHOULD be -1, done for alignment */, 0, 0 /* SHOULD be -1, done for alignment */, &rect, opt->direction);
+ break;
+ case SE_ProgressBarLayoutItem: {
+ rect = opt->rect;
+ int bottom = SIZE(3, 8, 8);
+ if (opt->state & State_Horizontal) {
+ rect.adjust(0, +1, 0, -bottom);
+ } else {
+ setLayoutItemMargins(+1, 0, -bottom, 0, &rect, opt->direction);
+ }
+ break;
+ }
+ case SE_PushButtonLayoutItem:
+ if (const QStyleOptionButton *buttonOpt
+ = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
+ if ((buttonOpt->features & QStyleOptionButton::Flat))
+ break; // leave rect alone
+ }
+ rect = opt->rect;
+ if (controlSize == QAquaSizeLarge) {
+ rect.adjust(+6, +4, -6, -8);
+ } else if (controlSize == QAquaSizeSmall) {
+ rect.adjust(+5, +4, -5, -6);
+ } else {
+ rect.adjust(+1, 0, -1, -2);
+ }
+ break;
+ case SE_RadioButtonLayoutItem:
+ rect = opt->rect;
+ if (controlSize == QAquaSizeLarge) {
+ setLayoutItemMargins(+2, +2 /* SHOULD BE +3, done for alignment */,
+ 0, -4 /* SHOULD BE -3, done for alignment */, &rect, opt->direction);
+ } else if (controlSize == QAquaSizeSmall) {
+ rect.adjust(0, +6, 0 /* fix */, -5);
+ } else {
+ rect.adjust(0, +6, 0 /* fix */, -7);
+ }
+ break;
+ case SE_SliderLayoutItem:
+ if (const QStyleOptionSlider *sliderOpt
+ = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
+ rect = opt->rect;
+ if (sliderOpt->tickPosition == QSlider::NoTicks) {
+ int above = SIZE(3, 0, 2);
+ int below = SIZE(4, 3, 0);
+ if (sliderOpt->orientation == Qt::Horizontal) {
+ rect.adjust(0, +above, 0, -below);
+ } else {
+ rect.adjust(+above, 0, -below, 0); //### Seems that QSlider flip the position of the ticks in reverse mode.
+ }
+ } else if (sliderOpt->tickPosition == QSlider::TicksAbove) {
+ int below = SIZE(3, 2, 0);
+ if (sliderOpt->orientation == Qt::Horizontal) {
+ rect.setHeight(rect.height() - below);
+ } else {
+ rect.setWidth(rect.width() - below);
+ }
+ } else if (sliderOpt->tickPosition == QSlider::TicksBelow) {
+ int above = SIZE(3, 2, 0);
+ if (sliderOpt->orientation == Qt::Horizontal) {
+ rect.setTop(rect.top() + above);
+ } else {
+ rect.setLeft(rect.left() + above);
+ }
+ }
+ }
+ break;
+ case SE_FrameLayoutItem:
+ // hack because QStyleOptionFrameV2 doesn't have a frameStyle member
+ if (const QFrame *frame = qobject_cast<const QFrame *>(widget)) {
+ rect = opt->rect;
+ switch (frame->frameStyle() & QFrame::Shape_Mask) {
+ case QFrame::HLine:
+ rect.adjust(0, +1, 0, -1);
+ break;
+ case QFrame::VLine:
+ rect.adjust(+1, 0, -1, 0);
+ break;
+ default:
+ ;
+ }
+ }
+ break;
+ case SE_GroupBoxLayoutItem:
+ rect = opt->rect;
+ if (const QStyleOptionGroupBox *groupBoxOpt =
+ qstyleoption_cast<const QStyleOptionGroupBox *>(opt)) {
+ /*
+ AHIG is very inconsistent when it comes to group boxes.
+ Basically, we make sure that (non-checkable) group boxes
+ and tab widgets look good when laid out side by side.
+ */
+ if (groupBoxOpt->subControls & (QStyle::SC_GroupBoxCheckBox
+ | QStyle::SC_GroupBoxLabel)) {
+ int delta;
+ if (groupBoxOpt->subControls & QStyle::SC_GroupBoxCheckBox) {
+ delta = SIZE(8, 4, 4); // guess
+ } else {
+ delta = SIZE(15, 12, 12); // guess
+ }
+ rect.setTop(rect.top() + delta);
+ }
+ }
+ rect.setBottom(rect.bottom() - 1);
+ break;
+ case SE_TabWidgetLayoutItem:
+ if (const QStyleOptionTabWidgetFrame *tabWidgetOpt =
+ qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
+ /*
+ AHIG specifies "12 or 14" as the distance from the window
+ edge. We choose 14 and since the default top margin is 20,
+ the overlap is 6.
+ */
+ rect = tabWidgetOpt->rect;
+ if (tabWidgetOpt->shape == QTabBar::RoundedNorth)
+ rect.setTop(rect.top() + SIZE(6 /* AHIG */, 3 /* guess */, 2 /* AHIG */));
+ }
+ break;
+ default:
+ rect = QWindowsStyle::subElementRect(sr, opt, widget);
+ break;
+ }
+ return rect;
+}
+
+static inline void drawToolbarButtonArrow(const QRect &toolButtonRect, ThemeDrawState tds, CGContextRef cg)
+{
+ QRect arrowRect = QRect(toolButtonRect.right() - 9, toolButtonRect.bottom() - 9, 7, 5);
+ HIThemePopupArrowDrawInfo padi;
+ padi.version = qt_mac_hitheme_version;
+ padi.state = tds;
+ padi.orientation = kThemeArrowDown;
+ padi.size = kThemeArrow7pt;
+ HIRect hirect = qt_hirectForQRect(arrowRect);
+ HIThemeDrawPopupArrow(&hirect, &padi, cg, kHIThemeOrientationNormal);
+}
+
+void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p,
+ const QWidget *widget) const
+{
+ ThemeDrawState tds = d->getDrawState(opt->state);
+ QMacCGContext cg(p);
+ switch (cc) {
+ case CC_Slider:
+ case CC_ScrollBar:
+ if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
+ HIThemeTrackDrawInfo tdi;
+ d->getSliderInfo(cc, slider, &tdi, widget);
+ if (slider->state & State_Sunken) {
+ if (cc == CC_Slider) {
+ if (slider->activeSubControls == SC_SliderHandle)
+ tdi.trackInfo.slider.pressState = kThemeThumbPressed;
+ else if (slider->activeSubControls == SC_SliderGroove)
+ tdi.trackInfo.slider.pressState = kThemeLeftTrackPressed;
+ } else {
+ if (slider->activeSubControls == SC_ScrollBarSubLine
+ || slider->activeSubControls == SC_ScrollBarAddLine) {
+ // This test looks complex but it basically boils down
+ // to the following: The "RTL look" on the mac also
+ // changed the directions of the controls, that's not
+ // what people expect (an arrow is an arrow), so we
+ // kind of fake and say the opposite button is hit.
+ // This works great, up until 10.4 which broke the
+ // scroll bars, so I also have actually do something
+ // similar when I have an upside down scroll bar
+ // because on Tiger I only "fake" the reverse stuff.
+ bool reverseHorizontal = (slider->direction == Qt::RightToLeft
+ && slider->orientation == Qt::Horizontal);
+ if ((reverseHorizontal
+ && slider->activeSubControls == SC_ScrollBarAddLine)
+ || (!reverseHorizontal
+ && slider->activeSubControls == SC_ScrollBarSubLine)) {
+ tdi.trackInfo.scrollbar.pressState = kThemeRightInsideArrowPressed
+ | kThemeLeftOutsideArrowPressed;
+ } else {
+ tdi.trackInfo.scrollbar.pressState = kThemeLeftInsideArrowPressed
+ | kThemeRightOutsideArrowPressed;
+ }
+ } else if (slider->activeSubControls == SC_ScrollBarAddPage) {
+ tdi.trackInfo.scrollbar.pressState = kThemeRightTrackPressed;
+ } else if (slider->activeSubControls == SC_ScrollBarSubPage) {
+ tdi.trackInfo.scrollbar.pressState = kThemeLeftTrackPressed;
+ } else if (slider->activeSubControls == SC_ScrollBarSlider) {
+ tdi.trackInfo.scrollbar.pressState = kThemeThumbPressed;
+ }
+ }
+ }
+ HIRect macRect;
+ bool tracking = slider->sliderPosition == slider->sliderValue;
+ if (!tracking) {
+ // Small optimization, the same as q->subControlRect
+ QCFType<HIShapeRef> shape;
+ HIThemeGetTrackThumbShape(&tdi, &shape);
+ ptrHIShapeGetBounds(shape, &macRect);
+ tdi.value = slider->sliderValue;
+ }
+
+ // Remove controls from the scroll bar if it is to short to draw them correctly.
+ // This is done in two stages: first the thumb indicator is removed when it is
+ // no longer possible to move it, second the up/down buttons are removed when
+ // there is not enough space for them.
+ if (cc == CC_ScrollBar) {
+ const int scrollBarLength = (slider->orientation == Qt::Horizontal)
+ ? slider->rect.width() : slider->rect.height();
+ const QMacStyle::WidgetSizePolicy sizePolicy = widgetSizePolicy(widget);
+ if (scrollBarLength < scrollButtonsCutoffSize(thumbIndicatorCutoff, sizePolicy))
+ tdi.attributes &= ~kThemeTrackShowThumb;
+ if (scrollBarLength < scrollButtonsCutoffSize(scrollButtonsCutoff, sizePolicy))
+ tdi.enableState = kThemeTrackNothingToScroll;
+ } else {
+ if (!(slider->subControls & SC_SliderHandle))
+ tdi.attributes &= ~kThemeTrackShowThumb;
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+ if (!(slider->subControls & SC_SliderGroove))
+ tdi.attributes |= kThemeTrackHideTrack;
+#endif
+ }
+
+ HIThemeDrawTrack(&tdi, tracking ? 0 : &macRect, cg,
+ kHIThemeOrientationNormal);
+ if (cc == CC_Slider && slider->subControls & SC_SliderTickmarks) {
+ if (qt_mac_is_metal(widget)) {
+ if (tdi.enableState == kThemeTrackInactive)
+ tdi.enableState = kThemeTrackActive; // Looks more Cocoa-like
+ }
+ int interval = slider->tickInterval;
+ if (interval == 0) {
+ interval = slider->pageStep;
+ if (interval == 0)
+ interval = slider->singleStep;
+ if (interval == 0)
+ interval = 1;
+ }
+ int numMarks = 1 + ((slider->maximum - slider->minimum) / interval);
+
+ if (tdi.trackInfo.slider.thumbDir == kThemeThumbPlain) {
+ // They asked for both, so we'll give it to them.
+ tdi.trackInfo.slider.thumbDir = kThemeThumbDownward;
+ HIThemeDrawTrackTickMarks(&tdi, numMarks,
+ cg,
+ kHIThemeOrientationNormal);
+ tdi.trackInfo.slider.thumbDir = kThemeThumbUpward;
+ HIThemeDrawTrackTickMarks(&tdi, numMarks,
+ cg,
+ kHIThemeOrientationNormal);
+ } else {
+ HIThemeDrawTrackTickMarks(&tdi, numMarks,
+ cg,
+ kHIThemeOrientationNormal);
+
+ }
+ }
+ }
+ break;
+ case CC_Q3ListView:
+ if (const QStyleOptionQ3ListView *lv = qstyleoption_cast<const QStyleOptionQ3ListView *>(opt)) {
+ if (lv->subControls & SC_Q3ListView)
+ QWindowsStyle::drawComplexControl(cc, lv, p, widget);
+ if (lv->subControls & (SC_Q3ListViewBranch | SC_Q3ListViewExpand)) {
+ int y = lv->rect.y();
+ int h = lv->rect.height();
+ int x = lv->rect.right() - 10;
+ for (int i = 1; i < lv->items.size() && y < h; ++i) {
+ QStyleOptionQ3ListViewItem item = lv->items.at(i);
+ if (y + item.height > 0 && (item.childCount > 0
+ || (item.features & (QStyleOptionQ3ListViewItem::Expandable
+ | QStyleOptionQ3ListViewItem::Visible))
+ == (QStyleOptionQ3ListViewItem::Expandable
+ | QStyleOptionQ3ListViewItem::Visible))) {
+ QStyleOption treeOpt(0);
+ treeOpt.rect.setRect(x, y + item.height / 2 - 4, 9, 9);
+ treeOpt.palette = lv->palette;
+ treeOpt.state = lv->state;
+ treeOpt.state |= State_Children;
+ if (item.state & State_Open)
+ treeOpt.state |= State_Open;
+ proxy()->drawPrimitive(PE_IndicatorBranch, &treeOpt, p, widget);
+ }
+ y += item.totalHeight;
+ }
+ }
+ }
+ break;
+ case CC_SpinBox:
+ if (const QStyleOptionSpinBox *sb = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
+ QStyleOptionSpinBox newSB = *sb;
+ if (sb->frame && (sb->subControls & SC_SpinBoxFrame)) {
+ SInt32 frame_size;
+ GetThemeMetric(kThemeMetricEditTextFrameOutset, &frame_size);
+
+ QRect lineeditRect = proxy()->subControlRect(CC_SpinBox, sb, SC_SpinBoxEditField, widget);
+ lineeditRect.adjust(-frame_size, -frame_size, +frame_size, +frame_size);
+
+ HIThemeFrameDrawInfo fdi;
+ fdi.version = qt_mac_hitheme_version;
+ fdi.state = tds;
+ fdi.kind = kHIThemeFrameTextFieldSquare;
+ fdi.isFocused = false;
+ HIRect hirect = qt_hirectForQRect(lineeditRect);
+ HIThemeDrawFrame(&hirect, &fdi, cg, kHIThemeOrientationNormal);
+ }
+ if (sb->subControls & (SC_SpinBoxUp | SC_SpinBoxDown)) {
+ HIThemeButtonDrawInfo bdi;
+ bdi.version = qt_mac_hitheme_version;
+ QAquaWidgetSize aquaSize = d->aquaSizeConstrain(opt, widget);
+ switch (aquaSize) {
+ case QAquaSizeUnknown:
+ case QAquaSizeLarge:
+ bdi.kind = kThemeIncDecButton;
+ break;
+ case QAquaSizeMini:
+ bdi.kind = kThemeIncDecButtonMini;
+ break;
+ case QAquaSizeSmall:
+ bdi.kind = kThemeIncDecButtonSmall;
+ break;
+ }
+ if (!(sb->stepEnabled & (QAbstractSpinBox::StepUpEnabled
+ | QAbstractSpinBox::StepDownEnabled)))
+ tds = kThemeStateUnavailable;
+ if (sb->activeSubControls == SC_SpinBoxDown
+ && (sb->state & State_Sunken))
+ tds = kThemeStatePressedDown;
+ else if (sb->activeSubControls == SC_SpinBoxUp
+ && (sb->state & State_Sunken))
+ tds = kThemeStatePressedUp;
+ bdi.state = tds;
+ if (!(sb->state & State_Active)
+ && sb->palette.currentColorGroup() == QPalette::Active
+ && tds == kThemeStateInactive)
+ bdi.state = kThemeStateActive;
+ bdi.value = kThemeButtonOff;
+ bdi.adornment = kThemeAdornmentNone;
+
+ QRect updown = proxy()->subControlRect(CC_SpinBox, sb, SC_SpinBoxUp, widget);
+
+ updown |= proxy()->subControlRect(CC_SpinBox, sb, SC_SpinBoxDown, widget);
+ HIRect newRect = qt_hirectForQRect(updown);
+ QRect off_rct;
+ HIRect outRect;
+ HIThemeGetButtonBackgroundBounds(&newRect, &bdi, &outRect);
+ off_rct.setRect(int(newRect.origin.x - outRect.origin.x),
+ int(newRect.origin.y - outRect.origin.y),
+ int(outRect.size.width - newRect.size.width),
+ int(outRect.size.height - newRect.size.height));
+
+ newRect = qt_hirectForQRect(updown, off_rct);
+ HIThemeDrawButton(&newRect, &bdi, cg, kHIThemeOrientationNormal, 0);
+ }
+ }
+ break;
+ case CC_ComboBox:
+ if (const QStyleOptionComboBox *combo = qstyleoption_cast<const QStyleOptionComboBox *>(opt)){
+ HIThemeButtonDrawInfo bdi;
+ d->initComboboxBdi(combo, &bdi, widget, d->getDrawState(opt->state));
+ bool drawColorless = combo->palette.currentColorGroup() == QPalette::Active && tds == kThemeStateInactive;
+ if (!drawColorless)
+ QMacStylePrivate::drawCombobox(qt_hirectForQRect(combo->rect), bdi, p);
+ else
+ d->drawColorlessButton(qt_hirectForQRect(combo->rect), &bdi, p, opt);
+ }
+ break;
+ case CC_TitleBar:
+ if (const QStyleOptionTitleBar *titlebar
+ = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) {
+ if (titlebar->state & State_Active) {
+ if (titlebar->titleBarState & State_Active)
+ tds = kThemeStateActive;
+ else
+ tds = kThemeStateInactive;
+ } else {
+ tds = kThemeStateInactive;
+ }
+
+ HIThemeWindowDrawInfo wdi;
+ wdi.version = qt_mac_hitheme_version;
+ wdi.state = tds;
+ wdi.windowType = QtWinType;
+ wdi.titleHeight = titlebar->rect.height();
+ wdi.titleWidth = titlebar->rect.width();
+ wdi.attributes = kThemeWindowHasTitleText;
+ // It seems HIThemeDrawTitleBarWidget is not able to draw a dirty
+ // close button, so use HIThemeDrawWindowFrame instead.
+ if (widget && widget->isWindowModified() && titlebar->subControls & SC_TitleBarCloseButton)
+ wdi.attributes |= kThemeWindowHasCloseBox | kThemeWindowHasDirty;
+
+ HIRect titleBarRect;
+ HIRect tmpRect = qt_hirectForQRect(titlebar->rect);
+ {
+ QCFType<HIShapeRef> titleRegion;
+ QRect newr = titlebar->rect.adjusted(0, 0, 2, 0);
+ HIThemeGetWindowShape(&tmpRect, &wdi, kWindowTitleBarRgn, &titleRegion);
+ ptrHIShapeGetBounds(titleRegion, &tmpRect);
+ newr.translate(newr.x() - int(tmpRect.origin.x), newr.y() - int(tmpRect.origin.y));
+ titleBarRect = qt_hirectForQRect(newr);
+ }
+ HIThemeDrawWindowFrame(&titleBarRect, &wdi, cg, kHIThemeOrientationNormal, 0);
+ if (titlebar->subControls & (SC_TitleBarCloseButton
+ | SC_TitleBarMaxButton
+ | SC_TitleBarMinButton
+ | SC_TitleBarNormalButton)) {
+ HIThemeWindowWidgetDrawInfo wwdi;
+ wwdi.version = qt_mac_hitheme_version;
+ wwdi.widgetState = tds;
+ if (titlebar->state & State_MouseOver)
+ wwdi.widgetState = kThemeStateRollover;
+ wwdi.windowType = QtWinType;
+ wwdi.attributes = wdi.attributes | kThemeWindowHasFullZoom | kThemeWindowHasCloseBox | kThemeWindowHasCollapseBox;
+ wwdi.windowState = wdi.state;
+ wwdi.titleHeight = wdi.titleHeight;
+ wwdi.titleWidth = wdi.titleWidth;
+ ThemeDrawState savedControlState = wwdi.widgetState;
+ uint sc = SC_TitleBarMinButton;
+ ThemeTitleBarWidget tbw = kThemeWidgetCollapseBox;
+ bool active = titlebar->state & State_Active;
+ if (qMacVersion() < QSysInfo::MV_10_6) {
+ int border = 2;
+ titleBarRect.origin.x += border;
+ titleBarRect.origin.y -= border;
+ }
+
+ while (sc <= SC_TitleBarCloseButton) {
+ if (sc & titlebar->subControls) {
+ uint tmp = sc;
+ wwdi.widgetState = savedControlState;
+ wwdi.widgetType = tbw;
+ if (sc == SC_TitleBarMinButton)
+ tmp |= SC_TitleBarNormalButton;
+ if (active && (titlebar->activeSubControls & tmp)
+ && (titlebar->state & State_Sunken))
+ wwdi.widgetState = kThemeStatePressed;
+ // Draw all sub controllers except the dirty close button
+ // (it is already handled by HIThemeDrawWindowFrame).
+ if (!(widget && widget->isWindowModified() && tbw == kThemeWidgetCloseBox)) {
+ HIThemeDrawTitleBarWidget(&titleBarRect, &wwdi, cg, kHIThemeOrientationNormal);
+ p->paintEngine()->syncState();
+ }
+ }
+ sc = sc << 1;
+ tbw = tbw >> 1;
+ }
+ }
+ p->paintEngine()->syncState();
+ if (titlebar->subControls & SC_TitleBarLabel) {
+ int iw = 0;
+ if (!titlebar->icon.isNull()) {
+ QCFType<HIShapeRef> titleRegion2;
+ HIThemeGetWindowShape(&titleBarRect, &wdi, kWindowTitleProxyIconRgn,
+ &titleRegion2);
+ ptrHIShapeGetBounds(titleRegion2, &tmpRect);
+ if (tmpRect.size.width != 1) {
+ int iconExtent = proxy()->pixelMetric(PM_SmallIconSize);
+ iw = titlebar->icon.actualSize(QSize(iconExtent, iconExtent)).width();
+ }
+ }
+ if (!titlebar->text.isEmpty()) {
+ p->save();
+ QCFType<HIShapeRef> titleRegion3;
+ HIThemeGetWindowShape(&titleBarRect, &wdi, kWindowTitleTextRgn, &titleRegion3);
+ ptrHIShapeGetBounds(titleRegion3, &tmpRect);
+ p->setClipRect(qt_qrectForHIRect(tmpRect));
+ QRect br = p->clipRegion().boundingRect();
+ int x = br.x(),
+ y = br.y() + (titlebar->rect.height() / 2 - p->fontMetrics().height() / 2);
+ if (br.width() <= (p->fontMetrics().width(titlebar->text) + iw * 2))
+ x += iw;
+ else
+ x += br.width() / 2 - p->fontMetrics().width(titlebar->text) / 2;
+ if (iw)
+ p->drawPixmap(x - iw, y,
+ titlebar->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize), QIcon::Normal));
+ drawItemText(p, br, Qt::AlignCenter, opt->palette, tds == kThemeStateActive,
+ titlebar->text, QPalette::Text);
+ p->restore();
+ }
+ }
+ }
+ break;
+ case CC_GroupBox:
+ if (const QStyleOptionGroupBox *groupBox
+ = qstyleoption_cast<const QStyleOptionGroupBox *>(opt)) {
+
+ QStyleOptionGroupBox groupBoxCopy(*groupBox);
+ if ((widget && !widget->testAttribute(Qt::WA_SetFont))
+ && QApplication::desktopSettingsAware())
+ groupBoxCopy.subControls = groupBoxCopy.subControls & ~SC_GroupBoxLabel;
+ QWindowsStyle::drawComplexControl(cc, &groupBoxCopy, p, widget);
+ if (groupBoxCopy.subControls != groupBox->subControls) {
+ bool checkable = groupBox->subControls & SC_GroupBoxCheckBox;
+ p->save();
+ CGContextSetShouldAntialias(cg, true);
+ CGContextSetShouldSmoothFonts(cg, true);
+ HIThemeTextInfo tti;
+ tti.version = qt_mac_hitheme_version;
+ tti.state = tds;
+ QColor textColor = groupBox->palette.windowText().color();
+ CGFloat colorComp[] = { textColor.redF(), textColor.greenF(),
+ textColor.blueF(), textColor.alphaF() };
+ CGContextSetFillColorSpace(cg, QCoreGraphicsPaintEngine::macGenericColorSpace());
+ CGContextSetFillColor(cg, colorComp);
+ tti.fontID = checkable ? kThemeSystemFont : kThemeSmallSystemFont;
+ tti.horizontalFlushness = kHIThemeTextHorizontalFlushCenter;
+ tti.verticalFlushness = kHIThemeTextVerticalFlushCenter;
+ tti.options = kHIThemeTextBoxOptionNone;
+ tti.truncationPosition = kHIThemeTextTruncationNone;
+ tti.truncationMaxLines = 1 + groupBox->text.count(QLatin1Char('\n'));
+ QCFString groupText = qt_mac_removeMnemonics(groupBox->text);
+ QRect r = proxy()->subControlRect(CC_GroupBox, groupBox, SC_GroupBoxLabel, widget);
+ HIRect bounds = qt_hirectForQRect(r);
+ HIThemeDrawTextBox(groupText, &bounds, &tti, cg, kHIThemeOrientationNormal);
+ p->restore();
+ }
+ }
+ break;
+ case CC_ToolButton:
+ if (const QStyleOptionToolButton *tb
+ = qstyleoption_cast<const QStyleOptionToolButton *>(opt)) {
+ if (widget && qobject_cast<QToolBar *>(widget->parentWidget())) {
+ if (tb->subControls & SC_ToolButtonMenu) {
+ QStyleOption arrowOpt(0);
+ arrowOpt.rect = proxy()->subControlRect(cc, tb, SC_ToolButtonMenu, widget);
+ arrowOpt.rect.setY(arrowOpt.rect.y() + arrowOpt.rect.height() / 2);
+ arrowOpt.rect.setHeight(arrowOpt.rect.height() / 2);
+ arrowOpt.state = tb->state;
+ arrowOpt.palette = tb->palette;
+ proxy()->drawPrimitive(PE_IndicatorArrowDown, &arrowOpt, p, widget);
+ } else if ((tb->features & QStyleOptionToolButton::HasMenu)
+ && (tb->toolButtonStyle != Qt::ToolButtonTextOnly && !tb->icon.isNull())) {
+ drawToolbarButtonArrow(tb->rect, tds, cg);
+ }
+ if (tb->state & State_On) {
+ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) {
+ static QPixmap pm(QLatin1String(":/trolltech/mac/style/images/leopard-unified-toolbar-on.png"));
+ p->setRenderHint(QPainter::SmoothPixmapTransform);
+ QStyleHelper::drawBorderPixmap(pm, p, tb->rect, 2, 2, 2, 2);
+ } else {
+ QPen oldPen = p->pen();
+ p->setPen(QColor(0, 0, 0, 0x3a));
+ p->fillRect(tb->rect.adjusted(1, 1, -1, -1), QColor(0, 0, 0, 0x12));
+ p->drawLine(tb->rect.left() + 1, tb->rect.top(),
+ tb->rect.right() - 1, tb->rect.top());
+ p->drawLine(tb->rect.left() + 1, tb->rect.bottom(),
+ tb->rect.right() - 1, tb->rect.bottom());
+ p->drawLine(tb->rect.topLeft(), tb->rect.bottomLeft());
+ p->drawLine(tb->rect.topRight(), tb->rect.bottomRight());
+ p->setPen(oldPen);
+ }
+ }
+ proxy()->drawControl(CE_ToolButtonLabel, opt, p, widget);
+ } else {
+ ThemeButtonKind bkind = kThemeBevelButton;
+ switch (d->aquaSizeConstrain(opt, widget)) {
+ case QAquaSizeUnknown:
+ case QAquaSizeLarge:
+ bkind = kThemeBevelButton;
+ break;
+ case QAquaSizeMini:
+ case QAquaSizeSmall:
+ bkind = kThemeSmallBevelButton;
+ break;
+ }
+
+ QRect button, menuarea;
+ button = proxy()->subControlRect(cc, tb, SC_ToolButton, widget);
+ menuarea = proxy()->subControlRect(cc, tb, SC_ToolButtonMenu, widget);
+ State bflags = tb->state,
+ mflags = tb->state;
+ if (tb->subControls & SC_ToolButton)
+ bflags |= State_Sunken;
+ if (tb->subControls & SC_ToolButtonMenu)
+ mflags |= State_Sunken;
+
+ if (tb->subControls & SC_ToolButton) {
+ if (bflags & (State_Sunken | State_On | State_Raised)) {
+ HIThemeButtonDrawInfo bdi;
+ bdi.version = qt_mac_hitheme_version;
+ bdi.state = tds;
+ bdi.adornment = kThemeAdornmentNone;
+ bdi.kind = bkind;
+ bdi.value = kThemeButtonOff;
+ if (tb->state & State_HasFocus)
+ bdi.adornment = kThemeAdornmentFocus;
+ if (tb->state & State_Sunken)
+ bdi.state = kThemeStatePressed;
+ if (tb->state & State_On)
+ bdi.value = kThemeButtonOn;
+
+ QRect off_rct(0, 0, 0, 0);
+ HIRect myRect, macRect;
+ myRect = CGRectMake(tb->rect.x(), tb->rect.y(),
+ tb->rect.width(), tb->rect.height());
+ HIThemeGetButtonBackgroundBounds(&myRect, &bdi, &macRect);
+ off_rct.setRect(int(myRect.origin.x - macRect.origin.x),
+ int(myRect.origin.y - macRect.origin.y),
+ int(macRect.size.width - myRect.size.width),
+ int(macRect.size.height - myRect.size.height));
+
+ myRect = qt_hirectForQRect(button, off_rct);
+ HIThemeDrawButton(&myRect, &bdi, cg, kHIThemeOrientationNormal, 0);
+ }
+ }
+
+ if (tb->subControls & SC_ToolButtonMenu) {
+ HIThemeButtonDrawInfo bdi;
+ bdi.version = qt_mac_hitheme_version;
+ bdi.state = tds;
+ bdi.value = kThemeButtonOff;
+ bdi.adornment = kThemeAdornmentNone;
+ bdi.kind = bkind;
+ if (tb->state & State_HasFocus)
+ bdi.adornment = kThemeAdornmentFocus;
+ if (tb->state & (State_On | State_Sunken)
+ || (tb->activeSubControls & SC_ToolButtonMenu))
+ bdi.state = kThemeStatePressed;
+ HIRect hirect = qt_hirectForQRect(menuarea);
+ HIThemeDrawButton(&hirect, &bdi, cg, kHIThemeOrientationNormal, 0);
+ QRect r(menuarea.x() + ((menuarea.width() / 2) - 3), menuarea.height() - 8, 8, 8);
+ HIThemePopupArrowDrawInfo padi;
+ padi.version = qt_mac_hitheme_version;
+ padi.state = tds;
+ padi.orientation = kThemeArrowDown;
+ padi.size = kThemeArrow7pt;
+ hirect = qt_hirectForQRect(r);
+ HIThemeDrawPopupArrow(&hirect, &padi, cg, kHIThemeOrientationNormal);
+ } else if (tb->features & QStyleOptionToolButton::HasMenu) {
+ drawToolbarButtonArrow(tb->rect, tds, cg);
+ }
+ QRect buttonRect = proxy()->subControlRect(CC_ToolButton, tb, SC_ToolButton, widget);
+ int fw = proxy()->pixelMetric(PM_DefaultFrameWidth, opt, widget);
+ QStyleOptionToolButton label = *tb;
+ label.rect = buttonRect.adjusted(fw, fw, -fw, -fw);
+ proxy()->drawControl(CE_ToolButtonLabel, &label, p, widget);
+ }
+ }
+ break;
+ case CC_Dial:
+ if (const QStyleOptionSlider *dial = qstyleoption_cast<const QStyleOptionSlider *>(opt))
+ QStyleHelper::drawDial(dial, p);
+ break;
+ default:
+ QWindowsStyle::drawComplexControl(cc, opt, p, widget);
+ break;
+ }
+}
+
+QStyle::SubControl QMacStyle::hitTestComplexControl(ComplexControl cc,
+ const QStyleOptionComplex *opt,
+ const QPoint &pt, const QWidget *widget) const
+{
+ SubControl sc = QStyle::SC_None;
+ switch (cc) {
+ case CC_ComboBox:
+ if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
+ sc = QWindowsStyle::hitTestComplexControl(cc, cmb, pt, widget);
+ if (!cmb->editable && sc != QStyle::SC_None)
+ sc = SC_ComboBoxArrow; // A bit of a lie, but what we want
+ }
+ break;
+ case CC_Slider:
+ if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
+ HIThemeTrackDrawInfo tdi;
+ d->getSliderInfo(cc, slider, &tdi, widget);
+ ControlPartCode part;
+ HIPoint pos = CGPointMake(pt.x(), pt.y());
+ if (HIThemeHitTestTrack(&tdi, &pos, &part)) {
+ if (part == kControlPageUpPart || part == kControlPageDownPart)
+ sc = SC_SliderGroove;
+ else
+ sc = SC_SliderHandle;
+ }
+ }
+ break;
+ case CC_ScrollBar:
+ if (const QStyleOptionSlider *sb = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
+ HIScrollBarTrackInfo sbi;
+ sbi.version = qt_mac_hitheme_version;
+ if (!(sb->state & State_Active))
+ sbi.enableState = kThemeTrackInactive;
+ else if (sb->state & State_Enabled)
+ sbi.enableState = kThemeTrackActive;
+ else
+ sbi.enableState = kThemeTrackDisabled;
+
+ // The arrow buttons are not drawn if the scroll bar is to short,
+ // exclude them from the hit test.
+ const int scrollBarLength = (sb->orientation == Qt::Horizontal)
+ ? sb->rect.width() : sb->rect.height();
+ if (scrollBarLength < scrollButtonsCutoffSize(scrollButtonsCutoff, widgetSizePolicy(widget)))
+ sbi.enableState = kThemeTrackNothingToScroll;
+
+ sbi.viewsize = sb->pageStep;
+ HIPoint pos = CGPointMake(pt.x(), pt.y());
+
+ HIRect macSBRect = qt_hirectForQRect(sb->rect);
+ ControlPartCode part;
+ bool reverseHorizontal = (sb->direction == Qt::RightToLeft
+ && sb->orientation == Qt::Horizontal
+ && (!sb->upsideDown ||
+ (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4
+ && sb->upsideDown)));
+ if (HIThemeHitTestScrollBarArrows(&macSBRect, &sbi, sb->orientation == Qt::Horizontal,
+ &pos, 0, &part)) {
+ if (part == kControlUpButtonPart)
+ sc = reverseHorizontal ? SC_ScrollBarAddLine : SC_ScrollBarSubLine;
+ else if (part == kControlDownButtonPart)
+ sc = reverseHorizontal ? SC_ScrollBarSubLine : SC_ScrollBarAddLine;
+ } else {
+ HIThemeTrackDrawInfo tdi;
+ d->getSliderInfo(cc, sb, &tdi, widget);
+ if(tdi.enableState == kThemeTrackInactive)
+ tdi.enableState = kThemeTrackActive;
+ if (HIThemeHitTestTrack(&tdi, &pos, &part)) {
+ if (part == kControlPageUpPart)
+ sc = reverseHorizontal ? SC_ScrollBarAddPage
+ : SC_ScrollBarSubPage;
+ else if (part == kControlPageDownPart)
+ sc = reverseHorizontal ? SC_ScrollBarSubPage
+ : SC_ScrollBarAddPage;
+ else
+ sc = SC_ScrollBarSlider;
+ }
+ }
+ }
+ break;
+/*
+ I don't know why, but we only get kWindowContentRgn here, which isn't what we want at all.
+ It would be very nice if this would work.
+ case QStyle::CC_TitleBar:
+ if (const QStyleOptionTitleBar *tbar = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) {
+ HIThemeWindowDrawInfo wdi;
+ memset(&wdi, 0, sizeof(wdi));
+ wdi.version = qt_mac_hitheme_version;
+ wdi.state = kThemeStateActive;
+ wdi.windowType = QtWinType;
+ wdi.titleWidth = tbar->rect.width();
+ wdi.titleHeight = tbar->rect.height();
+ if (tbar->titleBarState)
+ wdi.attributes |= kThemeWindowHasFullZoom | kThemeWindowHasCloseBox
+ | kThemeWindowHasCollapseBox;
+ else if (tbar->titleBarFlags & Qt::WindowSystemMenuHint)
+ wdi.attributes |= kThemeWindowHasCloseBox;
+ QRect tmpRect = tbar->rect;
+ tmpRect.setHeight(tmpRect.height() + 100);
+ HIRect hirect = qt_hirectForQRect(tmpRect);
+ WindowRegionCode hit;
+ HIPoint hipt = CGPointMake(pt.x(), pt.y());
+ if (HIThemeGetWindowRegionHit(&hirect, &wdi, &hipt, &hit)) {
+ switch (hit) {
+ case kWindowCloseBoxRgn:
+ sc = QStyle::SC_TitleBarCloseButton;
+ break;
+ case kWindowCollapseBoxRgn:
+ sc = QStyle::SC_TitleBarMinButton;
+ break;
+ case kWindowZoomBoxRgn:
+ sc = QStyle::SC_TitleBarMaxButton;
+ break;
+ case kWindowTitleTextRgn:
+ sc = QStyle::SC_TitleBarLabel;
+ break;
+ default:
+ qDebug("got something else %d", hit);
+ break;
+ }
+ }
+ }
+ break;
+*/
+ default:
+ sc = QWindowsStyle::hitTestComplexControl(cc, opt, pt, widget);
+ break;
+ }
+ return sc;
+}
+
+QRect QMacStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc,
+ const QWidget *widget) const
+{
+ QRect ret;
+ switch (cc) {
+ case CC_Slider:
+ case CC_ScrollBar:
+ if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
+ HIThemeTrackDrawInfo tdi;
+ d->getSliderInfo(cc, slider, &tdi, widget);
+ HIRect macRect;
+ QCFType<HIShapeRef> shape;
+ bool scrollBar = cc == CC_ScrollBar;
+ if ((scrollBar && sc == SC_ScrollBarSlider)
+ || (!scrollBar && sc == SC_SliderHandle)) {
+ HIThemeGetTrackThumbShape(&tdi, &shape);
+ ptrHIShapeGetBounds(shape, &macRect);
+ } else if (!scrollBar && sc == SC_SliderGroove) {
+ HIThemeGetTrackBounds(&tdi, &macRect);
+ } else if (sc == SC_ScrollBarGroove) { // Only scroll bar parts available...
+ HIThemeGetTrackDragRect(&tdi, &macRect);
+ } else {
+ ControlPartCode cpc;
+ if (sc == SC_ScrollBarSubPage || sc == SC_ScrollBarAddPage) {
+ cpc = sc == SC_ScrollBarSubPage ? kControlPageDownPart
+ : kControlPageUpPart;
+ } else {
+ cpc = sc == SC_ScrollBarSubLine ? kControlUpButtonPart
+ : kControlDownButtonPart;
+ if (slider->direction == Qt::RightToLeft
+ && slider->orientation == Qt::Horizontal) {
+ if (cpc == kControlDownButtonPart)
+ cpc = kControlUpButtonPart;
+ else if (cpc == kControlUpButtonPart)
+ cpc = kControlDownButtonPart;
+ }
+ }
+ HIThemeGetTrackPartBounds(&tdi, cpc, &macRect);
+ }
+ ret = qt_qrectForHIRect(macRect);
+
+ // Tweak: the dark line between the sub/add line buttons belong to only one of the buttons
+ // when doing hit-testing, but both of them have to repaint it. Extend the rect to cover
+ // the line in the cases where HIThemeGetTrackPartBounds returns a rect that doesn't.
+ if (slider->orientation == Qt::Horizontal) {
+ if (slider->direction == Qt::LeftToRight && sc == SC_ScrollBarSubLine)
+ ret.adjust(0, 0, 1, 0);
+ else if (slider->direction == Qt::RightToLeft && sc == SC_ScrollBarAddLine)
+ ret.adjust(-1, 0, 1, 0);
+ } else if (sc == SC_ScrollBarAddLine) {
+ ret.adjust(0, -1, 0, 1);
+ }
+ }
+ break;
+ case CC_TitleBar:
+ if (const QStyleOptionTitleBar *titlebar
+ = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) {
+ HIThemeWindowDrawInfo wdi;
+ memset(&wdi, 0, sizeof(wdi));
+ wdi.version = qt_mac_hitheme_version;
+ wdi.state = kThemeStateActive;
+ wdi.windowType = QtWinType;
+ wdi.titleHeight = titlebar->rect.height();
+ wdi.titleWidth = titlebar->rect.width();
+ wdi.attributes = kThemeWindowHasTitleText;
+ if (titlebar->subControls & SC_TitleBarCloseButton)
+ wdi.attributes |= kThemeWindowHasCloseBox;
+ if (titlebar->subControls & SC_TitleBarMaxButton
+ | SC_TitleBarNormalButton)
+ wdi.attributes |= kThemeWindowHasFullZoom;
+ if (titlebar->subControls & SC_TitleBarMinButton)
+ wdi.attributes |= kThemeWindowHasCollapseBox;
+ WindowRegionCode wrc = kWindowGlobalPortRgn;
+
+ if (sc == SC_TitleBarCloseButton)
+ wrc = kWindowCloseBoxRgn;
+ else if (sc == SC_TitleBarMinButton)
+ wrc = kWindowCollapseBoxRgn;
+ else if (sc == SC_TitleBarMaxButton)
+ wrc = kWindowZoomBoxRgn;
+ else if (sc == SC_TitleBarLabel)
+ wrc = kWindowTitleTextRgn;
+ else if (sc == SC_TitleBarSysMenu)
+ ret.setRect(-1024, -1024, 10, proxy()->pixelMetric(PM_TitleBarHeight,
+ titlebar, widget));
+ if (wrc != kWindowGlobalPortRgn) {
+ QCFType<HIShapeRef> region;
+ QRect tmpRect = titlebar->rect;
+ HIRect titleRect = qt_hirectForQRect(tmpRect);
+ HIThemeGetWindowShape(&titleRect, &wdi, kWindowTitleBarRgn, &region);
+ ptrHIShapeGetBounds(region, &titleRect);
+ CFRelease(region);
+ tmpRect.translate(tmpRect.x() - int(titleRect.origin.x),
+ tmpRect.y() - int(titleRect.origin.y));
+ titleRect = qt_hirectForQRect(tmpRect);
+ HIThemeGetWindowShape(&titleRect, &wdi, wrc, &region);
+ ptrHIShapeGetBounds(region, &titleRect);
+ ret = qt_qrectForHIRect(titleRect);
+ }
+ }
+ break;
+ case CC_ComboBox:
+ if (const QStyleOptionComboBox *combo = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
+ HIThemeButtonDrawInfo bdi;
+ d->initComboboxBdi(combo, &bdi, widget, d->getDrawState(opt->state));
+
+ switch (sc) {
+ case SC_ComboBoxEditField:{
+ ret = QMacStylePrivate::comboboxEditBounds(combo->rect, bdi);
+ // hack to posistion the edit feld correctly for QDateTimeEdits
+ // in calendarPopup mode.
+ if (qobject_cast<const QDateTimeEdit *>(widget)) {
+ ret.moveTop(ret.top() - 2);
+ ret.setHeight(ret.height() +1);
+ }
+ break; }
+ case SC_ComboBoxArrow:{
+ ret = QMacStylePrivate::comboboxEditBounds(combo->rect, bdi);
+ ret.setX(ret.x() + ret.width());
+ ret.setWidth(combo->rect.right() - ret.right());
+ break; }
+ case SC_ComboBoxListBoxPopup:{
+ if (combo->editable) {
+ HIRect inner = QMacStylePrivate::comboboxInnerBounds(qt_hirectForQRect(combo->rect), bdi.kind);
+ QRect editRect = QMacStylePrivate::comboboxEditBounds(combo->rect, bdi);
+ const int comboTop = combo->rect.top();
+ ret = QRect(qRound(inner.origin.x),
+ comboTop,
+ qRound(inner.origin.x - combo->rect.left() + inner.size.width),
+ editRect.bottom() - comboTop + 2);
+ } else {
+ QRect editRect = QMacStylePrivate::comboboxEditBounds(combo->rect, bdi);
+ ret = QRect(combo->rect.x() + 4 - 11,
+ combo->rect.y() + 1,
+ editRect.width() + 10 + 11,
+ 1);
+ }
+ break; }
+ default:
+ break;
+ }
+ }
+ break;
+ case CC_GroupBox:
+ if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(opt)) {
+ bool checkable = groupBox->subControls & SC_GroupBoxCheckBox;
+ bool flat = (groupBox->features & QStyleOptionFrameV2::Flat);
+ bool hasNoText = !checkable && groupBox->text.isEmpty();
+ switch (sc) {
+ case SC_GroupBoxLabel:
+ case SC_GroupBoxCheckBox: {
+ // Cheat and use the smaller font if we need to
+ bool checkable = groupBox->subControls & SC_GroupBoxCheckBox;
+ bool fontIsSet = (widget && widget->testAttribute(Qt::WA_SetFont))
+ || !QApplication::desktopSettingsAware();
+ int tw;
+ int h;
+ int margin = flat || hasNoText ? 0 : 12;
+ ret = groupBox->rect.adjusted(margin, 0, -margin, 0);
+
+ if (!fontIsSet) {
+ HIThemeTextInfo tti;
+ tti.version = qt_mac_hitheme_version;
+ tti.state = kThemeStateActive;
+ tti.fontID = checkable ? kThemeSystemFont : kThemeSmallSystemFont;
+ tti.horizontalFlushness = kHIThemeTextHorizontalFlushCenter;
+ tti.verticalFlushness = kHIThemeTextVerticalFlushCenter;
+ tti.options = kHIThemeTextBoxOptionNone;
+ tti.truncationPosition = kHIThemeTextTruncationNone;
+ tti.truncationMaxLines = 1 + groupBox->text.count(QLatin1Char('\n'));
+ CGFloat width;
+ CGFloat height;
+ QCFString groupText = qt_mac_removeMnemonics(groupBox->text);
+ HIThemeGetTextDimensions(groupText, 0, &tti, &width, &height, 0);
+ tw = qRound(width);
+ h = qCeil(height);
+ } else {
+ QFontMetricsF fm = QFontMetricsF(groupBox->fontMetrics);
+ h = qCeil(fm.height());
+ tw = qCeil(fm.size(Qt::TextShowMnemonic, groupBox->text).width());
+ }
+ ret.setHeight(h);
+
+ QRect labelRect = alignedRect(groupBox->direction, groupBox->textAlignment,
+ QSize(tw, h), ret);
+ int indicatorWidth = proxy()->pixelMetric(PM_IndicatorWidth, opt, widget);
+ bool rtl = groupBox->direction == Qt::RightToLeft;
+ if (sc == SC_GroupBoxLabel) {
+ if (checkable) {
+ int newSum = indicatorWidth + 1;
+ int newLeft = labelRect.left() + (rtl ? -newSum : newSum);
+ labelRect.moveLeft(newLeft);
+ } else if (flat) {
+ int newLeft = labelRect.left() - (rtl ? 3 : -3);
+ labelRect.moveLeft(newLeft);
+ labelRect.moveTop(labelRect.top() + 3);
+ } else {
+ int newLeft = labelRect.left() - (rtl ? 3 : 2);
+ labelRect.moveLeft(newLeft);
+ labelRect.moveTop(labelRect.top() + 5);
+ }
+ ret = labelRect;
+ }
+
+ if (sc == SC_GroupBoxCheckBox) {
+ int left = rtl ? labelRect.right() - indicatorWidth : labelRect.left();
+ ret.setRect(left, ret.top(),
+ indicatorWidth, proxy()->pixelMetric(PM_IndicatorHeight, opt, widget));
+ }
+ break;
+ }
+ case SC_GroupBoxContents:
+ case SC_GroupBoxFrame: {
+ if (flat) {
+ ret = QWindowsStyle::subControlRect(cc, groupBox, sc, widget);
+ break;
+ }
+ QFontMetrics fm = groupBox->fontMetrics;
+ bool checkable = groupBox->subControls & SC_GroupBoxCheckBox;
+ int yOffset = 3;
+ if (!checkable) {
+ if (widget && !widget->testAttribute(Qt::WA_SetFont)
+ && QApplication::desktopSettingsAware())
+ fm = QFontMetrics(qt_app_fonts_hash()->value("QSmallFont", QFont()));
+ yOffset = 5;
+ if (hasNoText)
+ yOffset = -qCeil(QFontMetricsF(fm).height());
+ }
+
+ ret = opt->rect.adjusted(0, qCeil(QFontMetricsF(fm).height()) + yOffset, 0, 0);
+ if (sc == SC_GroupBoxContents)
+ ret.adjust(3, 3, -3, -4); // guess
+ }
+ break;
+ default:
+ ret = QWindowsStyle::subControlRect(cc, groupBox, sc, widget);
+ break;
+ }
+ }
+ break;
+ case CC_SpinBox:
+ if (const QStyleOptionSpinBox *spin = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
+ QAquaWidgetSize aquaSize = d->aquaSizeConstrain(spin, widget);
+ int spinner_w;
+ int spinBoxSep;
+ int fw = proxy()->pixelMetric(PM_SpinBoxFrameWidth, spin, widget);
+ switch (aquaSize) {
+ default:
+ case QAquaSizeUnknown:
+ case QAquaSizeLarge:
+ spinner_w = 14;
+ spinBoxSep = 2;
+ break;
+ case QAquaSizeSmall:
+ spinner_w = 12;
+ spinBoxSep = 2;
+ break;
+ case QAquaSizeMini:
+ spinner_w = 10;
+ spinBoxSep = 1;
+ break;
+ }
+
+ switch (sc) {
+ case SC_SpinBoxUp:
+ case SC_SpinBoxDown: {
+ if (spin->buttonSymbols == QAbstractSpinBox::NoButtons)
+ break;
+
+ const int y = fw;
+ const int x = spin->rect.width() - spinner_w;
+ ret.setRect(x + spin->rect.x(), y + spin->rect.y(), spinner_w, spin->rect.height() - y * 2);
+ HIThemeButtonDrawInfo bdi;
+ bdi.version = qt_mac_hitheme_version;
+ bdi.kind = kThemeIncDecButton;
+ int hackTranslateX;
+ switch (aquaSize) {
+ default:
+ case QAquaSizeUnknown:
+ case QAquaSizeLarge:
+ bdi.kind = kThemeIncDecButton;
+ hackTranslateX = 0;
+ break;
+ case QAquaSizeSmall:
+ bdi.kind = kThemeIncDecButtonSmall;
+ hackTranslateX = -2;
+ break;
+ case QAquaSizeMini:
+ bdi.kind = kThemeIncDecButtonMini;
+ hackTranslateX = -1;
+ break;
+ }
+ bdi.state = kThemeStateActive;
+ bdi.value = kThemeButtonOff;
+ bdi.adornment = kThemeAdornmentNone;
+ HIRect hirect = qt_hirectForQRect(ret);
+
+ HIRect outRect;
+ HIThemeGetButtonBackgroundBounds(&hirect, &bdi, &outRect);
+ ret = qt_qrectForHIRect(outRect);
+ switch (sc) {
+ case SC_SpinBoxUp:
+ ret.setHeight(ret.height() / 2);
+ break;
+ case SC_SpinBoxDown:
+ ret.setY(ret.y() + ret.height() / 2);
+ break;
+ default:
+ Q_ASSERT(0);
+ break;
+ }
+ ret.translate(hackTranslateX, 0); // hack: position the buttons correctly (weird that we need this)
+ ret = visualRect(spin->direction, spin->rect, ret);
+ break;
+ }
+ case SC_SpinBoxEditField:
+ if (spin->buttonSymbols == QAbstractSpinBox::NoButtons) {
+ ret.setRect(fw, fw,
+ spin->rect.width() - fw * 2,
+ spin->rect.height() - fw * 2);
+ } else {
+ ret.setRect(fw, fw,
+ spin->rect.width() - fw * 2 - spinBoxSep - spinner_w,
+ spin->rect.height() - fw * 2);
+ }
+ ret = visualRect(spin->direction, spin->rect, ret);
+ break;
+ default:
+ ret = QWindowsStyle::subControlRect(cc, spin, sc, widget);
+ break;
+ }
+ }
+ break;
+ case CC_ToolButton:
+ ret = QWindowsStyle::subControlRect(cc, opt, sc, widget);
+ if (sc == SC_ToolButtonMenu && widget && !qobject_cast<QToolBar*>(widget->parentWidget())) {
+ ret.adjust(-1, 0, 0, 0);
+ }
+ break;
+ default:
+ ret = QWindowsStyle::subControlRect(cc, opt, sc, widget);
+ break;
+ }
+ return ret;
+}
+
+QSize QMacStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt,
+ const QSize &csz, const QWidget *widget) const
+{
+ QSize sz(csz);
+ bool useAquaGuideline = true;
+
+ switch (ct) {
+ case QStyle::CT_SpinBox:
+ // hack to work around horrible sizeHint() code in QAbstractSpinBox
+ sz.setHeight(sz.height() - 3);
+ break;
+ case QStyle::CT_TabWidget:
+ // the size between the pane and the "contentsRect" (+4,+4)
+ // (the "contentsRect" is on the inside of the pane)
+ sz = QWindowsStyle::sizeFromContents(ct, opt, csz, widget);
+ /**
+ This is supposed to show the relationship between the tabBar and
+ the stack widget of a QTabWidget.
+ Unfortunately ascii is not a good way of representing graphics.....
+ PS: The '=' line is the painted frame.
+
+ top ---+
+ |
+ |
+ |
+ | vvv just outside the painted frame is the "pane"
+ - -|- - - - - - - - - - <-+
+ TAB BAR +=====^============ | +2 pixels
+ - - -|- - -|- - - - - - - <-+
+ | | ^ ^^^ just inside the painted frame is the "contentsRect"
+ | | |
+ | overlap |
+ | | |
+ bottom ------+ <-+ +14 pixels
+ |
+ v
+ ------------------------------ <- top of stack widget
+
+
+ To summarize:
+ * 2 is the distance between the pane and the contentsRect
+ * The 14 and the 1's are the distance from the contentsRect to the stack widget.
+ (same value as used in SE_TabWidgetTabContents)
+ * overlap is how much the pane should overlap the tab bar
+ */
+ // then add the size between the stackwidget and the "contentsRect"
+
+ if (const QStyleOptionTabWidgetFrame *twf
+ = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
+ QSize extra(0,0);
+ const int overlap = pixelMetric(PM_TabBarBaseOverlap, opt, widget);
+ const int gapBetweenTabbarAndStackWidget = 2 + 14 - overlap;
+
+ if (getTabDirection(twf->shape) == kThemeTabNorth || getTabDirection(twf->shape) == kThemeTabSouth) {
+ extra = QSize(2, gapBetweenTabbarAndStackWidget + 1);
+ } else {
+ extra = QSize(gapBetweenTabbarAndStackWidget + 1, 2);
+ }
+ sz+= extra;
+ }
+
+ break;
+ case QStyle::CT_TabBarTab:
+ if (const QStyleOptionTabV3 *tab = qstyleoption_cast<const QStyleOptionTabV3 *>(opt)) {
+ const QAquaWidgetSize AquaSize = d->aquaSizeConstrain(opt, widget);
+ const bool differentFont = (widget && widget->testAttribute(Qt::WA_SetFont))
+ || !QApplication::desktopSettingsAware();
+ ThemeTabDirection ttd = getTabDirection(tab->shape);
+ bool vertTabs = ttd == kThemeTabWest || ttd == kThemeTabEast;
+ if (vertTabs)
+ sz.transpose();
+ int defaultTabHeight;
+ int defaultExtraSpace = proxy()->pixelMetric(PM_TabBarTabHSpace, tab, widget); // Remove spurious gcc warning (AFAIK)
+ QFontMetrics fm = opt->fontMetrics;
+ switch (AquaSize) {
+ case QAquaSizeUnknown:
+ case QAquaSizeLarge:
+ if (tab->documentMode)
+ defaultTabHeight = 23;
+ else
+ defaultTabHeight = 21;
+ break;
+ case QAquaSizeSmall:
+ defaultTabHeight = 18;
+ break;
+ case QAquaSizeMini:
+ defaultTabHeight = 16;
+ break;
+ }
+ bool setWidth = false;
+ if (differentFont || !tab->icon.isNull()) {
+ sz.rheight() = qMax(defaultTabHeight, sz.height());
+ } else {
+ QSize textSize = fm.size(Qt::TextShowMnemonic, tab->text);
+ sz.rheight() = qMax(defaultTabHeight, textSize.height());
+ sz.rwidth() = textSize.width() + defaultExtraSpace;
+ setWidth = true;
+ }
+
+ if (vertTabs)
+ sz.transpose();
+
+ int maxWidgetHeight = qMax(tab->leftButtonSize.height(), tab->rightButtonSize.height());
+ int maxWidgetWidth = qMax(tab->leftButtonSize.width(), tab->rightButtonSize.width());
+
+ int widgetWidth = 0;
+ int widgetHeight = 0;
+ int padding = 0;
+ if (tab->leftButtonSize.isValid()) {
+ padding += 8;
+ widgetWidth += tab->leftButtonSize.width();
+ widgetHeight += tab->leftButtonSize.height();
+ }
+ if (tab->rightButtonSize.isValid()) {
+ padding += 8;
+ widgetWidth += tab->rightButtonSize.width();
+ widgetHeight += tab->rightButtonSize.height();
+ }
+
+ if (vertTabs) {
+ sz.setHeight(sz.height() + widgetHeight + padding);
+ sz.setWidth(qMax(sz.width(), maxWidgetWidth));
+ } else {
+ if (setWidth)
+ sz.setWidth(sz.width() + widgetWidth + padding);
+ sz.setHeight(qMax(sz.height(), maxWidgetHeight));
+ }
+ }
+ break;
+ case QStyle::CT_PushButton:
+ // By default, we fit the contents inside a normal rounded push button.
+ // Do this by add enough space around the contents so that rounded
+ // borders (including highlighting when active) will show.
+ sz.rwidth() += QMacStylePrivate::PushButtonLeftOffset + QMacStylePrivate::PushButtonRightOffset + 12;
+ sz.rheight() += QMacStylePrivate::PushButtonTopOffset + QMacStylePrivate::PushButtonBottomOffset;
+ break;
+ case QStyle::CT_MenuItem:
+ if (const QStyleOptionMenuItem *mi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
+ int maxpmw = mi->maxIconWidth;
+ const QComboBox *comboBox = qobject_cast<const QComboBox *>(widget);
+ int w = sz.width(),
+ h = sz.height();
+ if (mi->menuItemType == QStyleOptionMenuItem::Separator) {
+ w = 10;
+ SInt16 ash;
+ GetThemeMenuSeparatorHeight(&ash);
+ h = ash;
+ } else {
+ h = mi->fontMetrics.height() + 2;
+ if (!mi->icon.isNull()) {
+ if (comboBox) {
+ const QSize &iconSize = comboBox->iconSize();
+ h = qMax(h, iconSize.height() + 4);
+ maxpmw = qMax(maxpmw, iconSize.width());
+ } else {
+ int iconExtent = proxy()->pixelMetric(PM_SmallIconSize);
+ h = qMax(h, mi->icon.actualSize(QSize(iconExtent, iconExtent)).height() + 4);
+ }
+ }
+ }
+ if (mi->text.contains(QLatin1Char('\t')))
+ w += 12;
+ if (mi->menuItemType == QStyleOptionMenuItem::SubMenu)
+ w += 20;
+ if (maxpmw)
+ w += maxpmw + 6;
+ // add space for a check. All items have place for a check too.
+ w += 20;
+ if (comboBox && comboBox->isVisible()) {
+ QStyleOptionComboBox cmb;
+ cmb.initFrom(comboBox);
+ cmb.editable = false;
+ cmb.subControls = QStyle::SC_ComboBoxEditField;
+ cmb.activeSubControls = QStyle::SC_None;
+ w = qMax(w, subControlRect(QStyle::CC_ComboBox, &cmb,
+ QStyle::SC_ComboBoxEditField,
+ comboBox).width());
+ } else {
+ w += 12;
+ }
+ sz = QSize(w, h);
+ }
+ break;
+ case CT_ToolButton:
+ if (widget && qobject_cast<const QToolBar *>(widget->parentWidget())) {
+ if (QMainWindow * mainWindow = qobject_cast<QMainWindow *>(widget->parent())) {
+ if (mainWindow->unifiedTitleAndToolBarOnMac()) {
+ sz.rwidth() += 4;
+ if (sz.height() <= 32) {
+ // Workaround strange HIToolBar bug when getting constraints.
+ sz.rheight() += 1;
+ }
+ return sz;
+ }
+ }
+ }
+ sz.rwidth() += 10;
+ sz.rheight() += 10;
+ return sz;
+ case CT_ComboBox:
+ sz.rwidth() += 50;
+ break;
+ case CT_Menu: {
+ QStyleHintReturnMask menuMask;
+ QStyleOption myOption = *opt;
+ myOption.rect.setSize(sz);
+ if (proxy()->styleHint(SH_Menu_Mask, &myOption, widget, &menuMask)) {
+ sz = menuMask.region.boundingRect().size();
+ }
+ break; }
+ case CT_HeaderSection:{
+ const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt);
+ sz = QWindowsStyle::sizeFromContents(ct, opt, csz, widget);
+ if (header->text.contains(QLatin1Char('\n')))
+ useAquaGuideline = false;
+ break; }
+ case CT_ScrollBar :
+ // Make sure that the scroll bar is large enough to display the thumb indicator.
+ if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
+ const int minimumSize = scrollButtonsCutoffSize(thumbIndicatorCutoff, widgetSizePolicy(widget));
+ if (slider->orientation == Qt::Horizontal)
+ sz = sz.expandedTo(QSize(minimumSize, sz.height()));
+ else
+ sz = sz.expandedTo(QSize(sz.width(), minimumSize));
+ }
+ break;
+ case CT_ItemViewItem:
+ if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(opt)) {
+ sz = QCommonStyle::sizeFromContents(ct, vopt, csz, widget);
+ sz.setHeight(sz.height() + 2);
+ }
+ break;
+
+ default:
+ sz = QWindowsStyle::sizeFromContents(ct, opt, csz, widget);
+ }
+
+ if (useAquaGuideline){
+ QSize macsz;
+ if (d->aquaSizeConstrain(opt, widget, ct, sz, &macsz) != QAquaSizeUnknown) {
+ if (macsz.width() != -1)
+ sz.setWidth(macsz.width());
+ if (macsz.height() != -1)
+ sz.setHeight(macsz.height());
+ }
+ }
+
+ // The sizes that Carbon and the guidelines gives us excludes the focus frame.
+ // We compensate for this by adding some extra space here to make room for the frame when drawing:
+ if (const QStyleOptionComboBox *combo = qstyleoption_cast<const QStyleOptionComboBox *>(opt)){
+ QAquaWidgetSize widgetSize = d->aquaSizeConstrain(opt, widget);
+ int bkind = 0;
+ switch (widgetSize) {
+ default:
+ case QAquaSizeLarge:
+ bkind = combo->editable ? kThemeComboBox : kThemePopupButton;
+ break;
+ case QAquaSizeSmall:
+ bkind = combo->editable ? int(kThemeComboBoxSmall) : int(kThemePopupButtonSmall);
+ break;
+ case QAquaSizeMini:
+ bkind = combo->editable ? kThemeComboBoxMini : kThemePopupButtonMini;
+ break;
+ }
+ HIRect tmpRect = {{0, 0}, {0, 0}};
+ HIRect diffRect = QMacStylePrivate::comboboxInnerBounds(tmpRect, bkind);
+ sz.rwidth() -= qRound(diffRect.size.width);
+ sz.rheight() -= qRound(diffRect.size.height);
+ } else if (ct == CT_PushButton || ct == CT_ToolButton){
+ ThemeButtonKind bkind;
+ QAquaWidgetSize widgetSize = d->aquaSizeConstrain(opt, widget);
+ switch (ct) {
+ default:
+ case CT_PushButton:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
+ if (btn->features & QStyleOptionButton::CommandLinkButton) {
+ return QWindowsStyle::sizeFromContents(ct, opt, sz, widget);
+ }
+ }
+
+ switch (widgetSize) {
+ default:
+ case QAquaSizeLarge:
+ bkind = kThemePushButton;
+ break;
+ case QAquaSizeSmall:
+ bkind = kThemePushButtonSmall;
+ break;
+ case QAquaSizeMini:
+ bkind = kThemePushButtonMini;
+ break;
+ }
+ break;
+ case CT_ToolButton:
+ switch (widgetSize) {
+ default:
+ case QAquaSizeLarge:
+ bkind = kThemeLargeBevelButton;
+ break;
+ case QAquaSizeMini:
+ case QAquaSizeSmall:
+ bkind = kThemeSmallBevelButton;
+ }
+ break;
+ }
+
+ HIThemeButtonDrawInfo bdi;
+ bdi.version = qt_mac_hitheme_version;
+ bdi.state = kThemeStateActive;
+ bdi.kind = bkind;
+ bdi.value = kThemeButtonOff;
+ bdi.adornment = kThemeAdornmentNone;
+ HIRect macRect, myRect;
+ myRect = CGRectMake(0, 0, sz.width(), sz.height());
+ HIThemeGetButtonBackgroundBounds(&myRect, &bdi, &macRect);
+ // Mini buttons only return their actual size in HIThemeGetButtonBackgroundBounds, so help them out a bit (guess),
+ if (bkind == kThemePushButtonMini)
+ macRect.size.height += 8.;
+ else if (bkind == kThemePushButtonSmall)
+ macRect.size.height -= 10;
+ sz.setWidth(sz.width() + int(macRect.size.width - myRect.size.width));
+ sz.setHeight(sz.height() + int(macRect.size.height - myRect.size.height));
+ }
+ return sz;
+}
+
+void QMacStyle::drawItemText(QPainter *p, const QRect &r, int flags, const QPalette &pal,
+ bool enabled, const QString &text, QPalette::ColorRole textRole) const
+{
+ if(flags & Qt::TextShowMnemonic)
+ flags |= Qt::TextHideMnemonic;
+ QWindowsStyle::drawItemText(p, r, flags, pal, enabled, text, textRole);
+}
+
+bool QMacStyle::event(QEvent *e)
+{
+ if(e->type() == QEvent::FocusIn) {
+ QWidget *f = 0;
+ QWidget *focusWidget = QApplication::focusWidget();
+#ifndef QT_NO_GRAPHICSVIEW
+ if (QGraphicsView *graphicsView = qobject_cast<QGraphicsView *>(focusWidget)) {
+ QGraphicsItem *focusItem = graphicsView->scene() ? graphicsView->scene()->focusItem() : 0;
+ if (focusItem && focusItem->type() == QGraphicsProxyWidget::Type) {
+ QGraphicsProxyWidget *proxy = static_cast<QGraphicsProxyWidget *>(focusItem);
+ if (proxy->widget())
+ focusWidget = proxy->widget()->focusWidget();
+ }
+ }
+#endif
+ if (focusWidget && focusWidget->testAttribute(Qt::WA_MacShowFocusRect)) {
+ f = focusWidget;
+ QWidget *top = f->parentWidget();
+ while (top && !top->isWindow() && !(top->windowType() == Qt::SubWindow))
+ top = top->parentWidget();
+#ifndef QT_NO_MAINWINDOW
+ if (qobject_cast<QMainWindow *>(top)) {
+ QWidget *central = static_cast<QMainWindow *>(top)->centralWidget();
+ for (const QWidget *par = f; par; par = par->parentWidget()) {
+ if (par == central) {
+ top = central;
+ break;
+ }
+ if (par->isWindow())
+ break;
+ }
+ }
+#endif
+ }
+ if (f) {
+ if(!d->focusWidget)
+ d->focusWidget = new QFocusFrame(f);
+ d->focusWidget->setWidget(f);
+ } else if(d->focusWidget) {
+ d->focusWidget->setWidget(0);
+ }
+ } else if(e->type() == QEvent::FocusOut) {
+ if(d->focusWidget)
+ d->focusWidget->setWidget(0);
+ }
+ return false;
+}
+
+QIcon QMacStyle::standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *opt,
+ const QWidget *widget) const
+{
+ switch (standardIcon) {
+ default:
+ return QWindowsStyle::standardIconImplementation(standardIcon, opt, widget);
+ case SP_ToolBarHorizontalExtensionButton:
+ case SP_ToolBarVerticalExtensionButton: {
+ QPixmap pixmap(qt_mac_toolbar_ext);
+ if (standardIcon == SP_ToolBarVerticalExtensionButton) {
+ QPixmap pix2(pixmap.height(), pixmap.width());
+ pix2.fill(Qt::transparent);
+ QPainter p(&pix2);
+ p.translate(pix2.width(), 0);
+ p.rotate(90);
+ p.drawPixmap(0, 0, pixmap);
+ return pix2;
+ }
+ return pixmap;
+ }
+ }
+}
+
+int QMacStyle::layoutSpacingImplementation(QSizePolicy::ControlType control1,
+ QSizePolicy::ControlType control2,
+ Qt::Orientation orientation,
+ const QStyleOption *option,
+ const QWidget *widget) const
+{
+ const int ButtonMask = QSizePolicy::ButtonBox | QSizePolicy::PushButton;
+ bool isMetal = (widget && widget->testAttribute(Qt::WA_MacBrushedMetal));
+ int controlSize = getControlSize(option, widget);
+
+ if (control2 == QSizePolicy::ButtonBox) {
+ /*
+ AHIG seems to prefer a 12-pixel margin between group
+ boxes and the row of buttons. The 20 pixel comes from
+ Builder.
+ */
+ if (isMetal // (AHIG, guess, guess)
+ || (control1 & (QSizePolicy::Frame // guess
+ | QSizePolicy::GroupBox // (AHIG, guess, guess)
+ | QSizePolicy::TabWidget // guess
+ | ButtonMask))) { // AHIG
+ return_SIZE(14, 8, 8);
+ } else if (control1 == QSizePolicy::LineEdit) {
+ return_SIZE(8, 8, 8); // Interface Builder
+ } else {
+ return_SIZE(20, 7, 7); // Interface Builder
+ }
+ }
+
+ if ((control1 | control2) & ButtonMask) {
+ if (control1 == QSizePolicy::LineEdit)
+ return_SIZE(8, 8, 8); // Interface Builder
+ else if (control2 == QSizePolicy::LineEdit) {
+ if (orientation == Qt::Vertical)
+ return_SIZE(20, 7, 7); // Interface Builder
+ else
+ return_SIZE(20, 8, 8);
+ }
+ return_SIZE(14, 8, 8); // Interface Builder
+ }
+
+ switch (CT2(control1, control2)) {
+ case CT1(QSizePolicy::Label): // guess
+ case CT2(QSizePolicy::Label, QSizePolicy::DefaultType): // guess
+ case CT2(QSizePolicy::Label, QSizePolicy::CheckBox): // AHIG
+ case CT2(QSizePolicy::Label, QSizePolicy::ComboBox): // AHIG
+ case CT2(QSizePolicy::Label, QSizePolicy::LineEdit): // guess
+ case CT2(QSizePolicy::Label, QSizePolicy::RadioButton): // AHIG
+ case CT2(QSizePolicy::Label, QSizePolicy::Slider): // guess
+ case CT2(QSizePolicy::Label, QSizePolicy::SpinBox): // guess
+ case CT2(QSizePolicy::Label, QSizePolicy::ToolButton): // guess
+ return_SIZE(8, 6, 5);
+ case CT1(QSizePolicy::ToolButton):
+ return 8; // AHIG
+ case CT1(QSizePolicy::CheckBox):
+ case CT2(QSizePolicy::CheckBox, QSizePolicy::RadioButton):
+ case CT2(QSizePolicy::RadioButton, QSizePolicy::CheckBox):
+ if (orientation == Qt::Vertical)
+ return_SIZE(8, 8, 7); // AHIG and Builder
+ break;
+ case CT1(QSizePolicy::RadioButton):
+ if (orientation == Qt::Vertical)
+ return 5; // (Builder, guess, AHIG)
+ }
+
+ if (orientation == Qt::Horizontal
+ && (control2 & (QSizePolicy::CheckBox | QSizePolicy::RadioButton)))
+ return_SIZE(12, 10, 8); // guess
+
+ if ((control1 | control2) & (QSizePolicy::Frame
+ | QSizePolicy::GroupBox
+ | QSizePolicy::TabWidget)) {
+ /*
+ These values were chosen so that nested container widgets
+ look good side by side. Builder uses 8, which looks way
+ too small, and AHIG doesn't say anything.
+ */
+ return_SIZE(16, 10, 10); // guess
+ }
+
+ if ((control1 | control2) & (QSizePolicy::Line | QSizePolicy::Slider))
+ return_SIZE(12, 10, 8); // AHIG
+
+ if ((control1 | control2) & QSizePolicy::LineEdit)
+ return_SIZE(10, 8, 8); // AHIG
+
+ /*
+ AHIG and Builder differ by up to 4 pixels for stacked editable
+ comboboxes. We use some values that work fairly well in all
+ cases.
+ */
+ if ((control1 | control2) & QSizePolicy::ComboBox)
+ return_SIZE(10, 8, 7); // guess
+
+ /*
+ Builder defaults to 8, 6, 5 in lots of cases, but most of the time the
+ result looks too cramped.
+ */
+ return_SIZE(10, 8, 6); // guess
+}
+
+QT_END_NAMESPACE
diff --git a/src/widgets/styles/qmacstyle_mac_p.h b/src/widgets/styles/qmacstyle_mac_p.h
new file mode 100644
index 0000000000..747779249c
--- /dev/null
+++ b/src/widgets/styles/qmacstyle_mac_p.h
@@ -0,0 +1,241 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QMACSTYLE_MAC_P_H
+#define QMACSTYLE_MAC_P_H
+
+#include <qmacstyle_mac.h>
+#include <private/qapplication_p.h>
+#include <private/qcombobox_p.h>
+#include <private/qmacstylepixmaps_mac_p.h>
+#include <private/qpaintengine_mac_p.h>
+#include <private/qpainter_p.h>
+#include <private/qprintengine_mac_p.h>
+#include <private/qstylehelper_p.h>
+#include <qapplication.h>
+#include <qbitmap.h>
+#include <qcheckbox.h>
+#include <qcombobox.h>
+#include <qdialogbuttonbox.h>
+#include <qdockwidget.h>
+#include <qevent.h>
+#include <qfocusframe.h>
+#include <qformlayout.h>
+#include <qgroupbox.h>
+#include <qhash.h>
+#include <qheaderview.h>
+#include <qlayout.h>
+#include <qlineedit.h>
+#include <qlistview.h>
+#include <qmainwindow.h>
+#include <qmap.h>
+#include <qmenubar.h>
+#include <qpaintdevice.h>
+#include <qpainter.h>
+#include <qpixmapcache.h>
+#include <qpointer.h>
+#include <qprogressbar.h>
+#include <qpushbutton.h>
+#include <qradiobutton.h>
+#include <qrubberband.h>
+#include <qsizegrip.h>
+#include <qspinbox.h>
+#include <qsplitter.h>
+#include <qstyleoption.h>
+#include <qtextedit.h>
+#include <qtextstream.h>
+#include <qtoolbar.h>
+#include <qtoolbutton.h>
+#include <qtreeview.h>
+#include <qtableview.h>
+#include <qwizard.h>
+#include <qdebug.h>
+#include <qlibrary.h>
+#include <qdatetimeedit.h>
+#include <qmath.h>
+#include <QtWidgets/qgraphicsproxywidget.h>
+#include <QtWidgets/qgraphicsview.h>
+#include <private/qt_cocoa_helpers_mac_p.h>
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+QT_BEGIN_NAMESPACE
+
+#if (MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5)
+enum {
+ kThemePushButtonTextured = 31,
+ kThemePushButtonTexturedSmall = 32,
+ kThemePushButtonTexturedMini = 33
+};
+
+/* Search fields */
+enum {
+ kHIThemeFrameTextFieldRound = 1000,
+ kHIThemeFrameTextFieldRoundSmall = 1001,
+ kHIThemeFrameTextFieldRoundMini = 1002
+};
+#endif
+
+/*
+ AHIG:
+ Apple Human Interface Guidelines
+ http://developer.apple.com/documentation/UserExperience/Conceptual/OSXHIGuidelines/
+
+ Builder:
+ Apple Interface Builder v. 3.1.1
+*/
+
+// this works as long as we have at most 16 different control types
+#define CT1(c) CT2(c, c)
+#define CT2(c1, c2) ((uint(c1) << 16) | uint(c2))
+
+enum QAquaWidgetSize { QAquaSizeLarge = 0, QAquaSizeSmall = 1, QAquaSizeMini = 2,
+ QAquaSizeUnknown = -1 };
+
+#define SIZE(large, small, mini) \
+ (controlSize == QAquaSizeLarge ? (large) : controlSize == QAquaSizeSmall ? (small) : (mini))
+
+// same as return SIZE(...) but optimized
+#define return_SIZE(large, small, mini) \
+ do { \
+ static const int sizes[] = { (large), (small), (mini) }; \
+ return sizes[controlSize]; \
+ } while (0)
+
+bool qt_mac_buttonIsRenderedFlat(const QPushButton *pushButton, const QStyleOptionButton *option);
+
+class QMacStylePrivate : public QObject
+{
+ Q_OBJECT
+
+public:
+ QMacStylePrivate(QMacStyle *style);
+
+ // Ideally these wouldn't exist, but since they already exist we need some accessors.
+ static const int PushButtonLeftOffset;
+ static const int PushButtonTopOffset;
+ static const int PushButtonRightOffset;
+ static const int PushButtonBottomOffset;
+ static const int MiniButtonH;
+ static const int SmallButtonH;
+ static const int BevelButtonW;
+ static const int BevelButtonH;
+ static const int PushButtonContentPadding;
+
+
+ // Stuff from QAquaAnimate:
+ bool addWidget(QWidget *);
+ void removeWidget(QWidget *);
+
+ enum Animates { AquaPushButton, AquaProgressBar, AquaListViewItemOpen };
+ bool animatable(Animates, const QWidget *) const;
+ void stopAnimate(Animates, QWidget *);
+ void startAnimate(Animates, QWidget *);
+ static ThemeDrawState getDrawState(QStyle::State flags);
+ QAquaWidgetSize aquaSizeConstrain(const QStyleOption *option, const QWidget *widg,
+ QStyle::ContentsType ct = QStyle::CT_CustomBase,
+ QSize szHint=QSize(-1, -1), QSize *insz = 0) const;
+ void getSliderInfo(QStyle::ComplexControl cc, const QStyleOptionSlider *slider,
+ HIThemeTrackDrawInfo *tdi, const QWidget *needToRemoveMe);
+ bool doAnimate(Animates);
+ inline int animateSpeed(Animates) const { return 33; }
+
+ // Utility functions
+ void drawColorlessButton(const HIRect &macRect, HIThemeButtonDrawInfo *bdi,
+ QPainter *p, const QStyleOption *opt) const;
+
+ QSize pushButtonSizeFromContents(const QStyleOptionButton *btn) const;
+
+ HIRect pushButtonContentBounds(const QStyleOptionButton *btn,
+ const HIThemeButtonDrawInfo *bdi) const;
+
+ void initComboboxBdi(const QStyleOptionComboBox *combo, HIThemeButtonDrawInfo *bdi,
+ const QWidget *widget, const ThemeDrawState &tds);
+
+ static HIRect comboboxInnerBounds(const HIRect &outerBounds, int buttonKind);
+
+ static QRect comboboxEditBounds(const QRect &outerBounds, const HIThemeButtonDrawInfo &bdi);
+
+ static void drawCombobox(const HIRect &outerBounds, const HIThemeButtonDrawInfo &bdi, QPainter *p);
+ static void drawTableHeader(const HIRect &outerBounds, bool drawTopBorder, bool drawLeftBorder,
+ const HIThemeButtonDrawInfo &bdi, QPainter *p);
+ bool contentFitsInPushButton(const QStyleOptionButton *btn, HIThemeButtonDrawInfo *bdi,
+ ThemeButtonKind buttonKindToCheck) const;
+ void initHIThemePushButton(const QStyleOptionButton *btn, const QWidget *widget,
+ const ThemeDrawState tds,
+ HIThemeButtonDrawInfo *bdi) const;
+ QPixmap generateBackgroundPattern() const;
+protected:
+ bool eventFilter(QObject *, QEvent *);
+ void timerEvent(QTimerEvent *);
+
+private slots:
+ void startAnimationTimer();
+
+public:
+ QPointer<QPushButton> defaultButton; //default push buttons
+ int timerID;
+ QList<QPointer<QWidget> > progressBars; //existing progress bars that need animation
+
+ struct ButtonState {
+ int frame;
+ enum { ButtonDark, ButtonLight } dir;
+ } buttonState;
+ UInt8 progressFrame;
+ QPointer<QFocusFrame> focusWidget;
+ CFAbsoluteTime defaultButtonStart;
+ QMacStyle *q;
+ bool mouseDown;
+};
+
+QT_END_NAMESPACE
+
+#endif // QMACSTYLE_MAC_P_H
diff --git a/src/gui/styles/qmacstylepixmaps_mac_p.h b/src/widgets/styles/qmacstylepixmaps_mac_p.h
index 7bd1a2b43e..7bd1a2b43e 100644
--- a/src/gui/styles/qmacstylepixmaps_mac_p.h
+++ b/src/widgets/styles/qmacstylepixmaps_mac_p.h
diff --git a/src/widgets/styles/qmotifstyle.cpp b/src/widgets/styles/qmotifstyle.cpp
new file mode 100644
index 0000000000..d9be3f3643
--- /dev/null
+++ b/src/widgets/styles/qmotifstyle.cpp
@@ -0,0 +1,2721 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmotifstyle.h"
+#include "qcdestyle.h"
+
+#if !defined(QT_NO_STYLE_MOTIF) || defined(QT_PLUGIN)
+
+#include "qmenu.h"
+#include "qapplication.h"
+#include "qpainter.h"
+#include "qdrawutil.h"
+#include "qpixmap.h"
+#include "qpalette.h"
+#include "qwidget.h"
+#include "qpushbutton.h"
+#include "qscrollbar.h"
+#include "qtabbar.h"
+#include "qtabwidget.h"
+#include "qlistview.h"
+#include "qsplitter.h"
+#include "qslider.h"
+#include "qcombobox.h"
+#include "qlineedit.h"
+#include "qprogressbar.h"
+#include "qimage.h"
+#include "qfocusframe.h"
+#include "qdebug.h"
+#include "qpainterpath.h"
+#include "qmotifstyle_p.h"
+#include "qdialogbuttonbox.h"
+#include "qformlayout.h"
+#include <limits.h>
+#include <QtWidgets/qgraphicsproxywidget.h>
+#include <QtWidgets/qgraphicsview.h>
+
+#ifdef Q_WS_X11
+#include "qx11info_x11.h"
+#endif
+
+QT_BEGIN_NAMESPACE
+
+// old constants that might still be useful...
+static const int motifItemFrame = 2; // menu item frame width
+static const int motifSepHeight = 2; // separator item height
+static const int motifItemHMargin = 3; // menu item hor text margin
+static const int motifItemVMargin = 2; // menu item ver text margin
+static const int motifArrowHMargin = 6; // arrow horizontal margin
+static const int motifTabSpacing = 12; // space between text and tab
+static const int motifCheckMarkHMargin = 2; // horiz. margins of check mark
+static const int motifCheckMarkSpace = 16;
+
+
+/*!
+ \class QMotifStyle
+ \brief The QMotifStyle class provides Motif look and feel.
+
+ \ingroup appearance
+
+ This class implements the Motif look and feel. It closely
+ resembles the original Motif look as defined by the Open Group,
+ but with some minor improvements. The Motif style is Qt's default
+ GUI style on Unix platforms.
+
+ \img qmotifstyle.png
+ \sa QWindowsXPStyle, QMacStyle, QWindowsStyle, QPlastiqueStyle, QCDEStyle
+*/
+
+/*!
+ \variable QMotifStyle::focus
+ \internal
+*/
+
+/*!
+ Constructs a QMotifStyle.
+
+ If \a useHighlightCols is false (the default), the style will
+ polish the application's color palette to emulate the Motif way of
+ highlighting, which is a simple inversion between the base and the
+ text color.
+*/
+QMotifStyle::QMotifStyle(bool useHighlightCols)
+ : QCommonStyle(*new QMotifStylePrivate)
+{
+ focus = 0;
+ highlightCols = useHighlightCols;
+}
+
+
+/*!
+ \internal
+*/
+QMotifStyle::QMotifStyle(QMotifStylePrivate &dd, bool useHighlightColors)
+ : QCommonStyle(dd)
+{
+ focus = 0;
+ highlightCols = useHighlightColors;
+}
+
+
+/*!
+ \overload
+
+ Destroys the style.
+*/
+QMotifStyle::~QMotifStyle()
+{
+ delete focus;
+}
+
+/*!
+ \internal
+ Animate indeterminate progress bars only when visible
+*/
+bool QMotifStyle::eventFilter(QObject *o, QEvent *e)
+{
+#ifndef QT_NO_PROGRESSBAR
+ Q_D(QMotifStyle);
+ switch(e->type()) {
+ case QEvent::StyleChange:
+ case QEvent::Show:
+ if (QProgressBar *bar = qobject_cast<QProgressBar *>(o)) {
+ d->bars << bar;
+ if (d->bars.size() == 1) {
+ Q_ASSERT(d->animationFps> 0);
+ d->animateTimer = startTimer(1000 / d->animationFps);
+ }
+ }
+ break;
+ case QEvent::Destroy:
+ case QEvent::Hide:
+ // reinterpret_cast because there is no type info when getting
+ // the destroy event. We know that it is a QProgressBar.
+ if (QProgressBar *bar = reinterpret_cast<QProgressBar *>(o)) {
+ d->bars.removeAll(bar);
+ if (d->bars.isEmpty() && d->animateTimer) {
+ killTimer(d->animateTimer);
+ d->animateTimer = 0;
+ }
+ }
+ default:
+ break;
+ }
+#endif // QT_NO_PROGRESSBAR
+ return QStyle::eventFilter(o, e);
+}
+
+/*!
+ \internal
+*/
+QIcon QMotifStyle::standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *opt,
+ const QWidget *widget) const
+{
+ return QCommonStyle::standardIconImplementation(standardIcon, opt, widget);
+}
+
+/*!
+ \reimp
+*/
+void QMotifStyle::timerEvent(QTimerEvent *event)
+{
+#ifndef QT_NO_PROGRESSBAR
+ Q_D(QMotifStyle);
+ if (event->timerId() == d->animateTimer) {
+ Q_ASSERT(d->animationFps > 0);
+ d->animateStep = d->startTime.elapsed() / (1000 / d->animationFps);
+ foreach (QProgressBar *bar, d->bars) {
+ if ((bar->minimum() == 0 && bar->maximum() == 0))
+ bar->update();
+ }
+ }
+#endif // QT_NO_PROGRESSBAR
+ event->ignore();
+}
+
+
+QMotifStylePrivate::QMotifStylePrivate()
+#ifndef QT_NO_PROGRESSBAR
+ : animationFps(25), animateTimer(0), animateStep(0)
+#endif
+{
+}
+
+/*!
+ If \a arg is false, the style will polish the application's color
+ palette to emulate the Motif way of highlighting, which is a
+ simple inversion between the base and the text color.
+
+ The effect will show up the next time an application palette is
+ set via QApplication::setPalette(). The current color palette of
+ the application remains unchanged.
+
+ \sa QStyle::polish()
+*/
+void QMotifStyle::setUseHighlightColors(bool arg)
+{
+ highlightCols = arg;
+}
+
+/*!
+ Returns true if the style treats the highlight colors of the
+ palette in a Motif-like manner, which is a simple inversion
+ between the base and the text color; otherwise returns false. The
+ default is false.
+*/
+bool QMotifStyle::useHighlightColors() const
+{
+ return highlightCols;
+}
+
+/*! \reimp */
+
+void QMotifStyle::polish(QPalette& pal)
+{
+ if (pal.brush(QPalette::Active, QPalette::Light) == pal.brush(QPalette::Active, QPalette::Base)) {
+ QColor nlight = pal.color(QPalette::Active, QPalette::Light).darker(108);
+ pal.setColor(QPalette::Active, QPalette::Light, nlight) ;
+ pal.setColor(QPalette::Disabled, QPalette::Light, nlight) ;
+ pal.setColor(QPalette::Inactive, QPalette::Light, nlight) ;
+ }
+
+ if (highlightCols)
+ return;
+
+ // force the ugly motif way of highlighting *sigh*
+ pal.setColor(QPalette::Active, QPalette::Highlight,
+ pal.color(QPalette::Active, QPalette::Text));
+ pal.setColor(QPalette::Active, QPalette::HighlightedText,
+ pal.color(QPalette::Active, QPalette::Base));
+ pal.setColor(QPalette::Disabled, QPalette::Highlight,
+ pal.color(QPalette::Disabled, QPalette::Text));
+ pal.setColor(QPalette::Disabled, QPalette::HighlightedText,
+ pal.color(QPalette::Disabled, QPalette::Base));
+ pal.setColor(QPalette::Inactive, QPalette::Highlight,
+ pal.color(QPalette::Active, QPalette::Text));
+ pal.setColor(QPalette::Inactive, QPalette::HighlightedText,
+ pal.color(QPalette::Active, QPalette::Base));
+}
+
+/*!
+ \reimp
+ \internal
+ Keep QStyle::polish() visible.
+*/
+void QMotifStyle::polish(QWidget* widget)
+{
+ QStyle::polish(widget);
+#ifndef QT_NO_PROGRESSBAR
+ if (qobject_cast<QProgressBar *>(widget))
+ widget->installEventFilter(this);
+#endif
+}
+
+/*!
+ \reimp
+ \internal
+ Keep QStyle::polish() visible.
+*/
+void QMotifStyle::unpolish(QWidget* widget)
+{
+ QCommonStyle::unpolish(widget);
+#ifndef QT_NO_PROGRESSBAR
+ if (qobject_cast<QProgressBar *>(widget)) {
+ Q_D(QMotifStyle);
+ widget->removeEventFilter(this);
+ d->bars.removeAll(static_cast<QProgressBar*>(widget));
+ }
+#endif
+}
+
+
+/*!
+ \reimp
+ \internal
+ Keep QStyle::polish() visible.
+*/
+void QMotifStyle::polish(QApplication* a)
+{
+ QCommonStyle::polish(a);
+}
+
+
+/*!
+ \reimp
+ \internal
+ Keep QStyle::polish() visible.
+*/
+void QMotifStyle::unpolish(QApplication* a)
+{
+ QCommonStyle::unpolish(a);
+}
+
+static void rot(QPolygon& a, int n)
+{
+ QPolygon r(a.size());
+ for (int i = 0; i < (int)a.size(); i++) {
+ switch (n) {
+ case 1: r.setPoint(i,-a[i].y(),a[i].x()); break;
+ case 2: r.setPoint(i,-a[i].x(),-a[i].y()); break;
+ case 3: r.setPoint(i,a[i].y(),-a[i].x()); break;
+ }
+ }
+ a = r;
+}
+
+
+/*!
+ \reimp
+*/
+void QMotifStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p,
+ const QWidget *w) const
+{
+ switch(pe) {
+ case PE_Q3CheckListExclusiveIndicator:
+ if (const QStyleOptionQ3ListView *lv = qstyleoption_cast<const QStyleOptionQ3ListView *>(opt)) {
+ if (lv->items.isEmpty())
+ return;
+
+ if (lv->state & State_Enabled)
+ p->setPen(QPen(opt->palette.text().color()));
+ else
+ p->setPen(QPen(lv->palette.color(QPalette::Disabled, QPalette::Text)));
+ QPolygon a;
+
+ int cx = opt->rect.width()/2 - 1;
+ int cy = opt->rect.height()/2;
+ int e = opt->rect.width()/2 - 1;
+ for (int i = 0; i < 3; i++) { //penWidth 2 doesn't quite work
+ a.setPoints(4, cx-e, cy, cx, cy-e, cx+e, cy, cx, cy+e);
+ p->drawPolygon(a);
+ e--;
+ }
+ if (opt->state & State_On) {
+ if (lv->state & State_Enabled)
+ p->setPen(QPen(opt->palette.text().color()));
+ else
+ p->setPen(QPen(lv->palette.color(QPalette::Disabled,
+ QPalette::Text)));
+ QBrush saveBrush = p->brush();
+ p->setBrush(opt->palette.text());
+ e = e - 2;
+ a.setPoints(4, cx-e, cy, cx, cy-e, cx+e, cy, cx, cy+e);
+ p->drawPolygon(a);
+ p->setBrush(saveBrush);
+ }
+ }
+ break;
+
+ case PE_FrameTabWidget:
+ case PE_FrameWindow:
+ qDrawShadePanel(p, opt->rect, opt->palette, QStyle::State_None, proxy()->pixelMetric(PM_DefaultFrameWidth));
+ break;
+ case PE_FrameFocusRect:
+ if (const QStyleOptionFocusRect *fropt = qstyleoption_cast<const QStyleOptionFocusRect *>(opt)) {
+ if ((fropt->state & State_HasFocus) && focus && focus->isVisible()
+ && !(fropt->state & QStyle::State_Item))
+ break;
+ QCommonStyle::drawPrimitive(pe, opt, p, w);
+ }
+ break;
+
+ case PE_IndicatorToolBarHandle: {
+ p->save();
+ p->translate(opt->rect.x(), opt->rect.y());
+
+ QColor dark(opt->palette.dark().color());
+ QColor light(opt->palette.light().color());
+ int i;
+ if (opt->state & State_Horizontal) {
+ int h = opt->rect.height();
+ if (h > 6) {
+ if (opt->state & State_On)
+ p->fillRect(1, 1, 8, h - 2, opt->palette.highlight());
+ QPolygon a(2 * ((h-6)/3));
+ int y = 3 + (h%3)/2;
+ p->setPen(dark);
+ p->drawLine(8, 1, 8, h-2);
+ for (i=0; 2*i < a.size(); ++i) {
+ a.setPoint(2*i, 5, y+1+3*i);
+ a.setPoint(2*i+1, 2, y+2+3*i);
+ }
+ p->drawPoints(a);
+ p->setPen(light);
+ p->drawLine(9, 1, 9, h-2);
+ for (i=0; 2*i < a.size(); i++) {
+ a.setPoint(2*i, 4, y+3*i);
+ a.setPoint(2*i+1, 1, y+1+3*i);
+ }
+ p->drawPoints(a);
+ // if (drawBorder) {
+ // p->setPen(QPen(Qt::darkGray));
+ // p->drawLine(0, opt->rect.height() - 1,
+ // tbExtent, opt->rect.height() - 1);
+ // }
+ }
+ } else {
+ int w = opt->rect.width();
+ if (w > 6) {
+ if (opt->state & State_On)
+ p->fillRect(1, 1, w - 2, 9, opt->palette.highlight());
+ QPolygon a(2 * ((w-6)/3));
+
+ int x = 3 + (w%3)/2;
+ p->setPen(dark);
+ p->drawLine(1, 8, w-2, 8);
+ for (i=0; 2*i < a.size(); ++i) {
+ a.setPoint(2*i, x+1+3*i, 6);
+ a.setPoint(2*i+1, x+2+3*i, 3);
+ }
+ p->drawPoints(a);
+ p->setPen(light);
+ p->drawLine(1, 9, w-2, 9);
+ for (i=0; 2*i < a.size(); ++i) {
+ a.setPoint(2*i, x+3*i, 5);
+ a.setPoint(2*i+1, x+1+3*i, 2);
+ }
+ p->drawPoints(a);
+ // if (drawBorder) {
+ // p->setPen(QPen(Qt::darkGray));
+ // p->drawLine(opt->rect.width() - 1, 0,
+ // opt->rect.width() - 1, tbExtent);
+ // }
+ }
+ }
+ p->restore();
+ break; }
+
+ case PE_PanelButtonCommand:
+ case PE_PanelButtonBevel:
+ case PE_PanelButtonTool: {
+ QBrush fill;
+ if (opt->state & State_Sunken)
+ fill = opt->palette.brush(QPalette::Mid);
+ else if ((opt->state & State_On) && (opt->state & State_Enabled))
+ fill = QBrush(opt->palette.mid().color(), Qt::Dense4Pattern);
+ else
+ fill = opt->palette.brush(QPalette::Button);
+ if ((opt->state & State_Enabled || opt->state & State_On) || !(opt->state & State_AutoRaise))
+ qDrawShadePanel(p, opt->rect, opt->palette, bool(opt->state & (State_Sunken | State_On)),
+ proxy()->pixelMetric(PM_DefaultFrameWidth), &fill);
+ break; }
+
+ case PE_IndicatorCheckBox: {
+ bool on = opt->state & State_On;
+ bool down = opt->state & State_Sunken;
+ bool showUp = !(down ^ on);
+ QBrush fill = opt->palette.brush((showUp || opt->state & State_NoChange) ?QPalette::Button : QPalette::Mid);
+ if (opt->state & State_NoChange) {
+ qDrawPlainRect(p, opt->rect, opt->palette.text().color(),
+ 1, &fill);
+ p->drawLine(opt->rect.x() + opt->rect.width() - 1, opt->rect.y(),
+ opt->rect.x(), opt->rect.y() + opt->rect.height() - 1);
+ } else {
+ qDrawShadePanel(p, opt->rect, opt->palette, !showUp,
+ proxy()->pixelMetric(PM_DefaultFrameWidth), &fill);
+ }
+ if (!(opt->state & State_Enabled) && proxy()->styleHint(SH_DitherDisabledText))
+ p->fillRect(opt->rect, QBrush(p->background().color(), Qt::Dense5Pattern));
+ break; }
+
+ case PE_IndicatorRadioButton: {
+#define INTARRLEN(x) sizeof(x)/(sizeof(int)*2)
+ int inner_pts[] = { // used for filling diamond
+ 2,opt->rect.height()/2,
+ opt->rect.width()/2,2,
+ opt->rect.width()-3,opt->rect.height()/2,
+ opt->rect.width()/2,opt->rect.height()-3
+ };
+ int top_pts[] = { // top (^) of diamond
+ 0,opt->rect.height()/2,
+ opt->rect.width()/2,0,
+ opt->rect.width()-2,opt->rect.height()/2-1,
+ opt->rect.width()-3,opt->rect.height()/2-1,
+ opt->rect.width()/2,1,
+ 1,opt->rect.height()/2,
+ 2,opt->rect.height()/2,
+ opt->rect.width()/2,2,
+ opt->rect.width()-4,opt->rect.height()/2-1
+ };
+ int bottom_pts[] = { // bottom (v) of diamond
+ 1,opt->rect.height()/2+1,
+ opt->rect.width()/2,opt->rect.height()-1,
+ opt->rect.width()-1,opt->rect.height()/2,
+ opt->rect.width()-2,opt->rect.height()/2,
+ opt->rect.width()/2,opt->rect.height()-2,
+ 2,opt->rect.height()/2+1,
+ 3,opt->rect.height()/2+1,
+ opt->rect.width()/2,opt->rect.height()-3,
+ opt->rect.width()-3,opt->rect.height()/2
+ };
+ bool on = opt->state & State_On;
+ bool down = opt->state & State_Sunken;
+ bool showUp = !(down ^ on);
+ QPen oldPen = p->pen();
+ QBrush oldBrush = p->brush();
+ QPolygon a(INTARRLEN(inner_pts), inner_pts);
+ p->setPen(Qt::NoPen);
+ p->setBrush(opt->palette.brush(showUp ? QPalette::Button : QPalette::Mid));
+ a.translate(opt->rect.x(), opt->rect.y());
+ p->drawPolygon(a);
+ p->setPen(showUp ? opt->palette.light().color() : opt->palette.dark().color());
+ p->setBrush(Qt::NoBrush);
+ a.setPoints(INTARRLEN(top_pts), top_pts);
+ a.translate(opt->rect.x(), opt->rect.y());
+ p->drawPolyline(a);
+ p->setPen(showUp ? opt->palette.dark().color() : opt->palette.light().color());
+ a.setPoints(INTARRLEN(bottom_pts), bottom_pts);
+ a.translate(opt->rect.x(), opt->rect.y());
+ p->drawPolyline(a);
+ if (!(opt->state & State_Enabled) && proxy()->styleHint(SH_DitherDisabledText))
+ p->fillRect(opt->rect, QBrush(p->background().color(), Qt::Dense5Pattern));
+ p->setPen(oldPen);
+ p->setBrush(oldBrush);
+ break; }
+
+ case PE_IndicatorSpinUp:
+ case PE_IndicatorSpinPlus:
+ case PE_IndicatorSpinDown:
+ case PE_IndicatorSpinMinus:
+ case PE_IndicatorArrowUp:
+ case PE_IndicatorArrowDown:
+ case PE_IndicatorArrowRight:
+ case PE_IndicatorArrowLeft: {
+ QRect rect = opt->rect;
+ QPolygon bFill;
+ QPolygon bTop;
+ QPolygon bBot;
+ QPolygon bLeft;
+ if (pe == PE_IndicatorSpinPlus || pe == PE_IndicatorSpinUp)
+ pe = PE_IndicatorArrowUp;
+ else if (pe == PE_IndicatorSpinMinus || pe == PE_IndicatorSpinDown)
+ pe = PE_IndicatorArrowDown;
+ bool vertical = pe == PE_IndicatorArrowUp || pe == PE_IndicatorArrowDown;
+ bool horizontal = !vertical;
+ int dim = rect.width() < rect.height() ? rect.width() : rect.height();
+ int colspec = 0x0000;
+
+ if (!(opt->state & State_Enabled))
+ dim -= 2;
+ if(dim < 2)
+ break;
+
+ // adjust size and center (to fix rotation below)
+ if (rect.width() > dim) {
+ rect.setX(rect.x() + ((rect.width() - dim) / 2));
+ rect.setWidth(dim);
+ }
+ if (rect.height() > dim) {
+ rect.setY(rect.y() + ((rect.height() - dim) / 2));
+ rect.setHeight(dim);
+ }
+
+ if (dim > 3) {
+ if (pixelMetric(PM_DefaultFrameWidth) < 2) { // thin style
+ bFill.resize( dim & 1 ? 3 : 4 );
+ bTop.resize( 2 );
+ bBot.resize( 2 );
+ bLeft.resize( 2 );
+ bLeft.putPoints( 0, 2, 0, 0, 0, dim-1 );
+ bTop.putPoints( 0, 2, 1, 0, dim-1, dim/2 );
+ bBot.putPoints( 0, 2, 1, dim-1, dim-1, dim/2 );
+
+ if ( dim > 6 ) { // dim>6: must fill interior
+ bFill.putPoints( 0, 2, 0, dim-1, 0, 0 );
+ if ( dim & 1 ) // if size is an odd number
+ bFill.setPoint( 2, dim - 1, dim / 2 );
+ else
+ bFill.putPoints( 2, 2, dim-1, dim/2-1, dim-1, dim/2 );
+ }
+ } else {
+ if (dim > 6)
+ bFill.resize(dim & 1 ? 3 : 4);
+ bTop.resize((dim/2)*2);
+ bBot.resize(dim & 1 ? dim + 1 : dim);
+ bLeft.resize(dim > 4 ? 4 : 2);
+ bLeft.putPoints(0, 2, 0,0, 0,dim-1);
+ if (dim > 4)
+ bLeft.putPoints(2, 2, 1,2, 1,dim-3);
+ bTop.putPoints(0, 4, 1,0, 1,1, 2,1, 3,1);
+ bBot.putPoints(0, 4, 1,dim-1, 1,dim-2, 2,dim-2, 3,dim-2);
+
+ for(int i=0; i<dim/2-2 ; i++) {
+ bTop.putPoints(i*2+4, 2, 2+i*2,2+i, 5+i*2, 2+i);
+ bBot.putPoints(i*2+4, 2, 2+i*2,dim-3-i, 5+i*2,dim-3-i);
+ }
+ if (dim & 1) // odd number size: extra line
+ bBot.putPoints(dim-1, 2, dim-3,dim/2, dim-1,dim/2);
+ if (dim > 6) { // dim>6: must fill interior
+ bFill.putPoints(0, 2, 1,dim-3, 1,2);
+ if (dim & 1) // if size is an odd number
+ bFill.setPoint(2, dim - 3, dim / 2);
+ else
+ bFill.putPoints(2, 2, dim-4,dim/2-1, dim-4,dim/2);
+ }
+ }
+ } else {
+ if (dim == 3) { // 3x3 arrow pattern
+ bLeft.setPoints(4, 0,0, 0,2, 1,1, 1,1);
+ bTop .setPoints(2, 1,0, 1,0);
+ bBot .setPoints(2, 1,2, 2,1);
+ }
+ else { // 2x2 arrow pattern
+ bLeft.setPoints(2, 0,0, 0,1);
+ bTop .setPoints(2, 1,0, 1,0);
+ bBot .setPoints(2, 1,1, 1,1);
+ }
+ }
+
+ // We use rot() and translate() as it is more efficient that
+ // matrix transformations on the painter, and because it still
+ // works with QT_NO_TRANSFORMATIONS defined.
+
+ if (pe == PE_IndicatorArrowUp || pe == PE_IndicatorArrowLeft) {
+ if (vertical) {
+ rot(bFill,3);
+ rot(bLeft,3);
+ rot(bTop,3);
+ rot(bBot,3);
+ bFill.translate(0, rect.height() - 1);
+ bLeft.translate(0, rect.height() - 1);
+ bTop.translate(0, rect.height() - 1);
+ bBot.translate(0, rect.height() - 1);
+ } else {
+ rot(bFill,2);
+ rot(bLeft,2);
+ rot(bTop,2);
+ rot(bBot,2);
+ bFill.translate(rect.width() - 1, rect.height() - 1);
+ bLeft.translate(rect.width() - 1, rect.height() - 1);
+ bTop.translate(rect.width() - 1, rect.height() - 1);
+ bBot.translate(rect.width() - 1, rect.height() - 1);
+ }
+ if (opt->state & State_Sunken)
+ colspec = horizontal ? 0x2334 : 0x2343;
+ else
+ colspec = horizontal ? 0x1443 : 0x1434;
+ } else {
+ if (vertical) {
+ rot(bFill,1);
+ rot(bLeft,1);
+ rot(bTop,1);
+ rot(bBot,1);
+ bFill.translate(rect.width() - 1, 0);
+ bLeft.translate(rect.width() - 1, 0);
+ bTop.translate(rect.width() - 1, 0);
+ bBot.translate(rect.width() - 1, 0);
+ }
+ if (opt->state & State_Sunken)
+ colspec = horizontal ? 0x2443 : 0x2434;
+ else
+ colspec = horizontal ? 0x1334 : 0x1343;
+ }
+ bFill.translate(rect.x(), rect.y());
+ bLeft.translate(rect.x(), rect.y());
+ bTop.translate(rect.x(), rect.y());
+ bBot.translate(rect.x(), rect.y());
+
+ const QColor *cols[5];
+ if (opt->state & State_Enabled) {
+ cols[0] = 0;
+ cols[1] = &opt->palette.button().color();
+ cols[2] = &opt->palette.mid().color();
+ cols[3] = &opt->palette.light().color();
+ cols[4] = &opt->palette.dark().color();
+ } else {
+ cols[0] = 0;
+ cols[1] = &opt->palette.mid().color();
+ cols[2] = &opt->palette.mid().color();
+ cols[3] = &opt->palette.mid().color();
+ cols[4] = &opt->palette.mid().color();
+ }
+
+#define CMID *cols[(colspec>>12) & 0xf]
+#define CLEFT *cols[(colspec>>8) & 0xf]
+#define CTOP *cols[(colspec>>4) & 0xf]
+#define CBOT *cols[colspec & 0xf]
+
+ QPen savePen = p->pen();
+ QBrush saveBrush = p->brush();
+ QPen pen(Qt::NoPen);
+ QBrush brush = opt->palette.brush((opt->state & State_Enabled) ?
+ QPalette::Button : QPalette::Mid);
+ p->setPen(pen);
+ p->setBrush(brush);
+ p->drawPolygon(bFill);
+ p->setBrush(Qt::NoBrush);
+
+ p->setPen(CLEFT);
+ p->drawPolyline(bLeft);
+ p->setPen(CTOP);
+ p->drawPolyline(bTop);
+ p->setPen(CBOT);
+ p->drawPolyline(bBot);
+
+ p->setBrush(saveBrush);
+ p->setPen(savePen);
+#undef CMID
+#undef CLEFT
+#undef CTOP
+#undef CBOT
+ if (!(opt->state & State_Enabled) && proxy()->styleHint(SH_DitherDisabledText))
+ p->fillRect(opt->rect, QBrush(p->background().color(), Qt::Dense5Pattern));
+ break; }
+
+ case PE_IndicatorDockWidgetResizeHandle: {
+ const int motifOffset = 10;
+ int sw = proxy()->pixelMetric(PM_SplitterWidth);
+ if (opt->state & State_Horizontal) {
+ int yPos = opt->rect.y() + opt->rect.height() / 2;
+ int kPos = opt->rect.right() - motifOffset - sw;
+ int kSize = sw - 2;
+
+ qDrawShadeLine(p, opt->rect.left(), yPos, kPos, yPos, opt->palette);
+ qDrawShadePanel(p, kPos, yPos - sw / 2 + 1, kSize, kSize,
+ opt->palette, false, 1, &opt->palette.brush(QPalette::Button));
+ qDrawShadeLine(p, kPos + kSize - 1, yPos, opt->rect.right(), yPos, opt->palette);
+ } else {
+ int xPos = opt->rect.x() + opt->rect.width() / 2;
+ int kPos = motifOffset;
+ int kSize = sw - 2;
+
+ qDrawShadeLine(p, xPos, opt->rect.top() + kPos + kSize - 1, xPos, opt->rect.bottom(), opt->palette);
+ qDrawShadePanel(p, xPos - sw / 2 + 1, opt->rect.top() + kPos, kSize, kSize, opt->palette,
+ false, 1, &opt->palette.brush(QPalette::Button));
+ qDrawShadeLine(p, xPos, opt->rect.top(), xPos, opt->rect.top() + kPos, opt->palette);
+ }
+ break; }
+
+ case PE_IndicatorMenuCheckMark: {
+ const int markW = 6;
+ const int markH = 6;
+ int posX = opt->rect.x() + (opt->rect.width() - markW) / 2 - 1;
+ int posY = opt->rect.y() + (opt->rect.height() - markH) / 2;
+ int dfw = proxy()->pixelMetric(PM_DefaultFrameWidth);
+
+ if (dfw < 2) {
+ // Could do with some optimizing/caching...
+ QPolygon a(7*2);
+ int i, xx, yy;
+ xx = posX;
+ yy = 3 + posY;
+ for (i=0; i<3; i++) {
+ a.setPoint(2*i, xx, yy);
+ a.setPoint(2*i+1, xx, yy+2);
+ xx++; yy++;
+ }
+ yy -= 2;
+ for (i=3; i<7; i++) {
+ a.setPoint(2*i, xx, yy);
+ a.setPoint(2*i+1, xx, yy+2);
+ xx++; yy--;
+ }
+ if (! (opt->state & State_Enabled) && ! (opt->state & State_On)) {
+ int pnt;
+ p->setPen(opt->palette.highlightedText().color());
+ QPoint offset(1,1);
+ for (pnt = 0; pnt < (int)a.size(); pnt++)
+ a[pnt] += offset;
+ p->drawPolyline(a);
+ for (pnt = 0; pnt < (int)a.size(); pnt++)
+ a[pnt] -= offset;
+ }
+ p->setPen(opt->palette.text().color());
+ p->drawPolyline(a);
+
+ qDrawShadePanel(p, posX-2, posY-2, markW+4, markH+6, opt->palette, true, dfw);
+ } else
+ qDrawShadePanel(p, posX, posY, markW, markH, opt->palette, true, dfw,
+ &opt->palette.brush(QPalette::Mid));
+
+ break; }
+
+ case PE_IndicatorProgressChunk:
+ {
+ bool vertical = false;
+ if (const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(opt))
+ vertical = (pb2->orientation == Qt::Vertical);
+ if (!vertical) {
+ p->fillRect(opt->rect.x(), opt->rect.y(), opt->rect.width(),
+ opt->rect.height(), opt->palette.brush(QPalette::Highlight));
+ } else {
+ p->fillRect(opt->rect.x(), opt->rect.y(), opt->rect.width(), opt->rect.height(),
+ opt->palette.brush(QPalette::Highlight));
+ }
+ }
+ break;
+
+ default:
+ QCommonStyle::drawPrimitive(pe, opt, p, w);
+ break;
+ }
+}
+
+
+/*!
+ \reimp
+*/
+void QMotifStyle::drawControl(ControlElement element, const QStyleOption *opt, QPainter *p,
+ const QWidget *widget) const
+{
+ switch(element) {
+ case CE_Splitter: {
+ QStyleOption handleOpt = *opt;
+ if (handleOpt.state & State_Horizontal)
+ handleOpt.state &= ~State_Horizontal;
+ else
+ handleOpt.state |= State_Horizontal;
+ proxy()->drawPrimitive(PE_IndicatorDockWidgetResizeHandle, &handleOpt, p, widget);
+ break; }
+
+ case CE_ScrollBarSubLine:
+ case CE_ScrollBarAddLine:{
+ PrimitiveElement pe;
+ if (element == CE_ScrollBarAddLine)
+ pe = (opt->state & State_Horizontal) ? (opt->direction == Qt::LeftToRight ? PE_IndicatorArrowRight : PE_IndicatorArrowLeft) : PE_IndicatorArrowDown;
+ else
+ pe = (opt->state & State_Horizontal) ? (opt->direction == Qt::LeftToRight ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight) : PE_IndicatorArrowUp;
+ QStyleOption arrowOpt = *opt;
+ arrowOpt.state |= State_Enabled;
+ proxy()->drawPrimitive(pe, &arrowOpt, p, widget);
+ if (!(opt->state & State_Enabled) && proxy()->styleHint(SH_DitherDisabledText)) {
+ int fw = proxy()->pixelMetric(PM_DefaultFrameWidth);
+ p->fillRect(opt->rect.adjusted(fw, fw, -fw, -fw), QBrush(p->background().color(), Qt::Dense5Pattern));
+ }
+ }break;
+
+ case CE_ScrollBarSubPage:
+ case CE_ScrollBarAddPage:
+ p->fillRect(opt->rect, opt->palette.brush((opt->state & State_Enabled) ? QPalette::Mid : QPalette::Window));
+ break;
+
+ case CE_ScrollBarSlider: {
+ QStyleOption bevelOpt = *opt;
+ bevelOpt.state |= State_Raised;
+ bevelOpt.state &= ~(State_Sunken | State_On);
+ p->save();
+ p->setBrushOrigin(bevelOpt.rect.topLeft());
+ proxy()->drawPrimitive(PE_PanelButtonBevel, &bevelOpt, p, widget);
+ p->restore();
+ if (!(opt->state & State_Enabled) && proxy()->styleHint(SH_DitherDisabledText))
+ p->fillRect(opt->rect, QBrush(p->background().color(), Qt::Dense5Pattern));
+ break; }
+
+ case CE_RadioButton:
+ case CE_CheckBox:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
+ bool isRadio = (element == CE_RadioButton);
+ QStyleOptionButton subopt = *btn;
+ subopt.rect = subElementRect(isRadio ? SE_RadioButtonIndicator
+ : SE_CheckBoxIndicator, btn, widget);
+ proxy()->drawPrimitive(isRadio ? PE_IndicatorRadioButton : PE_IndicatorCheckBox,
+ &subopt, p, widget);
+ subopt.rect = subElementRect(isRadio ? SE_RadioButtonContents
+ : SE_CheckBoxContents, btn, widget);
+ proxy()->drawControl(isRadio ? CE_RadioButtonLabel : CE_CheckBoxLabel, &subopt, p, widget);
+ if ((btn->state & State_HasFocus) && (!focus || !focus->isVisible())) {
+ QStyleOptionFocusRect fropt;
+ fropt.QStyleOption::operator=(*btn);
+ fropt.rect = subElementRect(isRadio ? SE_RadioButtonFocusRect
+ : SE_CheckBoxFocusRect, btn, widget);
+ proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, p, widget);
+ }
+ }
+ break;
+ case CE_PushButton:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
+ proxy()->drawControl(CE_PushButtonBevel, btn, p, widget);
+ QStyleOptionButton subopt = *btn;
+ subopt.rect = subElementRect(SE_PushButtonContents, btn, widget);
+ proxy()->drawControl(CE_PushButtonLabel, &subopt, p, widget);
+ if ((btn->state & State_HasFocus) && (!focus || !focus->isVisible())) {
+ QStyleOptionFocusRect fropt;
+ fropt.QStyleOption::operator=(*btn);
+ fropt.rect = subElementRect(SE_PushButtonFocusRect, btn, widget);
+ proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, p, widget);
+ }
+ }
+ break;
+ case CE_PushButtonBevel:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
+ int diw, x1, y1, x2, y2;
+ p->setPen(opt->palette.foreground().color());
+ p->setBrush(QBrush(opt->palette.button().color(), Qt::NoBrush));
+ diw = proxy()->pixelMetric(PM_ButtonDefaultIndicator);
+ opt->rect.getCoords(&x1, &y1, &x2, &y2);
+ if (btn->features & (QStyleOptionButton::AutoDefaultButton|QStyleOptionButton::DefaultButton)) {
+ x1 += diw;
+ y1 += diw;
+ x2 -= diw;
+ y2 -= diw;
+ }
+ if (btn->features & QStyleOptionButton::DefaultButton) {
+ if (diw == 0) {
+ QPolygon a;
+ a.setPoints(9,
+ x1, y1, x2, y1, x2, y2, x1, y2, x1, y1+1,
+ x2-1, y1+1, x2-1, y2-1, x1+1, y2-1, x1+1, y1+1);
+ p->setPen(opt->palette.shadow().color());
+ p->drawPolygon(a);
+ x1 += 2;
+ y1 += 2;
+ x2 -= 2;
+ y2 -= 2;
+ } else {
+ qDrawShadePanel(p, opt->rect.adjusted(1, 1, -1, -1), opt->palette, true);
+ }
+ }
+ if (!(btn->features & QStyleOptionButton::Flat) ||
+ (btn->state & (State_Sunken | State_On))) {
+ QStyleOptionButton newOpt = *btn;
+ newOpt.rect = QRect(x1, y1, x2 - x1 + 1, y2 - y1 + 1);
+ p->setBrushOrigin(p->brushOrigin());
+ proxy()->drawPrimitive(PE_PanelButtonCommand, &newOpt, p, widget);
+ }
+ if (btn->features & QStyleOptionButton::HasMenu) {
+ int mbi = proxy()->pixelMetric(PM_MenuButtonIndicator, btn, widget);
+ QRect ir = btn->rect;
+ QStyleOptionButton newBtn = *btn;
+ newBtn.rect = QRect(ir.right() - mbi - 3, ir.y() + 4, mbi, ir.height() - 8);
+ proxy()->drawPrimitive(PE_IndicatorArrowDown, &newBtn, p, widget);
+ }
+ break;
+ }
+
+#ifndef QT_NO_TABBAR
+ case CE_TabBarTabShape:
+ if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
+ const int default_frame = proxy()->pixelMetric(PM_DefaultFrameWidth, tab, widget);
+ const int frame_offset = (default_frame > 1) ? 1 : 0;
+
+ if (tab->shape == QTabBar::RoundedNorth || tab->shape == QTabBar::RoundedEast ||
+ tab->shape == QTabBar::RoundedSouth || tab->shape == QTabBar::RoundedWest) {
+ p->save();
+ QRect tabRect = opt->rect;
+ QColor tabLight = opt->palette.light().color();
+ QColor tabDark = opt->palette.dark().color();
+
+ p->fillRect(opt->rect.adjusted(default_frame, default_frame,
+ -default_frame, -default_frame),
+ tab->palette.background());
+
+ if(tab->shape == QTabBar::RoundedWest) {
+ tabDark = opt->palette.light().color();
+ tabLight = opt->palette.dark().color();
+ tabRect = QRect(0, 0, tabRect.height(), tabRect.width());
+ p->translate(opt->rect.left(), opt->rect.bottom());
+ p->rotate(-90);
+ } else if(tab->shape == QTabBar::RoundedSouth) {
+ tabDark = opt->palette.light().color();
+ tabLight = opt->palette.dark().color();
+ tabRect = QRect(0, 0, tabRect.width(), tabRect.height());
+ p->translate(opt->rect.right(), opt->rect.bottom());
+ p->rotate(180);
+ } else if(tab->shape == QTabBar::RoundedEast) {
+ tabRect = QRect(0, 0, tabRect.height(), tabRect.width());
+ p->translate(opt->rect.right(), opt->rect.top());
+ p->rotate(90);
+ }
+
+ if (default_frame > 1) {
+ p->setPen(tabLight);
+ p->drawLine(tabRect.left(), tabRect.bottom(),
+ tabRect.right(), tabRect.bottom());
+ p->setPen(tabLight);
+ p->drawLine(tabRect.left(), tabRect.bottom()-1,
+ tabRect.right(), tabRect.bottom()-1);
+ if (tabRect.left() == 0)
+ p->drawPoint(tabRect.bottomLeft());
+ } else {
+ p->setPen(tabLight);
+ p->drawLine(tabRect.left(), tabRect.bottom(),
+ tabRect.right(), tabRect.bottom());
+ }
+
+ if (opt->state & State_Selected) {
+ p->fillRect(QRect(tabRect.left()+1, tabRect.bottom()-frame_offset,
+ tabRect.width()-3, 2),
+ tab->palette.brush(QPalette::Active, QPalette::Background));
+ p->setPen(tab->palette.background().color());
+ p->drawLine(tabRect.left()+1, tabRect.bottom(),
+ tabRect.left()+1, tabRect.top()+2);
+ p->setPen(tabLight);
+ } else {
+ p->setPen(tabLight);
+ }
+ p->drawLine(tabRect.left(), tabRect.bottom()-1,
+ tabRect.left(), tabRect.top() + 2);
+ p->drawPoint(tabRect.left()+1, tabRect.top() + 1);
+ p->drawLine(tabRect.left()+2, tabRect.top(),
+ tabRect.right() - 2, tabRect.top());
+ p->drawPoint(tabRect.left(), tabRect.bottom());
+
+ if (default_frame > 1) {
+ p->drawLine(tabRect.left()+1, tabRect.bottom(),
+ tabRect.left()+1, tabRect.top() + 2);
+ p->drawLine(tabRect.left()+2, tabRect.top()+1,
+ tabRect.right() - 2, tabRect.top()+1);
+ }
+
+ p->setPen(tabDark);
+ p->drawLine(tabRect.right() - 1, tabRect.top() + 2,
+ tabRect.right() - 1, tabRect.bottom() - 1 +
+ ((opt->state & State_Selected) ? frame_offset : -frame_offset));
+ if (default_frame > 1) {
+ p->drawPoint(tabRect.right() - 1, tabRect.top() + 1);
+ p->drawLine(tabRect.right(), tabRect.top() + 2, tabRect.right(),
+ tabRect.bottom() -
+ ((opt->state & State_Selected) ?
+ ((tab->position == QStyleOptionTab::End) ? 0:1):1+frame_offset));
+ p->drawPoint(tabRect.right() - 1, tabRect.top() + 1);
+ }
+ p->restore();
+ } else {
+ QCommonStyle::drawControl(element, opt, p, widget);
+ }
+ break; }
+#endif // QT_NO_TABBAR
+ case CE_ProgressBarGroove:
+ qDrawShadePanel(p, opt->rect, opt->palette, true, 2);
+ break;
+
+ case CE_ProgressBarLabel:
+ if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) {
+ QTransform oldMatrix = p->transform();
+ QRect rect = pb->rect;
+ bool vertical = false;
+ bool invert = false;
+ bool bottomToTop = false;
+ if (const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(opt)) {
+ vertical = (pb2->orientation == Qt::Vertical);
+ invert = pb2->invertedAppearance;
+ bottomToTop = pb2->bottomToTop;
+ }
+ if (vertical) {
+ QTransform m;
+ rect = QRect(rect.left(), rect.top(), rect.height(), rect.width()); // flip width and height
+ if (bottomToTop) {
+ m.translate(0.0, rect.width());
+ m.rotate(-90);
+ } else {
+ m.translate(rect.height(), 0.0);
+ m.rotate(90);
+ }
+ p->setTransform(m, true);
+ }
+ const int unit_width = proxy()->pixelMetric(PM_ProgressBarChunkWidth, opt, widget);
+ int u = rect.width() / unit_width;
+ int p_v = pb->progress - pb->minimum;
+ int t_s = qMax(0, pb->maximum - pb->minimum);
+ if (u > 0 && pb->progress >= INT_MAX / u && t_s >= u) {
+ // scale down to something usable.
+ p_v /= u;
+ t_s /= u;
+ }
+ if (pb->textVisible && t_s) {
+ int nu = (u * p_v + t_s/2) / t_s;
+ int x = unit_width * nu;
+ QRect left(rect.x(), rect.y(), x, rect.height());
+ QRect right(rect.x() + x, rect.y(), rect.width() - x, rect.height());
+ Qt::LayoutDirection dir;
+ dir = vertical ? (bottomToTop ? Qt::LeftToRight : Qt::RightToLeft) : pb->direction;
+ if (invert)
+ dir = (dir == Qt::LeftToRight) ? Qt::RightToLeft : Qt::LeftToRight;
+ const QRect highlighted = visualRect(dir, rect, left);
+ const QRect background = visualRect(dir, rect, right);
+ p->setPen(opt->palette.highlightedText().color());
+ p->setClipRect(highlighted);
+ p->drawText(rect, Qt::AlignCenter | Qt::TextSingleLine, pb->text);
+
+ if (pb->progress != pb->maximum) {
+ p->setClipRect(background);
+ p->setPen(opt->palette.highlight().color());
+ p->drawText(rect, Qt::AlignCenter | Qt::TextSingleLine, pb->text);
+ }
+ }
+ p->setTransform(oldMatrix, false);
+ break;
+ }
+
+ case CE_MenuTearoff: {
+ if(opt->state & State_Selected) {
+ if(pixelMetric(PM_MenuPanelWidth, opt, widget) > 1)
+ qDrawShadePanel(p, opt->rect.x(), opt->rect.y(), opt->rect.width(),
+ opt->rect.height(), opt->palette, false, motifItemFrame,
+ &opt->palette.brush(QPalette::Button));
+ else
+ qDrawShadePanel(p, opt->rect.x()+1, opt->rect.y()+1, opt->rect.width()-2,
+ opt->rect.height()-2, opt->palette, true, 1, &opt->palette.brush(QPalette::Button));
+ } else {
+ p->fillRect(opt->rect, opt->palette.brush(QPalette::Button));
+ }
+ p->setPen(QPen(opt->palette.dark().color(), 1, Qt::DashLine));
+ p->drawLine(opt->rect.x()+2, opt->rect.y()+opt->rect.height()/2-1, opt->rect.x()+opt->rect.width()-4,
+ opt->rect.y()+opt->rect.height()/2-1);
+ p->setPen(QPen(opt->palette.light().color(), 1, Qt::DashLine));
+ p->drawLine(opt->rect.x()+2, opt->rect.y()+opt->rect.height()/2, opt->rect.x()+opt->rect.width()-4,
+ opt->rect.y()+opt->rect.height()/2);
+ break; }
+
+ case CE_MenuItem:
+ if (const QStyleOptionMenuItem *menuitem = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
+ int maxpmw = menuitem->maxIconWidth;
+ if(menuitem->menuHasCheckableItems)
+ maxpmw = qMax(maxpmw, motifCheckMarkSpace);
+
+ int x, y, w, h;
+ opt->rect.getRect(&x, &y, &w, &h);
+
+ if (menuitem->menuItemType == QStyleOptionMenuItem::Separator) { // draw separator
+ int textWidth = 0;
+ if (!menuitem->text.isEmpty()) {
+ QFont oldFont = p->font();
+ p->setFont(menuitem->font);
+ p->fillRect(x, y, w, h, opt->palette.brush(QPalette::Button));
+ proxy()->drawItemText(p, menuitem->rect.adjusted(10, 0, -5, 0), Qt::AlignLeft | Qt::AlignVCenter,
+ menuitem->palette, menuitem->state & State_Enabled, menuitem->text,
+ QPalette::Text);
+ textWidth = menuitem->fontMetrics.width(menuitem->text) + 10;
+ y += menuitem->fontMetrics.height() / 2;
+ p->setFont(oldFont);
+ }
+ p->setPen(opt->palette.dark().color());
+ p->drawLine(x, y, x + 5, y);
+ p->drawLine(x + 5 + textWidth, y, x+w, y);
+ p->setPen(opt->palette.light().color());
+ p->drawLine(x, y + 1, x + 5, y + 1);
+ p->drawLine(x + 5 + textWidth, y + 1, x+w, y + 1);
+ return;
+ }
+
+ int pw = motifItemFrame;
+ if((opt->state & State_Selected) && (opt->state & State_Enabled)) { // active item frame
+ if(pixelMetric(PM_MenuPanelWidth, opt) > 1)
+ qDrawShadePanel(p, x, y, w, h, opt->palette, false, pw,
+ &opt->palette.brush(QPalette::Button));
+ else
+ qDrawShadePanel(p, x+1, y+1, w-2, h-2, opt->palette, true, 1,
+ &opt->palette.brush(QPalette::Button));
+ } else { // incognito frame
+ p->fillRect(x, y, w, h, opt->palette.brush(QPalette::Button));
+ }
+
+ QRect vrect = visualRect(opt->direction, opt->rect,
+ QRect(x+motifItemFrame, y+motifItemFrame, maxpmw,
+ h-2*motifItemFrame));
+ int xvis = vrect.x();
+ if (menuitem->checked) {
+ if(!menuitem->icon.isNull())
+ qDrawShadePanel(p, xvis, y+motifItemFrame, maxpmw, h-2*motifItemFrame,
+ opt->palette, true, 1, &opt->palette.brush(QPalette::Midlight));
+ } else if (!(opt->state & State_Selected)) {
+ p->fillRect(xvis, y+motifItemFrame, maxpmw, h-2*motifItemFrame,
+ opt->palette.brush(QPalette::Button));
+ }
+
+ if(!menuitem->icon.isNull()) { // draw icon
+ QIcon::Mode mode = QIcon::Normal; // no disabled icons in Motif
+ if ((opt->state & State_Selected) && !!(opt->state & State_Enabled))
+ mode = QIcon::Active;
+ QPixmap pixmap;
+ if (menuitem->checkType != QStyleOptionMenuItem::NotCheckable && menuitem->checked)
+ pixmap = menuitem->icon.pixmap(pixelMetric(PM_SmallIconSize, opt, widget), mode, QIcon::On);
+ else
+ pixmap = menuitem->icon.pixmap(pixelMetric(PM_SmallIconSize, opt, widget), mode);
+
+ int pixw = pixmap.width();
+ int pixh = pixmap.height();
+ QRect pmr(0, 0, pixw, pixh);
+ pmr.moveCenter(vrect.center());
+ p->setPen(opt->palette.text().color());
+ p->drawPixmap(pmr.topLeft(), pixmap);
+
+ } else if (menuitem->checkType != QStyleOptionMenuItem::NotCheckable) { // just "checking"...
+ int mh = h - 2*motifItemFrame;
+
+ QStyleOptionButton newMenuItem;
+ newMenuItem.state = menuitem->checked ? State_On : State_None;
+ if (opt->state & State_Enabled) {
+ newMenuItem.state |= State_Enabled;
+ if (menuitem->state & State_Sunken)
+ newMenuItem.state |= State_Sunken;
+ }
+ if (menuitem->checkType & QStyleOptionMenuItem::Exclusive) {
+ newMenuItem.rect.setRect(xvis + 2, y + motifItemFrame + mh / 4, 11, 11);
+ proxy()->drawPrimitive(PE_IndicatorRadioButton, &newMenuItem, p, widget);
+ } else {
+ newMenuItem.rect.setRect(xvis + 5, y + motifItemFrame + mh / 4, 9, 9);
+ proxy()->drawPrimitive(PE_IndicatorCheckBox, &newMenuItem, p, widget);
+ }
+ }
+
+ p->setPen(opt->palette.buttonText().color());
+
+ QColor discol;
+ if (!(opt->state & State_Enabled)) {
+ discol = opt->palette.text().color();
+ p->setPen(discol);
+ }
+
+ int xm = motifItemFrame + maxpmw + motifItemHMargin;
+
+ vrect = visualRect(opt->direction, opt->rect,
+ QRect(x+xm, y+motifItemVMargin, w-xm-menuitem->tabWidth,
+ h-2*motifItemVMargin));
+ xvis = vrect.x();
+
+ QString s = menuitem->text;
+ if (!s.isNull()) { // draw text
+ int t = s.indexOf(QLatin1Char('\t'));
+ int m = motifItemVMargin;
+ int text_flags = Qt::AlignVCenter|Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
+ text_flags |= Qt::AlignLeft;
+ QFont oldFont = p->font();
+ p->setFont(menuitem->font);
+ if (t >= 0) { // draw tab text
+ QRect vr = visualRect(opt->direction, opt->rect,
+ QRect(x+w-menuitem->tabWidth-motifItemHMargin-motifItemFrame,
+ y+motifItemVMargin, menuitem->tabWidth,
+ h-2*motifItemVMargin));
+ int xv = vr.x();
+ QRect tr(xv, y+m, menuitem->tabWidth, h-2*m);
+ p->drawText(tr, text_flags, s.mid(t+1));
+ if (!(opt->state & State_Enabled) && proxy()->styleHint(SH_DitherDisabledText))
+ p->fillRect(tr, QBrush(p->background().color(), Qt::Dense5Pattern));
+ s = s.left(t);
+ }
+ QRect tr(xvis, y+m, w - xm - menuitem->tabWidth + 1, h-2*m);
+ p->drawText(tr, text_flags, s.left(t));
+ p->setFont(oldFont);
+ if (!(opt->state & State_Enabled) && proxy()->styleHint(SH_DitherDisabledText))
+ p->fillRect(tr, QBrush(p->background().color(), Qt::Dense5Pattern));
+ }
+ if (menuitem->menuItemType == QStyleOptionMenuItem::SubMenu) { // draw sub menu arrow
+ int dim = (h-2*motifItemFrame) / 2;
+ QStyle::PrimitiveElement arrow = (opt->direction == Qt::RightToLeft ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight);
+ QStyleOption arrowOpt = *opt;
+ arrowOpt.rect = visualRect(opt->direction, opt->rect,
+ QRect(x+w - motifArrowHMargin - motifItemFrame - dim,
+ y+h/2-dim/2, dim, dim));
+ if ((opt->state & State_Selected))
+ arrowOpt.state = (State_Sunken | ((opt->state & State_Enabled) ? State_Enabled : State_None));
+ else
+ arrowOpt.state = ((opt->state & State_Enabled) ? State_Enabled : State_None);
+ proxy()->drawPrimitive(arrow, &arrowOpt, p, widget);
+ }
+ break; }
+
+ case CE_MenuBarItem:
+ if (opt->state & State_Selected) // active item
+ qDrawShadePanel(p, opt->rect, opt->palette, false, motifItemFrame,
+ &opt->palette.brush(QPalette::Button));
+ else // other item
+ p->fillRect(opt->rect, opt->palette.brush(QPalette::Button));
+ QCommonStyle::drawControl(element, opt, p, widget);
+ break;
+
+ case CE_HeaderSection:
+ p->save();
+ p->setBrushOrigin(opt->rect.topLeft());
+ qDrawShadePanel(p, opt->rect, opt->palette, bool(opt->state & (State_Sunken|State_On)),
+ proxy()->pixelMetric(PM_DefaultFrameWidth),
+ &opt->palette.brush((opt->state & State_Sunken) ? QPalette::Mid : QPalette::Button));
+ p->restore();
+ break;
+ case CE_RubberBand: {
+ QPixmap tiledPixmap(16, 16);
+ QPainter pixmapPainter(&tiledPixmap);
+ pixmapPainter.setPen(Qt::NoPen);
+ pixmapPainter.setBrush(Qt::Dense4Pattern);
+ pixmapPainter.setBackground(QBrush(opt->palette.base()));
+ pixmapPainter.setBackgroundMode(Qt::OpaqueMode);
+ pixmapPainter.drawRect(0, 0, tiledPixmap.width(), tiledPixmap.height());
+ pixmapPainter.end();
+ // ### workaround for borked XRENDER
+ tiledPixmap = QPixmap::fromImage(tiledPixmap.toImage());
+
+ p->save();
+ QRect r = opt->rect;
+ QStyleHintReturnMask mask;
+ if (styleHint(QStyle::SH_RubberBand_Mask, opt, widget, &mask))
+ p->setClipRegion(mask.region);
+ p->drawTiledPixmap(r.x(), r.y(), r.width(), r.height(), tiledPixmap);
+ p->restore();
+ }
+ break;
+#ifndef QT_NO_PROGRESSBAR
+ case CE_ProgressBarContents:
+ if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) {
+ QRect rect = pb->rect;
+ bool vertical = false;
+ bool inverted = false;
+
+ // Get extra style options if version 2
+ const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(opt);
+ if (pb2) {
+ vertical = (pb2->orientation == Qt::Vertical);
+ inverted = pb2->invertedAppearance;
+ }
+
+ QTransform m;
+ if (vertical) {
+ rect = QRect(rect.left(), rect.top(), rect.height(), rect.width()); // flip width and height
+ m.rotate(90);
+ m.translate(0, -(rect.height() + rect.y()*2));
+ }
+
+ QPalette pal2 = pb->palette;
+ // Correct the highlight color if it is the same as the background
+ if (pal2.highlight() == pal2.background())
+ pal2.setColor(QPalette::Highlight, pb->palette.color(QPalette::Active,
+ QPalette::Highlight));
+ bool reverse = ((!vertical && (pb->direction == Qt::RightToLeft)) || vertical);
+ if (inverted)
+ reverse = !reverse;
+ int w = rect.width();
+ if (pb->minimum == 0 && pb->maximum == 0) {
+ QRect progressBar;
+ Q_D(const QMotifStyle);
+ // draw busy indicator
+ int x = (d->animateStep*8)% (w * 2);
+ if (x > w)
+ x = 2 * w - x;
+ x = reverse ? rect.right() - x : x + rect.x();
+ p->setTransform(m, true);
+ p->setPen(QPen(pal2.highlight().color(), 4));
+ p->drawLine(x, rect.y(), x, rect.height());
+
+ } else
+ QCommonStyle::drawControl(element, opt, p, widget);
+ }
+ break;
+#endif // QT_NO_PROGRESSBAR
+ default:
+ QCommonStyle::drawControl(element, opt, p, widget);
+ break; }
+}
+
+static int get_combo_extra_width(int h, int w, int *return_awh=0)
+{
+ int awh,
+ tmp;
+ if (h < 8) {
+ awh = 6;
+ } else if (h < 14) {
+ awh = h - 2;
+ } else {
+ awh = h/2;
+ }
+ tmp = (awh * 3) / 2;
+ if (tmp > w / 2) {
+ awh = w / 2 - 3;
+ tmp = w / 2 + 3;
+ }
+
+ if (return_awh)
+ *return_awh = awh;
+
+ return tmp;
+}
+
+static void get_combo_parameters(const QRect &r,
+ int &ew, int &awh, int &ax,
+ int &ay, int &sh, int &dh,
+ int &sy)
+{
+ ew = get_combo_extra_width(r.height(), r.width(), &awh);
+
+ sh = (awh+3)/4;
+ if (sh < 3)
+ sh = 3;
+ dh = sh/2 + 1;
+
+ ay = r.y() + (r.height()-awh-sh-dh)/2;
+ if (ay < 0) {
+ //panic mode
+ ay = 0;
+ sy = r.height();
+ } else {
+ sy = ay+awh+dh;
+ }
+ ax = r.x() + r.width() - ew;
+ ax += (ew-awh)/2;
+}
+
+/*!
+ \reimp
+*/
+void QMotifStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p,
+ const QWidget *widget) const
+{
+ switch (cc) {
+ case CC_ToolButton:
+ if (const QStyleOptionToolButton *toolbutton
+ = qstyleoption_cast<const QStyleOptionToolButton *>(opt)) {
+ QRect button, menuarea;
+ button = proxy()->subControlRect(cc, toolbutton, SC_ToolButton, widget);
+ menuarea = proxy()->subControlRect(cc, toolbutton, SC_ToolButtonMenu, widget);
+
+ State bflags = toolbutton->state & ~State_Sunken;
+ if (bflags & State_AutoRaise) {
+ if (!(bflags & State_MouseOver) || !(bflags & State_Enabled)) {
+ bflags &= ~State_Raised;
+ }
+ }
+ State mflags = bflags;
+ if (toolbutton->state & State_Sunken) {
+ if (toolbutton->activeSubControls & SC_ToolButton)
+ bflags |= State_Sunken;
+ mflags |= State_Sunken;
+ }
+
+ QStyleOption tool(0);
+ tool.palette = toolbutton->palette;
+ if (toolbutton->subControls & SC_ToolButton) {
+ if (bflags & (State_Sunken | State_On | State_Raised)) {
+ tool.rect = button;
+ tool.state = bflags;
+ proxy()->drawPrimitive(PE_PanelButtonTool, &tool, p, widget);
+ }
+ }
+
+ if ((toolbutton->state & State_HasFocus) && (!focus || !focus->isVisible())) {
+ QStyleOptionFocusRect fr;
+ fr.QStyleOption::operator=(*toolbutton);
+ fr.rect = toolbutton->rect.adjusted(3, 3, -3, -3);
+ proxy()->drawPrimitive(PE_FrameFocusRect, &fr, p, widget);
+ }
+ QStyleOptionToolButton label = *toolbutton;
+ label.state = bflags;
+ int fw = proxy()->pixelMetric(PM_DefaultFrameWidth, opt, widget);
+ label.rect = button.adjusted(fw, fw, -fw, -fw);
+ proxy()->drawControl(CE_ToolButtonLabel, &label, p, widget);
+
+ if (toolbutton->subControls & SC_ToolButtonMenu) {
+ tool.rect = menuarea;
+ tool.state = mflags;
+ if (mflags & (State_Sunken | State_On | State_Raised))
+ proxy()->drawPrimitive(PE_IndicatorButtonDropDown, &tool, p, widget);
+ proxy()->drawPrimitive(PE_IndicatorArrowDown, &tool, p, widget);
+ } else if (toolbutton->features & QStyleOptionToolButton::HasMenu) {
+ int mbi = proxy()->pixelMetric(PM_MenuButtonIndicator, toolbutton, widget);
+ QRect ir = toolbutton->rect;
+ QStyleOptionToolButton newBtn = *toolbutton;
+ newBtn.rect = QRect(ir.right() + 5 - mbi, ir.height() - mbi + 4, mbi - 6, mbi - 6);
+ proxy()->drawPrimitive(PE_IndicatorArrowDown, &newBtn, p, widget);
+ }
+ }
+ break;
+#ifndef QT_NO_SPINBOX
+ case CC_SpinBox:
+ if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
+ QStyleOptionSpinBox copy = *spinbox;
+ PrimitiveElement pe;
+
+ if (spinbox->frame && (spinbox->subControls & SC_SpinBoxFrame)) {
+ QRect r = proxy()->subControlRect(CC_SpinBox, spinbox, SC_SpinBoxFrame, widget);
+ qDrawShadePanel(p, r, opt->palette, false, proxy()->pixelMetric(PM_SpinBoxFrameWidth));
+
+ int fw = proxy()->pixelMetric(QStyle::PM_DefaultFrameWidth);
+ r = proxy()->subControlRect(CC_SpinBox, spinbox, SC_SpinBoxEditField, widget).adjusted(-fw,-fw,fw,fw);
+ QStyleOptionFrame lineOpt;
+ lineOpt.QStyleOption::operator=(*opt);
+ lineOpt.rect = r;
+ lineOpt.lineWidth = fw;
+ lineOpt.midLineWidth = 0;
+ lineOpt.state |= QStyle::State_Sunken;
+ proxy()->drawPrimitive(QStyle::PE_FrameLineEdit, &lineOpt, p, widget);
+ }
+
+ if (spinbox->subControls & SC_SpinBoxUp) {
+ copy.subControls = SC_SpinBoxUp;
+ QPalette pal2 = spinbox->palette;
+ if (!(spinbox->stepEnabled & QAbstractSpinBox::StepUpEnabled)) {
+ pal2.setCurrentColorGroup(QPalette::Disabled);
+ copy.state &= ~State_Enabled;
+ }
+
+ copy.palette = pal2;
+
+ if (spinbox->activeSubControls == SC_SpinBoxUp && (spinbox->state & State_Sunken)) {
+ copy.state |= State_On;
+ copy.state |= State_Sunken;
+ } else {
+ copy.state |= State_Raised;
+ copy.state &= ~State_Sunken;
+ }
+ pe = (spinbox->buttonSymbols == QAbstractSpinBox::PlusMinus ? PE_IndicatorSpinPlus
+ : PE_IndicatorSpinUp);
+
+ copy.rect = proxy()->subControlRect(CC_SpinBox, spinbox, SC_SpinBoxUp, widget);
+ proxy()->drawPrimitive(pe, &copy, p, widget);
+ }
+
+ if (spinbox->subControls & SC_SpinBoxDown) {
+ copy.subControls = SC_SpinBoxDown;
+ copy.state = spinbox->state;
+ QPalette pal2 = spinbox->palette;
+ if (!(spinbox->stepEnabled & QAbstractSpinBox::StepDownEnabled)) {
+ pal2.setCurrentColorGroup(QPalette::Disabled);
+ copy.state &= ~State_Enabled;
+ }
+ copy.palette = pal2;
+
+ if (spinbox->activeSubControls == SC_SpinBoxDown && (spinbox->state & State_Sunken)) {
+ copy.state |= State_On;
+ copy.state |= State_Sunken;
+ } else {
+ copy.state |= State_Raised;
+ copy.state &= ~State_Sunken;
+ }
+ pe = (spinbox->buttonSymbols == QAbstractSpinBox::PlusMinus ? PE_IndicatorSpinMinus
+ : PE_IndicatorSpinDown);
+
+ copy.rect = proxy()->subControlRect(CC_SpinBox, spinbox, SC_SpinBoxDown, widget);
+ proxy()->drawPrimitive(pe, &copy, p, widget);
+ }
+ }
+ break;
+#endif // QT_NO_SPINBOX
+#ifndef QT_NO_SLIDER
+ case CC_Slider:
+ if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
+ QRect groove = proxy()->subControlRect(CC_Slider, opt, SC_SliderGroove, widget),
+ handle = proxy()->subControlRect(CC_Slider, opt, SC_SliderHandle, widget);
+
+ if ((opt->subControls & SC_SliderGroove) && groove.isValid()) {
+ qDrawShadePanel(p, groove, opt->palette, true, proxy()->pixelMetric(PM_DefaultFrameWidth),
+ &opt->palette.brush((opt->state & State_Enabled) ? QPalette::Mid : QPalette::Window));
+ if ((opt->state & State_HasFocus) && (!focus || !focus->isVisible())) {
+ QStyleOption focusOpt = *opt;
+ focusOpt.rect = subElementRect(SE_SliderFocusRect, opt, widget);
+ proxy()->drawPrimitive(PE_FrameFocusRect, &focusOpt, p, widget);
+ }
+ }
+
+ if ((opt->subControls & SC_SliderHandle) && handle.isValid()) {
+ QStyleOption bevelOpt = *opt;
+ bevelOpt.state = (opt->state | State_Raised) & ~State_Sunken;
+ bevelOpt.rect = handle;
+ p->save();
+ p->setBrushOrigin(bevelOpt.rect.topLeft());
+ proxy()->drawPrimitive(PE_PanelButtonBevel, &bevelOpt, p, widget);
+ p->restore();
+
+ if (slider->orientation == Qt::Horizontal) {
+ int mid = handle.x() + handle.width() / 2;
+ qDrawShadeLine(p, mid, handle.y(), mid, handle.y() + handle.height() - 2,
+ opt->palette, true, 1);
+ } else {
+ int mid = handle.y() + handle.height() / 2;
+ qDrawShadeLine(p, handle.x(), mid, handle.x() + handle.width() - 2, mid, opt->palette,
+ true, 1);
+ }
+ if (!(opt->state & State_Enabled) && proxy()->styleHint(SH_DitherDisabledText))
+ p->fillRect(handle, QBrush(p->background().color(), Qt::Dense5Pattern));
+ }
+
+ if (slider->subControls & SC_SliderTickmarks) {
+ QStyleOptionSlider tmpSlider = *slider;
+ tmpSlider.subControls = SC_SliderTickmarks;
+ int frameWidth = proxy()->pixelMetric(PM_DefaultFrameWidth);
+ tmpSlider.rect.translate(frameWidth - 1, 0);
+ QCommonStyle::drawComplexControl(cc, &tmpSlider, p, widget);
+ }
+ }
+ break;
+#endif // QT_NO_SLIDER
+ case CC_ComboBox:
+ if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
+ if (opt->subControls & SC_ComboBoxArrow) {
+ int awh, ax, ay, sh, sy, dh, ew;
+ int fw = cb->frame ? proxy()->pixelMetric(PM_ComboBoxFrameWidth, opt, widget) : 0;
+
+ if (cb->frame) {
+ QStyleOptionButton btn;
+ btn.QStyleOption::operator=(*cb);
+ btn.state |= QStyle::State_Raised;
+ proxy()->drawPrimitive(PE_PanelButtonCommand, &btn, p, widget);
+ } else {
+ p->fillRect(opt->rect, opt->palette.brush(QPalette::Button));
+ }
+
+ QRect tr = opt->rect;
+ tr.adjust(fw, fw, -fw, -fw);
+ get_combo_parameters(tr, ew, awh, ax, ay, sh, dh, sy);
+
+ QRect ar = QStyle::visualRect(opt->direction, opt->rect, QRect(ax,ay,awh,awh));
+
+ QStyleOption arrowOpt = *opt;
+ arrowOpt.rect = ar;
+ arrowOpt.state |= State_Enabled;
+ proxy()->drawPrimitive(PE_IndicatorArrowDown, &arrowOpt, p, widget);
+
+
+ // draws the shaded line under the arrow
+ p->setPen(opt->palette.light().color());
+ p->drawLine(ar.x(), sy, ar.x()+awh-1, sy);
+ p->drawLine(ar.x(), sy, ar.x(), sy+sh-1);
+ p->setPen(opt->palette.dark().color());
+ p->drawLine(ar.x()+1, sy+sh-1, ar.x()+awh-1, sy+sh-1);
+ p->drawLine(ar.x()+awh-1, sy+1, ar.x()+awh-1, sy+sh-1);
+
+ if ((cb->state & State_HasFocus) && (!focus || !focus->isVisible())) {
+ QStyleOptionFocusRect focus;
+ focus.QStyleOption::operator=(*opt);
+ focus.rect = subElementRect(SE_ComboBoxFocusRect, opt, widget);
+ focus.backgroundColor = opt->palette.button().color();
+ proxy()->drawPrimitive(PE_FrameFocusRect, &focus, p, widget);
+ }
+ }
+
+ if (opt->subControls & SC_ComboBoxEditField) {
+ if (cb->editable) {
+ QRect er = proxy()->subControlRect(CC_ComboBox, opt, SC_ComboBoxEditField, widget);
+ er.adjust(-1, -1, 1, 1);
+ qDrawShadePanel(p, er, opt->palette, true, 1,
+ &opt->palette.brush(QPalette::Base));
+ }
+ }
+ p->setPen(opt->palette.buttonText().color());
+ }
+ break;
+
+#ifndef QT_NO_SCROLLBAR
+ case CC_ScrollBar: {
+ if (opt->subControls & SC_ScrollBarGroove)
+ qDrawShadePanel(p, opt->rect, opt->palette, true,
+ proxy()->pixelMetric(PM_DefaultFrameWidth, opt, widget),
+ &opt->palette.brush((opt->state & State_Enabled) ? QPalette::Mid : QPalette::Window));
+
+ if (const QStyleOptionSlider *scrollbar = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
+ QStyleOptionSlider newScrollbar = *scrollbar;
+ if (scrollbar->minimum == scrollbar->maximum)
+ newScrollbar.state |= State_Enabled; // make sure that the slider is drawn.
+ QCommonStyle::drawComplexControl(cc, &newScrollbar, p, widget);
+ }
+ break; }
+#endif
+
+ case CC_Q3ListView:
+ if (opt->subControls & (SC_Q3ListViewBranch | SC_Q3ListViewExpand)) {
+ int i;
+ if (opt->subControls & SC_Q3ListView)
+ QCommonStyle::drawComplexControl(cc, opt, p, widget);
+ if (const QStyleOptionQ3ListView *lv = qstyleoption_cast<const QStyleOptionQ3ListView *>(opt)) {
+ QStyleOptionQ3ListViewItem item = lv->items.at(0);
+ int y = opt->rect.y();
+ int c;
+ QPolygon dotlines;
+ if ((opt->activeSubControls & SC_All) && (opt->subControls & SC_Q3ListViewExpand)) {
+ c = 2;
+ dotlines.resize(2);
+ dotlines[0] = QPoint(opt->rect.right(), opt->rect.top());
+ dotlines[1] = QPoint(opt->rect.right(), opt->rect.bottom());
+ } else {
+ int linetop = 0, linebot = 0;
+ // each branch needs at most two lines, ie. four end points
+ dotlines.resize(item.childCount * 4);
+ c = 0;
+
+ // skip the stuff above the exposed rectangle
+ for (i = 1; i < lv->items.size(); ++i) {
+ QStyleOptionQ3ListViewItem child = lv->items.at(i);
+ if (child.height + y > 0)
+ break;
+ y += child.totalHeight;
+ }
+
+ int bx = opt->rect.width() / 2;
+
+ // paint stuff in the magical area
+ while (i < lv->items.size() && y < lv->rect.height()) {
+ QStyleOptionQ3ListViewItem child = lv->items.at(i);
+ if (child.features & QStyleOptionQ3ListViewItem::Visible) {
+ int lh;
+ if (!(item.features & QStyleOptionQ3ListViewItem::MultiLine))
+ lh = child.height;
+ else
+ lh = p->fontMetrics().height() + 2 * lv->itemMargin;
+ lh = qMax(lh, QApplication::globalStrut().height());
+ if (lh % 2 > 0)
+ lh++;
+ linebot = y + lh/2;
+ if ((child.features & QStyleOptionQ3ListViewItem::Expandable || child.childCount > 0) &&
+ child.height > 0) {
+ // needs a box
+ p->setPen(opt->palette.text().color());
+ p->drawRect(bx-4, linebot-4, 9, 9);
+ QPolygon a;
+ if ((child.state & State_Open))
+ a.setPoints(3, bx-2, linebot-2,
+ bx, linebot+2,
+ bx+2, linebot-2); //Qt::RightArrow
+ else
+ a.setPoints(3, bx-2, linebot-2,
+ bx+2, linebot,
+ bx-2, linebot+2); //Qt::DownArrow
+ p->setBrush(opt->palette.text());
+ p->drawPolygon(a);
+ p->setBrush(Qt::NoBrush);
+ // dotlinery
+ dotlines[c++] = QPoint(bx, linetop);
+ dotlines[c++] = QPoint(bx, linebot - 5);
+ dotlines[c++] = QPoint(bx + 5, linebot);
+ dotlines[c++] = QPoint(opt->rect.width(), linebot);
+ linetop = linebot + 5;
+ } else {
+ // just dotlinery
+ dotlines[c++] = QPoint(bx+1, linebot);
+ dotlines[c++] = QPoint(opt->rect.width(), linebot);
+ }
+ y += child.totalHeight;
+ }
+ ++i;
+ }
+
+ // Expand line height to edge of rectangle if there's any
+ // visible child below
+ while (i < lv->items.size() && lv->items.at(i).height <= 0)
+ ++i;
+ if (i < lv->items.size())
+ linebot = opt->rect.height();
+
+ if (linetop < linebot) {
+ dotlines[c++] = QPoint(bx, linetop);
+ dotlines[c++] = QPoint(bx, linebot);
+ }
+ }
+
+ int line; // index into dotlines
+ p->setPen(opt->palette.text().color());
+ if (opt->subControls & SC_Q3ListViewBranch) for(line = 0; line < c; line += 2) {
+ p->drawLine(dotlines[line].x(), dotlines[line].y(),
+ dotlines[line+1].x(), dotlines[line+1].y());
+ }
+ }
+ break; }
+
+ default:
+ QCommonStyle::drawComplexControl(cc, opt, p, widget);
+ break;
+ }
+}
+
+
+/*! \reimp */
+int QMotifStyle::pixelMetric(PixelMetric pm, const QStyleOption *opt,
+ const QWidget *widget) const
+{
+ int ret = 0;
+
+ switch(pm) {
+ case PM_ButtonDefaultIndicator:
+ ret = 5;
+ break;
+
+ case PM_CheckBoxLabelSpacing:
+ case PM_RadioButtonLabelSpacing:
+ ret = 10;
+ break;
+
+ case PM_ToolBarFrameWidth:
+ ret = proxy()->pixelMetric(PM_DefaultFrameWidth);
+ break;
+
+ case PM_ToolBarItemMargin:
+ ret = 1;
+ break;
+
+ case PM_ButtonShiftHorizontal:
+ case PM_ButtonShiftVertical:
+ ret = 0;
+ break;
+
+ case PM_SplitterWidth:
+ ret = qMax(10, QApplication::globalStrut().width());
+ break;
+
+ case PM_SliderLength:
+ ret = 30;
+ break;
+
+ case PM_SliderThickness:
+ ret = 16 + 4 * proxy()->pixelMetric(PM_DefaultFrameWidth);
+ break;
+#ifndef QT_NO_SLIDER
+ case PM_SliderControlThickness:
+ if (const QStyleOptionSlider *sl = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
+ int space = (sl->orientation == Qt::Horizontal) ? sl->rect.height() : sl->rect.width();
+ int ticks = sl->tickPosition;
+ int n = 0;
+ if (ticks & QSlider::TicksAbove)
+ n++;
+ if (ticks & QSlider::TicksBelow)
+ n++;
+ if (!n) {
+ ret = space;
+ break;
+ }
+
+ int thick = 6; // Magic constant to get 5 + 16 + 5
+
+ space -= thick;
+ //### the two sides may be unequal in size
+ if (space > 0)
+ thick += (space * 2) / (n + 2);
+ ret = thick;
+ }
+ break;
+
+ case PM_SliderSpaceAvailable:
+ if (const QStyleOptionSlider *sl = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
+ if (sl->orientation == Qt::Horizontal)
+ ret = sl->rect.width() - proxy()->pixelMetric(PM_SliderLength, opt, widget) - 2 * proxy()->pixelMetric(PM_DefaultFrameWidth, opt, widget);
+ else
+ ret = sl->rect.height() - proxy()->pixelMetric(PM_SliderLength, opt, widget) - 2 * proxy()->pixelMetric(PM_DefaultFrameWidth, opt, widget);
+ }
+ break;
+#endif // QT_NO_SLIDER
+ case PM_DockWidgetFrameWidth:
+ ret = 2;
+ break;
+
+ case PM_DockWidgetHandleExtent:
+ ret = 9;
+ break;
+
+ case PM_ProgressBarChunkWidth:
+ ret = 1;
+ break;
+
+ case PM_ExclusiveIndicatorWidth:
+ case PM_ExclusiveIndicatorHeight:
+ ret = 13;
+ break;
+
+ case PM_MenuBarHMargin:
+ ret = 2; // really ugly, but Motif
+ break;
+
+ case PM_MenuButtonIndicator:
+ if (!opt)
+ ret = 12;
+ else
+ ret = qMax(12, (opt->rect.height() - 4) / 3);
+ break;
+ default:
+ ret = QCommonStyle::pixelMetric(pm, opt, widget);
+ break;
+ }
+ return ret;
+}
+
+
+/*!
+ \reimp
+*/
+QRect
+QMotifStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex *opt,
+ SubControl sc, const QWidget *widget) const
+{
+ switch (cc) {
+#ifndef QT_NO_SPINBOX
+ case CC_SpinBox:
+ if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
+ int fw = spinbox->frame ? proxy()->pixelMetric(PM_SpinBoxFrameWidth, spinbox, widget) : 0;
+ QSize bs;
+ bs.setHeight(opt->rect.height()/2 - fw);
+ bs.setWidth(qMin(bs.height() * 8 / 5, opt->rect.width() / 4)); // 1.6 -approximate golden mean
+ bs = bs.expandedTo(QApplication::globalStrut());
+ int y = fw + spinbox->rect.y();
+ int x, lx, rx;
+ x = spinbox->rect.x() + opt->rect.width() - fw - bs.width();
+ lx = fw;
+ rx = x - fw * 2;
+ const int margin = spinbox->frame ? 4 : 0;
+ switch (sc) {
+ case SC_SpinBoxUp:
+ if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons)
+ return QRect();
+ return visualRect(spinbox->direction, spinbox->rect,
+ QRect(x, y, bs.width(), bs.height() - 1));
+ case SC_SpinBoxDown:
+ if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons)
+ return QRect();
+ return visualRect(spinbox->direction, spinbox->rect,
+ QRect(x, y + bs.height() + 1, bs.width(), bs.height() - 1));
+ case SC_SpinBoxEditField:
+ if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons)
+ return visualRect(spinbox->direction, spinbox->rect,
+ QRect(lx + margin, y + margin,
+ spinbox->rect.width() - 2*fw - 2*margin,
+ spinbox->rect.height() - 2*fw - 2*margin));
+
+ return visualRect(spinbox->direction, spinbox->rect,
+ QRect(lx + margin, y + margin, rx - margin,
+ spinbox->rect.height() - 2*fw - 2 * margin));
+ case SC_SpinBoxFrame:
+ return visualRect(spinbox->direction, spinbox->rect, spinbox->rect);
+ default:
+ break;
+ }
+ break; }
+#endif // QT_NO_SPINBOX
+#ifndef QT_NO_SLIDER
+ case CC_Slider:
+ if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
+ if (sc == SC_SliderHandle) {
+ int tickOffset = proxy()->pixelMetric(PM_SliderTickmarkOffset, opt, widget);
+ int thickness = proxy()->pixelMetric(PM_SliderControlThickness, opt, widget);
+ bool horizontal = slider->orientation == Qt::Horizontal;
+ int len = proxy()->pixelMetric(PM_SliderLength, opt, widget);
+ int motifBorder = proxy()->pixelMetric(PM_DefaultFrameWidth);
+ int sliderPos = sliderPositionFromValue(slider->minimum, slider->maximum, slider->sliderPosition,
+ horizontal ? slider->rect.width() - len - 2 * motifBorder
+ : slider->rect.height() - len - 2 * motifBorder,
+ slider->upsideDown);
+ if (horizontal)
+ return visualRect(slider->direction, slider->rect,
+ QRect(sliderPos + motifBorder, tickOffset + motifBorder, len,
+ thickness - 2 * motifBorder));
+ return visualRect(slider->direction, slider->rect,
+ QRect(tickOffset + motifBorder, sliderPos + motifBorder,
+ thickness - 2 * motifBorder, len));
+ }
+ }
+ break;
+#endif // QT_NO_SLIDER
+#ifndef QT_NO_SCROLLBAR
+ case CC_ScrollBar:
+ if (const QStyleOptionSlider *scrollbar = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
+ int dfw = proxy()->pixelMetric(PM_DefaultFrameWidth);
+ QRect rect = visualRect(scrollbar->direction, scrollbar->rect,
+ QCommonStyle::subControlRect(cc, scrollbar, sc, widget));
+ if (sc == SC_ScrollBarSlider) {
+ if (scrollbar->orientation == Qt::Horizontal)
+ rect.adjust(-dfw, dfw, dfw, -dfw);
+ else
+ rect.adjust(dfw, -dfw, -dfw, dfw);
+ } else if (sc != SC_ScrollBarGroove) {
+ if (scrollbar->orientation == Qt::Horizontal)
+ rect.adjust(0, dfw, 0, -dfw);
+ else
+ rect.adjust(dfw, 0, -dfw, 0);
+ }
+ return visualRect(scrollbar->direction, scrollbar->rect, rect);
+ }
+ break;
+#endif // QT_NO_SCROLLBAR
+#ifndef QT_NO_COMBOBOX
+ case CC_ComboBox:
+ if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
+ switch (sc) {
+ case SC_ComboBoxArrow: {
+ int ew, awh, sh, dh, ax, ay, sy;
+ int fw = cb->frame ? proxy()->pixelMetric(PM_ComboBoxFrameWidth, opt, widget) : 0;
+ QRect cr = opt->rect;
+ cr.adjust(fw, fw, -fw, -fw);
+ get_combo_parameters(cr, ew, awh, ax, ay, sh, dh, sy);
+ return visualRect(cb->direction, cb->rect, QRect(QPoint(ax, ay), cr.bottomRight()));
+ }
+
+ case SC_ComboBoxEditField: {
+ int fw = cb->frame ? proxy()->pixelMetric(PM_ComboBoxFrameWidth, opt, widget) : 0;
+ QRect rect = opt->rect;
+ rect.adjust(fw, fw, -fw, -fw);
+ int ew = get_combo_extra_width(rect.height(), rect.width());
+ rect.adjust(1, 1, -1-ew, -1);
+ return visualRect(cb->direction, cb->rect, rect);
+ }
+
+ default:
+ break;
+ }
+ }
+ break;
+#endif // QT_NO_SCROLLBAR
+ default:
+ break;
+ }
+ return QCommonStyle::subControlRect(cc, opt, sc, widget);
+}
+
+/*!
+ \reimp
+*/
+QSize
+QMotifStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt,
+ const QSize &contentsSize, const QWidget *widget) const
+{
+ QSize sz(contentsSize);
+
+ switch(ct) {
+ case CT_RadioButton:
+ case CT_CheckBox:
+ sz = QCommonStyle::sizeFromContents(ct, opt, contentsSize, widget);
+ sz.rwidth() += motifItemFrame;
+ break;
+
+ case CT_PushButton:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
+ sz = QCommonStyle::sizeFromContents(ct, opt, contentsSize, widget);
+ if (!btn->text.isEmpty() && (btn->features & (QStyleOptionButton::AutoDefaultButton|QStyleOptionButton::DefaultButton)))
+ sz.setWidth(qMax(75, sz.width()));
+ sz += QSize(0, 1); // magical extra pixel
+ }
+ break;
+
+ case CT_MenuBarItem: {
+ if(!sz.isEmpty())
+ sz += QSize(5*motifItemHMargin+1, 2*motifItemVMargin + motifItemFrame);
+ break; }
+
+ case CT_MenuItem:
+ if (const QStyleOptionMenuItem *mi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
+ sz = QCommonStyle::sizeFromContents(ct, opt, sz, widget);
+ int w = sz.width(), h = sz.height();
+
+ if (mi->menuItemType == QStyleOptionMenuItem::Separator) {
+ w = 10;
+ h = (mi->text.isEmpty()) ? motifSepHeight : mi->fontMetrics.height();
+ }
+
+ // a little bit of border can never harm
+ w += 2*motifItemHMargin + 2*motifItemFrame;
+
+ if (!mi->text.isNull() && mi->text.indexOf(QLatin1Char('\t')) >= 0)
+ // string contains tab
+ w += motifTabSpacing;
+ else if (mi->menuItemType == QStyleOptionMenuItem::SubMenu)
+ // submenu indicator needs some room if we don't have a tab column
+ w += motifArrowHMargin + 4*motifItemFrame;
+
+ int checkColumn = mi->maxIconWidth;
+ if (mi->menuHasCheckableItems)
+ checkColumn = qMax(checkColumn, motifCheckMarkSpace);
+ if (checkColumn > 0)
+ w += checkColumn + motifCheckMarkHMargin;
+
+ sz = QSize(w, h);
+ }
+ break;
+
+
+ default:
+ sz = QCommonStyle::sizeFromContents(ct, opt, contentsSize, widget);
+ break;
+ }
+
+ return sz;
+}
+
+/*!
+ \reimp
+*/
+QRect
+QMotifStyle::subElementRect(SubElement sr, const QStyleOption *opt, const QWidget *widget) const
+{
+ QRect rect;
+
+ switch (sr) {
+ case SE_SliderFocusRect:
+ rect = QCommonStyle::subElementRect(sr, opt, widget);
+ rect.adjust(2, 2, -2, -2);
+ break;
+
+ case SE_CheckBoxIndicator:
+ case SE_RadioButtonIndicator:
+ {
+ rect = visualRect(opt->direction, opt->rect,
+ QCommonStyle::subElementRect(sr, opt, widget));
+ rect.adjust(motifItemFrame,0, motifItemFrame,0);
+ rect = visualRect(opt->direction, opt->rect, rect);
+ }
+ break;
+
+ case SE_ComboBoxFocusRect:
+ {
+ int awh, ax, ay, sh, sy, dh, ew;
+ int fw = proxy()->pixelMetric(PM_DefaultFrameWidth, opt, widget);
+ QRect tr = opt->rect;
+
+ tr.adjust(fw, fw, -fw, -fw);
+ get_combo_parameters(tr, ew, awh, ax, ay, sh, dh, sy);
+ rect.setRect(ax-2, ay-2, awh+4, awh+sh+dh+4);
+ break;
+ }
+
+ case SE_Q3DockWindowHandleRect:
+ if (const QStyleOptionQ3DockWindow *dw = qstyleoption_cast<const QStyleOptionQ3DockWindow *>(opt)) {
+ if (!dw->docked || !dw->closeEnabled)
+ rect.setRect(0, 0, opt->rect.width(), opt->rect.height());
+ else {
+ if (dw->state == State_Horizontal)
+ rect.setRect(2, 15, opt->rect.width()-2, opt->rect.height() - 15);
+ else
+ rect.setRect(0, 2, opt->rect.width() - 15, opt->rect.height() - 2);
+ }
+ rect = visualRect(dw->direction, dw->rect, rect);
+ }
+ break;
+
+ case SE_ProgressBarLabel:
+ case SE_ProgressBarGroove:
+ case SE_ProgressBarContents:
+ if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) {
+ int textw = 0;
+ if (pb->textVisible)
+ textw = pb->fontMetrics.width(QLatin1String("100%")) + 6;
+
+ if (pb->textAlignment == Qt::AlignLeft || pb->textAlignment == Qt::AlignCenter) {
+ rect = opt->rect;
+ } else {
+ if(sr == SE_ProgressBarLabel)
+ rect.setCoords(opt->rect.right() - textw, opt->rect.top(),
+ opt->rect.right(), opt->rect.bottom());
+ else
+ rect.setCoords(opt->rect.left(), opt->rect.top(),
+ opt->rect.right() - textw, opt->rect.bottom());
+ }
+ if (sr == SE_ProgressBarContents)
+ rect.adjust(2, 2, -2, -2);
+ rect = visualRect(pb->direction, pb->rect, rect);
+ }
+ break;
+ case SE_CheckBoxClickRect:
+ case SE_RadioButtonClickRect:
+ rect = visualRect(opt->direction, opt->rect, opt->rect);
+ break;
+
+ default:
+ rect = QCommonStyle::subElementRect(sr, opt, widget);
+ }
+ return rect;
+}
+
+#ifndef QT_NO_IMAGEFORMAT_XPM
+static const char * const qt_menu_xpm[] = {
+"16 16 11 1",
+" c #000000",
+", c #336600",
+". c #99CC00",
+"X c #666600",
+"o c #999933",
+"+ c #333300",
+"@ c #669900",
+"# c #999900",
+"$ c #336633",
+"% c #666633",
+"& c #99CC33",
+"................",
+"................",
+".....#,++X#.....",
+"....X X....",
+"...X Xo#% X&..",
+"..# o..&@o o..",
+".., X..#+ @X X..",
+"..+ o.o+ +o# +..",
+"..+ #o+ +## +..",
+".., %@ ++ +, X..",
+"..# o@oo+ #..",
+"...X X##$ o..",
+"....X X..",
+"....&oX++X#oX...",
+"................",
+"................"};
+
+
+static const char * const qt_close_xpm[] = {
+ "12 12 2 1",
+ " s None c None",
+ ". c black",
+ " ",
+ " ",
+ " . . ",
+ " ... ... ",
+ " ...... ",
+ " .... ",
+ " .... ",
+ " ...... ",
+ " ... ... ",
+ " . . ",
+ " ",
+ " "};
+
+static const char * const qt_maximize_xpm[] = {
+ "12 12 2 1",
+ " s None c None",
+ ". c black",
+ " ",
+ " ",
+ " ",
+ " . ",
+ " ... ",
+ " ..... ",
+ " ....... ",
+ " ......... ",
+ " ",
+ " ",
+ " ",
+ " "};
+
+static const char * const qt_minimize_xpm[] = {
+ "12 12 2 1",
+ " s None c None",
+ ". c black",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ......... ",
+ " ....... ",
+ " ..... ",
+ " ... ",
+ " . ",
+ " ",
+ " ",
+ " "};
+
+#if 0 // ### not used???
+static const char * const qt_normalize_xpm[] = {
+ "12 12 2 1",
+ " s None c None",
+ ". c black",
+ " ",
+ " ",
+ " . ",
+ " .. ",
+ " ... ",
+ " .... ",
+ " ..... ",
+ " ...... ",
+ " ....... ",
+ " ",
+ " ",
+ " "};
+#endif
+
+static const char * const qt_normalizeup_xpm[] = {
+ "12 12 2 1",
+ " s None c None",
+ ". c black",
+ " ",
+ " ",
+ " ",
+ " ....... ",
+ " ...... ",
+ " ..... ",
+ " .... ",
+ " ... ",
+ " .. ",
+ " . ",
+ " ",
+ " "};
+
+static const char * const qt_shade_xpm[] = {
+ "12 12 2 1", "# c #000000",
+ ". c None",
+ "............",
+ "............",
+ ".#########..",
+ ".#########..",
+ "............",
+ "............",
+ "............",
+ "............",
+ "............",
+ "............",
+ "............",
+ "............"};
+
+
+static const char * const qt_unshade_xpm[] = {
+ "12 12 2 1",
+ "# c #000000",
+ ". c None",
+ "............",
+ "............",
+ ".#########..",
+ ".#########..",
+ ".#.......#..",
+ ".#.......#..",
+ ".#.......#..",
+ ".#.......#..",
+ ".#.......#..",
+ ".#########..",
+ "............",
+ "............"};
+
+
+static const char * dock_window_close_xpm[] = {
+ "8 8 2 1",
+ "# c #000000",
+ ". c None",
+ "##....##",
+ ".##..##.",
+ "..####..",
+ "...##...",
+ "..####..",
+ ".##..##.",
+ "##....##",
+ "........"};
+
+// Message box icons, from page 210 of the Windows style guide.
+
+// Hand-drawn to resemble Microsoft's icons, but in the Mac/Netscape palette.
+// Thanks to TrueColor displays, it is slightly more efficient to have
+// them duplicated.
+/* XPM */
+static const char * const information_xpm[]={
+ "32 32 5 1",
+ ". c None",
+ "c c #000000",
+ "* c #999999",
+ "a c #ffffff",
+ "b c #0000ff",
+ "...........********.............",
+ "........***aaaaaaaa***..........",
+ "......**aaaaaaaaaaaaaa**........",
+ ".....*aaaaaaaaaaaaaaaaaa*.......",
+ "....*aaaaaaaabbbbaaaaaaaac......",
+ "...*aaaaaaaabbbbbbaaaaaaaac.....",
+ "..*aaaaaaaaabbbbbbaaaaaaaaac....",
+ ".*aaaaaaaaaaabbbbaaaaaaaaaaac...",
+ ".*aaaaaaaaaaaaaaaaaaaaaaaaaac*..",
+ "*aaaaaaaaaaaaaaaaaaaaaaaaaaaac*.",
+ "*aaaaaaaaaabbbbbbbaaaaaaaaaaac*.",
+ "*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
+ "*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
+ "*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
+ "*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
+ "*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
+ ".*aaaaaaaaaaabbbbbaaaaaaaaaac***",
+ ".*aaaaaaaaaaabbbbbaaaaaaaaaac***",
+ "..*aaaaaaaaaabbbbbaaaaaaaaac***.",
+ "...caaaaaaabbbbbbbbbaaaaaac****.",
+ "....caaaaaaaaaaaaaaaaaaaac****..",
+ ".....caaaaaaaaaaaaaaaaaac****...",
+ "......ccaaaaaaaaaaaaaacc****....",
+ ".......*cccaaaaaaaaccc*****.....",
+ "........***cccaaaac*******......",
+ "..........****caaac*****........",
+ ".............*caaac**...........",
+ "...............caac**...........",
+ "................cac**...........",
+ ".................cc**...........",
+ "..................***...........",
+ "...................**..........."};
+/* XPM */
+static const char* const warning_xpm[]={
+ "32 32 4 1",
+ ". c None",
+ "a c #ffff00",
+ "* c #000000",
+ "b c #999999",
+ ".............***................",
+ "............*aaa*...............",
+ "...........*aaaaa*b.............",
+ "...........*aaaaa*bb............",
+ "..........*aaaaaaa*bb...........",
+ "..........*aaaaaaa*bb...........",
+ ".........*aaaaaaaaa*bb..........",
+ ".........*aaaaaaaaa*bb..........",
+ "........*aaaaaaaaaaa*bb.........",
+ "........*aaaa***aaaa*bb.........",
+ ".......*aaaa*****aaaa*bb........",
+ ".......*aaaa*****aaaa*bb........",
+ "......*aaaaa*****aaaaa*bb.......",
+ "......*aaaaa*****aaaaa*bb.......",
+ ".....*aaaaaa*****aaaaaa*bb......",
+ ".....*aaaaaa*****aaaaaa*bb......",
+ "....*aaaaaaaa***aaaaaaaa*bb.....",
+ "....*aaaaaaaa***aaaaaaaa*bb.....",
+ "...*aaaaaaaaa***aaaaaaaaa*bb....",
+ "...*aaaaaaaaaa*aaaaaaaaaa*bb....",
+ "..*aaaaaaaaaaa*aaaaaaaaaaa*bb...",
+ "..*aaaaaaaaaaaaaaaaaaaaaaa*bb...",
+ ".*aaaaaaaaaaaa**aaaaaaaaaaa*bb..",
+ ".*aaaaaaaaaaa****aaaaaaaaaa*bb..",
+ "*aaaaaaaaaaaa****aaaaaaaaaaa*bb.",
+ "*aaaaaaaaaaaaa**aaaaaaaaaaaa*bb.",
+ "*aaaaaaaaaaaaaaaaaaaaaaaaaaa*bbb",
+ "*aaaaaaaaaaaaaaaaaaaaaaaaaaa*bbb",
+ ".*aaaaaaaaaaaaaaaaaaaaaaaaa*bbbb",
+ "..*************************bbbbb",
+ "....bbbbbbbbbbbbbbbbbbbbbbbbbbb.",
+ ".....bbbbbbbbbbbbbbbbbbbbbbbbb.."};
+/* XPM */
+static const char* const critical_xpm[]={
+ "32 32 4 1",
+ ". c None",
+ "a c #999999",
+ "* c #ff0000",
+ "b c #ffffff",
+ "...........********.............",
+ ".........************...........",
+ ".......****************.........",
+ "......******************........",
+ ".....********************a......",
+ "....**********************a.....",
+ "...************************a....",
+ "..*******b**********b*******a...",
+ "..******bbb********bbb******a...",
+ ".******bbbbb******bbbbb******a..",
+ ".*******bbbbb****bbbbb*******a..",
+ "*********bbbbb**bbbbb*********a.",
+ "**********bbbbbbbbbb**********a.",
+ "***********bbbbbbbb***********aa",
+ "************bbbbbb************aa",
+ "************bbbbbb************aa",
+ "***********bbbbbbbb***********aa",
+ "**********bbbbbbbbbb**********aa",
+ "*********bbbbb**bbbbb*********aa",
+ ".*******bbbbb****bbbbb*******aa.",
+ ".******bbbbb******bbbbb******aa.",
+ "..******bbb********bbb******aaa.",
+ "..*******b**********b*******aa..",
+ "...************************aaa..",
+ "....**********************aaa...",
+ "....a********************aaa....",
+ ".....a******************aaa.....",
+ "......a****************aaa......",
+ ".......aa************aaaa.......",
+ ".........aa********aaaaa........",
+ "...........aaaaaaaaaaa..........",
+ ".............aaaaaaa............"};
+/* XPM */
+static const char *const question_xpm[] = {
+ "32 32 5 1",
+ ". c None",
+ "c c #000000",
+ "* c #999999",
+ "a c #ffffff",
+ "b c #0000ff",
+ "...........********.............",
+ "........***aaaaaaaa***..........",
+ "......**aaaaaaaaaaaaaa**........",
+ ".....*aaaaaaaaaaaaaaaaaa*.......",
+ "....*aaaaaaaaaaaaaaaaaaaac......",
+ "...*aaaaaaaabbbbbbaaaaaaaac.....",
+ "..*aaaaaaaabaaabbbbaaaaaaaac....",
+ ".*aaaaaaaabbaaaabbbbaaaaaaaac...",
+ ".*aaaaaaaabbbbaabbbbaaaaaaaac*..",
+ "*aaaaaaaaabbbbaabbbbaaaaaaaaac*.",
+ "*aaaaaaaaaabbaabbbbaaaaaaaaaac*.",
+ "*aaaaaaaaaaaaabbbbaaaaaaaaaaac**",
+ "*aaaaaaaaaaaaabbbaaaaaaaaaaaac**",
+ "*aaaaaaaaaaaaabbaaaaaaaaaaaaac**",
+ "*aaaaaaaaaaaaabbaaaaaaaaaaaaac**",
+ "*aaaaaaaaaaaaaaaaaaaaaaaaaaaac**",
+ ".*aaaaaaaaaaaabbaaaaaaaaaaaac***",
+ ".*aaaaaaaaaaabbbbaaaaaaaaaaac***",
+ "..*aaaaaaaaaabbbbaaaaaaaaaac***.",
+ "...caaaaaaaaaabbaaaaaaaaaac****.",
+ "....caaaaaaaaaaaaaaaaaaaac****..",
+ ".....caaaaaaaaaaaaaaaaaac****...",
+ "......ccaaaaaaaaaaaaaacc****....",
+ ".......*cccaaaaaaaaccc*****.....",
+ "........***cccaaaac*******......",
+ "..........****caaac*****........",
+ ".............*caaac**...........",
+ "...............caac**...........",
+ "................cac**...........",
+ ".................cc**...........",
+ "..................***...........",
+ "...................**...........",
+};
+#endif
+
+/*!
+ \reimp
+*/
+QPixmap
+QMotifStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt,
+ const QWidget *widget) const
+{
+#ifndef QT_NO_IMAGEFORMAT_XPM
+ switch (standardPixmap) {
+ case SP_TitleBarMenuButton:
+ return QPixmap(qt_menu_xpm);
+ case SP_TitleBarShadeButton:
+ return QPixmap(qt_shade_xpm);
+ case SP_TitleBarUnshadeButton:
+ return QPixmap(qt_unshade_xpm);
+ case SP_TitleBarNormalButton:
+ return QPixmap(qt_normalizeup_xpm);
+ case SP_TitleBarMinButton:
+ return QPixmap(qt_minimize_xpm);
+ case SP_TitleBarMaxButton:
+ return QPixmap(qt_maximize_xpm);
+ case SP_TitleBarCloseButton:
+ return QPixmap(qt_close_xpm);
+ case SP_DockWidgetCloseButton:
+ return QPixmap(dock_window_close_xpm);
+
+ case SP_MessageBoxInformation:
+ case SP_MessageBoxWarning:
+ case SP_MessageBoxCritical:
+ case SP_MessageBoxQuestion:
+ {
+ const char * const * xpm_data;
+ switch (standardPixmap) {
+ case SP_MessageBoxInformation:
+ xpm_data = information_xpm;
+ break;
+ case SP_MessageBoxWarning:
+ xpm_data = warning_xpm;
+ break;
+ case SP_MessageBoxCritical:
+ xpm_data = critical_xpm;
+ break;
+ case SP_MessageBoxQuestion:
+ xpm_data = question_xpm;
+ break;
+ default:
+ xpm_data = 0;
+ break;
+ }
+ QPixmap pm;
+ if (xpm_data) {
+ QImage image((const char **) xpm_data);
+ // All that color looks ugly in Motif
+ const QPalette &pal = QApplication::palette();
+ switch (standardPixmap) {
+ case SP_MessageBoxInformation:
+ case SP_MessageBoxQuestion:
+ image.setColor(2, 0xff000000 |
+ pal.color(QPalette::Active, QPalette::Dark).rgb());
+ image.setColor(3, 0xff000000 |
+ pal.color(QPalette::Active, QPalette::Base).rgb());
+ image.setColor(4, 0xff000000 |
+ pal.color(QPalette::Active, QPalette::Text).rgb());
+ break;
+ case SP_MessageBoxWarning:
+ image.setColor(1, 0xff000000 |
+ pal.color(QPalette::Active, QPalette::Base).rgb());
+ image.setColor(2, 0xff000000 |
+ pal.color(QPalette::Active, QPalette::Text).rgb());
+ image.setColor(3, 0xff000000 |
+ pal.color(QPalette::Active, QPalette::Dark).rgb());
+ break;
+ case SP_MessageBoxCritical:
+ image.setColor(1, 0xff000000 |
+ pal.color(QPalette::Active, QPalette::Dark).rgb());
+ image.setColor(2, 0xff000000 |
+ pal.color(QPalette::Active, QPalette::Text).rgb());
+ image.setColor(3, 0xff000000 |
+ pal.color(QPalette::Active, QPalette::Base).rgb());
+ break;
+ default:
+ break;
+ }
+ pm = QPixmap::fromImage(image);
+ }
+ return pm;
+ }
+
+ default:
+ break;
+ }
+#endif
+
+ return QCommonStyle::standardPixmap(standardPixmap, opt, widget);
+}
+
+/*! \reimp */
+bool QMotifStyle::event(QEvent *e)
+{
+ if(e->type() == QEvent::FocusIn) {
+ if (QWidget *focusWidget = QApplication::focusWidget()) {
+#ifndef QT_NO_GRAPHICSVIEW
+ if (QGraphicsView *graphicsView = qobject_cast<QGraphicsView *>(focusWidget)) {
+ QGraphicsItem *focusItem = graphicsView->scene() ? graphicsView->scene()->focusItem() : 0;
+ if (focusItem && focusItem->type() == QGraphicsProxyWidget::Type) {
+ QGraphicsProxyWidget *proxy = static_cast<QGraphicsProxyWidget *>(focusItem);
+ if (proxy->widget())
+ focusWidget = proxy->widget()->focusWidget();
+ }
+ }
+#endif
+ if(!focus)
+ focus = new QFocusFrame(focusWidget);
+ focus->setWidget(focusWidget);
+ } else {
+ if(focus)
+ focus->setWidget(0);
+ }
+ } else if(e->type() == QEvent::FocusOut) {
+ if(focus)
+ focus->setWidget(0);
+ }
+ return QCommonStyle::event(e);
+}
+
+
+/*! \reimp */
+int
+QMotifStyle::styleHint(StyleHint hint, const QStyleOption *opt, const QWidget *widget,
+ QStyleHintReturn *returnData) const
+{
+ int ret;
+
+ switch (hint) {
+#ifdef QT3_SUPPORT
+ case SH_GUIStyle:
+ ret = Qt::MotifStyle;
+ break;
+#endif
+ case SH_DrawMenuBarSeparator:
+ ret = true;
+ break;
+
+ case SH_ScrollBar_MiddleClickAbsolutePosition:
+ case SH_Slider_SloppyKeyEvents:
+ case SH_ProgressDialog_CenterCancelButton:
+ case SH_Menu_SpaceActivatesItem:
+ case SH_ScrollView_FrameOnlyAroundContents:
+ case SH_DitherDisabledText:
+ ret = 1;
+ break;
+
+ case SH_Menu_SubMenuPopupDelay:
+ ret = 96;
+ break;
+
+ case SH_ProgressDialog_TextLabelAlignment:
+ ret = Qt::AlignLeft | Qt::AlignVCenter;
+ break;
+
+ case SH_ItemView_ChangeHighlightOnFocus:
+ ret = 0;
+ break;
+
+ case SH_MessageBox_UseBorderForButtonSpacing:
+ ret = 1;
+ break;
+
+ case SH_Dial_BackgroundRole:
+ ret = QPalette::Mid;
+ break;
+
+ case SH_DialogButtonLayout:
+ ret = QDialogButtonBox::KdeLayout;
+ break;
+ case SH_LineEdit_PasswordCharacter:
+ ret = '*';
+ break;
+ case SH_DialogButtonBox_ButtonsHaveIcons:
+ ret = 0;
+ break;
+ default:
+ ret = QCommonStyle::styleHint(hint, opt, widget, returnData);
+ break;
+ }
+
+ return ret;
+}
+
+/*! \reimp */
+QPalette QMotifStyle::standardPalette() const
+{
+#ifdef Q_WS_X11
+ QColor background(0xcf, 0xcf, 0xcf);
+ if (QX11Info::appDepth() <= 8)
+ background = QColor(0xc0, 0xc0, 0xc0);
+#else
+ QColor background = QColor(0xcf, 0xcf, 0xcf);
+#endif
+
+ QColor light = background.lighter();
+ QColor mid = QColor(0xa6, 0xa6, 0xa6);
+ QColor dark = QColor(0x79, 0x7d, 0x79);
+ QPalette palette(Qt::black, background, light, dark, mid, Qt::black, Qt::white);
+ palette.setBrush(QPalette::Disabled, QPalette::WindowText, dark);
+ palette.setBrush(QPalette::Disabled, QPalette::Text, dark);
+ palette.setBrush(QPalette::Disabled, QPalette::ButtonText, dark);
+ palette.setBrush(QPalette::Disabled, QPalette::Base, background);
+ return palette;
+}
+
+QT_END_NAMESPACE
+
+#endif // !defined(QT_NO_STYLE_MOTIF) || defined(QT_PLUGIN)
diff --git a/src/widgets/styles/qmotifstyle.h b/src/widgets/styles/qmotifstyle.h
new file mode 100644
index 0000000000..35b3448289
--- /dev/null
+++ b/src/widgets/styles/qmotifstyle.h
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMOTIFSTYLE_H
+#define QMOTIFSTYLE_H
+
+#include <QtWidgets/qcommonstyle.h>
+#include <QtCore/qpointer.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#if !defined(QT_NO_STYLE_MOTIF)
+
+class QPalette;
+class QFocusFrame;
+
+class QMotifStylePrivate;
+class Q_WIDGETS_EXPORT QMotifStyle : public QCommonStyle
+{
+ Q_OBJECT
+public:
+ explicit QMotifStyle(bool useHighlightCols=false);
+ virtual ~QMotifStyle();
+
+ void setUseHighlightColors(bool);
+ bool useHighlightColors() const;
+
+ void polish(QPalette&);
+ void polish(QWidget*);
+ void unpolish(QWidget*);
+ void polish(QApplication*);
+ void unpolish(QApplication*);
+
+ void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p,
+ const QWidget *w = 0) const;
+
+ void drawControl(ControlElement element, const QStyleOption *opt, QPainter *p,
+ const QWidget *w = 0) const;
+
+ void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p,
+ const QWidget *w = 0) const;
+
+ QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt,
+ SubControl sc, const QWidget *widget = 0) const;
+
+ int pixelMetric(PixelMetric metric, const QStyleOption *option = 0,
+ const QWidget *widget = 0) const;
+
+ QSize sizeFromContents(ContentsType ct, const QStyleOption *opt,
+ const QSize &contentsSize, const QWidget *widget = 0) const;
+
+ QRect subElementRect(SubElement r, const QStyleOption *opt, const QWidget *widget = 0) const;
+
+ QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt,
+ const QWidget *widget = 0) const;
+
+ int styleHint(StyleHint hint, const QStyleOption *opt = 0, const QWidget *widget = 0,
+ QStyleHintReturn *returnData = 0) const;
+
+ bool event(QEvent *);
+ QPalette standardPalette() const;
+
+protected Q_SLOTS:
+ QIcon standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *opt = 0,
+ const QWidget *widget = 0) const;
+
+protected:
+ QPointer<QFocusFrame> focus;
+ QMotifStyle(QMotifStylePrivate &dd, bool useHighlightCols = false);
+ void timerEvent(QTimerEvent *event);
+ bool eventFilter(QObject *o, QEvent *e);
+
+private:
+ Q_DECLARE_PRIVATE(QMotifStyle)
+ Q_DISABLE_COPY(QMotifStyle)
+
+ bool highlightCols;
+};
+
+#endif // QT_NO_STYLE_MOTIF
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QMOTIFSTYLE_H
diff --git a/src/gui/styles/qmotifstyle_p.h b/src/widgets/styles/qmotifstyle_p.h
index 90e0c6d530..90e0c6d530 100644
--- a/src/gui/styles/qmotifstyle_p.h
+++ b/src/widgets/styles/qmotifstyle_p.h
diff --git a/src/gui/styles/qplastiquestyle.cpp b/src/widgets/styles/qplastiquestyle.cpp
index a5b0235dbe..a5b0235dbe 100644
--- a/src/gui/styles/qplastiquestyle.cpp
+++ b/src/widgets/styles/qplastiquestyle.cpp
diff --git a/src/widgets/styles/qplastiquestyle.h b/src/widgets/styles/qplastiquestyle.h
new file mode 100644
index 0000000000..d0afce6cf0
--- /dev/null
+++ b/src/widgets/styles/qplastiquestyle.h
@@ -0,0 +1,119 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPLASTIQUESTYLE_H
+#define QPLASTIQUESTYLE_H
+
+#include <QtWidgets/qwindowsstyle.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#if !defined(QT_NO_STYLE_PLASTIQUE)
+
+class QPlastiqueStylePrivate;
+class Q_WIDGETS_EXPORT QPlastiqueStyle : public QWindowsStyle
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QPlastiqueStyle)
+public:
+ QPlastiqueStyle();
+ ~QPlastiqueStyle();
+
+ void drawPrimitive(PrimitiveElement element, const QStyleOption *option,
+ QPainter *painter, const QWidget *widget = 0) const;
+ void drawControl(ControlElement element, const QStyleOption *option,
+ QPainter *painter, const QWidget *widget) const;
+ void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option,
+ QPainter *painter, const QWidget *widget) const;
+ QSize sizeFromContents(ContentsType type, const QStyleOption *option,
+ const QSize &size, const QWidget *widget) const;
+
+ QRect subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const;
+ QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt,
+ SubControl sc, const QWidget *widget) const;
+
+ int styleHint(StyleHint hint, const QStyleOption *option = 0, const QWidget *widget = 0,
+ QStyleHintReturn *returnData = 0) const;
+ SubControl hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option,
+ const QPoint &pos, const QWidget *widget = 0) const;
+
+ int pixelMetric(PixelMetric metric, const QStyleOption *option = 0, const QWidget *widget = 0) const;
+
+ QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt,
+ const QWidget *widget = 0) const;
+
+ void polish(QWidget *widget);
+ void polish(QApplication *app);
+ void polish(QPalette &pal);
+ void unpolish(QWidget *widget);
+ void unpolish(QApplication *app);
+
+ QPalette standardPalette() const;
+
+protected Q_SLOTS:
+ QIcon standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *opt = 0,
+ const QWidget *widget = 0) const;
+ int layoutSpacingImplementation(QSizePolicy::ControlType control1,
+ QSizePolicy::ControlType control2,
+ Qt::Orientation orientation,
+ const QStyleOption *option = 0,
+ const QWidget *widget = 0) const;
+
+protected:
+ bool eventFilter(QObject *watched, QEvent *event);
+ void timerEvent(QTimerEvent *event);
+
+private:
+ Q_DISABLE_COPY(QPlastiqueStyle)
+ void *reserved;
+};
+
+#endif // QT_NO_STYLE_PLASTIQUE
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QPLASTIQUESTYLE_H
diff --git a/src/gui/styles/qproxystyle.cpp b/src/widgets/styles/qproxystyle.cpp
index 476a758992..476a758992 100644
--- a/src/gui/styles/qproxystyle.cpp
+++ b/src/widgets/styles/qproxystyle.cpp
diff --git a/src/widgets/styles/qproxystyle.h b/src/widgets/styles/qproxystyle.h
new file mode 100644
index 0000000000..96c5c34f18
--- /dev/null
+++ b/src/widgets/styles/qproxystyle.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPROXYSTYLE_H
+#define QPROXYSTYLE_H
+
+#include <QtWidgets/QCommonStyle>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#if !defined(QT_NO_STYLE_PROXY)
+
+class QProxyStylePrivate;
+class Q_WIDGETS_EXPORT QProxyStyle : public QCommonStyle
+{
+ Q_OBJECT
+
+public:
+ QProxyStyle(QStyle *baseStyle = 0);
+ ~QProxyStyle();
+
+ QStyle *baseStyle() const;
+ void setBaseStyle(QStyle *style);
+
+ void drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = 0) const;
+ void drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = 0) const;
+ void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget = 0) const;
+ void drawItemText(QPainter *painter, const QRect &rect, int flags, const QPalette &pal, bool enabled,
+ const QString &text, QPalette::ColorRole textRole = QPalette::NoRole) const;
+ virtual void drawItemPixmap(QPainter *painter, const QRect &rect, int alignment, const QPixmap &pixmap) const;
+
+ QSize sizeFromContents(ContentsType type, const QStyleOption *option, const QSize &size, const QWidget *widget) const;
+
+ QRect subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const;
+ QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc, const QWidget *widget) const;
+ QRect itemTextRect(const QFontMetrics &fm, const QRect &r, int flags, bool enabled, const QString &text) const;
+ QRect itemPixmapRect(const QRect &r, int flags, const QPixmap &pixmap) const;
+
+ SubControl hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option, const QPoint &pos, const QWidget *widget = 0) const;
+ int styleHint(StyleHint hint, const QStyleOption *option = 0, const QWidget *widget = 0, QStyleHintReturn *returnData = 0) const;
+ int pixelMetric(PixelMetric metric, const QStyleOption *option = 0, const QWidget *widget = 0) const;
+
+ QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt, const QWidget *widget = 0) const;
+ QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, const QStyleOption *opt) const;
+ QPalette standardPalette() const;
+
+ void polish(QWidget *widget);
+ void polish(QPalette &pal);
+ void polish(QApplication *app);
+
+ void unpolish(QWidget *widget);
+ void unpolish(QApplication *app);
+
+protected:
+ bool event(QEvent *e);
+
+protected Q_SLOTS:
+ QIcon standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *option, const QWidget *widget) const;
+ int layoutSpacingImplementation(QSizePolicy::ControlType control1, QSizePolicy::ControlType control2,
+ Qt::Orientation orientation, const QStyleOption *option = 0, const QWidget *widget = 0) const;
+private:
+ Q_DISABLE_COPY(QProxyStyle)
+ Q_DECLARE_PRIVATE(QProxyStyle)
+};
+
+#endif // QT_NO_STYLE_PROXY
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QPROXYSTYLE_H
diff --git a/src/gui/styles/qproxystyle_p.h b/src/widgets/styles/qproxystyle_p.h
index 9ccd382cd3..9ccd382cd3 100644
--- a/src/gui/styles/qproxystyle_p.h
+++ b/src/widgets/styles/qproxystyle_p.h
diff --git a/src/gui/styles/qs60style.cpp b/src/widgets/styles/qs60style.cpp
index 634cf00536..634cf00536 100644
--- a/src/gui/styles/qs60style.cpp
+++ b/src/widgets/styles/qs60style.cpp
diff --git a/src/widgets/styles/qs60style.h b/src/widgets/styles/qs60style.h
new file mode 100644
index 0000000000..4520d19fd3
--- /dev/null
+++ b/src/widgets/styles/qs60style.h
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QS60STYLE_H
+#define QS60STYLE_H
+
+#include <QtWidgets/qcommonstyle.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+//Public custom pixel metrics values.
+//These can be used to fetch custom pixel metric value from outside QS60Style.
+enum {
+ PM_FrameCornerWidth = QStyle::PM_CustomBase + 1,
+ PM_FrameCornerHeight,
+ PM_BoldLineWidth,
+ PM_ThinLineWidth,
+ PM_MessageBoxHeight
+ };
+
+class QS60StylePrivate;
+
+class Q_WIDGETS_EXPORT QS60Style : public QCommonStyle
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QS60Style)
+
+public:
+ QS60Style();
+ ~QS60Style();
+
+ void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget = 0) const;
+ void drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = 0) const;
+ void drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = 0) const;
+ int pixelMetric(PixelMetric metric, const QStyleOption *option = 0, const QWidget *widget = 0) const;
+ QSize sizeFromContents(ContentsType ct, const QStyleOption *opt, const QSize &contentsSize, const QWidget *w = 0) const;
+ int styleHint(StyleHint sh, const QStyleOption *opt = 0, const QWidget *w = 0,
+ QStyleHintReturn *shret = 0) const;
+ QRect subControlRect(ComplexControl control, const QStyleOptionComplex *option, SubControl scontrol, const QWidget *widget = 0) const;
+ QRect subElementRect(SubElement element, const QStyleOption *opt, const QWidget *widget = 0) const;
+ void polish(QWidget *widget);
+ void unpolish(QWidget *widget);
+ void polish(QApplication *application);
+ void unpolish(QApplication *application);
+#ifndef Q_NO_USING_KEYWORD
+ using QCommonStyle::polish;
+#endif
+ bool event(QEvent *e);
+
+#ifndef Q_OS_SYMBIAN
+ static QStringList partKeys();
+ static QStringList colorListKeys();
+ void setS60Theme(const QHash<QString, QPicture> &parts,
+ const QHash<QPair<QString , int>, QColor> &colors);
+ bool loadS60ThemeFromBlob(const QString &blobFile);
+ bool saveS60ThemeToBlob(const QString &blobFile) const;
+#endif // !Q_OS_SYMBIAN
+
+protected Q_SLOTS:
+ QIcon standardIconImplementation(
+ StandardPixmap standardIcon, const QStyleOption * option = 0, const QWidget * widget = 0 ) const;
+
+protected:
+ void timerEvent(QTimerEvent *event);
+ bool eventFilter(QObject *o, QEvent *e);
+private:
+ Q_DISABLE_COPY(QS60Style)
+ friend class QStyleFactory;
+ friend class QApplicationPrivate;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QS60STYLE_H
diff --git a/src/gui/styles/qs60style_p.h b/src/widgets/styles/qs60style_p.h
index ee981c036b..ee981c036b 100644
--- a/src/gui/styles/qs60style_p.h
+++ b/src/widgets/styles/qs60style_p.h
diff --git a/src/widgets/styles/qs60style_s60.cpp b/src/widgets/styles/qs60style_s60.cpp
new file mode 100644
index 0000000000..f7ced9e8f8
--- /dev/null
+++ b/src/widgets/styles/qs60style_s60.cpp
@@ -0,0 +1,1591 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qs60style.h"
+#include "qs60style_p.h"
+#include "qpainter.h"
+#include "qstyleoption.h"
+#include "qstyle.h"
+#include "private/qt_s60_p.h"
+#include "private/qpixmap_s60_p.h"
+#include "private/qcore_symbian_p.h"
+#include "private/qvolatileimage_p.h"
+#include "qapplication.h"
+#include "qsettings.h"
+
+#include <w32std.h>
+#include <AknsConstants.h>
+#include <aknconsts.h>
+#include <AknsItemID.h>
+#include <AknsUtils.h>
+#include <AknsDrawUtils.h>
+#include <AknsSkinInstance.h>
+#include <AknsBasicBackgroundControlContext.h>
+#include <avkon.mbg>
+#include <AknFontAccess.h>
+#include <AknLayoutFont.h>
+#include <AknUtils.h>
+#include <aknnavi.h>
+#include <gulicon.h>
+#include <AknBitmapAnimation.h>
+#include <centralrepository.h>
+
+#if !defined(QT_NO_STYLE_S60) || defined(QT_PLUGIN)
+
+QT_BEGIN_NAMESPACE
+
+enum TDrawType {
+ EDrawIcon,
+ EDrawGulIcon,
+ EDrawBackground,
+ EDrawAnimation,
+ ENoDraw
+};
+
+const TUid personalisationUID = { 0x101F876F };
+
+enum TSupportRelease {
+ ES60_None = 0x0000, //indicates that the commonstyle should draw the graphics
+ ES60_3_1 = 0x0001,
+ ES60_3_2 = 0x0002,
+ ES60_5_0 = 0x0004,
+ ES60_5_1 = 0x0008,
+ ES60_5_2 = 0x0010,
+ ES60_5_3 = 0x0020,
+ ES60_3_X = ES60_3_1 | ES60_3_2,
+ // Releases before Symbian Foundation
+ ES60_PreSF = ES60_3_1 | ES60_3_2 | ES60_5_0,
+ // Releases before the S60 5.2
+ ES60_Pre52 = ES60_3_1 | ES60_3_2 | ES60_5_0 | ES60_5_1,
+ // Releases before S60 5.3
+ ES60_Pre53 = ES60_3_1 | ES60_3_2 | ES60_5_0 | ES60_5_1 | ES60_5_2,
+ // Add all new releases here
+ ES60_All = ES60_3_1 | ES60_3_2 | ES60_5_0 | ES60_5_1 | ES60_5_2 | ES60_5_3
+};
+
+typedef struct {
+ const TAknsItemID &skinID; // Determines default theme graphics ID.
+ TDrawType drawType; // Determines which native drawing routine is used to draw this item.
+ int supportInfo; // Defines the S60 versions that use the default graphics.
+ // These two, define new graphics that are used in releases other than partMapEntry.supportInfo defined releases.
+ // In general, these are given in numeric form to allow style compilation in earlier
+ // native releases that do not contain the new graphics.
+ int newMajorSkinId;
+ int newMinorSkinId;
+} partMapEntry;
+
+AnimationData::AnimationData(const QS60StyleEnums::SkinParts part, int frames, int interval) : m_id(part),
+ m_frames(frames), m_interval(interval), m_mode(QS60StyleEnums::AM_Looping)
+{
+}
+
+AnimationDataV2::AnimationDataV2(const AnimationData &data) : AnimationData(data.m_id, data.m_frames, data.m_interval),
+ m_animation(0), m_currentFrame(0), m_resourceBased(false), m_timerId(0)
+{
+}
+AnimationDataV2::~AnimationDataV2()
+{
+ delete m_animation;
+}
+
+QS60StyleAnimation::QS60StyleAnimation(const QS60StyleEnums::SkinParts part, int frames, int interval)
+{
+ QT_TRAP_THROWING(m_defaultData = new (ELeave) AnimationData(part, frames, interval));
+ QT_TRAP_THROWING(m_currentData = new (ELeave) AnimationDataV2(*m_defaultData));
+}
+
+QS60StyleAnimation::~QS60StyleAnimation()
+{
+ delete m_currentData;
+ delete m_defaultData;
+}
+
+void QS60StyleAnimation::setAnimationObject(CAknBitmapAnimation* animation)
+{
+ Q_ASSERT(animation);
+ if (m_currentData->m_animation)
+ delete m_currentData->m_animation;
+ m_currentData->m_animation = animation;
+}
+
+void QS60StyleAnimation::resetToDefaults()
+{
+ delete m_currentData;
+ m_currentData = 0;
+ QT_TRAP_THROWING(m_currentData = new (ELeave) AnimationDataV2(*m_defaultData));
+}
+
+class QS60StyleModeSpecifics
+{
+public:
+ static QPixmap skinnedGraphics(QS60StyleEnums::SkinParts stylepart,
+ const QSize &size, QS60StylePrivate::SkinElementFlags flags);
+ static QPixmap skinnedGraphics(QS60StylePrivate::SkinFrameElements frameElement, const QSize &size, QS60StylePrivate::SkinElementFlags flags);
+ static QPixmap colorSkinnedGraphics(const QS60StyleEnums::SkinParts &stylepart,
+ const QSize &size, QPainter *painter, QS60StylePrivate::SkinElementFlags flags);
+ static QColor colorValue(const TAknsItemID &colorGroup, int colorIndex);
+ static QPixmap fromFbsBitmap(CFbsBitmap *icon, CFbsBitmap *mask, QS60StylePrivate::SkinElementFlags flags, const TSize& targetSize);
+ static bool disabledPartGraphic(QS60StyleEnums::SkinParts &part);
+ static bool disabledFrameGraphic(QS60StylePrivate::SkinFrameElements &frame);
+ static QPixmap generateMissingThemeGraphic(QS60StyleEnums::SkinParts &part, const QSize &size, QS60StylePrivate::SkinElementFlags flags);
+ static TAknsItemID partSpecificThemeId(int part);
+
+ static QVariant themeDefinition(QS60StyleEnums::ThemeDefinitions definition, QS60StyleEnums::SkinParts part);
+
+private:
+ static QPixmap createSkinnedGraphicsLX(QS60StyleEnums::SkinParts part,
+ const QSize &size, QS60StylePrivate::SkinElementFlags flags);
+ static QPixmap createSkinnedGraphicsLX(QS60StylePrivate::SkinFrameElements frameElement, const QSize &size, QS60StylePrivate::SkinElementFlags flags);
+ static QPixmap colorSkinnedGraphicsLX(const QS60StyleEnums::SkinParts &stylepart,
+ const QSize &size, QPainter *painter, QS60StylePrivate::SkinElementFlags flags);
+ static void frameIdAndCenterId(QS60StylePrivate::SkinFrameElements frameElement, TAknsItemID &frameId, TAknsItemID &centerId);
+ static TRect innerRectFromElement(QS60StylePrivate::SkinFrameElements frameElement, const TRect &outerRect);
+ static void fallbackInfo(const QS60StyleEnums::SkinParts &stylePart, TInt &fallbackIndex);
+ static bool checkSupport(const int supportedRelease);
+ // Array to match the skin ID, fallback graphics and Qt widget graphics.
+ static const partMapEntry m_partMap[];
+};
+
+const partMapEntry QS60StyleModeSpecifics::m_partMap[] = {
+ /* SP_QgnGrafBarWaitAnim */ {KAknsIIDQgnGrafBarWaitAnim, EDrawAnimation, ES60_All, -1,-1},
+ /* SP_QgnGrafBarFrameCenter */ {KAknsIIDQgnGrafBarFrameCenter, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnGrafBarFrameSideL */ {KAknsIIDQgnGrafBarFrameSideL, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnGrafBarFrameSideR */ {KAknsIIDQgnGrafBarFrameSideR, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnGrafBarProgress */ {KAknsIIDQgnGrafBarProgress, EDrawIcon, ES60_All, -1,-1},
+ // No drop area for 3.x non-touch devices
+ /* SP_QgnGrafOrgBgGrid */ {KAknsIIDNone, EDrawIcon, ES60_3_X, EAknsMajorGeneric ,0x1eba}, //KAknsIIDQgnGrafOrgBgGrid
+ /* SP_QgnGrafScrollArrowDown */ {KAknsIIDQgnGrafScrollArrowDown, EDrawGulIcon, ES60_All, -1,-1},
+ /* SP_QgnGrafScrollArrowLeft */ {KAknsIIDQgnGrafScrollArrowLeft, EDrawGulIcon, ES60_All, -1,-1},
+ /* SP_QgnGrafScrollArrowRight */ {KAknsIIDQgnGrafScrollArrowRight, EDrawGulIcon, ES60_All, -1,-1},
+ /* SP_QgnGrafScrollArrowUp */ {KAknsIIDQgnGrafScrollArrowUp, EDrawGulIcon, ES60_All, -1,-1},
+
+ // In S60 5.3 there is a new tab graphic
+ /* SP_QgnGrafTabActiveL */ {KAknsIIDQgnGrafTabActiveL, EDrawIcon, ES60_Pre53, EAknsMajorSkin, 0x2219}, //KAknsIIDQtgFrTabActiveNormalL
+ /* SP_QgnGrafTabActiveM */ {KAknsIIDQgnGrafTabActiveM, EDrawIcon, ES60_Pre53, EAknsMajorSkin, 0x221b}, //KAknsIIDQtgFrTabActiveNormalC
+ /* SP_QgnGrafTabActiveR */ {KAknsIIDQgnGrafTabActiveR, EDrawIcon, ES60_Pre53, EAknsMajorSkin, 0x221a}, //KAknsIIDQtgFrTabActiveNormalR
+ /* SP_QgnGrafTabPassiveL */ {KAknsIIDQgnGrafTabPassiveL, EDrawIcon, ES60_Pre53, EAknsMajorSkin, 0x2221}, //KAknsIIDQtgFrTabPassiveNormalL
+ /* SP_QgnGrafTabPassiveM */ {KAknsIIDQgnGrafTabPassiveM, EDrawIcon, ES60_Pre53, EAknsMajorSkin, 0x2223}, //KAknsIIDQtgFrTabPassiveNormalC
+ /* SP_QgnGrafTabPassiveR */ {KAknsIIDQgnGrafTabPassiveR, EDrawIcon, ES60_Pre53, EAknsMajorSkin, 0x2222}, //KAknsIIDQtgFrTabPassiveNormalR
+
+ // In 3.1 there is no slider groove.
+ /* SP_QgnGrafNsliderEndLeft */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x19cf /* KAknsIIDQgnGrafNsliderEndLeft */},
+ /* SP_QgnGrafNsliderEndRight */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x19d0 /* KAknsIIDQgnGrafNsliderEndRight */},
+ /* SP_QgnGrafNsliderMiddle */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x19d2 /* KAknsIIDQgnGrafNsliderMiddle */},
+ /* SP_QgnIndiCheckboxOff */ {KAknsIIDQgnIndiCheckboxOff, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnIndiCheckboxOn */ {KAknsIIDQgnIndiCheckboxOn, EDrawIcon, ES60_All, -1,-1},
+
+ // Following 5 items (SP_QgnIndiHlColSuper - SP_QgnIndiHlLineStraight) are available starting from S60 release 3.2.
+ // In 3.1 CommonStyle drawing is used for these QTreeView elements, since no similar icons in AVKON UI.
+ /* SP_QgnIndiHlColSuper */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x17d5 /* KAknsIIDQgnIndiHlColSuper */},
+ /* SP_QgnIndiHlExpSuper */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x17d6 /* KAknsIIDQgnIndiHlExpSuper */},
+ /* SP_QgnIndiHlLineBranch */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x17d7 /* KAknsIIDQgnIndiHlLineBranch */},
+ /* SP_QgnIndiHlLineEnd */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x17d8 /* KAknsIIDQgnIndiHlLineEnd */},
+ /* SP_QgnIndiHlLineStraight */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x17d9 /* KAknsIIDQgnIndiHlLineStraight */},
+ /* SP_QgnIndiMarkedAdd */ {KAknsIIDQgnIndiMarkedAdd, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnIndiNaviArrowLeft */ {KAknsIIDQgnIndiNaviArrowLeft, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnIndiNaviArrowRight */ {KAknsIIDQgnIndiNaviArrowRight, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnIndiRadiobuttOff */ {KAknsIIDQgnIndiRadiobuttOff, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnIndiRadiobuttOn */ {KAknsIIDQgnIndiRadiobuttOn, EDrawIcon, ES60_All, -1,-1},
+
+ // In 3.1 there different slider graphic and no pressed state.
+ /* SP_QgnGrafNsliderMarker */ {KAknsIIDQgnIndiSliderEdit, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x19d1 /* KAknsIIDQgnGrafNsliderMarker */},
+ /* SP_QgnGrafNsliderMarkerSelected */ {KAknsIIDQgnIndiSliderEdit, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x1a4a /* KAknsIIDQgnGrafNsliderMarkerSelected */},
+ /* SP_QgnIndiSubmenu */ {KAknsIIDQgnIndiSubmenu, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnNoteErased */ {KAknsIIDQgnNoteErased, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnNoteError */ {KAknsIIDQgnNoteError, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnNoteInfo */ {KAknsIIDQgnNoteInfo, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnNoteOk */ {KAknsIIDQgnNoteOk, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnNoteQuery */ {KAknsIIDQgnNoteQuery, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnNoteWarning */ {KAknsIIDQgnNoteWarning, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnPropFileSmall */ {KAknsIIDQgnPropFileSmall, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnPropFolderCurrent */ {KAknsIIDQgnPropFolderCurrent, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnPropFolderSmall */ {KAknsIIDQgnPropFolderSmall, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnPropFolderSmallNew */ {KAknsIIDQgnPropFolderSmallNew, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnPropPhoneMemcLarge */ {KAknsIIDQgnPropPhoneMemcLarge, EDrawIcon, ES60_All, -1,-1},
+
+ // Toolbar graphics is different in 3.1/3.2 vs. 5.0
+ /* SP_QgnFrSctrlButtonCornerTl */ {KAknsIIDQsnFrButtonTbCornerTl, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2301}, /* KAknsIIDQgnFrSctrlButtonCornerTl*/
+ /* SP_QgnFrSctrlButtonCornerTr */ {KAknsIIDQsnFrButtonTbCornerTr, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2302},
+ /* SP_QgnFrSctrlButtonCornerBl */ {KAknsIIDQsnFrButtonTbCornerBl, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2303},
+ /* SP_QgnFrSctrlButtonCornerBr */ {KAknsIIDQsnFrButtonTbCornerBr, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2304},
+ /* SP_QgnFrSctrlButtonSideT */ {KAknsIIDQsnFrButtonTbSideT, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2305},
+ /* SP_QgnFrSctrlButtonSideB */ {KAknsIIDQsnFrButtonTbSideB, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2306},
+ /* SP_QgnFrSctrlButtonSideL */ {KAknsIIDQsnFrButtonTbSideL, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2307},
+ /* SP_QgnFrSctrlButtonSideR */ {KAknsIIDQsnFrButtonTbSideR, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2308},
+ /* SP_QgnFrSctrlButtonCenter */ {KAknsIIDQsnFrButtonTbCenter, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2309}, /*KAknsIIDQgnFrSctrlButtonCenter*/
+
+ // No pressed state for toolbar button in 3.1/3.2.
+ /* SP_QgnFrSctrlButtonCornerTlPressed */ {KAknsIIDQsnFrButtonTbCornerTl, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2621}, /*KAknsIIDQgnFrSctrlButtonCornerTlPressed*/
+ /* SP_QgnFrSctrlButtonCornerTrPressed */ {KAknsIIDQsnFrButtonTbCornerTr, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2622},
+ /* SP_QgnFrSctrlButtonCornerBlPressed */ {KAknsIIDQsnFrButtonTbCornerBl, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2623},
+ /* SP_QgnFrSctrlButtonCornerBrPressed */ {KAknsIIDQsnFrButtonTbCornerBr, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2624},
+ /* SP_QgnFrSctrlButtonSideTPressed */ {KAknsIIDQsnFrButtonTbSideT, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2625},
+ /* SP_QgnFrSctrlButtonSideBPressed */ {KAknsIIDQsnFrButtonTbSideB, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2626},
+ /* SP_QgnFrSctrlButtonSideLPressed */ {KAknsIIDQsnFrButtonTbSideL, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2627},
+ /* SP_QgnFrSctrlButtonSideRPressed */ {KAknsIIDQsnFrButtonTbSideR, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2628},
+ /* SP_QgnFrSctrlButtonCenterPressed */ {KAknsIIDQsnFrButtonTbCenter, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2629},
+
+ // 3.1 & 3.2 do not have pressed state for scrollbar, so use normal scrollbar graphics instead.
+ /* SP_QsnCpScrollHandleBottomPressed*/ {KAknsIIDQsnCpScrollHandleBottom, EDrawIcon, ES60_3_X, EAknsMajorGeneric, 0x20f8}, /*KAknsIIDQsnCpScrollHandleBottomPressed*/
+ /* SP_QsnCpScrollHandleMiddlePressed*/ {KAknsIIDQsnCpScrollHandleMiddle, EDrawIcon, ES60_3_X, EAknsMajorGeneric, 0x20f9}, /*KAknsIIDQsnCpScrollHandleMiddlePressed*/
+ /* SP_QsnCpScrollHandleTopPressed*/ {KAknsIIDQsnCpScrollHandleTop, EDrawIcon, ES60_3_X, EAknsMajorGeneric, 0x20fa}, /*KAknsIIDQsnCpScrollHandleTopPressed*/
+
+ /* SP_QsnBgScreen */ {KAknsIIDQsnBgScreen, EDrawBackground, ES60_All, -1,-1},
+
+ /* SP_QsnCpScrollBgBottom */ {KAknsIIDQsnCpScrollBgBottom, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QsnCpScrollBgMiddle */ {KAknsIIDQsnCpScrollBgMiddle, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QsnCpScrollBgTop */ {KAknsIIDQsnCpScrollBgTop, EDrawIcon, ES60_All, -1,-1},
+
+ /* SP_QsnCpScrollHandleBottom */ {KAknsIIDQsnCpScrollHandleBottom, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QsnCpScrollHandleMiddle */ {KAknsIIDQsnCpScrollHandleMiddle, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QsnCpScrollHandleTop */ {KAknsIIDQsnCpScrollHandleTop, EDrawIcon, ES60_All, -1,-1},
+
+ /* SP_QsnFrButtonTbCornerTl */ {KAknsIIDQsnFrButtonTbCornerTl, ENoDraw, ES60_All, -1, -1},
+ /* SP_QsnFrButtonTbCornerTr */ {KAknsIIDQsnFrButtonTbCornerTr, ENoDraw, ES60_All, -1, -1},
+ /* SP_QsnFrButtonTbCornerBl */ {KAknsIIDQsnFrButtonTbCornerBl, ENoDraw, ES60_All, -1, -1},
+ /* SP_QsnFrButtonTbCornerBr */ {KAknsIIDQsnFrButtonTbCornerBr, ENoDraw, ES60_All, -1, -1},
+ /* SP_QsnFrButtonTbSideT */ {KAknsIIDQsnFrButtonTbSideT, ENoDraw, ES60_All, -1, -1},
+ /* SP_QsnFrButtonTbSideB */ {KAknsIIDQsnFrButtonTbSideB, ENoDraw, ES60_All, -1, -1},
+ /* SP_QsnFrButtonTbSideL */ {KAknsIIDQsnFrButtonTbSideL, ENoDraw, ES60_All, -1, -1},
+ /* SP_QsnFrButtonTbSideR */ {KAknsIIDQsnFrButtonTbSideR, ENoDraw, ES60_All, -1, -1},
+ /* SP_QsnFrButtonTbCenter */ {KAknsIIDQsnFrButtonTbCenter, EDrawIcon, ES60_All, -1, -1},
+
+ /* SP_QsnFrButtonTbCornerTlPressed */{KAknsIIDQsnFrButtonTbCornerTlPressed, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrButtonTbCornerTrPressed */{KAknsIIDQsnFrButtonTbCornerTrPressed, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrButtonTbCornerBlPressed */{KAknsIIDQsnFrButtonTbCornerBlPressed, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrButtonTbCornerBrPressed */{KAknsIIDQsnFrButtonTbCornerBrPressed, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrButtonTbSideTPressed */ {KAknsIIDQsnFrButtonTbSideTPressed, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrButtonTbSideBPressed */ {KAknsIIDQsnFrButtonTbSideBPressed, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrButtonTbSideLPressed */ {KAknsIIDQsnFrButtonTbSideLPressed, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrButtonTbSideRPressed */ {KAknsIIDQsnFrButtonTbSideRPressed, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrButtonTbCenterPressed */ {KAknsIIDQsnFrButtonTbCenterPressed, EDrawIcon, ES60_All, -1,-1},
+
+ /* SP_QsnFrCaleCornerTl */ {KAknsIIDQsnFrCaleCornerTl, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrCaleCornerTr */ {KAknsIIDQsnFrCaleCornerTr, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrCaleCornerBl */ {KAknsIIDQsnFrCaleCornerBl, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrCaleCornerBr */ {KAknsIIDQsnFrCaleCornerBr, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrCaleSideT */ {KAknsIIDQsnFrCaleSideT, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrCaleSideB */ {KAknsIIDQsnFrCaleSideB, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrCaleSideL */ {KAknsIIDQsnFrCaleSideL, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrCaleSideR */ {KAknsIIDQsnFrCaleSideR, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrCaleCenter */ {KAknsIIDQsnFrCaleCenter, ENoDraw, ES60_All, -1,-1},
+
+ /* SP_QsnFrCaleHeadingCornerTl */ {KAknsIIDQsnFrCaleHeadingCornerTl, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrCaleHeadingCornerTr */ {KAknsIIDQsnFrCaleHeadingCornerTr, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrCaleHeadingCornerBl */ {KAknsIIDQsnFrCaleHeadingCornerBl, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrCaleHeadingCornerBr */ {KAknsIIDQsnFrCaleHeadingCornerBr, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrCaleHeadingSideT */ {KAknsIIDQsnFrCaleHeadingSideT, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrCaleHeadingSideB */ {KAknsIIDQsnFrCaleHeadingSideB, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrCaleHeadingSideL */ {KAknsIIDQsnFrCaleHeadingSideL, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrCaleHeadingSideR */ {KAknsIIDQsnFrCaleHeadingSideR, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrCaleHeadingCenter */ {KAknsIIDQsnFrCaleHeadingCenter, ENoDraw, ES60_All, -1,-1},
+
+ /* SP_QsnFrInputCornerTl */ {KAknsIIDQsnFrInputCornerTl, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrInputCornerTr */ {KAknsIIDQsnFrInputCornerTr, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrInputCornerBl */ {KAknsIIDQsnFrInputCornerBl, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrInputCornerBr */ {KAknsIIDQsnFrInputCornerBr, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrInputSideT */ {KAknsIIDQsnFrInputSideT, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrInputSideB */ {KAknsIIDQsnFrInputSideB, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrInputSideL */ {KAknsIIDQsnFrInputSideL, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrInputSideR */ {KAknsIIDQsnFrInputSideR, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrInputCenter */ {KAknsIIDQsnFrInputCenter, ENoDraw, ES60_All, -1,-1},
+
+ /* SP_QsnFrListCornerTl */ {KAknsIIDQsnFrListCornerTl, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrListCornerTr */ {KAknsIIDQsnFrListCornerTr, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrListCornerBl */ {KAknsIIDQsnFrListCornerBl, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrListCornerBr */ {KAknsIIDQsnFrListCornerBr, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrListSideT */ {KAknsIIDQsnFrListSideT, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrListSideB */ {KAknsIIDQsnFrListSideB, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrListSideL */ {KAknsIIDQsnFrListSideL, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrListSideR */ {KAknsIIDQsnFrListSideR, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrListCenter */ {KAknsIIDQsnFrListCenter, ENoDraw, ES60_All, -1,-1},
+
+ /* SP_QsnFrPopupCornerTl */ {KAknsIIDQsnFrPopupCornerTl, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrPopupCornerTr */ {KAknsIIDQsnFrPopupCornerTr, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrPopupCornerBl */ {KAknsIIDQsnFrPopupCornerBl, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrPopupCornerBr */ {KAknsIIDQsnFrPopupCornerBr, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrPopupSideT */ {KAknsIIDQsnFrPopupSideT, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrPopupSideB */ {KAknsIIDQsnFrPopupSideB, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrPopupSideL */ {KAknsIIDQsnFrPopupSideL, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrPopupSideR */ {KAknsIIDQsnFrPopupSideR, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrPopupCenter */ {KAknsIIDQsnFrPopupCenterSubmenu, ENoDraw, ES60_All, -1,-1},
+
+ // ToolTip graphics different in 3.1 vs. 3.2+.
+ /* SP_QsnFrPopupPreviewCornerTl */ {KAknsIIDQsnFrPopupCornerTl, ENoDraw, ES60_3_1, EAknsMajorSkin, 0x19c5}, /* KAknsIIDQsnFrPopupPreviewCornerTl */
+ /* SP_QsnFrPopupPreviewCornerTr */ {KAknsIIDQsnFrPopupCornerTr, ENoDraw, ES60_3_1, EAknsMajorSkin, 0x19c6},
+ /* SP_QsnFrPopupPreviewCornerBl */ {KAknsIIDQsnFrPopupCornerBl, ENoDraw, ES60_3_1, EAknsMajorSkin, 0x19c3},
+ /* SP_QsnFrPopupPreviewCornerBr */ {KAknsIIDQsnFrPopupCornerBr, ENoDraw, ES60_3_1, EAknsMajorSkin, 0x19c4},
+ /* SP_QsnFrPopupPreviewSideT */ {KAknsIIDQsnFrPopupSideT, ENoDraw, ES60_3_1, EAknsMajorSkin, 0x19ca},
+ /* SP_QsnFrPopupPreviewSideB */ {KAknsIIDQsnFrPopupSideB, ENoDraw, ES60_3_1, EAknsMajorSkin, 0x19c7},
+ /* SP_QsnFrPopupPreviewSideL */ {KAknsIIDQsnFrPopupSideL, ENoDraw, ES60_3_1, EAknsMajorSkin, 0x19c8},
+ /* SP_QsnFrPopupPreviewSideR */ {KAknsIIDQsnFrPopupSideR, ENoDraw, ES60_3_1, EAknsMajorSkin, 0x19c9},
+ /* SP_QsnFrPopupPreviewCenter */ {KAknsIIDQsnFrPopupCenter, ENoDraw, ES60_3_1, EAknsMajorSkin, 0x19c2},
+
+ /* SP_QsnFrSetOptCornerTl */ {KAknsIIDQsnFrSetOptCornerTl, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrSetOptCornerTr */ {KAknsIIDQsnFrSetOptCornerTr, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrSetOptCornerBl */ {KAknsIIDQsnFrSetOptCornerBl, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrSetOptCornerBr */ {KAknsIIDQsnFrSetOptCornerBr, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrSetOptSideT */ {KAknsIIDQsnFrSetOptSideT, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrSetOptSideB */ {KAknsIIDQsnFrSetOptSideB, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrSetOptSideL */ {KAknsIIDQsnFrSetOptSideL, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrSetOptSideR */ {KAknsIIDQsnFrSetOptSideR, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrSetOptCenter */ {KAknsIIDQsnFrSetOptCenter, ENoDraw, ES60_All, -1,-1},
+
+ // No toolbar frame for 5.0+ releases.
+ /* SP_QsnFrPopupSubCornerTl */ {KAknsIIDQsnFrPopupSubCornerTl, ENoDraw, ES60_3_X, -1,-1},
+ /* SP_QsnFrPopupSubCornerTr */ {KAknsIIDQsnFrPopupSubCornerTr, ENoDraw, ES60_3_X, -1,-1},
+ /* SP_QsnFrPopupSubCornerBl */ {KAknsIIDQsnFrPopupSubCornerBl, ENoDraw, ES60_3_X, -1,-1},
+ /* SP_QsnFrPopupSubCornerBr */ {KAknsIIDQsnFrPopupSubCornerBr, ENoDraw, ES60_3_X, -1,-1},
+ /* SP_QsnFrPopupSubSideT */ {KAknsIIDQsnFrPopupSubSideT, ENoDraw, ES60_3_X, -1,-1},
+ /* SP_QsnFrPopupSubSideB */ {KAknsIIDQsnFrPopupSubSideB, ENoDraw, ES60_3_X, -1,-1},
+ /* SP_QsnFrPopupSubSideL */ {KAknsIIDQsnFrPopupSubSideL, ENoDraw, ES60_3_X, -1,-1},
+ /* SP_QsnFrPopupSubSideR */ {KAknsIIDQsnFrPopupSubSideR, ENoDraw, ES60_3_X, -1,-1},
+ /* SP_QsnFrPopupSubCenter */ {KAknsIIDQsnFrPopupCenterSubmenu, ENoDraw, ES60_3_X, -1,-1},
+
+ // No inactive button graphics in 3.1/3.2
+ /* SP_QsnFrButtonCornerTlInactive */ {KAknsIIDQsnFrButtonTbCornerTl, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x21b1}, /*KAknsIIDQsnFrButtonCornerTlInactive*/
+ /* SP_QsnFrButtonCornerTrInactive */ {KAknsIIDQsnFrButtonTbCornerTr, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x21b2},
+ /* SP_QsnFrButtonCornerBlInactive */ {KAknsIIDQsnFrButtonTbCornerBl, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x21b3},
+ /* SP_QsnFrButtonCornerTrInactive */ {KAknsIIDQsnFrButtonTbCornerBr, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x21b4},
+ /* SP_QsnFrButtonSideTInactive */ {KAknsIIDQsnFrButtonTbSideT, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x21b5},
+ /* SP_QsnFrButtonSideBInactive */ {KAknsIIDQsnFrButtonTbSideB, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x21b6},
+ /* SP_QsnFrButtonSideLInactive */ {KAknsIIDQsnFrButtonTbSideL, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x21b7},
+ /* SP_QsnFrButtonSideRInactive */ {KAknsIIDQsnFrButtonTbSideR, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x21b8},
+ /* SP_QsnFrButtonCenterInactive */ {KAknsIIDQsnFrButtonTbCenter, EDrawIcon, ES60_3_X, EAknsMajorSkin, 0x21b9},
+
+ // No pressed down grid in 3.1/3.2
+ /* SP_QsnFrGridCornerTlPressed */ {KAknsIIDQsnFrGridCornerTl, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2681}, /*KAknsIIDQsnFrGridCornerTlPressed*/
+ /* SP_QsnFrGridCornerTrPressed */ {KAknsIIDQsnFrGridCornerTr, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2682},
+ /* SP_QsnFrGridCornerBlPressed */ {KAknsIIDQsnFrGridCornerBl, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2683},
+ /* SP_QsnFrGridCornerBrPressed */ {KAknsIIDQsnFrGridCornerBr, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2684},
+ /* SP_QsnFrGridSideTPressed */ {KAknsIIDQsnFrGridSideT, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2685},
+ /* SP_QsnFrGridSideBPressed */ {KAknsIIDQsnFrGridSideB, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2686},
+ /* SP_QsnFrGridSideLPressed */ {KAknsIIDQsnFrGridSideL, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2687},
+ /* SP_QsnFrGridSideRPressed */ {KAknsIIDQsnFrGridSideR, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2688},
+ /* SP_QsnFrGridCenterPressed */ {KAknsIIDQsnFrGridCenter, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2689},
+
+ // No pressed down list in 3.1/3.2
+ /* SP_QsnFrListCornerTlPressed */ {KAknsIIDQsnFrListCornerTl, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x268b}, /*KAknsIIDQsnFrListCornerTlPressed*/
+ /* SP_QsnFrListCornerTrPressed */ {KAknsIIDQsnFrListCornerTr, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x268c},
+ /* SP_QsnFrListCornerBlPressed */ {KAknsIIDQsnFrListCornerBl, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x268d},
+ /* SP_QsnFrListCornerBrPressed */ {KAknsIIDQsnFrListCornerBr, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x268e},
+ /* SP_QsnFrListSideTPressed */ {KAknsIIDQsnFrListSideT, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x268f},
+ /* SP_QsnFrListSideBPressed */ {KAknsIIDQsnFrListSideB, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2690},
+ /* SP_QsnFrListSideLPressed */ {KAknsIIDQsnFrListSideL, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2691},
+ /* SP_QsnFrListSideRPressed */ {KAknsIIDQsnFrListSideR, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2692},
+ /* SP_QsnFrListCenterPressed */ {KAknsIIDQsnFrListCenter, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2693},
+};
+
+QPixmap QS60StyleModeSpecifics::skinnedGraphics(
+ QS60StyleEnums::SkinParts stylepart, const QSize &size,
+ QS60StylePrivate::SkinElementFlags flags)
+{
+ QPixmap themedImage;
+ TRAPD( error, QT_TRYCATCH_LEAVING({
+ const QPixmap skinnedImage = createSkinnedGraphicsLX(stylepart, size, flags);
+ themedImage = skinnedImage;
+ }));
+ if (error)
+ return themedImage = QPixmap();
+ return themedImage;
+}
+
+QPixmap QS60StyleModeSpecifics::skinnedGraphics(
+ QS60StylePrivate::SkinFrameElements frame, const QSize &size, QS60StylePrivate::SkinElementFlags flags)
+{
+ QPixmap themedImage;
+ TRAPD( error, QT_TRYCATCH_LEAVING({
+ const QPixmap skinnedImage = createSkinnedGraphicsLX(frame, size, flags);
+ themedImage = skinnedImage;
+ }));
+ if (error)
+ return themedImage = QPixmap();
+ return themedImage;
+}
+
+QPixmap QS60StyleModeSpecifics::colorSkinnedGraphics(
+ const QS60StyleEnums::SkinParts &stylepart, const QSize &size, QPainter *painter,
+ QS60StylePrivate::SkinElementFlags flags)
+{
+ QPixmap colorGraphics;
+ TRAPD(error, QT_TRYCATCH_LEAVING(colorGraphics = colorSkinnedGraphicsLX(stylepart, size, painter, flags)));
+ return error ? QPixmap() : colorGraphics;
+}
+
+void QS60StyleModeSpecifics::fallbackInfo(const QS60StyleEnums::SkinParts &stylePart, TInt &fallbackIndex)
+{
+ switch(stylePart) {
+ case QS60StyleEnums::SP_QgnGrafBarWaitAnim:
+ fallbackIndex = EMbmAvkonQgn_graf_bar_wait_1;
+ break;
+ case QS60StyleEnums::SP_QgnGrafBarFrameCenter:
+ fallbackIndex = EMbmAvkonQgn_graf_bar_frame_center;
+ break;
+ case QS60StyleEnums::SP_QgnGrafBarFrameSideL:
+ fallbackIndex = EMbmAvkonQgn_graf_bar_frame_side_l;
+ break;
+ case QS60StyleEnums::SP_QgnGrafBarFrameSideR:
+ fallbackIndex = EMbmAvkonQgn_graf_bar_frame_side_r;
+ break;
+ case QS60StyleEnums::SP_QgnGrafBarProgress:
+ fallbackIndex = EMbmAvkonQgn_graf_bar_progress;
+ break;
+ case QS60StyleEnums::SP_QgnGrafTabActiveL:
+ fallbackIndex = EMbmAvkonQgn_graf_tab_active_l;
+ break;
+ case QS60StyleEnums::SP_QgnGrafTabActiveM:
+ fallbackIndex = EMbmAvkonQgn_graf_tab_active_m;
+ break;
+ case QS60StyleEnums::SP_QgnGrafTabActiveR:
+ fallbackIndex = EMbmAvkonQgn_graf_tab_active_r;
+ break;
+ case QS60StyleEnums::SP_QgnGrafTabPassiveL:
+ fallbackIndex = EMbmAvkonQgn_graf_tab_passive_l;
+ break;
+ case QS60StyleEnums::SP_QgnGrafTabPassiveM:
+ fallbackIndex = EMbmAvkonQgn_graf_tab_passive_m;
+ break;
+ case QS60StyleEnums::SP_QgnGrafTabPassiveR:
+ fallbackIndex = EMbmAvkonQgn_graf_tab_passive_r;
+ break;
+ case QS60StyleEnums::SP_QgnIndiCheckboxOff:
+ fallbackIndex = EMbmAvkonQgn_indi_checkbox_off;
+ break;
+ case QS60StyleEnums::SP_QgnIndiCheckboxOn:
+ fallbackIndex = EMbmAvkonQgn_indi_checkbox_on;
+ break;
+ case QS60StyleEnums::SP_QgnIndiHlColSuper:
+ fallbackIndex = 0x4456; /* EMbmAvkonQgn_indi_hl_col_super */
+ break;
+ case QS60StyleEnums::SP_QgnIndiHlExpSuper:
+ fallbackIndex = 0x4458; /* EMbmAvkonQgn_indi_hl_exp_super */
+ break;
+ case QS60StyleEnums::SP_QgnIndiHlLineBranch:
+ fallbackIndex = 0x445A; /* EMbmAvkonQgn_indi_hl_line_branch */
+ break;
+ case QS60StyleEnums::SP_QgnIndiHlLineEnd:
+ fallbackIndex = 0x445C; /* EMbmAvkonQgn_indi_hl_line_end */
+ break;
+ case QS60StyleEnums::SP_QgnIndiHlLineStraight:
+ fallbackIndex = 0x445E; /* EMbmAvkonQgn_indi_hl_line_straight */
+ break;
+ case QS60StyleEnums::SP_QgnIndiMarkedAdd:
+ fallbackIndex = EMbmAvkonQgn_indi_marked_add;
+ break;
+ case QS60StyleEnums::SP_QgnIndiNaviArrowLeft:
+ fallbackIndex = EMbmAvkonQgn_indi_navi_arrow_left;
+ break;
+ case QS60StyleEnums::SP_QgnIndiNaviArrowRight:
+ fallbackIndex = EMbmAvkonQgn_indi_navi_arrow_right;
+ break;
+ case QS60StyleEnums::SP_QgnIndiRadiobuttOff:
+ fallbackIndex = EMbmAvkonQgn_indi_radiobutt_off;
+ break;
+ case QS60StyleEnums::SP_QgnIndiRadiobuttOn:
+ fallbackIndex = EMbmAvkonQgn_indi_radiobutt_on;
+ break;
+ case QS60StyleEnums::SP_QgnGrafNsliderMarker:
+ fallbackIndex = 17572; /* EMbmAvkonQgn_graf_nslider_marker */
+ break;
+ case QS60StyleEnums::SP_QgnGrafNsliderMarkerSelected:
+ fallbackIndex = 17574; /* EMbmAvkonQgn_graf_nslider_marker_selected */
+ break;
+ case QS60StyleEnums::SP_QgnIndiSubmenu:
+ fallbackIndex = EMbmAvkonQgn_indi_submenu;
+ break;
+ case QS60StyleEnums::SP_QgnNoteErased:
+ fallbackIndex = EMbmAvkonQgn_note_erased;
+ break;
+ case QS60StyleEnums::SP_QgnNoteError:
+ fallbackIndex = EMbmAvkonQgn_note_error;
+ break;
+ case QS60StyleEnums::SP_QgnNoteInfo:
+ fallbackIndex = EMbmAvkonQgn_note_info;
+ break;
+ case QS60StyleEnums::SP_QgnNoteOk:
+ fallbackIndex = EMbmAvkonQgn_note_ok;
+ break;
+ case QS60StyleEnums::SP_QgnNoteQuery:
+ fallbackIndex = EMbmAvkonQgn_note_query;
+ break;
+ case QS60StyleEnums::SP_QgnNoteWarning:
+ fallbackIndex = EMbmAvkonQgn_note_warning;
+ break;
+ case QS60StyleEnums::SP_QgnPropFileSmall:
+ fallbackIndex = EMbmAvkonQgn_prop_file_small;
+ break;
+ case QS60StyleEnums::SP_QgnPropFolderCurrent:
+ fallbackIndex = EMbmAvkonQgn_prop_folder_current;
+ break;
+ case QS60StyleEnums::SP_QgnPropFolderSmall:
+ fallbackIndex = EMbmAvkonQgn_prop_folder_small;
+ break;
+ case QS60StyleEnums::SP_QgnPropFolderSmallNew:
+ fallbackIndex = EMbmAvkonQgn_prop_folder_small_new;
+ break;
+ case QS60StyleEnums::SP_QgnPropPhoneMemcLarge:
+ fallbackIndex = EMbmAvkonQgn_prop_phone_memc_large;
+ break;
+ default:
+ fallbackIndex = -1;
+ break;
+ }
+}
+
+QPixmap QS60StyleModeSpecifics::colorSkinnedGraphicsLX(
+ const QS60StyleEnums::SkinParts &stylepart,
+ const QSize &size, QPainter *painter, QS60StylePrivate::SkinElementFlags flags)
+{
+ // this function can throw both exceptions and leaves. There are no cleanup dependencies between Qt and Symbian parts.
+ const int stylepartIndex = (int)stylepart;
+ const TAknsItemID skinId = m_partMap[stylepartIndex].skinID;
+
+ TInt fallbackGraphicID = -1;
+ HBufC* iconFile = HBufC::NewLC( KMaxFileName );
+ fallbackInfo(stylepart, fallbackGraphicID);
+
+ TAknsItemID colorGroup = KAknsIIDQsnIconColors;
+ TRgb defaultColor = KRgbBlack;
+ int colorIndex = -1; //set a bogus value to color index to ensure that painter color is used
+ //to color the icon
+ if (painter) {
+ QRgb widgetColor = painter->pen().color().rgb();
+ defaultColor = TRgb(qRed(widgetColor), qGreen(widgetColor), qBlue(widgetColor));
+ }
+
+ const bool rotatedBy90or270 =
+ (flags & (QS60StylePrivate::SF_PointEast | QS60StylePrivate::SF_PointWest));
+ const TSize targetSize =
+ rotatedBy90or270?TSize(size.height(), size.width()):TSize(size.width(), size.height());
+ CFbsBitmap *icon = 0;
+ CFbsBitmap *iconMask = 0;
+ const TInt fallbackGraphicsMaskID =
+ fallbackGraphicID == KErrNotFound?KErrNotFound:fallbackGraphicID+1; //masks are auto-generated as next in mif files
+ MAknsSkinInstance* skinInstance = AknsUtils::SkinInstance();
+ AknsUtils::CreateColorIconLC(
+ skinInstance,
+ skinId,
+ colorGroup,
+ colorIndex,
+ icon,
+ iconMask,
+ AknIconUtils::AvkonIconFileName(),
+ fallbackGraphicID,
+ fallbackGraphicsMaskID,
+ defaultColor);
+
+ QPixmap result = fromFbsBitmap(icon, iconMask, flags, targetSize);
+ CleanupStack::PopAndDestroy(3); //icon, iconMask, iconFile
+ return result;
+}
+
+QColor QS60StyleModeSpecifics::colorValue(const TAknsItemID &colorGroup, int colorIndex)
+{
+ TRgb skinnedColor;
+ MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+ AknsUtils::GetCachedColor(skin, skinnedColor, colorGroup, colorIndex);
+ return QColor(skinnedColor.Red(),skinnedColor.Green(),skinnedColor.Blue());
+}
+
+struct QAutoFbsBitmapHeapLock
+{
+ QAutoFbsBitmapHeapLock(CFbsBitmap* aBmp) : mBmp(aBmp) { mBmp->LockHeap(); }
+ ~QAutoFbsBitmapHeapLock() { mBmp->UnlockHeap(); }
+ CFbsBitmap* mBmp;
+};
+
+QPixmap QS60StyleModeSpecifics::fromFbsBitmap(CFbsBitmap *icon, CFbsBitmap *mask, QS60StylePrivate::SkinElementFlags flags, const TSize &targetSize)
+{
+ Q_ASSERT(icon);
+
+ AknIconUtils::DisableCompression(icon);
+ TInt error = AknIconUtils::SetSize(icon, targetSize, EAspectRatioNotPreserved);
+
+ if (mask && !error) {
+ AknIconUtils::DisableCompression(mask);
+ error = AknIconUtils::SetSize(mask, targetSize, EAspectRatioNotPreserved);
+ }
+ if (error)
+ return QPixmap();
+
+ QPixmap pixmap;
+ QScopedPointer<QPlatformPixmap> pd(QPlatformPixmap::create(0, 0, QPlatformPixmap::PixmapType));
+ if (mask) {
+ // Try the efficient path with less copying and conversion.
+ QVolatileImage img(icon, mask);
+ pd->fromNativeType(&img, QPlatformPixmap::VolatileImage);
+ if (!pd->isNull())
+ pixmap = QPixmap(pd.take());
+ }
+ if (pixmap.isNull()) {
+ // Potentially more expensive path.
+ pd->fromNativeType(icon, QPlatformPixmap::FbsBitmap);
+ pixmap = QPixmap(pd.take());
+ if (mask) {
+ pixmap.setAlphaChannel(QPixmap::fromSymbianCFbsBitmap(mask));
+ }
+ }
+
+ if ((flags & QS60StylePrivate::SF_PointEast) ||
+ (flags & QS60StylePrivate::SF_PointSouth) ||
+ (flags & QS60StylePrivate::SF_PointWest)) {
+ QImage iconImage = pixmap.toImage();
+ QTransform imageTransform;
+ if (flags & QS60StylePrivate::SF_PointEast) {
+ imageTransform.rotate(90);
+ } else if (flags & QS60StylePrivate::SF_PointSouth) {
+ imageTransform.rotate(180);
+ iconImage = iconImage.transformed(imageTransform);
+ } else if (flags & QS60StylePrivate::SF_PointWest) {
+ imageTransform.rotate(270);
+ }
+ if (imageTransform.isRotating())
+ iconImage = iconImage.transformed(imageTransform);
+
+ pixmap = QPixmap::fromImage(iconImage);
+ }
+ if ((flags & QS60StylePrivate::SF_Mirrored_X_Axis) ||
+ (flags & QS60StylePrivate::SF_Mirrored_Y_Axis)) {
+ QImage iconImage = pixmap.toImage().mirrored(
+ flags & QS60StylePrivate::SF_Mirrored_X_Axis,
+ flags & QS60StylePrivate::SF_Mirrored_Y_Axis);
+ pixmap = QPixmap::fromImage(iconImage);
+ }
+
+ return pixmap;
+}
+
+bool QS60StylePrivate::isTouchSupported()
+{
+ return bool(AknLayoutUtils::PenEnabled());
+}
+
+bool QS60StylePrivate::isToolBarBackground()
+{
+ return (QSysInfo::s60Version() == QSysInfo::SV_S60_3_1 || QSysInfo::s60Version() == QSysInfo::SV_S60_3_2);
+}
+
+bool QS60StylePrivate::hasSliderGrooveGraphic()
+{
+ return QSysInfo::s60Version() != QSysInfo::SV_S60_3_1;
+}
+
+bool QS60StylePrivate::isSingleClickUi()
+{
+ return (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0);
+}
+
+void QS60StylePrivate::deleteStoredSettings()
+{
+ QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
+ settings.beginGroup(QLatin1String("QS60Style"));
+ settings.remove(QString());
+ settings.endGroup();
+}
+
+// Since S60Style has 'button' as a graphic, we don't have any native color which to use
+// for QPalette::Button. Therefore S60Style needs to guesstimate palette color by calculating
+// average rgb values for button pixels.
+// Returns Qt::black if there is an issue with the graphics (image is NULL, or no constBits() found).
+QColor QS60StylePrivate::colorFromFrameGraphics(SkinFrameElements frame) const
+{
+#ifndef QT_NO_SETTINGS
+ TInt themeID = 0;
+ //First we need to fetch active theme ID. We need to store the themeID at the same time
+ //as color, so that we can later check if the stored color is still from the same theme.
+ //Native side stores active theme UID/Timestamp into central repository.
+ int error = 0;
+ QT_TRAP_THROWING(
+ CRepository *themeRepository = CRepository::NewLC(personalisationUID);
+ if (themeRepository) {
+ TBuf<32> value; //themeID is currently max of 8 + 1 + 8 characters, but lets have some extra space
+ const TUint32 key = 0x00000002; //active theme key in the repository
+ error = themeRepository->Get(key, value);
+ if (error == KErrNone) {
+ TLex lex(value);
+ TPtrC numberToken(lex.NextToken());
+ if (numberToken.Length())
+ error = TLex(numberToken).Val(themeID);
+ else
+ error = KErrArgument;
+ }
+ }
+ CleanupStack::PopAndDestroy(themeRepository);
+ );
+
+ QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
+ settings.beginGroup(QLatin1String("QS60Style"));
+ if (themeID != 0) {
+ QVariant buttonColor = settings.value(QLatin1String("ButtonColor"));
+ if (!buttonColor.isNull()) {
+ //there is a stored color value, lets see if the theme ID matches
+ if (error == KErrNone) {
+ QVariant themeUID = settings.value(QLatin1String("ThemeUID"));
+ if (!themeUID.isNull() && themeUID.toInt() == themeID) {
+ QColor storedColor(buttonColor.value<QColor>());
+ if (storedColor.isValid())
+ return storedColor;
+ }
+ }
+ settings.remove(QString()); //if color was invalid, or theme has been changed, just delete all stored settings
+ }
+ }
+#endif
+
+ QColor color = calculatedColor(frame);
+
+#ifndef QT_NO_SETTINGS
+ settings.setValue(QLatin1String("ThemeUID"), QVariant(themeID));
+ if (frame == SF_ButtonNormal) //other colors are not currently calculated from graphics
+ settings.setValue(QLatin1String("ButtonColor"), QVariant(color));
+ settings.endGroup();
+#endif
+
+ return color;
+}
+
+QPoint qt_s60_fill_background_offset(const QWidget *targetWidget)
+{
+ CCoeControl *control = targetWidget->effectiveWinId();
+ TPoint pos(0,0);
+ if (control)
+ pos = control->PositionRelativeToScreen();
+ return QPoint(pos.iX, pos.iY);
+}
+
+QPixmap QS60StyleModeSpecifics::createSkinnedGraphicsLX(
+ QS60StyleEnums::SkinParts part, const QSize &size,
+ QS60StylePrivate::SkinElementFlags flags)
+{
+ // this function can throw both exceptions and leaves. There are no cleanup dependencies between Qt and Symbian parts.
+ if (!size.isValid())
+ return QPixmap();
+
+ // Check release support and change part, if necessary.
+ const TAknsItemID skinId = partSpecificThemeId((int)part);
+ const int stylepartIndex = (int)part;
+ const TDrawType drawType = m_partMap[stylepartIndex].drawType;
+ Q_ASSERT(drawType != ENoDraw);
+ const bool rotatedBy90or270 =
+ (flags & (QS60StylePrivate::SF_PointEast | QS60StylePrivate::SF_PointWest));
+ const TSize targetSize =
+ rotatedBy90or270 ? TSize(size.height(), size.width()) : qt_QSize2TSize(size);
+
+ MAknsSkinInstance* skinInstance = AknsUtils::SkinInstance();
+ static const TDisplayMode displayMode = S60->supportsPremultipliedAlpha ? Q_SYMBIAN_ECOLOR16MAP : EColor16MA;
+ static const TInt drawParam = S60->supportsPremultipliedAlpha ? KAknsDrawParamDefault : KAknsDrawParamRGBOnly;
+
+ QPixmap result;
+
+ switch (drawType) {
+ case EDrawGulIcon: {
+ CGulIcon* icon = AknsUtils::CreateGulIconL( AknsUtils::SkinInstance(), skinId, EFalse );
+ if (icon)
+ result = fromFbsBitmap(icon->Bitmap(), icon->Mask(), flags, targetSize);
+ delete icon;
+ break;
+ }
+ case EDrawIcon: {
+ TInt fallbackGraphicID = -1;
+ fallbackInfo(part, fallbackGraphicID);
+
+ CFbsBitmap *icon = 0;
+ CFbsBitmap *iconMask = 0;
+ const TInt fallbackGraphicsMaskID =
+ fallbackGraphicID == KErrNotFound?KErrNotFound:fallbackGraphicID+1; //masks are auto-generated as next in mif files
+
+ AknsUtils::CreateIconL(
+ skinInstance,
+ skinId,
+ icon,
+ iconMask,
+ AknIconUtils::AvkonIconFileName(),
+ fallbackGraphicID ,
+ fallbackGraphicsMaskID);
+
+ result = fromFbsBitmap(icon, iconMask, flags, targetSize);
+ delete icon;
+ delete iconMask;
+ break;
+ }
+ case EDrawBackground: {
+ // QS60WindowSurface::unlockBitmapHeap();
+ CFbsBitmap *background = new (ELeave) CFbsBitmap(); //offscreen
+ CleanupStack::PushL(background);
+ User::LeaveIfError(background->Create(targetSize, displayMode));
+
+ CFbsBitmapDevice *dev = CFbsBitmapDevice::NewL(background);
+ CleanupStack::PushL(dev);
+ CFbsBitGc *gc = NULL;
+ User::LeaveIfError(dev->CreateContext(gc));
+ CleanupStack::PushL(gc);
+
+ CAknsBasicBackgroundControlContext *bgContext = CAknsBasicBackgroundControlContext::NewL(
+ skinId,
+ targetSize,
+ EFalse);
+ CleanupStack::PushL(bgContext);
+
+ const TBool drawn = AknsDrawUtils::DrawBackground(
+ skinInstance,
+ bgContext,
+ NULL,
+ *gc,
+ TPoint(),
+ targetSize,
+ drawParam);
+
+ if (drawn)
+ result = fromFbsBitmap(background, NULL, flags, targetSize);
+ // if drawing fails in skin server, just ignore the background (probably OOM case)
+
+ CleanupStack::PopAndDestroy(4, background); //background, dev, gc, bgContext
+ // QS60WindowSurface::lockBitmapHeap();
+ break;
+ }
+ case EDrawAnimation: {
+ CFbsBitmap* animationFrame;
+ CFbsBitmap* frameMask;
+ CAknBitmapAnimation* aknAnimation = 0;
+ TBool constructedFromTheme = ETrue;
+
+ QS60StyleAnimation* animation = QS60StylePrivate::animationDefinition(part); //ownership is not passed
+ if (animation) {
+ if (!animation->animationObject() && !animation->isResourceBased()) {// no pre-made item exists, create new animation
+ CAknBitmapAnimation* newAnimation = CAknBitmapAnimation::NewL();
+ CleanupStack::PushL(newAnimation);
+ if (newAnimation)
+ constructedFromTheme = newAnimation->ConstructFromSkinL(skinId);
+ if (constructedFromTheme && newAnimation->BitmapAnimData()->FrameArray().Count() > 0) {
+ animation->setResourceBased(false);
+ animation->setAnimationObject(newAnimation); //animation takes ownership
+ }
+ CleanupStack::Pop(newAnimation);
+ }
+ //fill-in stored information
+ aknAnimation = animation->animationObject();
+ constructedFromTheme = !animation->isResourceBased();
+ }
+
+ const int currentFrame = QS60StylePrivate::currentAnimationFrame(part);
+ if (constructedFromTheme && aknAnimation && aknAnimation->BitmapAnimData()->FrameArray().Count() > 0) {
+ //Animation was created successfully and contains frames, just fetch current frame
+ if(currentFrame >= aknAnimation->BitmapAnimData()->FrameArray().Count())
+ User::Leave(KErrOverflow);
+ const CBitmapFrameData* frameData = aknAnimation->BitmapAnimData()->FrameArray().At(currentFrame);
+ if (frameData) {
+ animationFrame = frameData->Bitmap();
+ frameMask = frameData->Mask();
+ }
+ } else {
+ //Theme does not contain animation theming, create frames from resource file
+ TInt fallbackGraphicID = -1;
+ fallbackInfo(part, fallbackGraphicID);
+ fallbackGraphicID = fallbackGraphicID + (currentFrame * 2); //skip masks
+ TInt fallbackGraphicsMaskID =
+ (fallbackGraphicID == KErrNotFound) ? KErrNotFound : fallbackGraphicID + 1; //masks are auto-generated as next in mif files
+ if (fallbackGraphicsMaskID != KErrNotFound)
+ fallbackGraphicsMaskID = fallbackGraphicsMaskID + (currentFrame * 2); //skip actual graphics
+
+ //Then draw animation frame
+ AknsUtils::CreateIconL(
+ skinInstance,
+ KAknsIIDDefault, //animation is not themed, lets force fallback graphics
+ animationFrame,
+ frameMask,
+ AknIconUtils::AvkonIconFileName(),
+ fallbackGraphicID ,
+ fallbackGraphicsMaskID);
+ }
+ result = fromFbsBitmap(animationFrame, frameMask, flags, targetSize);
+ if (!constructedFromTheme) {
+ delete animationFrame;
+ animationFrame = 0;
+ delete frameMask;
+ frameMask = 0;
+ }
+ break;
+ }
+ }
+ if (!result)
+ result = QPixmap();
+
+ return result;
+}
+
+QPixmap QS60StyleModeSpecifics::createSkinnedGraphicsLX(QS60StylePrivate::SkinFrameElements frameElement,
+ const QSize &size, QS60StylePrivate::SkinElementFlags flags)
+{
+ // this function can throw both exceptions and leaves. There are no cleanup dependencies between Qt and Symbian parts.
+ if (!size.isValid())
+ return QPixmap();
+
+ const bool rotatedBy90or270 =
+ (flags & (QS60StylePrivate::SF_PointEast | QS60StylePrivate::SF_PointWest));
+ const TSize targetSize =
+ rotatedBy90or270 ? TSize(size.height(), size.width()) : qt_QSize2TSize(size);
+
+ MAknsSkinInstance* skinInstance = AknsUtils::SkinInstance();
+ QPixmap result;
+
+ static const TDisplayMode displayMode = S60->supportsPremultipliedAlpha ? Q_SYMBIAN_ECOLOR16MAP : EColor16MA;
+ static const TInt drawParam = S60->supportsPremultipliedAlpha ? KAknsDrawParamDefault : KAknsDrawParamNoClearUnderImage|KAknsDrawParamRGBOnly;
+
+ CFbsBitmap *frame = new (ELeave) CFbsBitmap(); //offscreen
+ CleanupStack::PushL(frame);
+ User::LeaveIfError(frame->Create(targetSize, displayMode));
+
+ CFbsBitmapDevice* bitmapDev = CFbsBitmapDevice::NewL(frame);
+ CleanupStack::PushL(bitmapDev);
+ CFbsBitGc* bitmapGc = NULL;
+ User::LeaveIfError(bitmapDev->CreateContext(bitmapGc));
+ CleanupStack::PushL(bitmapGc);
+
+ frame->LockHeap();
+ memset(frame->DataAddress(), 0, frame->SizeInPixels().iWidth * frame->SizeInPixels().iHeight * 4); // 4: argb bytes
+ frame->UnlockHeap();
+
+ const TRect outerRect(TPoint(0, 0), targetSize);
+ const TRect innerRect = innerRectFromElement(frameElement, outerRect);
+
+ TAknsItemID frameSkinID, centerSkinID;
+ frameSkinID = centerSkinID = partSpecificThemeId(QS60StylePrivate::m_frameElementsData[frameElement].center);
+ frameIdAndCenterId(frameElement, frameSkinID, centerSkinID);
+
+ TBool drawn = AknsDrawUtils::DrawFrame(
+ skinInstance,
+ *bitmapGc,
+ outerRect,
+ innerRect,
+ frameSkinID,
+ centerSkinID,
+ drawParam );
+
+ if (S60->supportsPremultipliedAlpha) {
+ if (drawn) {
+ result = fromFbsBitmap(frame, NULL, flags, targetSize);
+ } else {
+ // Drawing might fail due to OOM (we can do nothing about that),
+ // or due to skin item not being available.
+ // If the latter occurs, lets try switch to non-release specific items (if available)
+ // and re-try the drawing.
+ frameSkinID = centerSkinID = m_partMap[(int)QS60StylePrivate::m_frameElementsData[frameElement].center].skinID;
+ frameIdAndCenterId(frameElement, frameSkinID, centerSkinID);
+ drawn = AknsDrawUtils::DrawFrame( skinInstance,
+ *bitmapGc, outerRect, innerRect,
+ frameSkinID, centerSkinID,
+ drawParam );
+ // in case drawing fails, even after using default graphics, ignore the error
+ if (drawn)
+ result = fromFbsBitmap(frame, NULL, flags, targetSize);
+ }
+ } else {
+ TDisplayMode maskDepth = EGray256;
+ // Query the skin item for possible frame graphics mask details.
+ if (skinInstance) {
+ CAknsMaskedBitmapItemData* skinMaskedBmp = static_cast<CAknsMaskedBitmapItemData*>(
+ skinInstance->GetCachedItemData(frameSkinID,EAknsITMaskedBitmap));
+ if (skinMaskedBmp && skinMaskedBmp->Mask())
+ maskDepth = skinMaskedBmp->Mask()->DisplayMode();
+ }
+ if (maskDepth != ENone) {
+ CFbsBitmap *frameMask = new (ELeave) CFbsBitmap(); //offscreen
+ CleanupStack::PushL(frameMask);
+ User::LeaveIfError(frameMask->Create(targetSize, maskDepth));
+
+ CFbsBitmapDevice* maskBitmapDevice = CFbsBitmapDevice::NewL(frameMask);
+ CleanupStack::PushL(maskBitmapDevice);
+ CFbsBitGc* maskBitGc = NULL;
+ User::LeaveIfError(maskBitmapDevice->CreateContext(maskBitGc));
+ CleanupStack::PushL(maskBitGc);
+
+ if (drawn) {
+ //ensure that the mask is really transparent
+ maskBitGc->Activate( maskBitmapDevice );
+ maskBitGc->SetPenStyle(CGraphicsContext::ENullPen);
+ maskBitGc->SetBrushStyle(CGraphicsContext::ESolidBrush);
+ maskBitGc->SetBrushColor(KRgbWhite);
+ maskBitGc->Clear();
+ maskBitGc->SetBrushStyle(CGraphicsContext::ENullBrush);
+
+ drawn = AknsDrawUtils::DrawFrame(skinInstance,
+ *maskBitGc, outerRect, innerRect,
+ frameSkinID, centerSkinID,
+ KAknsSDMAlphaOnly |KAknsDrawParamNoClearUnderImage);
+ if (drawn)
+ result = fromFbsBitmap(frame, frameMask, flags, targetSize);
+ }
+ CleanupStack::PopAndDestroy(3, frameMask);
+ }
+ }
+ CleanupStack::PopAndDestroy(3, frame); //frame, bitmapDev, bitmapGc
+ return result;
+}
+
+void QS60StyleModeSpecifics::frameIdAndCenterId(QS60StylePrivate::SkinFrameElements frameElement, TAknsItemID &frameId, TAknsItemID &centerId)
+{
+// There are some major mix-ups in skin declarations for some frames.
+// First, the frames are not declared in sequence.
+// Second, the parts use different major than the frame-master.
+
+ switch(frameElement) {
+ case QS60StylePrivate::SF_ToolTip:
+ if (QSysInfo::s60Version() != QSysInfo::SV_S60_3_1) {
+ centerId.Set(EAknsMajorGeneric, 0x19c2);
+ frameId.Set(EAknsMajorSkin, 0x5300);
+ } else {
+ centerId.Set(KAknsIIDQsnFrPopupCenter);
+ frameId.iMinor = centerId.iMinor - 9;
+ }
+ break;
+ case QS60StylePrivate::SF_ToolBar:
+ if (QSysInfo::s60Version() == QSysInfo::SV_S60_3_1 ||
+ QSysInfo::s60Version() == QSysInfo::SV_S60_3_2) {
+ centerId.Set(KAknsIIDQsnFrPopupCenterSubmenu);
+ frameId.Set(KAknsIIDQsnFrPopupSub);
+ }
+ break;
+ case QS60StylePrivate::SF_PopupBackground:
+ centerId.Set(KAknsIIDQsnFrPopupCenterSubmenu);
+ frameId.Set(KAknsIIDQsnFrPopupSub);
+ break;
+ case QS60StylePrivate::SF_PanelBackground:
+ // remove center piece for panel graphics, so that only border is drawn
+ centerId.Set(KAknsIIDNone);
+ frameId.Set(KAknsIIDQsnFrSetOpt);
+ break;
+ default:
+ // center should be correct here
+ frameId.iMinor = centerId.iMinor - 9;
+ break;
+ }
+}
+
+TRect QS60StyleModeSpecifics::innerRectFromElement(QS60StylePrivate::SkinFrameElements frameElement, const TRect &outerRect)
+{
+ TInt widthShrink = QS60StylePrivate::pixelMetric(PM_FrameCornerWidth);
+ TInt heightShrink = QS60StylePrivate::pixelMetric(PM_FrameCornerHeight);
+ switch(frameElement) {
+ case QS60StylePrivate::SF_PanelBackground:
+ // panel should have slightly slimmer border to enable thin line of background graphics between closest component
+ widthShrink = widthShrink - 2;
+ heightShrink = heightShrink - 2;
+ break;
+ case QS60StylePrivate::SF_ToolTip:
+ widthShrink = widthShrink >> 1;
+ heightShrink = heightShrink >> 1;
+ break;
+ case QS60StylePrivate::SF_ListHighlight:
+ //In Sym^3 devices highlights are less blocky
+ if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0) {
+ widthShrink += 2;
+ heightShrink += 2;
+ } else {
+ widthShrink -= 2;
+ heightShrink -= 2;
+ }
+ break;
+ case QS60StylePrivate::SF_PopupBackground:
+ widthShrink = widthShrink + 5;
+ heightShrink = heightShrink + 5;
+ break;
+ default:
+ break;
+ }
+ TRect innerRect(outerRect);
+ innerRect.Shrink(widthShrink, heightShrink);
+ return innerRect;
+}
+
+bool QS60StyleModeSpecifics::checkSupport(const int supportedRelease)
+{
+ const QSysInfo::S60Version currentRelease = QSysInfo::s60Version();
+ return ( (currentRelease == QSysInfo::SV_S60_3_1 && supportedRelease & ES60_3_1) ||
+ (currentRelease == QSysInfo::SV_S60_3_2 && supportedRelease & ES60_3_2) ||
+ (currentRelease == QSysInfo::SV_S60_5_0 && supportedRelease & ES60_5_0) ||
+ (currentRelease == QSysInfo::SV_S60_5_1 && supportedRelease & ES60_5_1) ||
+ (currentRelease == QSysInfo::SV_S60_5_2 && supportedRelease & ES60_5_2) ||
+ (currentRelease == QSysInfo::SV_S60_5_3 && supportedRelease & ES60_5_3) );
+}
+
+TAknsItemID QS60StyleModeSpecifics::partSpecificThemeId(int part)
+{
+ TAknsItemID newSkinId;
+ if (!checkSupport(m_partMap[(int)part].supportInfo))
+ newSkinId.Set(m_partMap[(int)part].newMajorSkinId, m_partMap[(int)part].newMinorSkinId);
+ else
+ newSkinId.Set(m_partMap[(int)part].skinID);
+ return newSkinId;
+}
+
+QFont QS60StylePrivate::s60Font_specific(
+ QS60StyleEnums::FontCategories fontCategory,
+ int pointSize, bool resolveFontSize)
+{
+ Q_UNUSED(resolveFontSize);
+
+ TAknFontCategory aknFontCategory = EAknFontCategoryUndefined;
+ switch (fontCategory) {
+ case QS60StyleEnums::FC_Primary:
+ aknFontCategory = EAknFontCategoryPrimary;
+ break;
+ case QS60StyleEnums::FC_Secondary:
+ aknFontCategory = EAknFontCategorySecondary;
+ break;
+ case QS60StyleEnums::FC_Title:
+ aknFontCategory = EAknFontCategoryTitle;
+ break;
+ case QS60StyleEnums::FC_PrimarySmall:
+ aknFontCategory = EAknFontCategoryPrimarySmall;
+ break;
+ case QS60StyleEnums::FC_Digital:
+ aknFontCategory = EAknFontCategoryDigital;
+ break;
+ case QS60StyleEnums::FC_Undefined:
+ default:
+ break;
+ }
+
+ // Create AVKON font according the given parameters
+ CWsScreenDevice* dev = CCoeEnv::Static()->ScreenDevice();
+ TAknFontSpecification spec(aknFontCategory, TFontSpec(), NULL);
+ if (pointSize > 0) {
+ const TInt pixelSize = dev->VerticalTwipsToPixels(pointSize * KTwipsPerPoint);
+ spec.SetTextPaneHeight(pixelSize + 4); // TODO: Is 4 a reasonable top+bottom margin?
+ }
+
+ QFont result;
+ TRAPD( error, QT_TRYCATCH_LEAVING({
+ const CAknLayoutFont* aknFont =
+ AknFontAccess::CreateLayoutFontFromSpecificationL(*dev, spec);
+
+ result = qt_TFontSpec2QFontL(aknFont->DoFontSpecInTwips());
+ if (result.pointSize() != pointSize)
+ result.setPointSize(pointSize); // Correct the font size returned by CreateLayoutFontFromSpecificationL()
+
+ delete aknFont;
+ }));
+ if (error) result = QFont();
+ return result;
+}
+
+void QS60StylePrivate::setActiveLayout()
+{
+ const QSize activeScreenSize(screenSize());
+ int activeLayoutIndex = -1;
+ const short screenHeight = (short)activeScreenSize.height();
+ const short screenWidth = (short)activeScreenSize.width();
+ for (int i=0; i<m_numberOfLayouts; i++) {
+ if (screenHeight==m_layoutHeaders[i].height &&
+ screenWidth==m_layoutHeaders[i].width) {
+ activeLayoutIndex = i;
+ break;
+ }
+ }
+
+ //not found, lets try with either of dimensions
+ if (activeLayoutIndex==-1){
+ const QSysInfo::S60Version currentRelease = QSysInfo::s60Version();
+ const bool landscape = screenHeight < screenWidth;
+
+ activeLayoutIndex = (currentRelease == QSysInfo::SV_S60_3_1 || currentRelease == QSysInfo::SV_S60_3_2) ? 0 : 2;
+ activeLayoutIndex += (!landscape) ? 1 : 0;
+ }
+
+ setCurrentLayout(activeLayoutIndex);
+}
+
+Q_GLOBAL_STATIC(QList<QS60StyleAnimation *>, m_animations)
+
+QS60StylePrivate::QS60StylePrivate()
+{
+ //Animation defaults need to be created when style is instantiated
+ QS60StyleAnimation* progressBarAnimation = new QS60StyleAnimation(QS60StyleEnums::SP_QgnGrafBarWaitAnim, 7, 100);
+ m_animations()->append(progressBarAnimation);
+ // No need to set active layout, if dynamic metrics API is available
+ setActiveLayout();
+}
+
+void QS60StylePrivate::removeAnimations()
+{
+ //currently only one animation in the list.
+ m_animations()->removeFirst();
+}
+
+QColor QS60StylePrivate::s60Color(QS60StyleEnums::ColorLists list,
+ int index, const QStyleOption *option)
+{
+ static const TAknsItemID *idMap[] = {
+ &KAknsIIDQsnHighlightColors,
+ &KAknsIIDQsnIconColors,
+ &KAknsIIDQsnLineColors,
+ &KAknsIIDQsnOtherColors,
+ &KAknsIIDQsnParentColors,
+ &KAknsIIDQsnTextColors
+ };
+ Q_ASSERT((int)list < (int)sizeof(idMap)/sizeof(idMap[0]));
+ const QColor color = QS60StyleModeSpecifics::colorValue(*idMap[(int) list], index - 1);
+ return option ? QS60StylePrivate::stateColor(color, option) : color;
+}
+
+// In some cases, the AVKON UI themegraphic is already in 'disabled state'.
+// If so, return true for these parts.
+bool QS60StyleModeSpecifics::disabledPartGraphic(QS60StyleEnums::SkinParts &part)
+{
+ bool disabledGraphic = false;
+ switch(part){
+ // inactive button graphics are available from 5.0 onwards
+ case QS60StyleEnums::SP_QsnFrButtonCornerTlInactive:
+ case QS60StyleEnums::SP_QsnFrButtonCornerTrInactive:
+ case QS60StyleEnums::SP_QsnFrButtonCornerBlInactive:
+ case QS60StyleEnums::SP_QsnFrButtonCornerBrInactive:
+ case QS60StyleEnums::SP_QsnFrButtonSideTInactive:
+ case QS60StyleEnums::SP_QsnFrButtonSideBInactive:
+ case QS60StyleEnums::SP_QsnFrButtonSideLInactive:
+ case QS60StyleEnums::SP_QsnFrButtonSideRInactive:
+ case QS60StyleEnums::SP_QsnFrButtonCenterInactive:
+ if (!(QSysInfo::s60Version()==QSysInfo::SV_S60_3_1 ||
+ QSysInfo::s60Version()==QSysInfo::SV_S60_3_2))
+ disabledGraphic = true;
+ break;
+ default:
+ break;
+ }
+ return disabledGraphic;
+}
+
+// In some cases, the AVKON UI themegraphic is already in 'disabled state'.
+// If so, return true for these frames.
+bool QS60StyleModeSpecifics::disabledFrameGraphic(QS60StylePrivate::SkinFrameElements &frame)
+{
+ bool disabledGraphic = false;
+ switch(frame){
+ // inactive button graphics are available from 5.0 onwards
+ case QS60StylePrivate::SF_ButtonInactive:
+ if (!(QSysInfo::s60Version()==QSysInfo::SV_S60_3_1 ||
+ QSysInfo::s60Version()==QSysInfo::SV_S60_3_2))
+ disabledGraphic = true;
+ break;
+ default:
+ break;
+ }
+ return disabledGraphic;
+}
+
+QPixmap QS60StyleModeSpecifics::generateMissingThemeGraphic(QS60StyleEnums::SkinParts &part,
+ const QSize &size, QS60StylePrivate::SkinElementFlags flags)
+{
+ if (!QS60StylePrivate::isTouchSupported())
+ return QPixmap();
+
+ QS60StyleEnums::SkinParts updatedPart = part;
+ switch(part){
+ // AVKON UI has a abnormal handling for scrollbar graphics. It is possible that the root
+ // skin does not contain mandatory graphics for scrollbar pressed states. Therefore, AVKON UI
+ // creates dynamically these graphics by modifying the normal state scrollbar graphics slightly.
+ // S60Style needs to work similarly. Therefore if skingraphics call provides to be a miss
+ // (i.e. result is not valid), style needs to draw normal graphics instead and apply some
+ // modifications (similar to generatedIconPixmap()) to the result.
+ case QS60StyleEnums::SP_QsnCpScrollHandleBottomPressed:
+ updatedPart = QS60StyleEnums::SP_QsnCpScrollHandleBottom;
+ break;
+ case QS60StyleEnums::SP_QsnCpScrollHandleMiddlePressed:
+ updatedPart = QS60StyleEnums::SP_QsnCpScrollHandleMiddle;
+ break;
+ case QS60StyleEnums::SP_QsnCpScrollHandleTopPressed:
+ updatedPart = QS60StyleEnums::SP_QsnCpScrollHandleTop;
+ break;
+ default:
+ break;
+ }
+ if (part==updatedPart) {
+ return QPixmap();
+ } else {
+ QPixmap result = skinnedGraphics(updatedPart, size, flags);
+ QStyleOption opt;
+ QPalette *themePalette = QS60StylePrivate::themePalette();
+ if (themePalette)
+ opt.palette = *themePalette;
+
+ // For now, always generate new icon based on "selected". In the future possibly, expand
+ // this to consist other possibilities as well.
+ result = QApplication::style()->generatedIconPixmap(QIcon::Selected, result, &opt);
+ return result;
+ }
+}
+
+QPixmap QS60StylePrivate::part(QS60StyleEnums::SkinParts part,
+ const QSize &size, QPainter *painter, SkinElementFlags flags)
+{
+ QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock);
+
+ QPixmap result = (flags & SF_ColorSkinned)?
+ QS60StyleModeSpecifics::colorSkinnedGraphics(part, size, painter, flags)
+ : QS60StyleModeSpecifics::skinnedGraphics(part, size, flags);
+
+ lock.relock();
+
+ if (flags & SF_StateDisabled && !QS60StyleModeSpecifics::disabledPartGraphic(part)) {
+ QStyleOption opt;
+ QPalette *themePalette = QS60StylePrivate::themePalette();
+ if (themePalette)
+ opt.palette = *themePalette;
+ result = QApplication::style()->generatedIconPixmap(QIcon::Disabled, result, &opt);
+ }
+
+ if (!result)
+ result = QS60StyleModeSpecifics::generateMissingThemeGraphic(part, size, flags);
+
+ return result;
+}
+
+QPixmap QS60StylePrivate::frame(SkinFrameElements frame, const QSize &size, SkinElementFlags flags)
+{
+ QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock);
+ QPixmap result = QS60StyleModeSpecifics::skinnedGraphics(frame, size, flags);
+ lock.relock();
+
+ if (flags & SF_StateDisabled && !QS60StyleModeSpecifics::disabledFrameGraphic(frame)) {
+ QStyleOption opt;
+ QPalette *themePalette = QS60StylePrivate::themePalette();
+ if (themePalette)
+ opt.palette = *themePalette;
+ result = QApplication::style()->generatedIconPixmap(QIcon::Disabled, result, &opt);
+ }
+ return result;
+}
+
+QPixmap QS60StylePrivate::backgroundTexture(bool skipCreation)
+{
+ bool createNewBackground = false;
+ TRect applicationRect = (static_cast<CEikAppUi*>(S60->appUi())->ApplicationRect());
+ if (!m_background) {
+ createNewBackground = true;
+ } else {
+ //if background brush does not match screensize, re-create it
+ if (m_background->width() != applicationRect.Width() ||
+ m_background->height() != applicationRect.Height()) {
+ delete m_background;
+ m_background = 0;
+ createNewBackground = true;
+ }
+ }
+
+ if (createNewBackground && !skipCreation) {
+ QPixmap background = part(QS60StyleEnums::SP_QsnBgScreen,
+ QSize(applicationRect.Width(), applicationRect.Height()), 0, SkinElementFlags());
+ m_background = new QPixmap(background);
+
+ // Notify all widgets that palette is updated with the actual background texture.
+ QPalette pal = QApplication::palette();
+ pal.setBrush(QPalette::Window, *m_background);
+ QApplication::setPalette(pal);
+ setThemePaletteHash(&pal);
+ storeThemePalette(&pal);
+ foreach (QWidget *widget, QApplication::allWidgets()){
+ QEvent e(QEvent::PaletteChange);
+ QApplication::sendEvent(widget, &e);
+ setThemePalette(widget);
+ widget->ensurePolished();
+ }
+ }
+ if (!m_background)
+ return QPixmap();
+ return *m_background;
+}
+
+QSize QS60StylePrivate::screenSize()
+{
+ return QSize(S60->screenWidthInPixels, S60->screenHeightInPixels);
+}
+
+QS60Style::QS60Style()
+ : QCommonStyle(*new QS60StylePrivate)
+{
+}
+
+#ifdef Q_WS_S60
+void QS60StylePrivate::handleDynamicLayoutVariantSwitch()
+{
+ clearCaches(QS60StylePrivate::CC_LayoutChange);
+ setBackgroundTexture(qApp);
+ setActiveLayout();
+ foreach (QWidget *widget, QApplication::allWidgets())
+ widget->ensurePolished();
+}
+
+void QS60StylePrivate::handleSkinChange()
+{
+ clearCaches(QS60StylePrivate::CC_ThemeChange);
+ setThemePalette(qApp);
+ foreach (QWidget *topLevelWidget, QApplication::allWidgets()){
+ QEvent e(QEvent::StyleChange);
+ QApplication::sendEvent(topLevelWidget, &e);
+ setThemePalette(topLevelWidget);
+ topLevelWidget->ensurePolished();
+ }
+#ifndef QT_NO_PROGRESSBAR
+ //re-start animation timer
+ stopAnimation(QS60StyleEnums::SP_QgnGrafBarWaitAnim); //todo: once we have more animations, we could say "stop all running ones"
+ startAnimation(QS60StyleEnums::SP_QgnGrafBarWaitAnim); //and "re-start all previously running ones"
+#endif
+}
+
+int QS60StylePrivate::currentAnimationFrame(QS60StyleEnums::SkinParts part)
+{
+ QS60StyleAnimation *animation = animationDefinition(part);
+ // todo: looping could be done in QS60Style::timerEvent
+ if (animation->frameCount() == animation->currentFrame())
+ animation->setCurrentFrame(0);
+ return animation->currentFrame();
+}
+
+QS60StyleAnimation* QS60StylePrivate::animationDefinition(QS60StyleEnums::SkinParts part)
+{
+ int i = 0;
+ const int animationsCount = m_animations()->isEmpty() ? 0 : m_animations()->count();
+ for(; i < animationsCount; i++) {
+ if (part == m_animations()->at(i)->animationId())
+ break;
+ }
+ return m_animations()->at(i);
+}
+
+void QS60StylePrivate::startAnimation(QS60StyleEnums::SkinParts animationPart)
+{
+ Q_Q(QS60Style);
+
+ //Query animation data from theme and store values to local struct.
+ QVariant themeAnimationDataVariant = QS60StyleModeSpecifics::themeDefinition(
+ QS60StyleEnums::TD_AnimationData, animationPart);
+ QList<QVariant> themeAnimationData = themeAnimationDataVariant.toList();
+
+ QS60StyleAnimation *animation = QS60StylePrivate::animationDefinition(animationPart);
+ if (animation) {
+ if (themeAnimationData.at(QS60StyleEnums::AD_Interval).toInt() != 0)
+ animation->setInterval(themeAnimationData.at(QS60StyleEnums::AD_Interval).toInt());
+
+ if (themeAnimationData.at(QS60StyleEnums::AD_NumberOfFrames).toInt() != 0)
+ animation->setFrameCount(themeAnimationData.at(QS60StyleEnums::AD_NumberOfFrames).toInt());
+
+ //todo: playmode is ignored for now, since it seems to return invalid data on some themes
+ //lets use the table values for play mode
+
+ animation->setCurrentFrame(0); //always initialize
+ const int timerId = q->startTimer(animation->interval());
+ animation->setTimerId(timerId);
+ }
+}
+
+void QS60StylePrivate::stopAnimation(QS60StyleEnums::SkinParts animationPart)
+{
+ Q_Q(QS60Style);
+
+ QS60StyleAnimation *animation = QS60StylePrivate::animationDefinition(animationPart);
+ if (animation) {
+ animation->setCurrentFrame(0);
+ if (animation->timerId() != 0) {
+ q->killTimer(animation->timerId());
+ animation->setTimerId(0);
+ }
+ animation->resetToDefaults();
+ }
+}
+
+QVariant QS60StyleModeSpecifics::themeDefinition(
+ QS60StyleEnums::ThemeDefinitions definition, QS60StyleEnums::SkinParts part)
+{
+ MAknsSkinInstance* skinInstance = AknsUtils::SkinInstance();
+
+ Q_ASSERT(skinInstance);
+
+ switch(definition) {
+ //Animation definitions
+ case QS60StyleEnums::TD_AnimationData:
+ {
+ CAknsBmpAnimItemData *animationData;
+ TAknsItemID animationSkinId = partSpecificThemeId(part);
+ QList<QVariant> list;
+
+ TRAPD( error, QT_TRYCATCH_LEAVING(
+ animationData = static_cast<CAknsBmpAnimItemData*>(skinInstance->CreateUncachedItemDataL(
+ animationSkinId, EAknsITBmpAnim))));
+ if (error)
+ return list;
+
+ if (animationData) {
+ list.append((int)animationData->FrameInterval());
+ list.append((int)animationData->NumberOfImages());
+
+ QS60StyleEnums::AnimationMode playMode;
+ switch(animationData->PlayMode()) {
+ case CBitmapAnimClientData::EPlay:
+ playMode = QS60StyleEnums::AM_PlayOnce;
+ break;
+ case CBitmapAnimClientData::ECycle:
+ playMode = QS60StyleEnums::AM_Looping;
+ break;
+ case CBitmapAnimClientData::EBounce:
+ playMode = QS60StyleEnums::AM_Bounce;
+ break;
+ default:
+ break;
+ }
+ list.append(QVariant((int)playMode));
+ delete animationData;
+ } else {
+ list.append(0);
+ list.append(0);
+ }
+ return list;
+ }
+ break;
+ default:
+ break;
+ }
+ return QVariant();
+}
+
+#endif // Q_WS_S60
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_STYLE_S60 || QT_PLUGIN
diff --git a/src/gui/styles/qs60style_simulated.cpp b/src/widgets/styles/qs60style_simulated.cpp
index ca02cdf5e1..ca02cdf5e1 100644
--- a/src/gui/styles/qs60style_simulated.cpp
+++ b/src/widgets/styles/qs60style_simulated.cpp
diff --git a/src/gui/styles/qs60style_stub.cpp b/src/widgets/styles/qs60style_stub.cpp
index ce2f7743ad..ce2f7743ad 100644
--- a/src/gui/styles/qs60style_stub.cpp
+++ b/src/widgets/styles/qs60style_stub.cpp
diff --git a/src/widgets/styles/qstyle.cpp b/src/widgets/styles/qstyle.cpp
new file mode 100644
index 0000000000..c6e4b488c1
--- /dev/null
+++ b/src/widgets/styles/qstyle.cpp
@@ -0,0 +1,2459 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qstyle.h"
+#include "qapplication.h"
+#include "qpainter.h"
+#include "qwidget.h"
+#include "qbitmap.h"
+#include "qpixmapcache.h"
+#include "qstyleoption.h"
+#include "private/qstyle_p.h"
+#include "private/qguiapplication_p.h"
+#ifndef QT_NO_DEBUG
+#include "qdebug.h"
+#endif
+
+#ifdef Q_WS_X11
+#include <qx11info_x11.h>
+#endif
+
+#include <limits.h>
+
+QT_BEGIN_NAMESPACE
+
+static const int MaxBits = 8 * sizeof(QSizePolicy::ControlType);
+
+static int unpackControlTypes(QSizePolicy::ControlTypes controls, QSizePolicy::ControlType *array)
+{
+ if (!controls)
+ return 0;
+
+ // optimization: exactly one bit is set
+ if ((controls & (controls - 1)) == 0) {
+ array[0] = QSizePolicy::ControlType(uint(controls));
+ return 1;
+ }
+
+ int count = 0;
+ for (int i = 0; i < MaxBits; ++i) {
+ if (uint bit = (controls & (0x1 << i)))
+ array[count++] = QSizePolicy::ControlType(bit);
+ }
+ return count;
+}
+
+/*!
+ \class QStyle
+ \brief The QStyle class is an abstract base class that encapsulates the look and feel of a GUI.
+
+ \ingroup appearance
+
+ Qt contains a set of QStyle subclasses that emulate the styles of
+ the different platforms supported by Qt (QWindowsStyle,
+ QMacStyle, QMotifStyle, etc.). By default, these styles are built
+ into the QtGui library. Styles can also be made available as
+ plugins.
+
+ Qt's built-in widgets use QStyle to perform nearly all of their
+ drawing, ensuring that they look exactly like the equivalent
+ native widgets. The diagram below shows a QComboBox in eight
+ different styles.
+
+ \img qstyle-comboboxes.png Eight combo boxes
+
+ Topics:
+
+ \tableofcontents
+
+ \section1 Setting a Style
+
+ The style of the entire application can be set using the
+ QApplication::setStyle() function. It can also be specified by the
+ user of the application, using the \c -style command-line option:
+
+ \snippet doc/src/snippets/code/src_gui_styles_qstyle.cpp 0
+
+ If no style is specified, Qt will choose the most appropriate
+ style for the user's platform or desktop environment.
+
+ A style can also be set on an individual widget using the
+ QWidget::setStyle() function.
+
+ \section1 Developing Style-Aware Custom Widgets
+
+ If you are developing custom widgets and want them to look good on
+ all platforms, you can use QStyle functions to perform parts of
+ the widget drawing, such as drawItemText(), drawItemPixmap(),
+ drawPrimitive(), drawControl(), and drawComplexControl().
+
+ Most QStyle draw functions take four arguments:
+ \list
+ \o an enum value specifying which graphical element to draw
+ \o a QStyleOption specifying how and where to render that element
+ \o a QPainter that should be used to draw the element
+ \o a QWidget on which the drawing is performed (optional)
+ \endlist
+
+ For example, if you want to draw a focus rectangle on your
+ widget, you can write:
+
+ \snippet doc/src/snippets/styles/styles.cpp 1
+
+ QStyle gets all the information it needs to render the graphical
+ element from QStyleOption. The widget is passed as the last
+ argument in case the style needs it to perform special effects
+ (such as animated default buttons on Mac OS X), but it isn't
+ mandatory. In fact, you can use QStyle to draw on any paint
+ device, not just widgets, by setting the QPainter properly.
+
+ QStyleOption has various subclasses for the various types of
+ graphical elements that can be drawn. For example,
+ PE_FrameFocusRect expects a QStyleOptionFocusRect argument.
+
+ To ensure that drawing operations are as fast as possible,
+ QStyleOption and its subclasses have public data members. See the
+ QStyleOption class documentation for details on how to use it.
+
+ For convenience, Qt provides the QStylePainter class, which
+ combines a QStyle, a QPainter, and a QWidget. This makes it
+ possible to write
+
+ \snippet doc/src/snippets/styles/styles.cpp 5
+ \dots
+ \snippet doc/src/snippets/styles/styles.cpp 7
+
+ instead of
+
+ \snippet doc/src/snippets/styles/styles.cpp 2
+ \dots
+ \snippet doc/src/snippets/styles/styles.cpp 3
+
+ \section1 Creating a Custom Style
+
+ You can create a custom look and feel for your application by
+ creating a custom style. There are two approaches to creating a
+ custom style. In the static approach, you either choose an
+ existing QStyle class, subclass it, and reimplement virtual
+ functions to provide the custom behavior, or you create an entire
+ QStyle class from scratch. In the dynamic approach, you modify the
+ behavior of your system style at runtime. The static approach is
+ described below. The dynamic approach is described in QProxyStyle.
+
+ The first step in the static approach is to pick one of the styles
+ provided by Qt from which you will build your custom style. Your
+ choice of QStyle class will depend on which style resembles your
+ desired style the most. The most general class that you can use as
+ a base is QCommonStyle (not QStyle). This is because Qt requires
+ its styles to be \l{QCommonStyle}s.
+
+ Depending on which parts of the base style you want to change,
+ you must reimplement the functions that are used to draw those
+ parts of the interface. To illustrate this, we will modify the
+ look of the spin box arrows drawn by QWindowsStyle. The arrows
+ are \e{primitive elements} that are drawn by the drawPrimitive()
+ function, so we need to reimplement that function. We need the
+ following class declaration:
+
+ \snippet doc/src/snippets/customstyle/customstyle.h 0
+
+ To draw its up and down arrows, QSpinBox uses the
+ PE_IndicatorSpinUp and PE_IndicatorSpinDown primitive elements.
+ Here's how to reimplement the drawPrimitive() function to draw
+ them differently:
+
+ \snippet doc/src/snippets/customstyle/customstyle.cpp 2
+ \snippet doc/src/snippets/customstyle/customstyle.cpp 3
+ \snippet doc/src/snippets/customstyle/customstyle.cpp 4
+
+ Notice that we don't use the \c widget argument, except to pass it
+ on to the QWindowStyle::drawPrimitive() function. As mentioned
+ earlier, the information about what is to be drawn and how it
+ should be drawn is specified by a QStyleOption object, so there is
+ no need to ask the widget.
+
+ If you need to use the \c widget argument to obtain additional
+ information, be careful to ensure that it isn't 0 and that it is
+ of the correct type before using it. For example:
+
+ \snippet doc/src/snippets/customstyle/customstyle.cpp 0
+ \dots
+ \snippet doc/src/snippets/customstyle/customstyle.cpp 1
+
+ When implementing a custom style, you cannot assume that the
+ widget is a QSpinBox just because the enum value is called
+ PE_IndicatorSpinUp or PE_IndicatorSpinDown.
+
+ The documentation for the \l{widgets/styles}{Styles} example
+ covers this topic in more detail.
+
+ \warning Qt style sheets are currently not supported for custom QStyle
+ subclasses. We plan to address this in some future release.
+
+
+ \section1 Using a Custom Style
+
+ There are several ways of using a custom style in a Qt
+ application. The simplest way is to pass the custom style to the
+ QApplication::setStyle() static function before creating the
+ QApplication object:
+
+ \snippet snippets/customstyle/main.cpp using a custom style
+
+ You can call QApplication::setStyle() at any time, but by calling
+ it before the constructor, you ensure that the user's preference,
+ set using the \c -style command-line option, is respected.
+
+ You may want to make your custom style available for use in other
+ applications, which may not be yours and hence not available for
+ you to recompile. The Qt Plugin system makes it possible to create
+ styles as plugins. Styles created as plugins are loaded as shared
+ objects at runtime by Qt itself. Please refer to the \link
+ plugins-howto.html Qt Plugin\endlink documentation for more
+ information on how to go about creating a style plugin.
+
+ Compile your plugin and put it into Qt's \c plugins/styles
+ directory. We now have a pluggable style that Qt can load
+ automatically. To use your new style with existing applications,
+ simply start the application with the following argument:
+
+ \snippet doc/src/snippets/code/src_gui_styles_qstyle.cpp 1
+
+ The application will use the look and feel from the custom style you
+ implemented.
+
+ \section1 Right-to-Left Desktops
+
+ Languages written from right to left (such as Arabic and Hebrew)
+ usually also mirror the whole layout of widgets, and require the
+ light to come from the screen's top-right corner instead of
+ top-left.
+
+ If you create a custom style, you should take special care when
+ drawing asymmetric elements to make sure that they also look
+ correct in a mirrored layout. An easy way to test your styles is
+ to run applications with the \c -reverse command-line option or
+ to call QApplication::setLayoutDirection() in your \c main()
+ function.
+
+ Here are some things to keep in mind when making a style work well in a
+ right-to-left environment:
+
+ \list
+ \o subControlRect() and subElementRect() return rectangles in screen coordinates
+ \o QStyleOption::direction indicates in which direction the item should be drawn in
+ \o If a style is not right-to-left aware it will display items as if it were left-to-right
+ \o visualRect(), visualPos(), and visualAlignment() are helpful functions that will
+ translate from logical to screen representations.
+ \o alignedRect() will return a logical rect aligned for the current direction
+ \endlist
+
+ \section1 Styles in Item Views
+
+ The painting of items in views is performed by a delegate. Qt's
+ default delegate, QStyledItemDelegate, is also used for for calculating bounding
+ rectangles of items, and their sub-elements for the various kind
+ of item \l{Qt::ItemDataRole}{data roles}
+ QStyledItemDelegate supports. See the QStyledItemDelegate class
+ description to find out which datatypes and roles are supported. You
+ can read more about item data roles in \l{Model/View Programming}.
+
+ When QStyledItemDelegate paints its items, it draws
+ CE_ItemViewItem, and calculates their size with CT_ItemViewItem.
+ Note also that it uses SE_ItemViewItemText to set the size of
+ editors. When implementing a style to customize drawing of item
+ views, you need to check the implementation of QCommonStyle (and
+ any other subclasses from which your style
+ inherits). This way, you find out which and how
+ other style elements are painted, and you can then reimplement the
+ painting of elements that should be drawn differently.
+
+ We include a small example where we customize the drawing of item
+ backgrounds.
+
+ \snippet doc/src/snippets/customviewstyle.cpp 0
+
+ The primitive element PE_PanelItemViewItem is responsible for
+ painting the background of items, and is called from
+ \l{QCommonStyle}'s implementation of CE_ItemViewItem.
+
+ To add support for drawing of new datatypes and item data roles,
+ it is necessary to create a custom delegate. But if you only
+ need to support the datatypes implemented by the default
+ delegate, a custom style does not need an accompanying
+ delegate. The QStyledItemDelegate class description gives more
+ information on custom delegates.
+
+ The drawing of item view headers is also done by the style, giving
+ control over size of header items and row and column sizes.
+
+ \sa QStyleOption, QStylePainter, {Styles Example},
+ {Styles and Style Aware Widgets}, QStyledItemDelegate
+*/
+
+/*!
+ Constructs a style object.
+*/
+QStyle::QStyle()
+ : QObject(*new QStylePrivate)
+{
+ Q_D(QStyle);
+ d->proxyStyle = this;
+}
+
+/*!
+ \internal
+
+ Constructs a style object.
+*/
+QStyle::QStyle(QStylePrivate &dd)
+ : QObject(dd)
+{
+ Q_D(QStyle);
+ d->proxyStyle = this;
+}
+
+/*!
+ Destroys the style object.
+*/
+QStyle::~QStyle()
+{
+}
+
+/*!
+ Initializes the appearance of the given \a widget.
+
+ This function is called for every widget at some point after it
+ has been fully created but just \e before it is shown for the very
+ first time.
+
+ Note that the default implementation does nothing. Reasonable
+ actions in this function might be to call the
+ QWidget::setBackgroundMode() function for the widget. Do not use
+ the function to set, for example, the geometry. Reimplementing
+ this function provides a back-door through which the appearance
+ of a widget can be changed, but with Qt's style engine it is
+ rarely necessary to implement this function; reimplement
+ drawItemPixmap(), drawItemText(), drawPrimitive(), etc. instead.
+
+ The QWidget::inherits() function may provide enough information to
+ allow class-specific customizations. But because new QStyle
+ subclasses are expected to work reasonably with all current and \e
+ future widgets, limited use of hard-coded customization is
+ recommended.
+
+ \sa unpolish()
+*/
+void QStyle::polish(QWidget * /* widget */)
+{
+}
+
+/*!
+ Uninitialize the given \a{widget}'s appearance.
+
+ This function is the counterpart to polish(). It is called for
+ every polished widget whenever the style is dynamically changed;
+ the former style has to unpolish its settings before the new style
+ can polish them again.
+
+ Note that unpolish() will only be called if the widget is
+ destroyed. This can cause problems in some cases, e.g, if you
+ remove a widget from the UI, cache it, and then reinsert it after
+ the style has changed; some of Qt's classes cache their widgets.
+
+ \sa polish()
+*/
+void QStyle::unpolish(QWidget * /* widget */)
+{
+}
+
+/*!
+ \fn void QStyle::polish(QApplication * application)
+ \overload
+
+ Late initialization of the given \a application object.
+*/
+void QStyle::polish(QApplication * /* app */)
+{
+}
+
+/*!
+ \fn void QStyle::unpolish(QApplication * application)
+ \overload
+
+ Uninitialize the given \a application.
+*/
+void QStyle::unpolish(QApplication * /* app */)
+{
+}
+
+/*!
+ \fn void QStyle::polish(QPalette & palette)
+ \overload
+
+ Changes the \a palette according to style specific requirements
+ for color palettes (if any).
+
+ \sa QPalette, QApplication::setPalette()
+*/
+void QStyle::polish(QPalette & /* pal */)
+{
+}
+
+/*!
+ \fn QRect QStyle::itemTextRect(const QFontMetrics &metrics, const QRect &rectangle, int alignment, bool enabled, const QString &text) const
+
+ Returns the area within the given \a rectangle in which to draw
+ the provided \a text according to the specified font \a metrics
+ and \a alignment. The \a enabled parameter indicates whether or
+ not the associated item is enabled.
+
+ If the given \a rectangle is larger than the area needed to render
+ the \a text, the rectangle that is returned will be offset within
+ \a rectangle according to the specified \a alignment. For
+ example, if \a alignment is Qt::AlignCenter, the returned
+ rectangle will be centered within \a rectangle. If the given \a
+ rectangle is smaller than the area needed, the returned rectangle
+ will be the smallest rectangle large enough to render the \a text.
+
+ \sa Qt::Alignment
+*/
+QRect QStyle::itemTextRect(const QFontMetrics &metrics, const QRect &rect, int alignment, bool enabled,
+ const QString &text) const
+{
+ QRect result;
+ int x, y, w, h;
+ rect.getRect(&x, &y, &w, &h);
+ if (!text.isEmpty()) {
+ result = metrics.boundingRect(x, y, w, h, alignment, text);
+ if (!enabled && proxy()->styleHint(SH_EtchDisabledText)) {
+ result.setWidth(result.width()+1);
+ result.setHeight(result.height()+1);
+ }
+ } else {
+ result = QRect(x, y, w, h);
+ }
+ return result;
+}
+
+/*!
+ \fn QRect QStyle::itemPixmapRect(const QRect &rectangle, int alignment, const QPixmap &pixmap) const
+
+ Returns the area within the given \a rectangle in which to draw
+ the specified \a pixmap according to the defined \a alignment.
+*/
+QRect QStyle::itemPixmapRect(const QRect &rect, int alignment, const QPixmap &pixmap) const
+{
+ QRect result;
+ int x, y, w, h;
+ rect.getRect(&x, &y, &w, &h);
+ if ((alignment & Qt::AlignVCenter) == Qt::AlignVCenter)
+ y += h/2 - pixmap.height()/2;
+ else if ((alignment & Qt::AlignBottom) == Qt::AlignBottom)
+ y += h - pixmap.height();
+ if ((alignment & Qt::AlignRight) == Qt::AlignRight)
+ x += w - pixmap.width();
+ else if ((alignment & Qt::AlignHCenter) == Qt::AlignHCenter)
+ x += w/2 - pixmap.width()/2;
+ else if ((alignment & Qt::AlignLeft) != Qt::AlignLeft && QApplication::isRightToLeft())
+ x += w - pixmap.width();
+ result = QRect(x, y, pixmap.width(), pixmap.height());
+ return result;
+}
+
+/*!
+ \fn void QStyle::drawItemText(QPainter *painter, const QRect &rectangle, int alignment, const QPalette &palette, bool enabled, const QString& text, QPalette::ColorRole textRole) const
+
+ Draws the given \a text in the specified \a rectangle using the
+ provided \a painter and \a palette.
+
+ The text is drawn using the painter's pen, and aligned and wrapped
+ according to the specified \a alignment. If an explicit \a
+ textRole is specified, the text is drawn using the \a palette's
+ color for the given role. The \a enabled parameter indicates
+ whether or not the item is enabled; when reimplementing this
+ function, the \a enabled parameter should influence how the item is
+ drawn.
+
+ \sa Qt::Alignment, drawItemPixmap()
+*/
+void QStyle::drawItemText(QPainter *painter, const QRect &rect, int alignment, const QPalette &pal,
+ bool enabled, const QString& text, QPalette::ColorRole textRole) const
+{
+ if (text.isEmpty())
+ return;
+ QPen savedPen;
+ if (textRole != QPalette::NoRole) {
+ savedPen = painter->pen();
+ painter->setPen(QPen(pal.brush(textRole), savedPen.widthF()));
+ }
+ if (!enabled) {
+ if (proxy()->styleHint(SH_DitherDisabledText)) {
+ QRect br;
+ painter->drawText(rect, alignment, text, &br);
+ painter->fillRect(br, QBrush(painter->background().color(), Qt::Dense5Pattern));
+ return;
+ } else if (proxy()->styleHint(SH_EtchDisabledText)) {
+ QPen pen = painter->pen();
+ painter->setPen(pal.light().color());
+ painter->drawText(rect.adjusted(1, 1, 1, 1), alignment, text);
+ painter->setPen(pen);
+ }
+ }
+ painter->drawText(rect, alignment, text);
+ if (textRole != QPalette::NoRole)
+ painter->setPen(savedPen);
+}
+
+/*!
+ \fn void QStyle::drawItemPixmap(QPainter *painter, const QRect &rectangle, int alignment,
+ const QPixmap &pixmap) const
+
+ Draws the given \a pixmap in the specified \a rectangle, according
+ to the specified \a alignment, using the provided \a painter.
+
+ \sa drawItemText()
+*/
+
+void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment,
+ const QPixmap &pixmap) const
+{
+ QRect aligned = alignedRect(QApplication::layoutDirection(), QFlag(alignment), pixmap.size(), rect);
+ QRect inter = aligned.intersected(rect);
+
+ painter->drawPixmap(inter.x(), inter.y(), pixmap, inter.x() - aligned.x(), inter.y() - aligned.y(), inter.width(), inter.height());
+}
+
+/*!
+ \enum QStyle::PrimitiveElement
+
+ This enum describes the various primitive elements. A
+ primitive element is a common GUI element, such as a checkbox
+ indicator or button bevel.
+
+ \omitvalue PE_IndicatorViewItemCheck
+ \value PE_FrameStatusBar Frame
+
+ \value PE_PanelButtonCommand Button used to initiate an action, for
+ example, a QPushButton.
+
+ \value PE_FrameDefaultButton This frame around a default button, e.g. in a dialog.
+ \value PE_PanelButtonBevel Generic panel with a button bevel.
+ \value PE_PanelButtonTool Panel for a Tool button, used with QToolButton.
+ \value PE_PanelLineEdit Panel for a QLineEdit.
+ \value PE_IndicatorButtonDropDown Indicator for a drop down button, for example, a tool
+ button that displays a menu.
+
+ \value PE_FrameFocusRect Generic focus indicator.
+
+ \value PE_IndicatorArrowUp Generic Up arrow.
+ \value PE_IndicatorArrowDown Generic Down arrow.
+ \value PE_IndicatorArrowRight Generic Right arrow.
+ \value PE_IndicatorArrowLeft Generic Left arrow.
+
+ \value PE_IndicatorSpinUp Up symbol for a spin widget, for example a QSpinBox.
+ \value PE_IndicatorSpinDown Down symbol for a spin widget.
+ \value PE_IndicatorSpinPlus Increase symbol for a spin widget.
+ \value PE_IndicatorSpinMinus Decrease symbol for a spin widget.
+
+ \value PE_IndicatorItemViewItemCheck On/off indicator for a view item.
+
+ \value PE_IndicatorCheckBox On/off indicator, for example, a QCheckBox.
+ \value PE_IndicatorRadioButton Exclusive on/off indicator, for example, a QRadioButton.
+
+ \value PE_Q3DockWindowSeparator Item separator for Qt 3 compatible dock window
+ and toolbar contents.
+ \value PE_IndicatorDockWidgetResizeHandle Resize handle for dock windows.
+
+ \value PE_Frame Generic frame
+ \value PE_FrameMenu Frame for popup windows/menus; see also QMenu.
+ \value PE_PanelMenuBar Panel for menu bars.
+ \value PE_PanelScrollAreaCorner Panel at the bottom-right (or
+ bottom-left) corner of a scroll area.
+
+ \value PE_FrameDockWidget Panel frame for dock windows and toolbars.
+ \value PE_FrameTabWidget Frame for tab widgets.
+ \value PE_FrameLineEdit Panel frame for line edits.
+ \value PE_FrameGroupBox Panel frame around group boxes.
+ \value PE_FrameButtonBevel Panel frame for a button bevel.
+ \value PE_FrameButtonTool Panel frame for a tool button.
+
+ \value PE_IndicatorHeaderArrow Arrow used to indicate sorting on a list or table
+ header.
+ \value PE_FrameStatusBarItem Frame for an item of a status bar; see also QStatusBar.
+
+ \value PE_FrameWindow Frame around a MDI window or a docking window.
+
+ \value PE_Q3Separator Qt 3 compatible generic separator.
+
+ \value PE_IndicatorMenuCheckMark Check mark used in a menu.
+
+ \value PE_IndicatorProgressChunk Section of a progress bar indicator; see also QProgressBar.
+
+ \value PE_Q3CheckListController Qt 3 compatible controller part of a list view item.
+ \value PE_Q3CheckListIndicator Qt 3 compatible checkbox part of a list view item.
+ \value PE_Q3CheckListExclusiveIndicator Qt 3 compatible radio button part of a list view item.
+
+ \value PE_IndicatorBranch Lines used to represent the branch of a tree in a tree view.
+ \value PE_IndicatorToolBarHandle The handle of a toolbar.
+ \value PE_IndicatorToolBarSeparator The separator in a toolbar.
+ \value PE_PanelToolBar The panel for a toolbar.
+ \value PE_PanelTipLabel The panel for a tip label.
+ \value PE_FrameTabBarBase The frame that is drawn for a tab bar, ususally drawn for a tab bar that isn't part of a tab widget.
+ \value PE_IndicatorTabTear An indicator that a tab is partially scrolled out of the visible tab bar when there are many tabs.
+ \value PE_IndicatorColumnViewArrow An arrow in a QColumnView.
+
+ \value PE_Widget A plain QWidget.
+
+ \value PE_CustomBase Base value for custom primitive elements.
+ All values above this are reserved for custom use. Custom values
+ must be greater than this value.
+
+ \value PE_IndicatorItemViewItemDrop An indicator that is drawn to show where an item in an item view is about to be dropped
+ during a drag-and-drop operation in an item view.
+ \value PE_PanelItemViewItem The background for an item in an item view.
+ \value PE_PanelItemViewRow The background of a row in an item view.
+
+ \value PE_PanelStatusBar The panel for a status bar.
+
+ \value PE_IndicatorTabClose The close button on a tab bar.
+ \value PE_PanelMenu The panel for a menu.
+
+ \sa drawPrimitive()
+*/
+
+/*!
+ \typedef QStyle::SFlags
+ \internal
+*/
+
+/*!
+ \typedef QStyle::SCFlags
+ \internal
+*/
+
+/*!
+ \enum QStyle::StateFlag
+
+ This enum describes flags that are used when drawing primitive
+ elements.
+
+ Note that not all primitives use all of these flags, and that the
+ flags may mean different things to different items.
+
+ \value State_None Indicates that the widget does not have a state.
+ \value State_Active Indicates that the widget is active.
+ \value State_AutoRaise Used to indicate if auto-raise appearance should be usd on a tool button.
+ \value State_Children Used to indicate if an item view branch has children.
+ \value State_DownArrow Used to indicate if a down arrow should be visible on the widget.
+ \value State_Editing Used to indicate if an editor is opened on the widget.
+ \value State_Enabled Used to indicate if the widget is enabled.
+ \value State_HasEditFocus Used to indicate if the widget currently has edit focus.
+ \value State_HasFocus Used to indicate if the widget has focus.
+ \value State_Horizontal Used to indicate if the widget is laid out horizontally, for example. a tool bar.
+ \value State_KeyboardFocusChange Used to indicate if the focus was changed with the keyboard, e.g., tab, backtab or shortcut.
+ \value State_MouseOver Used to indicate if the widget is under the mouse.
+ \value State_NoChange Used to indicate a tri-state checkbox.
+ \value State_Off Used to indicate if the widget is not checked.
+ \value State_On Used to indicate if the widget is checked.
+ \value State_Raised Used to indicate if a button is raised.
+ \value State_ReadOnly Used to indicate if a widget is read-only.
+ \value State_Selected Used to indicate if a widget is selected.
+ \value State_Item Used by item views to indicate if a horizontal branch should be drawn.
+ \value State_Open Used by item views to indicate if the tree branch is open.
+ \value State_Sibling Used by item views to indicate if a vertical line needs to be drawn (for siblings).
+ \value State_Sunken Used to indicate if the widget is sunken or pressed.
+ \value State_UpArrow Used to indicate if an up arrow should be visible on the widget.
+ \value State_Mini Used to indicate a mini style Mac widget or button.
+ \value State_Small Used to indicate a small style Mac widget or button.
+ \omitvalue State_Window
+ \omitvalue State_Bottom
+ \omitvalue State_Default
+ \omitvalue State_FocusAtBorder
+ \omitvalue State_Top
+
+ \sa drawPrimitive()
+*/
+
+/*!
+ \fn void QStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option, \
+ QPainter *painter, const QWidget *widget) const
+
+ Draws the given primitive \a element with the provided \a painter using the style
+ options specified by \a option.
+
+ The \a widget argument is optional and may contain a widget that may
+ aid in drawing the primitive element.
+
+ The table below is listing the primitive elements and their
+ associated style option subclasses. The style options contain all
+ the parameters required to draw the elements, including
+ QStyleOption::state which holds the style flags that are used when
+ drawing. The table also describes which flags that are set when
+ casting the given option to the appropriate subclass.
+
+ Note that if a primitive element is not listed here, it is because
+ it uses a plain QStyleOption object.
+
+ \table
+ \header \o Primitive Element \o QStyleOption Subclass \o Style Flag \o Remark
+ \row \o \l PE_FrameFocusRect \o \l QStyleOptionFocusRect
+ \o \l State_FocusAtBorder
+ \o Whether the focus is is at the border or inside the widget.
+ \row \o{1,2} \l PE_IndicatorCheckBox \o{1,2} \l QStyleOptionButton
+ \o \l State_NoChange \o Indicates a "tri-state" checkbox.
+ \row \o \l State_On \o Indicates the indicator is checked.
+ \row \o \l PE_IndicatorRadioButton \o \l QStyleOptionButton
+ \o \l State_On \o Indicates that a radio button is selected.
+ \row \o{1,3} \l PE_Q3CheckListExclusiveIndicator, \l PE_Q3CheckListIndicator
+ \o{1,3} \l QStyleOptionQ3ListView \o \l State_On
+ \o Indicates whether or not the controller is selected.
+ \row \o \l State_NoChange \o Indicates a "tri-state" controller.
+ \row \o \l State_Enabled \o Indicates the controller is enabled.
+ \row \o{1,4} \l PE_IndicatorBranch \o{1,4} \l QStyleOption
+ \o \l State_Children \o Indicates that the control for expanding the tree to show child items, should be drawn.
+ \row \o \l State_Item \o Indicates that a horizontal branch (to show a child item), should be drawn.
+ \row \o \l State_Open \o Indicates that the tree branch is expanded.
+ \row \o \l State_Sibling \o Indicates that a vertical line (to show a sibling item), should be drawn.
+ \row \o \l PE_IndicatorHeaderArrow \o \l QStyleOptionHeader
+ \o \l State_UpArrow \o Indicates that the arrow should be drawn up;
+ otherwise it should be down.
+ \row \o \l PE_FrameGroupBox, \l PE_Frame, \l PE_FrameLineEdit,
+ \l PE_FrameMenu, \l PE_FrameDockWidget, \l PE_FrameWindow
+ \o \l QStyleOptionFrame \o \l State_Sunken
+ \o Indicates that the Frame should be sunken.
+ \row \o \l PE_IndicatorToolBarHandle \o \l QStyleOption
+ \o \l State_Horizontal \o Indicates that the window handle is horizontal
+ instead of vertical.
+ \row \o \l PE_Q3DockWindowSeparator \o \l QStyleOption
+ \o \l State_Horizontal \o Indicates that the separator is horizontal
+ instead of vertical.
+ \row \o \l PE_IndicatorSpinPlus, \l PE_IndicatorSpinMinus, \l PE_IndicatorSpinUp,
+ \l PE_IndicatorSpinDown,
+ \o \l QStyleOptionSpinBox
+ \o \l State_Sunken \o Indicates that the button is pressed.
+ \row \o{1,5} \l PE_PanelButtonCommand
+ \o{1,5} \l QStyleOptionButton
+ \o \l State_Enabled \o Set if the button is enabled.
+ \row \o \l State_HasFocus \o Set if the button has input focus.
+ \row \o \l State_Raised \o Set if the button is not down, not on and not flat.
+ \row \o \l State_On \o Set if the button is a toggle button and is toggled on.
+ \row \o \l State_Sunken
+ \o Set if the button is down (i.e., the mouse button or the
+ space bar is pressed on the button).
+ \endtable
+
+ \sa drawComplexControl(), drawControl()
+*/
+
+/*!
+ \enum QStyle::ControlElement
+
+ This enum represents a control element. A control element is a
+ part of a widget that performs some action or displays information
+ to the user.
+
+ \value CE_PushButton A QPushButton, draws CE_PushButtonBevel, CE_PushButtonLabel and PE_FrameFocusRect.
+ \value CE_PushButtonBevel The bevel and default indicator of a QPushButton.
+ \value CE_PushButtonLabel The label (an icon with text or pixmap) of a QPushButton.
+
+ \value CE_DockWidgetTitle Dock window title.
+ \value CE_Splitter Splitter handle; see also QSplitter.
+
+
+ \value CE_CheckBox A QCheckBox, draws a PE_IndicatorCheckBox, a CE_CheckBoxLabel and a PE_FrameFocusRect.
+ \value CE_CheckBoxLabel The label (text or pixmap) of a QCheckBox.
+
+ \value CE_RadioButton A QRadioButton, draws a PE_IndicatorRadioButton, a CE_RadioButtonLabel and a PE_FrameFocusRect.
+ \value CE_RadioButtonLabel The label (text or pixmap) of a QRadioButton.
+
+ \value CE_TabBarTab The tab and label within a QTabBar.
+ \value CE_TabBarTabShape The tab shape within a tab bar.
+ \value CE_TabBarTabLabel The label within a tab.
+
+ \value CE_ProgressBar A QProgressBar, draws CE_ProgressBarGroove, CE_ProgressBarContents and CE_ProgressBarLabel.
+ \value CE_ProgressBarGroove The groove where the progress
+ indicator is drawn in a QProgressBar.
+ \value CE_ProgressBarContents The progress indicator of a QProgressBar.
+ \value CE_ProgressBarLabel The text label of a QProgressBar.
+
+ \value CE_ToolButtonLabel A tool button's label.
+
+ \value CE_MenuBarItem A menu item in a QMenuBar.
+ \value CE_MenuBarEmptyArea The empty area of a QMenuBar.
+
+ \value CE_MenuItem A menu item in a QMenu.
+ \value CE_MenuScroller Scrolling areas in a QMenu when the
+ style supports scrolling.
+ \value CE_MenuTearoff A menu item representing the tear off section of
+ a QMenu.
+ \value CE_MenuEmptyArea The area in a menu without menu items.
+ \value CE_MenuHMargin The horizontal extra space on the left/right of a menu.
+ \value CE_MenuVMargin The vertical extra space on the top/bottom of a menu.
+
+ \value CE_Q3DockWindowEmptyArea The empty area of a QDockWidget.
+
+ \value CE_ToolBoxTab The toolbox's tab and label within a QToolBox.
+ \value CE_SizeGrip Window resize handle; see also QSizeGrip.
+
+ \value CE_Header A header.
+ \value CE_HeaderSection A header section.
+ \value CE_HeaderLabel The header's label.
+
+ \value CE_ScrollBarAddLine Scroll bar line increase indicator.
+ (i.e., scroll down); see also QScrollBar.
+ \value CE_ScrollBarSubLine Scroll bar line decrease indicator (i.e., scroll up).
+ \value CE_ScrollBarAddPage Scolllbar page increase indicator (i.e., page down).
+ \value CE_ScrollBarSubPage Scroll bar page decrease indicator (i.e., page up).
+ \value CE_ScrollBarSlider Scroll bar slider.
+ \value CE_ScrollBarFirst Scroll bar first line indicator (i.e., home).
+ \value CE_ScrollBarLast Scroll bar last line indicator (i.e., end).
+
+ \value CE_RubberBand Rubber band used in for example an icon view.
+
+ \value CE_FocusFrame Focus frame that is style controlled.
+
+ \value CE_ItemViewItem An item inside an item view.
+
+ \value CE_CustomBase Base value for custom control elements;
+ custom values must be greater than this value.
+ \value CE_ComboBoxLabel The label of a non-editable QComboBox.
+ \value CE_ToolBar A toolbar like QToolBar.
+ \value CE_ToolBoxTabShape The toolbox's tab shape.
+ \value CE_ToolBoxTabLabel The toolbox's tab label.
+ \value CE_HeaderEmptyArea The area of a header view where there are no header sections.
+
+ \value CE_ShapedFrame The frame with the shape specified in the QStyleOptionFrameV3; see QFrame.
+
+ \omitvalue CE_ColumnViewGrip
+
+ \sa drawControl()
+*/
+
+/*!
+ \fn void QStyle::drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const
+
+ Draws the given \a element with the provided \a painter with the
+ style options specified by \a option.
+
+ The \a widget argument is optional and can be used as aid in
+ drawing the control. The \a option parameter is a pointer to a
+ QStyleOption object that can be cast to the correct subclass
+ using the qstyleoption_cast() function.
+
+ The table below is listing the control elements and their
+ associated style option subclass. The style options contain all
+ the parameters required to draw the controls, including
+ QStyleOption::state which holds the style flags that are used when
+ drawing. The table also describes which flags that are set when
+ casting the given option to the appropriate subclass.
+
+ Note that if a control element is not listed here, it is because
+ it uses a plain QStyleOption object.
+
+ \table
+ \header \o Control Element \o QStyleOption Subclass \o Style Flag \o Remark
+ \row \o{1,5} \l CE_MenuItem, \l CE_MenuBarItem
+ \o{1,5} \l QStyleOptionMenuItem
+ \o \l State_Selected \o The menu item is currently selected item.
+ \row \o \l State_Enabled \o The item is enabled.
+ \row \o \l State_DownArrow \o Indicates that a scroll down arrow should be drawn.
+ \row \o \l State_UpArrow \o Indicates that a scroll up arrow should be drawn
+ \row \o \l State_HasFocus \o Set if the menu bar has input focus.
+
+ \row \o{1,5} \l CE_PushButton, \l CE_PushButtonBevel, \l CE_PushButtonLabel
+ \o{1,5} \l QStyleOptionButton
+ \o \l State_Enabled \o Set if the button is enabled.
+ \row \o \l State_HasFocus \o Set if the button has input focus.
+ \row \o \l State_Raised \o Set if the button is not down, not on and not flat.
+ \row \o \l State_On \o Set if the button is a toggle button and is toggled on.
+ \row \o \l State_Sunken
+ \o Set if the button is down (i.e., the mouse button or the
+ space bar is pressed on the button).
+
+ \row \o{1,6} \l CE_RadioButton, \l CE_RadioButtonLabel,
+ \l CE_CheckBox, \l CE_CheckBoxLabel
+ \o{1,6} \l QStyleOptionButton
+ \o \l State_Enabled \o Set if the button is enabled.
+ \row \o \l State_HasFocus \o Set if the button has input focus.
+ \row \o \l State_On \o Set if the button is checked.
+ \row \o \l State_Off \o Set if the button is not checked.
+ \row \o \l State_NoChange \o Set if the button is in the NoChange state.
+ \row \o \l State_Sunken
+ \o Set if the button is down (i.e., the mouse button or
+ the space bar is pressed on the button).
+
+ \row \o{1,2} \l CE_ProgressBarContents, \l CE_ProgressBarLabel,
+ \l CE_ProgressBarGroove
+ \o{1,2} \l QStyleOptionProgressBar
+ \o \l State_Enabled \o Set if the progress bar is enabled.
+ \row \o \l State_HasFocus \o Set if the progress bar has input focus.
+
+ \row \o \l CE_Header, \l CE_HeaderSection, \l CE_HeaderLabel \o \l QStyleOptionHeader \o \o
+
+ \row \o{1,3} \l CE_TabBarTab, CE_TabBarTabShape, CE_TabBarTabLabel
+ \o{1,3} \l QStyleOptionTab
+ \o \l State_Enabled \o Set if the tab bar is enabled.
+ \row \o \l State_Selected \o The tab bar is the currently selected tab bar.
+ \row \o \l State_HasFocus \o Set if the tab bar tab has input focus.
+
+ \row \o{1,7} \l CE_ToolButtonLabel
+ \o{1,7} \l QStyleOptionToolButton
+ \o \l State_Enabled \o Set if the tool button is enabled.
+ \row \o \l State_HasFocus \o Set if the tool button has input focus.
+ \row \o \l State_Sunken
+ \o Set if the tool button is down (i.e., a mouse button or
+ the space bar is pressed).
+ \row \o \l State_On \o Set if the tool button is a toggle button and is toggled on.
+ \row \o \l State_AutoRaise \o Set if the tool button has auto-raise enabled.
+ \row \o \l State_MouseOver \o Set if the mouse pointer is over the tool button.
+ \row \o \l State_Raised \o Set if the button is not down and is not on.
+
+ \row \o \l CE_ToolBoxTab \o \l QStyleOptionToolBox
+ \o \l State_Selected \o The tab is the currently selected tab.
+ \row \o{1,3} \l CE_HeaderSection \o{1,3} \l QStyleOptionHeader
+ \o \l State_Sunken \o Indicates that the section is pressed.
+ \row \o \l State_UpArrow \o Indicates that the sort indicator should be pointing up.
+ \row \o \l State_DownArrow \o Indicates that the sort indicator should be pointing down.
+ \endtable
+
+ \sa drawPrimitive(), drawComplexControl()
+*/
+
+/*!
+ \enum QStyle::SubElement
+
+ This enum represents a sub-area of a widget. Style implementations
+ use these areas to draw the different parts of a widget.
+
+ \value SE_PushButtonContents Area containing the label (icon
+ with text or pixmap).
+ \value SE_PushButtonFocusRect Area for the focus rect (usually
+ larger than the contents rect).
+ \value SE_PushButtonLayoutItem Area that counts for the parent layout.
+
+ \value SE_CheckBoxIndicator Area for the state indicator (e.g., check mark).
+ \value SE_CheckBoxContents Area for the label (text or pixmap).
+ \value SE_CheckBoxFocusRect Area for the focus indicator.
+ \value SE_CheckBoxClickRect Clickable area, defaults to SE_CheckBoxFocusRect.
+ \value SE_CheckBoxLayoutItem Area that counts for the parent layout.
+
+ \value SE_DateTimeEditLayoutItem Area that counts for the parent layout.
+
+ \value SE_RadioButtonIndicator Area for the state indicator.
+ \value SE_RadioButtonContents Area for the label.
+ \value SE_RadioButtonFocusRect Area for the focus indicator.
+ \value SE_RadioButtonClickRect Clickable area, defaults to SE_RadioButtonFocusRect.
+ \value SE_RadioButtonLayoutItem Area that counts for the parent layout.
+
+ \value SE_ComboBoxFocusRect Area for the focus indicator.
+
+ \value SE_SliderFocusRect Area for the focus indicator.
+ \value SE_SliderLayoutItem Area that counts for the parent layout.
+
+ \value SE_SpinBoxLayoutItem Area that counts for the parent layout.
+
+ \value SE_Q3DockWindowHandleRect Area for the tear-off handle.
+
+ \value SE_ProgressBarGroove Area for the groove.
+ \value SE_ProgressBarContents Area for the progress indicator.
+ \value SE_ProgressBarLabel Area for the text label.
+ \value SE_ProgressBarLayoutItem Area that counts for the parent layout.
+
+ \omitvalue SE_DialogButtonAccept
+ \omitvalue SE_DialogButtonReject
+ \omitvalue SE_DialogButtonApply
+ \omitvalue SE_DialogButtonHelp
+ \omitvalue SE_DialogButtonAll
+ \omitvalue SE_DialogButtonRetry
+ \omitvalue SE_DialogButtonAbort
+ \omitvalue SE_DialogButtonIgnore
+ \omitvalue SE_DialogButtonCustom
+ \omitvalue SE_ViewItemCheckIndicator
+
+ \value SE_FrameContents Area for a frame's contents.
+ \value SE_ShapedFrameContents Area for a frame's contents using the shape in QStyleOptionFrameV3; see QFrame
+ \value SE_FrameLayoutItem Area that counts for the parent layout.
+
+ \value SE_HeaderArrow Area for the sort indicator for a header.
+ \value SE_HeaderLabel Area for the label in a header.
+
+ \value SE_LabelLayoutItem Area that counts for the parent layout.
+
+ \value SE_LineEditContents Area for a line edit's contents.
+
+ \value SE_TabWidgetLeftCorner Area for the left corner widget in a tab widget.
+ \value SE_TabWidgetRightCorner Area for the right corner widget in a tab widget.
+ \value SE_TabWidgetTabBar Area for the tab bar widget in a tab widget.
+ \value SE_TabWidgetTabContents Area for the contents of the tab widget.
+ \value SE_TabWidgetTabPane Area for the pane of a tab widget.
+ \value SE_TabWidgetLayoutItem Area that counts for the parent layout.
+
+ \value SE_ToolBoxTabContents Area for a toolbox tab's icon and label.
+
+ \value SE_ToolButtonLayoutItem Area that counts for the parent layout.
+
+ \value SE_ItemViewItemCheckIndicator Area for a view item's check mark.
+
+ \value SE_TabBarTearIndicator Area for the tear indicator on a tab bar with scroll arrows.
+
+ \value SE_TreeViewDisclosureItem Area for the actual disclosure item in a tree branch.
+
+ \value SE_DialogButtonBoxLayoutItem Area that counts for the parent layout.
+
+ \value SE_GroupBoxLayoutItem Area that counts for the parent layout.
+
+ \value SE_CustomBase Base value for custom sub-elements.
+ Custom values must be greater than this value.
+
+ \value SE_DockWidgetFloatButton The float button of a dock
+ widget.
+ \value SE_DockWidgetTitleBarText The text bounds of the dock
+ widgets title.
+ \value SE_DockWidgetCloseButton The close button of a dock
+ widget.
+ \value SE_DockWidgetIcon The icon of a dock widget.
+ \value SE_ComboBoxLayoutItem Area that counts for the parent layout.
+
+
+ \value SE_ItemViewItemDecoration Area for a view item's decoration (icon).
+ \value SE_ItemViewItemText Area for a view item's text.
+ \value SE_ItemViewItemFocusRect Area for a view item's focus rect.
+
+ \value SE_TabBarTabLeftButton Area for a widget on the left side of a tab in a tab bar.
+ \value SE_TabBarTabRightButton Area for a widget on the right side of a tab in a tab bar.
+ \value SE_TabBarTabText Area for the text on a tab in a tab bar.
+
+ \value SE_ToolBarHandle Area for the handle of a tool bar.
+
+ \sa subElementRect()
+*/
+
+/*!
+ \fn QRect QStyle::subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const
+
+ Returns the sub-area for the given \a element as described in the
+ provided style \a option. The returned rectangle is defined in
+ screen coordinates.
+
+ The \a widget argument is optional and can be used to aid
+ determining the area. The QStyleOption object can be cast to the
+ appropriate type using the qstyleoption_cast() function. See the
+ table below for the appropriate \a option casts:
+
+ \table
+ \header \o Sub Element \o QStyleOption Subclass
+ \row \o \l SE_PushButtonContents \o \l QStyleOptionButton
+ \row \o \l SE_PushButtonFocusRect \o \l QStyleOptionButton
+ \row \o \l SE_CheckBoxIndicator \o \l QStyleOptionButton
+ \row \o \l SE_CheckBoxContents \o \l QStyleOptionButton
+ \row \o \l SE_CheckBoxFocusRect \o \l QStyleOptionButton
+ \row \o \l SE_RadioButtonIndicator \o \l QStyleOptionButton
+ \row \o \l SE_RadioButtonContents \o \l QStyleOptionButton
+ \row \o \l SE_RadioButtonFocusRect \o \l QStyleOptionButton
+ \row \o \l SE_ComboBoxFocusRect \o \l QStyleOptionComboBox
+ \row \o \l SE_Q3DockWindowHandleRect \o \l QStyleOptionQ3DockWindow
+ \row \o \l SE_ProgressBarGroove \o \l QStyleOptionProgressBar
+ \row \o \l SE_ProgressBarContents \o \l QStyleOptionProgressBar
+ \row \o \l SE_ProgressBarLabel \o \l QStyleOptionProgressBar
+ \endtable
+*/
+
+/*!
+ \enum QStyle::ComplexControl
+
+ This enum describes the available complex controls. Complex
+ controls have different behavior depending upon where the user
+ clicks on them or which keys are pressed.
+
+ \value CC_SpinBox A spinbox, like QSpinBox.
+ \value CC_ComboBox A combobox, like QComboBox.
+ \value CC_ScrollBar A scroll bar, like QScrollBar.
+ \value CC_Slider A slider, like QSlider.
+ \value CC_ToolButton A tool button, like QToolButton.
+ \value CC_TitleBar A Title bar, like those used in QMdiSubWindow.
+ \value CC_Q3ListView Used for drawing the Q3ListView class.
+ \value CC_GroupBox A group box, like QGroupBox.
+ \value CC_Dial A dial, like QDial.
+ \value CC_MdiControls The minimize, close, and normal
+ button in the menu bar for a
+ maximized MDI subwindow.
+
+ \value CC_CustomBase Base value for custom complex controls. Custom
+ values must be greater than this value.
+
+ \sa SubControl drawComplexControl()
+*/
+
+/*!
+ \enum QStyle::SubControl
+
+ This enum describes the available sub controls. A subcontrol is a
+ control element within a complex control (ComplexControl).
+
+ \value SC_None Special value that matches no other sub control.
+
+ \value SC_ScrollBarAddLine Scroll bar add line (i.e., down/right
+ arrow); see also QScrollBar.
+ \value SC_ScrollBarSubLine Scroll bar sub line (i.e., up/left arrow).
+ \value SC_ScrollBarAddPage Scroll bar add page (i.e., page down).
+ \value SC_ScrollBarSubPage Scroll bar sub page (i.e., page up).
+ \value SC_ScrollBarFirst Scroll bar first line (i.e., home).
+ \value SC_ScrollBarLast Scroll bar last line (i.e., end).
+ \value SC_ScrollBarSlider Scroll bar slider handle.
+ \value SC_ScrollBarGroove Special sub-control which contains the
+ area in which the slider handle may move.
+
+ \value SC_SpinBoxUp Spin widget up/increase; see also QSpinBox.
+ \value SC_SpinBoxDown Spin widget down/decrease.
+ \value SC_SpinBoxFrame Spin widget frame.
+ \value SC_SpinBoxEditField Spin widget edit field.
+
+ \value SC_ComboBoxEditField Combobox edit field; see also QComboBox.
+ \value SC_ComboBoxArrow Combobox arrow button.
+ \value SC_ComboBoxFrame Combobox frame.
+ \value SC_ComboBoxListBoxPopup The reference rectangle for the combobox popup.
+ Used to calculate the position of the popup.
+
+ \value SC_SliderGroove Special sub-control which contains the area
+ in which the slider handle may move.
+ \value SC_SliderHandle Slider handle.
+ \value SC_SliderTickmarks Slider tickmarks.
+
+ \value SC_ToolButton Tool button (see also QToolButton).
+ \value SC_ToolButtonMenu Sub-control for opening a popup menu in a
+ tool button; see also Q3PopupMenu.
+
+ \value SC_TitleBarSysMenu System menu button (i.e., restore, close, etc.).
+ \value SC_TitleBarMinButton Minimize button.
+ \value SC_TitleBarMaxButton Maximize button.
+ \value SC_TitleBarCloseButton Close button.
+ \value SC_TitleBarLabel Window title label.
+ \value SC_TitleBarNormalButton Normal (restore) button.
+ \value SC_TitleBarShadeButton Shade button.
+ \value SC_TitleBarUnshadeButton Unshade button.
+ \value SC_TitleBarContextHelpButton Context Help button.
+
+ \value SC_Q3ListView The list view area.
+ \value SC_Q3ListViewExpand Expand item (i.e., show/hide child items).
+
+ \value SC_DialHandle The handle of the dial (i.e. what you use to control the dial).
+ \value SC_DialGroove The groove for the dial.
+ \value SC_DialTickmarks The tickmarks for the dial.
+
+ \value SC_GroupBoxFrame The frame of a group box.
+ \value SC_GroupBoxLabel The title of a group box.
+ \value SC_GroupBoxCheckBox The optional check box of a group box.
+ \value SC_GroupBoxContents The group box contents.
+
+ \value SC_MdiNormalButton The normal button for a MDI
+ subwindow in the menu bar.
+ \value SC_MdiMinButton The minimize button for a MDI
+ subwindow in the menu bar.
+ \value SC_MdiCloseButton The close button for a MDI subwindow
+ in the menu bar.
+
+ \value SC_All Special value that matches all sub-controls.
+ \omitvalue SC_Q3ListViewBranch
+ \omitvalue SC_CustomBase
+
+ \sa ComplexControl
+*/
+
+/*!
+ \fn void QStyle::drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget) const
+
+ Draws the given \a control using the provided \a painter with the
+ style options specified by \a option.
+
+ The \a widget argument is optional and can be used as aid in
+ drawing the control.
+
+ The \a option parameter is a pointer to a QStyleOptionComplex
+ object that can be cast to the correct subclass using the
+ qstyleoption_cast() function. Note that the \c rect member of the
+ specified \a option must be in logical
+ coordinates. Reimplementations of this function should use
+ visualRect() to change the logical coordinates into screen
+ coordinates before calling the drawPrimitive() or drawControl()
+ function.
+
+ The table below is listing the complex control elements and their
+ associated style option subclass. The style options contain all
+ the parameters required to draw the controls, including
+ QStyleOption::state which holds the \l {QStyle::StateFlag}{style
+ flags} that are used when drawing. The table also describes which
+ flags that are set when casting the given \a option to the
+ appropriate subclass.
+
+ \table
+ \header \o Complex Control \o QStyleOptionComplex Subclass \o Style Flag \o Remark
+ \row \o{1,2} \l{CC_SpinBox} \o{1,2} \l QStyleOptionSpinBox
+ \o \l State_Enabled \o Set if the spin box is enabled.
+ \row \o \l State_HasFocus \o Set if the spin box has input focus.
+
+ \row \o{1,2} \l {CC_ComboBox} \o{1,2} \l QStyleOptionComboBox
+ \o \l State_Enabled \o Set if the combobox is enabled.
+ \row \o \l State_HasFocus \o Set if the combobox has input focus.
+
+ \row \o{1,2} \l {CC_ScrollBar} \o{1,2} \l QStyleOptionSlider
+ \o \l State_Enabled \o Set if the scroll bar is enabled.
+ \row \o \l State_HasFocus \o Set if the scroll bar has input focus.
+
+ \row \o{1,2} \l {CC_Slider} \o{1,2} \l QStyleOptionSlider
+ \o \l State_Enabled \o Set if the slider is enabled.
+ \row \o \l State_HasFocus \o Set if the slider has input focus.
+
+ \row \o{1,2} \l {CC_Dial} \o{1,2} \l QStyleOptionSlider
+ \o \l State_Enabled \o Set if the dial is enabled.
+ \row \o \l State_HasFocus \o Set if the dial has input focus.
+
+ \row \o{1,6} \l {CC_ToolButton} \o{1,6} \l QStyleOptionToolButton
+ \o \l State_Enabled \o Set if the tool button is enabled.
+ \row \o \l State_HasFocus \o Set if the tool button has input focus.
+ \row \o \l State_DownArrow \o Set if the tool button is down (i.e., a mouse
+ button or the space bar is pressed).
+ \row \o \l State_On \o Set if the tool button is a toggle button
+ and is toggled on.
+ \row \o \l State_AutoRaise \o Set if the tool button has auto-raise enabled.
+ \row \o \l State_Raised \o Set if the button is not down, not on, and doesn't
+ contain the mouse when auto-raise is enabled.
+
+ \row \o \l{CC_TitleBar} \o \l QStyleOptionTitleBar
+ \o \l State_Enabled \o Set if the title bar is enabled.
+
+ \row \o \l{CC_Q3ListView} \o \l QStyleOptionQ3ListView
+ \o \l State_Enabled \o Set if the list view is enabled.
+
+ \endtable
+
+ \sa drawPrimitive(), drawControl()
+*/
+
+
+/*!
+ \fn QRect QStyle::subControlRect(ComplexControl control,
+ const QStyleOptionComplex *option, SubControl subControl,
+ const QWidget *widget) const = 0
+
+ Returns the rectangle containing the specified \a subControl of
+ the given complex \a control (with the style specified by \a
+ option). The rectangle is defined in screen coordinates.
+
+ The \a option argument is a pointer to QStyleOptionComplex or
+ one of its subclasses, and can be cast to the appropriate type
+ using the qstyleoption_cast() function. See drawComplexControl()
+ for details. The \a widget is optional and can contain additional
+ information for the function.
+
+ \sa drawComplexControl()
+*/
+
+/*!
+ \fn QStyle::SubControl QStyle::hitTestComplexControl(ComplexControl control,
+ const QStyleOptionComplex *option, const QPoint &position,
+ const QWidget *widget) const = 0
+
+ Returns the sub control at the given \a position in the given
+ complex \a control (with the style options specified by \a
+ option).
+
+ Note that the \a position is expressed in screen coordinates.
+
+ The \a option argument is a pointer to a QStyleOptionComplex
+ object (or one of its subclasses). The object can be cast to the
+ appropriate type using the qstyleoption_cast() function. See
+ drawComplexControl() for details. The \a widget argument is
+ optional and can contain additional information for the function.
+
+ \sa drawComplexControl(), subControlRect()
+*/
+
+/*!
+ \enum QStyle::PixelMetric
+
+ This enum describes the various available pixel metrics. A pixel
+ metric is a style dependent size represented by a single pixel
+ value.
+
+ \value PM_ButtonMargin Amount of whitespace between push button
+ labels and the frame.
+ \value PM_DockWidgetTitleBarButtonMargin Amount of whitespace between dock widget's
+ title bar button labels and the frame.
+ \value PM_ButtonDefaultIndicator Width of the default-button indicator frame.
+ \value PM_MenuButtonIndicator Width of the menu button indicator
+ proportional to the widget height.
+ \value PM_ButtonShiftHorizontal Horizontal contents shift of a
+ button when the button is down.
+ \value PM_ButtonShiftVertical Vertical contents shift of a button when the
+ button is down.
+
+ \value PM_DefaultFrameWidth Default frame width (usually 2).
+ \value PM_SpinBoxFrameWidth Frame width of a spin box, defaults to PM_DefaultFrameWidth.
+ \value PM_ComboBoxFrameWidth Frame width of a combo box, defaults to PM_DefaultFrameWidth.
+
+ \value PM_MDIFrameWidth Obsolete. Use PM_MdiSubWindowFrameWidth instead.
+ \value PM_MdiSubWindowFrameWidth Frame width of an MDI window.
+ \value PM_MDIMinimizedWidth Obsolete. Use PM_MdiSubWindowMinimizedWidth instead.
+ \value PM_MdiSubWindowMinimizedWidth Width of a minimized MDI window.
+
+ \value PM_LayoutLeftMargin Default \l{QLayout::setContentsMargins()}{left margin} for a
+ QLayout.
+ \value PM_LayoutTopMargin Default \l{QLayout::setContentsMargins()}{top margin} for a QLayout.
+ \value PM_LayoutRightMargin Default \l{QLayout::setContentsMargins()}{right margin} for a
+ QLayout.
+ \value PM_LayoutBottomMargin Default \l{QLayout::setContentsMargins()}{bottom margin} for a
+ QLayout.
+ \value PM_LayoutHorizontalSpacing Default \l{QLayout::spacing}{horizontal spacing} for a
+ QLayout.
+ \value PM_LayoutVerticalSpacing Default \l{QLayout::spacing}{vertical spacing} for a QLayout.
+
+ \value PM_MaximumDragDistance The maximum allowed distance between
+ the mouse and a scrollbar when dragging. Exceeding the specified
+ distance will cause the slider to jump back to the original
+ position; a value of -1 disables this behavior.
+
+ \value PM_ScrollBarExtent Width of a vertical scroll bar and the
+ height of a horizontal scroll bar.
+ \value PM_ScrollBarSliderMin The minimum height of a vertical
+ scroll bar's slider and the minimum width of a horizontal
+ scroll bar's slider.
+
+ \value PM_SliderThickness Total slider thickness.
+ \value PM_SliderControlThickness Thickness of the slider handle.
+ \value PM_SliderLength Length of the slider.
+ \value PM_SliderTickmarkOffset The offset between the tickmarks
+ and the slider.
+ \value PM_SliderSpaceAvailable The available space for the slider to move.
+
+ \value PM_DockWidgetSeparatorExtent Width of a separator in a
+ horizontal dock window and the height of a separator in a
+ vertical dock window.
+ \value PM_DockWidgetHandleExtent Width of the handle in a
+ horizontal dock window and the height of the handle in a
+ vertical dock window.
+ \value PM_DockWidgetFrameWidth Frame width of a dock window.
+ \value PM_DockWidgetTitleMargin Margin of the dock window title.
+
+ \value PM_MenuBarPanelWidth Frame width of a menu bar, defaults to PM_DefaultFrameWidth.
+ \value PM_MenuBarItemSpacing Spacing between menu bar items.
+ \value PM_MenuBarHMargin Spacing between menu bar items and left/right of bar.
+ \value PM_MenuBarVMargin Spacing between menu bar items and top/bottom of bar.
+
+ \value PM_ToolBarFrameWidth Width of the frame around toolbars.
+ \value PM_ToolBarHandleExtent Width of a toolbar handle in a
+ horizontal toolbar and the height of the handle in a vertical toolbar.
+ \value PM_ToolBarItemMargin Spacing between the toolbar frame and the items.
+ \value PM_ToolBarItemSpacing Spacing between toolbar items.
+ \value PM_ToolBarSeparatorExtent Width of a toolbar separator in a
+ horizontal toolbar and the height of a separator in a vertical toolbar.
+ \value PM_ToolBarExtensionExtent Width of a toolbar extension
+ button in a horizontal toolbar and the height of the button in a
+ vertical toolbar.
+
+ \value PM_TabBarTabOverlap Number of pixels the tabs should overlap.
+ (Currently only used in styles, not inside of QTabBar)
+ \value PM_TabBarTabHSpace Extra space added to the tab width.
+ \value PM_TabBarTabVSpace Extra space added to the tab height.
+ \value PM_TabBarBaseHeight Height of the area between the tab bar
+ and the tab pages.
+ \value PM_TabBarBaseOverlap Number of pixels the tab bar overlaps
+ the tab bar base.
+ \value PM_TabBarScrollButtonWidth
+ \value PM_TabBarTabShiftHorizontal Horizontal pixel shift when a
+ tab is selected.
+ \value PM_TabBarTabShiftVertical Vertical pixel shift when a
+ tab is selected.
+
+ \value PM_ProgressBarChunkWidth Width of a chunk in a progress bar indicator.
+
+ \value PM_SplitterWidth Width of a splitter.
+
+ \value PM_TitleBarHeight Height of the title bar.
+
+ \value PM_IndicatorWidth Width of a check box indicator.
+ \value PM_IndicatorHeight Height of a checkbox indicator.
+ \value PM_ExclusiveIndicatorWidth Width of a radio button indicator.
+ \value PM_ExclusiveIndicatorHeight Height of a radio button indicator.
+
+ \value PM_MenuPanelWidth Border width (applied on all sides) for a QMenu.
+ \value PM_MenuHMargin Additional border (used on left and right) for a QMenu.
+ \value PM_MenuVMargin Additional border (used for bottom and top) for a QMenu.
+ \value PM_MenuScrollerHeight Height of the scroller area in a QMenu.
+ \value PM_MenuTearoffHeight Height of a tear off area in a QMenu.
+ \value PM_MenuDesktopFrameWidth The frame width for the menu on the desktop.
+
+ \value PM_CheckListButtonSize Area (width/height) of the
+ checkbox/radio button in a Q3CheckListItem.
+ \value PM_CheckListControllerSize Area (width/height) of the
+ controller in a Q3CheckListItem.
+
+ \omitvalue PM_DialogButtonsSeparator
+ \omitvalue PM_DialogButtonsButtonWidth
+ \omitvalue PM_DialogButtonsButtonHeight
+
+ \value PM_HeaderMarkSize The size of the sort indicator in a header.
+ \value PM_HeaderGripMargin The size of the resize grip in a header.
+ \value PM_HeaderMargin The size of the margin between the sort indicator and the text.
+ \value PM_SpinBoxSliderHeight The height of the optional spin box slider.
+
+ \value PM_ToolBarIconSize Default tool bar icon size
+ \value PM_SmallIconSize Default small icon size
+ \value PM_LargeIconSize Default large icon size
+
+ \value PM_FocusFrameHMargin Horizontal margin that the focus frame will outset the widget by.
+ \value PM_FocusFrameVMargin Vertical margin that the focus frame will outset the widget by.
+ \value PM_IconViewIconSize The default size for icons in an icon view.
+ \value PM_ListViewIconSize The default size for icons in a list view.
+
+ \value PM_ToolTipLabelFrameWidth The frame width for a tool tip label.
+ \value PM_CheckBoxLabelSpacing The spacing between a check box indicator and its label.
+ \value PM_RadioButtonLabelSpacing The spacing between a radio button indicator and its label.
+ \value PM_TabBarIconSize The default icon size for a tab bar.
+ \value PM_SizeGripSize The size of a size grip.
+ \value PM_MessageBoxIconSize The size of the standard icons in a message box
+ \value PM_ButtonIconSize The default size of button icons
+ \value PM_TextCursorWidth The width of the cursor in a line edit or text edit
+ \value PM_TabBar_ScrollButtonOverlap The distance between the left and right buttons in a tab bar.
+
+ \value PM_TabCloseIndicatorWidth The default width of a close button on a tab in a tab bar.
+ \value PM_TabCloseIndicatorHeight The default height of a close button on a tab in a tab bar.
+
+ \value PM_CustomBase Base value for custom pixel metrics. Custom
+ values must be greater than this value.
+
+ The following values are obsolete:
+
+ \value PM_DefaultTopLevelMargin Use PM_LayoutLeftMargin,
+ PM_LayoutTopMargin,
+ PM_LayoutRightMargin, and
+ PM_LayoutBottomMargin instead.
+ \value PM_DefaultChildMargin Use PM_LayoutLeftMargin,
+ PM_LayoutTopMargin,
+ PM_LayoutRightMargin, and
+ PM_LayoutBottomMargin instead.
+ \value PM_DefaultLayoutSpacing Use PM_LayoutHorizontalSpacing
+ and PM_LayoutVerticalSpacing
+ instead.
+
+ \value PM_ScrollView_ScrollBarSpacing Distance between frame and scrollbar
+ with SH_ScrollView_FrameOnlyAroundContents set.
+ \value PM_SubMenuOverlap The horizontal overlap between a submenu and its parent.
+
+
+ \sa pixelMetric()
+*/
+
+/*!
+ \fn int QStyle::pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const;
+
+ Returns the value of the given pixel \a metric.
+
+ The specified \a option and \a widget can be used for calculating
+ the metric. In general, the \a widget argument is not used. The \a
+ option can be cast to the appropriate type using the
+ qstyleoption_cast() function. Note that the \a option may be zero
+ even for PixelMetrics that can make use of it. See the table below
+ for the appropriate \a option casts:
+
+ \table
+ \header \o Pixel Metric \o QStyleOption Subclass
+ \row \o \l PM_SliderControlThickness \o \l QStyleOptionSlider
+ \row \o \l PM_SliderLength \o \l QStyleOptionSlider
+ \row \o \l PM_SliderTickmarkOffset \o \l QStyleOptionSlider
+ \row \o \l PM_SliderSpaceAvailable \o \l QStyleOptionSlider
+ \row \o \l PM_ScrollBarExtent \o \l QStyleOptionSlider
+ \row \o \l PM_TabBarTabOverlap \o \l QStyleOptionTab
+ \row \o \l PM_TabBarTabHSpace \o \l QStyleOptionTab
+ \row \o \l PM_TabBarTabVSpace \o \l QStyleOptionTab
+ \row \o \l PM_TabBarBaseHeight \o \l QStyleOptionTab
+ \row \o \l PM_TabBarBaseOverlap \o \l QStyleOptionTab
+ \endtable
+
+ Some pixel metrics are called from widgets and some are only called
+ internally by the style. If the metric is not called by a widget, it is the
+ discretion of the style author to make use of it. For some styles, this
+ may not be appropriate.
+*/
+
+/*!
+ \enum QStyle::ContentsType
+
+ This enum describes the available contents types. These are used to
+ calculate sizes for the contents of various widgets.
+
+ \value CT_CheckBox A check box, like QCheckBox.
+ \value CT_ComboBox A combo box, like QComboBox.
+ \omitvalue CT_DialogButtons
+ \value CT_Q3DockWindow A Q3DockWindow.
+ \value CT_HeaderSection A header section, like QHeader.
+ \value CT_LineEdit A line edit, like QLineEdit.
+ \value CT_Menu A menu, like QMenu.
+ \value CT_Q3Header A Qt 3 header section, like Q3Header.
+ \value CT_MenuBar A menu bar, like QMenuBar.
+ \value CT_MenuBarItem A menu bar item, like the buttons in a QMenuBar.
+ \value CT_MenuItem A menu item, like QMenuItem.
+ \value CT_ProgressBar A progress bar, like QProgressBar.
+ \value CT_PushButton A push button, like QPushButton.
+ \value CT_RadioButton A radio button, like QRadioButton.
+ \value CT_SizeGrip A size grip, like QSizeGrip.
+ \value CT_Slider A slider, like QSlider.
+ \value CT_ScrollBar A scroll bar, like QScrollBar.
+ \value CT_SpinBox A spin box, like QSpinBox.
+ \value CT_Splitter A splitter, like QSplitter.
+ \value CT_TabBarTab A tab on a tab bar, like QTabBar.
+ \value CT_TabWidget A tab widget, like QTabWidget.
+ \value CT_ToolButton A tool button, like QToolButton.
+ \value CT_GroupBox A group box, like QGroupBox.
+ \value CT_ItemViewItem An item inside an item view.
+
+ \value CT_CustomBase Base value for custom contents types.
+ Custom values must be greater than this value.
+
+ \value CT_MdiControls The minimize, normal, and close button
+ in the menu bar for a maximized MDI
+ subwindow.
+
+ \sa sizeFromContents()
+*/
+
+/*!
+ \fn QSize QStyle::sizeFromContents(ContentsType type, const QStyleOption *option, \
+ const QSize &contentsSize, const QWidget *widget) const
+
+ Returns the size of the element described by the specified
+ \a option and \a type, based on the provided \a contentsSize.
+
+ The \a option argument is a pointer to a QStyleOption or one of
+ its subclasses. The \a option can be cast to the appropriate type
+ using the qstyleoption_cast() function. The \a widget is an
+ optional argument and can contain extra information used for
+ calculating the size.
+
+ See the table below for the appropriate \a option casts:
+
+ \table
+ \header \o Contents Type \o QStyleOption Subclass
+ \row \o \l CT_PushButton \o \l QStyleOptionButton
+ \row \o \l CT_CheckBox \o \l QStyleOptionButton
+ \row \o \l CT_RadioButton \o \l QStyleOptionButton
+ \row \o \l CT_ToolButton \o \l QStyleOptionToolButton
+ \row \o \l CT_ComboBox \o \l QStyleOptionComboBox
+ \row \o \l CT_Splitter \o \l QStyleOption
+ \row \o \l CT_Q3DockWindow \o \l QStyleOptionQ3DockWindow
+ \row \o \l CT_ProgressBar \o \l QStyleOptionProgressBar
+ \row \o \l CT_MenuItem \o \l QStyleOptionMenuItem
+ \endtable
+
+ \sa ContentsType QStyleOption
+*/
+
+/*!
+ \enum QStyle::RequestSoftwareInputPanel
+
+ This enum describes under what circumstances a software input panel will be
+ requested by input capable widgets.
+
+ \value RSIP_OnMouseClickAndAlreadyFocused Requests an input panel if the user
+ clicks on the widget, but only if it is already focused.
+ \value RSIP_OnMouseClick Requests an input panel if the user clicks on the
+ widget.
+
+ \sa QEvent::RequestSoftwareInputPanel, QInputContext
+*/
+
+/*!
+ \enum QStyle::StyleHint
+
+ This enum describes the available style hints. A style hint is a general look
+ and/or feel hint.
+
+ \value SH_EtchDisabledText Disabled text is "etched" as it is on Windows.
+
+ \value SH_DitherDisabledText Disabled text is dithered as it is on Motif.
+
+ \value SH_GUIStyle The GUI style to use.
+
+ \value SH_ScrollBar_ContextMenu Whether or not a scroll bar has a context menu.
+
+ \value SH_ScrollBar_MiddleClickAbsolutePosition A boolean value.
+ If true, middle clicking on a scroll bar causes the slider to
+ jump to that position. If false, middle clicking is
+ ignored.
+
+ \value SH_ScrollBar_LeftClickAbsolutePosition A boolean value.
+ If true, left clicking on a scroll bar causes the slider to
+ jump to that position. If false, left clicking will
+ behave as appropriate for each control.
+
+ \value SH_ScrollBar_ScrollWhenPointerLeavesControl A boolean
+ value. If true, when clicking a scroll bar SubControl, holding
+ the mouse button down and moving the pointer outside the
+ SubControl, the scroll bar continues to scroll. If false, the
+ scollbar stops scrolling when the pointer leaves the
+ SubControl.
+
+ \value SH_ScrollBar_RollBetweenButtons A boolean value.
+ If true, when clicking a scroll bar button (SC_ScrollBarAddLine or
+ SC_ScrollBarSubLine) and dragging over to the opposite button (rolling)
+ will press the new button and release the old one. When it is false, the
+ original button is released and nothing happens (like a push button).
+
+ \value SH_TabBar_Alignment The alignment for tabs in a
+ QTabWidget. Possible values are Qt::AlignLeft,
+ Qt::AlignCenter and Qt::AlignRight.
+
+ \value SH_Header_ArrowAlignment The placement of the sorting
+ indicator may appear in list or table headers. Possible values
+ are Qt::Left or Qt::Right.
+
+ \value SH_Slider_SnapToValue Sliders snap to values while moving,
+ as they do on Windows.
+
+ \value SH_Slider_SloppyKeyEvents Key presses handled in a sloppy
+ manner, i.e., left on a vertical slider subtracts a line.
+
+ \value SH_ProgressDialog_CenterCancelButton Center button on
+ progress dialogs, like Motif, otherwise right aligned.
+
+ \value SH_ProgressDialog_TextLabelAlignment The alignment for text
+ labels in progress dialogs; Qt::AlignCenter on Windows,
+ Qt::AlignVCenter otherwise.
+
+ \value SH_PrintDialog_RightAlignButtons Right align buttons in
+ the print dialog, as done on Windows.
+
+ \value SH_MainWindow_SpaceBelowMenuBar One or two pixel space between
+ the menu bar and the dockarea, as done on Windows.
+
+ \value SH_FontDialog_SelectAssociatedText Select the text in the
+ line edit, or when selecting an item from the listbox, or when
+ the line edit receives focus, as done on Windows.
+
+ \value SH_Menu_KeyboardSearch Typing causes a menu to be search
+ for relevant items, otherwise only mnemnonic is considered.
+
+ \value SH_Menu_AllowActiveAndDisabled Allows disabled menu
+ items to be active.
+
+ \value SH_Menu_SpaceActivatesItem Pressing the space bar activates
+ the item, as done on Motif.
+
+ \value SH_Menu_SubMenuPopupDelay The number of milliseconds
+ to wait before opening a submenu (256 on Windows, 96 on Motif).
+
+ \value SH_Menu_Scrollable Whether popup menus must support scrolling.
+
+ \value SH_Menu_SloppySubMenus Whether popupmenu's must support
+ sloppy submenu; as implemented on Mac OS.
+
+ \value SH_ScrollView_FrameOnlyAroundContents Whether scrollviews
+ draw their frame only around contents (like Motif), or around
+ contents, scroll bars and corner widgets (like Windows).
+
+ \value SH_MenuBar_AltKeyNavigation Menu bars items are navigable
+ by pressing Alt, followed by using the arrow keys to select
+ the desired item.
+
+ \value SH_ComboBox_ListMouseTracking Mouse tracking in combobox
+ drop-down lists.
+
+ \value SH_Menu_MouseTracking Mouse tracking in popup menus.
+
+ \value SH_MenuBar_MouseTracking Mouse tracking in menu bars.
+
+ \value SH_Menu_FillScreenWithScroll Whether scrolling popups
+ should fill the screen as they are scrolled.
+
+ \value SH_Menu_SelectionWrap Whether popups should allow the selections
+ to wrap, that is when selection should the next item be the first item.
+
+ \value SH_ItemView_ChangeHighlightOnFocus Gray out selected items
+ when losing focus.
+
+ \value SH_Widget_ShareActivation Turn on sharing activation with
+ floating modeless dialogs.
+
+ \value SH_TabBar_SelectMouseType Which type of mouse event should
+ cause a tab to be selected.
+
+ \value SH_Q3ListViewExpand_SelectMouseType Which type of mouse event should
+ cause a list view expansion to be selected.
+
+ \value SH_TabBar_PreferNoArrows Whether a tab bar should suggest a size
+ to prevent scoll arrows.
+
+ \value SH_ComboBox_Popup Allows popups as a combobox drop-down
+ menu.
+
+ \value SH_Workspace_FillSpaceOnMaximize The workspace should
+ maximize the client area.
+
+ \value SH_TitleBar_NoBorder The title bar has no border.
+
+ \value SH_ScrollBar_StopMouseOverSlider Obsolete. Use
+ SH_Slider_StopMouseOverSlider instead.
+
+ \value SH_Slider_StopMouseOverSlider Stops auto-repeat when
+ the slider reaches the mouse position.
+
+ \value SH_BlinkCursorWhenTextSelected Whether cursor should blink
+ when text is selected.
+
+ \value SH_RichText_FullWidthSelection Whether richtext selections
+ should extend to the full width of the document.
+
+ \value SH_GroupBox_TextLabelVerticalAlignment How to vertically align a
+ group box's text label.
+
+ \value SH_GroupBox_TextLabelColor How to paint a group box's text label.
+
+ \value SH_DialogButtons_DefaultButton Which button gets the
+ default status in a dialog's button widget.
+
+ \value SH_ToolBox_SelectedPageTitleBold Boldness of the selected
+ page title in a QToolBox.
+
+ \value SH_LineEdit_PasswordCharacter The Unicode character to be
+ used for passwords.
+
+ \value SH_Table_GridLineColor The RGB value of the grid for a table.
+
+ \value SH_UnderlineShortcut Whether shortcuts are underlined.
+
+ \value SH_SpellCheckUnderlineStyle A
+ QTextCharFormat::UnderlineStyle value that specifies the way
+ misspelled words should be underlined.
+
+ \value SH_SpinBox_AnimateButton Animate a click when up or down is
+ pressed in a spin box.
+ \value SH_SpinBox_KeyPressAutoRepeatRate Auto-repeat interval for
+ spinbox key presses.
+ \value SH_SpinBox_ClickAutoRepeatRate Auto-repeat interval for
+ spinbox mouse clicks.
+ \value SH_SpinBox_ClickAutoRepeatThreshold Auto-repeat threshold for
+ spinbox mouse clicks.
+ \value SH_ToolTipLabel_Opacity An integer indicating the opacity for
+ the tip label, 0 is completely transparent, 255 is completely
+ opaque.
+ \value SH_DrawMenuBarSeparator Indicates whether or not the menu bar draws separators.
+ \value SH_TitleBar_ModifyNotification Indicates if the title bar should show
+ a '*' for windows that are modified.
+
+ \value SH_Button_FocusPolicy The default focus policy for buttons.
+
+ \value SH_CustomBase Base value for custom style hints.
+ Custom values must be greater than this value.
+
+ \value SH_MenuBar_DismissOnSecondClick A boolean indicating if a menu in
+ the menu bar should be dismissed when it is clicked on a second time. (Example:
+ Clicking and releasing on the File Menu in a menu bar and then
+ immediately clicking on the File Menu again.)
+
+ \value SH_MessageBox_UseBorderForButtonSpacing A boolean indicating what the to
+ use the border of the buttons (computed as half the button height) for the spacing
+ of the button in a message box.
+
+ \value SH_MessageBox_CenterButtons A boolean indicating whether the buttons in the
+ message box should be centered or not (see QDialogButtonBox::setCentered()).
+
+ \value SH_MessageBox_TextInteractionFlags A boolean indicating if
+ the text in a message box should allow user interfactions (e.g.
+ selection) or not.
+
+ \value SH_TitleBar_AutoRaise A boolean indicating whether
+ controls on a title bar ought to update when the mouse is over them.
+
+ \value SH_ToolButton_PopupDelay An int indicating the popup delay in milliseconds
+ for menus attached to tool buttons.
+
+ \value SH_FocusFrame_Mask The mask of the focus frame.
+
+ \value SH_RubberBand_Mask The mask of the rubber band.
+
+ \value SH_WindowFrame_Mask The mask of the window frame.
+
+ \value SH_SpinControls_DisableOnBounds Determines if the spin controls will shown
+ as disabled when reaching the spin range boundary.
+
+ \value SH_Dial_BackgroundRole Defines the style's preferred
+ background role (as QPalette::ColorRole) for a dial widget.
+
+ \value SH_ScrollBar_BackgroundMode The background mode for a scroll bar.
+
+ \value SH_ComboBox_LayoutDirection The layout direction for the
+ combo box. By default it should be the same as indicated by the
+ QStyleOption::direction variable.
+
+ \value SH_ItemView_EllipsisLocation The location where ellipses should be
+ added for item text that is too long to fit in an view item.
+
+ \value SH_ItemView_ShowDecorationSelected When an item in an item
+ view is selected, also highlight the branch or other decoration.
+
+ \value SH_ItemView_ActivateItemOnSingleClick Emit the activated signal
+ when the user single clicks on an item in an item in an item view.
+ Otherwise the signal is emitted when the user double clicks on an item.
+
+ \value SH_Slider_AbsoluteSetButtons Which mouse buttons cause a slider
+ to set the value to the position clicked on.
+
+ \value SH_Slider_PageSetButtons Which mouse buttons cause a slider
+ to page step the value.
+
+ \value SH_TabBar_ElideMode The default eliding style for a tab bar.
+
+ \value SH_DialogButtonLayout Controls how buttons are laid out in a QDialogButtonBox, returns a QDialogButtonBox::ButtonLayout enum.
+
+ \value SH_WizardStyle Controls the look and feel of a QWizard. Returns a QWizard::WizardStyle enum.
+
+ \value SH_FormLayoutWrapPolicy Provides a default for how rows are wrapped in a QFormLayout. Returns a QFormLayout::RowWrapPolicy enum.
+ \value SH_FormLayoutFieldGrowthPolicy Provides a default for how fields can grow in a QFormLayout. Returns a QFormLayout::FieldGrowthPolicy enum.
+ \value SH_FormLayoutFormAlignment Provides a default for how a QFormLayout aligns its contents within the available space. Returns a Qt::Alignment enum.
+ \value SH_FormLayoutLabelAlignment Provides a default for how a QFormLayout aligns labels within the available space. Returns a Qt::Alignment enum.
+
+ \value SH_ItemView_ArrowKeysNavigateIntoChildren Controls whether the tree view will select the first child when it is exapanded and the right arrow key is pressed.
+ \value SH_ComboBox_PopupFrameStyle The frame style used when drawing a combobox popup menu.
+
+ \value SH_DialogButtonBox_ButtonsHaveIcons Indicates whether or not StandardButtons in QDialogButtonBox should have icons or not.
+ \value SH_ItemView_MovementWithoutUpdatingSelection The item view is able to indicate a current item without changing the selection.
+ \value SH_ToolTip_Mask The mask of a tool tip.
+
+ \value SH_FocusFrame_AboveWidget The FocusFrame is stacked above the widget that it is "focusing on".
+
+ \value SH_TextControl_FocusIndicatorTextCharFormat Specifies the text format used to highlight focused anchors in rich text
+ documents displayed for example in QTextBrowser. The format has to be a QTextCharFormat returned in the variant of the
+ QStyleHintReturnVariant return value. The QTextFormat::OutlinePen property is used for the outline and QTextFormat::BackgroundBrush
+ for the background of the highlighted area.
+
+ \value SH_Menu_FlashTriggeredItem Flash triggered item.
+ \value SH_Menu_FadeOutOnHide Fade out the menu instead of hiding it immediately.
+
+ \value SH_TabWidget_DefaultTabPosition Default position of the tab bar in a tab widget.
+
+ \value SH_ToolBar_Movable Determines if the tool bar is movable by default.
+
+ \value SH_ItemView_PaintAlternatingRowColorsForEmptyArea Whether QTreeView paints alternating row colors for the area that does not have any items.
+
+ \value SH_Menu_Mask The mask for a popup menu.
+
+ \value SH_ItemView_DrawDelegateFrame Determines if there should be a frame for a delegate widget.
+
+ \value SH_TabBar_CloseButtonPosition Determines the position of the close button on a tab in a tab bar.
+
+ \value SH_DockWidget_ButtonsHaveFrame Determines if dockwidget buttons should have frames. Default is true.
+
+ \value SH_ToolButtonStyle Determines the default system style for tool buttons that uses Qt::ToolButtonFollowStyle.
+
+ \value SH_RequestSoftwareInputPanel Determines when a software input panel should
+ be requested by input widgets. Returns an enum of type QStyle::RequestSoftwareInputPanel.
+
+ \omitvalue SH_UnderlineAccelerator
+
+ \sa styleHint()
+*/
+
+/*!
+ \fn int QStyle::styleHint(StyleHint hint, const QStyleOption *option, \
+ const QWidget *widget, QStyleHintReturn *returnData) const
+
+ Returns an integer representing the specified style \a hint for
+ the given \a widget described by the provided style \a option.
+
+ \a returnData is used when the querying widget needs more detailed data than
+ the integer that styleHint() returns. See the QStyleHintReturn class
+ description for details.
+*/
+
+/*!
+ \enum QStyle::StandardPixmap
+
+ This enum describes the available standard pixmaps. A standard pixmap is a pixmap that
+ can follow some existing GUI style or guideline.
+
+ \value SP_TitleBarMinButton Minimize button on title bars (e.g.,
+ in QMdiSubWindow).
+ \value SP_TitleBarMenuButton Menu button on a title bar.
+ \value SP_TitleBarMaxButton Maximize button on title bars.
+ \value SP_TitleBarCloseButton Close button on title bars.
+ \value SP_TitleBarNormalButton Normal (restore) button on title bars.
+ \value SP_TitleBarShadeButton Shade button on title bars.
+ \value SP_TitleBarUnshadeButton Unshade button on title bars.
+ \value SP_TitleBarContextHelpButton The Context help button on title bars.
+ \value SP_MessageBoxInformation The "information" icon.
+ \value SP_MessageBoxWarning The "warning" icon.
+ \value SP_MessageBoxCritical The "critical" icon.
+ \value SP_MessageBoxQuestion The "question" icon.
+ \value SP_DesktopIcon The "desktop" icon.
+ \value SP_TrashIcon The "trash" icon.
+ \value SP_ComputerIcon The "My computer" icon.
+ \value SP_DriveFDIcon The floppy icon.
+ \value SP_DriveHDIcon The harddrive icon.
+ \value SP_DriveCDIcon The CD icon.
+ \value SP_DriveDVDIcon The DVD icon.
+ \value SP_DriveNetIcon The network icon.
+ \value SP_DirHomeIcon The home directory icon.
+ \value SP_DirOpenIcon The open directory icon.
+ \value SP_DirClosedIcon The closed directory icon.
+ \value SP_DirIcon The directory icon.
+ \value SP_DirLinkIcon The link to directory icon.
+ \value SP_FileIcon The file icon.
+ \value SP_FileLinkIcon The link to file icon.
+ \value SP_FileDialogStart The "start" icon in a file dialog.
+ \value SP_FileDialogEnd The "end" icon in a file dialog.
+ \value SP_FileDialogToParent The "parent directory" icon in a file dialog.
+ \value SP_FileDialogNewFolder The "create new folder" icon in a file dialog.
+ \value SP_FileDialogDetailedView The detailed view icon in a file dialog.
+ \value SP_FileDialogInfoView The file info icon in a file dialog.
+ \value SP_FileDialogContentsView The contents view icon in a file dialog.
+ \value SP_FileDialogListView The list view icon in a file dialog.
+ \value SP_FileDialogBack The back arrow in a file dialog.
+ \value SP_DockWidgetCloseButton Close button on dock windows (see also QDockWidget).
+ \value SP_ToolBarHorizontalExtensionButton Extension button for horizontal toolbars.
+ \value SP_ToolBarVerticalExtensionButton Extension button for vertical toolbars.
+ \value SP_DialogOkButton Icon for a standard OK button in a QDialogButtonBox.
+ \value SP_DialogCancelButton Icon for a standard Cancel button in a QDialogButtonBox.
+ \value SP_DialogHelpButton Icon for a standard Help button in a QDialogButtonBox.
+ \value SP_DialogOpenButton Icon for a standard Open button in a QDialogButtonBox.
+ \value SP_DialogSaveButton Icon for a standard Save button in a QDialogButtonBox.
+ \value SP_DialogCloseButton Icon for a standard Close button in a QDialogButtonBox.
+ \value SP_DialogApplyButton Icon for a standard Apply button in a QDialogButtonBox.
+ \value SP_DialogResetButton Icon for a standard Reset button in a QDialogButtonBox.
+ \value SP_DialogDiscardButton Icon for a standard Discard button in a QDialogButtonBox.
+ \value SP_DialogYesButton Icon for a standard Yes button in a QDialogButtonBox.
+ \value SP_DialogNoButton Icon for a standard No button in a QDialogButtonBox.
+ \value SP_ArrowUp Icon arrow pointing up.
+ \value SP_ArrowDown Icon arrow pointing down.
+ \value SP_ArrowLeft Icon arrow pointing left.
+ \value SP_ArrowRight Icon arrow pointing right.
+ \value SP_ArrowBack Equivalent to SP_ArrowLeft when the current layout direction is Qt::LeftToRight, otherwise SP_ArrowRight.
+ \value SP_ArrowForward Equivalent to SP_ArrowRight when the current layout direction is Qt::LeftToRight, otherwise SP_ArrowLeft.
+ \value SP_CommandLink Icon used to indicate a Vista style command link glyph.
+ \value SP_VistaShield Icon used to indicate UAC prompts on Windows Vista. This will return a null pixmap or icon on all other platforms.
+ \value SP_BrowserReload Icon indicating that the current page should be reloaded.
+ \value SP_BrowserStop Icon indicating that the page loading should stop.
+ \value SP_MediaPlay Icon indicating that media should begin playback.
+ \value SP_MediaStop Icon indicating that media should stop playback.
+ \value SP_MediaPause Icon indicating that media should pause playback.
+ \value SP_MediaSkipForward Icon indicating that media should skip forward.
+ \value SP_MediaSkipBackward Icon indicating that media should skip backward.
+ \value SP_MediaSeekForward Icon indicating that media should seek forward.
+ \value SP_MediaSeekBackward Icon indicating that media should seek backward.
+ \value SP_MediaVolume Icon indicating a volume control.
+ \value SP_MediaVolumeMuted Icon indicating a muted volume control.
+ \value SP_CustomBase Base value for custom standard pixmaps;
+ custom values must be greater than this value.
+
+ \sa standardIcon()
+*/
+
+/*!
+ \fn QPixmap QStyle::generatedIconPixmap(QIcon::Mode iconMode,
+ const QPixmap &pixmap, const QStyleOption *option) const
+
+ Returns a copy of the given \a pixmap, styled to conform to the
+ specified \a iconMode and taking into account the palette
+ specified by \a option.
+
+ The \a option parameter can pass extra information, but
+ it must contain a palette.
+
+ Note that not all pixmaps will conform, in which case the returned
+ pixmap is a plain copy.
+
+ \sa QIcon
+*/
+
+/*!
+ \fn QPixmap QStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *option, \
+ const QWidget *widget) const
+
+ \obsolete
+ Returns a pixmap for the given \a standardPixmap.
+
+ A standard pixmap is a pixmap that can follow some existing GUI
+ style or guideline. The \a option argument can be used to pass
+ extra information required when defining the appropriate
+ pixmap. The \a widget argument is optional and can also be used to
+ aid the determination of the pixmap.
+
+ Developers calling standardPixmap() should instead call standardIcon()
+ Developers who re-implemented standardPixmap() should instead re-implement
+ the slot standardIconImplementation().
+
+ \sa standardIcon()
+*/
+
+
+/*!
+ \fn QRect QStyle::visualRect(Qt::LayoutDirection direction, const QRect &boundingRectangle, const QRect &logicalRectangle)
+
+ Returns the given \a logicalRectangle converted to screen
+ coordinates based on the specified \a direction. The \a
+ boundingRectangle is used when performing the translation.
+
+ This function is provided to support right-to-left desktops, and
+ is typically used in implementations of the subControlRect()
+ function.
+
+ \sa QWidget::layoutDirection
+*/
+QRect QStyle::visualRect(Qt::LayoutDirection direction, const QRect &boundingRect, const QRect &logicalRect)
+{
+ if (direction == Qt::LeftToRight)
+ return logicalRect;
+ QRect rect = logicalRect;
+ rect.translate(2 * (boundingRect.right() - logicalRect.right()) +
+ logicalRect.width() - boundingRect.width(), 0);
+ return rect;
+}
+
+/*!
+ \fn QPoint QStyle::visualPos(Qt::LayoutDirection direction, const QRect &boundingRectangle, const QPoint &logicalPosition)
+
+ Returns the given \a logicalPosition converted to screen
+ coordinates based on the specified \a direction. The \a
+ boundingRectangle is used when performing the translation.
+
+ \sa QWidget::layoutDirection
+*/
+QPoint QStyle::visualPos(Qt::LayoutDirection direction, const QRect &boundingRect, const QPoint &logicalPos)
+{
+ if (direction == Qt::LeftToRight)
+ return logicalPos;
+ return QPoint(boundingRect.right() - logicalPos.x(), logicalPos.y());
+}
+
+/*!
+ Returns a new rectangle of the specified \a size that is aligned to the given \a
+ rectangle according to the specified \a alignment and \a direction.
+ */
+QRect QStyle::alignedRect(Qt::LayoutDirection direction, Qt::Alignment alignment, const QSize &size, const QRect &rectangle)
+{
+ alignment = visualAlignment(direction, alignment);
+ int x = rectangle.x();
+ int y = rectangle.y();
+ int w = size.width();
+ int h = size.height();
+ if ((alignment & Qt::AlignVCenter) == Qt::AlignVCenter)
+ y += rectangle.size().height()/2 - h/2;
+ else if ((alignment & Qt::AlignBottom) == Qt::AlignBottom)
+ y += rectangle.size().height() - h;
+ if ((alignment & Qt::AlignRight) == Qt::AlignRight)
+ x += rectangle.size().width() - w;
+ else if ((alignment & Qt::AlignHCenter) == Qt::AlignHCenter)
+ x += rectangle.size().width()/2 - w/2;
+ return QRect(x, y, w, h);
+}
+
+/*!
+ Transforms an \a alignment of Qt::AlignLeft or Qt::AlignRight
+ without Qt::AlignAbsolute into Qt::AlignLeft or Qt::AlignRight with
+ Qt::AlignAbsolute according to the layout \a direction. The other
+ alignment flags are left untouched.
+
+ If no horizontal alignment was specified, the function returns the
+ default alignment for the given layout \a direction.
+
+ QWidget::layoutDirection
+*/
+Qt::Alignment QStyle::visualAlignment(Qt::LayoutDirection direction, Qt::Alignment alignment)
+{
+ return QGuiApplicationPrivate::visualAlignment(direction, alignment);
+}
+
+/*!
+ Converts the given \a logicalValue to a pixel position. The \a min
+ parameter maps to 0, \a max maps to \a span and other values are
+ distributed evenly in-between.
+
+ This function can handle the entire integer range without
+ overflow, providing that \a span is less than 4096.
+
+ By default, this function assumes that the maximum value is on the
+ right for horizontal items and on the bottom for vertical items.
+ Set the \a upsideDown parameter to true to reverse this behavior.
+
+ \sa sliderValueFromPosition()
+*/
+
+int QStyle::sliderPositionFromValue(int min, int max, int logicalValue, int span, bool upsideDown)
+{
+ if (span <= 0 || logicalValue < min || max <= min)
+ return 0;
+ if (logicalValue > max)
+ return upsideDown ? span : min;
+
+ uint range = max - min;
+ uint p = upsideDown ? max - logicalValue : logicalValue - min;
+
+ if (range > (uint)INT_MAX/4096) {
+ double dpos = (double(p))/(double(range)/span);
+ return int(dpos);
+ } else if (range > (uint)span) {
+ return (2 * p * span + range) / (2*range);
+ } else {
+ uint div = span / range;
+ uint mod = span % range;
+ return p * div + (2 * p * mod + range) / (2 * range);
+ }
+ // equiv. to (p * span) / range + 0.5
+ // no overflow because of this implicit assumption:
+ // span <= 4096
+}
+
+/*!
+ \fn int QStyle::sliderValueFromPosition(int min, int max, int position, int span, bool upsideDown)
+
+ Converts the given pixel \a position to a logical value. 0 maps to
+ the \a min parameter, \a span maps to \a max and other values are
+ distributed evenly in-between.
+
+ This function can handle the entire integer range without
+ overflow.
+
+ By default, this function assumes that the maximum value is on the
+ right for horizontal items and on the bottom for vertical
+ items. Set the \a upsideDown parameter to true to reverse this
+ behavior.
+
+ \sa sliderPositionFromValue()
+*/
+
+int QStyle::sliderValueFromPosition(int min, int max, int pos, int span, bool upsideDown)
+{
+ if (span <= 0 || pos <= 0)
+ return upsideDown ? max : min;
+ if (pos >= span)
+ return upsideDown ? min : max;
+
+ uint range = max - min;
+
+ if ((uint)span > range) {
+ int tmp = (2 * pos * range + span) / (2 * span);
+ return upsideDown ? max - tmp : tmp + min;
+ } else {
+ uint div = range / span;
+ uint mod = range % span;
+ int tmp = pos * div + (2 * pos * mod + span) / (2 * span);
+ return upsideDown ? max - tmp : tmp + min;
+ }
+ // equiv. to min + (pos*range)/span + 0.5
+ // no overflow because of this implicit assumption:
+ // pos <= span < sqrt(INT_MAX+0.0625)+0.25 ~ sqrt(INT_MAX)
+}
+
+/*!
+ Returns the style's standard palette.
+
+ Note that on systems that support system colors, the style's
+ standard palette is not used. In particular, the Windows XP,
+ Vista, and Mac styles do not use the standard palette, but make
+ use of native theme engines. With these styles, you should not set
+ the palette with QApplication::setStandardPalette().
+
+ */
+QPalette QStyle::standardPalette() const
+{
+#ifdef Q_WS_X11
+ QColor background;
+ if (QX11Info::appDepth() > 8)
+ background = QColor(0xd4, 0xd0, 0xc8); // win 2000 grey
+ else
+ background = QColor(192, 192, 192);
+#else
+ QColor background(0xd4, 0xd0, 0xc8); // win 2000 grey
+#endif
+ QColor light(background.lighter());
+ QColor dark(background.darker());
+ QColor mid(Qt::gray);
+ QPalette palette(Qt::black, background, light, dark, mid, Qt::black, Qt::white);
+ palette.setBrush(QPalette::Disabled, QPalette::WindowText, dark);
+ palette.setBrush(QPalette::Disabled, QPalette::Text, dark);
+ palette.setBrush(QPalette::Disabled, QPalette::ButtonText, dark);
+ palette.setBrush(QPalette::Disabled, QPalette::Base, background);
+ return palette;
+}
+
+/*!
+ \since 4.1
+
+ Returns an icon for the given \a standardIcon.
+
+ The \a standardIcon is a standard pixmap which can follow some
+ existing GUI style or guideline. The \a option argument can be
+ used to pass extra information required when defining the
+ appropriate icon. The \a widget argument is optional and can also
+ be used to aid the determination of the icon.
+
+ \warning Because of binary compatibility constraints, this
+ function is not virtual. If you want to provide your own icons in
+ a QStyle subclass, reimplement the standardIconImplementation()
+ slot in your subclass instead. The standardIcon() function will
+ dynamically detect the slot and call it.
+
+ \sa standardIconImplementation()
+*/
+QIcon QStyle::standardIcon(StandardPixmap standardIcon, const QStyleOption *option,
+ const QWidget *widget) const
+{
+ QIcon result;
+ // ### Qt 4.1: invokeMethod should accept const functions, to avoid this dirty cast
+ QMetaObject::invokeMethod(const_cast<QStyle*>(this),
+ "standardIconImplementation", Qt::DirectConnection,
+ Q_RETURN_ARG(QIcon, result),
+ Q_ARG(StandardPixmap, standardIcon),
+ Q_ARG(const QStyleOption*, option),
+ Q_ARG(const QWidget*, widget));
+ return result;
+}
+
+/*!
+ \since 4.1
+
+ Returns an icon for the given \a standardIcon.
+
+ Reimplement this slot to provide your own icons in a QStyle
+ subclass; because of binary compatibility constraints, the
+ standardIcon() function (introduced in Qt 4.1) is not
+ virtual. Instead, standardIcon() will dynamically detect and call
+ \e this slot.
+
+ The \a standardIcon is a standard pixmap which can follow some
+ existing GUI style or guideline. The \a option argument can be
+ used to pass extra information required when defining the
+ appropriate icon. The \a widget argument is optional and can also
+ be used to aid the determination of the icon.
+
+ \sa standardIcon()
+*/
+QIcon QStyle::standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *option,
+ const QWidget *widget) const
+{
+ return QIcon(standardPixmap(standardIcon, option, widget));
+}
+
+/*!
+ \since 4.3
+
+ Returns the spacing that should be used between \a control1 and
+ \a control2 in a layout. \a orientation specifies whether the
+ controls are laid out side by side or stacked vertically. The \a
+ option parameter can be used to pass extra information about the
+ parent widget. The \a widget parameter is optional and can also
+ be used if \a option is 0.
+
+ This function is called by the layout system. It is used only if
+ PM_LayoutHorizontalSpacing or PM_LayoutVerticalSpacing returns a
+ negative value.
+
+ For binary compatibility reasons, this function is not virtual.
+ If you want to specify custom layout spacings in a QStyle
+ subclass, implement a slot called layoutSpacingImplementation().
+ QStyle will discover the slot at run-time (using Qt's
+ \l{meta-object system}) and direct all calls to layoutSpacing()
+ to layoutSpacingImplementation().
+
+ \sa combinedLayoutSpacing(), layoutSpacingImplementation()
+*/
+int QStyle::layoutSpacing(QSizePolicy::ControlType control1, QSizePolicy::ControlType control2,
+ Qt::Orientation orientation, const QStyleOption *option,
+ const QWidget *widget) const
+{
+ Q_D(const QStyle);
+ if (d->layoutSpacingIndex == -1) {
+ d->layoutSpacingIndex = metaObject()->indexOfMethod(
+ "layoutSpacingImplementation(QSizePolicy::ControlType,QSizePolicy::ControlType,"
+ "Qt::Orientation,const QStyleOption*,const QWidget*)"
+ );
+ }
+ if (d->layoutSpacingIndex < 0)
+ return -1;
+ int result = -1;
+ void *param[] = {&result, &control1, &control2, &orientation, &option, &widget};
+
+ const_cast<QStyle *>(this)->qt_metacall(QMetaObject::InvokeMetaMethod,
+ d->layoutSpacingIndex, param);
+ return result;
+}
+
+/*!
+ \since 4.3
+
+ Returns the spacing that should be used between \a controls1 and
+ \a controls2 in a layout. \a orientation specifies whether the
+ controls are laid out side by side or stacked vertically. The \a
+ option parameter can be used to pass extra information about the
+ parent widget. The \a widget parameter is optional and can also
+ be used if \a option is 0.
+
+ \a controls1 and \a controls2 are OR-combination of zero or more
+ \l{QSizePolicy::ControlTypes}{control types}.
+
+ This function is called by the layout system. It is used only if
+ PM_LayoutHorizontalSpacing or PM_LayoutVerticalSpacing returns a
+ negative value.
+
+ \sa layoutSpacing(), layoutSpacingImplementation()
+*/
+int QStyle::combinedLayoutSpacing(QSizePolicy::ControlTypes controls1,
+ QSizePolicy::ControlTypes controls2, Qt::Orientation orientation,
+ QStyleOption *option, QWidget *widget) const
+{
+ QSizePolicy::ControlType array1[MaxBits];
+ QSizePolicy::ControlType array2[MaxBits];
+ int count1 = unpackControlTypes(controls1, array1);
+ int count2 = unpackControlTypes(controls2, array2);
+ int result = -1;
+
+ for (int i = 0; i < count1; ++i) {
+ for (int j = 0; j < count2; ++j) {
+ int spacing = layoutSpacing(array1[i], array2[j], orientation, option, widget);
+ result = qMax(spacing, result);
+ }
+ }
+ return result;
+}
+
+/*!
+ \since 4.3
+
+ This slot is called by layoutSpacing() to determine the spacing
+ that should be used between \a control1 and \a control2 in a
+ layout. \a orientation specifies whether the controls are laid
+ out side by side or stacked vertically. The \a option parameter
+ can be used to pass extra information about the parent widget.
+ The \a widget parameter is optional and can also be used if \a
+ option is 0.
+
+ If you want to provide custom layout spacings in a QStyle
+ subclass, implement a slot called layoutSpacingImplementation()
+ in your subclass. Be aware that this slot will only be called if
+ PM_LayoutHorizontalSpacing or PM_LayoutVerticalSpacing returns a
+ negative value.
+
+ The default implementation returns -1.
+
+ \sa layoutSpacing(), combinedLayoutSpacing()
+*/
+int QStyle::layoutSpacingImplementation(QSizePolicy::ControlType /* control1 */,
+ QSizePolicy::ControlType /* control2 */,
+ Qt::Orientation /*orientation*/,
+ const QStyleOption * /* option */,
+ const QWidget * /* widget */) const
+{
+ return -1;
+}
+
+QT_BEGIN_INCLUDE_NAMESPACE
+#include <QDebug>
+QT_END_INCLUDE_NAMESPACE
+
+#if !defined(QT_NO_DEBUG_STREAM)
+QDebug operator<<(QDebug debug, QStyle::State state)
+{
+#if !defined(QT_NO_DEBUG)
+ debug << "QStyle::State(";
+
+ QStringList states;
+ if (state & QStyle::State_Active) states << QLatin1String("Active");
+ if (state & QStyle::State_AutoRaise) states << QLatin1String("AutoRaise");
+ if (state & QStyle::State_Bottom) states << QLatin1String("Bottom");
+ if (state & QStyle::State_Children) states << QLatin1String("Children");
+ if (state & QStyle::State_DownArrow) states << QLatin1String("DownArrow");
+ if (state & QStyle::State_Editing) states << QLatin1String("Editing");
+ if (state & QStyle::State_Enabled) states << QLatin1String("Enabled");
+ if (state & QStyle::State_FocusAtBorder) states << QLatin1String("FocusAtBorder");
+ if (state & QStyle::State_HasFocus) states << QLatin1String("HasFocus");
+ if (state & QStyle::State_Horizontal) states << QLatin1String("Horizontal");
+ if (state & QStyle::State_Item) states << QLatin1String("Item");
+ if (state & QStyle::State_KeyboardFocusChange) states << QLatin1String("KeyboardFocusChange");
+ if (state & QStyle::State_MouseOver) states << QLatin1String("MouseOver");
+ if (state & QStyle::State_NoChange) states << QLatin1String("NoChange");
+ if (state & QStyle::State_Off) states << QLatin1String("Off");
+ if (state & QStyle::State_On) states << QLatin1String("On");
+ if (state & QStyle::State_Open) states << QLatin1String("Open");
+ if (state & QStyle::State_Raised) states << QLatin1String("Raised");
+ if (state & QStyle::State_ReadOnly) states << QLatin1String("ReadOnly");
+ if (state & QStyle::State_Selected) states << QLatin1String("Selected");
+ if (state & QStyle::State_Sibling) states << QLatin1String("Sibling");
+ if (state & QStyle::State_Sunken) states << QLatin1String("Sunken");
+ if (state & QStyle::State_Top) states << QLatin1String("Top");
+ if (state & QStyle::State_UpArrow) states << QLatin1String("UpArrow");
+
+ qSort(states);
+ debug << states.join(QLatin1String(" | "));
+ debug << ')';
+#else
+ Q_UNUSED(state);
+#endif
+ return debug;
+}
+#endif
+
+/*!
+ \since 4.6
+
+ \fn const QStyle *QStyle::proxy() const
+
+ This function returns the current proxy for this style.
+ By default most styles will return themselves. However
+ when a proxy style is in use, it will allow the style to
+ call back into its proxy.
+*/
+const QStyle * QStyle::proxy() const
+{
+ Q_D(const QStyle);
+ return d->proxyStyle;
+}
+
+/* \internal
+
+ This function sets the base style that style calls will be
+ redirected to. Note that ownership is not transferred.
+*/
+void QStyle::setProxy(QStyle *style)
+{
+ Q_D(QStyle);
+ d->proxyStyle = style;
+}
+
+QT_END_NAMESPACE
diff --git a/src/widgets/styles/qstyle.h b/src/widgets/styles/qstyle.h
new file mode 100644
index 0000000000..1896f129e1
--- /dev/null
+++ b/src/widgets/styles/qstyle.h
@@ -0,0 +1,889 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSTYLE_H
+#define QSTYLE_H
+
+#include <QtCore/qobject.h>
+#include <QtCore/qrect.h>
+#include <QtCore/qsize.h>
+#include <QtWidgets/qicon.h>
+#include <QtGui/qpixmap.h>
+#include <QtGui/qpalette.h>
+#include <QtWidgets/qsizepolicy.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QAction;
+class QDebug;
+class QTab;
+class QFontMetrics;
+class QStyleHintReturn;
+class QStyleOption;
+class QStyleOptionComplex;
+class QStylePrivate;
+
+class Q_WIDGETS_EXPORT QStyle : public QObject
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QStyle)
+
+protected:
+ QStyle(QStylePrivate &dd);
+
+public:
+ QStyle();
+ virtual ~QStyle();
+
+ virtual void polish(QWidget *);
+ virtual void unpolish(QWidget *);
+
+ virtual void polish(QApplication *);
+ virtual void unpolish(QApplication *);
+
+ virtual void polish(QPalette &);
+
+ virtual QRect itemTextRect(const QFontMetrics &fm, const QRect &r,
+ int flags, bool enabled,
+ const QString &text) const;
+
+ virtual QRect itemPixmapRect(const QRect &r, int flags, const QPixmap &pixmap) const;
+
+ virtual void drawItemText(QPainter *painter, const QRect &rect,
+ int flags, const QPalette &pal, bool enabled,
+ const QString &text, QPalette::ColorRole textRole = QPalette::NoRole) const;
+
+ virtual void drawItemPixmap(QPainter *painter, const QRect &rect,
+ int alignment, const QPixmap &pixmap) const;
+
+ virtual QPalette standardPalette() const;
+
+ enum StateFlag {
+ State_None = 0x00000000,
+#ifdef QT3_SUPPORT
+ State_Default = State_None,
+#endif
+ State_Enabled = 0x00000001,
+ State_Raised = 0x00000002,
+ State_Sunken = 0x00000004,
+ State_Off = 0x00000008,
+ State_NoChange = 0x00000010,
+ State_On = 0x00000020,
+ State_DownArrow = 0x00000040,
+ State_Horizontal = 0x00000080,
+ State_HasFocus = 0x00000100,
+ State_Top = 0x00000200,
+ State_Bottom = 0x00000400,
+ State_FocusAtBorder = 0x00000800,
+ State_AutoRaise = 0x00001000,
+ State_MouseOver = 0x00002000,
+ State_UpArrow = 0x00004000,
+ State_Selected = 0x00008000,
+ State_Active = 0x00010000,
+ State_Window = 0x00020000,
+ State_Open = 0x00040000,
+ State_Children = 0x00080000,
+ State_Item = 0x00100000,
+ State_Sibling = 0x00200000,
+ State_Editing = 0x00400000,
+ State_KeyboardFocusChange = 0x00800000,
+#ifdef QT_KEYPAD_NAVIGATION
+ State_HasEditFocus = 0x01000000,
+#endif
+ State_ReadOnly = 0x02000000,
+ State_Small = 0x04000000,
+ State_Mini = 0x08000000
+ };
+ Q_DECLARE_FLAGS(State, StateFlag)
+
+#ifdef QT3_SUPPORT
+ typedef State SFlags;
+#endif
+
+ enum PrimitiveElement {
+ PE_Q3CheckListController,
+ PE_Q3CheckListExclusiveIndicator,
+ PE_Q3CheckListIndicator,
+ PE_Q3DockWindowSeparator,
+ PE_Q3Separator,
+
+ PE_Frame,
+ PE_FrameDefaultButton,
+ PE_FrameDockWidget,
+ PE_FrameFocusRect,
+ PE_FrameGroupBox,
+ PE_FrameLineEdit,
+ PE_FrameMenu,
+ PE_FrameStatusBar, // obsolete
+ PE_FrameStatusBarItem = PE_FrameStatusBar,
+ PE_FrameTabWidget,
+ PE_FrameWindow,
+ PE_FrameButtonBevel,
+ PE_FrameButtonTool,
+ PE_FrameTabBarBase,
+
+ PE_PanelButtonCommand,
+ PE_PanelButtonBevel,
+ PE_PanelButtonTool,
+ PE_PanelMenuBar,
+ PE_PanelToolBar,
+ PE_PanelLineEdit,
+
+ PE_IndicatorArrowDown,
+ PE_IndicatorArrowLeft,
+ PE_IndicatorArrowRight,
+ PE_IndicatorArrowUp,
+ PE_IndicatorBranch,
+ PE_IndicatorButtonDropDown,
+ PE_IndicatorViewItemCheck,
+ PE_IndicatorItemViewItemCheck = PE_IndicatorViewItemCheck,
+ PE_IndicatorCheckBox,
+ PE_IndicatorDockWidgetResizeHandle,
+ PE_IndicatorHeaderArrow,
+ PE_IndicatorMenuCheckMark,
+ PE_IndicatorProgressChunk,
+ PE_IndicatorRadioButton,
+ PE_IndicatorSpinDown,
+ PE_IndicatorSpinMinus,
+ PE_IndicatorSpinPlus,
+ PE_IndicatorSpinUp,
+ PE_IndicatorToolBarHandle,
+ PE_IndicatorToolBarSeparator,
+ PE_PanelTipLabel,
+ PE_IndicatorTabTear,
+ PE_PanelScrollAreaCorner,
+
+ PE_Widget,
+
+ PE_IndicatorColumnViewArrow,
+ PE_IndicatorItemViewItemDrop,
+
+ PE_PanelItemViewItem,
+ PE_PanelItemViewRow, // ### Qt 5: remove
+
+ PE_PanelStatusBar,
+
+ PE_IndicatorTabClose,
+ PE_PanelMenu,
+
+ // do not add any values below/greater this
+ PE_CustomBase = 0xf000000
+ };
+
+ virtual void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p,
+ const QWidget *w = 0) const = 0;
+ enum ControlElement {
+ CE_PushButton,
+ CE_PushButtonBevel,
+ CE_PushButtonLabel,
+
+ CE_CheckBox,
+ CE_CheckBoxLabel,
+
+ CE_RadioButton,
+ CE_RadioButtonLabel,
+
+ CE_TabBarTab,
+ CE_TabBarTabShape,
+ CE_TabBarTabLabel,
+
+ CE_ProgressBar,
+ CE_ProgressBarGroove,
+ CE_ProgressBarContents,
+ CE_ProgressBarLabel,
+
+ CE_MenuItem,
+ CE_MenuScroller,
+ CE_MenuVMargin,
+ CE_MenuHMargin,
+ CE_MenuTearoff,
+ CE_MenuEmptyArea,
+
+ CE_MenuBarItem,
+ CE_MenuBarEmptyArea,
+
+ CE_ToolButtonLabel,
+
+ CE_Header,
+ CE_HeaderSection,
+ CE_HeaderLabel,
+
+ CE_Q3DockWindowEmptyArea,
+ CE_ToolBoxTab,
+ CE_SizeGrip,
+ CE_Splitter,
+ CE_RubberBand,
+ CE_DockWidgetTitle,
+
+ CE_ScrollBarAddLine,
+ CE_ScrollBarSubLine,
+ CE_ScrollBarAddPage,
+ CE_ScrollBarSubPage,
+ CE_ScrollBarSlider,
+ CE_ScrollBarFirst,
+ CE_ScrollBarLast,
+
+ CE_FocusFrame,
+ CE_ComboBoxLabel,
+
+ CE_ToolBar,
+ CE_ToolBoxTabShape,
+ CE_ToolBoxTabLabel,
+ CE_HeaderEmptyArea,
+
+ CE_ColumnViewGrip,
+
+ CE_ItemViewItem,
+
+ CE_ShapedFrame,
+
+ // do not add any values below/greater than this
+ CE_CustomBase = 0xf0000000
+ };
+
+ virtual void drawControl(ControlElement element, const QStyleOption *opt, QPainter *p,
+ const QWidget *w = 0) const = 0;
+
+ enum SubElement {
+ SE_PushButtonContents,
+ SE_PushButtonFocusRect,
+
+ SE_CheckBoxIndicator,
+ SE_CheckBoxContents,
+ SE_CheckBoxFocusRect,
+ SE_CheckBoxClickRect,
+
+ SE_RadioButtonIndicator,
+ SE_RadioButtonContents,
+ SE_RadioButtonFocusRect,
+ SE_RadioButtonClickRect,
+
+ SE_ComboBoxFocusRect,
+
+ SE_SliderFocusRect,
+
+ SE_Q3DockWindowHandleRect,
+
+ SE_ProgressBarGroove,
+ SE_ProgressBarContents,
+ SE_ProgressBarLabel,
+
+ // ### Qt 5: These values are unused; eliminate them
+ SE_DialogButtonAccept,
+ SE_DialogButtonReject,
+ SE_DialogButtonApply,
+ SE_DialogButtonHelp,
+ SE_DialogButtonAll,
+ SE_DialogButtonAbort,
+ SE_DialogButtonIgnore,
+ SE_DialogButtonRetry,
+ SE_DialogButtonCustom,
+
+ SE_ToolBoxTabContents,
+
+ SE_HeaderLabel,
+ SE_HeaderArrow,
+
+ SE_TabWidgetTabBar,
+ SE_TabWidgetTabPane,
+ SE_TabWidgetTabContents,
+ SE_TabWidgetLeftCorner,
+ SE_TabWidgetRightCorner,
+
+ SE_ViewItemCheckIndicator,
+ SE_ItemViewItemCheckIndicator = SE_ViewItemCheckIndicator,
+
+ SE_TabBarTearIndicator,
+
+ SE_TreeViewDisclosureItem,
+
+ SE_LineEditContents,
+ SE_FrameContents,
+
+ SE_DockWidgetCloseButton,
+ SE_DockWidgetFloatButton,
+ SE_DockWidgetTitleBarText,
+ SE_DockWidgetIcon,
+
+ SE_CheckBoxLayoutItem,
+ SE_ComboBoxLayoutItem,
+ SE_DateTimeEditLayoutItem,
+ SE_DialogButtonBoxLayoutItem, // ### remove
+ SE_LabelLayoutItem,
+ SE_ProgressBarLayoutItem,
+ SE_PushButtonLayoutItem,
+ SE_RadioButtonLayoutItem,
+ SE_SliderLayoutItem,
+ SE_SpinBoxLayoutItem,
+ SE_ToolButtonLayoutItem,
+
+ SE_FrameLayoutItem,
+ SE_GroupBoxLayoutItem,
+ SE_TabWidgetLayoutItem,
+
+ SE_ItemViewItemDecoration,
+ SE_ItemViewItemText,
+ SE_ItemViewItemFocusRect,
+
+ SE_TabBarTabLeftButton,
+ SE_TabBarTabRightButton,
+ SE_TabBarTabText,
+
+ SE_ShapedFrameContents,
+
+ SE_ToolBarHandle,
+
+ // do not add any values below/greater than this
+ SE_CustomBase = 0xf0000000
+ };
+
+ virtual QRect subElementRect(SubElement subElement, const QStyleOption *option,
+ const QWidget *widget = 0) const = 0;
+
+
+ enum ComplexControl {
+ CC_SpinBox,
+ CC_ComboBox,
+ CC_ScrollBar,
+ CC_Slider,
+ CC_ToolButton,
+ CC_TitleBar,
+ CC_Q3ListView,
+ CC_Dial,
+ CC_GroupBox,
+ CC_MdiControls,
+
+ // do not add any values below/greater than this
+ CC_CustomBase = 0xf0000000
+ };
+
+ enum SubControl {
+ SC_None = 0x00000000,
+
+ SC_ScrollBarAddLine = 0x00000001,
+ SC_ScrollBarSubLine = 0x00000002,
+ SC_ScrollBarAddPage = 0x00000004,
+ SC_ScrollBarSubPage = 0x00000008,
+ SC_ScrollBarFirst = 0x00000010,
+ SC_ScrollBarLast = 0x00000020,
+ SC_ScrollBarSlider = 0x00000040,
+ SC_ScrollBarGroove = 0x00000080,
+
+ SC_SpinBoxUp = 0x00000001,
+ SC_SpinBoxDown = 0x00000002,
+ SC_SpinBoxFrame = 0x00000004,
+ SC_SpinBoxEditField = 0x00000008,
+
+ SC_ComboBoxFrame = 0x00000001,
+ SC_ComboBoxEditField = 0x00000002,
+ SC_ComboBoxArrow = 0x00000004,
+ SC_ComboBoxListBoxPopup = 0x00000008,
+
+ SC_SliderGroove = 0x00000001,
+ SC_SliderHandle = 0x00000002,
+ SC_SliderTickmarks = 0x00000004,
+
+ SC_ToolButton = 0x00000001,
+ SC_ToolButtonMenu = 0x00000002,
+
+ SC_TitleBarSysMenu = 0x00000001,
+ SC_TitleBarMinButton = 0x00000002,
+ SC_TitleBarMaxButton = 0x00000004,
+ SC_TitleBarCloseButton = 0x00000008,
+ SC_TitleBarNormalButton = 0x00000010,
+ SC_TitleBarShadeButton = 0x00000020,
+ SC_TitleBarUnshadeButton = 0x00000040,
+ SC_TitleBarContextHelpButton = 0x00000080,
+ SC_TitleBarLabel = 0x00000100,
+
+ SC_Q3ListView = 0x00000001,
+ SC_Q3ListViewBranch = 0x00000002,
+ SC_Q3ListViewExpand = 0x00000004,
+
+ SC_DialGroove = 0x00000001,
+ SC_DialHandle = 0x00000002,
+ SC_DialTickmarks = 0x00000004,
+
+ SC_GroupBoxCheckBox = 0x00000001,
+ SC_GroupBoxLabel = 0x00000002,
+ SC_GroupBoxContents = 0x00000004,
+ SC_GroupBoxFrame = 0x00000008,
+
+ SC_MdiMinButton = 0x00000001,
+ SC_MdiNormalButton = 0x00000002,
+ SC_MdiCloseButton = 0x00000004,
+
+ SC_CustomBase = 0xf0000000,
+ SC_All = 0xffffffff
+ };
+ Q_DECLARE_FLAGS(SubControls, SubControl)
+
+#ifdef QT3_SUPPORT
+ typedef SubControls SCFlags;
+#endif
+
+ virtual void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p,
+ const QWidget *widget = 0) const = 0;
+ virtual SubControl hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt,
+ const QPoint &pt, const QWidget *widget = 0) const = 0;
+ virtual QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt,
+ SubControl sc, const QWidget *widget = 0) const = 0;
+
+ enum PixelMetric {
+ PM_ButtonMargin,
+ PM_ButtonDefaultIndicator,
+ PM_MenuButtonIndicator,
+ PM_ButtonShiftHorizontal,
+ PM_ButtonShiftVertical,
+
+ PM_DefaultFrameWidth,
+ PM_SpinBoxFrameWidth,
+ PM_ComboBoxFrameWidth,
+
+ PM_MaximumDragDistance,
+
+ PM_ScrollBarExtent,
+ PM_ScrollBarSliderMin,
+
+ PM_SliderThickness, // total slider thickness
+ PM_SliderControlThickness, // thickness of the business part
+ PM_SliderLength, // total length of slider
+ PM_SliderTickmarkOffset, //
+ PM_SliderSpaceAvailable, // available space for slider to move
+
+ PM_DockWidgetSeparatorExtent,
+ PM_DockWidgetHandleExtent,
+ PM_DockWidgetFrameWidth,
+
+ PM_TabBarTabOverlap,
+ PM_TabBarTabHSpace,
+ PM_TabBarTabVSpace,
+ PM_TabBarBaseHeight,
+ PM_TabBarBaseOverlap,
+
+ PM_ProgressBarChunkWidth,
+
+ PM_SplitterWidth,
+ PM_TitleBarHeight,
+
+ PM_MenuScrollerHeight,
+ PM_MenuHMargin,
+ PM_MenuVMargin,
+ PM_MenuPanelWidth,
+ PM_MenuTearoffHeight,
+ PM_MenuDesktopFrameWidth,
+
+ PM_MenuBarPanelWidth,
+ PM_MenuBarItemSpacing,
+ PM_MenuBarVMargin,
+ PM_MenuBarHMargin,
+
+ PM_IndicatorWidth,
+ PM_IndicatorHeight,
+ PM_ExclusiveIndicatorWidth,
+ PM_ExclusiveIndicatorHeight,
+ PM_CheckListButtonSize,
+ PM_CheckListControllerSize,
+
+ PM_DialogButtonsSeparator,
+ PM_DialogButtonsButtonWidth,
+ PM_DialogButtonsButtonHeight,
+
+ PM_MdiSubWindowFrameWidth,
+ PM_MDIFrameWidth = PM_MdiSubWindowFrameWidth, //obsolete
+ PM_MdiSubWindowMinimizedWidth,
+ PM_MDIMinimizedWidth = PM_MdiSubWindowMinimizedWidth, //obsolete
+
+ PM_HeaderMargin,
+ PM_HeaderMarkSize,
+ PM_HeaderGripMargin,
+ PM_TabBarTabShiftHorizontal,
+ PM_TabBarTabShiftVertical,
+ PM_TabBarScrollButtonWidth,
+
+ PM_ToolBarFrameWidth,
+ PM_ToolBarHandleExtent,
+ PM_ToolBarItemSpacing,
+ PM_ToolBarItemMargin,
+ PM_ToolBarSeparatorExtent,
+ PM_ToolBarExtensionExtent,
+
+ PM_SpinBoxSliderHeight,
+
+ PM_DefaultTopLevelMargin,
+ PM_DefaultChildMargin,
+ PM_DefaultLayoutSpacing,
+
+ PM_ToolBarIconSize,
+ PM_ListViewIconSize,
+ PM_IconViewIconSize,
+ PM_SmallIconSize,
+ PM_LargeIconSize,
+
+ PM_FocusFrameVMargin,
+ PM_FocusFrameHMargin,
+
+ PM_ToolTipLabelFrameWidth,
+ PM_CheckBoxLabelSpacing,
+ PM_TabBarIconSize,
+ PM_SizeGripSize,
+ PM_DockWidgetTitleMargin,
+ PM_MessageBoxIconSize,
+ PM_ButtonIconSize,
+
+ PM_DockWidgetTitleBarButtonMargin,
+
+ PM_RadioButtonLabelSpacing,
+ PM_LayoutLeftMargin,
+ PM_LayoutTopMargin,
+ PM_LayoutRightMargin,
+ PM_LayoutBottomMargin,
+ PM_LayoutHorizontalSpacing,
+ PM_LayoutVerticalSpacing,
+ PM_TabBar_ScrollButtonOverlap,
+
+ PM_TextCursorWidth,
+
+ PM_TabCloseIndicatorWidth,
+ PM_TabCloseIndicatorHeight,
+
+ PM_ScrollView_ScrollBarSpacing,
+ PM_SubMenuOverlap,
+
+ // do not add any values below/greater than this
+ PM_CustomBase = 0xf0000000
+ };
+
+ virtual int pixelMetric(PixelMetric metric, const QStyleOption *option = 0,
+ const QWidget *widget = 0) const = 0;
+
+ enum ContentsType {
+ CT_PushButton,
+ CT_CheckBox,
+ CT_RadioButton,
+ CT_ToolButton,
+ CT_ComboBox,
+ CT_Splitter,
+ CT_Q3DockWindow,
+ CT_ProgressBar,
+ CT_MenuItem,
+ CT_MenuBarItem,
+ CT_MenuBar,
+ CT_Menu,
+ CT_TabBarTab,
+ CT_Slider,
+ CT_ScrollBar,
+ CT_Q3Header,
+ CT_LineEdit,
+ CT_SpinBox,
+ CT_SizeGrip,
+ CT_TabWidget,
+ CT_DialogButtons,
+ CT_HeaderSection,
+ CT_GroupBox,
+ CT_MdiControls,
+ CT_ItemViewItem,
+ // do not add any values below/greater than this
+ CT_CustomBase = 0xf0000000
+ };
+
+ virtual QSize sizeFromContents(ContentsType ct, const QStyleOption *opt,
+ const QSize &contentsSize, const QWidget *w = 0) const = 0;
+
+ enum RequestSoftwareInputPanel {
+ RSIP_OnMouseClickAndAlreadyFocused,
+ RSIP_OnMouseClick
+ };
+
+ enum StyleHint {
+ SH_EtchDisabledText,
+ SH_DitherDisabledText,
+ SH_ScrollBar_MiddleClickAbsolutePosition,
+ SH_ScrollBar_ScrollWhenPointerLeavesControl,
+ SH_TabBar_SelectMouseType,
+ SH_TabBar_Alignment,
+ SH_Header_ArrowAlignment,
+ SH_Slider_SnapToValue,
+ SH_Slider_SloppyKeyEvents,
+ SH_ProgressDialog_CenterCancelButton,
+ SH_ProgressDialog_TextLabelAlignment,
+ SH_PrintDialog_RightAlignButtons,
+ SH_MainWindow_SpaceBelowMenuBar,
+ SH_FontDialog_SelectAssociatedText,
+ SH_Menu_AllowActiveAndDisabled,
+ SH_Menu_SpaceActivatesItem,
+ SH_Menu_SubMenuPopupDelay,
+ SH_ScrollView_FrameOnlyAroundContents,
+ SH_MenuBar_AltKeyNavigation,
+ SH_ComboBox_ListMouseTracking,
+ SH_Menu_MouseTracking,
+ SH_MenuBar_MouseTracking,
+ SH_ItemView_ChangeHighlightOnFocus,
+ SH_Widget_ShareActivation,
+ SH_Workspace_FillSpaceOnMaximize,
+ SH_ComboBox_Popup,
+ SH_TitleBar_NoBorder,
+ SH_Slider_StopMouseOverSlider,
+ SH_ScrollBar_StopMouseOverSlider = SH_Slider_StopMouseOverSlider, // obsolete
+ SH_BlinkCursorWhenTextSelected,
+ SH_RichText_FullWidthSelection,
+ SH_Menu_Scrollable,
+ SH_GroupBox_TextLabelVerticalAlignment,
+ SH_GroupBox_TextLabelColor,
+ SH_Menu_SloppySubMenus,
+ SH_Table_GridLineColor,
+ SH_LineEdit_PasswordCharacter,
+ SH_DialogButtons_DefaultButton,
+ SH_ToolBox_SelectedPageTitleBold,
+ SH_TabBar_PreferNoArrows,
+ SH_ScrollBar_LeftClickAbsolutePosition,
+ SH_Q3ListViewExpand_SelectMouseType,
+ SH_UnderlineShortcut,
+ SH_SpinBox_AnimateButton,
+ SH_SpinBox_KeyPressAutoRepeatRate,
+ SH_SpinBox_ClickAutoRepeatRate,
+ SH_Menu_FillScreenWithScroll,
+ SH_ToolTipLabel_Opacity,
+ SH_DrawMenuBarSeparator,
+ SH_TitleBar_ModifyNotification,
+ SH_Button_FocusPolicy,
+ SH_MenuBar_DismissOnSecondClick,
+ SH_MessageBox_UseBorderForButtonSpacing,
+ SH_TitleBar_AutoRaise,
+ SH_ToolButton_PopupDelay,
+ SH_FocusFrame_Mask,
+ SH_RubberBand_Mask,
+ SH_WindowFrame_Mask,
+ SH_SpinControls_DisableOnBounds,
+ SH_Dial_BackgroundRole,
+ SH_ComboBox_LayoutDirection,
+ SH_ItemView_EllipsisLocation,
+ SH_ItemView_ShowDecorationSelected,
+ SH_ItemView_ActivateItemOnSingleClick,
+ SH_ScrollBar_ContextMenu,
+ SH_ScrollBar_RollBetweenButtons,
+ SH_Slider_AbsoluteSetButtons,
+ SH_Slider_PageSetButtons,
+ SH_Menu_KeyboardSearch,
+ SH_TabBar_ElideMode,
+ SH_DialogButtonLayout,
+ SH_ComboBox_PopupFrameStyle,
+ SH_MessageBox_TextInteractionFlags,
+ SH_DialogButtonBox_ButtonsHaveIcons,
+ SH_SpellCheckUnderlineStyle,
+ SH_MessageBox_CenterButtons,
+ SH_Menu_SelectionWrap,
+ SH_ItemView_MovementWithoutUpdatingSelection,
+ SH_ToolTip_Mask,
+ SH_FocusFrame_AboveWidget,
+ SH_TextControl_FocusIndicatorTextCharFormat,
+ SH_WizardStyle,
+ SH_ItemView_ArrowKeysNavigateIntoChildren,
+ SH_Menu_Mask,
+ SH_Menu_FlashTriggeredItem,
+ SH_Menu_FadeOutOnHide,
+ SH_SpinBox_ClickAutoRepeatThreshold,
+ SH_ItemView_PaintAlternatingRowColorsForEmptyArea,
+ SH_FormLayoutWrapPolicy,
+ SH_TabWidget_DefaultTabPosition,
+ SH_ToolBar_Movable,
+ SH_FormLayoutFieldGrowthPolicy,
+ SH_FormLayoutFormAlignment,
+ SH_FormLayoutLabelAlignment,
+ SH_ItemView_DrawDelegateFrame,
+ SH_TabBar_CloseButtonPosition,
+ SH_DockWidget_ButtonsHaveFrame,
+ SH_ToolButtonStyle,
+ SH_RequestSoftwareInputPanel,
+ // Add new style hint values here
+
+#ifdef QT3_SUPPORT
+ SH_GUIStyle = 0x00000100,
+ SH_ScrollBar_BackgroundMode,
+ // Add other compat values here
+
+ SH_UnderlineAccelerator = SH_UnderlineShortcut,
+#endif
+ SH_CustomBase = 0xf0000000
+ };
+
+ virtual int styleHint(StyleHint stylehint, const QStyleOption *opt = 0,
+ const QWidget *widget = 0, QStyleHintReturn* returnData = 0) const = 0;
+
+ enum StandardPixmap {
+ SP_TitleBarMenuButton,
+ SP_TitleBarMinButton,
+ SP_TitleBarMaxButton,
+ SP_TitleBarCloseButton,
+ SP_TitleBarNormalButton,
+ SP_TitleBarShadeButton,
+ SP_TitleBarUnshadeButton,
+ SP_TitleBarContextHelpButton,
+ SP_DockWidgetCloseButton,
+ SP_MessageBoxInformation,
+ SP_MessageBoxWarning,
+ SP_MessageBoxCritical,
+ SP_MessageBoxQuestion,
+ SP_DesktopIcon,
+ SP_TrashIcon,
+ SP_ComputerIcon,
+ SP_DriveFDIcon,
+ SP_DriveHDIcon,
+ SP_DriveCDIcon,
+ SP_DriveDVDIcon,
+ SP_DriveNetIcon,
+ SP_DirOpenIcon,
+ SP_DirClosedIcon,
+ SP_DirLinkIcon,
+ SP_FileIcon,
+ SP_FileLinkIcon,
+ SP_ToolBarHorizontalExtensionButton,
+ SP_ToolBarVerticalExtensionButton,
+ SP_FileDialogStart,
+ SP_FileDialogEnd,
+ SP_FileDialogToParent,
+ SP_FileDialogNewFolder,
+ SP_FileDialogDetailedView,
+ SP_FileDialogInfoView,
+ SP_FileDialogContentsView,
+ SP_FileDialogListView,
+ SP_FileDialogBack,
+ SP_DirIcon,
+ SP_DialogOkButton,
+ SP_DialogCancelButton,
+ SP_DialogHelpButton,
+ SP_DialogOpenButton,
+ SP_DialogSaveButton,
+ SP_DialogCloseButton,
+ SP_DialogApplyButton,
+ SP_DialogResetButton,
+ SP_DialogDiscardButton,
+ SP_DialogYesButton,
+ SP_DialogNoButton,
+ SP_ArrowUp,
+ SP_ArrowDown,
+ SP_ArrowLeft,
+ SP_ArrowRight,
+ SP_ArrowBack,
+ SP_ArrowForward,
+ SP_DirHomeIcon,
+ SP_CommandLink,
+ SP_VistaShield,
+ SP_BrowserReload,
+ SP_BrowserStop,
+ SP_MediaPlay,
+ SP_MediaStop,
+ SP_MediaPause,
+ SP_MediaSkipForward,
+ SP_MediaSkipBackward,
+ SP_MediaSeekForward,
+ SP_MediaSeekBackward,
+ SP_MediaVolume,
+ SP_MediaVolumeMuted,
+ // do not add any values below/greater than this
+ SP_CustomBase = 0xf0000000
+ };
+
+ virtual QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt = 0,
+ const QWidget *widget = 0) const = 0;
+
+ QIcon standardIcon(StandardPixmap standardIcon, const QStyleOption *option = 0,
+ const QWidget *widget = 0) const;
+
+ virtual QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap,
+ const QStyleOption *opt) const = 0;
+
+ static QRect visualRect(Qt::LayoutDirection direction, const QRect &boundingRect,
+ const QRect &logicalRect);
+ static QPoint visualPos(Qt::LayoutDirection direction, const QRect &boundingRect,
+ const QPoint &logicalPos);
+ static int sliderPositionFromValue(int min, int max, int val, int space,
+ bool upsideDown = false);
+ static int sliderValueFromPosition(int min, int max, int pos, int space,
+ bool upsideDown = false);
+ static Qt::Alignment visualAlignment(Qt::LayoutDirection direction, Qt::Alignment alignment);
+ static QRect alignedRect(Qt::LayoutDirection direction, Qt::Alignment alignment,
+ const QSize &size, const QRect &rectangle);
+
+ int layoutSpacing(QSizePolicy::ControlType control1,
+ QSizePolicy::ControlType control2, Qt::Orientation orientation,
+ const QStyleOption *option = 0, const QWidget *widget = 0) const;
+ int combinedLayoutSpacing(QSizePolicy::ControlTypes controls1,
+ QSizePolicy::ControlTypes controls2, Qt::Orientation orientation,
+ QStyleOption *option = 0, QWidget *widget = 0) const;
+
+ const QStyle * proxy() const;
+
+protected Q_SLOTS:
+ QIcon standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *opt = 0,
+ const QWidget *widget = 0) const;
+ int layoutSpacingImplementation(QSizePolicy::ControlType control1,
+ QSizePolicy::ControlType control2,
+ Qt::Orientation orientation,
+ const QStyleOption *option = 0,
+ const QWidget *widget = 0) const;
+
+private:
+ Q_DISABLE_COPY(QStyle)
+ friend class QWidget;
+ friend class QWidgetPrivate;
+ friend class QApplication;
+ friend class QProxyStyle;
+ friend class QProxyStylePrivate;
+ void setProxy(QStyle *style);
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QStyle::State)
+Q_DECLARE_OPERATORS_FOR_FLAGS(QStyle::SubControls)
+
+#if !defined(QT_NO_DEBUG_STREAM)
+Q_WIDGETS_EXPORT QDebug operator<<(QDebug debug, QStyle::State state);
+#endif
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QSTYLE_H
diff --git a/src/gui/styles/qstyle.qrc b/src/widgets/styles/qstyle.qrc
index 8654e66a37..8654e66a37 100644
--- a/src/gui/styles/qstyle.qrc
+++ b/src/widgets/styles/qstyle.qrc
diff --git a/src/widgets/styles/qstyle_p.h b/src/widgets/styles/qstyle_p.h
new file mode 100644
index 0000000000..dfb0e95731
--- /dev/null
+++ b/src/widgets/styles/qstyle_p.h
@@ -0,0 +1,108 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSTYLE_P_H
+#define QSTYLE_P_H
+
+#include "private/qobject_p.h"
+#include <QtWidgets/qstyle.h>
+
+QT_BEGIN_NAMESPACE
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of qstyle_*.cpp. This header file may change from version to version
+// without notice, or even be removed.
+//
+// We mean it.
+//
+
+// Private class
+
+class QStyle;
+
+class QStylePrivate: public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QStyle)
+public:
+ inline QStylePrivate()
+ : layoutSpacingIndex(-1), proxyStyle(0) {}
+ mutable int layoutSpacingIndex;
+ QStyle *proxyStyle;
+};
+
+
+#define BEGIN_STYLE_PIXMAPCACHE(a) \
+ QRect rect = option->rect; \
+ QPixmap internalPixmapCache; \
+ QImage imageCache; \
+ QPainter *p = painter; \
+ QString unique = QStyleHelper::uniqueName((a), option, option->rect.size()); \
+ int txType = painter->deviceTransform().type() | painter->worldTransform().type(); \
+ bool doPixmapCache = txType <= QTransform::TxTranslate; \
+ if (doPixmapCache && QPixmapCache::find(unique, internalPixmapCache)) { \
+ painter->drawPixmap(option->rect.topLeft(), internalPixmapCache); \
+ } else { \
+ if (doPixmapCache) { \
+ rect.setRect(0, 0, option->rect.width(), option->rect.height()); \
+ imageCache = QImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied); \
+ imageCache.fill(0); \
+ p = new QPainter(&imageCache); \
+ }
+
+
+
+#define END_STYLE_PIXMAPCACHE \
+ if (doPixmapCache) { \
+ p->end(); \
+ delete p; \
+ internalPixmapCache = QPixmap::fromImage(imageCache); \
+ painter->drawPixmap(option->rect.topLeft(), internalPixmapCache); \
+ QPixmapCache::insert(unique, internalPixmapCache); \
+ } \
+ }
+
+QT_END_NAMESPACE
+
+#endif //QSTYLE_P_H
diff --git a/src/gui/styles/qstyle_s60.qrc b/src/widgets/styles/qstyle_s60.qrc
index dbee38b266..dbee38b266 100644
--- a/src/gui/styles/qstyle_s60.qrc
+++ b/src/widgets/styles/qstyle_s60.qrc
diff --git a/src/gui/styles/qstyle_s60_simulated.qrc b/src/widgets/styles/qstyle_s60_simulated.qrc
index 969732e1e0..969732e1e0 100644
--- a/src/gui/styles/qstyle_s60_simulated.qrc
+++ b/src/widgets/styles/qstyle_s60_simulated.qrc
diff --git a/src/gui/styles/qstyle_wince.qrc b/src/widgets/styles/qstyle_wince.qrc
index bdcf604625..bdcf604625 100644
--- a/src/gui/styles/qstyle_wince.qrc
+++ b/src/widgets/styles/qstyle_wince.qrc
diff --git a/src/gui/styles/qstylefactory.cpp b/src/widgets/styles/qstylefactory.cpp
index 83b67484b8..83b67484b8 100644
--- a/src/gui/styles/qstylefactory.cpp
+++ b/src/widgets/styles/qstylefactory.cpp
diff --git a/src/widgets/styles/qstylefactory.h b/src/widgets/styles/qstylefactory.h
new file mode 100644
index 0000000000..b972c8e0e6
--- /dev/null
+++ b/src/widgets/styles/qstylefactory.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSTYLEFACTORY_H
+#define QSTYLEFACTORY_H
+
+#include <QtCore/qstringlist.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QStyle;
+
+class Q_WIDGETS_EXPORT QStyleFactory
+{
+public:
+ static QStringList keys();
+ static QStyle *create(const QString&);
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QSTYLEFACTORY_H
diff --git a/src/gui/styles/qstylehelper.cpp b/src/widgets/styles/qstylehelper.cpp
index bf7cb49bcf..bf7cb49bcf 100644
--- a/src/gui/styles/qstylehelper.cpp
+++ b/src/widgets/styles/qstylehelper.cpp
diff --git a/src/widgets/styles/qstylehelper_p.h b/src/widgets/styles/qstylehelper_p.h
new file mode 100644
index 0000000000..f2bb81929c
--- /dev/null
+++ b/src/widgets/styles/qstylehelper_p.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qglobal.h>
+#include <QtCore/qpoint.h>
+#include <QtCore/qstring.h>
+#include <QtGui/qpolygon.h>
+#include <QtCore/qstringbuilder.h>
+
+#ifndef QSTYLEHELPER_P_H
+#define QSTYLEHELPER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <private/qhexstring_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QPainter;
+class QPixmap;
+class QStyleOptionSlider;
+class QStyleOption;
+
+namespace QStyleHelper
+{
+ QString uniqueName(const QString &key, const QStyleOption *option, const QSize &size);
+ qreal dpiScaled(qreal value);
+#ifndef QT_NO_DIAL
+ qreal angle(const QPointF &p1, const QPointF &p2);
+ QPolygonF calcLines(const QStyleOptionSlider *dial);
+ int calcBigLineSize(int radius);
+ void drawDial(const QStyleOptionSlider *dial, QPainter *painter);
+#endif //QT_NO_DIAL
+ void drawBorderPixmap(const QPixmap &pixmap, QPainter *painter, const QRect &rect,
+ int left = 0, int top = 0, int right = 0,
+ int bottom = 0);
+}
+
+
+QT_END_NAMESPACE
+
+#endif // QSTYLEHELPER_P_H
diff --git a/src/gui/styles/qstyleoption.cpp b/src/widgets/styles/qstyleoption.cpp
index 90cfd427ed..90cfd427ed 100644
--- a/src/gui/styles/qstyleoption.cpp
+++ b/src/widgets/styles/qstyleoption.cpp
diff --git a/src/widgets/styles/qstyleoption.h b/src/widgets/styles/qstyleoption.h
new file mode 100644
index 0000000000..0640eef606
--- /dev/null
+++ b/src/widgets/styles/qstyleoption.h
@@ -0,0 +1,970 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSTYLEOPTION_H
+#define QSTYLEOPTION_H
+
+#include <QtCore/qvariant.h>
+#include <QtWidgets/qabstractspinbox.h>
+#include <QtWidgets/qicon.h>
+#include <QtGui/qmatrix.h>
+#include <QtWidgets/qslider.h>
+#include <QtWidgets/qstyle.h>
+#include <QtWidgets/qtabbar.h>
+#include <QtWidgets/qtabwidget.h>
+#include <QtWidgets/qrubberband.h>
+#include <QtWidgets/qframe.h>
+#ifndef QT_NO_ITEMVIEWS
+# include <QtCore/qabstractitemmodel.h>
+#endif
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QDebug;
+
+class Q_WIDGETS_EXPORT QStyleOption
+{
+public:
+ enum OptionType {
+ SO_Default, SO_FocusRect, SO_Button, SO_Tab, SO_MenuItem,
+ SO_Frame, SO_ProgressBar, SO_ToolBox, SO_Header, SO_Q3DockWindow,
+ SO_DockWidget, SO_Q3ListViewItem, SO_ViewItem, SO_TabWidgetFrame,
+ SO_TabBarBase, SO_RubberBand, SO_ToolBar, SO_GraphicsItem,
+
+ SO_Complex = 0xf0000, SO_Slider, SO_SpinBox, SO_ToolButton, SO_ComboBox,
+ SO_Q3ListView, SO_TitleBar, SO_GroupBox, SO_SizeGrip,
+
+ SO_CustomBase = 0xf00,
+ SO_ComplexCustomBase = 0xf000000
+ };
+
+ enum StyleOptionType { Type = SO_Default };
+ enum StyleOptionVersion { Version = 1 };
+
+ int version;
+ int type;
+ QStyle::State state;
+ Qt::LayoutDirection direction;
+ QRect rect;
+ QFontMetrics fontMetrics;
+ QPalette palette;
+
+ QStyleOption(int version = QStyleOption::Version, int type = SO_Default);
+ QStyleOption(const QStyleOption &other);
+ ~QStyleOption();
+
+ void init(const QWidget *w);
+ inline void initFrom(const QWidget *w) { init(w); }
+ QStyleOption &operator=(const QStyleOption &other);
+};
+
+class Q_WIDGETS_EXPORT QStyleOptionFocusRect : public QStyleOption
+{
+public:
+ enum StyleOptionType { Type = SO_FocusRect };
+ enum StyleOptionVersion { Version = 1 };
+
+ QColor backgroundColor;
+
+ QStyleOptionFocusRect();
+ QStyleOptionFocusRect(const QStyleOptionFocusRect &other) : QStyleOption(Version, Type) { *this = other; }
+
+protected:
+ QStyleOptionFocusRect(int version);
+};
+
+class Q_WIDGETS_EXPORT QStyleOptionFrame : public QStyleOption
+{
+public:
+ enum StyleOptionType { Type = SO_Frame };
+ enum StyleOptionVersion { Version = 1 };
+
+ int lineWidth;
+ int midLineWidth;
+
+ QStyleOptionFrame();
+ QStyleOptionFrame(const QStyleOptionFrame &other) : QStyleOption(Version, Type) { *this = other; }
+
+protected:
+ QStyleOptionFrame(int version);
+};
+
+class Q_WIDGETS_EXPORT QStyleOptionFrameV2 : public QStyleOptionFrame
+{
+public:
+ enum StyleOptionVersion { Version = 2 };
+ enum FrameFeature {
+ None = 0x00,
+ Flat = 0x01
+ };
+ Q_DECLARE_FLAGS(FrameFeatures, FrameFeature)
+ FrameFeatures features;
+
+ QStyleOptionFrameV2();
+ QStyleOptionFrameV2(const QStyleOptionFrameV2 &other) : QStyleOptionFrame(Version) { *this = other; }
+ QStyleOptionFrameV2(const QStyleOptionFrame &other);
+ QStyleOptionFrameV2 &operator=(const QStyleOptionFrame &other);
+
+protected:
+ QStyleOptionFrameV2(int version);
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QStyleOptionFrameV2::FrameFeatures)
+
+
+class Q_WIDGETS_EXPORT QStyleOptionFrameV3 : public QStyleOptionFrameV2
+{
+public:
+ enum StyleOptionVersion { Version = 3 };
+ QFrame::Shape frameShape : 4;
+ uint unused : 28;
+
+ QStyleOptionFrameV3();
+ QStyleOptionFrameV3(const QStyleOptionFrameV3 &other) : QStyleOptionFrameV2(Version) { *this = other; }
+ QStyleOptionFrameV3(const QStyleOptionFrame &other);
+ QStyleOptionFrameV3 &operator=(const QStyleOptionFrame &other);
+
+protected:
+ QStyleOptionFrameV3(int version);
+};
+
+
+#ifndef QT_NO_TABWIDGET
+class Q_WIDGETS_EXPORT QStyleOptionTabWidgetFrame : public QStyleOption
+{
+public:
+ enum StyleOptionType { Type = SO_TabWidgetFrame };
+ enum StyleOptionVersion { Version = 1 };
+
+ int lineWidth;
+ int midLineWidth;
+ QTabBar::Shape shape;
+ QSize tabBarSize;
+ QSize rightCornerWidgetSize;
+ QSize leftCornerWidgetSize;
+
+ QStyleOptionTabWidgetFrame();
+ inline QStyleOptionTabWidgetFrame(const QStyleOptionTabWidgetFrame &other)
+ : QStyleOption(Version, Type) { *this = other; }
+
+protected:
+ QStyleOptionTabWidgetFrame(int version);
+};
+
+class Q_WIDGETS_EXPORT QStyleOptionTabWidgetFrameV2 : public QStyleOptionTabWidgetFrame
+{
+public:
+ enum StyleOptionVersion { Version = 2 };
+
+ QRect tabBarRect;
+ QRect selectedTabRect;
+
+ QStyleOptionTabWidgetFrameV2();
+ QStyleOptionTabWidgetFrameV2(const QStyleOptionTabWidgetFrameV2 &other) :
+ QStyleOptionTabWidgetFrame(Version) { *this = other; }
+ QStyleOptionTabWidgetFrameV2(const QStyleOptionTabWidgetFrame &other);
+ QStyleOptionTabWidgetFrameV2 &operator=(const QStyleOptionTabWidgetFrame &other);
+
+protected:
+ QStyleOptionTabWidgetFrameV2(int version);
+};
+
+#endif
+
+
+#ifndef QT_NO_TABBAR
+class Q_WIDGETS_EXPORT QStyleOptionTabBarBase : public QStyleOption
+{
+public:
+ enum StyleOptionType { Type = SO_TabBarBase };
+ enum StyleOptionVersion { Version = 1 };
+
+ QTabBar::Shape shape;
+ QRect tabBarRect;
+ QRect selectedTabRect;
+
+ QStyleOptionTabBarBase();
+ QStyleOptionTabBarBase(const QStyleOptionTabBarBase &other) : QStyleOption(Version, Type) { *this = other; }
+
+protected:
+ QStyleOptionTabBarBase(int version);
+};
+
+class Q_WIDGETS_EXPORT QStyleOptionTabBarBaseV2 : public QStyleOptionTabBarBase
+{
+public:
+ enum StyleOptionVersion { Version = 2 };
+ bool documentMode;
+ QStyleOptionTabBarBaseV2();
+ QStyleOptionTabBarBaseV2(const QStyleOptionTabBarBaseV2 &other) : QStyleOptionTabBarBase(Version) { *this = other; }
+ QStyleOptionTabBarBaseV2(const QStyleOptionTabBarBase &other);
+ QStyleOptionTabBarBaseV2 &operator=(const QStyleOptionTabBarBase &other);
+
+protected:
+ QStyleOptionTabBarBaseV2(int version);
+};
+
+#endif
+
+class Q_WIDGETS_EXPORT QStyleOptionHeader : public QStyleOption
+{
+public:
+ enum StyleOptionType { Type = SO_Header };
+ enum StyleOptionVersion { Version = 1 };
+
+ enum SectionPosition { Beginning, Middle, End, OnlyOneSection };
+ enum SelectedPosition { NotAdjacent, NextIsSelected, PreviousIsSelected,
+ NextAndPreviousAreSelected };
+ enum SortIndicator { None, SortUp, SortDown };
+
+ int section;
+ QString text;
+ Qt::Alignment textAlignment;
+ QIcon icon;
+ Qt::Alignment iconAlignment;
+ SectionPosition position;
+ SelectedPosition selectedPosition;
+ SortIndicator sortIndicator;
+ Qt::Orientation orientation;
+
+ QStyleOptionHeader();
+ QStyleOptionHeader(const QStyleOptionHeader &other) : QStyleOption(Version, Type) { *this = other; }
+
+protected:
+ QStyleOptionHeader(int version);
+};
+
+class Q_WIDGETS_EXPORT QStyleOptionButton : public QStyleOption
+{
+public:
+ enum StyleOptionType { Type = SO_Button };
+ enum StyleOptionVersion { Version = 1 };
+
+ enum ButtonFeature { None = 0x00, Flat = 0x01, HasMenu = 0x02, DefaultButton = 0x04,
+ AutoDefaultButton = 0x08, CommandLinkButton = 0x10 };
+ Q_DECLARE_FLAGS(ButtonFeatures, ButtonFeature)
+
+ ButtonFeatures features;
+ QString text;
+ QIcon icon;
+ QSize iconSize;
+
+ QStyleOptionButton();
+ QStyleOptionButton(const QStyleOptionButton &other) : QStyleOption(Version, Type) { *this = other; }
+
+protected:
+ QStyleOptionButton(int version);
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QStyleOptionButton::ButtonFeatures)
+
+#ifndef QT_NO_TABBAR
+class Q_WIDGETS_EXPORT QStyleOptionTab : public QStyleOption
+{
+public:
+ enum StyleOptionType { Type = SO_Tab };
+ enum StyleOptionVersion { Version = 1 };
+
+ enum TabPosition { Beginning, Middle, End, OnlyOneTab };
+ enum SelectedPosition { NotAdjacent, NextIsSelected, PreviousIsSelected };
+ enum CornerWidget { NoCornerWidgets = 0x00, LeftCornerWidget = 0x01,
+ RightCornerWidget = 0x02 };
+ Q_DECLARE_FLAGS(CornerWidgets, CornerWidget)
+
+ QTabBar::Shape shape;
+ QString text;
+ QIcon icon;
+ int row;
+ TabPosition position;
+ SelectedPosition selectedPosition;
+ CornerWidgets cornerWidgets;
+
+ QStyleOptionTab();
+ QStyleOptionTab(const QStyleOptionTab &other) : QStyleOption(Version, Type) { *this = other; }
+
+protected:
+ QStyleOptionTab(int version);
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QStyleOptionTab::CornerWidgets)
+
+class Q_WIDGETS_EXPORT QStyleOptionTabV2 : public QStyleOptionTab
+{
+public:
+ enum StyleOptionVersion { Version = 2 };
+ QSize iconSize;
+ QStyleOptionTabV2();
+ QStyleOptionTabV2(const QStyleOptionTabV2 &other) : QStyleOptionTab(Version) { *this = other; }
+ QStyleOptionTabV2(const QStyleOptionTab &other);
+ QStyleOptionTabV2 &operator=(const QStyleOptionTab &other);
+
+protected:
+ QStyleOptionTabV2(int version);
+};
+
+class Q_WIDGETS_EXPORT QStyleOptionTabV3 : public QStyleOptionTabV2
+{
+public:
+ enum StyleOptionVersion { Version = 3 };
+ bool documentMode;
+ QSize leftButtonSize;
+ QSize rightButtonSize;
+ QStyleOptionTabV3();
+ QStyleOptionTabV3(const QStyleOptionTabV3 &other) : QStyleOptionTabV2(Version) { *this = other; }
+ QStyleOptionTabV3(const QStyleOptionTabV2 &other) : QStyleOptionTabV2(Version) { *this = other; }
+ QStyleOptionTabV3(const QStyleOptionTab &other);
+ QStyleOptionTabV3 &operator=(const QStyleOptionTab &other);
+
+protected:
+ QStyleOptionTabV3(int version);
+};
+
+#endif
+
+
+#ifndef QT_NO_TOOLBAR
+
+class Q_WIDGETS_EXPORT QStyleOptionToolBar : public QStyleOption
+{
+public:
+ enum StyleOptionType { Type = SO_ToolBar };
+ enum StyleOptionVersion { Version = 1 };
+ enum ToolBarPosition { Beginning, Middle, End, OnlyOne };
+ enum ToolBarFeature { None = 0x0, Movable = 0x1 };
+ Q_DECLARE_FLAGS(ToolBarFeatures, ToolBarFeature)
+ ToolBarPosition positionOfLine; // The toolbar line position
+ ToolBarPosition positionWithinLine; // The position within a toolbar
+ Qt::ToolBarArea toolBarArea; // The toolbar docking area
+ ToolBarFeatures features;
+ int lineWidth;
+ int midLineWidth;
+ QStyleOptionToolBar();
+ QStyleOptionToolBar(const QStyleOptionToolBar &other) : QStyleOption(Version, Type) { *this = other; }
+
+protected:
+ QStyleOptionToolBar(int version);
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QStyleOptionToolBar::ToolBarFeatures)
+
+#endif
+
+
+
+class Q_WIDGETS_EXPORT QStyleOptionProgressBar : public QStyleOption
+{
+public:
+ enum StyleOptionType { Type = SO_ProgressBar };
+ enum StyleOptionVersion { Version = 1 };
+
+ int minimum;
+ int maximum;
+ int progress;
+ QString text;
+ Qt::Alignment textAlignment;
+ bool textVisible;
+
+ QStyleOptionProgressBar();
+ QStyleOptionProgressBar(const QStyleOptionProgressBar &other) : QStyleOption(Version, Type) { *this = other; }
+
+protected:
+ QStyleOptionProgressBar(int version);
+};
+
+// Adds style info for vertical progress bars
+class Q_WIDGETS_EXPORT QStyleOptionProgressBarV2 : public QStyleOptionProgressBar
+{
+public:
+ enum StyleOptionType { Type = SO_ProgressBar };
+ enum StyleOptionVersion { Version = 2 };
+ Qt::Orientation orientation;
+ bool invertedAppearance;
+ bool bottomToTop;
+
+ QStyleOptionProgressBarV2();
+ QStyleOptionProgressBarV2(const QStyleOptionProgressBar &other);
+ QStyleOptionProgressBarV2(const QStyleOptionProgressBarV2 &other);
+ QStyleOptionProgressBarV2 &operator=(const QStyleOptionProgressBar &other);
+
+protected:
+ QStyleOptionProgressBarV2(int version);
+};
+
+class Q_WIDGETS_EXPORT QStyleOptionMenuItem : public QStyleOption
+{
+public:
+ enum StyleOptionType { Type = SO_MenuItem };
+ enum StyleOptionVersion { Version = 1 };
+
+ enum MenuItemType { Normal, DefaultItem, Separator, SubMenu, Scroller, TearOff, Margin,
+ EmptyArea };
+ enum CheckType { NotCheckable, Exclusive, NonExclusive };
+
+ MenuItemType menuItemType;
+ CheckType checkType;
+ bool checked;
+ bool menuHasCheckableItems;
+ QRect menuRect;
+ QString text;
+ QIcon icon;
+ int maxIconWidth;
+ int tabWidth;
+ QFont font;
+
+ QStyleOptionMenuItem();
+ QStyleOptionMenuItem(const QStyleOptionMenuItem &other) : QStyleOption(Version, Type) { *this = other; }
+
+protected:
+ QStyleOptionMenuItem(int version);
+};
+
+class Q_WIDGETS_EXPORT QStyleOptionQ3ListViewItem : public QStyleOption
+{
+public:
+ enum StyleOptionType { Type = SO_Q3ListViewItem };
+ enum StyleOptionVersion { Version = 1 };
+
+ enum Q3ListViewItemFeature { None = 0x00, Expandable = 0x01, MultiLine = 0x02, Visible = 0x04,
+ ParentControl = 0x08 };
+ Q_DECLARE_FLAGS(Q3ListViewItemFeatures, Q3ListViewItemFeature)
+
+ Q3ListViewItemFeatures features;
+ int height;
+ int totalHeight;
+ int itemY;
+ int childCount;
+
+ QStyleOptionQ3ListViewItem();
+ QStyleOptionQ3ListViewItem(const QStyleOptionQ3ListViewItem &other) : QStyleOption(Version, Type) { *this = other; }
+
+protected:
+ QStyleOptionQ3ListViewItem(int version);
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QStyleOptionQ3ListViewItem::Q3ListViewItemFeatures)
+
+class Q_WIDGETS_EXPORT QStyleOptionQ3DockWindow : public QStyleOption
+{
+public:
+ enum StyleOptionType { Type = SO_Q3DockWindow };
+ enum StyleOptionVersion { Version = 1 };
+
+ bool docked;
+ bool closeEnabled;
+
+ QStyleOptionQ3DockWindow();
+ QStyleOptionQ3DockWindow(const QStyleOptionQ3DockWindow &other) : QStyleOption(Version, Type) { *this = other; }
+
+protected:
+ QStyleOptionQ3DockWindow(int version);
+};
+
+class Q_WIDGETS_EXPORT QStyleOptionDockWidget : public QStyleOption
+{
+public:
+ enum StyleOptionType { Type = SO_DockWidget };
+ enum StyleOptionVersion { Version = 1 };
+
+ QString title;
+ bool closable;
+ bool movable;
+ bool floatable;
+
+ QStyleOptionDockWidget();
+ QStyleOptionDockWidget(const QStyleOptionDockWidget &other) : QStyleOption(Version, Type) { *this = other; }
+
+protected:
+ QStyleOptionDockWidget(int version);
+};
+
+class Q_WIDGETS_EXPORT QStyleOptionDockWidgetV2 : public QStyleOptionDockWidget
+{
+public:
+ enum StyleOptionVersion { Version = 2 };
+
+ bool verticalTitleBar;
+
+ QStyleOptionDockWidgetV2();
+ QStyleOptionDockWidgetV2(const QStyleOptionDockWidgetV2 &other)
+ : QStyleOptionDockWidget(Version) { *this = other; }
+ QStyleOptionDockWidgetV2(const QStyleOptionDockWidget &other);
+ QStyleOptionDockWidgetV2 &operator = (const QStyleOptionDockWidget &other);
+
+protected:
+ QStyleOptionDockWidgetV2(int version);
+};
+
+class Q_WIDGETS_EXPORT QStyleOptionViewItem : public QStyleOption
+{
+public:
+ enum StyleOptionType { Type = SO_ViewItem };
+ enum StyleOptionVersion { Version = 1 };
+
+ enum Position { Left, Right, Top, Bottom };
+
+ Qt::Alignment displayAlignment;
+ Qt::Alignment decorationAlignment;
+ Qt::TextElideMode textElideMode;
+ Position decorationPosition;
+ QSize decorationSize;
+ QFont font;
+ bool showDecorationSelected;
+
+ QStyleOptionViewItem();
+ QStyleOptionViewItem(const QStyleOptionViewItem &other) : QStyleOption(Version, Type) { *this = other; }
+
+protected:
+ QStyleOptionViewItem(int version);
+};
+
+class Q_WIDGETS_EXPORT QStyleOptionViewItemV2 : public QStyleOptionViewItem
+{
+public:
+ enum StyleOptionVersion { Version = 2 };
+
+ enum ViewItemFeature {
+ None = 0x00,
+ WrapText = 0x01,
+ Alternate = 0x02,
+ HasCheckIndicator = 0x04,
+ HasDisplay = 0x08,
+ HasDecoration = 0x10
+ };
+ Q_DECLARE_FLAGS(ViewItemFeatures, ViewItemFeature)
+
+ ViewItemFeatures features;
+
+ QStyleOptionViewItemV2();
+ QStyleOptionViewItemV2(const QStyleOptionViewItemV2 &other) : QStyleOptionViewItem(Version) { *this = other; }
+ QStyleOptionViewItemV2(const QStyleOptionViewItem &other);
+ QStyleOptionViewItemV2 &operator=(const QStyleOptionViewItem &other);
+
+protected:
+ QStyleOptionViewItemV2(int version);
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QStyleOptionViewItemV2::ViewItemFeatures)
+
+class Q_WIDGETS_EXPORT QStyleOptionViewItemV3 : public QStyleOptionViewItemV2
+{
+public:
+ enum StyleOptionVersion { Version = 3 };
+
+ QLocale locale;
+ const QWidget *widget;
+
+ QStyleOptionViewItemV3();
+ QStyleOptionViewItemV3(const QStyleOptionViewItemV3 &other)
+ : QStyleOptionViewItemV2(Version) { *this = other; }
+ QStyleOptionViewItemV3(const QStyleOptionViewItem &other);
+ QStyleOptionViewItemV3 &operator = (const QStyleOptionViewItem &other);
+
+protected:
+ QStyleOptionViewItemV3(int version);
+};
+
+#ifndef QT_NO_ITEMVIEWS
+class Q_WIDGETS_EXPORT QStyleOptionViewItemV4 : public QStyleOptionViewItemV3
+{
+public:
+ enum StyleOptionVersion { Version = 4 };
+ enum ViewItemPosition { Invalid, Beginning, Middle, End, OnlyOne };
+
+ QModelIndex index;
+ Qt::CheckState checkState;
+ QIcon icon;
+ QString text;
+ ViewItemPosition viewItemPosition;
+ QBrush backgroundBrush;
+
+ QStyleOptionViewItemV4();
+ QStyleOptionViewItemV4(const QStyleOptionViewItemV4 &other)
+ : QStyleOptionViewItemV3(Version) { *this = other; }
+ QStyleOptionViewItemV4(const QStyleOptionViewItem &other);
+ QStyleOptionViewItemV4 &operator = (const QStyleOptionViewItem &other);
+
+protected:
+ QStyleOptionViewItemV4(int version);
+};
+#endif
+
+class Q_WIDGETS_EXPORT QStyleOptionToolBox : public QStyleOption
+{
+public:
+ enum StyleOptionType { Type = SO_ToolBox };
+ enum StyleOptionVersion { Version = 1 };
+
+ QString text;
+ QIcon icon;
+
+ QStyleOptionToolBox();
+ QStyleOptionToolBox(const QStyleOptionToolBox &other) : QStyleOption(Version, Type) { *this = other; }
+
+protected:
+ QStyleOptionToolBox(int version);
+};
+
+class Q_WIDGETS_EXPORT QStyleOptionToolBoxV2 : public QStyleOptionToolBox
+{
+public:
+ enum StyleOptionVersion { Version = 2 };
+ enum TabPosition { Beginning, Middle, End, OnlyOneTab };
+ enum SelectedPosition { NotAdjacent, NextIsSelected, PreviousIsSelected };
+
+ TabPosition position;
+ SelectedPosition selectedPosition;
+
+ QStyleOptionToolBoxV2();
+ QStyleOptionToolBoxV2(const QStyleOptionToolBoxV2 &other) : QStyleOptionToolBox(Version) { *this = other; }
+ QStyleOptionToolBoxV2(const QStyleOptionToolBox &other);
+ QStyleOptionToolBoxV2 &operator=(const QStyleOptionToolBox &other);
+
+protected:
+ QStyleOptionToolBoxV2(int version);
+};
+
+#ifndef QT_NO_RUBBERBAND
+class Q_WIDGETS_EXPORT QStyleOptionRubberBand : public QStyleOption
+{
+public:
+ enum StyleOptionType { Type = SO_RubberBand };
+ enum StyleOptionVersion { Version = 1 };
+
+ QRubberBand::Shape shape;
+ bool opaque;
+
+ QStyleOptionRubberBand();
+ QStyleOptionRubberBand(const QStyleOptionRubberBand &other) : QStyleOption(Version, Type) { *this = other; }
+
+protected:
+ QStyleOptionRubberBand(int version);
+};
+#endif // QT_NO_RUBBERBAND
+
+// -------------------------- Complex style options -------------------------------
+class Q_WIDGETS_EXPORT QStyleOptionComplex : public QStyleOption
+{
+public:
+ enum StyleOptionType { Type = SO_Complex };
+ enum StyleOptionVersion { Version = 1 };
+
+ QStyle::SubControls subControls;
+ QStyle::SubControls activeSubControls;
+
+ QStyleOptionComplex(int version = QStyleOptionComplex::Version, int type = SO_Complex);
+ QStyleOptionComplex(const QStyleOptionComplex &other) : QStyleOption(Version, Type) { *this = other; }
+};
+
+#ifndef QT_NO_SLIDER
+class Q_WIDGETS_EXPORT QStyleOptionSlider : public QStyleOptionComplex
+{
+public:
+ enum StyleOptionType { Type = SO_Slider };
+ enum StyleOptionVersion { Version = 1 };
+
+ Qt::Orientation orientation;
+ int minimum;
+ int maximum;
+ QSlider::TickPosition tickPosition;
+ int tickInterval;
+ bool upsideDown;
+ int sliderPosition;
+ int sliderValue;
+ int singleStep;
+ int pageStep;
+ qreal notchTarget;
+ bool dialWrapping;
+
+ QStyleOptionSlider();
+ QStyleOptionSlider(const QStyleOptionSlider &other) : QStyleOptionComplex(Version, Type) { *this = other; }
+
+protected:
+ QStyleOptionSlider(int version);
+};
+#endif // QT_NO_SLIDER
+
+#ifndef QT_NO_SPINBOX
+class Q_WIDGETS_EXPORT QStyleOptionSpinBox : public QStyleOptionComplex
+{
+public:
+ enum StyleOptionType { Type = SO_SpinBox };
+ enum StyleOptionVersion { Version = 1 };
+
+ QAbstractSpinBox::ButtonSymbols buttonSymbols;
+ QAbstractSpinBox::StepEnabled stepEnabled;
+ bool frame;
+
+ QStyleOptionSpinBox();
+ QStyleOptionSpinBox(const QStyleOptionSpinBox &other) : QStyleOptionComplex(Version, Type) { *this = other; }
+
+protected:
+ QStyleOptionSpinBox(int version);
+};
+#endif // QT_NO_SPINBOX
+
+class Q_WIDGETS_EXPORT QStyleOptionQ3ListView : public QStyleOptionComplex
+{
+public:
+ enum StyleOptionType { Type = SO_Q3ListView };
+ enum StyleOptionVersion { Version = 1 };
+
+ QList<QStyleOptionQ3ListViewItem> items;
+ QPalette viewportPalette;
+ QPalette::ColorRole viewportBGRole;
+ int sortColumn;
+ int itemMargin;
+ int treeStepSize;
+ bool rootIsDecorated;
+
+ QStyleOptionQ3ListView();
+ QStyleOptionQ3ListView(const QStyleOptionQ3ListView &other) : QStyleOptionComplex(Version, Type) { *this = other; }
+
+protected:
+ QStyleOptionQ3ListView(int version);
+};
+
+class Q_WIDGETS_EXPORT QStyleOptionToolButton : public QStyleOptionComplex
+{
+public:
+ enum StyleOptionType { Type = SO_ToolButton };
+ enum StyleOptionVersion { Version = 1 };
+
+ enum ToolButtonFeature { None = 0x00, Arrow = 0x01, Menu = 0x04, MenuButtonPopup = Menu, PopupDelay = 0x08,
+ HasMenu = 0x10 };
+ Q_DECLARE_FLAGS(ToolButtonFeatures, ToolButtonFeature)
+
+ ToolButtonFeatures features;
+ QIcon icon;
+ QSize iconSize;
+ QString text;
+ Qt::ArrowType arrowType;
+ Qt::ToolButtonStyle toolButtonStyle;
+ QPoint pos;
+ QFont font;
+
+ QStyleOptionToolButton();
+ QStyleOptionToolButton(const QStyleOptionToolButton &other) : QStyleOptionComplex(Version, Type) { *this = other; }
+
+protected:
+ QStyleOptionToolButton(int version);
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QStyleOptionToolButton::ToolButtonFeatures)
+
+class Q_WIDGETS_EXPORT QStyleOptionComboBox : public QStyleOptionComplex
+{
+public:
+ enum StyleOptionType { Type = SO_ComboBox };
+ enum StyleOptionVersion { Version = 1 };
+
+ bool editable;
+ QRect popupRect;
+ bool frame;
+ QString currentText;
+ QIcon currentIcon;
+ QSize iconSize;
+
+ QStyleOptionComboBox();
+ QStyleOptionComboBox(const QStyleOptionComboBox &other) : QStyleOptionComplex(Version, Type) { *this = other; }
+
+protected:
+ QStyleOptionComboBox(int version);
+};
+
+class Q_WIDGETS_EXPORT QStyleOptionTitleBar : public QStyleOptionComplex
+{
+public:
+ enum StyleOptionType { Type = SO_TitleBar };
+ enum StyleOptionVersion { Version = 1 };
+
+ QString text;
+ QIcon icon;
+ int titleBarState;
+ Qt::WindowFlags titleBarFlags;
+
+ QStyleOptionTitleBar();
+ QStyleOptionTitleBar(const QStyleOptionTitleBar &other) : QStyleOptionComplex(Version, Type) { *this = other; }
+
+protected:
+ QStyleOptionTitleBar(int version);
+};
+
+class Q_WIDGETS_EXPORT QStyleOptionGroupBox : public QStyleOptionComplex
+{
+public:
+ enum StyleOptionType { Type = SO_GroupBox };
+ enum StyleOptionVersion { Version = 1 };
+
+ QStyleOptionFrameV2::FrameFeatures features;
+ QString text;
+ Qt::Alignment textAlignment;
+ QColor textColor;
+ int lineWidth;
+ int midLineWidth;
+
+ QStyleOptionGroupBox();
+ QStyleOptionGroupBox(const QStyleOptionGroupBox &other) : QStyleOptionComplex(Version, Type) { *this = other; }
+protected:
+ QStyleOptionGroupBox(int version);
+};
+
+class Q_WIDGETS_EXPORT QStyleOptionSizeGrip : public QStyleOptionComplex
+{
+public:
+ enum StyleOptionType { Type = SO_SizeGrip };
+ enum StyleOptionVersion { Version = 1 };
+
+ Qt::Corner corner;
+
+ QStyleOptionSizeGrip();
+ QStyleOptionSizeGrip(const QStyleOptionSizeGrip &other) : QStyleOptionComplex(Version, Type) { *this = other; }
+protected:
+ QStyleOptionSizeGrip(int version);
+};
+
+class Q_WIDGETS_EXPORT QStyleOptionGraphicsItem : public QStyleOption
+{
+public:
+ enum StyleOptionType { Type = SO_GraphicsItem };
+ enum StyleOptionVersion { Version = 1 };
+
+ QRectF exposedRect;
+ QMatrix matrix;
+ qreal levelOfDetail;
+
+ QStyleOptionGraphicsItem();
+ QStyleOptionGraphicsItem(const QStyleOptionGraphicsItem &other) : QStyleOption(Version, Type) { *this = other; }
+ static qreal levelOfDetailFromTransform(const QTransform &worldTransform);
+protected:
+ QStyleOptionGraphicsItem(int version);
+};
+
+template <typename T>
+T qstyleoption_cast(const QStyleOption *opt)
+{
+ if (opt && opt->version >= static_cast<T>(0)->Version && (opt->type == static_cast<T>(0)->Type
+ || int(static_cast<T>(0)->Type) == QStyleOption::SO_Default
+ || (int(static_cast<T>(0)->Type) == QStyleOption::SO_Complex
+ && opt->type > QStyleOption::SO_Complex)))
+ return static_cast<T>(opt);
+ return 0;
+}
+
+template <typename T>
+T qstyleoption_cast(QStyleOption *opt)
+{
+ if (opt && opt->version >= static_cast<T>(0)->Version && (opt->type == static_cast<T>(0)->Type
+ || int(static_cast<T>(0)->Type) == QStyleOption::SO_Default
+ || (int(static_cast<T>(0)->Type) == QStyleOption::SO_Complex
+ && opt->type > QStyleOption::SO_Complex)))
+ return static_cast<T>(opt);
+ return 0;
+}
+
+// -------------------------- QStyleHintReturn -------------------------------
+class Q_WIDGETS_EXPORT QStyleHintReturn {
+public:
+ enum HintReturnType {
+ SH_Default=0xf000, SH_Mask, SH_Variant
+ };
+
+ enum StyleOptionType { Type = SH_Default };
+ enum StyleOptionVersion { Version = 1 };
+
+ QStyleHintReturn(int version = QStyleOption::Version, int type = SH_Default);
+ ~QStyleHintReturn();
+
+ int version;
+ int type;
+};
+
+class Q_WIDGETS_EXPORT QStyleHintReturnMask : public QStyleHintReturn {
+public:
+ enum StyleOptionType { Type = SH_Mask };
+ enum StyleOptionVersion { Version = 1 };
+
+ QStyleHintReturnMask();
+
+ QRegion region;
+};
+
+class Q_WIDGETS_EXPORT QStyleHintReturnVariant : public QStyleHintReturn {
+public:
+ enum StyleOptionType { Type = SH_Variant };
+ enum StyleOptionVersion { Version = 1 };
+
+ QStyleHintReturnVariant();
+
+ QVariant variant;
+};
+
+template <typename T>
+T qstyleoption_cast(const QStyleHintReturn *hint)
+{
+ if (hint && hint->version <= static_cast<T>(0)->Version &&
+ (hint->type == static_cast<T>(0)->Type || int(static_cast<T>(0)->Type) == QStyleHintReturn::SH_Default))
+ return static_cast<T>(hint);
+ return 0;
+}
+
+template <typename T>
+T qstyleoption_cast(QStyleHintReturn *hint)
+{
+ if (hint && hint->version <= static_cast<T>(0)->Version &&
+ (hint->type == static_cast<T>(0)->Type || int(static_cast<T>(0)->Type) == QStyleHintReturn::SH_Default))
+ return static_cast<T>(hint);
+ return 0;
+}
+
+#if !defined(QT_NO_DEBUG_STREAM)
+Q_WIDGETS_EXPORT QDebug operator<<(QDebug debug, const QStyleOption::OptionType &optionType);
+Q_WIDGETS_EXPORT QDebug operator<<(QDebug debug, const QStyleOption &option);
+#endif
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QSTYLEOPTION_H
diff --git a/src/gui/painting/qstylepainter.cpp b/src/widgets/styles/qstylepainter.cpp
index 180499d791..180499d791 100644
--- a/src/gui/painting/qstylepainter.cpp
+++ b/src/widgets/styles/qstylepainter.cpp
diff --git a/src/widgets/styles/qstylepainter.h b/src/widgets/styles/qstylepainter.h
new file mode 100644
index 0000000000..ccb591c0f9
--- /dev/null
+++ b/src/widgets/styles/qstylepainter.h
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSTYLEPAINTER_H
+#define QSTYLEPAINTER_H
+
+#include <QtGui/qpainter.h>
+#include <QtWidgets/qstyle.h>
+#include <QtWidgets/qwidget.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QStylePainter : public QPainter
+{
+public:
+ inline QStylePainter() : QPainter(), widget(0), wstyle(0) {}
+ inline explicit QStylePainter(QWidget *w) { begin(w, w); }
+ inline QStylePainter(QPaintDevice *pd, QWidget *w) { begin(pd, w); }
+ inline bool begin(QWidget *w) { return begin(w, w); }
+ inline bool begin(QPaintDevice *pd, QWidget *w) {
+ Q_ASSERT_X(w, "QStylePainter::QStylePainter", "Widget must be non-zero");
+ widget = w;
+ wstyle = w->style();
+ return QPainter::begin(pd);
+ };
+ inline void drawPrimitive(QStyle::PrimitiveElement pe, const QStyleOption &opt);
+ inline void drawControl(QStyle::ControlElement ce, const QStyleOption &opt);
+ inline void drawComplexControl(QStyle::ComplexControl cc, const QStyleOptionComplex &opt);
+ inline void drawItemText(const QRect &r, int flags, const QPalette &pal, bool enabled,
+ const QString &text, QPalette::ColorRole textRole = QPalette::NoRole);
+ inline void drawItemPixmap(const QRect &r, int flags, const QPixmap &pixmap);
+ inline QStyle *style() const { return wstyle; }
+
+private:
+ QWidget *widget;
+ QStyle *wstyle;
+ Q_DISABLE_COPY(QStylePainter)
+};
+
+void QStylePainter::drawPrimitive(QStyle::PrimitiveElement pe, const QStyleOption &opt)
+{
+ wstyle->drawPrimitive(pe, &opt, this, widget);
+}
+
+void QStylePainter::drawControl(QStyle::ControlElement ce, const QStyleOption &opt)
+{
+ wstyle->drawControl(ce, &opt, this, widget);
+}
+
+void QStylePainter::drawComplexControl(QStyle::ComplexControl cc, const QStyleOptionComplex &opt)
+{
+ wstyle->drawComplexControl(cc, &opt, this, widget);
+}
+
+void QStylePainter::drawItemText(const QRect &r, int flags, const QPalette &pal, bool enabled,
+ const QString &text, QPalette::ColorRole textRole)
+{
+ wstyle->drawItemText(this, r, flags, pal, enabled, text, textRole);
+}
+
+void QStylePainter::drawItemPixmap(const QRect &r, int flags, const QPixmap &pixmap)
+{
+ wstyle->drawItemPixmap(this, r, flags, pixmap);
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QSTYLEPAINTER_H
diff --git a/src/gui/styles/qstyleplugin.cpp b/src/widgets/styles/qstyleplugin.cpp
index bb345c4bf1..bb345c4bf1 100644
--- a/src/gui/styles/qstyleplugin.cpp
+++ b/src/widgets/styles/qstyleplugin.cpp
diff --git a/src/widgets/styles/qstyleplugin.h b/src/widgets/styles/qstyleplugin.h
new file mode 100644
index 0000000000..ab55cdf54c
--- /dev/null
+++ b/src/widgets/styles/qstyleplugin.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSTYLEPLUGIN_H
+#define QSTYLEPLUGIN_H
+
+#include <QtCore/qplugin.h>
+#include <QtCore/qfactoryinterface.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QStyle;
+
+struct Q_WIDGETS_EXPORT QStyleFactoryInterface : public QFactoryInterface
+{
+ virtual QStyle *create(const QString &key) = 0;
+};
+
+#define QStyleFactoryInterface_iid "com.trolltech.Qt.QStyleFactoryInterface"
+
+Q_DECLARE_INTERFACE(QStyleFactoryInterface, QStyleFactoryInterface_iid)
+
+class Q_WIDGETS_EXPORT QStylePlugin : public QObject, public QStyleFactoryInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QStyleFactoryInterface:QFactoryInterface)
+public:
+ explicit QStylePlugin(QObject *parent = 0);
+ ~QStylePlugin();
+
+ virtual QStringList keys() const = 0;
+ virtual QStyle *create(const QString &key) = 0;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QSTYLEPLUGIN_H
diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp
new file mode 100644
index 0000000000..357b43c2b4
--- /dev/null
+++ b/src/widgets/styles/qstylesheetstyle.cpp
@@ -0,0 +1,5900 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qglobal.h>
+
+#ifndef QT_NO_STYLE_STYLESHEET
+
+#include "qstylesheetstyle_p.h"
+#include "private/qcssutil_p.h"
+#include <qdebug.h>
+#include <qapplication.h>
+#include <qmenu.h>
+#include <qmenubar.h>
+#include <qpainter.h>
+#include <qstyleoption.h>
+#include <qlineedit.h>
+#include <qwindowsstyle.h>
+#include <qcombobox.h>
+#include <qwindowsstyle.h>
+#include <qplastiquestyle.h>
+#include "private/qcssparser_p.h"
+#include "private/qmath_p.h"
+#include <qabstractscrollarea.h>
+#include "private/qabstractscrollarea_p.h"
+#include <qtooltip.h>
+#include <qshareddata.h>
+#include <qradiobutton.h>
+#include <qtoolbutton.h>
+#include <qscrollbar.h>
+#include <qstring.h>
+#include <qfile.h>
+#include <qcheckbox.h>
+#include <qstatusbar.h>
+#include <qheaderview.h>
+#include <qprogressbar.h>
+#include <private/qwindowsstyle_p.h>
+#include <qtabbar.h>
+#include <QMetaProperty>
+#include <qmainwindow.h>
+#include <qdockwidget.h>
+#include <qmdisubwindow.h>
+#include <qdialog.h>
+#include <private/qwidget_p.h>
+#include <QAbstractSpinBox>
+#include <QLabel>
+#include "qdrawutil.h"
+
+#include <limits.h>
+#include <QtWidgets/qtoolbar.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace QCss;
+
+
+class QStyleSheetStylePrivate : public QWindowsStylePrivate
+{
+ Q_DECLARE_PUBLIC(QStyleSheetStyle)
+public:
+ QStyleSheetStylePrivate() { }
+};
+
+
+static QStyleSheetStyleCaches *styleSheetCaches = 0;
+
+/* RECURSION_GUARD:
+ * the QStyleSheetStyle is a proxy. If used with others proxy style, we may end up with something like:
+ * QStyleSheetStyle -> ProxyStyle -> QStyleSheetStyle -> OriginalStyle
+ * Recursion may happen if the style call the widget()->style() again.
+ * Not to mention the performence penalty of having two lookup of rules.
+ *
+ * The first instance of QStyleSheetStyle will set globalStyleSheetStyle to itself. The second one
+ * will notice the globalStyleSheetStyle is not istelf and call its base style directly.
+ */
+static const QStyleSheetStyle *globalStyleSheetStyle = 0;
+class QStyleSheetStyleRecursionGuard
+{
+ public:
+ QStyleSheetStyleRecursionGuard(const QStyleSheetStyle *that)
+ : guarded(globalStyleSheetStyle == 0)
+ {
+ if (guarded) globalStyleSheetStyle = that;
+ }
+ ~QStyleSheetStyleRecursionGuard() { if (guarded) globalStyleSheetStyle = 0; }
+ bool guarded;
+};
+#define RECURSION_GUARD(RETURN) \
+ if (globalStyleSheetStyle != 0 && globalStyleSheetStyle != this) { RETURN; } \
+ QStyleSheetStyleRecursionGuard recursion_guard(this);
+
+#define ceil(x) ((int)(x) + ((x) > 0 && (x) != (int)(x)))
+
+enum PseudoElement {
+ PseudoElement_None,
+ PseudoElement_DownArrow,
+ PseudoElement_UpArrow,
+ PseudoElement_LeftArrow,
+ PseudoElement_RightArrow,
+ PseudoElement_Indicator,
+ PseudoElement_ExclusiveIndicator,
+ PseudoElement_PushButtonMenuIndicator,
+ PseudoElement_ComboBoxDropDown,
+ PseudoElement_ComboBoxArrow,
+ PseudoElement_Item,
+ PseudoElement_SpinBoxUpButton,
+ PseudoElement_SpinBoxUpArrow,
+ PseudoElement_SpinBoxDownButton,
+ PseudoElement_SpinBoxDownArrow,
+ PseudoElement_GroupBoxTitle,
+ PseudoElement_GroupBoxIndicator,
+ PseudoElement_ToolButtonMenu,
+ PseudoElement_ToolButtonMenuArrow,
+ PseudoElement_ToolButtonDownArrow,
+ PseudoElement_ToolBoxTab,
+ PseudoElement_ScrollBarSlider,
+ PseudoElement_ScrollBarAddPage,
+ PseudoElement_ScrollBarSubPage,
+ PseudoElement_ScrollBarAddLine,
+ PseudoElement_ScrollBarSubLine,
+ PseudoElement_ScrollBarFirst,
+ PseudoElement_ScrollBarLast,
+ PseudoElement_ScrollBarUpArrow,
+ PseudoElement_ScrollBarDownArrow,
+ PseudoElement_ScrollBarLeftArrow,
+ PseudoElement_ScrollBarRightArrow,
+ PseudoElement_SplitterHandle,
+ PseudoElement_ToolBarHandle,
+ PseudoElement_ToolBarSeparator,
+ PseudoElement_MenuScroller,
+ PseudoElement_MenuTearoff,
+ PseudoElement_MenuCheckMark,
+ PseudoElement_MenuSeparator,
+ PseudoElement_MenuIcon,
+ PseudoElement_MenuRightArrow,
+ PseudoElement_TreeViewBranch,
+ PseudoElement_HeaderViewSection,
+ PseudoElement_HeaderViewUpArrow,
+ PseudoElement_HeaderViewDownArrow,
+ PseudoElement_ProgressBarChunk,
+ PseudoElement_TabBarTab,
+ PseudoElement_TabBarScroller,
+ PseudoElement_TabBarTear,
+ PseudoElement_SliderGroove,
+ PseudoElement_SliderHandle,
+ PseudoElement_SliderAddPage,
+ PseudoElement_SliderSubPage,
+ PseudoElement_SliderTickmark,
+ PseudoElement_TabWidgetPane,
+ PseudoElement_TabWidgetTabBar,
+ PseudoElement_TabWidgetLeftCorner,
+ PseudoElement_TabWidgetRightCorner,
+ PseudoElement_DockWidgetTitle,
+ PseudoElement_DockWidgetCloseButton,
+ PseudoElement_DockWidgetFloatButton,
+ PseudoElement_DockWidgetSeparator,
+ PseudoElement_MdiCloseButton,
+ PseudoElement_MdiMinButton,
+ PseudoElement_MdiNormalButton,
+ PseudoElement_TitleBar,
+ PseudoElement_TitleBarCloseButton,
+ PseudoElement_TitleBarMinButton,
+ PseudoElement_TitleBarMaxButton,
+ PseudoElement_TitleBarShadeButton,
+ PseudoElement_TitleBarUnshadeButton,
+ PseudoElement_TitleBarNormalButton,
+ PseudoElement_TitleBarContextHelpButton,
+ PseudoElement_TitleBarSysMenu,
+ PseudoElement_ViewItem,
+ PseudoElement_ViewItemIcon,
+ PseudoElement_ViewItemText,
+ PseudoElement_ViewItemIndicator,
+ PseudoElement_ScrollAreaCorner,
+ PseudoElement_TabBarTabCloseButton,
+ NumPseudoElements
+};
+
+struct PseudoElementInfo {
+ QStyle::SubControl subControl;
+ const char *name;
+};
+
+static const PseudoElementInfo knownPseudoElements[NumPseudoElements] = {
+ { QStyle::SC_None, "" },
+ { QStyle::SC_None, "down-arrow" },
+ { QStyle::SC_None, "up-arrow" },
+ { QStyle::SC_None, "left-arrow" },
+ { QStyle::SC_None, "right-arrow" },
+ { QStyle::SC_None, "indicator" },
+ { QStyle::SC_None, "indicator" },
+ { QStyle::SC_None, "menu-indicator" },
+ { QStyle::SC_ComboBoxArrow, "drop-down" },
+ { QStyle::SC_ComboBoxArrow, "down-arrow" },
+ { QStyle::SC_None, "item" },
+ { QStyle::SC_SpinBoxUp, "up-button" },
+ { QStyle::SC_SpinBoxUp, "up-arrow" },
+ { QStyle::SC_SpinBoxDown, "down-button" },
+ { QStyle::SC_SpinBoxDown, "down-arrow" },
+ { QStyle::SC_GroupBoxLabel, "title" },
+ { QStyle::SC_GroupBoxCheckBox, "indicator" },
+ { QStyle::SC_ToolButtonMenu, "menu-button" },
+ { QStyle::SC_ToolButtonMenu, "menu-arrow" },
+ { QStyle::SC_None, "menu-indicator" },
+ { QStyle::SC_None, "tab" },
+ { QStyle::SC_ScrollBarSlider, "handle" },
+ { QStyle::SC_ScrollBarAddPage, "add-page" },
+ { QStyle::SC_ScrollBarSubPage, "sub-page" },
+ { QStyle::SC_ScrollBarAddLine, "add-line" },
+ { QStyle::SC_ScrollBarSubLine, "sub-line" },
+ { QStyle::SC_ScrollBarFirst, "first" },
+ { QStyle::SC_ScrollBarLast, "last" },
+ { QStyle::SC_ScrollBarSubLine, "up-arrow" },
+ { QStyle::SC_ScrollBarAddLine, "down-arrow" },
+ { QStyle::SC_ScrollBarSubLine, "left-arrow" },
+ { QStyle::SC_ScrollBarAddLine, "right-arrow" },
+ { QStyle::SC_None, "handle" },
+ { QStyle::SC_None, "handle" },
+ { QStyle::SC_None, "separator" },
+ { QStyle::SC_None, "scroller" },
+ { QStyle::SC_None, "tearoff" },
+ { QStyle::SC_None, "indicator" },
+ { QStyle::SC_None, "separator" },
+ { QStyle::SC_None, "icon" },
+ { QStyle::SC_None, "right-arrow" },
+ { QStyle::SC_None, "branch" },
+ { QStyle::SC_None, "section" },
+ { QStyle::SC_None, "down-arrow" },
+ { QStyle::SC_None, "up-arrow" },
+ { QStyle::SC_None, "chunk" },
+ { QStyle::SC_None, "tab" },
+ { QStyle::SC_None, "scroller" },
+ { QStyle::SC_None, "tear" },
+ { QStyle::SC_SliderGroove, "groove" },
+ { QStyle::SC_SliderHandle, "handle" },
+ { QStyle::SC_None, "add-page" },
+ { QStyle::SC_None, "sub-page"},
+ { QStyle::SC_SliderTickmarks, "tick-mark" },
+ { QStyle::SC_None, "pane" },
+ { QStyle::SC_None, "tab-bar" },
+ { QStyle::SC_None, "left-corner" },
+ { QStyle::SC_None, "right-corner" },
+ { QStyle::SC_None, "title" },
+ { QStyle::SC_None, "close-button" },
+ { QStyle::SC_None, "float-button" },
+ { QStyle::SC_None, "separator" },
+ { QStyle::SC_MdiCloseButton, "close-button" },
+ { QStyle::SC_MdiMinButton, "minimize-button" },
+ { QStyle::SC_MdiNormalButton, "normal-button" },
+ { QStyle::SC_TitleBarLabel, "title" },
+ { QStyle::SC_TitleBarCloseButton, "close-button" },
+ { QStyle::SC_TitleBarMinButton, "minimize-button" },
+ { QStyle::SC_TitleBarMaxButton, "maximize-button" },
+ { QStyle::SC_TitleBarShadeButton, "shade-button" },
+ { QStyle::SC_TitleBarUnshadeButton, "unshade-button" },
+ { QStyle::SC_TitleBarNormalButton, "normal-button" },
+ { QStyle::SC_TitleBarContextHelpButton, "contexthelp-button" },
+ { QStyle::SC_TitleBarSysMenu, "sys-menu" },
+ { QStyle::SC_None, "item" },
+ { QStyle::SC_None, "icon" },
+ { QStyle::SC_None, "text" },
+ { QStyle::SC_None, "indicator" },
+ { QStyle::SC_None, "corner" },
+ { QStyle::SC_None, "close-button" },
+};
+
+
+struct QStyleSheetBorderImageData : public QSharedData
+{
+ QStyleSheetBorderImageData()
+ : horizStretch(QCss::TileMode_Unknown), vertStretch(QCss::TileMode_Unknown)
+ {
+ for (int i = 0; i < 4; i++)
+ cuts[i] = -1;
+ }
+ int cuts[4];
+ QPixmap pixmap;
+ QImage image;
+ QCss::TileMode horizStretch, vertStretch;
+};
+
+struct QStyleSheetBackgroundData : public QSharedData
+{
+ QStyleSheetBackgroundData(const QBrush& b, const QPixmap& p, QCss::Repeat r,
+ Qt::Alignment a, QCss::Origin o, Attachment t, QCss::Origin c)
+ : brush(b), pixmap(p), repeat(r), position(a), origin(o), attachment(t), clip(c) { }
+
+ bool isTransparent() const {
+ if (brush.style() != Qt::NoBrush)
+ return !brush.isOpaque();
+ return pixmap.isNull() ? false : pixmap.hasAlpha();
+ }
+ QBrush brush;
+ QPixmap pixmap;
+ QCss::Repeat repeat;
+ Qt::Alignment position;
+ QCss::Origin origin;
+ QCss::Attachment attachment;
+ QCss::Origin clip;
+};
+
+struct QStyleSheetBorderData : public QSharedData
+{
+ QStyleSheetBorderData() : bi(0)
+ {
+ for (int i = 0; i < 4; i++) {
+ borders[i] = 0;
+ styles[i] = QCss::BorderStyle_None;
+ }
+ }
+
+ QStyleSheetBorderData(int *b, QBrush *c, QCss::BorderStyle *s, QSize *r) : bi(0)
+ {
+ for (int i = 0; i < 4; i++) {
+ borders[i] = b[i];
+ styles[i] = s[i];
+ colors[i] = c[i];
+ radii[i] = r[i];
+ }
+ }
+
+ int borders[4];
+ QBrush colors[4];
+ QCss::BorderStyle styles[4];
+ QSize radii[4]; // topleft, topright, bottomleft, bottomright
+
+ const QStyleSheetBorderImageData *borderImage() const
+ { return bi; }
+ bool hasBorderImage() const { return bi!=0; }
+
+ QSharedDataPointer<QStyleSheetBorderImageData> bi;
+
+ bool isOpaque() const
+ {
+ for (int i = 0; i < 4; i++) {
+ if (styles[i] == QCss::BorderStyle_Native || styles[i] == QCss::BorderStyle_None)
+ continue;
+ if (styles[i] >= QCss::BorderStyle_Dotted && styles[i] <= QCss::BorderStyle_DotDotDash
+ && styles[i] != BorderStyle_Solid)
+ return false;
+ if (!colors[i].isOpaque())
+ return false;
+ if (!radii[i].isEmpty())
+ return false;
+ }
+ if (bi != 0 && bi->pixmap.hasAlpha())
+ return false;
+ return true;
+ }
+};
+
+
+struct QStyleSheetOutlineData : public QStyleSheetBorderData
+{
+ QStyleSheetOutlineData()
+ {
+ for (int i = 0; i < 4; i++) {
+ offsets[i] = 0;
+ }
+ }
+
+ QStyleSheetOutlineData(int *b, QBrush *c, QCss::BorderStyle *s, QSize *r, int *o)
+ : QStyleSheetBorderData(b, c, s, r)
+ {
+ for (int i = 0; i < 4; i++) {
+ offsets[i] = o[i];
+ }
+ }
+
+ int offsets[4];
+};
+
+struct QStyleSheetBoxData : public QSharedData
+{
+ QStyleSheetBoxData(int *m, int *p, int s) : spacing(s)
+ {
+ for (int i = 0; i < 4; i++) {
+ margins[i] = m[i];
+ paddings[i] = p[i];
+ }
+ }
+
+ int margins[4];
+ int paddings[4];
+
+ int spacing;
+};
+
+struct QStyleSheetPaletteData : public QSharedData
+{
+ QStyleSheetPaletteData(const QBrush &fg, const QBrush &sfg, const QBrush &sbg,
+ const QBrush &abg)
+ : foreground(fg), selectionForeground(sfg), selectionBackground(sbg),
+ alternateBackground(abg) { }
+
+ QBrush foreground;
+ QBrush selectionForeground;
+ QBrush selectionBackground;
+ QBrush alternateBackground;
+};
+
+struct QStyleSheetGeometryData : public QSharedData
+{
+ QStyleSheetGeometryData(int w, int h, int minw, int minh, int maxw, int maxh)
+ : minWidth(minw), minHeight(minh), width(w), height(h), maxWidth(maxw), maxHeight(maxh) { }
+
+ int minWidth, minHeight, width, height, maxWidth, maxHeight;
+};
+
+struct QStyleSheetPositionData : public QSharedData
+{
+ QStyleSheetPositionData(int l, int t, int r, int b, Origin o, Qt::Alignment p, QCss::PositionMode m, Qt::Alignment a = 0)
+ : left(l), top(t), bottom(b), right(r), origin(o), position(p), mode(m), textAlignment(a) { }
+
+ int left, top, bottom, right;
+ Origin origin;
+ Qt::Alignment position;
+ QCss::PositionMode mode;
+ Qt::Alignment textAlignment;
+};
+
+struct QStyleSheetImageData : public QSharedData
+{
+ QStyleSheetImageData(const QIcon &i, Qt::Alignment a, const QSize &sz)
+ : icon(i), alignment(a), size(sz) { }
+
+ QIcon icon;
+ Qt::Alignment alignment;
+ QSize size;
+};
+
+class QRenderRule
+{
+public:
+ QRenderRule() : features(0), hasFont(false), pal(0), b(0), bg(0), bd(0), ou(0), geo(0), p(0), img(0), clipset(0) { }
+ QRenderRule(const QVector<QCss::Declaration> &, const QWidget *);
+ ~QRenderRule() { }
+
+ QRect borderRect(const QRect &r) const;
+ QRect outlineRect(const QRect &r) const;
+ QRect paddingRect(const QRect &r) const;
+ QRect contentsRect(const QRect &r) const;
+
+ enum { Margin = 1, Border = 2, Padding = 4, All=Margin|Border|Padding };
+ QRect boxRect(const QRect &r, int flags = All) const;
+ QSize boxSize(const QSize &s, int flags = All) const;
+ QRect originRect(const QRect &rect, Origin origin) const;
+
+ QPainterPath borderClip(QRect rect);
+ void drawBorder(QPainter *, const QRect&);
+ void drawOutline(QPainter *, const QRect&);
+ void drawBorderImage(QPainter *, const QRect&);
+ void drawBackground(QPainter *, const QRect&, const QPoint& = QPoint(0, 0));
+ void drawBackgroundImage(QPainter *, const QRect&, QPoint = QPoint(0, 0));
+ void drawFrame(QPainter *, const QRect&);
+ void drawImage(QPainter *p, const QRect &rect);
+ void drawRule(QPainter *, const QRect&);
+ void configurePalette(QPalette *, QPalette::ColorGroup, const QWidget *, bool);
+ void configurePalette(QPalette *p, QPalette::ColorRole fr, QPalette::ColorRole br);
+
+ const QStyleSheetPaletteData *palette() const { return pal; }
+ const QStyleSheetBoxData *box() const { return b; }
+ const QStyleSheetBackgroundData *background() const { return bg; }
+ const QStyleSheetBorderData *border() const { return bd; }
+ const QStyleSheetOutlineData *outline() const { return ou; }
+ const QStyleSheetGeometryData *geometry() const { return geo; }
+ const QStyleSheetPositionData *position() const { return p; }
+
+ bool hasPalette() const { return pal != 0; }
+ bool hasBackground() const { return bg != 0 && (!bg->pixmap.isNull() || bg->brush.style() != Qt::NoBrush); }
+ bool hasGradientBackground() const { return bg && bg->brush.style() >= Qt::LinearGradientPattern
+ && bg->brush.style() <= Qt::ConicalGradientPattern; }
+
+ bool hasNativeBorder() const {
+ return bd == 0
+ || (!bd->hasBorderImage() && bd->styles[0] == BorderStyle_Native);
+ }
+
+ bool hasNativeOutline() const {
+ return (ou == 0
+ || (!ou->hasBorderImage() && ou->styles[0] == BorderStyle_Native));
+ }
+
+ bool baseStyleCanDraw() const {
+ if (!hasBackground() || (background()->brush.style() == Qt::NoBrush && bg->pixmap.isNull()))
+ return true;
+ if (bg && !bg->pixmap.isNull())
+ return false;
+ if (hasGradientBackground())
+ return features & StyleFeature_BackgroundGradient;
+ return features & StyleFeature_BackgroundColor;
+ }
+
+ bool hasBox() const { return b != 0; }
+ bool hasBorder() const { return bd != 0; }
+ bool hasOutline() const { return ou != 0; }
+ bool hasPosition() const { return p != 0; }
+ bool hasGeometry() const { return geo != 0; }
+ bool hasDrawable() const { return !hasNativeBorder() || hasBackground() || hasImage(); }
+ bool hasImage() const { return img != 0; }
+
+ QSize minimumContentsSize() const
+ { return geo ? QSize(geo->minWidth, geo->minHeight) : QSize(0, 0); }
+ QSize minimumSize() const
+ { return boxSize(minimumContentsSize()); }
+
+ QSize contentsSize() const
+ { return geo ? QSize(geo->width, geo->height)
+ : ((img && img->size.isValid()) ? img->size : QSize()); }
+ QSize contentsSize(const QSize &sz) const
+ {
+ QSize csz = contentsSize();
+ if (csz.width() == -1) csz.setWidth(sz.width());
+ if (csz.height() == -1) csz.setHeight(sz.height());
+ return csz;
+ }
+ bool hasContentsSize() const
+ { return (geo && (geo->width != -1 || geo->height != -1)) || (img && img->size.isValid()); }
+
+ QSize size() const { return boxSize(contentsSize()); }
+ QSize size(const QSize &sz) const { return boxSize(contentsSize(sz)); }
+ QSize adjustSize(const QSize &sz)
+ {
+ if (!geo)
+ return sz;
+ QSize csz = contentsSize();
+ if (csz.width() == -1) csz.setWidth(sz.width());
+ if (csz.height() == -1) csz.setHeight(sz.height());
+ if (geo->maxWidth != -1 && csz.width() > geo->maxWidth) csz.setWidth(geo->maxWidth);
+ if (geo->maxHeight != -1 && csz.height() > geo->maxHeight) csz.setHeight(geo->maxHeight);
+ csz=csz.expandedTo(QSize(geo->minWidth, geo->minHeight));
+ return csz;
+ }
+
+ int features;
+ QBrush defaultBackground;
+ QFont font;
+ bool hasFont;
+
+ QHash<QString, QVariant> styleHints;
+ bool hasStyleHint(const QString& sh) const { return styleHints.contains(sh); }
+ QVariant styleHint(const QString& sh) const { return styleHints.value(sh); }
+
+ void fixupBorder(int);
+
+ QSharedDataPointer<QStyleSheetPaletteData> pal;
+ QSharedDataPointer<QStyleSheetBoxData> b;
+ QSharedDataPointer<QStyleSheetBackgroundData> bg;
+ QSharedDataPointer<QStyleSheetBorderData> bd;
+ QSharedDataPointer<QStyleSheetOutlineData> ou;
+ QSharedDataPointer<QStyleSheetGeometryData> geo;
+ QSharedDataPointer<QStyleSheetPositionData> p;
+ QSharedDataPointer<QStyleSheetImageData> img;
+
+ // Shouldn't be here
+ void setClip(QPainter *p, const QRect &rect);
+ void unsetClip(QPainter *);
+ int clipset;
+ QPainterPath clipPath;
+};
+
+///////////////////////////////////////////////////////////////////////////////////////////
+static const char *knownStyleHints[] = {
+ "activate-on-singleclick",
+ "alignment",
+ "arrow-keys-navigate-into-children",
+ "backward-icon",
+ "button-layout",
+ "cd-icon",
+ "combobox-list-mousetracking",
+ "combobox-popup",
+ "computer-icon",
+ "desktop-icon",
+ "dialog-apply-icon",
+ "dialog-cancel-icon",
+ "dialog-close-icon",
+ "dialog-discard-icon",
+ "dialog-help-icon",
+ "dialog-no-icon",
+ "dialog-ok-icon",
+ "dialog-open-icon",
+ "dialog-reset-icon",
+ "dialog-save-icon",
+ "dialog-yes-icon",
+ "dialogbuttonbox-buttons-have-icons",
+ "directory-closed-icon",
+ "directory-icon",
+ "directory-link-icon",
+ "directory-open-icon",
+ "dither-disable-text",
+ "dockwidget-close-icon",
+ "downarrow-icon",
+ "dvd-icon",
+ "etch-disabled-text",
+ "file-icon",
+ "file-link-icon",
+ "filedialog-backward-icon", // unused
+ "filedialog-contentsview-icon",
+ "filedialog-detailedview-icon",
+ "filedialog-end-icon",
+ "filedialog-infoview-icon",
+ "filedialog-listview-icon",
+ "filedialog-new-directory-icon",
+ "filedialog-parent-directory-icon",
+ "filedialog-start-icon",
+ "floppy-icon",
+ "forward-icon",
+ "gridline-color",
+ "harddisk-icon",
+ "home-icon",
+ "icon-size",
+ "leftarrow-icon",
+ "lineedit-password-character",
+ "mdi-fill-space-on-maximize",
+ "menu-scrollable",
+ "menubar-altkey-navigation",
+ "menubar-separator",
+ "messagebox-critical-icon",
+ "messagebox-information-icon",
+ "messagebox-question-icon",
+ "messagebox-text-interaction-flags",
+ "messagebox-warning-icon",
+ "mouse-tracking",
+ "network-icon",
+ "opacity",
+ "paint-alternating-row-colors-for-empty-area",
+ "rightarrow-icon",
+ "scrollbar-contextmenu",
+ "scrollbar-leftclick-absolute-position",
+ "scrollbar-middleclick-absolute-position",
+ "scrollbar-roll-between-buttons",
+ "scrollbar-scroll-when-pointer-leaves-control",
+ "scrollview-frame-around-contents",
+ "show-decoration-selected",
+ "spinbox-click-autorepeat-rate",
+ "spincontrol-disable-on-bounds",
+ "tabbar-elide-mode",
+ "tabbar-prefer-no-arrows",
+ "titlebar-close-icon",
+ "titlebar-contexthelp-icon",
+ "titlebar-maximize-icon",
+ "titlebar-menu-icon",
+ "titlebar-minimize-icon",
+ "titlebar-normal-icon",
+ "titlebar-shade-icon",
+ "titlebar-unshade-icon",
+ "toolbutton-popup-delay",
+ "trash-icon",
+ "uparrow-icon"
+};
+
+static const int numKnownStyleHints = sizeof(knownStyleHints)/sizeof(knownStyleHints[0]);
+
+static QList<QVariant> subControlLayout(const QString& layout)
+{
+ QList<QVariant> buttons;
+ for (int i = 0; i < layout.count(); i++) {
+ int button = layout[i].toAscii();
+ switch (button) {
+ case 'm':
+ buttons.append(PseudoElement_MdiMinButton);
+ buttons.append(PseudoElement_TitleBarMinButton);
+ break;
+ case 'M':
+ buttons.append(PseudoElement_TitleBarMaxButton);
+ break;
+ case 'X':
+ buttons.append(PseudoElement_MdiCloseButton);
+ buttons.append(PseudoElement_TitleBarCloseButton);
+ break;
+ case 'N':
+ buttons.append(PseudoElement_MdiNormalButton);
+ buttons.append(PseudoElement_TitleBarNormalButton);
+ break;
+ case 'I':
+ buttons.append(PseudoElement_TitleBarSysMenu);
+ break;
+ case 'T':
+ buttons.append(PseudoElement_TitleBar);
+ break;
+ case 'H':
+ buttons.append(PseudoElement_TitleBarContextHelpButton);
+ break;
+ case 'S':
+ buttons.append(PseudoElement_TitleBarShadeButton);
+ break;
+ default:
+ buttons.append(button);
+ break;
+ }
+ }
+ return buttons;
+}
+
+namespace {
+ struct ButtonInfo {
+ QRenderRule rule;
+ int element;
+ int offset;
+ int where;
+ int width;
+ };
+}
+
+QHash<QStyle::SubControl, QRect> QStyleSheetStyle::titleBarLayout(const QWidget *w, const QStyleOptionTitleBar *tb) const
+{
+ QHash<QStyle::SubControl, QRect> layoutRects;
+ const bool isMinimized = tb->titleBarState & Qt::WindowMinimized;
+ const bool isMaximized = tb->titleBarState & Qt::WindowMaximized;
+ QRenderRule subRule = renderRule(w, tb);
+ QRect cr = subRule.contentsRect(tb->rect);
+ QList<QVariant> layout = subRule.styleHint(QLatin1String("button-layout")).toList();
+ if (layout.isEmpty())
+ layout = subControlLayout(QLatin1String("I(T)HSmMX"));
+
+ int offsets[3] = { 0, 0, 0 };
+ enum Where { Left, Right, Center, NoWhere } where = Left;
+ QList<ButtonInfo> infos;
+ for (int i = 0; i < layout.count(); i++) {
+ ButtonInfo info;
+ info.element = layout[i].toInt();
+ if (info.element == '(') {
+ where = Center;
+ } else if (info.element == ')') {
+ where = Right;
+ } else {
+ switch (info.element) {
+ case PseudoElement_TitleBar:
+ if (!(tb->titleBarFlags & (Qt::WindowTitleHint | Qt::WindowSystemMenuHint)))
+ continue;
+ break;
+ case PseudoElement_TitleBarContextHelpButton:
+ if (!(tb->titleBarFlags & Qt::WindowContextHelpButtonHint))
+ continue;
+ break;
+ case PseudoElement_TitleBarMinButton:
+ if (!(tb->titleBarFlags & Qt::WindowMinimizeButtonHint))
+ continue;
+ if (isMinimized)
+ info.element = PseudoElement_TitleBarNormalButton;
+ break;
+ case PseudoElement_TitleBarMaxButton:
+ if (!(tb->titleBarFlags & Qt::WindowMaximizeButtonHint))
+ continue;
+ if (isMaximized)
+ info.element = PseudoElement_TitleBarNormalButton;
+ break;
+ case PseudoElement_TitleBarShadeButton:
+ if (!(tb->titleBarFlags & Qt::WindowShadeButtonHint))
+ continue;
+ if (isMinimized)
+ info.element = PseudoElement_TitleBarUnshadeButton;
+ break;
+ case PseudoElement_TitleBarCloseButton:
+ case PseudoElement_TitleBarSysMenu:
+ if (!(tb->titleBarFlags & Qt::WindowSystemMenuHint))
+ continue;
+ break;
+ default:
+ continue;
+ }
+ if (info.element == PseudoElement_TitleBar) {
+ info.width = tb->fontMetrics.width(tb->text) + 6;
+ subRule.geo = new QStyleSheetGeometryData(info.width, tb->fontMetrics.height(), -1, -1, -1, -1);
+ } else {
+ subRule = renderRule(w, tb, info.element);
+ info.width = subRule.size().width();
+ }
+ info.rule = subRule;
+ info.offset = offsets[where];
+ info.where = where;
+ infos.append(info);
+
+ offsets[where] += info.width;
+ }
+ }
+
+ for (int i = 0; i < infos.count(); i++) {
+ ButtonInfo info = infos[i];
+ QRect lr = cr;
+ switch (info.where) {
+ case Center: {
+ lr.setLeft(cr.left() + offsets[Left]);
+ lr.setRight(cr.right() - offsets[Right]);
+ QRect r(0, 0, offsets[Center], lr.height());
+ r.moveCenter(lr.center());
+ r.setLeft(r.left()+info.offset);
+ r.setWidth(info.width);
+ lr = r;
+ break; }
+ case Left:
+ lr.translate(info.offset, 0);
+ lr.setWidth(info.width);
+ break;
+ case Right:
+ lr.moveLeft(cr.right() + 1 - offsets[Right] + info.offset);
+ lr.setWidth(info.width);
+ break;
+ default:
+ break;
+ }
+ QStyle::SubControl control = knownPseudoElements[info.element].subControl;
+ layoutRects[control] = positionRect(w, info.rule, info.element, lr, tb->direction);
+ }
+
+ return layoutRects;
+}
+
+static QStyle::StandardPixmap subControlIcon(int pe)
+{
+ switch (pe) {
+ case PseudoElement_MdiCloseButton: return QStyle::SP_TitleBarCloseButton;
+ case PseudoElement_MdiMinButton: return QStyle::SP_TitleBarMinButton;
+ case PseudoElement_MdiNormalButton: return QStyle::SP_TitleBarNormalButton;
+ case PseudoElement_TitleBarCloseButton: return QStyle::SP_TitleBarCloseButton;
+ case PseudoElement_TitleBarMinButton: return QStyle::SP_TitleBarMinButton;
+ case PseudoElement_TitleBarMaxButton: return QStyle::SP_TitleBarMaxButton;
+ case PseudoElement_TitleBarShadeButton: return QStyle::SP_TitleBarShadeButton;
+ case PseudoElement_TitleBarUnshadeButton: return QStyle::SP_TitleBarUnshadeButton;
+ case PseudoElement_TitleBarNormalButton: return QStyle::SP_TitleBarNormalButton;
+ case PseudoElement_TitleBarContextHelpButton: return QStyle::SP_TitleBarContextHelpButton;
+ default: break;
+ }
+ return QStyle::SP_CustomBase;
+}
+
+QRenderRule::QRenderRule(const QVector<Declaration> &declarations, const QWidget *widget)
+: features(0), hasFont(false), pal(0), b(0), bg(0), bd(0), ou(0), geo(0), p(0), img(0), clipset(0)
+{
+ QPalette palette = QApplication::palette(); // ###: ideally widget's palette
+ ValueExtractor v(declarations, palette);
+ features = v.extractStyleFeatures();
+
+ int w = -1, h = -1, minw = -1, minh = -1, maxw = -1, maxh = -1;
+ if (v.extractGeometry(&w, &h, &minw, &minh, &maxw, &maxh))
+ geo = new QStyleSheetGeometryData(w, h, minw, minh, maxw, maxh);
+
+ int left = 0, top = 0, right = 0, bottom = 0;
+ Origin origin = Origin_Unknown;
+ Qt::Alignment position = 0;
+ QCss::PositionMode mode = PositionMode_Unknown;
+ Qt::Alignment textAlignment = 0;
+ if (v.extractPosition(&left, &top, &right, &bottom, &origin, &position, &mode, &textAlignment))
+ p = new QStyleSheetPositionData(left, top, right, bottom, origin, position, mode, textAlignment);
+
+ int margins[4], paddings[4], spacing = -1;
+ for (int i = 0; i < 4; i++)
+ margins[i] = paddings[i] = 0;
+ if (v.extractBox(margins, paddings, &spacing))
+ b = new QStyleSheetBoxData(margins, paddings, spacing);
+
+ int borders[4];
+ QBrush colors[4];
+ QCss::BorderStyle styles[4];
+ QSize radii[4];
+ for (int i = 0; i < 4; i++) {
+ borders[i] = 0;
+ styles[i] = BorderStyle_None;
+ }
+ if (v.extractBorder(borders, colors, styles, radii))
+ bd = new QStyleSheetBorderData(borders, colors, styles, radii);
+
+ int offsets[4];
+ for (int i = 0; i < 4; i++) {
+ borders[i] = offsets[i] = 0;
+ styles[i] = BorderStyle_None;
+ }
+ if (v.extractOutline(borders, colors, styles, radii, offsets))
+ ou = new QStyleSheetOutlineData(borders, colors, styles, radii, offsets);
+
+ QBrush brush;
+ QString uri;
+ Repeat repeat = Repeat_XY;
+ Qt::Alignment alignment = Qt::AlignTop | Qt::AlignLeft;
+ Attachment attachment = Attachment_Scroll;
+ origin = Origin_Padding;
+ Origin clip = Origin_Border;
+ if (v.extractBackground(&brush, &uri, &repeat, &alignment, &origin, &attachment, &clip))
+ bg = new QStyleSheetBackgroundData(brush, QPixmap(uri), repeat, alignment, origin, attachment, clip);
+
+ QBrush sfg, fg;
+ QBrush sbg, abg;
+ if (v.extractPalette(&fg, &sfg, &sbg, &abg))
+ pal = new QStyleSheetPaletteData(fg, sfg, sbg, abg);
+
+ QIcon icon;
+ alignment = Qt::AlignCenter;
+ QSize size;
+ if (v.extractImage(&icon, &alignment, &size))
+ img = new QStyleSheetImageData(icon, alignment, size);
+
+ int adj = -255;
+ hasFont = v.extractFont(&font, &adj);
+
+#ifndef QT_NO_TOOLTIP
+ if (widget && qstrcmp(widget->metaObject()->className(), "QTipLabel") == 0)
+ palette = QToolTip::palette();
+#endif
+
+ for (int i = 0; i < declarations.count(); i++) {
+ const Declaration& decl = declarations.at(i);
+ if (decl.d->propertyId == BorderImage) {
+ QString uri;
+ QCss::TileMode horizStretch, vertStretch;
+ int cuts[4];
+
+ decl.borderImageValue(&uri, cuts, &horizStretch, &vertStretch);
+ if (uri.isEmpty() || uri == QLatin1String("none")) {
+ if (bd && bd->bi)
+ bd->bi->pixmap = QPixmap();
+ } else {
+ if (!bd)
+ bd = new QStyleSheetBorderData;
+ if (!bd->bi)
+ bd->bi = new QStyleSheetBorderImageData;
+
+ QStyleSheetBorderImageData *bi = bd->bi;
+ bi->pixmap = QPixmap(uri);
+ for (int i = 0; i < 4; i++)
+ bi->cuts[i] = cuts[i];
+ bi->horizStretch = horizStretch;
+ bi->vertStretch = vertStretch;
+ }
+ } else if (decl.d->propertyId == QtBackgroundRole) {
+ if (bg && bg->brush.style() != Qt::NoBrush)
+ continue;
+ int role = decl.d->values.at(0).variant.toInt();
+ if (role >= Value_FirstColorRole && role <= Value_LastColorRole)
+ defaultBackground = palette.color((QPalette::ColorRole)(role-Value_FirstColorRole));
+ } else if (decl.d->property.startsWith(QLatin1String("qproperty-"), Qt::CaseInsensitive)) {
+ // intentionally left blank...
+ } else if (decl.d->propertyId == UnknownProperty) {
+ bool knownStyleHint = false;
+ for (int i = 0; i < numKnownStyleHints; i++) {
+ QLatin1String styleHint(knownStyleHints[i]);
+ if (decl.d->property.compare(styleHint) == 0) {
+ QString hintName = QString(styleHint);
+ QVariant hintValue;
+ if (hintName.endsWith(QLatin1String("alignment"))) {
+ hintValue = (int) decl.alignmentValue();
+ } else if (hintName.endsWith(QLatin1String("color"))) {
+ hintValue = (int) decl.colorValue().rgba();
+ } else if (hintName.endsWith(QLatin1String("size"))) {
+ hintValue = decl.sizeValue();
+ // ### Qt5
+// } else if (hintName.endsWith(QLatin1String("icon"))) {
+// hintValue = decl.iconValue();
+ } else if (hintName == QLatin1String("button-layout")
+ && decl.d->values.count() != 0 && decl.d->values.at(0).type == Value::String) {
+ hintValue = subControlLayout(decl.d->values.at(0).variant.toString());
+ } else {
+ int integer;
+ decl.intValue(&integer);
+ hintValue = integer;
+ }
+ styleHints[decl.d->property] = hintValue;
+ knownStyleHint = true;
+ break;
+ }
+ }
+ if (!knownStyleHint)
+ qDebug("Unknown property %s", qPrintable(decl.d->property));
+ }
+ }
+
+ if (widget) {
+ QStyleSheetStyle *style = const_cast<QStyleSheetStyle *>(globalStyleSheetStyle);
+ if (!style)
+ style = qobject_cast<QStyleSheetStyle *>(widget->style());
+ if (style)
+ fixupBorder(style->nativeFrameWidth(widget));
+
+ }
+ if (hasBorder() && border()->hasBorderImage())
+ defaultBackground = QBrush();
+}
+
+QRect QRenderRule::borderRect(const QRect& r) const
+{
+ if (!hasBox())
+ return r;
+ const int* m = box()->margins;
+ return r.adjusted(m[LeftEdge], m[TopEdge], -m[RightEdge], -m[BottomEdge]);
+}
+
+QRect QRenderRule::outlineRect(const QRect& r) const
+{
+ QRect br = borderRect(r);
+ if (!hasOutline())
+ return br;
+ const int *b = outline()->borders;
+ return r.adjusted(b[LeftEdge], b[TopEdge], -b[RightEdge], -b[BottomEdge]);
+}
+
+QRect QRenderRule::paddingRect(const QRect& r) const
+{
+ QRect br = borderRect(r);
+ if (!hasBorder())
+ return br;
+ const int *b = border()->borders;
+ return br.adjusted(b[LeftEdge], b[TopEdge], -b[RightEdge], -b[BottomEdge]);
+}
+
+QRect QRenderRule::contentsRect(const QRect& r) const
+{
+ QRect pr = paddingRect(r);
+ if (!hasBox())
+ return pr;
+ const int *p = box()->paddings;
+ return pr.adjusted(p[LeftEdge], p[TopEdge], -p[RightEdge], -p[BottomEdge]);
+}
+
+QRect QRenderRule::boxRect(const QRect& cr, int flags) const
+{
+ QRect r = cr;
+ if (hasBox()) {
+ if (flags & Margin) {
+ const int *m = box()->margins;
+ r.adjust(-m[LeftEdge], -m[TopEdge], m[RightEdge], m[BottomEdge]);
+ }
+ if (flags & Padding) {
+ const int *p = box()->paddings;
+ r.adjust(-p[LeftEdge], -p[TopEdge], p[RightEdge], p[BottomEdge]);
+ }
+ }
+ if (hasBorder() && (flags & Border)) {
+ const int *b = border()->borders;
+ r.adjust(-b[LeftEdge], -b[TopEdge], b[RightEdge], b[BottomEdge]);
+ }
+ return r;
+}
+
+QSize QRenderRule::boxSize(const QSize &cs, int flags) const
+{
+ QSize bs = boxRect(QRect(QPoint(0, 0), cs), flags).size();
+ if (cs.width() < 0) bs.setWidth(-1);
+ if (cs.height() < 0) bs.setHeight(-1);
+ return bs;
+}
+
+void QRenderRule::fixupBorder(int nativeWidth)
+{
+ if (bd == 0)
+ return;
+
+ if (!bd->hasBorderImage() || bd->bi->pixmap.isNull()) {
+ bd->bi = 0;
+ // ignore the color, border of edges that have none border-style
+ QBrush color = pal ? pal->foreground : QBrush();
+ const bool hasRadius = bd->radii[0].isValid() || bd->radii[1].isValid()
+ || bd->radii[2].isValid() || bd->radii[3].isValid();
+ for (int i = 0; i < 4; i++) {
+ if ((bd->styles[i] == BorderStyle_Native) && hasRadius)
+ bd->styles[i] = BorderStyle_None;
+
+ switch (bd->styles[i]) {
+ case BorderStyle_None:
+ // border-style: none forces width to be 0
+ bd->colors[i] = QBrush();
+ bd->borders[i] = 0;
+ break;
+ case BorderStyle_Native:
+ if (bd->borders[i] == 0)
+ bd->borders[i] = nativeWidth;
+ // intentional fall through
+ default:
+ if (!bd->colors[i].style() != Qt::NoBrush) // auto-acquire 'color'
+ bd->colors[i] = color;
+ break;
+ }
+ }
+
+ return;
+ }
+
+ // inspect the border image
+ QStyleSheetBorderImageData *bi = bd->bi;
+ if (bi->cuts[0] == -1) {
+ for (int i = 0; i < 4; i++) // assume, cut = border
+ bi->cuts[i] = int(border()->borders[i]);
+ }
+}
+
+void QRenderRule::drawBorderImage(QPainter *p, const QRect& rect)
+{
+ setClip(p, rect);
+ static const Qt::TileRule tileMode2TileRule[] = {
+ Qt::StretchTile, Qt::RoundTile, Qt::StretchTile, Qt::RepeatTile, Qt::StretchTile };
+
+ const QStyleSheetBorderImageData *borderImageData = border()->borderImage();
+ const int *targetBorders = border()->borders;
+ const int *sourceBorders = borderImageData->cuts;
+ QMargins sourceMargins(sourceBorders[LeftEdge], sourceBorders[TopEdge],
+ sourceBorders[RightEdge], sourceBorders[BottomEdge]);
+ QMargins targetMargins(targetBorders[LeftEdge], targetBorders[TopEdge],
+ targetBorders[RightEdge], targetBorders[BottomEdge]);
+
+ bool wasSmoothPixmapTransform = p->renderHints() & QPainter::SmoothPixmapTransform;
+ p->setRenderHint(QPainter::SmoothPixmapTransform);
+ qDrawBorderPixmap(p, rect, targetMargins, borderImageData->pixmap,
+ QRect(QPoint(), borderImageData->pixmap.size()), sourceMargins,
+ QTileRules(tileMode2TileRule[borderImageData->horizStretch], tileMode2TileRule[borderImageData->vertStretch]));
+ p->setRenderHint(QPainter::SmoothPixmapTransform, wasSmoothPixmapTransform);
+ unsetClip(p);
+}
+
+QRect QRenderRule::originRect(const QRect &rect, Origin origin) const
+{
+ switch (origin) {
+ case Origin_Padding:
+ return paddingRect(rect);
+ case Origin_Border:
+ return borderRect(rect);
+ case Origin_Content:
+ return contentsRect(rect);
+ case Origin_Margin:
+ default:
+ return rect;
+ }
+}
+
+void QRenderRule::drawBackgroundImage(QPainter *p, const QRect &rect, QPoint off)
+{
+ if (!hasBackground())
+ return;
+
+ const QPixmap& bgp = background()->pixmap;
+ if (bgp.isNull())
+ return;
+
+ setClip(p, borderRect(rect));
+
+ if (background()->origin != background()->clip) {
+ p->save();
+ p->setClipRect(originRect(rect, background()->clip), Qt::IntersectClip);
+ }
+
+ if (background()->attachment == Attachment_Fixed)
+ off = QPoint(0, 0);
+
+ QRect r = originRect(rect, background()->origin);
+ QRect aligned = QStyle::alignedRect(Qt::LeftToRight, background()->position, bgp.size(), r);
+ QRect inter = aligned.translated(-off).intersected(r);
+
+ switch (background()->repeat) {
+ case Repeat_Y:
+ p->drawTiledPixmap(inter.x(), r.y(), inter.width(), r.height(), bgp,
+ inter.x() - aligned.x() + off.x(),
+ bgp.height() - int(aligned.y() - r.y()) % bgp.height() + off.y());
+ break;
+ case Repeat_X:
+ p->drawTiledPixmap(r.x(), inter.y(), r.width(), inter.height(), bgp,
+ bgp.width() - int(aligned.x() - r.x())%bgp.width() + off.x(),
+ inter.y() - aligned.y() + off.y());
+ break;
+ case Repeat_XY:
+ p->drawTiledPixmap(r, bgp,
+ QPoint(bgp.width() - int(aligned.x() - r.x())% bgp.width() + off.x(),
+ bgp.height() - int(aligned.y() - r.y())%bgp.height() + off.y()));
+ break;
+ case Repeat_None:
+ default:
+ p->drawPixmap(inter.x(), inter.y(), bgp, inter.x() - aligned.x() + off.x(),
+ inter.y() - aligned.y() + off.y(), inter.width(), inter.height());
+ break;
+ }
+
+
+ if (background()->origin != background()->clip)
+ p->restore();
+
+ unsetClip(p);
+}
+
+void QRenderRule::drawOutline(QPainter *p, const QRect &rect)
+{
+ if (!hasOutline())
+ return;
+
+ bool wasAntialiased = p->renderHints() & QPainter::Antialiasing;
+ p->setRenderHint(QPainter::Antialiasing);
+ qDrawBorder(p, rect, ou->styles, ou->borders, ou->colors, ou->radii);
+ p->setRenderHint(QPainter::Antialiasing, wasAntialiased);
+}
+
+void QRenderRule::drawBorder(QPainter *p, const QRect& rect)
+{
+ if (!hasBorder())
+ return;
+
+ if (border()->hasBorderImage()) {
+ drawBorderImage(p, rect);
+ return;
+ }
+
+ bool wasAntialiased = p->renderHints() & QPainter::Antialiasing;
+ p->setRenderHint(QPainter::Antialiasing);
+ qDrawBorder(p, rect, bd->styles, bd->borders, bd->colors, bd->radii);
+ p->setRenderHint(QPainter::Antialiasing, wasAntialiased);
+}
+
+QPainterPath QRenderRule::borderClip(QRect r)
+{
+ if (!hasBorder())
+ return QPainterPath();
+
+ QSize tlr, trr, blr, brr;
+ qNormalizeRadii(r, bd->radii, &tlr, &trr, &blr, &brr);
+ if (tlr.isNull() && trr.isNull() && blr.isNull() && brr.isNull())
+ return QPainterPath();
+
+ const QRectF rect(r);
+ const int *borders = border()->borders;
+ QPainterPath path;
+ qreal curY = rect.y() + borders[TopEdge]/2.0;
+ path.moveTo(rect.x() + tlr.width(), curY);
+ path.lineTo(rect.right() - trr.width(), curY);
+ qreal curX = rect.right() - borders[RightEdge]/2.0;
+ path.arcTo(curX - 2*trr.width() + borders[RightEdge], curY,
+ trr.width()*2 - borders[RightEdge], trr.height()*2 - borders[TopEdge], 90, -90);
+
+ path.lineTo(curX, rect.bottom() - brr.height());
+ curY = rect.bottom() - borders[BottomEdge]/2.0;
+ path.arcTo(curX - 2*brr.width() + borders[RightEdge], curY - 2*brr.height() + borders[BottomEdge],
+ brr.width()*2 - borders[RightEdge], brr.height()*2 - borders[BottomEdge], 0, -90);
+
+ path.lineTo(rect.x() + blr.width(), curY);
+ curX = rect.left() + borders[LeftEdge]/2.0;
+ path.arcTo(curX, rect.bottom() - 2*blr.height() + borders[BottomEdge]/2,
+ blr.width()*2 - borders[LeftEdge], blr.height()*2 - borders[BottomEdge], 270, -90);
+
+ path.lineTo(curX, rect.top() + tlr.height());
+ path.arcTo(curX, rect.top() + borders[TopEdge]/2,
+ tlr.width()*2 - borders[LeftEdge], tlr.height()*2 - borders[TopEdge], 180, -90);
+
+ path.closeSubpath();
+ return path;
+}
+
+/*! \internal
+ Clip the painter to the border (in case we are using radius border)
+ */
+void QRenderRule::setClip(QPainter *p, const QRect &rect)
+{
+ if (clipset++)
+ return;
+ clipPath = borderClip(rect);
+ if (!clipPath.isEmpty()) {
+ p->save();
+ p->setClipPath(clipPath, Qt::IntersectClip);
+ }
+}
+
+void QRenderRule::unsetClip(QPainter *p)
+{
+ if (--clipset)
+ return;
+ if (!clipPath.isEmpty())
+ p->restore();
+}
+
+void QRenderRule::drawBackground(QPainter *p, const QRect& rect, const QPoint& off)
+{
+ QBrush brush = hasBackground() ? background()->brush : QBrush();
+ if (brush.style() == Qt::NoBrush)
+ brush = defaultBackground;
+
+ if (brush.style() != Qt::NoBrush) {
+ Origin origin = hasBackground() ? background()->clip : Origin_Border;
+ // ### fix for gradients
+ const QPainterPath &borderPath = borderClip(originRect(rect, origin));
+ if (!borderPath.isEmpty()) {
+ // Drawn intead of being used as clipping path for better visual quality
+ bool wasAntialiased = p->renderHints() & QPainter::Antialiasing;
+ p->setRenderHint(QPainter::Antialiasing);
+ p->fillPath(borderPath, brush);
+ p->setRenderHint(QPainter::Antialiasing, wasAntialiased);
+ } else {
+ p->fillRect(originRect(rect, origin), brush);
+ }
+ }
+
+ drawBackgroundImage(p, rect, off);
+}
+
+void QRenderRule::drawFrame(QPainter *p, const QRect& rect)
+{
+ drawBackground(p, rect);
+ if (hasBorder())
+ drawBorder(p, borderRect(rect));
+}
+
+void QRenderRule::drawImage(QPainter *p, const QRect &rect)
+{
+ if (!hasImage())
+ return;
+ img->icon.paint(p, rect, img->alignment);
+}
+
+void QRenderRule::drawRule(QPainter *p, const QRect& rect)
+{
+ drawFrame(p, rect);
+ drawImage(p, contentsRect(rect));
+}
+
+// *shudder* , *horror*, *whoa* <-- what you might feel when you see the functions below
+void QRenderRule::configurePalette(QPalette *p, QPalette::ColorRole fr, QPalette::ColorRole br)
+{
+ if (bg && bg->brush.style() != Qt::NoBrush) {
+ if (br != QPalette::NoRole)
+ p->setBrush(br, bg->brush);
+ p->setBrush(QPalette::Window, bg->brush);
+ if (bg->brush.style() == Qt::SolidPattern) {
+ p->setBrush(QPalette::Light, bg->brush.color().lighter(115));
+ p->setBrush(QPalette::Midlight, bg->brush.color().lighter(107));
+ p->setBrush(QPalette::Dark, bg->brush.color().darker(150));
+ p->setBrush(QPalette::Shadow, bg->brush.color().darker(300));
+ }
+ }
+
+ if (!hasPalette())
+ return;
+
+ if (pal->foreground.style() != Qt::NoBrush) {
+ if (fr != QPalette::NoRole)
+ p->setBrush(fr, pal->foreground);
+ p->setBrush(QPalette::WindowText, pal->foreground);
+ p->setBrush(QPalette::Text, pal->foreground);
+ }
+ if (pal->selectionBackground.style() != Qt::NoBrush)
+ p->setBrush(QPalette::Highlight, pal->selectionBackground);
+ if (pal->selectionForeground.style() != Qt::NoBrush)
+ p->setBrush(QPalette::HighlightedText, pal->selectionForeground);
+ if (pal->alternateBackground.style() != Qt::NoBrush)
+ p->setBrush(QPalette::AlternateBase, pal->alternateBackground);
+}
+
+void QRenderRule::configurePalette(QPalette *p, QPalette::ColorGroup cg, const QWidget *w, bool embedded)
+{
+ if (bg && bg->brush.style() != Qt::NoBrush) {
+ 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) {
+ /* For embedded widgets (ComboBox, SpinBox and ScrollArea) we want the embedded widget
+ * to be transparent when we have a transparent background or border image */
+ if ((hasBackground() && background()->isTransparent())
+ || (hasBorder() && border()->hasBorderImage() && !border()->borderImage()->pixmap.isNull()))
+ p->setBrush(cg, w->backgroundRole(), Qt::NoBrush);
+ }
+
+ if (!hasPalette())
+ return;
+
+ if (pal->foreground.style() != Qt::NoBrush) {
+ 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)
+ p->setBrush(cg, QPalette::Highlight, pal->selectionBackground);
+ if (pal->selectionForeground.style() != Qt::NoBrush)
+ p->setBrush(cg, QPalette::HighlightedText, pal->selectionForeground);
+ if (pal->alternateBackground.style() != Qt::NoBrush)
+ p->setBrush(cg, QPalette::AlternateBase, pal->alternateBackground);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Style rules
+#define WIDGET(x) (static_cast<QWidget *>(x.ptr))
+
+static inline QWidget *parentWidget(const QWidget *w)
+{
+ if(qobject_cast<const QLabel *>(w) && qstrcmp(w->metaObject()->className(), "QTipLabel") == 0) {
+ QWidget *p = qvariant_cast<QWidget *>(w->property("_q_stylesheet_parent"));
+ if (p)
+ return p;
+ }
+ return w->parentWidget();
+}
+
+class QStyleSheetStyleSelector : public StyleSelector
+{
+public:
+ QStyleSheetStyleSelector() { }
+
+ QStringList nodeNames(NodePtr node) const
+ {
+ if (isNullNode(node))
+ return QStringList();
+ const QMetaObject *metaObject = WIDGET(node)->metaObject();
+#ifndef QT_NO_TOOLTIP
+ if (qstrcmp(metaObject->className(), "QTipLabel") == 0)
+ return QStringList(QLatin1String("QToolTip"));
+#endif
+ QStringList result;
+ do {
+ result += QString::fromLatin1(metaObject->className()).replace(QLatin1Char(':'), QLatin1Char('-'));
+ metaObject = metaObject->superClass();
+ } while (metaObject != 0);
+ return result;
+ }
+ QString attribute(NodePtr node, const QString& name) const
+ {
+ if (isNullNode(node))
+ return QString();
+
+ QHash<QString, QString> &cache = m_attributeCache[WIDGET(node)];
+ QHash<QString, QString>::const_iterator cacheIt = cache.constFind(name);
+ if (cacheIt != cache.constEnd())
+ return cacheIt.value();
+
+ QVariant value = WIDGET(node)->property(name.toLatin1());
+ if (!value.isValid()) {
+ if (name == QLatin1String("class")) {
+ QString className = QString::fromLatin1(WIDGET(node)->metaObject()->className());
+ if (className.contains(QLatin1Char(':')))
+ className.replace(QLatin1Char(':'), QLatin1Char('-'));
+ cache[name] = className;
+ return className;
+ } else if (name == QLatin1String("style")) {
+ QStyleSheetStyle *proxy = qobject_cast<QStyleSheetStyle *>(WIDGET(node)->style());
+ if (proxy) {
+ QString styleName = QString::fromLatin1(proxy->baseStyle()->metaObject()->className());
+ cache[name] = styleName;
+ return styleName;
+ }
+ }
+ }
+ QString valueStr;
+ if(value.type() == QVariant::StringList || value.type() == QVariant::List)
+ valueStr = value.toStringList().join(QLatin1String(" "));
+ else
+ valueStr = value.toString();
+ cache[name] = valueStr;
+ return valueStr;
+ }
+ bool nodeNameEquals(NodePtr node, const QString& nodeName) const
+ {
+ if (isNullNode(node))
+ return false;
+ const QMetaObject *metaObject = WIDGET(node)->metaObject();
+#ifndef QT_NO_TOOLTIP
+ if (qstrcmp(metaObject->className(), "QTipLabel") == 0)
+ return nodeName == QLatin1String("QToolTip");
+#endif
+ do {
+ const ushort *uc = (const ushort *)nodeName.constData();
+ const ushort *e = uc + nodeName.length();
+ const uchar *c = (uchar *)metaObject->className();
+ while (*c && uc != e && (*uc == *c || (*c == ':' && *uc == '-'))) {
+ ++uc;
+ ++c;
+ }
+ if (uc == e && !*c)
+ return true;
+ metaObject = metaObject->superClass();
+ } while (metaObject != 0);
+ return false;
+ }
+ bool hasAttributes(NodePtr) const
+ { return true; }
+ QStringList nodeIds(NodePtr node) const
+ { return isNullNode(node) ? QStringList() : QStringList(WIDGET(node)->objectName()); }
+ bool isNullNode(NodePtr node) const
+ { return node.ptr == 0; }
+ NodePtr parentNode(NodePtr node) const
+ { NodePtr n; n.ptr = isNullNode(node) ? 0 : parentWidget(WIDGET(node)); return n; }
+ NodePtr previousSiblingNode(NodePtr) const
+ { NodePtr n; n.ptr = 0; return n; }
+ NodePtr duplicateNode(NodePtr node) const
+ { return node; }
+ void freeNode(NodePtr) const
+ { }
+
+private:
+ mutable QHash<const QWidget *, QHash<QString, QString> > m_attributeCache;
+};
+
+QVector<QCss::StyleRule> QStyleSheetStyle::styleRules(const QWidget *w) const
+{
+ QHash<const QWidget *, QVector<StyleRule> >::const_iterator cacheIt = styleSheetCaches->styleRulesCache.constFind(w);
+ if (cacheIt != styleSheetCaches->styleRulesCache.constEnd())
+ return cacheIt.value();
+
+ if (!initWidget(w)) {
+ return QVector<StyleRule>();
+ }
+
+ QStyleSheetStyleSelector styleSelector;
+
+ StyleSheet defaultSs;
+ QHash<const void *, StyleSheet>::const_iterator defaultCacheIt = styleSheetCaches->styleSheetCache.constFind(baseStyle());
+ if (defaultCacheIt == styleSheetCaches->styleSheetCache.constEnd()) {
+ defaultSs = getDefaultStyleSheet();
+ QStyle *bs = baseStyle();
+ styleSheetCaches->styleSheetCache.insert(bs, defaultSs);
+ QObject::connect(bs, SIGNAL(destroyed(QObject*)), styleSheetCaches, SLOT(styleDestroyed(QObject*)), Qt::UniqueConnection);
+ } else {
+ defaultSs = defaultCacheIt.value();
+ }
+ styleSelector.styleSheets += defaultSs;
+
+ if (!qApp->styleSheet().isEmpty()) {
+ StyleSheet appSs;
+ QHash<const void *, StyleSheet>::const_iterator appCacheIt = styleSheetCaches->styleSheetCache.constFind(qApp);
+ if (appCacheIt == styleSheetCaches->styleSheetCache.constEnd()) {
+ QString ss = qApp->styleSheet();
+ if (ss.startsWith(QLatin1String("file:///")))
+ ss.remove(0, 8);
+ parser.init(ss, qApp->styleSheet() != ss);
+ if (!parser.parse(&appSs))
+ qWarning("Could not parse application stylesheet");
+ appSs.origin = StyleSheetOrigin_Inline;
+ appSs.depth = 1;
+ styleSheetCaches->styleSheetCache.insert(qApp, appSs);
+ } else {
+ appSs = appCacheIt.value();
+ }
+ styleSelector.styleSheets += appSs;
+ }
+
+ QVector<QCss::StyleSheet> widgetSs;
+ for (const QWidget *wid = w; wid; wid = parentWidget(wid)) {
+ if (wid->styleSheet().isEmpty())
+ continue;
+ StyleSheet ss;
+ QHash<const void *, StyleSheet>::const_iterator widCacheIt = styleSheetCaches->styleSheetCache.constFind(wid);
+ if (widCacheIt == styleSheetCaches->styleSheetCache.constEnd()) {
+ parser.init(wid->styleSheet());
+ if (!parser.parse(&ss)) {
+ parser.init(QLatin1String("* {") + wid->styleSheet() + QLatin1Char('}'));
+ if (!parser.parse(&ss))
+ qWarning("Could not parse stylesheet of widget %p", wid);
+ }
+ ss.origin = StyleSheetOrigin_Inline;
+ styleSheetCaches->styleSheetCache.insert(wid, ss);
+ } else {
+ ss = widCacheIt.value();
+ }
+ widgetSs.append(ss);
+ }
+
+ for (int i = 0; i < widgetSs.count(); i++)
+ widgetSs[i].depth = widgetSs.count() - i + 2;
+
+ styleSelector.styleSheets += widgetSs;
+
+ StyleSelector::NodePtr n;
+ n.ptr = (void *)w;
+ QVector<QCss::StyleRule> rules = styleSelector.styleRulesForNode(n);
+ styleSheetCaches->styleRulesCache.insert(w, rules);
+ return rules;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Rendering rules
+static QVector<Declaration> declarations(const QVector<StyleRule> &styleRules, const QString &part, quint64 pseudoClass = PseudoClass_Unspecified)
+{
+ QVector<Declaration> decls;
+ for (int i = 0; i < styleRules.count(); i++) {
+ const Selector& selector = styleRules.at(i).selectors.at(0);
+ // Rules with pseudo elements don't cascade. This is an intentional
+ // diversion for CSS
+ if (part.compare(selector.pseudoElement(), Qt::CaseInsensitive) != 0)
+ continue;
+ quint64 negated = 0;
+ quint64 cssClass = selector.pseudoClass(&negated);
+ if ((pseudoClass == PseudoClass_Any) || (cssClass == PseudoClass_Unspecified)
+ || ((((cssClass & pseudoClass) == cssClass)) && ((negated & pseudoClass) == 0)))
+ decls += styleRules.at(i).declarations;
+ }
+ return decls;
+}
+
+int QStyleSheetStyle::nativeFrameWidth(const QWidget *w)
+{
+ QStyle *base = baseStyle();
+
+#ifndef QT_NO_SPINBOX
+ if (qobject_cast<const QAbstractSpinBox *>(w))
+ return base->pixelMetric(QStyle::PM_SpinBoxFrameWidth, 0, w);
+#endif
+
+#ifndef QT_NO_COMBOBOX
+ if (qobject_cast<const QComboBox *>(w))
+ return base->pixelMetric(QStyle::PM_ComboBoxFrameWidth, 0, w);
+#endif
+
+#ifndef QT_NO_MENU
+ if (qobject_cast<const QMenu *>(w))
+ return base->pixelMetric(QStyle::PM_MenuPanelWidth, 0, w);
+#endif
+
+#ifndef QT_NO_MENUBAR
+ if (qobject_cast<const QMenuBar *>(w))
+ return base->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, w);
+#endif
+#ifndef QT_NO_FRAME
+ if (const QFrame *frame = qobject_cast<const QFrame *>(w)) {
+ if (frame->frameShape() == QFrame::NoFrame)
+ return 0;
+ }
+#endif
+
+ if (qstrcmp(w->metaObject()->className(), "QTipLabel") == 0)
+ return base->pixelMetric(QStyle::PM_ToolTipLabelFrameWidth, 0, w);
+
+ return base->pixelMetric(QStyle::PM_DefaultFrameWidth, 0, w);
+}
+
+static quint64 pseudoClass(QStyle::State state)
+{
+ quint64 pc = 0;
+ if (state & QStyle::State_Enabled) {
+ pc |= PseudoClass_Enabled;
+ if (state & QStyle::State_MouseOver)
+ pc |= PseudoClass_Hover;
+ } else {
+ pc |= PseudoClass_Disabled;
+ }
+ if (state & QStyle::State_Active)
+ pc |= PseudoClass_Active;
+ if (state & QStyle::State_Window)
+ pc |= PseudoClass_Window;
+ if (state & QStyle::State_Sunken)
+ pc |= PseudoClass_Pressed;
+ if (state & QStyle::State_HasFocus)
+ pc |= PseudoClass_Focus;
+ if (state & QStyle::State_On)
+ pc |= (PseudoClass_On | PseudoClass_Checked);
+ if (state & QStyle::State_Off)
+ pc |= (PseudoClass_Off | PseudoClass_Unchecked);
+ if (state & QStyle::State_NoChange)
+ pc |= PseudoClass_Indeterminate;
+ if (state & QStyle::State_Selected)
+ pc |= PseudoClass_Selected;
+ if (state & QStyle::State_Horizontal)
+ pc |= PseudoClass_Horizontal;
+ else
+ pc |= PseudoClass_Vertical;
+ if (state & (QStyle::State_Open | QStyle::State_On | QStyle::State_Sunken))
+ pc |= PseudoClass_Open;
+ else
+ pc |= PseudoClass_Closed;
+ if (state & QStyle::State_Children)
+ pc |= PseudoClass_Children;
+ if (state & QStyle::State_Sibling)
+ pc |= PseudoClass_Sibling;
+ if (state & QStyle::State_ReadOnly)
+ pc |= PseudoClass_ReadOnly;
+ if (state & QStyle::State_Item)
+ pc |= PseudoClass_Item;
+#ifdef QT_KEYPAD_NAVIGATION
+ if (state & QStyle::State_HasEditFocus)
+ pc |= PseudoClass_EditFocus;
+#endif
+ return pc;
+}
+
+static void qt_check_if_internal_widget(const QWidget **w, int *element)
+{
+#ifdef QT_NO_DOCKWIDGET
+ Q_UNUSED(w);
+ Q_UNUSED(element);
+#else
+ if (*w && qstrcmp((*w)->metaObject()->className(), "QDockWidgetTitleButton") == 0) {
+ if ((*w)->objectName() == QLatin1String("qt_dockwidget_closebutton")) {
+ *element = PseudoElement_DockWidgetCloseButton;
+ } else if ((*w)->objectName() == QLatin1String("qt_dockwidget_floatbutton")) {
+ *element = PseudoElement_DockWidgetFloatButton;
+ }
+ *w = (*w)->parentWidget();
+ }
+#endif
+}
+
+QRenderRule QStyleSheetStyle::renderRule(const QWidget *w, int element, quint64 state) const
+{
+ qt_check_if_internal_widget(&w, &element);
+ QHash<quint64, QRenderRule> &cache = styleSheetCaches->renderRulesCache[w][element];
+ QHash<quint64, QRenderRule>::const_iterator cacheIt = cache.constFind(state);
+ if (cacheIt != cache.constEnd())
+ return cacheIt.value();
+
+ if (!initWidget(w))
+ return QRenderRule();
+
+ quint64 stateMask = 0;
+ const QVector<StyleRule> rules = styleRules(w);
+ for (int i = 0; i < rules.count(); i++) {
+ const Selector& selector = rules.at(i).selectors.at(0);
+ quint64 negated = 0;
+ stateMask |= selector.pseudoClass(&negated);
+ stateMask |= negated;
+ }
+
+ cacheIt = cache.constFind(state & stateMask);
+ if (cacheIt != cache.constEnd()) {
+ const QRenderRule &newRule = cacheIt.value();
+ cache[state] = newRule;
+ return newRule;
+ }
+
+
+ const QString part = QLatin1String(knownPseudoElements[element].name);
+ QVector<Declaration> decls = declarations(rules, part, state);
+ QRenderRule newRule(decls, w);
+ cache[state] = newRule;
+ if ((state & stateMask) != state)
+ cache[state&stateMask] = newRule;
+ return newRule;
+}
+
+QRenderRule QStyleSheetStyle::renderRule(const QWidget *w, const QStyleOption *opt, int pseudoElement) const
+{
+ quint64 extraClass = 0;
+ QStyle::State state = opt ? opt->state : QStyle::State(QStyle::State_None);
+
+ if (const QStyleOptionComplex *complex = qstyleoption_cast<const QStyleOptionComplex *>(opt)) {
+ if (pseudoElement != PseudoElement_None) {
+ // if not an active subcontrol, just pass enabled/disabled
+ QStyle::SubControl subControl = knownPseudoElements[pseudoElement].subControl;
+
+ if (!(complex->activeSubControls & subControl))
+ state &= (QStyle::State_Enabled | QStyle::State_Horizontal | QStyle::State_HasFocus);
+ }
+
+ switch (pseudoElement) {
+ case PseudoElement_ComboBoxDropDown:
+ case PseudoElement_ComboBoxArrow:
+ state |= (complex->state & (QStyle::State_On|QStyle::State_ReadOnly));
+ break;
+ case PseudoElement_SpinBoxUpButton:
+ case PseudoElement_SpinBoxDownButton:
+ case PseudoElement_SpinBoxUpArrow:
+ case PseudoElement_SpinBoxDownArrow:
+#ifndef QT_NO_SPINBOX
+ if (const QStyleOptionSpinBox *sb = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
+ bool on = false;
+ bool up = pseudoElement == PseudoElement_SpinBoxUpButton
+ || pseudoElement == PseudoElement_SpinBoxUpArrow;
+ if ((sb->stepEnabled & QAbstractSpinBox::StepUpEnabled) && up)
+ on = true;
+ else if ((sb->stepEnabled & QAbstractSpinBox::StepDownEnabled) && !up)
+ on = true;
+ state |= (on ? QStyle::State_On : QStyle::State_Off);
+ }
+#endif // QT_NO_SPINBOX
+ break;
+ case PseudoElement_GroupBoxTitle:
+ state |= (complex->state & (QStyle::State_MouseOver | QStyle::State_Sunken));
+ break;
+ case PseudoElement_ToolButtonMenu:
+ case PseudoElement_ToolButtonMenuArrow:
+ case PseudoElement_ToolButtonDownArrow:
+ state |= complex->state & QStyle::State_MouseOver;
+ if (complex->state & QStyle::State_Sunken ||
+ complex->activeSubControls & QStyle::SC_ToolButtonMenu)
+ state |= QStyle::State_Sunken;
+ break;
+ case PseudoElement_SliderGroove:
+ state |= complex->state & QStyle::State_MouseOver;
+ break;
+ default:
+ break;
+ }
+
+ if (const QStyleOptionComboBox *combo = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
+ // QStyle::State_On is set when the popup is being shown
+ // Propagate EditField Pressed state
+ if (pseudoElement == PseudoElement_None
+ && (complex->activeSubControls & QStyle::SC_ComboBoxEditField)
+ && (!(state & QStyle::State_MouseOver))) {
+ state |= QStyle::State_Sunken;
+ }
+
+ if (!combo->frame)
+ extraClass |= PseudoClass_Frameless;
+ if (!combo->editable)
+ extraClass |= PseudoClass_ReadOnly;
+ else
+ extraClass |= PseudoClass_Editable;
+#ifndef QT_NO_SPINBOX
+ } else if (const QStyleOptionSpinBox *spin = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
+ if (!spin->frame)
+ extraClass |= PseudoClass_Frameless;
+#endif // QT_NO_SPINBOX
+ } else if (const QStyleOptionGroupBox *gb = qstyleoption_cast<const QStyleOptionGroupBox *>(opt)) {
+ if (gb->features & QStyleOptionFrameV2::Flat)
+ extraClass |= PseudoClass_Flat;
+ if (gb->lineWidth == 0)
+ extraClass |= PseudoClass_Frameless;
+ } else if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) {
+ if (tb->titleBarState & Qt::WindowMinimized) {
+ extraClass |= PseudoClass_Minimized;
+ }
+ else if (tb->titleBarState & Qt::WindowMaximized)
+ extraClass |= PseudoClass_Maximized;
+ }
+ } else {
+ // handle simple style options
+ if (const QStyleOptionMenuItem *mi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
+ if (mi->menuItemType == QStyleOptionMenuItem::DefaultItem)
+ extraClass |= PseudoClass_Default;
+ if (mi->checkType == QStyleOptionMenuItem::Exclusive)
+ extraClass |= PseudoClass_Exclusive;
+ else if (mi->checkType == QStyleOptionMenuItem::NonExclusive)
+ extraClass |= PseudoClass_NonExclusive;
+ if (mi->checkType != QStyleOptionMenuItem::NotCheckable)
+ extraClass |= (mi->checked) ? (PseudoClass_On|PseudoClass_Checked)
+ : (PseudoClass_Off|PseudoClass_Unchecked);
+ } else if (const QStyleOptionHeader *hdr = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
+ if (hdr->position == QStyleOptionHeader::OnlyOneSection)
+ extraClass |= PseudoClass_OnlyOne;
+ else if (hdr->position == QStyleOptionHeader::Beginning)
+ extraClass |= PseudoClass_First;
+ else if (hdr->position == QStyleOptionHeader::End)
+ extraClass |= PseudoClass_Last;
+ else if (hdr->position == QStyleOptionHeader::Middle)
+ extraClass |= PseudoClass_Middle;
+
+ if (hdr->selectedPosition == QStyleOptionHeader::NextAndPreviousAreSelected)
+ extraClass |= (PseudoClass_NextSelected | PseudoClass_PreviousSelected);
+ else if (hdr->selectedPosition == QStyleOptionHeader::NextIsSelected)
+ extraClass |= PseudoClass_NextSelected;
+ else if (hdr->selectedPosition == QStyleOptionHeader::PreviousIsSelected)
+ extraClass |= PseudoClass_PreviousSelected;
+#ifndef QT_NO_TABWIDGET
+ } else if (const QStyleOptionTabWidgetFrame *tab = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
+ switch (tab->shape) {
+ case QTabBar::RoundedNorth:
+ case QTabBar::TriangularNorth:
+ extraClass |= PseudoClass_Top;
+ break;
+ case QTabBar::RoundedSouth:
+ case QTabBar::TriangularSouth:
+ extraClass |= PseudoClass_Bottom;
+ break;
+ case QTabBar::RoundedEast:
+ case QTabBar::TriangularEast:
+ extraClass |= PseudoClass_Left;
+ break;
+ case QTabBar::RoundedWest:
+ case QTabBar::TriangularWest:
+ extraClass |= PseudoClass_Right;
+ break;
+ default:
+ break;
+ }
+#endif
+#ifndef QT_NO_TABBAR
+ } else if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
+ if (tab->position == QStyleOptionTab::OnlyOneTab)
+ extraClass |= PseudoClass_OnlyOne;
+ else if (tab->position == QStyleOptionTab::Beginning)
+ extraClass |= PseudoClass_First;
+ else if (tab->position == QStyleOptionTab::End)
+ extraClass |= PseudoClass_Last;
+ else if (tab->position == QStyleOptionTab::Middle)
+ extraClass |= PseudoClass_Middle;
+
+ if (tab->selectedPosition == QStyleOptionTab::NextIsSelected)
+ extraClass |= PseudoClass_NextSelected;
+ else if (tab->selectedPosition == QStyleOptionTab::PreviousIsSelected)
+ extraClass |= PseudoClass_PreviousSelected;
+
+ switch (tab->shape) {
+ case QTabBar::RoundedNorth:
+ case QTabBar::TriangularNorth:
+ extraClass |= PseudoClass_Top;
+ break;
+ case QTabBar::RoundedSouth:
+ case QTabBar::TriangularSouth:
+ extraClass |= PseudoClass_Bottom;
+ break;
+ case QTabBar::RoundedEast:
+ case QTabBar::TriangularEast:
+ extraClass |= PseudoClass_Left;
+ break;
+ case QTabBar::RoundedWest:
+ case QTabBar::TriangularWest:
+ extraClass |= PseudoClass_Right;
+ break;
+ default:
+ break;
+ }
+#endif // QT_NO_TABBAR
+ } else if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
+ if (btn->features & QStyleOptionButton::Flat)
+ extraClass |= PseudoClass_Flat;
+ if (btn->features & QStyleOptionButton::DefaultButton)
+ extraClass |= PseudoClass_Default;
+ } else if (const QStyleOptionFrame *frm = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
+ if (frm->lineWidth == 0)
+ extraClass |= PseudoClass_Frameless;
+ if (const QStyleOptionFrameV2 *frame2 = qstyleoption_cast<const QStyleOptionFrameV2 *>(opt)) {
+ if (frame2->features & QStyleOptionFrameV2::Flat)
+ extraClass |= PseudoClass_Flat;
+ }
+ }
+#ifndef QT_NO_TOOLBAR
+ else if (const QStyleOptionToolBar *tb = qstyleoption_cast<const QStyleOptionToolBar *>(opt)) {
+ if (tb->toolBarArea == Qt::LeftToolBarArea)
+ extraClass |= PseudoClass_Left;
+ else if (tb->toolBarArea == Qt::RightToolBarArea)
+ extraClass |= PseudoClass_Right;
+ else if (tb->toolBarArea == Qt::TopToolBarArea)
+ extraClass |= PseudoClass_Top;
+ else if (tb->toolBarArea == Qt::BottomToolBarArea)
+ extraClass |= PseudoClass_Bottom;
+
+ if (tb->positionWithinLine == QStyleOptionToolBar::Beginning)
+ extraClass |= PseudoClass_First;
+ else if (tb->positionWithinLine == QStyleOptionToolBar::Middle)
+ extraClass |= PseudoClass_Middle;
+ else if (tb->positionWithinLine == QStyleOptionToolBar::End)
+ extraClass |= PseudoClass_Last;
+ else if (tb->positionWithinLine == QStyleOptionToolBar::OnlyOne)
+ extraClass |= PseudoClass_OnlyOne;
+ }
+#endif // QT_NO_TOOLBAR
+#ifndef QT_NO_TOOLBOX
+ else if (const QStyleOptionToolBoxV2 *tab = qstyleoption_cast<const QStyleOptionToolBoxV2 *>(opt)) {
+ if (tab->position == QStyleOptionToolBoxV2::OnlyOneTab)
+ extraClass |= PseudoClass_OnlyOne;
+ else if (tab->position == QStyleOptionToolBoxV2::Beginning)
+ extraClass |= PseudoClass_First;
+ else if (tab->position == QStyleOptionToolBoxV2::End)
+ extraClass |= PseudoClass_Last;
+ else if (tab->position == QStyleOptionToolBoxV2::Middle)
+ extraClass |= PseudoClass_Middle;
+
+ if (tab->selectedPosition == QStyleOptionToolBoxV2::NextIsSelected)
+ extraClass |= PseudoClass_NextSelected;
+ else if (tab->selectedPosition == QStyleOptionToolBoxV2::PreviousIsSelected)
+ extraClass |= PseudoClass_PreviousSelected;
+ }
+#endif // QT_NO_TOOLBOX
+#ifndef QT_NO_DOCKWIDGET
+ else if (const QStyleOptionDockWidgetV2 *dw = qstyleoption_cast<const QStyleOptionDockWidgetV2 *>(opt)) {
+ if (dw->verticalTitleBar)
+ extraClass |= PseudoClass_Vertical;
+ else
+ extraClass |= PseudoClass_Horizontal;
+ if (dw->closable)
+ extraClass |= PseudoClass_Closable;
+ if (dw->floatable)
+ extraClass |= PseudoClass_Floatable;
+ if (dw->movable)
+ extraClass |= PseudoClass_Movable;
+ }
+#endif // QT_NO_DOCKWIDGET
+#ifndef QT_NO_ITEMVIEWS
+ else if (const QStyleOptionViewItemV2 *v2 = qstyleoption_cast<const QStyleOptionViewItemV2 *>(opt)) {
+ if (v2->features & QStyleOptionViewItemV2::Alternate)
+ extraClass |= PseudoClass_Alternate;
+ if (const QStyleOptionViewItemV4 *v4 = qstyleoption_cast<const QStyleOptionViewItemV4 *>(opt)) {
+ if (v4->viewItemPosition == QStyleOptionViewItemV4::OnlyOne)
+ extraClass |= PseudoClass_OnlyOne;
+ else if (v4->viewItemPosition == QStyleOptionViewItemV4::Beginning)
+ extraClass |= PseudoClass_First;
+ else if (v4->viewItemPosition == QStyleOptionViewItemV4::End)
+ extraClass |= PseudoClass_Last;
+ else if (v4->viewItemPosition == QStyleOptionViewItemV4::Middle)
+ extraClass |= PseudoClass_Middle;
+ }
+ }
+#endif
+#ifndef QT_NO_LINEEDIT
+ // LineEdit sets Sunken flag to indicate Sunken frame (argh)
+ if (const QLineEdit *lineEdit = qobject_cast<const QLineEdit *>(w)) {
+ state &= ~QStyle::State_Sunken;
+ if (lineEdit->hasFrame()) {
+ extraClass &= ~PseudoClass_Frameless;
+ } else {
+ extraClass |= PseudoClass_Frameless;
+ }
+ } else
+#endif
+ if (const QFrame *frm = qobject_cast<const QFrame *>(w)) {
+ if (frm->lineWidth() == 0)
+ extraClass |= PseudoClass_Frameless;
+ }
+ }
+
+ return renderRule(w, pseudoElement, pseudoClass(state) | extraClass);
+}
+
+bool QStyleSheetStyle::hasStyleRule(const QWidget *w, int part) const
+{
+ QHash<int, bool> &cache = styleSheetCaches->hasStyleRuleCache[w];
+ QHash<int, bool>::const_iterator cacheIt = cache.constFind(part);
+ if (cacheIt != cache.constEnd())
+ return cacheIt.value();
+
+ if (!initWidget(w))
+ return false;
+
+
+ const QVector<StyleRule> &rules = styleRules(w);
+ if (part == PseudoElement_None) {
+ bool result = w && !rules.isEmpty();
+ cache[part] = result;
+ return result;
+ }
+
+ QString pseudoElement = QLatin1String(knownPseudoElements[part].name);
+ QVector<Declaration> declarations;
+ for (int i = 0; i < rules.count(); i++) {
+ const Selector& selector = rules.at(i).selectors.at(0);
+ if (pseudoElement.compare(selector.pseudoElement(), Qt::CaseInsensitive) == 0) {
+ cache[part] = true;
+ return true;
+ }
+ }
+
+ cache[part] = false;
+ return false;
+}
+
+static Origin defaultOrigin(int pe)
+{
+ switch (pe) {
+ case PseudoElement_ScrollBarAddPage:
+ case PseudoElement_ScrollBarSubPage:
+ case PseudoElement_ScrollBarAddLine:
+ case PseudoElement_ScrollBarSubLine:
+ case PseudoElement_ScrollBarFirst:
+ case PseudoElement_ScrollBarLast:
+ case PseudoElement_GroupBoxTitle:
+ case PseudoElement_GroupBoxIndicator: // never used
+ case PseudoElement_ToolButtonMenu:
+ case PseudoElement_SliderAddPage:
+ case PseudoElement_SliderSubPage:
+ return Origin_Border;
+
+ case PseudoElement_SpinBoxUpButton:
+ case PseudoElement_SpinBoxDownButton:
+ case PseudoElement_PushButtonMenuIndicator:
+ case PseudoElement_ComboBoxDropDown:
+ case PseudoElement_ToolButtonDownArrow:
+ case PseudoElement_MenuCheckMark:
+ case PseudoElement_MenuIcon:
+ case PseudoElement_MenuRightArrow:
+ return Origin_Padding;
+
+ case PseudoElement_Indicator:
+ case PseudoElement_ExclusiveIndicator:
+ case PseudoElement_ComboBoxArrow:
+ case PseudoElement_ScrollBarSlider:
+ case PseudoElement_ScrollBarUpArrow:
+ case PseudoElement_ScrollBarDownArrow:
+ case PseudoElement_ScrollBarLeftArrow:
+ case PseudoElement_ScrollBarRightArrow:
+ case PseudoElement_SpinBoxUpArrow:
+ case PseudoElement_SpinBoxDownArrow:
+ case PseudoElement_ToolButtonMenuArrow:
+ case PseudoElement_HeaderViewUpArrow:
+ case PseudoElement_HeaderViewDownArrow:
+ case PseudoElement_SliderGroove:
+ case PseudoElement_SliderHandle:
+ return Origin_Content;
+
+ default:
+ return Origin_Margin;
+ }
+}
+
+static Qt::Alignment defaultPosition(int pe)
+{
+ switch (pe) {
+ case PseudoElement_Indicator:
+ case PseudoElement_ExclusiveIndicator:
+ case PseudoElement_MenuCheckMark:
+ case PseudoElement_MenuIcon:
+ return Qt::AlignLeft | Qt::AlignVCenter;
+
+ case PseudoElement_ScrollBarAddLine:
+ case PseudoElement_ScrollBarLast:
+ case PseudoElement_SpinBoxDownButton:
+ case PseudoElement_PushButtonMenuIndicator:
+ case PseudoElement_ToolButtonDownArrow:
+ return Qt::AlignRight | Qt::AlignBottom;
+
+ case PseudoElement_ScrollBarSubLine:
+ case PseudoElement_ScrollBarFirst:
+ case PseudoElement_SpinBoxUpButton:
+ case PseudoElement_ComboBoxDropDown:
+ case PseudoElement_ToolButtonMenu:
+ case PseudoElement_DockWidgetCloseButton:
+ case PseudoElement_DockWidgetFloatButton:
+ return Qt::AlignRight | Qt::AlignTop;
+
+ case PseudoElement_ScrollBarUpArrow:
+ case PseudoElement_ScrollBarDownArrow:
+ case PseudoElement_ScrollBarLeftArrow:
+ case PseudoElement_ScrollBarRightArrow:
+ case PseudoElement_SpinBoxUpArrow:
+ case PseudoElement_SpinBoxDownArrow:
+ case PseudoElement_ComboBoxArrow:
+ case PseudoElement_DownArrow:
+ case PseudoElement_ToolButtonMenuArrow:
+ case PseudoElement_SliderGroove:
+ return Qt::AlignCenter;
+
+ case PseudoElement_GroupBoxTitle:
+ case PseudoElement_GroupBoxIndicator: // never used
+ return Qt::AlignLeft | Qt::AlignTop;
+
+ case PseudoElement_HeaderViewUpArrow:
+ case PseudoElement_HeaderViewDownArrow:
+ case PseudoElement_MenuRightArrow:
+ return Qt::AlignRight | Qt::AlignVCenter;
+
+ default:
+ return 0;
+ }
+}
+
+QSize QStyleSheetStyle::defaultSize(const QWidget *w, QSize sz, const QRect& rect, int pe) const
+{
+ QStyle *base = baseStyle();
+
+ switch (pe) {
+ case PseudoElement_Indicator:
+ case PseudoElement_MenuCheckMark:
+ if (sz.width() == -1)
+ sz.setWidth(base->pixelMetric(PM_IndicatorWidth, 0, w));
+ if (sz.height() == -1)
+ sz.setHeight(base->pixelMetric(PM_IndicatorHeight, 0, w));
+ break;
+
+ case PseudoElement_ExclusiveIndicator:
+ case PseudoElement_GroupBoxIndicator:
+ if (sz.width() == -1)
+ sz.setWidth(base->pixelMetric(PM_ExclusiveIndicatorWidth, 0, w));
+ if (sz.height() == -1)
+ sz.setHeight(base->pixelMetric(PM_ExclusiveIndicatorHeight, 0, w));
+ break;
+
+ case PseudoElement_PushButtonMenuIndicator: {
+ int pm = base->pixelMetric(PM_MenuButtonIndicator, 0, w);
+ if (sz.width() == -1)
+ sz.setWidth(pm);
+ if (sz.height() == -1)
+ sz.setHeight(pm);
+ }
+ break;
+
+ case PseudoElement_ComboBoxDropDown:
+ if (sz.width() == -1)
+ sz.setWidth(16);
+ break;
+
+ case PseudoElement_ComboBoxArrow:
+ case PseudoElement_DownArrow:
+ case PseudoElement_ToolButtonMenuArrow:
+ case PseudoElement_ToolButtonDownArrow:
+ case PseudoElement_MenuRightArrow:
+ if (sz.width() == -1)
+ sz.setWidth(13);
+ if (sz.height() == -1)
+ sz.setHeight(13);
+ break;
+
+ case PseudoElement_SpinBoxUpButton:
+ case PseudoElement_SpinBoxDownButton:
+ if (sz.width() == -1)
+ sz.setWidth(16);
+ if (sz.height() == -1)
+ sz.setHeight(rect.height()/2);
+ break;
+
+ case PseudoElement_ToolButtonMenu:
+ if (sz.width() == -1)
+ sz.setWidth(base->pixelMetric(PM_MenuButtonIndicator, 0, w));
+ break;
+
+ case PseudoElement_HeaderViewUpArrow:
+ case PseudoElement_HeaderViewDownArrow: {
+ int pm = base->pixelMetric(PM_HeaderMargin, 0, w);
+ if (sz.width() == -1)
+ sz.setWidth(pm);
+ if (sz.height() == 1)
+ sz.setHeight(pm);
+ break;
+ }
+
+ case PseudoElement_ScrollBarFirst:
+ case PseudoElement_ScrollBarLast:
+ case PseudoElement_ScrollBarAddLine:
+ case PseudoElement_ScrollBarSubLine:
+ case PseudoElement_ScrollBarSlider: {
+ int pm = pixelMetric(QStyle::PM_ScrollBarExtent, 0, w);
+ if (sz.width() == -1)
+ sz.setWidth(pm);
+ if (sz.height() == -1)
+ sz.setHeight(pm);
+ break;
+ }
+
+ case PseudoElement_DockWidgetCloseButton:
+ case PseudoElement_DockWidgetFloatButton: {
+ int iconSize = pixelMetric(PM_SmallIconSize, 0, w);
+ return QSize(iconSize, iconSize);
+ }
+
+ default:
+ break;
+ }
+
+ // expand to rectangle
+ if (sz.height() == -1)
+ sz.setHeight(rect.height());
+ if (sz.width() == -1)
+ sz.setWidth(rect.width());
+
+ return sz;
+}
+
+static PositionMode defaultPositionMode(int pe)
+{
+ switch (pe) {
+ case PseudoElement_ScrollBarFirst:
+ case PseudoElement_ScrollBarLast:
+ case PseudoElement_ScrollBarAddLine:
+ case PseudoElement_ScrollBarSubLine:
+ case PseudoElement_ScrollBarAddPage:
+ case PseudoElement_ScrollBarSubPage:
+ case PseudoElement_ScrollBarSlider:
+ case PseudoElement_SliderGroove:
+ case PseudoElement_SliderHandle:
+ case PseudoElement_TabWidgetPane:
+ return PositionMode_Absolute;
+ default:
+ return PositionMode_Static;
+ }
+}
+
+QRect QStyleSheetStyle::positionRect(const QWidget *w, const QRenderRule &rule2, int pe,
+ const QRect &originRect, Qt::LayoutDirection dir) const
+{
+ const QStyleSheetPositionData *p = rule2.position();
+ PositionMode mode = (p && p->mode != PositionMode_Unknown) ? p->mode : defaultPositionMode(pe);
+ Qt::Alignment position = (p && p->position != 0) ? p->position : defaultPosition(pe);
+ QRect r;
+
+ if (mode != PositionMode_Absolute) {
+ QSize sz = defaultSize(w, rule2.size(), originRect, pe);
+ sz = sz.expandedTo(rule2.minimumContentsSize());
+ r = QStyle::alignedRect(dir, position, sz, originRect);
+ if (p) {
+ int left = p->left ? p->left : -p->right;
+ int top = p->top ? p->top : -p->bottom;
+ r.translate(dir == Qt::LeftToRight ? left : -left, top);
+ }
+ } else {
+ r = p ? originRect.adjusted(dir == Qt::LeftToRight ? p->left : p->right, p->top,
+ dir == Qt::LeftToRight ? -p->right : -p->left, -p->bottom)
+ : originRect;
+ if (rule2.hasContentsSize()) {
+ QSize sz = rule2.size().expandedTo(rule2.minimumContentsSize());
+ if (sz.width() == -1) sz.setWidth(r.width());
+ if (sz.height() == -1) sz.setHeight(r.height());
+ r = QStyle::alignedRect(dir, position, sz, r);
+ }
+ }
+ return r;
+}
+
+QRect QStyleSheetStyle::positionRect(const QWidget *w, const QRenderRule& rule1, const QRenderRule& rule2, int pe,
+ const QRect& rect, Qt::LayoutDirection dir) const
+{
+ const QStyleSheetPositionData *p = rule2.position();
+ Origin origin = (p && p->origin != Origin_Unknown) ? p->origin : defaultOrigin(pe);
+ QRect originRect = rule1.originRect(rect, origin);
+ return positionRect(w, rule2, pe, originRect, dir);
+}
+
+
+/** \internal
+ For widget that have an embedded widget (such as combobox) return that embedded widget.
+ otherwise return the widget itself
+ */
+static QWidget *embeddedWidget(QWidget *w)
+{
+#ifndef QT_NO_COMBOBOX
+ if (QComboBox *cmb = qobject_cast<QComboBox *>(w)) {
+ if (cmb->isEditable())
+ return cmb->lineEdit();
+ else
+ return cmb;
+ }
+#endif
+
+#ifndef QT_NO_SPINBOX
+ if (QAbstractSpinBox *sb = qobject_cast<QAbstractSpinBox *>(w))
+ return sb->findChild<QLineEdit *>();
+#endif
+
+#ifndef QT_NO_SCROLLAREA
+ if (QAbstractScrollArea *sa = qobject_cast<QAbstractScrollArea *>(w))
+ return sa->viewport();
+#endif
+
+ return w;
+}
+
+/** \internal
+ in case w is an embedded widget, return the container widget
+ (i.e, the widget for which the rules actualy apply)
+ (exemple, if w is a lineedit embedded in a combobox, return the combobox)
+
+ if w is not embedded, return w itself
+*/
+static QWidget *containerWidget(const QWidget *w)
+{
+#ifndef QT_NO_LINEEDIT
+ if (qobject_cast<const QLineEdit *>(w)) {
+ //if the QLineEdit is an embeddedWidget, we need the rule of the real widget
+#ifndef QT_NO_COMBOBOX
+ if (qobject_cast<const QComboBox *>(w->parentWidget()))
+ return w->parentWidget();
+#endif
+#ifndef QT_NO_SPINBOX
+ if (qobject_cast<const QAbstractSpinBox *>(w->parentWidget()))
+ return w->parentWidget();
+#endif
+ }
+#endif // QT_NO_LINEEDIT
+
+#ifndef QT_NO_SCROLLAREA
+ if (const QAbstractScrollArea *sa = qobject_cast<const QAbstractScrollArea *>(w->parentWidget())) {
+ if (sa->viewport() == w)
+ return w->parentWidget();
+ }
+#endif
+
+ return const_cast<QWidget *>(w);
+}
+
+/** \internal
+ returns true if the widget can NOT be styled directly
+ */
+static bool unstylable(const QWidget *w)
+{
+ if (w->windowType() == Qt::Desktop)
+ return true;
+
+ if (!w->styleSheet().isEmpty())
+ return false;
+
+ if (containerWidget(w) != w)
+ return true;
+
+#ifndef QT_NO_FRAME
+ // detect QComboBoxPrivateContainer
+ else if (qobject_cast<const QFrame *>(w)) {
+ if (0
+#ifndef QT_NO_COMBOBOX
+ || qobject_cast<const QComboBox *>(w->parentWidget())
+#endif
+ )
+ return true;
+ }
+#endif
+ return false;
+}
+
+static quint64 extendedPseudoClass(const QWidget *w)
+{
+ quint64 pc = w->isWindow() ? quint64(PseudoClass_Window) : 0;
+ if (const QAbstractSlider *slider = qobject_cast<const QAbstractSlider *>(w)) {
+ pc |= ((slider->orientation() == Qt::Vertical) ? PseudoClass_Vertical : PseudoClass_Horizontal);
+ } else
+#ifndef QT_NO_COMBOBOX
+ if (const QComboBox *combo = qobject_cast<const QComboBox *>(w)) {
+ if (combo->isEditable())
+ pc |= (combo->isEditable() ? PseudoClass_Editable : PseudoClass_ReadOnly);
+ } else
+#endif
+#ifndef QT_NO_LINEEDIT
+ if (const QLineEdit *edit = qobject_cast<const QLineEdit *>(w)) {
+ pc |= (edit->isReadOnly() ? PseudoClass_ReadOnly : PseudoClass_Editable);
+ } else
+#endif
+ { } // required for the above ifdef'ery to work
+ return pc;
+}
+
+// sets up the geometry of the widget. We set a dynamic property when
+// we modify the min/max size of the widget. The min/max size is restored
+// to their original value when a new stylesheet that does not contain
+// the CSS properties is set and when the widget has this dynamic property set.
+// This way we don't trample on users who had setup a min/max size in code and
+// don't use stylesheets at all.
+void QStyleSheetStyle::setGeometry(QWidget *w)
+{
+ QRenderRule rule = renderRule(w, PseudoElement_None, PseudoClass_Enabled | extendedPseudoClass(w));
+ const QStyleSheetGeometryData *geo = rule.geometry();
+ if (w->property("_q_stylesheet_minw").toBool()
+ && ((!rule.hasGeometry() || geo->minWidth == -1))) {
+ w->setMinimumWidth(0);
+ w->setProperty("_q_stylesheet_minw", QVariant());
+ }
+ if (w->property("_q_stylesheet_minh").toBool()
+ && ((!rule.hasGeometry() || geo->minHeight == -1))) {
+ w->setMinimumHeight(0);
+ w->setProperty("_q_stylesheet_minh", QVariant());
+ }
+ if (w->property("_q_stylesheet_maxw").toBool()
+ && ((!rule.hasGeometry() || geo->maxWidth == -1))) {
+ w->setMaximumWidth(QWIDGETSIZE_MAX);
+ w->setProperty("_q_stylesheet_maxw", QVariant());
+ }
+ if (w->property("_q_stylesheet_maxh").toBool()
+ && ((!rule.hasGeometry() || geo->maxHeight == -1))) {
+ w->setMaximumHeight(QWIDGETSIZE_MAX);
+ w->setProperty("_q_stylesheet_maxh", QVariant());
+ }
+
+
+ if (rule.hasGeometry()) {
+ if (geo->minWidth != -1) {
+ w->setProperty("_q_stylesheet_minw", true);
+ w->setMinimumWidth(rule.boxSize(QSize(qMax(geo->width, geo->minWidth), 0)).width());
+ }
+ if (geo->minHeight != -1) {
+ w->setProperty("_q_stylesheet_minh", true);
+ w->setMinimumHeight(rule.boxSize(QSize(0, qMax(geo->height, geo->minHeight))).height());
+ }
+ if (geo->maxWidth != -1) {
+ w->setProperty("_q_stylesheet_maxw", true);
+ w->setMaximumWidth(rule.boxSize(QSize(qMin(geo->width == -1 ? QWIDGETSIZE_MAX : geo->width,
+ geo->maxWidth == -1 ? QWIDGETSIZE_MAX : geo->maxWidth), 0)).width());
+ }
+ if (geo->maxHeight != -1) {
+ w->setProperty("_q_stylesheet_maxh", true);
+ w->setMaximumHeight(rule.boxSize(QSize(0, qMin(geo->height == -1 ? QWIDGETSIZE_MAX : geo->height,
+ geo->maxHeight == -1 ? QWIDGETSIZE_MAX : geo->maxHeight))).height());
+ }
+ }
+}
+
+void QStyleSheetStyle::setProperties(QWidget *w)
+{
+ QHash<QString, QVariant> propertyHash;
+ QVector<Declaration> decls = declarations(styleRules(w), QString());
+
+ // run through the declarations in order
+ for (int i = 0; i < decls.count(); i++) {
+ const Declaration &decl = decls.at(i);
+ QString property = decl.d->property;
+ if (!property.startsWith(QLatin1String("qproperty-"), Qt::CaseInsensitive))
+ continue;
+ property.remove(0, 10); // strip "qproperty-"
+ const QVariant value = w->property(property.toLatin1());
+ const QMetaObject *metaObject = w->metaObject();
+ int index = metaObject->indexOfProperty(property.toLatin1());
+ if (index == -1) {
+ qWarning() << w << " does not have a property named " << property;
+ continue;
+ }
+ QMetaProperty metaProperty = metaObject->property(index);
+ if (!metaProperty.isWritable() || !metaProperty.isDesignable()) {
+ qWarning() << w << " cannot design property named " << property;
+ continue;
+ }
+ QVariant v;
+ switch (value.type()) {
+ // ### Qt 5
+// case QVariant::Icon: v = decl.iconValue(); break;
+ case QVariant::Image: v = QImage(decl.uriValue()); break;
+ case QVariant::Pixmap: v = QPixmap(decl.uriValue()); break;
+ case QVariant::Rect: v = decl.rectValue(); break;
+ case QVariant::Size: v = decl.sizeValue(); break;
+ case QVariant::Color: v = decl.colorValue(); break;
+ case QVariant::Brush: v = decl.brushValue(); break;
+#ifndef QT_NO_SHORTCUT
+ case QVariant::KeySequence: v = QKeySequence(decl.d->values.at(0).variant.toString()); break;
+#endif
+ default: v = decl.d->values.at(0).variant; break;
+ }
+ propertyHash[property] = v;
+ }
+ // apply the values
+ const QList<QString> properties = propertyHash.keys();
+ for (int i = 0; i < properties.count(); i++) {
+ const QString &property = properties.at(i);
+ w->setProperty(property.toLatin1(), propertyHash[property]);
+ }
+}
+
+void QStyleSheetStyle::setPalette(QWidget *w)
+{
+ struct RuleRoleMap {
+ int state;
+ QPalette::ColorGroup group;
+ } map[3] = {
+ { int(PseudoClass_Active | PseudoClass_Enabled), QPalette::Active },
+ { PseudoClass_Disabled, QPalette::Disabled },
+ { PseudoClass_Enabled, QPalette::Inactive }
+ };
+
+ QPalette p = w->palette();
+ QWidget *ew = embeddedWidget(w);
+
+ for (int i = 0; i < 3; i++) {
+ QRenderRule rule = renderRule(w, PseudoElement_None, map[i].state | extendedPseudoClass(w));
+ if (i == 0) {
+ if (!w->property("_q_styleSheetWidgetFont").isValid()) {
+ saveWidgetFont(w, w->font());
+ }
+ updateStyleSheetFont(w);
+ if (ew != w)
+ updateStyleSheetFont(ew);
+ }
+
+ rule.configurePalette(&p, map[i].group, ew, ew != w);
+ }
+
+ styleSheetCaches->customPaletteWidgets.insert(w, w->palette());
+ w->setPalette(p);
+ if (ew != w)
+ ew->setPalette(p);
+}
+
+void QStyleSheetStyle::unsetPalette(QWidget *w)
+{
+ if (styleSheetCaches->customPaletteWidgets.contains(w)) {
+ QPalette p = styleSheetCaches->customPaletteWidgets.value(w);
+ w->setPalette(p);
+ QWidget *ew = embeddedWidget(w);
+ if (ew != w)
+ ew->setPalette(p);
+ styleSheetCaches->customPaletteWidgets.remove(w);
+ }
+ QVariant oldFont = w->property("_q_styleSheetWidgetFont");
+ if (oldFont.isValid()) {
+ w->setFont(qvariant_cast<QFont>(oldFont));
+ }
+ if (styleSheetCaches->autoFillDisabledWidgets.contains(w)) {
+ embeddedWidget(w)->setAutoFillBackground(true);
+ styleSheetCaches->autoFillDisabledWidgets.remove(w);
+ }
+}
+
+static void updateWidgets(const QList<const QWidget *>& widgets)
+{
+ if (!styleSheetCaches->styleRulesCache.isEmpty() || !styleSheetCaches->hasStyleRuleCache.isEmpty() || !styleSheetCaches->renderRulesCache.isEmpty()) {
+ for (int i = 0; i < widgets.size(); ++i) {
+ const QWidget *widget = widgets.at(i);
+ styleSheetCaches->styleRulesCache.remove(widget);
+ styleSheetCaches->hasStyleRuleCache.remove(widget);
+ styleSheetCaches->renderRulesCache.remove(widget);
+ }
+ }
+ for (int i = 0; i < widgets.size(); ++i) {
+ QWidget *widget = const_cast<QWidget *>(widgets.at(i));
+ if (widget == 0)
+ continue;
+ widget->style()->polish(widget);
+ QEvent event(QEvent::StyleChange);
+ QApplication::sendEvent(widget, &event);
+ widget->update();
+ widget->updateGeometry();
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// The stylesheet style
+int QStyleSheetStyle::numinstances = 0;
+
+QStyleSheetStyle::QStyleSheetStyle(QStyle *base)
+ : QWindowsStyle(*new QStyleSheetStylePrivate), base(base), refcount(1)
+{
+ ++numinstances;
+ if (numinstances == 1) {
+ styleSheetCaches = new QStyleSheetStyleCaches;
+ }
+}
+
+QStyleSheetStyle::~QStyleSheetStyle()
+{
+ --numinstances;
+ if (numinstances == 0) {
+ delete styleSheetCaches;
+ }
+}
+QStyle *QStyleSheetStyle::baseStyle() const
+{
+ if (base)
+ return base;
+ if (QStyleSheetStyle *me = qobject_cast<QStyleSheetStyle *>(QApplication::style()))
+ return me->base;
+ return QApplication::style();
+}
+
+void QStyleSheetStyleCaches::widgetDestroyed(QObject *o)
+{
+ styleRulesCache.remove((const QWidget *)o);
+ hasStyleRuleCache.remove((const QWidget *)o);
+ renderRulesCache.remove((const QWidget *)o);
+ customPaletteWidgets.remove((const QWidget *)o);
+ styleSheetCache.remove((const QWidget *)o);
+ autoFillDisabledWidgets.remove((const QWidget *)o);
+}
+
+void QStyleSheetStyleCaches::styleDestroyed(QObject *o)
+{
+ styleSheetCache.remove(o);
+}
+
+/*!
+ * Make sure that the cache will be clean by connecting destroyed if needed.
+ * return false if the widget is not stylable;
+ */
+bool QStyleSheetStyle::initWidget(const QWidget *w) const
+{
+ if (!w)
+ return false;
+ if(w->testAttribute(Qt::WA_StyleSheet))
+ return true;
+
+ if(unstylable(w))
+ return false;
+
+ const_cast<QWidget *>(w)->setAttribute(Qt::WA_StyleSheet, true);
+ QObject::connect(w, SIGNAL(destroyed(QObject*)), styleSheetCaches, SLOT(widgetDestroyed(QObject*)), Qt::UniqueConnection);
+ return true;
+}
+
+void QStyleSheetStyle::polish(QWidget *w)
+{
+ baseStyle()->polish(w);
+ RECURSION_GUARD(return)
+
+ if (!initWidget(w))
+ return;
+
+ if (styleSheetCaches->styleRulesCache.contains(w)) {
+ // the widget accessed its style pointer before polish (or repolish)
+ // (exemple: the QAbstractSpinBox constructor ask for the stylehint)
+ styleSheetCaches->styleRulesCache.remove(w);
+ styleSheetCaches->hasStyleRuleCache.remove(w);
+ styleSheetCaches->renderRulesCache.remove(w);
+ }
+ setGeometry(w);
+ setProperties(w);
+ unsetPalette(w);
+ setPalette(w);
+
+ //set the WA_Hover attribute if one of the selector depends of the hover state
+ QVector<StyleRule> rules = styleRules(w);
+ for (int i = 0; i < rules.count(); i++) {
+ const Selector& selector = rules.at(i).selectors.at(0);
+ quint64 negated = 0;
+ quint64 cssClass = selector.pseudoClass(&negated);
+ if ( cssClass & PseudoClass_Hover || negated & PseudoClass_Hover) {
+ w->setAttribute(Qt::WA_Hover);
+ embeddedWidget(w)->setAttribute(Qt::WA_Hover);
+ }
+ }
+
+
+#ifndef QT_NO_SCROLLAREA
+ if (QAbstractScrollArea *sa = qobject_cast<QAbstractScrollArea *>(w)) {
+ QRenderRule rule = renderRule(sa, PseudoElement_None, PseudoClass_Enabled);
+ if ((rule.hasBorder() && rule.border()->hasBorderImage())
+ || (rule.hasBackground() && !rule.background()->pixmap.isNull())) {
+ QObject::connect(sa->horizontalScrollBar(), SIGNAL(valueChanged(int)),
+ sa, SLOT(update()), Qt::UniqueConnection);
+ QObject::connect(sa->verticalScrollBar(), SIGNAL(valueChanged(int)),
+ sa, SLOT(update()), Qt::UniqueConnection);
+ }
+ }
+#endif
+
+#ifndef QT_NO_PROGRESSBAR
+ if (QProgressBar *pb = qobject_cast<QProgressBar *>(w)) {
+ QWindowsStyle::polish(pb);
+ }
+#endif
+
+ QRenderRule rule = renderRule(w, PseudoElement_None, PseudoClass_Any);
+ if (rule.hasDrawable() || rule.hasBox()) {
+ if (w->metaObject() == &QWidget::staticMetaObject
+#ifndef QT_NO_ITEMVIEWS
+ || qobject_cast<QHeaderView *>(w)
+#endif
+#ifndef QT_NO_TABBAR
+ || qobject_cast<QTabBar *>(w)
+#endif
+#ifndef QT_NO_FRAME
+ || qobject_cast<QFrame *>(w)
+#endif
+#ifndef QT_NO_MAINWINDOW
+ || qobject_cast<QMainWindow *>(w)
+#endif
+#ifndef QT_NO_MDIAREA
+ || qobject_cast<QMdiSubWindow *>(w)
+#endif
+#ifndef QT_NO_MENUBAR
+ || qobject_cast<QMenuBar *>(w)
+#endif
+ || qobject_cast<QDialog *>(w)) {
+ w->setAttribute(Qt::WA_StyledBackground, true);
+ }
+ QWidget *ew = embeddedWidget(w);
+ if (ew->autoFillBackground()) {
+ ew->setAutoFillBackground(false);
+ styleSheetCaches->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()))
+ w->setAttribute(Qt::WA_OpaquePaintEvent, false);
+ }
+}
+
+void QStyleSheetStyle::polish(QApplication *app)
+{
+ baseStyle()->polish(app);
+}
+
+void QStyleSheetStyle::polish(QPalette &pal)
+{
+ baseStyle()->polish(pal);
+}
+
+void QStyleSheetStyle::repolish(QWidget *w)
+{
+ QList<const QWidget *> children = w->findChildren<const QWidget *>(QString());
+ children.append(w);
+ styleSheetCaches->styleSheetCache.remove(w);
+ updateWidgets(children);
+}
+
+void QStyleSheetStyle::repolish(QApplication *app)
+{
+ Q_UNUSED(app);
+ const QList<const QWidget*> allWidgets = styleSheetCaches->styleRulesCache.keys();
+ styleSheetCaches->styleSheetCache.remove(qApp);
+ styleSheetCaches->styleRulesCache.clear();
+ styleSheetCaches->hasStyleRuleCache.clear();
+ styleSheetCaches->renderRulesCache.clear();
+ updateWidgets(allWidgets);
+}
+
+void QStyleSheetStyle::unpolish(QWidget *w)
+{
+ if (!w || !w->testAttribute(Qt::WA_StyleSheet)) {
+ baseStyle()->unpolish(w);
+ return;
+ }
+
+ styleSheetCaches->styleRulesCache.remove(w);
+ styleSheetCaches->hasStyleRuleCache.remove(w);
+ styleSheetCaches->renderRulesCache.remove(w);
+ styleSheetCaches->styleSheetCache.remove(w);
+ unsetPalette(w);
+ w->setProperty("_q_stylesheet_minw", QVariant());
+ w->setProperty("_q_stylesheet_minh", QVariant());
+ w->setProperty("_q_stylesheet_maxw", QVariant());
+ w->setProperty("_q_stylesheet_maxh", QVariant());
+ w->setAttribute(Qt::WA_StyleSheet, false);
+ QObject::disconnect(w, 0, this, 0);
+#ifndef QT_NO_SCROLLAREA
+ if (QAbstractScrollArea *sa = qobject_cast<QAbstractScrollArea *>(w)) {
+ QObject::disconnect(sa->horizontalScrollBar(), SIGNAL(valueChanged(int)),
+ sa, SLOT(update()));
+ QObject::disconnect(sa->verticalScrollBar(), SIGNAL(valueChanged(int)),
+ sa, SLOT(update()));
+ }
+#endif
+#ifndef QT_NO_PROGRESSBAR
+ if (QProgressBar *pb = qobject_cast<QProgressBar *>(w))
+ QWindowsStyle::unpolish(pb);
+#endif
+ baseStyle()->unpolish(w);
+}
+
+void QStyleSheetStyle::unpolish(QApplication *app)
+{
+ baseStyle()->unpolish(app);
+ RECURSION_GUARD(return)
+ styleSheetCaches->styleRulesCache.clear();
+ styleSheetCaches->hasStyleRuleCache.clear();
+ styleSheetCaches->renderRulesCache.clear();
+ styleSheetCaches->styleSheetCache.remove(qApp);
+}
+
+#ifndef QT_NO_TABBAR
+inline static bool verticalTabs(QTabBar::Shape shape)
+{
+ return shape == QTabBar::RoundedWest
+ || shape == QTabBar::RoundedEast
+ || shape == QTabBar::TriangularWest
+ || shape == QTabBar::TriangularEast;
+}
+#endif // QT_NO_TABBAR
+
+void QStyleSheetStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p,
+ const QWidget *w) const
+{
+ RECURSION_GUARD(baseStyle()->drawComplexControl(cc, opt, p, w); return)
+
+ QRenderRule rule = renderRule(w, opt);
+
+ switch (cc) {
+ case CC_ComboBox:
+ if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
+ QStyleOptionComboBox cmbOpt(*cmb);
+ cmbOpt.rect = rule.borderRect(opt->rect);
+ if (rule.hasNativeBorder()) {
+ rule.drawBackgroundImage(p, cmbOpt.rect);
+ rule.configurePalette(&cmbOpt.palette, QPalette::ButtonText, QPalette::Button);
+ bool customDropDown = (opt->subControls & QStyle::SC_ComboBoxArrow)
+ && (hasStyleRule(w, PseudoElement_ComboBoxDropDown) || hasStyleRule(w, PseudoElement_ComboBoxArrow));
+ if (customDropDown)
+ cmbOpt.subControls &= ~QStyle::SC_ComboBoxArrow;
+ if (rule.baseStyleCanDraw()) {
+ baseStyle()->drawComplexControl(cc, &cmbOpt, p, w);
+ } else {
+ QWindowsStyle::drawComplexControl(cc, &cmbOpt, p, w);
+ }
+ if (!customDropDown)
+ return;
+ } else {
+ rule.drawRule(p, opt->rect);
+ }
+
+ if (opt->subControls & QStyle::SC_ComboBoxArrow) {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_ComboBoxDropDown);
+ if (subRule.hasDrawable()) {
+ QRect r = subControlRect(CC_ComboBox, opt, SC_ComboBoxArrow, w);
+ subRule.drawRule(p, r);
+ QRenderRule subRule2 = renderRule(w, opt, PseudoElement_ComboBoxArrow);
+ r = positionRect(w, subRule, subRule2, PseudoElement_ComboBoxArrow, r, opt->direction);
+ subRule2.drawRule(p, r);
+ } else {
+ cmbOpt.subControls = QStyle::SC_ComboBoxArrow;
+ QWindowsStyle::drawComplexControl(cc, &cmbOpt, p, w);
+ }
+ }
+
+ return;
+ }
+ break;
+
+#ifndef QT_NO_SPINBOX
+ case CC_SpinBox:
+ if (const QStyleOptionSpinBox *spin = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
+ QStyleOptionSpinBox spinOpt(*spin);
+ rule.configurePalette(&spinOpt.palette, QPalette::ButtonText, QPalette::Button);
+ rule.configurePalette(&spinOpt.palette, QPalette::Text, QPalette::Base);
+ spinOpt.rect = rule.borderRect(opt->rect);
+ bool customUp = true, customDown = true;
+ QRenderRule upRule = renderRule(w, opt, PseudoElement_SpinBoxUpButton);
+ QRenderRule downRule = renderRule(w, opt, PseudoElement_SpinBoxDownButton);
+ bool upRuleMatch = upRule.hasGeometry() || upRule.hasPosition();
+ bool downRuleMatch = downRule.hasGeometry() || downRule.hasPosition();
+ if (rule.hasNativeBorder() && !upRuleMatch && !downRuleMatch) {
+ rule.drawBackgroundImage(p, spinOpt.rect);
+ customUp = (opt->subControls & QStyle::SC_SpinBoxUp)
+ && (hasStyleRule(w, PseudoElement_SpinBoxUpButton) || hasStyleRule(w, PseudoElement_UpArrow));
+ if (customUp)
+ spinOpt.subControls &= ~QStyle::SC_SpinBoxUp;
+ customDown = (opt->subControls & QStyle::SC_SpinBoxDown)
+ && (hasStyleRule(w, PseudoElement_SpinBoxDownButton) || hasStyleRule(w, PseudoElement_DownArrow));
+ if (customDown)
+ spinOpt.subControls &= ~QStyle::SC_SpinBoxDown;
+ if (rule.baseStyleCanDraw()) {
+ baseStyle()->drawComplexControl(cc, &spinOpt, p, w);
+ } else {
+ QWindowsStyle::drawComplexControl(cc, &spinOpt, p, w);
+ }
+ if (!customUp && !customDown)
+ return;
+ } else {
+ rule.drawRule(p, opt->rect);
+ }
+
+ if ((opt->subControls & QStyle::SC_SpinBoxUp) && customUp) {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_SpinBoxUpButton);
+ if (subRule.hasDrawable()) {
+ QRect r = subControlRect(CC_SpinBox, opt, SC_SpinBoxUp, w);
+ subRule.drawRule(p, r);
+ QRenderRule subRule2 = renderRule(w, opt, PseudoElement_SpinBoxUpArrow);
+ r = positionRect(w, subRule, subRule2, PseudoElement_SpinBoxUpArrow, r, opt->direction);
+ subRule2.drawRule(p, r);
+ } else {
+ spinOpt.subControls = QStyle::SC_SpinBoxUp;
+ QWindowsStyle::drawComplexControl(cc, &spinOpt, p, w);
+ }
+ }
+
+ if ((opt->subControls & QStyle::SC_SpinBoxDown) && customDown) {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_SpinBoxDownButton);
+ if (subRule.hasDrawable()) {
+ QRect r = subControlRect(CC_SpinBox, opt, SC_SpinBoxDown, w);
+ subRule.drawRule(p, r);
+ QRenderRule subRule2 = renderRule(w, opt, PseudoElement_SpinBoxDownArrow);
+ r = positionRect(w, subRule, subRule2, PseudoElement_SpinBoxDownArrow, r, opt->direction);
+ subRule2.drawRule(p, r);
+ } else {
+ spinOpt.subControls = QStyle::SC_SpinBoxDown;
+ QWindowsStyle::drawComplexControl(cc, &spinOpt, p, w);
+ }
+ }
+ return;
+ }
+ break;
+#endif // QT_NO_SPINBOX
+
+ case CC_GroupBox:
+ if (const QStyleOptionGroupBox *gb = qstyleoption_cast<const QStyleOptionGroupBox *>(opt)) {
+
+ QRect labelRect, checkBoxRect, titleRect, frameRect;
+ bool hasTitle = (gb->subControls & QStyle::SC_GroupBoxCheckBox) || !gb->text.isEmpty();
+
+ if (!rule.hasDrawable() && (!hasTitle || !hasStyleRule(w, PseudoElement_GroupBoxTitle))
+ && !hasStyleRule(w, PseudoElement_Indicator) && !rule.hasBox() && !rule.hasFont && !rule.hasPalette()) {
+ // let the native style draw the combobox if there is no style for it.
+ break;
+ }
+ rule.drawBackground(p, opt->rect);
+
+ QRenderRule titleRule = renderRule(w, opt, PseudoElement_GroupBoxTitle);
+ bool clipSet = false;
+
+ if (hasTitle) {
+ labelRect = subControlRect(CC_GroupBox, opt, SC_GroupBoxLabel, w);
+ //Some native style (such as mac) may return a too small rectangle (because they use smaller fonts), so we may need to expand it a little bit.
+ labelRect.setSize(labelRect.size().expandedTo(ParentStyle::subControlRect(CC_GroupBox, opt, SC_GroupBoxLabel, w).size()));
+ if (gb->subControls & QStyle::SC_GroupBoxCheckBox) {
+ checkBoxRect = subControlRect(CC_GroupBox, opt, SC_GroupBoxCheckBox, w);
+ titleRect = titleRule.boxRect(checkBoxRect.united(labelRect));
+ } else {
+ titleRect = titleRule.boxRect(labelRect);
+ }
+ if (!titleRule.hasBackground() || !titleRule.background()->isTransparent()) {
+ clipSet = true;
+ p->save();
+ p->setClipRegion(QRegion(opt->rect) - titleRect);
+ }
+ }
+
+ frameRect = subControlRect(CC_GroupBox, opt, SC_GroupBoxFrame, w);
+ QStyleOptionFrameV2 frame;
+ frame.QStyleOption::operator=(*gb);
+ frame.features = gb->features;
+ frame.lineWidth = gb->lineWidth;
+ frame.midLineWidth = gb->midLineWidth;
+ frame.rect = frameRect;
+ drawPrimitive(PE_FrameGroupBox, &frame, p, w);
+
+ if (clipSet)
+ p->restore();
+
+ // draw background and frame of the title
+ if (hasTitle)
+ titleRule.drawRule(p, titleRect);
+
+ // draw the indicator
+ if (gb->subControls & QStyle::SC_GroupBoxCheckBox) {
+ QStyleOptionButton box;
+ box.QStyleOption::operator=(*gb);
+ box.rect = checkBoxRect;
+ drawPrimitive(PE_IndicatorCheckBox, &box, p, w);
+ }
+
+ // draw the text
+ if (!gb->text.isEmpty()) {
+ int alignment = int(Qt::AlignCenter | Qt::TextShowMnemonic);
+ if (!styleHint(QStyle::SH_UnderlineShortcut, opt, w)) {
+ alignment |= Qt::TextHideMnemonic;
+ }
+
+ QPalette pal = gb->palette;
+ if (gb->textColor.isValid())
+ pal.setColor(QPalette::WindowText, gb->textColor);
+ titleRule.configurePalette(&pal, QPalette::WindowText, QPalette::Window);
+ drawItemText(p, labelRect, alignment, pal, gb->state & State_Enabled,
+ gb->text, QPalette::WindowText);
+
+ if (gb->state & State_HasFocus) {
+ QStyleOptionFocusRect fropt;
+ fropt.QStyleOption::operator=(*gb);
+ fropt.rect = labelRect;
+ drawPrimitive(PE_FrameFocusRect, &fropt, p, w);
+ }
+ }
+
+ return;
+ }
+ break;
+
+ case CC_ToolButton:
+ if (const QStyleOptionToolButton *tool = qstyleoption_cast<const QStyleOptionToolButton *>(opt)) {
+ QStyleOptionToolButton toolOpt(*tool);
+ rule.configurePalette(&toolOpt.palette, QPalette::ButtonText, QPalette::Button);
+ toolOpt.font = rule.font.resolve(toolOpt.font);
+ toolOpt.rect = rule.borderRect(opt->rect);
+ bool customArrow = (tool->features & (QStyleOptionToolButton::HasMenu | QStyleOptionToolButton::MenuButtonPopup));
+ bool customDropDown = tool->features & QStyleOptionToolButton::MenuButtonPopup;
+ if (rule.hasNativeBorder()) {
+ if (tool->subControls & SC_ToolButton) {
+ //in some case (eg. the button is "auto raised") the style doesn't draw the background
+ //so we need to draw the background.
+ // use the same condition as in QCommonStyle
+ State bflags = tool->state & ~State_Sunken;
+ if (bflags & State_AutoRaise && (!(bflags & State_MouseOver) || !(bflags & State_Enabled)))
+ bflags &= ~State_Raised;
+ if (tool->state & State_Sunken && tool->activeSubControls & SC_ToolButton)
+ bflags |= State_Sunken;
+ if (!(bflags & (State_Sunken | State_On | State_Raised)))
+ rule.drawBackground(p, toolOpt.rect);
+ }
+ customArrow = customArrow && hasStyleRule(w, PseudoElement_ToolButtonDownArrow);
+ if (customArrow)
+ toolOpt.features &= ~QStyleOptionToolButton::HasMenu;
+ customDropDown = customDropDown && hasStyleRule(w, PseudoElement_ToolButtonMenu);
+ if (customDropDown)
+ toolOpt.subControls &= ~QStyle::SC_ToolButtonMenu;
+
+ if (rule.baseStyleCanDraw() && !(tool->features & QStyleOptionToolButton::Arrow)) {
+ baseStyle()->drawComplexControl(cc, &toolOpt, p, w);
+ } else {
+ QWindowsStyle::drawComplexControl(cc, &toolOpt, p, w);
+ }
+
+ if (!customArrow && !customDropDown)
+ return;
+ } else {
+ rule.drawRule(p, opt->rect);
+ toolOpt.rect = rule.contentsRect(opt->rect);
+ if (rule.hasFont)
+ toolOpt.font = rule.font;
+ drawControl(CE_ToolButtonLabel, &toolOpt, p, w);
+ }
+
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_ToolButtonMenu);
+ QRect r = subControlRect(CC_ToolButton, opt, QStyle::SC_ToolButtonMenu, w);
+ if (customDropDown) {
+ if (opt->subControls & QStyle::SC_ToolButtonMenu) {
+ if (subRule.hasDrawable()) {
+ subRule.drawRule(p, r);
+ } else {
+ toolOpt.rect = r;
+ baseStyle()->drawPrimitive(PE_IndicatorButtonDropDown, &toolOpt, p, w);
+ }
+ }
+ }
+
+ if (customArrow) {
+ QRenderRule subRule2 = customDropDown ? renderRule(w, opt, PseudoElement_ToolButtonMenuArrow)
+ : renderRule(w, opt, PseudoElement_ToolButtonDownArrow);
+ QRect r2 = customDropDown
+ ? positionRect(w, subRule, subRule2, PseudoElement_ToolButtonMenuArrow, r, opt->direction)
+ : positionRect(w, rule, subRule2, PseudoElement_ToolButtonDownArrow, opt->rect, opt->direction);
+ if (subRule2.hasDrawable()) {
+ subRule2.drawRule(p, r2);
+ } else {
+ toolOpt.rect = r2;
+ baseStyle()->drawPrimitive(QStyle::PE_IndicatorArrowDown, &toolOpt, p, w);
+ }
+ }
+
+ return;
+ }
+ break;
+
+#ifndef QT_NO_SCROLLBAR
+ case CC_ScrollBar:
+ if (const QStyleOptionSlider *sb = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
+ QStyleOptionSlider sbOpt(*sb);
+ if (!rule.hasDrawable()) {
+ sbOpt.rect = rule.borderRect(opt->rect);
+ rule.drawBackgroundImage(p, opt->rect);
+ baseStyle()->drawComplexControl(cc, &sbOpt, p, w);
+ } else {
+ rule.drawRule(p, opt->rect);
+ QWindowsStyle::drawComplexControl(cc, opt, p, w);
+ }
+ return;
+ }
+ break;
+#endif // QT_NO_SCROLLBAR
+
+#ifndef QT_NO_SLIDER
+ case CC_Slider:
+ if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
+ rule.drawRule(p, opt->rect);
+
+ QRenderRule grooveSubRule = renderRule(w, opt, PseudoElement_SliderGroove);
+ QRenderRule handleSubRule = renderRule(w, opt, PseudoElement_SliderHandle);
+ if (!grooveSubRule.hasDrawable()) {
+ QStyleOptionSlider slOpt(*slider);
+ bool handleHasRule = handleSubRule.hasDrawable();
+ // If the style specifies a different handler rule, draw the groove without the handler.
+ if (handleHasRule)
+ slOpt.subControls &= ~SC_SliderHandle;
+ baseStyle()->drawComplexControl(cc, &slOpt, p, w);
+ if (!handleHasRule)
+ return;
+ }
+
+ QRect gr = subControlRect(cc, opt, SC_SliderGroove, w);
+ if (slider->subControls & SC_SliderGroove) {
+ grooveSubRule.drawRule(p, gr);
+ }
+
+ if (slider->subControls & SC_SliderHandle) {
+ QRect hr = subControlRect(cc, opt, SC_SliderHandle, w);
+
+ QRenderRule subRule1 = renderRule(w, opt, PseudoElement_SliderSubPage);
+ if (subRule1.hasDrawable()) {
+ QRect r(gr.topLeft(),
+ slider->orientation == Qt::Horizontal
+ ? QPoint(hr.x()+hr.width()/2, gr.y()+gr.height() - 1)
+ : QPoint(gr.x()+gr.width() - 1, hr.y()+hr.height()/2));
+ subRule1.drawRule(p, r);
+ }
+
+ QRenderRule subRule2 = renderRule(w, opt, PseudoElement_SliderAddPage);
+ if (subRule2.hasDrawable()) {
+ QRect r(slider->orientation == Qt::Horizontal
+ ? QPoint(hr.x()+hr.width()/2+1, gr.y())
+ : QPoint(gr.x(), hr.y()+hr.height()/2+1),
+ gr.bottomRight());
+ subRule2.drawRule(p, r);
+ }
+
+ handleSubRule.drawRule(p, handleSubRule.boxRect(hr, Margin));
+ }
+
+ if (slider->subControls & SC_SliderTickmarks) {
+ // TODO...
+ }
+
+ return;
+ }
+ break;
+#endif // QT_NO_SLIDER
+
+ case CC_MdiControls:
+ if (hasStyleRule(w, PseudoElement_MdiCloseButton)
+ || hasStyleRule(w, PseudoElement_MdiNormalButton)
+ || hasStyleRule(w, PseudoElement_MdiMinButton)) {
+ QList<QVariant> layout = rule.styleHint(QLatin1String("button-layout")).toList();
+ if (layout.isEmpty())
+ layout = subControlLayout(QLatin1String("mNX"));
+
+ QStyleOptionComplex optCopy(*opt);
+ optCopy.subControls = 0;
+ for (int i = 0; i < layout.count(); i++) {
+ int layoutButton = layout[i].toInt();
+ if (layoutButton < PseudoElement_MdiCloseButton
+ || layoutButton > PseudoElement_MdiNormalButton)
+ continue;
+ QStyle::SubControl control = knownPseudoElements[layoutButton].subControl;
+ if (!(opt->subControls & control))
+ continue;
+ QRenderRule subRule = renderRule(w, opt, layoutButton);
+ if (subRule.hasDrawable()) {
+ QRect rect = subRule.boxRect(subControlRect(CC_MdiControls, opt, control, w), Margin);
+ subRule.drawRule(p, rect);
+ QIcon icon = standardIcon(subControlIcon(layoutButton), opt);
+ icon.paint(p, subRule.contentsRect(rect), Qt::AlignCenter);
+ } else {
+ optCopy.subControls |= control;
+ }
+ }
+
+ if (optCopy.subControls)
+ baseStyle()->drawComplexControl(CC_MdiControls, &optCopy, p, w);
+ return;
+ }
+ break;
+
+ case CC_TitleBar:
+ if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_TitleBar);
+ if (!subRule.hasDrawable() && !subRule.hasBox() && !subRule.hasBorder())
+ break;
+ subRule.drawRule(p, opt->rect);
+ QHash<QStyle::SubControl, QRect> layout = titleBarLayout(w, tb);
+
+ QRect ir;
+ ir = layout[SC_TitleBarLabel];
+ if (ir.isValid()) {
+ if (subRule.hasPalette())
+ p->setPen(subRule.palette()->foreground.color());
+ p->fillRect(ir, Qt::white);
+ p->drawText(ir.x(), ir.y(), ir.width(), ir.height(), Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine, tb->text);
+ }
+
+ QPixmap pm;
+
+ ir = layout[SC_TitleBarSysMenu];
+ if (ir.isValid()) {
+ QRenderRule subSubRule = renderRule(w, opt, PseudoElement_TitleBarSysMenu);
+ subSubRule.drawRule(p, ir);
+ ir = subSubRule.contentsRect(ir);
+ if (!tb->icon.isNull()) {
+ tb->icon.paint(p, ir);
+ } else {
+ int iconSize = pixelMetric(PM_SmallIconSize, tb, w);
+ pm = standardIcon(SP_TitleBarMenuButton, 0, w).pixmap(iconSize, iconSize);
+ drawItemPixmap(p, ir, Qt::AlignCenter, pm);
+ }
+ }
+
+ ir = layout[SC_TitleBarCloseButton];
+ if (ir.isValid()) {
+ QRenderRule subSubRule = renderRule(w, opt, PseudoElement_TitleBarCloseButton);
+ subSubRule.drawRule(p, ir);
+
+ QSize sz = subSubRule.contentsRect(ir).size();
+ if ((tb->titleBarFlags & Qt::WindowType_Mask) == Qt::Tool)
+ pm = standardIcon(SP_DockWidgetCloseButton, 0, w).pixmap(sz);
+ else
+ pm = standardIcon(SP_TitleBarCloseButton, 0, w).pixmap(sz);
+ drawItemPixmap(p, ir, Qt::AlignCenter, pm);
+ }
+
+ int pes[] = {
+ PseudoElement_TitleBarMaxButton,
+ PseudoElement_TitleBarMinButton,
+ PseudoElement_TitleBarNormalButton,
+ PseudoElement_TitleBarShadeButton,
+ PseudoElement_TitleBarUnshadeButton,
+ PseudoElement_TitleBarContextHelpButton
+ };
+
+ for (unsigned int i = 0; i < sizeof(pes)/sizeof(int); i++) {
+ int pe = pes[i];
+ QStyle::SubControl sc = knownPseudoElements[pe].subControl;
+ ir = layout[sc];
+ if (!ir.isValid())
+ continue;
+ QRenderRule subSubRule = renderRule(w, opt, pe);
+ subSubRule.drawRule(p, ir);
+ pm = standardIcon(subControlIcon(pe), 0, w).pixmap(subSubRule.contentsRect(ir).size());
+ drawItemPixmap(p, ir, Qt::AlignCenter, pm);
+ }
+
+ return;
+ }
+ break;
+
+
+ default:
+ break;
+ }
+
+ baseStyle()->drawComplexControl(cc, opt, p, w);
+}
+
+void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter *p,
+ const QWidget *w) const
+{
+ RECURSION_GUARD(baseStyle()->drawControl(ce, opt, p, w); return)
+
+ QRenderRule rule = renderRule(w, opt);
+ int pe1 = PseudoElement_None, pe2 = PseudoElement_None;
+ bool fallback = false;
+
+ switch (ce) {
+ case CE_ToolButtonLabel:
+ if (const QStyleOptionToolButton *btn = qstyleoption_cast<const QStyleOptionToolButton *>(opt)) {
+ if (rule.hasBox() || btn->features & QStyleOptionToolButton::Arrow) {
+ QCommonStyle::drawControl(ce, opt, p, w);
+ } else {
+ QStyleOptionToolButton butOpt(*btn);
+ rule.configurePalette(&butOpt.palette, QPalette::ButtonText, QPalette::Button);
+ baseStyle()->drawControl(ce, &butOpt, p, w);
+ }
+ return;
+ }
+ break;
+
+ case CE_FocusFrame:
+ if (!rule.hasNativeBorder()) {
+ rule.drawBorder(p, opt->rect);
+ return;
+ }
+ break;
+
+ case CE_PushButton:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
+ if (rule.hasDrawable() || rule.hasBox() || rule.hasPosition() || rule.hasPalette() ||
+ ((btn->features & QStyleOptionButton::HasMenu) && hasStyleRule(w, PseudoElement_PushButtonMenuIndicator))) {
+ ParentStyle::drawControl(ce, opt, p, w);
+ return;
+ }
+ }
+ break;
+ case CE_PushButtonBevel:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
+ QStyleOptionButton btnOpt(*btn);
+ btnOpt.rect = rule.borderRect(opt->rect);
+ if (rule.hasNativeBorder()) {
+ rule.drawBackgroundImage(p, btnOpt.rect);
+ rule.configurePalette(&btnOpt.palette, QPalette::ButtonText, QPalette::Button);
+ bool customMenu = (btn->features & QStyleOptionButton::HasMenu
+ && hasStyleRule(w, PseudoElement_PushButtonMenuIndicator));
+ if (customMenu)
+ btnOpt.features &= ~QStyleOptionButton::HasMenu;
+ if (rule.baseStyleCanDraw()) {
+ baseStyle()->drawControl(ce, &btnOpt, p, w);
+ } else {
+ QWindowsStyle::drawControl(ce, &btnOpt, p, w);
+ }
+ if (!customMenu)
+ return;
+ } else {
+ rule.drawRule(p, opt->rect);
+ }
+
+ if (btn->features & QStyleOptionButton::HasMenu) {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_PushButtonMenuIndicator);
+ QRect ir = positionRect(w, rule, subRule, PseudoElement_PushButtonMenuIndicator, opt->rect, opt->direction);
+ if (subRule.hasDrawable()) {
+ subRule.drawRule(p, ir);
+ } else {
+ btnOpt.rect = ir;
+ baseStyle()->drawPrimitive(PE_IndicatorArrowDown, &btnOpt, p, w);
+ }
+ }
+ }
+ return;
+
+ case CE_PushButtonLabel:
+ if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
+ QStyleOptionButton butOpt(*button);
+ rule.configurePalette(&butOpt.palette, QPalette::ButtonText, QPalette::Button);
+ if (rule.hasPosition() && rule.position()->textAlignment != 0) {
+ Qt::Alignment textAlignment = rule.position()->textAlignment;
+ QRect textRect = button->rect;
+ uint tf = Qt::TextShowMnemonic;
+ const uint verticalAlignMask = Qt::AlignVCenter | Qt::AlignTop | Qt::AlignLeft;
+ tf |= (textAlignment & verticalAlignMask) ? (textAlignment & verticalAlignMask) : Qt::AlignVCenter;
+ if (!styleHint(SH_UnderlineShortcut, button, w))
+ tf |= Qt::TextHideMnemonic;
+ if (!button->icon.isNull()) {
+ //Group both icon and text
+ QRect iconRect;
+ QIcon::Mode mode = button->state & State_Enabled ? QIcon::Normal : QIcon::Disabled;
+ if (mode == QIcon::Normal && button->state & State_HasFocus)
+ mode = QIcon::Active;
+ QIcon::State state = QIcon::Off;
+ if (button->state & State_On)
+ state = QIcon::On;
+
+ QPixmap pixmap = button->icon.pixmap(button->iconSize, mode, state);
+ int labelWidth = pixmap.width();
+ int labelHeight = pixmap.height();
+ int iconSpacing = 4;//### 4 is currently hardcoded in QPushButton::sizeHint()
+ int textWidth = button->fontMetrics.boundingRect(opt->rect, tf, button->text).width();
+ if (!button->text.isEmpty())
+ labelWidth += (textWidth + iconSpacing);
+
+ //Determine label alignment:
+ if (textAlignment & Qt::AlignLeft) { /*left*/
+ iconRect = QRect(textRect.x(), textRect.y() + (textRect.height() - labelHeight) / 2,
+ pixmap.width(), pixmap.height());
+ } else if (textAlignment & Qt::AlignHCenter) { /* center */
+ iconRect = QRect(textRect.x() + (textRect.width() - labelWidth) / 2,
+ textRect.y() + (textRect.height() - labelHeight) / 2,
+ pixmap.width(), pixmap.height());
+ } else { /*right*/
+ iconRect = QRect(textRect.x() + textRect.width() - labelWidth,
+ textRect.y() + (textRect.height() - labelHeight) / 2,
+ pixmap.width(), pixmap.height());
+ }
+
+ iconRect = visualRect(button->direction, textRect, iconRect);
+
+ tf |= Qt::AlignLeft; //left align, we adjust the text-rect instead
+
+ if (button->direction == Qt::RightToLeft)
+ textRect.setRight(iconRect.left() - iconSpacing);
+ else
+ textRect.setLeft(iconRect.left() + iconRect.width() + iconSpacing);
+
+ if (button->state & (State_On | State_Sunken))
+ iconRect.translate(pixelMetric(PM_ButtonShiftHorizontal, opt, w),
+ pixelMetric(PM_ButtonShiftVertical, opt, w));
+ p->drawPixmap(iconRect, pixmap);
+ } else {
+ tf |= textAlignment;
+ }
+ if (button->state & (State_On | State_Sunken))
+ textRect.translate(pixelMetric(PM_ButtonShiftHorizontal, opt, w),
+ pixelMetric(PM_ButtonShiftVertical, opt, w));
+
+ if (button->features & QStyleOptionButton::HasMenu) {
+ int indicatorSize = pixelMetric(PM_MenuButtonIndicator, button, w);
+ if (button->direction == Qt::LeftToRight)
+ textRect = textRect.adjusted(0, 0, -indicatorSize, 0);
+ else
+ textRect = textRect.adjusted(indicatorSize, 0, 0, 0);
+ }
+ drawItemText(p, textRect, tf, butOpt.palette, (button->state & State_Enabled),
+ button->text, QPalette::ButtonText);
+ } else {
+ ParentStyle::drawControl(ce, &butOpt, p, w);
+ }
+ }
+ return;
+
+ case CE_RadioButton:
+ case CE_CheckBox:
+ if (rule.hasBox() || !rule.hasNativeBorder() || rule.hasDrawable() || hasStyleRule(w, PseudoElement_Indicator)) {
+ rule.drawRule(p, opt->rect);
+ ParentStyle::drawControl(ce, opt, p, w);
+ return;
+ } else if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
+ QStyleOptionButton butOpt(*btn);
+ rule.configurePalette(&butOpt.palette, QPalette::ButtonText, QPalette::Button);
+ baseStyle()->drawControl(ce, &butOpt, p, w);
+ return;
+ }
+ break;
+ case CE_RadioButtonLabel:
+ case CE_CheckBoxLabel:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
+ QStyleOptionButton butOpt(*btn);
+ rule.configurePalette(&butOpt.palette, QPalette::ButtonText, QPalette::Button);
+ ParentStyle::drawControl(ce, &butOpt, p, w);
+ }
+ return;
+
+ case CE_Splitter:
+ pe1 = PseudoElement_SplitterHandle;
+ break;
+
+ case CE_ToolBar:
+ if (rule.hasBackground()) {
+ rule.drawBackground(p, opt->rect);
+ }
+ if (rule.hasBorder()) {
+ rule.drawBorder(p, rule.borderRect(opt->rect));
+ } else {
+#ifndef QT_NO_TOOLBAR
+ if (const QStyleOptionToolBar *tb = qstyleoption_cast<const QStyleOptionToolBar *>(opt)) {
+ QStyleOptionToolBar newTb(*tb);
+ newTb.rect = rule.borderRect(opt->rect);
+ baseStyle()->drawControl(ce, &newTb, p, w);
+ }
+#endif // QT_NO_TOOLBAR
+ }
+ return;
+
+ case CE_MenuEmptyArea:
+ case CE_MenuBarEmptyArea:
+ if (rule.hasDrawable()) {
+ // Drawn by PE_Widget
+ return;
+ }
+ break;
+
+ case CE_MenuTearoff:
+ case CE_MenuScroller:
+ if (const QStyleOptionMenuItem *m = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
+ QStyleOptionMenuItem mi(*m);
+ int pe = ce == CE_MenuTearoff ? PseudoElement_MenuTearoff : PseudoElement_MenuScroller;
+ QRenderRule subRule = renderRule(w, opt, pe);
+ mi.rect = subRule.contentsRect(opt->rect);
+ rule.configurePalette(&mi.palette, QPalette::ButtonText, QPalette::Button);
+ subRule.configurePalette(&mi.palette, QPalette::ButtonText, QPalette::Button);
+
+ if (subRule.hasDrawable()) {
+ subRule.drawRule(p, opt->rect);
+ } else {
+ baseStyle()->drawControl(ce, &mi, p, w);
+ }
+ }
+ return;
+
+ case CE_MenuItem:
+ if (const QStyleOptionMenuItem *m = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
+ QStyleOptionMenuItem mi(*m);
+
+ int pseudo = (mi.menuItemType == QStyleOptionMenuItem::Separator) ? PseudoElement_MenuSeparator : PseudoElement_Item;
+ QRenderRule subRule = renderRule(w, opt, pseudo);
+ mi.rect = subRule.contentsRect(opt->rect);
+ rule.configurePalette(&mi.palette, QPalette::ButtonText, QPalette::Button);
+ rule.configurePalette(&mi.palette, QPalette::HighlightedText, QPalette::Highlight);
+ subRule.configurePalette(&mi.palette, QPalette::ButtonText, QPalette::Button);
+ subRule.configurePalette(&mi.palette, QPalette::HighlightedText, QPalette::Highlight);
+ QFont oldFont = p->font();
+ if (subRule.hasFont)
+ p->setFont(subRule.font.resolve(p->font()));
+
+ // We fall back to drawing with the style sheet code whenever at least one of the
+ // items are styled in an incompatible way, such as having a background image.
+ QRenderRule allRules = renderRule(w, PseudoElement_Item, PseudoClass_Any);
+
+ if ((pseudo == PseudoElement_MenuSeparator) && subRule.hasDrawable()) {
+ subRule.drawRule(p, opt->rect);
+ } else if ((pseudo == PseudoElement_Item)
+ && (allRules.hasBox() || allRules.hasBorder()
+ || (allRules.background() && !allRules.background()->pixmap.isNull()))) {
+ subRule.drawRule(p, opt->rect);
+ if (subRule.hasBackground()) {
+ mi.palette.setBrush(QPalette::Highlight, Qt::NoBrush);
+ mi.palette.setBrush(QPalette::Button, Qt::NoBrush);
+ } else {
+ mi.palette.setBrush(QPalette::Highlight, mi.palette.brush(QPalette::Button));
+ }
+ mi.palette.setBrush(QPalette::HighlightedText, mi.palette.brush(QPalette::ButtonText));
+
+ bool checkable = mi.checkType != QStyleOptionMenuItem::NotCheckable;
+ bool checked = checkable ? mi.checked : false;
+
+ bool dis = !(opt->state & QStyle::State_Enabled),
+ act = opt->state & QStyle::State_Selected;
+
+ if (!mi.icon.isNull()) {
+ QIcon::Mode mode = dis ? QIcon::Disabled : QIcon::Normal;
+ if (act && !dis)
+ mode = QIcon::Active;
+ QPixmap pixmap;
+ if (checked)
+ pixmap = mi.icon.pixmap(pixelMetric(PM_SmallIconSize), mode, QIcon::On);
+ else
+ pixmap = mi.icon.pixmap(pixelMetric(PM_SmallIconSize), mode);
+ int pixw = pixmap.width();
+ int pixh = pixmap.height();
+ QRenderRule iconRule = renderRule(w, opt, PseudoElement_MenuIcon);
+ if (!iconRule.hasGeometry()) {
+ iconRule.geo = new QStyleSheetGeometryData(pixw, pixh, pixw, pixh, -1, -1);
+ } else {
+ iconRule.geo->width = pixw;
+ iconRule.geo->height = pixh;
+ }
+ QRect iconRect = positionRect(w, subRule, iconRule, PseudoElement_MenuIcon, opt->rect, opt->direction);
+ iconRule.drawRule(p, iconRect);
+ QRect pmr(0, 0, pixw, pixh);
+ pmr.moveCenter(iconRect.center());
+ p->drawPixmap(pmr.topLeft(), pixmap);
+ } else if (checkable) {
+ QRenderRule subSubRule = renderRule(w, opt, PseudoElement_MenuCheckMark);
+ if (subSubRule.hasDrawable() || checked) {
+ QStyleOptionMenuItem newMi = mi;
+ newMi.rect = positionRect(w, subRule, subSubRule, PseudoElement_MenuCheckMark, opt->rect, opt->direction);
+ drawPrimitive(PE_IndicatorMenuCheckMark, &newMi, p, w);
+ }
+ }
+
+ QRect textRect = subRule.contentsRect(opt->rect);
+ textRect.setWidth(textRect.width() - mi.tabWidth);
+ QString s = mi.text;
+ p->setPen(mi.palette.buttonText().color());
+ if (!s.isEmpty()) {
+ int text_flags = Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
+ if (!styleHint(SH_UnderlineShortcut, &mi, w))
+ text_flags |= Qt::TextHideMnemonic;
+ int t = s.indexOf(QLatin1Char('\t'));
+ if (t >= 0) {
+ QRect vShortcutRect = visualRect(opt->direction, mi.rect,
+ QRect(textRect.topRight(), QPoint(mi.rect.right(), textRect.bottom())));
+ p->drawText(vShortcutRect, text_flags, s.mid(t + 1));
+ s = s.left(t);
+ }
+ p->drawText(textRect, text_flags, s.left(t));
+ }
+
+ if (mi.menuItemType == QStyleOptionMenuItem::SubMenu) {// draw sub menu arrow
+ PrimitiveElement arrow = (opt->direction == Qt::RightToLeft) ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight;
+ QRenderRule subRule2 = renderRule(w, opt, PseudoElement_MenuRightArrow);
+ mi.rect = positionRect(w, subRule, subRule2, PseudoElement_MenuRightArrow, opt->rect, mi.direction);
+ drawPrimitive(arrow, &mi, p, w);
+ }
+ } else if (hasStyleRule(w, PseudoElement_MenuCheckMark) || hasStyleRule(w, PseudoElement_MenuRightArrow)) {
+ QWindowsStyle::drawControl(ce, &mi, p, w);
+ if (mi.checkType != QStyleOptionMenuItem::NotCheckable && !mi.checked) {
+ // We have a style defined, but QWindowsStyle won't draw anything if not checked.
+ // So we mimick what QWindowsStyle would do.
+ int checkcol = qMax<int>(mi.maxIconWidth, QWindowsStylePrivate::windowsCheckMarkWidth);
+ QRect vCheckRect = visualRect(opt->direction, mi.rect, QRect(mi.rect.x(), mi.rect.y(), checkcol, mi.rect.height()));
+ if (mi.state.testFlag(State_Enabled) && mi.state.testFlag(State_Selected)) {
+ qDrawShadePanel(p, vCheckRect, mi.palette, true, 1, &mi.palette.brush(QPalette::Button));
+ } else {
+ QBrush fill(mi.palette.light().color(), Qt::Dense4Pattern);
+ qDrawShadePanel(p, vCheckRect, mi.palette, true, 1, &fill);
+ }
+ QRenderRule subSubRule = renderRule(w, opt, PseudoElement_MenuCheckMark);
+ if (subSubRule.hasDrawable()) {
+ QStyleOptionMenuItem newMi(mi);
+ newMi.rect = visualRect(opt->direction, mi.rect, QRect(mi.rect.x() + QWindowsStylePrivate::windowsItemFrame,
+ mi.rect.y() + QWindowsStylePrivate::windowsItemFrame,
+ checkcol - 2 * QWindowsStylePrivate::windowsItemFrame,
+ mi.rect.height() - 2 * QWindowsStylePrivate::windowsItemFrame));
+ drawPrimitive(PE_IndicatorMenuCheckMark, &newMi, p, w);
+ }
+ }
+ } else {
+ if (rule.hasDrawable() && !subRule.hasDrawable() && !(opt->state & QStyle::State_Selected)) {
+ mi.palette.setColor(QPalette::Window, Qt::transparent);
+ mi.palette.setColor(QPalette::Button, Qt::transparent);
+ }
+ if (rule.baseStyleCanDraw() && subRule.baseStyleCanDraw()) {
+ baseStyle()->drawControl(ce, &mi, p, w);
+ } else {
+ ParentStyle::drawControl(ce, &mi, p, w);
+ }
+ }
+
+ if (subRule.hasFont)
+ p->setFont(oldFont);
+
+ return;
+ }
+ return;
+
+ case CE_MenuBarItem:
+ if (const QStyleOptionMenuItem *m = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
+ QStyleOptionMenuItem mi(*m);
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_Item);
+ mi.rect = subRule.contentsRect(opt->rect);
+ rule.configurePalette(&mi.palette, QPalette::ButtonText, QPalette::Button);
+ subRule.configurePalette(&mi.palette, QPalette::ButtonText, QPalette::Button);
+
+ if (subRule.hasDrawable()) {
+ subRule.drawRule(p, opt->rect);
+ QCommonStyle::drawControl(ce, &mi, p, w);
+ } else {
+ if (rule.hasDrawable() && !(opt->state & QStyle::State_Selected)) {
+ // So that the menu bar background is not hidden by the items
+ mi.palette.setColor(QPalette::Window, Qt::transparent);
+ mi.palette.setColor(QPalette::Button, Qt::transparent);
+ }
+ baseStyle()->drawControl(ce, &mi, p, w);
+ }
+ }
+ return;
+
+#ifndef QT_NO_COMBOBOX
+ case CE_ComboBoxLabel:
+ if (!rule.hasBox())
+ break;
+ if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
+ QRect editRect = subControlRect(CC_ComboBox, cb, SC_ComboBoxEditField, w);
+ p->save();
+ p->setClipRect(editRect);
+ if (!cb->currentIcon.isNull()) {
+ int spacing = rule.hasBox() ? rule.box()->spacing : -1;
+ if (spacing == -1)
+ spacing = 6;
+ QIcon::Mode mode = cb->state & State_Enabled ? QIcon::Normal : QIcon::Disabled;
+ QPixmap pixmap = cb->currentIcon.pixmap(cb->iconSize, mode);
+ QRect iconRect(editRect);
+ iconRect.setWidth(cb->iconSize.width());
+ iconRect = alignedRect(cb->direction,
+ Qt::AlignLeft | Qt::AlignVCenter,
+ iconRect.size(), editRect);
+ drawItemPixmap(p, iconRect, Qt::AlignCenter, pixmap);
+
+ if (cb->direction == Qt::RightToLeft)
+ editRect.translate(-spacing - cb->iconSize.width(), 0);
+ else
+ editRect.translate(cb->iconSize.width() + spacing, 0);
+ }
+ if (!cb->currentText.isEmpty() && !cb->editable) {
+ QPalette styledPalette(cb->palette);
+ rule.configurePalette(&styledPalette, QPalette::Text, QPalette::Base);
+ drawItemText(p, editRect.adjusted(0, 0, 0, 0), Qt::AlignLeft | Qt::AlignVCenter, styledPalette,
+ cb->state & State_Enabled, cb->currentText, QPalette::Text);
+ }
+ p->restore();
+ return;
+ }
+ break;
+#endif // QT_NO_COMBOBOX
+
+ case CE_Header:
+ if (hasStyleRule(w, PseudoElement_HeaderViewUpArrow)
+ || hasStyleRule(w, PseudoElement_HeaderViewDownArrow)) {
+ ParentStyle::drawControl(ce, opt, p, w);
+ return;
+ }
+ if(hasStyleRule(w, PseudoElement_HeaderViewSection)) {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_HeaderViewSection);
+ if (!subRule.hasNativeBorder() || !subRule.baseStyleCanDraw()
+ || subRule.hasBackground() || subRule.hasPalette()) {
+ ParentStyle::drawControl(ce, opt, p, w);
+ return;
+ }
+ }
+ break;
+ case CE_HeaderSection:
+ if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_HeaderViewSection);
+ if (subRule.hasNativeBorder()) {
+ QStyleOptionHeader hdr(*header);
+ subRule.configurePalette(&hdr.palette, QPalette::ButtonText, QPalette::Button);
+
+ if (subRule.baseStyleCanDraw()) {
+ baseStyle()->drawControl(CE_HeaderSection, &hdr, p, w);
+ } else {
+ QWindowsStyle::drawControl(CE_HeaderSection, &hdr, p, w);
+ }
+ } else {
+ subRule.drawRule(p, opt->rect);
+ }
+ return;
+ }
+ break;
+
+ case CE_HeaderLabel:
+ if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
+ QStyleOptionHeader hdr(*header);
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_HeaderViewSection);
+ subRule.configurePalette(&hdr.palette, QPalette::ButtonText, QPalette::Button);
+ QFont oldFont = p->font();
+ if (subRule.hasFont)
+ p->setFont(subRule.font.resolve(p->font()));
+ baseStyle()->drawControl(ce, &hdr, p, w);
+ if (subRule.hasFont)
+ p->setFont(oldFont);
+ return;
+ }
+ break;
+
+ case CE_HeaderEmptyArea:
+ if (rule.hasDrawable()) {
+ return;
+ }
+ break;
+
+ case CE_ProgressBar:
+ QWindowsStyle::drawControl(ce, opt, p, w);
+ return;
+
+ case CE_ProgressBarGroove:
+ if (!rule.hasNativeBorder()) {
+ rule.drawRule(p, rule.boxRect(opt->rect, Margin));
+ return;
+ }
+ break;
+
+ case CE_ProgressBarContents: {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_ProgressBarChunk);
+ if (subRule.hasDrawable()) {
+ if (const QStyleOptionProgressBarV2 *pb = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(opt)) {
+ p->save();
+ p->setClipRect(pb->rect);
+
+ qint64 minimum = qint64(pb->minimum);
+ qint64 maximum = qint64(pb->maximum);
+ qint64 progress = qint64(pb->progress);
+ bool vertical = (pb->orientation == Qt::Vertical);
+ bool inverted = pb->invertedAppearance;
+
+ QTransform m;
+ QRect rect = pb->rect;
+ if (vertical) {
+ rect = QRect(rect.y(), rect.x(), rect.height(), rect.width());
+ m.rotate(90);
+ m.translate(0, -(rect.height() + rect.y()*2));
+ }
+
+ bool reverse = ((!vertical && (pb->direction == Qt::RightToLeft)) || vertical);
+ if (inverted)
+ reverse = !reverse;
+ const bool indeterminate = pb->minimum == pb->maximum;
+ qreal fillRatio = indeterminate ? 0.50 : qreal(progress - minimum)/(maximum - minimum);
+ int fillWidth = int(rect.width() * fillRatio);
+ int chunkWidth = fillWidth;
+ if (subRule.hasContentsSize()) {
+ QSize sz = subRule.size();
+ chunkWidth = (opt->state & QStyle::State_Horizontal) ? sz.width() : sz.height();
+ }
+
+ QRect r = rect;
+ if (pb->minimum == 0 && pb->maximum == 0) {
+ Q_D(const QWindowsStyle);
+ int chunkCount = fillWidth/chunkWidth;
+ int offset = (d->animateStep*8%rect.width());
+ int x = reverse ? r.left() + r.width() - offset - chunkWidth : r.x() + offset;
+ while (chunkCount > 0) {
+ r.setRect(x, rect.y(), chunkWidth, rect.height());
+ r = m.mapRect(QRectF(r)).toRect();
+ subRule.drawRule(p, r);
+ x += reverse ? -chunkWidth : chunkWidth;
+ if (reverse ? x < rect.left() : x > rect.right())
+ break;
+ --chunkCount;
+ }
+
+ r = rect;
+ x = reverse ? r.right() - (r.left() - x - chunkWidth)
+ : r.left() + (x - r.right() - chunkWidth);
+ while (chunkCount > 0) {
+ r.setRect(x, rect.y(), chunkWidth, rect.height());
+ r = m.mapRect(QRectF(r)).toRect();
+ subRule.drawRule(p, r);
+ x += reverse ? -chunkWidth : chunkWidth;
+ --chunkCount;
+ };
+ } else {
+ int x = reverse ? r.left() + r.width() - chunkWidth : r.x();
+
+ for (int i = 0; i < ceil(qreal(fillWidth)/chunkWidth); ++i) {
+ r.setRect(x, rect.y(), chunkWidth, rect.height());
+ r = m.mapRect(QRectF(r)).toRect();
+ subRule.drawRule(p, r);
+ x += reverse ? -chunkWidth : chunkWidth;
+ }
+ }
+
+ p->restore();
+ return;
+ }
+ }
+ }
+ break;
+
+ case CE_ProgressBarLabel:
+ if (const QStyleOptionProgressBarV2 *pb = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(opt)) {
+ if (rule.hasBox() || rule.hasBorder() || hasStyleRule(w, PseudoElement_ProgressBarChunk)) {
+ drawItemText(p, pb->rect, pb->textAlignment | Qt::TextSingleLine, pb->palette,
+ pb->state & State_Enabled, pb->text, QPalette::Text);
+ } else {
+ QStyleOptionProgressBarV2 pbCopy(*pb);
+ rule.configurePalette(&pbCopy.palette, QPalette::HighlightedText, QPalette::Highlight);
+ baseStyle()->drawControl(ce, &pbCopy, p, w);
+ }
+ return;
+ }
+ break;
+
+ case CE_SizeGrip:
+ if (const QStyleOptionSizeGrip *sgOpt = qstyleoption_cast<const QStyleOptionSizeGrip *>(opt)) {
+ if (rule.hasDrawable()) {
+ rule.drawFrame(p, opt->rect);
+ p->save();
+ switch (sgOpt->corner) {
+ case Qt::BottomRightCorner: break;
+ case Qt::BottomLeftCorner: p->rotate(90); break;
+ case Qt::TopLeftCorner: p->rotate(180); break;
+ case Qt::TopRightCorner: p->rotate(270); break;
+ default: break;
+ }
+ rule.drawImage(p, opt->rect);
+ p->restore();
+ } else {
+ QStyleOptionSizeGrip sg(*sgOpt);
+ sg.rect = rule.contentsRect(opt->rect);
+ baseStyle()->drawControl(CE_SizeGrip, &sg, p, w);
+ }
+ return;
+ }
+ break;
+
+ case CE_ToolBoxTab:
+ QWindowsStyle::drawControl(ce, opt, p, w);
+ return;
+
+ case CE_ToolBoxTabShape: {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_ToolBoxTab);
+ if (subRule.hasDrawable()) {
+ subRule.drawRule(p, opt->rect);
+ return;
+ }
+ }
+ break;
+
+ case CE_ToolBoxTabLabel:
+ if (const QStyleOptionToolBox *box = qstyleoption_cast<const QStyleOptionToolBox *>(opt)) {
+ QStyleOptionToolBox boxCopy(*box);
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_ToolBoxTab);
+ subRule.configurePalette(&boxCopy.palette, QPalette::ButtonText, QPalette::Button);
+ QFont oldFont = p->font();
+ if (subRule.hasFont)
+ p->setFont(subRule.font);
+ boxCopy.rect = subRule.contentsRect(opt->rect);
+ QWindowsStyle::drawControl(ce, &boxCopy, p , w);
+ if (subRule.hasFont)
+ p->setFont(oldFont);
+ return;
+ }
+ break;
+
+ case CE_ScrollBarAddPage:
+ pe1 = PseudoElement_ScrollBarAddPage;
+ break;
+
+ case CE_ScrollBarSubPage:
+ pe1 = PseudoElement_ScrollBarSubPage;
+ break;
+
+ case CE_ScrollBarAddLine:
+ pe1 = PseudoElement_ScrollBarAddLine;
+ pe2 = (opt->state & QStyle::State_Horizontal) ? PseudoElement_ScrollBarRightArrow : PseudoElement_ScrollBarDownArrow;
+ fallback = true;
+ break;
+
+ case CE_ScrollBarSubLine:
+ pe1 = PseudoElement_ScrollBarSubLine;
+ pe2 = (opt->state & QStyle::State_Horizontal) ? PseudoElement_ScrollBarLeftArrow : PseudoElement_ScrollBarUpArrow;
+ fallback = true;
+ break;
+
+ case CE_ScrollBarFirst:
+ pe1 = PseudoElement_ScrollBarFirst;
+ break;
+
+ case CE_ScrollBarLast:
+ pe1 = PseudoElement_ScrollBarLast;
+ break;
+
+ case CE_ScrollBarSlider:
+ pe1 = PseudoElement_ScrollBarSlider;
+ fallback = true;
+ break;
+
+#ifndef QT_NO_ITEMVIEWS
+ case CE_ItemViewItem:
+ if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(opt)) {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_ViewItem);
+ if (subRule.hasDrawable() || hasStyleRule(w, PseudoElement_Indicator)) {
+ QStyleOptionViewItemV4 optCopy(*vopt);
+ subRule.configurePalette(&optCopy.palette, vopt->state & QStyle::State_Selected ? QPalette::HighlightedText : QPalette::Text,
+ vopt->state & QStyle::State_Selected ? QPalette::Highlight : QPalette::Base);
+ QWindowsStyle::drawControl(ce, &optCopy, p, w);
+ } else {
+ QStyleOptionViewItemV4 voptCopy(*vopt);
+ subRule.configurePalette(&voptCopy.palette, QPalette::Text, QPalette::NoRole);
+ baseStyle()->drawControl(ce, &voptCopy, p, w);
+ }
+ return;
+ }
+ break;
+#endif // QT_NO_ITEMVIEWS
+
+#ifndef QT_NO_TABBAR
+ case CE_TabBarTab:
+ if (hasStyleRule(w, PseudoElement_TabBarTab)) {
+ QWindowsStyle::drawControl(ce, opt, p, w);
+ return;
+ }
+ break;
+
+ case CE_TabBarTabLabel:
+ case CE_TabBarTabShape:
+ if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
+ QStyleOptionTabV3 tabCopy(*tab);
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_TabBarTab);
+ QRect r = positionRect(w, subRule, PseudoElement_TabBarTab, opt->rect, opt->direction);
+ if (ce == CE_TabBarTabShape && subRule.hasDrawable()) {
+ subRule.drawRule(p, r);
+ return;
+ }
+ subRule.configurePalette(&tabCopy.palette, QPalette::WindowText, QPalette::Window);
+ QFont oldFont = p->font();
+ if (subRule.hasFont)
+ p->setFont(subRule.font);
+ if (subRule.hasBox() || !subRule.hasNativeBorder()) {
+ tabCopy.rect = ce == CE_TabBarTabShape ? subRule.borderRect(r)
+ : subRule.contentsRect(r);
+ QWindowsStyle::drawControl(ce, &tabCopy, p, w);
+ } else {
+ baseStyle()->drawControl(ce, &tabCopy, p, w);
+ }
+ if (subRule.hasFont)
+ p->setFont(oldFont);
+
+ return;
+ }
+ break;
+#endif // QT_NO_TABBAR
+
+ case CE_ColumnViewGrip:
+ if (rule.hasDrawable()) {
+ rule.drawRule(p, opt->rect);
+ return;
+ }
+ break;
+
+ case CE_DockWidgetTitle:
+ if (const QStyleOptionDockWidgetV2 *dwOpt = qstyleoption_cast<const QStyleOptionDockWidgetV2 *>(opt)) {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_DockWidgetTitle);
+ if (!subRule.hasDrawable() && !subRule.hasPosition())
+ break;
+ if (subRule.hasDrawable()) {
+ subRule.drawRule(p, opt->rect);
+ } else {
+ QStyleOptionDockWidgetV2 dwCopy(*dwOpt);
+ dwCopy.title = QString();
+ baseStyle()->drawControl(ce, &dwCopy, p, w);
+ }
+
+ if (!dwOpt->title.isEmpty()) {
+ QRect r = opt->rect;
+ if (dwOpt->verticalTitleBar) {
+ QSize s = r.size();
+ s.transpose();
+ r.setSize(s);
+
+ p->save();
+ p->translate(r.left(), r.top() + r.width());
+ p->rotate(-90);
+ p->translate(-r.left(), -r.top());
+ }
+
+ Qt::Alignment alignment = 0;
+ if (subRule.hasPosition())
+ alignment = subRule.position()->textAlignment;
+ if (alignment == 0)
+ alignment = Qt::AlignLeft;
+ drawItemText(p, subRule.contentsRect(opt->rect),
+ alignment | Qt::TextShowMnemonic, dwOpt->palette,
+ dwOpt->state & State_Enabled, dwOpt->title,
+ QPalette::WindowText);
+
+ if (dwOpt->verticalTitleBar)
+ p->restore();
+ }
+
+ return;
+ }
+ break;
+ case CE_ShapedFrame:
+ if (const QStyleOptionFrame *frm = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
+ if (rule.hasNativeBorder()) {
+ QStyleOptionFrameV3 frmOpt(*frm);
+ rule.configurePalette(&frmOpt.palette, QPalette::Text, QPalette::Base);
+ frmOpt.rect = rule.borderRect(frmOpt.rect);
+ baseStyle()->drawControl(ce, &frmOpt, p, w);
+ }
+ // else, borders are already drawn in PE_Widget
+ }
+ return;
+
+
+ default:
+ break;
+ }
+
+ if (pe1 != PseudoElement_None) {
+ QRenderRule subRule = renderRule(w, opt, pe1);
+ if (subRule.bg != 0 || subRule.hasDrawable()) {
+ //We test subRule.bg directly because hasBackground() would return false for background:none.
+ //But we still don't want the default drawning in that case (example for QScrollBar::add-page) (task 198926)
+ subRule.drawRule(p, opt->rect);
+ } else if (fallback) {
+ QWindowsStyle::drawControl(ce, opt, p, w);
+ pe2 = PseudoElement_None;
+ } else {
+ baseStyle()->drawControl(ce, opt, p, w);
+ }
+ if (pe2 != PseudoElement_None) {
+ QRenderRule subSubRule = renderRule(w, opt, pe2);
+ QRect r = positionRect(w, subRule, subSubRule, pe2, opt->rect, opt->direction);
+ subSubRule.drawRule(p, r);
+ }
+ return;
+ }
+
+ baseStyle()->drawControl(ce, opt, p, w);
+}
+
+void QStyleSheetStyle::drawItemPixmap(QPainter *p, const QRect &rect, int alignment, const
+ QPixmap &pixmap) const
+{
+ baseStyle()->drawItemPixmap(p, rect, alignment, pixmap);
+}
+
+void QStyleSheetStyle::drawItemText(QPainter *painter, const QRect& rect, int alignment, const QPalette &pal,
+ bool enabled, const QString& text, QPalette::ColorRole textRole) const
+{
+ baseStyle()->drawItemText(painter, rect, alignment, pal, enabled, text, textRole);
+}
+
+void QStyleSheetStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p,
+ const QWidget *w) const
+{
+ RECURSION_GUARD(baseStyle()->drawPrimitive(pe, opt, p, w); return)
+
+ int pseudoElement = PseudoElement_None;
+ QRenderRule rule = renderRule(w, opt);
+ QRect rect = opt->rect;
+
+ switch (pe) {
+
+ case PE_FrameStatusBar: {
+ QRenderRule subRule = renderRule(w->parentWidget(), opt, PseudoElement_Item);
+ if (subRule.hasDrawable()) {
+ subRule.drawRule(p, opt->rect);
+ return;
+ }
+ break;
+ }
+
+ case PE_IndicatorArrowDown:
+ pseudoElement = PseudoElement_DownArrow;
+ break;
+
+ case PE_IndicatorArrowUp:
+ pseudoElement = PseudoElement_UpArrow;
+ break;
+
+ case PE_IndicatorRadioButton:
+ pseudoElement = PseudoElement_ExclusiveIndicator;
+ break;
+
+ case PE_IndicatorViewItemCheck:
+ pseudoElement = PseudoElement_ViewItemIndicator;
+ break;
+
+ case PE_IndicatorCheckBox:
+ pseudoElement = PseudoElement_Indicator;
+ break;
+
+ case PE_IndicatorHeaderArrow:
+ if (const QStyleOptionHeader *hdr = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
+ pseudoElement = hdr->sortIndicator == QStyleOptionHeader::SortUp
+ ? PseudoElement_HeaderViewUpArrow
+ : PseudoElement_HeaderViewDownArrow;
+ }
+ break;
+
+ case PE_PanelButtonTool:
+ case PE_PanelButtonCommand:
+ if (qobject_cast<const QAbstractButton *>(w) && rule.hasBackground() && rule.hasNativeBorder()) {
+ //the window style will draw the borders
+ ParentStyle::drawPrimitive(pe, opt, p, w);
+ if (!rule.background()->pixmap.isNull() || rule.hasImage()) {
+ rule.drawRule(p, rule.boxRect(opt->rect, QRenderRule::Margin).adjusted(1,1,-1,-1));
+ }
+ return;
+ }
+ if (!rule.hasNativeBorder()) {
+ rule.drawRule(p, rule.boxRect(opt->rect, QRenderRule::Margin));
+ return;
+ }
+ break;
+
+ case PE_IndicatorButtonDropDown: {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_ToolButtonMenu);
+ if (!subRule.hasNativeBorder()) {
+ rule.drawBorder(p, opt->rect);
+ return;
+ }
+ break;
+ }
+
+ case PE_FrameDefaultButton:
+ if (rule.hasNativeBorder()) {
+ if (rule.baseStyleCanDraw())
+ break;
+ QWindowsStyle::drawPrimitive(pe, opt, p, w);
+ }
+ return;
+
+ case PE_FrameWindow:
+ case PE_FrameDockWidget:
+ case PE_Frame:
+ if (const QStyleOptionFrame *frm = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
+ if (rule.hasNativeBorder()) {
+ QStyleOptionFrameV2 frmOpt(*frm);
+ rule.configurePalette(&frmOpt.palette, QPalette::Text, QPalette::Base);
+ if (!qstyleoption_cast<const QStyleOptionFrameV3 *>(opt)) //if it comes from CE_ShapedFrame, the margins are already sustracted
+ frmOpt.rect = rule.borderRect(frmOpt.rect);
+ baseStyle()->drawPrimitive(pe, &frmOpt, p, w);
+ } else {
+ rule.drawBorder(p, rule.borderRect(opt->rect));
+ }
+ }
+ return;
+
+ case PE_PanelLineEdit:
+ if (const QStyleOptionFrame *frm = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
+#ifndef QT_NO_SPINBOX
+ if (w && qobject_cast<const QAbstractSpinBox *>(w->parentWidget())) {
+ QRenderRule spinboxRule = renderRule(w->parentWidget(), opt);
+ if (!spinboxRule.hasNativeBorder() || !spinboxRule.baseStyleCanDraw())
+ return;
+ rule = spinboxRule;
+ }
+#endif
+ if (rule.hasNativeBorder()) {
+ QStyleOptionFrame frmOpt(*frm);
+ rule.configurePalette(&frmOpt.palette, QPalette::Text, QPalette::Base);
+ frmOpt.rect = rule.borderRect(frmOpt.rect);
+ if (rule.baseStyleCanDraw()) {
+ rule.drawBackgroundImage(p, opt->rect);
+ baseStyle()->drawPrimitive(pe, &frmOpt, p, w);
+ } else {
+ rule.drawBackground(p, opt->rect);
+ if (frmOpt.lineWidth > 0)
+ baseStyle()->drawPrimitive(PE_FrameLineEdit, &frmOpt, p, w);
+ }
+ } else {
+ rule.drawRule(p, opt->rect);
+ }
+ }
+ return;
+
+ case PE_Widget:
+ if (w && !rule.hasDrawable()) {
+ QWidget *container = containerWidget(w);
+ if (styleSheetCaches->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)) {
+ const QAbstractScrollAreaPrivate *sap = sa->d_func();
+ rule.drawBackground(p, opt->rect, sap->contentsOffset());
+ if (rule.hasBorder()) {
+ QRect brect = rule.borderRect(opt->rect);
+ if (styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents, opt, w)) {
+ QRect r = brect.adjusted(0, 0, sa->verticalScrollBar()->isVisible() ? -sa->verticalScrollBar()->width() : 0,
+ sa->horizontalScrollBar()->isVisible() ? -sa->horizontalScrollBar()->height() : 0);
+ brect = QStyle::visualRect(opt->direction, brect, r);
+ }
+ rule.drawBorder(p, brect);
+ }
+ break;
+ }
+#endif
+ //fall tghought
+ case PE_PanelMenu:
+ case PE_PanelStatusBar:
+ if(rule.hasDrawable()) {
+ rule.drawRule(p, opt->rect);
+ return;
+ }
+ break;
+
+ case PE_FrameMenu:
+ if (rule.hasDrawable()) {
+ // Drawn by PE_PanelMenu
+ return;
+ }
+ break;
+
+ case PE_PanelMenuBar:
+ if (rule.hasDrawable()) {
+ // Drawn by PE_Widget
+ return;
+ }
+ break;
+
+ case PE_IndicatorToolBarSeparator:
+ case PE_IndicatorToolBarHandle: {
+ PseudoElement ps = pe == PE_IndicatorToolBarHandle ? PseudoElement_ToolBarHandle : PseudoElement_ToolBarSeparator;
+ QRenderRule subRule = renderRule(w, opt, ps);
+ if (subRule.hasDrawable()) {
+ subRule.drawRule(p, opt->rect);
+ return;
+ }
+ }
+ break;
+
+ case PE_IndicatorMenuCheckMark:
+ pseudoElement = PseudoElement_MenuCheckMark;
+ break;
+
+ case PE_IndicatorArrowLeft:
+ pseudoElement = PseudoElement_LeftArrow;
+ break;
+
+ case PE_IndicatorArrowRight:
+ pseudoElement = PseudoElement_RightArrow;
+ break;
+
+ case PE_IndicatorColumnViewArrow:
+ if (const QStyleOptionViewItem *viewOpt = qstyleoption_cast<const QStyleOptionViewItem *>(opt)) {
+ bool reverse = (viewOpt->direction == Qt::RightToLeft);
+ pseudoElement = reverse ? PseudoElement_LeftArrow : PseudoElement_RightArrow;
+ } else {
+ pseudoElement = PseudoElement_RightArrow;
+ }
+ break;
+
+ case PE_IndicatorBranch:
+ if (const QStyleOptionViewItemV2 *v2 = qstyleoption_cast<const QStyleOptionViewItemV2 *>(opt)) {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_TreeViewBranch);
+ if (subRule.hasDrawable()) {
+ if ((v2->state & QStyle::State_Selected) && v2->showDecorationSelected)
+ p->fillRect(v2->rect, v2->palette.highlight());
+ else if (v2->features & QStyleOptionViewItemV2::Alternate)
+ p->fillRect(v2->rect, v2->palette.alternateBase());
+ subRule.drawRule(p, opt->rect);
+ } else {
+ baseStyle()->drawPrimitive(pe, v2, p, w);
+ }
+ }
+ return;
+
+ case PE_PanelTipLabel:
+ if (!rule.hasDrawable())
+ break;
+
+ if (const QStyleOptionFrame *frmOpt = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
+ if (rule.hasNativeBorder()) {
+ rule.drawBackground(p, opt->rect);
+ QStyleOptionFrame optCopy(*frmOpt);
+ optCopy.rect = rule.borderRect(opt->rect);
+ optCopy.palette.setBrush(QPalette::Window, Qt::NoBrush); // oh dear
+ baseStyle()->drawPrimitive(pe, &optCopy, p, w);
+ } else {
+ rule.drawRule(p, opt->rect);
+ }
+ }
+ return;
+
+ case PE_FrameGroupBox:
+ if (rule.hasNativeBorder())
+ break;
+ rule.drawBorder(p, opt->rect);
+ return;
+
+#ifndef QT_NO_TABWIDGET
+ case PE_FrameTabWidget:
+ if (const QStyleOptionTabWidgetFrame *frm = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_TabWidgetPane);
+ if (subRule.hasNativeBorder()) {
+ subRule.drawBackground(p, opt->rect);
+ QStyleOptionTabWidgetFrameV2 frmCopy(*frm);
+ subRule.configurePalette(&frmCopy.palette, QPalette::WindowText, QPalette::Window);
+ baseStyle()->drawPrimitive(pe, &frmCopy, p, w);
+ } else {
+ subRule.drawRule(p, opt->rect);
+ }
+ return;
+ }
+ break;
+#endif // QT_NO_TABWIDGET
+
+ case PE_IndicatorProgressChunk:
+ pseudoElement = PseudoElement_ProgressBarChunk;
+ break;
+
+ case PE_IndicatorTabTear:
+ pseudoElement = PseudoElement_TabBarTear;
+ break;
+
+ case PE_FrameFocusRect:
+ if (!rule.hasNativeOutline()) {
+ rule.drawOutline(p, opt->rect);
+ return;
+ }
+ break;
+
+ case PE_IndicatorDockWidgetResizeHandle:
+ pseudoElement = PseudoElement_DockWidgetSeparator;
+ break;
+
+ case PE_PanelItemViewItem:
+ pseudoElement = PseudoElement_ViewItem;
+ break;
+
+ case PE_PanelScrollAreaCorner:
+ pseudoElement = PseudoElement_ScrollAreaCorner;
+ break;
+
+ case PE_IndicatorSpinDown:
+ case PE_IndicatorSpinMinus:
+ pseudoElement = PseudoElement_SpinBoxDownArrow;
+ break;
+
+ case PE_IndicatorSpinUp:
+ case PE_IndicatorSpinPlus:
+ pseudoElement = PseudoElement_SpinBoxUpArrow;
+ break;
+#ifndef QT_NO_TABBAR
+ case PE_IndicatorTabClose:
+ if (w)
+ w = w->parentWidget(); //match on the QTabBar instead of the CloseButton
+ pseudoElement = PseudoElement_TabBarTabCloseButton;
+#endif
+
+ default:
+ break;
+ }
+
+ if (pseudoElement != PseudoElement_None) {
+ QRenderRule subRule = renderRule(w, opt, pseudoElement);
+ if (subRule.hasDrawable()) {
+ subRule.drawRule(p, rect);
+ } else {
+ baseStyle()->drawPrimitive(pe, opt, p, w);
+ }
+ } else {
+ baseStyle()->drawPrimitive(pe, opt, p, w);
+ }
+}
+
+QPixmap QStyleSheetStyle::generatedIconPixmap(QIcon::Mode iconMode, const QPixmap& pixmap,
+ const QStyleOption *option) const
+{
+ return baseStyle()->generatedIconPixmap(iconMode, pixmap, option);
+}
+
+QStyle::SubControl QStyleSheetStyle::hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt,
+ const QPoint &pt, const QWidget *w) const
+{
+ RECURSION_GUARD(return baseStyle()->hitTestComplexControl(cc, opt, pt, w))
+ switch (cc) {
+ case CC_TitleBar:
+ if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) {
+ QRenderRule rule = renderRule(w, opt, PseudoElement_TitleBar);
+ if (rule.hasDrawable() || rule.hasBox() || rule.hasBorder()) {
+ QHash<QStyle::SubControl, QRect> layout = titleBarLayout(w, tb);
+ QRect r;
+ QStyle::SubControl sc = QStyle::SC_None;
+ uint ctrl = SC_TitleBarSysMenu;
+ while (ctrl <= SC_TitleBarLabel) {
+ r = layout[QStyle::SubControl(ctrl)];
+ if (r.isValid() && r.contains(pt)) {
+ sc = QStyle::SubControl(ctrl);
+ break;
+ }
+ ctrl <<= 1;
+ }
+ return sc;
+ }
+ }
+ break;
+
+ case CC_MdiControls:
+ if (hasStyleRule(w, PseudoElement_MdiCloseButton)
+ || hasStyleRule(w, PseudoElement_MdiNormalButton)
+ || hasStyleRule(w, PseudoElement_MdiMinButton))
+ return QWindowsStyle::hitTestComplexControl(cc, opt, pt, w);
+ break;
+
+ case CC_ScrollBar: {
+ QRenderRule rule = renderRule(w, opt);
+ if (!rule.hasDrawable() && !rule.hasBox())
+ break;
+ }
+ // intentionally falls through
+ case CC_SpinBox:
+ case CC_GroupBox:
+ case CC_ComboBox:
+ case CC_Slider:
+ case CC_ToolButton:
+ return QWindowsStyle::hitTestComplexControl(cc, opt, pt, w);
+ default:
+ break;
+ }
+
+ return baseStyle()->hitTestComplexControl(cc, opt, pt, w);
+}
+
+QRect QStyleSheetStyle::itemPixmapRect(const QRect &rect, int alignment, const QPixmap &pixmap) const
+{
+ return baseStyle()->itemPixmapRect(rect, alignment, pixmap);
+}
+
+QRect QStyleSheetStyle::itemTextRect(const QFontMetrics &metrics, const QRect& rect, int alignment,
+ bool enabled, const QString& text) const
+{
+ return baseStyle()->itemTextRect(metrics, rect, alignment, enabled, text);
+}
+
+int QStyleSheetStyle::pixelMetric(PixelMetric m, const QStyleOption *opt, const QWidget *w) const
+{
+ RECURSION_GUARD(return baseStyle()->pixelMetric(m, opt, w))
+
+ QRenderRule rule = renderRule(w, opt);
+ QRenderRule subRule;
+
+ switch (m) {
+ case PM_MenuButtonIndicator:
+#ifndef QT_NO_TOOLBUTTON
+ // QToolButton adds this directly to the width
+ if (qobject_cast<const QToolButton *>(w) && (rule.hasBox() || !rule.hasNativeBorder()))
+ return 0;
+#endif
+ subRule = renderRule(w, opt, PseudoElement_PushButtonMenuIndicator);
+ if (subRule.hasContentsSize())
+ return subRule.size().width();
+ break;
+
+ case PM_ButtonShiftHorizontal:
+ case PM_ButtonShiftVertical:
+ case PM_ButtonMargin:
+ case PM_ButtonDefaultIndicator:
+ if (rule.hasBox())
+ return 0;
+ break;
+
+ case PM_DefaultFrameWidth:
+ if (!rule.hasNativeBorder())
+ return rule.border()->borders[LeftEdge];
+ break;
+
+ case PM_ExclusiveIndicatorWidth:
+ case PM_IndicatorWidth:
+ case PM_ExclusiveIndicatorHeight:
+ case PM_IndicatorHeight:
+ subRule = renderRule(w, opt, PseudoElement_Indicator);
+ if (subRule.hasContentsSize()) {
+ return (m == PM_ExclusiveIndicatorWidth) || (m == PM_IndicatorWidth)
+ ? subRule.size().width() : subRule.size().height();
+ }
+ break;
+
+ case PM_DockWidgetFrameWidth:
+ case PM_ToolTipLabelFrameWidth: // border + margin + padding (support only one width)
+ if (!rule.hasDrawable())
+ break;
+
+ return (rule.border() ? rule.border()->borders[LeftEdge] : 0)
+ + (rule.hasBox() ? rule.box()->margins[LeftEdge] + rule.box()->paddings[LeftEdge]: 0);
+
+ case PM_ToolBarFrameWidth:
+ if (rule.hasBorder() || rule.hasBox())
+ return (rule.border() ? rule.border()->borders[LeftEdge] : 0)
+ + (rule.hasBox() ? rule.box()->paddings[LeftEdge]: 0);
+ break;
+
+ case PM_MenuPanelWidth:
+ case PM_MenuBarPanelWidth:
+ if (rule.hasBorder() || rule.hasBox())
+ return (rule.border() ? rule.border()->borders[LeftEdge] : 0)
+ + (rule.hasBox() ? rule.box()->margins[LeftEdge]: 0);
+ break;
+
+
+ case PM_MenuHMargin:
+ case PM_MenuBarHMargin:
+ if (rule.hasBox())
+ return rule.box()->paddings[LeftEdge];
+ break;
+
+ case PM_MenuVMargin:
+ case PM_MenuBarVMargin:
+ if (rule.hasBox())
+ return rule.box()->paddings[TopEdge];
+ break;
+
+ case PM_DockWidgetTitleBarButtonMargin:
+ case PM_ToolBarItemMargin:
+ if (rule.hasBox())
+ return rule.box()->margins[TopEdge];
+ break;
+
+ case PM_ToolBarItemSpacing:
+ case PM_MenuBarItemSpacing:
+ if (rule.hasBox() && rule.box()->spacing != -1)
+ return rule.box()->spacing;
+ break;
+
+ case PM_MenuTearoffHeight:
+ case PM_MenuScrollerHeight: {
+ PseudoElement ps = m == PM_MenuTearoffHeight ? PseudoElement_MenuTearoff : PseudoElement_MenuScroller;
+ subRule = renderRule(w, opt, ps);
+ if (subRule.hasContentsSize())
+ return subRule.size().height();
+ break;
+ }
+
+ case PM_ToolBarExtensionExtent:
+ break;
+
+ case PM_SplitterWidth:
+ case PM_ToolBarSeparatorExtent:
+ case PM_ToolBarHandleExtent: {
+ PseudoElement ps;
+ if (m == PM_ToolBarHandleExtent) ps = PseudoElement_ToolBarHandle;
+ else if (m == PM_SplitterWidth) ps = PseudoElement_SplitterHandle;
+ else ps = PseudoElement_ToolBarSeparator;
+ subRule = renderRule(w, opt, ps);
+ if (subRule.hasContentsSize()) {
+ QSize sz = subRule.size();
+ return (opt && opt->state & QStyle::State_Horizontal) ? sz.width() : sz.height();
+ }
+ break;
+ }
+
+ case PM_RadioButtonLabelSpacing:
+ if (rule.hasBox() && rule.box()->spacing != -1)
+ return rule.box()->spacing;
+ break;
+ case PM_CheckBoxLabelSpacing:
+ if (qobject_cast<const QCheckBox *>(w)) {
+ if (rule.hasBox() && rule.box()->spacing != -1)
+ return rule.box()->spacing;
+ }
+ // assume group box
+ subRule = renderRule(w, opt, PseudoElement_GroupBoxTitle);
+ if (subRule.hasBox() && subRule.box()->spacing != -1)
+ return subRule.box()->spacing;
+ break;
+
+#ifndef QT_NO_SCROLLBAR
+ case PM_ScrollBarExtent:
+ if (rule.hasContentsSize()) {
+ QSize sz = rule.size();
+ if (const QStyleOptionSlider *sb = qstyleoption_cast<const QStyleOptionSlider *>(opt))
+ return sb->orientation == Qt::Horizontal ? sz.height() : sz.width();
+ return sz.width() == -1 ? sz.height() : sz.width();
+ }
+ break;
+
+ case PM_ScrollBarSliderMin:
+ if (hasStyleRule(w, PseudoElement_ScrollBarSlider)) {
+ subRule = renderRule(w, opt, PseudoElement_ScrollBarSlider);
+ QSize msz = subRule.minimumSize();
+ if (const QStyleOptionSlider *sb = qstyleoption_cast<const QStyleOptionSlider *>(opt))
+ return sb->orientation == Qt::Horizontal ? msz.width() : msz.height();
+ return msz.width() == -1 ? msz.height() : msz.width();
+ }
+ break;
+
+ case PM_ScrollView_ScrollBarSpacing:
+ if(!rule.hasNativeBorder() || rule.hasBox())
+ return 0;
+ break;
+#endif // QT_NO_SCROLLBAR
+
+ case PM_ProgressBarChunkWidth:
+ subRule = renderRule(w, opt, PseudoElement_ProgressBarChunk);
+ if (subRule.hasContentsSize()) {
+ QSize sz = subRule.size();
+ return (opt->state & QStyle::State_Horizontal)
+ ? sz.width() : sz.height();
+ }
+ break;
+
+#ifndef QT_NO_TABWIDGET
+ case PM_TabBarTabHSpace:
+ case PM_TabBarTabVSpace:
+ subRule = renderRule(w, opt, PseudoElement_TabBarTab);
+ if (subRule.hasBox() || subRule.hasBorder())
+ return 0;
+ break;
+
+ case PM_TabBarScrollButtonWidth: {
+ subRule = renderRule(w, opt, PseudoElement_TabBarScroller);
+ if (subRule.hasContentsSize()) {
+ QSize sz = subRule.size();
+ return sz.width() != -1 ? sz.width() : sz.height();
+ }
+ }
+ break;
+
+ case PM_TabBarTabShiftHorizontal:
+ case PM_TabBarTabShiftVertical:
+ subRule = renderRule(w, opt, PseudoElement_TabBarTab);
+ if (subRule.hasBox())
+ return 0;
+ break;
+
+ case PM_TabBarBaseOverlap: {
+ const QWidget *tabWidget = qobject_cast<const QTabWidget *>(w) ? w : w->parentWidget();
+ if (hasStyleRule(tabWidget, PseudoElement_TabWidgetPane)) {
+ return 0;
+ }
+ break;
+ }
+#endif // QT_NO_TABWIDGET
+
+ case PM_SliderThickness: // horizontal slider's height (sizeHint)
+ case PM_SliderLength: // minimum length of slider
+ if (rule.hasContentsSize()) {
+ bool horizontal = opt->state & QStyle::State_Horizontal;
+ if (m == PM_SliderThickness) {
+ QSize sz = rule.size();
+ return horizontal ? sz.height() : sz.width();
+ } else {
+ QSize msz = rule.minimumContentsSize();
+ return horizontal ? msz.width() : msz.height();
+ }
+ }
+ break;
+
+ case PM_SliderControlThickness: {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_SliderHandle);
+ if (!subRule.hasContentsSize())
+ break;
+ QSize size = subRule.size();
+ return (opt->state & QStyle::State_Horizontal) ? size.height() : size.width();
+ }
+
+ case PM_ToolBarIconSize:
+ case PM_ListViewIconSize:
+ case PM_IconViewIconSize:
+ case PM_TabBarIconSize:
+ case PM_MessageBoxIconSize:
+ case PM_ButtonIconSize:
+ case PM_SmallIconSize:
+ if (rule.hasStyleHint(QLatin1String("icon-size"))) {
+ return rule.styleHint(QLatin1String("icon-size")).toSize().width();
+ }
+ break;
+
+ case PM_DockWidgetTitleMargin: {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_DockWidgetTitle);
+ if (!subRule.hasBox())
+ break;
+ return (subRule.border() ? subRule.border()->borders[TopEdge] : 0)
+ + (subRule.hasBox() ? subRule.box()->margins[TopEdge] + subRule.box()->paddings[TopEdge]: 0);
+ }
+
+ case PM_DockWidgetSeparatorExtent: {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_DockWidgetSeparator);
+ if (!subRule.hasContentsSize())
+ break;
+ QSize sz = subRule.size();
+ return qMax(sz.width(), sz.height());
+ }
+
+ case PM_TitleBarHeight: {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_TitleBar);
+ if (subRule.hasContentsSize())
+ return subRule.size().height();
+ else if (subRule.hasBox() || subRule.hasBorder()) {
+ QFontMetrics fm = opt ? opt->fontMetrics : w->fontMetrics();
+ return subRule.size(QSize(0, fm.height())).height();
+ }
+ break;
+ }
+
+ case PM_MdiSubWindowFrameWidth:
+ if (rule.hasBox() || rule.hasBorder()) {
+ return (rule.border() ? rule.border()->borders[LeftEdge] : 0)
+ + (rule.hasBox() ? rule.box()->paddings[LeftEdge]+rule.box()->margins[LeftEdge]: 0);
+ }
+ break;
+
+ case PM_MdiSubWindowMinimizedWidth: {
+ QRenderRule subRule = renderRule(w, PseudoElement_None, PseudoClass_Minimized);
+ int width = subRule.size().width();
+ if (width != -1)
+ return width;
+ break;
+ }
+ default:
+ break;
+ }
+
+ return baseStyle()->pixelMetric(m, opt, w);
+}
+
+QSize QStyleSheetStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt,
+ const QSize &csz, const QWidget *w) const
+{
+ RECURSION_GUARD(return baseStyle()->sizeFromContents(ct, opt, csz, w))
+
+ QRenderRule rule = renderRule(w, opt);
+ QSize sz = rule.adjustSize(csz);
+
+ switch (ct) {
+ case CT_SpinBox: // ### hopelessly broken QAbstractSpinBox (part 1)
+ if (rule.hasBox() || !rule.hasNativeBorder())
+ return csz;
+ return rule.baseStyleCanDraw() ? baseStyle()->sizeFromContents(ct, opt, sz, w)
+ : QWindowsStyle::sizeFromContents(ct, opt, sz, w);
+ case CT_ToolButton:
+ if (rule.hasBox() || !rule.hasNativeBorder() || !rule.baseStyleCanDraw())
+ sz += QSize(3, 3); // ### broken QToolButton
+ //fall thought
+ case CT_ComboBox:
+ case CT_PushButton:
+ if (rule.hasBox() || !rule.hasNativeBorder()) {
+ if(ct == CT_ComboBox) {
+ //add some space for the drop down.
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_ComboBoxDropDown);
+ QRect comboRect = positionRect(w, rule, subRule, PseudoElement_ComboBoxDropDown, opt->rect, opt->direction);
+ //+2 because there is hardcoded margins in QCommonStyle::drawControl(CE_ComboBoxLabel)
+ sz += QSize(comboRect.width() + 2, 0);
+ }
+ return rule.boxSize(sz);
+ }
+ sz = rule.baseStyleCanDraw() ? baseStyle()->sizeFromContents(ct, opt, sz, w)
+ : QWindowsStyle::sizeFromContents(ct, opt, sz, w);
+ return rule.boxSize(sz, Margin);
+
+ case CT_HeaderSection: {
+ if (const QStyleOptionHeader *hdr = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_HeaderViewSection);
+ if (subRule.hasGeometry() || subRule.hasBox() || !subRule.hasNativeBorder()) {
+ sz = subRule.adjustSize(csz);
+ if (!subRule.hasGeometry()) {
+ QSize nativeContentsSize;
+ bool nullIcon = hdr->icon.isNull();
+ int iconSize = nullIcon ? 0 : pixelMetric(QStyle::PM_SmallIconSize, hdr, w);
+ QSize txt = hdr->fontMetrics.size(0, hdr->text);
+ nativeContentsSize.setHeight(qMax(iconSize, txt.height()));
+ nativeContentsSize.setWidth(iconSize + txt.width());
+ sz = sz.expandedTo(nativeContentsSize);
+ }
+ return subRule.size(sz);
+ }
+ return subRule.baseStyleCanDraw() ? baseStyle()->sizeFromContents(ct, opt, sz, w)
+ : QWindowsStyle::sizeFromContents(ct, opt, sz, w);
+ }
+ }
+ break;
+ case CT_GroupBox:
+ case CT_LineEdit:
+#ifndef QT_NO_SPINBOX
+ // ### hopelessly broken QAbstractSpinBox (part 2)
+ if (QAbstractSpinBox *spinBox = qobject_cast<QAbstractSpinBox *>(w ? w->parentWidget() : 0)) {
+ QRenderRule rule = renderRule(spinBox, opt);
+ if (rule.hasBox() || !rule.hasNativeBorder())
+ return csz;
+ return rule.baseStyleCanDraw() ? baseStyle()->sizeFromContents(ct, opt, sz, w)
+ : QWindowsStyle::sizeFromContents(ct, opt, sz, w);
+ }
+#endif
+ if (rule.hasBox() || !rule.hasNativeBorder()) {
+ return rule.boxSize(sz);
+ }
+ break;
+
+ case CT_CheckBox:
+ case CT_RadioButton:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
+ if (rule.hasBox() || rule.hasBorder() || hasStyleRule(w, PseudoElement_Indicator)) {
+ bool isRadio = (ct == CT_RadioButton);
+ int iw = pixelMetric(isRadio ? PM_ExclusiveIndicatorWidth
+ : PM_IndicatorWidth, btn, w);
+ int ih = pixelMetric(isRadio ? PM_ExclusiveIndicatorHeight
+ : PM_IndicatorHeight, btn, w);
+
+ int spacing = pixelMetric(isRadio ? PM_RadioButtonLabelSpacing
+ : PM_CheckBoxLabelSpacing, btn, w);
+ sz.setWidth(sz.width() + iw + spacing);
+ sz.setHeight(qMax(sz.height(), ih));
+ return rule.boxSize(sz);
+ }
+ }
+ break;
+
+ case CT_Menu:
+ case CT_MenuBar: // already has everything!
+ case CT_ScrollBar:
+ if (rule.hasBox() || rule.hasBorder())
+ return sz;
+ break;
+
+ case CT_MenuItem:
+ if (const QStyleOptionMenuItem *mi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
+ PseudoElement pe = (mi->menuItemType == QStyleOptionMenuItem::Separator)
+ ? PseudoElement_MenuSeparator : PseudoElement_Item;
+ QRenderRule subRule = renderRule(w, opt, pe);
+ if ((pe == PseudoElement_MenuSeparator) && subRule.hasContentsSize()) {
+ return QSize(sz.width(), subRule.size().height());
+ } else if ((pe == PseudoElement_Item) && (subRule.hasBox() || subRule.hasBorder())) {
+ int width = csz.width();
+ if (mi->text.contains(QLatin1Char('\t')))
+ width += 12; //as in QCommonStyle
+ return subRule.boxSize(subRule.adjustSize(QSize(width, csz.height())));
+ }
+ }
+ break;
+
+ case CT_Splitter:
+ case CT_MenuBarItem: {
+ PseudoElement pe = (ct == CT_Splitter) ? PseudoElement_SplitterHandle : PseudoElement_Item;
+ QRenderRule subRule = renderRule(w, opt, pe);
+ if (subRule.hasBox() || subRule.hasBorder())
+ return subRule.boxSize(sz);
+ break;
+ }
+
+ case CT_ProgressBar:
+ case CT_SizeGrip:
+ return (rule.hasContentsSize())
+ ? rule.size(sz)
+ : rule.boxSize(baseStyle()->sizeFromContents(ct, opt, sz, w));
+ break;
+
+ case CT_Slider:
+ if (rule.hasBorder() || rule.hasBox() || rule.hasGeometry())
+ return rule.boxSize(sz);
+ break;
+
+#ifndef QT_NO_TABBAR
+ case CT_TabBarTab: {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_TabBarTab);
+ if (subRule.hasBox() || !subRule.hasNativeBorder()) {
+ int spaceForIcon = 0;
+ bool vertical = false;
+ if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
+ if (!tab->icon.isNull())
+ spaceForIcon = 6 /* icon offset */ + 4 /* spacing */ + 2 /* magic */; // ###: hardcoded to match with common style
+ vertical = verticalTabs(tab->shape);
+ }
+ sz = csz + QSize(vertical ? 0 : spaceForIcon, vertical ? spaceForIcon : 0);
+ return subRule.boxSize(subRule.adjustSize(sz));
+ }
+#ifdef Q_WS_MAC
+ if (baseStyle()->inherits("QMacStyle")) {
+ //adjust the size after the call to the style because the mac style ignore the size arguments anyway.
+ //this might cause the (max-){width,height} property to include the native style border while they should not.
+ return subRule.adjustSize(baseStyle()->sizeFromContents(ct, opt, csz, w));
+ }
+#endif
+ sz = subRule.adjustSize(csz);
+ break;
+ }
+#endif // QT_NO_TABBAR
+
+ case CT_MdiControls:
+ if (const QStyleOptionComplex *ccOpt = qstyleoption_cast<const QStyleOptionComplex *>(opt)) {
+ if (!hasStyleRule(w, PseudoElement_MdiCloseButton)
+ && !hasStyleRule(w, PseudoElement_MdiNormalButton)
+ && !hasStyleRule(w, PseudoElement_MdiMinButton))
+ break;
+
+ QList<QVariant> layout = rule.styleHint(QLatin1String("button-layout")).toList();
+ if (layout.isEmpty())
+ layout = subControlLayout(QLatin1String("mNX"));
+
+ int width = 0, height = 0;
+ for (int i = 0; i < layout.count(); i++) {
+ int layoutButton = layout[i].toInt();
+ if (layoutButton < PseudoElement_MdiCloseButton
+ || layoutButton > PseudoElement_MdiNormalButton)
+ continue;
+ QStyle::SubControl sc = knownPseudoElements[layoutButton].subControl;
+ if (!(ccOpt->subControls & sc))
+ continue;
+ QRenderRule subRule = renderRule(w, opt, layoutButton);
+ QSize sz = subRule.size();
+ width += sz.width();
+ height = qMax(height, sz.height());
+ }
+
+ return QSize(width, height);
+ }
+ break;
+
+#ifndef QT_NO_ITEMVIEWS
+ case CT_ItemViewItem: {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_ViewItem);
+ sz = baseStyle()->sizeFromContents(ct, opt, csz, w);
+ sz = subRule.adjustSize(sz);
+ if (subRule.hasBox() || subRule.hasBorder())
+ sz = subRule.boxSize(sz);
+ return sz;
+ }
+#endif // QT_NO_ITEMVIEWS
+
+ default:
+ break;
+ }
+
+ return baseStyle()->sizeFromContents(ct, opt, sz, w);
+}
+
+/*!
+ \internal
+*/
+static QLatin1String propertyNameForStandardPixmap(QStyle::StandardPixmap sp)
+{
+ switch (sp) {
+ case QStyle::SP_TitleBarMenuButton: return QLatin1String("titlebar-menu-icon");
+ case QStyle::SP_TitleBarMinButton: return QLatin1String("titlebar-minimize-icon");
+ case QStyle::SP_TitleBarMaxButton: return QLatin1String("titlebar-maximize-icon");
+ case QStyle::SP_TitleBarCloseButton: return QLatin1String("titlebar-close-icon");
+ case QStyle::SP_TitleBarNormalButton: return QLatin1String("titlebar-normal-icon");
+ case QStyle::SP_TitleBarShadeButton: return QLatin1String("titlebar-shade-icon");
+ case QStyle::SP_TitleBarUnshadeButton: return QLatin1String("titlebar-unshade-icon");
+ case QStyle::SP_TitleBarContextHelpButton: return QLatin1String("titlebar-contexthelp-icon");
+ case QStyle::SP_DockWidgetCloseButton: return QLatin1String("dockwidget-close-icon");
+ case QStyle::SP_MessageBoxInformation: return QLatin1String("messagebox-information-icon");
+ case QStyle::SP_MessageBoxWarning: return QLatin1String("messagebox-warning-icon");
+ case QStyle::SP_MessageBoxCritical: return QLatin1String("messagebox-critical-icon");
+ case QStyle::SP_MessageBoxQuestion: return QLatin1String("messagebox-question-icon");
+ case QStyle::SP_DesktopIcon: return QLatin1String("desktop-icon");
+ case QStyle::SP_TrashIcon: return QLatin1String("trash-icon");
+ case QStyle::SP_ComputerIcon: return QLatin1String("computer-icon");
+ case QStyle::SP_DriveFDIcon: return QLatin1String("floppy-icon");
+ case QStyle::SP_DriveHDIcon: return QLatin1String("harddisk-icon");
+ case QStyle::SP_DriveCDIcon: return QLatin1String("cd-icon");
+ case QStyle::SP_DriveDVDIcon: return QLatin1String("dvd-icon");
+ case QStyle::SP_DriveNetIcon: return QLatin1String("network-icon");
+ case QStyle::SP_DirOpenIcon: return QLatin1String("directory-open-icon");
+ case QStyle::SP_DirClosedIcon: return QLatin1String("directory-closed-icon");
+ case QStyle::SP_DirLinkIcon: return QLatin1String("directory-link-icon");
+ case QStyle::SP_FileIcon: return QLatin1String("file-icon");
+ case QStyle::SP_FileLinkIcon: return QLatin1String("file-link-icon");
+ case QStyle::SP_FileDialogStart: return QLatin1String("filedialog-start-icon");
+ case QStyle::SP_FileDialogEnd: return QLatin1String("filedialog-end-icon");
+ case QStyle::SP_FileDialogToParent: return QLatin1String("filedialog-parent-directory-icon");
+ case QStyle::SP_FileDialogNewFolder: return QLatin1String("filedialog-new-directory-icon");
+ case QStyle::SP_FileDialogDetailedView: return QLatin1String("filedialog-detailedview-icon");
+ case QStyle::SP_FileDialogInfoView: return QLatin1String("filedialog-infoview-icon");
+ case QStyle::SP_FileDialogContentsView: return QLatin1String("filedialog-contentsview-icon");
+ case QStyle::SP_FileDialogListView: return QLatin1String("filedialog-listview-icon");
+ case QStyle::SP_FileDialogBack: return QLatin1String("filedialog-backward-icon");
+ case QStyle::SP_DirIcon: return QLatin1String("directory-icon");
+ case QStyle::SP_DialogOkButton: return QLatin1String("dialog-ok-icon");
+ case QStyle::SP_DialogCancelButton: return QLatin1String("dialog-cancel-icon");
+ case QStyle::SP_DialogHelpButton: return QLatin1String("dialog-help-icon");
+ case QStyle::SP_DialogOpenButton: return QLatin1String("dialog-open-icon");
+ case QStyle::SP_DialogSaveButton: return QLatin1String("dialog-save-icon");
+ case QStyle::SP_DialogCloseButton: return QLatin1String("dialog-close-icon");
+ case QStyle::SP_DialogApplyButton: return QLatin1String("dialog-apply-icon");
+ case QStyle::SP_DialogResetButton: return QLatin1String("dialog-reset-icon");
+ case QStyle::SP_DialogDiscardButton: return QLatin1String("discard-icon");
+ case QStyle::SP_DialogYesButton: return QLatin1String("dialog-yes-icon");
+ case QStyle::SP_DialogNoButton: return QLatin1String("dialog-no-icon");
+ case QStyle::SP_ArrowUp: return QLatin1String("uparrow-icon");
+ case QStyle::SP_ArrowDown: return QLatin1String("downarrow-icon");
+ case QStyle::SP_ArrowLeft: return QLatin1String("leftarrow-icon");
+ case QStyle::SP_ArrowRight: return QLatin1String("rightarrow-icon");
+ case QStyle::SP_ArrowBack: return QLatin1String("backward-icon");
+ case QStyle::SP_ArrowForward: return QLatin1String("forward-icon");
+ case QStyle::SP_DirHomeIcon: return QLatin1String("home-icon");
+ default: return QLatin1String("");
+ }
+}
+
+QIcon QStyleSheetStyle::standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *opt,
+ const QWidget *w) const
+{
+ RECURSION_GUARD(return baseStyle()->standardIcon(standardIcon, opt, w))
+ QString s = propertyNameForStandardPixmap(standardIcon);
+ if (!s.isEmpty()) {
+ QRenderRule rule = renderRule(w, opt);
+ if (rule.hasStyleHint(s))
+ return qvariant_cast<QIcon>(rule.styleHint(s));
+ }
+ return baseStyle()->standardIcon(standardIcon, opt, w);
+}
+
+QPalette QStyleSheetStyle::standardPalette() const
+{
+ return baseStyle()->standardPalette();
+}
+
+QPixmap QStyleSheetStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt,
+ const QWidget *w) const
+{
+ RECURSION_GUARD(return baseStyle()->standardPixmap(standardPixmap, opt, w))
+ QString s = propertyNameForStandardPixmap(standardPixmap);
+ if (!s.isEmpty()) {
+ QRenderRule rule = renderRule(w, opt);
+ if (rule.hasStyleHint(s)) {
+ QIcon icon = qvariant_cast<QIcon>(rule.styleHint(s));
+ return icon.pixmap(16, 16); // ###: unhard-code this if someone complains
+ }
+ }
+ return baseStyle()->standardPixmap(standardPixmap, opt, w);
+}
+
+int QStyleSheetStyle::layoutSpacing(QSizePolicy::ControlType control1, QSizePolicy::ControlType control2,
+ Qt::Orientation orientation, const QStyleOption *option,
+ const QWidget *widget) const
+{
+ return baseStyle()->layoutSpacing(control1, control2, orientation, option, widget);
+}
+
+int QStyleSheetStyle::layoutSpacingImplementation(QSizePolicy::ControlType control1 ,
+ QSizePolicy::ControlType control2,
+ Qt::Orientation orientation,
+ const QStyleOption * option ,
+ const QWidget * widget) const
+{
+ return baseStyle()->layoutSpacing(control1, control2, orientation, option, widget);
+}
+
+int QStyleSheetStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *w,
+ QStyleHintReturn *shret) const
+{
+ RECURSION_GUARD(return baseStyle()->styleHint(sh, opt, w, shret))
+ // Prevent endless loop if somebody use isActiveWindow property as selector.
+ // QWidget::isActiveWindow uses this styleHint to determine if the window is active or not
+ if (sh == SH_Widget_ShareActivation)
+ return baseStyle()->styleHint(sh, opt, w, shret);
+
+ QRenderRule rule = renderRule(w, opt);
+ QString s;
+ switch (sh) {
+ case SH_LineEdit_PasswordCharacter: s = QLatin1String("lineedit-password-character"); break;
+ case SH_DitherDisabledText: s = QLatin1String("dither-disabled-text"); break;
+ case SH_EtchDisabledText: s = QLatin1String("etch-disabled-text"); break;
+ case SH_ItemView_ActivateItemOnSingleClick: s = QLatin1String("activate-on-singleclick"); break;
+ case SH_ItemView_ShowDecorationSelected: s = QLatin1String("show-decoration-selected"); break;
+ case SH_Table_GridLineColor: s = QLatin1String("gridline-color"); break;
+ case SH_DialogButtonLayout: s = QLatin1String("button-layout"); break;
+ case SH_ToolTipLabel_Opacity: s = QLatin1String("opacity"); break;
+ case SH_ComboBox_Popup: s = QLatin1String("combobox-popup"); break;
+ case SH_ComboBox_ListMouseTracking: s = QLatin1String("combobox-list-mousetracking"); break;
+ case SH_MenuBar_AltKeyNavigation: s = QLatin1String("menubar-altkey-navigation"); break;
+ case SH_Menu_Scrollable: s = QLatin1String("menu-scrollable"); break;
+ case SH_DrawMenuBarSeparator: s = QLatin1String("menubar-separator"); break;
+ case SH_MenuBar_MouseTracking: s = QLatin1String("mouse-tracking"); break;
+ case SH_SpinBox_ClickAutoRepeatRate: s = QLatin1String("spinbox-click-autorepeat-rate"); break;
+ case SH_SpinControls_DisableOnBounds: s = QLatin1String("spincontrol-disable-on-bounds"); break;
+ case SH_MessageBox_TextInteractionFlags: s = QLatin1String("messagebox-text-interaction-flags"); break;
+ case SH_ToolButton_PopupDelay: s = QLatin1String("toolbutton-popup-delay"); break;
+ case SH_ToolBox_SelectedPageTitleBold:
+ if (renderRule(w, opt, PseudoElement_ToolBoxTab).hasFont)
+ return 0;
+ break;
+ case SH_GroupBox_TextLabelColor:
+ if (rule.hasPalette() && rule.palette()->foreground.style() != Qt::NoBrush)
+ return rule.palette()->foreground.color().rgba();
+ break;
+ case SH_ScrollView_FrameOnlyAroundContents: s = QLatin1String("scrollview-frame-around-contents"); break;
+ case SH_ScrollBar_ContextMenu: s = QLatin1String("scrollbar-contextmenu"); break;
+ case SH_ScrollBar_LeftClickAbsolutePosition: s = QLatin1String("scrollbar-leftclick-absolute-position"); break;
+ case SH_ScrollBar_MiddleClickAbsolutePosition: s = QLatin1String("scrollbar-middleclick-absolute-position"); break;
+ case SH_ScrollBar_RollBetweenButtons: s = QLatin1String("scrollbar-roll-between-buttons"); break;
+ case SH_ScrollBar_ScrollWhenPointerLeavesControl: s = QLatin1String("scrollbar-scroll-when-pointer-leaves-control"); break;
+ case SH_TabBar_Alignment:
+#ifndef QT_NO_TABWIDGET
+ if (qobject_cast<const QTabWidget *>(w)) {
+ rule = renderRule(w, opt, PseudoElement_TabWidgetTabBar);
+ if (rule.hasPosition())
+ return rule.position()->position;
+ }
+#endif // QT_NO_TABWIDGET
+ s = QLatin1String("alignment");
+ break;
+#ifndef QT_NO_TABBAR
+ case SH_TabBar_CloseButtonPosition:
+ rule = renderRule(w, opt, PseudoElement_TabBarTabCloseButton);
+ if (rule.hasPosition()) {
+ Qt::Alignment align = rule.position()->position;
+ if (align & Qt::AlignLeft || align & Qt::AlignTop)
+ return QTabBar::LeftSide;
+ if (align & Qt::AlignRight || align & Qt::AlignBottom)
+ return QTabBar::RightSide;
+ }
+ break;
+#endif
+ case SH_TabBar_ElideMode: s = QLatin1String("tabbar-elide-mode"); break;
+ case SH_TabBar_PreferNoArrows: s = QLatin1String("tabbar-prefer-no-arrows"); break;
+ case SH_ComboBox_PopupFrameStyle:
+#ifndef QT_NO_COMBOBOX
+ if (qobject_cast<const QComboBox *>(w)) {
+ QAbstractItemView *view = w->findChild<QAbstractItemView *>();
+ if (view) {
+ view->ensurePolished();
+ QRenderRule subRule = renderRule(view, PseudoElement_None);
+ if (subRule.hasBox() || !subRule.hasNativeBorder())
+ return QFrame::NoFrame;
+ }
+ }
+#endif // QT_NO_COMBOBOX
+ break;
+ case SH_DialogButtonBox_ButtonsHaveIcons: s = QLatin1String("dialogbuttonbox-buttons-have-icons"); break;
+ case SH_Workspace_FillSpaceOnMaximize: s = QLatin1String("mdi-fill-space-on-maximize"); break;
+ case SH_TitleBar_NoBorder:
+ if (rule.hasBorder())
+ return !rule.border()->borders[LeftEdge];
+ break;
+ case SH_TitleBar_AutoRaise: { // plain absurd
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_TitleBar);
+ if (subRule.hasDrawable())
+ return 1;
+ break;
+ }
+ case SH_ItemView_ArrowKeysNavigateIntoChildren: s = QLatin1String("arrow-keys-navigate-into-children"); break;
+ case SH_ItemView_PaintAlternatingRowColorsForEmptyArea: s = QLatin1String("paint-alternating-row-colors-for-empty-area"); break;
+ default: break;
+ }
+ if (!s.isEmpty() && rule.hasStyleHint(s)) {
+ return rule.styleHint(s).toInt();
+ }
+
+ return baseStyle()->styleHint(sh, opt, w, shret);
+}
+
+QRect QStyleSheetStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc,
+ const QWidget *w) const
+{
+ RECURSION_GUARD(return baseStyle()->subControlRect(cc, opt, sc, w))
+
+ QRenderRule rule = renderRule(w, opt);
+ switch (cc) {
+ case CC_ComboBox:
+ if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
+ if (rule.hasBox() || !rule.hasNativeBorder()) {
+ switch (sc) {
+ case SC_ComboBoxFrame: return rule.borderRect(opt->rect);
+ case SC_ComboBoxEditField:
+ {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_ComboBoxDropDown);
+ QRect r = rule.contentsRect(opt->rect);
+ QRect r2 = positionRect(w, rule, subRule, PseudoElement_ComboBoxDropDown,
+ opt->rect, opt->direction);
+ if (subRule.hasPosition() && subRule.position()->position & Qt::AlignLeft) {
+ return visualRect(opt->direction, r, r.adjusted(r2.width(),0,0,0));
+ } else {
+ return visualRect(opt->direction, r, r.adjusted(0,0,-r2.width(),0));
+ }
+ }
+ case SC_ComboBoxArrow: {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_ComboBoxDropDown);
+ return positionRect(w, rule, subRule, PseudoElement_ComboBoxDropDown, opt->rect, opt->direction);
+ }
+ case SC_ComboBoxListBoxPopup:
+ default:
+ return baseStyle()->subControlRect(cc, opt, sc, w);
+ }
+ }
+
+ QStyleOptionComboBox comboBox(*cb);
+ comboBox.rect = rule.borderRect(opt->rect);
+ return rule.baseStyleCanDraw() ? baseStyle()->subControlRect(cc, &comboBox, sc, w)
+ : QWindowsStyle::subControlRect(cc, &comboBox, sc, w);
+ }
+ break;
+
+#ifndef QT_NO_SPINBOX
+ case CC_SpinBox:
+ if (const QStyleOptionSpinBox *spin = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
+ QRenderRule upRule = renderRule(w, opt, PseudoElement_SpinBoxUpButton);
+ QRenderRule downRule = renderRule(w, opt, PseudoElement_SpinBoxDownButton);
+ bool ruleMatch = rule.hasBox() || !rule.hasNativeBorder();
+ bool upRuleMatch = upRule.hasGeometry() || upRule.hasPosition();
+ bool downRuleMatch = downRule.hasGeometry() || upRule.hasPosition();
+ if (ruleMatch || upRuleMatch || downRuleMatch) {
+ switch (sc) {
+ case SC_SpinBoxFrame:
+ return rule.borderRect(opt->rect);
+ case SC_SpinBoxEditField:
+ {
+ QRect r = rule.contentsRect(opt->rect);
+ // Use the widest button on each side to determine edit field size.
+ Qt::Alignment upAlign, downAlign;
+
+ upAlign = upRule.hasPosition() ? upRule.position()->position
+ : Qt::Alignment(Qt::AlignRight);
+ upAlign = resolveAlignment(opt->direction, upAlign);
+
+ downAlign = downRule.hasPosition() ? downRule.position()->position
+ : Qt::Alignment(Qt::AlignRight);
+ downAlign = resolveAlignment(opt->direction, downAlign);
+
+ int upSize = subControlRect(CC_SpinBox, opt, SC_SpinBoxUp, w).width();
+ int downSize = subControlRect(CC_SpinBox, opt, SC_SpinBoxDown, w).width();
+ int widestL = qMax((upAlign & Qt::AlignLeft) ? upSize : 0,
+ (downAlign & Qt::AlignLeft) ? downSize : 0);
+ int widestR = qMax((upAlign & Qt::AlignRight) ? upSize : 0,
+ (downAlign & Qt::AlignRight) ? downSize : 0);
+ r.setRight(r.right() - widestR);
+ r.setLeft(r.left() + widestL);
+ return r;
+ }
+ case SC_SpinBoxDown:
+ if (downRuleMatch)
+ return positionRect(w, rule, downRule, PseudoElement_SpinBoxDownButton,
+ opt->rect, opt->direction);
+ break;
+ case SC_SpinBoxUp:
+ if (upRuleMatch)
+ return positionRect(w, rule, upRule, PseudoElement_SpinBoxUpButton,
+ opt->rect, opt->direction);
+ break;
+ default:
+ break;
+ }
+
+ return baseStyle()->subControlRect(cc, opt, sc, w);
+ }
+
+ QStyleOptionSpinBox spinBox(*spin);
+ spinBox.rect = rule.borderRect(opt->rect);
+ return rule.baseStyleCanDraw() ? baseStyle()->subControlRect(cc, &spinBox, sc, w)
+ : QWindowsStyle::subControlRect(cc, &spinBox, sc, w);
+ }
+ break;
+#endif // QT_NO_SPINBOX
+
+ case CC_GroupBox:
+ if (const QStyleOptionGroupBox *gb = qstyleoption_cast<const QStyleOptionGroupBox *>(opt)) {
+ switch (sc) {
+ case SC_GroupBoxFrame:
+ case SC_GroupBoxContents: {
+ if (rule.hasBox() || !rule.hasNativeBorder()) {
+ return sc == SC_GroupBoxFrame ? rule.borderRect(opt->rect)
+ : rule.contentsRect(opt->rect);
+ }
+ QStyleOptionGroupBox groupBox(*gb);
+ groupBox.rect = rule.borderRect(opt->rect);
+ return baseStyle()->subControlRect(cc, &groupBox, sc, w);
+ }
+ default:
+ case SC_GroupBoxLabel:
+ case SC_GroupBoxCheckBox: {
+ QRenderRule indRule = renderRule(w, opt, PseudoElement_GroupBoxIndicator);
+ QRenderRule labelRule = renderRule(w, opt, PseudoElement_GroupBoxTitle);
+ if (!labelRule.hasPosition() && !labelRule.hasGeometry() && !labelRule.hasBox()
+ && !labelRule.hasBorder() && !indRule.hasContentsSize()) {
+ QStyleOptionGroupBox groupBox(*gb);
+ groupBox.rect = rule.borderRect(opt->rect);
+ return baseStyle()->subControlRect(cc, &groupBox, sc, w);
+ }
+ int tw = opt->fontMetrics.width(gb->text);
+ int th = opt->fontMetrics.height();
+ int spacing = pixelMetric(QStyle::PM_CheckBoxLabelSpacing, opt, w);
+ int iw = pixelMetric(QStyle::PM_IndicatorWidth, opt, w);
+ int ih = pixelMetric(QStyle::PM_IndicatorHeight, opt, w);
+
+ if (gb->subControls & QStyle::SC_GroupBoxCheckBox) {
+ tw = tw + iw + spacing;
+ th = qMax(th, ih);
+ }
+ if (!labelRule.hasGeometry()) {
+ labelRule.geo = new QStyleSheetGeometryData(tw, th, tw, th, -1, -1);
+ } else {
+ labelRule.geo->width = tw;
+ labelRule.geo->height = th;
+ }
+ if (!labelRule.hasPosition()) {
+ labelRule.p = new QStyleSheetPositionData(0, 0, 0, 0, defaultOrigin(PseudoElement_GroupBoxTitle),
+ gb->textAlignment, PositionMode_Static);
+ }
+ QRect r = positionRect(w, rule, labelRule, PseudoElement_GroupBoxTitle,
+ opt->rect, opt->direction);
+ if (gb->subControls & SC_GroupBoxCheckBox) {
+ r = labelRule.contentsRect(r);
+ if (sc == SC_GroupBoxLabel) {
+ r.setLeft(r.left() + iw + spacing);
+ r.setTop(r.center().y() - th/2);
+ } else {
+ r = QRect(r.left(), r.center().y() - ih/2, iw, ih);
+ }
+ return r;
+ } else {
+ return labelRule.contentsRect(r);
+ }
+ }
+ } // switch
+ }
+ break;
+
+ case CC_ToolButton:
+ if (const QStyleOptionToolButton *tb = qstyleoption_cast<const QStyleOptionToolButton *>(opt)) {
+ if (rule.hasBox() || !rule.hasNativeBorder()) {
+ switch (sc) {
+ case SC_ToolButton: return rule.borderRect(opt->rect);
+ case SC_ToolButtonMenu: {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_ToolButtonMenu);
+ return positionRect(w, rule, subRule, PseudoElement_ToolButtonMenu, opt->rect, opt->direction);
+ }
+ default:
+ break;
+ }
+ }
+
+ QStyleOptionToolButton tool(*tb);
+ tool.rect = rule.borderRect(opt->rect);
+ return rule.baseStyleCanDraw() ? baseStyle()->subControlRect(cc, &tool, sc, w)
+ : QWindowsStyle::subControlRect(cc, &tool, sc, w);
+ }
+ break;
+
+#ifndef QT_NO_SCROLLBAR
+ case CC_ScrollBar:
+ if (const QStyleOptionSlider *sb = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
+ QStyleOptionSlider styleOptionSlider(*sb);
+ styleOptionSlider.rect = rule.borderRect(opt->rect);
+ if (rule.hasDrawable() || rule.hasBox()) {
+ QRect grooveRect;
+ if (!rule.hasBox()) {
+ grooveRect = rule.baseStyleCanDraw() ? baseStyle()->subControlRect(cc, sb, SC_ScrollBarGroove, w)
+ : QWindowsStyle::subControlRect(cc, sb, SC_ScrollBarGroove, w);
+ } else {
+ grooveRect = rule.contentsRect(opt->rect);
+ }
+
+ PseudoElement pe = PseudoElement_None;
+
+ switch (sc) {
+ case SC_ScrollBarGroove:
+ return grooveRect;
+ case SC_ScrollBarAddPage:
+ case SC_ScrollBarSubPage:
+ case SC_ScrollBarSlider: {
+ QRect contentRect = grooveRect;
+ if (hasStyleRule(w, PseudoElement_ScrollBarSlider)) {
+ QRenderRule sliderRule = renderRule(w, opt, PseudoElement_ScrollBarSlider);
+ Origin origin = sliderRule.hasPosition() ? sliderRule.position()->origin : defaultOrigin(PseudoElement_ScrollBarSlider);
+ contentRect = rule.originRect(opt->rect, origin);
+ }
+ int maxlen = (styleOptionSlider.orientation == Qt::Horizontal) ? contentRect.width() : contentRect.height();
+ int sliderlen;
+ if (sb->maximum != sb->minimum) {
+ uint range = sb->maximum - sb->minimum;
+ sliderlen = (qint64(sb->pageStep) * maxlen) / (range + sb->pageStep);
+
+ int slidermin = pixelMetric(PM_ScrollBarSliderMin, sb, w);
+ if (sliderlen < slidermin || range > INT_MAX / 2)
+ sliderlen = slidermin;
+ if (sliderlen > maxlen)
+ sliderlen = maxlen;
+ } else {
+ sliderlen = maxlen;
+ }
+
+ int sliderstart = (styleOptionSlider.orientation == Qt::Horizontal ? contentRect.left() : contentRect.top())
+ + sliderPositionFromValue(sb->minimum, sb->maximum, sb->sliderPosition,
+ maxlen - sliderlen, sb->upsideDown);
+
+ QRect sr = (sb->orientation == Qt::Horizontal)
+ ? QRect(sliderstart, contentRect.top(), sliderlen, contentRect.height())
+ : QRect(contentRect.left(), sliderstart, contentRect.width(), sliderlen);
+ if (sc == SC_ScrollBarSlider) {
+ return sr;
+ } else if (sc == SC_ScrollBarSubPage) {
+ return QRect(contentRect.topLeft(), sb->orientation == Qt::Horizontal ? sr.bottomLeft() : sr.topRight());
+ } else { // SC_ScrollBarAddPage
+ return QRect(sb->orientation == Qt::Horizontal ? sr.topRight() : sr.bottomLeft(), contentRect.bottomRight());
+ }
+ break;
+ }
+ case SC_ScrollBarAddLine: pe = PseudoElement_ScrollBarAddLine; break;
+ case SC_ScrollBarSubLine: pe = PseudoElement_ScrollBarSubLine; break;
+ case SC_ScrollBarFirst: pe = PseudoElement_ScrollBarFirst; break;
+ case SC_ScrollBarLast: pe = PseudoElement_ScrollBarLast; break;
+ default: break;
+ }
+ if (hasStyleRule(w,pe)) {
+ QRenderRule subRule = renderRule(w, opt, pe);
+ if (subRule.hasPosition() || subRule.hasGeometry() || subRule.hasBox()) {
+ const QStyleSheetPositionData *pos = subRule.position();
+ QRect originRect = grooveRect;
+ if (rule.hasBox()) {
+ Origin origin = (pos && pos->origin != Origin_Unknown) ? pos->origin : defaultOrigin(pe);
+ originRect = rule.originRect(opt->rect, origin);
+ }
+ return positionRect(w, subRule, pe, originRect, styleOptionSlider.direction);
+ }
+ }
+ }
+ return rule.baseStyleCanDraw() ? baseStyle()->subControlRect(cc, &styleOptionSlider, sc, w)
+ : QWindowsStyle::subControlRect(cc, &styleOptionSlider, sc, w);
+ }
+ break;
+#endif // QT_NO_SCROLLBAR
+
+#ifndef QT_NO_SLIDER
+ case CC_Slider:
+ if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_SliderGroove);
+ if (!subRule.hasDrawable())
+ break;
+ subRule.img = 0;
+ QRect gr = positionRect(w, rule, subRule, PseudoElement_SliderGroove, opt->rect, opt->direction);
+ switch (sc) {
+ case SC_SliderGroove:
+ return gr;
+ case SC_SliderHandle: {
+ bool horizontal = slider->orientation & Qt::Horizontal;
+ QRect cr = subRule.contentsRect(gr);
+ QRenderRule subRule2 = renderRule(w, opt, PseudoElement_SliderHandle);
+ int len = horizontal ? subRule2.size().width() : subRule2.size().height();
+ subRule2.img = 0;
+ subRule2.geo = 0;
+ cr = positionRect(w, subRule2, PseudoElement_SliderHandle, cr, opt->direction);
+ int thickness = horizontal ? cr.height() : cr.width();
+ int sliderPos = sliderPositionFromValue(slider->minimum, slider->maximum, slider->sliderPosition,
+ (horizontal ? cr.width() : cr.height()) - len, slider->upsideDown);
+ cr = horizontal ? QRect(cr.x() + sliderPos, cr.y(), len, thickness)
+ : QRect(cr.x(), cr.y() + sliderPos, thickness, len);
+ return subRule2.borderRect(cr);
+ break; }
+ case SC_SliderTickmarks:
+ // TODO...
+ default:
+ break;
+ }
+ }
+ break;
+#endif // QT_NO_SLIDER
+
+ case CC_MdiControls:
+ if (hasStyleRule(w, PseudoElement_MdiCloseButton)
+ || hasStyleRule(w, PseudoElement_MdiNormalButton)
+ || hasStyleRule(w, PseudoElement_MdiMinButton)) {
+ QList<QVariant> layout = rule.styleHint(QLatin1String("button-layout")).toList();
+ if (layout.isEmpty())
+ layout = subControlLayout(QLatin1String("mNX"));
+
+ int x = 0, width = 0;
+ QRenderRule subRule;
+ for (int i = 0; i < layout.count(); i++) {
+ int layoutButton = layout[i].toInt();
+ if (layoutButton < PseudoElement_MdiCloseButton
+ || layoutButton > PseudoElement_MdiNormalButton)
+ continue;
+ QStyle::SubControl control = knownPseudoElements[layoutButton].subControl;
+ if (!(opt->subControls & control))
+ continue;
+ subRule = renderRule(w, opt, layoutButton);
+ width = subRule.size().width();
+ if (sc == control)
+ break;
+ x += width;
+ }
+
+ return subRule.borderRect(QRect(x, opt->rect.top(), width, opt->rect.height()));
+ }
+ break;
+
+ case CC_TitleBar:
+ if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_TitleBar);
+ if (!subRule.hasDrawable() && !subRule.hasBox() && !subRule.hasBorder())
+ break;
+ QHash<QStyle::SubControl, QRect> layoutRects = titleBarLayout(w, tb);
+ return layoutRects.value(sc);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return baseStyle()->subControlRect(cc, opt, sc, w);
+}
+
+QRect QStyleSheetStyle::subElementRect(SubElement se, const QStyleOption *opt, const QWidget *w) const
+{
+ RECURSION_GUARD(return baseStyle()->subElementRect(se, opt, w))
+
+ QRenderRule rule = renderRule(w, opt);
+#ifndef QT_NO_TABBAR
+ int pe = PseudoElement_None;
+#endif
+
+ switch (se) {
+ case SE_PushButtonContents:
+ case SE_PushButtonFocusRect:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
+ QStyleOptionButton btnOpt(*btn);
+ if (rule.hasBox() || !rule.hasNativeBorder())
+ return visualRect(opt->direction, opt->rect, rule.contentsRect(opt->rect));
+ return rule.baseStyleCanDraw() ? baseStyle()->subElementRect(se, &btnOpt, w)
+ : QWindowsStyle::subElementRect(se, &btnOpt, w);
+ }
+ break;
+
+ case SE_LineEditContents:
+ case SE_FrameContents:
+ case SE_ShapedFrameContents:
+ if (rule.hasBox() || !rule.hasNativeBorder()) {
+ return visualRect(opt->direction, opt->rect, rule.contentsRect(opt->rect));
+ }
+ break;
+
+ case SE_CheckBoxIndicator:
+ case SE_RadioButtonIndicator:
+ if (rule.hasBox() || rule.hasBorder() || hasStyleRule(w, PseudoElement_Indicator)) {
+ PseudoElement pe = se == SE_CheckBoxIndicator ? PseudoElement_Indicator : PseudoElement_ExclusiveIndicator;
+ QRenderRule subRule = renderRule(w, opt, pe);
+ return positionRect(w, rule, subRule, pe, opt->rect, opt->direction);
+ }
+ break;
+
+ case SE_CheckBoxContents:
+ case SE_RadioButtonContents:
+ if (rule.hasBox() || rule.hasBorder() || hasStyleRule(w, PseudoElement_Indicator)) {
+ bool isRadio = se == SE_RadioButtonContents;
+ QRect ir = subElementRect(isRadio ? SE_RadioButtonIndicator : SE_CheckBoxIndicator,
+ opt, w);
+ ir = visualRect(opt->direction, opt->rect, ir);
+ int spacing = pixelMetric(isRadio ? PM_RadioButtonLabelSpacing : PM_CheckBoxLabelSpacing, 0, w);
+ QRect cr = rule.contentsRect(opt->rect);
+ ir.setRect(ir.left() + ir.width() + spacing, cr.y(),
+ cr.width() - ir.width() - spacing, cr.height());
+ return visualRect(opt->direction, opt->rect, ir);
+ }
+ break;
+
+ case SE_ToolBoxTabContents:
+ if (w && hasStyleRule(w->parentWidget(), PseudoElement_ToolBoxTab)) {
+ QRenderRule subRule = renderRule(w->parentWidget(), opt, PseudoElement_ToolBoxTab);
+ return visualRect(opt->direction, opt->rect, subRule.contentsRect(opt->rect));
+ }
+ break;
+
+ case SE_RadioButtonFocusRect:
+ case SE_RadioButtonClickRect: // focusrect | indicator
+ if (rule.hasBox() || rule.hasBorder() || hasStyleRule(w, PseudoElement_Indicator)) {
+ return opt->rect;
+ }
+ break;
+
+ case SE_CheckBoxFocusRect:
+ case SE_CheckBoxClickRect: // relies on indicator and contents
+ return ParentStyle::subElementRect(se, opt, w);
+
+#ifndef QT_NO_ITEMVIEWS
+ case SE_ViewItemCheckIndicator:
+ if (!qstyleoption_cast<const QStyleOptionViewItemV4 *>(opt)) {
+ return subElementRect(SE_CheckBoxIndicator, opt, w);
+ }
+ // intentionally falls through
+ case SE_ItemViewItemText:
+ case SE_ItemViewItemDecoration:
+ case SE_ItemViewItemFocusRect:
+ if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(opt)) {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_ViewItem);
+ PseudoElement pe = PseudoElement_None;
+ if (se == SE_ItemViewItemText || se == SE_ItemViewItemFocusRect)
+ pe = PseudoElement_ViewItemText;
+ else if (se == SE_ItemViewItemDecoration && vopt->features & QStyleOptionViewItemV2::HasDecoration)
+ pe = PseudoElement_ViewItemIcon;
+ else if (se == SE_ItemViewItemCheckIndicator && vopt->features & QStyleOptionViewItemV2::HasCheckIndicator)
+ pe = PseudoElement_ViewItemIndicator;
+ else
+ break;
+ if (subRule.hasGeometry() || subRule.hasBox() || !subRule.hasNativeBorder() || hasStyleRule(w, pe)) {
+ QRenderRule subRule2 = renderRule(w, opt, pe);
+ QStyleOptionViewItemV4 optCopy(*vopt);
+ optCopy.rect = subRule.contentsRect(vopt->rect);
+ QRect rect = ParentStyle::subElementRect(se, &optCopy, w);
+ return positionRect(w, subRule2, pe, rect, opt->direction);
+ }
+ }
+ break;
+#endif // QT_NO_ITEMVIEWS
+
+ case SE_HeaderArrow: {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_HeaderViewUpArrow);
+ if (subRule.hasPosition() || subRule.hasGeometry())
+ return positionRect(w, rule, subRule, PseudoElement_HeaderViewUpArrow, opt->rect, opt->direction);
+ }
+ break;
+
+ case SE_HeaderLabel: {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_HeaderViewSection);
+ if (subRule.hasBox() || !subRule.hasNativeBorder())
+ return subRule.contentsRect(opt->rect);
+ }
+ break;
+
+ case SE_ProgressBarGroove:
+ case SE_ProgressBarContents:
+ case SE_ProgressBarLabel:
+ if (const QStyleOptionProgressBarV2 *pb = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(opt)) {
+ if (rule.hasBox() || !rule.hasNativeBorder() || rule.hasPosition() || hasStyleRule(w, PseudoElement_ProgressBarChunk)) {
+ if (se == SE_ProgressBarGroove)
+ return rule.borderRect(pb->rect);
+ else if (se == SE_ProgressBarContents)
+ return rule.contentsRect(pb->rect);
+
+ QSize sz = pb->fontMetrics.size(0, pb->text);
+ return QStyle::alignedRect(Qt::LeftToRight, rule.hasPosition() ? rule.position()->textAlignment : pb->textAlignment,
+ sz, pb->rect);
+ }
+ }
+ break;
+
+#ifndef QT_NO_TABBAR
+ case SE_TabWidgetLeftCorner:
+ pe = PseudoElement_TabWidgetLeftCorner;
+ // intentionally falls through
+ case SE_TabWidgetRightCorner:
+ if (pe == PseudoElement_None)
+ pe = PseudoElement_TabWidgetRightCorner;
+ // intentionally falls through
+ case SE_TabWidgetTabBar:
+ if (pe == PseudoElement_None)
+ pe = PseudoElement_TabWidgetTabBar;
+ // intentionally falls through
+ case SE_TabWidgetTabPane:
+ case SE_TabWidgetTabContents:
+ if (pe == PseudoElement_None)
+ pe = PseudoElement_TabWidgetPane;
+
+ if (hasStyleRule(w, pe)) {
+ QRect r = QWindowsStyle::subElementRect(pe == PseudoElement_TabWidgetPane ? SE_TabWidgetTabPane : se, opt, w);
+ QRenderRule subRule = renderRule(w, opt, pe);
+ r = positionRect(w, subRule, pe, r, opt->direction);
+ if (pe == PseudoElement_TabWidgetTabBar) {
+ Q_ASSERT(opt);
+ r = opt->rect.intersected(r);
+ }
+ if (se == SE_TabWidgetTabContents)
+ r = subRule.contentsRect(r);
+ return r;
+ }
+ break;
+
+ case SE_TabBarTearIndicator: {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_TabBarTear);
+ if (subRule.hasContentsSize()) {
+ QRect r;
+ if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
+ switch (tab->shape) {
+ case QTabBar::RoundedNorth:
+ case QTabBar::TriangularNorth:
+ case QTabBar::RoundedSouth:
+ case QTabBar::TriangularSouth:
+ r.setRect(tab->rect.left(), tab->rect.top(), subRule.size().width(), opt->rect.height());
+ break;
+ case QTabBar::RoundedWest:
+ case QTabBar::TriangularWest:
+ case QTabBar::RoundedEast:
+ case QTabBar::TriangularEast:
+ r.setRect(tab->rect.left(), tab->rect.top(), opt->rect.width(), subRule.size().height());
+ break;
+ default:
+ break;
+ }
+ r = visualRect(opt->direction, opt->rect, r);
+ }
+ return r;
+ }
+ break;
+ }
+ case SE_TabBarTabText:
+ case SE_TabBarTabLeftButton:
+ case SE_TabBarTabRightButton: {
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_TabBarTab);
+ if (subRule.hasBox() || !subRule.hasNativeBorder()) {
+ return ParentStyle::subElementRect(se, opt, w);
+ }
+ break;
+ }
+#endif // QT_NO_TABBAR
+
+ case SE_DockWidgetCloseButton:
+ case SE_DockWidgetFloatButton: {
+ PseudoElement pe = (se == SE_DockWidgetCloseButton) ? PseudoElement_DockWidgetCloseButton : PseudoElement_DockWidgetFloatButton;
+ QRenderRule subRule2 = renderRule(w, opt, pe);
+ if (!subRule2.hasPosition())
+ break;
+ QRenderRule subRule = renderRule(w, opt, PseudoElement_DockWidgetTitle);
+ return positionRect(w, subRule, subRule2, pe, opt->rect, opt->direction);
+ }
+
+#ifndef QT_NO_TOOLBAR
+ case SE_ToolBarHandle:
+ if (hasStyleRule(w, PseudoElement_ToolBarHandle))
+ return ParentStyle::subElementRect(se, opt, w);
+ break;
+#endif //QT_NO_TOOLBAR
+
+ default:
+ break;
+ }
+
+ return baseStyle()->subElementRect(se, opt, w);
+}
+
+bool QStyleSheetStyle::event(QEvent *e)
+{
+ return (baseStyle()->event(e) && e->isAccepted()) || ParentStyle::event(e);
+}
+
+void QStyleSheetStyle::updateStyleSheetFont(QWidget* w) const
+{
+ QWidget *container = containerWidget(w);
+ QRenderRule rule = renderRule(container, PseudoElement_None,
+ PseudoClass_Active | PseudoClass_Enabled | extendedPseudoClass(container));
+ QFont font = rule.font.resolve(w->font());
+
+ if ((!w->isWindow() || w->testAttribute(Qt::WA_WindowPropagation))
+ && isNaturalChild(w) && qobject_cast<QWidget *>(w->parent())) {
+
+ font = font.resolve(static_cast<QWidget *>(w->parent())->font());
+ }
+
+ if (w->data->fnt == font)
+ return;
+
+#ifdef QT3_SUPPORT
+ QFont old = w->data->fnt;
+#endif
+ w->data->fnt = font;
+#if defined(Q_WS_X11)
+ // make sure the font set on this widget is associated with the correct screen
+ //w->data->fnt.x11SetScreen(w->d_func()->xinfo.screen());
+#endif
+
+ QEvent e(QEvent::FontChange);
+ QApplication::sendEvent(w, &e);
+#ifdef QT3_SUPPORT
+ w->fontChange(old);
+#endif
+}
+
+void QStyleSheetStyle::saveWidgetFont(QWidget* w, const QFont& font) const
+{
+ w->setProperty("_q_styleSheetWidgetFont", font);
+}
+
+void QStyleSheetStyle::clearWidgetFont(QWidget* w) const
+{
+ w->setProperty("_q_styleSheetWidgetFont", QVariant(QVariant::Invalid));
+}
+
+// Polish palette that should be used for a particular widget, with particular states
+// (eg. :focus, :hover, ...)
+// this is called by widgets that paint themself in their paint event
+// Returns true if there is a new palette in pal.
+bool QStyleSheetStyle::styleSheetPalette(const QWidget* w, const QStyleOption* opt, QPalette* pal)
+{
+ if (!w || !opt || !pal)
+ return false;
+
+ RECURSION_GUARD(return false)
+
+ w = containerWidget(w);
+
+ QRenderRule rule = renderRule(w, PseudoElement_None, pseudoClass(opt->state) | extendedPseudoClass(w));
+ if (!rule.hasPalette())
+ return false;
+
+ rule.configurePalette(pal, QPalette::NoRole, QPalette::NoRole);
+ return true;
+}
+
+Qt::Alignment QStyleSheetStyle::resolveAlignment(Qt::LayoutDirection layDir, Qt::Alignment src)
+{
+ if (layDir == Qt::LeftToRight || src & Qt::AlignAbsolute)
+ return src;
+
+ if (src & Qt::AlignLeft) {
+ src &= ~Qt::AlignLeft;
+ src |= Qt::AlignRight;
+ } else if (src & Qt::AlignRight) {
+ src &= ~Qt::AlignRight;
+ src |= Qt::AlignLeft;
+ }
+ src |= Qt::AlignAbsolute;
+ return src;
+}
+
+// Returns whether the given QWidget has a "natural" parent, meaning that
+// the parent contains this child as part of its normal operation.
+// An example is the QTabBar inside a QTabWidget.
+// This does not mean that any QTabBar which is a child of QTabWidget will
+// match, only the one that was created by the QTabWidget initialization
+// (and hence has the correct object name).
+bool QStyleSheetStyle::isNaturalChild(const QWidget *w)
+{
+ if (w->objectName().startsWith(QLatin1String("qt_")))
+ return true;
+
+ return false;
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qstylesheetstyle_p.cpp"
+
+#endif // QT_NO_STYLE_STYLESHEET
diff --git a/src/gui/styles/qstylesheetstyle_default.cpp b/src/widgets/styles/qstylesheetstyle_default.cpp
index c9cfc435fa..c9cfc435fa 100644
--- a/src/gui/styles/qstylesheetstyle_default.cpp
+++ b/src/widgets/styles/qstylesheetstyle_default.cpp
diff --git a/src/widgets/styles/qstylesheetstyle_p.h b/src/widgets/styles/qstylesheetstyle_p.h
new file mode 100644
index 0000000000..1d38627edf
--- /dev/null
+++ b/src/widgets/styles/qstylesheetstyle_p.h
@@ -0,0 +1,204 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSTYLESHEETSTYLE_P_H
+#define QSTYLESHEETSTYLE_P_H
+
+#include "QtWidgets/qwindowsstyle.h"
+
+#ifndef QT_NO_STYLE_STYLESHEET
+
+#include "QtWidgets/qstyleoption.h"
+#include "QtCore/qhash.h"
+#include "QtGui/qevent.h"
+#include "QtCore/qvector.h"
+#include "QtWidgets/qapplication.h"
+#include "private/qcssparser_p.h"
+#include "QtGui/qbrush.h"
+
+QT_BEGIN_NAMESPACE
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+class QRenderRule;
+class QAbstractScrollArea;
+class QStyleSheetStylePrivate;
+class QStyleOptionTitleBar;
+
+class Q_AUTOTEST_EXPORT QStyleSheetStyle : public QWindowsStyle
+{
+ typedef QWindowsStyle ParentStyle;
+
+ Q_OBJECT
+public:
+ QStyleSheetStyle(QStyle *baseStyle);
+ ~QStyleSheetStyle();
+
+ void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p,
+ const QWidget *w = 0) const;
+ void drawControl(ControlElement element, const QStyleOption *opt, QPainter *p,
+ const QWidget *w = 0) const;
+ void drawItemPixmap(QPainter *painter, const QRect &rect, int alignment, const QPixmap &pixmap) const;
+ void drawItemText(QPainter *painter, const QRect& rect, int alignment, const QPalette &pal,
+ bool enabled, const QString& text, QPalette::ColorRole textRole = QPalette::NoRole) const;
+ void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p,
+ const QWidget *w = 0) const;
+ QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap,
+ const QStyleOption *option) const;
+ SubControl hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt,
+ const QPoint &pt, const QWidget *w = 0) const;
+ QRect itemPixmapRect(const QRect &rect, int alignment, const QPixmap &pixmap) const;
+ QRect itemTextRect(const QFontMetrics &metrics, const QRect &rect, int alignment, bool enabled,
+ const QString &text) const;
+ int pixelMetric(PixelMetric metric, const QStyleOption *option = 0, const QWidget *widget = 0) const;
+ void polish(QWidget *widget);
+ void polish(QApplication *app);
+ void polish(QPalette &pal);
+ QSize sizeFromContents(ContentsType ct, const QStyleOption *opt,
+ const QSize &contentsSize, const QWidget *widget = 0) const;
+ QPalette standardPalette() const;
+ QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *option = 0,
+ const QWidget *w = 0 ) const;
+ int layoutSpacing(QSizePolicy::ControlType control1, QSizePolicy::ControlType control2,
+ Qt::Orientation orientation, const QStyleOption *option = 0,
+ const QWidget *widget = 0) const;
+ int styleHint(StyleHint sh, const QStyleOption *opt = 0, const QWidget *w = 0,
+ QStyleHintReturn *shret = 0) const;
+ QRect subElementRect(SubElement r, const QStyleOption *opt, const QWidget *widget = 0) const;
+ QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc,
+ const QWidget *w = 0) const;
+
+ // These functions are called from QApplication/QWidget. Be careful.
+ QStyle *baseStyle() const;
+ void repolish(QWidget *widget);
+ void repolish(QApplication *app);
+
+ void unpolish(QWidget *widget);
+ void unpolish(QApplication *app);
+
+ QStyle *base;
+ void ref() { ++refcount; }
+ void deref() { Q_ASSERT(refcount > 0); if (!--refcount) delete this; }
+
+ void updateStyleSheetFont(QWidget* w) const;
+ void saveWidgetFont(QWidget* w, const QFont& font) const;
+ void clearWidgetFont(QWidget* w) const;
+
+ bool styleSheetPalette(const QWidget* w, const QStyleOption* opt, QPalette* pal);
+
+protected Q_SLOTS:
+ QIcon standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *opt = 0,
+ const QWidget *widget = 0) const;
+ int layoutSpacingImplementation(QSizePolicy::ControlType control1,
+ QSizePolicy::ControlType control2,
+ Qt::Orientation orientation,
+ const QStyleOption *option = 0,
+ const QWidget *widget = 0) const;
+
+protected:
+ bool event(QEvent *e);
+
+private:
+ int refcount;
+
+ friend class QRenderRule;
+ int nativeFrameWidth(const QWidget *);
+ QRenderRule renderRule(const QWidget *, int, quint64 = 0) const;
+ QRenderRule renderRule(const QWidget *, const QStyleOption *, int = 0) const;
+ QSize defaultSize(const QWidget *, QSize, const QRect&, int) const;
+ QRect positionRect(const QWidget *, const QRenderRule&, const QRenderRule&, int,
+ const QRect&, Qt::LayoutDirection) const;
+ QRect positionRect(const QWidget *w, const QRenderRule &rule2, int pe,
+ const QRect &originRect, Qt::LayoutDirection dir) const;
+
+ mutable QCss::Parser parser;
+
+ void setPalette(QWidget *);
+ void unsetPalette(QWidget *);
+ void setProperties(QWidget *);
+ void setGeometry(QWidget *);
+ QVector<QCss::StyleRule> styleRules(const QWidget *w) const;
+ bool hasStyleRule(const QWidget *w, int part) const;
+
+ QHash<QStyle::SubControl, QRect> titleBarLayout(const QWidget *w, const QStyleOptionTitleBar *tb) const;
+
+ QCss::StyleSheet getDefaultStyleSheet() const;
+
+ static Qt::Alignment resolveAlignment(Qt::LayoutDirection, Qt::Alignment);
+ static bool isNaturalChild(const QWidget *w);
+ bool initWidget(const QWidget *w) const;
+public:
+ static int numinstances;
+
+private:
+ Q_DISABLE_COPY(QStyleSheetStyle)
+ Q_DECLARE_PRIVATE(QStyleSheetStyle)
+};
+
+class QStyleSheetStyleCaches : public QObject
+{
+ Q_OBJECT
+public Q_SLOTS:
+ void widgetDestroyed(QObject *);
+ void styleDestroyed(QObject *);
+public:
+ QHash<const QWidget *, QVector<QCss::StyleRule> > styleRulesCache;
+ QHash<const QWidget *, QHash<int, bool> > hasStyleRuleCache;
+ typedef QHash<int, QHash<quint64, QRenderRule> > QRenderRules;
+ QHash<const QWidget *, QRenderRules> renderRulesCache;
+ QHash<const QWidget *, QPalette> customPaletteWidgets; // widgets whose palette we tampered
+ QHash<const void *, QCss::StyleSheet> styleSheetCache; // parsed style sheets
+ QSet<const QWidget *> autoFillDisabledWidgets;
+};
+
+
+QT_END_NAMESPACE
+#endif // QT_NO_STYLE_STYLESHEET
+#endif // QSTYLESHEETSTYLE_P_H
diff --git a/src/gui/styles/qwindowscestyle.cpp b/src/widgets/styles/qwindowscestyle.cpp
index 39174f9855..39174f9855 100644
--- a/src/gui/styles/qwindowscestyle.cpp
+++ b/src/widgets/styles/qwindowscestyle.cpp
diff --git a/src/widgets/styles/qwindowscestyle.h b/src/widgets/styles/qwindowscestyle.h
new file mode 100644
index 0000000000..3db9be58e2
--- /dev/null
+++ b/src/widgets/styles/qwindowscestyle.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSCESTYLE_H
+#define QWINDOWSCESTYLE_H
+
+#include <QtWidgets/qwindowsstyle.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#if !defined(QT_NO_STYLE_WINDOWSCE)
+
+class Q_WIDGETS_EXPORT QWindowsCEStyle : public QWindowsStyle
+{
+ Q_OBJECT
+public:
+ QWindowsCEStyle();
+
+ void drawPrimitive(PrimitiveElement element, const QStyleOption *option,
+ QPainter *painter, const QWidget *widget = 0) const;
+
+ void drawControl(ControlElement element, const QStyleOption *option,
+ QPainter *painter, const QWidget *widget) const;
+
+ void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option,
+ QPainter *painter, const QWidget *widget) const;
+
+ virtual void drawItemText(QPainter *painter, const QRect &rect,
+ int flags, const QPalette &pal, bool enabled,
+ const QString &text, QPalette::ColorRole textRole = QPalette::NoRole) const;
+
+ QSize sizeFromContents(ContentsType type, const QStyleOption *option,
+ const QSize &size, const QWidget *widget) const;
+
+ QRect subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const;
+ QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt,
+ SubControl sc, const QWidget *widget) const;
+
+ SubControl hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option,
+ const QPoint &pos, const QWidget *widget = 0) const;
+
+ QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt,
+ const QWidget *widget = 0) const;
+ int pixelMetric(PixelMetric metric, const QStyleOption *option = 0, const QWidget *widget = 0) const;
+
+ int styleHint(StyleHint hint, const QStyleOption *opt = 0, const QWidget *widget = 0,
+ QStyleHintReturn *returnData = 0) const;
+
+ void polish(QWidget *widget);
+ void polish(QPalette &palette);
+ void polish(QApplication *app);
+ QPalette standardPalette() const;
+};
+
+#endif // QT_NO_STYLE_WINDOWSCE
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QWINDOWSCESTYLE_H
diff --git a/src/gui/styles/qwindowscestyle_p.h b/src/widgets/styles/qwindowscestyle_p.h
index d32ac99d52..d32ac99d52 100644
--- a/src/gui/styles/qwindowscestyle_p.h
+++ b/src/widgets/styles/qwindowscestyle_p.h
diff --git a/src/gui/styles/qwindowsmobilestyle.cpp b/src/widgets/styles/qwindowsmobilestyle.cpp
index 1e029a30e0..1e029a30e0 100644
--- a/src/gui/styles/qwindowsmobilestyle.cpp
+++ b/src/widgets/styles/qwindowsmobilestyle.cpp
diff --git a/src/widgets/styles/qwindowsmobilestyle.h b/src/widgets/styles/qwindowsmobilestyle.h
new file mode 100644
index 0000000000..050f641888
--- /dev/null
+++ b/src/widgets/styles/qwindowsmobilestyle.h
@@ -0,0 +1,116 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSMOBILESTYLE_H
+#define QWINDOWSMOBILESTYLE_H
+
+#include <QtWidgets/qwindowsstyle.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#if !defined(QT_NO_STYLE_WINDOWSMOBILE)
+
+class QWindowsMobileStylePrivate;
+
+class Q_WIDGETS_EXPORT QWindowsMobileStyle : public QWindowsStyle
+{
+ Q_OBJECT
+public:
+ QWindowsMobileStyle();
+
+ void drawPrimitive(PrimitiveElement element, const QStyleOption *option,
+ QPainter *painter, const QWidget *widget = 0) const;
+
+ void drawControl(ControlElement element, const QStyleOption *option,
+ QPainter *painter, const QWidget *widget) const;
+
+ void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option,
+ QPainter *painter, const QWidget *widget) const;
+
+ QSize sizeFromContents(ContentsType type, const QStyleOption *option,
+ const QSize &size, const QWidget *widget) const;
+
+ QRect subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const;
+
+ QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt,
+ SubControl sc, const QWidget *widget) const;
+
+ QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap,
+ const QStyleOption *option) const;
+
+ QPixmap standardPixmap(StandardPixmap sp, const QStyleOption *option,
+ const QWidget *widget) const;
+
+ int pixelMetric(PixelMetric metric, const QStyleOption *option = 0, const QWidget *widget = 0) const;
+
+ int styleHint(StyleHint hint, const QStyleOption *opt = 0, const QWidget *widget = 0,
+ QStyleHintReturn *returnData = 0) const;
+
+ void polish(QApplication*);
+ void unpolish(QApplication*);
+ void polish(QWidget *widget);
+ void unpolish(QWidget *widget);
+ void polish(QPalette &);
+
+ QPalette standardPalette() const;
+
+ bool doubleControls() const;
+
+ void setDoubleControls(bool);
+
+protected:
+ QWindowsMobileStyle(QWindowsMobileStylePrivate &dd);
+
+private:
+ Q_DECLARE_PRIVATE(QWindowsMobileStyle)
+};
+
+#endif // QT_NO_STYLE_WINDOWSMOBILE
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif //QWINDOWSMOBILESTYLE_H
diff --git a/src/gui/styles/qwindowsmobilestyle_p.h b/src/widgets/styles/qwindowsmobilestyle_p.h
index 32ebe911ef..32ebe911ef 100644
--- a/src/gui/styles/qwindowsmobilestyle_p.h
+++ b/src/widgets/styles/qwindowsmobilestyle_p.h
diff --git a/src/widgets/styles/qwindowsstyle.cpp b/src/widgets/styles/qwindowsstyle.cpp
new file mode 100644
index 0000000000..d1d3865868
--- /dev/null
+++ b/src/widgets/styles/qwindowsstyle.cpp
@@ -0,0 +1,3390 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsstyle.h"
+#include "qwindowsstyle_p.h"
+
+#if !defined(QT_NO_STYLE_WINDOWS) || defined(QT_PLUGIN)
+
+#include <private/qsystemlibrary_p.h>
+#include "qapplication.h"
+#include "qbitmap.h"
+#include "qdrawutil.h" // for now
+#include "qevent.h"
+#include "qmenu.h"
+#include "qmenubar.h"
+#include <private/qmenubar_p.h>
+#include "qpaintengine.h"
+#include "qpainter.h"
+#include "qprogressbar.h"
+#include "qrubberband.h"
+#include "qstyleoption.h"
+#include "qtabbar.h"
+#include "qwidget.h"
+#include "qdebug.h"
+#include "qmainwindow.h"
+#include "qfile.h"
+#include "qtextstream.h"
+#include "qpixmapcache.h"
+#include "qwizard.h"
+#include "qlistview.h"
+#include <private/qmath_p.h>
+#include <qmath.h>
+
+#ifdef Q_WS_X11
+#include "qfileinfo.h"
+#include "qdir.h"
+#include <private/qt_x11_p.h>
+#endif
+
+#include <private/qstylehelper_p.h>
+
+QT_BEGIN_NAMESPACE
+
+#if defined(Q_WS_WIN)
+
+QT_BEGIN_INCLUDE_NAMESPACE
+#include "qt_windows.h"
+QT_END_INCLUDE_NAMESPACE
+# ifndef COLOR_GRADIENTACTIVECAPTION
+# define COLOR_GRADIENTACTIVECAPTION 27
+# endif
+# ifndef COLOR_GRADIENTINACTIVECAPTION
+# define COLOR_GRADIENTINACTIVECAPTION 28
+# endif
+
+
+typedef struct
+{
+ DWORD cbSize;
+ HICON hIcon;
+ int iSysImageIndex;
+ int iIcon;
+ WCHAR szPath[MAX_PATH];
+} QSHSTOCKICONINFO;
+
+#define _SHGFI_SMALLICON 0x000000001
+#define _SHGFI_LARGEICON 0x000000000
+#define _SHGFI_ICON 0x000000100
+#define _SIID_SHIELD 77
+
+typedef HRESULT (WINAPI *PtrSHGetStockIconInfo)(int siid, int uFlags, QSHSTOCKICONINFO *psii);
+static PtrSHGetStockIconInfo pSHGetStockIconInfo = 0;
+
+#endif //Q_WS_WIN
+
+QT_BEGIN_INCLUDE_NAMESPACE
+#include <limits.h>
+QT_END_INCLUDE_NAMESPACE
+
+enum QSliderDirection { SlUp, SlDown, SlLeft, SlRight };
+
+/*
+ \internal
+*/
+QWindowsStylePrivate::QWindowsStylePrivate()
+ : alt_down(false), menuBarTimer(0), animationFps(10), animateTimer(0), animateStep(0)
+{
+#if defined(Q_WS_WIN) && !defined(Q_OS_WINCE)
+ if ((QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA
+ && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)) {
+ QSystemLibrary shellLib(QLatin1String("shell32"));
+ pSHGetStockIconInfo = (PtrSHGetStockIconInfo)shellLib.resolve("SHGetStockIconInfo");
+ }
+#endif
+ startTime.start();
+}
+
+// Returns true if the toplevel parent of \a widget has seen the Alt-key
+bool QWindowsStylePrivate::hasSeenAlt(const QWidget *widget) const
+{
+ widget = widget->window();
+ return seenAlt.contains(widget);
+}
+
+/*!
+ \reimp
+*/
+void QWindowsStyle::timerEvent(QTimerEvent *event)
+{
+#ifndef QT_NO_PROGRESSBAR
+ Q_D(QWindowsStyle);
+ if (event->timerId() == d->animateTimer) {
+ Q_ASSERT(d->animationFps> 0);
+ d->animateStep = d->startTime.elapsed() / (1000 / d->animationFps);
+ foreach (QProgressBar *bar, d->bars) {
+ if ((bar->minimum() == 0 && bar->maximum() == 0))
+ bar->update();
+ }
+ }
+#endif // QT_NO_PROGRESSBAR
+ event->ignore();
+}
+
+/*!
+ \reimp
+*/
+bool QWindowsStyle::eventFilter(QObject *o, QEvent *e)
+{
+ // Records Alt- and Focus events
+ if (!o->isWidgetType())
+ return QObject::eventFilter(o, e);
+
+ QWidget *widget = qobject_cast<QWidget*>(o);
+ Q_D(QWindowsStyle);
+ switch(e->type()) {
+ case QEvent::KeyPress:
+ if (static_cast<QKeyEvent *>(e)->key() == Qt::Key_Alt) {
+ widget = widget->window();
+
+ // Alt has been pressed - find all widgets that care
+ QList<QWidget *> l = widget->findChildren<QWidget *>();
+ for (int pos=0 ; pos < l.size() ; ++pos) {
+ QWidget *w = l.at(pos);
+ if (w->isWindow() || !w->isVisible() ||
+ w->style()->styleHint(SH_UnderlineShortcut, 0, w))
+ l.removeAt(pos);
+ }
+ // Update states before repainting
+ d->seenAlt.append(widget);
+ d->alt_down = true;
+
+ // Repaint all relevant widgets
+ for (int pos = 0; pos < l.size(); ++pos)
+ l.at(pos)->update();
+ }
+ break;
+ case QEvent::KeyRelease:
+ if (static_cast<QKeyEvent*>(e)->key() == Qt::Key_Alt) {
+ widget = widget->window();
+
+ // Update state and repaint the menu bars.
+ d->alt_down = false;
+#ifndef QT_NO_MENUBAR
+ QList<QMenuBar *> l = widget->findChildren<QMenuBar *>();
+ for (int i = 0; i < l.size(); ++i)
+ l.at(i)->update();
+#endif
+ }
+ break;
+ case QEvent::Close:
+ // Reset widget when closing
+ d->seenAlt.removeAll(widget);
+ d->seenAlt.removeAll(widget->window());
+ break;
+#ifndef QT_NO_PROGRESSBAR
+ case QEvent::StyleChange:
+ case QEvent::Show:
+ if (QProgressBar *bar = qobject_cast<QProgressBar *>(o)) {
+ if (!d->bars.contains(bar)) {
+ d->bars << bar;
+ if (d->bars.size() == 1) {
+ Q_ASSERT(d->animationFps> 0);
+ d->animateTimer = startTimer(1000 / d->animationFps);
+ }
+ }
+ }
+ break;
+ case QEvent::Destroy:
+ case QEvent::Hide:
+ // reinterpret_cast because there is no type info when getting
+ // the destroy event. We know that it is a QProgressBar.
+ if (QProgressBar *bar = reinterpret_cast<QProgressBar *>(o)) {
+ d->bars.removeAll(bar);
+ if (d->bars.isEmpty() && d->animateTimer) {
+ killTimer(d->animateTimer);
+ d->animateTimer = 0;
+ }
+ }
+ break;
+#endif // QT_NO_PROGRESSBAR
+ default:
+ break;
+ }
+ return QCommonStyle::eventFilter(o, e);
+}
+
+/*!
+ \class QWindowsStyle
+ \brief The QWindowsStyle class provides a Microsoft Windows-like look and feel.
+
+ \ingroup appearance
+
+ This style is Qt's default GUI style on Windows.
+
+ \img qwindowsstyle.png
+ \sa QWindowsXPStyle, QMacStyle, QPlastiqueStyle, QCDEStyle, QMotifStyle
+*/
+
+/*!
+ Constructs a QWindowsStyle object.
+*/
+QWindowsStyle::QWindowsStyle() : QCommonStyle(*new QWindowsStylePrivate)
+{
+}
+
+/*!
+ \internal
+
+ Constructs a QWindowsStyle object.
+*/
+QWindowsStyle::QWindowsStyle(QWindowsStylePrivate &dd) : QCommonStyle(dd)
+{
+}
+
+
+/*! Destroys the QWindowsStyle object. */
+QWindowsStyle::~QWindowsStyle()
+{
+}
+
+#ifdef Q_WS_WIN
+static inline QRgb colorref2qrgb(COLORREF col)
+{
+ return qRgb(GetRValue(col), GetGValue(col), GetBValue(col));
+}
+#endif
+
+/*! \reimp */
+void QWindowsStyle::polish(QApplication *app)
+{
+ QCommonStyle::polish(app);
+ QWindowsStylePrivate *d = const_cast<QWindowsStylePrivate*>(d_func());
+ // We only need the overhead when shortcuts are sometimes hidden
+ if (!proxy()->styleHint(SH_UnderlineShortcut, 0) && app)
+ app->installEventFilter(this);
+
+ d->activeCaptionColor = app->palette().highlight().color();
+ d->activeGradientCaptionColor = app->palette().highlight() .color();
+ d->inactiveCaptionColor = app->palette().dark().color();
+ d->inactiveGradientCaptionColor = app->palette().dark().color();
+ d->inactiveCaptionText = app->palette().background().color();
+
+#if defined(Q_WS_WIN) //fetch native title bar colors
+ if(app->desktopSettingsAware()){
+ DWORD activeCaption = GetSysColor(COLOR_ACTIVECAPTION);
+ DWORD gradientActiveCaption = GetSysColor(COLOR_GRADIENTACTIVECAPTION);
+ DWORD inactiveCaption = GetSysColor(COLOR_INACTIVECAPTION);
+ DWORD gradientInactiveCaption = GetSysColor(COLOR_GRADIENTINACTIVECAPTION);
+ DWORD inactiveCaptionText = GetSysColor(COLOR_INACTIVECAPTIONTEXT);
+ d->activeCaptionColor = colorref2qrgb(activeCaption);
+ d->activeGradientCaptionColor = colorref2qrgb(gradientActiveCaption);
+ d->inactiveCaptionColor = colorref2qrgb(inactiveCaption);
+ d->inactiveGradientCaptionColor = colorref2qrgb(gradientInactiveCaption);
+ d->inactiveCaptionText = colorref2qrgb(inactiveCaptionText);
+ }
+#endif
+}
+
+/*! \reimp */
+void QWindowsStyle::unpolish(QApplication *app)
+{
+ QCommonStyle::unpolish(app);
+ app->removeEventFilter(this);
+}
+
+/*! \reimp */
+void QWindowsStyle::polish(QWidget *widget)
+{
+ QCommonStyle::polish(widget);
+#ifndef QT_NO_PROGRESSBAR
+ if (qobject_cast<QProgressBar *>(widget))
+ widget->installEventFilter(this);
+#endif
+}
+
+/*! \reimp */
+void QWindowsStyle::unpolish(QWidget *widget)
+{
+ QCommonStyle::unpolish(widget);
+#ifndef QT_NO_PROGRESSBAR
+ if (QProgressBar *bar=qobject_cast<QProgressBar *>(widget)) {
+ Q_D(QWindowsStyle);
+ widget->removeEventFilter(this);
+ d->bars.removeAll(bar);
+ }
+#endif
+}
+
+/*!
+ \reimp
+*/
+void QWindowsStyle::polish(QPalette &pal)
+{
+ QCommonStyle::polish(pal);
+}
+
+/*!
+ \reimp
+*/
+int QWindowsStyle::pixelMetric(PixelMetric pm, const QStyleOption *opt, const QWidget *widget) const
+{
+ int ret;
+
+ switch (pm) {
+ case PM_ButtonDefaultIndicator:
+ case PM_ButtonShiftHorizontal:
+ case PM_ButtonShiftVertical:
+ case PM_MenuHMargin:
+ case PM_MenuVMargin:
+ ret = 1;
+ break;
+#ifndef QT_NO_TABBAR
+ case PM_TabBarTabShiftHorizontal:
+ ret = 0;
+ break;
+ case PM_TabBarTabShiftVertical:
+ ret = 2;
+ break;
+#endif
+ case PM_MaximumDragDistance:
+#if defined(Q_WS_WIN)
+ {
+ HDC hdcScreen = GetDC(0);
+ int dpi = GetDeviceCaps(hdcScreen, LOGPIXELSX);
+ ReleaseDC(0, hdcScreen);
+ ret = (int)(dpi * 1.375);
+ }
+#else
+ ret = 60;
+#endif
+ break;
+
+#ifndef QT_NO_SLIDER
+ case PM_SliderLength:
+ ret = int(QStyleHelper::dpiScaled(11.));
+ break;
+
+ // Returns the number of pixels to use for the business part of the
+ // slider (i.e., the non-tickmark portion). The remaining space is shared
+ // equally between the tickmark regions.
+ case PM_SliderControlThickness:
+ if (const QStyleOptionSlider *sl = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
+ int space = (sl->orientation == Qt::Horizontal) ? sl->rect.height() : sl->rect.width();
+ int ticks = sl->tickPosition;
+ int n = 0;
+ if (ticks & QSlider::TicksAbove)
+ ++n;
+ if (ticks & QSlider::TicksBelow)
+ ++n;
+ if (!n) {
+ ret = space;
+ break;
+ }
+
+ int thick = 6; // Magic constant to get 5 + 16 + 5
+ if (ticks != QSlider::TicksBothSides && ticks != QSlider::NoTicks)
+ thick += proxy()->pixelMetric(PM_SliderLength, sl, widget) / 4;
+
+ space -= thick;
+ if (space > 0)
+ thick += (space * 2) / (n + 2);
+ ret = thick;
+ } else {
+ ret = 0;
+ }
+ break;
+#endif // QT_NO_SLIDER
+
+#ifndef QT_NO_MENU
+ case PM_MenuBarHMargin:
+ ret = 0;
+ break;
+
+ case PM_MenuBarVMargin:
+ ret = 0;
+ break;
+
+ case PM_MenuBarPanelWidth:
+ ret = 0;
+ break;
+
+ case PM_SmallIconSize:
+ ret = int(QStyleHelper::dpiScaled(16.));
+ break;
+
+ case PM_LargeIconSize:
+ ret = int(QStyleHelper::dpiScaled(32.));
+ break;
+
+ case PM_IconViewIconSize:
+ ret = proxy()->pixelMetric(PM_LargeIconSize, opt, widget);
+ break;
+
+ case PM_DockWidgetTitleMargin:
+ ret = int(QStyleHelper::dpiScaled(2.));
+ break;
+ case PM_DockWidgetTitleBarButtonMargin:
+ ret = int(QStyleHelper::dpiScaled(4.));
+ break;
+#if defined(Q_WS_WIN)
+ case PM_DockWidgetFrameWidth:
+#if defined(Q_OS_WINCE)
+ ret = GetSystemMetrics(SM_CXDLGFRAME);
+#else
+ ret = GetSystemMetrics(SM_CXFRAME);
+#endif
+ break;
+#else
+ case PM_DockWidgetFrameWidth:
+ ret = 4;
+ break;
+#endif // Q_WS_WIN
+ break;
+
+#endif // QT_NO_MENU
+
+
+#if defined(Q_WS_WIN)
+ case PM_TitleBarHeight:
+#ifdef QT3_SUPPORT
+ // qt3 dockwindow height should be equal to tool windows
+ if (widget && widget->inherits("Q3DockWindowTitleBar")) {
+ ret = GetSystemMetrics(SM_CYSMCAPTION) - 1;
+ } else
+#endif
+ if (widget && (widget->windowType() == Qt::Tool)) {
+ // MS always use one less than they say
+#if defined(Q_OS_WINCE)
+ ret = GetSystemMetrics(SM_CYCAPTION) - 1;
+#else
+ ret = GetSystemMetrics(SM_CYSMCAPTION) - 1;
+#endif
+ } else {
+ ret = GetSystemMetrics(SM_CYCAPTION) - 1;
+ }
+
+ break;
+
+ case PM_ScrollBarExtent:
+ {
+#ifndef Q_OS_WINCE
+ NONCLIENTMETRICS ncm;
+ ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICS, lfMessageFont) + sizeof(LOGFONT);
+ if (SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0))
+ ret = qMax(ncm.iScrollHeight, ncm.iScrollWidth);
+ else
+#endif
+ ret = QCommonStyle::pixelMetric(pm, opt, widget);
+ }
+ break;
+#endif // Q_WS_WIN
+
+ case PM_SplitterWidth:
+ ret = qMax(4, QApplication::globalStrut().width());
+ break;
+
+#if defined(Q_WS_WIN)
+ case PM_MdiSubWindowFrameWidth:
+#if defined(Q_OS_WINCE)
+ ret = GetSystemMetrics(SM_CYDLGFRAME);
+#else
+ ret = GetSystemMetrics(SM_CYFRAME);
+#endif
+ break;
+ case PM_TextCursorWidth: {
+ DWORD caretWidth = 1;
+#if defined(SPI_GETCARETWIDTH)
+ SystemParametersInfo(SPI_GETCARETWIDTH, 0, &caretWidth, 0);
+#endif
+ ret = (int)caretWidth;
+ break; }
+#endif
+ case PM_ToolBarItemMargin:
+ ret = 1;
+ break;
+ case PM_ToolBarItemSpacing:
+ ret = 0;
+ break;
+ case PM_ToolBarHandleExtent:
+ ret = int(QStyleHelper::dpiScaled(10.));
+ break;
+ default:
+ ret = QCommonStyle::pixelMetric(pm, opt, widget);
+ break;
+ }
+
+ return ret;
+}
+
+#ifndef QT_NO_IMAGEFORMAT_XPM
+
+/* XPM */
+static const char * const qt_menu_xpm[] = {
+"16 16 72 1",
+" c None",
+". c #65AF36",
+"+ c #66B036",
+"@ c #77B94C",
+"# c #A7D28C",
+"$ c #BADBA4",
+"% c #A4D088",
+"& c #72B646",
+"* c #9ACB7A",
+"= c #7FBD56",
+"- c #85C05F",
+"; c #F4F9F0",
+"> c #FFFFFF",
+", c #E5F1DC",
+"' c #ECF5E7",
+") c #7ABA50",
+"! c #83BF5C",
+"~ c #AED595",
+"{ c #D7EACA",
+"] c #A9D28D",
+"^ c #BCDDA8",
+"/ c #C4E0B1",
+"( c #81BE59",
+"_ c #D0E7C2",
+": c #D4E9C6",
+"< c #6FB542",
+"[ c #6EB440",
+"} c #88C162",
+"| c #98CA78",
+"1 c #F4F9F1",
+"2 c #8FC56C",
+"3 c #F1F8EC",
+"4 c #E8F3E1",
+"5 c #D4E9C7",
+"6 c #74B748",
+"7 c #80BE59",
+"8 c #73B747",
+"9 c #6DB43F",
+"0 c #CBE4BA",
+"a c #80BD58",
+"b c #6DB33F",
+"c c #FEFFFE",
+"d c #68B138",
+"e c #F9FCF7",
+"f c #91C66F",
+"g c #E8F3E0",
+"h c #DCEDD0",
+"i c #91C66E",
+"j c #A3CF86",
+"k c #C9E3B8",
+"l c #B0D697",
+"m c #E3F0DA",
+"n c #95C873",
+"o c #E6F2DE",
+"p c #9ECD80",
+"q c #BEDEAA",
+"r c #C7E2B6",
+"s c #79BA4F",
+"t c #6EB441",
+"u c #BCDCA7",
+"v c #FAFCF8",
+"w c #F6FAF3",
+"x c #84BF5D",
+"y c #EDF6E7",
+"z c #FAFDF9",
+"A c #88C263",
+"B c #98CA77",
+"C c #CDE5BE",
+"D c #67B037",
+"E c #D9EBCD",
+"F c #6AB23C",
+"G c #77B94D",
+" .++++++++++++++",
+".+++++++++++++++",
+"+++@#$%&+++*=+++",
+"++-;>,>')+!>~+++",
+"++{>]+^>/(_>:~<+",
+"+[>>}+|>123>456+",
+"+7>>8+->>90>~+++",
+"+a>>b+a>c[0>~+++",
+"+de>=+f>g+0>~+++",
+"++h>i+j>k+0>~+++",
+"++l>mno>p+q>rst+",
+"++duv>wl++xy>zA+",
+"++++B>Cb++++&D++",
+"+++++0zE++++++++",
+"++++++FG+++++++.",
+"++++++++++++++. "};
+
+static const char * const qt_close_xpm[] = {
+"10 10 2 1",
+"# c #000000",
+". c None",
+"..........",
+".##....##.",
+"..##..##..",
+"...####...",
+"....##....",
+"...####...",
+"..##..##..",
+".##....##.",
+"..........",
+".........."};
+
+static const char * const qt_maximize_xpm[]={
+"10 10 2 1",
+"# c #000000",
+". c None",
+"#########.",
+"#########.",
+"#.......#.",
+"#.......#.",
+"#.......#.",
+"#.......#.",
+"#.......#.",
+"#.......#.",
+"#########.",
+".........."};
+
+static const char * const qt_minimize_xpm[] = {
+"10 10 2 1",
+"# c #000000",
+". c None",
+"..........",
+"..........",
+"..........",
+"..........",
+"..........",
+"..........",
+"..........",
+".#######..",
+".#######..",
+".........."};
+
+static const char * const qt_normalizeup_xpm[] = {
+"10 10 2 1",
+"# c #000000",
+". c None",
+"...######.",
+"...######.",
+"...#....#.",
+".######.#.",
+".######.#.",
+".#....###.",
+".#....#...",
+".#....#...",
+".######...",
+".........."};
+
+static const char * const qt_help_xpm[] = {
+"10 10 2 1",
+". c None",
+"# c #000000",
+"..........",
+"..######..",
+".##....##.",
+"......##..",
+".....##...",
+"....##....",
+"....##....",
+"..........",
+"....##....",
+".........."};
+
+static const char * const qt_shade_xpm[] = {
+"10 10 2 1",
+"# c #000000",
+". c None",
+"..........",
+"..........",
+"..........",
+"..........",
+"....#.....",
+"...###....",
+"..#####...",
+".#######..",
+"..........",
+".........."};
+
+static const char * const qt_unshade_xpm[] = {
+"10 10 2 1",
+"# c #000000",
+". c None",
+"..........",
+"..........",
+"..........",
+".#######..",
+"..#####...",
+"...###....",
+"....#.....",
+"..........",
+"..........",
+".........."};
+
+static const char * dock_widget_close_xpm[] = {
+"8 8 2 1",
+"# c #000000",
+". c None",
+"........",
+".##..##.",
+"..####..",
+"...##...",
+"..####..",
+".##..##.",
+"........",
+"........"};
+
+/* XPM */
+static const char * const information_xpm[]={
+"32 32 5 1",
+". c None",
+"c c #000000",
+"* c #999999",
+"a c #ffffff",
+"b c #0000ff",
+"...........********.............",
+"........***aaaaaaaa***..........",
+"......**aaaaaaaaaaaaaa**........",
+".....*aaaaaaaaaaaaaaaaaa*.......",
+"....*aaaaaaaabbbbaaaaaaaac......",
+"...*aaaaaaaabbbbbbaaaaaaaac.....",
+"..*aaaaaaaaabbbbbbaaaaaaaaac....",
+".*aaaaaaaaaaabbbbaaaaaaaaaaac...",
+".*aaaaaaaaaaaaaaaaaaaaaaaaaac*..",
+"*aaaaaaaaaaaaaaaaaaaaaaaaaaaac*.",
+"*aaaaaaaaaabbbbbbbaaaaaaaaaaac*.",
+"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
+"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
+"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
+"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
+"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
+".*aaaaaaaaaaabbbbbaaaaaaaaaac***",
+".*aaaaaaaaaaabbbbbaaaaaaaaaac***",
+"..*aaaaaaaaaabbbbbaaaaaaaaac***.",
+"...caaaaaaabbbbbbbbbaaaaaac****.",
+"....caaaaaaaaaaaaaaaaaaaac****..",
+".....caaaaaaaaaaaaaaaaaac****...",
+"......ccaaaaaaaaaaaaaacc****....",
+".......*cccaaaaaaaaccc*****.....",
+"........***cccaaaac*******......",
+"..........****caaac*****........",
+".............*caaac**...........",
+"...............caac**...........",
+"................cac**...........",
+".................cc**...........",
+"..................***...........",
+"...................**..........."};
+/* XPM */
+static const char* const warning_xpm[]={
+"32 32 4 1",
+". c None",
+"a c #ffff00",
+"* c #000000",
+"b c #999999",
+".............***................",
+"............*aaa*...............",
+"...........*aaaaa*b.............",
+"...........*aaaaa*bb............",
+"..........*aaaaaaa*bb...........",
+"..........*aaaaaaa*bb...........",
+".........*aaaaaaaaa*bb..........",
+".........*aaaaaaaaa*bb..........",
+"........*aaaaaaaaaaa*bb.........",
+"........*aaaa***aaaa*bb.........",
+".......*aaaa*****aaaa*bb........",
+".......*aaaa*****aaaa*bb........",
+"......*aaaaa*****aaaaa*bb.......",
+"......*aaaaa*****aaaaa*bb.......",
+".....*aaaaaa*****aaaaaa*bb......",
+".....*aaaaaa*****aaaaaa*bb......",
+"....*aaaaaaaa***aaaaaaaa*bb.....",
+"....*aaaaaaaa***aaaaaaaa*bb.....",
+"...*aaaaaaaaa***aaaaaaaaa*bb....",
+"...*aaaaaaaaaa*aaaaaaaaaa*bb....",
+"..*aaaaaaaaaaa*aaaaaaaaaaa*bb...",
+"..*aaaaaaaaaaaaaaaaaaaaaaa*bb...",
+".*aaaaaaaaaaaa**aaaaaaaaaaa*bb..",
+".*aaaaaaaaaaa****aaaaaaaaaa*bb..",
+"*aaaaaaaaaaaa****aaaaaaaaaaa*bb.",
+"*aaaaaaaaaaaaa**aaaaaaaaaaaa*bb.",
+"*aaaaaaaaaaaaaaaaaaaaaaaaaaa*bbb",
+"*aaaaaaaaaaaaaaaaaaaaaaaaaaa*bbb",
+".*aaaaaaaaaaaaaaaaaaaaaaaaa*bbbb",
+"..*************************bbbbb",
+"....bbbbbbbbbbbbbbbbbbbbbbbbbbb.",
+".....bbbbbbbbbbbbbbbbbbbbbbbbb.."};
+/* XPM */
+static const char* const critical_xpm[]={
+"32 32 4 1",
+". c None",
+"a c #999999",
+"* c #ff0000",
+"b c #ffffff",
+"...........********.............",
+".........************...........",
+".......****************.........",
+"......******************........",
+".....********************a......",
+"....**********************a.....",
+"...************************a....",
+"..*******b**********b*******a...",
+"..******bbb********bbb******a...",
+".******bbbbb******bbbbb******a..",
+".*******bbbbb****bbbbb*******a..",
+"*********bbbbb**bbbbb*********a.",
+"**********bbbbbbbbbb**********a.",
+"***********bbbbbbbb***********aa",
+"************bbbbbb************aa",
+"************bbbbbb************aa",
+"***********bbbbbbbb***********aa",
+"**********bbbbbbbbbb**********aa",
+"*********bbbbb**bbbbb*********aa",
+".*******bbbbb****bbbbb*******aa.",
+".******bbbbb******bbbbb******aa.",
+"..******bbb********bbb******aaa.",
+"..*******b**********b*******aa..",
+"...************************aaa..",
+"....**********************aaa...",
+"....a********************aaa....",
+".....a******************aaa.....",
+"......a****************aaa......",
+".......aa************aaaa.......",
+".........aa********aaaaa........",
+"...........aaaaaaaaaaa..........",
+".............aaaaaaa............"};
+/* XPM */
+static const char *const question_xpm[] = {
+"32 32 5 1",
+". c None",
+"c c #000000",
+"* c #999999",
+"a c #ffffff",
+"b c #0000ff",
+"...........********.............",
+"........***aaaaaaaa***..........",
+"......**aaaaaaaaaaaaaa**........",
+".....*aaaaaaaaaaaaaaaaaa*.......",
+"....*aaaaaaaaaaaaaaaaaaaac......",
+"...*aaaaaaaabbbbbbaaaaaaaac.....",
+"..*aaaaaaaabaaabbbbaaaaaaaac....",
+".*aaaaaaaabbaaaabbbbaaaaaaaac...",
+".*aaaaaaaabbbbaabbbbaaaaaaaac*..",
+"*aaaaaaaaabbbbaabbbbaaaaaaaaac*.",
+"*aaaaaaaaaabbaabbbbaaaaaaaaaac*.",
+"*aaaaaaaaaaaaabbbbaaaaaaaaaaac**",
+"*aaaaaaaaaaaaabbbaaaaaaaaaaaac**",
+"*aaaaaaaaaaaaabbaaaaaaaaaaaaac**",
+"*aaaaaaaaaaaaabbaaaaaaaaaaaaac**",
+"*aaaaaaaaaaaaaaaaaaaaaaaaaaaac**",
+".*aaaaaaaaaaaabbaaaaaaaaaaaac***",
+".*aaaaaaaaaaabbbbaaaaaaaaaaac***",
+"..*aaaaaaaaaabbbbaaaaaaaaaac***.",
+"...caaaaaaaaaabbaaaaaaaaaac****.",
+"....caaaaaaaaaaaaaaaaaaaac****..",
+".....caaaaaaaaaaaaaaaaaac****...",
+"......ccaaaaaaaaaaaaaacc****....",
+".......*cccaaaaaaaaccc*****.....",
+"........***cccaaaac*******......",
+"..........****caaac*****........",
+".............*caaac**...........",
+"...............caac**...........",
+"................cac**...........",
+".................cc**...........",
+"..................***...........",
+"...................**..........."};
+
+#endif //QT_NO_IMAGEFORMAT_XPM
+
+#ifdef Q_WS_WIN
+static QPixmap loadIconFromShell32( int resourceId, int size )
+{
+#ifdef Q_OS_WINCE
+ HMODULE hmod = LoadLibrary(L"ceshell");
+#else
+ HMODULE hmod = QSystemLibrary::load(L"shell32");
+#endif
+ if( hmod ) {
+ HICON iconHandle = (HICON)LoadImage(hmod, MAKEINTRESOURCE(resourceId), IMAGE_ICON, size, size, 0);
+ if( iconHandle ) {
+ QPixmap iconpixmap = QPixmap::fromWinHICON( iconHandle );
+ DestroyIcon(iconHandle);
+ return iconpixmap;
+ }
+ }
+ return QPixmap();
+}
+#endif
+
+/*!
+ \reimp
+ */
+QPixmap QWindowsStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt,
+ const QWidget *widget) const
+{
+#if defined(Q_WS_WIN) && !defined(Q_OS_WINCE)
+ QPixmap desktopIcon;
+ switch(standardPixmap) {
+ case SP_DriveCDIcon:
+ case SP_DriveDVDIcon:
+ {
+ desktopIcon = loadIconFromShell32(12, 16);
+ break;
+ }
+ case SP_DriveNetIcon:
+ {
+ desktopIcon = loadIconFromShell32(10, 16);
+ break;
+ }
+ case SP_DriveHDIcon:
+ {
+ desktopIcon = loadIconFromShell32(9, 16);
+ break;
+ }
+ case SP_DriveFDIcon:
+ {
+ desktopIcon = loadIconFromShell32(7, 16);
+ break;
+ }
+ case SP_FileIcon:
+ {
+ desktopIcon = loadIconFromShell32(1, 16);
+ break;
+ }
+ case SP_FileLinkIcon:
+ {
+ desktopIcon = loadIconFromShell32(1, 16);
+ QPainter painter(&desktopIcon);
+ QPixmap link = loadIconFromShell32(30, 16);
+ painter.drawPixmap(0, 0, 16, 16, link);
+ break;
+ }
+ case SP_DirLinkIcon:
+ {
+ desktopIcon = loadIconFromShell32(4, 16);
+ QPainter painter(&desktopIcon);
+ QPixmap link = loadIconFromShell32(30, 16);
+ painter.drawPixmap(0, 0, 16, 16, link);
+ break;
+ }
+ case SP_DirClosedIcon:
+ {
+ desktopIcon = loadIconFromShell32(4, 16);
+ break;
+ }
+ case SP_DesktopIcon:
+ {
+ desktopIcon = loadIconFromShell32(35, 16);
+ break;
+ }
+ case SP_ComputerIcon:
+ {
+ desktopIcon = loadIconFromShell32(16, 16);
+ break;
+ }
+ case SP_DirOpenIcon:
+ {
+ desktopIcon = loadIconFromShell32(5, 16);
+ break;
+ }
+ case SP_FileDialogNewFolder:
+ {
+ desktopIcon = loadIconFromShell32(319, 16);
+ break;
+ }
+ case SP_DirHomeIcon:
+ {
+ desktopIcon = loadIconFromShell32(235, 16);
+ break;
+ }
+ case SP_TrashIcon:
+ {
+ desktopIcon = loadIconFromShell32(191, 16);
+ break;
+ }
+ case SP_MessageBoxInformation:
+ {
+ HICON iconHandle = LoadIcon(NULL, IDI_INFORMATION);
+ desktopIcon = QPixmap::fromWinHICON( iconHandle );
+ DestroyIcon(iconHandle);
+ break;
+ }
+ case SP_MessageBoxWarning:
+ {
+ HICON iconHandle = LoadIcon(NULL, IDI_WARNING);
+ desktopIcon = QPixmap::fromWinHICON( iconHandle );
+ DestroyIcon(iconHandle);
+ break;
+ }
+ case SP_MessageBoxCritical:
+ {
+ HICON iconHandle = LoadIcon(NULL, IDI_ERROR);
+ desktopIcon = QPixmap::fromWinHICON( iconHandle );
+ DestroyIcon(iconHandle);
+ break;
+ }
+ case SP_MessageBoxQuestion:
+ {
+ HICON iconHandle = LoadIcon(NULL, IDI_QUESTION);
+ desktopIcon = QPixmap::fromWinHICON( iconHandle );
+ DestroyIcon(iconHandle);
+ break;
+ }
+ case SP_VistaShield:
+ {
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA
+ && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based
+ && pSHGetStockIconInfo)
+ {
+ QPixmap pixmap;
+ QSHSTOCKICONINFO iconInfo;
+ memset(&iconInfo, 0, sizeof(iconInfo));
+ iconInfo.cbSize = sizeof(iconInfo);
+ if (pSHGetStockIconInfo(_SIID_SHIELD, _SHGFI_ICON | _SHGFI_SMALLICON, &iconInfo) == S_OK) {
+ pixmap = QPixmap::fromWinHICON(iconInfo.hIcon);
+ DestroyIcon(iconInfo.hIcon);
+ return pixmap;
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ if (!desktopIcon.isNull()) {
+ return desktopIcon;
+ }
+#endif
+#ifndef QT_NO_IMAGEFORMAT_XPM
+ switch (standardPixmap) {
+ case SP_TitleBarMenuButton:
+ return QPixmap(qt_menu_xpm);
+ case SP_TitleBarShadeButton:
+ return QPixmap(qt_shade_xpm);
+ case SP_TitleBarUnshadeButton:
+ return QPixmap(qt_unshade_xpm);
+ case SP_TitleBarNormalButton:
+ return QPixmap(qt_normalizeup_xpm);
+ case SP_TitleBarMinButton:
+ return QPixmap(qt_minimize_xpm);
+ case SP_TitleBarMaxButton:
+ return QPixmap(qt_maximize_xpm);
+ case SP_TitleBarCloseButton:
+ return QPixmap(qt_close_xpm);
+ case SP_TitleBarContextHelpButton:
+ return QPixmap(qt_help_xpm);
+ case SP_DockWidgetCloseButton:
+ return QPixmap(dock_widget_close_xpm);
+ case SP_MessageBoxInformation:
+ return QPixmap(information_xpm);
+ case SP_MessageBoxWarning:
+ return QPixmap(warning_xpm);
+ case SP_MessageBoxCritical:
+ return QPixmap(critical_xpm);
+ case SP_MessageBoxQuestion:
+ return QPixmap(question_xpm);
+ default:
+ break;
+ }
+#endif //QT_NO_IMAGEFORMAT_XPM
+ return QCommonStyle::standardPixmap(standardPixmap, opt, widget);
+}
+
+/*! \reimp */
+int QWindowsStyle::styleHint(StyleHint hint, const QStyleOption *opt, const QWidget *widget,
+ QStyleHintReturn *returnData) const
+{
+ int ret = 0;
+
+ switch (hint) {
+ case SH_EtchDisabledText:
+ case SH_Slider_SnapToValue:
+ case SH_PrintDialog_RightAlignButtons:
+ case SH_FontDialog_SelectAssociatedText:
+ case SH_Menu_AllowActiveAndDisabled:
+ case SH_MenuBar_AltKeyNavigation:
+ case SH_MenuBar_MouseTracking:
+ case SH_Menu_MouseTracking:
+ case SH_ComboBox_ListMouseTracking:
+ case SH_ScrollBar_StopMouseOverSlider:
+ case SH_MainWindow_SpaceBelowMenuBar:
+ ret = 1;
+
+ break;
+ case SH_ItemView_ShowDecorationSelected:
+#ifndef QT_NO_LISTVIEW
+ if (qobject_cast<const QListView*>(widget))
+ ret = 1;
+#endif
+ break;
+ case SH_ItemView_ChangeHighlightOnFocus:
+ ret = 1;
+ break;
+ case SH_ToolBox_SelectedPageTitleBold:
+ ret = 0;
+ break;
+
+#if defined(Q_WS_WIN)
+ case SH_UnderlineShortcut:
+ {
+ ret = 1;
+ BOOL cues = false;
+ SystemParametersInfo(SPI_GETKEYBOARDCUES, 0, &cues, 0);
+ ret = int(cues);
+ // Do nothing if we always paint underlines
+ Q_D(const QWindowsStyle);
+ if (!ret && widget && d) {
+#ifndef QT_NO_MENUBAR
+ const QMenuBar *menuBar = qobject_cast<const QMenuBar *>(widget);
+ if (!menuBar && qobject_cast<const QMenu *>(widget)) {
+ QWidget *w = QApplication::activeWindow();
+ if (w && w != widget)
+ menuBar = w->findChild<QMenuBar *>();
+ }
+ // If we paint a menu bar draw underlines if is in the keyboardState
+ if (menuBar) {
+ if (menuBar->d_func()->keyboardState || d->altDown())
+ ret = 1;
+ // Otherwise draw underlines if the toplevel widget has seen an alt-press
+ } else
+#endif // QT_NO_MENUBAR
+ if (d->hasSeenAlt(widget)) {
+ ret = 1;
+ }
+ }
+ break;
+ }
+#endif
+#ifndef QT_NO_RUBBERBAND
+ case SH_RubberBand_Mask:
+ if (const QStyleOptionRubberBand *rbOpt = qstyleoption_cast<const QStyleOptionRubberBand *>(opt)) {
+ ret = 0;
+ if (rbOpt->shape == QRubberBand::Rectangle) {
+ ret = true;
+ if(QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask*>(returnData)) {
+ mask->region = opt->rect;
+ int size = 1;
+ if (widget && widget->isWindow())
+ size = 4;
+ mask->region -= opt->rect.adjusted(size, size, -size, -size);
+ }
+ }
+ }
+ break;
+#endif // QT_NO_RUBBERBAND
+ case SH_LineEdit_PasswordCharacter:
+ {
+#ifdef Q_WS_WIN
+ if (widget && (QSysInfo::WindowsVersion >= QSysInfo::WV_XP && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)) {
+ const QFontMetrics &fm = widget->fontMetrics();
+ if (fm.inFont(QChar(0x25CF)))
+ ret = 0x25CF;
+ else if (fm.inFont(QChar(0x2022)))
+ ret = 0x2022;
+ }
+#endif
+ if (!ret)
+ ret = '*';
+ }
+ break;
+#ifndef QT_NO_WIZARD
+ case SH_WizardStyle:
+ ret = QWizard::ModernStyle;
+ break;
+#endif
+ case SH_ItemView_ArrowKeysNavigateIntoChildren:
+ ret = true;
+ break;
+ case SH_DialogButtonBox_ButtonsHaveIcons:
+ ret = 0;
+ break;
+ default:
+ ret = QCommonStyle::styleHint(hint, opt, widget, returnData);
+ break;
+ }
+ return ret;
+}
+
+/*! \reimp */
+void QWindowsStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p,
+ const QWidget *w) const
+{
+ // Used to restore across fallthrough cases. Currently only used in PE_IndicatorCheckBox
+ bool doRestore = false;
+
+ switch (pe) {
+#ifndef QT_NO_TOOLBAR
+ case PE_IndicatorToolBarSeparator:
+ {
+ QRect rect = opt->rect;
+ const int margin = 2;
+ QPen oldPen = p->pen();
+ if(opt->state & State_Horizontal){
+ const int offset = rect.width()/2;
+ p->setPen(QPen(opt->palette.dark().color()));
+ p->drawLine(rect.bottomLeft().x() + offset,
+ rect.bottomLeft().y() - margin,
+ rect.topLeft().x() + offset,
+ rect.topLeft().y() + margin);
+ p->setPen(QPen(opt->palette.light().color()));
+ p->drawLine(rect.bottomLeft().x() + offset + 1,
+ rect.bottomLeft().y() - margin,
+ rect.topLeft().x() + offset + 1,
+ rect.topLeft().y() + margin);
+ }
+ else{ //Draw vertical separator
+ const int offset = rect.height()/2;
+ p->setPen(QPen(opt->palette.dark().color()));
+ p->drawLine(rect.topLeft().x() + margin ,
+ rect.topLeft().y() + offset,
+ rect.topRight().x() - margin,
+ rect.topRight().y() + offset);
+ p->setPen(QPen(opt->palette.light().color()));
+ p->drawLine(rect.topLeft().x() + margin ,
+ rect.topLeft().y() + offset + 1,
+ rect.topRight().x() - margin,
+ rect.topRight().y() + offset + 1);
+ }
+ p->setPen(oldPen);
+ }
+ break;
+ case PE_IndicatorToolBarHandle:
+ p->save();
+ p->translate(opt->rect.x(), opt->rect.y());
+ if (opt->state & State_Horizontal) {
+ int x = opt->rect.width() / 2 - 4;
+ if (opt->direction == Qt::RightToLeft)
+ x -= 2;
+ if (opt->rect.height() > 4) {
+ qDrawShadePanel(p, x, 2, 3, opt->rect.height() - 4,
+ opt->palette, false, 1, 0);
+ qDrawShadePanel(p, x + 3, 2, 3, opt->rect.height() - 4,
+ opt->palette, false, 1, 0);
+ }
+ } else {
+ if (opt->rect.width() > 4) {
+ int y = opt->rect.height() / 2 - 4;
+ qDrawShadePanel(p, 2, y, opt->rect.width() - 4, 3,
+ opt->palette, false, 1, 0);
+ qDrawShadePanel(p, 2, y + 3, opt->rect.width() - 4, 3,
+ opt->palette, false, 1, 0);
+ }
+ }
+ p->restore();
+ break;
+
+#endif // QT_NO_TOOLBAR
+ case PE_FrameButtonTool:
+ case PE_PanelButtonTool: {
+ QPen oldPen = p->pen();
+#ifndef QT_NO_DOCKWIDGET
+ if (w && w->inherits("QDockWidgetTitleButton")) {
+ if (const QWidget *dw = w->parentWidget())
+ if (dw->isWindow()){
+ qDrawWinButton(p, opt->rect.adjusted(1, 1, 0, 0), opt->palette, opt->state & (State_Sunken | State_On),
+ &opt->palette.button());
+
+ return;
+ }
+ }
+#endif // QT_NO_DOCKWIDGET
+ QBrush fill;
+ bool stippled;
+ bool panel = (pe == PE_PanelButtonTool);
+ if ((!(opt->state & State_Sunken ))
+ && (!(opt->state & State_Enabled)
+ || !(opt->state & State_MouseOver && opt->state & State_AutoRaise))
+ && (opt->state & State_On)) {
+ fill = QBrush(opt->palette.light().color(), Qt::Dense4Pattern);
+ stippled = true;
+ } else {
+ fill = opt->palette.brush(QPalette::Button);
+ stippled = false;
+ }
+
+ if (opt->state & (State_Raised | State_Sunken | State_On)) {
+ if (opt->state & State_AutoRaise) {
+ if(opt->state & (State_Enabled | State_Sunken | State_On)){
+ if (panel)
+ qDrawShadePanel(p, opt->rect, opt->palette,
+ opt->state & (State_Sunken | State_On), 1, &fill);
+ else
+ qDrawShadeRect(p, opt->rect, opt->palette,
+ opt->state & (State_Sunken | State_On), 1);
+ }
+ if (stippled) {
+ p->setPen(opt->palette.button().color());
+ p->drawRect(opt->rect.adjusted(1,1,-2,-2));
+ }
+ } else {
+ qDrawWinButton(p, opt->rect, opt->palette,
+ opt->state & (State_Sunken | State_On), panel ? &fill : 0);
+ }
+ } else {
+ p->fillRect(opt->rect, fill);
+ }
+ p->setPen(oldPen);
+ break; }
+ case PE_PanelButtonCommand:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
+ QBrush fill;
+ State flags = opt->state;
+ QPalette pal = opt->palette;
+ QRect r = opt->rect;
+ if (! (flags & State_Sunken) && (flags & State_On))
+ fill = QBrush(pal.light().color(), Qt::Dense4Pattern);
+ else
+ fill = pal.brush(QPalette::Button);
+
+ if (btn->features & QStyleOptionButton::DefaultButton && flags & State_Sunken) {
+ p->setPen(pal.dark().color());
+ p->setBrush(fill);
+ p->drawRect(r.adjusted(0, 0, -1, -1));
+ } else if (flags & (State_Raised | State_Sunken | State_On | State_Sunken)) {
+ qDrawWinButton(p, r, pal, flags & (State_Sunken | State_On),
+ &fill);
+ } else {
+ p->fillRect(r, fill);
+ }
+ }
+ break;
+ case PE_FrameDefaultButton: {
+ QPen oldPen = p->pen();
+ p->setPen(opt->palette.shadow().color());
+ QRect rect = opt->rect;
+ rect.adjust(0, 0, -1, -1);
+ p->drawRect(rect);
+ p->setPen(oldPen);
+ break;
+ }
+ case PE_IndicatorArrowUp:
+ case PE_IndicatorArrowDown:
+ case PE_IndicatorArrowRight:
+ case PE_IndicatorArrowLeft:
+ {
+ if (opt->rect.width() <= 1 || opt->rect.height() <= 1)
+ break;
+ QRect r = opt->rect;
+ int size = qMin(r.height(), r.width());
+ QPixmap pixmap;
+ QString pixmapName = QStyleHelper::uniqueName(QLatin1String("$qt_ia-")
+ % QLatin1String(metaObject()->className()), opt, QSize(size, size))
+ % HexString<uint>(pe);
+ if (!QPixmapCache::find(pixmapName, pixmap)) {
+ int border = size/5;
+ int sqsize = 2*(size/2);
+ QImage image(sqsize, sqsize, QImage::Format_ARGB32_Premultiplied);
+ image.fill(0);
+ QPainter imagePainter(&image);
+
+ QPolygon a;
+ switch (pe) {
+ case PE_IndicatorArrowUp:
+ a.setPoints(3, border, sqsize/2, sqsize/2, border, sqsize - border, sqsize/2);
+ break;
+ case PE_IndicatorArrowDown:
+ a.setPoints(3, border, sqsize/2, sqsize/2, sqsize - border, sqsize - border, sqsize/2);
+ break;
+ case PE_IndicatorArrowRight:
+ a.setPoints(3, sqsize - border, sqsize/2, sqsize/2, border, sqsize/2, sqsize - border);
+ break;
+ case PE_IndicatorArrowLeft:
+ a.setPoints(3, border, sqsize/2, sqsize/2, border, sqsize/2, sqsize - border);
+ break;
+ default:
+ break;
+ }
+
+ int bsx = 0;
+ int bsy = 0;
+
+ if (opt->state & State_Sunken) {
+ bsx = proxy()->pixelMetric(PM_ButtonShiftHorizontal, opt, w);
+ bsy = proxy()->pixelMetric(PM_ButtonShiftVertical, opt, w);
+ }
+
+ QRect bounds = a.boundingRect();
+ int sx = sqsize / 2 - bounds.center().x() - 1;
+ int sy = sqsize / 2 - bounds.center().y() - 1;
+ imagePainter.translate(sx + bsx, sy + bsy);
+ imagePainter.setPen(opt->palette.buttonText().color());
+ imagePainter.setBrush(opt->palette.buttonText());
+
+ if (!(opt->state & State_Enabled)) {
+ imagePainter.translate(1, 1);
+ imagePainter.setBrush(opt->palette.light().color());
+ imagePainter.setPen(opt->palette.light().color());
+ imagePainter.drawPolygon(a);
+ imagePainter.translate(-1, -1);
+ imagePainter.setBrush(opt->palette.mid().color());
+ imagePainter.setPen(opt->palette.mid().color());
+ }
+
+ imagePainter.drawPolygon(a);
+ imagePainter.end();
+ pixmap = QPixmap::fromImage(image);
+ QPixmapCache::insert(pixmapName, pixmap);
+ }
+ int xOffset = r.x() + (r.width() - size)/2;
+ int yOffset = r.y() + (r.height() - size)/2;
+ p->drawPixmap(xOffset, yOffset, pixmap);
+ }
+ break;
+ case PE_IndicatorCheckBox: {
+ QBrush fill;
+ if (opt->state & State_NoChange)
+ fill = QBrush(opt->palette.base().color(), Qt::Dense4Pattern);
+ else if (opt->state & State_Sunken)
+ fill = opt->palette.button();
+ else if (opt->state & State_Enabled)
+ fill = opt->palette.base();
+ else
+ fill = opt->palette.background();
+ p->save();
+ doRestore = true;
+ qDrawWinPanel(p, opt->rect, opt->palette, true, &fill);
+ if (opt->state & State_NoChange)
+ p->setPen(opt->palette.dark().color());
+ else
+ p->setPen(opt->palette.text().color());
+ } // Fall through!
+ case PE_IndicatorViewItemCheck:
+ case PE_Q3CheckListIndicator:
+ if (!doRestore) {
+ p->save();
+ doRestore = true;
+ }
+ if (pe == PE_Q3CheckListIndicator || pe == PE_IndicatorViewItemCheck) {
+ const QStyleOptionViewItem *itemViewOpt = qstyleoption_cast<const QStyleOptionViewItem *>(opt);
+ p->setPen(itemViewOpt
+ && itemViewOpt->showDecorationSelected
+ && opt->state & State_Selected
+ ? opt->palette.highlightedText().color()
+ : opt->palette.text().color());
+ if (opt->state & State_NoChange)
+ p->setBrush(opt->palette.brush(QPalette::Button));
+ p->drawRect(opt->rect.x() + 1, opt->rect.y() + 1, 11, 11);
+ }
+ if (!(opt->state & State_Off)) {
+ QLineF lines[7];
+ int i, xx, yy;
+ xx = opt->rect.x() + 3;
+ yy = opt->rect.y() + 5;
+ for (i = 0; i < 3; ++i) {
+ lines[i] = QLineF(xx, yy, xx, yy + 2);
+ ++xx;
+ ++yy;
+ }
+ yy -= 2;
+ for (i = 3; i < 7; ++i) {
+ lines[i] = QLineF(xx, yy, xx, yy + 2);
+ ++xx;
+ --yy;
+ }
+ p->drawLines(lines, 7);
+ }
+ if (doRestore)
+ p->restore();
+ break;
+ case PE_FrameFocusRect:
+ if (const QStyleOptionFocusRect *fropt = qstyleoption_cast<const QStyleOptionFocusRect *>(opt)) {
+ //### check for d->alt_down
+ if (!(fropt->state & State_KeyboardFocusChange) && !proxy()->styleHint(SH_UnderlineShortcut, opt))
+ return;
+ QRect r = opt->rect;
+ p->save();
+ p->setBackgroundMode(Qt::TransparentMode);
+ QColor bg_col = fropt->backgroundColor;
+ if (!bg_col.isValid())
+ bg_col = p->background().color();
+ // Create an "XOR" color.
+ QColor patternCol((bg_col.red() ^ 0xff) & 0xff,
+ (bg_col.green() ^ 0xff) & 0xff,
+ (bg_col.blue() ^ 0xff) & 0xff);
+ p->setBrush(QBrush(patternCol, Qt::Dense4Pattern));
+ p->setBrushOrigin(r.topLeft());
+ p->setPen(Qt::NoPen);
+ p->drawRect(r.left(), r.top(), r.width(), 1); // Top
+ p->drawRect(r.left(), r.bottom(), r.width(), 1); // Bottom
+ p->drawRect(r.left(), r.top(), 1, r.height()); // Left
+ p->drawRect(r.right(), r.top(), 1, r.height()); // Right
+ p->restore();
+ }
+ break;
+ case PE_IndicatorRadioButton:
+ {
+#define PTSARRLEN(x) sizeof(x)/(sizeof(QPoint))
+ static const QPoint pts1[] = { // dark lines
+ QPoint(1, 9), QPoint(1, 8), QPoint(0, 7), QPoint(0, 4), QPoint(1, 3), QPoint(1, 2),
+ QPoint(2, 1), QPoint(3, 1), QPoint(4, 0), QPoint(7, 0), QPoint(8, 1), QPoint(9, 1)
+ };
+ static const QPoint pts2[] = { // black lines
+ QPoint(2, 8), QPoint(1, 7), QPoint(1, 4), QPoint(2, 3), QPoint(2, 2), QPoint(3, 2),
+ QPoint(4, 1), QPoint(7, 1), QPoint(8, 2), QPoint(9, 2)
+ };
+ static const QPoint pts3[] = { // background lines
+ QPoint(2, 9), QPoint(3, 9), QPoint(4, 10), QPoint(7, 10), QPoint(8, 9), QPoint(9, 9),
+ QPoint(9, 8), QPoint(10, 7), QPoint(10, 4), QPoint(9, 3)
+ };
+ static const QPoint pts4[] = { // white lines
+ QPoint(2, 10), QPoint(3, 10), QPoint(4, 11), QPoint(7, 11), QPoint(8, 10),
+ QPoint(9, 10), QPoint(10, 9), QPoint(10, 8), QPoint(11, 7), QPoint(11, 4),
+ QPoint(10, 3), QPoint(10, 2)
+ };
+ static const QPoint pts5[] = { // inner fill
+ QPoint(4, 2), QPoint(7, 2), QPoint(9, 4), QPoint(9, 7), QPoint(7, 9), QPoint(4, 9),
+ QPoint(2, 7), QPoint(2, 4)
+ };
+
+ // make sure the indicator is square
+ QRect ir = opt->rect;
+
+ if (opt->rect.width() < opt->rect.height()) {
+ ir.setTop(opt->rect.top() + (opt->rect.height() - opt->rect.width()) / 2);
+ ir.setHeight(opt->rect.width());
+ } else if (opt->rect.height() < opt->rect.width()) {
+ ir.setLeft(opt->rect.left() + (opt->rect.width() - opt->rect.height()) / 2);
+ ir.setWidth(opt->rect.height());
+ }
+
+ p->save();
+ bool down = opt->state & State_Sunken;
+ bool enabled = opt->state & State_Enabled;
+ bool on = opt->state & State_On;
+ QPolygon a;
+
+ //center when rect is larger than indicator size
+ int xOffset = 0;
+ int yOffset = 0;
+ int indicatorWidth = proxy()->pixelMetric(PM_ExclusiveIndicatorWidth);
+ int indicatorHeight = proxy()->pixelMetric(PM_ExclusiveIndicatorWidth);
+ if (ir.width() > indicatorWidth)
+ xOffset += (ir.width() - indicatorWidth)/2;
+ if (ir.height() > indicatorHeight)
+ yOffset += (ir.height() - indicatorHeight)/2;
+ p->translate(xOffset, yOffset);
+
+ p->translate(ir.x(), ir.y());
+
+ p->setPen(opt->palette.dark().color());
+ p->drawPolyline(pts1, PTSARRLEN(pts1));
+
+ p->setPen(opt->palette.shadow().color());
+ p->drawPolyline(pts2, PTSARRLEN(pts2));
+
+ p->setPen(opt->palette.midlight().color());
+ p->drawPolyline(pts3, PTSARRLEN(pts3));
+
+ p->setPen(opt->palette.light().color());
+ p->drawPolyline(pts4, PTSARRLEN(pts4));
+
+ QColor fillColor = (down || !enabled)
+ ? opt->palette.button().color()
+ : opt->palette.base().color();
+ p->setPen(fillColor);
+ p->setBrush(fillColor) ;
+ p->drawPolygon(pts5, PTSARRLEN(pts5));
+
+ p->translate(-ir.x(), -ir.y()); // restore translate
+
+ if (on) {
+ p->setPen(Qt::NoPen);
+ p->setBrush(opt->palette.text());
+ p->drawRect(ir.x() + 5, ir.y() + 4, 2, 4);
+ p->drawRect(ir.x() + 4, ir.y() + 5, 4, 2);
+ }
+ p->restore();
+ break;
+ }
+#ifndef QT_NO_FRAME
+ case PE_Frame:
+ case PE_FrameMenu:
+ if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
+ if (frame->lineWidth == 2 || pe == PE_Frame) {
+ QPalette popupPal = frame->palette;
+ if (pe == PE_FrameMenu) {
+ popupPal.setColor(QPalette::Light, frame->palette.background().color());
+ popupPal.setColor(QPalette::Midlight, frame->palette.light().color());
+ }
+ if (pe == PE_Frame && (frame->state & State_Raised))
+ qDrawWinButton(p, frame->rect, popupPal, frame->state & State_Sunken);
+ else if (pe == PE_Frame && (frame->state & State_Sunken))
+ {
+ popupPal.setColor(QPalette::Midlight, frame->palette.background().color());
+ qDrawWinPanel(p, frame->rect, popupPal, frame->state & State_Sunken);
+ }
+ else
+ qDrawWinPanel(p, frame->rect, popupPal, frame->state & State_Sunken);
+ } else {
+ QCommonStyle::drawPrimitive(pe, opt, p, w);
+ }
+ } else {
+ QPalette popupPal = opt->palette;
+ popupPal.setColor(QPalette::Light, opt->palette.background().color());
+ popupPal.setColor(QPalette::Midlight, opt->palette.light().color());
+ qDrawWinPanel(p, opt->rect, popupPal, opt->state & State_Sunken);
+ }
+ break;
+#endif // QT_NO_FRAME
+ case PE_IndicatorBranch: {
+ // This is _way_ too similar to the common style.
+ static const int decoration_size = 9;
+ int mid_h = opt->rect.x() + opt->rect.width() / 2;
+ int mid_v = opt->rect.y() + opt->rect.height() / 2;
+ int bef_h = mid_h;
+ int bef_v = mid_v;
+ int aft_h = mid_h;
+ int aft_v = mid_v;
+ if (opt->state & State_Children) {
+ int delta = decoration_size / 2;
+ bef_h -= delta;
+ bef_v -= delta;
+ aft_h += delta;
+ aft_v += delta;
+ p->drawLine(bef_h + 2, bef_v + 4, bef_h + 6, bef_v + 4);
+ if (!(opt->state & State_Open))
+ p->drawLine(bef_h + 4, bef_v + 2, bef_h + 4, bef_v + 6);
+ QPen oldPen = p->pen();
+ p->setPen(opt->palette.dark().color());
+ p->drawRect(bef_h, bef_v, decoration_size - 1, decoration_size - 1);
+ p->setPen(oldPen);
+ }
+ QBrush brush(opt->palette.dark().color(), Qt::Dense4Pattern);
+ if (opt->state & State_Item) {
+ if (opt->direction == Qt::RightToLeft)
+ p->fillRect(opt->rect.left(), mid_v, bef_h - opt->rect.left(), 1, brush);
+ else
+ p->fillRect(aft_h, mid_v, opt->rect.right() - aft_h + 1, 1, brush);
+ }
+ if (opt->state & State_Sibling)
+ p->fillRect(mid_h, aft_v, 1, opt->rect.bottom() - aft_v + 1, brush);
+ if (opt->state & (State_Open | State_Children | State_Item | State_Sibling))
+ p->fillRect(mid_h, opt->rect.y(), 1, bef_v - opt->rect.y(), brush);
+ break; }
+ case PE_FrameButtonBevel:
+ case PE_PanelButtonBevel: {
+ QBrush fill;
+ bool panel = pe != PE_FrameButtonBevel;
+ p->setBrushOrigin(opt->rect.topLeft());
+ if (!(opt->state & State_Sunken) && (opt->state & State_On))
+ fill = QBrush(opt->palette.light().color(), Qt::Dense4Pattern);
+ else
+ fill = opt->palette.brush(QPalette::Button);
+
+ if (opt->state & (State_Raised | State_On | State_Sunken)) {
+ qDrawWinButton(p, opt->rect, opt->palette, opt->state & (State_Sunken | State_On),
+ panel ? &fill : 0);
+ } else {
+ if (panel)
+ p->fillRect(opt->rect, fill);
+ else
+ p->drawRect(opt->rect);
+ }
+ break; }
+ case PE_FrameWindow: {
+ QPalette popupPal = opt->palette;
+ popupPal.setColor(QPalette::Light, opt->palette.background().color());
+ popupPal.setColor(QPalette::Midlight, opt->palette.light().color());
+ qDrawWinPanel(p, opt->rect, popupPal, opt->state & State_Sunken);
+ break; }
+#ifndef QT_NO_DOCKWIDGET
+ case PE_IndicatorDockWidgetResizeHandle: {
+ QPen oldPen = p->pen();
+ p->setPen(opt->palette.light().color());
+ if (opt->state & State_Horizontal) {
+ p->drawLine(opt->rect.left(), opt->rect.top(),
+ opt->rect.right(), opt->rect.top());
+ p->setPen(opt->palette.dark().color());
+ p->drawLine(opt->rect.left(), opt->rect.bottom() - 1,
+ opt->rect.right(), opt->rect.bottom() - 1);
+ p->setPen(opt->palette.shadow().color());
+ p->drawLine(opt->rect.left(), opt->rect.bottom(),
+ opt->rect.right(), opt->rect.bottom());
+ } else {
+ p->drawLine(opt->rect.left(), opt->rect.top(),
+ opt->rect.left(), opt->rect.bottom());
+ p->setPen(opt->palette.dark().color());
+ p->drawLine(opt->rect.right() - 1, opt->rect.top(),
+ opt->rect.right() - 1, opt->rect.bottom());
+ p->setPen(opt->palette.shadow().color());
+ p->drawLine(opt->rect.right(), opt->rect.top(),
+ opt->rect.right(), opt->rect.bottom());
+ }
+ p->setPen(oldPen);
+ break; }
+case PE_FrameDockWidget:
+ if (qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
+ proxy()->drawPrimitive(QStyle::PE_FrameWindow, opt, p, w);
+ }
+ break;
+#endif // QT_NO_DOCKWIDGET
+
+ case PE_FrameStatusBarItem:
+ qDrawShadePanel(p, opt->rect, opt->palette, true, 1, 0);
+ break;
+
+#ifndef QT_NO_PROGRESSBAR
+ case PE_IndicatorProgressChunk:
+ {
+ bool vertical = false, inverted = false;
+ if (const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(opt)) {
+ vertical = (pb2->orientation == Qt::Vertical);
+ inverted = pb2->invertedAppearance;
+ }
+
+ int space = 2;
+ int chunksize = proxy()->pixelMetric(PM_ProgressBarChunkWidth, opt, w) - space;
+ if (!vertical) {
+ if (opt->rect.width() <= chunksize)
+ space = 0;
+
+ if (inverted)
+ p->fillRect(opt->rect.x() + space, opt->rect.y(), opt->rect.width() - space, opt->rect.height(),
+ opt->palette.brush(QPalette::Highlight));
+ else
+ p->fillRect(opt->rect.x(), opt->rect.y(), opt->rect.width() - space, opt->rect.height(),
+ opt->palette.brush(QPalette::Highlight));
+ } else {
+ if (opt->rect.height() <= chunksize)
+ space = 0;
+
+ if (inverted)
+ p->fillRect(opt->rect.x(), opt->rect.y(), opt->rect.width(), opt->rect.height() - space,
+ opt->palette.brush(QPalette::Highlight));
+ else
+ p->fillRect(opt->rect.x(), opt->rect.y() + space, opt->rect.width(), opt->rect.height() - space,
+ opt->palette.brush(QPalette::Highlight));
+ }
+ }
+ break;
+#endif // QT_NO_PROGRESSBAR
+
+ case PE_FrameTabWidget: {
+ qDrawWinButton(p, opt->rect, opt->palette, false, 0);
+ break;
+ }
+ default:
+ QCommonStyle::drawPrimitive(pe, opt, p, w);
+ }
+}
+
+/*! \reimp */
+void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter *p,
+ const QWidget *widget) const
+{
+ switch (ce) {
+#ifndef QT_NO_RUBBERBAND
+ case CE_RubberBand:
+ if (qstyleoption_cast<const QStyleOptionRubberBand *>(opt)) {
+ // ### workaround for slow general painter path
+ QPixmap tiledPixmap(16, 16);
+ QPainter pixmapPainter(&tiledPixmap);
+ pixmapPainter.setPen(Qt::NoPen);
+ pixmapPainter.setBrush(Qt::Dense4Pattern);
+ pixmapPainter.setBackground(Qt::white);
+ pixmapPainter.setBackgroundMode(Qt::OpaqueMode);
+ pixmapPainter.drawRect(0, 0, tiledPixmap.width(), tiledPixmap.height());
+ pixmapPainter.end();
+ tiledPixmap = QPixmap::fromImage(tiledPixmap.toImage());
+ p->save();
+ QRect r = opt->rect;
+ QStyleHintReturnMask mask;
+ if (proxy()->styleHint(QStyle::SH_RubberBand_Mask, opt, widget, &mask))
+ p->setClipRegion(mask.region);
+ p->drawTiledPixmap(r.x(), r.y(), r.width(), r.height(), tiledPixmap);
+ p->restore();
+ return;
+ }
+ break;
+#endif // QT_NO_RUBBERBAND
+
+#if !defined(QT_NO_MENU) && !defined(QT_NO_MAINWINDOW)
+ case CE_MenuBarEmptyArea:
+ if (widget && qobject_cast<const QMainWindow *>(widget->parentWidget())) {
+ p->fillRect(opt->rect, opt->palette.button());
+ QPen oldPen = p->pen();
+ p->setPen(QPen(opt->palette.dark().color()));
+ p->drawLine(opt->rect.bottomLeft(), opt->rect.bottomRight());
+ p->setPen(oldPen);
+ }
+ break;
+#endif
+#ifndef QT_NO_MENU
+ case CE_MenuItem:
+ if (const QStyleOptionMenuItem *menuitem = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
+ int x, y, w, h;
+ menuitem->rect.getRect(&x, &y, &w, &h);
+ int tab = menuitem->tabWidth;
+ bool dis = !(menuitem->state & State_Enabled);
+ bool checked = menuitem->checkType != QStyleOptionMenuItem::NotCheckable
+ ? menuitem->checked : false;
+ bool act = menuitem->state & State_Selected;
+
+ // windows always has a check column, regardless whether we have an icon or not
+ int checkcol = qMax<int>(menuitem->maxIconWidth, QWindowsStylePrivate::windowsCheckMarkWidth);
+
+ QBrush fill = menuitem->palette.brush(act ? QPalette::Highlight : QPalette::Button);
+ p->fillRect(menuitem->rect.adjusted(0, 0, -1, 0), fill);
+
+ if (menuitem->menuItemType == QStyleOptionMenuItem::Separator){
+ int yoff = y-1 + h / 2;
+ p->setPen(menuitem->palette.dark().color());
+ p->drawLine(x + 2, yoff, x + w - 4, yoff);
+ p->setPen(menuitem->palette.light().color());
+ p->drawLine(x + 2, yoff + 1, x + w - 4, yoff + 1);
+ return;
+ }
+
+ QRect vCheckRect = visualRect(opt->direction, menuitem->rect, QRect(menuitem->rect.x(), menuitem->rect.y(), checkcol, menuitem->rect.height()));
+ if (!menuitem->icon.isNull() && checked) {
+ if (act) {
+ qDrawShadePanel(p, vCheckRect,
+ menuitem->palette, true, 1,
+ &menuitem->palette.brush(QPalette::Button));
+ } else {
+ QBrush fill(menuitem->palette.light().color(), Qt::Dense4Pattern);
+ qDrawShadePanel(p, vCheckRect, menuitem->palette, true, 1, &fill);
+ }
+ } else if (!act) {
+ p->fillRect(vCheckRect, menuitem->palette.brush(QPalette::Button));
+ }
+
+ // On Windows Style, if we have a checkable item and an icon we
+ // draw the icon recessed to indicate an item is checked. If we
+ // have no icon, we draw a checkmark instead.
+ if (!menuitem->icon.isNull()) {
+ QIcon::Mode mode = dis ? QIcon::Disabled : QIcon::Normal;
+ if (act && !dis)
+ mode = QIcon::Active;
+ QPixmap pixmap;
+ if (checked)
+ pixmap = menuitem->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, opt, widget), mode, QIcon::On);
+ else
+ pixmap = menuitem->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, opt, widget), mode);
+ int pixw = pixmap.width();
+ int pixh = pixmap.height();
+ if (act && !dis && !checked)
+ qDrawShadePanel(p, vCheckRect, menuitem->palette, false, 1,
+ &menuitem->palette.brush(QPalette::Button));
+ QRect pmr(0, 0, pixw, pixh);
+ pmr.moveCenter(vCheckRect.center());
+ p->setPen(menuitem->palette.text().color());
+ p->drawPixmap(pmr.topLeft(), pixmap);
+ } else if (checked) {
+ QStyleOptionMenuItem newMi = *menuitem;
+ newMi.state = State_None;
+ if (!dis)
+ newMi.state |= State_Enabled;
+ if (act)
+ newMi.state |= State_On;
+ newMi.rect = visualRect(opt->direction, menuitem->rect, QRect(menuitem->rect.x() + QWindowsStylePrivate::windowsItemFrame,
+ menuitem->rect.y() + QWindowsStylePrivate::windowsItemFrame,
+ checkcol - 2 * QWindowsStylePrivate::windowsItemFrame,
+ menuitem->rect.height() - 2 * QWindowsStylePrivate::windowsItemFrame));
+ proxy()->drawPrimitive(PE_IndicatorMenuCheckMark, &newMi, p, widget);
+ }
+ p->setPen(act ? menuitem->palette.highlightedText().color() : menuitem->palette.buttonText().color());
+
+ QColor discol;
+ if (dis) {
+ discol = menuitem->palette.text().color();
+ p->setPen(discol);
+ }
+
+ int xm = int(QWindowsStylePrivate::windowsItemFrame) + checkcol + int(QWindowsStylePrivate::windowsItemHMargin);
+ int xpos = menuitem->rect.x() + xm;
+ QRect textRect(xpos, y + QWindowsStylePrivate::windowsItemVMargin,
+ w - xm - QWindowsStylePrivate::windowsRightBorder - tab + 1, h - 2 * QWindowsStylePrivate::windowsItemVMargin);
+ QRect vTextRect = visualRect(opt->direction, menuitem->rect, textRect);
+ QString s = menuitem->text;
+ if (!s.isEmpty()) { // draw text
+ p->save();
+ int t = s.indexOf(QLatin1Char('\t'));
+ int text_flags = Qt::AlignVCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
+ if (!proxy()->styleHint(SH_UnderlineShortcut, menuitem, widget))
+ text_flags |= Qt::TextHideMnemonic;
+ text_flags |= Qt::AlignLeft;
+ if (t >= 0) {
+ QRect vShortcutRect = visualRect(opt->direction, menuitem->rect,
+ QRect(textRect.topRight(), QPoint(menuitem->rect.right(), textRect.bottom())));
+ if (dis && !act && proxy()->styleHint(SH_EtchDisabledText, opt, widget)) {
+ p->setPen(menuitem->palette.light().color());
+ p->drawText(vShortcutRect.adjusted(1,1,1,1), text_flags, s.mid(t + 1));
+ p->setPen(discol);
+ }
+ p->drawText(vShortcutRect, text_flags, s.mid(t + 1));
+ s = s.left(t);
+ }
+ QFont font = menuitem->font;
+ if (menuitem->menuItemType == QStyleOptionMenuItem::DefaultItem)
+ font.setBold(true);
+ p->setFont(font);
+ if (dis && !act && proxy()->styleHint(SH_EtchDisabledText, opt, widget)) {
+ p->setPen(menuitem->palette.light().color());
+ p->drawText(vTextRect.adjusted(1,1,1,1), text_flags, s.left(t));
+ p->setPen(discol);
+ }
+ p->drawText(vTextRect, text_flags, s.left(t));
+ p->restore();
+ }
+ if (menuitem->menuItemType == QStyleOptionMenuItem::SubMenu) {// draw sub menu arrow
+ int dim = (h - 2 * QWindowsStylePrivate::windowsItemFrame) / 2;
+ PrimitiveElement arrow;
+ arrow = (opt->direction == Qt::RightToLeft) ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight;
+ xpos = x + w - QWindowsStylePrivate::windowsArrowHMargin - QWindowsStylePrivate::windowsItemFrame - dim;
+ QRect vSubMenuRect = visualRect(opt->direction, menuitem->rect, QRect(xpos, y + h / 2 - dim / 2, dim, dim));
+ QStyleOptionMenuItem newMI = *menuitem;
+ newMI.rect = vSubMenuRect;
+ newMI.state = dis ? State_None : State_Enabled;
+ if (act)
+ newMI.palette.setColor(QPalette::ButtonText,
+ newMI.palette.highlightedText().color());
+ proxy()->drawPrimitive(arrow, &newMI, p, widget);
+ }
+
+ }
+ break;
+#endif // QT_NO_MENU
+#ifndef QT_NO_MENUBAR
+ case CE_MenuBarItem:
+ if (const QStyleOptionMenuItem *mbi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
+ bool active = mbi->state & State_Selected;
+ bool hasFocus = mbi->state & State_HasFocus;
+ bool down = mbi->state & State_Sunken;
+ QStyleOptionMenuItem newMbi = *mbi;
+ p->fillRect(mbi->rect, mbi->palette.brush(QPalette::Button));
+ if (active || hasFocus) {
+ QBrush b = mbi->palette.brush(QPalette::Button);
+ if (active && down)
+ p->setBrushOrigin(p->brushOrigin() + QPoint(1, 1));
+ if (active && hasFocus)
+ qDrawShadeRect(p, mbi->rect.x(), mbi->rect.y(), mbi->rect.width(),
+ mbi->rect.height(), mbi->palette, active && down, 1, 0, &b);
+ if (active && down) {
+ newMbi.rect.translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, mbi, widget),
+ proxy()->pixelMetric(PM_ButtonShiftVertical, mbi, widget));
+ p->setBrushOrigin(p->brushOrigin() - QPoint(1, 1));
+ }
+ }
+ QCommonStyle::drawControl(ce, &newMbi, p, widget);
+ }
+ break;
+#endif // QT_NO_MENUBAR
+#ifndef QT_NO_TABBAR
+ case CE_TabBarTabShape:
+ if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
+ bool rtlHorTabs = (tab->direction == Qt::RightToLeft
+ && (tab->shape == QTabBar::RoundedNorth
+ || tab->shape == QTabBar::RoundedSouth));
+ bool selected = tab->state & State_Selected;
+ bool lastTab = ((!rtlHorTabs && tab->position == QStyleOptionTab::End)
+ || (rtlHorTabs
+ && tab->position == QStyleOptionTab::Beginning));
+ bool firstTab = ((!rtlHorTabs
+ && tab->position == QStyleOptionTab::Beginning)
+ || (rtlHorTabs
+ && tab->position == QStyleOptionTab::End));
+ bool onlyOne = tab->position == QStyleOptionTab::OnlyOneTab;
+ bool previousSelected =
+ ((!rtlHorTabs
+ && tab->selectedPosition == QStyleOptionTab::PreviousIsSelected)
+ || (rtlHorTabs
+ && tab->selectedPosition == QStyleOptionTab::NextIsSelected));
+ bool nextSelected =
+ ((!rtlHorTabs
+ && tab->selectedPosition == QStyleOptionTab::NextIsSelected)
+ || (rtlHorTabs
+ && tab->selectedPosition
+ == QStyleOptionTab::PreviousIsSelected));
+ int tabBarAlignment = proxy()->styleHint(SH_TabBar_Alignment, tab, widget);
+ bool leftAligned = (!rtlHorTabs && tabBarAlignment == Qt::AlignLeft)
+ || (rtlHorTabs
+ && tabBarAlignment == Qt::AlignRight);
+
+ bool rightAligned = (!rtlHorTabs && tabBarAlignment == Qt::AlignRight)
+ || (rtlHorTabs
+ && tabBarAlignment == Qt::AlignLeft);
+
+ QColor light = tab->palette.light().color();
+ QColor dark = tab->palette.dark().color();
+ QColor shadow = tab->palette.shadow().color();
+ int borderThinkness = proxy()->pixelMetric(PM_TabBarBaseOverlap, tab, widget);
+ if (selected)
+ borderThinkness /= 2;
+ QRect r2(opt->rect);
+ int x1 = r2.left();
+ int x2 = r2.right();
+ int y1 = r2.top();
+ int y2 = r2.bottom();
+ switch (tab->shape) {
+ default:
+ QCommonStyle::drawControl(ce, tab, p, widget);
+ break;
+ case QTabBar::RoundedNorth: {
+ if (!selected) {
+ y1 += 2;
+ x1 += onlyOne || firstTab ? borderThinkness : 0;
+ x2 -= onlyOne || lastTab ? borderThinkness : 0;
+ }
+
+ p->fillRect(QRect(x1 + 1, y1 + 1, (x2 - x1) - 1, (y2 - y1) - 2), tab->palette.background());
+
+ // Delete border
+ if (selected) {
+ p->fillRect(QRect(x1,y2-1,x2-x1,1), tab->palette.background());
+ p->fillRect(QRect(x1,y2,x2-x1,1), tab->palette.background());
+ }
+ // Left
+ if (firstTab || selected || onlyOne || !previousSelected) {
+ p->setPen(light);
+ p->drawLine(x1, y1 + 2, x1, y2 - ((onlyOne || firstTab) && selected && leftAligned ? 0 : borderThinkness));
+ p->drawPoint(x1 + 1, y1 + 1);
+ }
+ // Top
+ {
+ int beg = x1 + (previousSelected ? 0 : 2);
+ int end = x2 - (nextSelected ? 0 : 2);
+ p->setPen(light);
+ p->drawLine(beg, y1, end, y1);
+ }
+ // Right
+ if (lastTab || selected || onlyOne || !nextSelected) {
+ p->setPen(shadow);
+ p->drawLine(x2, y1 + 2, x2, y2 - ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness));
+ p->drawPoint(x2 - 1, y1 + 1);
+ p->setPen(dark);
+ p->drawLine(x2 - 1, y1 + 2, x2 - 1, y2 - ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness));
+ }
+ break; }
+ case QTabBar::RoundedSouth: {
+ if (!selected) {
+ y2 -= 2;
+ x1 += firstTab ? borderThinkness : 0;
+ x2 -= lastTab ? borderThinkness : 0;
+ }
+
+ p->fillRect(QRect(x1 + 1, y1 + 2, (x2 - x1) - 1, (y2 - y1) - 1), tab->palette.background());
+
+ // Delete border
+ if (selected) {
+ p->fillRect(QRect(x1, y1 + 1, (x2 - 1)-x1, 1), tab->palette.background());
+ p->fillRect(QRect(x1, y1, (x2 - 1)-x1, 1), tab->palette.background());
+ }
+ // Left
+ if (firstTab || selected || onlyOne || !previousSelected) {
+ p->setPen(light);
+ p->drawLine(x1, y2 - 2, x1, y1 + ((onlyOne || firstTab) && selected && leftAligned ? 0 : borderThinkness));
+ p->drawPoint(x1 + 1, y2 - 1);
+ }
+ // Bottom
+ {
+ int beg = x1 + (previousSelected ? 0 : 2);
+ int end = x2 - (nextSelected ? 0 : 2);
+ p->setPen(shadow);
+ p->drawLine(beg, y2, end, y2);
+ p->setPen(dark);
+ p->drawLine(beg, y2 - 1, end, y2 - 1);
+ }
+ // Right
+ if (lastTab || selected || onlyOne || !nextSelected) {
+ p->setPen(shadow);
+ p->drawLine(x2, y2 - 2, x2, y1 + ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness));
+ p->drawPoint(x2 - 1, y2 - 1);
+ p->setPen(dark);
+ p->drawLine(x2 - 1, y2 - 2, x2 - 1, y1 + ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness));
+ }
+ break; }
+ case QTabBar::RoundedWest: {
+ if (!selected) {
+ x1 += 2;
+ y1 += firstTab ? borderThinkness : 0;
+ y2 -= lastTab ? borderThinkness : 0;
+ }
+
+ p->fillRect(QRect(x1 + 1, y1 + 1, (x2 - x1) - 2, (y2 - y1) - 1), tab->palette.background());
+
+ // Delete border
+ if (selected) {
+ p->fillRect(QRect(x2 - 1, y1, 1, y2-y1), tab->palette.background());
+ p->fillRect(QRect(x2, y1, 1, y2-y1), tab->palette.background());
+ }
+ // Top
+ if (firstTab || selected || onlyOne || !previousSelected) {
+ p->setPen(light);
+ p->drawLine(x1 + 2, y1, x2 - ((onlyOne || firstTab) && selected && leftAligned ? 0 : borderThinkness), y1);
+ p->drawPoint(x1 + 1, y1 + 1);
+ }
+ // Left
+ {
+ int beg = y1 + (previousSelected ? 0 : 2);
+ int end = y2 - (nextSelected ? 0 : 2);
+ p->setPen(light);
+ p->drawLine(x1, beg, x1, end);
+ }
+ // Bottom
+ if (lastTab || selected || onlyOne || !nextSelected) {
+ p->setPen(shadow);
+ p->drawLine(x1 + 3, y2, x2 - ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness), y2);
+ p->drawPoint(x1 + 2, y2 - 1);
+ p->setPen(dark);
+ p->drawLine(x1 + 3, y2 - 1, x2 - ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness), y2 - 1);
+ p->drawPoint(x1 + 1, y2 - 1);
+ p->drawPoint(x1 + 2, y2);
+ }
+ break; }
+ case QTabBar::RoundedEast: {
+ if (!selected) {
+ x2 -= 2;
+ y1 += firstTab ? borderThinkness : 0;
+ y2 -= lastTab ? borderThinkness : 0;
+ }
+
+ p->fillRect(QRect(x1 + 2, y1 + 1, (x2 - x1) - 1, (y2 - y1) - 1), tab->palette.background());
+
+ // Delete border
+ if (selected) {
+ p->fillRect(QRect(x1 + 1, y1, 1, (y2 - 1)-y1),tab->palette.background());
+ p->fillRect(QRect(x1, y1, 1, (y2-1)-y1), tab->palette.background());
+ }
+ // Top
+ if (firstTab || selected || onlyOne || !previousSelected) {
+ p->setPen(light);
+ p->drawLine(x2 - 2, y1, x1 + ((onlyOne || firstTab) && selected && leftAligned ? 0 : borderThinkness), y1);
+ p->drawPoint(x2 - 1, y1 + 1);
+ }
+ // Right
+ {
+ int beg = y1 + (previousSelected ? 0 : 2);
+ int end = y2 - (nextSelected ? 0 : 2);
+ p->setPen(shadow);
+ p->drawLine(x2, beg, x2, end);
+ p->setPen(dark);
+ p->drawLine(x2 - 1, beg, x2 - 1, end);
+ }
+ // Bottom
+ if (lastTab || selected || onlyOne || !nextSelected) {
+ p->setPen(shadow);
+ p->drawLine(x2 - 2, y2, x1 + ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness), y2);
+ p->drawPoint(x2 - 1, y2 - 1);
+ p->setPen(dark);
+ p->drawLine(x2 - 2, y2 - 1, x1 + ((onlyOne || lastTab) && selected && rightAligned ? 0 : borderThinkness), y2 - 1);
+ }
+ break; }
+ }
+ }
+ break;
+#endif // QT_NO_TABBAR
+ case CE_ToolBoxTabShape:
+ qDrawShadePanel(p, opt->rect, opt->palette,
+ opt->state & (State_Sunken | State_On), 1,
+ &opt->palette.brush(QPalette::Button));
+ break;
+#ifndef QT_NO_SPLITTER
+ case CE_Splitter:
+ p->eraseRect(opt->rect);
+ break;
+#endif // QT_NO_SPLITTER
+#ifndef QT_NO_SCROLLBAR
+ case CE_ScrollBarSubLine:
+ case CE_ScrollBarAddLine: {
+ if ((opt->state & State_Sunken)) {
+ p->setPen(opt->palette.dark().color());
+ p->setBrush(opt->palette.brush(QPalette::Button));
+ p->drawRect(opt->rect.adjusted(0, 0, -1, -1));
+ } else {
+ QStyleOption buttonOpt = *opt;
+ if (!(buttonOpt.state & State_Sunken))
+ buttonOpt.state |= State_Raised;
+ QPalette pal(opt->palette);
+ pal.setColor(QPalette::Button, opt->palette.light().color());
+ pal.setColor(QPalette::Light, opt->palette.button().color());
+ qDrawWinButton(p, opt->rect, pal, opt->state & (State_Sunken | State_On),
+ &opt->palette.brush(QPalette::Button));
+ }
+ PrimitiveElement arrow;
+ if (opt->state & State_Horizontal) {
+ if (ce == CE_ScrollBarAddLine)
+ arrow = opt->direction == Qt::LeftToRight ? PE_IndicatorArrowRight : PE_IndicatorArrowLeft;
+ else
+ arrow = opt->direction == Qt::LeftToRight ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight;
+ } else {
+ if (ce == CE_ScrollBarAddLine)
+ arrow = PE_IndicatorArrowDown;
+ else
+ arrow = PE_IndicatorArrowUp;
+ }
+ QStyleOption arrowOpt = *opt;
+ arrowOpt.rect = opt->rect.adjusted(4, 4, -4, -4);
+ proxy()->drawPrimitive(arrow, &arrowOpt, p, widget);
+ break; }
+ case CE_ScrollBarAddPage:
+ case CE_ScrollBarSubPage: {
+ QBrush br;
+ QBrush bg = p->background();
+ Qt::BGMode bg_mode = p->backgroundMode();
+ p->setPen(Qt::NoPen);
+ p->setBackgroundMode(Qt::OpaqueMode);
+
+ if (opt->state & State_Sunken) {
+ br = QBrush(opt->palette.shadow().color(), Qt::Dense4Pattern);
+ p->setBackground(opt->palette.dark().color());
+ p->setBrush(br);
+ } else {
+ QPixmap pm = opt->palette.brush(QPalette::Light).texture();
+ br = !pm.isNull() ? QBrush(pm) : QBrush(opt->palette.light().color(), Qt::Dense4Pattern);
+ p->setBackground(opt->palette.background().color());
+ p->setBrush(br);
+ }
+ p->drawRect(opt->rect);
+ p->setBackground(bg);
+ p->setBackgroundMode(bg_mode);
+ break; }
+ case CE_ScrollBarSlider:
+ if (!(opt->state & State_Enabled)) {
+ QPixmap pm = opt->palette.brush(QPalette::Light).texture();
+ QBrush br = !pm.isNull() ? QBrush(pm) : QBrush(opt->palette.light().color(), Qt::Dense4Pattern);
+ p->setPen(Qt::NoPen);
+ p->setBrush(br);
+ p->setBackgroundMode(Qt::OpaqueMode);
+ p->drawRect(opt->rect);
+ } else {
+ QStyleOptionButton buttonOpt;
+ buttonOpt.QStyleOption::operator=(*opt);
+ buttonOpt.state = State_Enabled | State_Raised;
+
+ QPalette pal(opt->palette);
+ pal.setColor(QPalette::Button, opt->palette.light().color());
+ pal.setColor(QPalette::Light, opt->palette.button().color());
+ qDrawWinButton(p, opt->rect, pal, false, &opt->palette.brush(QPalette::Button));
+ }
+ break;
+#endif // QT_NO_SCROLLBAR
+ case CE_HeaderSection: {
+ QBrush fill;
+ if (opt->state & State_On)
+ fill = QBrush(opt->palette.light().color(), Qt::Dense4Pattern);
+ else
+ fill = opt->palette.brush(QPalette::Button);
+
+ if (opt->state & (State_Raised | State_Sunken)) {
+ qDrawWinButton(p, opt->rect, opt->palette, opt->state & State_Sunken, &fill);
+ } else {
+ p->fillRect(opt->rect, fill);
+ }
+ break; }
+#ifndef QT_NO_TOOLBAR
+ case CE_ToolBar:
+ if (const QStyleOptionToolBar *toolbar = qstyleoption_cast<const QStyleOptionToolBar *>(opt)) {
+ QRect rect = opt->rect;
+
+ bool paintLeftBorder = true;
+ bool paintRightBorder = true;
+ bool paintBottomBorder = true;
+
+ switch (toolbar->toolBarArea){
+ case Qt::BottomToolBarArea :
+ switch(toolbar->positionOfLine){
+ case QStyleOptionToolBar::Beginning:
+ case QStyleOptionToolBar::OnlyOne:
+ paintBottomBorder = false;
+ default:
+ break;
+ }
+ case Qt::TopToolBarArea :
+ switch(toolbar->positionWithinLine){
+ case QStyleOptionToolBar::Beginning:
+ paintLeftBorder = false;
+ break;
+ case QStyleOptionToolBar::End:
+ paintRightBorder = false;
+ break;
+ case QStyleOptionToolBar::OnlyOne:
+ paintRightBorder = false;
+ paintLeftBorder = false;
+ default:
+ break;
+ }
+ if(opt->direction == Qt::RightToLeft){ //reverse layout changes the order of Beginning/end
+ bool tmp = paintLeftBorder;
+ paintRightBorder=paintLeftBorder;
+ paintLeftBorder=tmp;
+ }
+ break;
+ case Qt::RightToolBarArea :
+ switch (toolbar->positionOfLine){
+ case QStyleOptionToolBar::Beginning:
+ case QStyleOptionToolBar::OnlyOne:
+ paintRightBorder = false;
+ break;
+ default:
+ break;
+ }
+ break;
+ case Qt::LeftToolBarArea :
+ switch (toolbar->positionOfLine){
+ case QStyleOptionToolBar::Beginning:
+ case QStyleOptionToolBar::OnlyOne:
+ paintLeftBorder = false;
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+
+
+ //draw top border
+ p->setPen(QPen(opt->palette.light().color()));
+ p->drawLine(rect.topLeft().x(),
+ rect.topLeft().y(),
+ rect.topRight().x(),
+ rect.topRight().y());
+
+ if (paintLeftBorder){
+ p->setPen(QPen(opt->palette.light().color()));
+ p->drawLine(rect.topLeft().x(),
+ rect.topLeft().y(),
+ rect.bottomLeft().x(),
+ rect.bottomLeft().y());
+ }
+
+ if (paintRightBorder){
+ p->setPen(QPen(opt->palette.dark().color()));
+ p->drawLine(rect.topRight().x(),
+ rect.topRight().y(),
+ rect.bottomRight().x(),
+ rect.bottomRight().y());
+ }
+
+ if (paintBottomBorder){
+ p->setPen(QPen(opt->palette.dark().color()));
+ p->drawLine(rect.bottomLeft().x(),
+ rect.bottomLeft().y(),
+ rect.bottomRight().x(),
+ rect.bottomRight().y());
+ }
+ }
+ break;
+
+
+#endif // QT_NO_TOOLBAR
+#ifndef QT_NO_PROGRESSBAR
+ case CE_ProgressBarContents:
+ if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) {
+ QRect rect = pb->rect;
+ if (!rect.isValid())
+ return;
+
+ bool vertical = false;
+ bool inverted = false;
+
+ // Get extra style options if version 2
+ const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(opt);
+ if (pb2) {
+ vertical = (pb2->orientation == Qt::Vertical);
+ inverted = pb2->invertedAppearance;
+ }
+ QMatrix m;
+ if (vertical) {
+ rect = QRect(rect.y(), rect.x(), rect.height(), rect.width()); // flip width and height
+ m.rotate(90);
+ m.translate(0, -(rect.height() + rect.y()*2));
+ }
+ QPalette pal2 = pb->palette;
+ // Correct the highlight color if it is the same as the background
+ if (pal2.highlight() == pal2.background())
+ pal2.setColor(QPalette::Highlight, pb->palette.color(QPalette::Active,
+ QPalette::Highlight));
+ bool reverse = ((!vertical && (pb->direction == Qt::RightToLeft)) || vertical);
+ if (inverted)
+ reverse = !reverse;
+ int w = rect.width();
+ if (pb->minimum == 0 && pb->maximum == 0) {
+ Q_D(const QWindowsStyle);
+ const int unit_width = proxy()->pixelMetric(PM_ProgressBarChunkWidth, pb, widget);
+ QStyleOptionProgressBarV2 pbBits = *pb;
+ Q_ASSERT(unit_width >0);
+
+ pbBits.rect = rect;
+ pbBits.palette = pal2;
+
+ int chunkCount = w / unit_width + 1;
+ int step = d->animateStep%chunkCount;
+ int chunksInRow = 5;
+ int myY = pbBits.rect.y();
+ int myHeight = pbBits.rect.height();
+ int chunksToDraw = chunksInRow;
+
+ if(step > chunkCount - 5)chunksToDraw = (chunkCount - step);
+ p->save();
+ p->setClipRect(m.mapRect(QRectF(rect)).toRect());
+
+ int x0 = reverse ? rect.left() + rect.width() - unit_width*(step) - unit_width : rect.left() + unit_width * step;
+ int x = 0;
+
+ for (int i = 0; i < chunksToDraw ; ++i) {
+ pbBits.rect.setRect(x0 + x, myY, unit_width, myHeight);
+ pbBits.rect = m.mapRect(QRectF(pbBits.rect)).toRect();
+ proxy()->drawPrimitive(PE_IndicatorProgressChunk, &pbBits, p, widget);
+ x += reverse ? -unit_width : unit_width;
+ }
+ //Draw wrap-around chunks
+ if( step > chunkCount-5){
+ x0 = reverse ? rect.left() + rect.width() - unit_width : rect.left() ;
+ x = 0;
+ int chunksToDraw = step - (chunkCount - chunksInRow);
+ for (int i = 0; i < chunksToDraw ; ++i) {
+ pbBits.rect.setRect(x0 + x, myY, unit_width, myHeight);
+ pbBits.rect = m.mapRect(QRectF(pbBits.rect)).toRect();
+ proxy()->drawPrimitive(PE_IndicatorProgressChunk, &pbBits, p, widget);
+ x += reverse ? -unit_width : unit_width;
+ }
+ }
+ p->restore(); //restore state
+ }
+ else {
+ QCommonStyle::drawControl(ce, opt, p, widget);
+ }
+ }
+ break;
+#endif // QT_NO_PROGRESSBAR
+
+#ifndef QT_NO_DOCKWIDGET
+ case CE_DockWidgetTitle:
+
+ if (const QStyleOptionDockWidget *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(opt)) {
+ Q_D(const QWindowsStyle);
+
+ const QStyleOptionDockWidgetV2 *v2
+ = qstyleoption_cast<const QStyleOptionDockWidgetV2*>(opt);
+ bool verticalTitleBar = v2 == 0 ? false : v2->verticalTitleBar;
+
+ QRect rect = dwOpt->rect;
+ QRect r = rect;
+
+ if (verticalTitleBar) {
+ QSize s = r.size();
+ s.transpose();
+ r.setSize(s);
+
+ p->save();
+ p->translate(r.left(), r.top() + r.width());
+ p->rotate(-90);
+ p->translate(-r.left(), -r.top());
+ }
+
+ bool floating = false;
+ bool active = dwOpt->state & State_Active;
+ QColor inactiveCaptionTextColor = d->inactiveCaptionText;
+ if (dwOpt->movable) {
+ QColor left, right;
+
+ //Titlebar gradient
+ if (widget && widget->isWindow()) {
+ floating = true;
+ if (active) {
+ left = d->activeCaptionColor;
+ right = d->activeGradientCaptionColor;
+ } else {
+ left = d->inactiveCaptionColor;
+ right = d->inactiveGradientCaptionColor;
+ }
+ QBrush fillBrush(left);
+ if (left != right) {
+ QPoint p1(r.x(), r.top() + r.height()/2);
+ QPoint p2(rect.right(), r.top() + r.height()/2);
+ QLinearGradient lg(p1, p2);
+ lg.setColorAt(0, left);
+ lg.setColorAt(1, right);
+ fillBrush = lg;
+ }
+ p->fillRect(r.adjusted(0, 0, 0, -3), fillBrush);
+ }
+ p->setPen(dwOpt->palette.color(QPalette::Light));
+ if (!widget || !widget->isWindow()) {
+ p->drawLine(r.topLeft(), r.topRight());
+ p->setPen(dwOpt->palette.color(QPalette::Dark));
+ p->drawLine(r.bottomLeft(), r.bottomRight()); }
+ }
+ if (!dwOpt->title.isEmpty()) {
+ QFont oldFont = p->font();
+ if (floating) {
+ QFont font = oldFont;
+ font.setBold(true);
+ p->setFont(font);
+ }
+ QPalette palette = dwOpt->palette;
+ palette.setColor(QPalette::Window, inactiveCaptionTextColor);
+ QRect titleRect = subElementRect(SE_DockWidgetTitleBarText, opt, widget);
+ if (verticalTitleBar) {
+ titleRect = QRect(r.left() + rect.bottom()
+ - titleRect.bottom(),
+ r.top() + titleRect.left() - rect.left(),
+ titleRect.height(), titleRect.width());
+ }
+ proxy()->drawItemText(p, titleRect,
+ Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic, palette,
+ dwOpt->state & State_Enabled, dwOpt->title,
+ floating ? (active ? QPalette::BrightText : QPalette::Window) : QPalette::WindowText);
+ p->setFont(oldFont);
+ }
+ if (verticalTitleBar)
+ p->restore();
+ }
+ return;
+#endif // QT_NO_DOCKWIDGET
+ default:
+ QCommonStyle::drawControl(ce, opt, p, widget);
+ }
+}
+
+/*! \reimp */
+QRect QWindowsStyle::subElementRect(SubElement sr, const QStyleOption *opt, const QWidget *w) const
+{
+ QRect r;
+ switch (sr) {
+ case SE_SliderFocusRect:
+ case SE_ToolBoxTabContents:
+ r = visualRect(opt->direction, opt->rect, opt->rect);
+ break;
+ case SE_DockWidgetTitleBarText: {
+ r = QCommonStyle::subElementRect(sr, opt, w);
+ const QStyleOptionDockWidgetV2 *v2
+ = qstyleoption_cast<const QStyleOptionDockWidgetV2*>(opt);
+ bool verticalTitleBar = v2 == 0 ? false : v2->verticalTitleBar;
+ int m = proxy()->pixelMetric(PM_DockWidgetTitleMargin, opt, w);
+ if (verticalTitleBar) {
+ r.adjust(0, 0, 0, -m);
+ } else {
+ if (opt->direction == Qt::LeftToRight)
+ r.adjust(m, 0, 0, 0);
+ else
+ r.adjust(0, 0, -m, 0);
+ }
+ break;
+ }
+ case SE_ProgressBarContents:
+ r = QCommonStyle::subElementRect(SE_ProgressBarGroove, opt, w);
+ r.adjust(3, 3, -3, -3);
+ break;
+ default:
+ r = QCommonStyle::subElementRect(sr, opt, w);
+ }
+ return r;
+}
+
+#ifdef QT3_SUPPORT
+Q_GLOBAL_STATIC_WITH_ARGS(QBitmap, globalVerticalLine, (1, 129))
+Q_GLOBAL_STATIC_WITH_ARGS(QBitmap, globalHorizontalLine, (128, 1))
+#endif
+
+/*! \reimp */
+void QWindowsStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt,
+ QPainter *p, const QWidget *widget) const
+{
+ switch (cc) {
+#ifndef QT_NO_SLIDER
+ case CC_Slider:
+ if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
+ int thickness = proxy()->pixelMetric(PM_SliderControlThickness, slider, widget);
+ int len = proxy()->pixelMetric(PM_SliderLength, slider, widget);
+ int ticks = slider->tickPosition;
+ QRect groove = proxy()->subControlRect(CC_Slider, slider, SC_SliderGroove, widget);
+ QRect handle = proxy()->subControlRect(CC_Slider, slider, SC_SliderHandle, widget);
+
+ if ((slider->subControls & SC_SliderGroove) && groove.isValid()) {
+ int mid = thickness / 2;
+
+ if (ticks & QSlider::TicksAbove)
+ mid += len / 8;
+ if (ticks & QSlider::TicksBelow)
+ mid -= len / 8;
+
+ p->setPen(slider->palette.shadow().color());
+ if (slider->orientation == Qt::Horizontal) {
+ qDrawWinPanel(p, groove.x(), groove.y() + mid - 2,
+ groove.width(), 4, slider->palette, true);
+ p->drawLine(groove.x() + 1, groove.y() + mid - 1,
+ groove.x() + groove.width() - 3, groove.y() + mid - 1);
+ } else {
+ qDrawWinPanel(p, groove.x() + mid - 2, groove.y(),
+ 4, groove.height(), slider->palette, true);
+ p->drawLine(groove.x() + mid - 1, groove.y() + 1,
+ groove.x() + mid - 1, groove.y() + groove.height() - 3);
+ }
+ }
+
+ if (slider->subControls & SC_SliderTickmarks) {
+ QStyleOptionSlider tmpSlider = *slider;
+ tmpSlider.subControls = SC_SliderTickmarks;
+ QCommonStyle::drawComplexControl(cc, &tmpSlider, p, widget);
+ }
+
+ if (slider->subControls & SC_SliderHandle) {
+ // 4444440
+ // 4333310
+ // 4322210
+ // 4322210
+ // 4322210
+ // 4322210
+ // *43210*
+ // **410**
+ // ***0***
+ const QColor c0 = slider->palette.shadow().color();
+ const QColor c1 = slider->palette.dark().color();
+ // const QColor c2 = g.button();
+ const QColor c3 = slider->palette.midlight().color();
+ const QColor c4 = slider->palette.light().color();
+ QBrush handleBrush;
+
+ if (slider->state & State_Enabled) {
+ handleBrush = slider->palette.color(QPalette::Button);
+ } else {
+ handleBrush = QBrush(slider->palette.color(QPalette::Button),
+ Qt::Dense4Pattern);
+ }
+
+
+ int x = handle.x(), y = handle.y(),
+ wi = handle.width(), he = handle.height();
+
+ int x1 = x;
+ int x2 = x+wi-1;
+ int y1 = y;
+ int y2 = y+he-1;
+
+ Qt::Orientation orient = slider->orientation;
+ bool tickAbove = slider->tickPosition == QSlider::TicksAbove;
+ bool tickBelow = slider->tickPosition == QSlider::TicksBelow;
+
+ if (slider->state & State_HasFocus) {
+ QStyleOptionFocusRect fropt;
+ fropt.QStyleOption::operator=(*slider);
+ fropt.rect = subElementRect(SE_SliderFocusRect, slider, widget);
+ proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, p, widget);
+ }
+
+ if ((tickAbove && tickBelow) || (!tickAbove && !tickBelow)) {
+ Qt::BGMode oldMode = p->backgroundMode();
+ p->setBackgroundMode(Qt::OpaqueMode);
+ qDrawWinButton(p, QRect(x, y, wi, he), slider->palette, false,
+ &handleBrush);
+ p->setBackgroundMode(oldMode);
+ return;
+ }
+
+ QSliderDirection dir;
+
+ if (orient == Qt::Horizontal)
+ if (tickAbove)
+ dir = SlUp;
+ else
+ dir = SlDown;
+ else
+ if (tickAbove)
+ dir = SlLeft;
+ else
+ dir = SlRight;
+
+ QPolygon a;
+
+ int d = 0;
+ switch (dir) {
+ case SlUp:
+ y1 = y1 + wi/2;
+ d = (wi + 1) / 2 - 1;
+ a.setPoints(5, x1,y1, x1,y2, x2,y2, x2,y1, x1+d,y1-d);
+ break;
+ case SlDown:
+ y2 = y2 - wi/2;
+ d = (wi + 1) / 2 - 1;
+ a.setPoints(5, x1,y1, x1,y2, x1+d,y2+d, x2,y2, x2,y1);
+ break;
+ case SlLeft:
+ d = (he + 1) / 2 - 1;
+ x1 = x1 + he/2;
+ a.setPoints(5, x1,y1, x1-d,y1+d, x1,y2, x2,y2, x2,y1);
+ break;
+ case SlRight:
+ d = (he + 1) / 2 - 1;
+ x2 = x2 - he/2;
+ a.setPoints(5, x1,y1, x1,y2, x2,y2, x2+d,y1+d, x2,y1);
+ break;
+ }
+
+ QBrush oldBrush = p->brush();
+ p->setPen(Qt::NoPen);
+ p->setBrush(handleBrush);
+ Qt::BGMode oldMode = p->backgroundMode();
+ p->setBackgroundMode(Qt::OpaqueMode);
+ p->drawRect(x1, y1, x2-x1+1, y2-y1+1);
+ p->drawPolygon(a);
+ p->setBrush(oldBrush);
+ p->setBackgroundMode(oldMode);
+
+ if (dir != SlUp) {
+ p->setPen(c4);
+ p->drawLine(x1, y1, x2, y1);
+ p->setPen(c3);
+ p->drawLine(x1, y1+1, x2, y1+1);
+ }
+ if (dir != SlLeft) {
+ p->setPen(c3);
+ p->drawLine(x1+1, y1+1, x1+1, y2);
+ p->setPen(c4);
+ p->drawLine(x1, y1, x1, y2);
+ }
+ if (dir != SlRight) {
+ p->setPen(c0);
+ p->drawLine(x2, y1, x2, y2);
+ p->setPen(c1);
+ p->drawLine(x2-1, y1+1, x2-1, y2-1);
+ }
+ if (dir != SlDown) {
+ p->setPen(c0);
+ p->drawLine(x1, y2, x2, y2);
+ p->setPen(c1);
+ p->drawLine(x1+1, y2-1, x2-1, y2-1);
+ }
+
+ switch (dir) {
+ case SlUp:
+ p->setPen(c4);
+ p->drawLine(x1, y1, x1+d, y1-d);
+ p->setPen(c0);
+ d = wi - d - 1;
+ p->drawLine(x2, y1, x2-d, y1-d);
+ d--;
+ p->setPen(c3);
+ p->drawLine(x1+1, y1, x1+1+d, y1-d);
+ p->setPen(c1);
+ p->drawLine(x2-1, y1, x2-1-d, y1-d);
+ break;
+ case SlDown:
+ p->setPen(c4);
+ p->drawLine(x1, y2, x1+d, y2+d);
+ p->setPen(c0);
+ d = wi - d - 1;
+ p->drawLine(x2, y2, x2-d, y2+d);
+ d--;
+ p->setPen(c3);
+ p->drawLine(x1+1, y2, x1+1+d, y2+d);
+ p->setPen(c1);
+ p->drawLine(x2-1, y2, x2-1-d, y2+d);
+ break;
+ case SlLeft:
+ p->setPen(c4);
+ p->drawLine(x1, y1, x1-d, y1+d);
+ p->setPen(c0);
+ d = he - d - 1;
+ p->drawLine(x1, y2, x1-d, y2-d);
+ d--;
+ p->setPen(c3);
+ p->drawLine(x1, y1+1, x1-d, y1+1+d);
+ p->setPen(c1);
+ p->drawLine(x1, y2-1, x1-d, y2-1-d);
+ break;
+ case SlRight:
+ p->setPen(c4);
+ p->drawLine(x2, y1, x2+d, y1+d);
+ p->setPen(c0);
+ d = he - d - 1;
+ p->drawLine(x2, y2, x2+d, y2-d);
+ d--;
+ p->setPen(c3);
+ p->drawLine(x2, y1+1, x2+d, y1+1+d);
+ p->setPen(c1);
+ p->drawLine(x2, y2-1, x2+d, y2-1-d);
+ break;
+ }
+ }
+ }
+ break;
+#endif // QT_NO_SLIDER
+#ifndef QT_NO_SCROLLBAR
+ case CC_ScrollBar:
+ if (const QStyleOptionSlider *scrollbar = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
+ QStyleOptionSlider newScrollbar = *scrollbar;
+ if (scrollbar->minimum == scrollbar->maximum)
+ newScrollbar.state &= ~State_Enabled; //do not draw the slider.
+ QCommonStyle::drawComplexControl(cc, &newScrollbar, p, widget);
+ }
+ break;
+#endif // QT_NO_SCROLLBAR
+#ifdef QT3_SUPPORT
+ case CC_Q3ListView:
+ if (const QStyleOptionQ3ListView *lv = qstyleoption_cast<const QStyleOptionQ3ListView *>(opt)) {
+ int i;
+ if (lv->subControls & SC_Q3ListView)
+ QCommonStyle::drawComplexControl(cc, lv, p, widget);
+ if (lv->subControls & (SC_Q3ListViewBranch | SC_Q3ListViewExpand)) {
+ if (lv->items.isEmpty())
+ break;
+ QStyleOptionQ3ListViewItem item = lv->items.at(0);
+ int y = lv->rect.y();
+ int c;
+ int dotoffset = 0;
+ QPolygon dotlines;
+ if ((lv->activeSubControls & SC_All) && (lv->subControls & SC_Q3ListViewExpand)) {
+ c = 2;
+ dotlines.resize(2);
+ dotlines[0] = QPoint(lv->rect.right(), lv->rect.top());
+ dotlines[1] = QPoint(lv->rect.right(), lv->rect.bottom());
+ } else {
+ int linetop = 0, linebot = 0;
+ // each branch needs at most two lines, ie. four end points
+ dotoffset = (item.itemY + item.height - y) % 2;
+ dotlines.resize(item.childCount * 4);
+ c = 0;
+
+ // skip the stuff above the exposed rectangle
+ for (i = 1; i < lv->items.size(); ++i) {
+ QStyleOptionQ3ListViewItem child = lv->items.at(i);
+ if (child.height + y > 0)
+ break;
+ y += child.totalHeight;
+ }
+ int bx = lv->rect.width() / 2;
+
+ // paint stuff in the magical area
+ while (i < lv->items.size() && y < lv->rect.height()) {
+ QStyleOptionQ3ListViewItem child = lv->items.at(i);
+ if (child.features & QStyleOptionQ3ListViewItem::Visible) {
+ int lh;
+ if (!(item.features & QStyleOptionQ3ListViewItem::MultiLine))
+ lh = child.height;
+ else
+ lh = p->fontMetrics().height() + 2 * lv->itemMargin;
+ lh = qMax(lh, QApplication::globalStrut().height());
+ if (lh % 2 > 0)
+ ++lh;
+ linebot = y + lh / 2;
+ if (child.features & QStyleOptionQ3ListViewItem::Expandable
+ || (child.childCount > 0 && child.height > 0)) {
+ // needs a box
+ p->setPen(lv->palette.mid().color());
+ p->drawRect(bx - 4, linebot - 4, 8, 8);
+ // plus or minus
+ p->setPen(lv->palette.text().color());
+ p->drawLine(bx - 2, linebot, bx + 2, linebot);
+ if (!(child.state & State_Open))
+ p->drawLine(bx, linebot - 2, bx, linebot + 2);
+ // dotlinery
+ p->setPen(lv->palette.mid().color());
+ dotlines[c++] = QPoint(bx, linetop);
+ dotlines[c++] = QPoint(bx, linebot - 4);
+ dotlines[c++] = QPoint(bx + 5, linebot);
+ dotlines[c++] = QPoint(lv->rect.width(), linebot);
+ linetop = linebot + 5;
+ } else {
+ // just dotlinery
+ dotlines[c++] = QPoint(bx+1, linebot -1);
+ dotlines[c++] = QPoint(lv->rect.width(), linebot -1);
+ }
+ y += child.totalHeight;
+ }
+ ++i;
+ }
+
+ // Expand line height to edge of rectangle if there's any
+ // visible child below
+ while (i < lv->items.size() && lv->items.at(i).height <= 0)
+ ++i;
+ if (i < lv->items.size())
+ linebot = lv->rect.height();
+
+ if (linetop < linebot) {
+ dotlines[c++] = QPoint(bx, linetop);
+ dotlines[c++] = QPoint(bx, linebot);
+ }
+ }
+ p->setPen(lv->palette.text().color());
+ QBitmap *verticalLine = globalVerticalLine();
+ QBitmap *horizontalLine = globalHorizontalLine();
+ static bool isInit = false;
+ if (!isInit) {
+ isInit = true;
+ // make 128*1 and 1*128 bitmaps that can be used for
+ // drawing the right sort of lines.
+ verticalLine->clear();
+ horizontalLine->clear();
+ QPolygon a(64);
+ QPainter p;
+ p.begin(verticalLine);
+ for(i = 0; i < 64; ++i)
+ a.setPoint(i, 0, i * 2 + 1);
+ p.setPen(Qt::color1);
+ p.drawPoints(a);
+ p.end();
+ QApplication::flush();
+ verticalLine->setMask(*verticalLine);
+ p.begin(horizontalLine);
+ for(i = 0; i < 64; ++i)
+ a.setPoint(i, i * 2 + 1, 0);
+ p.setPen(Qt::color1);
+ p.drawPoints(a);
+ p.end();
+ QApplication::flush();
+ horizontalLine->setMask(*horizontalLine);
+ }
+
+ int line; // index into dotlines
+ if (lv->subControls & SC_Q3ListViewBranch) for(line = 0; line < c; line += 2) {
+ // assumptions here: lines are horizontal or vertical.
+ // lines always start with the numerically lowest
+ // coordinate.
+
+ // point ... relevant coordinate of current point
+ // end ..... same coordinate of the end of the current line
+ // other ... the other coordinate of the current point/line
+ if (dotlines[line].y() == dotlines[line+1].y()) {
+ int end = dotlines[line + 1].x();
+ int point = dotlines[line].x();
+ int other = dotlines[line].y();
+ while (point < end) {
+ int i = 128;
+ if (i + point > end)
+ i = end-point;
+ p->drawPixmap(point, other, *horizontalLine, 0, 0, i, 1);
+ point += i;
+ }
+ } else {
+ int end = dotlines[line + 1].y();
+ int point = dotlines[line].y();
+ int other = dotlines[line].x();
+ int pixmapoffset = ((point & 1) != dotoffset) ? 1 : 0;
+ while(point < end) {
+ int i = 128;
+ if (i + point > end)
+ i = end-point;
+ p->drawPixmap(other, point, *verticalLine, 0, pixmapoffset, 1, i);
+ point += i;
+ }
+ }
+ }
+ }
+ }
+ break;
+#endif // QT3_SUPPORT
+#ifndef QT_NO_COMBOBOX
+ case CC_ComboBox:
+ if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
+ QBrush editBrush = cmb->palette.brush(QPalette::Base);
+ if ((cmb->subControls & SC_ComboBoxFrame)) {
+ if (cmb->frame) {
+ QPalette shadePal = opt->palette;
+ shadePal.setColor(QPalette::Midlight, shadePal.button().color());
+ qDrawWinPanel(p, opt->rect, shadePal, true, &editBrush);
+ }
+ else {
+ p->fillRect(opt->rect, editBrush);
+ }
+ }
+ if (cmb->subControls & SC_ComboBoxArrow) {
+ State flags = State_None;
+
+ QRect ar = proxy()->subControlRect(CC_ComboBox, cmb, SC_ComboBoxArrow, widget);
+ bool sunkenArrow = cmb->activeSubControls == SC_ComboBoxArrow
+ && cmb->state & State_Sunken;
+ if (sunkenArrow) {
+ p->setPen(cmb->palette.dark().color());
+ p->setBrush(cmb->palette.brush(QPalette::Button));
+ p->drawRect(ar.adjusted(0,0,-1,-1));
+ } else {
+ // Make qDrawWinButton use the right colors for drawing the shade of the button
+ QPalette pal(cmb->palette);
+ pal.setColor(QPalette::Button, cmb->palette.light().color());
+ pal.setColor(QPalette::Light, cmb->palette.button().color());
+ qDrawWinButton(p, ar, pal, false,
+ &cmb->palette.brush(QPalette::Button));
+ }
+
+ ar.adjust(2, 2, -2, -2);
+ if (opt->state & State_Enabled)
+ flags |= State_Enabled;
+ if (opt->state & State_HasFocus)
+ flags |= State_HasFocus;
+
+ if (sunkenArrow)
+ flags |= State_Sunken;
+ QStyleOption arrowOpt(0);
+ arrowOpt.rect = ar.adjusted(1, 1, -1, -1);
+ arrowOpt.palette = cmb->palette;
+ arrowOpt.state = flags;
+ proxy()->drawPrimitive(PE_IndicatorArrowDown, &arrowOpt, p, widget);
+ }
+
+ if (cmb->subControls & SC_ComboBoxEditField) {
+ QRect re = proxy()->subControlRect(CC_ComboBox, cmb, SC_ComboBoxEditField, widget);
+ if (cmb->state & State_HasFocus && !cmb->editable)
+ p->fillRect(re.x(), re.y(), re.width(), re.height(),
+ cmb->palette.brush(QPalette::Highlight));
+
+ if (cmb->state & State_HasFocus) {
+ p->setPen(cmb->palette.highlightedText().color());
+ p->setBackground(cmb->palette.highlight());
+
+ } else {
+ p->setPen(cmb->palette.text().color());
+ p->setBackground(cmb->palette.background());
+ }
+
+ if (cmb->state & State_HasFocus && !cmb->editable) {
+ QStyleOptionFocusRect focus;
+ focus.QStyleOption::operator=(*cmb);
+ focus.rect = subElementRect(SE_ComboBoxFocusRect, cmb, widget);
+ focus.state |= State_FocusAtBorder;
+ focus.backgroundColor = cmb->palette.highlight().color();
+ proxy()->drawPrimitive(PE_FrameFocusRect, &focus, p, widget);
+ }
+ }
+ }
+ break;
+#endif // QT_NO_COMBOBOX
+#ifndef QT_NO_SPINBOX
+ case CC_SpinBox:
+ if (const QStyleOptionSpinBox *sb = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
+ QStyleOptionSpinBox copy = *sb;
+ PrimitiveElement pe;
+ bool enabled = opt->state & State_Enabled;
+ if (sb->frame && (sb->subControls & SC_SpinBoxFrame)) {
+ QBrush editBrush = sb->palette.brush(QPalette::Base);
+ QRect r = proxy()->subControlRect(CC_SpinBox, sb, SC_SpinBoxFrame, widget);
+ QPalette shadePal = sb->palette;
+ shadePal.setColor(QPalette::Midlight, shadePal.button().color());
+ qDrawWinPanel(p, r, shadePal, true, &editBrush);
+ }
+
+ QPalette shadePal(opt->palette);
+ shadePal.setColor(QPalette::Button, opt->palette.light().color());
+ shadePal.setColor(QPalette::Light, opt->palette.button().color());
+
+ if (sb->subControls & SC_SpinBoxUp) {
+ copy.subControls = SC_SpinBoxUp;
+ QPalette pal2 = sb->palette;
+ if (!(sb->stepEnabled & QAbstractSpinBox::StepUpEnabled)) {
+ pal2.setCurrentColorGroup(QPalette::Disabled);
+ copy.state &= ~State_Enabled;
+ }
+
+ copy.palette = pal2;
+
+ if (sb->activeSubControls == SC_SpinBoxUp && (sb->state & State_Sunken)) {
+ copy.state |= State_On;
+ copy.state |= State_Sunken;
+ } else {
+ copy.state |= State_Raised;
+ copy.state &= ~State_Sunken;
+ }
+ pe = (sb->buttonSymbols == QAbstractSpinBox::PlusMinus ? PE_IndicatorSpinPlus
+ : PE_IndicatorSpinUp);
+
+ copy.rect = proxy()->subControlRect(CC_SpinBox, sb, SC_SpinBoxUp, widget);
+ qDrawWinButton(p, copy.rect, shadePal, copy.state & (State_Sunken | State_On),
+ &copy.palette.brush(QPalette::Button));
+ copy.rect.adjust(4, 1, -5, -1);
+ if ((!enabled || !(sb->stepEnabled & QAbstractSpinBox::StepUpEnabled))
+ && proxy()->styleHint(SH_EtchDisabledText, opt, widget) )
+ {
+ QStyleOptionSpinBox lightCopy = copy;
+ lightCopy.rect.adjust(1, 1, 1, 1);
+ lightCopy.palette.setBrush(QPalette::ButtonText, copy.palette.light());
+ proxy()->drawPrimitive(pe, &lightCopy, p, widget);
+ }
+ proxy()->drawPrimitive(pe, &copy, p, widget);
+ }
+
+ if (sb->subControls & SC_SpinBoxDown) {
+ copy.subControls = SC_SpinBoxDown;
+ copy.state = sb->state;
+ QPalette pal2 = sb->palette;
+ if (!(sb->stepEnabled & QAbstractSpinBox::StepDownEnabled)) {
+ pal2.setCurrentColorGroup(QPalette::Disabled);
+ copy.state &= ~State_Enabled;
+ }
+ copy.palette = pal2;
+
+ if (sb->activeSubControls == SC_SpinBoxDown && (sb->state & State_Sunken)) {
+ copy.state |= State_On;
+ copy.state |= State_Sunken;
+ } else {
+ copy.state |= State_Raised;
+ copy.state &= ~State_Sunken;
+ }
+ pe = (sb->buttonSymbols == QAbstractSpinBox::PlusMinus ? PE_IndicatorSpinMinus
+ : PE_IndicatorSpinDown);
+
+ copy.rect = proxy()->subControlRect(CC_SpinBox, sb, SC_SpinBoxDown, widget);
+ qDrawWinButton(p, copy.rect, shadePal, copy.state & (State_Sunken | State_On),
+ &copy.palette.brush(QPalette::Button));
+ copy.rect.adjust(4, 0, -5, -1);
+ if ((!enabled || !(sb->stepEnabled & QAbstractSpinBox::StepDownEnabled))
+ && proxy()->styleHint(SH_EtchDisabledText, opt, widget) )
+ {
+ QStyleOptionSpinBox lightCopy = copy;
+ lightCopy.rect.adjust(1, 1, 1, 1);
+ lightCopy.palette.setBrush(QPalette::ButtonText, copy.palette.light());
+ proxy()->drawPrimitive(pe, &lightCopy, p, widget);
+ }
+ proxy()->drawPrimitive(pe, &copy, p, widget);
+ }
+ }
+ break;
+#endif // QT_NO_SPINBOX
+
+ default:
+ QCommonStyle::drawComplexControl(cc, opt, p, widget);
+ }
+}
+
+/*! \reimp */
+QSize QWindowsStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt,
+ const QSize &csz, const QWidget *widget) const
+{
+ QSize sz(csz);
+ switch (ct) {
+ case CT_PushButton:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
+ sz = QCommonStyle::sizeFromContents(ct, opt, csz, widget);
+ int w = sz.width(),
+ h = sz.height();
+ int defwidth = 0;
+ if (btn->features & QStyleOptionButton::AutoDefaultButton)
+ defwidth = 2 * proxy()->pixelMetric(PM_ButtonDefaultIndicator, btn, widget);
+ int minwidth = int(QStyleHelper::dpiScaled(75.));
+ int minheight = int(QStyleHelper::dpiScaled(23.));
+
+#ifndef QT_QWS_SMALL_PUSHBUTTON
+ if (w < minwidth + defwidth && !btn->text.isEmpty())
+ w = minwidth + defwidth;
+ if (h < minheight + defwidth)
+ h = minheight + defwidth;
+#endif
+ sz = QSize(w, h);
+ }
+ break;
+#ifndef QT_NO_MENU
+ case CT_MenuItem:
+ if (const QStyleOptionMenuItem *mi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
+ int w = sz.width();
+ sz = QCommonStyle::sizeFromContents(ct, opt, csz, widget);
+
+ if (mi->menuItemType == QStyleOptionMenuItem::Separator) {
+ sz = QSize(10, QWindowsStylePrivate::windowsSepHeight);
+ }
+ else if (mi->icon.isNull()) {
+ sz.setHeight(sz.height() - 2);
+ w -= 6;
+ }
+
+ if (mi->menuItemType != QStyleOptionMenuItem::Separator && !mi->icon.isNull()) {
+ int iconExtent = proxy()->pixelMetric(PM_SmallIconSize, opt, widget);
+ sz.setHeight(qMax(sz.height(),
+ mi->icon.actualSize(QSize(iconExtent, iconExtent)).height()
+ + 2 * QWindowsStylePrivate::windowsItemFrame));
+ }
+ int maxpmw = mi->maxIconWidth;
+ int tabSpacing = 20;
+ if (mi->text.contains(QLatin1Char('\t')))
+ w += tabSpacing;
+ else if (mi->menuItemType == QStyleOptionMenuItem::SubMenu)
+ w += 2 * QWindowsStylePrivate::windowsArrowHMargin;
+ else if (mi->menuItemType == QStyleOptionMenuItem::DefaultItem) {
+ // adjust the font and add the difference in size.
+ // it would be better if the font could be adjusted in the initStyleOption qmenu func!!
+ QFontMetrics fm(mi->font);
+ QFont fontBold = mi->font;
+ fontBold.setBold(true);
+ QFontMetrics fmBold(fontBold);
+ w += fmBold.width(mi->text) - fm.width(mi->text);
+ }
+
+ int checkcol = qMax<int>(maxpmw, QWindowsStylePrivate::windowsCheckMarkWidth); // Windows always shows a check column
+ w += checkcol;
+ w += int(QWindowsStylePrivate::windowsRightBorder) + 10;
+ sz.setWidth(w);
+ }
+ break;
+#endif // QT_NO_MENU
+#ifndef QT_NO_MENUBAR
+ case CT_MenuBarItem:
+ if (!sz.isEmpty())
+ sz += QSize(QWindowsStylePrivate::windowsItemHMargin * 4, QWindowsStylePrivate::windowsItemVMargin * 2);
+ break;
+#endif
+ // Otherwise, fall through
+ case CT_ToolButton:
+ if (qstyleoption_cast<const QStyleOptionToolButton *>(opt))
+ return sz += QSize(7, 6);
+ // Otherwise, fall through
+
+ default:
+ sz = QCommonStyle::sizeFromContents(ct, opt, csz, widget);
+ }
+ return sz;
+}
+
+/*!
+ \internal
+*/
+QIcon QWindowsStyle::standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *option,
+ const QWidget *widget) const
+{
+ QIcon icon;
+ QPixmap pixmap;
+#ifdef Q_WS_WIN
+ switch (standardIcon) {
+ case SP_FileDialogNewFolder:
+ {
+ for (int size = 16 ; size <= 32 ; size += 16) {
+ pixmap = loadIconFromShell32(319, size);
+ icon.addPixmap(pixmap, QIcon::Normal);
+ }
+ break;
+ }
+ case SP_DirHomeIcon:
+ {
+ for (int size = 16 ; size <= 32 ; size += 16) {
+ pixmap = loadIconFromShell32(235, size);
+ icon.addPixmap(pixmap, QIcon::Normal);
+ }
+ break;
+ }
+ case SP_DirIcon:
+ for (int size = 16 ; size <= 32 ; size += 16) {
+ pixmap = loadIconFromShell32(4, size);
+ icon.addPixmap(pixmap, QIcon::Normal, QIcon::Off);
+ pixmap = loadIconFromShell32(5, size);
+ icon.addPixmap(pixmap, QIcon::Normal, QIcon::On);
+ }
+ break;
+ case SP_DirLinkIcon:
+ for (int size = 16 ; size <= 32 ; size += 16) {
+ QPixmap link = loadIconFromShell32(30, size);
+ pixmap = loadIconFromShell32(4, size);
+ if (!pixmap.isNull() && !link.isNull()) {
+ QPainter painter(&pixmap);
+ painter.drawPixmap(0, 0, size, size, link);
+ icon.addPixmap(pixmap, QIcon::Normal, QIcon::Off);
+ }
+ link = loadIconFromShell32(30, size);
+ pixmap = loadIconFromShell32(5, size);
+ if (!pixmap.isNull() && !link.isNull()) {
+ QPainter painter(&pixmap);
+ painter.drawPixmap(0, 0, size, size, link);
+ icon.addPixmap(pixmap, QIcon::Normal, QIcon::On);
+ }
+ }
+ break;
+ case SP_FileIcon:
+ for (int size = 16 ; size <= 32 ; size += 16) {
+ pixmap = loadIconFromShell32(1, size);
+ icon.addPixmap(pixmap, QIcon::Normal);
+ }
+ break;
+ case SP_ComputerIcon:
+ for (int size = 16 ; size <= 32 ; size += 16) {
+ pixmap = loadIconFromShell32(16, size);
+ icon.addPixmap(pixmap, QIcon::Normal);
+ }
+ break;
+
+ case SP_DesktopIcon:
+ for (int size = 16 ; size <= 32 ; size += 16) {
+ pixmap = loadIconFromShell32(35, size);
+ icon.addPixmap(pixmap, QIcon::Normal);
+ }
+ break;
+ case SP_DriveCDIcon:
+ case SP_DriveDVDIcon:
+ for (int size = 16 ; size <= 32 ; size += 16) {
+ pixmap = loadIconFromShell32(12, size);
+ icon.addPixmap(pixmap, QIcon::Normal);
+ }
+ break;
+ case SP_DriveNetIcon:
+ for (int size = 16 ; size <= 32 ; size += 16) {
+ pixmap = loadIconFromShell32(10, size);
+ icon.addPixmap(pixmap, QIcon::Normal);
+ }
+ break;
+ case SP_DriveHDIcon:
+ for (int size = 16 ; size <= 32 ; size += 16) {
+ pixmap = loadIconFromShell32(9, size);
+ icon.addPixmap(pixmap, QIcon::Normal);
+ }
+ break;
+ case SP_DriveFDIcon:
+ for (int size = 16 ; size <= 32 ; size += 16) {
+ pixmap = loadIconFromShell32(7, size);
+ icon.addPixmap(pixmap, QIcon::Normal);
+ }
+ break;
+ case SP_FileLinkIcon:
+ for (int size = 16 ; size <= 32 ; size += 16) {
+ QPixmap link;
+ link = loadIconFromShell32(30, size);
+ pixmap = loadIconFromShell32(1, size);
+ if (!pixmap.isNull() && !link.isNull()) {
+ QPainter painter(&pixmap);
+ painter.drawPixmap(0, 0, size, size, link);
+ icon.addPixmap(pixmap, QIcon::Normal);
+ }
+ }
+ break;
+ case SP_VistaShield:
+ {
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA
+ && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based
+ && pSHGetStockIconInfo)
+ {
+ icon.addPixmap(proxy()->standardPixmap(SP_VistaShield, option, widget)); //fetches small icon
+ QSHSTOCKICONINFO iconInfo; //append large icon
+ memset(&iconInfo, 0, sizeof(iconInfo));
+ iconInfo.cbSize = sizeof(iconInfo);
+ if (pSHGetStockIconInfo(_SIID_SHIELD, _SHGFI_ICON | _SHGFI_LARGEICON, &iconInfo) == S_OK) {
+ icon.addPixmap(QPixmap::fromWinHICON(iconInfo.hIcon));
+ DestroyIcon(iconInfo.hIcon);
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+#endif
+
+ if (icon.isNull())
+ icon = QCommonStyle::standardIconImplementation(standardIcon, option, widget);
+ return icon;
+}
+
+
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_STYLE_WINDOWS
diff --git a/src/widgets/styles/qwindowsstyle.h b/src/widgets/styles/qwindowsstyle.h
new file mode 100644
index 0000000000..acecfa9140
--- /dev/null
+++ b/src/widgets/styles/qwindowsstyle.h
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSSTYLE_H
+#define QWINDOWSSTYLE_H
+
+#include <QtWidgets/qcommonstyle.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#if !defined(QT_NO_STYLE_WINDOWS)
+
+class QWindowsStylePrivate;
+
+class Q_WIDGETS_EXPORT QWindowsStyle : public QCommonStyle
+{
+ Q_OBJECT
+public:
+ QWindowsStyle();
+ ~QWindowsStyle();
+
+ void polish(QApplication*);
+ void unpolish(QApplication*);
+
+ void polish(QWidget*);
+ void unpolish(QWidget*);
+
+ void polish(QPalette &);
+
+ void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p,
+ const QWidget *w = 0) const;
+ void drawControl(ControlElement element, const QStyleOption *opt, QPainter *p,
+ const QWidget *w = 0) const;
+ QRect subElementRect(SubElement r, const QStyleOption *opt, const QWidget *widget = 0) const;
+ void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p,
+ const QWidget *w = 0) const;
+ QSize sizeFromContents(ContentsType ct, const QStyleOption *opt,
+ const QSize &contentsSize, const QWidget *widget = 0) const;
+
+ int pixelMetric(PixelMetric pm, const QStyleOption *option = 0, const QWidget *widget = 0) const;
+
+ int styleHint(StyleHint hint, const QStyleOption *opt = 0, const QWidget *widget = 0,
+ QStyleHintReturn *returnData = 0) const;
+
+ QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt,
+ const QWidget *widget = 0) const;
+
+protected Q_SLOTS:
+ QIcon standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *option,
+ const QWidget *widget = 0) const;
+
+protected:
+ bool eventFilter(QObject *o, QEvent *e);
+ void timerEvent(QTimerEvent *event);
+ QWindowsStyle(QWindowsStylePrivate &dd);
+
+private:
+ Q_DISABLE_COPY(QWindowsStyle)
+ Q_DECLARE_PRIVATE(QWindowsStyle)
+ void *reserved;
+};
+
+#endif // QT_NO_STYLE_WINDOWS
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QWINDOWSSTYLE_H
diff --git a/src/gui/styles/qwindowsstyle_p.h b/src/widgets/styles/qwindowsstyle_p.h
index b9f39a0940..b9f39a0940 100644
--- a/src/gui/styles/qwindowsstyle_p.h
+++ b/src/widgets/styles/qwindowsstyle_p.h
diff --git a/src/widgets/styles/qwindowsvistastyle.cpp b/src/widgets/styles/qwindowsvistastyle.cpp
new file mode 100644
index 0000000000..55e83f79fa
--- /dev/null
+++ b/src/widgets/styles/qwindowsvistastyle.cpp
@@ -0,0 +1,2672 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsvistastyle.h"
+#include "qwindowsvistastyle_p.h"
+#include <private/qstylehelper_p.h>
+#include <private/qsystemlibrary_p.h>
+#include <private/qapplication_p.h>
+#include <qplatformnativeinterface_qpa.h>
+
+#if !defined(QT_NO_STYLE_WINDOWSVISTA) || defined(QT_PLUGIN)
+
+QT_BEGIN_NAMESPACE
+
+static const int windowsItemFrame = 2; // menu item frame width
+static const int windowsItemHMargin = 3; // menu item hor text margin
+static const int windowsItemVMargin = 4; // menu item ver text margin
+static const int windowsArrowHMargin = 6; // arrow horizontal margin
+static const int windowsRightBorder = 15; // right border on windows
+
+#ifndef TMT_CONTENTMARGINS
+# define TMT_CONTENTMARGINS 3602
+#endif
+#ifndef TMT_SIZINGMARGINS
+# define TMT_SIZINGMARGINS 3601
+#endif
+#ifndef LISS_NORMAL
+# define LISS_NORMAL 1
+# define LISS_HOT 2
+# define LISS_SELECTED 3
+# define LISS_DISABLED 4
+# define LISS_SELECTEDNOTFOCUS 5
+# define LISS_HOTSELECTED 6
+#endif
+#ifndef BP_COMMANDLINK
+# define BP_COMMANDLINK 6
+# define BP_COMMANDLINKGLYPH 7
+# define CMDLGS_NORMAL 1
+# define CMDLGS_HOT 2
+# define CMDLGS_PRESSED 3
+# define CMDLGS_DISABLED 4
+#endif
+
+// Runtime resolved theme engine function calls
+
+
+typedef HRESULT (WINAPI *PtrGetThemePartSize)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, OPTIONAL RECT *prc, enum THEMESIZE eSize, OUT SIZE *psz);
+typedef HTHEME (WINAPI *PtrOpenThemeData)(HWND hwnd, LPCWSTR pszClassList);
+typedef HTHEME (WINAPI *PtrOpenThemeData)(HWND hwnd, LPCWSTR pszClassList);
+typedef HRESULT (WINAPI *PtrCloseThemeData)(HTHEME hTheme);
+typedef HRESULT (WINAPI *PtrDrawThemeBackground)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, OPTIONAL const RECT *pClipRect);
+typedef HRESULT (WINAPI *PtrDrawThemeBackgroundEx)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, OPTIONAL const DTBGOPTS *pOptions);
+typedef HRESULT (WINAPI *PtrGetCurrentThemeName)(OUT LPWSTR pszThemeFileName, int cchMaxNameChars, OUT OPTIONAL LPWSTR pszColorBuff, int cchMaxColorChars, OUT OPTIONAL LPWSTR pszSizeBuff, int cchMaxSizeChars);
+typedef HRESULT (WINAPI *PtrGetThemeBool)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT BOOL *pfVal);
+typedef HRESULT (WINAPI *PtrGetThemeColor)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT COLORREF *pColor);
+typedef HRESULT (WINAPI *PtrGetThemeEnumValue)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT int *piVal);
+typedef HRESULT (WINAPI *PtrGetThemeFilename)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT LPWSTR pszThemeFileName, int cchMaxBuffChars);
+typedef HRESULT (WINAPI *PtrGetThemeFont)(HTHEME hTheme, OPTIONAL HDC hdc, int iPartId, int iStateId, int iPropId, OUT LOGFONT *pFont);
+typedef HRESULT (WINAPI *PtrGetThemeInt)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT int *piVal);
+typedef HRESULT (WINAPI *PtrGetThemeIntList)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT INTLIST *pIntList);
+typedef HRESULT (WINAPI *PtrGetThemeMargins)(HTHEME hTheme, OPTIONAL HDC hdc, int iPartId, int iStateId, int iPropId, OPTIONAL RECT *prc, OUT MARGINS *pMargins);
+typedef HRESULT (WINAPI *PtrGetThemeMetric)(HTHEME hTheme, OPTIONAL HDC hdc, int iPartId, int iStateId, int iPropId, OUT int *piVal);
+typedef HRESULT (WINAPI *PtrGetThemePartSize)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, OPTIONAL RECT *prc, enum THEMESIZE eSize, OUT SIZE *psz);
+typedef HRESULT (WINAPI *PtrGetThemePosition)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT POINT *pPoint);
+typedef HRESULT (WINAPI *PtrGetThemeRect)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT RECT *pRect);
+typedef HRESULT (WINAPI *PtrGetThemeString)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT LPWSTR pszBuff, int cchMaxBuffChars);
+typedef HRESULT (WINAPI *PtrGetThemeTransitionDuration)(HTHEME hTheme, int iPartId, int iStateFromId, int iStateToId, int iPropId, int *pDuration);
+typedef HRESULT (WINAPI *PtrIsThemePartDefined)(HTHEME hTheme, int iPartId, int iStateId);
+typedef HRESULT (WINAPI *PtrSetWindowTheme)(HWND hwnd, LPCWSTR pszSubAppName, LPCWSTR pszSubIdList);
+typedef HRESULT (WINAPI *PtrGetThemePropertyOrigin)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT enum PROPERTYORIGIN *pOrigin);
+
+static PtrIsThemePartDefined pIsThemePartDefined = 0;
+static PtrOpenThemeData pOpenThemeData = 0;
+static PtrCloseThemeData pCloseThemeData = 0;
+static PtrDrawThemeBackground pDrawThemeBackground = 0;
+static PtrDrawThemeBackgroundEx pDrawThemeBackgroundEx = 0;
+static PtrGetCurrentThemeName pGetCurrentThemeName = 0;
+static PtrGetThemeBool pGetThemeBool = 0;
+static PtrGetThemeColor pGetThemeColor = 0;
+static PtrGetThemeEnumValue pGetThemeEnumValue = 0;
+static PtrGetThemeFilename pGetThemeFilename = 0;
+static PtrGetThemeFont pGetThemeFont = 0;
+static PtrGetThemeInt pGetThemeInt = 0;
+static PtrGetThemeIntList pGetThemeIntList = 0;
+static PtrGetThemeMargins pGetThemeMargins = 0;
+static PtrGetThemeMetric pGetThemeMetric = 0;
+static PtrGetThemePartSize pGetThemePartSize = 0;
+static PtrGetThemePosition pGetThemePosition = 0;
+static PtrGetThemeRect pGetThemeRect = 0;
+static PtrGetThemeString pGetThemeString = 0;
+static PtrGetThemeTransitionDuration pGetThemeTransitionDuration= 0;
+static PtrSetWindowTheme pSetWindowTheme = 0;
+static PtrGetThemePropertyOrigin pGetThemePropertyOrigin = 0;
+
+/* \internal
+ Checks if we should use Vista style , or if we should
+ fall back to Windows style.
+*/
+bool QWindowsVistaStylePrivate::useVista()
+{
+ return (QWindowsVistaStylePrivate::useXP() &&
+ (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA &&
+ QSysInfo::WindowsVersion < QSysInfo::WV_NT_based));
+}
+
+/*!
+ \class QWindowsVistaStyle
+ \brief The QWindowsVistaStyle class provides a look and feel suitable for applications on Microsoft Windows Vista.
+ \since 4.3
+ \ingroup appearance
+
+ \warning This style is only available on the Windows Vista platform
+ because it makes use of Windows Vista's style engine.
+
+ \sa QMacStyle, QWindowsXPStyle, QPlastiqueStyle, QCleanlooksStyle, QMotifStyle
+*/
+
+/*!
+ Constructs a QWindowsVistaStyle object.
+*/
+QWindowsVistaStyle::QWindowsVistaStyle()
+ : QWindowsXPStyle(*new QWindowsVistaStylePrivate)
+{
+}
+
+//convert Qt state flags to uxtheme button states
+static int buttonStateId(int flags, int partId)
+{
+ int stateId = 0;
+ if (partId == BP_RADIOBUTTON || partId == BP_CHECKBOX) {
+ if (!(flags & QStyle::State_Enabled))
+ stateId = RBS_UNCHECKEDDISABLED;
+ else if (flags & QStyle::State_Sunken)
+ stateId = RBS_UNCHECKEDPRESSED;
+ else if (flags & QStyle::State_MouseOver)
+ stateId = RBS_UNCHECKEDHOT;
+ else
+ stateId = RBS_UNCHECKEDNORMAL;
+
+ if (flags & QStyle::State_On)
+ stateId += RBS_CHECKEDNORMAL-1;
+
+ } else if (partId == BP_PUSHBUTTON) {
+ if (!(flags & QStyle::State_Enabled))
+ stateId = PBS_DISABLED;
+ else if (flags & (QStyle::State_Sunken | QStyle::State_On))
+ stateId = PBS_PRESSED;
+ else if (flags & QStyle::State_MouseOver)
+ stateId = PBS_HOT;
+ else
+ stateId = PBS_NORMAL;
+ } else {
+ Q_ASSERT(1);
+ }
+ return stateId;
+}
+
+void QWindowsVistaAnimation::paint(QPainter *painter, const QStyleOption *option)
+{
+ Q_UNUSED(option);
+ Q_UNUSED(painter);
+}
+
+/*! \internal
+
+ Helperfunction to paint the current transition state between two
+ animation frames.
+
+ The result is a blended image consisting of ((alpha)*_primaryImage)
+ + ((1-alpha)*_secondaryImage)
+
+*/
+void QWindowsVistaAnimation::drawBlendedImage(QPainter *painter, QRect rect, float alpha) {
+ if (_secondaryImage.isNull() || _primaryImage.isNull())
+ return;
+
+ if (_tempImage.isNull())
+ _tempImage = _secondaryImage;
+
+ const int a = qRound(alpha*256);
+ const int ia = 256 - a;
+ const int sw = _primaryImage.width();
+ const int sh = _primaryImage.height();
+ const int bpl = _primaryImage.bytesPerLine();
+ switch(_primaryImage.depth()) {
+ case 32:
+ {
+ uchar *mixed_data = _tempImage.bits();
+ const uchar *back_data = _primaryImage.bits();
+ const uchar *front_data = _secondaryImage.bits();
+ for (int sy = 0; sy < sh; sy++) {
+ quint32* mixed = (quint32*)mixed_data;
+ const quint32* back = (const quint32*)back_data;
+ const quint32* front = (const quint32*)front_data;
+ for (int sx = 0; sx < sw; sx++) {
+ quint32 bp = back[sx];
+ quint32 fp = front[sx];
+ mixed[sx] = qRgba ((qRed(bp)*ia + qRed(fp)*a)>>8,
+ (qGreen(bp)*ia + qGreen(fp)*a)>>8,
+ (qBlue(bp)*ia + qBlue(fp)*a)>>8,
+ (qAlpha(bp)*ia + qAlpha(fp)*a)>>8);
+ }
+ mixed_data += bpl;
+ back_data += bpl;
+ front_data += bpl;
+ }
+ }
+ default:
+ break;
+ }
+ painter->drawImage(rect, _tempImage);
+}
+
+/*! \internal
+ Paints a transition state. The result will be a mix between the
+ initial and final state of the transition, depending on the time
+ difference between _startTime and current time.
+*/
+void QWindowsVistaTransition::paint(QPainter *painter, const QStyleOption *option)
+{
+ float alpha = 1.0;
+ if (_duration > 0) {
+ QTime current = QTime::currentTime();
+
+ if (_startTime > current)
+ _startTime = current;
+
+ int timeDiff = _startTime.msecsTo(current);
+ alpha = timeDiff/(float)_duration;
+ if (timeDiff > _duration) {
+ _running = false;
+ alpha = 1.0;
+ }
+ }
+ else {
+ _running = false;
+ }
+ drawBlendedImage(painter, option->rect, alpha);
+}
+
+/*! \internal
+ Paints a pulse. The result will be a mix between the primary and
+ secondary pulse images depending on the time difference between
+ _startTime and current time.
+*/
+void QWindowsVistaPulse::paint(QPainter *painter, const QStyleOption *option)
+{
+ float alpha = 1.0;
+ if (_duration > 0) {
+ QTime current = QTime::currentTime();
+
+ if (_startTime > current)
+ _startTime = current;
+
+ int timeDiff = _startTime.msecsTo(current) % _duration*2;
+ if (timeDiff > _duration)
+ timeDiff = _duration*2 - timeDiff;
+ alpha = timeDiff/(float)_duration;
+ } else {
+ _running = false;
+ }
+ drawBlendedImage(painter, option->rect, alpha);
+}
+
+
+/*!
+ \internal
+
+ Animations are used for some state transitions on specific widgets.
+
+ Only one running animation can exist for a widget at any specific
+ time. Animations can be added through
+ QWindowsVistaStylePrivate::startAnimation(Animation *) and any
+ existing animation on a widget can be retrieved with
+ QWindowsVistaStylePrivate::widgetAnimation(Widget *).
+
+ Once an animation has been started,
+ QWindowsVistaStylePrivate::timerEvent(QTimerEvent *) will
+ continuously call update() on the widget until it is stopped,
+ meaning that drawPrimitive will be called many times until the
+ transition has completed. During this time, the result will be
+ retrieved by the Animation::paint(...) function and not by the style
+ itself.
+
+ To determine if a transition should occur, the style needs to know
+ the previous state of the widget as well as the current one. This is
+ solved by updating dynamic properties on the widget every time the
+ function is called.
+
+ Transitions interrupting existing transitions should always be
+ smooth, so whenever a hover-transition is started on a pulsating
+ button, it uses the current frame of the pulse-animation as the
+ starting image for the hover transition.
+
+ */
+void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option,
+ QPainter *painter, const QWidget *widget) const
+{
+ QWindowsVistaStylePrivate *d = const_cast<QWindowsVistaStylePrivate*>(d_func());
+
+ int state = option->state;
+ if (!QWindowsVistaStylePrivate::useVista()) {
+ QWindowsStyle::drawPrimitive(element, option, painter, widget);
+ return;
+ }
+
+ QRect oldRect;
+ QRect newRect;
+
+ if (widget && d->transitionsEnabled())
+ {
+ /* all widgets that supports state transitions : */
+ if (
+#ifndef QT_NO_LINEEDIT
+ (qobject_cast<const QLineEdit*>(widget) && element == PE_FrameLineEdit) ||
+#endif // QT_NO_LINEEDIT
+ (qobject_cast<const QRadioButton*>(widget)&& element == PE_IndicatorRadioButton) ||
+ (qobject_cast<const QCheckBox*>(widget) && element == PE_IndicatorCheckBox) ||
+ (qobject_cast<const QGroupBox *>(widget)&& element == PE_IndicatorCheckBox) ||
+ (qobject_cast<const QToolButton*>(widget) && element == PE_PanelButtonBevel)
+ )
+ {
+ // Retrieve and update the dynamic properties tracking
+ // the previous state of the widget:
+ QWidget *w = const_cast<QWidget *> (widget);
+ int oldState = w->property("_q_stylestate").toInt();
+ oldRect = w->property("_q_stylerect").toRect();
+ newRect = w->rect();
+ w->setProperty("_q_stylestate", (int)option->state);
+ w->setProperty("_q_stylerect", w->rect());
+
+ bool doTransition = oldState &&
+ ((state & State_Sunken) != (oldState & State_Sunken) ||
+ (state & State_On) != (oldState & State_On) ||
+ (state & State_MouseOver) != (oldState & State_MouseOver));
+
+ if (oldRect != newRect ||
+ (state & State_Enabled) != (oldState & State_Enabled) ||
+ (state & State_Active) != (oldState & State_Active))
+ d->stopAnimation(widget);
+
+#ifndef QT_NO_LINEEDIT
+ if (const QLineEdit *edit = qobject_cast<const QLineEdit *>(widget))
+ if (edit->isReadOnly() && element == PE_FrameLineEdit) // Do not animate read only line edits
+ doTransition = false;
+#endif // QT_NO_LINEEDIT
+
+ if (doTransition) {
+
+ // We create separate images for the initial and final transition states and store them in the
+ // Transition object.
+ QImage startImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
+ QImage endImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
+ QStyleOption opt = *option;
+
+ opt.rect.setRect(0, 0, option->rect.width(), option->rect.height());
+ opt.state = (QStyle::State)oldState;
+ startImage.fill(0);
+ QPainter startPainter(&startImage);
+
+ QWindowsVistaAnimation *anim = d->widgetAnimation(widget);
+ QWindowsVistaTransition *t = new QWindowsVistaTransition;
+ t->setWidget(w);
+
+ // If we have a running animation on the widget already, we will use that to paint the initial
+ // state of the new transition, this ensures a smooth transition from a current animation such as a
+ // pulsating default button into the intended target state.
+
+ if (!anim)
+ proxy()->drawPrimitive(element, &opt, &startPainter, 0); // Note that the widget pointer is intentionally 0
+ else // this ensures that we do not recurse in the animation logic above
+ anim->paint(&startPainter, &opt);
+
+ d->startAnimation(t);
+ t->setStartImage(startImage);
+
+ // The end state of the transition is simply the result we would have painted
+ // if the style was not animated.
+
+ QPainter endPainter(&endImage);
+ endImage.fill(0);
+ QStyleOption opt2 = opt;
+ opt2.state = option->state;
+ proxy()->drawPrimitive(element, &opt2, &endPainter, 0); // Note that the widget pointer is intentionally 0
+ // this ensures that we do not recurse in the animation logic above
+ t->setEndImage(endImage);
+
+ HTHEME theme;
+ int partId;
+ int duration;
+ int fromState = 0;
+ int toState = 0;
+
+ //translate state flags to UXTHEME states :
+ if (element == PE_FrameLineEdit) {
+ theme = pOpenThemeData(0, L"Edit");
+ partId = EP_EDITBORDER_NOSCROLL;
+
+ if (oldState & State_MouseOver)
+ fromState = ETS_HOT;
+ else if (oldState & State_HasFocus)
+ fromState = ETS_FOCUSED;
+ else
+ fromState = ETS_NORMAL;
+
+ if (state & State_MouseOver)
+ toState = ETS_HOT;
+ else if (state & State_HasFocus)
+ toState = ETS_FOCUSED;
+ else
+ toState = ETS_NORMAL;
+
+ } else {
+ theme = pOpenThemeData(0, L"Button");
+ if (element == PE_IndicatorRadioButton)
+ partId = BP_RADIOBUTTON;
+ else if (element == PE_IndicatorCheckBox)
+ partId = BP_CHECKBOX;
+ else
+ partId = BP_PUSHBUTTON;
+
+ fromState = buttonStateId(oldState, partId);
+ toState = buttonStateId(option->state, partId);
+ }
+
+ // Retrieve the transition time between the states from the system.
+ if (theme && pGetThemeTransitionDuration(theme, partId, fromState, toState,
+ TMT_TRANSITIONDURATIONS, &duration) == S_OK)
+ {
+ t->setDuration(duration);
+ }
+ t->setStartTime(QTime::currentTime());
+ }
+ }
+ } // End of animation part
+
+
+ QRect rect = option->rect;
+
+ switch (element) {
+ case PE_IndicatorHeaderArrow:
+ if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
+ int stateId = HSAS_SORTEDDOWN;
+ if (header->sortIndicator & QStyleOptionHeader::SortDown)
+ stateId = HSAS_SORTEDUP; //note that the uxtheme sort down indicator is the inverse of ours
+ XPThemeData theme(widget, painter, QLatin1String("HEADER"), HP_HEADERSORTARROW, stateId, option->rect);
+ d->drawBackground(theme);
+ }
+ break;
+
+ case PE_IndicatorBranch:
+ {
+ XPThemeData theme(d->treeViewHelper(), painter, QLatin1String("TREEVIEW"));
+ static int decoration_size = 0;
+ if (theme.isValid() && !decoration_size) {
+ SIZE size;
+ pGetThemePartSize(theme.handle(), 0, TVP_HOTGLYPH, GLPS_OPENED, 0, TS_TRUE, &size);
+ decoration_size = qMax(size.cx, size.cy);
+ }
+ int mid_h = option->rect.x() + option->rect.width() / 2;
+ int mid_v = option->rect.y() + option->rect.height() / 2;
+ int bef_h = mid_h;
+ int bef_v = mid_v;
+ int aft_h = mid_h;
+ int aft_v = mid_v;
+ if (option->state & State_Children) {
+ int delta = decoration_size / 2;
+ theme.rect = QRect(bef_h - delta, bef_v - delta, decoration_size, decoration_size);
+ theme.partId = option->state & State_MouseOver ? TVP_HOTGLYPH : TVP_GLYPH;
+ theme.stateId = option->state & QStyle::State_Open ? GLPS_OPENED : GLPS_CLOSED;
+ if (option->direction == Qt::RightToLeft)
+ theme.mirrorHorizontally = true;
+ d->drawBackground(theme);
+ bef_h -= delta + 2;
+ bef_v -= delta + 2;
+ aft_h += delta - 2;
+ aft_v += delta - 2;
+ }
+#if 0
+ QBrush brush(option->palette.dark().color(), Qt::Dense4Pattern);
+ if (option->state & State_Item) {
+ if (option->direction == Qt::RightToLeft)
+ painter->fillRect(option->rect.left(), mid_v, bef_h - option->rect.left(), 1, brush);
+ else
+ painter->fillRect(aft_h, mid_v, option->rect.right() - aft_h + 1, 1, brush);
+ }
+ if (option->state & State_Sibling && option->rect.bottom() > aft_v)
+ painter->fillRect(mid_h, aft_v, 1, option->rect.bottom() - aft_v + 1, brush);
+ if (option->state & (State_Open | State_Children | State_Item | State_Sibling) && (bef_v > option->rect.y()))
+ painter->fillRect(mid_h, option->rect.y(), 1, bef_v - option->rect.y(), brush);
+#endif
+ }
+ break;
+
+ case PE_PanelButtonBevel:
+ case PE_IndicatorCheckBox:
+ case PE_IndicatorRadioButton:
+ {
+ if (QWindowsVistaAnimation *a = d->widgetAnimation(widget)) {
+ a->paint(painter, option);
+ } else {
+ QWindowsXPStyle::drawPrimitive(element, option, painter, widget);
+ }
+ }
+ break;
+
+ case PE_FrameMenu:
+ {
+ int stateId = option->state & State_Active ? MB_ACTIVE : MB_INACTIVE;
+ XPThemeData theme(widget, painter, QLatin1String("MENU"), MENU_POPUPBORDERS, stateId, option->rect);
+ d->drawBackground(theme);
+ }
+ break;
+ case PE_Frame:
+#ifndef QT_NO_TEXTEDIT
+ if (const QTextEdit *edit = qobject_cast<const QTextEdit*>(widget)) {
+ painter->save();
+ int stateId = ETS_NORMAL;
+ if (!(state & State_Enabled))
+ stateId = ETS_DISABLED;
+ else if (edit->isReadOnly())
+ stateId = ETS_READONLY;
+ else if (state & State_HasFocus)
+ stateId = ETS_SELECTED;
+ XPThemeData theme(widget, painter, QLatin1String("EDIT"), EP_EDITBORDER_HVSCROLL, stateId, option->rect);
+ uint resolve_mask = option->palette.resolve();
+ if (resolve_mask & (1 << QPalette::Base)) {
+ // Since EP_EDITBORDER_HVSCROLL does not us borderfill, theme.noContent cannot be used for clipping
+ int borderSize = 1;
+ pGetThemeInt(theme.handle(), theme.partId, theme.stateId, TMT_BORDERSIZE, &borderSize);
+ QRegion clipRegion = option->rect;
+ QRegion content = option->rect.adjusted(borderSize, borderSize, -borderSize, -borderSize);
+ clipRegion ^= content;
+ painter->setClipRegion(clipRegion);
+ }
+ d->drawBackground(theme);
+ painter->restore();
+ } else
+#endif // QT_NO_TEXTEDIT
+ QWindowsXPStyle::drawPrimitive(element, option, painter, widget);
+ break;
+
+ case PE_PanelLineEdit:
+ if (const QStyleOptionFrame *panel = qstyleoption_cast<const QStyleOptionFrame *>(option)) {
+ QBrush bg;
+ bool usePalette = false;
+ bool isEnabled = option->state & State_Enabled;
+ uint resolve_mask = panel->palette.resolve();
+ if (widget) {
+ //Since spin box and combo box includes a line edit we need to resolve the palette on the parent instead
+#ifndef QT_NO_SPINBOX
+ if (QAbstractSpinBox *spinbox = qobject_cast<QAbstractSpinBox*>(widget->parentWidget()))
+ resolve_mask = spinbox->palette().resolve();
+#endif // QT_NO_SPINBOX
+ }
+ if (resolve_mask & (1 << QPalette::Base)) {
+ // Base color is set for this widget, so use it
+ bg = panel->palette.brush(QPalette::Base);
+ usePalette = true;
+ }
+ if (usePalette) {
+ painter->fillRect(panel->rect, bg);
+ } else {
+ int partId = EP_BACKGROUND;
+ int stateId = EBS_NORMAL;
+ if (!isEnabled)
+ stateId = EBS_DISABLED;
+ else if (state & State_ReadOnly)
+ stateId = EBS_READONLY;
+ else if (state & State_MouseOver)
+ stateId = EBS_HOT;
+
+ XPThemeData theme(0, painter, QLatin1String("EDIT"), partId, stateId, rect);
+ if (!theme.isValid()) {
+ QWindowsStyle::drawPrimitive(element, option, painter, widget);
+ return;
+ }
+ int bgType;
+ pGetThemeEnumValue( theme.handle(),
+ partId,
+ stateId,
+ TMT_BGTYPE,
+ &bgType);
+ if( bgType == BT_IMAGEFILE ) {
+ d->drawBackground(theme);
+ } else {
+ QBrush fillColor = option->palette.brush(QPalette::Base);
+ if (!isEnabled) {
+ PROPERTYORIGIN origin = PO_NOTFOUND;
+ pGetThemePropertyOrigin(theme.handle(), theme.partId, theme.stateId, TMT_FILLCOLOR, &origin);
+ // Use only if the fill property comes from our part
+ if ((origin == PO_PART || origin == PO_STATE)) {
+ COLORREF bgRef;
+ pGetThemeColor(theme.handle(), partId, stateId, TMT_FILLCOLOR, &bgRef);
+ fillColor = QBrush(qRgb(GetRValue(bgRef), GetGValue(bgRef), GetBValue(bgRef)));
+ }
+ }
+ painter->fillRect(option->rect, fillColor);
+ }
+ }
+ if (panel->lineWidth > 0)
+ proxy()->drawPrimitive(PE_FrameLineEdit, panel, painter, widget);
+ return;
+ }
+ break;
+
+ case PE_FrameLineEdit:
+ if (QWindowsVistaAnimation *anim = d->widgetAnimation(widget)) {
+ anim->paint(painter, option);
+ } else {
+ QPainter *p = painter;
+ QWidget *parentWidget = 0;
+ if (widget) {
+ parentWidget = widget->parentWidget();
+ if (parentWidget)
+ parentWidget = parentWidget->parentWidget();
+ }
+ if (widget && widget->inherits("QLineEdit")
+ && parentWidget && parentWidget->inherits("QAbstractItemView")) {
+ // we try to check if this lineedit is a delegate on a QAbstractItemView-derived class.
+ QPen oldPen = p->pen();
+ // Inner white border
+ p->setPen(QPen(option->palette.base().color(), 1));
+ p->drawRect(option->rect.adjusted(1, 1, -2, -2));
+ // Outer dark border
+ p->setPen(QPen(option->palette.shadow().color(), 1));
+ p->drawRect(option->rect.adjusted(0, 0, -1, -1));
+ p->setPen(oldPen);
+ return;
+ } else {
+ int stateId = ETS_NORMAL;
+ if (!(state & State_Enabled))
+ stateId = ETS_DISABLED;
+ else if (state & State_ReadOnly)
+ stateId = ETS_READONLY;
+ else if (state & State_MouseOver)
+ stateId = ETS_HOT;
+ else if (state & State_HasFocus)
+ stateId = ETS_SELECTED;
+ XPThemeData theme(widget, painter, QLatin1String("EDIT"), EP_EDITBORDER_NOSCROLL, stateId, option->rect);
+ painter->save();
+ QRegion clipRegion = option->rect;
+ clipRegion -= option->rect.adjusted(2, 2, -2, -2);
+ painter->setClipRegion(clipRegion);
+ d->drawBackground(theme);
+ painter->restore();
+ }
+ }
+ break;
+
+ case PE_IndicatorToolBarHandle:
+ {
+ XPThemeData theme;
+ QRect rect;
+ if (option->state & State_Horizontal) {
+ theme = XPThemeData(widget, painter, QLatin1String("REBAR"), RP_GRIPPER, ETS_NORMAL, option->rect.adjusted(0, 1, -2, -2));
+ rect = option->rect.adjusted(0, 1, 0, -2);
+ rect.setWidth(4);
+ } else {
+ theme = XPThemeData(widget, painter, QLatin1String("REBAR"), RP_GRIPPERVERT, ETS_NORMAL, option->rect.adjusted(0, 1, -2, -2));
+ rect = option->rect.adjusted(1, 0, -1, 0);
+ rect.setHeight(4);
+ }
+ theme.rect = rect;
+ d->drawBackground(theme);
+ }
+ break;
+
+ case PE_IndicatorToolBarSeparator:
+ {
+ QPen pen = painter->pen();
+ int margin = 3;
+ painter->setPen(option->palette.background().color().darker(114));
+ if (option->state & State_Horizontal) {
+ int x1 = option->rect.center().x();
+ painter->drawLine(QPoint(x1, option->rect.top() + margin), QPoint(x1, option->rect.bottom() - margin));
+ } else {
+ int y1 = option->rect.center().y();
+ painter->drawLine(QPoint(option->rect.left() + margin, y1), QPoint(option->rect.right() - margin, y1));
+ }
+ painter->setPen(pen);
+ }
+ break;
+
+ case PE_PanelTipLabel: {
+ XPThemeData theme(widget, painter, QLatin1String("TOOLTIP"), TTP_STANDARD, TTSS_NORMAL, option->rect);
+ d->drawBackground(theme);
+ break;
+ }
+
+ case PE_PanelItemViewItem:
+ {
+ const QStyleOptionViewItemV4 *vopt;
+ const QAbstractItemView *view = qobject_cast<const QAbstractItemView *>(widget);
+ bool newStyle = true;
+
+ if (qobject_cast<const QTableView*>(widget))
+ newStyle = false;
+
+ if (newStyle && view && (vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(option))) {
+ bool selected = vopt->state & QStyle::State_Selected;
+ bool hover = vopt->state & QStyle::State_MouseOver;
+ bool active = vopt->state & QStyle::State_Active;
+
+ if (vopt->features & QStyleOptionViewItemV2::Alternate)
+ painter->fillRect(vopt->rect, vopt->palette.alternateBase());
+
+ QPalette::ColorGroup cg = vopt->state & QStyle::State_Enabled
+ ? QPalette::Normal : QPalette::Disabled;
+ if (cg == QPalette::Normal && !(vopt->state & QStyle::State_Active))
+ cg = QPalette::Inactive;
+
+ QRect textRect = subElementRect(QStyle::SE_ItemViewItemText, option, widget);
+ QRect itemRect = subElementRect(QStyle::SE_ItemViewItemFocusRect, option, widget).adjusted(-1, 0, 1, 0);
+ itemRect.setTop(vopt->rect.top());
+ itemRect.setBottom(vopt->rect.bottom());
+
+ QSize sectionSize = itemRect.size();
+ if (vopt->showDecorationSelected)
+ sectionSize = vopt->rect.size();
+
+ if (view->selectionBehavior() == QAbstractItemView::SelectRows)
+ sectionSize.setWidth(vopt->rect.width());
+ if (view->selectionMode() == QAbstractItemView::NoSelection)
+ hover = false;
+ QPixmap pixmap;
+
+ if (vopt->backgroundBrush.style() != Qt::NoBrush) {
+ QPointF oldBO = painter->brushOrigin();
+ painter->setBrushOrigin(vopt->rect.topLeft());
+ painter->fillRect(vopt->rect, vopt->backgroundBrush);
+ }
+
+ if (hover || selected) {
+ QString key = QString::fromLatin1("qvdelegate-%1-%2-%3-%4-%5").arg(sectionSize.width())
+ .arg(sectionSize.height()).arg(selected).arg(active).arg(hover);
+ if (!QPixmapCache::find(key, pixmap)) {
+ pixmap = QPixmap(sectionSize);
+ pixmap.fill(Qt::transparent);
+
+ int state;
+ if (selected && hover)
+ state = LISS_HOTSELECTED;
+ else if (selected && !active)
+ state = LISS_SELECTEDNOTFOCUS;
+ else if (selected)
+ state = LISS_SELECTED;
+ else
+ state = LISS_HOT;
+
+ QPainter pixmapPainter(&pixmap);
+ XPThemeData theme(d->treeViewHelper(), &pixmapPainter, QLatin1String("TREEVIEW"),
+ LVP_LISTITEM, state, QRect(0, 0, sectionSize.width(), sectionSize.height()));
+ if (theme.isValid()) {
+ d->drawBackground(theme);
+ } else {
+ QWindowsXPStyle::drawPrimitive(PE_PanelItemViewItem, option, painter, widget);
+ break;;
+ }
+ QPixmapCache::insert(key, pixmap);
+ }
+
+ if (vopt->showDecorationSelected) {
+ const int frame = 2; //Assumes a 2 pixel pixmap border
+ QRect srcRect = QRect(0, 0, sectionSize.width(), sectionSize.height());
+ QRect pixmapRect = vopt->rect;
+ bool reverse = vopt->direction == Qt::RightToLeft;
+ bool leftSection = vopt->viewItemPosition == QStyleOptionViewItemV4::Beginning;
+ bool rightSection = vopt->viewItemPosition == QStyleOptionViewItemV4::End;
+ if (vopt->viewItemPosition == QStyleOptionViewItemV4::OnlyOne
+ || vopt->viewItemPosition == QStyleOptionViewItemV4::Invalid)
+ painter->drawPixmap(pixmapRect.topLeft(), pixmap);
+ 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 {
+ if (vopt->text.isEmpty() && vopt->icon.isNull())
+ break;
+ painter->drawPixmap(itemRect.topLeft(), pixmap);
+ }
+ }
+ } else {
+ QWindowsXPStyle::drawPrimitive(element, option, painter, widget);
+ }
+ break;
+ }
+ case PE_Widget:
+ {
+ const QDialogButtonBox *buttonBox = 0;
+
+ if (qobject_cast<const QMessageBox *> (widget))
+ buttonBox = widget->findChild<const QDialogButtonBox *>(QLatin1String("qt_msgbox_buttonbox"));
+#ifndef QT_NO_INPUTDIALOG
+ else if (qobject_cast<const QInputDialog *> (widget))
+ buttonBox = widget->findChild<const QDialogButtonBox *>(QLatin1String("qt_inputdlg_buttonbox"));
+#endif // QT_NO_INPUTDIALOG
+
+ if (buttonBox) {
+ //draw white panel part
+ XPThemeData theme(widget, painter, QLatin1String("TASKDIALOG"), TDLG_PRIMARYPANEL, 0, option->rect);
+ QRect toprect = option->rect;
+ toprect.setBottom(buttonBox->geometry().top());
+ theme.rect = toprect;
+ d->drawBackground(theme);
+
+ //draw bottom panel part
+ QRect buttonRect = option->rect;
+ buttonRect.setTop(buttonBox->geometry().top());
+ theme.rect = buttonRect;
+ theme.partId = TDLG_SECONDARYPANEL;
+ d->drawBackground(theme);
+ }
+ }
+ break;
+ default:
+ QWindowsXPStyle::drawPrimitive(element, option, painter, widget);
+ break;
+ }
+}
+
+
+/*!
+ \internal
+
+ see drawPrimitive for comments on the animation support
+ */
+void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption *option,
+ QPainter *painter, const QWidget *widget) const
+{
+ QWindowsVistaStylePrivate *d = const_cast<QWindowsVistaStylePrivate*>(d_func());
+
+ if (!QWindowsVistaStylePrivate::useVista()) {
+ QWindowsStyle::drawControl(element, option, painter, widget);
+ return;
+ }
+
+ bool selected = option->state & State_Selected;
+ bool pressed = option->state & State_Sunken;
+ bool disabled = !(option->state & State_Enabled);
+
+ int state = option->state;
+ QString name;
+
+ QRect rect(option->rect);
+ State flags = option->state;
+ int partId = 0;
+ int stateId = 0;
+
+ QRect oldRect;
+ QRect newRect;
+
+ if (d->transitionsEnabled() && widget) {
+ if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
+ if ((qobject_cast<const QPushButton*>(widget) && element == CE_PushButtonBevel))
+ {
+ QWidget *w = const_cast<QWidget *> (widget);
+ int oldState = w->property("_q_stylestate").toInt();
+ oldRect = w->property("_q_stylerect").toRect();
+ newRect = w->rect();
+ w->setProperty("_q_stylestate", (int)option->state);
+ w->setProperty("_q_stylerect", w->rect());
+
+ bool wasDefault = w->property("_q_isdefault").toBool();
+ bool isDefault = button->features & QStyleOptionButton::DefaultButton;
+ w->setProperty("_q_isdefault", isDefault);
+
+ bool doTransition = ((state & State_Sunken) != (oldState & State_Sunken) ||
+ (state & State_On) != (oldState & State_On) ||
+ (state & State_MouseOver) != (oldState & State_MouseOver));
+
+ if (oldRect != newRect || (wasDefault && !isDefault))
+ {
+ doTransition = false;
+ d->stopAnimation(widget);
+ }
+
+ if (doTransition) {
+ QImage startImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
+ QImage endImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
+ QWindowsVistaAnimation *anim = d->widgetAnimation(widget);
+
+ QStyleOptionButton opt = *button;
+ opt.state = (QStyle::State)oldState;
+
+ startImage.fill(0);
+ QWindowsVistaTransition *t = new QWindowsVistaTransition;
+ t->setWidget(w);
+ QPainter startPainter(&startImage);
+
+ if (!anim) {
+ proxy()->drawControl(element, &opt, &startPainter, 0 /* Intentional */);
+ } else {
+ anim->paint(&startPainter, &opt);
+ d->stopAnimation(widget);
+ }
+
+ t->setStartImage(startImage);
+ d->startAnimation(t);
+
+ endImage.fill(0);
+ QPainter endPainter(&endImage);
+ proxy()->drawControl(element, option, &endPainter, 0 /* Intentional */);
+ t->setEndImage(endImage);
+ int duration = 0;
+ HTHEME theme = pOpenThemeData(0, L"Button");
+
+ int fromState = buttonStateId(oldState, BP_PUSHBUTTON);
+ int toState = buttonStateId(option->state, BP_PUSHBUTTON);
+ if (pGetThemeTransitionDuration(theme, BP_PUSHBUTTON, fromState, toState, TMT_TRANSITIONDURATIONS, &duration) == S_OK)
+ t->setDuration(duration);
+ else
+ t->setDuration(0);
+ t->setStartTime(QTime::currentTime());
+ }
+ }
+ }
+ }
+ switch (element) {
+ case CE_PushButtonBevel:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option))
+ {
+
+ QWindowsVistaAnimation *anim = d->widgetAnimation(widget);
+ if (anim && (btn->state & State_Enabled)) {
+ anim->paint(painter, option);
+ } else {
+ name = QLatin1String("BUTTON");
+ partId = BP_PUSHBUTTON;
+ if (btn->features & QStyleOptionButton::CommandLinkButton)
+ partId = BP_COMMANDLINK;
+ bool justFlat = (btn->features & QStyleOptionButton::Flat) && !(flags & (State_On|State_Sunken));
+ if (!(flags & State_Enabled) && !(btn->features & QStyleOptionButton::Flat))
+ stateId = PBS_DISABLED;
+ else if (justFlat)
+ ;
+ else if (flags & (State_Sunken | State_On))
+ stateId = PBS_PRESSED;
+ else if (flags & State_MouseOver)
+ stateId = PBS_HOT;
+ else if (btn->features & QStyleOptionButton::DefaultButton && (state & State_Active))
+ stateId = PBS_DEFAULTED;
+ else
+ stateId = PBS_NORMAL;
+
+ if (!justFlat) {
+
+ if (widget && d->transitionsEnabled() && (btn->features & QStyleOptionButton::DefaultButton) &&
+ !(state & (State_Sunken | State_On)) && !(state & State_MouseOver) &&
+ (state & State_Enabled) && (state & State_Active))
+ {
+ if (!anim && widget) {
+ QImage startImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
+ startImage.fill(0);
+ QImage alternateImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
+ alternateImage.fill(0);
+
+ QWindowsVistaPulse *pulse = new QWindowsVistaPulse;
+ pulse->setWidget(const_cast<QWidget*>(widget));
+
+ QPainter startPainter(&startImage);
+ stateId = PBS_DEFAULTED;
+ XPThemeData theme(widget, &startPainter, name, partId, stateId, rect);
+ d->drawBackground(theme);
+
+ QPainter alternatePainter(&alternateImage);
+ theme.stateId = PBS_DEFAULTED_ANIMATING;
+ theme.painter = &alternatePainter;
+ d->drawBackground(theme);
+ pulse->setPrimaryImage(startImage);
+ pulse->setAlternateImage(alternateImage);
+ pulse->setStartTime(QTime::currentTime());
+ pulse->setDuration(2000);
+ d->startAnimation(pulse);
+ anim = pulse;
+ }
+
+ if (anim)
+ anim->paint(painter, option);
+ else {
+ XPThemeData theme(widget, painter, name, partId, stateId, rect);
+ d->drawBackground(theme);
+ }
+ }
+ else {
+ d->stopAnimation(widget);
+ XPThemeData theme(widget, painter, name, partId, stateId, rect);
+ d->drawBackground(theme);
+ }
+ }
+ }
+ if (btn->features & QStyleOptionButton::HasMenu) {
+ int mbiw = 0, mbih = 0;
+ XPThemeData theme(widget, 0, QLatin1String("TOOLBAR"), TP_DROPDOWNBUTTON);
+ if (theme.isValid()) {
+ SIZE size;
+ if (pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size) == S_OK) {
+ mbiw = size.cx;
+ mbih = size.cy;
+ }
+ }
+ QRect ir = subElementRect(SE_PushButtonContents, option, 0);
+ QStyleOptionButton newBtn = *btn;
+ newBtn.rect = QStyle::visualRect(option->direction, option->rect,
+ QRect(ir.right() - mbiw - 2,
+ option->rect.top() + (option->rect.height()/2) - (mbih/2),
+ mbiw + 1, mbih + 1));
+ proxy()->drawPrimitive(PE_IndicatorArrowDown, &newBtn, painter, widget);
+ }
+ return;
+ }
+ break;
+#ifndef QT_NO_PROGRESSBAR
+ case CE_ProgressBarContents:
+ if (const QStyleOptionProgressBar *bar
+ = qstyleoption_cast<const QStyleOptionProgressBar *>(option)) {
+ int stateId = MBI_NORMAL;
+ if (disabled)
+ stateId = MBI_DISABLED;
+ bool isIndeterminate = (bar->minimum == 0 && bar->maximum == 0);
+ bool vertical = false;
+ bool inverted = false;
+ if (const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option)) {
+ vertical = (pb2->orientation == Qt::Vertical);
+ inverted = pb2->invertedAppearance;
+ }
+
+ if (const QProgressBar *progressbar = qobject_cast<const QProgressBar *>(widget)) {
+ if (isIndeterminate || (progressbar->value() > 0 && (progressbar->value() < progressbar->maximum()) && d->transitionsEnabled())) {
+ if (!d->widgetAnimation(progressbar)) {
+ QWindowsVistaAnimation *a = new QWindowsVistaAnimation;
+ a->setWidget(const_cast<QWidget*>(widget));
+ a->setStartTime(QTime::currentTime());
+ d->startAnimation(a);
+ }
+ } else {
+ d->stopAnimation(progressbar);
+ }
+ }
+
+ XPThemeData theme(widget, painter, QLatin1String("PROGRESS"), vertical ? PP_FILLVERT : PP_FILL);
+ theme.rect = option->rect;
+ bool reverse = (bar->direction == Qt::LeftToRight && inverted) || (bar->direction == Qt::RightToLeft && !inverted);
+ QTime current = QTime::currentTime();
+
+ if (isIndeterminate) {
+ if (QWindowsVistaAnimation *a = d->widgetAnimation(widget)) {
+ int glowSize = 120;
+ int animationWidth = glowSize * 2 + (vertical ? theme.rect.height() : theme.rect.width());
+ int animOffset = a->startTime().msecsTo(current) / 4;
+ if (animOffset > animationWidth)
+ a->setStartTime(QTime::currentTime());
+ painter->save();
+ painter->setClipRect(theme.rect);
+ QRect animRect;
+ QSize pixmapSize(14, 14);
+ if (vertical) {
+ animRect = QRect(theme.rect.left(),
+ inverted ? rect.top() - glowSize + animOffset :
+ rect.bottom() + glowSize - animOffset,
+ rect.width(), glowSize);
+ pixmapSize.setHeight(animRect.height());
+ } else {
+ animRect = QRect(rect.left() - glowSize + animOffset,
+ rect.top(), glowSize, rect.height());
+ animRect = QStyle::visualRect(reverse ? Qt::RightToLeft : Qt::LeftToRight,
+ option->rect, animRect);
+ pixmapSize.setWidth(animRect.width());
+ }
+ QString name = QString::fromLatin1("qiprogress-%1-%2").arg(pixmapSize.width()).arg(pixmapSize.height());
+ QPixmap pixmap;
+ if (!QPixmapCache::find(name, pixmap)) {
+ QImage image(pixmapSize, QImage::Format_ARGB32);
+ image.fill(Qt::transparent);
+ QPainter imagePainter(&image);
+ theme.painter = &imagePainter;
+ theme.partId = vertical ? PP_FILLVERT : PP_FILL;
+ theme.rect = QRect(QPoint(0,0), theme.rect.size());
+ QLinearGradient alphaGradient(0, 0, vertical ? 0 : image.width(),
+ vertical ? image.height() : 0);
+ alphaGradient.setColorAt(0, QColor(0, 0, 0, 0));
+ alphaGradient.setColorAt(0.5, QColor(0, 0, 0, 220));
+ alphaGradient.setColorAt(1, QColor(0, 0, 0, 0));
+ imagePainter.fillRect(image.rect(), alphaGradient);
+ imagePainter.setCompositionMode(QPainter::CompositionMode_SourceIn);
+ d->drawBackground(theme);
+ imagePainter.end();
+ pixmap = QPixmap::fromImage(image);
+ QPixmapCache::insert(name, pixmap);
+ }
+ painter->drawPixmap(animRect, pixmap);
+ painter->restore();
+ }
+ }
+ else {
+ qint64 progress = qMax<qint64>(bar->progress, bar->minimum); // workaround for bug in QProgressBar
+
+ if (vertical) {
+ int maxHeight = option->rect.height();
+ int minHeight = 0;
+ double vc6_workaround = ((progress - qint64(bar->minimum)) / qMax(double(1.0), double(qint64(bar->maximum) - qint64(bar->minimum))) * maxHeight);
+ int height = isIndeterminate ? maxHeight: qMax(int(vc6_workaround), minHeight);
+ theme.rect.setHeight(height);
+ if (!inverted)
+ theme.rect.moveTop(rect.height() - theme.rect.height());
+ } else {
+ int maxWidth = option->rect.width();
+ int minWidth = 0;
+ double vc6_workaround = ((progress - qint64(bar->minimum)) / qMax(double(1.0), double(qint64(bar->maximum) - qint64(bar->minimum))) * maxWidth);
+ int width = isIndeterminate ? maxWidth : qMax(int(vc6_workaround), minWidth);
+ theme.rect.setWidth(width);
+ theme.rect = QStyle::visualRect(reverse ? Qt::RightToLeft : Qt::LeftToRight,
+ option->rect, theme.rect);
+ }
+ d->drawBackground(theme);
+
+ if (QWindowsVistaAnimation *a = d->widgetAnimation(widget)) {
+ int glowSize = 140;
+ int animationWidth = glowSize * 2 + (vertical ? theme.rect.height() : theme.rect.width());
+ int animOffset = a->startTime().msecsTo(current) / 4;
+ theme.partId = vertical ? PP_MOVEOVERLAYVERT : PP_MOVEOVERLAY;
+ if (animOffset > animationWidth) {
+ if (bar->progress < bar->maximum)
+ a->setStartTime(QTime::currentTime());
+ else
+ d->stopAnimation(widget); //we stop the glow motion only after it has
+ //moved out of view
+ }
+ painter->save();
+ painter->setClipRect(theme.rect);
+ if (vertical) {
+ theme.rect = QRect(theme.rect.left(),
+ inverted ? rect.top() - glowSize + animOffset :
+ rect.bottom() + glowSize - animOffset,
+ rect.width(), glowSize);
+ } else {
+ theme.rect = QRect(rect.left() - glowSize + animOffset,rect.top(), glowSize, rect.height());
+ theme.rect = QStyle::visualRect(reverse ? Qt::RightToLeft : Qt::LeftToRight, option->rect, theme.rect);
+ }
+ d->drawBackground(theme);
+ painter->restore();
+ }
+ }
+ }
+ break;
+#endif // QT_NO_PROGRESSBAR
+ case CE_MenuBarItem:
+ {
+
+ if (const QStyleOptionMenuItem *mbi = qstyleoption_cast<const QStyleOptionMenuItem *>(option))
+ {
+ if (mbi->menuItemType == QStyleOptionMenuItem::DefaultItem)
+ break;
+
+ QPalette::ColorRole textRole = disabled ? QPalette::Text : QPalette::ButtonText;
+ QPixmap pix = mbi->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, option, widget), QIcon::Normal);
+
+ uint alignment = Qt::AlignCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
+ if (!proxy()->styleHint(SH_UnderlineShortcut, mbi, widget))
+ alignment |= Qt::TextHideMnemonic;
+
+ //The rect adjustment is a workaround for the menu not really filling its background.
+ XPThemeData theme(widget, painter, QLatin1String("MENU"), MENU_BARBACKGROUND, 0, option->rect.adjusted(-1, 0, 2, 1));
+ d->drawBackground(theme);
+
+ int stateId = MBI_NORMAL;
+ if (disabled)
+ stateId = MBI_DISABLED;
+ else if (pressed)
+ stateId = MBI_PUSHED;
+ else if (selected)
+ stateId = MBI_HOT;
+
+ XPThemeData theme2(widget, painter, QLatin1String("MENU"), MENU_BARITEM, stateId, option->rect);
+ d->drawBackground(theme2);
+
+ if (!pix.isNull())
+ drawItemPixmap(painter, mbi->rect, alignment, pix);
+ else
+ drawItemText(painter, mbi->rect, alignment, mbi->palette, mbi->state & State_Enabled, mbi->text, textRole);
+ }
+ }
+ break;
+#ifndef QT_NO_MENU
+ case CE_MenuItem:
+ if (const QStyleOptionMenuItem *menuitem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
+ // windows always has a check column, regardless whether we have an icon or not
+ int checkcol = 28;
+ {
+ SIZE size;
+ MARGINS margins;
+ XPThemeData theme(widget, 0, QLatin1String("MENU"), MENU_POPUPCHECKBACKGROUND, MBI_HOT);
+ pGetThemePartSize(theme.handle(), NULL, MENU_POPUPCHECK, 0, NULL,TS_TRUE, &size);
+ pGetThemeMargins(theme.handle(), NULL, MENU_POPUPCHECK, 0, TMT_CONTENTMARGINS, NULL, &margins);
+ checkcol = qMax(menuitem->maxIconWidth, int(6 + size.cx + margins.cxLeftWidth + margins.cxRightWidth));
+ }
+ QColor darkLine = option->palette.background().color().darker(108);
+ QColor lightLine = option->palette.background().color().lighter(107);
+ QRect rect = option->rect;
+ QStyleOptionMenuItem mbiCopy = *menuitem;
+
+ //draw vertical menu line
+ QPoint p1 = QStyle::visualPos(option->direction, menuitem->rect, QPoint(checkcol, rect.top()));
+ QPoint p2 = QStyle::visualPos(option->direction, menuitem->rect, QPoint(checkcol, rect.bottom()));
+ QRect gutterRect(p1.x(), p1.y(), 3, p2.y() - p1.y() + 1);
+ XPThemeData theme2(widget, painter, QLatin1String("MENU"), MENU_POPUPGUTTER, stateId, gutterRect);
+ d->drawBackground(theme2);
+
+ int x, y, w, h;
+ menuitem->rect.getRect(&x, &y, &w, &h);
+ int tab = menuitem->tabWidth;
+ bool dis = !(menuitem->state & State_Enabled);
+ bool checked = menuitem->checkType != QStyleOptionMenuItem::NotCheckable
+ ? menuitem->checked : false;
+ bool act = menuitem->state & State_Selected;
+
+ if (menuitem->menuItemType == QStyleOptionMenuItem::Separator) {
+ int yoff = y-2 + h / 2;
+ QPoint p1 = QPoint(x + checkcol, yoff);
+ QPoint p2 = QPoint(x + w + 6 , yoff);
+ stateId = MBI_HOT;
+ QRect subRect(p1.x(), p1.y(), p2.x() - p1.x(), 6);
+ subRect = QStyle::visualRect(option->direction, option->rect, subRect );
+ XPThemeData theme2(widget, painter, QLatin1String("MENU"), MENU_POPUPSEPARATOR, stateId, subRect);
+ d->drawBackground(theme2);
+ return;
+ }
+
+ QRect vCheckRect = visualRect(option->direction, menuitem->rect, QRect(menuitem->rect.x(),
+ menuitem->rect.y(), checkcol - 6, menuitem->rect.height()));
+
+ if (act) {
+ stateId = MBI_HOT;
+ XPThemeData theme2(widget, painter, QLatin1String("MENU"), MENU_POPUPITEM, stateId, option->rect);
+ d->drawBackground(theme2);
+ }
+
+ if (checked) {
+ XPThemeData theme(widget, painter, QLatin1String("MENU"), MENU_POPUPCHECKBACKGROUND,
+ menuitem->icon.isNull() ? MBI_HOT : MBI_PUSHED, vCheckRect);
+ SIZE size;
+ MARGINS margins;
+ pGetThemePartSize(theme.handle(), NULL, MENU_POPUPCHECK, 0, NULL,TS_TRUE, &size);
+ pGetThemeMargins(theme.handle(), NULL, MENU_POPUPCHECK, 0,
+ TMT_CONTENTMARGINS, NULL, &margins);
+ QRect checkRect(0, 0, size.cx + margins.cxLeftWidth + margins.cxRightWidth ,
+ size.cy + margins.cyBottomHeight + margins.cyTopHeight);
+ checkRect.moveCenter(vCheckRect.center());
+ theme.rect = checkRect;
+
+ d->drawBackground(theme);
+
+ if (menuitem->icon.isNull()) {
+ checkRect = QRect(0, 0, size.cx, size.cy);
+ checkRect.moveCenter(theme.rect.center());
+ theme.rect = checkRect;
+
+ theme.partId = MENU_POPUPCHECK;
+ bool bullet = menuitem->checkType & QStyleOptionMenuItem::Exclusive;
+ if (dis)
+ theme.stateId = bullet ? MC_BULLETDISABLED: MC_CHECKMARKDISABLED;
+ else
+ theme.stateId = bullet ? MC_BULLETNORMAL: MC_CHECKMARKNORMAL;
+ d->drawBackground(theme);
+ }
+ }
+
+ if (!menuitem->icon.isNull()) {
+ QIcon::Mode mode = dis ? QIcon::Disabled : QIcon::Normal;
+ if (act && !dis)
+ mode = QIcon::Active;
+ QPixmap pixmap;
+ if (checked)
+ pixmap = menuitem->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, option, widget), mode, QIcon::On);
+ else
+ pixmap = menuitem->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, option, widget), mode);
+ int pixw = pixmap.width();
+ int pixh = pixmap.height();
+ QRect pmr(0, 0, pixw, pixh);
+ pmr.moveCenter(vCheckRect.center());
+ painter->setPen(menuitem->palette.text().color());
+ painter->drawPixmap(pmr.topLeft(), pixmap);
+ }
+
+ painter->setPen(menuitem->palette.buttonText().color());
+
+ QColor discol;
+ if (dis) {
+ discol = menuitem->palette.text().color();
+ painter->setPen(discol);
+ }
+
+ int xm = windowsItemFrame + checkcol + windowsItemHMargin;
+ int xpos = menuitem->rect.x() + xm;
+ QRect textRect(xpos, y + windowsItemVMargin, w - xm - windowsRightBorder - tab + 1, h - 2 * windowsItemVMargin);
+ QRect vTextRect = visualRect(option->direction, menuitem->rect, textRect);
+ QString s = menuitem->text;
+ if (!s.isEmpty()) { // draw text
+ painter->save();
+ int t = s.indexOf(QLatin1Char('\t'));
+ int text_flags = Qt::AlignVCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
+ if (!proxy()->styleHint(SH_UnderlineShortcut, menuitem, widget))
+ text_flags |= Qt::TextHideMnemonic;
+ text_flags |= Qt::AlignLeft;
+ if (t >= 0) {
+ QRect vShortcutRect = visualRect(option->direction, menuitem->rect,
+ QRect(textRect.topRight(), QPoint(menuitem->rect.right(), textRect.bottom())));
+ painter->drawText(vShortcutRect, text_flags, s.mid(t + 1));
+ s = s.left(t);
+ }
+ QFont font = menuitem->font;
+ if (menuitem->menuItemType == QStyleOptionMenuItem::DefaultItem)
+ font.setBold(true);
+ painter->setFont(font);
+ painter->setPen(discol);
+ painter->drawText(vTextRect, text_flags, s.left(t));
+ painter->restore();
+ }
+ if (menuitem->menuItemType == QStyleOptionMenuItem::SubMenu) {// draw sub menu arrow
+ int dim = (h - 2 * windowsItemFrame) / 2;
+ PrimitiveElement arrow;
+ arrow = (option->direction == Qt::RightToLeft) ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight;
+ xpos = x + w - windowsArrowHMargin - windowsItemFrame - dim;
+ QRect vSubMenuRect = visualRect(option->direction, menuitem->rect, QRect(xpos, y + h / 2 - dim / 2, dim, dim));
+ QStyleOptionMenuItem newMI = *menuitem;
+ newMI.rect = vSubMenuRect;
+ newMI.state = dis ? State_None : State_Enabled;
+ proxy()->drawPrimitive(arrow, &newMI, painter, widget);
+ }
+ }
+ break;
+#endif // QT_NO_MENU
+ case CE_HeaderSection:
+ if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
+ name = QLatin1String("HEADER");
+ partId = HP_HEADERITEM;
+ if (flags & State_Sunken)
+ stateId = HIS_PRESSED;
+ else if (flags & State_MouseOver)
+ stateId = HIS_HOT;
+ else
+ stateId = HIS_NORMAL;
+
+ if (header->sortIndicator != QStyleOptionHeader::None)
+ stateId += 3;
+
+ XPThemeData theme(widget, painter, name, partId, stateId, option->rect);
+ d->drawBackground(theme);
+ }
+ break;
+ case CE_MenuBarEmptyArea:
+ {
+ stateId = MBI_NORMAL;
+ if (!(state & State_Enabled))
+ stateId = MBI_DISABLED;
+ XPThemeData theme(widget, painter, QLatin1String("MENU"), MENU_BARBACKGROUND, stateId, option->rect);
+ d->drawBackground(theme);
+ }
+ break;
+ case CE_ToolBar:
+ if (const QStyleOptionToolBar *toolbar = qstyleoption_cast<const QStyleOptionToolBar *>(option)) {
+ QPalette pal = option->palette;
+ pal.setColor(QPalette::Dark, option->palette.background().color().darker(130));
+ QStyleOptionToolBar copyOpt = *toolbar;
+ copyOpt.palette = pal;
+ QWindowsStyle::drawControl(element, &copyOpt, painter, widget);
+ }
+ break;
+ case CE_DockWidgetTitle:
+ if (const QDockWidget *dockWidget = qobject_cast<const QDockWidget *>(widget)) {
+ QRect rect = option->rect;
+ if (dockWidget->isFloating()) {
+ QWindowsXPStyle::drawControl(element, option, painter, widget);
+ break; //otherwise fall through
+ }
+
+ if (const QStyleOptionDockWidget *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(option)) {
+
+ const QStyleOptionDockWidgetV2 *v2
+ = qstyleoption_cast<const QStyleOptionDockWidgetV2*>(dwOpt);
+ bool verticalTitleBar = v2 == 0 ? false : v2->verticalTitleBar;
+
+ if (verticalTitleBar) {
+ QSize s = rect.size();
+ s.transpose();
+ rect.setSize(s);
+
+ painter->translate(rect.left() - 1, rect.top() + rect.width());
+ painter->rotate(-90);
+ painter->translate(-rect.left() + 1, -rect.top());
+ }
+
+ painter->setBrush(option->palette.background().color().darker(110));
+ painter->setPen(option->palette.background().color().darker(130));
+ painter->drawRect(rect.adjusted(0, 1, -1, -3));
+
+ int buttonMargin = 4;
+ int mw = proxy()->pixelMetric(QStyle::PM_DockWidgetTitleMargin, dwOpt, widget);
+ int fw = proxy()->pixelMetric(PM_DockWidgetFrameWidth, dwOpt, widget);
+ const QDockWidget *dw = qobject_cast<const QDockWidget *>(widget);
+ bool isFloating = dw != 0 && dw->isFloating();
+
+ QRect r = option->rect.adjusted(0, 2, -1, -3);
+ QRect titleRect = r;
+
+ if (dwOpt->closable) {
+ QSize sz = standardIcon(QStyle::SP_TitleBarCloseButton, dwOpt, widget).actualSize(QSize(10, 10));
+ titleRect.adjust(0, 0, -sz.width() - mw - buttonMargin, 0);
+ }
+
+ if (dwOpt->floatable) {
+ QSize sz = standardIcon(QStyle::SP_TitleBarMaxButton, dwOpt, widget).actualSize(QSize(10, 10));
+ titleRect.adjust(0, 0, -sz.width() - mw - buttonMargin, 0);
+ }
+
+ if (isFloating) {
+ titleRect.adjust(0, -fw, 0, 0);
+ if (widget != 0 && widget->windowIcon().cacheKey() != QApplication::windowIcon().cacheKey())
+ titleRect.adjust(titleRect.height() + mw, 0, 0, 0);
+ } else {
+ titleRect.adjust(mw, 0, 0, 0);
+ if (!dwOpt->floatable && !dwOpt->closable)
+ titleRect.adjust(0, 0, -mw, 0);
+ }
+ if (!verticalTitleBar)
+ titleRect = visualRect(dwOpt->direction, r, titleRect);
+
+ if (!dwOpt->title.isEmpty()) {
+ QString titleText = painter->fontMetrics().elidedText(dwOpt->title, Qt::ElideRight,
+ verticalTitleBar ? titleRect.height() : titleRect.width());
+ const int indent = painter->fontMetrics().descent();
+ drawItemText(painter, rect.adjusted(indent + 1, 1, -indent - 1, -1),
+ Qt::AlignLeft | Qt::AlignVCenter, dwOpt->palette,
+ dwOpt->state & State_Enabled, titleText,
+ QPalette::WindowText);
+ }
+ }
+ break;
+ }
+#ifndef QT_NO_ITEMVIEWS
+ case CE_ItemViewItem:
+ {
+ const QStyleOptionViewItemV4 *vopt;
+ const QAbstractItemView *view = qobject_cast<const QAbstractItemView *>(widget);
+ bool newStyle = true;
+
+ if (qobject_cast<const QTableView*>(widget))
+ newStyle = false;
+
+ if (newStyle && view && (vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(option))) {
+ /*
+ // We cannot currently get the correct selection color for "explorer style" views
+ COLORREF cref = 0;
+ XPThemeData theme(d->treeViewHelper(), 0, QLatin1String("LISTVIEW"), 0, 0);
+ unsigned int res = pGetThemeColor(theme.handle(), LVP_LISTITEM, LISS_SELECTED, TMT_TEXTCOLOR, &cref);
+ QColor textColor(GetRValue(cref), GetGValue(cref), GetBValue(cref));
+ */
+ QPalette palette = vopt->palette;
+ palette.setColor(QPalette::All, QPalette::HighlightedText, palette.color(QPalette::Active, QPalette::Text));
+ // Note that setting a saturated color here results in ugly XOR colors in the focus rect
+ palette.setColor(QPalette::All, QPalette::Highlight, palette.base().color().darker(108));
+ QStyleOptionViewItemV4 adjustedOption = *vopt;
+ adjustedOption.palette = palette;
+ // We hide the focusrect in singleselection as it is not required
+ if ((view->selectionMode() == QAbstractItemView::SingleSelection)
+ && !(vopt->state & State_KeyboardFocusChange))
+ adjustedOption.state &= ~State_HasFocus;
+ QWindowsXPStyle::drawControl(element, &adjustedOption, painter, widget);
+ } else {
+ QWindowsXPStyle::drawControl(element, option, painter, widget);
+ }
+ break;
+ }
+#endif // QT_NO_ITEMVIEWS
+
+ default:
+ QWindowsXPStyle::drawControl(element, option, painter, widget);
+ break;
+ }
+}
+
+/*!
+ \internal
+
+ see drawPrimitive for comments on the animation support
+
+ */
+void QWindowsVistaStyle::drawComplexControl(ComplexControl control, const QStyleOptionComplex *option,
+ QPainter *painter, const QWidget *widget) const
+{
+ QWindowsVistaStylePrivate *d = const_cast<QWindowsVistaStylePrivate*>(d_func());
+ if (!QWindowsVistaStylePrivate::useVista()) {
+ QWindowsStyle::drawComplexControl(control, option, painter, widget);
+ return;
+ }
+
+ State state = option->state;
+ SubControls sub = option->subControls;
+ QRect r = option->rect;
+
+ int partId = 0;
+ int stateId = 0;
+
+ State flags = option->state;
+ if (widget && widget->testAttribute(Qt::WA_UnderMouse) && widget->isActiveWindow())
+ flags |= State_MouseOver;
+
+ if (d->transitionsEnabled() && widget) {
+ if ((qobject_cast<const QScrollBar *>(widget) && control == CC_ScrollBar)
+#ifndef QT_NO_SPINBOX
+ || (qobject_cast<const QAbstractSpinBox*>(widget) && control == CC_SpinBox)
+#endif // QT_NO_SPINBOX
+#ifndef QT_NO_COMBOBOX
+ || (qobject_cast<const QComboBox*>(widget) && control == CC_ComboBox)
+#endif // QT_NO_COMBOBOX
+ )
+ {
+ QWidget *w = const_cast<QWidget *> (widget);
+
+ int oldState = w->property("_q_stylestate").toInt();
+ int oldActiveControls = w->property("_q_stylecontrols").toInt();
+ QRect oldRect = w->property("_q_stylerect").toRect();
+ w->setProperty("_q_stylestate", (int)option->state);
+ w->setProperty("_q_stylecontrols", (int)option->activeSubControls);
+ w->setProperty("_q_stylerect", w->rect());
+
+ bool doTransition = ((state & State_Sunken) != (oldState & State_Sunken) ||
+ (state & State_On) != (oldState & State_On) ||
+ (state & State_MouseOver) != (oldState & State_MouseOver) ||
+ oldActiveControls != option->activeSubControls);
+
+
+ if (qstyleoption_cast<const QStyleOptionSlider *>(option)) {
+ QRect oldSliderPos = w->property("_q_stylesliderpos").toRect();
+ QRect currentPos = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider, widget);
+ w->setProperty("_q_stylesliderpos", currentPos);
+ if (oldSliderPos != currentPos) {
+ doTransition = false;
+ d->stopAnimation(widget);
+ }
+ } else if (control == CC_SpinBox) {
+ //spinboxes have a transition when focus changes
+ if (!doTransition)
+ doTransition = (state & State_HasFocus) != (oldState & State_HasFocus);
+ }
+
+ if (oldRect != option->rect) {
+ doTransition = false;
+ d->stopAnimation(widget);
+ }
+
+ if (doTransition) {
+ QImage startImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
+ QImage endImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
+ QWindowsVistaAnimation *anim = d->widgetAnimation(widget);
+ QWindowsVistaTransition *t = new QWindowsVistaTransition;
+ t->setWidget(w);
+ if (!anim) {
+ if (const QStyleOptionComboBox *combo = qstyleoption_cast<const QStyleOptionComboBox*>(option)) {
+ //Combo boxes are special cased to avoid cleartype issues
+ startImage.fill(0);
+ QPainter startPainter(&startImage);
+ QStyleOptionComboBox startCombo = *combo;
+ startCombo.state = (QStyle::State)oldState;
+ startCombo.activeSubControls = (QStyle::SubControl)oldActiveControls;
+ proxy()->drawComplexControl(control, &startCombo, &startPainter, 0 /* Intentional */);
+ t->setStartImage(startImage);
+ } else if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider*>(option)) {
+ //This is a workaround for the direct3d engine as it currently has some issues with grabWindow
+ startImage.fill(0);
+ QPainter startPainter(&startImage);
+ QStyleOptionSlider startSlider = *slider;
+ startSlider.state = (QStyle::State)oldState;
+ startSlider.activeSubControls = (QStyle::SubControl)oldActiveControls;
+ proxy()->drawComplexControl(control, &startSlider, &startPainter, 0 /* Intentional */);
+ t->setStartImage(startImage);
+ } else {
+ QPoint offset(0, 0);
+ if (!widget->internalWinId())
+ offset = widget->mapTo(widget->nativeParentWidget(), offset);
+ t->setStartImage(QPixmap::grabWindow(widget->effectiveWinId(), offset.x(), offset.y(),
+ option->rect.width(), option->rect.height()).toImage());
+ }
+ } else {
+ startImage.fill(0);
+ QPainter startPainter(&startImage);
+ anim->paint(&startPainter, option);
+ t->setStartImage(startImage);
+ }
+ d->startAnimation(t);
+ endImage.fill(0);
+ QPainter endPainter(&endImage);
+ proxy()->drawComplexControl(control, option, &endPainter, 0 /* Intentional */);
+ t->setEndImage(endImage);
+ t->setStartTime(QTime::currentTime());
+
+ if (option->state & State_MouseOver || option->state & State_Sunken)
+ t->setDuration(150);
+ else
+ t->setDuration(500);
+ }
+
+ if (QWindowsVistaAnimation *anim = d->widgetAnimation(widget)) {
+ anim->paint(painter, option);
+ return;
+ }
+
+ }
+ }
+
+ switch (control) {
+ case CC_ComboBox:
+ if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(option))
+ {
+ if (cmb->editable) {
+ if (sub & SC_ComboBoxEditField) {
+ partId = EP_EDITBORDER_NOSCROLL;
+ if (!(flags & State_Enabled))
+ stateId = ETS_DISABLED;
+ else if (flags & State_MouseOver)
+ stateId = ETS_HOT;
+ else if (flags & State_HasFocus)
+ stateId = ETS_FOCUSED;
+ else
+ stateId = ETS_NORMAL;
+
+ XPThemeData theme(widget, painter, QLatin1String("EDIT"), partId, stateId, r);
+
+ d->drawBackground(theme);
+ }
+ if (sub & SC_ComboBoxArrow) {
+ QRect subRect = proxy()->subControlRect(CC_ComboBox, option, SC_ComboBoxArrow, widget);
+ XPThemeData theme(widget, painter, QLatin1String("COMBOBOX"));
+ theme.rect = subRect;
+ partId = option->direction == Qt::RightToLeft ? CP_DROPDOWNBUTTONLEFT : CP_DROPDOWNBUTTONRIGHT;
+
+ if (!(cmb->state & State_Enabled))
+ stateId = CBXS_DISABLED;
+ else if (cmb->state & State_Sunken || cmb->state & State_On)
+ stateId = CBXS_PRESSED;
+ else if (cmb->state & State_MouseOver && option->activeSubControls & SC_ComboBoxArrow)
+ stateId = CBXS_HOT;
+ else
+ stateId = CBXS_NORMAL;
+
+ theme.partId = partId;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+ }
+
+ } else {
+ if (sub & SC_ComboBoxFrame) {
+ QStyleOptionButton btn;
+ btn.QStyleOption::operator=(*option);
+ btn.rect = option->rect.adjusted(-1, -1, 1, 1);
+ if (sub & SC_ComboBoxArrow)
+ btn.features = QStyleOptionButton::HasMenu;
+ proxy()->drawControl(QStyle::CE_PushButton, &btn, painter, widget);
+ }
+ }
+ }
+ break;
+ case CC_ScrollBar:
+ if (const QStyleOptionSlider *scrollbar = qstyleoption_cast<const QStyleOptionSlider *>(option))
+ {
+ XPThemeData theme(widget, painter, QLatin1String("SCROLLBAR"));
+
+ bool maxedOut = (scrollbar->maximum == scrollbar->minimum);
+ if (maxedOut)
+ flags &= ~State_Enabled;
+
+ bool isHorz = flags & State_Horizontal;
+ bool isRTL = option->direction == Qt::RightToLeft;
+ if (sub & SC_ScrollBarAddLine) {
+ theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarAddLine, widget);
+ partId = SBP_ARROWBTN;
+ if (!(flags & State_Enabled))
+ stateId = (isHorz ? (isRTL ? ABS_LEFTDISABLED : ABS_RIGHTDISABLED) : ABS_DOWNDISABLED);
+ else if (scrollbar->activeSubControls & SC_ScrollBarAddLine && (scrollbar->state & State_Sunken))
+ stateId = (isHorz ? (isRTL ? ABS_LEFTPRESSED : ABS_RIGHTPRESSED) : ABS_DOWNPRESSED);
+ else if (scrollbar->activeSubControls & SC_ScrollBarAddLine && (scrollbar->state & State_MouseOver))
+ stateId = (isHorz ? (isRTL ? ABS_LEFTHOT : ABS_RIGHTHOT) : ABS_DOWNHOT);
+ else if (scrollbar->state & State_MouseOver)
+ stateId = (isHorz ? (isRTL ? ABS_LEFTHOVER : ABS_RIGHTHOVER) : ABS_DOWNHOVER);
+ else
+ stateId = (isHorz ? (isRTL ? ABS_LEFTNORMAL : ABS_RIGHTNORMAL) : ABS_DOWNNORMAL);
+ theme.partId = partId;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+ }
+ if (sub & SC_ScrollBarSubLine) {
+ theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSubLine, widget);
+ partId = SBP_ARROWBTN;
+ if (!(flags & State_Enabled))
+ stateId = (isHorz ? (isRTL ? ABS_RIGHTDISABLED : ABS_LEFTDISABLED) : ABS_UPDISABLED);
+ else if (scrollbar->activeSubControls & SC_ScrollBarSubLine && (scrollbar->state & State_Sunken))
+ stateId = (isHorz ? (isRTL ? ABS_RIGHTPRESSED : ABS_LEFTPRESSED) : ABS_UPPRESSED);
+ else if (scrollbar->activeSubControls & SC_ScrollBarSubLine && (scrollbar->state & State_MouseOver))
+ stateId = (isHorz ? (isRTL ? ABS_RIGHTHOT : ABS_LEFTHOT) : ABS_UPHOT);
+ else if (scrollbar->state & State_MouseOver)
+ stateId = (isHorz ? (isRTL ? ABS_RIGHTHOVER : ABS_LEFTHOVER) : ABS_UPHOVER);
+ else
+ stateId = (isHorz ? (isRTL ? ABS_RIGHTNORMAL : ABS_LEFTNORMAL) : ABS_UPNORMAL);
+ theme.partId = partId;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+ }
+ if (maxedOut) {
+ theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider, widget);
+ theme.rect = theme.rect.united(proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSubPage, widget));
+ theme.rect = theme.rect.united(proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarAddPage, widget));
+ partId = flags & State_Horizontal ? SBP_LOWERTRACKHORZ : SBP_LOWERTRACKVERT;
+ stateId = SCRBS_DISABLED;
+ theme.partId = partId;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+ } else {
+ if (sub & SC_ScrollBarSubPage) {
+ theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSubPage, widget);
+ partId = flags & State_Horizontal ? SBP_UPPERTRACKHORZ : SBP_UPPERTRACKVERT;
+ if (!(flags & State_Enabled))
+ stateId = SCRBS_DISABLED;
+ else if (scrollbar->activeSubControls & SC_ScrollBarSubPage && (scrollbar->state & State_Sunken))
+ stateId = SCRBS_PRESSED;
+ else if (scrollbar->activeSubControls & SC_ScrollBarSubPage && (scrollbar->state & State_MouseOver))
+ stateId = SCRBS_HOT;
+ else
+ stateId = SCRBS_NORMAL;
+ theme.partId = partId;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+ }
+ if (sub & SC_ScrollBarAddPage) {
+ theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarAddPage, widget);
+ partId = flags & State_Horizontal ? SBP_LOWERTRACKHORZ : SBP_LOWERTRACKVERT;
+ if (!(flags & State_Enabled))
+ stateId = SCRBS_DISABLED;
+ else if (scrollbar->activeSubControls & SC_ScrollBarAddPage && (scrollbar->state & State_Sunken))
+ stateId = SCRBS_PRESSED;
+ else if (scrollbar->activeSubControls & SC_ScrollBarAddPage && (scrollbar->state & State_MouseOver))
+ stateId = SCRBS_HOT;
+ else
+ stateId = SCRBS_NORMAL;
+ theme.partId = partId;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+ }
+ if (sub & SC_ScrollBarSlider) {
+ theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider, widget);
+ if (!(flags & State_Enabled))
+ stateId = SCRBS_DISABLED;
+ else if (scrollbar->activeSubControls & SC_ScrollBarSlider && (scrollbar->state & State_Sunken))
+ stateId = SCRBS_PRESSED;
+ else if (scrollbar->activeSubControls & SC_ScrollBarSlider && (scrollbar->state & State_MouseOver))
+ stateId = SCRBS_HOT;
+ else if (option->state & State_MouseOver)
+ stateId = SCRBS_HOVER;
+ else
+ stateId = SCRBS_NORMAL;
+
+ // Draw handle
+ theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider, widget);
+ theme.partId = flags & State_Horizontal ? SBP_THUMBBTNHORZ : SBP_THUMBBTNVERT;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+
+ // Calculate rect of gripper
+ const int swidth = theme.rect.width();
+ const int sheight = theme.rect.height();
+
+ MARGINS contentsMargin;
+ RECT rect = theme.toRECT(theme.rect);
+ pGetThemeMargins(theme.handle(), 0, theme.partId, theme.stateId, TMT_SIZINGMARGINS, &rect, &contentsMargin);
+
+ SIZE size;
+ theme.partId = flags & State_Horizontal ? SBP_GRIPPERHORZ : SBP_GRIPPERVERT;
+ pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
+ int gw = size.cx, gh = size.cy;
+
+
+ QRect gripperBounds;
+ if (flags & State_Horizontal && ((swidth - contentsMargin.cxLeftWidth - contentsMargin.cxRightWidth) > gw)) {
+ gripperBounds.setLeft(theme.rect.left() + swidth/2 - gw/2);
+ gripperBounds.setTop(theme.rect.top() + sheight/2 - gh/2);
+ gripperBounds.setWidth(gw);
+ gripperBounds.setHeight(gh);
+ } else if ((sheight - contentsMargin.cyTopHeight - contentsMargin.cyBottomHeight) > gh) {
+ gripperBounds.setLeft(theme.rect.left() + swidth/2 - gw/2);
+ gripperBounds.setTop(theme.rect.top() + sheight/2 - gh/2);
+ gripperBounds.setWidth(gw);
+ gripperBounds.setHeight(gh);
+ }
+
+ // Draw gripper if there is enough space
+ if (!gripperBounds.isEmpty() && flags & State_Enabled) {
+ painter->save();
+ XPThemeData grippBackground = theme;
+ grippBackground.partId = flags & State_Horizontal ? SBP_LOWERTRACKHORZ : SBP_LOWERTRACKVERT;
+ theme.rect = gripperBounds;
+ painter->setClipRegion(d->region(theme));// Only change inside the region of the gripper
+ d->drawBackground(grippBackground);// The gutter is the grippers background
+ d->drawBackground(theme); // Transparent gripper ontop of background
+ painter->restore();
+ }
+ }
+ }
+ }
+ break;
+#ifndef QT_NO_SPINBOX
+ case CC_SpinBox:
+ if (const QStyleOptionSpinBox *sb = qstyleoption_cast<const QStyleOptionSpinBox *>(option))
+ {
+ XPThemeData theme(widget, painter, QLatin1String("SPIN"));
+ if (sb->frame && (sub & SC_SpinBoxFrame)) {
+ partId = EP_EDITBORDER_NOSCROLL;
+ if (!(flags & State_Enabled))
+ stateId = ETS_DISABLED;
+ else if (flags & State_MouseOver)
+ stateId = ETS_HOT;
+ else if (flags & State_HasFocus)
+ stateId = ETS_SELECTED;
+ else
+ stateId = ETS_NORMAL;
+
+ XPThemeData ftheme(widget, painter, QLatin1String("EDIT"), partId, stateId, r);
+ ftheme.noContent = true;
+ d->drawBackground(ftheme);
+ }
+ if (sub & SC_SpinBoxUp) {
+ theme.rect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxUp, widget).adjusted(0, 0, 0, 1);
+ partId = SPNP_UP;
+ if (!(sb->stepEnabled & QAbstractSpinBox::StepUpEnabled) || !(flags & State_Enabled))
+ stateId = UPS_DISABLED;
+ else if (sb->activeSubControls == SC_SpinBoxUp && (sb->state & State_Sunken))
+ stateId = UPS_PRESSED;
+ else if (sb->activeSubControls == SC_SpinBoxUp && (sb->state & State_MouseOver))
+ stateId = UPS_HOT;
+ else
+ stateId = UPS_NORMAL;
+ theme.partId = partId;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+ }
+ if (sub & SC_SpinBoxDown) {
+ theme.rect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxDown, widget);
+ partId = SPNP_DOWN;
+ if (!(sb->stepEnabled & QAbstractSpinBox::StepDownEnabled) || !(flags & State_Enabled))
+ stateId = DNS_DISABLED;
+ else if (sb->activeSubControls == SC_SpinBoxDown && (sb->state & State_Sunken))
+ stateId = DNS_PRESSED;
+ else if (sb->activeSubControls == SC_SpinBoxDown && (sb->state & State_MouseOver))
+ stateId = DNS_HOT;
+ else
+ stateId = DNS_NORMAL;
+ theme.partId = partId;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+ }
+ }
+ break;
+#endif // QT_NO_SPINBOX
+ default:
+ QWindowsXPStyle::drawComplexControl(control, option, painter, widget);
+ break;
+ }
+}
+
+/*!
+ \internal
+ */
+QSize QWindowsVistaStyle::sizeFromContents(ContentsType type, const QStyleOption *option,
+ const QSize &size, const QWidget *widget) const
+{
+ if (!QWindowsVistaStylePrivate::useVista())
+ return QWindowsStyle::sizeFromContents(type, option, size, widget);
+
+ QSize sz(size);
+ switch (type) {
+ case CT_MenuItem:
+ sz = QWindowsXPStyle::sizeFromContents(type, option, size, widget);
+ int minimumHeight;
+ {
+ SIZE size;
+ MARGINS margins;
+ XPThemeData theme(widget, 0, QLatin1String("MENU"), MENU_POPUPCHECKBACKGROUND, MBI_HOT);
+ pGetThemePartSize(theme.handle(), NULL, MENU_POPUPCHECK, 0, NULL,TS_TRUE, &size);
+ pGetThemeMargins(theme.handle(), NULL, MENU_POPUPCHECK, 0, TMT_CONTENTMARGINS, NULL, &margins);
+ minimumHeight = qMax<qint32>(size.cy + margins.cyBottomHeight+ margins.cyTopHeight, sz.height());
+ sz.rwidth() += size.cx + margins.cxLeftWidth + margins.cxRightWidth;
+ }
+
+ if (const QStyleOptionMenuItem *menuitem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
+ if (menuitem->menuItemType != QStyleOptionMenuItem::Separator)
+ sz.setHeight(minimumHeight);
+ }
+ return sz;
+#ifndef QT_NO_MENUBAR
+ case CT_MenuBarItem:
+ if (!sz.isEmpty())
+ sz += QSize(windowsItemHMargin * 5 + 1, 5);
+ return sz;
+ break;
+#endif
+ case CT_ItemViewItem:
+ sz = QWindowsXPStyle::sizeFromContents(type, option, size, widget);
+ sz.rheight() += 2;
+ return sz;
+ case CT_SpinBox:
+ {
+ //Spinbox adds frame twice
+ sz = QWindowsStyle::sizeFromContents(type, option, size, widget);
+ int border = proxy()->pixelMetric(PM_SpinBoxFrameWidth, option, widget);
+ sz -= QSize(2*border, 2*border);
+ }
+ return sz;
+ default:
+ break;
+ }
+ return QWindowsXPStyle::sizeFromContents(type, option, size, widget);
+}
+
+/*!
+ \internal
+ */
+QRect QWindowsVistaStyle::subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const
+{
+ if (!QWindowsVistaStylePrivate::useVista())
+ return QWindowsStyle::subElementRect(element, option, widget);
+
+ QRect rect = QWindowsXPStyle::subElementRect(element, option, widget);
+ switch (element) {
+
+ case SE_PushButtonContents:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
+ MARGINS borderSize;
+ HTHEME theme = pOpenThemeData(widget ? QWindowsVistaStylePrivate::winId(widget) : 0, L"Button");
+ if (theme) {
+ int stateId = PBS_NORMAL;
+ if (!(option->state & State_Enabled))
+ stateId = PBS_DISABLED;
+ else if (option->state & State_Sunken)
+ stateId = PBS_PRESSED;
+ else if (option->state & State_MouseOver)
+ stateId = PBS_HOT;
+ else if (btn->features & QStyleOptionButton::DefaultButton)
+ stateId = PBS_DEFAULTED;
+
+ int border = proxy()->pixelMetric(PM_DefaultFrameWidth, btn, widget);
+ rect = option->rect.adjusted(border, border, -border, -border);
+
+ int result = pGetThemeMargins(theme,
+ NULL,
+ BP_PUSHBUTTON,
+ stateId,
+ TMT_CONTENTMARGINS,
+ NULL,
+ &borderSize);
+
+ if (result == S_OK) {
+ rect.adjust(borderSize.cxLeftWidth, borderSize.cyTopHeight,
+ -borderSize.cxRightWidth, -borderSize.cyBottomHeight);
+ rect = visualRect(option->direction, option->rect, rect);
+ }
+ }
+ }
+ break;
+
+ case SE_HeaderArrow:
+ {
+ QRect r = rect;
+ int h = option->rect.height();
+ int w = option->rect.width();
+ int x = option->rect.x();
+ int y = option->rect.y();
+ int margin = proxy()->pixelMetric(QStyle::PM_HeaderMargin, option, widget);
+
+ XPThemeData theme(widget, 0, QLatin1String("HEADER"), HP_HEADERSORTARROW, HSAS_SORTEDDOWN, option->rect);
+
+ int arrowWidth = 13;
+ int arrowHeight = 5;
+ if (theme.isValid()) {
+ SIZE size;
+ if (pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size) == S_OK) {
+ arrowWidth = size.cx;
+ arrowHeight = size.cy;
+ }
+ }
+ if (option->state & State_Horizontal) {
+ r.setRect(x + w/2 - arrowWidth/2, y , arrowWidth, arrowHeight);
+ } else {
+ int vert_size = w / 2;
+ r.setRect(x + 5, y + h - margin * 2 - vert_size,
+ w - margin * 2 - 5, vert_size);
+ }
+ rect = visualRect(option->direction, option->rect, r);
+ }
+ break;
+
+ case SE_HeaderLabel:
+ {
+ int margin = proxy()->pixelMetric(QStyle::PM_HeaderMargin, option, widget);
+ QRect r = option->rect;
+ r.setRect(option->rect.x() + margin, option->rect.y() + margin,
+ option->rect.width() - margin * 2, option->rect.height() - margin * 2);
+ if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
+ // Subtract width needed for arrow, if there is one
+ if (header->sortIndicator != QStyleOptionHeader::None) {
+ if (!(option->state & State_Horizontal)) //horizontal arrows are positioned on top
+ r.setHeight(r.height() - (option->rect.width() / 2) - (margin * 2));
+ }
+ }
+ rect = visualRect(option->direction, option->rect, r);
+ }
+ break;
+ case SE_ProgressBarContents:
+ rect = QCommonStyle::subElementRect(SE_ProgressBarGroove, option, widget);
+ break;
+ case SE_ItemViewItemDecoration:
+ if (qstyleoption_cast<const QStyleOptionViewItemV4 *>(option))
+ rect.adjust(-2, 0, 2, 0);
+ break;
+ case SE_ItemViewItemFocusRect:
+ if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(option)) {
+ QRect textRect = subElementRect(QStyle::SE_ItemViewItemText, option, widget);
+ QRect displayRect = subElementRect(QStyle::SE_ItemViewItemDecoration, option, widget);
+ if (!vopt->icon.isNull())
+ rect = textRect.united(displayRect);
+ else
+ rect = textRect;
+ rect = rect.adjusted(1, 0, -1, 0);
+ }
+ break;
+ default:
+ break;
+ }
+ return rect;
+}
+
+
+/*
+ This function is used by subControlRect to check if a button
+ should be drawn for the given subControl given a set of window flags.
+*/
+static bool buttonVisible(const QStyle::SubControl sc, const QStyleOptionTitleBar *tb){
+
+ bool isMinimized = tb->titleBarState & Qt::WindowMinimized;
+ bool isMaximized = tb->titleBarState & Qt::WindowMaximized;
+ const uint flags = tb->titleBarFlags;
+ bool retVal = false;
+ switch (sc) {
+ case QStyle::SC_TitleBarContextHelpButton:
+ if (flags & Qt::WindowContextHelpButtonHint)
+ retVal = true;
+ break;
+ case QStyle::SC_TitleBarMinButton:
+ if (!isMinimized && (flags & Qt::WindowMinimizeButtonHint))
+ retVal = true;
+ break;
+ case QStyle::SC_TitleBarNormalButton:
+ if (isMinimized && (flags & Qt::WindowMinimizeButtonHint))
+ retVal = true;
+ else if (isMaximized && (flags & Qt::WindowMaximizeButtonHint))
+ retVal = true;
+ break;
+ case QStyle::SC_TitleBarMaxButton:
+ if (!isMaximized && (flags & Qt::WindowMaximizeButtonHint))
+ retVal = true;
+ break;
+ case QStyle::SC_TitleBarShadeButton:
+ if (!isMinimized && flags & Qt::WindowShadeButtonHint)
+ retVal = true;
+ break;
+ case QStyle::SC_TitleBarUnshadeButton:
+ if (isMinimized && flags & Qt::WindowShadeButtonHint)
+ retVal = true;
+ break;
+ case QStyle::SC_TitleBarCloseButton:
+ if (flags & Qt::WindowSystemMenuHint)
+ retVal = true;
+ break;
+ case QStyle::SC_TitleBarSysMenu:
+ if (flags & Qt::WindowSystemMenuHint)
+ retVal = true;
+ break;
+ default :
+ retVal = true;
+ }
+ return retVal;
+}
+
+
+/*! \internal */
+int QWindowsVistaStyle::styleHint(StyleHint hint, const QStyleOption *option, const QWidget *widget,
+ QStyleHintReturn *returnData) const
+{
+ QWindowsVistaStylePrivate *d = const_cast<QWindowsVistaStylePrivate*>(d_func());
+ int ret = 0;
+ switch (hint) {
+ case SH_MessageBox_CenterButtons:
+ ret = false;
+ break;
+ case SH_ToolTip_Mask:
+ if (option) {
+ if (QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask*>(returnData)) {
+ ret = true;
+ XPThemeData themeData(widget, 0, QLatin1String("TOOLTIP"), TTP_STANDARD, TTSS_NORMAL, option->rect);
+ mask->region = d->region(themeData);
+ }
+ }
+ break;
+ case SH_Table_GridLineColor:
+ if (option)
+ ret = option->palette.color(QPalette::Base).darker(118).rgb();
+ else
+ ret = -1;
+ break;
+ default:
+ ret = QWindowsXPStyle::styleHint(hint, option, widget, returnData);
+ break;
+ }
+ return ret;
+}
+
+
+/*!
+ \internal
+ */
+QRect QWindowsVistaStyle::subControlRect(ComplexControl control, const QStyleOptionComplex *option,
+ SubControl subControl, const QWidget *widget) const
+{
+ if (!QWindowsVistaStylePrivate::useVista())
+ return QWindowsStyle::subControlRect(control, option, subControl, widget);
+
+ QRect rect = QWindowsXPStyle::subControlRect(control, option, subControl, widget);
+ switch (control) {
+#ifndef QT_NO_COMBOBOX
+ case CC_ComboBox:
+ if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
+ int x = cb->rect.x(),
+ y = cb->rect.y(),
+ wi = cb->rect.width(),
+ he = cb->rect.height();
+ int xpos = x;
+ int margin = cb->frame ? 3 : 0;
+ int bmarg = cb->frame ? 2 : 0;
+ int arrowButtonWidth = bmarg + 16;
+ xpos += wi - arrowButtonWidth;
+
+ switch (subControl) {
+ case SC_ComboBoxFrame:
+ rect = cb->rect;
+ break;
+ case SC_ComboBoxArrow:
+ rect.setRect(xpos, y , arrowButtonWidth, he);
+ break;
+ case SC_ComboBoxEditField:
+ rect.setRect(x + margin, y + margin, wi - 2 * margin - 16, he - 2 * margin);
+ break;
+ case SC_ComboBoxListBoxPopup:
+ rect = cb->rect;
+ break;
+ default:
+ break;
+ }
+ rect = visualRect(cb->direction, cb->rect, rect);
+ return rect;
+ }
+#endif // QT_NO_COMBOBOX
+ case CC_TitleBar:
+ if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(option)) {
+ if (!buttonVisible(subControl, tb))
+ return rect;
+ const bool isToolTitle = false;
+ const int height = tb->rect.height();
+ const int width = tb->rect.width();
+ int buttonWidth = GetSystemMetrics(SM_CXSIZE) - 4;
+
+ const int frameWidth = proxy()->pixelMetric(PM_MdiSubWindowFrameWidth, option, widget);
+ const bool sysmenuHint = (tb->titleBarFlags & Qt::WindowSystemMenuHint) != 0;
+ const bool minimizeHint = (tb->titleBarFlags & Qt::WindowMinimizeButtonHint) != 0;
+ const bool maximizeHint = (tb->titleBarFlags & Qt::WindowMaximizeButtonHint) != 0;
+ const bool contextHint = (tb->titleBarFlags & Qt::WindowContextHelpButtonHint) != 0;
+ const bool shadeHint = (tb->titleBarFlags & Qt::WindowShadeButtonHint) != 0;
+
+ switch (subControl) {
+ case SC_TitleBarLabel:
+ rect = QRect(frameWidth, 0, width - (buttonWidth + frameWidth + 10), height);
+ if (isToolTitle) {
+ if (sysmenuHint) {
+ rect.adjust(0, 0, -buttonWidth - 3, 0);
+ }
+ if (minimizeHint || maximizeHint)
+ rect.adjust(0, 0, -buttonWidth - 2, 0);
+ } else {
+ if (sysmenuHint) {
+ const int leftOffset = height - 8;
+ rect.adjust(leftOffset, 0, 0, 4);
+ }
+ if (minimizeHint)
+ rect.adjust(0, 0, -buttonWidth - 2, 0);
+ if (maximizeHint)
+ rect.adjust(0, 0, -buttonWidth - 2, 0);
+ if (contextHint)
+ rect.adjust(0, 0, -buttonWidth - 2, 0);
+ if (shadeHint)
+ rect.adjust(0, 0, -buttonWidth - 2, 0);
+ }
+ rect.translate(0, 2);
+ rect = visualRect(option->direction, option->rect, rect);
+ break;
+ case SC_TitleBarSysMenu:
+ {
+ const int controlTop = 6;
+ const int controlHeight = height - controlTop - 3;
+ int iconExtent = proxy()->pixelMetric(PM_SmallIconSize);
+ QSize iconSize = tb->icon.actualSize(QSize(iconExtent, iconExtent));
+ if (tb->icon.isNull())
+ iconSize = QSize(controlHeight, controlHeight);
+ int hPad = (controlHeight - iconSize.height())/2;
+ int vPad = (controlHeight - iconSize.width())/2;
+ rect = QRect(frameWidth + hPad, controlTop + vPad, iconSize.width(), iconSize.height());
+ rect.translate(0, 3);
+ rect = visualRect(option->direction, option->rect, rect);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ return rect;
+}
+
+/*!
+ \internal
+ */
+bool QWindowsVistaStyle::event(QEvent *e)
+{
+ Q_D(QWindowsVistaStyle);
+ switch (e->type()) {
+ case QEvent::Timer:
+ {
+ QTimerEvent *timerEvent = (QTimerEvent *)e;
+ if (d->animationTimer.timerId() == timerEvent->timerId()) {
+ d->timerEvent();
+ e->accept();
+ return true;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ return QWindowsXPStyle::event(e);
+}
+
+/*!
+ \internal
+ */
+QStyle::SubControl QWindowsVistaStyle::hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option,
+ const QPoint &pos, const QWidget *widget) const
+{
+ if (!QWindowsVistaStylePrivate::useVista()) {
+ return QWindowsStyle::hitTestComplexControl(control, option, pos, widget);
+ }
+ return QWindowsXPStyle::hitTestComplexControl(control, option, pos, widget);
+}
+
+/*!
+ \internal
+ */
+int QWindowsVistaStyle::pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const
+{
+ if (!QWindowsVistaStylePrivate::useVista()) {
+ return QWindowsStyle::pixelMetric(metric, option, widget);
+ }
+ switch (metric) {
+
+ case PM_DockWidgetTitleBarButtonMargin:
+ return int(QStyleHelper::dpiScaled(5.));
+ case PM_ScrollBarSliderMin:
+ return int(QStyleHelper::dpiScaled(18.));
+ case PM_MenuHMargin:
+ case PM_MenuVMargin:
+ return 0;
+ case PM_MenuPanelWidth:
+ return 3;
+ default:
+ break;
+ }
+ return QWindowsXPStyle::pixelMetric(metric, option, widget);
+}
+
+/*!
+ \internal
+ */
+QPalette QWindowsVistaStyle::standardPalette() const
+{
+ return QWindowsXPStyle::standardPalette();
+}
+
+/*!
+ \internal
+ */
+void QWindowsVistaStyle::polish(QApplication *app)
+{
+ QWindowsXPStyle::polish(app);
+}
+
+/*!
+ \internal
+ */
+void QWindowsVistaStyle::polish(QWidget *widget)
+{
+ QWindowsXPStyle::polish(widget);
+#ifndef QT_NO_LINEEDIT
+ if (qobject_cast<QLineEdit*>(widget))
+ widget->setAttribute(Qt::WA_Hover);
+ else
+#endif // QT_NO_LINEEDIT
+ if (qobject_cast<QGroupBox*>(widget))
+ widget->setAttribute(Qt::WA_Hover);
+ else if (qobject_cast<QCommandLinkButton*>(widget)) {
+ QFont buttonFont = widget->font();
+ buttonFont.setFamily(QLatin1String("Segoe UI"));
+ widget->setFont(buttonFont);
+ }
+ else if (widget->inherits("QTipLabel")){
+ //note that since tooltips are not reused
+ //we do not have to care about unpolishing
+ widget->setContentsMargins(3, 0, 4, 0);
+ COLORREF bgRef;
+ HTHEME theme = pOpenThemeData(widget ? QWindowsVistaStylePrivate::winId(widget) : 0, L"TOOLTIP");
+ if (theme) {
+ if (pGetThemeColor(theme, TTP_STANDARD, TTSS_NORMAL, TMT_TEXTCOLOR, &bgRef) == S_OK) {
+ QColor textColor = QColor::fromRgb(bgRef);
+ QPalette pal;
+ pal.setColor(QPalette::All, QPalette::ToolTipText, textColor);
+ widget->setPalette(pal);
+ }
+ }
+ } else if (qobject_cast<QMessageBox *> (widget)) {
+ widget->setAttribute(Qt::WA_StyledBackground);
+ QDialogButtonBox *buttonBox = widget->findChild<QDialogButtonBox *>(QLatin1String("qt_msgbox_buttonbox"));
+ if (buttonBox)
+ buttonBox->setContentsMargins(0, 9, 0, 0);
+ }
+#ifndef QT_NO_INPUTDIALOG
+ else if (qobject_cast<QInputDialog *> (widget)) {
+ widget->setAttribute(Qt::WA_StyledBackground);
+ QDialogButtonBox *buttonBox = widget->findChild<QDialogButtonBox *>(QLatin1String("qt_inputdlg_buttonbox"));
+ if (buttonBox)
+ buttonBox->setContentsMargins(0, 9, 0, 0);
+ }
+#endif // QT_NO_INPUTDIALOG
+ 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);
+ }
+}
+
+/*!
+ \internal
+ */
+void QWindowsVistaStyle::unpolish(QWidget *widget)
+{
+ QWindowsXPStyle::unpolish(widget);
+
+ QWindowsVistaStylePrivate *d = const_cast<QWindowsVistaStylePrivate*>(d_func());
+ d->stopAnimation(widget);
+
+#ifndef QT_NO_LINEEDIT
+ if (qobject_cast<QLineEdit*>(widget))
+ widget->setAttribute(Qt::WA_Hover, false);
+ else
+#endif // QT_NO_LINEEDIT
+ if (qobject_cast<QGroupBox*>(widget))
+ widget->setAttribute(Qt::WA_Hover, false);
+ else if (qobject_cast<QMessageBox *> (widget)) {
+ widget->setAttribute(Qt::WA_StyledBackground, false);
+ QDialogButtonBox *buttonBox = widget->findChild<QDialogButtonBox *>(QLatin1String("qt_msgbox_buttonbox"));
+ if (buttonBox)
+ buttonBox->setContentsMargins(0, 0, 0, 0);
+ }
+#ifndef QT_NO_INPUTDIALOG
+ else if (qobject_cast<QInputDialog *> (widget)) {
+ widget->setAttribute(Qt::WA_StyledBackground, false);
+ QDialogButtonBox *buttonBox = widget->findChild<QDialogButtonBox *>(QLatin1String("qt_inputdlg_buttonbox"));
+ if (buttonBox)
+ buttonBox->setContentsMargins(0, 0, 0, 0);
+ }
+#endif // QT_NO_INPUTDIALOG
+ else if (QTreeView *tree = qobject_cast<QTreeView *> (widget)) {
+ tree->viewport()->setAttribute(Qt::WA_Hover, false);
+ } else if (qobject_cast<QCommandLinkButton*>(widget)) {
+ QFont font = QApplication::font("QCommandLinkButton");
+ QFont widgetFont = widget->font();
+ widgetFont.setFamily(font.family()); //Only family set by polish
+ widget->setFont(widgetFont);
+ }
+}
+
+
+/*!
+ \internal
+ */
+void QWindowsVistaStyle::unpolish(QApplication *app)
+{
+ QWindowsXPStyle::unpolish(app);
+}
+
+/*!
+ \internal
+ */
+void QWindowsVistaStyle::polish(QPalette &pal)
+{
+ QWindowsStyle::polish(pal);
+ pal.setBrush(QPalette::AlternateBase, pal.base().color().darker(104));
+}
+
+/*!
+ \internal
+ */
+QPixmap QWindowsVistaStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *option,
+ const QWidget *widget) const
+{
+ if (!QWindowsVistaStylePrivate::useVista()) {
+ return QWindowsStyle::standardPixmap(standardPixmap, option, widget);
+ }
+ return QWindowsXPStyle::standardPixmap(standardPixmap, option, widget);
+}
+
+QWindowsVistaStylePrivate::QWindowsVistaStylePrivate() :
+ QWindowsXPStylePrivate(), m_treeViewHelper(0)
+{
+ resolveSymbols();
+}
+
+QWindowsVistaStylePrivate::~QWindowsVistaStylePrivate()
+{
+ delete m_treeViewHelper;
+}
+
+void QWindowsVistaStylePrivate::timerEvent()
+{
+ for (int i = animations.size() - 1 ; i >= 0 ; --i) {
+
+ if (animations[i]->widget())
+ animations[i]->widget()->update();
+
+ if (!animations[i]->widget() ||
+ !animations[i]->widget()->isVisible() ||
+ animations[i]->widget()->window()->isMinimized() ||
+ !animations[i]->running() ||
+ !QWindowsVistaStylePrivate::useVista())
+ {
+ QWindowsVistaAnimation *a = animations.takeAt(i);
+ delete a;
+ }
+ }
+ if (animations.size() == 0 && animationTimer.isActive()) {
+ animationTimer.stop();
+ }
+}
+
+void QWindowsVistaStylePrivate::stopAnimation(const QWidget *w)
+{
+ for (int i = animations.size() - 1 ; i >= 0 ; --i) {
+ if (animations[i]->widget() == w) {
+ QWindowsVistaAnimation *a = animations.takeAt(i);
+ delete a;
+ break;
+ }
+ }
+}
+
+void QWindowsVistaStylePrivate::startAnimation(QWindowsVistaAnimation *t)
+{
+ Q_Q(QWindowsVistaStyle);
+ stopAnimation(t->widget());
+ animations.append(t);
+ if (animations.size() > 0 && !animationTimer.isActive()) {
+ animationTimer.start(45, q);
+ }
+}
+
+bool QWindowsVistaStylePrivate::transitionsEnabled() const
+{
+ BOOL animEnabled = false;
+ if (SystemParametersInfo(SPI_GETCLIENTAREAANIMATION, 0, &animEnabled, 0))
+ {
+ if (animEnabled)
+ return true;
+ }
+ return false;
+}
+
+
+QWindowsVistaAnimation * QWindowsVistaStylePrivate::widgetAnimation(const QWidget *widget) const
+{
+ if (!widget)
+ return 0;
+ foreach (QWindowsVistaAnimation *a, animations) {
+ if (a->widget() == widget)
+ return a;
+ }
+ return 0;
+}
+
+
+/*! \internal
+ Returns true if all the necessary theme engine symbols were
+ resolved.
+*/
+bool QWindowsVistaStylePrivate::resolveSymbols()
+{
+ static bool tried = false;
+ if (!tried) {
+ tried = true;
+ QSystemLibrary themeLib(QLatin1String("uxtheme"));
+ pSetWindowTheme = (PtrSetWindowTheme )themeLib.resolve("SetWindowTheme");
+ pIsThemePartDefined = (PtrIsThemePartDefined )themeLib.resolve("IsThemePartDefined");
+ pGetThemePartSize = (PtrGetThemePartSize )themeLib.resolve("GetThemePartSize");
+ pOpenThemeData = (PtrOpenThemeData )themeLib.resolve("OpenThemeData");
+ pCloseThemeData = (PtrCloseThemeData )themeLib.resolve("CloseThemeData");
+ pDrawThemeBackground = (PtrDrawThemeBackground )themeLib.resolve("DrawThemeBackground");
+ pDrawThemeBackgroundEx = (PtrDrawThemeBackgroundEx )themeLib.resolve("DrawThemeBackgroundEx");
+ pGetCurrentThemeName = (PtrGetCurrentThemeName )themeLib.resolve("GetCurrentThemeName");
+ pGetThemeBool = (PtrGetThemeBool )themeLib.resolve("GetThemeBool");
+ pGetThemeColor = (PtrGetThemeColor )themeLib.resolve("GetThemeColor");
+ pGetThemeEnumValue = (PtrGetThemeEnumValue )themeLib.resolve("GetThemeEnumValue");
+ pGetThemeFilename = (PtrGetThemeFilename )themeLib.resolve("GetThemeFilename");
+ pGetThemeFont = (PtrGetThemeFont )themeLib.resolve("GetThemeFont");
+ pGetThemeInt = (PtrGetThemeInt )themeLib.resolve("GetThemeInt");
+ pGetThemeIntList = (PtrGetThemeIntList )themeLib.resolve("GetThemeIntList");
+ pGetThemeMargins = (PtrGetThemeMargins )themeLib.resolve("GetThemeMargins");
+ pGetThemeMetric = (PtrGetThemeMetric )themeLib.resolve("GetThemeMetric");
+ pGetThemePartSize = (PtrGetThemePartSize )themeLib.resolve("GetThemePartSize");
+ pGetThemePosition = (PtrGetThemePosition )themeLib.resolve("GetThemePosition");
+ pGetThemeRect = (PtrGetThemeRect )themeLib.resolve("GetThemeRect");
+ pGetThemeString = (PtrGetThemeString )themeLib.resolve("GetThemeString");
+ pGetThemeTransitionDuration = (PtrGetThemeTransitionDuration)themeLib.resolve("GetThemeTransitionDuration");
+ pGetThemePropertyOrigin = (PtrGetThemePropertyOrigin)themeLib.resolve("GetThemePropertyOrigin");
+ }
+ return pGetThemeTransitionDuration != 0;
+}
+
+/*
+ * We need to set the windows explorer theme explicitly on a native widget
+ * in order to get Vista-style item view themes
+ */
+QWidget *QWindowsVistaStylePrivate::treeViewHelper()
+{
+ if (!m_treeViewHelper) {
+ m_treeViewHelper = new QWidget(0);
+ HWND handle = QApplicationPrivate::getHWNDForWidget(m_treeViewHelper);
+ pSetWindowTheme(handle, L"explorer", NULL);
+ }
+ return m_treeViewHelper;
+}
+
+
+/*!
+\internal
+*/
+QIcon QWindowsVistaStyle::standardIconImplementation(StandardPixmap standardIcon,
+ const QStyleOption *option,
+ const QWidget *widget) const
+{
+ if (!QWindowsVistaStylePrivate::useVista()) {
+ return QWindowsStyle::standardIconImplementation(standardIcon, option, widget);
+ }
+
+ QWindowsVistaStylePrivate *d = const_cast<QWindowsVistaStylePrivate *>(d_func());
+ switch(standardIcon) {
+ case SP_CommandLink:
+ {
+ XPThemeData theme(0, 0, QLatin1String("BUTTON"), BP_COMMANDLINKGLYPH, CMDLGS_NORMAL);
+ if (theme.isValid()) {
+ SIZE size;
+ pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
+ QIcon linkGlyph;
+ QPixmap pm = QPixmap(size.cx, size.cy);
+ pm.fill(Qt::transparent);
+ QPainter p(&pm);
+ theme.painter = &p;
+ theme.rect = QRect(0, 0, size.cx, size.cy);
+ d->drawBackground(theme);
+ linkGlyph.addPixmap(pm, QIcon::Normal, QIcon::Off); // Normal
+ pm.fill(Qt::transparent);
+
+ theme.stateId = CMDLGS_PRESSED;
+ d->drawBackground(theme);
+ linkGlyph.addPixmap(pm, QIcon::Normal, QIcon::On); // Pressed
+ pm.fill(Qt::transparent);
+
+ theme.stateId = CMDLGS_HOT;
+ d->drawBackground(theme);
+ linkGlyph.addPixmap(pm, QIcon::Active, QIcon::Off); // Hover
+ pm.fill(Qt::transparent);
+
+ theme.stateId = CMDLGS_DISABLED;
+ d->drawBackground(theme);
+ linkGlyph.addPixmap(pm, QIcon::Disabled, QIcon::Off); // Disabled
+ return linkGlyph;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ return QWindowsXPStyle::standardIconImplementation(standardIcon, option, widget);
+}
+
+QT_END_NAMESPACE
+
+#endif //QT_NO_WINDOWSVISTA
diff --git a/src/widgets/styles/qwindowsvistastyle.h b/src/widgets/styles/qwindowsvistastyle.h
new file mode 100644
index 0000000000..68b489107e
--- /dev/null
+++ b/src/widgets/styles/qwindowsvistastyle.h
@@ -0,0 +1,108 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSVISTASTYLE_H
+#define QWINDOWSVISTASTYLE_H
+
+#include <QtWidgets/qwindowsxpstyle.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#if !defined(QT_NO_STYLE_WINDOWSVISTA)
+
+class QWindowsVistaStylePrivate;
+class Q_WIDGETS_EXPORT QWindowsVistaStyle : public QWindowsXPStyle
+{
+ Q_OBJECT
+public:
+ QWindowsVistaStyle();
+
+ void drawPrimitive(PrimitiveElement element, const QStyleOption *option,
+ QPainter *painter, const QWidget *widget = 0) const;
+ void drawControl(ControlElement element, const QStyleOption *option,
+ QPainter *painter, const QWidget *widget) const;
+ void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option,
+ QPainter *painter, const QWidget *widget) const;
+ QSize sizeFromContents(ContentsType type, const QStyleOption *option,
+ const QSize &size, const QWidget *widget) const;
+
+ QRect subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const;
+ QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt,
+ SubControl sc, const QWidget *widget) const;
+
+ SubControl hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option,
+ const QPoint &pos, const QWidget *widget = 0) const;
+
+ QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt,
+ const QWidget *widget = 0) const;
+ int pixelMetric(PixelMetric metric, const QStyleOption *option = 0, const QWidget *widget = 0) const;
+ int styleHint(StyleHint hint, const QStyleOption *opt = 0, const QWidget *widget = 0,
+ QStyleHintReturn *returnData = 0) const;
+
+
+ void polish(QWidget *widget);
+ void unpolish(QWidget *widget);
+ void polish(QPalette &pal);
+ void polish(QApplication *app);
+ void unpolish(QApplication *app);
+ bool event(QEvent *event);
+ QPalette standardPalette() const;
+
+protected Q_SLOTS:
+ QIcon standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *option,
+ const QWidget *widget = 0) const;
+
+private:
+ Q_DISABLE_COPY(QWindowsVistaStyle)
+ Q_DECLARE_PRIVATE(QWindowsVistaStyle)
+ friend class QStyleFactory;
+};
+#endif //QT_NO_STYLE_WINDOWSVISTA
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif //QWINDOWSVISTASTYLE_H
diff --git a/src/gui/styles/qwindowsvistastyle_p.h b/src/widgets/styles/qwindowsvistastyle_p.h
index 4167bc4d0f..4167bc4d0f 100644
--- a/src/gui/styles/qwindowsvistastyle_p.h
+++ b/src/widgets/styles/qwindowsvistastyle_p.h
diff --git a/src/widgets/styles/qwindowsxpstyle.cpp b/src/widgets/styles/qwindowsxpstyle.cpp
new file mode 100644
index 0000000000..cbaf16989a
--- /dev/null
+++ b/src/widgets/styles/qwindowsxpstyle.cpp
@@ -0,0 +1,4350 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "qwindowsxpstyle.h"
+#include "qwindowsxpstyle_p.h"
+
+#if !defined(QT_NO_STYLE_WINDOWSXP) || defined(QT_PLUGIN)
+
+#include <private/qobject_p.h>
+#include <private/qpaintengine_raster_p.h>
+#include <private/qapplication_p.h>
+#include <qplatformnativeinterface_qpa.h>
+#include <private/qstylehelper_p.h>
+#include <private/qwidget_p.h>
+#include <private/qsystemlibrary_p.h>
+#include <qpainter.h>
+#include <qpaintengine.h>
+#include <qwidget.h>
+#include <qapplication.h>
+#include <qpixmapcache.h>
+
+#include <qdesktopwidget.h>
+#include <qtoolbutton.h>
+#include <qtabbar.h>
+#include <qcombobox.h>
+#include <qscrollbar.h>
+#include <qheaderview.h>
+#include <qspinbox.h>
+#include <qlistview.h>
+#include <qstackedwidget.h>
+#include <qpushbutton.h>
+#include <qtoolbar.h>
+#include <qlabel.h>
+#include <qvarlengtharray.h>
+#include <qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+// Runtime resolved theme engine function calls
+typedef bool (WINAPI *PtrIsAppThemed)();
+typedef bool (WINAPI *PtrIsThemeActive)();
+typedef HRESULT (WINAPI *PtrGetThemePartSize)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, OPTIONAL RECT *prc, enum THEMESIZE eSize, OUT SIZE *psz);
+typedef HTHEME (WINAPI *PtrOpenThemeData)(HWND hwnd, LPCWSTR pszClassList);
+typedef HRESULT (WINAPI *PtrCloseThemeData)(HTHEME hTheme);
+typedef HRESULT (WINAPI *PtrDrawThemeBackground)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, OPTIONAL const RECT *pClipRect);
+typedef HRESULT (WINAPI *PtrDrawThemeBackgroundEx)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, OPTIONAL const DTBGOPTS *pOptions);
+typedef HRESULT (WINAPI *PtrGetCurrentThemeName)(OUT LPWSTR pszThemeFileName, int cchMaxNameChars, OUT OPTIONAL LPWSTR pszColorBuff, int cchMaxColorChars, OUT OPTIONAL LPWSTR pszSizeBuff, int cchMaxSizeChars);
+typedef HRESULT (WINAPI *PtrGetThemeDocumentationProperty)(LPCWSTR pszThemeName, LPCWSTR pszPropertyName, OUT LPWSTR pszValueBuff, int cchMaxValChars);
+typedef HRESULT (WINAPI *PtrGetThemeBool)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT BOOL *pfVal);
+typedef HRESULT (WINAPI *PtrGetThemeColor)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT COLORREF *pColor);
+typedef HRESULT (WINAPI *PtrGetThemeEnumValue)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT int *piVal);
+typedef HRESULT (WINAPI *PtrGetThemeFilename)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT LPWSTR pszThemeFileName, int cchMaxBuffChars);
+typedef HRESULT (WINAPI *PtrGetThemeFont)(HTHEME hTheme, OPTIONAL HDC hdc, int iPartId, int iStateId, int iPropId, OUT LOGFONT *pFont);
+typedef HRESULT (WINAPI *PtrGetThemeInt)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT int *piVal);
+typedef HRESULT (WINAPI *PtrGetThemeIntList)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT INTLIST *pIntList);
+typedef HRESULT (WINAPI *PtrGetThemeMargins)(HTHEME hTheme, OPTIONAL HDC hdc, int iPartId, int iStateId, int iPropId, OPTIONAL RECT *prc, OUT MARGINS *pMargins);
+typedef HRESULT (WINAPI *PtrGetThemeMetric)(HTHEME hTheme, OPTIONAL HDC hdc, int iPartId, int iStateId, int iPropId, OUT int *piVal);
+typedef HRESULT (WINAPI *PtrGetThemePartSize)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, OPTIONAL RECT *prc, enum THEMESIZE eSize, OUT SIZE *psz);
+typedef HRESULT (WINAPI *PtrGetThemePosition)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT POINT *pPoint);
+typedef HRESULT (WINAPI *PtrGetThemePropertyOrigin)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT enum PROPERTYORIGIN *pOrigin);
+typedef HRESULT (WINAPI *PtrGetThemeRect)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT RECT *pRect);
+typedef HRESULT (WINAPI *PtrGetThemeString)(HTHEME hTheme, int iPartId, int iStateId, int iPropId, OUT LPWSTR pszBuff, int cchMaxBuffChars);
+typedef HRESULT (WINAPI *PtrGetThemeBackgroundRegion)(HTHEME hTheme, OPTIONAL HDC hdc, int iPartId, int iStateId, const RECT *pRect, OUT HRGN *pRegion);
+typedef BOOL (WINAPI *PtrIsThemeBackgroundPartiallyTransparent)(HTHEME hTheme, int iPartId, int iStateId);
+
+static PtrIsAppThemed pIsAppThemed = 0;
+static PtrIsThemeActive pIsThemeActive = 0;
+static PtrOpenThemeData pOpenThemeData = 0;
+static PtrCloseThemeData pCloseThemeData = 0;
+static PtrDrawThemeBackground pDrawThemeBackground = 0;
+static PtrDrawThemeBackgroundEx pDrawThemeBackgroundEx = 0;
+static PtrGetCurrentThemeName pGetCurrentThemeName = 0;
+static PtrGetThemeBool pGetThemeBool = 0;
+static PtrGetThemeColor pGetThemeColor = 0;
+static PtrGetThemeEnumValue pGetThemeEnumValue = 0;
+static PtrGetThemeFilename pGetThemeFilename = 0;
+static PtrGetThemeFont pGetThemeFont = 0;
+static PtrGetThemeInt pGetThemeInt = 0;
+static PtrGetThemeIntList pGetThemeIntList = 0;
+static PtrGetThemeMargins pGetThemeMargins = 0;
+static PtrGetThemeMetric pGetThemeMetric = 0;
+static PtrGetThemePartSize pGetThemePartSize = 0;
+static PtrGetThemePosition pGetThemePosition = 0;
+static PtrGetThemePropertyOrigin pGetThemePropertyOrigin = 0;
+static PtrGetThemeRect pGetThemeRect = 0;
+static PtrGetThemeString pGetThemeString = 0;
+static PtrGetThemeBackgroundRegion pGetThemeBackgroundRegion = 0;
+static PtrGetThemeDocumentationProperty pGetThemeDocumentationProperty = 0;
+static PtrIsThemeBackgroundPartiallyTransparent pIsThemeBackgroundPartiallyTransparent = 0;
+
+// General const values
+static const int windowsItemFrame = 2; // menu item frame width
+static const int windowsItemHMargin = 3; // menu item hor text margin
+static const int windowsItemVMargin = 0; // menu item ver text margin
+static const int windowsArrowHMargin = 6; // arrow horizontal margin
+static const int windowsRightBorder = 12; // right border on windows
+
+// External function calls
+extern Q_WIDGETS_EXPORT HDC qt_win_display_dc();
+extern QRegion qt_region_from_HRGN(HRGN rgn);
+
+
+
+// Theme data helper ------------------------------------------------------------------------------
+/* \internal
+ Returns true if the themedata is valid for use.
+*/
+bool XPThemeData::isValid()
+{
+ return QWindowsXPStylePrivate::useXP() && name.size() && handle();
+}
+
+
+/* \internal
+ Returns the theme engine handle to the specific class.
+ If the handle hasn't been opened before, it opens the data, and
+ adds it to a static map, for caching.
+*/
+HTHEME XPThemeData::handle()
+{
+ if (!QWindowsXPStylePrivate::useXP())
+ return 0;
+
+ if (!htheme && QWindowsXPStylePrivate::handleMap)
+ htheme = QWindowsXPStylePrivate::handleMap->operator[](name);
+
+ if (!htheme) {
+ htheme = pOpenThemeData(QWindowsXPStylePrivate::winId(widget), (wchar_t*)name.utf16());
+ if (htheme) {
+ if (!QWindowsXPStylePrivate::handleMap)
+ QWindowsXPStylePrivate::handleMap = new QMap<QString, HTHEME>;
+ QWindowsXPStylePrivate::handleMap->operator[](name) = htheme;
+ }
+ }
+
+ return htheme;
+}
+
+/* \internal
+ Converts a QRect to the native RECT structure.
+*/
+RECT XPThemeData::toRECT(const QRect &qr)
+{
+ RECT r;
+ r.left = qr.x();
+ r.right = qr.x() + qr.width();
+ r.top = qr.y();
+ r.bottom = qr.y() + qr.height();
+ return r;
+}
+
+/* \internal
+ Returns the native region of a part, if the part is considered
+ transparent. The region is scaled to the parts size (rect).
+*/
+HRGN XPThemeData::mask(QWidget *widget)
+{
+ if (!pIsThemeBackgroundPartiallyTransparent(handle(), partId, stateId))
+ return 0;
+
+ HRGN hrgn;
+ HDC dc = 0;
+ if (widget) {
+ QBackingStore *backingStore = widget->backingStore();
+ QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface();
+ dc = static_cast<HDC>(nativeInterface->nativeResourceForBackingStore("getDC", backingStore));
+ }
+ RECT nativeRect = toRECT(rect);
+ pGetThemeBackgroundRegion(handle(), dc, partId, stateId, &nativeRect, &hrgn);
+ return hrgn;
+}
+
+// QWindowsXPStylePrivate -------------------------------------------------------------------------
+// Static initializations
+QWidget *QWindowsXPStylePrivate::limboWidget = 0;
+QPixmap *QWindowsXPStylePrivate::tabbody = 0;
+QMap<QString,HTHEME> *QWindowsXPStylePrivate::handleMap = 0;
+bool QWindowsXPStylePrivate::use_xp = false;
+QBasicAtomicInt QWindowsXPStylePrivate::ref = Q_BASIC_ATOMIC_INITIALIZER(-1); // -1 based refcounting
+
+static void qt_add_rect(HRGN &winRegion, QRect r)
+{
+ HRGN rgn = CreateRectRgn(r.left(), r.top(), r.x() + r.width(), r.y() + r.height());
+ if (rgn) {
+ HRGN dest = CreateRectRgn(0,0,0,0);
+ int result = CombineRgn(dest, winRegion, rgn, RGN_OR);
+ if (result) {
+ DeleteObject(winRegion);
+ winRegion = dest;
+ }
+ DeleteObject(rgn);
+ }
+}
+
+static HRGN qt_hrgn_from_qregion(const QRegion &region)
+{
+ HRGN hRegion = CreateRectRgn(0,0,0,0);
+ if (region.rectCount() == 1) {
+ qt_add_rect(hRegion, region.boundingRect());
+ return hRegion;
+ }
+ foreach (const QRect &rect, region.rects())
+ qt_add_rect(hRegion, rect);
+ return hRegion;
+}
+
+/* \internal
+ Checks if the theme engine can/should be used, or if we should
+ fall back to Windows style.
+*/
+bool QWindowsXPStylePrivate::useXP(bool update)
+{
+ if (!update)
+ return use_xp;
+ return (use_xp = resolveSymbols() && pIsThemeActive()
+ && (pIsAppThemed() || !QApplication::instance()));
+}
+
+/* \internal
+ Handles refcounting, and queries the theme engine for usage.
+*/
+void QWindowsXPStylePrivate::init(bool force)
+{
+ if (ref.ref() && !force)
+ return;
+ if (!force) // -1 based atomic refcounting
+ ref.ref();
+
+ useXP(true);
+}
+
+/* \internal
+ Cleans up all static data.
+*/
+void QWindowsXPStylePrivate::cleanup(bool force)
+{
+ if(bufferBitmap) {
+ if (bufferDC && nullBitmap)
+ SelectObject(bufferDC, nullBitmap);
+ DeleteObject(bufferBitmap);
+ bufferBitmap = 0;
+ }
+
+ if(bufferDC)
+ DeleteDC(bufferDC);
+ bufferDC = 0;
+
+ if (ref.deref() && !force)
+ return;
+ if (!force) // -1 based atomic refcounting
+ ref.deref();
+
+ use_xp = false;
+ cleanupHandleMap();
+ if (limboWidget) {
+ if (QApplication::closingDown())
+ delete limboWidget;
+ else
+ limboWidget->deleteLater();
+ }
+ delete tabbody;
+ limboWidget = 0;
+ tabbody = 0;
+}
+
+/* \internal
+ Closes all open theme data handles to ensure that we don't leak
+ resources, and that we don't refere to old handles when for
+ example the user changes the theme style.
+*/
+void QWindowsXPStylePrivate::cleanupHandleMap()
+{
+ if (!handleMap)
+ return;
+
+ QMap<QString, HTHEME>::Iterator it;
+ for (it = handleMap->begin(); it != handleMap->end(); ++it)
+ pCloseThemeData(it.value());
+ delete handleMap;
+ handleMap = 0;
+}
+
+/*! \internal
+ This function will always return a valid window handle, and might
+ create a limbo widget to do so.
+ We often need a window handle to for example open theme data, so
+ this function ensures that we get one.
+*/
+HWND QWindowsXPStylePrivate::winId(const QWidget *widget)
+{
+ if (widget && widget->internalWinId()) {
+ QWidget *w = const_cast<QWidget *>(widget);
+ return QApplicationPrivate::getHWNDForWidget(w);
+ }
+ if (!limboWidget) {
+ limboWidget = new QWidget(0);
+ limboWidget->createWinId();
+ limboWidget->setObjectName(QLatin1String("xp_limbo_widget"));
+ // We don't need this internal widget to appear in QApplication::topLevelWidgets()
+ if (QWidgetPrivate::allWidgets)
+ QWidgetPrivate::allWidgets->remove(limboWidget);
+ }
+
+ return QApplicationPrivate::getHWNDForWidget(limboWidget);
+}
+
+/*! \internal
+ Returns the pointer to a tab widgets body pixmap, scaled to the
+ height of the screen. This way the theme engine doesn't need to
+ scale the body for every time we ask for it. (Speed optimization)
+*/
+const QPixmap *QWindowsXPStylePrivate::tabBody(QWidget *)
+{
+ if (!tabbody) {
+ SIZE sz;
+ XPThemeData theme(0, 0, QLatin1String("TAB"), TABP_BODY);
+ pGetThemePartSize(theme.handle(), qt_win_display_dc(), TABP_BODY, 0, 0, TS_TRUE, &sz);
+
+ tabbody = new QPixmap(sz.cx, QApplication::desktop()->screenGeometry().height());
+ QPainter painter(tabbody);
+ theme.rect = QRect(0, 0, sz.cx, sz.cy);
+ drawBackground(theme);
+ // We fill with the last line of the themedata, that
+ // way we don't get a tiled pixmap inside big tabs
+ QPixmap temp(sz.cx, 1);
+ painter.drawPixmap(0, 0, temp, 0, sz.cy-1, -1, -1);
+ painter.drawTiledPixmap(0, sz.cy, sz.cx, tabbody->height()-sz.cy, temp);
+ }
+ return tabbody;
+}
+
+/*! \internal
+ Returns true if all the necessary theme engine symbols were
+ resolved.
+*/
+bool QWindowsXPStylePrivate::resolveSymbols()
+{
+ static bool tried = false;
+ if (!tried) {
+ tried = true;
+ QSystemLibrary themeLib(QLatin1String("uxtheme"));
+ pIsAppThemed = (PtrIsAppThemed)themeLib.resolve("IsAppThemed");
+ if (pIsAppThemed) {
+ pIsThemeActive = (PtrIsThemeActive )themeLib.resolve("IsThemeActive");
+ pGetThemePartSize = (PtrGetThemePartSize )themeLib.resolve("GetThemePartSize");
+ pOpenThemeData = (PtrOpenThemeData )themeLib.resolve("OpenThemeData");
+ pCloseThemeData = (PtrCloseThemeData )themeLib.resolve("CloseThemeData");
+ pDrawThemeBackground = (PtrDrawThemeBackground )themeLib.resolve("DrawThemeBackground");
+ pDrawThemeBackgroundEx = (PtrDrawThemeBackgroundEx )themeLib.resolve("DrawThemeBackgroundEx");
+ pGetCurrentThemeName = (PtrGetCurrentThemeName )themeLib.resolve("GetCurrentThemeName");
+ pGetThemeBool = (PtrGetThemeBool )themeLib.resolve("GetThemeBool");
+ pGetThemeColor = (PtrGetThemeColor )themeLib.resolve("GetThemeColor");
+ pGetThemeEnumValue = (PtrGetThemeEnumValue )themeLib.resolve("GetThemeEnumValue");
+ pGetThemeFilename = (PtrGetThemeFilename )themeLib.resolve("GetThemeFilename");
+ pGetThemeFont = (PtrGetThemeFont )themeLib.resolve("GetThemeFont");
+ pGetThemeInt = (PtrGetThemeInt )themeLib.resolve("GetThemeInt");
+ pGetThemeIntList = (PtrGetThemeIntList )themeLib.resolve("GetThemeIntList");
+ pGetThemeMargins = (PtrGetThemeMargins )themeLib.resolve("GetThemeMargins");
+ pGetThemeMetric = (PtrGetThemeMetric )themeLib.resolve("GetThemeMetric");
+ pGetThemePartSize = (PtrGetThemePartSize )themeLib.resolve("GetThemePartSize");
+ pGetThemePosition = (PtrGetThemePosition )themeLib.resolve("GetThemePosition");
+ pGetThemePropertyOrigin = (PtrGetThemePropertyOrigin)themeLib.resolve("GetThemePropertyOrigin");
+ pGetThemeRect = (PtrGetThemeRect )themeLib.resolve("GetThemeRect");
+ pGetThemeString = (PtrGetThemeString )themeLib.resolve("GetThemeString");
+ pGetThemeBackgroundRegion = (PtrGetThemeBackgroundRegion )themeLib.resolve("GetThemeBackgroundRegion");
+ pGetThemeDocumentationProperty = (PtrGetThemeDocumentationProperty )themeLib.resolve("GetThemeDocumentationProperty");
+ pIsThemeBackgroundPartiallyTransparent = (PtrIsThemeBackgroundPartiallyTransparent)themeLib.resolve("IsThemeBackgroundPartiallyTransparent");
+ }
+ }
+
+ return pIsAppThemed != 0;
+}
+
+/*! \internal
+ Returns a native buffer (DIB section) of at least the size of
+ ( \a x , \a y ). The buffer has a 32 bit depth, to not lose
+ the alpha values on proper alpha-pixmaps.
+*/
+HBITMAP QWindowsXPStylePrivate::buffer(int w, int h)
+{
+ // If we already have a HBITMAP which is of adequate size, just return that
+ if (bufferBitmap) {
+ if (bufferW >= w && bufferH >= h)
+ return bufferBitmap;
+ // Not big enough, discard the old one
+ if (bufferDC && nullBitmap)
+ SelectObject(bufferDC, nullBitmap);
+ DeleteObject(bufferBitmap);
+ bufferBitmap = 0;
+ }
+
+ w = qMax(bufferW, w);
+ h = qMax(bufferH, h);
+
+ if (!bufferDC)
+ bufferDC = CreateCompatibleDC(qt_win_display_dc());
+
+ // Define the header
+ BITMAPINFO bmi;
+ memset(&bmi, 0, sizeof(bmi));
+ bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bmi.bmiHeader.biWidth = w;
+ bmi.bmiHeader.biHeight = -h;
+ bmi.bmiHeader.biPlanes = 1;
+ bmi.bmiHeader.biBitCount = 32;
+ bmi.bmiHeader.biCompression = BI_RGB;
+
+ // Create the pixmap
+ bufferPixels = 0;
+ bufferBitmap = CreateDIBSection(bufferDC, &bmi, DIB_RGB_COLORS, (void **) &bufferPixels, 0, 0);
+ GdiFlush();
+ nullBitmap = (HBITMAP)SelectObject(bufferDC, bufferBitmap);
+
+ if (!bufferBitmap) {
+ qErrnoWarning("QWindowsXPStylePrivate::buffer(w,h), failed to create dibsection");
+ bufferW = 0;
+ bufferH = 0;
+ return 0;
+ }
+ if (!bufferPixels) {
+ qErrnoWarning("QWindowsXPStylePrivate::buffer(w,h), did not allocate pixel data");
+ bufferW = 0;
+ bufferH = 0;
+ return 0;
+ }
+ bufferW = w;
+ bufferH = h;
+#ifdef DEBUG_XP_STYLE
+ qDebug("Creating new dib section (%d, %d)", w, h);
+#endif
+ return bufferBitmap;
+}
+
+/*! \internal
+ Returns true if the part contains any transparency at all. This does
+ not indicate what kind of transparency we're dealing with. It can be
+ - Alpha transparency
+ - Masked transparency
+*/
+bool QWindowsXPStylePrivate::isTransparent(XPThemeData &themeData)
+{
+ return pIsThemeBackgroundPartiallyTransparent(themeData.handle(), themeData.partId,
+ themeData.stateId);
+}
+
+
+/*! \internal
+ Returns a QRegion of the region of the part
+*/
+QRegion QWindowsXPStylePrivate::region(XPThemeData &themeData)
+{
+ HRGN hRgn = 0;
+ RECT rect = themeData.toRECT(themeData.rect);
+ if (!SUCCEEDED(pGetThemeBackgroundRegion(themeData.handle(), bufferHDC(), themeData.partId,
+ themeData.stateId, &rect, &hRgn)))
+ return QRegion();
+
+ HRGN dest = CreateRectRgn(0, 0, 0, 0);
+ const bool success = CombineRgn(dest, hRgn, 0, RGN_COPY) != ERROR;
+
+ QRegion region;
+
+ if (success) {
+ int numBytes = GetRegionData(dest, 0, 0);
+ if (numBytes == 0)
+ return QRegion();
+
+ char *buf = new char[numBytes];
+ if (buf == 0)
+ return QRegion();
+
+ RGNDATA *rd = reinterpret_cast<RGNDATA*>(buf);
+ if (GetRegionData(dest, numBytes, rd) == 0) {
+ delete [] buf;
+ return QRegion();
+ }
+
+ RECT *r = reinterpret_cast<RECT*>(rd->Buffer);
+ for (uint i = 0; i < rd->rdh.nCount; ++i) {
+ QRect rect;
+ rect.setCoords(r->left, r->top, r->right - 1, r->bottom - 1);
+ ++r;
+ region |= rect;
+ }
+
+ delete [] buf;
+ }
+
+ DeleteObject(hRgn);
+ DeleteObject(dest);
+
+ return region;
+}
+
+/*! \internal
+ Sets the parts region on a window.
+*/
+void QWindowsXPStylePrivate::setTransparency(QWidget *widget, XPThemeData &themeData)
+{
+ HRGN hrgn = themeData.mask(widget);
+ if (hrgn && widget)
+ SetWindowRgn(winId(widget), hrgn, true);
+}
+
+/*! \internal
+ Returns true if the native doublebuffer contains a pixel which
+ has a non-0xFF alpha value. Should only be use when its
+ guaranteed that data painted into the buffer wasn't a proper
+ alpha pixmap.
+*/
+bool QWindowsXPStylePrivate::hasAnyData(const QRect &rect)
+{
+ const int startX = rect.left();
+ const int startY = rect.top();
+ const int w = rect.width();
+ const int h = rect.height();
+
+ for (int y = startY; y < h; ++y) {
+ register DWORD *buffer = (DWORD*)bufferPixels + (y * bufferW);
+ for (int x = startX; x < w; ++x, ++buffer) {
+ int alpha = (*buffer) >> 24;
+ if (alpha != 0xFF) // buffer has been touched
+ return true;
+ }
+ }
+ return false;
+}
+
+/*! \internal
+ Returns true if the native doublebuffer contains pixels with
+ varying alpha value.
+*/
+bool QWindowsXPStylePrivate::hasAlphaChannel(const QRect &rect)
+{
+ const int startX = rect.left();
+ const int startY = rect.top();
+ const int w = rect.width();
+ const int h = rect.height();
+
+ int firstAlpha = -1;
+ for (int y = startY; y < h/2; ++y) {
+ register DWORD *buffer = (DWORD*)bufferPixels + (y * bufferW);
+ for (int x = startX; x < w; ++x, ++buffer) {
+ int alpha = (*buffer) >> 24;
+ if (firstAlpha == -1)
+ firstAlpha = alpha;
+ else if (alpha != firstAlpha)
+ return true;
+ }
+ }
+ return false;
+}
+
+/*! \internal
+ When the theme engine paints both a true alpha pixmap and a glyph
+ into our buffer, the glyph might not contain a proper alpha value.
+ The rule of thumb for premultiplied pixmaps is that the color
+ values of a pixel can never be higher than the alpha values, so
+ we use this to our advantage here, and fix all instances where
+ this occures.
+*/
+bool QWindowsXPStylePrivate::fixAlphaChannel(const QRect &rect)
+{
+ const int startX = rect.left();
+ const int startY = rect.top();
+ const int w = rect.width();
+ const int h = rect.height();
+ bool hasFixedAlphaValue = false;
+
+ for (int y = startY; y < h; ++y) {
+ register DWORD *buffer = (DWORD*)bufferPixels + (y * bufferW);
+ for (register int x = startX; x < w; ++x, ++buffer) {
+ uint pixel = *buffer;
+ int alpha = qAlpha(pixel);
+ if (qRed(pixel) > alpha || qGreen(pixel) > alpha || qBlue(pixel) > alpha) {
+ *buffer |= 0xff000000;
+ hasFixedAlphaValue = true;
+ }
+ }
+ }
+ return hasFixedAlphaValue;
+}
+
+/*! \internal
+ Swaps the alpha values on certain pixels:
+ 0xFF?????? -> 0x00??????
+ 0x00?????? -> 0xFF??????
+ Used to determin the mask of a non-alpha transparent pixmap in
+ the native doublebuffer, and swap the alphas so we may paint
+ the image as a Premultiplied QImage with drawImage(), and obtain
+ the mask transparency.
+*/
+bool QWindowsXPStylePrivate::swapAlphaChannel(const QRect &rect, bool allPixels)
+{
+ const int startX = rect.left();
+ const int startY = rect.top();
+ const int w = rect.width();
+ const int h = rect.height();
+ bool valueChange = false;
+
+ // Flip the alphas, so that 255-alpha pixels are 0, and 0-alpha are 255.
+ for (int y = startY; y < h; ++y) {
+ register DWORD *buffer = (DWORD*)bufferPixels + (y * bufferW);
+ for (register int x = startX; x < w; ++x, ++buffer) {
+ if (allPixels) {
+ *buffer |= 0xFF000000;
+ continue;
+ }
+ register unsigned int alphaValue = (*buffer) & 0xFF000000;
+ if (alphaValue == 0xFF000000) {
+ *buffer = 0;
+ valueChange = true;
+ } else if (alphaValue == 0) {
+ *buffer |= 0xFF000000;
+ valueChange = true;
+ }
+ }
+ }
+ return valueChange;
+}
+
+/*! \internal
+ Main theme drawing function.
+ Determines the correct lowlevel drawing method depending on several
+ factors.
+ Use drawBackgroundThruNativeBuffer() if:
+ - Painter does not have an HDC
+ - Theme part is flipped (mirrored horizontally)
+ else use drawBackgroundDirectly().
+*/
+void QWindowsXPStylePrivate::drawBackground(XPThemeData &themeData)
+{
+ if (themeData.rect.isEmpty())
+ return;
+
+ QPainter *painter = themeData.painter;
+ Q_ASSERT_X(painter != 0, "QWindowsXPStylePrivate::drawBackground()", "Trying to draw a theme part without a painter");
+ if (!painter || !painter->isActive())
+ return;
+
+ painter->save();
+
+ bool complexXForm = painter->deviceTransform().type() > QTransform::TxTranslate;
+
+ bool translucentToplevel = false;
+ QPaintDevice *pdev = painter->device();
+ if (pdev->devType() == QInternal::Widget) {
+ QWidget *win = ((QWidget *) pdev)->window();
+ translucentToplevel = win->testAttribute(Qt::WA_TranslucentBackground);
+ }
+
+ HDC dc = 0;
+ if (themeData.widget) {
+ QBackingStore *backingStore = themeData.widget->backingStore();
+ QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface();
+ dc = static_cast<HDC>(nativeInterface->nativeResourceForBackingStore("getDC", backingStore ));
+ }
+
+ bool useFallback = dc == 0
+ || painter->opacity() != 1.0
+ || themeData.rotate
+ || complexXForm
+ || themeData.mirrorVertically
+ || (themeData.mirrorHorizontally && pDrawThemeBackgroundEx == 0)
+ || translucentToplevel;
+
+ if (!useFallback)
+ drawBackgroundDirectly(themeData);
+ else
+ drawBackgroundThruNativeBuffer(themeData);
+
+ painter->restore();
+}
+
+/*! \internal
+ This function draws the theme parts directly to the paintengines HDC.
+ Do not use this if you need to perform other transformations on the
+ resulting data.
+*/
+void QWindowsXPStylePrivate::drawBackgroundDirectly(XPThemeData &themeData)
+{
+ QPainter *painter = themeData.painter;
+ HDC dc = 0;
+ if (themeData.widget) {
+ QBackingStore *backingStore = themeData.widget->backingStore();
+ QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface();
+ dc = static_cast<HDC>(nativeInterface->nativeResourceForBackingStore("getDC", backingStore));
+ }
+
+ QPoint redirectionDelta(int(painter->deviceMatrix().dx()),
+ int(painter->deviceMatrix().dy()));
+ QRect area = themeData.rect.translated(redirectionDelta);
+
+ QRegion sysRgn = painter->paintEngine()->systemClip();
+ if (sysRgn.isEmpty())
+ sysRgn = area;
+ else
+ sysRgn &= area;
+ if (painter->hasClipping())
+ sysRgn &= painter->clipRegion().translated(redirectionDelta);
+ HRGN hrgn = qt_hrgn_from_qregion(sysRgn);
+ SelectClipRgn(dc, hrgn);
+
+#ifdef DEBUG_XP_STYLE
+ printf("---[ DIRECT PAINTING ]------------------> Name(%-10s) Part(%d) State(%d)\n",
+ qPrintable(themeData.name), themeData.partId, themeData.stateId);
+ showProperties(themeData);
+#endif
+
+ RECT drawRECT = themeData.toRECT(area);
+ DTBGOPTS drawOptions;
+ drawOptions.dwSize = sizeof(drawOptions);
+ drawOptions.rcClip = themeData.toRECT(sysRgn.boundingRect());
+ drawOptions.dwFlags = DTBG_CLIPRECT
+ | (themeData.noBorder ? DTBG_OMITBORDER : 0)
+ | (themeData.noContent ? DTBG_OMITCONTENT : 0)
+ | (themeData.mirrorHorizontally ? DTBG_MIRRORDC : 0);
+
+ if (pDrawThemeBackgroundEx != 0) {
+ pDrawThemeBackgroundEx(themeData.handle(), dc, themeData.partId, themeData.stateId, &(drawRECT), &drawOptions);
+ } else {
+ // We are running on a system where the uxtheme.dll does not have
+ // the DrawThemeBackgroundEx function, so we need to clip away
+ // borders or contents manually. All flips and mirrors uses the
+ // fallback implementation
+
+ int borderSize = 0;
+ PROPERTYORIGIN origin = PO_NOTFOUND;
+ pGetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, TMT_BORDERSIZE, &origin);
+ pGetThemeInt(themeData.handle(), themeData.partId, themeData.stateId, TMT_BORDERSIZE, &borderSize);
+
+ // Clip away border region
+ QRegion extraClip = sysRgn;
+ if ((origin == PO_CLASS || origin == PO_PART || origin == PO_STATE) && borderSize > 0) {
+ if (themeData.noBorder) {
+ // extraClip &= area is already done
+ drawRECT = themeData.toRECT(area.adjusted(-borderSize, -borderSize, borderSize, borderSize));
+ }
+
+ // Clip away content region
+ if (themeData.noContent) {
+ QRegion content = area.adjusted(borderSize, borderSize, -borderSize, -borderSize);
+ extraClip ^= content;
+ }
+
+ // Set the clip region, if used..
+ if (themeData.noBorder || themeData.noContent) {
+ DeleteObject(hrgn);
+ hrgn = qt_hrgn_from_qregion(extraClip);
+ SelectClipRgn(dc, hrgn);
+ }
+ }
+
+ pDrawThemeBackground(themeData.handle(), dc, themeData.partId, themeData.stateId, &(drawRECT), &(drawOptions.rcClip));
+ }
+ SelectClipRgn(dc, 0);
+ DeleteObject(hrgn);
+}
+
+/*! \internal
+ This function uses a secondary Native doublebuffer for painting parts.
+ It should only be used when the painteengine doesn't provide a proper
+ HDC for direct painting (e.g. when doing a grabWidget(), painting to
+ other pixmaps etc), or when special transformations are needed (e.g.
+ flips (horizonal mirroring only, vertical are handled by the theme
+ engine).
+*/
+void QWindowsXPStylePrivate::drawBackgroundThruNativeBuffer(XPThemeData &themeData)
+{
+ QPainter *painter = themeData.painter;
+ QRect rect = themeData.rect;
+
+ if ((themeData.rotate + 90) % 180 == 0) { // Catch 90,270,etc.. degree flips.
+ rect = QRect(0, 0, rect.height(), rect.width());
+ }
+ rect.moveTo(0,0);
+ int partId = themeData.partId;
+ int stateId = themeData.stateId;
+ int w = rect.width();
+ int h = rect.height();
+
+ // Values initialized later, either from cached values, or from function calls
+ AlphaChannelType alphaType = UnknownAlpha;
+ bool stateHasData = true; // We assume so;
+ bool hasAlpha = false;
+ bool partIsTransparent;
+ bool inspectData;
+ bool potentialInvalidAlpha;
+
+ QString pixmapCacheKey = QString::fromLatin1("$qt_xp_%1p%2s%3s%4b%5c%6w%7h").arg(themeData.name)
+ .arg(partId).arg(stateId).arg(!themeData.noBorder).arg(!themeData.noContent)
+ .arg(w).arg(h);
+ QPixmap cachedPixmap;
+ ThemeMapKey key(themeData);
+ ThemeMapData data = alphaCache.value(key);
+
+ bool haveCachedPixmap = false;
+ bool isCached = data.dataValid;
+ if (isCached) {
+ if (!(stateHasData = data.hasAnyData))
+ return; // Cached NOOP
+ inspectData = data.wasAlphaSwapped;
+ partIsTransparent = data.partIsTransparent;
+ hasAlpha = data.hasAlphaChannel;
+ alphaType = data.alphaType;
+ potentialInvalidAlpha = data.hadInvalidAlpha;
+
+ haveCachedPixmap = QPixmapCache::find(pixmapCacheKey, cachedPixmap);
+
+#ifdef DEBUG_XP_STYLE
+ char buf[25];
+ ::sprintf(buf, "+ Pixmap(%3d, %3d) ]", w, h);
+ printf("---[ CACHED %s--------> Name(%-10s) Part(%d) State(%d)\n",
+ haveCachedPixmap ? buf : "]-------------------",
+ qPrintable(themeData.name), themeData.partId, themeData.stateId);
+#endif
+ } else {
+ // Not cached, so get values from Theme Engine
+ BOOL tmt_borderonly = false;
+ COLORREF tmt_transparentcolor = 0x0;
+ PROPERTYORIGIN proporigin = PO_NOTFOUND;
+ pGetThemeBool(themeData.handle(), themeData.partId, themeData.stateId, TMT_BORDERONLY, &tmt_borderonly);
+ pGetThemeColor(themeData.handle(), themeData.partId, themeData.stateId, TMT_TRANSPARENTCOLOR, &tmt_transparentcolor);
+ pGetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, TMT_CAPTIONMARGINS, &proporigin);
+ inspectData = (tmt_transparentcolor != 0 || tmt_borderonly || proporigin == PO_PART || proporigin == PO_STATE);
+
+ // ### This is a vista-specific workaround for broken alpha in titlebar pixmaps
+ if ((QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)) {
+ if (themeData.partId == WP_CAPTION || themeData.partId == WP_SMALLCAPTION)
+ inspectData = false;
+ }
+
+ partIsTransparent = isTransparent(themeData);
+
+ potentialInvalidAlpha = false;
+ pGetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, TMT_GLYPHTYPE, &proporigin);
+ if (proporigin == PO_PART || proporigin == PO_STATE) {
+ int tmt_glyphtype = GT_NONE;
+ pGetThemeEnumValue(themeData.handle(), themeData.partId, themeData.stateId, TMT_GLYPHTYPE, &tmt_glyphtype);
+ potentialInvalidAlpha = partIsTransparent && !inspectData && tmt_glyphtype == GT_IMAGEGLYPH;
+ }
+
+#ifdef DEBUG_XP_STYLE
+ printf("---[ NOT CACHED ]-----------------------> Name(%-10s) Part(%d) State(%d)\n",
+ qPrintable(themeData.name), themeData.partId, themeData.stateId);
+ printf("-->partIsTransparen = %d\n", partIsTransparent);
+ printf("-->inspectData = %d\n", inspectData);
+ printf("-->potentialInvalidAlpha = %d\n", potentialInvalidAlpha);
+ showProperties(themeData);
+#endif
+ }
+ bool wasAlphaSwapped = false;
+ bool wasAlphaFixed = false;
+
+ // OLD PSDK Workaround ------------------------------------------------------------------------
+ // See if we need extra clipping for the older PSDK, which does
+ // not have a DrawThemeBackgroundEx function for DTGB_OMITBORDER
+ // and DTGB_OMITCONTENT
+ bool addBorderContentClipping = false;
+ QRegion extraClip;
+ QRect area = rect;
+ if (themeData.noBorder || themeData.noContent) {
+ extraClip = area;
+ // We are running on a system where the uxtheme.dll does not have
+ // the DrawThemeBackgroundEx function, so we need to clip away
+ // borders or contents manually.
+
+ int borderSize = 0;
+ PROPERTYORIGIN origin = PO_NOTFOUND;
+ pGetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, TMT_BORDERSIZE, &origin);
+ pGetThemeInt(themeData.handle(), themeData.partId, themeData.stateId, TMT_BORDERSIZE, &borderSize);
+
+ // Clip away border region
+ if ((origin == PO_CLASS || origin == PO_PART || origin == PO_STATE) && borderSize > 0) {
+ if (themeData.noBorder) {
+ extraClip &= area;
+ area = area.adjusted(-borderSize, -borderSize, borderSize, borderSize);
+ }
+
+ // Clip away content region
+ if (themeData.noContent) {
+ QRegion content = area.adjusted(borderSize, borderSize, -borderSize, -borderSize);
+ extraClip ^= content;
+ }
+ }
+ addBorderContentClipping = (themeData.noBorder | themeData.noContent);
+ }
+
+ QImage img;
+ if (!haveCachedPixmap) { // If the pixmap is not cached, generate it! -------------------------
+ buffer(w, h); // Ensure a buffer of at least (w, h) in size
+ HDC dc = bufferHDC();
+
+ // Clear the buffer
+ if (alphaType != NoAlpha) {
+ // Consider have separate "memset" function for small chunks for more speedup
+ memset(bufferPixels, inspectData ? 0xFF : 0x00, bufferW * h * 4);
+ }
+
+ // Difference between area and rect
+ int dx = area.x() - rect.x();
+ int dy = area.y() - rect.y();
+ int dr = area.right() - rect.right();
+ int db = area.bottom() - rect.bottom();
+
+ // Adjust so painting rect starts from Origo
+ rect.moveTo(0,0);
+ area.moveTo(dx,dy);
+ DTBGOPTS drawOptions;
+ drawOptions.dwSize = sizeof(drawOptions);
+ drawOptions.rcClip = themeData.toRECT(rect);
+ drawOptions.dwFlags = DTBG_CLIPRECT
+ | (themeData.noBorder ? DTBG_OMITBORDER : 0)
+ | (themeData.noContent ? DTBG_OMITCONTENT : 0);
+
+ // Drawing the part into the backing store
+ if (pDrawThemeBackgroundEx != 0) {
+ RECT rect(themeData.toRECT(area));
+ pDrawThemeBackgroundEx(themeData.handle(), dc, themeData.partId, themeData.stateId, &rect, &drawOptions);
+ } else {
+ // Set the clip region, if used..
+ if (addBorderContentClipping) {
+ HRGN hrgn = qt_hrgn_from_qregion(extraClip);
+ SelectClipRgn(dc, hrgn);
+ // Compensate for the noBorder area difference (noContent has the same area)
+ drawOptions.rcClip = themeData.toRECT(rect.adjusted(dx, dy, dr, db));
+ DeleteObject(hrgn);
+ }
+
+ pDrawThemeBackground(themeData.handle(), dc, themeData.partId, themeData.stateId, &(drawOptions.rcClip), 0);
+
+ if (addBorderContentClipping)
+ SelectClipRgn(dc, 0);
+ }
+
+ // If not cached, analyze the buffer data to figure
+ // out alpha type, and if it contains data
+ if (!isCached) {
+ if (inspectData)
+ stateHasData = hasAnyData(rect);
+ // SHORTCUT: If the part's state has no data, cache it for NOOP later
+ if (!stateHasData) {
+ memset(&data, 0, sizeof(data));
+ data.dataValid = true;
+ alphaCache.insert(key, data);
+ return;
+ }
+ hasAlpha = hasAlphaChannel(rect);
+ if (!hasAlpha && partIsTransparent)
+ potentialInvalidAlpha = true;
+#if defined(DEBUG_XP_STYLE) && 1
+ dumpNativeDIB(w, h);
+#endif
+ }
+
+ // Swap alpha values, if needed
+ if (inspectData)
+ wasAlphaSwapped = swapAlphaChannel(rect);
+
+ // Fix alpha values, if needed
+ if (potentialInvalidAlpha)
+ wasAlphaFixed = fixAlphaChannel(rect);
+
+ QImage::Format format;
+ if ((partIsTransparent && !wasAlphaSwapped) || (!partIsTransparent && hasAlpha)) {
+ format = QImage::Format_ARGB32_Premultiplied;
+ alphaType = RealAlpha;
+ } else if (wasAlphaSwapped) {
+ format = QImage::Format_ARGB32_Premultiplied;
+ alphaType = MaskAlpha;
+ } else {
+ format = QImage::Format_RGB32;
+ // The image data we got from the theme engine does not have any transparency,
+ // thus the alpha channel is set to 0.
+ // However, Format_RGB32 requires the alpha part to be set to 0xff, thus
+ // we must flip it from 0x00 to 0xff
+ swapAlphaChannel(rect, true);
+ alphaType = NoAlpha;
+ }
+#if defined(DEBUG_XP_STYLE) && 1
+ printf("Image format is: %s\n", alphaType == RealAlpha ? "Real Alpha" : alphaType == MaskAlpha ? "Masked Alpha" : "No Alpha");
+#endif
+ img = QImage(bufferPixels, bufferW, bufferH, format);
+ }
+
+ // Blitting backing store
+ bool useRegion = partIsTransparent && !hasAlpha && !wasAlphaSwapped;
+
+ QRegion newRegion;
+ QRegion oldRegion;
+ if (useRegion) {
+ newRegion = region(themeData);
+ oldRegion = painter->clipRegion();
+ painter->setClipRegion(newRegion);
+#if defined(DEBUG_XP_STYLE) && 0
+ printf("Using region:\n");
+ QVector<QRect> rects = newRegion.rects();
+ for (int i = 0; i < rects.count(); ++i) {
+ const QRect &r = rects.at(i);
+ printf(" (%d, %d, %d, %d)\n", r.x(), r.y(), r.right(), r.bottom());
+ }
+#endif
+ }
+
+ if (addBorderContentClipping)
+ painter->setClipRegion(extraClip, Qt::IntersectClip);
+
+ if (!themeData.mirrorHorizontally && !themeData.mirrorVertically && !themeData.rotate) {
+ if (!haveCachedPixmap)
+ painter->drawImage(themeData.rect, img, rect);
+ else
+ painter->drawPixmap(themeData.rect, cachedPixmap);
+ } else {
+ // This is _slow_!
+ // Make a copy containing only the necessary data, and mirror
+ // on all wanted axes. Then draw the copy.
+ // If cached, the normal pixmap is cached, instead of caching
+ // all possible orientations for each part and state.
+ QImage imgCopy;
+ if (!haveCachedPixmap)
+ imgCopy = img.copy(rect);
+ else
+ imgCopy = cachedPixmap.toImage();
+
+ if (themeData.rotate) {
+ QMatrix rotMatrix;
+ rotMatrix.rotate(themeData.rotate);
+ imgCopy = imgCopy.transformed(rotMatrix);
+ }
+ if (themeData.mirrorHorizontally || themeData.mirrorVertically) {
+ imgCopy = imgCopy.mirrored(themeData.mirrorHorizontally, themeData.mirrorVertically);
+ }
+ painter->drawImage(themeData.rect,
+ imgCopy);
+ }
+
+ if (useRegion || addBorderContentClipping) {
+ if (oldRegion.isEmpty())
+ painter->setClipping(false);
+ else
+ painter->setClipRegion(oldRegion);
+ }
+
+ // Cache the pixmap to avoid expensive swapAlphaChannel() calls
+ if (!haveCachedPixmap && w && h) {
+ QPixmap pix = QPixmap::fromImage(img).copy(rect);
+ QPixmapCache::insert(pixmapCacheKey, pix);
+#ifdef DEBUG_XP_STYLE
+ printf("+++Adding pixmap to cache, size(%d, %d), wasAlphaSwapped(%d), wasAlphaFixed(%d), name(%s)\n",
+ w, h, wasAlphaSwapped, wasAlphaFixed, qPrintable(pixmapCacheKey));
+#endif
+ }
+
+ // Add to theme part cache
+ if (!isCached) {
+ memset(&data, 0, sizeof(data));
+ data.dataValid = true;
+ data.partIsTransparent = partIsTransparent;
+ data.alphaType = alphaType;
+ data.hasAlphaChannel = hasAlpha;
+ data.hasAnyData = stateHasData;
+ data.wasAlphaSwapped = wasAlphaSwapped;
+ data.hadInvalidAlpha = wasAlphaFixed;
+ alphaCache.insert(key, data);
+ }
+}
+
+
+// ------------------------------------------------------------------------------------------------
+
+/*!
+ \class QWindowsXPStyle
+ \brief The QWindowsXPStyle class provides a Microsoft Windows XP-like look and feel.
+
+ \ingroup appearance
+
+ \warning This style is only available on the Windows XP platform
+ because it makes use of Windows XP's style engine.
+
+ Most of the functions are documented in the base classes
+ QWindowsStyle, QCommonStyle, and QStyle, but the
+ QWindowsXPStyle overloads of drawComplexControl(), drawControl(),
+ drawControlMask(), drawPrimitive(), proxy()->subControlRect(), and
+ sizeFromContents(), are documented here.
+
+ \img qwindowsxpstyle.png
+ \sa QMacStyle, QWindowsStyle, QPlastiqueStyle, QCDEStyle, QMotifStyle
+*/
+
+/*!
+ Constructs a QWindowsStyle
+*/
+QWindowsXPStyle::QWindowsXPStyle()
+ : QWindowsStyle(*new QWindowsXPStylePrivate)
+{
+}
+
+/*!
+ Destroys the style.
+*/
+QWindowsXPStyle::~QWindowsXPStyle()
+{
+}
+
+/*! \reimp */
+void QWindowsXPStyle::unpolish(QApplication *app)
+{
+ QWindowsStyle::unpolish(app);
+}
+
+/*! \reimp */
+void QWindowsXPStyle::polish(QApplication *app)
+{
+ QWindowsStyle::polish(app);
+ if (!QWindowsXPStylePrivate::useXP())
+ return;
+}
+
+/*! \reimp */
+void QWindowsXPStyle::polish(QWidget *widget)
+{
+ QWindowsStyle::polish(widget);
+ if (!QWindowsXPStylePrivate::useXP())
+ return;
+
+ if (qobject_cast<QAbstractButton*>(widget)
+ || qobject_cast<QToolButton*>(widget)
+ || qobject_cast<QTabBar*>(widget)
+#ifndef QT_NO_COMBOBOX
+ || qobject_cast<QComboBox*>(widget)
+#endif // QT_NO_COMBOBOX
+ || qobject_cast<QScrollBar*>(widget)
+ || qobject_cast<QSlider*>(widget)
+ || qobject_cast<QHeaderView*>(widget)
+#ifndef QT_NO_SPINBOX
+ || qobject_cast<QAbstractSpinBox*>(widget)
+ || qobject_cast<QSpinBox*>(widget)
+#endif // QT_NO_SPINBOX
+ || widget->inherits("QWorkspaceChild")
+ || widget->inherits("Q3TitleBar"))
+ widget->setAttribute(Qt::WA_Hover);
+
+#ifndef QT_NO_RUBBERBAND
+ if (qobject_cast<QRubberBand*>(widget)) {
+ widget->setWindowOpacity(0.6);
+ }
+#endif
+ if (qobject_cast<QStackedWidget*>(widget) &&
+ qobject_cast<QTabWidget*>(widget->parent()))
+ widget->parentWidget()->setAttribute(Qt::WA_ContentsPropagated);
+
+ Q_D(QWindowsXPStyle);
+ if (!d->hasInitColors) {
+ // Get text color for group box labels
+ COLORREF cref;
+ XPThemeData theme(0, 0, QLatin1String("BUTTON"), 0, 0);
+ pGetThemeColor(theme.handle(), BP_GROUPBOX, GBS_NORMAL, TMT_TEXTCOLOR, &cref);
+ d->groupBoxTextColor = qRgb(GetRValue(cref), GetGValue(cref), GetBValue(cref));
+ pGetThemeColor(theme.handle(), BP_GROUPBOX, GBS_DISABLED, TMT_TEXTCOLOR, &cref);
+ d->groupBoxTextColorDisabled = qRgb(GetRValue(cref), GetGValue(cref), GetBValue(cref));
+ // Where does this color come from?
+ //pGetThemeColor(theme.handle(), TKP_TICS, TSS_NORMAL, TMT_COLOR, &cref);
+ d->sliderTickColor = qRgb(165, 162, 148);
+ d->hasInitColors = true;
+ }
+}
+
+/*! \reimp */
+void QWindowsXPStyle::polish(QPalette &pal)
+{
+ QWindowsStyle::polish(pal);
+ pal.setBrush(QPalette::AlternateBase, pal.base().color().darker(110));
+}
+
+/*! \reimp */
+void QWindowsXPStyle::unpolish(QWidget *widget)
+{
+#ifndef QT_NO_RUBBERBAND
+ if (qobject_cast<QRubberBand*>(widget)) {
+ widget->setWindowOpacity(1.0);
+ }
+#endif
+ Q_D(QWindowsXPStyle);
+ // Unpolish of widgets is the first thing that
+ // happens when a theme changes, or the theme
+ // engine is turned off. So we detect it here.
+ bool oldState = QWindowsXPStylePrivate::useXP();
+ bool newState = QWindowsXPStylePrivate::useXP(true);
+ if ((oldState != newState) && newState) {
+ d->cleanup(true);
+ d->init(true);
+ } else {
+ // Cleanup handle map, if just changing style,
+ // or turning it on. In both cases the values
+ // already in the map might be old (other style).
+ d->cleanupHandleMap();
+ }
+ if (qobject_cast<QAbstractButton*>(widget)
+ || qobject_cast<QToolButton*>(widget)
+ || qobject_cast<QTabBar*>(widget)
+#ifndef QT_NO_COMBOBOX
+ || qobject_cast<QComboBox*>(widget)
+#endif // QT_NO_COMBOBOX
+ || qobject_cast<QScrollBar*>(widget)
+ || qobject_cast<QSlider*>(widget)
+ || qobject_cast<QHeaderView*>(widget)
+#ifndef QT_NO_SPINBOX
+ || qobject_cast<QAbstractSpinBox*>(widget)
+ || qobject_cast<QSpinBox*>(widget)
+#endif // QT_NO_SPINBOX
+ || widget->inherits("QWorkspaceChild")
+ || widget->inherits("Q3TitleBar"))
+ widget->setAttribute(Qt::WA_Hover, false);
+ QWindowsStyle::unpolish(widget);
+}
+
+/*! \reimp */
+QRect QWindowsXPStyle::subElementRect(SubElement sr, const QStyleOption *option, const QWidget *widget) const
+{
+ if (!QWindowsXPStylePrivate::useXP()) {
+ return QWindowsStyle::subElementRect(sr, option, widget);
+ }
+
+ QRect rect(option->rect);
+ switch(sr) {
+ case SE_DockWidgetCloseButton:
+ case SE_DockWidgetFloatButton:
+ rect = QWindowsStyle::subElementRect(sr, option, widget);
+ return rect.translated(0, 1);
+ break;
+ case SE_TabWidgetTabContents:
+ if (qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(option))
+ {
+ rect = QWindowsStyle::subElementRect(sr, option, widget);
+ if (sr == SE_TabWidgetTabContents) {
+ if (const QTabWidget *tabWidget = qobject_cast<const QTabWidget *>(widget)) {
+ if (tabWidget->documentMode())
+ break;
+ }
+
+ rect.adjust(0, 0, -2, -2);
+ }
+ }
+ break;
+ case SE_TabWidgetTabBar: {
+ rect = QWindowsStyle::subElementRect(sr, option, widget);
+ const QStyleOptionTabWidgetFrame *twfOption =
+ qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(option);
+ if (twfOption && twfOption->direction == Qt::RightToLeft
+ && (twfOption->shape == QTabBar::RoundedNorth
+ || twfOption->shape == QTabBar::RoundedSouth))
+ {
+ QStyleOptionTab otherOption;
+ otherOption.shape = (twfOption->shape == QTabBar::RoundedNorth
+ ? QTabBar::RoundedEast : QTabBar::RoundedSouth);
+ int overlap = proxy()->pixelMetric(PM_TabBarBaseOverlap, &otherOption, widget);
+ int borderThickness = proxy()->pixelMetric(PM_DefaultFrameWidth, option, widget);
+ rect.adjust(-overlap + borderThickness, 0, -overlap + borderThickness, 0);
+ }
+ break;}
+
+ case SE_PushButtonContents:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
+ MARGINS borderSize;
+ if (widget) {
+ XPThemeData buttontheme(widget, 0, QLatin1String("Button"));
+ HTHEME theme = buttontheme.handle();
+ if (theme) {
+ int stateId;
+ if (!(option->state & State_Enabled))
+ stateId = PBS_DISABLED;
+ else if (option->state & State_Sunken)
+ stateId = PBS_PRESSED;
+ else if (option->state & State_MouseOver)
+ stateId = PBS_HOT;
+ else if (btn->features & QStyleOptionButton::DefaultButton)
+ stateId = PBS_DEFAULTED;
+ else
+ stateId = PBS_NORMAL;
+
+ int border = proxy()->pixelMetric(PM_DefaultFrameWidth, btn, widget);
+ rect = option->rect.adjusted(border, border, -border, -border);
+
+ int result = pGetThemeMargins(theme,
+ NULL,
+ BP_PUSHBUTTON,
+ stateId,
+ TMT_CONTENTMARGINS,
+ NULL,
+ &borderSize);
+
+ if (result == S_OK) {
+ rect.adjust(borderSize.cxLeftWidth, borderSize.cyTopHeight,
+ -borderSize.cxRightWidth, -borderSize.cyBottomHeight);
+ rect = visualRect(option->direction, option->rect, rect);
+ }
+ }
+ }
+ }
+ break;
+ case SE_ProgressBarContents:
+ rect = QCommonStyle::subElementRect(SE_ProgressBarGroove, option, widget);
+ if (option->state & QStyle::State_Horizontal)
+ rect.adjust(4, 3, -4, -3);
+ else
+ rect.adjust(3, 2, -3, -2);
+ break;
+ default:
+ rect = QWindowsStyle::subElementRect(sr, option, widget);
+ }
+ return rect;
+}
+
+/*!
+ \reimp
+*/
+void QWindowsXPStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *option, QPainter *p,
+ const QWidget *widget) const
+{
+ QWindowsXPStylePrivate *d = const_cast<QWindowsXPStylePrivate*>(d_func());
+
+ if (!QWindowsXPStylePrivate::useXP()) {
+ QWindowsStyle::drawPrimitive(pe, option, p, widget);
+ return;
+ }
+
+ QString name;
+ int partId = 0;
+ int stateId = 0;
+ QRect rect = option->rect;
+ State flags = option->state;
+ bool hMirrored = false;
+ bool vMirrored = false;
+ bool noBorder = false;
+ bool noContent = false;
+ int rotate = 0;
+
+ switch (pe) {
+ case PE_FrameTabBarBase:
+ if (const QStyleOptionTabBarBase *tbb
+ = qstyleoption_cast<const QStyleOptionTabBarBase *>(option)) {
+ p->save();
+ switch (tbb->shape) {
+ case QTabBar::RoundedNorth:
+ p->setPen(QPen(tbb->palette.dark(), 0));
+ p->drawLine(tbb->rect.topLeft(), tbb->rect.topRight());
+ break;
+ case QTabBar::RoundedWest:
+ p->setPen(QPen(tbb->palette.dark(), 0));
+ p->drawLine(tbb->rect.left(), tbb->rect.top(), tbb->rect.left(), tbb->rect.bottom());
+ break;
+ case QTabBar::RoundedSouth:
+ p->setPen(QPen(tbb->palette.dark(), 0));
+ p->drawLine(tbb->rect.left(), tbb->rect.top(),
+ tbb->rect.right(), tbb->rect.top());
+ break;
+ case QTabBar::RoundedEast:
+ p->setPen(QPen(tbb->palette.dark(), 0));
+ p->drawLine(tbb->rect.topLeft(), tbb->rect.bottomLeft());
+ break;
+ case QTabBar::TriangularNorth:
+ case QTabBar::TriangularEast:
+ case QTabBar::TriangularWest:
+ case QTabBar::TriangularSouth:
+ p->restore();
+ QWindowsStyle::drawPrimitive(pe, option, p, widget);
+ return;
+ }
+ p->restore();
+ }
+ return;
+ case PE_PanelButtonBevel:
+ name = QLatin1String("BUTTON");
+ partId = BP_PUSHBUTTON;
+ if (!(flags & State_Enabled))
+ stateId = PBS_DISABLED;
+ else if ((flags & State_Sunken) || (flags & State_On))
+ stateId = PBS_PRESSED;
+ else if (flags & State_MouseOver)
+ stateId = PBS_HOT;
+ //else if (flags & State_ButtonDefault)
+ // stateId = PBS_DEFAULTED;
+ else
+ stateId = PBS_NORMAL;
+ break;
+
+ case PE_PanelButtonTool:
+ if (widget && widget->inherits("QDockWidgetTitleButton")) {
+ if (const QWidget *dw = widget->parentWidget())
+ if (dw->isWindow())
+ return;
+ }
+ name = QLatin1String("TOOLBAR");
+ partId = TP_BUTTON;
+ if (!(flags & State_Enabled))
+ stateId = TS_DISABLED;
+ else if (flags & State_Sunken)
+ stateId = TS_PRESSED;
+ else if (flags & State_MouseOver)
+ stateId = flags & State_On ? TS_HOTCHECKED : TS_HOT;
+ else if (flags & State_On)
+ stateId = TS_CHECKED;
+ else if (!(flags & State_AutoRaise))
+ stateId = TS_HOT;
+ else
+ stateId = TS_NORMAL;
+ break;
+
+ case PE_IndicatorButtonDropDown:
+ name = QLatin1String("TOOLBAR");
+ partId = TP_SPLITBUTTONDROPDOWN;
+ if (!(flags & State_Enabled))
+ stateId = TS_DISABLED;
+ else if (flags & State_Sunken)
+ stateId = TS_PRESSED;
+ else if (flags & State_MouseOver)
+ stateId = flags & State_On ? TS_HOTCHECKED : TS_HOT;
+ else if (flags & State_On)
+ stateId = TS_CHECKED;
+ else if (!(flags & State_AutoRaise))
+ stateId = TS_HOT;
+ else
+ stateId = TS_NORMAL;
+ if (option->direction == Qt::RightToLeft)
+ hMirrored = true;
+ break;
+
+ case PE_IndicatorCheckBox:
+ name = QLatin1String("BUTTON");
+ partId = BP_CHECKBOX;
+ if (!(flags & State_Enabled))
+ stateId = CBS_UNCHECKEDDISABLED;
+ else if (flags & State_Sunken)
+ stateId = CBS_UNCHECKEDPRESSED;
+ else if (flags & State_MouseOver)
+ stateId = CBS_UNCHECKEDHOT;
+ else
+ stateId = CBS_UNCHECKEDNORMAL;
+
+ if (flags & State_On)
+ stateId += CBS_CHECKEDNORMAL-1;
+ else if (flags & State_NoChange)
+ stateId += CBS_MIXEDNORMAL-1;
+
+ break;
+
+ case PE_IndicatorRadioButton:
+ name = QLatin1String("BUTTON");
+ partId = BP_RADIOBUTTON;
+ if (!(flags & State_Enabled))
+ stateId = RBS_UNCHECKEDDISABLED;
+ else if (flags & State_Sunken)
+ stateId = RBS_UNCHECKEDPRESSED;
+ else if (flags & State_MouseOver)
+ stateId = RBS_UNCHECKEDHOT;
+ else
+ stateId = RBS_UNCHECKEDNORMAL;
+
+ if (flags & State_On)
+ stateId += RBS_CHECKEDNORMAL-1;
+ break;
+
+ case PE_IndicatorDockWidgetResizeHandle:
+ return;
+
+case PE_Frame:
+ {
+ if (flags & State_Raised)
+ return;
+ name = QLatin1String("LISTVIEW");
+ partId = LVP_LISTGROUP;
+ XPThemeData theme(0, 0, name, partId, 0);
+
+ if (!(flags & State_Enabled))
+ stateId = ETS_DISABLED;
+ else
+ stateId = ETS_NORMAL;
+ int fillType;
+ if (pGetThemeEnumValue(theme.handle(), partId, stateId, TMT_BGTYPE, &fillType) == S_OK) {
+ if (fillType == BT_BORDERFILL) {
+ COLORREF bcRef;
+ pGetThemeColor(theme.handle(), partId, stateId, TMT_BORDERCOLOR, &bcRef);
+ QColor bordercolor(qRgb(GetRValue(bcRef), GetGValue(bcRef), GetBValue(bcRef)));
+ QPen oldPen = p->pen();
+ // int borderSize = 1;
+ // pGetThemeInt(theme.handle(), partId, stateId, TMT_BORDERCOLOR, &borderSize);
+
+ // Inner white border
+ p->setPen(QPen(option->palette.base().color(), 1));
+ p->drawRect(option->rect.adjusted(1, 1, -2, -2));
+ // Outer dark border
+ p->setPen(QPen(bordercolor, 1));
+ p->drawRect(option->rect.adjusted(0, 0, -1, -1));
+ p->setPen(oldPen);
+ return;
+ } else if (fillType == BT_NONE) {
+ return;
+ } else {
+ break;
+ }
+ }
+ }
+ case PE_FrameLineEdit: {
+ // we try to check if this lineedit is a delegate on a QAbstractItemView-derived class.
+ QWidget *parentWidget = 0;
+ if (widget)
+ parentWidget = widget->parentWidget();
+ if (parentWidget)
+ parentWidget = parentWidget->parentWidget();
+ if (widget && widget->inherits("QLineEdit")
+ && parentWidget && parentWidget->inherits("QAbstractItemView")) {
+ QPen oldPen = p->pen();
+ // Inner white border
+ p->setPen(QPen(option->palette.base().color(), 1));
+ p->drawRect(option->rect.adjusted(1, 1, -2, -2));
+ // Outer dark border
+ p->setPen(QPen(option->palette.shadow().color(), 1));
+ p->drawRect(option->rect.adjusted(0, 0, -1, -1));
+ p->setPen(oldPen);
+ return;
+ } else if (qstyleoption_cast<const QStyleOptionFrame *>(option)) {
+ name = QLatin1String("EDIT");
+ partId = EP_EDITTEXT;
+ noContent = true;
+ if (!(flags & State_Enabled))
+ stateId = ETS_DISABLED;
+ else
+ stateId = ETS_NORMAL;
+ }
+ break;
+ }
+
+ case PE_PanelLineEdit:
+ if (const QStyleOptionFrame *panel = qstyleoption_cast<const QStyleOptionFrame *>(option)) {
+ name = QLatin1String("EDIT");
+ partId = EP_EDITTEXT;
+ noBorder = true;
+ QBrush bg;
+ bool usePalette = false;
+ bool isEnabled = flags & State_Enabled;
+ uint resolve_mask = panel->palette.resolve();
+
+#ifndef QT_NO_SPINBOX
+ //Since spin box includes a line edit we need to resolve the palette on the spin box instead
+ if (widget) {
+ if (QAbstractSpinBox *spinbox = qobject_cast<QAbstractSpinBox*>(widget->parentWidget()))
+ resolve_mask = spinbox->palette().resolve();
+ }
+#endif // QT_NO_SPINBOX
+ if (resolve_mask & (1 << QPalette::Base)) {
+ // Base color is set for this widget, so use it
+ bg = panel->palette.brush(QPalette::Base);
+ usePalette = true;
+ }
+
+ stateId = isEnabled ? ETS_NORMAL : ETS_DISABLED;
+
+ if (usePalette) {
+ p->fillRect(panel->rect, bg);
+ } else {
+ XPThemeData theme(0, p, name, partId, stateId, rect);
+ if (!theme.isValid()) {
+ QWindowsStyle::drawPrimitive(pe, option, p, widget);
+ return;
+ }
+ int bgType;
+ pGetThemeEnumValue( theme.handle(),
+ partId,
+ stateId,
+ TMT_BGTYPE,
+ &bgType);
+ if( bgType == BT_IMAGEFILE ) {
+ theme.mirrorHorizontally = hMirrored;
+ theme.mirrorVertically = vMirrored;
+ theme.noBorder = noBorder;
+ theme.noContent = noContent;
+ theme.rotate = rotate;
+ d->drawBackground(theme);
+ } else {
+ QBrush fillColor = option->palette.brush(QPalette::Base);
+
+ if (!isEnabled) {
+ PROPERTYORIGIN origin = PO_NOTFOUND;
+ pGetThemePropertyOrigin(theme.handle(), theme.partId, theme.stateId, TMT_FILLCOLOR, &origin);
+ // Use only if the fill property comes from our part
+ if ((origin == PO_PART || origin == PO_STATE)) {
+ COLORREF bgRef;
+ pGetThemeColor(theme.handle(), partId, stateId, TMT_FILLCOLOR, &bgRef);
+ fillColor = QBrush(qRgb(GetRValue(bgRef), GetGValue(bgRef), GetBValue(bgRef)));
+ }
+ }
+ p->fillRect(option->rect, fillColor);
+ }
+ }
+
+ if (panel->lineWidth > 0)
+ proxy()->drawPrimitive(PE_FrameLineEdit, panel, p, widget);
+ return;
+ }
+ break;
+
+ case PE_FrameTabWidget:
+ if (const QStyleOptionTabWidgetFrame *tab = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(option))
+ {
+ name = QLatin1String("TAB");
+ partId = TABP_PANE;
+
+ if (widget) {
+ bool useGradient = true;
+ const int maxlength = 256;
+ wchar_t themeFileName[maxlength];
+ wchar_t themeColor[maxlength];
+ // Due to a a scaling issue with the XP Silver theme, tab gradients are not used with it
+ if (pGetCurrentThemeName(themeFileName, maxlength, themeColor, maxlength, NULL, 0) == S_OK) {
+ wchar_t *offset = 0;
+ if ((offset = wcsrchr(themeFileName, QChar(QLatin1Char('\\')).unicode())) != NULL) {
+ offset++;
+ if (!lstrcmp(offset, L"Luna.msstyles") && !lstrcmp(offset, L"Metallic")) {
+ useGradient = false;
+ }
+ }
+ }
+ // This should work, but currently there's an error in the ::drawBackgroundDirectly()
+ // code, when using the HDC directly..
+ if (useGradient) {
+ QStyleOptionTabWidgetFrameV2 frameOpt = *tab;
+ frameOpt.rect = widget->rect();
+ QRect contentsRect = subElementRect(SE_TabWidgetTabContents, &frameOpt, widget);
+ QRegion reg = option->rect;
+ reg -= contentsRect;
+ p->setClipRegion(reg);
+ XPThemeData theme(widget, p, name, partId, stateId, rect);
+ theme.mirrorHorizontally = hMirrored;
+ theme.mirrorVertically = vMirrored;
+ d->drawBackground(theme);
+ p->setClipRect(contentsRect);
+ partId = TABP_BODY;
+ }
+ }
+ switch (tab->shape) {
+ case QTabBar::RoundedNorth:
+ case QTabBar::TriangularNorth:
+ break;
+ case QTabBar::RoundedSouth:
+ case QTabBar::TriangularSouth:
+ vMirrored = true;
+ break;
+ case QTabBar::RoundedEast:
+ case QTabBar::TriangularEast:
+ rotate = 90;
+ break;
+ case QTabBar::RoundedWest:
+ case QTabBar::TriangularWest:
+ rotate = 90;
+ hMirrored = true;
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case PE_FrameMenu:
+ p->save();
+ p->setPen(option->palette.dark().color());
+ p->drawRect(rect.adjusted(0, 0, -1, -1));
+ p->restore();
+ return;
+
+ case PE_PanelMenuBar:
+ break;
+
+ case PE_FrameDockWidget:
+ if (const QStyleOptionFrame *frm = qstyleoption_cast<const QStyleOptionFrame *>(option))
+ {
+ name = QLatin1String("WINDOW");
+ if (flags & State_Active)
+ stateId = FS_ACTIVE;
+ else
+ stateId = FS_INACTIVE;
+
+ int fwidth = proxy()->pixelMetric(PM_DockWidgetFrameWidth, frm, widget);
+
+ XPThemeData theme(widget, p, name, 0, stateId);
+ if (!theme.isValid())
+ break;
+ theme.rect = QRect(frm->rect.x(), frm->rect.y(), frm->rect.x()+fwidth, frm->rect.height()-fwidth); theme.partId = WP_SMALLFRAMELEFT;
+ d->drawBackground(theme);
+ theme.rect = QRect(frm->rect.width()-fwidth, frm->rect.y(), fwidth, frm->rect.height()-fwidth);
+ theme.partId = WP_SMALLFRAMERIGHT;
+ d->drawBackground(theme);
+ theme.rect = QRect(frm->rect.x(), frm->rect.bottom()-fwidth+1, frm->rect.width(), fwidth);
+ theme.partId = WP_SMALLFRAMEBOTTOM;
+ d->drawBackground(theme);
+ return;
+ }
+ break;
+
+ case PE_IndicatorHeaderArrow:
+ {
+#if 0 // XP theme engine doesn't know about this :(
+ name = QLatin1String("HEADER");
+ partId = HP_HEADERSORTARROW;
+ if (flags & State_Down)
+ stateId = HSAS_SORTEDDOWN;
+ else
+ stateId = HSAS_SORTEDUP;
+#else
+ if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
+ p->save();
+ p->setPen(option->palette.dark().color());
+ p->translate(0, option->rect.height()/2 - 4);
+ if (header->sortIndicator & QStyleOptionHeader::SortUp) { // invert logic to follow Windows style guide
+ p->drawLine(option->rect.x(), option->rect.y(), option->rect.x()+8, option->rect.y());
+ p->drawLine(option->rect.x()+1, option->rect.y()+1, option->rect.x()+7, option->rect.y()+1);
+ p->drawLine(option->rect.x()+2, option->rect.y()+2, option->rect.x()+6, option->rect.y()+2);
+ p->drawLine(option->rect.x()+3, option->rect.y()+3, option->rect.x()+5, option->rect.y()+3);
+ p->drawPoint(option->rect.x()+4, option->rect.y()+4);
+ } else if(header->sortIndicator & QStyleOptionHeader::SortDown) {
+ p->drawLine(option->rect.x(), option->rect.y()+4, option->rect.x()+8, option->rect.y()+4);
+ p->drawLine(option->rect.x()+1, option->rect.y()+3, option->rect.x()+7, option->rect.y()+3);
+ p->drawLine(option->rect.x()+2, option->rect.y()+2, option->rect.x()+6, option->rect.y()+2);
+ p->drawLine(option->rect.x()+3, option->rect.y()+1, option->rect.x()+5, option->rect.y()+1);
+ p->drawPoint(option->rect.x()+4, option->rect.y());
+ }
+ p->restore();
+ return;
+ }
+#endif
+ }
+ break;
+
+ case PE_FrameStatusBarItem:
+ name = QLatin1String("STATUS");
+ partId = SP_PANE;
+ break;
+
+ case PE_FrameGroupBox:
+ name = QLatin1String("BUTTON");
+ partId = BP_GROUPBOX;
+ if (!(flags & State_Enabled))
+ stateId = GBS_DISABLED;
+ else
+ stateId = GBS_NORMAL;
+ if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(option)) {
+ const QStyleOptionFrameV2 *frame2 = qstyleoption_cast<const QStyleOptionFrameV2 *>(option);
+ if (frame2->features & QStyleOptionFrameV2::Flat) {
+ // Windows XP does not have a theme part for a flat GroupBox, paint it with the windows style
+ QRect fr = frame->rect;
+ QPoint p1(fr.x(), fr.y() + 1);
+ QPoint p2(fr.x() + fr.width(), p1.y() + 1);
+ rect = QRect(p1, p2);
+ name = QLatin1String("");
+ }
+ }
+ break;
+
+ case PE_IndicatorProgressChunk:
+ {
+ Qt::Orientation orient = Qt::Horizontal;
+ bool inverted = false;
+ if (const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option)) {
+ orient = pb2->orientation;
+ if (pb2->invertedAppearance)
+ inverted = true;
+ }
+ if (orient == Qt::Horizontal) {
+ partId = PP_CHUNK;
+ rect = QRect(option->rect.x(), option->rect.y(), option->rect.width(), option->rect.height() );
+ if (inverted && option->direction == Qt::LeftToRight)
+ hMirrored = true;
+ } else {
+ partId = PP_CHUNKVERT;
+ rect = QRect(option->rect.x(), option->rect.y(), option->rect.width(), option->rect.height());
+ }
+ name = QLatin1String("PROGRESS");
+ stateId = 1;
+ }
+ break;
+
+ case PE_Q3DockWindowSeparator:
+ name = QLatin1String("TOOLBAR");
+ if (flags & State_Horizontal)
+ partId = TP_SEPARATOR;
+ else
+ partId = TP_SEPARATORVERT;
+ break;
+
+ case PE_FrameWindow:
+ if (const QStyleOptionFrame *frm = qstyleoption_cast<const QStyleOptionFrame *>(option))
+ {
+ name = QLatin1String("WINDOW");
+ if (flags & State_Active)
+ stateId = FS_ACTIVE;
+ else
+ stateId = FS_INACTIVE;
+
+ int fwidth = frm->lineWidth + frm->midLineWidth;
+
+ XPThemeData theme(0, p, name, 0, stateId);
+ if (!theme.isValid())
+ break;
+
+ theme.rect = QRect(option->rect.x(), option->rect.y()+fwidth, option->rect.x()+fwidth, option->rect.height()-fwidth);
+ theme.partId = WP_FRAMELEFT;
+ d->drawBackground(theme);
+ theme.rect = QRect(option->rect.width()-fwidth, option->rect.y()+fwidth, fwidth, option->rect.height()-fwidth);
+ theme.partId = WP_FRAMERIGHT;
+ d->drawBackground(theme);
+ theme.rect = QRect(option->rect.x(), option->rect.height()-fwidth, option->rect.width(), fwidth);
+ theme.partId = WP_FRAMEBOTTOM;
+ d->drawBackground(theme);
+ theme.rect = QRect(option->rect.x(), option->rect.y(), option->rect.width(), option->rect.y()+fwidth);
+ theme.partId = WP_CAPTION;
+ d->drawBackground(theme);
+ return;
+ }
+ break;
+
+ case PE_IndicatorBranch:
+ {
+ static const int decoration_size = 9;
+ int mid_h = option->rect.x() + option->rect.width() / 2;
+ int mid_v = option->rect.y() + option->rect.height() / 2;
+ int bef_h = mid_h;
+ int bef_v = mid_v;
+ int aft_h = mid_h;
+ int aft_v = mid_v;
+ QBrush brush(option->palette.dark().color(), Qt::Dense4Pattern);
+ if (option->state & State_Item) {
+ if (option->direction == Qt::RightToLeft)
+ p->fillRect(option->rect.left(), mid_v, bef_h - option->rect.left(), 1, brush);
+ else
+ p->fillRect(aft_h, mid_v, option->rect.right() - aft_h + 1, 1, brush);
+ }
+ if (option->state & State_Sibling)
+ p->fillRect(mid_h, aft_v, 1, option->rect.bottom() - aft_v + 1, brush);
+ if (option->state & (State_Open | State_Children | State_Item | State_Sibling))
+ p->fillRect(mid_h, option->rect.y(), 1, bef_v - option->rect.y(), brush);
+ if (option->state & State_Children) {
+ int delta = decoration_size / 2;
+ bef_h -= delta;
+ bef_v -= delta;
+ aft_h += delta;
+ aft_v += delta;
+ XPThemeData theme(0, p, QLatin1String("TREEVIEW"));
+ theme.rect = QRect(bef_h, bef_v, decoration_size, decoration_size);
+ theme.partId = TVP_GLYPH;
+ theme.stateId = flags & QStyle::State_Open ? GLPS_OPENED : GLPS_CLOSED;
+ d->drawBackground(theme);
+ }
+ }
+ return;
+
+ case PE_IndicatorToolBarSeparator:
+ if (option->rect.height() < 3) {
+ // XP style requires a few pixels for the separator
+ // to be visible.
+ QWindowsStyle::drawPrimitive(pe, option, p, widget);
+ return;
+ }
+ name = QLatin1String("TOOLBAR");
+ partId = TP_SEPARATOR;
+
+ if (option->state & State_Horizontal)
+ partId = TP_SEPARATOR;
+ else
+ partId = TP_SEPARATORVERT;
+
+ break;
+
+ case PE_IndicatorToolBarHandle:
+
+ name = QLatin1String("REBAR");
+ partId = RP_GRIPPER;
+ if (option->state & State_Horizontal) {
+ partId = RP_GRIPPER;
+ rect.adjust(0, 0, -2, 0);
+ }
+ else {
+ partId = RP_GRIPPERVERT;
+ rect.adjust(0, 0, 0, -2);
+ }
+ break;
+
+ case PE_IndicatorItemViewItemCheck: {
+ QStyleOptionButton button;
+ button.QStyleOption::operator=(*option);
+ button.state &= ~State_MouseOver;
+ proxy()->drawPrimitive(PE_IndicatorCheckBox, &button, p, widget);
+ return;
+ }
+
+ default:
+ break;
+ }
+
+ XPThemeData theme(0, p, name, partId, stateId, rect);
+ if (!theme.isValid()) {
+ QWindowsStyle::drawPrimitive(pe, option, p, widget);
+ return;
+ }
+ theme.mirrorHorizontally = hMirrored;
+ theme.mirrorVertically = vMirrored;
+ theme.noBorder = noBorder;
+ theme.noContent = noContent;
+ theme.rotate = rotate;
+ d->drawBackground(theme);
+}
+
+/*!
+ \reimp
+*/
+void QWindowsXPStyle::drawControl(ControlElement element, const QStyleOption *option, QPainter *p,
+ const QWidget *widget) const
+{
+ QWindowsXPStylePrivate *d = const_cast<QWindowsXPStylePrivate*>(d_func());
+ if (!QWindowsXPStylePrivate::useXP()) {
+ QWindowsStyle::drawControl(element, option, p, widget);
+ return;
+ }
+
+ QRect rect(option->rect);
+ State flags = option->state;
+
+ int rotate = 0;
+ bool hMirrored = false;
+ bool vMirrored = false;
+
+ QString name;
+ int partId = 0;
+ int stateId = 0;
+ switch (element) {
+ case CE_SizeGrip:
+ {
+ name = QLatin1String("STATUS");
+ partId = SP_GRIPPER;
+ SIZE sz;
+ XPThemeData theme(0, p, name, partId, 0);
+ pGetThemePartSize(theme.handle(), 0, partId, 0, 0, TS_TRUE, &sz);
+ --sz.cy;
+ if (const QStyleOptionSizeGrip *sg = qstyleoption_cast<const QStyleOptionSizeGrip *>(option)) {
+ switch (sg->corner) {
+ case Qt::BottomRightCorner:
+ rect = QRect(rect.right() - sz.cx, rect.bottom() - sz.cy, sz.cx, sz.cy);
+ break;
+ case Qt::BottomLeftCorner:
+ rect = QRect(rect.left() + 1, rect.bottom() - sz.cy, sz.cx, sz.cy);
+ hMirrored = true;
+ break;
+ case Qt::TopRightCorner:
+ rect = QRect(rect.right() - sz.cx, rect.top() + 1, sz.cx, sz.cy);
+ vMirrored = true;
+ break;
+ case Qt::TopLeftCorner:
+ rect = QRect(rect.left() + 1, rect.top() + 1, sz.cx, sz.cy);
+ hMirrored = vMirrored = true;
+ }
+ }
+ }
+ break;
+
+ case CE_HeaderSection:
+ name = QLatin1String("HEADER");
+ partId = HP_HEADERITEM;
+ if (flags & State_Sunken)
+ stateId = HIS_PRESSED;
+ else if (flags & State_MouseOver)
+ stateId = HIS_HOT;
+ else
+ stateId = HIS_NORMAL;
+ break;
+
+ case CE_Splitter:
+ p->eraseRect(option->rect);
+ return;
+
+ case CE_PushButtonBevel:
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option))
+ {
+ name = QLatin1String("BUTTON");
+ partId = BP_PUSHBUTTON;
+ bool justFlat = ((btn->features & QStyleOptionButton::Flat) && !(flags & (State_On|State_Sunken)))
+ || ((btn->features & QStyleOptionButton::CommandLinkButton)
+ && !(flags & State_MouseOver)
+ && !(btn->features & QStyleOptionButton::DefaultButton));
+ if (!(flags & State_Enabled) && !(btn->features & QStyleOptionButton::Flat))
+ stateId = PBS_DISABLED;
+ else if (justFlat)
+ ;
+ else if (flags & (State_Sunken | State_On))
+ stateId = PBS_PRESSED;
+ else if (flags & State_MouseOver)
+ stateId = PBS_HOT;
+ else if (btn->features & QStyleOptionButton::DefaultButton)
+ stateId = PBS_DEFAULTED;
+ else
+ stateId = PBS_NORMAL;
+
+ if (!justFlat) {
+ XPThemeData theme(widget, p, name, partId, stateId, rect);
+ d->drawBackground(theme);
+ }
+
+ if (btn->features & QStyleOptionButton::HasMenu) {
+ int mbiw = 0, mbih = 0;
+ XPThemeData theme(widget, 0, QLatin1String("TOOLBAR"), TP_SPLITBUTTONDROPDOWN);
+ if (theme.isValid()) {
+ SIZE size;
+ pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
+ mbiw = size.cx;
+ mbih = size.cy;
+ }
+
+ QRect ir = btn->rect;
+ QStyleOptionButton newBtn = *btn;
+ newBtn.rect = QRect(ir.right() - mbiw - 1, 1 + (ir.height()/2) - (mbih/2), mbiw, mbih);
+ proxy()->drawPrimitive(PE_IndicatorArrowDown, &newBtn, p, widget);
+ }
+ return;
+ }
+ break;
+ case CE_TabBarTab:
+ if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(option))
+ {
+ stateId = tab->state & State_Enabled ? TIS_NORMAL : TIS_DISABLED;
+ }
+ break;
+
+ case CE_TabBarTabShape:
+ if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(option))
+ {
+ name = QLatin1String("TAB");
+ bool isDisabled = !(tab->state & State_Enabled);
+ bool hasFocus = tab->state & State_HasFocus;
+ bool isHot = tab->state & State_MouseOver;
+ bool selected = tab->state & State_Selected;
+ bool lastTab = tab->position == QStyleOptionTab::End;
+ bool firstTab = tab->position == QStyleOptionTab::Beginning;
+ bool onlyOne = tab->position == QStyleOptionTab::OnlyOneTab;
+ bool leftAligned = proxy()->styleHint(SH_TabBar_Alignment, tab, widget) == Qt::AlignLeft;
+ bool centerAligned = proxy()->styleHint(SH_TabBar_Alignment, tab, widget) == Qt::AlignCenter;
+ int borderThickness = proxy()->pixelMetric(PM_DefaultFrameWidth, option, widget);
+ int tabOverlap = proxy()->pixelMetric(PM_TabBarTabOverlap, option, widget);
+
+ if (isDisabled)
+ stateId = TIS_DISABLED;
+ else if (selected)
+ stateId = TIS_SELECTED;
+ else if (hasFocus)
+ stateId = TIS_FOCUSED;
+ else if (isHot)
+ stateId = TIS_HOT;
+ else
+ stateId = TIS_NORMAL;
+
+ // Selecting proper part depending on position
+ if (firstTab || onlyOne) {
+ if (leftAligned) {
+ partId = TABP_TABITEMLEFTEDGE;
+ } else if (centerAligned) {
+ partId = TABP_TABITEM;
+ } else { // rightAligned
+ partId = TABP_TABITEMRIGHTEDGE;
+ }
+ } else {
+ partId = TABP_TABITEM;
+ }
+
+ if (tab->direction == Qt::RightToLeft
+ && (tab->shape == QTabBar::RoundedNorth
+ || tab->shape == QTabBar::RoundedSouth)) {
+ bool temp = firstTab;
+ firstTab = lastTab;
+ lastTab = temp;
+ }
+ bool begin = firstTab || onlyOne;
+ bool end = lastTab || onlyOne;
+ switch (tab->shape) {
+ case QTabBar::RoundedNorth:
+ if (selected)
+ rect.adjust(begin ? 0 : -tabOverlap, 0, end ? 0 : tabOverlap, borderThickness);
+ else
+ rect.adjust(begin? tabOverlap : 0, tabOverlap, end ? -tabOverlap : 0, 0);
+ break;
+ case QTabBar::RoundedSouth:
+ //vMirrored = true;
+ rotate = 180; // Not 100% correct, but works
+ if (selected)
+ rect.adjust(begin ? 0 : -tabOverlap , -borderThickness, end ? 0 : tabOverlap, 0);
+ else
+ rect.adjust(begin ? tabOverlap : 0, 0, end ? -tabOverlap : 0 , -tabOverlap);
+ break;
+ case QTabBar::RoundedEast:
+ rotate = 90;
+ if (selected) {
+ rect.adjust(-borderThickness, begin ? 0 : -tabOverlap, 0, end ? 0 : tabOverlap);
+ }else{
+ rect.adjust(0, begin ? tabOverlap : 0, -tabOverlap, end ? -tabOverlap : 0);
+ }
+ break;
+ case QTabBar::RoundedWest:
+ hMirrored = true;
+ rotate = 90;
+ if (selected) {
+ rect.adjust(0, begin ? 0 : -tabOverlap, borderThickness, end ? 0 : tabOverlap);
+ }else{
+ rect.adjust(tabOverlap, begin ? tabOverlap : 0, 0, end ? -tabOverlap : 0);
+ }
+ break;
+ default:
+ name = QLatin1String(""); // Do our own painting for triangular
+ break;
+ }
+
+ if (!selected) {
+ switch (tab->shape) {
+ case QTabBar::RoundedNorth:
+ rect.adjust(0,0, 0,-1);
+ break;
+ case QTabBar::RoundedSouth:
+ rect.adjust(0,1, 0,0);
+ break;
+ case QTabBar::RoundedEast:
+ rect.adjust( 1,0, 0,0);
+ break;
+ case QTabBar::RoundedWest:
+ rect.adjust(0,0, -1,0);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ break;
+
+ case CE_ProgressBarGroove:
+ {
+ Qt::Orientation orient = Qt::Horizontal;
+ if (const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option))
+ orient = pb2->orientation;
+ partId = (orient == Qt::Horizontal) ? PP_BAR : PP_BARVERT;
+ name = QLatin1String("PROGRESS");
+ stateId = 1;
+ }
+ break;
+
+ case CE_MenuEmptyArea:
+ case CE_MenuItem:
+ if (const QStyleOptionMenuItem *menuitem = qstyleoption_cast<const QStyleOptionMenuItem *>(option))
+ {
+ int tab = menuitem->tabWidth;
+ bool dis = !(menuitem->state & State_Enabled);
+ bool act = menuitem->state & State_Selected;
+ bool checkable = menuitem->menuHasCheckableItems;
+ bool checked = checkable ? menuitem->checked : false;
+
+ // windows always has a check column, regardless whether we have an icon or not
+ int checkcol = qMax(menuitem->maxIconWidth, 12);
+
+ int x, y, w, h;
+ rect.getRect(&x, &y, &w, &h);
+
+ QBrush fill = menuitem->palette.brush(act ? QPalette::Highlight : QPalette::Button);
+ p->fillRect(rect, fill);
+
+ if (element == CE_MenuEmptyArea)
+ break;
+
+ // draw separator -------------------------------------------------
+ if (menuitem->menuItemType == QStyleOptionMenuItem::Separator) {
+ int yoff = y-1 + h / 2;
+ p->setPen(menuitem->palette.dark().color());
+ p->drawLine(x, yoff, x+w, yoff);
+ ++yoff;
+ p->setPen(menuitem->palette.light().color());
+ p->drawLine(x, yoff, x+w, yoff);
+ return;
+ }
+
+ int xpos = x;
+
+ // draw icon ------------------------------------------------------
+ if (!menuitem->icon.isNull()) {
+ QIcon::Mode mode = dis ? QIcon::Disabled : QIcon::Normal;
+ if (act && !dis)
+ mode = QIcon::Active;
+ QPixmap pixmap = checked ?
+ menuitem->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, option, widget), mode, QIcon::On) :
+ menuitem->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, option, widget), mode);
+ int pixw = pixmap.width();
+ int pixh = pixmap.height();
+ QRect iconRect(0, 0, pixw, pixh);
+ iconRect.moveCenter(QRect(xpos, y, checkcol, h).center());
+ QRect vIconRect = visualRect(option->direction, option->rect, iconRect);
+ p->setPen(menuitem->palette.text().color());
+ p->setBrush(Qt::NoBrush);
+ if (checked)
+ p->drawRect(vIconRect.adjusted(-1, -1, 0, 0));
+ p->drawPixmap(vIconRect.topLeft(), pixmap);
+
+ // draw checkmark -------------------------------------------------
+ } else if (checked) {
+ QStyleOptionMenuItem newMi = *menuitem;
+ newMi.state = State_None;
+ if (!dis)
+ newMi.state |= State_Enabled;
+ if (act)
+ newMi.state |= State_On;
+
+ QRect checkMarkRect = QRect(menuitem->rect.x() + windowsItemFrame,
+ menuitem->rect.y() + windowsItemFrame,
+ checkcol - 2 * windowsItemFrame,
+ menuitem->rect.height() - 2*windowsItemFrame);
+ newMi.rect = visualRect(option->direction, option->rect, checkMarkRect);
+ proxy()->drawPrimitive(PE_IndicatorMenuCheckMark, &newMi, p, widget);
+ }
+
+ QColor textColor = dis ? menuitem->palette.text().color() :
+ act ? menuitem->palette.highlightedText().color() : menuitem->palette.buttonText().color();
+ p->setPen(textColor);
+
+ // draw text ------------------------------------------------------
+ int xm = windowsItemFrame + checkcol + windowsItemHMargin;
+ xpos = menuitem->rect.x() + xm;
+ QRect textRect(xpos, y + windowsItemVMargin, w - xm - windowsRightBorder - tab + 1, h - 2 * windowsItemVMargin);
+ QRect vTextRect = visualRect(option->direction, option->rect, textRect);
+ QString s = menuitem->text;
+ if (!s.isEmpty()) {
+ p->save();
+ int t = s.indexOf(QLatin1Char('\t'));
+ int text_flags = Qt::AlignVCenter|Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine | Qt::AlignLeft;
+ if (!proxy()->styleHint(SH_UnderlineShortcut, menuitem, widget))
+ text_flags |= Qt::TextHideMnemonic;
+ // draw tab text ----------------
+ if (t >= 0) {
+ QRect vShortcutRect = visualRect(option->direction, option->rect, QRect(textRect.topRight(), menuitem->rect.bottomRight()));
+ if (dis && !act && proxy()->styleHint(SH_EtchDisabledText, option, widget)) {
+ p->setPen(menuitem->palette.light().color());
+ p->drawText(vShortcutRect.adjusted(1,1,1,1), text_flags, s.mid(t + 1));
+ p->setPen(textColor);
+ }
+ p->drawText(vShortcutRect, text_flags, s.mid(t + 1));
+ s = s.left(t);
+ }
+ QFont font = menuitem->font;
+ if (menuitem->menuItemType == QStyleOptionMenuItem::DefaultItem)
+ font.setBold(true);
+ p->setFont(font);
+ if (dis && !act && proxy()->styleHint(SH_EtchDisabledText, option, widget)) {
+ p->setPen(menuitem->palette.light().color());
+ p->drawText(vTextRect.adjusted(1,1,1,1), text_flags, s.left(t));
+ p->setPen(textColor);
+ }
+ p->drawText(vTextRect, text_flags, s);
+ p->restore();
+ }
+
+ // draw sub menu arrow --------------------------------------------
+ if (menuitem->menuItemType == QStyleOptionMenuItem::SubMenu) {
+ int dim = (h - 2) / 2;
+ PrimitiveElement arrow;
+ arrow = (option->direction == Qt::RightToLeft) ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight;
+ xpos = x + w - windowsArrowHMargin - windowsItemFrame - dim;
+ QRect vSubMenuRect = visualRect(option->direction, option->rect, QRect(xpos, y + h / 2 - dim / 2, dim, dim));
+ QStyleOptionMenuItem newMI = *menuitem;
+ newMI.rect = vSubMenuRect;
+ newMI.state = dis ? State_None : State_Enabled;
+ if (act)
+ newMI.palette.setColor(QPalette::ButtonText, newMI.palette.highlightedText().color());
+ proxy()->drawPrimitive(arrow, &newMI, p, widget);
+ }
+ }
+ return;
+
+ case CE_MenuBarItem:
+ if (const QStyleOptionMenuItem *mbi = qstyleoption_cast<const QStyleOptionMenuItem *>(option))
+ {
+ if (mbi->menuItemType == QStyleOptionMenuItem::DefaultItem)
+ break;
+
+ bool act = mbi->state & State_Selected;
+ bool dis = !(mbi->state & State_Enabled);
+
+ QBrush fill = mbi->palette.brush(act ? QPalette::Highlight : QPalette::Button);
+ QPalette::ColorRole textRole = dis ? QPalette::Text:
+ act ? QPalette::HighlightedText : QPalette::ButtonText;
+ QPixmap pix = mbi->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, option, widget), QIcon::Normal);
+
+ uint alignment = Qt::AlignCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
+ if (!proxy()->styleHint(SH_UnderlineShortcut, mbi, widget))
+ alignment |= Qt::TextHideMnemonic;
+
+ p->fillRect(rect, fill);
+ if (!pix.isNull())
+ drawItemPixmap(p, mbi->rect, alignment, pix);
+ else
+ drawItemText(p, mbi->rect, alignment, mbi->palette, mbi->state & State_Enabled, mbi->text, textRole);
+ }
+ return;
+#ifndef QT_NO_DOCKWIDGET
+ case CE_DockWidgetTitle:
+ if (const QStyleOptionDockWidget *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(option))
+ {
+ int buttonMargin = 4;
+ int mw = proxy()->pixelMetric(QStyle::PM_DockWidgetTitleMargin, dwOpt, widget);
+ int fw = proxy()->pixelMetric(PM_DockWidgetFrameWidth, dwOpt, widget);
+ bool isFloating = widget && widget->isWindow();
+ bool isActive = dwOpt->state & State_Active;
+
+ const QStyleOptionDockWidgetV2 *v2
+ = qstyleoption_cast<const QStyleOptionDockWidgetV2*>(dwOpt);
+ bool verticalTitleBar = v2 == 0 ? false : v2->verticalTitleBar;
+
+ if (verticalTitleBar) {
+ QSize s = rect.size();
+ s.transpose();
+ rect.setSize(s);
+
+ p->translate(rect.left() - 1, rect.top() + rect.width());
+ p->rotate(-90);
+ p->translate(-rect.left() + 1, -rect.top());
+ }
+ QRect r = rect.adjusted(0, 2, -1, -3);
+ QRect titleRect = r;
+
+ if (dwOpt->closable) {
+ QSize sz = proxy()->standardIcon(QStyle::SP_TitleBarCloseButton, dwOpt, widget).actualSize(QSize(10, 10));
+ titleRect.adjust(0, 0, -sz.width() - mw - buttonMargin, 0);
+ }
+
+ if (dwOpt->floatable) {
+ QSize sz = proxy()->standardIcon(QStyle::SP_TitleBarMaxButton, dwOpt, widget).actualSize(QSize(10, 10));
+ titleRect.adjust(0, 0, -sz.width() - mw - buttonMargin, 0);
+ }
+
+ if (isFloating) {
+ titleRect.adjust(0, -fw, 0, 0);
+ if (widget != 0 && widget->windowIcon().cacheKey() != QApplication::windowIcon().cacheKey())
+ titleRect.adjust(titleRect.height() + mw, 0, 0, 0);
+ } else {
+ titleRect.adjust(mw, 0, 0, 0);
+ if (!dwOpt->floatable && !dwOpt->closable)
+ titleRect.adjust(0, 0, -mw, 0);
+ }
+
+ if (!verticalTitleBar)
+ titleRect = visualRect(dwOpt->direction, r, titleRect);
+
+ if (!isFloating) {
+ QPen oldPen = p->pen();
+ QString titleText = p->fontMetrics().elidedText(dwOpt->title, Qt::ElideRight, titleRect.width());
+ p->setPen(dwOpt->palette.color(QPalette::Dark));
+ p->drawRect(r);
+
+ if (!titleText.isEmpty()) {
+ drawItemText(p, titleRect,
+ Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic, dwOpt->palette,
+ dwOpt->state & State_Enabled, titleText,
+ QPalette::WindowText);
+ }
+
+ p->setPen(oldPen);
+ } else {
+ name = QLatin1String("WINDOW");
+ if (isActive)
+ stateId = CS_ACTIVE;
+ else
+ stateId = CS_INACTIVE;
+
+ int titleHeight = rect.height() - 2;
+ rect = rect.adjusted(-fw, -fw, fw, 0);
+
+ XPThemeData theme(widget, p, name, 0, stateId);
+ if (!theme.isValid())
+ break;
+
+ // Draw small type title bar
+ theme.rect = rect;
+ theme.partId = WP_SMALLCAPTION;
+ d->drawBackground(theme);
+
+ // Figure out maximal button space on title bar
+
+ QIcon ico = widget->windowIcon();
+ bool hasIcon = (ico.cacheKey() != QApplication::windowIcon().cacheKey());
+ if (hasIcon) {
+ QPixmap pxIco = ico.pixmap(titleHeight);
+ if (!verticalTitleBar && dwOpt->direction == Qt::RightToLeft)
+ p->drawPixmap(rect.width() - titleHeight - pxIco.width(), rect.bottom() - titleHeight - 2, pxIco);
+ else
+ p->drawPixmap(fw, rect.bottom() - titleHeight - 2, pxIco);
+ }
+ if (!dwOpt->title.isEmpty()) {
+ QPen oldPen = p->pen();
+ QFont oldFont = p->font();
+ QFont titleFont = oldFont;
+ titleFont.setBold(true);
+ p->setFont(titleFont);
+ QString titleText
+ = p->fontMetrics().elidedText(dwOpt->title, Qt::ElideRight, titleRect.width());
+
+ int result = TST_NONE;
+ pGetThemeEnumValue(theme.handle(), WP_SMALLCAPTION, isActive ? CS_ACTIVE : CS_INACTIVE, TMT_TEXTSHADOWTYPE, &result);
+ if (result != TST_NONE) {
+ COLORREF textShadowRef;
+ pGetThemeColor(theme.handle(), WP_SMALLCAPTION, isActive ? CS_ACTIVE : CS_INACTIVE, TMT_TEXTSHADOWCOLOR, &textShadowRef);
+ QColor textShadow = qRgb(GetRValue(textShadowRef), GetGValue(textShadowRef), GetBValue(textShadowRef));
+ p->setPen(textShadow);
+ drawItemText(p, titleRect.adjusted(1, 1, 1, 1),
+ Qt::AlignLeft | Qt::AlignBottom, dwOpt->palette,
+ dwOpt->state & State_Enabled, titleText);
+ }
+
+ COLORREF captionText = GetSysColor(isActive ? COLOR_CAPTIONTEXT : COLOR_INACTIVECAPTIONTEXT);
+ QColor textColor = qRgb(GetRValue(captionText), GetGValue(captionText), GetBValue(captionText));
+ p->setPen(textColor);
+ drawItemText(p, titleRect,
+ Qt::AlignLeft | Qt::AlignBottom, dwOpt->palette,
+ dwOpt->state & State_Enabled, titleText);
+ p->setFont(oldFont);
+ p->setPen(oldPen);
+ }
+
+ }
+
+ return;
+ }
+ break;
+#endif // QT_NO_DOCKWIDGET
+#ifndef QT_NO_RUBBERBAND
+ case CE_RubberBand:
+ if (qstyleoption_cast<const QStyleOptionRubberBand *>(option)) {
+ QColor highlight = option->palette.color(QPalette::Active, QPalette::Highlight);
+ p->save();
+ QRect r = option->rect;
+ p->setPen(highlight.darker(120));
+ QColor dimHighlight(qMin(highlight.red()/2 + 110, 255),
+ qMin(highlight.green()/2 + 110, 255),
+ qMin(highlight.blue()/2 + 110, 255),
+ (widget && widget->isTopLevel())? 255 : 127);
+ p->setBrush(dimHighlight);
+ p->drawRect(option->rect.adjusted(0, 0, -1, -1));
+ p->restore();
+ return;
+ }
+#endif // QT_NO_RUBBERBAND
+ case CE_HeaderEmptyArea:
+ if (option->state & State_Horizontal)
+ {
+ name = QLatin1String("HEADER");
+ stateId = HIS_NORMAL;
+ }
+ else {
+ QWindowsStyle::drawControl(CE_HeaderEmptyArea, option, p, widget);
+ return;
+ }
+ break;
+ default:
+ break;
+ }
+
+ XPThemeData theme(widget, p, name, partId, stateId, rect);
+ if (!theme.isValid()) {
+ QWindowsStyle::drawControl(element, option, p, widget);
+ return;
+ }
+
+ theme.rotate = rotate;
+ theme.mirrorHorizontally = hMirrored;
+ theme.mirrorVertically = vMirrored;
+ d->drawBackground(theme);
+}
+
+
+/*!
+ \reimp
+*/
+void QWindowsXPStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex *option,
+ QPainter *p, const QWidget *widget) const
+{
+ QWindowsXPStylePrivate *d = const_cast<QWindowsXPStylePrivate*>(d_func());
+
+ if (!QWindowsXPStylePrivate::useXP()) {
+ QWindowsStyle::drawComplexControl(cc, option, p, widget);
+ return;
+ }
+
+ State flags = option->state;
+ SubControls sub = option->subControls;
+ QRect r = option->rect;
+
+ int partId = 0;
+ int stateId = 0;
+ if (widget && widget->testAttribute(Qt::WA_UnderMouse) && widget->isActiveWindow())
+ flags |= State_MouseOver;
+
+ switch (cc) {
+#ifndef QT_NO_SPINBOX
+ case CC_SpinBox:
+ if (const QStyleOptionSpinBox *sb = qstyleoption_cast<const QStyleOptionSpinBox *>(option))
+ {
+ XPThemeData theme(widget, p, QLatin1String("SPIN"));
+
+ if (sb->frame && (sub & SC_SpinBoxFrame)) {
+ partId = EP_EDITTEXT;
+ if (!(flags & State_Enabled))
+ stateId = ETS_DISABLED;
+ else if (flags & State_HasFocus)
+ stateId = ETS_FOCUSED;
+ else
+ stateId = ETS_NORMAL;
+
+ XPThemeData ftheme(widget, p, QLatin1String("EDIT"), partId, stateId, r);
+ ftheme.noContent = true;
+ d->drawBackground(ftheme);
+ }
+ if (sub & SC_SpinBoxUp) {
+ theme.rect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxUp, widget);
+ partId = SPNP_UP;
+ if (!(sb->stepEnabled & QAbstractSpinBox::StepUpEnabled) || !(flags & State_Enabled))
+ stateId = UPS_DISABLED;
+ else if (sb->activeSubControls == SC_SpinBoxUp && (sb->state & State_Sunken))
+ stateId = UPS_PRESSED;
+ else if (sb->activeSubControls == SC_SpinBoxUp && (sb->state & State_MouseOver))
+ stateId = UPS_HOT;
+ else
+ stateId = UPS_NORMAL;
+ theme.partId = partId;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+ }
+ if (sub & SC_SpinBoxDown) {
+ theme.rect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxDown, widget);
+ partId = SPNP_DOWN;
+ if (!(sb->stepEnabled & QAbstractSpinBox::StepDownEnabled) || !(flags & State_Enabled))
+ stateId = DNS_DISABLED;
+ else if (sb->activeSubControls == SC_SpinBoxDown && (sb->state & State_Sunken))
+ stateId = DNS_PRESSED;
+ else if (sb->activeSubControls == SC_SpinBoxDown && (sb->state & State_MouseOver))
+ stateId = DNS_HOT;
+ else
+ stateId = DNS_NORMAL;
+ theme.partId = partId;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+ }
+ }
+ break;
+#endif // QT_NO_SPINBOX
+#ifndef QT_NO_COMBOBOX
+ case CC_ComboBox:
+ if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(option))
+ {
+ if (sub & SC_ComboBoxEditField) {
+ if (cmb->frame) {
+ partId = EP_EDITTEXT;
+ if (!(flags & State_Enabled))
+ stateId = ETS_DISABLED;
+ else if (flags & State_HasFocus)
+ stateId = ETS_FOCUSED;
+ else
+ stateId = ETS_NORMAL;
+ XPThemeData theme(widget, p, QLatin1String("EDIT"), partId, stateId, r);
+ d->drawBackground(theme);
+ } else {
+ QBrush editBrush = cmb->palette.brush(QPalette::Base);
+ p->fillRect(option->rect, editBrush);
+ }
+ if (!cmb->editable) {
+ QRect re = proxy()->subControlRect(CC_ComboBox, option, SC_ComboBoxEditField, widget);
+ if (option->state & State_HasFocus) {
+ p->fillRect(re, option->palette.highlight());
+ p->setPen(option->palette.highlightedText().color());
+ p->setBackground(option->palette.highlight());
+ } else {
+ p->fillRect(re, option->palette.base());
+ p->setPen(option->palette.text().color());
+ p->setBackground(option->palette.base());
+ }
+ }
+ }
+
+ if (sub & SC_ComboBoxArrow) {
+ XPThemeData theme(widget, p, QLatin1String("COMBOBOX"));
+ theme.rect = proxy()->subControlRect(CC_ComboBox, option, SC_ComboBoxArrow, widget);
+ partId = CP_DROPDOWNBUTTON;
+ if (!(flags & State_Enabled))
+ stateId = CBXS_DISABLED;
+ else if (cmb->activeSubControls == SC_ComboBoxArrow && (cmb->state & State_Sunken))
+ stateId = CBXS_PRESSED;
+ else if (cmb->activeSubControls == SC_ComboBoxArrow && (cmb->state & State_MouseOver))
+ stateId = CBXS_HOT;
+ else
+ stateId = CBXS_NORMAL;
+ theme.partId = partId;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+ }
+ }
+ break;
+#endif // QT_NO_COMBOBOX
+ case CC_ScrollBar:
+ if (const QStyleOptionSlider *scrollbar = qstyleoption_cast<const QStyleOptionSlider *>(option))
+ {
+ XPThemeData theme(widget, p, QLatin1String("SCROLLBAR"));
+ bool maxedOut = (scrollbar->maximum == scrollbar->minimum);
+ if (maxedOut)
+ flags &= ~State_Enabled;
+
+ bool isHorz = flags & State_Horizontal;
+ bool isRTL = option->direction == Qt::RightToLeft;
+ if (sub & SC_ScrollBarAddLine) {
+ theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarAddLine, widget);
+ partId = SBP_ARROWBTN;
+ if (!(flags & State_Enabled))
+ stateId = (isHorz ? (isRTL ? ABS_LEFTDISABLED : ABS_RIGHTDISABLED) : ABS_DOWNDISABLED);
+ else if (scrollbar->activeSubControls & SC_ScrollBarAddLine && (scrollbar->state & State_Sunken))
+ stateId = (isHorz ? (isRTL ? ABS_LEFTPRESSED : ABS_RIGHTPRESSED) : ABS_DOWNPRESSED);
+ else if (scrollbar->activeSubControls & SC_ScrollBarAddLine && (scrollbar->state & State_MouseOver))
+ stateId = (isHorz ? (isRTL ? ABS_LEFTHOT : ABS_RIGHTHOT) : ABS_DOWNHOT);
+ else
+ stateId = (isHorz ? (isRTL ? ABS_LEFTNORMAL : ABS_RIGHTNORMAL) : ABS_DOWNNORMAL);
+ theme.partId = partId;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+ }
+ if (sub & SC_ScrollBarSubLine) {
+ theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSubLine, widget);
+ partId = SBP_ARROWBTN;
+ if (!(flags & State_Enabled))
+ stateId = (isHorz ? (isRTL ? ABS_RIGHTDISABLED : ABS_LEFTDISABLED) : ABS_UPDISABLED);
+ else if (scrollbar->activeSubControls & SC_ScrollBarSubLine && (scrollbar->state & State_Sunken))
+ stateId = (isHorz ? (isRTL ? ABS_RIGHTPRESSED : ABS_LEFTPRESSED) : ABS_UPPRESSED);
+ else if (scrollbar->activeSubControls & SC_ScrollBarSubLine && (scrollbar->state & State_MouseOver))
+ stateId = (isHorz ? (isRTL ? ABS_RIGHTHOT : ABS_LEFTHOT) : ABS_UPHOT);
+ else
+ stateId = (isHorz ? (isRTL ? ABS_RIGHTNORMAL : ABS_LEFTNORMAL) : ABS_UPNORMAL);
+ theme.partId = partId;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+ }
+ if (maxedOut) {
+ theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider, widget);
+ theme.rect = theme.rect.united(proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSubPage, widget));
+ theme.rect = theme.rect.united(proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarAddPage, widget));
+ partId = scrollbar->orientation == Qt::Horizontal ? SBP_LOWERTRACKHORZ : SBP_LOWERTRACKVERT;
+ stateId = SCRBS_DISABLED;
+ theme.partId = partId;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+ } else {
+ if (sub & SC_ScrollBarSubPage) {
+ theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSubPage, widget);
+ partId = flags & State_Horizontal ? SBP_UPPERTRACKHORZ : SBP_UPPERTRACKVERT;
+ if (!(flags & State_Enabled))
+ stateId = SCRBS_DISABLED;
+ else if (scrollbar->activeSubControls & SC_ScrollBarSubPage && (scrollbar->state & State_Sunken))
+ stateId = SCRBS_PRESSED;
+ else if (scrollbar->activeSubControls & SC_ScrollBarSubPage && (scrollbar->state & State_MouseOver))
+ stateId = SCRBS_HOT;
+ else
+ stateId = SCRBS_NORMAL;
+ theme.partId = partId;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+ }
+ if (sub & SC_ScrollBarAddPage) {
+ theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarAddPage, widget);
+ partId = flags & State_Horizontal ? SBP_LOWERTRACKHORZ : SBP_LOWERTRACKVERT;
+ if (!(flags & State_Enabled))
+ stateId = SCRBS_DISABLED;
+ else if (scrollbar->activeSubControls & SC_ScrollBarAddPage && (scrollbar->state & State_Sunken))
+ stateId = SCRBS_PRESSED;
+ else if (scrollbar->activeSubControls & SC_ScrollBarAddPage && (scrollbar->state & State_MouseOver))
+ stateId = SCRBS_HOT;
+ else
+ stateId = SCRBS_NORMAL;
+ theme.partId = partId;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+ }
+ if (sub & SC_ScrollBarSlider) {
+ theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider, widget);
+ if (!(flags & State_Enabled))
+ stateId = SCRBS_DISABLED;
+ else if (scrollbar->activeSubControls & SC_ScrollBarSlider && (scrollbar->state & State_Sunken))
+ stateId = SCRBS_PRESSED;
+ else if (scrollbar->activeSubControls & SC_ScrollBarSlider && (scrollbar->state & State_MouseOver))
+ stateId = SCRBS_HOT;
+ else
+ stateId = SCRBS_NORMAL;
+
+ // Draw handle
+ theme.rect = proxy()->subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider, widget);
+ theme.partId = flags & State_Horizontal ? SBP_THUMBBTNHORZ : SBP_THUMBBTNVERT;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+
+ // Calculate rect of gripper
+ const int swidth = theme.rect.width();
+ const int sheight = theme.rect.height();
+
+ MARGINS contentsMargin;
+ RECT rect = theme.toRECT(theme.rect);
+ pGetThemeMargins(theme.handle(), 0, theme.partId, theme.stateId, TMT_SIZINGMARGINS, &rect, &contentsMargin);
+
+ SIZE size;
+ theme.partId = flags & State_Horizontal ? SBP_GRIPPERHORZ : SBP_GRIPPERVERT;
+ pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
+ int gw = size.cx, gh = size.cy;
+
+
+ QRect gripperBounds;
+ if (flags & State_Horizontal && ((swidth - contentsMargin.cxLeftWidth - contentsMargin.cxRightWidth) > gw)) {
+ gripperBounds.setLeft(theme.rect.left() + swidth/2 - gw/2);
+ gripperBounds.setTop(theme.rect.top() + sheight/2 - gh/2);
+ gripperBounds.setWidth(gw);
+ gripperBounds.setHeight(gh);
+ } else if ((sheight - contentsMargin.cyTopHeight - contentsMargin.cyBottomHeight) > gh) {
+ gripperBounds.setLeft(theme.rect.left() + swidth/2 - gw/2);
+ gripperBounds.setTop(theme.rect.top() + sheight/2 - gh/2);
+ gripperBounds.setWidth(gw);
+ gripperBounds.setHeight(gh);
+ }
+
+ // Draw gripper if there is enough space
+ if (!gripperBounds.isEmpty()) {
+ p->save();
+ theme.rect = gripperBounds;
+ p->setClipRegion(d->region(theme));// Only change inside the region of the gripper
+ d->drawBackground(theme); // Transparent gripper ontop of background
+ p->restore();
+ }
+ }
+ }
+ }
+ break;
+
+#ifndef QT_NO_SLIDER
+ case CC_Slider:
+ if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option))
+ {
+ XPThemeData theme(widget, p, QLatin1String("TRACKBAR"));
+ QRect slrect = slider->rect;
+ QRegion tickreg = slrect;
+ if (sub & SC_SliderGroove) {
+ theme.rect = proxy()->subControlRect(CC_Slider, option, SC_SliderGroove, widget);
+ if (slider->orientation == Qt::Horizontal) {
+ partId = TKP_TRACK;
+ stateId = TRS_NORMAL;
+ theme.rect = QRect(slrect.left(), theme.rect.center().y() - 2, slrect.width(), 4);
+ } else {
+ partId = TKP_TRACKVERT;
+ stateId = TRVS_NORMAL;
+ theme.rect = QRect(theme.rect.center().x() - 2, slrect.top(), 4, slrect.height());
+ }
+ theme.partId = partId;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+ tickreg -= theme.rect;
+ }
+ if (sub & SC_SliderTickmarks) {
+ int tickOffset = proxy()->pixelMetric(PM_SliderTickmarkOffset, slider, widget);
+ int ticks = slider->tickPosition;
+ int thickness = proxy()->pixelMetric(PM_SliderControlThickness, slider, widget);
+ int len = proxy()->pixelMetric(PM_SliderLength, slider, widget);
+ int available = proxy()->pixelMetric(PM_SliderSpaceAvailable, slider, widget);
+ int interval = slider->tickInterval;
+ if (interval <= 0) {
+ interval = slider->singleStep;
+ if (QStyle::sliderPositionFromValue(slider->minimum, slider->maximum, interval,
+ available)
+ - QStyle::sliderPositionFromValue(slider->minimum, slider->maximum,
+ 0, available) < 3)
+ interval = slider->pageStep;
+ }
+ if (!interval)
+ interval = 1;
+ int fudge = len / 2;
+ int pos;
+ int bothOffset = (ticks & QSlider::TicksAbove && ticks & QSlider::TicksBelow) ? 1 : 0;
+ p->setPen(d->sliderTickColor);
+ QVarLengthArray<QLine, 32> lines;
+ int v = slider->minimum;
+ while (v <= slider->maximum + 1) {
+ if (v == slider->maximum + 1 && interval == 1)
+ break;
+ const int v_ = qMin(v, slider->maximum);
+ int tickLength = (v_ == slider->minimum || v_ >= slider->maximum) ? 4 : 3;
+ pos = QStyle::sliderPositionFromValue(slider->minimum, slider->maximum,
+ v_, available) + fudge;
+ if (slider->orientation == Qt::Horizontal) {
+ if (ticks & QSlider::TicksAbove)
+ lines.append(QLine(pos, tickOffset - 1 - bothOffset,
+ pos, tickOffset - 1 - bothOffset - tickLength));
+
+ if (ticks & QSlider::TicksBelow)
+ lines.append(QLine(pos, tickOffset + thickness + bothOffset,
+ pos, tickOffset + thickness + bothOffset + tickLength));
+ } else {
+ if (ticks & QSlider::TicksAbove)
+ lines.append(QLine(tickOffset - 1 - bothOffset, pos,
+ tickOffset - 1 - bothOffset - tickLength, pos));
+
+ if (ticks & QSlider::TicksBelow)
+ lines.append(QLine(tickOffset + thickness + bothOffset, pos,
+ tickOffset + thickness + bothOffset + tickLength, pos));
+ }
+ // in the case where maximum is max int
+ int nextInterval = v + interval;
+ if (nextInterval < v)
+ break;
+ v = nextInterval;
+ }
+ if (lines.size() > 0) {
+ p->save();
+ p->translate(slrect.topLeft());
+ p->drawLines(lines.constData(), lines.size());
+ p->restore();
+ }
+ }
+ if (sub & SC_SliderHandle) {
+ theme.rect = proxy()->subControlRect(CC_Slider, option, SC_SliderHandle, widget);
+ if (slider->orientation == Qt::Horizontal) {
+ if (slider->tickPosition == QSlider::TicksAbove)
+ partId = TKP_THUMBTOP;
+ else if (slider->tickPosition == QSlider::TicksBelow)
+ partId = TKP_THUMBBOTTOM;
+ else
+ partId = TKP_THUMB;
+
+ if (!(slider->state & State_Enabled))
+ stateId = TUS_DISABLED;
+ else if (slider->activeSubControls & SC_SliderHandle && (slider->state & State_Sunken))
+ stateId = TUS_PRESSED;
+ else if (slider->activeSubControls & SC_SliderHandle && (slider->state & State_MouseOver))
+ stateId = TUS_HOT;
+ else if (flags & State_HasFocus)
+ stateId = TUS_FOCUSED;
+ else
+ stateId = TUS_NORMAL;
+ } else {
+ if (slider->tickPosition == QSlider::TicksLeft)
+ partId = TKP_THUMBLEFT;
+ else if (slider->tickPosition == QSlider::TicksRight)
+ partId = TKP_THUMBRIGHT;
+ else
+ partId = TKP_THUMBVERT;
+
+ if (!(slider->state & State_Enabled))
+ stateId = TUVS_DISABLED;
+ else if (slider->activeSubControls & SC_SliderHandle && (slider->state & State_Sunken))
+ stateId = TUVS_PRESSED;
+ else if (slider->activeSubControls & SC_SliderHandle && (slider->state & State_MouseOver))
+ stateId = TUVS_HOT;
+ else if (flags & State_HasFocus)
+ stateId = TUVS_FOCUSED;
+ else
+ stateId = TUVS_NORMAL;
+ }
+ theme.partId = partId;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+ }
+ if (slider->state & State_HasFocus) {
+ QStyleOptionFocusRect fropt;
+ fropt.QStyleOption::operator=(*slider);
+ fropt.rect = subElementRect(SE_SliderFocusRect, slider, widget);
+ proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, p, widget);
+ }
+ }
+ break;
+#endif
+#ifndef QT_NO_TOOLBUTTON
+ case CC_ToolButton:
+ if (const QStyleOptionToolButton *toolbutton
+ = qstyleoption_cast<const QStyleOptionToolButton *>(option)) {
+ QRect button, menuarea;
+ button = proxy()->subControlRect(cc, toolbutton, SC_ToolButton, widget);
+ menuarea = proxy()->subControlRect(cc, toolbutton, SC_ToolButtonMenu, widget);
+
+ State bflags = toolbutton->state & ~State_Sunken;
+ State mflags = bflags;
+ bool autoRaise = flags & State_AutoRaise;
+ if (autoRaise) {
+ if (!(bflags & State_MouseOver) || !(bflags & State_Enabled)) {
+ bflags &= ~State_Raised;
+ }
+ }
+
+ if (toolbutton->state & State_Sunken) {
+ if (toolbutton->activeSubControls & SC_ToolButton) {
+ bflags |= State_Sunken;
+ mflags |= State_MouseOver | State_Sunken;
+ } else if (toolbutton->activeSubControls & SC_ToolButtonMenu) {
+ mflags |= State_Sunken;
+ bflags |= State_MouseOver;
+ }
+ }
+
+ QStyleOption tool(0);
+ tool.palette = toolbutton->palette;
+ if (toolbutton->subControls & SC_ToolButton) {
+ if (flags & (State_Sunken | State_On | State_Raised) || !autoRaise) {
+ if (toolbutton->features & QStyleOptionToolButton::MenuButtonPopup && autoRaise) {
+ XPThemeData theme(widget, p, QLatin1String("TOOLBAR"));
+ theme.partId = TP_SPLITBUTTON;
+ theme.rect = button;
+ if (!(bflags & State_Enabled))
+ stateId = TS_DISABLED;
+ else if (bflags & State_Sunken)
+ stateId = TS_PRESSED;
+ else if (bflags & State_MouseOver || !(flags & State_AutoRaise))
+ stateId = flags & State_On ? TS_HOTCHECKED : TS_HOT;
+ else if (bflags & State_On)
+ stateId = TS_CHECKED;
+ else
+ stateId = TS_NORMAL;
+ if (option->direction == Qt::RightToLeft)
+ theme.mirrorHorizontally = true;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+ } else {
+ tool.rect = option->rect;
+ tool.state = bflags;
+ if (autoRaise) // for tool bars
+ proxy()->drawPrimitive(PE_PanelButtonTool, &tool, p, widget);
+ else
+ proxy()->drawPrimitive(PE_PanelButtonBevel, &tool, p, widget);
+ }
+ }
+ }
+
+ if (toolbutton->state & State_HasFocus) {
+ QStyleOptionFocusRect fr;
+ fr.QStyleOption::operator=(*toolbutton);
+ fr.rect.adjust(3, 3, -3, -3);
+ if (toolbutton->features & QStyleOptionToolButton::MenuButtonPopup)
+ fr.rect.adjust(0, 0, -proxy()->pixelMetric(QStyle::PM_MenuButtonIndicator,
+ toolbutton, widget), 0);
+ proxy()->drawPrimitive(PE_FrameFocusRect, &fr, p, widget);
+ }
+ QStyleOptionToolButton label = *toolbutton;
+ label.state = bflags;
+ int fw = 2;
+ if (!autoRaise)
+ label.state &= ~State_Sunken;
+ label.rect = button.adjusted(fw, fw, -fw, -fw);
+ proxy()->drawControl(CE_ToolButtonLabel, &label, p, widget);
+
+ if (toolbutton->subControls & SC_ToolButtonMenu) {
+ tool.rect = menuarea;
+ tool.state = mflags;
+ if (autoRaise) {
+ proxy()->drawPrimitive(PE_IndicatorButtonDropDown, &tool, p, widget);
+ } else {
+ tool.state = mflags;
+ menuarea.adjust(-2, 0, 0, 0);
+ // Draw menu button
+ if ((bflags & State_Sunken) != (mflags & State_Sunken)){
+ p->save();
+ p->setClipRect(menuarea);
+ tool.rect = option->rect;
+ proxy()->drawPrimitive(PE_PanelButtonBevel, &tool, p, 0);
+ p->restore();
+ }
+ // Draw arrow
+ p->save();
+ p->setPen(option->palette.dark().color());
+ p->drawLine(menuarea.left(), menuarea.top() + 3,
+ menuarea.left(), menuarea.bottom() - 3);
+ p->setPen(option->palette.light().color());
+ p->drawLine(menuarea.left() - 1, menuarea.top() + 3,
+ menuarea.left() - 1, menuarea.bottom() - 3);
+
+ tool.rect = menuarea.adjusted(2, 3, -2, -1);
+ proxy()->drawPrimitive(PE_IndicatorArrowDown, &tool, p, widget);
+ p->restore();
+ }
+ } else if (toolbutton->features & QStyleOptionToolButton::HasMenu) {
+ int mbi = proxy()->pixelMetric(PM_MenuButtonIndicator, toolbutton, widget);
+ QRect ir = toolbutton->rect;
+ QStyleOptionToolButton newBtn = *toolbutton;
+ newBtn.rect = QRect(ir.right() + 4 - mbi, ir.height() - mbi + 4, mbi - 5, mbi - 5);
+ proxy()->drawPrimitive(PE_IndicatorArrowDown, &newBtn, p, widget);
+ }
+ }
+ break;
+#endif // QT_NO_TOOLBUTTON
+
+ case CC_TitleBar:
+ {
+ if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(option))
+ {
+ bool isActive = tb->titleBarState & QStyle::State_Active;
+ XPThemeData theme(widget, p, QLatin1String("WINDOW"));
+ if (sub & SC_TitleBarLabel) {
+
+#ifdef QT3_SUPPORT
+ if (widget && widget->inherits("Q3DockWindowTitleBar")) {
+ partId = WP_SMALLCAPTION;
+ } else
+#endif
+ partId = (tb->titleBarState & Qt::WindowMinimized) ? WP_MINCAPTION : WP_CAPTION;
+ theme.rect = option->rect;
+ if (widget && !widget->isEnabled())
+ stateId = CS_DISABLED;
+ else if (isActive)
+ stateId = CS_ACTIVE;
+ else
+ stateId = CS_INACTIVE;
+
+ theme.partId = partId;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+
+ QRect ir = proxy()->subControlRect(CC_TitleBar, tb, SC_TitleBarLabel, widget);
+
+ int result = TST_NONE;
+ pGetThemeEnumValue(theme.handle(), WP_CAPTION, isActive ? CS_ACTIVE : CS_INACTIVE, TMT_TEXTSHADOWTYPE, &result);
+ if (result != TST_NONE) {
+ COLORREF textShadowRef;
+ pGetThemeColor(theme.handle(), WP_CAPTION, isActive ? CS_ACTIVE : CS_INACTIVE, TMT_TEXTSHADOWCOLOR, &textShadowRef);
+ QColor textShadow = qRgb(GetRValue(textShadowRef), GetGValue(textShadowRef), GetBValue(textShadowRef));
+ p->setPen(textShadow);
+ p->drawText(ir.x() + 3, ir.y() + 2, ir.width() - 1, ir.height(),
+ Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine, tb->text);
+ }
+ COLORREF captionText = GetSysColor(isActive ? COLOR_CAPTIONTEXT : COLOR_INACTIVECAPTIONTEXT);
+ QColor textColor = qRgb(GetRValue(captionText), GetGValue(captionText), GetBValue(captionText));
+ p->setPen(textColor);
+ p->drawText(ir.x() + 2, ir.y() + 1, ir.width() - 2, ir.height(),
+ Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine, tb->text);
+ }
+ if (sub & SC_TitleBarSysMenu && tb->titleBarFlags & Qt::WindowSystemMenuHint) {
+ theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarSysMenu, widget);
+ partId = WP_SYSBUTTON;
+ if ((widget && !widget->isEnabled()) || !isActive)
+ stateId = SBS_DISABLED;
+ else if (option->activeSubControls == SC_TitleBarSysMenu && (option->state & State_Sunken))
+ stateId = SBS_PUSHED;
+ else if (option->activeSubControls == SC_TitleBarSysMenu && (option->state & State_MouseOver))
+ stateId = SBS_HOT;
+ else
+ stateId = SBS_NORMAL;
+ if (!tb->icon.isNull()) {
+ tb->icon.paint(p, theme.rect);
+ } else {
+ theme.partId = partId;
+ theme.stateId = stateId;
+ SIZE sz;
+ pGetThemePartSize(theme.handle(), qt_win_display_dc(), theme.partId, theme.stateId, 0, TS_TRUE, &sz);
+ if (sz.cx == 0 || sz.cy == 0) {
+ int iconSize = proxy()->pixelMetric(PM_SmallIconSize, tb, widget);
+ QPixmap pm = proxy()->standardIcon(SP_TitleBarMenuButton, tb, widget).pixmap(iconSize, iconSize);
+ p->save();
+ drawItemPixmap(p, theme.rect, Qt::AlignCenter, pm);
+ p->restore();
+ } else {
+ d->drawBackground(theme);
+ }
+ }
+ }
+
+ if (sub & SC_TitleBarMinButton && tb->titleBarFlags & Qt::WindowMinimizeButtonHint
+ && !(tb->titleBarState & Qt::WindowMinimized)) {
+ theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarMinButton, widget);
+ partId = WP_MINBUTTON;
+ if (widget && !widget->isEnabled())
+ stateId = MINBS_DISABLED;
+ else if (option->activeSubControls == SC_TitleBarMinButton && (option->state & State_Sunken))
+ stateId = MINBS_PUSHED;
+ else if (option->activeSubControls == SC_TitleBarMinButton && (option->state & State_MouseOver))
+ stateId = MINBS_HOT;
+ else if (!isActive)
+ stateId = MINBS_INACTIVE;
+ else
+ stateId = MINBS_NORMAL;
+ theme.partId = partId;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+ }
+ if (sub & SC_TitleBarMaxButton && tb->titleBarFlags & Qt::WindowMaximizeButtonHint
+ && !(tb->titleBarState & Qt::WindowMaximized)) {
+ theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarMaxButton, widget);
+ partId = WP_MAXBUTTON;
+ if (widget && !widget->isEnabled())
+ stateId = MAXBS_DISABLED;
+ else if (option->activeSubControls == SC_TitleBarMaxButton && (option->state & State_Sunken))
+ stateId = MAXBS_PUSHED;
+ else if (option->activeSubControls == SC_TitleBarMaxButton && (option->state & State_MouseOver))
+ stateId = MAXBS_HOT;
+ else if (!isActive)
+ stateId = MAXBS_INACTIVE;
+ else
+ stateId = MAXBS_NORMAL;
+ theme.partId = partId;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+ }
+ if (sub & SC_TitleBarContextHelpButton
+ && tb->titleBarFlags & Qt::WindowContextHelpButtonHint) {
+ theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarContextHelpButton, widget);
+ partId = WP_HELPBUTTON;
+ if (widget && !widget->isEnabled())
+ stateId = MINBS_DISABLED;
+ else if (option->activeSubControls == SC_TitleBarContextHelpButton && (option->state & State_Sunken))
+ stateId = MINBS_PUSHED;
+ else if (option->activeSubControls == SC_TitleBarContextHelpButton && (option->state & State_MouseOver))
+ stateId = MINBS_HOT;
+ else if (!isActive)
+ stateId = MINBS_INACTIVE;
+ else
+ stateId = MINBS_NORMAL;
+ theme.partId = partId;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+ }
+ bool drawNormalButton = (sub & SC_TitleBarNormalButton)
+ && (((tb->titleBarFlags & Qt::WindowMinimizeButtonHint)
+ && (tb->titleBarState & Qt::WindowMinimized))
+ || ((tb->titleBarFlags & Qt::WindowMaximizeButtonHint)
+ && (tb->titleBarState & Qt::WindowMaximized)));
+ if (drawNormalButton) {
+ theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarNormalButton, widget);
+ partId = WP_RESTOREBUTTON;
+ if (widget && !widget->isEnabled())
+ stateId = RBS_DISABLED;
+ else if (option->activeSubControls == SC_TitleBarNormalButton && (option->state & State_Sunken))
+ stateId = RBS_PUSHED;
+ else if (option->activeSubControls == SC_TitleBarNormalButton && (option->state & State_MouseOver))
+ stateId = RBS_HOT;
+ else if (!isActive)
+ stateId = RBS_INACTIVE;
+ else
+ stateId = RBS_NORMAL;
+ theme.partId = partId;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+ }
+ if (sub & SC_TitleBarShadeButton && tb->titleBarFlags & Qt::WindowShadeButtonHint
+ && !(tb->titleBarState & Qt::WindowMinimized)) {
+ theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarShadeButton, widget);
+ partId = WP_MINBUTTON;
+ if (widget && !widget->isEnabled())
+ stateId = MINBS_DISABLED;
+ else if (option->activeSubControls == SC_TitleBarShadeButton && (option->state & State_Sunken))
+ stateId = MINBS_PUSHED;
+ else if (option->activeSubControls == SC_TitleBarShadeButton && (option->state & State_MouseOver))
+ stateId = MINBS_HOT;
+ else if (!isActive)
+ stateId = MINBS_INACTIVE;
+ else
+ stateId = MINBS_NORMAL;
+ theme.partId = partId;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+ }
+ if (sub & SC_TitleBarUnshadeButton && tb->titleBarFlags & Qt::WindowShadeButtonHint
+ && tb->titleBarState & Qt::WindowMinimized) {
+ theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarUnshadeButton, widget);
+ partId = WP_RESTOREBUTTON;
+ if (widget && !widget->isEnabled())
+ stateId = RBS_DISABLED;
+ else if (option->activeSubControls == SC_TitleBarUnshadeButton && (option->state & State_Sunken))
+ stateId = RBS_PUSHED;
+ else if (option->activeSubControls == SC_TitleBarUnshadeButton && (option->state & State_MouseOver))
+ stateId = RBS_HOT;
+ else if (!isActive)
+ stateId = RBS_INACTIVE;
+ else
+ stateId = RBS_NORMAL;
+ theme.partId = partId;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+ }
+ if (sub & SC_TitleBarCloseButton && tb->titleBarFlags & Qt::WindowSystemMenuHint) {
+ theme.rect = proxy()->subControlRect(CC_TitleBar, option, SC_TitleBarCloseButton, widget);
+ //partId = titlebar->testWFlags(Qt::WA_WState_Tool) ? WP_SMALLCLOSEBUTTON : WP_CLOSEBUTTON;
+ partId = WP_CLOSEBUTTON;
+ if (widget && !widget->isEnabled())
+ stateId = CBS_DISABLED;
+ else if (option->activeSubControls == SC_TitleBarCloseButton && (option->state & State_Sunken))
+ stateId = CBS_PUSHED;
+ else if (option->activeSubControls == SC_TitleBarCloseButton && (option->state & State_MouseOver))
+ stateId = CBS_HOT;
+ else if (!isActive)
+ stateId = CBS_INACTIVE;
+ else
+ stateId = CBS_NORMAL;
+ theme.partId = partId;
+ theme.stateId = stateId;
+ d->drawBackground(theme);
+ }
+ }
+ }
+ break;
+
+#ifndef QT_NO_WORKSPACE
+ case CC_MdiControls:
+ {
+ QRect buttonRect;
+ XPThemeData theme(widget, p, QLatin1String("WINDOW"), WP_MDICLOSEBUTTON, CBS_NORMAL);
+
+ if (option->subControls & SC_MdiCloseButton) {
+ buttonRect = proxy()->subControlRect(CC_MdiControls, option, SC_MdiCloseButton, widget);
+ if (theme.isValid()) {
+ theme.partId = WP_MDICLOSEBUTTON;
+ theme.rect = buttonRect;
+ if (!(flags & State_Enabled))
+ theme.stateId = CBS_INACTIVE;
+ else if (flags & State_Sunken && (option->activeSubControls & SC_MdiCloseButton))
+ theme.stateId = CBS_PUSHED;
+ else if (flags & State_MouseOver && (option->activeSubControls & SC_MdiCloseButton))
+ theme.stateId = CBS_HOT;
+ else
+ theme.stateId = CBS_NORMAL;
+ d->drawBackground(theme);
+ }
+ }
+ if (option->subControls & SC_MdiNormalButton) {
+ buttonRect = proxy()->subControlRect(CC_MdiControls, option, SC_MdiNormalButton, widget);
+ if (theme.isValid()) {
+ theme.partId = WP_MDIRESTOREBUTTON;
+ theme.rect = buttonRect;
+ if (!(flags & State_Enabled))
+ theme.stateId = CBS_INACTIVE;
+ else if (flags & State_Sunken && (option->activeSubControls & SC_MdiNormalButton))
+ theme.stateId = CBS_PUSHED;
+ else if (flags & State_MouseOver && (option->activeSubControls & SC_MdiNormalButton))
+ theme.stateId = CBS_HOT;
+ else
+ theme.stateId = CBS_NORMAL;
+ d->drawBackground(theme);
+ }
+ }
+ if (option->subControls & QStyle::SC_MdiMinButton) {
+ buttonRect = proxy()->subControlRect(CC_MdiControls, option, SC_MdiMinButton, widget);
+ if (theme.isValid()) {
+ theme.partId = WP_MDIMINBUTTON;
+ theme.rect = buttonRect;
+ if (!(flags & State_Enabled))
+ theme.stateId = CBS_INACTIVE;
+ else if (flags & State_Sunken && (option->activeSubControls & SC_MdiMinButton))
+ theme.stateId = CBS_PUSHED;
+ else if (flags & State_MouseOver && (option->activeSubControls & SC_MdiMinButton))
+ theme.stateId = CBS_HOT;
+ else
+ theme.stateId = CBS_NORMAL;
+ d->drawBackground(theme);
+ }
+ }
+ }
+ break;
+#endif //QT_NO_WORKSPACE
+#ifndef QT_NO_DIAL
+ case CC_Dial:
+ if (const QStyleOptionSlider *dial = qstyleoption_cast<const QStyleOptionSlider *>(option))
+ QStyleHelper::drawDial(dial, p);
+ break;
+#endif // QT_NO_DIAL
+ default:
+ QWindowsStyle::drawComplexControl(cc, option, p, widget);
+ break;
+ }
+}
+
+/*! \reimp */
+int QWindowsXPStyle::pixelMetric(PixelMetric pm, const QStyleOption *option, const QWidget *widget) const
+{
+ if (!QWindowsXPStylePrivate::useXP())
+ return QWindowsStyle::pixelMetric(pm, option, widget);
+
+ int res = 0;
+ switch (pm) {
+ case PM_MenuBarPanelWidth:
+ res = 0;
+ break;
+
+ case PM_DefaultFrameWidth:
+ if (qobject_cast<const QListView*>(widget))
+ res = 2;
+ else
+ res = 1;
+ break;
+ case PM_MenuPanelWidth:
+ case PM_SpinBoxFrameWidth:
+ res = 1;
+ break;
+
+ case PM_TabBarTabOverlap:
+ case PM_MenuHMargin:
+ case PM_MenuVMargin:
+ res = 2;
+ break;
+
+ case PM_TabBarBaseOverlap:
+ if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(option)) {
+ switch (tab->shape) {
+ case QTabBar::RoundedNorth:
+ case QTabBar::TriangularNorth:
+ res = 1;
+ break;
+ case QTabBar::RoundedSouth:
+ case QTabBar::TriangularSouth:
+ res = 2;
+ break;
+ case QTabBar::RoundedEast:
+ case QTabBar::TriangularEast:
+ res = 3;
+ break;
+ case QTabBar::RoundedWest:
+ case QTabBar::TriangularWest:
+ res = 1;
+ break;
+ }
+ }
+ break;
+
+ case PM_SplitterWidth:
+ res = qMax(int(QStyleHelper::dpiScaled(5.)), QApplication::globalStrut().width());
+ break;
+
+ case PM_IndicatorWidth:
+ case PM_IndicatorHeight:
+ {
+ XPThemeData theme(widget, 0, QLatin1String("BUTTON"), BP_CHECKBOX, CBS_UNCHECKEDNORMAL);
+ if (theme.isValid()) {
+ SIZE size;
+ pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
+ res = (pm == PM_IndicatorWidth) ? size.cx : size.cy;
+ }
+ }
+ break;
+
+ case PM_ExclusiveIndicatorWidth:
+ case PM_ExclusiveIndicatorHeight:
+ {
+ XPThemeData theme(widget, 0, QLatin1String("BUTTON"), BP_RADIOBUTTON, RBS_UNCHECKEDNORMAL);
+ if (theme.isValid()) {
+ SIZE size;
+ pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
+ res = (pm == PM_ExclusiveIndicatorWidth) ? size.cx : size.cy;
+ }
+ }
+ break;
+
+ case PM_ProgressBarChunkWidth:
+ {
+ Qt::Orientation orient = Qt::Horizontal;
+ if (const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option))
+ orient = pb2->orientation;
+ XPThemeData theme(widget, 0, QLatin1String("PROGRESS"), (orient == Qt::Horizontal) ? PP_CHUNK : PP_CHUNKVERT);
+ if (theme.isValid()) {
+ SIZE size;
+ pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
+ res = (orient == Qt::Horizontal) ? size.cx : size.cy;
+ }
+ }
+ break;
+
+ case PM_SliderThickness:
+ {
+ XPThemeData theme(widget, 0, QLatin1String("TRACKBAR"), TKP_THUMB);
+ if (theme.isValid()) {
+ SIZE size;
+ pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
+ res = size.cy;
+ }
+ }
+ break;
+
+ case PM_TitleBarHeight:
+ {
+#ifdef QT3_SUPPORT
+ if (widget && widget->inherits("Q3DockWindowTitleBar")) {
+ res = GetSystemMetrics(SM_CYSMCAPTION) + GetSystemMetrics(SM_CXSIZEFRAME);
+ } else
+#endif
+ if (widget && (widget->windowType() == Qt::Tool))
+ res = GetSystemMetrics(SM_CYSMCAPTION) + GetSystemMetrics(SM_CXSIZEFRAME);
+ else
+ res = GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CXSIZEFRAME);
+ }
+ break;
+
+ case PM_MdiSubWindowFrameWidth:
+ {
+ XPThemeData theme(widget, 0, QLatin1String("WINDOW"), WP_FRAMELEFT, FS_ACTIVE);
+ if (theme.isValid()) {
+ SIZE size;
+ pGetThemePartSize(theme.handle(), 0, WP_FRAMELEFT, FS_ACTIVE, 0, TS_TRUE, &size);
+ res = size.cx-1;
+ }
+ }
+ break;
+
+ case PM_MdiSubWindowMinimizedWidth:
+ res = 160;
+ break;
+
+#ifndef QT_NO_TOOLBAR
+ case PM_ToolBarHandleExtent:
+ res = int(QStyleHelper::dpiScaled(8.));
+ break;
+
+#endif // QT_NO_TOOLBAR
+ case PM_DockWidgetFrameWidth:
+ {
+ XPThemeData theme(widget, 0, QLatin1String("WINDOW"), WP_SMALLFRAMERIGHT, FS_ACTIVE);
+ if (theme.isValid()) {
+ SIZE size;
+ pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
+ res = size.cx;
+ }
+ }
+ break;
+ case PM_DockWidgetSeparatorExtent:
+ res = int(QStyleHelper::dpiScaled(4.));
+ break;
+ case PM_DockWidgetTitleMargin:
+ res = int(QStyleHelper::dpiScaled(4.));
+ break;
+
+ case PM_ButtonShiftHorizontal:
+ case PM_ButtonShiftVertical:
+ if (qstyleoption_cast<const QStyleOptionToolButton *>(option))
+ res = 1;
+ else
+ res = 0;
+ break;
+
+ case PM_ButtonDefaultIndicator:
+ res = 0;
+ break;
+
+ default:
+ res = QWindowsStyle::pixelMetric(pm, option, widget);
+ }
+
+ return res;
+}
+
+/*
+ This function is used by subControlRect to check if a button
+ should be drawn for the given subControl given a set of window flags.
+*/
+static bool buttonVisible(const QStyle::SubControl sc, const QStyleOptionTitleBar *tb){
+
+ bool isMinimized = tb->titleBarState & Qt::WindowMinimized;
+ bool isMaximized = tb->titleBarState & Qt::WindowMaximized;
+ const uint flags = tb->titleBarFlags;
+ bool retVal = false;
+ switch (sc) {
+ case QStyle::SC_TitleBarContextHelpButton:
+ if (flags & Qt::WindowContextHelpButtonHint)
+ retVal = true;
+ break;
+ case QStyle::SC_TitleBarMinButton:
+ if (!isMinimized && (flags & Qt::WindowMinimizeButtonHint))
+ retVal = true;
+ break;
+ case QStyle::SC_TitleBarNormalButton:
+ if (isMinimized && (flags & Qt::WindowMinimizeButtonHint))
+ retVal = true;
+ else if (isMaximized && (flags & Qt::WindowMaximizeButtonHint))
+ retVal = true;
+ break;
+ case QStyle::SC_TitleBarMaxButton:
+ if (!isMaximized && (flags & Qt::WindowMaximizeButtonHint))
+ retVal = true;
+ break;
+ case QStyle::SC_TitleBarShadeButton:
+ if (!isMinimized && flags & Qt::WindowShadeButtonHint)
+ retVal = true;
+ break;
+ case QStyle::SC_TitleBarUnshadeButton:
+ if (isMinimized && flags & Qt::WindowShadeButtonHint)
+ retVal = true;
+ break;
+ case QStyle::SC_TitleBarCloseButton:
+ if (flags & Qt::WindowSystemMenuHint)
+ retVal = true;
+ break;
+ case QStyle::SC_TitleBarSysMenu:
+ if (flags & Qt::WindowSystemMenuHint)
+ retVal = true;
+ break;
+ default :
+ retVal = true;
+ }
+ return retVal;
+}
+
+/*!
+ \reimp
+*/
+QRect QWindowsXPStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex *option,
+ SubControl subControl, const QWidget *widget) const
+{
+ if (!QWindowsXPStylePrivate::useXP())
+ return QWindowsStyle::subControlRect(cc, option, subControl, widget);
+
+ QRect rect;
+
+ switch (cc) {
+ case CC_TitleBar:
+ if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(option)) {
+ if (!buttonVisible(subControl, tb))
+ return rect;
+ const bool isToolTitle = false;
+ const int height = tb->rect.height();
+ const int width = tb->rect.width();
+ int buttonHeight = GetSystemMetrics(SM_CYSIZE) - 4;
+ int buttonWidth = GetSystemMetrics(SM_CXSIZE) - 4;
+ const int delta = buttonWidth + 2;
+ int controlTop = option->rect.bottom() - buttonHeight - 2;
+ const int frameWidth = proxy()->pixelMetric(PM_MdiSubWindowFrameWidth, option, widget);
+ const bool sysmenuHint = (tb->titleBarFlags & Qt::WindowSystemMenuHint) != 0;
+ const bool minimizeHint = (tb->titleBarFlags & Qt::WindowMinimizeButtonHint) != 0;
+ const bool maximizeHint = (tb->titleBarFlags & Qt::WindowMaximizeButtonHint) != 0;
+ const bool contextHint = (tb->titleBarFlags & Qt::WindowContextHelpButtonHint) != 0;
+ const bool shadeHint = (tb->titleBarFlags & Qt::WindowShadeButtonHint) != 0;
+ bool isMinimized = tb->titleBarState & Qt::WindowMinimized;
+ bool isMaximized = tb->titleBarState & Qt::WindowMaximized;
+ int offset = 0;
+
+ switch (subControl) {
+ case SC_TitleBarLabel:
+ rect = QRect(frameWidth, 0, width - (buttonWidth + frameWidth + 10), height);
+ if (isToolTitle) {
+ if (sysmenuHint) {
+ rect.adjust(0, 0, -buttonWidth - 3, 0);
+ }
+ if (minimizeHint || maximizeHint)
+ rect.adjust(0, 0, -buttonWidth - 2, 0);
+ } else {
+ if (sysmenuHint) {
+ const int leftOffset = height - 8;
+ rect.adjust(leftOffset, 0, 0, 0);
+ }
+ if (minimizeHint)
+ rect.adjust(0, 0, -buttonWidth - 2, 0);
+ if (maximizeHint)
+ rect.adjust(0, 0, -buttonWidth - 2, 0);
+ if (contextHint)
+ rect.adjust(0, 0, -buttonWidth - 2, 0);
+ if (shadeHint)
+ rect.adjust(0, 0, -buttonWidth - 2, 0);
+ }
+ break;
+
+ case SC_TitleBarContextHelpButton:
+ if (tb->titleBarFlags & Qt::WindowContextHelpButtonHint)
+ offset += delta;
+ //fall through
+ case SC_TitleBarMinButton:
+ if (!isMinimized && (tb->titleBarFlags & Qt::WindowMinimizeButtonHint))
+ offset += delta;
+ else if (subControl == SC_TitleBarMinButton)
+ break;
+ //fall through
+ case SC_TitleBarNormalButton:
+ if (isMinimized && (tb->titleBarFlags & Qt::WindowMinimizeButtonHint))
+ offset += delta;
+ else if (isMaximized && (tb->titleBarFlags & Qt::WindowMaximizeButtonHint))
+ offset += delta;
+ else if (subControl == SC_TitleBarNormalButton)
+ break;
+ //fall through
+ case SC_TitleBarMaxButton:
+ if (!isMaximized && (tb->titleBarFlags & Qt::WindowMaximizeButtonHint))
+ offset += delta;
+ else if (subControl == SC_TitleBarMaxButton)
+ break;
+ //fall through
+ case SC_TitleBarShadeButton:
+ if (!isMinimized && (tb->titleBarFlags & Qt::WindowShadeButtonHint))
+ offset += delta;
+ else if (subControl == SC_TitleBarShadeButton)
+ break;
+ //fall through
+ case SC_TitleBarUnshadeButton:
+ if (isMinimized && (tb->titleBarFlags & Qt::WindowShadeButtonHint))
+ offset += delta;
+ else if (subControl == SC_TitleBarUnshadeButton)
+ break;
+ //fall through
+ case SC_TitleBarCloseButton:
+ if (tb->titleBarFlags & Qt::WindowSystemMenuHint)
+ offset += delta;
+ else if (subControl == SC_TitleBarCloseButton)
+ break;
+
+ rect.setRect(width - offset - controlTop + 1, controlTop,
+ buttonWidth, buttonHeight);
+ break;
+
+ case SC_TitleBarSysMenu:
+ {
+ const int controlTop = 6;
+ const int controlHeight = height - controlTop - 3;
+ const int iconExtent = proxy()->pixelMetric(PM_SmallIconSize);
+ QSize iconSize = tb->icon.actualSize(QSize(iconExtent, iconExtent));
+ if (tb->icon.isNull())
+ iconSize = QSize(controlHeight, controlHeight);
+ int hPad = (controlHeight - iconSize.height())/2;
+ int vPad = (controlHeight - iconSize.width())/2;
+ rect = QRect(frameWidth + hPad, controlTop + vPad, iconSize.width(), iconSize.height());
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ case CC_ComboBox:
+ if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
+ int x = cmb->rect.x(), y = cmb->rect.y(), wi = cmb->rect.width(), he = cmb->rect.height();
+ int xpos = x;
+ xpos += wi - 1 - 16;
+
+ switch (subControl) {
+ case SC_ComboBoxFrame:
+ rect = cmb->rect;
+ break;
+
+ case SC_ComboBoxArrow:
+ rect = QRect(xpos, y+1, 16, he-2);
+ break;
+
+ case SC_ComboBoxEditField:
+ rect = QRect(x+2, y+2, wi-3-16, he-4);
+ break;
+
+ case SC_ComboBoxListBoxPopup:
+ rect = cmb->rect;
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
+#ifndef QT_NO_WORKSPACE
+ case CC_MdiControls:
+ {
+ int numSubControls = 0;
+ if (option->subControls & SC_MdiCloseButton)
+ ++numSubControls;
+ if (option->subControls & SC_MdiMinButton)
+ ++numSubControls;
+ if (option->subControls & SC_MdiNormalButton)
+ ++numSubControls;
+ if (numSubControls == 0)
+ break;
+
+ int buttonWidth = option->rect.width()/ numSubControls;
+ int offset = 0;
+ switch (subControl) {
+ case SC_MdiCloseButton:
+ // Only one sub control, no offset needed.
+ if (numSubControls == 1)
+ break;
+ offset += buttonWidth;
+ //FALL THROUGH
+ case SC_MdiNormalButton:
+ // No offset needed if
+ // 1) There's only one sub control
+ // 2) We have a close button and a normal button (offset already added in SC_MdiClose)
+ if (numSubControls == 1 || (numSubControls == 2 && !(option->subControls & SC_MdiMinButton)))
+ break;
+ if (option->subControls & SC_MdiNormalButton)
+ offset += buttonWidth;
+ break;
+ default:
+ break;
+ }
+ rect = QRect(offset, 0, buttonWidth, option->rect.height());
+ break;
+ }
+#endif // QT_NO_WORKSPACE
+
+ default:
+ rect = visualRect(option->direction, option->rect,
+ QWindowsStyle::subControlRect(cc, option, subControl, widget));
+ break;
+ }
+ return visualRect(option->direction, option->rect, rect);
+}
+
+/*!
+ \reimp
+*/
+QSize QWindowsXPStyle::sizeFromContents(ContentsType ct, const QStyleOption *option,
+ const QSize &contentsSize, const QWidget *widget) const
+{
+ if (!QWindowsXPStylePrivate::useXP())
+ return QWindowsStyle::sizeFromContents(ct, option, contentsSize, widget);
+
+ QSize sz(contentsSize);
+ switch (ct) {
+ case CT_LineEdit:
+ case CT_ComboBox:
+ {
+ XPThemeData buttontheme(widget, 0, QLatin1String("Button"));
+ HTHEME theme = buttontheme.handle();
+ MARGINS borderSize;
+ if (theme) {
+ int result = pGetThemeMargins(theme,
+ NULL,
+ BP_PUSHBUTTON,
+ PBS_NORMAL,
+ TMT_CONTENTMARGINS,
+ NULL,
+ &borderSize);
+ if (result == S_OK) {
+ sz += QSize(borderSize.cxLeftWidth + borderSize.cxRightWidth - 2,
+ borderSize.cyBottomHeight + borderSize.cyTopHeight - 2);
+ }
+ const int textMargins = 2*(proxy()->pixelMetric(PM_FocusFrameHMargin) + 1);
+ sz += QSize(qMax(pixelMetric(QStyle::PM_ScrollBarExtent, option, widget)
+ + textMargins, 23), 0); //arrow button
+ }
+ }
+ break;
+ case CT_SpinBox:
+ {
+ //Spinbox adds frame twice
+ sz = QWindowsStyle::sizeFromContents(ct, option, contentsSize, widget);
+ int border = proxy()->pixelMetric(PM_SpinBoxFrameWidth, option, widget);
+ sz -= QSize(2*border, 2*border);
+ }
+ break;
+ case CT_TabWidget:
+ sz += QSize(6, 6);
+ break;
+ case CT_Menu:
+ sz += QSize(1, 0);
+ break;
+#ifndef QT_NO_MENUBAR
+ case CT_MenuBarItem:
+ if (!sz.isEmpty())
+ sz += QSize(windowsItemHMargin * 5 + 1, 6);
+ break;
+#endif
+ case CT_MenuItem:
+ if (const QStyleOptionMenuItem *menuitem = qstyleoption_cast<const QStyleOptionMenuItem *>(option))
+ {
+ if (menuitem->menuItemType != QStyleOptionMenuItem::Separator) {
+ sz = QWindowsStyle::sizeFromContents(ct, option, sz, widget);
+ sz.setHeight(sz.height() - 2);
+ return sz;
+ }
+ }
+ sz = QWindowsStyle::sizeFromContents(ct, option, sz, widget);
+ break;
+
+ case CT_MdiControls:
+ if (const QStyleOptionComplex *styleOpt = qstyleoption_cast<const QStyleOptionComplex *>(option)) {
+ int width = 0;
+ if (styleOpt->subControls & SC_MdiMinButton)
+ width += 17 + 1;
+ if (styleOpt->subControls & SC_MdiNormalButton)
+ width += 17 + 1;
+ if (styleOpt->subControls & SC_MdiCloseButton)
+ width += 17 + 1;
+ sz = QSize(width, 19);
+ } else {
+ sz = QSize(54, 19);
+ }
+ break;
+
+ default:
+ sz = QWindowsStyle::sizeFromContents(ct, option, sz, widget);
+ break;
+ }
+
+ return sz;
+}
+
+
+/*! \reimp */
+int QWindowsXPStyle::styleHint(StyleHint hint, const QStyleOption *option, const QWidget *widget,
+ QStyleHintReturn *returnData) const
+{
+ QWindowsXPStylePrivate *d = const_cast<QWindowsXPStylePrivate*>(d_func());
+ if (!QWindowsXPStylePrivate::useXP())
+ return QWindowsStyle::styleHint(hint, option, widget, returnData);
+
+ int res = 0;
+ switch (hint) {
+
+ case SH_EtchDisabledText:
+ res = (qobject_cast<const QLabel*>(widget) != 0);
+ break;
+
+ case SH_SpinControls_DisableOnBounds:
+ res = 0;
+ break;
+
+ case SH_TitleBar_AutoRaise:
+ case SH_TitleBar_NoBorder:
+ res = 1;
+ break;
+
+ case SH_GroupBox_TextLabelColor:
+ if (!widget || (widget && widget->isEnabled()))
+ res = d->groupBoxTextColor;
+ else
+ res = d->groupBoxTextColorDisabled;
+ break;
+
+ case SH_Table_GridLineColor:
+ res = 0xC0C0C0;
+ break;
+
+ case SH_WindowFrame_Mask:
+ {
+ res = 1;
+ QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask *>(returnData);
+ const QStyleOptionTitleBar *titlebar = qstyleoption_cast<const QStyleOptionTitleBar *>(option);
+ if (mask && titlebar) {
+ // Note certain themes will not return the whole window frame but only the titlebar part when
+ // queried This function needs to return the entire window mask, hence we will only fetch the mask for the
+ // titlebar itself and add the remaining part of the window rect at the bottom.
+ int tbHeight = proxy()->pixelMetric(PM_TitleBarHeight, option, widget);
+ QRect titleBarRect = option->rect;
+ titleBarRect.setHeight(tbHeight);
+ XPThemeData themeData;
+ if (titlebar->titleBarState & Qt::WindowMinimized) {
+ themeData = XPThemeData(widget, 0, QLatin1String("WINDOW"), WP_MINCAPTION, CS_ACTIVE, titleBarRect);
+ } else
+ themeData = XPThemeData(widget, 0, QLatin1String("WINDOW"), WP_CAPTION, CS_ACTIVE, titleBarRect);
+ mask->region = d->region(themeData) +
+ QRect(0, tbHeight, option->rect.width(), option->rect.height() - tbHeight);
+ }
+ }
+ break;
+#ifndef QT_NO_RUBBERBAND
+ case SH_RubberBand_Mask:
+ if (qstyleoption_cast<const QStyleOptionRubberBand *>(option)) {
+ res = 0;
+ break;
+ }
+#endif // QT_NO_RUBBERBAND
+
+ case SH_ItemView_DrawDelegateFrame:
+ res = 1;
+ break;
+
+ default:
+ res =QWindowsStyle::styleHint(hint, option, widget, returnData);
+ }
+
+ return res;
+}
+
+/*! \reimp */
+QPalette QWindowsXPStyle::standardPalette() const
+{
+ if (QWindowsXPStylePrivate::useXP() && QApplicationPrivate::sys_pal)
+ return *QApplicationPrivate::sys_pal;
+ else
+ return QWindowsStyle::standardPalette();
+}
+
+/*!
+ \reimp
+*/
+QPixmap QWindowsXPStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *option,
+ const QWidget *widget) const
+{
+ if (!QWindowsXPStylePrivate::useXP())
+ return QWindowsStyle::standardPixmap(standardPixmap, option, widget);
+
+ switch(standardPixmap) {
+ case SP_TitleBarMaxButton:
+ case SP_TitleBarCloseButton:
+ if (qstyleoption_cast<const QStyleOptionDockWidget *>(option))
+ {
+ if (widget && widget->isWindow()) {
+ XPThemeData theme(widget, 0, QLatin1String("WINDOW"), WP_SMALLCLOSEBUTTON, CBS_NORMAL);
+ if (theme.isValid()) {
+ SIZE sz;
+ pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &sz);
+ return QIcon(QWindowsStyle::standardPixmap(standardPixmap, option, widget)).pixmap(QSize(sz.cx, sz.cy));
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ return QWindowsStyle::standardPixmap(standardPixmap, option, widget);
+}
+
+/*!
+ \internal
+*/
+QIcon QWindowsXPStyle::standardIconImplementation(StandardPixmap standardIcon,
+ const QStyleOption *option,
+ const QWidget *widget) const
+{
+ if (!QWindowsXPStylePrivate::useXP()) {
+ return QWindowsStyle::standardIconImplementation(standardIcon, option, widget);
+ }
+
+ QWindowsXPStylePrivate *d = const_cast<QWindowsXPStylePrivate*>(d_func());
+ switch(standardIcon) {
+ case SP_TitleBarMaxButton:
+ if (qstyleoption_cast<const QStyleOptionDockWidget *>(option))
+ {
+ if (d->dockFloat.isNull()) {
+ XPThemeData themeSize(0, 0, QLatin1String("WINDOW"), WP_SMALLCLOSEBUTTON, CBS_NORMAL);
+ XPThemeData theme(0, 0, QLatin1String("WINDOW"), WP_MAXBUTTON, MAXBS_NORMAL);
+ if (theme.isValid()) {
+ SIZE size;
+ pGetThemePartSize(themeSize.handle(), 0, themeSize.partId, themeSize.stateId, 0, TS_TRUE, &size);
+ QPixmap pm = QPixmap(size.cx, size.cy);
+ pm.fill(Qt::transparent);
+ QPainter p(&pm);
+ theme.painter = &p;
+ theme.rect = QRect(0, 0, size.cx, size.cy);
+ d->drawBackground(theme);
+ d->dockFloat.addPixmap(pm, QIcon::Normal, QIcon::Off); // Normal
+ pm.fill(Qt::transparent);
+ theme.stateId = MAXBS_PUSHED;
+ d->drawBackground(theme);
+ d->dockFloat.addPixmap(pm, QIcon::Normal, QIcon::On); // Pressed
+ pm.fill(Qt::transparent);
+ theme.stateId = MAXBS_HOT;
+ d->drawBackground(theme);
+ d->dockFloat.addPixmap(pm, QIcon::Active, QIcon::Off); // Hover
+ pm.fill(Qt::transparent);
+ theme.stateId = MAXBS_INACTIVE;
+ d->drawBackground(theme);
+ d->dockFloat.addPixmap(pm, QIcon::Disabled, QIcon::Off); // Disabled
+ }
+ }
+ if (widget && widget->isWindow())
+ return d->dockFloat;
+
+ }
+ break;
+ case SP_TitleBarCloseButton:
+ if (qstyleoption_cast<const QStyleOptionDockWidget *>(option))
+ {
+ if (d->dockClose.isNull()) {
+ XPThemeData theme(0, 0, QLatin1String("WINDOW"), WP_SMALLCLOSEBUTTON, CBS_NORMAL);
+ if (theme.isValid()) {
+ SIZE size;
+ pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size);
+ QPixmap pm = QPixmap(size.cx, size.cy);
+ pm.fill(Qt::transparent);
+ QPainter p(&pm);
+ theme.painter = &p;
+ theme.partId = WP_CLOSEBUTTON; // ####
+ theme.rect = QRect(0, 0, size.cx, size.cy);
+ d->drawBackground(theme);
+ d->dockClose.addPixmap(pm, QIcon::Normal, QIcon::Off); // Normal
+ pm.fill(Qt::transparent);
+ theme.stateId = CBS_PUSHED;
+ d->drawBackground(theme);
+ d->dockClose.addPixmap(pm, QIcon::Normal, QIcon::On); // Pressed
+ pm.fill(Qt::transparent);
+ theme.stateId = CBS_HOT;
+ d->drawBackground(theme);
+ d->dockClose.addPixmap(pm, QIcon::Active, QIcon::Off); // Hover
+ pm.fill(Qt::transparent);
+ theme.stateId = CBS_INACTIVE;
+ d->drawBackground(theme);
+ d->dockClose.addPixmap(pm, QIcon::Disabled, QIcon::Off); // Disabled
+ }
+ }
+ if (widget && widget->isWindow())
+ return d->dockClose;
+ }
+ break;
+ case SP_TitleBarNormalButton:
+ if (qstyleoption_cast<const QStyleOptionDockWidget *>(option))
+ {
+ if (d->dockFloat.isNull()) {
+ XPThemeData themeSize(0, 0, QLatin1String("WINDOW"), WP_SMALLCLOSEBUTTON, CBS_NORMAL);
+ XPThemeData theme(0, 0, QLatin1String("WINDOW"), WP_RESTOREBUTTON, RBS_NORMAL);
+ if (theme.isValid()) {
+ SIZE size;
+ pGetThemePartSize(themeSize.handle(), 0, themeSize.partId, themeSize.stateId, 0, TS_TRUE, &size);
+ QPixmap pm = QPixmap(size.cx, size.cy);
+ pm.fill(Qt::transparent);
+ QPainter p(&pm);
+ theme.painter = &p;
+ theme.rect = QRect(0, 0, size.cx, size.cy);
+ d->drawBackground(theme);
+ d->dockFloat.addPixmap(pm, QIcon::Normal, QIcon::Off); // Normal
+ pm.fill(Qt::transparent);
+ theme.stateId = RBS_PUSHED;
+ d->drawBackground(theme);
+ d->dockFloat.addPixmap(pm, QIcon::Normal, QIcon::On); // Pressed
+ pm.fill(Qt::transparent);
+ theme.stateId = RBS_HOT;
+ d->drawBackground(theme);
+ d->dockFloat.addPixmap(pm, QIcon::Active, QIcon::Off); // Hover
+ pm.fill(Qt::transparent);
+ theme.stateId = RBS_INACTIVE;
+ d->drawBackground(theme);
+ d->dockFloat.addPixmap(pm, QIcon::Disabled, QIcon::Off); // Disabled
+ }
+ }
+ if (widget && widget->isWindow())
+ return d->dockFloat;
+
+ }
+ break;
+ default:
+ break;
+ }
+
+ return QWindowsStyle::standardIconImplementation(standardIcon, option, widget);
+}
+
+/*!
+ \internal
+
+ Constructs a QWindowsXPStyle object.
+*/
+QWindowsXPStyle::QWindowsXPStyle(QWindowsXPStylePrivate &dd) : QWindowsStyle(dd)
+{
+}
+
+
+// Debugging code ---------------------------------------------------------------------[ START ]---
+// The code for this point on is not compiled by default, but only used as assisting
+// debugging code when you uncomment the DEBUG_XP_STYLE define at the top of the file.
+
+#ifdef DEBUG_XP_STYLE
+// The schema file expects these to be defined by the user.
+#define TMT_ENUMDEF 8
+#define TMT_ENUMVAL TEXT('A')
+#define TMT_ENUM TEXT('B')
+#define SCHEMA_STRINGS // For 2nd pass on schema file
+QT_BEGIN_INCLUDE_NAMESPACE
+#include <tmschema.h>
+QT_END_INCLUDE_NAMESPACE
+
+// A property's value, type and name combo
+struct PropPair {
+ int propValue;
+ int propType;
+ LPCWSTR propName;
+};
+
+// Operator for sorting of PropPairs
+bool operator<(PropPair a, PropPair b) {
+ return wcscmp(a.propName, b.propName) < 0;
+}
+
+// Our list of all possible properties
+static QList<PropPair> all_props;
+
+
+/*! \internal
+ Dumps a portion of the full native DIB section double buffer.
+ The DIB section double buffer is only used when doing special
+ transformations to the theme part, or when the real double
+ buffer in the paintengine does not have an HDC we may use
+ directly.
+ Since we cannot rely on the pixel data we get from Microsoft
+ when drawing into the DIB section, we use this function to
+ see the actual data we got, and can determin the appropriate
+ action.
+*/
+void QWindowsXPStylePrivate::dumpNativeDIB(int w, int h)
+{
+ if (w && h) {
+ static int pCount = 0;
+ DWORD *bufPix = (DWORD*)bufferPixels;
+
+ char *bufferDump = new char[bufferH * bufferW * 16];
+ char *bufferPos = bufferDump;
+
+ memset(bufferDump, 0, sizeof(bufferDump));
+ bufferPos += sprintf(bufferPos, "const int pixelBufferW%d = %d;\n", pCount, w);
+ bufferPos += sprintf(bufferPos, "const int pixelBufferH%d = %d;\n", pCount, h);
+ bufferPos += sprintf(bufferPos, "const unsigned DWORD pixelBuffer%d[] = {", pCount);
+ for (int iy = 0; iy < h; ++iy) {
+ bufferPos += sprintf(bufferPos, "\n ");
+ bufPix = (DWORD*)(bufferPixels + (iy * bufferW * 4));
+ for (int ix = 0; ix < w; ++ix) {
+ bufferPos += sprintf(bufferPos, "0x%08x, ", *bufPix);
+ ++bufPix;
+ }
+ }
+ bufferPos += sprintf(bufferPos, "\n};\n\n");
+ printf(bufferDump);
+
+ delete[] bufferDump;
+ ++pCount;
+ }
+}
+
+/*! \internal
+ Shows the value of a given property for a part.
+*/
+static void showProperty(XPThemeData &themeData, const PropPair &prop)
+{
+ PROPERTYORIGIN origin = PO_NOTFOUND;
+ pGetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &origin);
+ const char *originStr;
+ switch(origin) {
+ case PO_STATE:
+ originStr = "State ";
+ break;
+ case PO_PART:
+ originStr = "Part ";
+ break;
+ case PO_CLASS:
+ originStr = "Class ";
+ break;
+ case PO_GLOBAL:
+ originStr = "Globl ";
+ break;
+ case PO_NOTFOUND:
+ default:
+ originStr = "Unkwn ";
+ break;
+ }
+
+ switch(prop.propType) {
+ case TMT_STRING:
+ {
+ wchar_t buffer[512];
+ pGetThemeString(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, buffer, 512);
+ printf(" (%sString) %-20S: %S\n", originStr, prop.propName, buffer);
+ }
+ break;
+ case TMT_ENUM:
+ {
+ int result = -1;
+ pGetThemeEnumValue(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &result);
+ printf(" (%sEnum) %-20S: %d\n", originStr, prop.propName, result);
+ }
+ break;
+ case TMT_INT:
+ {
+ int result = -1;
+ pGetThemeInt(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &result);
+ printf(" (%sint) %-20S: %d\n", originStr, prop.propName, result);
+ }
+ break;
+ case TMT_BOOL:
+ {
+ BOOL result = false;
+ pGetThemeBool(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &result);
+ printf(" (%sbool) %-20S: %d\n", originStr, prop.propName, result);
+ }
+ break;
+ case TMT_COLOR:
+ {
+ COLORREF result = 0;
+ pGetThemeColor(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &result);
+ printf(" (%scolor) %-20S: 0x%08X\n", originStr, prop.propName, result);
+ }
+ break;
+ case TMT_MARGINS:
+ {
+ MARGINS result;
+ memset(&result, 0, sizeof(result));
+ pGetThemeMargins(themeData.handle(), 0, themeData.partId, themeData.stateId, prop.propValue, 0, &result);
+ printf(" (%smargins) %-20S: (%d, %d, %d, %d)\n", originStr,
+ prop.propName, result.cxLeftWidth, result.cyTopHeight, result.cxRightWidth, result.cyBottomHeight);
+ }
+ break;
+ case TMT_FILENAME:
+ {
+ wchar_t buffer[512];
+ pGetThemeFilename(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, buffer, 512);
+ printf(" (%sfilename)%-20S: %S\n", originStr, prop.propName, buffer);
+ }
+ break;
+ case TMT_SIZE:
+ {
+ SIZE result1;
+ SIZE result2;
+ SIZE result3;
+ memset(&result1, 0, sizeof(result1));
+ memset(&result2, 0, sizeof(result2));
+ memset(&result3, 0, sizeof(result3));
+ pGetThemePartSize(themeData.handle(), 0, themeData.partId, themeData.stateId, 0, TS_MIN, &result1);
+ pGetThemePartSize(themeData.handle(), 0, themeData.partId, themeData.stateId, 0, TS_TRUE, &result2);
+ pGetThemePartSize(themeData.handle(), 0, themeData.partId, themeData.stateId, 0, TS_DRAW, &result3);
+ printf(" (%ssize) %-20S: Min (%d, %d), True(%d, %d), Draw(%d, %d)\n", originStr, prop.propName,
+ result1.cx, result1.cy, result2.cx, result2.cy, result3.cx, result3.cy);
+ }
+ break;
+ case TMT_POSITION:
+ {
+ POINT result;
+ memset(&result, 0, sizeof(result));
+ pGetThemePosition(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &result);
+ printf(" (%sPosition)%-20S: (%d, %d)\n", originStr, prop.propName, result.x, result.y);
+ }
+ break;
+ case TMT_RECT:
+ {
+ RECT result;
+ memset(&result, 0, sizeof(result));
+ pGetThemeRect(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &result);
+ printf(" (%sRect) %-20S: (%d, %d, %d, %d)\n", originStr, prop.propName, result.left, result.top, result.right, result.bottom);
+ }
+ break;
+ case TMT_FONT:
+ {
+ LOGFONT result;
+ memset(&result, 0, sizeof(result));
+ pGetThemeFont(themeData.handle(), 0, themeData.partId, themeData.stateId, prop.propValue, &result);
+ printf(" (%sFont) %-20S: %S height(%d) width(%d) weight(%d)\n", originStr, prop.propName,
+ result.lfFaceName, result.lfHeight, result.lfWidth, result.lfWeight);
+ }
+ break;
+ case TMT_INTLIST:
+ {
+ INTLIST result;
+ memset(&result, 0, sizeof(result));
+ pGetThemeIntList(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &result);
+ printf(" (%sInt list)%-20S: { ", originStr, prop.propName);
+ for (int i = 0; i < result.iValueCount; ++i)
+ printf("%d ", result.iValues[i]);
+ printf("}\n");
+ }
+ break;
+ default:
+ printf(" %s%S : Unknown property type (%d)!\n", originStr, prop.propName, prop.propType);
+ }
+}
+
+/*! \internal
+ Dump all valid properties for a part.
+ If it's the first time this function is called, then the name,
+ enum value and documentation of all properties are shown, as
+ well as all global properties.
+*/
+void QWindowsXPStylePrivate::showProperties(XPThemeData &themeData)
+{
+ if (!all_props.count()) {
+ const TMSCHEMAINFO *infoTable = GetSchemaInfo();
+ for (int i = 0; i < infoTable->iPropCount; ++i) {
+ int propType = infoTable->pPropTable[i].bPrimVal;
+ int propValue = infoTable->pPropTable[i].sEnumVal;
+ LPCWSTR propName = infoTable->pPropTable[i].pszName;
+
+ switch(propType) {
+ case TMT_ENUMDEF:
+ case TMT_ENUMVAL:
+ continue;
+ default:
+ if (propType != propValue) {
+ PropPair prop;
+ prop.propValue = propValue;
+ prop.propName = propName;
+ prop.propType = propType;
+ all_props.append(prop);
+ }
+ }
+ }
+ qSort(all_props);
+
+ {// List all properties
+ printf("part properties count = %d:\n", all_props.count());
+ printf(" Enum Property Name Description\n");
+ printf("-----------------------------------------------------------\n");
+ wchar_t themeName[256];
+ pGetCurrentThemeName(themeName, 256, 0, 0, 0, 0);
+ for (int j = 0; j < all_props.count(); ++j) {
+ PropPair prop = all_props.at(j);
+ wchar_t buf[500];
+ pGetThemeDocumentationProperty(themeName, prop.propName, buf, 500);
+ printf("%3d: (%4d) %-20S %S\n", j, prop.propValue, prop.propName, buf);
+ }
+ }
+
+ {// Show Global values
+ printf("Global Properties:\n");
+ for (int j = 0; j < all_props.count(); ++j) {
+ PropPair prop = all_props.at(j);
+ PROPERTYORIGIN origin = PO_NOTFOUND;
+ pGetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &origin);
+ if (origin == PO_GLOBAL) {
+ showProperty(themeData, prop);
+ }
+ }
+ }
+ }
+
+ for (int j = 0; j < all_props.count(); ++j) {
+ PropPair prop = all_props.at(j);
+ PROPERTYORIGIN origin = PO_NOTFOUND;
+ pGetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, prop.propValue, &origin);
+ if (origin != PO_NOTFOUND)
+ {
+ showProperty(themeData, prop);
+ }
+ }
+}
+#endif
+// Debugging code -----------------------------------------------------------------------[ END ]---
+
+
+QT_END_NAMESPACE
+
+#endif //QT_NO_WINDOWSXP
diff --git a/src/widgets/styles/qwindowsxpstyle.h b/src/widgets/styles/qwindowsxpstyle.h
new file mode 100644
index 0000000000..1cfd16479b
--- /dev/null
+++ b/src/widgets/styles/qwindowsxpstyle.h
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSXPSTYLE_H
+#define QWINDOWSXPSTYLE_H
+
+#include <QtWidgets/qwindowsstyle.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#if !defined(QT_NO_STYLE_WINDOWSXP)
+
+class QWindowsXPStylePrivate;
+class Q_WIDGETS_EXPORT QWindowsXPStyle : public QWindowsStyle
+{
+ Q_OBJECT
+public:
+ QWindowsXPStyle();
+ QWindowsXPStyle(QWindowsXPStylePrivate &dd);
+ ~QWindowsXPStyle();
+
+ void unpolish(QApplication*);
+ void polish(QApplication*);
+ void polish(QWidget*);
+ void polish(QPalette&);
+ void unpolish(QWidget*);
+
+ void drawPrimitive(PrimitiveElement pe, const QStyleOption *option, QPainter *p,
+ const QWidget *widget = 0) const;
+ void drawControl(ControlElement element, const QStyleOption *option, QPainter *p,
+ const QWidget *wwidget = 0) const;
+ QRect subElementRect(SubElement r, const QStyleOption *option, const QWidget *widget = 0) const;
+ QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *option, SubControl sc,
+ const QWidget *widget = 0) const;
+ void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *option, QPainter *p,
+ const QWidget *widget = 0) const;
+ QSize sizeFromContents(ContentsType ct, const QStyleOption *option, const QSize &contentsSize,
+ const QWidget *widget = 0) const;
+ int pixelMetric(PixelMetric pm, const QStyleOption *option = 0,
+ const QWidget *widget = 0) const;
+ int styleHint(StyleHint hint, const QStyleOption *option = 0, const QWidget *widget = 0,
+ QStyleHintReturn *returnData = 0) const;
+
+ QPalette standardPalette() const;
+ QPixmap standardPixmap(StandardPixmap standardIcon, const QStyleOption *option,
+ const QWidget *widget = 0) const;
+
+protected Q_SLOTS:
+ QIcon standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *option,
+ const QWidget *widget = 0) const;
+
+private:
+ Q_DISABLE_COPY(QWindowsXPStyle)
+ Q_DECLARE_PRIVATE(QWindowsXPStyle)
+ friend class QStyleFactory;
+ void *reserved;
+};
+
+#endif // QT_NO_STYLE_WINDOWSXP
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QWINDOWSXPSTYLE_H
diff --git a/src/widgets/styles/qwindowsxpstyle_p.h b/src/widgets/styles/qwindowsxpstyle_p.h
new file mode 100644
index 0000000000..05ab2ec2e4
--- /dev/null
+++ b/src/widgets/styles/qwindowsxpstyle_p.h
@@ -0,0 +1,356 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSXPSTYLE_P_H
+#define QWINDOWSXPSTYLE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qwindowsxpstyle.h"
+#include "qwindowsstyle_p.h"
+#include <qmap.h>
+#include <qt_windows.h>
+
+// Note, these tests are duplicated in qwizard_win.cpp.
+#ifdef Q_CC_GNU
+# include <w32api.h>
+# if (__W32API_MAJOR_VERSION >= 3 || (__W32API_MAJOR_VERSION == 2 && __W32API_MINOR_VERSION >= 5))
+# ifdef _WIN32_WINNT
+# undef _WIN32_WINNT
+# endif
+# define _WIN32_WINNT 0x0501
+# include <commctrl.h>
+# endif
+#endif
+
+#include <uxtheme.h>
+
+#if WINVER >= 0x0600
+#include <vssym32.h>
+#else
+#include <tmschema.h>
+#endif
+
+#include <limits.h>
+
+QT_BEGIN_NAMESPACE
+
+// Older Platform SDKs do not have the extended DrawThemeBackgroundEx
+// function. We add the needed parts here, and use the extended
+// function dynamically, if available in uxtheme.dll. Else, we revert
+// back to using the DrawThemeBackground function.
+#ifndef DTBG_OMITBORDER
+# ifndef DTBG_CLIPRECT
+# define DTBG_CLIPRECT 0x00000001
+# endif
+# ifndef DTBG_DRAWSOLID
+# define DTBG_DRAWSOLID 0x00000002
+# endif
+# ifndef DTBG_OMITBORDER
+# define DTBG_OMITBORDER 0x00000004
+# endif
+# ifndef DTBG_OMITCONTENT
+# define DTBG_OMITCONTENT 0x00000008
+# endif
+# ifndef DTBG_COMPUTINGREGION
+# define DTBG_COMPUTINGREGION 0x00000010
+# endif
+# ifndef DTBG_MIRRORDC
+# define DTBG_MIRRORDC 0x00000020
+# endif
+ typedef struct _DTBGOPTS
+ {
+ DWORD dwSize;
+ DWORD dwFlags;
+ RECT rcClip;
+ } DTBGOPTS, *PDTBGOPTS;
+#endif // _DTBGOPTS
+
+// Undefined for some compile environments
+#ifndef TMT_TEXTCOLOR
+# define TMT_TEXTCOLOR 3803
+#endif
+#ifndef TMT_BORDERCOLORHINT
+# define TMT_BORDERCOLORHINT 3822
+#endif
+#ifndef TMT_BORDERSIZE
+# define TMT_BORDERSIZE 2403
+#endif
+#ifndef TMT_BORDERONLY
+# define TMT_BORDERONLY 2203
+#endif
+#ifndef TMT_TRANSPARENTCOLOR
+# define TMT_TRANSPARENTCOLOR 3809
+#endif
+#ifndef TMT_CAPTIONMARGINS
+# define TMT_CAPTIONMARGINS 3603
+#endif
+#ifndef TMT_CONTENTMARGINS
+# define TMT_CONTENTMARGINS 3602
+#endif
+#ifndef TMT_SIZINGMARGINS
+# define TMT_SIZINGMARGINS 3601
+#endif
+#ifndef TMT_GLYPHTYPE
+# define TMT_GLYPHTYPE 4012
+#endif
+#ifndef TMT_BGTYPE
+# define TMT_BGTYPE 4001
+#endif
+#ifndef TMT_TEXTSHADOWTYPE
+# define TMT_TEXTSHADOWTYPE 4010
+#endif
+#ifndef TMT_BORDERCOLOR
+# define TMT_BORDERCOLOR 3801
+#endif
+#ifndef BT_IMAGEFILE
+# define BT_IMAGEFILE 0
+#endif
+#ifndef BT_BORDERFILL
+# define BT_BORDERFILL 1
+#endif
+#ifndef BT_NONE
+# define BT_NONE 2
+#endif
+#ifndef TMT_FILLCOLOR
+# define TMT_FILLCOLOR 3802
+#endif
+#ifndef TMT_PROGRESSCHUNKSIZE
+# define TMT_PROGRESSCHUNKSIZE 2411
+#endif
+
+// TMT_TEXTSHADOWCOLOR is wrongly defined in mingw
+#if TMT_TEXTSHADOWCOLOR != 3818
+#undef TMT_TEXTSHADOWCOLOR
+#define TMT_TEXTSHADOWCOLOR 3818
+#endif
+#ifndef TST_NONE
+# define TST_NONE 0
+#endif
+
+#ifndef GT_NONE
+# define GT_NONE 0
+#endif
+#ifndef GT_IMAGEGLYPH
+# define GT_IMAGEGLYPH 1
+#endif
+
+// These defines are missing from the tmschema, but still exist as
+// states for their parts
+#ifndef MINBS_INACTIVE
+#define MINBS_INACTIVE 5
+#endif
+#ifndef MAXBS_INACTIVE
+#define MAXBS_INACTIVE 5
+#endif
+#ifndef RBS_INACTIVE
+#define RBS_INACTIVE 5
+#endif
+#ifndef HBS_INACTIVE
+#define HBS_INACTIVE 5
+#endif
+#ifndef CBS_INACTIVE
+#define CBS_INACTIVE 5
+#endif
+
+// Uncomment define below to build debug assisting code, and output
+// #define DEBUG_XP_STYLE
+
+#if !defined(QT_NO_STYLE_WINDOWSXP)
+
+// Declarations -----------------------------------------------------------------------------------
+class XPThemeData
+{
+public:
+ XPThemeData(const QWidget *w = 0, QPainter *p = 0, const QString &theme = QString(),
+ int part = 0, int state = 0, const QRect &r = QRect())
+ : widget(w), painter(p), name(theme), htheme(0), partId(part), stateId(state),
+ mirrorHorizontally(false), mirrorVertically(false), noBorder(false),
+ noContent(false), rotate(0), rect(r)
+ {}
+
+ HRGN mask(QWidget *widget);
+ HTHEME handle();
+
+ RECT toRECT(const QRect &qr);
+ bool isValid();
+
+ const QWidget *widget;
+ QPainter *painter;
+ QString name;
+ HTHEME htheme;
+ int partId;
+ int stateId;
+
+ uint mirrorHorizontally : 1;
+ uint mirrorVertically : 1;
+ uint noBorder : 1;
+ uint noContent : 1;
+ uint rotate;
+ QRect rect;
+};
+
+struct ThemeMapKey {
+ QString name;
+ int partId;
+ int stateId;
+ bool noBorder;
+ bool noContent;
+
+ ThemeMapKey() : partId(-1), stateId(-1) {}
+ ThemeMapKey(const XPThemeData &data)
+ : name(data.name), partId(data.partId), stateId(data.stateId),
+ noBorder(data.noBorder), noContent(data.noContent) {}
+
+};
+
+inline uint qHash(const ThemeMapKey &key)
+{ return qHash(key.name) ^ key.partId ^ key.stateId; }
+
+inline bool operator==(const ThemeMapKey &k1, const ThemeMapKey &k2)
+{
+ return k1.name == k2.name
+ && k1.partId == k2.partId
+ && k1.stateId == k2.stateId;
+}
+
+enum AlphaChannelType {
+ UnknownAlpha = -1, // Alpha of part & state not yet known
+ NoAlpha, // Totally opaque, no need to touch alpha (RGB)
+ MaskAlpha, // Alpha channel must be fixed (ARGB)
+ RealAlpha // Proper alpha values from Windows (ARGB_Premultiplied)
+};
+
+struct ThemeMapData {
+ AlphaChannelType alphaType; // Which type of alpha on part & state
+
+ bool dataValid : 1; // Only used to detect if hash value is ok
+ bool partIsTransparent : 1;
+ bool hasAnyData : 1; // False = part & state has not data, NOP
+ bool hasAlphaChannel : 1; // True = part & state has real Alpha
+ bool wasAlphaSwapped : 1; // True = alpha channel needs to be swapped
+ bool hadInvalidAlpha : 1; // True = alpha channel contained invalid alpha values
+
+ ThemeMapData() : dataValid(false), partIsTransparent(false), hasAnyData(false),
+ hasAlphaChannel(false), wasAlphaSwapped(false), hadInvalidAlpha(false) {}
+};
+
+class QWindowsXPStylePrivate : public QWindowsStylePrivate
+{
+ Q_DECLARE_PUBLIC(QWindowsXPStyle)
+public:
+ QWindowsXPStylePrivate()
+ : QWindowsStylePrivate(), hasInitColors(false), bufferDC(0), bufferBitmap(0), nullBitmap(0),
+ bufferPixels(0), bufferW(0), bufferH(0)
+ { init(); }
+
+ ~QWindowsXPStylePrivate()
+ { cleanup(); }
+
+ static HWND winId(const QWidget *widget);
+
+ void init(bool force = false);
+ void cleanup(bool force = false);
+ void cleanupHandleMap();
+ const QPixmap *tabBody(QWidget *widget);
+
+ HBITMAP buffer(int w = 0, int h = 0);
+ HDC bufferHDC()
+ { return bufferDC;}
+
+ static bool resolveSymbols();
+ static bool useXP(bool update = false);
+
+ bool isTransparent(XPThemeData &themeData);
+ QRegion region(XPThemeData &themeData);
+
+ void setTransparency(QWidget *widget, XPThemeData &themeData);
+ void drawBackground(XPThemeData &themeData);
+ void drawBackgroundThruNativeBuffer(XPThemeData &themeData);
+ void drawBackgroundDirectly(XPThemeData &themeData);
+
+ bool hasAnyData(const QRect &rect);
+ bool hasAlphaChannel(const QRect &rect);
+ bool fixAlphaChannel(const QRect &rect);
+ bool swapAlphaChannel(const QRect &rect, bool allPixels = false);
+
+ QRgb groupBoxTextColor;
+ QRgb groupBoxTextColorDisabled;
+ QRgb sliderTickColor;
+ bool hasInitColors;
+
+ static QMap<QString,HTHEME> *handleMap;
+
+ QIcon dockFloat, dockClose;
+
+private:
+#ifdef DEBUG_XP_STYLE
+ void dumpNativeDIB(int w, int h);
+ void showProperties(XPThemeData &themeData);
+#endif
+
+ static QBasicAtomicInt ref;
+ static bool use_xp;
+ static QWidget *limboWidget;
+ static QPixmap *tabbody;
+
+ QHash<ThemeMapKey, ThemeMapData> alphaCache;
+ HDC bufferDC;
+ HBITMAP bufferBitmap;
+ HBITMAP nullBitmap;
+ uchar *bufferPixels;
+ int bufferW, bufferH;
+};
+
+#endif // QT_NO_STYLE_WINDOWS
+
+QT_END_NAMESPACE
+
+#endif //QWINDOWSXPSTYLE_P_H
diff --git a/src/widgets/styles/styles.pri b/src/widgets/styles/styles.pri
new file mode 100644
index 0000000000..b20caf726e
--- /dev/null
+++ b/src/widgets/styles/styles.pri
@@ -0,0 +1,194 @@
+# Qt styles module
+
+HEADERS += \
+ styles/qdrawutil.h \
+ styles/qstyle.h \
+ styles/qstylefactory.h \
+ styles/qstyleoption.h \
+ styles/qstyleplugin.h \
+ styles/qcommonstylepixmaps_p.h \
+ styles/qcommonstyle.h \
+ styles/qstylehelper_p.h \
+ styles/qproxystyle.h \
+ styles/qproxystyle_p.h \
+ styles/qstylepainter.h \
+ styles/qstylesheetstyle_p.h
+
+SOURCES += \
+ styles/qdrawutil.cpp \
+ styles/qstyle.cpp \
+ styles/qstylefactory.cpp \
+ styles/qstyleoption.cpp \
+ styles/qstyleplugin.cpp \
+ styles/qstylehelper.cpp \
+ styles/qcommonstyle.cpp \
+ styles/qproxystyle.cpp \
+ styles/qstylepainter.cpp \
+ styles/qstylesheetstyle.cpp \
+ styles/qstylesheetstyle_default.cpp
+
+wince* {
+ RESOURCES += styles/qstyle_wince.qrc
+} else:symbian {
+ RESOURCES += styles/qstyle_s60.qrc
+} else {
+ RESOURCES += styles/qstyle.qrc
+}
+
+contains( styles, all ) {
+ styles = mac windows windowsxp windowsvista
+}
+
+x11|qpa|!macx-*:styles -= mac
+
+x11{
+ QMAKE_CXXFLAGS += $$QT_CFLAGS_QGTKSTYLE
+ LIBS_PRIVATE += $$QT_LIBS_QGTKSTYLE
+ styles += gtk
+}
+
+contains( styles, mac ) {
+ HEADERS += \
+ styles/qmacstyle_mac.h \
+ styles/qmacstylepixmaps_mac_p.h \
+ styles/qmacstyle_mac_p.h
+ OBJECTIVE_SOURCES += styles/qmacstyle_mac.mm
+
+ !contains( styles, windows ) {
+ message( mac requires windows )
+ styles += windows
+ DEFINES+= QT_STYLE_WINDOWS
+ }
+} else {
+ DEFINES += QT_NO_STYLE_MAC
+}
+
+contains( styles, cde ) {
+ HEADERS += styles/qcdestyle.h
+ SOURCES += styles/qcdestyle.cpp
+
+ !contains( styles, motif ) {
+ message( cde requires motif )
+ styles += motif
+ DEFINES+= QT_STYLE_MOTIF
+ }
+} else {
+ DEFINES += QT_NO_STYLE_CDE
+}
+
+contains( styles, windowsvista ) {
+ HEADERS += styles/qwindowsvistastyle.h
+ HEADERS += styles/qwindowsvistastyle_p.h
+ SOURCES += styles/qwindowsvistastyle.cpp
+ !contains( styles, windowsxp ) {
+ message( windowsvista requires windowsxp )
+ styles += windowsxp
+ DEFINES+= QT_STYLE_WINDOWSXP
+ }
+} else {
+ DEFINES += QT_NO_STYLE_WINDOWSVISTA
+}
+
+contains( styles, windowsxp ) {
+ HEADERS += styles/qwindowsxpstyle.h
+ SOURCES += styles/qwindowsxpstyle.cpp
+ !contains( styles, windows ) {
+ message( windowsxp requires windows )
+ styles += windows
+ DEFINES+= QT_STYLE_WINDOWS
+ }
+} else {
+ DEFINES += QT_NO_STYLE_WINDOWSXP
+}
+
+contains( styles, plastique ) {
+ HEADERS += styles/qplastiquestyle.h
+ SOURCES += styles/qplastiquestyle.cpp
+ !contains( styles, windows ) {
+ message( plastique requires windows )
+ styles += windows
+ DEFINES+= QT_STYLE_WINDOWS
+ }
+} else {
+ DEFINES += QT_NO_STYLE_PLASTIQUE
+}
+
+contains( styles, gtk ) {
+ HEADERS += styles/qgtkstyle.h
+ HEADERS += styles/qgtkpainter_p.h
+ HEADERS += styles/qgtkstyle_p.h
+ SOURCES += styles/qgtkstyle.cpp
+ SOURCES += styles/qgtkpainter.cpp
+ SOURCES += styles/qgtkstyle_p.cpp
+ !contains( styles, cleanlooks ) {
+ styles += cleanlooks
+ DEFINES+= QT_STYLE_CLEANLOOKS
+ }
+} else {
+ DEFINES += QT_NO_STYLE_GTK
+}
+
+contains( styles, cleanlooks ) {
+ HEADERS += styles/qcleanlooksstyle.h
+ HEADERS += styles/qcleanlooksstyle_p.h
+ SOURCES += styles/qcleanlooksstyle.cpp
+ !contains( styles, windows ) {
+ styles += windows
+ DEFINES+= QT_STYLE_WINDOWS
+ }
+} else {
+ DEFINES += QT_NO_STYLE_CLEANLOOKS
+}
+
+contains( styles, windows ) {
+ HEADERS += styles/qwindowsstyle.h
+ SOURCES += styles/qwindowsstyle.cpp
+} else {
+ DEFINES += QT_NO_STYLE_WINDOWS
+}
+
+contains( styles, motif ) {
+ HEADERS += styles/qmotifstyle.h
+ SOURCES += styles/qmotifstyle.cpp
+} else {
+ DEFINES += QT_NO_STYLE_MOTIF
+}
+
+contains( styles, windowsce ) {
+ HEADERS += styles/qwindowscestyle.h
+ SOURCES += styles/qwindowscestyle.cpp
+} else {
+ DEFINES += QT_NO_STYLE_WINDOWSCE
+}
+
+contains( styles, windowsmobile ) {
+ HEADERS += styles/qwindowsmobilestyle.h
+ SOURCES += styles/qwindowsmobilestyle.cpp
+} else {
+ DEFINES += QT_NO_STYLE_WINDOWSMOBILE
+}
+
+contains( styles, s60 ):contains(QT_CONFIG, s60) {
+ HEADERS += \
+ styles/qs60style.h \
+ styles/qs60style_p.h
+ SOURCES += styles/qs60style.cpp
+ symbian {
+ SOURCES += styles/qs60style_s60.cpp
+ LIBS += -legul -lbmpanim
+ contains(CONFIG, is_using_gnupoc) {
+ LIBS += -laknicon -laknskins -laknskinsrv -lfontutils
+ } else {
+ LIBS += -lAknIcon -lAKNSKINS -lAKNSKINSRV -lFontUtils
+ }
+ } else {
+ SOURCES += styles/qs60style_simulated.cpp
+ RESOURCES += styles/qstyle_s60_simulated.qrc
+ }
+} else {
+ symbian {
+ HEADERS += styles/qs60style.h
+ SOURCES += styles/qs60style_stub.cpp
+ }
+ DEFINES += QT_NO_STYLE_S60
+}
diff --git a/src/gui/symbian/images/blank.png b/src/widgets/symbian/images/blank.png
index bd396de62e..bd396de62e 100644
--- a/src/gui/symbian/images/blank.png
+++ b/src/widgets/symbian/images/blank.png
Binary files differ
diff --git a/src/gui/symbian/images/busy12.png b/src/widgets/symbian/images/busy12.png
index 909e70fa4f..909e70fa4f 100644
--- a/src/gui/symbian/images/busy12.png
+++ b/src/widgets/symbian/images/busy12.png
Binary files differ
diff --git a/src/gui/symbian/images/busy3.png b/src/widgets/symbian/images/busy3.png
index 983f5d8b8f..983f5d8b8f 100644
--- a/src/gui/symbian/images/busy3.png
+++ b/src/widgets/symbian/images/busy3.png
Binary files differ
diff --git a/src/gui/symbian/images/busy6.png b/src/widgets/symbian/images/busy6.png
index b2e878074f..b2e878074f 100644
--- a/src/gui/symbian/images/busy6.png
+++ b/src/widgets/symbian/images/busy6.png
Binary files differ
diff --git a/src/gui/symbian/images/busy9.png b/src/widgets/symbian/images/busy9.png
index e093d015c5..e093d015c5 100644
--- a/src/gui/symbian/images/busy9.png
+++ b/src/widgets/symbian/images/busy9.png
Binary files differ
diff --git a/src/gui/symbian/images/closehand.png b/src/widgets/symbian/images/closehand.png
index 05534f580d..05534f580d 100644
--- a/src/gui/symbian/images/closehand.png
+++ b/src/widgets/symbian/images/closehand.png
Binary files differ
diff --git a/src/gui/symbian/images/cross.png b/src/widgets/symbian/images/cross.png
index 50da7aafc3..50da7aafc3 100644
--- a/src/gui/symbian/images/cross.png
+++ b/src/widgets/symbian/images/cross.png
Binary files differ
diff --git a/src/gui/symbian/images/forbidden.png b/src/widgets/symbian/images/forbidden.png
index a3a0fd61e1..a3a0fd61e1 100644
--- a/src/gui/symbian/images/forbidden.png
+++ b/src/widgets/symbian/images/forbidden.png
Binary files differ
diff --git a/src/gui/symbian/images/handpoint.png b/src/widgets/symbian/images/handpoint.png
index a221548d22..a221548d22 100644
--- a/src/gui/symbian/images/handpoint.png
+++ b/src/widgets/symbian/images/handpoint.png
Binary files differ
diff --git a/src/gui/symbian/images/ibeam.png b/src/widgets/symbian/images/ibeam.png
index ace2fada1c..ace2fada1c 100644
--- a/src/gui/symbian/images/ibeam.png
+++ b/src/widgets/symbian/images/ibeam.png
Binary files differ
diff --git a/src/gui/symbian/images/openhand.png b/src/widgets/symbian/images/openhand.png
index 6f232f0d8f..6f232f0d8f 100644
--- a/src/gui/symbian/images/openhand.png
+++ b/src/widgets/symbian/images/openhand.png
Binary files differ
diff --git a/src/gui/symbian/images/pointer.png b/src/widgets/symbian/images/pointer.png
index 677404e250..677404e250 100644
--- a/src/gui/symbian/images/pointer.png
+++ b/src/widgets/symbian/images/pointer.png
Binary files differ
diff --git a/src/gui/symbian/images/sizeall.png b/src/widgets/symbian/images/sizeall.png
index 29500677eb..29500677eb 100644
--- a/src/gui/symbian/images/sizeall.png
+++ b/src/widgets/symbian/images/sizeall.png
Binary files differ
diff --git a/src/gui/symbian/images/sizebdiag.png b/src/widgets/symbian/images/sizebdiag.png
index f565a3a7a1..f565a3a7a1 100644
--- a/src/gui/symbian/images/sizebdiag.png
+++ b/src/widgets/symbian/images/sizebdiag.png
Binary files differ
diff --git a/src/gui/symbian/images/sizefdiag.png b/src/widgets/symbian/images/sizefdiag.png
index 9493f12723..9493f12723 100644
--- a/src/gui/symbian/images/sizefdiag.png
+++ b/src/widgets/symbian/images/sizefdiag.png
Binary files differ
diff --git a/src/gui/symbian/images/sizehor.png b/src/widgets/symbian/images/sizehor.png
index 217bf39fe2..217bf39fe2 100644
--- a/src/gui/symbian/images/sizehor.png
+++ b/src/widgets/symbian/images/sizehor.png
Binary files differ
diff --git a/src/gui/symbian/images/sizever.png b/src/widgets/symbian/images/sizever.png
index 2c99038c3f..2c99038c3f 100644
--- a/src/gui/symbian/images/sizever.png
+++ b/src/widgets/symbian/images/sizever.png
Binary files differ
diff --git a/src/gui/symbian/images/splith.png b/src/widgets/symbian/images/splith.png
index 343bed529a..343bed529a 100644
--- a/src/gui/symbian/images/splith.png
+++ b/src/widgets/symbian/images/splith.png
Binary files differ
diff --git a/src/gui/symbian/images/splitv.png b/src/widgets/symbian/images/splitv.png
index 69ee4163e8..69ee4163e8 100644
--- a/src/gui/symbian/images/splitv.png
+++ b/src/widgets/symbian/images/splitv.png
Binary files differ
diff --git a/src/gui/symbian/images/uparrow.png b/src/widgets/symbian/images/uparrow.png
index 92dd933856..92dd933856 100644
--- a/src/gui/symbian/images/uparrow.png
+++ b/src/widgets/symbian/images/uparrow.png
Binary files differ
diff --git a/src/gui/symbian/images/wait1.png b/src/widgets/symbian/images/wait1.png
index 5aebaab1f9..5aebaab1f9 100644
--- a/src/gui/symbian/images/wait1.png
+++ b/src/widgets/symbian/images/wait1.png
Binary files differ
diff --git a/src/gui/symbian/images/wait10.png b/src/widgets/symbian/images/wait10.png
index 3b549b08ed..3b549b08ed 100644
--- a/src/gui/symbian/images/wait10.png
+++ b/src/widgets/symbian/images/wait10.png
Binary files differ
diff --git a/src/gui/symbian/images/wait11.png b/src/widgets/symbian/images/wait11.png
index 24a943fa68..24a943fa68 100644
--- a/src/gui/symbian/images/wait11.png
+++ b/src/widgets/symbian/images/wait11.png
Binary files differ
diff --git a/src/gui/symbian/images/wait12.png b/src/widgets/symbian/images/wait12.png
index 15afd4daa2..15afd4daa2 100644
--- a/src/gui/symbian/images/wait12.png
+++ b/src/widgets/symbian/images/wait12.png
Binary files differ
diff --git a/src/gui/symbian/images/wait2.png b/src/widgets/symbian/images/wait2.png
index f2022b2853..f2022b2853 100644
--- a/src/gui/symbian/images/wait2.png
+++ b/src/widgets/symbian/images/wait2.png
Binary files differ
diff --git a/src/gui/symbian/images/wait3.png b/src/widgets/symbian/images/wait3.png
index 5b73e57124..5b73e57124 100644
--- a/src/gui/symbian/images/wait3.png
+++ b/src/widgets/symbian/images/wait3.png
Binary files differ
diff --git a/src/gui/symbian/images/wait4.png b/src/widgets/symbian/images/wait4.png
index 17a03396e0..17a03396e0 100644
--- a/src/gui/symbian/images/wait4.png
+++ b/src/widgets/symbian/images/wait4.png
Binary files differ
diff --git a/src/gui/symbian/images/wait5.png b/src/widgets/symbian/images/wait5.png
index 16a5c231f2..16a5c231f2 100644
--- a/src/gui/symbian/images/wait5.png
+++ b/src/widgets/symbian/images/wait5.png
Binary files differ
diff --git a/src/gui/symbian/images/wait6.png b/src/widgets/symbian/images/wait6.png
index 2870093a30..2870093a30 100644
--- a/src/gui/symbian/images/wait6.png
+++ b/src/widgets/symbian/images/wait6.png
Binary files differ
diff --git a/src/gui/symbian/images/wait7.png b/src/widgets/symbian/images/wait7.png
index 54f75a1db0..54f75a1db0 100644
--- a/src/gui/symbian/images/wait7.png
+++ b/src/widgets/symbian/images/wait7.png
Binary files differ
diff --git a/src/gui/symbian/images/wait8.png b/src/widgets/symbian/images/wait8.png
index 1d370c752e..1d370c752e 100644
--- a/src/gui/symbian/images/wait8.png
+++ b/src/widgets/symbian/images/wait8.png
Binary files differ
diff --git a/src/gui/symbian/images/wait9.png b/src/widgets/symbian/images/wait9.png
index c28096fe63..c28096fe63 100644
--- a/src/gui/symbian/images/wait9.png
+++ b/src/widgets/symbian/images/wait9.png
Binary files differ
diff --git a/src/gui/symbian/images/whatsthis.png b/src/widgets/symbian/images/whatsthis.png
index 3386ef0c50..3386ef0c50 100644
--- a/src/gui/symbian/images/whatsthis.png
+++ b/src/widgets/symbian/images/whatsthis.png
Binary files differ
diff --git a/src/gui/symbian/qsymbianevent.cpp b/src/widgets/symbian/qsymbianevent.cpp
index f6b2185405..f6b2185405 100644
--- a/src/gui/symbian/qsymbianevent.cpp
+++ b/src/widgets/symbian/qsymbianevent.cpp
diff --git a/src/widgets/symbian/qsymbianevent.h b/src/widgets/symbian/qsymbianevent.h
new file mode 100644
index 0000000000..2ecc846a8e
--- /dev/null
+++ b/src/widgets/symbian/qsymbianevent.h
@@ -0,0 +1,108 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSYMBIANEVENT_H
+#define QSYMBIANEVENT_H
+
+#include <QtCore/qglobal.h>
+
+#ifdef Q_OS_SYMBIAN
+
+class TWsEvent;
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class Q_WIDGETS_EXPORT QSymbianEvent
+{
+public:
+ enum Type {
+ InvalidEvent,
+ WindowServerEvent,
+ CommandEvent,
+ ResourceChangeEvent
+ };
+
+ QSymbianEvent(const TWsEvent *windowServerEvent);
+ QSymbianEvent(Type eventType, int value);
+ ~QSymbianEvent();
+
+ Type type() const;
+ bool isValid() const;
+
+ const TWsEvent *windowServerEvent() const;
+ int command() const;
+ int resourceChangeType() const;
+
+private:
+ Type m_type;
+ union {
+ const void *m_eventPtr;
+ int m_eventValue;
+
+ qint64 m_reserved;
+ };
+};
+
+inline QSymbianEvent::Type QSymbianEvent::type() const
+{
+ return m_type;
+}
+
+inline bool QSymbianEvent::isValid() const
+{
+ return m_type != InvalidEvent;
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+Q_WIDGETS_EXPORT QDebug operator<<(QDebug dbg, const QSymbianEvent *o);
+#endif
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // Q_OS_SYMBIAN
+
+#endif // QSYMBIANEVENT_H
diff --git a/src/gui/symbian/symbianresources.qrc b/src/widgets/symbian/symbianresources.qrc
index 0a4fc36c9a..0a4fc36c9a 100644
--- a/src/gui/symbian/symbianresources.qrc
+++ b/src/widgets/symbian/symbianresources.qrc
diff --git a/src/gui/kernel/qshortcut.cpp b/src/widgets/to_be_moved/qshortcut.cpp
index 0694ec85d8..0694ec85d8 100644
--- a/src/gui/kernel/qshortcut.cpp
+++ b/src/widgets/to_be_moved/qshortcut.cpp
diff --git a/src/widgets/to_be_moved/qshortcut.h b/src/widgets/to_be_moved/qshortcut.h
new file mode 100644
index 0000000000..6e3c647852
--- /dev/null
+++ b/src/widgets/to_be_moved/qshortcut.h
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSHORTCUT_H
+#define QSHORTCUT_H
+
+#include <QtWidgets/qwidget.h>
+#include <QtGui/qkeysequence.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_SHORTCUT
+
+class QShortcutPrivate;
+class Q_WIDGETS_EXPORT QShortcut : public QObject
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QShortcut)
+ Q_PROPERTY(QKeySequence key READ key WRITE setKey)
+ Q_PROPERTY(QString whatsThis READ whatsThis WRITE setWhatsThis)
+ Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled)
+ Q_PROPERTY(bool autoRepeat READ autoRepeat WRITE setAutoRepeat)
+ Q_PROPERTY(Qt::ShortcutContext context READ context WRITE setContext)
+public:
+ explicit QShortcut(QWidget *parent);
+ QShortcut(const QKeySequence& key, QWidget *parent,
+ const char *member = 0, const char *ambiguousMember = 0,
+ Qt::ShortcutContext context = Qt::WindowShortcut);
+ ~QShortcut();
+
+ void setKey(const QKeySequence& key);
+ QKeySequence key() const;
+
+ void setEnabled(bool enable);
+ bool isEnabled() const;
+
+ void setContext(Qt::ShortcutContext context);
+ Qt::ShortcutContext context();
+
+ void setWhatsThis(const QString &text);
+ QString whatsThis() const;
+
+ void setAutoRepeat(bool on);
+ bool autoRepeat() const;
+
+ int id() const;
+
+ inline QWidget *parentWidget() const
+ { return static_cast<QWidget *>(QObject::parent()); }
+
+Q_SIGNALS:
+ void activated();
+ void activatedAmbiguously();
+
+protected:
+ bool event(QEvent *e);
+};
+
+#endif // QT_NO_SHORTCUT
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QSHORTCUT_H
diff --git a/src/widgets/to_be_moved/qshortcutmap.cpp b/src/widgets/to_be_moved/qshortcutmap.cpp
new file mode 100644
index 0000000000..394c730d82
--- /dev/null
+++ b/src/widgets/to_be_moved/qshortcutmap.cpp
@@ -0,0 +1,897 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qshortcutmap_p.h"
+#include "private/qobject_p.h"
+#include "qkeysequence.h"
+#include "qgraphicsscene.h"
+#include "qgraphicsview.h"
+#include "qdebug.h"
+#include "qevent.h"
+#include "qwidget.h"
+#include "qapplication.h"
+#include "qvector.h"
+#include "qmenu.h"
+#include "qmenubar.h"
+#include "qshortcut.h"
+#include "private/qapplication_p.h"
+#include <private/qaction_p.h>
+#include <private/qkeymapper_p.h>
+#include <private/qwidget_p.h>
+
+#ifndef QT_NO_SHORTCUT
+
+QT_BEGIN_NAMESPACE
+
+// To enable verbose output uncomment below
+//#define DEBUG_QSHORTCUTMAP
+
+/* \internal
+ Entry data for QShortcutMap
+ Contains:
+ Keysequence for entry
+ Pointer to parent owning the sequence
+*/
+struct QShortcutEntry
+{
+ QShortcutEntry()
+ : keyseq(0), context(Qt::WindowShortcut), enabled(false), autorepeat(1), id(0), owner(0)
+ {}
+
+ QShortcutEntry(const QKeySequence &k)
+ : keyseq(k), context(Qt::WindowShortcut), enabled(false), autorepeat(1), id(0), owner(0)
+ {}
+
+ QShortcutEntry(QObject *o, const QKeySequence &k, Qt::ShortcutContext c, int i)
+ : keyseq(k), context(c), enabled(true), autorepeat(1), id(i), owner(o)
+ {}
+
+ QShortcutEntry(QObject *o, const QKeySequence &k, Qt::ShortcutContext c, int i, bool a)
+ : keyseq(k), context(c), enabled(true), autorepeat(a), id(i), owner(o)
+ {}
+
+ bool operator<(const QShortcutEntry &f) const
+ { return keyseq < f.keyseq; }
+
+ QKeySequence keyseq;
+ Qt::ShortcutContext context;
+ bool enabled : 1;
+ bool autorepeat : 1;
+ signed int id;
+ QObject *owner;
+};
+
+#if 0 //ndef QT_NO_DEBUG_STREAM
+/*! \internal
+ QDebug operator<< for easy debug output of the shortcut entries.
+*/
+static QDebug &operator<<(QDebug &dbg, const QShortcutEntry *se) {
+ if (!se)
+ return dbg << "QShortcutEntry(0x0)";
+ dbg.nospace()
+ << "QShortcutEntry(" << se->keyseq
+ << "), id(" << se->id << "), enabled(" << se->enabled << "), autorepeat(" << se->autorepeat
+ << "), owner(" << se->owner << ')';
+ return dbg.space();
+}
+#endif // QT_NO_DEBUGSTREAM
+
+/* \internal
+ Private data for QShortcutMap
+*/
+class QShortcutMapPrivate
+{
+ Q_DECLARE_PUBLIC(QShortcutMap)
+
+public:
+ QShortcutMapPrivate(QShortcutMap* parent)
+ : q_ptr(parent), currentId(0), ambigCount(0), currentState(QKeySequence::NoMatch)
+ {
+ identicals.reserve(10);
+ currentSequences.reserve(10);
+ }
+ QShortcutMap *q_ptr; // Private's parent
+
+ QList<QShortcutEntry> sequences; // All sequences!
+
+ int currentId; // Global shortcut ID number
+ int ambigCount; // Index of last enabled ambiguous dispatch
+ QKeySequence::SequenceMatch currentState;
+ QVector<QKeySequence> currentSequences; // Sequence for the current state
+ QVector<QKeySequence> newEntries;
+ QKeySequence prevSequence; // Sequence for the previous identical match
+ QVector<const QShortcutEntry*> identicals; // Last identical matches
+};
+
+
+/*! \internal
+ QShortcutMap constructor.
+*/
+QShortcutMap::QShortcutMap()
+ : d_ptr(new QShortcutMapPrivate(this))
+{
+ resetState();
+}
+
+/*! \internal
+ QShortcutMap destructor.
+*/
+QShortcutMap::~QShortcutMap()
+{
+}
+
+/*! \internal
+ Adds a shortcut to the global map.
+ Returns the id of the newly added shortcut.
+*/
+int QShortcutMap::addShortcut(QObject *owner, const QKeySequence &key, Qt::ShortcutContext context)
+{
+ Q_ASSERT_X(owner, "QShortcutMap::addShortcut", "All shortcuts need an owner");
+ Q_ASSERT_X(!key.isEmpty(), "QShortcutMap::addShortcut", "Cannot add keyless shortcuts to map");
+ Q_D(QShortcutMap);
+
+ QShortcutEntry newEntry(owner, key, context, --(d->currentId), true);
+ QList<QShortcutEntry>::iterator it = qUpperBound(d->sequences.begin(), d->sequences.end(), newEntry);
+ d->sequences.insert(it, newEntry); // Insert sorted
+#if defined(DEBUG_QSHORTCUTMAP)
+ qDebug().nospace()
+ << "QShortcutMap::addShortcut(" << owner << ", "
+ << key << ", " << context << ") = " << d->currentId;
+#endif
+ return d->currentId;
+}
+
+/*! \internal
+ Removes a shortcut from the global map.
+ If \a owner is 0, all entries in the map with the key sequence specified
+ is removed. If \a key is null, all sequences for \a owner is removed from
+ the map. If \a id is 0, any identical \a key sequences owned by \a owner
+ are removed.
+ Returns the number of sequences removed from the map.
+*/
+
+int QShortcutMap::removeShortcut(int id, QObject *owner, const QKeySequence &key)
+{
+ Q_D(QShortcutMap);
+ int itemsRemoved = 0;
+ bool allOwners = (owner == 0);
+ bool allKeys = key.isEmpty();
+ bool allIds = id == 0;
+
+ // Special case, remove everything
+ if (allOwners && allKeys && id == 0) {
+ itemsRemoved = d->sequences.size();
+ d->sequences.clear();
+ return itemsRemoved;
+ }
+
+ int i = d->sequences.size()-1;
+ while (i>=0)
+ {
+ const QShortcutEntry &entry = d->sequences.at(i);
+ int entryId = entry.id;
+ if ((allOwners || entry.owner == owner)
+ && (allIds || entry.id == id)
+ && (allKeys || entry.keyseq == key)) {
+ d->sequences.removeAt(i);
+ ++itemsRemoved;
+ }
+ if (id == entryId)
+ return itemsRemoved;
+ --i;
+ }
+#if defined(DEBUG_QSHORTCUTMAP)
+ qDebug().nospace()
+ << "QShortcutMap::removeShortcut(" << id << ", " << owner << ", "
+ << key << ") = " << itemsRemoved;
+#endif
+ return itemsRemoved;
+}
+
+/*! \internal
+ Changes the enable state of a shortcut to \a enable.
+ If \a owner is 0, all entries in the map with the key sequence specified
+ is removed. If \a key is null, all sequences for \a owner is removed from
+ the map. If \a id is 0, any identical \a key sequences owned by \a owner
+ are changed.
+ Returns the number of sequences which are matched in the map.
+*/
+int QShortcutMap::setShortcutEnabled(bool enable, int id, QObject *owner, const QKeySequence &key)
+{
+ Q_D(QShortcutMap);
+ int itemsChanged = 0;
+ bool allOwners = (owner == 0);
+ bool allKeys = key.isEmpty();
+ bool allIds = id == 0;
+
+ int i = d->sequences.size()-1;
+ while (i>=0)
+ {
+ QShortcutEntry entry = d->sequences.at(i);
+ if ((allOwners || entry.owner == owner)
+ && (allIds || entry.id == id)
+ && (allKeys || entry.keyseq == key)) {
+ d->sequences[i].enabled = enable;
+ ++itemsChanged;
+ }
+ if (id == entry.id)
+ return itemsChanged;
+ --i;
+ }
+#if defined(DEBUG_QSHORTCUTMAP)
+ qDebug().nospace()
+ << "QShortcutMap::setShortcutEnabled(" << enable << ", " << id << ", "
+ << owner << ", " << key << ") = " << itemsChanged;
+#endif
+ return itemsChanged;
+}
+
+/*! \internal
+ Changes the auto repeat state of a shortcut to \a enable.
+ If \a owner is 0, all entries in the map with the key sequence specified
+ is removed. If \a key is null, all sequences for \a owner is removed from
+ the map. If \a id is 0, any identical \a key sequences owned by \a owner
+ are changed.
+ Returns the number of sequences which are matched in the map.
+*/
+int QShortcutMap::setShortcutAutoRepeat(bool on, int id, QObject *owner, const QKeySequence &key)
+{
+ Q_D(QShortcutMap);
+ int itemsChanged = 0;
+ bool allOwners = (owner == 0);
+ bool allKeys = key.isEmpty();
+ bool allIds = id == 0;
+
+ int i = d->sequences.size()-1;
+ while (i>=0)
+ {
+ QShortcutEntry entry = d->sequences.at(i);
+ if ((allOwners || entry.owner == owner)
+ && (allIds || entry.id == id)
+ && (allKeys || entry.keyseq == key)) {
+ d->sequences[i].autorepeat = on;
+ ++itemsChanged;
+ }
+ if (id == entry.id)
+ return itemsChanged;
+ --i;
+ }
+#if defined(DEBUG_QSHORTCUTMAP)
+ qDebug().nospace()
+ << "QShortcutMap::setShortcutAutoRepeat(" << on << ", " << id << ", "
+ << owner << ", " << key << ") = " << itemsChanged;
+#endif
+ return itemsChanged;
+}
+
+/*! \internal
+ Resets the state of the statemachine to NoMatch
+*/
+void QShortcutMap::resetState()
+{
+ Q_D(QShortcutMap);
+ d->currentState = QKeySequence::NoMatch;
+ clearSequence(d->currentSequences);
+}
+
+/*! \internal
+ Returns the current state of the statemachine
+*/
+QKeySequence::SequenceMatch QShortcutMap::state()
+{
+ Q_D(QShortcutMap);
+ return d->currentState;
+}
+
+/*! \internal
+ Uses ShortcutOverride event to see if any widgets want to override
+ the event. If not, uses nextState(QKeyEvent) to check for a grabbed
+ Shortcut, and dispatchEvent() is found an identical.
+ \sa nextState dispatchEvent
+*/
+bool QShortcutMap::tryShortcutEvent(QObject *o, QKeyEvent *e)
+{
+ Q_D(QShortcutMap);
+
+ bool wasAccepted = e->isAccepted();
+ bool wasSpontaneous = e->spont;
+ if (d->currentState == QKeySequence::NoMatch) {
+ ushort orgType = e->t;
+ e->t = QEvent::ShortcutOverride;
+ e->ignore();
+ QCoreApplication::sendEvent(o, e);
+ e->t = orgType;
+ e->spont = wasSpontaneous;
+ if (e->isAccepted()) {
+ if (!wasAccepted)
+ e->ignore();
+ return false;
+ }
+ }
+
+ QKeySequence::SequenceMatch result = nextState(e);
+ bool stateWasAccepted = e->isAccepted();
+ if (wasAccepted)
+ e->accept();
+ else
+ e->ignore();
+
+ int identicalMatches = d->identicals.count();
+
+ switch(result) {
+ case QKeySequence::NoMatch:
+ return stateWasAccepted;
+ case QKeySequence::ExactMatch:
+ resetState();
+ dispatchEvent(e);
+ default:
+ break;
+ }
+ // If nextState is QKeySequence::ExactMatch && identicals.count == 0
+ // we've only found disabled shortcuts
+ return identicalMatches > 0 || result == QKeySequence::PartialMatch;
+}
+
+/*! \internal
+ Returns the next state of the statemachine
+ If return value is SequenceMatch::ExactMatch, then a call to matches()
+ will return a QObjects* list of all matching objects for the last matching
+ sequence.
+*/
+QKeySequence::SequenceMatch QShortcutMap::nextState(QKeyEvent *e)
+{
+ Q_D(QShortcutMap);
+ // Modifiers can NOT be shortcuts...
+ if (e->key() >= Qt::Key_Shift &&
+ e->key() <= Qt::Key_Alt)
+ return d->currentState;
+
+ QKeySequence::SequenceMatch result = QKeySequence::NoMatch;
+
+ // We start fresh each time..
+ d->identicals.resize(0);
+
+ result = find(e);
+ if (result == QKeySequence::NoMatch && e->modifiers() & Qt::ShiftModifier) {
+ // If Shift + Key_Backtab, also try Shift + Qt::Key_Tab
+ if (e->key() == Qt::Key_Backtab) {
+ QKeyEvent pe = QKeyEvent(e->type(), Qt::Key_Tab, e->modifiers(), e->text());
+ result = find(&pe);
+ }
+ }
+
+ // Should we eat this key press?
+ if (d->currentState == QKeySequence::PartialMatch
+ || (d->currentState == QKeySequence::ExactMatch && d->identicals.count()))
+ e->accept();
+ // Does the new state require us to clean up?
+ if (result == QKeySequence::NoMatch)
+ clearSequence(d->currentSequences);
+ d->currentState = result;
+
+#if defined(DEBUG_QSHORTCUTMAP)
+ qDebug().nospace() << "QShortcutMap::nextState(" << e << ") = " << result;
+#endif
+ return result;
+}
+
+
+/*! \internal
+ Determines if an enabled shortcut has a matcing key sequence.
+*/
+bool QShortcutMap::hasShortcutForKeySequence(const QKeySequence &seq) const
+{
+ Q_D(const QShortcutMap);
+ QShortcutEntry entry(seq); // needed for searching
+ QList<QShortcutEntry>::ConstIterator itEnd = d->sequences.constEnd();
+ QList<QShortcutEntry>::ConstIterator it = qLowerBound(d->sequences.constBegin(), itEnd, entry);
+
+ for (;it != itEnd; ++it) {
+ if (matches(entry.keyseq, (*it).keyseq) == QKeySequence::ExactMatch && correctContext(*it) && (*it).enabled) {
+ return true;
+ }
+ }
+
+ //end of the loop: we didn't find anything
+ return false;
+}
+
+/*! \internal
+ Returns the next state of the statemachine, based
+ on the new key event \a e.
+ Matches are appended to the vector of identicals,
+ which can be access through matches().
+ \sa matches
+*/
+QKeySequence::SequenceMatch QShortcutMap::find(QKeyEvent *e)
+{
+ Q_D(QShortcutMap);
+ if (!d->sequences.count())
+ return QKeySequence::NoMatch;
+
+ createNewSequences(e, d->newEntries);
+#if defined(DEBUG_QSHORTCUTMAP)
+ qDebug() << "Possible shortcut key sequences:" << d->newEntries;
+#endif
+
+ // Should never happen
+ if (d->newEntries == d->currentSequences) {
+ Q_ASSERT_X(e->key() != Qt::Key_unknown || e->text().length(),
+ "QShortcutMap::find", "New sequence to find identical to previous");
+ return QKeySequence::NoMatch;
+ }
+
+ // Looking for new identicals, scrap old
+ d->identicals.resize(0);
+
+ bool partialFound = false;
+ bool identicalDisabledFound = false;
+ QVector<QKeySequence> okEntries;
+ int result = QKeySequence::NoMatch;
+ for (int i = d->newEntries.count()-1; i >= 0 ; --i) {
+ QShortcutEntry entry(d->newEntries.at(i)); // needed for searching
+ QList<QShortcutEntry>::ConstIterator itEnd = d->sequences.constEnd();
+ QList<QShortcutEntry>::ConstIterator it =
+ qLowerBound(d->sequences.constBegin(), itEnd, entry);
+
+ int oneKSResult = QKeySequence::NoMatch;
+ int tempRes = QKeySequence::NoMatch;
+ do {
+ if (it == itEnd)
+ break;
+ tempRes = matches(entry.keyseq, (*it).keyseq);
+ oneKSResult = qMax(oneKSResult, tempRes);
+ if (tempRes != QKeySequence::NoMatch && correctContext(*it)) {
+ if (tempRes == QKeySequence::ExactMatch) {
+ if ((*it).enabled)
+ d->identicals.append(&*it);
+ else
+ identicalDisabledFound = true;
+ } else if (tempRes == QKeySequence::PartialMatch) {
+ // We don't need partials, if we have identicals
+ if (d->identicals.size())
+ break;
+ // We only care about enabled partials, so we don't consume
+ // key events when all partials are disabled!
+ partialFound |= (*it).enabled;
+ }
+ }
+ ++it;
+ // If we got a valid match on this run, there might still be more keys to check against,
+ // so we'll loop once more. If we get NoMatch, there's guaranteed no more possible
+ // matches in the shortcutmap.
+ } while (tempRes != QKeySequence::NoMatch);
+
+ // If the type of match improves (ergo, NoMatch->Partial, or Partial->Exact), clear the
+ // previous list. If this match is equal or better than the last match, append to the list
+ if (oneKSResult > result) {
+ okEntries.clear();
+#if defined(DEBUG_QSHORTCUTMAP)
+ qDebug() << "Found better match (" << d->newEntries << "), clearing key sequence list";
+#endif
+ }
+ if (oneKSResult && oneKSResult >= result) {
+ okEntries << d->newEntries.at(i);
+#if defined(DEBUG_QSHORTCUTMAP)
+ qDebug() << "Added ok key sequence" << d->newEntries;
+#endif
+ }
+ }
+
+ if (d->identicals.size()) {
+ result = QKeySequence::ExactMatch;
+ } else if (partialFound) {
+ result = QKeySequence::PartialMatch;
+ } else if (identicalDisabledFound) {
+ result = QKeySequence::ExactMatch;
+ } else {
+ clearSequence(d->currentSequences);
+ result = QKeySequence::NoMatch;
+ }
+ if (result != QKeySequence::NoMatch)
+ d->currentSequences = okEntries;
+#if defined(DEBUG_QSHORTCUTMAP)
+ qDebug() << "Returning shortcut match == " << result;
+#endif
+ return QKeySequence::SequenceMatch(result);
+}
+
+/*! \internal
+ Clears \a seq to an empty QKeySequence.
+ Same as doing (the slower)
+ \snippet doc/src/snippets/code/src_gui_kernel_qshortcutmap.cpp 0
+*/
+void QShortcutMap::clearSequence(QVector<QKeySequence> &ksl)
+{
+ ksl.clear();
+ d_func()->newEntries.clear();
+}
+
+/*! \internal
+ Alters \a seq to the new sequence state, based on the
+ current sequence state, and the new key event \a e.
+*/
+void QShortcutMap::createNewSequences(QKeyEvent *e, QVector<QKeySequence> &ksl)
+{
+ Q_D(QShortcutMap);
+ QList<int> possibleKeys = QKeyMapper::possibleKeys(e);
+ int pkTotal = possibleKeys.count();
+ if (!pkTotal)
+ return;
+
+ int ssActual = d->currentSequences.count();
+ int ssTotal = qMax(1, ssActual);
+ // Resize to possible permutations of the current sequence(s).
+ ksl.resize(pkTotal * ssTotal);
+
+ int index = ssActual ? d->currentSequences.at(0).count() : 0;
+ for (int pkNum = 0; pkNum < pkTotal; ++pkNum) {
+ for (int ssNum = 0; ssNum < ssTotal; ++ssNum) {
+ int i = (pkNum * ssTotal) + ssNum;
+ QKeySequence &curKsl = ksl[i];
+ if (ssActual) {
+ const QKeySequence &curSeq = d->currentSequences.at(ssNum);
+ curKsl.setKey(curSeq[0], 0);
+ curKsl.setKey(curSeq[1], 1);
+ curKsl.setKey(curSeq[2], 2);
+ curKsl.setKey(curSeq[3], 3);
+ } else {
+ curKsl.setKey(0, 0);
+ curKsl.setKey(0, 1);
+ curKsl.setKey(0, 2);
+ curKsl.setKey(0, 3);
+ }
+ // Filtering keycode here with 0xdfffffff to ignore the Keypad modifier
+ curKsl.setKey(possibleKeys.at(pkNum) & 0xdfffffff, index);
+ }
+ }
+}
+
+/*! \internal
+ Basically the same function as QKeySequence::matches(const QKeySequence &seq) const
+ only that is specially handles Key_hyphen as Key_Minus, as people mix these up all the time and
+ they conceptually the same.
+*/
+QKeySequence::SequenceMatch QShortcutMap::matches(const QKeySequence &seq1,
+ const QKeySequence &seq2) const
+{
+ uint userN = seq1.count(),
+ seqN = seq2.count();
+
+ if (userN > seqN)
+ return QKeySequence::NoMatch;
+
+ // If equal in length, we have a potential ExactMatch sequence,
+ // else we already know it can only be partial.
+ QKeySequence::SequenceMatch match = (userN == seqN
+ ? QKeySequence::ExactMatch
+ : QKeySequence::PartialMatch);
+
+ for (uint i = 0; i < userN; ++i) {
+ int userKey = seq1[i],
+ sequenceKey = seq2[i];
+ if ((userKey & Qt::Key_unknown) == Qt::Key_hyphen)
+ userKey = (userKey & Qt::KeyboardModifierMask) | Qt::Key_Minus;
+ if ((sequenceKey & Qt::Key_unknown) == Qt::Key_hyphen)
+ sequenceKey = (sequenceKey & Qt::KeyboardModifierMask) | Qt::Key_Minus;
+ if (userKey != sequenceKey)
+ return QKeySequence::NoMatch;
+ }
+ return match;
+}
+
+/*! \internal
+ Returns true if the widget \a w is a logical sub window of the current
+ top-level widget.
+*/
+bool QShortcutMap::correctContext(const QShortcutEntry &item) const {
+ Q_ASSERT_X(item.owner, "QShortcutMap", "Shortcut has no owner. Illegal map state!");
+
+ QWidget *active_window = QApplication::activeWindow();
+
+ // popups do not become the active window,
+ // so we fake it here to get the correct context
+ // for the shortcut system.
+ if (QApplication::activePopupWidget())
+ active_window = QApplication::activePopupWidget();
+
+ if (!active_window)
+ return false;
+#ifndef QT_NO_ACTION
+ if (QAction *a = qobject_cast<QAction *>(item.owner))
+ return correctContext(item.context, a, active_window);
+#endif
+#ifndef QT_NO_GRAPHICSVIEW
+ if (QGraphicsWidget *gw = qobject_cast<QGraphicsWidget *>(item.owner))
+ return correctGraphicsWidgetContext(item.context, gw, active_window);
+#endif
+ QWidget *w = qobject_cast<QWidget *>(item.owner);
+ if (!w) {
+ QShortcut *s = qobject_cast<QShortcut *>(item.owner);
+ w = s->parentWidget();
+ }
+ return correctWidgetContext(item.context, w, active_window);
+}
+
+bool QShortcutMap::correctWidgetContext(Qt::ShortcutContext context, QWidget *w, QWidget *active_window) const
+{
+ bool visible = w->isVisible();
+#ifdef Q_WS_MAC
+ if (!qApp->testAttribute(Qt::AA_DontUseNativeMenuBar) && qobject_cast<QMenuBar *>(w))
+ visible = true;
+#endif
+
+ if (!visible || !w->isEnabled())
+ return false;
+
+ if (context == Qt::ApplicationShortcut)
+ return QApplicationPrivate::tryModalHelper(w, 0); // true, unless w is shadowed by a modal dialog
+
+ if (context == Qt::WidgetShortcut)
+ return w == QApplication::focusWidget();
+
+ if (context == Qt::WidgetWithChildrenShortcut) {
+ const QWidget *tw = QApplication::focusWidget();
+ while (tw && tw != w && (tw->windowType() == Qt::Widget || tw->windowType() == Qt::Popup))
+ tw = tw->parentWidget();
+ return tw == w;
+ }
+
+ // Below is Qt::WindowShortcut context
+ QWidget *tlw = w->window();
+#ifndef QT_NO_GRAPHICSVIEW
+ if (QWExtra *topData = tlw->d_func()->extra) {
+ if (topData->proxyWidget) {
+ bool res = correctGraphicsWidgetContext(context, (QGraphicsWidget *)topData->proxyWidget, active_window);
+ return res;
+ }
+ }
+#endif
+
+ /* if a floating tool window is active, keep shortcuts on the
+ * parent working */
+ if (active_window != tlw && active_window && active_window->windowType() == Qt::Tool && active_window->parentWidget()) {
+ active_window = active_window->parentWidget()->window();
+ }
+
+ if (active_window != tlw)
+ return false;
+
+ /* if we live in a MDI subwindow, ignore the event if we are
+ not the active document window */
+ const QWidget* sw = w;
+ while (sw && !(sw->windowType() == Qt::SubWindow) && !sw->isWindow())
+ sw = sw->parentWidget();
+ if (sw && (sw->windowType() == Qt::SubWindow)) {
+ QWidget *focus_widget = QApplication::focusWidget();
+ while (focus_widget && focus_widget != sw)
+ focus_widget = focus_widget->parentWidget();
+ return sw == focus_widget;
+ }
+
+#if defined(DEBUG_QSHORTCUTMAP)
+ qDebug().nospace() << "..true [Pass-through]";
+#endif
+ return true;
+}
+
+#ifndef QT_NO_GRAPHICSVIEW
+bool QShortcutMap::correctGraphicsWidgetContext(Qt::ShortcutContext context, QGraphicsWidget *w, QWidget *active_window) const
+{
+ bool visible = w->isVisible();
+#ifdef Q_WS_MAC
+ if (!qApp->testAttribute(Qt::AA_DontUseNativeMenuBar) && qobject_cast<QMenuBar *>(w))
+ visible = true;
+#endif
+
+ if (!visible || !w->isEnabled() || !w->scene())
+ return false;
+
+ if (context == Qt::ApplicationShortcut) {
+ // Applicationwide shortcuts are always reachable unless their owner
+ // is shadowed by modality. In QGV there's no modality concept, but we
+ // must still check if all views are shadowed.
+ QList<QGraphicsView *> views = w->scene()->views();
+ for (int i = 0; i < views.size(); ++i) {
+ if (QApplicationPrivate::tryModalHelper(views.at(i), 0))
+ return true;
+ }
+ return false;
+ }
+
+ if (context == Qt::WidgetShortcut)
+ return static_cast<QGraphicsItem *>(w) == w->scene()->focusItem();
+
+ if (context == Qt::WidgetWithChildrenShortcut) {
+ const QGraphicsItem *ti = w->scene()->focusItem();
+ if (ti && ti->isWidget()) {
+ const QGraphicsWidget *tw = static_cast<const QGraphicsWidget *>(ti);
+ while (tw && tw != w && (tw->windowType() == Qt::Widget || tw->windowType() == Qt::Popup))
+ tw = tw->parentWidget();
+ return tw == w;
+ }
+ return false;
+ }
+
+ // Below is Qt::WindowShortcut context
+
+ // Find the active view (if any).
+ QList<QGraphicsView *> views = w->scene()->views();
+ QGraphicsView *activeView = 0;
+ for (int i = 0; i < views.size(); ++i) {
+ QGraphicsView *view = views.at(i);
+ if (view->window() == active_window) {
+ activeView = view;
+ break;
+ }
+ }
+ if (!activeView)
+ return false;
+
+ // The shortcut is reachable if owned by a windowless widget, or if the
+ // widget's window is the same as the focus item's window.
+ QGraphicsWidget *a = w->scene()->activeWindow();
+ return !w->window() || a == w->window();
+}
+#endif
+
+#ifndef QT_NO_ACTION
+bool QShortcutMap::correctContext(Qt::ShortcutContext context, QAction *a, QWidget *active_window) const
+{
+ const QList<QWidget *> &widgets = a->d_func()->widgets;
+#if defined(DEBUG_QSHORTCUTMAP)
+ if (widgets.isEmpty())
+ qDebug() << a << "not connected to any widgets; won't trigger";
+#endif
+ for (int i = 0; i < widgets.size(); ++i) {
+ QWidget *w = widgets.at(i);
+#ifndef QT_NO_MENU
+ if (QMenu *menu = qobject_cast<QMenu *>(w)) {
+ QAction *a = menu->menuAction();
+ if (correctContext(context, a, active_window))
+ return true;
+ } else
+#endif
+ if (correctWidgetContext(context, w, active_window))
+ return true;
+ }
+
+#ifndef QT_NO_GRAPHICSVIEW
+ const QList<QGraphicsWidget *> &graphicsWidgets = a->d_func()->graphicsWidgets;
+#if defined(DEBUG_QSHORTCUTMAP)
+ if (graphicsWidgets.isEmpty())
+ qDebug() << a << "not connected to any widgets; won't trigger";
+#endif
+ for (int i = 0; i < graphicsWidgets.size(); ++i) {
+ QGraphicsWidget *w = graphicsWidgets.at(i);
+ if (correctGraphicsWidgetContext(context, w, active_window))
+ return true;
+ }
+#endif
+ return false;
+}
+#endif // QT_NO_ACTION
+
+/*! \internal
+ Converts keyboard button states into modifier states
+*/
+int QShortcutMap::translateModifiers(Qt::KeyboardModifiers modifiers)
+{
+ int result = 0;
+ if (modifiers & Qt::ShiftModifier)
+ result |= Qt::SHIFT;
+ if (modifiers & Qt::ControlModifier)
+ result |= Qt::CTRL;
+ if (modifiers & Qt::MetaModifier)
+ result |= Qt::META;
+ if (modifiers & Qt::AltModifier)
+ result |= Qt::ALT;
+ return result;
+}
+
+/*! \internal
+ Returns the vector of QShortcutEntry's matching the last Identical state.
+*/
+QVector<const QShortcutEntry*> QShortcutMap::matches() const
+{
+ Q_D(const QShortcutMap);
+ return d->identicals;
+}
+
+/*! \internal
+ Dispatches QShortcutEvents to widgets who grabbed the matched key sequence.
+*/
+void QShortcutMap::dispatchEvent(QKeyEvent *e)
+{
+ Q_D(QShortcutMap);
+ if (!d->identicals.size())
+ return;
+
+ const QKeySequence &curKey = d->identicals.at(0)->keyseq;
+ if (d->prevSequence != curKey) {
+ d->ambigCount = 0;
+ d->prevSequence = curKey;
+ }
+ // Find next
+ const QShortcutEntry *current = 0, *next = 0;
+ int i = 0, enabledShortcuts = 0;
+ while(i < d->identicals.size()) {
+ current = d->identicals.at(i);
+ if (current->enabled || !next){
+ ++enabledShortcuts;
+ if (enabledShortcuts > d->ambigCount + 1)
+ break;
+ next = current;
+ }
+ ++i;
+ }
+ d->ambigCount = (d->identicals.size() == i ? 0 : d->ambigCount + 1);
+ // Don't trigger shortcut if we're autorepeating and the shortcut is
+ // grabbed with not accepting autorepeats.
+ if (!next || (e->isAutoRepeat() && !next->autorepeat))
+ return;
+ // Dispatch next enabled
+#if defined(DEBUG_QSHORTCUTMAP)
+ qDebug().nospace()
+ << "QShortcutMap::dispatchEvent(): Sending QShortcutEvent(\""
+ << (QString)next->keyseq << "\", " << next->id << ", "
+ << (bool)(enabledShortcuts>1) << ") to object(" << next->owner << ')';
+#endif
+ QShortcutEvent se(next->keyseq, next->id, enabledShortcuts>1);
+ QCoreApplication::sendEvent(const_cast<QObject *>(next->owner), &se);
+}
+
+/* \internal
+ QShortcutMap dump function, only available when DEBUG_QSHORTCUTMAP is
+ defined.
+*/
+#if defined(Dump_QShortcutMap)
+void QShortcutMap::dumpMap() const
+{
+ Q_D(const QShortcutMap);
+ for (int i = 0; i < d->sequences.size(); ++i)
+ qDebug().nospace() << &(d->sequences.at(i));
+}
+#endif
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_SHORTCUT
diff --git a/src/gui/kernel/qshortcutmap_p.h b/src/widgets/to_be_moved/qshortcutmap_p.h
index 0090cea8e9..0090cea8e9 100644
--- a/src/gui/kernel/qshortcutmap_p.h
+++ b/src/widgets/to_be_moved/qshortcutmap_p.h
diff --git a/src/widgets/to_be_moved/to_be_moved.pri b/src/widgets/to_be_moved/to_be_moved.pri
new file mode 100644
index 0000000000..fc570ce2d9
--- /dev/null
+++ b/src/widgets/to_be_moved/to_be_moved.pri
@@ -0,0 +1,7 @@
+HEADERS += \
+ to_be_moved/qshortcut.h \
+ to_be_moved/qshortcutmap_p.h \
+
+SOURCES += \
+ to_be_moved/qshortcut.cpp \
+ to_be_moved/qshortcutmap.cpp \
diff --git a/src/widgets/util/qcolormap.h b/src/widgets/util/qcolormap.h
new file mode 100644
index 0000000000..ebb5142768
--- /dev/null
+++ b/src/widgets/util/qcolormap.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCOLORMAP_H
+#define QCOLORMAP_H
+
+#include <QtCore/qatomic.h>
+#include <QtGui/qrgb.h>
+#include <QtCore/qvector.h>
+#include <QtGui/qwindowdefs.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QColor;
+class QColormapPrivate;
+
+class Q_WIDGETS_EXPORT QColormap
+{
+public:
+ enum Mode { Direct, Indexed, Gray };
+
+ static void initialize();
+ static void cleanup();
+
+ static QColormap instance(int screen = -1);
+
+ QColormap(const QColormap &colormap);
+ ~QColormap();
+
+ QColormap &operator=(const QColormap &colormap);
+
+ Mode mode() const;
+
+ int depth() const;
+ int size() const;
+
+ uint pixel(const QColor &color) const;
+ const QColor colorAt(uint pixel) const;
+
+ const QVector<QColor> colormap() const;
+
+#ifdef Q_WS_WIN
+ static HPALETTE hPal();
+#endif
+
+private:
+ QColormap();
+ QColormapPrivate *d;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QCOLORMAP_H
diff --git a/src/gui/painting/qcolormap.qdoc b/src/widgets/util/qcolormap.qdoc
index 99b97a54b4..99b97a54b4 100644
--- a/src/gui/painting/qcolormap.qdoc
+++ b/src/widgets/util/qcolormap.qdoc
diff --git a/src/widgets/util/qcolormap_qpa.cpp b/src/widgets/util/qcolormap_qpa.cpp
new file mode 100644
index 0000000000..6ad3abb3aa
--- /dev/null
+++ b/src/widgets/util/qcolormap_qpa.cpp
@@ -0,0 +1,228 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcolormap.h"
+#include "qcolor.h"
+#include "qpaintdevice.h"
+#include "qscreen.h"
+#include "qguiapplication.h"
+
+QT_BEGIN_NAMESPACE
+
+class QColormapPrivate
+{
+public:
+ inline QColormapPrivate()
+ : ref(1), mode(QColormap::Direct), depth(0), numcolors(0)
+ { }
+
+ QAtomicInt ref;
+
+ QColormap::Mode mode;
+ int depth;
+ int numcolors;
+};
+
+static QColormapPrivate *screenMap = 0;
+
+void QColormap::initialize()
+{
+ screenMap = new QColormapPrivate;
+
+ screenMap->depth = QGuiApplication::primaryScreen()->depth();
+ if (screenMap->depth < 8) {
+ screenMap->mode = QColormap::Indexed;
+ screenMap->numcolors = 256;
+ } else {
+ screenMap->mode = QColormap::Direct;
+ screenMap->numcolors = -1;
+ }
+}
+
+void QColormap::cleanup()
+{
+ delete screenMap;
+ screenMap = 0;
+}
+
+QColormap QColormap::instance(int /*screen*/)
+{
+ return QColormap();
+}
+
+QColormap::QColormap()
+ : d(screenMap)
+{ d->ref.ref(); }
+
+QColormap::QColormap(const QColormap &colormap)
+ :d (colormap.d)
+{ d->ref.ref(); }
+
+QColormap::~QColormap()
+{
+ if (!d->ref.deref())
+ delete d;
+}
+
+QColormap::Mode QColormap::mode() const
+{ return d->mode; }
+
+
+int QColormap::depth() const
+{ return d->depth; }
+
+
+int QColormap::size() const
+{
+ return d->numcolors;
+}
+
+#ifndef QT_QWS_DEPTH16_RGB
+#define QT_QWS_DEPTH16_RGB 565
+#endif
+static const int qt_rbits = (QT_QWS_DEPTH16_RGB/100);
+static const int qt_gbits = (QT_QWS_DEPTH16_RGB/10%10);
+static const int qt_bbits = (QT_QWS_DEPTH16_RGB%10);
+static const int qt_red_shift = qt_bbits+qt_gbits-(8-qt_rbits);
+static const int qt_green_shift = qt_bbits-(8-qt_gbits);
+static const int qt_neg_blue_shift = 8-qt_bbits;
+static const int qt_blue_mask = (1<<qt_bbits)-1;
+static const int qt_green_mask = (1<<(qt_gbits+qt_bbits))-(1<<qt_bbits);
+static const int qt_red_mask = (1<<(qt_rbits+qt_gbits+qt_bbits))-(1<<(qt_gbits+qt_bbits));
+
+static const int qt_red_rounding_shift = qt_red_shift + qt_rbits;
+static const int qt_green_rounding_shift = qt_green_shift + qt_gbits;
+static const int qt_blue_rounding_shift = qt_bbits - qt_neg_blue_shift;
+
+inline ushort qt_convRgbTo16(QRgb c)
+{
+ const int tr = qRed(c) << qt_red_shift;
+ const int tg = qGreen(c) << qt_green_shift;
+ const int tb = qBlue(c) >> qt_neg_blue_shift;
+
+ return (tb & qt_blue_mask) | (tg & qt_green_mask) | (tr & qt_red_mask);
+}
+
+inline QRgb qt_conv16ToRgb(ushort c)
+{
+ const int r=(c & qt_red_mask);
+ const int g=(c & qt_green_mask);
+ const int b=(c & qt_blue_mask);
+ const int tr = r >> qt_red_shift | r >> qt_red_rounding_shift;
+ const int tg = g >> qt_green_shift | g >> qt_green_rounding_shift;
+ const int tb = b << qt_neg_blue_shift | b >> qt_blue_rounding_shift;
+
+ return qRgb(tr,tg,tb);
+}
+
+uint QColormap::pixel(const QColor &color) const
+{
+ QRgb rgb = color.rgba();
+ if (d->mode == QColormap::Direct) {
+ switch(d->depth) {
+ case 16:
+ return qt_convRgbTo16(rgb);
+ case 24:
+ case 32:
+ {
+ const int r = qRed(rgb);
+ const int g = qGreen(rgb);
+ const int b = qBlue(rgb);
+ const int red_shift = 16;
+ const int green_shift = 8;
+ const int red_mask = 0xff0000;
+ const int green_mask = 0x00ff00;
+ const int blue_mask = 0x0000ff;
+ const int tg = g << green_shift;
+#ifdef QT_QWS_DEPTH_32_BGR
+ if (qt_screen->pixelType() == QScreen::BGRPixel) {
+ const int tb = b << red_shift;
+ return 0xff000000 | (r & blue_mask) | (tg & green_mask) | (tb & red_mask);
+ }
+#endif
+ const int tr = r << red_shift;
+ return 0xff000000 | (b & blue_mask) | (tg & green_mask) | (tr & red_mask);
+ }
+ }
+ }
+ //XXX
+ //return qt_screen->alloc(qRed(rgb), qGreen(rgb), qBlue(rgb));
+ return 0;
+}
+
+const QColor QColormap::colorAt(uint pixel) const
+{
+ if (d->mode == Direct) {
+ if (d->depth == 16) {
+ pixel = qt_conv16ToRgb(pixel);
+ }
+ const int red_shift = 16;
+ const int green_shift = 8;
+ const int red_mask = 0xff0000;
+ const int green_mask = 0x00ff00;
+ const int blue_mask = 0x0000ff;
+#ifdef QT_QWS_DEPTH_32_BGR
+ if (qt_screen->pixelType() == QScreen::BGRPixel) {
+ return QColor((pixel & blue_mask),
+ (pixel & green_mask) >> green_shift,
+ (pixel & red_mask) >> red_shift);
+ }
+#endif
+ return QColor((pixel & red_mask) >> red_shift,
+ (pixel & green_mask) >> green_shift,
+ (pixel & blue_mask));
+ }
+#if 0 // XXX
+ Q_ASSERT_X(int(pixel) < qt_screen->numCols(), "QColormap::colorAt", "pixel out of bounds of palette");
+ return QColor(qt_screen->clut()[pixel]);
+#endif
+ return QColor();
+}
+
+const QVector<QColor> QColormap::colormap() const
+{
+ return QVector<QColor>();
+}
+
+QColormap &QColormap::operator=(const QColormap &colormap)
+{ qAtomicAssign(d, colormap.d); return *this; }
+
+QT_END_NAMESPACE
diff --git a/src/widgets/util/qcompleter.cpp b/src/widgets/util/qcompleter.cpp
new file mode 100644
index 0000000000..d1ec03f1e4
--- /dev/null
+++ b/src/widgets/util/qcompleter.cpp
@@ -0,0 +1,1833 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \class QCompleter
+ \brief The QCompleter class provides completions based on an item model.
+ \since 4.2
+
+ You can use QCompleter to provide auto completions in any Qt
+ widget, such as QLineEdit and QComboBox.
+ When the user starts typing a word, QCompleter suggests possible ways of
+ completing the word, based on a word list. The word list is
+ provided as a QAbstractItemModel. (For simple applications, where
+ the word list is static, you can pass a QStringList to
+ QCompleter's constructor.)
+
+ \tableofcontents
+
+ \section1 Basic Usage
+
+ A QCompleter is used typically with a QLineEdit or QComboBox.
+ For example, here's how to provide auto completions from a simple
+ word list in a QLineEdit:
+
+ \snippet doc/src/snippets/code/src_gui_util_qcompleter.cpp 0
+
+ A QFileSystemModel can be used to provide auto completion of file names.
+ For example:
+
+ \snippet doc/src/snippets/code/src_gui_util_qcompleter.cpp 1
+
+ To set the model on which QCompleter should operate, call
+ setModel(). By default, QCompleter will attempt to match the \l
+ {completionPrefix}{completion prefix} (i.e., the word that the
+ user has started typing) against the Qt::EditRole data stored in
+ column 0 in the model case sensitively. This can be changed
+ using setCompletionRole(), setCompletionColumn(), and
+ setCaseSensitivity().
+
+ If the model is sorted on the column and role that are used for completion,
+ you can call setModelSorting() with either
+ QCompleter::CaseSensitivelySortedModel or
+ QCompleter::CaseInsensitivelySortedModel as the argument. On large models,
+ this can lead to significant performance improvements, because QCompleter
+ can then use binary search instead of linear search.
+
+ The model can be a \l{QAbstractListModel}{list model},
+ a \l{QAbstractTableModel}{table model}, or a
+ \l{QAbstractItemModel}{tree model}. Completion on tree models
+ is slightly more involved and is covered in the \l{Handling
+ Tree Models} section below.
+
+ The completionMode() determines the mode used to provide completions to
+ the user.
+
+ \section1 Iterating Through Completions
+
+ To retrieve a single candidate string, call setCompletionPrefix()
+ with the text that needs to be completed and call
+ currentCompletion(). You can iterate through the list of
+ completions as below:
+
+ \snippet doc/src/snippets/code/src_gui_util_qcompleter.cpp 2
+
+ completionCount() returns the total number of completions for the
+ current prefix. completionCount() should be avoided when possible,
+ since it requires a scan of the entire model.
+
+ \section1 The Completion Model
+
+ completionModel() return a list model that contains all possible
+ completions for the current completion prefix, in the order in which
+ they appear in the model. This model can be used to display the current
+ completions in a custom view. Calling setCompletionPrefix() automatically
+ refreshes the completion model.
+
+ \section1 Handling Tree Models
+
+ QCompleter can look for completions in tree models, assuming
+ that any item (or sub-item or sub-sub-item) can be unambiguously
+ represented as a string by specifying the path to the item. The
+ completion is then performed one level at a time.
+
+ Let's take the example of a user typing in a file system path.
+ The model is a (hierarchical) QFileSystemModel. The completion
+ occurs for every element in the path. For example, if the current
+ text is \c C:\Wind, QCompleter might suggest \c Windows to
+ complete the current path element. Similarly, if the current text
+ is \c C:\Windows\Sy, QCompleter might suggest \c System.
+
+ For this kind of completion to work, QCompleter needs to be able to
+ split the path into a list of strings that are matched at each level.
+ For \c C:\Windows\Sy, it needs to be split as "C:", "Windows" and "Sy".
+ The default implementation of splitPath(), splits the completionPrefix
+ using QDir::separator() if the model is a QFileSystemModel.
+
+ To provide completions, QCompleter needs to know the path from an index.
+ This is provided by pathFromIndex(). The default implementation of
+ pathFromIndex(), returns the data for the \l{Qt::EditRole}{edit role}
+ for list models and the absolute file path if the mode is a QFileSystemModel.
+
+ \sa QAbstractItemModel, QLineEdit, QComboBox, {Completer Example}
+*/
+
+#include "qcompleter_p.h"
+
+#ifndef QT_NO_COMPLETER
+
+#include "QtWidgets/qscrollbar.h"
+#include "QtWidgets/qstringlistmodel.h"
+#include "QtWidgets/qdirmodel.h"
+#include "QtWidgets/qfilesystemmodel.h"
+#include "QtWidgets/qheaderview.h"
+#include "QtWidgets/qlistview.h"
+#include "QtWidgets/qapplication.h"
+#include "QtGui/qevent.h"
+#include "QtWidgets/qheaderview.h"
+#include "QtWidgets/qdesktopwidget.h"
+#include "QtWidgets/qlineedit.h"
+
+QT_BEGIN_NAMESPACE
+
+QCompletionModel::QCompletionModel(QCompleterPrivate *c, QObject *parent)
+ : QAbstractProxyModel(*new QCompletionModelPrivate, parent),
+ c(c), showAll(false)
+{
+ createEngine();
+}
+
+int QCompletionModel::columnCount(const QModelIndex &) const
+{
+ Q_D(const QCompletionModel);
+ return d->model->columnCount();
+}
+
+void QCompletionModel::setSourceModel(QAbstractItemModel *source)
+{
+ bool hadModel = (sourceModel() != 0);
+
+ if (hadModel)
+ QObject::disconnect(sourceModel(), 0, this, 0);
+
+ QAbstractProxyModel::setSourceModel(source);
+
+ if (source) {
+ // TODO: Optimize updates in the source model
+ connect(source, SIGNAL(modelReset()), this, SLOT(invalidate()));
+ connect(source, SIGNAL(destroyed()), this, SLOT(modelDestroyed()));
+ connect(source, SIGNAL(layoutChanged()), this, SLOT(invalidate()));
+ connect(source, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(rowsInserted()));
+ connect(source, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(invalidate()));
+ connect(source, SIGNAL(columnsInserted(QModelIndex,int,int)), this, SLOT(invalidate()));
+ connect(source, SIGNAL(columnsRemoved(QModelIndex,int,int)), this, SLOT(invalidate()));
+ connect(source, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(invalidate()));
+ }
+
+ invalidate();
+}
+
+void QCompletionModel::createEngine()
+{
+ bool sortedEngine = false;
+ switch (c->sorting) {
+ case QCompleter::UnsortedModel:
+ sortedEngine = false;
+ break;
+ case QCompleter::CaseSensitivelySortedModel:
+ sortedEngine = c->cs == Qt::CaseSensitive;
+ break;
+ case QCompleter::CaseInsensitivelySortedModel:
+ sortedEngine = c->cs == Qt::CaseInsensitive;
+ break;
+ }
+
+ if (sortedEngine)
+ engine.reset(new QSortedModelEngine(c));
+ else
+ engine.reset(new QUnsortedModelEngine(c));
+}
+
+QModelIndex QCompletionModel::mapToSource(const QModelIndex& index) const
+{
+ Q_D(const QCompletionModel);
+ if (!index.isValid())
+ return engine->curParent;
+
+ int row;
+ QModelIndex parent = engine->curParent;
+ if (!showAll) {
+ if (!engine->matchCount())
+ return QModelIndex();
+ Q_ASSERT(index.row() < engine->matchCount());
+ QIndexMapper& rootIndices = engine->historyMatch.indices;
+ if (index.row() < rootIndices.count()) {
+ row = rootIndices[index.row()];
+ parent = QModelIndex();
+ } else {
+ row = engine->curMatch.indices[index.row() - rootIndices.count()];
+ }
+ } else {
+ row = index.row();
+ }
+
+ return d->model->index(row, index.column(), parent);
+}
+
+QModelIndex QCompletionModel::mapFromSource(const QModelIndex& idx) const
+{
+ if (!idx.isValid())
+ return QModelIndex();
+
+ int row = -1;
+ if (!showAll) {
+ if (!engine->matchCount())
+ return QModelIndex();
+
+ QIndexMapper& rootIndices = engine->historyMatch.indices;
+ if (idx.parent().isValid()) {
+ if (idx.parent() != engine->curParent)
+ return QModelIndex();
+ } else {
+ row = rootIndices.indexOf(idx.row());
+ if (row == -1 && engine->curParent.isValid())
+ return QModelIndex(); // source parent and our parent don't match
+ }
+
+ if (row == -1) {
+ QIndexMapper& indices = engine->curMatch.indices;
+ engine->filterOnDemand(idx.row() - indices.last());
+ row = indices.indexOf(idx.row()) + rootIndices.count();
+ }
+
+ if (row == -1)
+ return QModelIndex();
+ } else {
+ if (idx.parent() != engine->curParent)
+ return QModelIndex();
+ row = idx.row();
+ }
+
+ return createIndex(row, idx.column());
+}
+
+bool QCompletionModel::setCurrentRow(int row)
+{
+ if (row < 0 || !engine->matchCount())
+ return false;
+
+ if (row >= engine->matchCount())
+ engine->filterOnDemand(row + 1 - engine->matchCount());
+
+ if (row >= engine->matchCount()) // invalid row
+ return false;
+
+ engine->curRow = row;
+ return true;
+}
+
+QModelIndex QCompletionModel::currentIndex(bool sourceIndex) const
+{
+ if (!engine->matchCount())
+ return QModelIndex();
+
+ int row = engine->curRow;
+ if (showAll)
+ row = engine->curMatch.indices[engine->curRow];
+
+ QModelIndex idx = createIndex(row, c->column);
+ if (!sourceIndex)
+ return idx;
+ return mapToSource(idx);
+}
+
+QModelIndex QCompletionModel::index(int row, int column, const QModelIndex& parent) const
+{
+ Q_D(const QCompletionModel);
+ if (row < 0 || column < 0 || column >= columnCount(parent) || parent.isValid())
+ return QModelIndex();
+
+ if (!showAll) {
+ if (!engine->matchCount())
+ return QModelIndex();
+ if (row >= engine->historyMatch.indices.count()) {
+ int want = row + 1 - engine->matchCount();
+ if (want > 0)
+ engine->filterOnDemand(want);
+ if (row >= engine->matchCount())
+ return QModelIndex();
+ }
+ } else {
+ if (row >= d->model->rowCount(engine->curParent))
+ return QModelIndex();
+ }
+
+ return createIndex(row, column);
+}
+
+int QCompletionModel::completionCount() const
+{
+ if (!engine->matchCount())
+ return 0;
+
+ engine->filterOnDemand(INT_MAX);
+ return engine->matchCount();
+}
+
+int QCompletionModel::rowCount(const QModelIndex &parent) const
+{
+ Q_D(const QCompletionModel);
+ if (parent.isValid())
+ return 0;
+
+ if (showAll) {
+ // Show all items below current parent, even if we have no valid matches
+ if (engine->curParts.count() != 1 && !engine->matchCount()
+ && !engine->curParent.isValid())
+ return 0;
+ return d->model->rowCount(engine->curParent);
+ }
+
+ return completionCount();
+}
+
+void QCompletionModel::setFiltered(bool filtered)
+{
+ if (showAll == !filtered)
+ return;
+ showAll = !filtered;
+ resetModel();
+}
+
+bool QCompletionModel::hasChildren(const QModelIndex &parent) const
+{
+ Q_D(const QCompletionModel);
+ if (parent.isValid())
+ return false;
+
+ if (showAll)
+ return d->model->hasChildren(mapToSource(parent));
+
+ if (!engine->matchCount())
+ return false;
+
+ return true;
+}
+
+QVariant QCompletionModel::data(const QModelIndex& index, int role) const
+{
+ Q_D(const QCompletionModel);
+ return d->model->data(mapToSource(index), role);
+}
+
+void QCompletionModel::modelDestroyed()
+{
+ QAbstractProxyModel::setSourceModel(0); // switch to static empty model
+ invalidate();
+}
+
+void QCompletionModel::rowsInserted()
+{
+ invalidate();
+ emit rowsAdded();
+}
+
+void QCompletionModel::invalidate()
+{
+ engine->cache.clear();
+ filter(engine->curParts);
+}
+
+void QCompletionModel::filter(const QStringList& parts)
+{
+ Q_D(QCompletionModel);
+ engine->filter(parts);
+ resetModel();
+
+ if (d->model->canFetchMore(engine->curParent))
+ d->model->fetchMore(engine->curParent);
+}
+
+void QCompletionModel::resetModel()
+{
+ if (rowCount() == 0) {
+ reset();
+ return;
+ }
+
+ emit layoutAboutToBeChanged();
+ QModelIndexList piList = persistentIndexList();
+ QModelIndexList empty;
+ for (int i = 0; i < piList.size(); i++)
+ empty.append(QModelIndex());
+ changePersistentIndexList(piList, empty);
+ emit layoutChanged();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void QCompletionEngine::filter(const QStringList& parts)
+{
+ const QAbstractItemModel *model = c->proxy->sourceModel();
+ curParts = parts;
+ if (curParts.isEmpty())
+ curParts.append(QString());
+
+ curRow = -1;
+ curParent = QModelIndex();
+ curMatch = QMatchData();
+ historyMatch = filterHistory();
+
+ if (!model)
+ return;
+
+ QModelIndex parent;
+ for (int i = 0; i < curParts.count() - 1; i++) {
+ QString part = curParts[i];
+ int emi = filter(part, parent, -1).exactMatchIndex;
+ if (emi == -1)
+ return;
+ parent = model->index(emi, c->column, parent);
+ }
+
+ // Note that we set the curParent to a valid parent, even if we have no matches
+ // When filtering is disabled, we show all the items under this parent
+ curParent = parent;
+ if (curParts.last().isEmpty())
+ curMatch = QMatchData(QIndexMapper(0, model->rowCount(curParent) - 1), -1, false);
+ else
+ curMatch = filter(curParts.last(), curParent, 1); // build at least one
+ curRow = curMatch.isValid() ? 0 : -1;
+}
+
+QMatchData QCompletionEngine::filterHistory()
+{
+ QAbstractItemModel *source = c->proxy->sourceModel();
+ if (curParts.count() <= 1 || c->proxy->showAll || !source)
+ return QMatchData();
+ bool isDirModel = false;
+ bool isFsModel = false;
+#ifndef QT_NO_DIRMODEL
+ isDirModel = (qobject_cast<QDirModel *>(source) != 0);
+#endif
+#ifndef QT_NO_FILESYSTEMMODEL
+ isFsModel = (qobject_cast<QFileSystemModel *>(source) != 0);
+#endif
+ QVector<int> v;
+ QIndexMapper im(v);
+ QMatchData m(im, -1, true);
+
+ for (int i = 0; i < source->rowCount(); i++) {
+ QString str = source->index(i, c->column).data().toString();
+ if (str.startsWith(c->prefix, c->cs)
+#if (!defined(Q_OS_WIN) || defined(Q_OS_WINCE)) && !defined(Q_OS_SYMBIAN)
+ && ((!isFsModel && !isDirModel) || QDir::toNativeSeparators(str) != QDir::separator())
+#endif
+ )
+ m.indices.append(i);
+ }
+ return m;
+}
+
+// Returns a match hint from the cache by chopping the search string
+bool QCompletionEngine::matchHint(QString part, const QModelIndex& parent, QMatchData *hint)
+{
+ if (c->cs == Qt::CaseInsensitive)
+ part = part.toLower();
+
+ const CacheItem& map = cache[parent];
+
+ QString key = part;
+ while (!key.isEmpty()) {
+ key.chop(1);
+ if (map.contains(key)) {
+ *hint = map[key];
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool QCompletionEngine::lookupCache(QString part, const QModelIndex& parent, QMatchData *m)
+{
+ if (c->cs == Qt::CaseInsensitive)
+ part = part.toLower();
+ const CacheItem& map = cache[parent];
+ if (!map.contains(part))
+ return false;
+ *m = map[part];
+ return true;
+}
+
+// When the cache size exceeds 1MB, it clears out about 1/2 of the cache.
+void QCompletionEngine::saveInCache(QString part, const QModelIndex& parent, const QMatchData& m)
+{
+ QMatchData old = cache[parent].take(part);
+ cost = cost + m.indices.cost() - old.indices.cost();
+ if (cost * sizeof(int) > 1024 * 1024) {
+ QMap<QModelIndex, CacheItem>::iterator it1 = cache.begin();
+ while (it1 != cache.end()) {
+ CacheItem& ci = it1.value();
+ int sz = ci.count()/2;
+ QMap<QString, QMatchData>::iterator it2 = ci.begin();
+ int i = 0;
+ while (it2 != ci.end() && i < sz) {
+ cost -= it2.value().indices.cost();
+ it2 = ci.erase(it2);
+ i++;
+ }
+ if (ci.count() == 0) {
+ it1 = cache.erase(it1);
+ } else {
+ ++it1;
+ }
+ }
+ }
+
+ if (c->cs == Qt::CaseInsensitive)
+ part = part.toLower();
+ cache[parent][part] = m;
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+QIndexMapper QSortedModelEngine::indexHint(QString part, const QModelIndex& parent, Qt::SortOrder order)
+{
+ const QAbstractItemModel *model = c->proxy->sourceModel();
+
+ if (c->cs == Qt::CaseInsensitive)
+ part = part.toLower();
+
+ const CacheItem& map = cache[parent];
+
+ // Try to find a lower and upper bound for the search from previous results
+ int to = model->rowCount(parent) - 1;
+ int from = 0;
+ const CacheItem::const_iterator it = map.lowerBound(part);
+
+ // look backward for first valid hint
+ for(CacheItem::const_iterator it1 = it; it1-- != map.constBegin();) {
+ const QMatchData& value = it1.value();
+ if (value.isValid()) {
+ if (order == Qt::AscendingOrder) {
+ from = value.indices.last() + 1;
+ } else {
+ to = value.indices.first() - 1;
+ }
+ break;
+ }
+ }
+
+ // look forward for first valid hint
+ for(CacheItem::const_iterator it2 = it; it2 != map.constEnd(); ++it2) {
+ const QMatchData& value = it2.value();
+ if (value.isValid() && !it2.key().startsWith(part)) {
+ if (order == Qt::AscendingOrder) {
+ to = value.indices.first() - 1;
+ } else {
+ from = value.indices.first() + 1;
+ }
+ break;
+ }
+ }
+
+ return QIndexMapper(from, to);
+}
+
+Qt::SortOrder QSortedModelEngine::sortOrder(const QModelIndex &parent) const
+{
+ const QAbstractItemModel *model = c->proxy->sourceModel();
+
+ int rowCount = model->rowCount(parent);
+ if (rowCount < 2)
+ return Qt::AscendingOrder;
+ QString first = model->data(model->index(0, c->column, parent), c->role).toString();
+ QString last = model->data(model->index(rowCount - 1, c->column, parent), c->role).toString();
+ return QString::compare(first, last, c->cs) <= 0 ? Qt::AscendingOrder : Qt::DescendingOrder;
+}
+
+QMatchData QSortedModelEngine::filter(const QString& part, const QModelIndex& parent, int)
+{
+ const QAbstractItemModel *model = c->proxy->sourceModel();
+
+ QMatchData hint;
+ if (lookupCache(part, parent, &hint))
+ return hint;
+
+ QIndexMapper indices;
+ Qt::SortOrder order = sortOrder(parent);
+
+ if (matchHint(part, parent, &hint)) {
+ if (!hint.isValid())
+ return QMatchData();
+ indices = hint.indices;
+ } else {
+ indices = indexHint(part, parent, order);
+ }
+
+ // binary search the model within 'indices' for 'part' under 'parent'
+ int high = indices.to() + 1;
+ int low = indices.from() - 1;
+ int probe;
+ QModelIndex probeIndex;
+ QString probeData;
+
+ while (high - low > 1)
+ {
+ probe = (high + low) / 2;
+ probeIndex = model->index(probe, c->column, parent);
+ probeData = model->data(probeIndex, c->role).toString();
+ const int cmp = QString::compare(probeData, part, c->cs);
+ if ((order == Qt::AscendingOrder && cmp >= 0)
+ || (order == Qt::DescendingOrder && cmp < 0)) {
+ high = probe;
+ } else {
+ low = probe;
+ }
+ }
+
+ if ((order == Qt::AscendingOrder && low == indices.to())
+ || (order == Qt::DescendingOrder && high == indices.from())) { // not found
+ saveInCache(part, parent, QMatchData());
+ return QMatchData();
+ }
+
+ probeIndex = model->index(order == Qt::AscendingOrder ? low+1 : high-1, c->column, parent);
+ probeData = model->data(probeIndex, c->role).toString();
+ if (!probeData.startsWith(part, c->cs)) {
+ saveInCache(part, parent, QMatchData());
+ return QMatchData();
+ }
+
+ const bool exactMatch = QString::compare(probeData, part, c->cs) == 0;
+ int emi = exactMatch ? (order == Qt::AscendingOrder ? low+1 : high-1) : -1;
+
+ int from = 0;
+ int to = 0;
+ if (order == Qt::AscendingOrder) {
+ from = low + 1;
+ high = indices.to() + 1;
+ low = from;
+ } else {
+ to = high - 1;
+ low = indices.from() - 1;
+ high = to;
+ }
+
+ while (high - low > 1)
+ {
+ probe = (high + low) / 2;
+ probeIndex = model->index(probe, c->column, parent);
+ probeData = model->data(probeIndex, c->role).toString();
+ const bool startsWith = probeData.startsWith(part, c->cs);
+ if ((order == Qt::AscendingOrder && startsWith)
+ || (order == Qt::DescendingOrder && !startsWith)) {
+ low = probe;
+ } else {
+ high = probe;
+ }
+ }
+
+ QMatchData m(order == Qt::AscendingOrder ? QIndexMapper(from, high - 1) : QIndexMapper(low+1, to), emi, false);
+ saveInCache(part, parent, m);
+ return m;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+int QUnsortedModelEngine::buildIndices(const QString& str, const QModelIndex& parent, int n,
+ const QIndexMapper& indices, QMatchData* m)
+{
+ Q_ASSERT(m->partial);
+ Q_ASSERT(n != -1 || m->exactMatchIndex == -1);
+ const QAbstractItemModel *model = c->proxy->sourceModel();
+ int i, count = 0;
+
+ for (i = 0; i < indices.count() && count != n; ++i) {
+ QModelIndex idx = model->index(indices[i], c->column, parent);
+ QString data = model->data(idx, c->role).toString();
+ if (!data.startsWith(str, c->cs) || !(model->flags(idx) & Qt::ItemIsSelectable))
+ continue;
+ m->indices.append(indices[i]);
+ ++count;
+ if (m->exactMatchIndex == -1 && QString::compare(data, str, c->cs) == 0) {
+ m->exactMatchIndex = indices[i];
+ if (n == -1)
+ return indices[i];
+ }
+ }
+ return indices[i-1];
+}
+
+void QUnsortedModelEngine::filterOnDemand(int n)
+{
+ Q_ASSERT(matchCount());
+ if (!curMatch.partial)
+ return;
+ Q_ASSERT(n >= -1);
+ const QAbstractItemModel *model = c->proxy->sourceModel();
+ int lastRow = model->rowCount(curParent) - 1;
+ QIndexMapper im(curMatch.indices.last() + 1, lastRow);
+ int lastIndex = buildIndices(curParts.last(), curParent, n, im, &curMatch);
+ curMatch.partial = (lastRow != lastIndex);
+ saveInCache(curParts.last(), curParent, curMatch);
+}
+
+QMatchData QUnsortedModelEngine::filter(const QString& part, const QModelIndex& parent, int n)
+{
+ QMatchData hint;
+
+ QVector<int> v;
+ QIndexMapper im(v);
+ QMatchData m(im, -1, true);
+
+ const QAbstractItemModel *model = c->proxy->sourceModel();
+ bool foundInCache = lookupCache(part, parent, &m);
+
+ if (!foundInCache) {
+ if (matchHint(part, parent, &hint) && !hint.isValid())
+ return QMatchData();
+ }
+
+ if (!foundInCache && !hint.isValid()) {
+ const int lastRow = model->rowCount(parent) - 1;
+ QIndexMapper all(0, lastRow);
+ int lastIndex = buildIndices(part, parent, n, all, &m);
+ m.partial = (lastIndex != lastRow);
+ } else {
+ if (!foundInCache) { // build from hint as much as we can
+ buildIndices(part, parent, INT_MAX, hint.indices, &m);
+ m.partial = hint.partial;
+ }
+ if (m.partial && ((n == -1 && m.exactMatchIndex == -1) || (m.indices.count() < n))) {
+ // need more and have more
+ const int lastRow = model->rowCount(parent) - 1;
+ QIndexMapper rest(hint.indices.last() + 1, lastRow);
+ int want = n == -1 ? -1 : n - m.indices.count();
+ int lastIndex = buildIndices(part, parent, want, rest, &m);
+ m.partial = (lastRow != lastIndex);
+ }
+ }
+
+ saveInCache(part, parent, m);
+ return m;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+QCompleterPrivate::QCompleterPrivate()
+: widget(0), proxy(0), popup(0), cs(Qt::CaseSensitive), role(Qt::EditRole), column(0),
+ maxVisibleItems(7), sorting(QCompleter::UnsortedModel), wrap(true), eatFocusOut(true),
+ hiddenBecauseNoMatch(false)
+{
+}
+
+void QCompleterPrivate::init(QAbstractItemModel *m)
+{
+ Q_Q(QCompleter);
+ proxy = new QCompletionModel(this, q);
+ QObject::connect(proxy, SIGNAL(rowsAdded()), q, SLOT(_q_autoResizePopup()));
+ q->setModel(m);
+#ifdef QT_NO_LISTVIEW
+ q->setCompletionMode(QCompleter::InlineCompletion);
+#else
+ q->setCompletionMode(QCompleter::PopupCompletion);
+#endif // QT_NO_LISTVIEW
+}
+
+void QCompleterPrivate::setCurrentIndex(QModelIndex index, bool select)
+{
+ Q_Q(QCompleter);
+ if (!q->popup())
+ return;
+ if (!select) {
+ popup->selectionModel()->setCurrentIndex(index, QItemSelectionModel::NoUpdate);
+ } else {
+ if (!index.isValid())
+ popup->selectionModel()->clear();
+ else
+ popup->selectionModel()->setCurrentIndex(index, QItemSelectionModel::Select
+ | QItemSelectionModel::Rows);
+ }
+ index = popup->selectionModel()->currentIndex();
+ if (!index.isValid())
+ popup->scrollToTop();
+ else
+ popup->scrollTo(index, QAbstractItemView::PositionAtTop);
+}
+
+void QCompleterPrivate::_q_completionSelected(const QItemSelection& selection)
+{
+ QModelIndex index;
+ if (!selection.indexes().isEmpty())
+ index = selection.indexes().first();
+
+ _q_complete(index, true);
+}
+
+void QCompleterPrivate::_q_complete(QModelIndex index, bool highlighted)
+{
+ Q_Q(QCompleter);
+ QString completion;
+
+ if (!index.isValid() || (!proxy->showAll && (index.row() >= proxy->engine->matchCount()))) {
+ completion = prefix;
+ } else {
+ if (!(index.flags() & Qt::ItemIsEnabled))
+ return;
+ QModelIndex si = proxy->mapToSource(index);
+ si = si.sibling(si.row(), column); // for clicked()
+ completion = q->pathFromIndex(si);
+#ifndef QT_NO_DIRMODEL
+ // add a trailing separator in inline
+ if (mode == QCompleter::InlineCompletion) {
+ if (qobject_cast<QDirModel *>(proxy->sourceModel()) && QFileInfo(completion).isDir())
+ completion += QDir::separator();
+ }
+#endif
+#ifndef QT_NO_FILESYSTEMMODEL
+ // add a trailing separator in inline
+ if (mode == QCompleter::InlineCompletion) {
+ if (qobject_cast<QFileSystemModel *>(proxy->sourceModel()) && QFileInfo(completion).isDir())
+ completion += QDir::separator();
+ }
+#endif
+ }
+
+ if (highlighted) {
+ emit q->highlighted(index);
+ emit q->highlighted(completion);
+ } else {
+ emit q->activated(index);
+ emit q->activated(completion);
+ }
+}
+
+void QCompleterPrivate::_q_autoResizePopup()
+{
+ if (!popup || !popup->isVisible())
+ return;
+ showPopup(popupRect);
+}
+
+void QCompleterPrivate::showPopup(const QRect& rect)
+{
+ const QRect screen = QApplication::desktop()->availableGeometry(widget);
+ Qt::LayoutDirection dir = widget->layoutDirection();
+ QPoint pos;
+ int rh, w;
+ int h = (popup->sizeHintForRow(0) * qMin(maxVisibleItems, popup->model()->rowCount()) + 3) + 3;
+ QScrollBar *hsb = popup->horizontalScrollBar();
+ if (hsb && hsb->isVisible())
+ h += popup->horizontalScrollBar()->sizeHint().height();
+
+ if (rect.isValid()) {
+ rh = rect.height();
+ w = rect.width();
+ pos = widget->mapToGlobal(dir == Qt::RightToLeft ? rect.bottomRight() : rect.bottomLeft());
+ } else {
+ rh = widget->height();
+ pos = widget->mapToGlobal(QPoint(0, widget->height() - 2));
+ w = widget->width();
+ }
+
+ if (w > screen.width())
+ w = screen.width();
+ if ((pos.x() + w) > (screen.x() + screen.width()))
+ pos.setX(screen.x() + screen.width() - w);
+ if (pos.x() < screen.x())
+ pos.setX(screen.x());
+
+ int top = pos.y() - rh - screen.top() + 2;
+ int bottom = screen.bottom() - pos.y();
+ h = qMax(h, popup->minimumHeight());
+ if (h > bottom) {
+ h = qMin(qMax(top, bottom), h);
+
+ if (top > bottom)
+ pos.setY(pos.y() - h - rh + 2);
+ }
+
+ popup->setGeometry(pos.x(), pos.y(), w, h);
+
+ if (!popup->isVisible())
+ popup->show();
+}
+
+void QCompleterPrivate::_q_fileSystemModelDirectoryLoaded(const QString &path)
+{
+ Q_Q(QCompleter);
+ // Slot called when QFileSystemModel has finished loading.
+ // If we hide the popup because there was no match because the model was not loaded yet,
+ // we re-start the completion when we get the results
+ if (hiddenBecauseNoMatch
+ && prefix.startsWith(path) && prefix != (path + QLatin1Char('/'))
+ && widget) {
+ q->complete();
+ }
+}
+
+/*!
+ Constructs a completer object with the given \a parent.
+*/
+QCompleter::QCompleter(QObject *parent)
+: QObject(*new QCompleterPrivate(), parent)
+{
+ Q_D(QCompleter);
+ d->init();
+}
+
+/*!
+ Constructs a completer object with the given \a parent that provides completions
+ from the specified \a model.
+*/
+QCompleter::QCompleter(QAbstractItemModel *model, QObject *parent)
+ : QObject(*new QCompleterPrivate(), parent)
+{
+ Q_D(QCompleter);
+ d->init(model);
+}
+
+#ifndef QT_NO_STRINGLISTMODEL
+/*!
+ Constructs a QCompleter object with the given \a parent that uses the specified
+ \a list as a source of possible completions.
+*/
+QCompleter::QCompleter(const QStringList& list, QObject *parent)
+: QObject(*new QCompleterPrivate(), parent)
+{
+ Q_D(QCompleter);
+ d->init(new QStringListModel(list, this));
+}
+#endif // QT_NO_STRINGLISTMODEL
+
+/*!
+ Destroys the completer object.
+*/
+QCompleter::~QCompleter()
+{
+}
+
+/*!
+ Sets the widget for which completion are provided for to \a widget. This
+ function is automatically called when a QCompleter is set on a QLineEdit
+ using QLineEdit::setCompleter() or on a QComboBox using
+ QComboBox::setCompleter(). The widget needs to be set explicitly when
+ providing completions for custom widgets.
+
+ \sa widget(), setModel(), setPopup()
+ */
+void QCompleter::setWidget(QWidget *widget)
+{
+ Q_D(QCompleter);
+ if (d->widget)
+ d->widget->removeEventFilter(this);
+ d->widget = widget;
+ if (d->widget)
+ d->widget->installEventFilter(this);
+ if (d->popup) {
+ d->popup->hide();
+ d->popup->setFocusProxy(d->widget);
+ }
+}
+
+/*!
+ Returns the widget for which the completer object is providing completions.
+
+ \sa setWidget()
+ */
+QWidget *QCompleter::widget() const
+{
+ Q_D(const QCompleter);
+ return d->widget;
+}
+
+/*!
+ Sets the model which provides completions to \a model. The \a model can
+ be list model or a tree model. If a model has been already previously set
+ and it has the QCompleter as its parent, it is deleted.
+
+ For convenience, if \a model is a QFileSystemModel, QCompleter switches its
+ caseSensitivity to Qt::CaseInsensitive on Windows and Qt::CaseSensitive
+ on other platforms.
+
+ \sa completionModel(), modelSorting, {Handling Tree Models}
+*/
+void QCompleter::setModel(QAbstractItemModel *model)
+{
+ Q_D(QCompleter);
+ QAbstractItemModel *oldModel = d->proxy->sourceModel();
+ d->proxy->setSourceModel(model);
+ if (d->popup)
+ setPopup(d->popup); // set the model and make new connections
+ if (oldModel && oldModel->QObject::parent() == this)
+ delete oldModel;
+#ifndef QT_NO_DIRMODEL
+ if (qobject_cast<QDirModel *>(model)) {
+#if (defined(Q_OS_WIN) && !defined(Q_OS_WINCE)) || defined(Q_OS_SYMBIAN)
+ setCaseSensitivity(Qt::CaseInsensitive);
+#else
+ setCaseSensitivity(Qt::CaseSensitive);
+#endif
+ }
+#endif // QT_NO_DIRMODEL
+#ifndef QT_NO_FILESYSTEMMODEL
+ QFileSystemModel *fsModel = qobject_cast<QFileSystemModel *>(model);
+ if (fsModel) {
+#if (defined(Q_OS_WIN) && !defined(Q_OS_WINCE)) || defined(Q_OS_SYMBIAN)
+ setCaseSensitivity(Qt::CaseInsensitive);
+#else
+ setCaseSensitivity(Qt::CaseSensitive);
+#endif
+ setCompletionRole(QFileSystemModel::FileNameRole);
+ connect(fsModel, SIGNAL(directoryLoaded(QString)), this, SLOT(_q_fileSystemModelDirectoryLoaded(QString)));
+ }
+#endif // QT_NO_FILESYSTEMMODEL
+}
+
+/*!
+ Returns the model that provides completion strings.
+
+ \sa completionModel()
+*/
+QAbstractItemModel *QCompleter::model() const
+{
+ Q_D(const QCompleter);
+ return d->proxy->sourceModel();
+}
+
+/*!
+ \enum QCompleter::CompletionMode
+
+ This enum specifies how completions are provided to the user.
+
+ \value PopupCompletion Current completions are displayed in a popup window.
+ \value InlineCompletion Completions appear inline (as selected text).
+ \value UnfilteredPopupCompletion All possible completions are displayed in a popup window with the most likely suggestion indicated as current.
+
+ \sa setCompletionMode()
+*/
+
+/*!
+ \property QCompleter::completionMode
+ \brief how the completions are provided to the user
+
+ The default value is QCompleter::PopupCompletion.
+*/
+void QCompleter::setCompletionMode(QCompleter::CompletionMode mode)
+{
+ Q_D(QCompleter);
+ d->mode = mode;
+ d->proxy->setFiltered(mode != QCompleter::UnfilteredPopupCompletion);
+
+ if (mode == QCompleter::InlineCompletion) {
+ if (d->widget)
+ d->widget->removeEventFilter(this);
+ if (d->popup) {
+ d->popup->deleteLater();
+ d->popup = 0;
+ }
+ } else {
+ if (d->widget)
+ d->widget->installEventFilter(this);
+ }
+}
+
+QCompleter::CompletionMode QCompleter::completionMode() const
+{
+ Q_D(const QCompleter);
+ return d->mode;
+}
+
+/*!
+ Sets the popup used to display completions to \a popup. QCompleter takes
+ ownership of the view.
+
+ A QListView is automatically created when the completionMode() is set to
+ QCompleter::PopupCompletion or QCompleter::UnfilteredPopupCompletion. The
+ default popup displays the completionColumn().
+
+ Ensure that this function is called before the view settings are modified.
+ This is required since view's properties may require that a model has been
+ set on the view (for example, hiding columns in the view requires a model
+ to be set on the view).
+
+ \sa popup()
+*/
+void QCompleter::setPopup(QAbstractItemView *popup)
+{
+ Q_D(QCompleter);
+ Q_ASSERT(popup != 0);
+ if (d->popup) {
+ QObject::disconnect(d->popup->selectionModel(), 0, this, 0);
+ QObject::disconnect(d->popup, 0, this, 0);
+ }
+ if (d->popup != popup)
+ delete d->popup;
+ if (popup->model() != d->proxy)
+ popup->setModel(d->proxy);
+#if defined(Q_OS_MAC) && !defined(QT_MAC_USE_COCOA)
+ popup->show();
+#else
+ popup->hide();
+#endif
+
+ Qt::FocusPolicy origPolicy = Qt::NoFocus;
+ if (d->widget)
+ origPolicy = d->widget->focusPolicy();
+ popup->setParent(0, Qt::Popup);
+ popup->setFocusPolicy(Qt::NoFocus);
+ if (d->widget)
+ d->widget->setFocusPolicy(origPolicy);
+
+ popup->setFocusProxy(d->widget);
+ popup->installEventFilter(this);
+ popup->setItemDelegate(new QCompleterItemDelegate(popup));
+#ifndef QT_NO_LISTVIEW
+ if (QListView *listView = qobject_cast<QListView *>(popup)) {
+ listView->setModelColumn(d->column);
+ }
+#endif
+
+ QObject::connect(popup, SIGNAL(clicked(QModelIndex)),
+ this, SLOT(_q_complete(QModelIndex)));
+ QObject::connect(this, SIGNAL(activated(QModelIndex)),
+ popup, SLOT(hide()));
+
+ QObject::connect(popup->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
+ this, SLOT(_q_completionSelected(QItemSelection)));
+ d->popup = popup;
+}
+
+/*!
+ Returns the popup used to display completions.
+
+ \sa setPopup()
+*/
+QAbstractItemView *QCompleter::popup() const
+{
+ Q_D(const QCompleter);
+#ifndef QT_NO_LISTVIEW
+ if (!d->popup && completionMode() != QCompleter::InlineCompletion) {
+ QListView *listView = new QListView;
+ listView->setEditTriggers(QAbstractItemView::NoEditTriggers);
+ listView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ listView->setSelectionBehavior(QAbstractItemView::SelectRows);
+ listView->setSelectionMode(QAbstractItemView::SingleSelection);
+ listView->setModelColumn(d->column);
+ QCompleter *that = const_cast<QCompleter*>(this);
+ that->setPopup(listView);
+ }
+#endif // QT_NO_LISTVIEW
+ return d->popup;
+}
+
+/*!
+ \reimp
+*/
+bool QCompleter::event(QEvent *ev)
+{
+ return QObject::event(ev);
+}
+
+/*!
+ \reimp
+*/
+bool QCompleter::eventFilter(QObject *o, QEvent *e)
+{
+ Q_D(QCompleter);
+
+ if (d->eatFocusOut && o == d->widget && e->type() == QEvent::FocusOut) {
+ d->hiddenBecauseNoMatch = false;
+ if (d->popup && d->popup->isVisible())
+ return true;
+ }
+
+ if (o != d->popup)
+ return QObject::eventFilter(o, e);
+
+ switch (e->type()) {
+ case QEvent::KeyPress: {
+ QKeyEvent *ke = static_cast<QKeyEvent *>(e);
+
+ QModelIndex curIndex = d->popup->currentIndex();
+ QModelIndexList selList = d->popup->selectionModel()->selectedIndexes();
+
+ const int key = ke->key();
+ // In UnFilteredPopup mode, select the current item
+ if ((key == Qt::Key_Up || key == Qt::Key_Down) && selList.isEmpty() && curIndex.isValid()
+ && d->mode == QCompleter::UnfilteredPopupCompletion) {
+ d->setCurrentIndex(curIndex);
+ return true;
+ }
+
+ // Handle popup navigation keys. These are hardcoded because up/down might make the
+ // widget do something else (lineedit cursor moves to home/end on mac, for instance)
+ switch (key) {
+ case Qt::Key_End:
+ case Qt::Key_Home:
+ if (ke->modifiers() & Qt::ControlModifier)
+ return false;
+ break;
+
+ case Qt::Key_Up:
+ if (!curIndex.isValid()) {
+ int rowCount = d->proxy->rowCount();
+ QModelIndex lastIndex = d->proxy->index(rowCount - 1, d->column);
+ d->setCurrentIndex(lastIndex);
+ return true;
+ } else if (curIndex.row() == 0) {
+ if (d->wrap)
+ d->setCurrentIndex(QModelIndex());
+ return true;
+ }
+ return false;
+
+ case Qt::Key_Down:
+ if (!curIndex.isValid()) {
+ QModelIndex firstIndex = d->proxy->index(0, d->column);
+ d->setCurrentIndex(firstIndex);
+ return true;
+ } else if (curIndex.row() == d->proxy->rowCount() - 1) {
+ if (d->wrap)
+ d->setCurrentIndex(QModelIndex());
+ return true;
+ }
+ return false;
+
+ case Qt::Key_PageUp:
+ case Qt::Key_PageDown:
+ return false;
+ }
+
+ // Send the event to the widget. If the widget accepted the event, do nothing
+ // If the widget did not accept the event, provide a default implementation
+ d->eatFocusOut = false;
+ (static_cast<QObject *>(d->widget))->event(ke);
+ d->eatFocusOut = true;
+ if (!d->widget || e->isAccepted() || !d->popup->isVisible()) {
+ // widget lost focus, hide the popup
+ if (d->widget && (!d->widget->hasFocus()
+#ifdef QT_KEYPAD_NAVIGATION
+ || (QApplication::keypadNavigationEnabled() && !d->widget->hasEditFocus())
+#endif
+ ))
+ d->popup->hide();
+ if (e->isAccepted())
+ return true;
+ }
+
+ // default implementation for keys not handled by the widget when popup is open
+ switch (key) {
+#ifdef QT_KEYPAD_NAVIGATION
+ case Qt::Key_Select:
+ if (!QApplication::keypadNavigationEnabled())
+ break;
+#endif
+ case Qt::Key_Return:
+ case Qt::Key_Enter:
+ case Qt::Key_Tab:
+ d->popup->hide();
+ if (curIndex.isValid())
+ d->_q_complete(curIndex);
+ break;
+
+ case Qt::Key_F4:
+ if (ke->modifiers() & Qt::AltModifier)
+ d->popup->hide();
+ break;
+
+ case Qt::Key_Backtab:
+ case Qt::Key_Escape:
+ d->popup->hide();
+ break;
+
+ default:
+ break;
+ }
+
+ return true;
+ }
+
+#ifdef QT_KEYPAD_NAVIGATION
+ case QEvent::KeyRelease: {
+ QKeyEvent *ke = static_cast<QKeyEvent *>(e);
+ if (QApplication::keypadNavigationEnabled() && ke->key() == Qt::Key_Back) {
+ // Send the event to the 'widget'. This is what we did for KeyPress, so we need
+ // to do the same for KeyRelease, in case the widget's KeyPress event set
+ // up something (such as a timer) that is relying on also receiving the
+ // key release. I see this as a bug in Qt, and should really set it up for all
+ // the affected keys. However, it is difficult to tell how this will affect
+ // existing code, and I can't test for every combination!
+ d->eatFocusOut = false;
+ static_cast<QObject *>(d->widget)->event(ke);
+ d->eatFocusOut = true;
+ }
+ break;
+ }
+#endif
+
+ case QEvent::MouseButtonPress: {
+#ifdef QT_KEYPAD_NAVIGATION
+ if (QApplication::keypadNavigationEnabled()) {
+ // if we've clicked in the widget (or its descendant), let it handle the click
+ QWidget *source = qobject_cast<QWidget *>(o);
+ if (source) {
+ QPoint pos = source->mapToGlobal((static_cast<QMouseEvent *>(e))->pos());
+ QWidget *target = QApplication::widgetAt(pos);
+ if (target && (d->widget->isAncestorOf(target) ||
+ target == d->widget)) {
+ d->eatFocusOut = false;
+ static_cast<QObject *>(target)->event(e);
+ d->eatFocusOut = true;
+ return true;
+ }
+ }
+ }
+#endif
+ if (!d->popup->underMouse()) {
+ d->popup->hide();
+ return true;
+ }
+ }
+ return false;
+
+ case QEvent::InputMethod:
+ case QEvent::ShortcutOverride:
+ QApplication::sendEvent(d->widget, e);
+ break;
+
+ default:
+ return false;
+ }
+ return false;
+}
+
+/*!
+ For QCompleter::PopupCompletion and QCompletion::UnfilteredPopupCompletion
+ modes, calling this function displays the popup displaying the current
+ completions. By default, if \a rect is not specified, the popup is displayed
+ on the bottom of the widget(). If \a rect is specified the popup is
+ displayed on the left edge of the rectangle.
+
+ For QCompleter::InlineCompletion mode, the highlighted() signal is fired
+ with the current completion.
+*/
+void QCompleter::complete(const QRect& rect)
+{
+ Q_D(QCompleter);
+ QModelIndex idx = d->proxy->currentIndex(false);
+ d->hiddenBecauseNoMatch = false;
+ if (d->mode == QCompleter::InlineCompletion) {
+ if (idx.isValid())
+ d->_q_complete(idx, true);
+ return;
+ }
+
+ Q_ASSERT(d->widget != 0);
+ if ((d->mode == QCompleter::PopupCompletion && !idx.isValid())
+ || (d->mode == QCompleter::UnfilteredPopupCompletion && d->proxy->rowCount() == 0)) {
+ if (d->popup)
+ d->popup->hide(); // no suggestion, hide
+ d->hiddenBecauseNoMatch = true;
+ return;
+ }
+
+ popup();
+ if (d->mode == QCompleter::UnfilteredPopupCompletion)
+ d->setCurrentIndex(idx, false);
+
+ d->showPopup(rect);
+ d->popupRect = rect;
+}
+
+/*!
+ Sets the current row to the \a row specified. Returns true if successful;
+ otherwise returns false.
+
+ This function may be used along with currentCompletion() to iterate
+ through all the possible completions.
+
+ \sa currentCompletion(), completionCount()
+*/
+bool QCompleter::setCurrentRow(int row)
+{
+ Q_D(QCompleter);
+ return d->proxy->setCurrentRow(row);
+}
+
+/*!
+ Returns the current row.
+
+ \sa setCurrentRow()
+*/
+int QCompleter::currentRow() const
+{
+ Q_D(const QCompleter);
+ return d->proxy->currentRow();
+}
+
+/*!
+ Returns the number of completions for the current prefix. For an unsorted
+ model with a large number of items this can be expensive. Use setCurrentRow()
+ and currentCompletion() to iterate through all the completions.
+*/
+int QCompleter::completionCount() const
+{
+ Q_D(const QCompleter);
+ return d->proxy->completionCount();
+}
+
+/*!
+ \enum QCompleter::ModelSorting
+
+ This enum specifies how the items in the model are sorted.
+
+ \value UnsortedModel The model is unsorted.
+ \value CaseSensitivelySortedModel The model is sorted case sensitively.
+ \value CaseInsensitivelySortedModel The model is sorted case insensitively.
+
+ \sa setModelSorting()
+*/
+
+/*!
+ \property QCompleter::modelSorting
+ \brief the way the model is sorted
+
+ By default, no assumptions are made about the order of the items
+ in the model that provides the completions.
+
+ If the model's data for the completionColumn() and completionRole() is sorted in
+ ascending order, you can set this property to \l CaseSensitivelySortedModel
+ or \l CaseInsensitivelySortedModel. On large models, this can lead to
+ significant performance improvements because the completer object can
+ then use a binary search algorithm instead of linear search algorithm.
+
+ The sort order (i.e ascending or descending order) of the model is determined
+ dynamically by inspecting the contents of the model.
+
+ \bold{Note:} The performance improvements described above cannot take place
+ when the completer's \l caseSensitivity is different to the case sensitivity
+ used by the model's when sorting.
+
+ \sa setCaseSensitivity(), QCompleter::ModelSorting
+*/
+void QCompleter::setModelSorting(QCompleter::ModelSorting sorting)
+{
+ Q_D(QCompleter);
+ if (d->sorting == sorting)
+ return;
+ d->sorting = sorting;
+ d->proxy->createEngine();
+ d->proxy->invalidate();
+}
+
+QCompleter::ModelSorting QCompleter::modelSorting() const
+{
+ Q_D(const QCompleter);
+ return d->sorting;
+}
+
+/*!
+ \property QCompleter::completionColumn
+ \brief the column in the model in which completions are searched for.
+
+ If the popup() is a QListView, it is automatically setup to display
+ this column.
+
+ By default, the match column is 0.
+
+ \sa completionRole, caseSensitivity
+*/
+void QCompleter::setCompletionColumn(int column)
+{
+ Q_D(QCompleter);
+ if (d->column == column)
+ return;
+#ifndef QT_NO_LISTVIEW
+ if (QListView *listView = qobject_cast<QListView *>(d->popup))
+ listView->setModelColumn(column);
+#endif
+ d->column = column;
+ d->proxy->invalidate();
+}
+
+int QCompleter::completionColumn() const
+{
+ Q_D(const QCompleter);
+ return d->column;
+}
+
+/*!
+ \property QCompleter::completionRole
+ \brief the item role to be used to query the contents of items for matching.
+
+ The default role is Qt::EditRole.
+
+ \sa completionColumn, caseSensitivity
+*/
+void QCompleter::setCompletionRole(int role)
+{
+ Q_D(QCompleter);
+ if (d->role == role)
+ return;
+ d->role = role;
+ d->proxy->invalidate();
+}
+
+int QCompleter::completionRole() const
+{
+ Q_D(const QCompleter);
+ return d->role;
+}
+
+/*!
+ \property QCompleter::wrapAround
+ \brief the completions wrap around when navigating through items
+ \since 4.3
+
+ The default is true.
+*/
+void QCompleter::setWrapAround(bool wrap)
+{
+ Q_D(QCompleter);
+ if (d->wrap == wrap)
+ return;
+ d->wrap = wrap;
+}
+
+bool QCompleter::wrapAround() const
+{
+ Q_D(const QCompleter);
+ return d->wrap;
+}
+
+/*!
+ \property QCompleter::maxVisibleItems
+ \brief the maximum allowed size on screen of the completer, measured in items
+ \since 4.6
+
+ By default, this property has a value of 7.
+*/
+int QCompleter::maxVisibleItems() const
+{
+ Q_D(const QCompleter);
+ return d->maxVisibleItems;
+}
+
+void QCompleter::setMaxVisibleItems(int maxItems)
+{
+ Q_D(QCompleter);
+ if (maxItems < 0) {
+ qWarning("QCompleter::setMaxVisibleItems: "
+ "Invalid max visible items (%d) must be >= 0", maxItems);
+ return;
+ }
+ d->maxVisibleItems = maxItems;
+}
+
+/*!
+ \property QCompleter::caseSensitivity
+ \brief the case sensitivity of the matching
+
+ The default is Qt::CaseSensitive.
+
+ \sa completionColumn, completionRole, modelSorting
+*/
+void QCompleter::setCaseSensitivity(Qt::CaseSensitivity cs)
+{
+ Q_D(QCompleter);
+ if (d->cs == cs)
+ return;
+ d->cs = cs;
+ d->proxy->createEngine();
+ d->proxy->invalidate();
+}
+
+Qt::CaseSensitivity QCompleter::caseSensitivity() const
+{
+ Q_D(const QCompleter);
+ return d->cs;
+}
+
+/*!
+ \property QCompleter::completionPrefix
+ \brief the completion prefix used to provide completions.
+
+ The completionModel() is updated to reflect the list of possible
+ matches for \a prefix.
+*/
+void QCompleter::setCompletionPrefix(const QString &prefix)
+{
+ Q_D(QCompleter);
+ d->prefix = prefix;
+ d->proxy->filter(splitPath(prefix));
+}
+
+QString QCompleter::completionPrefix() const
+{
+ Q_D(const QCompleter);
+ return d->prefix;
+}
+
+/*!
+ Returns the model index of the current completion in the completionModel().
+
+ \sa setCurrentRow(), currentCompletion(), model()
+*/
+QModelIndex QCompleter::currentIndex() const
+{
+ Q_D(const QCompleter);
+ return d->proxy->currentIndex(false);
+}
+
+/*!
+ Returns the current completion string. This includes the \l completionPrefix.
+ When used alongside setCurrentRow(), it can be used to iterate through
+ all the matches.
+
+ \sa setCurrentRow(), currentIndex()
+*/
+QString QCompleter::currentCompletion() const
+{
+ Q_D(const QCompleter);
+ return pathFromIndex(d->proxy->currentIndex(true));
+}
+
+/*!
+ Returns the completion model. The completion model is a read-only list model
+ that contains all the possible matches for the current completion prefix.
+ The completion model is auto-updated to reflect the current completions.
+
+ \note The return value of this function is defined to be an QAbstractItemModel
+ purely for generality. This actual kind of model returned is an instance of an
+ QAbstractProxyModel subclass.
+
+ \sa completionPrefix, model()
+*/
+QAbstractItemModel *QCompleter::completionModel() const
+{
+ Q_D(const QCompleter);
+ return d->proxy;
+}
+
+/*!
+ Returns the path for the given \a index. The completer object uses this to
+ obtain the completion text from the underlying model.
+
+ The default implementation returns the \l{Qt::EditRole}{edit role} of the
+ item for list models. It returns the absolute file path if the model is a
+ QFileSystemModel.
+
+ \sa splitPath()
+*/
+
+QString QCompleter::pathFromIndex(const QModelIndex& index) const
+{
+ Q_D(const QCompleter);
+ if (!index.isValid())
+ return QString();
+
+ QAbstractItemModel *sourceModel = d->proxy->sourceModel();
+ if (!sourceModel)
+ return QString();
+ bool isDirModel = false;
+ bool isFsModel = false;
+#ifndef QT_NO_DIRMODEL
+ isDirModel = qobject_cast<QDirModel *>(d->proxy->sourceModel()) != 0;
+#endif
+#ifndef QT_NO_FILESYSTEMMODEL
+ isFsModel = qobject_cast<QFileSystemModel *>(d->proxy->sourceModel()) != 0;
+#endif
+ if (!isDirModel && !isFsModel)
+ return sourceModel->data(index, d->role).toString();
+
+ QModelIndex idx = index;
+ QStringList list;
+ do {
+ QString t;
+ if (isDirModel)
+ t = sourceModel->data(idx, Qt::EditRole).toString();
+#ifndef QT_NO_FILESYSTEMMODEL
+ else
+ t = sourceModel->data(idx, QFileSystemModel::FileNameRole).toString();
+#endif
+ list.prepend(t);
+ QModelIndex parent = idx.parent();
+ idx = parent.sibling(parent.row(), index.column());
+ } while (idx.isValid());
+
+#if (!defined(Q_OS_WIN) || defined(Q_OS_WINCE)) && !defined(Q_OS_SYMBIAN)
+ if (list.count() == 1) // only the separator or some other text
+ return list[0];
+ list[0].clear() ; // the join below will provide the separator
+#endif
+
+ return list.join(QDir::separator());
+}
+
+/*!
+ Splits the given \a path into strings that are used to match at each level
+ in the model().
+
+ The default implementation of splitPath() splits a file system path based on
+ QDir::separator() when the sourceModel() is a QFileSystemModel.
+
+ When used with list models, the first item in the returned list is used for
+ matching.
+
+ \sa pathFromIndex(), {Handling Tree Models}
+*/
+QStringList QCompleter::splitPath(const QString& path) const
+{
+ bool isDirModel = false;
+ bool isFsModel = false;
+#ifndef QT_NO_DIRMODEL
+ Q_D(const QCompleter);
+ isDirModel = qobject_cast<QDirModel *>(d->proxy->sourceModel()) != 0;
+#endif
+#ifndef QT_NO_FILESYSTEMMODEL
+#ifdef QT_NO_DIRMODEL
+ Q_D(const QCompleter);
+#endif
+ isFsModel = qobject_cast<QFileSystemModel *>(d->proxy->sourceModel()) != 0;
+#endif
+
+ if ((!isDirModel && !isFsModel) || path.isEmpty())
+ return QStringList(completionPrefix());
+
+ QString pathCopy = QDir::toNativeSeparators(path);
+ QString sep = QDir::separator();
+#if defined(Q_OS_SYMBIAN)
+ if (pathCopy == QLatin1String("\\"))
+ return QStringList(pathCopy);
+#elif defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+ if (pathCopy == QLatin1String("\\") || pathCopy == QLatin1String("\\\\"))
+ return QStringList(pathCopy);
+ QString doubleSlash(QLatin1String("\\\\"));
+ if (pathCopy.startsWith(doubleSlash))
+ pathCopy = pathCopy.mid(2);
+ else
+ doubleSlash.clear();
+#endif
+
+ QRegExp re(QLatin1Char('[') + QRegExp::escape(sep) + QLatin1Char(']'));
+ QStringList parts = pathCopy.split(re);
+
+#if defined(Q_OS_SYMBIAN)
+ // Do nothing
+#elif defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+ if (!doubleSlash.isEmpty())
+ parts[0].prepend(doubleSlash);
+#else
+ if (pathCopy[0] == sep[0]) // readd the "/" at the beginning as the split removed it
+ parts[0] = QDir::fromNativeSeparators(QString(sep[0]));
+#endif
+
+ return parts;
+}
+
+/*!
+ \fn void QCompleter::activated(const QModelIndex& index)
+
+ This signal is sent when an item in the popup() is activated by the user.
+ (by clicking or pressing return). The item's \a index in the completionModel()
+ is given.
+
+*/
+
+/*!
+ \fn void QCompleter::activated(const QString &text)
+
+ This signal is sent when an item in the popup() is activated by the user (by
+ clicking or pressing return). The item's \a text is given.
+
+*/
+
+/*!
+ \fn void QCompleter::highlighted(const QModelIndex& index)
+
+ This signal is sent when an item in the popup() is highlighted by
+ the user. It is also sent if complete() is called with the completionMode()
+ set to QCompleter::InlineCompletion. The item's \a index in the completionModel()
+ is given.
+*/
+
+/*!
+ \fn void QCompleter::highlighted(const QString &text)
+
+ This signal is sent when an item in the popup() is highlighted by
+ the user. It is also sent if complete() is called with the completionMode()
+ set to QCompleter::InlineCompletion. The item's \a text is given.
+*/
+
+QT_END_NAMESPACE
+
+#include "moc_qcompleter.cpp"
+
+#endif // QT_NO_COMPLETER
diff --git a/src/widgets/util/qcompleter.h b/src/widgets/util/qcompleter.h
new file mode 100644
index 0000000000..c7e1b6e945
--- /dev/null
+++ b/src/widgets/util/qcompleter.h
@@ -0,0 +1,171 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCOMPLETER_H
+#define QCOMPLETER_H
+
+#include <QtCore/qobject.h>
+#include <QtCore/qpoint.h>
+#include <QtCore/qstring.h>
+#include <QtCore/qabstractitemmodel.h>
+#include <QtCore/qrect.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_COMPLETER
+
+class QCompleterPrivate;
+class QAbstractItemView;
+class QAbstractProxyModel;
+class QWidget;
+
+class Q_WIDGETS_EXPORT QCompleter : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QString completionPrefix READ completionPrefix WRITE setCompletionPrefix)
+ Q_PROPERTY(ModelSorting modelSorting READ modelSorting WRITE setModelSorting)
+ Q_PROPERTY(CompletionMode completionMode READ completionMode WRITE setCompletionMode)
+ Q_PROPERTY(int completionColumn READ completionColumn WRITE setCompletionColumn)
+ Q_PROPERTY(int completionRole READ completionRole WRITE setCompletionRole)
+ Q_PROPERTY(int maxVisibleItems READ maxVisibleItems WRITE setMaxVisibleItems)
+ Q_PROPERTY(Qt::CaseSensitivity caseSensitivity READ caseSensitivity WRITE setCaseSensitivity)
+ Q_PROPERTY(bool wrapAround READ wrapAround WRITE setWrapAround)
+
+public:
+ enum CompletionMode {
+ PopupCompletion,
+ UnfilteredPopupCompletion,
+ InlineCompletion
+ };
+
+ enum ModelSorting {
+ UnsortedModel = 0,
+ CaseSensitivelySortedModel,
+ CaseInsensitivelySortedModel
+ };
+
+ QCompleter(QObject *parent = 0);
+ QCompleter(QAbstractItemModel *model, QObject *parent = 0);
+#ifndef QT_NO_STRINGLISTMODEL
+ QCompleter(const QStringList& completions, QObject *parent = 0);
+#endif
+ ~QCompleter();
+
+ void setWidget(QWidget *widget);
+ QWidget *widget() const;
+
+ void setModel(QAbstractItemModel *c);
+ QAbstractItemModel *model() const;
+
+ void setCompletionMode(CompletionMode mode);
+ CompletionMode completionMode() const;
+
+ QAbstractItemView *popup() const;
+ void setPopup(QAbstractItemView *popup);
+
+ void setCaseSensitivity(Qt::CaseSensitivity caseSensitivity);
+ Qt::CaseSensitivity caseSensitivity() const;
+
+ void setModelSorting(ModelSorting sorting);
+ ModelSorting modelSorting() const;
+
+ void setCompletionColumn(int column);
+ int completionColumn() const;
+
+ void setCompletionRole(int role);
+ int completionRole() const;
+
+ bool wrapAround() const;
+
+ int maxVisibleItems() const;
+ void setMaxVisibleItems(int maxItems);
+
+ int completionCount() const;
+ bool setCurrentRow(int row);
+ int currentRow() const;
+
+ QModelIndex currentIndex() const;
+ QString currentCompletion() const;
+
+ QAbstractItemModel *completionModel() const;
+
+ QString completionPrefix() const;
+
+public Q_SLOTS:
+ void setCompletionPrefix(const QString &prefix);
+ void complete(const QRect& rect = QRect());
+ void setWrapAround(bool wrap);
+
+public:
+ virtual QString pathFromIndex(const QModelIndex &index) const;
+ virtual QStringList splitPath(const QString &path) const;
+
+protected:
+ bool eventFilter(QObject *o, QEvent *e);
+ bool event(QEvent *);
+
+Q_SIGNALS:
+ void activated(const QString &text);
+ void activated(const QModelIndex &index);
+ void highlighted(const QString &text);
+ void highlighted(const QModelIndex &index);
+
+private:
+ Q_DISABLE_COPY(QCompleter)
+ Q_DECLARE_PRIVATE(QCompleter)
+
+ Q_PRIVATE_SLOT(d_func(), void _q_complete(QModelIndex))
+ Q_PRIVATE_SLOT(d_func(), void _q_completionSelected(const QItemSelection&))
+ Q_PRIVATE_SLOT(d_func(), void _q_autoResizePopup())
+ Q_PRIVATE_SLOT(d_func(), void _q_fileSystemModelDirectoryLoaded(const QString&))
+};
+
+#endif // QT_NO_COMPLETER
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QCOMPLETER_H
diff --git a/src/widgets/util/qcompleter_p.h b/src/widgets/util/qcompleter_p.h
new file mode 100644
index 0000000000..639c875568
--- /dev/null
+++ b/src/widgets/util/qcompleter_p.h
@@ -0,0 +1,264 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCOMPLETER_P_H
+#define QCOMPLETER_P_H
+
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "private/qobject_p.h"
+
+#ifndef QT_NO_COMPLETER
+
+#include "QtWidgets/qtreeview.h"
+#include "QtWidgets/qabstractproxymodel.h"
+#include "qcompleter.h"
+#include "QtWidgets/qitemdelegate.h"
+#include "QtGui/qpainter.h"
+#include "private/qabstractproxymodel_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QCompletionModel;
+
+class QCompleterPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QCompleter)
+
+public:
+ QCompleterPrivate();
+ ~QCompleterPrivate() { delete popup; }
+ void init(QAbstractItemModel *model = 0);
+
+ QPointer<QWidget> widget;
+ QCompletionModel *proxy;
+ QAbstractItemView *popup;
+ QCompleter::CompletionMode mode;
+
+ QString prefix;
+ Qt::CaseSensitivity cs;
+ int role;
+ int column;
+ int maxVisibleItems;
+ QCompleter::ModelSorting sorting;
+ bool wrap;
+
+ bool eatFocusOut;
+ QRect popupRect;
+ bool hiddenBecauseNoMatch;
+
+ void showPopup(const QRect&);
+ void _q_complete(QModelIndex, bool = false);
+ void _q_completionSelected(const QItemSelection&);
+ void _q_autoResizePopup();
+ void _q_fileSystemModelDirectoryLoaded(const QString &path);
+ void setCurrentIndex(QModelIndex, bool = true);
+};
+
+class QIndexMapper
+{
+public:
+ QIndexMapper() : v(false), f(0), t(-1) { }
+ QIndexMapper(int f, int t) : v(false), f(f), t(t) { }
+ QIndexMapper(QVector<int> vec) : v(true), vector(vec), f(-1), t(-1) { }
+
+ inline int count() const { return v ? vector.count() : t - f + 1; }
+ inline int operator[] (int index) const { return v ? vector[index] : f + index; }
+ inline int indexOf(int x) const { return v ? vector.indexOf(x) : ((t < f) ? -1 : x - f); }
+ inline bool isValid() const { return !isEmpty(); }
+ inline bool isEmpty() const { return v ? vector.isEmpty() : (t < f); }
+ inline void append(int x) { Q_ASSERT(v); vector.append(x); }
+ inline int first() const { return v ? vector.first() : f; }
+ inline int last() const { return v ? vector.last() : t; }
+ inline int from() const { Q_ASSERT(!v); return f; }
+ inline int to() const { Q_ASSERT(!v); return t; }
+ inline int cost() const { return vector.count()+2; }
+
+private:
+ bool v;
+ QVector<int> vector;
+ int f, t;
+};
+
+struct QMatchData {
+ QMatchData() : exactMatchIndex(-1) { }
+ QMatchData(const QIndexMapper& indices, int em, bool p) :
+ indices(indices), exactMatchIndex(em), partial(p) { }
+ QIndexMapper indices;
+ inline bool isValid() const { return indices.isValid(); }
+ int exactMatchIndex;
+ bool partial;
+};
+
+class QCompletionEngine
+{
+public:
+ typedef QMap<QString, QMatchData> CacheItem;
+ typedef QMap<QModelIndex, CacheItem> Cache;
+
+ QCompletionEngine(QCompleterPrivate *c) : c(c), curRow(-1), cost(0) { }
+ virtual ~QCompletionEngine() { }
+
+ void filter(const QStringList &parts);
+
+ QMatchData filterHistory();
+ bool matchHint(QString, const QModelIndex&, QMatchData*);
+
+ void saveInCache(QString, const QModelIndex&, const QMatchData&);
+ bool lookupCache(QString part, const QModelIndex& parent, QMatchData *m);
+
+ virtual void filterOnDemand(int) { }
+ virtual QMatchData filter(const QString&, const QModelIndex&, int) = 0;
+
+ int matchCount() const { return curMatch.indices.count() + historyMatch.indices.count(); }
+
+ QMatchData curMatch, historyMatch;
+ QCompleterPrivate *c;
+ QStringList curParts;
+ QModelIndex curParent;
+ int curRow;
+
+ Cache cache;
+ int cost;
+};
+
+class QSortedModelEngine : public QCompletionEngine
+{
+public:
+ QSortedModelEngine(QCompleterPrivate *c) : QCompletionEngine(c) { }
+ QMatchData filter(const QString&, const QModelIndex&, int);
+ QIndexMapper indexHint(QString, const QModelIndex&, Qt::SortOrder);
+ Qt::SortOrder sortOrder(const QModelIndex&) const;
+};
+
+class QUnsortedModelEngine : public QCompletionEngine
+{
+public:
+ QUnsortedModelEngine(QCompleterPrivate *c) : QCompletionEngine(c) { }
+
+ void filterOnDemand(int);
+ QMatchData filter(const QString&, const QModelIndex&, int);
+private:
+ int buildIndices(const QString& str, const QModelIndex& parent, int n,
+ const QIndexMapper& iv, QMatchData* m);
+};
+
+class QCompleterItemDelegate : public QItemDelegate
+{
+public:
+ QCompleterItemDelegate(QAbstractItemView *view)
+ : QItemDelegate(view), view(view) { }
+ void paint(QPainter *p, const QStyleOptionViewItem& opt, const QModelIndex& idx) const {
+ QStyleOptionViewItem optCopy = opt;
+ optCopy.showDecorationSelected = true;
+ if (view->currentIndex() == idx)
+ optCopy.state |= QStyle::State_HasFocus;
+ QItemDelegate::paint(p, optCopy, idx);
+ }
+
+private:
+ QAbstractItemView *view;
+};
+
+class QCompletionModelPrivate;
+
+class QCompletionModel : public QAbstractProxyModel
+{
+ Q_OBJECT
+
+public:
+ QCompletionModel(QCompleterPrivate *c, QObject *parent);
+
+ void createEngine();
+ void setFiltered(bool);
+ void filter(const QStringList& parts);
+ int completionCount() const;
+ int currentRow() const { return engine->curRow; }
+ bool setCurrentRow(int row);
+ QModelIndex currentIndex(bool) const;
+ void resetModel();
+
+ QModelIndex index(int row, int column, const QModelIndex & = QModelIndex()) const;
+ int rowCount(const QModelIndex &index = QModelIndex()) const;
+ int columnCount(const QModelIndex &index = QModelIndex()) const;
+ bool hasChildren(const QModelIndex &parent = QModelIndex()) const;
+ QModelIndex parent(const QModelIndex & = QModelIndex()) const { return QModelIndex(); }
+ QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
+
+ void setSourceModel(QAbstractItemModel *sourceModel);
+ QModelIndex mapToSource(const QModelIndex& proxyIndex) const;
+ QModelIndex mapFromSource(const QModelIndex& sourceIndex) const;
+
+ QCompleterPrivate *c;
+ QScopedPointer<QCompletionEngine> engine;
+ bool showAll;
+
+ Q_DECLARE_PRIVATE(QCompletionModel)
+
+signals:
+ void rowsAdded();
+
+public Q_SLOTS:
+ void invalidate();
+ void rowsInserted();
+ void modelDestroyed();
+};
+
+class QCompletionModelPrivate : public QAbstractProxyModelPrivate
+{
+ Q_DECLARE_PUBLIC(QCompletionModel)
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_COMPLETER
+
+#endif // QCOMPLETER_P_H
diff --git a/src/widgets/util/qflickgesture.cpp b/src/widgets/util/qflickgesture.cpp
new file mode 100644
index 0000000000..c92fb94be7
--- /dev/null
+++ b/src/widgets/util/qflickgesture.cpp
@@ -0,0 +1,717 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qgesture.h"
+#include "qapplication.h"
+#include "qevent.h"
+#include "qwidget.h"
+#include "qgraphicsitem.h"
+#include "qgraphicsscene.h"
+#include "qgraphicssceneevent.h"
+#include "qgraphicsview.h"
+#include "qscroller.h"
+#include "private/qevent_p.h"
+#include "private/qflickgesture_p.h"
+#include "qdebug.h"
+
+#ifndef QT_NO_GESTURES
+
+QT_BEGIN_NAMESPACE
+
+//#define QFLICKGESTURE_DEBUG
+
+#ifdef QFLICKGESTURE_DEBUG
+# define qFGDebug qDebug
+#else
+# define qFGDebug while (false) qDebug
+#endif
+
+extern bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event);
+
+static QMouseEvent *copyMouseEvent(QEvent *e)
+{
+ switch (e->type()) {
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseMove: {
+ QMouseEvent *me = static_cast<QMouseEvent *>(e);
+ return new QMouseEvent(me->type(), QPoint(0, 0), me->windowPos(), me->screenPos(), me->button(), me->buttons(), me->modifiers());
+ }
+#ifndef QT_NO_GRAPHICSVIEW
+ case QEvent::GraphicsSceneMousePress:
+ case QEvent::GraphicsSceneMouseRelease:
+ case QEvent::GraphicsSceneMouseMove: {
+ QGraphicsSceneMouseEvent *me = static_cast<QGraphicsSceneMouseEvent *>(e);
+#if 1
+ QEvent::Type met = me->type() == QEvent::GraphicsSceneMousePress ? QEvent::MouseButtonPress :
+ (me->type() == QEvent::GraphicsSceneMouseRelease ? QEvent::MouseButtonRelease : QEvent::MouseMove);
+ return new QMouseEvent(met, QPoint(0, 0), QPoint(0, 0), me->screenPos(), me->button(), me->buttons(), me->modifiers());
+#else
+ QGraphicsSceneMouseEvent *copy = new QGraphicsSceneMouseEvent(me->type());
+ copy->setPos(me->pos());
+ copy->setScenePos(me->scenePos());
+ copy->setScreenPos(me->screenPos());
+ for (int i = 0x1; i <= 0x10; i <<= 1) {
+ Qt::MouseButton button = Qt::MouseButton(i);
+ copy->setButtonDownPos(button, me->buttonDownPos(button));
+ copy->setButtonDownScenePos(button, me->buttonDownScenePos(button));
+ copy->setButtonDownScreenPos(button, me->buttonDownScreenPos(button));
+ }
+ copy->setLastPos(me->lastPos());
+ copy->setLastScenePos(me->lastScenePos());
+ copy->setLastScreenPos(me->lastScreenPos());
+ copy->setButtons(me->buttons());
+ copy->setButton(me->button());
+ copy->setModifiers(me->modifiers());
+ return copy;
+#endif
+ }
+#endif // QT_NO_GRAPHICSVIEW
+ default:
+ return 0;
+ }
+}
+
+class PressDelayHandler : public QObject
+{
+private:
+ PressDelayHandler(QObject *parent = 0)
+ : QObject(parent)
+ , pressDelayTimer(0)
+ , sendingEvent(false)
+ , mouseButton(Qt::NoButton)
+ , mouseTarget(0)
+ { }
+
+ static PressDelayHandler *inst;
+
+public:
+ enum {
+ UngrabMouseBefore = 1,
+ RegrabMouseAfterwards = 2
+ };
+
+ static PressDelayHandler *instance()
+ {
+ static PressDelayHandler *inst = 0;
+ if (!inst)
+ inst = new PressDelayHandler(QCoreApplication::instance());
+ return inst;
+ }
+
+ bool shouldEventBeIgnored(QEvent *) const
+ {
+ return sendingEvent;
+ }
+
+ bool isDelaying() const
+ {
+ return !pressDelayEvent.isNull();
+ }
+
+ void pressed(QEvent *e, int delay)
+ {
+ if (!pressDelayEvent) {
+ pressDelayEvent.reset(copyMouseEvent(e));
+ pressDelayTimer = startTimer(delay);
+ mouseTarget = QApplication::widgetAt(pressDelayEvent->globalPos());
+ mouseButton = pressDelayEvent->button();
+ qFGDebug() << "QFG: consuming/delaying mouse press";
+ } else {
+ qFGDebug() << "QFG: NOT consuming/delaying mouse press";
+ }
+ e->setAccepted(true);
+ }
+
+ bool released(QEvent *e, bool scrollerWasActive, bool scrollerIsActive)
+ {
+ // consume this event if the scroller was or is active
+ bool result = scrollerWasActive || scrollerIsActive;
+
+ // stop the timer
+ if (pressDelayTimer) {
+ killTimer(pressDelayTimer);
+ pressDelayTimer = 0;
+ }
+ // we still haven't even sent the press, so do it now
+ if (pressDelayEvent && mouseTarget && !scrollerIsActive) {
+ QScopedPointer<QMouseEvent> releaseEvent(copyMouseEvent(e));
+
+ qFGDebug() << "QFG: re-sending mouse press (due to release) for " << mouseTarget;
+ sendMouseEvent(pressDelayEvent.data(), UngrabMouseBefore);
+
+ qFGDebug() << "QFG: faking mouse release (due to release) for " << mouseTarget;
+ sendMouseEvent(releaseEvent.data());
+
+ result = true; // consume this event
+ } else if (mouseTarget && scrollerIsActive) {
+ // we grabbed the mouse expicitly when the scroller became active, so undo that now
+ sendMouseEvent(0, UngrabMouseBefore);
+ }
+ pressDelayEvent.reset(0);
+ mouseTarget = 0;
+ return result;
+ }
+
+ void scrollerWasIntercepted()
+ {
+ qFGDebug() << "QFG: deleting delayed mouse press, since scroller was only intercepted";
+ if (pressDelayEvent) {
+ // we still haven't even sent the press, so just throw it away now
+ if (pressDelayTimer) {
+ killTimer(pressDelayTimer);
+ pressDelayTimer = 0;
+ }
+ pressDelayEvent.reset(0);
+ }
+ mouseTarget = 0;
+ }
+
+ void scrollerBecameActive()
+ {
+ if (pressDelayEvent) {
+ // we still haven't even sent the press, so just throw it away now
+ qFGDebug() << "QFG: deleting delayed mouse press, since scroller is active now";
+ if (pressDelayTimer) {
+ killTimer(pressDelayTimer);
+ pressDelayTimer = 0;
+ }
+ pressDelayEvent.reset(0);
+ mouseTarget = 0;
+ } else if (mouseTarget) {
+ // we did send a press, so we need to fake a release now
+
+ // release all pressed mouse buttons
+ /* Qt::MouseButtons mouseButtons = QApplication::mouseButtons();
+ for (int i = 0; i < 32; ++i) {
+ if (mouseButtons & (1 << i)) {
+ Qt::MouseButton b = static_cast<Qt::MouseButton>(1 << i);
+ mouseButtons &= ~b;
+ QPoint farFarAway(-QWIDGETSIZE_MAX, -QWIDGETSIZE_MAX);
+
+ qFGDebug() << "QFG: sending a fake mouse release at far-far-away to " << mouseTarget;
+ QMouseEvent re(QEvent::MouseButtonRelease, QPoint(), farFarAway,
+ b, mouseButtons, QApplication::keyboardModifiers());
+ sendMouseEvent(&re);
+ }
+ }*/
+
+ QPoint farFarAway(-QWIDGETSIZE_MAX, -QWIDGETSIZE_MAX);
+
+ qFGDebug() << "QFG: sending a fake mouse release at far-far-away to " << mouseTarget;
+ QMouseEvent re(QEvent::MouseButtonRelease, QPoint(), farFarAway, farFarAway,
+ mouseButton, QApplication::mouseButtons() & ~mouseButton,
+ QApplication::keyboardModifiers());
+ sendMouseEvent(&re, RegrabMouseAfterwards);
+ // don't clear the mouseTarget just yet, since we need to explicitly ungrab the mouse on release!
+ }
+ }
+
+protected:
+ void timerEvent(QTimerEvent *e)
+ {
+ if (e->timerId() == pressDelayTimer) {
+ if (pressDelayEvent && mouseTarget) {
+ qFGDebug() << "QFG: timer event: re-sending mouse press to " << mouseTarget;
+ sendMouseEvent(pressDelayEvent.data(), UngrabMouseBefore);
+ }
+ pressDelayEvent.reset(0);
+
+ if (pressDelayTimer) {
+ killTimer(pressDelayTimer);
+ pressDelayTimer = 0;
+ }
+ }
+ }
+
+ void sendMouseEvent(QMouseEvent *me, int flags = 0)
+ {
+ if (mouseTarget) {
+ sendingEvent = true;
+
+#ifndef QT_NO_GRAPHICSVIEW
+ QGraphicsItem *grabber = 0;
+ if (mouseTarget->parentWidget()) {
+ if (QGraphicsView *gv = qobject_cast<QGraphicsView *>(mouseTarget->parentWidget())) {
+ if (gv->scene())
+ grabber = gv->scene()->mouseGrabberItem();
+ }
+ }
+
+ if (grabber && (flags & UngrabMouseBefore)) {
+ // GraphicsView Mouse Handling Workaround #1:
+ // we need to ungrab the mouse before re-sending the press,
+ // since the scene had already set the mouse grabber to the
+ // original (and consumed) event's receiver
+ qFGDebug() << "QFG: ungrabbing" << grabber;
+ grabber->ungrabMouse();
+ }
+#endif // QT_NO_GRAPHICSVIEW
+
+ if (me) {
+ QMouseEvent copy(me->type(), mouseTarget->mapFromGlobal(me->globalPos()),
+ mouseTarget->topLevelWidget()->mapFromGlobal(me->globalPos()), me->screenPos(),
+ me->button(), me->buttons(), me->modifiers());
+ qt_sendSpontaneousEvent(mouseTarget, &copy);
+ }
+
+#ifndef QT_NO_GRAPHICSVIEW
+ if (grabber && (flags & RegrabMouseAfterwards)) {
+ // GraphicsView Mouse Handling Workaround #2:
+ // we need to re-grab the mouse after sending a faked mouse
+ // release, since we still need the mouse moves for the gesture
+ // (the scene will clear the item's mouse grabber status on
+ // release).
+ qFGDebug() << "QFG: re-grabbing" << grabber;
+ grabber->grabMouse();
+ }
+#endif
+ sendingEvent = false;
+ }
+ }
+
+
+private:
+ int pressDelayTimer;
+ QScopedPointer<QMouseEvent> pressDelayEvent;
+ bool sendingEvent;
+ Qt::MouseButton mouseButton;
+ QPointer<QWidget> mouseTarget;
+};
+
+
+/*!
+ \internal
+ \class QFlickGesture
+ \since 4.8
+ \brief The QFlickGesture class describes a flicking gesture made by the user.
+ \ingroup gestures
+ The QFlickGesture is more complex than the QPanGesture that uses QScroller and QScrollerProperties
+ to decide if it is triggered.
+ This gesture is reacting on touch event as compared to the QMouseFlickGesture.
+
+ \sa {Gestures Programming}, QScroller, QScrollerProperties, QMouseFlickGesture
+*/
+
+/*!
+ \internal
+*/
+QFlickGesture::QFlickGesture(QObject *receiver, Qt::MouseButton button, QObject *parent)
+ : QGesture(*new QFlickGesturePrivate, parent)
+{
+ d_func()->q_ptr = this;
+ d_func()->receiver = receiver;
+ d_func()->receiverScroller = (receiver && QScroller::hasScroller(receiver)) ? QScroller::scroller(receiver) : 0;
+ d_func()->button = button;
+}
+
+QFlickGesture::~QFlickGesture()
+{ }
+
+QFlickGesturePrivate::QFlickGesturePrivate()
+ : receiverScroller(0), button(Qt::NoButton), macIgnoreWheel(false)
+{ }
+
+
+//
+// QFlickGestureRecognizer
+//
+
+
+QFlickGestureRecognizer::QFlickGestureRecognizer(Qt::MouseButton button)
+{
+ this->button = button;
+}
+
+/*! \reimp
+ */
+QGesture *QFlickGestureRecognizer::create(QObject *target)
+{
+#ifndef QT_NO_GRAPHICSVIEW
+ QGraphicsObject *go = qobject_cast<QGraphicsObject*>(target);
+ if (go && button == Qt::NoButton) {
+ go->setAcceptTouchEvents(true);
+ }
+#endif
+ return new QFlickGesture(target, button);
+}
+
+/*! \internal
+ The recognize function detects a touch event suitable to start the attached QScroller.
+ The QFlickGesture will be triggered as soon as the scroller is no longer in the state
+ QScroller::Inactive or QScroller::Pressed. It will be finished or canceled
+ at the next QEvent::TouchEnd.
+ Note that the QScroller might continue scrolling (kinetically) at this point.
+ */
+QGestureRecognizer::Result QFlickGestureRecognizer::recognize(QGesture *state,
+ QObject *watched,
+ QEvent *event)
+{
+ Q_UNUSED(watched);
+
+ static QElapsedTimer monotonicTimer;
+ if (!monotonicTimer.isValid())
+ monotonicTimer.start();
+
+ QFlickGesture *q = static_cast<QFlickGesture *>(state);
+ QFlickGesturePrivate *d = q->d_func();
+
+ QScroller *scroller = d->receiverScroller;
+ if (!scroller)
+ return Ignore; // nothing to do without a scroller?
+
+ QWidget *receiverWidget = qobject_cast<QWidget *>(d->receiver);
+#ifndef QT_NO_GRAPHICSVIEW
+ QGraphicsObject *receiverGraphicsObject = qobject_cast<QGraphicsObject *>(d->receiver);
+#endif
+
+ // this is only set for events that we inject into the event loop via sendEvent()
+ if (PressDelayHandler::instance()->shouldEventBeIgnored(event)) {
+ //qFGDebug() << state << "QFG: ignored event: " << event->type();
+ return Ignore;
+ }
+
+ const QMouseEvent *me = 0;
+#ifndef QT_NO_GRAPHICSVIEW
+ const QGraphicsSceneMouseEvent *gsme = 0;
+#endif
+ const QTouchEvent *te = 0;
+ QPoint globalPos;
+
+ // qFGDebug() << "FlickGesture "<<state<<"watched:"<<watched<<"receiver"<<d->receiver<<"event"<<event->type()<<"button"<<button;
+
+ switch (event->type()) {
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseMove:
+ if (!receiverWidget)
+ return Ignore;
+ if (button != Qt::NoButton) {
+ me = static_cast<const QMouseEvent *>(event);
+ globalPos = me->globalPos();
+ }
+ break;
+#ifndef QT_NO_GRAPHICSVIEW
+ case QEvent::GraphicsSceneMousePress:
+ case QEvent::GraphicsSceneMouseRelease:
+ case QEvent::GraphicsSceneMouseMove:
+ if (!receiverGraphicsObject)
+ return Ignore;
+ if (button != Qt::NoButton) {
+ gsme = static_cast<const QGraphicsSceneMouseEvent *>(event);
+ globalPos = gsme->screenPos();
+ }
+ break;
+#endif
+ case QEvent::TouchBegin:
+ case QEvent::TouchEnd:
+ case QEvent::TouchUpdate:
+ if (button == Qt::NoButton) {
+ te = static_cast<const QTouchEvent *>(event);
+ if (!te->touchPoints().isEmpty())
+ globalPos = te->touchPoints().at(0).screenPos().toPoint();
+ }
+ break;
+
+#if defined(Q_WS_MAC)
+ // the only way to distinguish between real mouse wheels and wheel
+ // events generated by the native 2 finger swipe gesture is to listen
+ // for these events (according to Apple's Cocoa Event-Handling Guide)
+
+ case QEvent::NativeGesture: {
+ QNativeGestureEvent *nge = static_cast<QNativeGestureEvent *>(event);
+ if (nge->gestureType == QNativeGestureEvent::GestureBegin)
+ d->macIgnoreWheel = true;
+ else if (nge->gestureType == QNativeGestureEvent::GestureEnd)
+ d->macIgnoreWheel = false;
+ break;
+ }
+#endif
+
+ // consume all wheel events if the scroller is active
+ case QEvent::Wheel:
+ if (d->macIgnoreWheel || (scroller->state() != QScroller::Inactive))
+ return Ignore | ConsumeEventHint;
+ break;
+
+ // consume all dbl click events if the scroller is active
+ case QEvent::MouseButtonDblClick:
+ if (scroller->state() != QScroller::Inactive)
+ return Ignore | ConsumeEventHint;
+ break;
+
+ default:
+ break;
+ }
+
+ if (!me
+#ifndef QT_NO_GRAPHICSVIEW
+ && !gsme
+#endif
+ && !te) // Neither mouse nor touch
+ return Ignore;
+
+ // get the current pointer position in local coordinates.
+ QPointF point;
+ QScroller::Input inputType = (QScroller::Input) 0;
+
+ switch (event->type()) {
+ case QEvent::MouseButtonPress:
+ if (me && me->button() == button && me->buttons() == button) {
+ point = me->globalPos();
+ inputType = QScroller::InputPress;
+ } else if (me) {
+ scroller->stop();
+ return CancelGesture;
+ }
+ break;
+ case QEvent::MouseButtonRelease:
+ if (me && me->button() == button) {
+ point = me->globalPos();
+ inputType = QScroller::InputRelease;
+ }
+ break;
+ case QEvent::MouseMove:
+#ifdef Q_OS_SYMBIAN
+ // Qt on Symbian tracks the button state internally, while Qt on Win/Mac/Unix
+ // relies on the windowing system to report the current buttons state.
+ if (me && (me->buttons() == button || !me->buttons())) {
+#else
+ if (me && me->buttons() == button) {
+#endif
+ point = me->globalPos();
+ inputType = QScroller::InputMove;
+ }
+ break;
+
+#ifndef QT_NO_GRAPHICSVIEW
+ case QEvent::GraphicsSceneMousePress:
+ if (gsme && gsme->button() == button && gsme->buttons() == button) {
+ point = gsme->scenePos();
+ inputType = QScroller::InputPress;
+ } else if (gsme) {
+ scroller->stop();
+ return CancelGesture;
+ }
+ break;
+ case QEvent::GraphicsSceneMouseRelease:
+ if (gsme && gsme->button() == button) {
+ point = gsme->scenePos();
+ inputType = QScroller::InputRelease;
+ }
+ break;
+ case QEvent::GraphicsSceneMouseMove:
+#ifdef Q_OS_SYMBIAN
+ // Qt on Symbian tracks the button state internally, while Qt on Win/Mac/Unix
+ // relies on the windowing system to report the current buttons state.
+ if (gsme && (gsme->buttons() == button || !me->buttons())) {
+#else
+ if (gsme && gsme->buttons() == button) {
+#endif
+ point = gsme->scenePos();
+ inputType = QScroller::InputMove;
+ }
+ break;
+#endif
+
+ case QEvent::TouchBegin:
+ inputType = QScroller::InputPress;
+ // fall through
+ case QEvent::TouchEnd:
+ if (!inputType)
+ inputType = QScroller::InputRelease;
+ // fallthrough
+ case QEvent::TouchUpdate:
+ if (!inputType)
+ inputType = QScroller::InputMove;
+
+ if (te->deviceType() == QTouchEvent::TouchPad) {
+ if (te->touchPoints().count() != 2) // 2 fingers on pad
+ return Ignore;
+
+ point = te->touchPoints().at(0).startScenePos() +
+ ((te->touchPoints().at(0).scenePos() - te->touchPoints().at(0).startScenePos()) +
+ (te->touchPoints().at(1).scenePos() - te->touchPoints().at(1).startScenePos())) / 2;
+ } else { // TouchScreen
+ if (te->touchPoints().count() != 1) // 1 finger on screen
+ return Ignore;
+
+ point = te->touchPoints().at(0).scenePos();
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ // Check for an active scroller at globalPos
+ if (inputType == QScroller::InputPress) {
+ foreach (QScroller *as, QScroller::activeScrollers()) {
+ if (as != scroller) {
+ QRegion scrollerRegion;
+
+ if (QWidget *w = qobject_cast<QWidget *>(as->target())) {
+ scrollerRegion = QRect(w->mapToGlobal(QPoint(0, 0)), w->size());
+#ifndef QT_NO_GRAPHICSVIEW
+ } else if (QGraphicsObject *go = qobject_cast<QGraphicsObject *>(as->target())) {
+ if (go->scene() && !go->scene()->views().isEmpty()) {
+ foreach (QGraphicsView *gv, go->scene()->views())
+ scrollerRegion |= gv->mapFromScene(go->mapToScene(go->boundingRect()))
+ .translated(gv->mapToGlobal(QPoint(0, 0)));
+ }
+#endif
+ }
+ // active scrollers always have priority
+ if (scrollerRegion.contains(globalPos))
+ return Ignore;
+ }
+ }
+ }
+
+ bool scrollerWasDragging = (scroller->state() == QScroller::Dragging);
+ bool scrollerWasScrolling = (scroller->state() == QScroller::Scrolling);
+
+ if (inputType) {
+ if (QWidget *w = qobject_cast<QWidget *>(d->receiver))
+ point = w->mapFromGlobal(point.toPoint());
+#ifndef QT_NO_GRAPHICSVIEW
+ else if (QGraphicsObject *go = qobject_cast<QGraphicsObject *>(d->receiver))
+ point = go->mapFromScene(point);
+#endif
+
+ // inform the scroller about the new event
+ scroller->handleInput(inputType, point, monotonicTimer.elapsed());
+ }
+
+ // depending on the scroller state return the gesture state
+ Result result(0);
+ bool scrollerIsActive = (scroller->state() == QScroller::Dragging ||
+ scroller->state() == QScroller::Scrolling);
+
+ // Consume all mouse events while dragging or scrolling to avoid nasty
+ // side effects with Qt's standard widgets.
+ if ((me
+#ifndef QT_NO_GRAPHICSVIEW
+ || gsme
+#endif
+ ) && scrollerIsActive)
+ result |= ConsumeEventHint;
+
+ // The only problem with this approach is that we consume the
+ // MouseRelease when we start the scrolling with a flick gesture, so we
+ // have to fake a MouseRelease "somewhere" to not mess with the internal
+ // states of Qt's widgets (a QPushButton would stay in 'pressed' state
+ // forever, if it doesn't receive a MouseRelease).
+ if (me
+#ifndef QT_NO_GRAPHICSVIEW
+ || gsme
+#endif
+ ) {
+ if (!scrollerWasDragging && !scrollerWasScrolling && scrollerIsActive)
+ PressDelayHandler::instance()->scrollerBecameActive();
+ else if (scrollerWasScrolling && (scroller->state() == QScroller::Dragging || scroller->state() == QScroller::Inactive))
+ PressDelayHandler::instance()->scrollerWasIntercepted();
+ }
+
+ if (!inputType) {
+ result |= Ignore;
+ } else {
+ switch (event->type()) {
+ case QEvent::MouseButtonPress:
+#ifndef QT_NO_GRAPHICSVIEW
+ case QEvent::GraphicsSceneMousePress:
+#endif
+ if (scroller->state() == QScroller::Pressed) {
+ int pressDelay = int(1000 * scroller->scrollerProperties().scrollMetric(QScrollerProperties::MousePressEventDelay).toReal());
+ if (pressDelay > 0) {
+ result |= ConsumeEventHint;
+
+ PressDelayHandler::instance()->pressed(event, pressDelay);
+ event->accept();
+ }
+ }
+ // fall through
+ case QEvent::TouchBegin:
+ q->setHotSpot(globalPos);
+ result |= scrollerIsActive ? TriggerGesture : MayBeGesture;
+ break;
+
+ case QEvent::MouseMove:
+#ifndef QT_NO_GRAPHICSVIEW
+ case QEvent::GraphicsSceneMouseMove:
+#endif
+ if (PressDelayHandler::instance()->isDelaying())
+ result |= ConsumeEventHint;
+ // fall through
+ case QEvent::TouchUpdate:
+ result |= scrollerIsActive ? TriggerGesture : Ignore;
+ break;
+
+#ifndef QT_NO_GRAPHICSVIEW
+ case QEvent::GraphicsSceneMouseRelease:
+#endif
+ case QEvent::MouseButtonRelease:
+ if (PressDelayHandler::instance()->released(event, scrollerWasDragging || scrollerWasScrolling, scrollerIsActive))
+ result |= ConsumeEventHint;
+ // fall through
+ case QEvent::TouchEnd:
+ result |= scrollerIsActive ? FinishGesture : CancelGesture;
+ break;
+
+ default:
+ result |= Ignore;
+ break;
+ }
+ }
+ return result;
+}
+
+
+/*! \reimp
+ */
+void QFlickGestureRecognizer::reset(QGesture *state)
+{
+ QGestureRecognizer::reset(state);
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_GESTURES
diff --git a/src/widgets/util/qflickgesture_p.h b/src/widgets/util/qflickgesture_p.h
new file mode 100644
index 0000000000..23c8b6e788
--- /dev/null
+++ b/src/widgets/util/qflickgesture_p.h
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QFLICKGESTURE_P_H
+#define QFLICKGESTURE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qevent.h"
+#include "qgesturerecognizer.h"
+#include "private/qgesture_p.h"
+#include "qscroller.h"
+#include "qscopedpointer.h"
+
+#ifndef QT_NO_GESTURES
+
+QT_BEGIN_NAMESPACE
+
+class QFlickGesturePrivate;
+class QGraphicsItem;
+
+class Q_WIDGETS_EXPORT QFlickGesture : public QGesture
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QFlickGesture)
+
+public:
+ QFlickGesture(QObject *receiver, Qt::MouseButton button, QObject *parent = 0);
+ ~QFlickGesture();
+
+ friend class QFlickGestureRecognizer;
+};
+
+class PressDelayHandler;
+
+class QFlickGesturePrivate : public QGesturePrivate
+{
+ Q_DECLARE_PUBLIC(QFlickGesture)
+public:
+ QFlickGesturePrivate();
+
+ QPointer<QObject> receiver;
+ QScroller *receiverScroller;
+ Qt::MouseButton button; // NoButton == Touch
+ bool macIgnoreWheel;
+ static PressDelayHandler *pressDelayHandler;
+};
+
+class QFlickGestureRecognizer : public QGestureRecognizer
+{
+public:
+ QFlickGestureRecognizer(Qt::MouseButton button);
+
+ QGesture *create(QObject *target);
+ QGestureRecognizer::Result recognize(QGesture *state, QObject *watched, QEvent *event);
+ void reset(QGesture *state);
+
+private:
+ Qt::MouseButton button; // NoButton == Touch
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_GESTURES
+
+#endif // QFLICKGESTURE_P_H
diff --git a/src/gui/util/qscroller.cpp b/src/widgets/util/qscroller.cpp
index 7ad726228d..7ad726228d 100644
--- a/src/gui/util/qscroller.cpp
+++ b/src/widgets/util/qscroller.cpp
diff --git a/src/widgets/util/qscroller.h b/src/widgets/util/qscroller.h
new file mode 100644
index 0000000000..3484139cbb
--- /dev/null
+++ b/src/widgets/util/qscroller.h
@@ -0,0 +1,155 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSCROLLER_H
+#define QSCROLLER_H
+
+#include <QtCore/QObject>
+#include <QtCore/QPointF>
+#include <QtWidgets/QScrollerProperties>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QWidget;
+class QScrollerPrivate;
+class QScrollerProperties;
+#ifndef QT_NO_GESTURES
+class QFlickGestureRecognizer;
+class QMouseFlickGestureRecognizer;
+#endif
+
+class Q_WIDGETS_EXPORT QScroller : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(State state READ state NOTIFY stateChanged)
+ Q_PROPERTY(QScrollerProperties scrollerProperties READ scrollerProperties WRITE setScrollerProperties NOTIFY scrollerPropertiesChanged)
+ Q_ENUMS(State)
+
+public:
+ enum State
+ {
+ Inactive,
+ Pressed,
+ Dragging,
+ Scrolling
+ };
+
+ enum ScrollerGestureType
+ {
+ TouchGesture,
+ LeftMouseButtonGesture,
+ RightMouseButtonGesture,
+ MiddleMouseButtonGesture
+ };
+
+ enum Input
+ {
+ InputPress = 1,
+ InputMove,
+ InputRelease
+ };
+
+ static bool hasScroller(QObject *target);
+
+ static QScroller *scroller(QObject *target);
+ static const QScroller *scroller(const QObject *target);
+
+#ifndef QT_NO_GESTURES
+ static Qt::GestureType grabGesture(QObject *target, ScrollerGestureType gestureType = TouchGesture);
+ static Qt::GestureType grabbedGesture(QObject *target);
+ static void ungrabGesture(QObject *target);
+#endif
+
+ static QList<QScroller *> activeScrollers();
+
+ QObject *target() const;
+
+ State state() const;
+
+ bool handleInput(Input input, const QPointF &position, qint64 timestamp = 0);
+
+ void stop();
+ QPointF velocity() const;
+ QPointF finalPosition() const;
+ QPointF pixelPerMeter() const;
+
+ QScrollerProperties scrollerProperties() const;
+
+ void setSnapPositionsX( const QList<qreal> &positions );
+ void setSnapPositionsX( qreal first, qreal interval );
+ void setSnapPositionsY( const QList<qreal> &positions );
+ void setSnapPositionsY( qreal first, qreal interval );
+
+public Q_SLOTS:
+ void setScrollerProperties(const QScrollerProperties &prop);
+ void scrollTo(const QPointF &pos);
+ void scrollTo(const QPointF &pos, int scrollTime);
+ void ensureVisible(const QRectF &rect, qreal xmargin, qreal ymargin);
+ void ensureVisible(const QRectF &rect, qreal xmargin, qreal ymargin, int scrollTime);
+ void resendPrepareEvent();
+
+Q_SIGNALS:
+ void stateChanged(QScroller::State newstate);
+ void scrollerPropertiesChanged(const QScrollerProperties &);
+
+private:
+ QScrollerPrivate *d_ptr;
+
+ QScroller(QObject *target);
+ virtual ~QScroller();
+
+ Q_DISABLE_COPY(QScroller)
+ Q_DECLARE_PRIVATE(QScroller)
+
+#ifndef QT_NO_GESTURES
+ friend class QFlickGestureRecognizer;
+#endif
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QSCROLLER_H
diff --git a/src/gui/util/qscroller_mac.mm b/src/widgets/util/qscroller_mac.mm
index 81d18aaf6b..81d18aaf6b 100644
--- a/src/gui/util/qscroller_mac.mm
+++ b/src/widgets/util/qscroller_mac.mm
diff --git a/src/gui/util/qscroller_p.h b/src/widgets/util/qscroller_p.h
index b4f4db5e34..b4f4db5e34 100644
--- a/src/gui/util/qscroller_p.h
+++ b/src/widgets/util/qscroller_p.h
diff --git a/src/gui/util/qscrollerproperties.cpp b/src/widgets/util/qscrollerproperties.cpp
index 5e2459a37e..5e2459a37e 100644
--- a/src/gui/util/qscrollerproperties.cpp
+++ b/src/widgets/util/qscrollerproperties.cpp
diff --git a/src/widgets/util/qscrollerproperties.h b/src/widgets/util/qscrollerproperties.h
new file mode 100644
index 0000000000..73c1125fe0
--- /dev/null
+++ b/src/widgets/util/qscrollerproperties.h
@@ -0,0 +1,140 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSCROLLERPROPERTIES_H
+#define QSCROLLERPROPERTIES_H
+
+#include <QtCore/QScopedPointer>
+#include <QtCore/QMetaType>
+#include <QtCore/QVariant>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QScroller;
+class QScrollerPrivate;
+class QScrollerPropertiesPrivate;
+
+class Q_WIDGETS_EXPORT QScrollerProperties
+{
+public:
+ QScrollerProperties();
+ QScrollerProperties(const QScrollerProperties &sp);
+ QScrollerProperties &operator=(const QScrollerProperties &sp);
+ virtual ~QScrollerProperties();
+
+ bool operator==(const QScrollerProperties &sp) const;
+ bool operator!=(const QScrollerProperties &sp) const;
+
+ static void setDefaultScrollerProperties(const QScrollerProperties &sp);
+ static void unsetDefaultScrollerProperties();
+
+ enum OvershootPolicy
+ {
+ OvershootWhenScrollable,
+ OvershootAlwaysOff,
+ OvershootAlwaysOn
+ };
+
+ enum FrameRates {
+ Standard,
+ Fps60,
+ Fps30,
+ Fps20
+ };
+
+ enum ScrollMetric
+ {
+ MousePressEventDelay, // qreal [s]
+ DragStartDistance, // qreal [m]
+ DragVelocitySmoothingFactor, // qreal [0..1/s] (complex calculation involving time) v = v_new* DASF + v_old * (1-DASF)
+ AxisLockThreshold, // qreal [0..1] atan(|min(dx,dy)|/|max(dx,dy)|)
+
+ ScrollingCurve, // QEasingCurve
+ DecelerationFactor, // slope of the curve
+
+ MinimumVelocity, // qreal [m/s]
+ MaximumVelocity, // qreal [m/s]
+ MaximumClickThroughVelocity, // qreal [m/s]
+
+ AcceleratingFlickMaximumTime, // qreal [s]
+ AcceleratingFlickSpeedupFactor, // qreal [1..]
+
+ SnapPositionRatio, // qreal [0..1]
+ SnapTime, // qreal [s]
+
+ OvershootDragResistanceFactor, // qreal [0..1]
+ OvershootDragDistanceFactor, // qreal [0..1]
+ OvershootScrollDistanceFactor, // qreal [0..1]
+ OvershootScrollTime, // qreal [s]
+
+ HorizontalOvershootPolicy, // enum OvershootPolicy
+ VerticalOvershootPolicy, // enum OvershootPolicy
+ FrameRate, // enum FrameRates
+
+ ScrollMetricCount
+ };
+
+ QVariant scrollMetric(ScrollMetric metric) const;
+ void setScrollMetric(ScrollMetric metric, const QVariant &value);
+
+protected:
+ QScopedPointer<QScrollerPropertiesPrivate> d;
+
+private:
+ QScrollerProperties(QScrollerPropertiesPrivate &dd);
+
+ friend class QScrollerPropertiesPrivate;
+ friend class QScroller;
+ friend class QScrollerPrivate;
+};
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QScrollerProperties::OvershootPolicy)
+Q_DECLARE_METATYPE(QScrollerProperties::FrameRates)
+
+QT_END_HEADER
+
+#endif // QSCROLLERPROPERTIES_H
diff --git a/src/gui/util/qscrollerproperties_p.h b/src/widgets/util/qscrollerproperties_p.h
index 2e57a3f7dd..2e57a3f7dd 100644
--- a/src/gui/util/qscrollerproperties_p.h
+++ b/src/widgets/util/qscrollerproperties_p.h
diff --git a/src/widgets/util/qsystemtrayicon.cpp b/src/widgets/util/qsystemtrayicon.cpp
new file mode 100644
index 0000000000..f6eeaa02b2
--- /dev/null
+++ b/src/widgets/util/qsystemtrayicon.cpp
@@ -0,0 +1,674 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qsystemtrayicon.h"
+#include "qsystemtrayicon_p.h"
+
+#ifndef QT_NO_SYSTEMTRAYICON
+
+#include "qmenu.h"
+#include "qevent.h"
+#include "qpoint.h"
+#include "qlabel.h"
+#include "qpushbutton.h"
+#include "qpainterpath.h"
+#include "qpainter.h"
+#include "qstyle.h"
+#include "qgridlayout.h"
+#include "qapplication.h"
+#include "qdesktopwidget.h"
+#include "qbitmap.h"
+#include "private/qlabel_p.h"
+#include "qapplication.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QSystemTrayIcon
+ \brief The QSystemTrayIcon class provides an icon for an application in the system tray.
+ \since 4.2
+ \ingroup desktop
+
+ Modern operating systems usually provide a special area on the desktop,
+ called the \e{system tray} or \e{notification area}, where long-running
+ applications can display icons and short messages.
+
+ \image system-tray.png The system tray on Windows XP.
+
+ The QSystemTrayIcon class can be used on the following platforms:
+
+ \list
+ \o All supported versions of Windows.
+ \o All window managers for X11 that implement the \l{freedesktop.org} system
+ tray specification, including recent versions of KDE and GNOME.
+ \o All supported versions of Mac OS X. Note that the Growl
+ notification system must be installed for
+ QSystemTrayIcon::showMessage() to display messages.
+ \endlist
+
+ To check whether a system tray is present on the user's desktop,
+ call the QSystemTrayIcon::isSystemTrayAvailable() static function.
+
+ To add a system tray entry, create a QSystemTrayIcon object, call setContextMenu()
+ to provide a context menu for the icon, and call show() to make it visible in the
+ system tray. Status notification messages ("balloon messages") can be displayed at
+ any time using showMessage().
+
+ If the system tray is unavailable when a system tray icon is constructed, but
+ becomes available later, QSystemTrayIcon will automatically add an entry for the
+ application in the system tray if the icon is \l visible.
+
+ The activated() signal is emitted when the user activates the icon.
+
+ Only on X11, when a tooltip is requested, the QSystemTrayIcon receives a QHelpEvent
+ of type QEvent::ToolTip. Additionally, the QSystemTrayIcon receives wheel events of
+ type QEvent::Wheel. These are not supported on any other platform.
+
+ \sa QDesktopServices, QDesktopWidget, {Desktop Integration}, {System Tray Icon Example}
+*/
+
+/*!
+ \enum QSystemTrayIcon::MessageIcon
+
+ This enum describes the icon that is shown when a balloon message is displayed.
+
+ \value NoIcon No icon is shown.
+ \value Information An information icon is shown.
+ \value Warning A standard warning icon is shown.
+ \value Critical A critical warning icon is shown.
+
+ \sa QMessageBox
+*/
+
+/*!
+ Constructs a QSystemTrayIcon object with the given \a parent.
+
+ The icon is initially invisible.
+
+ \sa visible
+*/
+QSystemTrayIcon::QSystemTrayIcon(QObject *parent)
+: QObject(*new QSystemTrayIconPrivate(), parent)
+{
+}
+
+/*!
+ Constructs a QSystemTrayIcon object with the given \a icon and \a parent.
+
+ The icon is initially invisible.
+
+ \sa visible
+*/
+QSystemTrayIcon::QSystemTrayIcon(const QIcon &icon, QObject *parent)
+: QObject(*new QSystemTrayIconPrivate(), parent)
+{
+ setIcon(icon);
+}
+
+/*!
+ Removes the icon from the system tray and frees all allocated resources.
+*/
+QSystemTrayIcon::~QSystemTrayIcon()
+{
+ Q_D(QSystemTrayIcon);
+ d->remove_sys();
+}
+
+#ifndef QT_NO_MENU
+
+/*!
+ Sets the specified \a menu to be the context menu for the system tray icon.
+
+ The menu will pop up when the user requests the context menu for the system
+ tray icon by clicking the mouse button.
+
+ On Mac OS X, this is currenly converted to a NSMenu, so the
+ aboutToHide() signal is not emitted.
+
+ \note The system tray icon does not take ownership of the menu. You must
+ ensure that it is deleted at the appropriate time by, for example, creating
+ the menu with a suitable parent object.
+*/
+void QSystemTrayIcon::setContextMenu(QMenu *menu)
+{
+ Q_D(QSystemTrayIcon);
+ d->menu = menu;
+ d->updateMenu_sys();
+}
+
+/*!
+ Returns the current context menu for the system tray entry.
+*/
+QMenu* QSystemTrayIcon::contextMenu() const
+{
+ Q_D(const QSystemTrayIcon);
+ return d->menu;
+}
+
+#endif // QT_NO_MENU
+
+/*!
+ \property QSystemTrayIcon::icon
+ \brief the system tray icon
+
+ On Windows, the system tray icon size is 16x16; on X11, the preferred size is
+ 22x22. The icon will be scaled to the appropriate size as necessary.
+*/
+void QSystemTrayIcon::setIcon(const QIcon &icon)
+{
+ Q_D(QSystemTrayIcon);
+ d->icon = icon;
+ d->updateIcon_sys();
+}
+
+QIcon QSystemTrayIcon::icon() const
+{
+ Q_D(const QSystemTrayIcon);
+ return d->icon;
+}
+
+/*!
+ \property QSystemTrayIcon::toolTip
+ \brief the tooltip for the system tray entry
+
+ On some systems, the tooltip's length is limited. The tooltip will be truncated
+ if necessary.
+*/
+void QSystemTrayIcon::setToolTip(const QString &tooltip)
+{
+ Q_D(QSystemTrayIcon);
+ d->toolTip = tooltip;
+ d->updateToolTip_sys();
+}
+
+QString QSystemTrayIcon::toolTip() const
+{
+ Q_D(const QSystemTrayIcon);
+ return d->toolTip;
+}
+
+/*!
+ \fn void QSystemTrayIcon::show()
+
+ Shows the icon in the system tray.
+
+ \sa hide(), visible
+*/
+
+/*!
+ \fn void QSystemTrayIcon::hide()
+
+ Hides the system tray entry.
+
+ \sa show(), visible
+*/
+
+/*!
+ \since 4.3
+ Returns the geometry of the system tray icon in screen coordinates.
+
+ \sa visible
+*/
+QRect QSystemTrayIcon::geometry() const
+{
+ Q_D(const QSystemTrayIcon);
+ if (!d->visible)
+ return QRect();
+ return d->geometry_sys();
+}
+
+/*!
+ \property QSystemTrayIcon::visible
+ \brief whether the system tray entry is visible
+
+ Setting this property to true or calling show() makes the system tray icon
+ visible; setting this property to false or calling hide() hides it.
+*/
+void QSystemTrayIcon::setVisible(bool visible)
+{
+ Q_D(QSystemTrayIcon);
+ if (visible == d->visible)
+ return;
+ if (d->icon.isNull() && visible)
+ qWarning("QSystemTrayIcon::setVisible: No Icon set");
+ d->visible = visible;
+ if (d->visible)
+ d->install_sys();
+ else
+ d->remove_sys();
+}
+
+bool QSystemTrayIcon::isVisible() const
+{
+ Q_D(const QSystemTrayIcon);
+ return d->visible;
+}
+
+/*!
+ \reimp
+*/
+bool QSystemTrayIcon::event(QEvent *e)
+{
+#if defined(Q_WS_X11)
+ if (e->type() == QEvent::ToolTip) {
+ Q_D(QSystemTrayIcon);
+ return d->sys->deliverToolTipEvent(e);
+ }
+#endif
+ return QObject::event(e);
+}
+
+/*!
+ \enum QSystemTrayIcon::ActivationReason
+
+ This enum describes the reason the system tray was activated.
+
+ \value Unknown Unknown reason
+ \value Context The context menu for the system tray entry was requested
+ \value DoubleClick The system tray entry was double clicked
+ \value Trigger The system tray entry was clicked
+ \value MiddleClick The system tray entry was clicked with the middle mouse button
+
+ \sa activated()
+*/
+
+/*!
+ \fn void QSystemTrayIcon::activated(QSystemTrayIcon::ActivationReason reason)
+
+ This signal is emitted when the user activates the system tray icon. \a reason
+ specifies the reason for activation. QSystemTrayIcon::ActivationReason enumerates
+ the various reasons.
+
+ \sa QSystemTrayIcon::ActivationReason
+*/
+
+/*!
+ \fn void QSystemTrayIcon::messageClicked()
+
+ This signal is emitted when the message displayed using showMessage()
+ was clicked by the user.
+
+ Currently this signal is not sent on Mac OS X.
+
+ \note We follow Microsoft Windows XP/Vista behavior, so the
+ signal is also emitted when the user clicks on a tray icon with
+ a balloon message displayed.
+
+ \sa activated()
+*/
+
+
+/*!
+ Returns true if the system tray is available; otherwise returns false.
+
+ If the system tray is currently unavailable but becomes available later,
+ QSystemTrayIcon will automatically add an entry in the system tray if it
+ is \l visible.
+*/
+
+bool QSystemTrayIcon::isSystemTrayAvailable()
+{
+ return QSystemTrayIconPrivate::isSystemTrayAvailable_sys();
+}
+
+/*!
+ Returns true if the system tray supports balloon messages; otherwise returns false.
+
+ \sa showMessage()
+*/
+bool QSystemTrayIcon::supportsMessages()
+{
+ return QSystemTrayIconPrivate::supportsMessages_sys();
+}
+
+/*!
+ \fn void QSystemTrayIcon::showMessage(const QString &title, const QString &message, MessageIcon icon, int millisecondsTimeoutHint)
+ \since 4.3
+
+ Shows a balloon message for the entry with the given \a title, \a message and
+ \a icon for the time specified in \a millisecondsTimeoutHint. \a title and \a message
+ must be plain text strings.
+
+ Message can be clicked by the user; the messageClicked() signal will emitted when
+ this occurs.
+
+ Note that display of messages are dependent on the system configuration and user
+ preferences, and that messages may not appear at all. Hence, it should not be
+ relied upon as the sole means for providing critical information.
+
+ On Windows, the \a millisecondsTimeoutHint is usually ignored by the system
+ when the application has focus.
+
+ On Mac OS X, the Growl notification system must be installed for this function to
+ display messages.
+
+ \sa show() supportsMessages()
+ */
+void QSystemTrayIcon::showMessage(const QString& title, const QString& msg,
+ QSystemTrayIcon::MessageIcon icon, int msecs)
+{
+ Q_D(QSystemTrayIcon);
+ if (d->visible)
+ d->showMessage_sys(title, msg, icon, msecs);
+}
+
+//////////////////////////////////////////////////////////////////////
+static QBalloonTip *theSolitaryBalloonTip = 0;
+
+void QBalloonTip::showBalloon(QSystemTrayIcon::MessageIcon icon, const QString& title,
+ const QString& message, QSystemTrayIcon *trayIcon,
+ const QPoint& pos, int timeout, bool showArrow)
+{
+ hideBalloon();
+ if (message.isEmpty() && title.isEmpty())
+ return;
+
+ theSolitaryBalloonTip = new QBalloonTip(icon, title, message, trayIcon);
+ if (timeout < 0)
+ timeout = 10000; //10 s default
+ theSolitaryBalloonTip->balloon(pos, timeout, showArrow);
+}
+
+void QBalloonTip::hideBalloon()
+{
+ if (!theSolitaryBalloonTip)
+ return;
+ theSolitaryBalloonTip->hide();
+ delete theSolitaryBalloonTip;
+ theSolitaryBalloonTip = 0;
+}
+
+bool QBalloonTip::isBalloonVisible()
+{
+ return theSolitaryBalloonTip;
+}
+
+QBalloonTip::QBalloonTip(QSystemTrayIcon::MessageIcon icon, const QString& title,
+ const QString& message, QSystemTrayIcon *ti)
+ : QWidget(0, Qt::ToolTip), trayIcon(ti), timerId(-1)
+{
+ setAttribute(Qt::WA_DeleteOnClose);
+ QObject::connect(ti, SIGNAL(destroyed()), this, SLOT(close()));
+
+ QLabel *titleLabel = new QLabel;
+ titleLabel->installEventFilter(this);
+ titleLabel->setText(title);
+ QFont f = titleLabel->font();
+ f.setBold(true);
+#ifdef Q_WS_WINCE
+ f.setPointSize(f.pointSize() - 2);
+#endif
+ titleLabel->setFont(f);
+ titleLabel->setTextFormat(Qt::PlainText); // to maintain compat with windows
+
+#ifdef Q_WS_WINCE
+ const int iconSize = style()->pixelMetric(QStyle::PM_SmallIconSize);
+ const int closeButtonSize = style()->pixelMetric(QStyle::PM_SmallIconSize) - 2;
+#else
+ const int iconSize = 18;
+ const int closeButtonSize = 15;
+#endif
+
+ QPushButton *closeButton = new QPushButton;
+ closeButton->setIcon(style()->standardIcon(QStyle::SP_TitleBarCloseButton));
+ closeButton->setIconSize(QSize(closeButtonSize, closeButtonSize));
+ closeButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+ closeButton->setFixedSize(closeButtonSize, closeButtonSize);
+ QObject::connect(closeButton, SIGNAL(clicked()), this, SLOT(close()));
+
+ QLabel *msgLabel = new QLabel;
+#ifdef Q_WS_WINCE
+ f.setBold(false);
+ msgLabel->setFont(f);
+#endif
+ msgLabel->installEventFilter(this);
+ msgLabel->setText(message);
+ msgLabel->setTextFormat(Qt::PlainText);
+ msgLabel->setAlignment(Qt::AlignTop | Qt::AlignLeft);
+
+ // smart size for the message label
+#ifdef Q_WS_WINCE
+ int limit = QApplication::desktop()->availableGeometry(msgLabel).size().width() / 2;
+#else
+ int limit = QApplication::desktop()->availableGeometry(msgLabel).size().width() / 3;
+#endif
+ if (msgLabel->sizeHint().width() > limit) {
+ msgLabel->setWordWrap(true);
+ if (msgLabel->sizeHint().width() > limit) {
+ msgLabel->d_func()->ensureTextControl();
+ if (QWidgetTextControl *control = msgLabel->d_func()->control) {
+ QTextOption opt = control->document()->defaultTextOption();
+ opt.setWrapMode(QTextOption::WrapAnywhere);
+ control->document()->setDefaultTextOption(opt);
+ }
+ }
+#ifdef Q_WS_WINCE
+ // Make sure that the text isn't wrapped "somewhere" in the balloon widget
+ // in the case that we have a long title label.
+ setMaximumWidth(limit);
+#else
+ // Here we allow the text being much smaller than the balloon widget
+ // to emulate the weird standard windows behavior.
+ msgLabel->setFixedSize(limit, msgLabel->heightForWidth(limit));
+#endif
+ }
+
+ QIcon si;
+ switch (icon) {
+ case QSystemTrayIcon::Warning:
+ si = style()->standardIcon(QStyle::SP_MessageBoxWarning);
+ break;
+ case QSystemTrayIcon::Critical:
+ si = style()->standardIcon(QStyle::SP_MessageBoxCritical);
+ break;
+ case QSystemTrayIcon::Information:
+ si = style()->standardIcon(QStyle::SP_MessageBoxInformation);
+ break;
+ case QSystemTrayIcon::NoIcon:
+ default:
+ break;
+ }
+
+ QGridLayout *layout = new QGridLayout;
+ if (!si.isNull()) {
+ QLabel *iconLabel = new QLabel;
+ iconLabel->setPixmap(si.pixmap(iconSize, iconSize));
+ iconLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+ iconLabel->setMargin(2);
+ layout->addWidget(iconLabel, 0, 0);
+ layout->addWidget(titleLabel, 0, 1);
+ } else {
+ layout->addWidget(titleLabel, 0, 0, 1, 2);
+ }
+
+ layout->addWidget(closeButton, 0, 2);
+ layout->addWidget(msgLabel, 1, 0, 1, 3);
+ layout->setSizeConstraint(QLayout::SetFixedSize);
+ layout->setMargin(3);
+ setLayout(layout);
+
+ QPalette pal = palette();
+ pal.setColor(QPalette::Window, QColor(0xff, 0xff, 0xe1));
+ pal.setColor(QPalette::WindowText, Qt::black);
+ setPalette(pal);
+}
+
+QBalloonTip::~QBalloonTip()
+{
+ theSolitaryBalloonTip = 0;
+}
+
+void QBalloonTip::paintEvent(QPaintEvent *)
+{
+ QPainter painter(this);
+ painter.drawPixmap(rect(), pixmap);
+}
+
+void QBalloonTip::resizeEvent(QResizeEvent *ev)
+{
+ QWidget::resizeEvent(ev);
+}
+
+void QBalloonTip::balloon(const QPoint& pos, int msecs, bool showArrow)
+{
+ QRect scr = QApplication::desktop()->screenGeometry(pos);
+ QSize sh = sizeHint();
+ const int border = 1;
+ const int ah = 18, ao = 18, aw = 18, rc = 7;
+ bool arrowAtTop = (pos.y() + sh.height() + ah < scr.height());
+ bool arrowAtLeft = (pos.x() + sh.width() - ao < scr.width());
+ setContentsMargins(border + 3, border + (arrowAtTop ? ah : 0) + 2, border + 3, border + (arrowAtTop ? 0 : ah) + 2);
+ updateGeometry();
+ sh = sizeHint();
+
+ int ml, mr, mt, mb;
+ QSize sz = sizeHint();
+ if (!arrowAtTop) {
+ ml = mt = 0;
+ mr = sz.width() - 1;
+ mb = sz.height() - ah - 1;
+ } else {
+ ml = 0;
+ mt = ah;
+ mr = sz.width() - 1;
+ mb = sz.height() - 1;
+ }
+
+ QPainterPath path;
+#if defined(QT_NO_XSHAPE) && defined(Q_WS_X11)
+ // XShape is required for setting the mask, so we just
+ // draw an ugly square when its not available
+ path.moveTo(0, 0);
+ path.lineTo(sz.width() - 1, 0);
+ path.lineTo(sz.width() - 1, sz.height() - 1);
+ path.lineTo(0, sz.height() - 1);
+ path.lineTo(0, 0);
+ move(qMax(pos.x() - sz.width(), scr.left()), pos.y());
+#else
+ path.moveTo(ml + rc, mt);
+ if (arrowAtTop && arrowAtLeft) {
+ if (showArrow) {
+ path.lineTo(ml + ao, mt);
+ path.lineTo(ml + ao, mt - ah);
+ path.lineTo(ml + ao + aw, mt);
+ }
+ move(qMax(pos.x() - ao, scr.left() + 2), pos.y());
+ } else if (arrowAtTop && !arrowAtLeft) {
+ if (showArrow) {
+ path.lineTo(mr - ao - aw, mt);
+ path.lineTo(mr - ao, mt - ah);
+ path.lineTo(mr - ao, mt);
+ }
+ move(qMin(pos.x() - sh.width() + ao, scr.right() - sh.width() - 2), pos.y());
+ }
+ path.lineTo(mr - rc, mt);
+ path.arcTo(QRect(mr - rc*2, mt, rc*2, rc*2), 90, -90);
+ path.lineTo(mr, mb - rc);
+ path.arcTo(QRect(mr - rc*2, mb - rc*2, rc*2, rc*2), 0, -90);
+ if (!arrowAtTop && !arrowAtLeft) {
+ if (showArrow) {
+ path.lineTo(mr - ao, mb);
+ path.lineTo(mr - ao, mb + ah);
+ path.lineTo(mr - ao - aw, mb);
+ }
+ move(qMin(pos.x() - sh.width() + ao, scr.right() - sh.width() - 2),
+ pos.y() - sh.height());
+ } else if (!arrowAtTop && arrowAtLeft) {
+ if (showArrow) {
+ path.lineTo(ao + aw, mb);
+ path.lineTo(ao, mb + ah);
+ path.lineTo(ao, mb);
+ }
+ move(qMax(pos.x() - ao, scr.x() + 2), pos.y() - sh.height());
+ }
+ path.lineTo(ml + rc, mb);
+ path.arcTo(QRect(ml, mb - rc*2, rc*2, rc*2), -90, -90);
+ path.lineTo(ml, mt + rc);
+ path.arcTo(QRect(ml, mt, rc*2, rc*2), 180, -90);
+
+ // Set the mask
+ QBitmap bitmap = QBitmap(sizeHint());
+ bitmap.fill(Qt::color0);
+ QPainter painter1(&bitmap);
+ painter1.setPen(QPen(Qt::color1, border));
+ painter1.setBrush(QBrush(Qt::color1));
+ painter1.drawPath(path);
+ setMask(bitmap);
+#endif
+
+ // Draw the border
+ pixmap = QPixmap(sz);
+ QPainter painter2(&pixmap);
+ painter2.setPen(QPen(palette().color(QPalette::Window).darker(160), border));
+ painter2.setBrush(palette().color(QPalette::Window));
+ painter2.drawPath(path);
+
+ if (msecs > 0)
+ timerId = startTimer(msecs);
+ show();
+}
+
+void QBalloonTip::mousePressEvent(QMouseEvent *e)
+{
+ close();
+ if(e->button() == Qt::LeftButton)
+ emit trayIcon->messageClicked();
+}
+
+void QBalloonTip::timerEvent(QTimerEvent *e)
+{
+ if (e->timerId() == timerId) {
+ killTimer(timerId);
+ if (!underMouse())
+ close();
+ return;
+ }
+ QWidget::timerEvent(e);
+}
+
+void qtsystray_sendActivated(QSystemTrayIcon *i, int r)
+{
+ emit i->activated((QSystemTrayIcon::ActivationReason)r);
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_SYSTEMTRAYICON
diff --git a/src/widgets/util/qsystemtrayicon.h b/src/widgets/util/qsystemtrayicon.h
new file mode 100644
index 0000000000..3327ce4223
--- /dev/null
+++ b/src/widgets/util/qsystemtrayicon.h
@@ -0,0 +1,132 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSYSTEMTRAYICON_H
+#define QSYSTEMTRAYICON_H
+
+#include <QtCore/qobject.h>
+
+#ifndef QT_NO_SYSTEMTRAYICON
+
+#include <QtWidgets/qicon.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QSystemTrayIconPrivate;
+
+class QMenu;
+class QEvent;
+class QWheelEvent;
+class QMouseEvent;
+class QPoint;
+
+class Q_WIDGETS_EXPORT QSystemTrayIcon : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QString toolTip READ toolTip WRITE setToolTip)
+ Q_PROPERTY(QIcon icon READ icon WRITE setIcon)
+ Q_PROPERTY(bool visible READ isVisible WRITE setVisible DESIGNABLE false)
+
+public:
+ QSystemTrayIcon(QObject *parent = 0);
+ QSystemTrayIcon(const QIcon &icon, QObject *parent = 0);
+ ~QSystemTrayIcon();
+
+ enum ActivationReason {
+ Unknown,
+ Context,
+ DoubleClick,
+ Trigger,
+ MiddleClick
+ };
+
+#ifndef QT_NO_MENU
+ void setContextMenu(QMenu *menu);
+ QMenu *contextMenu() const;
+#endif
+
+ QIcon icon() const;
+ void setIcon(const QIcon &icon);
+
+ QString toolTip() const;
+ void setToolTip(const QString &tip);
+
+ static bool isSystemTrayAvailable();
+ static bool supportsMessages();
+
+ enum MessageIcon { NoIcon, Information, Warning, Critical };
+ void showMessage(const QString &title, const QString &msg,
+ MessageIcon icon = Information, int msecs = 10000);
+
+ QRect geometry() const;
+ bool isVisible() const;
+
+public Q_SLOTS:
+ void setVisible(bool visible);
+ inline void show() { setVisible(true); }
+ inline void hide() { setVisible(false); }
+
+Q_SIGNALS:
+ void activated(QSystemTrayIcon::ActivationReason reason);
+ void messageClicked();
+
+protected:
+ bool event(QEvent *event);
+
+private:
+ Q_DISABLE_COPY(QSystemTrayIcon)
+ Q_DECLARE_PRIVATE(QSystemTrayIcon)
+
+ friend class QSystemTrayIconSys;
+ friend class QBalloonTip;
+ friend void qtsystray_sendActivated(QSystemTrayIcon *, int);
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QT_NO_SYSTEMTRAYICON
+#endif // QSYSTEMTRAYICON_H
diff --git a/src/gui/util/qsystemtrayicon_mac.mm b/src/widgets/util/qsystemtrayicon_mac.mm
index 4186ac3e55..4186ac3e55 100644
--- a/src/gui/util/qsystemtrayicon_mac.mm
+++ b/src/widgets/util/qsystemtrayicon_mac.mm
diff --git a/src/widgets/util/qsystemtrayicon_p.h b/src/widgets/util/qsystemtrayicon_p.h
new file mode 100644
index 0000000000..ce2404ae8b
--- /dev/null
+++ b/src/widgets/util/qsystemtrayicon_p.h
@@ -0,0 +1,186 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSYSTEMTRAYICON_P_H
+#define QSYSTEMTRAYICON_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of a number of Qt sources files. This header file may change from
+// version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qsystemtrayicon.h"
+#include "private/qobject_p.h"
+
+#ifndef QT_NO_SYSTEMTRAYICON
+
+#include "QtWidgets/qmenu.h"
+#include "QtGui/qpixmap.h"
+#include "QtCore/qstring.h"
+#include "QtCore/qpointer.h"
+
+QT_BEGIN_NAMESPACE
+
+class QSystemTrayIconSys;
+class QToolButton;
+class QLabel;
+
+class QSystemTrayIconPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QSystemTrayIcon)
+
+public:
+ QSystemTrayIconPrivate() : sys(0), visible(false) { }
+
+ void install_sys();
+ void remove_sys();
+ void updateIcon_sys();
+ void updateToolTip_sys();
+ void updateMenu_sys();
+ QRect geometry_sys() const;
+ void showMessage_sys(const QString &msg, const QString &title, QSystemTrayIcon::MessageIcon icon, int secs);
+
+ static bool isSystemTrayAvailable_sys();
+ static bool supportsMessages_sys();
+
+ QPointer<QMenu> menu;
+ QIcon icon;
+ QString toolTip;
+ QSystemTrayIconSys *sys;
+ bool visible;
+};
+
+class QBalloonTip : public QWidget
+{
+ Q_OBJECT
+public:
+ static void showBalloon(QSystemTrayIcon::MessageIcon icon, const QString& title,
+ const QString& msg, QSystemTrayIcon *trayIcon,
+ const QPoint& pos, int timeout, bool showArrow = true);
+ static void hideBalloon();
+ static bool isBalloonVisible();
+
+private:
+ QBalloonTip(QSystemTrayIcon::MessageIcon icon, const QString& title,
+ const QString& msg, QSystemTrayIcon *trayIcon);
+ ~QBalloonTip();
+ void balloon(const QPoint&, int, bool);
+
+protected:
+ void paintEvent(QPaintEvent *);
+ void resizeEvent(QResizeEvent *);
+ void mousePressEvent(QMouseEvent *e);
+ void timerEvent(QTimerEvent *e);
+
+private:
+ QSystemTrayIcon *trayIcon;
+ QPixmap pixmap;
+ int timerId;
+};
+
+#if defined(Q_WS_X11)
+QT_BEGIN_INCLUDE_NAMESPACE
+#include <QtCore/qcoreapplication.h>
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+#include <X11/Xutil.h>
+QT_END_INCLUDE_NAMESPACE
+
+class QSystemTrayIconSys : public QWidget
+{
+ friend class QSystemTrayIconPrivate;
+
+public:
+ QSystemTrayIconSys(QSystemTrayIcon *q);
+ ~QSystemTrayIconSys();
+ enum {
+ SYSTEM_TRAY_REQUEST_DOCK = 0,
+ SYSTEM_TRAY_BEGIN_MESSAGE = 1,
+ SYSTEM_TRAY_CANCEL_MESSAGE =2
+ };
+
+ void addToTray();
+ void updateIcon();
+ XVisualInfo* getSysTrayVisualInfo();
+
+ // QObject::event is public but QWidget's ::event() re-implementation
+ // is protected ;(
+ inline bool deliverToolTipEvent(QEvent *e)
+ { return QWidget::event(e); }
+
+ static Window sysTrayWindow;
+ static QList<QSystemTrayIconSys *> trayIcons;
+ static QCoreApplication::EventFilter oldEventFilter;
+ static bool sysTrayTracker(void *message, long *result);
+ static Window locateSystemTray();
+ static Atom sysTraySelection;
+ static XVisualInfo sysTrayVisual;
+
+protected:
+ void paintEvent(QPaintEvent *pe);
+ void resizeEvent(QResizeEvent *re);
+ bool x11Event(XEvent *event);
+ void mousePressEvent(QMouseEvent *event);
+ void mouseDoubleClickEvent(QMouseEvent *event);
+#ifndef QT_NO_WHEELEVENT
+ void wheelEvent(QWheelEvent *event);
+#endif
+ bool event(QEvent *e);
+
+private:
+ QPixmap background;
+ QSystemTrayIcon *q;
+ Colormap colormap;
+};
+#endif // Q_WS_X11
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_SYSTEMTRAYICON
+
+#endif // QSYSTEMTRAYICON_P_H
+
diff --git a/src/gui/util/qsystemtrayicon_qws.cpp b/src/widgets/util/qsystemtrayicon_qpa.cpp
index 9a4f12d02d..9a4f12d02d 100644
--- a/src/gui/util/qsystemtrayicon_qws.cpp
+++ b/src/widgets/util/qsystemtrayicon_qpa.cpp
diff --git a/src/gui/util/qsystemtrayicon_win.cpp b/src/widgets/util/qsystemtrayicon_win.cpp
index 7a572849b0..7a572849b0 100644
--- a/src/gui/util/qsystemtrayicon_win.cpp
+++ b/src/widgets/util/qsystemtrayicon_win.cpp
diff --git a/src/gui/util/qsystemtrayicon_wince.cpp b/src/widgets/util/qsystemtrayicon_wince.cpp
index 7a403a3ee5..7a403a3ee5 100644
--- a/src/gui/util/qsystemtrayicon_wince.cpp
+++ b/src/widgets/util/qsystemtrayicon_wince.cpp
diff --git a/src/gui/util/qsystemtrayicon_x11.cpp b/src/widgets/util/qsystemtrayicon_x11.cpp
index 86c27499b4..86c27499b4 100644
--- a/src/gui/util/qsystemtrayicon_x11.cpp
+++ b/src/widgets/util/qsystemtrayicon_x11.cpp
diff --git a/src/gui/util/qundogroup.cpp b/src/widgets/util/qundogroup.cpp
index 4f83e3a815..4f83e3a815 100644
--- a/src/gui/util/qundogroup.cpp
+++ b/src/widgets/util/qundogroup.cpp
diff --git a/src/widgets/util/qundogroup.h b/src/widgets/util/qundogroup.h
new file mode 100644
index 0000000000..ce2dac2503
--- /dev/null
+++ b/src/widgets/util/qundogroup.h
@@ -0,0 +1,110 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QUNDOGROUP_H
+#define QUNDOGROUP_H
+
+#include <QtCore/qobject.h>
+#include <QtCore/qstring.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QUndoGroupPrivate;
+class QUndoStack;
+class QAction;
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_UNDOGROUP
+
+class Q_WIDGETS_EXPORT QUndoGroup : public QObject
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QUndoGroup)
+
+public:
+ explicit QUndoGroup(QObject *parent = 0);
+ ~QUndoGroup();
+
+ void addStack(QUndoStack *stack);
+ void removeStack(QUndoStack *stack);
+ QList<QUndoStack*> stacks() const;
+ QUndoStack *activeStack() const;
+
+#ifndef QT_NO_ACTION
+ QAction *createUndoAction(QObject *parent,
+ const QString &prefix = QString()) const;
+ QAction *createRedoAction(QObject *parent,
+ const QString &prefix = QString()) const;
+#endif // QT_NO_ACTION
+ bool canUndo() const;
+ bool canRedo() const;
+ QString undoText() const;
+ QString redoText() const;
+ bool isClean() const;
+
+public Q_SLOTS:
+ void undo();
+ void redo();
+ void setActiveStack(QUndoStack *stack);
+
+Q_SIGNALS:
+ void activeStackChanged(QUndoStack *stack);
+ void indexChanged(int idx);
+ void cleanChanged(bool clean);
+ void canUndoChanged(bool canUndo);
+ void canRedoChanged(bool canRedo);
+ void undoTextChanged(const QString &undoText);
+ void redoTextChanged(const QString &redoText);
+
+private:
+ Q_DISABLE_COPY(QUndoGroup)
+};
+
+#endif // QT_NO_UNDOGROUP
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QUNDOGROUP_H
diff --git a/src/gui/util/qundostack.cpp b/src/widgets/util/qundostack.cpp
index 59e73e6ad2..59e73e6ad2 100644
--- a/src/gui/util/qundostack.cpp
+++ b/src/widgets/util/qundostack.cpp
diff --git a/src/widgets/util/qundostack.h b/src/widgets/util/qundostack.h
new file mode 100644
index 0000000000..493d11fdb7
--- /dev/null
+++ b/src/widgets/util/qundostack.h
@@ -0,0 +1,159 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QUNDOSTACK_H
+#define QUNDOSTACK_H
+
+#include <QtCore/qobject.h>
+#include <QtCore/qstring.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QAction;
+class QUndoCommandPrivate;
+class QUndoStackPrivate;
+
+#ifndef QT_NO_UNDOCOMMAND
+
+class Q_WIDGETS_EXPORT QUndoCommand
+{
+ QUndoCommandPrivate *d;
+
+public:
+ explicit QUndoCommand(QUndoCommand *parent = 0);
+ explicit QUndoCommand(const QString &text, QUndoCommand *parent = 0);
+ virtual ~QUndoCommand();
+
+ virtual void undo();
+ virtual void redo();
+
+ QString text() const;
+ QString actionText() const;
+ void setText(const QString &text);
+
+ virtual int id() const;
+ virtual bool mergeWith(const QUndoCommand *other);
+
+ int childCount() const;
+ const QUndoCommand *child(int index) const;
+
+private:
+ Q_DISABLE_COPY(QUndoCommand)
+ friend class QUndoStack;
+};
+
+#endif // QT_NO_UNDOCOMMAND
+
+#ifndef QT_NO_UNDOSTACK
+
+class Q_WIDGETS_EXPORT QUndoStack : public QObject
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QUndoStack)
+ Q_PROPERTY(bool active READ isActive WRITE setActive)
+ Q_PROPERTY(int undoLimit READ undoLimit WRITE setUndoLimit)
+
+public:
+ explicit QUndoStack(QObject *parent = 0);
+ ~QUndoStack();
+ void clear();
+
+ void push(QUndoCommand *cmd);
+
+ bool canUndo() const;
+ bool canRedo() const;
+ QString undoText() const;
+ QString redoText() const;
+
+ int count() const;
+ int index() const;
+ QString text(int idx) const;
+
+#ifndef QT_NO_ACTION
+ QAction *createUndoAction(QObject *parent,
+ const QString &prefix = QString()) const;
+ QAction *createRedoAction(QObject *parent,
+ const QString &prefix = QString()) const;
+#endif // QT_NO_ACTION
+
+ bool isActive() const;
+ bool isClean() const;
+ int cleanIndex() const;
+
+ void beginMacro(const QString &text);
+ void endMacro();
+
+ void setUndoLimit(int limit);
+ int undoLimit() const;
+
+ const QUndoCommand *command(int index) const;
+
+public Q_SLOTS:
+ void setClean();
+ void setIndex(int idx);
+ void undo();
+ void redo();
+ void setActive(bool active = true);
+
+Q_SIGNALS:
+ void indexChanged(int idx);
+ void cleanChanged(bool clean);
+ void canUndoChanged(bool canUndo);
+ void canRedoChanged(bool canRedo);
+ void undoTextChanged(const QString &undoText);
+ void redoTextChanged(const QString &redoText);
+
+private:
+ Q_DISABLE_COPY(QUndoStack)
+ friend class QUndoGroup;
+};
+
+#endif // QT_NO_UNDOSTACK
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QUNDOSTACK_H
diff --git a/src/widgets/util/qundostack_p.h b/src/widgets/util/qundostack_p.h
new file mode 100644
index 0000000000..1e5f99bc6c
--- /dev/null
+++ b/src/widgets/util/qundostack_p.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QUNDOSTACK_P_H
+#define QUNDOSTACK_P_H
+
+#include <private/qobject_p.h>
+#include <QtCore/qlist.h>
+#include <QtCore/qstring.h>
+#include <QtWidgets/qaction.h>
+
+#include "qundostack.h"
+
+QT_BEGIN_NAMESPACE
+class QUndoCommand;
+class QUndoGroup;
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+class QUndoCommandPrivate
+{
+public:
+ QUndoCommandPrivate() : id(-1) {}
+ QList<QUndoCommand*> child_list;
+ QString text;
+ QString actionText;
+ int id;
+};
+
+#ifndef QT_NO_UNDOSTACK
+
+class QUndoStackPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QUndoStack)
+public:
+ QUndoStackPrivate() : index(0), clean_index(0), group(0), undo_limit(0) {}
+
+ QList<QUndoCommand*> command_list;
+ QList<QUndoCommand*> macro_stack;
+ int index;
+ int clean_index;
+ QUndoGroup *group;
+ int undo_limit;
+
+ void setIndex(int idx, bool clean);
+ bool checkUndoLimit();
+};
+
+#ifndef QT_NO_ACTION
+class QUndoAction : public QAction
+{
+ Q_OBJECT
+public:
+ QUndoAction(const QString &prefix, QObject *parent = 0);
+ void setTextFormat(const QString &textFormat, const QString &defaultText);
+public Q_SLOTS:
+ void setPrefixedText(const QString &text);
+private:
+ QString m_prefix;
+ QString m_defaultText;
+};
+#endif // QT_NO_ACTION
+
+
+QT_END_NAMESPACE
+#endif // QT_NO_UNDOSTACK
+#endif // QUNDOSTACK_P_H
diff --git a/src/widgets/util/qundoview.cpp b/src/widgets/util/qundoview.cpp
new file mode 100644
index 0000000000..820fcaf2de
--- /dev/null
+++ b/src/widgets/util/qundoview.cpp
@@ -0,0 +1,476 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qundostack.h"
+#include "qundoview.h"
+
+#ifndef QT_NO_UNDOVIEW
+
+#include "qundogroup.h"
+#include <QtCore/qabstractitemmodel.h>
+#include <QtCore/qpointer.h>
+#include <QtWidgets/qicon.h>
+#include <private/qlistview_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QUndoModel : public QAbstractItemModel
+{
+ Q_OBJECT
+public:
+ QUndoModel(QObject *parent = 0);
+
+ QUndoStack *stack() const;
+
+ virtual QModelIndex index(int row, int column,
+ const QModelIndex &parent = QModelIndex()) const;
+ virtual QModelIndex parent(const QModelIndex &child) const;
+ virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
+ virtual int columnCount(const QModelIndex &parent = QModelIndex()) const;
+ virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+
+ QModelIndex selectedIndex() const;
+ QItemSelectionModel *selectionModel() const;
+
+ QString emptyLabel() const;
+ void setEmptyLabel(const QString &label);
+
+ void setCleanIcon(const QIcon &icon);
+ QIcon cleanIcon() const;
+
+public slots:
+ void setStack(QUndoStack *stack);
+
+private slots:
+ void stackChanged();
+ void stackDestroyed(QObject *obj);
+ void setStackCurrentIndex(const QModelIndex &index);
+
+private:
+ QUndoStack *m_stack;
+ QItemSelectionModel *m_sel_model;
+ QString m_emty_label;
+ QIcon m_clean_icon;
+};
+
+QUndoModel::QUndoModel(QObject *parent)
+ : QAbstractItemModel(parent)
+{
+ m_stack = 0;
+ m_sel_model = new QItemSelectionModel(this, this);
+ connect(m_sel_model, SIGNAL(currentChanged(QModelIndex,QModelIndex)),
+ this, SLOT(setStackCurrentIndex(QModelIndex)));
+ m_emty_label = tr("<empty>");
+}
+
+QItemSelectionModel *QUndoModel::selectionModel() const
+{
+ return m_sel_model;
+}
+
+QUndoStack *QUndoModel::stack() const
+{
+ return m_stack;
+}
+
+void QUndoModel::setStack(QUndoStack *stack)
+{
+ if (m_stack == stack)
+ return;
+
+ if (m_stack != 0) {
+ disconnect(m_stack, SIGNAL(cleanChanged(bool)), this, SLOT(stackChanged()));
+ disconnect(m_stack, SIGNAL(indexChanged(int)), this, SLOT(stackChanged()));
+ disconnect(m_stack, SIGNAL(destroyed(QObject*)), this, SLOT(stackDestroyed(QObject*)));
+ }
+ m_stack = stack;
+ if (m_stack != 0) {
+ connect(m_stack, SIGNAL(cleanChanged(bool)), this, SLOT(stackChanged()));
+ connect(m_stack, SIGNAL(indexChanged(int)), this, SLOT(stackChanged()));
+ connect(m_stack, SIGNAL(destroyed(QObject*)), this, SLOT(stackDestroyed(QObject*)));
+ }
+
+ stackChanged();
+}
+
+void QUndoModel::stackDestroyed(QObject *obj)
+{
+ if (obj != m_stack)
+ return;
+ m_stack = 0;
+
+ stackChanged();
+}
+
+void QUndoModel::stackChanged()
+{
+ reset();
+ m_sel_model->setCurrentIndex(selectedIndex(), QItemSelectionModel::ClearAndSelect);
+}
+
+void QUndoModel::setStackCurrentIndex(const QModelIndex &index)
+{
+ if (m_stack == 0)
+ return;
+
+ if (index == selectedIndex())
+ return;
+
+ if (index.column() != 0)
+ return;
+
+ m_stack->setIndex(index.row());
+}
+
+QModelIndex QUndoModel::selectedIndex() const
+{
+ return m_stack == 0 ? QModelIndex() : createIndex(m_stack->index(), 0);
+}
+
+QModelIndex QUndoModel::index(int row, int column, const QModelIndex &parent) const
+{
+ if (m_stack == 0)
+ return QModelIndex();
+
+ if (parent.isValid())
+ return QModelIndex();
+
+ if (column != 0)
+ return QModelIndex();
+
+ if (row < 0 || row > m_stack->count())
+ return QModelIndex();
+
+ return createIndex(row, column);
+}
+
+QModelIndex QUndoModel::parent(const QModelIndex&) const
+{
+ return QModelIndex();
+}
+
+int QUndoModel::rowCount(const QModelIndex &parent) const
+{
+ if (m_stack == 0)
+ return 0;
+
+ if (parent.isValid())
+ return 0;
+
+ return m_stack->count() + 1;
+}
+
+int QUndoModel::columnCount(const QModelIndex&) const
+{
+ return 1;
+}
+
+QVariant QUndoModel::data(const QModelIndex &index, int role) const
+{
+ if (m_stack == 0)
+ return QVariant();
+
+ if (index.column() != 0)
+ return QVariant();
+
+ if (index.row() < 0 || index.row() > m_stack->count())
+ return QVariant();
+
+ if (role == Qt::DisplayRole) {
+ if (index.row() == 0)
+ return m_emty_label;
+ return m_stack->text(index.row() - 1);
+ } else if (role == Qt::DecorationRole) {
+ if (index.row() == m_stack->cleanIndex() && !m_clean_icon.isNull())
+ return m_clean_icon;
+ return QVariant();
+ }
+
+ return QVariant();
+}
+
+QString QUndoModel::emptyLabel() const
+{
+ return m_emty_label;
+}
+
+void QUndoModel::setEmptyLabel(const QString &label)
+{
+ m_emty_label = label;
+ stackChanged();
+}
+
+void QUndoModel::setCleanIcon(const QIcon &icon)
+{
+ m_clean_icon = icon;
+ stackChanged();
+}
+
+QIcon QUndoModel::cleanIcon() const
+{
+ return m_clean_icon;
+}
+
+/*!
+ \class QUndoView
+ \brief The QUndoView class displays the contents of a QUndoStack.
+ \since 4.2
+
+ \ingroup advanced
+
+ QUndoView is a QListView which displays the list of commands pushed on an undo stack.
+ The most recently executed command is always selected. Selecting a different command
+ results in a call to QUndoStack::setIndex(), rolling the state of the document
+ backwards or forward to the new command.
+
+ The stack can be set explicitly with setStack(). Alternatively, a QUndoGroup object can
+ be set with setGroup(). The view will then update itself automatically whenever the
+ active stack of the group changes.
+
+ \image qundoview.png
+*/
+
+class QUndoViewPrivate : public QListViewPrivate
+{
+ Q_DECLARE_PUBLIC(QUndoView)
+public:
+ QUndoViewPrivate() :
+#ifndef QT_NO_UNDOGROUP
+ group(0),
+#endif
+ model(0) {}
+
+#ifndef QT_NO_UNDOGROUP
+ QPointer<QUndoGroup> group;
+#endif
+ QUndoModel *model;
+
+ void init();
+};
+
+void QUndoViewPrivate::init()
+{
+ Q_Q(QUndoView);
+
+ model = new QUndoModel(q);
+ q->setModel(model);
+ q->setSelectionModel(model->selectionModel());
+}
+
+/*!
+ Constructs a new view with parent \a parent.
+*/
+
+QUndoView::QUndoView(QWidget *parent)
+ : QListView(*new QUndoViewPrivate(), parent)
+{
+ Q_D(QUndoView);
+ d->init();
+}
+
+/*!
+ Constructs a new view with parent \a parent and sets the observed stack to \a stack.
+*/
+
+QUndoView::QUndoView(QUndoStack *stack, QWidget *parent)
+ : QListView(*new QUndoViewPrivate(), parent)
+{
+ Q_D(QUndoView);
+ d->init();
+ setStack(stack);
+}
+
+#ifndef QT_NO_UNDOGROUP
+
+/*!
+ Constructs a new view with parent \a parent and sets the observed group to \a group.
+
+ The view will update itself autmiatically whenever the active stack of the group changes.
+*/
+
+QUndoView::QUndoView(QUndoGroup *group, QWidget *parent)
+ : QListView(*new QUndoViewPrivate(), parent)
+{
+ Q_D(QUndoView);
+ d->init();
+ setGroup(group);
+}
+
+#endif // QT_NO_UNDOGROUP
+
+/*!
+ Destroys this view.
+*/
+
+QUndoView::~QUndoView()
+{
+}
+
+/*!
+ Returns the stack currently displayed by this view. If the view is looking at a
+ QUndoGroup, this the group's active stack.
+
+ \sa setStack() setGroup()
+*/
+
+QUndoStack *QUndoView::stack() const
+{
+ Q_D(const QUndoView);
+ return d->model->stack();
+}
+
+/*!
+ Sets the stack displayed by this view to \a stack. If \a stack is 0, the view
+ will be empty.
+
+ If the view was previously looking at a QUndoGroup, the group is set to 0.
+
+ \sa stack() setGroup()
+*/
+
+void QUndoView::setStack(QUndoStack *stack)
+{
+ Q_D(QUndoView);
+#ifndef QT_NO_UNDOGROUP
+ setGroup(0);
+#endif
+ d->model->setStack(stack);
+}
+
+#ifndef QT_NO_UNDOGROUP
+
+/*!
+ Sets the group displayed by this view to \a group. If \a group is 0, the view will
+ be empty.
+
+ The view will update itself autmiatically whenever the active stack of the group changes.
+
+ \sa group() setStack()
+*/
+
+void QUndoView::setGroup(QUndoGroup *group)
+{
+ Q_D(QUndoView);
+
+ if (d->group == group)
+ return;
+
+ if (d->group != 0) {
+ disconnect(d->group, SIGNAL(activeStackChanged(QUndoStack*)),
+ d->model, SLOT(setStack(QUndoStack*)));
+ }
+
+ d->group = group;
+
+ if (d->group != 0) {
+ connect(d->group, SIGNAL(activeStackChanged(QUndoStack*)),
+ d->model, SLOT(setStack(QUndoStack*)));
+ d->model->setStack(d->group->activeStack());
+ } else {
+ d->model->setStack(0);
+ }
+}
+
+/*!
+ Returns the group displayed by this view.
+
+ If the view is not looking at group, this function returns 0.
+
+ \sa setGroup() setStack()
+*/
+
+QUndoGroup *QUndoView::group() const
+{
+ Q_D(const QUndoView);
+ return d->group;
+}
+
+#endif // QT_NO_UNDOGROUP
+
+/*!
+ \property QUndoView::emptyLabel
+ \brief the label used for the empty state.
+
+ The empty label is the topmost element in the list of commands, which represents
+ the state of the document before any commands were pushed on the stack. The default
+ is the string "<empty>".
+*/
+
+void QUndoView::setEmptyLabel(const QString &label)
+{
+ Q_D(QUndoView);
+ d->model->setEmptyLabel(label);
+}
+
+QString QUndoView::emptyLabel() const
+{
+ Q_D(const QUndoView);
+ return d->model->emptyLabel();
+}
+
+/*!
+ \property QUndoView::cleanIcon
+ \brief the icon used to represent the clean state.
+
+ A stack may have a clean state set with QUndoStack::setClean(). This is usually
+ the state of the document at the point it was saved. QUndoView can display an
+ icon in the list of commands to show the clean state. If this property is
+ a null icon, no icon is shown. The default value is the null icon.
+*/
+
+void QUndoView::setCleanIcon(const QIcon &icon)
+{
+ Q_D(const QUndoView);
+ d->model->setCleanIcon(icon);
+
+}
+
+QIcon QUndoView::cleanIcon() const
+{
+ Q_D(const QUndoView);
+ return d->model->cleanIcon();
+}
+
+QT_END_NAMESPACE
+
+#include "qundoview.moc"
+
+#endif // QT_NO_UNDOVIEW
diff --git a/src/widgets/util/qundoview.h b/src/widgets/util/qundoview.h
new file mode 100644
index 0000000000..9df2995f9d
--- /dev/null
+++ b/src/widgets/util/qundoview.h
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QUNDOVIEW_H
+#define QUNDOVIEW_H
+
+#include <QtWidgets/qlistview.h>
+#include <QtCore/qstring.h>
+
+#ifndef QT_NO_UNDOVIEW
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QUndoViewPrivate;
+class QUndoStack;
+class QUndoGroup;
+class QIcon;
+
+QT_MODULE(Gui)
+
+class Q_WIDGETS_EXPORT QUndoView : public QListView
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QUndoView)
+ Q_PROPERTY(QString emptyLabel READ emptyLabel WRITE setEmptyLabel)
+ Q_PROPERTY(QIcon cleanIcon READ cleanIcon WRITE setCleanIcon)
+
+public:
+ explicit QUndoView(QWidget *parent = 0);
+ explicit QUndoView(QUndoStack *stack, QWidget *parent = 0);
+#ifndef QT_NO_UNDOGROUP
+ explicit QUndoView(QUndoGroup *group, QWidget *parent = 0);
+#endif
+ ~QUndoView();
+
+ QUndoStack *stack() const;
+#ifndef QT_NO_UNDOGROUP
+ QUndoGroup *group() const;
+#endif
+
+ void setEmptyLabel(const QString &label);
+ QString emptyLabel() const;
+
+ void setCleanIcon(const QIcon &icon);
+ QIcon cleanIcon() const;
+
+public Q_SLOTS:
+ void setStack(QUndoStack *stack);
+#ifndef QT_NO_UNDOGROUP
+ void setGroup(QUndoGroup *group);
+#endif
+
+private:
+ Q_DISABLE_COPY(QUndoView)
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QT_NO_UNDOVIEW
+#endif // QUNDOVIEW_H
diff --git a/src/widgets/util/util.pri b/src/widgets/util/util.pri
new file mode 100644
index 0000000000..2eec946338
--- /dev/null
+++ b/src/widgets/util/util.pri
@@ -0,0 +1,71 @@
+# Qt util module
+
+HEADERS += \
+ util/qsystemtrayicon.h \
+ util/qcolormap.h \
+ util/qcompleter.h \
+ util/qcompleter_p.h \
+ util/qsystemtrayicon_p.h \
+ util/qscroller.h \
+ util/qscroller_p.h \
+ util/qscrollerproperties.h \
+ util/qscrollerproperties_p.h \
+ util/qflickgesture_p.h \
+ util/qundogroup.h \
+ util/qundostack.h \
+ util/qundostack_p.h \
+ util/qundoview.h
+
+SOURCES += \
+ util/qsystemtrayicon.cpp \
+ util/qcolormap_qpa.cpp \
+ util/qcompleter.cpp \
+ util/qscroller.cpp \
+ util/qscrollerproperties.cpp \
+ util/qflickgesture.cpp \
+ util/qundogroup.cpp \
+ util/qundostack.cpp \
+ util/qundoview.cpp
+
+
+wince* {
+ SOURCES += \
+ util/qsystemtrayicon_wince.cpp
+} else:win32:!qpa {
+ SOURCES += \
+ util/qsystemtrayicon_win.cpp
+}
+
+unix:x11 {
+ SOURCES += \
+ util/qsystemtrayicon_x11.cpp
+}
+
+qpa {
+ SOURCES += \
+ util/qsystemtrayicon_qpa.cpp
+}
+
+!qpa:!x11:mac {
+ OBJECTIVE_SOURCES += util/qsystemtrayicon_mac.mm
+}
+
+symbian {
+ LIBS += -letext -lplatformenv
+ contains(S60_VERSION, 3.1)|contains(S60_VERSION, 3.2)|contains(S60_VERSION, 5.0) {
+ LIBS += -lsendas2 -lapmime
+ contains(QT_CONFIG, s60) {
+ contains(CONFIG, is_using_gnupoc) {
+ LIBS += -lcommonui
+ } else {
+ LIBS += -lCommonUI
+ }
+ }
+ } else {
+ DEFINES += USE_SCHEMEHANDLER
+ }
+}
+
+macx {
+ OBJECTIVE_SOURCES += util/qscroller_mac.mm
+}
diff --git a/src/widgets/widgets.pro b/src/widgets/widgets.pro
new file mode 100644
index 0000000000..bff487bf3f
--- /dev/null
+++ b/src/widgets/widgets.pro
@@ -0,0 +1,227 @@
+load(qt_module)
+
+TARGET = QtWidgets
+QPRO_PWD = $$PWD
+QT = core core-private gui gui-private
+
+CONFIG += module
+MODULE_PRI = ../modules/qt_widgets.pri
+
+DEFINES += QT_BUILD_WIDGETS_LIB QT_NO_USING_NAMESPACE
+win32-msvc*|win32-icc:QMAKE_LFLAGS += /BASE:0x65000000
+irix-cc*:QMAKE_CXXFLAGS += -no_prelink -ptused
+
+!win32:!qpa:!mac:!symbian:CONFIG += x11
+
+unix|win32-g++*:QMAKE_PKGCONFIG_REQUIRES = QtCore
+
+HEADERS += $$QT_SOURCE_TREE/src/widgets/qtwidgetsversion.h
+
+include(../qbase.pri)
+
+contains(QT_CONFIG, x11sm):CONFIG += x11sm
+
+#platforms
+x11:include(kernel/x11.pri)
+mac:include(kernel/mac.pri)
+win32:include(kernel/win.pri)
+symbian {
+ include(kernel/symbian.pri)
+ include(s60framework/s60framework.pri)
+}
+
+# to be moved into QtGui
+include(to_be_moved/to_be_moved.pri)
+
+#modules
+include(animation/animation.pri)
+include(kernel/kernel.pri)
+include(styles/styles.pri)
+include(widgets/widgets.pri)
+include(dialogs/dialogs.pri)
+include(accessible/accessible.pri)
+include(itemviews/itemviews.pri)
+include(graphicsview/graphicsview.pri)
+include(util/util.pri)
+include(statemachine/statemachine.pri)
+include(effects/effects.pri)
+
+
+QMAKE_LIBS += $$QMAKE_LIBS_GUI
+
+contains(DEFINES,QT_EVAL):include($$QT_SOURCE_TREE/src/corelib/eval.pri)
+
+QMAKE_DYNAMIC_LIST_FILE = $$PWD/QtGui.dynlist
+
+DEFINES += Q_INTERNAL_QAPP_SRC
+symbian {
+ TARGET.UID3=0x2001B2DD
+
+ # ro-section in gui can exceed default allocated space, so move rw-section a little further
+ QMAKE_LFLAGS.ARMCC += --rw-base 0x800000
+ QMAKE_LFLAGS.GCCE += -Tdata 0x800000
+}
+
+neon:*-g++* {
+ DEFINES += QT_HAVE_NEON
+ HEADERS += $$NEON_HEADERS
+
+ DRAWHELPER_NEON_ASM_FILES = $$NEON_ASM
+
+ neon_compiler.commands = $$QMAKE_CXX -c
+ neon_compiler.commands += $(CXXFLAGS) -mfpu=neon $(INCPATH) ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT}
+ neon_compiler.dependency_type = TYPE_C
+ neon_compiler.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_OBJ)}
+ neon_compiler.input = DRAWHELPER_NEON_ASM_FILES NEON_SOURCES
+ neon_compiler.variable_out = OBJECTS
+ neon_compiler.name = compiling[neon] ${QMAKE_FILE_IN}
+ silent:neon_compiler.commands = @echo compiling[neon] ${QMAKE_FILE_IN} && $$neon_compiler.commands
+ QMAKE_EXTRA_COMPILERS += neon_compiler
+}
+
+INCLUDEPATH += ../3rdparty/harfbuzz/src
+
+win32:!contains(QT_CONFIG, directwrite) {
+ DEFINES += QT_NO_DIRECTWRITE
+}
+
+contains(QMAKE_MAC_XARCH, no) {
+ DEFINES += QT_NO_MAC_XARCH
+} else {
+ win32-g++*|!win32:!win32-icc*:!macx-icc* {
+ mmx {
+ mmx_compiler.commands = $$QMAKE_CXX -c -Winline
+
+ mac {
+ mmx_compiler.commands += -Xarch_i386 -mmmx
+ mmx_compiler.commands += -Xarch_x86_64 -mmmx
+ } else {
+ mmx_compiler.commands += -mmmx
+ }
+
+ mmx_compiler.commands += $(CXXFLAGS) $(INCPATH) ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT}
+ mmx_compiler.dependency_type = TYPE_C
+ mmx_compiler.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_OBJ)}
+ mmx_compiler.input = MMX_SOURCES
+ mmx_compiler.variable_out = OBJECTS
+ mmx_compiler.name = compiling[mmx] ${QMAKE_FILE_IN}
+ silent:mmx_compiler.commands = @echo compiling[mmx] ${QMAKE_FILE_IN} && $$mmx_compiler.commands
+ QMAKE_EXTRA_COMPILERS += mmx_compiler
+ }
+ 3dnow {
+ mmx3dnow_compiler.commands = $$QMAKE_CXX -c -Winline
+
+ mac {
+ mmx3dnow_compiler.commands += -Xarch_i386 -m3dnow -Xarch_i386 -mmmx
+ mmx3dnow_compiler.commands += -Xarch_x86_64 -m3dnow -Xarch_x86_64 -mmmx
+ } else {
+ mmx3dnow_compiler.commands += -m3dnow -mmmx
+ }
+
+ mmx3dnow_compiler.commands += $(CXXFLAGS) $(INCPATH) ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT}
+ mmx3dnow_compiler.dependency_type = TYPE_C
+ mmx3dnow_compiler.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_OBJ)}
+ mmx3dnow_compiler.input = MMX3DNOW_SOURCES
+ mmx3dnow_compiler.variable_out = OBJECTS
+ mmx3dnow_compiler.name = compiling[mmx3dnow] ${QMAKE_FILE_IN}
+ silent:mmx3dnow_compiler.commands = @echo compiling[mmx3dnow] ${QMAKE_FILE_IN} && $$mmx3dnow_compiler.commands
+ QMAKE_EXTRA_COMPILERS += mmx3dnow_compiler
+ sse {
+ sse3dnow_compiler.commands = $$QMAKE_CXX -c -Winline
+
+ mac {
+ sse3dnow_compiler.commands += -Xarch_i386 -m3dnow -Xarch_i386 -msse
+ sse3dnow_compiler.commands += -Xarch_x86_64 -m3dnow -Xarch_x86_64 -msse
+ } else {
+ sse3dnow_compiler.commands += -m3dnow -msse
+ }
+
+ sse3dnow_compiler.commands += $(CXXFLAGS) $(INCPATH) ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT}
+ sse3dnow_compiler.dependency_type = TYPE_C
+ sse3dnow_compiler.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_OBJ)}
+ sse3dnow_compiler.input = SSE3DNOW_SOURCES
+ sse3dnow_compiler.variable_out = OBJECTS
+ sse3dnow_compiler.name = compiling[sse3dnow] ${QMAKE_FILE_IN}
+ silent:sse3dnow_compiler.commands = @echo compiling[sse3dnow] ${QMAKE_FILE_IN} && $$sse3dnow_compiler.commands
+ QMAKE_EXTRA_COMPILERS += sse3dnow_compiler
+ }
+ }
+ sse {
+ sse_compiler.commands = $$QMAKE_CXX -c -Winline
+
+ mac {
+ sse_compiler.commands += -Xarch_i386 -msse
+ sse_compiler.commands += -Xarch_x86_64 -msse
+ } else {
+ sse_compiler.commands += -msse
+ }
+
+ sse_compiler.commands += $(CXXFLAGS) $(INCPATH) ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT}
+ sse_compiler.dependency_type = TYPE_C
+ sse_compiler.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_OBJ)}
+ sse_compiler.input = SSE_SOURCES
+ sse_compiler.variable_out = OBJECTS
+ sse_compiler.name = compiling[sse] ${QMAKE_FILE_IN}
+ silent:sse_compiler.commands = @echo compiling[sse] ${QMAKE_FILE_IN} && $$sse_compiler.commands
+ QMAKE_EXTRA_COMPILERS += sse_compiler
+ }
+ sse2 {
+ sse2_compiler.commands = $$QMAKE_CXX -c -Winline
+
+ mac {
+ sse2_compiler.commands += -Xarch_i386 -msse2
+ sse2_compiler.commands += -Xarch_x86_64 -msse2
+ } else {
+ sse2_compiler.commands += -msse2
+ }
+
+ sse2_compiler.commands += $(CXXFLAGS) $(INCPATH) ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT}
+ sse2_compiler.dependency_type = TYPE_C
+ sse2_compiler.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_OBJ)}
+ sse2_compiler.input = SSE2_SOURCES
+ sse2_compiler.variable_out = OBJECTS
+ sse2_compiler.name = compiling[sse2] ${QMAKE_FILE_IN}
+ silent:sse2_compiler.commands = @echo compiling[sse2] ${QMAKE_FILE_IN} && $$sse2_compiler.commands
+ QMAKE_EXTRA_COMPILERS += sse2_compiler
+ }
+ ssse3 {
+ ssse3_compiler.commands = $$QMAKE_CXX -c -Winline
+
+ mac {
+ ssse3_compiler.commands += -Xarch_i386 -mssse3
+ ssse3_compiler.commands += -Xarch_x86_64 -mssse3
+ } else {
+ ssse3_compiler.commands += -mssse3
+ }
+
+ ssse3_compiler.commands += $(CXXFLAGS) $(INCPATH) ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT}
+ ssse3_compiler.dependency_type = TYPE_C
+ ssse3_compiler.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_OBJ)}
+ ssse3_compiler.input = SSSE3_SOURCES
+ ssse3_compiler.variable_out = OBJECTS
+ ssse3_compiler.name = compiling[ssse3] ${QMAKE_FILE_IN}
+ silent:ssse3_compiler.commands = @echo compiling[ssse3] ${QMAKE_FILE_IN} && $$ssse3_compiler.commands
+ QMAKE_EXTRA_COMPILERS += ssse3_compiler
+ }
+ iwmmxt {
+ iwmmxt_compiler.commands = $$QMAKE_CXX -c -Winline
+ iwmmxt_compiler.commands += -mcpu=iwmmxt
+ iwmmxt_compiler.commands += $(CXXFLAGS) $(INCPATH) ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT}
+ iwmmxt_compiler.dependency_type = TYPE_C
+ iwmmxt_compiler.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_OBJ)}
+ iwmmxt_compiler.input = IWMMXT_SOURCES
+ iwmmxt_compiler.variable_out = OBJECTS
+ iwmmxt_compiler.name = compiling[iwmmxt] ${QMAKE_FILE_IN}
+ silent:iwmmxt_compiler.commands = @echo compiling[iwmmxt] ${QMAKE_FILE_IN} && $$iwmmxt_compiler.commands
+ QMAKE_EXTRA_COMPILERS += iwmmxt_compiler
+ }
+ } else {
+ mmx: SOURCES += $$MMX_SOURCES
+ 3dnow: SOURCES += $$MMX3DNOW_SOURCES
+ 3dnow:sse: SOURCES += $$SSE3DNOW_SOURCES
+ sse: SOURCES += $$SSE_SOURCES
+ sse2: SOURCES += $$SSE2_SOURCES
+ ssse3: SOURCES += $$SSSE3_SOURCES
+ iwmmxt: SOURCES += $$IWMMXT_SOURCES
+ }
+}
diff --git a/src/widgets/widgets/qabstractbutton.cpp b/src/widgets/widgets/qabstractbutton.cpp
new file mode 100644
index 0000000000..d777cc7567
--- /dev/null
+++ b/src/widgets/widgets/qabstractbutton.cpp
@@ -0,0 +1,1470 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qabstractbutton.h"
+#include "qabstractitemview.h"
+#include "qbuttongroup.h"
+#include "qabstractbutton_p.h"
+#include "qevent.h"
+#include "qpainter.h"
+#include "qapplication.h"
+#include "qstyle.h"
+#include "qaction.h"
+#ifndef QT_NO_ACCESSIBILITY
+#include "qaccessible.h"
+#endif
+
+QT_BEGIN_NAMESPACE
+
+#define AUTO_REPEAT_DELAY 300
+#define AUTO_REPEAT_INTERVAL 100
+
+Q_WIDGETS_EXPORT extern bool qt_tab_all_widgets;
+
+/*!
+ \class QAbstractButton
+
+ \brief The QAbstractButton class is the abstract base class of
+ button widgets, providing functionality common to buttons.
+
+ \ingroup abstractwidgets
+
+ This class implements an \e abstract button.
+ Subclasses of this class handle user actions, and specify how the button
+ is drawn.
+
+ QAbstractButton provides support for both push buttons and checkable
+ (toggle) buttons. Checkable buttons are implemented in the QRadioButton
+ and QCheckBox classes. Push buttons are implemented in the
+ QPushButton and QToolButton classes; these also provide toggle
+ behavior if required.
+
+ Any button can display a label containing text and an icon. setText()
+ sets the text; setIcon() sets the icon. If a button is disabled, its label
+ is changed to give the button a "disabled" appearance.
+
+ If the button is a text button with a string containing an
+ ampersand ('&'), QAbstractButton automatically creates a shortcut
+ key. For example:
+
+ \snippet doc/src/snippets/code/src_gui_widgets_qabstractbutton.cpp 0
+
+ The \key Alt+C shortcut is assigned to the button, i.e., when the
+ user presses \key Alt+C the button will call animateClick(). See
+ the \l {QShortcut#mnemonic}{QShortcut} documentation for details
+ (to display an actual ampersand, use '&&').
+
+ You can also set a custom shortcut key using the setShortcut()
+ function. This is useful mostly for buttons that do not have any
+ text, because they have no automatic shortcut.
+
+ \snippet doc/src/snippets/code/src_gui_widgets_qabstractbutton.cpp 1
+
+ All of the buttons provided by Qt (QPushButton, QToolButton,
+ QCheckBox, and QRadioButton) can display both \l text and \l{icon}{icons}.
+
+ A button can be made the default button in a dialog are provided by
+ QPushButton::setDefault() and QPushButton::setAutoDefault().
+
+ QAbstractButton provides most of the states used for buttons:
+
+ \list
+
+ \o isDown() indicates whether the button is \e pressed down.
+
+ \o isChecked() indicates whether the button is \e checked. Only
+ checkable buttons can be checked and unchecked (see below).
+
+ \o isEnabled() indicates whether the button can be pressed by the
+ user.
+
+ \o setAutoRepeat() sets whether the button will auto-repeat if the
+ user holds it down. \l autoRepeatDelay and \l autoRepeatInterval
+ define how auto-repetition is done.
+
+ \o setCheckable() sets whether the button is a toggle button or not.
+
+ \endlist
+
+ The difference between isDown() and isChecked() is as follows.
+ When the user clicks a toggle button to check it, the button is first
+ \e pressed then released into the \e checked state. When the user
+ clicks it again (to uncheck it), the button moves first to the
+ \e pressed state, then to the \e unchecked state (isChecked() and
+ isDown() are both false).
+
+ QAbstractButton provides four signals:
+
+ \list 1
+
+ \o pressed() is emitted when the left mouse button is pressed while
+ the mouse cursor is inside the button.
+
+ \o released() is emitted when the left mouse button is released.
+
+ \o clicked() is emitted when the button is first pressed and then
+ released, when the shortcut key is typed, or when click() or
+ animateClick() is called.
+
+ \o toggled() is emitted when the state of a toggle button changes.
+
+ \endlist
+
+ To subclass QAbstractButton, you must reimplement at least
+ paintEvent() to draw the button's outline and its text or pixmap. It
+ is generally advisable to reimplement sizeHint() as well, and
+ sometimes hitButton() (to determine whether a button press is within
+ the button). For buttons with more than two states (like tri-state
+ buttons), you will also have to reimplement checkStateSet() and
+ nextCheckState().
+
+ \sa QButtonGroup
+*/
+
+QAbstractButtonPrivate::QAbstractButtonPrivate(QSizePolicy::ControlType type)
+ :
+#ifndef QT_NO_SHORTCUT
+ shortcutId(0),
+#endif
+ checkable(false), checked(false), autoRepeat(false), autoExclusive(false),
+ down(false), blockRefresh(false), pressed(false),
+#ifndef QT_NO_BUTTONGROUP
+ group(0),
+#endif
+ autoRepeatDelay(AUTO_REPEAT_DELAY),
+ autoRepeatInterval(AUTO_REPEAT_INTERVAL),
+ controlType(type)
+{}
+
+#ifndef QT_NO_BUTTONGROUP
+
+class QButtonGroupPrivate: public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QButtonGroup)
+
+public:
+ QButtonGroupPrivate():exclusive(true){}
+ QList<QAbstractButton *> buttonList;
+ QPointer<QAbstractButton> checkedButton;
+ void detectCheckedButton();
+ void notifyChecked(QAbstractButton *button);
+ bool exclusive;
+ QMap<QAbstractButton*, int> mapping;
+};
+
+QButtonGroup::QButtonGroup(QObject *parent)
+ : QObject(*new QButtonGroupPrivate, parent)
+{
+}
+
+QButtonGroup::~QButtonGroup()
+{
+ Q_D(QButtonGroup);
+ for (int i = 0; i < d->buttonList.count(); ++i)
+ d->buttonList.at(i)->d_func()->group = 0;
+}
+
+
+bool QButtonGroup::exclusive() const
+{
+ Q_D(const QButtonGroup);
+ return d->exclusive;
+}
+
+void QButtonGroup::setExclusive(bool exclusive)
+{
+ Q_D(QButtonGroup);
+ d->exclusive = exclusive;
+}
+
+
+// TODO: Qt 5: Merge with addButton(QAbstractButton *button, int id)
+void QButtonGroup::addButton(QAbstractButton *button)
+{
+ addButton(button, -1);
+}
+
+void QButtonGroup::addButton(QAbstractButton *button, int id)
+{
+ Q_D(QButtonGroup);
+ if (QButtonGroup *previous = button->d_func()->group)
+ previous->removeButton(button);
+ button->d_func()->group = this;
+ d->buttonList.append(button);
+ if (id == -1) {
+ QList<int> ids = d->mapping.values();
+ if (ids.isEmpty())
+ d->mapping[button] = -2;
+ else {
+ qSort(ids);
+ d->mapping[button] = ids.first()-1;
+ }
+ } else {
+ d->mapping[button] = id;
+ }
+
+ if (d->exclusive && button->isChecked())
+ button->d_func()->notifyChecked();
+}
+
+void QButtonGroup::removeButton(QAbstractButton *button)
+{
+ Q_D(QButtonGroup);
+ if (d->checkedButton == button) {
+ d->detectCheckedButton();
+ }
+ if (button->d_func()->group == this) {
+ button->d_func()->group = 0;
+ d->buttonList.removeAll(button);
+ d->mapping.remove(button);
+ }
+}
+
+QList<QAbstractButton*> QButtonGroup::buttons() const
+{
+ Q_D(const QButtonGroup);
+ return d->buttonList;
+}
+
+QAbstractButton *QButtonGroup::checkedButton() const
+{
+ Q_D(const QButtonGroup);
+ return d->checkedButton;
+}
+
+QAbstractButton *QButtonGroup::button(int id) const
+{
+ Q_D(const QButtonGroup);
+ return d->mapping.key(id);
+}
+
+void QButtonGroup::setId(QAbstractButton *button, int id)
+{
+ Q_D(QButtonGroup);
+ if (button && id != -1)
+ d->mapping[button] = id;
+}
+
+int QButtonGroup::id(QAbstractButton *button) const
+{
+ Q_D(const QButtonGroup);
+ return d->mapping.value(button, -1);
+}
+
+int QButtonGroup::checkedId() const
+{
+ Q_D(const QButtonGroup);
+ return d->mapping.value(d->checkedButton, -1);
+}
+
+// detect a checked button other than the current one
+void QButtonGroupPrivate::detectCheckedButton()
+{
+ QAbstractButton *previous = checkedButton;
+ checkedButton = 0;
+ if (exclusive)
+ return;
+ for (int i = 0; i < buttonList.count(); i++) {
+ if (buttonList.at(i) != previous && buttonList.at(i)->isChecked()) {
+ checkedButton = buttonList.at(i);
+ return;
+ }
+ }
+}
+
+#endif // QT_NO_BUTTONGROUP
+
+QList<QAbstractButton *>QAbstractButtonPrivate::queryButtonList() const
+{
+#ifndef QT_NO_BUTTONGROUP
+ if (group)
+ return group->d_func()->buttonList;
+#endif
+
+ QList<QAbstractButton*>candidates = parent->findChildren<QAbstractButton *>();
+ if (autoExclusive) {
+ for (int i = candidates.count() - 1; i >= 0; --i) {
+ QAbstractButton *candidate = candidates.at(i);
+ if (!candidate->autoExclusive()
+#ifndef QT_NO_BUTTONGROUP
+ || candidate->group()
+#endif
+ )
+ candidates.removeAt(i);
+ }
+ }
+ return candidates;
+}
+
+QAbstractButton *QAbstractButtonPrivate::queryCheckedButton() const
+{
+#ifndef QT_NO_BUTTONGROUP
+ if (group)
+ return group->d_func()->checkedButton;
+#endif
+
+ Q_Q(const QAbstractButton);
+ QList<QAbstractButton *> buttonList = queryButtonList();
+ if (!autoExclusive || buttonList.count() == 1) // no group
+ return 0;
+
+ for (int i = 0; i < buttonList.count(); ++i) {
+ QAbstractButton *b = buttonList.at(i);
+ if (b->d_func()->checked && b != q)
+ return b;
+ }
+ return checked ? const_cast<QAbstractButton *>(q) : 0;
+}
+
+void QAbstractButtonPrivate::notifyChecked()
+{
+#ifndef QT_NO_BUTTONGROUP
+ Q_Q(QAbstractButton);
+ if (group) {
+ QAbstractButton *previous = group->d_func()->checkedButton;
+ group->d_func()->checkedButton = q;
+ if (group->d_func()->exclusive && previous && previous != q)
+ previous->nextCheckState();
+ } else
+#endif
+ if (autoExclusive) {
+ if (QAbstractButton *b = queryCheckedButton())
+ b->setChecked(false);
+ }
+}
+
+void QAbstractButtonPrivate::moveFocus(int key)
+{
+ QList<QAbstractButton *> buttonList = queryButtonList();;
+#ifndef QT_NO_BUTTONGROUP
+ bool exclusive = group ? group->d_func()->exclusive : autoExclusive;
+#else
+ bool exclusive = autoExclusive;
+#endif
+ QWidget *f = QApplication::focusWidget();
+ QAbstractButton *fb = qobject_cast<QAbstractButton *>(f);
+ if (!fb || !buttonList.contains(fb))
+ return;
+
+ QAbstractButton *candidate = 0;
+ int bestScore = -1;
+ QRect target = f->rect().translated(f->mapToGlobal(QPoint(0,0)));
+ QPoint goal = target.center();
+ uint focus_flag = qt_tab_all_widgets ? Qt::TabFocus : Qt::StrongFocus;
+
+ for (int i = 0; i < buttonList.count(); ++i) {
+ QAbstractButton *button = buttonList.at(i);
+ if (button != f && button->window() == f->window() && button->isEnabled() && !button->isHidden() &&
+ (autoExclusive || (button->focusPolicy() & focus_flag) == focus_flag)) {
+ QRect buttonRect = button->rect().translated(button->mapToGlobal(QPoint(0,0)));
+ QPoint p = buttonRect.center();
+
+ //Priority to widgets that overlap on the same coordinate.
+ //In that case, the distance in the direction will be used as significant score,
+ //take also in account orthogonal distance in case two widget are in the same distance.
+ int score;
+ if ((buttonRect.x() < target.right() && target.x() < buttonRect.right())
+ && (key == Qt::Key_Up || key == Qt::Key_Down)) {
+ //one item's is at the vertical of the other
+ score = (qAbs(p.y() - goal.y()) << 16) + qAbs(p.x() - goal.x());
+ } else if ((buttonRect.y() < target.bottom() && target.y() < buttonRect.bottom())
+ && (key == Qt::Key_Left || key == Qt::Key_Right) ) {
+ //one item's is at the horizontal of the other
+ score = (qAbs(p.x() - goal.x()) << 16) + qAbs(p.y() - goal.y());
+ } else {
+ score = (1 << 30) + (p.y() - goal.y()) * (p.y() - goal.y()) + (p.x() - goal.x()) * (p.x() - goal.x());
+ }
+
+ if (score > bestScore && candidate)
+ continue;
+
+ switch(key) {
+ case Qt::Key_Up:
+ if (p.y() < goal.y()) {
+ candidate = button;
+ bestScore = score;
+ }
+ break;
+ case Qt::Key_Down:
+ if (p.y() > goal.y()) {
+ candidate = button;
+ bestScore = score;
+ }
+ break;
+ case Qt::Key_Left:
+ if (p.x() < goal.x()) {
+ candidate = button;
+ bestScore = score;
+ }
+ break;
+ case Qt::Key_Right:
+ if (p.x() > goal.x()) {
+ candidate = button;
+ bestScore = score;
+ }
+ break;
+ }
+ }
+ }
+
+ if (exclusive
+#ifdef QT_KEYPAD_NAVIGATION
+ && !QApplication::keypadNavigationEnabled()
+#endif
+ && candidate
+ && fb->d_func()->checked
+ && candidate->d_func()->checkable)
+ candidate->click();
+
+ if (candidate) {
+ if (key == Qt::Key_Up || key == Qt::Key_Left)
+ candidate->setFocus(Qt::BacktabFocusReason);
+ else
+ candidate->setFocus(Qt::TabFocusReason);
+ }
+}
+
+void QAbstractButtonPrivate::fixFocusPolicy()
+{
+ Q_Q(QAbstractButton);
+#ifndef QT_NO_BUTTONGROUP
+ if (!group && !autoExclusive)
+#else
+ if (!autoExclusive)
+#endif
+ return;
+
+ QList<QAbstractButton *> buttonList = queryButtonList();
+ for (int i = 0; i < buttonList.count(); ++i) {
+ QAbstractButton *b = buttonList.at(i);
+ if (!b->isCheckable())
+ continue;
+ b->setFocusPolicy((Qt::FocusPolicy) ((b == q || !q->isCheckable())
+ ? (b->focusPolicy() | Qt::TabFocus)
+ : (b->focusPolicy() & ~Qt::TabFocus)));
+ }
+}
+
+void QAbstractButtonPrivate::init()
+{
+ Q_Q(QAbstractButton);
+
+ q->setFocusPolicy(Qt::FocusPolicy(q->style()->styleHint(QStyle::SH_Button_FocusPolicy)));
+ q->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed, controlType));
+ q->setAttribute(Qt::WA_WState_OwnSizePolicy, false);
+ q->setForegroundRole(QPalette::ButtonText);
+ q->setBackgroundRole(QPalette::Button);
+}
+
+void QAbstractButtonPrivate::refresh()
+{
+ Q_Q(QAbstractButton);
+
+ if (blockRefresh)
+ return;
+ q->update();
+#ifndef QT_NO_ACCESSIBILITY
+ QAccessible::updateAccessibility(q, 0, QAccessible::StateChanged);
+#endif
+}
+
+void QAbstractButtonPrivate::click()
+{
+ Q_Q(QAbstractButton);
+
+ down = false;
+ blockRefresh = true;
+ bool changeState = true;
+ if (checked && queryCheckedButton() == q) {
+ // the checked button of an exclusive or autoexclusive group cannot be unchecked
+#ifndef QT_NO_BUTTONGROUP
+ if (group ? group->d_func()->exclusive : autoExclusive)
+#else
+ if (autoExclusive)
+#endif
+ changeState = false;
+ }
+
+ QPointer<QAbstractButton> guard(q);
+ if (changeState) {
+ q->nextCheckState();
+ if (!guard)
+ return;
+ }
+ blockRefresh = false;
+ refresh();
+ q->repaint(); //flush paint event before invoking potentially expensive operation
+ QApplication::flush();
+ if (guard)
+ emitReleased();
+ if (guard)
+ emitClicked();
+}
+
+void QAbstractButtonPrivate::emitClicked()
+{
+ Q_Q(QAbstractButton);
+ QPointer<QAbstractButton> guard(q);
+ emit q->clicked(checked);
+#ifndef QT_NO_BUTTONGROUP
+ if (guard && group) {
+ emit group->buttonClicked(group->id(q));
+ if (guard && group)
+ emit group->buttonClicked(q);
+ }
+#endif
+}
+
+void QAbstractButtonPrivate::emitPressed()
+{
+ Q_Q(QAbstractButton);
+ QPointer<QAbstractButton> guard(q);
+ emit q->pressed();
+#ifndef QT_NO_BUTTONGROUP
+ if (guard && group) {
+ emit group->buttonPressed(group->id(q));
+ if (guard && group)
+ emit group->buttonPressed(q);
+ }
+#endif
+}
+
+void QAbstractButtonPrivate::emitReleased()
+{
+ Q_Q(QAbstractButton);
+ QPointer<QAbstractButton> guard(q);
+ emit q->released();
+#ifndef QT_NO_BUTTONGROUP
+ if (guard && group) {
+ emit group->buttonReleased(group->id(q));
+ if (guard && group)
+ emit group->buttonReleased(q);
+ }
+#endif
+}
+
+/*!
+ Constructs an abstract button with a \a parent.
+*/
+QAbstractButton::QAbstractButton(QWidget *parent)
+ : QWidget(*new QAbstractButtonPrivate, parent, 0)
+{
+ Q_D(QAbstractButton);
+ d->init();
+}
+
+/*!
+ Destroys the button.
+ */
+ QAbstractButton::~QAbstractButton()
+{
+#ifndef QT_NO_BUTTONGROUP
+ Q_D(QAbstractButton);
+ if (d->group)
+ d->group->removeButton(this);
+#endif
+}
+
+
+/*! \internal
+ */
+QAbstractButton::QAbstractButton(QAbstractButtonPrivate &dd, QWidget *parent)
+ : QWidget(dd, parent, 0)
+{
+ Q_D(QAbstractButton);
+ d->init();
+}
+
+/*!
+\property QAbstractButton::text
+\brief the text shown on the button
+
+If the button has no text, the text() function will return a an empty
+string.
+
+If the text contains an ampersand character ('&'), a shortcut is
+automatically created for it. The character that follows the '&' will
+be used as the shortcut key. Any previous shortcut will be
+overwritten, or cleared if no shortcut is defined by the text. See the
+\l {QShortcut#mnemonic}{QShortcut} documentation for details (to
+display an actual ampersand, use '&&').
+
+There is no default text.
+*/
+
+void QAbstractButton::setText(const QString &text)
+{
+ Q_D(QAbstractButton);
+ if (d->text == text)
+ return;
+ d->text = text;
+#ifndef QT_NO_SHORTCUT
+ QKeySequence newMnemonic = QKeySequence::mnemonic(text);
+ setShortcut(newMnemonic);
+#endif
+ d->sizeHint = QSize();
+ update();
+ updateGeometry();
+#ifndef QT_NO_ACCESSIBILITY
+ QAccessible::updateAccessibility(this, 0, QAccessible::NameChanged);
+#endif
+}
+
+QString QAbstractButton::text() const
+{
+ Q_D(const QAbstractButton);
+ return d->text;
+}
+
+
+/*!
+ \property QAbstractButton::icon
+ \brief the icon shown on the button
+
+ The icon's default size is defined by the GUI style, but can be
+ adjusted by setting the \l iconSize property.
+*/
+void QAbstractButton::setIcon(const QIcon &icon)
+{
+ Q_D(QAbstractButton);
+ d->icon = icon;
+ d->sizeHint = QSize();
+ update();
+ updateGeometry();
+}
+
+QIcon QAbstractButton::icon() const
+{
+ Q_D(const QAbstractButton);
+ return d->icon;
+}
+
+#ifndef QT_NO_SHORTCUT
+/*!
+\property QAbstractButton::shortcut
+\brief the mnemonic associated with the button
+*/
+
+void QAbstractButton::setShortcut(const QKeySequence &key)
+{
+ Q_D(QAbstractButton);
+ if (d->shortcutId != 0)
+ releaseShortcut(d->shortcutId);
+ d->shortcut = key;
+ d->shortcutId = grabShortcut(key);
+}
+
+QKeySequence QAbstractButton::shortcut() const
+{
+ Q_D(const QAbstractButton);
+ return d->shortcut;
+}
+#endif // QT_NO_SHORTCUT
+
+/*!
+\property QAbstractButton::checkable
+\brief whether the button is checkable
+
+By default, the button is not checkable.
+
+\sa checked
+*/
+void QAbstractButton::setCheckable(bool checkable)
+{
+ Q_D(QAbstractButton);
+ if (d->checkable == checkable)
+ return;
+
+ d->checkable = checkable;
+ d->checked = false;
+}
+
+bool QAbstractButton::isCheckable() const
+{
+ Q_D(const QAbstractButton);
+ return d->checkable;
+}
+
+/*!
+\property QAbstractButton::checked
+\brief whether the button is checked
+
+Only checkable buttons can be checked. By default, the button is unchecked.
+
+\sa checkable
+*/
+void QAbstractButton::setChecked(bool checked)
+{
+ Q_D(QAbstractButton);
+ if (!d->checkable || d->checked == checked) {
+ if (!d->blockRefresh)
+ checkStateSet();
+ return;
+ }
+
+ if (!checked && d->queryCheckedButton() == this) {
+ // the checked button of an exclusive or autoexclusive group cannot be unchecked
+#ifndef QT_NO_BUTTONGROUP
+ if (d->group ? d->group->d_func()->exclusive : d->autoExclusive)
+ return;
+ if (d->group)
+ d->group->d_func()->detectCheckedButton();
+#else
+ if (d->autoExclusive)
+ return;
+#endif
+ }
+
+ QPointer<QAbstractButton> guard(this);
+
+ d->checked = checked;
+ if (!d->blockRefresh)
+ checkStateSet();
+ d->refresh();
+
+ if (guard && checked)
+ d->notifyChecked();
+ if (guard)
+ emit toggled(checked);
+}
+
+bool QAbstractButton::isChecked() const
+{
+ Q_D(const QAbstractButton);
+ return d->checked;
+}
+
+/*!
+ \property QAbstractButton::down
+ \brief whether the button is pressed down
+
+ If this property is true, the button is pressed down. The signals
+ pressed() and clicked() are not emitted if you set this property
+ to true. The default is false.
+*/
+
+void QAbstractButton::setDown(bool down)
+{
+ Q_D(QAbstractButton);
+ if (d->down == down)
+ return;
+ d->down = down;
+ d->refresh();
+ if (d->autoRepeat && d->down)
+ d->repeatTimer.start(d->autoRepeatDelay, this);
+ else
+ d->repeatTimer.stop();
+}
+
+bool QAbstractButton::isDown() const
+{
+ Q_D(const QAbstractButton);
+ return d->down;
+}
+
+/*!
+\property QAbstractButton::autoRepeat
+\brief whether autoRepeat is enabled
+
+If autoRepeat is enabled, then the pressed(), released(), and clicked() signals are emitted at
+regular intervals when the button is down. autoRepeat is off by default.
+The initial delay and the repetition interval are defined in milliseconds by \l
+autoRepeatDelay and \l autoRepeatInterval.
+
+Note: If a button is pressed down by a shortcut key, then auto-repeat is enabled and timed by the
+system and not by this class. The pressed(), released(), and clicked() signals will be emitted
+like in the normal case.
+*/
+
+void QAbstractButton::setAutoRepeat(bool autoRepeat)
+{
+ Q_D(QAbstractButton);
+ if (d->autoRepeat == autoRepeat)
+ return;
+ d->autoRepeat = autoRepeat;
+ if (d->autoRepeat && d->down)
+ d->repeatTimer.start(d->autoRepeatDelay, this);
+ else
+ d->repeatTimer.stop();
+}
+
+bool QAbstractButton::autoRepeat() const
+{
+ Q_D(const QAbstractButton);
+ return d->autoRepeat;
+}
+
+/*!
+ \property QAbstractButton::autoRepeatDelay
+ \brief the initial delay of auto-repetition
+ \since 4.2
+
+ If \l autoRepeat is enabled, then autoRepeatDelay defines the initial
+ delay in milliseconds before auto-repetition kicks in.
+
+ \sa autoRepeat, autoRepeatInterval
+*/
+
+void QAbstractButton::setAutoRepeatDelay(int autoRepeatDelay)
+{
+ Q_D(QAbstractButton);
+ d->autoRepeatDelay = autoRepeatDelay;
+}
+
+int QAbstractButton::autoRepeatDelay() const
+{
+ Q_D(const QAbstractButton);
+ return d->autoRepeatDelay;
+}
+
+/*!
+ \property QAbstractButton::autoRepeatInterval
+ \brief the interval of auto-repetition
+ \since 4.2
+
+ If \l autoRepeat is enabled, then autoRepeatInterval defines the
+ length of the auto-repetition interval in millisecons.
+
+ \sa autoRepeat, autoRepeatDelay
+*/
+
+void QAbstractButton::setAutoRepeatInterval(int autoRepeatInterval)
+{
+ Q_D(QAbstractButton);
+ d->autoRepeatInterval = autoRepeatInterval;
+}
+
+int QAbstractButton::autoRepeatInterval() const
+{
+ Q_D(const QAbstractButton);
+ return d->autoRepeatInterval;
+}
+
+
+
+/*!
+\property QAbstractButton::autoExclusive
+\brief whether auto-exclusivity is enabled
+
+If auto-exclusivity is enabled, checkable buttons that belong to the
+same parent widget behave as if they were part of the same
+exclusive button group. In an exclusive button group, only one button
+can be checked at any time; checking another button automatically
+unchecks the previously checked one.
+
+The property has no effect on buttons that belong to a button
+group.
+
+autoExclusive is off by default, except for radio buttons.
+
+\sa QRadioButton
+*/
+void QAbstractButton::setAutoExclusive(bool autoExclusive)
+{
+ Q_D(QAbstractButton);
+ d->autoExclusive = autoExclusive;
+}
+
+bool QAbstractButton::autoExclusive() const
+{
+ Q_D(const QAbstractButton);
+ return d->autoExclusive;
+}
+
+#ifndef QT_NO_BUTTONGROUP
+/*!
+ Returns the group that this button belongs to.
+
+ If the button is not a member of any QButtonGroup, this function
+ returns 0.
+
+ \sa QButtonGroup
+*/
+QButtonGroup *QAbstractButton::group() const
+{
+ Q_D(const QAbstractButton);
+ return d->group;
+}
+#endif // QT_NO_BUTTONGROUP
+
+/*!
+Performs an animated click: the button is pressed immediately, and
+released \a msec milliseconds later (the default is 100 ms).
+
+Calling this function again before the button was released will reset
+the release timer.
+
+All signals associated with a click are emitted as appropriate.
+
+This function does nothing if the button is \link setEnabled()
+disabled. \endlink
+
+\sa click()
+*/
+void QAbstractButton::animateClick(int msec)
+{
+ if (!isEnabled())
+ return;
+ Q_D(QAbstractButton);
+ if (d->checkable && focusPolicy() & Qt::ClickFocus)
+ setFocus();
+ setDown(true);
+ repaint(); //flush paint event before invoking potentially expensive operation
+ QApplication::flush();
+ if (!d->animateTimer.isActive())
+ d->emitPressed();
+ d->animateTimer.start(msec, this);
+}
+
+/*!
+Performs a click.
+
+All the usual signals associated with a click are emitted as
+appropriate. If the button is checkable, the state of the button is
+toggled.
+
+This function does nothing if the button is \link setEnabled()
+disabled. \endlink
+
+\sa animateClick()
+ */
+void QAbstractButton::click()
+{
+ if (!isEnabled())
+ return;
+ Q_D(QAbstractButton);
+ QPointer<QAbstractButton> guard(this);
+ d->down = true;
+ d->emitPressed();
+ if (guard) {
+ d->down = false;
+ nextCheckState();
+ if (guard)
+ d->emitReleased();
+ if (guard)
+ d->emitClicked();
+ }
+}
+
+/*! \fn void QAbstractButton::toggle()
+
+ Toggles the state of a checkable button.
+
+ \sa checked
+*/
+void QAbstractButton::toggle()
+{
+ Q_D(QAbstractButton);
+ setChecked(!d->checked);
+}
+
+
+/*! This virtual handler is called when setChecked() was called,
+unless it was called from within nextCheckState(). It allows
+subclasses to reset their intermediate button states.
+
+\sa nextCheckState()
+ */
+void QAbstractButton::checkStateSet()
+{
+}
+
+/*! This virtual handler is called when a button is clicked. The
+default implementation calls setChecked(!isChecked()) if the button
+isCheckable(). It allows subclasses to implement intermediate button
+states.
+
+\sa checkStateSet()
+*/
+void QAbstractButton::nextCheckState()
+{
+ if (isCheckable())
+ setChecked(!isChecked());
+}
+
+/*!
+Returns true if \a pos is inside the clickable button rectangle;
+otherwise returns false.
+
+By default, the clickable area is the entire widget. Subclasses
+may reimplement this function to provide support for clickable
+areas of different shapes and sizes.
+*/
+bool QAbstractButton::hitButton(const QPoint &pos) const
+{
+ return rect().contains(pos);
+}
+
+/*! \reimp */
+bool QAbstractButton::event(QEvent *e)
+{
+ // as opposed to other widgets, disabled buttons accept mouse
+ // events. This avoids surprising click-through scenarios
+ if (!isEnabled()) {
+ switch(e->type()) {
+ case QEvent::TabletPress:
+ case QEvent::TabletRelease:
+ case QEvent::TabletMove:
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseButtonDblClick:
+ case QEvent::MouseMove:
+ case QEvent::HoverMove:
+ case QEvent::HoverEnter:
+ case QEvent::HoverLeave:
+ case QEvent::ContextMenu:
+#ifndef QT_NO_WHEELEVENT
+ case QEvent::Wheel:
+#endif
+ return true;
+ default:
+ break;
+ }
+ }
+
+#ifndef QT_NO_SHORTCUT
+ if (e->type() == QEvent::Shortcut) {
+ Q_D(QAbstractButton);
+ QShortcutEvent *se = static_cast<QShortcutEvent *>(e);
+ if (d->shortcutId != se->shortcutId())
+ return false;
+ if (!se->isAmbiguous()) {
+ if (!d->animateTimer.isActive())
+ animateClick();
+ } else {
+ if (focusPolicy() != Qt::NoFocus)
+ setFocus(Qt::ShortcutFocusReason);
+ window()->setAttribute(Qt::WA_KeyboardFocusChange);
+ }
+ return true;
+ }
+#endif
+ return QWidget::event(e);
+}
+
+/*! \reimp */
+void QAbstractButton::mousePressEvent(QMouseEvent *e)
+{
+ Q_D(QAbstractButton);
+ if (e->button() != Qt::LeftButton) {
+ e->ignore();
+ return;
+ }
+ if (hitButton(e->pos())) {
+ setDown(true);
+ d->pressed = true;
+ repaint(); //flush paint event before invoking potentially expensive operation
+ QApplication::flush();
+ d->emitPressed();
+ e->accept();
+ } else {
+ e->ignore();
+ }
+}
+
+/*! \reimp */
+void QAbstractButton::mouseReleaseEvent(QMouseEvent *e)
+{
+ Q_D(QAbstractButton);
+ d->pressed = false;
+
+ if (e->button() != Qt::LeftButton) {
+ e->ignore();
+ return;
+ }
+
+ if (!d->down) {
+ e->ignore();
+ return;
+ }
+
+ if (hitButton(e->pos())) {
+ d->repeatTimer.stop();
+ d->click();
+ e->accept();
+ } else {
+ setDown(false);
+ e->ignore();
+ }
+}
+
+/*! \reimp */
+void QAbstractButton::mouseMoveEvent(QMouseEvent *e)
+{
+ Q_D(QAbstractButton);
+ if (!(e->buttons() & Qt::LeftButton) || !d->pressed) {
+ e->ignore();
+ return;
+ }
+
+ if (hitButton(e->pos()) != d->down) {
+ setDown(!d->down);
+ repaint(); //flush paint event before invoking potentially expensive operation
+ QApplication::flush();
+ if (d->down)
+ d->emitPressed();
+ else
+ d->emitReleased();
+ e->accept();
+ } else if (!hitButton(e->pos())) {
+ e->ignore();
+ }
+}
+
+/*! \reimp */
+void QAbstractButton::keyPressEvent(QKeyEvent *e)
+{
+ Q_D(QAbstractButton);
+ bool next = true;
+ switch (e->key()) {
+ case Qt::Key_Enter:
+ case Qt::Key_Return:
+ e->ignore();
+ break;
+ case Qt::Key_Select:
+ case Qt::Key_Space:
+ if (!e->isAutoRepeat()) {
+ setDown(true);
+ repaint(); //flush paint event before invoking potentially expensive operation
+ QApplication::flush();
+ d->emitPressed();
+ }
+ break;
+ case Qt::Key_Up:
+ case Qt::Key_Left:
+ next = false;
+ // fall through
+ case Qt::Key_Right:
+ case Qt::Key_Down:
+#ifdef QT_KEYPAD_NAVIGATION
+ if ((QApplication::keypadNavigationEnabled()
+ && (e->key() == Qt::Key_Left || e->key() == Qt::Key_Right))
+ || (!QApplication::navigationMode() == Qt::NavigationModeKeypadDirectional
+ || (e->key() == Qt::Key_Up || e->key() == Qt::Key_Down))) {
+ e->ignore();
+ return;
+ }
+#endif
+ QWidget *pw;
+ if (d->autoExclusive
+#ifndef QT_NO_BUTTONGROUP
+ || d->group
+#endif
+#ifndef QT_NO_ITEMVIEWS
+ || ((pw = parentWidget()) && qobject_cast<QAbstractItemView *>(pw->parentWidget()))
+#endif
+ ) {
+ // ### Using qobject_cast to check if the parent is a viewport of
+ // QAbstractItemView is a crude hack, and should be revisited and
+ // cleaned up when fixing task 194373. It's here to ensure that we
+ // keep compatibility outside QAbstractItemView.
+ d->moveFocus(e->key());
+ if (hasFocus()) // nothing happend, propagate
+ e->ignore();
+ } else {
+ focusNextPrevChild(next);
+ }
+ break;
+ case Qt::Key_Escape:
+ if (d->down) {
+ setDown(false);
+ repaint(); //flush paint event before invoking potentially expensive operation
+ QApplication::flush();
+ d->emitReleased();
+ break;
+ }
+ // fall through
+ default:
+ e->ignore();
+ }
+}
+
+/*! \reimp */
+void QAbstractButton::keyReleaseEvent(QKeyEvent *e)
+{
+ Q_D(QAbstractButton);
+
+ if (!e->isAutoRepeat())
+ d->repeatTimer.stop();
+
+ switch (e->key()) {
+ case Qt::Key_Select:
+ case Qt::Key_Space:
+ if (!e->isAutoRepeat() && d->down)
+ d->click();
+ break;
+ default:
+ e->ignore();
+ }
+}
+
+/*!\reimp
+ */
+void QAbstractButton::timerEvent(QTimerEvent *e)
+{
+ Q_D(QAbstractButton);
+ if (e->timerId() == d->repeatTimer.timerId()) {
+ d->repeatTimer.start(d->autoRepeatInterval, this);
+ if (d->down) {
+ QPointer<QAbstractButton> guard(this);
+ nextCheckState();
+ if (guard)
+ d->emitReleased();
+ if (guard)
+ d->emitClicked();
+ if (guard)
+ d->emitPressed();
+ }
+ } else if (e->timerId() == d->animateTimer.timerId()) {
+ d->animateTimer.stop();
+ d->click();
+ }
+}
+
+/*! \reimp */
+void QAbstractButton::focusInEvent(QFocusEvent *e)
+{
+ Q_D(QAbstractButton);
+#ifdef QT_KEYPAD_NAVIGATION
+ if (!QApplication::keypadNavigationEnabled())
+#endif
+ d->fixFocusPolicy();
+ QWidget::focusInEvent(e);
+}
+
+/*! \reimp */
+void QAbstractButton::focusOutEvent(QFocusEvent *e)
+{
+ Q_D(QAbstractButton);
+ if (e->reason() != Qt::PopupFocusReason)
+ d->down = false;
+ QWidget::focusOutEvent(e);
+}
+
+/*! \reimp */
+void QAbstractButton::changeEvent(QEvent *e)
+{
+ Q_D(QAbstractButton);
+ switch (e->type()) {
+ case QEvent::EnabledChange:
+ if (!isEnabled())
+ setDown(false);
+ break;
+ default:
+ d->sizeHint = QSize();
+ break;
+ }
+ QWidget::changeEvent(e);
+}
+
+/*!
+ \fn void QAbstractButton::paintEvent(QPaintEvent *e)
+ \reimp
+*/
+
+/*!
+ \fn void QAbstractButton::pressed()
+
+ This signal is emitted when the button is pressed down.
+
+ \sa released(), clicked()
+*/
+
+/*!
+ \fn void QAbstractButton::released()
+
+ This signal is emitted when the button is released.
+
+ \sa pressed(), clicked(), toggled()
+*/
+
+/*!
+\fn void QAbstractButton::clicked(bool checked)
+
+This signal is emitted when the button is activated (i.e. pressed down
+then released while the mouse cursor is inside the button), when the
+shortcut key is typed, or when click() or animateClick() is called.
+Notably, this signal is \e not emitted if you call setDown(),
+setChecked() or toggle().
+
+If the button is checkable, \a checked is true if the button is
+checked, or false if the button is unchecked.
+
+\sa pressed(), released(), toggled()
+*/
+
+/*!
+\fn void QAbstractButton::toggled(bool checked)
+
+This signal is emitted whenever a checkable button changes its state.
+\a checked is true if the button is checked, or false if the button is
+unchecked.
+
+This may be the result of a user action, click() slot activation,
+or because setChecked() was called.
+
+The states of buttons in exclusive button groups are updated before this
+signal is emitted. This means that slots can act on either the "off"
+signal or the "on" signal emitted by the buttons in the group whose
+states have changed.
+
+For example, a slot that reacts to signals emitted by newly checked
+buttons but which ignores signals from buttons that have been unchecked
+can be implemented using the following pattern:
+
+\snippet doc/src/snippets/code/src_gui_widgets_qabstractbutton.cpp 2
+
+Button groups can be created using the QButtonGroup class, and
+updates to the button states monitored with the
+\l{QButtonGroup::buttonClicked()} signal.
+
+\sa checked, clicked()
+*/
+
+/*!
+ \property QAbstractButton::iconSize
+ \brief the icon size used for this button.
+
+ The default size is defined by the GUI style. This is a maximum
+ size for the icons. Smaller icons will not be scaled up.
+*/
+
+QSize QAbstractButton::iconSize() const
+{
+ Q_D(const QAbstractButton);
+ if (d->iconSize.isValid())
+ return d->iconSize;
+ int e = style()->pixelMetric(QStyle::PM_ButtonIconSize, 0, this);
+ return QSize(e, e);
+}
+
+void QAbstractButton::setIconSize(const QSize &size)
+{
+ Q_D(QAbstractButton);
+ if (d->iconSize == size)
+ return;
+
+ d->iconSize = size;
+ d->sizeHint = QSize();
+ updateGeometry();
+ if (isVisible()) {
+ update();
+ }
+}
+
+
+#ifdef QT3_SUPPORT
+/*!
+ Use icon() instead.
+*/
+QIcon *QAbstractButton::iconSet() const
+{
+ Q_D(const QAbstractButton);
+ if (!d->icon.isNull())
+ return const_cast<QIcon *>(&d->icon);
+ return 0;
+}
+
+/*!
+ Use QAbstractButton(QWidget *) instead.
+
+ Call setObjectName() if you want to specify an object name, and
+ setParent() if you want to set the window flags.
+*/
+QAbstractButton::QAbstractButton(QWidget *parent, const char *name, Qt::WindowFlags f)
+ : QWidget(*new QAbstractButtonPrivate, parent, f)
+{
+ Q_D(QAbstractButton);
+ setObjectName(QString::fromAscii(name));
+ d->init();
+}
+
+/*! \fn bool QAbstractButton::isOn() const
+
+ Use isChecked() instead.
+*/
+
+/*!
+ \fn QPixmap *QAbstractButton::pixmap() const
+
+ This compatibility function always returns 0.
+
+ Use icon() instead.
+*/
+
+/*! \fn void QAbstractButton::setPixmap(const QPixmap &p)
+
+ Use setIcon() instead.
+*/
+
+/*! \fn void QAbstractButton::setIconSet(const QIcon &icon)
+
+ Use setIcon() instead.
+*/
+
+/*! \fn void QAbstractButton::setOn(bool b)
+
+ Use setChecked() instead.
+*/
+
+/*! \fn bool QAbstractButton::isToggleButton() const
+
+ Use isCheckable() instead.
+*/
+
+/*!
+ \fn void QAbstractButton::setToggleButton(bool b)
+
+ Use setCheckable() instead.
+*/
+
+/*! \fn void QAbstractButton::setAccel(const QKeySequence &key)
+
+ Use setShortcut() instead.
+*/
+
+/*! \fn QKeySequence QAbstractButton::accel() const
+
+ Use shortcut() instead.
+*/
+#endif
+
+QT_END_NAMESPACE
diff --git a/src/widgets/widgets/qabstractbutton.h b/src/widgets/widgets/qabstractbutton.h
new file mode 100644
index 0000000000..9edfa1b267
--- /dev/null
+++ b/src/widgets/widgets/qabstractbutton.h
@@ -0,0 +1,180 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QABSTRACTBUTTON_H
+#define QABSTRACTBUTTON_H
+
+#include <QtWidgets/qicon.h>
+#include <QtGui/qkeysequence.h>
+#include <QtWidgets/qwidget.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QButtonGroup;
+class QAbstractButtonPrivate;
+
+class Q_WIDGETS_EXPORT QAbstractButton : public QWidget
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QString text READ text WRITE setText)
+ Q_PROPERTY(QIcon icon READ icon WRITE setIcon)
+ Q_PROPERTY(QSize iconSize READ iconSize WRITE setIconSize)
+#ifndef QT_NO_SHORTCUT
+ Q_PROPERTY(QKeySequence shortcut READ shortcut WRITE setShortcut)
+#endif
+ Q_PROPERTY(bool checkable READ isCheckable WRITE setCheckable)
+ Q_PROPERTY(bool checked READ isChecked WRITE setChecked DESIGNABLE isCheckable NOTIFY toggled USER true)
+ Q_PROPERTY(bool autoRepeat READ autoRepeat WRITE setAutoRepeat)
+ Q_PROPERTY(bool autoExclusive READ autoExclusive WRITE setAutoExclusive)
+ Q_PROPERTY(int autoRepeatDelay READ autoRepeatDelay WRITE setAutoRepeatDelay)
+ Q_PROPERTY(int autoRepeatInterval READ autoRepeatInterval WRITE setAutoRepeatInterval)
+ Q_PROPERTY(bool down READ isDown WRITE setDown DESIGNABLE false)
+
+public:
+ explicit QAbstractButton(QWidget* parent=0);
+ ~QAbstractButton();
+
+ void setText(const QString &text);
+ QString text() const;
+
+ void setIcon(const QIcon &icon);
+ QIcon icon() const;
+
+ QSize iconSize() const;
+
+#ifndef QT_NO_SHORTCUT
+ void setShortcut(const QKeySequence &key);
+ QKeySequence shortcut() const;
+#endif
+
+ void setCheckable(bool);
+ bool isCheckable() const;
+
+ bool isChecked() const;
+
+ void setDown(bool);
+ bool isDown() const;
+
+ void setAutoRepeat(bool);
+ bool autoRepeat() const;
+
+ void setAutoRepeatDelay(int);
+ int autoRepeatDelay() const;
+
+ void setAutoRepeatInterval(int);
+ int autoRepeatInterval() const;
+
+ void setAutoExclusive(bool);
+ bool autoExclusive() const;
+
+#ifndef QT_NO_BUTTONGROUP
+ QButtonGroup *group() const;
+#endif
+
+public Q_SLOTS:
+ void setIconSize(const QSize &size);
+ void animateClick(int msec = 100);
+ void click();
+ void toggle();
+ void setChecked(bool);
+
+Q_SIGNALS:
+ void pressed();
+ void released();
+ void clicked(bool checked = false);
+ void toggled(bool checked);
+
+protected:
+ virtual void paintEvent(QPaintEvent *e) = 0;
+ virtual bool hitButton(const QPoint &pos) const;
+ virtual void checkStateSet();
+ virtual void nextCheckState();
+
+ bool event(QEvent *e);
+ void keyPressEvent(QKeyEvent *e);
+ void keyReleaseEvent(QKeyEvent *e);
+ void mousePressEvent(QMouseEvent *e);
+ void mouseReleaseEvent(QMouseEvent *e);
+ void mouseMoveEvent(QMouseEvent *e);
+ void focusInEvent(QFocusEvent *e);
+ void focusOutEvent(QFocusEvent *e);
+ void changeEvent(QEvent *e);
+ void timerEvent(QTimerEvent *e);
+
+#ifdef QT3_SUPPORT
+public:
+ QT3_SUPPORT_CONSTRUCTOR QAbstractButton(QWidget *parent, const char *name, Qt::WindowFlags f=0);
+ inline QT3_SUPPORT bool isOn() const { return isChecked(); }
+ inline QT3_SUPPORT const QPixmap *pixmap() const { return 0; } // help styles compile
+ inline QT3_SUPPORT void setPixmap( const QPixmap &p ) {
+ setIcon(QIcon(p));
+ setIconSize(p.size());
+ }
+ QT3_SUPPORT QIcon *iconSet() const;
+ inline QT3_SUPPORT void setIconSet(const QIcon &icon) { setIcon(icon); }
+ inline QT3_SUPPORT bool isToggleButton() const { return isCheckable(); }
+ inline QT3_SUPPORT void setToggleButton(bool b) { setCheckable(b); }
+ inline QT3_SUPPORT void setAccel(const QKeySequence &key) { setShortcut(key); }
+ inline QT3_SUPPORT QKeySequence accel() const { return shortcut(); }
+
+public Q_SLOTS:
+ inline QT_MOC_COMPAT void setOn(bool b) { setChecked(b); }
+#endif
+
+protected:
+ QAbstractButton(QAbstractButtonPrivate &dd, QWidget* parent = 0);
+
+private:
+ Q_DECLARE_PRIVATE(QAbstractButton)
+ Q_DISABLE_COPY(QAbstractButton)
+ friend class QButtonGroup;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QABSTRACTBUTTON_H
diff --git a/src/gui/widgets/qabstractbutton_p.h b/src/widgets/widgets/qabstractbutton_p.h
index d2d4c06bff..d2d4c06bff 100644
--- a/src/gui/widgets/qabstractbutton_p.h
+++ b/src/widgets/widgets/qabstractbutton_p.h
diff --git a/src/gui/widgets/qabstractscrollarea.cpp b/src/widgets/widgets/qabstractscrollarea.cpp
index 6081bc8a55..6081bc8a55 100644
--- a/src/gui/widgets/qabstractscrollarea.cpp
+++ b/src/widgets/widgets/qabstractscrollarea.cpp
diff --git a/src/widgets/widgets/qabstractscrollarea.h b/src/widgets/widgets/qabstractscrollarea.h
new file mode 100644
index 0000000000..3f2a273297
--- /dev/null
+++ b/src/widgets/widgets/qabstractscrollarea.h
@@ -0,0 +1,144 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QABSTRACTSCROLLAREA_H
+#define QABSTRACTSCROLLAREA_H
+
+#include <QtWidgets/qframe.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_SCROLLAREA
+
+class QMargins;
+class QScrollBar;
+class QAbstractScrollAreaPrivate;
+
+class Q_WIDGETS_EXPORT QAbstractScrollArea : public QFrame
+{
+ Q_OBJECT
+ Q_PROPERTY(Qt::ScrollBarPolicy verticalScrollBarPolicy READ verticalScrollBarPolicy WRITE setVerticalScrollBarPolicy)
+ Q_PROPERTY(Qt::ScrollBarPolicy horizontalScrollBarPolicy READ horizontalScrollBarPolicy WRITE setHorizontalScrollBarPolicy)
+
+public:
+ explicit QAbstractScrollArea(QWidget* parent=0);
+ ~QAbstractScrollArea();
+
+ Qt::ScrollBarPolicy verticalScrollBarPolicy() const;
+ void setVerticalScrollBarPolicy(Qt::ScrollBarPolicy);
+ QScrollBar *verticalScrollBar() const;
+ void setVerticalScrollBar(QScrollBar *scrollbar);
+
+ Qt::ScrollBarPolicy horizontalScrollBarPolicy() const;
+ void setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy);
+ QScrollBar *horizontalScrollBar() const;
+ void setHorizontalScrollBar(QScrollBar *scrollbar);
+
+ QWidget *cornerWidget() const;
+ void setCornerWidget(QWidget *widget);
+
+ void addScrollBarWidget(QWidget *widget, Qt::Alignment alignment);
+ QWidgetList scrollBarWidgets(Qt::Alignment alignment);
+
+ QWidget *viewport() const;
+ void setViewport(QWidget *widget);
+ QSize maximumViewportSize() const;
+
+ QSize minimumSizeHint() const;
+
+ QSize sizeHint() const;
+
+protected Q_SLOTS:
+ void setupViewport(QWidget *viewport);
+
+protected:
+ QAbstractScrollArea(QAbstractScrollAreaPrivate &dd, QWidget *parent = 0);
+ void setViewportMargins(int left, int top, int right, int bottom);
+ void setViewportMargins(const QMargins &margins);
+
+ bool event(QEvent *);
+ virtual bool viewportEvent(QEvent *);
+
+ void resizeEvent(QResizeEvent *);
+ void paintEvent(QPaintEvent *);
+ void mousePressEvent(QMouseEvent *);
+ void mouseReleaseEvent(QMouseEvent *);
+ void mouseDoubleClickEvent(QMouseEvent *);
+ void mouseMoveEvent(QMouseEvent *);
+#ifndef QT_NO_WHEELEVENT
+ void wheelEvent(QWheelEvent *);
+#endif
+#ifndef QT_NO_CONTEXTMENU
+ void contextMenuEvent(QContextMenuEvent *);
+#endif
+#ifndef QT_NO_DRAGANDDROP
+ void dragEnterEvent(QDragEnterEvent *);
+ void dragMoveEvent(QDragMoveEvent *);
+ void dragLeaveEvent(QDragLeaveEvent *);
+ void dropEvent(QDropEvent *);
+#endif
+
+ void keyPressEvent(QKeyEvent *);
+
+ virtual void scrollContentsBy(int dx, int dy);
+
+private:
+ Q_DECLARE_PRIVATE(QAbstractScrollArea)
+ Q_DISABLE_COPY(QAbstractScrollArea)
+ Q_PRIVATE_SLOT(d_func(), void _q_hslide(int))
+ Q_PRIVATE_SLOT(d_func(), void _q_vslide(int))
+ Q_PRIVATE_SLOT(d_func(), void _q_showOrHideScrollBars())
+
+ friend class QStyleSheetStyle;
+ friend class QWidgetPrivate;
+};
+
+#endif // QT_NO_SCROLLAREA
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QABSTRACTSCROLLAREA_H
diff --git a/src/widgets/widgets/qabstractscrollarea_p.h b/src/widgets/widgets/qabstractscrollarea_p.h
new file mode 100644
index 0000000000..5511d08f4e
--- /dev/null
+++ b/src/widgets/widgets/qabstractscrollarea_p.h
@@ -0,0 +1,146 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QABSTRACTSCROLLAREA_P_H
+#define QABSTRACTSCROLLAREA_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "private/qframe_p.h"
+#include "qabstractscrollarea.h"
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_SCROLLAREA
+
+class QScrollBar;
+class QAbstractScrollAreaScrollBarContainer;
+class Q_WIDGETS_EXPORT QAbstractScrollAreaPrivate: public QFramePrivate
+{
+ Q_DECLARE_PUBLIC(QAbstractScrollArea)
+
+public:
+ QAbstractScrollAreaPrivate();
+
+ void replaceScrollBar(QScrollBar *scrollBar, Qt::Orientation orientation);
+
+ QAbstractScrollAreaScrollBarContainer *scrollBarContainers[Qt::Vertical + 1];
+ QScrollBar *hbar, *vbar;
+ Qt::ScrollBarPolicy vbarpolicy, hbarpolicy;
+
+ QWidget *viewport;
+ QWidget *cornerWidget;
+ QRect cornerPaintingRect;
+#ifdef Q_WS_MAC
+ QRect reverseCornerPaintingRect;
+#endif
+ int left, top, right, bottom; // viewport margin
+
+ int xoffset, yoffset;
+ QPoint overshoot;
+
+ void init();
+ void layoutChildren();
+ // ### Fix for 4.4, talk to Bjoern E or Girish.
+ virtual void scrollBarPolicyChanged(Qt::Orientation, Qt::ScrollBarPolicy) {}
+ bool canStartScrollingAt( const QPoint &startPos );
+
+ void _q_hslide(int);
+ void _q_vslide(int);
+ void _q_showOrHideScrollBars();
+
+ virtual QPoint contentsOffset() const;
+
+ inline bool viewportEvent(QEvent *event)
+ { return q_func()->viewportEvent(event); }
+ QScopedPointer<QObject> viewportFilter;
+
+#ifdef Q_WS_WIN
+ bool singleFingerPanEnabled;
+ void setSingleFingerPanEnabled(bool on = true);
+#endif
+};
+
+class QAbstractScrollAreaFilter : public QObject
+{
+ Q_OBJECT
+public:
+ QAbstractScrollAreaFilter(QAbstractScrollAreaPrivate *p) : d(p)
+ { setObjectName(QLatin1String("qt_abstractscrollarea_filter")); }
+ bool eventFilter(QObject *o, QEvent *e)
+ { return (o == d->viewport ? d->viewportEvent(e) : false); }
+private:
+ QAbstractScrollAreaPrivate *d;
+};
+
+class QBoxLayout;
+class QAbstractScrollAreaScrollBarContainer : public QWidget
+{
+public:
+ enum LogicalPosition { LogicalLeft = 1, LogicalRight = 2 };
+
+ QAbstractScrollAreaScrollBarContainer(Qt::Orientation orientation, QWidget *parent);
+ void addWidget(QWidget *widget, LogicalPosition position);
+ QWidgetList widgets(LogicalPosition position);
+ void removeWidget(QWidget *widget);
+
+ QScrollBar *scrollBar;
+ QBoxLayout *layout;
+private:
+ int scrollBarLayoutIndex() const;
+
+ Qt::Orientation orientation;
+};
+
+#endif // QT_NO_SCROLLAREA
+
+QT_END_NAMESPACE
+
+#endif // QABSTRACTSCROLLAREA_P_H
diff --git a/src/gui/widgets/qabstractslider.cpp b/src/widgets/widgets/qabstractslider.cpp
index c86146e83e..c86146e83e 100644
--- a/src/gui/widgets/qabstractslider.cpp
+++ b/src/widgets/widgets/qabstractslider.cpp
diff --git a/src/widgets/widgets/qabstractslider.h b/src/widgets/widgets/qabstractslider.h
new file mode 100644
index 0000000000..109798154e
--- /dev/null
+++ b/src/widgets/widgets/qabstractslider.h
@@ -0,0 +1,184 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QABSTRACTSLIDER_H
+#define QABSTRACTSLIDER_H
+
+#include <QtWidgets/qwidget.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QAbstractSliderPrivate;
+
+class Q_WIDGETS_EXPORT QAbstractSlider : public QWidget
+{
+ Q_OBJECT
+
+ Q_PROPERTY(int minimum READ minimum WRITE setMinimum)
+ Q_PROPERTY(int maximum READ maximum WRITE setMaximum)
+ Q_PROPERTY(int singleStep READ singleStep WRITE setSingleStep)
+ Q_PROPERTY(int pageStep READ pageStep WRITE setPageStep)
+ Q_PROPERTY(int value READ value WRITE setValue NOTIFY valueChanged USER true)
+ Q_PROPERTY(int sliderPosition READ sliderPosition WRITE setSliderPosition NOTIFY sliderMoved)
+ Q_PROPERTY(bool tracking READ hasTracking WRITE setTracking)
+ Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation)
+ Q_PROPERTY(bool invertedAppearance READ invertedAppearance WRITE setInvertedAppearance)
+ Q_PROPERTY(bool invertedControls READ invertedControls WRITE setInvertedControls)
+ Q_PROPERTY(bool sliderDown READ isSliderDown WRITE setSliderDown DESIGNABLE false)
+
+public:
+ explicit QAbstractSlider(QWidget *parent=0);
+ ~QAbstractSlider();
+
+ Qt::Orientation orientation() const;
+
+ void setMinimum(int);
+ int minimum() const;
+
+ void setMaximum(int);
+ int maximum() const;
+
+ void setRange(int min, int max);
+
+ void setSingleStep(int);
+ int singleStep() const;
+
+ void setPageStep(int);
+ int pageStep() const;
+
+ void setTracking(bool enable);
+ bool hasTracking() const;
+
+ void setSliderDown(bool);
+ bool isSliderDown() const;
+
+ void setSliderPosition(int);
+ int sliderPosition() const;
+
+ void setInvertedAppearance(bool);
+ bool invertedAppearance() const;
+
+ void setInvertedControls(bool);
+ bool invertedControls() const;
+
+ enum SliderAction {
+ SliderNoAction,
+ SliderSingleStepAdd,
+ SliderSingleStepSub,
+ SliderPageStepAdd,
+ SliderPageStepSub,
+ SliderToMinimum,
+ SliderToMaximum,
+ SliderMove
+ };
+
+ int value() const;
+
+ void triggerAction(SliderAction action);
+
+public Q_SLOTS:
+ void setValue(int);
+ void setOrientation(Qt::Orientation);
+
+Q_SIGNALS:
+ void valueChanged(int value);
+
+ void sliderPressed();
+ void sliderMoved(int position);
+ void sliderReleased();
+
+ void rangeChanged(int min, int max);
+
+ void actionTriggered(int action);
+
+protected:
+ bool event(QEvent *e);
+
+ void setRepeatAction(SliderAction action, int thresholdTime = 500, int repeatTime = 50);
+ SliderAction repeatAction() const;
+
+ enum SliderChange {
+ SliderRangeChange,
+ SliderOrientationChange,
+ SliderStepsChange,
+ SliderValueChange
+ };
+ virtual void sliderChange(SliderChange change);
+
+ void keyPressEvent(QKeyEvent *ev);
+ void timerEvent(QTimerEvent *);
+#ifndef QT_NO_WHEELEVENT
+ void wheelEvent(QWheelEvent *e);
+#endif
+ void changeEvent(QEvent *e);
+
+#ifdef QT3_SUPPORT
+public:
+ inline QT3_SUPPORT int minValue() const { return minimum(); }
+ inline QT3_SUPPORT int maxValue() const { return maximum(); }
+ inline QT3_SUPPORT int lineStep() const { return singleStep(); }
+ inline QT3_SUPPORT void setMinValue(int v) { setMinimum(v); }
+ inline QT3_SUPPORT void setMaxValue(int v) { setMaximum(v); }
+ inline QT3_SUPPORT void setLineStep(int v) { setSingleStep(v); }
+ inline QT3_SUPPORT void setSteps(int single, int page) { setSingleStep(single); setPageStep(page); }
+ inline QT3_SUPPORT void addPage() { triggerAction(SliderPageStepAdd); }
+ inline QT3_SUPPORT void subtractPage() { triggerAction(SliderPageStepSub); }
+ inline QT3_SUPPORT void addLine() { triggerAction(SliderSingleStepAdd); }
+ inline QT3_SUPPORT void subtractLine() { triggerAction(SliderSingleStepSub); }
+#endif
+
+protected:
+ QAbstractSlider(QAbstractSliderPrivate &dd, QWidget *parent=0);
+
+private:
+ Q_DISABLE_COPY(QAbstractSlider)
+ Q_DECLARE_PRIVATE(QAbstractSlider)
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QABSTRACTSLIDER_H
diff --git a/src/gui/widgets/qabstractslider_p.h b/src/widgets/widgets/qabstractslider_p.h
index fdbc0f9534..fdbc0f9534 100644
--- a/src/gui/widgets/qabstractslider_p.h
+++ b/src/widgets/widgets/qabstractslider_p.h
diff --git a/src/gui/widgets/qabstractspinbox.cpp b/src/widgets/widgets/qabstractspinbox.cpp
index 4372ae3341..4372ae3341 100644
--- a/src/gui/widgets/qabstractspinbox.cpp
+++ b/src/widgets/widgets/qabstractspinbox.cpp
diff --git a/src/widgets/widgets/qabstractspinbox.h b/src/widgets/widgets/qabstractspinbox.h
new file mode 100644
index 0000000000..fb3ae2f5ee
--- /dev/null
+++ b/src/widgets/widgets/qabstractspinbox.h
@@ -0,0 +1,181 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QABSTRACTSPINBOX_H
+#define QABSTRACTSPINBOX_H
+
+#include <QtWidgets/qwidget.h>
+#include <QtGui/qvalidator.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_SPINBOX
+
+class QLineEdit;
+
+class QAbstractSpinBoxPrivate;
+class QStyleOptionSpinBox;
+
+class Q_WIDGETS_EXPORT QAbstractSpinBox : public QWidget
+{
+ Q_OBJECT
+
+ Q_ENUMS(ButtonSymbols)
+ Q_ENUMS(CorrectionMode)
+ Q_PROPERTY(bool wrapping READ wrapping WRITE setWrapping)
+ Q_PROPERTY(bool frame READ hasFrame WRITE setFrame)
+ Q_PROPERTY(Qt::Alignment alignment READ alignment WRITE setAlignment)
+ Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly)
+ Q_PROPERTY(ButtonSymbols buttonSymbols READ buttonSymbols WRITE setButtonSymbols)
+ Q_PROPERTY(QString specialValueText READ specialValueText WRITE setSpecialValueText)
+ Q_PROPERTY(QString text READ text)
+ Q_PROPERTY(bool accelerated READ isAccelerated WRITE setAccelerated)
+ Q_PROPERTY(CorrectionMode correctionMode READ correctionMode WRITE setCorrectionMode)
+ Q_PROPERTY(bool acceptableInput READ hasAcceptableInput)
+ Q_PROPERTY(bool keyboardTracking READ keyboardTracking WRITE setKeyboardTracking)
+public:
+ explicit QAbstractSpinBox(QWidget *parent = 0);
+ ~QAbstractSpinBox();
+
+ enum StepEnabledFlag { StepNone = 0x00, StepUpEnabled = 0x01,
+ StepDownEnabled = 0x02 };
+ Q_DECLARE_FLAGS(StepEnabled, StepEnabledFlag)
+
+ enum ButtonSymbols { UpDownArrows, PlusMinus, NoButtons };
+
+ ButtonSymbols buttonSymbols() const;
+ void setButtonSymbols(ButtonSymbols bs);
+
+ enum CorrectionMode { CorrectToPreviousValue, CorrectToNearestValue };
+
+ void setCorrectionMode(CorrectionMode cm);
+ CorrectionMode correctionMode() const;
+
+ bool hasAcceptableInput() const;
+ QString text() const;
+
+ QString specialValueText() const;
+ void setSpecialValueText(const QString &txt);
+
+ bool wrapping() const;
+ void setWrapping(bool w);
+
+ void setReadOnly(bool r);
+ bool isReadOnly() const;
+
+ void setKeyboardTracking(bool kt);
+ bool keyboardTracking() const;
+
+ void setAlignment(Qt::Alignment flag);
+ Qt::Alignment alignment() const;
+
+ void setFrame(bool);
+ bool hasFrame() const;
+
+ void setAccelerated(bool on);
+ bool isAccelerated() const;
+
+ QSize sizeHint() const;
+ QSize minimumSizeHint() const;
+ void interpretText();
+ bool event(QEvent *event);
+
+ QVariant inputMethodQuery(Qt::InputMethodQuery) const;
+
+ virtual QValidator::State validate(QString &input, int &pos) const;
+ virtual void fixup(QString &input) const;
+
+ virtual void stepBy(int steps);
+public Q_SLOTS:
+ void stepUp();
+ void stepDown();
+ void selectAll();
+ virtual void clear();
+protected:
+ void resizeEvent(QResizeEvent *event);
+ void keyPressEvent(QKeyEvent *event);
+ void keyReleaseEvent(QKeyEvent *event);
+#ifndef QT_NO_WHEELEVENT
+ void wheelEvent(QWheelEvent *event);
+#endif
+ void focusInEvent(QFocusEvent *event);
+ void focusOutEvent(QFocusEvent *event);
+ void contextMenuEvent(QContextMenuEvent *event);
+ void changeEvent(QEvent *event);
+ void closeEvent(QCloseEvent *event);
+ void hideEvent(QHideEvent *event);
+ void mousePressEvent(QMouseEvent *event);
+ void mouseReleaseEvent(QMouseEvent *event);
+ void mouseMoveEvent(QMouseEvent *event);
+ void timerEvent(QTimerEvent *event);
+ void paintEvent(QPaintEvent *event);
+ void showEvent(QShowEvent *event);
+ void initStyleOption(QStyleOptionSpinBox *option) const;
+
+ QLineEdit *lineEdit() const;
+ void setLineEdit(QLineEdit *edit);
+
+ virtual StepEnabled stepEnabled() const;
+Q_SIGNALS:
+ void editingFinished();
+protected:
+ QAbstractSpinBox(QAbstractSpinBoxPrivate &dd, QWidget *parent = 0);
+
+private:
+ Q_PRIVATE_SLOT(d_func(), void _q_editorTextChanged(const QString &))
+ Q_PRIVATE_SLOT(d_func(), void _q_editorCursorPositionChanged(int, int))
+
+ Q_DECLARE_PRIVATE(QAbstractSpinBox)
+ Q_DISABLE_COPY(QAbstractSpinBox)
+};
+Q_DECLARE_OPERATORS_FOR_FLAGS(QAbstractSpinBox::StepEnabled)
+
+#endif // QT_NO_SPINBOX
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QABSTRACTSPINBOX_H
diff --git a/src/widgets/widgets/qabstractspinbox_p.h b/src/widgets/widgets/qabstractspinbox_p.h
new file mode 100644
index 0000000000..33d4e32875
--- /dev/null
+++ b/src/widgets/widgets/qabstractspinbox_p.h
@@ -0,0 +1,170 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QABSTRACTSPINBOX_P_H
+#define QABSTRACTSPINBOX_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "QtWidgets/qabstractspinbox.h"
+
+#ifndef QT_NO_SPINBOX
+
+#include "QtWidgets/qlineedit.h"
+#include "QtWidgets/qstyleoption.h"
+#include "QtGui/qvalidator.h"
+#include "QtCore/qdatetime.h"
+#include "QtCore/qvariant.h"
+#include "private/qwidget_p.h"
+#include "private/qdatetime_p.h"
+
+QT_BEGIN_NAMESPACE
+
+QVariant operator+(const QVariant &arg1, const QVariant &arg2);
+QVariant operator-(const QVariant &arg1, const QVariant &arg2);
+QVariant operator*(const QVariant &arg1, double multiplier);
+double operator/(const QVariant &arg1, const QVariant &arg2);
+
+enum EmitPolicy {
+ EmitIfChanged,
+ AlwaysEmit,
+ NeverEmit
+};
+
+enum Button {
+ None = 0x000,
+ Keyboard = 0x001,
+ Mouse = 0x002,
+ Wheel = 0x004,
+ ButtonMask = 0x008,
+ Up = 0x010,
+ Down = 0x020,
+ DirectionMask = 0x040
+};
+class QSpinBoxValidator;
+class QAbstractSpinBoxPrivate : public QWidgetPrivate
+{
+ Q_DECLARE_PUBLIC(QAbstractSpinBox)
+public:
+ QAbstractSpinBoxPrivate();
+ ~QAbstractSpinBoxPrivate();
+
+ void init();
+ void reset();
+ void updateState(bool up, bool fromKeyboard = false);
+ QString stripped(const QString &text, int *pos = 0) const;
+ bool specialValue() const;
+ virtual QVariant getZeroVariant() const;
+ virtual void setRange(const QVariant &min, const QVariant &max);
+ void setValue(const QVariant &val, EmitPolicy ep, bool updateEdit = true);
+ virtual QVariant bound(const QVariant &val, const QVariant &old = QVariant(), int steps = 0) const;
+ virtual void updateEdit();
+
+ virtual void emitSignals(EmitPolicy ep, const QVariant &old);
+ virtual void interpret(EmitPolicy ep);
+ virtual QString textFromValue(const QVariant &n) const;
+ virtual QVariant valueFromText(const QString &input) const;
+
+ void _q_editorTextChanged(const QString &);
+ virtual void _q_editorCursorPositionChanged(int oldpos, int newpos);
+
+ virtual QStyle::SubControl newHoverControl(const QPoint &pos);
+ bool updateHoverControl(const QPoint &pos);
+
+ virtual void clearCache() const;
+ virtual void updateEditFieldGeometry();
+
+ static int variantCompare(const QVariant &arg1, const QVariant &arg2);
+ static QVariant variantBound(const QVariant &min, const QVariant &value, const QVariant &max);
+
+ QLineEdit *edit;
+ QString prefix, suffix, specialValueText;
+ QVariant value, minimum, maximum, singleStep;
+ QVariant::Type type;
+ int spinClickTimerId, spinClickTimerInterval, spinClickThresholdTimerId, spinClickThresholdTimerInterval;
+ int effectiveSpinRepeatRate;
+ uint buttonState;
+ mutable QString cachedText;
+ mutable QVariant cachedValue;
+ mutable QValidator::State cachedState;
+ mutable QSize cachedSizeHint, cachedMinimumSizeHint;
+ uint pendingEmit : 1;
+ uint readOnly : 1;
+ uint wrapping : 1;
+ uint ignoreCursorPositionChanged : 1;
+ uint frame : 1;
+ uint accelerate : 1;
+ uint keyboardTracking : 1;
+ uint cleared : 1;
+ uint ignoreUpdateEdit : 1;
+ QAbstractSpinBox::CorrectionMode correctionMode;
+ int acceleration;
+ QStyle::SubControl hoverControl;
+ QRect hoverRect;
+ QAbstractSpinBox::ButtonSymbols buttonSymbols;
+ QSpinBoxValidator *validator;
+};
+
+class QSpinBoxValidator : public QValidator
+{
+public:
+ QSpinBoxValidator(QAbstractSpinBox *qptr, QAbstractSpinBoxPrivate *dptr);
+ QValidator::State validate(QString &input, int &) const;
+ void fixup(QString &) const;
+private:
+ QAbstractSpinBox *qptr;
+ QAbstractSpinBoxPrivate *dptr;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_SPINBOX
+
+#endif // QABSTRACTSPINBOX_P_H
diff --git a/src/gui/widgets/qbuttongroup.cpp b/src/widgets/widgets/qbuttongroup.cpp
index 1caa33f2f7..1caa33f2f7 100644
--- a/src/gui/widgets/qbuttongroup.cpp
+++ b/src/widgets/widgets/qbuttongroup.cpp
diff --git a/src/widgets/widgets/qbuttongroup.h b/src/widgets/widgets/qbuttongroup.h
new file mode 100644
index 0000000000..e3ef34644e
--- /dev/null
+++ b/src/widgets/widgets/qbuttongroup.h
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QBUTTONGROUP_H
+#define QBUTTONGROUP_H
+
+#include <QtCore/qobject.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_BUTTONGROUP
+
+class QAbstractButton;
+class QAbstractButtonPrivate;
+class QButtonGroupPrivate;
+
+class Q_WIDGETS_EXPORT QButtonGroup : public QObject
+{
+ Q_OBJECT
+
+ Q_PROPERTY(bool exclusive READ exclusive WRITE setExclusive)
+public:
+ explicit QButtonGroup(QObject *parent = 0);
+ ~QButtonGroup();
+
+ void setExclusive(bool);
+ bool exclusive() const;
+
+ void addButton(QAbstractButton *);
+ void addButton(QAbstractButton *, int id);
+ void removeButton(QAbstractButton *);
+
+ QList<QAbstractButton*> buttons() const;
+
+ QAbstractButton * checkedButton() const;
+ // no setter on purpose!
+
+ QAbstractButton *button(int id) const;
+ void setId(QAbstractButton *button, int id);
+ int id(QAbstractButton *button) const;
+ int checkedId() const;
+
+Q_SIGNALS:
+ void buttonClicked(QAbstractButton *);
+ void buttonClicked(int);
+ void buttonPressed(QAbstractButton *);
+ void buttonPressed(int);
+ void buttonReleased(QAbstractButton *);
+ void buttonReleased(int);
+
+#ifdef QT3_SUPPORT
+public:
+ inline QT3_SUPPORT void insert(QAbstractButton *b) { addButton(b); }
+ inline QT3_SUPPORT void remove(QAbstractButton *b) { removeButton(b); }
+#endif
+
+private:
+ Q_DISABLE_COPY(QButtonGroup)
+ Q_DECLARE_PRIVATE(QButtonGroup)
+ friend class QAbstractButton;
+ friend class QAbstractButtonPrivate;
+};
+
+#endif // QT_NO_BUTTONGROUP
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QBUTTONGROUP_H
diff --git a/src/gui/widgets/qcalendartextnavigator_p.h b/src/widgets/widgets/qcalendartextnavigator_p.h
index b602c6d51e..b602c6d51e 100644
--- a/src/gui/widgets/qcalendartextnavigator_p.h
+++ b/src/widgets/widgets/qcalendartextnavigator_p.h
diff --git a/src/gui/widgets/qcalendarwidget.cpp b/src/widgets/widgets/qcalendarwidget.cpp
index 583e163cee..583e163cee 100644
--- a/src/gui/widgets/qcalendarwidget.cpp
+++ b/src/widgets/widgets/qcalendarwidget.cpp
diff --git a/src/widgets/widgets/qcalendarwidget.h b/src/widgets/widgets/qcalendarwidget.h
new file mode 100644
index 0000000000..a80bae2f49
--- /dev/null
+++ b/src/widgets/widgets/qcalendarwidget.h
@@ -0,0 +1,204 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCALENDARWIDGET_H
+#define QCALENDARWIDGET_H
+
+#include <QtWidgets/qwidget.h>
+#include <QtCore/qdatetime.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_CALENDARWIDGET
+
+class QDate;
+class QTextCharFormat;
+class QCalendarWidgetPrivate;
+
+class Q_WIDGETS_EXPORT QCalendarWidget : public QWidget
+{
+ Q_OBJECT
+ Q_ENUMS(Qt::DayOfWeek)
+ Q_ENUMS(HorizontalHeaderFormat)
+ Q_ENUMS(VerticalHeaderFormat)
+ Q_ENUMS(SelectionMode)
+ Q_PROPERTY(QDate selectedDate READ selectedDate WRITE setSelectedDate)
+ Q_PROPERTY(QDate minimumDate READ minimumDate WRITE setMinimumDate)
+ Q_PROPERTY(QDate maximumDate READ maximumDate WRITE setMaximumDate)
+ Q_PROPERTY(Qt::DayOfWeek firstDayOfWeek READ firstDayOfWeek WRITE setFirstDayOfWeek)
+ Q_PROPERTY(bool gridVisible READ isGridVisible WRITE setGridVisible)
+ Q_PROPERTY(SelectionMode selectionMode READ selectionMode WRITE setSelectionMode)
+ Q_PROPERTY(HorizontalHeaderFormat horizontalHeaderFormat READ horizontalHeaderFormat WRITE setHorizontalHeaderFormat)
+ Q_PROPERTY(VerticalHeaderFormat verticalHeaderFormat READ verticalHeaderFormat WRITE setVerticalHeaderFormat)
+ Q_PROPERTY(bool headerVisible READ isHeaderVisible WRITE setHeaderVisible STORED false DESIGNABLE false) // obsolete
+ Q_PROPERTY(bool navigationBarVisible READ isNavigationBarVisible WRITE setNavigationBarVisible)
+ Q_PROPERTY(bool dateEditEnabled READ isDateEditEnabled WRITE setDateEditEnabled)
+ Q_PROPERTY(int dateEditAcceptDelay READ dateEditAcceptDelay WRITE setDateEditAcceptDelay)
+
+public:
+ enum HorizontalHeaderFormat {
+ NoHorizontalHeader,
+ SingleLetterDayNames,
+ ShortDayNames,
+ LongDayNames
+ };
+
+ enum VerticalHeaderFormat {
+ NoVerticalHeader,
+ ISOWeekNumbers
+ };
+
+ enum SelectionMode {
+ NoSelection,
+ SingleSelection
+ };
+
+ explicit QCalendarWidget(QWidget *parent = 0);
+ ~QCalendarWidget();
+
+ virtual QSize sizeHint() const;
+ virtual QSize minimumSizeHint() const;
+
+ QDate selectedDate() const;
+
+ int yearShown() const;
+ int monthShown() const;
+
+ QDate minimumDate() const;
+ void setMinimumDate(const QDate &date);
+
+ QDate maximumDate() const;
+ void setMaximumDate(const QDate &date);
+
+ Qt::DayOfWeek firstDayOfWeek() const;
+ void setFirstDayOfWeek(Qt::DayOfWeek dayOfWeek);
+
+ // ### Qt 5: eliminate these two
+ bool isHeaderVisible() const;
+ void setHeaderVisible(bool show);
+
+ inline bool isNavigationBarVisible() const { return isHeaderVisible(); }
+
+ bool isGridVisible() const;
+
+ SelectionMode selectionMode() const;
+ void setSelectionMode(SelectionMode mode);
+
+ HorizontalHeaderFormat horizontalHeaderFormat() const;
+ void setHorizontalHeaderFormat(HorizontalHeaderFormat format);
+
+ VerticalHeaderFormat verticalHeaderFormat() const;
+ void setVerticalHeaderFormat(VerticalHeaderFormat format);
+
+ QTextCharFormat headerTextFormat() const;
+ void setHeaderTextFormat(const QTextCharFormat &format);
+
+ QTextCharFormat weekdayTextFormat(Qt::DayOfWeek dayOfWeek) const;
+ void setWeekdayTextFormat(Qt::DayOfWeek dayOfWeek, const QTextCharFormat &format);
+
+ QMap<QDate, QTextCharFormat> dateTextFormat() const;
+ QTextCharFormat dateTextFormat(const QDate &date) const;
+ void setDateTextFormat(const QDate &date, const QTextCharFormat &format);
+
+ bool isDateEditEnabled() const;
+ void setDateEditEnabled(bool enable);
+
+ int dateEditAcceptDelay() const;
+ void setDateEditAcceptDelay(int delay);
+
+protected:
+ bool event(QEvent *event);
+ bool eventFilter(QObject *watched, QEvent *event);
+ void mousePressEvent(QMouseEvent *event);
+ void resizeEvent(QResizeEvent * event);
+ void keyPressEvent(QKeyEvent * event);
+
+ virtual void paintCell(QPainter *painter, const QRect &rect, const QDate &date) const;
+ void updateCell(const QDate &date);
+ void updateCells();
+
+public Q_SLOTS:
+ void setSelectedDate(const QDate &date);
+ void setDateRange(const QDate &min, const QDate &max);
+ void setCurrentPage(int year, int month);
+ void setGridVisible(bool show);
+ void setNavigationBarVisible(bool visible);
+ void showNextMonth();
+ void showPreviousMonth();
+ void showNextYear();
+ void showPreviousYear();
+ void showSelectedDate();
+ void showToday();
+
+Q_SIGNALS:
+ void selectionChanged();
+ void clicked(const QDate &date);
+ void activated(const QDate &date);
+ void currentPageChanged(int year, int month);
+
+private:
+ Q_DECLARE_PRIVATE(QCalendarWidget)
+ Q_DISABLE_COPY(QCalendarWidget)
+
+ Q_PRIVATE_SLOT(d_func(), void _q_slotShowDate(const QDate &date))
+ Q_PRIVATE_SLOT(d_func(), void _q_slotChangeDate(const QDate &date))
+ Q_PRIVATE_SLOT(d_func(), void _q_slotChangeDate(const QDate &date, bool changeMonth))
+ Q_PRIVATE_SLOT(d_func(), void _q_editingFinished())
+ Q_PRIVATE_SLOT(d_func(), void _q_prevMonthClicked())
+ Q_PRIVATE_SLOT(d_func(), void _q_nextMonthClicked())
+ Q_PRIVATE_SLOT(d_func(), void _q_yearEditingFinished())
+ Q_PRIVATE_SLOT(d_func(), void _q_yearClicked())
+ Q_PRIVATE_SLOT(d_func(), void _q_monthChanged(QAction *act))
+
+};
+
+#endif // QT_NO_CALENDARWIDGET
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QCALENDARWIDGET_H
+
diff --git a/src/gui/widgets/qcheckbox.cpp b/src/widgets/widgets/qcheckbox.cpp
index c6d1317147..c6d1317147 100644
--- a/src/gui/widgets/qcheckbox.cpp
+++ b/src/widgets/widgets/qcheckbox.cpp
diff --git a/src/widgets/widgets/qcheckbox.h b/src/widgets/widgets/qcheckbox.h
new file mode 100644
index 0000000000..b040b13be1
--- /dev/null
+++ b/src/widgets/widgets/qcheckbox.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCHECKBOX_H
+#define QCHECKBOX_H
+
+#include <QtWidgets/qabstractbutton.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QCheckBoxPrivate;
+class QStyleOptionButton;
+
+class Q_WIDGETS_EXPORT QCheckBox : public QAbstractButton
+{
+ Q_OBJECT
+
+ Q_PROPERTY(bool tristate READ isTristate WRITE setTristate)
+
+public:
+ explicit QCheckBox(QWidget *parent=0);
+ explicit QCheckBox(const QString &text, QWidget *parent=0);
+
+
+ QSize sizeHint() const;
+ QSize minimumSizeHint() const;
+
+ void setTristate(bool y = true);
+ bool isTristate() const;
+
+ Qt::CheckState checkState() const;
+ void setCheckState(Qt::CheckState state);
+
+Q_SIGNALS:
+ void stateChanged(int);
+
+protected:
+ bool event(QEvent *e);
+ bool hitButton(const QPoint &pos) const;
+ void checkStateSet();
+ void nextCheckState();
+ void paintEvent(QPaintEvent *);
+ void mouseMoveEvent(QMouseEvent *);
+ void initStyleOption(QStyleOptionButton *option) const;
+
+#ifdef QT3_SUPPORT
+public:
+ enum ToggleState {
+ Off = Qt::Unchecked,
+ NoChange = Qt::PartiallyChecked,
+ On = Qt::Checked
+ };
+ inline QT3_SUPPORT ToggleState state() const
+ { return static_cast<QCheckBox::ToggleState>(static_cast<int>(checkState())); }
+ inline QT3_SUPPORT void setState(ToggleState state)
+ { setCheckState(static_cast<Qt::CheckState>(static_cast<int>(state))); }
+ inline QT3_SUPPORT void setNoChange()
+ { setCheckState(Qt::PartiallyChecked); }
+ QT3_SUPPORT_CONSTRUCTOR QCheckBox(QWidget *parent, const char* name);
+ QT3_SUPPORT_CONSTRUCTOR QCheckBox(const QString &text, QWidget *parent, const char* name);
+#endif
+
+private:
+ Q_DECLARE_PRIVATE(QCheckBox)
+ Q_DISABLE_COPY(QCheckBox)
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QCHECKBOX_H
diff --git a/src/gui/widgets/qcocoatoolbardelegate_mac.mm b/src/widgets/widgets/qcocoatoolbardelegate_mac.mm
index 2ced5b3665..2ced5b3665 100644
--- a/src/gui/widgets/qcocoatoolbardelegate_mac.mm
+++ b/src/widgets/widgets/qcocoatoolbardelegate_mac.mm
diff --git a/src/gui/widgets/qcocoatoolbardelegate_mac_p.h b/src/widgets/widgets/qcocoatoolbardelegate_mac_p.h
index 813d278392..813d278392 100644
--- a/src/gui/widgets/qcocoatoolbardelegate_mac_p.h
+++ b/src/widgets/widgets/qcocoatoolbardelegate_mac_p.h
diff --git a/src/gui/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp
index 650227214a..650227214a 100644
--- a/src/gui/widgets/qcombobox.cpp
+++ b/src/widgets/widgets/qcombobox.cpp
diff --git a/src/widgets/widgets/qcombobox.h b/src/widgets/widgets/qcombobox.h
new file mode 100644
index 0000000000..ed766cc004
--- /dev/null
+++ b/src/widgets/widgets/qcombobox.h
@@ -0,0 +1,339 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCOMBOBOX_H
+#define QCOMBOBOX_H
+
+#include <QtWidgets/qwidget.h>
+#include <QtWidgets/qabstractitemdelegate.h>
+#include <QtCore/qabstractitemmodel.h>
+#include <QtCore/qvariant.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+#ifndef QT_NO_COMBOBOX
+
+class QAbstractItemView;
+class QLineEdit;
+class QComboBoxPrivate;
+class QCompleter;
+
+class Q_WIDGETS_EXPORT QComboBox : public QWidget
+{
+ Q_OBJECT
+
+ Q_ENUMS(InsertPolicy)
+ Q_ENUMS(SizeAdjustPolicy)
+ Q_PROPERTY(bool editable READ isEditable WRITE setEditable)
+ Q_PROPERTY(int count READ count)
+ Q_PROPERTY(QString currentText READ currentText)
+ Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged USER true)
+ Q_PROPERTY(int maxVisibleItems READ maxVisibleItems WRITE setMaxVisibleItems)
+ Q_PROPERTY(int maxCount READ maxCount WRITE setMaxCount)
+ Q_PROPERTY(InsertPolicy insertPolicy READ insertPolicy WRITE setInsertPolicy)
+ Q_PROPERTY(SizeAdjustPolicy sizeAdjustPolicy READ sizeAdjustPolicy WRITE setSizeAdjustPolicy)
+ Q_PROPERTY(int minimumContentsLength READ minimumContentsLength WRITE setMinimumContentsLength)
+ Q_PROPERTY(QSize iconSize READ iconSize WRITE setIconSize)
+
+#ifndef QT_NO_COMPLETER
+ Q_PROPERTY(bool autoCompletion READ autoCompletion WRITE setAutoCompletion DESIGNABLE false)
+ Q_PROPERTY(Qt::CaseSensitivity autoCompletionCaseSensitivity READ autoCompletionCaseSensitivity WRITE setAutoCompletionCaseSensitivity DESIGNABLE false)
+#endif // QT_NO_COMPLETER
+
+ Q_PROPERTY(bool duplicatesEnabled READ duplicatesEnabled WRITE setDuplicatesEnabled)
+ Q_PROPERTY(bool frame READ hasFrame WRITE setFrame)
+ Q_PROPERTY(int modelColumn READ modelColumn WRITE setModelColumn)
+
+public:
+ explicit QComboBox(QWidget *parent = 0);
+ ~QComboBox();
+
+ int maxVisibleItems() const;
+ void setMaxVisibleItems(int maxItems);
+
+ int count() const;
+ void setMaxCount(int max);
+ int maxCount() const;
+
+#ifndef QT_NO_COMPLETER
+ bool autoCompletion() const;
+ void setAutoCompletion(bool enable);
+
+ Qt::CaseSensitivity autoCompletionCaseSensitivity() const;
+ void setAutoCompletionCaseSensitivity(Qt::CaseSensitivity sensitivity);
+#endif
+
+ bool duplicatesEnabled() const;
+ void setDuplicatesEnabled(bool enable);
+
+ void setFrame(bool);
+ bool hasFrame() const;
+
+ inline int findText(const QString &text,
+ Qt::MatchFlags flags = static_cast<Qt::MatchFlags>(Qt::MatchExactly|Qt::MatchCaseSensitive)) const
+ { return findData(text, Qt::DisplayRole, flags); }
+ int findData(const QVariant &data, int role = Qt::UserRole,
+ Qt::MatchFlags flags = static_cast<Qt::MatchFlags>(Qt::MatchExactly|Qt::MatchCaseSensitive)) const;
+
+ enum InsertPolicy {
+ NoInsert,
+ InsertAtTop,
+ InsertAtCurrent,
+ InsertAtBottom,
+ InsertAfterCurrent,
+ InsertBeforeCurrent,
+ InsertAlphabetically
+#if defined(QT3_SUPPORT) && !defined(Q_MOC_RUN)
+ ,
+ NoInsertion = NoInsert,
+ AtTop = InsertAtTop,
+ AtCurrent = InsertAtCurrent,
+ AtBottom = InsertAtBottom,
+ AfterCurrent = InsertAfterCurrent,
+ BeforeCurrent = InsertBeforeCurrent
+#endif
+ };
+#ifdef QT3_SUPPORT
+ typedef InsertPolicy Policy;
+#endif
+
+ InsertPolicy insertPolicy() const;
+ void setInsertPolicy(InsertPolicy policy);
+
+ enum SizeAdjustPolicy {
+ AdjustToContents,
+ AdjustToContentsOnFirstShow,
+ AdjustToMinimumContentsLength, // ### Qt 5: remove
+ AdjustToMinimumContentsLengthWithIcon
+ };
+
+ SizeAdjustPolicy sizeAdjustPolicy() const;
+ void setSizeAdjustPolicy(SizeAdjustPolicy policy);
+ int minimumContentsLength() const;
+ void setMinimumContentsLength(int characters);
+ QSize iconSize() const;
+ void setIconSize(const QSize &size);
+
+ bool isEditable() const;
+ void setEditable(bool editable);
+ void setLineEdit(QLineEdit *edit);
+ QLineEdit *lineEdit() const;
+#ifndef QT_NO_VALIDATOR
+ void setValidator(const QValidator *v);
+ const QValidator *validator() const;
+#endif
+
+#ifndef QT_NO_COMPLETER
+ void setCompleter(QCompleter *c);
+ QCompleter *completer() const;
+#endif
+
+ QAbstractItemDelegate *itemDelegate() const;
+ void setItemDelegate(QAbstractItemDelegate *delegate);
+
+ QAbstractItemModel *model() const;
+ void setModel(QAbstractItemModel *model);
+
+ QModelIndex rootModelIndex() const;
+ void setRootModelIndex(const QModelIndex &index);
+
+ int modelColumn() const;
+ void setModelColumn(int visibleColumn);
+
+ int currentIndex() const;
+
+ QString currentText() const;
+
+ QString itemText(int index) const;
+ QIcon itemIcon(int index) const;
+ QVariant itemData(int index, int role = Qt::UserRole) const;
+
+ inline void addItem(const QString &text, const QVariant &userData = QVariant());
+ inline void addItem(const QIcon &icon, const QString &text,
+ const QVariant &userData = QVariant());
+ inline void addItems(const QStringList &texts)
+ { insertItems(count(), texts); }
+
+ inline void insertItem(int index, const QString &text, const QVariant &userData = QVariant());
+ void insertItem(int index, const QIcon &icon, const QString &text,
+ const QVariant &userData = QVariant());
+ void insertItems(int index, const QStringList &texts);
+ void insertSeparator(int index);
+
+ void removeItem(int index);
+
+ void setItemText(int index, const QString &text);
+ void setItemIcon(int index, const QIcon &icon);
+ void setItemData(int index, const QVariant &value, int role = Qt::UserRole);
+
+ QAbstractItemView *view() const;
+ void setView(QAbstractItemView *itemView);
+
+ QSize sizeHint() const;
+ QSize minimumSizeHint() const;
+
+ virtual void showPopup();
+ virtual void hidePopup();
+
+ bool event(QEvent *event);
+
+public Q_SLOTS:
+ void clear();
+ void clearEditText();
+ void setEditText(const QString &text);
+ void setCurrentIndex(int index);
+
+Q_SIGNALS:
+ void editTextChanged(const QString &);
+ void activated(int index);
+ void activated(const QString &);
+ void highlighted(int index);
+ void highlighted(const QString &);
+ void currentIndexChanged(int index);
+ void currentIndexChanged(const QString &);
+
+protected:
+ void focusInEvent(QFocusEvent *e);
+ void focusOutEvent(QFocusEvent *e);
+ void changeEvent(QEvent *e);
+ void resizeEvent(QResizeEvent *e);
+ void paintEvent(QPaintEvent *e);
+ void showEvent(QShowEvent *e);
+ void hideEvent(QHideEvent *e);
+ void mousePressEvent(QMouseEvent *e);
+ void mouseReleaseEvent(QMouseEvent *e);
+ void keyPressEvent(QKeyEvent *e);
+ void keyReleaseEvent(QKeyEvent *e);
+#ifndef QT_NO_WHEELEVENT
+ void wheelEvent(QWheelEvent *e);
+#endif
+ void contextMenuEvent(QContextMenuEvent *e);
+ void inputMethodEvent(QInputMethodEvent *);
+ QVariant inputMethodQuery(Qt::InputMethodQuery) const;
+ void initStyleOption(QStyleOptionComboBox *option) const;
+
+#ifdef QT3_SUPPORT
+public:
+ QT3_SUPPORT_CONSTRUCTOR QComboBox(QWidget *parent, const char *name);
+ QT3_SUPPORT_CONSTRUCTOR QComboBox(bool rw, QWidget *parent, const char *name = 0);
+ inline QT3_SUPPORT int currentItem() const { return currentIndex(); }
+ inline QT3_SUPPORT void setCurrentItem(int index) { setCurrentIndex(index); }
+ inline QT3_SUPPORT InsertPolicy insertionPolicy() const { return insertPolicy(); }
+ inline QT3_SUPPORT void setInsertionPolicy(InsertPolicy policy) { setInsertPolicy(policy); }
+ inline QT3_SUPPORT bool editable() const { return isEditable(); }
+ inline QT3_SUPPORT void popup() { showPopup(); }
+ inline QT3_SUPPORT void setCurrentText(const QString& text) {
+ int i = findText(text);
+ if (i != -1)
+ setCurrentIndex(i);
+ else if (isEditable())
+ setEditText(text);
+ else
+ setItemText(currentIndex(), text);
+ }
+ inline QT3_SUPPORT QString text(int index) const { return itemText(index); }
+
+ inline QT3_SUPPORT QPixmap pixmap(int index) const
+ { return itemIcon(index).pixmap(iconSize(), isEnabled() ? QIcon::Normal : QIcon::Disabled); }
+ inline QT3_SUPPORT void insertStringList(const QStringList &list, int index = -1)
+ { insertItems((index < 0 ? count() : index), list); }
+ inline QT3_SUPPORT void insertItem(const QString &text, int index = -1)
+ { insertItem((index < 0 ? count() : index), text); }
+ inline QT3_SUPPORT void insertItem(const QPixmap &pix, int index = -1)
+ { insertItem((index < 0 ? count() : index), QIcon(pix), QString()); }
+ inline QT3_SUPPORT void insertItem(const QPixmap &pix, const QString &text, int index = -1)
+ { insertItem((index < 0 ? count() : index), QIcon(pix), text); }
+ inline QT3_SUPPORT void changeItem(const QString &text, int index)
+ { setItemText(index, text); }
+ inline QT3_SUPPORT void changeItem(const QPixmap &pix, int index)
+ { setItemIcon(index, QIcon(pix)); }
+ inline QT3_SUPPORT void changeItem(const QPixmap &pix, const QString &text, int index)
+ { setItemIcon(index, QIcon(pix)); setItemText(index, text); }
+ inline QT3_SUPPORT void clearValidator() { setValidator(0); }
+ inline QT3_SUPPORT void clearEdit() { clearEditText(); }
+
+Q_SIGNALS:
+ QT_MOC_COMPAT void textChanged(const QString &);
+#endif
+
+protected:
+ QComboBox(QComboBoxPrivate &, QWidget *);
+
+private:
+ Q_DECLARE_PRIVATE(QComboBox)
+ Q_DISABLE_COPY(QComboBox)
+ Q_PRIVATE_SLOT(d_func(), void _q_itemSelected(const QModelIndex &item))
+ Q_PRIVATE_SLOT(d_func(), void _q_emitHighlighted(const QModelIndex &))
+ Q_PRIVATE_SLOT(d_func(), void _q_emitCurrentIndexChanged(const QModelIndex &index))
+ Q_PRIVATE_SLOT(d_func(), void _q_editingFinished())
+ Q_PRIVATE_SLOT(d_func(), void _q_returnPressed())
+ Q_PRIVATE_SLOT(d_func(), void _q_resetButton())
+ Q_PRIVATE_SLOT(d_func(), void _q_dataChanged(const QModelIndex &, const QModelIndex &))
+ Q_PRIVATE_SLOT(d_func(), void _q_updateIndexBeforeChange())
+ Q_PRIVATE_SLOT(d_func(), void _q_rowsInserted(const QModelIndex & parent, int start, int end))
+ Q_PRIVATE_SLOT(d_func(), void _q_rowsRemoved(const QModelIndex & parent, int start, int end))
+ Q_PRIVATE_SLOT(d_func(), void _q_modelDestroyed())
+ Q_PRIVATE_SLOT(d_func(), void _q_modelReset())
+#ifdef QT_KEYPAD_NAVIGATION
+ Q_PRIVATE_SLOT(d_func(), void _q_completerActivated())
+#endif
+};
+
+inline void QComboBox::addItem(const QString &atext, const QVariant &auserData)
+{ insertItem(count(), atext, auserData); }
+inline void QComboBox::addItem(const QIcon &aicon, const QString &atext,
+ const QVariant &auserData)
+{ insertItem(count(), aicon, atext, auserData); }
+
+inline void QComboBox::insertItem(int aindex, const QString &atext,
+ const QVariant &auserData)
+{ insertItem(aindex, QIcon(), atext, auserData); }
+
+#endif // QT_NO_COMBOBOX
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QCOMBOBOX_H
diff --git a/src/widgets/widgets/qcombobox_p.h b/src/widgets/widgets/qcombobox_p.h
new file mode 100644
index 0000000000..2d3f261d6e
--- /dev/null
+++ b/src/widgets/widgets/qcombobox_p.h
@@ -0,0 +1,421 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCOMBOBOX_P_H
+#define QCOMBOBOX_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "QtWidgets/qcombobox.h"
+
+#ifndef QT_NO_COMBOBOX
+#include "QtWidgets/qabstractslider.h"
+#include "QtWidgets/qapplication.h"
+#include "QtWidgets/qitemdelegate.h"
+#include "QtWidgets/qstandarditemmodel.h"
+#include "QtWidgets/qlineedit.h"
+#include "QtWidgets/qlistview.h"
+#include "QtGui/qpainter.h"
+#include "QtWidgets/qstyle.h"
+#include "QtWidgets/qstyleoption.h"
+#include "QtCore/qhash.h"
+#include "QtCore/qpair.h"
+#include "QtCore/qtimer.h"
+#include "private/qwidget_p.h"
+#include "QtCore/qpointer.h"
+#include "QtWidgets/qcompleter.h"
+#include "QtGui/qevent.h"
+#include "QtCore/qdebug.h"
+
+#include <limits.h>
+
+QT_BEGIN_NAMESPACE
+
+class QAction;
+
+class QComboBoxListView : public QListView
+{
+ Q_OBJECT
+public:
+ QComboBoxListView(QComboBox *cmb = 0) : combo(cmb) {}
+
+protected:
+ void resizeEvent(QResizeEvent *event)
+ {
+ resizeContents(viewport()->width(), contentsSize().height());
+ QListView::resizeEvent(event);
+ }
+
+ QStyleOptionViewItem viewOptions() const
+ {
+ QStyleOptionViewItem option = QListView::viewOptions();
+ option.showDecorationSelected = true;
+ if (combo)
+ option.font = combo->font();
+ return option;
+ }
+
+ void paintEvent(QPaintEvent *e)
+ {
+ if (combo) {
+ QStyleOptionComboBox opt;
+ opt.initFrom(combo);
+ opt.editable = combo->isEditable();
+ if (combo->style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, combo)) {
+ //we paint the empty menu area to avoid having blank space that can happen when scrolling
+ QStyleOptionMenuItem menuOpt;
+ menuOpt.initFrom(this);
+ menuOpt.palette = palette();
+ menuOpt.state = QStyle::State_None;
+ menuOpt.checkType = QStyleOptionMenuItem::NotCheckable;
+ menuOpt.menuRect = e->rect();
+ menuOpt.maxIconWidth = 0;
+ menuOpt.tabWidth = 0;
+ QPainter p(viewport());
+ combo->style()->drawControl(QStyle::CE_MenuEmptyArea, &menuOpt, &p, this);
+ }
+ }
+ QListView::paintEvent(e);
+ }
+
+private:
+ QComboBox *combo;
+};
+
+
+class QStandardItemModel;
+
+class Q_AUTOTEST_EXPORT QComboBoxPrivateScroller : public QWidget
+{
+ Q_OBJECT
+
+public:
+ QComboBoxPrivateScroller(QAbstractSlider::SliderAction action, QWidget *parent)
+ : QWidget(parent), sliderAction(action)
+ {
+ setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
+ setAttribute(Qt::WA_NoMousePropagation);
+ }
+ QSize sizeHint() const {
+ return QSize(20, style()->pixelMetric(QStyle::PM_MenuScrollerHeight));
+ }
+
+protected:
+ inline void stopTimer() {
+ timer.stop();
+ }
+
+ inline void startTimer() {
+ timer.start(100, this);
+ fast = false;
+ }
+
+ void enterEvent(QEvent *) {
+ startTimer();
+ }
+
+ void leaveEvent(QEvent *) {
+ stopTimer();
+ }
+ void timerEvent(QTimerEvent *e) {
+ if (e->timerId() == timer.timerId()) {
+ emit doScroll(sliderAction);
+ if (fast) {
+ emit doScroll(sliderAction);
+ emit doScroll(sliderAction);
+ }
+ }
+ }
+ void hideEvent(QHideEvent *) {
+ stopTimer();
+ }
+
+ void mouseMoveEvent(QMouseEvent *e)
+ {
+ // Enable fast scrolling if the cursor is directly above or below the popup.
+ const int mouseX = e->pos().x();
+ const int mouseY = e->pos().y();
+ const bool horizontallyInside = pos().x() < mouseX && mouseX < rect().right() + 1;
+ const bool verticallyOutside = (sliderAction == QAbstractSlider::SliderSingleStepAdd) ?
+ rect().bottom() + 1 < mouseY : mouseY < pos().y();
+
+ fast = horizontallyInside && verticallyOutside;
+ }
+
+ void paintEvent(QPaintEvent *) {
+ QPainter p(this);
+ QStyleOptionMenuItem menuOpt;
+ menuOpt.init(this);
+ menuOpt.checkType = QStyleOptionMenuItem::NotCheckable;
+ menuOpt.menuRect = rect();
+ menuOpt.maxIconWidth = 0;
+ menuOpt.tabWidth = 0;
+ menuOpt.menuItemType = QStyleOptionMenuItem::Scroller;
+ if (sliderAction == QAbstractSlider::SliderSingleStepAdd)
+ menuOpt.state |= QStyle::State_DownArrow;
+#ifndef Q_WS_S60
+ p.eraseRect(rect());
+#endif
+ style()->drawControl(QStyle::CE_MenuScroller, &menuOpt, &p);
+ }
+
+Q_SIGNALS:
+ void doScroll(int action);
+
+private:
+ QAbstractSlider::SliderAction sliderAction;
+ QBasicTimer timer;
+ bool fast;
+};
+
+class Q_AUTOTEST_EXPORT QComboBoxPrivateContainer : public QFrame
+{
+ Q_OBJECT
+
+public:
+ QComboBoxPrivateContainer(QAbstractItemView *itemView, QComboBox *parent);
+ QAbstractItemView *itemView() const;
+ void setItemView(QAbstractItemView *itemView);
+ int spacing() const;
+ void updateTopBottomMargin();
+
+ QTimer blockMouseReleaseTimer;
+ QBasicTimer adjustSizeTimer;
+ QPoint initialClickPosition;
+
+public Q_SLOTS:
+ void scrollItemView(int action);
+ void updateScrollers();
+ void viewDestroyed();
+
+protected:
+ void changeEvent(QEvent *e);
+ bool eventFilter(QObject *o, QEvent *e);
+ void mousePressEvent(QMouseEvent *e);
+ void mouseReleaseEvent(QMouseEvent *e);
+ void showEvent(QShowEvent *e);
+ void hideEvent(QHideEvent *e);
+ void timerEvent(QTimerEvent *timerEvent);
+ void leaveEvent(QEvent *e);
+ void resizeEvent(QResizeEvent *e);
+ QStyleOptionComboBox comboStyleOption() const;
+
+Q_SIGNALS:
+ void itemSelected(const QModelIndex &);
+ void resetButton();
+
+private:
+ QComboBox *combo;
+ QAbstractItemView *view;
+ QComboBoxPrivateScroller *top;
+ QComboBoxPrivateScroller *bottom;
+#ifdef QT_SOFTKEYS_ENABLED
+ QAction *selectAction;
+ QAction *cancelAction;
+#endif
+};
+
+class QComboMenuDelegate : public QAbstractItemDelegate
+{ Q_OBJECT
+public:
+ QComboMenuDelegate(QObject *parent, QComboBox *cmb) : QAbstractItemDelegate(parent), mCombo(cmb) {}
+
+protected:
+ void paint(QPainter *painter,
+ const QStyleOptionViewItem &option,
+ const QModelIndex &index) const {
+ QStyleOptionMenuItem opt = getStyleOption(option, index);
+#ifndef Q_WS_S60
+ painter->fillRect(option.rect, opt.palette.background());
+#endif
+ mCombo->style()->drawControl(QStyle::CE_MenuItem, &opt, painter, mCombo);
+ }
+ QSize sizeHint(const QStyleOptionViewItem &option,
+ const QModelIndex &index) const {
+ QStyleOptionMenuItem opt = getStyleOption(option, index);
+ return mCombo->style()->sizeFromContents(
+ QStyle::CT_MenuItem, &opt, option.rect.size(), mCombo);
+ }
+
+private:
+ QStyleOptionMenuItem getStyleOption(const QStyleOptionViewItem &option,
+ const QModelIndex &index) const;
+ QComboBox *mCombo;
+};
+
+// Note that this class is intentionally not using QStyledItemDelegate
+// Vista does not use the new theme for combo boxes and there might
+// be other side effects from using the new class
+class QComboBoxDelegate : public QItemDelegate
+{ Q_OBJECT
+public:
+ QComboBoxDelegate(QObject *parent, QComboBox *cmb) : QItemDelegate(parent), mCombo(cmb) {}
+
+ static bool isSeparator(const QModelIndex &index) {
+ return index.data(Qt::AccessibleDescriptionRole).toString() == QLatin1String("separator");
+ }
+ static void setSeparator(QAbstractItemModel *model, const QModelIndex &index) {
+ model->setData(index, QString::fromLatin1("separator"), Qt::AccessibleDescriptionRole);
+ if (QStandardItemModel *m = qobject_cast<QStandardItemModel*>(model))
+ if (QStandardItem *item = m->itemFromIndex(index))
+ item->setFlags(item->flags() & ~(Qt::ItemIsSelectable|Qt::ItemIsEnabled));
+ }
+
+protected:
+ void paint(QPainter *painter,
+ const QStyleOptionViewItem &option,
+ const QModelIndex &index) const {
+ if (isSeparator(index)) {
+ QRect rect = option.rect;
+ if (const QStyleOptionViewItemV3 *v3 = qstyleoption_cast<const QStyleOptionViewItemV3*>(&option))
+ if (const QAbstractItemView *view = qobject_cast<const QAbstractItemView*>(v3->widget))
+ rect.setWidth(view->viewport()->width());
+ QStyleOption opt;
+ opt.rect = rect;
+ mCombo->style()->drawPrimitive(QStyle::PE_IndicatorToolBarSeparator, &opt, painter, mCombo);
+ } else {
+ QItemDelegate::paint(painter, option, index);
+ }
+ }
+
+ QSize sizeHint(const QStyleOptionViewItem &option,
+ const QModelIndex &index) const {
+ if (isSeparator(index)) {
+ int pm = mCombo->style()->pixelMetric(QStyle::PM_DefaultFrameWidth, 0, mCombo);
+ return QSize(pm, pm);
+ }
+ return QItemDelegate::sizeHint(option, index);
+ }
+private:
+ QComboBox *mCombo;
+};
+
+class Q_AUTOTEST_EXPORT QComboBoxPrivate : public QWidgetPrivate
+{
+ Q_DECLARE_PUBLIC(QComboBox)
+public:
+ QComboBoxPrivate();
+ ~QComboBoxPrivate() {}
+ void init();
+ QComboBoxPrivateContainer* viewContainer();
+ void updateLineEditGeometry();
+ Qt::MatchFlags matchFlags() const;
+ void _q_editingFinished();
+ void _q_returnPressed();
+ void _q_complete();
+ void _q_itemSelected(const QModelIndex &item);
+ bool contains(const QString &text, int role);
+ void emitActivated(const QModelIndex&);
+ void _q_emitHighlighted(const QModelIndex&);
+ void _q_emitCurrentIndexChanged(const QModelIndex &index);
+ void _q_modelDestroyed();
+ void _q_modelReset();
+#ifdef QT_KEYPAD_NAVIGATION
+ void _q_completerActivated();
+#endif
+ void _q_resetButton();
+ void _q_dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
+ void _q_updateIndexBeforeChange();
+ void _q_rowsInserted(const QModelIndex & parent, int start, int end);
+ void _q_rowsRemoved(const QModelIndex & parent, int start, int end);
+ void updateArrow(QStyle::StateFlag state);
+ bool updateHoverControl(const QPoint &pos);
+ QRect popupGeometry(int screen = -1) const;
+ QStyle::SubControl newHoverControl(const QPoint &pos);
+ int computeWidthHint() const;
+ QSize recomputeSizeHint(QSize &sh) const;
+ void adjustComboBoxSize();
+ QString itemText(const QModelIndex &index) const;
+ QIcon itemIcon(const QModelIndex &index) const;
+ int itemRole() const;
+ void updateLayoutDirection();
+ void setCurrentIndex(const QModelIndex &index);
+ void updateDelegate(bool force = false);
+ void keyboardSearchString(const QString &text);
+ void modelChanged();
+ void updateViewContainerPaletteAndOpacity();
+
+ QAbstractItemModel *model;
+ QLineEdit *lineEdit;
+ QComboBoxPrivateContainer *container;
+ QComboBox::InsertPolicy insertPolicy;
+ QComboBox::SizeAdjustPolicy sizeAdjustPolicy;
+ int minimumContentsLength;
+ QSize iconSize;
+ uint shownOnce : 1;
+ uint autoCompletion : 1;
+ uint duplicatesEnabled : 1;
+ uint frame : 1;
+ uint padding : 26;
+ int maxVisibleItems;
+ int maxCount;
+ int modelColumn;
+ bool inserting;
+ mutable QSize minimumSizeHint;
+ mutable QSize sizeHint;
+ QStyle::StateFlag arrowState;
+ QStyle::SubControl hoverControl;
+ QRect hoverRect;
+ QPersistentModelIndex currentIndex;
+ QPersistentModelIndex root;
+ Qt::CaseSensitivity autoCompletionCaseSensitivity;
+ int indexBeforeChange;
+#ifndef QT_NO_COMPLETER
+ QPointer<QCompleter> completer;
+#endif
+ static QPalette viewContainerPalette(QComboBox *cmb)
+ { return cmb->d_func()->viewContainer()->palette(); }
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_COMBOBOX
+
+#endif // QCOMBOBOX_P_H
diff --git a/src/gui/widgets/qcommandlinkbutton.cpp b/src/widgets/widgets/qcommandlinkbutton.cpp
index 257459a96f..257459a96f 100644
--- a/src/gui/widgets/qcommandlinkbutton.cpp
+++ b/src/widgets/widgets/qcommandlinkbutton.cpp
diff --git a/src/widgets/widgets/qcommandlinkbutton.h b/src/widgets/widgets/qcommandlinkbutton.h
new file mode 100644
index 0000000000..9d01e37b1b
--- /dev/null
+++ b/src/widgets/widgets/qcommandlinkbutton.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCOMMANDLINKBUTTON_H
+#define QCOMMANDLINKBUTTON_H
+
+#include <QtWidgets/qpushbutton.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QCommandLinkButtonPrivate;
+
+class Q_WIDGETS_EXPORT QCommandLinkButton: public QPushButton
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QString description READ description WRITE setDescription)
+ Q_PROPERTY(bool flat READ isFlat WRITE setFlat DESIGNABLE false)
+
+public:
+ explicit QCommandLinkButton(QWidget *parent=0);
+ explicit QCommandLinkButton(const QString &text, QWidget *parent=0);
+ QCommandLinkButton(const QString &text, const QString &description, QWidget *parent=0);
+ QString description() const;
+ void setDescription(const QString &description);
+
+protected:
+ QSize sizeHint() const;
+ int heightForWidth(int) const;
+ QSize minimumSizeHint() const;
+ bool event(QEvent *e);
+ void paintEvent(QPaintEvent *);
+
+private:
+ Q_DISABLE_COPY(QCommandLinkButton)
+ Q_DECLARE_PRIVATE(QCommandLinkButton)
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QCOMMANDLINKBUTTON
diff --git a/src/gui/widgets/qdatetimeedit.cpp b/src/widgets/widgets/qdatetimeedit.cpp
index d9ff8a6bad..d9ff8a6bad 100644
--- a/src/gui/widgets/qdatetimeedit.cpp
+++ b/src/widgets/widgets/qdatetimeedit.cpp
diff --git a/src/widgets/widgets/qdatetimeedit.h b/src/widgets/widgets/qdatetimeedit.h
new file mode 100644
index 0000000000..a57a5f29e9
--- /dev/null
+++ b/src/widgets/widgets/qdatetimeedit.h
@@ -0,0 +1,230 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDATETIMEEDIT_H
+#define QDATETIMEEDIT_H
+
+#include <QtCore/qdatetime.h>
+#include <QtCore/qvariant.h>
+#include <QtWidgets/qabstractspinbox.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_DATETIMEEDIT
+
+class QDateTimeEditPrivate;
+class QStyleOptionSpinBox;
+class QCalendarWidget;
+
+class Q_WIDGETS_EXPORT QDateTimeEdit : public QAbstractSpinBox
+{
+ Q_OBJECT
+
+ Q_ENUMS(Section)
+ Q_FLAGS(Sections)
+ Q_PROPERTY(QDateTime dateTime READ dateTime WRITE setDateTime NOTIFY dateTimeChanged USER true)
+ Q_PROPERTY(QDate date READ date WRITE setDate NOTIFY dateChanged)
+ Q_PROPERTY(QTime time READ time WRITE setTime NOTIFY timeChanged)
+ Q_PROPERTY(QDateTime maximumDateTime READ maximumDateTime WRITE setMaximumDateTime RESET clearMaximumDateTime)
+ Q_PROPERTY(QDateTime minimumDateTime READ minimumDateTime WRITE setMinimumDateTime RESET clearMinimumDateTime)
+ Q_PROPERTY(QDate maximumDate READ maximumDate WRITE setMaximumDate RESET clearMaximumDate)
+ Q_PROPERTY(QDate minimumDate READ minimumDate WRITE setMinimumDate RESET clearMinimumDate)
+ Q_PROPERTY(QTime maximumTime READ maximumTime WRITE setMaximumTime RESET clearMaximumTime)
+ Q_PROPERTY(QTime minimumTime READ minimumTime WRITE setMinimumTime RESET clearMinimumTime)
+ Q_PROPERTY(Section currentSection READ currentSection WRITE setCurrentSection)
+ Q_PROPERTY(Sections displayedSections READ displayedSections)
+ Q_PROPERTY(QString displayFormat READ displayFormat WRITE setDisplayFormat)
+ Q_PROPERTY(bool calendarPopup READ calendarPopup WRITE setCalendarPopup)
+ Q_PROPERTY(int currentSectionIndex READ currentSectionIndex WRITE setCurrentSectionIndex)
+ Q_PROPERTY(int sectionCount READ sectionCount)
+ Q_PROPERTY(Qt::TimeSpec timeSpec READ timeSpec WRITE setTimeSpec)
+public:
+ enum Section {
+ NoSection = 0x0000,
+ AmPmSection = 0x0001,
+ MSecSection = 0x0002,
+ SecondSection = 0x0004,
+ MinuteSection = 0x0008,
+ HourSection = 0x0010,
+ DaySection = 0x0100,
+ MonthSection = 0x0200,
+ YearSection = 0x0400,
+ TimeSections_Mask = AmPmSection|MSecSection|SecondSection|MinuteSection|HourSection,
+ DateSections_Mask = DaySection|MonthSection|YearSection
+ };
+
+ Q_DECLARE_FLAGS(Sections, Section)
+
+ explicit QDateTimeEdit(QWidget *parent = 0);
+ explicit QDateTimeEdit(const QDateTime &dt, QWidget *parent = 0);
+ explicit QDateTimeEdit(const QDate &d, QWidget *parent = 0);
+ explicit QDateTimeEdit(const QTime &t, QWidget *parent = 0);
+
+ QDateTime dateTime() const;
+ QDate date() const;
+ QTime time() const;
+
+ QDateTime minimumDateTime() const;
+ void clearMinimumDateTime();
+ void setMinimumDateTime(const QDateTime &dt);
+
+ QDateTime maximumDateTime() const;
+ void clearMaximumDateTime();
+ void setMaximumDateTime(const QDateTime &dt);
+
+ void setDateTimeRange(const QDateTime &min, const QDateTime &max);
+
+ QDate minimumDate() const;
+ void setMinimumDate(const QDate &min);
+ void clearMinimumDate();
+
+ QDate maximumDate() const;
+ void setMaximumDate(const QDate &max);
+ void clearMaximumDate();
+
+ void setDateRange(const QDate &min, const QDate &max);
+
+ QTime minimumTime() const;
+ void setMinimumTime(const QTime &min);
+ void clearMinimumTime();
+
+ QTime maximumTime() const;
+ void setMaximumTime(const QTime &max);
+ void clearMaximumTime();
+
+ void setTimeRange(const QTime &min, const QTime &max);
+
+ Sections displayedSections() const;
+ Section currentSection() const;
+ Section sectionAt(int index) const;
+ void setCurrentSection(Section section);
+
+ int currentSectionIndex() const;
+ void setCurrentSectionIndex(int index);
+
+ QCalendarWidget *calendarWidget() const;
+ void setCalendarWidget(QCalendarWidget *calendarWidget);
+
+ int sectionCount() const;
+
+ void setSelectedSection(Section section);
+
+ QString sectionText(Section section) const;
+
+ QString displayFormat() const;
+ void setDisplayFormat(const QString &format);
+
+ bool calendarPopup() const;
+ void setCalendarPopup(bool enable);
+
+ Qt::TimeSpec timeSpec() const;
+ void setTimeSpec(Qt::TimeSpec spec);
+
+ QSize sizeHint() const;
+
+ virtual void clear();
+ virtual void stepBy(int steps);
+
+ bool event(QEvent *event);
+Q_SIGNALS:
+ void dateTimeChanged(const QDateTime &date);
+ void timeChanged(const QTime &date);
+ void dateChanged(const QDate &date);
+
+public Q_SLOTS:
+ void setDateTime(const QDateTime &dateTime);
+ void setDate(const QDate &date);
+ void setTime(const QTime &time);
+
+protected:
+ virtual void keyPressEvent(QKeyEvent *event);
+#ifndef QT_NO_WHEELEVENT
+ virtual void wheelEvent(QWheelEvent *event);
+#endif
+ virtual void focusInEvent(QFocusEvent *event);
+ virtual bool focusNextPrevChild(bool next);
+ virtual QValidator::State validate(QString &input, int &pos) const;
+ virtual void fixup(QString &input) const;
+
+ virtual QDateTime dateTimeFromText(const QString &text) const;
+ virtual QString textFromDateTime(const QDateTime &dt) const;
+ virtual StepEnabled stepEnabled() const;
+ virtual void mousePressEvent(QMouseEvent *event);
+ virtual void paintEvent(QPaintEvent *event);
+ void initStyleOption(QStyleOptionSpinBox *option) const;
+
+ QDateTimeEdit(const QVariant &val, QVariant::Type parserType, QWidget *parent = 0);
+private:
+ Q_DECLARE_PRIVATE(QDateTimeEdit)
+ Q_DISABLE_COPY(QDateTimeEdit)
+
+ Q_PRIVATE_SLOT(d_func(), void _q_resetButton())
+};
+
+class Q_WIDGETS_EXPORT QTimeEdit : public QDateTimeEdit
+{
+ Q_OBJECT
+public:
+ QTimeEdit(QWidget *parent = 0);
+ QTimeEdit(const QTime &time, QWidget *parent = 0);
+};
+
+class Q_WIDGETS_EXPORT QDateEdit : public QDateTimeEdit
+{
+ Q_OBJECT
+public:
+ QDateEdit(QWidget *parent = 0);
+ QDateEdit(const QDate &date, QWidget *parent = 0);
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QDateTimeEdit::Sections)
+
+#endif // QT_NO_DATETIMEEDIT
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QDATETIMEEDIT_H
diff --git a/src/widgets/widgets/qdatetimeedit_p.h b/src/widgets/widgets/qdatetimeedit_p.h
new file mode 100644
index 0000000000..57799d5bc0
--- /dev/null
+++ b/src/widgets/widgets/qdatetimeedit_p.h
@@ -0,0 +1,185 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDATETIMEEDIT_P_H
+#define QDATETIMEEDIT_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "QtWidgets/qcombobox.h"
+#include "QtWidgets/qcalendarwidget.h"
+#include "QtWidgets/qspinbox.h"
+#include "QtWidgets/qtoolbutton.h"
+#include "QtWidgets/qmenu.h"
+#include "QtWidgets/qlabel.h"
+#include "QtWidgets/qdatetimeedit.h"
+#include "private/qabstractspinbox_p.h"
+#include "private/qdatetime_p.h"
+
+#include "qdebug.h"
+
+#ifndef QT_NO_DATETIMEEDIT
+
+QT_BEGIN_NAMESPACE
+
+class QCalendarPopup;
+class QDateTimeEditPrivate : public QAbstractSpinBoxPrivate, public QDateTimeParser
+{
+ Q_DECLARE_PUBLIC(QDateTimeEdit)
+public:
+ QDateTimeEditPrivate();
+
+ void init(const QVariant &var);
+ void readLocaleSettings();
+
+ void emitSignals(EmitPolicy ep, const QVariant &old);
+ QString textFromValue(const QVariant &f) const;
+ QVariant valueFromText(const QString &f) const;
+ virtual void _q_editorCursorPositionChanged(int oldpos, int newpos);
+ virtual void interpret(EmitPolicy ep);
+ virtual void clearCache() const;
+
+ QDateTime validateAndInterpret(QString &input, int &, QValidator::State &state,
+ bool fixup = false) const;
+ void clearSection(int index);
+ virtual QString displayText() const { return edit->text(); } // this is from QDateTimeParser
+
+ int absoluteIndex(QDateTimeEdit::Section s, int index) const;
+ int absoluteIndex(const SectionNode &s) const;
+ void updateEdit();
+ QDateTime stepBy(int index, int steps, bool test = false) const;
+ int sectionAt(int pos) const;
+ int closestSection(int index, bool forward) const;
+ int nextPrevSection(int index, bool forward) const;
+ void setSelected(int index, bool forward = false);
+
+ void updateCache(const QVariant &val, const QString &str) const;
+
+ void updateTimeSpec();
+ virtual QDateTime getMinimum() const { return minimum.toDateTime(); }
+ virtual QDateTime getMaximum() const { return maximum.toDateTime(); }
+ virtual QLocale locale() const { return q_func()->locale(); }
+ QString valueToText(const QVariant &var) const { return textFromValue(var); }
+ QString getAmPmText(AmPm ap, Case cs) const;
+ int cursorPosition() const { return edit ? edit->cursorPosition() : -1; }
+
+ virtual QStyle::SubControl newHoverControl(const QPoint &pos);
+ virtual void updateEditFieldGeometry();
+ virtual QVariant getZeroVariant() const;
+ virtual void setRange(const QVariant &min, const QVariant &max);
+
+ void _q_resetButton();
+ void updateArrow(QStyle::StateFlag state);
+ bool calendarPopupEnabled() const;
+ void syncCalendarWidget();
+
+ bool isSeparatorKey(const QKeyEvent *k) const;
+
+ static QDateTimeEdit::Sections convertSections(QDateTimeParser::Sections s);
+ static QDateTimeEdit::Section convertToPublic(QDateTimeParser::Section s);
+
+ void initCalendarPopup(QCalendarWidget *cw = 0);
+ void positionCalendarPopup();
+
+ QDateTimeEdit::Sections sections;
+ mutable bool cacheGuard;
+
+ QString defaultDateFormat, defaultTimeFormat, defaultDateTimeFormat, unreversedFormat;
+ mutable QVariant conflictGuard;
+ bool hasHadFocus, formatExplicitlySet, calendarPopup;
+ QStyle::StateFlag arrowState;
+ QCalendarPopup *monthCalendar;
+
+#ifdef QT_KEYPAD_NAVIGATION
+ bool focusOnButton;
+#endif
+};
+
+
+class QCalendarPopup : public QWidget
+{
+ Q_OBJECT
+public:
+ QCalendarPopup(QWidget *parent = 0, QCalendarWidget *cw = 0);
+ QDate selectedDate() { return verifyCalendarInstance()->selectedDate(); }
+ void setDate(const QDate &date);
+ void setDateRange(const QDate &min, const QDate &max);
+ void setFirstDayOfWeek(Qt::DayOfWeek dow) { verifyCalendarInstance()->setFirstDayOfWeek(dow); }
+ QCalendarWidget *calendarWidget() const { return const_cast<QCalendarPopup*>(this)->verifyCalendarInstance(); }
+ void setCalendarWidget(QCalendarWidget *cw);
+Q_SIGNALS:
+ void activated(const QDate &date);
+ void newDateSelected(const QDate &newDate);
+ void hidingCalendar(const QDate &oldDate);
+ void resetButton();
+
+private Q_SLOTS:
+ void dateSelected(const QDate &date);
+ void dateSelectionChanged();
+
+protected:
+ void hideEvent(QHideEvent *);
+ void mousePressEvent(QMouseEvent *e);
+ void mouseReleaseEvent(QMouseEvent *);
+ bool event(QEvent *e);
+
+private:
+ QCalendarWidget *verifyCalendarInstance();
+
+ QWeakPointer<QCalendarWidget> calendar;
+ QDate oldDate;
+ bool dateChanged;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_DATETIMEEDIT
+
+#endif // QDATETIMEEDIT_P_H
diff --git a/src/gui/widgets/qdial.cpp b/src/widgets/widgets/qdial.cpp
index e2b1983f66..e2b1983f66 100644
--- a/src/gui/widgets/qdial.cpp
+++ b/src/widgets/widgets/qdial.cpp
diff --git a/src/widgets/widgets/qdial.h b/src/widgets/widgets/qdial.h
new file mode 100644
index 0000000000..7687b7e7a1
--- /dev/null
+++ b/src/widgets/widgets/qdial.h
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QDIAL_H
+#define QDIAL_H
+
+#include <QtWidgets/qabstractslider.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_DIAL
+
+class QDialPrivate;
+class QStyleOptionSlider;
+
+class Q_WIDGETS_EXPORT QDial: public QAbstractSlider
+{
+ Q_OBJECT
+
+ Q_PROPERTY(bool wrapping READ wrapping WRITE setWrapping)
+ Q_PROPERTY(int notchSize READ notchSize)
+ Q_PROPERTY(qreal notchTarget READ notchTarget WRITE setNotchTarget)
+ Q_PROPERTY(bool notchesVisible READ notchesVisible WRITE setNotchesVisible)
+public:
+ explicit QDial(QWidget *parent = 0);
+
+ ~QDial();
+
+ bool wrapping() const;
+
+ int notchSize() const;
+
+ void setNotchTarget(double target);
+ qreal notchTarget() const;
+ bool notchesVisible() const;
+
+ QSize sizeHint() const;
+ QSize minimumSizeHint() const;
+
+public Q_SLOTS:
+ void setNotchesVisible(bool visible);
+ void setWrapping(bool on);
+
+protected:
+ bool event(QEvent *e);
+ void resizeEvent(QResizeEvent *re);
+ void paintEvent(QPaintEvent *pe);
+
+ void mousePressEvent(QMouseEvent *me);
+ void mouseReleaseEvent(QMouseEvent *me);
+ void mouseMoveEvent(QMouseEvent *me);
+
+ void sliderChange(SliderChange change);
+ void initStyleOption(QStyleOptionSlider *option) const;
+
+#ifdef QT3_SUPPORT
+public:
+ QT3_SUPPORT_CONSTRUCTOR QDial(int minValue, int maxValue, int pageStep, int value,
+ QWidget* parent = 0, const char* name = 0);
+ QT3_SUPPORT_CONSTRUCTOR QDial(QWidget *parent, const char *name);
+
+Q_SIGNALS:
+ QT_MOC_COMPAT void dialPressed();
+ QT_MOC_COMPAT void dialMoved(int value);
+ QT_MOC_COMPAT void dialReleased();
+#endif
+
+private:
+ Q_DECLARE_PRIVATE(QDial)
+ Q_DISABLE_COPY(QDial)
+};
+
+#endif // QT_NO_DIAL
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QDIAL_H
diff --git a/src/widgets/widgets/qdialogbuttonbox.cpp b/src/widgets/widgets/qdialogbuttonbox.cpp
new file mode 100644
index 0000000000..64fd3caa1e
--- /dev/null
+++ b/src/widgets/widgets/qdialogbuttonbox.cpp
@@ -0,0 +1,1285 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qhash.h>
+#include <QtWidgets/qpushbutton.h>
+#include <QtWidgets/qstyle.h>
+#include <QtWidgets/qlayout.h>
+#include <QtWidgets/qdialog.h>
+#include <QtWidgets/qapplication.h>
+#include <private/qwidget_p.h>
+#include <QtWidgets/qaction.h>
+
+#include "qdialogbuttonbox.h"
+
+#ifdef QT_SOFTKEYS_ENABLED
+#include <QtWidgets/qaction.h>
+#endif
+
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QDialogButtonBox
+ \since 4.2
+ \brief The QDialogButtonBox class is a widget that presents buttons in a
+ layout that is appropriate to the current widget style.
+
+ \ingroup dialog-classes
+
+
+ Dialogs and message boxes typically present buttons in a layout that
+ conforms to the interface guidelines for that platform. Invariably,
+ different platforms have different layouts for their dialogs.
+ QDialogButtonBox allows a developer to add buttons to it and will
+ automatically use the appropriate layout for the user's desktop
+ environment.
+
+ Most buttons for a dialog follow certain roles. Such roles include:
+
+ \list
+ \o Accepting or rejecting the dialog.
+ \o Asking for help.
+ \o Performing actions on the dialog itself (such as resetting fields or
+ applying changes).
+ \endlist
+
+ There can also be alternate ways of dismissing the dialog which may cause
+ destructive results.
+
+ Most dialogs have buttons that can almost be considered standard (e.g.
+ \gui OK and \gui Cancel buttons). It is sometimes convenient to create these
+ buttons in a standard way.
+
+ There are a couple ways of using QDialogButtonBox. One ways is to create
+ the buttons (or button texts) yourself and add them to the button box,
+ specifying their role.
+
+ \snippet examples/dialogs/extension/finddialog.cpp 1
+
+ Alternatively, QDialogButtonBox provides several standard buttons (e.g. OK, Cancel, Save)
+ that you can use. They exist as flags so you can OR them together in the constructor.
+
+ \snippet examples/dialogs/tabdialog/tabdialog.cpp 2
+
+ You can mix and match normal buttons and standard buttons.
+
+ Currently the buttons are laid out in the following way if the button box is horizontal:
+ \table
+ \row \o \inlineimage buttonbox-gnomelayout-horizontal.png GnomeLayout Horizontal
+ \o Button box laid out in horizontal GnomeLayout
+ \row \o \inlineimage buttonbox-kdelayout-horizontal.png KdeLayout Horizontal
+ \o Button box laid out in horizontal KdeLayout
+ \row \o \inlineimage buttonbox-maclayout-horizontal.png MacLayout Horizontal
+ \o Button box laid out in horizontal MacLayout
+ \row \o \inlineimage buttonbox-winlayout-horizontal.png WinLayout Horizontal
+ \o Button box laid out in horizontal WinLayout
+ \endtable
+
+ The buttons are laid out the following way if the button box is vertical:
+
+ \table
+ \row \o GnomeLayout
+ \o KdeLayout
+ \o MacLayout
+ \o WinLayout
+ \row \o \inlineimage buttonbox-gnomelayout-vertical.png GnomeLayout Vertical
+ \o \inlineimage buttonbox-kdelayout-vertical.png KdeLayout Vertical
+ \o \inlineimage buttonbox-maclayout-vertical.png MacLayout Vertical
+ \o \inlineimage buttonbox-winlayout-vertical.png WinLayout Vertical
+ \endtable
+
+ Additionally, button boxes that contain only buttons with ActionRole or
+ HelpRole can be considered modeless and have an alternate look on Mac OS X:
+
+ \table
+ \row \o modeless horizontal MacLayout
+ \o \inlineimage buttonbox-mac-modeless-horizontal.png Screenshot of modeless horizontal MacLayout
+ \endtable
+
+ When a button is clicked in the button box, the clicked() signal is emitted
+ for the actual button is that is pressed. For convenience, if the button
+ has an AcceptRole, RejectRole, or HelpRole, the accepted(), rejected(), or
+ helpRequested() signals are emitted respectively.
+
+ If you want a specific button to be default you need to call
+ QPushButton::setDefault() on it yourself. However, if there is no default
+ button set and to preserve which button is the default button across
+ platforms when using the QPushButton::autoDefault property, the first push
+ button with the accept role is made the default button when the
+ QDialogButtonBox is shown,
+
+ \sa QMessageBox, QPushButton, QDialog
+*/
+
+enum {
+ AcceptRole = QDialogButtonBox::AcceptRole,
+ RejectRole = QDialogButtonBox::RejectRole,
+ DestructiveRole = QDialogButtonBox::DestructiveRole,
+ ActionRole = QDialogButtonBox::ActionRole,
+ HelpRole = QDialogButtonBox::HelpRole,
+ YesRole = QDialogButtonBox::YesRole,
+ NoRole = QDialogButtonBox::NoRole,
+ ApplyRole = QDialogButtonBox::ApplyRole,
+ ResetRole = QDialogButtonBox::ResetRole,
+
+ AlternateRole = 0x10000000,
+ Stretch = 0x20000000,
+ EOL = 0x40000000,
+ Reverse = 0x80000000
+};
+
+static QDialogButtonBox::ButtonRole roleFor(QDialogButtonBox::StandardButton button)
+{
+ switch (button) {
+ case QDialogButtonBox::Ok:
+ case QDialogButtonBox::Save:
+ case QDialogButtonBox::Open:
+ case QDialogButtonBox::SaveAll:
+ case QDialogButtonBox::Retry:
+ case QDialogButtonBox::Ignore:
+ return QDialogButtonBox::AcceptRole;
+
+ case QDialogButtonBox::Cancel:
+ case QDialogButtonBox::Close:
+ case QDialogButtonBox::Abort:
+ return QDialogButtonBox::RejectRole;
+
+ case QDialogButtonBox::Discard:
+ return QDialogButtonBox::DestructiveRole;
+
+ case QDialogButtonBox::Help:
+ return QDialogButtonBox::HelpRole;
+
+ case QDialogButtonBox::Apply:
+ return QDialogButtonBox::ApplyRole;
+
+ case QDialogButtonBox::Yes:
+ case QDialogButtonBox::YesToAll:
+ return QDialogButtonBox::YesRole;
+
+ case QDialogButtonBox::No:
+ case QDialogButtonBox::NoToAll:
+ return QDialogButtonBox::NoRole;
+
+ case QDialogButtonBox::RestoreDefaults:
+ case QDialogButtonBox::Reset:
+ return QDialogButtonBox::ResetRole;
+
+ case QDialogButtonBox::NoButton: // NoButton means zero buttons, not "No" button
+ ;
+ }
+
+ return QDialogButtonBox::InvalidRole;
+}
+
+static const int layouts[2][5][14] =
+{
+ // Qt::Horizontal
+ {
+ // WinLayout
+ { ResetRole, Stretch, YesRole, AcceptRole, AlternateRole, DestructiveRole, NoRole, ActionRole, RejectRole, ApplyRole,
+ HelpRole, EOL, EOL, EOL },
+
+ // MacLayout
+ { HelpRole, ResetRole, ApplyRole, ActionRole, Stretch, DestructiveRole | Reverse,
+ AlternateRole | Reverse, RejectRole | Reverse, AcceptRole | Reverse, NoRole | Reverse, YesRole | Reverse, EOL, EOL },
+
+ // KdeLayout
+ { HelpRole, ResetRole, Stretch, YesRole, NoRole, ActionRole, AcceptRole, AlternateRole,
+ ApplyRole, DestructiveRole, RejectRole, EOL },
+
+ // GnomeLayout
+ { HelpRole, ResetRole, Stretch, ActionRole, ApplyRole | Reverse, DestructiveRole | Reverse,
+ AlternateRole | Reverse, RejectRole | Reverse, AcceptRole | Reverse, NoRole | Reverse, YesRole | Reverse, EOL },
+
+ // Mac modeless
+ { ResetRole, ApplyRole, ActionRole, Stretch, HelpRole, EOL, EOL, EOL, EOL, EOL, EOL, EOL, EOL, EOL }
+ },
+
+ // Qt::Vertical
+ {
+ // WinLayout
+ { ActionRole, YesRole, AcceptRole, AlternateRole, DestructiveRole, NoRole, RejectRole, ApplyRole, ResetRole,
+ HelpRole, Stretch, EOL, EOL, EOL },
+
+ // MacLayout
+ { YesRole, NoRole, AcceptRole, RejectRole, AlternateRole, DestructiveRole, Stretch, ActionRole, ApplyRole,
+ ResetRole, HelpRole, EOL, EOL },
+
+ // KdeLayout
+ { AcceptRole, AlternateRole, ApplyRole, ActionRole, YesRole, NoRole, Stretch, ResetRole,
+ DestructiveRole, RejectRole, HelpRole, EOL },
+
+ // GnomeLayout
+ { YesRole, NoRole, AcceptRole, RejectRole, AlternateRole, DestructiveRole, ApplyRole, ActionRole, Stretch,
+ ResetRole, HelpRole, EOL, EOL, EOL },
+
+ // Mac modeless
+ { ActionRole, ApplyRole, ResetRole, Stretch, HelpRole, EOL, EOL, EOL, EOL, EOL, EOL, EOL, EOL, EOL }
+ }
+};
+
+#if defined(QT_SOFTKEYS_ENABLED) && !defined(QT_NO_ACTION)
+class QDialogButtonEnabledProxy : public QObject
+{
+public:
+ QDialogButtonEnabledProxy(QObject *parent, QWidget *src, QAction *trg) : QObject(parent), source(src), target(trg)
+ {
+ source->installEventFilter(this);
+ target->setEnabled(source->isEnabled());
+ }
+ ~QDialogButtonEnabledProxy()
+ {
+ source->removeEventFilter(this);
+ }
+ bool eventFilter(QObject *object, QEvent *event)
+ {
+ if (object == source && event->type() == QEvent::EnabledChange) {
+ target->setEnabled(source->isEnabled());
+ }
+ return false;
+ };
+private:
+ QWidget *source;
+ QAction *target;
+};
+#endif
+
+class QDialogButtonBoxPrivate : public QWidgetPrivate
+{
+ Q_DECLARE_PUBLIC(QDialogButtonBox)
+
+public:
+ QDialogButtonBoxPrivate(Qt::Orientation orient);
+
+ QList<QAbstractButton *> buttonLists[QDialogButtonBox::NRoles];
+ QHash<QPushButton *, QDialogButtonBox::StandardButton> standardButtonHash;
+#ifdef QT_SOFTKEYS_ENABLED
+ QHash<QAbstractButton *, QAction *> softKeyActions;
+#endif
+
+ Qt::Orientation orientation;
+ QDialogButtonBox::ButtonLayout layoutPolicy;
+ QBoxLayout *buttonLayout;
+ bool internalRemove;
+ bool center;
+
+ void createStandardButtons(QDialogButtonBox::StandardButtons buttons);
+
+ void layoutButtons();
+ void initLayout();
+ void resetLayout();
+ QPushButton *createButton(QDialogButtonBox::StandardButton button, bool doLayout = true);
+ void addButton(QAbstractButton *button, QDialogButtonBox::ButtonRole role, bool doLayout = true);
+ void _q_handleButtonDestroyed();
+ void _q_handleButtonClicked();
+ void addButtonsToLayout(const QList<QAbstractButton *> &buttonList, bool reverse);
+ void retranslateStrings();
+ const char *standardButtonText(QDialogButtonBox::StandardButton sbutton) const;
+#if defined(QT_SOFTKEYS_ENABLED) && !defined(QT_NO_ACTION)
+ QAction *createSoftKey(QAbstractButton *button, QDialogButtonBox::ButtonRole role);
+#endif
+};
+
+QDialogButtonBoxPrivate::QDialogButtonBoxPrivate(Qt::Orientation orient)
+ : orientation(orient), buttonLayout(0), internalRemove(false), center(false)
+{
+}
+
+void QDialogButtonBoxPrivate::initLayout()
+{
+ Q_Q(QDialogButtonBox);
+ layoutPolicy = QDialogButtonBox::ButtonLayout(q->style()->styleHint(QStyle::SH_DialogButtonLayout, 0, q));
+ bool createNewLayout = buttonLayout == 0
+ || (orientation == Qt::Horizontal && qobject_cast<QVBoxLayout *>(buttonLayout) != 0)
+ || (orientation == Qt::Vertical && qobject_cast<QHBoxLayout *>(buttonLayout) != 0);
+ if (createNewLayout) {
+ delete buttonLayout;
+ if (orientation == Qt::Horizontal)
+ buttonLayout = new QHBoxLayout(q);
+ else
+ buttonLayout = new QVBoxLayout(q);
+ }
+
+ int left, top, right, bottom;
+ setLayoutItemMargins(QStyle::SE_PushButtonLayoutItem);
+ getLayoutItemMargins(&left, &top, &right, &bottom);
+ buttonLayout->setContentsMargins(-left, -top, -right, -bottom);
+
+ if (!q->testAttribute(Qt::WA_WState_OwnSizePolicy)) {
+ QSizePolicy sp(QSizePolicy::Expanding, QSizePolicy::Fixed, QSizePolicy::ButtonBox);
+ if (orientation == Qt::Vertical)
+ sp.transpose();
+ q->setSizePolicy(sp);
+ q->setAttribute(Qt::WA_WState_OwnSizePolicy, false);
+ }
+
+ // ### move to a real init() function
+ q->setFocusPolicy(Qt::TabFocus);
+}
+
+void QDialogButtonBoxPrivate::resetLayout()
+{
+ //delete buttonLayout;
+ initLayout();
+ layoutButtons();
+}
+
+void QDialogButtonBoxPrivate::addButtonsToLayout(const QList<QAbstractButton *> &buttonList,
+ bool reverse)
+{
+ int start = reverse ? buttonList.count() - 1 : 0;
+ int end = reverse ? -1 : buttonList.count();
+ int step = reverse ? -1 : 1;
+
+ for (int i = start; i != end; i += step) {
+ QAbstractButton *button = buttonList.at(i);
+ buttonLayout->addWidget(button);
+ button->show();
+ }
+}
+
+void QDialogButtonBoxPrivate::layoutButtons()
+{
+ Q_Q(QDialogButtonBox);
+ const int MacGap = 36 - 8; // 8 is the default gap between a widget and a spacer item
+
+ for (int i = buttonLayout->count() - 1; i >= 0; --i) {
+ QLayoutItem *item = buttonLayout->takeAt(i);
+ if (QWidget *widget = item->widget())
+ widget->hide();
+ delete item;
+ }
+
+ int tmpPolicy = layoutPolicy;
+
+ static const int M = 5;
+ static const int ModalRoles[M] = { AcceptRole, RejectRole, DestructiveRole, YesRole, NoRole };
+ if (tmpPolicy == QDialogButtonBox::MacLayout) {
+ bool hasModalButton = false;
+ for (int i = 0; i < M; ++i) {
+ if (!buttonLists[ModalRoles[i]].isEmpty()) {
+ hasModalButton = true;
+ break;
+ }
+ }
+ if (!hasModalButton)
+ tmpPolicy = 4; // Mac modeless
+ }
+
+ const int *currentLayout = layouts[orientation == Qt::Vertical][tmpPolicy];
+
+ if (center)
+ buttonLayout->addStretch();
+
+ QList<QAbstractButton *> acceptRoleList = buttonLists[AcceptRole];
+
+ while (*currentLayout != EOL) {
+ int role = (*currentLayout & ~Reverse);
+ bool reverse = (*currentLayout & Reverse);
+
+ switch (role) {
+ case Stretch:
+ if (!center)
+ buttonLayout->addStretch();
+ break;
+ case AcceptRole: {
+ if (acceptRoleList.isEmpty())
+ break;
+ // Only the first one
+ QAbstractButton *button = acceptRoleList.first();
+ buttonLayout->addWidget(button);
+ button->show();
+ }
+ break;
+ case AlternateRole:
+ {
+ if (acceptRoleList.size() < 2)
+ break;
+ QList<QAbstractButton *> list = acceptRoleList;
+ list.removeFirst();
+ addButtonsToLayout(list, reverse);
+ }
+ break;
+ case DestructiveRole:
+ {
+ const QList<QAbstractButton *> &list = buttonLists[role];
+
+ /*
+ Mac: Insert a gap on the left of the destructive
+ buttons to ensure that they don't get too close to
+ the help and action buttons (but only if there are
+ some buttons to the left of the destructive buttons
+ (and the stretch, whence buttonLayout->count() > 1
+ and not 0)).
+ */
+ if (tmpPolicy == QDialogButtonBox::MacLayout
+ && !list.isEmpty() && buttonLayout->count() > 1)
+ buttonLayout->addSpacing(MacGap);
+
+ addButtonsToLayout(list, reverse);
+
+ /*
+ Insert a gap between the destructive buttons and the
+ accept and reject buttons.
+ */
+ if (tmpPolicy == QDialogButtonBox::MacLayout && !list.isEmpty())
+ buttonLayout->addSpacing(MacGap);
+ }
+ break;
+ case RejectRole:
+ case ActionRole:
+ case HelpRole:
+ case YesRole:
+ case NoRole:
+ case ApplyRole:
+ case ResetRole:
+ addButtonsToLayout(buttonLists[role], reverse);
+ }
+ ++currentLayout;
+ }
+
+ QWidget *lastWidget = 0;
+ q->setFocusProxy(0);
+ for (int i = 0; i < buttonLayout->count(); ++i) {
+ QLayoutItem *item = buttonLayout->itemAt(i);
+ if (QWidget *widget = item->widget()) {
+ if (lastWidget)
+ QWidget::setTabOrder(lastWidget, widget);
+ else
+ q->setFocusProxy(widget);
+ lastWidget = widget;
+ }
+ }
+
+ if (center)
+ buttonLayout->addStretch();
+}
+
+QPushButton *QDialogButtonBoxPrivate::createButton(QDialogButtonBox::StandardButton sbutton,
+ bool doLayout)
+{
+ Q_Q(QDialogButtonBox);
+ const char *buttonText = 0;
+ int icon = 0;
+
+ switch (sbutton) {
+ case QDialogButtonBox::Ok:
+ icon = QStyle::SP_DialogOkButton;
+ break;
+ case QDialogButtonBox::Save:
+ icon = QStyle::SP_DialogSaveButton;
+ break;
+ case QDialogButtonBox::Open:
+ icon = QStyle::SP_DialogOpenButton;
+ break;
+ case QDialogButtonBox::Cancel:
+ icon = QStyle::SP_DialogCancelButton;
+ break;
+ case QDialogButtonBox::Close:
+ icon = QStyle::SP_DialogCloseButton;
+ break;
+ case QDialogButtonBox::Apply:
+ icon = QStyle::SP_DialogApplyButton;
+ break;
+ case QDialogButtonBox::Reset:
+ icon = QStyle::SP_DialogResetButton;
+ break;
+ case QDialogButtonBox::Help:
+ icon = QStyle::SP_DialogHelpButton;
+ break;
+ case QDialogButtonBox::Discard:
+ icon = QStyle::SP_DialogDiscardButton;
+ break;
+ case QDialogButtonBox::Yes:
+ icon = QStyle::SP_DialogYesButton;
+ break;
+ case QDialogButtonBox::No:
+ icon = QStyle::SP_DialogNoButton;
+ break;
+ case QDialogButtonBox::YesToAll:
+ case QDialogButtonBox::NoToAll:
+ case QDialogButtonBox::SaveAll:
+ case QDialogButtonBox::Abort:
+ case QDialogButtonBox::Retry:
+ case QDialogButtonBox::Ignore:
+ case QDialogButtonBox::RestoreDefaults:
+ break;
+ case QDialogButtonBox::NoButton:
+ return 0;
+ ;
+ }
+ buttonText = standardButtonText(sbutton);
+
+ QPushButton *button = new QPushButton(QDialogButtonBox::tr(buttonText), q);
+ QStyle *style = q->style();
+ if (style->styleHint(QStyle::SH_DialogButtonBox_ButtonsHaveIcons, 0, q) && icon != 0)
+ button->setIcon(style->standardIcon(QStyle::StandardPixmap(icon), 0, q));
+ if (style != QApplication::style()) // Propagate style
+ button->setStyle(style);
+ standardButtonHash.insert(button, sbutton);
+ if (roleFor(sbutton) != QDialogButtonBox::InvalidRole) {
+ addButton(button, roleFor(sbutton), doLayout);
+ } else {
+ qWarning("QDialogButtonBox::createButton: Invalid ButtonRole, button not added");
+ }
+
+#ifdef Q_WS_MAC
+ // Since mnemonics is off by default on Mac, we add a Cmd-D
+ // shortcut here to e.g. make the "Don't Save" button work nativly:
+ if (sbutton == QDialogButtonBox::Discard)
+ button->setShortcut(QKeySequence(QLatin1String("Ctrl+D")));
+#endif
+
+ return button;
+}
+
+void QDialogButtonBoxPrivate::addButton(QAbstractButton *button, QDialogButtonBox::ButtonRole role,
+ bool doLayout)
+{
+ Q_Q(QDialogButtonBox);
+ QObject::connect(button, SIGNAL(clicked()), q, SLOT(_q_handleButtonClicked()));
+ QObject::connect(button, SIGNAL(destroyed()), q, SLOT(_q_handleButtonDestroyed()));
+ buttonLists[role].append(button);
+#if defined(QT_SOFTKEYS_ENABLED) && !defined(QT_NO_ACTION)
+ QAction *action = createSoftKey(button, role);
+ softKeyActions.insert(button, action);
+ new QDialogButtonEnabledProxy(action, button, action);
+#endif
+ if (doLayout)
+ layoutButtons();
+}
+
+#if defined(QT_SOFTKEYS_ENABLED) && !defined(QT_NO_ACTION)
+QAction* QDialogButtonBoxPrivate::createSoftKey(QAbstractButton *button, QDialogButtonBox::ButtonRole role)
+{
+ Q_Q(QDialogButtonBox);
+ QAction::SoftKeyRole softkeyRole;
+
+ QAction *action = new QAction(button->text(), button);
+
+ switch (role) {
+ case ApplyRole:
+ case AcceptRole:
+ case YesRole:
+ case ActionRole:
+ case HelpRole:
+ softkeyRole = QAction::PositiveSoftKey;
+ break;
+ case RejectRole:
+ case DestructiveRole:
+ case NoRole:
+ case ResetRole:
+ softkeyRole = QAction::NegativeSoftKey;
+ break;
+ default:
+ break;
+ }
+ QObject::connect(action, SIGNAL(triggered()), button, SIGNAL(clicked()));
+ action->setSoftKeyRole(softkeyRole);
+
+
+ QWidget *dialog = 0;
+ QWidget *p = q;
+ while (p && !p->isWindow()) {
+ p = p->parentWidget();
+ if ((dialog = qobject_cast<QDialog *>(p)))
+ break;
+ }
+
+ if (dialog) {
+ dialog->addAction(action);
+ } else {
+ q->addAction(action);
+ }
+
+ return action;
+}
+#endif
+
+void QDialogButtonBoxPrivate::createStandardButtons(QDialogButtonBox::StandardButtons buttons)
+{
+ uint i = QDialogButtonBox::FirstButton;
+ while (i <= QDialogButtonBox::LastButton) {
+ if (i & buttons) {
+ createButton(QDialogButtonBox::StandardButton(i), false);
+ }
+ i = i << 1;
+ }
+ layoutButtons();
+}
+
+const char *QDialogButtonBoxPrivate::standardButtonText(QDialogButtonBox::StandardButton sbutton) const
+{
+ const char *buttonText = 0;
+ bool gnomeLayout = (layoutPolicy == QDialogButtonBox::GnomeLayout);
+ switch (sbutton) {
+ case QDialogButtonBox::Ok:
+ buttonText = gnomeLayout ? QT_TRANSLATE_NOOP("QDialogButtonBox", "&OK") : QT_TRANSLATE_NOOP("QDialogButtonBox", "OK");
+ break;
+ case QDialogButtonBox::Save:
+ buttonText = gnomeLayout ? QT_TRANSLATE_NOOP("QDialogButtonBox", "&Save") : QT_TRANSLATE_NOOP("QDialogButtonBox", "Save");
+ break;
+ case QDialogButtonBox::Open:
+ buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "Open");
+ break;
+ case QDialogButtonBox::Cancel:
+ buttonText = gnomeLayout ? QT_TRANSLATE_NOOP("QDialogButtonBox", "&Cancel") : QT_TRANSLATE_NOOP("QDialogButtonBox", "Cancel");
+ break;
+ case QDialogButtonBox::Close:
+ buttonText = gnomeLayout ? QT_TRANSLATE_NOOP("QDialogButtonBox", "&Close") : QT_TRANSLATE_NOOP("QDialogButtonBox", "Close");
+ break;
+ case QDialogButtonBox::Apply:
+ buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "Apply");
+ break;
+ case QDialogButtonBox::Reset:
+ buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "Reset");
+ break;
+ case QDialogButtonBox::Help:
+ buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "Help");
+ break;
+ case QDialogButtonBox::Discard:
+ if (layoutPolicy == QDialogButtonBox::MacLayout)
+ buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "Don't Save");
+ else if (layoutPolicy == QDialogButtonBox::GnomeLayout)
+ buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "Close without Saving");
+ else
+ buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "Discard");
+ break;
+ case QDialogButtonBox::Yes:
+ buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "&Yes");
+ break;
+ case QDialogButtonBox::YesToAll:
+ buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "Yes to &All");
+ break;
+ case QDialogButtonBox::No:
+ buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "&No");
+ break;
+ case QDialogButtonBox::NoToAll:
+ buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "N&o to All");
+ break;
+ case QDialogButtonBox::SaveAll:
+ buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "Save All");
+ break;
+ case QDialogButtonBox::Abort:
+ buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "Abort");
+ break;
+ case QDialogButtonBox::Retry:
+ buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "Retry");
+ break;
+ case QDialogButtonBox::Ignore:
+ buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "Ignore");
+ break;
+ case QDialogButtonBox::RestoreDefaults:
+ buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "Restore Defaults");
+ break;
+ case QDialogButtonBox::NoButton:
+ ;
+ } // switch
+ return buttonText;
+}
+
+void QDialogButtonBoxPrivate::retranslateStrings()
+{
+ const char *buttonText = 0;
+ QHash<QPushButton *, QDialogButtonBox::StandardButton>::iterator it = standardButtonHash.begin();
+ while (it != standardButtonHash.end()) {
+ buttonText = standardButtonText(it.value());
+ if (buttonText) {
+ QPushButton *button = it.key();
+ button->setText(QDialogButtonBox::tr(buttonText));
+#if defined(QT_SOFTKEYS_ENABLED) && !defined(QT_NO_ACTION)
+ QAction *action = softKeyActions.value(button, 0);
+ if (action)
+ action->setText(button->text());
+#endif
+ }
+ ++it;
+ }
+}
+
+/*!
+ Constructs an empty, horizontal button box with the given \a parent.
+
+ \sa orientation, addButton()
+*/
+QDialogButtonBox::QDialogButtonBox(QWidget *parent)
+ : QWidget(*new QDialogButtonBoxPrivate(Qt::Horizontal), parent, 0)
+{
+ d_func()->initLayout();
+}
+
+/*!
+ Constructs an empty button box with the given \a orientation and \a parent.
+
+ \sa orientation, addButton()
+*/
+QDialogButtonBox::QDialogButtonBox(Qt::Orientation orientation, QWidget *parent)
+ : QWidget(*new QDialogButtonBoxPrivate(orientation), parent, 0)
+{
+ d_func()->initLayout();
+}
+
+/*!
+ Constructs a button box with the given \a orientation and \a parent, containing
+ the standard buttons specified by \a buttons.
+
+ \sa orientation, addButton()
+*/
+QDialogButtonBox::QDialogButtonBox(StandardButtons buttons, Qt::Orientation orientation,
+ QWidget *parent)
+ : QWidget(*new QDialogButtonBoxPrivate(orientation), parent, 0)
+{
+ d_func()->initLayout();
+ d_func()->createStandardButtons(buttons);
+}
+
+/*!
+ Destroys the button box.
+*/
+QDialogButtonBox::~QDialogButtonBox()
+{
+}
+
+/*!
+ \enum QDialogButtonBox::ButtonRole
+ \enum QMessageBox::ButtonRole
+
+ This enum describes the roles that can be used to describe buttons in
+ the button box. Combinations of these roles are as flags used to
+ describe different aspects of their behavior.
+
+ \value InvalidRole The button is invalid.
+ \value AcceptRole Clicking the button causes the dialog to be accepted
+ (e.g. OK).
+ \value RejectRole Clicking the button causes the dialog to be rejected
+ (e.g. Cancel).
+ \value DestructiveRole Clicking the button causes a destructive change
+ (e.g. for Discarding Changes) and closes the dialog.
+ \value ActionRole Clicking the button causes changes to the elements within
+ the dialog.
+ \value HelpRole The button can be clicked to request help.
+ \value YesRole The button is a "Yes"-like button.
+ \value NoRole The button is a "No"-like button.
+ \value ApplyRole The button applies current changes.
+ \value ResetRole The button resets the dialog's fields to default values.
+
+ \omitvalue NRoles
+
+ \sa StandardButton
+*/
+
+/*!
+ \enum QDialogButtonBox::StandardButton
+
+ These enums describe flags for standard buttons. Each button has a
+ defined \l ButtonRole.
+
+ \value Ok An "OK" button defined with the \l AcceptRole.
+ \value Open A "Open" button defined with the \l AcceptRole.
+ \value Save A "Save" button defined with the \l AcceptRole.
+ \value Cancel A "Cancel" button defined with the \l RejectRole.
+ \value Close A "Close" button defined with the \l RejectRole.
+ \value Discard A "Discard" or "Don't Save" button, depending on the platform,
+ defined with the \l DestructiveRole.
+ \value Apply An "Apply" button defined with the \l ApplyRole.
+ \value Reset A "Reset" button defined with the \l ResetRole.
+ \value RestoreDefaults A "Restore Defaults" button defined with the \l ResetRole.
+ \value Help A "Help" button defined with the \l HelpRole.
+ \value SaveAll A "Save All" button defined with the \l AcceptRole.
+ \value Yes A "Yes" button defined with the \l YesRole.
+ \value YesToAll A "Yes to All" button defined with the \l YesRole.
+ \value No A "No" button defined with the \l NoRole.
+ \value NoToAll A "No to All" button defined with the \l NoRole.
+ \value Abort An "Abort" button defined with the \l RejectRole.
+ \value Retry A "Retry" button defined with the \l AcceptRole.
+ \value Ignore An "Ignore" button defined with the \l AcceptRole.
+
+ \value NoButton An invalid button.
+
+ \omitvalue FirstButton
+ \omitvalue LastButton
+
+ \sa ButtonRole, standardButtons
+*/
+
+/*!
+ \enum QDialogButtonBox::ButtonLayout
+
+ This enum describes the layout policy to be used when arranging the buttons
+ contained in the button box.
+
+ \value WinLayout Use a policy appropriate for applications on Windows.
+ \value MacLayout Use a policy appropriate for applications on Mac OS X.
+ \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}. However,
+ on the X11 platform, it may be influenced by the desktop environment.
+*/
+
+/*!
+ \fn void QDialogButtonBox::clicked(QAbstractButton *button)
+
+ This signal is emitted when a button inside the button box is clicked. The
+ specific button that was pressed is specified by \a button.
+
+ \sa accepted(), rejected(), helpRequested()
+*/
+
+/*!
+ \fn void QDialogButtonBox::accepted()
+
+ This signal is emitted when a button inside the button box is clicked, as long
+ as it was defined with the \l AcceptRole or \l YesRole.
+
+ \sa rejected(), clicked() helpRequested()
+*/
+
+/*!
+ \fn void QDialogButtonBox::rejected()
+
+ This signal is emitted when a button inside the button box is clicked, as long
+ as it was defined with the \l RejectRole or \l NoRole.
+
+ \sa accepted() helpRequested() clicked()
+*/
+
+/*!
+ \fn void QDialogButtonBox::helpRequested()
+
+ This signal is emitted when a button inside the button box is clicked, as long
+ as it was defined with the \l HelpRole.
+
+ \sa accepted() rejected() clicked()
+*/
+
+/*!
+ \property QDialogButtonBox::orientation
+ \brief the orientation of the button box
+
+ By default, the orientation is horizontal (i.e. the buttons are laid out
+ side by side). The possible orientations are Qt::Horizontal and
+ Qt::Vertical.
+*/
+Qt::Orientation QDialogButtonBox::orientation() const
+{
+ return d_func()->orientation;
+}
+
+void QDialogButtonBox::setOrientation(Qt::Orientation orientation)
+{
+ Q_D(QDialogButtonBox);
+ if (orientation == d->orientation)
+ return;
+
+ d->orientation = orientation;
+ d->resetLayout();
+}
+
+/*!
+ Clears the button box, deleting all buttons within it.
+
+ \sa removeButton(), addButton()
+*/
+void QDialogButtonBox::clear()
+{
+ Q_D(QDialogButtonBox);
+#ifdef QT_SOFTKEYS_ENABLED
+ // Delete softkey actions as they have the buttons as parents
+ qDeleteAll(d->softKeyActions.values());
+ d->softKeyActions.clear();
+#endif
+ // Remove the created standard buttons, they should be in the other lists, which will
+ // do the deletion
+ d->standardButtonHash.clear();
+ for (int i = 0; i < NRoles; ++i) {
+ QList<QAbstractButton *> &list = d->buttonLists[i];
+ while (list.count()) {
+ QAbstractButton *button = list.takeAt(0);
+ QObject::disconnect(button, SIGNAL(destroyed()), this, SLOT(_q_handleButtonDestroyed()));
+ delete button;
+ }
+ }
+}
+
+/*!
+ Returns a list of all the buttons that have been added to the button box.
+
+ \sa buttonRole(), addButton(), removeButton()
+*/
+QList<QAbstractButton *> QDialogButtonBox::buttons() const
+{
+ Q_D(const QDialogButtonBox);
+ QList<QAbstractButton *> finalList;
+ for (int i = 0; i < NRoles; ++i) {
+ const QList<QAbstractButton *> &list = d->buttonLists[i];
+ for (int j = 0; j < list.count(); ++j)
+ finalList.append(list.at(j));
+ }
+ return finalList;
+}
+
+/*!
+ Returns the button role for the specified \a button. This function returns
+ \l InvalidRole if \a button is 0 or has not been added to the button box.
+
+ \sa buttons(), addButton()
+*/
+QDialogButtonBox::ButtonRole QDialogButtonBox::buttonRole(QAbstractButton *button) const
+{
+ Q_D(const QDialogButtonBox);
+ for (int i = 0; i < NRoles; ++i) {
+ const QList<QAbstractButton *> &list = d->buttonLists[i];
+ for (int j = 0; j < list.count(); ++j) {
+ if (list.at(j) == button)
+ return ButtonRole(i);
+ }
+ }
+ return InvalidRole;
+}
+
+/*!
+ Removes \a button from the button box without deleting it and sets its parent to zero.
+
+ \sa clear(), buttons(), addButton()
+*/
+void QDialogButtonBox::removeButton(QAbstractButton *button)
+{
+ Q_D(QDialogButtonBox);
+
+ if (!button)
+ return;
+
+ // Remove it from the standard button hash first and then from the roles
+ if (QPushButton *pushButton = qobject_cast<QPushButton *>(button))
+ d->standardButtonHash.remove(pushButton);
+ for (int i = 0; i < NRoles; ++i) {
+ QList<QAbstractButton *> &list = d->buttonLists[i];
+ for (int j = 0; j < list.count(); ++j) {
+ if (list.at(j) == button) {
+ list.takeAt(j);
+ if (!d->internalRemove) {
+ disconnect(button, SIGNAL(clicked()), this, SLOT(_q_handleButtonClicked()));
+ disconnect(button, SIGNAL(destroyed()), this, SLOT(_q_handleButtonDestroyed()));
+ }
+ break;
+ }
+ }
+ }
+#if defined(QT_SOFTKEYS_ENABLED) && !defined(QT_NO_ACTION)
+ QAction *action = d->softKeyActions.value(button, 0);
+ if (action) {
+ d->softKeyActions.remove(button);
+ delete action;
+ }
+#endif
+ if (!d->internalRemove)
+ button->setParent(0);
+}
+
+/*!
+ Adds the given \a button to the button box with the specified \a role.
+ If the role is invalid, the button is not added.
+
+ If the button has already been added, it is removed and added again with the
+ new role.
+
+ \note The button box takes ownership of the button.
+
+ \sa removeButton(), clear()
+*/
+void QDialogButtonBox::addButton(QAbstractButton *button, ButtonRole role)
+{
+ Q_D(QDialogButtonBox);
+ if (role <= InvalidRole || role >= NRoles) {
+ qWarning("QDialogButtonBox::addButton: Invalid ButtonRole, button not added");
+ return;
+ }
+ removeButton(button);
+ button->setParent(this);
+ d->addButton(button, role);
+}
+
+/*!
+ Creates a push button with the given \a text, adds it to the button box for the
+ specified \a role, and returns the corresponding push button. If \a role is
+ invalid, no button is created, and zero is returned.
+
+ \sa removeButton(), clear()
+*/
+QPushButton *QDialogButtonBox::addButton(const QString &text, ButtonRole role)
+{
+ Q_D(QDialogButtonBox);
+ if (role <= InvalidRole || role >= NRoles) {
+ qWarning("QDialogButtonBox::addButton: Invalid ButtonRole, button not added");
+ return 0;
+ }
+ QPushButton *button = new QPushButton(text, this);
+ d->addButton(button, role);
+ return button;
+}
+
+/*!
+ Adds a standard \a button to the button box if it is valid to do so, and returns
+ a push button. If \a button is invalid, it is not added to the button box, and
+ zero is returned.
+
+ \sa removeButton(), clear()
+*/
+QPushButton *QDialogButtonBox::addButton(StandardButton button)
+{
+ Q_D(QDialogButtonBox);
+ return d->createButton(button);
+}
+
+/*!
+ \property QDialogButtonBox::standardButtons
+ \brief collection of standard buttons in the button box
+
+ This property controls which standard buttons are used by the button box.
+
+ \sa addButton()
+*/
+void QDialogButtonBox::setStandardButtons(StandardButtons buttons)
+{
+ Q_D(QDialogButtonBox);
+#ifdef QT_SOFTKEYS_ENABLED
+ // Delete softkey actions since they have the buttons as parents
+ qDeleteAll(d->softKeyActions.values());
+ d->softKeyActions.clear();
+#endif
+ // Clear out all the old standard buttons, then recreate them.
+ qDeleteAll(d->standardButtonHash.keys());
+ d->standardButtonHash.clear();
+
+ d->createStandardButtons(buttons);
+}
+
+QDialogButtonBox::StandardButtons QDialogButtonBox::standardButtons() const
+{
+ Q_D(const QDialogButtonBox);
+ StandardButtons standardButtons = NoButton;
+ QHash<QPushButton *, StandardButton>::const_iterator it = d->standardButtonHash.constBegin();
+ while (it != d->standardButtonHash.constEnd()) {
+ standardButtons |= it.value();
+ ++it;
+ }
+ return standardButtons;
+}
+
+/*!
+ Returns the QPushButton corresponding to the standard button \a which,
+ or 0 if the standard button doesn't exist in this button box.
+
+ \sa standardButton(), standardButtons(), buttons()
+*/
+QPushButton *QDialogButtonBox::button(StandardButton which) const
+{
+ Q_D(const QDialogButtonBox);
+ return d->standardButtonHash.key(which);
+}
+
+/*!
+ Returns the standard button enum value corresponding to the given \a button,
+ or NoButton if the given \a button isn't a standard button.
+
+ \sa button(), buttons(), standardButtons()
+*/
+QDialogButtonBox::StandardButton QDialogButtonBox::standardButton(QAbstractButton *button) const
+{
+ Q_D(const QDialogButtonBox);
+ return d->standardButtonHash.value(static_cast<QPushButton *>(button));
+}
+
+void QDialogButtonBoxPrivate::_q_handleButtonClicked()
+{
+ Q_Q(QDialogButtonBox);
+ if (QAbstractButton *button = qobject_cast<QAbstractButton *>(q->sender())) {
+ emit q->clicked(button);
+
+ switch (q->buttonRole(button)) {
+ case AcceptRole:
+ case YesRole:
+ emit q->accepted();
+ break;
+ case RejectRole:
+ case NoRole:
+ emit q->rejected();
+ break;
+ case HelpRole:
+ emit q->helpRequested();
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+void QDialogButtonBoxPrivate::_q_handleButtonDestroyed()
+{
+ Q_Q(QDialogButtonBox);
+ if (QObject *object = q->sender()) {
+ QBoolBlocker skippy(internalRemove);
+ q->removeButton(static_cast<QAbstractButton *>(object));
+ }
+}
+
+/*!
+ \property QDialogButtonBox::centerButtons
+ \brief whether the buttons in the button box are centered
+
+ By default, this property is false. This behavior is appopriate
+ for most types of dialogs. A notable exception is message boxes
+ on most platforms (e.g. Windows), where the button box is
+ centered horizontally.
+
+ \sa QMessageBox
+*/
+void QDialogButtonBox::setCenterButtons(bool center)
+{
+ Q_D(QDialogButtonBox);
+ if (d->center != center) {
+ d->center = center;
+ d->resetLayout();
+ }
+}
+
+bool QDialogButtonBox::centerButtons() const
+{
+ Q_D(const QDialogButtonBox);
+ return d->center;
+}
+
+/*!
+ \reimp
+*/
+void QDialogButtonBox::changeEvent(QEvent *event)
+{
+ typedef QHash<QPushButton *, QDialogButtonBox::StandardButton> StandardButtonHash;
+
+ Q_D(QDialogButtonBox);
+ switch (event->type()) {
+ case QEvent::StyleChange: // Propagate style
+ if (!d->standardButtonHash.empty()) {
+ QStyle *newStyle = style();
+ const StandardButtonHash::iterator end = d->standardButtonHash.end();
+ for (StandardButtonHash::iterator it = d->standardButtonHash.begin(); it != end; ++it)
+ it.key()->setStyle(newStyle);
+ }
+ // fallthrough intended
+#ifdef Q_WS_MAC
+ case QEvent::MacSizeChange:
+#endif
+ d->resetLayout();
+ QWidget::changeEvent(event);
+ break;
+ default:
+ QWidget::changeEvent(event);
+ break;
+ }
+}
+
+/*!
+ \reimp
+*/
+bool QDialogButtonBox::event(QEvent *event)
+{
+ Q_D(QDialogButtonBox);
+ if (event->type() == QEvent::Show) {
+ QList<QAbstractButton *> acceptRoleList = d->buttonLists[AcceptRole];
+ QPushButton *firstAcceptButton = acceptRoleList.isEmpty() ? 0 : qobject_cast<QPushButton *>(acceptRoleList.at(0));
+ bool hasDefault = false;
+ QWidget *dialog = 0;
+ QWidget *p = this;
+ while (p && !p->isWindow()) {
+ p = p->parentWidget();
+ if ((dialog = qobject_cast<QDialog *>(p)))
+ break;
+ }
+
+ foreach (QPushButton *pb, (dialog ? dialog : this)->findChildren<QPushButton *>()) {
+ if (pb->isDefault() && pb != firstAcceptButton) {
+ hasDefault = true;
+ break;
+ }
+ }
+ if (!hasDefault && firstAcceptButton)
+ firstAcceptButton->setDefault(true);
+#ifdef QT_SOFTKEYS_ENABLED
+ if (dialog)
+ setFixedSize(0,0);
+#endif
+ }else if (event->type() == QEvent::LanguageChange) {
+ d->retranslateStrings();
+ }
+#if defined(QT_SOFTKEYS_ENABLED) && !defined(QT_NO_ACTION)
+ else if (event->type() == QEvent::ParentChange) {
+ QWidget *dialog = 0;
+ QWidget *p = this;
+ while (p && !p->isWindow()) {
+ p = p->parentWidget();
+ if ((dialog = qobject_cast<QDialog *>(p)))
+ break;
+ }
+
+ // If the parent changes, then move the softkeys
+ for (QHash<QAbstractButton *, QAction *>::const_iterator it = d->softKeyActions.constBegin();
+ it != d->softKeyActions.constEnd(); ++it) {
+ QAction *current = it.value();
+ QList<QWidget *> widgets = current->associatedWidgets();
+ foreach (QWidget *w, widgets)
+ w->removeAction(current);
+ if (dialog)
+ dialog->addAction(current);
+ else
+ addAction(current);
+ }
+ }
+#endif
+
+ return QWidget::event(event);
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qdialogbuttonbox.cpp"
diff --git a/src/widgets/widgets/qdialogbuttonbox.h b/src/widgets/widgets/qdialogbuttonbox.h
new file mode 100644
index 0000000000..0a6e231e3f
--- /dev/null
+++ b/src/widgets/widgets/qdialogbuttonbox.h
@@ -0,0 +1,168 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDIALOGBUTTONBOX_H
+#define QDIALOGBUTTONBOX_H
+
+#include <QtWidgets/qwidget.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QAbstractButton;
+class QPushButton;
+class QDialogButtonBoxPrivate;
+
+class Q_WIDGETS_EXPORT QDialogButtonBox : public QWidget
+{
+ Q_OBJECT
+ Q_FLAGS(StandardButtons)
+ Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation)
+ Q_PROPERTY(StandardButtons standardButtons READ standardButtons WRITE setStandardButtons)
+ Q_PROPERTY(bool centerButtons READ centerButtons WRITE setCenterButtons)
+
+public:
+ enum ButtonRole {
+ // keep this in sync with QMessageBox::ButtonRole
+ InvalidRole = -1,
+ AcceptRole,
+ RejectRole,
+ DestructiveRole,
+ ActionRole,
+ HelpRole,
+ YesRole,
+ NoRole,
+ ResetRole,
+ ApplyRole,
+
+ NRoles
+ };
+
+ enum StandardButton {
+ // keep this in sync with QMessageBox::StandardButton
+ NoButton = 0x00000000,
+ Ok = 0x00000400,
+ Save = 0x00000800,
+ SaveAll = 0x00001000,
+ Open = 0x00002000,
+ Yes = 0x00004000,
+ YesToAll = 0x00008000,
+ No = 0x00010000,
+ NoToAll = 0x00020000,
+ Abort = 0x00040000,
+ Retry = 0x00080000,
+ Ignore = 0x00100000,
+ Close = 0x00200000,
+ Cancel = 0x00400000,
+ Discard = 0x00800000,
+ Help = 0x01000000,
+ Apply = 0x02000000,
+ Reset = 0x04000000,
+ RestoreDefaults = 0x08000000,
+
+#ifndef Q_MOC_RUN
+ FirstButton = Ok,
+ LastButton = RestoreDefaults
+#endif
+ };
+
+ Q_DECLARE_FLAGS(StandardButtons, StandardButton)
+
+ enum ButtonLayout {
+ WinLayout,
+ MacLayout,
+ KdeLayout,
+ GnomeLayout
+ };
+
+ QDialogButtonBox(QWidget *parent = 0);
+ QDialogButtonBox(Qt::Orientation orientation, QWidget *parent = 0);
+ QDialogButtonBox(StandardButtons buttons, Qt::Orientation orientation = Qt::Horizontal,
+ QWidget *parent = 0);
+ ~QDialogButtonBox();
+
+ void setOrientation(Qt::Orientation orientation);
+ Qt::Orientation orientation() const;
+
+ void addButton(QAbstractButton *button, ButtonRole role);
+ QPushButton *addButton(const QString &text, ButtonRole role);
+ QPushButton *addButton(StandardButton button);
+ void removeButton(QAbstractButton *button);
+ void clear();
+
+ QList<QAbstractButton *> buttons() const;
+ ButtonRole buttonRole(QAbstractButton *button) const;
+
+ void setStandardButtons(StandardButtons buttons);
+ StandardButtons standardButtons() const;
+ StandardButton standardButton(QAbstractButton *button) const;
+ QPushButton *button(StandardButton which) const;
+
+ void setCenterButtons(bool center);
+ bool centerButtons() const;
+
+Q_SIGNALS:
+ void clicked(QAbstractButton *button);
+ void accepted();
+ void helpRequested();
+ void rejected();
+
+protected:
+ void changeEvent(QEvent *event);
+ bool event(QEvent *event);
+
+private:
+ Q_DISABLE_COPY(QDialogButtonBox)
+ Q_DECLARE_PRIVATE(QDialogButtonBox)
+ Q_PRIVATE_SLOT(d_func(), void _q_handleButtonClicked())
+ Q_PRIVATE_SLOT(d_func(), void _q_handleButtonDestroyed())
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QDialogButtonBox::StandardButtons)
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QDIALOGBUTTONBOX_H
diff --git a/src/widgets/widgets/qdockarealayout.cpp b/src/widgets/widgets/qdockarealayout.cpp
new file mode 100644
index 0000000000..aa627ef4f8
--- /dev/null
+++ b/src/widgets/widgets/qdockarealayout.cpp
@@ -0,0 +1,3329 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "QtWidgets/qapplication.h"
+#include "QtWidgets/qwidget.h"
+#include "QtWidgets/qtabbar.h"
+#include "QtWidgets/qstyle.h"
+#include "QtWidgets/qdesktopwidget.h"
+#include "QtCore/qvariant.h"
+#include "qdockarealayout_p.h"
+#include "qdockwidget.h"
+#include "qmainwindow.h"
+#include "qwidgetanimator_p.h"
+#include "qmainwindowlayout_p.h"
+#include "qdockwidget_p.h"
+#include <private/qlayoutengine_p.h>
+
+#include <qpainter.h>
+#include <qstyleoption.h>
+
+#ifndef QT_NO_DOCKWIDGET
+
+QT_BEGIN_NAMESPACE
+
+// qmainwindow.cpp
+extern QMainWindowLayout *qt_mainwindow_layout(const QMainWindow *window);
+
+enum { StateFlagVisible = 1, StateFlagFloating = 2 };
+
+/******************************************************************************
+** QPlaceHolderItem
+*/
+
+QPlaceHolderItem::QPlaceHolderItem(QWidget *w)
+{
+ objectName = w->objectName();
+ hidden = w->isHidden();
+ window = w->isWindow();
+ if (window)
+ topLevelRect = w->geometry();
+}
+
+/******************************************************************************
+** QDockAreaLayoutItem
+*/
+
+QDockAreaLayoutItem::QDockAreaLayoutItem(QLayoutItem *_widgetItem)
+ : widgetItem(_widgetItem), subinfo(0), placeHolderItem(0), pos(0), size(-1), flags(NoFlags)
+{
+}
+
+QDockAreaLayoutItem::QDockAreaLayoutItem(QDockAreaLayoutInfo *_subinfo)
+ : widgetItem(0), subinfo(_subinfo), placeHolderItem(0), pos(0), size(-1), flags(NoFlags)
+{
+}
+
+QDockAreaLayoutItem::QDockAreaLayoutItem(QPlaceHolderItem *_placeHolderItem)
+ : widgetItem(0), subinfo(0), placeHolderItem(_placeHolderItem), pos(0), size(-1), flags(NoFlags)
+{
+}
+
+QDockAreaLayoutItem::QDockAreaLayoutItem(const QDockAreaLayoutItem &other)
+ : widgetItem(other.widgetItem), subinfo(0), placeHolderItem(0), pos(other.pos),
+ size(other.size), flags(other.flags)
+{
+ if (other.subinfo != 0)
+ subinfo = new QDockAreaLayoutInfo(*other.subinfo);
+ else if (other.placeHolderItem != 0)
+ placeHolderItem = new QPlaceHolderItem(*other.placeHolderItem);
+}
+
+QDockAreaLayoutItem::~QDockAreaLayoutItem()
+{
+ delete subinfo;
+ delete placeHolderItem;
+}
+
+bool QDockAreaLayoutItem::skip() const
+{
+ if (placeHolderItem != 0)
+ return true;
+
+ if (flags & GapItem)
+ return false;
+
+ if (widgetItem != 0)
+ return widgetItem->isEmpty();
+
+ if (subinfo != 0) {
+ for (int i = 0; i < subinfo->item_list.count(); ++i) {
+ if (!subinfo->item_list.at(i).skip())
+ return false;
+ }
+ }
+
+ return true;
+}
+
+QSize QDockAreaLayoutItem::minimumSize() const
+{
+ if (widgetItem != 0) {
+ int left, top, right, bottom;
+ widgetItem->widget()->getContentsMargins(&left, &top, &right, &bottom);
+ return widgetItem->minimumSize() + QSize(left+right, top+bottom);
+ }
+ if (subinfo != 0)
+ return subinfo->minimumSize();
+ return QSize(0, 0);
+}
+
+QSize QDockAreaLayoutItem::maximumSize() const
+{
+ if (widgetItem != 0) {
+ int left, top, right, bottom;
+ widgetItem->widget()->getContentsMargins(&left, &top, &right, &bottom);
+ return widgetItem->maximumSize()+ QSize(left+right, top+bottom);
+ }
+ if (subinfo != 0)
+ return subinfo->maximumSize();
+ return QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
+}
+
+bool QDockAreaLayoutItem::hasFixedSize(Qt::Orientation o) const
+{
+ return perp(o, minimumSize()) == perp(o, maximumSize());
+}
+
+bool QDockAreaLayoutItem::expansive(Qt::Orientation o) const
+{
+ if ((flags & GapItem) || placeHolderItem != 0)
+ return false;
+ if (widgetItem != 0)
+ return ((widgetItem->expandingDirections() & o) == o);
+ if (subinfo != 0)
+ return subinfo->expansive(o);
+ return false;
+}
+
+QSize QDockAreaLayoutItem::sizeHint() const
+{
+ if (placeHolderItem != 0)
+ return QSize(0, 0);
+ if (widgetItem != 0) {
+ int left, top, right, bottom;
+ widgetItem->widget()->getContentsMargins(&left, &top, &right, &bottom);
+ return widgetItem->sizeHint() + QSize(left+right, top+bottom);
+ }
+ if (subinfo != 0)
+ return subinfo->sizeHint();
+ return QSize(-1, -1);
+}
+
+QDockAreaLayoutItem
+ &QDockAreaLayoutItem::operator = (const QDockAreaLayoutItem &other)
+{
+ widgetItem = other.widgetItem;
+ if (other.subinfo == 0)
+ subinfo = 0;
+ else
+ subinfo = new QDockAreaLayoutInfo(*other.subinfo);
+
+ delete placeHolderItem;
+ if (other.placeHolderItem == 0)
+ placeHolderItem = 0;
+ else
+ placeHolderItem = new QPlaceHolderItem(*other.placeHolderItem);
+
+ pos = other.pos;
+ size = other.size;
+ flags = other.flags;
+
+ return *this;
+}
+
+/******************************************************************************
+** QDockAreaLayoutInfo
+*/
+
+#ifndef QT_NO_TABBAR
+static quintptr tabId(const QDockAreaLayoutItem &item)
+{
+ if (item.widgetItem == 0)
+ return 0;
+ return reinterpret_cast<quintptr>(item.widgetItem->widget());
+}
+#endif
+
+static const int zero = 0;
+
+QDockAreaLayoutInfo::QDockAreaLayoutInfo()
+ : sep(&zero), dockPos(QInternal::LeftDock), o(Qt::Horizontal), mainWindow(0)
+#ifndef QT_NO_TABBAR
+ , tabbed(false), tabBar(0), tabBarShape(QTabBar::RoundedSouth)
+#endif
+{
+}
+
+QDockAreaLayoutInfo::QDockAreaLayoutInfo(const int *_sep, QInternal::DockPosition _dockPos,
+ Qt::Orientation _o, int tbshape,
+ QMainWindow *window)
+ : sep(_sep), dockPos(_dockPos), o(_o), mainWindow(window)
+#ifndef QT_NO_TABBAR
+ , tabbed(false), tabBar(0), tabBarShape(static_cast<QTabBar::Shape>(tbshape))
+#endif
+{
+#ifdef QT_NO_TABBAR
+ Q_UNUSED(tbshape);
+#endif
+}
+
+QSize QDockAreaLayoutInfo::size() const
+{
+ return isEmpty() ? QSize(0, 0) : rect.size();
+}
+
+void QDockAreaLayoutInfo::clear()
+{
+ item_list.clear();
+ rect = QRect();
+#ifndef QT_NO_TABBAR
+ tabbed = false;
+ tabBar = 0;
+#endif
+}
+
+bool QDockAreaLayoutInfo::isEmpty() const
+{
+ return next(-1) == -1;
+}
+
+QSize QDockAreaLayoutInfo::minimumSize() const
+{
+ if (isEmpty())
+ return QSize(0, 0);
+
+ int a = 0, b = 0;
+ bool first = true;
+ for (int i = 0; i < item_list.size(); ++i) {
+ const QDockAreaLayoutItem &item = item_list.at(i);
+ if (item.skip())
+ continue;
+
+ QSize min_size = item.minimumSize();
+#ifndef QT_NO_TABBAR
+ if (tabbed) {
+ a = qMax(a, pick(o, min_size));
+ } else
+#endif
+ {
+ if (!first)
+ a += *sep;
+ a += pick(o, min_size);
+ }
+ b = qMax(b, perp(o, min_size));
+
+ first = false;
+ }
+
+ QSize result;
+ rpick(o, result) = a;
+ rperp(o, result) = b;
+
+#ifndef QT_NO_TABBAR
+ QSize tbm = tabBarMinimumSize();
+ if (!tbm.isNull()) {
+ switch (tabBarShape) {
+ case QTabBar::RoundedNorth:
+ case QTabBar::RoundedSouth:
+ case QTabBar::TriangularNorth:
+ case QTabBar::TriangularSouth:
+ result.rheight() += tbm.height();
+ result.rwidth() = qMax(tbm.width(), result.width());
+ break;
+ case QTabBar::RoundedEast:
+ case QTabBar::RoundedWest:
+ case QTabBar::TriangularEast:
+ case QTabBar::TriangularWest:
+ result.rheight() = qMax(tbm.height(), result.height());
+ result.rwidth() += tbm.width();
+ break;
+ default:
+ break;
+ }
+ }
+#endif // QT_NO_TABBAR
+
+ return result;
+}
+
+QSize QDockAreaLayoutInfo::maximumSize() const
+{
+ if (isEmpty())
+ return QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
+
+ int a = 0, b = QWIDGETSIZE_MAX;
+#ifndef QT_NO_TABBAR
+ if (tabbed)
+ a = QWIDGETSIZE_MAX;
+#endif
+
+ int min_perp = 0;
+
+ bool first = true;
+ for (int i = 0; i < item_list.size(); ++i) {
+ const QDockAreaLayoutItem &item = item_list.at(i);
+ if (item.skip())
+ continue;
+
+ QSize max_size = item.maximumSize();
+ min_perp = qMax(min_perp, perp(o, item.minimumSize()));
+
+#ifndef QT_NO_TABBAR
+ if (tabbed) {
+ a = qMin(a, pick(o, max_size));
+ } else
+#endif
+ {
+ if (!first)
+ a += *sep;
+ a += pick(o, max_size);
+ }
+ b = qMin(b, perp(o, max_size));
+
+ a = qMin(a, int(QWIDGETSIZE_MAX));
+ b = qMin(b, int(QWIDGETSIZE_MAX));
+
+ first = false;
+ }
+
+ b = qMax(b, min_perp);
+
+ QSize result;
+ rpick(o, result) = a;
+ rperp(o, result) = b;
+
+#ifndef QT_NO_TABBAR
+ QSize tbh = tabBarSizeHint();
+ if (!tbh.isNull()) {
+ switch (tabBarShape) {
+ case QTabBar::RoundedNorth:
+ case QTabBar::RoundedSouth:
+ result.rheight() += tbh.height();
+ break;
+ case QTabBar::RoundedEast:
+ case QTabBar::RoundedWest:
+ result.rwidth() += tbh.width();
+ break;
+ default:
+ break;
+ }
+ }
+#endif // QT_NO_TABBAR
+
+ return result;
+}
+
+QSize QDockAreaLayoutInfo::sizeHint() const
+{
+ if (isEmpty())
+ return QSize(0, 0);
+
+ int a = 0, b = 0;
+ int min_perp = 0;
+ int max_perp = QWIDGETSIZE_MAX;
+ const QDockAreaLayoutItem *previous = 0;
+ for (int i = 0; i < item_list.size(); ++i) {
+ const QDockAreaLayoutItem &item = item_list.at(i);
+ if (item.skip())
+ continue;
+
+ bool gap = item.flags & QDockAreaLayoutItem::GapItem;
+
+ QSize size_hint = item.sizeHint();
+ min_perp = qMax(min_perp, perp(o, item.minimumSize()));
+ max_perp = qMin(max_perp, perp(o, item.maximumSize()));
+
+#ifndef QT_NO_TABBAR
+ if (tabbed) {
+ a = qMax(a, gap ? item.size : pick(o, size_hint));
+ } else
+#endif
+ {
+ if (previous && !gap && !(previous->flags & QDockAreaLayoutItem::GapItem)
+ && !previous->hasFixedSize(o)) {
+ a += *sep;
+ }
+ a += gap ? item.size : pick(o, size_hint);
+ }
+ b = qMax(b, perp(o, size_hint));
+
+ previous = &item;
+ }
+
+ max_perp = qMax(max_perp, min_perp);
+ b = qMax(b, min_perp);
+ b = qMin(b, max_perp);
+
+ QSize result;
+ rpick(o, result) = a;
+ rperp(o, result) = b;
+
+#ifndef QT_NO_TABBAR
+ if (tabbed) {
+ QSize tbh = tabBarSizeHint();
+ switch (tabBarShape) {
+ case QTabBar::RoundedNorth:
+ case QTabBar::RoundedSouth:
+ case QTabBar::TriangularNorth:
+ case QTabBar::TriangularSouth:
+ result.rheight() += tbh.height();
+ result.rwidth() = qMax(tbh.width(), result.width());
+ break;
+ case QTabBar::RoundedEast:
+ case QTabBar::RoundedWest:
+ case QTabBar::TriangularEast:
+ case QTabBar::TriangularWest:
+ result.rheight() = qMax(tbh.height(), result.height());
+ result.rwidth() += tbh.width();
+ break;
+ default:
+ break;
+ }
+ }
+#endif // QT_NO_TABBAR
+
+ return result;
+}
+
+bool QDockAreaLayoutInfo::expansive(Qt::Orientation o) const
+{
+ for (int i = 0; i < item_list.size(); ++i) {
+ if (item_list.at(i).expansive(o))
+ return true;
+ }
+ return false;
+}
+
+/* QDockAreaLayoutInfo::maximumSize() doesn't return the real max size. For example,
+ if the layout is empty, it returns QWIDGETSIZE_MAX. This is so that empty dock areas
+ don't constrain the size of the QMainWindow, but sometimes we really need to know the
+ maximum size. Also, these functions take into account widgets that want to keep their
+ size (f.ex. when they are hidden and then shown, they should not change size).
+*/
+
+static int realMinSize(const QDockAreaLayoutInfo &info)
+{
+ int result = 0;
+ bool first = true;
+ for (int i = 0; i < info.item_list.size(); ++i) {
+ const QDockAreaLayoutItem &item = info.item_list.at(i);
+ if (item.skip())
+ continue;
+
+ int min = 0;
+ if ((item.flags & QDockAreaLayoutItem::KeepSize) && item.size != -1)
+ min = item.size;
+ else
+ min = pick(info.o, item.minimumSize());
+
+ if (!first)
+ result += *info.sep;
+ result += min;
+
+ first = false;
+ }
+
+ return result;
+}
+
+static int realMaxSize(const QDockAreaLayoutInfo &info)
+{
+ int result = 0;
+ bool first = true;
+ for (int i = 0; i < info.item_list.size(); ++i) {
+ const QDockAreaLayoutItem &item = info.item_list.at(i);
+ if (item.skip())
+ continue;
+
+ int max = 0;
+ if ((item.flags & QDockAreaLayoutItem::KeepSize) && item.size != -1)
+ max = item.size;
+ else
+ max = pick(info.o, item.maximumSize());
+
+ if (!first)
+ result += *info.sep;
+ result += max;
+
+ if (result >= QWIDGETSIZE_MAX)
+ return QWIDGETSIZE_MAX;
+
+ first = false;
+ }
+
+ return result;
+}
+
+void QDockAreaLayoutInfo::fitItems()
+{
+#ifndef QT_NO_TABBAR
+ if (tabbed) {
+ return;
+ }
+#endif
+
+ QVector<QLayoutStruct> layout_struct_list(item_list.size()*2);
+ int j = 0;
+
+ int size = pick(o, rect.size());
+ int min_size = realMinSize(*this);
+ int max_size = realMaxSize(*this);
+ int last_index = -1;
+
+ const QDockAreaLayoutItem *previous = 0;
+ for (int i = 0; i < item_list.size(); ++i) {
+ QDockAreaLayoutItem &item = item_list[i];
+ if (item.skip())
+ continue;
+
+ bool gap = item.flags & QDockAreaLayoutItem::GapItem;
+ if (previous && !gap) {
+ if (!(previous->flags & QDockAreaLayoutItem::GapItem)) {
+ QLayoutStruct &ls = layout_struct_list[j++];
+ ls.init();
+ ls.minimumSize = ls.maximumSize = ls.sizeHint = previous->hasFixedSize(o) ? 0 : *sep;
+ ls.empty = false;
+ }
+ }
+
+ if (item.flags & QDockAreaLayoutItem::KeepSize) {
+ // Check if the item can keep its size, without violating size constraints
+ // of other items.
+
+ if (size < min_size) {
+ // There is too little space to keep this widget's size
+ item.flags &= ~QDockAreaLayoutItem::KeepSize;
+ min_size -= item.size;
+ min_size += pick(o, item.minimumSize());
+ min_size = qMax(0, min_size);
+ } else if (size > max_size) {
+ // There is too much space to keep this widget's size
+ item.flags &= ~QDockAreaLayoutItem::KeepSize;
+ max_size -= item.size;
+ max_size += pick(o, item.maximumSize());
+ max_size = qMin<int>(QWIDGETSIZE_MAX, max_size);
+ }
+ }
+
+ last_index = j;
+ QLayoutStruct &ls = layout_struct_list[j++];
+ ls.init();
+ ls.empty = false;
+ if (item.flags & QDockAreaLayoutItem::KeepSize) {
+ ls.minimumSize = ls.maximumSize = ls.sizeHint = item.size;
+ ls.expansive = false;
+ ls.stretch = 0;
+ } else {
+ ls.maximumSize = pick(o, item.maximumSize());
+ ls.expansive = item.expansive(o);
+ ls.minimumSize = pick(o, item.minimumSize());
+ ls.sizeHint = item.size == -1 ? pick(o, item.sizeHint()) : item.size;
+ ls.stretch = ls.expansive ? ls.sizeHint : 0;
+ }
+
+ item.flags &= ~QDockAreaLayoutItem::KeepSize;
+ previous = &item;
+ }
+ layout_struct_list.resize(j);
+
+ // If there is more space than the widgets can take (due to maximum size constraints),
+ // we detect it here and stretch the last widget to take up the rest of the space.
+ if (size > max_size && last_index != -1) {
+ layout_struct_list[last_index].maximumSize = QWIDGETSIZE_MAX;
+ layout_struct_list[last_index].expansive = true;
+ }
+
+ qGeomCalc(layout_struct_list, 0, j, pick(o, rect.topLeft()), size, 0);
+
+ j = 0;
+ bool prev_gap = false;
+ bool first = true;
+ for (int i = 0; i < item_list.size(); ++i) {
+ QDockAreaLayoutItem &item = item_list[i];
+ if (item.skip())
+ continue;
+
+ bool gap = item.flags & QDockAreaLayoutItem::GapItem;
+ if (!first && !gap && !prev_gap)
+ ++j;
+
+ const QLayoutStruct &ls = layout_struct_list.at(j++);
+ item.size = ls.size;
+ item.pos = ls.pos;
+
+ if (item.subinfo != 0) {
+ item.subinfo->rect = itemRect(i);
+ item.subinfo->fitItems();
+ }
+
+ prev_gap = gap;
+ first = false;
+ }
+}
+
+static QInternal::DockPosition dockPosHelper(const QRect &rect, const QPoint &_pos,
+ Qt::Orientation o,
+ bool nestingEnabled,
+ QDockAreaLayoutInfo::TabMode tabMode)
+{
+ if (tabMode == QDockAreaLayoutInfo::ForceTabs)
+ return QInternal::DockCount;
+
+ QPoint pos = _pos - rect.topLeft();
+
+ int x = pos.x();
+ int y = pos.y();
+ int w = rect.width();
+ int h = rect.height();
+
+ if (tabMode != QDockAreaLayoutInfo::NoTabs) {
+ // is it in the center?
+ if (nestingEnabled) {
+ /* 2/3
+ +--------------+
+ | |
+ | CCCCCCCC |
+ 2/3 | CCCCCCCC |
+ | CCCCCCCC |
+ | |
+ +--------------+ */
+
+ QRect center(w/6, h/6, 2*w/3, 2*h/3);
+ if (center.contains(pos))
+ return QInternal::DockCount;
+ } else if (o == Qt::Horizontal) {
+ /* 2/3
+ +--------------+
+ | CCCCCCCC |
+ | CCCCCCCC |
+ | CCCCCCCC |
+ | CCCCCCCC |
+ | CCCCCCCC |
+ +--------------+ */
+
+ if (x > w/6 && x < w*5/6)
+ return QInternal::DockCount;
+ } else {
+ /*
+ +--------------+
+ | |
+ 2/3 |CCCCCCCCCCCCCC|
+ |CCCCCCCCCCCCCC|
+ | |
+ +--------------+ */
+ if (y > h/6 && y < 5*h/6)
+ return QInternal::DockCount;
+ }
+ }
+
+ // not in the center. which edge?
+ if (nestingEnabled) {
+ if (o == Qt::Horizontal) {
+ /* 1/3 1/3 1/3
+ +------------+ (we've already ruled out the center)
+ |LLLLTTTTRRRR|
+ |LLLLTTTTRRRR|
+ |LLLLBBBBRRRR|
+ |LLLLBBBBRRRR|
+ +------------+ */
+
+ if (x < w/3)
+ return QInternal::LeftDock;
+ if (x > 2*w/3)
+ return QInternal::RightDock;
+ if (y < h/2)
+ return QInternal::TopDock;
+ return QInternal::BottomDock;
+ } else {
+ /* +------------+ (we've already ruled out the center)
+ 1/3 |TTTTTTTTTTTT|
+ |LLLLLLRRRRRR|
+ 1/3 |LLLLLLRRRRRR|
+ 1/3 |BBBBBBBBBBBB|
+ +------------+ */
+
+ if (y < h/3)
+ return QInternal::TopDock;
+ if (y > 2*h/3)
+ return QInternal::BottomDock;
+ if (x < w/2)
+ return QInternal::LeftDock;
+ return QInternal::RightDock;
+ }
+ } else {
+ if (o == Qt::Horizontal) {
+ return x < w/2
+ ? QInternal::LeftDock
+ : QInternal::RightDock;
+ } else {
+ return y < h/2
+ ? QInternal::TopDock
+ : QInternal::BottomDock;
+ }
+ }
+}
+
+QList<int> QDockAreaLayoutInfo::gapIndex(const QPoint& _pos,
+ bool nestingEnabled, TabMode tabMode) const
+{
+ QList<int> result;
+ QRect item_rect;
+ int item_index = 0;
+
+#ifndef QT_NO_TABBAR
+ if (tabbed) {
+ item_rect = tabContentRect();
+ } else
+#endif
+ {
+ int pos = pick(o, _pos);
+
+ int last = -1;
+ for (int i = 0; i < item_list.size(); ++i) {
+ const QDockAreaLayoutItem &item = item_list.at(i);
+ if (item.skip())
+ continue;
+
+ last = i;
+
+ if (item.pos + item.size < pos)
+ continue;
+
+ if (item.subinfo != 0
+#ifndef QT_NO_TABBAR
+ && !item.subinfo->tabbed
+#endif
+ ) {
+ result = item.subinfo->gapIndex(_pos, nestingEnabled,
+ tabMode);
+ result.prepend(i);
+ return result;
+ }
+
+ item_rect = itemRect(i);
+ item_index = i;
+ break;
+ }
+
+ if (item_rect.isNull()) {
+ result.append(last + 1);
+ return result;
+ }
+ }
+
+ Q_ASSERT(!item_rect.isNull());
+
+ QInternal::DockPosition dock_pos
+ = dockPosHelper(item_rect, _pos, o, nestingEnabled, tabMode);
+
+ switch (dock_pos) {
+ case QInternal::LeftDock:
+ if (o == Qt::Horizontal)
+ result << item_index;
+ else
+ result << item_index << 0; // this subinfo doesn't exist yet, but insertGap()
+ // handles this by inserting it
+ break;
+ case QInternal::RightDock:
+ if (o == Qt::Horizontal)
+ result << item_index + 1;
+ else
+ result << item_index << 1;
+ break;
+ case QInternal::TopDock:
+ if (o == Qt::Horizontal)
+ result << item_index << 0;
+ else
+ result << item_index;
+ break;
+ case QInternal::BottomDock:
+ if (o == Qt::Horizontal)
+ result << item_index << 1;
+ else
+ result << item_index + 1;
+ break;
+ case QInternal::DockCount:
+ result << (-item_index - 1) << 0; // negative item_index means "on top of"
+ // -item_index - 1, insertGap()
+ // will insert a tabbed subinfo
+ break;
+ default:
+ break;
+ }
+
+ return result;
+}
+
+static inline int shrink(QLayoutStruct &ls, int delta)
+{
+ if (ls.empty)
+ return 0;
+ int old_size = ls.size;
+ ls.size = qMax(ls.size - delta, ls.minimumSize);
+ return old_size - ls.size;
+}
+
+static inline int grow(QLayoutStruct &ls, int delta)
+{
+ if (ls.empty)
+ return 0;
+ int old_size = ls.size;
+ ls.size = qMin(ls.size + delta, ls.maximumSize);
+ return ls.size - old_size;
+}
+
+static int separatorMoveHelper(QVector<QLayoutStruct> &list, int index, int delta, int sep)
+{
+ // adjust sizes
+ int pos = -1;
+ for (int i = 0; i < list.size(); ++i) {
+ const QLayoutStruct &ls = list.at(i);
+ if (!ls.empty) {
+ pos = ls.pos;
+ break;
+ }
+ }
+ if (pos == -1)
+ return 0;
+
+ if (delta > 0) {
+ int growlimit = 0;
+ for (int i = 0; i<=index; ++i) {
+ const QLayoutStruct &ls = list.at(i);
+ if (ls.empty)
+ continue;
+ if (ls.maximumSize == QLAYOUTSIZE_MAX) {
+ growlimit = QLAYOUTSIZE_MAX;
+ break;
+ }
+ growlimit += ls.maximumSize - ls.size;
+ }
+ if (delta > growlimit)
+ delta = growlimit;
+
+ int d = 0;
+ for (int i = index + 1; d < delta && i < list.count(); ++i)
+ d += shrink(list[i], delta - d);
+ delta = d;
+ d = 0;
+ for (int i = index; d < delta && i >= 0; --i)
+ d += grow(list[i], delta - d);
+ } else if (delta < 0) {
+ int growlimit = 0;
+ for (int i = index + 1; i < list.count(); ++i) {
+ const QLayoutStruct &ls = list.at(i);
+ if (ls.empty)
+ continue;
+ if (ls.maximumSize == QLAYOUTSIZE_MAX) {
+ growlimit = QLAYOUTSIZE_MAX;
+ break;
+ }
+ growlimit += ls.maximumSize - ls.size;
+ }
+ if (-delta > growlimit)
+ delta = -growlimit;
+
+ int d = 0;
+ for (int i = index; d < -delta && i >= 0; --i)
+ d += shrink(list[i], -delta - d);
+ delta = -d;
+ d = 0;
+ for (int i = index + 1; d < -delta && i < list.count(); ++i)
+ d += grow(list[i], -delta - d);
+ }
+
+ // adjust positions
+ bool first = true;
+ for (int i = 0; i < list.size(); ++i) {
+ QLayoutStruct &ls = list[i];
+ if (ls.empty) {
+ ls.pos = pos + (first ? 0 : sep);
+ continue;
+ }
+ if (!first)
+ pos += sep;
+ ls.pos = pos;
+ pos += ls.size;
+ first = false;
+ }
+
+ return delta;
+}
+
+int QDockAreaLayoutInfo::separatorMove(int index, int delta)
+{
+#ifndef QT_NO_TABBAR
+ Q_ASSERT(!tabbed);
+#endif
+
+ QVector<QLayoutStruct> list(item_list.size());
+ for (int i = 0; i < list.size(); ++i) {
+ const QDockAreaLayoutItem &item = item_list.at(i);
+ QLayoutStruct &ls = list[i];
+ Q_ASSERT(!(item.flags & QDockAreaLayoutItem::GapItem));
+ if (item.skip()) {
+ ls.empty = true;
+ } else {
+ const int separatorSpace = item.hasFixedSize(o) ? 0 : *sep;
+ ls.empty = false;
+ ls.pos = item.pos;
+ ls.size = item.size + separatorSpace;
+ ls.minimumSize = pick(o, item.minimumSize()) + separatorSpace;
+ ls.maximumSize = pick(o, item.maximumSize()) + separatorSpace;
+
+ }
+ }
+
+ //the separator space has been added to the size, so we pass 0 as a parameter
+ delta = separatorMoveHelper(list, index, delta, 0 /*separator*/);
+
+ for (int i = 0; i < list.size(); ++i) {
+ QDockAreaLayoutItem &item = item_list[i];
+ if (item.skip())
+ continue;
+ QLayoutStruct &ls = list[i];
+ const int separatorSpace = item.hasFixedSize(o) ? 0 : *sep;
+ item.size = ls.size - separatorSpace;
+ item.pos = ls.pos;
+ if (item.subinfo != 0) {
+ item.subinfo->rect = itemRect(i);
+ item.subinfo->fitItems();
+ }
+ }
+
+ return delta;
+}
+
+void QDockAreaLayoutInfo::unnest(int index)
+{
+ QDockAreaLayoutItem &item = item_list[index];
+ if (item.subinfo == 0)
+ return;
+ if (item.subinfo->item_list.count() > 1)
+ return;
+
+ if (item.subinfo->item_list.count() == 0) {
+ item_list.removeAt(index);
+ } else if (item.subinfo->item_list.count() == 1) {
+ QDockAreaLayoutItem &child = item.subinfo->item_list.first();
+ if (child.widgetItem != 0) {
+ item.widgetItem = child.widgetItem;
+ delete item.subinfo;
+ item.subinfo = 0;
+ } else if (child.subinfo != 0) {
+ QDockAreaLayoutInfo *tmp = item.subinfo;
+ item.subinfo = child.subinfo;
+ child.subinfo = 0;
+ tmp->item_list.clear();
+ delete tmp;
+ }
+ }
+}
+
+void QDockAreaLayoutInfo::remove(const QList<int> &path)
+{
+ Q_ASSERT(!path.isEmpty());
+
+ if (path.count() > 1) {
+ const int index = path.first();
+ QDockAreaLayoutItem &item = item_list[index];
+ Q_ASSERT(item.subinfo != 0);
+ item.subinfo->remove(path.mid(1));
+ unnest(index);
+ } else {
+ int index = path.first();
+ item_list.removeAt(index);
+ }
+}
+
+QLayoutItem *QDockAreaLayoutInfo::plug(const QList<int> &path)
+{
+ Q_ASSERT(!path.isEmpty());
+
+ int index = path.first();
+ if (index < 0)
+ index = -index - 1;
+
+ if (path.count() > 1) {
+ const QDockAreaLayoutItem &item = item_list.at(index);
+ Q_ASSERT(item.subinfo != 0);
+ return item.subinfo->plug(path.mid(1));
+ }
+
+ QDockAreaLayoutItem &item = item_list[index];
+
+ Q_ASSERT(item.widgetItem != 0);
+ Q_ASSERT(item.flags & QDockAreaLayoutItem::GapItem);
+ item.flags &= ~QDockAreaLayoutItem::GapItem;
+
+ QRect result;
+
+#ifndef QT_NO_TABBAR
+ if (tabbed) {
+ } else
+#endif
+ {
+ int prev = this->prev(index);
+ int next = this->next(index);
+
+ if (prev != -1 && !(item_list.at(prev).flags & QDockAreaLayoutItem::GapItem)) {
+ item.pos += *sep;
+ item.size -= *sep;
+ }
+ if (next != -1 && !(item_list.at(next).flags & QDockAreaLayoutItem::GapItem))
+ item.size -= *sep;
+
+ QPoint pos;
+ rpick(o, pos) = item.pos;
+ rperp(o, pos) = perp(o, rect.topLeft());
+ QSize s;
+ rpick(o, s) = item.size;
+ rperp(o, s) = perp(o, rect.size());
+ result = QRect(pos, s);
+ }
+
+ return item.widgetItem;
+}
+
+QLayoutItem *QDockAreaLayoutInfo::unplug(const QList<int> &path)
+{
+ Q_ASSERT(!path.isEmpty());
+
+ const int index = path.first();
+ if (path.count() > 1) {
+ const QDockAreaLayoutItem &item = item_list.at(index);
+ Q_ASSERT(item.subinfo != 0);
+ return item.subinfo->unplug(path.mid(1));
+ }
+
+ QDockAreaLayoutItem &item = item_list[index];
+ int prev = this->prev(index);
+ int next = this->next(index);
+
+ Q_ASSERT(!(item.flags & QDockAreaLayoutItem::GapItem));
+ item.flags |= QDockAreaLayoutItem::GapItem;
+
+#ifndef QT_NO_TABBAR
+ if (tabbed) {
+ } else
+#endif
+ {
+ if (prev != -1 && !(item_list.at(prev).flags & QDockAreaLayoutItem::GapItem)) {
+ item.pos -= *sep;
+ item.size += *sep;
+ }
+ if (next != -1 && !(item_list.at(next).flags & QDockAreaLayoutItem::GapItem))
+ item.size += *sep;
+ }
+
+ return item.widgetItem;
+}
+
+#ifndef QT_NO_TABBAR
+
+quintptr QDockAreaLayoutInfo::currentTabId() const
+{
+ if (!tabbed || tabBar == 0)
+ return 0;
+
+ int index = tabBar->currentIndex();
+ if (index == -1)
+ return 0;
+
+ return qvariant_cast<quintptr>(tabBar->tabData(index));
+}
+
+void QDockAreaLayoutInfo::setCurrentTab(QWidget *widget)
+{
+ setCurrentTabId(reinterpret_cast<quintptr>(widget));
+}
+
+void QDockAreaLayoutInfo::setCurrentTabId(quintptr id)
+{
+ if (!tabbed || tabBar == 0)
+ return;
+
+ for (int i = 0; i < tabBar->count(); ++i) {
+ if (qvariant_cast<quintptr>(tabBar->tabData(i)) == id) {
+ tabBar->setCurrentIndex(i);
+ return;
+ }
+ }
+}
+
+#endif // QT_NO_TABBAR
+
+static QRect dockedGeometry(QWidget *widget)
+{
+ int titleHeight = 0;
+
+ QDockWidgetLayout *layout
+ = qobject_cast<QDockWidgetLayout*>(widget->layout());
+ if(layout != 0 && layout->nativeWindowDeco())
+ titleHeight = layout->titleHeight();
+
+ QRect result = widget->geometry();
+ result.adjust(0, -titleHeight, 0, 0);
+ return result;
+}
+
+bool QDockAreaLayoutInfo::insertGap(const QList<int> &path, QLayoutItem *dockWidgetItem)
+{
+ Q_ASSERT(!path.isEmpty());
+
+ bool insert_tabbed = false;
+ int index = path.first();
+ if (index < 0) {
+ insert_tabbed = true;
+ index = -index - 1;
+ }
+
+// dump(qDebug() << "insertGap() before:" << index << tabIndex, *this, QString());
+
+ if (path.count() > 1) {
+ QDockAreaLayoutItem &item = item_list[index];
+
+ if (item.subinfo == 0
+#ifndef QT_NO_TABBAR
+ || (item.subinfo->tabbed && !insert_tabbed)
+#endif
+ ) {
+
+ // this is not yet a nested layout - make it
+
+ QDockAreaLayoutInfo *subinfo = item.subinfo;
+ QLayoutItem *widgetItem = item.widgetItem;
+ QPlaceHolderItem *placeHolderItem = item.placeHolderItem;
+ QRect r = subinfo == 0 ? widgetItem ? dockedGeometry(widgetItem->widget()) : placeHolderItem->topLevelRect : subinfo->rect;
+
+ Qt::Orientation opposite = o == Qt::Horizontal ? Qt::Vertical : Qt::Horizontal;
+#ifdef QT_NO_TABBAR
+ const int tabBarShape = 0;
+#endif
+ QDockAreaLayoutInfo *new_info
+ = new QDockAreaLayoutInfo(sep, dockPos, opposite, tabBarShape, mainWindow);
+
+ //item become a new top-level
+ item.subinfo = new_info;
+ item.widgetItem = 0;
+ item.placeHolderItem = 0;
+
+ QDockAreaLayoutItem new_item
+ = widgetItem == 0
+ ? QDockAreaLayoutItem(subinfo)
+ : widgetItem ? QDockAreaLayoutItem(widgetItem) : QDockAreaLayoutItem(placeHolderItem);
+ new_item.size = pick(opposite, r.size());
+ new_item.pos = pick(opposite, r.topLeft());
+ new_info->item_list.append(new_item);
+#ifndef QT_NO_TABBAR
+ if (insert_tabbed) {
+ new_info->tabbed = true;
+ }
+#endif
+ }
+
+ return item.subinfo->insertGap(path.mid(1), dockWidgetItem);
+ }
+
+ // create the gap item
+ QDockAreaLayoutItem gap_item;
+ gap_item.flags |= QDockAreaLayoutItem::GapItem;
+ gap_item.widgetItem = dockWidgetItem; // so minimumSize(), maximumSize() and
+ // sizeHint() will work
+#ifndef QT_NO_TABBAR
+ if (!tabbed)
+#endif
+ {
+ int prev = this->prev(index);
+ int next = this->next(index - 1);
+ // find out how much space we have in the layout
+ int space = 0;
+ if (isEmpty()) {
+ // I am an empty dock area, therefore I am a top-level dock area.
+ switch (dockPos) {
+ case QInternal::LeftDock:
+ case QInternal::RightDock:
+ if (o == Qt::Vertical) {
+ // the "size" is the height of the dock area (remember we are empty)
+ space = pick(Qt::Vertical, rect.size());
+ } else {
+ space = pick(Qt::Horizontal, dockWidgetItem->widget()->size());
+ }
+ break;
+ case QInternal::TopDock:
+ case QInternal::BottomDock:
+ default:
+ if (o == Qt::Horizontal) {
+ // the "size" is width of the dock area
+ space = pick(Qt::Horizontal, rect.size());
+ } else {
+ space = pick(Qt::Vertical, dockWidgetItem->widget()->size());
+ }
+ break;
+ }
+ } else {
+ for (int i = 0; i < item_list.count(); ++i) {
+ const QDockAreaLayoutItem &item = item_list.at(i);
+ if (item.skip())
+ continue;
+ Q_ASSERT(!(item.flags & QDockAreaLayoutItem::GapItem));
+ space += item.size - pick(o, item.minimumSize());
+ }
+ }
+
+ // find the actual size of the gap
+ int gap_size = 0;
+ int sep_size = 0;
+ if (isEmpty()) {
+ gap_size = space;
+ sep_size = 0;
+ } else {
+ QRect r = dockedGeometry(dockWidgetItem->widget());
+ gap_size = pick(o, r.size());
+ if (prev != -1 && !(item_list.at(prev).flags & QDockAreaLayoutItem::GapItem))
+ sep_size += *sep;
+ if (next != -1 && !(item_list.at(next).flags & QDockAreaLayoutItem::GapItem))
+ sep_size += *sep;
+ }
+ if (gap_size + sep_size > space)
+ gap_size = pick(o, gap_item.minimumSize());
+ gap_item.size = gap_size + sep_size;
+ }
+
+ // finally, insert the gap
+ item_list.insert(index, gap_item);
+
+// dump(qDebug() << "insertGap() after:" << index << tabIndex, *this, QString());
+
+ return true;
+}
+
+QDockAreaLayoutInfo *QDockAreaLayoutInfo::info(QWidget *widget)
+{
+ for (int i = 0; i < item_list.count(); ++i) {
+ const QDockAreaLayoutItem &item = item_list.at(i);
+ if (item.skip())
+ continue;
+
+#ifndef QT_NO_TABBAR
+ if (tabbed && widget == tabBar)
+ return this;
+#endif
+
+ if (item.widgetItem != 0 && item.widgetItem->widget() == widget)
+ return this;
+
+ if (item.subinfo != 0) {
+ if (QDockAreaLayoutInfo *result = item.subinfo->info(widget))
+ return result;
+ }
+ }
+
+ return 0;
+}
+
+QDockAreaLayoutInfo *QDockAreaLayoutInfo::info(const QList<int> &path)
+{
+ int index = path.first();
+ if (index < 0)
+ index = -index - 1;
+ if (index >= item_list.count())
+ return this;
+ if (path.count() == 1 || item_list[index].subinfo == 0)
+ return this;
+ return item_list[index].subinfo->info(path.mid(1));
+}
+
+QRect QDockAreaLayoutInfo::itemRect(int index) const
+{
+ const QDockAreaLayoutItem &item = item_list.at(index);
+
+ if (item.skip())
+ return QRect();
+
+ QRect result;
+
+#ifndef QT_NO_TABBAR
+ if (tabbed) {
+ if (tabId(item) == currentTabId())
+ result = tabContentRect();
+ } else
+#endif
+ {
+ QPoint pos;
+ rpick(o, pos) = item.pos;
+ rperp(o, pos) = perp(o, rect.topLeft());
+ QSize s;
+ rpick(o, s) = item.size;
+ rperp(o, s) = perp(o, rect.size());
+ result = QRect(pos, s);
+ }
+
+ return result;
+}
+
+QRect QDockAreaLayoutInfo::itemRect(const QList<int> &path) const
+{
+ Q_ASSERT(!path.isEmpty());
+
+ const int index = path.first();
+ if (path.count() > 1) {
+ const QDockAreaLayoutItem &item = item_list.at(index);
+ Q_ASSERT(item.subinfo != 0);
+ return item.subinfo->itemRect(path.mid(1));
+ }
+
+ return itemRect(index);
+}
+
+QRect QDockAreaLayoutInfo::separatorRect(int index) const
+{
+#ifndef QT_NO_TABBAR
+ if (tabbed)
+ return QRect();
+#endif
+
+ const QDockAreaLayoutItem &item = item_list.at(index);
+ if (item.skip())
+ return QRect();
+
+ QPoint pos = rect.topLeft();
+ rpick(o, pos) = item.pos + item.size;
+ QSize s = rect.size();
+ rpick(o, s) = *sep;
+
+ return QRect(pos, s);
+}
+
+QRect QDockAreaLayoutInfo::separatorRect(const QList<int> &path) const
+{
+ Q_ASSERT(!path.isEmpty());
+
+ const int index = path.first();
+ if (path.count() > 1) {
+ const QDockAreaLayoutItem &item = item_list.at(index);
+ Q_ASSERT(item.subinfo != 0);
+ return item.subinfo->separatorRect(path.mid(1));
+ }
+ return separatorRect(index);
+}
+
+QList<int> QDockAreaLayoutInfo::findSeparator(const QPoint &_pos) const
+{
+#ifndef QT_NO_TABBAR
+ if (tabbed)
+ return QList<int>();
+#endif
+
+ int pos = pick(o, _pos);
+
+ for (int i = 0; i < item_list.size(); ++i) {
+ const QDockAreaLayoutItem &item = item_list.at(i);
+ if (item.skip() || (item.flags & QDockAreaLayoutItem::GapItem))
+ continue;
+
+ if (item.pos + item.size > pos) {
+ if (item.subinfo != 0) {
+ QList<int> result = item.subinfo->findSeparator(_pos);
+ if (!result.isEmpty()) {
+ result.prepend(i);
+ return result;
+ } else {
+ return QList<int>();
+ }
+ }
+ }
+
+ int next = this->next(i);
+ if (next == -1 || (item_list.at(next).flags & QDockAreaLayoutItem::GapItem))
+ continue;
+
+ QRect sepRect = separatorRect(i);
+ if (!sepRect.isNull() && *sep == 1)
+ sepRect.adjust(-2, -2, 2, 2);
+ //we also make sure we don't find a separator that's not there
+ if (sepRect.contains(_pos) && !item.hasFixedSize(o)) {
+ return QList<int>() << i;
+ }
+
+ }
+
+ return QList<int>();
+}
+
+QList<int> QDockAreaLayoutInfo::indexOfPlaceHolder(const QString &objectName) const
+{
+ for (int i = 0; i < item_list.size(); ++i) {
+ const QDockAreaLayoutItem &item = item_list.at(i);
+
+ if (item.subinfo != 0) {
+ QList<int> result = item.subinfo->indexOfPlaceHolder(objectName);
+ if (!result.isEmpty()) {
+ result.prepend(i);
+ return result;
+ }
+ continue;
+ }
+
+ if (item.placeHolderItem != 0 && item.placeHolderItem->objectName == objectName) {
+ QList<int> result;
+ result << i;
+ return result;
+ }
+ }
+
+ return QList<int>();
+}
+
+QList<int> QDockAreaLayoutInfo::indexOf(QWidget *widget) const
+{
+ for (int i = 0; i < item_list.size(); ++i) {
+ const QDockAreaLayoutItem &item = item_list.at(i);
+
+ if (item.placeHolderItem != 0)
+ continue;
+
+ if (item.subinfo != 0) {
+ QList<int> result = item.subinfo->indexOf(widget);
+ if (!result.isEmpty()) {
+ result.prepend(i);
+ return result;
+ }
+ continue;
+ }
+
+ if (!(item.flags & QDockAreaLayoutItem::GapItem) && item.widgetItem->widget() == widget) {
+ QList<int> result;
+ result << i;
+ return result;
+ }
+ }
+
+ return QList<int>();
+}
+
+QMainWindowLayout *QDockAreaLayoutInfo::mainWindowLayout() const
+{
+ QMainWindowLayout *result = qt_mainwindow_layout(mainWindow);
+ Q_ASSERT(result != 0);
+ return result;
+}
+
+bool QDockAreaLayoutInfo::hasFixedSize() const
+{
+ return perp(o, minimumSize()) == perp(o, maximumSize());
+}
+
+
+void QDockAreaLayoutInfo::apply(bool animate)
+{
+ QWidgetAnimator &widgetAnimator = mainWindowLayout()->widgetAnimator;
+
+#ifndef QT_NO_TABBAR
+ if (tabbed) {
+ QRect tab_rect;
+ QSize tbh = tabBarSizeHint();
+
+ if (!tbh.isNull()) {
+ switch (tabBarShape) {
+ case QTabBar::RoundedNorth:
+ case QTabBar::TriangularNorth:
+ tab_rect = QRect(rect.left(), rect.top(), rect.width(), tbh.height());
+ break;
+ case QTabBar::RoundedSouth:
+ case QTabBar::TriangularSouth:
+ tab_rect = QRect(rect.left(), rect.bottom() - tbh.height() + 1,
+ rect.width(), tbh.height());
+ break;
+ case QTabBar::RoundedEast:
+ case QTabBar::TriangularEast:
+ tab_rect = QRect(rect.right() - tbh.width() + 1, rect.top(),
+ tbh.width(), rect.height());
+ break;
+ case QTabBar::RoundedWest:
+ case QTabBar::TriangularWest:
+ tab_rect = QRect(rect.left(), rect.top(),
+ tbh.width(), rect.height());
+ break;
+ default:
+ break;
+ }
+ }
+
+ widgetAnimator.animate(tabBar, tab_rect, animate);
+ }
+#endif // QT_NO_TABBAR
+
+ for (int i = 0; i < item_list.size(); ++i) {
+ QDockAreaLayoutItem &item = item_list[i];
+
+ if (item.flags & QDockAreaLayoutItem::GapItem)
+ continue;
+
+ if (item.subinfo != 0) {
+ item.subinfo->apply(animate);
+ continue;
+ }
+
+ if (item.skip())
+ continue;
+
+ Q_ASSERT(item.widgetItem);
+ QRect r = itemRect(i);
+ QWidget *w = item.widgetItem->widget();
+
+ QRect geo = w->geometry();
+ widgetAnimator.animate(w, r, animate);
+ if (!w->isHidden() && w->window()->isVisible()) {
+ QDockWidget *dw = qobject_cast<QDockWidget*>(w);
+ if (!r.isValid() && geo.right() >= 0 && geo.bottom() >= 0) {
+ dw->lower();
+ emit dw->visibilityChanged(false);
+ } else if (r.isValid()
+ && (geo.right() < 0 || geo.bottom() < 0)) {
+ emit dw->visibilityChanged(true);
+ }
+ }
+ }
+#ifndef QT_NO_TABBAR
+ if (*sep == 1)
+ updateSeparatorWidgets();
+#endif //QT_NO_TABBAR
+}
+
+static void paintSep(QPainter *p, QWidget *w, const QRect &r, Qt::Orientation o, bool mouse_over)
+{
+ QStyleOption opt(0);
+ opt.state = QStyle::State_None;
+ if (w->isEnabled())
+ opt.state |= QStyle::State_Enabled;
+ if (o != Qt::Horizontal)
+ opt.state |= QStyle::State_Horizontal;
+ if (mouse_over)
+ opt.state |= QStyle::State_MouseOver;
+ opt.rect = r;
+ opt.palette = w->palette();
+
+ w->style()->drawPrimitive(QStyle::PE_IndicatorDockWidgetResizeHandle, &opt, p, w);
+}
+
+QRegion QDockAreaLayoutInfo::separatorRegion() const
+{
+ QRegion result;
+
+ if (isEmpty())
+ return result;
+#ifndef QT_NO_TABBAR
+ if (tabbed)
+ return result;
+#endif
+
+ for (int i = 0; i < item_list.count(); ++i) {
+ const QDockAreaLayoutItem &item = item_list.at(i);
+
+ if (item.skip())
+ continue;
+
+ int next = this->next(i);
+
+ if (item.subinfo)
+ result |= item.subinfo->separatorRegion();
+
+ if (next == -1)
+ break;
+ result |= separatorRect(i);
+ }
+
+ return result;
+}
+
+void QDockAreaLayoutInfo::paintSeparators(QPainter *p, QWidget *widget,
+ const QRegion &clip,
+ const QPoint &mouse) const
+{
+ if (isEmpty())
+ return;
+#ifndef QT_NO_TABBAR
+ if (tabbed)
+ return;
+#endif
+
+ for (int i = 0; i < item_list.count(); ++i) {
+ const QDockAreaLayoutItem &item = item_list.at(i);
+
+ if (item.skip())
+ continue;
+
+ int next = this->next(i);
+ if ((item.flags & QDockAreaLayoutItem::GapItem)
+ || (next != -1 && (item_list.at(next).flags & QDockAreaLayoutItem::GapItem)))
+ continue;
+
+ if (item.subinfo) {
+ if (clip.contains(item.subinfo->rect))
+ item.subinfo->paintSeparators(p, widget, clip, mouse);
+ }
+
+ if (next == -1)
+ break;
+ QRect r = separatorRect(i);
+ if (clip.contains(r) && !item.hasFixedSize(o))
+ paintSep(p, widget, r, o, r.contains(mouse));
+ }
+}
+
+int QDockAreaLayoutInfo::next(int index) const
+{
+ for (int i = index + 1; i < item_list.size(); ++i) {
+ if (!item_list.at(i).skip())
+ return i;
+ }
+ return -1;
+}
+
+int QDockAreaLayoutInfo::prev(int index) const
+{
+ for (int i = index - 1; i >= 0; --i) {
+ if (!item_list.at(i).skip())
+ return i;
+ }
+ return -1;
+}
+
+void QDockAreaLayoutInfo::tab(int index, QLayoutItem *dockWidgetItem)
+{
+#ifdef QT_NO_TABBAR
+ Q_UNUSED(index);
+ Q_UNUSED(dockWidgetItem);
+#else
+ if (tabbed) {
+ item_list.append(QDockAreaLayoutItem(dockWidgetItem));
+ updateTabBar();
+ setCurrentTab(dockWidgetItem->widget());
+ } else {
+ QDockAreaLayoutInfo *new_info
+ = new QDockAreaLayoutInfo(sep, dockPos, o, tabBarShape, mainWindow);
+ item_list[index].subinfo = new_info;
+ new_info->item_list.append(item_list.at(index).widgetItem);
+ item_list[index].widgetItem = 0;
+ new_info->item_list.append(dockWidgetItem);
+ new_info->tabbed = true;
+ new_info->updateTabBar();
+ new_info->setCurrentTab(dockWidgetItem->widget());
+ }
+#endif // QT_NO_TABBAR
+}
+
+void QDockAreaLayoutInfo::split(int index, Qt::Orientation orientation,
+ QLayoutItem *dockWidgetItem)
+{
+ if (orientation == o) {
+ item_list.insert(index + 1, QDockAreaLayoutItem(dockWidgetItem));
+ } else {
+#ifdef QT_NO_TABBAR
+ const int tabBarShape = 0;
+#endif
+ QDockAreaLayoutInfo *new_info
+ = new QDockAreaLayoutInfo(sep, dockPos, orientation, tabBarShape, mainWindow);
+ item_list[index].subinfo = new_info;
+ new_info->item_list.append(item_list.at(index).widgetItem);
+ item_list[index].widgetItem = 0;
+ new_info->item_list.append(dockWidgetItem);
+ }
+}
+
+QDockAreaLayoutItem &QDockAreaLayoutInfo::item(const QList<int> &path)
+{
+ Q_ASSERT(!path.isEmpty());
+ const int index = path.first();
+ if (path.count() > 1) {
+ const QDockAreaLayoutItem &item = item_list[index];
+ Q_ASSERT(item.subinfo != 0);
+ return item.subinfo->item(path.mid(1));
+ }
+ return item_list[index];
+}
+
+QLayoutItem *QDockAreaLayoutInfo::itemAt(int *x, int index) const
+{
+ for (int i = 0; i < item_list.count(); ++i) {
+ const QDockAreaLayoutItem &item = item_list.at(i);
+ if (item.placeHolderItem != 0)
+ continue;
+ if (item.subinfo) {
+ if (QLayoutItem *ret = item.subinfo->itemAt(x, index))
+ return ret;
+ } else if (item.widgetItem) {
+ if ((*x)++ == index)
+ return item.widgetItem;
+ }
+ }
+ return 0;
+}
+
+QLayoutItem *QDockAreaLayoutInfo::takeAt(int *x, int index)
+{
+ for (int i = 0; i < item_list.count(); ++i) {
+ QDockAreaLayoutItem &item = item_list[i];
+ if (item.placeHolderItem != 0)
+ continue;
+ else if (item.subinfo) {
+ if (QLayoutItem *ret = item.subinfo->takeAt(x, index)) {
+ unnest(i);
+ return ret;
+ }
+ } else if (item.widgetItem) {
+ if ((*x)++ == index) {
+ item.placeHolderItem = new QPlaceHolderItem(item.widgetItem->widget());
+ QLayoutItem *ret = item.widgetItem;
+ item.widgetItem = 0;
+ if (item.size != -1)
+ item.flags |= QDockAreaLayoutItem::KeepSize;
+ return ret;
+ }
+ }
+ }
+ return 0;
+}
+
+void QDockAreaLayoutInfo::deleteAllLayoutItems()
+{
+ for (int i = 0; i < item_list.count(); ++i) {
+ QDockAreaLayoutItem &item= item_list[i];
+ if (item.subinfo) {
+ item.subinfo->deleteAllLayoutItems();
+ } else {
+ delete item.widgetItem;
+ item.widgetItem = 0;
+ }
+ }
+}
+
+void QDockAreaLayoutInfo::saveState(QDataStream &stream) const
+{
+#ifndef QT_NO_TABBAR
+ if (tabbed) {
+ stream << (uchar) TabMarker;
+
+ // write the index in item_list of the widget that's currently on top.
+ quintptr id = currentTabId();
+ int index = -1;
+ for (int i = 0; i < item_list.count(); ++i) {
+ if (tabId(item_list.at(i)) == id) {
+ index = i;
+ break;
+ }
+ }
+ stream << index;
+ } else
+#endif // QT_NO_TABBAR
+ {
+ stream << (uchar) SequenceMarker;
+ }
+
+ stream << (uchar) o << item_list.count();
+
+ for (int i = 0; i < item_list.count(); ++i) {
+ const QDockAreaLayoutItem &item = item_list.at(i);
+ if (item.widgetItem != 0) {
+ stream << (uchar) WidgetMarker;
+ QWidget *w = item.widgetItem->widget();
+ QString name = w->objectName();
+ if (name.isEmpty()) {
+ qWarning("QMainWindow::saveState(): 'objectName' not set for QDockWidget %p '%s;",
+ w, qPrintable(w->windowTitle()));
+ }
+ stream << name;
+
+ uchar flags = 0;
+ if (!w->isHidden())
+ flags |= StateFlagVisible;
+ if (w->isWindow())
+ flags |= StateFlagFloating;
+ stream << flags;
+
+ if (w->isWindow()) {
+ stream << w->x() << w->y() << w->width() << w->height();
+ } else {
+ stream << item.pos << item.size << pick(o, item.minimumSize())
+ << pick(o, item.maximumSize());
+ }
+ } else if (item.placeHolderItem != 0) {
+ stream << (uchar) WidgetMarker;
+ stream << item.placeHolderItem->objectName;
+ uchar flags = 0;
+ if (!item.placeHolderItem->hidden)
+ flags |= StateFlagVisible;
+ if (item.placeHolderItem->window)
+ flags |= StateFlagFloating;
+ stream << flags;
+ if (item.placeHolderItem->window) {
+ QRect r = item.placeHolderItem->topLevelRect;
+ stream << r.x() << r.y() << r.width() << r.height();
+ } else {
+ stream << item.pos << item.size << (int)0 << (int)0;
+ }
+ } else if (item.subinfo != 0) {
+ stream << (uchar) SequenceMarker << item.pos << item.size << pick(o, item.minimumSize()) << pick(o, item.maximumSize());
+ item.subinfo->saveState(stream);
+ }
+ }
+}
+
+static Qt::DockWidgetArea toDockWidgetArea(QInternal::DockPosition pos)
+{
+ switch (pos) {
+ case QInternal::LeftDock: return Qt::LeftDockWidgetArea;
+ case QInternal::RightDock: return Qt::RightDockWidgetArea;
+ case QInternal::TopDock: return Qt::TopDockWidgetArea;
+ case QInternal::BottomDock: return Qt::BottomDockWidgetArea;
+ default: break;
+ }
+ return Qt::NoDockWidgetArea;
+}
+
+static QRect constrainedRect(QRect rect, const QRect &desktop)
+{
+ if (desktop.isValid()) {
+ rect.setWidth(qMin(rect.width(), desktop.width()));
+ rect.setHeight(qMin(rect.height(), desktop.height()));
+ rect.moveLeft(qMax(rect.left(), desktop.left()));
+ rect.moveTop(qMax(rect.top(), desktop.top()));
+ rect.moveRight(qMin(rect.right(), desktop.right()));
+ rect.moveBottom(qMin(rect.bottom(), desktop.bottom()));
+ }
+
+ return rect;
+}
+
+bool QDockAreaLayoutInfo::restoreState(QDataStream &stream, QList<QDockWidget*> &widgets, bool testing)
+{
+ uchar marker;
+ stream >> marker;
+ if (marker != TabMarker && marker != SequenceMarker)
+ return false;
+
+#ifndef QT_NO_TABBAR
+ tabbed = marker == TabMarker;
+
+ int index = -1;
+ if (tabbed)
+ stream >> index;
+#endif
+
+ uchar orientation;
+ stream >> orientation;
+ o = static_cast<Qt::Orientation>(orientation);
+
+ int cnt;
+ stream >> cnt;
+
+ for (int i = 0; i < cnt; ++i) {
+ uchar nextMarker;
+ stream >> nextMarker;
+ if (nextMarker == WidgetMarker) {
+ QString name;
+ uchar flags;
+ stream >> name >> flags;
+ if (name.isEmpty()) {
+ int dummy;
+ stream >> dummy >> dummy >> dummy >> dummy;
+ continue;
+ }
+
+ QDockWidget *widget = 0;
+ for (int j = 0; j < widgets.count(); ++j) {
+ if (widgets.at(j)->objectName() == name) {
+ widget = widgets.takeAt(j);
+ break;
+ }
+ }
+
+ if (widget == 0) {
+ QPlaceHolderItem *placeHolder = new QPlaceHolderItem;
+ QDockAreaLayoutItem item(placeHolder);
+
+ placeHolder->objectName = name;
+ placeHolder->window = flags & StateFlagFloating;
+ placeHolder->hidden = !(flags & StateFlagVisible);
+ if (placeHolder->window) {
+ int x, y, w, h;
+ stream >> x >> y >> w >> h;
+ placeHolder->topLevelRect = QRect(x, y, w, h);
+ } else {
+ int dummy;
+ stream >> item.pos >> item.size >> dummy >> dummy;
+ }
+ if (item.size != -1)
+ item.flags |= QDockAreaLayoutItem::KeepSize;
+ if (!testing)
+ item_list.append(item);
+ } else {
+ QDockAreaLayoutItem item(new QDockWidgetItem(widget));
+ if (flags & StateFlagFloating) {
+ bool drawer = false;
+#ifdef Q_WS_MAC // drawer support
+ extern bool qt_mac_is_macdrawer(const QWidget *); //qwidget_mac.cpp
+ extern bool qt_mac_set_drawer_preferred_edge(QWidget *, Qt::DockWidgetArea); //qwidget_mac.cpp
+ drawer = qt_mac_is_macdrawer(widget);
+#endif
+
+ if (!testing) {
+ widget->hide();
+ if (!drawer)
+ widget->setFloating(true);
+ }
+
+ int x, y, w, h;
+ stream >> x >> y >> w >> h;
+
+#ifdef Q_WS_MAC // drawer support
+ if (drawer) {
+ mainWindow->window()->createWinId();
+ widget->window()->createWinId();
+ qt_mac_set_drawer_preferred_edge(widget, toDockWidgetArea(dockPos));
+ } else
+#endif
+ if (!testing) {
+ QRect r(x, y, w, h);
+ QDesktopWidget *desktop = QApplication::desktop();
+ if (desktop->isVirtualDesktop())
+ r = constrainedRect(r, desktop->screenGeometry(desktop->screenNumber(r.topLeft())));
+ else
+ r = constrainedRect(r, desktop->screenGeometry(widget));
+ widget->move(r.topLeft());
+ widget->resize(r.size());
+ }
+
+ if (!testing) {
+ widget->setVisible(flags & StateFlagVisible);
+ item_list.append(item);
+ }
+ } else {
+ int dummy;
+ stream >> item.pos >> item.size >> dummy >> dummy;
+ if (!testing) {
+ item_list.append(item);
+ widget->setFloating(false);
+ widget->setVisible(flags & StateFlagVisible);
+ emit widget->dockLocationChanged(toDockWidgetArea(dockPos));
+ }
+ }
+ if (testing) {
+ //was it is not really added to the layout, we need to delete the object here
+ delete item.widgetItem;
+ }
+ }
+ } else if (nextMarker == SequenceMarker) {
+ int dummy;
+#ifdef QT_NO_TABBAR
+ const int tabBarShape = 0;
+#endif
+ QDockAreaLayoutItem item(new QDockAreaLayoutInfo(sep, dockPos, o,
+ tabBarShape, mainWindow));
+ stream >> item.pos >> item.size >> dummy >> dummy;
+ //we need to make sure the element is in the list so the dock widget can eventually be docked correctly
+ if (!testing)
+ item_list.append(item);
+
+ //here we need to make sure we change the item in the item_list
+ QDockAreaLayoutItem &lastItem = testing ? item : item_list.last();
+
+ if (!lastItem.subinfo->restoreState(stream, widgets, testing))
+ return false;
+
+ } else {
+ return false;
+ }
+ }
+
+#ifndef QT_NO_TABBAR
+ if (!testing && tabbed && index >= 0 && index < item_list.count()) {
+ updateTabBar();
+ setCurrentTabId(tabId(item_list.at(index)));
+ }
+ if (!testing && *sep == 1)
+ updateSeparatorWidgets();
+#endif
+
+ return true;
+}
+
+#ifndef QT_NO_TABBAR
+void QDockAreaLayoutInfo::updateSeparatorWidgets() const
+{
+ if (tabbed) {
+ separatorWidgets.clear();
+ return;
+ }
+
+ int j = 0;
+ for (int i = 0; i < item_list.count(); ++i) {
+ const QDockAreaLayoutItem &item = item_list.at(i);
+
+ if (item.skip())
+ continue;
+
+ int next = this->next(i);
+ if ((item.flags & QDockAreaLayoutItem::GapItem)
+ || (next != -1 && (item_list.at(next).flags & QDockAreaLayoutItem::GapItem)))
+ continue;
+
+ if (item.subinfo) {
+ item.subinfo->updateSeparatorWidgets();
+ }
+
+ if (next == -1)
+ break;
+
+ QWidget *sepWidget;
+ if (j < separatorWidgets.size() && separatorWidgets.at(j)) {
+ sepWidget = separatorWidgets.at(j);
+ } else {
+ sepWidget = mainWindowLayout()->getSeparatorWidget();
+ separatorWidgets.append(sepWidget);
+ }
+ j++;
+
+#ifndef QT_MAC_USE_COCOA
+ sepWidget->raise();
+#endif
+ QRect sepRect = separatorRect(i).adjusted(-2, -2, 2, 2);
+ sepWidget->setGeometry(sepRect);
+ sepWidget->setMask( QRegion(separatorRect(i).translated( - sepRect.topLeft())));
+ sepWidget->show();
+ }
+
+ for (int k = j; k < separatorWidgets.size(); ++k) {
+ separatorWidgets[k]->hide();
+ }
+ separatorWidgets.resize(j);
+ Q_ASSERT(separatorWidgets.size() == j);
+}
+#endif //QT_NO_TABBAR
+
+#ifndef QT_NO_TABBAR
+//returns whether the tabbar is visible or not
+bool QDockAreaLayoutInfo::updateTabBar() const
+{
+ if (!tabbed)
+ return false;
+
+ QDockAreaLayoutInfo *that = const_cast<QDockAreaLayoutInfo*>(this);
+
+ if (that->tabBar == 0) {
+ that->tabBar = mainWindowLayout()->getTabBar();
+ that->tabBar->setShape(static_cast<QTabBar::Shape>(tabBarShape));
+ that->tabBar->setDrawBase(true);
+ }
+
+ bool blocked = tabBar->blockSignals(true);
+ bool gap = false;
+
+ int tab_idx = 0;
+ for (int i = 0; i < item_list.count(); ++i) {
+ const QDockAreaLayoutItem &item = item_list.at(i);
+ if (item.skip())
+ continue;
+ if (item.flags & QDockAreaLayoutItem::GapItem) {
+ gap = true;
+ continue;
+ }
+ if (item.widgetItem == 0)
+ continue;
+
+ QDockWidget *dw = qobject_cast<QDockWidget*>(item.widgetItem->widget());
+ QString title = dw->d_func()->fixedWindowTitle;
+ quintptr id = tabId(item);
+ if (tab_idx == tabBar->count()) {
+ tabBar->insertTab(tab_idx, title);
+#ifndef QT_NO_TOOLTIP
+ tabBar->setTabToolTip(tab_idx, title);
+#endif
+ tabBar->setTabData(tab_idx, id);
+ } else if (qvariant_cast<quintptr>(tabBar->tabData(tab_idx)) != id) {
+ if (tab_idx + 1 < tabBar->count()
+ && qvariant_cast<quintptr>(tabBar->tabData(tab_idx + 1)) == id)
+ tabBar->removeTab(tab_idx);
+ else {
+ tabBar->insertTab(tab_idx, title);
+#ifndef QT_NO_TOOLTIP
+ tabBar->setTabToolTip(tab_idx, title);
+#endif
+ tabBar->setTabData(tab_idx, id);
+ }
+ }
+
+ if (title != tabBar->tabText(tab_idx)) {
+ tabBar->setTabText(tab_idx, title);
+#ifndef QT_NO_TOOLTIP
+ tabBar->setTabToolTip(tab_idx, title);
+#endif
+ }
+
+ ++tab_idx;
+ }
+
+ while (tab_idx < tabBar->count()) {
+ tabBar->removeTab(tab_idx);
+ }
+
+ tabBar->blockSignals(blocked);
+
+ //returns if the tabbar is visible or not
+ return ( (gap ? 1 : 0) + tabBar->count()) > 1;
+}
+
+void QDockAreaLayoutInfo::setTabBarShape(int shape)
+{
+ if (shape == tabBarShape)
+ return;
+ tabBarShape = shape;
+ if (tabBar != 0)
+ tabBar->setShape(static_cast<QTabBar::Shape>(shape));
+
+ for (int i = 0; i < item_list.count(); ++i) {
+ QDockAreaLayoutItem &item = item_list[i];
+ if (item.subinfo != 0)
+ item.subinfo->setTabBarShape(shape);
+ }
+}
+
+QSize QDockAreaLayoutInfo::tabBarMinimumSize() const
+{
+ if (!updateTabBar())
+ return QSize(0, 0);
+
+ return tabBar->minimumSizeHint();
+}
+
+QSize QDockAreaLayoutInfo::tabBarSizeHint() const
+{
+ if (!updateTabBar())
+ return QSize(0, 0);
+
+ return tabBar->sizeHint();
+}
+
+QSet<QTabBar*> QDockAreaLayoutInfo::usedTabBars() const
+{
+ QSet<QTabBar*> result;
+
+ if (tabbed) {
+ updateTabBar();
+ result.insert(tabBar);
+ }
+
+ for (int i = 0; i < item_list.count(); ++i) {
+ const QDockAreaLayoutItem &item = item_list.at(i);
+ if (item.subinfo != 0)
+ result += item.subinfo->usedTabBars();
+ }
+
+ return result;
+}
+
+// returns a set of all used separator widgets for this dockarelayout info
+// and all subinfos
+QSet<QWidget*> QDockAreaLayoutInfo::usedSeparatorWidgets() const
+{
+ QSet<QWidget*> result;
+
+ for (int i = 0; i < separatorWidgets.count(); ++i)
+ result << separatorWidgets.at(i);
+
+ for (int i = 0; i < item_list.count(); ++i) {
+ const QDockAreaLayoutItem &item = item_list.at(i);
+ if (item.subinfo != 0)
+ result += item.subinfo->usedSeparatorWidgets();
+ }
+
+ return result;
+}
+
+QRect QDockAreaLayoutInfo::tabContentRect() const
+{
+ if (!tabbed)
+ return QRect();
+
+ QRect result = rect;
+ QSize tbh = tabBarSizeHint();
+
+ if (!tbh.isNull()) {
+ switch (tabBarShape) {
+ case QTabBar::RoundedNorth:
+ case QTabBar::TriangularNorth:
+ result.adjust(0, tbh.height(), 0, 0);
+ break;
+ case QTabBar::RoundedSouth:
+ case QTabBar::TriangularSouth:
+ result.adjust(0, 0, 0, -tbh.height());
+ break;
+ case QTabBar::RoundedEast:
+ case QTabBar::TriangularEast:
+ result.adjust(0, 0, -tbh.width(), 0);
+ break;
+ case QTabBar::RoundedWest:
+ case QTabBar::TriangularWest:
+ result.adjust(tbh.width(), 0, 0, 0);
+ break;
+ default:
+ break;
+ }
+ }
+
+ return result;
+}
+#endif // QT_NO_TABBAR
+
+/******************************************************************************
+** QDockAreaLayout
+*/
+
+QDockAreaLayout::QDockAreaLayout(QMainWindow *win) : fallbackToSizeHints(true)
+{
+ mainWindow = win;
+ sep = win->style()->pixelMetric(QStyle::PM_DockWidgetSeparatorExtent, 0, win);
+#ifndef QT_NO_TABBAR
+ const int tabShape = QTabBar::RoundedSouth;
+#else
+ const int tabShape = 0;
+#endif
+ docks[QInternal::LeftDock]
+ = QDockAreaLayoutInfo(&sep, QInternal::LeftDock, Qt::Vertical, tabShape, win);
+ docks[QInternal::RightDock]
+ = QDockAreaLayoutInfo(&sep, QInternal::RightDock, Qt::Vertical, tabShape, win);
+ docks[QInternal::TopDock]
+ = QDockAreaLayoutInfo(&sep, QInternal::TopDock, Qt::Horizontal, tabShape, win);
+ docks[QInternal::BottomDock]
+ = QDockAreaLayoutInfo(&sep, QInternal::BottomDock, Qt::Horizontal, tabShape, win);
+ centralWidgetItem = 0;
+
+
+ corners[Qt::TopLeftCorner] = Qt::TopDockWidgetArea;
+ corners[Qt::TopRightCorner] = Qt::TopDockWidgetArea;
+ corners[Qt::BottomLeftCorner] = Qt::BottomDockWidgetArea;
+ corners[Qt::BottomRightCorner] = Qt::BottomDockWidgetArea;
+}
+
+bool QDockAreaLayout::isValid() const
+{
+ return rect.isValid();
+}
+
+void QDockAreaLayout::saveState(QDataStream &stream) const
+{
+ stream << (uchar) DockWidgetStateMarker;
+ int cnt = 0;
+ for (int i = 0; i < QInternal::DockCount; ++i) {
+ if (!docks[i].item_list.isEmpty())
+ ++cnt;
+ }
+ stream << cnt;
+ for (int i = 0; i < QInternal::DockCount; ++i) {
+ if (docks[i].item_list.isEmpty())
+ continue;
+ stream << i << docks[i].rect.size();
+ docks[i].saveState(stream);
+ }
+
+ stream << centralWidgetRect.size();
+
+ for (int i = 0; i < 4; ++i)
+ stream << static_cast<int>(corners[i]);
+}
+
+bool QDockAreaLayout::restoreState(QDataStream &stream, const QList<QDockWidget*> &_dockwidgets, bool testing)
+{
+ QList<QDockWidget*> dockwidgets = _dockwidgets;
+
+ int cnt;
+ stream >> cnt;
+ for (int i = 0; i < cnt; ++i) {
+ int pos;
+ stream >> pos;
+ QSize size;
+ stream >> size;
+ if (!testing) {
+ docks[pos].rect = QRect(QPoint(0, 0), size);
+ }
+ if (!docks[pos].restoreState(stream, dockwidgets, testing)) {
+ stream.setStatus(QDataStream::ReadCorruptData);
+ return false;
+ }
+ }
+
+ QSize size;
+ stream >> size;
+ centralWidgetRect = QRect(QPoint(0, 0), size);
+
+ bool ok = stream.status() == QDataStream::Ok;
+
+ if (ok) {
+ int cornerData[4];
+ for (int i = 0; i < 4; ++i)
+ stream >> cornerData[i];
+ if (stream.status() == QDataStream::Ok) {
+ for (int i = 0; i < 4; ++i)
+ corners[i] = static_cast<Qt::DockWidgetArea>(cornerData[i]);
+ }
+
+ if (!testing)
+ fallbackToSizeHints = false;
+ }
+
+ return ok;
+}
+
+QList<int> QDockAreaLayout::indexOfPlaceHolder(const QString &objectName) const
+{
+ for (int i = 0; i < QInternal::DockCount; ++i) {
+ QList<int> result = docks[i].indexOfPlaceHolder(objectName);
+ if (!result.isEmpty()) {
+ result.prepend(i);
+ return result;
+ }
+ }
+ return QList<int>();
+}
+
+QList<int> QDockAreaLayout::indexOf(QWidget *dockWidget) const
+{
+ for (int i = 0; i < QInternal::DockCount; ++i) {
+ QList<int> result = docks[i].indexOf(dockWidget);
+ if (!result.isEmpty()) {
+ result.prepend(i);
+ return result;
+ }
+ }
+ return QList<int>();
+}
+
+QList<int> QDockAreaLayout::gapIndex(const QPoint &pos) const
+{
+ QMainWindow::DockOptions opts = mainWindow->dockOptions();
+ bool nestingEnabled = opts & QMainWindow::AllowNestedDocks;
+ QDockAreaLayoutInfo::TabMode tabMode = QDockAreaLayoutInfo::NoTabs;
+#ifndef QT_NO_TABBAR
+ if (opts & QMainWindow::AllowTabbedDocks
+ || opts & QMainWindow::VerticalTabs)
+ tabMode = QDockAreaLayoutInfo::AllowTabs;
+ if (opts & QMainWindow::ForceTabbedDocks)
+ tabMode = QDockAreaLayoutInfo::ForceTabs;
+
+ if (tabMode == QDockAreaLayoutInfo::ForceTabs)
+ nestingEnabled = false;
+#endif
+
+
+ for (int i = 0; i < QInternal::DockCount; ++i) {
+ const QDockAreaLayoutInfo &info = docks[i];
+
+ if (!info.isEmpty() && info.rect.contains(pos)) {
+ QList<int> result
+ = docks[i].gapIndex(pos, nestingEnabled, tabMode);
+ if (!result.isEmpty())
+ result.prepend(i);
+ return result;
+ }
+ }
+
+ for (int i = 0; i < QInternal::DockCount; ++i) {
+ const QDockAreaLayoutInfo &info = docks[i];
+
+ if (info.isEmpty()) {
+ QRect r;
+ switch (i) {
+ case QInternal::LeftDock:
+ r = QRect(rect.left(), rect.top(), EmptyDropAreaSize, rect.height());
+ break;
+ case QInternal::RightDock:
+ r = QRect(rect.right() - EmptyDropAreaSize, rect.top(),
+ EmptyDropAreaSize, rect.height());
+ break;
+ case QInternal::TopDock:
+ r = QRect(rect.left(), rect.top(), rect.width(), EmptyDropAreaSize);
+ break;
+ case QInternal::BottomDock:
+ r = QRect(rect.left(), rect.bottom() - EmptyDropAreaSize,
+ rect.width(), EmptyDropAreaSize);
+ break;
+ }
+ if (r.contains(pos)) {
+ if (opts & QMainWindow::ForceTabbedDocks && !info.item_list.isEmpty()) {
+ //in case of ForceTabbedDocks, we pass -1 in order to force the gap to be tabbed
+ //it mustn't be completely empty otherwise it won't work
+ return QList<int>() << i << -1 << 0;
+ } else {
+ return QList<int>() << i << 0;
+ }
+ }
+ }
+ }
+
+ return QList<int>();
+}
+
+QList<int> QDockAreaLayout::findSeparator(const QPoint &pos) const
+{
+ QList<int> result;
+ for (int i = 0; i < QInternal::DockCount; ++i) {
+ const QDockAreaLayoutInfo &info = docks[i];
+ if (info.isEmpty())
+ continue;
+ QRect rect = separatorRect(i);
+ if (!rect.isNull() && sep == 1)
+ rect.adjust(-2, -2, 2, 2);
+ if (rect.contains(pos) && !info.hasFixedSize()) {
+ result << i;
+ break;
+ } else if (info.rect.contains(pos)) {
+ result = docks[i].findSeparator(pos);
+ if (!result.isEmpty()) {
+ result.prepend(i);
+ break;
+ }
+ }
+ }
+
+ return result;
+}
+
+QDockAreaLayoutInfo *QDockAreaLayout::info(QWidget *widget)
+{
+ for (int i = 0; i < QInternal::DockCount; ++i) {
+ if (QDockAreaLayoutInfo *result = docks[i].info(widget))
+ return result;
+ }
+
+ return 0;
+}
+
+QDockAreaLayoutInfo *QDockAreaLayout::info(const QList<int> &path)
+{
+ Q_ASSERT(!path.isEmpty());
+ const int index = path.first();
+ Q_ASSERT(index >= 0 && index < QInternal::DockCount);
+
+ if (path.count() == 1)
+ return &docks[index];
+
+ return docks[index].info(path.mid(1));
+}
+
+const QDockAreaLayoutInfo *QDockAreaLayout::info(const QList<int> &path) const
+{
+ return const_cast<QDockAreaLayout*>(this)->info(path);
+}
+
+QDockAreaLayoutItem &QDockAreaLayout::item(const QList<int> &path)
+{
+ Q_ASSERT(!path.isEmpty());
+ const int index = path.first();
+ Q_ASSERT(index >= 0 && index < QInternal::DockCount);
+ return docks[index].item(path.mid(1));
+}
+
+QRect QDockAreaLayout::itemRect(const QList<int> &path) const
+{
+ Q_ASSERT(!path.isEmpty());
+ const int index = path.first();
+ Q_ASSERT(index >= 0 && index < QInternal::DockCount);
+ return docks[index].itemRect(path.mid(1));
+}
+
+QRect QDockAreaLayout::separatorRect(int index) const
+{
+ const QDockAreaLayoutInfo &dock = docks[index];
+ if (dock.isEmpty())
+ return QRect();
+ QRect r = dock.rect;
+ switch (index) {
+ case QInternal::LeftDock:
+ return QRect(r.right() + 1, r.top(), sep, r.height());
+ case QInternal::RightDock:
+ return QRect(r.left() - sep, r.top(), sep, r.height());
+ case QInternal::TopDock:
+ return QRect(r.left(), r.bottom() + 1, r.width(), sep);
+ case QInternal::BottomDock:
+ return QRect(r.left(), r.top() - sep, r.width(), sep);
+ default:
+ break;
+ }
+ return QRect();
+}
+
+QRect QDockAreaLayout::separatorRect(const QList<int> &path) const
+{
+ Q_ASSERT(!path.isEmpty());
+
+ const int index = path.first();
+ Q_ASSERT(index >= 0 && index < QInternal::DockCount);
+
+ if (path.count() == 1)
+ return separatorRect(index);
+ else
+ return docks[index].separatorRect(path.mid(1));
+}
+
+bool QDockAreaLayout::insertGap(const QList<int> &path, QLayoutItem *dockWidgetItem)
+{
+ Q_ASSERT(!path.isEmpty());
+ const int index = path.first();
+ Q_ASSERT(index >= 0 && index < QInternal::DockCount);
+ return docks[index].insertGap(path.mid(1), dockWidgetItem);
+}
+
+QLayoutItem *QDockAreaLayout::plug(const QList<int> &path)
+{
+ Q_ASSERT(!path.isEmpty());
+ const int index = path.first();
+ Q_ASSERT(index >= 0 && index < QInternal::DockCount);
+ return docks[index].plug(path.mid(1));
+}
+
+QLayoutItem *QDockAreaLayout::unplug(const QList<int> &path)
+{
+ Q_ASSERT(!path.isEmpty());
+ const int index = path.first();
+ Q_ASSERT(index >= 0 && index < QInternal::DockCount);
+ return docks[index].unplug(path.mid(1));
+}
+
+void QDockAreaLayout::remove(const QList<int> &path)
+{
+ Q_ASSERT(!path.isEmpty());
+ const int index = path.first();
+ Q_ASSERT(index >= 0 && index < QInternal::DockCount);
+ docks[index].remove(path.mid(1));
+}
+
+static inline int qMin(int i1, int i2, int i3) { return qMin(i1, qMin(i2, i3)); }
+static inline int qMax(int i1, int i2, int i3) { return qMax(i1, qMax(i2, i3)); }
+
+void QDockAreaLayout::getGrid(QVector<QLayoutStruct> *_ver_struct_list,
+ QVector<QLayoutStruct> *_hor_struct_list)
+{
+ QSize center_hint(0, 0);
+ QSize center_min(0, 0);
+ const bool have_central = centralWidgetItem != 0 && !centralWidgetItem->isEmpty();
+ if (have_central) {
+ center_hint = centralWidgetRect.size();
+ if (!center_hint.isValid())
+ center_hint = centralWidgetItem->sizeHint();
+ center_min = centralWidgetItem->minimumSize();
+ }
+
+ QRect center_rect = rect;
+ if (!docks[QInternal::LeftDock].isEmpty())
+ center_rect.setLeft(rect.left() + docks[QInternal::LeftDock].rect.width() + sep);
+ if (!docks[QInternal::TopDock].isEmpty())
+ center_rect.setTop(rect.top() + docks[QInternal::TopDock].rect.height() + sep);
+ if (!docks[QInternal::RightDock].isEmpty())
+ center_rect.setRight(rect.right() - docks[QInternal::RightDock].rect.width() - sep);
+ if (!docks[QInternal::BottomDock].isEmpty())
+ center_rect.setBottom(rect.bottom() - docks[QInternal::BottomDock].rect.height() - sep);
+
+ QSize left_hint = docks[QInternal::LeftDock].size();
+ if (left_hint.isNull() || fallbackToSizeHints)
+ left_hint = docks[QInternal::LeftDock].sizeHint();
+ QSize left_min = docks[QInternal::LeftDock].minimumSize();
+ QSize left_max = docks[QInternal::LeftDock].maximumSize();
+ left_hint = left_hint.boundedTo(left_max).expandedTo(left_min);
+
+ QSize right_hint = docks[QInternal::RightDock].size();
+ if (right_hint.isNull() || fallbackToSizeHints)
+ right_hint = docks[QInternal::RightDock].sizeHint();
+ QSize right_min = docks[QInternal::RightDock].minimumSize();
+ QSize right_max = docks[QInternal::RightDock].maximumSize();
+ right_hint = right_hint.boundedTo(right_max).expandedTo(right_min);
+
+ QSize top_hint = docks[QInternal::TopDock].size();
+ if (top_hint.isNull() || fallbackToSizeHints)
+ top_hint = docks[QInternal::TopDock].sizeHint();
+ QSize top_min = docks[QInternal::TopDock].minimumSize();
+ QSize top_max = docks[QInternal::TopDock].maximumSize();
+ top_hint = top_hint.boundedTo(top_max).expandedTo(top_min);
+
+ QSize bottom_hint = docks[QInternal::BottomDock].size();
+ if (bottom_hint.isNull() || fallbackToSizeHints)
+ bottom_hint = docks[QInternal::BottomDock].sizeHint();
+ QSize bottom_min = docks[QInternal::BottomDock].minimumSize();
+ QSize bottom_max = docks[QInternal::BottomDock].maximumSize();
+ bottom_hint = bottom_hint.boundedTo(bottom_max).expandedTo(bottom_min);
+
+ fallbackToSizeHints = false;
+
+ if (_ver_struct_list != 0) {
+ QVector<QLayoutStruct> &ver_struct_list = *_ver_struct_list;
+ ver_struct_list.resize(3);
+
+ // top --------------------------------------------------
+ ver_struct_list[0].init();
+ ver_struct_list[0].stretch = 0;
+ ver_struct_list[0].sizeHint = top_hint.height();
+ ver_struct_list[0].minimumSize = top_min.height();
+ ver_struct_list[0].maximumSize = top_max.height();
+ ver_struct_list[0].expansive = false;
+ ver_struct_list[0].empty = docks[QInternal::TopDock].isEmpty();
+ ver_struct_list[0].pos = docks[QInternal::TopDock].rect.top();
+ ver_struct_list[0].size = docks[QInternal::TopDock].rect.height();
+
+ // center --------------------------------------------------
+ ver_struct_list[1].init();
+ ver_struct_list[1].stretch = center_hint.height();
+
+ bool tl_significant = corners[Qt::TopLeftCorner] == Qt::TopDockWidgetArea
+ || docks[QInternal::TopDock].isEmpty();
+ bool bl_significant = corners[Qt::BottomLeftCorner] == Qt::BottomDockWidgetArea
+ || docks[QInternal::BottomDock].isEmpty();
+ bool tr_significant = corners[Qt::TopRightCorner] == Qt::TopDockWidgetArea
+ || docks[QInternal::TopDock].isEmpty();
+ bool br_significant = corners[Qt::BottomRightCorner] == Qt::BottomDockWidgetArea
+ || docks[QInternal::BottomDock].isEmpty();
+
+ int left = (tl_significant && bl_significant) ? left_hint.height() : 0;
+ int right = (tr_significant && br_significant) ? right_hint.height() : 0;
+ ver_struct_list[1].sizeHint = qMax(left, center_hint.height(), right);
+
+ left = (tl_significant && bl_significant) ? left_min.height() : 0;
+ right = (tr_significant && br_significant) ? right_min.height() : 0;
+ ver_struct_list[1].minimumSize = qMax(left, center_min.height(), right);
+ ver_struct_list[1].maximumSize = have_central ? QWIDGETSIZE_MAX : 0;
+ ver_struct_list[1].expansive = have_central;
+ ver_struct_list[1].empty = docks[QInternal::LeftDock].isEmpty()
+ && !have_central
+ && docks[QInternal::RightDock].isEmpty();
+ ver_struct_list[1].pos = center_rect.top();
+ ver_struct_list[1].size = center_rect.height();
+
+ // bottom --------------------------------------------------
+ ver_struct_list[2].init();
+ ver_struct_list[2].stretch = 0;
+ ver_struct_list[2].sizeHint = bottom_hint.height();
+ ver_struct_list[2].minimumSize = bottom_min.height();
+ ver_struct_list[2].maximumSize = bottom_max.height();
+ ver_struct_list[2].expansive = false;
+ ver_struct_list[2].empty = docks[QInternal::BottomDock].isEmpty();
+ ver_struct_list[2].pos = docks[QInternal::BottomDock].rect.top();
+ ver_struct_list[2].size = docks[QInternal::BottomDock].rect.height();
+
+ for (int i = 0; i < 3; ++i) {
+ ver_struct_list[i].sizeHint
+ = qMax(ver_struct_list[i].sizeHint, ver_struct_list[i].minimumSize);
+ }
+ }
+
+ if (_hor_struct_list != 0) {
+ QVector<QLayoutStruct> &hor_struct_list = *_hor_struct_list;
+ hor_struct_list.resize(3);
+
+ // left --------------------------------------------------
+ hor_struct_list[0].init();
+ hor_struct_list[0].stretch = 0;
+ hor_struct_list[0].sizeHint = left_hint.width();
+ hor_struct_list[0].minimumSize = left_min.width();
+ hor_struct_list[0].maximumSize = left_max.width();
+ hor_struct_list[0].expansive = false;
+ hor_struct_list[0].empty = docks[QInternal::LeftDock].isEmpty();
+ hor_struct_list[0].pos = docks[QInternal::LeftDock].rect.left();
+ hor_struct_list[0].size = docks[QInternal::LeftDock].rect.width();
+
+ // center --------------------------------------------------
+ hor_struct_list[1].init();
+ hor_struct_list[1].stretch = center_hint.width();
+
+ bool tl_significant = corners[Qt::TopLeftCorner] == Qt::LeftDockWidgetArea
+ || docks[QInternal::LeftDock].isEmpty();
+ bool tr_significant = corners[Qt::TopRightCorner] == Qt::RightDockWidgetArea
+ || docks[QInternal::RightDock].isEmpty();
+ bool bl_significant = corners[Qt::BottomLeftCorner] == Qt::LeftDockWidgetArea
+ || docks[QInternal::LeftDock].isEmpty();
+ bool br_significant = corners[Qt::BottomRightCorner] == Qt::RightDockWidgetArea
+ || docks[QInternal::RightDock].isEmpty();
+
+ int top = (tl_significant && tr_significant) ? top_hint.width() : 0;
+ int bottom = (bl_significant && br_significant) ? bottom_hint.width() : 0;
+ hor_struct_list[1].sizeHint = qMax(top, center_hint.width(), bottom);
+
+ top = (tl_significant && tr_significant) ? top_min.width() : 0;
+ bottom = (bl_significant && br_significant) ? bottom_min.width() : 0;
+ hor_struct_list[1].minimumSize = qMax(top, center_min.width(), bottom);
+
+ hor_struct_list[1].maximumSize = have_central ? QWIDGETSIZE_MAX : 0;
+ hor_struct_list[1].expansive = have_central;
+ hor_struct_list[1].empty = !have_central;
+ hor_struct_list[1].pos = center_rect.left();
+ hor_struct_list[1].size = center_rect.width();
+
+ // right --------------------------------------------------
+ hor_struct_list[2].init();
+ hor_struct_list[2].stretch = 0;
+ hor_struct_list[2].sizeHint = right_hint.width();
+ hor_struct_list[2].minimumSize = right_min.width();
+ hor_struct_list[2].maximumSize = right_max.width();
+ hor_struct_list[2].expansive = false;
+ hor_struct_list[2].empty = docks[QInternal::RightDock].isEmpty();
+ hor_struct_list[2].pos = docks[QInternal::RightDock].rect.left();
+ hor_struct_list[2].size = docks[QInternal::RightDock].rect.width();
+
+ for (int i = 0; i < 3; ++i) {
+ hor_struct_list[i].sizeHint
+ = qMax(hor_struct_list[i].sizeHint, hor_struct_list[i].minimumSize);
+ }
+ }
+}
+
+void QDockAreaLayout::setGrid(QVector<QLayoutStruct> *ver_struct_list,
+ QVector<QLayoutStruct> *hor_struct_list)
+{
+
+ // top ---------------------------------------------------
+
+ if (!docks[QInternal::TopDock].isEmpty()) {
+ QRect r = docks[QInternal::TopDock].rect;
+ if (hor_struct_list != 0) {
+ r.setLeft(corners[Qt::TopLeftCorner] == Qt::TopDockWidgetArea
+ || docks[QInternal::LeftDock].isEmpty()
+ ? rect.left() : hor_struct_list->at(1).pos);
+ r.setRight(corners[Qt::TopRightCorner] == Qt::TopDockWidgetArea
+ || docks[QInternal::RightDock].isEmpty()
+ ? rect.right() : hor_struct_list->at(2).pos - sep - 1);
+ }
+ if (ver_struct_list != 0) {
+ r.setTop(rect.top());
+ r.setBottom(ver_struct_list->at(1).pos - sep - 1);
+ }
+ docks[QInternal::TopDock].rect = r;
+ docks[QInternal::TopDock].fitItems();
+ }
+
+ // bottom ---------------------------------------------------
+
+ if (!docks[QInternal::BottomDock].isEmpty()) {
+ QRect r = docks[QInternal::BottomDock].rect;
+ if (hor_struct_list != 0) {
+ r.setLeft(corners[Qt::BottomLeftCorner] == Qt::BottomDockWidgetArea
+ || docks[QInternal::LeftDock].isEmpty()
+ ? rect.left() : hor_struct_list->at(1).pos);
+ r.setRight(corners[Qt::BottomRightCorner] == Qt::BottomDockWidgetArea
+ || docks[QInternal::RightDock].isEmpty()
+ ? rect.right() : hor_struct_list->at(2).pos - sep - 1);
+ }
+ if (ver_struct_list != 0) {
+ r.setTop(ver_struct_list->at(2).pos);
+ r.setBottom(rect.bottom());
+ }
+ docks[QInternal::BottomDock].rect = r;
+ docks[QInternal::BottomDock].fitItems();
+ }
+
+ // left ---------------------------------------------------
+
+ if (!docks[QInternal::LeftDock].isEmpty()) {
+ QRect r = docks[QInternal::LeftDock].rect;
+ if (hor_struct_list != 0) {
+ r.setLeft(rect.left());
+ r.setRight(hor_struct_list->at(1).pos - sep - 1);
+ }
+ if (ver_struct_list != 0) {
+ r.setTop(corners[Qt::TopLeftCorner] == Qt::LeftDockWidgetArea
+ || docks[QInternal::TopDock].isEmpty()
+ ? rect.top() : ver_struct_list->at(1).pos);
+ r.setBottom(corners[Qt::BottomLeftCorner] == Qt::LeftDockWidgetArea
+ || docks[QInternal::BottomDock].isEmpty()
+ ? rect.bottom() : ver_struct_list->at(2).pos - sep - 1);
+ }
+ docks[QInternal::LeftDock].rect = r;
+ docks[QInternal::LeftDock].fitItems();
+ }
+
+ // right ---------------------------------------------------
+
+ if (!docks[QInternal::RightDock].isEmpty()) {
+ QRect r = docks[QInternal::RightDock].rect;
+ if (hor_struct_list != 0) {
+ r.setLeft(hor_struct_list->at(2).pos);
+ r.setRight(rect.right());
+ }
+ if (ver_struct_list != 0) {
+ r.setTop(corners[Qt::TopRightCorner] == Qt::RightDockWidgetArea
+ || docks[QInternal::TopDock].isEmpty()
+ ? rect.top() : ver_struct_list->at(1).pos);
+ r.setBottom(corners[Qt::BottomRightCorner] == Qt::RightDockWidgetArea
+ || docks[QInternal::BottomDock].isEmpty()
+ ? rect.bottom() : ver_struct_list->at(2).pos - sep - 1);
+ }
+ docks[QInternal::RightDock].rect = r;
+ docks[QInternal::RightDock].fitItems();
+ }
+
+ // center ---------------------------------------------------
+
+ if (hor_struct_list != 0) {
+ centralWidgetRect.setLeft(hor_struct_list->at(1).pos);
+ centralWidgetRect.setWidth(hor_struct_list->at(1).size);
+ }
+ if (ver_struct_list != 0) {
+ centralWidgetRect.setTop(ver_struct_list->at(1).pos);
+ centralWidgetRect.setHeight(ver_struct_list->at(1).size);
+ }
+}
+
+void QDockAreaLayout::fitLayout()
+{
+ QVector<QLayoutStruct> ver_struct_list(3);
+ QVector<QLayoutStruct> hor_struct_list(3);
+ getGrid(&ver_struct_list, &hor_struct_list);
+
+ qGeomCalc(ver_struct_list, 0, 3, rect.top(), rect.height(), sep);
+ qGeomCalc(hor_struct_list, 0, 3, rect.left(), rect.width(), sep);
+
+ setGrid(&ver_struct_list, &hor_struct_list);
+}
+
+void QDockAreaLayout::clear()
+{
+ for (int i = 0; i < QInternal::DockCount; ++i)
+ docks[i].clear();
+
+ rect = QRect();
+ centralWidgetRect = QRect();
+}
+
+QSize QDockAreaLayout::sizeHint() const
+{
+ int left_sep = 0;
+ int right_sep = 0;
+ int top_sep = 0;
+ int bottom_sep = 0;
+
+ if (centralWidgetItem != 0) {
+ left_sep = docks[QInternal::LeftDock].isEmpty() ? 0 : sep;
+ right_sep = docks[QInternal::RightDock].isEmpty() ? 0 : sep;
+ top_sep = docks[QInternal::TopDock].isEmpty() ? 0 : sep;
+ bottom_sep = docks[QInternal::BottomDock].isEmpty() ? 0 : sep;
+ }
+
+ QSize left = docks[QInternal::LeftDock].sizeHint() + QSize(left_sep, 0);
+ QSize right = docks[QInternal::RightDock].sizeHint() + QSize(right_sep, 0);
+ QSize top = docks[QInternal::TopDock].sizeHint() + QSize(0, top_sep);
+ QSize bottom = docks[QInternal::BottomDock].sizeHint() + QSize(0, bottom_sep);
+ QSize center = centralWidgetItem == 0 ? QSize(0, 0) : centralWidgetItem->sizeHint();
+
+ int row1 = top.width();
+ int row2 = left.width() + center.width() + right.width();
+ int row3 = bottom.width();
+ int col1 = left.height();
+ int col2 = top.height() + center.height() + bottom.height();
+ int col3 = right.height();
+
+ if (corners[Qt::TopLeftCorner] == Qt::LeftDockWidgetArea)
+ row1 += left.width();
+ else
+ col1 += top.height();
+
+ if (corners[Qt::TopRightCorner] == Qt::RightDockWidgetArea)
+ row1 += right.width();
+ else
+ col3 += top.height();
+
+ if (corners[Qt::BottomLeftCorner] == Qt::LeftDockWidgetArea)
+ row3 += left.width();
+ else
+ col1 += bottom.height();
+
+ if (corners[Qt::BottomRightCorner] == Qt::RightDockWidgetArea)
+ row3 += right.width();
+ else
+ col3 += bottom.height();
+
+ return QSize(qMax(row1, row2, row3), qMax(col1, col2, col3));
+}
+
+QSize QDockAreaLayout::minimumSize() const
+{
+ int left_sep = 0;
+ int right_sep = 0;
+ int top_sep = 0;
+ int bottom_sep = 0;
+
+ if (centralWidgetItem != 0) {
+ left_sep = docks[QInternal::LeftDock].isEmpty() ? 0 : sep;
+ right_sep = docks[QInternal::RightDock].isEmpty() ? 0 : sep;
+ top_sep = docks[QInternal::TopDock].isEmpty() ? 0 : sep;
+ bottom_sep = docks[QInternal::BottomDock].isEmpty() ? 0 : sep;
+ }
+
+ QSize left = docks[QInternal::LeftDock].minimumSize() + QSize(left_sep, 0);
+ QSize right = docks[QInternal::RightDock].minimumSize() + QSize(right_sep, 0);
+ QSize top = docks[QInternal::TopDock].minimumSize() + QSize(0, top_sep);
+ QSize bottom = docks[QInternal::BottomDock].minimumSize() + QSize(0, bottom_sep);
+ QSize center = centralWidgetItem == 0 ? QSize(0, 0) : centralWidgetItem->minimumSize();
+
+ int row1 = top.width();
+ int row2 = left.width() + center.width() + right.width();
+ int row3 = bottom.width();
+ int col1 = left.height();
+ int col2 = top.height() + center.height() + bottom.height();
+ int col3 = right.height();
+
+ if (corners[Qt::TopLeftCorner] == Qt::LeftDockWidgetArea)
+ row1 += left.width();
+ else
+ col1 += top.height();
+
+ if (corners[Qt::TopRightCorner] == Qt::RightDockWidgetArea)
+ row1 += right.width();
+ else
+ col3 += top.height();
+
+ if (corners[Qt::BottomLeftCorner] == Qt::LeftDockWidgetArea)
+ row3 += left.width();
+ else
+ col1 += bottom.height();
+
+ if (corners[Qt::BottomRightCorner] == Qt::RightDockWidgetArea)
+ row3 += right.width();
+ else
+ col3 += bottom.height();
+
+ return QSize(qMax(row1, row2, row3), qMax(col1, col2, col3));
+}
+
+bool QDockAreaLayout::restoreDockWidget(QDockWidget *dockWidget)
+{
+ QList<int> index = indexOfPlaceHolder(dockWidget->objectName());
+ if (index.isEmpty())
+ return false;
+
+ QDockAreaLayoutItem &item = this->item(index);
+ QPlaceHolderItem *placeHolder = item.placeHolderItem;
+ Q_ASSERT(placeHolder != 0);
+
+ item.widgetItem = new QDockWidgetItem(dockWidget);
+
+ if (placeHolder->window) {
+ QDesktopWidget desktop;
+ QRect r = constrainedRect(placeHolder->topLevelRect, desktop.screenGeometry(dockWidget));
+ dockWidget->d_func()->setWindowState(true, true, r);
+ }
+ dockWidget->setVisible(!placeHolder->hidden);
+#ifdef Q_WS_X11
+ if (placeHolder->window) // gets rid of the X11BypassWindowManager window flag
+ dockWidget->d_func()->setWindowState(true);
+#endif
+
+ item.placeHolderItem = 0;
+ delete placeHolder;
+
+ return true;
+}
+
+void QDockAreaLayout::addDockWidget(QInternal::DockPosition pos, QDockWidget *dockWidget,
+ Qt::Orientation orientation)
+{
+ QLayoutItem *dockWidgetItem = new QDockWidgetItem(dockWidget);
+ QDockAreaLayoutInfo &info = docks[pos];
+ if (orientation == info.o || info.item_list.count() <= 1) {
+ // empty dock areas, or dock areas containing exactly one widget can have their orientation
+ // switched.
+ info.o = orientation;
+
+ QDockAreaLayoutItem new_item(dockWidgetItem);
+ info.item_list.append(new_item);
+#ifndef QT_NO_TABBAR
+ if (info.tabbed && !new_item.skip()) {
+ info.updateTabBar();
+ info.setCurrentTabId(tabId(new_item));
+ }
+#endif
+ } else {
+#ifndef QT_NO_TABBAR
+ int tbshape = info.tabBarShape;
+#else
+ int tbshape = 0;
+#endif
+ QDockAreaLayoutInfo new_info(&sep, pos, orientation, tbshape, mainWindow);
+ new_info.item_list.append(new QDockAreaLayoutInfo(info));
+ new_info.item_list.append(dockWidgetItem);
+ info = new_info;
+ }
+
+ QList<int> index = indexOfPlaceHolder(dockWidget->objectName());
+ if (!index.isEmpty())
+ remove(index);
+}
+
+void QDockAreaLayout::tabifyDockWidget(QDockWidget *first, QDockWidget *second)
+{
+ QList<int> path = indexOf(first);
+ if (path.isEmpty())
+ return;
+
+ QDockAreaLayoutInfo *info = this->info(path);
+ Q_ASSERT(info != 0);
+ info->tab(path.last(), new QDockWidgetItem(second));
+
+ QList<int> index = indexOfPlaceHolder(second->objectName());
+ if (!index.isEmpty())
+ remove(index);
+}
+
+void QDockAreaLayout::splitDockWidget(QDockWidget *after,
+ QDockWidget *dockWidget,
+ Qt::Orientation orientation)
+{
+ QList<int> path = indexOf(after);
+ if (path.isEmpty())
+ return;
+
+ QDockAreaLayoutInfo *info = this->info(path);
+ Q_ASSERT(info != 0);
+ info->split(path.last(), orientation, new QDockWidgetItem(dockWidget));
+
+ QList<int> index = indexOfPlaceHolder(dockWidget->objectName());
+ if (!index.isEmpty())
+ remove(index);
+}
+
+void QDockAreaLayout::apply(bool animate)
+{
+ QWidgetAnimator &widgetAnimator = qt_mainwindow_layout(mainWindow)->widgetAnimator;
+
+ for (int i = 0; i < QInternal::DockCount; ++i)
+ docks[i].apply(animate);
+ if (centralWidgetItem != 0 && !centralWidgetItem->isEmpty()) {
+ widgetAnimator.animate(centralWidgetItem->widget(), centralWidgetRect,
+ animate);
+ }
+#ifndef QT_NO_TABBAR
+ if (sep == 1)
+ updateSeparatorWidgets();
+#endif //QT_NO_TABBAR
+}
+
+void QDockAreaLayout::paintSeparators(QPainter *p, QWidget *widget,
+ const QRegion &clip,
+ const QPoint &mouse) const
+{
+ for (int i = 0; i < QInternal::DockCount; ++i) {
+ const QDockAreaLayoutInfo &dock = docks[i];
+ if (dock.isEmpty())
+ continue;
+ QRect r = separatorRect(i);
+ if (clip.contains(r) && !dock.hasFixedSize()) {
+ Qt::Orientation opposite = dock.o == Qt::Horizontal
+ ? Qt::Vertical : Qt::Horizontal;
+ paintSep(p, widget, r, opposite, r.contains(mouse));
+ }
+ if (clip.contains(dock.rect))
+ dock.paintSeparators(p, widget, clip, mouse);
+ }
+}
+
+QRegion QDockAreaLayout::separatorRegion() const
+{
+ QRegion result;
+
+ for (int i = 0; i < QInternal::DockCount; ++i) {
+ const QDockAreaLayoutInfo &dock = docks[i];
+ if (dock.isEmpty())
+ continue;
+ result |= separatorRect(i);
+ result |= dock.separatorRegion();
+ }
+
+ return result;
+}
+
+int QDockAreaLayout::separatorMove(const QList<int> &separator, const QPoint &origin,
+ const QPoint &dest)
+{
+ int delta = 0;
+ int index = separator.last();
+
+ if (separator.count() > 1) {
+ QDockAreaLayoutInfo *info = this->info(separator);
+ delta = pick(info->o, dest - origin);
+ if (delta != 0)
+ delta = info->separatorMove(index, delta);
+ info->apply(false);
+ return delta;
+ }
+
+ QVector<QLayoutStruct> list;
+
+ if (index == QInternal::LeftDock || index == QInternal::RightDock)
+ getGrid(0, &list);
+ else
+ getGrid(&list, 0);
+
+ int sep_index = index == QInternal::LeftDock || index == QInternal::TopDock
+ ? 0 : 1;
+ Qt::Orientation o = index == QInternal::LeftDock || index == QInternal::RightDock
+ ? Qt::Horizontal
+ : Qt::Vertical;
+
+ delta = pick(o, dest - origin);
+ delta = separatorMoveHelper(list, sep_index, delta, sep);
+
+ if (index == QInternal::LeftDock || index == QInternal::RightDock)
+ setGrid(0, &list);
+ else
+ setGrid(&list, 0);
+
+ apply(false);
+
+ return delta;
+}
+
+#ifndef QT_NO_TABBAR
+// Sets the correct positions for the separator widgets
+// Allocates new sepearator widgets with getSeparatorWidget
+void QDockAreaLayout::updateSeparatorWidgets() const
+{
+ int j = 0;
+
+ for (int i = 0; i < QInternal::DockCount; ++i) {
+ const QDockAreaLayoutInfo &dock = docks[i];
+ if (dock.isEmpty())
+ continue;
+
+ QWidget *sepWidget;
+ if (j < separatorWidgets.size()) {
+ sepWidget = separatorWidgets.at(j);
+ } else {
+ sepWidget = qt_mainwindow_layout(mainWindow)->getSeparatorWidget();
+ separatorWidgets.append(sepWidget);
+ }
+ j++;
+
+#ifndef QT_MAC_USE_COCOA
+ sepWidget->raise();
+#endif
+ QRect sepRect = separatorRect(i).adjusted(-2, -2, 2, 2);
+ sepWidget->setGeometry(sepRect);
+ sepWidget->setMask( QRegion(separatorRect(i).translated( - sepRect.topLeft())));
+ sepWidget->show();
+ }
+ for (int i = j; i < separatorWidgets.size(); ++i)
+ separatorWidgets.at(i)->hide();
+
+ separatorWidgets.resize(j);
+}
+#endif //QT_NO_TABBAR
+
+QLayoutItem *QDockAreaLayout::itemAt(int *x, int index) const
+{
+ Q_ASSERT(x != 0);
+
+ for (int i = 0; i < QInternal::DockCount; ++i) {
+ const QDockAreaLayoutInfo &dock = docks[i];
+ if (QLayoutItem *ret = dock.itemAt(x, index))
+ return ret;
+ }
+
+ if (centralWidgetItem && (*x)++ == index)
+ return centralWidgetItem;
+
+ return 0;
+}
+
+QLayoutItem *QDockAreaLayout::takeAt(int *x, int index)
+{
+ Q_ASSERT(x != 0);
+
+ for (int i = 0; i < QInternal::DockCount; ++i) {
+ QDockAreaLayoutInfo &dock = docks[i];
+ if (QLayoutItem *ret = dock.takeAt(x, index))
+ return ret;
+ }
+
+ if (centralWidgetItem && (*x)++ == index) {
+ QLayoutItem *ret = centralWidgetItem;
+ centralWidgetItem = 0;
+ return ret;
+ }
+
+ return 0;
+}
+
+void QDockAreaLayout::deleteAllLayoutItems()
+{
+ for (int i = 0; i < QInternal::DockCount; ++i)
+ docks[i].deleteAllLayoutItems();
+}
+
+#ifndef QT_NO_TABBAR
+QSet<QTabBar*> QDockAreaLayout::usedTabBars() const
+{
+ QSet<QTabBar*> result;
+ for (int i = 0; i < QInternal::DockCount; ++i) {
+ const QDockAreaLayoutInfo &dock = docks[i];
+ result += dock.usedTabBars();
+ }
+ return result;
+}
+
+// Returns the set of all used separator widgets
+QSet<QWidget*> QDockAreaLayout::usedSeparatorWidgets() const
+{
+ QSet<QWidget*> result;
+
+ for (int i = 0; i < separatorWidgets.count(); ++i)
+ result << separatorWidgets.at(i);
+ for (int i = 0; i < QInternal::DockCount; ++i) {
+ const QDockAreaLayoutInfo &dock = docks[i];
+ result += dock.usedSeparatorWidgets();
+ }
+ return result;
+}
+#endif
+
+QRect QDockAreaLayout::gapRect(const QList<int> &path) const
+{
+ const QDockAreaLayoutInfo *info = this->info(path);
+ if (info == 0)
+ return QRect();
+ const QList<QDockAreaLayoutItem> &item_list = info->item_list;
+ Qt::Orientation o = info->o;
+ int index = path.last();
+ if (index < 0 || index >= item_list.count())
+ return QRect();
+ const QDockAreaLayoutItem &item = item_list.at(index);
+ if (!(item.flags & QDockAreaLayoutItem::GapItem))
+ return QRect();
+
+ QRect result;
+
+#ifndef QT_NO_TABBAR
+ if (info->tabbed) {
+ result = info->tabContentRect();
+ } else
+#endif
+ {
+ int pos = item.pos;
+ int size = item.size;
+
+ int prev = info->prev(index);
+ int next = info->next(index);
+
+ if (prev != -1 && !(item_list.at(prev).flags & QDockAreaLayoutItem::GapItem)) {
+ pos += sep;
+ size -= sep;
+ }
+ if (next != -1 && !(item_list.at(next).flags & QDockAreaLayoutItem::GapItem))
+ size -= sep;
+
+ QPoint p;
+ rpick(o, p) = pos;
+ rperp(o, p) = perp(o, info->rect.topLeft());
+ QSize s;
+ rpick(o, s) = size;
+ rperp(o, s) = perp(o, info->rect.size());
+
+ result = QRect(p, s);
+ }
+
+ return result;
+}
+
+void QDockAreaLayout::keepSize(QDockWidget *w)
+{
+ QList<int> path = indexOf(w);
+ if (path.isEmpty())
+ return;
+ QDockAreaLayoutItem &item = this->item(path);
+ if (item.size != -1)
+ item.flags |= QDockAreaLayoutItem::KeepSize;
+}
+
+void QDockAreaLayout::styleChangedEvent()
+{
+ sep = mainWindow->style()->pixelMetric(QStyle::PM_DockWidgetSeparatorExtent, 0, mainWindow);
+ fitLayout();
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_DOCKWIDGET
diff --git a/src/widgets/widgets/qdockarealayout_p.h b/src/widgets/widgets/qdockarealayout_p.h
new file mode 100644
index 0000000000..a341ad487b
--- /dev/null
+++ b/src/widgets/widgets/qdockarealayout_p.h
@@ -0,0 +1,308 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDOCKAREALAYOUT_P_H
+#define QDOCKAREALAYOUT_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "QtCore/qrect.h"
+#include "QtCore/qpair.h"
+#include "QtCore/qlist.h"
+#include "QtCore/qvector.h"
+#include "QtWidgets/qlayout.h"
+
+#ifndef QT_NO_DOCKWIDGET
+
+QT_BEGIN_NAMESPACE
+
+class QLayoutItem;
+class QWidget;
+class QLayoutItem;
+class QDockAreaLayoutInfo;
+class QPlaceHolderItem;
+class QDockWidget;
+class QMainWindow;
+class QWidgetAnimator;
+class QMainWindowLayout;
+struct QLayoutStruct;
+class QTabBar;
+
+// The classes in this file represent the tree structure that represents all the docks
+// Also see the wiki internal documentation
+// At the root of the tree is: QDockAreaLayout, which handles all 4 sides, so there is only one.
+// For each side it has one QDockAreaLayoutInfo child. (See QDockAreaLayout::docks.)
+// The QDockAreaLayoutInfo have QDockAreaLayoutItems as children (See QDockAreaLayoutInfo::item_list),
+// which then has one QDockAreaLayoutInfo as a child. (QDockAreaLayoutItem::subInfo) or
+// a widgetItem if this is a node of the tree (QDockAreaLayoutItem::widgetItem)
+//
+// A path indetifies uniquely one object in this tree, the first number being the side and all the following
+// indexes into the QDockAreaLayoutInfo::item_list.
+
+struct QDockAreaLayoutItem
+{
+ enum ItemFlags { NoFlags = 0, GapItem = 1, KeepSize = 2 };
+
+ QDockAreaLayoutItem(QLayoutItem *_widgetItem = 0);
+ QDockAreaLayoutItem(QDockAreaLayoutInfo *_subinfo);
+ QDockAreaLayoutItem(QPlaceHolderItem *_placeHolderItem);
+ QDockAreaLayoutItem(const QDockAreaLayoutItem &other);
+ ~QDockAreaLayoutItem();
+
+ QDockAreaLayoutItem &operator = (const QDockAreaLayoutItem &other);
+
+ bool skip() const;
+ QSize minimumSize() const;
+ QSize maximumSize() const;
+ QSize sizeHint() const;
+ bool expansive(Qt::Orientation o) const;
+ bool hasFixedSize(Qt::Orientation o) const;
+
+ QLayoutItem *widgetItem;
+ QDockAreaLayoutInfo *subinfo;
+ QPlaceHolderItem *placeHolderItem;
+ int pos;
+ int size;
+ uint flags;
+};
+
+class Q_AUTOTEST_EXPORT QPlaceHolderItem
+{
+public:
+ QPlaceHolderItem() : hidden(false), window(false) {}
+ QPlaceHolderItem(QWidget *w);
+
+ QString objectName;
+ bool hidden, window;
+ QRect topLevelRect;
+};
+
+class Q_AUTOTEST_EXPORT QDockAreaLayoutInfo
+{
+public:
+ QDockAreaLayoutInfo();
+ QDockAreaLayoutInfo(const int *_sep, QInternal::DockPosition _dockPos, Qt::Orientation _o,
+ int tbhape, QMainWindow *window);
+
+ QSize minimumSize() const;
+ QSize maximumSize() const;
+ QSize sizeHint() const;
+ QSize size() const;
+
+ bool insertGap(const QList<int> &path, QLayoutItem *dockWidgetItem);
+ QLayoutItem *plug(const QList<int> &path);
+ QLayoutItem *unplug(const QList<int> &path);
+ enum TabMode { NoTabs, AllowTabs, ForceTabs };
+ QList<int> gapIndex(const QPoint &pos, bool nestingEnabled,
+ TabMode tabMode) const;
+ void remove(const QList<int> &path);
+ void unnest(int index);
+ void split(int index, Qt::Orientation orientation, QLayoutItem *dockWidgetItem);
+ void tab(int index, QLayoutItem *dockWidgetItem);
+ QDockAreaLayoutItem &item(const QList<int> &path);
+ QDockAreaLayoutInfo *info(const QList<int> &path);
+ QDockAreaLayoutInfo *info(QWidget *widget);
+
+ enum { // sentinel values used to validate state data
+ SequenceMarker = 0xfc,
+ TabMarker = 0xfa,
+ WidgetMarker = 0xfb
+ };
+ void saveState(QDataStream &stream) const;
+ bool restoreState(QDataStream &stream, QList<QDockWidget*> &widgets, bool testing);
+
+ void fitItems();
+ bool expansive(Qt::Orientation o) const;
+ int changeSize(int index, int size, bool below);
+ QRect itemRect(int index) const;
+ QRect itemRect(const QList<int> &path) const;
+ QRect separatorRect(int index) const;
+ QRect separatorRect(const QList<int> &path) const;
+
+ void clear();
+ bool isEmpty() const;
+ bool hasFixedSize() const;
+ QList<int> findSeparator(const QPoint &pos) const;
+ int next(int idx) const;
+ int prev(int idx) const;
+
+ QList<int> indexOf(QWidget *widget) const;
+ QList<int> indexOfPlaceHolder(const QString &objectName) const;
+
+ void apply(bool animate);
+
+ void paintSeparators(QPainter *p, QWidget *widget, const QRegion &clip,
+ const QPoint &mouse) const;
+ QRegion separatorRegion() const;
+ int separatorMove(int index, int delta);
+
+ QLayoutItem *itemAt(int *x, int index) const;
+ QLayoutItem *takeAt(int *x, int index);
+ void deleteAllLayoutItems();
+
+ QMainWindowLayout *mainWindowLayout() const;
+
+ const int *sep;
+ mutable QVector<QWidget*> separatorWidgets;
+ QInternal::DockPosition dockPos;
+ Qt::Orientation o;
+ QRect rect;
+ QMainWindow *mainWindow;
+ QList<QDockAreaLayoutItem> item_list;
+#ifndef QT_NO_TABBAR
+ void updateSeparatorWidgets() const;
+ QSet<QWidget*> usedSeparatorWidgets() const;
+#endif //QT_NO_TABBAR
+
+#ifndef QT_NO_TABBAR
+ quintptr currentTabId() const;
+ void setCurrentTab(QWidget *widget);
+ void setCurrentTabId(quintptr id);
+ QRect tabContentRect() const;
+ bool tabbed;
+ QTabBar *tabBar;
+ int tabBarShape;
+
+ bool updateTabBar() const;
+ void setTabBarShape(int shape);
+ QSize tabBarMinimumSize() const;
+ QSize tabBarSizeHint() const;
+
+ QSet<QTabBar*> usedTabBars() const;
+#endif // QT_NO_TABBAR
+};
+
+class Q_AUTOTEST_EXPORT QDockAreaLayout
+{
+public:
+ enum { EmptyDropAreaSize = 80 }; // when a dock area is empty, how "wide" is it?
+
+ Qt::DockWidgetArea corners[4]; // use a Qt::Corner for indexing
+ QRect rect;
+ QLayoutItem *centralWidgetItem;
+ QMainWindow *mainWindow;
+ QRect centralWidgetRect;
+ QDockAreaLayout(QMainWindow *win);
+ QDockAreaLayoutInfo docks[4];
+ int sep; // separator extent
+ bool fallbackToSizeHints; //determines if we should use the sizehint for the dock areas (true until the layout is restored or the central widget is set)
+ mutable QVector<QWidget*> separatorWidgets;
+
+ bool isValid() const;
+
+ enum { DockWidgetStateMarker = 0xfd };
+ void saveState(QDataStream &stream) const;
+ bool restoreState(QDataStream &stream, const QList<QDockWidget*> &widgets, bool testing = false);
+
+ QList<int> indexOfPlaceHolder(const QString &objectName) const;
+ QList<int> indexOf(QWidget *dockWidget) const;
+ QList<int> gapIndex(const QPoint &pos) const;
+ QList<int> findSeparator(const QPoint &pos) const;
+
+ QDockAreaLayoutItem &item(const QList<int> &path);
+ QDockAreaLayoutInfo *info(const QList<int> &path);
+ const QDockAreaLayoutInfo *info(const QList<int> &path) const;
+ QDockAreaLayoutInfo *info(QWidget *widget);
+ QRect itemRect(const QList<int> &path) const;
+ QRect separatorRect(int index) const;
+ QRect separatorRect(const QList<int> &path) const;
+
+ bool insertGap(const QList<int> &path, QLayoutItem *dockWidgetItem);
+ QLayoutItem *plug(const QList<int> &path);
+ QLayoutItem *unplug(const QList<int> &path);
+ void remove(const QList<int> &path);
+
+ void fitLayout();
+
+ void clear();
+
+ QSize sizeHint() const;
+ QSize minimumSize() const;
+
+ void addDockWidget(QInternal::DockPosition pos, QDockWidget *dockWidget, Qt::Orientation orientation);
+ bool restoreDockWidget(QDockWidget *dockWidget);
+ void splitDockWidget(QDockWidget *after, QDockWidget *dockWidget,
+ Qt::Orientation orientation);
+ void tabifyDockWidget(QDockWidget *first, QDockWidget *second);
+
+ void apply(bool animate);
+
+ void paintSeparators(QPainter *p, QWidget *widget, const QRegion &clip,
+ const QPoint &mouse) const;
+ QRegion separatorRegion() const;
+ int separatorMove(const QList<int> &separator, const QPoint &origin, const QPoint &dest);
+#ifndef QT_NO_TABBAR
+ void updateSeparatorWidgets() const;
+#endif //QT_NO_TABBAR
+
+ QLayoutItem *itemAt(int *x, int index) const;
+ QLayoutItem *takeAt(int *x, int index);
+ void deleteAllLayoutItems();
+
+ void getGrid(QVector<QLayoutStruct> *ver_struct_list,
+ QVector<QLayoutStruct> *hor_struct_list);
+ void setGrid(QVector<QLayoutStruct> *ver_struct_list,
+ QVector<QLayoutStruct> *hor_struct_list);
+
+ QRect gapRect(const QList<int> &path) const;
+
+ void keepSize(QDockWidget *w);
+#ifndef QT_NO_TABBAR
+ QSet<QTabBar*> usedTabBars() const;
+ QSet<QWidget*> usedSeparatorWidgets() const;
+#endif //QT_NO_TABBAR
+ void styleChangedEvent();
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_QDOCKWIDGET
+
+#endif // QDOCKAREALAYOUT_P_H
diff --git a/src/widgets/widgets/qdockwidget.cpp b/src/widgets/widgets/qdockwidget.cpp
new file mode 100644
index 0000000000..53e007aea5
--- /dev/null
+++ b/src/widgets/widgets/qdockwidget.cpp
@@ -0,0 +1,1605 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdockwidget.h"
+
+#ifndef QT_NO_DOCKWIDGET
+#include <qaction.h>
+#include <qapplication.h>
+#include <qdesktopwidget.h>
+#include <qdrawutil.h>
+#include <qevent.h>
+#include <qfontmetrics.h>
+#include <qmainwindow.h>
+#include <qrubberband.h>
+#include <qstylepainter.h>
+#include <qtoolbutton.h>
+#include <qdebug.h>
+
+#include <private/qwidgetresizehandler_p.h>
+
+#include "qdockwidget_p.h"
+#include "qmainwindowlayout_p.h"
+#ifdef Q_WS_MAC
+#include <private/qapplication_p.h>
+#include <private/qt_mac_p.h>
+#include <qmacstyle_mac.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+extern QString qt_setWindowTitle_helperHelper(const QString&, const QWidget*); // qwidget.cpp
+
+// qmainwindow.cpp
+extern QMainWindowLayout *qt_mainwindow_layout(const QMainWindow *window);
+
+static inline bool hasFeature(const QDockWidgetPrivate *priv, QDockWidget::DockWidgetFeature feature)
+{ return (priv->features & feature) == feature; }
+
+static inline bool hasFeature(const QDockWidget *dockwidget, QDockWidget::DockWidgetFeature feature)
+{ return (dockwidget->features() & feature) == feature; }
+
+
+/*
+ A Dock Window:
+
+ [+] is the float button
+ [X] is the close button
+
+ +-------------------------------+
+ | Dock Window Title [+][X]|
+ +-------------------------------+
+ | |
+ | place to put the single |
+ | QDockWidget child (this space |
+ | does not yet have a name) |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ +-------------------------------+
+
+*/
+
+/******************************************************************************
+** QDockWidgetTitleButton
+*/
+
+class QDockWidgetTitleButton : public QAbstractButton
+{
+ Q_OBJECT
+
+public:
+ QDockWidgetTitleButton(QDockWidget *dockWidget);
+
+ QSize sizeHint() const;
+ inline QSize minimumSizeHint() const
+ { return sizeHint(); }
+
+ void enterEvent(QEvent *event);
+ void leaveEvent(QEvent *event);
+ void paintEvent(QPaintEvent *event);
+};
+
+
+QDockWidgetTitleButton::QDockWidgetTitleButton(QDockWidget *dockWidget)
+ : QAbstractButton(dockWidget)
+{
+ setFocusPolicy(Qt::NoFocus);
+}
+
+QSize QDockWidgetTitleButton::sizeHint() const
+{
+ ensurePolished();
+
+ int size = 2*style()->pixelMetric(QStyle::PM_DockWidgetTitleBarButtonMargin, 0, this);
+ if (!icon().isNull()) {
+ int iconSize = style()->pixelMetric(QStyle::PM_SmallIconSize, 0, this);
+ QSize sz = icon().actualSize(QSize(iconSize, iconSize));
+ size += qMax(sz.width(), sz.height());
+ }
+
+ return QSize(size, size);
+}
+
+void QDockWidgetTitleButton::enterEvent(QEvent *event)
+{
+ if (isEnabled()) update();
+ QAbstractButton::enterEvent(event);
+}
+
+void QDockWidgetTitleButton::leaveEvent(QEvent *event)
+{
+ if (isEnabled()) update();
+ QAbstractButton::leaveEvent(event);
+}
+
+void QDockWidgetTitleButton::paintEvent(QPaintEvent *)
+{
+ QPainter p(this);
+
+ QStyleOptionToolButton opt;
+ opt.init(this);
+ opt.state |= QStyle::State_AutoRaise;
+
+ if (style()->styleHint(QStyle::SH_DockWidget_ButtonsHaveFrame, 0, this))
+ {
+ if (isEnabled() && underMouse() && !isChecked() && !isDown())
+ opt.state |= QStyle::State_Raised;
+ if (isChecked())
+ opt.state |= QStyle::State_On;
+ if (isDown())
+ opt.state |= QStyle::State_Sunken;
+ style()->drawPrimitive(QStyle::PE_PanelButtonTool, &opt, &p, this);
+ }
+
+ opt.icon = icon();
+ opt.subControls = 0;
+ opt.activeSubControls = 0;
+ opt.features = QStyleOptionToolButton::None;
+ opt.arrowType = Qt::NoArrow;
+ int size = style()->pixelMetric(QStyle::PM_SmallIconSize, 0, this);
+ opt.iconSize = QSize(size, size);
+ style()->drawComplexControl(QStyle::CC_ToolButton, &opt, &p, this);
+}
+
+/******************************************************************************
+** QDockWidgetLayout
+*/
+
+QDockWidgetLayout::QDockWidgetLayout(QWidget *parent)
+ : QLayout(parent), verticalTitleBar(false), item_list(RoleCount, 0)
+{
+}
+
+QDockWidgetLayout::~QDockWidgetLayout()
+{
+ qDeleteAll(item_list);
+}
+
+bool QDockWidgetLayout::nativeWindowDeco() const
+{
+ return nativeWindowDeco(parentWidget()->isWindow());
+}
+
+bool QDockWidgetLayout::nativeWindowDeco(bool floating) const
+{
+#if defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_WS_WINCE)
+ Q_UNUSED(floating);
+ return false;
+#else
+ return floating && item_list[QDockWidgetLayout::TitleBar] == 0;
+#endif
+}
+
+
+void QDockWidgetLayout::addItem(QLayoutItem*)
+{
+ qWarning() << "QDockWidgetLayout::addItem(): please use QDockWidgetLayout::setWidget()";
+ return;
+}
+
+QLayoutItem *QDockWidgetLayout::itemAt(int index) const
+{
+ int cnt = 0;
+ for (int i = 0; i < item_list.count(); ++i) {
+ QLayoutItem *item = item_list.at(i);
+ if (item == 0)
+ continue;
+ if (index == cnt++)
+ return item;
+ }
+ return 0;
+}
+
+QLayoutItem *QDockWidgetLayout::takeAt(int index)
+{
+ int j = 0;
+ for (int i = 0; i < item_list.count(); ++i) {
+ QLayoutItem *item = item_list.at(i);
+ if (item == 0)
+ continue;
+ if (index == j) {
+ item_list[i] = 0;
+ invalidate();
+ return item;
+ }
+ ++j;
+ }
+ return 0;
+}
+
+int QDockWidgetLayout::count() const
+{
+ int result = 0;
+ for (int i = 0; i < item_list.count(); ++i) {
+ if (item_list.at(i))
+ ++result;
+ }
+ return result;
+}
+
+QSize QDockWidgetLayout::sizeFromContent(const QSize &content, bool floating) const
+{
+ QSize result = content;
+
+ if (verticalTitleBar) {
+ result.setHeight(qMax(result.height(), minimumTitleWidth()));
+ result.setWidth(qMax(content.width(), 0));
+ } else {
+ result.setHeight(qMax(result.height(), 0));
+ result.setWidth(qMax(content.width(), minimumTitleWidth()));
+ }
+
+ QDockWidget *w = qobject_cast<QDockWidget*>(parentWidget());
+ const bool nativeDeco = nativeWindowDeco(floating);
+
+ int fw = floating && !nativeDeco
+ ? w->style()->pixelMetric(QStyle::PM_DockWidgetFrameWidth, 0, w)
+ : 0;
+
+ const int th = titleHeight();
+ if (!nativeDeco) {
+ if (verticalTitleBar)
+ result += QSize(th + 2*fw, 2*fw);
+ else
+ result += QSize(2*fw, th + 2*fw);
+ }
+
+ result.setHeight(qMin(result.height(), (int) QWIDGETSIZE_MAX));
+ result.setWidth(qMin(result.width(), (int) QWIDGETSIZE_MAX));
+
+ if (content.width() < 0)
+ result.setWidth(-1);
+ if (content.height() < 0)
+ result.setHeight(-1);
+
+ 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()
+ into account if the user set it herself. Otherwise we end up expanding the result
+ of a calculation for a non-floating dock widget to a floating dock widget's
+ minimum size + window decorations. */
+
+ uint explicitMin = 0;
+ uint explicitMax = 0;
+ if (w->d_func()->extra != 0) {
+ explicitMin = w->d_func()->extra->explicitMinSize;
+ explicitMax = w->d_func()->extra->explicitMaxSize;
+ }
+
+ if (!(explicitMin & Qt::Horizontal) || min.width() == 0)
+ min.setWidth(-1);
+ if (!(explicitMin & Qt::Vertical) || min.height() == 0)
+ min.setHeight(-1);
+
+ if (!(explicitMax & Qt::Horizontal))
+ max.setWidth(QWIDGETSIZE_MAX);
+ if (!(explicitMax & Qt::Vertical))
+ max.setHeight(QWIDGETSIZE_MAX);
+
+ return result.boundedTo(max).expandedTo(min);
+}
+
+QSize QDockWidgetLayout::sizeHint() const
+{
+ QDockWidget *w = qobject_cast<QDockWidget*>(parentWidget());
+
+ QSize content(-1, -1);
+ if (item_list[Content] != 0)
+ content = item_list[Content]->sizeHint();
+
+ return sizeFromContent(content, w->isFloating());
+}
+
+QSize QDockWidgetLayout::maximumSize() const
+{
+ if (item_list[Content] != 0) {
+ const QSize content = item_list[Content]->maximumSize();
+ return sizeFromContent(content, parentWidget()->isWindow());
+ } else {
+ return parentWidget()->maximumSize();
+ }
+
+}
+
+QSize QDockWidgetLayout::minimumSize() const
+{
+ QDockWidget *w = qobject_cast<QDockWidget*>(parentWidget());
+
+ QSize content(0, 0);
+ if (item_list[Content] != 0)
+ content = item_list[Content]->minimumSize();
+
+ return sizeFromContent(content, w->isFloating());
+}
+
+QWidget *QDockWidgetLayout::widgetForRole(Role r) const
+{
+ QLayoutItem *item = item_list.at(r);
+ return item == 0 ? 0 : item->widget();
+}
+
+QLayoutItem *QDockWidgetLayout::itemForRole(Role r) const
+{
+ return item_list.at(r);
+}
+
+void QDockWidgetLayout::setWidgetForRole(Role r, QWidget *w)
+{
+ QWidget *old = widgetForRole(r);
+ if (old != 0) {
+ old->hide();
+ removeWidget(old);
+ }
+
+ if (w != 0) {
+ addChildWidget(w);
+ item_list[r] = new QWidgetItemV2(w);
+ w->show();
+ } else {
+ item_list[r] = 0;
+ }
+
+ invalidate();
+}
+
+static inline int pick(bool vertical, const QSize &size)
+{
+ return vertical ? size.height() : size.width();
+}
+
+static inline int perp(bool vertical, const QSize &size)
+{
+ return vertical ? size.width() : size.height();
+}
+
+int QDockWidgetLayout::minimumTitleWidth() const
+{
+ QDockWidget *q = qobject_cast<QDockWidget*>(parentWidget());
+
+ if (QWidget *title = widgetForRole(TitleBar))
+ return pick(verticalTitleBar, title->minimumSizeHint());
+
+ QSize closeSize(0, 0);
+ QSize floatSize(0, 0);
+ 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();
+
+ int mw = q->style()->pixelMetric(QStyle::PM_DockWidgetTitleMargin, 0, q);
+ int fw = q->style()->pixelMetric(QStyle::PM_DockWidgetFrameWidth, 0, q);
+
+ return pick(verticalTitleBar, closeSize)
+ + pick(verticalTitleBar, floatSize)
+ + titleHeight + 2*fw + 3*mw;
+}
+
+int QDockWidgetLayout::titleHeight() const
+{
+ QDockWidget *q = qobject_cast<QDockWidget*>(parentWidget());
+
+ if (QWidget *title = widgetForRole(TitleBar))
+ return perp(verticalTitleBar, title->sizeHint());
+
+ QSize closeSize(0, 0);
+ QSize floatSize(0, 0);
+ if (QLayoutItem *item = item_list[CloseButton])
+ closeSize = item->widget()->sizeHint();
+ if (QLayoutItem *item = item_list[FloatButton])
+ floatSize = item->widget()->sizeHint();
+
+ int buttonHeight = qMax(perp(verticalTitleBar, closeSize),
+ perp(verticalTitleBar, floatSize));
+
+ QFontMetrics titleFontMetrics = q->fontMetrics();
+#ifdef Q_WS_MAC
+ if (qobject_cast<QMacStyle *>(q->style())) {
+ //### this breaks on proxy styles. (But is this code still called?)
+ QFont font = qt_app_fonts_hash()->value("QToolButton", q->font());
+ titleFontMetrics = QFontMetrics(font);
+ }
+#endif
+
+ int mw = q->style()->pixelMetric(QStyle::PM_DockWidgetTitleMargin, 0, q);
+
+ return qMax(buttonHeight + 2, titleFontMetrics.height() + 2*mw);
+}
+
+void QDockWidgetLayout::setGeometry(const QRect &geometry)
+{
+ QDockWidget *q = qobject_cast<QDockWidget*>(parentWidget());
+
+ bool nativeDeco = nativeWindowDeco();
+
+ int fw = q->isFloating() && !nativeDeco
+ ? q->style()->pixelMetric(QStyle::PM_DockWidgetFrameWidth, 0, q)
+ : 0;
+
+ if (nativeDeco) {
+ if (QLayoutItem *item = item_list[Content])
+ item->setGeometry(geometry);
+ } else {
+ int titleHeight = this->titleHeight();
+
+ if (verticalTitleBar) {
+ _titleArea = QRect(QPoint(fw, fw),
+ QSize(titleHeight, geometry.height() - (fw * 2)));
+ } else {
+ _titleArea = QRect(QPoint(fw, fw),
+ QSize(geometry.width() - (fw * 2), titleHeight));
+ }
+
+ if (QLayoutItem *item = item_list[TitleBar]) {
+ item->setGeometry(_titleArea);
+ } else {
+ QStyleOptionDockWidgetV2 opt;
+ q->initStyleOption(&opt);
+
+ if (QLayoutItem *item = item_list[CloseButton]) {
+ if (!item->isEmpty()) {
+ QRect r = q->style()
+ ->subElementRect(QStyle::SE_DockWidgetCloseButton,
+ &opt, q);
+ if (!r.isNull())
+ item->setGeometry(r);
+ }
+ }
+
+ if (QLayoutItem *item = item_list[FloatButton]) {
+ if (!item->isEmpty()) {
+ QRect r = q->style()
+ ->subElementRect(QStyle::SE_DockWidgetFloatButton,
+ &opt, q);
+ if (!r.isNull())
+ item->setGeometry(r);
+ }
+ }
+ }
+
+ if (QLayoutItem *item = item_list[Content]) {
+ QRect r = geometry;
+ if (verticalTitleBar) {
+ r.setLeft(_titleArea.right() + 1);
+ r.adjust(0, fw, -fw, -fw);
+ } else {
+ r.setTop(_titleArea.bottom() + 1);
+ r.adjust(fw, 0, -fw, -fw);
+ }
+ item->setGeometry(r);
+ }
+ }
+}
+
+void QDockWidgetLayout::setVerticalTitleBar(bool b)
+{
+ if (b == verticalTitleBar)
+ return;
+ verticalTitleBar = b;
+ invalidate();
+ parentWidget()->update();
+}
+
+/******************************************************************************
+** QDockWidgetItem
+*/
+
+QDockWidgetItem::QDockWidgetItem(QDockWidget *dockWidget)
+ : QWidgetItem(dockWidget)
+{
+}
+
+QSize QDockWidgetItem::minimumSize() const
+{
+ QSize widgetMin(0, 0);
+ if (QLayoutItem *item = dockWidgetChildItem())
+ widgetMin = item->minimumSize();
+ return dockWidgetLayout()->sizeFromContent(widgetMin, false);
+}
+
+QSize QDockWidgetItem::maximumSize() const
+{
+ if (QLayoutItem *item = dockWidgetChildItem()) {
+ return dockWidgetLayout()->sizeFromContent(item->maximumSize(), false);
+ } else {
+ return QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
+ }
+}
+
+
+QSize QDockWidgetItem::sizeHint() const
+{
+ if (QLayoutItem *item = dockWidgetChildItem()) {
+ return dockWidgetLayout()->sizeFromContent(item->sizeHint(), false);
+ } else {
+ return QWidgetItem::sizeHint();
+ }
+}
+
+/******************************************************************************
+** QDockWidgetPrivate
+*/
+
+void QDockWidgetPrivate::init()
+{
+ Q_Q(QDockWidget);
+
+ QDockWidgetLayout *layout = new QDockWidgetLayout(q);
+ layout->setSizeConstraint(QLayout::SetMinAndMaxSize);
+
+ QAbstractButton *button = new QDockWidgetTitleButton(q);
+ button->setObjectName(QLatin1String("qt_dockwidget_floatbutton"));
+ QObject::connect(button, SIGNAL(clicked()), q, SLOT(_q_toggleTopLevel()));
+ layout->setWidgetForRole(QDockWidgetLayout::FloatButton, button);
+
+ button = new QDockWidgetTitleButton(q);
+ button->setObjectName(QLatin1String("qt_dockwidget_closebutton"));
+ QObject::connect(button, SIGNAL(clicked()), q, SLOT(close()));
+ layout->setWidgetForRole(QDockWidgetLayout::CloseButton, button);
+
+ resizer = new QWidgetResizeHandler(q);
+ resizer->setMovingEnabled(false);
+ resizer->setActive(false);
+
+#ifndef QT_NO_ACTION
+ toggleViewAction = new QAction(q);
+ toggleViewAction->setCheckable(true);
+ fixedWindowTitle = qt_setWindowTitle_helperHelper(q->windowTitle(), q);
+ toggleViewAction->setText(fixedWindowTitle);
+ QObject::connect(toggleViewAction, SIGNAL(triggered(bool)),
+ q, SLOT(_q_toggleView(bool)));
+#endif
+
+ updateButtons();
+}
+
+/*!
+ Initialize \a option with the values from this QDockWidget. This method
+ is useful for subclasses when they need a QStyleOptionDockWidget, but don't want
+ to fill in all the information themselves.
+
+ \sa QStyleOption::initFrom()
+*/
+void QDockWidget::initStyleOption(QStyleOptionDockWidget *option) const
+{
+ Q_D(const QDockWidget);
+
+ if (!option)
+ return;
+ QDockWidgetLayout *dwlayout = qobject_cast<QDockWidgetLayout*>(layout());
+
+ option->initFrom(this);
+ option->rect = dwlayout->titleArea();
+ option->title = d->fixedWindowTitle;
+ option->closable = hasFeature(this, QDockWidget::DockWidgetClosable);
+ option->movable = hasFeature(this, QDockWidget::DockWidgetMovable);
+ option->floatable = hasFeature(this, QDockWidget::DockWidgetFloatable);
+
+ QDockWidgetLayout *l = qobject_cast<QDockWidgetLayout*>(layout());
+ QStyleOptionDockWidgetV2 *v2
+ = qstyleoption_cast<QStyleOptionDockWidgetV2*>(option);
+ if (v2 != 0)
+ v2->verticalTitleBar = l->verticalTitleBar;
+}
+
+void QDockWidgetPrivate::_q_toggleView(bool b)
+{
+ Q_Q(QDockWidget);
+ if (b == q->isHidden()) {
+ if (b)
+ q->show();
+ else
+ q->close();
+ }
+}
+
+void QDockWidgetPrivate::updateButtons()
+{
+ Q_Q(QDockWidget);
+ QDockWidgetLayout *dwLayout = qobject_cast<QDockWidgetLayout*>(layout);
+
+ QStyleOptionDockWidget opt;
+ q->initStyleOption(&opt);
+
+ bool customTitleBar = dwLayout->widgetForRole(QDockWidgetLayout::TitleBar) != 0;
+ bool nativeDeco = dwLayout->nativeWindowDeco();
+ bool hideButtons = nativeDeco || customTitleBar;
+
+ bool canClose = hasFeature(this, QDockWidget::DockWidgetClosable);
+ bool canFloat = hasFeature(this, QDockWidget::DockWidgetFloatable);
+
+ QAbstractButton *button
+ = qobject_cast<QAbstractButton*>(dwLayout->widgetForRole(QDockWidgetLayout::FloatButton));
+ button->setIcon(q->style()->standardIcon(QStyle::SP_TitleBarNormalButton, &opt, q));
+ button->setVisible(canFloat && !hideButtons);
+
+ button
+ = qobject_cast <QAbstractButton*>(dwLayout->widgetForRole(QDockWidgetLayout::CloseButton));
+ button->setIcon(q->style()->standardIcon(QStyle::SP_TitleBarCloseButton, &opt, q));
+ button->setVisible(canClose && !hideButtons);
+
+ q->setAttribute(Qt::WA_ContentsPropagated,
+ (canFloat || canClose) && !hideButtons);
+
+ layout->invalidate();
+}
+
+void QDockWidgetPrivate::_q_toggleTopLevel()
+{
+ Q_Q(QDockWidget);
+ q->setFloating(!q->isFloating());
+}
+
+void QDockWidgetPrivate::initDrag(const QPoint &pos, bool nca)
+{
+ if (state != 0)
+ return;
+
+ QMainWindow *win = qobject_cast<QMainWindow*>(parent);
+ Q_ASSERT(win != 0);
+ QMainWindowLayout *layout = qt_mainwindow_layout(win);
+ Q_ASSERT(layout != 0);
+ if (layout->pluggingWidget != 0) // the main window is animating a docking operation
+ return;
+
+ state = new QDockWidgetPrivate::DragState;
+ state->pressPos = pos;
+ state->dragging = false;
+ state->widgetItem = 0;
+ state->ownWidgetItem = false;
+ state->nca = nca;
+ state->ctrlDrag = false;
+}
+
+void QDockWidgetPrivate::startDrag()
+{
+ Q_Q(QDockWidget);
+
+ if (state == 0 || state->dragging)
+ return;
+
+ QMainWindowLayout *layout = qt_mainwindow_layout(qobject_cast<QMainWindow *>(q->parentWidget()));
+ Q_ASSERT(layout != 0);
+
+ state->widgetItem = layout->unplug(q);
+ if (state->widgetItem == 0) {
+ /* I have a QMainWindow parent, but I was never inserted with
+ QMainWindow::addDockWidget, so the QMainWindowLayout has no
+ widget item for me. :( I have to create it myself, and then
+ delete it if I don't get dropped into a dock area. */
+ state->widgetItem = new QDockWidgetItem(q);
+ state->ownWidgetItem = true;
+ }
+
+ if (state->ctrlDrag)
+ layout->restore();
+
+ state->dragging = true;
+}
+
+void QDockWidgetPrivate::endDrag(bool abort)
+{
+ Q_Q(QDockWidget);
+ Q_ASSERT(state != 0);
+
+ q->releaseMouse();
+
+ if (state->dragging) {
+ QMainWindowLayout *mwLayout = qt_mainwindow_layout(qobject_cast<QMainWindow *>(q->parentWidget()));
+ Q_ASSERT(mwLayout != 0);
+
+ if (abort || !mwLayout->plug(state->widgetItem)) {
+ if (hasFeature(this, QDockWidget::DockWidgetFloatable)) {
+ if (state->ownWidgetItem)
+ delete state->widgetItem;
+ mwLayout->restore();
+#ifdef Q_WS_X11
+ // get rid of the X11BypassWindowManager window flag and activate the resizer
+ Qt::WindowFlags flags = q->windowFlags();
+ flags &= ~Qt::X11BypassWindowManagerHint;
+ q->setWindowFlags(flags);
+ resizer->setActive(QWidgetResizeHandler::Resize, true);
+ q->show();
+#else
+ QDockWidgetLayout *myLayout
+ = qobject_cast<QDockWidgetLayout*>(layout);
+ resizer->setActive(QWidgetResizeHandler::Resize,
+ myLayout->widgetForRole(QDockWidgetLayout::TitleBar) != 0);
+#endif
+ undockedGeometry = q->geometry();
+ q->activateWindow();
+ } else {
+ mwLayout->revert(state->widgetItem);
+ }
+ }
+ }
+ delete state;
+ state = 0;
+}
+
+bool QDockWidgetPrivate::isAnimating() const
+{
+ Q_Q(const QDockWidget);
+
+ QMainWindow *mainWin = qobject_cast<QMainWindow*>(parent);
+ if (mainWin == 0)
+ return false;
+
+ QMainWindowLayout *mainWinLayout = qt_mainwindow_layout(mainWin);
+ if (mainWinLayout == 0)
+ return false;
+
+ return (void*)mainWinLayout->pluggingWidget == (void*)q;
+}
+
+bool QDockWidgetPrivate::mousePressEvent(QMouseEvent *event)
+{
+#if !defined(QT_NO_MAINWINDOW)
+ Q_Q(QDockWidget);
+
+ QDockWidgetLayout *dwLayout
+ = qobject_cast<QDockWidgetLayout*>(layout);
+
+ if (!dwLayout->nativeWindowDeco()) {
+ QRect titleArea = dwLayout->titleArea();
+
+ if (event->button() != Qt::LeftButton ||
+ !titleArea.contains(event->pos()) ||
+ // check if the tool window is movable... do nothing if it
+ // is not (but allow moving if the window is floating)
+ (!hasFeature(this, QDockWidget::DockWidgetMovable) && !q->isFloating()) ||
+ qobject_cast<QMainWindow*>(parent) == 0 ||
+ isAnimating() || state != 0) {
+ return false;
+ }
+
+ initDrag(event->pos(), false);
+
+ if (state)
+ state->ctrlDrag = hasFeature(this, QDockWidget::DockWidgetFloatable) && event->modifiers() & Qt::ControlModifier;
+
+ return true;
+ }
+
+#endif // !defined(QT_NO_MAINWINDOW)
+ return false;
+}
+
+bool QDockWidgetPrivate::mouseDoubleClickEvent(QMouseEvent *event)
+{
+ QDockWidgetLayout *dwLayout = qobject_cast<QDockWidgetLayout*>(layout);
+
+ if (!dwLayout->nativeWindowDeco()) {
+ QRect titleArea = dwLayout->titleArea();
+
+ if (event->button() == Qt::LeftButton && titleArea.contains(event->pos()) &&
+ hasFeature(this, QDockWidget::DockWidgetFloatable)) {
+ _q_toggleTopLevel();
+ return true;
+ }
+ }
+ return false;
+}
+
+bool QDockWidgetPrivate::mouseMoveEvent(QMouseEvent *event)
+{
+ bool ret = false;
+#if !defined(QT_NO_MAINWINDOW)
+ Q_Q(QDockWidget);
+
+ if (!state)
+ return ret;
+
+ QDockWidgetLayout *dwlayout
+ = qobject_cast<QDockWidgetLayout *>(layout);
+ QMainWindowLayout *mwlayout = qt_mainwindow_layout(qobject_cast<QMainWindow *>(q->parentWidget()));
+ if (!dwlayout->nativeWindowDeco()) {
+ if (!state->dragging
+ && mwlayout->pluggingWidget == 0
+ && (event->pos() - state->pressPos).manhattanLength()
+ > QApplication::startDragDistance()) {
+ startDrag();
+#ifdef Q_WS_WIN
+ grabMouseWhileInWindow();
+#else
+ q->grabMouse();
+#endif
+ ret = true;
+ }
+ }
+
+ if (state->dragging && !state->nca) {
+ QPoint pos = event->globalPos() - state->pressPos;
+ q->move(pos);
+
+ if (!state->ctrlDrag)
+ mwlayout->hover(state->widgetItem, event->globalPos());
+
+ ret = true;
+ }
+
+#endif // !defined(QT_NO_MAINWINDOW)
+ return ret;
+}
+
+bool QDockWidgetPrivate::mouseReleaseEvent(QMouseEvent *event)
+{
+#if !defined(QT_NO_MAINWINDOW)
+
+ if (event->button() == Qt::LeftButton && state && !state->nca) {
+ endDrag();
+ return true; //filter out the event
+ }
+
+#endif // !defined(QT_NO_MAINWINDOW)
+ return false;
+}
+
+void QDockWidgetPrivate::nonClientAreaMouseEvent(QMouseEvent *event)
+{
+ Q_Q(QDockWidget);
+
+ int fw = q->style()->pixelMetric(QStyle::PM_DockWidgetFrameWidth, 0, q);
+
+ QRect geo = q->geometry();
+ QRect titleRect = q->frameGeometry();
+#ifdef Q_WS_MAC
+ if ((features & QDockWidget::DockWidgetVerticalTitleBar)) {
+ titleRect.setTop(geo.top());
+ titleRect.setBottom(geo.bottom());
+ titleRect.setRight(geo.left() - 1);
+ } else
+#endif
+ {
+ titleRect.setLeft(geo.left());
+ titleRect.setRight(geo.right());
+ titleRect.setBottom(geo.top() - 1);
+ titleRect.adjust(0, fw, 0, 0);
+ }
+
+ switch (event->type()) {
+ case QEvent::NonClientAreaMouseButtonPress:
+ if (!titleRect.contains(event->globalPos()))
+ break;
+ if (state != 0)
+ break;
+ if (qobject_cast<QMainWindow*>(parent) == 0)
+ break;
+ if (isAnimating())
+ break;
+ initDrag(event->pos(), true);
+ if (state == 0)
+ break;
+#ifdef Q_WS_WIN
+ // On Windows, NCA mouse events don't contain modifier info
+ state->ctrlDrag = GetKeyState(VK_CONTROL) & 0x8000;
+#else
+ state->ctrlDrag = event->modifiers() & Qt::ControlModifier;
+#endif
+ startDrag();
+ break;
+ case QEvent::NonClientAreaMouseMove:
+ if (state == 0 || !state->dragging)
+ break;
+ if (state->nca) {
+ endDrag();
+ }
+#ifdef Q_OS_MAC
+ else { // workaround for lack of mouse-grab on Mac
+ QMainWindowLayout *layout = qt_mainwindow_layout(qobject_cast<QMainWindow *>(q->parentWidget()));
+ Q_ASSERT(layout != 0);
+
+ q->move(event->globalPos() - state->pressPos);
+ if (!state->ctrlDrag)
+ layout->hover(state->widgetItem, event->globalPos());
+ }
+#endif
+ break;
+ case QEvent::NonClientAreaMouseButtonRelease:
+#ifdef Q_OS_MAC
+ if (state)
+ endDrag();
+#endif
+ break;
+ case QEvent::NonClientAreaMouseButtonDblClick:
+ _q_toggleTopLevel();
+ break;
+ default:
+ break;
+ }
+}
+
+void QDockWidgetPrivate::moveEvent(QMoveEvent *event)
+{
+ Q_Q(QDockWidget);
+
+ if (state == 0 || !state->dragging || !state->nca || !q->isWindow())
+ return;
+
+ // When the native window frame is being dragged, all we get is these mouse
+ // move events.
+
+ if (state->ctrlDrag)
+ return;
+
+ QMainWindowLayout *layout = qt_mainwindow_layout(qobject_cast<QMainWindow *>(q->parentWidget()));
+ Q_ASSERT(layout != 0);
+
+ QPoint globalMousePos = event->pos() + state->pressPos;
+ layout->hover(state->widgetItem, globalMousePos);
+}
+
+void QDockWidgetPrivate::unplug(const QRect &rect)
+{
+ Q_Q(QDockWidget);
+ QRect r = rect;
+ r.moveTopLeft(q->mapToGlobal(QPoint(0, 0)));
+ QDockWidgetLayout *dwLayout = qobject_cast<QDockWidgetLayout*>(layout);
+ if (dwLayout->nativeWindowDeco(true))
+ r.adjust(0, dwLayout->titleHeight(), 0, 0);
+ setWindowState(true, true, r);
+}
+
+void QDockWidgetPrivate::plug(const QRect &rect)
+{
+ setWindowState(false, false, rect);
+}
+
+void QDockWidgetPrivate::setWindowState(bool floating, bool unplug, const QRect &rect)
+{
+ Q_Q(QDockWidget);
+
+ if (!floating && parent) {
+ QMainWindowLayout *mwlayout = qt_mainwindow_layout(qobject_cast<QMainWindow *>(q->parentWidget()));
+ if (mwlayout && mwlayout->dockWidgetArea(q) == Qt::NoDockWidgetArea)
+ return; // this dockwidget can't be redocked
+ }
+
+ bool wasFloating = q->isFloating();
+ bool hidden = q->isHidden();
+
+ if (q->isVisible())
+ q->hide();
+
+ Qt::WindowFlags flags = floating ? Qt::Tool : Qt::Widget;
+
+ QDockWidgetLayout *dwLayout = qobject_cast<QDockWidgetLayout*>(layout);
+ const bool nativeDeco = dwLayout->nativeWindowDeco(floating);
+
+ if (nativeDeco) {
+ flags |= Qt::CustomizeWindowHint | Qt::WindowTitleHint;
+ if (hasFeature(this, QDockWidget::DockWidgetClosable))
+ flags |= Qt::WindowCloseButtonHint;
+ } else {
+ flags |= Qt::FramelessWindowHint;
+ }
+
+ if (unplug)
+ flags |= Qt::X11BypassWindowManagerHint;
+
+ q->setWindowFlags(flags);
+
+#if defined(Q_WS_MAC) && !defined(QT_MAC_USE_COCOA)
+ if (floating && nativeDeco && (q->features() & QDockWidget::DockWidgetVerticalTitleBar)) {
+ ChangeWindowAttributes(HIViewGetWindow(HIViewRef(q->winId())), kWindowSideTitlebarAttribute, 0);
+ }
+#endif
+
+ if (!rect.isNull())
+ q->setGeometry(rect);
+
+ updateButtons();
+
+ if (!hidden)
+ q->show();
+
+ if (floating != wasFloating) {
+ emit q->topLevelChanged(floating);
+ if (!floating && parent) {
+ QMainWindowLayout *mwlayout = qt_mainwindow_layout(qobject_cast<QMainWindow *>(q->parentWidget()));
+ if (mwlayout)
+ emit q->dockLocationChanged(mwlayout->dockWidgetArea(q));
+ }
+ }
+
+ resizer->setActive(QWidgetResizeHandler::Resize, !unplug && floating && !nativeDeco);
+}
+
+/*!
+ \class QDockWidget
+
+ \brief The QDockWidget class provides a widget that can be docked
+ inside a QMainWindow or floated as a top-level window on the
+ desktop.
+
+ \ingroup mainwindow-classes
+
+ QDockWidget provides the concept of dock widgets, also know as
+ tool palettes or utility windows. Dock windows are secondary
+ windows placed in the \e {dock widget area} around the
+ \l{QMainWindow::centralWidget()}{central widget} in a
+ QMainWindow.
+
+ \image mainwindow-docks.png
+
+ Dock windows can be moved inside their current area, moved into
+ new areas and floated (e.g., undocked) by the end-user. The
+ QDockWidget API allows the programmer to restrict the dock widgets
+ ability to move, float and close, as well as the areas in which
+ they can be placed.
+
+ \section1 Appearance
+
+ A QDockWidget consists of a title bar and the content area. The
+ title bar displays the dock widgets \link QWidget::windowTitle()
+ window title\endlink, a \e float button and a \e close button.
+ Depending on the state of the QDockWidget, the \e float and \e
+ close buttons may be either disabled or not shown at all.
+
+ The visual appearance of the title bar and buttons is dependent
+ on the \l{QStyle}{style} in use.
+
+ A QDockWidget acts as a wrapper for its child widget, set with setWidget().
+ Custom size hints, minimum and maximum sizes and size policies should be
+ implemented in the child widget. QDockWidget will respect them, adjusting
+ its own constraints to include the frame and title. Size constraints
+ should not be set on the QDockWidget itself, because they change depending
+ on whether it is docked; a docked QDockWidget has no frame and a smaller title
+ bar.
+
+ \sa QMainWindow, {Dock Widgets Example}
+*/
+
+/*!
+ \enum QDockWidget::DockWidgetFeature
+
+ \value DockWidgetClosable The dock widget can be closed. On some systems the dock
+ widget always has a close button when it's floating
+ (for example on MacOS 10.5).
+ \value DockWidgetMovable The dock widget can be moved between docks
+ by the user.
+ \value DockWidgetFloatable The dock widget can be detached from the
+ main window, and floated as an independent
+ window.
+ \value DockWidgetVerticalTitleBar The dock widget displays a vertical title
+ bar on its left side. This can be used to
+ increase the amount of vertical space in
+ a QMainWindow.
+ \value AllDockWidgetFeatures (Deprecated) The dock widget can be closed, moved,
+ and floated. Since new features might be added in future
+ releases, the look and behavior of dock widgets might
+ change if you use this flag. Please specify individual
+ flags instead.
+ \value NoDockWidgetFeatures The dock widget cannot be closed, moved,
+ or floated.
+
+ \omitvalue DockWidgetFeatureMask
+ \omitvalue Reserved
+*/
+
+/*!
+ \property QDockWidget::windowTitle
+ \brief the dock widget title (caption)
+
+ By default, this property contains an empty string.
+*/
+
+/*!
+ Constructs a QDockWidget with parent \a parent and window flags \a
+ flags. The dock widget will be placed in the left dock widget
+ area.
+*/
+QDockWidget::QDockWidget(QWidget *parent, Qt::WindowFlags flags)
+ : QWidget(*new QDockWidgetPrivate, parent, flags)
+{
+ Q_D(QDockWidget);
+ d->init();
+}
+
+/*!
+ Constructs a QDockWidget with parent \a parent and window flags \a
+ flags. The dock widget will be placed in the left dock widget
+ area.
+
+ The window title is set to \a title. This title is used when the
+ QDockWidget is docked and undocked. It is also used in the context
+ menu provided by QMainWindow.
+
+ \sa setWindowTitle()
+*/
+QDockWidget::QDockWidget(const QString &title, QWidget *parent, Qt::WindowFlags flags)
+ : QWidget(*new QDockWidgetPrivate, parent, flags)
+{
+ Q_D(QDockWidget);
+ d->init();
+ setWindowTitle(title);
+}
+
+/*!
+ Destroys the dock widget.
+*/
+QDockWidget::~QDockWidget()
+{ }
+
+/*!
+ Returns the widget for the dock widget. This function returns zero
+ if the widget has not been set.
+
+ \sa setWidget()
+*/
+QWidget *QDockWidget::widget() const
+{
+ QDockWidgetLayout *layout = qobject_cast<QDockWidgetLayout*>(this->layout());
+ return layout->widgetForRole(QDockWidgetLayout::Content);
+}
+
+/*!
+ Sets the widget for the dock widget to \a widget.
+
+ If the dock widget is visible when \a widget is added, you must
+ \l{QWidget::}{show()} it explicitly.
+
+ Note that you must add the layout of the \a widget before you call
+ this function; if not, the \a widget will not be visible.
+
+ \sa widget()
+*/
+void QDockWidget::setWidget(QWidget *widget)
+{
+ QDockWidgetLayout *layout = qobject_cast<QDockWidgetLayout*>(this->layout());
+ layout->setWidgetForRole(QDockWidgetLayout::Content, widget);
+}
+
+/*!
+ \property QDockWidget::features
+ \brief whether the dock widget is movable, closable, and floatable
+
+ By default, this property is set to a combination of DockWidgetClosable,
+ DockWidgetMovable and DockWidgetFloatable.
+
+ \sa DockWidgetFeature
+*/
+
+void QDockWidget::setFeatures(QDockWidget::DockWidgetFeatures features)
+{
+ Q_D(QDockWidget);
+ features &= DockWidgetFeatureMask;
+ if (d->features == features)
+ return;
+ const bool closableChanged = (d->features ^ features) & DockWidgetClosable;
+ d->features = features;
+ QDockWidgetLayout *layout
+ = qobject_cast<QDockWidgetLayout*>(this->layout());
+ layout->setVerticalTitleBar(features & DockWidgetVerticalTitleBar);
+ d->updateButtons();
+ d->toggleViewAction->setEnabled((d->features & DockWidgetClosable) == DockWidgetClosable);
+ emit featuresChanged(d->features);
+ update();
+ if (closableChanged && layout->nativeWindowDeco()) {
+ //this ensures the native decoration is drawn
+ d->setWindowState(true /*floating*/, true /*unplug*/);
+ }
+}
+
+QDockWidget::DockWidgetFeatures QDockWidget::features() const
+{
+ Q_D(const QDockWidget);
+ return d->features;
+}
+
+/*!
+ \property QDockWidget::floating
+ \brief whether the dock widget is floating
+
+ A floating dock widget is presented to the user as an independent
+ window "on top" of its parent QMainWindow, instead of being
+ docked in the QMainWindow.
+
+ By default, this property is true.
+
+ \sa isWindow()
+*/
+void QDockWidget::setFloating(bool floating)
+{
+ Q_D(QDockWidget);
+
+ // the initial click of a double-click may have started a drag...
+ if (d->state != 0)
+ d->endDrag(true);
+
+ QRect r = d->undockedGeometry;
+
+ d->setWindowState(floating, false, floating ? r : QRect());
+
+ if (floating && r.isNull()) {
+ if (x() < 0 || y() < 0) //may happen if we have been hidden
+ move(QPoint());
+ setAttribute(Qt::WA_Moved, false); //we want it at the default position
+ }
+}
+
+/*!
+ \property QDockWidget::allowedAreas
+ \brief areas where the dock widget may be placed
+
+ The default is Qt::AllDockWidgetAreas.
+
+ \sa Qt::DockWidgetArea
+*/
+
+void QDockWidget::setAllowedAreas(Qt::DockWidgetAreas areas)
+{
+ Q_D(QDockWidget);
+ areas &= Qt::DockWidgetArea_Mask;
+ if (areas == d->allowedAreas)
+ return;
+ d->allowedAreas = areas;
+ emit allowedAreasChanged(d->allowedAreas);
+}
+
+Qt::DockWidgetAreas QDockWidget::allowedAreas() const
+{
+ Q_D(const QDockWidget);
+ return d->allowedAreas;
+}
+
+/*!
+ \fn bool QDockWidget::isAreaAllowed(Qt::DockWidgetArea area) const
+
+ Returns true if this dock widget can be placed in the given \a area;
+ otherwise returns false.
+*/
+
+/*! \reimp */
+void QDockWidget::changeEvent(QEvent *event)
+{
+ Q_D(QDockWidget);
+ QDockWidgetLayout *layout = qobject_cast<QDockWidgetLayout*>(this->layout());
+
+ switch (event->type()) {
+ case QEvent::ModifiedChange:
+ case QEvent::WindowTitleChange:
+ update(layout->titleArea());
+#ifndef QT_NO_ACTION
+ d->fixedWindowTitle = qt_setWindowTitle_helperHelper(windowTitle(), this);
+ d->toggleViewAction->setText(d->fixedWindowTitle);
+#endif
+#ifndef QT_NO_TABBAR
+ {
+ QMainWindow *win = qobject_cast<QMainWindow*>(parentWidget());
+ if (QMainWindowLayout *winLayout = qt_mainwindow_layout(win)) {
+ if (QDockAreaLayoutInfo *info = winLayout->layoutState.dockAreaLayout.info(this))
+ info->updateTabBar();
+ }
+ }
+#endif // QT_NO_TABBAR
+ break;
+ default:
+ break;
+ }
+ QWidget::changeEvent(event);
+}
+
+/*! \reimp */
+void QDockWidget::closeEvent(QCloseEvent *event)
+{
+ Q_D(QDockWidget);
+ if (d->state)
+ d->endDrag(true);
+ QWidget::closeEvent(event);
+}
+
+/*! \reimp */
+void QDockWidget::paintEvent(QPaintEvent *event)
+{
+ Q_UNUSED(event)
+
+ QDockWidgetLayout *layout
+ = qobject_cast<QDockWidgetLayout*>(this->layout());
+ bool customTitleBar = layout->widgetForRole(QDockWidgetLayout::TitleBar) != 0;
+ bool nativeDeco = layout->nativeWindowDeco();
+
+ if (!nativeDeco && !customTitleBar) {
+ QStylePainter p(this);
+ // ### Add PixelMetric to change spacers, so style may show border
+ // when not floating.
+ if (isFloating()) {
+ QStyleOptionFrame framOpt;
+ framOpt.init(this);
+ p.drawPrimitive(QStyle::PE_FrameDockWidget, framOpt);
+ }
+
+ // Title must be painted after the frame, since the areas overlap, and
+ // the title may wish to extend out to all sides (eg. XP style)
+ QStyleOptionDockWidgetV2 titleOpt;
+ initStyleOption(&titleOpt);
+ p.drawControl(QStyle::CE_DockWidgetTitle, titleOpt);
+ }
+}
+
+/*! \reimp */
+bool QDockWidget::event(QEvent *event)
+{
+ Q_D(QDockWidget);
+
+ QMainWindow *win = qobject_cast<QMainWindow*>(parentWidget());
+ QMainWindowLayout *layout = qt_mainwindow_layout(win);
+
+ switch (event->type()) {
+#ifndef QT_NO_ACTION
+ case QEvent::Hide:
+ if (layout != 0)
+ layout->keepSize(this);
+ d->toggleViewAction->setChecked(false);
+ emit visibilityChanged(false);
+ break;
+ case QEvent::Show:
+ d->toggleViewAction->setChecked(true);
+ emit visibilityChanged(geometry().right() >= 0 && geometry().bottom() >= 0);
+ break;
+#endif
+ case QEvent::ApplicationLayoutDirectionChange:
+ case QEvent::LayoutDirectionChange:
+ case QEvent::StyleChange:
+ case QEvent::ParentChange:
+ d->updateButtons();
+ break;
+ case QEvent::ZOrderChange: {
+ bool onTop = false;
+ if (win != 0) {
+ const QObjectList &siblings = win->children();
+ onTop = siblings.count() > 0 && siblings.last() == (QObject*)this;
+ }
+ if (!isFloating() && layout != 0 && onTop)
+ layout->raise(this);
+ break;
+ }
+ case QEvent::WindowActivate:
+ case QEvent::WindowDeactivate:
+ update(qobject_cast<QDockWidgetLayout *>(this->layout())->titleArea());
+ break;
+ case QEvent::ContextMenu:
+ if (d->state) {
+ event->accept();
+ return true;
+ }
+ break;
+ // return true after calling the handler since we don't want
+ // them to be passed onto the default handlers
+ case QEvent::MouseButtonPress:
+ if (d->mousePressEvent(static_cast<QMouseEvent *>(event)))
+ return true;
+ break;
+ case QEvent::MouseButtonDblClick:
+ if (d->mouseDoubleClickEvent(static_cast<QMouseEvent *>(event)))
+ return true;
+ break;
+ case QEvent::MouseMove:
+ if (d->mouseMoveEvent(static_cast<QMouseEvent *>(event)))
+ return true;
+ break;
+#ifdef Q_WS_WIN
+ case QEvent::Leave:
+ if (d->state != 0 && d->state->dragging && !d->state->nca) {
+ // This is a workaround for loosing the mouse on Vista.
+ QPoint pos = QCursor::pos();
+ QMouseEvent fake(QEvent::MouseMove, mapFromGlobal(pos), pos, Qt::NoButton,
+ QApplication::mouseButtons(), QApplication::keyboardModifiers());
+ d->mouseMoveEvent(&fake);
+ }
+ break;
+#endif
+ case QEvent::MouseButtonRelease:
+ if (d->mouseReleaseEvent(static_cast<QMouseEvent *>(event)))
+ return true;
+ break;
+ case QEvent::NonClientAreaMouseMove:
+ case QEvent::NonClientAreaMouseButtonPress:
+ case QEvent::NonClientAreaMouseButtonRelease:
+ case QEvent::NonClientAreaMouseButtonDblClick:
+ d->nonClientAreaMouseEvent(static_cast<QMouseEvent*>(event));
+ return true;
+ case QEvent::Move:
+ d->moveEvent(static_cast<QMoveEvent*>(event));
+ break;
+ case QEvent::Resize:
+ // if the mainwindow is plugging us, we don't want to update undocked geometry
+ if (isFloating() && layout != 0 && layout->pluggingWidget != this)
+ d->undockedGeometry = geometry();
+ break;
+ default:
+ break;
+ }
+ return QWidget::event(event);
+}
+
+#ifndef QT_NO_ACTION
+/*!
+ Returns a checkable action that can be used to show or close this
+ dock widget.
+
+ The action's text is set to the dock widget's window title.
+
+ \sa QAction::text QWidget::windowTitle
+ */
+QAction * QDockWidget::toggleViewAction() const
+{
+ Q_D(const QDockWidget);
+ return d->toggleViewAction;
+}
+#endif // QT_NO_ACTION
+
+/*!
+ \fn void QDockWidget::featuresChanged(QDockWidget::DockWidgetFeatures features)
+
+ This signal is emitted when the \l features property changes. The
+ \a features parameter gives the new value of the property.
+*/
+
+/*!
+ \fn void QDockWidget::topLevelChanged(bool topLevel)
+
+ This signal is emitted when the \l floating property changes.
+ The \a topLevel parameter is true if the dock widget is now floating;
+ otherwise it is false.
+
+ \sa isWindow()
+*/
+
+/*!
+ \fn void QDockWidget::allowedAreasChanged(Qt::DockWidgetAreas allowedAreas)
+
+ This signal is emitted when the \l allowedAreas property changes. The
+ \a allowedAreas parameter gives the new value of the property.
+*/
+
+/*!
+ \fn void QDockWidget::visibilityChanged(bool visible)
+ \since 4.3
+
+ This signal is emitted when the dock widget becomes \a visible (or
+ invisible). This happens when the widget is hidden or shown, as
+ well as when it is docked in a tabbed dock area and its tab
+ becomes selected or unselected.
+*/
+
+/*!
+ \fn void QDockWidget::dockLocationChanged(Qt::DockWidgetArea area)
+ \since 4.3
+
+ This signal is emitted when the dock widget is moved to another
+ dock \a area, or is moved to a different location in its current
+ dock area. This happens when the dock widget is moved
+ programmatically or is dragged to a new location by the user.
+*/
+
+/*!
+ \since 4.3
+
+ Sets an arbitrary \a widget as the dock widget's title bar. If \a widget
+ is 0, any custom title bar widget previously set on the dock widget is
+ removed, but not deleted, and the default title bar will be used
+ instead.
+
+ If a title bar widget is set, QDockWidget will not use native window
+ decorations when it is floated.
+
+ Here are some tips for implementing custom title bars:
+
+ \list
+ \o Mouse events that are not explicitly handled by the title bar widget
+ must be ignored by calling QMouseEvent::ignore(). These events then
+ propagate to the QDockWidget parent, which handles them in the usual
+ manner, moving when the title bar is dragged, docking and undocking
+ when it is double-clicked, etc.
+
+ \o When DockWidgetVerticalTitleBar is set on QDockWidget, the title
+ bar widget is repositioned accordingly. In resizeEvent(), the title
+ bar should check what orientation it should assume:
+ \snippet doc/src/snippets/code/src_gui_widgets_qdockwidget.cpp 0
+
+ \o The title bar widget must have a valid QWidget::sizeHint() and
+ QWidget::minimumSizeHint(). These functions should take into account
+ the current orientation of the title bar.
+
+ \o It is not possible to remove a title bar from a dock widget. However,
+ a similar effect can be achieved by setting a default constructed
+ QWidget as the title bar widget.
+ \endlist
+
+ Using qobject_cast() as shown above, the title bar widget has full access
+ to its parent QDockWidget. Hence it can perform such operations as docking
+ and hiding in response to user actions.
+
+ \sa titleBarWidget() DockWidgetVerticalTitleBar
+*/
+
+void QDockWidget::setTitleBarWidget(QWidget *widget)
+{
+ Q_D(QDockWidget);
+ QDockWidgetLayout *layout
+ = qobject_cast<QDockWidgetLayout*>(this->layout());
+ layout->setWidgetForRole(QDockWidgetLayout::TitleBar, widget);
+ d->updateButtons();
+ if (isWindow()) {
+ //this ensures the native decoration is drawn
+ d->setWindowState(true /*floating*/, true /*unplug*/);
+ }
+}
+
+/*!
+ \since 4.3
+ Returns the custom title bar widget set on the QDockWidget, or 0 if no
+ custom title bar has been set.
+
+ \sa setTitleBarWidget()
+*/
+
+QWidget *QDockWidget::titleBarWidget() const
+{
+ QDockWidgetLayout *layout
+ = qobject_cast<QDockWidgetLayout*>(this->layout());
+ return layout->widgetForRole(QDockWidgetLayout::TitleBar);
+}
+
+QT_END_NAMESPACE
+
+#include "qdockwidget.moc"
+#include "moc_qdockwidget.cpp"
+
+#endif // QT_NO_DOCKWIDGET
diff --git a/src/widgets/widgets/qdockwidget.h b/src/widgets/widgets/qdockwidget.h
new file mode 100644
index 0000000000..cc81db2fc2
--- /dev/null
+++ b/src/widgets/widgets/qdockwidget.h
@@ -0,0 +1,146 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDYNAMICDOCKWIDGET_H
+#define QDYNAMICDOCKWIDGET_H
+
+#include <QtWidgets/qwidget.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_DOCKWIDGET
+
+class QDockAreaLayout;
+class QDockWidgetPrivate;
+class QMainWindow;
+class QStyleOptionDockWidget;
+
+class Q_WIDGETS_EXPORT QDockWidget : public QWidget
+{
+ Q_OBJECT
+
+ Q_FLAGS(DockWidgetFeatures)
+ Q_PROPERTY(bool floating READ isFloating WRITE setFloating)
+ Q_PROPERTY(DockWidgetFeatures features READ features WRITE setFeatures NOTIFY featuresChanged)
+ Q_PROPERTY(Qt::DockWidgetAreas allowedAreas READ allowedAreas
+ WRITE setAllowedAreas NOTIFY allowedAreasChanged)
+ Q_PROPERTY(QString windowTitle READ windowTitle WRITE setWindowTitle DESIGNABLE true)
+
+public:
+ explicit QDockWidget(const QString &title, QWidget *parent = 0, Qt::WindowFlags flags = 0);
+ explicit QDockWidget(QWidget *parent = 0, Qt::WindowFlags flags = 0);
+ ~QDockWidget();
+
+ QWidget *widget() const;
+ void setWidget(QWidget *widget);
+
+ enum DockWidgetFeature {
+ DockWidgetClosable = 0x01,
+ DockWidgetMovable = 0x02,
+ DockWidgetFloatable = 0x04,
+ DockWidgetVerticalTitleBar = 0x08,
+
+ DockWidgetFeatureMask = 0x0f,
+ AllDockWidgetFeatures = DockWidgetClosable|DockWidgetMovable|DockWidgetFloatable, // ### remove in 5.0
+ NoDockWidgetFeatures = 0x00,
+
+ Reserved = 0xff
+ };
+ Q_DECLARE_FLAGS(DockWidgetFeatures, DockWidgetFeature)
+
+ void setFeatures(DockWidgetFeatures features);
+ DockWidgetFeatures features() const;
+
+ void setFloating(bool floating);
+ inline bool isFloating() const { return isWindow(); }
+
+ void setAllowedAreas(Qt::DockWidgetAreas areas);
+ Qt::DockWidgetAreas allowedAreas() const;
+
+ void setTitleBarWidget(QWidget *widget);
+ QWidget *titleBarWidget() const;
+
+ inline bool isAreaAllowed(Qt::DockWidgetArea area) const
+ { return (allowedAreas() & area) == area; }
+
+#ifndef QT_NO_ACTION
+ QAction *toggleViewAction() const;
+#endif
+
+Q_SIGNALS:
+ void featuresChanged(QDockWidget::DockWidgetFeatures features);
+ void topLevelChanged(bool topLevel);
+ void allowedAreasChanged(Qt::DockWidgetAreas allowedAreas);
+ void visibilityChanged(bool visible);
+ void dockLocationChanged(Qt::DockWidgetArea area);
+
+protected:
+ void changeEvent(QEvent *event);
+ void closeEvent(QCloseEvent *event);
+ void paintEvent(QPaintEvent *event);
+ bool event(QEvent *event);
+ void initStyleOption(QStyleOptionDockWidget *option) const;
+
+private:
+ Q_DECLARE_PRIVATE(QDockWidget)
+ Q_DISABLE_COPY(QDockWidget)
+ Q_PRIVATE_SLOT(d_func(), void _q_toggleView(bool))
+ Q_PRIVATE_SLOT(d_func(), void _q_toggleTopLevel())
+ friend class QDockAreaLayout;
+ friend class QDockWidgetItem;
+ friend class QMainWindowLayout;
+ friend class QDockWidgetLayout;
+ friend class QDockAreaLayoutInfo;
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QDockWidget::DockWidgetFeatures)
+
+#endif // QT_NO_DOCKWIDGET
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QDYNAMICDOCKWIDGET_H
diff --git a/src/widgets/widgets/qdockwidget_p.h b/src/widgets/widgets/qdockwidget_p.h
new file mode 100644
index 0000000000..4d3c4f4d70
--- /dev/null
+++ b/src/widgets/widgets/qdockwidget_p.h
@@ -0,0 +1,207 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDYNAMICDOCKWIDGET_P_H
+#define QDYNAMICDOCKWIDGET_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "QtWidgets/qstyleoption.h"
+#include "private/qwidget_p.h"
+#include "QtWidgets/qboxlayout.h"
+#include "QtWidgets/qdockwidget.h"
+
+#ifndef QT_NO_DOCKWIDGET
+
+QT_BEGIN_NAMESPACE
+
+class QGridLayout;
+class QWidgetResizeHandler;
+class QRubberBand;
+class QDockWidgetTitleButton;
+class QSpacerItem;
+class QDockWidgetItem;
+
+class QDockWidgetPrivate : public QWidgetPrivate
+{
+ Q_DECLARE_PUBLIC(QDockWidget)
+
+ struct DragState {
+ QPoint pressPos;
+ bool dragging;
+ QLayoutItem *widgetItem;
+ bool ownWidgetItem;
+ bool nca;
+ bool ctrlDrag;
+ };
+
+public:
+ inline QDockWidgetPrivate()
+ : QWidgetPrivate(), state(0),
+ features(QDockWidget::DockWidgetClosable
+ | QDockWidget::DockWidgetMovable
+ | QDockWidget::DockWidgetFloatable),
+ allowedAreas(Qt::AllDockWidgetAreas)
+ { }
+
+ void init();
+ void _q_toggleView(bool); // private slot
+ void _q_toggleTopLevel(); // private slot
+
+ void updateButtons();
+ DragState *state;
+
+ QDockWidget::DockWidgetFeatures features;
+ Qt::DockWidgetAreas allowedAreas;
+
+ QWidgetResizeHandler *resizer;
+
+#ifndef QT_NO_ACTION
+ QAction *toggleViewAction;
+#endif
+
+// QMainWindow *findMainWindow(QWidget *widget) const;
+ QRect undockedGeometry;
+ QString fixedWindowTitle;
+
+ bool mousePressEvent(QMouseEvent *event);
+ bool mouseDoubleClickEvent(QMouseEvent *event);
+ bool mouseMoveEvent(QMouseEvent *event);
+ bool mouseReleaseEvent(QMouseEvent *event);
+ void setWindowState(bool floating, bool unplug = false, const QRect &rect = QRect());
+ void nonClientAreaMouseEvent(QMouseEvent *event);
+ void initDrag(const QPoint &pos, bool nca);
+ void startDrag();
+ void endDrag(bool abort = false);
+ void moveEvent(QMoveEvent *event);
+
+ void unplug(const QRect &rect);
+ void plug(const QRect &rect);
+
+ bool isAnimating() const;
+};
+
+class Q_WIDGETS_EXPORT QDockWidgetLayout : public QLayout
+{
+ Q_OBJECT
+public:
+ QDockWidgetLayout(QWidget *parent = 0);
+ ~QDockWidgetLayout();
+ void addItem(QLayoutItem *item);
+ QLayoutItem *itemAt(int index) const;
+ QLayoutItem *takeAt(int index);
+ int count() const;
+
+ QSize maximumSize() const;
+ QSize minimumSize() const;
+ QSize sizeHint() const;
+
+ QSize sizeFromContent(const QSize &content, bool floating) const;
+
+ void setGeometry(const QRect &r);
+
+ enum Role { Content, CloseButton, FloatButton, TitleBar, RoleCount };
+ QWidget *widgetForRole(Role r) const;
+ void setWidgetForRole(Role r, QWidget *w);
+ QLayoutItem *itemForRole(Role r) const;
+
+ QRect titleArea() const { return _titleArea; }
+
+ int minimumTitleWidth() const;
+ int titleHeight() const;
+ void updateMaxSize();
+ bool nativeWindowDeco() const;
+ bool nativeWindowDeco(bool floating) const;
+
+ void setVerticalTitleBar(bool b);
+
+ bool verticalTitleBar;
+
+private:
+ QVector<QLayoutItem*> item_list;
+ QRect _titleArea;
+};
+
+/* The size hints of a QDockWidget will depend on whether it is docked or not.
+ This layout item always returns the size hints as if the dock widget was docked. */
+
+class QDockWidgetItem : public QWidgetItem
+{
+public:
+ QDockWidgetItem(QDockWidget *dockWidget);
+ QSize minimumSize() const;
+ QSize maximumSize() const;
+ QSize sizeHint() const;
+
+private:
+ inline QLayoutItem *dockWidgetChildItem() const;
+ inline QDockWidgetLayout *dockWidgetLayout() const;
+};
+
+inline QLayoutItem *QDockWidgetItem::dockWidgetChildItem() const
+{
+ if (QDockWidgetLayout *layout = dockWidgetLayout())
+ return layout->itemForRole(QDockWidgetLayout::Content);
+ return 0;
+}
+
+inline QDockWidgetLayout *QDockWidgetItem::dockWidgetLayout() const
+{
+ QWidget *w = const_cast<QDockWidgetItem*>(this)->widget();
+ if (w != 0)
+ return qobject_cast<QDockWidgetLayout*>(w->layout());
+ return 0;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_DOCKWIDGET
+
+#endif // QDYNAMICDOCKWIDGET_P_H
diff --git a/src/gui/widgets/qeffects.cpp b/src/widgets/widgets/qeffects.cpp
index adf1cc1f87..adf1cc1f87 100644
--- a/src/gui/widgets/qeffects.cpp
+++ b/src/widgets/widgets/qeffects.cpp
diff --git a/src/widgets/widgets/qeffects_p.h b/src/widgets/widgets/qeffects_p.h
new file mode 100644
index 0000000000..bae2bbf54a
--- /dev/null
+++ b/src/widgets/widgets/qeffects_p.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QEFFECTS_P_H
+#define QEFFECTS_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of qeffects.cpp, qcombobox.cpp, qpopupmenu.cpp and qtooltip.cpp.
+// This header file may change from version to version without notice,
+// or even be removed.
+//
+// We mean it.
+//
+
+#include "QtCore/qnamespace.h"
+
+#ifndef QT_NO_EFFECTS
+
+QT_BEGIN_NAMESPACE
+
+class QWidget;
+
+struct QEffects
+{
+ enum Direction {
+ LeftScroll = 0x0001,
+ RightScroll = 0x0002,
+ UpScroll = 0x0004,
+ DownScroll = 0x0008
+ };
+
+ typedef uint DirFlags;
+};
+
+extern void Q_WIDGETS_EXPORT qScrollEffect(QWidget*, QEffects::DirFlags dir = QEffects::DownScroll, int time = -1);
+extern void Q_WIDGETS_EXPORT qFadeEffect(QWidget*, int time = -1);
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_EFFECTS
+
+#endif // QEFFECTS_P_H
diff --git a/src/gui/widgets/qfocusframe.cpp b/src/widgets/widgets/qfocusframe.cpp
index b41a71ab54..b41a71ab54 100644
--- a/src/gui/widgets/qfocusframe.cpp
+++ b/src/widgets/widgets/qfocusframe.cpp
diff --git a/src/widgets/widgets/qfocusframe.h b/src/widgets/widgets/qfocusframe.h
new file mode 100644
index 0000000000..f4f1d1c854
--- /dev/null
+++ b/src/widgets/widgets/qfocusframe.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QFOCUSFRAME_H
+#define QFOCUSFRAME_H
+
+#include <QtWidgets/qwidget.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QFocusFramePrivate;
+class QStyleOption;
+
+class Q_WIDGETS_EXPORT QFocusFrame : public QWidget
+{
+ Q_OBJECT
+public:
+ QFocusFrame(QWidget *parent=0);
+ ~QFocusFrame();
+
+ void setWidget(QWidget *widget);
+ QWidget *widget() const;
+
+protected:
+ bool event(QEvent *e);
+
+ bool eventFilter(QObject *, QEvent *);
+ void paintEvent(QPaintEvent *);
+ void initStyleOption(QStyleOption *option) const;
+
+private:
+ Q_DECLARE_PRIVATE(QFocusFrame)
+ Q_DISABLE_COPY(QFocusFrame)
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QFOCUSFRAME_H
diff --git a/src/gui/widgets/qfontcombobox.cpp b/src/widgets/widgets/qfontcombobox.cpp
index bd53410f31..bd53410f31 100644
--- a/src/gui/widgets/qfontcombobox.cpp
+++ b/src/widgets/widgets/qfontcombobox.cpp
diff --git a/src/widgets/widgets/qfontcombobox.h b/src/widgets/widgets/qfontcombobox.h
new file mode 100644
index 0000000000..b0007207da
--- /dev/null
+++ b/src/widgets/widgets/qfontcombobox.h
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QFONTCOMBOBOX_H
+#define QFONTCOMBOBOX_H
+
+#include <QtWidgets/qcombobox.h>
+#include <QtGui/qfontdatabase.h>
+
+#ifndef QT_NO_FONTCOMBOBOX
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QFontComboBoxPrivate;
+
+class Q_WIDGETS_EXPORT QFontComboBox : public QComboBox
+{
+ Q_OBJECT
+ Q_FLAGS(FontFilters)
+ Q_PROPERTY(QFontDatabase::WritingSystem writingSystem READ writingSystem WRITE setWritingSystem)
+ Q_PROPERTY(FontFilters fontFilters READ fontFilters WRITE setFontFilters)
+ Q_PROPERTY(QFont currentFont READ currentFont WRITE setCurrentFont NOTIFY currentFontChanged)
+ Q_ENUMS(FontSelection)
+
+public:
+ explicit QFontComboBox(QWidget *parent = 0);
+ ~QFontComboBox();
+
+ void setWritingSystem(QFontDatabase::WritingSystem);
+ QFontDatabase::WritingSystem writingSystem() const;
+
+ enum FontFilter {
+ AllFonts = 0,
+ ScalableFonts = 0x1,
+ NonScalableFonts = 0x2,
+ MonospacedFonts = 0x4,
+ ProportionalFonts = 0x8
+ };
+ Q_DECLARE_FLAGS(FontFilters, FontFilter)
+
+ void setFontFilters(FontFilters filters);
+ FontFilters fontFilters() const;
+
+ QFont currentFont() const;
+ QSize sizeHint() const;
+
+public Q_SLOTS:
+ void setCurrentFont(const QFont &f);
+
+Q_SIGNALS:
+ void currentFontChanged(const QFont &f);
+
+protected:
+ bool event(QEvent *e);
+
+private:
+ Q_DISABLE_COPY(QFontComboBox)
+ Q_DECLARE_PRIVATE(QFontComboBox)
+ Q_PRIVATE_SLOT(d_func(), void _q_currentChanged(const QString &))
+ Q_PRIVATE_SLOT(d_func(), void _q_updateModel())
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QFontComboBox::FontFilters)
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QT_NO_FONTCOMBOBOX
+#endif
diff --git a/src/gui/widgets/qframe.cpp b/src/widgets/widgets/qframe.cpp
index 083136f9fe..083136f9fe 100644
--- a/src/gui/widgets/qframe.cpp
+++ b/src/widgets/widgets/qframe.cpp
diff --git a/src/widgets/widgets/qframe.h b/src/widgets/widgets/qframe.h
new file mode 100644
index 0000000000..80d41365cd
--- /dev/null
+++ b/src/widgets/widgets/qframe.h
@@ -0,0 +1,148 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QFRAME_H
+#define QFRAME_H
+
+#include <QtWidgets/qwidget.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QFramePrivate;
+
+class Q_WIDGETS_EXPORT QFrame : public QWidget
+{
+ Q_OBJECT
+
+ Q_ENUMS(Shape Shadow)
+ Q_PROPERTY(Shape frameShape READ frameShape WRITE setFrameShape)
+ Q_PROPERTY(Shadow frameShadow READ frameShadow WRITE setFrameShadow)
+ Q_PROPERTY(int lineWidth READ lineWidth WRITE setLineWidth)
+ Q_PROPERTY(int midLineWidth READ midLineWidth WRITE setMidLineWidth)
+ Q_PROPERTY(int frameWidth READ frameWidth)
+ Q_PROPERTY(QRect frameRect READ frameRect WRITE setFrameRect DESIGNABLE false)
+
+public:
+ explicit QFrame(QWidget* parent = 0, Qt::WindowFlags f = 0);
+ ~QFrame();
+
+ int frameStyle() const;
+ void setFrameStyle(int);
+
+ int frameWidth() const;
+
+ QSize sizeHint() const;
+
+ enum Shape {
+ NoFrame = 0, // no frame
+ Box = 0x0001, // rectangular box
+ Panel = 0x0002, // rectangular panel
+ WinPanel = 0x0003, // rectangular panel (Windows)
+ HLine = 0x0004, // horizontal line
+ VLine = 0x0005, // vertical line
+ StyledPanel = 0x0006 // rectangular panel depending on the GUI style
+
+#if defined(QT3_SUPPORT) && !defined(Q_MOC_RUN)
+ ,PopupPanel = StyledPanel, // rectangular panel depending on the GUI style
+ MenuBarPanel = StyledPanel,
+ ToolBarPanel = StyledPanel,
+ LineEditPanel = StyledPanel,
+ TabWidgetPanel = StyledPanel,
+ GroupBoxPanel = StyledPanel
+#endif
+ };
+ enum Shadow {
+ Plain = 0x0010, // plain line
+ Raised = 0x0020, // raised shadow effect
+ Sunken = 0x0030 // sunken shadow effect
+ };
+
+ enum StyleMask {
+ Shadow_Mask = 0x00f0, // mask for the shadow
+ Shape_Mask = 0x000f // mask for the shape
+#if defined(QT3_SUPPORT)
+ ,MShadow = Shadow_Mask,
+ MShape = Shape_Mask
+#endif
+ };
+
+ Shape frameShape() const;
+ void setFrameShape(Shape);
+ Shadow frameShadow() const;
+ void setFrameShadow(Shadow);
+
+ int lineWidth() const;
+ void setLineWidth(int);
+
+ int midLineWidth() const;
+ void setMidLineWidth(int);
+
+ QRect frameRect() const;
+ void setFrameRect(const QRect &);
+
+protected:
+ bool event(QEvent *e);
+ void paintEvent(QPaintEvent *);
+ void changeEvent(QEvent *);
+ void drawFrame(QPainter *);
+
+#ifdef QT3_SUPPORT
+public:
+ QT3_SUPPORT_CONSTRUCTOR QFrame(QWidget* parent, const char* name, Qt::WindowFlags f = 0);
+#endif
+
+protected:
+ QFrame(QFramePrivate &dd, QWidget* parent = 0, Qt::WindowFlags f = 0);
+
+private:
+ Q_DISABLE_COPY(QFrame)
+ Q_DECLARE_PRIVATE(QFrame)
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QFRAME_H
diff --git a/src/gui/widgets/qframe_p.h b/src/widgets/widgets/qframe_p.h
index 8825abaf92..8825abaf92 100644
--- a/src/gui/widgets/qframe_p.h
+++ b/src/widgets/widgets/qframe_p.h
diff --git a/src/gui/widgets/qgroupbox.cpp b/src/widgets/widgets/qgroupbox.cpp
index 56fb2dd412..56fb2dd412 100644
--- a/src/gui/widgets/qgroupbox.cpp
+++ b/src/widgets/widgets/qgroupbox.cpp
diff --git a/src/widgets/widgets/qgroupbox.h b/src/widgets/widgets/qgroupbox.h
new file mode 100644
index 0000000000..fba094d303
--- /dev/null
+++ b/src/widgets/widgets/qgroupbox.h
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGROUPBOX_H
+#define QGROUPBOX_H
+
+#include <QtWidgets/qframe.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_GROUPBOX
+
+class QGroupBoxPrivate;
+class QStyleOptionGroupBox;
+class Q_WIDGETS_EXPORT QGroupBox : public QWidget
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QString title READ title WRITE setTitle)
+ Q_PROPERTY(Qt::Alignment alignment READ alignment WRITE setAlignment)
+ Q_PROPERTY(bool flat READ isFlat WRITE setFlat)
+ Q_PROPERTY(bool checkable READ isCheckable WRITE setCheckable)
+ Q_PROPERTY(bool checked READ isChecked WRITE setChecked DESIGNABLE isCheckable NOTIFY toggled USER true)
+public:
+ explicit QGroupBox(QWidget* parent=0);
+ explicit QGroupBox(const QString &title, QWidget* parent=0);
+ ~QGroupBox();
+
+ QString title() const;
+ void setTitle(const QString &title);
+
+ Qt::Alignment alignment() const;
+ void setAlignment(int alignment);
+
+ QSize minimumSizeHint() const;
+
+ bool isFlat() const;
+ void setFlat(bool flat);
+ bool isCheckable() const;
+ void setCheckable(bool checkable);
+ bool isChecked() const;
+
+public Q_SLOTS:
+ void setChecked(bool checked);
+
+Q_SIGNALS:
+ void clicked(bool checked = false);
+ void toggled(bool);
+
+protected:
+ bool event(QEvent *event);
+ void childEvent(QChildEvent *event);
+ void resizeEvent(QResizeEvent *event);
+ void paintEvent(QPaintEvent *event);
+ void focusInEvent(QFocusEvent *event);
+ void changeEvent(QEvent *event);
+ void mousePressEvent(QMouseEvent *event);
+ void mouseMoveEvent(QMouseEvent *event);
+ void mouseReleaseEvent(QMouseEvent *event);
+ void initStyleOption(QStyleOptionGroupBox *option) const;
+
+#ifdef QT3_SUPPORT
+public:
+ QT3_SUPPORT_CONSTRUCTOR QGroupBox(QWidget* parent, const char* name);
+ QT3_SUPPORT_CONSTRUCTOR QGroupBox(const QString &title, QWidget* parent, const char* name);
+#endif
+
+private:
+ Q_DISABLE_COPY(QGroupBox)
+ Q_DECLARE_PRIVATE(QGroupBox)
+ Q_PRIVATE_SLOT(d_func(), void _q_setChildrenEnabled(bool b))
+};
+
+#endif // QT_NO_GROUPBOX
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QGROUPBOX_H
diff --git a/src/widgets/widgets/qlabel.cpp b/src/widgets/widgets/qlabel.cpp
new file mode 100644
index 0000000000..b122632e44
--- /dev/null
+++ b/src/widgets/widgets/qlabel.cpp
@@ -0,0 +1,1734 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qpainter.h"
+#include "qevent.h"
+#include "qdrawutil.h"
+#include "qapplication.h"
+#include "qabstractbutton.h"
+#include "qstyle.h"
+#include "qstyleoption.h"
+#include <limits.h>
+#include "qaction.h"
+#include "qclipboard.h"
+#include <qdebug.h>
+#include <qurl.h>
+#include "qlabel_p.h"
+#include "private/qstylesheetstyle_p.h"
+#include <qmath.h>
+
+#ifndef QT_NO_ACCESSIBILITY
+#include <qaccessible.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QLabel
+ \brief The QLabel widget provides a text or image display.
+
+ \ingroup basicwidgets
+
+ QLabel is used for displaying text or an image. No user
+ interaction functionality is provided. The visual appearance of
+ the label can be configured in various ways, and it can be used
+ for specifying a focus mnemonic key for another widget.
+
+ A QLabel can contain any of the following content types:
+
+ \table
+ \header \o Content \o Setting
+ \row \o Plain text
+ \o Pass a QString to setText().
+ \row \o Rich text
+ \o Pass a QString that contains rich text to setText().
+ \row \o A pixmap
+ \o Pass a QPixmap to setPixmap().
+ \row \o A movie
+ \o Pass a QMovie to setMovie().
+ \row \o A number
+ \o Pass an \e int or a \e double to setNum(), which converts
+ the number to plain text.
+ \row \o Nothing
+ \o The same as an empty plain text. This is the default. Set
+ by clear().
+ \endtable
+
+ \warning When passing a QString to the constructor or calling setText(),
+ make sure to sanitize your input, as QLabel tries to guess whether it
+ displays the text as plain text or as rich text. You may want to call
+ setTextFormat() explicitly, e.g. in case you expect the text to be in
+ plain format but cannot control the text source (for instance when
+ displaying data loaded from the Web).
+
+ When the content is changed using any of these functions, any
+ previous content is cleared.
+
+ By default, labels display \l{alignment}{left-aligned, vertically-centered}
+ text and images, where any tabs in the text to be displayed are
+ \l{Qt::TextExpandTabs}{automatically expanded}. However, the look
+ of a QLabel can be adjusted and fine-tuned in several ways.
+
+ The positioning of the content within the QLabel widget area can
+ be tuned with setAlignment() and setIndent(). Text content can
+ also wrap lines along word boundaries with setWordWrap(). For
+ example, this code sets up a sunken panel with a two-line text in
+ the bottom right corner (both lines being flush with the right
+ side of the label):
+
+ \snippet doc/src/snippets/code/src_gui_widgets_qlabel.cpp 0
+
+ The properties and functions QLabel inherits from QFrame can also
+ be used to specify the widget frame to be used for any given label.
+
+ A QLabel is often used as a label for an interactive widget. For
+ this use QLabel provides a useful mechanism for adding an
+ mnemonic (see QKeySequence) that will set the keyboard focus to
+ the other widget (called the QLabel's "buddy"). For example:
+
+ \snippet doc/src/snippets/code/src_gui_widgets_qlabel.cpp 1
+
+ In this example, keyboard focus is transferred to the label's
+ buddy (the QLineEdit) when the user presses Alt+P. If the buddy
+ was a button (inheriting from QAbstractButton), triggering the
+ mnemonic would emulate a button click.
+
+ \table 100%
+ \row
+ \o \inlineimage macintosh-label.png Screenshot of a Macintosh style label
+ \o A label shown in the \l{Macintosh Style Widget Gallery}{Macintosh widget style}.
+ \row
+ \o \inlineimage plastique-label.png Screenshot of a Plastique style label
+ \o A label shown in the \l{Plastique Style Widget Gallery}{Plastique widget style}.
+ \row
+ \o \inlineimage windowsxp-label.png Screenshot of a Windows XP style label
+ \o A label shown in the \l{Windows XP Style Widget Gallery}{Windows XP widget style}.
+ \endtable
+
+ \sa QLineEdit, QTextEdit, QPixmap, QMovie,
+ {fowler}{GUI Design Handbook: Label}
+*/
+
+#ifndef QT_NO_PICTURE
+/*!
+ Returns the label's picture or 0 if the label doesn't have a
+ picture.
+*/
+
+const QPicture *QLabel::picture() const
+{
+ Q_D(const QLabel);
+ return d->picture;
+}
+#endif
+
+
+/*!
+ Constructs an empty label.
+
+ The \a parent and widget flag \a f, arguments are passed
+ to the QFrame constructor.
+
+ \sa setAlignment(), setFrameStyle(), setIndent()
+*/
+QLabel::QLabel(QWidget *parent, Qt::WindowFlags f)
+ : QFrame(*new QLabelPrivate(), parent, f)
+{
+ Q_D(QLabel);
+ d->init();
+}
+
+/*!
+ Constructs a label that displays the text, \a text.
+
+ The \a parent and widget flag \a f, arguments are passed
+ to the QFrame constructor.
+
+ \sa setText(), setAlignment(), setFrameStyle(), setIndent()
+*/
+QLabel::QLabel(const QString &text, QWidget *parent, Qt::WindowFlags f)
+ : QFrame(*new QLabelPrivate(), parent, f)
+{
+ Q_D(QLabel);
+ d->init();
+ setText(text);
+}
+
+
+#ifdef QT3_SUPPORT
+/*! \obsolete
+ Constructs an empty label.
+
+ The \a parent, \a name and widget flag \a f, arguments are passed
+ to the QFrame constructor.
+
+ \sa setAlignment(), setFrameStyle(), setIndent()
+*/
+
+QLabel::QLabel(QWidget *parent, const char *name, Qt::WindowFlags f)
+ : QFrame(*new QLabelPrivate(), parent, f)
+{
+ Q_D(QLabel);
+ if (name)
+ setObjectName(QString::fromAscii(name));
+ d->init();
+}
+
+
+/*! \obsolete
+ Constructs a label that displays the text, \a text.
+
+ The \a parent, \a name and widget flag \a f, arguments are passed
+ to the QFrame constructor.
+
+ \sa setText(), setAlignment(), setFrameStyle(), setIndent()
+*/
+
+QLabel::QLabel(const QString &text, QWidget *parent, const char *name,
+ Qt::WindowFlags f)
+ : QFrame(*new QLabelPrivate(), parent, f)
+{
+ Q_D(QLabel);
+ if (name)
+ setObjectName(QString::fromAscii(name));
+ d->init();
+ setText(text);
+}
+
+
+/*! \obsolete
+ Constructs a label that displays the text \a text. The label has a
+ buddy widget, \a buddy.
+
+ If the \a text contains an underlined letter (a letter preceded by
+ an ampersand, \&), when the user presses Alt+ the underlined letter,
+ focus is passed to the buddy widget.
+
+ The \a parent, \a name and widget flag, \a f, arguments are passed
+ to the QFrame constructor.
+
+ \sa setText(), setBuddy(), setAlignment(), setFrameStyle(),
+ setIndent()
+*/
+QLabel::QLabel(QWidget *buddy, const QString &text,
+ QWidget *parent, const char *name, Qt::WindowFlags f)
+ : QFrame(*new QLabelPrivate(), parent, f)
+{
+ Q_D(QLabel);
+ if (name)
+ setObjectName(QString::fromAscii(name));
+ d->init();
+#ifndef QT_NO_SHORTCUT
+ setBuddy(buddy);
+#endif
+ setText(text);
+}
+#endif //QT3_SUPPORT
+
+/*!
+ Destroys the label.
+*/
+
+QLabel::~QLabel()
+{
+ Q_D(QLabel);
+ d->clearContents();
+}
+
+void QLabelPrivate::init()
+{
+ Q_Q(QLabel);
+
+ valid_hints = false;
+ margin = 0;
+#ifndef QT_NO_MOVIE
+ movie = 0;
+#endif
+#ifndef QT_NO_SHORTCUT
+ shortcutId = 0;
+#endif
+ pixmap = 0;
+ scaledpixmap = 0;
+ cachedimage = 0;
+#ifndef QT_NO_PICTURE
+ picture = 0;
+#endif
+ align = Qt::AlignLeft | Qt::AlignVCenter | Qt::TextExpandTabs;
+ indent = -1;
+ scaledcontents = false;
+ textLayoutDirty = false;
+ textDirty = false;
+ textformat = Qt::AutoText;
+ control = 0;
+ textInteractionFlags = Qt::LinksAccessibleByMouse;
+ isRichText = false;
+ isTextLabel = false;
+
+ q->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred,
+ QSizePolicy::Label));
+
+#ifndef QT_NO_CURSOR
+ validCursor = false;
+ onAnchor = false;
+#endif
+
+ openExternalLinks = false;
+
+ setLayoutItemMargins(QStyle::SE_LabelLayoutItem);
+}
+
+
+/*!
+ \property QLabel::text
+ \brief the label's text
+
+ If no text has been set this will return an empty string. Setting
+ the text clears any previous content.
+
+ The text will be interpreted either as plain text or as rich
+ text, depending on the text format setting; see setTextFormat().
+ The default setting is Qt::AutoText; i.e. QLabel will try to
+ auto-detect the format of the text set.
+
+ If a buddy has been set, the buddy mnemonic key is updated
+ from the new text.
+
+ Note that QLabel is well-suited to display small rich text
+ documents, such as small documents that get their document
+ specific settings (font, text color, link color) from the label's
+ palette and font properties. For large documents, use QTextEdit
+ in read-only mode instead. QTextEdit can also provide a scroll bar
+ when necessary.
+
+ \note This function enables mouse tracking if \a text contains rich
+ text.
+
+ \sa setTextFormat(), setBuddy(), alignment
+*/
+
+void QLabel::setText(const QString &text)
+{
+ Q_D(QLabel);
+ if (d->text == text)
+ return;
+
+ QWidgetTextControl *oldControl = d->control;
+ d->control = 0;
+
+ d->clearContents();
+ d->text = text;
+ d->isTextLabel = true;
+ d->textDirty = true;
+ d->isRichText = d->textformat == Qt::RichText
+ || (d->textformat == Qt::AutoText && Qt::mightBeRichText(d->text));
+
+ d->control = oldControl;
+
+ if (d->needTextControl()) {
+ d->ensureTextControl();
+ } else {
+ delete d->control;
+ d->control = 0;
+ }
+
+ if (d->isRichText) {
+ setMouseTracking(true);
+ } else {
+ // Note: mouse tracking not disabled intentionally
+ }
+
+#ifndef QT_NO_SHORTCUT
+ if (d->buddy)
+ d->updateShortcut();
+#endif
+
+ d->updateLabel();
+
+#ifndef QT_NO_ACCESSIBILITY
+ if (accessibleName().isEmpty())
+ QAccessible::updateAccessibility(this, 0, QAccessible::NameChanged);
+#endif
+}
+
+QString QLabel::text() const
+{
+ Q_D(const QLabel);
+ return d->text;
+}
+
+/*!
+ Clears any label contents.
+*/
+
+void QLabel::clear()
+{
+ Q_D(QLabel);
+ d->clearContents();
+ d->updateLabel();
+}
+
+/*!
+ \property QLabel::pixmap
+ \brief the label's pixmap
+
+ If no pixmap has been set this will return 0.
+
+ Setting the pixmap clears any previous content. The buddy
+ shortcut, if any, is disabled.
+*/
+void QLabel::setPixmap(const QPixmap &pixmap)
+{
+ Q_D(QLabel);
+ if (!d->pixmap || d->pixmap->cacheKey() != pixmap.cacheKey()) {
+ d->clearContents();
+ d->pixmap = new QPixmap(pixmap);
+ }
+
+ if (d->pixmap->depth() == 1 && !d->pixmap->mask())
+ d->pixmap->setMask(*((QBitmap *)d->pixmap));
+
+ d->updateLabel();
+}
+
+const QPixmap *QLabel::pixmap() const
+{
+ Q_D(const QLabel);
+ return d->pixmap;
+}
+
+#ifndef QT_NO_PICTURE
+/*!
+ Sets the label contents to \a picture. Any previous content is
+ cleared.
+
+ The buddy shortcut, if any, is disabled.
+
+ \sa picture(), setBuddy()
+*/
+
+void QLabel::setPicture(const QPicture &picture)
+{
+ Q_D(QLabel);
+ d->clearContents();
+ d->picture = new QPicture(picture);
+
+ d->updateLabel();
+}
+#endif // QT_NO_PICTURE
+
+/*!
+ Sets the label contents to plain text containing the textual
+ representation of integer \a num. Any previous content is cleared.
+ Does nothing if the integer's string representation is the same as
+ the current contents of the label.
+
+ The buddy shortcut, if any, is disabled.
+
+ \sa setText(), QString::setNum(), setBuddy()
+*/
+
+void QLabel::setNum(int num)
+{
+ QString str;
+ str.setNum(num);
+ setText(str);
+}
+
+/*!
+ \overload
+
+ Sets the label contents to plain text containing the textual
+ representation of double \a num. Any previous content is cleared.
+ Does nothing if the double's string representation is the same as
+ the current contents of the label.
+
+ The buddy shortcut, if any, is disabled.
+
+ \sa setText(), QString::setNum(), setBuddy()
+*/
+
+void QLabel::setNum(double num)
+{
+ QString str;
+ str.setNum(num);
+ setText(str);
+}
+
+/*!
+ \property QLabel::alignment
+ \brief the alignment of the label's contents
+
+ By default, the contents of the label are left-aligned and vertically-centered.
+
+ \sa text
+*/
+
+void QLabel::setAlignment(Qt::Alignment alignment)
+{
+ Q_D(QLabel);
+ if (alignment == (d->align & (Qt::AlignVertical_Mask|Qt::AlignHorizontal_Mask)))
+ return;
+ d->align = (d->align & ~(Qt::AlignVertical_Mask|Qt::AlignHorizontal_Mask))
+ | (alignment & (Qt::AlignVertical_Mask|Qt::AlignHorizontal_Mask));
+
+ d->updateLabel();
+}
+
+#ifdef QT3_SUPPORT
+/*!
+ Use setAlignment(Qt::Alignment) instead.
+
+ If \a alignment specifies text flags as well, use setTextFormat()
+ to set those.
+*/
+void QLabel::setAlignment(int alignment)
+{
+ Q_D(QLabel);
+ d->align = alignment & ~(Qt::AlignVertical_Mask|Qt::AlignHorizontal_Mask|Qt::TextWordWrap);
+ setAlignment(Qt::Alignment(QFlag(alignment)));
+}
+#endif
+
+Qt::Alignment QLabel::alignment() const
+{
+ Q_D(const QLabel);
+ return QFlag(d->align & (Qt::AlignVertical_Mask|Qt::AlignHorizontal_Mask));
+}
+
+
+/*!
+ \property QLabel::wordWrap
+ \brief the label's word-wrapping policy
+
+ If this property is true then label text is wrapped where
+ necessary at word-breaks; otherwise it is not wrapped at all.
+
+ By default, word wrap is disabled.
+
+ \sa text
+*/
+void QLabel::setWordWrap(bool on)
+{
+ Q_D(QLabel);
+ if (on)
+ d->align |= Qt::TextWordWrap;
+ else
+ d->align &= ~Qt::TextWordWrap;
+
+ d->updateLabel();
+}
+
+bool QLabel::wordWrap() const
+{
+ Q_D(const QLabel);
+ return d->align & Qt::TextWordWrap;
+}
+
+/*!
+ \property QLabel::indent
+ \brief the label's text indent in pixels
+
+ If a label displays text, the indent applies to the left edge if
+ alignment() is Qt::AlignLeft, to the right edge if alignment() is
+ Qt::AlignRight, to the top edge if alignment() is Qt::AlignTop, and
+ to to the bottom edge if alignment() is Qt::AlignBottom.
+
+ If indent is negative, or if no indent has been set, the label
+ computes the effective indent as follows: If frameWidth() is 0,
+ the effective indent becomes 0. If frameWidth() is greater than 0,
+ the effective indent becomes half the width of the "x" character
+ of the widget's current font().
+
+ By default, the indent is -1, meaning that an effective indent is
+ calculating in the manner described above.
+
+ \sa alignment, margin, frameWidth(), font()
+*/
+
+void QLabel::setIndent(int indent)
+{
+ Q_D(QLabel);
+ d->indent = indent;
+ d->updateLabel();
+}
+
+int QLabel::indent() const
+{
+ Q_D(const QLabel);
+ return d->indent;
+}
+
+
+/*!
+ \property QLabel::margin
+ \brief the width of the margin
+
+ The margin is the distance between the innermost pixel of the
+ frame and the outermost pixel of contents.
+
+ The default margin is 0.
+
+ \sa indent
+*/
+int QLabel::margin() const
+{
+ Q_D(const QLabel);
+ return d->margin;
+}
+
+void QLabel::setMargin(int margin)
+{
+ Q_D(QLabel);
+ if (d->margin == margin)
+ return;
+ d->margin = margin;
+ d->updateLabel();
+}
+
+/*!
+ Returns the size that will be used if the width of the label is \a
+ w. If \a w is -1, the sizeHint() is returned. If \a w is 0 minimumSizeHint() is returned
+*/
+QSize QLabelPrivate::sizeForWidth(int w) const
+{
+ Q_Q(const QLabel);
+ if(q->minimumWidth() > 0)
+ w = qMax(w, q->minimumWidth());
+ QSize contentsMargin(leftmargin + rightmargin, topmargin + bottommargin);
+
+ QRect br;
+
+ int hextra = 2 * margin;
+ int vextra = hextra;
+ QFontMetrics fm = q->fontMetrics();
+
+ if (pixmap && !pixmap->isNull())
+ br = pixmap->rect();
+#ifndef QT_NO_PICTURE
+ else if (picture && !picture->isNull())
+ br = picture->boundingRect();
+#endif
+#ifndef QT_NO_MOVIE
+ else if (movie && !movie->currentPixmap().isNull())
+ br = movie->currentPixmap().rect();
+#endif
+ else if (isTextLabel) {
+ int align = QStyle::visualAlignment(textDirection(), QFlag(this->align));
+ // Add indentation
+ int m = indent;
+
+ if (m < 0 && q->frameWidth()) // no indent, but we do have a frame
+ m = fm.width(QLatin1Char('x')) - margin*2;
+ if (m > 0) {
+ if ((align & Qt::AlignLeft) || (align & Qt::AlignRight))
+ hextra += m;
+ if ((align & Qt::AlignTop) || (align & Qt::AlignBottom))
+ vextra += m;
+ }
+
+ if (control) {
+ ensureTextLayouted();
+ const qreal oldTextWidth = control->textWidth();
+ // Calculate the length of document if w is the width
+ if (align & Qt::TextWordWrap) {
+ if (w >= 0) {
+ w = qMax(w-hextra-contentsMargin.width(), 0); // strip margin and indent
+ control->setTextWidth(w);
+ } else {
+ control->adjustSize();
+ }
+ } else {
+ control->setTextWidth(-1);
+ }
+
+ QSizeF controlSize = control->size();
+ br = QRect(QPoint(0, 0), QSize(qCeil(controlSize.width()), qCeil(controlSize.height())));
+
+ // restore state
+ control->setTextWidth(oldTextWidth);
+ } else {
+ // Turn off center alignment in order to avoid rounding errors for centering,
+ // since centering involves a division by 2. At the end, all we want is the size.
+ int flags = align & ~(Qt::AlignVCenter | Qt::AlignHCenter);
+ if (hasShortcut) {
+ flags |= Qt::TextShowMnemonic;
+ QStyleOption opt;
+ opt.initFrom(q);
+ if (!q->style()->styleHint(QStyle::SH_UnderlineShortcut, &opt, q))
+ flags |= Qt::TextHideMnemonic;
+ }
+
+ bool tryWidth = (w < 0) && (align & Qt::TextWordWrap);
+ if (tryWidth)
+ w = qMin(fm.averageCharWidth() * 80, q->maximumSize().width());
+ else if (w < 0)
+ w = 2000;
+ w -= (hextra + contentsMargin.width());
+ br = fm.boundingRect(0, 0, w ,2000, flags, text);
+ if (tryWidth && br.height() < 4*fm.lineSpacing() && br.width() > w/2)
+ br = fm.boundingRect(0, 0, w/2, 2000, flags, text);
+ if (tryWidth && br.height() < 2*fm.lineSpacing() && br.width() > w/4)
+ br = fm.boundingRect(0, 0, w/4, 2000, flags, text);
+ }
+ } else {
+ br = QRect(QPoint(0, 0), QSize(fm.averageCharWidth(), fm.lineSpacing()));
+ }
+
+ const QSize contentsSize(br.width() + hextra, br.height() + vextra);
+ return (contentsSize + contentsMargin).expandedTo(q->minimumSize());
+}
+
+
+/*!
+ \reimp
+*/
+
+int QLabel::heightForWidth(int w) const
+{
+ Q_D(const QLabel);
+ if (d->isTextLabel)
+ return d->sizeForWidth(w).height();
+ return QWidget::heightForWidth(w);
+}
+
+/*!
+ \property QLabel::openExternalLinks
+ \since 4.2
+
+ Specifies whether QLabel should automatically open links using
+ QDesktopServices::openUrl() instead of emitting the
+ linkActivated() signal.
+
+ \bold{Note:} The textInteractionFlags set on the label need to include
+ either LinksAccessibleByMouse or LinksAccessibleByKeyboard.
+
+ The default value is false.
+
+ \sa textInteractionFlags()
+*/
+bool QLabel::openExternalLinks() const
+{
+ Q_D(const QLabel);
+ return d->openExternalLinks;
+}
+
+void QLabel::setOpenExternalLinks(bool open)
+{
+ Q_D(QLabel);
+ d->openExternalLinks = open;
+ if (d->control)
+ d->control->setOpenExternalLinks(open);
+}
+
+/*!
+ \property QLabel::textInteractionFlags
+ \since 4.2
+
+ Specifies how the label should interact with user input if it displays text.
+
+ If the flags contain Qt::LinksAccessibleByKeyboard the focus policy is also
+ automatically set to Qt::StrongFocus. If Qt::TextSelectableByKeyboard is set
+ then the focus policy is set to Qt::ClickFocus.
+
+ The default value is Qt::LinksAccessibleByMouse.
+*/
+void QLabel::setTextInteractionFlags(Qt::TextInteractionFlags flags)
+{
+ Q_D(QLabel);
+ if (d->textInteractionFlags == flags)
+ return;
+ d->textInteractionFlags = flags;
+ if (flags & Qt::LinksAccessibleByKeyboard)
+ setFocusPolicy(Qt::StrongFocus);
+ else if (flags & (Qt::TextSelectableByKeyboard | Qt::TextSelectableByMouse))
+ setFocusPolicy(Qt::ClickFocus);
+ else
+ setFocusPolicy(Qt::NoFocus);
+
+ if (d->needTextControl()) {
+ d->ensureTextControl();
+ } else {
+ delete d->control;
+ d->control = 0;
+ }
+
+ if (d->control)
+ d->control->setTextInteractionFlags(d->textInteractionFlags);
+}
+
+Qt::TextInteractionFlags QLabel::textInteractionFlags() const
+{
+ Q_D(const QLabel);
+ return d->textInteractionFlags;
+}
+
+/*!
+ Selects text from position \a start and for \a length characters.
+
+ \sa selectedText()
+
+ \bold{Note:} The textInteractionFlags set on the label need to include
+ either TextSelectableByMouse or TextSelectableByKeyboard.
+
+ \since 4.7
+*/
+void QLabel::setSelection(int start, int length)
+{
+ Q_D(QLabel);
+ if (d->control) {
+ d->ensureTextPopulated();
+ QTextCursor cursor = d->control->textCursor();
+ cursor.setPosition(start);
+ cursor.setPosition(start + length, QTextCursor::KeepAnchor);
+ d->control->setTextCursor(cursor);
+ }
+}
+
+/*!
+ \property QLabel::hasSelectedText
+ \brief whether there is any text selected
+
+ hasSelectedText() returns true if some or all of the text has been
+ selected by the user; otherwise returns false.
+
+ By default, this property is false.
+
+ \sa selectedText()
+
+ \bold{Note:} The textInteractionFlags set on the label need to include
+ either TextSelectableByMouse or TextSelectableByKeyboard.
+
+ \since 4.7
+*/
+bool QLabel::hasSelectedText() const
+{
+ Q_D(const QLabel);
+ if (d->control)
+ return d->control->textCursor().hasSelection();
+ return false;
+}
+
+/*!
+ \property QLabel::selectedText
+ \brief the selected text
+
+ If there is no selected text this property's value is
+ an empty string.
+
+ By default, this property contains an empty string.
+
+ \sa hasSelectedText()
+
+ \bold{Note:} The textInteractionFlags set on the label need to include
+ either TextSelectableByMouse or TextSelectableByKeyboard.
+
+ \since 4.7
+*/
+QString QLabel::selectedText() const
+{
+ Q_D(const QLabel);
+ if (d->control)
+ return d->control->textCursor().selectedText();
+ return QString();
+}
+
+/*!
+ selectionStart() returns the index of the first selected character in the
+ label or -1 if no text is selected.
+
+ \sa selectedText()
+
+ \bold{Note:} The textInteractionFlags set on the label need to include
+ either TextSelectableByMouse or TextSelectableByKeyboard.
+
+ \since 4.7
+*/
+int QLabel::selectionStart() const
+{
+ Q_D(const QLabel);
+ if (d->control && d->control->textCursor().hasSelection())
+ return d->control->textCursor().selectionStart();
+ return -1;
+}
+
+/*!\reimp
+*/
+QSize QLabel::sizeHint() const
+{
+ Q_D(const QLabel);
+ if (!d->valid_hints)
+ (void) QLabel::minimumSizeHint();
+ return d->sh;
+}
+
+/*!
+ \reimp
+*/
+QSize QLabel::minimumSizeHint() const
+{
+ Q_D(const QLabel);
+ if (d->valid_hints) {
+ if (d->sizePolicy == sizePolicy())
+ return d->msh;
+ }
+
+ ensurePolished();
+ d->valid_hints = true;
+ d->sh = d->sizeForWidth(-1); // wrap ? golden ratio : min doc size
+ QSize msh(-1, -1);
+
+ if (!d->isTextLabel) {
+ msh = d->sh;
+ } else {
+ msh.rheight() = d->sizeForWidth(QWIDGETSIZE_MAX).height(); // height for one line
+ msh.rwidth() = d->sizeForWidth(0).width(); // wrap ? size of biggest word : min doc size
+ if (d->sh.height() < msh.height())
+ msh.rheight() = d->sh.height();
+ }
+ d->msh = msh;
+ d->sizePolicy = sizePolicy();
+ return msh;
+}
+
+/*!\reimp
+*/
+void QLabel::mousePressEvent(QMouseEvent *ev)
+{
+ Q_D(QLabel);
+ d->sendControlEvent(ev);
+}
+
+/*!\reimp
+*/
+void QLabel::mouseMoveEvent(QMouseEvent *ev)
+{
+ Q_D(QLabel);
+ d->sendControlEvent(ev);
+}
+
+/*!\reimp
+*/
+void QLabel::mouseReleaseEvent(QMouseEvent *ev)
+{
+ Q_D(QLabel);
+ d->sendControlEvent(ev);
+}
+
+/*!\reimp
+*/
+void QLabel::contextMenuEvent(QContextMenuEvent *ev)
+{
+#ifdef QT_NO_CONTEXTMENU
+ Q_UNUSED(ev);
+#else
+ Q_D(QLabel);
+ if (!d->isTextLabel) {
+ ev->ignore();
+ return;
+ }
+ QMenu *menu = d->createStandardContextMenu(ev->pos());
+ if (!menu) {
+ ev->ignore();
+ return;
+ }
+ ev->accept();
+ menu->setAttribute(Qt::WA_DeleteOnClose);
+ menu->popup(ev->globalPos());
+#endif
+}
+
+/*!
+ \reimp
+*/
+void QLabel::focusInEvent(QFocusEvent *ev)
+{
+ Q_D(QLabel);
+ if (d->isTextLabel) {
+ d->ensureTextControl();
+ d->sendControlEvent(ev);
+ }
+ QFrame::focusInEvent(ev);
+}
+
+/*!
+ \reimp
+*/
+void QLabel::focusOutEvent(QFocusEvent *ev)
+{
+ Q_D(QLabel);
+ if (d->control) {
+ d->sendControlEvent(ev);
+ QTextCursor cursor = d->control->textCursor();
+ Qt::FocusReason reason = ev->reason();
+ if (reason != Qt::ActiveWindowFocusReason
+ && reason != Qt::PopupFocusReason
+ && cursor.hasSelection()) {
+ cursor.clearSelection();
+ d->control->setTextCursor(cursor);
+ }
+ }
+
+ QFrame::focusOutEvent(ev);
+}
+
+/*!\reimp
+*/
+bool QLabel::focusNextPrevChild(bool next)
+{
+ Q_D(QLabel);
+ if (d->control && d->control->setFocusToNextOrPreviousAnchor(next))
+ return true;
+ return QFrame::focusNextPrevChild(next);
+}
+
+/*!\reimp
+*/
+void QLabel::keyPressEvent(QKeyEvent *ev)
+{
+ Q_D(QLabel);
+ d->sendControlEvent(ev);
+}
+
+/*!\reimp
+*/
+bool QLabel::event(QEvent *e)
+{
+ Q_D(QLabel);
+ QEvent::Type type = e->type();
+
+#ifndef QT_NO_SHORTCUT
+ if (type == QEvent::Shortcut) {
+ QShortcutEvent *se = static_cast<QShortcutEvent *>(e);
+ if (se->shortcutId() == d->shortcutId) {
+ QWidget * w = d->buddy;
+ QAbstractButton *button = qobject_cast<QAbstractButton *>(w);
+ if (w->focusPolicy() != Qt::NoFocus)
+ w->setFocus(Qt::ShortcutFocusReason);
+ if (button && !se->isAmbiguous())
+ button->animateClick();
+ else
+ window()->setAttribute(Qt::WA_KeyboardFocusChange);
+ return true;
+ }
+ } else
+#endif
+ if (type == QEvent::Resize) {
+ if (d->control)
+ d->textLayoutDirty = true;
+ } else if (e->type() == QEvent::StyleChange
+#ifdef Q_WS_MAC
+ || e->type() == QEvent::MacSizeChange
+#endif
+ ) {
+ d->setLayoutItemMargins(QStyle::SE_LabelLayoutItem);
+ d->updateLabel();
+ }
+
+ return QFrame::event(e);
+}
+
+/*!\reimp
+*/
+void QLabel::paintEvent(QPaintEvent *)
+{
+ Q_D(QLabel);
+ QStyle *style = QWidget::style();
+ QPainter painter(this);
+ drawFrame(&painter);
+ QRect cr = contentsRect();
+ cr.adjust(d->margin, d->margin, -d->margin, -d->margin);
+ int align = QStyle::visualAlignment(d->isTextLabel ? d->textDirection()
+ : layoutDirection(), QFlag(d->align));
+
+#ifndef QT_NO_MOVIE
+ if (d->movie) {
+ if (d->scaledcontents)
+ style->drawItemPixmap(&painter, cr, align, d->movie->currentPixmap().scaled(cr.size()));
+ else
+ style->drawItemPixmap(&painter, cr, align, d->movie->currentPixmap());
+ }
+ else
+#endif
+ if (d->isTextLabel) {
+ QRectF lr = d->layoutRect().toAlignedRect();
+ QStyleOption opt;
+ opt.initFrom(this);
+#ifndef QT_NO_STYLE_STYLESHEET
+ if (QStyleSheetStyle* cssStyle = qobject_cast<QStyleSheetStyle*>(style)) {
+ cssStyle->styleSheetPalette(this, &opt, &opt.palette);
+ }
+#endif
+ if (d->control) {
+#ifndef QT_NO_SHORTCUT
+ const bool underline = (bool)style->styleHint(QStyle::SH_UnderlineShortcut, 0, this, 0);
+ if (d->shortcutId != 0
+ && underline != d->shortcutCursor.charFormat().fontUnderline()) {
+ QTextCharFormat fmt;
+ fmt.setFontUnderline(underline);
+ d->shortcutCursor.mergeCharFormat(fmt);
+ }
+#endif
+ d->ensureTextLayouted();
+
+ QAbstractTextDocumentLayout::PaintContext context;
+ if (!isEnabled() && !d->control &&
+ // We cannot support etched for rich text controls because custom
+ // colors and links will override the light palette
+ style->styleHint(QStyle::SH_EtchDisabledText, &opt, this)) {
+ context.palette = opt.palette;
+ context.palette.setColor(QPalette::Text, context.palette.light().color());
+ painter.save();
+ painter.translate(lr.x() + 1, lr.y() + 1);
+ painter.setClipRect(lr.translated(-lr.x() - 1, -lr.y() - 1));
+ QAbstractTextDocumentLayout *layout = d->control->document()->documentLayout();
+ layout->draw(&painter, context);
+ painter.restore();
+ }
+
+ // Adjust the palette
+ context.palette = opt.palette;
+
+ if (foregroundRole() != QPalette::Text && isEnabled())
+ context.palette.setColor(QPalette::Text, context.palette.color(foregroundRole()));
+
+ painter.save();
+ painter.translate(lr.topLeft());
+ painter.setClipRect(lr.translated(-lr.x(), -lr.y()));
+ d->control->setPalette(context.palette);
+ d->control->drawContents(&painter, QRectF(), this);
+ painter.restore();
+ } else {
+ int flags = align | (d->textDirection() == Qt::LeftToRight ? Qt::TextForceLeftToRight
+ : Qt::TextForceRightToLeft);
+ if (d->hasShortcut) {
+ flags |= Qt::TextShowMnemonic;
+ if (!style->styleHint(QStyle::SH_UnderlineShortcut, &opt, this))
+ flags |= Qt::TextHideMnemonic;
+ }
+ style->drawItemText(&painter, lr.toRect(), flags, opt.palette, isEnabled(), d->text, foregroundRole());
+ }
+ } else
+#ifndef QT_NO_PICTURE
+ if (d->picture) {
+ QRect br = d->picture->boundingRect();
+ int rw = br.width();
+ int rh = br.height();
+ if (d->scaledcontents) {
+ painter.save();
+ painter.translate(cr.x(), cr.y());
+ painter.scale((double)cr.width()/rw, (double)cr.height()/rh);
+ painter.drawPicture(-br.x(), -br.y(), *d->picture);
+ painter.restore();
+ } else {
+ int xo = 0;
+ int yo = 0;
+ if (align & Qt::AlignVCenter)
+ yo = (cr.height()-rh)/2;
+ else if (align & Qt::AlignBottom)
+ yo = cr.height()-rh;
+ if (align & Qt::AlignRight)
+ xo = cr.width()-rw;
+ else if (align & Qt::AlignHCenter)
+ xo = (cr.width()-rw)/2;
+ painter.drawPicture(cr.x()+xo-br.x(), cr.y()+yo-br.y(), *d->picture);
+ }
+ } else
+#endif
+ if (d->pixmap && !d->pixmap->isNull()) {
+ QPixmap pix;
+ if (d->scaledcontents) {
+ if (!d->scaledpixmap || d->scaledpixmap->size() != cr.size()) {
+ if (!d->cachedimage)
+ d->cachedimage = new QImage(d->pixmap->toImage());
+ delete d->scaledpixmap;
+ d->scaledpixmap = new QPixmap(QPixmap::fromImage(d->cachedimage->scaled(cr.size(),Qt::IgnoreAspectRatio,Qt::SmoothTransformation)));
+ }
+ pix = *d->scaledpixmap;
+ } else
+ pix = *d->pixmap;
+ QStyleOption opt;
+ opt.initFrom(this);
+ if (!isEnabled())
+ pix = style->generatedIconPixmap(QIcon::Disabled, pix, &opt);
+ style->drawItemPixmap(&painter, cr, align, pix);
+ }
+}
+
+
+/*!
+ Updates the label, but not the frame.
+*/
+
+void QLabelPrivate::updateLabel()
+{
+ Q_Q(QLabel);
+ valid_hints = false;
+
+ if (isTextLabel) {
+ QSizePolicy policy = q->sizePolicy();
+ const bool wrap = align & Qt::TextWordWrap;
+ policy.setHeightForWidth(wrap);
+ if (policy != q->sizePolicy()) // ### should be replaced by WA_WState_OwnSizePolicy idiom
+ q->setSizePolicy(policy);
+ textLayoutDirty = true;
+ }
+ q->updateGeometry();
+ q->update(q->contentsRect());
+}
+
+#ifndef QT_NO_SHORTCUT
+/*!
+ Sets this label's buddy to \a buddy.
+
+ When the user presses the shortcut key indicated by this label,
+ the keyboard focus is transferred to the label's buddy widget.
+
+ The buddy mechanism is only available for QLabels that contain
+ text in which one character is prefixed with an ampersand, '&'.
+ This character is set as the shortcut key. See the \l
+ QKeySequence::mnemonic() documentation for details (to display an
+ actual ampersand, use '&&').
+
+ In a dialog, you might create two data entry widgets and a label
+ for each, and set up the geometry layout so each label is just to
+ the left of its data entry widget (its "buddy"), for example:
+ \snippet doc/src/snippets/code/src_gui_widgets_qlabel.cpp 2
+
+ With the code above, the focus jumps to the Name field when the
+ user presses Alt+N, and to the Phone field when the user presses
+ Alt+P.
+
+ To unset a previously set buddy, call this function with \a buddy
+ set to 0.
+
+ \sa buddy(), setText(), QShortcut, setAlignment()
+*/
+
+void QLabel::setBuddy(QWidget *buddy)
+{
+ Q_D(QLabel);
+ d->buddy = buddy;
+ if (d->isTextLabel) {
+ if (d->shortcutId)
+ releaseShortcut(d->shortcutId);
+ d->shortcutId = 0;
+ d->textDirty = true;
+ if (buddy)
+ d->updateShortcut(); // grab new shortcut
+ d->updateLabel();
+ }
+}
+
+
+/*!
+ Returns this label's buddy, or 0 if no buddy is currently set.
+
+ \sa setBuddy()
+*/
+
+QWidget * QLabel::buddy() const
+{
+ Q_D(const QLabel);
+ return d->buddy;
+}
+
+void QLabelPrivate::updateShortcut()
+{
+ Q_Q(QLabel);
+ Q_ASSERT(shortcutId == 0);
+ // Introduce an extra boolean to indicate the presence of a shortcut in the
+ // text. We cannot use the shortcutId itself because on the mac mnemonics are
+ // off by default, so QKeySequence::mnemonic always returns an empty sequence.
+ // But then we do want to hide the ampersands, so we can't use shortcutId.
+ hasShortcut = false;
+
+ if (!text.contains(QLatin1Char('&')))
+ return;
+ hasShortcut = true;
+ shortcutId = q->grabShortcut(QKeySequence::mnemonic(text));
+}
+
+#endif // QT_NO_SHORTCUT
+
+#ifndef QT_NO_MOVIE
+void QLabelPrivate::_q_movieUpdated(const QRect& rect)
+{
+ Q_Q(QLabel);
+ if (movie && movie->isValid()) {
+ QRect r;
+ if (scaledcontents) {
+ QRect cr = q->contentsRect();
+ QRect pixmapRect(cr.topLeft(), movie->currentPixmap().size());
+ if (pixmapRect.isEmpty())
+ return;
+ r.setRect(cr.left(), cr.top(),
+ (rect.width() * cr.width()) / pixmapRect.width(),
+ (rect.height() * cr.height()) / pixmapRect.height());
+ } else {
+ r = q->style()->itemPixmapRect(q->contentsRect(), align, movie->currentPixmap());
+ r.translate(rect.x(), rect.y());
+ r.setWidth(qMin(r.width(), rect.width()));
+ r.setHeight(qMin(r.height(), rect.height()));
+ }
+ q->update(r);
+ }
+}
+
+void QLabelPrivate::_q_movieResized(const QSize& size)
+{
+ Q_Q(QLabel);
+ q->update(); //we need to refresh the whole background in case the new size is smaler
+ valid_hints = false;
+ _q_movieUpdated(QRect(QPoint(0,0), size));
+ q->updateGeometry();
+}
+
+/*!
+ Sets the label contents to \a movie. Any previous content is
+ cleared. The label does NOT take ownership of the movie.
+
+ The buddy shortcut, if any, is disabled.
+
+ \sa movie(), setBuddy()
+*/
+
+void QLabel::setMovie(QMovie *movie)
+{
+ Q_D(QLabel);
+ d->clearContents();
+
+ if (!movie)
+ return;
+
+ d->movie = movie;
+ connect(movie, SIGNAL(resized(QSize)), this, SLOT(_q_movieResized(QSize)));
+ connect(movie, SIGNAL(updated(QRect)), this, SLOT(_q_movieUpdated(QRect)));
+
+ // Assume that if the movie is running,
+ // resize/update signals will come soon enough
+ if (movie->state() != QMovie::Running)
+ d->updateLabel();
+}
+
+#endif // QT_NO_MOVIE
+
+/*!
+ \internal
+
+ Clears any contents, without updating/repainting the label.
+*/
+
+void QLabelPrivate::clearContents()
+{
+ delete control;
+ control = 0;
+ isTextLabel = false;
+ hasShortcut = false;
+
+#ifndef QT_NO_PICTURE
+ delete picture;
+ picture = 0;
+#endif
+ delete scaledpixmap;
+ scaledpixmap = 0;
+ delete cachedimage;
+ cachedimage = 0;
+ delete pixmap;
+ pixmap = 0;
+
+ text.clear();
+ Q_Q(QLabel);
+#ifndef QT_NO_SHORTCUT
+ if (shortcutId)
+ q->releaseShortcut(shortcutId);
+ shortcutId = 0;
+#endif
+#ifndef QT_NO_MOVIE
+ if (movie) {
+ QObject::disconnect(movie, SIGNAL(resized(QSize)), q, SLOT(_q_movieResized(QSize)));
+ QObject::disconnect(movie, SIGNAL(updated(QRect)), q, SLOT(_q_movieUpdated(QRect)));
+ }
+ movie = 0;
+#endif
+#ifndef QT_NO_CURSOR
+ if (onAnchor) {
+ if (validCursor)
+ q->setCursor(cursor);
+ else
+ q->unsetCursor();
+ }
+ validCursor = false;
+ onAnchor = false;
+#endif
+}
+
+
+#ifndef QT_NO_MOVIE
+
+/*!
+ Returns a pointer to the label's movie, or 0 if no movie has been
+ set.
+
+ \sa setMovie()
+*/
+
+QMovie *QLabel::movie() const
+{
+ Q_D(const QLabel);
+ return d->movie;
+}
+
+#endif // QT_NO_MOVIE
+
+/*!
+ \property QLabel::textFormat
+ \brief the label's text format
+
+ See the Qt::TextFormat enum for an explanation of the possible
+ options.
+
+ The default format is Qt::AutoText.
+
+ \sa text()
+*/
+
+Qt::TextFormat QLabel::textFormat() const
+{
+ Q_D(const QLabel);
+ return d->textformat;
+}
+
+void QLabel::setTextFormat(Qt::TextFormat format)
+{
+ Q_D(QLabel);
+ if (format != d->textformat) {
+ d->textformat = format;
+ QString t = d->text;
+ if (!t.isNull()) {
+ d->text.clear();
+ setText(t);
+ }
+ }
+}
+
+/*!
+ \reimp
+*/
+void QLabel::changeEvent(QEvent *ev)
+{
+ Q_D(QLabel);
+ if(ev->type() == QEvent::FontChange || ev->type() == QEvent::ApplicationFontChange) {
+ if (d->isTextLabel) {
+ if (d->control)
+ d->control->document()->setDefaultFont(font());
+ d->updateLabel();
+ }
+ } else if (ev->type() == QEvent::PaletteChange && d->control) {
+ d->control->setPalette(palette());
+ } else if (ev->type() == QEvent::ContentsRectChange) {
+ d->updateLabel();
+ }
+ QFrame::changeEvent(ev);
+}
+
+/*!
+ \property QLabel::scaledContents
+ \brief whether the label will scale its contents to fill all
+ available space.
+
+ When enabled and the label shows a pixmap, it will scale the
+ pixmap to fill the available space.
+
+ This property's default is false.
+*/
+bool QLabel::hasScaledContents() const
+{
+ Q_D(const QLabel);
+ return d->scaledcontents;
+}
+
+void QLabel::setScaledContents(bool enable)
+{
+ Q_D(QLabel);
+ if ((bool)d->scaledcontents == enable)
+ return;
+ d->scaledcontents = enable;
+ if (!enable) {
+ delete d->scaledpixmap;
+ d->scaledpixmap = 0;
+ delete d->cachedimage;
+ d->cachedimage = 0;
+ }
+ update(contentsRect());
+}
+
+Qt::LayoutDirection QLabelPrivate::textDirection() const
+{
+ if (control) {
+ QTextOption opt = control->document()->defaultTextOption();
+ return opt.textDirection();
+ }
+
+ return text.isRightToLeft() ? Qt::RightToLeft : Qt::LeftToRight;
+}
+
+/*!
+ \fn void QLabel::setAlignment(Qt::AlignmentFlag flag)
+ \internal
+
+ Without this function, a call to e.g. setAlignment(Qt::AlignTop)
+ results in the \c QT3_SUPPORT function setAlignment(int) being called,
+ rather than setAlignment(Qt::Alignment).
+*/
+
+// Returns the rect that is available for us to draw the document
+QRect QLabelPrivate::documentRect() const
+{
+ Q_Q(const QLabel);
+ Q_ASSERT_X(isTextLabel, "documentRect", "document rect called for label that is not a text label!");
+ QRect cr = q->contentsRect();
+ cr.adjust(margin, margin, -margin, -margin);
+ const int align = QStyle::visualAlignment(isTextLabel ? textDirection()
+ : q->layoutDirection(), QFlag(this->align));
+ int m = indent;
+ if (m < 0 && q->frameWidth()) // no indent, but we do have a frame
+ m = q->fontMetrics().width(QLatin1Char('x')) / 2 - margin;
+ if (m > 0) {
+ if (align & Qt::AlignLeft)
+ cr.setLeft(cr.left() + m);
+ if (align & Qt::AlignRight)
+ cr.setRight(cr.right() - m);
+ if (align & Qt::AlignTop)
+ cr.setTop(cr.top() + m);
+ if (align & Qt::AlignBottom)
+ cr.setBottom(cr.bottom() - m);
+ }
+ return cr;
+}
+
+void QLabelPrivate::ensureTextPopulated() const
+{
+ if (!textDirty)
+ return;
+ if (control) {
+ QTextDocument *doc = control->document();
+ if (textDirty) {
+#ifndef QT_NO_TEXTHTMLPARSER
+ if (isRichText)
+ doc->setHtml(text);
+ else
+ doc->setPlainText(text);
+#else
+ doc->setPlainText(text);
+#endif
+ doc->setUndoRedoEnabled(false);
+
+#ifndef QT_NO_SHORTCUT
+ if (hasShortcut) {
+ // Underline the first character that follows an ampersand (and remove the others ampersands)
+ int from = 0;
+ bool found = false;
+ QTextCursor cursor;
+ while (!(cursor = control->document()->find((QLatin1String("&")), from)).isNull()) {
+ cursor.deleteChar(); // remove the ampersand
+ cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);
+ from = cursor.position();
+ if (!found && cursor.selectedText() != QLatin1String("&")) { //not a second &
+ found = true;
+ shortcutCursor = cursor;
+ }
+ }
+ }
+#endif
+ }
+ }
+ textDirty = false;
+}
+
+void QLabelPrivate::ensureTextLayouted() const
+{
+ if (!textLayoutDirty)
+ return;
+ ensureTextPopulated();
+ if (control) {
+ QTextDocument *doc = control->document();
+ QTextOption opt = doc->defaultTextOption();
+
+ opt.setAlignment(QFlag(this->align));
+
+ if (this->align & Qt::TextWordWrap)
+ opt.setWrapMode(QTextOption::WordWrap);
+ else
+ opt.setWrapMode(QTextOption::ManualWrap);
+
+ doc->setDefaultTextOption(opt);
+
+ QTextFrameFormat fmt = doc->rootFrame()->frameFormat();
+ fmt.setMargin(0);
+ doc->rootFrame()->setFrameFormat(fmt);
+ doc->setTextWidth(documentRect().width());
+ }
+ textLayoutDirty = false;
+}
+
+void QLabelPrivate::ensureTextControl() const
+{
+ Q_Q(const QLabel);
+ if (!isTextLabel)
+ return;
+ if (!control) {
+ control = new QWidgetTextControl(const_cast<QLabel *>(q));
+ control->document()->setUndoRedoEnabled(false);
+ control->document()->setDefaultFont(q->font());
+ control->setTextInteractionFlags(textInteractionFlags);
+ control->setOpenExternalLinks(openExternalLinks);
+ control->setPalette(q->palette());
+ control->setFocus(q->hasFocus());
+ QObject::connect(control, SIGNAL(updateRequest(QRectF)),
+ q, SLOT(update()));
+ QObject::connect(control, SIGNAL(linkHovered(QString)),
+ q, SLOT(_q_linkHovered(QString)));
+ QObject::connect(control, SIGNAL(linkActivated(QString)),
+ q, SIGNAL(linkActivated(QString)));
+ textLayoutDirty = true;
+ textDirty = true;
+ }
+}
+
+void QLabelPrivate::sendControlEvent(QEvent *e)
+{
+ Q_Q(QLabel);
+ if (!isTextLabel || !control || textInteractionFlags == Qt::NoTextInteraction) {
+ e->ignore();
+ return;
+ }
+ control->processEvent(e, -layoutRect().topLeft(), q);
+}
+
+void QLabelPrivate::_q_linkHovered(const QString &anchor)
+{
+ Q_Q(QLabel);
+#ifndef QT_NO_CURSOR
+ if (anchor.isEmpty()) { // restore cursor
+ if (validCursor)
+ q->setCursor(cursor);
+ else
+ q->unsetCursor();
+ onAnchor = false;
+ } else if (!onAnchor) {
+ validCursor = q->testAttribute(Qt::WA_SetCursor);
+ if (validCursor) {
+ cursor = q->cursor();
+ }
+ q->setCursor(Qt::PointingHandCursor);
+ onAnchor = true;
+ }
+#endif
+ emit q->linkHovered(anchor);
+}
+
+// Return the layout rect - this is the rect that is given to the layout painting code
+// This may be different from the document rect since vertical alignment is not
+// done by the text layout code
+QRectF QLabelPrivate::layoutRect() const
+{
+ QRectF cr = documentRect();
+ if (!control)
+ return cr;
+ ensureTextLayouted();
+ // Caculate y position manually
+ qreal rh = control->document()->documentLayout()->documentSize().height();
+ qreal yo = 0;
+ if (align & Qt::AlignVCenter)
+ yo = qMax((cr.height()-rh)/2, qreal(0));
+ else if (align & Qt::AlignBottom)
+ yo = qMax(cr.height()-rh, qreal(0));
+ return QRectF(cr.x(), yo + cr.y(), cr.width(), cr.height());
+}
+
+// Returns the point in the document rect adjusted with p
+QPoint QLabelPrivate::layoutPoint(const QPoint& p) const
+{
+ QRect lr = layoutRect().toRect();
+ return p - lr.topLeft();
+}
+
+#ifndef QT_NO_CONTEXTMENU
+QMenu *QLabelPrivate::createStandardContextMenu(const QPoint &pos)
+{
+ QString linkToCopy;
+ QPoint p;
+ if (control && isRichText) {
+ p = layoutPoint(pos);
+ linkToCopy = control->document()->documentLayout()->anchorAt(p);
+ }
+
+ if (linkToCopy.isEmpty() && !control)
+ return 0;
+
+ return control->createStandardContextMenu(p, q_func());
+}
+#endif
+
+/*!
+ \fn void QLabel::linkHovered(const QString &link)
+ \since 4.2
+
+ This signal is emitted when the user hovers over a link. The URL
+ referred to by the anchor is passed in \a link.
+
+ \sa linkActivated()
+*/
+
+
+/*!
+ \fn void QLabel::linkActivated(const QString &link)
+ \since 4.2
+
+ This signal is emitted when the user clicks a link. The URL
+ referred to by the anchor is passed in \a link.
+
+ \sa linkHovered()
+*/
+
+QT_END_NAMESPACE
+
+#include "moc_qlabel.cpp"
diff --git a/src/widgets/widgets/qlabel.h b/src/widgets/widgets/qlabel.h
new file mode 100644
index 0000000000..d8fc297299
--- /dev/null
+++ b/src/widgets/widgets/qlabel.h
@@ -0,0 +1,182 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QLABEL_H
+#define QLABEL_H
+
+#include <QtWidgets/qframe.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QLabelPrivate;
+
+class Q_WIDGETS_EXPORT QLabel : public QFrame
+{
+ Q_OBJECT
+ Q_PROPERTY(QString text READ text WRITE setText)
+ Q_PROPERTY(Qt::TextFormat textFormat READ textFormat WRITE setTextFormat)
+ Q_PROPERTY(QPixmap pixmap READ pixmap WRITE setPixmap)
+ Q_PROPERTY(bool scaledContents READ hasScaledContents WRITE setScaledContents)
+ Q_PROPERTY(Qt::Alignment alignment READ alignment WRITE setAlignment)
+ Q_PROPERTY(bool wordWrap READ wordWrap WRITE setWordWrap)
+ Q_PROPERTY(int margin READ margin WRITE setMargin)
+ Q_PROPERTY(int indent READ indent WRITE setIndent)
+ Q_PROPERTY(bool openExternalLinks READ openExternalLinks WRITE setOpenExternalLinks)
+ Q_PROPERTY(Qt::TextInteractionFlags textInteractionFlags READ textInteractionFlags WRITE setTextInteractionFlags)
+ Q_PROPERTY(bool hasSelectedText READ hasSelectedText)
+ Q_PROPERTY(QString selectedText READ selectedText)
+
+public:
+ explicit QLabel(QWidget *parent=0, Qt::WindowFlags f=0);
+ explicit QLabel(const QString &text, QWidget *parent=0, Qt::WindowFlags f=0);
+ ~QLabel();
+
+ QString text() const;
+ const QPixmap *pixmap() const;
+#ifndef QT_NO_PICTURE
+ const QPicture *picture() const;
+#endif
+#ifndef QT_NO_MOVIE
+ QMovie *movie() const;
+#endif
+
+ Qt::TextFormat textFormat() const;
+ void setTextFormat(Qt::TextFormat);
+
+ Qt::Alignment alignment() const;
+ void setAlignment(Qt::Alignment);
+
+ void setWordWrap(bool on);
+ bool wordWrap() const;
+
+ int indent() const;
+ void setIndent(int);
+
+ int margin() const;
+ void setMargin(int);
+
+ bool hasScaledContents() const;
+ void setScaledContents(bool);
+ QSize sizeHint() const;
+ QSize minimumSizeHint() const;
+#ifndef QT_NO_SHORTCUT
+ void setBuddy(QWidget *);
+ QWidget *buddy() const;
+#endif
+ int heightForWidth(int) const;
+
+ bool openExternalLinks() const;
+ void setOpenExternalLinks(bool open);
+
+ void setTextInteractionFlags(Qt::TextInteractionFlags flags);
+ Qt::TextInteractionFlags textInteractionFlags() const;
+
+ void setSelection(int, int);
+ bool hasSelectedText() const;
+ QString selectedText() const;
+ int selectionStart() const;
+
+public Q_SLOTS:
+ void setText(const QString &);
+ void setPixmap(const QPixmap &);
+#ifndef QT_NO_PICTURE
+ void setPicture(const QPicture &);
+#endif
+#ifndef QT_NO_MOVIE
+ void setMovie(QMovie *movie);
+#endif
+ void setNum(int);
+ void setNum(double);
+ void clear();
+
+Q_SIGNALS:
+ void linkActivated(const QString& link);
+ void linkHovered(const QString& link);
+
+protected:
+ bool event(QEvent *e);
+ void keyPressEvent(QKeyEvent *ev);
+ void paintEvent(QPaintEvent *);
+ void changeEvent(QEvent *);
+ void mousePressEvent(QMouseEvent *ev);
+ void mouseMoveEvent(QMouseEvent *ev);
+ void mouseReleaseEvent(QMouseEvent *ev);
+ void contextMenuEvent(QContextMenuEvent *ev);
+ void focusInEvent(QFocusEvent *ev);
+ void focusOutEvent(QFocusEvent *ev);
+ bool focusNextPrevChild(bool next);
+
+#ifdef QT3_SUPPORT
+public:
+ QT3_SUPPORT_CONSTRUCTOR QLabel(QWidget *parent, const char* name, Qt::WindowFlags f=0);
+ QT3_SUPPORT_CONSTRUCTOR QLabel(const QString &text, QWidget *parent, const char* name,
+ Qt::WindowFlags f=0);
+ QT3_SUPPORT_CONSTRUCTOR QLabel(QWidget *buddy, const QString &,
+ QWidget *parent=0, const char* name=0, Qt::WindowFlags f=0);
+ QT3_SUPPORT void setAlignment(int alignment);
+
+ // don't mark the next function with QT3_SUPPORT
+ inline void setAlignment(Qt::AlignmentFlag flag) { setAlignment((Qt::Alignment)flag); }
+#endif
+
+private:
+ Q_DISABLE_COPY(QLabel)
+ Q_DECLARE_PRIVATE(QLabel)
+#ifndef QT_NO_MOVIE
+ Q_PRIVATE_SLOT(d_func(), void _q_movieUpdated(const QRect&))
+ Q_PRIVATE_SLOT(d_func(), void _q_movieResized(const QSize&))
+#endif
+ Q_PRIVATE_SLOT(d_func(), void _q_linkHovered(const QString &))
+
+ friend class QTipLabel;
+ friend class QMessageBoxPrivate;
+ friend class QBalloonTip;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QLABEL_H
diff --git a/src/widgets/widgets/qlabel_p.h b/src/widgets/widgets/qlabel_p.h
new file mode 100644
index 0000000000..b6f2db6a25
--- /dev/null
+++ b/src/widgets/widgets/qlabel_p.h
@@ -0,0 +1,153 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QLABEL_P_H
+#define QLABEL_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qlabel.h"
+
+#include "private/qtextdocumentlayout_p.h"
+#include "private/qwidgettextcontrol_p.h"
+#include "qtextdocumentfragment.h"
+#include "qframe_p.h"
+#include "qtextdocument.h"
+#include "qmovie.h"
+#include "qimage.h"
+#include "qbitmap.h"
+#include "qpicture.h"
+#include "qmenu.h"
+
+QT_BEGIN_NAMESPACE
+
+class QLabelPrivate : public QFramePrivate
+{
+ Q_DECLARE_PUBLIC(QLabel)
+public:
+ QLabelPrivate() {}
+
+ void init();
+ void clearContents();
+ void updateLabel();
+ QSize sizeForWidth(int w) const;
+
+ mutable QSize sh;
+ mutable QSize msh;
+ mutable bool valid_hints;
+ mutable QSizePolicy sizePolicy;
+ int margin;
+ QString text;
+ QPixmap *pixmap;
+ QPixmap *scaledpixmap;
+ QImage *cachedimage;
+#ifndef QT_NO_PICTURE
+ QPicture *picture;
+#endif
+#ifndef QT_NO_MOVIE
+ QPointer<QMovie> movie;
+ void _q_movieUpdated(const QRect&);
+ void _q_movieResized(const QSize&);
+#endif
+#ifndef QT_NO_SHORTCUT
+ void updateShortcut();
+#endif
+#ifndef QT_NO_SHORTCUT
+ QPointer<QWidget> buddy;
+ int shortcutId;
+#endif
+ ushort align;
+ short indent;
+ uint scaledcontents :1;
+ mutable uint textLayoutDirty : 1;
+ mutable uint textDirty : 1;
+ mutable uint isRichText : 1;
+ mutable uint isTextLabel : 1;
+ mutable uint hasShortcut : 1;
+ Qt::TextFormat textformat;
+ mutable QWidgetTextControl *control;
+ mutable QTextCursor shortcutCursor;
+ Qt::TextInteractionFlags textInteractionFlags;
+
+ inline bool needTextControl() const {
+ return isTextLabel
+ && (isRichText
+ || (!isRichText && (textInteractionFlags & (Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard))));
+ }
+
+ void ensureTextPopulated() const;
+ void ensureTextLayouted() const;
+ void ensureTextControl() const;
+ void sendControlEvent(QEvent *e);
+
+ void _q_linkHovered(const QString &link);
+
+ QRectF layoutRect() const;
+ QRect documentRect() const;
+ QPoint layoutPoint(const QPoint& p) const;
+ Qt::LayoutDirection textDirection() const;
+#ifndef QT_NO_CONTEXTMENU
+ QMenu *createStandardContextMenu(const QPoint &pos);
+#endif
+
+ bool openExternalLinks;
+
+#ifndef QT_NO_CURSOR
+ uint validCursor : 1;
+ uint onAnchor : 1;
+ QCursor cursor;
+#endif
+
+ friend class QMessageBoxPrivate;
+};
+
+QT_END_NAMESPACE
+
+#endif // QLABEL_P_H
diff --git a/src/gui/widgets/qlcdnumber.cpp b/src/widgets/widgets/qlcdnumber.cpp
index 1e034cf3ed..1e034cf3ed 100644
--- a/src/gui/widgets/qlcdnumber.cpp
+++ b/src/widgets/widgets/qlcdnumber.cpp
diff --git a/src/widgets/widgets/qlcdnumber.h b/src/widgets/widgets/qlcdnumber.h
new file mode 100644
index 0000000000..7b104cbfcf
--- /dev/null
+++ b/src/widgets/widgets/qlcdnumber.h
@@ -0,0 +1,144 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QLCDNUMBER_H
+#define QLCDNUMBER_H
+
+#include <QtWidgets/qframe.h>
+#include <QtCore/qbitarray.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_LCDNUMBER
+
+class QLCDNumberPrivate;
+class Q_WIDGETS_EXPORT QLCDNumber : public QFrame // LCD number widget
+{
+ Q_OBJECT
+ Q_ENUMS(Mode SegmentStyle)
+ Q_PROPERTY(bool smallDecimalPoint READ smallDecimalPoint WRITE setSmallDecimalPoint)
+ Q_PROPERTY(int numDigits READ numDigits WRITE setNumDigits)
+ Q_PROPERTY(int digitCount READ digitCount WRITE setDigitCount)
+ Q_PROPERTY(Mode mode READ mode WRITE setMode)
+ Q_PROPERTY(SegmentStyle segmentStyle READ segmentStyle WRITE setSegmentStyle)
+ Q_PROPERTY(double value READ value WRITE display)
+ Q_PROPERTY(int intValue READ intValue WRITE display)
+
+public:
+ explicit QLCDNumber(QWidget* parent = 0);
+ explicit QLCDNumber(uint numDigits, QWidget* parent = 0);
+ ~QLCDNumber();
+
+ enum Mode {
+ Hex, Dec, Oct, Bin
+#if defined(QT3_SUPPORT) && !defined(Q_MOC_RUN)
+ , HEX = Hex, DEC = Dec, OCT = Oct, BIN = Bin
+#endif
+ };
+ enum SegmentStyle {
+ Outline, Filled, Flat
+ };
+
+ bool smallDecimalPoint() const;
+#ifdef QT_DEPRECATED
+ QT_DEPRECATED int numDigits() const;
+ QT_DEPRECATED void setNumDigits(int nDigits);
+#endif
+ int digitCount() const;
+ void setDigitCount(int nDigits);
+
+ bool checkOverflow(double num) const;
+ bool checkOverflow(int num) const;
+
+ Mode mode() const;
+ void setMode(Mode);
+
+ SegmentStyle segmentStyle() const;
+ void setSegmentStyle(SegmentStyle);
+
+ double value() const;
+ int intValue() const;
+
+ QSize sizeHint() const;
+
+public Q_SLOTS:
+ void display(const QString &str);
+ void display(int num);
+ void display(double num);
+ void setHexMode();
+ void setDecMode();
+ void setOctMode();
+ void setBinMode();
+ void setSmallDecimalPoint(bool);
+
+Q_SIGNALS:
+ void overflow();
+
+protected:
+ bool event(QEvent *e);
+ void paintEvent(QPaintEvent *);
+
+public:
+#ifdef QT3_SUPPORT
+ QT3_SUPPORT_CONSTRUCTOR QLCDNumber(QWidget* parent, const char* name);
+ QT3_SUPPORT_CONSTRUCTOR QLCDNumber(uint numDigits, QWidget* parent, const char* name);
+
+ QT3_SUPPORT void setMargin(int margin) { setContentsMargins(margin, margin, margin, margin); }
+ QT3_SUPPORT int margin() const
+ { int margin; int dummy; getContentsMargins(&margin, &dummy, &dummy, &dummy); return margin; }
+#endif
+
+private:
+ Q_DISABLE_COPY(QLCDNumber)
+ Q_DECLARE_PRIVATE(QLCDNumber)
+};
+
+#endif // QT_NO_LCDNUMBER
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QLCDNUMBER_H
diff --git a/src/widgets/widgets/qlineedit.cpp b/src/widgets/widgets/qlineedit.cpp
new file mode 100644
index 0000000000..aca15f30ed
--- /dev/null
+++ b/src/widgets/widgets/qlineedit.cpp
@@ -0,0 +1,2363 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qlineedit.h"
+#include "qlineedit_p.h"
+
+#ifndef QT_NO_LINEEDIT
+#include "qaction.h"
+#include "qapplication.h"
+#include "qclipboard.h"
+#include "qdrag.h"
+#include "qdrawutil.h"
+#include "qevent.h"
+#include "qfontmetrics.h"
+#include "qmenu.h"
+#include "qpainter.h"
+#include "qpixmap.h"
+#include "qpointer.h"
+#include "qstringlist.h"
+#include "qstyle.h"
+#include "qstyleoption.h"
+#include "qtimer.h"
+#include "qvalidator.h"
+#include "qvariant.h"
+#include "qvector.h"
+#include "qwhatsthis.h"
+#include "qdebug.h"
+#include "qtextedit.h"
+#include <private/qtextedit_p.h>
+#ifndef QT_NO_ACCESSIBILITY
+#include "qaccessible.h"
+#endif
+#ifndef QT_NO_IM
+#include "qinputcontext.h"
+#include "qlist.h"
+#endif
+#include "qabstractitemview.h"
+#include "private/qstylesheetstyle_p.h"
+
+#ifndef QT_NO_SHORTCUT
+#include "private/qapplication_p.h"
+#include "private/qshortcutmap_p.h"
+#include "qkeysequence.h"
+#define ACCEL_KEY(k) (!qApp->d_func()->shortcutMap.hasShortcutForKeySequence(k) ? QLatin1Char('\t') + QString(QKeySequence(k)) : QString())
+#else
+#define ACCEL_KEY(k) QString()
+#endif
+
+#include <limits.h>
+#ifdef DrawText
+#undef DrawText
+#endif
+
+QT_BEGIN_NAMESPACE
+
+#ifdef Q_WS_MAC
+extern void qt_mac_secure_keyboard(bool); //qapplication_mac.cpp
+#endif
+
+/*!
+ Initialize \a option with the values from this QLineEdit. This method
+ is useful for subclasses when they need a QStyleOptionFrame or QStyleOptionFrameV2, but don't want
+ to fill in all the information themselves. This function will check the version
+ of the QStyleOptionFrame and fill in the additional values for a
+ QStyleOptionFrameV2.
+
+ \sa QStyleOption::initFrom()
+*/
+void QLineEdit::initStyleOption(QStyleOptionFrame *option) const
+{
+ if (!option)
+ return;
+
+ Q_D(const QLineEdit);
+ option->initFrom(this);
+ option->rect = contentsRect();
+ option->lineWidth = d->frame ? style()->pixelMetric(QStyle::PM_DefaultFrameWidth, option, this)
+ : 0;
+ option->midLineWidth = 0;
+ option->state |= QStyle::State_Sunken;
+ if (d->control->isReadOnly())
+ option->state |= QStyle::State_ReadOnly;
+#ifdef QT_KEYPAD_NAVIGATION
+ if (hasEditFocus())
+ option->state |= QStyle::State_HasEditFocus;
+#endif
+ if (QStyleOptionFrameV2 *optionV2 = qstyleoption_cast<QStyleOptionFrameV2 *>(option))
+ optionV2->features = QStyleOptionFrameV2::None;
+}
+
+/*!
+ \class QLineEdit
+ \brief The QLineEdit widget is a one-line text editor.
+
+ \ingroup basicwidgets
+
+
+ A line edit allows the user to enter and edit a single line of
+ plain text with a useful collection of editing functions,
+ including undo and redo, cut and paste, and drag and drop.
+
+ By changing the echoMode() of a line edit, it can also be used as
+ a "write-only" field, for inputs such as passwords.
+
+ The length of the text can be constrained to maxLength(). The text
+ can be arbitrarily constrained using a validator() or an
+ inputMask(), or both. When switching between a validator and an input mask
+ on the same line edit, it is best to clear the validator or input mask to
+ prevent undefined behavior.
+
+
+ A related class is QTextEdit which allows multi-line, rich text
+ editing.
+
+ You can change the text with setText() or insert(). The text is
+ retrieved with text(); the displayed text (which may be different,
+ see \l{EchoMode}) is retrieved with displayText(). Text can be
+ selected with setSelection() or selectAll(), and the selection can
+ be cut(), copy()ied and paste()d. The text can be aligned with
+ setAlignment().
+
+ When the text changes the textChanged() signal is emitted; when
+ the text changes other than by calling setText() the textEdited()
+ signal is emitted; when the cursor is moved the
+ cursorPositionChanged() signal is emitted; and when the Return or
+ Enter key is pressed the returnPressed() signal is emitted.
+
+ When editing is finished, either because the line edit lost focus
+ or Return/Enter is pressed the editingFinished() signal is
+ emitted.
+
+ Note that if there is a validator set on the line edit, the
+ returnPressed()/editingFinished() signals will only be emitted if
+ the validator returns QValidator::Acceptable.
+
+ By default, QLineEdits have a frame as specified by the Windows
+ and Motif style guides; you can turn it off by calling
+ setFrame(false).
+
+ The default key bindings are described below. The line edit also
+ provides a context menu (usually invoked by a right mouse click)
+ that presents some of these editing options.
+ \target desc
+ \table
+ \header \i Keypress \i Action
+ \row \i Left Arrow \i Moves the cursor one character to the left.
+ \row \i Shift+Left Arrow \i Moves and selects text one character to the left.
+ \row \i Right Arrow \i Moves the cursor one character to the right.
+ \row \i Shift+Right Arrow \i Moves and selects text one character to the right.
+ \row \i Home \i Moves the cursor to the beginning of the line.
+ \row \i End \i Moves the cursor to the end of the line.
+ \row \i Backspace \i Deletes the character to the left of the cursor.
+ \row \i Ctrl+Backspace \i Deletes the word to the left of the cursor.
+ \row \i Delete \i Deletes the character to the right of the cursor.
+ \row \i Ctrl+Delete \i Deletes the word to the right of the cursor.
+ \row \i Ctrl+A \i Select all.
+ \row \i Ctrl+C \i Copies the selected text to the clipboard.
+ \row \i Ctrl+Insert \i Copies the selected text to the clipboard.
+ \row \i Ctrl+K \i Deletes to the end of the line.
+ \row \i Ctrl+V \i Pastes the clipboard text into line edit.
+ \row \i Shift+Insert \i Pastes the clipboard text into line edit.
+ \row \i Ctrl+X \i Deletes the selected text and copies it to the clipboard.
+ \row \i Shift+Delete \i Deletes the selected text and copies it to the clipboard.
+ \row \i Ctrl+Z \i Undoes the last operation.
+ \row \i Ctrl+Y \i Redoes the last undone operation.
+ \endtable
+
+ Any other key sequence that represents a valid character, will
+ cause the character to be inserted into the line edit.
+
+ \table 100%
+ \row \o \inlineimage macintosh-lineedit.png Screenshot of a Macintosh style line edit
+ \o A line edit shown in the \l{Macintosh Style Widget Gallery}{Macintosh widget style}.
+ \row \o \inlineimage windows-lineedit.png Screenshot of a Windows XP style line edit
+ \o A line edit shown in the \l{Windows XP Style Widget Gallery}{Windows XP widget style}.
+ \row \o \inlineimage plastique-lineedit.png Screenshot of a Plastique style line edit
+ \o A line edit shown in the \l{Plastique Style Widget Gallery}{Plastique widget style}.
+ \endtable
+
+ \sa QTextEdit, QLabel, QComboBox, {fowler}{GUI Design Handbook: Field, Entry}, {Line Edits Example}
+*/
+
+
+/*!
+ \fn void QLineEdit::textChanged(const QString &text)
+
+ This signal is emitted whenever the text changes. The \a text
+ argument is the new text.
+
+ Unlike textEdited(), this signal is also emitted when the text is
+ changed programmatically, for example, by calling setText().
+*/
+
+/*!
+ \fn void QLineEdit::textEdited(const QString &text)
+
+ This signal is emitted whenever the text is edited. The \a text
+ argument is the next text.
+
+ Unlike textChanged(), this signal is not emitted when the text is
+ changed programmatically, for example, by calling setText().
+*/
+
+/*!
+ \fn void QLineEdit::cursorPositionChanged(int old, int new)
+
+ This signal is emitted whenever the cursor moves. The previous
+ position is given by \a old, and the new position by \a new.
+
+ \sa setCursorPosition(), cursorPosition()
+*/
+
+/*!
+ \fn void QLineEdit::selectionChanged()
+
+ This signal is emitted whenever the selection changes.
+
+ \sa hasSelectedText(), selectedText()
+*/
+
+/*!
+ Constructs a line edit with no text.
+
+ The maximum text length is set to 32767 characters.
+
+ The \a parent argument is sent to the QWidget constructor.
+
+ \sa setText(), setMaxLength()
+*/
+QLineEdit::QLineEdit(QWidget* parent)
+ : QWidget(*new QLineEditPrivate, parent,0)
+{
+ Q_D(QLineEdit);
+ d->init(QString());
+}
+
+/*!
+ Constructs a line edit containing the text \a contents.
+
+ The cursor position is set to the end of the line and the maximum
+ text length to 32767 characters.
+
+ The \a parent and argument is sent to the QWidget
+ constructor.
+
+ \sa text(), setMaxLength()
+*/
+QLineEdit::QLineEdit(const QString& contents, QWidget* parent)
+ : QWidget(*new QLineEditPrivate, parent, 0)
+{
+ Q_D(QLineEdit);
+ d->init(contents);
+}
+
+
+#ifdef QT3_SUPPORT
+/*!
+ Constructs a line edit with no text.
+
+ The maximum text length is set to 32767 characters.
+
+ The \a parent and \a name arguments are sent to the QWidget constructor.
+
+ \sa setText(), setMaxLength()
+*/
+QLineEdit::QLineEdit(QWidget* parent, const char* name)
+ : QWidget(*new QLineEditPrivate, parent,0)
+{
+ Q_D(QLineEdit);
+ setObjectName(QString::fromAscii(name));
+ d->init(QString());
+}
+
+/*!
+ Constructs a line edit containing the text \a contents.
+
+ The cursor position is set to the end of the line and the maximum
+ text length to 32767 characters.
+
+ The \a parent and \a name arguments are sent to the QWidget
+ constructor.
+
+ \sa text(), setMaxLength()
+*/
+
+QLineEdit::QLineEdit(const QString& contents, QWidget* parent, const char* name)
+ : QWidget(*new QLineEditPrivate, parent, 0)
+{
+ Q_D(QLineEdit);
+ setObjectName(QString::fromAscii(name));
+ d->init(contents);
+}
+
+/*!
+ Constructs a line edit with an input \a inputMask and the text \a
+ contents.
+
+ The cursor position is set to the end of the line and the maximum
+ text length is set to the length of the mask (the number of mask
+ characters and separators).
+
+ The \a parent and \a name arguments are sent to the QWidget
+ constructor.
+
+ \sa setMask() text()
+*/
+QLineEdit::QLineEdit(const QString& contents, const QString &inputMask, QWidget* parent, const char* name)
+ : QWidget(*new QLineEditPrivate, parent, 0)
+{
+ Q_D(QLineEdit);
+ setObjectName(QString::fromAscii(name));
+ d->init(contents);
+ d->control->setInputMask(inputMask);
+ d->control->moveCursor(d->control->nextMaskBlank(contents.length()));
+}
+#endif
+
+/*!
+ Destroys the line edit.
+*/
+
+QLineEdit::~QLineEdit()
+{
+}
+
+
+/*!
+ \property QLineEdit::text
+ \brief the line edit's text
+
+ Setting this property clears the selection, clears the undo/redo
+ history, moves the cursor to the end of the line and resets the
+ \l modified property to false. The text is not validated when
+ inserted with setText().
+
+ The text is truncated to maxLength() length.
+
+ By default, this property contains an empty string.
+
+ \sa insert(), clear()
+*/
+QString QLineEdit::text() const
+{
+ Q_D(const QLineEdit);
+ return d->control->text();
+}
+
+void QLineEdit::setText(const QString& text)
+{
+ Q_D(QLineEdit);
+ d->control->setText(text);
+}
+
+/*!
+ \since 4.7
+
+ \property QLineEdit::placeholderText
+ \brief the line edit's placeholder text
+
+ Setting this property makes the line edit display a grayed-out
+ placeholder text as long as the text() is empty and the widget doesn't
+ have focus.
+
+ By default, this property contains an empty string.
+
+ \sa text()
+*/
+QString QLineEdit::placeholderText() const
+{
+ Q_D(const QLineEdit);
+ return d->placeholderText;
+}
+
+void QLineEdit::setPlaceholderText(const QString& placeholderText)
+{
+ Q_D(QLineEdit);
+ if (d->placeholderText != placeholderText) {
+ d->placeholderText = placeholderText;
+ if (!hasFocus())
+ update();
+ }
+}
+
+/*!
+ \property QLineEdit::displayText
+ \brief the displayed text
+
+ If \l echoMode is \l Normal this returns the same as text(); if
+ \l EchoMode is \l Password or \l PasswordEchoOnEdit it returns a string of asterisks
+ text().length() characters long, e.g. "******"; if \l EchoMode is
+ \l NoEcho returns an empty string, "".
+
+ By default, this property contains an empty string.
+
+ \sa setEchoMode() text() EchoMode
+*/
+
+QString QLineEdit::displayText() const
+{
+ Q_D(const QLineEdit);
+ return d->control->displayText();
+}
+
+
+/*!
+ \property QLineEdit::maxLength
+ \brief the maximum permitted length of the text
+
+ If the text is too long, it is truncated at the limit.
+
+ If truncation occurs any selected text will be unselected, the
+ cursor position is set to 0 and the first part of the string is
+ shown.
+
+ If the line edit has an input mask, the mask defines the maximum
+ string length.
+
+ By default, this property contains a value of 32767.
+
+ \sa inputMask
+*/
+
+int QLineEdit::maxLength() const
+{
+ Q_D(const QLineEdit);
+ return d->control->maxLength();
+}
+
+void QLineEdit::setMaxLength(int maxLength)
+{
+ Q_D(QLineEdit);
+ d->control->setMaxLength(maxLength);
+}
+
+/*!
+ \property QLineEdit::frame
+ \brief whether the line edit draws itself with a frame
+
+ If enabled (the default) the line edit draws itself inside a
+ frame, otherwise the line edit draws itself without any frame.
+*/
+bool QLineEdit::hasFrame() const
+{
+ Q_D(const QLineEdit);
+ return d->frame;
+}
+
+
+void QLineEdit::setFrame(bool enable)
+{
+ Q_D(QLineEdit);
+ d->frame = enable;
+ update();
+ updateGeometry();
+}
+
+
+/*!
+ \enum QLineEdit::EchoMode
+
+ This enum type describes how a line edit should display its
+ contents.
+
+ \value Normal Display characters as they are entered. This is the
+ default.
+ \value NoEcho Do not display anything. This may be appropriate
+ for passwords where even the length of the
+ password should be kept secret.
+ \value Password Display asterisks instead of the characters
+ actually entered.
+ \value PasswordEchoOnEdit Display characters as they are entered
+ while editing otherwise display asterisks.
+
+ \sa setEchoMode() echoMode()
+*/
+
+
+/*!
+ \property QLineEdit::echoMode
+ \brief the line edit's echo mode
+
+ The echo mode determines how the text entered in the line edit is
+ displayed (or echoed) to the user.
+
+ The most common setting is \l Normal, in which the text entered by the
+ user is displayed verbatim, but QLineEdit also supports modes that allow
+ the entered text to be suppressed or obscured: these include \l NoEcho,
+ \l Password and \l PasswordEchoOnEdit.
+
+ The widget's display and the ability to copy or drag the text is
+ affected by this setting.
+
+ By default, this property is set to \l Normal.
+
+ \sa EchoMode displayText()
+*/
+
+QLineEdit::EchoMode QLineEdit::echoMode() const
+{
+ Q_D(const QLineEdit);
+ return (EchoMode) d->control->echoMode();
+}
+
+void QLineEdit::setEchoMode(EchoMode mode)
+{
+ Q_D(QLineEdit);
+ if (mode == (EchoMode)d->control->echoMode())
+ return;
+ Qt::InputMethodHints imHints = inputMethodHints();
+ if (mode == Password || mode == NoEcho) {
+ imHints |= Qt::ImhHiddenText;
+ } else {
+ imHints &= ~Qt::ImhHiddenText;
+ }
+ if (mode != Normal) {
+ imHints |= (Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText);
+ } else {
+ imHints &= ~(Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText);
+ }
+ setInputMethodHints(imHints);
+ d->control->setEchoMode(mode);
+ update();
+#ifdef Q_WS_MAC
+ if (hasFocus())
+ qt_mac_secure_keyboard(mode == Password || mode == NoEcho);
+#endif
+}
+
+
+#ifndef QT_NO_VALIDATOR
+/*!
+ Returns a pointer to the current input validator, or 0 if no
+ validator has been set.
+
+ \sa setValidator()
+*/
+
+const QValidator * QLineEdit::validator() const
+{
+ Q_D(const QLineEdit);
+ return d->control->validator();
+}
+
+/*!
+ Sets this line edit to only accept input that the validator, \a v,
+ will accept. This allows you to place any arbitrary constraints on
+ the text which may be entered.
+
+ If \a v == 0, setValidator() removes the current input validator.
+ The initial setting is to have no input validator (i.e. any input
+ is accepted up to maxLength()).
+
+ \sa validator() QIntValidator QDoubleValidator QRegExpValidator
+*/
+
+void QLineEdit::setValidator(const QValidator *v)
+{
+ Q_D(QLineEdit);
+ d->control->setValidator(v);
+}
+#endif // QT_NO_VALIDATOR
+
+#ifndef QT_NO_COMPLETER
+/*!
+ \since 4.2
+
+ Sets this line edit to provide auto completions from the completer, \a c.
+ The completion mode is set using QCompleter::setCompletionMode().
+
+ To use a QCompleter with a QValidator or QLineEdit::inputMask, you need to
+ ensure that the model provided to QCompleter contains valid entries. You can
+ use the QSortFilterProxyModel to ensure that the QCompleter's model contains
+ only valid entries.
+
+ If \a c == 0, setCompleter() removes the current completer, effectively
+ disabling auto completion.
+
+ \sa QCompleter
+*/
+void QLineEdit::setCompleter(QCompleter *c)
+{
+ Q_D(QLineEdit);
+ if (c == d->control->completer())
+ return;
+ if (d->control->completer()) {
+ disconnect(d->control->completer(), 0, this, 0);
+ d->control->completer()->setWidget(0);
+ if (d->control->completer()->parent() == this)
+ delete d->control->completer();
+ }
+ d->control->setCompleter(c);
+ if (!c)
+ return;
+ if (c->widget() == 0)
+ c->setWidget(this);
+ if (hasFocus()) {
+ QObject::connect(d->control->completer(), SIGNAL(activated(QString)),
+ this, SLOT(setText(QString)));
+ QObject::connect(d->control->completer(), SIGNAL(highlighted(QString)),
+ this, SLOT(_q_completionHighlighted(QString)));
+ }
+}
+
+/*!
+ \since 4.2
+
+ Returns the current QCompleter that provides completions.
+*/
+QCompleter *QLineEdit::completer() const
+{
+ Q_D(const QLineEdit);
+ return d->control->completer();
+}
+
+#endif // QT_NO_COMPLETER
+
+/*!
+ Returns a recommended size for the widget.
+
+ The width returned, in pixels, is usually enough for about 15 to
+ 20 characters.
+*/
+
+QSize QLineEdit::sizeHint() const
+{
+ Q_D(const QLineEdit);
+ ensurePolished();
+ QFontMetrics fm(font());
+ int h = qMax(fm.height(), 14) + 2*d->verticalMargin
+ + d->topTextMargin + d->bottomTextMargin
+ + d->topmargin + d->bottommargin;
+ int w = fm.width(QLatin1Char('x')) * 17 + 2*d->horizontalMargin
+ + d->leftTextMargin + d->rightTextMargin
+ + d->leftmargin + d->rightmargin; // "some"
+ QStyleOptionFrameV2 opt;
+ initStyleOption(&opt);
+ return (style()->sizeFromContents(QStyle::CT_LineEdit, &opt, QSize(w, h).
+ expandedTo(QApplication::globalStrut()), this));
+}
+
+
+/*!
+ Returns a minimum size for the line edit.
+
+ The width returned is enough for at least one character.
+*/
+
+QSize QLineEdit::minimumSizeHint() const
+{
+ Q_D(const QLineEdit);
+ ensurePolished();
+ QFontMetrics fm = fontMetrics();
+ int h = fm.height() + qMax(2*d->verticalMargin, fm.leading())
+ + d->topmargin + d->bottommargin;
+ int w = fm.maxWidth() + d->leftmargin + d->rightmargin;
+ QStyleOptionFrameV2 opt;
+ initStyleOption(&opt);
+ return (style()->sizeFromContents(QStyle::CT_LineEdit, &opt, QSize(w, h).
+ expandedTo(QApplication::globalStrut()), this));
+}
+
+
+/*!
+ \property QLineEdit::cursorPosition
+ \brief the current cursor position for this line edit
+
+ Setting the cursor position causes a repaint when appropriate.
+
+ By default, this property contains a value of 0.
+*/
+
+int QLineEdit::cursorPosition() const
+{
+ Q_D(const QLineEdit);
+ return d->control->cursorPosition();
+}
+
+void QLineEdit::setCursorPosition(int pos)
+{
+ Q_D(QLineEdit);
+ d->control->setCursorPosition(pos);
+}
+
+/*!
+ Returns the cursor position under the point \a pos.
+*/
+// ### What should this do if the point is outside of contentsRect? Currently returns 0.
+int QLineEdit::cursorPositionAt(const QPoint &pos)
+{
+ Q_D(QLineEdit);
+ return d->xToPos(pos.x());
+}
+
+
+#ifdef QT3_SUPPORT
+/*! \obsolete
+
+ Use setText(), setCursorPosition() and setSelection() instead.
+*/
+bool QLineEdit::validateAndSet(const QString &newText, int newPos,
+ int newMarkAnchor, int newMarkDrag)
+{
+ // The suggested functions above in the docs don't seem to validate,
+ // below code tries to mimic previous behaviour.
+ QString oldText = text();
+ setText(newText);
+ if(!hasAcceptableInput()){
+ setText(oldText);
+ return false;
+ }
+ int selstart = qMin(newMarkAnchor, newMarkDrag);
+ int sellength = qAbs(newMarkAnchor - newMarkDrag);
+ if (selstart == newPos) {
+ selstart = qMax(newMarkAnchor, newMarkDrag);
+ sellength = -sellength;
+ }
+ //setSelection also set the position
+ setSelection(selstart, sellength);
+ return true;
+}
+#endif //QT3_SUPPORT
+
+/*!
+ \property QLineEdit::alignment
+ \brief the alignment of the line edit
+
+ Both horizontal and vertical alignment is allowed here, Qt::AlignJustify
+ will map to Qt::AlignLeft.
+
+ By default, this property contains a combination of Qt::AlignLeft and Qt::AlignVCenter.
+
+ \sa Qt::Alignment
+*/
+
+Qt::Alignment QLineEdit::alignment() const
+{
+ Q_D(const QLineEdit);
+ return QFlag(d->alignment);
+}
+
+void QLineEdit::setAlignment(Qt::Alignment alignment)
+{
+ Q_D(QLineEdit);
+ d->alignment = alignment;
+ update();
+}
+
+
+/*!
+ Moves the cursor forward \a steps characters. If \a mark is true
+ each character moved over is added to the selection; if \a mark is
+ false the selection is cleared.
+
+ \sa cursorBackward()
+*/
+
+void QLineEdit::cursorForward(bool mark, int steps)
+{
+ Q_D(QLineEdit);
+ d->control->cursorForward(mark, steps);
+}
+
+
+/*!
+ Moves the cursor back \a steps characters. If \a mark is true each
+ character moved over is added to the selection; if \a mark is
+ false the selection is cleared.
+
+ \sa cursorForward()
+*/
+void QLineEdit::cursorBackward(bool mark, int steps)
+{
+ cursorForward(mark, -steps);
+}
+
+/*!
+ Moves the cursor one word forward. If \a mark is true, the word is
+ also selected.
+
+ \sa cursorWordBackward()
+*/
+void QLineEdit::cursorWordForward(bool mark)
+{
+ Q_D(QLineEdit);
+ d->control->cursorWordForward(mark);
+}
+
+/*!
+ Moves the cursor one word backward. If \a mark is true, the word
+ is also selected.
+
+ \sa cursorWordForward()
+*/
+
+void QLineEdit::cursorWordBackward(bool mark)
+{
+ Q_D(QLineEdit);
+ d->control->cursorWordBackward(mark);
+}
+
+
+/*!
+ If no text is selected, deletes the character to the left of the
+ text cursor and moves the cursor one position to the left. If any
+ text is selected, the cursor is moved to the beginning of the
+ selected text and the selected text is deleted.
+
+ \sa del()
+*/
+void QLineEdit::backspace()
+{
+ Q_D(QLineEdit);
+ d->control->backspace();
+}
+
+/*!
+ If no text is selected, deletes the character to the right of the
+ text cursor. If any text is selected, the cursor is moved to the
+ beginning of the selected text and the selected text is deleted.
+
+ \sa backspace()
+*/
+
+void QLineEdit::del()
+{
+ Q_D(QLineEdit);
+ d->control->del();
+}
+
+/*!
+ Moves the text cursor to the beginning of the line unless it is
+ already there. If \a mark is true, text is selected towards the
+ first position; otherwise, any selected text is unselected if the
+ cursor is moved.
+
+ \sa end()
+*/
+
+void QLineEdit::home(bool mark)
+{
+ Q_D(QLineEdit);
+ d->control->home(mark);
+}
+
+/*!
+ Moves the text cursor to the end of the line unless it is already
+ there. If \a mark is true, text is selected towards the last
+ position; otherwise, any selected text is unselected if the cursor
+ is moved.
+
+ \sa home()
+*/
+
+void QLineEdit::end(bool mark)
+{
+ Q_D(QLineEdit);
+ d->control->end(mark);
+}
+
+
+/*!
+ \property QLineEdit::modified
+ \brief whether the line edit's contents has been modified by the user
+
+ The modified flag is never read by QLineEdit; it has a default value
+ of false and is changed to true whenever the user changes the line
+ edit's contents.
+
+ This is useful for things that need to provide a default value but
+ do not start out knowing what the default should be (perhaps it
+ depends on other fields on the form). Start the line edit without
+ the best default, and when the default is known, if modified()
+ returns false (the user hasn't entered any text), insert the
+ default value.
+
+ Calling setText() resets the modified flag to false.
+*/
+
+bool QLineEdit::isModified() const
+{
+ Q_D(const QLineEdit);
+ return d->control->isModified();
+}
+
+void QLineEdit::setModified(bool modified)
+{
+ Q_D(QLineEdit);
+ d->control->setModified(modified);
+}
+
+
+/*!\fn QLineEdit::clearModified()
+
+Use setModified(false) instead.
+
+ \sa isModified()
+*/
+
+
+/*!
+ \property QLineEdit::hasSelectedText
+ \brief whether there is any text selected
+
+ hasSelectedText() returns true if some or all of the text has been
+ selected by the user; otherwise returns false.
+
+ By default, this property is false.
+
+ \sa selectedText()
+*/
+
+
+bool QLineEdit::hasSelectedText() const
+{
+ Q_D(const QLineEdit);
+ return d->control->hasSelectedText();
+}
+
+/*!
+ \property QLineEdit::selectedText
+ \brief the selected text
+
+ If there is no selected text this property's value is
+ an empty string.
+
+ By default, this property contains an empty string.
+
+ \sa hasSelectedText()
+*/
+
+QString QLineEdit::selectedText() const
+{
+ Q_D(const QLineEdit);
+ return d->control->selectedText();
+}
+
+/*!
+ selectionStart() returns the index of the first selected character in the
+ line edit or -1 if no text is selected.
+
+ \sa selectedText()
+*/
+
+int QLineEdit::selectionStart() const
+{
+ Q_D(const QLineEdit);
+ return d->control->selectionStart();
+}
+
+
+#ifdef QT3_SUPPORT
+
+/*!
+ \fn void QLineEdit::lostFocus()
+
+ This signal is emitted when the line edit has lost focus.
+
+ Use editingFinished() instead
+ \sa editingFinished(), returnPressed()
+*/
+
+/*!
+ Use isModified() instead.
+*/
+bool QLineEdit::edited() const { return isModified(); }
+/*!
+ Use setModified() or setText().
+*/
+void QLineEdit::setEdited(bool on) { setModified(on); }
+
+/*!
+ There exists no equivalent functionality in Qt 4.
+*/
+int QLineEdit::characterAt(int xpos, QChar *chr) const
+{
+ Q_D(const QLineEdit);
+ int pos = d->xToPos(xpos + contentsRect().x() - d->hscroll + d->horizontalMargin);
+ QString txt = d->control->text();
+ if (chr && pos < (int) txt.length())
+ *chr = txt.at(pos);
+ return pos;
+
+}
+
+/*!
+ Use selectedText() and selectionStart() instead.
+*/
+bool QLineEdit::getSelection(int *start, int *end)
+{
+ Q_D(QLineEdit);
+ if (d->control->hasSelectedText() && start && end) {
+ *start = selectionStart();
+ *end = *start + selectedText().length();
+ return true;
+ }
+ return false;
+}
+#endif
+
+
+/*!
+ Selects text from position \a start and for \a length characters.
+ Negative lengths are allowed.
+
+ \sa deselect() selectAll() selectedText()
+*/
+
+void QLineEdit::setSelection(int start, int length)
+{
+ Q_D(QLineEdit);
+ if (start < 0 || start > (int)d->control->text().length()) {
+ qWarning("QLineEdit::setSelection: Invalid start position (%d)", start);
+ return;
+ }
+
+ d->control->setSelection(start, length);
+
+ if (d->control->hasSelectedText()){
+ QStyleOptionFrameV2 opt;
+ initStyleOption(&opt);
+ if (!style()->styleHint(QStyle::SH_BlinkCursorWhenTextSelected, &opt, this))
+ d->setCursorVisible(false);
+ }
+}
+
+
+/*!
+ \property QLineEdit::undoAvailable
+ \brief whether undo is available
+
+ Undo becomes available once the user has modified the text in the line edit.
+
+ By default, this property is false.
+*/
+
+bool QLineEdit::isUndoAvailable() const
+{
+ Q_D(const QLineEdit);
+ return d->control->isUndoAvailable();
+}
+
+/*!
+ \property QLineEdit::redoAvailable
+ \brief whether redo is available
+
+ Redo becomes available once the user has performed one or more undo operations
+ on text in the line edit.
+
+ By default, this property is false.
+*/
+
+bool QLineEdit::isRedoAvailable() const
+{
+ Q_D(const QLineEdit);
+ return d->control->isRedoAvailable();
+}
+
+/*!
+ \property QLineEdit::dragEnabled
+ \brief whether the lineedit starts a drag if the user presses and
+ moves the mouse on some selected text
+
+ Dragging is disabled by default.
+*/
+
+bool QLineEdit::dragEnabled() const
+{
+ Q_D(const QLineEdit);
+ return d->dragEnabled;
+}
+
+void QLineEdit::setDragEnabled(bool b)
+{
+ Q_D(QLineEdit);
+ d->dragEnabled = b;
+}
+
+
+/*!
+ \property QLineEdit::cursorMoveStyle
+ \brief the movement style of cursor in this line edit
+ \since 4.8
+
+ When this property is set to Qt::VisualMoveStyle, the line edit will use visual
+ movement style. Pressing the left arrow key will always cause the cursor to move
+ left, regardless of the text's writing direction. The same behavior applies to
+ right arrow key.
+
+ When the property is Qt::LogicalMoveStyle (the default), within a LTR text block,
+ increase cursor position when pressing left arrow key, decrease cursor position
+ when pressing the right arrow key. If the text block is right to left, the opposite
+ behavior applies.
+*/
+
+Qt::CursorMoveStyle QLineEdit::cursorMoveStyle() const
+{
+ Q_D(const QLineEdit);
+ return d->control->cursorMoveStyle();
+}
+
+void QLineEdit::setCursorMoveStyle(Qt::CursorMoveStyle style)
+{
+ Q_D(QLineEdit);
+ d->control->setCursorMoveStyle(style);
+}
+
+/*!
+ \property QLineEdit::acceptableInput
+ \brief whether the input satisfies the inputMask and the
+ validator.
+
+ By default, this property is true.
+
+ \sa setInputMask(), setValidator()
+*/
+bool QLineEdit::hasAcceptableInput() const
+{
+ Q_D(const QLineEdit);
+ return d->control->hasAcceptableInput();
+}
+
+/*!
+ Sets the margins around the text inside the frame to have the
+ sizes \a left, \a top, \a right, and \a bottom.
+ \since 4.5
+
+ See also getTextMargins().
+*/
+void QLineEdit::setTextMargins(int left, int top, int right, int bottom)
+{
+ Q_D(QLineEdit);
+ d->leftTextMargin = left;
+ d->topTextMargin = top;
+ d->rightTextMargin = right;
+ d->bottomTextMargin = bottom;
+ updateGeometry();
+ update();
+}
+
+/*!
+ \since 4.6
+ Sets the \a margins around the text inside the frame.
+
+ See also textMargins().
+*/
+void QLineEdit::setTextMargins(const QMargins &margins)
+{
+ setTextMargins(margins.left(), margins.top(), margins.right(), margins.bottom());
+}
+
+/*!
+ Returns the widget's text margins for \a left, \a top, \a right, and \a bottom.
+ \since 4.5
+
+ \sa setTextMargins()
+*/
+void QLineEdit::getTextMargins(int *left, int *top, int *right, int *bottom) const
+{
+ Q_D(const QLineEdit);
+ if (left)
+ *left = d->leftTextMargin;
+ if (top)
+ *top = d->topTextMargin;
+ if (right)
+ *right = d->rightTextMargin;
+ if (bottom)
+ *bottom = d->bottomTextMargin;
+}
+
+/*!
+ \since 4.6
+ Returns the widget's text margins.
+
+ \sa setTextMargins()
+*/
+QMargins QLineEdit::textMargins() const
+{
+ Q_D(const QLineEdit);
+ return QMargins(d->leftTextMargin, d->topTextMargin, d->rightTextMargin, d->bottomTextMargin);
+}
+
+/*!
+ \property QLineEdit::inputMask
+ \brief The validation input mask
+
+ If no mask is set, inputMask() returns an empty string.
+
+ Sets the QLineEdit's validation mask. Validators can be used
+ instead of, or in conjunction with masks; see setValidator().
+
+ Unset the mask and return to normal QLineEdit operation by passing
+ an empty string ("") or just calling setInputMask() with no
+ arguments.
+
+ The table below shows the characters that can be used in an input mask.
+ A space character, the default character for a blank, is needed for cases
+ where a character is \e{permitted but not required}.
+
+ \table
+ \header \i Character \i Meaning
+ \row \i \c A \i ASCII alphabetic character required. A-Z, a-z.
+ \row \i \c a \i ASCII alphabetic character permitted but not required.
+ \row \i \c N \i ASCII alphanumeric character required. A-Z, a-z, 0-9.
+ \row \i \c n \i ASCII alphanumeric character permitted but not required.
+ \row \i \c X \i Any character required.
+ \row \i \c x \i Any character permitted but not required.
+ \row \i \c 9 \i ASCII digit required. 0-9.
+ \row \i \c 0 \i ASCII digit permitted but not required.
+ \row \i \c D \i ASCII digit required. 1-9.
+ \row \i \c d \i ASCII digit permitted but not required (1-9).
+ \row \i \c # \i ASCII digit or plus/minus sign permitted but not required.
+ \row \i \c H \i Hexadecimal character required. A-F, a-f, 0-9.
+ \row \i \c h \i Hexadecimal character permitted but not required.
+ \row \i \c B \i Binary character required. 0-1.
+ \row \i \c b \i Binary character permitted but not required.
+ \row \i \c > \i All following alphabetic characters are uppercased.
+ \row \i \c < \i All following alphabetic characters are lowercased.
+ \row \i \c ! \i Switch off case conversion.
+ \row \i \tt{\\} \i Use \tt{\\} to escape the special
+ characters listed above to use them as
+ separators.
+ \endtable
+
+ The mask consists of a string of mask characters and separators,
+ optionally followed by a semicolon and the character used for
+ blanks. The blank characters are always removed from the text
+ after editing.
+
+ Examples:
+ \table
+ \header \i Mask \i Notes
+ \row \i \c 000.000.000.000;_ \i IP address; blanks are \c{_}.
+ \row \i \c HH:HH:HH:HH:HH:HH;_ \i MAC address
+ \row \i \c 0000-00-00 \i ISO Date; blanks are \c space
+ \row \i \c >AAAAA-AAAAA-AAAAA-AAAAA-AAAAA;# \i License number;
+ blanks are \c - and all (alphabetic) characters are converted to
+ uppercase.
+ \endtable
+
+ To get range control (e.g., for an IP address) use masks together
+ with \link setValidator() validators\endlink.
+
+ \sa maxLength
+*/
+QString QLineEdit::inputMask() const
+{
+ Q_D(const QLineEdit);
+ return d->control->inputMask();
+}
+
+void QLineEdit::setInputMask(const QString &inputMask)
+{
+ Q_D(QLineEdit);
+ d->control->setInputMask(inputMask);
+}
+
+/*!
+ Selects all the text (i.e. highlights it) and moves the cursor to
+ the end. This is useful when a default value has been inserted
+ because if the user types before clicking on the widget, the
+ selected text will be deleted.
+
+ \sa setSelection() deselect()
+*/
+
+void QLineEdit::selectAll()
+{
+ Q_D(QLineEdit);
+ d->control->selectAll();
+}
+
+/*!
+ Deselects any selected text.
+
+ \sa setSelection() selectAll()
+*/
+
+void QLineEdit::deselect()
+{
+ Q_D(QLineEdit);
+ d->control->deselect();
+}
+
+
+/*!
+ Deletes any selected text, inserts \a newText, and validates the
+ result. If it is valid, it sets it as the new contents of the line
+ edit.
+
+ \sa setText(), clear()
+*/
+void QLineEdit::insert(const QString &newText)
+{
+// q->resetInputContext(); //#### FIX ME IN QT
+ Q_D(QLineEdit);
+ d->control->insert(newText);
+}
+
+/*!
+ Clears the contents of the line edit.
+
+ \sa setText(), insert()
+*/
+void QLineEdit::clear()
+{
+ Q_D(QLineEdit);
+ resetInputContext();
+ d->control->clear();
+}
+
+/*!
+ Undoes the last operation if undo is \link
+ QLineEdit::undoAvailable available\endlink. Deselects any current
+ selection, and updates the selection start to the current cursor
+ position.
+*/
+void QLineEdit::undo()
+{
+ Q_D(QLineEdit);
+ resetInputContext();
+ d->control->undo();
+}
+
+/*!
+ Redoes the last operation if redo is \link
+ QLineEdit::redoAvailable available\endlink.
+*/
+void QLineEdit::redo()
+{
+ Q_D(QLineEdit);
+ resetInputContext();
+ d->control->redo();
+}
+
+
+/*!
+ \property QLineEdit::readOnly
+ \brief whether the line edit is read only.
+
+ In read-only mode, the user can still copy the text to the
+ clipboard, or drag and drop the text (if echoMode() is \l Normal),
+ but cannot edit it.
+
+ QLineEdit does not show a cursor in read-only mode.
+
+ By default, this property is false.
+
+ \sa setEnabled()
+*/
+
+bool QLineEdit::isReadOnly() const
+{
+ Q_D(const QLineEdit);
+ return d->control->isReadOnly();
+}
+
+void QLineEdit::setReadOnly(bool enable)
+{
+ Q_D(QLineEdit);
+ if (d->control->isReadOnly() != enable) {
+ d->control->setReadOnly(enable);
+ setAttribute(Qt::WA_MacShowFocusRect, !enable);
+ setAttribute(Qt::WA_InputMethodEnabled, d->shouldEnableInputMethod());
+#ifndef QT_NO_CURSOR
+ setCursor(enable ? Qt::ArrowCursor : Qt::IBeamCursor);
+#endif
+ update();
+ }
+}
+
+
+#ifndef QT_NO_CLIPBOARD
+/*!
+ Copies the selected text to the clipboard and deletes it, if there
+ is any, and if echoMode() is \l Normal.
+
+ If the current validator disallows deleting the selected text,
+ cut() will copy without deleting.
+
+ \sa copy() paste() setValidator()
+*/
+
+void QLineEdit::cut()
+{
+ if (hasSelectedText()) {
+ copy();
+ del();
+ }
+}
+
+
+/*!
+ Copies the selected text to the clipboard, if there is any, and if
+ echoMode() is \l Normal.
+
+ \sa cut() paste()
+*/
+
+void QLineEdit::copy() const
+{
+ Q_D(const QLineEdit);
+ d->control->copy();
+}
+
+/*!
+ Inserts the clipboard's text at the cursor position, deleting any
+ selected text, providing the line edit is not \link
+ QLineEdit::readOnly read-only\endlink.
+
+ If the end result would not be acceptable to the current
+ \link setValidator() validator\endlink, nothing happens.
+
+ \sa copy() cut()
+*/
+
+void QLineEdit::paste()
+{
+ Q_D(QLineEdit);
+ d->control->paste();
+}
+
+#endif // !QT_NO_CLIPBOARD
+
+/*! \reimp
+*/
+bool QLineEdit::event(QEvent * e)
+{
+ Q_D(QLineEdit);
+ if (e->type() == QEvent::Timer) {
+ // should be timerEvent, is here for binary compatibility
+ int timerId = ((QTimerEvent*)e)->timerId();
+ if (false) {
+#ifndef QT_NO_DRAGANDDROP
+ } else if (timerId == d->dndTimer.timerId()) {
+ d->drag();
+#endif
+ }
+ else if (timerId == d->tripleClickTimer.timerId())
+ d->tripleClickTimer.stop();
+ } else if (e->type() == QEvent::ContextMenu) {
+#ifndef QT_NO_IM
+ if (d->control->composeMode())
+ return true;
+#endif
+ //d->separate();
+ } else if (e->type() == QEvent::WindowActivate) {
+ QTimer::singleShot(0, this, SLOT(_q_handleWindowActivate()));
+ }else if(e->type() == QEvent::ShortcutOverride){
+ d->control->processEvent(e);
+ } else if (e->type() == QEvent::KeyRelease) {
+ d->control->setCursorBlinkPeriod(QApplication::cursorFlashTime());
+ } else if (e->type() == QEvent::Show) {
+ //In order to get the cursor blinking if QComboBox::setEditable is called when the combobox has focus
+ if (hasFocus()) {
+ d->control->setCursorBlinkPeriod(QApplication::cursorFlashTime());
+ QStyleOptionFrameV2 opt;
+ initStyleOption(&opt);
+ if ((!hasSelectedText() && d->control->preeditAreaText().isEmpty())
+ || style()->styleHint(QStyle::SH_BlinkCursorWhenTextSelected, &opt, this))
+ d->setCursorVisible(true);
+ }
+ }
+
+#ifdef QT_KEYPAD_NAVIGATION
+ if (QApplication::keypadNavigationEnabled()) {
+ if (e->type() == QEvent::EnterEditFocus) {
+ end(false);
+ d->setCursorVisible(true);
+ d->control->setCursorBlinkPeriod(QApplication::cursorFlashTime());
+ } else if (e->type() == QEvent::LeaveEditFocus) {
+ d->setCursorVisible(false);
+ d->control->setCursorBlinkPeriod(0);
+ if (d->control->hasAcceptableInput() || d->control->fixup())
+ emit editingFinished();
+ }
+ }
+#endif
+ return QWidget::event(e);
+}
+
+/*! \reimp
+*/
+void QLineEdit::mousePressEvent(QMouseEvent* e)
+{
+ Q_D(QLineEdit);
+ if (d->sendMouseEventToInputContext(e))
+ return;
+ if (e->button() == Qt::RightButton)
+ return;
+#ifdef QT_KEYPAD_NAVIGATION
+ if (QApplication::keypadNavigationEnabled() && !hasEditFocus()) {
+ setEditFocus(true);
+ // Get the completion list to pop up.
+ if (d->control->completer())
+ d->control->completer()->complete();
+ }
+#endif
+ if (d->tripleClickTimer.isActive() && (e->pos() - d->tripleClick).manhattanLength() <
+ QApplication::startDragDistance()) {
+ selectAll();
+ return;
+ }
+ bool mark = e->modifiers() & Qt::ShiftModifier;
+ int cursor = d->xToPos(e->pos().x());
+#ifndef QT_NO_DRAGANDDROP
+ if (!mark && d->dragEnabled && d->control->echoMode() == Normal &&
+ e->button() == Qt::LeftButton && d->control->inSelection(e->pos().x())) {
+ d->dndPos = e->pos();
+ if (!d->dndTimer.isActive())
+ d->dndTimer.start(QApplication::startDragTime(), this);
+ } else
+#endif
+ {
+ d->control->moveCursor(cursor, mark);
+ }
+}
+
+/*! \reimp
+*/
+void QLineEdit::mouseMoveEvent(QMouseEvent * e)
+{
+ Q_D(QLineEdit);
+ if (d->sendMouseEventToInputContext(e))
+ return;
+
+ if (e->buttons() & Qt::LeftButton) {
+#ifndef QT_NO_DRAGANDDROP
+ if (d->dndTimer.isActive()) {
+ if ((d->dndPos - e->pos()).manhattanLength() > QApplication::startDragDistance())
+ d->drag();
+ } else
+#endif
+ {
+ d->control->moveCursor(d->xToPos(e->pos().x()), true);
+ }
+ }
+}
+
+/*! \reimp
+*/
+void QLineEdit::mouseReleaseEvent(QMouseEvent* e)
+{
+ Q_D(QLineEdit);
+ if (d->sendMouseEventToInputContext(e))
+ return;
+#ifndef QT_NO_DRAGANDDROP
+ if (e->button() == Qt::LeftButton) {
+ if (d->dndTimer.isActive()) {
+ d->dndTimer.stop();
+ deselect();
+ return;
+ }
+ }
+#endif
+#ifndef QT_NO_CLIPBOARD
+ if (QApplication::clipboard()->supportsSelection()) {
+ if (e->button() == Qt::LeftButton) {
+ d->control->copy(QClipboard::Selection);
+ } else if (!d->control->isReadOnly() && e->button() == Qt::MidButton) {
+ deselect();
+ insert(QApplication::clipboard()->text(QClipboard::Selection));
+ }
+ }
+#endif
+
+ if (!isReadOnly() && rect().contains(e->pos()))
+ d->handleSoftwareInputPanel(e->button(), d->clickCausedFocus);
+ d->clickCausedFocus = 0;
+}
+
+/*! \reimp
+*/
+void QLineEdit::mouseDoubleClickEvent(QMouseEvent* e)
+{
+ Q_D(QLineEdit);
+ if (d->sendMouseEventToInputContext(e))
+ return;
+ if (e->button() == Qt::LeftButton) {
+ d->control->selectWordAtPos(d->xToPos(e->pos().x()));
+ d->tripleClickTimer.start(QApplication::doubleClickInterval(), this);
+ d->tripleClick = e->pos();
+ }
+}
+
+/*!
+ \fn void QLineEdit::returnPressed()
+
+ This signal is emitted when the Return or Enter key is pressed.
+ Note that if there is a validator() or inputMask() set on the line
+ edit, the returnPressed() signal will only be emitted if the input
+ follows the inputMask() and the validator() returns
+ QValidator::Acceptable.
+*/
+
+/*!
+ \fn void QLineEdit::editingFinished()
+
+ This signal is emitted when the Return or Enter key is pressed or
+ the line edit loses focus. Note that if there is a validator() or
+ inputMask() set on the line edit and enter/return is pressed, the
+ editingFinished() signal will only be emitted if the input follows
+ the inputMask() and the validator() returns QValidator::Acceptable.
+*/
+
+/*!
+ Converts the given key press \a event into a line edit action.
+
+ If Return or Enter is pressed and the current text is valid (or
+ can be \link QValidator::fixup() made valid\endlink by the
+ validator), the signal returnPressed() is emitted.
+
+ The default key bindings are listed in the class's detailed
+ description.
+*/
+
+void QLineEdit::keyPressEvent(QKeyEvent *event)
+{
+ Q_D(QLineEdit);
+ #ifdef QT_KEYPAD_NAVIGATION
+ bool select = false;
+ switch (event->key()) {
+ case Qt::Key_Select:
+ if (QApplication::keypadNavigationEnabled()) {
+ if (hasEditFocus()) {
+ setEditFocus(false);
+ if (d->control->completer() && d->control->completer()->popup()->isVisible())
+ d->control->completer()->popup()->hide();
+ select = true;
+ }
+ }
+ break;
+ case Qt::Key_Back:
+ case Qt::Key_No:
+ if (!QApplication::keypadNavigationEnabled() || !hasEditFocus()) {
+ event->ignore();
+ return;
+ }
+ break;
+ default:
+ if (QApplication::keypadNavigationEnabled()) {
+ if (!hasEditFocus() && !(event->modifiers() & Qt::ControlModifier)) {
+ if (!event->text().isEmpty() && event->text().at(0).isPrint()
+ && !isReadOnly())
+ setEditFocus(true);
+ else {
+ event->ignore();
+ return;
+ }
+ }
+ }
+ }
+
+
+
+ if (QApplication::keypadNavigationEnabled() && !select && !hasEditFocus()) {
+ setEditFocus(true);
+ if (event->key() == Qt::Key_Select)
+ return; // Just start. No action.
+ }
+#endif
+ d->control->processKeyEvent(event);
+ if (event->isAccepted()) {
+ if (layoutDirection() != d->control->layoutDirection())
+ setLayoutDirection(d->control->layoutDirection());
+ d->control->setCursorBlinkPeriod(0);
+ }
+}
+
+/*!
+ \since 4.4
+
+ Returns a rectangle that includes the lineedit cursor.
+*/
+QRect QLineEdit::cursorRect() const
+{
+ Q_D(const QLineEdit);
+ return d->cursorRect();
+}
+
+/*! \reimp
+ */
+void QLineEdit::inputMethodEvent(QInputMethodEvent *e)
+{
+ Q_D(QLineEdit);
+ if (d->control->isReadOnly()) {
+ e->ignore();
+ return;
+ }
+
+ if (echoMode() == PasswordEchoOnEdit && !d->control->passwordEchoEditing()) {
+ // Clear the edit and reset to normal echo mode while entering input
+ // method data; the echo mode switches back when the edit loses focus.
+ // ### changes a public property, resets current content.
+ d->updatePasswordEchoEditing(true);
+ clear();
+ }
+
+#ifdef QT_KEYPAD_NAVIGATION
+ // Focus in if currently in navigation focus on the widget
+ // Only focus in on preedits, to allow input methods to
+ // commit text as they focus out without interfering with focus
+ if (QApplication::keypadNavigationEnabled()
+ && hasFocus() && !hasEditFocus()
+ && !e->preeditString().isEmpty())
+ setEditFocus(true);
+#endif
+
+ d->control->processInputMethodEvent(e);
+
+#ifndef QT_NO_COMPLETER
+ if (!e->commitString().isEmpty())
+ d->control->complete(Qt::Key_unknown);
+#endif
+}
+
+/*!\reimp
+*/
+QVariant QLineEdit::inputMethodQuery(Qt::InputMethodQuery property) const
+{
+ Q_D(const QLineEdit);
+ switch(property) {
+ case Qt::ImCursorRectangle:
+ return d->cursorRect();
+ case Qt::ImFont:
+ return font();
+ case Qt::ImCursorPosition:
+ return QVariant(d->control->cursor());
+ case Qt::ImSurroundingText:
+ return QVariant(text());
+ case Qt::ImCurrentSelection:
+ return QVariant(selectedText());
+ case Qt::ImMaximumTextLength:
+ return QVariant(maxLength());
+ case Qt::ImAnchorPosition:
+ if (d->control->selectionStart() == d->control->selectionEnd())
+ return QVariant(d->control->cursor());
+ else if (d->control->selectionStart() == d->control->cursor())
+ return QVariant(d->control->selectionEnd());
+ else
+ return QVariant(d->control->selectionStart());
+ default:
+ return QVariant();
+ }
+}
+
+/*!\reimp
+*/
+
+void QLineEdit::focusInEvent(QFocusEvent *e)
+{
+ Q_D(QLineEdit);
+ if (e->reason() == Qt::TabFocusReason ||
+ e->reason() == Qt::BacktabFocusReason ||
+ e->reason() == Qt::ShortcutFocusReason) {
+ if (!d->control->inputMask().isEmpty())
+ d->control->moveCursor(d->control->nextMaskBlank(0));
+ else if (!d->control->hasSelectedText())
+ selectAll();
+ } else if (e->reason() == Qt::MouseFocusReason) {
+ d->clickCausedFocus = 1;
+ }
+#ifdef QT_KEYPAD_NAVIGATION
+ if (!QApplication::keypadNavigationEnabled() || (hasEditFocus() && ( e->reason() == Qt::PopupFocusReason
+#ifdef Q_OS_SYMBIAN
+ || e->reason() == Qt::ActiveWindowFocusReason
+#endif
+ ))) {
+#endif
+ d->control->setCursorBlinkPeriod(QApplication::cursorFlashTime());
+ QStyleOptionFrameV2 opt;
+ initStyleOption(&opt);
+ if((!hasSelectedText() && d->control->preeditAreaText().isEmpty())
+ || style()->styleHint(QStyle::SH_BlinkCursorWhenTextSelected, &opt, this))
+ d->setCursorVisible(true);
+#ifdef Q_WS_MAC
+ if (d->control->echoMode() == Password || d->control->echoMode() == NoEcho)
+ qt_mac_secure_keyboard(true);
+#endif
+#ifdef QT_KEYPAD_NAVIGATION
+ d->control->setCancelText(d->control->text());
+ }
+#endif
+#ifndef QT_NO_COMPLETER
+ if (d->control->completer()) {
+ d->control->completer()->setWidget(this);
+ QObject::connect(d->control->completer(), SIGNAL(activated(QString)),
+ this, SLOT(setText(QString)));
+ QObject::connect(d->control->completer(), SIGNAL(highlighted(QString)),
+ this, SLOT(_q_completionHighlighted(QString)));
+ }
+#endif
+ update();
+}
+
+/*!\reimp
+*/
+
+void QLineEdit::focusOutEvent(QFocusEvent *e)
+{
+ Q_D(QLineEdit);
+ if (d->control->passwordEchoEditing()) {
+ // Reset the echomode back to PasswordEchoOnEdit when the widget loses
+ // focus.
+ d->updatePasswordEchoEditing(false);
+ }
+
+ Qt::FocusReason reason = e->reason();
+ if (reason != Qt::ActiveWindowFocusReason &&
+ reason != Qt::PopupFocusReason)
+ deselect();
+
+ d->setCursorVisible(false);
+ d->control->setCursorBlinkPeriod(0);
+#ifdef QT_KEYPAD_NAVIGATION
+ // editingFinished() is already emitted on LeaveEditFocus
+ if (!QApplication::keypadNavigationEnabled())
+#endif
+ if (reason != Qt::PopupFocusReason
+ || !(QApplication::activePopupWidget() && QApplication::activePopupWidget()->parentWidget() == this)) {
+ if (hasAcceptableInput() || d->control->fixup())
+ emit editingFinished();
+#ifdef QT3_SUPPORT
+ emit lostFocus();
+#endif
+ }
+#ifdef Q_WS_MAC
+ if (d->control->echoMode() == Password || d->control->echoMode() == NoEcho)
+ qt_mac_secure_keyboard(false);
+#endif
+#ifdef QT_KEYPAD_NAVIGATION
+ d->control->setCancelText(QString());
+#endif
+#ifndef QT_NO_COMPLETER
+ if (d->control->completer()) {
+ QObject::disconnect(d->control->completer(), 0, this, 0);
+ }
+#endif
+ update();
+}
+
+/*!\reimp
+*/
+void QLineEdit::paintEvent(QPaintEvent *)
+{
+ Q_D(QLineEdit);
+ QPainter p(this);
+
+ QRect r = rect();
+ QPalette pal = palette();
+
+ QStyleOptionFrameV2 panel;
+ initStyleOption(&panel);
+ style()->drawPrimitive(QStyle::PE_PanelLineEdit, &panel, &p, this);
+ r = style()->subElementRect(QStyle::SE_LineEditContents, &panel, this);
+ r.setX(r.x() + d->leftTextMargin);
+ r.setY(r.y() + d->topTextMargin);
+ r.setRight(r.right() - d->rightTextMargin);
+ r.setBottom(r.bottom() - d->bottomTextMargin);
+ p.setClipRect(r);
+
+ QFontMetrics fm = fontMetrics();
+ Qt::Alignment va = QStyle::visualAlignment(d->control->layoutDirection(), QFlag(d->alignment));
+ switch (va & Qt::AlignVertical_Mask) {
+ case Qt::AlignBottom:
+ d->vscroll = r.y() + r.height() - fm.height() - d->verticalMargin;
+ break;
+ case Qt::AlignTop:
+ d->vscroll = r.y() + d->verticalMargin;
+ break;
+ default:
+ //center
+ d->vscroll = r.y() + (r.height() - fm.height() + 1) / 2;
+ break;
+ }
+ QRect lineRect(r.x() + d->horizontalMargin, d->vscroll, r.width() - 2*d->horizontalMargin, fm.height());
+
+ int minLB = qMax(0, -fm.minLeftBearing());
+ int minRB = qMax(0, -fm.minRightBearing());
+
+ if (d->control->text().isEmpty()) {
+ if (!hasFocus() && !d->placeholderText.isEmpty()) {
+ QColor col = pal.text().color();
+ col.setAlpha(128);
+ QPen oldpen = p.pen();
+ p.setPen(col);
+ lineRect.adjust(minLB, 0, 0, 0);
+ QString elidedText = fm.elidedText(d->placeholderText, Qt::ElideRight, lineRect.width());
+ p.drawText(lineRect, va, elidedText);
+ p.setPen(oldpen);
+ return;
+ }
+ }
+
+ int cix = qRound(d->control->cursorToX());
+
+ // horizontal scrolling. d->hscroll is the left indent from the beginning
+ // of the text line to the left edge of lineRect. we update this value
+ // depending on the delta from the last paint event; in effect this means
+ // the below code handles all scrolling based on the textline (widthUsed,
+ // minLB, minRB), the line edit rect (lineRect) and the cursor position
+ // (cix).
+ int widthUsed = qRound(d->control->naturalTextWidth()) + 1 + minRB;
+ if ((minLB + widthUsed) <= lineRect.width()) {
+ // text fits in lineRect; use hscroll for alignment
+ switch (va & ~(Qt::AlignAbsolute|Qt::AlignVertical_Mask)) {
+ case Qt::AlignRight:
+ d->hscroll = widthUsed - lineRect.width() + 1;
+ break;
+ case Qt::AlignHCenter:
+ d->hscroll = (widthUsed - lineRect.width()) / 2;
+ break;
+ default:
+ // Left
+ d->hscroll = 0;
+ break;
+ }
+ d->hscroll -= minLB;
+ } else if (cix - d->hscroll >= lineRect.width()) {
+ // text doesn't fit, cursor is to the right of lineRect (scroll right)
+ d->hscroll = cix - lineRect.width() + 1;
+ } else if (cix - d->hscroll < 0 && d->hscroll < widthUsed) {
+ // text doesn't fit, cursor is to the left of lineRect (scroll left)
+ d->hscroll = cix;
+ } else if (widthUsed - d->hscroll < lineRect.width()) {
+ // text doesn't fit, text document is to the left of lineRect; align
+ // right
+ d->hscroll = widthUsed - lineRect.width() + 1;
+ } else {
+ //in case the text is bigger than the lineedit, the hscroll can never be negative
+ d->hscroll = qMax(0, d->hscroll);
+ }
+
+ // the y offset is there to keep the baseline constant in case we have script changes in the text.
+ QPoint topLeft = lineRect.topLeft() - QPoint(d->hscroll, d->control->ascent() - fm.ascent());
+
+ // draw text, selections and cursors
+#ifndef QT_NO_STYLE_STYLESHEET
+ if (QStyleSheetStyle* cssStyle = qobject_cast<QStyleSheetStyle*>(style())) {
+ cssStyle->styleSheetPalette(this, &panel, &pal);
+ }
+#endif
+ p.setPen(pal.text().color());
+
+ int flags = QWidgetLineControl::DrawText;
+
+#ifdef QT_KEYPAD_NAVIGATION
+ if (!QApplication::keypadNavigationEnabled() || hasEditFocus())
+#endif
+ if (d->control->hasSelectedText() || (d->cursorVisible && !d->control->inputMask().isEmpty() && !d->control->isReadOnly())){
+ flags |= QWidgetLineControl::DrawSelections;
+ // Palette only used for selections/mask and may not be in sync
+ if (d->control->palette() != pal
+ || d->control->palette().currentColorGroup() != pal.currentColorGroup())
+ d->control->setPalette(pal);
+ }
+
+ // Asian users see an IM selection text as cursor on candidate
+ // selection phase of input method, so the ordinary cursor should be
+ // invisible if we have a preedit string.
+ if (d->cursorVisible && !d->control->isReadOnly())
+ flags |= QWidgetLineControl::DrawCursor;
+
+ d->control->setCursorWidth(style()->pixelMetric(QStyle::PM_TextCursorWidth));
+ d->control->draw(&p, topLeft, r, flags);
+
+}
+
+
+#ifndef QT_NO_DRAGANDDROP
+/*!\reimp
+*/
+void QLineEdit::dragMoveEvent(QDragMoveEvent *e)
+{
+ Q_D(QLineEdit);
+ if (!d->control->isReadOnly() && e->mimeData()->hasFormat(QLatin1String("text/plain"))) {
+ e->acceptProposedAction();
+ d->control->moveCursor(d->xToPos(e->pos().x()), false);
+ d->cursorVisible = true;
+ update();
+ }
+}
+
+/*!\reimp */
+void QLineEdit::dragEnterEvent(QDragEnterEvent * e)
+{
+ QLineEdit::dragMoveEvent(e);
+}
+
+/*!\reimp */
+void QLineEdit::dragLeaveEvent(QDragLeaveEvent *)
+{
+ Q_D(QLineEdit);
+ if (d->cursorVisible) {
+ d->cursorVisible = false;
+ update();
+ }
+}
+
+/*!\reimp */
+void QLineEdit::dropEvent(QDropEvent* e)
+{
+ Q_D(QLineEdit);
+ QString str = e->mimeData()->text();
+
+ if (!str.isNull() && !d->control->isReadOnly()) {
+ if (e->source() == this && e->dropAction() == Qt::CopyAction)
+ deselect();
+ int cursorPos = d->xToPos(e->pos().x());
+ int selStart = cursorPos;
+ int oldSelStart = d->control->selectionStart();
+ int oldSelEnd = d->control->selectionEnd();
+ d->control->moveCursor(cursorPos, false);
+ d->cursorVisible = false;
+ e->acceptProposedAction();
+ insert(str);
+ if (e->source() == this) {
+ if (e->dropAction() == Qt::MoveAction) {
+ if (selStart > oldSelStart && selStart <= oldSelEnd)
+ setSelection(oldSelStart, str.length());
+ else if (selStart > oldSelEnd)
+ setSelection(selStart - str.length(), str.length());
+ else
+ setSelection(selStart, str.length());
+ } else {
+ setSelection(selStart, str.length());
+ }
+ }
+ } else {
+ e->ignore();
+ update();
+ }
+}
+
+#endif // QT_NO_DRAGANDDROP
+
+#ifndef QT_NO_CONTEXTMENU
+/*!
+ Shows the standard context menu created with
+ createStandardContextMenu().
+
+ If you do not want the line edit to have a context menu, you can set
+ its \l contextMenuPolicy to Qt::NoContextMenu. If you want to
+ customize the context menu, reimplement this function. If you want
+ to extend the standard context menu, reimplement this function, call
+ createStandardContextMenu() and extend the menu returned.
+
+ \snippet doc/src/snippets/code/src_gui_widgets_qlineedit.cpp 0
+
+ The \a event parameter is used to obtain the position where
+ the mouse cursor was when the event was generated.
+
+ \sa setContextMenuPolicy()
+*/
+void QLineEdit::contextMenuEvent(QContextMenuEvent *event)
+{
+ if (QMenu *menu = createStandardContextMenu()) {
+ menu->setAttribute(Qt::WA_DeleteOnClose);
+ menu->popup(event->globalPos());
+ }
+}
+
+#if defined(Q_WS_WIN) || defined(Q_WS_X11)
+ extern bool qt_use_rtl_extensions;
+#endif
+
+/*! This function creates the standard context menu which is shown
+ when the user clicks on the line edit with the right mouse
+ button. It is called from the default contextMenuEvent() handler.
+ The popup menu's ownership is transferred to the caller.
+*/
+
+QMenu *QLineEdit::createStandardContextMenu()
+{
+ Q_D(QLineEdit);
+ QMenu *popup = new QMenu(this);
+ popup->setObjectName(QLatin1String("qt_edit_menu"));
+ QAction *action = 0;
+
+ if (!isReadOnly()) {
+ action = popup->addAction(QLineEdit::tr("&Undo") + ACCEL_KEY(QKeySequence::Undo));
+ action->setEnabled(d->control->isUndoAvailable());
+ connect(action, SIGNAL(triggered()), SLOT(undo()));
+
+ action = popup->addAction(QLineEdit::tr("&Redo") + ACCEL_KEY(QKeySequence::Redo));
+ action->setEnabled(d->control->isRedoAvailable());
+ connect(action, SIGNAL(triggered()), SLOT(redo()));
+
+ popup->addSeparator();
+ }
+
+#ifndef QT_NO_CLIPBOARD
+ if (!isReadOnly()) {
+ action = popup->addAction(QLineEdit::tr("Cu&t") + ACCEL_KEY(QKeySequence::Cut));
+ action->setEnabled(!d->control->isReadOnly() && d->control->hasSelectedText()
+ && d->control->echoMode() == QLineEdit::Normal);
+ connect(action, SIGNAL(triggered()), SLOT(cut()));
+ }
+
+ action = popup->addAction(QLineEdit::tr("&Copy") + ACCEL_KEY(QKeySequence::Copy));
+ action->setEnabled(d->control->hasSelectedText()
+ && d->control->echoMode() == QLineEdit::Normal);
+ connect(action, SIGNAL(triggered()), SLOT(copy()));
+
+ if (!isReadOnly()) {
+ action = popup->addAction(QLineEdit::tr("&Paste") + ACCEL_KEY(QKeySequence::Paste));
+ action->setEnabled(!d->control->isReadOnly() && !QApplication::clipboard()->text().isEmpty());
+ connect(action, SIGNAL(triggered()), SLOT(paste()));
+ }
+#endif
+
+ if (!isReadOnly()) {
+ action = popup->addAction(QLineEdit::tr("Delete"));
+ action->setEnabled(!d->control->isReadOnly() && !d->control->text().isEmpty() && d->control->hasSelectedText());
+ connect(action, SIGNAL(triggered()), d->control, SLOT(_q_deleteSelected()));
+ }
+
+ if (!popup->isEmpty())
+ popup->addSeparator();
+
+ action = popup->addAction(QLineEdit::tr("Select All") + ACCEL_KEY(QKeySequence::SelectAll));
+ action->setEnabled(!d->control->text().isEmpty() && !d->control->allSelected());
+ d->selectAllAction = action;
+ connect(action, SIGNAL(triggered()), SLOT(selectAll()));
+
+#if !defined(QT_NO_IM)
+ QInputContext *qic = inputContext();
+ if (qic) {
+ QList<QAction *> imActions = qic->actions();
+ for (int i = 0; i < imActions.size(); ++i)
+ popup->addAction(imActions.at(i));
+ }
+#endif
+
+#if defined(Q_WS_WIN) || defined(Q_WS_X11)
+ if (!d->control->isReadOnly() && qt_use_rtl_extensions) {
+#else
+ if (!d->control->isReadOnly()) {
+#endif
+ popup->addSeparator();
+ QUnicodeControlCharacterMenu *ctrlCharacterMenu = new QUnicodeControlCharacterMenu(this, popup);
+ popup->addMenu(ctrlCharacterMenu);
+ }
+ return popup;
+}
+#endif // QT_NO_CONTEXTMENU
+
+/*! \reimp */
+void QLineEdit::changeEvent(QEvent *ev)
+{
+ Q_D(QLineEdit);
+ switch(ev->type())
+ {
+ case QEvent::ActivationChange:
+ if (!palette().isEqual(QPalette::Active, QPalette::Inactive))
+ update();
+ break;
+ case QEvent::FontChange:
+ d->control->setFont(font());
+ break;
+ case QEvent::StyleChange:
+ {
+ QStyleOptionFrameV2 opt;
+ initStyleOption(&opt);
+ d->control->setPasswordCharacter(style()->styleHint(QStyle::SH_LineEdit_PasswordCharacter, &opt, this));
+ }
+ update();
+ break;
+ default:
+ break;
+ }
+ QWidget::changeEvent(ev);
+}
+
+/*!
+ \fn void QLineEdit::repaintArea(int a, int b)
+
+ Use update() instead.
+*/
+
+/*!
+ \fn void QLineEdit::cursorLeft(bool mark, int steps)
+
+ Use cursorForward() with a negative number of steps instead. For
+ example, cursorForward(mark, -steps).
+*/
+
+/*!
+ \fn void QLineEdit::cursorRight(bool mark, int steps)
+
+ Use cursorForward() instead.
+*/
+
+/*!
+ \fn bool QLineEdit::frame() const
+
+ Use hasFrame() instead.
+*/
+
+/*!
+ \fn void QLineEdit::clearValidator()
+
+ Use setValidator(0) instead.
+*/
+
+/*!
+ \fn bool QLineEdit::hasMarkedText() const
+
+ Use hasSelectedText() instead.
+*/
+
+/*!
+ \fn QString QLineEdit::markedText() const
+
+ Use selectedText() instead.
+*/
+
+/*!
+ \fn void QLineEdit::setFrameRect(QRect)
+ \internal
+*/
+
+/*!
+ \fn QRect QLineEdit::frameRect() const
+ \internal
+*/
+/*!
+ \enum QLineEdit::DummyFrame
+ \internal
+
+ \value Box
+ \value Sunken
+ \value Plain
+ \value Raised
+ \value MShadow
+ \value NoFrame
+ \value Panel
+ \value StyledPanel
+ \value HLine
+ \value VLine
+ \value GroupBoxPanel
+ \value WinPanel
+ \value ToolBarPanel
+ \value MenuBarPanel
+ \value PopupPanel
+ \value LineEditPanel
+ \value TabWidgetPanel
+ \value MShape
+*/
+
+/*!
+ \fn void QLineEdit::setFrameShadow(DummyFrame)
+ \internal
+*/
+
+/*!
+ \fn DummyFrame QLineEdit::frameShadow() const
+ \internal
+*/
+
+/*!
+ \fn void QLineEdit::setFrameShape(DummyFrame)
+ \internal
+*/
+
+/*!
+ \fn DummyFrame QLineEdit::frameShape() const
+ \internal
+*/
+
+/*!
+ \fn void QLineEdit::setFrameStyle(int)
+ \internal
+*/
+
+/*!
+ \fn int QLineEdit::frameStyle() const
+ \internal
+*/
+
+/*!
+ \fn int QLineEdit::frameWidth() const
+ \internal
+*/
+
+/*!
+ \fn void QLineEdit::setLineWidth(int)
+ \internal
+*/
+
+/*!
+ \fn int QLineEdit::lineWidth() const
+ \internal
+*/
+
+/*!
+ \fn void QLineEdit::setMargin(int margin)
+ Sets the width of the margin around the contents of the widget to \a margin.
+
+ Use QWidget::setContentsMargins() instead.
+ \sa margin(), QWidget::setContentsMargins()
+*/
+
+/*!
+ \fn int QLineEdit::margin() const
+ Returns the width of the margin around the contents of the widget.
+
+ Use QWidget::getContentsMargins() instead.
+ \sa setMargin(), QWidget::getContentsMargins()
+*/
+
+/*!
+ \fn void QLineEdit::setMidLineWidth(int)
+ \internal
+*/
+
+/*!
+ \fn int QLineEdit::midLineWidth() const
+ \internal
+*/
+
+QT_END_NAMESPACE
+
+#include "moc_qlineedit.cpp"
+
+#endif // QT_NO_LINEEDIT
diff --git a/src/widgets/widgets/qlineedit.h b/src/widgets/widgets/qlineedit.h
new file mode 100644
index 0000000000..b0971db968
--- /dev/null
+++ b/src/widgets/widgets/qlineedit.h
@@ -0,0 +1,300 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QLINEEDIT_H
+#define QLINEEDIT_H
+
+#include <QtWidgets/qframe.h>
+#include <QtGui/qtextcursor.h>
+#include <QtCore/qstring.h>
+#include <QtCore/qmargins.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_LINEEDIT
+
+class QValidator;
+class QMenu;
+class QLineEditPrivate;
+class QCompleter;
+class QStyleOptionFrame;
+class QAbstractSpinBox;
+class QDateTimeEdit;
+
+class Q_WIDGETS_EXPORT QLineEdit : public QWidget
+{
+ Q_OBJECT
+
+ Q_ENUMS(EchoMode)
+ Q_PROPERTY(QString inputMask READ inputMask WRITE setInputMask)
+ Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged USER true)
+ Q_PROPERTY(int maxLength READ maxLength WRITE setMaxLength)
+ Q_PROPERTY(bool frame READ hasFrame WRITE setFrame)
+ Q_PROPERTY(EchoMode echoMode READ echoMode WRITE setEchoMode)
+ Q_PROPERTY(QString displayText READ displayText)
+ Q_PROPERTY(int cursorPosition READ cursorPosition WRITE setCursorPosition)
+ Q_PROPERTY(Qt::Alignment alignment READ alignment WRITE setAlignment)
+ Q_PROPERTY(bool modified READ isModified WRITE setModified DESIGNABLE false)
+ Q_PROPERTY(bool hasSelectedText READ hasSelectedText)
+ Q_PROPERTY(QString selectedText READ selectedText)
+ Q_PROPERTY(bool dragEnabled READ dragEnabled WRITE setDragEnabled)
+ Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly)
+ Q_PROPERTY(bool undoAvailable READ isUndoAvailable)
+ Q_PROPERTY(bool redoAvailable READ isRedoAvailable)
+ Q_PROPERTY(bool acceptableInput READ hasAcceptableInput)
+ Q_PROPERTY(QString placeholderText READ placeholderText WRITE setPlaceholderText)
+ Q_PROPERTY(Qt::CursorMoveStyle cursorMoveStyle READ cursorMoveStyle WRITE setCursorMoveStyle)
+
+public:
+ explicit QLineEdit(QWidget* parent=0);
+ explicit QLineEdit(const QString &, QWidget* parent=0);
+#ifdef QT3_SUPPORT
+ QT3_SUPPORT_CONSTRUCTOR QLineEdit(QWidget* parent, const char* name);
+ QT3_SUPPORT_CONSTRUCTOR QLineEdit(const QString &, QWidget* parent, const char* name);
+ QT3_SUPPORT_CONSTRUCTOR QLineEdit(const QString &, const QString &, QWidget* parent=0, const char* name=0);
+#endif
+ ~QLineEdit();
+
+ QString text() const;
+
+ QString displayText() const;
+
+ QString placeholderText() const;
+ void setPlaceholderText(const QString &);
+
+ int maxLength() const;
+ void setMaxLength(int);
+
+ void setFrame(bool);
+ bool hasFrame() const;
+
+ enum EchoMode { Normal, NoEcho, Password, PasswordEchoOnEdit };
+ EchoMode echoMode() const;
+ void setEchoMode(EchoMode);
+
+ bool isReadOnly() const;
+ void setReadOnly(bool);
+
+#ifndef QT_NO_VALIDATOR
+ void setValidator(const QValidator *);
+ const QValidator * validator() const;
+#endif
+
+#ifndef QT_NO_COMPLETER
+ void setCompleter(QCompleter *completer);
+ QCompleter *completer() const;
+#endif
+
+ QSize sizeHint() const;
+ QSize minimumSizeHint() const;
+
+ int cursorPosition() const;
+ void setCursorPosition(int);
+ int cursorPositionAt(const QPoint &pos);
+
+ void setAlignment(Qt::Alignment flag);
+ Qt::Alignment alignment() const;
+
+ void cursorForward(bool mark, int steps = 1);
+ void cursorBackward(bool mark, int steps = 1);
+ void cursorWordForward(bool mark);
+ void cursorWordBackward(bool mark);
+ void backspace();
+ void del();
+ void home(bool mark);
+ void end(bool mark);
+
+ bool isModified() const;
+ void setModified(bool);
+
+ void setSelection(int, int);
+ bool hasSelectedText() const;
+ QString selectedText() const;
+ int selectionStart() const;
+
+ bool isUndoAvailable() const;
+ bool isRedoAvailable() const;
+
+ void setDragEnabled(bool b);
+ bool dragEnabled() const;
+
+ void setCursorMoveStyle(Qt::CursorMoveStyle style);
+ Qt::CursorMoveStyle cursorMoveStyle() const;
+
+ QString inputMask() const;
+ void setInputMask(const QString &inputMask);
+ bool hasAcceptableInput() const;
+
+ void setTextMargins(int left, int top, int right, int bottom);
+ void setTextMargins(const QMargins &margins);
+ void getTextMargins(int *left, int *top, int *right, int *bottom) const;
+ QMargins textMargins() const;
+
+public Q_SLOTS:
+ void setText(const QString &);
+ void clear();
+ void selectAll();
+ void undo();
+ void redo();
+#ifndef QT_NO_CLIPBOARD
+ void cut();
+ void copy() const;
+ void paste();
+#endif
+
+public:
+ void deselect();
+ void insert(const QString &);
+#ifndef QT_NO_CONTEXTMENU
+ QMenu *createStandardContextMenu();
+#endif
+
+Q_SIGNALS:
+ void textChanged(const QString &);
+ void textEdited(const QString &);
+ void cursorPositionChanged(int, int);
+ void returnPressed();
+ void editingFinished();
+ void selectionChanged();
+
+protected:
+ void mousePressEvent(QMouseEvent *);
+ void mouseMoveEvent(QMouseEvent *);
+ void mouseReleaseEvent(QMouseEvent *);
+ void mouseDoubleClickEvent(QMouseEvent *);
+ void keyPressEvent(QKeyEvent *);
+ void focusInEvent(QFocusEvent *);
+ void focusOutEvent(QFocusEvent *);
+ void paintEvent(QPaintEvent *);
+#ifndef QT_NO_DRAGANDDROP
+ void dragEnterEvent(QDragEnterEvent *);
+ void dragMoveEvent(QDragMoveEvent *e);
+ void dragLeaveEvent(QDragLeaveEvent *e);
+ void dropEvent(QDropEvent *);
+#endif
+ void changeEvent(QEvent *);
+#ifndef QT_NO_CONTEXTMENU
+ void contextMenuEvent(QContextMenuEvent *);
+#endif
+#ifdef QT3_SUPPORT
+ inline QT3_SUPPORT void repaintArea(int, int) { update(); }
+#endif
+
+ void inputMethodEvent(QInputMethodEvent *);
+ void initStyleOption(QStyleOptionFrame *option) const;
+public:
+ QVariant inputMethodQuery(Qt::InputMethodQuery) const;
+ bool event(QEvent *);
+protected:
+ QRect cursorRect() const;
+
+public:
+#ifdef QT3_SUPPORT
+ inline QT3_SUPPORT void clearModified() { setModified(false); }
+ inline QT3_SUPPORT void cursorLeft(bool mark, int steps = 1) { cursorForward(mark, -steps); }
+ inline QT3_SUPPORT void cursorRight(bool mark, int steps = 1) { cursorForward(mark, steps); }
+ QT3_SUPPORT bool validateAndSet(const QString &, int, int, int);
+ inline QT3_SUPPORT bool frame() const { return hasFrame(); }
+#ifndef QT_NO_VALIDATOR
+ inline QT3_SUPPORT void clearValidator() { setValidator(0); }
+#endif
+ inline QT3_SUPPORT bool hasMarkedText() const { return hasSelectedText(); }
+ inline QT3_SUPPORT QString markedText() const { return selectedText(); }
+ QT3_SUPPORT bool edited() const;
+ QT3_SUPPORT void setEdited(bool);
+ QT3_SUPPORT int characterAt(int, QChar*) const;
+ QT3_SUPPORT bool getSelection(int *, int *);
+
+ QT3_SUPPORT void setFrameRect(QRect) {}
+ QT3_SUPPORT QRect frameRect() const { return QRect(); }
+ enum DummyFrame { Box, Sunken, Plain, Raised, MShadow, NoFrame, Panel, StyledPanel,
+ HLine, VLine, GroupBoxPanel, WinPanel, ToolBarPanel, MenuBarPanel,
+ PopupPanel, LineEditPanel, TabWidgetPanel, MShape };
+ QT3_SUPPORT void setFrameShadow(DummyFrame) {}
+ QT3_SUPPORT DummyFrame frameShadow() const { return Plain; }
+ QT3_SUPPORT void setFrameShape(DummyFrame) {}
+ QT3_SUPPORT DummyFrame frameShape() const { return NoFrame; }
+ QT3_SUPPORT void setFrameStyle(int) {}
+ QT3_SUPPORT int frameStyle() const { return 0; }
+ QT3_SUPPORT int frameWidth() const { return 0; }
+ QT3_SUPPORT void setLineWidth(int) {}
+ QT3_SUPPORT int lineWidth() const { return 0; }
+ QT3_SUPPORT void setMargin(int margin) { setContentsMargins(margin, margin, margin, margin); }
+ QT3_SUPPORT int margin() const
+ { int margin; int dummy; getContentsMargins(&margin, &dummy, &dummy, &dummy); return margin; }
+ QT3_SUPPORT void setMidLineWidth(int) {}
+ QT3_SUPPORT int midLineWidth() const { return 0; }
+
+Q_SIGNALS:
+ QT_MOC_COMPAT void lostFocus();
+#endif
+
+private:
+ friend class QAbstractSpinBox;
+#ifdef QT_KEYPAD_NAVIGATION
+ friend class QDateTimeEdit;
+#endif
+ Q_DISABLE_COPY(QLineEdit)
+ Q_DECLARE_PRIVATE(QLineEdit)
+ Q_PRIVATE_SLOT(d_func(), void _q_handleWindowActivate())
+ Q_PRIVATE_SLOT(d_func(), void _q_textEdited(const QString &))
+ Q_PRIVATE_SLOT(d_func(), void _q_cursorPositionChanged(int, int))
+#ifndef QT_NO_COMPLETER
+ Q_PRIVATE_SLOT(d_func(), void _q_completionHighlighted(QString))
+#endif
+#ifdef QT_KEYPAD_NAVIGATION
+ Q_PRIVATE_SLOT(d_func(), void _q_editFocusChange(bool))
+#endif
+ Q_PRIVATE_SLOT(d_func(), void _q_selectionChanged())
+ Q_PRIVATE_SLOT(d_func(), void _q_updateNeeded(const QRect &))
+};
+
+#endif // QT_NO_LINEEDIT
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QLINEEDIT_H
diff --git a/src/widgets/widgets/qlineedit_p.cpp b/src/widgets/widgets/qlineedit_p.cpp
new file mode 100644
index 0000000000..8511d0c9e5
--- /dev/null
+++ b/src/widgets/widgets/qlineedit_p.cpp
@@ -0,0 +1,293 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qlineedit.h"
+#include "qlineedit_p.h"
+
+#ifndef QT_NO_LINEEDIT
+
+#include "qabstractitemview.h"
+#include "qdrag.h"
+#include "qclipboard.h"
+#ifndef QT_NO_ACCESSIBILITY
+#include "qaccessible.h"
+#endif
+#ifndef QT_NO_IM
+#include "qinputcontext.h"
+#include "qlist.h"
+#endif
+
+QT_BEGIN_NAMESPACE
+
+const int QLineEditPrivate::verticalMargin(1);
+const int QLineEditPrivate::horizontalMargin(2);
+
+QRect QLineEditPrivate::adjustedControlRect(const QRect &rect) const
+{
+ QRect cr = adjustedContentsRect();
+ int cix = cr.x() - hscroll + horizontalMargin;
+ return rect.translated(QPoint(cix, vscroll));
+}
+
+int QLineEditPrivate::xToPos(int x, QTextLine::CursorPosition betweenOrOn) const
+{
+ QRect cr = adjustedContentsRect();
+ x-= cr.x() - hscroll + horizontalMargin;
+ return control->xToPos(x, betweenOrOn);
+}
+
+QRect QLineEditPrivate::cursorRect() const
+{
+ return adjustedControlRect(control->cursorRect());
+}
+
+#ifndef QT_NO_COMPLETER
+
+void QLineEditPrivate::_q_completionHighlighted(QString newText)
+{
+ Q_Q(QLineEdit);
+ if (control->completer()->completionMode() != QCompleter::InlineCompletion) {
+ q->setText(newText);
+ } else {
+ int c = control->cursor();
+ QString text = control->text();
+ q->setText(text.left(c) + newText.mid(c));
+ control->moveCursor(control->end(), false);
+ control->moveCursor(c, true);
+ }
+}
+
+#endif // QT_NO_COMPLETER
+
+void QLineEditPrivate::_q_handleWindowActivate()
+{
+ Q_Q(QLineEdit);
+ if (!q->hasFocus() && control->hasSelectedText())
+ control->deselect();
+}
+
+void QLineEditPrivate::_q_textEdited(const QString &text)
+{
+ Q_Q(QLineEdit);
+ emit q->textEdited(text);
+#ifndef QT_NO_COMPLETER
+ if (control->completer()
+ && control->completer()->completionMode() != QCompleter::InlineCompletion)
+ control->complete(-1); // update the popup on cut/paste/del
+#endif
+}
+
+void QLineEditPrivate::_q_cursorPositionChanged(int from, int to)
+{
+ Q_Q(QLineEdit);
+ q->update();
+ emit q->cursorPositionChanged(from, to);
+}
+
+#ifdef QT_KEYPAD_NAVIGATION
+void QLineEditPrivate::_q_editFocusChange(bool e)
+{
+ Q_Q(QLineEdit);
+ q->setEditFocus(e);
+}
+#endif
+
+void QLineEditPrivate::_q_selectionChanged()
+{
+ Q_Q(QLineEdit);
+ if (!control->text().isEmpty() && control->preeditAreaText().isEmpty()) {
+ QStyleOptionFrameV2 opt;
+ q->initStyleOption(&opt);
+ bool showCursor = control->hasSelectedText() ?
+ q->style()->styleHint(QStyle::SH_BlinkCursorWhenTextSelected, &opt, q):
+ q->hasFocus();
+ setCursorVisible(showCursor);
+ }
+
+ emit q->selectionChanged();
+}
+
+void QLineEditPrivate::_q_updateNeeded(const QRect &rect)
+{
+ q_func()->update(adjustedControlRect(rect));
+}
+
+void QLineEditPrivate::init(const QString& txt)
+{
+ Q_Q(QLineEdit);
+ control = new QWidgetLineControl(txt);
+ control->setParent(q);
+ control->setFont(q->font());
+ QObject::connect(control, SIGNAL(textChanged(QString)),
+ q, SIGNAL(textChanged(QString)));
+ QObject::connect(control, SIGNAL(textEdited(QString)),
+ q, SLOT(_q_textEdited(QString)));
+ QObject::connect(control, SIGNAL(cursorPositionChanged(int,int)),
+ q, SLOT(_q_cursorPositionChanged(int,int)));
+ QObject::connect(control, SIGNAL(selectionChanged()),
+ q, SLOT(_q_selectionChanged()));
+ QObject::connect(control, SIGNAL(accepted()),
+ q, SIGNAL(returnPressed()));
+ QObject::connect(control, SIGNAL(editingFinished()),
+ q, SIGNAL(editingFinished()));
+#ifdef QT_KEYPAD_NAVIGATION
+ QObject::connect(control, SIGNAL(editFocusChange(bool)),
+ q, SLOT(_q_editFocusChange(bool)));
+#endif
+ QObject::connect(control, SIGNAL(cursorPositionChanged(int,int)),
+ q, SLOT(updateMicroFocus()));
+
+ QObject::connect(control, SIGNAL(textChanged(const QString &)),
+ q, SLOT(updateMicroFocus()));
+
+ // for now, going completely overboard with updates.
+ QObject::connect(control, SIGNAL(selectionChanged()),
+ q, SLOT(update()));
+
+ QObject::connect(control, SIGNAL(displayTextChanged(QString)),
+ q, SLOT(update()));
+
+ QObject::connect(control, SIGNAL(updateNeeded(QRect)),
+ q, SLOT(_q_updateNeeded(QRect)));
+
+ QStyleOptionFrameV2 opt;
+ q->initStyleOption(&opt);
+ control->setPasswordCharacter(q->style()->styleHint(QStyle::SH_LineEdit_PasswordCharacter, &opt, q));
+#ifndef QT_NO_CURSOR
+ q->setCursor(Qt::IBeamCursor);
+#endif
+ q->setFocusPolicy(Qt::StrongFocus);
+ q->setAttribute(Qt::WA_InputMethodEnabled);
+ // Specifies that this widget can use more, but is able to survive on
+ // less, horizontal space; and is fixed vertically.
+ q->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed, QSizePolicy::LineEdit));
+ q->setBackgroundRole(QPalette::Base);
+ q->setAttribute(Qt::WA_KeyCompression);
+ q->setMouseTracking(true);
+ q->setAcceptDrops(true);
+
+ q->setAttribute(Qt::WA_MacShowFocusRect);
+}
+
+QRect QLineEditPrivate::adjustedContentsRect() const
+{
+ Q_Q(const QLineEdit);
+ QStyleOptionFrameV2 opt;
+ q->initStyleOption(&opt);
+ QRect r = q->style()->subElementRect(QStyle::SE_LineEditContents, &opt, q);
+ r.setX(r.x() + leftTextMargin);
+ r.setY(r.y() + topTextMargin);
+ r.setRight(r.right() - rightTextMargin);
+ r.setBottom(r.bottom() - bottomTextMargin);
+ return r;
+}
+
+void QLineEditPrivate::setCursorVisible(bool visible)
+{
+ Q_Q(QLineEdit);
+ if ((bool)cursorVisible == visible)
+ return;
+ cursorVisible = visible;
+ if (control->inputMask().isEmpty())
+ q->update(cursorRect());
+ else
+ q->update();
+}
+
+void QLineEditPrivate::updatePasswordEchoEditing(bool editing)
+{
+ Q_Q(QLineEdit);
+ control->updatePasswordEchoEditing(editing);
+ q->setAttribute(Qt::WA_InputMethodEnabled, shouldEnableInputMethod());
+}
+
+/*!
+ This function is not intended as polymorphic usage. Just a shared code
+ fragment that calls QInputContext::mouseHandler for this
+ class.
+*/
+bool QLineEditPrivate::sendMouseEventToInputContext( QMouseEvent *e )
+{
+#if !defined QT_NO_IM
+ Q_Q(QLineEdit);
+ if ( control->composeMode() ) {
+ int tmp_cursor = xToPos(e->pos().x());
+ int mousePos = tmp_cursor - control->cursor();
+ if ( mousePos < 0 || mousePos > control->preeditAreaText().length() ) {
+ mousePos = -1;
+ // don't send move events outside the preedit area
+ if ( e->type() == QEvent::MouseMove )
+ return true;
+ }
+
+ QInputContext *qic = q->inputContext();
+ if ( qic )
+ // may be causing reset() in some input methods
+ qic->mouseHandler(mousePos, e);
+ if (!control->preeditAreaText().isEmpty())
+ return true;
+ }
+#else
+ Q_UNUSED(e);
+#endif
+
+ return false;
+}
+
+#ifndef QT_NO_DRAGANDDROP
+void QLineEditPrivate::drag()
+{
+ Q_Q(QLineEdit);
+ dndTimer.stop();
+ QMimeData *data = new QMimeData;
+ data->setText(control->selectedText());
+ QDrag *drag = new QDrag(q);
+ drag->setMimeData(data);
+ Qt::DropAction action = drag->start();
+ if (action == Qt::MoveAction && !control->isReadOnly() && drag->target() != q)
+ control->removeSelection();
+}
+
+#endif // QT_NO_DRAGANDDROP
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/widgets/widgets/qlineedit_p.h b/src/widgets/widgets/qlineedit_p.h
new file mode 100644
index 0000000000..74717fd2fa
--- /dev/null
+++ b/src/widgets/widgets/qlineedit_p.h
@@ -0,0 +1,155 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QLINEEDIT_P_H
+#define QLINEEDIT_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "QtCore/qglobal.h"
+
+#ifndef QT_NO_LINEEDIT
+#include "private/qwidget_p.h"
+#include "QtWidgets/qlineedit.h"
+#include "QtGui/qtextlayout.h"
+#include "QtWidgets/qstyleoption.h"
+#include "QtCore/qbasictimer.h"
+#include "QtWidgets/qcompleter.h"
+#include "QtCore/qpointer.h"
+#include "QtWidgets/qlineedit.h"
+
+#include "private/qwidgetlinecontrol_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QLineEditPrivate : public QWidgetPrivate
+{
+ Q_DECLARE_PUBLIC(QLineEdit)
+public:
+
+ QLineEditPrivate()
+ : control(0), frame(1), contextMenuEnabled(1), cursorVisible(0),
+ dragEnabled(0), clickCausedFocus(0), hscroll(0), vscroll(0),
+ alignment(Qt::AlignLeading | Qt::AlignVCenter),
+ leftTextMargin(0), topTextMargin(0), rightTextMargin(0), bottomTextMargin(0)
+ {
+ }
+
+ ~QLineEditPrivate()
+ {
+ }
+
+ QWidgetLineControl *control;
+
+#ifndef QT_NO_CONTEXTMENU
+ QPointer<QAction> selectAllAction;
+#endif
+ void init(const QString&);
+
+ QRect adjustedControlRect(const QRect &) const;
+
+ int xToPos(int x, QTextLine::CursorPosition = QTextLine::CursorBetweenCharacters) const;
+ QRect cursorRect() const;
+ void setCursorVisible(bool visible);
+
+ void updatePasswordEchoEditing(bool);
+
+ inline bool shouldEnableInputMethod() const
+ {
+ return !control->isReadOnly();
+ }
+
+ QPoint tripleClick;
+ QBasicTimer tripleClickTimer;
+ uint frame : 1;
+ uint contextMenuEnabled : 1;
+ uint cursorVisible : 1;
+ uint dragEnabled : 1;
+ uint clickCausedFocus : 1;
+ int hscroll;
+ int vscroll;
+ uint alignment;
+ static const int verticalMargin;
+ static const int horizontalMargin;
+
+ bool sendMouseEventToInputContext(QMouseEvent *e);
+
+ QRect adjustedContentsRect() const;
+
+ void _q_handleWindowActivate();
+ void _q_textEdited(const QString &);
+ void _q_cursorPositionChanged(int, int);
+#ifdef QT_KEYPAD_NAVIGATION
+ void _q_editFocusChange(bool);
+#endif
+ void _q_selectionChanged();
+ void _q_updateNeeded(const QRect &);
+#ifndef QT_NO_COMPLETER
+ void _q_completionHighlighted(QString);
+#endif
+#ifndef QT_NO_DRAGANDDROP
+ QPoint dndPos;
+ QBasicTimer dndTimer;
+ void drag();
+#endif
+
+ int leftTextMargin;
+ int topTextMargin;
+ int rightTextMargin;
+ int bottomTextMargin;
+
+ QString placeholderText;
+};
+
+#endif // QT_NO_LINEEDIT
+
+QT_END_NAMESPACE
+
+#endif // QLINEEDIT_P_H
diff --git a/src/widgets/widgets/qmaccocoaviewcontainer_mac.h b/src/widgets/widgets/qmaccocoaviewcontainer_mac.h
new file mode 100644
index 0000000000..48eac4f490
--- /dev/null
+++ b/src/widgets/widgets/qmaccocoaviewcontainer_mac.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCOCOAVIEWCONTAINER_H
+#define QCOCOAVIEWCONTAINER_H
+
+#include <QtWidgets/QWidget>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QMacCocoaViewContainerPrivate;
+
+class Q_WIDGETS_EXPORT QMacCocoaViewContainer : public QWidget
+{
+ Q_OBJECT
+public:
+ QMacCocoaViewContainer(void *cocoaViewToWrap, QWidget *parent = 0);
+ virtual ~QMacCocoaViewContainer();
+
+ void setCocoaView(void *cocoaViewToWrap);
+ void *cocoaView() const;
+
+private:
+ Q_DECLARE_PRIVATE(QMacCocoaViewContainer)
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QCOCOAVIEWCONTAINER_H
diff --git a/src/gui/widgets/qmaccocoaviewcontainer_mac.mm b/src/widgets/widgets/qmaccocoaviewcontainer_mac.mm
index 5bb7a3bbf2..5bb7a3bbf2 100644
--- a/src/gui/widgets/qmaccocoaviewcontainer_mac.mm
+++ b/src/widgets/widgets/qmaccocoaviewcontainer_mac.mm
diff --git a/src/widgets/widgets/qmacnativewidget_mac.h b/src/widgets/widgets/qmacnativewidget_mac.h
new file mode 100644
index 0000000000..935feac58e
--- /dev/null
+++ b/src/widgets/widgets/qmacnativewidget_mac.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMACNATIVEWIDGET_H
+#define QMACNATIVEWIDGET_H
+
+#include <QtWidgets/QWidget>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QMacNativeWidgetPrivate;
+class Q_WIDGETS_EXPORT QMacNativeWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ QMacNativeWidget(void *parentRef = 0);
+ ~QMacNativeWidget();
+
+ QSize sizeHint() const;
+
+protected:
+ bool event(QEvent *ev);
+
+private:
+ Q_DECLARE_PRIVATE(QMacNativeWidget)
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QMACNATIVEWIDGET_H
diff --git a/src/gui/widgets/qmacnativewidget_mac.mm b/src/widgets/widgets/qmacnativewidget_mac.mm
index b3c00d3cc6..b3c00d3cc6 100644
--- a/src/gui/widgets/qmacnativewidget_mac.mm
+++ b/src/widgets/widgets/qmacnativewidget_mac.mm
diff --git a/src/widgets/widgets/qmainwindow.cpp b/src/widgets/widgets/qmainwindow.cpp
new file mode 100644
index 0000000000..b3bd972497
--- /dev/null
+++ b/src/widgets/widgets/qmainwindow.cpp
@@ -0,0 +1,1686 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//#define QT_EXPERIMENTAL_CLIENT_DECORATIONS
+
+#include "qmainwindow.h"
+#include "qmainwindowlayout_p.h"
+
+#ifndef QT_NO_MAINWINDOW
+
+#include "qdockwidget.h"
+#include "qtoolbar.h"
+
+#include <qapplication.h>
+#include <qmenubar.h>
+#include <qstatusbar.h>
+#include <qevent.h>
+#include <qstyle.h>
+#include <qdebug.h>
+#include <qpainter.h>
+
+#include <private/qwidget_p.h>
+#include "qtoolbar_p.h"
+#include "qwidgetanimator_p.h"
+#ifdef Q_WS_MAC
+#include <private/qt_mac_p.h>
+#include <private/qt_cocoa_helpers_mac_p.h>
+QT_BEGIN_NAMESPACE
+extern OSWindowRef qt_mac_window_for(const QWidget *); // qwidget_mac.cpp
+QT_END_NAMESPACE
+#endif
+
+QT_BEGIN_NAMESPACE
+
+class QMainWindowPrivate : public QWidgetPrivate
+{
+ Q_DECLARE_PUBLIC(QMainWindow)
+public:
+ inline QMainWindowPrivate()
+ : layout(0), explicitIconSize(false), toolButtonStyle(Qt::ToolButtonIconOnly)
+#ifdef Q_WS_MAC
+ , useHIToolBar(false)
+ , activateUnifiedToolbarAfterFullScreen(false)
+#endif
+#if !defined(QT_NO_DOCKWIDGET) && !defined(QT_NO_CURSOR)
+ , hasOldCursor(false) , cursorAdjusted(false)
+#endif
+ { }
+ QMainWindowLayout *layout;
+ QSize iconSize;
+ bool explicitIconSize;
+ Qt::ToolButtonStyle toolButtonStyle;
+#ifdef Q_WS_MAC
+ bool useHIToolBar;
+ bool activateUnifiedToolbarAfterFullScreen;
+#endif
+ void init();
+ QList<int> hoverSeparator;
+ QPoint hoverPos;
+
+#if !defined(QT_NO_DOCKWIDGET) && !defined(QT_NO_CURSOR)
+ QCursor separatorCursor(const QList<int> &path) const;
+ void adjustCursor(const QPoint &pos);
+ QCursor oldCursor;
+ uint hasOldCursor : 1;
+ uint cursorAdjusted : 1;
+#endif
+
+ static inline QMainWindowLayout *mainWindowLayout(const QMainWindow *mainWindow)
+ {
+ return mainWindow ? mainWindow->d_func()->layout : static_cast<QMainWindowLayout *>(0);
+ }
+};
+
+QMainWindowLayout *qt_mainwindow_layout(const QMainWindow *mainWindow)
+{
+ return QMainWindowPrivate::mainWindowLayout(mainWindow);
+}
+
+#ifdef QT_EXPERIMENTAL_CLIENT_DECORATIONS
+Q_WIDGETS_EXPORT void qt_setMainWindowTitleWidget(QMainWindow *mainWindow, Qt::DockWidgetArea area, QWidget *widget)
+{
+ QGridLayout *topLayout = qobject_cast<QGridLayout *>(mainWindow->layout());
+ Q_ASSERT(topLayout);
+
+ int row = 0;
+ int column = 0;
+
+ switch (area) {
+ case Qt::LeftDockWidgetArea:
+ row = 1;
+ column = 0;
+ break;
+ case Qt::TopDockWidgetArea:
+ row = 0;
+ column = 1;
+ break;
+ case Qt::BottomDockWidgetArea:
+ row = 2;
+ column = 1;
+ break;
+ case Qt::RightDockWidgetArea:
+ row = 1;
+ column = 2;
+ break;
+ default:
+ Q_ASSERT_X(false, "qt_setMainWindowTitleWidget", "Unknown area");
+ return;
+ }
+
+ if (QLayoutItem *oldItem = topLayout->itemAtPosition(row, column))
+ delete oldItem->widget();
+ topLayout->addWidget(widget, row, column);
+}
+#endif
+
+void QMainWindowPrivate::init()
+{
+ Q_Q(QMainWindow);
+
+#ifdef QT_EXPERIMENTAL_CLIENT_DECORATIONS
+ QGridLayout *topLayout = new QGridLayout(q);
+ topLayout->setContentsMargins(0, 0, 0, 0);
+
+ layout = new QMainWindowLayout(q, topLayout);
+
+ topLayout->addItem(layout, 1, 1);
+#else
+ layout = new QMainWindowLayout(q, 0);
+#endif
+
+ const int metric = q->style()->pixelMetric(QStyle::PM_ToolBarIconSize, 0, q);
+ iconSize = QSize(metric, metric);
+ q->setAttribute(Qt::WA_Hover);
+}
+
+/*
+ The Main Window:
+
+ +----------------------------------------------------------+
+ | Menu Bar |
+ +----------------------------------------------------------+
+ | Tool Bar Area |
+ | +--------------------------------------------------+ |
+ | | Dock Window Area | |
+ | | +------------------------------------------+ | |
+ | | | | | |
+ | | | Central Widget | | |
+ | | | | | |
+ | | | | | |
+ | | | | | |
+ | | | | | |
+ | | | | | |
+ | | | | | |
+ | | | | | |
+ | | | | | |
+ | | | | | |
+ | | | | | |
+ | | +------------------------------------------+ | |
+ | | | |
+ | +--------------------------------------------------+ |
+ | |
+ +----------------------------------------------------------+
+ | Status Bar |
+ +----------------------------------------------------------+
+
+*/
+
+/*!
+ \class QMainWindow
+ \brief The QMainWindow class provides a main application
+ window.
+ \ingroup mainwindow-classes
+
+
+ \tableofcontents
+
+ \section1 Qt Main Window Framework
+
+ A main window provides a framework for building an
+ application's user interface. Qt has QMainWindow and its \l{Main
+ Window and Related Classes}{related classes} for main window
+ management. QMainWindow has its own layout to which you can add
+ \l{QToolBar}s, \l{QDockWidget}s, a
+ QMenuBar, and a QStatusBar. The layout has a center area that can
+ be occupied by any kind of widget. You can see an image of the
+ layout below.
+
+ \image mainwindowlayout.png
+
+ \note Creating a main window without a central widget is not supported.
+ You must have a central widget even if it is just a placeholder.
+
+ \section1 Creating Main Window Components
+
+ A central widget will typically be a standard Qt widget such
+ as a QTextEdit or a QGraphicsView. Custom widgets can also be
+ used for advanced applications. You set the central widget with \c
+ setCentralWidget().
+
+ Main windows have either a single (SDI) or multiple (MDI)
+ document interface. You create MDI applications in Qt by using a
+ QMdiArea as the central widget.
+
+ We will now examine each of the other widgets that can be
+ added to a main window. We give examples on how to create and add
+ them.
+
+ \section2 Creating Menus
+
+ Qt implements menus in QMenu and QMainWindow keeps them in a
+ QMenuBar. \l{QAction}{QAction}s are added to the menus, which
+ display them as menu items.
+
+ You can add new menus to the main window's menu bar by calling
+ \c menuBar(), which returns the QMenuBar for the window, and then
+ add a menu with QMenuBar::addMenu().
+
+ QMainWindow comes with a default menu bar, but you can also
+ set one yourself with \c setMenuBar(). If you wish to implement a
+ custom menu bar (i.e., not use the QMenuBar widget), you can set it
+ with \c setMenuWidget().
+
+ An example of how to create menus follows:
+
+ \snippet examples/mainwindows/application/mainwindow.cpp 26
+
+ The \c createPopupMenu() function creates popup menus when the
+ main window receives context menu events. The default
+ implementation generates a menu with the checkable actions from
+ the dock widgets and toolbars. You can reimplement \c
+ createPopupMenu() for a custom menu.
+
+ \section2 Creating Toolbars
+
+ Toolbars are implemented in the QToolBar class. You add a
+ toolbar to a main window with \c addToolBar().
+
+ You control the initial position of toolbars by assigning them
+ to a specific Qt::ToolBarArea. You can split an area by inserting
+ a toolbar break - think of this as a line break in text editing -
+ with \c addToolBarBreak() or \c insertToolBarBreak(). You can also
+ restrict placement by the user with QToolBar::setAllowedAreas()
+ and QToolBar::setMovable().
+
+ The size of toolbar icons can be retrieved with \c iconSize().
+ The sizes are platform dependent; you can set a fixed size with \c
+ setIconSize(). You can alter the appearance of all tool buttons in
+ the toolbars with \c setToolButtonStyle().
+
+ An example of toolbar creation follows:
+
+ \snippet examples/mainwindows/application/mainwindow.cpp 29
+
+ \section2 Creating Dock Widgets
+
+ Dock widgets are implemented in the QDockWidget class. A dock
+ widget is a window that can be docked into the main window. You
+ add dock widgets to a main window with \c addDockWidget().
+
+ There are four dock widget areas as given by the
+ Qt::DockWidgetArea enum: left, right, top, and bottom. You can
+ specify which dock widget area that should occupy the corners
+ where the areas overlap with \c setCorner(). By default
+ each area can only contain one row (vertical or horizontal) of
+ dock widgets, but if you enable nesting with \c
+ setDockNestingEnabled(), dock widgets can be added in either
+ direction.
+
+ Two dock widgets may also be stacked on top of each other. A
+ QTabBar is then used to select which of the widgets that should be
+ displayed.
+
+ We give an example of how to create and add dock widgets to a
+ main window:
+
+ \snippet doc/src/snippets/mainwindowsnippet.cpp 0
+
+ \section2 The Status Bar
+
+ You can set a status bar with \c setStatusBar(), but one is
+ created the first time \c statusBar() (which returns the main
+ window's status bar) is called. See QStatusBar for information on
+ how to use it.
+
+ \section1 Storing State
+
+ QMainWindow can store the state of its layout with \c
+ saveState(); it can later be retrieved with \c restoreState(). It
+ is the position and size (relative to the size of the main window)
+ of the toolbars and dock widgets that are stored.
+
+ \sa QMenuBar, QToolBar, QStatusBar, QDockWidget, {Application
+ Example}, {Dock Widgets Example}, {MDI Example}, {SDI Example},
+ {Menus Example}
+*/
+
+/*!
+ \fn void QMainWindow::iconSizeChanged(const QSize &iconSize)
+
+ This signal is emitted when the size of the icons used in the
+ window is changed. The new icon size is passed in \a iconSize.
+
+ You can connect this signal to other components to help maintain
+ a consistent appearance for your application.
+
+ \sa setIconSize()
+*/
+
+/*!
+ \fn void QMainWindow::toolButtonStyleChanged(Qt::ToolButtonStyle toolButtonStyle)
+
+ This signal is emitted when the style used for tool buttons in the
+ window is changed. The new style is passed in \a toolButtonStyle.
+
+ You can connect this signal to other components to help maintain
+ a consistent appearance for your application.
+
+ \sa setToolButtonStyle()
+*/
+
+/*!
+ Constructs a QMainWindow with the given \a parent and the specified
+ widget \a flags.
+
+ QMainWindow sets the Qt::Window flag itself, and will hence
+ always be created as a top-level widget.
+ */
+QMainWindow::QMainWindow(QWidget *parent, Qt::WindowFlags flags)
+ : QWidget(*(new QMainWindowPrivate()), parent, flags | Qt::Window)
+{
+ d_func()->init();
+}
+
+#ifdef QT3_SUPPORT
+/*!
+ \obsolete
+ Constructs a QMainWindow with the given \a parent, \a name, and
+ with the specified widget \a flags.
+ */
+QMainWindow::QMainWindow(QWidget *parent, const char *name, Qt::WindowFlags flags)
+ : QWidget(*(new QMainWindowPrivate()), parent, flags | Qt::WType_TopLevel)
+{
+ setObjectName(QString::fromAscii(name));
+ d_func()->init();
+}
+#endif
+
+/*!
+ Destroys the main window.
+ */
+QMainWindow::~QMainWindow()
+{ }
+
+/*! \property QMainWindow::iconSize
+ \brief size of toolbar icons in this mainwindow.
+
+ The default is the default tool bar icon size of the GUI style.
+ Note that the icons used must be at least of this size as the
+ icons are only scaled down.
+*/
+
+/*!
+ \property QMainWindow::dockOptions
+ \brief the docking behavior of QMainWindow
+ \since 4.3
+
+ The default value is AnimatedDocks | AllowTabbedDocks.
+*/
+
+/*!
+ \enum QMainWindow::DockOption
+ \since 4.3
+
+ This enum contains flags that specify the docking behavior of QMainWindow.
+
+ \value AnimatedDocks Identical to the \l animated property.
+
+ \value AllowNestedDocks Identical to the \l dockNestingEnabled property.
+
+ \value AllowTabbedDocks The user can drop one dock widget "on top" of
+ another. The two widgets are stacked and a tab
+ bar appears for selecting which one is visible.
+
+ \value ForceTabbedDocks Each dock area contains a single stack of tabbed
+ dock widgets. In other words, dock widgets cannot
+ be placed next to each other in a dock area. If
+ this option is set, AllowNestedDocks has no effect.
+
+ \value VerticalTabs The two vertical dock areas on the sides of the
+ main window show their tabs vertically. If this
+ option is not set, all dock areas show their tabs
+ at the bottom. Implies AllowTabbedDocks. See also
+ \l setTabPosition().
+
+ These options only control how dock widgets may be dropped in a QMainWindow.
+ They do not re-arrange the dock widgets to conform with the specified
+ options. For this reason they should be set before any dock widgets
+ are added to the main window. Exceptions to this are the AnimatedDocks and
+ VerticalTabs options, which may be set at any time.
+*/
+
+void QMainWindow::setDockOptions(DockOptions opt)
+{
+ Q_D(QMainWindow);
+ d->layout->setDockOptions(opt);
+}
+
+QMainWindow::DockOptions QMainWindow::dockOptions() const
+{
+ Q_D(const QMainWindow);
+ return d->layout->dockOptions;
+}
+
+QSize QMainWindow::iconSize() const
+{ return d_func()->iconSize; }
+
+void QMainWindow::setIconSize(const QSize &iconSize)
+{
+ Q_D(QMainWindow);
+ QSize sz = iconSize;
+ if (!sz.isValid()) {
+ const int metric = style()->pixelMetric(QStyle::PM_ToolBarIconSize, 0, this);
+ sz = QSize(metric, metric);
+ }
+ if (d->iconSize != sz) {
+ d->iconSize = sz;
+ emit iconSizeChanged(d->iconSize);
+ }
+ d->explicitIconSize = iconSize.isValid();
+}
+
+/*! \property QMainWindow::toolButtonStyle
+ \brief style of toolbar buttons in this mainwindow.
+
+ The default is Qt::ToolButtonIconOnly.
+*/
+
+Qt::ToolButtonStyle QMainWindow::toolButtonStyle() const
+{ return d_func()->toolButtonStyle; }
+
+void QMainWindow::setToolButtonStyle(Qt::ToolButtonStyle toolButtonStyle)
+{
+ Q_D(QMainWindow);
+ if (d->toolButtonStyle == toolButtonStyle)
+ return;
+ d->toolButtonStyle = toolButtonStyle;
+ emit toolButtonStyleChanged(d->toolButtonStyle);
+}
+
+#ifndef QT_NO_MENUBAR
+/*!
+ Returns the menu bar for the main window. This function creates
+ and returns an empty menu bar if the menu bar does not exist.
+
+ If you want all windows in a Mac application to share one menu
+ bar, don't use this function to create it, because the menu bar
+ created here will have this QMainWindow as its parent. Instead,
+ you must create a menu bar that does not have a parent, which you
+ can then share among all the Mac windows. Create a parent-less
+ menu bar this way:
+
+ \snippet doc/src/snippets/code/src_gui_widgets_qmenubar.cpp 1
+
+ \sa setMenuBar()
+*/
+QMenuBar *QMainWindow::menuBar() const
+{
+ QMenuBar *menuBar = qobject_cast<QMenuBar *>(layout()->menuBar());
+ if (!menuBar) {
+ QMainWindow *self = const_cast<QMainWindow *>(this);
+ menuBar = new QMenuBar(self);
+ self->setMenuBar(menuBar);
+ }
+ return menuBar;
+}
+
+/*!
+ Sets the menu bar for the main window to \a menuBar.
+
+ Note: QMainWindow takes ownership of the \a menuBar pointer and
+ deletes it at the appropriate time.
+
+ \sa menuBar()
+*/
+void QMainWindow::setMenuBar(QMenuBar *menuBar)
+{
+ QLayout *topLayout = layout();
+
+ if (topLayout->menuBar() && topLayout->menuBar() != menuBar) {
+ // Reparent corner widgets before we delete the old menu bar.
+ QMenuBar *oldMenuBar = qobject_cast<QMenuBar *>(topLayout->menuBar());
+ if (menuBar) {
+ // TopLeftCorner widget.
+ QWidget *cornerWidget = oldMenuBar->cornerWidget(Qt::TopLeftCorner);
+ if (cornerWidget)
+ menuBar->setCornerWidget(cornerWidget, Qt::TopLeftCorner);
+ // TopRightCorner widget.
+ cornerWidget = oldMenuBar->cornerWidget(Qt::TopRightCorner);
+ if (cornerWidget)
+ menuBar->setCornerWidget(cornerWidget, Qt::TopRightCorner);
+ }
+ oldMenuBar->hide();
+ oldMenuBar->deleteLater();
+ }
+ topLayout->setMenuBar(menuBar);
+}
+
+/*!
+ \since 4.2
+
+ Returns the menu bar for the main window. This function returns
+ null if a menu bar hasn't been constructed yet.
+*/
+QWidget *QMainWindow::menuWidget() const
+{
+ QWidget *menuBar = d_func()->layout->menuBar();
+ return menuBar;
+}
+
+/*!
+ \since 4.2
+
+ Sets the menu bar for the main window to \a menuBar.
+
+ QMainWindow takes ownership of the \a menuBar pointer and
+ deletes it at the appropriate time.
+*/
+void QMainWindow::setMenuWidget(QWidget *menuBar)
+{
+ Q_D(QMainWindow);
+ if (d->layout->menuBar() && d->layout->menuBar() != menuBar) {
+ d->layout->menuBar()->hide();
+ d->layout->menuBar()->deleteLater();
+ }
+ d->layout->setMenuBar(menuBar);
+}
+#endif // QT_NO_MENUBAR
+
+#ifndef QT_NO_STATUSBAR
+/*!
+ Returns the status bar for the main window. This function creates
+ and returns an empty status bar if the status bar does not exist.
+
+ \sa setStatusBar()
+*/
+QStatusBar *QMainWindow::statusBar() const
+{
+ QStatusBar *statusbar = d_func()->layout->statusBar();
+ if (!statusbar) {
+ QMainWindow *self = const_cast<QMainWindow *>(this);
+ statusbar = new QStatusBar(self);
+ statusbar->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed);
+ self->setStatusBar(statusbar);
+ }
+ return statusbar;
+}
+
+/*!
+ Sets the status bar for the main window to \a statusbar.
+
+ Setting the status bar to 0 will remove it from the main window.
+ Note that QMainWindow takes ownership of the \a statusbar pointer
+ and deletes it at the appropriate time.
+
+ \sa statusBar()
+*/
+void QMainWindow::setStatusBar(QStatusBar *statusbar)
+{
+ Q_D(QMainWindow);
+ if (d->layout->statusBar() && d->layout->statusBar() != statusbar) {
+ d->layout->statusBar()->hide();
+ d->layout->statusBar()->deleteLater();
+ }
+ d->layout->setStatusBar(statusbar);
+}
+#endif // QT_NO_STATUSBAR
+
+/*!
+ Returns the central widget for the main window. This function
+ returns zero if the central widget has not been set.
+
+ \sa setCentralWidget()
+*/
+QWidget *QMainWindow::centralWidget() const
+{ return d_func()->layout->centralWidget(); }
+
+/*!
+ Sets the given \a widget to be the main window's central widget.
+
+ Note: QMainWindow takes ownership of the \a widget pointer and
+ deletes it at the appropriate time.
+
+ \sa centralWidget()
+*/
+void QMainWindow::setCentralWidget(QWidget *widget)
+{
+ Q_D(QMainWindow);
+ if (d->layout->centralWidget() && d->layout->centralWidget() != widget) {
+ d->layout->centralWidget()->hide();
+ d->layout->centralWidget()->deleteLater();
+ }
+ d->layout->setCentralWidget(widget);
+}
+
+#ifndef QT_NO_DOCKWIDGET
+/*!
+ Sets the given dock widget \a area to occupy the specified \a
+ corner.
+
+ \sa corner()
+*/
+void QMainWindow::setCorner(Qt::Corner corner, Qt::DockWidgetArea area)
+{
+ bool valid = false;
+ switch (corner) {
+ case Qt::TopLeftCorner:
+ valid = (area == Qt::TopDockWidgetArea || area == Qt::LeftDockWidgetArea);
+ break;
+ case Qt::TopRightCorner:
+ valid = (area == Qt::TopDockWidgetArea || area == Qt::RightDockWidgetArea);
+ break;
+ case Qt::BottomLeftCorner:
+ valid = (area == Qt::BottomDockWidgetArea || area == Qt::LeftDockWidgetArea);
+ break;
+ case Qt::BottomRightCorner:
+ valid = (area == Qt::BottomDockWidgetArea || area == Qt::RightDockWidgetArea);
+ break;
+ }
+ if (!valid)
+ qWarning("QMainWindow::setCorner(): 'area' is not valid for 'corner'");
+ else
+ d_func()->layout->setCorner(corner, area);
+}
+
+/*!
+ Returns the dock widget area that occupies the specified \a
+ corner.
+
+ \sa setCorner()
+*/
+Qt::DockWidgetArea QMainWindow::corner(Qt::Corner corner) const
+{ return d_func()->layout->corner(corner); }
+#endif
+
+#ifndef QT_NO_TOOLBAR
+
+static bool checkToolBarArea(Qt::ToolBarArea area, const char *where)
+{
+ switch (area) {
+ case Qt::LeftToolBarArea:
+ case Qt::RightToolBarArea:
+ case Qt::TopToolBarArea:
+ case Qt::BottomToolBarArea:
+ return true;
+ default:
+ break;
+ }
+ qWarning("%s: invalid 'area' argument", where);
+ return false;
+}
+
+/*!
+ Adds a toolbar break to the given \a area after all the other
+ objects that are present.
+*/
+void QMainWindow::addToolBarBreak(Qt::ToolBarArea area)
+{
+ if (!checkToolBarArea(area, "QMainWindow::addToolBarBreak"))
+ return;
+ d_func()->layout->addToolBarBreak(area);
+}
+
+/*!
+ Inserts a toolbar break before the toolbar specified by \a before.
+*/
+void QMainWindow::insertToolBarBreak(QToolBar *before)
+{ d_func()->layout->insertToolBarBreak(before); }
+
+/*!
+ Removes a toolbar break previously inserted before the toolbar specified by \a before.
+*/
+
+void QMainWindow::removeToolBarBreak(QToolBar *before)
+{
+ Q_D(QMainWindow);
+ d->layout->removeToolBarBreak(before);
+}
+
+/*!
+ Adds the \a toolbar into the specified \a area in this main
+ window. The \a toolbar is placed at the end of the current tool
+ bar block (i.e. line). If the main window already manages \a toolbar
+ then it will only move the toolbar to \a area.
+
+ \sa insertToolBar() addToolBarBreak() insertToolBarBreak()
+*/
+void QMainWindow::addToolBar(Qt::ToolBarArea area, QToolBar *toolbar)
+{
+ if (!checkToolBarArea(area, "QMainWindow::addToolBar"))
+ return;
+
+ Q_D(QMainWindow);
+
+ disconnect(this, SIGNAL(iconSizeChanged(QSize)),
+ toolbar, SLOT(_q_updateIconSize(QSize)));
+ disconnect(this, SIGNAL(toolButtonStyleChanged(Qt::ToolButtonStyle)),
+ toolbar, SLOT(_q_updateToolButtonStyle(Qt::ToolButtonStyle)));
+
+ if(toolbar->d_func()->state && toolbar->d_func()->state->dragging) {
+ //removing a toolbar which is dragging will cause crash
+#ifndef QT_NO_DOCKWIDGET
+ bool animated = isAnimated();
+ setAnimated(false);
+#endif
+ toolbar->d_func()->endDrag();
+#ifndef QT_NO_DOCKWIDGET
+ setAnimated(animated);
+#endif
+ }
+
+ if (!d->layout->usesHIToolBar(toolbar)) {
+ d->layout->removeWidget(toolbar);
+ } else {
+ d->layout->removeToolBar(toolbar);
+ }
+
+ toolbar->d_func()->_q_updateIconSize(d->iconSize);
+ toolbar->d_func()->_q_updateToolButtonStyle(d->toolButtonStyle);
+ connect(this, SIGNAL(iconSizeChanged(QSize)),
+ toolbar, SLOT(_q_updateIconSize(QSize)));
+ connect(this, SIGNAL(toolButtonStyleChanged(Qt::ToolButtonStyle)),
+ toolbar, SLOT(_q_updateToolButtonStyle(Qt::ToolButtonStyle)));
+
+ d->layout->addToolBar(area, toolbar);
+}
+
+/*! \overload
+ Equivalent of calling addToolBar(Qt::TopToolBarArea, \a toolbar)
+*/
+void QMainWindow::addToolBar(QToolBar *toolbar)
+{ addToolBar(Qt::TopToolBarArea, toolbar); }
+
+/*!
+ \overload
+
+ Creates a QToolBar object, setting its window title to \a title,
+ and inserts it into the top toolbar area.
+
+ \sa setWindowTitle()
+*/
+QToolBar *QMainWindow::addToolBar(const QString &title)
+{
+ QToolBar *toolBar = new QToolBar(this);
+ toolBar->setWindowTitle(title);
+ addToolBar(toolBar);
+ return toolBar;
+}
+
+/*!
+ Inserts the \a toolbar into the area occupied by the \a before toolbar
+ so that it appears before it. For example, in normal left-to-right
+ layout operation, this means that \a toolbar will appear to the left
+ of the toolbar specified by \a before in a horizontal toolbar area.
+
+ \sa insertToolBarBreak() addToolBar() addToolBarBreak()
+*/
+void QMainWindow::insertToolBar(QToolBar *before, QToolBar *toolbar)
+{
+ Q_D(QMainWindow);
+
+ d->layout->removeToolBar(toolbar);
+
+ toolbar->d_func()->_q_updateIconSize(d->iconSize);
+ toolbar->d_func()->_q_updateToolButtonStyle(d->toolButtonStyle);
+ connect(this, SIGNAL(iconSizeChanged(QSize)),
+ toolbar, SLOT(_q_updateIconSize(QSize)));
+ connect(this, SIGNAL(toolButtonStyleChanged(Qt::ToolButtonStyle)),
+ toolbar, SLOT(_q_updateToolButtonStyle(Qt::ToolButtonStyle)));
+
+ d->layout->insertToolBar(before, toolbar);
+}
+
+/*!
+ Removes the \a toolbar from the main window layout and hides
+ it. Note that the \a toolbar is \e not deleted.
+*/
+void QMainWindow::removeToolBar(QToolBar *toolbar)
+{
+ if (toolbar) {
+ d_func()->layout->removeToolBar(toolbar);
+ toolbar->hide();
+ }
+}
+
+/*!
+ Returns the Qt::ToolBarArea for \a toolbar. If \a toolbar has not
+ been added to the main window, this function returns \c
+ Qt::NoToolBarArea.
+
+ \sa addToolBar() addToolBarBreak() Qt::ToolBarArea
+*/
+Qt::ToolBarArea QMainWindow::toolBarArea(QToolBar *toolbar) const
+{ return d_func()->layout->toolBarArea(toolbar); }
+
+/*!
+
+ Returns whether there is a toolbar
+ break before the \a toolbar.
+
+ \sa addToolBarBreak(), insertToolBarBreak()
+*/
+bool QMainWindow::toolBarBreak(QToolBar *toolbar) const
+{
+ return d_func()->layout->toolBarBreak(toolbar);
+}
+
+#endif // QT_NO_TOOLBAR
+
+#ifndef QT_NO_DOCKWIDGET
+
+/*! \property QMainWindow::animated
+ \brief whether manipulating dock widgets and tool bars is animated
+ \since 4.2
+
+ When a dock widget or tool bar is dragged over the
+ main window, the main window adjusts its contents
+ to indicate where the dock widget or tool bar will
+ be docked if it is dropped. Setting this property
+ causes QMainWindow to move its contents in a smooth
+ animation. Clearing this property causes the contents
+ to snap into their new positions.
+
+ By default, this property is set. It may be cleared if
+ the main window contains widgets which are slow at resizing
+ or repainting themselves.
+
+ Setting this property is identical to setting the AnimatedDocks
+ option using setDockOptions().
+*/
+
+bool QMainWindow::isAnimated() const
+{
+ Q_D(const QMainWindow);
+ return d->layout->dockOptions & AnimatedDocks;
+}
+
+void QMainWindow::setAnimated(bool enabled)
+{
+ Q_D(QMainWindow);
+
+ DockOptions opts = d->layout->dockOptions;
+ if (enabled)
+ opts |= AnimatedDocks;
+ else
+ opts &= ~AnimatedDocks;
+
+ d->layout->setDockOptions(opts);
+}
+
+/*! \property QMainWindow::dockNestingEnabled
+ \brief whether docks can be nested
+ \since 4.2
+
+ If this property is false, dock areas can only contain a single row
+ (horizontal or vertical) of dock widgets. If this property is true,
+ the area occupied by a dock widget can be split in either direction to contain
+ more dock widgets.
+
+ Dock nesting is only necessary in applications that contain a lot of
+ dock widgets. It gives the user greater freedom in organizing their
+ main window. However, dock nesting leads to more complex
+ (and less intuitive) behavior when a dock widget is dragged over the
+ main window, since there are more ways in which a dropped dock widget
+ may be placed in the dock area.
+
+ Setting this property is identical to setting the AllowNestedDocks option
+ using setDockOptions().
+*/
+
+bool QMainWindow::isDockNestingEnabled() const
+{
+ Q_D(const QMainWindow);
+ return d->layout->dockOptions & AllowNestedDocks;
+}
+
+void QMainWindow::setDockNestingEnabled(bool enabled)
+{
+ Q_D(QMainWindow);
+
+ DockOptions opts = d->layout->dockOptions;
+ if (enabled)
+ opts |= AllowNestedDocks;
+ else
+ opts &= ~AllowNestedDocks;
+
+ d->layout->setDockOptions(opts);
+}
+
+#if 0
+/*! \property QMainWindow::verticalTabsEnabled
+ \brief whether left and right dock areas use vertical tabs
+ \since 4.2
+
+ If this property is set to false, dock areas containing tabbed dock widgets
+ display horizontal tabs, simmilar to Visual Studio.
+
+ If this property is set to true, then the right and left dock areas display vertical
+ tabs, simmilar to KDevelop.
+
+ This property should be set before any dock widgets are added to the main window.
+*/
+
+bool QMainWindow::verticalTabsEnabled() const
+{
+ return d_func()->layout->verticalTabsEnabled();
+}
+
+void QMainWindow::setVerticalTabsEnabled(bool enabled)
+{
+ d_func()->layout->setVerticalTabsEnabled(enabled);
+}
+#endif
+
+static bool checkDockWidgetArea(Qt::DockWidgetArea area, const char *where)
+{
+ switch (area) {
+ case Qt::LeftDockWidgetArea:
+ case Qt::RightDockWidgetArea:
+ case Qt::TopDockWidgetArea:
+ case Qt::BottomDockWidgetArea:
+ return true;
+ default:
+ break;
+ }
+ qWarning("%s: invalid 'area' argument", where);
+ return false;
+}
+
+#ifndef QT_NO_TABBAR
+/*!
+ \property QMainWindow::documentMode
+ \brief whether the tab bar for tabbed dockwidgets is set to document mode.
+ \since 4.5
+
+ The default is false.
+
+ \sa QTabBar::documentMode
+*/
+bool QMainWindow::documentMode() const
+{
+ return d_func()->layout->documentMode();
+}
+
+void QMainWindow::setDocumentMode(bool enabled)
+{
+ d_func()->layout->setDocumentMode(enabled);
+}
+#endif // QT_NO_TABBAR
+
+#ifndef QT_NO_TABWIDGET
+/*!
+ \property QMainWindow::tabShape
+ \brief the tab shape used for tabbed dock widgets.
+ \since 4.5
+
+ The default is \l QTabWidget::Rounded.
+
+ \sa setTabPosition()
+*/
+QTabWidget::TabShape QMainWindow::tabShape() const
+{
+ return d_func()->layout->tabShape();
+}
+
+void QMainWindow::setTabShape(QTabWidget::TabShape tabShape)
+{
+ d_func()->layout->setTabShape(tabShape);
+}
+
+/*!
+ \since 4.5
+
+ Returns the tab position for \a area.
+
+ \note The \l VerticalTabs dock option overrides the tab positions returned
+ by this function.
+
+ \sa setTabPosition(), tabShape()
+*/
+QTabWidget::TabPosition QMainWindow::tabPosition(Qt::DockWidgetArea area) const
+{
+ if (!checkDockWidgetArea(area, "QMainWindow::tabPosition"))
+ return QTabWidget::South;
+ return d_func()->layout->tabPosition(area);
+}
+
+/*!
+ \since 4.5
+
+ Sets the tab position for the given dock widget \a areas to the specified
+ \a tabPosition. By default, all dock areas show their tabs at the bottom.
+
+ \note The \l VerticalTabs dock option overrides the tab positions set by
+ this method.
+
+ \sa tabPosition(), setTabShape()
+*/
+void QMainWindow::setTabPosition(Qt::DockWidgetAreas areas, QTabWidget::TabPosition tabPosition)
+{
+ d_func()->layout->setTabPosition(areas, tabPosition);
+}
+#endif // QT_NO_TABWIDGET
+
+/*!
+ Adds the given \a dockwidget to the specified \a area.
+*/
+void QMainWindow::addDockWidget(Qt::DockWidgetArea area, QDockWidget *dockwidget)
+{
+ if (!checkDockWidgetArea(area, "QMainWindow::addDockWidget"))
+ return;
+
+ Qt::Orientation orientation = Qt::Vertical;
+ switch (area) {
+ case Qt::TopDockWidgetArea:
+ case Qt::BottomDockWidgetArea:
+ orientation = Qt::Horizontal;
+ break;
+ default:
+ break;
+ }
+ d_func()->layout->removeWidget(dockwidget); // in case it was already in here
+ addDockWidget(area, dockwidget, orientation);
+
+#ifdef Q_WS_MAC //drawer support
+ QMacCocoaAutoReleasePool pool;
+ extern bool qt_mac_is_macdrawer(const QWidget *); //qwidget_mac.cpp
+ if (qt_mac_is_macdrawer(dockwidget)) {
+ extern bool qt_mac_set_drawer_preferred_edge(QWidget *, Qt::DockWidgetArea); //qwidget_mac.cpp
+ window()->createWinId();
+ dockwidget->window()->createWinId();
+ qt_mac_set_drawer_preferred_edge(dockwidget, area);
+ if (dockwidget->isVisible()) {
+ dockwidget->hide();
+ dockwidget->show();
+ }
+ }
+#endif
+}
+
+/*!
+ Restores the state of \a dockwidget if it is created after the call
+ to restoreState(). Returns true if the state was restored; otherwise
+ returns false.
+
+ \sa restoreState(), saveState()
+*/
+
+bool QMainWindow::restoreDockWidget(QDockWidget *dockwidget)
+{
+ return d_func()->layout->restoreDockWidget(dockwidget);
+}
+
+/*!
+ Adds \a dockwidget into the given \a area in the direction
+ specified by the \a orientation.
+*/
+void QMainWindow::addDockWidget(Qt::DockWidgetArea area, QDockWidget *dockwidget,
+ Qt::Orientation orientation)
+{
+ if (!checkDockWidgetArea(area, "QMainWindow::addDockWidget"))
+ return;
+
+ // add a window to an area, placing done relative to the previous
+ d_func()->layout->addDockWidget(area, dockwidget, orientation);
+}
+
+/*!
+ \fn void QMainWindow::splitDockWidget(QDockWidget *first, QDockWidget *second, Qt::Orientation orientation)
+
+ Splits the space covered by the \a first dock widget into two parts,
+ moves the \a first dock widget into the first part, and moves the
+ \a second dock widget into the second part.
+
+ The \a orientation specifies how the space is divided: A Qt::Horizontal
+ split places the second dock widget to the right of the first; a
+ Qt::Vertical split places the second dock widget below the first.
+
+ \e Note: if \a first is currently in a tabbed docked area, \a second will
+ be added as a new tab, not as a neighbor of \a first. This is because a
+ single tab can contain only one dock widget.
+
+ \e Note: The Qt::LayoutDirection influences the order of the dock widgets
+ in the two parts of the divided area. When right-to-left layout direction
+ is enabled, the placing of the dock widgets will be reversed.
+
+ \sa tabifyDockWidget(), addDockWidget(), removeDockWidget()
+*/
+void QMainWindow::splitDockWidget(QDockWidget *after, QDockWidget *dockwidget,
+ Qt::Orientation orientation)
+{
+ d_func()->layout->splitDockWidget(after, dockwidget, orientation);
+}
+
+/*!
+ \fn void QMainWindow::tabifyDockWidget(QDockWidget *first, QDockWidget *second)
+
+ Moves \a second dock widget on top of \a first dock widget, creating a tabbed
+ docked area in the main window.
+
+ \sa tabifiedDockWidgets()
+*/
+void QMainWindow::tabifyDockWidget(QDockWidget *first, QDockWidget *second)
+{
+ d_func()->layout->tabifyDockWidget(first, second);
+}
+
+
+/*!
+ \fn QList<QDockWidget*> QMainWindow::tabifiedDockWidgets(QDockWidget *dockwidget) const
+
+ Returns the dock widgets that are tabified together with \a dockwidget.
+
+ \since 4.5
+ \sa tabifyDockWidget()
+*/
+
+QList<QDockWidget*> QMainWindow::tabifiedDockWidgets(QDockWidget *dockwidget) const
+{
+ QList<QDockWidget*> ret;
+#if defined(QT_NO_TABBAR)
+ Q_UNUSED(dockwidget);
+#else
+ const QDockAreaLayoutInfo *info = d_func()->layout->layoutState.dockAreaLayout.info(dockwidget);
+ if (info && info->tabbed && info->tabBar) {
+ for(int i = 0; i < info->item_list.count(); ++i) {
+ const QDockAreaLayoutItem &item = info->item_list.at(i);
+ if (item.widgetItem) {
+ if (QDockWidget *dock = qobject_cast<QDockWidget*>(item.widgetItem->widget())) {
+ if (dock != dockwidget) {
+ ret += dock;
+ }
+ }
+ }
+ }
+ }
+#endif
+ return ret;
+}
+
+
+/*!
+ Removes the \a dockwidget from the main window layout and hides
+ it. Note that the \a dockwidget is \e not deleted.
+*/
+void QMainWindow::removeDockWidget(QDockWidget *dockwidget)
+{
+ if (dockwidget) {
+ d_func()->layout->removeWidget(dockwidget);
+ dockwidget->hide();
+ }
+}
+
+/*!
+ Returns the Qt::DockWidgetArea for \a dockwidget. If \a dockwidget
+ has not been added to the main window, this function returns \c
+ Qt::NoDockWidgetArea.
+
+ \sa addDockWidget() splitDockWidget() Qt::DockWidgetArea
+*/
+Qt::DockWidgetArea QMainWindow::dockWidgetArea(QDockWidget *dockwidget) const
+{ return d_func()->layout->dockWidgetArea(dockwidget); }
+
+#endif // QT_NO_DOCKWIDGET
+
+/*!
+ Saves the current state of this mainwindow's toolbars and
+ dockwidgets. The \a version number is stored as part of the data.
+
+ The \link QObject::objectName objectName\endlink property is used
+ to identify each QToolBar and QDockWidget. You should make sure
+ that this property is unique for each QToolBar and QDockWidget you
+ add to the QMainWindow
+
+ To restore the saved state, pass the return value and \a version
+ number to restoreState().
+
+ To save the geometry when the window closes, you can
+ implement a close event like this:
+
+ \snippet doc/src/snippets/code/src_gui_widgets_qmainwindow.cpp 0
+
+ \sa restoreState(), QWidget::saveGeometry(), QWidget::restoreGeometry()
+*/
+QByteArray QMainWindow::saveState(int version) const
+{
+ QByteArray data;
+ QDataStream stream(&data, QIODevice::WriteOnly);
+ stream << QMainWindowLayout::VersionMarker;
+ stream << version;
+ d_func()->layout->saveState(stream);
+ return data;
+}
+
+/*!
+ Restores the \a state of this mainwindow's toolbars and
+ dockwidgets. The \a version number is compared with that stored
+ in \a state. If they do not match, the mainwindow's state is left
+ unchanged, and this function returns \c false; otherwise, the state
+ is restored, and this function returns \c true.
+
+ To restore geometry saved using QSettings, you can use code like
+ this:
+
+ \snippet doc/src/snippets/code/src_gui_widgets_qmainwindow.cpp 1
+
+ \sa saveState(), QWidget::saveGeometry(),
+ QWidget::restoreGeometry(), restoreDockWidget()
+*/
+bool QMainWindow::restoreState(const QByteArray &state, int version)
+{
+ if (state.isEmpty())
+ return false;
+ QByteArray sd = state;
+ QDataStream stream(&sd, QIODevice::ReadOnly);
+ int marker, v;
+ stream >> marker;
+ stream >> v;
+ if (stream.status() != QDataStream::Ok || marker != QMainWindowLayout::VersionMarker || v != version)
+ return false;
+ bool restored = d_func()->layout->restoreState(stream);
+ return restored;
+}
+
+#if !defined(QT_NO_DOCKWIDGET) && !defined(QT_NO_CURSOR)
+QCursor QMainWindowPrivate::separatorCursor(const QList<int> &path) const
+{
+ QDockAreaLayoutInfo *info = layout->layoutState.dockAreaLayout.info(path);
+ Q_ASSERT(info != 0);
+ if (path.size() == 1) { // is this the "top-level" separator which separates a dock area
+ // from the central widget?
+ switch (path.first()) {
+ case QInternal::LeftDock:
+ case QInternal::RightDock:
+ return Qt::SplitHCursor;
+ case QInternal::TopDock:
+ case QInternal::BottomDock:
+ return Qt::SplitVCursor;
+ default:
+ break;
+ }
+ }
+
+ // no, it's a splitter inside a dock area, separating two dock widgets
+
+ return info->o == Qt::Horizontal
+ ? Qt::SplitHCursor : Qt::SplitVCursor;
+}
+
+void QMainWindowPrivate::adjustCursor(const QPoint &pos)
+{
+ Q_Q(QMainWindow);
+
+ hoverPos = pos;
+
+ if (pos == QPoint(0, 0)) {
+ if (!hoverSeparator.isEmpty())
+ q->update(layout->layoutState.dockAreaLayout.separatorRect(hoverSeparator));
+ hoverSeparator.clear();
+
+ if (cursorAdjusted) {
+ cursorAdjusted = false;
+ if (hasOldCursor)
+ q->setCursor(oldCursor);
+ else
+ q->unsetCursor();
+ }
+ } else {
+ QList<int> pathToSeparator
+ = layout->layoutState.dockAreaLayout.findSeparator(pos);
+
+ if (pathToSeparator != hoverSeparator) {
+ if (!hoverSeparator.isEmpty())
+ q->update(layout->layoutState.dockAreaLayout.separatorRect(hoverSeparator));
+
+ hoverSeparator = pathToSeparator;
+
+ if (hoverSeparator.isEmpty()) {
+ if (cursorAdjusted) {
+ cursorAdjusted = false;
+ if (hasOldCursor)
+ q->setCursor(oldCursor);
+ else
+ q->unsetCursor();
+ }
+ } else {
+ q->update(layout->layoutState.dockAreaLayout.separatorRect(hoverSeparator));
+ if (!cursorAdjusted) {
+ oldCursor = q->cursor();
+ hasOldCursor = q->testAttribute(Qt::WA_SetCursor);
+ }
+ QCursor cursor = separatorCursor(hoverSeparator);
+ cursorAdjusted = false; //to not reset the oldCursor in event(CursorChange)
+ q->setCursor(cursor);
+ cursorAdjusted = true;
+ }
+ }
+ }
+}
+#endif
+
+/*! \reimp */
+bool QMainWindow::event(QEvent *event)
+{
+ Q_D(QMainWindow);
+ switch (event->type()) {
+
+#ifndef QT_NO_DOCKWIDGET
+ case QEvent::Paint: {
+ QPainter p(this);
+ QRegion r = static_cast<QPaintEvent*>(event)->region();
+ d->layout->layoutState.dockAreaLayout.paintSeparators(&p, this, r, d->hoverPos);
+ break;
+ }
+
+#ifndef QT_NO_CURSOR
+ case QEvent::HoverMove: {
+ d->adjustCursor(static_cast<QHoverEvent*>(event)->pos());
+ break;
+ }
+
+ // We don't want QWidget to call update() on the entire QMainWindow
+ // on HoverEnter and HoverLeave, hence accept the event (return true).
+ case QEvent::HoverEnter:
+ return true;
+ case QEvent::HoverLeave:
+ d->adjustCursor(QPoint(0, 0));
+ return true;
+ case QEvent::ShortcutOverride: // when a menu pops up
+ d->adjustCursor(QPoint(0, 0));
+ break;
+#endif // QT_NO_CURSOR
+
+ case QEvent::MouseButtonPress: {
+ QMouseEvent *e = static_cast<QMouseEvent*>(event);
+ if (e->button() == Qt::LeftButton && d->layout->startSeparatorMove(e->pos())) {
+ // The click was on a separator, eat this event
+ e->accept();
+ return true;
+ }
+ break;
+ }
+
+ case QEvent::MouseMove: {
+ QMouseEvent *e = static_cast<QMouseEvent*>(event);
+
+#ifndef QT_NO_CURSOR
+ d->adjustCursor(e->pos());
+#endif
+ if (e->buttons() & Qt::LeftButton) {
+ if (d->layout->separatorMove(e->pos())) {
+ // We're moving a separator, eat this event
+ e->accept();
+ return true;
+ }
+ }
+
+ break;
+ }
+
+ case QEvent::MouseButtonRelease: {
+ QMouseEvent *e = static_cast<QMouseEvent*>(event);
+ if (d->layout->endSeparatorMove(e->pos())) {
+ // We've released a separator, eat this event
+ e->accept();
+ return true;
+ }
+ break;
+ }
+
+#endif
+
+#ifndef QT_NO_TOOLBAR
+ case QEvent::ToolBarChange: {
+ d->layout->toggleToolBarsVisible();
+ return true;
+ }
+#endif
+
+#ifndef QT_NO_STATUSTIP
+ case QEvent::StatusTip:
+#ifndef QT_NO_STATUSBAR
+ if (QStatusBar *sb = d->layout->statusBar())
+ sb->showMessage(static_cast<QStatusTipEvent*>(event)->tip());
+ else
+#endif
+ static_cast<QStatusTipEvent*>(event)->ignore();
+ return true;
+#endif // QT_NO_STATUSTIP
+
+ case QEvent::StyleChange:
+#ifndef QT_NO_DOCKWIDGET
+ d->layout->layoutState.dockAreaLayout.styleChangedEvent();
+#endif
+ if (!d->explicitIconSize)
+ setIconSize(QSize());
+ break;
+#ifdef Q_WS_MAC
+ case QEvent::Show:
+ if (unifiedTitleAndToolBarOnMac())
+ d->layout->syncUnifiedToolbarVisibility();
+ d->layout->blockVisiblityCheck = false;
+ break;
+ case QEvent::WindowStateChange:
+ {
+ if (isHidden()) {
+ // We are coming out of a minimize, leave things as is.
+ d->layout->blockVisiblityCheck = true;
+ }
+# ifdef QT_MAC_USE_COCOA
+ // We need to update the HIToolbar status when we go out of or into fullscreen.
+ QWindowStateChangeEvent *wce = static_cast<QWindowStateChangeEvent *>(event);
+ if ((windowState() & Qt::WindowFullScreen) || (wce->oldState() & Qt::WindowFullScreen)) {
+ d->layout->updateHIToolBarStatus();
+ }
+# endif // Cocoa
+ }
+ break;
+#endif // Q_WS_MAC
+#if !defined(QT_NO_DOCKWIDGET) && !defined(QT_NO_CURSOR)
+ case QEvent::CursorChange:
+ if (d->cursorAdjusted) {
+ d->oldCursor = cursor();
+ d->hasOldCursor = testAttribute(Qt::WA_SetCursor);
+ }
+ break;
+#endif
+ default:
+ break;
+ }
+
+ return QWidget::event(event);
+}
+
+#ifndef QT_NO_TOOLBAR
+
+/*!
+ \property QMainWindow::unifiedTitleAndToolBarOnMac
+ \brief whether the window uses the unified title and toolbar look on Mac OS X
+ \since 4.3
+
+ This property is false by default and only has any effect on Mac OS X 10.4 or higher.
+
+ If set to true, then the top toolbar area is replaced with a Carbon HIToolbar
+ or a Cocoa NSToolbar (depending on whether Qt was built with Carbon or Cocoa).
+ All toolbars in the top toolbar area and any toolbars added afterwards are
+ moved to that. This means a couple of things.
+
+ \list
+ \i QToolBars in this toolbar area are not movable and you cannot drag other
+ toolbars to it
+ \i Toolbar breaks are not respected or preserved
+ \i Any custom widgets in the toolbar will not be shown if the toolbar
+ becomes too small (only actions will be shown)
+ \i Before Qt 4.5, if you called showFullScreen() on the main window, the QToolbar would
+ disappear since it is considered to be part of the title bar. Qt 4.5 and up will now work around this by pulling
+ the toolbars out and back into the regular toolbar and vice versa when you swap out.
+ \endlist
+
+ Setting this back to false will remove these restrictions.
+
+ The Qt::WA_MacBrushedMetal attribute takes precedence over this property.
+*/
+void QMainWindow::setUnifiedTitleAndToolBarOnMac(bool set)
+{
+#ifdef Q_WS_MAC
+ Q_D(QMainWindow);
+ if (!isWindow() || d->useHIToolBar == set || QSysInfo::MacintoshVersion < QSysInfo::MV_10_3)
+ return;
+
+ d->useHIToolBar = set;
+ createWinId(); // We need the hiview for down below.
+
+#ifdef QT_MAC_USE_COCOA
+ // Activate the unified toolbar with the raster engine.
+ if (windowSurface() && set) {
+ d->layout->unifiedSurface = new QUnifiedToolbarSurface(this);
+ }
+#endif // QT_MAC_USE_COCOA
+
+ d->layout->updateHIToolBarStatus();
+
+#ifdef QT_MAC_USE_COCOA
+ // Deactivate the unified toolbar with the raster engine.
+ if (windowSurface() && !set) {
+ if (d->layout->unifiedSurface) {
+ delete d->layout->unifiedSurface;
+ d->layout->unifiedSurface = 0;
+ }
+ }
+#endif // QT_MAC_USE_COCOA
+
+ // Enabling the unified toolbar clears the opaque size grip setting, update it.
+ d->macUpdateOpaqueSizeGrip();
+#else
+ Q_UNUSED(set)
+#endif
+}
+
+bool QMainWindow::unifiedTitleAndToolBarOnMac() const
+{
+#ifdef Q_WS_MAC
+ return d_func()->useHIToolBar && !testAttribute(Qt::WA_MacBrushedMetal) && !(windowFlags() & Qt::FramelessWindowHint);
+#endif
+ return false;
+}
+
+#endif // QT_NO_TOOLBAR
+
+/*!
+ \internal
+*/
+bool QMainWindow::isSeparator(const QPoint &pos) const
+{
+#ifndef QT_NO_DOCKWIDGET
+ Q_D(const QMainWindow);
+ return !d->layout->layoutState.dockAreaLayout.findSeparator(pos).isEmpty();
+#else
+ Q_UNUSED(pos);
+ return false;
+#endif
+}
+
+#ifndef QT_NO_CONTEXTMENU
+/*!
+ \reimp
+*/
+void QMainWindow::contextMenuEvent(QContextMenuEvent *event)
+{
+ event->ignore();
+ // only show the context menu for direct QDockWidget and QToolBar
+ // children and for the menu bar as well
+ QWidget *child = childAt(event->pos());
+ while (child && child != this) {
+#ifndef QT_NO_MENUBAR
+ if (QMenuBar *mb = qobject_cast<QMenuBar *>(child)) {
+ if (mb->parentWidget() != this)
+ return;
+ break;
+ }
+#endif
+#ifndef QT_NO_DOCKWIDGET
+ if (QDockWidget *dw = qobject_cast<QDockWidget *>(child)) {
+ if (dw->parentWidget() != this)
+ return;
+ if (dw->widget()
+ && dw->widget()->geometry().contains(child->mapFrom(this, event->pos()))) {
+ // ignore the event if the mouse is over the QDockWidget contents
+ return;
+ }
+ break;
+ }
+#endif // QT_NO_DOCKWIDGET
+#ifndef QT_NO_TOOLBAR
+ if (QToolBar *tb = qobject_cast<QToolBar *>(child)) {
+ if (tb->parentWidget() != this)
+ return;
+ break;
+ }
+#endif
+ child = child->parentWidget();
+ }
+ if (child == this)
+ return;
+
+#ifndef QT_NO_MENU
+ QMenu *popup = createPopupMenu();
+ if (popup) {
+ if (!popup->isEmpty()) {
+ popup->setAttribute(Qt::WA_DeleteOnClose);
+ popup->popup(event->globalPos());
+ event->accept();
+ } else {
+ delete popup;
+ }
+ }
+#endif
+}
+#endif // QT_NO_CONTEXTMENU
+
+#ifndef QT_NO_MENU
+/*!
+ Returns a popup menu containing checkable entries for the toolbars and
+ dock widgets present in the main window. If there are no toolbars and
+ dock widgets present, this function returns a null pointer.
+
+ By default, this function is called by the main window when the user
+ activates a context menu, typically by right-clicking on a toolbar or a dock
+ widget.
+
+ If you want to create a custom popup menu, reimplement this function and
+ return a newly-created popup menu. Ownership of the popup menu is transferred
+ to the caller.
+
+ \sa addDockWidget(), addToolBar(), menuBar()
+*/
+QMenu *QMainWindow::createPopupMenu()
+{
+ Q_D(QMainWindow);
+ QMenu *menu = 0;
+#ifndef QT_NO_DOCKWIDGET
+ QList<QDockWidget *> dockwidgets = findChildren<QDockWidget *>();
+ if (dockwidgets.size()) {
+ menu = new QMenu(this);
+ for (int i = 0; i < dockwidgets.size(); ++i) {
+ QDockWidget *dockWidget = dockwidgets.at(i);
+ if (dockWidget->parentWidget() == this
+ && !d->layout->layoutState.dockAreaLayout.indexOf(dockWidget).isEmpty()) {
+ menu->addAction(dockwidgets.at(i)->toggleViewAction());
+ }
+ }
+ menu->addSeparator();
+ }
+#endif // QT_NO_DOCKWIDGET
+#ifndef QT_NO_TOOLBAR
+ QList<QToolBar *> toolbars = findChildren<QToolBar *>();
+ if (toolbars.size()) {
+ if (!menu)
+ menu = new QMenu(this);
+ for (int i = 0; i < toolbars.size(); ++i) {
+ QToolBar *toolBar = toolbars.at(i);
+ if (toolBar->parentWidget() == this
+ && (!d->layout->layoutState.toolBarAreaLayout.indexOf(toolBar).isEmpty()
+ || (unifiedTitleAndToolBarOnMac()
+ && toolBarArea(toolBar) == Qt::TopToolBarArea))) {
+ menu->addAction(toolbars.at(i)->toggleViewAction());
+ }
+ }
+ }
+#endif
+ Q_UNUSED(d);
+ return menu;
+}
+#endif // QT_NO_MENU
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_MAINWINDOW
diff --git a/src/widgets/widgets/qmainwindow.h b/src/widgets/widgets/qmainwindow.h
new file mode 100644
index 0000000000..f060d3f460
--- /dev/null
+++ b/src/widgets/widgets/qmainwindow.h
@@ -0,0 +1,219 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDYNAMICMAINWINDOW_H
+#define QDYNAMICMAINWINDOW_H
+
+#include <QtWidgets/qwidget.h>
+#include <QtWidgets/qtabwidget.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_MAINWINDOW
+
+class QDockWidget;
+class QMainWindowPrivate;
+class QMenuBar;
+class QStatusBar;
+class QToolBar;
+class QMenu;
+
+class Q_WIDGETS_EXPORT QMainWindow : public QWidget
+{
+ Q_OBJECT
+
+ Q_ENUMS(DockOption)
+ Q_FLAGS(DockOptions)
+ Q_PROPERTY(QSize iconSize READ iconSize WRITE setIconSize)
+ Q_PROPERTY(Qt::ToolButtonStyle toolButtonStyle READ toolButtonStyle WRITE setToolButtonStyle)
+#ifndef QT_NO_DOCKWIDGET
+ Q_PROPERTY(bool animated READ isAnimated WRITE setAnimated)
+#ifndef QT_NO_TABBAR
+ Q_PROPERTY(bool documentMode READ documentMode WRITE setDocumentMode)
+#endif // QT_NO_TABBAR
+#ifndef QT_NO_TABWIDGET
+ Q_PROPERTY(QTabWidget::TabShape tabShape READ tabShape WRITE setTabShape)
+#endif // QT_NO_TABWIDGET
+ Q_PROPERTY(bool dockNestingEnabled READ isDockNestingEnabled WRITE setDockNestingEnabled)
+#endif // QT_NO_DOCKWIDGET
+ Q_PROPERTY(DockOptions dockOptions READ dockOptions WRITE setDockOptions)
+#ifndef QT_NO_TOOLBAR
+ Q_PROPERTY(bool unifiedTitleAndToolBarOnMac READ unifiedTitleAndToolBarOnMac WRITE setUnifiedTitleAndToolBarOnMac)
+#endif
+
+public:
+ enum DockOption {
+ AnimatedDocks = 0x01,
+ AllowNestedDocks = 0x02,
+ AllowTabbedDocks = 0x04,
+ ForceTabbedDocks = 0x08, // implies AllowTabbedDocks, !AllowNestedDocks
+ VerticalTabs = 0x10 // implies AllowTabbedDocks
+ };
+ Q_DECLARE_FLAGS(DockOptions, DockOption)
+
+ explicit QMainWindow(QWidget *parent = 0, Qt::WindowFlags flags = 0);
+ ~QMainWindow();
+
+ QSize iconSize() const;
+ void setIconSize(const QSize &iconSize);
+
+ Qt::ToolButtonStyle toolButtonStyle() const;
+ void setToolButtonStyle(Qt::ToolButtonStyle toolButtonStyle);
+
+#ifndef QT_NO_DOCKWIDGET
+ bool isAnimated() const;
+ bool isDockNestingEnabled() const;
+#endif
+
+#ifndef QT_NO_TABBAR
+ bool documentMode() const;
+ void setDocumentMode(bool enabled);
+#endif
+
+#ifndef QT_NO_TABWIDGET
+ QTabWidget::TabShape tabShape() const;
+ void setTabShape(QTabWidget::TabShape tabShape);
+ QTabWidget::TabPosition tabPosition(Qt::DockWidgetArea area) const;
+ void setTabPosition(Qt::DockWidgetAreas areas, QTabWidget::TabPosition tabPosition);
+#endif // QT_NO_TABWIDGET
+
+ void setDockOptions(DockOptions options);
+ DockOptions dockOptions() const;
+
+ bool isSeparator(const QPoint &pos) const;
+
+#ifndef QT_NO_MENUBAR
+ QMenuBar *menuBar() const;
+ void setMenuBar(QMenuBar *menubar);
+
+ QWidget *menuWidget() const;
+ void setMenuWidget(QWidget *menubar);
+#endif
+
+#ifndef QT_NO_STATUSBAR
+ QStatusBar *statusBar() const;
+ void setStatusBar(QStatusBar *statusbar);
+#endif
+
+ QWidget *centralWidget() const;
+ void setCentralWidget(QWidget *widget);
+
+#ifndef QT_NO_DOCKWIDGET
+ void setCorner(Qt::Corner corner, Qt::DockWidgetArea area);
+ Qt::DockWidgetArea corner(Qt::Corner corner) const;
+#endif
+
+#ifndef QT_NO_TOOLBAR
+ void addToolBarBreak(Qt::ToolBarArea area = Qt::TopToolBarArea);
+ void insertToolBarBreak(QToolBar *before);
+
+ void addToolBar(Qt::ToolBarArea area, QToolBar *toolbar);
+ void addToolBar(QToolBar *toolbar);
+ QToolBar *addToolBar(const QString &title);
+ void insertToolBar(QToolBar *before, QToolBar *toolbar);
+ void removeToolBar(QToolBar *toolbar);
+ void removeToolBarBreak(QToolBar *before);
+
+ void setUnifiedTitleAndToolBarOnMac(bool set);
+ bool unifiedTitleAndToolBarOnMac() const;
+
+ Qt::ToolBarArea toolBarArea(QToolBar *toolbar) const;
+ bool toolBarBreak(QToolBar *toolbar) const;
+#endif
+#ifndef QT_NO_DOCKWIDGET
+ void addDockWidget(Qt::DockWidgetArea area, QDockWidget *dockwidget);
+ void addDockWidget(Qt::DockWidgetArea area, QDockWidget *dockwidget,
+ Qt::Orientation orientation);
+ void splitDockWidget(QDockWidget *after, QDockWidget *dockwidget,
+ Qt::Orientation orientation);
+ void tabifyDockWidget(QDockWidget *first, QDockWidget *second);
+ QList<QDockWidget*> tabifiedDockWidgets(QDockWidget *dockwidget) const;
+ void removeDockWidget(QDockWidget *dockwidget);
+ bool restoreDockWidget(QDockWidget *dockwidget);
+
+ Qt::DockWidgetArea dockWidgetArea(QDockWidget *dockwidget) const;
+#endif // QT_NO_DOCKWIDGET
+
+ QByteArray saveState(int version = 0) const;
+ bool restoreState(const QByteArray &state, int version = 0);
+
+#ifndef QT_NO_MENU
+ virtual QMenu *createPopupMenu();
+#endif
+
+#ifdef QT3_SUPPORT
+ QT3_SUPPORT_CONSTRUCTOR QMainWindow(QWidget *parent, const char *name, Qt::WindowFlags flags = 0);
+#endif
+
+#ifndef QT_NO_DOCKWIDGET
+public Q_SLOTS:
+ void setAnimated(bool enabled);
+ void setDockNestingEnabled(bool enabled);
+#endif
+
+Q_SIGNALS:
+ void iconSizeChanged(const QSize &iconSize);
+ void toolButtonStyleChanged(Qt::ToolButtonStyle toolButtonStyle);
+
+protected:
+#ifndef QT_NO_CONTEXTMENU
+ void contextMenuEvent(QContextMenuEvent *event);
+#endif
+ bool event(QEvent *event);
+
+private:
+ Q_DECLARE_PRIVATE(QMainWindow)
+ Q_DISABLE_COPY(QMainWindow)
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QMainWindow::DockOptions)
+
+#endif // QT_NO_MAINWINDOW
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QDYNAMICMAINWINDOW_H
diff --git a/src/gui/widgets/qmainwindowlayout.cpp b/src/widgets/widgets/qmainwindowlayout.cpp
index ebabf2d93c..ebabf2d93c 100644
--- a/src/gui/widgets/qmainwindowlayout.cpp
+++ b/src/widgets/widgets/qmainwindowlayout.cpp
diff --git a/src/gui/widgets/qmainwindowlayout_mac.mm b/src/widgets/widgets/qmainwindowlayout_mac.mm
index 28e8764fcb..28e8764fcb 100644
--- a/src/gui/widgets/qmainwindowlayout_mac.mm
+++ b/src/widgets/widgets/qmainwindowlayout_mac.mm
diff --git a/src/widgets/widgets/qmainwindowlayout_p.h b/src/widgets/widgets/qmainwindowlayout_p.h
new file mode 100644
index 0000000000..f8116096c7
--- /dev/null
+++ b/src/widgets/widgets/qmainwindowlayout_p.h
@@ -0,0 +1,357 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDYNAMICMAINWINDOWLAYOUT_P_H
+#define QDYNAMICMAINWINDOWLAYOUT_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qmainwindow.h"
+
+#ifndef QT_NO_MAINWINDOW
+
+#include "QtWidgets/qlayout.h"
+#include "QtWidgets/qtabbar.h"
+#include "QtCore/qvector.h"
+#include "QtCore/qset.h"
+#include "QtCore/qbasictimer.h"
+#include "private/qlayoutengine_p.h"
+#include "private/qwidgetanimator_p.h"
+
+#include "qdockarealayout_p.h"
+#include "qtoolbararealayout_p.h"
+
+//#define Q_DEBUG_MAINWINDOW_LAYOUT
+
+#if defined(Q_DEBUG_MAINWINDOW_LAYOUT) && !defined(QT_NO_DOCKWIDGET)
+QT_BEGIN_NAMESPACE
+class QTextStream;
+Q_WIDGETS_EXPORT void qt_dumpLayout(QTextStream &qout, QMainWindow *window);
+QT_END_NAMESPACE
+#endif // Q_DEBUG_MAINWINDOW_LAYOUT && !QT_NO_DOCKWIDGET
+
+#ifdef Q_WS_MAC
+// Forward defs to make avoid including Carbon.h (faster compile you know ;).
+struct OpaqueHIObjectRef;
+typedef struct OpaqueHIObjectRef* HIObjectRef;
+typedef HIObjectRef HIToolbarItemRef;
+typedef const void * CFTypeRef;
+typedef const struct __CFString * CFStringRef;
+
+# ifdef QT_MAC_USE_COCOA
+#include <private/qunifiedtoolbarsurface_mac_p.h>
+# endif // QT_MAC_USE_COCOA
+
+#endif // Q_WS_MAC
+
+QT_BEGIN_NAMESPACE
+
+class QToolBar;
+class QRubberBand;
+
+/* This data structure represents the state of all the tool-bars and dock-widgets. It's value based
+ so it can be easilly copied into a temporary variable. All operations are performed without moving
+ any widgets. Only when we are sure we have the desired state, we call apply(), which moves the
+ widgets.
+*/
+
+class QMainWindowLayoutState
+{
+public:
+ QRect rect;
+ QMainWindow *mainWindow;
+
+ QMainWindowLayoutState(QMainWindow *win);
+
+#ifndef QT_NO_TOOLBAR
+ QToolBarAreaLayout toolBarAreaLayout;
+#endif
+
+#ifndef QT_NO_DOCKWIDGET
+ QDockAreaLayout dockAreaLayout;
+#else
+ QLayoutItem *centralWidgetItem;
+ QRect centralWidgetRect;
+#endif
+
+ void apply(bool animated);
+ void deleteAllLayoutItems();
+ void deleteCentralWidgetItem();
+
+ QSize sizeHint() const;
+ QSize minimumSize() const;
+ void fitLayout();
+
+ QLayoutItem *itemAt(int index, int *x) const;
+ QLayoutItem *takeAt(int index, int *x);
+ QList<int> indexOf(QWidget *widget) const;
+ QLayoutItem *item(const QList<int> &path);
+ QRect itemRect(const QList<int> &path) const;
+ QRect gapRect(const QList<int> &path) const; // ### get rid of this, use itemRect() instead
+
+ bool contains(QWidget *widget) const;
+
+ void setCentralWidget(QWidget *widget);
+ QWidget *centralWidget() const;
+
+ QList<int> gapIndex(QWidget *widget, const QPoint &pos) const;
+ bool insertGap(const QList<int> &path, QLayoutItem *item);
+ void remove(const QList<int> &path);
+ void remove(QLayoutItem *item);
+ void clear();
+ bool isValid() const;
+
+ QLayoutItem *plug(const QList<int> &path);
+ QLayoutItem *unplug(const QList<int> &path, QMainWindowLayoutState *savedState = 0);
+
+ void saveState(QDataStream &stream) const;
+ bool checkFormat(QDataStream &stream, bool pre43);
+ bool restoreState(QDataStream &stream, const QMainWindowLayoutState &oldState);
+};
+
+class Q_AUTOTEST_EXPORT QMainWindowLayout : public QLayout
+{
+ Q_OBJECT
+
+public:
+ QMainWindowLayoutState layoutState, savedState;
+
+ QMainWindowLayout(QMainWindow *mainwindow, QLayout *parentLayout);
+ ~QMainWindowLayout();
+
+ QMainWindow::DockOptions dockOptions;
+ void setDockOptions(QMainWindow::DockOptions opts);
+ bool usesHIToolBar(QToolBar *toolbar) const;
+
+ void timerEvent(QTimerEvent *e);
+
+ // status bar
+
+ QLayoutItem *statusbar;
+
+#ifndef QT_NO_STATUSBAR
+ QStatusBar *statusBar() const;
+ void setStatusBar(QStatusBar *sb);
+#endif
+
+ // central widget
+
+ QWidget *centralWidget() const;
+ void setCentralWidget(QWidget *cw);
+
+ // toolbars
+
+#ifndef QT_NO_TOOLBAR
+ void addToolBarBreak(Qt::ToolBarArea area);
+ void insertToolBarBreak(QToolBar *before);
+ void removeToolBarBreak(QToolBar *before);
+
+ void addToolBar(Qt::ToolBarArea area, QToolBar *toolbar, bool needAddChildWidget = true);
+ void insertToolBar(QToolBar *before, QToolBar *toolbar);
+ Qt::ToolBarArea toolBarArea(QToolBar *toolbar) const;
+ bool toolBarBreak(QToolBar *toolBar) const;
+ void getStyleOptionInfo(QStyleOptionToolBar *option, QToolBar *toolBar) const;
+ void removeToolBar(QToolBar *toolbar);
+ void toggleToolBarsVisible();
+ void moveToolBar(QToolBar *toolbar, int pos);
+#endif
+
+ // dock widgets
+
+#ifndef QT_NO_DOCKWIDGET
+ void setCorner(Qt::Corner corner, Qt::DockWidgetArea area);
+ Qt::DockWidgetArea corner(Qt::Corner corner) const;
+ void addDockWidget(Qt::DockWidgetArea area,
+ QDockWidget *dockwidget,
+ Qt::Orientation orientation);
+ void splitDockWidget(QDockWidget *after,
+ QDockWidget *dockwidget,
+ Qt::Orientation orientation);
+ void tabifyDockWidget(QDockWidget *first, QDockWidget *second);
+ Qt::DockWidgetArea dockWidgetArea(QDockWidget *dockwidget) const;
+ void raise(QDockWidget *widget);
+ void setVerticalTabsEnabled(bool enabled);
+ bool restoreDockWidget(QDockWidget *dockwidget);
+
+#ifndef QT_NO_TABBAR
+ bool _documentMode;
+ bool documentMode() const;
+ void setDocumentMode(bool enabled);
+
+ QTabBar *getTabBar();
+ QSet<QTabBar*> usedTabBars;
+ QList<QTabBar*> unusedTabBars;
+ bool verticalTabsEnabled;
+
+ QWidget *getSeparatorWidget();
+ QSet<QWidget*> usedSeparatorWidgets;
+ QList<QWidget*> unusedSeparatorWidgets;
+ int sep; // separator extent
+
+#ifndef QT_NO_TABWIDGET
+ QTabWidget::TabPosition tabPositions[4];
+ QTabWidget::TabShape _tabShape;
+
+ QTabWidget::TabShape tabShape() const;
+ void setTabShape(QTabWidget::TabShape tabShape);
+ QTabWidget::TabPosition tabPosition(Qt::DockWidgetArea area) const;
+ void setTabPosition(Qt::DockWidgetAreas areas, QTabWidget::TabPosition tabPosition);
+#endif // QT_NO_TABWIDGET
+#endif // QT_NO_TABBAR
+
+ // separators
+
+ QList<int> movingSeparator;
+ QPoint movingSeparatorOrigin, movingSeparatorPos;
+ QBasicTimer separatorMoveTimer;
+
+ bool startSeparatorMove(const QPoint &pos);
+ bool separatorMove(const QPoint &pos);
+ bool endSeparatorMove(const QPoint &pos);
+ void keepSize(QDockWidget *w);
+#endif // QT_NO_DOCKWIDGET
+
+ // save/restore
+
+ enum { // sentinel values used to validate state data
+ VersionMarker = 0xff
+ };
+ void saveState(QDataStream &stream) const;
+ bool restoreState(QDataStream &stream);
+
+ // QLayout interface
+
+ void addItem(QLayoutItem *item);
+ void setGeometry(const QRect &r);
+ QLayoutItem *itemAt(int index) const;
+ QLayoutItem *takeAt(int index);
+ int count() const;
+
+ QSize sizeHint() const;
+ QSize minimumSize() const;
+ mutable QSize szHint;
+ mutable QSize minSize;
+ void invalidate();
+
+ // animations
+
+ QWidgetAnimator widgetAnimator;
+ QList<int> currentGapPos;
+ QRect currentGapRect;
+ QWidget *pluggingWidget;
+#ifndef QT_NO_RUBBERBAND
+ QRubberBand *gapIndicator;
+#endif
+
+ QList<int> hover(QLayoutItem *widgetItem, const QPoint &mousePos);
+ bool plug(QLayoutItem *widgetItem);
+ QLayoutItem *unplug(QWidget *widget);
+ void revert(QLayoutItem *widgetItem);
+ void updateGapIndicator();
+ void paintDropIndicator(QPainter *p, QWidget *widget, const QRegion &clip);
+ void applyState(QMainWindowLayoutState &newState, bool animate = true);
+ void restore(bool keepSavedState = false);
+ void updateHIToolBarStatus();
+ void animationFinished(QWidget *widget);
+
+private Q_SLOTS:
+#ifndef QT_NO_DOCKWIDGET
+#ifndef QT_NO_TABBAR
+ void tabChanged();
+#endif
+#endif
+private:
+#ifndef QT_NO_TABBAR
+ void updateTabBarShapes();
+#endif
+#ifdef Q_WS_MAC
+# ifndef QT_MAC_USE_COCOA
+ static OSStatus qtmacToolbarDelegate(EventHandlerCallRef, EventRef , void *);
+ static OSStatus qtoolbarInHIToolbarHandler(EventHandlerCallRef inCallRef, EventRef event,
+ void *data);
+ static void qtMacHIToolbarRegisterQToolBarInHIToolborItemClass();
+ static HIToolbarItemRef CreateToolbarItemForIdentifier(CFStringRef identifier, CFTypeRef data);
+ static HIToolbarItemRef createQToolBarInHIToolbarItem(QToolBar *toolbar,
+ QMainWindowLayout *layout);
+# endif
+public:
+ struct ToolBarSaveState {
+ ToolBarSaveState() : movable(false) { }
+ ToolBarSaveState(bool newMovable, const QSize &newMax)
+ : movable(newMovable), maximumSize(newMax) { }
+ bool movable;
+ QSize maximumSize;
+ };
+ QList<QToolBar *> qtoolbarsInUnifiedToolbarList;
+ QList<void *> toolbarItemsCopy;
+ QHash<void *, QToolBar *> unifiedToolbarHash;
+ QHash<QToolBar *, ToolBarSaveState> toolbarSaveState;
+ QHash<QString, QToolBar *> cocoaItemIDToToolbarHash;
+ void insertIntoMacToolbar(QToolBar *before, QToolBar *after);
+ void removeFromMacToolbar(QToolBar *toolbar);
+ void cleanUpMacToolbarItems();
+ void fixSizeInUnifiedToolbar(QToolBar *tb) const;
+ bool useHIToolBar;
+ bool activateUnifiedToolbarAfterFullScreen;
+ void syncUnifiedToolbarVisibility();
+ bool blockVisiblityCheck;
+
+#ifdef QT_MAC_USE_COCOA
+ QUnifiedToolbarSurface *unifiedSurface;
+ void updateUnifiedToolbarOffset();
+#endif // QT_MAC_USE_COCOA
+
+#endif // Q_WS_MAC
+};
+QT_END_NAMESPACE
+
+#endif // QT_NO_MAINWINDOW
+
+#endif // QDYNAMICMAINWINDOWLAYOUT_P_H
diff --git a/src/gui/widgets/qmdiarea.cpp b/src/widgets/widgets/qmdiarea.cpp
index 2fe9706edf..2fe9706edf 100644
--- a/src/gui/widgets/qmdiarea.cpp
+++ b/src/widgets/widgets/qmdiarea.cpp
diff --git a/src/widgets/widgets/qmdiarea.h b/src/widgets/widgets/qmdiarea.h
new file mode 100644
index 0000000000..f1ffb29e53
--- /dev/null
+++ b/src/widgets/widgets/qmdiarea.h
@@ -0,0 +1,179 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMDIAREA_H
+#define QMDIAREA_H
+
+#include <QtWidgets/qabstractscrollarea.h>
+#include <QtWidgets/qtabwidget.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_MDIAREA
+
+class QMdiSubWindow;
+
+class QMdiAreaPrivate;
+class Q_WIDGETS_EXPORT QMdiArea : public QAbstractScrollArea
+{
+ Q_OBJECT
+ Q_ENUMS(ViewMode)
+ Q_PROPERTY(QBrush background READ background WRITE setBackground)
+ Q_PROPERTY(WindowOrder activationOrder READ activationOrder WRITE setActivationOrder)
+ Q_PROPERTY(ViewMode viewMode READ viewMode WRITE setViewMode)
+#ifndef QT_NO_TABBAR
+ Q_PROPERTY(bool documentMode READ documentMode WRITE setDocumentMode)
+ Q_PROPERTY(bool tabsClosable READ tabsClosable WRITE setTabsClosable)
+ Q_PROPERTY(bool tabsMovable READ tabsMovable WRITE setTabsMovable)
+#endif
+#ifndef QT_NO_TABWIDGET
+ Q_PROPERTY(QTabWidget::TabShape tabShape READ tabShape WRITE setTabShape)
+ Q_PROPERTY(QTabWidget::TabPosition tabPosition READ tabPosition WRITE setTabPosition)
+#endif
+ Q_ENUMS(WindowOrder)
+public:
+ enum AreaOption {
+ DontMaximizeSubWindowOnActivation = 0x1
+ };
+ Q_DECLARE_FLAGS(AreaOptions, AreaOption)
+
+ enum WindowOrder {
+ CreationOrder,
+ StackingOrder,
+ ActivationHistoryOrder
+ };
+
+ enum ViewMode {
+ SubWindowView,
+ TabbedView
+ };
+
+ QMdiArea(QWidget *parent = 0);
+ ~QMdiArea();
+
+ QSize sizeHint() const;
+ QSize minimumSizeHint() const;
+
+ QMdiSubWindow *currentSubWindow() const;
+ QMdiSubWindow *activeSubWindow() const;
+ QList<QMdiSubWindow *> subWindowList(WindowOrder order = CreationOrder) const;
+
+ QMdiSubWindow *addSubWindow(QWidget *widget, Qt::WindowFlags flags = 0);
+ void removeSubWindow(QWidget *widget);
+
+ QBrush background() const;
+ void setBackground(const QBrush &background);
+
+ WindowOrder activationOrder() const;
+ void setActivationOrder(WindowOrder order);
+
+ void setOption(AreaOption option, bool on = true);
+ bool testOption(AreaOption opton) const;
+
+ void setViewMode(ViewMode mode);
+ ViewMode viewMode() const;
+
+#ifndef QT_NO_TABBAR
+ bool documentMode() const;
+ void setDocumentMode(bool enabled);
+
+ void setTabsClosable(bool closable);
+ bool tabsClosable() const;
+
+ void setTabsMovable(bool movable);
+ bool tabsMovable() const;
+#endif
+#ifndef QT_NO_TABWIDGET
+ void setTabShape(QTabWidget::TabShape shape);
+ QTabWidget::TabShape tabShape() const;
+
+ void setTabPosition(QTabWidget::TabPosition position);
+ QTabWidget::TabPosition tabPosition() const;
+#endif
+
+Q_SIGNALS:
+ void subWindowActivated(QMdiSubWindow *);
+
+public Q_SLOTS:
+ void setActiveSubWindow(QMdiSubWindow *window);
+ void tileSubWindows();
+ void cascadeSubWindows();
+ void closeActiveSubWindow();
+ void closeAllSubWindows();
+ void activateNextSubWindow();
+ void activatePreviousSubWindow();
+
+protected Q_SLOTS:
+ void setupViewport(QWidget *viewport);
+
+protected:
+ bool event(QEvent *event);
+ bool eventFilter(QObject *object, QEvent *event);
+ void paintEvent(QPaintEvent *paintEvent);
+ void childEvent(QChildEvent *childEvent);
+ void resizeEvent(QResizeEvent *resizeEvent);
+ void timerEvent(QTimerEvent *timerEvent);
+ void showEvent(QShowEvent *showEvent);
+ bool viewportEvent(QEvent *event);
+ void scrollContentsBy(int dx, int dy);
+
+private:
+ Q_DISABLE_COPY(QMdiArea)
+ Q_DECLARE_PRIVATE(QMdiArea)
+ Q_PRIVATE_SLOT(d_func(), void _q_deactivateAllWindows())
+ Q_PRIVATE_SLOT(d_func(), void _q_processWindowStateChanged(Qt::WindowStates, Qt::WindowStates))
+ Q_PRIVATE_SLOT(d_func(), void _q_currentTabChanged(int))
+ Q_PRIVATE_SLOT(d_func(), void _q_closeTab(int))
+ Q_PRIVATE_SLOT(d_func(), void _q_moveTab(int, int))
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QMdiArea::AreaOptions)
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QT_NO_MDIAREA
+#endif // QMDIAREA_H
diff --git a/src/widgets/widgets/qmdiarea_p.h b/src/widgets/widgets/qmdiarea_p.h
new file mode 100644
index 0000000000..18a022d7dd
--- /dev/null
+++ b/src/widgets/widgets/qmdiarea_p.h
@@ -0,0 +1,285 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMDIAREA_P_H
+#define QMDIAREA_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qmdiarea.h"
+#include "qmdisubwindow.h"
+
+#ifndef QT_NO_MDIAREA
+
+#include <QList>
+#include <QRect>
+#include <QPoint>
+#include <QtWidgets/qapplication.h>
+#include <private/qmdisubwindow_p.h>
+#include <private/qabstractscrollarea_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace QMdi {
+class Rearranger
+{
+public:
+ enum Type {
+ RegularTiler,
+ SimpleCascader,
+ IconTiler
+ };
+
+ // Rearranges widgets relative to domain.
+ virtual void rearrange(QList<QWidget *> &widgets, const QRect &domain) const = 0;
+ virtual Type type() const = 0;
+ virtual ~Rearranger() {}
+};
+
+class RegularTiler : public Rearranger
+{
+ // Rearranges widgets according to a regular tiling pattern
+ // covering the entire domain.
+ // Both positions and sizes may change.
+ void rearrange(QList<QWidget *> &widgets, const QRect &domain) const;
+ inline Type type() const { return Rearranger::RegularTiler; }
+};
+
+class SimpleCascader : public Rearranger
+{
+ // Rearranges widgets according to a simple, regular cascading pattern.
+ // Widgets are resized to minimumSize.
+ // Both positions and sizes may change.
+ void rearrange(QList<QWidget *> &widgets, const QRect &domain) const;
+ inline Type type() const { return Rearranger::SimpleCascader; }
+};
+
+class IconTiler : public Rearranger
+{
+ // Rearranges icons (assumed to be the same size) according to a regular
+ // tiling pattern filling up the domain from the bottom.
+ // Only positions may change.
+ void rearrange(QList<QWidget *> &widgets, const QRect &domain) const;
+ inline Type type() const { return Rearranger::IconTiler; }
+};
+
+class Placer
+{
+public:
+ // Places the rectangle defined by 'size' relative to 'rects' and 'domain'.
+ // Returns the position of the resulting rectangle.
+ virtual QPoint place(
+ const QSize &size, const QList<QRect> &rects, const QRect &domain) const = 0;
+ virtual ~Placer() {}
+};
+
+class MinOverlapPlacer : public Placer
+{
+ QPoint place(const QSize &size, const QList<QRect> &rects, const QRect &domain) const;
+ static int accumulatedOverlap(const QRect &source, const QList<QRect> &rects);
+ static QRect findMinOverlapRect(const QList<QRect> &source, const QList<QRect> &rects);
+ static void getCandidatePlacements(
+ const QSize &size, const QList<QRect> &rects, const QRect &domain,
+ QList<QRect> &candidates);
+ static QPoint findBestPlacement(
+ const QRect &domain, const QList<QRect> &rects, QList<QRect> &source);
+ static void findNonInsiders(
+ const QRect &domain, QList<QRect> &source, QList<QRect> &result);
+ static void findMaxOverlappers(
+ const QRect &domain, const QList<QRect> &source, QList<QRect> &result);
+};
+} // namespace QMdi
+
+class QMdiAreaTabBar;
+class QMdiAreaPrivate : public QAbstractScrollAreaPrivate
+{
+ Q_DECLARE_PUBLIC(QMdiArea)
+public:
+ QMdiAreaPrivate();
+
+ // Variables.
+ QMdi::Rearranger *cascader;
+ QMdi::Rearranger *regularTiler;
+ QMdi::Rearranger *iconTiler;
+ QMdi::Placer *placer;
+#ifndef QT_NO_RUBBERBAND
+ QRubberBand *rubberBand;
+#endif
+ QMdiAreaTabBar *tabBar;
+ QList<QMdi::Rearranger *> pendingRearrangements;
+ QList< QPointer<QMdiSubWindow> > pendingPlacements;
+ QList< QPointer<QMdiSubWindow> > childWindows;
+ QList<int> indicesToActivatedChildren;
+ QPointer<QMdiSubWindow> active;
+ QPointer<QMdiSubWindow> aboutToBecomeActive;
+ QBrush background;
+ QMdiArea::WindowOrder activationOrder;
+ QMdiArea::AreaOptions options;
+ QMdiArea::ViewMode viewMode;
+#ifndef QT_NO_TABBAR
+ bool documentMode;
+ bool tabsClosable;
+ bool tabsMovable;
+#endif
+#ifndef QT_NO_TABWIDGET
+ QTabWidget::TabShape tabShape;
+ QTabWidget::TabPosition tabPosition;
+#endif
+ bool ignoreGeometryChange;
+ bool ignoreWindowStateChange;
+ bool isActivated;
+ bool isSubWindowsTiled;
+ bool showActiveWindowMaximized;
+ bool tileCalledFromResizeEvent;
+ bool updatesDisabledByUs;
+ bool inViewModeChange;
+ int indexToNextWindow;
+ int indexToPreviousWindow;
+ int indexToHighlighted;
+ int indexToLastActiveTab;
+ int resizeTimerId;
+ int tabToPreviousTimerId;
+
+ // Slots.
+ void _q_deactivateAllWindows(QMdiSubWindow *aboutToActivate = 0);
+ void _q_processWindowStateChanged(Qt::WindowStates oldState, Qt::WindowStates newState);
+ void _q_currentTabChanged(int index);
+ void _q_closeTab(int index);
+ void _q_moveTab(int from, int to);
+
+ // Functions.
+ void appendChild(QMdiSubWindow *child);
+ void place(QMdi::Placer *placer, QMdiSubWindow *child);
+ void rearrange(QMdi::Rearranger *rearranger);
+ void arrangeMinimizedSubWindows();
+ void activateWindow(QMdiSubWindow *child);
+ void activateCurrentWindow();
+ void activateHighlightedWindow();
+ void emitWindowActivated(QMdiSubWindow *child);
+ void resetActiveWindow(QMdiSubWindow *child = 0);
+ void updateActiveWindow(int removedIndex, bool activeRemoved);
+ void updateScrollBars();
+ void internalRaise(QMdiSubWindow *child) const;
+ bool scrollBarsEnabled() const;
+ bool lastWindowAboutToBeDestroyed() const;
+ void setChildActivationEnabled(bool enable = true, bool onlyNextActivationEvent = false) const;
+ QRect resizeToMinimumTileSize(const QSize &minSubWindowSize, int subWindowCount);
+ void scrollBarPolicyChanged(Qt::Orientation, Qt::ScrollBarPolicy); // reimp
+ QMdiSubWindow *nextVisibleSubWindow(int increaseFactor, QMdiArea::WindowOrder,
+ int removed = -1, int fromIndex = -1) const;
+ void highlightNextSubWindow(int increaseFactor);
+ QList<QMdiSubWindow *> subWindowList(QMdiArea::WindowOrder, bool reversed = false) const;
+ void disconnectSubWindow(QObject *subWindow);
+ void setViewMode(QMdiArea::ViewMode mode);
+#ifndef QT_NO_TABBAR
+ void updateTabBarGeometry();
+ void refreshTabBar();
+#endif
+
+ inline void startResizeTimer()
+ {
+ Q_Q(QMdiArea);
+ if (resizeTimerId > 0)
+ q->killTimer(resizeTimerId);
+ resizeTimerId = q->startTimer(200);
+ }
+
+ inline void startTabToPreviousTimer()
+ {
+ Q_Q(QMdiArea);
+ if (tabToPreviousTimerId > 0)
+ q->killTimer(tabToPreviousTimerId);
+ tabToPreviousTimerId = q->startTimer(QApplication::keyboardInputInterval());
+ }
+
+ inline bool windowStaysOnTop(QMdiSubWindow *subWindow) const
+ {
+ if (!subWindow)
+ return false;
+ return subWindow->windowFlags() & Qt::WindowStaysOnTopHint;
+ }
+
+ inline bool isExplicitlyDeactivated(QMdiSubWindow *subWindow) const
+ {
+ if (!subWindow)
+ return true;
+ return subWindow->d_func()->isExplicitlyDeactivated;
+ }
+
+ inline void setActive(QMdiSubWindow *subWindow, bool active = true, bool changeFocus = true) const
+ {
+ if (subWindow)
+ subWindow->d_func()->setActive(active, changeFocus);
+ }
+
+#ifndef QT_NO_RUBBERBAND
+ inline void showRubberBandFor(QMdiSubWindow *subWindow)
+ {
+ if (!subWindow || !rubberBand)
+ return;
+ rubberBand->setGeometry(subWindow->geometry());
+ rubberBand->raise();
+ rubberBand->show();
+ }
+
+ inline void hideRubberBand()
+ {
+ if (rubberBand && rubberBand->isVisible())
+ rubberBand->hide();
+ indexToHighlighted = -1;
+ }
+#endif // QT_NO_RUBBERBAND
+};
+
+#endif // QT_NO_MDIAREA
+
+QT_END_NAMESPACE
+
+#endif // QMDIAREA_P_H
diff --git a/src/gui/widgets/qmdisubwindow.cpp b/src/widgets/widgets/qmdisubwindow.cpp
index 5cbd6208cf..5cbd6208cf 100644
--- a/src/gui/widgets/qmdisubwindow.cpp
+++ b/src/widgets/widgets/qmdisubwindow.cpp
diff --git a/src/widgets/widgets/qmdisubwindow.h b/src/widgets/widgets/qmdisubwindow.h
new file mode 100644
index 0000000000..88074c7ca5
--- /dev/null
+++ b/src/widgets/widgets/qmdisubwindow.h
@@ -0,0 +1,159 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMDISUBWINDOW_H
+#define QMDISUBWINDOW_H
+
+#include <QtWidgets/qwidget.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_MDIAREA
+
+class QMenu;
+class QMdiArea;
+
+namespace QMdi { class ControlContainer; }
+class QMdiSubWindowPrivate;
+class Q_WIDGETS_EXPORT QMdiSubWindow : public QWidget
+{
+ Q_OBJECT
+ Q_PROPERTY(int keyboardSingleStep READ keyboardSingleStep WRITE setKeyboardSingleStep)
+ Q_PROPERTY(int keyboardPageStep READ keyboardPageStep WRITE setKeyboardPageStep)
+public:
+ enum SubWindowOption {
+ AllowOutsideAreaHorizontally = 0x1, // internal
+ AllowOutsideAreaVertically = 0x2, // internal
+ RubberBandResize = 0x4,
+ RubberBandMove = 0x8
+ };
+ Q_DECLARE_FLAGS(SubWindowOptions, SubWindowOption)
+
+ QMdiSubWindow(QWidget *parent = 0, Qt::WindowFlags flags = 0);
+ ~QMdiSubWindow();
+
+ QSize sizeHint() const;
+ QSize minimumSizeHint() const;
+
+ void setWidget(QWidget *widget);
+ QWidget *widget() const;
+
+ QWidget *maximizedButtonsWidget() const; // internal
+ QWidget *maximizedSystemMenuIconWidget() const; // internal
+
+ bool isShaded() const;
+
+ void setOption(SubWindowOption option, bool on = true);
+ bool testOption(SubWindowOption) const;
+
+ void setKeyboardSingleStep(int step);
+ int keyboardSingleStep() const;
+
+ void setKeyboardPageStep(int step);
+ int keyboardPageStep() const;
+
+#ifndef QT_NO_MENU
+ void setSystemMenu(QMenu *systemMenu);
+ QMenu *systemMenu() const;
+#endif
+
+ QMdiArea *mdiArea() const;
+
+Q_SIGNALS:
+ void windowStateChanged(Qt::WindowStates oldState, Qt::WindowStates newState);
+ void aboutToActivate();
+
+public Q_SLOTS:
+#ifndef QT_NO_MENU
+ void showSystemMenu();
+#endif
+ void showShaded();
+
+protected:
+ bool eventFilter(QObject *object, QEvent *event);
+ bool event(QEvent *event);
+ void showEvent(QShowEvent *showEvent);
+ void hideEvent(QHideEvent *hideEvent);
+ void changeEvent(QEvent *changeEvent);
+ void closeEvent(QCloseEvent *closeEvent);
+ void leaveEvent(QEvent *leaveEvent);
+ void resizeEvent(QResizeEvent *resizeEvent);
+ void timerEvent(QTimerEvent *timerEvent);
+ void moveEvent(QMoveEvent *moveEvent);
+ void paintEvent(QPaintEvent *paintEvent);
+ void mousePressEvent(QMouseEvent *mouseEvent);
+ void mouseDoubleClickEvent(QMouseEvent *mouseEvent);
+ void mouseReleaseEvent(QMouseEvent *mouseEvent);
+ void mouseMoveEvent(QMouseEvent *mouseEvent);
+ void keyPressEvent(QKeyEvent *keyEvent);
+#ifndef QT_NO_CONTEXTMENU
+ void contextMenuEvent(QContextMenuEvent *contextMenuEvent);
+#endif
+ void focusInEvent(QFocusEvent *focusInEvent);
+ void focusOutEvent(QFocusEvent *focusOutEvent);
+ void childEvent(QChildEvent *childEvent);
+
+private:
+ Q_DISABLE_COPY(QMdiSubWindow)
+ Q_DECLARE_PRIVATE(QMdiSubWindow)
+ Q_PRIVATE_SLOT(d_func(), void _q_updateStaysOnTopHint())
+ Q_PRIVATE_SLOT(d_func(), void _q_enterInteractiveMode())
+ Q_PRIVATE_SLOT(d_func(), void _q_processFocusChanged(QWidget *, QWidget *))
+ friend class QMdiAreaPrivate;
+#ifndef QT_NO_TABBAR
+ friend class QMdiAreaTabBar;
+#endif
+ friend class QMdi::ControlContainer;
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QMdiSubWindow::SubWindowOptions)
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QT_NO_MDIAREA
+
+#endif // QMDISUBWINDOW_H
diff --git a/src/gui/widgets/qmdisubwindow_p.h b/src/widgets/widgets/qmdisubwindow_p.h
index d04a7d4b75..d04a7d4b75 100644
--- a/src/gui/widgets/qmdisubwindow_p.h
+++ b/src/widgets/widgets/qmdisubwindow_p.h
diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp
new file mode 100644
index 0000000000..67dbd7e265
--- /dev/null
+++ b/src/widgets/widgets/qmenu.cpp
@@ -0,0 +1,3100 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmenu.h"
+
+#ifndef QT_NO_MENU
+
+#include "qdebug.h"
+#include "qstyle.h"
+#include "qevent.h"
+#include "qtimer.h"
+#include "qlayout.h"
+#include "qpainter.h"
+#include "qapplication.h"
+#include "qdesktopwidget.h"
+#ifndef QT_NO_ACCESSIBILITY
+# include "qaccessible.h"
+#endif
+#ifndef QT_NO_EFFECTS
+# include <private/qeffects_p.h>
+#endif
+#ifndef QT_NO_WHATSTHIS
+# include <qwhatsthis.h>
+#endif
+
+#include "qmenu_p.h"
+#include "qmenubar_p.h"
+#include "qwidgetaction.h"
+#include "qtoolbutton.h"
+#include "qpushbutton.h"
+#include <private/qpushbutton_p.h>
+#include <private/qaction_p.h>
+#include <private/qsoftkeymanager_p.h>
+
+#ifdef Q_WS_X11
+# include <private/qt_x11_p.h>
+#endif
+
+#if defined(Q_OS_MAC) && !defined(QT_NO_EFFECTS)
+# include <private/qcore_mac_p.h>
+# include <private/qt_cocoa_helpers_mac_p.h>
+#endif
+
+
+QT_BEGIN_NAMESPACE
+
+QMenu *QMenuPrivate::mouseDown = 0;
+int QMenuPrivate::sloppyDelayTimer = 0;
+
+/* QMenu code */
+// internal class used for the torn off popup
+class QTornOffMenu : public QMenu
+{
+ Q_OBJECT
+ class QTornOffMenuPrivate : public QMenuPrivate
+ {
+ Q_DECLARE_PUBLIC(QMenu)
+ public:
+ QTornOffMenuPrivate(QMenu *p) : causedMenu(p) {
+ tornoff = 1;
+ causedPopup.widget = 0;
+ causedPopup.action = ((QTornOffMenu*)p)->d_func()->causedPopup.action;
+ causedStack = ((QTornOffMenu*)p)->d_func()->calcCausedStack();
+ }
+ QList<QPointer<QWidget> > calcCausedStack() const { return causedStack; }
+ QPointer<QMenu> causedMenu;
+ QList<QPointer<QWidget> > causedStack;
+ };
+public:
+ QTornOffMenu(QMenu *p) : QMenu(*(new QTornOffMenuPrivate(p)))
+ {
+ Q_D(QTornOffMenu);
+ // make the torn-off menu a sibling of p (instead of a child)
+ QWidget *parentWidget = d->causedStack.isEmpty() ? p : d->causedStack.last();
+ if (parentWidget->parentWidget())
+ parentWidget = parentWidget->parentWidget();
+ setParent(parentWidget, Qt::Window | Qt::Tool);
+ setAttribute(Qt::WA_DeleteOnClose, true);
+ setAttribute(Qt::WA_X11NetWmWindowTypeMenu, true);
+ setWindowTitle(p->windowTitle());
+ setEnabled(p->isEnabled());
+ //QObject::connect(this, SIGNAL(triggered(QAction*)), this, SLOT(onTrigger(QAction*)));
+ //QObject::connect(this, SIGNAL(hovered(QAction*)), this, SLOT(onHovered(QAction*)));
+ QList<QAction*> items = p->actions();
+ for(int i = 0; i < items.count(); i++)
+ addAction(items.at(i));
+ }
+ void syncWithMenu(QMenu *menu, QActionEvent *act)
+ {
+ Q_D(QTornOffMenu);
+ if(menu != d->causedMenu)
+ return;
+ if (act->type() == QEvent::ActionAdded) {
+ insertAction(act->before(), act->action());
+ } else if (act->type() == QEvent::ActionRemoved)
+ removeAction(act->action());
+ }
+ void actionEvent(QActionEvent *e)
+ {
+ QMenu::actionEvent(e);
+ setFixedSize(sizeHint());
+ }
+public slots:
+ void onTrigger(QAction *action) { d_func()->activateAction(action, QAction::Trigger, false); }
+ void onHovered(QAction *action) { d_func()->activateAction(action, QAction::Hover, false); }
+private:
+ Q_DECLARE_PRIVATE(QTornOffMenu)
+ friend class QMenuPrivate;
+};
+
+void QMenuPrivate::init()
+{
+ Q_Q(QMenu);
+#ifndef QT_NO_WHATSTHIS
+ q->setAttribute(Qt::WA_CustomWhatsThis);
+#endif
+ q->setAttribute(Qt::WA_X11NetWmWindowTypePopupMenu);
+ defaultMenuAction = menuAction = new QAction(q);
+ menuAction->d_func()->menu = q;
+ q->setMouseTracking(q->style()->styleHint(QStyle::SH_Menu_MouseTracking, 0, q));
+ if (q->style()->styleHint(QStyle::SH_Menu_Scrollable, 0, q)) {
+ scroll = new QMenuPrivate::QMenuScroller;
+ scroll->scrollFlags = QMenuPrivate::QMenuScroller::ScrollNone;
+ }
+
+ platformMenu = QGuiApplicationPrivate::platformIntegration()->createPlatformMenu(q);
+
+#ifdef QT_SOFTKEYS_ENABLED
+ selectAction = QSoftKeyManager::createKeyedAction(QSoftKeyManager::SelectSoftKey, Qt::Key_Select, q);
+ cancelAction = QSoftKeyManager::createKeyedAction(QSoftKeyManager::CancelSoftKey, Qt::Key_Back, q);
+ selectAction->setPriority(QAction::HighPriority);
+ cancelAction->setPriority(QAction::HighPriority);
+ q->addAction(selectAction);
+ q->addAction(cancelAction);
+#endif
+}
+
+int QMenuPrivate::scrollerHeight() const
+{
+ Q_Q(const QMenu);
+ return qMax(QApplication::globalStrut().height(), q->style()->pixelMetric(QStyle::PM_MenuScrollerHeight, 0, q));
+}
+
+//Windows and KDE allows menus to cover the taskbar, while GNOME and Mac don't
+QRect QMenuPrivate::popupGeometry(const QWidget *widget) const
+{
+#ifdef Q_WS_WIN
+ return QApplication::desktop()->screenGeometry(widget);
+#elif defined Q_WS_X11
+ if (X11->desktopEnvironment == DE_KDE)
+ return QApplication::desktop()->screenGeometry(widget);
+ else
+ return QApplication::desktop()->availableGeometry(widget);
+#else
+ return QApplication::desktop()->availableGeometry(widget);
+#endif
+}
+
+//Windows and KDE allows menus to cover the taskbar, while GNOME and Mac don't
+QRect QMenuPrivate::popupGeometry(int screen) const
+{
+#ifdef Q_WS_WIN
+ return QApplication::desktop()->screenGeometry(screen);
+#elif defined Q_WS_X11
+ if (X11->desktopEnvironment == DE_KDE)
+ return QApplication::desktop()->screenGeometry(screen);
+ else
+ return QApplication::desktop()->availableGeometry(screen);
+#else
+ return QApplication::desktop()->availableGeometry(screen);
+#endif
+}
+
+QList<QPointer<QWidget> > QMenuPrivate::calcCausedStack() const
+{
+ QList<QPointer<QWidget> > ret;
+ for(QWidget *widget = causedPopup.widget; widget; ) {
+ ret.append(widget);
+ if (QTornOffMenu *qtmenu = qobject_cast<QTornOffMenu*>(widget))
+ ret += qtmenu->d_func()->causedStack;
+ if (QMenu *qmenu = qobject_cast<QMenu*>(widget))
+ widget = qmenu->d_func()->causedPopup.widget;
+ else
+ break;
+ }
+ return ret;
+}
+
+void QMenuPrivate::updateActionRects() const
+{
+ Q_Q(const QMenu);
+ updateActionRects(popupGeometry(q));
+}
+
+void QMenuPrivate::updateActionRects(const QRect &screen) const
+{
+ Q_Q(const QMenu);
+ if (!itemsDirty)
+ return;
+
+ q->ensurePolished();
+
+ //let's reinitialize the buffer
+ actionRects.resize(actions.count());
+ actionRects.fill(QRect());
+
+ int lastVisibleAction = getLastVisibleAction();
+
+ int max_column_width = 0,
+ dh = screen.height(),
+ y = 0;
+ QStyle *style = q->style();
+ QStyleOption opt;
+ opt.init(q);
+ const int hmargin = style->pixelMetric(QStyle::PM_MenuHMargin, &opt, q),
+ vmargin = style->pixelMetric(QStyle::PM_MenuVMargin, &opt, q),
+ icone = style->pixelMetric(QStyle::PM_SmallIconSize, &opt, q);
+ const int fw = style->pixelMetric(QStyle::PM_MenuPanelWidth, &opt, q);
+ const int deskFw = style->pixelMetric(QStyle::PM_MenuDesktopFrameWidth, &opt, q);
+ const int tearoffHeight = tearoff ? style->pixelMetric(QStyle::PM_MenuTearoffHeight, &opt, q) : 0;
+
+ //for compatibility now - will have to refactor this away
+ tabWidth = 0;
+ maxIconWidth = 0;
+ hasCheckableItems = false;
+ ncols = 1;
+ sloppyAction = 0;
+
+ for (int i = 0; i < actions.count(); ++i) {
+ QAction *action = actions.at(i);
+ if (action->isSeparator() || !action->isVisible() || widgetItems.contains(action))
+ continue;
+ //..and some members
+ hasCheckableItems |= action->isCheckable();
+ QIcon is = action->icon();
+ if (!is.isNull()) {
+ maxIconWidth = qMax<uint>(maxIconWidth, icone + 4);
+ }
+ }
+
+ //calculate size
+ QFontMetrics qfm = q->fontMetrics();
+ bool previousWasSeparator = true; // this is true to allow removing the leading separators
+ for(int i = 0; i <= lastVisibleAction; i++) {
+ QAction *action = actions.at(i);
+
+ if (!action->isVisible() ||
+ (collapsibleSeparators && previousWasSeparator && action->isSeparator()))
+ continue; // we continue, this action will get an empty QRect
+
+ previousWasSeparator = action->isSeparator();
+
+ //let the style modify the above size..
+ QStyleOptionMenuItem opt;
+ q->initStyleOption(&opt, action);
+ const QFontMetrics &fm = opt.fontMetrics;
+
+ QSize sz;
+ if (QWidget *w = widgetItems.value(action)) {
+ sz = w->sizeHint().expandedTo(w->minimumSize()).expandedTo(w->minimumSizeHint()).boundedTo(w->maximumSize());
+ } else {
+ //calc what I think the size is..
+ if (action->isSeparator()) {
+ sz = QSize(2, 2);
+ } else {
+ QString s = action->text();
+ int t = s.indexOf(QLatin1Char('\t'));
+ if (t != -1) {
+ tabWidth = qMax(int(tabWidth), qfm.width(s.mid(t+1)));
+ s = s.left(t);
+ #ifndef QT_NO_SHORTCUT
+ } else {
+ QKeySequence seq = action->shortcut();
+ if (!seq.isEmpty())
+ tabWidth = qMax(int(tabWidth), qfm.width(seq));
+ #endif
+ }
+ sz.setWidth(fm.boundingRect(QRect(), Qt::TextSingleLine | Qt::TextShowMnemonic, s).width());
+ sz.setHeight(qMax(fm.height(), qfm.height()));
+
+ QIcon is = action->icon();
+ if (!is.isNull()) {
+ QSize is_sz = QSize(icone, icone);
+ if (is_sz.height() > sz.height())
+ sz.setHeight(is_sz.height());
+ }
+ }
+ sz = style->sizeFromContents(QStyle::CT_MenuItem, &opt, sz, q);
+ }
+
+
+ if (!sz.isEmpty()) {
+ max_column_width = qMax(max_column_width, sz.width());
+ //wrapping
+ if (!scroll &&
+ y+sz.height()+vmargin > dh - (deskFw * 2)) {
+ ncols++;
+ y = vmargin;
+ }
+ y += sz.height();
+ //update the item
+ actionRects[i] = QRect(0, 0, sz.width(), sz.height());
+ }
+ }
+
+ max_column_width += tabWidth; //finally add in the tab width
+ const int sfcMargin = style->sizeFromContents(QStyle::CT_Menu, &opt, QApplication::globalStrut(), q).width() - QApplication::globalStrut().width();
+ const int min_column_width = q->minimumWidth() - (sfcMargin + leftmargin + rightmargin + 2 * (fw + hmargin));
+ max_column_width = qMax(min_column_width, max_column_width);
+
+ //calculate position
+ const int base_y = vmargin + fw + topmargin +
+ (scroll ? scroll->scrollOffset : 0) +
+ tearoffHeight;
+ int x = hmargin + fw + leftmargin;
+ y = base_y;
+
+ for(int i = 0; i < actions.count(); i++) {
+ QRect &rect = actionRects[i];
+ if (rect.isNull())
+ continue;
+ if (!scroll &&
+ y+rect.height() > dh - deskFw * 2) {
+ x += max_column_width + hmargin;
+ y = base_y;
+ }
+ rect.translate(x, y); //move
+ rect.setWidth(max_column_width); //uniform width
+
+ //we need to update the widgets geometry
+ if (QWidget *widget = widgetItems.value(actions.at(i))) {
+ widget->setGeometry(rect);
+ widget->setVisible(actions.at(i)->isVisible());
+ }
+
+ y += rect.height();
+ }
+ itemsDirty = 0;
+}
+
+QSize QMenuPrivate::adjustMenuSizeForScreen(const QRect &screen)
+{
+ Q_Q(QMenu);
+ QSize ret = screen.size();
+ itemsDirty = true;
+ updateActionRects(screen);
+ const int fw = q->style()->pixelMetric(QStyle::PM_MenuPanelWidth, 0, q);
+ ret.setWidth(actionRects.at(getLastVisibleAction()).right() + fw);
+ return ret;
+}
+
+int QMenuPrivate::getLastVisibleAction() const
+{
+ //let's try to get the last visible action
+ int lastVisibleAction = actions.count() - 1;
+ for (;lastVisibleAction >= 0; --lastVisibleAction) {
+ const QAction *action = actions.at(lastVisibleAction);
+ if (action->isVisible()) {
+ //removing trailing separators
+ if (action->isSeparator() && collapsibleSeparators)
+ continue;
+ break;
+ }
+ }
+ return lastVisibleAction;
+}
+
+
+QRect QMenuPrivate::actionRect(QAction *act) const
+{
+ int index = actions.indexOf(act);
+ if (index == -1)
+ return QRect();
+
+ updateActionRects();
+
+ //we found the action
+ return actionRects.at(index);
+}
+
+#if defined(Q_OS_MAC)
+static const qreal MenuFadeTimeInSec = 0.150;
+#endif
+
+void QMenuPrivate::hideUpToMenuBar()
+{
+ Q_Q(QMenu);
+ bool fadeMenus = q->style()->styleHint(QStyle::SH_Menu_FadeOutOnHide);
+ if (!tornoff) {
+ QWidget *caused = causedPopup.widget;
+ hideMenu(q); //hide after getting causedPopup
+ while(caused) {
+#ifndef QT_NO_MENUBAR
+ if (QMenuBar *mb = qobject_cast<QMenuBar*>(caused)) {
+ mb->d_func()->setCurrentAction(0);
+ mb->d_func()->setKeyboardMode(false);
+ caused = 0;
+ } else
+#endif
+ if (QMenu *m = qobject_cast<QMenu*>(caused)) {
+ caused = m->d_func()->causedPopup.widget;
+ if (!m->d_func()->tornoff)
+ hideMenu(m, fadeMenus);
+ if (!fadeMenus) // Mac doesn't clear the action until after hidden.
+ m->d_func()->setCurrentAction(0);
+ } else { caused = 0;
+ }
+ }
+#if defined(Q_WS_MAC)
+ if (fadeMenus) {
+ QEventLoop eventLoop;
+ QTimer::singleShot(int(MenuFadeTimeInSec * 1000), &eventLoop, SLOT(quit()));
+ QMacWindowFader::currentFader()->performFade();
+ eventLoop.exec();
+ }
+#endif
+ }
+ setCurrentAction(0);
+}
+
+void QMenuPrivate::hideMenu(QMenu *menu, bool justRegister)
+{
+ if (!menu)
+ return;
+#if !defined(QT_NO_EFFECTS)
+ menu->blockSignals(true);
+ aboutToHide = true;
+ // Flash item which is about to trigger (if any).
+ if (menu->style()->styleHint(QStyle::SH_Menu_FlashTriggeredItem)
+ && currentAction && currentAction == actionAboutToTrigger
+ && menu->actions().contains(currentAction)) {
+ QEventLoop eventLoop;
+ QAction *activeAction = currentAction;
+
+ menu->setActiveAction(0);
+ QTimer::singleShot(60, &eventLoop, SLOT(quit()));
+ eventLoop.exec();
+
+ // Select and wait 20 ms.
+ menu->setActiveAction(activeAction);
+ QTimer::singleShot(20, &eventLoop, SLOT(quit()));
+ eventLoop.exec();
+ }
+
+ // Fade out.
+ if (menu->style()->styleHint(QStyle::SH_Menu_FadeOutOnHide)) {
+ // ### Qt 4.4:
+ // Should be something like: q->transitionWindow(Qt::FadeOutTransition, MenuFadeTimeInSec);
+ // Hopefully we'll integrate qt/research/windowtransitions into main before 4.4.
+ // Talk to Richard, Trenton or Bjoern.
+#if defined(Q_WS_MAC)
+ if (justRegister) {
+ QMacWindowFader::currentFader()->setFadeDuration(MenuFadeTimeInSec);
+ QMacWindowFader::currentFader()->registerWindowToFade(menu);
+ } else {
+ macWindowFade(qt_mac_window_for(menu), MenuFadeTimeInSec);
+ }
+
+#endif // Q_WS_MAC
+ }
+ aboutToHide = false;
+ menu->blockSignals(false);
+#endif // QT_NO_EFFECTS
+ if (!justRegister)
+ menu->hide();
+}
+
+void QMenuPrivate::popupAction(QAction *action, int delay, bool activateFirst)
+{
+ Q_Q(QMenu);
+ if (action && action->isEnabled()) {
+ if (!delay)
+ q->internalDelayedPopup();
+ else if (!menuDelayTimer.isActive() && (!action->menu() || !action->menu()->isVisible()))
+ menuDelayTimer.start(delay, q);
+ if (activateFirst && action->menu())
+ action->menu()->d_func()->setFirstActionActive();
+ } else if (QMenu *menu = activeMenu) { //hide the current item
+ activeMenu = 0;
+ hideMenu(menu);
+ }
+}
+
+void QMenuPrivate::setSyncAction()
+{
+ Q_Q(QMenu);
+ QAction *current = currentAction;
+ if(current && (!current->isEnabled() || current->menu() || current->isSeparator()))
+ current = 0;
+ for(QWidget *caused = q; caused;) {
+ if (QMenu *m = qobject_cast<QMenu*>(caused)) {
+ caused = m->d_func()->causedPopup.widget;
+ if (m->d_func()->eventLoop)
+ m->d_func()->syncAction = current; // synchronous operation
+ } else {
+ break;
+ }
+ }
+}
+
+
+void QMenuPrivate::setFirstActionActive()
+{
+ Q_Q(QMenu);
+ updateActionRects();
+ for(int i = 0, saccum = 0; i < actions.count(); i++) {
+ const QRect &rect = actionRects.at(i);
+ if (rect.isNull())
+ continue;
+ if (scroll && scroll->scrollFlags & QMenuScroller::ScrollUp) {
+ saccum -= rect.height();
+ if (saccum > scroll->scrollOffset - scrollerHeight())
+ continue;
+ }
+ QAction *act = actions.at(i);
+ if (!act->isSeparator() &&
+ (q->style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, q)
+ || act->isEnabled())) {
+ setCurrentAction(act);
+ break;
+ }
+ }
+}
+
+// popup == -1 means do not popup, 0 means immediately, others mean use a timer
+void QMenuPrivate::setCurrentAction(QAction *action, int popup, SelectionReason reason, bool activateFirst)
+{
+ Q_Q(QMenu);
+ tearoffHighlighted = 0;
+ if (currentAction)
+ q->update(actionRect(currentAction));
+
+ sloppyAction = 0;
+ if (!sloppyRegion.isEmpty())
+ sloppyRegion = QRegion();
+ QMenu *hideActiveMenu = activeMenu;
+#ifndef QT_NO_STATUSTIP
+ QAction *previousAction = currentAction;
+#endif
+
+ currentAction = action;
+ if (action) {
+ if (!action->isSeparator()) {
+ activateAction(action, QAction::Hover);
+ if (popup != -1) {
+ hideActiveMenu = 0; //will be done "later"
+ // if the menu is visible then activate the required action,
+ // otherwise we just mark the action as currentAction
+ // and activate it when the menu will be popuped.
+ if (q->isVisible())
+ popupAction(currentAction, popup, activateFirst);
+ }
+ q->update(actionRect(action));
+
+ if (reason == SelectedFromKeyboard) {
+ QWidget *widget = widgetItems.value(action);
+ if (widget) {
+ if (widget->focusPolicy() != Qt::NoFocus)
+ widget->setFocus(Qt::TabFocusReason);
+ } else {
+ //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.
+ if (!q->hasFocus()) {
+ q->setFocus(Qt::PopupFocusReason);
+ }
+ }
+ }
+ } else { //action is a separator
+ if (popup != -1)
+ hideActiveMenu = 0; //will be done "later"
+ }
+#ifndef QT_NO_STATUSTIP
+ } else if (previousAction) {
+ previousAction->d_func()->showStatusText(topCausedWidget(), QString());
+#endif
+ }
+ if (hideActiveMenu) {
+ activeMenu = 0;
+#ifndef QT_NO_EFFECTS
+ // kill any running effect
+ qFadeEffect(0);
+ qScrollEffect(0);
+#endif
+ hideMenu(hideActiveMenu);
+ }
+}
+
+//return the top causedPopup.widget that is not a QMenu
+QWidget *QMenuPrivate::topCausedWidget() const
+{
+ QWidget* top = causedPopup.widget;
+ while (QMenu* m = qobject_cast<QMenu *>(top))
+ top = m->d_func()->causedPopup.widget;
+ return top;
+}
+
+QAction *QMenuPrivate::actionAt(QPoint p) const
+{
+ if (!q_func()->rect().contains(p)) //sanity check
+ return 0;
+
+ for(int i = 0; i < actionRects.count(); i++) {
+ if (actionRects.at(i).contains(p))
+ return actions.at(i);
+ }
+ return 0;
+}
+
+void QMenuPrivate::setOverrideMenuAction(QAction *a)
+{
+ Q_Q(QMenu);
+ QObject::disconnect(menuAction, SIGNAL(destroyed()), q, SLOT(_q_overrideMenuActionDestroyed()));
+ if (a) {
+ menuAction = a;
+ QObject::connect(a, SIGNAL(destroyed()), q, SLOT(_q_overrideMenuActionDestroyed()));
+ } else { //we revert back to the default action created by the QMenu itself
+ menuAction = defaultMenuAction;
+ }
+}
+
+void QMenuPrivate::_q_overrideMenuActionDestroyed()
+{
+ menuAction=defaultMenuAction;
+}
+
+
+void QMenuPrivate::updateLayoutDirection()
+{
+ Q_Q(QMenu);
+ //we need to mimic the cause of the popup's layout direction
+ //to allow setting it on a mainwindow for example
+ //we call setLayoutDirection_helper to not overwrite a user-defined value
+ if (!q->testAttribute(Qt::WA_SetLayoutDirection)) {
+ if (QWidget *w = causedPopup.widget)
+ setLayoutDirection_helper(w->layoutDirection());
+ else if (QWidget *w = q->parentWidget())
+ setLayoutDirection_helper(w->layoutDirection());
+ else
+ setLayoutDirection_helper(QApplication::layoutDirection());
+ }
+}
+
+
+/*!
+ Returns the action associated with this menu.
+*/
+QAction *QMenu::menuAction() const
+{
+ return d_func()->menuAction;
+}
+
+/*!
+ \property QMenu::title
+ \brief The title of the menu
+
+ This is equivalent to the QAction::text property of the menuAction().
+
+ By default, this property contains an empty string.
+*/
+QString QMenu::title() const
+{
+ return d_func()->menuAction->text();
+}
+
+void QMenu::setTitle(const QString &text)
+{
+ d_func()->menuAction->setText(text);
+}
+
+/*!
+ \property QMenu::icon
+
+ \brief The icon of the menu
+
+ This is equivalent to the QAction::icon property of the menuAction().
+
+ By default, if no icon is explicitly set, this property contains a null icon.
+*/
+QIcon QMenu::icon() const
+{
+ return d_func()->menuAction->icon();
+}
+
+void QMenu::setIcon(const QIcon &icon)
+{
+ d_func()->menuAction->setIcon(icon);
+}
+
+
+//actually performs the scrolling
+void QMenuPrivate::scrollMenu(QAction *action, QMenuScroller::ScrollLocation location, bool active)
+{
+ Q_Q(QMenu);
+ if (!scroll || !scroll->scrollFlags)
+ return;
+ updateActionRects();
+ int newOffset = 0;
+ const int topScroll = (scroll->scrollFlags & QMenuScroller::ScrollUp) ? scrollerHeight() : 0;
+ const int botScroll = (scroll->scrollFlags & QMenuScroller::ScrollDown) ? scrollerHeight() : 0;
+ const int vmargin = q->style()->pixelMetric(QStyle::PM_MenuVMargin, 0, q);
+ const int fw = q->style()->pixelMetric(QStyle::PM_MenuPanelWidth, 0, q);
+
+ if (location == QMenuScroller::ScrollTop) {
+ for(int i = 0, saccum = 0; i < actions.count(); i++) {
+ if (actions.at(i) == action) {
+ newOffset = topScroll - saccum;
+ break;
+ }
+ saccum += actionRects.at(i).height();
+ }
+ } else {
+ for(int i = 0, saccum = 0; i < actions.count(); i++) {
+ saccum += actionRects.at(i).height();
+ if (actions.at(i) == action) {
+ if (location == QMenuScroller::ScrollCenter)
+ newOffset = ((q->height() / 2) - botScroll) - (saccum - topScroll);
+ else
+ newOffset = (q->height() - botScroll) - saccum;
+ break;
+ }
+ }
+ if(newOffset)
+ newOffset -= fw * 2;
+ }
+
+ //figure out which scroll flags
+ uint newScrollFlags = QMenuScroller::ScrollNone;
+ if (newOffset < 0) //easy and cheap one
+ newScrollFlags |= QMenuScroller::ScrollUp;
+ int saccum = newOffset;
+ for(int i = 0; i < actionRects.count(); i++) {
+ saccum += actionRects.at(i).height();
+ if (saccum > q->height()) {
+ newScrollFlags |= QMenuScroller::ScrollDown;
+ break;
+ }
+ }
+
+ if (!(newScrollFlags & QMenuScroller::ScrollDown) && (scroll->scrollFlags & QMenuScroller::ScrollDown)) {
+ newOffset = q->height() - (saccum - newOffset) - fw*2 - vmargin; //last item at bottom
+ }
+
+ if (!(newScrollFlags & QMenuScroller::ScrollUp) && (scroll->scrollFlags & QMenuScroller::ScrollUp)) {
+ newOffset = 0; //first item at top
+ }
+
+ if (newScrollFlags & QMenuScroller::ScrollUp)
+ newOffset -= vmargin;
+
+ QRect screen = popupGeometry(q);
+ const int desktopFrame = q->style()->pixelMetric(QStyle::PM_MenuDesktopFrameWidth, 0, q);
+ if (q->height() < screen.height()-(desktopFrame*2)-1) {
+ QRect geom = q->geometry();
+ if (newOffset > scroll->scrollOffset && (scroll->scrollFlags & newScrollFlags & QMenuScroller::ScrollUp)) { //scroll up
+ const int newHeight = geom.height()-(newOffset-scroll->scrollOffset);
+ if(newHeight > geom.height())
+ geom.setHeight(newHeight);
+ } else if(scroll->scrollFlags & newScrollFlags & QMenuScroller::ScrollDown) {
+ int newTop = geom.top() + (newOffset-scroll->scrollOffset);
+ if (newTop < desktopFrame+screen.top())
+ newTop = desktopFrame+screen.top();
+ if (newTop < geom.top()) {
+ geom.setTop(newTop);
+ newOffset = 0;
+ newScrollFlags &= ~QMenuScroller::ScrollUp;
+ }
+ }
+ if (geom.bottom() > screen.bottom() - desktopFrame)
+ geom.setBottom(screen.bottom() - desktopFrame);
+ if (geom.top() < desktopFrame+screen.top())
+ geom.setTop(desktopFrame+screen.top());
+ if (geom != q->geometry()) {
+#if 0
+ if (newScrollFlags & QMenuScroller::ScrollDown &&
+ q->geometry().top() - geom.top() >= -newOffset)
+ newScrollFlags &= ~QMenuScroller::ScrollDown;
+#endif
+ q->setGeometry(geom);
+ }
+ }
+
+ //actually update flags
+ const int delta = qMin(0, newOffset) - scroll->scrollOffset; //make sure the new offset is always negative
+ if (!itemsDirty && delta) {
+ //we've scrolled so we need to update the action rects
+ for (int i = 0; i < actionRects.count(); ++i) {
+ QRect &current = actionRects[i];
+ current.moveTop(current.top() + delta);
+
+ //we need to update the widgets geometry
+ if (QWidget *w = widgetItems.value(actions.at(i)))
+ w->setGeometry(current);
+ }
+ }
+ scroll->scrollOffset += delta;
+ scroll->scrollFlags = newScrollFlags;
+ if (active)
+ setCurrentAction(action);
+
+ q->update(); //issue an update so we see all the new state..
+}
+
+void QMenuPrivate::scrollMenu(QMenuScroller::ScrollLocation location, bool active)
+{
+ Q_Q(QMenu);
+ updateActionRects();
+ if(location == QMenuScroller::ScrollBottom) {
+ for(int i = actions.size()-1; i >= 0; --i) {
+ QAction *act = actions.at(i);
+ if (actionRects.at(i).isNull())
+ continue;
+ if (!act->isSeparator() &&
+ (q->style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, q)
+ || act->isEnabled())) {
+ if(scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollDown)
+ scrollMenu(act, QMenuPrivate::QMenuScroller::ScrollBottom, active);
+ else if(active)
+ setCurrentAction(act, /*popup*/-1, QMenuPrivate::SelectedFromKeyboard);
+ break;
+ }
+ }
+ } else if(location == QMenuScroller::ScrollTop) {
+ for(int i = 0; i < actions.size(); ++i) {
+ QAction *act = actions.at(i);
+ if (actionRects.at(i).isNull())
+ continue;
+ if (!act->isSeparator() &&
+ (q->style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, q)
+ || act->isEnabled())) {
+ if(scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp)
+ scrollMenu(act, QMenuPrivate::QMenuScroller::ScrollTop, active);
+ else if(active)
+ setCurrentAction(act, /*popup*/-1, QMenuPrivate::SelectedFromKeyboard);
+ break;
+ }
+ }
+ }
+}
+
+//only directional
+void QMenuPrivate::scrollMenu(QMenuScroller::ScrollDirection direction, bool page, bool active)
+{
+ Q_Q(QMenu);
+ if (!scroll || !(scroll->scrollFlags & direction)) //not really possible...
+ return;
+ updateActionRects();
+ const int topScroll = (scroll->scrollFlags & QMenuScroller::ScrollUp) ? scrollerHeight() : 0;
+ const int botScroll = (scroll->scrollFlags & QMenuScroller::ScrollDown) ? scrollerHeight() : 0;
+ const int vmargin = q->style()->pixelMetric(QStyle::PM_MenuVMargin, 0, q);
+ const int fw = q->style()->pixelMetric(QStyle::PM_MenuPanelWidth, 0, q);
+ const int offset = topScroll ? topScroll-vmargin : 0;
+ if (direction == QMenuScroller::ScrollUp) {
+ for(int i = 0, saccum = 0; i < actions.count(); i++) {
+ saccum -= actionRects.at(i).height();
+ if (saccum <= scroll->scrollOffset-offset) {
+ scrollMenu(actions.at(i), page ? QMenuScroller::ScrollBottom : QMenuScroller::ScrollTop, active);
+ break;
+ }
+ }
+ } else if (direction == QMenuScroller::ScrollDown) {
+ bool scrolled = false;
+ for(int i = 0, saccum = 0; i < actions.count(); i++) {
+ const int iHeight = actionRects.at(i).height();
+ saccum -= iHeight;
+ if (saccum <= scroll->scrollOffset-offset) {
+ const int scrollerArea = q->height() - botScroll - fw*2;
+ int visible = (scroll->scrollOffset-offset) - saccum;
+ for(i++ ; i < actions.count(); i++) {
+ visible += actionRects.at(i).height();
+ if (visible > scrollerArea - topScroll) {
+ scrolled = true;
+ scrollMenu(actions.at(i), page ? QMenuScroller::ScrollTop : QMenuScroller::ScrollBottom, active);
+ break;
+ }
+ }
+ break;
+ }
+ }
+ if(!scrolled) {
+ scroll->scrollFlags &= ~QMenuScroller::ScrollDown;
+ q->update();
+ }
+ }
+}
+
+/* This is poor-mans eventfilters. This avoids the use of
+ eventFilter (which can be nasty for users of QMenuBar's). */
+bool QMenuPrivate::mouseEventTaken(QMouseEvent *e)
+{
+ Q_Q(QMenu);
+ QPoint pos = q->mapFromGlobal(e->globalPos());
+ if (scroll && !activeMenu) { //let the scroller "steal" the event
+ bool isScroll = false;
+ if (pos.x() >= 0 && pos.x() < q->width()) {
+ for(int dir = QMenuScroller::ScrollUp; dir <= QMenuScroller::ScrollDown; dir = dir << 1) {
+ if (scroll->scrollFlags & dir) {
+ if (dir == QMenuScroller::ScrollUp)
+ isScroll = (pos.y() <= scrollerHeight());
+ else if (dir == QMenuScroller::ScrollDown)
+ isScroll = (pos.y() >= q->height() - scrollerHeight());
+ if (isScroll) {
+ scroll->scrollDirection = dir;
+ break;
+ }
+ }
+ }
+ }
+ if (isScroll) {
+ scroll->scrollTimer.start(50, q);
+ return true;
+ } else {
+ scroll->scrollTimer.stop();
+ }
+ }
+
+ if (tearoff) { //let the tear off thingie "steal" the event..
+ QRect tearRect(0, 0, q->width(), q->style()->pixelMetric(QStyle::PM_MenuTearoffHeight, 0, q));
+ if (scroll && scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp)
+ tearRect.translate(0, scrollerHeight());
+ q->update(tearRect);
+ if (tearRect.contains(pos) && hasMouseMoved(e->globalPos())) {
+ setCurrentAction(0);
+ tearoffHighlighted = 1;
+ if (e->type() == QEvent::MouseButtonRelease) {
+ if (!tornPopup)
+ tornPopup = new QTornOffMenu(q);
+ tornPopup->setGeometry(q->geometry());
+ tornPopup->show();
+ hideUpToMenuBar();
+ }
+ return true;
+ }
+ tearoffHighlighted = 0;
+ }
+
+ if (q->frameGeometry().contains(e->globalPos())) //otherwise if the event is in our rect we want it..
+ return false;
+
+ for(QWidget *caused = causedPopup.widget; caused;) {
+ bool passOnEvent = false;
+ QWidget *next_widget = 0;
+ QPoint cpos = caused->mapFromGlobal(e->globalPos());
+#ifndef QT_NO_MENUBAR
+ if (QMenuBar *mb = qobject_cast<QMenuBar*>(caused)) {
+ passOnEvent = mb->rect().contains(cpos);
+ } else
+#endif
+ if (QMenu *m = qobject_cast<QMenu*>(caused)) {
+ passOnEvent = m->rect().contains(cpos);
+ next_widget = m->d_func()->causedPopup.widget;
+ }
+ if (passOnEvent) {
+ if(e->type() != QEvent::MouseButtonRelease || mouseDown == caused) {
+ QMouseEvent new_e(e->type(), cpos, caused->mapTo(caused->topLevelWidget(), cpos), e->screenPos(),
+ e->button(), e->buttons(), e->modifiers());
+ QApplication::sendEvent(caused, &new_e);
+ return true;
+ }
+ }
+ if (!next_widget)
+ break;
+ caused = next_widget;
+ }
+ return false;
+}
+
+void QMenuPrivate::activateCausedStack(const QList<QPointer<QWidget> > &causedStack, QAction *action, QAction::ActionEvent action_e, bool self)
+{
+ QBoolBlocker guard(activationRecursionGuard);
+ if(self)
+ action->activate(action_e);
+
+ for(int i = 0; i < causedStack.size(); ++i) {
+ QPointer<QWidget> widget = causedStack.at(i);
+ if (!widget)
+ continue;
+ //fire
+ if (QMenu *qmenu = qobject_cast<QMenu*>(widget)) {
+ widget = qmenu->d_func()->causedPopup.widget;
+ if (action_e == QAction::Trigger) {
+ emit qmenu->triggered(action);
+ } else if (action_e == QAction::Hover) {
+ emit qmenu->hovered(action);
+ }
+#ifndef QT_NO_MENUBAR
+ } else if (QMenuBar *qmenubar = qobject_cast<QMenuBar*>(widget)) {
+ if (action_e == QAction::Trigger) {
+ emit qmenubar->triggered(action);
+ } else if (action_e == QAction::Hover) {
+ emit qmenubar->hovered(action);
+ }
+ break; //nothing more..
+#endif
+ }
+ }
+}
+
+void QMenuPrivate::activateAction(QAction *action, QAction::ActionEvent action_e, bool self)
+{
+ Q_Q(QMenu);
+#ifndef QT_NO_WHATSTHIS
+ bool inWhatsThisMode = QWhatsThis::inWhatsThisMode();
+#endif
+ if (!action || !q->isEnabled()
+ || (action_e == QAction::Trigger
+#ifndef QT_NO_WHATSTHIS
+ && !inWhatsThisMode
+#endif
+ && (action->isSeparator() ||!action->isEnabled())))
+ return;
+
+ /* I have to save the caused stack here because it will be undone after popup execution (ie in the hide).
+ Then I iterate over the list to actually send the events. --Sam
+ */
+ const QList<QPointer<QWidget> > causedStack = calcCausedStack();
+ if (action_e == QAction::Trigger) {
+#ifndef QT_NO_WHATSTHIS
+ if (!inWhatsThisMode)
+ actionAboutToTrigger = action;
+#endif
+
+ if (q->testAttribute(Qt::WA_DontShowOnScreen)) {
+ hideUpToMenuBar();
+ } else {
+ for(QWidget *widget = QApplication::activePopupWidget(); widget; ) {
+ if (QMenu *qmenu = qobject_cast<QMenu*>(widget)) {
+ if(qmenu == q)
+ hideUpToMenuBar();
+ widget = qmenu->d_func()->causedPopup.widget;
+ } else {
+ break;
+ }
+ }
+ }
+
+#ifndef QT_NO_WHATSTHIS
+ if (inWhatsThisMode) {
+ QString s = action->whatsThis();
+ if (s.isEmpty())
+ s = whatsThis;
+ QWhatsThis::showText(q->mapToGlobal(actionRect(action).center()), s, q);
+ return;
+ }
+#endif
+ }
+
+
+ activateCausedStack(causedStack, action, action_e, self);
+
+
+ if (action_e == QAction::Hover) {
+#ifndef QT_NO_ACCESSIBILITY
+ if (QAccessible::isActive()) {
+ int actionIndex = indexOf(action) + 1;
+ QAccessible::updateAccessibility(q, actionIndex, QAccessible::Focus);
+ QAccessible::updateAccessibility(q, actionIndex, QAccessible::Selection);
+ }
+#endif
+ action->showStatusText(topCausedWidget());
+ } else {
+ actionAboutToTrigger = 0;
+ }
+}
+
+void QMenuPrivate::_q_actionTriggered()
+{
+ Q_Q(QMenu);
+ if (QAction *action = qobject_cast<QAction *>(q->sender())) {
+ QWeakPointer<QAction> actionGuard = action;
+ emit q->triggered(action);
+ if (!activationRecursionGuard && actionGuard) {
+ //in case the action has not been activated by the mouse
+ //we check the parent hierarchy
+ QList< QPointer<QWidget> > list;
+ for(QWidget *widget = q->parentWidget(); widget; ) {
+ if (qobject_cast<QMenu*>(widget)
+#ifndef QT_NO_MENUBAR
+ || qobject_cast<QMenuBar*>(widget)
+#endif
+ ) {
+ list.append(widget);
+ widget = widget->parentWidget();
+ } else {
+ break;
+ }
+ }
+ activateCausedStack(list, action, QAction::Trigger, false);
+ }
+ }
+}
+
+void QMenuPrivate::_q_actionHovered()
+{
+ Q_Q(QMenu);
+ if (QAction * action = qobject_cast<QAction *>(q->sender())) {
+ emit q->hovered(action);
+ }
+}
+
+bool QMenuPrivate::hasMouseMoved(const QPoint &globalPos)
+{
+ //determines if the mouse has moved (ie its initial position has
+ //changed by more than QApplication::startDragDistance()
+ //or if there were at least 6 mouse motions)
+ return motions > 6 ||
+ QApplication::startDragDistance() < (mousePopupPos - globalPos).manhattanLength();
+}
+
+
+/*!
+ Initialize \a option with the values from this menu and information from \a action. This method
+ is useful for subclasses when they need a QStyleOptionMenuItem, but don't want
+ to fill in all the information themselves.
+
+ \sa QStyleOption::initFrom() QMenuBar::initStyleOption()
+*/
+void QMenu::initStyleOption(QStyleOptionMenuItem *option, const QAction *action) const
+{
+ if (!option || !action)
+ return;
+
+ Q_D(const QMenu);
+ option->initFrom(this);
+ option->palette = palette();
+ option->state = QStyle::State_None;
+
+ if (window()->isActiveWindow())
+ option->state |= QStyle::State_Active;
+ if (isEnabled() && action->isEnabled()
+ && (!action->menu() || action->menu()->isEnabled()))
+ option->state |= QStyle::State_Enabled;
+ else
+ option->palette.setCurrentColorGroup(QPalette::Disabled);
+
+ option->font = action->font().resolve(font());
+ option->fontMetrics = QFontMetrics(option->font);
+
+ if (d->currentAction && d->currentAction == action && !d->currentAction->isSeparator()) {
+ option->state |= QStyle::State_Selected
+ | (d->mouseDown ? QStyle::State_Sunken : QStyle::State_None);
+ }
+
+ option->menuHasCheckableItems = d->hasCheckableItems;
+ if (!action->isCheckable()) {
+ option->checkType = QStyleOptionMenuItem::NotCheckable;
+ } else {
+ option->checkType = (action->actionGroup() && action->actionGroup()->isExclusive())
+ ? QStyleOptionMenuItem::Exclusive : QStyleOptionMenuItem::NonExclusive;
+ option->checked = action->isChecked();
+ }
+ if (action->menu())
+ option->menuItemType = QStyleOptionMenuItem::SubMenu;
+ else if (action->isSeparator())
+ option->menuItemType = QStyleOptionMenuItem::Separator;
+ else if (d->defaultAction == action)
+ option->menuItemType = QStyleOptionMenuItem::DefaultItem;
+ else
+ option->menuItemType = QStyleOptionMenuItem::Normal;
+ if (action->isIconVisibleInMenu())
+ option->icon = action->icon();
+ QString textAndAccel = action->text();
+#ifndef QT_NO_SHORTCUT
+ if (textAndAccel.indexOf(QLatin1Char('\t')) == -1) {
+ QKeySequence seq = action->shortcut();
+ if (!seq.isEmpty())
+ textAndAccel += QLatin1Char('\t') + QString(seq);
+ }
+#endif
+ option->text = textAndAccel;
+ option->tabWidth = d->tabWidth;
+ option->maxIconWidth = d->maxIconWidth;
+ option->menuRect = rect();
+}
+
+/*!
+ \class QMenu
+ \brief The QMenu class provides a menu widget for use in menu
+ bars, context menus, and other popup menus.
+
+ \ingroup mainwindow-classes
+ \ingroup basicwidgets
+
+
+ A menu widget is a selection menu. It can be either a pull-down
+ menu in a menu bar or a standalone context menu. Pull-down menus
+ are shown by the menu bar when the user clicks on the respective
+ item or presses the specified shortcut key. Use
+ QMenuBar::addMenu() to insert a menu into a menu bar. Context
+ menus are usually invoked by some special keyboard key or by
+ right-clicking. They can be executed either asynchronously with
+ popup() or synchronously with exec(). Menus can also be invoked in
+ response to button presses; these are just like context menus
+ except for how they are invoked.
+
+ \table 100%
+ \row
+ \o \inlineimage plastique-menu.png
+ \o \inlineimage windowsxp-menu.png
+ \o \inlineimage macintosh-menu.png
+ \endtable
+ \caption Fig. A menu shown in \l{Plastique Style Widget Gallery}{Plastique widget style},
+ \l{Windows XP Style Widget Gallery}{Windows XP widget style},
+ and \l{Macintosh Style Widget Gallery}{Macintosh widget style}.
+
+ \section1 Actions
+
+ A menu consists of a list of action items. Actions are added with
+ the addAction(), addActions() and insertAction() functions. An action
+ is represented vertically and rendered by QStyle. In addition, actions
+ can have a text label, an optional icon drawn on the very left side,
+ and shortcut key sequence such as "Ctrl+X".
+
+ The existing actions held by a menu can be found with actions().
+
+ There are four kinds of action items: separators, actions that
+ show a submenu, widgets, and actions that perform an action.
+ Separators are inserted with addSeparator(), submenus with addMenu(),
+ and all other items are considered action items.
+
+ When inserting action items you usually specify a receiver and a
+ slot. The receiver will be notifed whenever the item is
+ \l{QAction::triggered()}{triggered()}. In addition, QMenu provides
+ two signals, activated() and highlighted(), which signal the
+ QAction that was triggered from the menu.
+
+ You clear a menu with clear() and remove individual action items
+ with removeAction().
+
+ A QMenu can also provide a tear-off menu. A tear-off menu is a
+ top-level window that contains a copy of the menu. This makes it
+ possible for the user to "tear off" frequently used menus and
+ position them in a convenient place on the screen. If you want
+ this functionality for a particular menu, insert a tear-off handle
+ with setTearOffEnabled(). When using tear-off menus, bear in mind
+ that the concept isn't typically used on Microsoft Windows so
+ some users may not be familiar with it. Consider using a QToolBar
+ instead.
+
+ Widgets can be inserted into menus with the QWidgetAction class.
+ Instances of this class are used to hold widgets, and are inserted
+ into menus with the addAction() overload that takes a QAction.
+
+ Conversely, actions can be added to widgets with the addAction(),
+ addActions() and insertAction() functions.
+
+ \warning To make QMenu visible on the screen, exec() or popup() should be
+ used instead of show().
+
+ \section1 QMenu on Qt for Windows CE
+
+ If a menu is integrated into the native menubar on Windows Mobile we
+ do not support the signals: aboutToHide (), aboutToShow () and hovered ().
+ It is not possible to display an icon in a native menu on Windows Mobile.
+
+ \section1 QMenu on Mac OS X with Qt build against Cocoa
+
+ QMenu can be inserted only once in a menu/menubar. Subsequent insertions will
+ have no effect or will result in a disabled menu item.
+
+ See the \l{mainwindows/menus}{Menus} example for an example of how
+ to use QMenuBar and QMenu in your application.
+
+ \bold{Important inherited functions:} addAction(), removeAction(), clear(),
+ addSeparator(), and addMenu().
+
+ \sa QMenuBar, {fowler}{GUI Design Handbook: Menu, Drop-Down and Pop-Up},
+ {Application Example}, {Menus Example}, {Recent Files Example}
+*/
+
+
+/*!
+ Constructs a menu with parent \a parent.
+
+ Although a popup menu is always a top-level widget, if a parent is
+ passed the popup menu will be deleted when that parent is
+ destroyed (as with any other QObject).
+*/
+QMenu::QMenu(QWidget *parent)
+ : QWidget(*new QMenuPrivate, parent, Qt::Popup)
+{
+ Q_D(QMenu);
+ d->init();
+}
+
+/*!
+ Constructs a menu with a \a title and a \a parent.
+
+ Although a popup menu is always a top-level widget, if a parent is
+ passed the popup menu will be deleted when that parent is
+ destroyed (as with any other QObject).
+
+ \sa title
+*/
+QMenu::QMenu(const QString &title, QWidget *parent)
+ : QWidget(*new QMenuPrivate, parent, Qt::Popup)
+{
+ Q_D(QMenu);
+ d->init();
+ d->menuAction->setText(title);
+}
+
+/*! \internal
+ */
+QMenu::QMenu(QMenuPrivate &dd, QWidget *parent)
+ : QWidget(dd, parent, Qt::Popup)
+{
+ Q_D(QMenu);
+ d->init();
+}
+
+/*!
+ Destroys the menu.
+*/
+QMenu::~QMenu()
+{
+ Q_D(QMenu);
+ if (!d->widgetItems.isEmpty()) { // avoid detach on shared null hash
+ QHash<QAction *, QWidget *>::iterator it = d->widgetItems.begin();
+ for (; it != d->widgetItems.end(); ++it) {
+ if (QWidget *widget = it.value()) {
+ QWidgetAction *action = static_cast<QWidgetAction *>(it.key());
+ action->releaseWidget(widget);
+ *it = 0;
+ }
+ }
+ }
+
+ if (d->eventLoop)
+ d->eventLoop->exit();
+ hideTearOffMenu();
+}
+
+/*!
+ \overload
+
+ This convenience function creates a new action with \a text.
+ The function adds the newly created action to the menu's
+ list of actions, and returns it.
+
+ \sa QWidget::addAction()
+*/
+QAction *QMenu::addAction(const QString &text)
+{
+ QAction *ret = new QAction(text, this);
+ addAction(ret);
+ return ret;
+}
+
+/*!
+ \overload
+
+ This convenience function creates a new action with an \a icon
+ and some \a text. The function adds the newly created action to
+ the menu's list of actions, and returns it.
+
+ \sa QWidget::addAction()
+*/
+QAction *QMenu::addAction(const QIcon &icon, const QString &text)
+{
+ QAction *ret = new QAction(icon, text, this);
+ addAction(ret);
+ return ret;
+}
+
+/*!
+ \overload
+
+ This convenience function creates a new action with the text \a
+ text and an optional shortcut \a shortcut. The action's
+ \l{QAction::triggered()}{triggered()} signal is connected to the
+ \a receiver's \a member slot. The function adds the newly created
+ action to the menu's list of actions and returns it.
+
+ \sa QWidget::addAction()
+*/
+QAction *QMenu::addAction(const QString &text, const QObject *receiver, const char* member, const QKeySequence &shortcut)
+{
+ QAction *action = new QAction(text, this);
+#ifdef QT_NO_SHORTCUT
+ Q_UNUSED(shortcut);
+#else
+ action->setShortcut(shortcut);
+#endif
+ QObject::connect(action, SIGNAL(triggered(bool)), receiver, member);
+ addAction(action);
+ return action;
+}
+
+/*!
+ \overload
+
+ This convenience function creates a new action with an \a icon and
+ some \a text and an optional shortcut \a shortcut. The action's
+ \l{QAction::triggered()}{triggered()} signal is connected to the
+ \a member slot of the \a receiver object. The function adds the
+ newly created action to the menu's list of actions, and returns it.
+
+ \sa QWidget::addAction()
+*/
+QAction *QMenu::addAction(const QIcon &icon, const QString &text, const QObject *receiver,
+ const char* member, const QKeySequence &shortcut)
+{
+ QAction *action = new QAction(icon, text, this);
+#ifdef QT_NO_SHORTCUT
+ Q_UNUSED(shortcut);
+#else
+ action->setShortcut(shortcut);
+#endif
+ QObject::connect(action, SIGNAL(triggered(bool)), receiver, member);
+ addAction(action);
+ return action;
+}
+
+/*!
+ This convenience function adds \a menu as a submenu to this menu.
+ It returns \a menu's menuAction(). This menu does not take
+ ownership of \a menu.
+
+ \sa QWidget::addAction() QMenu::menuAction()
+*/
+QAction *QMenu::addMenu(QMenu *menu)
+{
+ QAction *action = menu->menuAction();
+ addAction(action);
+ return action;
+}
+
+/*!
+ Appends a new QMenu with \a title to the menu. The menu
+ takes ownership of the menu. Returns the new menu.
+
+ \sa QWidget::addAction() QMenu::menuAction()
+*/
+QMenu *QMenu::addMenu(const QString &title)
+{
+ QMenu *menu = new QMenu(title, this);
+ addAction(menu->menuAction());
+ return menu;
+}
+
+/*!
+ Appends a new QMenu with \a icon and \a title to the menu. The menu
+ takes ownership of the menu. Returns the new menu.
+
+ \sa QWidget::addAction() QMenu::menuAction()
+*/
+QMenu *QMenu::addMenu(const QIcon &icon, const QString &title)
+{
+ QMenu *menu = new QMenu(title, this);
+ menu->setIcon(icon);
+ addAction(menu->menuAction());
+ return menu;
+}
+
+/*!
+ This convenience function creates a new separator action, i.e. an
+ action with QAction::isSeparator() returning true, and adds the new
+ action to this menu's list of actions. It returns the newly
+ created action.
+
+ \sa QWidget::addAction()
+*/
+QAction *QMenu::addSeparator()
+{
+ QAction *action = new QAction(this);
+ action->setSeparator(true);
+ addAction(action);
+ return action;
+}
+
+/*!
+ This convenience function inserts \a menu before action \a before
+ and returns the menus menuAction().
+
+ \sa QWidget::insertAction(), addMenu()
+*/
+QAction *QMenu::insertMenu(QAction *before, QMenu *menu)
+{
+ QAction *action = menu->menuAction();
+ insertAction(before, action);
+ return action;
+}
+
+/*!
+ This convenience function creates a new separator action, i.e. an
+ action with QAction::isSeparator() returning true. The function inserts
+ the newly created action into this menu's list of actions before
+ action \a before and returns it.
+
+ \sa QWidget::insertAction(), addSeparator()
+*/
+QAction *QMenu::insertSeparator(QAction *before)
+{
+ QAction *action = new QAction(this);
+ action->setSeparator(true);
+ insertAction(before, action);
+ return action;
+}
+
+/*!
+ This sets the default action to \a act. The default action may have
+ a visual cue, depending on the current QStyle. A default action
+ usually indicates what will happen by default when a drop occurs.
+
+ \sa defaultAction()
+*/
+void QMenu::setDefaultAction(QAction *act)
+{
+ d_func()->defaultAction = act;
+}
+
+/*!
+ Returns the current default action.
+
+ \sa setDefaultAction()
+*/
+QAction *QMenu::defaultAction() const
+{
+ return d_func()->defaultAction;
+}
+
+/*!
+ \property QMenu::tearOffEnabled
+ \brief whether the menu supports being torn off
+
+ When true, the menu contains a special tear-off item (often shown as a dashed
+ line at the top of the menu) that creates a copy of the menu when it is
+ triggered.
+
+ This "torn-off" copy lives in a separate window. It contains the same menu
+ items as the original menu, with the exception of the tear-off handle.
+
+ By default, this property is false.
+*/
+void QMenu::setTearOffEnabled(bool b)
+{
+ Q_D(QMenu);
+ if (d->tearoff == b)
+ return;
+ if (!b)
+ hideTearOffMenu();
+ d->tearoff = b;
+
+ d->itemsDirty = true;
+ if (isVisible())
+ resize(sizeHint());
+}
+
+bool QMenu::isTearOffEnabled() const
+{
+ return d_func()->tearoff;
+}
+
+/*!
+ When a menu is torn off a second menu is shown to display the menu
+ contents in a new window. When the menu is in this mode and the menu
+ is visible returns true; otherwise false.
+
+ \sa hideTearOffMenu() isTearOffEnabled()
+*/
+bool QMenu::isTearOffMenuVisible() const
+{
+ if (d_func()->tornPopup)
+ return d_func()->tornPopup->isVisible();
+ return false;
+}
+
+/*!
+ This function will forcibly hide the torn off menu making it
+ disappear from the users desktop.
+
+ \sa isTearOffMenuVisible() isTearOffEnabled()
+*/
+void QMenu::hideTearOffMenu()
+{
+ if (QWidget *w = d_func()->tornPopup)
+ w->close();
+}
+
+
+/*!
+ Sets the currently highlighted action to \a act.
+*/
+void QMenu::setActiveAction(QAction *act)
+{
+ Q_D(QMenu);
+ d->setCurrentAction(act, 0);
+ if (d->scroll)
+ d->scrollMenu(act, QMenuPrivate::QMenuScroller::ScrollCenter);
+}
+
+
+/*!
+ Returns the currently highlighted action, or 0 if no
+ action is currently highlighted.
+*/
+QAction *QMenu::activeAction() const
+{
+ return d_func()->currentAction;
+}
+
+/*!
+ \since 4.2
+
+ Returns true if there are no visible actions inserted into the menu, false
+ otherwise.
+
+ \sa QWidget::actions()
+*/
+
+bool QMenu::isEmpty() const
+{
+ bool ret = true;
+ for(int i = 0; ret && i < actions().count(); ++i) {
+ const QAction *action = actions().at(i);
+ if (!action->isSeparator() && action->isVisible()) {
+ ret = false;
+ }
+ }
+ return ret;
+}
+
+/*!
+ Removes all the menu's actions. Actions owned by the menu and not
+ shown in any other widget are deleted.
+
+ \sa removeAction()
+*/
+void QMenu::clear()
+{
+ QList<QAction*> acts = actions();
+
+ for(int i = 0; i < acts.size(); i++) {
+#ifdef QT_SOFTKEYS_ENABLED
+ Q_D(QMenu);
+ // Lets not touch to our internal softkey actions
+ if(acts[i] == d->selectAction || acts[i] == d->cancelAction)
+ continue;
+#endif
+ removeAction(acts[i]);
+ if (acts[i]->parent() == this && acts[i]->d_func()->widgets.isEmpty())
+ delete acts[i];
+ }
+}
+
+/*!
+ If a menu does not fit on the screen it lays itself out so that it
+ does fit. It is style dependent what layout means (for example, on
+ Windows it will use multiple columns).
+
+ This functions returns the number of columns necessary.
+*/
+int QMenu::columnCount() const
+{
+ return d_func()->ncols;
+}
+
+/*!
+ Returns the item at \a pt; returns 0 if there is no item there.
+*/
+QAction *QMenu::actionAt(const QPoint &pt) const
+{
+ if (QAction *ret = d_func()->actionAt(pt))
+ return ret;
+ return 0;
+}
+
+/*!
+ Returns the geometry of action \a act.
+*/
+QRect QMenu::actionGeometry(QAction *act) const
+{
+ return d_func()->actionRect(act);
+}
+
+/*!
+ \reimp
+*/
+QSize QMenu::sizeHint() const
+{
+ Q_D(const QMenu);
+ d->updateActionRects();
+
+ QSize s;
+ for (int i = 0; i < d->actionRects.count(); ++i) {
+ const QRect &rect = d->actionRects.at(i);
+ if (rect.isNull())
+ continue;
+ if (rect.bottom() >= s.height())
+ s.setHeight(rect.y() + rect.height());
+ if (rect.right() >= s.width())
+ s.setWidth(rect.x() + rect.width());
+ }
+ // Note that the action rects calculated above already include
+ // the top and left margins, so we only need to add margins for
+ // the bottom and right.
+ QStyleOption opt(0);
+ opt.init(this);
+ const int fw = style()->pixelMetric(QStyle::PM_MenuPanelWidth, &opt, this);
+ s.rwidth() += style()->pixelMetric(QStyle::PM_MenuHMargin, &opt, this) + fw + d->rightmargin;
+ s.rheight() += style()->pixelMetric(QStyle::PM_MenuVMargin, &opt, this) + fw + d->bottommargin;
+
+ return style()->sizeFromContents(QStyle::CT_Menu, &opt,
+ s.expandedTo(QApplication::globalStrut()), this);
+}
+
+/*!
+ Displays the menu so that the action \a atAction will be at the
+ specified \e global position \a p. To translate a widget's local
+ coordinates into global coordinates, use QWidget::mapToGlobal().
+
+ When positioning a menu with exec() or popup(), bear in mind that
+ you cannot rely on the menu's current size(). For performance
+ reasons, the menu adapts its size only when necessary, so in many
+ cases, the size before and after the show is different. Instead,
+ use sizeHint() which calculates the proper size depending on the
+ menu's current contents.
+
+ \sa QWidget::mapToGlobal(), exec()
+*/
+void QMenu::popup(const QPoint &p, QAction *atAction)
+{
+ Q_D(QMenu);
+#ifndef Q_OS_SYMBIAN
+ if (d->scroll) { // reset scroll state from last popup
+ d->scroll->scrollOffset = 0;
+ d->scroll->scrollFlags = QMenuPrivate::QMenuScroller::ScrollNone;
+ }
+#endif
+ d->tearoffHighlighted = 0;
+ d->motions = 0;
+ d->doChildEffects = true;
+ d->updateLayoutDirection();
+
+#ifndef QT_NO_MENUBAR
+ // if this menu is part of a chain attached to a QMenuBar, set the
+ // _NET_WM_WINDOW_TYPE_DROPDOWN_MENU X11 window type
+ setAttribute(Qt::WA_X11NetWmWindowTypeDropDownMenu, qobject_cast<QMenuBar *>(d->topCausedWidget()) != 0);
+#endif
+
+ ensurePolished(); // Get the right font
+ emit aboutToShow();
+ const bool actionListChanged = d->itemsDirty;
+ d->updateActionRects();
+ QPoint pos;
+ QPushButton *causedButton = qobject_cast<QPushButton*>(d->causedPopup.widget);
+ if (actionListChanged && causedButton)
+ pos = QPushButtonPrivate::get(causedButton)->adjustedMenuPosition();
+ else
+ pos = p;
+
+ QSize size = sizeHint();
+ QRect screen;
+#ifndef QT_NO_GRAPHICSVIEW
+ bool isEmbedded = !bypassGraphicsProxyWidget(this) && d->nearestGraphicsProxyWidget(this);
+ if (isEmbedded)
+ screen = d->popupGeometry(this);
+ else
+#endif
+ screen = d->popupGeometry(QApplication::desktop()->screenNumber(p));
+ const int desktopFrame = style()->pixelMetric(QStyle::PM_MenuDesktopFrameWidth, 0, this);
+ bool adjustToDesktop = !window()->testAttribute(Qt::WA_DontShowOnScreen);
+
+ // if the screens have very different geometries and the menu is too big, we have to recalculate
+ if (size.height() > screen.height() || size.width() > screen.width()) {
+ size = d->adjustMenuSizeForScreen(screen);
+ adjustToDesktop = true;
+ }
+ // Layout is not right, we might be able to save horizontal space
+ if (d->ncols >1 && size.height() < screen.height()) {
+ size = d->adjustMenuSizeForScreen(screen);
+ adjustToDesktop = true;
+ }
+
+#ifdef QT_KEYPAD_NAVIGATION
+ if (!atAction && QApplication::keypadNavigationEnabled()) {
+ // Try to have one item activated
+ if (d->defaultAction && d->defaultAction->isEnabled()) {
+ atAction = d->defaultAction;
+ // TODO: This works for first level menus, not yet sub menus
+ } else {
+ foreach (QAction *action, d->actions)
+ if (action->isEnabled()) {
+ atAction = action;
+ break;
+ }
+ }
+ d->currentAction = atAction;
+ }
+#endif
+ if (d->ncols > 1) {
+ pos.setY(screen.top() + desktopFrame);
+ } else if (atAction) {
+ for (int i = 0, above_height = 0; i < d->actions.count(); i++) {
+ QAction *action = d->actions.at(i);
+ if (action == atAction) {
+ int newY = pos.y() - above_height;
+ if (d->scroll && newY < desktopFrame) {
+ d->scroll->scrollFlags = d->scroll->scrollFlags
+ | QMenuPrivate::QMenuScroller::ScrollUp;
+ d->scroll->scrollOffset = newY;
+ newY = desktopFrame;
+ }
+ pos.setY(newY);
+
+ if (d->scroll && d->scroll->scrollFlags != QMenuPrivate::QMenuScroller::ScrollNone
+ && !style()->styleHint(QStyle::SH_Menu_FillScreenWithScroll, 0, this)) {
+ int below_height = above_height + d->scroll->scrollOffset;
+ for (int i2 = i; i2 < d->actionRects.count(); i2++)
+ below_height += d->actionRects.at(i2).height();
+ size.setHeight(below_height);
+ }
+ break;
+ } else {
+ above_height += d->actionRects.at(i).height();
+ }
+ }
+ }
+
+ QPoint mouse = QCursor::pos();
+ d->mousePopupPos = mouse;
+ const bool snapToMouse = (QRect(p.x() - 3, p.y() - 3, 6, 6).contains(mouse));
+
+ if (adjustToDesktop) {
+ // handle popup falling "off screen"
+ if (isRightToLeft()) {
+ if (snapToMouse) // position flowing left from the mouse
+ pos.setX(mouse.x() - size.width());
+
+#ifndef QT_NO_MENUBAR
+ // if in a menubar, it should be right-aligned
+ if (qobject_cast<QMenuBar*>(d->causedPopup.widget))
+ pos.rx() -= size.width();
+#endif //QT_NO_MENUBAR
+
+ if (pos.x() < screen.left() + desktopFrame)
+ pos.setX(qMax(p.x(), screen.left() + desktopFrame));
+ if (pos.x() + size.width() - 1 > screen.right() - desktopFrame)
+ pos.setX(qMax(p.x() - size.width(), screen.right() - desktopFrame - size.width() + 1));
+ } else {
+ if (pos.x() + size.width() - 1 > screen.right() - desktopFrame)
+ pos.setX(screen.right() - desktopFrame - size.width() + 1);
+ if (pos.x() < screen.left() + desktopFrame)
+ pos.setX(screen.left() + desktopFrame);
+ }
+ if (pos.y() + size.height() - 1 > screen.bottom() - desktopFrame) {
+ if(snapToMouse)
+ pos.setY(qMin(mouse.y() - (size.height() + desktopFrame), screen.bottom()-desktopFrame-size.height()+1));
+ else
+ pos.setY(qMax(p.y() - (size.height() + desktopFrame), screen.bottom()-desktopFrame-size.height()+1));
+ } else if (pos.y() < screen.top() + desktopFrame) {
+ pos.setY(screen.top() + desktopFrame);
+ }
+
+ if (pos.y() < screen.top() + desktopFrame)
+ pos.setY(screen.top() + desktopFrame);
+ if (pos.y() + size.height() - 1 > screen.bottom() - desktopFrame) {
+ if (d->scroll) {
+ d->scroll->scrollFlags |= uint(QMenuPrivate::QMenuScroller::ScrollDown);
+ int y = qMax(screen.y(),pos.y());
+ size.setHeight(screen.bottom() - (desktopFrame * 2) - y);
+ } else {
+ // Too big for screen, bias to see bottom of menu (for some reason)
+ pos.setY(screen.bottom() - size.height() + 1);
+ }
+ }
+ }
+ const int subMenuOffset = style()->pixelMetric(QStyle::PM_SubMenuOverlap, 0, this);
+ const QSize menuSize(sizeHint());
+ QMenu *caused = qobject_cast<QMenu*>(d_func()->causedPopup.widget);
+ if (caused && caused->geometry().width() + menuSize.width() + subMenuOffset < screen.width()) {
+ QRect parentActionRect(caused->d_func()->actionRect(caused->d_func()->currentAction));
+ const QPoint actionTopLeft = caused->mapToGlobal(parentActionRect.topLeft());
+ parentActionRect.moveTopLeft(actionTopLeft);
+ if (isRightToLeft()) {
+ if ((pos.x() + menuSize.width() > parentActionRect.left() - subMenuOffset)
+ && (pos.x() < parentActionRect.right()))
+ {
+ pos.rx() = parentActionRect.right();
+ }
+ } else {
+ if ((pos.x() < parentActionRect.right() + subMenuOffset)
+ && (pos.x() + menuSize.width() > parentActionRect.left()))
+ {
+ pos.rx() = parentActionRect.left() - menuSize.width();
+ }
+ }
+ }
+ setGeometry(QRect(pos, size));
+#ifndef QT_NO_EFFECTS
+ int hGuess = isRightToLeft() ? QEffects::LeftScroll : QEffects::RightScroll;
+ int vGuess = QEffects::DownScroll;
+ if (isRightToLeft()) {
+ if ((snapToMouse && (pos.x() + size.width() / 2 > mouse.x())) ||
+ (qobject_cast<QMenu*>(d->causedPopup.widget) && pos.x() + size.width() / 2 > d->causedPopup.widget->x()))
+ hGuess = QEffects::RightScroll;
+ } else {
+ if ((snapToMouse && (pos.x() + size.width() / 2 < mouse.x())) ||
+ (qobject_cast<QMenu*>(d->causedPopup.widget) && pos.x() + size.width() / 2 < d->causedPopup.widget->x()))
+ hGuess = QEffects::LeftScroll;
+ }
+
+#ifndef QT_NO_MENUBAR
+ if ((snapToMouse && (pos.y() + size.height() / 2 < mouse.y())) ||
+ (qobject_cast<QMenuBar*>(d->causedPopup.widget) &&
+ pos.y() + size.width() / 2 < d->causedPopup.widget->mapToGlobal(d->causedPopup.widget->pos()).y()))
+ vGuess = QEffects::UpScroll;
+#endif
+ if (QApplication::isEffectEnabled(Qt::UI_AnimateMenu)) {
+ bool doChildEffects = true;
+#ifndef QT_NO_MENUBAR
+ if (QMenuBar *mb = qobject_cast<QMenuBar*>(d->causedPopup.widget)) {
+ doChildEffects = mb->d_func()->doChildEffects;
+ mb->d_func()->doChildEffects = false;
+ } else
+#endif
+ if (QMenu *m = qobject_cast<QMenu*>(d->causedPopup.widget)) {
+ doChildEffects = m->d_func()->doChildEffects;
+ m->d_func()->doChildEffects = false;
+ }
+
+ if (doChildEffects) {
+ if (QApplication::isEffectEnabled(Qt::UI_FadeMenu))
+ qFadeEffect(this);
+ else if (d->causedPopup.widget)
+ qScrollEffect(this, qobject_cast<QMenu*>(d->causedPopup.widget) ? hGuess : vGuess);
+ else
+ qScrollEffect(this, hGuess | vGuess);
+ } else {
+ // kill any running effect
+ qFadeEffect(0);
+ qScrollEffect(0);
+
+ show();
+ }
+ } else
+#endif
+ {
+ show();
+ }
+
+#ifndef QT_NO_ACCESSIBILITY
+ QAccessible::updateAccessibility(this, 0, QAccessible::PopupMenuStart);
+#endif
+}
+
+/*!
+ Executes this menu synchronously.
+
+ This is equivalent to \c{exec(pos())}.
+
+ This returns the triggered QAction in either the popup menu or one
+ of its submenus, or 0 if no item was triggered (normally because
+ the user pressed Esc).
+
+ In most situations you'll want to specify the position yourself,
+ for example, the current mouse position:
+ \snippet doc/src/snippets/code/src_gui_widgets_qmenu.cpp 0
+ or aligned to a widget:
+ \snippet doc/src/snippets/code/src_gui_widgets_qmenu.cpp 1
+ or in reaction to a QMouseEvent *e:
+ \snippet doc/src/snippets/code/src_gui_widgets_qmenu.cpp 2
+*/
+QAction *QMenu::exec()
+{
+ return exec(pos());
+}
+
+
+/*!
+ \overload
+
+ Executes this menu synchronously.
+
+ Pops up the menu so that the action \a action will be at the
+ specified \e global position \a p. To translate a widget's local
+ coordinates into global coordinates, use QWidget::mapToGlobal().
+
+ This returns the triggered QAction in either the popup menu or one
+ of its submenus, or 0 if no item was triggered (normally because
+ the user pressed Esc).
+
+ Note that all signals are emitted as usual. If you connect a
+ QAction to a slot and call the menu's exec(), you get the result
+ both via the signal-slot connection and in the return value of
+ exec().
+
+ Common usage is to position the menu at the current mouse
+ position:
+ \snippet doc/src/snippets/code/src_gui_widgets_qmenu.cpp 3
+ or aligned to a widget:
+ \snippet doc/src/snippets/code/src_gui_widgets_qmenu.cpp 4
+ or in reaction to a QMouseEvent *e:
+ \snippet doc/src/snippets/code/src_gui_widgets_qmenu.cpp 5
+
+ When positioning a menu with exec() or popup(), bear in mind that
+ you cannot rely on the menu's current size(). For performance
+ reasons, the menu adapts its size only when necessary. So in many
+ cases, the size before and after the show is different. Instead,
+ use sizeHint() which calculates the proper size depending on the
+ menu's current contents.
+
+ \sa popup(), QWidget::mapToGlobal()
+*/
+QAction *QMenu::exec(const QPoint &p, QAction *action)
+{
+ Q_D(QMenu);
+ createWinId();
+ QEventLoop eventLoop;
+ d->eventLoop = &eventLoop;
+ popup(p, action);
+
+ QPointer<QObject> guard = this;
+ (void) eventLoop.exec();
+ if (guard.isNull())
+ return 0;
+
+ action = d->syncAction;
+ d->syncAction = 0;
+ d->eventLoop = 0;
+ return action;
+}
+
+/*!
+ \overload
+
+ Executes a menu synchronously.
+
+ The menu's actions are specified by the list of \a actions. The menu will
+ pop up so that the specified action, \a at, appears at global position \a
+ pos. If \a at is not specified then the menu appears at position \a
+ pos. \a parent is the menu's parent widget; specifying the parent will
+ provide context when \a pos alone is not enough to decide where the menu
+ should go (e.g., with multiple desktops or when the parent is embedded in
+ QGraphicsView).
+
+ The function returns the triggered QAction in either the popup
+ menu or one of its submenus, or 0 if no item was triggered
+ (normally because the user pressed Esc).
+
+ This is equivalent to:
+ \snippet doc/src/snippets/code/src_gui_widgets_qmenu.cpp 6
+
+ \sa popup(), QWidget::mapToGlobal()
+*/
+QAction *QMenu::exec(QList<QAction*> actions, const QPoint &pos, QAction *at, QWidget *parent)
+{
+ QMenu menu(parent);
+ menu.addActions(actions);
+ return menu.exec(pos, at);
+}
+
+/*!
+ \overload
+
+ Executes a menu synchronously.
+
+ The menu's actions are specified by the list of \a actions. The menu
+ will pop up so that the specified action, \a at, appears at global
+ position \a pos. If \a at is not specified then the menu appears
+ at position \a pos.
+
+ The function returns the triggered QAction in either the popup
+ menu or one of its submenus, or 0 if no item was triggered
+ (normally because the user pressed Esc).
+
+ This is equivalent to:
+ \snippet doc/src/snippets/code/src_gui_widgets_qmenu.cpp 6
+
+ \sa popup(), QWidget::mapToGlobal()
+*/
+QAction *QMenu::exec(QList<QAction*> actions, const QPoint &pos, QAction *at)
+{
+ // ### Qt 5: merge
+ return exec(actions, pos, at, 0);
+}
+
+/*!
+ \reimp
+*/
+void QMenu::hideEvent(QHideEvent *)
+{
+ Q_D(QMenu);
+ emit aboutToHide();
+ if (d->eventLoop)
+ d->eventLoop->exit();
+ d->setCurrentAction(0);
+#ifndef QT_NO_ACCESSIBILITY
+ QAccessible::updateAccessibility(this, 0, QAccessible::PopupMenuEnd);
+#endif
+#ifndef QT_NO_MENUBAR
+ if (QMenuBar *mb = qobject_cast<QMenuBar*>(d->causedPopup.widget))
+ mb->d_func()->setCurrentAction(0);
+#endif
+ d->mouseDown = 0;
+ d->hasHadMouse = false;
+ d->causedPopup.widget = 0;
+ d->causedPopup.action = 0;
+ if (d->scroll)
+ d->scroll->scrollTimer.stop(); //make sure the timer stops
+}
+
+/*!
+ \reimp
+*/
+void QMenu::paintEvent(QPaintEvent *e)
+{
+ Q_D(QMenu);
+ d->updateActionRects();
+ QPainter p(this);
+ QRegion emptyArea = QRegion(rect());
+
+ QStyleOptionMenuItem menuOpt;
+ menuOpt.initFrom(this);
+ menuOpt.state = QStyle::State_None;
+ menuOpt.checkType = QStyleOptionMenuItem::NotCheckable;
+ menuOpt.maxIconWidth = 0;
+ menuOpt.tabWidth = 0;
+ style()->drawPrimitive(QStyle::PE_PanelMenu, &menuOpt, &p, this);
+
+ //draw the items that need updating..
+ for (int i = 0; i < d->actions.count(); ++i) {
+ QAction *action = d->actions.at(i);
+ QRect adjustedActionRect = d->actionRects.at(i);
+ if (!e->rect().intersects(adjustedActionRect)
+ || d->widgetItems.value(action))
+ continue;
+ //set the clip region to be extra safe (and adjust for the scrollers)
+ QRegion adjustedActionReg(adjustedActionRect);
+ emptyArea -= adjustedActionReg;
+ p.setClipRegion(adjustedActionReg);
+
+ QStyleOptionMenuItem opt;
+ initStyleOption(&opt, action);
+ opt.rect = adjustedActionRect;
+ style()->drawControl(QStyle::CE_MenuItem, &opt, &p, this);
+ }
+
+ const int fw = style()->pixelMetric(QStyle::PM_MenuPanelWidth, 0, this);
+ //draw the scroller regions..
+ if (d->scroll) {
+ menuOpt.menuItemType = QStyleOptionMenuItem::Scroller;
+ menuOpt.state |= QStyle::State_Enabled;
+ if (d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp) {
+ menuOpt.rect.setRect(fw, fw, width() - (fw * 2), d->scrollerHeight());
+ emptyArea -= QRegion(menuOpt.rect);
+ p.setClipRect(menuOpt.rect);
+ style()->drawControl(QStyle::CE_MenuScroller, &menuOpt, &p, this);
+ }
+ if (d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollDown) {
+ menuOpt.rect.setRect(fw, height() - d->scrollerHeight() - fw, width() - (fw * 2),
+ d->scrollerHeight());
+ emptyArea -= QRegion(menuOpt.rect);
+ menuOpt.state |= QStyle::State_DownArrow;
+ p.setClipRect(menuOpt.rect);
+ style()->drawControl(QStyle::CE_MenuScroller, &menuOpt, &p, this);
+ }
+ }
+ //paint the tear off..
+ if (d->tearoff) {
+ menuOpt.menuItemType = QStyleOptionMenuItem::TearOff;
+ menuOpt.rect.setRect(fw, fw, width() - (fw * 2),
+ style()->pixelMetric(QStyle::PM_MenuTearoffHeight, 0, this));
+ if (d->scroll && d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp)
+ menuOpt.rect.translate(0, d->scrollerHeight());
+ emptyArea -= QRegion(menuOpt.rect);
+ p.setClipRect(menuOpt.rect);
+ menuOpt.state = QStyle::State_None;
+ if (d->tearoffHighlighted)
+ menuOpt.state |= QStyle::State_Selected;
+ style()->drawControl(QStyle::CE_MenuTearoff, &menuOpt, &p, this);
+ }
+ //draw border
+ if (fw) {
+ QRegion borderReg;
+ borderReg += QRect(0, 0, fw, height()); //left
+ borderReg += QRect(width()-fw, 0, fw, height()); //right
+ borderReg += QRect(0, 0, width(), fw); //top
+ borderReg += QRect(0, height()-fw, width(), fw); //bottom
+ p.setClipRegion(borderReg);
+ emptyArea -= borderReg;
+ QStyleOptionFrame frame;
+ frame.rect = rect();
+ frame.palette = palette();
+ frame.state = QStyle::State_None;
+ frame.lineWidth = style()->pixelMetric(QStyle::PM_MenuPanelWidth);
+ frame.midLineWidth = 0;
+ style()->drawPrimitive(QStyle::PE_FrameMenu, &frame, &p, this);
+ }
+
+ //finally the rest of the space
+ p.setClipRegion(emptyArea);
+ menuOpt.state = QStyle::State_None;
+ menuOpt.menuItemType = QStyleOptionMenuItem::EmptyArea;
+ menuOpt.checkType = QStyleOptionMenuItem::NotCheckable;
+ menuOpt.rect = rect();
+ menuOpt.menuRect = rect();
+ style()->drawControl(QStyle::CE_MenuEmptyArea, &menuOpt, &p, this);
+}
+
+#ifndef QT_NO_WHEELEVENT
+/*!
+ \reimp
+*/
+void QMenu::wheelEvent(QWheelEvent *e)
+{
+ Q_D(QMenu);
+ if (d->scroll && rect().contains(e->pos()))
+ d->scrollMenu(e->delta() > 0 ?
+ QMenuPrivate::QMenuScroller::ScrollUp : QMenuPrivate::QMenuScroller::ScrollDown);
+}
+#endif
+
+/*!
+ \reimp
+*/
+void QMenu::mousePressEvent(QMouseEvent *e)
+{
+ Q_D(QMenu);
+ if (d->aboutToHide || d->mouseEventTaken(e))
+ return;
+ if (!rect().contains(e->pos())) {
+ if (d->noReplayFor
+ && QRect(d->noReplayFor->mapToGlobal(QPoint()), d->noReplayFor->size()).contains(e->globalPos()))
+ setAttribute(Qt::WA_NoMouseReplay);
+ if (d->eventLoop) // synchronous operation
+ d->syncAction = 0;
+ d->hideUpToMenuBar();
+ return;
+ }
+ d->mouseDown = this;
+
+ QAction *action = d->actionAt(e->pos());
+ d->setCurrentAction(action, 20);
+ update();
+}
+
+/*!
+ \reimp
+*/
+void QMenu::mouseReleaseEvent(QMouseEvent *e)
+{
+ Q_D(QMenu);
+ if (d->aboutToHide || d->mouseEventTaken(e))
+ return;
+ if(d->mouseDown != this) {
+ d->mouseDown = 0;
+ return;
+ }
+
+ d->mouseDown = 0;
+ d->setSyncAction();
+ QAction *action = d->actionAt(e->pos());
+
+ if (action && action == d->currentAction) {
+ if (!action->menu()){
+#if defined(Q_WS_WIN)
+ //On Windows only context menus can be activated with the right button
+ if (e->button() == Qt::LeftButton || d->topCausedWidget() == 0)
+#endif
+ d->activateAction(action, QAction::Trigger);
+ }
+ } else if (d->hasMouseMoved(e->globalPos())) {
+ d->hideUpToMenuBar();
+ }
+}
+
+/*!
+ \reimp
+*/
+void QMenu::changeEvent(QEvent *e)
+{
+ Q_D(QMenu);
+ if (e->type() == QEvent::StyleChange || e->type() == QEvent::FontChange ||
+ e->type() == QEvent::LayoutDirectionChange) {
+ d->itemsDirty = 1;
+ setMouseTracking(style()->styleHint(QStyle::SH_Menu_MouseTracking, 0, this));
+ if (isVisible())
+ resize(sizeHint());
+ if (!style()->styleHint(QStyle::SH_Menu_Scrollable, 0, this)) {
+ delete d->scroll;
+ d->scroll = 0;
+ } else if (!d->scroll) {
+ d->scroll = new QMenuPrivate::QMenuScroller;
+ d->scroll->scrollFlags = QMenuPrivate::QMenuScroller::ScrollNone;
+ }
+ } else if (e->type() == QEvent::EnabledChange) {
+ if (d->tornPopup) // torn-off menu
+ d->tornPopup->setEnabled(isEnabled());
+ d->menuAction->setEnabled(isEnabled());
+ if (d->platformMenu)
+ d->platformMenu->setMenuEnabled(isEnabled());
+ }
+ QWidget::changeEvent(e);
+}
+
+
+/*!
+ \reimp
+*/
+bool
+QMenu::event(QEvent *e)
+{
+ Q_D(QMenu);
+ switch (e->type()) {
+ case QEvent::Polish:
+ d->updateLayoutDirection();
+ break;
+ case QEvent::ShortcutOverride: {
+ QKeyEvent *kev = static_cast<QKeyEvent*>(e);
+ if (kev->key() == Qt::Key_Up || kev->key() == Qt::Key_Down
+ || kev->key() == Qt::Key_Left || kev->key() == Qt::Key_Right
+ || kev->key() == Qt::Key_Enter || kev->key() == Qt::Key_Return
+ || kev->key() == Qt::Key_Escape) {
+ e->accept();
+ return true;
+ }
+ }
+ break;
+ case QEvent::KeyPress: {
+ QKeyEvent *ke = (QKeyEvent*)e;
+ if (ke->key() == Qt::Key_Tab || ke->key() == Qt::Key_Backtab) {
+ keyPressEvent(ke);
+ return true;
+ }
+ } break;
+ case QEvent::ContextMenu:
+ if(d->menuDelayTimer.isActive()) {
+ d->menuDelayTimer.stop();
+ internalDelayedPopup();
+ }
+ break;
+ case QEvent::Resize: {
+ QStyleHintReturnMask menuMask;
+ QStyleOption option;
+ option.initFrom(this);
+ if (style()->styleHint(QStyle::SH_Menu_Mask, &option, this, &menuMask)) {
+ setMask(menuMask.region);
+ }
+ d->itemsDirty = 1;
+ d->updateActionRects();
+ break; }
+ case QEvent::Show:
+ d->mouseDown = 0;
+ d->updateActionRects();
+ if (d->currentAction)
+ d->popupAction(d->currentAction, 0, false);
+ break;
+#ifndef QT_NO_WHATSTHIS
+ case QEvent::QueryWhatsThis:
+ e->setAccepted(d->whatsThis.size());
+ if (QAction *action = d->actionAt(static_cast<QHelpEvent*>(e)->pos())) {
+ if (action->whatsThis().size() || action->menu())
+ e->accept();
+ }
+ return true;
+#endif
+#ifdef QT_SOFTKEYS_ENABLED
+ case QEvent::LanguageChange: {
+ d->selectAction->setText(QSoftKeyManager::standardSoftKeyText(QSoftKeyManager::SelectSoftKey));
+ d->cancelAction->setText(QSoftKeyManager::standardSoftKeyText(QSoftKeyManager::CancelSoftKey));
+ }
+ break;
+#endif
+ default:
+ break;
+ }
+ return QWidget::event(e);
+}
+
+/*!
+ \reimp
+*/
+bool QMenu::focusNextPrevChild(bool next)
+{
+ setFocus();
+ QKeyEvent ev(QEvent::KeyPress, next ? Qt::Key_Tab : Qt::Key_Backtab, Qt::NoModifier);
+ keyPressEvent(&ev);
+ return true;
+}
+
+/*!
+ \reimp
+*/
+void QMenu::keyPressEvent(QKeyEvent *e)
+{
+ Q_D(QMenu);
+ d->updateActionRects();
+ int key = e->key();
+ if (isRightToLeft()) { // in reverse mode open/close key for submenues are reversed
+ if (key == Qt::Key_Left)
+ key = Qt::Key_Right;
+ else if (key == Qt::Key_Right)
+ key = Qt::Key_Left;
+ }
+#ifndef Q_OS_MAC
+ if (key == Qt::Key_Tab) //means down
+ key = Qt::Key_Down;
+ if (key == Qt::Key_Backtab) //means up
+ key = Qt::Key_Up;
+#endif
+
+ bool key_consumed = false;
+ switch(key) {
+ case Qt::Key_Home:
+ key_consumed = true;
+ if (d->scroll)
+ d->scrollMenu(QMenuPrivate::QMenuScroller::ScrollTop, true);
+ break;
+ case Qt::Key_End:
+ key_consumed = true;
+ if (d->scroll)
+ d->scrollMenu(QMenuPrivate::QMenuScroller::ScrollBottom, true);
+ break;
+ case Qt::Key_PageUp:
+ key_consumed = true;
+ if (d->currentAction && d->scroll) {
+ if(d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp)
+ d->scrollMenu(QMenuPrivate::QMenuScroller::ScrollUp, true, true);
+ else
+ d->scrollMenu(QMenuPrivate::QMenuScroller::ScrollTop, true);
+ }
+ break;
+ case Qt::Key_PageDown:
+ key_consumed = true;
+ if (d->currentAction && d->scroll) {
+ if(d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollDown)
+ d->scrollMenu(QMenuPrivate::QMenuScroller::ScrollDown, true, true);
+ else
+ d->scrollMenu(QMenuPrivate::QMenuScroller::ScrollBottom, true);
+ }
+ break;
+ case Qt::Key_Up:
+ case Qt::Key_Down: {
+ key_consumed = true;
+ QAction *nextAction = 0;
+ QMenuPrivate::QMenuScroller::ScrollLocation scroll_loc = QMenuPrivate::QMenuScroller::ScrollStay;
+ if (!d->currentAction) {
+ if(key == Qt::Key_Down) {
+ for(int i = 0; i < d->actions.count(); ++i) {
+ QAction *act = d->actions.at(i);
+ if (d->actionRects.at(i).isNull())
+ continue;
+ if (!act->isSeparator() &&
+ (style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, this)
+ || act->isEnabled())) {
+ nextAction = act;
+ break;
+ }
+ }
+ } else {
+ for(int i = d->actions.count()-1; i >= 0; --i) {
+ QAction *act = d->actions.at(i);
+ if (d->actionRects.at(i).isNull())
+ continue;
+ if (!act->isSeparator() &&
+ (style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, this)
+ || act->isEnabled())) {
+ nextAction = act;
+ break;
+ }
+ }
+ }
+ } else {
+ for(int i = 0, y = 0; !nextAction && i < d->actions.count(); i++) {
+ QAction *act = d->actions.at(i);
+ if (act == d->currentAction) {
+ if (key == Qt::Key_Up) {
+ for(int next_i = i-1; true; next_i--) {
+ if (next_i == -1) {
+ if(!style()->styleHint(QStyle::SH_Menu_SelectionWrap, 0, this))
+ break;
+ if (d->scroll)
+ scroll_loc = QMenuPrivate::QMenuScroller::ScrollBottom;
+ next_i = d->actionRects.count()-1;
+ }
+ QAction *next = d->actions.at(next_i);
+ if (next == d->currentAction)
+ break;
+ if (d->actionRects.at(next_i).isNull())
+ continue;
+ if (next->isSeparator() ||
+ (!next->isEnabled() &&
+ !style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, this)))
+ continue;
+ nextAction = next;
+ if (d->scroll && (d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp)) {
+ int topVisible = d->scrollerHeight();
+ if (d->tearoff)
+ topVisible += style()->pixelMetric(QStyle::PM_MenuTearoffHeight, 0, this);
+ if (((y + d->scroll->scrollOffset) - topVisible) <= d->actionRects.at(next_i).height())
+ scroll_loc = QMenuPrivate::QMenuScroller::ScrollTop;
+ }
+ break;
+ }
+ if (!nextAction && d->tearoff)
+ d->tearoffHighlighted = 1;
+ } else {
+ y += d->actionRects.at(i).height();
+ for(int next_i = i+1; true; next_i++) {
+ if (next_i == d->actionRects.count()) {
+ if(!style()->styleHint(QStyle::SH_Menu_SelectionWrap, 0, this))
+ break;
+ if (d->scroll)
+ scroll_loc = QMenuPrivate::QMenuScroller::ScrollTop;
+ next_i = 0;
+ }
+ QAction *next = d->actions.at(next_i);
+ if (next == d->currentAction)
+ break;
+ if (d->actionRects.at(next_i).isNull())
+ continue;
+ if (next->isSeparator() ||
+ (!next->isEnabled() &&
+ !style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, this)))
+ continue;
+ nextAction = next;
+ if (d->scroll && (d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollDown)) {
+ int bottomVisible = height() - d->scrollerHeight();
+ if (d->scroll->scrollFlags & QMenuPrivate::QMenuScroller::ScrollUp)
+ bottomVisible -= d->scrollerHeight();
+ if (d->tearoff)
+ bottomVisible -= style()->pixelMetric(QStyle::PM_MenuTearoffHeight, 0, this);
+ if ((y + d->scroll->scrollOffset + d->actionRects.at(next_i).height()) > bottomVisible)
+ scroll_loc = QMenuPrivate::QMenuScroller::ScrollBottom;
+ }
+ break;
+ }
+ }
+ break;
+ }
+ y += d->actionRects.at(i).height();
+ }
+ }
+ if (nextAction) {
+ if (d->scroll && scroll_loc != QMenuPrivate::QMenuScroller::ScrollStay) {
+ d->scroll->scrollTimer.stop();
+ d->scrollMenu(nextAction, scroll_loc);
+ }
+ d->setCurrentAction(nextAction, /*popup*/-1, QMenuPrivate::SelectedFromKeyboard);
+ }
+ break; }
+
+ case Qt::Key_Right:
+ if (d->currentAction && d->currentAction->isEnabled() && d->currentAction->menu()) {
+ d->popupAction(d->currentAction, 0, true);
+ key_consumed = true;
+ break;
+ }
+ //FALL THROUGH
+ case Qt::Key_Left: {
+ if (d->currentAction && !d->scroll) {
+ QAction *nextAction = 0;
+ if (key == Qt::Key_Left) {
+ QRect actionR = d->actionRect(d->currentAction);
+ for(int x = actionR.left()-1; !nextAction && x >= 0; x--)
+ nextAction = d->actionAt(QPoint(x, actionR.center().y()));
+ } else {
+ QRect actionR = d->actionRect(d->currentAction);
+ for(int x = actionR.right()+1; !nextAction && x < width(); x++)
+ nextAction = d->actionAt(QPoint(x, actionR.center().y()));
+ }
+ if (nextAction) {
+ d->setCurrentAction(nextAction, /*popup*/-1, QMenuPrivate::SelectedFromKeyboard);
+ key_consumed = true;
+ }
+ }
+ if (!key_consumed && key == Qt::Key_Left && qobject_cast<QMenu*>(d->causedPopup.widget)) {
+ QPointer<QWidget> caused = d->causedPopup.widget;
+ d->hideMenu(this);
+ if (caused)
+ caused->setFocus();
+ key_consumed = true;
+ }
+ break; }
+
+ case Qt::Key_Alt:
+ if (d->tornoff)
+ break;
+
+ key_consumed = true;
+ if (style()->styleHint(QStyle::SH_MenuBar_AltKeyNavigation, 0, this))
+ {
+ d->hideMenu(this);
+#ifndef QT_NO_MENUBAR
+ if (QMenuBar *mb = qobject_cast<QMenuBar*>(QApplication::focusWidget())) {
+ mb->d_func()->setKeyboardMode(false);
+ }
+#endif
+ }
+ break;
+
+ case Qt::Key_Escape:
+#ifdef QT_KEYPAD_NAVIGATION
+ case Qt::Key_Back:
+#endif
+ key_consumed = true;
+ if (d->tornoff) {
+ close();
+ return;
+ }
+ {
+ QPointer<QWidget> caused = d->causedPopup.widget;
+ d->hideMenu(this); // hide after getting causedPopup
+#ifndef QT_NO_MENUBAR
+ if (QMenuBar *mb = qobject_cast<QMenuBar*>(caused)) {
+ mb->d_func()->setCurrentAction(d->menuAction);
+ mb->d_func()->setKeyboardMode(true);
+ }
+#endif
+ }
+ break;
+
+ case Qt::Key_Space:
+ if (!style()->styleHint(QStyle::SH_Menu_SpaceActivatesItem, 0, this))
+ break;
+ // for motif, fall through
+#ifdef QT_KEYPAD_NAVIGATION
+ case Qt::Key_Select:
+#endif
+ case Qt::Key_Return:
+ case Qt::Key_Enter: {
+ if (!d->currentAction) {
+ d->setFirstActionActive();
+ key_consumed = true;
+ break;
+ }
+
+ d->setSyncAction();
+
+ if (d->currentAction->menu())
+ d->popupAction(d->currentAction, 0, true);
+ else
+ d->activateAction(d->currentAction, QAction::Trigger);
+ key_consumed = true;
+ break; }
+
+#ifndef QT_NO_WHATSTHIS
+ case Qt::Key_F1:
+ if (!d->currentAction || d->currentAction->whatsThis().isNull())
+ break;
+ QWhatsThis::enterWhatsThisMode();
+ d->activateAction(d->currentAction, QAction::Trigger);
+ return;
+#endif
+ default:
+ key_consumed = false;
+ }
+
+ if (!key_consumed) { // send to menu bar
+ if ((!e->modifiers() || e->modifiers() == Qt::AltModifier || e->modifiers() == Qt::ShiftModifier) &&
+ e->text().length()==1) {
+ bool activateAction = false;
+ QAction *nextAction = 0;
+ if (style()->styleHint(QStyle::SH_Menu_KeyboardSearch, 0, this) && !e->modifiers()) {
+ int best_match_count = 0;
+ d->searchBufferTimer.start(2000, this);
+ d->searchBuffer += e->text();
+ for(int i = 0; i < d->actions.size(); ++i) {
+ int match_count = 0;
+ if (d->actionRects.at(i).isNull())
+ continue;
+ QAction *act = d->actions.at(i);
+ const QString act_text = act->text();
+ for(int c = 0; c < d->searchBuffer.size(); ++c) {
+ if(act_text.indexOf(d->searchBuffer.at(c), 0, Qt::CaseInsensitive) != -1)
+ ++match_count;
+ }
+ if(match_count > best_match_count) {
+ best_match_count = match_count;
+ nextAction = act;
+ }
+ }
+ }
+#ifndef QT_NO_SHORTCUT
+ else {
+ int clashCount = 0;
+ QAction *first = 0, *currentSelected = 0, *firstAfterCurrent = 0;
+ QChar c = e->text().at(0).toUpper();
+ for(int i = 0; i < d->actions.size(); ++i) {
+ if (d->actionRects.at(i).isNull())
+ continue;
+ QAction *act = d->actions.at(i);
+ QKeySequence sequence = QKeySequence::mnemonic(act->text());
+ int key = sequence[0] & 0xffff;
+ if (key == c.unicode()) {
+ clashCount++;
+ if (!first)
+ first = act;
+ if (act == d->currentAction)
+ currentSelected = act;
+ else if (!firstAfterCurrent && currentSelected)
+ firstAfterCurrent = act;
+ }
+ }
+ if (clashCount == 1)
+ activateAction = true;
+ if (clashCount >= 1) {
+ if (clashCount == 1 || !currentSelected || !firstAfterCurrent)
+ nextAction = first;
+ else
+ nextAction = firstAfterCurrent;
+ }
+ }
+#endif
+ if (nextAction) {
+ key_consumed = true;
+ if(d->scroll)
+ d->scrollMenu(nextAction, QMenuPrivate::QMenuScroller::ScrollCenter, false);
+ d->setCurrentAction(nextAction, 20, QMenuPrivate::SelectedFromElsewhere, true);
+ if (!nextAction->menu() && activateAction) {
+ d->setSyncAction();
+ d->activateAction(nextAction, QAction::Trigger);
+ }
+ }
+ }
+ if (!key_consumed) {
+#ifndef QT_NO_MENUBAR
+ if (QMenuBar *mb = qobject_cast<QMenuBar*>(d->topCausedWidget())) {
+ QAction *oldAct = mb->d_func()->currentAction;
+ QApplication::sendEvent(mb, e);
+ if (mb->d_func()->currentAction != oldAct)
+ key_consumed = true;
+ }
+#endif
+ }
+
+#ifdef Q_OS_WIN32
+ if (key_consumed && (e->key() == Qt::Key_Control || e->key() == Qt::Key_Shift || e->key() == Qt::Key_Meta))
+ QApplication::beep();
+#endif // Q_OS_WIN32
+ }
+ if (key_consumed)
+ e->accept();
+ else
+ e->ignore();
+}
+
+/*!
+ \reimp
+*/
+void QMenu::mouseMoveEvent(QMouseEvent *e)
+{
+ Q_D(QMenu);
+ if (!isVisible() || d->aboutToHide || d->mouseEventTaken(e))
+ return;
+ d->motions++;
+ if (d->motions == 0) // ignore first mouse move event (see enterEvent())
+ return;
+ d->hasHadMouse = d->hasHadMouse || rect().contains(e->pos());
+
+ QAction *action = d->actionAt(e->pos());
+ if (!action) {
+ if (d->hasHadMouse
+ && (!d->currentAction
+ || !(d->currentAction->menu() && d->currentAction->menu()->isVisible())))
+ d->setCurrentAction(0);
+ return;
+ } else if(e->buttons()) {
+ d->mouseDown = this;
+ }
+ if (d->sloppyRegion.contains(e->pos())) {
+ d->sloppyAction = action;
+ QMenuPrivate::sloppyDelayTimer = startTimer(style()->styleHint(QStyle::SH_Menu_SubMenuPopupDelay, 0, this)*6);
+ } else if (action != d->currentAction) {
+ d->setCurrentAction(action, style()->styleHint(QStyle::SH_Menu_SubMenuPopupDelay, 0, this));
+ }
+}
+
+/*!
+ \reimp
+*/
+void QMenu::enterEvent(QEvent *)
+{
+ d_func()->motions = -1; // force us to ignore the generate mouse move in mouseMoveEvent()
+}
+
+/*!
+ \reimp
+*/
+void QMenu::leaveEvent(QEvent *)
+{
+ Q_D(QMenu);
+ d->sloppyAction = 0;
+ if (!d->sloppyRegion.isEmpty())
+ d->sloppyRegion = QRegion();
+ if (!d->activeMenu && d->currentAction)
+ setActiveAction(0);
+}
+
+/*!
+ \reimp
+*/
+void
+QMenu::timerEvent(QTimerEvent *e)
+{
+ Q_D(QMenu);
+ if (d->scroll && d->scroll->scrollTimer.timerId() == e->timerId()) {
+ d->scrollMenu((QMenuPrivate::QMenuScroller::ScrollDirection)d->scroll->scrollDirection);
+ if (d->scroll->scrollFlags == QMenuPrivate::QMenuScroller::ScrollNone)
+ d->scroll->scrollTimer.stop();
+ } else if(d->menuDelayTimer.timerId() == e->timerId()) {
+ d->menuDelayTimer.stop();
+ internalDelayedPopup();
+ } else if(QMenuPrivate::sloppyDelayTimer == e->timerId()) {
+ killTimer(QMenuPrivate::sloppyDelayTimer);
+ QMenuPrivate::sloppyDelayTimer = 0;
+ internalSetSloppyAction();
+ } else if(d->searchBufferTimer.timerId() == e->timerId()) {
+ d->searchBuffer.clear();
+ }
+}
+
+/*!
+ \reimp
+*/
+void QMenu::actionEvent(QActionEvent *e)
+{
+ Q_D(QMenu);
+ d->itemsDirty = 1;
+ setAttribute(Qt::WA_Resized, false);
+ if (d->tornPopup)
+ d->tornPopup->syncWithMenu(this, e);
+ if (e->type() == QEvent::ActionAdded) {
+ if(!d->tornoff) {
+ connect(e->action(), SIGNAL(triggered()), this, SLOT(_q_actionTriggered()));
+ connect(e->action(), SIGNAL(hovered()), this, SLOT(_q_actionHovered()));
+ }
+ if (QWidgetAction *wa = qobject_cast<QWidgetAction *>(e->action())) {
+ QWidget *widget = wa->requestWidget(this);
+ if (widget)
+ d->widgetItems.insert(wa, widget);
+ }
+ } else if (e->type() == QEvent::ActionRemoved) {
+ e->action()->disconnect(this);
+ if (e->action() == d->currentAction)
+ d->currentAction = 0;
+ if (QWidgetAction *wa = qobject_cast<QWidgetAction *>(e->action())) {
+ if (QWidget *widget = d->widgetItems.value(wa))
+ wa->releaseWidget(widget);
+ }
+ d->widgetItems.remove(e->action());
+ }
+
+ if (d->platformMenu) {
+ if (e->type() == QEvent::ActionAdded)
+ d->platformMenu->addAction(e->action(), e->before());
+ else if (e->type() == QEvent::ActionRemoved)
+ d->platformMenu->removeAction(e->action());
+ else if (e->type() == QEvent::ActionChanged)
+ d->platformMenu->syncAction(e->action());
+ }
+
+#if defined(Q_WS_WINCE) && !defined(QT_NO_MENUBAR)
+ if (!d->wce_menu)
+ d->wce_menu = new QMenuPrivate::QWceMenuPrivate;
+ if (e->type() == QEvent::ActionAdded)
+ d->wce_menu->addAction(e->action(), d->wce_menu->findAction(e->before()));
+ else if (e->type() == QEvent::ActionRemoved)
+ d->wce_menu->removeAction(e->action());
+ else if (e->type() == QEvent::ActionChanged)
+ d->wce_menu->syncAction(e->action());
+#endif
+
+#ifdef Q_WS_S60
+ if (!d->symbian_menu)
+ d->symbian_menu = new QMenuPrivate::QSymbianMenuPrivate;
+ if (e->type() == QEvent::ActionAdded)
+ d->symbian_menu->addAction(e->action(), d->symbian_menu->findAction(e->before()));
+ else if (e->type() == QEvent::ActionRemoved)
+ d->symbian_menu->removeAction(e->action());
+ else if (e->type() == QEvent::ActionChanged)
+ d->symbian_menu->syncAction(e->action());
+#endif
+ if (isVisible()) {
+ d->updateActionRects();
+ resize(sizeHint());
+ update();
+ }
+}
+
+/*!
+ \internal
+*/
+void QMenu::internalSetSloppyAction()
+{
+ if (d_func()->sloppyAction)
+ d_func()->setCurrentAction(d_func()->sloppyAction, 0);
+}
+
+/*!
+ \internal
+*/
+void QMenu::internalDelayedPopup()
+{
+ Q_D(QMenu);
+
+ //hide the current item
+ if (QMenu *menu = d->activeMenu) {
+ d->activeMenu = 0;
+ d->hideMenu(menu);
+ }
+
+ if (!d->currentAction || !d->currentAction->isEnabled() || !d->currentAction->menu() ||
+ !d->currentAction->menu()->isEnabled() || d->currentAction->menu()->isVisible())
+ return;
+
+ //setup
+ d->activeMenu = d->currentAction->menu();
+ d->activeMenu->d_func()->causedPopup.widget = this;
+ d->activeMenu->d_func()->causedPopup.action = d->currentAction;
+
+ 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(actionRect.right() + subMenuOffset + 1, actionRect.top())));
+
+ QPoint pos(rightPos);
+
+ //calc sloppy focus buffer
+ if (style()->styleHint(QStyle::SH_Menu_SloppySubMenus, 0, this)) {
+ QPoint cur = QCursor::pos();
+ if (actionRect.contains(mapFromGlobal(cur))) {
+ QPoint pts[4];
+ pts[0] = QPoint(cur.x(), cur.y() - 2);
+ pts[3] = QPoint(cur.x(), cur.y() + 2);
+ if (pos.x() >= cur.x()) {
+ pts[1] = QPoint(geometry().right(), pos.y());
+ pts[2] = QPoint(geometry().right(), pos.y() + menuSize.height());
+ } else {
+ pts[1] = QPoint(pos.x() + menuSize.width(), pos.y());
+ pts[2] = QPoint(pos.x() + menuSize.width(), pos.y() + menuSize.height());
+ }
+ QPolygon points(4);
+ for(int i = 0; i < 4; i++)
+ points.setPoint(i, mapFromGlobal(pts[i]));
+ d->sloppyRegion = QRegion(points);
+ }
+ }
+
+ //do the popup
+ d->activeMenu->popup(pos);
+}
+
+/*!
+ \fn void QMenu::addAction(QAction *action)
+ \overload
+
+ Appends the action \a action to the menu's list of actions.
+
+ \sa QMenuBar::addAction(), QWidget::addAction()
+*/
+
+/*!
+ \fn void QMenu::aboutToHide()
+ \since 4.2
+
+ This signal is emitted just before the menu is hidden from the user.
+
+ \sa aboutToShow(), hide()
+*/
+
+/*!
+ \fn void QMenu::aboutToShow()
+
+ This signal is emitted just before the menu is shown to the user.
+
+ \sa aboutToHide(), show()
+*/
+
+/*!
+ \fn void QMenu::triggered(QAction *action)
+
+ This signal is emitted when an action in this menu is triggered.
+
+ \a action is the action that caused the signal to be emitted.
+
+ Normally, you connect each menu action's \l{QAction::}{triggered()} signal
+ to its own custom slot, but sometimes you will want to connect several
+ actions to a single slot, for example, when you have a group of closely
+ related actions, such as "left justify", "center", "right justify".
+
+ \note This signal is emitted for the main parent menu in a hierarchy.
+ Hence, only the parent menu needs to be connected to a slot; sub-menus need
+ not be connected.
+
+ \sa hovered(), QAction::triggered()
+*/
+
+/*!
+ \fn void QMenu::hovered(QAction *action)
+
+ This signal is emitted when a menu action is highlighted; \a action
+ is the action that caused the signal to be emitted.
+
+ Often this is used to update status information.
+
+ \sa triggered(), QAction::hovered()
+*/
+
+
+/*!\internal
+*/
+void QMenu::setNoReplayFor(QWidget *noReplayFor)
+{
+#ifdef Q_WS_WIN
+ d_func()->noReplayFor = noReplayFor;
+#else
+ Q_UNUSED(noReplayFor);
+#endif
+}
+
+/*!\internal
+*/
+QPlatformMenu *QMenu::platformMenu()
+{
+
+ return d_func()->platformMenu;
+}
+
+/*!
+ \property QMenu::separatorsCollapsible
+ \since 4.2
+
+ \brief whether consecutive separators should be collapsed
+
+ This property specifies whether consecutive separators in the menu
+ should be visually collapsed to a single one. Separators at the
+ beginning or the end of the menu are also hidden.
+
+ By default, this property is true.
+*/
+bool QMenu::separatorsCollapsible() const
+{
+ Q_D(const QMenu);
+ return d->collapsibleSeparators;
+}
+
+void QMenu::setSeparatorsCollapsible(bool collapse)
+{
+ Q_D(QMenu);
+ if (d->collapsibleSeparators == collapse)
+ return;
+
+ d->collapsibleSeparators = collapse;
+ d->itemsDirty = 1;
+ if (isVisible()) {
+ d->updateActionRects();
+ update();
+ }
+ if (d->platformMenu)
+ d->platformMenu->syncSeparatorsCollapsible(collapse);
+}
+
+QT_END_NAMESPACE
+
+// for private slots
+#include "moc_qmenu.cpp"
+#include "qmenu.moc"
+
+#endif // QT_NO_MENU
diff --git a/src/widgets/widgets/qmenu.h b/src/widgets/widgets/qmenu.h
new file mode 100644
index 0000000000..49bf8295ec
--- /dev/null
+++ b/src/widgets/widgets/qmenu.h
@@ -0,0 +1,210 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMENU_H
+#define QMENU_H
+
+#include <QtWidgets/qwidget.h>
+#include <QtCore/qstring.h>
+#include <QtWidgets/qicon.h>
+#include <QtWidgets/qaction.h>
+#include <QtWidgets/qplatformmenu_qpa.h>
+
+#ifdef Q_WS_WINCE
+#include <windef.h> // for HMENU
+#endif
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_MENU
+
+class QMenuPrivate;
+class QStyleOptionMenuItem;
+
+class Q_WIDGETS_EXPORT QMenu : public QWidget
+{
+private:
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QMenu)
+
+ Q_PROPERTY(bool tearOffEnabled READ isTearOffEnabled WRITE setTearOffEnabled)
+ Q_PROPERTY(QString title READ title WRITE setTitle)
+ Q_PROPERTY(QIcon icon READ icon WRITE setIcon)
+ Q_PROPERTY(bool separatorsCollapsible READ separatorsCollapsible WRITE setSeparatorsCollapsible)
+
+public:
+ explicit QMenu(QWidget *parent = 0);
+ explicit QMenu(const QString &title, QWidget *parent = 0);
+ ~QMenu();
+
+#ifdef Q_NO_USING_KEYWORD
+ inline void addAction(QAction *action) { QWidget::addAction(action); }
+#else
+ using QWidget::addAction;
+#endif
+ QAction *addAction(const QString &text);
+ QAction *addAction(const QIcon &icon, const QString &text);
+ QAction *addAction(const QString &text, const QObject *receiver, const char* member, const QKeySequence &shortcut = 0);
+ QAction *addAction(const QIcon &icon, const QString &text, const QObject *receiver, const char* member, const QKeySequence &shortcut = 0);
+
+ QAction *addMenu(QMenu *menu);
+ QMenu *addMenu(const QString &title);
+ QMenu *addMenu(const QIcon &icon, const QString &title);
+
+ QAction *addSeparator();
+
+ QAction *insertMenu(QAction *before, QMenu *menu);
+ QAction *insertSeparator(QAction *before);
+
+ bool isEmpty() const;
+ void clear();
+
+ void setTearOffEnabled(bool);
+ bool isTearOffEnabled() const;
+
+ bool isTearOffMenuVisible() const;
+ void hideTearOffMenu();
+
+ void setDefaultAction(QAction *);
+ QAction *defaultAction() const;
+
+ void setActiveAction(QAction *act);
+ QAction *activeAction() const;
+
+ void popup(const QPoint &pos, QAction *at=0);
+ QAction *exec();
+ QAction *exec(const QPoint &pos, QAction *at=0);
+
+ // ### Qt 5: merge
+ static QAction *exec(QList<QAction*> actions, const QPoint &pos, QAction *at=0);
+ static QAction *exec(QList<QAction*> actions, const QPoint &pos, QAction *at, QWidget *parent);
+
+ QSize sizeHint() const;
+
+ QRect actionGeometry(QAction *) const;
+ QAction *actionAt(const QPoint &) const;
+
+ QAction *menuAction() const;
+
+ QString title() const;
+ void setTitle(const QString &title);
+
+ QIcon icon() const;
+ void setIcon(const QIcon &icon);
+
+ void setNoReplayFor(QWidget *widget);
+ QPlatformMenu *platformMenu();
+
+#ifdef Q_WS_WINCE
+ HMENU wceMenu();
+#endif
+
+ bool separatorsCollapsible() const;
+ void setSeparatorsCollapsible(bool collapse);
+
+Q_SIGNALS:
+ void aboutToShow();
+ void aboutToHide();
+ void triggered(QAction *action);
+ void hovered(QAction *action);
+
+protected:
+ int columnCount() const;
+
+ void changeEvent(QEvent *);
+ void keyPressEvent(QKeyEvent *);
+ void mouseReleaseEvent(QMouseEvent *);
+ void mousePressEvent(QMouseEvent *);
+ void mouseMoveEvent(QMouseEvent *);
+#ifndef QT_NO_WHEELEVENT
+ void wheelEvent(QWheelEvent *);
+#endif
+ void enterEvent(QEvent *);
+ void leaveEvent(QEvent *);
+ void hideEvent(QHideEvent *);
+ void paintEvent(QPaintEvent *);
+ void actionEvent(QActionEvent *);
+ void timerEvent(QTimerEvent *);
+ bool event(QEvent *);
+ bool focusNextPrevChild(bool next);
+ void initStyleOption(QStyleOptionMenuItem *option, const QAction *action) const;
+
+#ifdef Q_WS_WINCE
+ QAction* wceCommands(uint command);
+#endif
+
+private Q_SLOTS:
+ void internalSetSloppyAction();
+ void internalDelayedPopup();
+
+private:
+ Q_PRIVATE_SLOT(d_func(), void _q_actionTriggered())
+ Q_PRIVATE_SLOT(d_func(), void _q_actionHovered())
+ Q_PRIVATE_SLOT(d_func(), void _q_overrideMenuActionDestroyed())
+
+protected:
+ QMenu(QMenuPrivate &dd, QWidget* parent = 0);
+
+private:
+ Q_DISABLE_COPY(QMenu)
+
+ friend class QMenuBar;
+ friend class QMenuBarPrivate;
+ friend class QTornOffMenu;
+ friend class Q3PopupMenu;
+ friend class QComboBox;
+ friend class QAction;
+ friend class QToolButtonPrivate;
+ friend void qt_mac_emit_menuSignals(QMenu *menu, bool show);
+ friend void qt_mac_menu_emit_hovered(QMenu *menu, QAction *action);
+};
+
+#endif // QT_NO_MENU
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QMENU_H
diff --git a/src/widgets/widgets/qmenu_p.h b/src/widgets/widgets/qmenu_p.h
new file mode 100644
index 0000000000..df15512b3e
--- /dev/null
+++ b/src/widgets/widgets/qmenu_p.h
@@ -0,0 +1,316 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMENU_P_H
+#define QMENU_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "QtWidgets/qmenubar.h"
+#include "QtWidgets/qstyleoption.h"
+#ifdef Q_OS_MAC
+#include "QtWidgets/qmacdefines_mac.h"
+#endif
+#include "QtCore/qdatetime.h"
+#include "QtCore/qmap.h"
+#include "QtCore/qhash.h"
+#include "QtCore/qbasictimer.h"
+#include "private/qwidget_p.h"
+
+
+#ifdef Q_WS_S60
+class CEikMenuPane;
+#define QT_SYMBIAN_FIRST_MENU_ITEM 32000
+#define QT_SYMBIAN_LAST_MENU_ITEM 41999 // 10000 items ought to be enough for anybody...
+#endif
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_MENU
+
+#ifdef Q_WS_S60
+void qt_symbian_next_menu_from_action(QWidget* actionContainer);
+void qt_symbian_show_toplevel(CEikMenuPane* menuPane);
+void qt_symbian_show_submenu(CEikMenuPane* menuPane, int id);
+#endif // Q_WS_S60
+
+class QTornOffMenu;
+class QEventLoop;
+
+#ifdef Q_WS_WINCE
+struct QWceMenuAction {
+ uint command;
+ QPointer<QAction> action;
+ HMENU menuHandle;
+ QWceMenuAction() : menuHandle(0), command(0) {}
+};
+#endif
+#ifdef Q_WS_S60
+struct QSymbianMenuAction {
+ uint command;
+ int parent;
+ CEikMenuPane* menuPane;
+ QPointer<QAction> action;
+ QSymbianMenuAction() : command(0) {}
+};
+#endif
+
+class QMenuPrivate : public QWidgetPrivate
+{
+ Q_DECLARE_PUBLIC(QMenu)
+public:
+ QMenuPrivate() : itemsDirty(0), maxIconWidth(0), tabWidth(0), ncols(0),
+ collapsibleSeparators(true), activationRecursionGuard(false), hasHadMouse(0), aboutToHide(0), motions(0),
+ currentAction(0),
+#ifdef QT_KEYPAD_NAVIGATION
+ selectAction(0),
+ cancelAction(0),
+#endif
+ scroll(0), eventLoop(0), tearoff(0), tornoff(0), tearoffHighlighted(0),
+ hasCheckableItems(0), sloppyAction(0), doChildEffects(false), platformMenu(0)
+
+#if defined(Q_WS_WINCE) && !defined(QT_NO_MENUBAR)
+ ,wce_menu(0)
+#endif
+#ifdef Q_WS_S60
+ ,symbian_menu(0)
+#endif
+ { }
+ ~QMenuPrivate()
+ {
+ delete scroll;
+ delete platformMenu;
+#if defined(Q_WS_WINCE) && !defined(QT_NO_MENUBAR)
+ delete wce_menu;
+#endif
+#ifdef Q_WS_S60
+ delete symbian_menu;
+#endif
+
+ }
+ void init();
+
+ static QMenuPrivate *get(QMenu *m) { return m->d_func(); }
+ int scrollerHeight() const;
+
+ //item calculations
+ mutable uint itemsDirty : 1;
+ mutable uint maxIconWidth, tabWidth;
+ QRect actionRect(QAction *) const;
+
+ mutable QVector<QRect> actionRects;
+ mutable QHash<QAction *, QWidget *> widgetItems;
+ void updateActionRects() const;
+ void updateActionRects(const QRect &screen) const;
+ QRect popupGeometry(const QWidget *widget) const;
+ QRect popupGeometry(int screen = -1) const;
+ mutable uint ncols : 4; //4 bits is probably plenty
+ uint collapsibleSeparators : 1;
+ QSize adjustMenuSizeForScreen(const QRect & screen);
+ int getLastVisibleAction() const;
+
+ bool activationRecursionGuard;
+
+ //selection
+ static QMenu *mouseDown;
+ QPoint mousePopupPos;
+ uint hasHadMouse : 1;
+ uint aboutToHide : 1;
+ int motions;
+ QAction *currentAction;
+#ifdef QT_KEYPAD_NAVIGATION
+ QAction *selectAction;
+ QAction *cancelAction;
+#endif
+ QBasicTimer menuDelayTimer;
+ enum SelectionReason {
+ SelectedFromKeyboard,
+ SelectedFromElsewhere
+ };
+ QWidget *topCausedWidget() const;
+ QAction *actionAt(QPoint p) const;
+ void setFirstActionActive();
+ void setCurrentAction(QAction *, int popup = -1, SelectionReason reason = SelectedFromElsewhere, bool activateFirst = false);
+ void popupAction(QAction *, int, bool);
+ void setSyncAction();
+
+ //scrolling support
+ struct QMenuScroller {
+ enum ScrollLocation { ScrollStay, ScrollBottom, ScrollTop, ScrollCenter };
+ enum ScrollDirection { ScrollNone=0, ScrollUp=0x01, ScrollDown=0x02 };
+ uint scrollFlags : 2, scrollDirection : 2;
+ int scrollOffset;
+ QBasicTimer scrollTimer;
+
+ QMenuScroller() : scrollFlags(ScrollNone), scrollDirection(ScrollNone), scrollOffset(0) { }
+ ~QMenuScroller() { }
+ } *scroll;
+ void scrollMenu(QMenuScroller::ScrollLocation location, bool active=false);
+ void scrollMenu(QMenuScroller::ScrollDirection direction, bool page=false, bool active=false);
+ void scrollMenu(QAction *action, QMenuScroller::ScrollLocation location, bool active=false);
+
+ //synchronous operation (ie exec())
+ QEventLoop *eventLoop;
+ QPointer<QAction> syncAction;
+
+ //search buffer
+ QString searchBuffer;
+ QBasicTimer searchBufferTimer;
+
+ //passing of mouse events up the parent hierarchy
+ QPointer<QMenu> activeMenu;
+ bool mouseEventTaken(QMouseEvent *);
+
+ //used to walk up the popup list
+ struct QMenuCaused {
+ QPointer<QWidget> widget;
+ QPointer<QAction> action;
+ };
+ virtual QList<QPointer<QWidget> > calcCausedStack() const;
+ QMenuCaused causedPopup;
+ void hideUpToMenuBar();
+ void hideMenu(QMenu *menu, bool justRegister = false);
+
+ //index mappings
+ inline QAction *actionAt(int i) const { return q_func()->actions().at(i); }
+ inline int indexOf(QAction *act) const { return q_func()->actions().indexOf(act); }
+
+ //tear off support
+ uint tearoff : 1, tornoff : 1, tearoffHighlighted : 1;
+ QPointer<QTornOffMenu> tornPopup;
+
+ mutable bool hasCheckableItems;
+
+ //sloppy selection
+ static int sloppyDelayTimer;
+ mutable QAction *sloppyAction;
+ QRegion sloppyRegion;
+
+ //default action
+ QPointer<QAction> defaultAction;
+
+ QAction *menuAction;
+ QAction *defaultMenuAction;
+
+ void setOverrideMenuAction(QAction *);
+ void _q_overrideMenuActionDestroyed();
+
+ //firing of events
+ void activateAction(QAction *, QAction::ActionEvent, bool self=true);
+ void activateCausedStack(const QList<QPointer<QWidget> > &, QAction *, QAction::ActionEvent, bool);
+
+ void _q_actionTriggered();
+ void _q_actionHovered();
+
+ bool hasMouseMoved(const QPoint &globalPos);
+
+ void updateLayoutDirection();
+
+ //menu fading/scrolling effects
+ bool doChildEffects;
+
+ QPlatformMenu *platformMenu;
+
+ QPointer<QAction> actionAboutToTrigger;
+
+#if defined(Q_WS_WINCE) && !defined(QT_NO_MENUBAR)
+ struct QWceMenuPrivate {
+ QList<QWceMenuAction*> actionItems;
+ HMENU menuHandle;
+ QWceMenuPrivate();
+ ~QWceMenuPrivate();
+ void addAction(QAction *, QWceMenuAction* =0);
+ void addAction(QWceMenuAction *, QWceMenuAction* =0);
+ void syncAction(QWceMenuAction *);
+ inline void syncAction(QAction *a) { syncAction(findAction(a)); }
+ void removeAction(QWceMenuAction *);
+ void rebuild();
+ inline void removeAction(QAction *a) { removeAction(findAction(a)); }
+ inline QWceMenuAction *findAction(QAction *a) {
+ for(int i = 0; i < actionItems.size(); i++) {
+ QWceMenuAction *act = actionItems[i];
+ if(a == act->action)
+ return act;
+ }
+ return 0;
+ }
+ } *wce_menu;
+ HMENU wceMenu();
+ QAction* wceCommands(uint command);
+#endif
+#if defined(Q_WS_S60)
+ struct QSymbianMenuPrivate {
+ QList<QSymbianMenuAction*> actionItems;
+ QSymbianMenuPrivate();
+ ~QSymbianMenuPrivate();
+ void addAction(QAction *, QSymbianMenuAction* =0);
+ void addAction(QSymbianMenuAction *, QSymbianMenuAction* =0);
+ void syncAction(QSymbianMenuAction *);
+ inline void syncAction(QAction *a) { syncAction(findAction(a)); }
+ void removeAction(QSymbianMenuAction *);
+ void rebuild(bool reCreate = false);
+ inline void removeAction(QAction *a) { removeAction(findAction(a)); }
+ inline QSymbianMenuAction *findAction(QAction *a) {
+ for(int i = 0; i < actionItems.size(); i++) {
+ QSymbianMenuAction *act = actionItems[i];
+ if(a == act->action)
+ return act;
+ }
+ return 0;
+ }
+ } *symbian_menu;
+#endif
+ QPointer<QWidget> noReplayFor;
+};
+
+#endif // QT_NO_MENU
+
+QT_END_NAMESPACE
+
+#endif // QMENU_P_H
diff --git a/src/gui/widgets/qmenu_symbian.cpp b/src/widgets/widgets/qmenu_symbian.cpp
index 4250601f98..4250601f98 100644
--- a/src/gui/widgets/qmenu_symbian.cpp
+++ b/src/widgets/widgets/qmenu_symbian.cpp
diff --git a/src/gui/widgets/qmenu_wince.cpp b/src/widgets/widgets/qmenu_wince.cpp
index b0c6c1bd12..b0c6c1bd12 100644
--- a/src/gui/widgets/qmenu_wince.cpp
+++ b/src/widgets/widgets/qmenu_wince.cpp
diff --git a/src/gui/widgets/qmenu_wince.rc b/src/widgets/widgets/qmenu_wince.rc
index 2540d9f43a..2540d9f43a 100644
--- a/src/gui/widgets/qmenu_wince.rc
+++ b/src/widgets/widgets/qmenu_wince.rc
diff --git a/src/gui/widgets/qmenu_wince_resource_p.h b/src/widgets/widgets/qmenu_wince_resource_p.h
index 42de05f319..42de05f319 100644
--- a/src/gui/widgets/qmenu_wince_resource_p.h
+++ b/src/widgets/widgets/qmenu_wince_resource_p.h
diff --git a/src/widgets/widgets/qmenubar.cpp b/src/widgets/widgets/qmenubar.cpp
new file mode 100644
index 0000000000..385df52adf
--- /dev/null
+++ b/src/widgets/widgets/qmenubar.cpp
@@ -0,0 +1,2063 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qmenubar.h>
+
+#include <qstyle.h>
+#include <qlayout.h>
+#include <qapplication.h>
+#include <qdesktopwidget.h>
+#ifndef QT_NO_ACCESSIBILITY
+# include <qaccessible.h>
+#endif
+#include <qpainter.h>
+#include <qstylepainter.h>
+#include <qevent.h>
+#include <qmainwindow.h>
+#include <qtoolbar.h>
+#include <qtoolbutton.h>
+#include <qwhatsthis.h>
+#include "private/qguiapplication_p.h"
+
+#ifndef QT_NO_MENUBAR
+
+#ifdef QT3_SUPPORT
+#include <private/qaction_p.h>
+#include <qmenudata.h>
+#endif
+
+#include "qmenu_p.h"
+#include "qmenubar_p.h"
+#include "qdebug.h"
+
+#ifdef Q_WS_WINCE
+extern bool qt_wince_is_mobile(); //defined in qguifunctions_wce.cpp
+#endif
+
+#ifdef QT_SOFTKEYS_ENABLED
+#include <private/qsoftkeymanager_p.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+class QMenuBarExtension : public QToolButton
+{
+public:
+ explicit QMenuBarExtension(QWidget *parent);
+
+ QSize sizeHint() const;
+ void paintEvent(QPaintEvent *);
+};
+
+QMenuBarExtension::QMenuBarExtension(QWidget *parent)
+ : QToolButton(parent)
+{
+ setObjectName(QLatin1String("qt_menubar_ext_button"));
+ setAutoRaise(true);
+#ifndef QT_NO_MENU
+ setPopupMode(QToolButton::InstantPopup);
+#endif
+ setIcon(style()->standardIcon(QStyle::SP_ToolBarHorizontalExtensionButton, 0, parentWidget()));
+}
+
+void QMenuBarExtension::paintEvent(QPaintEvent *)
+{
+ QStylePainter p(this);
+ QStyleOptionToolButton opt;
+ initStyleOption(&opt);
+ // We do not need to draw both extension arrows
+ opt.features &= ~QStyleOptionToolButton::HasMenu;
+ p.drawComplexControl(QStyle::CC_ToolButton, opt);
+}
+
+
+QSize QMenuBarExtension::sizeHint() const
+{
+ int ext = style()->pixelMetric(QStyle::PM_ToolBarExtensionExtent, 0, parentWidget());
+ return QSize(ext, ext);
+}
+
+
+/*!
+ \internal
+*/
+QAction *QMenuBarPrivate::actionAt(QPoint p) const
+{
+ for(int i = 0; i < actions.size(); ++i) {
+ if(actionRect(actions.at(i)).contains(p))
+ return actions.at(i);
+ }
+ return 0;
+}
+
+QRect QMenuBarPrivate::menuRect(bool extVisible) const
+{
+ Q_Q(const QMenuBar);
+
+ int hmargin = q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, q);
+ QRect result = q->rect();
+ result.adjust(hmargin, 0, -hmargin, 0);
+
+ if (extVisible) {
+ if (q->isRightToLeft())
+ result.setLeft(result.left() + extension->sizeHint().width());
+ else
+ result.setWidth(result.width() - extension->sizeHint().width());
+ }
+
+ if (leftWidget && leftWidget->isVisible()) {
+ QSize sz = leftWidget->sizeHint();
+ if (q->isRightToLeft())
+ result.setRight(result.right() - sz.width());
+ else
+ result.setLeft(result.left() + sz.width());
+ }
+
+ if (rightWidget && rightWidget->isVisible()) {
+ QSize sz = rightWidget->sizeHint();
+ if (q->isRightToLeft())
+ result.setLeft(result.left() + sz.width());
+ else
+ result.setRight(result.right() - sz.width());
+ }
+
+ return result;
+}
+
+bool QMenuBarPrivate::isVisible(QAction *action)
+{
+ return !hiddenActions.contains(action);
+}
+
+void QMenuBarPrivate::updateGeometries()
+{
+ Q_Q(QMenuBar);
+ if(!itemsDirty)
+ return;
+ int q_width = q->width()-(q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, q)*2);
+ int q_start = -1;
+ if(leftWidget || rightWidget) {
+ int vmargin = q->style()->pixelMetric(QStyle::PM_MenuBarVMargin, 0, q)
+ + q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, q);
+ int hmargin = q->style()->pixelMetric(QStyle::PM_MenuBarHMargin, 0, q)
+ + q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, q);
+ if (leftWidget && leftWidget->isVisible()) {
+ QSize sz = leftWidget->sizeHint();
+ q_width -= sz.width();
+ q_start = sz.width();
+ QPoint pos(hmargin, (q->height() - leftWidget->height()) / 2);
+ QRect vRect = QStyle::visualRect(q->layoutDirection(), q->rect(), QRect(pos, sz));
+ leftWidget->setGeometry(vRect);
+ }
+ if (rightWidget && rightWidget->isVisible()) {
+ QSize sz = rightWidget->sizeHint();
+ q_width -= sz.width();
+ QPoint pos(q->width() - sz.width() - hmargin, vmargin);
+ QRect vRect = QStyle::visualRect(q->layoutDirection(), q->rect(), QRect(pos, sz));
+ rightWidget->setGeometry(vRect);
+ }
+ }
+
+#ifdef Q_OS_MAC
+ if(q->isNativeMenuBar()) {//nothing to see here folks, move along..
+ itemsDirty = false;
+ return;
+ }
+#endif
+ calcActionRects(q_width, q_start);
+ currentAction = 0;
+#ifndef QT_NO_SHORTCUT
+ if(itemsDirty) {
+ for(int j = 0; j < shortcutIndexMap.size(); ++j)
+ q->releaseShortcut(shortcutIndexMap.value(j));
+ shortcutIndexMap.resize(0); // faster than clear
+ for(int i = 0; i < actions.count(); i++)
+ shortcutIndexMap.append(q->grabShortcut(QKeySequence::mnemonic(actions.at(i)->text())));
+ }
+#endif
+ itemsDirty = false;
+
+ hiddenActions.clear();
+ //this is the menu rectangle without any extension
+ QRect menuRect = this->menuRect(false);
+
+ //we try to see if the actions will fit there
+ bool hasHiddenActions = false;
+ for (int i = 0; i < actions.count(); ++i) {
+ const QRect &rect = actionRects.at(i);
+ if (rect.isValid() && !menuRect.contains(rect)) {
+ hasHiddenActions = true;
+ break;
+ }
+ }
+
+ //...and if not, determine the ones that fit on the menu with the extension visible
+ if (hasHiddenActions) {
+ menuRect = this->menuRect(true);
+ for (int i = 0; i < actions.count(); ++i) {
+ const QRect &rect = actionRects.at(i);
+ if (rect.isValid() && !menuRect.contains(rect)) {
+ hiddenActions.append(actions.at(i));
+ }
+ }
+ }
+
+ if (hiddenActions.count() > 0) {
+ QMenu *pop = extension->menu();
+ if (!pop) {
+ pop = new QMenu(q);
+ extension->setMenu(pop);
+ }
+ pop->clear();
+ pop->addActions(hiddenActions);
+
+ int vmargin = q->style()->pixelMetric(QStyle::PM_MenuBarVMargin, 0, q);
+ int x = q->isRightToLeft()
+ ? menuRect.left() - extension->sizeHint().width() + 1
+ : menuRect.right();
+ extension->setGeometry(x, vmargin, extension->sizeHint().width(), menuRect.height() - vmargin*2);
+ extension->show();
+ } else {
+ extension->hide();
+ }
+ q->updateGeometry();
+#ifdef QT3_SUPPORT
+ if (parent) {
+ QMenubarUpdatedEvent menubarUpdated(q);
+ QApplication::sendEvent(parent, &menubarUpdated);
+ }
+#endif
+}
+
+QRect QMenuBarPrivate::actionRect(QAction *act) const
+{
+ const int index = actions.indexOf(act);
+
+ //makes sure the geometries are up-to-date
+ const_cast<QMenuBarPrivate*>(this)->updateGeometries();
+
+ if (index < 0 || index >= actionRects.count())
+ return QRect(); // that can happen in case of native menubar
+
+ return actionRects.at(index);
+}
+
+void QMenuBarPrivate::focusFirstAction()
+{
+ if(!currentAction) {
+ updateGeometries();
+ int index = 0;
+ while (index < actions.count() && actionRects.at(index).isNull()) ++index;
+ if (index < actions.count())
+ setCurrentAction(actions.at(index));
+ }
+}
+
+void QMenuBarPrivate::setKeyboardMode(bool b)
+{
+ Q_Q(QMenuBar);
+ if (b && !q->style()->styleHint(QStyle::SH_MenuBar_AltKeyNavigation, 0, q)) {
+ setCurrentAction(0);
+ return;
+ }
+ keyboardState = b;
+ if(b) {
+ QWidget *fw = QApplication::focusWidget();
+ if (fw != q)
+ keyboardFocusWidget = fw;
+ focusFirstAction();
+ q->setFocus(Qt::MenuBarFocusReason);
+ } else {
+ if(!popupState)
+ setCurrentAction(0);
+ if(keyboardFocusWidget) {
+ if (QApplication::focusWidget() == q)
+ keyboardFocusWidget->setFocus(Qt::MenuBarFocusReason);
+ keyboardFocusWidget = 0;
+ }
+ }
+ q->update();
+}
+
+void QMenuBarPrivate::popupAction(QAction *action, bool activateFirst)
+{
+ Q_Q(QMenuBar);
+ if(!action || !action->menu() || closePopupMode)
+ return;
+ popupState = true;
+ if (action->isEnabled() && action->menu()->isEnabled()) {
+ closePopupMode = 0;
+ activeMenu = action->menu();
+ activeMenu->d_func()->causedPopup.widget = q;
+ activeMenu->d_func()->causedPopup.action = action;
+
+ QRect adjustedActionRect = actionRect(action);
+ QPoint pos(q->mapToGlobal(QPoint(adjustedActionRect.left(), adjustedActionRect.bottom() + 1)));
+ QSize popup_size = activeMenu->sizeHint();
+
+ //we put the popup menu on the screen containing the bottom-center of the action rect
+ QRect screenRect = QApplication::desktop()->screenGeometry(pos + QPoint(adjustedActionRect.width() / 2, 0));
+ pos = QPoint(qMax(pos.x(), screenRect.x()), qMax(pos.y(), screenRect.y()));
+
+ const bool fitUp = (q->mapToGlobal(adjustedActionRect.topLeft()).y() >= popup_size.height());
+ const bool fitDown = (pos.y() + popup_size.height() <= screenRect.bottom());
+ const bool rtl = q->isRightToLeft();
+ const int actionWidth = adjustedActionRect.width();
+
+ if (!fitUp && !fitDown) { //we should shift the menu
+ bool shouldShiftToRight = !rtl;
+ if (rtl && popup_size.width() > pos.x())
+ shouldShiftToRight = true;
+ else if (actionWidth + popup_size.width() + pos.x() > screenRect.right())
+ shouldShiftToRight = false;
+
+ if (shouldShiftToRight) {
+ pos.rx() += actionWidth + (rtl ? popup_size.width() : 0);
+ } else {
+ //shift to left
+ if (!rtl)
+ pos.rx() -= popup_size.width();
+ }
+ } else if (rtl) {
+ pos.rx() += actionWidth;
+ }
+
+ if(!defaultPopDown || (fitUp && !fitDown))
+ pos.setY(qMax(screenRect.y(), q->mapToGlobal(QPoint(0, adjustedActionRect.top()-popup_size.height())).y()));
+ activeMenu->popup(pos);
+ if(activateFirst)
+ activeMenu->d_func()->setFirstActionActive();
+ }
+ q->update(actionRect(action));
+}
+
+void QMenuBarPrivate::setCurrentAction(QAction *action, bool popup, bool activateFirst)
+{
+ if(currentAction == action && popup == popupState)
+ return;
+
+ autoReleaseTimer.stop();
+
+ doChildEffects = (popup && !activeMenu);
+ Q_Q(QMenuBar);
+ QWidget *fw = 0;
+ if(QMenu *menu = activeMenu) {
+ activeMenu = 0;
+ if (popup) {
+ fw = q->window()->focusWidget();
+ q->setFocus(Qt::NoFocusReason);
+ }
+ menu->hide();
+ }
+
+ if(currentAction)
+ q->update(actionRect(currentAction));
+
+ popupState = popup;
+#ifndef QT_NO_STATUSTIP
+ QAction *previousAction = currentAction;
+#endif
+ currentAction = action;
+ if (action) {
+ activateAction(action, QAction::Hover);
+ if(popup)
+ popupAction(action, activateFirst);
+ q->update(actionRect(action));
+#ifndef QT_NO_STATUSTIP
+ } else if (previousAction) {
+ QString empty;
+ QStatusTipEvent tip(empty);
+ QApplication::sendEvent(q, &tip);
+#endif
+ }
+ if (fw)
+ fw->setFocus(Qt::NoFocusReason);
+}
+
+void QMenuBarPrivate::calcActionRects(int max_width, int start) const
+{
+ Q_Q(const QMenuBar);
+
+ if(!itemsDirty)
+ return;
+
+ //let's reinitialize the buffer
+ actionRects.resize(actions.count());
+ actionRects.fill(QRect());
+
+ const QStyle *style = q->style();
+
+ const int itemSpacing = style->pixelMetric(QStyle::PM_MenuBarItemSpacing, 0, q);
+ int max_item_height = 0, separator = -1, separator_start = 0, separator_len = 0;
+
+ //calculate size
+ const QFontMetrics fm = q->fontMetrics();
+ const int hmargin = style->pixelMetric(QStyle::PM_MenuBarHMargin, 0, q),
+ vmargin = style->pixelMetric(QStyle::PM_MenuBarVMargin, 0, q),
+ icone = style->pixelMetric(QStyle::PM_SmallIconSize, 0, q);
+ for(int i = 0; i < actions.count(); i++) {
+ QAction *action = actions.at(i);
+ if(!action->isVisible())
+ continue;
+
+ QSize sz;
+
+ //calc what I think the size is..
+ if(action->isSeparator()) {
+ if (style->styleHint(QStyle::SH_DrawMenuBarSeparator, 0, q))
+ separator = i;
+ continue; //we don't really position these!
+ } else {
+ const QString s = action->text();
+ QIcon is = action->icon();
+ // If an icon is set, only the icon is visible
+ if (!is.isNull())
+ sz = sz.expandedTo(QSize(icone, icone));
+ else if (!s.isEmpty())
+ sz = fm.size(Qt::TextShowMnemonic, s);
+ }
+
+ //let the style modify the above size..
+ QStyleOptionMenuItem opt;
+ q->initStyleOption(&opt, action);
+ sz = q->style()->sizeFromContents(QStyle::CT_MenuBarItem, &opt, sz, q);
+
+ if(!sz.isEmpty()) {
+ { //update the separator state
+ int iWidth = sz.width() + itemSpacing;
+ if(separator == -1)
+ separator_start += iWidth;
+ else
+ separator_len += iWidth;
+ }
+ //maximum height
+ max_item_height = qMax(max_item_height, sz.height());
+ //append
+ actionRects[i] = QRect(0, 0, sz.width(), sz.height());
+ }
+ }
+
+ //calculate position
+ const int fw = q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, q);
+ int x = fw + ((start == -1) ? hmargin : start) + itemSpacing;
+ int y = fw + vmargin;
+ for(int i = 0; i < actions.count(); i++) {
+ QRect &rect = actionRects[i];
+ if (rect.isNull())
+ continue;
+
+ //resize
+ rect.setHeight(max_item_height);
+
+ //move
+ if(separator != -1 && i >= separator) { //after the separator
+ int left = (max_width - separator_len - hmargin - itemSpacing) + (x - separator_start - hmargin);
+ if(left < separator_start) { //wrap
+ separator_start = x = hmargin;
+ y += max_item_height;
+ }
+ rect.moveLeft(left);
+ } else {
+ rect.moveLeft(x);
+ }
+ rect.moveTop(y);
+
+ //keep moving along..
+ x += rect.width() + itemSpacing;
+
+ //make sure we follow the layout direction
+ rect = QStyle::visualRect(q->layoutDirection(), q->rect(), rect);
+ }
+}
+
+void QMenuBarPrivate::activateAction(QAction *action, QAction::ActionEvent action_e)
+{
+ Q_Q(QMenuBar);
+ if (!action || !action->isEnabled())
+ return;
+ action->activate(action_e);
+ if (action_e == QAction::Hover)
+ action->showStatusText(q);
+
+// if(action_e == QAction::Trigger)
+// emit q->activated(action);
+// else if(action_e == QAction::Hover)
+// emit q->highlighted(action);
+}
+
+
+void QMenuBarPrivate::_q_actionTriggered()
+{
+ Q_Q(QMenuBar);
+ if (QAction *action = qobject_cast<QAction *>(q->sender())) {
+ emit q->triggered(action);
+#ifdef QT3_SUPPORT
+ emit q->activated(q->findIdForAction(action));
+#endif
+ }
+}
+
+void QMenuBarPrivate::_q_actionHovered()
+{
+ Q_Q(QMenuBar);
+ if (QAction *action = qobject_cast<QAction *>(q->sender())) {
+ emit q->hovered(action);
+#ifndef QT_NO_ACCESSIBILITY
+ if (QAccessible::isActive()) {
+ int actionIndex = actions.indexOf(action);
+ ++actionIndex;
+ QAccessible::updateAccessibility(q, actionIndex, QAccessible::Focus);
+ QAccessible::updateAccessibility(q, actionIndex, QAccessible::Selection);
+ }
+#endif //QT_NO_ACCESSIBILITY
+ }
+}
+
+/*!
+ Initialize \a option with the values from the menu bar and information from \a action. This method
+ is useful for subclasses when they need a QStyleOptionMenuItem, but don't want
+ to fill in all the information themselves.
+
+ \sa QStyleOption::initFrom() QMenu::initStyleOption()
+*/
+void QMenuBar::initStyleOption(QStyleOptionMenuItem *option, const QAction *action) const
+{
+ if (!option || !action)
+ return;
+ Q_D(const QMenuBar);
+ option->palette = palette();
+ option->state = QStyle::State_None;
+ if (isEnabled() && action->isEnabled())
+ option->state |= QStyle::State_Enabled;
+ else
+ option->palette.setCurrentColorGroup(QPalette::Disabled);
+ option->fontMetrics = fontMetrics();
+ if (d->currentAction && d->currentAction == action) {
+ option->state |= QStyle::State_Selected;
+ if (d->popupState && !d->closePopupMode)
+ option->state |= QStyle::State_Sunken;
+ }
+ if (hasFocus() || d->currentAction)
+ option->state |= QStyle::State_HasFocus;
+ option->menuRect = rect();
+ option->menuItemType = QStyleOptionMenuItem::Normal;
+ option->checkType = QStyleOptionMenuItem::NotCheckable;
+ option->text = action->text();
+ option->icon = action->icon();
+}
+
+/*!
+ \class QMenuBar
+ \brief The QMenuBar class provides a horizontal menu bar.
+
+ \ingroup mainwindow-classes
+
+ A menu bar consists of a list of pull-down menu items. You add
+ menu items with addMenu(). For example, asuming that \c menubar
+ is a pointer to a QMenuBar and \c fileMenu is a pointer to a
+ QMenu, the following statement inserts the menu into the menu bar:
+ \snippet doc/src/snippets/code/src_gui_widgets_qmenubar.cpp 0
+
+ The ampersand in the menu item's text sets Alt+F as a shortcut for
+ this menu. (You can use "\&\&" to get a real ampersand in the menu
+ bar.)
+
+ There is no need to lay out a menu bar. It automatically sets its
+ own geometry to the top of the parent widget and changes it
+ appropriately whenever the parent is resized.
+
+ \section1 Usage
+
+ In most main window style applications you would use the
+ \l{QMainWindow::}{menuBar()} function provided in QMainWindow,
+ adding \l{QMenu}s to the menu bar and adding \l{QAction}s to the
+ pop-up menus.
+
+ Example (from the \l{mainwindows/menus}{Menus} example):
+
+ \snippet examples/mainwindows/menus/mainwindow.cpp 9
+
+ Menu items may be removed with removeAction().
+
+ Widgets can be added to menus by using instances of the QWidgetAction
+ class to hold them. These actions can then be inserted into menus
+ in the usual way; see the QMenu documentation for more details.
+
+ \section1 Platform Dependent Look and Feel
+
+ Different platforms have different requirements for the appearance
+ of menu bars and their behavior when the user interacts with them.
+ For example, Windows systems are often configured so that the
+ underlined character mnemonics that indicate keyboard shortcuts
+ for items in the menu bar are only shown when the \gui{Alt} key is
+ pressed.
+
+ \table
+
+ \row \o \inlineimage plastique-menubar.png A menu bar shown in the
+ Plastique widget style.
+
+ \o The \l{QPlastiqueStyle}{Plastique widget style}, like most
+ other styles, handles the \gui{Help} menu in the same way as it
+ handles any other menu.
+
+ \row \o \inlineimage motif-menubar.png A menu bar shown in the
+ Motif widget style.
+
+ \o The \l{QMotifStyle}{Motif widget style} treats \gui{Help} menus
+ in a special way, placing them at right-hand end of the menu bar.
+
+ \endtable
+
+ \section1 QMenuBar on Mac OS X
+
+ QMenuBar on Mac OS X is a wrapper for using the system-wide menu bar.
+ If you have multiple menu bars in one dialog the outermost menu bar
+ (normally inside a widget with widget flag Qt::Window) will
+ be used for the system-wide menu bar.
+
+ Qt for Mac OS X also provides a menu bar merging feature to make
+ QMenuBar conform more closely to accepted Mac OS X menu bar layout.
+ The merging functionality is based on string matching the title of
+ a QMenu entry. These strings are translated (using QObject::tr())
+ in the "QMenuBar" context. If an entry is moved its slots will still
+ fire as if it was in the original place. The table below outlines
+ the strings looked for and where the entry is placed if matched:
+
+ \table
+ \header \i String matches \i Placement \i Notes
+ \row \i about.*
+ \i Application Menu | About <application name>
+ \i The application name is fetched from the \c {Info.plist} file
+ (see note below). If this entry is not found no About item
+ will appear in the Application Menu.
+ \row \i config, options, setup, settings or preferences
+ \i Application Menu | Preferences
+ \i If this entry is not found the Settings item will be disabled
+ \row \i quit or exit
+ \i Application Menu | Quit <application name>
+ \i If this entry is not found a default Quit item will be
+ created to call QApplication::quit()
+ \endtable
+
+ You can override this behavior by using the QAction::menuRole()
+ property.
+
+ If you want all windows in a Mac application to share one menu
+ bar, you must create a menu bar that does not have a parent.
+ Create a parent-less menu bar this way:
+
+ \snippet doc/src/snippets/code/src_gui_widgets_qmenubar.cpp 1
+
+ \bold{Note:} Do \e{not} call QMainWindow::menuBar() to create the
+ shared menu bar, because that menu bar will have the QMainWindow
+ as its parent. That menu bar would only be displayed for the
+ parent QMainWindow.
+
+ \bold{Note:} The text used for the application name in the menu
+ bar is obtained from the value set in the \c{Info.plist} file in
+ the application's bundle. See \l{Deploying an Application on
+ Mac OS X} for more information.
+
+ \section1 QMenuBar on Windows CE
+
+ QMenuBar on Windows CE is a wrapper for using the system-wide menu bar,
+ similar to the Mac. This feature is activated for Windows Mobile
+ and integrates QMenuBar with the native soft keys. The left soft
+ key can be controlled with QMenuBar::setDefaultAction() and the
+ right soft key can be used to access the menu bar.
+
+ The hovered() signal is not supported for the native menu
+ integration. Also, it is not possible to display an icon in a
+ native menu on Windows Mobile.
+
+ \section1 Examples
+
+ The \l{mainwindows/menus}{Menus} example shows how to use QMenuBar
+ and QMenu. The other \l{Main Window Examples}{main window
+ application examples} also provide menus using these classes.
+
+ \sa QMenu, QShortcut, QAction,
+ {http://developer.apple.com/documentation/UserExperience/Conceptual/AppleHIGuidelines/XHIGIntro/XHIGIntro.html}{Introduction to Apple Human Interface Guidelines},
+ {fowler}{GUI Design Handbook: Menu Bar}, {Menus Example}
+*/
+
+
+void QMenuBarPrivate::init()
+{
+ Q_Q(QMenuBar);
+ q->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum);
+ q->setAttribute(Qt::WA_CustomWhatsThis);
+
+ platformMenuBar = QGuiApplicationPrivate::platformIntegration()->createPlatformMenuBar(q);
+
+ if (platformMenuBar)
+ q->hide();
+#ifdef Q_WS_WINCE
+ if (qt_wince_is_mobile()) {
+ wceCreateMenuBar(q->parentWidget());
+ if(wce_menubar)
+ q->hide();
+ }
+ else {
+ QApplication::setAttribute(Qt::AA_DontUseNativeMenuBar, true);
+ }
+#endif
+ q->setBackgroundRole(QPalette::Button);
+ oldWindow = oldParent = 0;
+#ifdef QT_SOFTKEYS_ENABLED
+ menuBarAction = 0;
+#endif
+ handleReparent();
+ q->setMouseTracking(q->style()->styleHint(QStyle::SH_MenuBar_MouseTracking, 0, q));
+
+ extension = new QMenuBarExtension(q);
+ extension->setFocusPolicy(Qt::NoFocus);
+ extension->hide();
+}
+
+//Gets the next action for keyboard navigation
+QAction *QMenuBarPrivate::getNextAction(const int _start, const int increment) const
+{
+ Q_Q(const QMenuBar);
+ const_cast<QMenuBarPrivate*>(this)->updateGeometries();
+ bool allowActiveAndDisabled = q->style()->styleHint(QStyle::SH_Menu_AllowActiveAndDisabled, 0, q);
+ const int start = (_start == -1 && increment == -1) ? actions.count() : _start;
+ const int end = increment == -1 ? 0 : actions.count() - 1;
+
+ for (int i = start; i != end;) {
+ i += increment;
+ QAction *current = actions.at(i);
+ if (!actionRects.at(i).isNull() && (allowActiveAndDisabled || current->isEnabled()))
+ return current;
+ }
+
+ if (_start != -1) //let's try from the beginning or the end
+ return getNextAction(-1, increment);
+
+ return 0;
+}
+
+/*!
+ Constructs a menu bar with parent \a parent.
+*/
+QMenuBar::QMenuBar(QWidget *parent) : QWidget(*new QMenuBarPrivate, parent, 0)
+{
+ Q_D(QMenuBar);
+ d->init();
+}
+
+
+/*!
+ Destroys the menu bar.
+*/
+QMenuBar::~QMenuBar()
+{
+ Q_D(QMenuBar);
+ delete d->platformMenuBar;
+ d->platformMenuBar = 0;
+
+#ifdef Q_WS_WINCE
+ Q_D(QMenuBar);
+ if (qt_wince_is_mobile())
+ d->wceDestroyMenuBar();
+#endif
+#ifdef Q_WS_S60
+ Q_D(QMenuBar);
+ d->symbianDestroyMenuBar();
+#endif
+}
+
+/*!
+ \overload
+
+ This convenience function creates a new action with \a text.
+ The function adds the newly created action to the menu's
+ list of actions, and returns it.
+
+ \sa QWidget::addAction(), QWidget::actions()
+*/
+QAction *QMenuBar::addAction(const QString &text)
+{
+ QAction *ret = new QAction(text, this);
+ addAction(ret);
+ return ret;
+}
+
+/*!
+ \overload
+
+ This convenience function creates a new action with the given \a
+ text. The action's triggered() signal is connected to the \a
+ receiver's \a member slot. The function adds the newly created
+ action to the menu's list of actions and returns it.
+
+ \sa QWidget::addAction(), QWidget::actions()
+*/
+QAction *QMenuBar::addAction(const QString &text, const QObject *receiver, const char* member)
+{
+ QAction *ret = new QAction(text, this);
+ QObject::connect(ret, SIGNAL(triggered(bool)), receiver, member);
+ addAction(ret);
+ return ret;
+}
+
+/*!
+ Appends a new QMenu with \a title to the menu bar. The menu bar
+ takes ownership of the menu. Returns the new menu.
+
+ \sa QWidget::addAction() QMenu::menuAction()
+*/
+QMenu *QMenuBar::addMenu(const QString &title)
+{
+ QMenu *menu = new QMenu(title, this);
+ addAction(menu->menuAction());
+ return menu;
+}
+
+/*!
+ Appends a new QMenu with \a icon and \a title to the menu bar. The menu bar
+ takes ownership of the menu. Returns the new menu.
+
+ \sa QWidget::addAction() QMenu::menuAction()
+*/
+QMenu *QMenuBar::addMenu(const QIcon &icon, const QString &title)
+{
+ QMenu *menu = new QMenu(title, this);
+ menu->setIcon(icon);
+ addAction(menu->menuAction());
+ return menu;
+}
+
+/*!
+ Appends \a menu to the menu bar. Returns the menu's menuAction().
+
+ \note The returned QAction object can be used to hide the corresponding
+ menu.
+
+ \sa QWidget::addAction() QMenu::menuAction()
+*/
+QAction *QMenuBar::addMenu(QMenu *menu)
+{
+ QAction *action = menu->menuAction();
+ addAction(action);
+ return action;
+}
+
+/*!
+ Appends a separator to the menu.
+*/
+QAction *QMenuBar::addSeparator()
+{
+ QAction *ret = new QAction(this);
+ ret->setSeparator(true);
+ addAction(ret);
+ return ret;
+}
+
+/*!
+ This convenience function creates a new separator action, i.e. an
+ action with QAction::isSeparator() returning true. The function inserts
+ the newly created action into this menu bar's list of actions before
+ action \a before and returns it.
+
+ \sa QWidget::insertAction(), addSeparator()
+*/
+QAction *QMenuBar::insertSeparator(QAction *before)
+{
+ QAction *action = new QAction(this);
+ action->setSeparator(true);
+ insertAction(before, action);
+ return action;
+}
+
+/*!
+ This convenience function inserts \a menu before action \a before
+ and returns the menus menuAction().
+
+ \sa QWidget::insertAction() addMenu()
+*/
+QAction *QMenuBar::insertMenu(QAction *before, QMenu *menu)
+{
+ QAction *action = menu->menuAction();
+ insertAction(before, action);
+ return action;
+}
+
+/*!
+ Returns the QAction that is currently highlighted. A null pointer
+ will be returned if no action is currently selected.
+*/
+QAction *QMenuBar::activeAction() const
+{
+ Q_D(const QMenuBar);
+ return d->currentAction;
+}
+
+/*!
+ \since 4.1
+
+ Sets the currently highlighted action to \a act.
+*/
+void QMenuBar::setActiveAction(QAction *act)
+{
+ Q_D(QMenuBar);
+ d->setCurrentAction(act, true, false);
+}
+
+
+/*!
+ Removes all the actions from the menu bar.
+
+ \note On Mac OS X, menu items that have been merged to the system
+ menu bar are not removed by this function. One way to handle this
+ would be to remove the extra actions yourself. You can set the
+ \l{QAction::MenuRole}{menu role} on the different menus, so that
+ you know ahead of time which menu items get merged and which do
+ not. Then decide what to recreate or remove yourself.
+
+ \sa removeAction()
+*/
+void QMenuBar::clear()
+{
+ QList<QAction*> acts = actions();
+ for(int i = 0; i < acts.size(); i++)
+ removeAction(acts[i]);
+}
+
+/*!
+ \property QMenuBar::defaultUp
+ \brief the popup orientation
+
+ The default popup orientation. By default, menus pop "down" the
+ screen. By setting the property to true, the menu will pop "up".
+ You might call this for menus that are \e below the document to
+ which they refer.
+
+ If the menu would not fit on the screen, the other direction is
+ used automatically.
+*/
+void QMenuBar::setDefaultUp(bool b)
+{
+ Q_D(QMenuBar);
+ d->defaultPopDown = !b;
+}
+
+bool QMenuBar::isDefaultUp() const
+{
+ Q_D(const QMenuBar);
+ return !d->defaultPopDown;
+}
+
+/*!
+ \reimp
+*/
+void QMenuBar::resizeEvent(QResizeEvent *)
+{
+ Q_D(QMenuBar);
+ d->itemsDirty = true;
+ d->updateGeometries();
+}
+
+/*!
+ \reimp
+*/
+void QMenuBar::paintEvent(QPaintEvent *e)
+{
+ Q_D(QMenuBar);
+ QPainter p(this);
+ QRegion emptyArea(rect());
+
+ //draw the items
+ for (int i = 0; i < d->actions.count(); ++i) {
+ QAction *action = d->actions.at(i);
+ QRect adjustedActionRect = d->actionRect(action);
+ if (adjustedActionRect.isEmpty() || !d->isVisible(action))
+ continue;
+ if(!e->rect().intersects(adjustedActionRect))
+ continue;
+
+ emptyArea -= adjustedActionRect;
+ QStyleOptionMenuItem opt;
+ initStyleOption(&opt, action);
+ opt.rect = adjustedActionRect;
+ p.setClipRect(adjustedActionRect);
+ style()->drawControl(QStyle::CE_MenuBarItem, &opt, &p, this);
+ }
+ //draw border
+ if(int fw = style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, this)) {
+ QRegion borderReg;
+ borderReg += QRect(0, 0, fw, height()); //left
+ borderReg += QRect(width()-fw, 0, fw, height()); //right
+ borderReg += QRect(0, 0, width(), fw); //top
+ borderReg += QRect(0, height()-fw, width(), fw); //bottom
+ p.setClipRegion(borderReg);
+ emptyArea -= borderReg;
+ QStyleOptionFrame frame;
+ frame.rect = rect();
+ frame.palette = palette();
+ frame.state = QStyle::State_None;
+ frame.lineWidth = style()->pixelMetric(QStyle::PM_MenuBarPanelWidth);
+ frame.midLineWidth = 0;
+ style()->drawPrimitive(QStyle::PE_PanelMenuBar, &frame, &p, this);
+ }
+ p.setClipRegion(emptyArea);
+ QStyleOptionMenuItem menuOpt;
+ menuOpt.palette = palette();
+ menuOpt.state = QStyle::State_None;
+ menuOpt.menuItemType = QStyleOptionMenuItem::EmptyArea;
+ menuOpt.checkType = QStyleOptionMenuItem::NotCheckable;
+ menuOpt.rect = rect();
+ menuOpt.menuRect = rect();
+ style()->drawControl(QStyle::CE_MenuBarEmptyArea, &menuOpt, &p, this);
+}
+
+/*!
+ \reimp
+*/
+void QMenuBar::setVisible(bool visible)
+{
+#if defined(Q_OS_MAC) || defined(Q_OS_WINCE) || defined(Q_WS_S60)
+ if (isNativeMenuBar()) {
+ if (!visible)
+ QWidget::setVisible(false);
+ return;
+ }
+#endif
+ QWidget::setVisible(visible);
+}
+
+/*!
+ \reimp
+*/
+void QMenuBar::mousePressEvent(QMouseEvent *e)
+{
+ Q_D(QMenuBar);
+ if(e->button() != Qt::LeftButton)
+ return;
+
+ d->mouseDown = true;
+
+ QAction *action = d->actionAt(e->pos());
+ if (!action || !d->isVisible(action)) {
+ d->setCurrentAction(0);
+#ifndef QT_NO_WHATSTHIS
+ if (QWhatsThis::inWhatsThisMode())
+ QWhatsThis::showText(e->globalPos(), d->whatsThis, this);
+#endif
+ return;
+ }
+
+ if(d->currentAction == action && d->popupState) {
+ if(QMenu *menu = d->activeMenu) {
+ d->activeMenu = 0;
+ menu->hide();
+ }
+#ifdef Q_WS_WIN
+ if((d->closePopupMode = style()->styleHint(QStyle::SH_MenuBar_DismissOnSecondClick)))
+ update(d->actionRect(action));
+#endif
+ } else {
+ d->setCurrentAction(action, true);
+ }
+}
+
+/*!
+ \reimp
+*/
+void QMenuBar::mouseReleaseEvent(QMouseEvent *e)
+{
+ Q_D(QMenuBar);
+ if(e->button() != Qt::LeftButton || !d->mouseDown)
+ return;
+
+ d->mouseDown = false;
+ QAction *action = d->actionAt(e->pos());
+ if((d->closePopupMode && action == d->currentAction) || !action || !action->menu()) {
+ //we set the current action before activating
+ //so that we let the leave event set the current back to 0
+ d->setCurrentAction(action, false);
+ if(action)
+ d->activateAction(action, QAction::Trigger);
+ }
+ d->closePopupMode = 0;
+}
+
+/*!
+ \reimp
+*/
+void QMenuBar::keyPressEvent(QKeyEvent *e)
+{
+ Q_D(QMenuBar);
+ d->updateGeometries();
+ int key = e->key();
+ if(isRightToLeft()) { // in reverse mode open/close key for submenues are reversed
+ if(key == Qt::Key_Left)
+ key = Qt::Key_Right;
+ else if(key == Qt::Key_Right)
+ key = Qt::Key_Left;
+ }
+ if(key == Qt::Key_Tab) //means right
+ key = Qt::Key_Right;
+ else if(key == Qt::Key_Backtab) //means left
+ key = Qt::Key_Left;
+
+ bool key_consumed = false;
+ switch(key) {
+ case Qt::Key_Up:
+ case Qt::Key_Down:
+ case Qt::Key_Enter:
+ case Qt::Key_Space:
+ case Qt::Key_Return: {
+ if(!style()->styleHint(QStyle::SH_MenuBar_AltKeyNavigation, 0, this) || !d->currentAction)
+ break;
+ if(d->currentAction->menu()) {
+ d->popupAction(d->currentAction, true);
+ } else if(key == Qt::Key_Enter || key == Qt::Key_Return || key == Qt::Key_Space) {
+ d->activateAction(d->currentAction, QAction::Trigger);
+ d->setCurrentAction(d->currentAction, false);
+ d->setKeyboardMode(false);
+ }
+ key_consumed = true;
+ break; }
+
+ case Qt::Key_Right:
+ case Qt::Key_Left: {
+ if(d->currentAction) {
+ int index = d->actions.indexOf(d->currentAction);
+ if (QAction *nextAction = d->getNextAction(index, key == Qt::Key_Left ? -1 : +1)) {
+ d->setCurrentAction(nextAction, d->popupState, true);
+ key_consumed = true;
+ }
+ }
+ break; }
+
+ case Qt::Key_Escape:
+ d->setCurrentAction(0);
+ d->setKeyboardMode(false);
+ key_consumed = true;
+ break;
+
+ default:
+ key_consumed = false;
+ }
+
+ if(!key_consumed &&
+ (!e->modifiers() ||
+ (e->modifiers()&(Qt::MetaModifier|Qt::AltModifier))) && e->text().length()==1 && !d->popupState) {
+ int clashCount = 0;
+ QAction *first = 0, *currentSelected = 0, *firstAfterCurrent = 0;
+ {
+ QChar c = e->text()[0].toUpper();
+ for(int i = 0; i < d->actions.size(); ++i) {
+ if (d->actionRects.at(i).isNull())
+ continue;
+ QAction *act = d->actions.at(i);
+ QString s = act->text();
+ if(!s.isEmpty()) {
+ int ampersand = s.indexOf(QLatin1Char('&'));
+ if(ampersand >= 0) {
+ if(s[ampersand+1].toUpper() == c) {
+ clashCount++;
+ if(!first)
+ first = act;
+ if(act == d->currentAction)
+ currentSelected = act;
+ else if (!firstAfterCurrent && currentSelected)
+ firstAfterCurrent = act;
+ }
+ }
+ }
+ }
+ }
+ QAction *next_action = 0;
+ if(clashCount >= 1) {
+ if(clashCount == 1 || !d->currentAction || (currentSelected && !firstAfterCurrent))
+ next_action = first;
+ else
+ next_action = firstAfterCurrent;
+ }
+ if(next_action) {
+ key_consumed = true;
+ d->setCurrentAction(next_action, true, true);
+ }
+ }
+ if(key_consumed)
+ e->accept();
+ else
+ e->ignore();
+}
+
+/*!
+ \reimp
+*/
+void QMenuBar::mouseMoveEvent(QMouseEvent *e)
+{
+ Q_D(QMenuBar);
+ if (!(e->buttons() & Qt::LeftButton))
+ d->mouseDown = false;
+ bool popupState = d->popupState || d->mouseDown;
+ QAction *action = d->actionAt(e->pos());
+ if ((action && d->isVisible(action)) || !popupState)
+ d->setCurrentAction(action, popupState);
+}
+
+/*!
+ \reimp
+*/
+void QMenuBar::leaveEvent(QEvent *)
+{
+ Q_D(QMenuBar);
+ if((!hasFocus() && !d->popupState) ||
+ (d->currentAction && d->currentAction->menu() == 0))
+ d->setCurrentAction(0);
+}
+
+/*!
+ \reimp
+*/
+void QMenuBar::actionEvent(QActionEvent *e)
+{
+ Q_D(QMenuBar);
+ d->itemsDirty = true;
+
+ if (d->platformMenuBar) {
+ QPlatformMenuBar *nativeMenuBar = d->platformMenuBar;
+#if defined(Q_WS_S60)
+ QMenuBarPrivate::QSymbianMenuBarPrivate *nativeMenuBar = d->symbian_menubar;
+#elif defined(Q_WS_WINCE)
+ QMenuBarPrivate::QWceMenuBarPrivate *nativeMenuBar = d->wce_menubar;
+#endif
+ if (!nativeMenuBar)
+ return;
+ if(e->type() == QEvent::ActionAdded)
+ nativeMenuBar->addAction(e->action(), e->before());
+ else if(e->type() == QEvent::ActionRemoved)
+ nativeMenuBar->removeAction(e->action());
+ else if(e->type() == QEvent::ActionChanged)
+ nativeMenuBar->syncAction(e->action());
+ }
+
+ if(e->type() == QEvent::ActionAdded) {
+ connect(e->action(), SIGNAL(triggered()), this, SLOT(_q_actionTriggered()));
+ connect(e->action(), SIGNAL(hovered()), this, SLOT(_q_actionHovered()));
+ } else if(e->type() == QEvent::ActionRemoved) {
+ e->action()->disconnect(this);
+ }
+ if (isVisible()) {
+ d->updateGeometries();
+ update();
+ }
+}
+
+/*!
+ \reimp
+*/
+void QMenuBar::focusInEvent(QFocusEvent *)
+{
+ Q_D(QMenuBar);
+ if(d->keyboardState)
+ d->focusFirstAction();
+}
+
+/*!
+ \reimp
+*/
+void QMenuBar::focusOutEvent(QFocusEvent *)
+{
+ Q_D(QMenuBar);
+ if(!d->popupState) {
+ d->setCurrentAction(0);
+ d->setKeyboardMode(false);
+ }
+}
+
+/*!
+ \reimp
+ */
+void QMenuBar::timerEvent (QTimerEvent *e)
+{
+ Q_D(QMenuBar);
+ if (e->timerId() == d->autoReleaseTimer.timerId()) {
+ d->autoReleaseTimer.stop();
+ d->setCurrentAction(0);
+ }
+ QWidget::timerEvent(e);
+}
+
+
+void QMenuBarPrivate::handleReparent()
+{
+ Q_Q(QMenuBar);
+ QWidget *newParent = q->parentWidget();
+ //Note: if parent is reparented, then window may change even if parent doesn't
+
+ // we need to install an event filter on parent, and remove the old one
+
+ if (oldParent != newParent) {
+ if (oldParent)
+ oldParent->removeEventFilter(q);
+ if (newParent)
+ newParent->installEventFilter(q);
+ }
+
+ //we also need event filter on top-level (for shortcuts)
+ QWidget *newWindow = newParent ? newParent->window() : 0;
+
+ if (oldWindow != newWindow) {
+ if (oldParent && oldParent != oldWindow)
+ oldWindow->removeEventFilter(q);
+
+ if (newParent && newParent != newWindow)
+ newWindow->installEventFilter(q);
+ }
+
+ oldParent = newParent;
+ oldWindow = newWindow;
+
+ if (platformMenuBar)
+ platformMenuBar->handleReparent(newParent);
+
+#ifdef Q_WS_WINCE
+ if (qt_wince_is_mobile() && wce_menubar)
+ wce_menubar->rebuild();
+#endif
+#ifdef Q_WS_S60
+
+ // Construct symbian_menubar when this code path is entered first time
+ // and when newParent != NULL
+ if (!symbian_menubar)
+ symbianCreateMenuBar(newParent);
+
+ // Reparent and rebuild menubar when parent is changed
+ if (symbian_menubar) {
+ if (oldParent != newParent)
+ reparentMenuBar(oldParent, newParent);
+ q->hide();
+ symbian_menubar->rebuild();
+ }
+
+#ifdef QT_SOFTKEYS_ENABLED
+ // Constuct menuBarAction when this code path is entered first time
+ if (!menuBarAction) {
+ if (newParent) {
+ menuBarAction = QSoftKeyManager::createAction(QSoftKeyManager::MenuSoftKey, newParent);
+ newParent->addAction(menuBarAction);
+ }
+ } else {
+ // If reparenting i.e. we already have menuBarAction, remove it from old parent
+ // and add for a new parent
+ if (oldParent)
+ oldParent->removeAction(menuBarAction);
+ if (newParent)
+ newParent->addAction(menuBarAction);
+ }
+#endif // QT_SOFTKEYS_ENABLED
+#endif // Q_WS_S60
+}
+
+/*!
+ \reimp
+*/
+void QMenuBar::changeEvent(QEvent *e)
+{
+ Q_D(QMenuBar);
+ if(e->type() == QEvent::StyleChange) {
+ d->itemsDirty = true;
+ setMouseTracking(style()->styleHint(QStyle::SH_MenuBar_MouseTracking, 0, this));
+ if(parentWidget())
+ resize(parentWidget()->width(), heightForWidth(parentWidget()->width()));
+ d->updateGeometries();
+ } else if (e->type() == QEvent::ParentChange) {
+ d->handleReparent();
+ } else if (e->type() == QEvent::FontChange
+ || e->type() == QEvent::ApplicationFontChange) {
+ d->itemsDirty = true;
+ d->updateGeometries();
+#ifdef QT_SOFTKEYS_ENABLED
+ } else if (e->type() == QEvent::LanguageChange) {
+ if (d->menuBarAction)
+ d->menuBarAction->setText(QSoftKeyManager::standardSoftKeyText(QSoftKeyManager::MenuSoftKey));
+#endif
+ }
+
+ QWidget::changeEvent(e);
+}
+
+/*!
+ \reimp
+*/
+bool QMenuBar::event(QEvent *e)
+{
+ Q_D(QMenuBar);
+ switch (e->type()) {
+ case QEvent::KeyPress: {
+ QKeyEvent *ke = (QKeyEvent*)e;
+#if 0
+ if(!d->keyboardState) { //all keypresses..
+ d->setCurrentAction(0);
+ return ;
+ }
+#endif
+ if(ke->key() == Qt::Key_Tab || ke->key() == Qt::Key_Backtab) {
+ keyPressEvent(ke);
+ return true;
+ }
+
+ } break;
+#ifndef QT_NO_SHORTCUT
+ case QEvent::Shortcut: {
+ QShortcutEvent *se = static_cast<QShortcutEvent *>(e);
+ int shortcutId = se->shortcutId();
+ for(int j = 0; j < d->shortcutIndexMap.size(); ++j) {
+ if (shortcutId == d->shortcutIndexMap.value(j))
+ d->_q_internalShortcutActivated(j);
+ }
+ } break;
+#endif
+ case QEvent::Show:
+ d->_q_updateLayout();
+ break;
+ case QEvent::ShortcutOverride: {
+ QKeyEvent *kev = static_cast<QKeyEvent*>(e);
+ //we only filter out escape if there is a current action
+ if (kev->key() == Qt::Key_Escape && d->currentAction) {
+ e->accept();
+ return true;
+ }
+ }
+ break;
+
+
+#ifndef QT_NO_WHATSTHIS
+ case QEvent::QueryWhatsThis:
+ e->setAccepted(d->whatsThis.size());
+ if (QAction *action = d->actionAt(static_cast<QHelpEvent*>(e)->pos())) {
+ if (action->whatsThis().size() || action->menu())
+ e->accept();
+ }
+ return true;
+#endif
+ case QEvent::LayoutDirectionChange:
+ d->_q_updateLayout();
+ break;
+ default:
+ break;
+ }
+ return QWidget::event(e);
+}
+
+/*!
+ \reimp
+*/
+bool QMenuBar::eventFilter(QObject *object, QEvent *event)
+{
+ Q_D(QMenuBar);
+ if (object == parent() && object) {
+ if (event->type() == QEvent::ParentChange) //GrandparentChange
+ d->handleReparent();
+ }
+ if (object == d->leftWidget || object == d->rightWidget) {
+ switch (event->type()) {
+ case QEvent::ShowToParent:
+ case QEvent::HideToParent:
+ d->_q_updateLayout();
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (style()->styleHint(QStyle::SH_MenuBar_AltKeyNavigation, 0, this)) {
+ if (d->altPressed) {
+ switch (event->type()) {
+ case QEvent::KeyPress:
+ case QEvent::KeyRelease:
+ {
+ QKeyEvent *kev = static_cast<QKeyEvent*>(event);
+ if (kev->key() == Qt::Key_Alt || kev->key() == Qt::Key_Meta) {
+ if (event->type() == QEvent::KeyPress) // Alt-press does not interest us, we have the shortcut-override event
+ break;
+ d->setKeyboardMode(!d->keyboardState);
+ }
+ }
+ // fall through
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseMove:
+ case QEvent::FocusIn:
+ case QEvent::FocusOut:
+ case QEvent::ActivationChange:
+ d->altPressed = false;
+ qApp->removeEventFilter(this);
+ break;
+ default:
+ break;
+ }
+ } else if (isVisible()) {
+ if (event->type() == QEvent::ShortcutOverride) {
+ QKeyEvent *kev = static_cast<QKeyEvent*>(event);
+ if ((kev->key() == Qt::Key_Alt || kev->key() == Qt::Key_Meta)
+ && kev->modifiers() == Qt::AltModifier) {
+ d->altPressed = true;
+ qApp->installEventFilter(this);
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+/*!
+ Returns the QAction at \a pt. Returns 0 if there is no action at \a pt or if
+the location has a separator.
+
+ \sa addAction(), addSeparator()
+*/
+QAction *QMenuBar::actionAt(const QPoint &pt) const
+{
+ Q_D(const QMenuBar);
+ return d->actionAt(pt);
+}
+
+/*!
+ Returns the geometry of action \a act as a QRect.
+
+ \sa actionAt()
+*/
+QRect QMenuBar::actionGeometry(QAction *act) const
+{
+ Q_D(const QMenuBar);
+ return d->actionRect(act);
+}
+
+/*!
+ \reimp
+*/
+QSize QMenuBar::minimumSizeHint() const
+{
+ Q_D(const QMenuBar);
+#if defined(Q_OS_MAC) || defined(Q_WS_WINCE) || defined(Q_WS_S60)
+ const bool as_gui_menubar = !isNativeMenuBar();
+#else
+ const bool as_gui_menubar = true;
+#endif
+
+ ensurePolished();
+ QSize ret(0, 0);
+ const_cast<QMenuBarPrivate*>(d)->updateGeometries();
+ const int hmargin = style()->pixelMetric(QStyle::PM_MenuBarHMargin, 0, this);
+ const int vmargin = style()->pixelMetric(QStyle::PM_MenuBarVMargin, 0, this);
+ int fw = style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, this);
+ int spaceBelowMenuBar = style()->styleHint(QStyle::SH_MainWindow_SpaceBelowMenuBar, 0, this);
+ if(as_gui_menubar) {
+ int w = parentWidget() ? parentWidget()->width() : QApplication::desktop()->width();
+ d->calcActionRects(w - (2 * fw), 0);
+ for (int i = 0; ret.isNull() && i < d->actions.count(); ++i)
+ ret = d->actionRects.at(i).size();
+ if (!d->extension->isHidden())
+ ret += QSize(d->extension->sizeHint().width(), 0);
+ ret += QSize(2*fw + hmargin, 2*fw + vmargin);
+ }
+ int margin = 2*vmargin + 2*fw + spaceBelowMenuBar;
+ if(d->leftWidget) {
+ QSize sz = d->leftWidget->minimumSizeHint();
+ ret.setWidth(ret.width() + sz.width());
+ if(sz.height() + margin > ret.height())
+ ret.setHeight(sz.height() + margin);
+ }
+ if(d->rightWidget) {
+ QSize sz = d->rightWidget->minimumSizeHint();
+ ret.setWidth(ret.width() + sz.width());
+ if(sz.height() + margin > ret.height())
+ ret.setHeight(sz.height() + margin);
+ }
+ if(as_gui_menubar) {
+ QStyleOptionMenuItem opt;
+ opt.rect = rect();
+ opt.menuRect = rect();
+ opt.state = QStyle::State_None;
+ opt.menuItemType = QStyleOptionMenuItem::Normal;
+ opt.checkType = QStyleOptionMenuItem::NotCheckable;
+ opt.palette = palette();
+ return (style()->sizeFromContents(QStyle::CT_MenuBar, &opt,
+ ret.expandedTo(QApplication::globalStrut()),
+ this));
+ }
+ return ret;
+}
+
+/*!
+ \reimp
+*/
+QSize QMenuBar::sizeHint() const
+{
+ Q_D(const QMenuBar);
+#if defined(Q_OS_MAC) || defined(Q_WS_WINCE) || defined(Q_WS_S60)
+ const bool as_gui_menubar = !isNativeMenuBar();
+#else
+ const bool as_gui_menubar = true;
+#endif
+
+
+ ensurePolished();
+ QSize ret(0, 0);
+ const_cast<QMenuBarPrivate*>(d)->updateGeometries();
+ const int hmargin = style()->pixelMetric(QStyle::PM_MenuBarHMargin, 0, this);
+ const int vmargin = style()->pixelMetric(QStyle::PM_MenuBarVMargin, 0, this);
+ int fw = style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, this);
+ int spaceBelowMenuBar = style()->styleHint(QStyle::SH_MainWindow_SpaceBelowMenuBar, 0, this);
+ if(as_gui_menubar) {
+ const int w = parentWidget() ? parentWidget()->width() : QApplication::desktop()->width();
+ d->calcActionRects(w - (2 * fw), 0);
+ for (int i = 0; i < d->actionRects.count(); ++i) {
+ const QRect &actionRect = d->actionRects.at(i);
+ ret = ret.expandedTo(QSize(actionRect.x() + actionRect.width(), actionRect.y() + actionRect.height()));
+ }
+ //the action geometries already contain the top and left
+ //margins. So we only need to add those from right and bottom.
+ ret += QSize(fw + hmargin, fw + vmargin);
+ }
+ int margin = 2*vmargin + 2*fw + spaceBelowMenuBar;
+ if(d->leftWidget) {
+ QSize sz = d->leftWidget->sizeHint();
+ ret.setWidth(ret.width() + sz.width());
+ if(sz.height() + margin > ret.height())
+ ret.setHeight(sz.height() + margin);
+ }
+ if(d->rightWidget) {
+ QSize sz = d->rightWidget->sizeHint();
+ ret.setWidth(ret.width() + sz.width());
+ if(sz.height() + margin > ret.height())
+ ret.setHeight(sz.height() + margin);
+ }
+ if(as_gui_menubar) {
+ QStyleOptionMenuItem opt;
+ opt.rect = rect();
+ opt.menuRect = rect();
+ opt.state = QStyle::State_None;
+ opt.menuItemType = QStyleOptionMenuItem::Normal;
+ opt.checkType = QStyleOptionMenuItem::NotCheckable;
+ opt.palette = palette();
+ return (style()->sizeFromContents(QStyle::CT_MenuBar, &opt,
+ ret.expandedTo(QApplication::globalStrut()),
+ this));
+ }
+ return ret;
+}
+
+/*!
+ \reimp
+*/
+int QMenuBar::heightForWidth(int) const
+{
+ Q_D(const QMenuBar);
+#if defined(Q_OS_MAC) || defined(Q_WS_WINCE) || defined(Q_WS_S60)
+ const bool as_gui_menubar = !isNativeMenuBar();
+#else
+ const bool as_gui_menubar = true;
+#endif
+
+ const_cast<QMenuBarPrivate*>(d)->updateGeometries();
+ int height = 0;
+ const int vmargin = style()->pixelMetric(QStyle::PM_MenuBarVMargin, 0, this);
+ int fw = style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, this);
+ int spaceBelowMenuBar = style()->styleHint(QStyle::SH_MainWindow_SpaceBelowMenuBar, 0, this);
+ if(as_gui_menubar) {
+ for (int i = 0; i < d->actionRects.count(); ++i)
+ height = qMax(height, d->actionRects.at(i).height());
+ if (height) //there is at least one non-null item
+ height += spaceBelowMenuBar;
+ height += 2*fw;
+ height += 2*vmargin;
+ }
+ int margin = 2*vmargin + 2*fw + spaceBelowMenuBar;
+ if(d->leftWidget)
+ height = qMax(d->leftWidget->sizeHint().height() + margin, height);
+ if(d->rightWidget)
+ height = qMax(d->rightWidget->sizeHint().height() + margin, height);
+ if(as_gui_menubar) {
+ QStyleOptionMenuItem opt;
+ opt.init(this);
+ opt.menuRect = rect();
+ opt.state = QStyle::State_None;
+ opt.menuItemType = QStyleOptionMenuItem::Normal;
+ opt.checkType = QStyleOptionMenuItem::NotCheckable;
+ return style()->sizeFromContents(QStyle::CT_MenuBar, &opt, QSize(0, height), this).height(); //not pretty..
+ }
+ return height;
+}
+
+/*!
+ \internal
+*/
+void QMenuBarPrivate::_q_internalShortcutActivated(int id)
+{
+ Q_Q(QMenuBar);
+ QAction *act = actions.at(id);
+ setCurrentAction(act, true, true);
+ if (act && !act->menu()) {
+ activateAction(act, QAction::Trigger);
+ //100 is the same as the default value in QPushButton::animateClick
+ autoReleaseTimer.start(100, q);
+ } else if (act && q->style()->styleHint(QStyle::SH_MenuBar_AltKeyNavigation, 0, q)) {
+ // When we open a menu using a shortcut, we should end up in keyboard state
+ setKeyboardMode(true);
+ }
+}
+
+void QMenuBarPrivate::_q_updateLayout()
+{
+ Q_Q(QMenuBar);
+ itemsDirty = true;
+ if (q->isVisible()) {
+ updateGeometries();
+ q->update();
+ }
+}
+
+/*!
+ \fn void QMenuBar::setCornerWidget(QWidget *widget, Qt::Corner corner)
+
+ This sets the given \a widget to be shown directly on the left of the first
+ menu item, or on the right of the last menu item, depending on \a corner.
+
+ The menu bar takes ownership of \a widget, reparenting it into the menu bar.
+ However, if the \a corner already contains a widget, this previous widget
+ will no longer be managed and will still be a visible child of the menu bar.
+
+ \note Using a corner other than Qt::TopRightCorner or Qt::TopLeftCorner
+ will result in a warning.
+*/
+void QMenuBar::setCornerWidget(QWidget *w, Qt::Corner corner)
+{
+ Q_D(QMenuBar);
+ switch (corner) {
+ case Qt::TopLeftCorner:
+ if (d->leftWidget)
+ d->leftWidget->removeEventFilter(this);
+ d->leftWidget = w;
+ break;
+ case Qt::TopRightCorner:
+ if (d->rightWidget)
+ d->rightWidget->removeEventFilter(this);
+ d->rightWidget = w;
+ break;
+ default:
+ qWarning("QMenuBar::setCornerWidget: Only TopLeftCorner and TopRightCorner are supported");
+ return;
+ }
+
+ if (w) {
+ w->setParent(this);
+ w->installEventFilter(this);
+ }
+
+ d->_q_updateLayout();
+}
+
+/*!
+ Returns the widget on the left of the first or on the right of the last menu
+ item, depending on \a corner.
+
+ \note Using a corner other than Qt::TopRightCorner or Qt::TopLeftCorner
+ will result in a warning.
+*/
+QWidget *QMenuBar::cornerWidget(Qt::Corner corner) const
+{
+ Q_D(const QMenuBar);
+ QWidget *w = 0;
+ switch(corner) {
+ case Qt::TopLeftCorner:
+ w = d->leftWidget;
+ break;
+ case Qt::TopRightCorner:
+ w = d->rightWidget;
+ break;
+ default:
+ qWarning("QMenuBar::cornerWidget: Only TopLeftCorner and TopRightCorner are supported");
+ break;
+ }
+
+ return w;
+}
+
+/*!
+ \property QMenuBar::nativeMenuBar
+ \brief Whether or not a menubar will be used as a native menubar on platforms that support it
+ \since 4.6
+
+ This property specifies whether or not the menubar should be used as a native menubar on platforms
+ that support it. The currently supported platforms are Mac OS X and Windows CE. On these platforms
+ if this property is true, the menubar is used in the native menubar and is not in the window of
+ its parent, if false the menubar remains in the window. On other platforms the value of this
+ attribute has no effect.
+
+ The default is to follow whether the Qt::AA_DontUseNativeMenuBar attribute
+ is set for the application. Explicitly settings this property overrides
+ the presence (or abscence) of the attribute.
+*/
+
+void QMenuBar::setNativeMenuBar(bool nativeMenuBar)
+{
+ Q_D(QMenuBar);
+ if (d->nativeMenuBar == -1 || (nativeMenuBar != bool(d->nativeMenuBar))) {
+ d->nativeMenuBar = nativeMenuBar;
+
+ if (!d->nativeMenuBar) {
+ delete d->platformMenuBar;
+ d->platformMenuBar = 0;
+ } else {
+ if (!d->platformMenuBar)
+ d->platformMenuBar = QGuiApplicationPrivate::platformIntegration()->createPlatformMenuBar(this);
+ }
+
+ updateGeometry();
+ if (!d->nativeMenuBar && parentWidget())
+ setVisible(true);
+ }
+}
+
+bool QMenuBar::isNativeMenuBar() const
+{
+ Q_D(const QMenuBar);
+ if (d->nativeMenuBar == -1) {
+ return !QApplication::instance()->testAttribute(Qt::AA_DontUseNativeMenuBar);
+ }
+ return d->nativeMenuBar;
+}
+
+QPlatformMenuBar *QMenuBar::platformMenuBar()
+{
+ Q_D(const QMenuBar);
+ return d->platformMenuBar;
+}
+
+/*!
+ \since 4.4
+
+ Sets the default action to \a act.
+
+ The default action is assigned to the left soft key. The menu is assigned
+ to the right soft key.
+
+ Currently there is only support for the default action on Windows
+ Mobile. On all other platforms this method is not available.
+
+ \sa defaultAction()
+*/
+
+#ifdef Q_WS_WINCE
+void QMenuBar::setDefaultAction(QAction *act)
+{
+ Q_D(QMenuBar);
+ if (d->defaultAction == act)
+ return;
+#ifdef Q_WS_WINCE
+ if (qt_wince_is_mobile())
+ if (d->defaultAction) {
+ disconnect(d->defaultAction, SIGNAL(changed()), this, SLOT(_q_updateDefaultAction()));
+ disconnect(d->defaultAction, SIGNAL(destroyed()), this, SLOT(_q_updateDefaultAction()));
+ }
+#endif
+ d->defaultAction = act;
+#ifdef Q_WS_WINCE
+ if (qt_wince_is_mobile())
+ if (d->defaultAction) {
+ connect(d->defaultAction, SIGNAL(changed()), this, SLOT(_q_updateDefaultAction()));
+ connect(d->defaultAction, SIGNAL(destroyed()), this, SLOT(_q_updateDefaultAction()));
+ }
+ if (d->wce_menubar) {
+ d->wce_menubar->rebuild();
+ }
+#endif
+}
+
+/*!
+ \since 4.4
+
+ Returns the current default action.
+
+ \sa setDefaultAction()
+*/
+QAction *QMenuBar::defaultAction() const
+{
+ return d_func()->defaultAction;
+}
+#endif
+
+/*!
+ \fn void QMenuBar::triggered(QAction *action)
+
+ This signal is emitted when an action in a menu belonging to this menubar
+ is triggered as a result of a mouse click; \a action is the action that
+ caused the signal to be emitted.
+
+ Normally, you connect each menu action to a single slot using
+ QAction::triggered(), but sometimes you will want to connect
+ several items to a single slot (most often if the user selects
+ from an array). This signal is useful in such cases.
+
+ \sa hovered(), QAction::triggered()
+*/
+
+/*!
+ \fn void QMenuBar::hovered(QAction *action)
+
+ This signal is emitted when a menu action is highlighted; \a action
+ is the action that caused the event to be sent.
+
+ Often this is used to update status information.
+
+ \sa triggered(), QAction::hovered()
+*/
+
+/*!
+ \enum QMenuBar::Separator
+
+ \compat
+
+ \value Never
+ \value InWindowsStyle
+
+*/
+
+/*!
+ \fn void QMenuBar::addAction(QAction *action)
+ \overload
+
+ Appends the action \a action to the menu bar's list of actions.
+
+ \sa QMenu::addAction(), QWidget::addAction(), QWidget::actions()
+*/
+
+/*!
+ \fn void QMenuBar::setFrameRect(QRect)
+ \internal
+*/
+
+/*!
+ \fn QRect QMenuBar::frameRect() const
+ \internal
+*/
+/*!
+ \enum QMenuBar::DummyFrame
+ \internal
+
+ \value Box
+ \value Sunken
+ \value Plain
+ \value Raised
+ \value MShadow
+ \value NoFrame
+ \value Panel
+ \value StyledPanel
+ \value HLine
+ \value VLine
+ \value GroupBoxPanel
+ \value WinPanel
+ \value ToolBarPanel
+ \value MenuBarPanel
+ \value PopupPanel
+ \value LineEditPanel
+ \value TabWidgetPanel
+ \value MShape
+*/
+
+/*!
+ \fn void QMenuBar::setFrameShadow(DummyFrame)
+ \internal
+*/
+
+/*!
+ \fn DummyFrame QMenuBar::frameShadow() const
+ \internal
+*/
+
+/*!
+ \fn void QMenuBar::setFrameShape(DummyFrame)
+ \internal
+*/
+
+/*!
+ \fn DummyFrame QMenuBar::frameShape() const
+ \internal
+*/
+
+/*!
+ \fn void QMenuBar::setFrameStyle(int)
+ \internal
+*/
+
+/*!
+ \fn int QMenuBar::frameStyle() const
+ \internal
+*/
+
+/*!
+ \fn void QMenuBar::setLineWidth(int)
+ \internal
+*/
+
+/*!
+ \fn int QMenuBar::lineWidth() const
+ \internal
+*/
+
+/*!
+ \fn void QMenuBar::setMidLineWidth(int)
+ \internal
+*/
+
+/*!
+ \fn int QMenuBar::midLineWidth() const
+ \internal
+*/
+
+// for private slots
+
+
+QT_END_NAMESPACE
+
+#include <moc_qmenubar.cpp>
+
+#endif // QT_NO_MENUBAR
diff --git a/src/widgets/widgets/qmenubar.h b/src/widgets/widgets/qmenubar.h
new file mode 100644
index 0000000000..b165ec78f3
--- /dev/null
+++ b/src/widgets/widgets/qmenubar.h
@@ -0,0 +1,177 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMENUBAR_H
+#define QMENUBAR_H
+
+#include <QtWidgets/qmenu.h>
+#ifdef Q_OS_MAC
+#include "QtWidgets/qmacdefines_mac.h"
+#endif
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_MENUBAR
+
+class QMenuBarPrivate;
+class QStyleOptionMenuItem;
+class QWindowsStyle;
+#ifdef QT3_SUPPORT
+class QMenuItem;
+#endif
+
+class Q_WIDGETS_EXPORT QMenuBar : public QWidget
+{
+ Q_OBJECT
+
+ Q_PROPERTY(bool defaultUp READ isDefaultUp WRITE setDefaultUp)
+ Q_PROPERTY(bool nativeMenuBar READ isNativeMenuBar WRITE setNativeMenuBar)
+
+public:
+ explicit QMenuBar(QWidget *parent = 0);
+ ~QMenuBar();
+
+#ifdef Q_NO_USING_KEYWORD
+ void addAction(QAction *action) { QWidget::addAction(action); }
+#else
+ using QWidget::addAction;
+#endif
+ QAction *addAction(const QString &text);
+ QAction *addAction(const QString &text, const QObject *receiver, const char* member);
+
+ QAction *addMenu(QMenu *menu);
+ QMenu *addMenu(const QString &title);
+ QMenu *addMenu(const QIcon &icon, const QString &title);
+
+
+ QAction *addSeparator();
+ QAction *insertSeparator(QAction *before);
+
+ QAction *insertMenu(QAction *before, QMenu *menu);
+
+ void clear();
+
+ QAction *activeAction() const;
+ void setActiveAction(QAction *action);
+
+ void setDefaultUp(bool);
+ bool isDefaultUp() const;
+
+ QSize sizeHint() const;
+ QSize minimumSizeHint() const;
+ int heightForWidth(int) const;
+
+ QRect actionGeometry(QAction *) const;
+ QAction *actionAt(const QPoint &) const;
+
+ void setCornerWidget(QWidget *w, Qt::Corner corner = Qt::TopRightCorner);
+ QWidget *cornerWidget(Qt::Corner corner = Qt::TopRightCorner) const;
+
+#ifdef Q_WS_WINCE
+ void setDefaultAction(QAction *);
+ QAction *defaultAction() const;
+
+ static void wceCommands(uint command);
+ static void wceRefresh();
+#endif
+
+ bool isNativeMenuBar() const;
+ void setNativeMenuBar(bool nativeMenuBar);
+ QPlatformMenuBar *platformMenuBar();
+public Q_SLOTS:
+ virtual void setVisible(bool visible);
+
+Q_SIGNALS:
+ void triggered(QAction *action);
+ void hovered(QAction *action);
+
+protected:
+ void changeEvent(QEvent *);
+ void keyPressEvent(QKeyEvent *);
+ void mouseReleaseEvent(QMouseEvent *);
+ void mousePressEvent(QMouseEvent *);
+ void mouseMoveEvent(QMouseEvent *);
+ void leaveEvent(QEvent *);
+ void paintEvent(QPaintEvent *);
+ void resizeEvent(QResizeEvent *);
+ void actionEvent(QActionEvent *);
+ void focusOutEvent(QFocusEvent *);
+ void focusInEvent(QFocusEvent *);
+ void timerEvent(QTimerEvent *);
+ bool eventFilter(QObject *, QEvent *);
+ bool event(QEvent *);
+ void initStyleOption(QStyleOptionMenuItem *option, const QAction *action) const;
+
+private:
+ Q_DECLARE_PRIVATE(QMenuBar)
+ Q_DISABLE_COPY(QMenuBar)
+ Q_PRIVATE_SLOT(d_func(), void _q_actionTriggered())
+ Q_PRIVATE_SLOT(d_func(), void _q_actionHovered())
+ Q_PRIVATE_SLOT(d_func(), void _q_internalShortcutActivated(int))
+ Q_PRIVATE_SLOT(d_func(), void _q_updateLayout())
+
+#ifdef Q_WS_WINCE
+ Q_PRIVATE_SLOT(d_func(), void _q_updateDefaultAction())
+#endif
+
+ friend class QMenu;
+ friend class QMenuPrivate;
+ friend class QWindowsStyle;
+
+#ifdef Q_OS_MAC
+ friend class QApplicationPrivate;
+ friend class QWidgetPrivate;
+ friend bool qt_mac_activate_action(MenuRef, uint, QAction::ActionEvent, bool);
+#endif
+};
+
+#endif // QT_NO_MENUBAR
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QMENUBAR_H
diff --git a/src/widgets/widgets/qmenubar_p.h b/src/widgets/widgets/qmenubar_p.h
new file mode 100644
index 0000000000..5f482c228e
--- /dev/null
+++ b/src/widgets/widgets/qmenubar_p.h
@@ -0,0 +1,251 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMENUBAR_P_H
+#define QMENUBAR_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QMAC_Q3MENUBAR_CPP_FILE
+#include "QtWidgets/qstyleoption.h"
+#include <private/qmenu_p.h> // Mac needs what in this file!
+
+#ifdef Q_WS_WINCE
+#include "qguifunctions_wince.h"
+#endif
+
+#ifndef QT_NO_MENUBAR
+#ifdef Q_WS_S60
+class CCoeControl;
+class CEikMenuBar;
+#endif
+#endif
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_MENUBAR
+class QMenuBarExtension;
+class QMenuBarPrivate : public QWidgetPrivate
+{
+ Q_DECLARE_PUBLIC(QMenuBar)
+public:
+ QMenuBarPrivate() : itemsDirty(0), currentAction(0), mouseDown(0),
+ closePopupMode(0), defaultPopDown(1), popupState(0), keyboardState(0), altPressed(0),
+ nativeMenuBar(-1), doChildEffects(false), platformMenuBar(0)
+#ifdef QT3_SUPPORT
+ , doAutoResize(false)
+#endif
+
+#ifdef Q_WS_WINCE
+ , wce_menubar(0), wceClassicMenu(false)
+#endif
+#ifdef Q_WS_S60
+ , symbian_menubar(0)
+#endif
+
+ { }
+ ~QMenuBarPrivate()
+ {
+ delete platformMenuBar;
+#ifdef Q_WS_WINCE
+ delete wce_menubar;
+#endif
+#ifdef Q_WS_S60
+ delete symbian_menubar;
+#endif
+ }
+
+ void init();
+ QAction *getNextAction(const int start, const int increment) const;
+
+ //item calculations
+ uint itemsDirty : 1;
+
+ QVector<int> shortcutIndexMap;
+ mutable QVector<QRect> actionRects;
+ void calcActionRects(int max_width, int start) const;
+ QRect actionRect(QAction *) const;
+ void updateGeometries();
+
+ //selection
+ QPointer<QAction>currentAction;
+ uint mouseDown : 1, closePopupMode : 1, defaultPopDown;
+ QAction *actionAt(QPoint p) const;
+ void setCurrentAction(QAction *, bool =false, bool =false);
+ void popupAction(QAction *, bool);
+
+ //active popup state
+ uint popupState : 1;
+ QPointer<QMenu> activeMenu;
+
+ //keyboard mode for keyboard navigation
+ void focusFirstAction();
+ void setKeyboardMode(bool);
+ uint keyboardState : 1, altPressed : 1;
+ QPointer<QWidget> keyboardFocusWidget;
+
+
+ int nativeMenuBar : 3; // Only has values -1, 0, and 1
+ //firing of events
+ void activateAction(QAction *, QAction::ActionEvent);
+
+ void _q_actionTriggered();
+ void _q_actionHovered();
+ void _q_internalShortcutActivated(int);
+ void _q_updateLayout();
+
+#ifdef Q_WS_WINCE
+ void _q_updateDefaultAction();
+#endif
+
+ //extra widgets in the menubar
+ QPointer<QWidget> leftWidget, rightWidget;
+ QMenuBarExtension *extension;
+ bool isVisible(QAction *action);
+
+ //menu fading/scrolling effects
+ bool doChildEffects;
+
+ QRect menuRect(bool) const;
+
+ // reparenting
+ void handleReparent();
+ QWidget *oldParent;
+ QWidget *oldWindow;
+
+ QList<QAction*> hiddenActions;
+ //default action
+ QPointer<QAction> defaultAction;
+
+ QBasicTimer autoReleaseTimer;
+#ifdef QT3_SUPPORT
+ bool doAutoResize;
+#endif
+ QPlatformMenuBar *platformMenuBar;
+
+#ifdef Q_WS_WINCE
+ void wceCreateMenuBar(QWidget *);
+ void wceDestroyMenuBar();
+ struct QWceMenuBarPrivate {
+ QList<QWceMenuAction*> actionItems;
+ QList<QWceMenuAction*> actionItemsLeftButton;
+ QList<QList<QWceMenuAction*>> actionItemsClassic;
+ HMENU menuHandle;
+ HMENU leftButtonMenuHandle;
+ HWND menubarHandle;
+ HWND parentWindowHandle;
+ bool leftButtonIsMenu;
+ QPointer<QAction> leftButtonAction;
+ QMenuBarPrivate *d;
+ int leftButtonCommand;
+
+ QWceMenuBarPrivate(QMenuBarPrivate *menubar);
+ ~QWceMenuBarPrivate();
+ void addAction(QAction *, QWceMenuAction* =0);
+ void addAction(QWceMenuAction *, QWceMenuAction* =0);
+ void syncAction(QWceMenuAction *);
+ inline void syncAction(QAction *a) { syncAction(findAction(a)); }
+ void removeAction(QWceMenuAction *);
+ void rebuild();
+ inline void removeAction(QAction *a) { removeAction(findAction(a)); }
+ inline QWceMenuAction *findAction(QAction *a) {
+ for(int i = 0; i < actionItems.size(); i++) {
+ QWceMenuAction *act = actionItems[i];
+ if(a == act->action)
+ return act;
+ }
+ return 0;
+ }
+ } *wce_menubar;
+ bool wceClassicMenu;
+ void wceCommands(uint command);
+ void wceRefresh();
+ bool wceEmitSignals(QList<QWceMenuAction*> actions, uint command);
+#endif
+#ifdef Q_WS_S60
+ void symbianCreateMenuBar(QWidget *);
+ void symbianDestroyMenuBar();
+ void reparentMenuBar(QWidget *oldParent, QWidget *newParent);
+ struct QSymbianMenuBarPrivate {
+ QList<QSymbianMenuAction*> actionItems;
+ QMenuBarPrivate *d;
+ QSymbianMenuBarPrivate(QMenuBarPrivate *menubar);
+ ~QSymbianMenuBarPrivate();
+ void addAction(QAction *, QSymbianMenuAction* =0);
+ void addAction(QSymbianMenuAction *, QSymbianMenuAction* =0);
+ void syncAction(QSymbianMenuAction *);
+ inline void syncAction(QAction *a) { syncAction(findAction(a)); }
+ void removeAction(QSymbianMenuAction *);
+ void rebuild();
+ inline void removeAction(QAction *a) { removeAction(findAction(a)); }
+ inline QSymbianMenuAction *findAction(QAction *a) {
+ for(int i = 0; i < actionItems.size(); i++) {
+ QSymbianMenuAction *act = actionItems[i];
+ if(a == act->action)
+ return act;
+ }
+ return 0;
+ }
+ void insertNativeMenuItems(const QList<QAction*> &actions);
+
+ } *symbian_menubar;
+ static int symbianCommands(int command);
+#endif
+#ifdef QT_SOFTKEYS_ENABLED
+ QAction *menuBarAction;
+#endif
+};
+#endif
+
+#endif // QT_NO_MENUBAR
+
+QT_END_NAMESPACE
+
+#endif // QMENUBAR_P_H
diff --git a/src/widgets/widgets/qplaintextedit.cpp b/src/widgets/widgets/qplaintextedit.cpp
new file mode 100644
index 0000000000..e408a6e7aa
--- /dev/null
+++ b/src/widgets/widgets/qplaintextedit.cpp
@@ -0,0 +1,2996 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qplaintextedit_p.h"
+
+
+#include <qfont.h>
+#include <qpainter.h>
+#include <qevent.h>
+#include <qdebug.h>
+#include <qmime.h>
+#include <qdrag.h>
+#include <qclipboard.h>
+#include <qmenu.h>
+#include <qstyle.h>
+#include <qtimer.h>
+#include "private/qtextdocumentlayout_p.h"
+#include "private/qabstracttextdocumentlayout_p.h"
+#include "qtextdocument.h"
+#include "private/qtextdocument_p.h"
+#include "qtextlist.h"
+
+#include <qtextformat.h>
+#include <qdatetime.h>
+#include <qapplication.h>
+#include <limits.h>
+#include <qtexttable.h>
+#include <qvariant.h>
+#include <qinputcontext.h>
+
+#ifndef QT_NO_TEXTEDIT
+
+QT_BEGIN_NAMESPACE
+
+static inline bool shouldEnableInputMethod(QPlainTextEdit *plaintextedit)
+{
+ return !plaintextedit->isReadOnly();
+}
+
+class QPlainTextDocumentLayoutPrivate : public QAbstractTextDocumentLayoutPrivate
+{
+ Q_DECLARE_PUBLIC(QPlainTextDocumentLayout)
+public:
+ QPlainTextDocumentLayoutPrivate() {
+ mainViewPrivate = 0;
+ width = 0;
+ maximumWidth = 0;
+ maximumWidthBlockNumber = 0;
+ blockCount = 1;
+ blockUpdate = blockDocumentSizeChanged = false;
+ cursorWidth = 1;
+ textLayoutFlags = 0;
+ }
+
+ qreal width;
+ qreal maximumWidth;
+ int maximumWidthBlockNumber;
+ int blockCount;
+ QPlainTextEditPrivate *mainViewPrivate;
+ bool blockUpdate;
+ bool blockDocumentSizeChanged;
+ int cursorWidth;
+ int textLayoutFlags;
+
+ void layoutBlock(const QTextBlock &block);
+ qreal blockWidth(const QTextBlock &block);
+
+ void relayout();
+};
+
+
+
+/*! \class QPlainTextDocumentLayout
+ \since 4.4
+ \brief The QPlainTextDocumentLayout class implements a plain text layout for QTextDocument
+
+ \ingroup richtext-processing
+
+ A QPlainTextDocumentLayout is required for text documents that can
+ be display or edited in a QPlainTextEdit. See
+ QTextDocument::setDocumentLayout().
+
+ QPlainTextDocumentLayout uses the QAbstractTextDocumentLayout API
+ that QTextDocument requires, but redefines it partially in order to
+ support plain text better. For instances, it does not operate on
+ vertical pixels, but on paragraphs (called blocks) instead. The
+ height of a document is identical to the number of paragraphs it
+ contains. The layout also doesn't support tables or nested frames,
+ or any sort of advanced text layout that goes beyond a list of
+ paragraphs with syntax highlighting.
+
+*/
+
+
+
+/*!
+ Constructs a plain text document layout for the text \a document.
+ */
+QPlainTextDocumentLayout::QPlainTextDocumentLayout(QTextDocument *document)
+ :QAbstractTextDocumentLayout(* new QPlainTextDocumentLayoutPrivate, document) {
+}
+/*!
+ Destructs a plain text document layout.
+ */
+QPlainTextDocumentLayout::~QPlainTextDocumentLayout() {}
+
+
+/*!
+ \reimp
+ */
+void QPlainTextDocumentLayout::draw(QPainter *, const PaintContext &)
+{
+}
+
+/*!
+ \reimp
+ */
+int QPlainTextDocumentLayout::hitTest(const QPointF &, Qt::HitTestAccuracy ) const
+{
+// this function is used from
+// QAbstractTextDocumentLayout::anchorAt(), but is not
+// implementable in a plain text document layout, because the
+// layout depends on the top block and top line which depends on
+// the view
+ return -1;
+}
+
+/*!
+ \reimp
+ */
+int QPlainTextDocumentLayout::pageCount() const
+{ return 1; }
+
+/*!
+ \reimp
+ */
+QSizeF QPlainTextDocumentLayout::documentSize() const
+{
+ Q_D(const QPlainTextDocumentLayout);
+ return QSizeF(d->maximumWidth, document()->lineCount());
+}
+
+/*!
+ \reimp
+ */
+QRectF QPlainTextDocumentLayout::frameBoundingRect(QTextFrame *) const
+{
+ Q_D(const QPlainTextDocumentLayout);
+ return QRectF(0, 0, qMax(d->width, d->maximumWidth), qreal(INT_MAX));
+}
+
+/*!
+ \reimp
+ */
+QRectF QPlainTextDocumentLayout::blockBoundingRect(const QTextBlock &block) const
+{
+ if (!block.isValid()) { return QRectF(); }
+ QTextLayout *tl = block.layout();
+ if (!tl->lineCount())
+ const_cast<QPlainTextDocumentLayout*>(this)->layoutBlock(block);
+ QRectF br;
+ if (block.isVisible()) {
+ br = QRectF(QPointF(0, 0), tl->boundingRect().bottomRight());
+ if (tl->lineCount() == 1)
+ br.setWidth(qMax(br.width(), tl->lineAt(0).naturalTextWidth()));
+ qreal margin = document()->documentMargin();
+ br.adjust(0, 0, margin, 0);
+ if (!block.next().isValid())
+ br.adjust(0, 0, 0, margin);
+ }
+ return br;
+
+}
+
+/*!
+ Ensures that \a block has a valid layout
+ */
+void QPlainTextDocumentLayout::ensureBlockLayout(const QTextBlock &block) const
+{
+ if (!block.isValid())
+ return;
+ QTextLayout *tl = block.layout();
+ if (!tl->lineCount())
+ const_cast<QPlainTextDocumentLayout*>(this)->layoutBlock(block);
+}
+
+
+/*! \property QPlainTextDocumentLayout::cursorWidth
+
+ This property specifies the width of the cursor in pixels. The default value is 1.
+*/
+void QPlainTextDocumentLayout::setCursorWidth(int width)
+{
+ Q_D(QPlainTextDocumentLayout);
+ d->cursorWidth = width;
+}
+
+int QPlainTextDocumentLayout::cursorWidth() const
+{
+ Q_D(const QPlainTextDocumentLayout);
+ return d->cursorWidth;
+}
+
+QPlainTextDocumentLayoutPrivate *QPlainTextDocumentLayout::priv() const
+{
+ Q_D(const QPlainTextDocumentLayout);
+ return const_cast<QPlainTextDocumentLayoutPrivate*>(d);
+}
+
+
+/*!
+
+ Requests a complete update on all views.
+ */
+void QPlainTextDocumentLayout::requestUpdate()
+{
+ emit update(QRectF(0., -document()->documentMargin(), 1000000000., 1000000000.));
+}
+
+
+void QPlainTextDocumentLayout::setTextWidth(qreal newWidth)
+{
+ Q_D(QPlainTextDocumentLayout);
+ d->width = d->maximumWidth = newWidth;
+ d->relayout();
+}
+
+qreal QPlainTextDocumentLayout::textWidth() const
+{
+ Q_D(const QPlainTextDocumentLayout);
+ return d->width;
+}
+
+void QPlainTextDocumentLayoutPrivate::relayout()
+{
+ Q_Q(QPlainTextDocumentLayout);
+ QTextBlock block = q->document()->firstBlock();
+ while (block.isValid()) {
+ block.layout()->clearLayout();
+ block.setLineCount(block.isVisible() ? 1 : 0);
+ block = block.next();
+ }
+ emit q->update();
+}
+
+
+/*! \reimp
+ */
+void QPlainTextDocumentLayout::documentChanged(int from, int /*charsRemoved*/, int charsAdded)
+{
+ Q_D(QPlainTextDocumentLayout);
+ QTextDocument *doc = document();
+ int newBlockCount = doc->blockCount();
+
+ QTextBlock changeStartBlock = doc->findBlock(from);
+ QTextBlock changeEndBlock = doc->findBlock(qMax(0, from + charsAdded - 1));
+
+ if (changeStartBlock == changeEndBlock && newBlockCount == d->blockCount) {
+ QTextBlock block = changeStartBlock;
+ int blockLineCount = block.layout()->lineCount();
+ if (block.isValid() && blockLineCount) {
+ QRectF oldBr = blockBoundingRect(block);
+ layoutBlock(block);
+ QRectF newBr = blockBoundingRect(block);
+ if (newBr.height() == oldBr.height()) {
+ if (!d->blockUpdate)
+ emit updateBlock(block);
+ return;
+ }
+ }
+ } else {
+ QTextBlock block = changeStartBlock;
+ do {
+ block.clearLayout();
+ if (block == changeEndBlock)
+ break;
+ block = block.next();
+ } while(block.isValid());
+ }
+
+ if (newBlockCount != d->blockCount) {
+
+ int changeEnd = changeEndBlock.blockNumber();
+ int blockDiff = newBlockCount - d->blockCount;
+ int oldChangeEnd = changeEnd - blockDiff;
+
+ if (d->maximumWidthBlockNumber > oldChangeEnd)
+ d->maximumWidthBlockNumber += blockDiff;
+
+ d->blockCount = newBlockCount;
+ if (d->blockCount == 1)
+ d->maximumWidth = blockWidth(doc->firstBlock());
+
+ if (!d->blockDocumentSizeChanged)
+ emit documentSizeChanged(documentSize());
+
+ if (blockDiff == 1 && changeEnd == newBlockCount -1 ) {
+ if (!d->blockUpdate) {
+ QTextBlock b = changeStartBlock;
+ for(;;) {
+ emit updateBlock(b);
+ if (b == changeEndBlock)
+ break;
+ b = b.next();
+ }
+ }
+ return;
+ }
+ }
+
+ if (!d->blockUpdate)
+ emit update(QRectF(0., -doc->documentMargin(), 1000000000., 1000000000.)); // optimization potential
+}
+
+
+void QPlainTextDocumentLayout::layoutBlock(const QTextBlock &block)
+{
+ Q_D(QPlainTextDocumentLayout);
+ QTextDocument *doc = document();
+ qreal margin = doc->documentMargin();
+ qreal blockMaximumWidth = 0;
+
+ qreal height = 0;
+ QTextLayout *tl = block.layout();
+ QTextOption option = doc->defaultTextOption();
+ tl->setTextOption(option);
+
+ int extraMargin = 0;
+ if (option.flags() & QTextOption::AddSpaceForLineAndParagraphSeparators) {
+ QFontMetrics fm(block.charFormat().font());
+ extraMargin += fm.width(QChar(0x21B5));
+ }
+ tl->beginLayout();
+ qreal availableWidth = d->width;
+ if (availableWidth <= 0) {
+ availableWidth = qreal(INT_MAX); // similar to text edit with pageSize.width == 0
+ }
+ availableWidth -= 2*margin + extraMargin;
+ while (1) {
+ QTextLine line = tl->createLine();
+ if (!line.isValid())
+ break;
+ line.setLeadingIncluded(true);
+ line.setLineWidth(availableWidth);
+ line.setPosition(QPointF(margin, height));
+ height += line.height();
+ blockMaximumWidth = qMax(blockMaximumWidth, line.naturalTextWidth() + 2*margin);
+ }
+ tl->endLayout();
+
+ int previousLineCount = doc->lineCount();
+ const_cast<QTextBlock&>(block).setLineCount(block.isVisible() ? tl->lineCount() : 0);
+ int lineCount = doc->lineCount();
+
+ bool emitDocumentSizeChanged = previousLineCount != lineCount;
+ if (blockMaximumWidth > d->maximumWidth) {
+ // new longest line
+ d->maximumWidth = blockMaximumWidth;
+ d->maximumWidthBlockNumber = block.blockNumber();
+ emitDocumentSizeChanged = true;
+ } else if (block.blockNumber() == d->maximumWidthBlockNumber && blockMaximumWidth < d->maximumWidth) {
+ // longest line shrinking
+ QTextBlock b = doc->firstBlock();
+ d->maximumWidth = 0;
+ QTextBlock maximumBlock;
+ while (b.isValid()) {
+ qreal blockMaximumWidth = blockWidth(b);
+ if (blockMaximumWidth > d->maximumWidth) {
+ d->maximumWidth = blockMaximumWidth;
+ maximumBlock = b;
+ }
+ b = b.next();
+ }
+ if (maximumBlock.isValid()) {
+ d->maximumWidthBlockNumber = maximumBlock.blockNumber();
+ emitDocumentSizeChanged = true;
+ }
+ }
+ if (emitDocumentSizeChanged && !d->blockDocumentSizeChanged)
+ emit documentSizeChanged(documentSize());
+}
+
+qreal QPlainTextDocumentLayout::blockWidth(const QTextBlock &block)
+{
+ QTextLayout *layout = block.layout();
+ if (!layout->lineCount())
+ return 0; // only for layouted blocks
+ qreal blockWidth = 0;
+ for (int i = 0; i < layout->lineCount(); ++i) {
+ QTextLine line = layout->lineAt(i);
+ blockWidth = qMax(line.naturalTextWidth() + 8, blockWidth);
+ }
+ return blockWidth;
+}
+
+
+QPlainTextEditControl::QPlainTextEditControl(QPlainTextEdit *parent)
+ : QWidgetTextControl(parent), textEdit(parent),
+ topBlock(0)
+{
+ setAcceptRichText(false);
+}
+
+void QPlainTextEditPrivate::_q_cursorPositionChanged()
+{
+ pageUpDownLastCursorYIsValid = false;
+}
+
+void QPlainTextEditPrivate::_q_verticalScrollbarActionTriggered(int action) {
+ if (action == QAbstractSlider::SliderPageStepAdd) {
+ pageUpDown(QTextCursor::Down, QTextCursor::MoveAnchor, false);
+ } else if (action == QAbstractSlider::SliderPageStepSub) {
+ pageUpDown(QTextCursor::Up, QTextCursor::MoveAnchor, false);
+ }
+}
+
+QMimeData *QPlainTextEditControl::createMimeDataFromSelection() const {
+ QPlainTextEdit *ed = qobject_cast<QPlainTextEdit *>(parent());
+ if (!ed)
+ return QWidgetTextControl::createMimeDataFromSelection();
+ return ed->createMimeDataFromSelection();
+ }
+bool QPlainTextEditControl::canInsertFromMimeData(const QMimeData *source) const {
+ QPlainTextEdit *ed = qobject_cast<QPlainTextEdit *>(parent());
+ if (!ed)
+ return QWidgetTextControl::canInsertFromMimeData(source);
+ return ed->canInsertFromMimeData(source);
+}
+void QPlainTextEditControl::insertFromMimeData(const QMimeData *source) {
+ QPlainTextEdit *ed = qobject_cast<QPlainTextEdit *>(parent());
+ if (!ed)
+ QWidgetTextControl::insertFromMimeData(source);
+ else
+ ed->insertFromMimeData(source);
+}
+
+int QPlainTextEditPrivate::verticalOffset(int topBlock, int topLine) const
+{
+ qreal offset = 0;
+ QTextDocument *doc = control->document();
+
+ if (topLine) {
+ QTextBlock currentBlock = doc->findBlockByNumber(topBlock);
+ QPlainTextDocumentLayout *documentLayout = qobject_cast<QPlainTextDocumentLayout*>(doc->documentLayout());
+ Q_ASSERT(documentLayout);
+ QRectF r = documentLayout->blockBoundingRect(currentBlock);
+ Q_UNUSED(r);
+ QTextLayout *layout = currentBlock.layout();
+ if (layout && topLine <= layout->lineCount()) {
+ QTextLine line = layout->lineAt(topLine - 1);
+ const QRectF lr = line.naturalTextRect();
+ offset = lr.bottom();
+ }
+ }
+ if (topBlock == 0 && topLine == 0)
+ offset -= doc->documentMargin(); // top margin
+ return (int)offset;
+}
+
+
+int QPlainTextEditPrivate::verticalOffset() const {
+ return verticalOffset(control->topBlock, topLine);
+}
+
+
+QTextBlock QPlainTextEditControl::firstVisibleBlock() const
+{
+ return document()->findBlockByNumber(topBlock);
+}
+
+
+
+int QPlainTextEditControl::hitTest(const QPointF &point, Qt::HitTestAccuracy ) const {
+ int currentBlockNumber = topBlock;
+ QTextBlock currentBlock = document()->findBlockByNumber(currentBlockNumber);
+ if (!currentBlock.isValid())
+ return -1;
+
+ QPlainTextDocumentLayout *documentLayout = qobject_cast<QPlainTextDocumentLayout*>(document()->documentLayout());
+ Q_ASSERT(documentLayout);
+
+ QPointF offset;
+ QRectF r = documentLayout->blockBoundingRect(currentBlock);
+ while (currentBlock.next().isValid() && r.bottom() + offset.y() <= point.y()) {
+ offset.ry() += r.height();
+ currentBlock = currentBlock.next();
+ ++currentBlockNumber;
+ r = documentLayout->blockBoundingRect(currentBlock);
+ }
+ while (currentBlock.previous().isValid() && r.top() + offset.y() > point.y()) {
+ offset.ry() -= r.height();
+ currentBlock = currentBlock.previous();
+ --currentBlockNumber;
+ r = documentLayout->blockBoundingRect(currentBlock);
+ }
+
+
+ if (!currentBlock.isValid())
+ return -1;
+ QTextLayout *layout = currentBlock.layout();
+ int off = 0;
+ QPointF pos = point - offset;
+ for (int i = 0; i < layout->lineCount(); ++i) {
+ QTextLine line = layout->lineAt(i);
+ const QRectF lr = line.naturalTextRect();
+ if (lr.top() > pos.y()) {
+ off = qMin(off, line.textStart());
+ } else if (lr.bottom() <= pos.y()) {
+ off = qMax(off, line.textStart() + line.textLength());
+ } else {
+ off = line.xToCursor(pos.x(), overwriteMode() ?
+ QTextLine::CursorOnCharacter : QTextLine::CursorBetweenCharacters);
+ break;
+ }
+ }
+
+ return currentBlock.position() + off;
+}
+
+QRectF QPlainTextEditControl::blockBoundingRect(const QTextBlock &block) const {
+ int currentBlockNumber = topBlock;
+ int blockNumber = block.blockNumber();
+ QTextBlock currentBlock = document()->findBlockByNumber(currentBlockNumber);
+ if (!currentBlock.isValid())
+ return QRectF();
+ Q_ASSERT(currentBlock.blockNumber() == currentBlockNumber);
+ QTextDocument *doc = document();
+ QPlainTextDocumentLayout *documentLayout = qobject_cast<QPlainTextDocumentLayout*>(doc->documentLayout());
+ Q_ASSERT(documentLayout);
+
+ QPointF offset;
+ if (!block.isValid())
+ return QRectF();
+ QRectF r = documentLayout->blockBoundingRect(currentBlock);
+ int maxVerticalOffset = r.height();
+ while (currentBlockNumber < blockNumber && offset.y() - maxVerticalOffset <= 2* textEdit->viewport()->height()) {
+ offset.ry() += r.height();
+ currentBlock = currentBlock.next();
+ ++currentBlockNumber;
+ if (!currentBlock.isVisible()) {
+ currentBlock = doc->findBlockByLineNumber(currentBlock.firstLineNumber());
+ currentBlockNumber = currentBlock.blockNumber();
+ }
+ r = documentLayout->blockBoundingRect(currentBlock);
+ }
+ while (currentBlockNumber > blockNumber && offset.y() + maxVerticalOffset >= -textEdit->viewport()->height()) {
+ currentBlock = currentBlock.previous();
+ --currentBlockNumber;
+ while (!currentBlock.isVisible()) {
+ currentBlock = currentBlock.previous();
+ --currentBlockNumber;
+ }
+ if (!currentBlock.isValid())
+ break;
+
+ r = documentLayout->blockBoundingRect(currentBlock);
+ offset.ry() -= r.height();
+ }
+
+ if (currentBlockNumber != blockNumber) {
+ // fallback for blocks out of reach. Give it some geometry at
+ // least, and ensure the layout is up to date.
+ r = documentLayout->blockBoundingRect(block);
+ if (currentBlockNumber > blockNumber)
+ offset.ry() -= r.height();
+ }
+ r.translate(offset);
+ return r;
+}
+
+
+void QPlainTextEditPrivate::setTopLine(int visualTopLine, int dx)
+{
+ QTextDocument *doc = control->document();
+ QTextBlock block = doc->findBlockByLineNumber(visualTopLine);
+ int blockNumber = block.blockNumber();
+ int lineNumber = visualTopLine - block.firstLineNumber();
+ setTopBlock(blockNumber, lineNumber, dx);
+}
+
+void QPlainTextEditPrivate::setTopBlock(int blockNumber, int lineNumber, int dx)
+{
+ Q_Q(QPlainTextEdit);
+ blockNumber = qMax(0, blockNumber);
+ lineNumber = qMax(0, lineNumber);
+ QTextDocument *doc = control->document();
+ QTextBlock block = doc->findBlockByNumber(blockNumber);
+
+ int newTopLine = block.firstLineNumber() + lineNumber;
+ int maxTopLine = vbar->maximum();
+
+ if (newTopLine > maxTopLine) {
+ block = doc->findBlockByLineNumber(maxTopLine);
+ blockNumber = block.blockNumber();
+ lineNumber = maxTopLine - block.firstLineNumber();
+ }
+
+ bool vbarSignalsBlocked = vbar->blockSignals(true);
+ vbar->setValue(newTopLine);
+ vbar->blockSignals(vbarSignalsBlocked);
+
+ if (!dx && blockNumber == control->topBlock && lineNumber == topLine)
+ return;
+
+ if (viewport->updatesEnabled() && viewport->isVisible()) {
+ int dy = 0;
+ if (doc->findBlockByNumber(control->topBlock).isValid()) {
+ dy = (int)(-q->blockBoundingGeometry(block).y())
+ + verticalOffset() - verticalOffset(blockNumber, lineNumber);
+ }
+ control->topBlock = blockNumber;
+ topLine = lineNumber;
+
+ bool vbarSignalsBlocked = vbar->blockSignals(true);
+ vbar->setValue(block.firstLineNumber() + lineNumber);
+ vbar->blockSignals(vbarSignalsBlocked);
+
+ if (dx || dy)
+ viewport->scroll(q->isRightToLeft() ? -dx : dx, dy);
+ else
+ viewport->update();
+ emit q->updateRequest(viewport->rect(), dy);
+ } else {
+ control->topBlock = blockNumber;
+ topLine = lineNumber;
+ }
+
+}
+
+
+
+void QPlainTextEditPrivate::ensureVisible(int position, bool center, bool forceCenter) {
+ Q_Q(QPlainTextEdit);
+ QRectF visible = QRectF(viewport->rect()).translated(-q->contentOffset());
+ QTextBlock block = control->document()->findBlock(position);
+ if (!block.isValid())
+ return;
+ QRectF br = control->blockBoundingRect(block);
+ if (!br.isValid())
+ return;
+ QRectF lr = br;
+ QTextLine line = block.layout()->lineForTextPosition(position - block.position());
+ Q_ASSERT(line.isValid());
+ lr = line.naturalTextRect().translated(br.topLeft());
+
+ if (lr.bottom() >= visible.bottom() || (center && lr.top() < visible.top()) || forceCenter){
+
+ qreal height = visible.height();
+ if (center)
+ height /= 2;
+
+ qreal h = center ? line.naturalTextRect().center().y() : line.naturalTextRect().bottom();
+
+ QTextBlock previousVisibleBlock = block;
+ while (h < height && block.previous().isValid()) {
+ previousVisibleBlock = block;
+ do {
+ block = block.previous();
+ } while (!block.isVisible() && block.previous().isValid());
+ h += q->blockBoundingRect(block).height();
+ }
+
+ int l = 0;
+ int lineCount = block.layout()->lineCount();
+ int voffset = verticalOffset(block.blockNumber(), 0);
+ while (l < lineCount) {
+ QRectF lineRect = block.layout()->lineAt(l).naturalTextRect();
+ if (h - voffset - lineRect.top() <= height)
+ break;
+ ++l;
+ }
+
+ if (l >= lineCount) {
+ block = previousVisibleBlock;
+ l = 0;
+ }
+ setTopBlock(block.blockNumber(), l);
+ } else if (lr.top() < visible.top()) {
+ setTopBlock(block.blockNumber(), line.lineNumber());
+ }
+
+}
+
+
+void QPlainTextEditPrivate::updateViewport()
+{
+ Q_Q(QPlainTextEdit);
+ viewport->update();
+ emit q->updateRequest(viewport->rect(), 0);
+}
+
+QPlainTextEditPrivate::QPlainTextEditPrivate()
+ : control(0),
+ tabChangesFocus(false),
+ lineWrap(QPlainTextEdit::WidgetWidth),
+ wordWrap(QTextOption::WrapAtWordBoundaryOrAnywhere),
+ clickCausedFocus(0),topLine(0),
+ pageUpDownLastCursorYIsValid(false)
+{
+ showCursorOnInitialShow = true;
+ backgroundVisible = false;
+ centerOnScroll = false;
+ inDrag = false;
+}
+
+
+void QPlainTextEditPrivate::init(const QString &txt)
+{
+ Q_Q(QPlainTextEdit);
+ control = new QPlainTextEditControl(q);
+
+ QTextDocument *doc = new QTextDocument(control);
+ QAbstractTextDocumentLayout *layout = new QPlainTextDocumentLayout(doc);
+ doc->setDocumentLayout(layout);
+ control->setDocument(doc);
+
+ control->setPalette(q->palette());
+
+ QObject::connect(vbar, SIGNAL(actionTriggered(int)), q, SLOT(_q_verticalScrollbarActionTriggered(int)));
+
+ QObject::connect(control, SIGNAL(microFocusChanged()), q, SLOT(updateMicroFocus()));
+ QObject::connect(control, SIGNAL(documentSizeChanged(QSizeF)), q, SLOT(_q_adjustScrollbars()));
+ QObject::connect(control, SIGNAL(blockCountChanged(int)), q, SIGNAL(blockCountChanged(int)));
+ QObject::connect(control, SIGNAL(updateRequest(QRectF)), q, SLOT(_q_repaintContents(QRectF)));
+ QObject::connect(control, SIGNAL(modificationChanged(bool)), q, SIGNAL(modificationChanged(bool)));
+
+ QObject::connect(control, SIGNAL(textChanged()), q, SIGNAL(textChanged()));
+ QObject::connect(control, SIGNAL(undoAvailable(bool)), q, SIGNAL(undoAvailable(bool)));
+ QObject::connect(control, SIGNAL(redoAvailable(bool)), q, SIGNAL(redoAvailable(bool)));
+ QObject::connect(control, SIGNAL(copyAvailable(bool)), q, SIGNAL(copyAvailable(bool)));
+ QObject::connect(control, SIGNAL(selectionChanged()), q, SIGNAL(selectionChanged()));
+ QObject::connect(control, SIGNAL(cursorPositionChanged()), q, SLOT(_q_cursorPositionChanged()));
+ QObject::connect(control, SIGNAL(cursorPositionChanged()), q, SIGNAL(cursorPositionChanged()));
+
+ QObject::connect(control, SIGNAL(textChanged()), q, SLOT(updateMicroFocus()));
+
+ // set a null page size initially to avoid any relayouting until the textedit
+ // is shown. relayoutDocument() will take care of setting the page size to the
+ // viewport dimensions later.
+ doc->setTextWidth(-1);
+ doc->documentLayout()->setPaintDevice(viewport);
+ doc->setDefaultFont(q->font());
+
+
+ if (!txt.isEmpty())
+ control->setPlainText(txt);
+
+ hbar->setSingleStep(20);
+ vbar->setSingleStep(1);
+
+ viewport->setBackgroundRole(QPalette::Base);
+ q->setAcceptDrops(true);
+ q->setFocusPolicy(Qt::WheelFocus);
+ q->setAttribute(Qt::WA_KeyCompression);
+ q->setAttribute(Qt::WA_InputMethodEnabled);
+
+#ifndef QT_NO_CURSOR
+ viewport->setCursor(Qt::IBeamCursor);
+#endif
+ originalOffsetY = 0;
+#ifdef Q_WS_WIN
+ setSingleFingerPanEnabled(true);
+#endif
+}
+
+void QPlainTextEditPrivate::_q_repaintContents(const QRectF &contentsRect)
+{
+ Q_Q(QPlainTextEdit);
+ if (!contentsRect.isValid()) {
+ updateViewport();
+ return;
+ }
+ const int xOffset = horizontalOffset();
+ const int yOffset = verticalOffset();
+ const QRect visibleRect(xOffset, yOffset, viewport->width(), viewport->height());
+
+ QRect r = contentsRect.adjusted(-1, -1, 1, 1).intersected(visibleRect).toAlignedRect();
+ if (r.isEmpty())
+ return;
+
+ r.translate(-xOffset, -yOffset);
+ viewport->update(r);
+ emit q->updateRequest(r, 0);
+}
+
+void QPlainTextEditPrivate::pageUpDown(QTextCursor::MoveOperation op, QTextCursor::MoveMode moveMode, bool moveCursor)
+{
+
+ Q_Q(QPlainTextEdit);
+
+ QTextCursor cursor = control->textCursor();
+ if (moveCursor) {
+ ensureCursorVisible();
+ if (!pageUpDownLastCursorYIsValid)
+ pageUpDownLastCursorY = control->cursorRect(cursor).top() - verticalOffset();
+ }
+
+ qreal lastY = pageUpDownLastCursorY;
+
+
+ if (op == QTextCursor::Down) {
+ QRectF visible = QRectF(viewport->rect()).translated(-q->contentOffset());
+ QTextBlock firstVisibleBlock = q->firstVisibleBlock();
+ QTextBlock block = firstVisibleBlock;
+ QRectF br = q->blockBoundingRect(block);
+ qreal h = 0;
+ int atEnd = false;
+ while (h + br.height() <= visible.bottom()) {
+ if (!block.next().isValid()) {
+ atEnd = true;
+ lastY = visible.bottom(); // set cursor to last line
+ break;
+ }
+ h += br.height();
+ block = block.next();
+ br = q->blockBoundingRect(block);
+ }
+
+ if (!atEnd) {
+ int line = 0;
+ qreal diff = visible.bottom() - h;
+ int lineCount = block.layout()->lineCount();
+ while (line < lineCount - 1) {
+ if (block.layout()->lineAt(line).naturalTextRect().bottom() > diff) {
+ // the first line that did not completely fit the screen
+ break;
+ }
+ ++line;
+ }
+ setTopBlock(block.blockNumber(), line);
+ }
+
+ if (moveCursor) {
+ // move using movePosition to keep the cursor's x
+ lastY += verticalOffset();
+ bool moved = false;
+ do {
+ moved = cursor.movePosition(op, moveMode);
+ } while (moved && control->cursorRect(cursor).top() < lastY);
+ }
+
+ } else if (op == QTextCursor::Up) {
+
+ QRectF visible = QRectF(viewport->rect()).translated(-q->contentOffset());
+ visible.translate(0, -visible.height()); // previous page
+ QTextBlock block = q->firstVisibleBlock();
+ qreal h = 0;
+ while (h >= visible.top()) {
+ if (!block.previous().isValid()) {
+ if (control->topBlock == 0 && topLine == 0) {
+ lastY = 0; // set cursor to first line
+ }
+ break;
+ }
+ block = block.previous();
+ QRectF br = q->blockBoundingRect(block);
+ h -= br.height();
+ }
+
+ int line = 0;
+ if (block.isValid()) {
+ qreal diff = visible.top() - h;
+ int lineCount = block.layout()->lineCount();
+ while (line < lineCount) {
+ if (block.layout()->lineAt(line).naturalTextRect().top() >= diff)
+ break;
+ ++line;
+ }
+ if (line == lineCount) {
+ if (block.next().isValid() && block.next() != q->firstVisibleBlock()) {
+ block = block.next();
+ line = 0;
+ } else {
+ --line;
+ }
+ }
+ }
+ setTopBlock(block.blockNumber(), line);
+
+ if (moveCursor) {
+ cursor.setVisualNavigation(true);
+ // move using movePosition to keep the cursor's x
+ lastY += verticalOffset();
+ bool moved = false;
+ do {
+ moved = cursor.movePosition(op, moveMode);
+ } while (moved && control->cursorRect(cursor).top() > lastY);
+ }
+ }
+
+ if (moveCursor) {
+ control->setTextCursor(cursor);
+ pageUpDownLastCursorYIsValid = true;
+ }
+}
+
+#ifndef QT_NO_SCROLLBAR
+
+void QPlainTextEditPrivate::_q_adjustScrollbars()
+{
+ Q_Q(QPlainTextEdit);
+ QTextDocument *doc = control->document();
+ QPlainTextDocumentLayout *documentLayout = qobject_cast<QPlainTextDocumentLayout*>(doc->documentLayout());
+ Q_ASSERT(documentLayout);
+ bool documentSizeChangedBlocked = documentLayout->priv()->blockDocumentSizeChanged;
+ documentLayout->priv()->blockDocumentSizeChanged = true;
+ qreal margin = doc->documentMargin();
+
+ int vmax = 0;
+
+ int vSliderLength = 0;
+ if (!centerOnScroll && q->isVisible()) {
+ QTextBlock block = doc->lastBlock();
+ const qreal visible = viewport->rect().height() - margin - 1;
+ qreal y = 0;
+ int visibleFromBottom = 0;
+
+ while (block.isValid()) {
+ if (!block.isVisible()) {
+ block = block.previous();
+ continue;
+ }
+ y += documentLayout->blockBoundingRect(block).height();
+
+ QTextLayout *layout = block.layout();
+ int layoutLineCount = layout->lineCount();
+ if (y > visible) {
+ int lineNumber = 0;
+ while (lineNumber < layoutLineCount) {
+ QTextLine line = layout->lineAt(lineNumber);
+ const QRectF lr = line.naturalTextRect();
+ if (lr.top() >= y - visible)
+ break;
+ ++lineNumber;
+ }
+ if (lineNumber < layoutLineCount)
+ visibleFromBottom += (layoutLineCount - lineNumber);
+ break;
+
+ }
+ visibleFromBottom += layoutLineCount;
+ block = block.previous();
+ }
+ vmax = qMax(0, doc->lineCount() - visibleFromBottom);
+ vSliderLength = visibleFromBottom;
+
+ } else {
+ vmax = qMax(0, doc->lineCount() - 1);
+ vSliderLength = viewport->height() / q->fontMetrics().lineSpacing();
+ }
+
+
+
+ QSizeF documentSize = documentLayout->documentSize();
+ vbar->setRange(0, qMax(0, vmax));
+ vbar->setPageStep(vSliderLength);
+ int visualTopLine = vmax;
+ QTextBlock firstVisibleBlock = q->firstVisibleBlock();
+ if (firstVisibleBlock.isValid())
+ visualTopLine = firstVisibleBlock.firstLineNumber() + topLine;
+ bool vbarSignalsBlocked = vbar->blockSignals(true);
+ vbar->setValue(visualTopLine);
+ vbar->blockSignals(vbarSignalsBlocked);
+
+ hbar->setRange(0, (int)documentSize.width() - viewport->width());
+ hbar->setPageStep(viewport->width());
+ documentLayout->priv()->blockDocumentSizeChanged = documentSizeChangedBlocked;
+ setTopLine(vbar->value());
+}
+
+#endif
+
+
+void QPlainTextEditPrivate::ensureViewportLayouted()
+{
+}
+
+/*!
+ \class QPlainTextEdit
+ \since 4.4
+ \brief The QPlainTextEdit class provides a widget that is used to edit and display
+ plain text.
+
+ \ingroup richtext-processing
+
+
+ \tableofcontents
+
+ \section1 Introduction and Concepts
+
+ QPlainTextEdit is an advanced viewer/editor supporting plain
+ text. It is optimized to handle large documents and to respond
+ quickly to user input.
+
+ QPlainText uses very much the same technology and concepts as
+ QTextEdit, but is optimized for plain text handling.
+
+ QPlainTextEdit works on paragraphs and characters. A paragraph is
+ a formatted string which is word-wrapped to fit into the width of
+ the widget. By default when reading plain text, one newline
+ signifies a paragraph. A document consists of zero or more
+ paragraphs. Paragraphs are separated by hard line breaks. Each
+ character within a paragraph has its own attributes, for example,
+ font and color.
+
+ The shape of the mouse cursor on a QPlainTextEdit is
+ Qt::IBeamCursor by default. It can be changed through the
+ viewport()'s cursor property.
+
+ \section1 Using QPlainTextEdit as a Display Widget
+
+ The text is set or replaced using setPlainText() which deletes the
+ existing text and replaces it with the text passed to setPlainText().
+
+ Text can be inserted using the QTextCursor class or using the
+ convenience functions insertPlainText(), appendPlainText() or
+ paste().
+
+ By default, the text edit wraps words at whitespace to fit within
+ the text edit widget. The setLineWrapMode() function is used to
+ specify the kind of line wrap you want, \l WidgetWidth or \l
+ NoWrap if you don't want any wrapping. If you use word wrap to
+ the widget's width \l WidgetWidth, you can specify whether to
+ break on whitespace or anywhere with setWordWrapMode().
+
+ The find() function can be used to find and select a given string
+ within the text.
+
+ If you want to limit the total number of paragraphs in a
+ QPlainTextEdit, as it is for example useful in a log viewer, then
+ you can use the maximumBlockCount property. The combination of
+ setMaximumBlockCount() and appendPlainText() turns QPlainTextEdit
+ into an efficient viewer for log text. The scrolling can be
+ reduced with the centerOnScroll() property, making the log viewer
+ even faster. Text can be formatted in a limited way, either using
+ a syntax highlighter (see below), or by appending html-formatted
+ text with appendHtml(). While QPlainTextEdit does not support
+ complex rich text rendering with tables and floats, it does
+ support limited paragraph-based formatting that you may need in a
+ log viewer.
+
+ \section2 Read-only Key Bindings
+
+ When QPlainTextEdit is used read-only the key bindings are limited to
+ navigation, and text may only be selected with the mouse:
+ \table
+ \header \i Keypresses \i Action
+ \row \i Qt::UpArrow \i Moves one line up.
+ \row \i Qt::DownArrow \i Moves one line down.
+ \row \i Qt::LeftArrow \i Moves one character to the left.
+ \row \i Qt::RightArrow \i Moves one character to the right.
+ \row \i PageUp \i Moves one (viewport) page up.
+ \row \i PageDown \i Moves one (viewport) page down.
+ \row \i Home \i Moves to the beginning of the text.
+ \row \i End \i Moves to the end of the text.
+ \row \i Alt+Wheel
+ \i Scrolls the page horizontally (the Wheel is the mouse wheel).
+ \row \i Ctrl+Wheel \i Zooms the text.
+ \row \i Ctrl+A \i Selects all text.
+ \endtable
+
+
+ \section1 Using QPlainTextEdit as an Editor
+
+ All the information about using QPlainTextEdit as a display widget also
+ applies here.
+
+ Selection of text is handled by the QTextCursor class, which provides
+ functionality for creating selections, retrieving the text contents or
+ deleting selections. You can retrieve the object that corresponds with
+ the user-visible cursor using the textCursor() method. If you want to set
+ a selection in QPlainTextEdit just create one on a QTextCursor object and
+ then make that cursor the visible cursor using setCursor(). The selection
+ can be copied to the clipboard with copy(), or cut to the clipboard with
+ cut(). The entire text can be selected using selectAll().
+
+ QPlainTextEdit holds a QTextDocument object which can be retrieved using the
+ document() method. You can also set your own document object using setDocument().
+ QTextDocument emits a textChanged() signal if the text changes and it also
+ provides a isModified() function which will return true if the text has been
+ modified since it was either loaded or since the last call to setModified
+ with false as argument. In addition it provides methods for undo and redo.
+
+ \section2 Syntax Highlighting
+
+ Just like QTextEdit, QPlainTextEdit works together with
+ QSyntaxHighlighter.
+
+ \section2 Editing Key Bindings
+
+ The list of key bindings which are implemented for editing:
+ \table
+ \header \i Keypresses \i Action
+ \row \i Backspace \i Deletes the character to the left of the cursor.
+ \row \i Delete \i Deletes the character to the right of the cursor.
+ \row \i Ctrl+C \i Copy the selected text to the clipboard.
+ \row \i Ctrl+Insert \i Copy the selected text to the clipboard.
+ \row \i Ctrl+K \i Deletes to the end of the line.
+ \row \i Ctrl+V \i Pastes the clipboard text into text edit.
+ \row \i Shift+Insert \i Pastes the clipboard text into text edit.
+ \row \i Ctrl+X \i Deletes the selected text and copies it to the clipboard.
+ \row \i Shift+Delete \i Deletes the selected text and copies it to the clipboard.
+ \row \i Ctrl+Z \i Undoes the last operation.
+ \row \i Ctrl+Y \i Redoes the last operation.
+ \row \i LeftArrow \i Moves the cursor one character to the left.
+ \row \i Ctrl+LeftArrow \i Moves the cursor one word to the left.
+ \row \i RightArrow \i Moves the cursor one character to the right.
+ \row \i Ctrl+RightArrow \i Moves the cursor one word to the right.
+ \row \i UpArrow \i Moves the cursor one line up.
+ \row \i Ctrl+UpArrow \i Moves the cursor one word up.
+ \row \i DownArrow \i Moves the cursor one line down.
+ \row \i Ctrl+Down Arrow \i Moves the cursor one word down.
+ \row \i PageUp \i Moves the cursor one page up.
+ \row \i PageDown \i Moves the cursor one page down.
+ \row \i Home \i Moves the cursor to the beginning of the line.
+ \row \i Ctrl+Home \i Moves the cursor to the beginning of the text.
+ \row \i End \i Moves the cursor to the end of the line.
+ \row \i Ctrl+End \i Moves the cursor to the end of the text.
+ \row \i Alt+Wheel \i Scrolls the page horizontally (the Wheel is the mouse wheel).
+ \row \i Ctrl+Wheel \i Zooms the text.
+ \endtable
+
+ To select (mark) text hold down the Shift key whilst pressing one
+ of the movement keystrokes, for example, \e{Shift+Right Arrow}
+ will select the character to the right, and \e{Shift+Ctrl+Right
+ Arrow} will select the word to the right, etc.
+
+ \section1 Differences to QTextEdit
+
+ QPlainTextEdit is a thin class, implemented by using most of the
+ technology that is behind QTextEdit and QTextDocument. Its
+ performance benefits over QTextEdit stem mostly from using a
+ different and simplified text layout called
+ QPlainTextDocumentLayout on the text document (see
+ QTextDocument::setDocumentLayout()). The plain text document layout
+ does not support tables nor embedded frames, and \e{replaces a
+ pixel-exact height calculation with a line-by-line respectively
+ paragraph-by-paragraph scrolling approach}. This makes it possible
+ to handle significantly larger documents, and still resize the
+ editor with line wrap enabled in real time. It also makes for a
+ fast log viewer (see setMaximumBlockCount()).
+
+
+ \sa QTextDocument, QTextCursor, {Application Example},
+ {Code Editor Example}, {Syntax Highlighter Example},
+ {Rich Text Processing}
+
+*/
+
+/*!
+ \property QPlainTextEdit::plainText
+
+ This property gets and sets the plain text editor's contents. The previous
+ contents are removed and undo/redo history is reset when this property is set.
+
+ By default, for an editor with no contents, this property contains an empty string.
+*/
+
+/*!
+ \property QPlainTextEdit::undoRedoEnabled
+ \brief whether undo and redo are enabled
+
+ Users are only able to undo or redo actions if this property is
+ true, and if there is an action that can be undone (or redone).
+
+ By default, this property is true.
+*/
+
+/*!
+ \enum QPlainTextEdit::LineWrapMode
+
+ \value NoWrap
+ \value WidgetWidth
+*/
+
+
+/*!
+ Constructs an empty QPlainTextEdit with parent \a
+ parent.
+*/
+QPlainTextEdit::QPlainTextEdit(QWidget *parent)
+ : QAbstractScrollArea(*new QPlainTextEditPrivate, parent)
+{
+ Q_D(QPlainTextEdit);
+ d->init();
+}
+
+/*!
+ \internal
+*/
+QPlainTextEdit::QPlainTextEdit(QPlainTextEditPrivate &dd, QWidget *parent)
+ : QAbstractScrollArea(dd, parent)
+{
+ Q_D(QPlainTextEdit);
+ d->init();
+}
+
+/*!
+ Constructs a QPlainTextEdit with parent \a parent. The text edit will display
+ the plain text \a text.
+*/
+QPlainTextEdit::QPlainTextEdit(const QString &text, QWidget *parent)
+ : QAbstractScrollArea(*new QPlainTextEditPrivate, parent)
+{
+ Q_D(QPlainTextEdit);
+ d->init(text);
+}
+
+
+/*!
+ Destructor.
+*/
+QPlainTextEdit::~QPlainTextEdit()
+{
+ Q_D(QPlainTextEdit);
+ if (d->documentLayoutPtr) {
+ if (d->documentLayoutPtr->priv()->mainViewPrivate == d)
+ d->documentLayoutPtr->priv()->mainViewPrivate = 0;
+ }
+}
+
+/*!
+ Makes \a document the new document of the text editor.
+
+ The parent QObject of the provided document remains the owner
+ of the object. If the current document is a child of the text
+ editor, then it is deleted.
+
+ The document must have a document layout that inherits
+ QPlainTextDocumentLayout (see QTextDocument::setDocumentLayout()).
+
+ \sa document()
+*/
+void QPlainTextEdit::setDocument(QTextDocument *document)
+{
+ Q_D(QPlainTextEdit);
+ QPlainTextDocumentLayout *documentLayout = 0;
+
+ if (!document) {
+ document = new QTextDocument(d->control);
+ documentLayout = new QPlainTextDocumentLayout(document);
+ document->setDocumentLayout(documentLayout);
+ } else {
+ documentLayout = qobject_cast<QPlainTextDocumentLayout*>(document->documentLayout());
+ if (!documentLayout) {
+ qWarning("QPlainTextEdit::setDocument: Document set does not support QPlainTextDocumentLayout");
+ return;
+ }
+ }
+ d->control->setDocument(document);
+ if (!documentLayout->priv()->mainViewPrivate)
+ documentLayout->priv()->mainViewPrivate = d;
+ d->documentLayoutPtr = documentLayout;
+ d->updateDefaultTextOption();
+ d->relayoutDocument();
+ d->_q_adjustScrollbars();
+}
+
+/*!
+ Returns a pointer to the underlying document.
+
+ \sa setDocument()
+*/
+QTextDocument *QPlainTextEdit::document() const
+{
+ Q_D(const QPlainTextEdit);
+ return d->control->document();
+}
+
+/*!
+ Sets the visible \a cursor.
+*/
+void QPlainTextEdit::setTextCursor(const QTextCursor &cursor)
+{
+ Q_D(QPlainTextEdit);
+ d->control->setTextCursor(cursor);
+}
+
+/*!
+ Returns a copy of the QTextCursor that represents the currently visible cursor.
+ Note that changes on the returned cursor do not affect QPlainTextEdit's cursor; use
+ setTextCursor() to update the visible cursor.
+ */
+QTextCursor QPlainTextEdit::textCursor() const
+{
+ Q_D(const QPlainTextEdit);
+ return d->control->textCursor();
+}
+
+/*!
+ Returns the reference of the anchor at position \a pos, or an
+ empty string if no anchor exists at that point.
+
+ \since 4.7
+ */
+QString QPlainTextEdit::anchorAt(const QPoint &pos) const
+{
+ Q_D(const QPlainTextEdit);
+ int cursorPos = d->control->hitTest(pos + QPoint(d->horizontalOffset(),
+ d->verticalOffset()),
+ Qt::ExactHit);
+ if (cursorPos < 0)
+ return QString();
+
+ QTextDocumentPrivate *pieceTable = document()->docHandle();
+ QTextDocumentPrivate::FragmentIterator it = pieceTable->find(cursorPos);
+ QTextCharFormat fmt = pieceTable->formatCollection()->charFormat(it->format);
+ return fmt.anchorHref();
+}
+
+/*!
+ Undoes the last operation.
+
+ If there is no operation to undo, i.e. there is no undo step in
+ the undo/redo history, nothing happens.
+
+ \sa redo()
+*/
+void QPlainTextEdit::undo()
+{
+ Q_D(QPlainTextEdit);
+ d->control->undo();
+}
+
+void QPlainTextEdit::redo()
+{
+ Q_D(QPlainTextEdit);
+ d->control->redo();
+}
+
+/*!
+ \fn void QPlainTextEdit::redo()
+
+ Redoes the last operation.
+
+ If there is no operation to redo, i.e. there is no redo step in
+ the undo/redo history, nothing happens.
+
+ \sa undo()
+*/
+
+#ifndef QT_NO_CLIPBOARD
+/*!
+ Copies the selected text to the clipboard and deletes it from
+ the text edit.
+
+ If there is no selected text nothing happens.
+
+ \sa copy() paste()
+*/
+
+void QPlainTextEdit::cut()
+{
+ Q_D(QPlainTextEdit);
+ d->control->cut();
+}
+
+/*!
+ Copies any selected text to the clipboard.
+
+ \sa copyAvailable()
+*/
+
+void QPlainTextEdit::copy()
+{
+ Q_D(QPlainTextEdit);
+ d->control->copy();
+}
+
+/*!
+ Pastes the text from the clipboard into the text edit at the
+ current cursor position.
+
+ If there is no text in the clipboard nothing happens.
+
+ To change the behavior of this function, i.e. to modify what
+ QPlainTextEdit can paste and how it is being pasted, reimplement the
+ virtual canInsertFromMimeData() and insertFromMimeData()
+ functions.
+
+ \sa cut() copy()
+*/
+
+void QPlainTextEdit::paste()
+{
+ Q_D(QPlainTextEdit);
+ d->control->paste();
+}
+#endif
+
+/*!
+ Deletes all the text in the text edit.
+
+ Note that the undo/redo history is cleared by this function.
+
+ \sa cut() setPlainText()
+*/
+void QPlainTextEdit::clear()
+{
+ Q_D(QPlainTextEdit);
+ // clears and sets empty content
+ d->control->topBlock = d->topLine = 0;
+ d->control->clear();
+}
+
+
+/*!
+ Selects all text.
+
+ \sa copy() cut() textCursor()
+ */
+void QPlainTextEdit::selectAll()
+{
+ Q_D(QPlainTextEdit);
+ d->control->selectAll();
+}
+
+/*! \internal
+*/
+bool QPlainTextEdit::event(QEvent *e)
+{
+ Q_D(QPlainTextEdit);
+
+#ifndef QT_NO_CONTEXTMENU
+ if (e->type() == QEvent::ContextMenu
+ && static_cast<QContextMenuEvent *>(e)->reason() == QContextMenuEvent::Keyboard) {
+ ensureCursorVisible();
+ const QPoint cursorPos = cursorRect().center();
+ QContextMenuEvent ce(QContextMenuEvent::Keyboard, cursorPos, d->viewport->mapToGlobal(cursorPos));
+ ce.setAccepted(e->isAccepted());
+ const bool result = QAbstractScrollArea::event(&ce);
+ e->setAccepted(ce.isAccepted());
+ return result;
+ }
+#endif // QT_NO_CONTEXTMENU
+ if (e->type() == QEvent::ShortcutOverride
+ || e->type() == QEvent::ToolTip) {
+ d->sendControlEvent(e);
+ }
+#ifdef QT_KEYPAD_NAVIGATION
+ else if (e->type() == QEvent::EnterEditFocus || e->type() == QEvent::LeaveEditFocus) {
+ if (QApplication::keypadNavigationEnabled())
+ d->sendControlEvent(e);
+ }
+#endif
+#ifndef QT_NO_GESTURES
+ else if (e->type() == QEvent::Gesture) {
+ QGestureEvent *ge = static_cast<QGestureEvent *>(e);
+ QPanGesture *g = static_cast<QPanGesture *>(ge->gesture(Qt::PanGesture));
+ if (g) {
+ QScrollBar *hBar = horizontalScrollBar();
+ QScrollBar *vBar = verticalScrollBar();
+ if (g->state() == Qt::GestureStarted)
+ d->originalOffsetY = vBar->value();
+ QPointF offset = g->offset();
+ if (!offset.isNull()) {
+ if (QApplication::isRightToLeft())
+ offset.rx() *= -1;
+ // QPlainTextEdit scrolls by lines only in vertical direction
+ QFontMetrics fm(document()->defaultFont());
+ int lineHeight = fm.height();
+ int newX = hBar->value() - g->delta().x();
+ int newY = d->originalOffsetY - offset.y()/lineHeight;
+ hBar->setValue(newX);
+ vBar->setValue(newY);
+ }
+ }
+ return true;
+ }
+#endif // QT_NO_GESTURES
+ return QAbstractScrollArea::event(e);
+}
+
+/*! \internal
+*/
+
+void QPlainTextEdit::timerEvent(QTimerEvent *e)
+{
+ Q_D(QPlainTextEdit);
+ if (e->timerId() == d->autoScrollTimer.timerId()) {
+ QRect visible = d->viewport->rect();
+ QPoint pos;
+ if (d->inDrag) {
+ pos = d->autoScrollDragPos;
+ visible.adjust(qMin(visible.width()/3,20), qMin(visible.height()/3,20),
+ -qMin(visible.width()/3,20), -qMin(visible.height()/3,20));
+ } else {
+ const QPoint globalPos = QCursor::pos();
+ pos = d->viewport->mapFromGlobal(globalPos);
+ QMouseEvent ev(QEvent::MouseMove, pos, d->viewport->mapTo(d->viewport->topLevelWidget(), pos), globalPos,
+ Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
+ mouseMoveEvent(&ev);
+ }
+ int deltaY = qMax(pos.y() - visible.top(), visible.bottom() - pos.y()) - visible.height();
+ int deltaX = qMax(pos.x() - visible.left(), visible.right() - pos.x()) - visible.width();
+ int delta = qMax(deltaX, deltaY);
+ if (delta >= 0) {
+ if (delta < 7)
+ delta = 7;
+ int timeout = 4900 / (delta * delta);
+ d->autoScrollTimer.start(timeout, this);
+
+ if (deltaY > 0)
+ d->vbar->triggerAction(pos.y() < visible.center().y() ?
+ QAbstractSlider::SliderSingleStepSub
+ : QAbstractSlider::SliderSingleStepAdd);
+ if (deltaX > 0)
+ d->hbar->triggerAction(pos.x() < visible.center().x() ?
+ QAbstractSlider::SliderSingleStepSub
+ : QAbstractSlider::SliderSingleStepAdd);
+ }
+ }
+#ifdef QT_KEYPAD_NAVIGATION
+ else if (e->timerId() == d->deleteAllTimer.timerId()) {
+ d->deleteAllTimer.stop();
+ clear();
+ }
+#endif
+}
+
+/*!
+ Changes the text of the text edit to the string \a text.
+ Any previous text is removed.
+
+ \a text is interpreted as plain text.
+
+ Note that the undo/redo history is cleared by this function.
+
+ \sa toText()
+*/
+
+void QPlainTextEdit::setPlainText(const QString &text)
+{
+ Q_D(QPlainTextEdit);
+ d->control->setPlainText(text);
+}
+
+/*!
+ \fn QString QPlainTextEdit::toPlainText() const
+
+ Returns the text of the text edit as plain text.
+
+ \sa QPlainTextEdit::setPlainText()
+ */
+
+/*! \reimp
+*/
+void QPlainTextEdit::keyPressEvent(QKeyEvent *e)
+{
+ Q_D(QPlainTextEdit);
+
+#ifdef QT_KEYPAD_NAVIGATION
+ switch (e->key()) {
+ case Qt::Key_Select:
+ if (QApplication::keypadNavigationEnabled()) {
+ if (!(d->control->textInteractionFlags() & Qt::LinksAccessibleByKeyboard))
+ setEditFocus(!hasEditFocus());
+ else {
+ if (!hasEditFocus())
+ setEditFocus(true);
+ else {
+ QTextCursor cursor = d->control->textCursor();
+ QTextCharFormat charFmt = cursor.charFormat();
+ if (!cursor.hasSelection() || charFmt.anchorHref().isEmpty()) {
+ setEditFocus(false);
+ }
+ }
+ }
+ }
+ break;
+ case Qt::Key_Back:
+ case Qt::Key_No:
+ if (!QApplication::keypadNavigationEnabled()
+ || (QApplication::keypadNavigationEnabled() && !hasEditFocus())) {
+ e->ignore();
+ return;
+ }
+ break;
+ default:
+ if (QApplication::keypadNavigationEnabled()) {
+ if (!hasEditFocus() && !(e->modifiers() & Qt::ControlModifier)) {
+ if (e->text()[0].isPrint()) {
+ setEditFocus(true);
+ clear();
+ } else {
+ e->ignore();
+ return;
+ }
+ }
+ }
+ break;
+ }
+#endif
+
+#ifndef QT_NO_SHORTCUT
+
+ Qt::TextInteractionFlags tif = d->control->textInteractionFlags();
+
+ if (tif & Qt::TextSelectableByKeyboard){
+ if (e == QKeySequence::SelectPreviousPage) {
+ e->accept();
+ d->pageUpDown(QTextCursor::Up, QTextCursor::KeepAnchor);
+ return;
+ } else if (e ==QKeySequence::SelectNextPage) {
+ e->accept();
+ d->pageUpDown(QTextCursor::Down, QTextCursor::KeepAnchor);
+ return;
+ }
+ }
+ if (tif & (Qt::TextSelectableByKeyboard | Qt::TextEditable)) {
+ if (e == QKeySequence::MoveToPreviousPage) {
+ e->accept();
+ d->pageUpDown(QTextCursor::Up, QTextCursor::MoveAnchor);
+ return;
+ } else if (e == QKeySequence::MoveToNextPage) {
+ e->accept();
+ d->pageUpDown(QTextCursor::Down, QTextCursor::MoveAnchor);
+ return;
+ }
+ }
+
+ if (!(tif & Qt::TextEditable)) {
+ switch (e->key()) {
+ case Qt::Key_Space:
+ e->accept();
+ if (e->modifiers() & Qt::ShiftModifier)
+ d->vbar->triggerAction(QAbstractSlider::SliderPageStepSub);
+ else
+ d->vbar->triggerAction(QAbstractSlider::SliderPageStepAdd);
+ break;
+ default:
+ d->sendControlEvent(e);
+ if (!e->isAccepted() && e->modifiers() == Qt::NoModifier) {
+ if (e->key() == Qt::Key_Home) {
+ d->vbar->triggerAction(QAbstractSlider::SliderToMinimum);
+ e->accept();
+ } else if (e->key() == Qt::Key_End) {
+ d->vbar->triggerAction(QAbstractSlider::SliderToMaximum);
+ e->accept();
+ }
+ }
+ if (!e->isAccepted()) {
+ QAbstractScrollArea::keyPressEvent(e);
+ }
+ }
+ return;
+ }
+#endif // QT_NO_SHORTCUT
+
+ d->sendControlEvent(e);
+#ifdef QT_KEYPAD_NAVIGATION
+ if (!e->isAccepted()) {
+ switch (e->key()) {
+ case Qt::Key_Up:
+ case Qt::Key_Down:
+ if (QApplication::keypadNavigationEnabled()) {
+ // Cursor position didn't change, so we want to leave
+ // these keys to change focus.
+ e->ignore();
+ return;
+ }
+ break;
+ case Qt::Key_Left:
+ case Qt::Key_Right:
+ if (QApplication::keypadNavigationEnabled()
+ && QApplication::navigationMode() == Qt::NavigationModeKeypadDirectional) {
+ // Same as for Key_Up and Key_Down.
+ e->ignore();
+ return;
+ }
+ break;
+ case Qt::Key_Back:
+ if (!e->isAutoRepeat()) {
+ if (QApplication::keypadNavigationEnabled()) {
+ if (document()->isEmpty()) {
+ setEditFocus(false);
+ e->accept();
+ } else if (!d->deleteAllTimer.isActive()) {
+ e->accept();
+ d->deleteAllTimer.start(750, this);
+ }
+ } else {
+ e->ignore();
+ return;
+ }
+ }
+ break;
+ default: break;
+ }
+ }
+#endif
+}
+
+/*! \reimp
+*/
+void QPlainTextEdit::keyReleaseEvent(QKeyEvent *e)
+{
+#ifdef QT_KEYPAD_NAVIGATION
+ Q_D(QPlainTextEdit);
+ if (QApplication::keypadNavigationEnabled()) {
+ if (!e->isAutoRepeat() && e->key() == Qt::Key_Back
+ && d->deleteAllTimer.isActive()) {
+ d->deleteAllTimer.stop();
+ QTextCursor cursor = d->control->textCursor();
+ QTextBlockFormat blockFmt = cursor.blockFormat();
+
+ QTextList *list = cursor.currentList();
+ if (list && cursor.atBlockStart()) {
+ list->remove(cursor.block());
+ } else if (cursor.atBlockStart() && blockFmt.indent() > 0) {
+ blockFmt.setIndent(blockFmt.indent() - 1);
+ cursor.setBlockFormat(blockFmt);
+ } else {
+ cursor.deletePreviousChar();
+ }
+ setTextCursor(cursor);
+ }
+ }
+#else
+ Q_UNUSED(e);
+#endif
+}
+
+/*!
+ Loads the resource specified by the given \a type and \a name.
+
+ This function is an extension of QTextDocument::loadResource().
+
+ \sa QTextDocument::loadResource()
+*/
+QVariant QPlainTextEdit::loadResource(int type, const QUrl &name)
+{
+ Q_UNUSED(type);
+ Q_UNUSED(name);
+ return QVariant();
+}
+
+/*! \reimp
+*/
+void QPlainTextEdit::resizeEvent(QResizeEvent *e)
+{
+ Q_D(QPlainTextEdit);
+ if (e->oldSize().width() != e->size().width())
+ d->relayoutDocument();
+ d->_q_adjustScrollbars();
+}
+
+void QPlainTextEditPrivate::relayoutDocument()
+{
+ QTextDocument *doc = control->document();
+ QPlainTextDocumentLayout *documentLayout = qobject_cast<QPlainTextDocumentLayout*>(doc->documentLayout());
+ Q_ASSERT(documentLayout);
+ documentLayoutPtr = documentLayout;
+
+ int width = viewport->width();
+
+ if (documentLayout->priv()->mainViewPrivate == 0
+ || documentLayout->priv()->mainViewPrivate == this
+ || width > documentLayout->textWidth()) {
+ documentLayout->priv()->mainViewPrivate = this;
+ documentLayout->setTextWidth(width);
+ }
+}
+
+static void fillBackground(QPainter *p, const QRectF &rect, QBrush brush, QRectF gradientRect = QRectF())
+{
+ p->save();
+ if (brush.style() >= Qt::LinearGradientPattern && brush.style() <= Qt::ConicalGradientPattern) {
+ if (!gradientRect.isNull()) {
+ QTransform m = QTransform::fromTranslate(gradientRect.left(), gradientRect.top());
+ m.scale(gradientRect.width(), gradientRect.height());
+ brush.setTransform(m);
+ const_cast<QGradient *>(brush.gradient())->setCoordinateMode(QGradient::LogicalMode);
+ }
+ } else {
+ p->setBrushOrigin(rect.topLeft());
+ }
+ p->fillRect(rect, brush);
+ p->restore();
+}
+
+
+
+/*! \reimp
+*/
+void QPlainTextEdit::paintEvent(QPaintEvent *e)
+{
+ QPainter painter(viewport());
+ Q_ASSERT(qobject_cast<QPlainTextDocumentLayout*>(document()->documentLayout()));
+
+ QPointF offset(contentOffset());
+
+ QRect er = e->rect();
+ QRect viewportRect = viewport()->rect();
+
+ bool editable = !isReadOnly();
+
+ QTextBlock block = firstVisibleBlock();
+ qreal maximumWidth = document()->documentLayout()->documentSize().width();
+
+ // Set a brush origin so that the WaveUnderline knows where the wave started
+ painter.setBrushOrigin(offset);
+
+ // keep right margin clean from full-width selection
+ int maxX = offset.x() + qMax((qreal)viewportRect.width(), maximumWidth)
+ - document()->documentMargin();
+ er.setRight(qMin(er.right(), maxX));
+ painter.setClipRect(er);
+
+
+ QAbstractTextDocumentLayout::PaintContext context = getPaintContext();
+
+ while (block.isValid()) {
+
+ QRectF r = blockBoundingRect(block).translated(offset);
+ QTextLayout *layout = block.layout();
+
+ if (!block.isVisible()) {
+ offset.ry() += r.height();
+ block = block.next();
+ continue;
+ }
+
+ if (r.bottom() >= er.top() && r.top() <= er.bottom()) {
+
+ QTextBlockFormat blockFormat = block.blockFormat();
+
+ QBrush bg = blockFormat.background();
+ if (bg != Qt::NoBrush) {
+ QRectF contentsRect = r;
+ contentsRect.setWidth(qMax(r.width(), maximumWidth));
+ fillBackground(&painter, contentsRect, bg);
+ }
+
+
+ QVector<QTextLayout::FormatRange> selections;
+ int blpos = block.position();
+ int bllen = block.length();
+ for (int i = 0; i < context.selections.size(); ++i) {
+ const QAbstractTextDocumentLayout::Selection &range = context.selections.at(i);
+ const int selStart = range.cursor.selectionStart() - blpos;
+ const int selEnd = range.cursor.selectionEnd() - blpos;
+ if (selStart < bllen && selEnd > 0
+ && selEnd > selStart) {
+ QTextLayout::FormatRange o;
+ o.start = selStart;
+ o.length = selEnd - selStart;
+ o.format = range.format;
+ selections.append(o);
+ } else if (!range.cursor.hasSelection() && range.format.hasProperty(QTextFormat::FullWidthSelection)
+ && block.contains(range.cursor.position())) {
+ // for full width selections we don't require an actual selection, just
+ // a position to specify the line. that's more convenience in usage.
+ QTextLayout::FormatRange o;
+ QTextLine l = layout->lineForTextPosition(range.cursor.position() - blpos);
+ o.start = l.textStart();
+ o.length = l.textLength();
+ if (o.start + o.length == bllen - 1)
+ ++o.length; // include newline
+ o.format = range.format;
+ selections.append(o);
+ }
+ }
+
+ bool drawCursor = (editable
+ && context.cursorPosition >= blpos
+ && context.cursorPosition < blpos + bllen);
+
+ bool drawCursorAsBlock = drawCursor && overwriteMode() ;
+
+ if (drawCursorAsBlock) {
+ if (context.cursorPosition == blpos + bllen - 1) {
+ drawCursorAsBlock = false;
+ } else {
+ QTextLayout::FormatRange o;
+ o.start = context.cursorPosition - blpos;
+ o.length = 1;
+ o.format.setForeground(palette().base());
+ o.format.setBackground(palette().text());
+ selections.append(o);
+ }
+ }
+
+
+ layout->draw(&painter, offset, selections, er);
+ if ((drawCursor && !drawCursorAsBlock)
+ || (editable && context.cursorPosition < -1
+ && !layout->preeditAreaText().isEmpty())) {
+ int cpos = context.cursorPosition;
+ if (cpos < -1)
+ cpos = layout->preeditAreaPosition() - (cpos + 2);
+ else
+ cpos -= blpos;
+ layout->drawCursor(&painter, offset, cpos, cursorWidth());
+ }
+ }
+
+ offset.ry() += r.height();
+ if (offset.y() > viewportRect.height())
+ break;
+ block = block.next();
+ }
+
+ if (backgroundVisible() && !block.isValid() && offset.y() <= er.bottom()
+ && (centerOnScroll() || verticalScrollBar()->maximum() == verticalScrollBar()->minimum())) {
+ painter.fillRect(QRect(QPoint((int)er.left(), (int)offset.y()), er.bottomRight()), palette().background());
+ }
+}
+
+
+void QPlainTextEditPrivate::updateDefaultTextOption()
+{
+ QTextDocument *doc = control->document();
+
+ QTextOption opt = doc->defaultTextOption();
+ QTextOption::WrapMode oldWrapMode = opt.wrapMode();
+
+ if (lineWrap == QPlainTextEdit::NoWrap)
+ opt.setWrapMode(QTextOption::NoWrap);
+ else
+ opt.setWrapMode(wordWrap);
+
+ if (opt.wrapMode() != oldWrapMode)
+ doc->setDefaultTextOption(opt);
+}
+
+
+/*! \reimp
+*/
+void QPlainTextEdit::mousePressEvent(QMouseEvent *e)
+{
+ Q_D(QPlainTextEdit);
+#ifdef QT_KEYPAD_NAVIGATION
+ if (QApplication::keypadNavigationEnabled() && !hasEditFocus())
+ setEditFocus(true);
+#endif
+ d->sendControlEvent(e);
+}
+
+/*! \reimp
+*/
+void QPlainTextEdit::mouseMoveEvent(QMouseEvent *e)
+{
+ Q_D(QPlainTextEdit);
+ d->inDrag = false; // paranoia
+ const QPoint pos = e->pos();
+ d->sendControlEvent(e);
+ if (!(e->buttons() & Qt::LeftButton))
+ return;
+ QRect visible = d->viewport->rect();
+ if (visible.contains(pos))
+ d->autoScrollTimer.stop();
+ else if (!d->autoScrollTimer.isActive())
+ d->autoScrollTimer.start(100, this);
+}
+
+/*! \reimp
+*/
+void QPlainTextEdit::mouseReleaseEvent(QMouseEvent *e)
+{
+ Q_D(QPlainTextEdit);
+ d->sendControlEvent(e);
+ if (d->autoScrollTimer.isActive()) {
+ d->autoScrollTimer.stop();
+ d->ensureCursorVisible();
+ }
+
+ if (!isReadOnly() && rect().contains(e->pos()))
+ d->handleSoftwareInputPanel(e->button(), d->clickCausedFocus);
+ d->clickCausedFocus = 0;
+}
+
+/*! \reimp
+*/
+void QPlainTextEdit::mouseDoubleClickEvent(QMouseEvent *e)
+{
+ Q_D(QPlainTextEdit);
+ d->sendControlEvent(e);
+}
+
+/*! \reimp
+*/
+bool QPlainTextEdit::focusNextPrevChild(bool next)
+{
+ Q_D(const QPlainTextEdit);
+ if (!d->tabChangesFocus && d->control->textInteractionFlags() & Qt::TextEditable)
+ return false;
+ return QAbstractScrollArea::focusNextPrevChild(next);
+}
+
+#ifndef QT_NO_CONTEXTMENU
+/*!
+ \fn void QPlainTextEdit::contextMenuEvent(QContextMenuEvent *event)
+
+ Shows the standard context menu created with createStandardContextMenu().
+
+ If you do not want the text edit to have a context menu, you can set
+ its \l contextMenuPolicy to Qt::NoContextMenu. If you want to
+ customize the context menu, reimplement this function. If you want
+ to extend the standard context menu, reimplement this function, call
+ createStandardContextMenu() and extend the menu returned.
+
+ Information about the event is passed in the \a event object.
+
+ \snippet doc/src/snippets/code/src_gui_widgets_qplaintextedit.cpp 0
+*/
+void QPlainTextEdit::contextMenuEvent(QContextMenuEvent *e)
+{
+ Q_D(QPlainTextEdit);
+ d->sendControlEvent(e);
+}
+#endif // QT_NO_CONTEXTMENU
+
+#ifndef QT_NO_DRAGANDDROP
+/*! \reimp
+*/
+void QPlainTextEdit::dragEnterEvent(QDragEnterEvent *e)
+{
+ Q_D(QPlainTextEdit);
+ d->inDrag = true;
+ d->sendControlEvent(e);
+}
+
+/*! \reimp
+*/
+void QPlainTextEdit::dragLeaveEvent(QDragLeaveEvent *e)
+{
+ Q_D(QPlainTextEdit);
+ d->inDrag = false;
+ d->autoScrollTimer.stop();
+ d->sendControlEvent(e);
+}
+
+/*! \reimp
+*/
+void QPlainTextEdit::dragMoveEvent(QDragMoveEvent *e)
+{
+ Q_D(QPlainTextEdit);
+ d->autoScrollDragPos = e->pos();
+ if (!d->autoScrollTimer.isActive())
+ d->autoScrollTimer.start(100, this);
+ d->sendControlEvent(e);
+}
+
+/*! \reimp
+*/
+void QPlainTextEdit::dropEvent(QDropEvent *e)
+{
+ Q_D(QPlainTextEdit);
+ d->inDrag = false;
+ d->autoScrollTimer.stop();
+ d->sendControlEvent(e);
+}
+
+#endif // QT_NO_DRAGANDDROP
+
+/*! \reimp
+ */
+void QPlainTextEdit::inputMethodEvent(QInputMethodEvent *e)
+{
+ Q_D(QPlainTextEdit);
+#ifdef QT_KEYPAD_NAVIGATION
+ if (d->control->textInteractionFlags() & Qt::TextEditable
+ && QApplication::keypadNavigationEnabled()
+ && !hasEditFocus()) {
+ setEditFocus(true);
+ selectAll(); // so text is replaced rather than appended to
+ }
+#endif
+ d->sendControlEvent(e);
+ ensureCursorVisible();
+}
+
+/*!\reimp
+*/
+void QPlainTextEdit::scrollContentsBy(int dx, int /*dy*/)
+{
+ Q_D(QPlainTextEdit);
+ d->setTopLine(d->vbar->value(), dx);
+}
+
+/*!\reimp
+*/
+QVariant QPlainTextEdit::inputMethodQuery(Qt::InputMethodQuery property) const
+{
+ Q_D(const QPlainTextEdit);
+ QVariant v = d->control->inputMethodQuery(property);
+ const QPoint offset(-d->horizontalOffset(), -0);
+ if (v.type() == QVariant::RectF)
+ v = v.toRectF().toRect().translated(offset);
+ else if (v.type() == QVariant::PointF)
+ v = v.toPointF().toPoint() + offset;
+ else if (v.type() == QVariant::Rect)
+ v = v.toRect().translated(offset);
+ else if (v.type() == QVariant::Point)
+ v = v.toPoint() + offset;
+ return v;
+}
+
+/*! \reimp
+*/
+void QPlainTextEdit::focusInEvent(QFocusEvent *e)
+{
+ Q_D(QPlainTextEdit);
+ if (e->reason() == Qt::MouseFocusReason) {
+ d->clickCausedFocus = 1;
+ }
+ QAbstractScrollArea::focusInEvent(e);
+ d->sendControlEvent(e);
+}
+
+/*! \reimp
+*/
+void QPlainTextEdit::focusOutEvent(QFocusEvent *e)
+{
+ Q_D(QPlainTextEdit);
+ QAbstractScrollArea::focusOutEvent(e);
+ d->sendControlEvent(e);
+}
+
+/*! \reimp
+*/
+void QPlainTextEdit::showEvent(QShowEvent *)
+{
+ Q_D(QPlainTextEdit);
+ if (d->showCursorOnInitialShow) {
+ d->showCursorOnInitialShow = false;
+ ensureCursorVisible();
+ }
+}
+
+/*! \reimp
+*/
+void QPlainTextEdit::changeEvent(QEvent *e)
+{
+ Q_D(QPlainTextEdit);
+ QAbstractScrollArea::changeEvent(e);
+ if (e->type() == QEvent::ApplicationFontChange
+ || e->type() == QEvent::FontChange) {
+ d->control->document()->setDefaultFont(font());
+ } else if(e->type() == QEvent::ActivationChange) {
+ if (!isActiveWindow())
+ d->autoScrollTimer.stop();
+ } else if (e->type() == QEvent::EnabledChange) {
+ e->setAccepted(isEnabled());
+ d->sendControlEvent(e);
+ } else if (e->type() == QEvent::PaletteChange) {
+ d->control->setPalette(palette());
+ } else if (e->type() == QEvent::LayoutDirectionChange) {
+ d->sendControlEvent(e);
+ }
+}
+
+/*! \reimp
+*/
+#ifndef QT_NO_WHEELEVENT
+void QPlainTextEdit::wheelEvent(QWheelEvent *e)
+{
+ QAbstractScrollArea::wheelEvent(e);
+ updateMicroFocus();
+}
+#endif
+
+#ifndef QT_NO_CONTEXTMENU
+/*! This function creates the standard context menu which is shown
+ when the user clicks on the line edit with the right mouse
+ button. It is called from the default contextMenuEvent() handler.
+ The popup menu's ownership is transferred to the caller.
+*/
+
+QMenu *QPlainTextEdit::createStandardContextMenu()
+{
+ Q_D(QPlainTextEdit);
+ return d->control->createStandardContextMenu(QPointF(), this);
+}
+#endif // QT_NO_CONTEXTMENU
+
+/*!
+ returns a QTextCursor at position \a pos (in viewport coordinates).
+*/
+QTextCursor QPlainTextEdit::cursorForPosition(const QPoint &pos) const
+{
+ Q_D(const QPlainTextEdit);
+ return d->control->cursorForPosition(d->mapToContents(pos));
+}
+
+/*!
+ returns a rectangle (in viewport coordinates) that includes the
+ \a cursor.
+ */
+QRect QPlainTextEdit::cursorRect(const QTextCursor &cursor) const
+{
+ Q_D(const QPlainTextEdit);
+ if (cursor.isNull())
+ return QRect();
+
+ QRect r = d->control->cursorRect(cursor).toRect();
+ r.translate(-d->horizontalOffset(),-d->verticalOffset());
+ return r;
+}
+
+/*!
+ returns a rectangle (in viewport coordinates) that includes the
+ cursor of the text edit.
+ */
+QRect QPlainTextEdit::cursorRect() const
+{
+ Q_D(const QPlainTextEdit);
+ QRect r = d->control->cursorRect().toRect();
+ r.translate(-d->horizontalOffset(),-d->verticalOffset());
+ return r;
+}
+
+
+/*!
+ \property QPlainTextEdit::overwriteMode
+ \brief whether text entered by the user will overwrite existing text
+
+ As with many text editors, the plain text editor widget can be configured
+ to insert or overwrite existing text with new text entered by the user.
+
+ If this property is true, existing text is overwritten, character-for-character
+ by new text; otherwise, text is inserted at the cursor position, displacing
+ existing text.
+
+ By default, this property is false (new text does not overwrite existing text).
+*/
+
+bool QPlainTextEdit::overwriteMode() const
+{
+ Q_D(const QPlainTextEdit);
+ return d->control->overwriteMode();
+}
+
+void QPlainTextEdit::setOverwriteMode(bool overwrite)
+{
+ Q_D(QPlainTextEdit);
+ d->control->setOverwriteMode(overwrite);
+}
+
+/*!
+ \property QPlainTextEdit::tabStopWidth
+ \brief the tab stop width in pixels
+
+ By default, this property contains a value of 80.
+*/
+
+int QPlainTextEdit::tabStopWidth() const
+{
+ Q_D(const QPlainTextEdit);
+ return qRound(d->control->document()->defaultTextOption().tabStop());
+}
+
+void QPlainTextEdit::setTabStopWidth(int width)
+{
+ Q_D(QPlainTextEdit);
+ QTextOption opt = d->control->document()->defaultTextOption();
+ if (opt.tabStop() == width || width < 0)
+ return;
+ opt.setTabStop(width);
+ d->control->document()->setDefaultTextOption(opt);
+}
+
+/*!
+ \property QPlainTextEdit::cursorWidth
+
+ This property specifies the width of the cursor in pixels. The default value is 1.
+*/
+int QPlainTextEdit::cursorWidth() const
+{
+ Q_D(const QPlainTextEdit);
+ return d->control->cursorWidth();
+}
+
+void QPlainTextEdit::setCursorWidth(int width)
+{
+ Q_D(QPlainTextEdit);
+ d->control->setCursorWidth(width);
+}
+
+
+
+/*!
+ This function allows temporarily marking certain regions in the document
+ with a given color, specified as \a selections. This can be useful for
+ example in a programming editor to mark a whole line of text with a given
+ background color to indicate the existence of a breakpoint.
+
+ \sa QTextEdit::ExtraSelection, extraSelections()
+*/
+void QPlainTextEdit::setExtraSelections(const QList<QTextEdit::ExtraSelection> &selections)
+{
+ Q_D(QPlainTextEdit);
+ d->control->setExtraSelections(selections);
+}
+
+/*!
+ Returns previously set extra selections.
+
+ \sa setExtraSelections()
+*/
+QList<QTextEdit::ExtraSelection> QPlainTextEdit::extraSelections() const
+{
+ Q_D(const QPlainTextEdit);
+ return d->control->extraSelections();
+}
+
+/*!
+ This function returns a new MIME data object to represent the contents
+ of the text edit's current selection. It is called when the selection needs
+ to be encapsulated into a new QMimeData object; for example, when a drag
+ and drop operation is started, or when data is copied to the clipboard.
+
+ If you reimplement this function, note that the ownership of the returned
+ QMimeData object is passed to the caller. The selection can be retrieved
+ by using the textCursor() function.
+*/
+QMimeData *QPlainTextEdit::createMimeDataFromSelection() const
+{
+ Q_D(const QPlainTextEdit);
+ return d->control->QWidgetTextControl::createMimeDataFromSelection();
+}
+
+/*!
+ This function returns true if the contents of the MIME data object, specified
+ by \a source, can be decoded and inserted into the document. It is called
+ for example when during a drag operation the mouse enters this widget and it
+ is necessary to determine whether it is possible to accept the drag.
+ */
+bool QPlainTextEdit::canInsertFromMimeData(const QMimeData *source) const
+{
+ Q_D(const QPlainTextEdit);
+ return d->control->QWidgetTextControl::canInsertFromMimeData(source);
+}
+
+/*!
+ This function inserts the contents of the MIME data object, specified
+ by \a source, into the text edit at the current cursor position. It is
+ called whenever text is inserted as the result of a clipboard paste
+ operation, or when the text edit accepts data from a drag and drop
+ operation.
+*/
+void QPlainTextEdit::insertFromMimeData(const QMimeData *source)
+{
+ Q_D(QPlainTextEdit);
+ d->control->QWidgetTextControl::insertFromMimeData(source);
+}
+
+/*!
+ \property QPlainTextEdit::readOnly
+ \brief whether the text edit is read-only
+
+ In a read-only text edit the user can only navigate through the
+ text and select text; modifying the text is not possible.
+
+ This property's default is false.
+*/
+
+bool QPlainTextEdit::isReadOnly() const
+{
+ Q_D(const QPlainTextEdit);
+ return !(d->control->textInteractionFlags() & Qt::TextEditable);
+}
+
+void QPlainTextEdit::setReadOnly(bool ro)
+{
+ Q_D(QPlainTextEdit);
+ Qt::TextInteractionFlags flags = Qt::NoTextInteraction;
+ if (ro) {
+ flags = Qt::TextSelectableByMouse;
+ } else {
+ flags = Qt::TextEditorInteraction;
+ }
+ setAttribute(Qt::WA_InputMethodEnabled, shouldEnableInputMethod(this));
+ d->control->setTextInteractionFlags(flags);
+}
+
+/*!
+ \property QPlainTextEdit::textInteractionFlags
+
+ Specifies how the label should interact with user input if it displays text.
+
+ If the flags contain either Qt::LinksAccessibleByKeyboard or Qt::TextSelectableByKeyboard
+ then the focus policy is also automatically set to Qt::ClickFocus.
+
+ The default value depends on whether the QPlainTextEdit is read-only
+ or editable.
+*/
+
+void QPlainTextEdit::setTextInteractionFlags(Qt::TextInteractionFlags flags)
+{
+ Q_D(QPlainTextEdit);
+ d->control->setTextInteractionFlags(flags);
+}
+
+Qt::TextInteractionFlags QPlainTextEdit::textInteractionFlags() const
+{
+ Q_D(const QPlainTextEdit);
+ return d->control->textInteractionFlags();
+}
+
+/*!
+ Merges the properties specified in \a modifier into the current character
+ format by calling QTextCursor::mergeCharFormat on the editor's cursor.
+ If the editor has a selection then the properties of \a modifier are
+ directly applied to the selection.
+
+ \sa QTextCursor::mergeCharFormat()
+ */
+void QPlainTextEdit::mergeCurrentCharFormat(const QTextCharFormat &modifier)
+{
+ Q_D(QPlainTextEdit);
+ d->control->mergeCurrentCharFormat(modifier);
+}
+
+/*!
+ Sets the char format that is be used when inserting new text to \a
+ format by calling QTextCursor::setCharFormat() on the editor's
+ cursor. If the editor has a selection then the char format is
+ directly applied to the selection.
+ */
+void QPlainTextEdit::setCurrentCharFormat(const QTextCharFormat &format)
+{
+ Q_D(QPlainTextEdit);
+ d->control->setCurrentCharFormat(format);
+}
+
+/*!
+ Returns the char format that is used when inserting new text.
+ */
+QTextCharFormat QPlainTextEdit::currentCharFormat() const
+{
+ Q_D(const QPlainTextEdit);
+ return d->control->currentCharFormat();
+}
+
+
+
+/*!
+ Convenience slot that inserts \a text at the current
+ cursor position.
+
+ It is equivalent to
+
+ \snippet doc/src/snippets/code/src_gui_widgets_qplaintextedit.cpp 1
+ */
+void QPlainTextEdit::insertPlainText(const QString &text)
+{
+ Q_D(QPlainTextEdit);
+ d->control->insertPlainText(text);
+}
+
+
+/*!
+ Moves the cursor by performing the given \a operation.
+
+ If \a mode is QTextCursor::KeepAnchor, the cursor selects the text it moves over.
+ This is the same effect that the user achieves when they hold down the Shift key
+ and move the cursor with the cursor keys.
+
+ \sa QTextCursor::movePosition()
+*/
+void QPlainTextEdit::moveCursor(QTextCursor::MoveOperation operation, QTextCursor::MoveMode mode)
+{
+ Q_D(QPlainTextEdit);
+ d->control->moveCursor(operation, mode);
+}
+
+/*!
+ Returns whether text can be pasted from the clipboard into the textedit.
+*/
+bool QPlainTextEdit::canPaste() const
+{
+ Q_D(const QPlainTextEdit);
+ return d->control->canPaste();
+}
+
+/*!
+ Convenience function to print the text edit's document to the given \a printer. This
+ is equivalent to calling the print method on the document directly except that this
+ function also supports QPrinter::Selection as print range.
+
+ \sa QTextDocument::print()
+*/
+void QPlainTextEdit::print(QPagedPaintDevice *printer) const
+{
+ Q_D(const QPlainTextEdit);
+ d->control->print(printer);
+}
+
+/*! \property QPlainTextEdit::tabChangesFocus
+ \brief whether \gui Tab changes focus or is accepted as input
+
+ In some occasions text edits should not allow the user to input
+ tabulators or change indentation using the \gui Tab key, as this breaks
+ the focus chain. The default is false.
+
+*/
+
+bool QPlainTextEdit::tabChangesFocus() const
+{
+ Q_D(const QPlainTextEdit);
+ return d->tabChangesFocus;
+}
+
+void QPlainTextEdit::setTabChangesFocus(bool b)
+{
+ Q_D(QPlainTextEdit);
+ d->tabChangesFocus = b;
+}
+
+/*!
+ \property QPlainTextEdit::documentTitle
+ \brief the title of the document parsed from the text.
+
+ By default, this property contains an empty string.
+*/
+
+/*!
+ \property QPlainTextEdit::lineWrapMode
+ \brief the line wrap mode
+
+ The default mode is WidgetWidth which causes words to be
+ wrapped at the right edge of the text edit. Wrapping occurs at
+ whitespace, keeping whole words intact. If you want wrapping to
+ occur within words use setWordWrapMode().
+*/
+
+QPlainTextEdit::LineWrapMode QPlainTextEdit::lineWrapMode() const
+{
+ Q_D(const QPlainTextEdit);
+ return d->lineWrap;
+}
+
+void QPlainTextEdit::setLineWrapMode(LineWrapMode wrap)
+{
+ Q_D(QPlainTextEdit);
+ if (d->lineWrap == wrap)
+ return;
+ d->lineWrap = wrap;
+ d->updateDefaultTextOption();
+ d->relayoutDocument();
+ d->_q_adjustScrollbars();
+ ensureCursorVisible();
+}
+
+/*!
+ \property QPlainTextEdit::wordWrapMode
+ \brief the mode QPlainTextEdit will use when wrapping text by words
+
+ By default, this property is set to QTextOption::WrapAtWordBoundaryOrAnywhere.
+
+ \sa QTextOption::WrapMode
+*/
+
+QTextOption::WrapMode QPlainTextEdit::wordWrapMode() const
+{
+ Q_D(const QPlainTextEdit);
+ return d->wordWrap;
+}
+
+void QPlainTextEdit::setWordWrapMode(QTextOption::WrapMode mode)
+{
+ Q_D(QPlainTextEdit);
+ if (mode == d->wordWrap)
+ return;
+ d->wordWrap = mode;
+ d->updateDefaultTextOption();
+}
+
+/*!
+ \property QPlainTextEdit::backgroundVisible
+ \brief whether the palette background is visible outside the document area
+
+ If set to true, the plain text edit paints the palette background
+ on the viewport area not covered by the text document. Otherwise,
+ if set to false, it won't. The feature makes it possible for
+ the user to visually distinguish between the area of the document,
+ painted with the base color of the palette, and the empty
+ area not covered by any document.
+
+ The default is false.
+*/
+
+bool QPlainTextEdit::backgroundVisible() const
+{
+ Q_D(const QPlainTextEdit);
+ return d->backgroundVisible;
+}
+
+void QPlainTextEdit::setBackgroundVisible(bool visible)
+{
+ Q_D(QPlainTextEdit);
+ if (visible == d->backgroundVisible)
+ return;
+ d->backgroundVisible = visible;
+ d->updateViewport();
+}
+
+/*!
+ \property QPlainTextEdit::centerOnScroll
+ \brief whether the cursor should be centered on screen
+
+ If set to true, the plain text edit scrolls the document
+ vertically to make the cursor visible at the center of the
+ viewport. This also allows the text edit to scroll below the end
+ of the document. Otherwise, if set to false, the plain text edit
+ scrolls the smallest amount possible to ensure the cursor is
+ visible. The same algorithm is applied to any new line appended
+ through appendPlainText().
+
+ The default is false.
+
+ \sa centerCursor(), ensureCursorVisible()
+*/
+
+bool QPlainTextEdit::centerOnScroll() const
+{
+ Q_D(const QPlainTextEdit);
+ return d->centerOnScroll;
+}
+
+void QPlainTextEdit::setCenterOnScroll(bool enabled)
+{
+ Q_D(QPlainTextEdit);
+ if (enabled == d->centerOnScroll)
+ return;
+ d->centerOnScroll = enabled;
+}
+
+
+
+/*!
+ Finds the next occurrence of the string, \a exp, using the given
+ \a options. Returns true if \a exp was found and changes the
+ cursor to select the match; otherwise returns false.
+*/
+bool QPlainTextEdit::find(const QString &exp, QTextDocument::FindFlags options)
+{
+ Q_D(QPlainTextEdit);
+ return d->control->find(exp, options);
+}
+
+/*!
+ \fn void QPlainTextEdit::copyAvailable(bool yes)
+
+ This signal is emitted when text is selected or de-selected in the
+ text edit.
+
+ When text is selected this signal will be emitted with \a yes set
+ to true. If no text has been selected or if the selected text is
+ de-selected this signal is emitted with \a yes set to false.
+
+ If \a yes is true then copy() can be used to copy the selection to
+ the clipboard. If \a yes is false then copy() does nothing.
+
+ \sa selectionChanged()
+*/
+
+
+/*!
+ \fn void QPlainTextEdit::selectionChanged()
+
+ This signal is emitted whenever the selection changes.
+
+ \sa copyAvailable()
+*/
+
+/*!
+ \fn void QPlainTextEdit::cursorPositionChanged()
+
+ This signal is emitted whenever the position of the
+ cursor changed.
+*/
+
+
+
+/*!
+ \fn void QPlainTextEdit::updateRequest(const QRect &rect, int dy)
+
+ This signal is emitted when the text document needs an update of
+ the specified \a rect. If the text is scrolled, \a rect will cover
+ the entire viewport area. If the text is scrolled vertically, \a
+ dy carries the amount of pixels the viewport was scrolled.
+
+ The purpose of the signal is to support extra widgets in plain
+ text edit subclasses that e.g. show line numbers, breakpoints, or
+ other extra information.
+*/
+
+/*! \fn void QPlainTextEdit::blockCountChanged(int newBlockCount);
+
+ This signal is emitted whenever the block count changes. The new
+ block count is passed in \a newBlockCount.
+*/
+
+/*! \fn void QPlainTextEdit::modificationChanged(bool changed);
+
+ This signal is emitted whenever the content of the document
+ changes in a way that affects the modification state. If \a
+ changed is true, the document has been modified; otherwise it is
+ false.
+
+ For example, calling setModified(false) on a document and then
+ inserting text causes the signal to get emitted. If you undo that
+ operation, causing the document to return to its original
+ unmodified state, the signal will get emitted again.
+*/
+
+
+
+
+void QPlainTextEditPrivate::append(const QString &text, Qt::TextFormat format)
+{
+ Q_Q(QPlainTextEdit);
+
+ QTextDocument *document = control->document();
+ QPlainTextDocumentLayout *documentLayout = qobject_cast<QPlainTextDocumentLayout*>(document->documentLayout());
+ Q_ASSERT(documentLayout);
+
+ int maximumBlockCount = document->maximumBlockCount();
+ if (maximumBlockCount)
+ document->setMaximumBlockCount(0);
+
+ const bool atBottom = q->isVisible()
+ && (control->blockBoundingRect(document->lastBlock()).bottom() - verticalOffset()
+ <= viewport->rect().bottom());
+
+ if (!q->isVisible())
+ showCursorOnInitialShow = true;
+
+ bool documentSizeChangedBlocked = documentLayout->priv()->blockDocumentSizeChanged;
+ documentLayout->priv()->blockDocumentSizeChanged = true;
+
+ if (format == Qt::RichText)
+ control->appendHtml(text);
+ else if (format == Qt::PlainText)
+ control->appendPlainText(text);
+ else
+ control->append(text);
+
+ if (maximumBlockCount > 0) {
+ if (document->blockCount() > maximumBlockCount) {
+ bool blockUpdate = false;
+ if (control->topBlock) {
+ control->topBlock--;
+ blockUpdate = true;
+ emit q->updateRequest(viewport->rect(), 0);
+ }
+
+ bool updatesBlocked = documentLayout->priv()->blockUpdate;
+ documentLayout->priv()->blockUpdate = blockUpdate;
+ QTextCursor cursor(document);
+ cursor.movePosition(QTextCursor::NextBlock, QTextCursor::KeepAnchor);
+ cursor.removeSelectedText();
+ documentLayout->priv()->blockUpdate = updatesBlocked;
+ }
+ document->setMaximumBlockCount(maximumBlockCount);
+ }
+
+ documentLayout->priv()->blockDocumentSizeChanged = documentSizeChangedBlocked;
+ _q_adjustScrollbars();
+
+
+ if (atBottom) {
+ const bool needScroll = !centerOnScroll
+ || control->blockBoundingRect(document->lastBlock()).bottom() - verticalOffset()
+ > viewport->rect().bottom();
+ if (needScroll)
+ vbar->setValue(vbar->maximum());
+ }
+}
+
+
+/*!
+ Appends a new paragraph with \a text to the end of the text edit.
+
+ \sa appendHtml()
+*/
+
+void QPlainTextEdit::appendPlainText(const QString &text)
+{
+ Q_D(QPlainTextEdit);
+ d->append(text, Qt::PlainText);
+}
+
+/*!
+ Appends a new paragraph with \a html to the end of the text edit.
+
+ appendPlainText()
+*/
+
+void QPlainTextEdit::appendHtml(const QString &html)
+{
+ Q_D(QPlainTextEdit);
+ d->append(html, Qt::RichText);
+}
+
+void QPlainTextEditPrivate::ensureCursorVisible(bool center)
+{
+ Q_Q(QPlainTextEdit);
+ QRect visible = viewport->rect();
+ QRect cr = q->cursorRect();
+ if (cr.top() < visible.top() || cr.bottom() > visible.bottom()) {
+ ensureVisible(control->textCursor().position(), center);
+ }
+
+ const bool rtl = q->isRightToLeft();
+ if (cr.left() < visible.left() || cr.right() > visible.right()) {
+ int x = cr.center().x() + horizontalOffset() - visible.width()/2;
+ hbar->setValue(rtl ? hbar->maximum() - x : x);
+ }
+}
+
+/*!
+ Ensures that the cursor is visible by scrolling the text edit if
+ necessary.
+
+ \sa centerCursor(), centerOnScroll
+*/
+void QPlainTextEdit::ensureCursorVisible()
+{
+ Q_D(QPlainTextEdit);
+ d->ensureCursorVisible(d->centerOnScroll);
+}
+
+
+/*! Scrolls the document in order to center the cursor vertically.
+
+\sa ensureCursorVisible(), centerOnScroll
+ */
+void QPlainTextEdit::centerCursor()
+{
+ Q_D(QPlainTextEdit);
+ d->ensureVisible(textCursor().position(), true, true);
+}
+
+/*!
+ Returns the first visible block.
+
+ \sa blockBoundingRect()
+ */
+QTextBlock QPlainTextEdit::firstVisibleBlock() const
+{
+ Q_D(const QPlainTextEdit);
+ return d->control->firstVisibleBlock();
+}
+
+/*! Returns the content's origin in viewport coordinates.
+
+ The origin of the content of a plain text edit is always the top
+ left corner of the first visible text block. The content offset
+ is different from (0,0) when the text has been scrolled
+ horizontally, or when the first visible block has been scrolled
+ partially off the screen, i.e. the visible text does not start
+ with the first line of the first visible block, or when the first
+ visible block is the very first block and the editor displays a
+ margin.
+
+ \sa firstVisibleBlock(), horizontalScrollBar(), verticalScrollBar()
+ */
+QPointF QPlainTextEdit::contentOffset() const
+{
+ Q_D(const QPlainTextEdit);
+ return QPointF(-d->horizontalOffset(), -d->verticalOffset());
+}
+
+
+/*! Returns the bounding rectangle of the text \a block in content
+ coordinates. Translate the rectangle with the contentOffset() to get
+ visual coordinates on the viewport.
+
+ \sa firstVisibleBlock(), blockBoundingRect()
+ */
+QRectF QPlainTextEdit::blockBoundingGeometry(const QTextBlock &block) const
+{
+ Q_D(const QPlainTextEdit);
+ return d->control->blockBoundingRect(block);
+}
+
+/*!
+ Returns the bounding rectangle of the text \a block in the block's own coordinates.
+
+ \sa blockBoundingGeometry()
+ */
+QRectF QPlainTextEdit::blockBoundingRect(const QTextBlock &block) const
+{
+ QPlainTextDocumentLayout *documentLayout = qobject_cast<QPlainTextDocumentLayout*>(document()->documentLayout());
+ Q_ASSERT(documentLayout);
+ return documentLayout->blockBoundingRect(block);
+}
+
+/*!
+ \property QPlainTextEdit::blockCount
+ \brief the number of text blocks in the document.
+
+ By default, in an empty document, this property contains a value of 1.
+*/
+int QPlainTextEdit::blockCount() const
+{
+ return document()->blockCount();
+}
+
+/*! Returns the paint context for the viewport(), useful only when
+ reimplementing paintEvent().
+ */
+QAbstractTextDocumentLayout::PaintContext QPlainTextEdit::getPaintContext() const
+{
+ Q_D(const QPlainTextEdit);
+ return d->control->getPaintContext(d->viewport);
+}
+
+/*!
+ \property QPlainTextEdit::maximumBlockCount
+ \brief the limit for blocks in the document.
+
+ Specifies the maximum number of blocks the document may have. If there are
+ more blocks in the document that specified with this property blocks are removed
+ from the beginning of the document.
+
+ A negative or zero value specifies that the document may contain an unlimited
+ amount of blocks.
+
+ The default value is 0.
+
+ Note that setting this property will apply the limit immediately to the document
+ contents. Setting this property also disables the undo redo history.
+
+*/
+
+
+/*!
+ \fn void QPlainTextEdit::textChanged()
+
+ This signal is emitted whenever the document's content changes; for
+ example, when text is inserted or deleted, or when formatting is applied.
+*/
+
+/*!
+ \fn void QPlainTextEdit::undoAvailable(bool available)
+
+ This signal is emitted whenever undo operations become available
+ (\a available is true) or unavailable (\a available is false).
+*/
+
+/*!
+ \fn void QPlainTextEdit::redoAvailable(bool available)
+
+ This signal is emitted whenever redo operations become available
+ (\a available is true) or unavailable (\a available is false).
+*/
+
+QT_END_NAMESPACE
+
+#include "moc_qplaintextedit.cpp"
+#include "moc_qplaintextedit_p.cpp"
+
+#endif // QT_NO_TEXTEDIT
diff --git a/src/widgets/widgets/qplaintextedit.h b/src/widgets/widgets/qplaintextedit.h
new file mode 100644
index 0000000000..d5fa71bbb7
--- /dev/null
+++ b/src/widgets/widgets/qplaintextedit.h
@@ -0,0 +1,327 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPLAINTEXTEDIT_H
+#define QPLAINTEXTEDIT_H
+
+#include <QtWidgets/qtextedit.h>
+
+#include <QtWidgets/qabstractscrollarea.h>
+#include <QtGui/qtextdocument.h>
+#include <QtGui/qtextoption.h>
+#include <QtGui/qtextcursor.h>
+#include <QtGui/qtextformat.h>
+#include <QtGui/qabstracttextdocumentlayout.h>
+
+#ifndef QT_NO_TEXTEDIT
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QStyleSheet;
+class QTextDocument;
+class QMenu;
+class QPlainTextEditPrivate;
+class QMimeData;
+class QPagedPaintDevice;
+
+class Q_WIDGETS_EXPORT QPlainTextEdit : public QAbstractScrollArea
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QPlainTextEdit)
+ Q_ENUMS(LineWrapMode)
+ Q_PROPERTY(bool tabChangesFocus READ tabChangesFocus WRITE setTabChangesFocus)
+ Q_PROPERTY(QString documentTitle READ documentTitle WRITE setDocumentTitle)
+ Q_PROPERTY(bool undoRedoEnabled READ isUndoRedoEnabled WRITE setUndoRedoEnabled)
+ Q_PROPERTY(LineWrapMode lineWrapMode READ lineWrapMode WRITE setLineWrapMode)
+ QDOC_PROPERTY(QTextOption::WrapMode wordWrapMode READ wordWrapMode WRITE setWordWrapMode)
+ Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly)
+ Q_PROPERTY(QString plainText READ toPlainText WRITE setPlainText NOTIFY textChanged USER true)
+ Q_PROPERTY(bool overwriteMode READ overwriteMode WRITE setOverwriteMode)
+ Q_PROPERTY(int tabStopWidth READ tabStopWidth WRITE setTabStopWidth)
+ Q_PROPERTY(int cursorWidth READ cursorWidth WRITE setCursorWidth)
+ Q_PROPERTY(Qt::TextInteractionFlags textInteractionFlags READ textInteractionFlags WRITE setTextInteractionFlags)
+ Q_PROPERTY(int blockCount READ blockCount)
+ Q_PROPERTY(int maximumBlockCount READ maximumBlockCount WRITE setMaximumBlockCount)
+ Q_PROPERTY(bool backgroundVisible READ backgroundVisible WRITE setBackgroundVisible)
+ Q_PROPERTY(bool centerOnScroll READ centerOnScroll WRITE setCenterOnScroll)
+public:
+ enum LineWrapMode {
+ NoWrap,
+ WidgetWidth
+ };
+
+ explicit QPlainTextEdit(QWidget *parent = 0);
+ explicit QPlainTextEdit(const QString &text, QWidget *parent = 0);
+ virtual ~QPlainTextEdit();
+
+ void setDocument(QTextDocument *document);
+ QTextDocument *document() const;
+
+ void setTextCursor(const QTextCursor &cursor);
+ QTextCursor textCursor() const;
+
+ bool isReadOnly() const;
+ void setReadOnly(bool ro);
+
+ void setTextInteractionFlags(Qt::TextInteractionFlags flags);
+ Qt::TextInteractionFlags textInteractionFlags() const;
+
+ void mergeCurrentCharFormat(const QTextCharFormat &modifier);
+ void setCurrentCharFormat(const QTextCharFormat &format);
+ QTextCharFormat currentCharFormat() const;
+
+ bool tabChangesFocus() const;
+ void setTabChangesFocus(bool b);
+
+ inline void setDocumentTitle(const QString &title)
+ { document()->setMetaInformation(QTextDocument::DocumentTitle, title); }
+ inline QString documentTitle() const
+ { return document()->metaInformation(QTextDocument::DocumentTitle); }
+
+ inline bool isUndoRedoEnabled() const
+ { return document()->isUndoRedoEnabled(); }
+ inline void setUndoRedoEnabled(bool enable)
+ { document()->setUndoRedoEnabled(enable); }
+
+ inline void setMaximumBlockCount(int maximum)
+ { document()->setMaximumBlockCount(maximum); }
+ inline int maximumBlockCount() const
+ { return document()->maximumBlockCount(); }
+
+
+ LineWrapMode lineWrapMode() const;
+ void setLineWrapMode(LineWrapMode mode);
+
+ QTextOption::WrapMode wordWrapMode() const;
+ void setWordWrapMode(QTextOption::WrapMode policy);
+
+ void setBackgroundVisible(bool visible);
+ bool backgroundVisible() const;
+
+ void setCenterOnScroll(bool enabled);
+ bool centerOnScroll() const;
+
+ bool find(const QString &exp, QTextDocument::FindFlags options = 0);
+
+ inline QString toPlainText() const
+ { return document()->toPlainText(); }
+
+ void ensureCursorVisible();
+
+ virtual QVariant loadResource(int type, const QUrl &name);
+#ifndef QT_NO_CONTEXTMENU
+ QMenu *createStandardContextMenu();
+#endif
+
+ QTextCursor cursorForPosition(const QPoint &pos) const;
+ QRect cursorRect(const QTextCursor &cursor) const;
+ QRect cursorRect() const;
+
+ QString anchorAt(const QPoint &pos) const;
+
+ bool overwriteMode() const;
+ void setOverwriteMode(bool overwrite);
+
+ int tabStopWidth() const;
+ void setTabStopWidth(int width);
+
+ int cursorWidth() const;
+ void setCursorWidth(int width);
+
+ void setExtraSelections(const QList<QTextEdit::ExtraSelection> &selections);
+ QList<QTextEdit::ExtraSelection> extraSelections() const;
+
+ void moveCursor(QTextCursor::MoveOperation operation, QTextCursor::MoveMode mode = QTextCursor::MoveAnchor);
+
+ bool canPaste() const;
+
+ void print(QPagedPaintDevice *printer) const;
+
+ int blockCount() const;
+
+public Q_SLOTS:
+
+ void setPlainText(const QString &text);
+
+#ifndef QT_NO_CLIPBOARD
+ void cut();
+ void copy();
+ void paste();
+#endif
+
+ void undo();
+ void redo();
+
+ void clear();
+ void selectAll();
+
+ void insertPlainText(const QString &text);
+
+ void appendPlainText(const QString &text);
+ void appendHtml(const QString &html);
+
+ void centerCursor();
+
+Q_SIGNALS:
+ void textChanged();
+ void undoAvailable(bool b);
+ void redoAvailable(bool b);
+ void copyAvailable(bool b);
+ void selectionChanged();
+ void cursorPositionChanged();
+
+ void updateRequest(const QRect &rect, int dy);
+ void blockCountChanged(int newBlockCount);
+ void modificationChanged(bool);
+
+protected:
+ virtual bool event(QEvent *e);
+ virtual void timerEvent(QTimerEvent *e);
+ virtual void keyPressEvent(QKeyEvent *e);
+ virtual void keyReleaseEvent(QKeyEvent *e);
+ virtual void resizeEvent(QResizeEvent *e);
+ virtual void paintEvent(QPaintEvent *e);
+ virtual void mousePressEvent(QMouseEvent *e);
+ virtual void mouseMoveEvent(QMouseEvent *e);
+ virtual void mouseReleaseEvent(QMouseEvent *e);
+ virtual void mouseDoubleClickEvent(QMouseEvent *e);
+ virtual bool focusNextPrevChild(bool next);
+#ifndef QT_NO_CONTEXTMENU
+ virtual void contextMenuEvent(QContextMenuEvent *e);
+#endif
+#ifndef QT_NO_DRAGANDDROP
+ virtual void dragEnterEvent(QDragEnterEvent *e);
+ virtual void dragLeaveEvent(QDragLeaveEvent *e);
+ virtual void dragMoveEvent(QDragMoveEvent *e);
+ virtual void dropEvent(QDropEvent *e);
+#endif
+ virtual void focusInEvent(QFocusEvent *e);
+ virtual void focusOutEvent(QFocusEvent *e);
+ virtual void showEvent(QShowEvent *);
+ virtual void changeEvent(QEvent *e);
+#ifndef QT_NO_WHEELEVENT
+ virtual void wheelEvent(QWheelEvent *e);
+#endif
+
+ virtual QMimeData *createMimeDataFromSelection() const;
+ virtual bool canInsertFromMimeData(const QMimeData *source) const;
+ virtual void insertFromMimeData(const QMimeData *source);
+
+ virtual void inputMethodEvent(QInputMethodEvent *);
+ QVariant inputMethodQuery(Qt::InputMethodQuery property) const;
+
+ QPlainTextEdit(QPlainTextEditPrivate &dd, QWidget *parent);
+
+ virtual void scrollContentsBy(int dx, int dy);
+
+ QTextBlock firstVisibleBlock() const;
+ QPointF contentOffset() const;
+ QRectF blockBoundingRect(const QTextBlock &block) const;
+ QRectF blockBoundingGeometry(const QTextBlock &block) const;
+ QAbstractTextDocumentLayout::PaintContext getPaintContext() const;
+
+
+private:
+ Q_DISABLE_COPY(QPlainTextEdit)
+ Q_PRIVATE_SLOT(d_func(), void _q_repaintContents(const QRectF &r))
+ Q_PRIVATE_SLOT(d_func(), void _q_adjustScrollbars())
+ Q_PRIVATE_SLOT(d_func(), void _q_verticalScrollbarActionTriggered(int))
+ Q_PRIVATE_SLOT(d_func(), void _q_cursorPositionChanged())
+
+ friend class QPlainTextEditControl;
+};
+
+
+class QPlainTextDocumentLayoutPrivate;
+class Q_WIDGETS_EXPORT QPlainTextDocumentLayout : public QAbstractTextDocumentLayout
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QPlainTextDocumentLayout)
+ Q_PROPERTY(int cursorWidth READ cursorWidth WRITE setCursorWidth)
+
+public:
+ QPlainTextDocumentLayout(QTextDocument *document);
+ ~QPlainTextDocumentLayout();
+
+ void draw(QPainter *, const PaintContext &);
+ int hitTest(const QPointF &, Qt::HitTestAccuracy ) const;
+
+ int pageCount() const;
+ QSizeF documentSize() const;
+
+ QRectF frameBoundingRect(QTextFrame *) const;
+ QRectF blockBoundingRect(const QTextBlock &block) const;
+
+ void ensureBlockLayout(const QTextBlock &block) const;
+
+ void setCursorWidth(int width);
+ int cursorWidth() const;
+
+ void requestUpdate();
+
+protected:
+ void documentChanged(int from, int /*charsRemoved*/, int charsAdded);
+
+
+private:
+ void setTextWidth(qreal newWidth);
+ qreal textWidth() const;
+ void layoutBlock(const QTextBlock &block);
+ qreal blockWidth(const QTextBlock &block);
+
+ QPlainTextDocumentLayoutPrivate *priv() const;
+
+ friend class QPlainTextEdit;
+ friend class QPlainTextEditPrivate;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif // QT_NO_TEXTEDIT
+
+#endif // QPLAINTEXTEDIT_H
diff --git a/src/widgets/widgets/qplaintextedit_p.h b/src/widgets/widgets/qplaintextedit_p.h
new file mode 100644
index 0000000000..190156a684
--- /dev/null
+++ b/src/widgets/widgets/qplaintextedit_p.h
@@ -0,0 +1,187 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPLAINTEXTEDIT_P_H
+#define QPLAINTEXTEDIT_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "private/qabstractscrollarea_p.h"
+#include "QtGui/qtextdocumentfragment.h"
+#include "QtWidgets/qscrollbar.h"
+#include "QtGui/qtextcursor.h"
+#include "QtGui/qtextformat.h"
+#include "QtWidgets/qmenu.h"
+#include "QtGui/qabstracttextdocumentlayout.h"
+#include "QtCore/qbasictimer.h"
+#include "private/qwidgettextcontrol_p.h"
+#include "qplaintextedit.h"
+
+#ifndef QT_NO_TEXTEDIT
+
+QT_BEGIN_NAMESPACE
+
+class QMimeData;
+
+class QPlainTextEdit;
+class ExtraArea;
+
+class QPlainTextEditControl : public QWidgetTextControl
+{
+ Q_OBJECT
+public:
+ QPlainTextEditControl(QPlainTextEdit *parent);
+
+
+ QMimeData *createMimeDataFromSelection() const;
+ bool canInsertFromMimeData(const QMimeData *source) const;
+ void insertFromMimeData(const QMimeData *source);
+ int hitTest(const QPointF &point, Qt::HitTestAccuracy = Qt::FuzzyHit) const;
+ QRectF blockBoundingRect(const QTextBlock &block) const;
+ inline QRectF cursorRect(const QTextCursor &cursor) const {
+ QRectF r = QWidgetTextControl::cursorRect(cursor);
+ r.setLeft(qMax(r.left(), (qreal) 0.));
+ return r;
+ }
+ inline QRectF cursorRect() { return cursorRect(textCursor()); }
+ void ensureCursorVisible() {
+ textEdit->ensureCursorVisible();
+ emit microFocusChanged();
+ }
+
+
+ QPlainTextEdit *textEdit;
+ int topBlock;
+ QTextBlock firstVisibleBlock() const;
+
+ QVariant loadResource(int type, const QUrl &name) {
+ return textEdit->loadResource(type, name);
+ }
+
+};
+
+
+class QPlainTextEditPrivate : public QAbstractScrollAreaPrivate
+{
+ Q_DECLARE_PUBLIC(QPlainTextEdit)
+public:
+ QPlainTextEditPrivate();
+
+ void init(const QString &txt = QString());
+ void _q_repaintContents(const QRectF &contentsRect);
+
+ inline QPoint mapToContents(const QPoint &point) const
+ { return QPoint(point.x() + horizontalOffset(), point.y() + verticalOffset()); }
+
+ void _q_adjustScrollbars();
+ void _q_verticalScrollbarActionTriggered(int action);
+ void ensureViewportLayouted();
+ void relayoutDocument();
+
+ void pageUpDown(QTextCursor::MoveOperation op, QTextCursor::MoveMode moveMode, bool moveCursor = true);
+
+ inline int horizontalOffset() const
+ { return (q_func()->isRightToLeft() ? (hbar->maximum() - hbar->value()) : hbar->value()); }
+ int verticalOffset(int topBlock, int topLine) const;
+ int verticalOffset() const;
+
+ inline void sendControlEvent(QEvent *e)
+ { control->processEvent(e, QPointF(horizontalOffset(), verticalOffset()), viewport); }
+
+ void updateDefaultTextOption();
+
+ QPlainTextEditControl *control;
+
+ bool tabChangesFocus;
+
+ QBasicTimer autoScrollTimer;
+ QPoint autoScrollDragPos;
+
+ QPlainTextEdit::LineWrapMode lineWrap;
+ QTextOption::WrapMode wordWrap;
+
+ uint showCursorOnInitialShow : 1;
+ uint backgroundVisible : 1;
+ uint centerOnScroll : 1;
+ uint inDrag : 1;
+ uint clickCausedFocus : 1;
+
+ int topLine;
+
+ void setTopLine(int visualTopLine, int dx = 0);
+ void setTopBlock(int newTopBlock, int newTopLine, int dx = 0);
+
+ void ensureVisible(int position, bool center, bool forceCenter = false);
+ void ensureCursorVisible(bool center = false);
+ void updateViewport();
+
+ QPointer<QPlainTextDocumentLayout> documentLayoutPtr;
+
+ void append(const QString &text, Qt::TextFormat format = Qt::AutoText);
+
+ qreal pageUpDownLastCursorY;
+ bool pageUpDownLastCursorYIsValid;
+
+
+#ifdef QT_KEYPAD_NAVIGATION
+ QBasicTimer deleteAllTimer;
+#endif
+
+ void _q_cursorPositionChanged();
+ void _q_modificationChanged(bool);
+
+ int originalOffsetY;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_TEXTEDIT
+
+#endif // QPLAINTEXTEDIT_P_H
diff --git a/src/gui/widgets/qprogressbar.cpp b/src/widgets/widgets/qprogressbar.cpp
index dd92bda993..dd92bda993 100644
--- a/src/gui/widgets/qprogressbar.cpp
+++ b/src/widgets/widgets/qprogressbar.cpp
diff --git a/src/widgets/widgets/qprogressbar.h b/src/widgets/widgets/qprogressbar.h
new file mode 100644
index 0000000000..ac34f64a2e
--- /dev/null
+++ b/src/widgets/widgets/qprogressbar.h
@@ -0,0 +1,132 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPROGRESSBAR_H
+#define QPROGRESSBAR_H
+
+#include <QtWidgets/qframe.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_PROGRESSBAR
+
+class QProgressBarPrivate;
+class QStyleOptionProgressBar;
+
+class Q_WIDGETS_EXPORT QProgressBar : public QWidget
+{
+ Q_OBJECT
+ Q_ENUMS(Direction)
+ Q_PROPERTY(int minimum READ minimum WRITE setMinimum)
+ Q_PROPERTY(int maximum READ maximum WRITE setMaximum)
+ Q_PROPERTY(QString text READ text)
+ Q_PROPERTY(int value READ value WRITE setValue NOTIFY valueChanged)
+ Q_PROPERTY(Qt::Alignment alignment READ alignment WRITE setAlignment)
+ Q_PROPERTY(bool textVisible READ isTextVisible WRITE setTextVisible)
+ Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation)
+ Q_PROPERTY(bool invertedAppearance READ invertedAppearance WRITE setInvertedAppearance)
+ Q_PROPERTY(Direction textDirection READ textDirection WRITE setTextDirection)
+ Q_PROPERTY(QString format READ format WRITE setFormat)
+
+public:
+ enum Direction { TopToBottom, BottomToTop };
+
+ explicit QProgressBar(QWidget *parent = 0);
+
+ int minimum() const;
+ int maximum() const;
+
+ int value() const;
+
+ virtual QString text() const;
+ void setTextVisible(bool visible);
+ bool isTextVisible() const;
+
+ Qt::Alignment alignment() const;
+ void setAlignment(Qt::Alignment alignment);
+
+ QSize sizeHint() const;
+ QSize minimumSizeHint() const;
+
+ Qt::Orientation orientation() const;
+
+ void setInvertedAppearance(bool invert);
+ bool invertedAppearance(); //### Qt5 make const
+ bool invertedAppearance() const { return const_cast<QProgressBar *>(this)->invertedAppearance(); }
+ void setTextDirection(QProgressBar::Direction textDirection);
+ QProgressBar::Direction textDirection(); //### Qt5 make const
+ QProgressBar::Direction textDirection() const { return const_cast<QProgressBar *>(this)->textDirection(); }
+
+ void setFormat(const QString &format);
+ QString format() const;
+
+public Q_SLOTS:
+ void reset();
+ void setRange(int minimum, int maximum);
+ void setMinimum(int minimum);
+ void setMaximum(int maximum);
+ void setValue(int value);
+ void setOrientation(Qt::Orientation);
+
+Q_SIGNALS:
+ void valueChanged(int value);
+
+protected:
+ bool event(QEvent *e);
+ void paintEvent(QPaintEvent *);
+ void initStyleOption(QStyleOptionProgressBar *option) const;
+
+private:
+ Q_DECLARE_PRIVATE(QProgressBar)
+ Q_DISABLE_COPY(QProgressBar)
+};
+
+#endif // QT_NO_PROGRESSBAR
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QPROGRESSBAR_H
diff --git a/src/gui/widgets/qpushbutton.cpp b/src/widgets/widgets/qpushbutton.cpp
index a1bc4d9cb9..a1bc4d9cb9 100644
--- a/src/gui/widgets/qpushbutton.cpp
+++ b/src/widgets/widgets/qpushbutton.cpp
diff --git a/src/widgets/widgets/qpushbutton.h b/src/widgets/widgets/qpushbutton.h
new file mode 100644
index 0000000000..4f1f85dea4
--- /dev/null
+++ b/src/widgets/widgets/qpushbutton.h
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPUSHBUTTON_H
+#define QPUSHBUTTON_H
+
+#include <QtWidgets/qabstractbutton.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QPushButtonPrivate;
+class QMenu;
+class QStyleOptionButton;
+
+class Q_WIDGETS_EXPORT QPushButton : public QAbstractButton
+{
+ Q_OBJECT
+
+ Q_PROPERTY(bool autoDefault READ autoDefault WRITE setAutoDefault)
+ Q_PROPERTY(bool default READ isDefault WRITE setDefault)
+ Q_PROPERTY(bool flat READ isFlat WRITE setFlat)
+
+public:
+ explicit QPushButton(QWidget *parent=0);
+ explicit QPushButton(const QString &text, QWidget *parent=0);
+ QPushButton(const QIcon& icon, const QString &text, QWidget *parent=0);
+ ~QPushButton();
+
+ QSize sizeHint() const;
+ QSize minimumSizeHint() const;
+
+ bool autoDefault() const;
+ void setAutoDefault(bool);
+ bool isDefault() const;
+ void setDefault(bool);
+
+#ifndef QT_NO_MENU
+ void setMenu(QMenu* menu);
+ QMenu* menu() const;
+#endif
+
+ void setFlat(bool);
+ bool isFlat() const;
+
+public Q_SLOTS:
+#ifndef QT_NO_MENU
+ void showMenu();
+#endif
+
+protected:
+ bool event(QEvent *e);
+#ifdef Q_WS_MAC
+ bool hitButton(const QPoint &pos) const;
+#endif // Q_WS_MAC
+ void paintEvent(QPaintEvent *);
+ void keyPressEvent(QKeyEvent *);
+ void focusInEvent(QFocusEvent *);
+ void focusOutEvent(QFocusEvent *);
+ void initStyleOption(QStyleOptionButton *option) const;
+ QPushButton(QPushButtonPrivate &dd, QWidget* parent = 0);
+
+public:
+#ifdef QT3_SUPPORT
+ QT3_SUPPORT_CONSTRUCTOR QPushButton(QWidget *parent, const char* name);
+ QT3_SUPPORT_CONSTRUCTOR QPushButton(const QString &text, QWidget *parent, const char* name);
+ QT3_SUPPORT_CONSTRUCTOR QPushButton(const QIcon& icon, const QString &text, QWidget *parent, const char* name);
+ inline QT3_SUPPORT void openPopup() { showMenu(); }
+ inline QT3_SUPPORT bool isMenuButton() const { return menu() != 0; }
+ inline QT3_SUPPORT void setPopup(QMenu* popup) {setMenu(popup); }
+ inline QT3_SUPPORT QMenu* popup() const { return menu(); }
+#endif
+
+private:
+ Q_DISABLE_COPY(QPushButton)
+ Q_DECLARE_PRIVATE(QPushButton)
+#ifndef QT_NO_MENU
+ Q_PRIVATE_SLOT(d_func(), void _q_popupPressed())
+#endif
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QPUSHBUTTON_H
diff --git a/src/gui/widgets/qpushbutton_p.h b/src/widgets/widgets/qpushbutton_p.h
index 0056288a98..0056288a98 100644
--- a/src/gui/widgets/qpushbutton_p.h
+++ b/src/widgets/widgets/qpushbutton_p.h
diff --git a/src/gui/widgets/qradiobutton.cpp b/src/widgets/widgets/qradiobutton.cpp
index eeef40e00a..eeef40e00a 100644
--- a/src/gui/widgets/qradiobutton.cpp
+++ b/src/widgets/widgets/qradiobutton.cpp
diff --git a/src/widgets/widgets/qradiobutton.h b/src/widgets/widgets/qradiobutton.h
new file mode 100644
index 0000000000..e3837253c8
--- /dev/null
+++ b/src/widgets/widgets/qradiobutton.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QRADIOBUTTON_H
+#define QRADIOBUTTON_H
+
+#include <QtWidgets/qabstractbutton.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QRadioButtonPrivate;
+class QStyleOptionButton;
+
+class Q_WIDGETS_EXPORT QRadioButton : public QAbstractButton
+{
+ Q_OBJECT
+
+public:
+ explicit QRadioButton(QWidget *parent=0);
+ explicit QRadioButton(const QString &text, QWidget *parent=0);
+
+ QSize sizeHint() const;
+ QSize minimumSizeHint() const;
+
+protected:
+ bool event(QEvent *e);
+ bool hitButton(const QPoint &) const;
+ void paintEvent(QPaintEvent *);
+ void mouseMoveEvent(QMouseEvent *);
+ void initStyleOption(QStyleOptionButton *button) const;
+
+#ifdef QT3_SUPPORT
+public:
+ QT3_SUPPORT_CONSTRUCTOR QRadioButton(QWidget *parent, const char* name);
+ QT3_SUPPORT_CONSTRUCTOR QRadioButton(const QString &text, QWidget *parent, const char* name);
+#endif
+
+private:
+ Q_DECLARE_PRIVATE(QRadioButton)
+ Q_DISABLE_COPY(QRadioButton)
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QRADIOBUTTON_H
diff --git a/src/gui/widgets/qrubberband.cpp b/src/widgets/widgets/qrubberband.cpp
index e288835609..e288835609 100644
--- a/src/gui/widgets/qrubberband.cpp
+++ b/src/widgets/widgets/qrubberband.cpp
diff --git a/src/widgets/widgets/qrubberband.h b/src/widgets/widgets/qrubberband.h
new file mode 100644
index 0000000000..3d30004770
--- /dev/null
+++ b/src/widgets/widgets/qrubberband.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QRUBBERBAND_H
+#define QRUBBERBAND_H
+
+#include <QtWidgets/qwidget.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_RUBBERBAND
+
+class QRubberBandPrivate;
+class QStyleOptionRubberBand;
+
+class Q_WIDGETS_EXPORT QRubberBand : public QWidget
+{
+ Q_OBJECT
+
+public:
+ enum Shape { Line, Rectangle };
+ explicit QRubberBand(Shape, QWidget * =0);
+ ~QRubberBand();
+
+ Shape shape() const;
+
+ void setGeometry(const QRect &r);
+
+ inline void setGeometry(int x, int y, int w, int h);
+ inline void move(int x, int y);
+ inline void move(const QPoint &p)
+ { move(p.x(), p.y()); }
+ inline void resize(int w, int h)
+ { setGeometry(geometry().x(), geometry().y(), w, h); }
+ inline void resize(const QSize &s)
+ { resize(s.width(), s.height()); }
+
+protected:
+ bool event(QEvent *e);
+ void paintEvent(QPaintEvent *);
+ void changeEvent(QEvent *);
+ void showEvent(QShowEvent *);
+ void resizeEvent(QResizeEvent *);
+ void moveEvent(QMoveEvent *);
+ void initStyleOption(QStyleOptionRubberBand *option) const;
+
+private:
+ Q_DECLARE_PRIVATE(QRubberBand)
+};
+
+inline void QRubberBand::setGeometry(int ax, int ay, int aw, int ah)
+{ setGeometry(QRect(ax, ay, aw, ah)); }
+inline void QRubberBand::move(int ax, int ay)
+{ setGeometry(ax, ay, width(), height()); }
+
+#endif // QT_NO_RUBBERBAND
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QRUBBERBAND_H
diff --git a/src/widgets/widgets/qscrollarea.cpp b/src/widgets/widgets/qscrollarea.cpp
new file mode 100644
index 0000000000..5d03c07472
--- /dev/null
+++ b/src/widgets/widgets/qscrollarea.cpp
@@ -0,0 +1,522 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qscrollarea.h"
+#include "private/qscrollarea_p.h"
+
+#ifndef QT_NO_SCROLLAREA
+
+#include "qscrollbar.h"
+#include "qlayout.h"
+#include "qstyle.h"
+#include "qapplication.h"
+#include "qvariant.h"
+#include "qdebug.h"
+#include "private/qlayoutengine_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QScrollArea
+
+ \brief The QScrollArea class provides a scrolling view onto
+ another widget.
+
+ \ingroup basicwidgets
+
+
+ A scroll area is used to display the contents of a child widget
+ within a frame. If the widget exceeds the size of the frame, the
+ view can provide scroll bars so that the entire area of the child
+ widget can be viewed. The child widget must be specified with
+ setWidget(). For example:
+
+ \snippet doc/src/snippets/code/src_gui_widgets_qscrollarea.cpp 0
+
+ The code above creates a scroll area (shown in the images below)
+ containing an image label. When scaling the image, the scroll area
+ can provide the necessary scroll bars:
+
+ \table
+ \row
+ \o \inlineimage qscrollarea-noscrollbars.png
+ \o \inlineimage qscrollarea-onescrollbar.png
+ \o \inlineimage qscrollarea-twoscrollbars.png
+ \endtable
+
+ The scroll bars appearance depends on the currently set \l
+ {Qt::ScrollBarPolicy}{scroll bar policies}. You can control the
+ appearance of the scroll bars using the inherited functionality
+ from QAbstractScrollArea.
+
+ For example, you can set the
+ QAbstractScrollArea::horizontalScrollBarPolicy and
+ QAbstractScrollArea::verticalScrollBarPolicy properties. Or if you
+ want the scroll bars to adjust dynamically when the contents of
+ the scroll area changes, you can use the \l
+ {QAbstractScrollArea::horizontalScrollBar()}{horizontalScrollBar()}
+ and \l
+ {QAbstractScrollArea::verticalScrollBar()}{verticalScrollBar()}
+ functions (which enable you to access the scroll bars) and set the
+ scroll bars' values whenever the scroll area's contents change,
+ using the QScrollBar::setValue() function.
+
+ You can retrieve the child widget using the widget() function. The
+ view can be made to be resizable with the setWidgetResizable()
+ function. The alignment of the widget can be specified with
+ setAlignment().
+
+ Two convenience functions ensureVisible() and
+ ensureWidgetVisible() ensure a certain region of the contents is
+ visible inside the viewport, by scrolling the contents if
+ necessary.
+
+ \section1 Size Hints and Layouts
+
+ When using a scroll area to display the contents of a custom
+ widget, it is important to ensure that the
+ \l{QWidget::sizeHint}{size hint} of the child widget is set to a
+ suitable value. If a standard QWidget is used for the child
+ widget, it may be necessary to call QWidget::setMinimumSize() to
+ ensure that the contents of the widget are shown correctly within
+ the scroll area.
+
+ If a scroll area is used to display the contents of a widget that
+ contains child widgets arranged in a layout, it is important to
+ realize that the size policy of the layout will also determine the
+ size of the widget. This is especially useful to know if you intend
+ to dynamically change the contents of the layout. In such cases,
+ setting the layout's \l{QLayout::sizeConstraint}{size constraint}
+ property to one which provides constraints on the minimum and/or
+ maximum size of the layout (e.g., QLayout::SetMinAndMaxSize) will
+ cause the size of the scroll area to be updated whenever the
+ contents of the layout changes.
+
+ For a complete example using the QScrollArea class, see the \l
+ {widgets/imageviewer}{Image Viewer} example. The example shows how
+ to combine QLabel and QScrollArea to display an image.
+
+ \sa QAbstractScrollArea, QScrollBar, {Image Viewer Example}
+*/
+
+
+/*!
+ Constructs an empty scroll area with the given \a parent.
+
+ \sa setWidget()
+*/
+QScrollArea::QScrollArea(QWidget *parent)
+ : QAbstractScrollArea(*new QScrollAreaPrivate,parent)
+{
+ Q_D(QScrollArea);
+ d->viewport->setBackgroundRole(QPalette::NoRole);
+ d->vbar->setSingleStep(20);
+ d->hbar->setSingleStep(20);
+ d->layoutChildren();
+}
+
+/*!
+ \internal
+*/
+QScrollArea::QScrollArea(QScrollAreaPrivate &dd, QWidget *parent)
+ : QAbstractScrollArea(dd, parent)
+{
+ Q_D(QScrollArea);
+ d->viewport->setBackgroundRole(QPalette::NoRole);
+ d->vbar->setSingleStep(20);
+ d->hbar->setSingleStep(20);
+ d->layoutChildren();
+}
+
+/*!
+ Destroys the scroll area and its child widget.
+
+ \sa setWidget()
+*/
+QScrollArea::~QScrollArea()
+{
+}
+
+void QScrollAreaPrivate::updateWidgetPosition()
+{
+ Q_Q(QScrollArea);
+ Qt::LayoutDirection dir = q->layoutDirection();
+ QRect scrolled = QStyle::visualRect(dir, viewport->rect(), QRect(QPoint(-hbar->value(), -vbar->value()), widget->size()));
+ QRect aligned = QStyle::alignedRect(dir, alignment, widget->size(), viewport->rect());
+ widget->move(widget->width() < viewport->width() ? aligned.x() : scrolled.x(),
+ widget->height() < viewport->height() ? aligned.y() : scrolled.y());
+}
+
+void QScrollAreaPrivate::updateScrollBars()
+{
+ Q_Q(QScrollArea);
+ if (!widget)
+ return;
+ QSize p = viewport->size();
+ QSize m = q->maximumViewportSize();
+
+ QSize min = qSmartMinSize(widget);
+ QSize max = qSmartMaxSize(widget);
+
+ if (resizable) {
+ if ((widget->layout() ? widget->layout()->hasHeightForWidth() : widget->sizePolicy().hasHeightForWidth())) {
+ QSize p_hfw = p.expandedTo(min).boundedTo(max);
+ int h = widget->heightForWidth( p_hfw.width() );
+ min = QSize(p_hfw.width(), qMax(p_hfw.height(), h));
+ }
+ }
+
+ if ((resizable && m.expandedTo(min) == m && m.boundedTo(max) == m)
+ || (!resizable && m.expandedTo(widget->size()) == m))
+ p = m; // no scroll bars needed
+
+ if (resizable)
+ widget->resize(p.expandedTo(min).boundedTo(max));
+ QSize v = widget->size();
+
+ hbar->setRange(0, v.width() - p.width());
+ hbar->setPageStep(p.width());
+ vbar->setRange(0, v.height() - p.height());
+ vbar->setPageStep(p.height());
+ updateWidgetPosition();
+
+}
+
+/*!
+ Returns the scroll area's widget, or 0 if there is none.
+
+ \sa setWidget()
+*/
+
+QWidget *QScrollArea::widget() const
+{
+ Q_D(const QScrollArea);
+ return d->widget;
+}
+
+/*!
+ \fn void QScrollArea::setWidget(QWidget *widget)
+
+ Sets the scroll area's \a widget.
+
+ The \a widget becomes a child of the scroll area, and will be
+ destroyed when the scroll area is deleted or when a new widget is
+ set.
+
+ The widget's \l{QWidget::setAutoFillBackground()}{autoFillBackground}
+ property will be set to \c{true}.
+
+ If the scroll area is visible when the \a widget is
+ added, you must \l{QWidget::}{show()} it explicitly.
+
+ Note that You must add the layout of \a widget before you call
+ this function; if you add it later, the \a widget will not be
+ visible - regardless of when you \l{QWidget::}{show()} the scroll
+ area. In this case, you can also not \l{QWidget::}{show()} the \a
+ widget later.
+
+ \sa widget()
+*/
+void QScrollArea::setWidget(QWidget *widget)
+{
+ Q_D(QScrollArea);
+ if (widget == d->widget || !widget)
+ return;
+
+ delete d->widget;
+ d->widget = 0;
+ d->hbar->setValue(0);
+ d->vbar->setValue(0);
+ if (widget->parentWidget() != d->viewport)
+ widget->setParent(d->viewport);
+ if (!widget->testAttribute(Qt::WA_Resized))
+ widget->resize(widget->sizeHint());
+ d->widget = widget;
+ d->widget->setAutoFillBackground(true);
+ widget->installEventFilter(this);
+ d->widgetSize = QSize();
+ d->updateScrollBars();
+ d->widget->show();
+
+}
+
+/*!
+ Removes the scroll area's widget, and passes ownership of the
+ widget to the caller.
+
+ \sa widget()
+ */
+QWidget *QScrollArea::takeWidget()
+{
+ Q_D(QScrollArea);
+ QWidget *w = d->widget;
+ d->widget = 0;
+ if (w)
+ w->setParent(0);
+ return w;
+}
+
+/*!
+ \reimp
+ */
+bool QScrollArea::event(QEvent *e)
+{
+ Q_D(QScrollArea);
+ if (e->type() == QEvent::StyleChange || e->type() == QEvent::LayoutRequest) {
+ d->updateScrollBars();
+ }
+#ifdef QT_KEYPAD_NAVIGATION
+ else if (QApplication::keypadNavigationEnabled()) {
+ if (e->type() == QEvent::Show)
+ QApplication::instance()->installEventFilter(this);
+ else if (e->type() == QEvent::Hide)
+ QApplication::instance()->removeEventFilter(this);
+ }
+#endif
+ return QAbstractScrollArea::event(e);
+}
+
+
+/*!
+ \reimp
+ */
+bool QScrollArea::eventFilter(QObject *o, QEvent *e)
+{
+ Q_D(QScrollArea);
+#ifdef QT_KEYPAD_NAVIGATION
+ if (d->widget && o != d->widget && e->type() == QEvent::FocusIn
+ && QApplication::keypadNavigationEnabled()) {
+ if (o->isWidgetType())
+ ensureWidgetVisible(static_cast<QWidget *>(o));
+ }
+#endif
+ if (o == d->widget && e->type() == QEvent::Resize)
+ d->updateScrollBars();
+
+ return false;
+}
+
+/*!
+ \reimp
+ */
+void QScrollArea::resizeEvent(QResizeEvent *)
+{
+ Q_D(QScrollArea);
+ d->updateScrollBars();
+
+}
+
+
+/*!\reimp
+ */
+void QScrollArea::scrollContentsBy(int, int)
+{
+ Q_D(QScrollArea);
+ if (!d->widget)
+ return;
+ d->updateWidgetPosition();
+}
+
+
+/*!
+ \property QScrollArea::widgetResizable
+ \brief whether the scroll area should resize the view widget
+
+ If this property is set to false (the default), the scroll area
+ honors the size of its widget. Regardless of this property, you
+ can programmatically resize the widget using widget()->resize(),
+ and the scroll area will automatically adjust itself to the new
+ size.
+
+ If this property is set to true, the scroll area will
+ automatically resize the widget in order to avoid scroll bars
+ where they can be avoided, or to take advantage of extra space.
+*/
+bool QScrollArea::widgetResizable() const
+{
+ Q_D(const QScrollArea);
+ return d->resizable;
+}
+
+void QScrollArea::setWidgetResizable(bool resizable)
+{
+ Q_D(QScrollArea);
+ d->resizable = resizable;
+ updateGeometry();
+ d->updateScrollBars();
+}
+
+/*!
+ \reimp
+ */
+QSize QScrollArea::sizeHint() const
+{
+ Q_D(const QScrollArea);
+ int f = 2 * d->frameWidth;
+ QSize sz(f, f);
+ int h = fontMetrics().height();
+ if (d->widget) {
+ if (!d->widgetSize.isValid())
+ d->widgetSize = d->resizable ? d->widget->sizeHint() : d->widget->size();
+ sz += d->widgetSize;
+ } else {
+ sz += QSize(12 * h, 8 * h);
+ }
+ if (d->vbarpolicy == Qt::ScrollBarAlwaysOn)
+ sz.setWidth(sz.width() + d->vbar->sizeHint().width());
+ if (d->hbarpolicy == Qt::ScrollBarAlwaysOn)
+ sz.setHeight(sz.height() + d->hbar->sizeHint().height());
+ return sz.boundedTo(QSize(36 * h, 24 * h));
+}
+
+
+
+/*!
+ \reimp
+ */
+bool QScrollArea::focusNextPrevChild(bool next)
+{
+ if (QWidget::focusNextPrevChild(next)) {
+ if (QWidget *fw = focusWidget())
+ ensureWidgetVisible(fw);
+ return true;
+ }
+ return false;
+}
+
+/*!
+ Scrolls the contents of the scroll area so that the point (\a x, \a y) is visible
+ inside the region of the viewport with margins specified in pixels by \a xmargin and
+ \a ymargin. If the specified point cannot be reached, the contents are scrolled to
+ the nearest valid position. The default value for both margins is 50 pixels.
+*/
+void QScrollArea::ensureVisible(int x, int y, int xmargin, int ymargin)
+{
+ Q_D(QScrollArea);
+
+ int logicalX = QStyle::visualPos(layoutDirection(), d->viewport->rect(), QPoint(x, y)).x();
+
+ if (logicalX - xmargin < d->hbar->value()) {
+ d->hbar->setValue(qMax(0, logicalX - xmargin));
+ } else if (logicalX > d->hbar->value() + d->viewport->width() - xmargin) {
+ d->hbar->setValue(qMin(logicalX - d->viewport->width() + xmargin, d->hbar->maximum()));
+ }
+
+ if (y - ymargin < d->vbar->value()) {
+ d->vbar->setValue(qMax(0, y - ymargin));
+ } else if (y > d->vbar->value() + d->viewport->height() - ymargin) {
+ d->vbar->setValue(qMin(y - d->viewport->height() + ymargin, d->vbar->maximum()));
+ }
+}
+
+/*!
+ \since 4.2
+
+ Scrolls the contents of the scroll area so that the \a childWidget
+ of QScrollArea::widget() is visible inside the viewport with
+ margins specified in pixels by \a xmargin and \a ymargin. If the
+ specified point cannot be reached, the contents are scrolled to
+ the nearest valid position. The default value for both margins is
+ 50 pixels.
+
+*/
+void QScrollArea::ensureWidgetVisible(QWidget *childWidget, int xmargin, int ymargin)
+{
+ Q_D(QScrollArea);
+
+ if (!d->widget->isAncestorOf(childWidget))
+ return;
+
+ const QRect microFocus = childWidget->inputMethodQuery(Qt::ImCursorRectangle).toRect();
+ const QRect defaultMicroFocus =
+ childWidget->QWidget::inputMethodQuery(Qt::ImCursorRectangle).toRect();
+ QRect focusRect = (microFocus != defaultMicroFocus)
+ ? QRect(childWidget->mapTo(d->widget, microFocus.topLeft()), microFocus.size())
+ : QRect(childWidget->mapTo(d->widget, QPoint(0,0)), childWidget->size());
+ const QRect visibleRect(-d->widget->pos(), d->viewport->size());
+
+ if (visibleRect.contains(focusRect))
+ return;
+
+ focusRect.adjust(-xmargin, -ymargin, xmargin, ymargin);
+
+ if (focusRect.width() > visibleRect.width())
+ d->hbar->setValue(focusRect.center().x() - d->viewport->width() / 2);
+ else if (focusRect.right() > visibleRect.right())
+ d->hbar->setValue(focusRect.right() - d->viewport->width());
+ else if (focusRect.left() < visibleRect.left())
+ d->hbar->setValue(focusRect.left());
+
+ if (focusRect.height() > visibleRect.height())
+ d->vbar->setValue(focusRect.center().y() - d->viewport->height() / 2);
+ else if (focusRect.bottom() > visibleRect.bottom())
+ d->vbar->setValue(focusRect.bottom() - d->viewport->height());
+ else if (focusRect.top() < visibleRect.top())
+ d->vbar->setValue(focusRect.top());
+}
+
+
+/*!
+ \property QScrollArea::alignment
+ \brief the alignment of the scroll area's widget
+ \since 4.2
+
+ By default, the widget stays rooted to the top-left corner of the
+ scroll area.
+*/
+
+void QScrollArea::setAlignment(Qt::Alignment alignment)
+{
+ Q_D(QScrollArea);
+ d->alignment = alignment;
+ if (d->widget)
+ d->updateWidgetPosition();
+}
+
+Qt::Alignment QScrollArea::alignment() const
+{
+ Q_D(const QScrollArea);
+ return d->alignment;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_SCROLLAREA
diff --git a/src/widgets/widgets/qscrollarea.h b/src/widgets/widgets/qscrollarea.h
new file mode 100644
index 0000000000..2d62cc1bc4
--- /dev/null
+++ b/src/widgets/widgets/qscrollarea.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSCROLLAREA_H
+#define QSCROLLAREA_H
+
+#include <QtWidgets/qabstractscrollarea.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_SCROLLAREA
+
+class QScrollAreaPrivate;
+
+class Q_WIDGETS_EXPORT QScrollArea : public QAbstractScrollArea
+{
+ Q_OBJECT
+ Q_PROPERTY(bool widgetResizable READ widgetResizable WRITE setWidgetResizable)
+ Q_PROPERTY(Qt::Alignment alignment READ alignment WRITE setAlignment)
+
+public:
+ explicit QScrollArea(QWidget* parent=0);
+ ~QScrollArea();
+
+ QWidget *widget() const;
+ void setWidget(QWidget *widget);
+ QWidget *takeWidget();
+
+ bool widgetResizable() const;
+ void setWidgetResizable(bool resizable);
+
+ QSize sizeHint() const;
+ bool focusNextPrevChild(bool next);
+
+ Qt::Alignment alignment() const;
+ void setAlignment(Qt::Alignment);
+
+ void ensureVisible(int x, int y, int xmargin = 50, int ymargin = 50);
+ void ensureWidgetVisible(QWidget *childWidget, int xmargin = 50, int ymargin = 50);
+
+protected:
+ QScrollArea(QScrollAreaPrivate &dd, QWidget *parent = 0);
+ bool event(QEvent *);
+ bool eventFilter(QObject *, QEvent *);
+ void resizeEvent(QResizeEvent *);
+ void scrollContentsBy(int dx, int dy);
+
+private:
+ Q_DECLARE_PRIVATE(QScrollArea)
+ Q_DISABLE_COPY(QScrollArea)
+};
+
+#endif // QT_NO_SCROLLAREA
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QSCROLLAREA_H
diff --git a/src/widgets/widgets/qscrollarea_p.h b/src/widgets/widgets/qscrollarea_p.h
new file mode 100644
index 0000000000..0e5e21b7c0
--- /dev/null
+++ b/src/widgets/widgets/qscrollarea_p.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSCROLLAREA_P_H
+#define QSCROLLAREA_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QT_NO_SCROLLAREA
+
+#include "private/qabstractscrollarea_p.h"
+#include <QtWidgets/qscrollbar.h>
+
+QT_BEGIN_NAMESPACE
+
+class QScrollAreaPrivate: public QAbstractScrollAreaPrivate
+{
+ Q_DECLARE_PUBLIC(QScrollArea)
+
+public:
+ QScrollAreaPrivate(): resizable(false), alignment(0){}
+ void updateScrollBars();
+ void updateWidgetPosition();
+ QPointer<QWidget> widget;
+ mutable QSize widgetSize;
+ bool resizable;
+ Qt::Alignment alignment;
+};
+
+#endif
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/widgets/widgets/qscrollbar.cpp b/src/widgets/widgets/qscrollbar.cpp
new file mode 100644
index 0000000000..534ff6e619
--- /dev/null
+++ b/src/widgets/widgets/qscrollbar.cpp
@@ -0,0 +1,764 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qapplication.h"
+#include "qcursor.h"
+#include "qevent.h"
+#include "qpainter.h"
+#include "qscrollbar.h"
+#include "qstyle.h"
+#include "qstyleoption.h"
+#include "qmenu.h"
+#include <QtCore/qelapsedtimer.h>
+
+#ifndef QT_NO_SCROLLBAR
+
+#ifndef QT_NO_ACCESSIBILITY
+#include "qaccessible.h"
+#endif
+#include <limits.h>
+#include "qabstractslider_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QScrollBar
+ \brief The QScrollBar widget provides a vertical or horizontal scroll bar.
+
+ \ingroup basicwidgets
+
+ A scroll bar is a control that enables the user to access parts of a
+ document that is larger than the widget used to display it. It provides
+ a visual indication of the user's current position within the document
+ and the amount of the document that is visible. Scroll bars are usually
+ equipped with other controls that enable more accurate navigation.
+ Qt displays scroll bars in a way that is appropriate for each platform.
+
+ If you need to provide a scrolling view onto another widget, it may be
+ more convenient to use the QScrollArea class because this provides a
+ viewport widget and scroll bars. QScrollBar is useful if you need to
+ implement similar functionality for specialized widgets using QAbstractScrollArea;
+ for example, if you decide to subclass QAbstractItemView.
+ For most other situations where a slider control is used to obtain a value
+ within a given range, the QSlider class may be more appropriate for your
+ needs.
+
+ \table
+ \row \o \image qscrollbar-picture.png
+ \o Scroll bars typically include four separate controls: a slider,
+ scroll arrows, and a page control.
+
+ \list
+ \o a. The slider provides a way to quickly go to any part of the
+ document, but does not support accurate navigation within large
+ documents.
+ \o b. The scroll arrows are push buttons which can be used to accurately
+ navigate to a particular place in a document. For a vertical scroll bar
+ connected to a text editor, these typically move the current position one
+ "line" up or down, and adjust the position of the slider by a small
+ amount. In editors and list boxes a "line" might mean one line of text;
+ in an image viewer it might mean 20 pixels.
+ \o c. The page control is the area over which the slider is dragged (the
+ scroll bar's background). Clicking here moves the scroll bar towards
+ the click by one "page". This value is usually the same as the length of
+ the slider.
+ \endlist
+ \endtable
+
+ Each scroll bar has a value that indicates how far the slider is from
+ the start of the scroll bar; this is obtained with value() and set
+ with setValue(). This value always lies within the range of values
+ defined for the scroll bar, from \l{QAbstractSlider::minimum()}{minimum()}
+ to \l{QAbstractSlider::minimum()}{maximum()} inclusive. The range of
+ acceptable values can be set with setMinimum() and setMaximum().
+ At the minimum value, the top edge of the slider (for a vertical scroll
+ bar) or left edge (for a horizontal scroll bar) will be at the top (or
+ left) end of the scroll bar. At the maximum value, the bottom (or right)
+ edge of the slider will be at the bottom (or right) end of the scroll bar.
+
+ The length of the slider is usually related to the value of the page step,
+ and typically represents the proportion of the document area shown in a
+ scrolling view. The page step is the amount that the value changes by
+ when the user presses the \key{Page Up} and \key{Page Down} keys, and is
+ set with setPageStep(). Smaller changes to the value defined by the
+ line step are made using the cursor keys, and this quantity is set with
+ \l{QAbstractSlider::}{setSingleStep()}.
+
+ Note that the range of values used is independent of the actual size
+ of the scroll bar widget. You do not need to take this into account when
+ you choose values for the range and the page step.
+
+ The range of values specified for the scroll bar are often determined
+ differently to those for a QSlider because the length of the slider
+ needs to be taken into account. If we have a document with 100 lines,
+ and we can only show 20 lines in a widget, we may wish to construct a
+ scroll bar with a page step of 20, a minimum value of 0, and a maximum
+ value of 80. This would give us a scroll bar with five "pages".
+
+ \table
+ \row \o \inlineimage qscrollbar-values.png
+ \o The relationship between a document length, the range of values used
+ in a scroll bar, and the page step is simple in many common situations.
+ The scroll bar's range of values is determined by subtracting a
+ chosen page step from some value representing the length of the document.
+ In such cases, the following equation is useful:
+ \e{document length} = maximum() - minimum() + pageStep().
+ \endtable
+
+ QScrollBar only provides integer ranges. Note that although
+ QScrollBar handles very large numbers, scroll bars on current
+ screens cannot usefully represent ranges above about 100,000 pixels.
+ Beyond that, it becomes difficult for the user to control the
+ slider using either the keyboard or the mouse, and the scroll
+ arrows will have limited use.
+
+ ScrollBar inherits a comprehensive set of signals from QAbstractSlider:
+ \list
+ \o \l{QAbstractSlider::valueChanged()}{valueChanged()} is emitted when the
+ scroll bar's value has changed. The tracking() determines whether this
+ signal is emitted during user interaction.
+ \o \l{QAbstractSlider::rangeChanged()}{rangeChanged()} is emitted when the
+ scroll bar's range of values has changed.
+ \o \l{QAbstractSlider::sliderPressed()}{sliderPressed()} is emitted when
+ the user starts to drag the slider.
+ \o \l{QAbstractSlider::sliderMoved()}{sliderMoved()} is emitted when the user
+ drags the slider.
+ \o \l{QAbstractSlider::sliderReleased()}{sliderReleased()} is emitted when
+ the user releases the slider.
+ \o \l{QAbstractSlider::actionTriggered()}{actionTriggered()} is emitted
+ when the scroll bar is changed by user interaction or via the
+ \l{QAbstractSlider::triggerAction()}{triggerAction()} function.
+ \endlist
+
+ A scroll bar can be controlled by the keyboard, but it has a
+ default focusPolicy() of Qt::NoFocus. Use setFocusPolicy() to
+ enable keyboard interaction with the scroll bar:
+ \list
+ \o Left/Right move a horizontal scroll bar by one single step.
+ \o Up/Down move a vertical scroll bar by one single step.
+ \o PageUp moves up one page.
+ \o PageDown moves down one page.
+ \o Home moves to the start (mininum).
+ \o End moves to the end (maximum).
+ \endlist
+
+ The slider itself can be controlled by using the
+ \l{QAbstractSlider::triggerAction()}{triggerAction()} function to simulate
+ user interaction with the scroll bar controls. This is useful if you have
+ many different widgets that use a common range of values.
+
+ Most GUI styles use the pageStep() value to calculate the size of the
+ slider.
+
+ \table 100%
+ \row \o \inlineimage macintosh-horizontalscrollbar.png Screenshot of a Macintosh style scroll bar
+ \o A scroll bar shown in the \l{Macintosh Style Widget Gallery}{Macintosh widget style}.
+ \row \o \inlineimage windowsxp-horizontalscrollbar.png Screenshot of a Windows XP style scroll bar
+ \o A scroll bar shown in the \l{Windows XP Style Widget Gallery}{Windows XP widget style}.
+ \row \o \inlineimage plastique-horizontalscrollbar.png Screenshot of a Plastique style scroll bar
+ \o A scroll bar shown in the \l{Plastique Style Widget Gallery}{Plastique widget style}.
+ \endtable
+
+ \sa QScrollArea, QSlider, QDial, QSpinBox, {fowler}{GUI Design Handbook: Scroll Bar}, {Sliders Example}
+*/
+
+class QScrollBarPrivate : public QAbstractSliderPrivate
+{
+ Q_DECLARE_PUBLIC(QScrollBar)
+public:
+ QStyle::SubControl pressedControl;
+ bool pointerOutsidePressedControl;
+
+ int clickOffset, snapBackPosition;
+
+ void activateControl(uint control, int threshold = 500);
+ void stopRepeatAction();
+ int pixelPosToRangeValue(int pos) const;
+ void init();
+ bool updateHoverControl(const QPoint &pos);
+ QStyle::SubControl newHoverControl(const QPoint &pos);
+
+ QStyle::SubControl hoverControl;
+ QRect hoverRect;
+};
+
+bool QScrollBarPrivate::updateHoverControl(const QPoint &pos)
+{
+ Q_Q(QScrollBar);
+ QRect lastHoverRect = hoverRect;
+ QStyle::SubControl lastHoverControl = hoverControl;
+ bool doesHover = q->testAttribute(Qt::WA_Hover);
+ if (lastHoverControl != newHoverControl(pos) && doesHover) {
+ q->update(lastHoverRect);
+ q->update(hoverRect);
+ return true;
+ }
+ return !doesHover;
+}
+
+QStyle::SubControl QScrollBarPrivate::newHoverControl(const QPoint &pos)
+{
+ Q_Q(QScrollBar);
+ QStyleOptionSlider opt;
+ q->initStyleOption(&opt);
+ opt.subControls = QStyle::SC_All;
+ hoverControl = q->style()->hitTestComplexControl(QStyle::CC_ScrollBar, &opt, pos, q);
+ if (hoverControl == QStyle::SC_None)
+ hoverRect = QRect();
+ else
+ hoverRect = q->style()->subControlRect(QStyle::CC_ScrollBar, &opt, hoverControl, q);
+ return hoverControl;
+}
+
+void QScrollBarPrivate::activateControl(uint control, int threshold)
+{
+ QAbstractSlider::SliderAction action = QAbstractSlider::SliderNoAction;
+ switch (control) {
+ case QStyle::SC_ScrollBarAddPage:
+ action = QAbstractSlider::SliderPageStepAdd;
+ break;
+ case QStyle::SC_ScrollBarSubPage:
+ action = QAbstractSlider::SliderPageStepSub;
+ break;
+ case QStyle::SC_ScrollBarAddLine:
+ action = QAbstractSlider::SliderSingleStepAdd;
+ break;
+ case QStyle::SC_ScrollBarSubLine:
+ action = QAbstractSlider::SliderSingleStepSub;
+ break;
+ case QStyle::SC_ScrollBarFirst:
+ action = QAbstractSlider::SliderToMinimum;
+ break;
+ case QStyle::SC_ScrollBarLast:
+ action = QAbstractSlider::SliderToMaximum;
+ break;
+ default:
+ break;
+ }
+
+ if (action) {
+ q_func()->setRepeatAction(action, threshold);
+ q_func()->triggerAction(action);
+ }
+}
+
+void QScrollBarPrivate::stopRepeatAction()
+{
+ Q_Q(QScrollBar);
+ QStyle::SubControl tmp = pressedControl;
+ q->setRepeatAction(QAbstractSlider::SliderNoAction);
+ pressedControl = QStyle::SC_None;
+
+ if (tmp == QStyle::SC_ScrollBarSlider)
+ q->setSliderDown(false);
+
+ QStyleOptionSlider opt;
+ q->initStyleOption(&opt);
+ q->repaint(q->style()->subControlRect(QStyle::CC_ScrollBar, &opt, tmp, q));
+}
+
+/*!
+ Initialize \a option with the values from this QScrollBar. This method
+ is useful for subclasses when they need a QStyleOptionSlider, but don't want
+ to fill in all the information themselves.
+
+ \sa QStyleOption::initFrom()
+*/
+void QScrollBar::initStyleOption(QStyleOptionSlider *option) const
+{
+ if (!option)
+ return;
+
+ Q_D(const QScrollBar);
+ option->initFrom(this);
+ option->subControls = QStyle::SC_None;
+ option->activeSubControls = QStyle::SC_None;
+ option->orientation = d->orientation;
+ option->minimum = d->minimum;
+ option->maximum = d->maximum;
+ option->sliderPosition = d->position;
+ option->sliderValue = d->value;
+ option->singleStep = d->singleStep;
+ option->pageStep = d->pageStep;
+ option->upsideDown = d->invertedAppearance;
+ if (d->orientation == Qt::Horizontal)
+ option->state |= QStyle::State_Horizontal;
+}
+
+
+#define HORIZONTAL (d_func()->orientation == Qt::Horizontal)
+#define VERTICAL !HORIZONTAL
+
+/*!
+ Constructs a vertical scroll bar.
+
+ The \a parent argument is sent to the QWidget constructor.
+
+ The \l {QAbstractSlider::minimum} {minimum} defaults to 0, the
+ \l {QAbstractSlider::maximum} {maximum} to 99, with a
+ \l {QAbstractSlider::singleStep} {singleStep} size of 1 and a
+ \l {QAbstractSlider::pageStep} {pageStep} size of 10, and an
+ initial \l {QAbstractSlider::value} {value} of 0.
+*/
+QScrollBar::QScrollBar(QWidget *parent)
+ : QAbstractSlider(*new QScrollBarPrivate, parent)
+{
+ d_func()->orientation = Qt::Vertical;
+ d_func()->init();
+}
+
+/*!
+ Constructs a scroll bar with the given \a orientation.
+
+ The \a parent argument is passed to the QWidget constructor.
+
+ The \l {QAbstractSlider::minimum} {minimum} defaults to 0, the
+ \l {QAbstractSlider::maximum} {maximum} to 99, with a
+ \l {QAbstractSlider::singleStep} {singleStep} size of 1 and a
+ \l {QAbstractSlider::pageStep} {pageStep} size of 10, and an
+ initial \l {QAbstractSlider::value} {value} of 0.
+*/
+QScrollBar::QScrollBar(Qt::Orientation orientation, QWidget *parent)
+ : QAbstractSlider(*new QScrollBarPrivate, parent)
+{
+ d_func()->orientation = orientation;
+ d_func()->init();
+}
+
+
+#ifdef QT3_SUPPORT
+/*!
+ Use one of the constructors that doesn't take the \a name
+ argument and then use setObjectName() instead.
+*/
+QScrollBar::QScrollBar(QWidget *parent, const char *name)
+ : QAbstractSlider(*new QScrollBarPrivate, parent)
+{
+ setObjectName(QString::fromAscii(name));
+ d_func()->orientation = Qt::Vertical;
+ d_func()->init();
+}
+
+/*!
+ Use one of the constructors that doesn't take the \a name
+ argument and then use setObjectName() instead.
+*/
+QScrollBar::QScrollBar(Qt::Orientation orientation, QWidget *parent, const char *name)
+ : QAbstractSlider(*new QScrollBarPrivate, parent)
+{
+ setObjectName(QString::fromAscii(name));
+ d_func()->orientation = orientation;
+ d_func()->init();
+}
+
+/*!
+ Use one of the constructors that doesn't take the \a name
+ argument and then use setObjectName() instead.
+*/
+QScrollBar::QScrollBar(int minimum, int maximum, int lineStep, int pageStep,
+ int value, Qt::Orientation orientation,
+ QWidget *parent, const char *name)
+ : QAbstractSlider(*new QScrollBarPrivate, parent)
+{
+ Q_D(QScrollBar);
+ setObjectName(QString::fromAscii(name));
+ d->minimum = minimum;
+ d->maximum = maximum;
+ d->singleStep = lineStep;
+ d->pageStep = pageStep;
+ d->value = value;
+ d->orientation = orientation;
+ d->init();
+}
+#endif // QT3_SUPPORT
+
+/*!
+ Destroys the scroll bar.
+*/
+QScrollBar::~QScrollBar()
+{
+}
+
+void QScrollBarPrivate::init()
+{
+ Q_Q(QScrollBar);
+ invertedControls = true;
+ pressedControl = hoverControl = QStyle::SC_None;
+ pointerOutsidePressedControl = false;
+ q->setFocusPolicy(Qt::NoFocus);
+ QSizePolicy sp(QSizePolicy::Minimum, QSizePolicy::Fixed, QSizePolicy::Slider);
+ if (orientation == Qt::Vertical)
+ sp.transpose();
+ q->setSizePolicy(sp);
+ q->setAttribute(Qt::WA_WState_OwnSizePolicy, false);
+ q->setAttribute(Qt::WA_OpaquePaintEvent);
+
+#if !defined(QT_NO_CONTEXTMENU) && defined(Q_WS_WINCE)
+ if (!q->style()->styleHint(QStyle::SH_ScrollBar_ContextMenu, 0, q)) {
+ q->setContextMenuPolicy(Qt::PreventContextMenu);
+ }
+#endif
+}
+
+#ifndef QT_NO_CONTEXTMENU
+/*! \reimp */
+void QScrollBar::contextMenuEvent(QContextMenuEvent *event)
+{
+ if (!style()->styleHint(QStyle::SH_ScrollBar_ContextMenu, 0, this)) {
+ QAbstractSlider::contextMenuEvent(event);
+ return ;
+ }
+
+#ifndef QT_NO_MENU
+ bool horiz = HORIZONTAL;
+ 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)
+ setValue(d_func()->pixelPosToRangeValue(horiz ? event->pos().x() : event->pos().y()));
+ else if (actionSelected == actScrollTop)
+ triggerAction(QAbstractSlider::SliderToMinimum);
+ else if (actionSelected == actScrollBottom)
+ triggerAction(QAbstractSlider::SliderToMaximum);
+ else if (actionSelected == actPageUp)
+ triggerAction(QAbstractSlider::SliderPageStepSub);
+ else if (actionSelected == actPageDn)
+ triggerAction(QAbstractSlider::SliderPageStepAdd);
+ else if (actionSelected == actScrollUp)
+ triggerAction(QAbstractSlider::SliderSingleStepSub);
+ else if (actionSelected == actScrollDn)
+ triggerAction(QAbstractSlider::SliderSingleStepAdd);
+#endif // QT_NO_MENU
+}
+#endif // QT_NO_CONTEXTMENU
+
+
+/*! \reimp */
+QSize QScrollBar::sizeHint() const
+{
+ ensurePolished();
+ QStyleOptionSlider opt;
+ initStyleOption(&opt);
+
+ int scrollBarExtent = style()->pixelMetric(QStyle::PM_ScrollBarExtent, &opt, this);
+ int scrollBarSliderMin = style()->pixelMetric(QStyle::PM_ScrollBarSliderMin, &opt, this);
+ QSize size;
+ if (opt.orientation == Qt::Horizontal)
+ size = QSize(scrollBarExtent * 2 + scrollBarSliderMin, scrollBarExtent);
+ else
+ size = QSize(scrollBarExtent, scrollBarExtent * 2 + scrollBarSliderMin);
+
+ return style()->sizeFromContents(QStyle::CT_ScrollBar, &opt, size, this)
+ .expandedTo(QApplication::globalStrut());
+ }
+
+/*!\reimp */
+void QScrollBar::sliderChange(SliderChange change)
+{
+ QAbstractSlider::sliderChange(change);
+}
+
+/*!
+ \reimp
+*/
+bool QScrollBar::event(QEvent *event)
+{
+ switch(event->type()) {
+ case QEvent::HoverEnter:
+ case QEvent::HoverLeave:
+ case QEvent::HoverMove:
+ if (const QHoverEvent *he = static_cast<const QHoverEvent *>(event))
+ d_func()->updateHoverControl(he->pos());
+ break;
+#ifndef QT_NO_WHEELEVENT
+ case QEvent::Wheel: {
+ event->ignore();
+ // override wheel event without adding virtual function override
+ QWheelEvent *ev = static_cast<QWheelEvent *>(event);
+ int delta = ev->delta();
+ // scrollbar is a special case - in vertical mode it reaches minimum
+ // value in the upper position, however QSlider's minimum value is on
+ // the bottom. So we need to invert a value, but since the scrollbar is
+ // inverted by default, we need to inverse the delta value for the
+ // horizontal orientation.
+ if (ev->orientation() == Qt::Horizontal)
+ delta = -delta;
+ Q_D(QScrollBar);
+ if (d->scrollByDelta(ev->orientation(), ev->modifiers(), delta))
+ event->accept();
+ return true;
+ }
+#endif
+ default:
+ break;
+ }
+ return QAbstractSlider::event(event);
+}
+
+/*!
+ \reimp
+*/
+void QScrollBar::paintEvent(QPaintEvent *)
+{
+ Q_D(QScrollBar);
+ QPainter p(this);
+ QStyleOptionSlider opt;
+ initStyleOption(&opt);
+ opt.subControls = QStyle::SC_All;
+ if (d->pressedControl) {
+ opt.activeSubControls = (QStyle::SubControl)d->pressedControl;
+ if (!d->pointerOutsidePressedControl)
+ opt.state |= QStyle::State_Sunken;
+ } else {
+ opt.activeSubControls = (QStyle::SubControl)d->hoverControl;
+ }
+ style()->drawComplexControl(QStyle::CC_ScrollBar, &opt, &p, this);
+}
+
+/*!
+ \reimp
+*/
+void QScrollBar::mousePressEvent(QMouseEvent *e)
+{
+ Q_D(QScrollBar);
+
+ if (d->repeatActionTimer.isActive())
+ d->stopRepeatAction();
+
+ bool midButtonAbsPos = style()->styleHint(QStyle::SH_ScrollBar_MiddleClickAbsolutePosition,
+ 0, this);
+ QStyleOptionSlider opt;
+ initStyleOption(&opt);
+
+ if (d->maximum == d->minimum // no range
+ || (e->buttons() & (~e->button())) // another button was clicked before
+ || !(e->button() == Qt::LeftButton || (midButtonAbsPos && e->button() == Qt::MidButton)))
+ return;
+
+ d->pressedControl = style()->hitTestComplexControl(QStyle::CC_ScrollBar, &opt, e->pos(), this);
+ d->pointerOutsidePressedControl = false;
+
+ QRect sr = style()->subControlRect(QStyle::CC_ScrollBar, &opt,
+ QStyle::SC_ScrollBarSlider, this);
+ QPoint click = e->pos();
+ QPoint pressValue = click - sr.center() + sr.topLeft();
+ d->pressValue = d->orientation == Qt::Horizontal ? d->pixelPosToRangeValue(pressValue.x()) :
+ d->pixelPosToRangeValue(pressValue.y());
+ if (d->pressedControl == QStyle::SC_ScrollBarSlider) {
+ d->clickOffset = HORIZONTAL ? (click.x()-sr.x()) : (click.y()-sr.y());
+ d->snapBackPosition = d->position;
+ }
+
+ if ((d->pressedControl == QStyle::SC_ScrollBarAddPage
+ || d->pressedControl == QStyle::SC_ScrollBarSubPage)
+ && ((midButtonAbsPos && e->button() == Qt::MidButton)
+ || (style()->styleHint(QStyle::SH_ScrollBar_LeftClickAbsolutePosition, &opt, this)
+ && e->button() == Qt::LeftButton))) {
+ int sliderLength = HORIZONTAL ? sr.width() : sr.height();
+ setSliderPosition(d->pixelPosToRangeValue((HORIZONTAL ? e->pos().x()
+ : e->pos().y()) - sliderLength / 2));
+ d->pressedControl = QStyle::SC_ScrollBarSlider;
+ d->clickOffset = sliderLength / 2;
+ }
+ const int initialDelay = 500; // default threshold
+ d->activateControl(d->pressedControl, initialDelay);
+ QElapsedTimer time;
+ time.start();
+ repaint(style()->subControlRect(QStyle::CC_ScrollBar, &opt, d->pressedControl, this));
+ if (time.elapsed() >= initialDelay && d->repeatActionTimer.isActive()) {
+ // It took more than 500ms (the initial timer delay) to process the repaint(), we
+ // therefore need to restart the timer in case we have a pending mouse release event;
+ // otherwise we'll get a timer event right before the release event,
+ // causing the repeat action to be invoked twice on a single mouse click.
+ // 50ms is the default repeat time (see activateControl/setRepeatAction).
+ d->repeatActionTimer.start(50, this);
+ }
+ if (d->pressedControl == QStyle::SC_ScrollBarSlider)
+ setSliderDown(true);
+}
+
+
+/*!
+ \reimp
+*/
+void QScrollBar::mouseReleaseEvent(QMouseEvent *e)
+{
+ Q_D(QScrollBar);
+ if (!d->pressedControl)
+ return;
+
+ if (e->buttons() & (~e->button())) // some other button is still pressed
+ return;
+
+ d->stopRepeatAction();
+}
+
+
+/*!
+ \reimp
+*/
+void QScrollBar::mouseMoveEvent(QMouseEvent *e)
+{
+ Q_D(QScrollBar);
+ if (!d->pressedControl)
+ return;
+
+ QStyleOptionSlider opt;
+ initStyleOption(&opt);
+ if (!(e->buttons() & Qt::LeftButton
+ || ((e->buttons() & Qt::MidButton)
+ && style()->styleHint(QStyle::SH_ScrollBar_MiddleClickAbsolutePosition, &opt, this))))
+ return;
+
+ if (d->pressedControl == QStyle::SC_ScrollBarSlider) {
+ QPoint click = e->pos();
+ int newPosition = d->pixelPosToRangeValue((HORIZONTAL ? click.x() : click.y()) -d->clickOffset);
+ int m = style()->pixelMetric(QStyle::PM_MaximumDragDistance, &opt, this);
+ if (m >= 0) {
+ QRect r = rect();
+ r.adjust(-m, -m, m, m);
+ if (! r.contains(e->pos()))
+ newPosition = d->snapBackPosition;
+ }
+ setSliderPosition(newPosition);
+ } else if (!style()->styleHint(QStyle::SH_ScrollBar_ScrollWhenPointerLeavesControl, &opt, this)) {
+
+ if (style()->styleHint(QStyle::SH_ScrollBar_RollBetweenButtons, &opt, this)
+ && d->pressedControl & (QStyle::SC_ScrollBarAddLine | QStyle::SC_ScrollBarSubLine)) {
+ QStyle::SubControl newSc = style()->hitTestComplexControl(QStyle::CC_ScrollBar, &opt, e->pos(), this);
+ if (newSc == d->pressedControl && !d->pointerOutsidePressedControl)
+ return; // nothing to do
+ if (newSc & (QStyle::SC_ScrollBarAddLine | QStyle::SC_ScrollBarSubLine)) {
+ d->pointerOutsidePressedControl = false;
+ QRect scRect = style()->subControlRect(QStyle::CC_ScrollBar, &opt, newSc, this);
+ scRect |= style()->subControlRect(QStyle::CC_ScrollBar, &opt, d->pressedControl, this);
+ d->pressedControl = newSc;
+ d->activateControl(d->pressedControl, 0);
+ update(scRect);
+ return;
+ }
+ }
+
+ // stop scrolling when the mouse pointer leaves a control
+ // similar to push buttons
+ QRect pr = style()->subControlRect(QStyle::CC_ScrollBar, &opt, d->pressedControl, this);
+ if (pr.contains(e->pos()) == d->pointerOutsidePressedControl) {
+ if ((d->pointerOutsidePressedControl = !d->pointerOutsidePressedControl)) {
+ d->pointerOutsidePressedControl = true;
+ setRepeatAction(SliderNoAction);
+ repaint(pr);
+ } else {
+ d->activateControl(d->pressedControl);
+ }
+ }
+ }
+}
+
+
+int QScrollBarPrivate::pixelPosToRangeValue(int pos) const
+{
+ Q_Q(const QScrollBar);
+ QStyleOptionSlider opt;
+ q->initStyleOption(&opt);
+ QRect gr = q->style()->subControlRect(QStyle::CC_ScrollBar, &opt,
+ QStyle::SC_ScrollBarGroove, q);
+ QRect sr = q->style()->subControlRect(QStyle::CC_ScrollBar, &opt,
+ QStyle::SC_ScrollBarSlider, q);
+ int sliderMin, sliderMax, sliderLength;
+
+ if (orientation == Qt::Horizontal) {
+ sliderLength = sr.width();
+ sliderMin = gr.x();
+ sliderMax = gr.right() - sliderLength + 1;
+ if (q->layoutDirection() == Qt::RightToLeft)
+ opt.upsideDown = !opt.upsideDown;
+ } else {
+ sliderLength = sr.height();
+ sliderMin = gr.y();
+ sliderMax = gr.bottom() - sliderLength + 1;
+ }
+
+ return QStyle::sliderValueFromPosition(minimum, maximum, pos - sliderMin,
+ sliderMax - sliderMin, opt.upsideDown);
+}
+
+/*! \reimp
+*/
+void QScrollBar::hideEvent(QHideEvent *)
+{
+ Q_D(QScrollBar);
+ if (d->pressedControl) {
+ d->pressedControl = QStyle::SC_None;
+ setRepeatAction(SliderNoAction);
+ }
+}
+
+/*!
+ \fn bool QScrollBar::draggingSlider()
+
+ Use isSliderDown() instead.
+*/
+
+/*! \internal
+ Returns the style option for scroll bar.
+*/
+Q_WIDGETS_EXPORT QStyleOptionSlider qt_qscrollbarStyleOption(QScrollBar *scrollbar)
+{
+ QStyleOptionSlider opt;
+ scrollbar->initStyleOption(&opt);
+ return opt;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_SCROLLBAR
diff --git a/src/widgets/widgets/qscrollbar.h b/src/widgets/widgets/qscrollbar.h
new file mode 100644
index 0000000000..2fd00de522
--- /dev/null
+++ b/src/widgets/widgets/qscrollbar.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSCROLLBAR_H
+#define QSCROLLBAR_H
+
+#include <QtWidgets/qwidget.h>
+#include <QtWidgets/qabstractslider.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_SCROLLBAR
+
+class QScrollBarPrivate;
+class QStyleOptionSlider;
+
+class Q_WIDGETS_EXPORT QScrollBar : public QAbstractSlider
+{
+ Q_OBJECT
+public:
+ explicit QScrollBar(QWidget *parent=0);
+ explicit QScrollBar(Qt::Orientation, QWidget *parent=0);
+ ~QScrollBar();
+
+ QSize sizeHint() const;
+ bool event(QEvent *event);
+
+protected:
+ void paintEvent(QPaintEvent *);
+ void mousePressEvent(QMouseEvent *);
+ void mouseReleaseEvent(QMouseEvent *);
+ void mouseMoveEvent(QMouseEvent *);
+ void hideEvent(QHideEvent*);
+ void sliderChange(SliderChange change);
+#ifndef QT_NO_CONTEXTMENU
+ void contextMenuEvent(QContextMenuEvent *);
+#endif
+ void initStyleOption(QStyleOptionSlider *option) const;
+
+#ifdef QT3_SUPPORT
+public:
+ QT3_SUPPORT_CONSTRUCTOR QScrollBar(QWidget *parent, const char* name);
+ QT3_SUPPORT_CONSTRUCTOR QScrollBar(Qt::Orientation, QWidget *parent, const char* name);
+ QT3_SUPPORT_CONSTRUCTOR QScrollBar(int minValue, int maxValue, int lineStep, int pageStep,
+ int value, Qt::Orientation, QWidget *parent=0, const char* name = 0);
+ inline QT3_SUPPORT bool draggingSlider() { return isSliderDown(); }
+#endif
+
+private:
+ friend Q_WIDGETS_EXPORT QStyleOptionSlider qt_qscrollbarStyleOption(QScrollBar *scrollBar);
+
+ Q_DISABLE_COPY(QScrollBar)
+ Q_DECLARE_PRIVATE(QScrollBar)
+};
+
+#endif // QT_NO_SCROLLBAR
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QSCROLLBAR_H
diff --git a/src/widgets/widgets/qsizegrip.cpp b/src/widgets/widgets/qsizegrip.cpp
new file mode 100644
index 0000000000..10e99ba135
--- /dev/null
+++ b/src/widgets/widgets/qsizegrip.cpp
@@ -0,0 +1,570 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qsizegrip.h"
+
+#ifndef QT_NO_SIZEGRIP
+
+#include "qapplication.h"
+#include "qevent.h"
+#include "qpainter.h"
+#include "qstyle.h"
+#include "qstyleoption.h"
+#include "qlayout.h"
+#include "qdebug.h"
+#include <QDesktopWidget>
+
+#if defined(Q_WS_X11)
+#include <private/qt_x11_p.h>
+#elif defined (Q_WS_WIN)
+#include "qt_windows.h"
+#endif
+#ifdef Q_WS_MAC
+#include <private/qt_mac_p.h>
+#endif
+
+#include <private/qwidget_p.h>
+#include <QtWidgets/qabstractscrollarea.h>
+
+#define SZ_SIZEBOTTOMRIGHT 0xf008
+#define SZ_SIZEBOTTOMLEFT 0xf007
+#define SZ_SIZETOPLEFT 0xf004
+#define SZ_SIZETOPRIGHT 0xf005
+
+QT_BEGIN_NAMESPACE
+
+static QWidget *qt_sizegrip_topLevelWidget(QWidget* w)
+{
+ while (w && !w->isWindow() && w->windowType() != Qt::SubWindow)
+ w = w->parentWidget();
+ return w;
+}
+
+class QSizeGripPrivate : public QWidgetPrivate
+{
+ Q_DECLARE_PUBLIC(QSizeGrip)
+public:
+ void init();
+ QPoint p;
+ QRect r;
+ int d;
+ int dxMax;
+ int dyMax;
+ Qt::Corner m_corner;
+ bool gotMousePress;
+ QWidget *tlw;
+#ifdef Q_WS_MAC
+ void updateMacSizer(bool hide) const;
+#endif
+ Qt::Corner corner() const;
+ inline bool atBottom() const
+ {
+ return m_corner == Qt::BottomRightCorner || m_corner == Qt::BottomLeftCorner;
+ }
+
+ inline bool atLeft() const
+ {
+ return m_corner == Qt::BottomLeftCorner || m_corner == Qt::TopLeftCorner;
+ }
+
+ void updateTopLevelWidget()
+ {
+ Q_Q(QSizeGrip);
+ QWidget *w = qt_sizegrip_topLevelWidget(q);
+ if (tlw == w)
+ return;
+ if (tlw)
+ tlw->removeEventFilter(q);
+ tlw = w;
+ if (tlw)
+ tlw->installEventFilter(q);
+ }
+
+ // This slot is invoked by QLayout when the size grip is added to
+ // a layout or reparented after the tlw is shown. This re-implementation is basically
+ // the same as QWidgetPrivate::_q_showIfNotHidden except that it checks
+ // for Qt::WindowFullScreen and Qt::WindowMaximized as well.
+ void _q_showIfNotHidden()
+ {
+ Q_Q(QSizeGrip);
+ bool showSizeGrip = !(q->isHidden() && q->testAttribute(Qt::WA_WState_ExplicitShowHide));
+ updateTopLevelWidget();
+ if (tlw && showSizeGrip) {
+ Qt::WindowStates sizeGripNotVisibleState = Qt::WindowFullScreen;
+#ifndef Q_WS_MAC
+ sizeGripNotVisibleState |= Qt::WindowMaximized;
+#endif
+ // Don't show the size grip if the tlw is maximized or in full screen mode.
+ showSizeGrip = !(tlw->windowState() & sizeGripNotVisibleState);
+ }
+ if (showSizeGrip)
+ q->setVisible(true);
+ }
+};
+
+#ifdef Q_WS_MAC
+void QSizeGripPrivate::updateMacSizer(bool hide) const
+{
+ Q_Q(const QSizeGrip);
+ if (QApplication::closingDown() || !parent)
+ return;
+ QWidget *topLevelWindow = qt_sizegrip_topLevelWidget(const_cast<QSizeGrip *>(q));
+ if(topLevelWindow && topLevelWindow->isWindow())
+ QWidgetPrivate::qt_mac_update_sizer(topLevelWindow, hide ? -1 : 1);
+}
+#endif
+
+Qt::Corner QSizeGripPrivate::corner() const
+{
+ Q_Q(const QSizeGrip);
+ QWidget *tlw = qt_sizegrip_topLevelWidget(const_cast<QSizeGrip *>(q));
+ const QPoint sizeGripPos = q->mapTo(tlw, QPoint(0, 0));
+ bool isAtBottom = sizeGripPos.y() >= tlw->height() / 2;
+ bool isAtLeft = sizeGripPos.x() <= tlw->width() / 2;
+ if (isAtLeft)
+ return isAtBottom ? Qt::BottomLeftCorner : Qt::TopLeftCorner;
+ else
+ return isAtBottom ? Qt::BottomRightCorner : Qt::TopRightCorner;
+}
+
+/*!
+ \class QSizeGrip
+
+ \brief The QSizeGrip class provides a resize handle for resizing top-level windows.
+
+ \ingroup mainwindow-classes
+ \ingroup basicwidgets
+
+ This widget works like the standard Windows resize handle. In the
+ X11 version this resize handle generally works differently from
+ the one provided by the system if the X11 window manager does not
+ support necessary modern post-ICCCM specifications.
+
+ Put this widget anywhere in a widget tree and the user can use it
+ to resize the top-level window or any widget with the Qt::SubWindow
+ flag set. Generally, this should be in the lower right-hand corner.
+ Note that QStatusBar already uses this widget, so if you have a
+ status bar (e.g., you are using QMainWindow), then you don't need
+ to use this widget explicitly.
+
+ On some platforms the size grip automatically hides itself when the
+ window is shown full screen or maximised.
+
+ \table 50%
+ \row \o \inlineimage plastique-sizegrip.png Screenshot of a Plastique style size grip
+ \o A size grip widget at the bottom-right corner of a main window, shown in the
+ \l{Plastique Style Widget Gallery}{Plastique widget style}.
+ \endtable
+
+ The QSizeGrip class inherits QWidget and reimplements the \l
+ {QWidget::mousePressEvent()}{mousePressEvent()} and \l
+ {QWidget::mouseMoveEvent()}{mouseMoveEvent()} functions to feature
+ the resize functionality, and the \l
+ {QWidget::paintEvent()}{paintEvent()} function to render the
+ size grip widget.
+
+ \sa QStatusBar QWidget::windowState()
+*/
+
+
+/*!
+ Constructs a resize corner as a child widget of the given \a
+ parent.
+*/
+QSizeGrip::QSizeGrip(QWidget * parent)
+ : QWidget(*new QSizeGripPrivate, parent, 0)
+{
+ Q_D(QSizeGrip);
+ d->init();
+}
+
+#ifdef QT3_SUPPORT
+/*!
+ \obsolete
+
+ Constructs a resize corner with the given \a name, as a child
+ widget of the given \a parent.
+*/
+QSizeGrip::QSizeGrip(QWidget * parent, const char* name)
+ : QWidget(*new QSizeGripPrivate, parent, 0)
+{
+ Q_D(QSizeGrip);
+ setObjectName(QString::fromAscii(name));
+ d->init();
+}
+#endif
+
+void QSizeGripPrivate::init()
+{
+ Q_Q(QSizeGrip);
+ dxMax = 0;
+ dyMax = 0;
+ tlw = 0;
+ m_corner = q->isLeftToRight() ? Qt::BottomRightCorner : Qt::BottomLeftCorner;
+ gotMousePress = false;
+
+#if !defined(QT_NO_CURSOR) && !defined(Q_WS_MAC)
+ q->setCursor(m_corner == Qt::TopLeftCorner || m_corner == Qt::BottomRightCorner
+ ? Qt::SizeFDiagCursor : Qt::SizeBDiagCursor);
+#endif
+ q->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed));
+ updateTopLevelWidget();
+}
+
+
+/*!
+ Destroys this size grip.
+*/
+QSizeGrip::~QSizeGrip()
+{
+}
+
+/*!
+ \reimp
+*/
+QSize QSizeGrip::sizeHint() const
+{
+ QStyleOption opt(0);
+ opt.init(this);
+ return (style()->sizeFromContents(QStyle::CT_SizeGrip, &opt, QSize(13, 13), this).
+ expandedTo(QApplication::globalStrut()));
+}
+
+/*!
+ Paints the resize grip.
+
+ Resize grips are usually rendered as small diagonal textured lines
+ in the lower-right corner. The paint event is passed in the \a
+ event parameter.
+*/
+void QSizeGrip::paintEvent(QPaintEvent *event)
+{
+ Q_UNUSED(event);
+ Q_D(QSizeGrip);
+ QPainter painter(this);
+ QStyleOptionSizeGrip opt;
+ opt.init(this);
+ opt.corner = d->m_corner;
+ style()->drawControl(QStyle::CE_SizeGrip, &opt, &painter, this);
+}
+
+/*!
+ \fn void QSizeGrip::mousePressEvent(QMouseEvent * event)
+
+ Receives the mouse press events for the widget, and primes the
+ resize operation. The mouse press event is passed in the \a event
+ parameter.
+*/
+void QSizeGrip::mousePressEvent(QMouseEvent * e)
+{
+ if (e->button() != Qt::LeftButton) {
+ QWidget::mousePressEvent(e);
+ return;
+ }
+
+ Q_D(QSizeGrip);
+ QWidget *tlw = qt_sizegrip_topLevelWidget(this);
+ d->p = e->globalPos();
+ d->gotMousePress = true;
+ d->r = tlw->geometry();
+
+#ifdef Q_WS_X11
+ // Use a native X11 sizegrip for "real" top-level windows if supported.
+ if (tlw->isWindow() && X11->isSupportedByWM(ATOM(_NET_WM_MOVERESIZE))
+ && !(tlw->windowFlags() & Qt::X11BypassWindowManagerHint)
+ && !tlw->testAttribute(Qt::WA_DontShowOnScreen) && !qt_widget_private(tlw)->hasHeightForWidth()) {
+ XEvent xev;
+ xev.xclient.type = ClientMessage;
+ xev.xclient.message_type = ATOM(_NET_WM_MOVERESIZE);
+ xev.xclient.display = X11->display;
+ xev.xclient.window = tlw->winId();
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = e->globalPos().x();
+ xev.xclient.data.l[1] = e->globalPos().y();
+ if (d->atBottom())
+ xev.xclient.data.l[2] = d->atLeft() ? 6 : 4; // bottomleft/bottomright
+ else
+ xev.xclient.data.l[2] = d->atLeft() ? 0 : 2; // topleft/topright
+ xev.xclient.data.l[3] = Button1;
+ xev.xclient.data.l[4] = 0;
+ XUngrabPointer(X11->display, X11->time);
+ XSendEvent(X11->display, QX11Info::appRootWindow(x11Info().screen()), False,
+ SubstructureRedirectMask | SubstructureNotifyMask, &xev);
+ return;
+ }
+#endif // Q_WS_X11
+#ifdef Q_WS_WIN
+ if (tlw->isWindow() && !tlw->testAttribute(Qt::WA_DontShowOnScreen) && !qt_widget_private(tlw)->hasHeightForWidth()) {
+ uint orientation = 0;
+ if (d->atBottom())
+ orientation = d->atLeft() ? SZ_SIZEBOTTOMLEFT : SZ_SIZEBOTTOMRIGHT;
+ else
+ orientation = d->atLeft() ? SZ_SIZETOPLEFT : SZ_SIZETOPRIGHT;
+
+ ReleaseCapture();
+ PostMessage(tlw->winId(), WM_SYSCOMMAND, orientation, 0);
+ return;
+ }
+#endif // Q_WS_WIN
+
+ // Find available desktop/workspace geometry.
+ QRect availableGeometry;
+ bool hasVerticalSizeConstraint = true;
+ bool hasHorizontalSizeConstraint = true;
+ if (tlw->isWindow())
+ availableGeometry = QApplication::desktop()->availableGeometry(tlw);
+ else {
+ const QWidget *tlwParent = tlw->parentWidget();
+ // Check if tlw is inside QAbstractScrollArea/QScrollArea.
+ // If that's the case tlw->parentWidget() will return the viewport
+ // and tlw->parentWidget()->parentWidget() will return the scroll area.
+#ifndef QT_NO_SCROLLAREA
+ QAbstractScrollArea *scrollArea = qobject_cast<QAbstractScrollArea *>(tlwParent->parentWidget());
+ if (scrollArea) {
+ hasHorizontalSizeConstraint = scrollArea->horizontalScrollBarPolicy() == Qt::ScrollBarAlwaysOff;
+ hasVerticalSizeConstraint = scrollArea->verticalScrollBarPolicy() == Qt::ScrollBarAlwaysOff;
+ }
+#endif // QT_NO_SCROLLAREA
+ availableGeometry = tlwParent->contentsRect();
+ }
+
+ // Find frame geometries, title bar height, and decoration sizes.
+ const QRect frameGeometry = tlw->frameGeometry();
+ const int titleBarHeight = qMax(tlw->geometry().y() - frameGeometry.y(), 0);
+ const int bottomDecoration = qMax(frameGeometry.height() - tlw->height() - titleBarHeight, 0);
+ const int leftRightDecoration = qMax((frameGeometry.width() - tlw->width()) / 2, 0);
+
+ // Determine dyMax depending on whether the sizegrip is at the bottom
+ // of the widget or not.
+ if (d->atBottom()) {
+ if (hasVerticalSizeConstraint)
+ d->dyMax = availableGeometry.bottom() - d->r.bottom() - bottomDecoration;
+ else
+ d->dyMax = INT_MAX;
+ } else {
+ if (hasVerticalSizeConstraint)
+ d->dyMax = availableGeometry.y() - d->r.y() + titleBarHeight;
+ else
+ d->dyMax = -INT_MAX;
+ }
+
+ // In RTL mode, the size grip is to the left; find dxMax from the desktop/workspace
+ // geometry, the size grip geometry and the width of the decoration.
+ if (d->atLeft()) {
+ if (hasHorizontalSizeConstraint)
+ d->dxMax = availableGeometry.x() - d->r.x() + leftRightDecoration;
+ else
+ d->dxMax = -INT_MAX;
+ } else {
+ if (hasHorizontalSizeConstraint)
+ d->dxMax = availableGeometry.right() - d->r.right() - leftRightDecoration;
+ else
+ d->dxMax = INT_MAX;
+ }
+}
+
+
+/*!
+ \fn void QSizeGrip::mouseMoveEvent(QMouseEvent * event)
+ Resizes the top-level widget containing this widget. The mouse
+ move event is passed in the \a event parameter.
+*/
+void QSizeGrip::mouseMoveEvent(QMouseEvent * e)
+{
+ if (e->buttons() != Qt::LeftButton) {
+ QWidget::mouseMoveEvent(e);
+ return;
+ }
+
+ Q_D(QSizeGrip);
+ QWidget* tlw = qt_sizegrip_topLevelWidget(this);
+ if (!d->gotMousePress || tlw->testAttribute(Qt::WA_WState_ConfigPending))
+ return;
+
+#ifdef Q_WS_X11
+ if (tlw->isWindow() && X11->isSupportedByWM(ATOM(_NET_WM_MOVERESIZE))
+ && tlw->isTopLevel() && !(tlw->windowFlags() & Qt::X11BypassWindowManagerHint)
+ && !tlw->testAttribute(Qt::WA_DontShowOnScreen) && !qt_widget_private(tlw)->hasHeightForWidth())
+ return;
+#endif
+#ifdef Q_WS_WIN
+ if (tlw->isWindow() && GetSystemMenu(tlw->winId(), FALSE) != 0 && internalWinId()
+ && !tlw->testAttribute(Qt::WA_DontShowOnScreen) && !qt_widget_private(tlw)->hasHeightForWidth()) {
+ MSG msg;
+ while(PeekMessage(&msg, winId(), WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE));
+ return;
+ }
+#endif
+
+ QPoint np(e->globalPos());
+
+ // Don't extend beyond the available geometry; bound to dyMax and dxMax.
+ QSize ns;
+ if (d->atBottom())
+ ns.rheight() = d->r.height() + qMin(np.y() - d->p.y(), d->dyMax);
+ else
+ ns.rheight() = d->r.height() - qMax(np.y() - d->p.y(), d->dyMax);
+
+ if (d->atLeft())
+ ns.rwidth() = d->r.width() - qMax(np.x() - d->p.x(), d->dxMax);
+ else
+ ns.rwidth() = d->r.width() + qMin(np.x() - d->p.x(), d->dxMax);
+
+ ns = QLayout::closestAcceptableSize(tlw, ns);
+
+ QPoint p;
+ QRect nr(p, ns);
+ if (d->atBottom()) {
+ if (d->atLeft())
+ nr.moveTopRight(d->r.topRight());
+ else
+ nr.moveTopLeft(d->r.topLeft());
+ } else {
+ if (d->atLeft())
+ nr.moveBottomRight(d->r.bottomRight());
+ else
+ nr.moveBottomLeft(d->r.bottomLeft());
+ }
+
+ tlw->setGeometry(nr);
+}
+
+/*!
+ \reimp
+*/
+void QSizeGrip::mouseReleaseEvent(QMouseEvent *mouseEvent)
+{
+ if (mouseEvent->button() == Qt::LeftButton) {
+ Q_D(QSizeGrip);
+ d->gotMousePress = false;
+ d->p = QPoint();
+ } else {
+ QWidget::mouseReleaseEvent(mouseEvent);
+ }
+}
+
+/*!
+ \reimp
+*/
+void QSizeGrip::moveEvent(QMoveEvent * /*moveEvent*/)
+{
+ Q_D(QSizeGrip);
+ // We're inside a resize operation; no update necessary.
+ if (!d->p.isNull())
+ return;
+
+ d->m_corner = d->corner();
+#if !defined(QT_NO_CURSOR) && !defined(Q_WS_MAC)
+ setCursor(d->m_corner == Qt::TopLeftCorner || d->m_corner == Qt::BottomRightCorner
+ ? Qt::SizeFDiagCursor : Qt::SizeBDiagCursor);
+#endif
+}
+
+/*!
+ \reimp
+*/
+void QSizeGrip::showEvent(QShowEvent *showEvent)
+{
+#ifdef Q_WS_MAC
+ d_func()->updateMacSizer(false);
+#endif
+ QWidget::showEvent(showEvent);
+}
+
+/*!
+ \reimp
+*/
+void QSizeGrip::hideEvent(QHideEvent *hideEvent)
+{
+#ifdef Q_WS_MAC
+ d_func()->updateMacSizer(true);
+#endif
+ QWidget::hideEvent(hideEvent);
+}
+
+/*!
+ \reimp
+*/
+void QSizeGrip::setVisible(bool visible)
+{
+ QWidget::setVisible(visible);
+}
+
+/*! \reimp */
+bool QSizeGrip::eventFilter(QObject *o, QEvent *e)
+{
+ Q_D(QSizeGrip);
+ if ((isHidden() && testAttribute(Qt::WA_WState_ExplicitShowHide))
+ || e->type() != QEvent::WindowStateChange
+ || o != d->tlw) {
+ return QWidget::eventFilter(o, e);
+ }
+ Qt::WindowStates sizeGripNotVisibleState = Qt::WindowFullScreen;
+#ifndef Q_WS_MAC
+ sizeGripNotVisibleState |= Qt::WindowMaximized;
+#endif
+ // Don't show the size grip if the tlw is maximized or in full screen mode.
+ setVisible(!(d->tlw->windowState() & sizeGripNotVisibleState));
+ setAttribute(Qt::WA_WState_ExplicitShowHide, false);
+ return QWidget::eventFilter(o, e);
+}
+
+/*!
+ \reimp
+*/
+bool QSizeGrip::event(QEvent *event)
+{
+ return QWidget::event(event);
+}
+
+#ifdef Q_WS_WIN
+/*! \reimp */
+bool QSizeGrip::winEvent( MSG *m, long *result )
+{
+ return QWidget::winEvent(m, result);
+}
+#endif
+
+QT_END_NAMESPACE
+
+#include "moc_qsizegrip.cpp"
+
+#endif //QT_NO_SIZEGRIP
diff --git a/src/widgets/widgets/qsizegrip.h b/src/widgets/widgets/qsizegrip.h
new file mode 100644
index 0000000000..9e75f38457
--- /dev/null
+++ b/src/widgets/widgets/qsizegrip.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSIZEGRIP_H
+#define QSIZEGRIP_H
+
+#include <QtWidgets/qwidget.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_SIZEGRIP
+class QSizeGripPrivate;
+class Q_WIDGETS_EXPORT QSizeGrip : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit QSizeGrip(QWidget *parent);
+ ~QSizeGrip();
+
+ QSize sizeHint() const;
+ void setVisible(bool);
+
+protected:
+ void paintEvent(QPaintEvent *);
+ void mousePressEvent(QMouseEvent *);
+ void mouseMoveEvent(QMouseEvent *);
+ void mouseReleaseEvent(QMouseEvent *mouseEvent);
+ void moveEvent(QMoveEvent *moveEvent);
+ void showEvent(QShowEvent *showEvent);
+ void hideEvent(QHideEvent *hideEvent);
+ bool eventFilter(QObject *, QEvent *);
+ bool event(QEvent *);
+#ifdef Q_WS_WIN
+ bool winEvent(MSG *m, long *result);
+#endif
+
+public:
+#ifdef QT3_SUPPORT
+ QT3_SUPPORT_CONSTRUCTOR QSizeGrip(QWidget *parent, const char *name);
+#endif
+
+private:
+ Q_DECLARE_PRIVATE(QSizeGrip)
+ Q_DISABLE_COPY(QSizeGrip)
+ Q_PRIVATE_SLOT(d_func(), void _q_showIfNotHidden())
+};
+#endif // QT_NO_SIZEGRIP
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QSIZEGRIP_H
diff --git a/src/widgets/widgets/qslider.cpp b/src/widgets/widgets/qslider.cpp
new file mode 100644
index 0000000000..2858b98781
--- /dev/null
+++ b/src/widgets/widgets/qslider.cpp
@@ -0,0 +1,666 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qslider.h"
+#ifndef QT_NO_SLIDER
+#ifndef QT_NO_ACCESSIBILITY
+#include "qaccessible.h"
+#endif
+#include "qapplication.h"
+#include "qevent.h"
+#include "qpainter.h"
+#include "qstyle.h"
+#include "qstyleoption.h"
+#include "private/qabstractslider_p.h"
+#include "qdebug.h"
+
+QT_BEGIN_NAMESPACE
+
+class QSliderPrivate : public QAbstractSliderPrivate
+{
+ Q_DECLARE_PUBLIC(QSlider)
+public:
+ QStyle::SubControl pressedControl;
+ int tickInterval;
+ QSlider::TickPosition tickPosition;
+ int clickOffset;
+ void init();
+ void resetLayoutItemMargins();
+ int pixelPosToRangeValue(int pos) const;
+ inline int pick(const QPoint &pt) const;
+
+ QStyle::SubControl newHoverControl(const QPoint &pos);
+ bool updateHoverControl(const QPoint &pos);
+ QStyle::SubControl hoverControl;
+ QRect hoverRect;
+};
+
+void QSliderPrivate::init()
+{
+ Q_Q(QSlider);
+ pressedControl = QStyle::SC_None;
+ tickInterval = 0;
+ tickPosition = QSlider::NoTicks;
+ hoverControl = QStyle::SC_None;
+ q->setFocusPolicy(Qt::FocusPolicy(q->style()->styleHint(QStyle::SH_Button_FocusPolicy)));
+ QSizePolicy sp(QSizePolicy::Expanding, QSizePolicy::Fixed, QSizePolicy::Slider);
+ if (orientation == Qt::Vertical)
+ sp.transpose();
+ q->setSizePolicy(sp);
+ q->setAttribute(Qt::WA_WState_OwnSizePolicy, false);
+ resetLayoutItemMargins();
+}
+
+void QSliderPrivate::resetLayoutItemMargins()
+{
+ Q_Q(QSlider);
+ QStyleOptionSlider opt;
+ q->initStyleOption(&opt);
+ setLayoutItemMargins(QStyle::SE_SliderLayoutItem, &opt);
+}
+
+int QSliderPrivate::pixelPosToRangeValue(int pos) const
+{
+ Q_Q(const QSlider);
+ QStyleOptionSlider opt;
+ q->initStyleOption(&opt);
+ QRect gr = q->style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderGroove, q);
+ QRect sr = q->style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, q);
+ int sliderMin, sliderMax, sliderLength;
+
+ if (orientation == Qt::Horizontal) {
+ sliderLength = sr.width();
+ sliderMin = gr.x();
+ sliderMax = gr.right() - sliderLength + 1;
+ } else {
+ sliderLength = sr.height();
+ sliderMin = gr.y();
+ sliderMax = gr.bottom() - sliderLength + 1;
+ }
+ return QStyle::sliderValueFromPosition(minimum, maximum, pos - sliderMin,
+ sliderMax - sliderMin, opt.upsideDown);
+}
+
+inline int QSliderPrivate::pick(const QPoint &pt) const
+{
+ return orientation == Qt::Horizontal ? pt.x() : pt.y();
+}
+
+/*!
+ Initialize \a option with the values from this QSlider. This method
+ is useful for subclasses when they need a QStyleOptionSlider, but don't want
+ to fill in all the information themselves.
+
+ \sa QStyleOption::initFrom()
+*/
+void QSlider::initStyleOption(QStyleOptionSlider *option) const
+{
+ if (!option)
+ return;
+
+ Q_D(const QSlider);
+ option->initFrom(this);
+ option->subControls = QStyle::SC_None;
+ option->activeSubControls = QStyle::SC_None;
+ option->orientation = d->orientation;
+ option->maximum = d->maximum;
+ option->minimum = d->minimum;
+ option->tickPosition = (QSlider::TickPosition)d->tickPosition;
+ option->tickInterval = d->tickInterval;
+ option->upsideDown = (d->orientation == Qt::Horizontal) ?
+ (d->invertedAppearance != (option->direction == Qt::RightToLeft))
+ : (!d->invertedAppearance);
+ option->direction = Qt::LeftToRight; // we use the upsideDown option instead
+ option->sliderPosition = d->position;
+ option->sliderValue = d->value;
+ option->singleStep = d->singleStep;
+ option->pageStep = d->pageStep;
+ if (d->orientation == Qt::Horizontal)
+ option->state |= QStyle::State_Horizontal;
+}
+
+bool QSliderPrivate::updateHoverControl(const QPoint &pos)
+{
+ Q_Q(QSlider);
+ QRect lastHoverRect = hoverRect;
+ QStyle::SubControl lastHoverControl = hoverControl;
+ bool doesHover = q->testAttribute(Qt::WA_Hover);
+ if (lastHoverControl != newHoverControl(pos) && doesHover) {
+ q->update(lastHoverRect);
+ q->update(hoverRect);
+ return true;
+ }
+ return !doesHover;
+}
+
+QStyle::SubControl QSliderPrivate::newHoverControl(const QPoint &pos)
+{
+ Q_Q(QSlider);
+ QStyleOptionSlider opt;
+ q->initStyleOption(&opt);
+ opt.subControls = QStyle::SC_All;
+ QRect handleRect = q->style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, q);
+ QRect grooveRect = q->style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderGroove, q);
+ QRect tickmarksRect = q->style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderTickmarks, q);
+
+ if (handleRect.contains(pos)) {
+ hoverRect = handleRect;
+ hoverControl = QStyle::SC_SliderHandle;
+ } else if (grooveRect.contains(pos)) {
+ hoverRect = grooveRect;
+ hoverControl = QStyle::SC_SliderGroove;
+ } else if (tickmarksRect.contains(pos)) {
+ hoverRect = tickmarksRect;
+ hoverControl = QStyle::SC_SliderTickmarks;
+ } else {
+ hoverRect = QRect();
+ hoverControl = QStyle::SC_None;
+ }
+
+ return hoverControl;
+}
+
+/*!
+ \class QSlider
+ \brief The QSlider widget provides a vertical or horizontal slider.
+
+ \ingroup basicwidgets
+
+
+ The slider is the classic widget for controlling a bounded value.
+ It lets the user move a slider handle along a horizontal or vertical
+ groove and translates the handle's position into an integer value
+ within the legal range.
+
+ QSlider has very few of its own functions; most of the functionality is in
+ QAbstractSlider. The most useful functions are setValue() to set
+ the slider directly to some value; triggerAction() to simulate
+ the effects of clicking (useful for shortcut keys);
+ setSingleStep(), setPageStep() to set the steps; and setMinimum()
+ and setMaximum() to define the range of the scroll bar.
+
+ QSlider provides methods for controlling tickmarks. You can use
+ setTickPosition() to indicate where you want the tickmarks to be,
+ setTickInterval() to indicate how many of them you want. the
+ currently set tick position and interval can be queried using the
+ tickPosition() and tickInterval() functions, respectively.
+
+ QSlider inherits a comprehensive set of signals:
+ \table
+ \header \o Signal \o Description
+ \row \o \l valueChanged()
+ \o Emitted when the slider's value has changed. The tracking()
+ determines whether this signal is emitted during user
+ interaction.
+ \row \o \l sliderPressed()
+ \o Emitted when the user starts to drag the slider.
+ \row \o \l sliderMoved()
+ \o Emitted when the user drags the slider.
+ \row \o \l sliderReleased()
+ \o Emitted when the user releases the slider.
+ \endtable
+
+ QSlider only provides integer ranges. Note that although
+ QSlider handles very large numbers, it becomes difficult for users
+ to use a slider accurately for very large ranges.
+
+ A slider accepts focus on Tab and provides both a mouse wheel and a
+ keyboard interface. The keyboard interface is the following:
+
+ \list
+ \o Left/Right move a horizontal slider by one single step.
+ \o Up/Down move a vertical slider by one single step.
+ \o PageUp moves up one page.
+ \o PageDown moves down one page.
+ \o Home moves to the start (mininum).
+ \o End moves to the end (maximum).
+ \endlist
+
+ \table 100%
+ \row \o \inlineimage macintosh-slider.png Screenshot of a Macintosh slider
+ \o A slider shown in the \l{Macintosh Style Widget Gallery}{Macintosh widget style}.
+ \row \o \inlineimage windows-slider.png Screenshot of a Windows XP slider
+ \o A slider shown in the \l{Windows XP Style Widget Gallery}{Windows XP widget style}.
+ \row \o \inlineimage plastique-slider.png Screenshot of a Plastique slider
+ \o A slider shown in the \l{Plastique Style Widget Gallery}{Plastique widget style}.
+ \endtable
+
+ \sa QScrollBar, QSpinBox, QDial, {fowler}{GUI Design Handbook: Slider}, {Sliders Example}
+*/
+
+
+/*!
+ \enum QSlider::TickPosition
+
+ This enum specifies where the tick marks are to be drawn relative
+ to the slider's groove and the handle the user moves.
+
+ \value NoTicks Do not draw any tick marks.
+ \value TicksBothSides Draw tick marks on both sides of the groove.
+ \value TicksAbove Draw tick marks above the (horizontal) slider
+ \value TicksBelow Draw tick marks below the (horizontal) slider
+ \value TicksLeft Draw tick marks to the left of the (vertical) slider
+ \value TicksRight Draw tick marks to the right of the (vertical) slider
+
+ \omitvalue NoMarks
+ \omitvalue Above
+ \omitvalue Left
+ \omitvalue Below
+ \omitvalue Right
+ \omitvalue Both
+*/
+
+
+/*!
+ Constructs a vertical slider with the given \a parent.
+*/
+QSlider::QSlider(QWidget *parent)
+ : QAbstractSlider(*new QSliderPrivate, parent)
+{
+ d_func()->orientation = Qt::Vertical;
+ d_func()->init();
+}
+
+/*!
+ Constructs a slider with the given \a parent. The \a orientation
+ parameter determines whether the slider is horizontal or vertical;
+ the valid values are Qt::Vertical and Qt::Horizontal.
+*/
+
+QSlider::QSlider(Qt::Orientation orientation, QWidget *parent)
+ : QAbstractSlider(*new QSliderPrivate, parent)
+{
+ d_func()->orientation = orientation;
+ d_func()->init();
+}
+
+#ifdef QT3_SUPPORT
+/*!
+ Use QSlider() and QObject::setObjectName() instead.
+
+ \oldcode
+ QSlider *mySlider = new QSlider(parent, name);
+ \newcode
+ QSlider *mySlider = new QSlider(parent);
+ mySlider->setObjectName(name);
+ \endcode
+*/
+QSlider::QSlider(QWidget *parent, const char *name)
+ : QAbstractSlider(*new QSliderPrivate, parent)
+{
+ setObjectName(QString::fromAscii(name));
+ d_func()->orientation = Qt::Vertical;
+ d_func()->init();
+}
+
+/*!
+ Use QSlider() and QObject::setObjectName() instead.
+
+ \oldcode
+ QSlider *mySlider = new QSlider(orientation, parent, name);
+ \newcode
+ QSlider *mySlider = new QSlider(orientation, parent);
+ mySlider->setObjectName(name);
+ \endcode
+*/
+QSlider::QSlider(Qt::Orientation orientation, QWidget *parent, const char *name)
+ : QAbstractSlider(*new QSliderPrivate, parent)
+{
+ setObjectName(QString::fromAscii(name));
+ d_func()->orientation = orientation;
+ d_func()->init();
+}
+
+/*!
+ Use QSlider(), QObject::setObjectName() and the functionality
+ inherited from QAbstractSlider instead.
+
+ \oldcode
+ QSlider *mySlider = new QSlider(minValue, maxValue, pageStep,
+ value, orientation, parent, name);
+ \newcode
+ QSlider *mySlider = new QSlider(orientation, parent);
+ mySlider->setObjectName(name);
+ mySlider->setMinimum(minValue);
+ mySlider->setMaximum(maxValue);
+ mySlider->setPageStep(pageStep);
+ mySlider->setValue(value);
+ \endcode
+*/
+QSlider::QSlider(int minValue, int maxValue, int pageStep, int value, Qt::Orientation orientation,
+ QWidget *parent, const char *name)
+ : QAbstractSlider(*new QSliderPrivate, parent)
+{
+ Q_D(QSlider);
+ setObjectName(QString::fromAscii(name));
+ d->minimum = minValue;
+ d->maximum = maxValue;
+ d->pageStep = pageStep;
+ d->position = d->value = value;
+ d->orientation = orientation;
+ d->init();
+}
+#endif
+
+/*!
+ Destroys this slider.
+*/
+QSlider::~QSlider()
+{
+}
+
+/*!
+ \reimp
+*/
+void QSlider::paintEvent(QPaintEvent *)
+{
+ Q_D(QSlider);
+ QPainter p(this);
+ QStyleOptionSlider opt;
+ initStyleOption(&opt);
+
+ opt.subControls = QStyle::SC_SliderGroove | QStyle::SC_SliderHandle;
+ if (d->tickPosition != NoTicks)
+ opt.subControls |= QStyle::SC_SliderTickmarks;
+ if (d->pressedControl) {
+ opt.activeSubControls = d->pressedControl;
+ opt.state |= QStyle::State_Sunken;
+ } else {
+ opt.activeSubControls = d->hoverControl;
+ }
+
+ style()->drawComplexControl(QStyle::CC_Slider, &opt, &p, this);
+}
+
+/*!
+ \reimp
+*/
+
+bool QSlider::event(QEvent *event)
+{
+ Q_D(QSlider);
+
+ switch(event->type()) {
+ case QEvent::HoverEnter:
+ case QEvent::HoverLeave:
+ case QEvent::HoverMove:
+ if (const QHoverEvent *he = static_cast<const QHoverEvent *>(event))
+ d->updateHoverControl(he->pos());
+ break;
+ case QEvent::StyleChange:
+ case QEvent::MacSizeChange:
+ d->resetLayoutItemMargins();
+ break;
+ default:
+ break;
+ }
+ return QAbstractSlider::event(event);
+}
+
+/*!
+ \reimp
+*/
+void QSlider::mousePressEvent(QMouseEvent *ev)
+{
+ Q_D(QSlider);
+ if (d->maximum == d->minimum || (ev->buttons() ^ ev->button())) {
+ ev->ignore();
+ return;
+ }
+#ifdef QT_KEYPAD_NAVIGATION
+ if (QApplication::keypadNavigationEnabled())
+ setEditFocus(true);
+#endif
+ ev->accept();
+ if ((ev->button() & style()->styleHint(QStyle::SH_Slider_AbsoluteSetButtons)) == ev->button()) {
+ QStyleOptionSlider opt;
+ initStyleOption(&opt);
+ const QRect sliderRect = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this);
+ const QPoint center = sliderRect.center() - sliderRect.topLeft();
+ // to take half of the slider off for the setSliderPosition call we use the center - topLeft
+
+ setSliderPosition(d->pixelPosToRangeValue(d->pick(ev->pos() - center)));
+ triggerAction(SliderMove);
+ setRepeatAction(SliderNoAction);
+ d->pressedControl = QStyle::SC_SliderHandle;
+ update();
+ } else if ((ev->button() & style()->styleHint(QStyle::SH_Slider_PageSetButtons)) == ev->button()) {
+ QStyleOptionSlider opt;
+ initStyleOption(&opt);
+ d->pressedControl = style()->hitTestComplexControl(QStyle::CC_Slider,
+ &opt, ev->pos(), this);
+ SliderAction action = SliderNoAction;
+ if (d->pressedControl == QStyle::SC_SliderGroove) {
+ const QRect sliderRect = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this);
+ int pressValue = d->pixelPosToRangeValue(d->pick(ev->pos() - sliderRect.center() + sliderRect.topLeft()));
+ d->pressValue = pressValue;
+ if (pressValue > d->value)
+ action = SliderPageStepAdd;
+ else if (pressValue < d->value)
+ action = SliderPageStepSub;
+ if (action) {
+ triggerAction(action);
+ setRepeatAction(action);
+ }
+ }
+ } else {
+ ev->ignore();
+ return;
+ }
+
+ if (d->pressedControl == QStyle::SC_SliderHandle) {
+ QStyleOptionSlider opt;
+ initStyleOption(&opt);
+ setRepeatAction(SliderNoAction);
+ QRect sr = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this);
+ d->clickOffset = d->pick(ev->pos() - sr.topLeft());
+ update(sr);
+ setSliderDown(true);
+ }
+}
+
+/*!
+ \reimp
+*/
+void QSlider::mouseMoveEvent(QMouseEvent *ev)
+{
+ Q_D(QSlider);
+ if (d->pressedControl != QStyle::SC_SliderHandle) {
+ ev->ignore();
+ return;
+ }
+ ev->accept();
+ int newPosition = d->pixelPosToRangeValue(d->pick(ev->pos()) - d->clickOffset);
+ QStyleOptionSlider opt;
+ initStyleOption(&opt);
+ setSliderPosition(newPosition);
+}
+
+
+/*!
+ \reimp
+*/
+void QSlider::mouseReleaseEvent(QMouseEvent *ev)
+{
+ Q_D(QSlider);
+ if (d->pressedControl == QStyle::SC_None || ev->buttons()) {
+ ev->ignore();
+ return;
+ }
+ ev->accept();
+ QStyle::SubControl oldPressed = QStyle::SubControl(d->pressedControl);
+ d->pressedControl = QStyle::SC_None;
+ setRepeatAction(SliderNoAction);
+ if (oldPressed == QStyle::SC_SliderHandle)
+ setSliderDown(false);
+ QStyleOptionSlider opt;
+ initStyleOption(&opt);
+ opt.subControls = oldPressed;
+ update(style()->subControlRect(QStyle::CC_Slider, &opt, oldPressed, this));
+}
+
+/*!
+ \reimp
+*/
+QSize QSlider::sizeHint() const
+{
+ Q_D(const QSlider);
+ ensurePolished();
+ const int SliderLength = 84, TickSpace = 5;
+ QStyleOptionSlider opt;
+ initStyleOption(&opt);
+ int thick = style()->pixelMetric(QStyle::PM_SliderThickness, &opt, this);
+ if (d->tickPosition & TicksAbove)
+ thick += TickSpace;
+ if (d->tickPosition & TicksBelow)
+ thick += TickSpace;
+ int w = thick, h = SliderLength;
+ if (d->orientation == Qt::Horizontal) {
+ w = SliderLength;
+ h = thick;
+ }
+ return style()->sizeFromContents(QStyle::CT_Slider, &opt, QSize(w, h), this).expandedTo(QApplication::globalStrut());
+}
+
+/*!
+ \reimp
+*/
+QSize QSlider::minimumSizeHint() const
+{
+ Q_D(const QSlider);
+ QSize s = sizeHint();
+ QStyleOptionSlider opt;
+ initStyleOption(&opt);
+ int length = style()->pixelMetric(QStyle::PM_SliderLength, &opt, this);
+ if (d->orientation == Qt::Horizontal)
+ s.setWidth(length);
+ else
+ s.setHeight(length);
+ return s;
+}
+
+/*!
+ \property QSlider::tickPosition
+ \brief the tickmark position for this slider
+
+ The valid values are described by the QSlider::TickPosition enum.
+
+ The default value is \l QSlider::NoTicks.
+
+ \sa tickInterval
+*/
+
+void QSlider::setTickPosition(TickPosition position)
+{
+ Q_D(QSlider);
+ d->tickPosition = position;
+ d->resetLayoutItemMargins();
+ update();
+ updateGeometry();
+}
+
+QSlider::TickPosition QSlider::tickPosition() const
+{
+ return d_func()->tickPosition;
+}
+
+/*!
+ \fn TickPosition QSlider::tickmarks() const
+ \compat
+
+ Use tickPosition() instead.
+*/
+
+/*!
+ \fn QSlider::setTickmarks(TickPosition position)
+ \compat
+
+ Use setTickPosition() instead.
+*/
+
+/*!
+ \property QSlider::tickInterval
+ \brief the interval between tickmarks
+
+ This is a value interval, not a pixel interval. If it is 0, the
+ slider will choose between singleStep() and pageStep().
+
+ The default value is 0.
+
+ \sa tickPosition, lineStep(), pageStep()
+*/
+
+void QSlider::setTickInterval(int ts)
+{
+ d_func()->tickInterval = qMax(0, ts);
+ update();
+}
+
+int QSlider::tickInterval() const
+{
+ return d_func()->tickInterval;
+}
+
+/*!
+ \fn void QSlider::addStep()
+
+ Use setValue() instead.
+*/
+
+/*!
+ \fn void QSlider::subtractStep()
+
+ Use setValue() instead.
+*/
+
+/*! \internal
+ Returns the style option for slider.
+*/
+Q_WIDGETS_EXPORT QStyleOptionSlider qt_qsliderStyleOption(QSlider *slider)
+{
+ QStyleOptionSlider sliderOption;
+ slider->initStyleOption(&sliderOption);
+ return sliderOption;
+}
+
+#endif
+
+QT_END_NAMESPACE
diff --git a/src/widgets/widgets/qslider.h b/src/widgets/widgets/qslider.h
new file mode 100644
index 0000000000..907548fcb2
--- /dev/null
+++ b/src/widgets/widgets/qslider.h
@@ -0,0 +1,134 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSLIDER_H
+#define QSLIDER_H
+
+#include <QtWidgets/qabstractslider.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_SLIDER
+
+class QSliderPrivate;
+class QStyleOptionSlider;
+class Q_WIDGETS_EXPORT QSlider : public QAbstractSlider
+{
+ Q_OBJECT
+
+ Q_ENUMS(TickPosition)
+ Q_PROPERTY(TickPosition tickPosition READ tickPosition WRITE setTickPosition)
+ Q_PROPERTY(int tickInterval READ tickInterval WRITE setTickInterval)
+
+public:
+ enum TickPosition {
+ NoTicks = 0,
+ TicksAbove = 1,
+ TicksLeft = TicksAbove,
+ TicksBelow = 2,
+ TicksRight = TicksBelow,
+ TicksBothSides = 3
+
+#if defined(QT3_SUPPORT) && !defined(Q_MOC_RUN)
+ ,NoMarks = NoTicks,
+ Above = TicksAbove,
+ Left = TicksAbove,
+ Below = TicksBelow,
+ Right = TicksRight,
+ Both = TicksBothSides
+#endif
+ };
+
+ explicit QSlider(QWidget *parent = 0);
+ explicit QSlider(Qt::Orientation orientation, QWidget *parent = 0);
+
+ ~QSlider();
+
+ QSize sizeHint() const;
+ QSize minimumSizeHint() const;
+
+ void setTickPosition(TickPosition position);
+ TickPosition tickPosition() const;
+
+ void setTickInterval(int ti);
+ int tickInterval() const;
+
+ bool event(QEvent *event);
+
+protected:
+ void paintEvent(QPaintEvent *ev);
+ void mousePressEvent(QMouseEvent *ev);
+ void mouseReleaseEvent(QMouseEvent *ev);
+ void mouseMoveEvent(QMouseEvent *ev);
+ void initStyleOption(QStyleOptionSlider *option) const;
+
+#ifdef QT3_SUPPORT
+public:
+ QT3_SUPPORT_CONSTRUCTOR QSlider(QWidget *parent, const char *name);
+ QT3_SUPPORT_CONSTRUCTOR QSlider(Qt::Orientation, QWidget *parent, const char *name);
+ QT3_SUPPORT_CONSTRUCTOR QSlider(int minValue, int maxValue, int pageStep, int value,
+ Qt::Orientation orientation,
+ QWidget *parent = 0, const char *name = 0);
+ inline QT3_SUPPORT void setTickmarks(TickPosition position) { setTickPosition(position); }
+ inline QT3_SUPPORT TickPosition tickmarks() const { return tickPosition(); }
+public Q_SLOTS:
+ inline QT_MOC_COMPAT void addStep() { triggerAction(SliderSingleStepAdd); }
+ inline QT_MOC_COMPAT void subtractStep() { triggerAction(SliderSingleStepSub); }
+#endif
+
+private:
+ friend Q_WIDGETS_EXPORT QStyleOptionSlider qt_qsliderStyleOption(QSlider *slider);
+
+ Q_DISABLE_COPY(QSlider)
+ Q_DECLARE_PRIVATE(QSlider)
+};
+
+#endif // QT_NO_SLIDER
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QSLIDER_H
diff --git a/src/gui/widgets/qspinbox.cpp b/src/widgets/widgets/qspinbox.cpp
index 952f9e2728..952f9e2728 100644
--- a/src/gui/widgets/qspinbox.cpp
+++ b/src/widgets/widgets/qspinbox.cpp
diff --git a/src/widgets/widgets/qspinbox.h b/src/widgets/widgets/qspinbox.h
new file mode 100644
index 0000000000..1421b1d6d2
--- /dev/null
+++ b/src/widgets/widgets/qspinbox.h
@@ -0,0 +1,188 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSPINBOX_H
+#define QSPINBOX_H
+
+#include <QtWidgets/qabstractspinbox.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_SPINBOX
+
+class QSpinBoxPrivate;
+class Q_WIDGETS_EXPORT QSpinBox : public QAbstractSpinBox
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QString suffix READ suffix WRITE setSuffix)
+ Q_PROPERTY(QString prefix READ prefix WRITE setPrefix)
+ Q_PROPERTY(QString cleanText READ cleanText)
+ Q_PROPERTY(int minimum READ minimum WRITE setMinimum)
+ Q_PROPERTY(int maximum READ maximum WRITE setMaximum)
+ Q_PROPERTY(int singleStep READ singleStep WRITE setSingleStep)
+ Q_PROPERTY(int value READ value WRITE setValue NOTIFY valueChanged USER true)
+
+public:
+ explicit QSpinBox(QWidget *parent = 0);
+#ifdef QT3_SUPPORT
+ QT3_SUPPORT_CONSTRUCTOR QSpinBox(QWidget *parent, const char *name);
+ QT3_SUPPORT_CONSTRUCTOR QSpinBox(int min, int max, int step, QWidget *parent,
+ const char *name = 0);
+#endif
+
+ int value() const;
+
+ QString prefix() const;
+ void setPrefix(const QString &prefix);
+
+ QString suffix() const;
+ void setSuffix(const QString &suffix);
+
+ QString cleanText() const;
+
+ int singleStep() const;
+ void setSingleStep(int val);
+
+ int minimum() const;
+ void setMinimum(int min);
+
+ int maximum() const;
+ void setMaximum(int max);
+
+ void setRange(int min, int max);
+
+#ifdef QT3_SUPPORT
+ inline QT3_SUPPORT void setLineStep(int step) { setSingleStep(step); }
+ inline QT3_SUPPORT void setMaxValue(int val) { setMaximum(val); }
+ inline QT3_SUPPORT void setMinValue(int val) { setMinimum(val); }
+ inline QT3_SUPPORT int maxValue() const { return maximum(); }
+ inline QT3_SUPPORT int minValue() const { return minimum(); }
+#endif
+
+protected:
+ bool event(QEvent *event);
+ virtual QValidator::State validate(QString &input, int &pos) const;
+ virtual int valueFromText(const QString &text) const;
+ virtual QString textFromValue(int val) const;
+ virtual void fixup(QString &str) const;
+
+
+public Q_SLOTS:
+ void setValue(int val);
+
+Q_SIGNALS:
+ void valueChanged(int);
+ void valueChanged(const QString &);
+
+private:
+ Q_DISABLE_COPY(QSpinBox)
+ Q_DECLARE_PRIVATE(QSpinBox)
+};
+
+class QDoubleSpinBoxPrivate;
+class Q_WIDGETS_EXPORT QDoubleSpinBox : public QAbstractSpinBox
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QString prefix READ prefix WRITE setPrefix)
+ Q_PROPERTY(QString suffix READ suffix WRITE setSuffix)
+ Q_PROPERTY(QString cleanText READ cleanText)
+ Q_PROPERTY(int decimals READ decimals WRITE setDecimals)
+ Q_PROPERTY(double minimum READ minimum WRITE setMinimum)
+ Q_PROPERTY(double maximum READ maximum WRITE setMaximum)
+ Q_PROPERTY(double singleStep READ singleStep WRITE setSingleStep)
+ Q_PROPERTY(double value READ value WRITE setValue NOTIFY valueChanged USER true)
+public:
+ explicit QDoubleSpinBox(QWidget *parent = 0);
+
+ double value() const;
+
+ QString prefix() const;
+ void setPrefix(const QString &prefix);
+
+ QString suffix() const;
+ void setSuffix(const QString &suffix);
+
+ QString cleanText() const;
+
+ double singleStep() const;
+ void setSingleStep(double val);
+
+ double minimum() const;
+ void setMinimum(double min);
+
+ double maximum() const;
+ void setMaximum(double max);
+
+ void setRange(double min, double max);
+
+ int decimals() const;
+ void setDecimals(int prec);
+
+ virtual QValidator::State validate(QString &input, int &pos) const;
+ virtual double valueFromText(const QString &text) const;
+ virtual QString textFromValue(double val) const;
+ virtual void fixup(QString &str) const;
+
+public Q_SLOTS:
+ void setValue(double val);
+
+Q_SIGNALS:
+ void valueChanged(double);
+ void valueChanged(const QString &);
+
+private:
+ Q_DISABLE_COPY(QDoubleSpinBox)
+ Q_DECLARE_PRIVATE(QDoubleSpinBox)
+};
+
+#endif // QT_NO_SPINBOX
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QSPINBOX_H
diff --git a/src/gui/widgets/qsplashscreen.cpp b/src/widgets/widgets/qsplashscreen.cpp
index e051878db9..e051878db9 100644
--- a/src/gui/widgets/qsplashscreen.cpp
+++ b/src/widgets/widgets/qsplashscreen.cpp
diff --git a/src/widgets/widgets/qsplashscreen.h b/src/widgets/widgets/qsplashscreen.h
new file mode 100644
index 0000000000..0faaa628c8
--- /dev/null
+++ b/src/widgets/widgets/qsplashscreen.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSPLASHSCREEN_H
+#define QSPLASHSCREEN_H
+
+#include <QtGui/qpixmap.h>
+#include <QtWidgets/qwidget.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_SPLASHSCREEN
+class QSplashScreenPrivate;
+
+class Q_WIDGETS_EXPORT QSplashScreen : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit QSplashScreen(const QPixmap &pixmap = QPixmap(), Qt::WindowFlags f = 0);
+ QSplashScreen(QWidget *parent, const QPixmap &pixmap = QPixmap(), Qt::WindowFlags f = 0);
+ virtual ~QSplashScreen();
+
+ void setPixmap(const QPixmap &pixmap);
+ const QPixmap pixmap() const;
+ void finish(QWidget *w);
+ void repaint();
+
+public Q_SLOTS:
+ void showMessage(const QString &message, int alignment = Qt::AlignLeft,
+ const QColor &color = Qt::black);
+ void clearMessage();
+#ifdef QT3_SUPPORT
+ inline QT_MOC_COMPAT void message(const QString &str, int alignment = Qt::AlignLeft,
+ const QColor &color = Qt::black) { showMessage(str, alignment, color); }
+ inline QT_MOC_COMPAT void clear() { clearMessage(); }
+#endif
+
+Q_SIGNALS:
+ void messageChanged(const QString &message);
+
+protected:
+ bool event(QEvent *e);
+ virtual void drawContents(QPainter *painter);
+ void mousePressEvent(QMouseEvent *);
+
+private:
+ Q_DISABLE_COPY(QSplashScreen)
+ Q_DECLARE_PRIVATE(QSplashScreen)
+};
+
+#endif // QT_NO_SPLASHSCREEN
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QSPLASHSCREEN_H
diff --git a/src/gui/widgets/qsplitter.cpp b/src/widgets/widgets/qsplitter.cpp
index 5d5897311b..5d5897311b 100644
--- a/src/gui/widgets/qsplitter.cpp
+++ b/src/widgets/widgets/qsplitter.cpp
diff --git a/src/widgets/widgets/qsplitter.h b/src/widgets/widgets/qsplitter.h
new file mode 100644
index 0000000000..09d7d3589d
--- /dev/null
+++ b/src/widgets/widgets/qsplitter.h
@@ -0,0 +1,192 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSPLITTER_H
+#define QSPLITTER_H
+
+#include <QtWidgets/qframe.h>
+#include <QtWidgets/qsizepolicy.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_SPLITTER
+
+class QSplitterPrivate;
+class QTextStream;
+template <typename T> class QList;
+
+class QSplitterHandle;
+
+class Q_WIDGETS_EXPORT QSplitter : public QFrame
+{
+ Q_OBJECT
+
+ Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation)
+ Q_PROPERTY(bool opaqueResize READ opaqueResize WRITE setOpaqueResize)
+ Q_PROPERTY(int handleWidth READ handleWidth WRITE setHandleWidth)
+ Q_PROPERTY(bool childrenCollapsible READ childrenCollapsible WRITE setChildrenCollapsible)
+
+public:
+ explicit QSplitter(QWidget* parent = 0);
+ explicit QSplitter(Qt::Orientation, QWidget* parent = 0);
+ ~QSplitter();
+
+ void addWidget(QWidget *widget);
+ void insertWidget(int index, QWidget *widget);
+
+ void setOrientation(Qt::Orientation);
+ Qt::Orientation orientation() const;
+
+ void setChildrenCollapsible(bool);
+ bool childrenCollapsible() const;
+
+ void setCollapsible(int index, bool);
+ bool isCollapsible(int index) const;
+ void setOpaqueResize(bool opaque = true);
+ bool opaqueResize() const;
+ void refresh();
+
+ QSize sizeHint() const;
+ QSize minimumSizeHint() const;
+
+ QList<int> sizes() const;
+ void setSizes(const QList<int> &list);
+
+ QByteArray saveState() const;
+ bool restoreState(const QByteArray &state);
+
+ int handleWidth() const;
+ void setHandleWidth(int);
+
+ int indexOf(QWidget *w) const;
+ QWidget *widget(int index) const;
+ int count() const;
+
+ void getRange(int index, int *, int *) const;
+ QSplitterHandle *handle(int index) const;
+
+ void setStretchFactor(int index, int stretch);
+
+Q_SIGNALS:
+ void splitterMoved(int pos, int index);
+
+protected:
+ virtual QSplitterHandle *createHandle();
+
+ void childEvent(QChildEvent *);
+
+ bool event(QEvent *);
+ void resizeEvent(QResizeEvent *);
+
+ void changeEvent(QEvent *);
+ void moveSplitter(int pos, int index);
+ void setRubberBand(int position);
+ int closestLegalPosition(int, int);
+
+#ifdef QT3_SUPPORT
+public:
+ QT3_SUPPORT_CONSTRUCTOR QSplitter(QWidget* parent, const char* name);
+ QT3_SUPPORT_CONSTRUCTOR QSplitter(Qt::Orientation, QWidget* parent, const char* name);
+ enum ResizeMode { Stretch, KeepSize, FollowSizeHint, Auto };
+ QT3_SUPPORT void setResizeMode(QWidget *w, ResizeMode mode);
+ inline QT3_SUPPORT void moveToFirst(QWidget *w) { insertWidget(0,w); }
+ inline QT3_SUPPORT void moveToLast(QWidget *w) { addWidget(w); }
+ inline QT3_SUPPORT void setCollapsible(QWidget *w, bool collapse)
+ { setCollapsible(indexOf(w), collapse); }
+ QT3_SUPPORT void setMargin(int margin) { setContentsMargins(margin, margin, margin, margin); }
+ QT3_SUPPORT int margin() const
+ { int margin; int dummy; getContentsMargins(&margin, &dummy, &dummy, &dummy); return margin; }
+#endif
+
+private:
+ Q_DISABLE_COPY(QSplitter)
+ Q_DECLARE_PRIVATE(QSplitter)
+private:
+ friend class QSplitterHandle;
+};
+
+//#ifdef QT3_SUPPORT
+#ifndef QT_NO_TEXTSTREAM
+Q_WIDGETS_EXPORT QTextStream& operator<<(QTextStream&, const QSplitter&);
+Q_WIDGETS_EXPORT QTextStream& operator>>(QTextStream&, QSplitter&);
+#endif
+//#endif
+
+class QSplitterHandlePrivate;
+class Q_WIDGETS_EXPORT QSplitterHandle : public QWidget
+{
+ Q_OBJECT
+public:
+ QSplitterHandle(Qt::Orientation o, QSplitter *parent);
+ void setOrientation(Qt::Orientation o);
+ Qt::Orientation orientation() const;
+ bool opaqueResize() const;
+ QSplitter *splitter() const;
+
+ QSize sizeHint() const;
+
+protected:
+ void paintEvent(QPaintEvent *);
+ void mouseMoveEvent(QMouseEvent *);
+ void mousePressEvent(QMouseEvent *);
+ void mouseReleaseEvent(QMouseEvent *);
+ void resizeEvent(QResizeEvent *);
+ bool event(QEvent *);
+
+ void moveSplitter(int p);
+ int closestLegalPosition(int p);
+
+private:
+ Q_DISABLE_COPY(QSplitterHandle)
+ Q_DECLARE_PRIVATE(QSplitterHandle)
+};
+
+#endif // QT_NO_SPLITTER
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QSPLITTER_H
diff --git a/src/gui/widgets/qsplitter_p.h b/src/widgets/widgets/qsplitter_p.h
index 05e7a35165..05e7a35165 100644
--- a/src/gui/widgets/qsplitter_p.h
+++ b/src/widgets/widgets/qsplitter_p.h
diff --git a/src/gui/widgets/qstackedwidget.cpp b/src/widgets/widgets/qstackedwidget.cpp
index c4bf79a1c4..c4bf79a1c4 100644
--- a/src/gui/widgets/qstackedwidget.cpp
+++ b/src/widgets/widgets/qstackedwidget.cpp
diff --git a/src/widgets/widgets/qstackedwidget.h b/src/widgets/widgets/qstackedwidget.h
new file mode 100644
index 0000000000..e0275fe27f
--- /dev/null
+++ b/src/widgets/widgets/qstackedwidget.h
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSTACKEDWIDGET_H
+#define QSTACKEDWIDGET_H
+
+#include <QtWidgets/qframe.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_STACKEDWIDGET
+
+class QStackedWidgetPrivate;
+
+class Q_WIDGETS_EXPORT QStackedWidget : public QFrame
+{
+ Q_OBJECT
+
+ Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentChanged)
+ Q_PROPERTY(int count READ count)
+public:
+ explicit QStackedWidget(QWidget *parent=0);
+ ~QStackedWidget();
+
+ int addWidget(QWidget *w);
+ int insertWidget(int index, QWidget *w);
+ void removeWidget(QWidget *w);
+
+ QWidget *currentWidget() const;
+ int currentIndex() const;
+
+ int indexOf(QWidget *) const;
+ QWidget *widget(int) const;
+ int count() const;
+
+public Q_SLOTS:
+ void setCurrentIndex(int index);
+ void setCurrentWidget(QWidget *w);
+
+Q_SIGNALS:
+ void currentChanged(int);
+ void widgetRemoved(int index);
+
+protected:
+ bool event(QEvent *e);
+
+private:
+ Q_DISABLE_COPY(QStackedWidget)
+ Q_DECLARE_PRIVATE(QStackedWidget)
+};
+
+#endif // QT_NO_STACKEDWIDGET
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QSTACKEDWIDGET_H
diff --git a/src/gui/widgets/qstatusbar.cpp b/src/widgets/widgets/qstatusbar.cpp
index dbf299a712..dbf299a712 100644
--- a/src/gui/widgets/qstatusbar.cpp
+++ b/src/widgets/widgets/qstatusbar.cpp
diff --git a/src/widgets/widgets/qstatusbar.h b/src/widgets/widgets/qstatusbar.h
new file mode 100644
index 0000000000..32dfed8f7b
--- /dev/null
+++ b/src/widgets/widgets/qstatusbar.h
@@ -0,0 +1,116 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSTATUSBAR_H
+#define QSTATUSBAR_H
+
+#include <QtWidgets/qwidget.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_STATUSBAR
+
+class QStatusBarPrivate;
+
+class Q_WIDGETS_EXPORT QStatusBar: public QWidget
+{
+ Q_OBJECT
+
+ Q_PROPERTY(bool sizeGripEnabled READ isSizeGripEnabled WRITE setSizeGripEnabled)
+
+public:
+ explicit QStatusBar(QWidget* parent=0);
+ virtual ~QStatusBar();
+
+ void addWidget(QWidget *widget, int stretch = 0);
+ int insertWidget(int index, QWidget *widget, int stretch = 0);
+ void addPermanentWidget(QWidget *widget, int stretch = 0);
+ int insertPermanentWidget(int index, QWidget *widget, int stretch = 0);
+ void removeWidget(QWidget *widget);
+
+ void setSizeGripEnabled(bool);
+ bool isSizeGripEnabled() const;
+
+ QString currentMessage() const;
+
+public Q_SLOTS:
+ void showMessage(const QString &text, int timeout = 0);
+ void clearMessage();
+
+#ifdef QT3_SUPPORT
+public:
+ QT3_SUPPORT_CONSTRUCTOR QStatusBar(QWidget* parent, const char* name);
+ QT3_SUPPORT void addWidget(QWidget *w, int stretch, bool permanent)
+ { if (permanent) addPermanentWidget(w, stretch); else addWidget(w, stretch); }
+public Q_SLOTS:
+ inline QT_MOC_COMPAT void message(const QString &text, int timeout = 0) { showMessage(text, timeout); }
+ inline QT_MOC_COMPAT void clear() { clearMessage(); }
+#endif
+
+Q_SIGNALS:
+ void messageChanged(const QString &text);
+
+protected:
+ void showEvent(QShowEvent *);
+ void paintEvent(QPaintEvent *);
+ void resizeEvent(QResizeEvent *);
+
+ // ### Qt 5: consider making reformat() and hideOrShow() private
+ void reformat();
+ void hideOrShow();
+ bool event(QEvent *);
+
+private:
+ Q_DISABLE_COPY(QStatusBar)
+ Q_DECLARE_PRIVATE(QStatusBar)
+};
+
+#endif // QT_NO_STATUSBAR
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QSTATUSBAR_H
diff --git a/src/gui/widgets/qtabbar.cpp b/src/widgets/widgets/qtabbar.cpp
index 8faf156608..8faf156608 100644
--- a/src/gui/widgets/qtabbar.cpp
+++ b/src/widgets/widgets/qtabbar.cpp
diff --git a/src/widgets/widgets/qtabbar.h b/src/widgets/widgets/qtabbar.h
new file mode 100644
index 0000000000..3e2ff3e9d0
--- /dev/null
+++ b/src/widgets/widgets/qtabbar.h
@@ -0,0 +1,226 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTABBAR_H
+#define QTABBAR_H
+
+#include <QtWidgets/qwidget.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_TABBAR
+
+class QIcon;
+class QTabBarPrivate;
+class QStyleOptionTab;
+
+class Q_WIDGETS_EXPORT QTabBar: public QWidget
+{
+ Q_OBJECT
+
+ Q_ENUMS(Shape)
+ Q_PROPERTY(Shape shape READ shape WRITE setShape)
+ Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentChanged)
+ Q_PROPERTY(int count READ count)
+ Q_PROPERTY(bool drawBase READ drawBase WRITE setDrawBase)
+ Q_PROPERTY(QSize iconSize READ iconSize WRITE setIconSize)
+ Q_PROPERTY(Qt::TextElideMode elideMode READ elideMode WRITE setElideMode)
+ Q_PROPERTY(bool usesScrollButtons READ usesScrollButtons WRITE setUsesScrollButtons)
+ Q_PROPERTY(bool tabsClosable READ tabsClosable WRITE setTabsClosable)
+ Q_PROPERTY(SelectionBehavior selectionBehaviorOnRemove READ selectionBehaviorOnRemove WRITE setSelectionBehaviorOnRemove)
+ Q_PROPERTY(bool expanding READ expanding WRITE setExpanding)
+ Q_PROPERTY(bool movable READ isMovable WRITE setMovable)
+ Q_PROPERTY(bool documentMode READ documentMode WRITE setDocumentMode)
+
+public:
+ explicit QTabBar(QWidget* parent=0);
+ ~QTabBar();
+
+ enum Shape { RoundedNorth, RoundedSouth, RoundedWest, RoundedEast,
+ TriangularNorth, TriangularSouth, TriangularWest, TriangularEast
+#if defined(QT3_SUPPORT) && !defined(Q_MOC_RUN)
+ , RoundedAbove = RoundedNorth, RoundedBelow = RoundedSouth,
+ TriangularAbove = TriangularNorth, TriangularBelow = TriangularSouth
+#endif
+ };
+
+ enum ButtonPosition {
+ LeftSide,
+ RightSide
+ };
+
+ enum SelectionBehavior {
+ SelectLeftTab,
+ SelectRightTab,
+ SelectPreviousTab
+ };
+
+ Shape shape() const;
+ void setShape(Shape shape);
+
+ int addTab(const QString &text);
+ int addTab(const QIcon &icon, const QString &text);
+
+ int insertTab(int index, const QString &text);
+ int insertTab(int index, const QIcon&icon, const QString &text);
+
+ void removeTab(int index);
+ void moveTab(int from, int to);
+
+ bool isTabEnabled(int index) const;
+ void setTabEnabled(int index, bool);
+
+ QString tabText(int index) const;
+ void setTabText(int index, const QString &text);
+
+ QColor tabTextColor(int index) const;
+ void setTabTextColor(int index, const QColor &color);
+
+ QIcon tabIcon(int index) const;
+ void setTabIcon(int index, const QIcon &icon);
+
+ Qt::TextElideMode elideMode() const;
+ void setElideMode(Qt::TextElideMode);
+
+#ifndef QT_NO_TOOLTIP
+ void setTabToolTip(int index, const QString &tip);
+ QString tabToolTip(int index) const;
+#endif
+
+#ifndef QT_NO_WHATSTHIS
+ void setTabWhatsThis(int index, const QString &text);
+ QString tabWhatsThis(int index) const;
+#endif
+
+ void setTabData(int index, const QVariant &data);
+ QVariant tabData(int index) const;
+
+ QRect tabRect(int index) const;
+ int tabAt(const QPoint &pos) const;
+
+ int currentIndex() const;
+ int count() const;
+
+ QSize sizeHint() const;
+ QSize minimumSizeHint() const;
+
+ void setDrawBase(bool drawTheBase);
+ bool drawBase() const;
+
+ QSize iconSize() const;
+ void setIconSize(const QSize &size);
+
+ bool usesScrollButtons() const;
+ void setUsesScrollButtons(bool useButtons);
+
+ bool tabsClosable() const;
+ void setTabsClosable(bool closable);
+
+ void setTabButton(int index, ButtonPosition position, QWidget *widget);
+ QWidget *tabButton(int index, ButtonPosition position) const;
+
+ SelectionBehavior selectionBehaviorOnRemove() const;
+ void setSelectionBehaviorOnRemove(SelectionBehavior behavior);
+
+ bool expanding() const;
+ void setExpanding(bool enabled);
+
+ bool isMovable() const;
+ void setMovable(bool movable);
+
+ bool documentMode() const;
+ void setDocumentMode(bool set);
+
+public Q_SLOTS:
+ void setCurrentIndex(int index);
+
+Q_SIGNALS:
+ void currentChanged(int index);
+ void tabCloseRequested(int index);
+ void tabMoved(int from, int to);
+
+protected:
+ virtual QSize tabSizeHint(int index) const;
+ virtual void tabInserted(int index);
+ virtual void tabRemoved(int index);
+ virtual void tabLayoutChange();
+
+ bool event(QEvent *);
+ void resizeEvent(QResizeEvent *);
+ void showEvent(QShowEvent *);
+ void hideEvent(QHideEvent *);
+ void paintEvent(QPaintEvent *);
+ void mousePressEvent (QMouseEvent *);
+ void mouseMoveEvent (QMouseEvent *);
+ void mouseReleaseEvent (QMouseEvent *);
+#ifndef QT_NO_WHEELEVENT
+ void wheelEvent(QWheelEvent *event);
+#endif
+ void keyPressEvent(QKeyEvent *);
+ void changeEvent(QEvent *);
+ void initStyleOption(QStyleOptionTab *option, int tabIndex) const;
+
+#ifdef QT3_SUPPORT
+public Q_SLOTS:
+ QT_MOC_COMPAT void setCurrentTab(int index) { setCurrentIndex(index); }
+Q_SIGNALS:
+ QT_MOC_COMPAT void selected(int);
+#endif
+
+ friend class QAccessibleTabBar;
+private:
+ Q_DISABLE_COPY(QTabBar)
+ Q_DECLARE_PRIVATE(QTabBar)
+ Q_PRIVATE_SLOT(d_func(), void _q_scrollTabs())
+ Q_PRIVATE_SLOT(d_func(), void _q_closeTab())
+};
+
+#endif // QT_NO_TABBAR
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QTABBAR_H
diff --git a/src/gui/widgets/qtabbar_p.h b/src/widgets/widgets/qtabbar_p.h
index 69ca361967..69ca361967 100644
--- a/src/gui/widgets/qtabbar_p.h
+++ b/src/widgets/widgets/qtabbar_p.h
diff --git a/src/gui/widgets/qtabwidget.cpp b/src/widgets/widgets/qtabwidget.cpp
index c6551e591e..c6551e591e 100644
--- a/src/gui/widgets/qtabwidget.cpp
+++ b/src/widgets/widgets/qtabwidget.cpp
diff --git a/src/widgets/widgets/qtabwidget.h b/src/widgets/widgets/qtabwidget.h
new file mode 100644
index 0000000000..899b7a5dba
--- /dev/null
+++ b/src/widgets/widgets/qtabwidget.h
@@ -0,0 +1,254 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTABWIDGET_H
+#define QTABWIDGET_H
+
+#include <QtWidgets/qwidget.h>
+#include <QtWidgets/qicon.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_TABWIDGET
+
+class QTabBar;
+class QTabWidgetPrivate;
+class QStyleOptionTabWidgetFrame;
+
+class Q_WIDGETS_EXPORT QTabWidget : public QWidget
+{
+ Q_OBJECT
+ Q_ENUMS(TabPosition TabShape)
+ Q_PROPERTY(TabPosition tabPosition READ tabPosition WRITE setTabPosition)
+ Q_PROPERTY(TabShape tabShape READ tabShape WRITE setTabShape)
+ Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentChanged)
+ Q_PROPERTY(int count READ count)
+ Q_PROPERTY(QSize iconSize READ iconSize WRITE setIconSize)
+ Q_PROPERTY(Qt::TextElideMode elideMode READ elideMode WRITE setElideMode)
+ Q_PROPERTY(bool usesScrollButtons READ usesScrollButtons WRITE setUsesScrollButtons)
+ Q_PROPERTY(bool documentMode READ documentMode WRITE setDocumentMode)
+ Q_PROPERTY(bool tabsClosable READ tabsClosable WRITE setTabsClosable)
+ Q_PROPERTY(bool movable READ isMovable WRITE setMovable)
+
+public:
+ explicit QTabWidget(QWidget *parent = 0);
+ ~QTabWidget();
+
+ int addTab(QWidget *widget, const QString &);
+ int addTab(QWidget *widget, const QIcon& icon, const QString &label);
+
+ int insertTab(int index, QWidget *widget, const QString &);
+ int insertTab(int index, QWidget *widget, const QIcon& icon, const QString &label);
+
+ void removeTab(int index);
+
+ bool isTabEnabled(int index) const;
+ void setTabEnabled(int index, bool);
+
+ QString tabText(int index) const;
+ void setTabText(int index, const QString &);
+
+ QIcon tabIcon(int index) const;
+ void setTabIcon(int index, const QIcon & icon);
+
+#ifndef QT_NO_TOOLTIP
+ void setTabToolTip(int index, const QString & tip);
+ QString tabToolTip(int index) const;
+#endif
+
+#ifndef QT_NO_WHATSTHIS
+ void setTabWhatsThis(int index, const QString &text);
+ QString tabWhatsThis(int index) const;
+#endif
+
+ int currentIndex() const;
+ QWidget *currentWidget() const;
+ QWidget *widget(int index) const;
+ int indexOf(QWidget *widget) const;
+ int count() const;
+
+ enum TabPosition { North, South, West, East
+#if defined(QT3_SUPPORT) && !defined(Q_MOC_RUN)
+ , Top = North, Bottom = South
+#endif
+ };
+ TabPosition tabPosition() const;
+ void setTabPosition(TabPosition);
+
+ bool tabsClosable() const;
+ void setTabsClosable(bool closeable);
+
+ bool isMovable() const;
+ void setMovable(bool movable);
+
+ enum TabShape { Rounded, Triangular };
+ TabShape tabShape() const;
+ void setTabShape(TabShape s);
+
+ QSize sizeHint() const;
+ QSize minimumSizeHint() const;
+ int heightForWidth(int width) const;
+
+ void setCornerWidget(QWidget * w, Qt::Corner corner = Qt::TopRightCorner);
+ QWidget * cornerWidget(Qt::Corner corner = Qt::TopRightCorner) const;
+
+ Qt::TextElideMode elideMode() const;
+ void setElideMode(Qt::TextElideMode);
+
+ QSize iconSize() const;
+ void setIconSize(const QSize &size);
+
+ bool usesScrollButtons() const;
+ void setUsesScrollButtons(bool useButtons);
+
+ bool documentMode() const;
+ void setDocumentMode(bool set);
+
+ void clear();
+
+ QTabBar* tabBar() const;
+
+public Q_SLOTS:
+ void setCurrentIndex(int index);
+ void setCurrentWidget(QWidget *widget);
+
+Q_SIGNALS:
+ void currentChanged(int index);
+ void tabCloseRequested(int index);
+
+protected:
+ virtual void tabInserted(int index);
+ virtual void tabRemoved(int index);
+
+ void showEvent(QShowEvent *);
+ void resizeEvent(QResizeEvent *);
+ void keyPressEvent(QKeyEvent *);
+ void paintEvent(QPaintEvent *);
+ void setTabBar(QTabBar *);
+ void changeEvent(QEvent *);
+ bool event(QEvent *);
+ void initStyleOption(QStyleOptionTabWidgetFrame *option) const;
+
+#ifdef QT3_SUPPORT
+public:
+ QT3_SUPPORT_CONSTRUCTOR QTabWidget(QWidget *parent, const char *name, Qt::WindowFlags f = 0);
+
+ inline QT3_SUPPORT void insertTab(QWidget * w, const QString &s, int index = -1) { insertTab(index, w, s); }
+ inline QT3_SUPPORT void insertTab(QWidget *child, const QIcon& icon,
+ const QString &label, int index = -1) { insertTab(index, child, icon, label); }
+
+ inline QT3_SUPPORT void changeTab(QWidget *w, const QString &s) {setTabText(indexOf(w), s); }
+ inline QT3_SUPPORT void changeTab(QWidget *w, const QIcon& icon,
+ const QString &label) { int idx = indexOf(w); setTabText(idx, label); setTabIcon(idx, icon); }
+
+ inline QT3_SUPPORT bool isTabEnabled( QWidget *w) const {return isTabEnabled(indexOf(w)); }
+ inline QT3_SUPPORT void setTabEnabled(QWidget *w, bool b) { setTabEnabled(indexOf(w), b); }
+
+ inline QT3_SUPPORT QString tabLabel(QWidget *w) const {return tabText(indexOf(w)); }
+ inline QT3_SUPPORT void setTabLabel(QWidget *w, const QString &l) { setTabText(indexOf(w), l); }
+
+ inline QT3_SUPPORT QIcon tabIconSet(QWidget * w) const {return tabIcon(indexOf(w)); }
+ inline QT3_SUPPORT void setTabIconSet(QWidget * w, const QIcon & icon) { setTabIcon(indexOf(w), icon); }
+
+ inline QT3_SUPPORT void removeTabToolTip(QWidget * w) {
+#ifndef QT_NO_TOOLTIP
+ setTabToolTip(indexOf(w), QString());
+#else
+ Q_UNUSED(w);
+#endif
+ }
+ inline QT3_SUPPORT void setTabToolTip(QWidget * w, const QString & tip) {
+#ifndef QT_NO_TOOLTIP
+ setTabToolTip(indexOf(w), tip);
+#else
+ Q_UNUSED(w);
+ Q_UNUSED(tip);
+#endif
+ }
+
+ inline QT3_SUPPORT QString tabToolTip(QWidget * w) const {
+#ifndef QT_NO_TOOLTIP
+ return tabToolTip(indexOf(w));
+#else
+ Q_UNUSED(w);
+ return QString();
+#endif
+ }
+
+ inline QT3_SUPPORT QWidget * currentPage() const { return currentWidget(); }
+ inline QT3_SUPPORT QWidget *page(int index) const { return widget(index); }
+ inline QT3_SUPPORT QString label(int index) const { return tabText(index); }
+ inline QT3_SUPPORT int currentPageIndex() const { return currentIndex(); }
+
+ inline QT3_SUPPORT int margin() const { return 0; }
+ inline QT3_SUPPORT void setMargin(int) {}
+
+public Q_SLOTS:
+ inline QT_MOC_COMPAT void setCurrentPage(int index) { setCurrentIndex(index); }
+ inline QT_MOC_COMPAT void showPage(QWidget *w) { setCurrentIndex(indexOf(w)); }
+ inline QT_MOC_COMPAT void removePage(QWidget *w) { removeTab(indexOf(w)); }
+
+Q_SIGNALS:
+ QT_MOC_COMPAT void currentChanged(QWidget *);
+ QT_MOC_COMPAT void selected(const QString&);
+#endif // QT3_SUPPORT
+
+private:
+ Q_DECLARE_PRIVATE(QTabWidget)
+ Q_DISABLE_COPY(QTabWidget)
+ Q_PRIVATE_SLOT(d_func(), void _q_showTab(int))
+ Q_PRIVATE_SLOT(d_func(), void _q_removeTab(int))
+ Q_PRIVATE_SLOT(d_func(), void _q_tabMoved(int, int))
+ void setUpLayout(bool = false);
+ friend class Q3TabDialog;
+};
+
+#endif // QT_NO_TABWIDGET
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QTABWIDGET_H
diff --git a/src/gui/widgets/qtextbrowser.cpp b/src/widgets/widgets/qtextbrowser.cpp
index cd8fa117b7..cd8fa117b7 100644
--- a/src/gui/widgets/qtextbrowser.cpp
+++ b/src/widgets/widgets/qtextbrowser.cpp
diff --git a/src/widgets/widgets/qtextbrowser.h b/src/widgets/widgets/qtextbrowser.h
new file mode 100644
index 0000000000..3f488975ec
--- /dev/null
+++ b/src/widgets/widgets/qtextbrowser.h
@@ -0,0 +1,140 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTEXTBROWSER_H
+#define QTEXTBROWSER_H
+
+#include <QtWidgets/qtextedit.h>
+#include <QtCore/qurl.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_TEXTBROWSER
+
+class QTextBrowserPrivate;
+
+class Q_WIDGETS_EXPORT QTextBrowser : public QTextEdit
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QUrl source READ source WRITE setSource)
+ Q_OVERRIDE(bool modified SCRIPTABLE false)
+ Q_OVERRIDE(bool readOnly DESIGNABLE false SCRIPTABLE false)
+ Q_OVERRIDE(bool undoRedoEnabled DESIGNABLE false SCRIPTABLE false)
+ Q_PROPERTY(QStringList searchPaths READ searchPaths WRITE setSearchPaths)
+ Q_PROPERTY(bool openExternalLinks READ openExternalLinks WRITE setOpenExternalLinks)
+ Q_PROPERTY(bool openLinks READ openLinks WRITE setOpenLinks)
+
+public:
+ explicit QTextBrowser(QWidget* parent = 0);
+ virtual ~QTextBrowser();
+
+ QUrl source() const;
+
+ QStringList searchPaths() const;
+ void setSearchPaths(const QStringList &paths);
+
+ virtual QVariant loadResource(int type, const QUrl &name);
+
+ bool isBackwardAvailable() const;
+ bool isForwardAvailable() const;
+ void clearHistory();
+ QString historyTitle(int) const;
+ QUrl historyUrl(int) const;
+ int backwardHistoryCount() const;
+ int forwardHistoryCount() const;
+
+ bool openExternalLinks() const;
+ void setOpenExternalLinks(bool open);
+
+ bool openLinks() const;
+ void setOpenLinks(bool open);
+
+public Q_SLOTS:
+ virtual void setSource(const QUrl &name);
+ virtual void backward();
+ virtual void forward();
+ virtual void home();
+ virtual void reload();
+
+Q_SIGNALS:
+ void backwardAvailable(bool);
+ void forwardAvailable(bool);
+ void historyChanged();
+ void sourceChanged(const QUrl &);
+ void highlighted(const QUrl &);
+ void highlighted(const QString &);
+ void anchorClicked(const QUrl &);
+
+protected:
+ bool event(QEvent *e);
+ virtual void keyPressEvent(QKeyEvent *ev);
+ virtual void mouseMoveEvent(QMouseEvent *ev);
+ virtual void mousePressEvent(QMouseEvent *ev);
+ virtual void mouseReleaseEvent(QMouseEvent *ev);
+ virtual void focusOutEvent(QFocusEvent *ev);
+ virtual bool focusNextPrevChild(bool next);
+ virtual void paintEvent(QPaintEvent *e);
+
+#if defined(QT3_SUPPORT)
+public:
+ QT3_SUPPORT_CONSTRUCTOR QTextBrowser(QWidget *parent, const char *name);
+#endif
+
+private:
+ Q_DISABLE_COPY(QTextBrowser)
+ Q_DECLARE_PRIVATE(QTextBrowser)
+ Q_PRIVATE_SLOT(d_func(), void _q_documentModified())
+ Q_PRIVATE_SLOT(d_func(), void _q_activateAnchor(const QString &))
+ Q_PRIVATE_SLOT(d_func(), void _q_highlightLink(const QString &))
+};
+
+#endif // QT_NO_TEXTBROWSER
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QTEXTBROWSER_H
diff --git a/src/widgets/widgets/qtextedit.cpp b/src/widgets/widgets/qtextedit.cpp
new file mode 100644
index 0000000000..67be9dbed3
--- /dev/null
+++ b/src/widgets/widgets/qtextedit.cpp
@@ -0,0 +1,2809 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtextedit_p.h"
+#include "qlineedit.h"
+#include "qtextbrowser.h"
+
+#ifndef QT_NO_TEXTEDIT
+#include <qfont.h>
+#include <qpainter.h>
+#include <qevent.h>
+#include <qdebug.h>
+#include <qmime.h>
+#include <qdrag.h>
+#include <qclipboard.h>
+#include <qmenu.h>
+#include <qstyle.h>
+#include <qtimer.h>
+#include "private/qtextdocumentlayout_p.h"
+#include "qtextdocument.h"
+#include "private/qtextdocument_p.h"
+#include "qtextlist.h"
+#include "private/qwidgettextcontrol_p.h"
+
+#include <qtextformat.h>
+#include <qdatetime.h>
+#include <qapplication.h>
+#include <limits.h>
+#include <qtexttable.h>
+#include <qvariant.h>
+
+#include <qinputcontext.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+
+#ifndef QT_NO_TEXTEDIT
+static inline bool shouldEnableInputMethod(QTextEdit *textedit)
+{
+ return !textedit->isReadOnly();
+}
+
+class QTextEditControl : public QWidgetTextControl
+{
+public:
+ inline QTextEditControl(QObject *parent) : QWidgetTextControl(parent) {}
+
+ virtual QMimeData *createMimeDataFromSelection() const {
+ QTextEdit *ed = qobject_cast<QTextEdit *>(parent());
+ if (!ed)
+ return QWidgetTextControl::createMimeDataFromSelection();
+ return ed->createMimeDataFromSelection();
+ }
+ virtual bool canInsertFromMimeData(const QMimeData *source) const {
+ QTextEdit *ed = qobject_cast<QTextEdit *>(parent());
+ if (!ed)
+ return QWidgetTextControl::canInsertFromMimeData(source);
+ return ed->canInsertFromMimeData(source);
+ }
+ virtual void insertFromMimeData(const QMimeData *source) {
+ QTextEdit *ed = qobject_cast<QTextEdit *>(parent());
+ if (!ed)
+ QWidgetTextControl::insertFromMimeData(source);
+ else
+ ed->insertFromMimeData(source);
+ }
+};
+
+QTextEditPrivate::QTextEditPrivate()
+ : control(0),
+ autoFormatting(QTextEdit::AutoNone), tabChangesFocus(false),
+ lineWrap(QTextEdit::WidgetWidth), lineWrapColumnOrWidth(0),
+ wordWrap(QTextOption::WrapAtWordBoundaryOrAnywhere), clickCausedFocus(0),
+ textFormat(Qt::AutoText)
+{
+ ignoreAutomaticScrollbarAdjustment = false;
+ preferRichText = false;
+ showCursorOnInitialShow = true;
+ inDrag = false;
+}
+
+void QTextEditPrivate::createAutoBulletList()
+{
+ QTextCursor cursor = control->textCursor();
+ cursor.beginEditBlock();
+
+ QTextBlockFormat blockFmt = cursor.blockFormat();
+
+ QTextListFormat listFmt;
+ listFmt.setStyle(QTextListFormat::ListDisc);
+ listFmt.setIndent(blockFmt.indent() + 1);
+
+ blockFmt.setIndent(0);
+ cursor.setBlockFormat(blockFmt);
+
+ cursor.createList(listFmt);
+
+ cursor.endEditBlock();
+ control->setTextCursor(cursor);
+}
+
+void QTextEditPrivate::init(const QString &html)
+{
+ Q_Q(QTextEdit);
+ control = new QTextEditControl(q);
+ control->setPalette(q->palette());
+
+ QObject::connect(control, SIGNAL(microFocusChanged()), q, SLOT(updateMicroFocus()));
+ QObject::connect(control, SIGNAL(documentSizeChanged(QSizeF)), q, SLOT(_q_adjustScrollbars()));
+ QObject::connect(control, SIGNAL(updateRequest(QRectF)), q, SLOT(_q_repaintContents(QRectF)));
+ QObject::connect(control, SIGNAL(visibilityRequest(QRectF)), q, SLOT(_q_ensureVisible(QRectF)));
+ QObject::connect(control, SIGNAL(currentCharFormatChanged(QTextCharFormat)),
+ q, SLOT(_q_currentCharFormatChanged(QTextCharFormat)));
+
+ QObject::connect(control, SIGNAL(textChanged()), q, SIGNAL(textChanged()));
+ QObject::connect(control, SIGNAL(undoAvailable(bool)), q, SIGNAL(undoAvailable(bool)));
+ QObject::connect(control, SIGNAL(redoAvailable(bool)), q, SIGNAL(redoAvailable(bool)));
+ QObject::connect(control, SIGNAL(copyAvailable(bool)), q, SIGNAL(copyAvailable(bool)));
+ QObject::connect(control, SIGNAL(selectionChanged()), q, SIGNAL(selectionChanged()));
+ QObject::connect(control, SIGNAL(cursorPositionChanged()), q, SIGNAL(cursorPositionChanged()));
+
+ QObject::connect(control, SIGNAL(textChanged()), q, SLOT(updateMicroFocus()));
+
+ QTextDocument *doc = control->document();
+ // set a null page size initially to avoid any relayouting until the textedit
+ // is shown. relayoutDocument() will take care of setting the page size to the
+ // viewport dimensions later.
+ doc->setPageSize(QSize(0, 0));
+ doc->documentLayout()->setPaintDevice(viewport);
+ doc->setDefaultFont(q->font());
+ doc->setUndoRedoEnabled(false); // flush undo buffer.
+ doc->setUndoRedoEnabled(true);
+
+ if (!html.isEmpty())
+ control->setHtml(html);
+
+ hbar->setSingleStep(20);
+ vbar->setSingleStep(20);
+
+ viewport->setBackgroundRole(QPalette::Base);
+ q->setAcceptDrops(true);
+ q->setFocusPolicy(Qt::WheelFocus);
+ q->setAttribute(Qt::WA_KeyCompression);
+ q->setAttribute(Qt::WA_InputMethodEnabled);
+ q->setInputMethodHints(Qt::ImhMultiLine);
+
+#ifndef QT_NO_CURSOR
+ viewport->setCursor(Qt::IBeamCursor);
+#endif
+#ifdef Q_WS_WIN
+ setSingleFingerPanEnabled(true);
+#endif
+}
+
+void QTextEditPrivate::_q_repaintContents(const QRectF &contentsRect)
+{
+ if (!contentsRect.isValid()) {
+ viewport->update();
+ return;
+ }
+ const int xOffset = horizontalOffset();
+ const int yOffset = verticalOffset();
+ const QRectF visibleRect(xOffset, yOffset, viewport->width(), viewport->height());
+
+ QRect r = contentsRect.intersected(visibleRect).toAlignedRect();
+ if (r.isEmpty())
+ return;
+
+ r.translate(-xOffset, -yOffset);
+ viewport->update(r);
+}
+
+void QTextEditPrivate::pageUpDown(QTextCursor::MoveOperation op, QTextCursor::MoveMode moveMode)
+{
+ QTextCursor cursor = control->textCursor();
+ bool moved = false;
+ qreal lastY = control->cursorRect(cursor).top();
+ qreal distance = 0;
+ // move using movePosition to keep the cursor's x
+ do {
+ qreal y = control->cursorRect(cursor).top();
+ distance += qAbs(y - lastY);
+ lastY = y;
+ moved = cursor.movePosition(op, moveMode);
+ } while (moved && distance < viewport->height());
+
+ if (moved) {
+ if (op == QTextCursor::Up) {
+ cursor.movePosition(QTextCursor::Down, moveMode);
+ vbar->triggerAction(QAbstractSlider::SliderPageStepSub);
+ } else {
+ cursor.movePosition(QTextCursor::Up, moveMode);
+ vbar->triggerAction(QAbstractSlider::SliderPageStepAdd);
+ }
+ }
+ control->setTextCursor(cursor);
+}
+
+#ifndef QT_NO_SCROLLBAR
+static QSize documentSize(QWidgetTextControl *control)
+{
+ QTextDocument *doc = control->document();
+ QAbstractTextDocumentLayout *layout = doc->documentLayout();
+
+ QSize docSize;
+
+ if (QTextDocumentLayout *tlayout = qobject_cast<QTextDocumentLayout *>(layout)) {
+ docSize = tlayout->dynamicDocumentSize().toSize();
+ int percentageDone = tlayout->layoutStatus();
+ // extrapolate height
+ if (percentageDone > 0)
+ docSize.setHeight(docSize.height() * 100 / percentageDone);
+ } else {
+ docSize = layout->documentSize().toSize();
+ }
+
+ return docSize;
+}
+
+void QTextEditPrivate::_q_adjustScrollbars()
+{
+ if (ignoreAutomaticScrollbarAdjustment)
+ return;
+ ignoreAutomaticScrollbarAdjustment = true; // avoid recursion, #106108
+
+ QSize viewportSize = viewport->size();
+ QSize docSize = documentSize(control);
+
+ // due to the recursion guard we have to repeat this step a few times,
+ // as adding/removing a scroll bar will cause the document or viewport
+ // size to change
+ // ideally we should loop until the viewport size and doc size stabilize,
+ // but in corner cases they might fluctuate, so we need to limit the
+ // number of iterations
+ for (int i = 0; i < 4; ++i) {
+ hbar->setRange(0, docSize.width() - viewportSize.width());
+ hbar->setPageStep(viewportSize.width());
+
+ vbar->setRange(0, docSize.height() - viewportSize.height());
+ vbar->setPageStep(viewportSize.height());
+
+ // if we are in left-to-right mode widening the document due to
+ // lazy layouting does not require a repaint. If in right-to-left
+ // the scroll bar has the value zero and it visually has the maximum
+ // value (it is visually at the right), then widening the document
+ // keeps it at value zero but visually adjusts it to the new maximum
+ // on the right, hence we need an update.
+ if (q_func()->isRightToLeft())
+ viewport->update();
+
+ _q_showOrHideScrollBars();
+
+ const QSize oldViewportSize = viewportSize;
+ const QSize oldDocSize = docSize;
+
+ // make sure the document is layouted if the viewport width changes
+ viewportSize = viewport->size();
+ if (viewportSize.width() != oldViewportSize.width())
+ relayoutDocument();
+
+ docSize = documentSize(control);
+ if (viewportSize == oldViewportSize && docSize == oldDocSize)
+ break;
+ }
+ ignoreAutomaticScrollbarAdjustment = false;
+}
+#endif
+
+// rect is in content coordinates
+void QTextEditPrivate::_q_ensureVisible(const QRectF &_rect)
+{
+ const QRect rect = _rect.toRect();
+ if ((vbar->isVisible() && vbar->maximum() < rect.bottom())
+ || (hbar->isVisible() && hbar->maximum() < rect.right()))
+ _q_adjustScrollbars();
+ const int visibleWidth = viewport->width();
+ const int visibleHeight = viewport->height();
+ const bool rtl = q_func()->isRightToLeft();
+
+ if (rect.x() < horizontalOffset()) {
+ if (rtl)
+ hbar->setValue(hbar->maximum() - rect.x());
+ else
+ hbar->setValue(rect.x());
+ } else if (rect.x() + rect.width() > horizontalOffset() + visibleWidth) {
+ if (rtl)
+ hbar->setValue(hbar->maximum() - (rect.x() + rect.width() - visibleWidth));
+ else
+ hbar->setValue(rect.x() + rect.width() - visibleWidth);
+ }
+
+ if (rect.y() < verticalOffset())
+ vbar->setValue(rect.y());
+ else if (rect.y() + rect.height() > verticalOffset() + visibleHeight)
+ vbar->setValue(rect.y() + rect.height() - visibleHeight);
+}
+
+/*!
+ \class QTextEdit
+ \brief The QTextEdit class provides a widget that is used to edit and display
+ both plain and rich text.
+
+ \ingroup richtext-processing
+
+
+ \tableofcontents
+
+ \section1 Introduction and Concepts
+
+ QTextEdit is an advanced WYSIWYG viewer/editor supporting rich
+ text formatting using HTML-style tags. It is optimized to handle
+ large documents and to respond quickly to user input.
+
+ QTextEdit works on paragraphs and characters. A paragraph is a
+ formatted string which is word-wrapped to fit into the width of
+ the widget. By default when reading plain text, one newline
+ signifies a paragraph. A document consists of zero or more
+ paragraphs. The words in the paragraph are aligned in accordance
+ with the paragraph's alignment. Paragraphs are separated by hard
+ line breaks. Each character within a paragraph has its own
+ attributes, for example, font and color.
+
+ QTextEdit can display images, lists and tables. If the text is
+ too large to view within the text edit's viewport, scroll bars will
+ appear. The text edit can load both plain text and HTML files (a
+ subset of HTML 3.2 and 4).
+
+ If you just need to display a small piece of rich text use QLabel.
+
+ The rich text support in Qt is designed to provide a fast, portable and
+ efficient way to add reasonable online help facilities to
+ applications, and to provide a basis for rich text editors. If
+ you find the HTML support insufficient for your needs you may consider
+ the use of QtWebKit, which provides a full-featured web browser
+ widget.
+
+ The shape of the mouse cursor on a QTextEdit is Qt::IBeamCursor by default.
+ It can be changed through the viewport()'s cursor property.
+
+ \section1 Using QTextEdit as a Display Widget
+
+ QTextEdit can display a large HTML subset, including tables and
+ images.
+
+ The text is set or replaced using setHtml() which deletes any
+ existing text and replaces it with the text passed in the
+ setHtml() call. If you call setHtml() with legacy HTML, and then
+ call toHtml(), the text that is returned may have different markup,
+ but will render the same. The entire text can be deleted with clear().
+
+ Text itself can be inserted using the QTextCursor class or using the
+ convenience functions insertHtml(), insertPlainText(), append() or
+ paste(). QTextCursor is also able to insert complex objects like tables
+ or lists into the document, and it deals with creating selections
+ and applying changes to selected text.
+
+ By default the text edit wraps words at whitespace to fit within
+ the text edit widget. The setLineWrapMode() function is used to
+ specify the kind of line wrap you want, or \l NoWrap if you don't
+ want any wrapping. Call setLineWrapMode() to set a fixed pixel width
+ \l FixedPixelWidth, or character column (e.g. 80 column) \l
+ FixedColumnWidth with the pixels or columns specified with
+ setLineWrapColumnOrWidth(). If you use word wrap to the widget's width
+ \l WidgetWidth, you can specify whether to break on whitespace or
+ anywhere with setWordWrapMode().
+
+ The find() function can be used to find and select a given string
+ within the text.
+
+ If you want to limit the total number of paragraphs in a QTextEdit,
+ as it is for example open useful in a log viewer, then you can use
+ QTextDocument's maximumBlockCount property for that.
+
+ \section2 Read-only Key Bindings
+
+ When QTextEdit is used read-only the key bindings are limited to
+ navigation, and text may only be selected with the mouse:
+ \table
+ \header \i Keypresses \i Action
+ \row \i Up \i Moves one line up.
+ \row \i Down \i Moves one line down.
+ \row \i Left \i Moves one character to the left.
+ \row \i Right \i Moves one character to the right.
+ \row \i PageUp \i Moves one (viewport) page up.
+ \row \i PageDown \i Moves one (viewport) page down.
+ \row \i Home \i Moves to the beginning of the text.
+ \row \i End \i Moves to the end of the text.
+ \row \i Alt+Wheel
+ \i Scrolls the page horizontally (the Wheel is the mouse wheel).
+ \row \i Ctrl+Wheel \i Zooms the text.
+ \row \i Ctrl+A \i Selects all text.
+ \endtable
+
+ The text edit may be able to provide some meta-information. For
+ example, the documentTitle() function will return the text from
+ within HTML \c{<title>} tags.
+
+ \section1 Using QTextEdit as an Editor
+
+ All the information about using QTextEdit as a display widget also
+ applies here.
+
+ The current char format's attributes are set with setFontItalic(),
+ setFontWeight(), setFontUnderline(), setFontFamily(),
+ setFontPointSize(), setTextColor() and setCurrentFont(). The current
+ paragraph's alignment is set with setAlignment().
+
+ Selection of text is handled by the QTextCursor class, which provides
+ functionality for creating selections, retrieving the text contents or
+ deleting selections. You can retrieve the object that corresponds with
+ the user-visible cursor using the textCursor() method. If you want to set
+ a selection in QTextEdit just create one on a QTextCursor object and
+ then make that cursor the visible cursor using setTextCursor(). The selection
+ can be copied to the clipboard with copy(), or cut to the clipboard with
+ cut(). The entire text can be selected using selectAll().
+
+ When the cursor is moved and the underlying formatting attributes change,
+ the currentCharFormatChanged() signal is emitted to reflect the new attributes
+ at the new cursor position.
+
+ QTextEdit holds a QTextDocument object which can be retrieved using the
+ document() method. You can also set your own document object using setDocument().
+ QTextDocument emits a textChanged() signal if the text changes and it also
+ provides a isModified() function which will return true if the text has been
+ modified since it was either loaded or since the last call to setModified
+ with false as argument. In addition it provides methods for undo and redo.
+
+ \section2 Drag and Drop
+
+ QTextEdit also supports custom drag and drop behavior. By default,
+ QTextEdit will insert plain text, HTML and rich text when the user drops
+ data of these MIME types onto a document. Reimplement
+ canInsertFromMimeData() and insertFromMimeData() to add support for
+ additional MIME types.
+
+ For example, to allow the user to drag and drop an image onto a QTextEdit,
+ you could the implement these functions in the following way:
+
+ \snippet doc/src/snippets/textdocument-imagedrop/textedit.cpp 0
+
+ We add support for image MIME types by returning true. For all other
+ MIME types, we use the default implementation.
+
+ \snippet doc/src/snippets/textdocument-imagedrop/textedit.cpp 1
+
+ We unpack the image from the QVariant held by the MIME source and insert
+ it into the document as a resource.
+
+ \section2 Editing Key Bindings
+
+ The list of key bindings which are implemented for editing:
+ \table
+ \header \i Keypresses \i Action
+ \row \i Backspace \i Deletes the character to the left of the cursor.
+ \row \i Delete \i Deletes the character to the right of the cursor.
+ \row \i Ctrl+C \i Copy the selected text to the clipboard.
+ \row \i Ctrl+Insert \i Copy the selected text to the clipboard.
+ \row \i Ctrl+K \i Deletes to the end of the line.
+ \row \i Ctrl+V \i Pastes the clipboard text into text edit.
+ \row \i Shift+Insert \i Pastes the clipboard text into text edit.
+ \row \i Ctrl+X \i Deletes the selected text and copies it to the clipboard.
+ \row \i Shift+Delete \i Deletes the selected text and copies it to the clipboard.
+ \row \i Ctrl+Z \i Undoes the last operation.
+ \row \i Ctrl+Y \i Redoes the last operation.
+ \row \i Left \i Moves the cursor one character to the left.
+ \row \i Ctrl+Left \i Moves the cursor one word to the left.
+ \row \i Right \i Moves the cursor one character to the right.
+ \row \i Ctrl+Right \i Moves the cursor one word to the right.
+ \row \i Up \i Moves the cursor one line up.
+ \row \i Down \i Moves the cursor one line down.
+ \row \i PageUp \i Moves the cursor one page up.
+ \row \i PageDown \i Moves the cursor one page down.
+ \row \i Home \i Moves the cursor to the beginning of the line.
+ \row \i Ctrl+Home \i Moves the cursor to the beginning of the text.
+ \row \i End \i Moves the cursor to the end of the line.
+ \row \i Ctrl+End \i Moves the cursor to the end of the text.
+ \row \i Alt+Wheel \i Scrolls the page horizontally (the Wheel is the mouse wheel).
+ \endtable
+
+ To select (mark) text hold down the Shift key whilst pressing one
+ of the movement keystrokes, for example, \e{Shift+Right}
+ will select the character to the right, and \e{Shift+Ctrl+Right} will select the word to the right, etc.
+
+ \sa QTextDocument, QTextCursor, {Application Example},
+ {Syntax Highlighter Example}, {Rich Text Processing}
+*/
+
+/*!
+ \property QTextEdit::plainText
+ \since 4.3
+
+ This property gets and sets the text editor's contents as plain
+ text. Previous contents are removed and undo/redo history is reset
+ when the property is set.
+
+ If the text edit has another content type, it will not be replaced
+ by plain text if you call toPlainText(). The only exception to this
+ is the non-break space, \e{nbsp;}, that will be converted into
+ standard space.
+
+ By default, for an editor with no contents, this property contains
+ an empty string.
+
+ \sa html
+*/
+
+/*!
+ \property QTextEdit::undoRedoEnabled
+ \brief whether undo and redo are enabled
+
+ Users are only able to undo or redo actions if this property is
+ true, and if there is an action that can be undone (or redone).
+*/
+
+/*!
+ \enum QTextEdit::LineWrapMode
+
+ \value NoWrap
+ \value WidgetWidth
+ \value FixedPixelWidth
+ \value FixedColumnWidth
+*/
+
+/*!
+ \enum QTextEdit::AutoFormattingFlag
+
+ \value AutoNone Don't do any automatic formatting.
+ \value AutoBulletList Automatically create bullet lists (e.g. when
+ the user enters an asterisk ('*') in the left most column, or
+ presses Enter in an existing list item.
+ \value AutoAll Apply all automatic formatting. Currently only
+ automatic bullet lists are supported.
+*/
+
+#ifdef QT3_SUPPORT
+/*!
+ \enum QTextEdit::CursorAction
+ \compat
+
+ \value MoveBackward
+ \value MoveForward
+ \value MoveWordBackward
+ \value MoveWordForward
+ \value MoveUp
+ \value MoveDown
+ \value MoveLineStart
+ \value MoveLineEnd
+ \value MoveHome
+ \value MoveEnd
+ \value MovePageUp
+ \value MovePageDown
+
+ \omitvalue MovePgUp
+ \omitvalue MovePgDown
+*/
+#endif
+
+/*!
+ Constructs an empty QTextEdit with parent \a
+ parent.
+*/
+QTextEdit::QTextEdit(QWidget *parent)
+ : QAbstractScrollArea(*new QTextEditPrivate, parent)
+{
+ Q_D(QTextEdit);
+ d->init();
+}
+
+/*!
+ \internal
+*/
+QTextEdit::QTextEdit(QTextEditPrivate &dd, QWidget *parent)
+ : QAbstractScrollArea(dd, parent)
+{
+ Q_D(QTextEdit);
+ d->init();
+}
+
+/*!
+ Constructs a QTextEdit with parent \a parent. The text edit will display
+ the text \a text. The text is interpreted as html.
+*/
+QTextEdit::QTextEdit(const QString &text, QWidget *parent)
+ : QAbstractScrollArea(*new QTextEditPrivate, parent)
+{
+ Q_D(QTextEdit);
+ d->init(text);
+}
+
+#ifdef QT3_SUPPORT
+/*!
+ Use one of the constructors that doesn't take the \a name
+ argument and then use setObjectName() instead.
+*/
+QTextEdit::QTextEdit(QWidget *parent, const char *name)
+ : QAbstractScrollArea(*new QTextEditPrivate, parent)
+{
+ Q_D(QTextEdit);
+ d->init();
+ setObjectName(QString::fromAscii(name));
+}
+#endif
+
+
+/*!
+ Destructor.
+*/
+QTextEdit::~QTextEdit()
+{
+}
+
+/*!
+ Returns the point size of the font of the current format.
+
+ \sa setFontFamily() setCurrentFont() setFontPointSize()
+*/
+qreal QTextEdit::fontPointSize() const
+{
+ Q_D(const QTextEdit);
+ return d->control->textCursor().charFormat().fontPointSize();
+}
+
+/*!
+ Returns the font family of the current format.
+
+ \sa setFontFamily() setCurrentFont() setFontPointSize()
+*/
+QString QTextEdit::fontFamily() const
+{
+ Q_D(const QTextEdit);
+ return d->control->textCursor().charFormat().fontFamily();
+}
+
+/*!
+ Returns the font weight of the current format.
+
+ \sa setFontWeight() setCurrentFont() setFontPointSize() QFont::Weight
+*/
+int QTextEdit::fontWeight() const
+{
+ Q_D(const QTextEdit);
+ return d->control->textCursor().charFormat().fontWeight();
+}
+
+/*!
+ Returns true if the font of the current format is underlined; otherwise returns
+ false.
+
+ \sa setFontUnderline()
+*/
+bool QTextEdit::fontUnderline() const
+{
+ Q_D(const QTextEdit);
+ return d->control->textCursor().charFormat().fontUnderline();
+}
+
+/*!
+ Returns true if the font of the current format is italic; otherwise returns
+ false.
+
+ \sa setFontItalic()
+*/
+bool QTextEdit::fontItalic() const
+{
+ Q_D(const QTextEdit);
+ return d->control->textCursor().charFormat().fontItalic();
+}
+
+/*!
+ Returns the text color of the current format.
+
+ \sa setTextColor()
+*/
+QColor QTextEdit::textColor() const
+{
+ Q_D(const QTextEdit);
+ return d->control->textCursor().charFormat().foreground().color();
+}
+
+/*!
+ \since 4.4
+
+ Returns the text background color of the current format.
+
+ \sa setTextBackgroundColor()
+*/
+QColor QTextEdit::textBackgroundColor() const
+{
+ Q_D(const QTextEdit);
+ return d->control->textCursor().charFormat().background().color();
+}
+
+/*!
+ Returns the font of the current format.
+
+ \sa setCurrentFont() setFontFamily() setFontPointSize()
+*/
+QFont QTextEdit::currentFont() const
+{
+ Q_D(const QTextEdit);
+ return d->control->textCursor().charFormat().font();
+}
+
+/*!
+ Sets the alignment of the current paragraph to \a a. Valid
+ alignments are Qt::AlignLeft, Qt::AlignRight,
+ Qt::AlignJustify and Qt::AlignCenter (which centers
+ horizontally).
+*/
+void QTextEdit::setAlignment(Qt::Alignment a)
+{
+ Q_D(QTextEdit);
+ QTextBlockFormat fmt;
+ fmt.setAlignment(a);
+ QTextCursor cursor = d->control->textCursor();
+ cursor.mergeBlockFormat(fmt);
+ d->control->setTextCursor(cursor);
+}
+
+/*!
+ Returns the alignment of the current paragraph.
+
+ \sa setAlignment()
+*/
+Qt::Alignment QTextEdit::alignment() const
+{
+ Q_D(const QTextEdit);
+ return d->control->textCursor().blockFormat().alignment();
+}
+
+/*!
+ Makes \a document the new document of the text editor.
+
+ \note The editor \e{does not take ownership of the document} unless it
+ is the document's parent object. The parent object of the provided document
+ remains the owner of the object.
+
+ The editor does not delete the current document, even if it is a child of the editor.
+
+ \sa document()
+*/
+void QTextEdit::setDocument(QTextDocument *document)
+{
+ Q_D(QTextEdit);
+ d->control->setDocument(document);
+ d->updateDefaultTextOption();
+ d->relayoutDocument();
+}
+
+/*!
+ Returns a pointer to the underlying document.
+
+ \sa setDocument()
+*/
+QTextDocument *QTextEdit::document() const
+{
+ Q_D(const QTextEdit);
+ return d->control->document();
+}
+
+/*!
+ Sets the visible \a cursor.
+*/
+void QTextEdit::setTextCursor(const QTextCursor &cursor)
+{
+ Q_D(QTextEdit);
+ d->control->setTextCursor(cursor);
+}
+
+/*!
+ Returns a copy of the QTextCursor that represents the currently visible cursor.
+ Note that changes on the returned cursor do not affect QTextEdit's cursor; use
+ setTextCursor() to update the visible cursor.
+ */
+QTextCursor QTextEdit::textCursor() const
+{
+ Q_D(const QTextEdit);
+ return d->control->textCursor();
+}
+
+/*!
+ Sets the font family of the current format to \a fontFamily.
+
+ \sa fontFamily() setCurrentFont()
+*/
+void QTextEdit::setFontFamily(const QString &fontFamily)
+{
+ QTextCharFormat fmt;
+ fmt.setFontFamily(fontFamily);
+ mergeCurrentCharFormat(fmt);
+}
+
+/*!
+ Sets the point size of the current format to \a s.
+
+ Note that if \a s is zero or negative, the behavior of this
+ function is not defined.
+
+ \sa fontPointSize() setCurrentFont() setFontFamily()
+*/
+void QTextEdit::setFontPointSize(qreal s)
+{
+ QTextCharFormat fmt;
+ fmt.setFontPointSize(s);
+ mergeCurrentCharFormat(fmt);
+}
+
+/*!
+ \fn void QTextEdit::setFontWeight(int weight)
+
+ Sets the font weight of the current format to the given \a weight,
+ where the value used is in the range defined by the QFont::Weight
+ enum.
+
+ \sa fontWeight(), setCurrentFont(), setFontFamily()
+*/
+void QTextEdit::setFontWeight(int w)
+{
+ QTextCharFormat fmt;
+ fmt.setFontWeight(w);
+ mergeCurrentCharFormat(fmt);
+}
+
+/*!
+ If \a underline is true, sets the current format to underline;
+ otherwise sets the current format to non-underline.
+
+ \sa fontUnderline()
+*/
+void QTextEdit::setFontUnderline(bool underline)
+{
+ QTextCharFormat fmt;
+ fmt.setFontUnderline(underline);
+ mergeCurrentCharFormat(fmt);
+}
+
+/*!
+ If \a italic is true, sets the current format to italic;
+ otherwise sets the current format to non-italic.
+
+ \sa fontItalic()
+*/
+void QTextEdit::setFontItalic(bool italic)
+{
+ QTextCharFormat fmt;
+ fmt.setFontItalic(italic);
+ mergeCurrentCharFormat(fmt);
+}
+
+/*!
+ Sets the text color of the current format to \a c.
+
+ \sa textColor()
+*/
+void QTextEdit::setTextColor(const QColor &c)
+{
+ QTextCharFormat fmt;
+ fmt.setForeground(QBrush(c));
+ mergeCurrentCharFormat(fmt);
+}
+
+/*!
+ \since 4.4
+
+ Sets the text background color of the current format to \a c.
+
+ \sa textBackgroundColor()
+*/
+void QTextEdit::setTextBackgroundColor(const QColor &c)
+{
+ QTextCharFormat fmt;
+ fmt.setBackground(QBrush(c));
+ mergeCurrentCharFormat(fmt);
+}
+
+/*!
+ Sets the font of the current format to \a f.
+
+ \sa currentFont() setFontPointSize() setFontFamily()
+*/
+void QTextEdit::setCurrentFont(const QFont &f)
+{
+ QTextCharFormat fmt;
+ fmt.setFont(f);
+ mergeCurrentCharFormat(fmt);
+}
+
+/*!
+ \since 4.2
+
+ Undoes the last operation.
+
+ If there is no operation to undo, i.e. there is no undo step in
+ the undo/redo history, nothing happens.
+
+ \sa redo()
+*/
+void QTextEdit::undo()
+{
+ Q_D(QTextEdit);
+ d->control->undo();
+}
+
+void QTextEdit::redo()
+{
+ Q_D(QTextEdit);
+ d->control->redo();
+}
+
+/*!
+ \fn void QTextEdit::undo() const
+ \fn void QTextEdit::redo() const
+ \overload
+
+ Use the non-const overload instead.
+*/
+
+/*!
+ \fn void QTextEdit::redo()
+ \since 4.2
+
+ Redoes the last operation.
+
+ If there is no operation to redo, i.e. there is no redo step in
+ the undo/redo history, nothing happens.
+
+ \sa undo()
+*/
+
+#ifndef QT_NO_CLIPBOARD
+/*!
+ Copies the selected text to the clipboard and deletes it from
+ the text edit.
+
+ If there is no selected text nothing happens.
+
+ \sa copy() paste()
+*/
+
+void QTextEdit::cut()
+{
+ Q_D(QTextEdit);
+ d->control->cut();
+}
+
+/*!
+ Copies any selected text to the clipboard.
+
+ \sa copyAvailable()
+*/
+
+void QTextEdit::copy()
+{
+ Q_D(QTextEdit);
+ d->control->copy();
+}
+
+/*!
+ Pastes the text from the clipboard into the text edit at the
+ current cursor position.
+
+ If there is no text in the clipboard nothing happens.
+
+ To change the behavior of this function, i.e. to modify what
+ QTextEdit can paste and how it is being pasted, reimplement the
+ virtual canInsertFromMimeData() and insertFromMimeData()
+ functions.
+
+ \sa cut() copy()
+*/
+
+void QTextEdit::paste()
+{
+ Q_D(QTextEdit);
+ d->control->paste();
+}
+#endif
+
+/*!
+ Deletes all the text in the text edit.
+
+ Note that the undo/redo history is cleared by this function.
+
+ \sa cut() setPlainText() setHtml()
+*/
+void QTextEdit::clear()
+{
+ Q_D(QTextEdit);
+ // clears and sets empty content
+ d->control->clear();
+}
+
+
+/*!
+ Selects all text.
+
+ \sa copy() cut() textCursor()
+ */
+void QTextEdit::selectAll()
+{
+ Q_D(QTextEdit);
+ d->control->selectAll();
+}
+
+/*! \internal
+*/
+bool QTextEdit::event(QEvent *e)
+{
+ Q_D(QTextEdit);
+#ifndef QT_NO_CONTEXTMENU
+ if (e->type() == QEvent::ContextMenu
+ && static_cast<QContextMenuEvent *>(e)->reason() == QContextMenuEvent::Keyboard) {
+ Q_D(QTextEdit);
+ ensureCursorVisible();
+ const QPoint cursorPos = cursorRect().center();
+ QContextMenuEvent ce(QContextMenuEvent::Keyboard, cursorPos, d->viewport->mapToGlobal(cursorPos));
+ ce.setAccepted(e->isAccepted());
+ const bool result = QAbstractScrollArea::event(&ce);
+ e->setAccepted(ce.isAccepted());
+ return result;
+ } else if (e->type() == QEvent::ShortcutOverride
+ || e->type() == QEvent::ToolTip) {
+ d->sendControlEvent(e);
+ }
+#endif // QT_NO_CONTEXTMENU
+#ifdef QT_KEYPAD_NAVIGATION
+ if (e->type() == QEvent::EnterEditFocus || e->type() == QEvent::LeaveEditFocus) {
+ if (QApplication::keypadNavigationEnabled())
+ d->sendControlEvent(e);
+ }
+#endif
+ return QAbstractScrollArea::event(e);
+}
+
+/*! \internal
+*/
+
+void QTextEdit::timerEvent(QTimerEvent *e)
+{
+ Q_D(QTextEdit);
+ if (e->timerId() == d->autoScrollTimer.timerId()) {
+ QRect visible = d->viewport->rect();
+ QPoint pos;
+ if (d->inDrag) {
+ pos = d->autoScrollDragPos;
+ visible.adjust(qMin(visible.width()/3,20), qMin(visible.height()/3,20),
+ -qMin(visible.width()/3,20), -qMin(visible.height()/3,20));
+ } else {
+ const QPoint globalPos = QCursor::pos();
+ pos = d->viewport->mapFromGlobal(globalPos);
+ QMouseEvent ev(QEvent::MouseMove, pos, mapTo(topLevelWidget(), pos), globalPos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
+ mouseMoveEvent(&ev);
+ }
+ int deltaY = qMax(pos.y() - visible.top(), visible.bottom() - pos.y()) - visible.height();
+ int deltaX = qMax(pos.x() - visible.left(), visible.right() - pos.x()) - visible.width();
+ int delta = qMax(deltaX, deltaY);
+ if (delta >= 0) {
+ if (delta < 7)
+ delta = 7;
+ int timeout = 4900 / (delta * delta);
+ d->autoScrollTimer.start(timeout, this);
+
+ if (deltaY > 0)
+ d->vbar->triggerAction(pos.y() < visible.center().y() ?
+ QAbstractSlider::SliderSingleStepSub
+ : QAbstractSlider::SliderSingleStepAdd);
+ if (deltaX > 0)
+ d->hbar->triggerAction(pos.x() < visible.center().x() ?
+ QAbstractSlider::SliderSingleStepSub
+ : QAbstractSlider::SliderSingleStepAdd);
+ }
+ }
+#ifdef QT_KEYPAD_NAVIGATION
+ else if (e->timerId() == d->deleteAllTimer.timerId()) {
+ d->deleteAllTimer.stop();
+ clear();
+ }
+#endif
+}
+
+/*!
+ Changes the text of the text edit to the string \a text.
+ Any previous text is removed.
+
+ \a text is interpreted as plain text.
+
+ Note that the undo/redo history is cleared by this function.
+
+ \sa toPlainText()
+*/
+
+void QTextEdit::setPlainText(const QString &text)
+{
+ Q_D(QTextEdit);
+ d->control->setPlainText(text);
+ d->preferRichText = false;
+}
+
+/*!
+ \fn QString QTextEdit::toPlainText() const
+
+ Returns the text of the text edit as plain text.
+
+ \sa QTextEdit::setPlainText()
+ */
+
+
+/*!
+ \property QTextEdit::html
+
+ This property provides an HTML interface to the text of the text edit.
+
+ toHtml() returns the text of the text edit as html.
+
+ setHtml() changes the text of the text edit. Any previous text is
+ removed and the undo/redo history is cleared. The input text is
+ interpreted as rich text in html format.
+
+ \note It is the responsibility of the caller to make sure that the
+ text is correctly decoded when a QString containing HTML is created
+ and passed to setHtml().
+
+ By default, for a newly-created, empty document, this property contains
+ text to describe an HTML 4.0 document with no body text.
+
+ \sa {Supported HTML Subset}, plainText
+*/
+
+#ifndef QT_NO_TEXTHTMLPARSER
+void QTextEdit::setHtml(const QString &text)
+{
+ Q_D(QTextEdit);
+ d->control->setHtml(text);
+ d->preferRichText = true;
+}
+#endif
+
+/*! \reimp
+*/
+void QTextEdit::keyPressEvent(QKeyEvent *e)
+{
+ Q_D(QTextEdit);
+
+#ifdef QT_KEYPAD_NAVIGATION
+ switch (e->key()) {
+ case Qt::Key_Select:
+ if (QApplication::keypadNavigationEnabled()) {
+ // code assumes linksaccessible + editable isn't meaningful
+ if (d->control->textInteractionFlags() & Qt::TextEditable) {
+ setEditFocus(!hasEditFocus());
+ } else {
+ if (!hasEditFocus())
+ setEditFocus(true);
+ else {
+ QTextCursor cursor = d->control->textCursor();
+ QTextCharFormat charFmt = cursor.charFormat();
+ if (!(d->control->textInteractionFlags() & Qt::LinksAccessibleByKeyboard)
+ || !cursor.hasSelection() || charFmt.anchorHref().isEmpty()) {
+ e->accept();
+ return;
+ }
+ }
+ }
+ }
+ break;
+ case Qt::Key_Back:
+ case Qt::Key_No:
+ if (!QApplication::keypadNavigationEnabled()
+ || (QApplication::keypadNavigationEnabled() && !hasEditFocus())) {
+ e->ignore();
+ return;
+ }
+ break;
+ default:
+ if (QApplication::keypadNavigationEnabled()) {
+ if (!hasEditFocus() && !(e->modifiers() & Qt::ControlModifier)) {
+ if (e->text()[0].isPrint())
+ setEditFocus(true);
+ else {
+ e->ignore();
+ return;
+ }
+ }
+ }
+ break;
+ }
+#endif
+#ifndef QT_NO_SHORTCUT
+
+ Qt::TextInteractionFlags tif = d->control->textInteractionFlags();
+
+ if (tif & Qt::TextSelectableByKeyboard){
+ if (e == QKeySequence::SelectPreviousPage) {
+ e->accept();
+ d->pageUpDown(QTextCursor::Up, QTextCursor::KeepAnchor);
+ return;
+ } else if (e ==QKeySequence::SelectNextPage) {
+ e->accept();
+ d->pageUpDown(QTextCursor::Down, QTextCursor::KeepAnchor);
+ return;
+ }
+ }
+ if (tif & (Qt::TextSelectableByKeyboard | Qt::TextEditable)) {
+ if (e == QKeySequence::MoveToPreviousPage) {
+ e->accept();
+ d->pageUpDown(QTextCursor::Up, QTextCursor::MoveAnchor);
+ return;
+ } else if (e == QKeySequence::MoveToNextPage) {
+ e->accept();
+ d->pageUpDown(QTextCursor::Down, QTextCursor::MoveAnchor);
+ return;
+ }
+ }
+
+ if (!(tif & Qt::TextEditable)) {
+ switch (e->key()) {
+ case Qt::Key_Space:
+ e->accept();
+ if (e->modifiers() & Qt::ShiftModifier)
+ d->vbar->triggerAction(QAbstractSlider::SliderPageStepSub);
+ else
+ d->vbar->triggerAction(QAbstractSlider::SliderPageStepAdd);
+ break;
+ default:
+ d->sendControlEvent(e);
+ if (!e->isAccepted() && e->modifiers() == Qt::NoModifier) {
+ if (e->key() == Qt::Key_Home) {
+ d->vbar->triggerAction(QAbstractSlider::SliderToMinimum);
+ e->accept();
+ } else if (e->key() == Qt::Key_End) {
+ d->vbar->triggerAction(QAbstractSlider::SliderToMaximum);
+ e->accept();
+ }
+ }
+ if (!e->isAccepted()) {
+ QAbstractScrollArea::keyPressEvent(e);
+ }
+ }
+ return;
+ }
+#endif // QT_NO_SHORTCUT
+
+ {
+ QTextCursor cursor = d->control->textCursor();
+ const QString text = e->text();
+ if (cursor.atBlockStart()
+ && (d->autoFormatting & AutoBulletList)
+ && (text.length() == 1)
+ && (text.at(0) == QLatin1Char('-') || text.at(0) == QLatin1Char('*'))
+ && (!cursor.currentList())) {
+
+ d->createAutoBulletList();
+ e->accept();
+ return;
+ }
+ }
+
+ d->sendControlEvent(e);
+#ifdef QT_KEYPAD_NAVIGATION
+ if (!e->isAccepted()) {
+ switch (e->key()) {
+ case Qt::Key_Up:
+ case Qt::Key_Down:
+ if (QApplication::keypadNavigationEnabled()) {
+ // Cursor position didn't change, so we want to leave
+ // these keys to change focus.
+ e->ignore();
+ return;
+ }
+ break;
+ case Qt::Key_Back:
+ if (!e->isAutoRepeat()) {
+ if (QApplication::keypadNavigationEnabled()) {
+ if (document()->isEmpty() || !(d->control->textInteractionFlags() & Qt::TextEditable)) {
+ setEditFocus(false);
+ e->accept();
+ } else if (!d->deleteAllTimer.isActive()) {
+ e->accept();
+ d->deleteAllTimer.start(750, this);
+ }
+ } else {
+ e->ignore();
+ return;
+ }
+ }
+ break;
+ default: break;
+ }
+ }
+#endif
+}
+
+/*! \reimp
+*/
+void QTextEdit::keyReleaseEvent(QKeyEvent *e)
+{
+#ifdef QT_KEYPAD_NAVIGATION
+ Q_D(QTextEdit);
+ if (QApplication::keypadNavigationEnabled()) {
+ if (!e->isAutoRepeat() && e->key() == Qt::Key_Back
+ && d->deleteAllTimer.isActive()) {
+ d->deleteAllTimer.stop();
+ QTextCursor cursor = d->control->textCursor();
+ QTextBlockFormat blockFmt = cursor.blockFormat();
+
+ QTextList *list = cursor.currentList();
+ if (list && cursor.atBlockStart()) {
+ list->remove(cursor.block());
+ } else if (cursor.atBlockStart() && blockFmt.indent() > 0) {
+ blockFmt.setIndent(blockFmt.indent() - 1);
+ cursor.setBlockFormat(blockFmt);
+ } else {
+ cursor.deletePreviousChar();
+ }
+ setTextCursor(cursor);
+ e->accept();
+ return;
+ }
+ }
+#endif
+ e->ignore();
+}
+
+/*!
+ Loads the resource specified by the given \a type and \a name.
+
+ This function is an extension of QTextDocument::loadResource().
+
+ \sa QTextDocument::loadResource()
+*/
+QVariant QTextEdit::loadResource(int type, const QUrl &name)
+{
+ Q_UNUSED(type);
+ Q_UNUSED(name);
+ return QVariant();
+}
+
+/*! \reimp
+*/
+void QTextEdit::resizeEvent(QResizeEvent *e)
+{
+ Q_D(QTextEdit);
+
+ if (d->lineWrap == NoWrap) {
+ QTextDocument *doc = d->control->document();
+ QVariant alignmentProperty = doc->documentLayout()->property("contentHasAlignment");
+
+ if (!doc->pageSize().isNull()
+ && alignmentProperty.type() == QVariant::Bool
+ && !alignmentProperty.toBool()) {
+
+ d->_q_adjustScrollbars();
+ return;
+ }
+ }
+
+ if (d->lineWrap != FixedPixelWidth
+ && e->oldSize().width() != e->size().width())
+ d->relayoutDocument();
+ else
+ d->_q_adjustScrollbars();
+}
+
+void QTextEditPrivate::relayoutDocument()
+{
+ QTextDocument *doc = control->document();
+ QAbstractTextDocumentLayout *layout = doc->documentLayout();
+
+ if (QTextDocumentLayout *tlayout = qobject_cast<QTextDocumentLayout *>(layout)) {
+ if (lineWrap == QTextEdit::FixedColumnWidth)
+ tlayout->setFixedColumnWidth(lineWrapColumnOrWidth);
+ else
+ tlayout->setFixedColumnWidth(-1);
+ }
+
+ QTextDocumentLayout *tlayout = qobject_cast<QTextDocumentLayout *>(layout);
+ QSize lastUsedSize;
+ if (tlayout)
+ lastUsedSize = tlayout->dynamicDocumentSize().toSize();
+ else
+ lastUsedSize = layout->documentSize().toSize();
+
+ // ignore calls to _q_adjustScrollbars caused by an emission of the
+ // usedSizeChanged() signal in the layout, as we're calling it
+ // later on our own anyway (or deliberately not) .
+ const bool oldIgnoreScrollbarAdjustment = ignoreAutomaticScrollbarAdjustment;
+ ignoreAutomaticScrollbarAdjustment = true;
+
+ int width = viewport->width();
+ if (lineWrap == QTextEdit::FixedPixelWidth)
+ width = lineWrapColumnOrWidth;
+ else if (lineWrap == QTextEdit::NoWrap) {
+ QVariant alignmentProperty = doc->documentLayout()->property("contentHasAlignment");
+ if (alignmentProperty.type() == QVariant::Bool && !alignmentProperty.toBool()) {
+
+ width = 0;
+ }
+ }
+
+ doc->setPageSize(QSize(width, -1));
+ if (tlayout)
+ tlayout->ensureLayouted(verticalOffset() + viewport->height());
+
+ ignoreAutomaticScrollbarAdjustment = oldIgnoreScrollbarAdjustment;
+
+ QSize usedSize;
+ if (tlayout)
+ usedSize = tlayout->dynamicDocumentSize().toSize();
+ else
+ usedSize = layout->documentSize().toSize();
+
+ // this is an obscure situation in the layout that can happen:
+ // if a character at the end of a line is the tallest one and therefore
+ // influencing the total height of the line and the line right below it
+ // is always taller though, then it can happen that if due to line breaking
+ // that tall character wraps into the lower line the document not only shrinks
+ // horizontally (causing the character to wrap in the first place) but also
+ // vertically, because the original line is now smaller and the one below kept
+ // its size. So a layout with less width _can_ take up less vertical space, too.
+ // If the wider case causes a vertical scroll bar to appear and the narrower one
+ // (narrower because the vertical scroll bar takes up horizontal space)) to disappear
+ // again then we have an endless loop, as _q_adjustScrollBars sets new ranges on the
+ // scroll bars, the QAbstractScrollArea will find out about it and try to show/hide
+ // the scroll bars again. That's why we try to detect this case here and break out.
+ //
+ // (if you change this please also check the layoutingLoop() testcase in
+ // QTextEdit's autotests)
+ if (lastUsedSize.isValid()
+ && !vbar->isHidden()
+ && viewport->width() < lastUsedSize.width()
+ && usedSize.height() < lastUsedSize.height()
+ && usedSize.height() <= viewport->height())
+ return;
+
+ _q_adjustScrollbars();
+}
+
+void QTextEditPrivate::paint(QPainter *p, QPaintEvent *e)
+{
+ const int xOffset = horizontalOffset();
+ const int yOffset = verticalOffset();
+
+ QRect r = e->rect();
+ p->translate(-xOffset, -yOffset);
+ r.translate(xOffset, yOffset);
+
+ QTextDocument *doc = control->document();
+ QTextDocumentLayout *layout = qobject_cast<QTextDocumentLayout *>(doc->documentLayout());
+
+ // the layout might need to expand the root frame to
+ // the viewport if NoWrap is set
+ if (layout)
+ layout->setViewport(viewport->rect());
+
+ control->drawContents(p, r, q_func());
+
+ if (layout)
+ layout->setViewport(QRect());
+}
+
+/*! \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)
+{
+ Q_D(QTextEdit);
+ QPainter p(d->viewport);
+ d->paint(&p, e);
+}
+
+void QTextEditPrivate::_q_currentCharFormatChanged(const QTextCharFormat &fmt)
+{
+ Q_Q(QTextEdit);
+ emit q->currentCharFormatChanged(fmt);
+#ifdef QT3_SUPPORT
+ // compat signals
+ emit q->currentFontChanged(fmt.font());
+ emit q->currentColorChanged(fmt.foreground().color());
+#endif
+}
+
+void QTextEditPrivate::updateDefaultTextOption()
+{
+ QTextDocument *doc = control->document();
+
+ QTextOption opt = doc->defaultTextOption();
+ QTextOption::WrapMode oldWrapMode = opt.wrapMode();
+
+ if (lineWrap == QTextEdit::NoWrap)
+ opt.setWrapMode(QTextOption::NoWrap);
+ else
+ opt.setWrapMode(wordWrap);
+
+ if (opt.wrapMode() != oldWrapMode)
+ doc->setDefaultTextOption(opt);
+}
+
+/*! \reimp
+*/
+void QTextEdit::mousePressEvent(QMouseEvent *e)
+{
+ Q_D(QTextEdit);
+#ifdef QT_KEYPAD_NAVIGATION
+ if (QApplication::keypadNavigationEnabled() && !hasEditFocus())
+ setEditFocus(true);
+#endif
+ d->sendControlEvent(e);
+}
+
+/*! \reimp
+*/
+void QTextEdit::mouseMoveEvent(QMouseEvent *e)
+{
+ Q_D(QTextEdit);
+ d->inDrag = false; // paranoia
+ const QPoint pos = e->pos();
+ d->sendControlEvent(e);
+ if (!(e->buttons() & Qt::LeftButton))
+ return;
+ QRect visible = d->viewport->rect();
+ if (visible.contains(pos))
+ d->autoScrollTimer.stop();
+ else if (!d->autoScrollTimer.isActive())
+ d->autoScrollTimer.start(100, this);
+}
+
+/*! \reimp
+*/
+void QTextEdit::mouseReleaseEvent(QMouseEvent *e)
+{
+ Q_D(QTextEdit);
+ d->sendControlEvent(e);
+ if (d->autoScrollTimer.isActive()) {
+ d->autoScrollTimer.stop();
+ ensureCursorVisible();
+ }
+ if (!isReadOnly() && rect().contains(e->pos()))
+ d->handleSoftwareInputPanel(e->button(), d->clickCausedFocus);
+ d->clickCausedFocus = 0;
+}
+
+/*! \reimp
+*/
+void QTextEdit::mouseDoubleClickEvent(QMouseEvent *e)
+{
+ Q_D(QTextEdit);
+ d->sendControlEvent(e);
+}
+
+/*! \reimp
+*/
+bool QTextEdit::focusNextPrevChild(bool next)
+{
+ Q_D(const QTextEdit);
+ if (!d->tabChangesFocus && d->control->textInteractionFlags() & Qt::TextEditable)
+ return false;
+ return QAbstractScrollArea::focusNextPrevChild(next);
+}
+
+#ifndef QT_NO_CONTEXTMENU
+/*!
+ \fn void QTextEdit::contextMenuEvent(QContextMenuEvent *event)
+
+ Shows the standard context menu created with createStandardContextMenu().
+
+ If you do not want the text edit to have a context menu, you can set
+ its \l contextMenuPolicy to Qt::NoContextMenu. If you want to
+ customize the context menu, reimplement this function. If you want
+ to extend the standard context menu, reimplement this function, call
+ createStandardContextMenu() and extend the menu returned.
+
+ Information about the event is passed in the \a event object.
+
+ \snippet doc/src/snippets/code/src_gui_widgets_qtextedit.cpp 0
+*/
+void QTextEdit::contextMenuEvent(QContextMenuEvent *e)
+{
+ Q_D(QTextEdit);
+ d->sendControlEvent(e);
+}
+#endif // QT_NO_CONTEXTMENU
+
+#ifndef QT_NO_DRAGANDDROP
+/*! \reimp
+*/
+void QTextEdit::dragEnterEvent(QDragEnterEvent *e)
+{
+ Q_D(QTextEdit);
+ d->inDrag = true;
+ d->sendControlEvent(e);
+}
+
+/*! \reimp
+*/
+void QTextEdit::dragLeaveEvent(QDragLeaveEvent *e)
+{
+ Q_D(QTextEdit);
+ d->inDrag = false;
+ d->autoScrollTimer.stop();
+ d->sendControlEvent(e);
+}
+
+/*! \reimp
+*/
+void QTextEdit::dragMoveEvent(QDragMoveEvent *e)
+{
+ Q_D(QTextEdit);
+ d->autoScrollDragPos = e->pos();
+ if (!d->autoScrollTimer.isActive())
+ d->autoScrollTimer.start(100, this);
+ d->sendControlEvent(e);
+}
+
+/*! \reimp
+*/
+void QTextEdit::dropEvent(QDropEvent *e)
+{
+ Q_D(QTextEdit);
+ d->inDrag = false;
+ d->autoScrollTimer.stop();
+ d->sendControlEvent(e);
+}
+
+#endif // QT_NO_DRAGANDDROP
+
+/*! \reimp
+ */
+void QTextEdit::inputMethodEvent(QInputMethodEvent *e)
+{
+ Q_D(QTextEdit);
+#ifdef QT_KEYPAD_NAVIGATION
+ if (d->control->textInteractionFlags() & Qt::TextEditable
+ && QApplication::keypadNavigationEnabled()
+ && !hasEditFocus())
+ setEditFocus(true);
+#endif
+ d->sendControlEvent(e);
+ ensureCursorVisible();
+}
+
+/*!\reimp
+*/
+void QTextEdit::scrollContentsBy(int dx, int dy)
+{
+ Q_D(QTextEdit);
+ if (isRightToLeft())
+ dx = -dx;
+ d->viewport->scroll(dx, dy);
+}
+
+/*!\reimp
+*/
+QVariant QTextEdit::inputMethodQuery(Qt::InputMethodQuery property) const
+{
+ Q_D(const QTextEdit);
+ QVariant v = d->control->inputMethodQuery(property);
+ const QPoint offset(-d->horizontalOffset(), -d->verticalOffset());
+ if (v.type() == QVariant::RectF)
+ v = v.toRectF().toRect().translated(offset);
+ else if (v.type() == QVariant::PointF)
+ v = v.toPointF().toPoint() + offset;
+ else if (v.type() == QVariant::Rect)
+ v = v.toRect().translated(offset);
+ else if (v.type() == QVariant::Point)
+ v = v.toPoint() + offset;
+ return v;
+}
+
+/*! \reimp
+*/
+void QTextEdit::focusInEvent(QFocusEvent *e)
+{
+ Q_D(QTextEdit);
+ if (e->reason() == Qt::MouseFocusReason) {
+ d->clickCausedFocus = 1;
+ }
+ QAbstractScrollArea::focusInEvent(e);
+ d->sendControlEvent(e);
+}
+
+/*! \reimp
+*/
+void QTextEdit::focusOutEvent(QFocusEvent *e)
+{
+ Q_D(QTextEdit);
+ QAbstractScrollArea::focusOutEvent(e);
+ d->sendControlEvent(e);
+}
+
+/*! \reimp
+*/
+void QTextEdit::showEvent(QShowEvent *)
+{
+ Q_D(QTextEdit);
+ if (!d->anchorToScrollToWhenVisible.isEmpty()) {
+ scrollToAnchor(d->anchorToScrollToWhenVisible);
+ d->anchorToScrollToWhenVisible.clear();
+ d->showCursorOnInitialShow = false;
+ } else if (d->showCursorOnInitialShow) {
+ d->showCursorOnInitialShow = false;
+ ensureCursorVisible();
+ }
+}
+
+/*! \reimp
+*/
+void QTextEdit::changeEvent(QEvent *e)
+{
+ Q_D(QTextEdit);
+ QAbstractScrollArea::changeEvent(e);
+ if (e->type() == QEvent::ApplicationFontChange
+ || e->type() == QEvent::FontChange) {
+ d->control->document()->setDefaultFont(font());
+ } else if(e->type() == QEvent::ActivationChange) {
+ if (!isActiveWindow())
+ d->autoScrollTimer.stop();
+ } else if (e->type() == QEvent::EnabledChange) {
+ e->setAccepted(isEnabled());
+ d->control->setPalette(palette());
+ d->sendControlEvent(e);
+ } else if (e->type() == QEvent::PaletteChange) {
+ d->control->setPalette(palette());
+ } else if (e->type() == QEvent::LayoutDirectionChange) {
+ d->sendControlEvent(e);
+ }
+}
+
+/*! \reimp
+*/
+#ifndef QT_NO_WHEELEVENT
+void QTextEdit::wheelEvent(QWheelEvent *e)
+{
+ Q_D(QTextEdit);
+ if (!(d->control->textInteractionFlags() & Qt::TextEditable)) {
+ if (e->modifiers() & Qt::ControlModifier) {
+ const int delta = e->delta();
+ if (delta < 0)
+ zoomOut();
+ else if (delta > 0)
+ zoomIn();
+ return;
+ }
+ }
+ QAbstractScrollArea::wheelEvent(e);
+ updateMicroFocus();
+}
+#endif
+
+#ifndef QT_NO_CONTEXTMENU
+/*! This function creates the standard context menu which is shown
+ when the user clicks on the text edit with the right mouse
+ button. It is called from the default contextMenuEvent() handler.
+ The popup menu's ownership is transferred to the caller.
+
+ We recommend that you use the createStandardContextMenu(QPoint) version instead
+ which will enable the actions that are sensitive to where the user clicked.
+*/
+
+QMenu *QTextEdit::createStandardContextMenu()
+{
+ Q_D(QTextEdit);
+ return d->control->createStandardContextMenu(QPointF(), this);
+}
+
+/*!
+ \since 4.4
+ This function creates the standard context menu which is shown
+ when the user clicks on the text edit with the right mouse
+ button. It is called from the default contextMenuEvent() handler
+ and it takes the \a position of where the mouse click was.
+ This can enable actions that are sensitive to the position where the user clicked.
+ The popup menu's ownership is transferred to the caller.
+*/
+
+QMenu *QTextEdit::createStandardContextMenu(const QPoint &position)
+{
+ Q_D(QTextEdit);
+ return d->control->createStandardContextMenu(position, this);
+}
+#endif // QT_NO_CONTEXTMENU
+
+/*!
+ returns a QTextCursor at position \a pos (in viewport coordinates).
+*/
+QTextCursor QTextEdit::cursorForPosition(const QPoint &pos) const
+{
+ Q_D(const QTextEdit);
+ return d->control->cursorForPosition(d->mapToContents(pos));
+}
+
+/*!
+ returns a rectangle (in viewport coordinates) that includes the
+ \a cursor.
+ */
+QRect QTextEdit::cursorRect(const QTextCursor &cursor) const
+{
+ Q_D(const QTextEdit);
+ if (cursor.isNull())
+ return QRect();
+
+ QRect r = d->control->cursorRect(cursor).toRect();
+ r.translate(-d->horizontalOffset(),-d->verticalOffset());
+ return r;
+}
+
+/*!
+ returns a rectangle (in viewport coordinates) that includes the
+ cursor of the text edit.
+ */
+QRect QTextEdit::cursorRect() const
+{
+ Q_D(const QTextEdit);
+ QRect r = d->control->cursorRect().toRect();
+ r.translate(-d->horizontalOffset(),-d->verticalOffset());
+ return r;
+}
+
+
+/*!
+ Returns the reference of the anchor at position \a pos, or an
+ empty string if no anchor exists at that point.
+*/
+QString QTextEdit::anchorAt(const QPoint& pos) const
+{
+ Q_D(const QTextEdit);
+ return d->control->anchorAt(d->mapToContents(pos));
+}
+
+/*!
+ \property QTextEdit::overwriteMode
+ \since 4.1
+ \brief whether text entered by the user will overwrite existing text
+
+ As with many text editors, the text editor widget can be configured
+ to insert or overwrite existing text with new text entered by the user.
+
+ If this property is true, existing text is overwritten, character-for-character
+ by new text; otherwise, text is inserted at the cursor position, displacing
+ existing text.
+
+ By default, this property is false (new text does not overwrite existing text).
+*/
+
+bool QTextEdit::overwriteMode() const
+{
+ Q_D(const QTextEdit);
+ return d->control->overwriteMode();
+}
+
+void QTextEdit::setOverwriteMode(bool overwrite)
+{
+ Q_D(QTextEdit);
+ d->control->setOverwriteMode(overwrite);
+}
+
+/*!
+ \property QTextEdit::tabStopWidth
+ \brief the tab stop width in pixels
+ \since 4.1
+
+ By default, this property contains a value of 80 pixels.
+*/
+
+int QTextEdit::tabStopWidth() const
+{
+ Q_D(const QTextEdit);
+ return qRound(d->control->document()->defaultTextOption().tabStop());
+}
+
+void QTextEdit::setTabStopWidth(int width)
+{
+ Q_D(QTextEdit);
+ QTextOption opt = d->control->document()->defaultTextOption();
+ if (opt.tabStop() == width || width < 0)
+ return;
+ opt.setTabStop(width);
+ d->control->document()->setDefaultTextOption(opt);
+}
+
+/*!
+ \since 4.2
+ \property QTextEdit::cursorWidth
+
+ This property specifies the width of the cursor in pixels. The default value is 1.
+*/
+int QTextEdit::cursorWidth() const
+{
+ Q_D(const QTextEdit);
+ return d->control->cursorWidth();
+}
+
+void QTextEdit::setCursorWidth(int width)
+{
+ Q_D(QTextEdit);
+ d->control->setCursorWidth(width);
+}
+
+/*!
+ \property QTextEdit::acceptRichText
+ \brief whether the text edit accepts rich text insertions by the user
+ \since 4.1
+
+ When this propery is set to false text edit will accept only
+ plain text input from the user. For example through clipboard or drag and drop.
+
+ This property's default is true.
+*/
+
+bool QTextEdit::acceptRichText() const
+{
+ Q_D(const QTextEdit);
+ return d->control->acceptRichText();
+}
+
+void QTextEdit::setAcceptRichText(bool accept)
+{
+ Q_D(QTextEdit);
+ d->control->setAcceptRichText(accept);
+}
+
+/*!
+ \class QTextEdit::ExtraSelection
+ \since 4.2
+ \brief The QTextEdit::ExtraSelection structure provides a way of specifying a
+ character format for a given selection in a document
+*/
+
+/*!
+ \variable QTextEdit::ExtraSelection::cursor
+ A cursor that contains a selection in a QTextDocument
+*/
+
+/*!
+ \variable QTextEdit::ExtraSelection::format
+ A format that is used to specify a foreground or background brush/color
+ for the selection.
+*/
+
+/*!
+ \since 4.2
+ This function allows temporarily marking certain regions in the document
+ with a given color, specified as \a selections. This can be useful for
+ example in a programming editor to mark a whole line of text with a given
+ background color to indicate the existence of a breakpoint.
+
+ \sa QTextEdit::ExtraSelection, extraSelections()
+*/
+void QTextEdit::setExtraSelections(const QList<ExtraSelection> &selections)
+{
+ Q_D(QTextEdit);
+ d->control->setExtraSelections(selections);
+}
+
+/*!
+ \since 4.2
+ Returns previously set extra selections.
+
+ \sa setExtraSelections()
+*/
+QList<QTextEdit::ExtraSelection> QTextEdit::extraSelections() const
+{
+ Q_D(const QTextEdit);
+ return d->control->extraSelections();
+}
+
+/*!
+ This function returns a new MIME data object to represent the contents
+ of the text edit's current selection. It is called when the selection needs
+ to be encapsulated into a new QMimeData object; for example, when a drag
+ and drop operation is started, or when data is copyied to the clipboard.
+
+ If you reimplement this function, note that the ownership of the returned
+ QMimeData object is passed to the caller. The selection can be retrieved
+ by using the textCursor() function.
+*/
+QMimeData *QTextEdit::createMimeDataFromSelection() const
+{
+ Q_D(const QTextEdit);
+ return d->control->QWidgetTextControl::createMimeDataFromSelection();
+}
+
+/*!
+ This function returns true if the contents of the MIME data object, specified
+ by \a source, can be decoded and inserted into the document. It is called
+ for example when during a drag operation the mouse enters this widget and it
+ is necessary to determine whether it is possible to accept the drag and drop
+ operation.
+
+ Reimplement this function to enable drag and drop support for additional MIME types.
+ */
+bool QTextEdit::canInsertFromMimeData(const QMimeData *source) const
+{
+ Q_D(const QTextEdit);
+ return d->control->QWidgetTextControl::canInsertFromMimeData(source);
+}
+
+/*!
+ This function inserts the contents of the MIME data object, specified
+ by \a source, into the text edit at the current cursor position. It is
+ called whenever text is inserted as the result of a clipboard paste
+ operation, or when the text edit accepts data from a drag and drop
+ operation.
+
+ Reimplement this function to enable drag and drop support for additional MIME types.
+ */
+void QTextEdit::insertFromMimeData(const QMimeData *source)
+{
+ Q_D(QTextEdit);
+ d->control->QWidgetTextControl::insertFromMimeData(source);
+}
+
+/*!
+ \property QTextEdit::readOnly
+ \brief whether the text edit is read-only
+
+ In a read-only text edit the user can only navigate through the
+ text and select text; modifying the text is not possible.
+
+ This property's default is false.
+*/
+
+bool QTextEdit::isReadOnly() const
+{
+ Q_D(const QTextEdit);
+ return !(d->control->textInteractionFlags() & Qt::TextEditable);
+}
+
+void QTextEdit::setReadOnly(bool ro)
+{
+ Q_D(QTextEdit);
+ Qt::TextInteractionFlags flags = Qt::NoTextInteraction;
+ if (ro) {
+ flags = Qt::TextSelectableByMouse;
+#ifndef QT_NO_TEXTBROWSER
+ if (qobject_cast<QTextBrowser *>(this))
+ flags |= Qt::TextBrowserInteraction;
+#endif
+ } else {
+ flags = Qt::TextEditorInteraction;
+ }
+ d->control->setTextInteractionFlags(flags);
+ setAttribute(Qt::WA_InputMethodEnabled, shouldEnableInputMethod(this));
+}
+
+/*!
+ \property QTextEdit::textInteractionFlags
+ \since 4.2
+
+ Specifies how the widget should interact with user input.
+
+ The default value depends on whether the QTextEdit is read-only
+ or editable, and whether it is a QTextBrowser or not.
+*/
+
+void QTextEdit::setTextInteractionFlags(Qt::TextInteractionFlags flags)
+{
+ Q_D(QTextEdit);
+ d->control->setTextInteractionFlags(flags);
+}
+
+Qt::TextInteractionFlags QTextEdit::textInteractionFlags() const
+{
+ Q_D(const QTextEdit);
+ return d->control->textInteractionFlags();
+}
+
+/*!
+ Merges the properties specified in \a modifier into the current character
+ format by calling QTextCursor::mergeCharFormat on the editor's cursor.
+ If the editor has a selection then the properties of \a modifier are
+ directly applied to the selection.
+
+ \sa QTextCursor::mergeCharFormat()
+ */
+void QTextEdit::mergeCurrentCharFormat(const QTextCharFormat &modifier)
+{
+ Q_D(QTextEdit);
+ d->control->mergeCurrentCharFormat(modifier);
+}
+
+/*!
+ Sets the char format that is be used when inserting new text to \a
+ format by calling QTextCursor::setCharFormat() on the editor's
+ cursor. If the editor has a selection then the char format is
+ directly applied to the selection.
+ */
+void QTextEdit::setCurrentCharFormat(const QTextCharFormat &format)
+{
+ Q_D(QTextEdit);
+ d->control->setCurrentCharFormat(format);
+}
+
+/*!
+ Returns the char format that is used when inserting new text.
+ */
+QTextCharFormat QTextEdit::currentCharFormat() const
+{
+ Q_D(const QTextEdit);
+ return d->control->currentCharFormat();
+}
+
+/*!
+ \property QTextEdit::autoFormatting
+ \brief the enabled set of auto formatting features
+
+ The value can be any combination of the values in the
+ AutoFormattingFlag enum. The default is AutoNone. Choose
+ AutoAll to enable all automatic formatting.
+
+ Currently, the only automatic formatting feature provided is
+ AutoBulletList; future versions of Qt may offer more.
+*/
+
+QTextEdit::AutoFormatting QTextEdit::autoFormatting() const
+{
+ Q_D(const QTextEdit);
+ return d->autoFormatting;
+}
+
+void QTextEdit::setAutoFormatting(AutoFormatting features)
+{
+ Q_D(QTextEdit);
+ d->autoFormatting = features;
+}
+
+/*!
+ Convenience slot that inserts \a text at the current
+ cursor position.
+
+ It is equivalent to
+
+ \snippet doc/src/snippets/code/src_gui_widgets_qtextedit.cpp 1
+ */
+void QTextEdit::insertPlainText(const QString &text)
+{
+ Q_D(QTextEdit);
+ d->control->insertPlainText(text);
+}
+
+/*!
+ Convenience slot that inserts \a text which is assumed to be of
+ html formatting at the current cursor position.
+
+ It is equivalent to:
+
+ \snippet doc/src/snippets/code/src_gui_widgets_qtextedit.cpp 2
+
+ \note When using this function with a style sheet, the style sheet will
+ only apply to the current block in the document. In order to apply a style
+ sheet throughout a document, use QTextDocument::setDefaultStyleSheet()
+ instead.
+ */
+#ifndef QT_NO_TEXTHTMLPARSER
+void QTextEdit::insertHtml(const QString &text)
+{
+ Q_D(QTextEdit);
+ d->control->insertHtml(text);
+}
+#endif // QT_NO_TEXTHTMLPARSER
+
+/*!
+ Scrolls the text edit so that the anchor with the given \a name is
+ visible; does nothing if the \a name is empty, or is already
+ visible, or isn't found.
+*/
+void QTextEdit::scrollToAnchor(const QString &name)
+{
+ Q_D(QTextEdit);
+ if (name.isEmpty())
+ return;
+
+ if (!isVisible()) {
+ d->anchorToScrollToWhenVisible = name;
+ return;
+ }
+
+ QPointF p = d->control->anchorPosition(name);
+ const int newPosition = qRound(p.y());
+ if ( d->vbar->maximum() < newPosition )
+ d->_q_adjustScrollbars();
+ d->vbar->setValue(newPosition);
+}
+
+/*!
+ \fn QTextEdit::zoomIn(int range)
+
+ Zooms in on the text by making the base font size \a range
+ points larger and recalculating all font sizes to be the new size.
+ This does not change the size of any images.
+
+ \sa zoomOut()
+*/
+void QTextEdit::zoomIn(int range)
+{
+ QFont f = font();
+ const int newSize = f.pointSize() + range;
+ if (newSize <= 0)
+ return;
+ f.setPointSize(newSize);
+ setFont(f);
+}
+
+/*!
+ \fn QTextEdit::zoomOut(int range)
+
+ \overload
+
+ Zooms out on the text by making the base font size \a range points
+ smaller and recalculating all font sizes to be the new size. This
+ does not change the size of any images.
+
+ \sa zoomIn()
+*/
+void QTextEdit::zoomOut(int range)
+{
+ zoomIn(-range);
+}
+
+/*!
+ \since 4.2
+ Moves the cursor by performing the given \a operation.
+
+ If \a mode is QTextCursor::KeepAnchor, the cursor selects the text it moves over.
+ This is the same effect that the user achieves when they hold down the Shift key
+ and move the cursor with the cursor keys.
+
+ \sa QTextCursor::movePosition()
+*/
+void QTextEdit::moveCursor(QTextCursor::MoveOperation operation, QTextCursor::MoveMode mode)
+{
+ Q_D(QTextEdit);
+ d->control->moveCursor(operation, mode);
+}
+
+/*!
+ \since 4.2
+ Returns whether text can be pasted from the clipboard into the textedit.
+*/
+bool QTextEdit::canPaste() const
+{
+ Q_D(const QTextEdit);
+ return d->control->canPaste();
+}
+
+/*!
+ \since 4.3
+ Convenience function to print the text edit's document to the given \a printer. This
+ is equivalent to calling the print method on the document directly except that this
+ function also supports QPrinter::Selection as print range.
+
+ \sa QTextDocument::print()
+*/
+void QTextEdit::print(QPagedPaintDevice *printer) const
+{
+ Q_D(const QTextEdit);
+ d->control->print(printer);
+}
+
+/*! \property QTextEdit::tabChangesFocus
+ \brief whether \gui Tab changes focus or is accepted as input
+
+ In some occasions text edits should not allow the user to input
+ tabulators or change indentation using the \gui Tab key, as this breaks
+ the focus chain. The default is false.
+
+*/
+
+bool QTextEdit::tabChangesFocus() const
+{
+ Q_D(const QTextEdit);
+ return d->tabChangesFocus;
+}
+
+void QTextEdit::setTabChangesFocus(bool b)
+{
+ Q_D(QTextEdit);
+ d->tabChangesFocus = b;
+}
+
+/*!
+ \property QTextEdit::documentTitle
+ \brief the title of the document parsed from the text.
+
+ By default, for a newly-created, empty document, this property contains
+ an empty string.
+*/
+
+/*!
+ \property QTextEdit::lineWrapMode
+ \brief the line wrap mode
+
+ The default mode is WidgetWidth which causes words to be
+ wrapped at the right edge of the text edit. Wrapping occurs at
+ whitespace, keeping whole words intact. If you want wrapping to
+ occur within words use setWordWrapMode(). If you set a wrap mode of
+ FixedPixelWidth or FixedColumnWidth you should also call
+ setLineWrapColumnOrWidth() with the width you want.
+
+ \sa lineWrapColumnOrWidth
+*/
+
+QTextEdit::LineWrapMode QTextEdit::lineWrapMode() const
+{
+ Q_D(const QTextEdit);
+ return d->lineWrap;
+}
+
+void QTextEdit::setLineWrapMode(LineWrapMode wrap)
+{
+ Q_D(QTextEdit);
+ if (d->lineWrap == wrap)
+ return;
+ d->lineWrap = wrap;
+ d->updateDefaultTextOption();
+ d->relayoutDocument();
+}
+
+/*!
+ \property QTextEdit::lineWrapColumnOrWidth
+ \brief the position (in pixels or columns depending on the wrap mode) where text will be wrapped
+
+ If the wrap mode is FixedPixelWidth, the value is the number of
+ pixels from the left edge of the text edit at which text should be
+ wrapped. If the wrap mode is FixedColumnWidth, the value is the
+ column number (in character columns) from the left edge of the
+ text edit at which text should be wrapped.
+
+ By default, this property contains a value of 0.
+
+ \sa lineWrapMode
+*/
+
+int QTextEdit::lineWrapColumnOrWidth() const
+{
+ Q_D(const QTextEdit);
+ return d->lineWrapColumnOrWidth;
+}
+
+void QTextEdit::setLineWrapColumnOrWidth(int w)
+{
+ Q_D(QTextEdit);
+ d->lineWrapColumnOrWidth = w;
+ d->relayoutDocument();
+}
+
+/*!
+ \property QTextEdit::wordWrapMode
+ \brief the mode QTextEdit will use when wrapping text by words
+
+ By default, this property is set to QTextOption::WrapAtWordBoundaryOrAnywhere.
+
+ \sa QTextOption::WrapMode
+*/
+
+QTextOption::WrapMode QTextEdit::wordWrapMode() const
+{
+ Q_D(const QTextEdit);
+ return d->wordWrap;
+}
+
+void QTextEdit::setWordWrapMode(QTextOption::WrapMode mode)
+{
+ Q_D(QTextEdit);
+ if (mode == d->wordWrap)
+ return;
+ d->wordWrap = mode;
+ d->updateDefaultTextOption();
+}
+
+/*!
+ Finds the next occurrence of the string, \a exp, using the given
+ \a options. Returns true if \a exp was found and changes the
+ cursor to select the match; otherwise returns false.
+*/
+bool QTextEdit::find(const QString &exp, QTextDocument::FindFlags options)
+{
+ Q_D(QTextEdit);
+ return d->control->find(exp, options);
+}
+
+/*!
+ \fn void QTextEdit::copyAvailable(bool yes)
+
+ This signal is emitted when text is selected or de-selected in the
+ text edit.
+
+ When text is selected this signal will be emitted with \a yes set
+ to true. If no text has been selected or if the selected text is
+ de-selected this signal is emitted with \a yes set to false.
+
+ If \a yes is true then copy() can be used to copy the selection to
+ the clipboard. If \a yes is false then copy() does nothing.
+
+ \sa selectionChanged()
+*/
+
+/*!
+ \fn void QTextEdit::currentCharFormatChanged(const QTextCharFormat &f)
+
+ This signal is emitted if the current character format has changed, for
+ example caused by a change of the cursor position.
+
+ The new format is \a f.
+
+ \sa setCurrentCharFormat()
+*/
+
+/*!
+ \fn void QTextEdit::selectionChanged()
+
+ This signal is emitted whenever the selection changes.
+
+ \sa copyAvailable()
+*/
+
+/*!
+ \fn void QTextEdit::cursorPositionChanged()
+
+ This signal is emitted whenever the position of the
+ cursor changed.
+*/
+
+/*!
+ \since 4.2
+
+ Sets the text edit's \a text. The text can be plain text or HTML
+ and the text edit will try to guess the right format.
+
+ Use setHtml() or setPlainText() directly to avoid text edit's guessing.
+*/
+void QTextEdit::setText(const QString &text)
+{
+ Q_D(QTextEdit);
+ Qt::TextFormat format = d->textFormat;
+ if (d->textFormat == Qt::AutoText)
+ format = Qt::mightBeRichText(text) ? Qt::RichText : Qt::PlainText;
+#ifndef QT_NO_TEXTHTMLPARSER
+ if (format == Qt::RichText || format == Qt::LogText)
+ setHtml(text);
+ else
+#endif
+ setPlainText(text);
+}
+
+#ifdef QT3_SUPPORT
+/*!
+ Use the QTextCursor class instead.
+*/
+void QTextEdit::moveCursor(CursorAction action, QTextCursor::MoveMode mode)
+{
+ Q_D(QTextEdit);
+ if (action == MovePageUp) {
+ d->pageUpDown(QTextCursor::Up, mode);
+ return;
+ } else if (action == MovePageDown) {
+ d->pageUpDown(QTextCursor::Down, mode);
+ return;
+ }
+
+ QTextCursor cursor = d->control->textCursor();
+ QTextCursor::MoveOperation op = QTextCursor::NoMove;
+ switch (action) {
+ case MoveBackward: op = QTextCursor::Left; break;
+ case MoveForward: op = QTextCursor::Right; break;
+ case MoveWordBackward: op = QTextCursor::WordLeft; break;
+ case MoveWordForward: op = QTextCursor::WordRight; break;
+ case MoveUp: op = QTextCursor::Up; break;
+ case MoveDown: op = QTextCursor::Down; break;
+ case MoveLineStart: op = QTextCursor::StartOfLine; break;
+ case MoveLineEnd: op = QTextCursor::EndOfLine; break;
+ case MoveHome: op = QTextCursor::Start; break;
+ case MoveEnd: op = QTextCursor::End; break;
+ default: return;
+ }
+ cursor.movePosition(op, mode);
+ d->control->setTextCursor(cursor);
+}
+
+/*!
+ Use the QTextCursor class instead.
+*/
+void QTextEdit::moveCursor(CursorAction action, bool select)
+{
+ moveCursor(action, select ? QTextCursor::KeepAnchor : QTextCursor::MoveAnchor);
+}
+
+/*!
+ Executes keyboard action \a action.
+
+ Use the QTextCursor class instead.
+
+ \sa textCursor()
+*/
+void QTextEdit::doKeyboardAction(KeyboardAction action)
+{
+ Q_D(QTextEdit);
+ QTextCursor cursor = d->control->textCursor();
+ switch (action) {
+ case ActionBackspace: cursor.deletePreviousChar(); break;
+ case ActionDelete: cursor.deleteChar(); break;
+ case ActionReturn: cursor.insertBlock(); break;
+ case ActionKill: {
+ QTextBlock block = cursor.block();
+ if (cursor.position() == block.position() + block.length() - 2)
+ cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor);
+ else
+ cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
+ cursor.deleteChar();
+ break;
+ }
+ case ActionWordBackspace:
+ cursor.movePosition(QTextCursor::PreviousWord, QTextCursor::KeepAnchor);
+ cursor.deletePreviousChar();
+ break;
+ case ActionWordDelete:
+ cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);
+ cursor.deleteChar();
+ break;
+ }
+ d->control->setTextCursor(cursor);
+}
+
+/*!
+ Returns all the text in the text edit as plain text.
+*/
+QString QTextEdit::text() const
+{
+ Q_D(const QTextEdit);
+ if (d->textFormat == Qt::RichText || d->textFormat == Qt::LogText || (d->textFormat == Qt::AutoText && d->preferRichText))
+ return d->control->toHtml();
+ else
+ return d->control->toPlainText();
+}
+
+
+/*!
+ Sets the text format to format \a f.
+
+ \sa textFormat()
+*/
+void QTextEdit::setTextFormat(Qt::TextFormat f)
+{
+ Q_D(QTextEdit);
+ d->textFormat = f;
+}
+
+/*!
+ Returns the text format.
+
+ \sa setTextFormat()
+*/
+Qt::TextFormat QTextEdit::textFormat() const
+{
+ Q_D(const QTextEdit);
+ return d->textFormat;
+}
+
+#endif // QT3_SUPPORT
+
+/*!
+ Appends a new paragraph with \a text to the end of the text edit.
+
+ \note The new paragraph appended will have the same character format and
+ block format as the current paragraph, determined by the position of the cursor.
+
+ \sa currentCharFormat(), QTextCursor::blockFormat()
+*/
+
+void QTextEdit::append(const QString &text)
+{
+ Q_D(QTextEdit);
+ const bool atBottom = isReadOnly() ? d->verticalOffset() >= d->vbar->maximum() :
+ d->control->textCursor().atEnd();
+ d->control->append(text);
+ if (atBottom)
+ d->vbar->setValue(d->vbar->maximum());
+}
+
+/*!
+ Ensures that the cursor is visible by scrolling the text edit if
+ necessary.
+*/
+void QTextEdit::ensureCursorVisible()
+{
+ Q_D(QTextEdit);
+ d->control->ensureCursorVisible();
+}
+
+/*!
+ \enum QTextEdit::KeyboardAction
+
+ \compat
+
+ \value ActionBackspace
+ \value ActionDelete
+ \value ActionReturn
+ \value ActionKill
+ \value ActionWordBackspace
+ \value ActionWordDelete
+*/
+
+/*!
+ \fn bool QTextEdit::find(const QString &exp, bool cs, bool wo)
+
+ Use the find() overload that takes a QTextDocument::FindFlags
+ argument.
+*/
+
+/*!
+ \fn void QTextEdit::sync()
+
+ Does nothing.
+*/
+
+/*!
+ \fn void QTextEdit::setBold(bool b)
+
+ Use setFontWeight() instead.
+*/
+
+/*!
+ \fn void QTextEdit::setUnderline(bool b)
+
+ Use setFontUnderline() instead.
+*/
+
+/*!
+ \fn void QTextEdit::setItalic(bool i)
+
+ Use setFontItalic() instead.
+*/
+
+/*!
+ \fn void QTextEdit::setFamily(const QString &family)
+
+ Use setFontFamily() instead.
+*/
+
+/*!
+ \fn void QTextEdit::setPointSize(int size)
+
+ Use setFontPointSize() instead.
+*/
+
+/*!
+ \fn bool QTextEdit::italic() const
+
+ Use fontItalic() instead.
+*/
+
+/*!
+ \fn bool QTextEdit::bold() const
+
+ Use fontWeight() >= QFont::Bold instead.
+*/
+
+/*!
+ \fn bool QTextEdit::underline() const
+
+ Use fontUnderline() instead.
+*/
+
+/*!
+ \fn QString QTextEdit::family() const
+
+ Use fontFamily() instead.
+*/
+
+/*!
+ \fn int QTextEdit::pointSize() const
+
+ Use int(fontPointSize()+0.5) instead.
+*/
+
+/*!
+ \fn bool QTextEdit::hasSelectedText() const
+
+ Use textCursor().hasSelection() instead.
+*/
+
+/*!
+ \fn QString QTextEdit::selectedText() const
+
+ Use textCursor().selectedText() instead.
+*/
+
+/*!
+ \fn bool QTextEdit::isUndoAvailable() const
+
+ Use document()->isUndoAvailable() instead.
+*/
+
+/*!
+ \fn bool QTextEdit::isRedoAvailable() const
+
+ Use document()->isRedoAvailable() instead.
+*/
+
+/*!
+ \fn void QTextEdit::insert(const QString &text)
+
+ Use insertPlainText() instead.
+*/
+
+/*!
+ \fn bool QTextEdit::isModified() const
+
+ Use document()->isModified() instead.
+*/
+
+/*!
+ \fn QColor QTextEdit::color() const
+
+ Use textColor() instead.
+*/
+
+/*!
+ \fn void QTextEdit::textChanged()
+
+ This signal is emitted whenever the document's content changes; for
+ example, when text is inserted or deleted, or when formatting is applied.
+*/
+
+/*!
+ \fn void QTextEdit::undoAvailable(bool available)
+
+ This signal is emitted whenever undo operations become available
+ (\a available is true) or unavailable (\a available is false).
+*/
+
+/*!
+ \fn void QTextEdit::redoAvailable(bool available)
+
+ This signal is emitted whenever redo operations become available
+ (\a available is true) or unavailable (\a available is false).
+*/
+
+/*!
+ \fn void QTextEdit::currentFontChanged(const QFont &font)
+
+ Use currentCharFormatChanged() instead.
+*/
+
+/*!
+ \fn void QTextEdit::currentColorChanged(const QColor &color)
+
+ Use currentCharFormatChanged() instead.
+*/
+
+/*!
+ \fn void QTextEdit::setModified(bool m)
+
+ Use document->setModified() instead.
+*/
+
+/*!
+ \fn void QTextEdit::setColor(const QColor &color)
+
+ Use setTextColor() instead.
+*/
+#endif // QT_NO_TEXTEDIT
+
+QT_END_NAMESPACE
+
+#include "moc_qtextedit.cpp"
diff --git a/src/widgets/widgets/qtextedit.h b/src/widgets/widgets/qtextedit.h
new file mode 100644
index 0000000000..69f5ac23d5
--- /dev/null
+++ b/src/widgets/widgets/qtextedit.h
@@ -0,0 +1,430 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTEXTEDIT_H
+#define QTEXTEDIT_H
+
+#include <QtWidgets/qabstractscrollarea.h>
+#include <QtGui/qtextdocument.h>
+#include <QtGui/qtextoption.h>
+#include <QtGui/qtextcursor.h>
+#include <QtGui/qtextformat.h>
+
+#ifndef QT_NO_TEXTEDIT
+
+#ifdef QT3_SUPPORT
+#include <QtGui/qtextobject.h>
+#include <QtGui/qtextlayout.h>
+#endif
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QStyleSheet;
+class QTextDocument;
+class QMenu;
+class QTextEditPrivate;
+class QMimeData;
+class QPagedPaintDevice;
+
+class Q_WIDGETS_EXPORT QTextEdit : public QAbstractScrollArea
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QTextEdit)
+ Q_FLAGS(AutoFormatting)
+ Q_ENUMS(LineWrapMode)
+ Q_PROPERTY(AutoFormatting autoFormatting READ autoFormatting WRITE setAutoFormatting)
+ Q_PROPERTY(bool tabChangesFocus READ tabChangesFocus WRITE setTabChangesFocus)
+ Q_PROPERTY(QString documentTitle READ documentTitle WRITE setDocumentTitle)
+ Q_PROPERTY(bool undoRedoEnabled READ isUndoRedoEnabled WRITE setUndoRedoEnabled)
+ Q_PROPERTY(LineWrapMode lineWrapMode READ lineWrapMode WRITE setLineWrapMode)
+ QDOC_PROPERTY(QTextOption::WrapMode wordWrapMode READ wordWrapMode WRITE setWordWrapMode)
+ Q_PROPERTY(int lineWrapColumnOrWidth READ lineWrapColumnOrWidth WRITE setLineWrapColumnOrWidth)
+ Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly)
+#ifndef QT_NO_TEXTHTMLPARSER
+ Q_PROPERTY(QString html READ toHtml WRITE setHtml NOTIFY textChanged USER true)
+#endif
+ Q_PROPERTY(QString plainText READ toPlainText WRITE setPlainText DESIGNABLE false)
+ Q_PROPERTY(bool overwriteMode READ overwriteMode WRITE setOverwriteMode)
+ Q_PROPERTY(int tabStopWidth READ tabStopWidth WRITE setTabStopWidth)
+ Q_PROPERTY(bool acceptRichText READ acceptRichText WRITE setAcceptRichText)
+ Q_PROPERTY(int cursorWidth READ cursorWidth WRITE setCursorWidth)
+ Q_PROPERTY(Qt::TextInteractionFlags textInteractionFlags READ textInteractionFlags WRITE setTextInteractionFlags)
+ Q_PROPERTY(QObject *document READ document)
+public:
+ enum LineWrapMode {
+ NoWrap,
+ WidgetWidth,
+ FixedPixelWidth,
+ FixedColumnWidth
+ };
+
+ enum AutoFormattingFlag {
+ AutoNone = 0,
+ AutoBulletList = 0x00000001,
+ AutoAll = 0xffffffff
+ };
+
+ Q_DECLARE_FLAGS(AutoFormatting, AutoFormattingFlag)
+
+#if defined(QT3_SUPPORT)
+ enum CursorAction {
+ MoveBackward,
+ MoveForward,
+ MoveWordBackward,
+ MoveWordForward,
+ MoveUp,
+ MoveDown,
+ MoveLineStart,
+ MoveLineEnd,
+ MoveHome,
+ MoveEnd,
+ MovePageUp,
+ MovePageDown
+#if !defined(Q_MOC_RUN)
+ ,
+ MovePgUp = MovePageUp,
+ MovePgDown = MovePageDown
+#endif
+ };
+#endif
+
+ explicit QTextEdit(QWidget *parent = 0);
+ explicit QTextEdit(const QString &text, QWidget *parent = 0);
+ virtual ~QTextEdit();
+
+ void setDocument(QTextDocument *document);
+ QTextDocument *document() const;
+
+ void setTextCursor(const QTextCursor &cursor);
+ QTextCursor textCursor() const;
+
+ bool isReadOnly() const;
+ void setReadOnly(bool ro);
+
+ void setTextInteractionFlags(Qt::TextInteractionFlags flags);
+ Qt::TextInteractionFlags textInteractionFlags() const;
+
+ qreal fontPointSize() const;
+ QString fontFamily() const;
+ int fontWeight() const;
+ bool fontUnderline() const;
+ bool fontItalic() const;
+ QColor textColor() const;
+ QColor textBackgroundColor() const;
+ QFont currentFont() const;
+ Qt::Alignment alignment() const;
+
+ void mergeCurrentCharFormat(const QTextCharFormat &modifier);
+
+ void setCurrentCharFormat(const QTextCharFormat &format);
+ QTextCharFormat currentCharFormat() const;
+
+ AutoFormatting autoFormatting() const;
+ void setAutoFormatting(AutoFormatting features);
+
+ bool tabChangesFocus() const;
+ void setTabChangesFocus(bool b);
+
+ inline void setDocumentTitle(const QString &title)
+ { document()->setMetaInformation(QTextDocument::DocumentTitle, title); }
+ inline QString documentTitle() const
+ { return document()->metaInformation(QTextDocument::DocumentTitle); }
+
+ inline bool isUndoRedoEnabled() const
+ { return document()->isUndoRedoEnabled(); }
+ inline void setUndoRedoEnabled(bool enable)
+ { document()->setUndoRedoEnabled(enable); }
+
+ LineWrapMode lineWrapMode() const;
+ void setLineWrapMode(LineWrapMode mode);
+
+ int lineWrapColumnOrWidth() const;
+ void setLineWrapColumnOrWidth(int w);
+
+ QTextOption::WrapMode wordWrapMode() const;
+ void setWordWrapMode(QTextOption::WrapMode policy);
+
+ bool find(const QString &exp, QTextDocument::FindFlags options = 0);
+
+ inline QString toPlainText() const
+ { return document()->toPlainText(); }
+#ifndef QT_NO_TEXTHTMLPARSER
+ inline QString toHtml() const
+ { return document()->toHtml(); }
+#endif
+
+ void ensureCursorVisible();
+
+ virtual QVariant loadResource(int type, const QUrl &name);
+#ifndef QT_NO_CONTEXTMENU
+ QMenu *createStandardContextMenu();
+ QMenu *createStandardContextMenu(const QPoint &position);
+#endif
+
+ QTextCursor cursorForPosition(const QPoint &pos) const;
+ QRect cursorRect(const QTextCursor &cursor) const;
+ QRect cursorRect() const;
+
+ QString anchorAt(const QPoint& pos) const;
+
+ bool overwriteMode() const;
+ void setOverwriteMode(bool overwrite);
+
+ int tabStopWidth() const;
+ void setTabStopWidth(int width);
+
+ int cursorWidth() const;
+ void setCursorWidth(int width);
+
+ bool acceptRichText() const;
+ void setAcceptRichText(bool accept);
+
+ struct ExtraSelection
+ {
+ QTextCursor cursor;
+ QTextCharFormat format;
+ };
+ void setExtraSelections(const QList<ExtraSelection> &selections);
+ QList<ExtraSelection> extraSelections() const;
+
+ void moveCursor(QTextCursor::MoveOperation operation, QTextCursor::MoveMode mode = QTextCursor::MoveAnchor);
+
+ bool canPaste() const;
+
+ void print(QPagedPaintDevice *printer) const;
+
+public Q_SLOTS:
+ void setFontPointSize(qreal s);
+ void setFontFamily(const QString &fontFamily);
+ void setFontWeight(int w);
+ void setFontUnderline(bool b);
+ void setFontItalic(bool b);
+ void setTextColor(const QColor &c);
+ void setTextBackgroundColor(const QColor &c);
+ void setCurrentFont(const QFont &f);
+ void setAlignment(Qt::Alignment a);
+
+ void setPlainText(const QString &text);
+#ifndef QT_NO_TEXTHTMLPARSER
+ void setHtml(const QString &text);
+#endif
+ void setText(const QString &text);
+
+#ifndef QT_NO_CLIPBOARD
+ void cut();
+ void copy();
+ void paste();
+#endif
+
+ void undo();
+ void redo();
+
+ void clear();
+ void selectAll();
+
+ void insertPlainText(const QString &text);
+#ifndef QT_NO_TEXTHTMLPARSER
+ void insertHtml(const QString &text);
+#endif // QT_NO_TEXTHTMLPARSER
+
+ void append(const QString &text);
+
+ void scrollToAnchor(const QString &name);
+
+ void zoomIn(int range = 1);
+ void zoomOut(int range = 1);
+
+Q_SIGNALS:
+ void textChanged();
+ void undoAvailable(bool b);
+ void redoAvailable(bool b);
+ void currentCharFormatChanged(const QTextCharFormat &format);
+ void copyAvailable(bool b);
+ void selectionChanged();
+ void cursorPositionChanged();
+
+protected:
+ virtual bool event(QEvent *e);
+ virtual void timerEvent(QTimerEvent *e);
+ virtual void keyPressEvent(QKeyEvent *e);
+ virtual void keyReleaseEvent(QKeyEvent *e);
+ virtual void resizeEvent(QResizeEvent *e);
+ virtual void paintEvent(QPaintEvent *e);
+ virtual void mousePressEvent(QMouseEvent *e);
+ virtual void mouseMoveEvent(QMouseEvent *e);
+ virtual void mouseReleaseEvent(QMouseEvent *e);
+ virtual void mouseDoubleClickEvent(QMouseEvent *e);
+ virtual bool focusNextPrevChild(bool next);
+#ifndef QT_NO_CONTEXTMENU
+ virtual void contextMenuEvent(QContextMenuEvent *e);
+#endif
+#ifndef QT_NO_DRAGANDDROP
+ virtual void dragEnterEvent(QDragEnterEvent *e);
+ virtual void dragLeaveEvent(QDragLeaveEvent *e);
+ virtual void dragMoveEvent(QDragMoveEvent *e);
+ virtual void dropEvent(QDropEvent *e);
+#endif
+ virtual void focusInEvent(QFocusEvent *e);
+ virtual void focusOutEvent(QFocusEvent *e);
+ virtual void showEvent(QShowEvent *);
+ virtual void changeEvent(QEvent *e);
+#ifndef QT_NO_WHEELEVENT
+ virtual void wheelEvent(QWheelEvent *e);
+#endif
+
+ virtual QMimeData *createMimeDataFromSelection() const;
+ virtual bool canInsertFromMimeData(const QMimeData *source) const;
+ virtual void insertFromMimeData(const QMimeData *source);
+
+ virtual void inputMethodEvent(QInputMethodEvent *);
+ QVariant inputMethodQuery(Qt::InputMethodQuery property) const;
+
+ QTextEdit(QTextEditPrivate &dd, QWidget *parent);
+
+ virtual void scrollContentsBy(int dx, int dy);
+
+#ifdef QT3_SUPPORT
+Q_SIGNALS:
+ QT_MOC_COMPAT void currentFontChanged(const QFont &f);
+ QT_MOC_COMPAT void currentColorChanged(const QColor &c);
+
+public:
+ QT3_SUPPORT_CONSTRUCTOR QTextEdit(QWidget *parent, const char *name);
+ inline QT3_SUPPORT bool find(const QString &exp, bool cs, bool wo)
+ {
+ QTextDocument::FindFlags flags = 0;
+ if (cs)
+ flags |= QTextDocument::FindCaseSensitively;
+ if (wo)
+ flags |= QTextDocument::FindWholeWords;
+ return find(exp, flags);
+ }
+
+ inline QT3_SUPPORT void sync() {}
+
+ QT3_SUPPORT void moveCursor(CursorAction action, QTextCursor::MoveMode mode = QTextCursor::MoveAnchor);
+ QT3_SUPPORT void moveCursor(CursorAction action, bool select);
+
+ enum KeyboardAction {
+ ActionBackspace,
+ ActionDelete,
+ ActionReturn,
+ ActionKill,
+ ActionWordBackspace,
+ ActionWordDelete
+ };
+
+ QT3_SUPPORT void doKeyboardAction(KeyboardAction action);
+
+ QT3_SUPPORT QString text() const;
+ QT3_SUPPORT void setTextFormat(Qt::TextFormat);
+ QT3_SUPPORT Qt::TextFormat textFormat() const;
+
+ inline QT3_SUPPORT void setBold(bool b) { setFontWeight(b ? QFont::Bold : QFont::Normal); }
+ inline QT3_SUPPORT void setUnderline(bool b) { setFontUnderline(b); }
+ inline QT3_SUPPORT void setItalic(bool i) { setFontItalic(i); }
+ inline QT3_SUPPORT void setFamily(const QString &family) { setFontFamily(family); }
+ inline QT3_SUPPORT void setPointSize(int size) { setFontPointSize(size); }
+
+ inline QT3_SUPPORT bool italic() const { return fontItalic(); }
+ inline QT3_SUPPORT bool bold() const { return fontWeight() >= QFont::Bold; }
+ inline QT3_SUPPORT bool underline() const { return fontUnderline(); }
+ inline QT3_SUPPORT QString family() const { return fontFamily(); }
+ inline QT3_SUPPORT int pointSize() const { return (int)(fontPointSize()+0.5); }
+
+ inline QT3_SUPPORT bool hasSelectedText() const
+ { return textCursor().hasSelection(); }
+ inline QT3_SUPPORT QString selectedText() const
+ { return textCursor().selectedText(); }
+
+ inline QT3_SUPPORT bool isUndoAvailable() const
+ { return document()->isUndoAvailable(); }
+ inline QT3_SUPPORT bool isRedoAvailable() const
+ { return document()->isRedoAvailable(); }
+
+ inline QT3_SUPPORT void insert(const QString &text)
+ { insertPlainText(text); }
+
+ inline QT3_SUPPORT bool isModified() const
+ { return document()->isModified(); }
+
+ inline QT3_SUPPORT QColor color() const
+ { return textColor(); }
+
+public Q_SLOTS:
+ inline QT_MOC_COMPAT void setModified(bool m = true)
+ { document()->setModified(m); }
+public:
+ inline QT3_SUPPORT void undo() const
+ { document()->undo(); }
+ inline QT3_SUPPORT void redo() const
+ { document()->redo(); }
+
+public Q_SLOTS:
+ inline QT_MOC_COMPAT void setColor(const QColor &c)
+ { setTextColor(c); }
+
+#endif
+
+private:
+ Q_DISABLE_COPY(QTextEdit)
+ Q_PRIVATE_SLOT(d_func(), void _q_repaintContents(const QRectF &r))
+ Q_PRIVATE_SLOT(d_func(), void _q_currentCharFormatChanged(const QTextCharFormat &))
+ Q_PRIVATE_SLOT(d_func(), void _q_adjustScrollbars())
+ Q_PRIVATE_SLOT(d_func(), void _q_ensureVisible(const QRectF &))
+ friend class QTextEditControl;
+ friend class QTextDocument;
+ friend class QWidgetTextControl;
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QTextEdit::AutoFormatting)
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QT_NO_TEXTEDIT
+
+#endif // QTEXTEDIT_H
diff --git a/src/widgets/widgets/qtextedit_p.h b/src/widgets/widgets/qtextedit_p.h
new file mode 100644
index 0000000000..3512c80ac4
--- /dev/null
+++ b/src/widgets/widgets/qtextedit_p.h
@@ -0,0 +1,141 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTEXTEDIT_P_H
+#define QTEXTEDIT_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "private/qabstractscrollarea_p.h"
+#include "QtGui/qtextdocumentfragment.h"
+#include "QtWidgets/qscrollbar.h"
+#include "QtGui/qtextcursor.h"
+#include "QtGui/qtextformat.h"
+#include "QtWidgets/qmenu.h"
+#include "QtGui/qabstracttextdocumentlayout.h"
+#include "QtCore/qbasictimer.h"
+#include "QtCore/qurl.h"
+#include "private/qwidgettextcontrol_p.h"
+#include "qtextedit.h"
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_TEXTEDIT
+
+class QMimeData;
+class QTextEditPrivate : public QAbstractScrollAreaPrivate
+{
+ Q_DECLARE_PUBLIC(QTextEdit)
+public:
+ QTextEditPrivate();
+
+ void init(const QString &html = QString());
+ void paint(QPainter *p, QPaintEvent *e);
+ void _q_repaintContents(const QRectF &contentsRect);
+
+ inline QPoint mapToContents(const QPoint &point) const
+ { return QPoint(point.x() + horizontalOffset(), point.y() + verticalOffset()); }
+
+ void _q_adjustScrollbars();
+ void _q_ensureVisible(const QRectF &rect);
+ void relayoutDocument();
+
+ void createAutoBulletList();
+ void pageUpDown(QTextCursor::MoveOperation op, QTextCursor::MoveMode moveMode);
+
+ inline int horizontalOffset() const
+ { return q_func()->isRightToLeft() ? (hbar->maximum() - hbar->value()) : hbar->value(); }
+ inline int verticalOffset() const
+ { return vbar->value(); }
+
+ inline void sendControlEvent(QEvent *e)
+ { control->processEvent(e, QPointF(horizontalOffset(), verticalOffset()), viewport); }
+
+ void _q_currentCharFormatChanged(const QTextCharFormat &format);
+
+ void updateDefaultTextOption();
+
+ // re-implemented by QTextBrowser, called by QTextDocument::loadResource
+ virtual QUrl resolveUrl(const QUrl &url) const
+ { return url; }
+
+ QWidgetTextControl *control;
+
+ QTextEdit::AutoFormatting autoFormatting;
+ bool tabChangesFocus;
+
+ QBasicTimer autoScrollTimer;
+ QPoint autoScrollDragPos;
+
+ QTextEdit::LineWrapMode lineWrap;
+ int lineWrapColumnOrWidth;
+ QTextOption::WrapMode wordWrap;
+
+ uint ignoreAutomaticScrollbarAdjustment : 1;
+ uint preferRichText : 1;
+ uint showCursorOnInitialShow : 1;
+ uint inDrag : 1;
+ uint clickCausedFocus : 1;
+
+ // Qt3 COMPAT only, for setText
+ Qt::TextFormat textFormat;
+
+ QString anchorToScrollToWhenVisible;
+
+#ifdef QT_KEYPAD_NAVIGATION
+ QBasicTimer deleteAllTimer;
+#endif
+};
+#endif // QT_NO_TEXTEDIT
+
+
+QT_END_NAMESPACE
+
+#endif // QTEXTEDIT_P_H
diff --git a/src/widgets/widgets/qtoolbar.cpp b/src/widgets/widgets/qtoolbar.cpp
new file mode 100644
index 0000000000..7527baa518
--- /dev/null
+++ b/src/widgets/widgets/qtoolbar.cpp
@@ -0,0 +1,1349 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtoolbar.h"
+
+#ifndef QT_NO_TOOLBAR
+
+#include <qapplication.h>
+#include <qcombobox.h>
+#include <qevent.h>
+#include <qlayout.h>
+#include <qmainwindow.h>
+#include <qmenu.h>
+#include <qmenubar.h>
+#include <qrubberband.h>
+#include <qsignalmapper.h>
+#include <qstylepainter.h>
+#include <qtoolbutton.h>
+#include <qwidgetaction.h>
+#include <qtimer.h>
+#include <private/qwidgetaction_p.h>
+#ifdef Q_WS_MAC
+#include <private/qt_mac_p.h>
+#include <private/qt_cocoa_helpers_mac_p.h>
+#endif
+
+#include <private/qmainwindowlayout_p.h>
+
+#include "qtoolbar_p.h"
+#include "qtoolbarseparator_p.h"
+#include "qtoolbarlayout_p.h"
+
+#include "qdebug.h"
+
+#define POPUP_TIMER_INTERVAL 500
+
+QT_BEGIN_NAMESPACE
+
+#ifdef Q_WS_MAC
+static void qt_mac_updateToolBarButtonHint(QWidget *parentWidget)
+{
+ if (!(parentWidget->windowFlags() & Qt::CustomizeWindowHint))
+ parentWidget->setWindowFlags(parentWidget->windowFlags() | Qt::MacWindowToolBarButtonHint);
+}
+#endif
+
+// qmainwindow.cpp
+extern QMainWindowLayout *qt_mainwindow_layout(const QMainWindow *window);
+
+/******************************************************************************
+** QToolBarPrivate
+*/
+
+void QToolBarPrivate::init()
+{
+ Q_Q(QToolBar);
+ q->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed));
+ q->setBackgroundRole(QPalette::Button);
+ q->setAttribute(Qt::WA_Hover);
+ q->setAttribute(Qt::WA_X11NetWmWindowTypeToolBar);
+
+ QStyle *style = q->style();
+ int e = style->pixelMetric(QStyle::PM_ToolBarIconSize, 0, q);
+ iconSize = QSize(e, e);
+
+ layout = new QToolBarLayout(q);
+ layout->updateMarginAndSpacing();
+
+#ifdef Q_WS_MAC
+ if (q->parentWidget() && q->parentWidget()->isWindow()) {
+ // Make sure that the window has the "toolbar" button.
+ QWidget *parentWidget = q->parentWidget();
+ qt_mac_updateToolBarButtonHint(parentWidget);
+ reinterpret_cast<QToolBar *>(parentWidget)->d_func()->createWinId(); // Please let me create your winId...
+ extern OSWindowRef qt_mac_window_for(const QWidget *); // qwidget_mac.cpp
+ macWindowToolbarShow(q->parentWidget(), true);
+ }
+#endif
+
+ toggleViewAction = new QAction(q);
+ toggleViewAction->setCheckable(true);
+ q->setMovable(q->style()->styleHint(QStyle::SH_ToolBar_Movable, 0, q ));
+ QObject::connect(toggleViewAction, SIGNAL(triggered(bool)), q, SLOT(_q_toggleView(bool)));
+}
+
+void QToolBarPrivate::_q_toggleView(bool b)
+{
+ Q_Q(QToolBar);
+ if (b == q->isHidden()) {
+ if (b)
+ q->show();
+ else
+ q->close();
+ }
+}
+
+void QToolBarPrivate::_q_updateIconSize(const QSize &sz)
+{
+ Q_Q(QToolBar);
+ if (!explicitIconSize) {
+ // iconSize not explicitly set
+ q->setIconSize(sz);
+ explicitIconSize = false;
+ }
+}
+
+void QToolBarPrivate::_q_updateToolButtonStyle(Qt::ToolButtonStyle style)
+{
+ Q_Q(QToolBar);
+ if (!explicitToolButtonStyle) {
+ q->setToolButtonStyle(style);
+ explicitToolButtonStyle = false;
+ }
+}
+
+void QToolBarPrivate::updateWindowFlags(bool floating, bool unplug)
+{
+ Q_Q(QToolBar);
+ Qt::WindowFlags flags = floating ? Qt::Tool : Qt::Widget;
+
+ flags |= Qt::FramelessWindowHint;
+
+ if (unplug) {
+ flags |= Qt::X11BypassWindowManagerHint;
+#ifdef Q_WS_MAC
+ flags |= Qt::WindowStaysOnTopHint;
+#endif
+ }
+
+ q->setWindowFlags(flags);
+}
+
+void QToolBarPrivate::setWindowState(bool floating, bool unplug, const QRect &rect)
+{
+ Q_Q(QToolBar);
+ bool visible = !q->isHidden();
+ bool wasFloating = q->isFloating(); // ...is also currently using popup menus
+
+ q->hide();
+
+ updateWindowFlags(floating, unplug);
+
+ if (floating != wasFloating)
+ layout->checkUsePopupMenu();
+
+ if (!rect.isNull())
+ q->setGeometry(rect);
+
+ if (visible)
+ q->show();
+
+ if (floating != wasFloating)
+ emit q->topLevelChanged(floating);
+}
+
+void QToolBarPrivate::initDrag(const QPoint &pos)
+{
+ Q_Q(QToolBar);
+
+ if (state != 0)
+ return;
+
+ QMainWindow *win = qobject_cast<QMainWindow*>(parent);
+ Q_ASSERT(win != 0);
+ QMainWindowLayout *layout = qt_mainwindow_layout(win);
+ Q_ASSERT(layout != 0);
+ if (layout->pluggingWidget != 0) // the main window is animating a docking operation
+ return;
+
+ state = new DragState;
+ state->pressPos = pos;
+ state->dragging = false;
+ state->moving = false;
+ state->widgetItem = 0;
+
+ if (q->isRightToLeft())
+ state->pressPos = QPoint(q->width() - state->pressPos.x(), state->pressPos.y());
+}
+
+void QToolBarPrivate::startDrag(bool moving)
+{
+ Q_Q(QToolBar);
+
+ Q_ASSERT(state != 0);
+
+ if ((moving && state->moving) || state->dragging)
+ return;
+
+ QMainWindow *win = qobject_cast<QMainWindow*>(parent);
+ Q_ASSERT(win != 0);
+ QMainWindowLayout *layout = qt_mainwindow_layout(win);
+ Q_ASSERT(layout != 0);
+
+ if (!moving) {
+ state->widgetItem = layout->unplug(q);
+#if defined(Q_WS_MAC) && !defined(QT_MAC_USE_COCOA)
+ if (q->isWindow()) {
+ setWindowState(true, true); //set it to floating
+ }
+#endif
+ Q_ASSERT(state->widgetItem != 0);
+ }
+ state->dragging = !moving;
+ state->moving = moving;
+}
+
+void QToolBarPrivate::endDrag()
+{
+ Q_Q(QToolBar);
+ Q_ASSERT(state != 0);
+
+ q->releaseMouse();
+
+ if (state->dragging) {
+ QMainWindowLayout *layout = qt_mainwindow_layout(qobject_cast<QMainWindow *>(q->parentWidget()));
+ Q_ASSERT(layout != 0);
+
+ if (!layout->plug(state->widgetItem)) {
+ if (q->isFloatable()) {
+ layout->restore();
+#if defined(Q_WS_X11) || defined(Q_WS_MAC)
+ setWindowState(true); // gets rid of the X11BypassWindowManager window flag
+ // and activates the resizer
+#endif
+ q->activateWindow();
+ } else {
+ layout->revert(state->widgetItem);
+ }
+ }
+ }
+
+ delete state;
+ state = 0;
+}
+
+bool QToolBarPrivate::mousePressEvent(QMouseEvent *event)
+{
+ Q_Q(QToolBar);
+ QStyleOptionToolBar opt;
+ q->initStyleOption(&opt);
+ if (q->style()->subElementRect(QStyle::SE_ToolBarHandle, &opt, q).contains(event->pos()) == false) {
+#ifdef Q_WS_MAC
+ // When using the unified toolbar on Mac OS X the user can can click and
+ // drag between toolbar contents to move the window. Make this work by
+ // implementing the standard mouse-dragging code and then call
+ // window->move() in mouseMoveEvent below.
+ if (QMainWindow *mainWindow = qobject_cast<QMainWindow *>(parent)) {
+ if (mainWindow->toolBarArea(q) == Qt::TopToolBarArea
+ && mainWindow->unifiedTitleAndToolBarOnMac()
+ && q->childAt(event->pos()) == 0) {
+ macWindowDragging = true;
+ macWindowDragPressPosition = event->pos();
+ return true;
+ }
+ }
+#endif
+ return false;
+ }
+
+ if (event->button() != Qt::LeftButton)
+ return true;
+
+ if (!layout->movable())
+ return true;
+
+ initDrag(event->pos());
+ return true;
+}
+
+bool QToolBarPrivate::mouseReleaseEvent(QMouseEvent*)
+{
+ if (state != 0) {
+ endDrag();
+ return true;
+ } else {
+#ifdef Q_WS_MAC
+ if (!macWindowDragging)
+ return false;
+ macWindowDragging = false;
+ macWindowDragPressPosition = QPoint();
+ return true;
+#endif
+ return false;
+ }
+}
+
+bool QToolBarPrivate::mouseMoveEvent(QMouseEvent *event)
+{
+ Q_Q(QToolBar);
+
+ if (!state) {
+#ifdef Q_WS_MAC
+ if (!macWindowDragging)
+ return false;
+ QWidget *w = q->window();
+ const QPoint delta = event->pos() - macWindowDragPressPosition;
+ w->move(w->pos() + delta);
+ return true;
+#endif
+ return false;
+ }
+
+ QMainWindow *win = qobject_cast<QMainWindow*>(parent);
+ if (win == 0)
+ return true;
+
+ QMainWindowLayout *layout = qt_mainwindow_layout(win);
+ Q_ASSERT(layout != 0);
+
+ if (layout->pluggingWidget == 0
+ && (event->pos() - state->pressPos).manhattanLength() > QApplication::startDragDistance()) {
+ const bool wasDragging = state->dragging;
+ const bool moving = !q->isWindow() && (orientation == Qt::Vertical ?
+ event->x() >= 0 && event->x() < q->width() :
+ event->y() >= 0 && event->y() < q->height());
+
+ startDrag(moving);
+ if (!moving && !wasDragging) {
+#ifdef Q_WS_WIN
+ grabMouseWhileInWindow();
+#else
+ q->grabMouse();
+#endif
+ }
+ }
+
+ if (state->dragging) {
+ QPoint pos = event->globalPos();
+ // if we are right-to-left, we move so as to keep the right edge the same distance
+ // from the mouse
+ if (q->isLeftToRight())
+ pos -= state->pressPos;
+ else
+ pos += QPoint(state->pressPos.x() - q->width(), -state->pressPos.y());
+
+ q->move(pos);
+ layout->hover(state->widgetItem, event->globalPos());
+ } else if (state->moving) {
+
+ const QPoint rtl(q->width() - state->pressPos.x(), state->pressPos.y()); //for RTL
+ const QPoint globalPressPos = q->mapToGlobal(q->isRightToLeft() ? rtl : state->pressPos);
+ int pos = 0;
+
+ QPoint delta = event->globalPos() - globalPressPos;
+ if (orientation == Qt::Vertical) {
+ pos = q->y() + delta.y();
+ } else {
+ if (q->isRightToLeft()) {
+ pos = win->width() - q->width() - q->x() - delta.x();
+ } else {
+ pos = q->x() + delta.x();
+ }
+ }
+
+ layout->moveToolBar(q, pos);
+ }
+ return true;
+}
+
+void QToolBarPrivate::unplug(const QRect &_r)
+{
+ Q_Q(QToolBar);
+ QRect r = _r;
+ r.moveTopLeft(q->mapToGlobal(QPoint(0, 0)));
+ setWindowState(true, true, r);
+ layout->setExpanded(false);
+}
+
+void QToolBarPrivate::plug(const QRect &r)
+{
+ setWindowState(false, false, r);
+}
+
+/******************************************************************************
+** QToolBar
+*/
+
+/*!
+ \class QToolBar
+
+ \brief The QToolBar class provides a movable panel that contains a
+ set of controls.
+
+ \ingroup mainwindow-classes
+
+
+ Toolbar buttons are added by adding \e actions, using addAction()
+ or insertAction(). Groups of buttons can be separated using
+ addSeparator() or insertSeparator(). If a toolbar button is not
+ appropriate, a widget can be inserted instead using addWidget() or
+ insertWidget(); examples of suitable widgets are QSpinBox,
+ QDoubleSpinBox, and QComboBox. When a toolbar button is pressed it
+ emits the actionTriggered() signal.
+
+ A toolbar can be fixed in place in a particular area (e.g. at the
+ top of the window), or it can be movable (isMovable()) between
+ toolbar areas; see allowedAreas() and isAreaAllowed().
+
+ When a toolbar is resized in such a way that it is too small to
+ show all the items it contains, an extension button will appear as
+ the last item in the toolbar. Pressing the extension button will
+ pop up a menu containing the items that does not currently fit in
+ the toolbar.
+
+ When a QToolBar is not a child of a QMainWindow, it looses the ability
+ to populate the extension pop up with widgets added to the toolbar using
+ addWidget(). Please use widget actions created by inheriting QWidgetAction
+ and implementing QWidgetAction::createWidget() instead.
+
+ \sa QToolButton, QMenu, QAction, {Application Example}
+*/
+
+/*!
+ \fn bool QToolBar::isAreaAllowed(Qt::ToolBarArea area) const
+
+ Returns true if this toolbar is dockable in the given \a area;
+ otherwise returns false.
+*/
+
+/*!
+ \fn void QToolBar::addAction(QAction *action)
+ \overload
+
+ Appends the action \a action to the toolbar's list of actions.
+
+ \sa QMenu::addAction(), QWidget::addAction()
+*/
+
+/*!
+ \fn void QToolBar::actionTriggered(QAction *action)
+
+ This signal is emitted when an action in this toolbar is triggered.
+ This happens when the action's tool button is pressed, or when the
+ action is triggered in some other way outside the tool bar. The parameter
+ holds the triggered \a action.
+*/
+
+/*!
+ \fn void QToolBar::allowedAreasChanged(Qt::ToolBarAreas allowedAreas)
+
+ This signal is emitted when the collection of allowed areas for the
+ toolbar is changed. The new areas in which the toolbar can be positioned
+ are specified by \a allowedAreas.
+
+ \sa allowedAreas
+*/
+
+/*!
+ \fn void QToolBar::iconSizeChanged(const QSize &iconSize)
+
+ This signal is emitted when the icon size is changed. The \a
+ iconSize parameter holds the toolbar's new icon size.
+
+ \sa iconSize QMainWindow::iconSize
+*/
+
+/*!
+ \fn void QToolBar::movableChanged(bool movable)
+
+ This signal is emitted when the toolbar becomes movable or fixed.
+ If the toolbar can be moved, \a movable is true; otherwise it is
+ false.
+
+ \sa movable
+*/
+
+/*!
+ \fn void QToolBar::orientationChanged(Qt::Orientation orientation)
+
+ This signal is emitted when the orientation of the toolbar changes.
+ The new orientation is specified by the \a orientation given.
+
+ \sa orientation
+*/
+
+/*!
+ \fn void QToolBar::toolButtonStyleChanged(Qt::ToolButtonStyle toolButtonStyle)
+
+ This signal is emitted when the tool button style is changed. The
+ \a toolButtonStyle parameter holds the toolbar's new tool button
+ style.
+
+ \sa toolButtonStyle QMainWindow::toolButtonStyle
+*/
+
+/*!
+ \since 4.6
+
+ \fn void QToolBar::topLevelChanged(bool topLevel)
+
+ This signal is emitted when the \l floating property changes.
+ The \a topLevel parameter is true if the toolbar is now floating;
+ otherwise it is false.
+
+ \sa isWindow()
+*/
+
+
+/*!
+ \fn void QToolBar::visibilityChanged(bool visible)
+ \since 4.7
+
+ This signal is emitted when the toolbar becomes \a visible (or
+ invisible). This happens when the widget is hidden or shown.
+*/
+
+/*!
+ Constructs a QToolBar with the given \a parent.
+*/
+QToolBar::QToolBar(QWidget *parent)
+ : QWidget(*new QToolBarPrivate, parent, 0)
+{
+ Q_D(QToolBar);
+ d->init();
+}
+
+/*!
+ Constructs a QToolBar with the given \a parent.
+
+ The given window \a title identifies the toolbar and is shown in
+ the context menu provided by QMainWindow.
+
+ \sa setWindowTitle()
+*/
+QToolBar::QToolBar(const QString &title, QWidget *parent)
+ : QWidget(*new QToolBarPrivate, parent, 0)
+{
+ Q_D(QToolBar);
+ d->init();
+ setWindowTitle(title);
+}
+
+#ifdef QT3_SUPPORT
+/*! \obsolete
+ Constructs a QToolBar with the given \a parent and \a name.
+*/
+QToolBar::QToolBar(QWidget *parent, const char *name)
+ : QWidget(*new QToolBarPrivate, parent, 0)
+{
+ Q_D(QToolBar);
+ d->init();
+ setObjectName(QString::fromAscii(name));
+}
+#endif
+
+/*!
+ Destroys the toolbar.
+*/
+QToolBar::~QToolBar()
+{
+ // Remove the toolbar button if there is nothing left.
+ QMainWindow *mainwindow = qobject_cast<QMainWindow *>(parentWidget());
+ if (mainwindow) {
+#ifdef Q_WS_MAC
+ QMainWindowLayout *mainwin_layout = qt_mainwindow_layout(mainwindow);
+ if (mainwin_layout && mainwin_layout->layoutState.toolBarAreaLayout.isEmpty()
+ && mainwindow->testAttribute(Qt::WA_WState_Created))
+ macWindowToolbarShow(mainwindow, false);
+#endif
+ }
+}
+
+/*! \property QToolBar::movable
+ \brief whether the user can move the toolbar within the toolbar area,
+ or between toolbar areas
+
+ By default, this property is true.
+
+ This property only makes sense if the toolbar is in a
+ QMainWindow.
+
+ \sa allowedAreas
+*/
+
+void QToolBar::setMovable(bool movable)
+{
+ Q_D(QToolBar);
+ if (!movable == !d->movable)
+ return;
+ d->movable = movable;
+ d->layout->invalidate();
+ emit movableChanged(d->movable);
+}
+
+bool QToolBar::isMovable() const
+{
+ Q_D(const QToolBar);
+ return d->movable;
+}
+
+/*!
+ \property QToolBar::floatable
+ \brief whether the toolbar can be dragged and dropped as an independent window.
+
+ The default is true.
+*/
+bool QToolBar::isFloatable() const
+{
+ Q_D(const QToolBar);
+ return d->floatable;
+}
+
+void QToolBar::setFloatable(bool floatable)
+{
+ Q_D(QToolBar);
+ d->floatable = floatable;
+}
+
+/*!
+ \property QToolBar::floating
+ \brief whether the toolbar is an independent window.
+
+ By default, this property is true.
+
+ \sa QWidget::isWindow()
+*/
+bool QToolBar::isFloating() const
+{
+ return isWindow();
+}
+
+/*!
+ \property QToolBar::allowedAreas
+ \brief areas where the toolbar may be placed
+
+ The default is Qt::AllToolBarAreas.
+
+ This property only makes sense if the toolbar is in a
+ QMainWindow.
+
+ \sa movable
+*/
+
+void QToolBar::setAllowedAreas(Qt::ToolBarAreas areas)
+{
+ Q_D(QToolBar);
+ areas &= Qt::ToolBarArea_Mask;
+ if (areas == d->allowedAreas)
+ return;
+ d->allowedAreas = areas;
+ emit allowedAreasChanged(d->allowedAreas);
+}
+
+Qt::ToolBarAreas QToolBar::allowedAreas() const
+{
+ Q_D(const QToolBar);
+#ifdef Q_WS_MAC
+ if (QMainWindow *window = qobject_cast<QMainWindow *>(parentWidget())) {
+ if (window->unifiedTitleAndToolBarOnMac()) // Don't allow drags to the top (for now).
+ return (d->allowedAreas & ~Qt::TopToolBarArea);
+ }
+#endif
+ return d->allowedAreas;
+}
+
+/*! \property QToolBar::orientation
+ \brief orientation of the toolbar
+
+ The default is Qt::Horizontal.
+
+ This function should not be used when the toolbar is managed
+ by QMainWindow. You can use QMainWindow::addToolBar() or
+ QMainWindow::insertToolBar() if you wish to move a toolbar (that
+ is already added to a main window) to another Qt::ToolBarArea.
+*/
+
+void QToolBar::setOrientation(Qt::Orientation orientation)
+{
+ Q_D(QToolBar);
+ if (orientation == d->orientation)
+ return;
+
+ d->orientation = orientation;
+
+ if (orientation == Qt::Vertical)
+ setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred));
+ else
+ setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed));
+
+ d->layout->invalidate();
+ d->layout->activate();
+
+ emit orientationChanged(d->orientation);
+}
+
+Qt::Orientation QToolBar::orientation() const
+{ Q_D(const QToolBar); return d->orientation; }
+
+/*!
+ \property QToolBar::iconSize
+ \brief size of icons in the toolbar.
+
+ The default size is determined by the application's style and is
+ derived from the QStyle::PM_ToolBarIconSize pixel metric. It is
+ the maximum size an icon can have. Icons of smaller size will not
+ be scaled up.
+*/
+
+QSize QToolBar::iconSize() const
+{ Q_D(const QToolBar); return d->iconSize; }
+
+void QToolBar::setIconSize(const QSize &iconSize)
+{
+ Q_D(QToolBar);
+ QSize sz = iconSize;
+ if (!sz.isValid()) {
+ QMainWindow *mw = qobject_cast<QMainWindow *>(parentWidget());
+ if (mw && mw->layout()) {
+ QLayout *layout = mw->layout();
+ int i = 0;
+ QLayoutItem *item = 0;
+ do {
+ item = layout->itemAt(i++);
+ if (item && (item->widget() == this))
+ sz = mw->iconSize();
+ } while (!sz.isValid() && item != 0);
+ }
+ }
+ if (!sz.isValid()) {
+ const int metric = style()->pixelMetric(QStyle::PM_ToolBarIconSize, 0, this);
+ sz = QSize(metric, metric);
+ }
+ if (d->iconSize != sz) {
+ d->iconSize = sz;
+ setMinimumSize(0, 0);
+ emit iconSizeChanged(d->iconSize);
+ }
+ d->explicitIconSize = iconSize.isValid();
+
+ d->layout->invalidate();
+}
+
+/*!
+ \property QToolBar::toolButtonStyle
+ \brief the style of toolbar buttons
+
+ This property defines the style of all tool buttons that are added
+ as \l{QAction}s. Note that if you add a QToolButton with the
+ addWidget() method, it will not get this button style.
+
+ The default is Qt::ToolButtonIconOnly.
+*/
+
+Qt::ToolButtonStyle QToolBar::toolButtonStyle() const
+{ Q_D(const QToolBar); return d->toolButtonStyle; }
+
+void QToolBar::setToolButtonStyle(Qt::ToolButtonStyle toolButtonStyle)
+{
+ Q_D(QToolBar);
+ d->explicitToolButtonStyle = true;
+ if (d->toolButtonStyle == toolButtonStyle)
+ return;
+ d->toolButtonStyle = toolButtonStyle;
+ setMinimumSize(0, 0);
+ emit toolButtonStyleChanged(d->toolButtonStyle);
+}
+
+/*!
+ Removes all actions from the toolbar.
+
+ \sa removeAction()
+*/
+void QToolBar::clear()
+{
+ QList<QAction *> actions = this->actions();
+ for(int i = 0; i < actions.size(); i++)
+ removeAction(actions.at(i));
+}
+
+/*!
+ \overload
+
+ Creates a new action with the given \a text. This action is added to
+ the end of the toolbar.
+*/
+QAction *QToolBar::addAction(const QString &text)
+{
+ QAction *action = new QAction(text, this);
+ addAction(action);
+ return action;
+}
+
+/*!
+ \overload
+
+ Creates a new action with the given \a icon and \a text. This
+ action is added to the end of the toolbar.
+*/
+QAction *QToolBar::addAction(const QIcon &icon, const QString &text)
+{
+ QAction *action = new QAction(icon, text, this);
+ addAction(action);
+ return action;
+}
+
+/*!
+ \overload
+
+ Creates a new action with the given \a text. This action is added to
+ the end of the toolbar. The action's \link QAction::triggered()
+ triggered()\endlink signal is connected to \a member in \a
+ receiver.
+*/
+QAction *QToolBar::addAction(const QString &text,
+ const QObject *receiver, const char* member)
+{
+ QAction *action = new QAction(text, this);
+ QObject::connect(action, SIGNAL(triggered(bool)), receiver, member);
+ addAction(action);
+ return action;
+}
+
+/*!
+ \overload
+
+ Creates a new action with the icon \a icon and text \a text. This
+ action is added to the end of the toolbar. The action's \link
+ QAction::triggered() triggered()\endlink signal is connected to \a
+ member in \a receiver.
+*/
+QAction *QToolBar::addAction(const QIcon &icon, const QString &text,
+ const QObject *receiver, const char* member)
+{
+ QAction *action = new QAction(icon, text, this);
+ QObject::connect(action, SIGNAL(triggered(bool)), receiver, member);
+ addAction(action);
+ return action;
+}
+
+/*!
+ Adds a separator to the end of the toolbar.
+
+ \sa insertSeparator()
+*/
+QAction *QToolBar::addSeparator()
+{
+ QAction *action = new QAction(this);
+ action->setSeparator(true);
+ addAction(action);
+ return action;
+}
+
+/*!
+ Inserts a separator into the toolbar in front of the toolbar
+ item associated with the \a before action.
+
+ \sa addSeparator()
+*/
+QAction *QToolBar::insertSeparator(QAction *before)
+{
+ QAction *action = new QAction(this);
+ action->setSeparator(true);
+ insertAction(before, action);
+ return action;
+}
+
+/*!
+ Adds the given \a widget to the toolbar as the toolbar's last
+ item.
+
+ The toolbar takes ownership of \a widget.
+
+ If you add a QToolButton with this method, the tools bar's
+ Qt::ToolButtonStyle will not be respected.
+
+ \note You should use QAction::setVisible() to change the
+ visibility of the widget. Using QWidget::setVisible(),
+ QWidget::show() and QWidget::hide() does not work.
+
+ \sa insertWidget()
+*/
+QAction *QToolBar::addWidget(QWidget *widget)
+{
+ QWidgetAction *action = new QWidgetAction(this);
+ action->setDefaultWidget(widget);
+ action->d_func()->autoCreated = true;
+ addAction(action);
+ return action;
+}
+
+/*!
+ Inserts the given \a widget in front of the toolbar item
+ associated with the \a before action.
+
+ Note: You should use QAction::setVisible() to change the
+ visibility of the widget. Using QWidget::setVisible(),
+ QWidget::show() and QWidget::hide() does not work.
+
+ \sa addWidget()
+*/
+QAction *QToolBar::insertWidget(QAction *before, QWidget *widget)
+{
+ QWidgetAction *action = new QWidgetAction(this);
+ action->setDefaultWidget(widget);
+ action->d_func()->autoCreated = true;
+ insertAction(before, action);
+ return action;
+}
+
+/*!
+ \internal
+
+ Returns the geometry of the toolbar item associated with the given
+ \a action, or an invalid QRect if no matching item is found.
+*/
+QRect QToolBar::actionGeometry(QAction *action) const
+{
+ Q_D(const QToolBar);
+
+ int index = d->layout->indexOf(action);
+ if (index == -1)
+ return QRect();
+ return d->layout->itemAt(index)->widget()->geometry();
+}
+
+/*!
+ Returns the action at point \a p. This function returns zero if no
+ action was found.
+
+ \sa QWidget::childAt()
+*/
+QAction *QToolBar::actionAt(const QPoint &p) const
+{
+ Q_D(const QToolBar);
+ QWidget *widget = childAt(p);
+ int index = d->layout->indexOf(widget);
+ if (index == -1)
+ return 0;
+ QLayoutItem *item = d->layout->itemAt(index);
+ return static_cast<QToolBarItem*>(item)->action;
+}
+
+/*! \fn QAction *QToolBar::actionAt(int x, int y) const
+ \overload
+
+ Returns the action at the point \a x, \a y. This function returns
+ zero if no action was found.
+*/
+
+/*! \reimp */
+void QToolBar::actionEvent(QActionEvent *event)
+{
+ Q_D(QToolBar);
+ QAction *action = event->action();
+ QWidgetAction *widgetAction = qobject_cast<QWidgetAction *>(action);
+
+ switch (event->type()) {
+ case QEvent::ActionAdded: {
+ Q_ASSERT_X(widgetAction == 0 || d->layout->indexOf(widgetAction) == -1,
+ "QToolBar", "widgets cannot be inserted multiple times");
+
+ // reparent the action to this toolbar if it has been created
+ // using the addAction(text) etc. convenience functions, to
+ // preserve Qt 4.1.x behavior. The widget is already
+ // reparented to us due to the createWidget call inside
+ // createItem()
+ if (widgetAction != 0 && widgetAction->d_func()->autoCreated)
+ widgetAction->setParent(this);
+
+ int index = d->layout->count();
+ if (event->before()) {
+ index = d->layout->indexOf(event->before());
+ Q_ASSERT_X(index != -1, "QToolBar::insertAction", "internal error");
+ }
+ d->layout->insertAction(index, action);
+ break;
+ }
+
+ case QEvent::ActionChanged:
+ d->layout->invalidate();
+ break;
+
+ case QEvent::ActionRemoved: {
+ int index = d->layout->indexOf(action);
+ if (index != -1) {
+ delete d->layout->takeAt(index);
+ }
+ break;
+ }
+
+ default:
+ Q_ASSERT_X(false, "QToolBar::actionEvent", "internal error");
+ }
+}
+
+/*! \reimp */
+void QToolBar::changeEvent(QEvent *event)
+{
+ Q_D(QToolBar);
+ switch (event->type()) {
+ case QEvent::WindowTitleChange:
+ d->toggleViewAction->setText(windowTitle());
+ break;
+ case QEvent::StyleChange:
+ d->layout->invalidate();
+ if (!d->explicitIconSize)
+ setIconSize(QSize());
+ d->layout->updateMarginAndSpacing();
+ break;
+ case QEvent::LayoutDirectionChange:
+ d->layout->invalidate();
+ break;
+ default:
+ break;
+ }
+ QWidget::changeEvent(event);
+}
+
+/*! \reimp */
+void QToolBar::paintEvent(QPaintEvent *)
+{
+ Q_D(QToolBar);
+
+ QPainter p(this);
+ QStyle *style = this->style();
+ QStyleOptionToolBar opt;
+ initStyleOption(&opt);
+
+ if (d->layout->expanded || d->layout->animating || isWindow()) {
+ //if the toolbar is expended, we need to fill the background with the window color
+ //because some styles may expects that.
+ p.fillRect(opt.rect, palette().background());
+ style->drawControl(QStyle::CE_ToolBar, &opt, &p, this);
+ style->drawPrimitive(QStyle::PE_FrameMenu, &opt, &p, this);
+ } else {
+ style->drawControl(QStyle::CE_ToolBar, &opt, &p, this);
+ }
+
+ opt.rect = style->subElementRect(QStyle::SE_ToolBarHandle, &opt, this);
+ if (opt.rect.isValid())
+ style->drawPrimitive(QStyle::PE_IndicatorToolBarHandle, &opt, &p, this);
+}
+
+/*
+ Checks if an expanded toolbar has to wait for this popup to close before
+ the toolbar collapses. This is true if
+ 1) the popup has the toolbar in its parent chain,
+ 2) the popup is a menu whose menuAction is somewhere in the toolbar.
+*/
+static bool waitForPopup(QToolBar *tb, QWidget *popup)
+{
+ if (popup == 0 || popup->isHidden())
+ return false;
+
+ QWidget *w = popup;
+ while (w != 0) {
+ if (w == tb)
+ return true;
+ w = w->parentWidget();
+ }
+
+ QMenu *menu = qobject_cast<QMenu*>(popup);
+ if (menu == 0)
+ return false;
+
+ QAction *action = menu->menuAction();
+ QList<QWidget*> widgets = action->associatedWidgets();
+ for (int i = 0; i < widgets.count(); ++i) {
+ if (waitForPopup(tb, widgets.at(i)))
+ return true;
+ }
+
+ return false;
+}
+
+#if defined(Q_WS_MAC)
+static bool toolbarInUnifiedToolBar(QToolBar *toolbar)
+{
+ const QMainWindow *mainWindow = qobject_cast<const QMainWindow *>(toolbar->parentWidget());
+ return mainWindow && mainWindow->unifiedTitleAndToolBarOnMac()
+ && mainWindow->toolBarArea(toolbar) == Qt::TopToolBarArea;
+}
+#endif
+
+/*! \reimp */
+bool QToolBar::event(QEvent *event)
+{
+ Q_D(QToolBar);
+
+ switch (event->type()) {
+ case QEvent::Timer:
+ if (d->waitForPopupTimer.timerId() == static_cast<QTimerEvent*>(event)->timerId()) {
+ QWidget *w = QApplication::activePopupWidget();
+ if (!waitForPopup(this, w)) {
+ d->waitForPopupTimer.stop();
+ if (!this->underMouse())
+ d->layout->setExpanded(false);
+ }
+ }
+ break;
+ case QEvent::Hide:
+ if (!isHidden())
+ break;
+ // fallthrough intended
+ case QEvent::Show:
+ d->toggleViewAction->setChecked(event->type() == QEvent::Show);
+ emit visibilityChanged(event->type() == QEvent::Show);
+#if defined(Q_WS_MAC)
+ if (toolbarInUnifiedToolBar(this)) {
+ // I can static_cast because I did the qobject_cast in the if above, therefore
+ // we must have a QMainWindowLayout here.
+ QMainWindowLayout *mwLayout = qt_mainwindow_layout(qobject_cast<QMainWindow *>(parentWidget()));
+ mwLayout->fixSizeInUnifiedToolbar(this);
+ mwLayout->syncUnifiedToolbarVisibility();
+ }
+# if !defined(QT_MAC_USE_COCOA)
+ // Fall through
+ case QEvent::LayoutRequest: {
+ // There's currently no way to invalidate the size and let
+ // HIToolbar know about it. This forces a re-check.
+ int earlyResult = -1;
+ if (QMainWindow *mainWindow = qobject_cast<QMainWindow *>(parentWidget())) {
+ bool needUpdate = true;
+ if (event->type() == QEvent::LayoutRequest) {
+ QSize oldSizeHint = sizeHint();
+ earlyResult = QWidget::event(event) ? 1 : 0;
+ needUpdate = oldSizeHint != sizeHint();
+ }
+
+ if (needUpdate) {
+ OSWindowRef windowRef = qt_mac_window_for(mainWindow);
+ if (toolbarInUnifiedToolBar(this)
+ && macWindowToolbarIsVisible(windowRef)) {
+ DisableScreenUpdates();
+ macWindowToolbarShow(this, false);
+ macWindowToolbarShow(this, true);
+ EnableScreenUpdates();
+ }
+ }
+
+ if (earlyResult != -1)
+ return earlyResult;
+ }
+ }
+# endif // !QT_MAC_USE_COCOA
+#endif // Q_WS_MAC
+ break;
+ case QEvent::ParentChange:
+ d->layout->checkUsePopupMenu();
+#if defined(Q_WS_MAC)
+ if (parentWidget() && parentWidget()->isWindow())
+ qt_mac_updateToolBarButtonHint(parentWidget());
+#endif
+ break;
+
+ case QEvent::MouseButtonPress: {
+ if (d->mousePressEvent(static_cast<QMouseEvent*>(event)))
+ return true;
+ break;
+ }
+ case QEvent::MouseButtonRelease:
+ if (d->mouseReleaseEvent(static_cast<QMouseEvent*>(event)))
+ return true;
+ break;
+ case QEvent::HoverEnter:
+ case QEvent::HoverLeave:
+ // there's nothing special to do here and we don't want to update the whole widget
+ return true;
+ case QEvent::HoverMove: {
+#ifndef QT_NO_CURSOR
+ QHoverEvent *e = static_cast<QHoverEvent*>(event);
+ QStyleOptionToolBar opt;
+ initStyleOption(&opt);
+ if (style()->subElementRect(QStyle::SE_ToolBarHandle, &opt, this).contains(e->pos()))
+ setCursor(Qt::SizeAllCursor);
+ else
+ unsetCursor();
+#endif
+ break;
+ }
+ case QEvent::MouseMove:
+ if (d->mouseMoveEvent(static_cast<QMouseEvent*>(event)))
+ return true;
+ break;
+#ifdef Q_WS_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
+ // This is a workaround for loosing the mouse on Vista.
+ QPoint pos = QCursor::pos();
+ QMouseEvent fake(QEvent::MouseMove, mapFromGlobal(pos), pos, Qt::NoButton,
+ QApplication::mouseButtons(), QApplication::keyboardModifiers());
+ d->mouseMoveEvent(&fake);
+#endif
+ } else {
+ if (!d->layout->expanded)
+ break;
+
+ QWidget *w = QApplication::activePopupWidget();
+ if (waitForPopup(this, w)) {
+ d->waitForPopupTimer.start(POPUP_TIMER_INTERVAL, this);
+ break;
+ }
+
+ d->waitForPopupTimer.stop();
+ d->layout->setExpanded(false);
+ break;
+ }
+ default:
+ break;
+ }
+ return QWidget::event(event);
+}
+
+/*!
+ Returns a checkable action that can be used to show or hide this
+ toolbar.
+
+ The action's text is set to the toolbar's window title.
+
+ \sa QAction::text QWidget::windowTitle
+*/
+QAction *QToolBar::toggleViewAction() const
+{ Q_D(const QToolBar); return d->toggleViewAction; }
+
+/*!
+ \fn void QToolBar::setLabel(const QString &label)
+
+ Use setWindowTitle() instead.
+*/
+
+/*!
+ \fn QString QToolBar::label() const
+
+ Use windowTitle() instead.
+*/
+
+/*!
+ \since 4.2
+
+ Returns the widget associated with the specified \a action.
+
+ \sa addWidget()
+*/
+QWidget *QToolBar::widgetForAction(QAction *action) const
+{
+ Q_D(const QToolBar);
+
+ int index = d->layout->indexOf(action);
+ if (index == -1)
+ return 0;
+
+ return d->layout->itemAt(index)->widget();
+}
+
+extern QMainWindowLayout *qt_mainwindow_layout(const QMainWindow *window);
+
+/*!
+ \internal
+*/
+void QToolBar::initStyleOption(QStyleOptionToolBar *option) const
+{
+ Q_D(const QToolBar);
+
+ if (!option)
+ return;
+
+ option->initFrom(this);
+ if (orientation() == Qt::Horizontal)
+ option->state |= QStyle::State_Horizontal;
+ option->lineWidth = style()->pixelMetric(QStyle::PM_ToolBarFrameWidth, 0, this);
+ option->features = d->layout->movable()
+ ? QStyleOptionToolBar::Movable
+ : QStyleOptionToolBar::None;
+ // if the tool bar is not in a QMainWindow, this will make the painting right
+ option->toolBarArea = Qt::NoToolBarArea;
+
+ // Add more styleoptions if the toolbar has been added to a mainwindow.
+ QMainWindow *mainWindow = qobject_cast<QMainWindow *>(parentWidget());
+
+ if (!mainWindow)
+ return;
+
+ QMainWindowLayout *layout = qt_mainwindow_layout(mainWindow);
+ Q_ASSERT_X(layout != 0, "QToolBar::initStyleOption()",
+ "QMainWindow->layout() != QMainWindowLayout");
+
+ layout->getStyleOptionInfo(option, const_cast<QToolBar *>(this));
+}
+
+/*!
+ \reimp
+*/
+void QToolBar::childEvent(QChildEvent *event) // ### remove me in 5.0
+{
+ QWidget::childEvent(event);
+}
+
+/*!
+ \reimp
+*/
+void QToolBar::resizeEvent(QResizeEvent *event) // ### remove me in 5.0
+{
+ QWidget::resizeEvent(event);
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qtoolbar.cpp"
+
+#endif // QT_NO_TOOLBAR
diff --git a/src/widgets/widgets/qtoolbar.h b/src/widgets/widgets/qtoolbar.h
new file mode 100644
index 0000000000..98c44f059a
--- /dev/null
+++ b/src/widgets/widgets/qtoolbar.h
@@ -0,0 +1,188 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDYNAMICTOOLBAR_H
+#define QDYNAMICTOOLBAR_H
+
+#include <QtWidgets/qwidget.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_TOOLBAR
+
+class QToolBarPrivate;
+
+class QAction;
+class QIcon;
+class QMainWindow;
+class QStyleOptionToolBar;
+
+class Q_WIDGETS_EXPORT QToolBar : public QWidget
+{
+ Q_OBJECT
+
+ Q_PROPERTY(bool movable READ isMovable WRITE setMovable
+ DESIGNABLE (qobject_cast<QMainWindow *>(parentWidget()) != 0)
+ NOTIFY movableChanged)
+ Q_PROPERTY(Qt::ToolBarAreas allowedAreas READ allowedAreas WRITE setAllowedAreas
+ DESIGNABLE (qobject_cast<QMainWindow *>(parentWidget()) != 0)
+ NOTIFY allowedAreasChanged)
+ Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation
+ DESIGNABLE (qobject_cast<QMainWindow *>(parentWidget()) == 0)
+ NOTIFY orientationChanged)
+ Q_PROPERTY(QSize iconSize READ iconSize WRITE setIconSize NOTIFY iconSizeChanged)
+ Q_PROPERTY(Qt::ToolButtonStyle toolButtonStyle READ toolButtonStyle WRITE setToolButtonStyle
+ NOTIFY toolButtonStyleChanged)
+ Q_PROPERTY(bool floating READ isFloating)
+ Q_PROPERTY(bool floatable READ isFloatable WRITE setFloatable)
+
+public:
+ explicit QToolBar(const QString &title, QWidget *parent = 0);
+ explicit QToolBar(QWidget *parent = 0);
+ ~QToolBar();
+
+ void setMovable(bool movable);
+ bool isMovable() const;
+
+ void setAllowedAreas(Qt::ToolBarAreas areas);
+ Qt::ToolBarAreas allowedAreas() const;
+
+ inline bool isAreaAllowed(Qt::ToolBarArea area) const
+ { return (allowedAreas() & area) == area; }
+
+ void setOrientation(Qt::Orientation orientation);
+ Qt::Orientation orientation() const;
+
+ void clear();
+
+#ifdef Q_NO_USING_KEYWORD
+ inline void addAction(QAction *action)
+ { QWidget::addAction(action); }
+#else
+ using QWidget::addAction;
+#endif
+
+ QAction *addAction(const QString &text);
+ QAction *addAction(const QIcon &icon, const QString &text);
+ QAction *addAction(const QString &text, const QObject *receiver, const char* member);
+ QAction *addAction(const QIcon &icon, const QString &text,
+ const QObject *receiver, const char* member);
+
+ QAction *addSeparator();
+ QAction *insertSeparator(QAction *before);
+
+ QAction *addWidget(QWidget *widget);
+ QAction *insertWidget(QAction *before, QWidget *widget);
+
+ QRect actionGeometry(QAction *action) const;
+ QAction *actionAt(const QPoint &p) const;
+ inline QAction *actionAt(int x, int y) const;
+
+ QAction *toggleViewAction() const;
+
+ QSize iconSize() const;
+ Qt::ToolButtonStyle toolButtonStyle() const;
+
+ QWidget *widgetForAction(QAction *action) const;
+
+ bool isFloatable() const;
+ void setFloatable(bool floatable);
+ bool isFloating() const;
+
+public Q_SLOTS:
+ void setIconSize(const QSize &iconSize);
+ void setToolButtonStyle(Qt::ToolButtonStyle toolButtonStyle);
+
+Q_SIGNALS:
+ void actionTriggered(QAction *action);
+ void movableChanged(bool movable);
+ void allowedAreasChanged(Qt::ToolBarAreas allowedAreas);
+ void orientationChanged(Qt::Orientation orientation);
+ void iconSizeChanged(const QSize &iconSize);
+ void toolButtonStyleChanged(Qt::ToolButtonStyle toolButtonStyle);
+ void topLevelChanged(bool topLevel);
+ void visibilityChanged(bool visible);
+
+protected:
+ void actionEvent(QActionEvent *event);
+ void changeEvent(QEvent *event);
+ void childEvent(QChildEvent *event);
+ void paintEvent(QPaintEvent *event);
+ void resizeEvent(QResizeEvent *event);
+ bool event(QEvent *event);
+ void initStyleOption(QStyleOptionToolBar *option) const;
+
+#ifdef QT3_SUPPORT
+public:
+ QT3_SUPPORT_CONSTRUCTOR QToolBar(QWidget *parent, const char *name);
+ inline QT3_SUPPORT void setLabel(const QString &label)
+ { setWindowTitle(label); }
+ inline QT3_SUPPORT QString label() const
+ { return windowTitle(); }
+#endif
+
+private:
+ Q_DECLARE_PRIVATE(QToolBar)
+ Q_DISABLE_COPY(QToolBar)
+ Q_PRIVATE_SLOT(d_func(), void _q_toggleView(bool))
+ Q_PRIVATE_SLOT(d_func(), void _q_updateIconSize(const QSize &))
+ Q_PRIVATE_SLOT(d_func(), void _q_updateToolButtonStyle(Qt::ToolButtonStyle))
+
+ friend class QMainWindow;
+ friend class QMainWindowLayout;
+ friend class QToolBarLayout;
+ friend class QToolBarAreaLayout;
+};
+
+inline QAction *QToolBar::actionAt(int ax, int ay) const
+{ return actionAt(QPoint(ax, ay)); }
+
+#endif // QT_NO_TOOLBAR
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QDYNAMICTOOLBAR_H
diff --git a/src/widgets/widgets/qtoolbar_p.h b/src/widgets/widgets/qtoolbar_p.h
new file mode 100644
index 0000000000..70f1b6dca1
--- /dev/null
+++ b/src/widgets/widgets/qtoolbar_p.h
@@ -0,0 +1,135 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDYNAMICTOOLBAR_P_H
+#define QDYNAMICTOOLBAR_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qtoolbar.h"
+#include "QtWidgets/qaction.h"
+#include "private/qwidget_p.h"
+#include <QtCore/qbasictimer.h>
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_TOOLBAR
+
+class QToolBarLayout;
+class QTimer;
+
+class QToolBarPrivate : public QWidgetPrivate
+{
+ Q_DECLARE_PUBLIC(QToolBar)
+
+public:
+ inline QToolBarPrivate()
+ : explicitIconSize(false), explicitToolButtonStyle(false), movable(true), floatable(true),
+ allowedAreas(Qt::AllToolBarAreas), orientation(Qt::Horizontal),
+ toolButtonStyle(Qt::ToolButtonIconOnly),
+ layout(0), state(0)
+#ifdef Q_WS_MAC
+ , macWindowDragging(false)
+#endif
+ { }
+
+ void init();
+ void actionTriggered();
+ void _q_toggleView(bool b);
+ void _q_updateIconSize(const QSize &sz);
+ void _q_updateToolButtonStyle(Qt::ToolButtonStyle style);
+
+ bool explicitIconSize;
+ bool explicitToolButtonStyle;
+ bool movable;
+ bool floatable;
+ Qt::ToolBarAreas allowedAreas;
+ Qt::Orientation orientation;
+ Qt::ToolButtonStyle toolButtonStyle;
+ QSize iconSize;
+
+ QAction *toggleViewAction;
+
+ QToolBarLayout *layout;
+
+ struct DragState {
+ QPoint pressPos;
+ bool dragging;
+ bool moving;
+ QLayoutItem *widgetItem;
+ };
+ DragState *state;
+
+#ifdef Q_WS_MAC
+ bool macWindowDragging;
+ QPoint macWindowDragPressPosition;
+#endif
+
+ bool mousePressEvent(QMouseEvent *e);
+ bool mouseReleaseEvent(QMouseEvent *e);
+ bool mouseMoveEvent(QMouseEvent *e);
+
+ void updateWindowFlags(bool floating, bool unplug = false);
+ void setWindowState(bool floating, bool unplug = false, const QRect &rect = QRect());
+ void initDrag(const QPoint &pos);
+ void startDrag(bool moving = false);
+ void endDrag();
+
+ void unplug(const QRect &r);
+ void plug(const QRect &r);
+
+ QBasicTimer waitForPopupTimer;
+};
+
+#endif // QT_NO_TOOLBAR
+
+QT_END_NAMESPACE
+
+#endif // QDYNAMICTOOLBAR_P_H
diff --git a/src/gui/widgets/qtoolbararealayout.cpp b/src/widgets/widgets/qtoolbararealayout.cpp
index fbd5ef2cd7..fbd5ef2cd7 100644
--- a/src/gui/widgets/qtoolbararealayout.cpp
+++ b/src/widgets/widgets/qtoolbararealayout.cpp
diff --git a/src/gui/widgets/qtoolbararealayout_p.h b/src/widgets/widgets/qtoolbararealayout_p.h
index 940901df96..940901df96 100644
--- a/src/gui/widgets/qtoolbararealayout_p.h
+++ b/src/widgets/widgets/qtoolbararealayout_p.h
diff --git a/src/gui/widgets/qtoolbarextension.cpp b/src/widgets/widgets/qtoolbarextension.cpp
index c522b416f2..c522b416f2 100644
--- a/src/gui/widgets/qtoolbarextension.cpp
+++ b/src/widgets/widgets/qtoolbarextension.cpp
diff --git a/src/widgets/widgets/qtoolbarextension_p.h b/src/widgets/widgets/qtoolbarextension_p.h
new file mode 100644
index 0000000000..d7f28bf0f3
--- /dev/null
+++ b/src/widgets/widgets/qtoolbarextension_p.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDYNAMICTOOLBAREXTENSION_P_H
+#define QDYNAMICTOOLBAREXTENSION_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "QtWidgets/qtoolbutton.h"
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_TOOLBUTTON
+
+class Q_AUTOTEST_EXPORT QToolBarExtension : public QToolButton
+{
+ Q_OBJECT
+ Qt::Orientation orientation;
+
+public:
+ explicit QToolBarExtension(QWidget *parent);
+ void paintEvent(QPaintEvent *);
+ QSize sizeHint() const;
+
+public Q_SLOTS:
+ void setOrientation(Qt::Orientation o);
+};
+
+#endif // QT_NO_TOOLBUTTON
+
+QT_END_NAMESPACE
+
+#endif // QDYNAMICTOOLBAREXTENSION_P_H
diff --git a/src/gui/widgets/qtoolbarlayout.cpp b/src/widgets/widgets/qtoolbarlayout.cpp
index 971fddaafd..971fddaafd 100644
--- a/src/gui/widgets/qtoolbarlayout.cpp
+++ b/src/widgets/widgets/qtoolbarlayout.cpp
diff --git a/src/widgets/widgets/qtoolbarlayout_p.h b/src/widgets/widgets/qtoolbarlayout_p.h
new file mode 100644
index 0000000000..4e4a8eab84
--- /dev/null
+++ b/src/widgets/widgets/qtoolbarlayout_p.h
@@ -0,0 +1,134 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTOOLBARLAYOUT_P_H
+#define QTOOLBARLAYOUT_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtWidgets/qlayout.h>
+#include <private/qlayoutengine_p.h>
+#include <QVector>
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_TOOLBAR
+
+class QAction;
+class QToolBarExtension;
+class QMenu;
+
+class QToolBarItem : public QWidgetItem
+{
+public:
+ QToolBarItem(QWidget *widget);
+ bool isEmpty() const;
+
+ QAction *action;
+ bool customWidget;
+};
+
+class QToolBarLayout : public QLayout
+{
+ Q_OBJECT
+
+public:
+ QToolBarLayout(QWidget *parent = 0);
+ ~QToolBarLayout();
+
+ void addItem(QLayoutItem *item);
+ QLayoutItem *itemAt(int index) const;
+ QLayoutItem *takeAt(int index);
+ int count() const;
+
+ bool isEmpty() const;
+ void invalidate();
+ Qt::Orientations expandingDirections() const;
+
+ void setGeometry(const QRect &r);
+ QSize minimumSize() const;
+ QSize sizeHint() const;
+
+ void insertAction(int index, QAction *action);
+ int indexOf(QAction *action) const;
+ int indexOf(QWidget *widget) const { return QLayout::indexOf(widget); }
+
+ bool layoutActions(const QSize &size);
+ QSize expandedSize(const QSize &size) const;
+ bool expanded, animating;
+
+ void setUsePopupMenu(bool set); // Yeah, there's no getter, but it's internal.
+ void checkUsePopupMenu();
+
+ bool movable() const;
+ void updateMarginAndSpacing();
+ bool hasExpandFlag() const;
+
+public Q_SLOTS:
+ void setExpanded(bool b);
+
+private:
+ QList<QToolBarItem*> items;
+ QSize hint, minSize;
+ bool dirty, expanding, empty, expandFlag;
+ QVector<QLayoutStruct> geomArray;
+ QRect handRect;
+ QToolBarExtension *extension;
+
+ void updateGeomArray() const;
+ QToolBarItem *createItem(QAction *action);
+ QMenu *popupMenu;
+};
+
+#endif // QT_NO_TOOLBAR
+
+QT_END_NAMESPACE
+
+#endif // QTOOLBARLAYOUT_P_H
diff --git a/src/gui/widgets/qtoolbarseparator.cpp b/src/widgets/widgets/qtoolbarseparator.cpp
index bd0ed9854f..bd0ed9854f 100644
--- a/src/gui/widgets/qtoolbarseparator.cpp
+++ b/src/widgets/widgets/qtoolbarseparator.cpp
diff --git a/src/widgets/widgets/qtoolbarseparator_p.h b/src/widgets/widgets/qtoolbarseparator_p.h
new file mode 100644
index 0000000000..0f1eb05abc
--- /dev/null
+++ b/src/widgets/widgets/qtoolbarseparator_p.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDYNAMICTOOLBARSEPARATOR_P_H
+#define QDYNAMICTOOLBARSEPARATOR_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "QtWidgets/qwidget.h"
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_TOOLBAR
+
+class QStyleOption;
+class QToolBar;
+
+class QToolBarSeparator : public QWidget
+{
+ Q_OBJECT
+ Qt::Orientation orient;
+
+public:
+ explicit QToolBarSeparator(QToolBar *parent);
+
+ Qt::Orientation orientation() const;
+
+ QSize sizeHint() const;
+
+ void paintEvent(QPaintEvent *);
+ void initStyleOption(QStyleOption *option) const;
+
+public Q_SLOTS:
+ void setOrientation(Qt::Orientation orientation);
+};
+
+#endif // QT_NO_TOOLBAR
+
+QT_END_NAMESPACE
+
+#endif // QDYNAMICTOOLBARSEPARATOR_P_H
diff --git a/src/gui/widgets/qtoolbox.cpp b/src/widgets/widgets/qtoolbox.cpp
index 711bf8c89c..711bf8c89c 100644
--- a/src/gui/widgets/qtoolbox.cpp
+++ b/src/widgets/widgets/qtoolbox.cpp
diff --git a/src/widgets/widgets/qtoolbox.h b/src/widgets/widgets/qtoolbox.h
new file mode 100644
index 0000000000..b08d37e424
--- /dev/null
+++ b/src/widgets/widgets/qtoolbox.h
@@ -0,0 +1,148 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTOOLBOX_H
+#define QTOOLBOX_H
+
+#include <QtWidgets/qframe.h>
+#include <QtWidgets/qicon.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_TOOLBOX
+
+class QToolBoxPrivate;
+
+class Q_WIDGETS_EXPORT QToolBox : public QFrame
+{
+ Q_OBJECT
+ Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentChanged)
+ Q_PROPERTY(int count READ count)
+
+public:
+ explicit QToolBox(QWidget *parent = 0, Qt::WindowFlags f = 0);
+ ~QToolBox();
+
+ int addItem(QWidget *widget, const QString &text);
+ int addItem(QWidget *widget, const QIcon &icon, const QString &text);
+ int insertItem(int index, QWidget *widget, const QString &text);
+ int insertItem(int index, QWidget *widget, const QIcon &icon, const QString &text);
+
+ void removeItem(int index);
+
+ void setItemEnabled(int index, bool enabled);
+ bool isItemEnabled(int index) const;
+
+ void setItemText(int index, const QString &text);
+ QString itemText(int index) const;
+
+ void setItemIcon(int index, const QIcon &icon);
+ QIcon itemIcon(int index) const;
+
+#ifndef QT_NO_TOOLTIP
+ void setItemToolTip(int index, const QString &toolTip);
+ QString itemToolTip(int index) const;
+#endif
+
+ int currentIndex() const;
+ QWidget *currentWidget() const;
+ QWidget *widget(int index) const;
+ int indexOf(QWidget *widget) const;
+ int count() const;
+
+public Q_SLOTS:
+ void setCurrentIndex(int index);
+ void setCurrentWidget(QWidget *widget);
+
+Q_SIGNALS:
+ void currentChanged(int index);
+
+protected:
+ bool event(QEvent *e);
+ virtual void itemInserted(int index);
+ virtual void itemRemoved(int index);
+ void showEvent(QShowEvent *e);
+ void changeEvent(QEvent *);
+
+#ifdef QT3_SUPPORT
+public:
+ QT3_SUPPORT_CONSTRUCTOR QToolBox(QWidget *parent, const char *name, Qt::WindowFlags f = 0);
+ inline QT3_SUPPORT void setItemLabel(int index, const QString &text) { setItemText(index, text); }
+ inline QT3_SUPPORT QString itemLabel(int index) const { return itemText(index); }
+ inline QT3_SUPPORT QWidget *currentItem() const { return widget(currentIndex()); }
+ inline QT3_SUPPORT void setCurrentItem(QWidget *item) { setCurrentIndex(indexOf(item)); }
+ inline QT3_SUPPORT void setItemIconSet(int index, const QIcon &icon) { setItemIcon(index, icon); }
+ inline QT3_SUPPORT QIcon itemIconSet(int index) const { return itemIcon(index); }
+ inline QT3_SUPPORT int removeItem(QWidget *item)
+ { int i = indexOf(item); removeItem(i); return i; }
+ inline QT3_SUPPORT QWidget *item(int index) const { return widget(index); }
+ QT3_SUPPORT void setMargin(int margin) { setContentsMargins(margin, margin, margin, margin); }
+ QT3_SUPPORT int margin() const
+ { int margin; int dummy; getContentsMargins(&margin, &dummy, &dummy, &dummy); return margin; }
+#endif
+
+private:
+ Q_DECLARE_PRIVATE(QToolBox)
+ Q_DISABLE_COPY(QToolBox)
+ Q_PRIVATE_SLOT(d_func(), void _q_buttonClicked())
+ Q_PRIVATE_SLOT(d_func(), void _q_widgetDestroyed(QObject*))
+};
+
+
+inline int QToolBox::addItem(QWidget *item, const QString &text)
+{ return insertItem(-1, item, QIcon(), text); }
+inline int QToolBox::addItem(QWidget *item, const QIcon &iconSet,
+ const QString &text)
+{ return insertItem(-1, item, iconSet, text); }
+inline int QToolBox::insertItem(int index, QWidget *item, const QString &text)
+{ return insertItem(index, item, QIcon(), text); }
+
+#endif // QT_NO_TOOLBOX
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QTOOLBOX_H
diff --git a/src/gui/widgets/qtoolbutton.cpp b/src/widgets/widgets/qtoolbutton.cpp
index f023f8af0f..f023f8af0f 100644
--- a/src/gui/widgets/qtoolbutton.cpp
+++ b/src/widgets/widgets/qtoolbutton.cpp
diff --git a/src/widgets/widgets/qtoolbutton.h b/src/widgets/widgets/qtoolbutton.h
new file mode 100644
index 0000000000..7d1ff13409
--- /dev/null
+++ b/src/widgets/widgets/qtoolbutton.h
@@ -0,0 +1,199 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTOOLBUTTON_H
+#define QTOOLBUTTON_H
+
+#include <QtWidgets/qabstractbutton.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_TOOLBUTTON
+
+class QToolButtonPrivate;
+class QMenu;
+class QStyleOptionToolButton;
+
+class Q_WIDGETS_EXPORT QToolButton : public QAbstractButton
+{
+ Q_OBJECT
+ Q_ENUMS(Qt::ToolButtonStyle Qt::ArrowType ToolButtonPopupMode)
+#ifndef QT_NO_MENU
+ Q_PROPERTY(ToolButtonPopupMode popupMode READ popupMode WRITE setPopupMode)
+#endif
+ Q_PROPERTY(Qt::ToolButtonStyle toolButtonStyle READ toolButtonStyle WRITE setToolButtonStyle)
+ Q_PROPERTY(bool autoRaise READ autoRaise WRITE setAutoRaise)
+ Q_PROPERTY(Qt::ArrowType arrowType READ arrowType WRITE setArrowType)
+
+public:
+ enum ToolButtonPopupMode {
+ DelayedPopup,
+ MenuButtonPopup,
+ InstantPopup
+ };
+
+ explicit QToolButton(QWidget * parent=0);
+ ~QToolButton();
+
+ QSize sizeHint() const;
+ QSize minimumSizeHint() const;
+
+ Qt::ToolButtonStyle toolButtonStyle() const;
+
+ Qt::ArrowType arrowType() const;
+ void setArrowType(Qt::ArrowType type);
+
+#ifndef QT_NO_MENU
+ void setMenu(QMenu* menu);
+ QMenu* menu() const;
+
+ void setPopupMode(ToolButtonPopupMode mode);
+ ToolButtonPopupMode popupMode() const;
+#endif
+
+ QAction *defaultAction() const;
+
+ void setAutoRaise(bool enable);
+ bool autoRaise() const;
+
+public Q_SLOTS:
+#ifndef QT_NO_MENU
+ void showMenu();
+#endif
+ void setToolButtonStyle(Qt::ToolButtonStyle style);
+ void setDefaultAction(QAction *);
+
+Q_SIGNALS:
+ void triggered(QAction *);
+
+protected:
+ QToolButton(QToolButtonPrivate &, QWidget* parent);
+ bool event(QEvent *e);
+ void mousePressEvent(QMouseEvent *);
+ void mouseReleaseEvent(QMouseEvent *);
+ void paintEvent(QPaintEvent *);
+ void actionEvent(QActionEvent *);
+
+ void enterEvent(QEvent *);
+ void leaveEvent(QEvent *);
+ void timerEvent(QTimerEvent *);
+ void changeEvent(QEvent *);
+
+ bool hitButton(const QPoint &pos) const;
+ void nextCheckState();
+ void initStyleOption(QStyleOptionToolButton *option) const;
+
+private:
+ Q_DISABLE_COPY(QToolButton)
+ Q_DECLARE_PRIVATE(QToolButton)
+#ifndef QT_NO_MENU
+ Q_PRIVATE_SLOT(d_func(), void _q_buttonPressed())
+ Q_PRIVATE_SLOT(d_func(), void _q_updateButtonDown())
+ Q_PRIVATE_SLOT(d_func(), void _q_menuTriggered(QAction*))
+#endif
+ Q_PRIVATE_SLOT(d_func(), void _q_actionTriggered())
+
+#ifdef QT3_SUPPORT
+public:
+ enum TextPosition {
+ BesideIcon,
+ BelowIcon
+ , Right = BesideIcon,
+ Under = BelowIcon
+ };
+
+ QT3_SUPPORT_CONSTRUCTOR QToolButton(QWidget * parent, const char* name);
+ QT3_SUPPORT_CONSTRUCTOR QToolButton(Qt::ArrowType type, QWidget *parent, const char* name);
+ QT3_SUPPORT_CONSTRUCTOR QToolButton( const QIcon& s, const QString &textLabel,
+ const QString& grouptext,
+ QObject * receiver, const char* slot,
+ QWidget * parent, const char* name=0 );
+ inline QT3_SUPPORT void setPixmap(const QPixmap &pixmap) { setIcon(static_cast<QIcon>(pixmap)); }
+ QT3_SUPPORT void setOnIconSet(const QIcon&);
+ QT3_SUPPORT void setOffIconSet(const QIcon&);
+ inline QT3_SUPPORT void setIconSet(const QIcon &icon){setIcon(icon);}
+ QT3_SUPPORT void setIconSet(const QIcon &, bool on);
+ inline QT3_SUPPORT void setTextLabel(const QString &text, bool tooltip = true) {
+ setText(text);
+#ifndef QT_NO_TOOLTIP
+ if (tooltip)
+ setToolTip(text);
+#else
+ Q_UNUSED(tooltip);
+#endif
+ }
+ inline QT3_SUPPORT QString textLabel() const { return text(); }
+ QT3_SUPPORT QIcon onIconSet() const;
+ QT3_SUPPORT QIcon offIconSet() const;
+ QT3_SUPPORT QIcon iconSet(bool on) const;
+ inline QT3_SUPPORT QIcon iconSet() const { return icon(); }
+ inline QT3_SUPPORT void openPopup() { showMenu(); }
+ inline QT3_SUPPORT void setPopup(QMenu* popup) {setMenu(popup); }
+ inline QT3_SUPPORT QMenu* popup() const { return menu(); }
+ inline QT3_SUPPORT bool usesBigPixmap() const { return iconSize().height() > 22; }
+ inline QT3_SUPPORT bool usesTextLabel() const { return toolButtonStyle() != Qt::ToolButtonIconOnly; }
+ inline QT3_SUPPORT TextPosition textPosition() const
+ { return toolButtonStyle() == Qt::ToolButtonTextUnderIcon ? BelowIcon : BesideIcon; }
+ QT3_SUPPORT void setPopupDelay(int delay);
+ QT3_SUPPORT int popupDelay() const;
+
+public Q_SLOTS:
+ QT_MOC_COMPAT void setUsesBigPixmap(bool enable)
+ { setIconSize(enable?QSize(32,32):QSize(22,22)); }
+ QT_MOC_COMPAT void setUsesTextLabel(bool enable)
+ { setToolButtonStyle(enable?Qt::ToolButtonTextUnderIcon : Qt::ToolButtonIconOnly); }
+ QT_MOC_COMPAT void setTextPosition(QToolButton::TextPosition pos)
+ { setToolButtonStyle(pos == BesideIcon ? Qt::ToolButtonTextBesideIcon : Qt::ToolButtonTextUnderIcon); }
+
+#endif
+};
+
+#endif // QT_NO_TOOLBUTTON
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QTOOLBUTTON_H
diff --git a/src/widgets/widgets/qwidgetanimator.cpp b/src/widgets/widgets/qwidgetanimator.cpp
new file mode 100644
index 0000000000..9df7dfc0eb
--- /dev/null
+++ b/src/widgets/widgets/qwidgetanimator.cpp
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qpropertyanimation.h>
+#include <QtWidgets/qwidget.h>
+#include <private/qmainwindowlayout_p.h>
+
+#include "qwidgetanimator_p.h"
+
+QT_BEGIN_NAMESPACE
+
+QWidgetAnimator::QWidgetAnimator(QMainWindowLayout *layout) : m_mainWindowLayout(layout)
+{
+}
+
+void QWidgetAnimator::abort(QWidget *w)
+{
+#ifndef QT_NO_ANIMATION
+ AnimationMap::iterator it = m_animation_map.find(w);
+ if (it == m_animation_map.end())
+ return;
+ QPropertyAnimation *anim = *it;
+ m_animation_map.erase(it);
+ anim->stop();
+#ifndef QT_NO_MAINWINDOW
+ m_mainWindowLayout->animationFinished(w);
+#endif
+#else
+ Q_UNUSED(w); //there is no animation to abort
+#endif //QT_NO_ANIMATION
+}
+
+#ifndef QT_NO_ANIMATION
+void QWidgetAnimator::animationFinished()
+{
+ QPropertyAnimation *anim = qobject_cast<QPropertyAnimation*>(sender());
+ abort(static_cast<QWidget*>(anim->targetObject()));
+}
+#endif //QT_NO_ANIMATION
+
+void QWidgetAnimator::animate(QWidget *widget, const QRect &_final_geometry, bool animate)
+{
+ QRect r = widget->geometry();
+ if (r.right() < 0 || r.bottom() < 0)
+ r = QRect();
+
+ animate = animate && !r.isNull() && !_final_geometry.isNull();
+
+ // might make the wigdet go away by sending it to negative space
+ const QRect final_geometry = _final_geometry.isValid() || widget->isWindow() ? _final_geometry :
+ QRect(QPoint(-500 - widget->width(), -500 - widget->height()), widget->size());
+
+#ifndef QT_NO_ANIMATION
+ AnimationMap::const_iterator it = m_animation_map.constFind(widget);
+ if (it != m_animation_map.constEnd() && (*it)->endValue().toRect() == final_geometry)
+ return;
+
+ QPropertyAnimation *anim = new QPropertyAnimation(widget, "geometry", widget);
+ anim->setDuration(animate ? 200 : 0);
+ anim->setEasingCurve(QEasingCurve::InOutQuad);
+ anim->setEndValue(final_geometry);
+ m_animation_map[widget] = anim;
+ connect(anim, SIGNAL(finished()), SLOT(animationFinished()));
+ anim->start(QPropertyAnimation::DeleteWhenStopped);
+#else
+ //we do it in one shot
+ widget->setGeometry(final_geometry);
+#ifndef QT_NO_MAINWINDOW
+ m_mainWindowLayout->animationFinished(widget);
+#endif //QT_NO_MAINWINDOW
+#endif //QT_NO_ANIMATION
+}
+
+bool QWidgetAnimator::animating() const
+{
+ return !m_animation_map.isEmpty();
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/widgets/qwidgetanimator_p.h b/src/widgets/widgets/qwidgetanimator_p.h
index 40a2f274eb..40a2f274eb 100644
--- a/src/gui/widgets/qwidgetanimator_p.h
+++ b/src/widgets/widgets/qwidgetanimator_p.h
diff --git a/src/widgets/widgets/qwidgetlinecontrol.cpp b/src/widgets/widgets/qwidgetlinecontrol.cpp
new file mode 100644
index 0000000000..790ed73f99
--- /dev/null
+++ b/src/widgets/widgets/qwidgetlinecontrol.cpp
@@ -0,0 +1,1862 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwidgetlinecontrol_p.h"
+
+#ifndef QT_NO_LINEEDIT
+
+#include "qabstractitemview.h"
+#include "qclipboard.h"
+#ifndef QT_NO_ACCESSIBILITY
+#include "qaccessible.h"
+#endif
+#ifndef QT_NO_IM
+#include "qinputcontext.h"
+#include "qlist.h"
+#endif
+#include "qapplication.h"
+#ifndef QT_NO_GRAPHICSVIEW
+#include "qgraphicssceneevent.h"
+#endif
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \internal
+
+ Updates the internal text layout. Returns the ascent of the
+ created QTextLine.
+*/
+int QWidgetLineControl::redoTextLayout() const
+{
+ m_textLayout.clearLayout();
+
+ m_textLayout.beginLayout();
+ QTextLine l = m_textLayout.createLine();
+ m_textLayout.endLayout();
+
+#if defined(Q_WS_MAC)
+ if (m_threadChecks)
+ m_textLayoutThread = QThread::currentThread();
+#endif
+
+ return qRound(l.ascent());
+}
+
+/*!
+ \internal
+
+ Updates the display text based of the current edit text
+ If the text has changed will emit displayTextChanged()
+*/
+void QWidgetLineControl::updateDisplayText(bool forceUpdate)
+{
+ QString orig = m_textLayout.text();
+ QString str;
+ if (m_echoMode == QLineEdit::NoEcho)
+ str = QString::fromLatin1("");
+ else
+ str = m_text;
+
+ if (m_echoMode == QLineEdit::Password || (m_echoMode == QLineEdit::PasswordEchoOnEdit
+ && !m_passwordEchoEditing))
+ str.fill(m_passwordCharacter);
+
+ // replace certain non-printable characters with spaces (to avoid
+ // drawing boxes when using fonts that don't have glyphs for such
+ // characters)
+ QChar* uc = str.data();
+ for (int i = 0; i < (int)str.length(); ++i) {
+ if ((uc[i] < 0x20 && uc[i] != 0x09)
+ || uc[i] == QChar::LineSeparator
+ || uc[i] == QChar::ParagraphSeparator
+ || uc[i] == QChar::ObjectReplacementCharacter)
+ uc[i] = QChar(0x0020);
+ }
+
+ m_textLayout.setText(str);
+
+ QTextOption option = m_textLayout.textOption();
+ option.setTextDirection(m_layoutDirection);
+ option.setFlags(QTextOption::IncludeTrailingSpaces);
+ m_textLayout.setTextOption(option);
+
+ m_ascent = redoTextLayout();
+
+ if (str != orig || forceUpdate)
+ emit displayTextChanged(str);
+}
+
+#ifndef QT_NO_CLIPBOARD
+/*!
+ \internal
+
+ Copies the currently selected text into the clipboard using the given
+ \a mode.
+
+ \note If the echo mode is set to a mode other than Normal then copy
+ will not work. This is to prevent using copy as a method of bypassing
+ password features of the line control.
+*/
+void QWidgetLineControl::copy(QClipboard::Mode mode) const
+{
+ QString t = selectedText();
+ if (!t.isEmpty() && m_echoMode == QLineEdit::Normal) {
+ disconnect(QApplication::clipboard(), SIGNAL(selectionChanged()), this, 0);
+ QApplication::clipboard()->setText(t, mode);
+ connect(QApplication::clipboard(), SIGNAL(selectionChanged()),
+ this, SLOT(_q_clipboardChanged()));
+ }
+}
+
+/*!
+ \internal
+
+ Inserts the text stored in the application clipboard into the line
+ control.
+
+ \sa insert()
+*/
+void QWidgetLineControl::paste(QClipboard::Mode clipboardMode)
+{
+ QString clip = QApplication::clipboard()->text(clipboardMode);
+ if (!clip.isEmpty() || hasSelectedText()) {
+ separate(); //make it a separate undo/redo command
+ insert(clip);
+ separate();
+ }
+}
+
+#endif // !QT_NO_CLIPBOARD
+
+/*!
+ \internal
+
+ Handles the behavior for the backspace key or function.
+ Removes the current selection if there is a selection, otherwise
+ removes the character prior to the cursor position.
+
+ \sa del()
+*/
+void QWidgetLineControl::backspace()
+{
+ int priorState = m_undoState;
+ if (hasSelectedText()) {
+ removeSelectedText();
+ } else if (m_cursor) {
+ --m_cursor;
+ if (m_maskData)
+ m_cursor = prevMaskBlank(m_cursor);
+ QChar uc = m_text.at(m_cursor);
+ if (m_cursor > 0 && uc.unicode() >= 0xdc00 && uc.unicode() < 0xe000) {
+ // second half of a surrogate, check if we have the first half as well,
+ // if yes delete both at once
+ uc = m_text.at(m_cursor - 1);
+ if (uc.unicode() >= 0xd800 && uc.unicode() < 0xdc00) {
+ internalDelete(true);
+ --m_cursor;
+ }
+ }
+ internalDelete(true);
+ }
+ finishChange(priorState);
+}
+
+/*!
+ \internal
+
+ Handles the behavior for the delete key or function.
+ Removes the current selection if there is a selection, otherwise
+ removes the character after the cursor position.
+
+ \sa del()
+*/
+void QWidgetLineControl::del()
+{
+ int priorState = m_undoState;
+ if (hasSelectedText()) {
+ removeSelectedText();
+ } else {
+ int n = textLayout()->nextCursorPosition(m_cursor) - m_cursor;
+ while (n--)
+ internalDelete();
+ }
+ finishChange(priorState);
+}
+
+/*!
+ \internal
+
+ Inserts the given \a newText at the current cursor position.
+ If there is any selected text it is removed prior to insertion of
+ the new text.
+*/
+void QWidgetLineControl::insert(const QString &newText)
+{
+ int priorState = m_undoState;
+ removeSelectedText();
+ internalInsert(newText);
+ finishChange(priorState);
+}
+
+/*!
+ \internal
+
+ Clears the line control text.
+*/
+void QWidgetLineControl::clear()
+{
+ int priorState = m_undoState;
+ m_selstart = 0;
+ m_selend = m_text.length();
+ removeSelectedText();
+ separate();
+ finishChange(priorState, /*update*/false, /*edited*/false);
+}
+
+/*!
+ \internal
+
+ Sets \a length characters from the given \a start position as selected.
+ The given \a start position must be within the current text for
+ the line control. If \a length characters cannot be selected, then
+ the selection will extend to the end of the current text.
+*/
+void QWidgetLineControl::setSelection(int start, int length)
+{
+ if(start < 0 || start > (int)m_text.length()){
+ qWarning("QWidgetLineControl::setSelection: Invalid start position");
+ return;
+ }
+
+ if (length > 0) {
+ if (start == m_selstart && start + length == m_selend)
+ return;
+ m_selstart = start;
+ m_selend = qMin(start + length, (int)m_text.length());
+ m_cursor = m_selend;
+ } else if (length < 0){
+ if (start == m_selend && start + length == m_selstart)
+ return;
+ m_selstart = qMax(start + length, 0);
+ m_selend = start;
+ m_cursor = m_selstart;
+ } else if (m_selstart != m_selend) {
+ m_selstart = 0;
+ m_selend = 0;
+ m_cursor = start;
+ } else {
+ m_cursor = start;
+ emitCursorPositionChanged();
+ return;
+ }
+ emit selectionChanged();
+ emitCursorPositionChanged();
+}
+
+void QWidgetLineControl::_q_clipboardChanged()
+{
+}
+
+void QWidgetLineControl::_q_deleteSelected()
+{
+ if (!hasSelectedText())
+ return;
+
+ int priorState = m_undoState;
+ emit resetInputContext();
+ removeSelectedText();
+ separate();
+ finishChange(priorState);
+}
+
+/*!
+ \internal
+
+ Initializes the line control with a starting text value of \a txt.
+*/
+void QWidgetLineControl::init(const QString &txt)
+{
+ m_text = txt;
+ updateDisplayText();
+ m_cursor = m_text.length();
+}
+
+/*!
+ \internal
+
+ Sets the password echo editing to \a editing. If password echo editing
+ is true, then the text of the password is displayed even if the echo
+ mode is set to QLineEdit::PasswordEchoOnEdit. Password echoing editing
+ does not affect other echo modes.
+*/
+void QWidgetLineControl::updatePasswordEchoEditing(bool editing)
+{
+ m_passwordEchoEditing = editing;
+ updateDisplayText();
+}
+
+/*!
+ \internal
+
+ Returns the cursor position of the given \a x pixel value in relation
+ to the displayed text. The given \a betweenOrOn specified what kind
+ of cursor position is requested.
+*/
+int QWidgetLineControl::xToPos(int x, QTextLine::CursorPosition betweenOrOn) const
+{
+ return textLayout()->lineAt(0).xToCursor(x, betweenOrOn);
+}
+
+/*!
+ \internal
+
+ Returns the bounds of the current cursor, as defined as a
+ between characters cursor.
+*/
+QRect QWidgetLineControl::cursorRect() const
+{
+ QTextLine l = textLayout()->lineAt(0);
+ int c = m_cursor;
+ if (m_preeditCursor != -1)
+ c += m_preeditCursor;
+ int cix = qRound(l.cursorToX(c));
+ int w = m_cursorWidth;
+ int ch = l.height() + 1;
+
+ return QRect(cix-5, 0, w+9, ch);
+}
+
+/*!
+ \internal
+
+ Fixes the current text so that it is valid given any set validators.
+
+ Returns true if the text was changed. Otherwise returns false.
+*/
+bool QWidgetLineControl::fixup() // this function assumes that validate currently returns != Acceptable
+{
+#ifndef QT_NO_VALIDATOR
+ if (m_validator) {
+ QString textCopy = m_text;
+ int cursorCopy = m_cursor;
+ m_validator->fixup(textCopy);
+ if (m_validator->validate(textCopy, cursorCopy) == QValidator::Acceptable) {
+ if (textCopy != m_text || cursorCopy != m_cursor)
+ internalSetText(textCopy, cursorCopy);
+ return true;
+ }
+ }
+#endif
+ return false;
+}
+
+/*!
+ \internal
+
+ Moves the cursor to the given position \a pos. If \a mark is true will
+ adjust the currently selected text.
+*/
+void QWidgetLineControl::moveCursor(int pos, bool mark)
+{
+ if (pos != m_cursor) {
+ separate();
+ if (m_maskData)
+ pos = pos > m_cursor ? nextMaskBlank(pos) : prevMaskBlank(pos);
+ }
+ if (mark) {
+ int anchor;
+ if (m_selend > m_selstart && m_cursor == m_selstart)
+ anchor = m_selend;
+ else if (m_selend > m_selstart && m_cursor == m_selend)
+ anchor = m_selstart;
+ else
+ anchor = m_cursor;
+ m_selstart = qMin(anchor, pos);
+ m_selend = qMax(anchor, pos);
+ updateDisplayText();
+ } else {
+ internalDeselect();
+ }
+ m_cursor = pos;
+ if (mark || m_selDirty) {
+ m_selDirty = false;
+ emit selectionChanged();
+ }
+ emitCursorPositionChanged();
+}
+
+/*!
+ \internal
+
+ Applies the given input method event \a event to the text of the line
+ control
+*/
+void QWidgetLineControl::processInputMethodEvent(QInputMethodEvent *event)
+{
+ int priorState = 0;
+ bool isGettingInput = !event->commitString().isEmpty()
+ || event->preeditString() != preeditAreaText()
+ || event->replacementLength() > 0;
+ bool cursorPositionChanged = false;
+
+ if (isGettingInput) {
+ // If any text is being input, remove selected text.
+ priorState = m_undoState;
+ if (echoMode() == QLineEdit::PasswordEchoOnEdit && !passwordEchoEditing()) {
+ updatePasswordEchoEditing(true);
+ m_selstart = 0;
+ m_selend = m_text.length();
+ }
+ removeSelectedText();
+ }
+
+ int c = m_cursor; // cursor position after insertion of commit string
+ if (event->replacementStart() <= 0)
+ c += event->commitString().length() - qMin(-event->replacementStart(), event->replacementLength());
+
+ m_cursor += event->replacementStart();
+ if (m_cursor < 0)
+ m_cursor = 0;
+
+ // insert commit string
+ if (event->replacementLength()) {
+ m_selstart = m_cursor;
+ m_selend = m_selstart + event->replacementLength();
+ removeSelectedText();
+ }
+ if (!event->commitString().isEmpty()) {
+ internalInsert(event->commitString());
+ cursorPositionChanged = true;
+ }
+
+ m_cursor = qBound(0, c, m_text.length());
+
+ for (int i = 0; i < event->attributes().size(); ++i) {
+ const QInputMethodEvent::Attribute &a = event->attributes().at(i);
+ if (a.type == QInputMethodEvent::Selection) {
+ m_cursor = qBound(0, a.start + a.length, m_text.length());
+ if (a.length) {
+ m_selstart = qMax(0, qMin(a.start, m_text.length()));
+ m_selend = m_cursor;
+ if (m_selend < m_selstart) {
+ qSwap(m_selstart, m_selend);
+ }
+ } else {
+ m_selstart = m_selend = 0;
+ }
+ cursorPositionChanged = true;
+ }
+ }
+#ifndef QT_NO_IM
+ setPreeditArea(m_cursor, event->preeditString());
+#endif //QT_NO_IM
+ const int oldPreeditCursor = m_preeditCursor;
+ m_preeditCursor = event->preeditString().length();
+ m_hideCursor = false;
+ QList<QTextLayout::FormatRange> formats;
+ for (int i = 0; i < event->attributes().size(); ++i) {
+ const QInputMethodEvent::Attribute &a = event->attributes().at(i);
+ if (a.type == QInputMethodEvent::Cursor) {
+ m_preeditCursor = a.start;
+ m_hideCursor = !a.length;
+ } else if (a.type == QInputMethodEvent::TextFormat) {
+ QTextCharFormat f = qvariant_cast<QTextFormat>(a.value).toCharFormat();
+ if (f.isValid()) {
+ QTextLayout::FormatRange o;
+ o.start = a.start + m_cursor;
+ o.length = a.length;
+ o.format = f;
+ formats.append(o);
+ }
+ }
+ }
+ m_textLayout.setAdditionalFormats(formats);
+ updateDisplayText(/*force*/ true);
+ if (cursorPositionChanged)
+ emitCursorPositionChanged();
+ else if (m_preeditCursor != oldPreeditCursor)
+ emit updateMicroFocus();
+ if (isGettingInput)
+ finishChange(priorState);
+}
+
+/*!
+ \internal
+
+ Draws the display text for the line control using the given
+ \a painter, \a clip, and \a offset. Which aspects of the display text
+ are drawn is specified by the given \a flags.
+
+ If the flags contain DrawSelections, then the selection or input mask
+ backgrounds and foregrounds will be applied before drawing the text.
+
+ If the flags contain DrawCursor a cursor of the current cursorWidth()
+ will be drawn after drawing the text.
+
+ The display text will only be drawn if the flags contain DrawText
+*/
+void QWidgetLineControl::draw(QPainter *painter, const QPoint &offset, const QRect &clip, int flags)
+{
+ QVector<QTextLayout::FormatRange> selections;
+ if (flags & DrawSelections) {
+ QTextLayout::FormatRange o;
+ if (m_selstart < m_selend) {
+ o.start = m_selstart;
+ o.length = m_selend - m_selstart;
+ o.format.setBackground(m_palette.brush(QPalette::Highlight));
+ o.format.setForeground(m_palette.brush(QPalette::HighlightedText));
+ } else {
+ // mask selection
+ if(!m_blinkPeriod || m_blinkStatus){
+ o.start = m_cursor;
+ o.length = 1;
+ o.format.setBackground(m_palette.brush(QPalette::Text));
+ o.format.setForeground(m_palette.brush(QPalette::Window));
+ }
+ }
+ selections.append(o);
+ }
+
+ if (flags & DrawText)
+ textLayout()->draw(painter, offset, selections, clip);
+
+ if (flags & DrawCursor){
+ int cursor = m_cursor;
+ if (m_preeditCursor != -1)
+ cursor += m_preeditCursor;
+ if (!m_hideCursor && (!m_blinkPeriod || m_blinkStatus))
+ textLayout()->drawCursor(painter, offset, cursor, m_cursorWidth);
+ }
+}
+
+/*!
+ \internal
+
+ Sets the selection to cover the word at the given cursor position.
+ The word boundaries are defined by the behavior of QTextLayout::SkipWords
+ cursor mode.
+*/
+void QWidgetLineControl::selectWordAtPos(int cursor)
+{
+ int next = cursor + 1;
+ if(next > end())
+ --next;
+ int c = textLayout()->previousCursorPosition(next, QTextLayout::SkipWords);
+ moveCursor(c, false);
+ // ## text layout should support end of words.
+ int end = textLayout()->nextCursorPosition(c, QTextLayout::SkipWords);
+ while (end > cursor && m_text[end-1].isSpace())
+ --end;
+ moveCursor(end, true);
+}
+
+/*!
+ \internal
+
+ Completes a change to the line control text. If the change is not valid
+ will undo the line control state back to the given \a validateFromState.
+
+ If \a edited is true and the change is valid, will emit textEdited() in
+ addition to textChanged(). Otherwise only emits textChanged() on a valid
+ change.
+
+ The \a update value is currently unused.
+*/
+bool QWidgetLineControl::finishChange(int validateFromState, bool update, bool edited)
+{
+ Q_UNUSED(update)
+ bool lineDirty = m_selDirty;
+ if (m_textDirty) {
+ // do validation
+ bool wasValidInput = m_validInput;
+ m_validInput = true;
+#ifndef QT_NO_VALIDATOR
+ if (m_validator) {
+ m_validInput = false;
+ QString textCopy = m_text;
+ int cursorCopy = m_cursor;
+ m_validInput = (m_validator->validate(textCopy, cursorCopy) != QValidator::Invalid);
+ if (m_validInput) {
+ if (m_text != textCopy) {
+ internalSetText(textCopy, cursorCopy);
+ return true;
+ }
+ m_cursor = cursorCopy;
+ }
+ }
+#endif
+ if (validateFromState >= 0 && wasValidInput && !m_validInput) {
+ if (m_transactions.count())
+ return false;
+ internalUndo(validateFromState);
+ m_history.resize(m_undoState);
+ if (m_modifiedState > m_undoState)
+ m_modifiedState = -1;
+ m_validInput = true;
+ m_textDirty = false;
+ }
+ updateDisplayText();
+ lineDirty |= m_textDirty;
+ if (m_textDirty) {
+ m_textDirty = false;
+ QString actualText = text();
+ if (edited)
+ emit textEdited(actualText);
+ emit textChanged(actualText);
+ }
+ }
+ if (m_selDirty) {
+ m_selDirty = false;
+ emit selectionChanged();
+ }
+ emitCursorPositionChanged();
+ return true;
+}
+
+/*!
+ \internal
+
+ An internal function for setting the text of the line control.
+*/
+void QWidgetLineControl::internalSetText(const QString &txt, int pos, bool edited)
+{
+ internalDeselect();
+ emit resetInputContext();
+ QString oldText = m_text;
+ if (m_maskData) {
+ m_text = maskString(0, txt, true);
+ m_text += clearString(m_text.length(), m_maxLength - m_text.length());
+ } else {
+ m_text = txt.isEmpty() ? txt : txt.left(m_maxLength);
+ }
+ m_history.clear();
+ m_modifiedState = m_undoState = 0;
+ m_cursor = (pos < 0 || pos > m_text.length()) ? m_text.length() : pos;
+ m_textDirty = (oldText != m_text);
+ bool changed = finishChange(-1, true, edited);
+
+#ifndef QT_NO_ACCESSIBILITY
+ if (changed)
+ QAccessible::updateAccessibility(parent(), 0, QAccessible::TextUpdated);
+#endif
+}
+
+
+/*!
+ \internal
+
+ Adds the given \a command to the undo history
+ of the line control. Does not apply the command.
+*/
+void QWidgetLineControl::addCommand(const Command &cmd)
+{
+ if (m_separator && m_undoState && m_history[m_undoState - 1].type != Separator) {
+ m_history.resize(m_undoState + 2);
+ m_history[m_undoState++] = Command(Separator, m_cursor, 0, m_selstart, m_selend);
+ } else {
+ m_history.resize(m_undoState + 1);
+ }
+ m_separator = false;
+ m_history[m_undoState++] = cmd;
+}
+
+/*!
+ \internal
+
+ Inserts the given string \a s into the line
+ control.
+
+ Also adds the appropriate commands into the undo history.
+ This function does not call finishChange(), and may leave the text
+ in an invalid state.
+*/
+void QWidgetLineControl::internalInsert(const QString &s)
+{
+ if (hasSelectedText())
+ addCommand(Command(SetSelection, m_cursor, 0, m_selstart, m_selend));
+ if (m_maskData) {
+ QString ms = maskString(m_cursor, s);
+ for (int i = 0; i < (int) ms.length(); ++i) {
+ addCommand (Command(DeleteSelection, m_cursor + i, m_text.at(m_cursor + i), -1, -1));
+ addCommand(Command(Insert, m_cursor + i, ms.at(i), -1, -1));
+ }
+ m_text.replace(m_cursor, ms.length(), ms);
+ m_cursor += ms.length();
+ m_cursor = nextMaskBlank(m_cursor);
+ m_textDirty = true;
+ } else {
+ int remaining = m_maxLength - m_text.length();
+ if (remaining != 0) {
+ m_text.insert(m_cursor, s.left(remaining));
+ for (int i = 0; i < (int) s.left(remaining).length(); ++i)
+ addCommand(Command(Insert, m_cursor++, s.at(i), -1, -1));
+ m_textDirty = true;
+ }
+ }
+}
+
+/*!
+ \internal
+
+ deletes a single character from the current text. If \a wasBackspace,
+ the character prior to the cursor is removed. Otherwise the character
+ after the cursor is removed.
+
+ Also adds the appropriate commands into the undo history.
+ This function does not call finishChange(), and may leave the text
+ in an invalid state.
+*/
+void QWidgetLineControl::internalDelete(bool wasBackspace)
+{
+ if (m_cursor < (int) m_text.length()) {
+ if (hasSelectedText())
+ addCommand(Command(SetSelection, m_cursor, 0, m_selstart, m_selend));
+ addCommand(Command((CommandType)((m_maskData ? 2 : 0) + (wasBackspace ? Remove : Delete)),
+ m_cursor, m_text.at(m_cursor), -1, -1));
+ if (m_maskData) {
+ m_text.replace(m_cursor, 1, clearString(m_cursor, 1));
+ addCommand(Command(Insert, m_cursor, m_text.at(m_cursor), -1, -1));
+ } else {
+ m_text.remove(m_cursor, 1);
+ }
+ m_textDirty = true;
+ }
+}
+
+/*!
+ \internal
+
+ removes the currently selected text from the line control.
+
+ Also adds the appropriate commands into the undo history.
+ This function does not call finishChange(), and may leave the text
+ in an invalid state.
+*/
+void QWidgetLineControl::removeSelectedText()
+{
+ if (m_selstart < m_selend && m_selend <= (int) m_text.length()) {
+ separate();
+ int i ;
+ addCommand(Command(SetSelection, m_cursor, 0, m_selstart, m_selend));
+ if (m_selstart <= m_cursor && m_cursor < m_selend) {
+ // cursor is within the selection. Split up the commands
+ // to be able to restore the correct cursor position
+ for (i = m_cursor; i >= m_selstart; --i)
+ addCommand (Command(DeleteSelection, i, m_text.at(i), -1, 1));
+ for (i = m_selend - 1; i > m_cursor; --i)
+ addCommand (Command(DeleteSelection, i - m_cursor + m_selstart - 1, m_text.at(i), -1, -1));
+ } else {
+ for (i = m_selend-1; i >= m_selstart; --i)
+ addCommand (Command(RemoveSelection, i, m_text.at(i), -1, -1));
+ }
+ if (m_maskData) {
+ m_text.replace(m_selstart, m_selend - m_selstart, clearString(m_selstart, m_selend - m_selstart));
+ for (int i = 0; i < m_selend - m_selstart; ++i)
+ addCommand(Command(Insert, m_selstart + i, m_text.at(m_selstart + i), -1, -1));
+ } else {
+ m_text.remove(m_selstart, m_selend - m_selstart);
+ }
+ if (m_cursor > m_selstart)
+ m_cursor -= qMin(m_cursor, m_selend) - m_selstart;
+ internalDeselect();
+ m_textDirty = true;
+ }
+}
+
+/*!
+ \internal
+
+ Parses the input mask specified by \a maskFields to generate
+ the mask data used to handle input masks.
+*/
+void QWidgetLineControl::parseInputMask(const QString &maskFields)
+{
+ int delimiter = maskFields.indexOf(QLatin1Char(';'));
+ if (maskFields.isEmpty() || delimiter == 0) {
+ if (m_maskData) {
+ delete [] m_maskData;
+ m_maskData = 0;
+ m_maxLength = 32767;
+ internalSetText(QString());
+ }
+ return;
+ }
+
+ if (delimiter == -1) {
+ m_blank = QLatin1Char(' ');
+ m_inputMask = maskFields;
+ } else {
+ m_inputMask = maskFields.left(delimiter);
+ m_blank = (delimiter + 1 < maskFields.length()) ? maskFields[delimiter + 1] : QLatin1Char(' ');
+ }
+
+ // calculate m_maxLength / m_maskData length
+ m_maxLength = 0;
+ QChar c = 0;
+ for (int i=0; i<m_inputMask.length(); i++) {
+ c = m_inputMask.at(i);
+ if (i > 0 && m_inputMask.at(i-1) == QLatin1Char('\\')) {
+ m_maxLength++;
+ continue;
+ }
+ if (c != QLatin1Char('\\') && c != QLatin1Char('!') &&
+ c != QLatin1Char('<') && c != QLatin1Char('>') &&
+ c != QLatin1Char('{') && c != QLatin1Char('}') &&
+ c != QLatin1Char('[') && c != QLatin1Char(']'))
+ m_maxLength++;
+ }
+
+ delete [] m_maskData;
+ m_maskData = new MaskInputData[m_maxLength];
+
+ MaskInputData::Casemode m = MaskInputData::NoCaseMode;
+ c = 0;
+ bool s;
+ bool escape = false;
+ int index = 0;
+ for (int i = 0; i < m_inputMask.length(); i++) {
+ c = m_inputMask.at(i);
+ if (escape) {
+ s = true;
+ m_maskData[index].maskChar = c;
+ m_maskData[index].separator = s;
+ m_maskData[index].caseMode = m;
+ index++;
+ escape = false;
+ } else if (c == QLatin1Char('<')) {
+ m = MaskInputData::Lower;
+ } else if (c == QLatin1Char('>')) {
+ m = MaskInputData::Upper;
+ } else if (c == QLatin1Char('!')) {
+ m = MaskInputData::NoCaseMode;
+ } else if (c != QLatin1Char('{') && c != QLatin1Char('}') && c != QLatin1Char('[') && c != QLatin1Char(']')) {
+ switch (c.unicode()) {
+ case 'A':
+ case 'a':
+ case 'N':
+ case 'n':
+ case 'X':
+ case 'x':
+ case '9':
+ case '0':
+ case 'D':
+ case 'd':
+ case '#':
+ case 'H':
+ case 'h':
+ case 'B':
+ case 'b':
+ s = false;
+ break;
+ case '\\':
+ escape = true;
+ default:
+ s = true;
+ break;
+ }
+
+ if (!escape) {
+ m_maskData[index].maskChar = c;
+ m_maskData[index].separator = s;
+ m_maskData[index].caseMode = m;
+ index++;
+ }
+ }
+ }
+ internalSetText(m_text);
+}
+
+
+/*!
+ \internal
+
+ checks if the key is valid compared to the inputMask
+*/
+bool QWidgetLineControl::isValidInput(QChar key, QChar mask) const
+{
+ switch (mask.unicode()) {
+ case 'A':
+ if (key.isLetter())
+ return true;
+ break;
+ case 'a':
+ if (key.isLetter() || key == m_blank)
+ return true;
+ break;
+ case 'N':
+ if (key.isLetterOrNumber())
+ return true;
+ break;
+ case 'n':
+ if (key.isLetterOrNumber() || key == m_blank)
+ return true;
+ break;
+ case 'X':
+ if (key.isPrint())
+ return true;
+ break;
+ case 'x':
+ if (key.isPrint() || key == m_blank)
+ return true;
+ break;
+ case '9':
+ if (key.isNumber())
+ return true;
+ break;
+ case '0':
+ if (key.isNumber() || key == m_blank)
+ return true;
+ break;
+ case 'D':
+ if (key.isNumber() && key.digitValue() > 0)
+ return true;
+ break;
+ case 'd':
+ if ((key.isNumber() && key.digitValue() > 0) || key == m_blank)
+ return true;
+ break;
+ case '#':
+ if (key.isNumber() || key == QLatin1Char('+') || key == QLatin1Char('-') || key == m_blank)
+ return true;
+ break;
+ case 'B':
+ if (key == QLatin1Char('0') || key == QLatin1Char('1'))
+ return true;
+ break;
+ case 'b':
+ if (key == QLatin1Char('0') || key == QLatin1Char('1') || key == m_blank)
+ return true;
+ break;
+ case 'H':
+ if (key.isNumber() || (key >= QLatin1Char('a') && key <= QLatin1Char('f')) || (key >= QLatin1Char('A') && key <= QLatin1Char('F')))
+ return true;
+ break;
+ case 'h':
+ if (key.isNumber() || (key >= QLatin1Char('a') && key <= QLatin1Char('f')) || (key >= QLatin1Char('A') && key <= QLatin1Char('F')) || key == m_blank)
+ return true;
+ break;
+ default:
+ break;
+ }
+ return false;
+}
+
+/*!
+ \internal
+
+ Returns true if the given text \a str is valid for any
+ validator or input mask set for the line control.
+
+ Otherwise returns false
+*/
+bool QWidgetLineControl::hasAcceptableInput(const QString &str) const
+{
+#ifndef QT_NO_VALIDATOR
+ QString textCopy = str;
+ int cursorCopy = m_cursor;
+ if (m_validator && m_validator->validate(textCopy, cursorCopy)
+ != QValidator::Acceptable)
+ return false;
+#endif
+
+ if (!m_maskData)
+ return true;
+
+ if (str.length() != m_maxLength)
+ return false;
+
+ for (int i=0; i < m_maxLength; ++i) {
+ if (m_maskData[i].separator) {
+ if (str.at(i) != m_maskData[i].maskChar)
+ return false;
+ } else {
+ if (!isValidInput(str.at(i), m_maskData[i].maskChar))
+ return false;
+ }
+ }
+ return true;
+}
+
+/*!
+ \internal
+
+ Applies the inputMask on \a str starting from position \a pos in the mask. \a clear
+ specifies from where characters should be gotten when a separator is met in \a str - true means
+ that blanks will be used, false that previous input is used.
+ Calling this when no inputMask is set is undefined.
+*/
+QString QWidgetLineControl::maskString(uint pos, const QString &str, bool clear) const
+{
+ if (pos >= (uint)m_maxLength)
+ return QString::fromLatin1("");
+
+ QString fill;
+ fill = clear ? clearString(0, m_maxLength) : m_text;
+
+ int strIndex = 0;
+ QString s = QString::fromLatin1("");
+ int i = pos;
+ while (i < m_maxLength) {
+ if (strIndex < str.length()) {
+ if (m_maskData[i].separator) {
+ s += m_maskData[i].maskChar;
+ if (str[(int)strIndex] == m_maskData[i].maskChar)
+ strIndex++;
+ ++i;
+ } else {
+ if (isValidInput(str[(int)strIndex], m_maskData[i].maskChar)) {
+ switch (m_maskData[i].caseMode) {
+ case MaskInputData::Upper:
+ s += str[(int)strIndex].toUpper();
+ break;
+ case MaskInputData::Lower:
+ s += str[(int)strIndex].toLower();
+ break;
+ default:
+ s += str[(int)strIndex];
+ }
+ ++i;
+ } else {
+ // search for separator first
+ int n = findInMask(i, true, true, str[(int)strIndex]);
+ if (n != -1) {
+ if (str.length() != 1 || i == 0 || (i > 0 && (!m_maskData[i-1].separator || m_maskData[i-1].maskChar != str[(int)strIndex]))) {
+ s += fill.mid(i, n-i+1);
+ i = n + 1; // update i to find + 1
+ }
+ } else {
+ // search for valid m_blank if not
+ n = findInMask(i, true, false, str[(int)strIndex]);
+ if (n != -1) {
+ s += fill.mid(i, n-i);
+ switch (m_maskData[n].caseMode) {
+ case MaskInputData::Upper:
+ s += str[(int)strIndex].toUpper();
+ break;
+ case MaskInputData::Lower:
+ s += str[(int)strIndex].toLower();
+ break;
+ default:
+ s += str[(int)strIndex];
+ }
+ i = n + 1; // updates i to find + 1
+ }
+ }
+ }
+ ++strIndex;
+ }
+ } else
+ break;
+ }
+
+ return s;
+}
+
+
+
+/*!
+ \internal
+
+ Returns a "cleared" string with only separators and blank chars.
+ Calling this when no inputMask is set is undefined.
+*/
+QString QWidgetLineControl::clearString(uint pos, uint len) const
+{
+ if (pos >= (uint)m_maxLength)
+ return QString();
+
+ QString s;
+ int end = qMin((uint)m_maxLength, pos + len);
+ for (int i = pos; i < end; ++i)
+ if (m_maskData[i].separator)
+ s += m_maskData[i].maskChar;
+ else
+ s += m_blank;
+
+ return s;
+}
+
+/*!
+ \internal
+
+ Strips blank parts of the input in a QWidgetLineControl when an inputMask is set,
+ separators are still included. Typically "127.0__.0__.1__" becomes "127.0.0.1".
+*/
+QString QWidgetLineControl::stripString(const QString &str) const
+{
+ if (!m_maskData)
+ return str;
+
+ QString s;
+ int end = qMin(m_maxLength, (int)str.length());
+ for (int i = 0; i < end; ++i)
+ if (m_maskData[i].separator)
+ s += m_maskData[i].maskChar;
+ else
+ if (str[i] != m_blank)
+ s += str[i];
+
+ return s;
+}
+
+/*!
+ \internal
+ searches forward/backward in m_maskData for either a separator or a m_blank
+*/
+int QWidgetLineControl::findInMask(int pos, bool forward, bool findSeparator, QChar searchChar) const
+{
+ if (pos >= m_maxLength || pos < 0)
+ return -1;
+
+ int end = forward ? m_maxLength : -1;
+ int step = forward ? 1 : -1;
+ int i = pos;
+
+ while (i != end) {
+ if (findSeparator) {
+ if (m_maskData[i].separator && m_maskData[i].maskChar == searchChar)
+ return i;
+ } else {
+ if (!m_maskData[i].separator) {
+ if (searchChar.isNull())
+ return i;
+ else if (isValidInput(searchChar, m_maskData[i].maskChar))
+ return i;
+ }
+ }
+ i += step;
+ }
+ return -1;
+}
+
+void QWidgetLineControl::internalUndo(int until)
+{
+ if (!isUndoAvailable())
+ return;
+ internalDeselect();
+ while (m_undoState && m_undoState > until) {
+ Command& cmd = m_history[--m_undoState];
+ switch (cmd.type) {
+ case Insert:
+ m_text.remove(cmd.pos, 1);
+ m_cursor = cmd.pos;
+ break;
+ case SetSelection:
+ m_selstart = cmd.selStart;
+ m_selend = cmd.selEnd;
+ m_cursor = cmd.pos;
+ break;
+ case Remove:
+ case RemoveSelection:
+ m_text.insert(cmd.pos, cmd.uc);
+ m_cursor = cmd.pos + 1;
+ break;
+ case Delete:
+ case DeleteSelection:
+ m_text.insert(cmd.pos, cmd.uc);
+ m_cursor = cmd.pos;
+ break;
+ case Separator:
+ continue;
+ }
+ if (until < 0 && m_undoState) {
+ Command& next = m_history[m_undoState-1];
+ if (next.type != cmd.type && next.type < RemoveSelection
+ && (cmd.type < RemoveSelection || next.type == Separator))
+ break;
+ }
+ }
+ m_textDirty = true;
+ emitCursorPositionChanged();
+}
+
+void QWidgetLineControl::internalRedo()
+{
+ if (!isRedoAvailable())
+ return;
+ internalDeselect();
+ while (m_undoState < (int)m_history.size()) {
+ Command& cmd = m_history[m_undoState++];
+ switch (cmd.type) {
+ case Insert:
+ m_text.insert(cmd.pos, cmd.uc);
+ m_cursor = cmd.pos + 1;
+ break;
+ case SetSelection:
+ m_selstart = cmd.selStart;
+ m_selend = cmd.selEnd;
+ m_cursor = cmd.pos;
+ break;
+ case Remove:
+ case Delete:
+ case RemoveSelection:
+ case DeleteSelection:
+ m_text.remove(cmd.pos, 1);
+ m_selstart = cmd.selStart;
+ m_selend = cmd.selEnd;
+ m_cursor = cmd.pos;
+ break;
+ case Separator:
+ m_selstart = cmd.selStart;
+ m_selend = cmd.selEnd;
+ m_cursor = cmd.pos;
+ break;
+ }
+ if (m_undoState < (int)m_history.size()) {
+ Command& next = m_history[m_undoState];
+ if (next.type != cmd.type && cmd.type < RemoveSelection && next.type != Separator
+ && (next.type < RemoveSelection || cmd.type == Separator))
+ break;
+ }
+ }
+ m_textDirty = true;
+ emitCursorPositionChanged();
+}
+
+/*!
+ \internal
+
+ If the current cursor position differs from the last emitted cursor
+ position, emits cursorPositionChanged().
+*/
+void QWidgetLineControl::emitCursorPositionChanged()
+{
+ if (m_cursor != m_lastCursorPos) {
+ const int oldLast = m_lastCursorPos;
+ m_lastCursorPos = m_cursor;
+ cursorPositionChanged(oldLast, m_cursor);
+#ifndef QT_NO_ACCESSIBILITY
+ QAccessible::updateAccessibility(parent(), 0, QAccessible::TextCaretMoved);
+#endif
+ }
+}
+
+#ifndef QT_NO_COMPLETER
+// iterating forward(dir=1)/backward(dir=-1) from the
+// current row based. dir=0 indicates a new completion prefix was set.
+bool QWidgetLineControl::advanceToEnabledItem(int dir)
+{
+ int start = m_completer->currentRow();
+ if (start == -1)
+ return false;
+ int i = start + dir;
+ if (dir == 0) dir = 1;
+ do {
+ if (!m_completer->setCurrentRow(i)) {
+ if (!m_completer->wrapAround())
+ break;
+ i = i > 0 ? 0 : m_completer->completionCount() - 1;
+ } else {
+ QModelIndex currentIndex = m_completer->currentIndex();
+ if (m_completer->completionModel()->flags(currentIndex) & Qt::ItemIsEnabled)
+ return true;
+ i += dir;
+ }
+ } while (i != start);
+
+ m_completer->setCurrentRow(start); // restore
+ return false;
+}
+
+void QWidgetLineControl::complete(int key)
+{
+ if (!m_completer || isReadOnly() || echoMode() != QLineEdit::Normal)
+ return;
+
+ QString text = this->text();
+ if (m_completer->completionMode() == QCompleter::InlineCompletion) {
+ if (key == Qt::Key_Backspace)
+ return;
+ int n = 0;
+ if (key == Qt::Key_Up || key == Qt::Key_Down) {
+ if (textAfterSelection().length())
+ return;
+ QString prefix = hasSelectedText() ? textBeforeSelection()
+ : text;
+ if (text.compare(m_completer->currentCompletion(), m_completer->caseSensitivity()) != 0
+ || prefix.compare(m_completer->completionPrefix(), m_completer->caseSensitivity()) != 0) {
+ m_completer->setCompletionPrefix(prefix);
+ } else {
+ n = (key == Qt::Key_Up) ? -1 : +1;
+ }
+ } else {
+ m_completer->setCompletionPrefix(text);
+ }
+ if (!advanceToEnabledItem(n))
+ return;
+ } else {
+#ifndef QT_KEYPAD_NAVIGATION
+ if (text.isEmpty()) {
+ m_completer->popup()->hide();
+ return;
+ }
+#endif
+ m_completer->setCompletionPrefix(text);
+ }
+
+ m_completer->complete();
+}
+#endif
+
+void QWidgetLineControl::setCursorBlinkPeriod(int msec)
+{
+ if (msec == m_blinkPeriod)
+ return;
+ if (m_blinkTimer) {
+ killTimer(m_blinkTimer);
+ }
+ if (msec) {
+ m_blinkTimer = startTimer(msec / 2);
+ m_blinkStatus = 1;
+ } else {
+ m_blinkTimer = 0;
+ if (m_blinkStatus == 1)
+ emit updateNeeded(inputMask().isEmpty() ? cursorRect() : QRect());
+ }
+ m_blinkPeriod = msec;
+}
+
+void QWidgetLineControl::resetCursorBlinkTimer()
+{
+ if (m_blinkPeriod == 0 || m_blinkTimer == 0)
+ return;
+ killTimer(m_blinkTimer);
+ m_blinkTimer = startTimer(m_blinkPeriod / 2);
+ m_blinkStatus = 1;
+}
+
+void QWidgetLineControl::timerEvent(QTimerEvent *event)
+{
+ if (event->timerId() == m_blinkTimer) {
+ m_blinkStatus = !m_blinkStatus;
+ emit updateNeeded(inputMask().isEmpty() ? cursorRect() : QRect());
+ } else if (event->timerId() == m_deleteAllTimer) {
+ killTimer(m_deleteAllTimer);
+ m_deleteAllTimer = 0;
+ clear();
+ } else if (event->timerId() == m_tripleClickTimer) {
+ killTimer(m_tripleClickTimer);
+ m_tripleClickTimer = 0;
+ }
+}
+
+bool QWidgetLineControl::processEvent(QEvent* ev)
+{
+#ifdef QT_KEYPAD_NAVIGATION
+ if (QApplication::keypadNavigationEnabled()) {
+ if ((ev->type() == QEvent::KeyPress) || (ev->type() == QEvent::KeyRelease)) {
+ QKeyEvent *ke = (QKeyEvent *)ev;
+ if (ke->key() == Qt::Key_Back) {
+ if (ke->isAutoRepeat()) {
+ // Swallow it. We don't want back keys running amok.
+ ke->accept();
+ return true;
+ }
+ if ((ev->type() == QEvent::KeyRelease)
+ && !isReadOnly()
+ && m_deleteAllTimer) {
+ killTimer(m_deleteAllTimer);
+ m_deleteAllTimer = 0;
+ backspace();
+ ke->accept();
+ return true;
+ }
+ }
+ }
+ }
+#endif
+ switch(ev->type()){
+#ifndef QT_NO_GRAPHICSVIEW
+ case QEvent::GraphicsSceneMouseDoubleClick:
+ case QEvent::GraphicsSceneMouseMove:
+ case QEvent::GraphicsSceneMouseRelease:
+ case QEvent::GraphicsSceneMousePress:{
+ QGraphicsSceneMouseEvent *gvEv = static_cast<QGraphicsSceneMouseEvent*>(ev);
+ QMouseEvent mouse(ev->type(),
+ gvEv->pos(), gvEv->pos(), gvEv->screenPos(), gvEv->button(), gvEv->buttons(), gvEv->modifiers());
+ processMouseEvent(&mouse); break;
+ }
+#endif
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseButtonDblClick:
+ case QEvent::MouseMove:
+ processMouseEvent(static_cast<QMouseEvent*>(ev)); break;
+ case QEvent::KeyPress:
+ case QEvent::KeyRelease:
+ processKeyEvent(static_cast<QKeyEvent*>(ev)); break;
+ case QEvent::InputMethod:
+ processInputMethodEvent(static_cast<QInputMethodEvent*>(ev)); break;
+#ifndef QT_NO_SHORTCUT
+ case QEvent::ShortcutOverride:{
+ if (isReadOnly())
+ return false;
+ QKeyEvent* ke = static_cast<QKeyEvent*>(ev);
+ if (ke == QKeySequence::Copy
+ || ke == QKeySequence::Paste
+ || ke == QKeySequence::Cut
+ || ke == QKeySequence::Redo
+ || ke == QKeySequence::Undo
+ || ke == QKeySequence::MoveToNextWord
+ || ke == QKeySequence::MoveToPreviousWord
+ || ke == QKeySequence::MoveToStartOfDocument
+ || ke == QKeySequence::MoveToEndOfDocument
+ || ke == QKeySequence::SelectNextWord
+ || ke == QKeySequence::SelectPreviousWord
+ || ke == QKeySequence::SelectStartOfLine
+ || ke == QKeySequence::SelectEndOfLine
+ || ke == QKeySequence::SelectStartOfBlock
+ || ke == QKeySequence::SelectEndOfBlock
+ || ke == QKeySequence::SelectStartOfDocument
+ || ke == QKeySequence::SelectAll
+ || ke == QKeySequence::SelectEndOfDocument) {
+ ke->accept();
+ } else if (ke->modifiers() == Qt::NoModifier || ke->modifiers() == Qt::ShiftModifier
+ || ke->modifiers() == Qt::KeypadModifier) {
+ if (ke->key() < Qt::Key_Escape) {
+ ke->accept();
+ } else {
+ switch (ke->key()) {
+ case Qt::Key_Delete:
+ case Qt::Key_Home:
+ case Qt::Key_End:
+ case Qt::Key_Backspace:
+ case Qt::Key_Left:
+ case Qt::Key_Right:
+ ke->accept();
+ default:
+ break;
+ }
+ }
+ }
+ }
+#endif
+ default:
+ return false;
+ }
+ return true;
+}
+
+void QWidgetLineControl::processMouseEvent(QMouseEvent* ev)
+{
+
+ switch (ev->type()) {
+ case QEvent::GraphicsSceneMousePress:
+ case QEvent::MouseButtonPress:{
+ if (m_tripleClickTimer
+ && (ev->pos() - m_tripleClick).manhattanLength()
+ < QApplication::startDragDistance()) {
+ selectAll();
+ return;
+ }
+ if (ev->button() == Qt::RightButton)
+ return;
+
+ bool mark = ev->modifiers() & Qt::ShiftModifier;
+ int cursor = xToPos(ev->pos().x());
+ moveCursor(cursor, mark);
+ break;
+ }
+ case QEvent::GraphicsSceneMouseDoubleClick:
+ case QEvent::MouseButtonDblClick:
+ if (ev->button() == Qt::LeftButton) {
+ selectWordAtPos(xToPos(ev->pos().x()));
+ if (m_tripleClickTimer)
+ killTimer(m_tripleClickTimer);
+ m_tripleClickTimer = startTimer(QApplication::doubleClickInterval());
+ m_tripleClick = ev->pos();
+ }
+ break;
+ case QEvent::GraphicsSceneMouseRelease:
+ case QEvent::MouseButtonRelease:
+#ifndef QT_NO_CLIPBOARD
+ if (QApplication::clipboard()->supportsSelection()) {
+ if (ev->button() == Qt::LeftButton) {
+ copy(QClipboard::Selection);
+ } else if (!isReadOnly() && ev->button() == Qt::MidButton) {
+ deselect();
+ insert(QApplication::clipboard()->text(QClipboard::Selection));
+ }
+ }
+#endif
+ break;
+ case QEvent::GraphicsSceneMouseMove:
+ case QEvent::MouseMove:
+ if (ev->buttons() & Qt::LeftButton) {
+ moveCursor(xToPos(ev->pos().x()), true);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void QWidgetLineControl::processKeyEvent(QKeyEvent* event)
+{
+ bool inlineCompletionAccepted = false;
+
+#ifndef QT_NO_COMPLETER
+ if (m_completer) {
+ QCompleter::CompletionMode completionMode = m_completer->completionMode();
+ if ((completionMode == QCompleter::PopupCompletion
+ || completionMode == QCompleter::UnfilteredPopupCompletion)
+ && m_completer->popup()
+ && m_completer->popup()->isVisible()) {
+ // The following keys are forwarded by the completer to the widget
+ // Ignoring the events lets the completer provide suitable default behavior
+ switch (event->key()) {
+ case Qt::Key_Escape:
+ event->ignore();
+ return;
+ case Qt::Key_Enter:
+ case Qt::Key_Return:
+ case Qt::Key_F4:
+#ifdef QT_KEYPAD_NAVIGATION
+ case Qt::Key_Select:
+ if (!QApplication::keypadNavigationEnabled())
+ break;
+#endif
+ m_completer->popup()->hide(); // just hide. will end up propagating to parent
+ default:
+ break; // normal key processing
+ }
+ } else if (completionMode == QCompleter::InlineCompletion) {
+ switch (event->key()) {
+ case Qt::Key_Enter:
+ case Qt::Key_Return:
+ case Qt::Key_F4:
+#ifdef QT_KEYPAD_NAVIGATION
+ case Qt::Key_Select:
+ if (!QApplication::keypadNavigationEnabled())
+ break;
+#endif
+ if (!m_completer->currentCompletion().isEmpty() && hasSelectedText()
+ && textAfterSelection().isEmpty()) {
+ setText(m_completer->currentCompletion());
+ inlineCompletionAccepted = true;
+ }
+ default:
+ break; // normal key processing
+ }
+ }
+ }
+#endif // QT_NO_COMPLETER
+
+ if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) {
+ if (hasAcceptableInput() || fixup()) {
+ emit accepted();
+ emit editingFinished();
+ }
+ if (inlineCompletionAccepted)
+ event->accept();
+ else
+ event->ignore();
+ return;
+ }
+
+ if (echoMode() == QLineEdit::PasswordEchoOnEdit
+ && !passwordEchoEditing()
+ && !isReadOnly()
+ && !event->text().isEmpty()
+#ifdef QT_KEYPAD_NAVIGATION
+ && event->key() != Qt::Key_Select
+ && event->key() != Qt::Key_Up
+ && event->key() != Qt::Key_Down
+ && event->key() != Qt::Key_Back
+#endif
+ && !(event->modifiers() & Qt::ControlModifier)) {
+ // Clear the edit and reset to normal echo mode while editing; the
+ // echo mode switches back when the edit loses focus
+ // ### resets current content. dubious code; you can
+ // navigate with keys up, down, back, and select(?), but if you press
+ // "left" or "right" it clears?
+ updatePasswordEchoEditing(true);
+ clear();
+ }
+
+ bool unknown = false;
+ bool visual = cursorMoveStyle() == Qt::VisualMoveStyle;
+
+ if (false) {
+ }
+#ifndef QT_NO_SHORTCUT
+ else if (event == QKeySequence::Undo) {
+ if (!isReadOnly())
+ undo();
+ }
+ else if (event == QKeySequence::Redo) {
+ if (!isReadOnly())
+ redo();
+ }
+ else if (event == QKeySequence::SelectAll) {
+ selectAll();
+ }
+#ifndef QT_NO_CLIPBOARD
+ else if (event == QKeySequence::Copy) {
+ copy();
+ }
+ else if (event == QKeySequence::Paste) {
+ if (!isReadOnly()) {
+ QClipboard::Mode mode = QClipboard::Clipboard;
+#ifdef Q_WS_X11
+ if (event->modifiers() == (Qt::CTRL | Qt::SHIFT) && event->key() == Qt::Key_Insert)
+ mode = QClipboard::Selection;
+#endif
+ paste(mode);
+ }
+ }
+ else if (event == QKeySequence::Cut) {
+ if (!isReadOnly()) {
+ copy();
+ del();
+ }
+ }
+ else if (event == QKeySequence::DeleteEndOfLine) {
+ if (!isReadOnly()) {
+ setSelection(cursor(), end());
+ copy();
+ del();
+ }
+ }
+#endif //QT_NO_CLIPBOARD
+ else if (event == QKeySequence::MoveToStartOfLine || event == QKeySequence::MoveToStartOfBlock) {
+ home(0);
+ }
+ else if (event == QKeySequence::MoveToEndOfLine || event == QKeySequence::MoveToEndOfBlock) {
+ end(0);
+ }
+ else if (event == QKeySequence::SelectStartOfLine || event == QKeySequence::SelectStartOfBlock) {
+ home(1);
+ }
+ else if (event == QKeySequence::SelectEndOfLine || event == QKeySequence::SelectEndOfBlock) {
+ end(1);
+ }
+ else if (event == QKeySequence::MoveToNextChar) {
+#if !defined(Q_WS_WIN) || defined(QT_NO_COMPLETER)
+ if (hasSelectedText()) {
+#else
+ if (hasSelectedText() && m_completer
+ && m_completer->completionMode() == QCompleter::InlineCompletion) {
+#endif
+ moveCursor(selectionEnd(), false);
+ } else {
+ cursorForward(0, visual ? 1 : (layoutDirection() == Qt::LeftToRight ? 1 : -1));
+ }
+ }
+ else if (event == QKeySequence::SelectNextChar) {
+ cursorForward(1, visual ? 1 : (layoutDirection() == Qt::LeftToRight ? 1 : -1));
+ }
+ else if (event == QKeySequence::MoveToPreviousChar) {
+#if !defined(Q_WS_WIN) || defined(QT_NO_COMPLETER)
+ if (hasSelectedText()) {
+#else
+ if (hasSelectedText() && m_completer
+ && m_completer->completionMode() == QCompleter::InlineCompletion) {
+#endif
+ moveCursor(selectionStart(), false);
+ } else {
+ cursorForward(0, visual ? -1 : (layoutDirection() == Qt::LeftToRight ? -1 : 1));
+ }
+ }
+ else if (event == QKeySequence::SelectPreviousChar) {
+ cursorForward(1, visual ? -1 : (layoutDirection() == Qt::LeftToRight ? -1 : 1));
+ }
+ else if (event == QKeySequence::MoveToNextWord) {
+ if (echoMode() == QLineEdit::Normal)
+ layoutDirection() == Qt::LeftToRight ? cursorWordForward(0) : cursorWordBackward(0);
+ else
+ layoutDirection() == Qt::LeftToRight ? end(0) : home(0);
+ }
+ else if (event == QKeySequence::MoveToPreviousWord) {
+ if (echoMode() == QLineEdit::Normal)
+ layoutDirection() == Qt::LeftToRight ? cursorWordBackward(0) : cursorWordForward(0);
+ else if (!isReadOnly()) {
+ layoutDirection() == Qt::LeftToRight ? home(0) : end(0);
+ }
+ }
+ else if (event == QKeySequence::SelectNextWord) {
+ if (echoMode() == QLineEdit::Normal)
+ layoutDirection() == Qt::LeftToRight ? cursorWordForward(1) : cursorWordBackward(1);
+ else
+ layoutDirection() == Qt::LeftToRight ? end(1) : home(1);
+ }
+ else if (event == QKeySequence::SelectPreviousWord) {
+ if (echoMode() == QLineEdit::Normal)
+ layoutDirection() == Qt::LeftToRight ? cursorWordBackward(1) : cursorWordForward(1);
+ else
+ layoutDirection() == Qt::LeftToRight ? home(1) : end(1);
+ }
+ else if (event == QKeySequence::Delete) {
+ if (!isReadOnly())
+ del();
+ }
+ else if (event == QKeySequence::DeleteEndOfWord) {
+ if (!isReadOnly()) {
+ cursorWordForward(true);
+ del();
+ }
+ }
+ else if (event == QKeySequence::DeleteStartOfWord) {
+ if (!isReadOnly()) {
+ cursorWordBackward(true);
+ del();
+ }
+ }
+#endif // QT_NO_SHORTCUT
+ else {
+ bool handled = false;
+#ifdef Q_WS_MAC
+ if (event->key() == Qt::Key_Up || event->key() == Qt::Key_Down) {
+ Qt::KeyboardModifiers myModifiers = (event->modifiers() & ~Qt::KeypadModifier);
+ if (myModifiers & Qt::ShiftModifier) {
+ if (myModifiers == (Qt::ControlModifier|Qt::ShiftModifier)
+ || myModifiers == (Qt::AltModifier|Qt::ShiftModifier)
+ || myModifiers == Qt::ShiftModifier) {
+
+ event->key() == Qt::Key_Up ? home(1) : end(1);
+ }
+ } else {
+ if ((myModifiers == Qt::ControlModifier
+ || myModifiers == Qt::AltModifier
+ || myModifiers == Qt::NoModifier)) {
+ event->key() == Qt::Key_Up ? home(0) : end(0);
+ }
+ }
+ handled = true;
+ }
+#endif
+ if (event->modifiers() & Qt::ControlModifier) {
+ switch (event->key()) {
+ case Qt::Key_Backspace:
+ if (!isReadOnly()) {
+ cursorWordBackward(true);
+ del();
+ }
+ break;
+#ifndef QT_NO_COMPLETER
+ case Qt::Key_Up:
+ case Qt::Key_Down:
+ complete(event->key());
+ break;
+#endif
+#if defined(Q_WS_X11)
+ case Qt::Key_E:
+ end(0);
+ break;
+
+ case Qt::Key_U:
+ if (!isReadOnly()) {
+ setSelection(0, text().size());
+#ifndef QT_NO_CLIPBOARD
+ copy();
+#endif
+ del();
+ }
+ break;
+#endif
+ default:
+ if (!handled)
+ unknown = true;
+ }
+ } else { // ### check for *no* modifier
+ switch (event->key()) {
+ case Qt::Key_Backspace:
+ if (!isReadOnly()) {
+ backspace();
+#ifndef QT_NO_COMPLETER
+ complete(Qt::Key_Backspace);
+#endif
+ }
+ break;
+#ifdef QT_KEYPAD_NAVIGATION
+ case Qt::Key_Back:
+ if (QApplication::keypadNavigationEnabled() && !event->isAutoRepeat()
+ && !isReadOnly()) {
+ if (text().length() == 0) {
+ setText(m_cancelText);
+
+ if (passwordEchoEditing())
+ updatePasswordEchoEditing(false);
+
+ emit editFocusChange(false);
+ } else if (!m_deleteAllTimer) {
+ m_deleteAllTimer = startTimer(750);
+ }
+ } else {
+ unknown = true;
+ }
+ break;
+#endif
+ default:
+ if (!handled)
+ unknown = true;
+ }
+ }
+ }
+
+ if (event->key() == Qt::Key_Direction_L || event->key() == Qt::Key_Direction_R) {
+ setLayoutDirection((event->key() == Qt::Key_Direction_L) ? Qt::LeftToRight : Qt::RightToLeft);
+ unknown = false;
+ }
+
+ if (unknown && !isReadOnly()) {
+ QString t = event->text();
+ if (!t.isEmpty() && t.at(0).isPrint()) {
+ insert(t);
+#ifndef QT_NO_COMPLETER
+ complete(event->key());
+#endif
+ event->accept();
+ return;
+ }
+ }
+
+ if (unknown)
+ event->ignore();
+ else
+ event->accept();
+}
+
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/widgets/widgets/qwidgetlinecontrol_p.h b/src/widgets/widgets/qwidgetlinecontrol_p.h
new file mode 100644
index 0000000000..4169d2de29
--- /dev/null
+++ b/src/widgets/widgets/qwidgetlinecontrol_p.h
@@ -0,0 +1,499 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWidgetLineControl_P_H
+#define QWidgetLineControl_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "QtCore/qglobal.h"
+
+#ifndef QT_NO_LINEEDIT
+#include "private/qwidget_p.h"
+#include "QtWidgets/qlineedit.h"
+#include "QtGui/qtextlayout.h"
+#include "QtWidgets/qstyleoption.h"
+#include "QtCore/qpointer.h"
+#include "QtGui/qclipboard.h"
+#include "QtCore/qpoint.h"
+#include "QtWidgets/qcompleter.h"
+#include "QtWidgets/qaccessible.h"
+#include "QtCore/qthread.h"
+
+#include "qplatformdefs.h"
+
+QT_BEGIN_HEADER
+
+#ifdef DrawText
+# undef DrawText
+#endif
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class Q_WIDGETS_EXPORT QWidgetLineControl : public QObject
+{
+ Q_OBJECT
+
+public:
+ QWidgetLineControl(const QString &txt = QString())
+ : m_cursor(0), m_preeditCursor(0), m_cursorWidth(0), m_layoutDirection(Qt::LayoutDirectionAuto),
+ m_hideCursor(false), m_separator(0), m_readOnly(0),
+ m_dragEnabled(0), m_echoMode(0), m_textDirty(0), m_selDirty(0),
+ m_validInput(1), m_blinkStatus(0), m_blinkPeriod(0), m_blinkTimer(0), m_deleteAllTimer(0),
+ m_ascent(0), m_maxLength(32767), m_lastCursorPos(-1),
+ m_tripleClickTimer(0), m_maskData(0), m_modifiedState(0), m_undoState(0),
+ m_selstart(0), m_selend(0), m_passwordEchoEditing(false)
+#ifdef QT_GUI_PASSWORD_ECHO_DELAY
+ , m_passwordEchoTimer(0)
+#endif
+#if defined(Q_WS_MAC)
+ , m_threadChecks(false)
+ , m_textLayoutThread(0)
+ #endif
+ {
+ init(txt);
+ }
+
+ ~QWidgetLineControl()
+ {
+ delete [] m_maskData;
+ }
+
+ int nextMaskBlank(int pos)
+ {
+ int c = findInMask(pos, true, false);
+ m_separator |= (c != pos);
+ return (c != -1 ? c : m_maxLength);
+ }
+
+ int prevMaskBlank(int pos)
+ {
+ int c = findInMask(pos, false, false);
+ m_separator |= (c != pos);
+ return (c != -1 ? c : 0);
+ }
+
+ bool isUndoAvailable() const { return !m_readOnly && m_undoState; }
+ bool isRedoAvailable() const { return !m_readOnly && m_undoState < (int)m_history.size(); }
+ void clearUndo() { m_history.clear(); m_modifiedState = m_undoState = 0; }
+
+ bool isModified() const { return m_modifiedState != m_undoState; }
+ void setModified(bool modified) { m_modifiedState = modified ? -1 : m_undoState; }
+
+ bool allSelected() const { return !m_text.isEmpty() && m_selstart == 0 && m_selend == (int)m_text.length(); }
+ bool hasSelectedText() const { return !m_text.isEmpty() && m_selend > m_selstart; }
+
+ int width() const { return qRound(m_textLayout.lineAt(0).width()) + 1; }
+ int height() const { return qRound(m_textLayout.lineAt(0).height()) + 1; }
+ int ascent() const { return m_ascent; }
+ qreal naturalTextWidth() const { return m_textLayout.lineAt(0).naturalTextWidth(); }
+
+ void setSelection(int start, int length);
+
+ inline QString selectedText() const { return hasSelectedText() ? m_text.mid(m_selstart, m_selend - m_selstart) : QString(); }
+ QString textBeforeSelection() const { return hasSelectedText() ? m_text.left(m_selstart) : QString(); }
+ QString textAfterSelection() const { return hasSelectedText() ? m_text.mid(m_selend) : QString(); }
+
+ int selectionStart() const { return hasSelectedText() ? m_selstart : -1; }
+ int selectionEnd() const { return hasSelectedText() ? m_selend : -1; }
+ bool inSelection(int x) const
+ {
+ if (m_selstart >= m_selend)
+ return false;
+ int pos = xToPos(x, QTextLine::CursorOnCharacter);
+ return pos >= m_selstart && pos < m_selend;
+ }
+
+ void removeSelection()
+ {
+ int priorState = m_undoState;
+ removeSelectedText();
+ finishChange(priorState);
+ }
+
+ int start() const { return 0; }
+ int end() const { return m_text.length(); }
+
+#ifndef QT_NO_CLIPBOARD
+ void copy(QClipboard::Mode mode = QClipboard::Clipboard) const;
+ void paste(QClipboard::Mode mode = QClipboard::Clipboard);
+#endif
+
+ int cursor() const{ return m_cursor; }
+ int preeditCursor() const { return m_preeditCursor; }
+
+ int cursorWidth() const { return m_cursorWidth; }
+ void setCursorWidth(int value) { m_cursorWidth = value; }
+
+ Qt::CursorMoveStyle cursorMoveStyle() const { return m_textLayout.cursorMoveStyle(); }
+ void setCursorMoveStyle(Qt::CursorMoveStyle style) { m_textLayout.setCursorMoveStyle(style); }
+
+ void moveCursor(int pos, bool mark = false);
+ void cursorForward(bool mark, int steps)
+ {
+ int c = m_cursor;
+ if (steps > 0) {
+ while (steps--)
+ c = cursorMoveStyle() == Qt::VisualMoveStyle ? m_textLayout.rightCursorPosition(c)
+ : m_textLayout.nextCursorPosition(c);
+ } else if (steps < 0) {
+ while (steps++)
+ c = cursorMoveStyle() == Qt::VisualMoveStyle ? m_textLayout.leftCursorPosition(c)
+ : m_textLayout.previousCursorPosition(c);
+ }
+ moveCursor(c, mark);
+ }
+
+ void cursorWordForward(bool mark) { moveCursor(m_textLayout.nextCursorPosition(m_cursor, QTextLayout::SkipWords), mark); }
+ void cursorWordBackward(bool mark) { moveCursor(m_textLayout.previousCursorPosition(m_cursor, QTextLayout::SkipWords), mark); }
+
+ void home(bool mark) { moveCursor(0, mark); }
+ void end(bool mark) { moveCursor(text().length(), mark); }
+
+ int xToPos(int x, QTextLine::CursorPosition = QTextLine::CursorBetweenCharacters) const;
+ QRect cursorRect() const;
+
+ qreal cursorToX(int cursor) const { return m_textLayout.lineAt(0).cursorToX(cursor); }
+ qreal cursorToX() const
+ {
+ int cursor = m_cursor;
+ if (m_preeditCursor != -1)
+ cursor += m_preeditCursor;
+ return cursorToX(cursor);
+ }
+
+ bool isReadOnly() const { return m_readOnly; }
+ void setReadOnly(bool enable) { m_readOnly = enable; }
+
+ QString text() const
+ {
+ QString res = m_maskData ? stripString(m_text) : m_text;
+ return (res.isNull() ? QString::fromLatin1("") : res);
+ }
+ void setText(const QString &txt) { internalSetText(txt, -1, false); }
+ QString displayText() const { return m_textLayout.text(); }
+
+ void backspace();
+ void del();
+ void deselect() { internalDeselect(); finishChange(); }
+ void selectAll() { m_selstart = m_selend = m_cursor = 0; moveCursor(m_text.length(), true); }
+
+ void insert(const QString &);
+ void clear();
+ void undo() { internalUndo(); finishChange(-1, true); }
+ void redo() { internalRedo(); finishChange(); }
+ void selectWordAtPos(int);
+
+ uint echoMode() const { return m_echoMode; }
+ void setEchoMode(uint mode)
+ {
+ m_echoMode = mode;
+ m_passwordEchoEditing = false;
+ updateDisplayText();
+ }
+
+ int maxLength() const { return m_maxLength; }
+ void setMaxLength(int maxLength)
+ {
+ if (m_maskData)
+ return;
+ m_maxLength = maxLength;
+ setText(m_text);
+ }
+
+#ifndef QT_NO_VALIDATOR
+ const QValidator *validator() const { return m_validator; }
+ void setValidator(const QValidator *v) { m_validator = const_cast<QValidator*>(v); }
+#endif
+
+#ifndef QT_NO_COMPLETER
+ QCompleter *completer() const { return m_completer; }
+ /* Note that you must set the widget for the completer separately */
+ void setCompleter(const QCompleter *c) { m_completer = const_cast<QCompleter*>(c); }
+ void complete(int key);
+#endif
+
+ int cursorPosition() const { return m_cursor; }
+ void setCursorPosition(int pos) { if (pos <= m_text.length()) moveCursor(qMax(0, pos)); }
+
+ bool hasAcceptableInput() const { return hasAcceptableInput(m_text); }
+ bool fixup();
+
+ QString inputMask() const { return m_maskData ? m_inputMask + QLatin1Char(';') + m_blank : QString(); }
+ void setInputMask(const QString &mask)
+ {
+ parseInputMask(mask);
+ if (m_maskData)
+ moveCursor(nextMaskBlank(0));
+ }
+
+ // input methods
+#ifndef QT_NO_IM
+ bool composeMode() const { return !m_textLayout.preeditAreaText().isEmpty(); }
+ void setPreeditArea(int cursor, const QString &text) { m_textLayout.setPreeditArea(cursor, text); }
+#endif
+
+ QString preeditAreaText() const { return m_textLayout.preeditAreaText(); }
+
+ void updatePasswordEchoEditing(bool editing);
+ bool passwordEchoEditing() const { return m_passwordEchoEditing; }
+
+ QChar passwordCharacter() const { return m_passwordCharacter; }
+ void setPasswordCharacter(const QChar &character) { m_passwordCharacter = character; updateDisplayText(); }
+
+ Qt::LayoutDirection layoutDirection() const {
+ if (m_layoutDirection == Qt::LayoutDirectionAuto) {
+ if (m_text.isEmpty())
+ return QApplication::keyboardInputDirection();
+ return m_text.isRightToLeft() ? Qt::RightToLeft : Qt::LeftToRight;
+ }
+ return m_layoutDirection;
+ }
+ void setLayoutDirection(Qt::LayoutDirection direction)
+ {
+ if (direction != m_layoutDirection) {
+ m_layoutDirection = direction;
+ updateDisplayText();
+ }
+ }
+
+ void setFont(const QFont &font) { m_textLayout.setFont(font); updateDisplayText(); }
+
+ void processInputMethodEvent(QInputMethodEvent *event);
+ void processMouseEvent(QMouseEvent* ev);
+ void processKeyEvent(QKeyEvent* ev);
+
+ int cursorBlinkPeriod() const { return m_blinkPeriod; }
+ void setCursorBlinkPeriod(int msec);
+ void resetCursorBlinkTimer();
+
+ bool cursorBlinkStatus() const { return m_blinkStatus; }
+
+ QString cancelText() const { return m_cancelText; }
+ void setCancelText(const QString &text) { m_cancelText = text; }
+
+ const QPalette &palette() const { return m_palette; }
+ void setPalette(const QPalette &p) { m_palette = p; }
+
+ enum DrawFlags {
+ DrawText = 0x01,
+ DrawSelections = 0x02,
+ DrawCursor = 0x04,
+ DrawAll = DrawText | DrawSelections | DrawCursor
+ };
+ void draw(QPainter *, const QPoint &, const QRect &, int flags = DrawAll);
+
+ bool processEvent(QEvent *ev);
+
+ QTextLayout *textLayout() const
+ {
+#if defined(Q_WS_MAC)
+ if (m_threadChecks && QThread::currentThread() != m_textLayoutThread)
+ redoTextLayout();
+#endif
+ return &m_textLayout;
+ }
+
+#if defined(Q_WS_MAC)
+ void setThreadChecks(bool threadChecks)
+ {
+ m_threadChecks = threadChecks;
+ }
+
+ bool threadChecks() const
+ {
+ return m_threadChecks;
+ }
+#endif
+
+private:
+ void init(const QString &txt);
+ void removeSelectedText();
+ void internalSetText(const QString &txt, int pos = -1, bool edited = true);
+ void updateDisplayText(bool forceUpdate = false);
+
+ void internalInsert(const QString &s);
+ void internalDelete(bool wasBackspace = false);
+ void internalRemove(int pos);
+
+ inline void internalDeselect()
+ {
+ m_selDirty |= (m_selend > m_selstart);
+ m_selstart = m_selend = 0;
+ }
+
+ void internalUndo(int until = -1);
+ void internalRedo();
+
+ QString m_text;
+ QPalette m_palette;
+ int m_cursor;
+ int m_preeditCursor;
+ int m_cursorWidth;
+ Qt::LayoutDirection m_layoutDirection;
+ uint m_hideCursor : 1; // used to hide the m_cursor inside preedit areas
+ uint m_separator : 1;
+ uint m_readOnly : 1;
+ uint m_dragEnabled : 1;
+ uint m_echoMode : 2;
+ uint m_textDirty : 1;
+ uint m_selDirty : 1;
+ uint m_validInput : 1;
+ uint m_blinkStatus : 1;
+ int m_blinkPeriod; // 0 for non-blinking cursor
+ int m_blinkTimer;
+ int m_deleteAllTimer;
+ int m_ascent;
+ int m_maxLength;
+ int m_lastCursorPos;
+ QList<int> m_transactions;
+ QPoint m_tripleClick;
+ int m_tripleClickTimer;
+ QString m_cancelText;
+
+ void emitCursorPositionChanged();
+
+ bool finishChange(int validateFromState = -1, bool update = false, bool edited = true);
+
+#ifndef QT_NO_VALIDATOR
+ QPointer<QValidator> m_validator;
+#endif
+ QPointer<QCompleter> m_completer;
+#ifndef QT_NO_COMPLETER
+ bool advanceToEnabledItem(int dir);
+#endif
+
+ struct MaskInputData {
+ enum Casemode { NoCaseMode, Upper, Lower };
+ QChar maskChar; // either the separator char or the inputmask
+ bool separator;
+ Casemode caseMode;
+ };
+ QString m_inputMask;
+ QChar m_blank;
+ MaskInputData *m_maskData;
+
+ // undo/redo handling
+ enum CommandType { Separator, Insert, Remove, Delete, RemoveSelection, DeleteSelection, SetSelection };
+ struct Command {
+ inline Command() {}
+ inline Command(CommandType t, int p, QChar c, int ss, int se) : type(t),uc(c),pos(p),selStart(ss),selEnd(se) {}
+ uint type : 4;
+ QChar uc;
+ int pos, selStart, selEnd;
+ };
+ int m_modifiedState;
+ int m_undoState;
+ QVector<Command> m_history;
+ void addCommand(const Command& cmd);
+
+ inline void separate() { m_separator = true; }
+
+ // selection
+ int m_selstart;
+ int m_selend;
+
+ // masking
+ void parseInputMask(const QString &maskFields);
+ bool isValidInput(QChar key, QChar mask) const;
+ bool hasAcceptableInput(const QString &text) const;
+ QString maskString(uint pos, const QString &str, bool clear = false) const;
+ QString clearString(uint pos, uint len) const;
+ QString stripString(const QString &str) const;
+ int findInMask(int pos, bool forward, bool findSeparator, QChar searchChar = QChar()) const;
+
+ // complex text layout (must be mutable so it can be reshaped at will)
+ mutable QTextLayout m_textLayout;
+
+ bool m_passwordEchoEditing;
+ QChar m_passwordCharacter;
+
+ int redoTextLayout() const;
+#if defined(Q_WS_MAC)
+ bool m_threadChecks;
+ mutable QThread *m_textLayoutThread;
+#endif
+
+Q_SIGNALS:
+ void cursorPositionChanged(int, int);
+ void selectionChanged();
+
+ void displayTextChanged(const QString &);
+ void textChanged(const QString &);
+ void textEdited(const QString &);
+
+ void resetInputContext();
+ void updateMicroFocus();
+
+ void accepted();
+ void editingFinished();
+ void updateNeeded(const QRect &);
+
+#ifdef QT_KEYPAD_NAVIGATION
+ void editFocusChange(bool);
+#endif
+protected:
+ virtual void timerEvent(QTimerEvent *event);
+
+private Q_SLOTS:
+ void _q_clipboardChanged();
+ void _q_deleteSelected();
+
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QT_NO_LINEEDIT
+
+#endif // QWidgetLineControl_P_H
diff --git a/src/gui/widgets/qwidgetresizehandler.cpp b/src/widgets/widgets/qwidgetresizehandler.cpp
index f43e0f7dfa..f43e0f7dfa 100644
--- a/src/gui/widgets/qwidgetresizehandler.cpp
+++ b/src/widgets/widgets/qwidgetresizehandler.cpp
diff --git a/src/widgets/widgets/qwidgetresizehandler_p.h b/src/widgets/widgets/qwidgetresizehandler_p.h
new file mode 100644
index 0000000000..9d09d63967
--- /dev/null
+++ b/src/widgets/widgets/qwidgetresizehandler_p.h
@@ -0,0 +1,141 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWIDGETRESIZEHANDLER_P_H
+#define QWIDGETRESIZEHANDLER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. This header file may
+// change from version to version without notice, or even be
+// removed.
+//
+// We mean it.
+//
+
+#include "QtCore/qobject.h"
+#include "QtCore/qpoint.h"
+
+#ifndef QT_NO_RESIZEHANDLER
+
+QT_BEGIN_NAMESPACE
+
+class QMouseEvent;
+class QKeyEvent;
+
+class Q_WIDGETS_EXPORT QWidgetResizeHandler : public QObject
+{
+ Q_OBJECT
+
+public:
+ enum Action {
+ Move = 0x01,
+ Resize = 0x02,
+ Any = Move|Resize
+ };
+
+ explicit QWidgetResizeHandler(QWidget *parent, QWidget *cw = 0);
+ void setActive(bool b) { setActive(Any, b); }
+ void setActive(Action ac, bool b);
+ bool isActive() const { return isActive(Any); }
+ bool isActive(Action ac) const;
+ void setMovingEnabled(bool b) { movingEnabled = b; }
+ bool isMovingEnabled() const { return movingEnabled; }
+
+ bool isButtonDown() const { return buttonDown; }
+
+ void setExtraHeight(int h) { extrahei = h; }
+ void setSizeProtection(bool b) { sizeprotect = b; }
+
+ void setFrameWidth(int w) { fw = w; }
+
+ void doResize();
+ void doMove();
+
+Q_SIGNALS:
+ void activate();
+
+protected:
+ bool eventFilter(QObject *o, QEvent *e);
+ void mouseMoveEvent(QMouseEvent *e);
+ void keyPressEvent(QKeyEvent *e);
+
+private:
+ Q_DISABLE_COPY(QWidgetResizeHandler)
+
+ enum MousePosition {
+ Nowhere,
+ TopLeft, BottomRight, BottomLeft, TopRight,
+ Top, Bottom, Left, Right,
+ Center
+ };
+
+ QWidget *widget;
+ QWidget *childWidget;
+ QPoint moveOffset;
+ QPoint invertedMoveOffset;
+ MousePosition mode;
+ int fw;
+ int extrahei;
+ int range;
+ uint buttonDown :1;
+ uint moveResizeMode :1;
+ uint activeForResize :1;
+ uint sizeprotect :1;
+ uint movingEnabled :1;
+ uint activeForMove :1;
+
+ void setMouseCursor(MousePosition m);
+ bool isMove() const {
+ return moveResizeMode && mode == Center;
+ }
+ bool isResize() const {
+ return moveResizeMode && !isMove();
+ }
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_RESIZEHANDLER
+
+#endif // QWIDGETRESIZEHANDLER_P_H
diff --git a/src/widgets/widgets/qwidgettextcontrol.cpp b/src/widgets/widgets/qwidgettextcontrol.cpp
new file mode 100644
index 0000000000..43ebb6b078
--- /dev/null
+++ b/src/widgets/widgets/qwidgettextcontrol.cpp
@@ -0,0 +1,3148 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwidgettextcontrol_p.h"
+#include "qwidgettextcontrol_p_p.h"
+
+#ifndef QT_NO_TEXTCONTROL
+
+#include <qfont.h>
+#include <qpainter.h>
+#include <qevent.h>
+#include <qdebug.h>
+#include <qmime.h>
+#include <qdrag.h>
+#include <qclipboard.h>
+#include <qmenu.h>
+#include <qstyle.h>
+#include <qtimer.h>
+#include "private/qtextdocumentlayout_p.h"
+#include "private/qabstracttextdocumentlayout_p.h"
+#include "private/qtextedit_p.h"
+#include "qtextdocument.h"
+#include "private/qtextdocument_p.h"
+#include "qtextlist.h"
+#include "private/qwidgettextcontrol_p.h"
+#include "qgraphicssceneevent.h"
+#include "qpagedpaintdevice.h"
+#include "private/qpagedpaintdevice_p.h"
+#include "qtextdocumentwriter.h"
+#include "private/qtextcursor_p.h"
+
+#include <qtextformat.h>
+#include <qdatetime.h>
+#include <qbuffer.h>
+#include <qapplication.h>
+#include <limits.h>
+#include <qtexttable.h>
+#include <qvariant.h>
+#include <qurl.h>
+#include <qdesktopservices.h>
+#include <qinputcontext.h>
+#include <qtooltip.h>
+#include <qstyleoption.h>
+#include <QtWidgets/qlineedit.h>
+
+#ifndef QT_NO_SHORTCUT
+#include "private/qapplication_p.h"
+#include "private/qshortcutmap_p.h"
+#include <qkeysequence.h>
+#define ACCEL_KEY(k) (!qApp->d_func()->shortcutMap.hasShortcutForKeySequence(k) ? QLatin1Char('\t') + QString(QKeySequence(k)) : QString())
+#else
+#define ACCEL_KEY(k) QString()
+#endif
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_CONTEXTMENU
+#if defined(Q_WS_WIN) || defined(Q_WS_X11)
+extern bool qt_use_rtl_extensions;
+#endif
+#endif
+
+// could go into QTextCursor...
+static QTextLine currentTextLine(const QTextCursor &cursor)
+{
+ const QTextBlock block = cursor.block();
+ if (!block.isValid())
+ return QTextLine();
+
+ const QTextLayout *layout = block.layout();
+ if (!layout)
+ return QTextLine();
+
+ const int relativePos = cursor.position() - block.position();
+ return layout->lineForTextPosition(relativePos);
+}
+
+QWidgetTextControlPrivate::QWidgetTextControlPrivate()
+ : doc(0), cursorOn(false), cursorIsFocusIndicator(false),
+ interactionFlags(Qt::TextEditorInteraction),
+ dragEnabled(true),
+#ifndef QT_NO_DRAGANDDROP
+ mousePressed(false), mightStartDrag(false),
+#endif
+ lastSelectionState(false), ignoreAutomaticScrollbarAdjustement(false),
+ overwriteMode(false),
+ acceptRichText(true),
+ preeditCursor(0), hideCursor(false),
+ hasFocus(false),
+#ifdef QT_KEYPAD_NAVIGATION
+ hasEditFocus(false),
+#endif
+ isEnabled(true),
+ hadSelectionOnMousePress(false),
+ ignoreUnusedNavigationEvents(false),
+ openExternalLinks(false),
+ wordSelectionEnabled(false)
+{}
+
+bool QWidgetTextControlPrivate::cursorMoveKeyEvent(QKeyEvent *e)
+{
+#ifdef QT_NO_SHORTCUT
+ Q_UNUSED(e);
+#endif
+
+ Q_Q(QWidgetTextControl);
+ if (cursor.isNull())
+ return false;
+
+ const QTextCursor oldSelection = cursor;
+ const int oldCursorPos = cursor.position();
+
+ QTextCursor::MoveMode mode = QTextCursor::MoveAnchor;
+ QTextCursor::MoveOperation op = QTextCursor::NoMove;
+
+ if (false) {
+ }
+#ifndef QT_NO_SHORTCUT
+ if (e == QKeySequence::MoveToNextChar) {
+ op = QTextCursor::Right;
+ }
+ else if (e == QKeySequence::MoveToPreviousChar) {
+ op = QTextCursor::Left;
+ }
+ else if (e == QKeySequence::SelectNextChar) {
+ op = QTextCursor::Right;
+ mode = QTextCursor::KeepAnchor;
+ }
+ else if (e == QKeySequence::SelectPreviousChar) {
+ op = QTextCursor::Left;
+ mode = QTextCursor::KeepAnchor;
+ }
+ else if (e == QKeySequence::SelectNextWord) {
+ op = QTextCursor::WordRight;
+ mode = QTextCursor::KeepAnchor;
+ }
+ else if (e == QKeySequence::SelectPreviousWord) {
+ op = QTextCursor::WordLeft;
+ mode = QTextCursor::KeepAnchor;
+ }
+ else if (e == QKeySequence::SelectStartOfLine) {
+ op = QTextCursor::StartOfLine;
+ mode = QTextCursor::KeepAnchor;
+ }
+ else if (e == QKeySequence::SelectEndOfLine) {
+ op = QTextCursor::EndOfLine;
+ mode = QTextCursor::KeepAnchor;
+ }
+ else if (e == QKeySequence::SelectStartOfBlock) {
+ op = QTextCursor::StartOfBlock;
+ mode = QTextCursor::KeepAnchor;
+ }
+ else if (e == QKeySequence::SelectEndOfBlock) {
+ op = QTextCursor::EndOfBlock;
+ mode = QTextCursor::KeepAnchor;
+ }
+ else if (e == QKeySequence::SelectStartOfDocument) {
+ op = QTextCursor::Start;
+ mode = QTextCursor::KeepAnchor;
+ }
+ else if (e == QKeySequence::SelectEndOfDocument) {
+ op = QTextCursor::End;
+ mode = QTextCursor::KeepAnchor;
+ }
+ else if (e == QKeySequence::SelectPreviousLine) {
+ op = QTextCursor::Up;
+ mode = QTextCursor::KeepAnchor;
+ }
+ else if (e == QKeySequence::SelectNextLine) {
+ op = QTextCursor::Down;
+ mode = QTextCursor::KeepAnchor;
+ {
+ QTextBlock block = cursor.block();
+ QTextLine line = currentTextLine(cursor);
+ if (!block.next().isValid()
+ && line.isValid()
+ && line.lineNumber() == block.layout()->lineCount() - 1)
+ op = QTextCursor::End;
+ }
+ }
+ else if (e == QKeySequence::MoveToNextWord) {
+ op = QTextCursor::WordRight;
+ }
+ else if (e == QKeySequence::MoveToPreviousWord) {
+ op = QTextCursor::WordLeft;
+ }
+ else if (e == QKeySequence::MoveToEndOfBlock) {
+ op = QTextCursor::EndOfBlock;
+ }
+ else if (e == QKeySequence::MoveToStartOfBlock) {
+ op = QTextCursor::StartOfBlock;
+ }
+ else if (e == QKeySequence::MoveToNextLine) {
+ op = QTextCursor::Down;
+ }
+ else if (e == QKeySequence::MoveToPreviousLine) {
+ op = QTextCursor::Up;
+ }
+ else if (e == QKeySequence::MoveToPreviousLine) {
+ op = QTextCursor::Up;
+ }
+ else if (e == QKeySequence::MoveToStartOfLine) {
+ op = QTextCursor::StartOfLine;
+ }
+ else if (e == QKeySequence::MoveToEndOfLine) {
+ op = QTextCursor::EndOfLine;
+ }
+ else if (e == QKeySequence::MoveToStartOfDocument) {
+ op = QTextCursor::Start;
+ }
+ else if (e == QKeySequence::MoveToEndOfDocument) {
+ op = QTextCursor::End;
+ }
+#endif // QT_NO_SHORTCUT
+ else {
+ return false;
+ }
+
+// Except for pageup and pagedown, Mac OS X has very different behavior, we don't do it all, but
+// here's the breakdown:
+// Shift still works as an anchor, but only one of the other keys can be down Ctrl (Command),
+// Alt (Option), or Meta (Control).
+// Command/Control + Left/Right -- Move to left or right of the line
+// + Up/Down -- Move to top bottom of the file. (Control doesn't move the cursor)
+// Option + Left/Right -- Move one word Left/right.
+// + Up/Down -- Begin/End of Paragraph.
+// Home/End Top/Bottom of file. (usually don't move the cursor, but will select)
+
+ bool visualNavigation = cursor.visualNavigation();
+ cursor.setVisualNavigation(true);
+ const bool moved = cursor.movePosition(op, mode);
+ cursor.setVisualNavigation(visualNavigation);
+ q->ensureCursorVisible();
+
+ bool ignoreNavigationEvents = ignoreUnusedNavigationEvents;
+ bool isNavigationEvent = e->key() == Qt::Key_Up || e->key() == Qt::Key_Down;
+
+#ifdef QT_KEYPAD_NAVIGATION
+ ignoreNavigationEvents = ignoreNavigationEvents || QApplication::keypadNavigationEnabled();
+ isNavigationEvent = isNavigationEvent ||
+ (QApplication::navigationMode() == Qt::NavigationModeKeypadDirectional
+ && (e->key() == Qt::Key_Left || e->key() == Qt::Key_Right));
+#else
+ isNavigationEvent = isNavigationEvent || e->key() == Qt::Key_Left || e->key() == Qt::Key_Right;
+#endif
+
+ if (moved) {
+ if (cursor.position() != oldCursorPos)
+ emit q->cursorPositionChanged();
+ emit q->microFocusChanged();
+ } else if (ignoreNavigationEvents && isNavigationEvent && oldSelection.anchor() == cursor.anchor()) {
+ return false;
+ }
+
+ selectionChanged(/*forceEmitSelectionChanged =*/(mode == QTextCursor::KeepAnchor));
+
+ repaintOldAndNewSelection(oldSelection);
+
+ return true;
+}
+
+void QWidgetTextControlPrivate::updateCurrentCharFormat()
+{
+ Q_Q(QWidgetTextControl);
+
+ QTextCharFormat fmt = cursor.charFormat();
+ if (fmt == lastCharFormat)
+ return;
+ lastCharFormat = fmt;
+
+ emit q->currentCharFormatChanged(fmt);
+ emit q->microFocusChanged();
+}
+
+void QWidgetTextControlPrivate::indent()
+{
+ QTextBlockFormat blockFmt = cursor.blockFormat();
+
+ QTextList *list = cursor.currentList();
+ if (!list) {
+ QTextBlockFormat modifier;
+ modifier.setIndent(blockFmt.indent() + 1);
+ cursor.mergeBlockFormat(modifier);
+ } else {
+ QTextListFormat format = list->format();
+ format.setIndent(format.indent() + 1);
+
+ if (list->itemNumber(cursor.block()) == 1)
+ list->setFormat(format);
+ else
+ cursor.createList(format);
+ }
+}
+
+void QWidgetTextControlPrivate::outdent()
+{
+ QTextBlockFormat blockFmt = cursor.blockFormat();
+
+ QTextList *list = cursor.currentList();
+
+ if (!list) {
+ QTextBlockFormat modifier;
+ modifier.setIndent(blockFmt.indent() - 1);
+ cursor.mergeBlockFormat(modifier);
+ } else {
+ QTextListFormat listFmt = list->format();
+ listFmt.setIndent(listFmt.indent() - 1);
+ list->setFormat(listFmt);
+ }
+}
+
+void QWidgetTextControlPrivate::gotoNextTableCell()
+{
+ QTextTable *table = cursor.currentTable();
+ QTextTableCell cell = table->cellAt(cursor);
+
+ int newColumn = cell.column() + cell.columnSpan();
+ int newRow = cell.row();
+
+ if (newColumn >= table->columns()) {
+ newColumn = 0;
+ ++newRow;
+ if (newRow >= table->rows())
+ table->insertRows(table->rows(), 1);
+ }
+
+ cell = table->cellAt(newRow, newColumn);
+ cursor = cell.firstCursorPosition();
+}
+
+void QWidgetTextControlPrivate::gotoPreviousTableCell()
+{
+ QTextTable *table = cursor.currentTable();
+ QTextTableCell cell = table->cellAt(cursor);
+
+ int newColumn = cell.column() - 1;
+ int newRow = cell.row();
+
+ if (newColumn < 0) {
+ newColumn = table->columns() - 1;
+ --newRow;
+ if (newRow < 0)
+ return;
+ }
+
+ cell = table->cellAt(newRow, newColumn);
+ cursor = cell.firstCursorPosition();
+}
+
+void QWidgetTextControlPrivate::createAutoBulletList()
+{
+ cursor.beginEditBlock();
+
+ QTextBlockFormat blockFmt = cursor.blockFormat();
+
+ QTextListFormat listFmt;
+ listFmt.setStyle(QTextListFormat::ListDisc);
+ listFmt.setIndent(blockFmt.indent() + 1);
+
+ blockFmt.setIndent(0);
+ cursor.setBlockFormat(blockFmt);
+
+ cursor.createList(listFmt);
+
+ cursor.endEditBlock();
+}
+
+void QWidgetTextControlPrivate::init(Qt::TextFormat format, const QString &text, QTextDocument *document)
+{
+ Q_Q(QWidgetTextControl);
+ setContent(format, text, document);
+
+ doc->setUndoRedoEnabled(interactionFlags & Qt::TextEditable);
+ q->setCursorWidth(-1);
+}
+
+void QWidgetTextControlPrivate::setContent(Qt::TextFormat format, const QString &text, QTextDocument *document)
+{
+ Q_Q(QWidgetTextControl);
+
+ // for use when called from setPlainText. we may want to re-use the currently
+ // set char format then.
+ const QTextCharFormat charFormatForInsertion = cursor.charFormat();
+
+ bool clearDocument = true;
+ if (!doc) {
+ if (document) {
+ doc = document;
+ clearDocument = false;
+ } else {
+ palette = QApplication::palette("QWidgetTextControl");
+ doc = new QTextDocument(q);
+ }
+ _q_documentLayoutChanged();
+ cursor = QTextCursor(doc);
+
+// #### doc->documentLayout()->setPaintDevice(viewport);
+
+ QObject::connect(doc, SIGNAL(contentsChanged()), q, SLOT(_q_updateCurrentCharFormatAndSelection()));
+ QObject::connect(doc, SIGNAL(cursorPositionChanged(QTextCursor)), q, SLOT(_q_emitCursorPosChanged(QTextCursor)));
+ QObject::connect(doc, SIGNAL(documentLayoutChanged()), q, SLOT(_q_documentLayoutChanged()));
+
+ // convenience signal forwards
+ QObject::connect(doc, SIGNAL(undoAvailable(bool)), q, SIGNAL(undoAvailable(bool)));
+ QObject::connect(doc, SIGNAL(redoAvailable(bool)), q, SIGNAL(redoAvailable(bool)));
+ QObject::connect(doc, SIGNAL(modificationChanged(bool)), q, SIGNAL(modificationChanged(bool)));
+ QObject::connect(doc, SIGNAL(blockCountChanged(int)), q, SIGNAL(blockCountChanged(int)));
+ }
+
+ bool previousUndoRedoState = doc->isUndoRedoEnabled();
+ if (!document)
+ doc->setUndoRedoEnabled(false);
+
+ //Saving the index save some time.
+ static int contentsChangedIndex = QTextDocument::staticMetaObject.indexOfSignal("contentsChanged()");
+ static int textChangedIndex = QWidgetTextControl::staticMetaObject.indexOfSignal("textChanged()");
+ // avoid multiple textChanged() signals being emitted
+ QMetaObject::disconnect(doc, contentsChangedIndex, q, textChangedIndex);
+
+ if (!text.isEmpty()) {
+ // clear 'our' cursor for insertion to prevent
+ // the emission of the cursorPositionChanged() signal.
+ // instead we emit it only once at the end instead of
+ // at the end of the document after loading and when
+ // positioning the cursor again to the start of the
+ // document.
+ cursor = QTextCursor();
+ if (format == Qt::PlainText) {
+ QTextCursor formatCursor(doc);
+ // put the setPlainText and the setCharFormat into one edit block,
+ // so that the syntax highlight triggers only /once/ for the entire
+ // document, not twice.
+ formatCursor.beginEditBlock();
+ doc->setPlainText(text);
+ doc->setUndoRedoEnabled(false);
+ formatCursor.select(QTextCursor::Document);
+ formatCursor.setCharFormat(charFormatForInsertion);
+ formatCursor.endEditBlock();
+ } else {
+#ifndef QT_NO_TEXTHTMLPARSER
+ doc->setHtml(text);
+#else
+ doc->setPlainText(text);
+#endif
+ doc->setUndoRedoEnabled(false);
+ }
+ cursor = QTextCursor(doc);
+ } else if (clearDocument) {
+ doc->clear();
+ }
+ cursor.setCharFormat(charFormatForInsertion);
+
+ QMetaObject::connect(doc, contentsChangedIndex, q, textChangedIndex);
+ emit q->textChanged();
+ if (!document)
+ doc->setUndoRedoEnabled(previousUndoRedoState);
+ _q_updateCurrentCharFormatAndSelection();
+ if (!document)
+ doc->setModified(false);
+
+ q->ensureCursorVisible();
+ emit q->cursorPositionChanged();
+}
+
+void QWidgetTextControlPrivate::startDrag()
+{
+#ifndef QT_NO_DRAGANDDROP
+ Q_Q(QWidgetTextControl);
+ mousePressed = false;
+ if (!contextWidget)
+ return;
+ QMimeData *data = q->createMimeDataFromSelection();
+
+ QDrag *drag = new QDrag(contextWidget);
+ drag->setMimeData(data);
+
+ Qt::DropActions actions = Qt::CopyAction;
+ Qt::DropAction action;
+ if (interactionFlags & Qt::TextEditable) {
+ actions |= Qt::MoveAction;
+ action = drag->exec(actions, Qt::MoveAction);
+ } else {
+ action = drag->exec(actions, Qt::CopyAction);
+ }
+
+ if (action == Qt::MoveAction && drag->target() != contextWidget)
+ cursor.removeSelectedText();
+#endif
+}
+
+void QWidgetTextControlPrivate::setCursorPosition(const QPointF &pos)
+{
+ Q_Q(QWidgetTextControl);
+ const int cursorPos = q->hitTest(pos, Qt::FuzzyHit);
+ if (cursorPos == -1)
+ return;
+ cursor.setPosition(cursorPos);
+}
+
+void QWidgetTextControlPrivate::setCursorPosition(int pos, QTextCursor::MoveMode mode)
+{
+ cursor.setPosition(pos, mode);
+
+ if (mode != QTextCursor::KeepAnchor) {
+ selectedWordOnDoubleClick = QTextCursor();
+ selectedBlockOnTrippleClick = QTextCursor();
+ }
+}
+
+void QWidgetTextControlPrivate::repaintCursor()
+{
+ Q_Q(QWidgetTextControl);
+ emit q->updateRequest(cursorRectPlusUnicodeDirectionMarkers(cursor));
+}
+
+void QWidgetTextControlPrivate::repaintOldAndNewSelection(const QTextCursor &oldSelection)
+{
+ Q_Q(QWidgetTextControl);
+ if (cursor.hasSelection()
+ && oldSelection.hasSelection()
+ && cursor.currentFrame() == oldSelection.currentFrame()
+ && !cursor.hasComplexSelection()
+ && !oldSelection.hasComplexSelection()
+ && cursor.anchor() == oldSelection.anchor()
+ ) {
+ QTextCursor differenceSelection(doc);
+ differenceSelection.setPosition(oldSelection.position());
+ differenceSelection.setPosition(cursor.position(), QTextCursor::KeepAnchor);
+ emit q->updateRequest(q->selectionRect(differenceSelection));
+ } else {
+ if (!oldSelection.isNull())
+ emit q->updateRequest(q->selectionRect(oldSelection) | cursorRectPlusUnicodeDirectionMarkers(oldSelection));
+ emit q->updateRequest(q->selectionRect() | cursorRectPlusUnicodeDirectionMarkers(cursor));
+ }
+}
+
+void QWidgetTextControlPrivate::selectionChanged(bool forceEmitSelectionChanged /*=false*/)
+{
+ Q_Q(QWidgetTextControl);
+ if (forceEmitSelectionChanged)
+ emit q->selectionChanged();
+
+ bool current = cursor.hasSelection();
+ if (current == lastSelectionState)
+ return;
+
+ lastSelectionState = current;
+ emit q->copyAvailable(current);
+ if (!forceEmitSelectionChanged)
+ emit q->selectionChanged();
+ emit q->microFocusChanged();
+}
+
+void QWidgetTextControlPrivate::_q_updateCurrentCharFormatAndSelection()
+{
+ updateCurrentCharFormat();
+ selectionChanged();
+}
+
+#ifndef QT_NO_CLIPBOARD
+void QWidgetTextControlPrivate::setClipboardSelection()
+{
+ QClipboard *clipboard = QApplication::clipboard();
+ if (!cursor.hasSelection() || !clipboard->supportsSelection())
+ return;
+ Q_Q(QWidgetTextControl);
+ QMimeData *data = q->createMimeDataFromSelection();
+ clipboard->setMimeData(data, QClipboard::Selection);
+}
+#endif
+
+void QWidgetTextControlPrivate::_q_emitCursorPosChanged(const QTextCursor &someCursor)
+{
+ Q_Q(QWidgetTextControl);
+ if (someCursor.isCopyOf(cursor)) {
+ emit q->cursorPositionChanged();
+ emit q->microFocusChanged();
+ }
+}
+
+void QWidgetTextControlPrivate::_q_documentLayoutChanged()
+{
+ Q_Q(QWidgetTextControl);
+ QAbstractTextDocumentLayout *layout = doc->documentLayout();
+ QObject::connect(layout, SIGNAL(update(QRectF)), q, SIGNAL(updateRequest(QRectF)));
+ QObject::connect(layout, SIGNAL(updateBlock(QTextBlock)), q, SLOT(_q_updateBlock(QTextBlock)));
+ QObject::connect(layout, SIGNAL(documentSizeChanged(QSizeF)), q, SIGNAL(documentSizeChanged(QSizeF)));
+
+}
+
+void QWidgetTextControlPrivate::setBlinkingCursorEnabled(bool enable)
+{
+ Q_Q(QWidgetTextControl);
+
+ if (enable && QApplication::cursorFlashTime() > 0)
+ cursorBlinkTimer.start(QApplication::cursorFlashTime() / 2, q);
+ else
+ cursorBlinkTimer.stop();
+
+ cursorOn = enable;
+
+ repaintCursor();
+}
+
+void QWidgetTextControlPrivate::extendWordwiseSelection(int suggestedNewPosition, qreal mouseXPosition)
+{
+ Q_Q(QWidgetTextControl);
+
+ // if inside the initial selected word keep that
+ if (suggestedNewPosition >= selectedWordOnDoubleClick.selectionStart()
+ && suggestedNewPosition <= selectedWordOnDoubleClick.selectionEnd()) {
+ q->setTextCursor(selectedWordOnDoubleClick);
+ return;
+ }
+
+ QTextCursor curs = selectedWordOnDoubleClick;
+ curs.setPosition(suggestedNewPosition, QTextCursor::KeepAnchor);
+
+ if (!curs.movePosition(QTextCursor::StartOfWord))
+ return;
+ const int wordStartPos = curs.position();
+
+ const int blockPos = curs.block().position();
+ const QPointF blockCoordinates = q->blockBoundingRect(curs.block()).topLeft();
+
+ QTextLine line = currentTextLine(curs);
+ if (!line.isValid())
+ return;
+
+ const qreal wordStartX = line.cursorToX(curs.position() - blockPos) + blockCoordinates.x();
+
+ if (!curs.movePosition(QTextCursor::EndOfWord))
+ return;
+ const int wordEndPos = curs.position();
+
+ const QTextLine otherLine = currentTextLine(curs);
+ if (otherLine.textStart() != line.textStart()
+ || wordEndPos == wordStartPos)
+ return;
+
+ const qreal wordEndX = line.cursorToX(curs.position() - blockPos) + blockCoordinates.x();
+
+ if (!wordSelectionEnabled && (mouseXPosition < wordStartX || mouseXPosition > wordEndX))
+ return;
+
+ // keep the already selected word even when moving to the left
+ // (#39164)
+ if (suggestedNewPosition < selectedWordOnDoubleClick.position())
+ cursor.setPosition(selectedWordOnDoubleClick.selectionEnd());
+ else
+ cursor.setPosition(selectedWordOnDoubleClick.selectionStart());
+
+ const qreal differenceToStart = mouseXPosition - wordStartX;
+ const qreal differenceToEnd = wordEndX - mouseXPosition;
+
+ if (differenceToStart < differenceToEnd)
+ setCursorPosition(wordStartPos, QTextCursor::KeepAnchor);
+ else
+ setCursorPosition(wordEndPos, QTextCursor::KeepAnchor);
+
+ if (interactionFlags & Qt::TextSelectableByMouse) {
+#ifndef QT_NO_CLIPBOARD
+ setClipboardSelection();
+#endif
+ selectionChanged(true);
+ }
+}
+
+void QWidgetTextControlPrivate::extendBlockwiseSelection(int suggestedNewPosition)
+{
+ Q_Q(QWidgetTextControl);
+
+ // if inside the initial selected line keep that
+ if (suggestedNewPosition >= selectedBlockOnTrippleClick.selectionStart()
+ && suggestedNewPosition <= selectedBlockOnTrippleClick.selectionEnd()) {
+ q->setTextCursor(selectedBlockOnTrippleClick);
+ return;
+ }
+
+ if (suggestedNewPosition < selectedBlockOnTrippleClick.position()) {
+ cursor.setPosition(selectedBlockOnTrippleClick.selectionEnd());
+ cursor.setPosition(suggestedNewPosition, QTextCursor::KeepAnchor);
+ cursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::KeepAnchor);
+ } else {
+ cursor.setPosition(selectedBlockOnTrippleClick.selectionStart());
+ cursor.setPosition(suggestedNewPosition, QTextCursor::KeepAnchor);
+ cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
+ cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);
+ }
+
+ if (interactionFlags & Qt::TextSelectableByMouse) {
+#ifndef QT_NO_CLIPBOARD
+ setClipboardSelection();
+#endif
+ selectionChanged(true);
+ }
+}
+
+void QWidgetTextControlPrivate::_q_deleteSelected()
+{
+ if (!(interactionFlags & Qt::TextEditable) || !cursor.hasSelection())
+ return;
+ cursor.removeSelectedText();
+}
+
+void QWidgetTextControl::undo()
+{
+ Q_D(QWidgetTextControl);
+ d->repaintSelection();
+ const int oldCursorPos = d->cursor.position();
+ d->doc->undo(&d->cursor);
+ if (d->cursor.position() != oldCursorPos)
+ emit cursorPositionChanged();
+ emit microFocusChanged();
+ ensureCursorVisible();
+}
+
+void QWidgetTextControl::redo()
+{
+ Q_D(QWidgetTextControl);
+ d->repaintSelection();
+ const int oldCursorPos = d->cursor.position();
+ d->doc->redo(&d->cursor);
+ if (d->cursor.position() != oldCursorPos)
+ emit cursorPositionChanged();
+ emit microFocusChanged();
+ ensureCursorVisible();
+}
+
+QWidgetTextControl::QWidgetTextControl(QObject *parent)
+ : QObject(*new QWidgetTextControlPrivate, parent)
+{
+ Q_D(QWidgetTextControl);
+ d->init();
+}
+
+QWidgetTextControl::QWidgetTextControl(const QString &text, QObject *parent)
+ : QObject(*new QWidgetTextControlPrivate, parent)
+{
+ Q_D(QWidgetTextControl);
+ d->init(Qt::RichText, text);
+}
+
+QWidgetTextControl::QWidgetTextControl(QTextDocument *doc, QObject *parent)
+ : QObject(*new QWidgetTextControlPrivate, parent)
+{
+ Q_D(QWidgetTextControl);
+ d->init(Qt::RichText, QString(), doc);
+}
+
+QWidgetTextControl::~QWidgetTextControl()
+{
+}
+
+void QWidgetTextControl::setDocument(QTextDocument *document)
+{
+ Q_D(QWidgetTextControl);
+ if (d->doc == document)
+ return;
+
+ d->doc->disconnect(this);
+ d->doc->documentLayout()->disconnect(this);
+ d->doc->documentLayout()->setPaintDevice(0);
+
+ if (d->doc->parent() == this)
+ delete d->doc;
+
+ d->doc = 0;
+ d->setContent(Qt::RichText, QString(), document);
+}
+
+QTextDocument *QWidgetTextControl::document() const
+{
+ Q_D(const QWidgetTextControl);
+ return d->doc;
+}
+
+void QWidgetTextControl::setTextCursor(const QTextCursor &cursor)
+{
+ Q_D(QWidgetTextControl);
+ d->cursorIsFocusIndicator = false;
+ const bool posChanged = cursor.position() != d->cursor.position();
+ const QTextCursor oldSelection = d->cursor;
+ d->cursor = cursor;
+ d->cursorOn = d->hasFocus && (d->interactionFlags & Qt::TextEditable);
+ d->_q_updateCurrentCharFormatAndSelection();
+ ensureCursorVisible();
+ d->repaintOldAndNewSelection(oldSelection);
+ if (posChanged)
+ emit cursorPositionChanged();
+}
+
+QTextCursor QWidgetTextControl::textCursor() const
+{
+ Q_D(const QWidgetTextControl);
+ return d->cursor;
+}
+
+#ifndef QT_NO_CLIPBOARD
+
+void QWidgetTextControl::cut()
+{
+ Q_D(QWidgetTextControl);
+ if (!(d->interactionFlags & Qt::TextEditable) || !d->cursor.hasSelection())
+ return;
+ copy();
+ d->cursor.removeSelectedText();
+}
+
+void QWidgetTextControl::copy()
+{
+ Q_D(QWidgetTextControl);
+ if (!d->cursor.hasSelection())
+ return;
+ QMimeData *data = createMimeDataFromSelection();
+ QApplication::clipboard()->setMimeData(data);
+}
+
+void QWidgetTextControl::paste(QClipboard::Mode mode)
+{
+ const QMimeData *md = QApplication::clipboard()->mimeData(mode);
+ if (md)
+ insertFromMimeData(md);
+}
+#endif
+
+void QWidgetTextControl::clear()
+{
+ Q_D(QWidgetTextControl);
+ // clears and sets empty content
+ d->extraSelections.clear();
+ d->setContent();
+}
+
+
+void QWidgetTextControl::selectAll()
+{
+ Q_D(QWidgetTextControl);
+ const int selectionLength = qAbs(d->cursor.position() - d->cursor.anchor());
+ d->cursor.select(QTextCursor::Document);
+ d->selectionChanged(selectionLength != qAbs(d->cursor.position() - d->cursor.anchor()));
+ d->cursorIsFocusIndicator = false;
+ emit updateRequest();
+}
+
+void QWidgetTextControl::processEvent(QEvent *e, const QPointF &coordinateOffset, QWidget *contextWidget)
+{
+ QMatrix m;
+ m.translate(coordinateOffset.x(), coordinateOffset.y());
+ processEvent(e, m, contextWidget);
+}
+
+void QWidgetTextControl::processEvent(QEvent *e, const QMatrix &matrix, QWidget *contextWidget)
+{
+ Q_D(QWidgetTextControl);
+ if (d->interactionFlags == Qt::NoTextInteraction) {
+ e->ignore();
+ return;
+ }
+
+ d->contextWidget = contextWidget;
+
+ if (!d->contextWidget) {
+ switch (e->type()) {
+#ifndef QT_NO_GRAPHICSVIEW
+ case QEvent::GraphicsSceneMouseMove:
+ case QEvent::GraphicsSceneMousePress:
+ case QEvent::GraphicsSceneMouseRelease:
+ case QEvent::GraphicsSceneMouseDoubleClick:
+ case QEvent::GraphicsSceneContextMenu:
+ case QEvent::GraphicsSceneHoverEnter:
+ case QEvent::GraphicsSceneHoverMove:
+ case QEvent::GraphicsSceneHoverLeave:
+ case QEvent::GraphicsSceneHelp:
+ case QEvent::GraphicsSceneDragEnter:
+ case QEvent::GraphicsSceneDragMove:
+ case QEvent::GraphicsSceneDragLeave:
+ case QEvent::GraphicsSceneDrop: {
+ QGraphicsSceneEvent *ev = static_cast<QGraphicsSceneEvent *>(e);
+ d->contextWidget = ev->widget();
+ break;
+ }
+#endif // QT_NO_GRAPHICSVIEW
+ default: break;
+ };
+ }
+
+ switch (e->type()) {
+ case QEvent::KeyPress:
+ d->keyPressEvent(static_cast<QKeyEvent *>(e));
+ break;
+ case QEvent::MouseButtonPress: {
+ QMouseEvent *ev = static_cast<QMouseEvent *>(e);
+ d->mousePressEvent(ev, ev->button(), matrix.map(ev->pos()), ev->modifiers(),
+ ev->buttons(), ev->globalPos());
+ break; }
+ case QEvent::MouseMove: {
+ QMouseEvent *ev = static_cast<QMouseEvent *>(e);
+ d->mouseMoveEvent(ev, ev->button(), matrix.map(ev->pos()), ev->modifiers(),
+ ev->buttons(), ev->globalPos());
+ break; }
+ case QEvent::MouseButtonRelease: {
+ QMouseEvent *ev = static_cast<QMouseEvent *>(e);
+ d->mouseReleaseEvent(ev, ev->button(), matrix.map(ev->pos()), ev->modifiers(),
+ ev->buttons(), ev->globalPos());
+ break; }
+ case QEvent::MouseButtonDblClick: {
+ QMouseEvent *ev = static_cast<QMouseEvent *>(e);
+ d->mouseDoubleClickEvent(ev, ev->button(), matrix.map(ev->pos()), ev->modifiers(),
+ ev->buttons(), ev->globalPos());
+ break; }
+ case QEvent::InputMethod:
+ d->inputMethodEvent(static_cast<QInputMethodEvent *>(e));
+ break;
+#ifndef QT_NO_CONTEXTMENU
+ case QEvent::ContextMenu: {
+ QContextMenuEvent *ev = static_cast<QContextMenuEvent *>(e);
+ d->contextMenuEvent(ev->globalPos(), matrix.map(ev->pos()), contextWidget);
+ break; }
+#endif // QT_NO_CONTEXTMENU
+ case QEvent::FocusIn:
+ case QEvent::FocusOut:
+ d->focusEvent(static_cast<QFocusEvent *>(e));
+ break;
+
+ case QEvent::EnabledChange:
+ d->isEnabled = e->isAccepted();
+ break;
+
+#ifndef QT_NO_TOOLTIP
+ case QEvent::ToolTip: {
+ QHelpEvent *ev = static_cast<QHelpEvent *>(e);
+ d->showToolTip(ev->globalPos(), matrix.map(ev->pos()), contextWidget);
+ break;
+ }
+#endif // QT_NO_TOOLTIP
+
+#ifndef QT_NO_DRAGANDDROP
+ case QEvent::DragEnter: {
+ QDragEnterEvent *ev = static_cast<QDragEnterEvent *>(e);
+ if (d->dragEnterEvent(e, ev->mimeData()))
+ ev->acceptProposedAction();
+ break;
+ }
+ case QEvent::DragLeave:
+ d->dragLeaveEvent();
+ break;
+ case QEvent::DragMove: {
+ QDragMoveEvent *ev = static_cast<QDragMoveEvent *>(e);
+ if (d->dragMoveEvent(e, ev->mimeData(), matrix.map(ev->pos())))
+ ev->acceptProposedAction();
+ break;
+ }
+ case QEvent::Drop: {
+ QDropEvent *ev = static_cast<QDropEvent *>(e);
+ if (d->dropEvent(ev->mimeData(), matrix.map(ev->pos()), ev->dropAction(), ev->source()))
+ ev->acceptProposedAction();
+ break;
+ }
+#endif
+
+#ifndef QT_NO_GRAPHICSVIEW
+ case QEvent::GraphicsSceneMousePress: {
+ QGraphicsSceneMouseEvent *ev = static_cast<QGraphicsSceneMouseEvent *>(e);
+ d->mousePressEvent(ev, ev->button(), matrix.map(ev->pos()), ev->modifiers(), ev->buttons(),
+ ev->screenPos());
+ break; }
+ case QEvent::GraphicsSceneMouseMove: {
+ QGraphicsSceneMouseEvent *ev = static_cast<QGraphicsSceneMouseEvent *>(e);
+ d->mouseMoveEvent(ev, ev->button(), matrix.map(ev->pos()), ev->modifiers(), ev->buttons(),
+ ev->screenPos());
+ break; }
+ case QEvent::GraphicsSceneMouseRelease: {
+ QGraphicsSceneMouseEvent *ev = static_cast<QGraphicsSceneMouseEvent *>(e);
+ d->mouseReleaseEvent(ev, ev->button(), matrix.map(ev->pos()), ev->modifiers(), ev->buttons(),
+ ev->screenPos());
+ break; }
+ case QEvent::GraphicsSceneMouseDoubleClick: {
+ QGraphicsSceneMouseEvent *ev = static_cast<QGraphicsSceneMouseEvent *>(e);
+ d->mouseDoubleClickEvent(ev, ev->button(), matrix.map(ev->pos()), ev->modifiers(), ev->buttons(),
+ ev->screenPos());
+ break; }
+ case QEvent::GraphicsSceneContextMenu: {
+ QGraphicsSceneContextMenuEvent *ev = static_cast<QGraphicsSceneContextMenuEvent *>(e);
+ d->contextMenuEvent(ev->screenPos(), matrix.map(ev->pos()), contextWidget);
+ break; }
+
+ case QEvent::GraphicsSceneHoverMove: {
+ QGraphicsSceneHoverEvent *ev = static_cast<QGraphicsSceneHoverEvent *>(e);
+ d->mouseMoveEvent(ev, Qt::NoButton, matrix.map(ev->pos()), ev->modifiers(),Qt::NoButton,
+ ev->screenPos());
+ break; }
+
+ case QEvent::GraphicsSceneDragEnter: {
+ QGraphicsSceneDragDropEvent *ev = static_cast<QGraphicsSceneDragDropEvent *>(e);
+ if (d->dragEnterEvent(e, ev->mimeData()))
+ ev->acceptProposedAction();
+ break; }
+ case QEvent::GraphicsSceneDragLeave:
+ d->dragLeaveEvent();
+ break;
+ case QEvent::GraphicsSceneDragMove: {
+ QGraphicsSceneDragDropEvent *ev = static_cast<QGraphicsSceneDragDropEvent *>(e);
+ if (d->dragMoveEvent(e, ev->mimeData(), matrix.map(ev->pos())))
+ ev->acceptProposedAction();
+ break; }
+ case QEvent::GraphicsSceneDrop: {
+ QGraphicsSceneDragDropEvent *ev = static_cast<QGraphicsSceneDragDropEvent *>(e);
+ if (d->dropEvent(ev->mimeData(), matrix.map(ev->pos()), ev->dropAction(), ev->source()))
+ ev->accept();
+ break; }
+#endif // QT_NO_GRAPHICSVIEW
+#ifdef QT_KEYPAD_NAVIGATION
+ case QEvent::EnterEditFocus:
+ case QEvent::LeaveEditFocus:
+ if (QApplication::keypadNavigationEnabled())
+ d->editFocusEvent(e);
+ break;
+#endif
+ case QEvent::ShortcutOverride:
+ if (d->interactionFlags & Qt::TextEditable) {
+ QKeyEvent* ke = static_cast<QKeyEvent *>(e);
+ if (ke->modifiers() == Qt::NoModifier
+ || ke->modifiers() == Qt::ShiftModifier
+ || ke->modifiers() == Qt::KeypadModifier) {
+ if (ke->key() < Qt::Key_Escape) {
+ ke->accept();
+ } else {
+ switch (ke->key()) {
+ case Qt::Key_Return:
+ case Qt::Key_Enter:
+ case Qt::Key_Delete:
+ case Qt::Key_Home:
+ case Qt::Key_End:
+ case Qt::Key_Backspace:
+ case Qt::Key_Left:
+ case Qt::Key_Right:
+ case Qt::Key_Up:
+ case Qt::Key_Down:
+ case Qt::Key_Tab:
+ ke->accept();
+ default:
+ break;
+ }
+ }
+#ifndef QT_NO_SHORTCUT
+ } else if (ke == QKeySequence::Copy
+ || ke == QKeySequence::Paste
+ || ke == QKeySequence::Cut
+ || ke == QKeySequence::Redo
+ || ke == QKeySequence::Undo
+ || ke == QKeySequence::MoveToNextWord
+ || ke == QKeySequence::MoveToPreviousWord
+ || ke == QKeySequence::MoveToStartOfDocument
+ || ke == QKeySequence::MoveToEndOfDocument
+ || ke == QKeySequence::SelectNextWord
+ || ke == QKeySequence::SelectPreviousWord
+ || ke == QKeySequence::SelectStartOfLine
+ || ke == QKeySequence::SelectEndOfLine
+ || ke == QKeySequence::SelectStartOfBlock
+ || ke == QKeySequence::SelectEndOfBlock
+ || ke == QKeySequence::SelectStartOfDocument
+ || ke == QKeySequence::SelectEndOfDocument
+ || ke == QKeySequence::SelectAll
+ ) {
+ ke->accept();
+#endif
+ }
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+bool QWidgetTextControl::event(QEvent *e)
+{
+ return QObject::event(e);
+}
+
+void QWidgetTextControl::timerEvent(QTimerEvent *e)
+{
+ Q_D(QWidgetTextControl);
+ if (e->timerId() == d->cursorBlinkTimer.timerId()) {
+ d->cursorOn = !d->cursorOn;
+
+ if (d->cursor.hasSelection())
+ d->cursorOn &= (QApplication::style()->styleHint(QStyle::SH_BlinkCursorWhenTextSelected)
+ != 0);
+
+ d->repaintCursor();
+ } else if (e->timerId() == d->trippleClickTimer.timerId()) {
+ d->trippleClickTimer.stop();
+ }
+}
+
+void QWidgetTextControl::setPlainText(const QString &text)
+{
+ Q_D(QWidgetTextControl);
+ d->setContent(Qt::PlainText, text);
+}
+
+void QWidgetTextControl::setHtml(const QString &text)
+{
+ Q_D(QWidgetTextControl);
+ d->setContent(Qt::RichText, text);
+}
+
+void QWidgetTextControlPrivate::keyPressEvent(QKeyEvent *e)
+{
+ Q_Q(QWidgetTextControl);
+#ifndef QT_NO_SHORTCUT
+ if (e == QKeySequence::SelectAll) {
+ e->accept();
+ q->selectAll();
+ return;
+ }
+#ifndef QT_NO_CLIPBOARD
+ else if (e == QKeySequence::Copy) {
+ e->accept();
+ q->copy();
+ return;
+ }
+#endif
+#endif // QT_NO_SHORTCUT
+
+ if (interactionFlags & Qt::TextSelectableByKeyboard
+ && cursorMoveKeyEvent(e))
+ goto accept;
+
+ if (interactionFlags & Qt::LinksAccessibleByKeyboard) {
+ if ((e->key() == Qt::Key_Return
+ || e->key() == Qt::Key_Enter
+#ifdef QT_KEYPAD_NAVIGATION
+ || e->key() == Qt::Key_Select
+#endif
+ )
+ && cursor.hasSelection()) {
+
+ e->accept();
+ activateLinkUnderCursor();
+ return;
+ }
+ }
+
+ if (!(interactionFlags & Qt::TextEditable)) {
+ e->ignore();
+ return;
+ }
+
+ if (e->key() == Qt::Key_Direction_L || e->key() == Qt::Key_Direction_R) {
+ QTextBlockFormat fmt;
+ fmt.setLayoutDirection((e->key() == Qt::Key_Direction_L) ? Qt::LeftToRight : Qt::RightToLeft);
+ cursor.mergeBlockFormat(fmt);
+ goto accept;
+ }
+
+ // schedule a repaint of the region of the cursor, as when we move it we
+ // want to make sure the old cursor disappears (not noticeable when moving
+ // only a few pixels but noticeable when jumping between cells in tables for
+ // example)
+ repaintSelection();
+
+ if (e->key() == Qt::Key_Backspace && !(e->modifiers() & ~Qt::ShiftModifier)) {
+ QTextBlockFormat blockFmt = cursor.blockFormat();
+ QTextList *list = cursor.currentList();
+ if (list && cursor.atBlockStart() && !cursor.hasSelection()) {
+ list->remove(cursor.block());
+ } else if (cursor.atBlockStart() && blockFmt.indent() > 0) {
+ blockFmt.setIndent(blockFmt.indent() - 1);
+ cursor.setBlockFormat(blockFmt);
+ } else {
+ QTextCursor localCursor = cursor;
+ localCursor.deletePreviousChar();
+ }
+ goto accept;
+ }
+#ifndef QT_NO_SHORTCUT
+ else if (e == QKeySequence::InsertParagraphSeparator) {
+ cursor.insertBlock();
+ e->accept();
+ goto accept;
+ } else if (e == QKeySequence::InsertLineSeparator) {
+ cursor.insertText(QString(QChar::LineSeparator));
+ e->accept();
+ goto accept;
+ }
+#endif
+ if (false) {
+ }
+#ifndef QT_NO_SHORTCUT
+ else if (e == QKeySequence::Undo) {
+ q->undo();
+ }
+ else if (e == QKeySequence::Redo) {
+ q->redo();
+ }
+#ifndef QT_NO_CLIPBOARD
+ else if (e == QKeySequence::Cut) {
+ q->cut();
+ }
+ else if (e == QKeySequence::Paste) {
+ QClipboard::Mode mode = QClipboard::Clipboard;
+#ifdef Q_WS_X11
+ if (e->modifiers() == (Qt::CTRL | Qt::SHIFT) && e->key() == Qt::Key_Insert)
+ mode = QClipboard::Selection;
+#endif
+ q->paste(mode);
+ }
+#endif
+ else if (e == QKeySequence::Delete) {
+ QTextCursor localCursor = cursor;
+ localCursor.deleteChar();
+ }
+ else if (e == QKeySequence::DeleteEndOfWord) {
+ if (!cursor.hasSelection())
+ cursor.movePosition(QTextCursor::NextWord, QTextCursor::KeepAnchor);
+ cursor.removeSelectedText();
+ }
+ else if (e == QKeySequence::DeleteStartOfWord) {
+ if (!cursor.hasSelection())
+ cursor.movePosition(QTextCursor::PreviousWord, QTextCursor::KeepAnchor);
+ cursor.removeSelectedText();
+ }
+ else if (e == QKeySequence::DeleteEndOfLine) {
+ QTextBlock block = cursor.block();
+ if (cursor.position() == block.position() + block.length() - 2)
+ cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor);
+ else
+ cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
+ cursor.removeSelectedText();
+ }
+#endif // QT_NO_SHORTCUT
+ else {
+ goto process;
+ }
+ goto accept;
+
+process:
+ {
+ QString text = e->text();
+ if (!text.isEmpty() && (text.at(0).isPrint() || text.at(0) == QLatin1Char('\t'))) {
+ if (overwriteMode
+ // no need to call deleteChar() if we have a selection, insertText
+ // does it already
+ && !cursor.hasSelection()
+ && !cursor.atBlockEnd())
+ cursor.deleteChar();
+
+ cursor.insertText(text);
+ selectionChanged();
+ } else {
+ e->ignore();
+ return;
+ }
+ }
+
+ accept:
+
+ e->accept();
+ cursorOn = true;
+
+ q->ensureCursorVisible();
+
+ updateCurrentCharFormat();
+}
+
+QVariant QWidgetTextControl::loadResource(int type, const QUrl &name)
+{
+#ifdef QT_NO_TEXTEDIT
+ Q_UNUSED(type);
+ Q_UNUSED(name);
+#else
+ if (QTextEdit *textEdit = qobject_cast<QTextEdit *>(parent())) {
+ QUrl resolvedName = textEdit->d_func()->resolveUrl(name);
+ return textEdit->loadResource(type, resolvedName);
+ }
+#endif
+ return QVariant();
+}
+
+void QWidgetTextControlPrivate::_q_updateBlock(const QTextBlock &block)
+{
+ Q_Q(QWidgetTextControl);
+ QRectF br = q->blockBoundingRect(block);
+ br.setRight(qreal(INT_MAX)); // the block might have shrunk
+ emit q->updateRequest(br);
+}
+
+QRectF QWidgetTextControlPrivate::rectForPosition(int position) const
+{
+ Q_Q(const QWidgetTextControl);
+ const QTextBlock block = doc->findBlock(position);
+ if (!block.isValid())
+ return QRectF();
+ const QAbstractTextDocumentLayout *docLayout = doc->documentLayout();
+ const QTextLayout *layout = block.layout();
+ const QPointF layoutPos = q->blockBoundingRect(block).topLeft();
+ int relativePos = position - block.position();
+ if (preeditCursor != 0) {
+ int preeditPos = layout->preeditAreaPosition();
+ if (relativePos == preeditPos)
+ relativePos += preeditCursor;
+ else if (relativePos > preeditPos)
+ relativePos += layout->preeditAreaText().length();
+ }
+ QTextLine line = layout->lineForTextPosition(relativePos);
+
+ int cursorWidth;
+ {
+ bool ok = false;
+#ifndef QT_NO_PROPERTIES
+ cursorWidth = docLayout->property("cursorWidth").toInt(&ok);
+#endif
+ if (!ok)
+ cursorWidth = 1;
+ }
+
+ QRectF r;
+
+ if (line.isValid()) {
+ qreal x = line.cursorToX(relativePos);
+ qreal w = 0;
+ if (overwriteMode) {
+ if (relativePos < line.textLength() - line.textStart())
+ w = line.cursorToX(relativePos + 1) - x;
+ else
+ w = QFontMetrics(block.layout()->font()).width(QLatin1Char(' ')); // in sync with QTextLine::draw()
+ }
+ r = QRectF(layoutPos.x() + x, layoutPos.y() + line.y(),
+ cursorWidth + w, line.height());
+ } else {
+ r = QRectF(layoutPos.x(), layoutPos.y(), cursorWidth, 10); // #### correct height
+ }
+
+ return r;
+}
+
+static inline bool firstFramePosLessThanCursorPos(QTextFrame *frame, int position)
+{
+ return frame->firstPosition() < position;
+}
+
+static inline bool cursorPosLessThanLastFramePos(int position, QTextFrame *frame)
+{
+ return position < frame->lastPosition();
+}
+
+static QRectF boundingRectOfFloatsInSelection(const QTextCursor &cursor)
+{
+ QRectF r;
+ QTextFrame *frame = cursor.currentFrame();
+ const QList<QTextFrame *> children = frame->childFrames();
+
+ const QList<QTextFrame *>::ConstIterator firstFrame = qLowerBound(children.constBegin(), children.constEnd(),
+ cursor.selectionStart(), firstFramePosLessThanCursorPos);
+ const QList<QTextFrame *>::ConstIterator lastFrame = qUpperBound(children.constBegin(), children.constEnd(),
+ cursor.selectionEnd(), cursorPosLessThanLastFramePos);
+ for (QList<QTextFrame *>::ConstIterator it = firstFrame; it != lastFrame; ++it) {
+ if ((*it)->frameFormat().position() != QTextFrameFormat::InFlow)
+ r |= frame->document()->documentLayout()->frameBoundingRect(*it);
+ }
+ return r;
+}
+
+QRectF QWidgetTextControl::selectionRect(const QTextCursor &cursor) const
+{
+ Q_D(const QWidgetTextControl);
+
+ QRectF r = d->rectForPosition(cursor.selectionStart());
+
+ if (cursor.hasComplexSelection() && cursor.currentTable()) {
+ QTextTable *table = cursor.currentTable();
+
+ r = d->doc->documentLayout()->frameBoundingRect(table);
+ /*
+ int firstRow, numRows, firstColumn, numColumns;
+ cursor.selectedTableCells(&firstRow, &numRows, &firstColumn, &numColumns);
+
+ const QTextTableCell firstCell = table->cellAt(firstRow, firstColumn);
+ const QTextTableCell lastCell = table->cellAt(firstRow + numRows - 1, firstColumn + numColumns - 1);
+
+ const QAbstractTextDocumentLayout * const layout = doc->documentLayout();
+
+ QRectF tableSelRect = layout->blockBoundingRect(firstCell.firstCursorPosition().block());
+
+ for (int col = firstColumn; col < firstColumn + numColumns; ++col) {
+ const QTextTableCell cell = table->cellAt(firstRow, col);
+ const qreal y = layout->blockBoundingRect(cell.firstCursorPosition().block()).top();
+
+ tableSelRect.setTop(qMin(tableSelRect.top(), y));
+ }
+
+ for (int row = firstRow; row < firstRow + numRows; ++row) {
+ const QTextTableCell cell = table->cellAt(row, firstColumn);
+ const qreal x = layout->blockBoundingRect(cell.firstCursorPosition().block()).left();
+
+ tableSelRect.setLeft(qMin(tableSelRect.left(), x));
+ }
+
+ for (int col = firstColumn; col < firstColumn + numColumns; ++col) {
+ const QTextTableCell cell = table->cellAt(firstRow + numRows - 1, col);
+ const qreal y = layout->blockBoundingRect(cell.lastCursorPosition().block()).bottom();
+
+ tableSelRect.setBottom(qMax(tableSelRect.bottom(), y));
+ }
+
+ for (int row = firstRow; row < firstRow + numRows; ++row) {
+ const QTextTableCell cell = table->cellAt(row, firstColumn + numColumns - 1);
+ const qreal x = layout->blockBoundingRect(cell.lastCursorPosition().block()).right();
+
+ tableSelRect.setRight(qMax(tableSelRect.right(), x));
+ }
+
+ r = tableSelRect.toRect();
+ */
+ } else if (cursor.hasSelection()) {
+ const int position = cursor.selectionStart();
+ const int anchor = cursor.selectionEnd();
+ const QTextBlock posBlock = d->doc->findBlock(position);
+ const QTextBlock anchorBlock = d->doc->findBlock(anchor);
+ if (posBlock == anchorBlock && posBlock.isValid() && posBlock.layout()->lineCount()) {
+ const QTextLine posLine = posBlock.layout()->lineForTextPosition(position - posBlock.position());
+ const QTextLine anchorLine = anchorBlock.layout()->lineForTextPosition(anchor - anchorBlock.position());
+
+ const int firstLine = qMin(posLine.lineNumber(), anchorLine.lineNumber());
+ const int lastLine = qMax(posLine.lineNumber(), anchorLine.lineNumber());
+ const QTextLayout *layout = posBlock.layout();
+ r = QRectF();
+ for (int i = firstLine; i <= lastLine; ++i) {
+ r |= layout->lineAt(i).rect();
+ r |= layout->lineAt(i).naturalTextRect(); // might be bigger in the case of wrap not enabled
+ }
+ r.translate(blockBoundingRect(posBlock).topLeft());
+ } else {
+ QRectF anchorRect = d->rectForPosition(cursor.selectionEnd());
+ r |= anchorRect;
+ r |= boundingRectOfFloatsInSelection(cursor);
+ QRectF frameRect(d->doc->documentLayout()->frameBoundingRect(cursor.currentFrame()));
+ r.setLeft(frameRect.left());
+ r.setRight(frameRect.right());
+ }
+ if (r.isValid())
+ r.adjust(-1, -1, 1, 1);
+ }
+
+ return r;
+}
+
+QRectF QWidgetTextControl::selectionRect() const
+{
+ Q_D(const QWidgetTextControl);
+ return selectionRect(d->cursor);
+}
+
+void QWidgetTextControlPrivate::mousePressEvent(QEvent *e, Qt::MouseButton button, const QPointF &pos, Qt::KeyboardModifiers modifiers,
+ Qt::MouseButtons buttons, const QPoint &globalPos)
+{
+ Q_Q(QWidgetTextControl);
+
+ if (sendMouseEventToInputContext(
+ e, QEvent::MouseButtonPress, button, pos, modifiers, buttons, globalPos)) {
+ return;
+ }
+
+ if (interactionFlags & Qt::LinksAccessibleByMouse) {
+ anchorOnMousePress = q->anchorAt(pos);
+
+ if (cursorIsFocusIndicator) {
+ cursorIsFocusIndicator = false;
+ repaintSelection();
+ cursor.clearSelection();
+ }
+ }
+ if (!(button & Qt::LeftButton) ||
+ !((interactionFlags & Qt::TextSelectableByMouse) || (interactionFlags & Qt::TextEditable))) {
+ e->ignore();
+ return;
+ }
+
+ cursorIsFocusIndicator = false;
+ const QTextCursor oldSelection = cursor;
+ const int oldCursorPos = cursor.position();
+
+ mousePressed = (interactionFlags & Qt::TextSelectableByMouse);
+#ifndef QT_NO_DRAGANDDROP
+ mightStartDrag = false;
+#endif
+
+ if (trippleClickTimer.isActive()
+ && ((pos - trippleClickPoint).toPoint().manhattanLength() < QApplication::startDragDistance())) {
+
+ cursor.movePosition(QTextCursor::StartOfBlock);
+ cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
+ cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);
+ selectedBlockOnTrippleClick = cursor;
+
+ anchorOnMousePress = QString();
+
+ trippleClickTimer.stop();
+ } else {
+ int cursorPos = q->hitTest(pos, Qt::FuzzyHit);
+ if (cursorPos == -1) {
+ e->ignore();
+ return;
+ }
+
+ if (modifiers == Qt::ShiftModifier && (interactionFlags & Qt::TextSelectableByMouse)) {
+ if (wordSelectionEnabled && !selectedWordOnDoubleClick.hasSelection()) {
+ selectedWordOnDoubleClick = cursor;
+ selectedWordOnDoubleClick.select(QTextCursor::WordUnderCursor);
+ }
+
+ if (selectedBlockOnTrippleClick.hasSelection())
+ extendBlockwiseSelection(cursorPos);
+ else if (selectedWordOnDoubleClick.hasSelection())
+ extendWordwiseSelection(cursorPos, pos.x());
+ else if (!wordSelectionEnabled)
+ setCursorPosition(cursorPos, QTextCursor::KeepAnchor);
+ } else {
+
+ if (dragEnabled
+ && cursor.hasSelection()
+ && !cursorIsFocusIndicator
+ && cursorPos >= cursor.selectionStart()
+ && cursorPos <= cursor.selectionEnd()
+ && q->hitTest(pos, Qt::ExactHit) != -1) {
+#ifndef QT_NO_DRAGANDDROP
+ mightStartDrag = true;
+ dragStartPos = pos.toPoint();
+#endif
+ return;
+ }
+
+ setCursorPosition(cursorPos);
+ }
+ }
+
+ if (interactionFlags & Qt::TextEditable) {
+ q->ensureCursorVisible();
+ if (cursor.position() != oldCursorPos)
+ emit q->cursorPositionChanged();
+ _q_updateCurrentCharFormatAndSelection();
+ } else {
+ if (cursor.position() != oldCursorPos) {
+ emit q->cursorPositionChanged();
+ emit q->microFocusChanged();
+ }
+ selectionChanged();
+ }
+ repaintOldAndNewSelection(oldSelection);
+ hadSelectionOnMousePress = cursor.hasSelection();
+}
+
+void QWidgetTextControlPrivate::mouseMoveEvent(QEvent *e, Qt::MouseButton button, const QPointF &mousePos, Qt::KeyboardModifiers modifiers,
+ Qt::MouseButtons buttons, const QPoint &globalPos)
+{
+ Q_Q(QWidgetTextControl);
+
+ if (sendMouseEventToInputContext(
+ e, QEvent::MouseMove, button, mousePos, modifiers, buttons, globalPos)) {
+ return;
+ }
+
+ if (interactionFlags & Qt::LinksAccessibleByMouse) {
+ QString anchor = q->anchorAt(mousePos);
+ if (anchor != highlightedAnchor) {
+ highlightedAnchor = anchor;
+ emit q->linkHovered(anchor);
+ }
+ }
+
+ if (!(buttons & Qt::LeftButton))
+ return;
+
+ const bool editable = interactionFlags & Qt::TextEditable;
+
+ if (!(mousePressed
+ || editable
+ || mightStartDrag
+ || selectedWordOnDoubleClick.hasSelection()
+ || selectedBlockOnTrippleClick.hasSelection()))
+ return;
+
+ const QTextCursor oldSelection = cursor;
+ const int oldCursorPos = cursor.position();
+
+ if (mightStartDrag) {
+ if ((mousePos.toPoint() - dragStartPos).manhattanLength() > QApplication::startDragDistance())
+ startDrag();
+ return;
+ }
+
+ if (!mousePressed)
+ return;
+
+ const qreal mouseX = qreal(mousePos.x());
+
+ int newCursorPos = q->hitTest(mousePos, Qt::FuzzyHit);
+ if (newCursorPos == -1)
+ return;
+
+ if (wordSelectionEnabled && !selectedWordOnDoubleClick.hasSelection()) {
+ selectedWordOnDoubleClick = cursor;
+ selectedWordOnDoubleClick.select(QTextCursor::WordUnderCursor);
+ }
+
+ if (selectedBlockOnTrippleClick.hasSelection())
+ extendBlockwiseSelection(newCursorPos);
+ else if (selectedWordOnDoubleClick.hasSelection())
+ extendWordwiseSelection(newCursorPos, mouseX);
+ else
+ setCursorPosition(newCursorPos, QTextCursor::KeepAnchor);
+
+ if (interactionFlags & Qt::TextEditable) {
+ // don't call ensureVisible for the visible cursor to avoid jumping
+ // scrollbars. the autoscrolling ensures smooth scrolling if necessary.
+ //q->ensureCursorVisible();
+ if (cursor.position() != oldCursorPos)
+ emit q->cursorPositionChanged();
+ _q_updateCurrentCharFormatAndSelection();
+#ifndef QT_NO_IM
+ if (contextWidget) {
+ if (QInputContext *ic = inputContext()) {
+ ic->update();
+ }
+ }
+#endif //QT_NO_IM
+ } else {
+ //emit q->visibilityRequest(QRectF(mousePos, QSizeF(1, 1)));
+ if (cursor.position() != oldCursorPos)
+ emit q->cursorPositionChanged();
+ }
+ selectionChanged(true);
+ repaintOldAndNewSelection(oldSelection);
+}
+
+void QWidgetTextControlPrivate::mouseReleaseEvent(QEvent *e, Qt::MouseButton button, const QPointF &pos, Qt::KeyboardModifiers modifiers,
+ Qt::MouseButtons buttons, const QPoint &globalPos)
+{
+ Q_Q(QWidgetTextControl);
+
+ if (sendMouseEventToInputContext(
+ e, QEvent::MouseButtonRelease, button, pos, modifiers, buttons, globalPos)) {
+ return;
+ }
+
+ const QTextCursor oldSelection = cursor;
+ const int oldCursorPos = cursor.position();
+
+#ifndef QT_NO_DRAGANDDROP
+ if (mightStartDrag && (button & Qt::LeftButton)) {
+ mousePressed = false;
+ setCursorPosition(pos);
+ cursor.clearSelection();
+ selectionChanged();
+ }
+#endif
+ if (mousePressed) {
+ mousePressed = false;
+#ifndef QT_NO_CLIPBOARD
+ setClipboardSelection();
+ selectionChanged(true);
+ } else if (button == Qt::MidButton
+ && (interactionFlags & Qt::TextEditable)
+ && QApplication::clipboard()->supportsSelection()) {
+ setCursorPosition(pos);
+ const QMimeData *md = QApplication::clipboard()->mimeData(QClipboard::Selection);
+ if (md)
+ q->insertFromMimeData(md);
+#endif
+ }
+
+ repaintOldAndNewSelection(oldSelection);
+
+ if (cursor.position() != oldCursorPos)
+ emit q->cursorPositionChanged();
+
+ if (interactionFlags & Qt::LinksAccessibleByMouse) {
+ if (!(button & Qt::LeftButton))
+ return;
+
+ const QString anchor = q->anchorAt(pos);
+
+ if (anchor.isEmpty())
+ return;
+
+ if (!cursor.hasSelection()
+ || (anchor == anchorOnMousePress && hadSelectionOnMousePress)) {
+
+ const int anchorPos = q->hitTest(pos, Qt::ExactHit);
+ if (anchorPos != -1) {
+ cursor.setPosition(anchorPos);
+
+ QString anchor = anchorOnMousePress;
+ anchorOnMousePress = QString();
+ activateLinkUnderCursor(anchor);
+ }
+ }
+ }
+}
+
+void QWidgetTextControlPrivate::mouseDoubleClickEvent(QEvent *e, Qt::MouseButton button, const QPointF &pos, Qt::KeyboardModifiers modifiers,
+ Qt::MouseButtons buttons, const QPoint &globalPos)
+{
+ Q_Q(QWidgetTextControl);
+
+ if (sendMouseEventToInputContext(
+ e, QEvent::MouseButtonDblClick, button, pos, modifiers, buttons, globalPos)) {
+ return;
+ }
+
+ if (button != Qt::LeftButton
+ || !(interactionFlags & Qt::TextSelectableByMouse)) {
+ e->ignore();
+ return;
+ }
+
+#ifndef QT_NO_DRAGANDDROP
+ mightStartDrag = false;
+#endif
+ const QTextCursor oldSelection = cursor;
+ setCursorPosition(pos);
+ QTextLine line = currentTextLine(cursor);
+ bool doEmit = false;
+ if (line.isValid() && line.textLength()) {
+ cursor.select(QTextCursor::WordUnderCursor);
+ doEmit = true;
+ }
+ repaintOldAndNewSelection(oldSelection);
+
+ cursorIsFocusIndicator = false;
+ selectedWordOnDoubleClick = cursor;
+
+ trippleClickPoint = pos;
+ trippleClickTimer.start(QApplication::doubleClickInterval(), q);
+ if (doEmit) {
+ selectionChanged();
+#ifndef QT_NO_CLIPBOARD
+ setClipboardSelection();
+#endif
+ emit q->cursorPositionChanged();
+ }
+}
+
+bool QWidgetTextControlPrivate::sendMouseEventToInputContext(
+ QEvent *e, QEvent::Type eventType, Qt::MouseButton button, const QPointF &pos,
+ Qt::KeyboardModifiers modifiers, Qt::MouseButtons buttons, const QPoint &globalPos)
+{
+#if !defined(QT_NO_IM)
+ Q_Q(QWidgetTextControl);
+
+ QTextLayout *layout = cursor.block().layout();
+ if (contextWidget && layout && !layout->preeditAreaText().isEmpty()) {
+ QInputContext *ctx = inputContext();
+ int cursorPos = q->hitTest(pos, Qt::FuzzyHit) - cursor.position();
+
+ if (cursorPos < 0 || cursorPos > layout->preeditAreaText().length()) {
+ cursorPos = -1;
+ // don't send move events outside the preedit area
+ if (eventType == QEvent::MouseMove)
+ return true;
+ }
+ if (ctx) {
+ QMouseEvent ev(eventType, contextWidget->mapFromGlobal(globalPos),
+ contextWidget->topLevelWidget()->mapFromGlobal(globalPos), globalPos,
+ button, buttons, modifiers);
+ ctx->mouseHandler(cursorPos, &ev);
+ e->setAccepted(ev.isAccepted());
+ }
+ if (!layout->preeditAreaText().isEmpty())
+ return true;
+ }
+#else
+ Q_UNUSED(e);
+ Q_UNUSED(eventType);
+ Q_UNUSED(button);
+ Q_UNUSED(pos);
+ Q_UNUSED(modifiers);
+ Q_UNUSED(buttons);
+ Q_UNUSED(globalPos);
+#endif
+ return false;
+}
+
+void QWidgetTextControlPrivate::contextMenuEvent(const QPoint &screenPos, const QPointF &docPos, QWidget *contextWidget)
+{
+#ifdef QT_NO_CONTEXTMENU
+ Q_UNUSED(screenPos);
+ Q_UNUSED(docPos);
+ Q_UNUSED(contextWidget);
+#else
+ Q_Q(QWidgetTextControl);
+ if (!hasFocus)
+ return;
+ QMenu *menu = q->createStandardContextMenu(docPos, contextWidget);
+ if (!menu)
+ return;
+ menu->setAttribute(Qt::WA_DeleteOnClose);
+ menu->popup(screenPos);
+#endif
+}
+
+bool QWidgetTextControlPrivate::dragEnterEvent(QEvent *e, const QMimeData *mimeData)
+{
+ Q_Q(QWidgetTextControl);
+ if (!(interactionFlags & Qt::TextEditable) || !q->canInsertFromMimeData(mimeData)) {
+ e->ignore();
+ return false;
+ }
+
+ dndFeedbackCursor = QTextCursor();
+
+ return true; // accept proposed action
+}
+
+void QWidgetTextControlPrivate::dragLeaveEvent()
+{
+ Q_Q(QWidgetTextControl);
+
+ const QRectF crect = q->cursorRect(dndFeedbackCursor);
+ dndFeedbackCursor = QTextCursor();
+
+ if (crect.isValid())
+ emit q->updateRequest(crect);
+}
+
+bool QWidgetTextControlPrivate::dragMoveEvent(QEvent *e, const QMimeData *mimeData, const QPointF &pos)
+{
+ Q_Q(QWidgetTextControl);
+ if (!(interactionFlags & Qt::TextEditable) || !q->canInsertFromMimeData(mimeData)) {
+ e->ignore();
+ return false;
+ }
+
+ const int cursorPos = q->hitTest(pos, Qt::FuzzyHit);
+ if (cursorPos != -1) {
+ QRectF crect = q->cursorRect(dndFeedbackCursor);
+ if (crect.isValid())
+ emit q->updateRequest(crect);
+
+ dndFeedbackCursor = cursor;
+ dndFeedbackCursor.setPosition(cursorPos);
+
+ crect = q->cursorRect(dndFeedbackCursor);
+ emit q->updateRequest(crect);
+ }
+
+ return true; // accept proposed action
+}
+
+bool QWidgetTextControlPrivate::dropEvent(const QMimeData *mimeData, const QPointF &pos, Qt::DropAction dropAction, QObject *source)
+{
+ Q_Q(QWidgetTextControl);
+ dndFeedbackCursor = QTextCursor();
+
+ if (!(interactionFlags & Qt::TextEditable) || !q->canInsertFromMimeData(mimeData))
+ return false;
+
+ repaintSelection();
+
+ QTextCursor insertionCursor = q->cursorForPosition(pos);
+ insertionCursor.beginEditBlock();
+
+ if (dropAction == Qt::MoveAction && source == contextWidget)
+ cursor.removeSelectedText();
+
+ cursor = insertionCursor;
+ q->insertFromMimeData(mimeData);
+ insertionCursor.endEditBlock();
+ q->ensureCursorVisible();
+ return true; // accept proposed action
+}
+
+void QWidgetTextControlPrivate::inputMethodEvent(QInputMethodEvent *e)
+{
+ Q_Q(QWidgetTextControl);
+ if (!(interactionFlags & Qt::TextEditable) || cursor.isNull()) {
+ e->ignore();
+ return;
+ }
+ bool isGettingInput = !e->commitString().isEmpty()
+ || e->preeditString() != cursor.block().layout()->preeditAreaText()
+ || e->replacementLength() > 0;
+
+ cursor.beginEditBlock();
+ if (isGettingInput) {
+ cursor.removeSelectedText();
+ }
+
+ // insert commit string
+ if (!e->commitString().isEmpty() || e->replacementLength()) {
+ QTextCursor c = cursor;
+ c.setPosition(c.position() + e->replacementStart());
+ c.setPosition(c.position() + e->replacementLength(), QTextCursor::KeepAnchor);
+ c.insertText(e->commitString());
+ }
+
+ for (int i = 0; i < e->attributes().size(); ++i) {
+ const QInputMethodEvent::Attribute &a = e->attributes().at(i);
+ if (a.type == QInputMethodEvent::Selection) {
+ QTextCursor oldCursor = cursor;
+ int blockStart = a.start + cursor.block().position();
+ cursor.setPosition(blockStart, QTextCursor::MoveAnchor);
+ cursor.setPosition(blockStart + a.length, QTextCursor::KeepAnchor);
+ q->ensureCursorVisible();
+ repaintOldAndNewSelection(oldCursor);
+ }
+ }
+
+ QTextBlock block = cursor.block();
+ QTextLayout *layout = block.layout();
+ if (isGettingInput)
+ layout->setPreeditArea(cursor.position() - block.position(), e->preeditString());
+ QList<QTextLayout::FormatRange> overrides;
+ const int oldPreeditCursor = preeditCursor;
+ preeditCursor = e->preeditString().length();
+ hideCursor = false;
+ for (int i = 0; i < e->attributes().size(); ++i) {
+ const QInputMethodEvent::Attribute &a = e->attributes().at(i);
+ if (a.type == QInputMethodEvent::Cursor) {
+ preeditCursor = a.start;
+ hideCursor = !a.length;
+ } else if (a.type == QInputMethodEvent::TextFormat) {
+ QTextCharFormat f = qvariant_cast<QTextFormat>(a.value).toCharFormat();
+ if (f.isValid()) {
+ QTextLayout::FormatRange o;
+ o.start = a.start + cursor.position() - block.position();
+ o.length = a.length;
+ o.format = f;
+ overrides.append(o);
+ }
+ }
+ }
+ layout->setAdditionalFormats(overrides);
+ cursor.endEditBlock();
+ if (cursor.d)
+ cursor.d->setX();
+ if (oldPreeditCursor != preeditCursor)
+ emit q->microFocusChanged();
+}
+
+QVariant QWidgetTextControl::inputMethodQuery(Qt::InputMethodQuery property) const
+{
+ Q_D(const QWidgetTextControl);
+ QTextBlock block = d->cursor.block();
+ switch(property) {
+ case Qt::ImCursorRectangle:
+ return cursorRect();
+ case Qt::ImFont:
+ return QVariant(d->cursor.charFormat().font());
+ case Qt::ImCursorPosition:
+ return QVariant(d->cursor.position() - block.position());
+ case Qt::ImSurroundingText:
+ return QVariant(block.text());
+ case Qt::ImCurrentSelection:
+ return QVariant(d->cursor.selectedText());
+ case Qt::ImMaximumTextLength:
+ return QVariant(); // No limit.
+ case Qt::ImAnchorPosition:
+ return QVariant(qBound(0, d->cursor.anchor() - block.position(), block.length()));
+ default:
+ return QVariant();
+ }
+}
+
+void QWidgetTextControl::setFocus(bool focus, Qt::FocusReason reason)
+{
+ QFocusEvent ev(focus ? QEvent::FocusIn : QEvent::FocusOut,
+ reason);
+ processEvent(&ev);
+}
+
+void QWidgetTextControlPrivate::focusEvent(QFocusEvent *e)
+{
+ Q_Q(QWidgetTextControl);
+ emit q->updateRequest(q->selectionRect());
+ if (e->gotFocus()) {
+#ifdef QT_KEYPAD_NAVIGATION
+ if (!QApplication::keypadNavigationEnabled() || (hasEditFocus && (e->reason() == Qt::PopupFocusReason
+#ifdef Q_OS_SYMBIAN
+ || e->reason() == Qt::ActiveWindowFocusReason
+#endif
+ ))) {
+#endif
+ cursorOn = (interactionFlags & Qt::TextSelectableByKeyboard);
+ if (interactionFlags & Qt::TextEditable) {
+ setBlinkingCursorEnabled(true);
+ }
+#ifdef QT_KEYPAD_NAVIGATION
+ }
+#endif
+ } else {
+ setBlinkingCursorEnabled(false);
+
+ if (cursorIsFocusIndicator
+ && e->reason() != Qt::ActiveWindowFocusReason
+ && e->reason() != Qt::PopupFocusReason
+ && cursor.hasSelection()) {
+ cursor.clearSelection();
+ }
+ }
+ hasFocus = e->gotFocus();
+}
+
+QString QWidgetTextControlPrivate::anchorForCursor(const QTextCursor &anchorCursor) const
+{
+ if (anchorCursor.hasSelection()) {
+ QTextCursor cursor = anchorCursor;
+ if (cursor.selectionStart() != cursor.position())
+ cursor.setPosition(cursor.selectionStart());
+ cursor.movePosition(QTextCursor::NextCharacter);
+ QTextCharFormat fmt = cursor.charFormat();
+ if (fmt.isAnchor() && fmt.hasProperty(QTextFormat::AnchorHref))
+ return fmt.stringProperty(QTextFormat::AnchorHref);
+ }
+ return QString();
+}
+
+#ifdef QT_KEYPAD_NAVIGATION
+void QWidgetTextControlPrivate::editFocusEvent(QEvent *e)
+{
+ Q_Q(QWidgetTextControl);
+
+ if (QApplication::keypadNavigationEnabled()) {
+ if (e->type() == QEvent::EnterEditFocus && interactionFlags & Qt::TextEditable) {
+ const QTextCursor oldSelection = cursor;
+ const int oldCursorPos = cursor.position();
+ const bool moved = cursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor);
+ q->ensureCursorVisible();
+ if (moved) {
+ if (cursor.position() != oldCursorPos)
+ emit q->cursorPositionChanged();
+ emit q->microFocusChanged();
+ }
+ selectionChanged();
+ repaintOldAndNewSelection(oldSelection);
+
+ setBlinkingCursorEnabled(true);
+ } else
+ setBlinkingCursorEnabled(false);
+ }
+
+ hasEditFocus = e->type() == QEvent::EnterEditFocus ? true : false;
+}
+#endif
+
+#ifndef QT_NO_CONTEXTMENU
+QMenu *QWidgetTextControl::createStandardContextMenu(const QPointF &pos, QWidget *parent)
+{
+ Q_D(QWidgetTextControl);
+
+ const bool showTextSelectionActions = d->interactionFlags & (Qt::TextEditable | Qt::TextSelectableByKeyboard | Qt::TextSelectableByMouse);
+
+ d->linkToCopy = QString();
+ if (!pos.isNull())
+ d->linkToCopy = anchorAt(pos);
+
+ if (d->linkToCopy.isEmpty() && !showTextSelectionActions)
+ return 0;
+
+ QMenu *menu = new QMenu(parent);
+ QAction *a;
+
+ if (d->interactionFlags & Qt::TextEditable) {
+ a = menu->addAction(tr("&Undo") + ACCEL_KEY(QKeySequence::Undo), this, SLOT(undo()));
+ a->setEnabled(d->doc->isUndoAvailable());
+ a = menu->addAction(tr("&Redo") + ACCEL_KEY(QKeySequence::Redo), this, SLOT(redo()));
+ a->setEnabled(d->doc->isRedoAvailable());
+ menu->addSeparator();
+
+ a = menu->addAction(tr("Cu&t") + ACCEL_KEY(QKeySequence::Cut), this, SLOT(cut()));
+ a->setEnabled(d->cursor.hasSelection());
+ }
+
+ if (showTextSelectionActions) {
+ a = menu->addAction(tr("&Copy") + ACCEL_KEY(QKeySequence::Copy), this, SLOT(copy()));
+ a->setEnabled(d->cursor.hasSelection());
+ }
+
+ if ((d->interactionFlags & Qt::LinksAccessibleByKeyboard)
+ || (d->interactionFlags & Qt::LinksAccessibleByMouse)) {
+
+ a = menu->addAction(tr("Copy &Link Location"), this, SLOT(_q_copyLink()));
+ a->setEnabled(!d->linkToCopy.isEmpty());
+ }
+
+ if (d->interactionFlags & Qt::TextEditable) {
+#if !defined(QT_NO_CLIPBOARD)
+ a = menu->addAction(tr("&Paste") + ACCEL_KEY(QKeySequence::Paste), this, SLOT(paste()));
+ a->setEnabled(canPaste());
+#endif
+ a = menu->addAction(tr("Delete"), this, SLOT(_q_deleteSelected()));
+ a->setEnabled(d->cursor.hasSelection());
+ }
+
+
+ if (showTextSelectionActions) {
+ menu->addSeparator();
+ a = menu->addAction(tr("Select All") + ACCEL_KEY(QKeySequence::SelectAll), this, SLOT(selectAll()));
+ a->setEnabled(!d->doc->isEmpty());
+ }
+
+#if !defined(QT_NO_IM)
+ if (d->contextWidget) {
+ QInputContext *qic = d->inputContext();
+ if (qic) {
+ QList<QAction *> imActions = qic->actions();
+ for (int i = 0; i < imActions.size(); ++i)
+ menu->addAction(imActions.at(i));
+ }
+ }
+#endif
+
+#if defined(Q_WS_WIN) || defined(Q_WS_X11)
+ if ((d->interactionFlags & Qt::TextEditable) && qt_use_rtl_extensions) {
+#else
+ if (d->interactionFlags & Qt::TextEditable) {
+#endif
+ menu->addSeparator();
+ QUnicodeControlCharacterMenu *ctrlCharacterMenu = new QUnicodeControlCharacterMenu(this, menu);
+ menu->addMenu(ctrlCharacterMenu);
+ }
+
+ return menu;
+}
+#endif // QT_NO_CONTEXTMENU
+
+QTextCursor QWidgetTextControl::cursorForPosition(const QPointF &pos) const
+{
+ Q_D(const QWidgetTextControl);
+ int cursorPos = hitTest(pos, Qt::FuzzyHit);
+ if (cursorPos == -1)
+ cursorPos = 0;
+ QTextCursor c(d->doc);
+ c.setPosition(cursorPos);
+ return c;
+}
+
+QRectF QWidgetTextControl::cursorRect(const QTextCursor &cursor) const
+{
+ Q_D(const QWidgetTextControl);
+ if (cursor.isNull())
+ return QRectF();
+
+ return d->rectForPosition(cursor.position());
+}
+
+QRectF QWidgetTextControl::cursorRect() const
+{
+ Q_D(const QWidgetTextControl);
+ return cursorRect(d->cursor);
+}
+
+QRectF QWidgetTextControlPrivate::cursorRectPlusUnicodeDirectionMarkers(const QTextCursor &cursor) const
+{
+ if (cursor.isNull())
+ return QRectF();
+
+ return rectForPosition(cursor.position()).adjusted(-4, 0, 4, 0);
+}
+
+QString QWidgetTextControl::anchorAt(const QPointF &pos) const
+{
+ Q_D(const QWidgetTextControl);
+ return d->doc->documentLayout()->anchorAt(pos);
+}
+
+QString QWidgetTextControl::anchorAtCursor() const
+{
+ Q_D(const QWidgetTextControl);
+
+ return d->anchorForCursor(d->cursor);
+}
+
+bool QWidgetTextControl::overwriteMode() const
+{
+ Q_D(const QWidgetTextControl);
+ return d->overwriteMode;
+}
+
+void QWidgetTextControl::setOverwriteMode(bool overwrite)
+{
+ Q_D(QWidgetTextControl);
+ d->overwriteMode = overwrite;
+}
+
+int QWidgetTextControl::cursorWidth() const
+{
+#ifndef QT_NO_PROPERTIES
+ Q_D(const QWidgetTextControl);
+ return d->doc->documentLayout()->property("cursorWidth").toInt();
+#else
+ return 1;
+#endif
+}
+
+void QWidgetTextControl::setCursorWidth(int width)
+{
+ Q_D(QWidgetTextControl);
+#ifdef QT_NO_PROPERTIES
+ Q_UNUSED(width);
+#else
+ if (width == -1)
+ width = QApplication::style()->pixelMetric(QStyle::PM_TextCursorWidth);
+ d->doc->documentLayout()->setProperty("cursorWidth", width);
+#endif
+ d->repaintCursor();
+}
+
+bool QWidgetTextControl::acceptRichText() const
+{
+ Q_D(const QWidgetTextControl);
+ return d->acceptRichText;
+}
+
+void QWidgetTextControl::setAcceptRichText(bool accept)
+{
+ Q_D(QWidgetTextControl);
+ d->acceptRichText = accept;
+}
+
+#ifndef QT_NO_TEXTEDIT
+
+void QWidgetTextControl::setExtraSelections(const QList<QTextEdit::ExtraSelection> &selections)
+{
+ Q_D(QWidgetTextControl);
+
+ QHash<int, int> hash;
+ for (int i = 0; i < d->extraSelections.count(); ++i) {
+ const QAbstractTextDocumentLayout::Selection &esel = d->extraSelections.at(i);
+ hash.insertMulti(esel.cursor.anchor(), i);
+ }
+
+ for (int i = 0; i < selections.count(); ++i) {
+ const QTextEdit::ExtraSelection &sel = selections.at(i);
+ QHash<int, int>::iterator it = hash.find(sel.cursor.anchor());
+ if (it != hash.end()) {
+ const QAbstractTextDocumentLayout::Selection &esel = d->extraSelections.at(it.value());
+ if (esel.cursor.position() == sel.cursor.position()
+ && esel.format == sel.format) {
+ hash.erase(it);
+ continue;
+ }
+ }
+ QRectF r = selectionRect(sel.cursor);
+ if (sel.format.boolProperty(QTextFormat::FullWidthSelection)) {
+ r.setLeft(0);
+ r.setWidth(qreal(INT_MAX));
+ }
+ emit updateRequest(r);
+ }
+
+ for (QHash<int, int>::iterator it = hash.begin(); it != hash.end(); ++it) {
+ const QAbstractTextDocumentLayout::Selection &esel = d->extraSelections.at(it.value());
+ QRectF r = selectionRect(esel.cursor);
+ if (esel.format.boolProperty(QTextFormat::FullWidthSelection)) {
+ r.setLeft(0);
+ r.setWidth(qreal(INT_MAX));
+ }
+ emit updateRequest(r);
+ }
+
+ d->extraSelections.resize(selections.count());
+ for (int i = 0; i < selections.count(); ++i) {
+ d->extraSelections[i].cursor = selections.at(i).cursor;
+ d->extraSelections[i].format = selections.at(i).format;
+ }
+}
+
+QList<QTextEdit::ExtraSelection> QWidgetTextControl::extraSelections() const
+{
+ Q_D(const QWidgetTextControl);
+ QList<QTextEdit::ExtraSelection> selections;
+ for (int i = 0; i < d->extraSelections.count(); ++i) {
+ QTextEdit::ExtraSelection sel;
+ sel.cursor = d->extraSelections.at(i).cursor;
+ sel.format = d->extraSelections.at(i).format;
+ selections.append(sel);
+ }
+ return selections;
+}
+
+#endif // QT_NO_TEXTEDIT
+
+void QWidgetTextControl::setTextWidth(qreal width)
+{
+ Q_D(QWidgetTextControl);
+ d->doc->setTextWidth(width);
+}
+
+qreal QWidgetTextControl::textWidth() const
+{
+ Q_D(const QWidgetTextControl);
+ return d->doc->textWidth();
+}
+
+QSizeF QWidgetTextControl::size() const
+{
+ Q_D(const QWidgetTextControl);
+ return d->doc->size();
+}
+
+void QWidgetTextControl::setOpenExternalLinks(bool open)
+{
+ Q_D(QWidgetTextControl);
+ d->openExternalLinks = open;
+}
+
+bool QWidgetTextControl::openExternalLinks() const
+{
+ Q_D(const QWidgetTextControl);
+ return d->openExternalLinks;
+}
+
+bool QWidgetTextControl::ignoreUnusedNavigationEvents() const
+{
+ Q_D(const QWidgetTextControl);
+ return d->ignoreUnusedNavigationEvents;
+}
+
+void QWidgetTextControl::setIgnoreUnusedNavigationEvents(bool ignore)
+{
+ Q_D(QWidgetTextControl);
+ d->ignoreUnusedNavigationEvents = ignore;
+}
+
+void QWidgetTextControl::moveCursor(QTextCursor::MoveOperation op, QTextCursor::MoveMode mode)
+{
+ Q_D(QWidgetTextControl);
+ const QTextCursor oldSelection = d->cursor;
+ const bool moved = d->cursor.movePosition(op, mode);
+ d->_q_updateCurrentCharFormatAndSelection();
+ ensureCursorVisible();
+ d->repaintOldAndNewSelection(oldSelection);
+ if (moved)
+ emit cursorPositionChanged();
+}
+
+bool QWidgetTextControl::canPaste() const
+{
+#ifndef QT_NO_CLIPBOARD
+ Q_D(const QWidgetTextControl);
+ if (d->interactionFlags & Qt::TextEditable) {
+ const QMimeData *md = QApplication::clipboard()->mimeData();
+ return md && canInsertFromMimeData(md);
+ }
+#endif
+ return false;
+}
+
+void QWidgetTextControl::setCursorIsFocusIndicator(bool b)
+{
+ Q_D(QWidgetTextControl);
+ d->cursorIsFocusIndicator = b;
+ d->repaintCursor();
+}
+
+bool QWidgetTextControl::cursorIsFocusIndicator() const
+{
+ Q_D(const QWidgetTextControl);
+ return d->cursorIsFocusIndicator;
+}
+
+
+void QWidgetTextControl::setDragEnabled(bool enabled)
+{
+ Q_D(QWidgetTextControl);
+ d->dragEnabled = enabled;
+}
+
+bool QWidgetTextControl::isDragEnabled() const
+{
+ Q_D(const QWidgetTextControl);
+ return d->dragEnabled;
+}
+
+void QWidgetTextControl::setWordSelectionEnabled(bool enabled)
+{
+ Q_D(QWidgetTextControl);
+ d->wordSelectionEnabled = enabled;
+}
+
+bool QWidgetTextControl::isWordSelectionEnabled() const
+{
+ Q_D(const QWidgetTextControl);
+ return d->wordSelectionEnabled;
+}
+
+void QWidgetTextControl::print(QPagedPaintDevice *printer) const
+{
+ Q_D(const QWidgetTextControl);
+ if (!printer)
+ return;
+ QTextDocument *tempDoc = 0;
+ const QTextDocument *doc = d->doc;
+ if (QPagedPaintDevicePrivate::get(printer)->printSelectionOnly) {
+ if (!d->cursor.hasSelection())
+ return;
+ tempDoc = new QTextDocument(const_cast<QTextDocument *>(doc));
+ tempDoc->setMetaInformation(QTextDocument::DocumentTitle, doc->metaInformation(QTextDocument::DocumentTitle));
+ tempDoc->setPageSize(doc->pageSize());
+ tempDoc->setDefaultFont(doc->defaultFont());
+ tempDoc->setUseDesignMetrics(doc->useDesignMetrics());
+ QTextCursor(tempDoc).insertFragment(d->cursor.selection());
+ doc = tempDoc;
+
+ // copy the custom object handlers
+ doc->documentLayout()->d_func()->handlers = d->doc->documentLayout()->d_func()->handlers;
+ }
+ doc->print(printer);
+ delete tempDoc;
+}
+
+QMimeData *QWidgetTextControl::createMimeDataFromSelection() const
+{
+ Q_D(const QWidgetTextControl);
+ const QTextDocumentFragment fragment(d->cursor);
+ return new QTextEditMimeData(fragment);
+}
+
+bool QWidgetTextControl::canInsertFromMimeData(const QMimeData *source) const
+{
+ Q_D(const QWidgetTextControl);
+ if (d->acceptRichText)
+ return (source->hasText() && !source->text().isEmpty())
+ || source->hasHtml()
+ || source->hasFormat(QLatin1String("application/x-qrichtext"))
+ || source->hasFormat(QLatin1String("application/x-qt-richtext"));
+ else
+ return source->hasText() && !source->text().isEmpty();
+}
+
+void QWidgetTextControl::insertFromMimeData(const QMimeData *source)
+{
+ Q_D(QWidgetTextControl);
+ if (!(d->interactionFlags & Qt::TextEditable) || !source)
+ return;
+
+ bool hasData = false;
+ QTextDocumentFragment fragment;
+#ifndef QT_NO_TEXTHTMLPARSER
+ if (source->hasFormat(QLatin1String("application/x-qrichtext")) && d->acceptRichText) {
+ // x-qrichtext is always UTF-8 (taken from Qt3 since we don't use it anymore).
+ QString richtext = QString::fromUtf8(source->data(QLatin1String("application/x-qrichtext")));
+ richtext.prepend(QLatin1String("<meta name=\"qrichtext\" content=\"1\" />"));
+ fragment = QTextDocumentFragment::fromHtml(richtext, d->doc);
+ hasData = true;
+ } else if (source->hasHtml() && d->acceptRichText) {
+ fragment = QTextDocumentFragment::fromHtml(source->html(), d->doc);
+ hasData = true;
+ } else {
+ QString text = source->text();
+ if (!text.isNull()) {
+ fragment = QTextDocumentFragment::fromPlainText(text);
+ hasData = true;
+ }
+ }
+#else
+ fragment = QTextDocumentFragment::fromPlainText(source->text());
+#endif // QT_NO_TEXTHTMLPARSER
+
+ if (hasData)
+ d->cursor.insertFragment(fragment);
+ ensureCursorVisible();
+}
+
+bool QWidgetTextControl::findNextPrevAnchor(const QTextCursor &startCursor, bool next, QTextCursor &newAnchor)
+{
+ Q_D(QWidgetTextControl);
+
+ int anchorStart = -1;
+ QString anchorHref;
+ int anchorEnd = -1;
+
+ if (next) {
+ const int startPos = startCursor.selectionEnd();
+
+ QTextBlock block = d->doc->findBlock(startPos);
+ QTextBlock::Iterator it = block.begin();
+
+ while (!it.atEnd() && it.fragment().position() < startPos)
+ ++it;
+
+ while (block.isValid()) {
+ anchorStart = -1;
+
+ // find next anchor
+ for (; !it.atEnd(); ++it) {
+ const QTextFragment fragment = it.fragment();
+ const QTextCharFormat fmt = fragment.charFormat();
+
+ if (fmt.isAnchor() && fmt.hasProperty(QTextFormat::AnchorHref)) {
+ anchorStart = fragment.position();
+ anchorHref = fmt.anchorHref();
+ break;
+ }
+ }
+
+ if (anchorStart != -1) {
+ anchorEnd = -1;
+
+ // find next non-anchor fragment
+ for (; !it.atEnd(); ++it) {
+ const QTextFragment fragment = it.fragment();
+ const QTextCharFormat fmt = fragment.charFormat();
+
+ if (!fmt.isAnchor() || fmt.anchorHref() != anchorHref) {
+ anchorEnd = fragment.position();
+ break;
+ }
+ }
+
+ if (anchorEnd == -1)
+ anchorEnd = block.position() + block.length() - 1;
+
+ // make found selection
+ break;
+ }
+
+ block = block.next();
+ it = block.begin();
+ }
+ } else {
+ int startPos = startCursor.selectionStart();
+ if (startPos > 0)
+ --startPos;
+
+ QTextBlock block = d->doc->findBlock(startPos);
+ QTextBlock::Iterator blockStart = block.begin();
+ QTextBlock::Iterator it = block.end();
+
+ if (startPos == block.position()) {
+ it = block.begin();
+ } else {
+ do {
+ if (it == blockStart) {
+ it = QTextBlock::Iterator();
+ block = QTextBlock();
+ } else {
+ --it;
+ }
+ } while (!it.atEnd() && it.fragment().position() + it.fragment().length() - 1 > startPos);
+ }
+
+ while (block.isValid()) {
+ anchorStart = -1;
+
+ if (!it.atEnd()) {
+ do {
+ const QTextFragment fragment = it.fragment();
+ const QTextCharFormat fmt = fragment.charFormat();
+
+ if (fmt.isAnchor() && fmt.hasProperty(QTextFormat::AnchorHref)) {
+ anchorStart = fragment.position() + fragment.length();
+ anchorHref = fmt.anchorHref();
+ break;
+ }
+
+ if (it == blockStart)
+ it = QTextBlock::Iterator();
+ else
+ --it;
+ } while (!it.atEnd());
+ }
+
+ if (anchorStart != -1 && !it.atEnd()) {
+ anchorEnd = -1;
+
+ do {
+ const QTextFragment fragment = it.fragment();
+ const QTextCharFormat fmt = fragment.charFormat();
+
+ if (!fmt.isAnchor() || fmt.anchorHref() != anchorHref) {
+ anchorEnd = fragment.position() + fragment.length();
+ break;
+ }
+
+ if (it == blockStart)
+ it = QTextBlock::Iterator();
+ else
+ --it;
+ } while (!it.atEnd());
+
+ if (anchorEnd == -1)
+ anchorEnd = qMax(0, block.position());
+
+ break;
+ }
+
+ block = block.previous();
+ it = block.end();
+ if (it != block.begin())
+ --it;
+ blockStart = block.begin();
+ }
+
+ }
+
+ if (anchorStart != -1 && anchorEnd != -1) {
+ newAnchor = d->cursor;
+ newAnchor.setPosition(anchorStart);
+ newAnchor.setPosition(anchorEnd, QTextCursor::KeepAnchor);
+ return true;
+ }
+
+ return false;
+}
+
+void QWidgetTextControlPrivate::activateLinkUnderCursor(QString href)
+{
+ QTextCursor oldCursor = cursor;
+
+ if (href.isEmpty()) {
+ QTextCursor tmp = cursor;
+ if (tmp.selectionStart() != tmp.position())
+ tmp.setPosition(tmp.selectionStart());
+ tmp.movePosition(QTextCursor::NextCharacter);
+ href = tmp.charFormat().anchorHref();
+ }
+ if (href.isEmpty())
+ return;
+
+ if (!cursor.hasSelection()) {
+ QTextBlock block = cursor.block();
+ const int cursorPos = cursor.position();
+
+ QTextBlock::Iterator it = block.begin();
+ QTextBlock::Iterator linkFragment;
+
+ for (; !it.atEnd(); ++it) {
+ QTextFragment fragment = it.fragment();
+ const int fragmentPos = fragment.position();
+ if (fragmentPos <= cursorPos &&
+ fragmentPos + fragment.length() > cursorPos) {
+ linkFragment = it;
+ break;
+ }
+ }
+
+ if (!linkFragment.atEnd()) {
+ it = linkFragment;
+ cursor.setPosition(it.fragment().position());
+ if (it != block.begin()) {
+ do {
+ --it;
+ QTextFragment fragment = it.fragment();
+ if (fragment.charFormat().anchorHref() != href)
+ break;
+ cursor.setPosition(fragment.position());
+ } while (it != block.begin());
+ }
+
+ for (it = linkFragment; !it.atEnd(); ++it) {
+ QTextFragment fragment = it.fragment();
+ if (fragment.charFormat().anchorHref() != href)
+ break;
+ cursor.setPosition(fragment.position() + fragment.length(), QTextCursor::KeepAnchor);
+ }
+ }
+ }
+
+ if (hasFocus) {
+ cursorIsFocusIndicator = true;
+ } else {
+ cursorIsFocusIndicator = false;
+ cursor.clearSelection();
+ }
+ repaintOldAndNewSelection(oldCursor);
+
+#ifndef QT_NO_DESKTOPSERVICES
+ if (openExternalLinks)
+ QDesktopServices::openUrl(href);
+ else
+#endif
+ emit q_func()->linkActivated(href);
+}
+
+#ifndef QT_NO_TOOLTIP
+void QWidgetTextControlPrivate::showToolTip(const QPoint &globalPos, const QPointF &pos, QWidget *contextWidget)
+{
+ const QString toolTip = q_func()->cursorForPosition(pos).charFormat().toolTip();
+ if (toolTip.isEmpty())
+ return;
+ QToolTip::showText(globalPos, toolTip, contextWidget);
+}
+#endif // QT_NO_TOOLTIP
+
+bool QWidgetTextControl::setFocusToNextOrPreviousAnchor(bool next)
+{
+ Q_D(QWidgetTextControl);
+
+ if (!(d->interactionFlags & Qt::LinksAccessibleByKeyboard))
+ return false;
+
+ QRectF crect = selectionRect();
+ emit updateRequest(crect);
+
+ // If we don't have a current anchor, we start from the start/end
+ if (!d->cursor.hasSelection()) {
+ d->cursor = QTextCursor(d->doc);
+ if (next)
+ d->cursor.movePosition(QTextCursor::Start);
+ else
+ d->cursor.movePosition(QTextCursor::End);
+ }
+
+ QTextCursor newAnchor;
+ if (findNextPrevAnchor(d->cursor, next, newAnchor)) {
+ d->cursor = newAnchor;
+ d->cursorIsFocusIndicator = true;
+ } else {
+ d->cursor.clearSelection();
+ }
+
+ if (d->cursor.hasSelection()) {
+ crect = selectionRect();
+ emit updateRequest(crect);
+ emit visibilityRequest(crect);
+ return true;
+ } else {
+ return false;
+ }
+}
+
+bool QWidgetTextControl::setFocusToAnchor(const QTextCursor &newCursor)
+{
+ Q_D(QWidgetTextControl);
+
+ if (!(d->interactionFlags & Qt::LinksAccessibleByKeyboard))
+ return false;
+
+ // Verify that this is an anchor.
+ const QString anchorHref = d->anchorForCursor(newCursor);
+ if (anchorHref.isEmpty())
+ return false;
+
+ // and process it
+ QRectF crect = selectionRect();
+ emit updateRequest(crect);
+
+ d->cursor.setPosition(newCursor.selectionStart());
+ d->cursor.setPosition(newCursor.selectionEnd(), QTextCursor::KeepAnchor);
+ d->cursorIsFocusIndicator = true;
+
+ crect = selectionRect();
+ emit updateRequest(crect);
+ emit visibilityRequest(crect);
+ return true;
+}
+
+void QWidgetTextControl::setTextInteractionFlags(Qt::TextInteractionFlags flags)
+{
+ Q_D(QWidgetTextControl);
+ if (flags == d->interactionFlags)
+ return;
+ d->interactionFlags = flags;
+
+ if (d->hasFocus)
+ d->setBlinkingCursorEnabled(flags & Qt::TextEditable);
+}
+
+Qt::TextInteractionFlags QWidgetTextControl::textInteractionFlags() const
+{
+ Q_D(const QWidgetTextControl);
+ return d->interactionFlags;
+}
+
+void QWidgetTextControl::mergeCurrentCharFormat(const QTextCharFormat &modifier)
+{
+ Q_D(QWidgetTextControl);
+ d->cursor.mergeCharFormat(modifier);
+ d->updateCurrentCharFormat();
+}
+
+void QWidgetTextControl::setCurrentCharFormat(const QTextCharFormat &format)
+{
+ Q_D(QWidgetTextControl);
+ d->cursor.setCharFormat(format);
+ d->updateCurrentCharFormat();
+}
+
+QTextCharFormat QWidgetTextControl::currentCharFormat() const
+{
+ Q_D(const QWidgetTextControl);
+ return d->cursor.charFormat();
+}
+
+void QWidgetTextControl::insertPlainText(const QString &text)
+{
+ Q_D(QWidgetTextControl);
+ d->cursor.insertText(text);
+}
+
+#ifndef QT_NO_TEXTHTMLPARSER
+void QWidgetTextControl::insertHtml(const QString &text)
+{
+ Q_D(QWidgetTextControl);
+ d->cursor.insertHtml(text);
+}
+#endif // QT_NO_TEXTHTMLPARSER
+
+QPointF QWidgetTextControl::anchorPosition(const QString &name) const
+{
+ Q_D(const QWidgetTextControl);
+ if (name.isEmpty())
+ return QPointF();
+
+ QRectF r;
+ for (QTextBlock block = d->doc->begin(); block.isValid(); block = block.next()) {
+ QTextCharFormat format = block.charFormat();
+ if (format.isAnchor() && format.anchorNames().contains(name)) {
+ r = d->rectForPosition(block.position());
+ break;
+ }
+
+ for (QTextBlock::Iterator it = block.begin(); !it.atEnd(); ++it) {
+ QTextFragment fragment = it.fragment();
+ format = fragment.charFormat();
+ if (format.isAnchor() && format.anchorNames().contains(name)) {
+ r = d->rectForPosition(fragment.position());
+ block = QTextBlock();
+ break;
+ }
+ }
+ }
+ if (!r.isValid())
+ return QPointF();
+ return QPointF(0, r.top());
+}
+
+void QWidgetTextControl::adjustSize()
+{
+ Q_D(QWidgetTextControl);
+ d->doc->adjustSize();
+}
+
+bool QWidgetTextControl::find(const QString &exp, QTextDocument::FindFlags options)
+{
+ Q_D(QWidgetTextControl);
+ QTextCursor search = d->doc->find(exp, d->cursor, options);
+ if (search.isNull())
+ return false;
+
+ setTextCursor(search);
+ return true;
+}
+
+
+
+void QWidgetTextControlPrivate::append(const QString &text, Qt::TextFormat format)
+{
+ QTextCursor tmp(doc);
+ tmp.beginEditBlock();
+ tmp.movePosition(QTextCursor::End);
+
+ if (!doc->isEmpty())
+ tmp.insertBlock(cursor.blockFormat(), cursor.charFormat());
+ else
+ tmp.setCharFormat(cursor.charFormat());
+
+ // preserve the char format
+ QTextCharFormat oldCharFormat = cursor.charFormat();
+
+#ifndef QT_NO_TEXTHTMLPARSER
+ if (format == Qt::RichText || (format == Qt::AutoText && Qt::mightBeRichText(text))) {
+ tmp.insertHtml(text);
+ } else {
+ tmp.insertText(text);
+ }
+#else
+ tmp.insertText(text);
+#endif // QT_NO_TEXTHTMLPARSER
+ if (!cursor.hasSelection())
+ cursor.setCharFormat(oldCharFormat);
+
+ tmp.endEditBlock();
+}
+
+void QWidgetTextControl::append(const QString &text)
+{
+ Q_D(QWidgetTextControl);
+ d->append(text, Qt::AutoText);
+}
+
+void QWidgetTextControl::appendHtml(const QString &html)
+{
+ Q_D(QWidgetTextControl);
+ d->append(html, Qt::RichText);
+}
+
+void QWidgetTextControl::appendPlainText(const QString &text)
+{
+ Q_D(QWidgetTextControl);
+ d->append(text, Qt::PlainText);
+}
+
+
+void QWidgetTextControl::ensureCursorVisible()
+{
+ Q_D(QWidgetTextControl);
+ QRectF crect = d->rectForPosition(d->cursor.position()).adjusted(-5, 0, 5, 0);
+ emit visibilityRequest(crect);
+ emit microFocusChanged();
+}
+
+QPalette QWidgetTextControl::palette() const
+{
+ Q_D(const QWidgetTextControl);
+ return d->palette;
+}
+
+void QWidgetTextControl::setPalette(const QPalette &pal)
+{
+ Q_D(QWidgetTextControl);
+ d->palette = pal;
+}
+
+QAbstractTextDocumentLayout::PaintContext QWidgetTextControl::getPaintContext(QWidget *widget) const
+{
+ Q_D(const QWidgetTextControl);
+
+ QAbstractTextDocumentLayout::PaintContext ctx;
+
+ ctx.selections = d->extraSelections;
+ ctx.palette = d->palette;
+ if (d->cursorOn && d->isEnabled) {
+ if (d->hideCursor)
+ ctx.cursorPosition = -1;
+ else if (d->preeditCursor != 0)
+ ctx.cursorPosition = - (d->preeditCursor + 2);
+ else
+ ctx.cursorPosition = d->cursor.position();
+ }
+
+ if (!d->dndFeedbackCursor.isNull())
+ ctx.cursorPosition = d->dndFeedbackCursor.position();
+#ifdef QT_KEYPAD_NAVIGATION
+ if (!QApplication::keypadNavigationEnabled() || d->hasEditFocus)
+#endif
+ if (d->cursor.hasSelection()) {
+ QAbstractTextDocumentLayout::Selection selection;
+ selection.cursor = d->cursor;
+ if (d->cursorIsFocusIndicator) {
+ QStyleOption opt;
+ opt.palette = ctx.palette;
+ QStyleHintReturnVariant ret;
+ QStyle *style = QApplication::style();
+ if (widget)
+ style = widget->style();
+ style->styleHint(QStyle::SH_TextControl_FocusIndicatorTextCharFormat, &opt, widget, &ret);
+ selection.format = qvariant_cast<QTextFormat>(ret.variant).toCharFormat();
+ } else {
+ QPalette::ColorGroup cg = d->hasFocus ? QPalette::Active : QPalette::Inactive;
+ selection.format.setBackground(ctx.palette.brush(cg, QPalette::Highlight));
+ selection.format.setForeground(ctx.palette.brush(cg, QPalette::HighlightedText));
+ QStyleOption opt;
+ QStyle *style = QApplication::style();
+ if (widget) {
+ opt.initFrom(widget);
+ style = widget->style();
+ }
+ if (style->styleHint(QStyle::SH_RichText_FullWidthSelection, &opt, widget))
+ selection.format.setProperty(QTextFormat::FullWidthSelection, true);
+ }
+ ctx.selections.append(selection);
+ }
+
+ return ctx;
+}
+
+void QWidgetTextControl::drawContents(QPainter *p, const QRectF &rect, QWidget *widget)
+{
+ Q_D(QWidgetTextControl);
+ p->save();
+ QAbstractTextDocumentLayout::PaintContext ctx = getPaintContext(widget);
+ if (rect.isValid())
+ p->setClipRect(rect, Qt::IntersectClip);
+ ctx.clip = rect;
+
+ d->doc->documentLayout()->draw(p, ctx);
+ p->restore();
+}
+
+void QWidgetTextControlPrivate::_q_copyLink()
+{
+#ifndef QT_NO_CLIPBOARD
+ QMimeData *md = new QMimeData;
+ md->setText(linkToCopy);
+ QApplication::clipboard()->setMimeData(md);
+#endif
+}
+
+QInputContext *QWidgetTextControlPrivate::inputContext()
+{
+ QInputContext *ctx = contextWidget->inputContext();
+ if (!ctx && contextWidget->parentWidget())
+ ctx = contextWidget->parentWidget()->inputContext();
+ return ctx;
+}
+
+int QWidgetTextControl::hitTest(const QPointF &point, Qt::HitTestAccuracy accuracy) const
+{
+ Q_D(const QWidgetTextControl);
+ return d->doc->documentLayout()->hitTest(point, accuracy);
+}
+
+QRectF QWidgetTextControl::blockBoundingRect(const QTextBlock &block) const
+{
+ Q_D(const QWidgetTextControl);
+ return d->doc->documentLayout()->blockBoundingRect(block);
+}
+
+#ifndef QT_NO_CONTEXTMENU
+#define NUM_CONTROL_CHARACTERS 10
+const struct QUnicodeControlCharacter {
+ const char *text;
+ ushort character;
+} qt_controlCharacters[NUM_CONTROL_CHARACTERS] = {
+ { QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "LRM Left-to-right mark"), 0x200e },
+ { QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "RLM Right-to-left mark"), 0x200f },
+ { QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "ZWJ Zero width joiner"), 0x200d },
+ { QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "ZWNJ Zero width non-joiner"), 0x200c },
+ { QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "ZWSP Zero width space"), 0x200b },
+ { QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "LRE Start of left-to-right embedding"), 0x202a },
+ { QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "RLE Start of right-to-left embedding"), 0x202b },
+ { QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "LRO Start of left-to-right override"), 0x202d },
+ { QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "RLO Start of right-to-left override"), 0x202e },
+ { QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "PDF Pop directional formatting"), 0x202c },
+};
+
+QUnicodeControlCharacterMenu::QUnicodeControlCharacterMenu(QObject *_editWidget, QWidget *parent)
+ : QMenu(parent), editWidget(_editWidget)
+{
+ setTitle(tr("Insert Unicode control character"));
+ for (int i = 0; i < NUM_CONTROL_CHARACTERS; ++i) {
+ addAction(tr(qt_controlCharacters[i].text), this, SLOT(menuActionTriggered()));
+ }
+}
+
+void QUnicodeControlCharacterMenu::menuActionTriggered()
+{
+ QAction *a = qobject_cast<QAction *>(sender());
+ int idx = actions().indexOf(a);
+ if (idx < 0 || idx >= NUM_CONTROL_CHARACTERS)
+ return;
+ QChar c(qt_controlCharacters[idx].character);
+ QString str(c);
+
+#ifndef QT_NO_TEXTEDIT
+ if (QTextEdit *edit = qobject_cast<QTextEdit *>(editWidget)) {
+ edit->insertPlainText(str);
+ return;
+ }
+#endif
+ if (QWidgetTextControl *control = qobject_cast<QWidgetTextControl *>(editWidget)) {
+ control->insertPlainText(str);
+ }
+#ifndef QT_NO_LINEEDIT
+ if (QLineEdit *edit = qobject_cast<QLineEdit *>(editWidget)) {
+ edit->insert(str);
+ return;
+ }
+#endif
+}
+#endif // QT_NO_CONTEXTMENU
+
+QStringList QTextEditMimeData::formats() const
+{
+ if (!fragment.isEmpty())
+ return QStringList() << QString::fromLatin1("text/plain") << QString::fromLatin1("text/html")
+#ifndef QT_NO_TEXTODFWRITER
+ << QString::fromLatin1("application/vnd.oasis.opendocument.text")
+#endif
+ ;
+ else
+ return QMimeData::formats();
+}
+
+QVariant QTextEditMimeData::retrieveData(const QString &mimeType, QVariant::Type type) const
+{
+ if (!fragment.isEmpty())
+ setup();
+ return QMimeData::retrieveData(mimeType, type);
+}
+
+void QTextEditMimeData::setup() const
+{
+ QTextEditMimeData *that = const_cast<QTextEditMimeData *>(this);
+#ifndef QT_NO_TEXTHTMLPARSER
+ that->setData(QLatin1String("text/html"), fragment.toHtml("utf-8").toUtf8());
+#endif
+#ifndef QT_NO_TEXTODFWRITER
+ {
+ QBuffer buffer;
+ QTextDocumentWriter writer(&buffer, "ODF");
+ writer.write(fragment);
+ buffer.close();
+ that->setData(QLatin1String("application/vnd.oasis.opendocument.text"), buffer.data());
+ }
+#endif
+ that->setText(fragment.toPlainText());
+ fragment = QTextDocumentFragment();
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qwidgettextcontrol_p.cpp"
+
+#endif // QT_NO_TEXTCONTROL
diff --git a/src/widgets/widgets/qwidgettextcontrol_p.h b/src/widgets/widgets/qwidgettextcontrol_p.h
new file mode 100644
index 0000000000..67ae0596b3
--- /dev/null
+++ b/src/widgets/widgets/qwidgettextcontrol_p.h
@@ -0,0 +1,305 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWIDGETTEXTCONTROL_P_H
+#define QWIDGETTEXTCONTROL_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtGui/qtextdocument.h>
+#include <QtGui/qtextoption.h>
+#include <QtGui/qtextcursor.h>
+#include <QtGui/qtextformat.h>
+#include <QtWidgets/qtextedit.h>
+#include <QtWidgets/qmenu.h>
+#include <QtCore/qrect.h>
+#include <QtGui/qabstracttextdocumentlayout.h>
+#include <QtGui/qtextdocumentfragment.h>
+#include <QtGui/qclipboard.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QStyleSheet;
+class QTextDocument;
+class QMenu;
+class QWidgetTextControlPrivate;
+class QMimeData;
+class QAbstractScrollArea;
+class QEvent;
+class QTimerEvent;
+
+class Q_WIDGETS_EXPORT QWidgetTextControl : public QObject
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QWidgetTextControl)
+#ifndef QT_NO_TEXTHTMLPARSER
+ Q_PROPERTY(QString html READ toHtml WRITE setHtml NOTIFY textChanged USER true)
+#endif
+ Q_PROPERTY(bool overwriteMode READ overwriteMode WRITE setOverwriteMode)
+ Q_PROPERTY(bool acceptRichText READ acceptRichText WRITE setAcceptRichText)
+ Q_PROPERTY(int cursorWidth READ cursorWidth WRITE setCursorWidth)
+ Q_PROPERTY(Qt::TextInteractionFlags textInteractionFlags READ textInteractionFlags WRITE setTextInteractionFlags)
+ Q_PROPERTY(bool openExternalLinks READ openExternalLinks WRITE setOpenExternalLinks)
+ Q_PROPERTY(bool ignoreUnusedNavigationEvents READ ignoreUnusedNavigationEvents WRITE setIgnoreUnusedNavigationEvents)
+public:
+ explicit QWidgetTextControl(QObject *parent = 0);
+ explicit QWidgetTextControl(const QString &text, QObject *parent = 0);
+ explicit QWidgetTextControl(QTextDocument *doc, QObject *parent = 0);
+ virtual ~QWidgetTextControl();
+
+ void setDocument(QTextDocument *document);
+ QTextDocument *document() const;
+
+ void setTextCursor(const QTextCursor &cursor);
+ QTextCursor textCursor() const;
+
+ void setTextInteractionFlags(Qt::TextInteractionFlags flags);
+ Qt::TextInteractionFlags textInteractionFlags() const;
+
+ void mergeCurrentCharFormat(const QTextCharFormat &modifier);
+
+ void setCurrentCharFormat(const QTextCharFormat &format);
+ QTextCharFormat currentCharFormat() const;
+
+ bool find(const QString &exp, QTextDocument::FindFlags options = 0);
+
+ inline QString toPlainText() const
+ { return document()->toPlainText(); }
+#ifndef QT_NO_TEXTHTMLPARSER
+ inline QString toHtml() const
+ { return document()->toHtml(); }
+#endif
+
+ virtual void ensureCursorVisible();
+
+ virtual QVariant loadResource(int type, const QUrl &name);
+#ifndef QT_NO_CONTEXTMENU
+ QMenu *createStandardContextMenu(const QPointF &pos, QWidget *parent);
+#endif
+
+ QTextCursor cursorForPosition(const QPointF &pos) const;
+ QRectF cursorRect(const QTextCursor &cursor) const;
+ QRectF cursorRect() const;
+ QRectF selectionRect(const QTextCursor &cursor) const;
+ QRectF selectionRect() const;
+
+ QString anchorAt(const QPointF &pos) const;
+ QPointF anchorPosition(const QString &name) const;
+
+ QString anchorAtCursor() const;
+
+ bool overwriteMode() const;
+ void setOverwriteMode(bool overwrite);
+
+ int cursorWidth() const;
+ void setCursorWidth(int width);
+
+ bool acceptRichText() const;
+ void setAcceptRichText(bool accept);
+
+#ifndef QT_NO_TEXTEDIT
+ void setExtraSelections(const QList<QTextEdit::ExtraSelection> &selections);
+ QList<QTextEdit::ExtraSelection> extraSelections() const;
+#endif
+
+ void setTextWidth(qreal width);
+ qreal textWidth() const;
+ QSizeF size() const;
+
+ void setOpenExternalLinks(bool open);
+ bool openExternalLinks() const;
+
+ void setIgnoreUnusedNavigationEvents(bool ignore);
+ bool ignoreUnusedNavigationEvents() const;
+
+ void moveCursor(QTextCursor::MoveOperation op, QTextCursor::MoveMode mode = QTextCursor::MoveAnchor);
+
+ bool canPaste() const;
+
+ void setCursorIsFocusIndicator(bool b);
+ bool cursorIsFocusIndicator() const;
+
+ void setDragEnabled(bool enabled);
+ bool isDragEnabled() const;
+
+ bool isWordSelectionEnabled() const;
+ void setWordSelectionEnabled(bool enabled);
+
+ void print(QPagedPaintDevice *printer) const;
+
+ virtual int hitTest(const QPointF &point, Qt::HitTestAccuracy accuracy) const;
+ virtual QRectF blockBoundingRect(const QTextBlock &block) const;
+ QAbstractTextDocumentLayout::PaintContext getPaintContext(QWidget *widget) const;
+
+public Q_SLOTS:
+ void setPlainText(const QString &text);
+ void setHtml(const QString &text);
+
+#ifndef QT_NO_CLIPBOARD
+ void cut();
+ void copy();
+ void paste(QClipboard::Mode mode = QClipboard::Clipboard);
+#endif
+
+ void undo();
+ void redo();
+
+ void clear();
+ void selectAll();
+
+ void insertPlainText(const QString &text);
+#ifndef QT_NO_TEXTHTMLPARSER
+ void insertHtml(const QString &text);
+#endif
+
+ void append(const QString &text);
+ void appendHtml(const QString &html);
+ void appendPlainText(const QString &text);
+
+ void adjustSize();
+
+Q_SIGNALS:
+ void textChanged();
+ void undoAvailable(bool b);
+ void redoAvailable(bool b);
+ void currentCharFormatChanged(const QTextCharFormat &format);
+ void copyAvailable(bool b);
+ void selectionChanged();
+ void cursorPositionChanged();
+
+ // control signals
+ void updateRequest(const QRectF &rect = QRectF());
+ void documentSizeChanged(const QSizeF &);
+ void blockCountChanged(int newBlockCount);
+ void visibilityRequest(const QRectF &rect);
+ void microFocusChanged();
+ void linkActivated(const QString &link);
+ void linkHovered(const QString &);
+ void modificationChanged(bool m);
+
+public:
+ // control properties
+ QPalette palette() const;
+ void setPalette(const QPalette &pal);
+
+ virtual void processEvent(QEvent *e, const QMatrix &matrix, QWidget *contextWidget = 0);
+ void processEvent(QEvent *e, const QPointF &coordinateOffset = QPointF(), QWidget *contextWidget = 0);
+
+ // control methods
+ void drawContents(QPainter *painter, const QRectF &rect = QRectF(), QWidget *widget = 0);
+
+ void setFocus(bool focus, Qt::FocusReason = Qt::OtherFocusReason);
+
+ virtual QVariant inputMethodQuery(Qt::InputMethodQuery property) const;
+
+ virtual QMimeData *createMimeDataFromSelection() const;
+ virtual bool canInsertFromMimeData(const QMimeData *source) const;
+ virtual void insertFromMimeData(const QMimeData *source);
+
+ bool setFocusToAnchor(const QTextCursor &newCursor);
+ bool setFocusToNextOrPreviousAnchor(bool next);
+ bool findNextPrevAnchor(const QTextCursor& from, bool next, QTextCursor& newAnchor);
+
+protected:
+ virtual void timerEvent(QTimerEvent *e);
+
+ virtual bool event(QEvent *e);
+
+private:
+ Q_DISABLE_COPY(QWidgetTextControl)
+ Q_PRIVATE_SLOT(d_func(), void _q_updateCurrentCharFormatAndSelection())
+ Q_PRIVATE_SLOT(d_func(), void _q_emitCursorPosChanged(const QTextCursor &))
+ Q_PRIVATE_SLOT(d_func(), void _q_deleteSelected())
+ Q_PRIVATE_SLOT(d_func(), void _q_copyLink())
+ Q_PRIVATE_SLOT(d_func(), void _q_updateBlock(const QTextBlock &))
+ Q_PRIVATE_SLOT(d_func(), void _q_documentLayoutChanged())
+};
+
+
+#ifndef QT_NO_CONTEXTMENU
+class QUnicodeControlCharacterMenu : public QMenu
+{
+ Q_OBJECT
+public:
+ QUnicodeControlCharacterMenu(QObject *editWidget, QWidget *parent);
+
+private Q_SLOTS:
+ void menuActionTriggered();
+
+private:
+ QObject *editWidget;
+};
+#endif // QT_NO_CONTEXTMENU
+
+
+// also used by QLabel
+class QTextEditMimeData : public QMimeData
+{
+public:
+ inline QTextEditMimeData(const QTextDocumentFragment &aFragment) : fragment(aFragment) {}
+
+ virtual QStringList formats() const;
+protected:
+ virtual QVariant retrieveData(const QString &mimeType, QVariant::Type type) const;
+private:
+ void setup() const;
+
+ mutable QTextDocumentFragment fragment;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QWidgetTextControl_H
diff --git a/src/widgets/widgets/qwidgettextcontrol_p_p.h b/src/widgets/widgets/qwidgettextcontrol_p_p.h
new file mode 100644
index 0000000000..7cc3026dec
--- /dev/null
+++ b/src/widgets/widgets/qwidgettextcontrol_p_p.h
@@ -0,0 +1,238 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWIDGETTEXTCONTROL_P_P_H
+#define QWIDGETTEXTCONTROL_P_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "QtGui/qtextdocumentfragment.h"
+#include "QtWidgets/qscrollbar.h"
+#include "QtGui/qtextcursor.h"
+#include "QtGui/qtextformat.h"
+#include "QtWidgets/qmenu.h"
+#include "QtGui/qabstracttextdocumentlayout.h"
+#include "QtCore/qbasictimer.h"
+#include "QtCore/qpointer.h"
+#include "private/qobject_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QMimeData;
+class QAbstractScrollArea;
+class QInputContext;
+
+class QWidgetTextControlPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QWidgetTextControl)
+public:
+ QWidgetTextControlPrivate();
+
+ bool cursorMoveKeyEvent(QKeyEvent *e);
+
+ void updateCurrentCharFormat();
+
+ void indent();
+ void outdent();
+
+ void gotoNextTableCell();
+ void gotoPreviousTableCell();
+
+ void createAutoBulletList();
+
+ void init(Qt::TextFormat format = Qt::RichText, const QString &text = QString(),
+ QTextDocument *document = 0);
+ void setContent(Qt::TextFormat format = Qt::RichText, const QString &text = QString(),
+ QTextDocument *document = 0);
+ void startDrag();
+
+ void paste(const QMimeData *source);
+
+ void setCursorPosition(const QPointF &pos);
+ void setCursorPosition(int pos, QTextCursor::MoveMode mode = QTextCursor::MoveAnchor);
+
+ void repaintCursor();
+ inline void repaintSelection()
+ { repaintOldAndNewSelection(QTextCursor()); }
+ void repaintOldAndNewSelection(const QTextCursor &oldSelection);
+
+ void selectionChanged(bool forceEmitSelectionChanged = false);
+
+ void _q_updateCurrentCharFormatAndSelection();
+
+#ifndef QT_NO_CLIPBOARD
+ void setClipboardSelection();
+#endif
+
+ void _q_emitCursorPosChanged(const QTextCursor &someCursor);
+
+ void setBlinkingCursorEnabled(bool enable);
+
+ void extendWordwiseSelection(int suggestedNewPosition, qreal mouseXPosition);
+ void extendBlockwiseSelection(int suggestedNewPosition);
+
+ void _q_deleteSelected();
+
+ void _q_setCursorAfterUndoRedo(int undoPosition, int charsAdded, int charsRemoved);
+
+ QRectF cursorRectPlusUnicodeDirectionMarkers(const QTextCursor &cursor) const;
+ QRectF rectForPosition(int position) const;
+ QRectF selectionRect(const QTextCursor &cursor) const;
+ inline QRectF selectionRect() const
+ { return selectionRect(this->cursor); }
+
+ QString anchorForCursor(const QTextCursor &anchor) const;
+
+ void keyPressEvent(QKeyEvent *e);
+ void mousePressEvent(QEvent *e, Qt::MouseButton button, const QPointF &pos,
+ Qt::KeyboardModifiers modifiers,
+ Qt::MouseButtons buttons,
+ const QPoint &globalPos);
+ void mouseMoveEvent(QEvent *e, Qt::MouseButton button, const QPointF &pos,
+ Qt::KeyboardModifiers modifiers,
+ Qt::MouseButtons buttons,
+ const QPoint &globalPos);
+ void mouseReleaseEvent(QEvent *e, Qt::MouseButton button, const QPointF &pos,
+ Qt::KeyboardModifiers modifiers,
+ Qt::MouseButtons buttons,
+ const QPoint &globalPos);
+ void mouseDoubleClickEvent(QEvent *e, Qt::MouseButton button, const QPointF &pos,
+ Qt::KeyboardModifiers modifiers,
+ Qt::MouseButtons buttons,
+ const QPoint &globalPos);
+ bool sendMouseEventToInputContext(QEvent *e, QEvent::Type eventType, Qt::MouseButton button,
+ const QPointF &pos,
+ Qt::KeyboardModifiers modifiers,
+ Qt::MouseButtons buttons,
+ const QPoint &globalPos);
+ void contextMenuEvent(const QPoint &screenPos, const QPointF &docPos, QWidget *contextWidget);
+ void focusEvent(QFocusEvent *e);
+#ifdef QT_KEYPAD_NAVIGATION
+ void editFocusEvent(QEvent *e);
+#endif
+ bool dragEnterEvent(QEvent *e, const QMimeData *mimeData);
+ void dragLeaveEvent();
+ bool dragMoveEvent(QEvent *e, const QMimeData *mimeData, const QPointF &pos);
+ bool dropEvent(const QMimeData *mimeData, const QPointF &pos, Qt::DropAction dropAction, QObject *source);
+
+ void inputMethodEvent(QInputMethodEvent *);
+
+ void activateLinkUnderCursor(QString href = QString());
+
+#ifndef QT_NO_TOOLTIP
+ void showToolTip(const QPoint &globalPos, const QPointF &pos, QWidget *contextWidget);
+#endif
+
+ void append(const QString &text, Qt::TextFormat format = Qt::AutoText);
+
+ QInputContext *inputContext();
+
+ QTextDocument *doc;
+ bool cursorOn;
+ QTextCursor cursor;
+ bool cursorIsFocusIndicator;
+ QTextCharFormat lastCharFormat;
+
+ QTextCursor dndFeedbackCursor;
+
+ Qt::TextInteractionFlags interactionFlags;
+
+ QBasicTimer cursorBlinkTimer;
+ QBasicTimer trippleClickTimer;
+ QPointF trippleClickPoint;
+
+ bool dragEnabled;
+
+ bool mousePressed;
+
+ bool mightStartDrag;
+ QPoint dragStartPos;
+ QPointer<QWidget> contextWidget;
+
+ bool lastSelectionState;
+
+ bool ignoreAutomaticScrollbarAdjustement;
+
+ QTextCursor selectedWordOnDoubleClick;
+ QTextCursor selectedBlockOnTrippleClick;
+
+ bool overwriteMode;
+ bool acceptRichText;
+
+ int preeditCursor;
+ bool hideCursor; // used to hide the cursor in the preedit area
+
+ QVector<QAbstractTextDocumentLayout::Selection> extraSelections;
+
+ QPalette palette;
+ bool hasFocus;
+#ifdef QT_KEYPAD_NAVIGATION
+ bool hasEditFocus;
+#endif
+ bool isEnabled;
+
+ QString highlightedAnchor; // Anchor below cursor
+ QString anchorOnMousePress;
+ bool hadSelectionOnMousePress;
+
+ bool ignoreUnusedNavigationEvents;
+ bool openExternalLinks;
+
+ bool wordSelectionEnabled;
+
+ QString linkToCopy;
+ void _q_copyLink();
+ void _q_updateBlock(const QTextBlock &);
+ void _q_documentLayoutChanged();
+};
+
+QT_END_NAMESPACE
+
+#endif // QWidgetTextControl_P_H
diff --git a/src/gui/widgets/qworkspace.cpp b/src/widgets/widgets/qworkspace.cpp
index 9516bcaa7d..9516bcaa7d 100644
--- a/src/gui/widgets/qworkspace.cpp
+++ b/src/widgets/widgets/qworkspace.cpp
diff --git a/src/widgets/widgets/qworkspace.h b/src/widgets/widgets/qworkspace.h
new file mode 100644
index 0000000000..a251242542
--- /dev/null
+++ b/src/widgets/widgets/qworkspace.h
@@ -0,0 +1,137 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWORKSPACE_H
+#define QWORKSPACE_H
+
+#include <QtWidgets/qwidget.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#ifndef QT_NO_WORKSPACE
+
+class QAction;
+class QWorkspaceChild;
+class QShowEvent;
+class QWorkspacePrivate;
+
+class Q_WIDGETS_EXPORT QWorkspace : public QWidget
+{
+ Q_OBJECT
+ Q_PROPERTY(bool scrollBarsEnabled READ scrollBarsEnabled WRITE setScrollBarsEnabled)
+ Q_PROPERTY(QBrush background READ background WRITE setBackground)
+
+public:
+ explicit QWorkspace(QWidget* parent=0);
+ ~QWorkspace();
+
+ enum WindowOrder { CreationOrder, StackingOrder };
+
+ QWidget* activeWindow() const;
+ QWidgetList windowList(WindowOrder order = CreationOrder) const;
+
+ QWidget * addWindow(QWidget *w, Qt::WindowFlags flags = 0);
+
+ QSize sizeHint() const;
+
+ bool scrollBarsEnabled() const;
+ void setScrollBarsEnabled(bool enable);
+
+#ifdef QT3_SUPPORT
+ QT3_SUPPORT_CONSTRUCTOR QWorkspace(QWidget* parent, const char* name);
+ QT3_SUPPORT void setPaletteBackgroundColor(const QColor &);
+ QT3_SUPPORT void setPaletteBackgroundPixmap(const QPixmap &);
+#endif
+
+ void setBackground(const QBrush &background);
+ QBrush background() const;
+
+Q_SIGNALS:
+ void windowActivated(QWidget* w);
+
+public Q_SLOTS:
+ void setActiveWindow(QWidget *w);
+ void cascade();
+ void tile();
+ void arrangeIcons();
+ void closeActiveWindow();
+ void closeAllWindows();
+ void activateNextWindow();
+ void activatePreviousWindow();
+
+protected:
+ bool event(QEvent *e);
+ void paintEvent(QPaintEvent *e);
+ void changeEvent(QEvent *);
+ void childEvent(QChildEvent *);
+ void resizeEvent(QResizeEvent *);
+ bool eventFilter(QObject *, QEvent *);
+ void showEvent(QShowEvent *e);
+ void hideEvent(QHideEvent *e);
+#ifndef QT_NO_WHEELEVENT
+ void wheelEvent(QWheelEvent *e);
+#endif
+
+private:
+ Q_DECLARE_PRIVATE(QWorkspace)
+ Q_DISABLE_COPY(QWorkspace)
+ Q_PRIVATE_SLOT(d_func(), void _q_normalizeActiveWindow())
+ Q_PRIVATE_SLOT(d_func(), void _q_minimizeActiveWindow())
+ Q_PRIVATE_SLOT(d_func(), void _q_showOperationMenu())
+ Q_PRIVATE_SLOT(d_func(), void _q_popupOperationMenu(const QPoint&))
+ Q_PRIVATE_SLOT(d_func(), void _q_operationMenuActivated(QAction *))
+ Q_PRIVATE_SLOT(d_func(), void _q_updateActions())
+ Q_PRIVATE_SLOT(d_func(), void _q_scrollBarChanged())
+
+ friend class QWorkspaceChild;
+};
+
+#endif // QT_NO_WORKSPACE
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QWORKSPACE_H
diff --git a/src/widgets/widgets/widgets.pri b/src/widgets/widgets/widgets.pri
new file mode 100644
index 0000000000..986e5e79a0
--- /dev/null
+++ b/src/widgets/widgets/widgets.pri
@@ -0,0 +1,165 @@
+# Qt widgets module
+
+HEADERS += \
+ widgets/qbuttongroup.h \
+ widgets/qabstractbutton.h \
+ widgets/qabstractbutton_p.h \
+ widgets/qabstractslider.h \
+ widgets/qabstractslider_p.h \
+ widgets/qabstractspinbox.h \
+ widgets/qabstractspinbox_p.h \
+ widgets/qcalendartextnavigator_p.h \
+ widgets/qcalendarwidget.h \
+ widgets/qcheckbox.h \
+ widgets/qcombobox.h \
+ widgets/qcombobox_p.h \
+ widgets/qcommandlinkbutton.h \
+ widgets/qdatetimeedit.h \
+ widgets/qdatetimeedit_p.h \
+ widgets/qdial.h \
+ widgets/qdialogbuttonbox.h \
+ widgets/qdockwidget.h \
+ widgets/qdockwidget_p.h \
+ widgets/qdockarealayout_p.h \
+ widgets/qfontcombobox.h \
+ widgets/qframe.h \
+ widgets/qframe_p.h \
+ widgets/qgroupbox.h \
+ widgets/qlabel.h \
+ widgets/qlabel_p.h \
+ widgets/qlcdnumber.h \
+ widgets/qlineedit.h \
+ widgets/qlineedit_p.h \
+ widgets/qmainwindow.h \
+ widgets/qmainwindowlayout_p.h \
+ widgets/qmdiarea.h \
+ widgets/qmdiarea_p.h \
+ widgets/qmdisubwindow.h \
+ widgets/qmdisubwindow_p.h \
+ widgets/qmenu.h \
+ widgets/qmenu_p.h \
+ widgets/qmenubar.h \
+ widgets/qmenubar_p.h \
+ widgets/qprogressbar.h \
+ widgets/qpushbutton.h \
+ widgets/qpushbutton_p.h \
+ widgets/qradiobutton.h \
+ widgets/qrubberband.h \
+ widgets/qscrollbar.h \
+ widgets/qscrollarea_p.h \
+ widgets/qsizegrip.h \
+ widgets/qslider.h \
+ widgets/qspinbox.h \
+ widgets/qsplashscreen.h \
+ widgets/qsplitter.h \
+ widgets/qsplitter_p.h \
+ widgets/qstackedwidget.h \
+ widgets/qstatusbar.h \
+ widgets/qtabbar.h \
+ widgets/qtabbar_p.h \
+ widgets/qtabwidget.h \
+ widgets/qtextedit.h \
+ widgets/qtextedit_p.h \
+ widgets/qtextbrowser.h \
+ widgets/qtoolbar.h \
+ widgets/qtoolbar_p.h \
+ widgets/qtoolbarlayout_p.h \
+ widgets/qtoolbarextension_p.h \
+ widgets/qtoolbarseparator_p.h \
+ widgets/qtoolbox.h \
+ widgets/qtoolbutton.h \
+ widgets/qabstractscrollarea.h \
+ widgets/qabstractscrollarea_p.h \
+ widgets/qwidgetresizehandler_p.h \
+ widgets/qfocusframe.h \
+ widgets/qscrollarea.h \
+ widgets/qworkspace.h \
+ widgets/qwidgetanimator_p.h \
+ widgets/qwidgettextcontrol_p.h \
+ widgets/qwidgettextcontrol_p_p.h \
+ widgets/qwidgetlinecontrol_p.h \
+ widgets/qtoolbararealayout_p.h \
+ widgets/qplaintextedit.h \
+ widgets/qplaintextedit_p.h
+
+SOURCES += \
+ widgets/qabstractbutton.cpp \
+ widgets/qabstractslider.cpp \
+ widgets/qabstractspinbox.cpp \
+ widgets/qcalendarwidget.cpp \
+ widgets/qcheckbox.cpp \
+ widgets/qcombobox.cpp \
+ widgets/qcommandlinkbutton.cpp \
+ widgets/qdatetimeedit.cpp \
+ widgets/qdial.cpp \
+ widgets/qdialogbuttonbox.cpp \
+ widgets/qdockwidget.cpp \
+ widgets/qdockarealayout.cpp \
+ widgets/qeffects.cpp \
+ widgets/qfontcombobox.cpp \
+ widgets/qframe.cpp \
+ widgets/qgroupbox.cpp \
+ widgets/qlabel.cpp \
+ widgets/qlcdnumber.cpp \
+ widgets/qlineedit_p.cpp \
+ widgets/qlineedit.cpp \
+ widgets/qmainwindow.cpp \
+ widgets/qmainwindowlayout.cpp \
+ widgets/qmdiarea.cpp \
+ widgets/qmdisubwindow.cpp \
+ widgets/qmenu.cpp \
+ widgets/qmenubar.cpp \
+ widgets/qprogressbar.cpp \
+ widgets/qpushbutton.cpp \
+ widgets/qradiobutton.cpp \
+ widgets/qrubberband.cpp \
+ widgets/qscrollbar.cpp \
+ widgets/qsizegrip.cpp \
+ widgets/qslider.cpp \
+ widgets/qspinbox.cpp \
+ widgets/qsplashscreen.cpp \
+ widgets/qsplitter.cpp \
+ widgets/qstackedwidget.cpp \
+ widgets/qstatusbar.cpp \
+ widgets/qtabbar.cpp \
+ widgets/qtabwidget.cpp \
+ widgets/qtextedit.cpp \
+ widgets/qtextbrowser.cpp \
+ widgets/qtoolbar.cpp \
+ widgets/qtoolbarlayout.cpp \
+ widgets/qtoolbarextension.cpp \
+ widgets/qtoolbarseparator.cpp \
+ widgets/qtoolbox.cpp \
+ widgets/qtoolbutton.cpp \
+ widgets/qabstractscrollarea.cpp \
+ widgets/qwidgetresizehandler.cpp \
+ widgets/qfocusframe.cpp \
+ widgets/qscrollarea.cpp \
+ widgets/qworkspace.cpp \
+ widgets/qwidgetanimator.cpp \
+ widgets/qwidgettextcontrol.cpp \
+ widgets/qwidgetlinecontrol.cpp \
+ widgets/qtoolbararealayout.cpp \
+ widgets/qplaintextedit.cpp
+
+!qpa:mac {
+ HEADERS += widgets/qmacnativewidget_mac.h \
+ widgets/qmaccocoaviewcontainer_mac.h
+ OBJECTIVE_HEADERS += widgets/qcocoatoolbardelegate_mac_p.h \
+ widgets/qcocoamenu_mac_p.h
+ OBJECTIVE_SOURCES += widgets/qmaccocoaviewcontainer_mac.mm \
+ widgets/qcocoatoolbardelegate_mac.mm \
+ widgets/qmainwindowlayout_mac.mm \
+ widgets/qmacnativewidget_mac.mm \
+}
+
+wince*: {
+ SOURCES += widgets/qmenu_wince.cpp
+ HEADERS += widgets/qmenu_wince_resource_p.h
+ RC_FILE = widgets/qmenu_wince.rc
+ !static: QMAKE_WRITE_DEFAULT_RC = 1
+}
+
+symbian: {
+ SOURCES += widgets/qmenu_symbian.cpp
+}